summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--library/msgcat/Makefile.in86
-rwxr-xr-xlibrary/msgcat/configure2128
-rw-r--r--library/msgcat/configure.in2
-rw-r--r--library/msgcat/configure.make10
-rw-r--r--library/msgcat/doc/Access.371
-rw-r--r--library/msgcat/doc/AddErrInfo.3312
-rw-r--r--library/msgcat/doc/Alloc.392
-rw-r--r--library/msgcat/doc/AllowExc.344
-rw-r--r--library/msgcat/doc/AppInit.383
-rw-r--r--library/msgcat/doc/AssocData.387
-rw-r--r--library/msgcat/doc/Async.3161
-rw-r--r--library/msgcat/doc/BackgdErr.378
-rw-r--r--library/msgcat/doc/Backslash.347
-rw-r--r--library/msgcat/doc/BoolObj.395
-rw-r--r--library/msgcat/doc/ByteArrObj.391
-rw-r--r--library/msgcat/doc/CallDel.367
-rw-r--r--library/msgcat/doc/Cancel.366
-rw-r--r--library/msgcat/doc/ChnlStack.397
-rw-r--r--library/msgcat/doc/Class.3236
-rw-r--r--library/msgcat/doc/CmdCmplt.334
-rw-r--r--library/msgcat/doc/Concat.351
-rw-r--r--library/msgcat/doc/CrtChannel.3928
-rw-r--r--library/msgcat/doc/CrtChnlHdlr.389
-rw-r--r--library/msgcat/doc/CrtCloseHdlr.355
-rw-r--r--library/msgcat/doc/CrtCommand.3143
-rw-r--r--library/msgcat/doc/CrtFileHdlr.391
-rw-r--r--library/msgcat/doc/CrtInterp.3149
-rw-r--r--library/msgcat/doc/CrtMathFnc.3155
-rw-r--r--library/msgcat/doc/CrtObjCmd.3302
-rw-r--r--library/msgcat/doc/CrtSlave.3236
-rw-r--r--library/msgcat/doc/CrtTimerHdlr.376
-rw-r--r--library/msgcat/doc/CrtTrace.3191
-rw-r--r--library/msgcat/doc/DString.3153
-rw-r--r--library/msgcat/doc/DetachPids.375
-rw-r--r--library/msgcat/doc/DictObj.3234
-rw-r--r--library/msgcat/doc/DoOneEvent.3106
-rw-r--r--library/msgcat/doc/DoWhenIdle.387
-rw-r--r--library/msgcat/doc/DoubleObj.364
-rw-r--r--library/msgcat/doc/DumpActiveMemory.368
-rw-r--r--library/msgcat/doc/Encoding.3592
-rw-r--r--library/msgcat/doc/Ensemble.3219
-rw-r--r--library/msgcat/doc/Environment.338
-rw-r--r--library/msgcat/doc/Eval.3211
-rw-r--r--library/msgcat/doc/Exit.3140
-rw-r--r--library/msgcat/doc/ExprLong.3106
-rw-r--r--library/msgcat/doc/ExprLongObj.3106
-rw-r--r--library/msgcat/doc/FileSystem.31643
-rw-r--r--library/msgcat/doc/FindExec.363
-rwxr-xr-xlibrary/msgcat/doc/GetCwd.352
-rw-r--r--library/msgcat/doc/GetHostName.327
-rw-r--r--library/msgcat/doc/GetIndex.398
-rw-r--r--library/msgcat/doc/GetInt.386
-rw-r--r--library/msgcat/doc/GetOpnFl.358
-rw-r--r--library/msgcat/doc/GetStdChan.386
-rw-r--r--library/msgcat/doc/GetTime.3109
-rwxr-xr-xlibrary/msgcat/doc/GetVersion.348
-rw-r--r--library/msgcat/doc/Hash.3334
-rw-r--r--library/msgcat/doc/Init.334
-rw-r--r--library/msgcat/doc/InitStubs.389
-rw-r--r--library/msgcat/doc/IntObj.3151
-rw-r--r--library/msgcat/doc/Interp.3134
-rw-r--r--library/msgcat/doc/Limit.3192
-rw-r--r--library/msgcat/doc/LinkVar.3207
-rw-r--r--library/msgcat/doc/ListObj.3250
-rw-r--r--library/msgcat/doc/Load.369
-rw-r--r--library/msgcat/doc/Method.3248
-rw-r--r--library/msgcat/doc/NRE.3328
-rw-r--r--library/msgcat/doc/Namespace.3165
-rw-r--r--library/msgcat/doc/Notifier.3635
-rw-r--r--library/msgcat/doc/Object.3350
-rw-r--r--library/msgcat/doc/ObjectType.3255
-rw-r--r--library/msgcat/doc/OpenFileChnl.3648
-rw-r--r--library/msgcat/doc/OpenTcp.3169
-rw-r--r--library/msgcat/doc/Panic.389
-rw-r--r--library/msgcat/doc/ParseArgs.3198
-rw-r--r--library/msgcat/doc/ParseCmd.3467
-rw-r--r--library/msgcat/doc/PkgRequire.397
-rw-r--r--library/msgcat/doc/Preserve.3110
-rw-r--r--library/msgcat/doc/PrintDbl.351
-rw-r--r--library/msgcat/doc/RecEvalObj.353
-rw-r--r--library/msgcat/doc/RecordEval.355
-rw-r--r--library/msgcat/doc/RegConfig.3111
-rw-r--r--library/msgcat/doc/RegExp.3383
-rw-r--r--library/msgcat/doc/SaveResult.3120
-rw-r--r--library/msgcat/doc/SetChanErr.3140
-rw-r--r--library/msgcat/doc/SetErrno.366
-rw-r--r--library/msgcat/doc/SetRecLmt.353
-rw-r--r--library/msgcat/doc/SetResult.3255
-rw-r--r--library/msgcat/doc/SetVar.3249
-rw-r--r--library/msgcat/doc/Signal.341
-rw-r--r--library/msgcat/doc/Sleep.334
-rw-r--r--library/msgcat/doc/SourceRCFile.332
-rw-r--r--library/msgcat/doc/SplitList.3188
-rw-r--r--library/msgcat/doc/SplitPath.397
-rw-r--r--library/msgcat/doc/StaticPkg.370
-rw-r--r--library/msgcat/doc/StdChannels.3120
-rw-r--r--library/msgcat/doc/StrMatch.349
-rw-r--r--library/msgcat/doc/StringObj.3384
-rw-r--r--library/msgcat/doc/SubstObj.368
-rw-r--r--library/msgcat/doc/TCL_MEM_DEBUG.380
-rw-r--r--library/msgcat/doc/Tcl.n270
-rw-r--r--library/msgcat/doc/TclZlib.3248
-rw-r--r--library/msgcat/doc/Tcl_Main.3196
-rw-r--r--library/msgcat/doc/Thread.3241
-rw-r--r--library/msgcat/doc/ToUpper.388
-rw-r--r--library/msgcat/doc/TraceCmd.3163
-rw-r--r--library/msgcat/doc/TraceVar.3380
-rw-r--r--library/msgcat/doc/Translate.371
-rw-r--r--library/msgcat/doc/UniCharIsAlpha.391
-rw-r--r--library/msgcat/doc/UpVar.374
-rw-r--r--library/msgcat/doc/Utf.3259
-rw-r--r--library/msgcat/doc/WrongNumArgs.379
-rw-r--r--library/msgcat/doc/after.n151
-rw-r--r--library/msgcat/doc/append.n49
-rw-r--r--library/msgcat/doc/apply.n102
-rw-r--r--library/msgcat/doc/array.n187
-rw-r--r--library/msgcat/doc/bgerror.n90
-rw-r--r--library/msgcat/doc/binary.n892
-rw-r--r--library/msgcat/doc/break.n47
-rw-r--r--library/msgcat/doc/case.n60
-rw-r--r--library/msgcat/doc/catch.n124
-rw-r--r--library/msgcat/doc/cd.n43
-rw-r--r--library/msgcat/doc/chan.n836
-rw-r--r--library/msgcat/doc/class.n136
-rw-r--r--library/msgcat/doc/clock.n937
-rw-r--r--library/msgcat/doc/close.n108
-rw-r--r--library/msgcat/doc/concat.n58
-rw-r--r--library/msgcat/doc/continue.n47
-rw-r--r--library/msgcat/doc/copy.n66
-rw-r--r--library/msgcat/doc/coroutine.n205
-rw-r--r--library/msgcat/doc/dde.n184
-rw-r--r--library/msgcat/doc/define.n404
-rw-r--r--library/msgcat/doc/dict.n416
-rw-r--r--library/msgcat/doc/encoding.n95
-rw-r--r--library/msgcat/doc/eof.n61
-rw-r--r--library/msgcat/doc/error.n78
-rw-r--r--library/msgcat/doc/eval.n83
-rw-r--r--library/msgcat/doc/exec.n516
-rw-r--r--library/msgcat/doc/exit.n51
-rw-r--r--library/msgcat/doc/expr.n463
-rw-r--r--library/msgcat/doc/fblocked.n67
-rw-r--r--library/msgcat/doc/fconfigure.n289
-rw-r--r--library/msgcat/doc/fcopy.n155
-rw-r--r--library/msgcat/doc/file.n543
-rw-r--r--library/msgcat/doc/fileevent.n153
-rw-r--r--library/msgcat/doc/filename.n178
-rw-r--r--library/msgcat/doc/flush.n45
-rw-r--r--library/msgcat/doc/for.n87
-rw-r--r--library/msgcat/doc/foreach.n104
-rw-r--r--library/msgcat/doc/format.n285
-rw-r--r--library/msgcat/doc/gets.n71
-rw-r--r--library/msgcat/doc/glob.n273
-rw-r--r--library/msgcat/doc/global.n58
-rw-r--r--library/msgcat/doc/history.n102
-rw-r--r--library/msgcat/doc/http.n646
-rw-r--r--library/msgcat/doc/if.n88
-rw-r--r--library/msgcat/doc/incr.n61
-rw-r--r--library/msgcat/doc/info.n777
-rw-r--r--library/msgcat/doc/interp.n910
-rw-r--r--library/msgcat/doc/join.n44
-rw-r--r--library/msgcat/doc/lappend.n49
-rw-r--r--library/msgcat/doc/lassign.n60
-rw-r--r--library/msgcat/doc/library.n314
-rw-r--r--library/msgcat/doc/lindex.n125
-rw-r--r--library/msgcat/doc/linsert.n55
-rw-r--r--library/msgcat/doc/list.n56
-rw-r--r--library/msgcat/doc/llength.n55
-rw-r--r--library/msgcat/doc/load.n180
-rw-r--r--library/msgcat/doc/lrange.n78
-rw-r--r--library/msgcat/doc/lrepeat.n38
-rw-r--r--library/msgcat/doc/lreplace.n86
-rw-r--r--library/msgcat/doc/lreverse.n34
-rw-r--r--library/msgcat/doc/lsearch.n220
-rwxr-xr-xlibrary/msgcat/doc/lset.n146
-rw-r--r--library/msgcat/doc/lsort.n274
-rw-r--r--library/msgcat/doc/man.macros267
-rw-r--r--library/msgcat/doc/mathfunc.n305
-rw-r--r--library/msgcat/doc/mathop.n310
-rw-r--r--library/msgcat/doc/memory.n115
-rw-r--r--library/msgcat/doc/msgcat.n355
-rw-r--r--library/msgcat/doc/my.n56
-rw-r--r--library/msgcat/doc/namespace.n969
-rw-r--r--library/msgcat/doc/next.n203
-rw-r--r--library/msgcat/doc/object.n128
-rw-r--r--library/msgcat/doc/open.n465
-rw-r--r--library/msgcat/doc/package.n370
-rw-r--r--library/msgcat/doc/packagens.n50
-rw-r--r--library/msgcat/doc/pid.n48
-rw-r--r--library/msgcat/doc/pkgMkIndex.n233
-rw-r--r--library/msgcat/doc/platform.n86
-rw-r--r--library/msgcat/doc/platform_shell.n57
-rw-r--r--library/msgcat/doc/prefix.n116
-rw-r--r--library/msgcat/doc/proc.n110
-rw-r--r--library/msgcat/doc/puts.n98
-rw-r--r--library/msgcat/doc/pwd.n39
-rw-r--r--library/msgcat/doc/re_syntax.n834
-rw-r--r--library/msgcat/doc/read.n89
-rw-r--r--library/msgcat/doc/refchan.n411
-rw-r--r--library/msgcat/doc/regexp.n208
-rw-r--r--library/msgcat/doc/registry.n218
-rw-r--r--library/msgcat/doc/regsub.n192
-rw-r--r--library/msgcat/doc/rename.n45
-rw-r--r--library/msgcat/doc/return.n326
-rw-r--r--library/msgcat/doc/safe.n359
-rw-r--r--library/msgcat/doc/scan.n293
-rw-r--r--library/msgcat/doc/seek.n92
-rw-r--r--library/msgcat/doc/self.n152
-rw-r--r--library/msgcat/doc/set.n75
-rw-r--r--library/msgcat/doc/socket.n227
-rw-r--r--library/msgcat/doc/source.n69
-rw-r--r--library/msgcat/doc/split.n93
-rw-r--r--library/msgcat/doc/string.n441
-rw-r--r--library/msgcat/doc/subst.n164
-rw-r--r--library/msgcat/doc/switch.n186
-rw-r--r--library/msgcat/doc/tailcall.n69
-rw-r--r--library/msgcat/doc/tclsh.1147
-rw-r--r--library/msgcat/doc/tcltest.n1257
-rw-r--r--library/msgcat/doc/tclvars.n566
-rw-r--r--library/msgcat/doc/tell.n48
-rw-r--r--library/msgcat/doc/throw.n48
-rw-r--r--library/msgcat/doc/time.n47
-rw-r--r--library/msgcat/doc/tm.n308
-rw-r--r--library/msgcat/doc/trace.n426
-rw-r--r--library/msgcat/doc/transchan.n160
-rw-r--r--library/msgcat/doc/try.n103
-rw-r--r--library/msgcat/doc/unknown.n91
-rw-r--r--library/msgcat/doc/unload.n172
-rw-r--r--library/msgcat/doc/unset.n68
-rw-r--r--library/msgcat/doc/update.n65
-rw-r--r--library/msgcat/doc/uplevel.n103
-rw-r--r--library/msgcat/doc/upvar.n122
-rw-r--r--library/msgcat/doc/variable.n100
-rw-r--r--library/msgcat/doc/vwait.n246
-rw-r--r--library/msgcat/doc/while.n65
-rw-r--r--library/msgcat/doc/zlib.n391
-rw-r--r--library/msgcat/tests/README107
-rw-r--r--library/msgcat/tests/all.tcl19
-rw-r--r--library/msgcat/tests/append.test306
-rw-r--r--library/msgcat/tests/appendComp.test455
-rw-r--r--library/msgcat/tests/apply.test321
-rw-r--r--library/msgcat/tests/assemble.test3293
-rw-r--r--library/msgcat/tests/assemble1.bench85
-rw-r--r--library/msgcat/tests/assocd.test61
-rw-r--r--library/msgcat/tests/async.test213
-rw-r--r--library/msgcat/tests/autoMkindex.test340
-rw-r--r--library/msgcat/tests/basic.test974
-rw-r--r--library/msgcat/tests/binary.test2781
-rw-r--r--library/msgcat/tests/case.test89
-rw-r--r--library/msgcat/tests/chan.test275
-rw-r--r--library/msgcat/tests/chanio.test7716
-rw-r--r--library/msgcat/tests/clock.test36941
-rw-r--r--library/msgcat/tests/cmdAH.test1578
-rw-r--r--library/msgcat/tests/cmdIL.test723
-rw-r--r--library/msgcat/tests/cmdInfo.test106
-rw-r--r--library/msgcat/tests/cmdMZ.test355
-rw-r--r--library/msgcat/tests/compExpr-old.test674
-rw-r--r--library/msgcat/tests/compExpr.test393
-rw-r--r--library/msgcat/tests/compile.test721
-rw-r--r--library/msgcat/tests/concat.test57
-rw-r--r--library/msgcat/tests/config.test60
-rw-r--r--library/msgcat/tests/coroutine.test618
-rw-r--r--library/msgcat/tests/dcall.test42
-rw-r--r--library/msgcat/tests/dict.test1531
-rw-r--r--library/msgcat/tests/dstring.test436
-rw-r--r--library/msgcat/tests/encoding.test597
-rw-r--r--library/msgcat/tests/env.test308
-rw-r--r--library/msgcat/tests/error.test1061
-rw-r--r--library/msgcat/tests/eval.test89
-rw-r--r--library/msgcat/tests/event.test921
-rw-r--r--library/msgcat/tests/exec.test699
-rw-r--r--library/msgcat/tests/execute.test1062
-rw-r--r--library/msgcat/tests/expr-old.test1207
-rw-r--r--library/msgcat/tests/expr.test7187
-rw-r--r--library/msgcat/tests/fCmd.test2601
-rw-r--r--library/msgcat/tests/fileName.test1627
-rw-r--r--library/msgcat/tests/fileSystem.test935
-rw-r--r--library/msgcat/tests/for-old.test71
-rw-r--r--library/msgcat/tests/for.test830
-rw-r--r--library/msgcat/tests/foreach.test274
-rw-r--r--library/msgcat/tests/format.test584
-rw-r--r--library/msgcat/tests/get.test98
-rw-r--r--library/msgcat/tests/history.test250
-rw-r--r--library/msgcat/tests/http.test632
-rw-r--r--library/msgcat/tests/http11.test656
-rw-r--r--library/msgcat/tests/httpd236
-rw-r--r--library/msgcat/tests/httpd11.tcl254
-rw-r--r--library/msgcat/tests/httpold.test293
-rw-r--r--library/msgcat/tests/if-old.test162
-rw-r--r--library/msgcat/tests/if.test1282
-rw-r--r--library/msgcat/tests/incr-old.test92
-rw-r--r--library/msgcat/tests/incr.test522
-rw-r--r--library/msgcat/tests/indexObj.test163
-rw-r--r--library/msgcat/tests/info.test1964
-rw-r--r--library/msgcat/tests/init.test195
-rw-r--r--library/msgcat/tests/interp.test3630
-rw-r--r--library/msgcat/tests/io.test7797
-rw-r--r--library/msgcat/tests/ioCmd.test3741
-rw-r--r--library/msgcat/tests/ioTrans.test1864
-rw-r--r--library/msgcat/tests/iogt.test802
-rw-r--r--library/msgcat/tests/join.test55
-rw-r--r--library/msgcat/tests/lindex.test455
-rw-r--r--library/msgcat/tests/link.test307
-rw-r--r--library/msgcat/tests/linsert.test119
-rw-r--r--library/msgcat/tests/list.test134
-rw-r--r--library/msgcat/tests/listObj.test202
-rw-r--r--library/msgcat/tests/llength.test41
-rw-r--r--library/msgcat/tests/load.test217
-rw-r--r--library/msgcat/tests/lrange.test88
-rw-r--r--library/msgcat/tests/lrepeat.test84
-rw-r--r--library/msgcat/tests/lreplace.test136
-rw-r--r--library/msgcat/tests/lsearch.test528
-rw-r--r--library/msgcat/tests/lset.test478
-rwxr-xr-xlibrary/msgcat/tests/lsetComp.test431
-rw-r--r--library/msgcat/tests/macOSXFCmd.test181
-rw-r--r--library/msgcat/tests/macOSXLoad.test33
-rw-r--r--library/msgcat/tests/main.test1297
-rw-r--r--library/msgcat/tests/mathop.test1340
-rw-r--r--library/msgcat/tests/misc.test76
-rw-r--r--library/msgcat/tests/msgcat.test618
-rw-r--r--library/msgcat/tests/namespace-old.test750
-rw-r--r--library/msgcat/tests/namespace.test2944
-rwxr-xr-xlibrary/msgcat/tests/notify.test324
-rw-r--r--library/msgcat/tests/nre.test445
-rw-r--r--library/msgcat/tests/obj.test632
-rw-r--r--library/msgcat/tests/oo.test3364
-rw-r--r--library/msgcat/tests/ooNext2.test790
-rw-r--r--library/msgcat/tests/opt.test245
-rw-r--r--library/msgcat/tests/package.test1279
-rw-r--r--library/msgcat/tests/parse.test1094
-rw-r--r--library/msgcat/tests/parseExpr.test1068
-rw-r--r--library/msgcat/tests/parseOld.test543
-rw-r--r--library/msgcat/tests/pid.test57
-rw-r--r--library/msgcat/tests/pkgMkIndex.test700
-rw-r--r--library/msgcat/tests/platform.test59
-rw-r--r--library/msgcat/tests/proc-old.test517
-rw-r--r--library/msgcat/tests/proc.test396
-rw-r--r--library/msgcat/tests/pwd.test31
-rw-r--r--library/msgcat/tests/reg.test1087
-rw-r--r--library/msgcat/tests/regexp.test1072
-rw-r--r--library/msgcat/tests/regexpComp.test992
-rw-r--r--library/msgcat/tests/registry.test691
-rw-r--r--library/msgcat/tests/remote.tcl159
-rw-r--r--library/msgcat/tests/rename.test182
-rw-r--r--library/msgcat/tests/resolver.test200
-rw-r--r--library/msgcat/tests/result.test146
-rw-r--r--library/msgcat/tests/safe.test774
-rw-r--r--library/msgcat/tests/scan.test773
-rw-r--r--library/msgcat/tests/security.test45
-rw-r--r--library/msgcat/tests/set-old.test928
-rw-r--r--library/msgcat/tests/set.test531
-rw-r--r--library/msgcat/tests/socket.test1860
-rw-r--r--library/msgcat/tests/source.test302
-rw-r--r--library/msgcat/tests/split.test88
-rw-r--r--library/msgcat/tests/stack.test64
-rw-r--r--library/msgcat/tests/string.test1966
-rw-r--r--library/msgcat/tests/stringComp.test703
-rw-r--r--library/msgcat/tests/stringObj.test487
-rw-r--r--library/msgcat/tests/subst.test303
-rw-r--r--library/msgcat/tests/switch.test772
-rw-r--r--library/msgcat/tests/tailcall.test663
-rwxr-xr-xlibrary/msgcat/tests/tcltest.test1837
-rw-r--r--library/msgcat/tests/thread.test1436
-rw-r--r--library/msgcat/tests/timer.test605
-rw-r--r--library/msgcat/tests/tm.test245
-rw-r--r--library/msgcat/tests/trace.test2639
-rw-r--r--library/msgcat/tests/unixFCmd.test437
-rw-r--r--library/msgcat/tests/unixFile.test62
-rw-r--r--library/msgcat/tests/unixInit.test402
-rw-r--r--library/msgcat/tests/unixNotfy.test102
-rw-r--r--library/msgcat/tests/unknown.test67
-rw-r--r--library/msgcat/tests/unload.test242
-rw-r--r--library/msgcat/tests/uplevel.test206
-rw-r--r--library/msgcat/tests/upvar.test543
-rw-r--r--library/msgcat/tests/utf.test445
-rw-r--r--library/msgcat/tests/util.test4024
-rw-r--r--library/msgcat/tests/var.test815
-rw-r--r--library/msgcat/tests/while-old.test119
-rw-r--r--library/msgcat/tests/while.test702
-rw-r--r--library/msgcat/tests/winConsole.test48
-rw-r--r--library/msgcat/tests/winDde.test471
-rw-r--r--library/msgcat/tests/winFCmd.test1549
-rw-r--r--library/msgcat/tests/winFile.test239
-rw-r--r--library/msgcat/tests/winNotify.test159
-rw-r--r--library/msgcat/tests/winPipe.test450
-rw-r--r--library/msgcat/tests/winTime.test63
-rw-r--r--library/msgcat/tests/zlib.test672
-rw-r--r--pkgs/msgcat/Makefile.in86
-rwxr-xr-xpkgs/msgcat/configure2128
-rw-r--r--pkgs/msgcat/configure.in2
-rw-r--r--pkgs/msgcat/configure.make10
-rw-r--r--pkgs/msgcat/doc/Access.371
-rw-r--r--pkgs/msgcat/doc/AddErrInfo.3312
-rw-r--r--pkgs/msgcat/doc/Alloc.392
-rw-r--r--pkgs/msgcat/doc/AllowExc.344
-rw-r--r--pkgs/msgcat/doc/AppInit.383
-rw-r--r--pkgs/msgcat/doc/AssocData.387
-rw-r--r--pkgs/msgcat/doc/Async.3161
-rw-r--r--pkgs/msgcat/doc/BackgdErr.378
-rw-r--r--pkgs/msgcat/doc/Backslash.347
-rw-r--r--pkgs/msgcat/doc/BoolObj.395
-rw-r--r--pkgs/msgcat/doc/ByteArrObj.391
-rw-r--r--pkgs/msgcat/doc/CallDel.367
-rw-r--r--pkgs/msgcat/doc/Cancel.366
-rw-r--r--pkgs/msgcat/doc/ChnlStack.397
-rw-r--r--pkgs/msgcat/doc/Class.3236
-rw-r--r--pkgs/msgcat/doc/CmdCmplt.334
-rw-r--r--pkgs/msgcat/doc/Concat.351
-rw-r--r--pkgs/msgcat/doc/CrtChannel.3928
-rw-r--r--pkgs/msgcat/doc/CrtChnlHdlr.389
-rw-r--r--pkgs/msgcat/doc/CrtCloseHdlr.355
-rw-r--r--pkgs/msgcat/doc/CrtCommand.3143
-rw-r--r--pkgs/msgcat/doc/CrtFileHdlr.391
-rw-r--r--pkgs/msgcat/doc/CrtInterp.3149
-rw-r--r--pkgs/msgcat/doc/CrtMathFnc.3155
-rw-r--r--pkgs/msgcat/doc/CrtObjCmd.3302
-rw-r--r--pkgs/msgcat/doc/CrtSlave.3236
-rw-r--r--pkgs/msgcat/doc/CrtTimerHdlr.376
-rw-r--r--pkgs/msgcat/doc/CrtTrace.3191
-rw-r--r--pkgs/msgcat/doc/DString.3153
-rw-r--r--pkgs/msgcat/doc/DetachPids.375
-rw-r--r--pkgs/msgcat/doc/DictObj.3234
-rw-r--r--pkgs/msgcat/doc/DoOneEvent.3106
-rw-r--r--pkgs/msgcat/doc/DoWhenIdle.387
-rw-r--r--pkgs/msgcat/doc/DoubleObj.364
-rw-r--r--pkgs/msgcat/doc/DumpActiveMemory.368
-rw-r--r--pkgs/msgcat/doc/Encoding.3592
-rw-r--r--pkgs/msgcat/doc/Ensemble.3219
-rw-r--r--pkgs/msgcat/doc/Environment.338
-rw-r--r--pkgs/msgcat/doc/Eval.3211
-rw-r--r--pkgs/msgcat/doc/Exit.3140
-rw-r--r--pkgs/msgcat/doc/ExprLong.3106
-rw-r--r--pkgs/msgcat/doc/ExprLongObj.3106
-rw-r--r--pkgs/msgcat/doc/FileSystem.31643
-rw-r--r--pkgs/msgcat/doc/FindExec.363
-rwxr-xr-xpkgs/msgcat/doc/GetCwd.352
-rw-r--r--pkgs/msgcat/doc/GetHostName.327
-rw-r--r--pkgs/msgcat/doc/GetIndex.398
-rw-r--r--pkgs/msgcat/doc/GetInt.386
-rw-r--r--pkgs/msgcat/doc/GetOpnFl.358
-rw-r--r--pkgs/msgcat/doc/GetStdChan.386
-rw-r--r--pkgs/msgcat/doc/GetTime.3109
-rwxr-xr-xpkgs/msgcat/doc/GetVersion.348
-rw-r--r--pkgs/msgcat/doc/Hash.3334
-rw-r--r--pkgs/msgcat/doc/Init.334
-rw-r--r--pkgs/msgcat/doc/InitStubs.389
-rw-r--r--pkgs/msgcat/doc/IntObj.3151
-rw-r--r--pkgs/msgcat/doc/Interp.3134
-rw-r--r--pkgs/msgcat/doc/Limit.3192
-rw-r--r--pkgs/msgcat/doc/LinkVar.3207
-rw-r--r--pkgs/msgcat/doc/ListObj.3250
-rw-r--r--pkgs/msgcat/doc/Load.369
-rw-r--r--pkgs/msgcat/doc/Method.3248
-rw-r--r--pkgs/msgcat/doc/NRE.3328
-rw-r--r--pkgs/msgcat/doc/Namespace.3165
-rw-r--r--pkgs/msgcat/doc/Notifier.3635
-rw-r--r--pkgs/msgcat/doc/Object.3350
-rw-r--r--pkgs/msgcat/doc/ObjectType.3255
-rw-r--r--pkgs/msgcat/doc/OpenFileChnl.3648
-rw-r--r--pkgs/msgcat/doc/OpenTcp.3169
-rw-r--r--pkgs/msgcat/doc/Panic.389
-rw-r--r--pkgs/msgcat/doc/ParseArgs.3198
-rw-r--r--pkgs/msgcat/doc/ParseCmd.3467
-rw-r--r--pkgs/msgcat/doc/PkgRequire.397
-rw-r--r--pkgs/msgcat/doc/Preserve.3110
-rw-r--r--pkgs/msgcat/doc/PrintDbl.351
-rw-r--r--pkgs/msgcat/doc/RecEvalObj.353
-rw-r--r--pkgs/msgcat/doc/RecordEval.355
-rw-r--r--pkgs/msgcat/doc/RegConfig.3111
-rw-r--r--pkgs/msgcat/doc/RegExp.3383
-rw-r--r--pkgs/msgcat/doc/SaveResult.3120
-rw-r--r--pkgs/msgcat/doc/SetChanErr.3140
-rw-r--r--pkgs/msgcat/doc/SetErrno.366
-rw-r--r--pkgs/msgcat/doc/SetRecLmt.353
-rw-r--r--pkgs/msgcat/doc/SetResult.3255
-rw-r--r--pkgs/msgcat/doc/SetVar.3249
-rw-r--r--pkgs/msgcat/doc/Signal.341
-rw-r--r--pkgs/msgcat/doc/Sleep.334
-rw-r--r--pkgs/msgcat/doc/SourceRCFile.332
-rw-r--r--pkgs/msgcat/doc/SplitList.3188
-rw-r--r--pkgs/msgcat/doc/SplitPath.397
-rw-r--r--pkgs/msgcat/doc/StaticPkg.370
-rw-r--r--pkgs/msgcat/doc/StdChannels.3120
-rw-r--r--pkgs/msgcat/doc/StrMatch.349
-rw-r--r--pkgs/msgcat/doc/StringObj.3384
-rw-r--r--pkgs/msgcat/doc/SubstObj.368
-rw-r--r--pkgs/msgcat/doc/TCL_MEM_DEBUG.380
-rw-r--r--pkgs/msgcat/doc/Tcl.n270
-rw-r--r--pkgs/msgcat/doc/TclZlib.3248
-rw-r--r--pkgs/msgcat/doc/Tcl_Main.3196
-rw-r--r--pkgs/msgcat/doc/Thread.3241
-rw-r--r--pkgs/msgcat/doc/ToUpper.388
-rw-r--r--pkgs/msgcat/doc/TraceCmd.3163
-rw-r--r--pkgs/msgcat/doc/TraceVar.3380
-rw-r--r--pkgs/msgcat/doc/Translate.371
-rw-r--r--pkgs/msgcat/doc/UniCharIsAlpha.391
-rw-r--r--pkgs/msgcat/doc/UpVar.374
-rw-r--r--pkgs/msgcat/doc/Utf.3259
-rw-r--r--pkgs/msgcat/doc/WrongNumArgs.379
-rw-r--r--pkgs/msgcat/doc/after.n151
-rw-r--r--pkgs/msgcat/doc/append.n49
-rw-r--r--pkgs/msgcat/doc/apply.n102
-rw-r--r--pkgs/msgcat/doc/array.n187
-rw-r--r--pkgs/msgcat/doc/bgerror.n90
-rw-r--r--pkgs/msgcat/doc/binary.n892
-rw-r--r--pkgs/msgcat/doc/break.n47
-rw-r--r--pkgs/msgcat/doc/case.n60
-rw-r--r--pkgs/msgcat/doc/catch.n124
-rw-r--r--pkgs/msgcat/doc/cd.n43
-rw-r--r--pkgs/msgcat/doc/chan.n836
-rw-r--r--pkgs/msgcat/doc/class.n136
-rw-r--r--pkgs/msgcat/doc/clock.n937
-rw-r--r--pkgs/msgcat/doc/close.n108
-rw-r--r--pkgs/msgcat/doc/concat.n58
-rw-r--r--pkgs/msgcat/doc/continue.n47
-rw-r--r--pkgs/msgcat/doc/copy.n66
-rw-r--r--pkgs/msgcat/doc/coroutine.n205
-rw-r--r--pkgs/msgcat/doc/dde.n184
-rw-r--r--pkgs/msgcat/doc/define.n404
-rw-r--r--pkgs/msgcat/doc/dict.n416
-rw-r--r--pkgs/msgcat/doc/encoding.n95
-rw-r--r--pkgs/msgcat/doc/eof.n61
-rw-r--r--pkgs/msgcat/doc/error.n78
-rw-r--r--pkgs/msgcat/doc/eval.n83
-rw-r--r--pkgs/msgcat/doc/exec.n516
-rw-r--r--pkgs/msgcat/doc/exit.n51
-rw-r--r--pkgs/msgcat/doc/expr.n463
-rw-r--r--pkgs/msgcat/doc/fblocked.n67
-rw-r--r--pkgs/msgcat/doc/fconfigure.n289
-rw-r--r--pkgs/msgcat/doc/fcopy.n155
-rw-r--r--pkgs/msgcat/doc/file.n543
-rw-r--r--pkgs/msgcat/doc/fileevent.n153
-rw-r--r--pkgs/msgcat/doc/filename.n178
-rw-r--r--pkgs/msgcat/doc/flush.n45
-rw-r--r--pkgs/msgcat/doc/for.n87
-rw-r--r--pkgs/msgcat/doc/foreach.n104
-rw-r--r--pkgs/msgcat/doc/format.n285
-rw-r--r--pkgs/msgcat/doc/gets.n71
-rw-r--r--pkgs/msgcat/doc/glob.n273
-rw-r--r--pkgs/msgcat/doc/global.n58
-rw-r--r--pkgs/msgcat/doc/history.n102
-rw-r--r--pkgs/msgcat/doc/http.n646
-rw-r--r--pkgs/msgcat/doc/if.n88
-rw-r--r--pkgs/msgcat/doc/incr.n61
-rw-r--r--pkgs/msgcat/doc/info.n777
-rw-r--r--pkgs/msgcat/doc/interp.n910
-rw-r--r--pkgs/msgcat/doc/join.n44
-rw-r--r--pkgs/msgcat/doc/lappend.n49
-rw-r--r--pkgs/msgcat/doc/lassign.n60
-rw-r--r--pkgs/msgcat/doc/library.n314
-rw-r--r--pkgs/msgcat/doc/lindex.n125
-rw-r--r--pkgs/msgcat/doc/linsert.n55
-rw-r--r--pkgs/msgcat/doc/list.n56
-rw-r--r--pkgs/msgcat/doc/llength.n55
-rw-r--r--pkgs/msgcat/doc/load.n180
-rw-r--r--pkgs/msgcat/doc/lrange.n78
-rw-r--r--pkgs/msgcat/doc/lrepeat.n38
-rw-r--r--pkgs/msgcat/doc/lreplace.n86
-rw-r--r--pkgs/msgcat/doc/lreverse.n34
-rw-r--r--pkgs/msgcat/doc/lsearch.n220
-rwxr-xr-xpkgs/msgcat/doc/lset.n146
-rw-r--r--pkgs/msgcat/doc/lsort.n274
-rw-r--r--pkgs/msgcat/doc/man.macros267
-rw-r--r--pkgs/msgcat/doc/mathfunc.n305
-rw-r--r--pkgs/msgcat/doc/mathop.n310
-rw-r--r--pkgs/msgcat/doc/memory.n115
-rw-r--r--pkgs/msgcat/doc/msgcat.n355
-rw-r--r--pkgs/msgcat/doc/my.n56
-rw-r--r--pkgs/msgcat/doc/namespace.n969
-rw-r--r--pkgs/msgcat/doc/next.n203
-rw-r--r--pkgs/msgcat/doc/object.n128
-rw-r--r--pkgs/msgcat/doc/open.n465
-rw-r--r--pkgs/msgcat/doc/package.n370
-rw-r--r--pkgs/msgcat/doc/packagens.n50
-rw-r--r--pkgs/msgcat/doc/pid.n48
-rw-r--r--pkgs/msgcat/doc/pkgMkIndex.n233
-rw-r--r--pkgs/msgcat/doc/platform.n86
-rw-r--r--pkgs/msgcat/doc/platform_shell.n57
-rw-r--r--pkgs/msgcat/doc/prefix.n116
-rw-r--r--pkgs/msgcat/doc/proc.n110
-rw-r--r--pkgs/msgcat/doc/puts.n98
-rw-r--r--pkgs/msgcat/doc/pwd.n39
-rw-r--r--pkgs/msgcat/doc/re_syntax.n834
-rw-r--r--pkgs/msgcat/doc/read.n89
-rw-r--r--pkgs/msgcat/doc/refchan.n411
-rw-r--r--pkgs/msgcat/doc/regexp.n208
-rw-r--r--pkgs/msgcat/doc/registry.n218
-rw-r--r--pkgs/msgcat/doc/regsub.n192
-rw-r--r--pkgs/msgcat/doc/rename.n45
-rw-r--r--pkgs/msgcat/doc/return.n326
-rw-r--r--pkgs/msgcat/doc/safe.n359
-rw-r--r--pkgs/msgcat/doc/scan.n293
-rw-r--r--pkgs/msgcat/doc/seek.n92
-rw-r--r--pkgs/msgcat/doc/self.n152
-rw-r--r--pkgs/msgcat/doc/set.n75
-rw-r--r--pkgs/msgcat/doc/socket.n227
-rw-r--r--pkgs/msgcat/doc/source.n69
-rw-r--r--pkgs/msgcat/doc/split.n93
-rw-r--r--pkgs/msgcat/doc/string.n441
-rw-r--r--pkgs/msgcat/doc/subst.n164
-rw-r--r--pkgs/msgcat/doc/switch.n186
-rw-r--r--pkgs/msgcat/doc/tailcall.n69
-rw-r--r--pkgs/msgcat/doc/tclsh.1147
-rw-r--r--pkgs/msgcat/doc/tcltest.n1257
-rw-r--r--pkgs/msgcat/doc/tclvars.n566
-rw-r--r--pkgs/msgcat/doc/tell.n48
-rw-r--r--pkgs/msgcat/doc/throw.n48
-rw-r--r--pkgs/msgcat/doc/time.n47
-rw-r--r--pkgs/msgcat/doc/tm.n308
-rw-r--r--pkgs/msgcat/doc/trace.n426
-rw-r--r--pkgs/msgcat/doc/transchan.n160
-rw-r--r--pkgs/msgcat/doc/try.n103
-rw-r--r--pkgs/msgcat/doc/unknown.n91
-rw-r--r--pkgs/msgcat/doc/unload.n172
-rw-r--r--pkgs/msgcat/doc/unset.n68
-rw-r--r--pkgs/msgcat/doc/update.n65
-rw-r--r--pkgs/msgcat/doc/uplevel.n103
-rw-r--r--pkgs/msgcat/doc/upvar.n122
-rw-r--r--pkgs/msgcat/doc/variable.n100
-rw-r--r--pkgs/msgcat/doc/vwait.n246
-rw-r--r--pkgs/msgcat/doc/while.n65
-rw-r--r--pkgs/msgcat/doc/zlib.n391
-rw-r--r--pkgs/msgcat/msgcat.tcl497
-rw-r--r--pkgs/msgcat/pkgIndex.tcl2
-rw-r--r--pkgs/msgcat/tests/README107
-rw-r--r--pkgs/msgcat/tests/all.tcl19
-rw-r--r--pkgs/msgcat/tests/append.test306
-rw-r--r--pkgs/msgcat/tests/appendComp.test455
-rw-r--r--pkgs/msgcat/tests/apply.test321
-rw-r--r--pkgs/msgcat/tests/assemble.test3293
-rw-r--r--pkgs/msgcat/tests/assemble1.bench85
-rw-r--r--pkgs/msgcat/tests/assocd.test61
-rw-r--r--pkgs/msgcat/tests/async.test213
-rw-r--r--pkgs/msgcat/tests/autoMkindex.test340
-rw-r--r--pkgs/msgcat/tests/basic.test974
-rw-r--r--pkgs/msgcat/tests/binary.test2781
-rw-r--r--pkgs/msgcat/tests/case.test89
-rw-r--r--pkgs/msgcat/tests/chan.test275
-rw-r--r--pkgs/msgcat/tests/chanio.test7716
-rw-r--r--pkgs/msgcat/tests/clock.test36941
-rw-r--r--pkgs/msgcat/tests/cmdAH.test1578
-rw-r--r--pkgs/msgcat/tests/cmdIL.test723
-rw-r--r--pkgs/msgcat/tests/cmdInfo.test106
-rw-r--r--pkgs/msgcat/tests/cmdMZ.test355
-rw-r--r--pkgs/msgcat/tests/compExpr-old.test674
-rw-r--r--pkgs/msgcat/tests/compExpr.test393
-rw-r--r--pkgs/msgcat/tests/compile.test721
-rw-r--r--pkgs/msgcat/tests/concat.test57
-rw-r--r--pkgs/msgcat/tests/config.test60
-rw-r--r--pkgs/msgcat/tests/coroutine.test618
-rw-r--r--pkgs/msgcat/tests/dcall.test42
-rw-r--r--pkgs/msgcat/tests/dict.test1531
-rw-r--r--pkgs/msgcat/tests/dstring.test436
-rw-r--r--pkgs/msgcat/tests/encoding.test597
-rw-r--r--pkgs/msgcat/tests/env.test308
-rw-r--r--pkgs/msgcat/tests/error.test1061
-rw-r--r--pkgs/msgcat/tests/eval.test89
-rw-r--r--pkgs/msgcat/tests/event.test921
-rw-r--r--pkgs/msgcat/tests/exec.test699
-rw-r--r--pkgs/msgcat/tests/execute.test1062
-rw-r--r--pkgs/msgcat/tests/expr-old.test1207
-rw-r--r--pkgs/msgcat/tests/expr.test7187
-rw-r--r--pkgs/msgcat/tests/fCmd.test2601
-rw-r--r--pkgs/msgcat/tests/fileName.test1627
-rw-r--r--pkgs/msgcat/tests/fileSystem.test935
-rw-r--r--pkgs/msgcat/tests/for-old.test71
-rw-r--r--pkgs/msgcat/tests/for.test830
-rw-r--r--pkgs/msgcat/tests/foreach.test274
-rw-r--r--pkgs/msgcat/tests/format.test584
-rw-r--r--pkgs/msgcat/tests/get.test98
-rw-r--r--pkgs/msgcat/tests/history.test250
-rw-r--r--pkgs/msgcat/tests/http.test632
-rw-r--r--pkgs/msgcat/tests/http11.test656
-rw-r--r--pkgs/msgcat/tests/httpd236
-rw-r--r--pkgs/msgcat/tests/httpd11.tcl254
-rw-r--r--pkgs/msgcat/tests/httpold.test293
-rw-r--r--pkgs/msgcat/tests/if-old.test162
-rw-r--r--pkgs/msgcat/tests/if.test1282
-rw-r--r--pkgs/msgcat/tests/incr-old.test92
-rw-r--r--pkgs/msgcat/tests/incr.test522
-rw-r--r--pkgs/msgcat/tests/indexObj.test163
-rw-r--r--pkgs/msgcat/tests/info.test1964
-rw-r--r--pkgs/msgcat/tests/init.test195
-rw-r--r--pkgs/msgcat/tests/interp.test3630
-rw-r--r--pkgs/msgcat/tests/io.test7797
-rw-r--r--pkgs/msgcat/tests/ioCmd.test3741
-rw-r--r--pkgs/msgcat/tests/ioTrans.test1864
-rw-r--r--pkgs/msgcat/tests/iogt.test802
-rw-r--r--pkgs/msgcat/tests/join.test55
-rw-r--r--pkgs/msgcat/tests/lindex.test455
-rw-r--r--pkgs/msgcat/tests/link.test307
-rw-r--r--pkgs/msgcat/tests/linsert.test119
-rw-r--r--pkgs/msgcat/tests/list.test134
-rw-r--r--pkgs/msgcat/tests/listObj.test202
-rw-r--r--pkgs/msgcat/tests/llength.test41
-rw-r--r--pkgs/msgcat/tests/load.test217
-rw-r--r--pkgs/msgcat/tests/lrange.test88
-rw-r--r--pkgs/msgcat/tests/lrepeat.test84
-rw-r--r--pkgs/msgcat/tests/lreplace.test136
-rw-r--r--pkgs/msgcat/tests/lsearch.test528
-rw-r--r--pkgs/msgcat/tests/lset.test478
-rwxr-xr-xpkgs/msgcat/tests/lsetComp.test431
-rw-r--r--pkgs/msgcat/tests/macOSXFCmd.test181
-rw-r--r--pkgs/msgcat/tests/macOSXLoad.test33
-rw-r--r--pkgs/msgcat/tests/main.test1297
-rw-r--r--pkgs/msgcat/tests/mathop.test1340
-rw-r--r--pkgs/msgcat/tests/misc.test76
-rw-r--r--pkgs/msgcat/tests/msgcat.test618
-rw-r--r--pkgs/msgcat/tests/namespace-old.test750
-rw-r--r--pkgs/msgcat/tests/namespace.test2944
-rwxr-xr-xpkgs/msgcat/tests/notify.test324
-rw-r--r--pkgs/msgcat/tests/nre.test445
-rw-r--r--pkgs/msgcat/tests/obj.test632
-rw-r--r--pkgs/msgcat/tests/oo.test3364
-rw-r--r--pkgs/msgcat/tests/ooNext2.test790
-rw-r--r--pkgs/msgcat/tests/opt.test245
-rw-r--r--pkgs/msgcat/tests/package.test1279
-rw-r--r--pkgs/msgcat/tests/parse.test1094
-rw-r--r--pkgs/msgcat/tests/parseExpr.test1068
-rw-r--r--pkgs/msgcat/tests/parseOld.test543
-rw-r--r--pkgs/msgcat/tests/pid.test57
-rw-r--r--pkgs/msgcat/tests/pkgMkIndex.test700
-rw-r--r--pkgs/msgcat/tests/platform.test59
-rw-r--r--pkgs/msgcat/tests/proc-old.test517
-rw-r--r--pkgs/msgcat/tests/proc.test396
-rw-r--r--pkgs/msgcat/tests/pwd.test31
-rw-r--r--pkgs/msgcat/tests/reg.test1087
-rw-r--r--pkgs/msgcat/tests/regexp.test1072
-rw-r--r--pkgs/msgcat/tests/regexpComp.test992
-rw-r--r--pkgs/msgcat/tests/registry.test691
-rw-r--r--pkgs/msgcat/tests/remote.tcl159
-rw-r--r--pkgs/msgcat/tests/rename.test182
-rw-r--r--pkgs/msgcat/tests/resolver.test200
-rw-r--r--pkgs/msgcat/tests/result.test146
-rw-r--r--pkgs/msgcat/tests/safe.test774
-rw-r--r--pkgs/msgcat/tests/scan.test773
-rw-r--r--pkgs/msgcat/tests/security.test45
-rw-r--r--pkgs/msgcat/tests/set-old.test928
-rw-r--r--pkgs/msgcat/tests/set.test531
-rw-r--r--pkgs/msgcat/tests/socket.test1860
-rw-r--r--pkgs/msgcat/tests/source.test302
-rw-r--r--pkgs/msgcat/tests/split.test88
-rw-r--r--pkgs/msgcat/tests/stack.test64
-rw-r--r--pkgs/msgcat/tests/string.test1966
-rw-r--r--pkgs/msgcat/tests/stringComp.test703
-rw-r--r--pkgs/msgcat/tests/stringObj.test487
-rw-r--r--pkgs/msgcat/tests/subst.test303
-rw-r--r--pkgs/msgcat/tests/switch.test772
-rw-r--r--pkgs/msgcat/tests/tailcall.test663
-rwxr-xr-xpkgs/msgcat/tests/tcltest.test1837
-rw-r--r--pkgs/msgcat/tests/thread.test1436
-rw-r--r--pkgs/msgcat/tests/timer.test605
-rw-r--r--pkgs/msgcat/tests/tm.test245
-rw-r--r--pkgs/msgcat/tests/trace.test2639
-rw-r--r--pkgs/msgcat/tests/unixFCmd.test437
-rw-r--r--pkgs/msgcat/tests/unixFile.test62
-rw-r--r--pkgs/msgcat/tests/unixInit.test402
-rw-r--r--pkgs/msgcat/tests/unixNotfy.test102
-rw-r--r--pkgs/msgcat/tests/unknown.test67
-rw-r--r--pkgs/msgcat/tests/unload.test242
-rw-r--r--pkgs/msgcat/tests/uplevel.test206
-rw-r--r--pkgs/msgcat/tests/upvar.test543
-rw-r--r--pkgs/msgcat/tests/utf.test445
-rw-r--r--pkgs/msgcat/tests/util.test4024
-rw-r--r--pkgs/msgcat/tests/var.test815
-rw-r--r--pkgs/msgcat/tests/while-old.test119
-rw-r--r--pkgs/msgcat/tests/while.test702
-rw-r--r--pkgs/msgcat/tests/winConsole.test48
-rw-r--r--pkgs/msgcat/tests/winDde.test471
-rw-r--r--pkgs/msgcat/tests/winFCmd.test1549
-rw-r--r--pkgs/msgcat/tests/winFile.test239
-rw-r--r--pkgs/msgcat/tests/winNotify.test159
-rw-r--r--pkgs/msgcat/tests/winPipe.test450
-rw-r--r--pkgs/msgcat/tests/winTime.test63
-rw-r--r--pkgs/msgcat/tests/zlib.test672
774 files changed, 418363 insertions, 0 deletions
diff --git a/library/msgcat/Makefile.in b/library/msgcat/Makefile.in
new file mode 100644
index 0000000..cc60045
--- /dev/null
+++ b/library/msgcat/Makefile.in
@@ -0,0 +1,86 @@
+# TODO: Get libdir and mandir from tclConfig.sh or tclsh?
+# TODO: Get default value of TCLSH_PROG
+
+MIN_TCL = 8.5
+PACKAGE = @PACKAGE_NAME@
+VERSION = @PACKAGE_VERSION@
+
+srcdir = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+mandir = @mandir@
+
+TCLSH_PROG = $(srcdir)/../../unix/tclsh
+DIST_ROOT = /tmp/dist
+
+# Install files under $(DESTDIR)
+INSTALL_ROOT = $(DESTDIR)
+LIB_INSTALL_DIR = $(INSTALL_ROOT)$(libdir)
+MAN_INSTALL_DIR = $(INSTALL_ROOT)$(mandir)
+MANN_INSTALL_DIR = $(MAN_INSTALL_DIR)/mann
+MODULE_INSTALL_DIR = $(LIB_INSTALL_DIR)/tcl8/$(MIN_TCL)
+
+MANTAIL = $(PACKAGE).n
+MANPAGE = $(srcdir)/doc/$(MANTAIL)
+TESTTAIL = $(PACKAGE).test
+TESTFILE = $(srcdir)/tests/$(TESTTAIL)
+SOURCE = $(srcdir)/$(PACKAGE).tcl
+MODULE_STEM = $(PACKAGE)-$(VERSION)
+MODULE = $(MODULE_STEM).tm
+DIST_DIR = $(DIST_ROOT)/$(MODULE_STEM)
+
+all: $(MODULE)
+
+$(MODULE): $(SOURCE)
+ cp -f $< $@
+
+# Test package in place using $(TCLSH_PROG)
+test: $(MODULE)
+ TCL$(subst .,_,$(MIN_TCL))_TM_PATH=. $(TCLSH_PROG) $(TESTFILE)
+
+install: install-module install-doc
+
+install-module: $(MODULE)
+ @echo "Installing package '$(PACKAGE) $(VERSION)' as Tcl Module"
+ @mkdir -p "$(MODULE_INSTALL_DIR)"
+ @cp -f "$(MODULE)" "$(MODULE_INSTALL_DIR)"
+ @chmod 644 "$(MODULE_INSTALL_DIR)/$(MODULE)"
+
+install-doc: $(MANPAGE)
+ @echo "Installing package '$(PACKAGE) $(VERSION)' documentation"
+ @mkdir -p "$(MANN_INSTALL_DIR)"
+ @cp -f "$(MANPAGE)" "$(MANN_INSTALL_DIR)"
+ @chmod 644 "$(MANN_INSTALL_DIR)/$(MANTAIL)"
+
+# Clean away files made by `make all`
+clean:
+ -rm -f $(MODULE)
+
+# Clean away files made by configure
+distclean: clean
+ -rm -f Makefile
+ -rm -f config.log config.status
+
+# TODO
+# Build distribution tarball under $(DIST_ROOT)
+dist: dist-clean
+ mkdir -p $(DIST_DIR)
+
+dist-clean:
+ -rm -rf $(DIST_DIR) $(DIST_ROOT)/$(MODULE_STEM).tar.*
+
+Makefile: $(srcdir)/Makefile.in config.status
+ -rm -f $(MODULE)
+ $(SHELL) config.status
+
+config.status: $(srcdir)/configure
+ $(SHELL) config.status --recheck
+
+$(srcdir)/configure: $(SOURCE)
+ -$(MAKE) -C $(srcdir) -f configure.make \
+ "PACKAGE=$(PACKAGE)" "TCLSH=$(TCLSH_PROG)"
+
+.PHONY: all test install install-module install-doc clean distclean dist
+
diff --git a/library/msgcat/configure b/library/msgcat/configure
new file mode 100755
index 0000000..daf4ab7
--- /dev/null
+++ b/library/msgcat/configure
@@ -0,0 +1,2128 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for msgcat 1.4.3.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete. It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='msgcat'
+PACKAGE_TARNAME='msgcat'
+PACKAGE_VERSION='1.4.3'
+PACKAGE_STRING='msgcat 1.4.3'
+PACKAGE_BUGREPORT=''
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_option in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ eval "enable_$ac_feature=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_$ac_feature='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_$ac_package='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/-/_/g'`
+ eval "with_$ac_package=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+ eval "$ac_envvar='$ac_optarg'"
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+ localstatedir libdir includedir oldincludedir infodir mandir
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+ { (exit 1); exit 1; }; }
+ else
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+ fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+ { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures msgcat 1.4.3 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+ cat <<_ACEOF
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --infodir=DIR info documentation [PREFIX/info]
+ --mandir=DIR man documentation [PREFIX/man]
+_ACEOF
+
+ cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of msgcat 1.4.3:";;
+ esac
+ cat <<\_ACEOF
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ ac_popdir=`pwd`
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d $ac_dir || continue
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+ cd $ac_dir
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_srcdir/configure.gnu; then
+ echo
+ $SHELL $ac_srcdir/configure.gnu --help=recursive
+ elif test -f $ac_srcdir/configure; then
+ echo
+ $SHELL $ac_srcdir/configure --help=recursive
+ elif test -f $ac_srcdir/configure.ac ||
+ test -f $ac_srcdir/configure.in; then
+ echo
+ $ac_configure --help
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi
+ cd $ac_popdir
+ done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+ cat <<\_ACEOF
+msgcat configure 1.4.3
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by msgcat $as_me 1.4.3, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+ # Get rid of the leading space.
+ ac_sep=" "
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+{
+ (set) 2>&1 |
+ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ sed -n \
+ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+ ;;
+ *)
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+}
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ sed "/^$/d" confdefs.h | sort
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core &&
+ rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+ ' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . $cache_file;;
+ *) . ./$cache_file;;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+ eval ac_new_val="\$ac_env_${ac_var}_value"
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_files="$ac_config_files Makefile"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+ (set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+} |
+ sed '
+ t clear
+ : clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+ if test -w $cache_file; then
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[ ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[ ]*$//;
+}'
+fi
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section. Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g
+t quote
+s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[ `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output. A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_i=`echo "$ac_i" |
+ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+ # 2. Add them.
+ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling. Logging --version etc. is OK.
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by msgcat $as_me 1.4.3, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+msgcat config.status 1.4.3
+configured by $0, generated by GNU Autoconf 2.59,
+ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "x$1" : 'x\([^=]*\)='`
+ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ -*)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ *) # This is not an option, so the user has probably given explicit
+ # arguments.
+ ac_option=$1
+ ac_need_defaults=false;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --vers* | -V )
+ echo "$ac_cs_version"; exit 0 ;;
+ --he | --h)
+ # Conflict between --help and --header
+ { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ echo "$ac_cs_usage"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1" ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+ case "$ac_config_target" in
+ # Handling of arguments.
+ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./confstat$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+ # Protect against being on the right side of a sed subst in config.status.
+ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+ cat >>$CONFIG_STATUS <<\_ACEOF
+ # Split the substitutions into bite-sized pieces for seds with
+ # small command number limits, like on Digital OSF/1 and HP-UX.
+ ac_max_sed_lines=48
+ ac_sed_frag=1 # Number of current file.
+ ac_beg=1 # First line for current file.
+ ac_end=$ac_max_sed_lines # Line after last line for current file.
+ ac_more_lines=:
+ ac_sed_cmds=
+ while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ else
+ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ fi
+ if test ! -s $tmp/subs.frag; then
+ ac_more_lines=false
+ else
+ # The purpose of the label and of the branching condition is to
+ # speed up the sed processing (if there are no `@' at all, there
+ # is no need to browse any of the substitutions).
+ # These are the two extra sed commands mentioned above.
+ (echo ':t
+ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+ fi
+ ac_sed_frag=`expr $ac_sed_frag + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_lines`
+ fi
+ done
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+ fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ configure_input=
+ else
+ configure_input="$ac_file. "
+ fi
+ configure_input=$configure_input"Generated from `echo $ac_file_in |
+ sed 's,.*/,,'` by configure."
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+ rm -f $tmp/stdin
+ if test x"$ac_file" != x-; then
+ mv $tmp/out $ac_file
+ else
+ cat $tmp/out
+ rm -f $tmp/out
+ fi
+
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/library/msgcat/configure.in b/library/msgcat/configure.in
new file mode 100644
index 0000000..8bd2b85
--- /dev/null
+++ b/library/msgcat/configure.in
@@ -0,0 +1,2 @@
+AC_INIT([msgcat], [1.4.3])
+AC_OUTPUT([Makefile])
diff --git a/library/msgcat/configure.make b/library/msgcat/configure.make
new file mode 100644
index 0000000..1d2e79e
--- /dev/null
+++ b/library/msgcat/configure.make
@@ -0,0 +1,10 @@
+configure: configure.in
+ -autoconf
+
+configure.in: $(PACKAGE).tcl
+ version=`echo "source $(PACKAGE).tcl; \
+ puts [package provide $(PACKAGE)]" | $(TCLSH)`; \
+ (\
+ echo "AC_INIT([$(PACKAGE)], [$$version])"; \
+ echo "AC_OUTPUT([Makefile])"; \
+ ) > configure.in
diff --git a/library/msgcat/doc/Access.3 b/library/msgcat/doc/Access.3
new file mode 100644
index 0000000..1e82e07
--- /dev/null
+++ b/library/msgcat/doc/Access.3
@@ -0,0 +1,71 @@
+'\"
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_Access 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Access, Tcl_Stat \- check file permissions and other attributes
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_Access\fR(\fIpath\fR, \fImode\fR)
+.sp
+int
+\fBTcl_Stat\fR(\fIpath\fR, \fIstatPtr\fR)
+.SH ARGUMENTS
+.AS "struct stat" *statPtr out
+.AP char *path in
+Native name of the file to check the attributes of.
+.AP int mode in
+Mask consisting of one or more of \fBR_OK\fR, \fBW_OK\fR, \fBX_OK\fR and
+\fBF_OK\fR. \fBR_OK\fR, \fBW_OK\fR and \fBX_OK\fR request checking whether the
+file exists and has read, write and execute permissions, respectively.
+\fBF_OK\fR just requests a check for the existence of the file.
+.AP "struct stat" *statPtr out
+The structure that contains the result.
+.BE
+.SH DESCRIPTION
+.PP
+As of Tcl 8.4, the object-based APIs \fBTcl_FSAccess\fR and \fBTcl_FSStat\fR
+should be used in preference to \fBTcl_Access\fR and \fBTcl_Stat\fR, wherever
+possible. Those functions also support Tcl's virtual filesystem layer, which
+these do not.
+.SS "OBSOLETE FUNCTIONS"
+.PP
+There are two reasons for calling \fBTcl_Access\fR and \fBTcl_Stat\fR rather
+than calling system level functions \fBaccess\fR and \fBstat\fR directly.
+First, the Windows implementation of both functions fixes some bugs in the
+system level calls. Second, both \fBTcl_Access\fR and \fBTcl_Stat\fR (as well
+as \fBTcl_OpenFileChannelProc\fR) hook into a linked list of functions. This
+allows the possibility to reroute file access to alternative media or access
+methods.
+.PP
+\fBTcl_Access\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
+\fIpath\fR. If \fIpath\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.
+.PP
+\fBTcl_Stat\fR fills the stat structure \fIstatPtr\fR with information about
+the specified file. You do not need any access rights to the file to get this
+information but you need search rights to all directories named in the path
+leading to the file. The stat structure includes info regarding device, inode
+(always 0 on Windows), privilege mode, nlink (always 1 on Windows), user id
+(always 0 on Windows), group id (always 0 on Windows), rdev (same as device on
+Windows), size, last access time, last modification time, and creation time.
+.PP
+If \fIpath\fR exists, \fBTcl_Stat\fR returns 0 and the stat structure is
+filled with data. Otherwise, -1 is returned, and no stat info is given.
+.SH KEYWORDS
+stat, access
+.SH "SEE ALSO"
+Tcl_FSAccess(3), Tcl_FSStat(3)
diff --git a/library/msgcat/doc/AddErrInfo.3 b/library/msgcat/doc/AddErrInfo.3
new file mode 100644
index 0000000..e450a3e
--- /dev/null
+++ b/library/msgcat/doc/AddErrInfo.3
@@ -0,0 +1,312 @@
+'\"
+'\" Copyright (c) 1989-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.
+'\"
+.so man.macros
+.TH Tcl_AddErrorInfo 3 8.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_GetReturnOptions, Tcl_SetReturnOptions, Tcl_AddErrorInfo, Tcl_AppendObjToErrorInfo, Tcl_AddObjErrorInfo, Tcl_SetObjErrorCode, Tcl_SetErrorCode, Tcl_SetErrorCodeVA, Tcl_SetErrorLine, Tcl_GetErrorLine, Tcl_PosixError, Tcl_LogCommandInfo \- retrieve or record information about errors and other return options
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_GetReturnOptions\fR(\fIinterp, code\fR)
+.sp
+int
+\fBTcl_SetReturnOptions\fR(\fIinterp, options\fR)
+.sp
+\fBTcl_AddErrorInfo\fR(\fIinterp, message\fR)
+.sp
+\fBTcl_AppendObjToErrorInfo\fR(\fIinterp, objPtr\fR)
+.sp
+\fBTcl_AddObjErrorInfo\fR(\fIinterp, message, length\fR)
+.sp
+\fBTcl_SetObjErrorCode\fR(\fIinterp, errorObjPtr\fR)
+.sp
+\fBTcl_SetErrorCode\fR(\fIinterp, element, element, ... \fB(char *) NULL\fR)
+.sp
+\fBTcl_SetErrorCodeVA\fR(\fIinterp, argList\fR)
+.sp
+\fBTcl_GetErrorLine\fR(\fIinterp\fR)
+.sp
+\fBTcl_SetErrorLine\fR(\fIinterp, lineNum\fR)
+.sp
+const char *
+\fBTcl_PosixError\fR(\fIinterp\fR)
+.sp
+void
+\fBTcl_LogCommandInfo\fR(\fIinterp, script, command, commandLength\fR)
+.SH ARGUMENTS
+.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 \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.
+.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.
+.AP int length in
+The number of bytes to copy from \fImessage\fR when
+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
+The \fB\-errorcode\fR return option will be set to this value.
+.AP char *element in
+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
+\fBva_start\fR, and cleared using \fBva_end\fR.
+.AP int lineNum
+The line number of a script where an error occurred.
+.AP "const char" *script in
+Pointer to first character in script containing command (must be <= command)
+.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
+.BE
+.SH DESCRIPTION
+.PP
+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.
+As with any \fBTcl_Obj\fR with reference count of zero, it is up to
+the caller to arrange for its disposal with \fBTcl_DecrRefCount\fR or
+to a reference to it via \fBTcl_IncrRefCount\fR (or one of the many
+functions that call that, notably including \fBTcl_SetObjResult\fR and
+\fBTcl_SetVar2Ex\fR).
+.PP
+A typical usage for \fBTcl_GetReturnOptions\fR is to
+retrieve the stack trace when script evaluation returns
+\fBTCL_ERROR\fR, like so:
+.PP
+.CS
+int code = Tcl_Eval(interp, script);
+if (code == TCL_ERROR) {
+ Tcl_Obj *options = \fBTcl_GetReturnOptions\fR(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 */
+ Tcl_DecrRefCount(options);
+}
+.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:
+.PP
+.CS
+if ((objc % 2) == 0) { /* explicit result argument */
+ objc--;
+ Tcl_SetObjResult(interp, objv[objc]);
+}
+return \fBTcl_SetReturnOptions\fR(interp, Tcl_NewListObj(objc-1, objv+1));
+.CE
+.PP
+(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. The \fB\-errorline\fR
+return option is also read by commands that evaluate scripts
+and wish to supply detailed error location information in
+the stack trace text they append to the \fB\-errorinfo\fR option.
+Tcl provides several simpler interfaces to more directly set
+these return options.
+.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 \fB\-errorcode\fR option holds a list of items that
+are intended to be machine-readable.
+The first item in the \fB\-errorcode\fR value identifies the class of
+error that occurred
+(e.g. POSIX means an error occurred in a POSIX system call)
+and additional elements hold additional pieces
+of information that depend on the class.
+See the \fBtclvars\fR manual entry for details on the various
+formats for the \fB\-errorcode\fR option used by
+Tcl's built-in commands.
+.PP
+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_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
+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_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
+\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.
+.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
+\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
+the \fB\-errorcode\fR return option to \fBNONE\fR.
+.PP
+The procedure \fBTcl_SetErrorCode\fR is also used to set the
+\fB\-errorcode\fR return option. However, it takes one or more strings to
+record instead of an object. Otherwise, it is similar to
+\fBTcl_SetObjErrorCode\fR in behavior.
+.PP
+\fBTcl_SetErrorCodeVA\fR is the same as \fBTcl_SetErrorCode\fR except that
+instead of taking a variable number of arguments it takes an argument list.
+.PP
+The procedure \fBTcl_GetErrorLine\fR is used to read the integer value
+of the \fB\-errorline\fR return option without the overhead of a full
+call to \fBTcl_GetReturnOptions\fR. Likewise, \fBTcl_SetErrorLine\fR
+sets the \fB\-errorline\fR return option value.
+.PP
+\fBTcl_PosixError\fR
+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 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
+occurs in a dynamically loaded extension. See the manual entry for
+\fBTcl_SetErrno\fR for more information.
+.PP
+\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 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 \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 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.
+.PP
+If the procedure \fBTcl_ResetResult\fR is called,
+it clears all of the state of the interpreter associated with
+script evaluation, including the entire return options dictionary.
+In particular, the \fB\-errorinfo\fR and \fB\-errorcode\fR options
+are reset.
+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(3), Tcl_IncrRefCount(3), Tcl_Interp(3), Tcl_ResetResult(3),
+Tcl_SetErrno(3), tclvars(n)
+.SH KEYWORDS
+error, object, object result, stack, trace, variable
diff --git a/library/msgcat/doc/Alloc.3 b/library/msgcat/doc/Alloc.3
new file mode 100644
index 0000000..ca4f949
--- /dev/null
+++ b/library/msgcat/doc/Alloc.3
@@ -0,0 +1,92 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_Alloc 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Alloc, Tcl_Free, Tcl_Realloc, Tcl_AttemptAlloc, Tcl_AttemptRealloc, ckalloc, ckfree, ckrealloc, attemptckalloc, attemptckrealloc \- allocate or free heap memory
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+char *
+\fBTcl_Alloc\fR(\fIsize\fR)
+.sp
+void
+\fBTcl_Free\fR(\fIptr\fR)
+.sp
+char *
+\fBTcl_Realloc\fR(\fIptr, size\fR)
+.sp
+char *
+\fBTcl_AttemptAlloc\fR(\fIsize\fR)
+.sp
+char *
+\fBTcl_AttemptRealloc\fR(\fIptr, size\fR)
+.sp
+char *
+\fBckalloc\fR(\fIsize\fR)
+.sp
+void
+\fBckfree\fR(\fIptr\fR)
+.sp
+char *
+\fBckrealloc\fR(\fIptr, size\fR)
+.sp
+char *
+\fBattemptckalloc\fR(\fIsize\fR)
+.sp
+char *
+\fBattemptckrealloc\fR(\fIptr, size\fR)
+.SH ARGUMENTS
+.AS char *size
+.AP "unsigned int" size in
+Size in bytes of the memory block to allocate.
+.AP char *ptr in
+Pointer to memory block to free or realloc.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures provide a platform and compiler independent interface
+for memory allocation. Programs that need to transfer ownership of
+memory blocks between Tcl and other modules should use these routines
+rather than the native \fBmalloc()\fR and \fBfree()\fR routines
+provided by the C run-time library.
+.PP
+\fBTcl_Alloc\fR returns a pointer to a block of at least \fIsize\fR
+bytes suitably aligned for any use.
+.PP
+\fBTcl_Free\fR makes the space referred to by \fIptr\fR available for
+further allocation.
+.PP
+\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. 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, 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 procedures. To support Tcl's memory debugging within a
+module, use the macros rather than direct calls to \fBTcl_Alloc\fR, etc.
+
+.SH KEYWORDS
+alloc, allocation, free, malloc, memory, realloc, TCL_MEM_DEBUG
diff --git a/library/msgcat/doc/AllowExc.3 b/library/msgcat/doc/AllowExc.3
new file mode 100644
index 0000000..ae595f1
--- /dev/null
+++ b/library/msgcat/doc/AllowExc.3
@@ -0,0 +1,44 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_AllowExceptions 3 7.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_AllowExceptions \- allow all exceptions in next script evaluation
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_AllowExceptions\fR(\fIinterp\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Interpreter in which script will be evaluated.
+.BE
+
+.SH DESCRIPTION
+.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 \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,
+\fBTcl_GlobalEval\fR, \fBTcl_GlobalEvalObj\fR, \fBTcl_VarEval\fR and
+\fBTcl_VarEvalVA\fR.
+.PP
+However, if \fBTcl_AllowExceptions\fR is invoked immediately before
+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 \fBTCL_BREAK\fR or \fBTCL_CONTINUE\fR in a meaningful way.
+
+.SH KEYWORDS
+continue, break, exception, interpreter
diff --git a/library/msgcat/doc/AppInit.3 b/library/msgcat/doc/AppInit.3
new file mode 100644
index 0000000..e4ae971
--- /dev/null
+++ b/library/msgcat/doc/AppInit.3
@@ -0,0 +1,83 @@
+'\"
+'\" 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 Tcl_AppInit 3 7.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_AppInit \- perform application-specific initialization
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_AppInit\fR(\fIinterp\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Interpreter for the application.
+.BE
+
+.SH DESCRIPTION
+.PP
+\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.
+To create a new application you write a new version of
+\fBTcl_AppInit\fR to replace the default version provided by Tcl,
+then link your new \fBTcl_AppInit\fR with the Tcl library.
+.PP
+\fBTcl_AppInit\fR is invoked by \fBTcl_Main\fR and \fBTk_Main\fR
+after their own initialization and before entering the main loop
+to process commands.
+Here are some examples of things that \fBTcl_AppInit\fR might do:
+.IP [1]
+Call initialization procedures for various packages used by
+the application.
+Each initialization procedure adds new commands to \fIinterp\fR
+for its package and performs other package-specific initialization.
+.IP [2]
+Process command-line arguments, which can be accessed from the
+Tcl variables \fBargv\fR and \fBargv0\fR in \fIinterp\fR.
+.IP [3]
+Invoke a startup script to initialize the application.
+.IP [4]
+Use the routines \fBTcl_SetStartupScript\fR and
+\fBTcl_GetStartupScript\fR to set or query the file and encoding
+that the active \fBTcl_Main\fR or \fBTk_Main\fR routine will
+use as a startup script.
+.LP
+\fBTcl_AppInit\fR returns \fBTCL_OK\fR or \fBTCL_ERROR\fR.
+If it returns \fBTCL_ERROR\fR then it must leave an error message in
+for the interpreter's result; otherwise the result is ignored.
+.PP
+In addition to \fBTcl_AppInit\fR, your application should also contain
+a procedure \fBmain\fR that calls \fBTcl_Main\fR as follows:
+.PP
+.CS
+Tcl_Main(argc, argv, Tcl_AppInit);
+.CE
+.PP
+The third argument to \fBTcl_Main\fR gives the address of the
+application-specific initialization procedure to invoke.
+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).
+The best way to get started is to make a copy of the file
+\fBtclAppInit.c\fR from the Tcl library or source directory.
+It already contains a \fBmain\fR procedure and a template for
+\fBTcl_AppInit\fR that you can modify for your application.
+
+.SH "SEE ALSO"
+Tcl_Main(3)
+
+.SH KEYWORDS
+application, argument, command, initialization, interpreter
diff --git a/library/msgcat/doc/AssocData.3 b/library/msgcat/doc/AssocData.3
new file mode 100644
index 0000000..59c26a4
--- /dev/null
+++ b/library/msgcat/doc/AssocData.3
@@ -0,0 +1,87 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.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
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+ClientData
+\fBTcl_GetAssocData\fR(\fIinterp, key, delProcPtr\fR)
+.sp
+\fBTcl_SetAssocData\fR(\fIinterp, key, delProc, clientData\fR)
+.sp
+\fBTcl_DeleteAssocData\fR(\fIinterp, key\fR)
+.SH ARGUMENTS
+.AS Tcl_InterpDeleteProc **delProcPtr
+.AP Tcl_Interp *interp in
+Interpreter in which to execute the specified command.
+.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
+Procedure to call when \fIinterp\fR is deleted.
+.AP Tcl_InterpDeleteProc **delProcPtr in
+Pointer to location in which to store address of current deletion procedure
+for association. Ignored if NULL.
+.AP ClientData clientData in
+Arbitrary one-word value associated with the given key in this
+interpreter. This data is owned by the caller.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures allow extensions to associate their own data with
+a Tcl interpreter.
+An association consists of a string key, typically the name of
+the extension, and a one-word value, which is typically a pointer
+to a data structure holding data specific to the extension.
+Tcl makes no interpretation of either the key or the value for
+an association.
+.PP
+Storage management is facilitated by storing with each association a
+procedure to call when the interpreter is deleted. This
+procedure can dispose of the storage occupied by the client's data in any
+way it sees fit.
+.PP
+\fBTcl_SetAssocData\fR creates an association between a string
+key and a user specified datum in the given interpreter.
+If there is already an association with the given \fIkey\fR,
+\fBTcl_SetAssocData\fR overwrites it with the new information.
+It is up to callers to organize their use of names to avoid conflicts,
+for example, by using package names as the keys.
+If the \fIdeleteProc\fR argument is non-NULL it specifies the address of a
+procedure to invoke if the interpreter is deleted before the association
+is deleted. \fIDeleteProc\fR should have arguments and result that match
+the type \fBTcl_InterpDeleteProc\fR:
+.PP
+.CS
+typedef void \fBTcl_InterpDeleteProc\fR(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+When \fIdeleteProc\fR is invoked the \fIclientData\fR and \fIinterp\fR
+arguments will be the same as the corresponding arguments passed to
+\fBTcl_SetAssocData\fR.
+The deletion procedure will \fInot\fR be invoked if the association
+is deleted before the interpreter is deleted.
+.PP
+\fBTcl_GetAssocData\fR returns the datum stored in the association with the
+specified key in the given interpreter, and if the \fIdelProcPtr\fR field
+is non-\fBNULL\fR, the address indicated by it gets the address of the
+delete procedure stored with this association. If no association with the
+specified key exists in the given interpreter \fBTcl_GetAssocData\fR
+returns \fBNULL\fR.
+.PP
+\fBTcl_DeleteAssocData\fR deletes an association with a specified key in
+the given interpreter. Then it calls the deletion procedure.
+.SH KEYWORDS
+association, data, deletion procedure, interpreter, key
diff --git a/library/msgcat/doc/Async.3 b/library/msgcat/doc/Async.3
new file mode 100644
index 0000000..d02f76d
--- /dev/null
+++ b/library/msgcat/doc/Async.3
@@ -0,0 +1,161 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_AsyncCreate 3 7.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_AsyncCreate, Tcl_AsyncMark, Tcl_AsyncInvoke, Tcl_AsyncDelete, Tcl_AsyncReady \- handle asynchronous events
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_AsyncHandler
+\fBTcl_AsyncCreate\fR(\fIproc, clientData\fR)
+.sp
+\fBTcl_AsyncMark\fR(\fIasync\fR)
+.sp
+int
+\fBTcl_AsyncInvoke\fR(\fIinterp, code\fR)
+.sp
+\fBTcl_AsyncDelete\fR(\fIasync\fR)
+.sp
+int
+\fBTcl_AsyncReady\fR()
+.SH ARGUMENTS
+.AS Tcl_AsyncHandler clientData
+.AP Tcl_AsyncProc *proc in
+Procedure to invoke to handle an asynchronous event.
+.AP ClientData clientData in
+One-word value to pass to \fIproc\fR.
+.AP Tcl_AsyncHandler async in
+Token for asynchronous event handler.
+.AP Tcl_Interp *interp in
+Tcl interpreter in which command was being evaluated when handler was
+invoked, or NULL if handler was invoked when there was no interpreter
+active.
+.AP int code in
+Completion code from command that just completed in \fIinterp\fR,
+or 0 if \fIinterp\fR is NULL.
+.BE
+
+.SH DESCRIPTION
+.PP
+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 is not safe to take any substantive action to
+process the event.
+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.
+The only safe approach is to set a flag indicating that the event
+occurred, then handle the event later when the world has returned
+to a clean state, such as after the current Tcl command completes.
+.PP
+\fBTcl_AsyncCreate\fR, \fBTcl_AsyncDelete\fR, and \fBTcl_AsyncReady\fR
+are thread sensitive. They access and/or set a thread-specific data
+structure in the event of a core built with \fI\-\-enable\-threads\fR. The token
+created by \fBTcl_AsyncCreate\fR contains the needed thread information it
+was called from so that calling \fBTcl_AsyncMark\fR(\fItoken\fR) will only yield
+the origin thread into the asynchronous handler.
+.PP
+\fBTcl_AsyncCreate\fR creates an asynchronous handler and returns
+a token for it.
+The asynchronous handler must be created before
+any occurrences of the asynchronous event that it is intended
+to handle (it is not safe to create a handler at the time of
+an event).
+When an asynchronous event occurs the code that detects the event
+(such as a signal handler) should call \fBTcl_AsyncMark\fR with the
+token for the handler.
+\fBTcl_AsyncMark\fR will mark the handler as ready to execute, but it
+will not invoke the handler immediately.
+Tcl will call the \fIproc\fR associated with the handler later, when
+the world is in a safe state, and \fIproc\fR can then carry out
+the actions associated with the asynchronous event.
+\fIProc\fR should have arguments and result that match the
+type \fBTcl_AsyncProc\fR:
+.PP
+.CS
+typedef int \fBTcl_AsyncProc\fR(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ int \fIcode\fR);
+.CE
+.PP
+The \fIclientData\fR will be the same as the \fIclientData\fR
+argument passed to \fBTcl_AsyncCreate\fR when the handler was
+created.
+If \fIproc\fR is invoked just after a command has completed
+execution in an interpreter, then \fIinterp\fR will identify
+the interpreter in which the command was evaluated and
+\fIcode\fR will be the completion code returned by that
+command.
+The command's result will be present in the interpreter's result.
+When \fIproc\fR returns, whatever it leaves in the interpreter's result
+will be returned as the result of the command and the integer
+value returned by \fIproc\fR will be used as the new completion
+code for the command.
+.PP
+It is also possible for \fIproc\fR to be invoked when no interpreter
+is active.
+This can happen, for example, if an asynchronous event occurs while
+the application is waiting for interactive input or an X event.
+In this case \fIinterp\fR will be NULL and \fIcode\fR will be
+0, and the return value from \fIproc\fR will be ignored.
+.PP
+The procedure \fBTcl_AsyncInvoke\fR is called to invoke all of the
+handlers that are ready.
+The procedure \fBTcl_AsyncReady\fR will return non-zero whenever any
+asynchronous handlers are ready; it can be checked to avoid calls
+to \fBTcl_AsyncInvoke\fR when there are no ready handlers.
+Tcl calls \fBTcl_AsyncReady\fR after each command is evaluated
+and calls \fBTcl_AsyncInvoke\fR if needed.
+Applications may also call \fBTcl_AsyncInvoke\fR at interesting
+times for that application.
+For example, Tcl's event handler calls \fBTcl_AsyncReady\fR
+after each event and calls \fBTcl_AsyncInvoke\fR if needed.
+The \fIinterp\fR and \fIcode\fR arguments to \fBTcl_AsyncInvoke\fR
+have the same meaning as for \fIproc\fR: they identify the active
+interpreter, if any, and the completion code from the command
+that just completed.
+.PP
+\fBTcl_AsyncDelete\fR removes an asynchronous handler so that
+its \fIproc\fR will never be invoked again.
+A handler can be deleted even when ready, and it will still
+not be invoked.
+.PP
+If multiple handlers become active at the same time, the
+handlers are invoked in the order they were created (oldest
+handler first).
+The \fIcode\fR and the interpreter's result for later handlers
+reflect the values returned by earlier handlers, so that
+the most recently created handler has last say about
+the interpreter's result and completion code.
+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
+handler to modify the interpreter's result or return a code different
+from its \fIcode\fR argument.
+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 state by calling
+\fBTcl_SaveInterpState\fR, passing in the \fIcode\fR argument.
+When the asynchronous handler is finished it should restore
+the interpreter's state by calling \fBTcl_RestoreInterpState\fR,
+and then returning the \fIcode\fR argument.
+
+.SH KEYWORDS
+asynchronous event, handler, signal, Tcl_SaveInterpState, thread
diff --git a/library/msgcat/doc/BackgdErr.3 b/library/msgcat/doc/BackgdErr.3
new file mode 100644
index 0000000..3116671
--- /dev/null
+++ b/library/msgcat/doc/BackgdErr.3
@@ -0,0 +1,78 @@
+'\"
+'\" Copyright (c) 1992-1994 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 Tcl_BackgroundError 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_BackgroundException, Tcl_BackgroundError \- report Tcl exception that occurred in background processing
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_BackgroundException\fR(\fIinterp, code\fR)
+.sp
+\fBTcl_BackgroundError\fR(\fIinterp\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Interpreter in which the exception occurred.
+.AP int code in
+The exceptional return code to be reported.
+.BE
+
+.SH DESCRIPTION
+.PP
+This procedure is typically invoked when a Tcl exception (any
+return code other than TCL_OK) occurs during
+.QW "background processing"
+such as executing an event handler.
+When such an exception occurs, the 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 exception to the user.
+In these cases the code calls \fBTcl_BackgroundException\fR with an
+\fIinterp\fR argument identifying the interpreter in which the
+exception occurred, and a \fIcode\fR argument holding the return
+code value of the exception. The state of the interpreter, including
+any error message in the interpreter result, and the values of
+any entries in the return options dictionary, is captured and
+saved. \fBTcl_BackgroundException\fR then arranges for the event
+loop to invoke at some later time the command registered
+in that interpreter to handle background errors by the
+\fBinterp bgerror\fR command, passing the captured values as
+arguments.
+The registered handler command is meant to report the exception
+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_BackgroundException\fR reports the
+error itself by printing a message on the standard error file.
+.PP
+\fBTcl_BackgroundException\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 the handler command later as an idle callback.
+.PP
+It is possible for many background exceptions to accumulate before
+the handler command is invoked. When this happens, each of the exceptions
+is processed in order. However, if the handler command returns a
+break exception, then all remaining error reports for the
+interpreter are skipped.
+.PP
+The \fBTcl_BackgroundError\fR routine is an older and simpler interface
+useful when the exception code reported is \fBTCL_ERROR\fR. It is
+equivalent to:
+.PP
+.CS
+Tcl_BackgroundException(interp, TCL_ERROR);
+.CE
+
+.SH KEYWORDS
+background, bgerror, error, interp
diff --git a/library/msgcat/doc/Backslash.3 b/library/msgcat/doc/Backslash.3
new file mode 100644
index 0000000..8b399fc
--- /dev/null
+++ b/library/msgcat/doc/Backslash.3
@@ -0,0 +1,47 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_Backslash 3 "8.1" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Backslash \- parse a backslash sequence
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+char
+\fBTcl_Backslash\fR(\fIsrc, countPtr\fR)
+.SH ARGUMENTS
+.AS char *countPtr out
+.AP char *src in
+Pointer to a string starting with a backslash.
+.AP int *countPtr out
+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
+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.
+\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.
+.SH "SEE ALSO"
+Tcl(n), Tcl_UtfBackslash(3)
+
+.SH KEYWORDS
+backslash, parse
diff --git a/library/msgcat/doc/BoolObj.3 b/library/msgcat/doc/BoolObj.3
new file mode 100644
index 0000000..395d159
--- /dev/null
+++ b/library/msgcat/doc/BoolObj.3
@@ -0,0 +1,95 @@
+'\"
+'\" 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.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_NewBooleanObj, Tcl_SetBooleanObj, Tcl_GetBooleanFromObj \- store/retrieve boolean value in a Tcl_Obj
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewBooleanObj\fR(\fIboolValue\fR)
+.sp
+\fBTcl_SetBooleanObj\fR(\fIobjPtr, boolValue\fR)
+.sp
+int
+\fBTcl_GetBooleanFromObj\fR(\fIinterp, objPtr, boolPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp boolValue in/out
+.AP int boolValue in
+Integer value to be stored as a boolean value in a Tcl_Obj.
+.AP Tcl_Obj *objPtr in/out
+Points to the Tcl_Obj in which to store, or from which to
+retrieve a boolean value.
+.AP Tcl_Interp *interp in/out
+If a boolean value cannot be retrieved,
+an error message is left in the interpreter's result object
+unless \fIinterp\fR is NULL.
+.AP int *boolPtr out
+Points to place where \fBTcl_GetBooleanFromObj\fR
+stores the boolean value (0 or 1) obtained from \fIobjPtr\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+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_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_IsShared, Tcl_GetBoolean
+
+.SH KEYWORDS
+boolean, object
diff --git a/library/msgcat/doc/ByteArrObj.3 b/library/msgcat/doc/ByteArrObj.3
new file mode 100644
index 0000000..77c94ac
--- /dev/null
+++ b/library/msgcat/doc/ByteArrObj.3
@@ -0,0 +1,91 @@
+'\"
+'\" 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 Tcl_ByteArrayObj 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_NewByteArrayObj, Tcl_SetByteArrayObj, Tcl_GetByteArrayFromObj, Tcl_SetByteArrayLength \- manipulate Tcl objects as a arrays of bytes
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewByteArrayObj\fR(\fIbytes, length\fR)
+.sp
+void
+\fBTcl_SetByteArrayObj\fR(\fIobjPtr, bytes, length\fR)
+.sp
+unsigned char *
+\fBTcl_GetByteArrayFromObj\fR(\fIobjPtr, lengthPtr\fR)
+.sp
+unsigned char *
+\fBTcl_SetByteArrayLength\fR(\fIobjPtr, length\fR)
+.SH ARGUMENTS
+.AS "const unsigned char" *lengthPtr in/out
+.AP "const unsigned char" *bytes in
+The array of bytes used to initialize or set a byte-array object. May be NULL
+even if \fIlength\fR is non-zero.
+.AP int length in
+The length of the array of bytes. It must be >= 0.
+.AP Tcl_Obj *objPtr in/out
+For \fBTcl_SetByteArrayObj\fR, this points to the object to be converted to
+byte-array type. For \fBTcl_GetByteArrayFromObj\fR and
+\fBTcl_SetByteArrayLength\fR, this points to the object from which to get
+the byte-array value; if \fIobjPtr\fR does not already point to a byte-array
+object, it will be converted to one.
+.AP int *lengthPtr out
+If non-NULL, filled with the length of the array of bytes in the object.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures are used to create, modify, and read Tcl byte-array objects
+from C code. Byte-array objects are typically used to hold the
+results of binary IO operations or data structures created with the
+\fBbinary\fR command. In Tcl, an array of bytes is not equivalent to a
+string. Conceptually, a string is an array of Unicode characters, while a
+byte-array is an array of 8-bit quantities with no implicit meaning.
+Accessor functions are provided to get the string representation of a
+byte-array or to convert an arbitrary object to a byte-array. Obtaining the
+string representation of a byte-array object (by calling
+\fBTcl_GetStringFromObj\fR) produces a properly formed UTF-8 sequence with a
+one-to-one mapping between the bytes in the internal representation and the
+UTF-8 characters in the string representation.
+.PP
+\fBTcl_NewByteArrayObj\fR and \fBTcl_SetByteArrayObj\fR will
+create a new object of byte-array type or modify an existing object to have a
+byte-array type. Both of these procedures set the object's type to be
+byte-array and set the object's internal representation to a copy of the
+array of bytes given by \fIbytes\fR. \fBTcl_NewByteArrayObj\fR returns a
+pointer to a newly allocated object with a reference count of zero.
+\fBTcl_SetByteArrayObj\fR invalidates any old string representation and, if
+the object is not already a byte-array object, frees any old internal
+representation. If \fIbytes\fR is NULL then the new byte array contains
+arbitrary values.
+.PP
+\fBTcl_GetByteArrayFromObj\fR converts a Tcl object to byte-array type and
+returns a pointer to the object's new internal representation as an array of
+bytes. The length of this array is stored in \fIlengthPtr\fR if
+\fIlengthPtr\fR is non-NULL. The storage for the array of bytes is owned by
+the object and should not be freed. The contents of the array may be
+modified by the caller only if the object is not shared and the caller
+invalidates the string representation.
+.PP
+\fBTcl_SetByteArrayLength\fR converts the Tcl object to byte-array type
+and changes the length of the object's internal representation as an
+array of bytes. If \fIlength\fR is greater than the space currently
+allocated for the array, the array is reallocated to the new length; the
+newly allocated bytes at the end of the array have arbitrary values. If
+\fIlength\fR is less than the space currently allocated for the array,
+the length of array is reduced to the new length. The return value is a
+pointer to the object's new array of bytes.
+
+.SH "SEE ALSO"
+Tcl_GetStringFromObj, Tcl_NewObj, Tcl_IncrRefCount, Tcl_DecrRefCount
+
+.SH KEYWORDS
+object, byte array, utf, unicode, internationalization
diff --git a/library/msgcat/doc/CallDel.3 b/library/msgcat/doc/CallDel.3
new file mode 100644
index 0000000..dec4392
--- /dev/null
+++ b/library/msgcat/doc/CallDel.3
@@ -0,0 +1,67 @@
+'\"
+'\" 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 Tcl_CallWhenDeleted 3 7.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CallWhenDeleted, Tcl_DontCallWhenDeleted \- Arrange for callback when interpreter is deleted
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_CallWhenDeleted\fR(\fIinterp\fR, \fIproc\fR, \fIclientData\fR)
+.sp
+\fBTcl_DontCallWhenDeleted\fR(\fIinterp\fR, \fIproc\fR, \fIclientData\fR)
+.SH ARGUMENTS
+.AS Tcl_InterpDeleteProc clientData
+.AP Tcl_Interp *interp in
+Interpreter with which to associated callback.
+.AP Tcl_InterpDeleteProc *proc in
+Procedure to call when \fIinterp\fR is deleted.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CallWhenDeleted\fR arranges for \fIproc\fR to be called by
+\fBTcl_DeleteInterp\fR if/when \fIinterp\fR is deleted at some future
+time. \fIProc\fR will be invoked just before the interpreter
+is deleted, but the interpreter will still be valid at the
+time of the call.
+\fIProc\fR should have arguments and result that match the
+type \fBTcl_InterpDeleteProc\fR:
+.PP
+.CS
+typedef void \fBTcl_InterpDeleteProc\fR(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+The \fIclientData\fR and \fIinterp\fR parameters are
+copies of the \fIclientData\fR and \fIinterp\fR arguments given
+to \fBTcl_CallWhenDeleted\fR.
+Typically, \fIclientData\fR points to an application-specific
+data structure that \fIproc\fR uses to perform cleanup when an
+interpreter is about to go away.
+\fIProc\fR does not return a value.
+.PP
+\fBTcl_DontCallWhenDeleted\fR cancels a previous call to
+\fBTcl_CallWhenDeleted\fR with the same arguments, so that
+\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
+\fBTcl_DontCallWhenDeleted\fR has no effect.
+.PP
+Note that if the callback is being used to delete a resource that \fImust\fR
+be released on exit, \fBTcl_CreateExitHandler\fR should be used to ensure that
+a callback is received even if the application terminates without deleting the interpreter.
+.SH "SEE ALSO"
+Tcl_CreateExitHandler(3), Tcl_CreateThreadExitHandler(3)
+.SH KEYWORDS
+callback, cleanup, delete, interpreter
diff --git a/library/msgcat/doc/Cancel.3 b/library/msgcat/doc/Cancel.3
new file mode 100644
index 0000000..80db3a3
--- /dev/null
+++ b/library/msgcat/doc/Cancel.3
@@ -0,0 +1,66 @@
+'\"
+'\" Copyright (c) 2006-2008 Joe Mistachkin.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_Cancel 3 8.6 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CancelEval, Tcl_Canceled \- cancel Tcl scripts
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+int
+\fBTcl_CancelEval\fR(\fIinterp, clientData, flags\fR)
+.sp
+int
+\fBTcl_Canceled\fR(\fIinterp, flags\fR)
+.SH ARGUMENTS
+.AP Tcl_Interp *interp in
+Interpreter in which to cancel the script.
+.AP int flags in
+ORed combination of flag bits that specify additional options.
+For \fBTcl_CancelEval\fR, only \fBTCL_CANCEL_UNWIND\fR is currently
+supported. For \fBTcl_Canceled\fR, only \fBTCL_LEAVE_ERR_MSG\fR and
+\fBTCL_CANCEL_UNWIND\fR are currently supported.
+.AP ClientData clientData in
+Currently, reserved for future use.
+It should be set to NULL.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CancelEval\fR cancels or unwinds the script in progress soon after
+the next invocation of asynchronous handlers, causing \fBTCL_ERROR\fR to be
+the return code for that script. This function is thread-safe and may be
+called from any thread in the process.
+.PP
+\fBTcl_Canceled\fR checks if the script in progress has been canceled and
+returns \fBTCL_ERROR\fR if it has. Otherwise, \fBTCL_OK\fR is returned.
+Extensions can use this function to check to see if they should abort a long
+running command. This function is thread sensitive and may only be called
+from the thread the interpreter was created in.
+.SH "FLAG BITS"
+Any ORed combination of the following values may be used for the
+\fIflags\fR argument to procedures such as \fBTcl_CancelEval\fR:
+.TP 23
+\fBTCL_CANCEL_UNWIND\fR
+This flag is used by \fBTcl_CancelEval\fR and \fBTcl_Canceled\fR.
+For \fBTcl_CancelEval\fR, if this flag is set, the script in progress
+is canceled and the evaluation stack for the interpreter is unwound.
+For \fBTcl_Canceled\fR, if this flag is set, the script in progress
+is considered to be canceled only if the evaluation stack for the
+interpreter is being unwound.
+.TP 23
+\fBTCL_LEAVE_ERR_MSG\fR
+This flag is only used by \fBTcl_Canceled\fR; it is ignored by
+other procedures. 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 is not set then no error
+message is left and the interpreter's result will not be modified.
+.SH "SEE ALSO"
+TIP 285
+.SH KEYWORDS
+cancel, unwind
diff --git a/library/msgcat/doc/ChnlStack.3 b/library/msgcat/doc/ChnlStack.3
new file mode 100644
index 0000000..9ec38b4
--- /dev/null
+++ b/library/msgcat/doc/ChnlStack.3
@@ -0,0 +1,97 @@
+'\"
+'\" Copyright (c) 1999-2000 Ajuba Solutions.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+.so man.macros
+.TH Tcl_StackChannel 3 8.3 Tcl "Tcl Library Procedures"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_StackChannel, Tcl_UnstackChannel, Tcl_GetStackedChannel, Tcl_GetTopChannel \- manipulate stacked I/O channels
+.SH SYNOPSIS
+.nf
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Channel
+\fBTcl_StackChannel\fR(\fIinterp, typePtr, clientData, mask, channel\fR)
+.sp
+int
+\fBTcl_UnstackChannel\fR(\fIinterp, channel\fR)
+.sp
+Tcl_Channel
+\fBTcl_GetStackedChannel\fR(\fIchannel\fR)
+.sp
+Tcl_Channel
+\fBTcl_GetTopChannel\fR(\fIchannel\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_ChannelType clientData
+.AP Tcl_Interp *interp in
+Interpreter for error reporting.
+.AP "const Tcl_ChannelType" *typePtr in
+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\fR.
+.AP Tcl_Channel channel in
+An existing Tcl channel such as returned by \fBTcl_CreateChannel\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+These functions are for use by extensions that add processing layers to Tcl
+I/O channels. Examples include compression and encryption modules. These
+functions transparently stack and unstack a new channel on top of an
+existing one. Any number of channels can be stacked together.
+.PP
+The implementation of the Tcl channel code was rewritten in 8.3.2 to
+correct some problems with the previous implementation with regard to
+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\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
+buffering options are shared between all channels in the stack. The hidden
+channel does no buffering, newline translations, or character set encoding.
+Instead, the buffering, newline translations, and encoding functions all
+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\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.
+.PP
+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\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\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
+\fBTcl_GetTopChannel\fR returns the top channel in the stack of
+channels the supplied channel is part of.
+.PP
+\fBTcl_GetStackedChannel\fR returns the channel in the stack of
+channels which is just below the supplied channel.
+
+.SH "SEE ALSO"
+Notifier(3), Tcl_CreateChannel(3), Tcl_OpenFileChannel(3), vwait(n).
+
+.SH KEYWORDS
+channel, compression
diff --git a/library/msgcat/doc/Class.3 b/library/msgcat/doc/Class.3
new file mode 100644
index 0000000..28cea9b
--- /dev/null
+++ b/library/msgcat/doc/Class.3
@@ -0,0 +1,236 @@
+'\"
+'\" Copyright (c) 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 Tcl_Class 3 0.1 TclOO "TclOO Library Functions"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_ClassGetMetadata, Tcl_ClassSetMetadata, Tcl_CopyObjectInstance, Tcl_GetClassAsObject, Tcl_GetObjectAsClass, Tcl_GetObjectCommand, Tcl_GetObjectFromObj, Tcl_GetObjectName, Tcl_GetObjectNamespace, Tcl_NewObjectInstance, Tcl_ObjectDeleted, Tcl_ObjectGetMetadata, Tcl_ObjectGetMethodNameMapper, Tcl_ObjectSetMetadata, Tcl_ObjectSetMethodNameMapper \- manipulate objects and classes
+.SH SYNOPSIS
+.nf
+\fB#include <tclOO.h>\fR
+.sp
+Tcl_Object
+\fBTcl_GetObjectFromObj\fR(\fIinterp, objPtr\fR)
+.sp
+Tcl_Object
+\fBTcl_GetClassAsObject\fR(\fIclass\fR)
+.sp
+Tcl_Class
+\fBTcl_GetObjectAsClass\fR(\fIobject\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetObjectName\fR(\fIinterp, object\fR)
+.sp
+Tcl_Command
+\fBTcl_GetObjectCommand\fR(\fIobject\fR)
+.sp
+Tcl_Namespace *
+\fBTcl_GetObjectNamespace\fR(\fIobject\fR)
+.sp
+Tcl_Object
+\fBTcl_NewObjectInstance\fR(\fIinterp, class, name, nsName, objc, objv, skip\fR)
+.sp
+Tcl_Object
+\fBTcl_CopyObjectInstance\fR(\fIinterp, object, name, nsName\fR)
+.sp
+int
+\fBTcl_ObjectDeleted\fR(\fIobject\fR)
+.sp
+ClientData
+\fBTcl_ObjectGetMetadata\fR(\fIobject, metaTypePtr\fR)
+.sp
+\fBTcl_ObjectSetMetadata\fR(\fIobject, metaTypePtr, metadata\fR)
+.sp
+ClientData
+\fBTcl_ClassGetMetadata\fR(\fIclass, metaTypePtr\fR)
+.sp
+\fBTcl_ClassSetMetadata\fR(\fIclass, metaTypePtr, metadata\fR)
+.sp
+Tcl_ObjectMapMethodNameProc
+\fBTcl_ObjectGetMethodNameMapper\fR(\fIobject\fR)
+.sp
+\fBTcl_ObjectSetMethodNameMapper\fR(\fIobject\fR, \fImethodNameMapper\fR)
+.SH ARGUMENTS
+.AS ClientData metadata in/out
+.AP Tcl_Interp *interp in/out
+Interpreter providing the context for looking up or creating an object, and
+into whose result error messages will be written on failure.
+.AP Tcl_Obj *objPtr in
+The name of the object to look up.
+.AP Tcl_Object object in
+Reference to the object to operate upon.
+.AP Tcl_Class class in
+Reference to the class to operate upon.
+.AP "const char" *name in
+The name of the object to create, or NULL if a new unused name is to be
+automatically selected.
+.AP "const char" *nsName in
+The name of the namespace to create for the object's private use, or NULL if a
+new unused name is to be automatically selected.
+.AP int objc in
+The number of elements in the \fIobjv\fR array.
+.AP "Tcl_Obj *const" *objv in
+The arguments to the command to create the instance of the class.
+.AP int skip in
+The number of arguments at the start of the argument array, \fIobjv\fR, that
+are not arguments to any constructors.
+.AP Tcl_ObjectMetadataType *metaTypePtr in
+The type of \fImetadata\fR being set with \fBTcl_ClassSetMetadata\fR or
+retrieved with \fBTcl_ClassGetMetadata\fR.
+.AP ClientData metadata in
+An item of metadata to attach to the class, or NULL to remove the metadata
+associated with a particular \fImetaTypePtr\fR.
+.AP "Tcl_ObjectMapMethodNameProc" "methodNameMapper" in
+A pointer to a function to call to adjust the mapping of objects and method
+names to implementations, or NULL when no such mapping is required.
+.BE
+.SH DESCRIPTION
+.PP
+Objects are typed entities that have a set of operations ("methods")
+associated with them. Classes are objects that can manufacture objects. Each
+class can be viewed as an object itself; the object view can be retrieved
+using \fBTcl_GetClassAsObject\fR which always returns the object when applied
+to a non-destroyed class, and an object can be viewed as a class with the aid
+of the \fBTcl_GetObjectAsClass\fR (which either returns the class, or NULL if
+the object is not a class). An object may be looked up using the
+\fBTcl_GetObjectFromObj\fR function, which either returns an object or NULL
+(with an error message in the interpreter result) if the object cannot be
+found. The correct way to look up a class by name is to look up the object
+with that name, and then to use \fBTcl_GetObjectAsClass\fR.
+.PP
+Every object has its own command and namespace associated with it. The command
+may be retrieved using the \fBTcl_GetObjectCommand\fR function, the name of
+the object (and hence the name of the command) with \fBTcl_GetObjectName\fR,
+and the namespace may be retrieved using the \fBTcl_GetObjectNamespace\fR
+function. Note that the Tcl_Obj reference returned by \fBTcl_GetObjectName\fR
+is a shared reference.
+.PP
+Instances of classes are created using \fBTcl_NewObjectInstance\fR, which
+takes creates an object from any class (and which is internally called by both
+the \fBcreate\fR and \fBnew\fR methods of the \fBoo::class\fR class). It takes
+parameters that optionally give the name of the object and namespace to
+create, and which describe the arguments to pass to the class's constructor
+(if any). The result of the function will be either a reference to the newly
+created object, or NULL if the creation failed (when an error message will be
+left in the interpreter result). In addition, objects may be copied by using
+\fBTcl_CopyObjectInstance\fR which creates a copy of an object without running
+any constructors.
+.SH "OBJECT AND CLASS METADATA"
+.PP
+Every object and every class may have arbitrary amounts of metadata attached
+to it, which the object or class attaches no meaning to beyond what is
+described in a Tcl_ObjectMetadataType structure instance. Metadata to be
+attached is described by the type of the metadata (given in the
+\fImetaTypePtr\fR argument) and an arbitrary pointer (the \fImetadata\fR
+argument) that are given to \fBTcl_ObjectSetMetadata\fR and
+\fBTcl_ClassSetMetadata\fR, and a particular piece of metadata can be
+retrieved given its type using \fBTcl_ObjectGetMetadata\fR and
+\fBTcl_ClassGetMetadata\fR. If the \fImetadata\fR parameter to either
+\fBTcl_ObjectSetMetadata\fR or \fBTcl_ClassSetMetadata\fR is NULL, the
+metadata is removed if it was attached, and the results of
+\fBTcl_ObjectGetMetadata\fR and \fBTcl_ClassGetMetadata\fR are NULL if the
+given type of metadata was not attached. It is not an error to request or
+remove a piece of metadata that was not attached.
+.SS "TCL_OBJECTMETADATATYPE STRUCTURE"
+.PP
+The contents of the Tcl_ObjectMetadataType structure are as follows:
+.PP
+.CS
+typedef const struct {
+ int \fIversion\fR;
+ const char *\fIname\fR;
+ Tcl_ObjectMetadataDeleteProc *\fIdeleteProc\fR;
+ Tcl_CloneProc *\fIcloneProc\fR;
+} \fBTcl_ObjectMetadataType\fR;
+.CE
+.PP
+The \fIversion\fR field allows for future expansion of the structure, and
+should always be declared equal to TCL_OO_METADATA_VERSION_CURRENT. The
+\fIname\fR field provides a human-readable name for the type, and is reserved
+for debugging.
+.PP
+The \fIdeleteProc\fR field gives a function of type
+Tcl_ObjectMetadataDeleteProc that is used to delete a particular piece of
+metadata, and is called when the attached metadata is replaced or removed; the
+field must not be NULL.
+.PP
+The \fIcloneProc\fR field gives a function that is used to copy a piece of
+metadata (used when a copy of an object is created using
+\fBTcl_CopyObjectInstance\fR); if NULL, the metadata will be just directly
+copied.
+.SS "TCL_OBJECTMETADATADELETEPROC FUNCTION SIGNATURE"
+.PP
+Functions matching this signature are used to delete metadata associated with
+a class or object.
+.PP
+.CS
+typedef void \fBTcl_ObjectMetadataDeleteProc\fR(
+ ClientData \fImetadata\fR);
+.CE
+.PP
+The \fImetadata\fR argument gives the address of the metadata to be
+deleted.
+.SS "TCL_CLONEPROC FUNCTION SIGNATURE"
+.PP
+Functions matching this signature are used to create copies of metadata
+associated with a class or object.
+.PP
+.CS
+typedef int \fBTcl_CloneProc\fR(
+ Tcl_Interp *\fIinterp\fR,
+ ClientData \fIsrcMetadata\fR,
+ ClientData *\fIdstMetadataPtr\fR);
+.CE
+.PP
+The \fIinterp\fR argument gives a place to write an error message when the
+attempt to clone the object is to fail, in which case the clone procedure must
+also return TCL_ERROR; it should return TCL_OK otherwise.
+The \fIsrcMetadata\fR argument gives the address of the metadata to be cloned,
+and the cloned metadata should be written into the variable pointed to by
+\fIdstMetadataPtr\fR; a NULL should be written if the metadata is to not be
+cloned but the overall object copy operation is still to succeed.
+.SH "OBJECT METHOD NAME MAPPING"
+It is possible to control, on a per-object basis, what methods are invoked
+when a particular method is invoked. Normally this is done by looking up the
+method name in the object and then in the class hierarchy, but fine control of
+exactly what the value used to perform the look up is afforded through the
+ability to set a method name mapper callback via
+\fBTcl_ObjectSetMethodNameMapper\fR (and its introspection counterpart,
+\fBTcl_ObjectGetMethodNameMapper\fR, which returns the current mapper). The
+current mapper (if any) is invoked immediately before looking up what chain of
+method implementations is to be used.
+.SS "TCL_OBJECTMAPMETHODNAMEPROC FUNCTION SIGNATURE"
+The \fITcl_ObjectMapMethodNameProc\fR callback is defined as follows:
+.PP
+.CS
+typedef int \fBTcl_ObjectMapMethodNameProc\fR(
+ Tcl_Interp *\fIinterp\fR,
+ Tcl_Object \fIobject\fR,
+ Tcl_Class *\fIstartClsPtr\fR,
+ Tcl_Obj *\fImethodNameObj\fR);
+.CE
+.PP
+If the result is TCL_OK, the remapping is assumed to have been done. If the
+result is TCL_ERROR, an error message will have been left in \fIinterp\fR and
+the method call will fail. If the result is TCL_BREAK, the standard method
+name lookup rules will be used; the behavior of other result codes is
+currently undefined. The \fIobject\fR parameter says which object is being
+processed. The \fIstartClsPtr\fR parameter points to a variable that contains
+the first class to provide a definition in the method chain to process, or
+NULL if the whole chain is to be processed (the argument itself is never
+NULL); this variable may be updated by the callback. The \fImethodNameObj\fR
+parameter gives an unshared object containing the name of the method being
+invoked, as provided by the user; this object may be updated by the callback.
+.SH "SEE ALSO"
+Method(3), oo::class(n), oo::copy(n), oo::define(n), oo::object(n)
+.SH KEYWORDS
+class, constructor, object
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/library/msgcat/doc/CmdCmplt.3 b/library/msgcat/doc/CmdCmplt.3
new file mode 100644
index 0000000..eeae039
--- /dev/null
+++ b/library/msgcat/doc/CmdCmplt.3
@@ -0,0 +1,34 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_CommandComplete 3 "" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CommandComplete \- Check for unmatched braces in a Tcl command
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_CommandComplete\fR(\fIcmd\fR)
+.SH ARGUMENTS
+.AS "const char" *cmd
+.AP "const char" *cmd in
+Command string to test for completeness.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_CommandComplete\fR takes a Tcl command string
+as argument and determines whether it contains one or more
+complete commands (i.e. there are no unclosed quotes, braces,
+brackets, or variable references).
+If the command string is complete then it returns 1; otherwise it returns 0.
+
+.SH KEYWORDS
+complete command, partial command
diff --git a/library/msgcat/doc/Concat.3 b/library/msgcat/doc/Concat.3
new file mode 100644
index 0000000..c38bf82
--- /dev/null
+++ b/library/msgcat/doc/Concat.3
@@ -0,0 +1,51 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_Concat 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Concat \- concatenate a collection of strings
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+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
+Array of strings to concatenate. Must have \fIargc\fR entries.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_Concat\fR is a utility procedure used by several of the
+Tcl commands. Given a collection of strings, it concatenates
+them together into a single string, with the original strings
+separated by spaces. This procedure behaves differently than
+\fBTcl_Merge\fR, in that the arguments are simply concatenated:
+no effort is made to ensure proper list structure.
+However, in most common usage the arguments will all be proper
+lists themselves; if this is true, then the result will also have
+proper list structure.
+.PP
+\fBTcl_Concat\fR eliminates leading and trailing white space as it
+copies strings from \fBargv\fR to the result. If an element of
+\fBargv\fR consists of nothing but white space, then that string
+is ignored entirely. This white-space removal was added to make
+the output of the \fBconcat\fR command cleaner-looking.
+.PP
+The result string is dynamically allocated
+using \fBTcl_Alloc\fR; the caller must eventually release the space
+by calling \fBTcl_Free\fR.
+.SH "SEE ALSO"
+Tcl_ConcatObj
+.SH KEYWORDS
+concatenate, strings
diff --git a/library/msgcat/doc/CrtChannel.3 b/library/msgcat/doc/CrtChannel.3
new file mode 100644
index 0000000..478ef0b
--- /dev/null
+++ b/library/msgcat/doc/CrtChannel.3
@@ -0,0 +1,928 @@
+'\"
+'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
+'\" Copyright (c) 1997-2000 Ajuba Solutions.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+.so man.macros
+.TH Tcl_CreateChannel 3 8.4 Tcl "Tcl Library Procedures"
+.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_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
+.sp
+Tcl_Channel
+\fBTcl_CreateChannel\fR(\fItypePtr, channelName, instanceData, mask\fR)
+.sp
+ClientData
+\fBTcl_GetChannelInstanceData\fR(\fIchannel\fR)
+.sp
+const Tcl_ChannelType *
+\fBTcl_GetChannelType\fR(\fIchannel\fR)
+.sp
+const char *
+\fBTcl_GetChannelName\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_GetChannelHandle\fR(\fIchannel, direction, handlePtr\fR)
+.sp
+Tcl_ThreadId
+\fBTcl_GetChannelThread\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_GetChannelMode\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_GetChannelBufferSize\fR(\fIchannel\fR)
+.sp
+\fBTcl_SetChannelBufferSize\fR(\fIchannel, size\fR)
+.sp
+\fBTcl_NotifyChannel\fR(\fIchannel, mask\fR)
+.sp
+int
+\fBTcl_BadChannelOption\fR(\fIinterp, optionName, optionList\fR)
+.sp
+int
+\fBTcl_IsChannelShared\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_IsChannelRegistered\fR(\fIinterp, channel\fR)
+.sp
+int
+\fBTcl_IsChannelExisting\fR(\fIchannelName\fR)
+.sp
+void
+\fBTcl_CutChannel\fR(\fIchannel\fR)
+.sp
+void
+\fBTcl_SpliceChannel\fR(\fIchannel\fR)
+.sp
+void
+\fBTcl_ClearChannelHandlers\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_ChannelBuffered\fR(\fIchannel\fR)
+.sp
+const char *
+\fBTcl_ChannelName\fR(\fItypePtr\fR)
+.sp
+Tcl_ChannelTypeVersion
+\fBTcl_ChannelVersion\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverBlockModeProc *
+\fBTcl_ChannelBlockModeProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverCloseProc *
+\fBTcl_ChannelCloseProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverClose2Proc *
+\fBTcl_ChannelClose2Proc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverInputProc *
+\fBTcl_ChannelInputProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverOutputProc *
+\fBTcl_ChannelOutputProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverSeekProc *
+\fBTcl_ChannelSeekProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverWideSeekProc *
+\fBTcl_ChannelWideSeekProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverThreadActionProc *
+\fBTcl_ChannelThreadActionProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverTruncateProc *
+\fBTcl_ChannelTruncateProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverSetOptionProc *
+\fBTcl_ChannelSetOptionProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverGetOptionProc *
+\fBTcl_ChannelGetOptionProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverWatchProc *
+\fBTcl_ChannelWatchProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverGetHandleProc *
+\fBTcl_ChannelGetHandleProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverFlushProc *
+\fBTcl_ChannelFlushProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverHandlerProc *
+\fBTcl_ChannelHandlerProc\fR(\fItypePtr\fR)
+.sp
+.SH ARGUMENTS
+.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
+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. If the created channel is assigned to one
+of the standard channels (\fBstdin\fR, \fBstdout\fR or \fBstderr\fR),
+the assigned channel name will be the name of the standard channel.
+.AP ClientData instanceData in
+Arbitrary one-word value to be associated with this channel. This
+value is passed to procedures in \fItypePtr\fR when they are invoked.
+.AP int mask in
+OR-ed combination of \fBTCL_READABLE\fR and \fBTCL_WRITABLE\fR to indicate
+whether a channel is readable and writable.
+.AP Tcl_Channel channel in
+The channel to operate on.
+.AP int direction in
+\fBTCL_READABLE\fR means the input handle is wanted; \fBTCL_WRITABLE\fR
+means the output handle is wanted.
+.AP ClientData *handlePtr out
+Points to the location where the desired OS-specific handle should be
+stored.
+.AP int size in
+The size, in bytes, of buffers to allocate in this channel.
+.AP int mask in
+An OR-ed combination of \fBTCL_READABLE\fR, \fBTCL_WRITABLE\fR
+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
+Name of the invalid option.
+.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.
+.BE
+.SH DESCRIPTION
+.PP
+Tcl uses a two-layered channel architecture. It provides a generic upper
+layer to enable C and Tcl programs to perform input and output using the
+same APIs for a variety of files, devices, sockets etc. The generic C APIs
+are described in the manual entry for \fBTcl_OpenFileChannel\fR.
+.PP
+The lower layer provides type-specific channel drivers for each type
+of device supported on each platform. This manual entry describes the
+C APIs used to communicate between the generic layer and the
+type-specific channel drivers. It also explains how new types of
+channels can be added by providing new channel drivers.
+.PP
+Channel drivers consist of a number of components: First, each channel
+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
+\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
+command creates channels that use the file and command channel
+drivers, and the Tcl \fBsocket\fR command creates channels that use
+TCP sockets for network communication.
+.PP
+Third, a channel driver optionally provides a C function to open
+channel instances of that type. For example, \fBTcl_OpenFileChannel\fR
+opens a channel that uses the file channel driver, and
+\fBTcl_OpenTcpClient\fR opens a channel that uses the TCP network
+protocol. These creation functions typically use
+\fBTcl_CreateChannel\fR internally to open the channel.
+.PP
+To add a new type of channel you must implement a C API or a Tcl command
+that opens a channel by invoking \fBTcl_CreateChannel\fR.
+When your driver calls \fBTcl_CreateChannel\fR it passes in
+a \fBTcl_ChannelType\fR structure describing the driver's I/O
+procedures.
+The generic layer will then invoke the functions referenced in that
+structure to perform operations on the channel.
+.PP
+\fBTcl_CreateChannel\fR opens a new channel and associates the supplied
+\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 \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
+call to \fBTcl_GetStdChannel\fR or a call to \fBTcl_SetStdChannel\fR
+closing this standard channel will cause the next call to
+\fBTcl_CreateChannel\fR to make the new channel the new standard
+channel too. See \fBTcl_StandardChannels\fR for a general treatise
+about standard channels and the behavior of the Tcl library with
+regard to them.
+.PP
+\fBTcl_GetChannelInstanceData\fR returns the instance data associated with
+the channel in \fIchannel\fR. This is the same as the \fIinstanceData\fR
+argument in the call to \fBTcl_CreateChannel\fR that created this channel.
+.PP
+\fBTcl_GetChannelType\fR returns a pointer to the \fBTcl_ChannelType\fR
+structure used by the channel in the \fIchannel\fR argument. This is
+the same as the \fItypePtr\fR argument in the call to
+\fBTcl_CreateChannel\fR that created this channel.
+.PP
+\fBTcl_GetChannelName\fR returns a string containing the name associated
+with the channel, or NULL if the \fIchannelName\fR argument to
+\fBTcl_CreateChannel\fR was NULL.
+.PP
+\fBTcl_GetChannelHandle\fR places the OS-specific device handle
+associated with \fIchannel\fR for the given \fIdirection\fR in the
+location specified by \fIhandlePtr\fR and returns \fBTCL_OK\fR. If
+the channel does not have a device handle for the specified direction,
+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
+\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.
+.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
+and output.
+.PP
+\fBTcl_GetChannelBufferSize\fR returns the size, in bytes, of buffers
+allocated to store input or output in \fIchannel\fR. If the value was not set
+by a previous call to \fBTcl_SetChannelBufferSize\fR, described below, then
+the default value of 4096 is returned.
+.PP
+\fBTcl_SetChannelBufferSize\fR sets the size, in bytes, of buffers that
+will be allocated in subsequent operations on the channel to store input or
+output. The \fIsize\fR argument should be between ten and one million,
+allowing buffers of ten bytes to one million bytes. If \fIsize\fR is
+outside this range, \fBTcl_SetChannelBufferSize\fR sets the buffer size to
+4096.
+.PP
+\fBTcl_NotifyChannel\fR is called by a channel driver to indicate to
+the generic layer that the events specified by \fImask\fR have
+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
+\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
+\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).
+.PP
+\fBTcl_IsChannelRegistered\fR checks whether the specified \fIchannel\fR is
+registered in the given \fIinterp\fRreter (result == 1) or not
+(result == 0).
+.PP
+\fBTcl_IsChannelExisting\fR checks whether a channel with the specified
+name is registered in the (thread)-global list of all channels (result
+== 1) or not (result == 0).
+.PP
+\fBTcl_CutChannel\fR removes the specified \fIchannel\fR from the
+(thread)global list of all channels (of the current thread).
+Application to a channel still registered in some interpreter
+is not allowed.
+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.
+.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.
+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.
+.PP
+\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.
+.SH TCL_CHANNELTYPE
+.PP
+A channel driver provides a \fBTcl_ChannelType\fR structure that contains
+pointers to functions that implement the various operations on a channel;
+these operations are invoked as needed by the generic layer. The structure
+was versioned starting in Tcl 8.3.2/8.4 to correct a problem with stacked
+channel drivers. See the \fBOLD CHANNEL TYPES\fR section below for
+details about the old structure.
+.PP
+The \fBTcl_ChannelType\fR structure contains the following fields:
+.PP
+.CS
+typedef struct Tcl_ChannelType {
+ const 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;
+ Tcl_DriverTruncateProc *\fItruncateProc\fR;
+} \fBTcl_ChannelType\fR;
+.CE
+.PP
+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, \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
+structure, the following functions should be used to obtain the values:
+\fBTcl_ChannelName\fR, \fBTcl_ChannelVersion\fR,
+\fBTcl_ChannelBlockModeProc\fR, \fBTcl_ChannelCloseProc\fR,
+\fBTcl_ChannelClose2Proc\fR, \fBTcl_ChannelInputProc\fR,
+\fBTcl_ChannelOutputProc\fR, \fBTcl_ChannelSeekProc\fR,
+\fBTcl_ChannelWideSeekProc\fR, \fBTcl_ChannelThreadActionProc\fR,
+\fBTcl_ChannelTruncateProc\fR,
+\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 (i.e. TLS, Trf) have new versions to correspond to the above change
+since the previous code for stacked channels had problems.
+.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.
+\fBfile\fR or \fBsocket\fR.
+.PP
+This value can be retrieved with \fBTcl_ChannelName\fR, which returns
+a pointer to the string.
+.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.
+\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).
+\fBTCL_CHANNEL_VERSION_5\fR must be set to specify the
+\fItruncateProc\fR members (includes
+\fIwideSeekProc\fR and \fIthreadActionProc\fR).
+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
+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
+one of
+\fBTCL_CHANNEL_VERSION_5\fR,
+\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.
+\fIBlockModeProc\fR should match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverBlockModeProc\fR(
+ ClientData \fIinstanceData\fR,
+ int \fImode\fR);
+.CE
+.PP
+The \fIinstanceData\fR is the same as the value passed to
+\fBTcl_CreateChannel\fR when this channel was created. The \fImode\fR
+argument is either \fBTCL_MODE_BLOCKING\fR or \fBTCL_MODE_NONBLOCKING\fR to
+set the device into blocking or nonblocking mode. The function should
+return zero if the operation was successful, or a nonzero POSIX error code
+if the operation failed.
+.PP
+If the operation is successful, the function can modify the supplied
+\fIinstanceData\fR to record that the channel entered blocking or
+nonblocking mode and to implement the blocking or nonblocking behavior.
+For some device types, the blocking and nonblocking behavior can be
+implemented by the underlying operating system; for other device types, the
+behavior must be emulated in the channel driver.
+.PP
+This value can be retrieved with \fBTcl_ChannelBlockModeProc\fR, which returns
+a pointer to the function.
+.PP
+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
+unacceptable value. Any confusion here may lead the interpreter into a
+(spurious and difficult to find) deadlock.
+.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
+closed. \fICloseProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverCloseProc\fR(
+ ClientData \fIinstanceData\fR,
+ Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+The \fIinstanceData\fR argument is the same as the value provided to
+\fBTcl_CreateChannel\fR when the channel was created. The function should
+release any storage maintained by the channel driver for this channel, and
+close the input and output devices encapsulated by this channel. All queued
+output will have been flushed to the device before this function is called,
+and no further driver operations will be invoked on this instance after
+calling the \fIcloseProc\fR. If the close operation is successful, the
+procedure should return zero; otherwise it should 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
+Alternatively, channels that support closing the read and write sides
+independently may set \fIcloseProc\fR to \fBTCL_CLOSE2PROC\fR and set
+\fIclose2Proc\fR to the address of a function that matches the
+following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverClose2Proc\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
+combination of \fBTCL_CLOSE_READ\fR or \fBTCL_CLOSE_WRITE\fR to
+indicate that the driver should close the read and/or write side of
+the channel. The channel driver may be invoked to perform
+additional operations on the channel after \fIclose2Proc\fR is
+called to close one or both sides of the channel. If \fIflags\fR is
+\fB0\fR (zero), the driver should close the channel in the manner
+described above for \fIcloseProc\fR. No further operations will be
+invoked on this instance after \fIclose2Proc\fR is called with all
+flags cleared. In all cases, the \fIclose2Proc\fR function should
+return zero if the close operation was successful; otherwise it should
+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
+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
+internal buffer. \fIInputProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverInputProc\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
+\fBTcl_CreateChannel\fR when the channel was created. The \fIbuf\fR
+argument points to an array of bytes in which to store input from the
+device, and the \fIbufSize\fR argument indicates how many bytes are
+available at \fIbuf\fR.
+.PP
+The \fIerrorCodePtr\fR argument points to an integer variable provided by
+the generic layer. If an error occurs, the function should set the variable
+to a POSIX error code that identifies the error that occurred.
+.PP
+The function should read data from the input device encapsulated by the
+channel and store it at \fIbuf\fR. On success, the function should return
+a nonnegative integer indicating how many bytes were read from the input
+device and stored at \fIbuf\fR. On error, the function should return -1. If
+an error occurs after some data has been read from the device, that data is
+lost.
+.PP
+If \fIinputProc\fR can determine that the input device has some data
+available but less than requested by the \fIbufSize\fR argument, the
+function should only attempt to read as much data as is available and
+return without blocking. If the input device has no data available
+whatsoever and the channel is in nonblocking mode, the function should
+return an \fBEAGAIN\fR error. If the input device has no data available
+whatsoever and the channel is in blocking mode, the function should block
+for the shortest possible time until at least one byte of data can be read
+from the device; then, it should return as much data as it can read without
+blocking.
+.PP
+This value can be retrieved with \fBTcl_ChannelInputProc\fR, which returns
+a pointer to the function.
+.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.
+\fIOutputProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverOutputProc\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
+\fBTcl_CreateChannel\fR when the channel was created. The \fIbuf\fR
+argument contains an array of bytes to be written to the device, and the
+\fItoWrite\fR argument indicates how many bytes are to be written from the
+\fIbuf\fR argument.
+.PP
+The \fIerrorCodePtr\fR argument points to an integer variable provided by
+the generic layer. If an error occurs, the function should set this
+variable to a POSIX error code that identifies the error.
+.PP
+The function should write the data at \fIbuf\fR to the output device
+encapsulated by the channel. On success, the function should return a
+nonnegative integer indicating how many bytes were written to the output
+device. The return value is normally the same as \fItoWrite\fR, but may be
+less in some cases such as if the output operation is interrupted by a
+signal. If an error occurs the function should return -1. In case of
+error, some data may have been written to the device.
+.PP
+If the channel is nonblocking and the output device is unable to absorb any
+data whatsoever, the function should return -1 with an \fBEAGAIN\fR error
+without writing any data.
+.PP
+This value can be retrieved with \fBTcl_ChannelOutputProc\fR, which returns
+a pointer to the function.
+.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
+operations will be applied. \fISeekProc\fR must match the following
+prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverSeekProc\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
+\fBTcl_CreateChannel\fR when this channel was created. \fIOffset\fR and
+\fIseekMode\fR have the same meaning as for the \fBTcl_Seek\fR
+procedure (described in the manual entry for \fBTcl_OpenFileChannel\fR).
+.PP
+The \fIerrorCodePtr\fR argument points to an integer variable provided by
+the generic layer for returning \fBerrno\fR values from the function. The
+function should set this variable to a POSIX error code if an error occurs.
+The function should store an \fBEINVAL\fR error code if the channel type
+does not implement seeking.
+.PP
+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
+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
+within files larger than 2GB. The \fIwideSeekProc\fR will be called
+in preference to the \fIseekProc\fR, but both must be defined if the
+\fIwideSeekProc\fR is defined. \fIWideSeekProc\fR must match the
+following prototype:
+.PP
+.CS
+typedef Tcl_WideInt \fBTcl_DriverWideSeekProc\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
+\fIseekProc\fR above, except that the type of offsets and the return
+type are different.
+.PP
+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.
+.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.
+\fIsetOptionProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverSetOptionProc\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
+the new value for that option, as a string. The \fIinstanceData\fR is the
+same as the value given to \fBTcl_CreateChannel\fR when this channel was
+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
+each channel type and the \fIsetOptionProc\fR procedure of the channel
+driver will get called to implement them. The \fIsetOptionProc\fR field can
+be NULL, which indicates that this channel type supports no type specific
+options.
+.PP
+If the option value is successfully modified to the new value, the function
+returns \fBTCL_OK\fR.
+It should call \fBTcl_BadChannelOption\fR which itself returns
+\fBTCL_ERROR\fR if the \fIoptionName\fR is
+unrecognized.
+If \fInewValue\fR specifies a value for the option that
+is not supported or if a system call error occurs,
+the function should leave an error message in the
+\fIresult\fR field of \fIinterp\fR if \fIinterp\fR is not NULL. The
+function should also call \fBTcl_SetErrno\fR to store an appropriate POSIX
+error code.
+.PP
+This value can be retrieved with \fBTcl_ChannelSetOptionProc\fR, which returns
+a pointer to the function.
+.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
+channel. \fIgetOptionProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverGetOptionProc\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
+channel. If the option name is not NULL, the function stores its current
+value, as a string, in the Tcl dynamic string \fIoptionValue\fR.
+If \fIoptionName\fR is NULL, the function stores in \fIoptionValue\fR an
+alternating list of all supported options and their current values.
+On success, the function returns \fBTCL_OK\fR.
+It should call \fBTcl_BadChannelOption\fR which itself returns
+\fBTCL_ERROR\fR if the \fIoptionName\fR is
+unrecognized. If a system call error occurs,
+the function should leave an error message in the
+result of \fIinterp\fR if \fIinterp\fR is not NULL. The
+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
+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
+specific options.
+.PP
+This value can be retrieved with \fBTcl_ChannelGetOptionProc\fR, which returns
+a pointer to the function.
+.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
+notice events of interest on this channel.
+\fIWatchProc\fR should match the following prototype:
+.PP
+.CS
+typedef void \fBTcl_DriverWatchProc\fR(
+ ClientData \fIinstanceData\fR,
+ int \fImask\fR);
+.CE
+.PP
+The \fIinstanceData\fR is the same as the value passed to
+\fBTcl_CreateChannel\fR when this channel was created. The \fImask\fR
+argument is an OR-ed combination of \fBTCL_READABLE\fR, \fBTCL_WRITABLE\fR
+and \fBTCL_EXCEPTION\fR; it indicates events the caller is interested in
+noticing on this channel.
+.PP
+The function should initialize device type specific mechanisms to
+notice when an event of interest is present on the channel. When one
+or more of the designated events occurs on the channel, the channel
+driver is responsible for calling \fBTcl_NotifyChannel\fR to inform
+the generic channel module. The driver should take care not to starve
+other channel drivers or sources of callbacks by invoking
+Tcl_NotifyChannel too frequently. Fairness can be insured by using
+the Tcl event queue to allow the channel event to be scheduled in sequence
+with other events. See the description of \fBTcl_QueueEvent\fR for
+details on how to queue an event.
+.PP
+This value can be retrieved with \fBTcl_ChannelWatchProc\fR, which returns
+a pointer to the function.
+.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.
+\fIGetHandleProc\fR should match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverGetHandleProc\fR(
+ ClientData \fIinstanceData\fR,
+ int \fIdirection\fR,
+ ClientData *\fIhandlePtr\fR);
+.CE
+.PP
+\fIInstanceData\fR is the same as the value passed to
+\fBTcl_CreateChannel\fR when this channel was created. The \fIdirection\fR
+argument is either \fBTCL_READABLE\fR to retrieve the handle used
+for input, or \fBTCL_WRITABLE\fR to retrieve the handle used for
+output.
+.PP
+If the channel implementation has device-specific handles, the
+function should retrieve the appropriate handle associated with the
+channel, according the \fIdirection\fR argument. The handle should be
+stored in the location referred to by \fIhandlePtr\fR, and
+\fBTCL_OK\fR should be returned. If the channel is not open for the
+specified direction, or if the channel implementation does not use
+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.
+.SS FLUSHPROC
+.PP
+The \fIflushProc\fR field is currently reserved for future use.
+It should be set to NULL.
+\fIFlushProc\fR should match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverFlushProc\fR(
+ ClientData \fIinstanceData\fR);
+.CE
+.PP
+This value can be retrieved with \fBTcl_ChannelFlushProc\fR, which returns
+a pointer to the function.
+.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
+be defined for stacked channel drivers that wish to be notified of events
+that occur on the underlying (stacked) channel.
+\fIHandlerProc\fR should match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverHandlerProc\fR(
+ ClientData \fIinstanceData\fR,
+ int \fIinterestMask\fR);
+.CE
+.PP
+\fIInstanceData\fR is the same as the value passed to \fBTcl_CreateChannel\fR
+when this channel was created. The \fIinterestMask\fR is an OR-ed
+combination of \fBTCL_READABLE\fR or \fBTCL_WRITABLE\fR; it indicates what
+type of event occurred on this channel.
+.PP
+This value can be retrieved with \fBTcl_ChannelHandlerProc\fR, which returns
+a pointer to the function.
+
+.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
+going to move to a different thread, i.e. whenever thread-specific
+driver state might have to initialized or updated. It can be NULL.
+The action \fITCL_CHANNEL_THREAD_REMOVE\fR is used to notify the
+driver that it should update or remove any thread-specific data it
+might be maintaining for the channel.
+.PP
+The action \fITCL_CHANNEL_THREAD_INSERT\fR is used to notify the
+driver that it should update or initialize any thread-specific data it
+might be maintaining using the calling thread as the associate. See
+\fBTcl_CutChannel\fR and \fBTcl_SpliceChannel\fR for more detail.
+.PP
+.CS
+typedef void \fBTcl_DriverThreadActionProc\fR(
+ ClientData \fIinstanceData\fR,
+ int \fIaction\fR);
+.CE
+.PP
+\fIInstanceData\fR is the same as the value passed to
+\fBTcl_CreateChannel\fR when this channel was created.
+.PP
+These values can be retrieved with \fBTcl_ChannelThreadActionProc\fR,
+which returns a pointer to the function.
+.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 \fBTcl_DriverTruncateProc\fR(
+ 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
+.QW "bad option"
+error message in an
+(optional) interpreter. It is used by channel drivers when
+an invalid Set/Get option is requested. Its purpose is to concatenate
+the generic options list to the specific ones and factorize
+the generic options error message string.
+.PP
+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 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
+.CE
+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
+.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 {
+ const 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;
+} \fBTcl_ChannelType\fR;
+.CE
+.PP
+It is still possible to create channel with the above structure. The
+internal channel code will determine the version. It is imperative to use
+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
+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 {
+ const 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;
+} \fBTcl_ChannelType\fR;
+.CE
+.PP
+When the above structure is registered as a channel type, the
+\fIversion\fR field should always be \fBTCL_CHANNEL_VERSION_2\fR.
+.SH "SEE ALSO"
+Tcl_Close(3), Tcl_OpenFileChannel(3), Tcl_SetErrno(3), Tcl_QueueEvent(3), Tcl_StackChannel(3), Tcl_GetStdChannel(3)
+.SH KEYWORDS
+blocking, channel driver, channel registration, channel type, nonblocking
diff --git a/library/msgcat/doc/CrtChnlHdlr.3 b/library/msgcat/doc/CrtChnlHdlr.3
new file mode 100644
index 0000000..1451e30
--- /dev/null
+++ b/library/msgcat/doc/CrtChnlHdlr.3
@@ -0,0 +1,89 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_CreateChannelHandler 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_CreateChannelHandler, Tcl_DeleteChannelHandler \- call a procedure when a channel becomes readable or writable
+.SH SYNOPSIS
+.nf
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_CreateChannelHandler\fR(\fIchannel, mask, proc, clientData\fR)
+.sp
+void
+\fBTcl_DeleteChannelHandler\fR(\fIchannel, proc, clientData\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_ChannelProc clientData
+.AP Tcl_Channel channel in
+Tcl channel such as returned by \fBTcl_CreateChannel\fR.
+.AP int mask in
+Conditions under which \fIproc\fR should be called: OR-ed combination of
+\fBTCL_READABLE\fR, \fBTCL_WRITABLE\fR and \fBTCL_EXCEPTION\fR. Specify
+a zero value to temporarily disable an existing handler.
+.AP Tcl_FileProc *proc in
+Procedure to invoke whenever the channel indicated by \fIchannel\fR meets
+the conditions specified by \fImask\fR.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateChannelHandler\fR arranges for \fIproc\fR to be called in the
+future whenever input or output becomes possible on the channel identified
+by \fIchannel\fR, or whenever an exceptional condition exists for
+\fIchannel\fR. The conditions of interest under which \fIproc\fR will be
+invoked are specified by the \fImask\fR argument.
+See the manual entry for \fBfileevent\fR for a precise description of
+what it means for a channel to be readable or writable.
+\fIProc\fR must conform to the following prototype:
+.PP
+.CS
+typedef void \fBTcl_ChannelProc\fR(
+ ClientData \fIclientData\fR,
+ int \fImask\fR);
+.CE
+.PP
+The \fIclientData\fR argument is the same as the value passed to
+\fBTcl_CreateChannelHandler\fR when the handler was created. Typically,
+\fIclientData\fR points to a data structure containing application-specific
+information about the channel. \fIMask\fR is an integer mask indicating
+which of the requested conditions actually exists for the channel; it will
+contain a subset of the bits from the \fImask\fR argument to
+\fBTcl_CreateChannelHandler\fR when the handler was created.
+.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 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
+handler is created; instead, the \fImask\fR is changed for the
+existing handler.
+.PP
+\fBTcl_DeleteChannelHandler\fR deletes a channel handler identified by
+\fIchannel\fR, \fIproc\fR and \fIclientData\fR; if no such handler exists,
+the call has no effect.
+.PP
+Channel handlers are invoked via the Tcl event mechanism, so they
+are only useful in applications that are event-driven.
+Note also that the conditions specified in the \fImask\fR argument
+to \fIproc\fR may no longer exist when \fIproc\fR is invoked: for
+example, if there are two handlers for \fBTCL_READABLE\fR on the same
+channel, the first handler could consume all of the available input
+so that the channel is no longer readable when the second handler
+is invoked.
+For this reason it may be useful to use nonblocking I/O on channels
+for which there are event handlers.
+.SH "SEE ALSO"
+Notifier(3), Tcl_CreateChannel(3), Tcl_OpenFileChannel(3), vwait(n).
+.SH KEYWORDS
+blocking, callback, channel, events, handler, nonblocking.
diff --git a/library/msgcat/doc/CrtCloseHdlr.3 b/library/msgcat/doc/CrtCloseHdlr.3
new file mode 100644
index 0000000..a114f9c
--- /dev/null
+++ b/library/msgcat/doc/CrtCloseHdlr.3
@@ -0,0 +1,55 @@
+'\"
+'\" 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 Tcl_CreateCloseHandler 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_CreateCloseHandler, Tcl_DeleteCloseHandler \- arrange for callbacks when channels are closed
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_CreateCloseHandler\fR(\fIchannel, proc, clientData\fR)
+.sp
+void
+\fBTcl_DeleteCloseHandler\fR(\fIchannel, proc, clientData\fR)
+.sp
+.SH ARGUMENTS
+.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
+The procedure to call as the callback.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateCloseHandler\fR arranges for \fIproc\fR to be called when
+\fIchannel\fR is closed with \fBTcl_Close\fR or
+\fBTcl_UnregisterChannel\fR, or using the Tcl \fBclose\fR command.
+\fIProc\fR should match the following prototype:
+.PP
+.CS
+typedef void \fBTcl_CloseProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR is the same as the value provided in the call to
+\fBTcl_CreateCloseHandler\fR.
+.PP
+\fBTcl_DeleteCloseHandler\fR removes a close callback for \fIchannel\fR.
+The \fIproc\fR and \fIclientData\fR identify which close callback to
+remove; \fBTcl_DeleteCloseHandler\fR does nothing if its \fIproc\fR and
+\fIclientData\fR arguments do not match the \fIproc\fR and \fIclientData\fR
+for a close handler for \fIchannel\fR.
+.SH "SEE ALSO"
+close(n), Tcl_Close(3), Tcl_UnregisterChannel(3)
+.SH KEYWORDS
+callback, channel closing
diff --git a/library/msgcat/doc/CrtCommand.3 b/library/msgcat/doc/CrtCommand.3
new file mode 100644
index 0000000..f0a7b43
--- /dev/null
+++ b/library/msgcat/doc/CrtCommand.3
@@ -0,0 +1,143 @@
+'\"
+'\" Copyright (c) 1989-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.
+'\"
+.so man.macros
+.TH Tcl_CreateCommand 3 "" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CreateCommand \- implement new commands in C
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Command
+\fBTcl_CreateCommand\fR(\fIinterp, cmdName, proc, clientData, deleteProc\fR)
+.SH ARGUMENTS
+.AS Tcl_CmdDeleteProc *deleteProc
+.AP Tcl_Interp *interp in
+Interpreter in which to create new command.
+.AP "const char" *cmdName in
+Name of command.
+.AP Tcl_CmdProc *proc in
+Implementation of new command: \fIproc\fR will be called whenever
+\fIcmdName\fR is invoked as a command.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR and \fIdeleteProc\fR.
+.AP Tcl_CmdDeleteProc *deleteProc in
+Procedure to call before \fIcmdName\fR is deleted from the interpreter;
+allows for command-specific cleanup. If NULL, then no procedure is
+called before the command is deleted.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateCommand\fR defines a new command in \fIinterp\fR and associates
+it with procedure \fIproc\fR such that whenever \fIcmdName\fR is
+invoked as a Tcl command (via a call to \fBTcl_Eval\fR) the Tcl interpreter
+will call \fIproc\fR to process the command.
+It differs from \fBTcl_CreateObjCommand\fR in that a new string-based
+command is defined;
+that is, a command procedure is defined that takes an array of
+argument strings instead of objects.
+The object-based command procedures registered by \fBTcl_CreateObjCommand\fR
+can execute significantly faster than the string-based command procedures
+defined by \fBTcl_CreateCommand\fR.
+This is because they take Tcl objects as arguments
+and those objects can retain an internal representation that
+can be manipulated more efficiently.
+Also, Tcl's interpreter now uses objects internally.
+In order to invoke a string-based command procedure
+registered by \fBTcl_CreateCommand\fR,
+it must generate and fetch a string representation
+from each argument object before the call.
+New commands should be defined using \fBTcl_CreateObjCommand\fR.
+We support \fBTcl_CreateCommand\fR for backwards compatibility.
+.PP
+The procedures \fBTcl_DeleteCommand\fR, \fBTcl_GetCommandInfo\fR,
+and \fBTcl_SetCommandInfo\fR are used in conjunction with
+\fBTcl_CreateCommand\fR.
+.PP
+\fBTcl_CreateCommand\fR will delete an existing command \fIcmdName\fR,
+if one is already associated with the interpreter.
+It returns a token that may be used to refer
+to the command in subsequent calls to \fBTcl_GetCommandName\fR.
+If \fIcmdName\fR contains any \fB::\fR namespace qualifiers,
+then the command is added to the specified namespace;
+otherwise the command is added to the global namespace.
+If \fBTcl_CreateCommand\fR is called for an interpreter that is in
+the process of being deleted, then it does not create a new command
+and it returns NULL.
+\fIProc\fR should have arguments and result that match the type
+\fBTcl_CmdProc\fR:
+.PP
+.CS
+typedef int \fBTcl_CmdProc\fR(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ int \fIargc\fR,
+ const char *\fIargv\fR[]);
+.CE
+.PP
+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 \fBTcl_CreateCommand\fR.
+Typically, \fIclientData\fR points to an application-specific
+data structure that describes what to do when the command procedure
+is invoked. \fIArgc\fR and \fIargv\fR describe the arguments to
+the command, \fIargc\fR giving the number of arguments (including
+the command name) and \fIargv\fR giving the values of the arguments
+as strings. The \fIargv\fR array will contain \fIargc\fR+1 values;
+the first \fIargc\fR values point to the argument strings, and the
+last value is NULL.
+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.
+.PP
+Note that the argument strings are encoded in normalized UTF-8 since
+version 8.1 of Tcl.
+.PP
+\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;
+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 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,
+so simple commands can return an empty result by doing nothing at all.
+.PP
+The contents of the \fIargv\fR array belong to Tcl and are not
+guaranteed to persist once \fIproc\fR returns: \fIproc\fR should
+not modify them, nor should it set the interpreter result to point
+anywhere within the \fIargv\fR values.
+Call \fBTcl_SetResult\fR with status \fBTCL_VOLATILE\fR if you want
+to return something from the \fIargv\fR array.
+.PP
+\fIDeleteProc\fR will be invoked when (if) \fIcmdName\fR is deleted. This can
+occur through a call to \fBTcl_DeleteCommand\fR or \fBTcl_DeleteInterp\fR,
+or by replacing \fIcmdName\fR in another call to \fBTcl_CreateCommand\fR.
+\fIDeleteProc\fR is invoked before the command is deleted, and gives the
+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:
+.PP
+.CS
+typedef void \fBTcl_CmdDeleteProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR argument will be the same as the \fIclientData\fR
+argument passed to \fBTcl_CreateCommand\fR.
+.SH "SEE ALSO"
+Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_GetCommandInfo,
+Tcl_SetCommandInfo, Tcl_GetCommandName, Tcl_SetObjResult
+.SH KEYWORDS
+bind, command, create, delete, interpreter, namespace
diff --git a/library/msgcat/doc/CrtFileHdlr.3 b/library/msgcat/doc/CrtFileHdlr.3
new file mode 100644
index 0000000..cbc5e9f
--- /dev/null
+++ b/library/msgcat/doc/CrtFileHdlr.3
@@ -0,0 +1,91 @@
+'\"
+'\" Copyright (c) 1990-1994 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.
+'\"
+.so man.macros
+.TH Tcl_CreateFileHandler 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CreateFileHandler, Tcl_DeleteFileHandler \- associate procedure callbacks with files or devices (Unix only)
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_CreateFileHandler\fR(\fIfd, mask, proc, clientData\fR)
+.sp
+\fBTcl_DeleteFileHandler\fR(\fIfd\fR)
+.SH ARGUMENTS
+.AS Tcl_FileProc clientData
+.AP int fd in
+Unix file descriptor for an open file or device.
+.AP int mask in
+Conditions under which \fIproc\fR should be called:
+OR-ed combination of \fBTCL_READABLE\fR, \fBTCL_WRITABLE\fR,
+and \fBTCL_EXCEPTION\fR. May be set to 0 to temporarily disable
+a handler.
+.AP Tcl_FileProc *proc in
+Procedure to invoke whenever the file or device indicated
+by \fIfile\fR meets the conditions specified by \fImask\fR.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+\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
+are indicated by \fImask\fR. For example, if \fImask\fR
+is \fBTCL_READABLE\fR, \fIproc\fR will be called when
+the file is readable.
+The callback to \fIproc\fR is made by \fBTcl_DoOneEvent\fR, so
+\fBTcl_CreateFileHandler\fR is only useful in programs that dispatch
+events through \fBTcl_DoOneEvent\fR or through Tcl commands such
+as \fBvwait\fR.
+.PP
+\fIProc\fR should have arguments and result that match the
+type \fBTcl_FileProc\fR:
+.PP
+.CS
+typedef void \fBTcl_FileProc\fR(
+ ClientData \fIclientData\fR,
+ int \fImask\fR);
+.CE
+.PP
+The \fIclientData\fR parameter to \fIproc\fR is a copy
+of the \fIclientData\fR
+argument given to \fBTcl_CreateFileHandler\fR when the callback
+was created. Typically, \fIclientData\fR points to a data
+structure containing application-specific information about
+the file. \fIMask\fR is an integer mask indicating which
+of the requested conditions actually exists for the file; it
+will contain a subset of the bits in the \fImask\fR argument
+to \fBTcl_CreateFileHandler\fR.
+.PP
+There may exist only one handler for a given file at a given time.
+If \fBTcl_CreateFileHandler\fR is called when a handler already
+exists for \fIfd\fR, then the new callback replaces the information
+that was previously recorded.
+.PP
+\fBTcl_DeleteFileHandler\fR may be called to delete the
+file handler for \fIfd\fR; if no handler exists for the
+file given by \fIfd\fR then the procedure has no effect.
+.PP
+The purpose of file handlers is to enable an application to respond to
+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 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
+Note that these interfaces are only supported by the Unix
+implementation of the Tcl notifier.
+.SH "SEE ALSO"
+fileevent(n), Tcl_CreateTimerHandler(3), Tcl_DoWhenIdle(3)
+.SH KEYWORDS
+callback, file, handler
diff --git a/library/msgcat/doc/CrtInterp.3 b/library/msgcat/doc/CrtInterp.3
new file mode 100644
index 0000000..a248cf4
--- /dev/null
+++ b/library/msgcat/doc/CrtInterp.3
@@ -0,0 +1,149 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_CreateInterp 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CreateInterp, Tcl_DeleteInterp, Tcl_InterpActive, Tcl_InterpDeleted \- create and delete Tcl command interpreters
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Interp *
+\fBTcl_CreateInterp\fR()
+.sp
+\fBTcl_DeleteInterp\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_InterpDeleted\fR(\fIinterp\fR)
+.sp
+.VS 8.6
+int
+\fBTcl_InterpActive\fR(\fIinterp\fR)
+.VE 8.6
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Token for interpreter to be destroyed or queried.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateInterp\fR creates a new interpreter structure and returns
+a token for it. The token is required in calls to most other Tcl
+procedures, such as \fBTcl_CreateCommand\fR, \fBTcl_Eval\fR, and
+\fBTcl_DeleteInterp\fR. The token returned by \fBTcl_CreateInterp\fR
+may only be passed to Tcl routines called from the same thread as
+the original \fBTcl_CreateInterp\fR call. It is not safe for multiple
+threads to pass the same token to Tcl's routines.
+The new interpreter is initialized with the built-in Tcl commands
+and with the variables documented in the \fBtclvars\fR manual page. To bind in
+additional commands, call \fBTcl_CreateCommand\fR.
+.PP
+\fBTcl_DeleteInterp\fR marks an interpreter as deleted; the interpreter
+will eventually be deleted when all calls to \fBTcl_Preserve\fR for it have
+been matched by calls to \fBTcl_Release\fR. At that time, all of the
+resources associated with it, including variables, procedures, and
+application-specific command bindings, will be deleted. After
+\fBTcl_DeleteInterp\fR returns any attempt to use \fBTcl_Eval\fR on the
+interpreter will fail and return \fBTCL_ERROR\fR. After the call to
+\fBTcl_DeleteInterp\fR it is safe to examine the interpreter's result,
+query or set the values of variables, define, undefine or retrieve
+procedures, and examine the runtime evaluation stack. See below, in the
+section \fBINTERPRETERS AND MEMORY MANAGEMENT\fR for details.
+.PP
+\fBTcl_InterpDeleted\fR returns nonzero if \fBTcl_DeleteInterp\fR was
+called with \fIinterp\fR as its argument; this indicates that the
+interpreter will eventually be deleted, when the last call to
+\fBTcl_Preserve\fR for it is matched by a call to \fBTcl_Release\fR. If
+nonzero is returned, further calls to \fBTcl_Eval\fR in this interpreter
+will return \fBTCL_ERROR\fR.
+.PP
+\fBTcl_InterpDeleted\fR is useful in deletion callbacks to distinguish
+between when only the memory the callback is responsible for is being
+deleted and when the whole interpreter is being deleted. In the former case
+the callback may recreate the data being deleted, but this would lead to an
+infinite loop if the interpreter were being deleted.
+.PP
+.VS 8.6
+\fBTcl_InterpActive\fR is useful for determining whether there is any
+execution of scripts ongoing in an interpreter, which is a useful piece of
+information when Tcl is embedded in a garbage-collected environment and it
+becomes necessary to determine whether the interpreter is a candidate for
+deletion. The function returns a true value if the interpreter has at least
+one active execution running inside it, and a false value otherwise.
+.VE 8.6
+.SH "INTERPRETERS AND MEMORY MANAGEMENT"
+.PP
+\fBTcl_DeleteInterp\fR can be called at any time on an interpreter that may
+be used by nested evaluations and C code in various extensions. Tcl
+implements a simple mechanism that allows callers to use interpreters
+without worrying about the interpreter being deleted in a nested call, and
+without requiring special code to protect the interpreter, in most cases.
+This mechanism ensures that nested uses of an interpreter can safely
+continue using it even after \fBTcl_DeleteInterp\fR is called.
+.PP
+The mechanism relies on matching up calls to \fBTcl_Preserve\fR with calls
+to \fBTcl_Release\fR. If \fBTcl_DeleteInterp\fR has been called, only when
+the last call to \fBTcl_Preserve\fR is matched by a call to
+\fBTcl_Release\fR, will the interpreter be freed. See the manual entry for
+\fBTcl_Preserve\fR for a description of these functions.
+.PP
+The rules for when the user of an interpreter must call \fBTcl_Preserve\fR
+and \fBTcl_Release\fR are simple:
+.TP
+\fBInterpreters Passed As Arguments\fR
+.
+Functions that are passed an interpreter as an argument can safely use the
+interpreter without any special protection. Thus, when you write an
+extension consisting of new Tcl commands, no special code is needed to
+protect interpreters received as arguments. This covers the majority of all
+uses.
+.TP
+\fBInterpreter Creation And Deletion\fR
+.
+When a new interpreter is created and used in a call to \fBTcl_Eval\fR,
+\fBTcl_VarEval\fR, \fBTcl_GlobalEval\fR, \fBTcl_SetVar\fR, or
+\fBTcl_GetVar\fR, a pair of calls to \fBTcl_Preserve\fR and
+\fBTcl_Release\fR should be wrapped around all uses of the interpreter.
+Remember that it is unsafe to use the interpreter once \fBTcl_Release\fR
+has been called. To ensure that the interpreter is properly deleted when
+it is no longer needed, call \fBTcl_InterpDeleted\fR to test if some other
+code already called \fBTcl_DeleteInterp\fR; if not, call
+\fBTcl_DeleteInterp\fR before calling \fBTcl_Release\fR in your own code.
+.TP
+\fBRetrieving An Interpreter From A Data Structure\fR
+.
+When an interpreter is retrieved from a data structure (e.g. the client
+data of a callback) for use in one of the evaluation functions
+(\fBTcl_Eval\fR, \fBTcl_VarEval\fR, \fBTcl_GlobalEval\fR, \fBTcl_EvalObjv\fR,
+etc.) or variable access functions (\fBTcl_SetVar\fR, \fBTcl_GetVar\fR,
+\fBTcl_SetVar2Ex\fR, etc.), a pair of
+calls to \fBTcl_Preserve\fR and \fBTcl_Release\fR should be wrapped around
+all uses of the interpreter; it is unsafe to reuse the interpreter once
+\fBTcl_Release\fR has been called. If an interpreter is stored inside a
+callback data structure, an appropriate deletion cleanup mechanism should
+be set up by the code that creates the data structure so that the
+interpreter is removed from the data structure (e.g. by setting the field
+to NULL) when the interpreter is deleted. Otherwise, you may be using an
+interpreter that has been freed and whose memory may already have been
+reused.
+.PP
+All uses of interpreters in Tcl and Tk have already been protected.
+Extension writers should ensure that their code also properly protects any
+additional interpreters used, as described above.
+.PP
+.VS 8.6
+Note that the protection mechanisms do not work well with conventional garbage
+collection systems. When in such a managed environment, \fBTcl_InterpActive\fR
+should be used to determine when an interpreter is a candidate for deletion
+due to inactivity.
+.VE 8.6
+.SH "SEE ALSO"
+Tcl_Preserve(3), Tcl_Release(3), tclvars(n)
+.SH KEYWORDS
+command, create, delete, interpreter
diff --git a/library/msgcat/doc/CrtMathFnc.3 b/library/msgcat/doc/CrtMathFnc.3
new file mode 100644
index 0000000..3f2c84e
--- /dev/null
+++ b/library/msgcat/doc/CrtMathFnc.3
@@ -0,0 +1,155 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_CreateMathFunc 3 8.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CreateMathFunc, Tcl_GetMathFuncInfo, Tcl_ListMathFuncs \- Define, query and enumerate math functions for expressions
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_CreateMathFunc\fR(\fIinterp, name, numArgs, argTypes, proc, clientData\fR)
+.sp
+int
+\fBTcl_GetMathFuncInfo\fR(\fIinterp, name, numArgsPtr, argTypesPtr, procPtr,
+ clientDataPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ListMathFuncs\fR(\fIinterp, pattern\fR)
+.SH ARGUMENTS
+.AS Tcl_ValueType *clientDataPtr out
+.AP Tcl_Interp *interp in
+Interpreter in which new function will be defined.
+.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.
+.AP Tcl_ValueType *argTypes in
+Points to an array giving the permissible types for each argument to
+function.
+.AP Tcl_MathProc *proc in
+Procedure that implements the function.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR when it is invoked.
+.AP int *numArgsPtr out
+Points to a variable that will be set to contain the number of
+arguments to the function.
+.AP Tcl_ValueType **argTypesPtr out
+Points to a variable that will be set to contain a pointer to an array
+giving the permissible types for each argument to the function which
+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).
+.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
+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
+.SH DESCRIPTION
+.PP
+Tcl allows a number of mathematical functions to be used in
+expressions, such as \fBsin\fR, \fBcos\fR, and \fBhypot\fR.
+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 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
+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.
+.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:
+.PP
+.CS
+typedef int \fBTcl_MathProc\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:
+.PP
+.CS
+typedef struct Tcl_Value {
+ Tcl_ValueType \fItype\fR;
+ long \fIintValue\fR;
+ double \fIdoubleValue\fR;
+ Tcl_WideInt \fIwideValue\fR;
+} \fBTcl_Value\fR;
+.CE
+.PP
+The \fItype\fR field indicates the type of the argument and is
+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 \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,
+\fIdoubleValue\fR or \fIwideValue\fR
+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
+\fBTCL_INT\fR, \fBTCL_DOUBLE\fR or \fBTCL_WIDE_INT\fR
+to indicate which value was set.
+Under normal circumstances \fIproc\fR should return \fBTCL_OK\fR.
+If an error occurs while executing the function, \fIproc\fR should
+return \fBTCL_ERROR\fR and leave an error message in the interpreter's result.
+.PP
+\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
+\fBTCL_OK\fR but if the named function does not exist, \fBTCL_ERROR\fR
+is returned and an error message is placed in the interpreter's
+result.
+.PP
+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, 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. 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
diff --git a/library/msgcat/doc/CrtObjCmd.3 b/library/msgcat/doc/CrtObjCmd.3
new file mode 100644
index 0000000..343b3dd
--- /dev/null
+++ b/library/msgcat/doc/CrtObjCmd.3
@@ -0,0 +1,302 @@
+'\"
+'\" Copyright (c) 1996-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 Tcl_CreateObjCommand 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_DeleteCommandFromToken, Tcl_GetCommandInfo, Tcl_GetCommandInfoFromToken, Tcl_SetCommandInfo, Tcl_SetCommandInfoFromToken, Tcl_GetCommandName, Tcl_GetCommandFullName, Tcl_GetCommandFromObj \- implement new commands in C
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Command
+\fBTcl_CreateObjCommand\fR(\fIinterp, cmdName, proc, clientData, deleteProc\fR)
+.sp
+int
+\fBTcl_DeleteCommand\fR(\fIinterp, cmdName\fR)
+.sp
+int
+\fBTcl_DeleteCommandFromToken\fR(\fIinterp, token\fR)
+.sp
+int
+\fBTcl_GetCommandInfo\fR(\fIinterp, cmdName, infoPtr\fR)
+.sp
+int
+\fBTcl_SetCommandInfo\fR(\fIinterp, cmdName, infoPtr\fR)
+.sp
+int
+\fBTcl_GetCommandInfoFromToken\fR(\fItoken, infoPtr\fR)
+.sp
+int
+\fBTcl_SetCommandInfoFromToken\fR(\fItoken, infoPtr\fR)
+.sp
+const char *
+\fBTcl_GetCommandName\fR(\fIinterp, token\fR)
+.sp
+void
+\fBTcl_GetCommandFullName\fR(\fIinterp, token, objPtr\fR)
+.sp
+Tcl_Command
+\fBTcl_GetCommandFromObj\fR(\fIinterp, objPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_CmdDeleteProc *deleteProc in/out
+.AP Tcl_Interp *interp in
+Interpreter in which to create a new command or that contains a command.
+.AP char *cmdName in
+Name of command.
+.AP Tcl_ObjCmdProc *proc in
+Implementation of the new command: \fIproc\fR will be called whenever
+\fIcmdName\fR is invoked as a command.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR and \fIdeleteProc\fR.
+.AP Tcl_CmdDeleteProc *deleteProc in
+Procedure to call before \fIcmdName\fR is deleted from the interpreter;
+allows for command-specific cleanup. If NULL, then no procedure is
+called before the command is deleted.
+.AP Tcl_Command token in
+Token for command, returned by previous call to \fBTcl_CreateObjCommand\fR.
+The command must not have been deleted.
+.AP Tcl_CmdInfo *infoPtr in/out
+Pointer to structure containing various information about a
+Tcl command.
+.AP Tcl_Obj *objPtr in
+Object containing the name of a Tcl command.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateObjCommand\fR defines a new command in \fIinterp\fR
+and associates it with procedure \fIproc\fR
+such that whenever \fIname\fR is
+invoked as a Tcl command (e.g., via a call to \fBTcl_EvalObjEx\fR)
+the Tcl interpreter will call \fIproc\fR to process the command.
+.PP
+\fBTcl_CreateObjCommand\fR deletes any existing command
+\fIname\fR already associated with the interpreter
+(however see below for an exception where the existing command
+is not deleted).
+It returns a token that may be used to refer
+to the command in subsequent calls to \fBTcl_GetCommandName\fR.
+If \fIname\fR contains any \fB::\fR namespace qualifiers,
+then the command is added to the specified namespace;
+otherwise the command is added to the global namespace.
+If \fBTcl_CreateObjCommand\fR is called for an interpreter that is in
+the process of being deleted, then it does not create a new command
+and it returns NULL.
+\fIproc\fR should have arguments and result that match the type
+\fBTcl_ObjCmdProc\fR:
+.PP
+.CS
+typedef int \fBTcl_ObjCmdProc\fR(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ int \fIobjc\fR,
+ Tcl_Obj *const \fIobjv\fR[]);
+.CE
+.PP
+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
+\fBTcl_CreateObjCommand\fR. Typically, \fIclientData\fR points to an
+application-specific data structure that describes what to do when the
+command procedure is invoked. \fIObjc\fR and \fIobjv\fR describe the
+arguments to the command, \fIobjc\fR giving the number of argument objects
+(including the command name) and \fIobjv\fR giving the values of the
+arguments. The \fIobjv\fR array will contain \fIobjc\fR values, pointing to
+the argument objects. Unlike \fIargv\fR[\fIargv\fR] used in a
+string-based command procedure, \fIobjv\fR[\fIobjc\fR] will not contain NULL.
+.PP
+Additionally, when \fIproc\fR is invoked, it must not modify the contents
+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
+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
+\fBTcl_GetIntFromObj\fR on \fIobjv\fR[\fB2\fR] to obtain the integer
+representation of that object; that call may change the type of the object
+that \fIobjv\fR[\fB2\fR] points at, but will not change where
+\fIobjv\fR[\fB2\fR] points.
+.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
+for details on what these codes mean. Most normal commands will only
+return \fBTCL_OK\fR or \fBTCL_ERROR\fR.
+In addition, if \fIproc\fR needs to return a non-empty result,
+it can call \fBTcl_SetObjResult\fR to set the interpreter's result.
+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 this gives an error message.
+Before invoking a command procedure,
+\fBTcl_EvalObjEx\fR sets interpreter's result to
+point to an object representing an empty string, so simple
+commands can return an empty result by doing nothing at all.
+.PP
+The contents of the \fIobjv\fR array belong to Tcl and are not
+guaranteed to persist once \fIproc\fR returns: \fIproc\fR should
+not modify them.
+Call \fBTcl_SetObjResult\fR if you want
+to return something from the \fIobjv\fR array.
+.PP
+Ordinarily, \fBTcl_CreateObjCommand\fR deletes any existing command
+\fIname\fR already associated with the interpreter.
+However, if the existing command was created by a previous call to
+\fBTcl_CreateCommand\fR,
+\fBTcl_CreateObjCommand\fR does not delete the command
+but instead arranges for the Tcl interpreter to call the
+\fBTcl_ObjCmdProc\fR \fIproc\fR in the future.
+The old string-based \fBTcl_CmdProc\fR associated with the command
+is retained and its address can be obtained by subsequent
+\fBTcl_GetCommandInfo\fR calls. This is done for backwards compatibility.
+.PP
+\fIDeleteProc\fR will be invoked when (if) \fIname\fR is deleted.
+This can occur through a call to \fBTcl_DeleteCommand\fR,
+\fBTcl_DeleteCommandFromToken\fR, or \fBTcl_DeleteInterp\fR,
+or by replacing \fIname\fR in another call to \fBTcl_CreateObjCommand\fR.
+\fIDeleteProc\fR is invoked before the command is deleted, and gives the
+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:
+.PP
+.CS
+typedef void \fBTcl_CmdDeleteProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR argument will be the same as the \fIclientData\fR
+argument passed to \fBTcl_CreateObjCommand\fR.
+.PP
+\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 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
+a built-in command, an application-specific command, or a Tcl procedure.
+If \fIname\fR contains any \fB::\fR namespace qualifiers,
+the command is deleted from the specified namespace.
+.PP
+Given a token returned by \fBTcl_CreateObjCommand\fR,
+\fBTcl_DeleteCommandFromToken\fR deletes the command
+from a command interpreter.
+It will delete a command even if that command has been renamed.
+Once the call completes, attempts to invoke the command in
+\fIinterp\fR will result in errors.
+If the command corresponding to \fItoken\fR
+has already been deleted from \fIinterp\fR then
+\fBTcl_DeleteCommand\fR does nothing and returns -1;
+otherwise it returns 0.
+.PP
+\fBTcl_GetCommandInfo\fR checks to see whether its \fIcmdName\fR argument
+exists as a command in \fIinterp\fR.
+\fIcmdName\fR may include \fB::\fR namespace qualifiers
+to identify a command in a particular namespace.
+If the command is not found, then it returns 0.
+Otherwise it places information about the command
+in the \fBTcl_CmdInfo\fR structure
+pointed to by \fIinfoPtr\fR and returns 1.
+A \fBTcl_CmdInfo\fR structure has the following fields:
+.PP
+.CS
+typedef struct Tcl_CmdInfo {
+ 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;
+} \fBTcl_CmdInfo\fR;
+.CE
+.PP
+The \fIisNativeObjectProc\fR field has the value 1
+if \fBTcl_CreateObjCommand\fR was called to register the command;
+it is 0 if only \fBTcl_CreateCommand\fR was called.
+It allows a program to determine whether it is faster to
+call \fIobjProc\fR or \fIproc\fR:
+\fIobjProc\fR is normally faster
+if \fIisNativeObjectProc\fR has the value 1.
+The fields \fIobjProc\fR and \fIobjClientData\fR
+have the same meaning as the \fIproc\fR and \fIclientData\fR
+arguments to \fBTcl_CreateObjCommand\fR;
+they hold information about the object-based command procedure
+that the Tcl interpreter calls to implement the command.
+The fields \fIproc\fR and \fIclientData\fR
+hold information about the string-based command procedure
+that implements the command.
+If \fBTcl_CreateCommand\fR was called for this command,
+this is the procedure passed to it;
+otherwise, this is a compatibility procedure
+registered by \fBTcl_CreateObjCommand\fR
+that simply calls the command's
+object-based procedure after converting its string arguments to Tcl objects.
+The field \fIdeleteData\fR is the ClientData value
+to pass to \fIdeleteProc\fR; it is normally the same as
+\fIclientData\fR but may be set independently using the
+\fBTcl_SetCommandInfo\fR procedure.
+The field \fInamespacePtr\fR holds a pointer to the
+Tcl_Namespace that contains the command.
+.PP
+\fBTcl_GetCommandInfoFromToken\fR is identical to
+\fBTcl_GetCommandInfo\fR except that it uses a command token returned
+from \fBTcl_CreateObjCommand\fR in place of the command name. If the
+\fItoken\fR parameter is NULL, it returns 0; otherwise, it returns 1
+and fills in the structure designated by \fIinfoPtr\fR.
+.PP
+\fBTcl_SetCommandInfo\fR is used to modify the procedures and
+ClientData values associated with a command.
+Its \fIcmdName\fR argument is the name of a command in \fIinterp\fR.
+\fIcmdName\fR may include \fB::\fR namespace qualifiers
+to identify a command in a particular namespace.
+If this command does not exist then \fBTcl_SetCommandInfo\fR returns 0.
+Otherwise, it copies the information from \fI*infoPtr\fR to
+Tcl's internal structure for the command and returns 1.
+.PP
+\fBTcl_SetCommandInfoFromToken\fR is identical to
+\fBTcl_SetCommandInfo\fR except that it takes a command token as
+returned by \fBTcl_CreateObjCommand\fR instead of the command name.
+If the \fItoken\fR parameter is NULL, it returns 0. Otherwise, it
+copies the information from \fI*infoPtr\fR to Tcl's internal structure
+for the command and returns 1.
+.PP
+Note that \fBTcl_SetCommandInfo\fR and
+\fBTcl_SetCommandInfoFromToken\fR both allow the ClientData for a
+command's deletion procedure to be given a different value than the
+ClientData for its command procedure.
+.PP
+Note that neither \fBTcl_SetCommandInfo\fR nor
+\fBTcl_SetCommandInfoFromToken\fR will change a command's namespace.
+Use \fBTcl_Eval\fR to call the \fBrename\fR command to do that.
+.PP
+\fBTcl_GetCommandName\fR provides a mechanism for tracking commands
+that have been renamed.
+Given a token returned by \fBTcl_CreateObjCommand\fR
+when the command was created, \fBTcl_GetCommandName\fR returns the
+string name of the command. If the command has been renamed since it
+was created, then \fBTcl_GetCommandName\fR returns the current name.
+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 is not deleted or renamed; callers should copy the string if
+they need to keep it for a long time.
+.PP
+\fBTcl_GetCommandFullName\fR produces the fully qualified name
+of a command from a command token.
+The name, including all namespace prefixes,
+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\fR.
+The command name is resolved relative to the current namespace.
+Returns NULL if the command is not found.
+.SH "SEE ALSO"
+Tcl_CreateCommand(3), Tcl_ResetResult(3), Tcl_SetObjResult(3)
+.SH KEYWORDS
+bind, command, create, delete, namespace, object
diff --git a/library/msgcat/doc/CrtSlave.3 b/library/msgcat/doc/CrtSlave.3
new file mode 100644
index 0000000..3863373
--- /dev/null
+++ b/library/msgcat/doc/CrtSlave.3
@@ -0,0 +1,236 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.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
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_IsSafe\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_MakeSafe\fR(\fIinterp\fR)
+.sp
+Tcl_Interp *
+\fBTcl_CreateSlave\fR(\fIinterp, slaveName, isSafe\fR)
+.sp
+Tcl_Interp *
+\fBTcl_GetSlave\fR(\fIinterp, slaveName\fR)
+.sp
+Tcl_Interp *
+\fBTcl_GetMaster\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_GetInterpPath\fR(\fIaskingInterp, slaveInterp\fR)
+.sp
+int
+\fBTcl_CreateAlias\fR(\fIslaveInterp, slaveCmd, targetInterp, targetCmd,
+ argc, argv\fR)
+.sp
+int
+\fBTcl_CreateAliasObj\fR(\fIslaveInterp, slaveCmd, targetInterp, targetCmd,
+ objc, objv\fR)
+.sp
+int
+\fBTcl_GetAlias\fR(\fIinterp, slaveCmd, targetInterpPtr, targetCmdPtr,
+ argcPtr, argvPtr\fR)
+.sp
+int
+\fBTcl_GetAliasObj\fR(\fIinterp, slaveCmd, targetInterpPtr, targetCmdPtr,
+ objcPtr, objvPtr\fR)
+.sp
+int
+\fBTcl_ExposeCommand\fR(\fIinterp, hiddenCmdName, cmdName\fR)
+.sp
+int
+\fBTcl_HideCommand\fR(\fIinterp, cmdName, hiddenCmdName\fR)
+.SH ARGUMENTS
+.AS "const char *const" **targetInterpPtr out
+.AP Tcl_Interp *interp in
+Interpreter in which to execute the specified command.
+.AP "const char" *slaveName in
+Name of slave interpreter to create or manipulate.
+.AP int isSafe in
+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
+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
+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
+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_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
+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
+Pointer to location to store a vector of strings, the additional arguments
+to pass to an alias. The location is in storage owned by the caller, the
+vector of strings is owned by the called function.
+.AP int *objcPtr out
+Pointer to location to store count of additional object arguments to be
+passed to the alias. The location is in storage owned by the caller.
+.AP Tcl_Obj ***objvPtr out
+Pointer to location to store a vector of Tcl_Obj structures, the additional
+arguments to pass to an object alias command. The location is in storage
+owned by the caller, the vector of Tcl_Obj structures is owned by the
+called function.
+.AP "const char" *cmdName in
+Name of an exposed command to hide or create.
+.AP "const char" *hiddenCmdName in
+Name under which a hidden command is stored and with which it can be
+exposed or invoked.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures are intended for access to the multiple interpreter
+facility from inside C programs. They enable managing multiple interpreters
+in a hierarchical relationship, and the management of aliases, commands
+that when invoked in one interpreter execute a command in another
+interpreter. The return value for those procedures that return an \fBint\fR
+is either \fBTCL_OK\fR or \fBTCL_ERROR\fR. If \fBTCL_ERROR\fR is returned
+then the \fBresult\fR field of the interpreter contains an error message.
+.PP
+\fBTcl_CreateSlave\fR creates a new interpreter as a slave of \fIinterp\fR.
+It also creates a slave command named \fIslaveName\fR in \fIinterp\fR which
+allows \fIinterp\fR to manipulate the new slave.
+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
+.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
+.QW safe
+(was created with the \fBTCL_SAFE_INTERPRETER\fR flag specified),
+\fB0\fR otherwise.
+.PP
+\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
+or application are safe and does not make any attempt to remove those
+parts, so safety is not guaranteed after calling \fBTcl_MakeSafe\fR.
+Callers will want to take care with their use of \fBTcl_MakeSafe\fR
+to avoid false claims of safety. For many situations, \fBTcl_CreateSlave\fR
+may be a better choice, since it creates interpreters in a known-safe state.
+.PP
+\fBTcl_GetSlave\fR returns a pointer to a slave interpreter of
+\fIinterp\fR. The slave interpreter is identified by \fIslaveName\fR.
+If no such slave interpreter exists, \fBNULL\fR is returned.
+.PP
+\fBTcl_GetMaster\fR returns a pointer to the master interpreter of
+\fIinterp\fR. If \fIinterp\fR has no master (it is a
+top-level interpreter) then \fBNULL\fR is returned.
+.PP
+\fBTcl_GetInterpPath\fR sets the \fIresult\fR field in \fIaskingInterp\fR
+to the relative path between \fIaskingInterp\fR and \fIslaveInterp\fR;
+\fIslaveInterp\fR must be a slave of \fIaskingInterp\fR. If the computation
+of the relative path succeeds, \fBTCL_OK\fR is returned, else
+\fBTCL_ERROR\fR is returned and the \fIresult\fR field in
+\fIaskingInterp\fR contains the error message.
+.PP
+\fBTcl_CreateAlias\fR creates an object command named \fIslaveCmd\fR in
+\fIslaveInterp\fR that when invoked, will cause the command \fItargetCmd\fR
+to be invoked in \fItargetInterp\fR. The arguments specified by the strings
+contained in \fIargv\fR are always prepended to any arguments supplied in the
+invocation of \fIslaveCmd\fR and passed to \fItargetCmd\fR.
+This operation returns \fBTCL_OK\fR if it succeeds, or \fBTCL_ERROR\fR if
+it fails; in that case, an error message is left in the object result
+of \fIslaveInterp\fR.
+Note that there are no restrictions on the ancestry relationship (as
+created by \fBTcl_CreateSlave\fR) between \fIslaveInterp\fR and
+\fItargetInterp\fR. Any two interpreters can be used, without any
+restrictions on how they are related.
+.PP
+\fBTcl_CreateAliasObj\fR is similar to \fBTcl_CreateAlias\fR except
+that it takes a vector of objects to pass as additional arguments instead
+of a vector of strings.
+.PP
+\fBTcl_GetAlias\fR returns information about an alias \fIaliasName\fR
+in \fIinterp\fR. Any of the result fields can be \fBNULL\fR, in
+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.
+.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
+strings.
+.PP
+\fBTcl_ExposeCommand\fR moves the command named \fIhiddenCmdName\fR from
+the set of hidden commands to the set of exposed commands, putting
+it under the name
+\fIcmdName\fR.
+\fIHiddenCmdName\fR must be the name of an existing hidden
+command, or the operation will return \fBTCL_ERROR\fR and leave an error
+message in the \fIresult\fR field in \fIinterp\fR.
+If an exposed command named \fIcmdName\fR already exists,
+the operation returns \fBTCL_ERROR\fR and leaves an error message in the
+object result of \fIinterp\fR.
+If the operation succeeds, it returns \fBTCL_OK\fR.
+After executing this command, attempts to use \fIcmdName\fR in a call to
+\fBTcl_Eval\fR or with the Tcl \fBeval\fR command will again succeed.
+.PP
+\fBTcl_HideCommand\fR moves the command named \fIcmdName\fR from the set of
+exposed commands to the set of hidden commands, under the name
+\fIhiddenCmdName\fR.
+\fICmdName\fR must be the name of an existing exposed
+command, or the operation will return \fBTCL_ERROR\fR and leave an error
+message in the object result of \fIinterp\fR.
+Currently both \fIcmdName\fR and \fIhiddenCmdName\fR must not contain
+namespace qualifiers, or the operation will return \fBTCL_ERROR\fR and
+leave an error message in the object result of \fIinterp\fR.
+The \fICmdName\fR will be looked up in the global namespace, and not
+relative to the current namespace, even if the current namespace is not the
+global one.
+If a hidden command whose name is \fIhiddenCmdName\fR already
+exists, the operation also returns \fBTCL_ERROR\fR and the \fIresult\fR
+field in \fIinterp\fR contains an error message.
+If the operation succeeds, it returns \fBTCL_OK\fR.
+After executing this command, attempts to use \fIcmdName\fR in a call to
+\fBTcl_Eval\fR or with the Tcl \fBeval\fR command will fail.
+.PP
+For a description of the Tcl interface to multiple interpreters, see
+\fIinterp(n)\fR.
+.SH "SEE ALSO"
+interp
+
+.SH KEYWORDS
+alias, command, exposed commands, hidden commands, interpreter, invoke,
+master, slave
diff --git a/library/msgcat/doc/CrtTimerHdlr.3 b/library/msgcat/doc/CrtTimerHdlr.3
new file mode 100644
index 0000000..2c9f90a
--- /dev/null
+++ b/library/msgcat/doc/CrtTimerHdlr.3
@@ -0,0 +1,76 @@
+'\"
+'\" Copyright (c) 1990 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 Tcl_CreateTimerHandler 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CreateTimerHandler, Tcl_DeleteTimerHandler \- call a procedure at a given time
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_TimerToken
+\fBTcl_CreateTimerHandler\fR(\fImilliseconds, proc, clientData\fR)
+.sp
+\fBTcl_DeleteTimerHandler\fR(\fItoken\fR)
+.SH ARGUMENTS
+.AS Tcl_TimerToken milliseconds
+.AP int milliseconds in
+How many milliseconds to wait before invoking \fIproc\fR.
+.AP Tcl_TimerProc *proc in
+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
+from some previous call to \fBTcl_CreateTimerHandler\fR).
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateTimerHandler\fR arranges for \fIproc\fR to be
+invoked at a time \fImilliseconds\fR milliseconds in the
+future.
+The callback to \fIproc\fR will be made by \fBTcl_DoOneEvent\fR,
+so \fBTcl_CreateTimerHandler\fR is only useful in programs that
+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 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.
+.PP
+\fIProc\fR should have arguments and return value that match
+the type \fBTcl_TimerProc\fR:
+.PP
+.CS
+typedef void \fBTcl_TimerProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR parameter to \fIproc\fR is a
+copy of the \fIclientData\fR argument given to
+\fBTcl_CreateTimerHandler\fR when the callback
+was created. Typically, \fIclientData\fR points to a data
+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
+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
+has been invoked then \fBTcl_DeleteTimerHandler\fR does nothing.
+The tokens returned by \fBTcl_CreateTimerHandler\fR never have
+a value of NULL, so if NULL is passed to \fBTcl_DeleteTimerHandler\fR
+then the procedure does nothing.
+.SH "SEE ALSO"
+after(n), Tcl_CreateFileHandler(3), Tcl_DoWhenIdle(3)
+.SH KEYWORDS
+callback, clock, handler, timer
diff --git a/library/msgcat/doc/CrtTrace.3 b/library/msgcat/doc/CrtTrace.3
new file mode 100644
index 0000000..3689add
--- /dev/null
+++ b/library/msgcat/doc/CrtTrace.3
@@ -0,0 +1,191 @@
+'\"
+'\" 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 <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 Tcl_CreateTrace 3 "" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CreateTrace, Tcl_CreateObjTrace, Tcl_DeleteTrace \- arrange for command execution to be traced
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Trace
+\fBTcl_CreateTrace\fR(\fIinterp, level, proc, clientData\fR)
+.sp
+Tcl_Trace
+\fBTcl_CreateObjTrace\fR(\fIinterp, level, flags, objProc, clientData, deleteProc\fR)
+.sp
+\fBTcl_DeleteTrace\fR(\fIinterp, trace\fR)
+.SH ARGUMENTS
+.AS Tcl_CmdObjTraceDeleteProc *deleteProc
+.AP Tcl_Interp *interp in
+Interpreter containing command to be traced or untraced.
+.AP int level in
+Only commands at or below this nesting level will be traced unless
+0 is specified. 1 means
+top-level commands only, 2 means top-level commands or those that are
+invoked as immediate consequences of executing top-level commands
+(procedure bodies, bracketed commands, etc.) and so on.
+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 is executed. See below for
+details of the calling sequence.
+.AP Tcl_CmdTraceProc *proc in
+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 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.
+.AP Tcl_Trace trace in
+Token for trace to be removed (return value from previous call
+to \fBTcl_CreateTrace\fR).
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateObjTrace\fR arranges for command tracing. After it is
+called, \fIobjProc\fR will be invoked before the Tcl interpreter calls
+any command procedure when evaluating commands in \fIinterp\fR.
+The return value from \fBTcl_CreateObjTrace\fR is a token for the trace,
+which may be passed to \fBTcl_DeleteTrace\fR to remove the trace.
+There may be many traces in effect simultaneously for the same
+interpreter.
+.PP
+\fIobjProc\fR should have arguments and result that match the type,
+\fBTcl_CmdObjTraceProc\fR:
+.PP
+.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[]);
+.CE
+.PP
+The \fIclientData\fR and \fIinterp\fR parameters are copies of the
+corresponding arguments given to \fBTcl_CreateTrace\fR.
+\fIClientData\fR typically points to an application-specific data
+structure that describes what to do when \fIobjProc\fR is invoked. The
+\fIlevel\fR parameter gives the nesting level of the command (1 for
+top-level commands passed to \fBTcl_Eval\fR by the application, 2 for
+the next-level commands passed to \fBTcl_Eval\fR as part of parsing or
+interpreting level-1 commands, and so on). The \fIcommand\fR parameter
+points to a string containing the text of the command, before any
+argument substitution. The \fIcommandToken\fR parameter is a Tcl
+command token that identifies the command to be invoked. The token
+may be passed to \fBTcl_GetCommandName\fR,
+\fBTcl_GetCommandInfoFromToken\fR, or \fBTcl_SetCommandInfoFromToken\fR to
+manipulate the definition of the command. The \fIobjc\fR and \fIobjv\fR
+parameters designate the final parameter count and parameter vector
+that will be passed to the command, and have had all substitutions
+performed.
+.PP
+The \fIobjProc\fR callback is expected to return a standard Tcl status
+return code. If this code is \fBTCL_OK\fR (the normal case), then
+the Tcl interpreter will invoke the command. Any other return code
+is treated as if the command returned that status, and the command is
+\fInot\fR invoked.
+.PP
+The \fIobjProc\fR callback must not modify \fIobjv\fR in any way. It
+is, however, permissible to change the command by calling
+\fBTcl_SetCommandTokenInfo\fR prior to returning. Any such change
+takes effect immediately, and the command is invoked with the new
+information.
+.PP
+Tracing will only occur for commands at nesting level less than
+or equal to the \fIlevel\fR parameter (i.e. the \fIlevel\fR
+parameter to \fIobjProc\fR will always be less than or equal to the
+\fIlevel\fR parameter to \fBTcl_CreateTrace\fR).
+.PP
+Tracing has a significant effect on runtime performance because it
+causes the bytecode compiler to refrain from generating in-line code
+for Tcl commands such as \fBif\fR and \fBwhile\fR in order that they
+may be traced. If traces for the built-in commands are not required,
+the \fIflags\fR parameter may be set to the constant value
+\fBTCL_ALLOW_INLINE_COMPILATION\fR. In this case, traces on built-in
+commands may or may not result in trace callbacks, depending on the
+state of the interpreter, but run-time performance will be improved
+significantly. (This functionality is desirable, for example, when
+using \fBTcl_CreateObjTrace\fR to implement an execution time
+profiler.)
+.PP
+Calls to \fIobjProc\fR will be made by the Tcl parser immediately before
+it calls the command procedure for the command (\fIcmdProc\fR). This
+occurs after argument parsing and substitution, so tracing for
+substituted commands occurs before tracing of the commands
+containing the substitutions. If there is a syntax error in a
+command, or if there is no command procedure associated with a
+command name, then no tracing will occur for that command. If a
+string passed to Tcl_Eval contains multiple commands (bracketed, or
+on different lines) then multiple calls to \fIobjProc\fR will occur,
+one for each command.
+.PP
+\fBTcl_DeleteTrace\fR removes a trace, so that no future calls will be
+made to the procedure associated with the trace. After \fBTcl_DeleteTrace\fR
+returns, the caller should never again use the \fItrace\fR token.
+.PP
+When \fBTcl_DeleteTrace\fR is called, the interpreter invokes the
+\fIdeleteProc\fR that was passed as a parameter to
+\fBTcl_CreateObjTrace\fR. The \fIdeleteProc\fR must match the type,
+\fBTcl_CmdObjTraceDeleteProc\fR:
+.PP
+.CS
+typedef void \fBTcl_CmdObjTraceDeleteProc\fR(
+ \fBClientData\fR \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR parameter will be the same as the
+\fIclientData\fR parameter that was originally passed to
+\fBTcl_CreateObjTrace\fR.
+.PP
+\fBTcl_CreateTrace\fR is an alternative interface for command tracing,
+\fInot recommended for new applications\fR. It is provided for backward
+compatibility with code that was developed for older versions of the
+Tcl interpreter. It is similar to \fBTcl_CreateObjTrace\fR, except
+that its \fIproc\fR parameter should have arguments and result that
+match the type \fBTcl_CmdTraceProc\fR:
+.PP
+.CS
+typedef void \fBTcl_CmdTraceProc\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
+.PP
+The parameters to the \fIproc\fR callback are similar to those of the
+\fIobjProc\fR callback above. The \fIcommandToken\fR is
+replaced with \fIcmdProc\fR, a pointer to the (string-based) command
+procedure that will be invoked; and \fIcmdClientData\fR, the client
+data that will be passed to the procedure. The \fIobjc\fR parameter
+is replaced with an \fIargv\fR parameter, that gives the arguments to
+the command as character strings.
+\fIProc\fR must not modify the \fIcommand\fR or \fIargv\fR strings.
+.PP
+If a trace created with \fBTcl_CreateTrace\fR is in effect, inline
+compilation of Tcl commands such as \fBif\fR and \fBwhile\fR is always
+disabled. There is no notification when a trace created with
+\fBTcl_CreateTrace\fR is deleted.
+There is no way to be notified when the trace created by
+\fBTcl_CreateTrace\fR is deleted. There is no way for the \fIproc\fR
+associated with a call to \fBTcl_CreateTrace\fR to abort execution of
+\fIcommand\fR.
+.SH KEYWORDS
+command, create, delete, interpreter, trace
diff --git a/library/msgcat/doc/DString.3 b/library/msgcat/doc/DString.3
new file mode 100644
index 0000000..a85b1cf
--- /dev/null
+++ b/library/msgcat/doc/DString.3
@@ -0,0 +1,153 @@
+'\"
+'\" 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 Tcl_DString 3 7.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_DStringInit, Tcl_DStringAppend, Tcl_DStringAppendElement, Tcl_DStringStartSublist, Tcl_DStringEndSublist, Tcl_DStringLength, Tcl_DStringValue, Tcl_DStringSetLength, Tcl_DStringTrunc, Tcl_DStringFree, Tcl_DStringResult, Tcl_DStringGetResult \- manipulate dynamic strings
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_DStringInit\fR(\fIdsPtr\fR)
+.sp
+char *
+\fBTcl_DStringAppend\fR(\fIdsPtr, bytes, length\fR)
+.sp
+char *
+\fBTcl_DStringAppendElement\fR(\fIdsPtr, element\fR)
+.sp
+\fBTcl_DStringStartSublist\fR(\fIdsPtr\fR)
+.sp
+\fBTcl_DStringEndSublist\fR(\fIdsPtr\fR)
+.sp
+int
+\fBTcl_DStringLength\fR(\fIdsPtr\fR)
+.sp
+char *
+\fBTcl_DStringValue\fR(\fIdsPtr\fR)
+.sp
+\fBTcl_DStringSetLength\fR(\fIdsPtr, newLength\fR)
+.sp
+\fBTcl_DStringTrunc\fR(\fIdsPtr, newLength\fR)
+.sp
+\fBTcl_DStringFree\fR(\fIdsPtr\fR)
+.sp
+\fBTcl_DStringResult\fR(\fIinterp, dsPtr\fR)
+.sp
+\fBTcl_DStringGetResult\fR(\fIinterp, dsPtr\fR)
+.SH ARGUMENTS
+.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" *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 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
+character.
+.AP Tcl_Interp *interp in/out
+Interpreter whose result is to be set from or moved to the
+dynamic string.
+.BE
+
+.SH DESCRIPTION
+.PP
+Dynamic strings provide a mechanism for building up arbitrarily long
+strings by gradually appending information. If the dynamic string is
+short then there will be no memory allocation overhead; as the string
+gets larger, additional space will be allocated as needed.
+.PP
+\fBTcl_DStringInit\fR initializes a dynamic string to zero length.
+The Tcl_DString structure must have been allocated by the caller.
+No assumptions are made about the current state of the structure;
+anything already in it is discarded.
+If the structure has been used previously, \fBTcl_DStringFree\fR should
+be called first to free up any memory allocated for the old
+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 \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
+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 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
+.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
+\fBTcl_DStringStartSublist\fR and \fBTcl_DStringEndSublist\fR can be
+used to create nested lists.
+To append a list element that is itself a sublist, first
+call \fBTcl_DStringStartSublist\fR, then call \fBTcl_DStringAppendElement\fR
+for each of the elements in the sublist, then call
+\fBTcl_DStringEndSublist\fR to end the sublist.
+\fBTcl_DStringStartSublist\fR appends a space character if needed,
+followed by an open brace; \fBTcl_DStringEndSublist\fR appends
+a close brace.
+Lists can be nested to any depth.
+.PP
+\fBTcl_DStringLength\fR is a macro that returns the current length
+of a dynamic string (not including the terminating null character).
+\fBTcl_DStringValue\fR is a macro that returns a pointer to the
+current contents of a dynamic string.
+.PP
+.PP
+\fBTcl_DStringSetLength\fR changes the length of a dynamic string.
+If \fInewLength\fR is less than the string's current length, then
+the string is truncated.
+If \fInewLength\fR is greater than the string's current length,
+then the string will become longer and new space will be allocated
+for the string if needed.
+However, \fBTcl_DStringSetLength\fR will not initialize the new
+space except to provide a terminating null character; it is up to the
+caller to fill in the new space.
+\fBTcl_DStringSetLength\fR does not free up the string's storage space
+even if the string is truncated to zero length, so \fBTcl_DStringFree\fR
+will still need to be called.
+.PP
+\fBTcl_DStringTrunc\fR changes the length of a dynamic string.
+This procedure is now deprecated. \fBTcl_DStringSetLength\fR should
+be used instead.
+.PP
+\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
+\fBTcl_DStringResult\fR sets the result of \fIinterp\fR to the value of
+the dynamic string given by \fIdsPtr\fR. It does this by moving
+a pointer from \fIdsPtr\fR to the interpreter's result.
+This saves the cost of allocating new memory and copying the string.
+\fBTcl_DStringResult\fR also reinitializes the dynamic string to
+an empty string.
+.PP
+\fBTcl_DStringGetResult\fR does the opposite of \fBTcl_DStringResult\fR.
+It sets the value of \fIdsPtr\fR to the result of \fIinterp\fR and
+it clears \fIinterp\fR's result.
+If possible it does this by moving a pointer rather than by copying
+the string.
+
+.SH KEYWORDS
+append, dynamic string, free, result
diff --git a/library/msgcat/doc/DetachPids.3 b/library/msgcat/doc/DetachPids.3
new file mode 100644
index 0000000..0535cd8
--- /dev/null
+++ b/library/msgcat/doc/DetachPids.3
@@ -0,0 +1,75 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_DetachPids 3 "" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_DetachPids, Tcl_ReapDetachedProcs, Tcl_WaitPid \- manage child processes in background
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_DetachPids\fR(\fInumPids, pidPtr\fR)
+.sp
+\fBTcl_ReapDetachedProcs\fR()
+.sp
+Tcl_Pid
+\fBTcl_WaitPid\fR(\fIpid, statusPtr, options\fR)
+.SH ARGUMENTS
+.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 *statusPtr out
+The result of waiting on a process (pipe). Either 0 or ECHILD.
+.AP int options in
+The options controlling the wait. WNOHANG specifies not to wait when
+checking the process.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_DetachPids\fR and \fBTcl_ReapDetachedProcs\fR provide a
+mechanism for managing subprocesses that are running in background.
+These procedures are needed because the parent of a process must
+eventually invoke the \fBwaitpid\fR kernel call (or one of a few other
+similar kernel calls) to wait for the child to exit. Until the
+parent waits for the child, the child's state cannot be completely
+reclaimed by the system. If a parent continually creates children
+and doesn't wait on them, the system's process table will eventually
+overflow, even if all the children have exited.
+.PP
+\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 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 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 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
+\fBTcl_ReapDetachedProcs\fR from time to time so that background
+processes can be cleaned up.
+.PP
+\fBTcl_WaitPid\fR is a thin wrapper around the facilities provided by
+the operating system to wait on the end of a spawned process and to
+check a whether spawned process is still running. It is used by
+\fBTcl_ReapDetachedProcs\fR and the channel system to portably access
+the operating system.
+
+.SH KEYWORDS
+background, child, detach, process, wait
diff --git a/library/msgcat/doc/DictObj.3 b/library/msgcat/doc/DictObj.3
new file mode 100644
index 0000000..a5dc9e5
--- /dev/null
+++ b/library/msgcat/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 manipulated 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/library/msgcat/doc/DoOneEvent.3 b/library/msgcat/doc/DoOneEvent.3
new file mode 100644
index 0000000..9bdf926
--- /dev/null
+++ b/library/msgcat/doc/DoOneEvent.3
@@ -0,0 +1,106 @@
+'\"
+'\" Copyright (c) 1990-1992 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 Tcl_DoOneEvent 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_DoOneEvent \- wait for events and invoke event handlers
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_DoOneEvent\fR(\fIflags\fR)
+.SH ARGUMENTS
+.AS int flags
+.AP int flags in
+This parameter is normally zero. It may be an OR-ed combination
+of any of the following flag bits:
+\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
+.PP
+This procedure is the entry point to Tcl's event loop; it is responsible for
+waiting for events and dispatching event handlers created with
+procedures such as \fBTk_CreateEventHandler\fR, \fBTcl_CreateFileHandler\fR,
+\fBTcl_CreateTimerHandler\fR, and \fBTcl_DoWhenIdle\fR.
+\fBTcl_DoOneEvent\fR checks to see if
+events are already present on the Tcl event queue; if so,
+it calls the handler(s) for the first (oldest) event, removes it from
+the queue, and returns.
+If there are no events ready to be handled, then \fBTcl_DoOneEvent\fR
+checks for new events from all possible sources.
+If any are found, it puts all of them on Tcl's event queue, calls
+handlers for the first event on the queue, and returns.
+If no events are found, \fBTcl_DoOneEvent\fR checks for \fBTcl_DoWhenIdle\fR
+callbacks; if any are found, it invokes all of them and returns.
+Finally, if no events or idle callbacks have been found, then
+\fBTcl_DoOneEvent\fR sleeps until an event occurs; then it adds any
+new events to the Tcl event queue, calls handlers for the first event,
+and returns.
+The normal return value is 1 to signify that some event
+was processed (see below for other alternatives).
+.PP
+If the \fIflags\fR argument to \fBTcl_DoOneEvent\fR is non-zero,
+it restricts the kinds of events that will be processed by
+\fBTcl_DoOneEvent\fR.
+\fIFlags\fR may be an OR-ed combination of any of the following bits:
+.TP 27
+\fBTCL_WINDOW_EVENTS\fR \-
+Process window system events.
+.TP 27
+\fBTCL_FILE_EVENTS\fR \-
+Process file events.
+.TP 27
+\fBTCL_TIMER_EVENTS\fR \-
+Process timer events.
+.TP 27
+\fBTCL_IDLE_EVENTS\fR \-
+Process idle callbacks.
+.TP 27
+\fBTCL_ALL_EVENTS\fR \-
+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 \-
+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,
+\fBTCL_TIMER_EVENTS\fR, or \fBTCL_IDLE_EVENTS\fR is set, then the only
+events that will be considered are those for which flags are set.
+Setting none of these flags is equivalent to the value
+\fBTCL_ALL_EVENTS\fR, which causes all event types to be processed.
+If an application has defined additional event sources with
+\fBTcl_CreateEventSource\fR, then additional \fIflag\fR values
+may also be valid, depending on those event sources.
+.PP
+The \fBTCL_DONT_WAIT\fR flag causes \fBTcl_DoOneEvent\fR not to put
+the process to sleep: it will check for events but if none are found
+then it returns immediately with a return value of 0 to indicate
+that no work was done.
+\fBTcl_DoOneEvent\fR will also return 0 without doing anything if
+the only alternative is to block forever (this can happen, for example,
+if \fIflags\fR is \fBTCL_IDLE_EVENTS\fR and there are no
+\fBTcl_DoWhenIdle\fR callbacks pending, or if no event handlers or
+timer handlers exist).
+.PP
+\fBTcl_DoOneEvent\fR may be invoked recursively. For example,
+it is possible to invoke \fBTcl_DoOneEvent\fR recursively
+from a handler called by \fBTcl_DoOneEvent\fR. This sort
+of operation is useful in some modal situations, such
+as when a
+notification dialog has been popped up and an application wishes to
+wait for the user to click a button in the dialog before
+doing anything else.
+
+.SH KEYWORDS
+callback, event, handler, idle, timer
diff --git a/library/msgcat/doc/DoWhenIdle.3 b/library/msgcat/doc/DoWhenIdle.3
new file mode 100644
index 0000000..27a4b8c
--- /dev/null
+++ b/library/msgcat/doc/DoWhenIdle.3
@@ -0,0 +1,87 @@
+'\"
+'\" Copyright (c) 1990 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 Tcl_DoWhenIdle 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_DoWhenIdle, Tcl_CancelIdleCall \- invoke a procedure when there are no pending events
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_DoWhenIdle\fR(\fIproc, clientData\fR)
+.sp
+\fBTcl_CancelIdleCall\fR(\fIproc, clientData\fR)
+.SH ARGUMENTS
+.AS Tcl_IdleProc clientData
+.AP Tcl_IdleProc *proc in
+Procedure to invoke.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+\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, 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
+be a single call to \fIproc\fR; after \fIproc\fR is
+invoked the handler is automatically removed.
+\fBTcl_DoWhenIdle\fR is only usable in programs that
+use \fBTcl_DoOneEvent\fR to dispatch events.
+.PP
+\fIProc\fR should have arguments and result that match the
+type \fBTcl_IdleProc\fR:
+.PP
+.CS
+typedef void \fBTcl_IdleProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR parameter to \fIproc\fR is a copy of the \fIclientData\fR
+argument given to \fBTcl_DoWhenIdle\fR. Typically, \fIclientData\fR
+points to a data structure containing application-specific information about
+what \fIproc\fR should do.
+.PP
+\fBTcl_CancelIdleCall\fR
+may be used to cancel one or more previous
+calls to \fBTcl_DoWhenIdle\fR: if there is a \fBTcl_DoWhenIdle\fR
+handler registered for \fIproc\fR and \fIclientData\fR, then it
+is removed without invoking it. If there is more than one
+handler on the idle list that refers to \fIproc\fR and \fIclientData\fR,
+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 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
+actual work to be deferred until all pending events have
+been processed. At this point the exact work to be done
+will presumably be known and it can be done exactly once.
+.PP
+For example, \fBTcl_DoWhenIdle\fR might be used by an editor
+to defer display updates until all pending commands have
+been processed. Without this feature, redundant redisplays
+might occur in some situations, such as the processing of
+a command file.
+.SH BUGS
+.PP
+At present it is not safe for an idle callback to reschedule itself
+continuously. This will interact badly with certain features of Tk
+that attempt to wait for all idle callbacks to complete. If you would
+like for an idle callback to reschedule itself continuously, it is
+better to use a timer handler with a zero timeout period.
+.SH "SEE ALSO"
+after(n), Tcl_CreateFileHandler(3), Tcl_CreateTimerHandler(3)
+.SH KEYWORDS
+callback, defer, idle callback
diff --git a/library/msgcat/doc/DoubleObj.3 b/library/msgcat/doc/DoubleObj.3
new file mode 100644
index 0000000..12818b0
--- /dev/null
+++ b/library/msgcat/doc/DoubleObj.3
@@ -0,0 +1,64 @@
+'\"
+'\" Copyright (c) 1996-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 Tcl_DoubleObj 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_NewDoubleObj, Tcl_SetDoubleObj, Tcl_GetDoubleFromObj \- manipulate Tcl objects as floating-point values
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewDoubleObj\fR(\fIdoubleValue\fR)
+.sp
+\fBTcl_SetDoubleObj\fR(\fIobjPtr, doubleValue\fR)
+.sp
+int
+\fBTcl_GetDoubleFromObj\fR(\fIinterp, objPtr, doublePtr\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp doubleValue in/out
+.AP double doubleValue in
+A double-precision floating-point value used to initialize or set a Tcl object.
+.AP Tcl_Obj *objPtr in/out
+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 retrieve a double value.
+.AP Tcl_Interp *interp in/out
+When non-NULL, an error message is left here when double value retrieval fails.
+.AP double *doublePtr out
+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 Tcl objects that
+hold double-precision floating-point values.
+.PP
+\fBTcl_NewDoubleObj\fR creates and returns a new Tcl object initialized to
+the double value \fIdoubleValue\fR. The returned Tcl object is unshared.
+.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/library/msgcat/doc/DumpActiveMemory.3 b/library/msgcat/doc/DumpActiveMemory.3
new file mode 100644
index 0000000..1f6cb46
--- /dev/null
+++ b/library/msgcat/doc/DumpActiveMemory.3
@@ -0,0 +1,68 @@
+'\"
+'\" Copyright (c) 1992-1999 Karl Lehenbauer and Mark Diekhans.
+'\" Copyright (c) 2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.so man.macros
+.TH "Tcl_DumpActiveMemory" 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_DumpActiveMemory, Tcl_InitMemory, Tcl_ValidateAllMemory \- Validated memory allocation interface
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_DumpActiveMemory\fR(\fIfileName\fR)
+.sp
+void
+\fBTcl_InitMemory\fR(\fIinterp\fR)
+.sp
+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
+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).
+.AP int line in
+Line number at which the call to \fBTcl_ValidateAllMemory\fR is made
+(normally \fB__LINE__\fR).
+.BE
+
+.SH DESCRIPTION
+These functions provide access to Tcl memory debugging information.
+They are only functional when Tcl has been compiled with
+\fBTCL_MEM_DEBUG\fR defined at compile-time. When \fBTCL_MEM_DEBUG\fR
+is not defined, these functions are all no-ops.
+.PP
+\fBTcl_DumpActiveMemory\fR will output a list of all currently
+allocated memory to the specified file. The information output for
+each allocated block of memory is: starting and ending addresses
+(excluding guard zone), size, source file where \fBckalloc\fR was
+called to allocate the block and line number in that file. It is
+especially useful to call \fBTcl_DumpActiveMemory\fR after the Tcl
+interpreter has been deleted.
+.PP
+\fBTcl_InitMemory\fR adds the Tcl \fBmemory\fR command to the
+interpreter given by \fIinterp\fR. \fBTcl_InitMemory\fR is called
+by \fBTcl_Main\fR.
+.PP
+\fBTcl_ValidateAllMemory\fR forces a validation of the guard zones of
+all currently allocated blocks of memory. Normally validation of a
+block occurs when its freed, unless full validation is enabled, in
+which case validation of all blocks occurs when \fBckalloc\fR and
+\fBckfree\fR are called. This function forces the validation to occur
+at any point.
+
+.SH "SEE ALSO"
+TCL_MEM_DEBUG, memory
+
+.SH KEYWORDS
+memory, debug
+
+
diff --git a/library/msgcat/doc/Encoding.3 b/library/msgcat/doc/Encoding.3
new file mode 100644
index 0000000..7bcb285
--- /dev/null
+++ b/library/msgcat/doc/Encoding.3
@@ -0,0 +1,592 @@
+'\"
+'\" 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_GetEncoding 3 "8.1" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_GetEncoding, Tcl_FreeEncoding, Tcl_GetEncodingFromObj, Tcl_ExternalToUtfDString, Tcl_ExternalToUtf, Tcl_UtfToExternalDString, Tcl_UtfToExternal, Tcl_WinTCharToUtf, Tcl_WinUtfToTChar, Tcl_GetEncodingName, Tcl_SetSystemEncoding, Tcl_GetEncodingNameFromEnvironment, Tcl_GetEncodingNames, Tcl_CreateEncoding, Tcl_GetEncodingSearchPath, Tcl_SetEncodingSearchPath, Tcl_GetDefaultEncodingDir, Tcl_SetDefaultEncodingDir \- procedures for creating and using encodings
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Encoding
+\fBTcl_GetEncoding\fR(\fIinterp, name\fR)
+.sp
+void
+\fBTcl_FreeEncoding\fR(\fIencoding\fR)
+.sp
+int
+\fBTcl_GetEncodingFromObj\fR(\fIinterp, objPtr, encodingPtr\fR)
+.sp
+char *
+\fBTcl_ExternalToUtfDString\fR(\fIencoding, src, srcLen, dstPtr\fR)
+.sp
+char *
+\fBTcl_UtfToExternalDString\fR(\fIencoding, src, srcLen, dstPtr\fR)
+.sp
+int
+\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)
+.sp
+TCHAR *
+\fBTcl_WinUtfToTChar\fR(\fIsrc, srcLen, dstPtr\fR)
+.sp
+const char *
+\fBTcl_GetEncodingName\fR(\fIencoding\fR)
+.sp
+int
+\fBTcl_SetSystemEncoding\fR(\fIinterp, name\fR)
+.sp
+const char *
+\fBTcl_GetEncodingNameFromEnvironment\fR(\fIbufPtr\fR)
+.sp
+void
+\fBTcl_GetEncodingNames\fR(\fIinterp\fR)
+.sp
+Tcl_Encoding
+\fBTcl_CreateEncoding\fR(\fItypePtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetEncodingSearchPath\fR()
+.sp
+int
+\fBTcl_SetEncodingSearchPath\fR(\fIsearchPath\fR)
+.sp
+const char *
+\fBTcl_GetDefaultEncodingDir\fR(\fIvoid\fR)
+.sp
+void
+\fBTcl_SetDefaultEncodingDir\fR(\fIpath\fR)
+.SH ARGUMENTS
+.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
+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 Tcl_Obj *objPtr in
+Name of encoding to get token for.
+.AP Tcl_Encoding *encodingPtr out
+Points to storage where encoding token is to be written.
+.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
+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
+encoding-specific length of the string is used.
+.AP Tcl_DString *dstPtr out
+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.
+\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. \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.
+\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
+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
+routine knows what state it was in when it left off at the end of the
+last piece. May be NULL, in which case the value specified for \fIflags\fR
+is ignored and the source buffer is assumed to contain the complete string to
+convert.
+.AP char *dst out
+Buffer in which the converted result will be stored. No more than
+\fIdstLen\fR bytes will be stored in \fIdst\fR.
+.AP int dstLen in
+The maximum length of the output buffer \fIdst\fR in bytes.
+.AP int *srcReadPtr out
+Filled with the number of bytes from \fIsrc\fR that were actually
+converted. This may be less than the original source length if there was
+a problem converting some source characters. May be NULL.
+.AP int *dstWrotePtr out
+Filled with the number of bytes that were actually stored in the output
+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_DString *bufPtr out
+Storage for the prescribed system encoding name.
+.AP "const Tcl_EncodingType" *typePtr in
+Structure that defines a new type of encoding.
+.AP Tcl_Obj *searchPath in
+List of filesystem directories in which to search for encoding data files.
+.AP "const char" *path in
+A path to the location of the encoding file.
+.BE
+.SH INTRODUCTION
+.PP
+These routines convert between Tcl's internal character representation,
+UTF-8, and character representations used by various operating systems or
+file systems, such as Unicode, ASCII, or Shift-JIS. When operating on
+strings, such as such as obtaining the names of files or displaying
+characters using international fonts, the strings must be translated into
+one or possibly multiple formats that the various system calls can use. For
+instance, on a Japanese Unix workstation, a user might obtain a filename
+represented in the EUC-JP file encoding and then translate the characters to
+the jisx0208 font encoding in order to display the filename in a Tk widget.
+The purpose of the encoding package is to help bridge the translation gap.
+UTF-8 provides an intermediate staging ground for all the various
+encodings. In the example above, text would be translated into UTF-8 from
+whatever file encoding the operating system is using. Then it would be
+translated from UTF-8 into whatever font encoding the display routines
+require.
+.PP
+Some basic encodings are compiled into Tcl. Others can be defined by the
+user or dynamically loaded from encoding files in a
+platform-independent manner.
+.SH DESCRIPTION
+.PP
+\fBTcl_GetEncoding\fR finds an encoding given its \fIname\fR. The name may
+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,
+\fBTcl_FreeEncoding\fR, and \fBTcl_UtfToExternal\fR. If the name did not
+refer to any known or loadable encoding, NULL is returned and an error
+message is returned in \fIinterp\fR.
+.PP
+The encoding package maintains a database of all encodings currently in use.
+The first time \fIname\fR is seen, \fBTcl_GetEncoding\fR returns an
+encoding with a reference count of 1. If the same \fIname\fR is requested
+further times, then the reference count for that encoding is incremented
+without the overhead of allocating a new encoding and all its associated
+data structures.
+.PP
+When an \fIencoding\fR is no longer needed, \fBTcl_FreeEncoding\fR
+should be called to release it. When an \fIencoding\fR is no longer in use
+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
+\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.
+.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
+call \fBTcl_DStringFree\fR to free any information stored in \fIdstPtr\fR.
+When converting, if any of the characters in the source buffer cannot be
+represented in the target encoding, a default fallback character will be
+used. The return value is a pointer to the value stored in the DString.
+.PP
+\fBTcl_ExternalToUtf\fR converts a source buffer \fIsrc\fR from the specified
+\fIencoding\fR into UTF-8. Up to \fIsrcLen\fR bytes are converted from the
+source buffer and up to \fIdstLen\fR converted bytes are stored in \fIdst\fR.
+In all cases, \fI*srcReadPtr\fR is filled with the number of bytes that were
+successfully converted from \fIsrc\fR and \fI*dstWrotePtr\fR is filled with
+the corresponding number of bytes that were stored in \fIdst\fR. The return
+value is one of the following:
+.RS
+.IP \fBTCL_OK\fR 29
+All bytes of \fIsrc\fR were converted.
+.IP \fBTCL_CONVERT_NOSPACE\fR 29
+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 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
+from the source stream to properly convert the formerly split-up multibyte
+sequence.
+.IP \fBTCL_CONVERT_SYNTAX\fR 29
+The source buffer contained an invalid character sequence. This may occur
+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 \fBTCL_ENCODING_STOPONERROR\fR was specified.
+.RE
+.LP
+\fBTcl_UtfToExternalDString\fR converts a source buffer \fIsrc\fR from UTF-8
+into the specified \fIencoding\fR. The converted bytes are stored in
+\fIdstPtr\fR, which is then terminated with the appropriate encoding-specific
+null. The caller should eventually call \fBTcl_DStringFree\fR to free any
+information stored in \fIdstPtr\fR. When converting, if any of the
+characters in the source buffer cannot be represented in the target
+encoding, a default fallback character will be used. The return value is
+a pointer to the value stored in the DString.
+.PP
+\fBTcl_UtfToExternal\fR converts a source buffer \fIsrc\fR from UTF-8 into
+the specified \fIencoding\fR. Up to \fIsrcLen\fR bytes are converted from
+the source buffer and up to \fIdstLen\fR converted bytes are stored in
+\fIdst\fR. In all cases, \fI*srcReadPtr\fR is filled with the number of
+bytes that were successfully converted from \fIsrc\fR and \fI*dstWrotePtr\fR
+is filled with the corresponding number of bytes that were stored in
+\fIdst\fR. The return values are the same as the return values for
+\fBTcl_ExternalToUtf\fR.
+.PP
+\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 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
+.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
+.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
+.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):
+.PP
+.CS
+if (running NT) {
+ encoding <- Tcl_GetEncoding("unicode");
+ nativeBuffer <- Tcl_UtfToExternal(encoding, utfBuffer);
+ Tcl_FreeEncoding(encoding);
+} else {
+ nativeBuffer <- Tcl_UtfToExternal(NULL, utfBuffer);
+}
+.CE
+.PP
+\fBTcl_WinUtfToTChar\fR and \fBTcl_WinTCharToUtf\fR automatically
+handle this test and use the proper encoding based on the current
+operating system. \fBTcl_WinUtfToTChar\fR returns a pointer to
+a TCHAR string, and \fBTcl_WinTCharToUtf\fR expects a TCHAR string
+pointer as the \fIsrc\fR string. Otherwise, these functions
+behave identically to \fBTcl_UtfToExternalDString\fR and
+\fBTcl_ExternalToUtfDString\fR.
+.PP
+\fBTcl_GetEncodingName\fR is roughly the inverse of \fBTcl_GetEncoding\fR.
+Given an \fIencoding\fR, the return value is the \fIname\fR argument that
+was used to create the encoding. The string returned by
+\fBTcl_GetEncodingName\fR is only guaranteed to persist until the
+\fIencoding\fR is deleted. The caller must not modify this string.
+.PP
+\fBTcl_SetSystemEncoding\fR sets the default encoding that should be used
+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, \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
+\fBTCL_OK\fR.
+.PP
+\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.
+.PP
+\fBTcl_GetEncodingNames\fR sets the \fIinterp\fR result to a list
+consisting of the names of all the encodings that are currently defined
+or can be dynamically loaded, searching the encoding path specified by
+\fBTcl_SetDefaultEncodingDir\fR. This procedure does not ensure that the
+dynamically-loadable encoding files contain valid data, but merely that they
+exist.
+.PP
+\fBTcl_CreateEncoding\fR defines a new encoding and registers the C
+procedures that are called back to convert between the encoding and
+UTF-8. Encodings created by \fBTcl_CreateEncoding\fR are thereafter
+visible in the database used by \fBTcl_GetEncoding\fR. Just as with the
+\fBTcl_GetEncoding\fR procedure, the return value is a token that
+represents the encoding and can be used in subsequent calls to other
+encoding functions. \fBTcl_CreateEncoding\fR returns an encoding with a
+reference count of 1. If an encoding with the specified \fIname\fR
+already exists, then its entry in the database is replaced with the new
+encoding; the token for the old encoding will remain valid and continue
+to behave as before, but users of the new token will now call the new
+encoding procedures.
+.PP
+The \fItypePtr\fR argument to \fBTcl_CreateEncoding\fR contains information
+about the name of the encoding and the procedures that will be called to
+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;
+} \fBTcl_EncodingType\fR;
+.CE
+.PP
+The \fIencodingName\fR provides a string name for the encoding, by
+which it can be referred in other procedures such as
+\fBTcl_GetEncoding\fR. The \fItoUtfProc\fR refers to a callback
+procedure to invoke to convert text from this encoding into UTF-8.
+The \fIfromUtfProc\fR refers to a callback procedure to invoke to
+convert text from UTF-8 into this encoding. The \fIfreeProc\fR refers
+to a callback procedure to invoke when this encoding is deleted. The
+\fIfreeProc\fR field may be NULL. The \fIclientData\fR contains an
+arbitrary one-word value passed to \fItoUtfProc\fR, \fIfromUtfProc\fR,
+and \fIfreeProc\fR whenever they are called. Typically, this is a
+pointer to a data structure containing encoding-specific information
+that can be used by the callback procedures. For instance, two very
+similar encodings such as \fBascii\fR and \fBmacRoman\fR may use the
+same callback procedure, but use different values of \fIclientData\fR
+to control its behavior. The \fInullSize\fR specifies the number of
+zero bytes that signify end-of-string in this encoding. It must be
+\fB1\fR (for single-byte or multi-byte encodings like ASCII or
+Shift-JIS) or \fB2\fR (for double-byte encodings like Unicode).
+Constant-sized encodings with 3 or more bytes per character (such as
+CNS11643) are not accepted.
+.PP
+The callback procedures \fItoUtfProc\fR and \fIfromUtfProc\fR should match the
+type \fBTcl_EncodingConvertProc\fR:
+.PP
+.CS
+typedef int \fBTcl_EncodingConvertProc\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
+\fBTcl_ExternalToUtf\fR or \fBTcl_UtfToExternal\fR family of functions to
+perform the actual conversion. The \fIclientData\fR parameter to these
+procedures is the same as the \fIclientData\fR field specified to
+\fBTcl_CreateEncoding\fR when the encoding was created. The remaining
+arguments to the callback procedures are the same as the arguments,
+documented at the top, to \fBTcl_ExternalToUtf\fR or
+\fBTcl_UtfToExternal\fR, with the following exceptions. If the
+\fIsrcLen\fR argument to one of those high-level functions is negative,
+the value passed to the callback procedure will be the appropriate
+encoding-specific string length of \fIsrc\fR. If any of the \fIsrcReadPtr\fR,
+\fIdstWrotePtr\fR, or \fIdstCharsPtr\fR arguments to one of the high-level
+functions is NULL, the corresponding value passed to the callback
+procedure will be a non-NULL location.
+.PP
+The callback procedure \fIfreeProc\fR, if non-NULL, should match the type
+\fBTcl_EncodingFreeProc\fR:
+.PP
+.CS
+typedef void \fBTcl_EncodingFreeProc\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
+\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
+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.
+.SH "ENCODING FILES"
+Space would prohibit precompiling into Tcl every possible encoding
+algorithm, so many encodings are stored on disk as dynamically-loadable
+encoding files. This behavior also allows the user to create additional
+encoding files that can be loaded using the same mechanism. These
+encoding files contain information about the tables and/or escape
+sequences used to map between an external encoding and Unicode. The
+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
+.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"
+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"
+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"
+A multi-byte encoding, where one character may be either one or two bytes long.
+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"
+An escape-sequence encoding, specifying that certain sequences of bytes
+do not represent characters, but commands that describe how following bytes
+should be interpreted.
+.PP
+The rest of the lines in the file depend on the type.
+.PP
+Cases [1], [2], and [3] are collectively referred to as table-based encoding
+files. The lines in a table-based encoding file are in the same
+format as this example taken from the \fBshiftjis\fR encoding (this is not
+the complete file):
+.PP
+.CS
+# Encoding file: shiftjis, multi-byte
+M
+003F 0 40
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D203E007F
+0080000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
+FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
+FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
+FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+81
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+300030013002FF0CFF0E30FBFF1AFF1BFF1FFF01309B309C00B4FF4000A8FF3E
+FFE3FF3F30FD30FE309D309E30034EDD30053006300730FC20152010FF0F005C
+301C2016FF5C2026202520182019201C201DFF08FF0930143015FF3BFF3DFF5B
+FF5D30083009300A300B300C300D300E300F30103011FF0B221200B100D70000
+00F7FF1D2260FF1CFF1E22662267221E22342642264000B0203220332103FFE5
+FF0400A200A3FF05FF03FF06FF0AFF2000A72606260525CB25CF25CE25C725C6
+25A125A025B325B225BD25BC203B301221922190219121933013000000000000
+000000000000000000000000000000002208220B2286228722822283222A2229
+000000000000000000000000000000002227222800AC21D221D4220022030000
+0000000000000000000000000000000000000000222022A52312220222072261
+2252226A226B221A223D221D2235222B222C0000000000000000000000000000
+212B2030266F266D266A2020202100B6000000000000000025EF000000000000
+.CE
+.PP
+The third line of the file is three numbers. The first number is the
+fallback character (in base 16) to use when converting from UTF-8 to this
+encoding. The second number is a \fB1\fR if this file represents the
+encoding for a symbol font, or \fB0\fR otherwise. The last number (in base
+10) is how many pages of data follow.
+.PP
+Subsequent lines in the example above are pages that describe how to map
+from the encoding into 2-byte Unicode. The first line in a page identifies
+the page number. Following it are 256 double-byte numbers, arranged as 16
+rows of 16 numbers. Given a character in the encoding, the high byte of
+that character is used to select which page, and the low byte of that
+character is used as an index to select one of the double-byte numbers in
+that page \- the value obtained being the corresponding Unicode character.
+By examination of the example above, one can see that the characters 0x7E
+and 0x8163 in \fBshiftjis\fR map to 203E and 2026 in Unicode, respectively.
+.PP
+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 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
+file are in the same format as this example taken from the \fBiso2022-jp\fR
+encoding:
+.PP
+.CS
+.ta 1.5i
+# Encoding file: iso2022-jp, escape-driven
+E
+init {}
+final {}
+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
+is the associated value. \fBinit\fR is a string to emit or expect before
+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,
+.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 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/library/msgcat/doc/Ensemble.3 b/library/msgcat/doc/Ensemble.3
new file mode 100644
index 0000000..cd69bbd
--- /dev/null
+++ b/library/msgcat/doc/Ensemble.3
@@ -0,0 +1,219 @@
+'\"
+'\" 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_GetEnsembleParameterList, Tcl_GetEnsembleUnknownHandler, Tcl_GetEnsembleSubcommandList, Tcl_IsEnsemble, Tcl_SetEnsembleFlags, Tcl_SetEnsembleMappingDict, Tcl_SetEnsembleParameterList, 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
+.VS 8.6
+int
+\fBTcl_GetEnsembleParameterList\fR(\fIinterp, token, listObjPtr\fR)
+.sp
+int
+\fBTcl_SetEnsembleParameterList\fR(\fIinterp, token, listObj\fR)
+.VE 8.6
+.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, \fBTCL_ENSEMBLE_PREFIX\fR,
+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 \fBTCL_LEAVE_ERR_MSG\fR 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 \fBTCL_ENSEMBLE_PREFIX\fR 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 list of formal pre-subcommand parameters, the
+defined list of subcommands in the dictionary or the unknown subcommand
+handler command prefix. May be NULL if the subcommand list or unknown handler
+are to be removed.
+.AP Tcl_Obj **listObjPtr out
+Pointer to a variable into which to write the current list of formal
+pre-subcommand parameters, the defined 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 \fBTCL_LEAVE_ERR_MSG\fR 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 \fBTCL_ENSEMBLE_PREFIX\fR
+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 (\fBTCL_OK\fR, or \fBTCL_ERROR\fR 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 (\fBTCL_OK\fR, or \fBTCL_ERROR\fR if the token does not refer to an
+ensemble) and the dictionary obtained from
+\fBTcl_GetEnsembleMappingDict\fR should always be treated as immutable
+even if it is unshared.
+All command names in prefixes set via \fBTcl_SetEnsembleMappingDict\fR
+must be fully qualified.
+.TP
+\fBformal pre-subcommand parameter list\fR (read-write)
+.VS 8.6
+A list of formal parameter names (the names only being used when generating
+error messages) that come at invocation of the ensemble between the name of
+the ensemble and the subcommand argument. NULL (the default) is equivalent to
+the empty list. May be read and written using
+\fBTcl_GetEnsembleParameterList\fR and \fBTcl_SetEnsembleParameterList\fR
+respectively. The result of both of those functions is a Tcl result code
+(\fBTCL_OK\fR, or \fBTCL_ERROR\fR if the token does not refer to an
+ensemble) and the
+dictionary obtained from \fBTcl_GetEnsembleParameterList\fR should always be
+treated as immutable even if it is unshared.
+.VE 8.6
+.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 (\fBTCL_OK\fR, or
+\fBTCL_ERROR\fR if the
+token does not refer to an ensemble) and the list obtained from
+\fBTcl_GetEnsembleSubcommandList\fR should always be treated as
+immutable even if it is unshared.
+.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 (\fBTCL_OK\fR, or \fBTCL_ERROR\fR 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
+(\fBTCL_OK\fR, or \fBTCL_ERROR\fR if the token does not refer to an ensemble).
+.SH "SEE ALSO"
+namespace(n), Tcl_DeleteCommandFromToken(3)
+.SH KEYWORDS
+command, ensemble
diff --git a/library/msgcat/doc/Environment.3 b/library/msgcat/doc/Environment.3
new file mode 100644
index 0000000..3753f43
--- /dev/null
+++ b/library/msgcat/doc/Environment.3
@@ -0,0 +1,38 @@
+'\"
+'\" 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_PutEnv 3 "7.5" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_PutEnv \- procedures to manipulate the environment
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_PutEnv\fR(\fIassignment\fR)
+.SH ARGUMENTS
+.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
+.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
+\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/library/msgcat/doc/Eval.3 b/library/msgcat/doc/Eval.3
new file mode 100644
index 0000000..b776e93
--- /dev/null
+++ b/library/msgcat/doc/Eval.3
@@ -0,0 +1,211 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Scriptics Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_Eval 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_EvalObjEx, Tcl_EvalFile, Tcl_EvalObjv, Tcl_Eval, Tcl_EvalEx, Tcl_GlobalEval, Tcl_GlobalEvalObj, Tcl_VarEval, Tcl_VarEvalVA \- execute Tcl scripts
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_EvalObjEx\fR(\fIinterp, objPtr, flags\fR)
+.sp
+int
+\fBTcl_EvalFile\fR(\fIinterp, fileName\fR)
+.sp
+int
+\fBTcl_EvalObjv\fR(\fIinterp, objc, objv, flags\fR)
+.sp
+int
+\fBTcl_Eval\fR(\fIinterp, script\fR)
+.sp
+int
+\fBTcl_EvalEx\fR(\fIinterp, script, numBytes, flags\fR)
+.sp
+int
+\fBTcl_GlobalEval\fR(\fIinterp, script\fR)
+.sp
+int
+\fBTcl_GlobalEvalObj\fR(\fIinterp, objPtr\fR)
+.sp
+int
+\fBTcl_VarEval\fR(\fIinterp, part, part, ... \fB(char *) NULL\fR)
+.sp
+int
+\fBTcl_VarEvalVA\fR(\fIinterp, argList\fR)
+.SH ARGUMENTS
+.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.
+.AP Tcl_Obj *objPtr in
+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
+Name of a file containing a Tcl script.
+.AP int objc in
+The number of objects in the array pointed to by \fIobjPtr\fR;
+this is also the number of words in the command.
+.AP Tcl_Obj **objv in
+Points to an array of pointers to objects; each object holds the
+value of a single word in the command to execute.
+.AP int numBytes in
+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
+Points to first byte of script to execute (null-terminated and UTF-8).
+.AP char *part in
+String forming part of a Tcl script.
+.AP va_list argList in
+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 invoked to execute Tcl scripts in
+various forms.
+\fBTcl_EvalObjEx\fR is the core procedure and is used by many of the others.
+It executes the commands in the script stored in \fIobjPtr\fR
+until either an error occurs or the end of the script is reached.
+If this is the first time \fIobjPtr\fR has been executed,
+its commands are compiled into bytecode instructions
+which are then executed. The
+bytecodes are saved in \fIobjPtr\fR so that the compilation step
+can be skipped if the object is evaluated again in the future.
+.PP
+The return value from \fBTcl_EvalObjEx\fR (and all the other procedures
+described here) is a Tcl completion code with
+one of the values \fBTCL_OK\fR, \fBTCL_ERROR\fR, \fBTCL_RETURN\fR,
+\fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR, or possibly some other
+integer value originating in an extension.
+In addition, a result value or error message is left in \fIinterp\fR's
+result; it can be retrieved using \fBTcl_GetObjResult\fR.
+.PP
+\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 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 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
+executed again, \fBTcl_Eval\fR may be faster than \fBTcl_EvalObjEx\fR.
+ \fBTcl_Eval\fR returns a completion code and result just like
+\fBTcl_EvalObjEx\fR. Note: for backward compatibility with versions before
+Tcl 8.0, \fBTcl_Eval\fR copies the object result in \fIinterp\fR to
+\fIinterp->result\fR (use is deprecated) where it can be accessed directly.
+ This makes \fBTcl_Eval\fR somewhat slower than \fBTcl_EvalEx\fR, which
+does not do the copy.
+.PP
+\fBTcl_EvalEx\fR is an extended version of \fBTcl_Eval\fR that takes
+additional arguments \fInumBytes\fR and \fIflags\fR. For the
+efficiency reason given above, \fBTcl_EvalEx\fR is generally preferred
+over \fBTcl_Eval\fR.
+.PP
+\fBTcl_GlobalEval\fR and \fBTcl_GlobalEvalObj\fR are older procedures
+that are now deprecated. They are similar to \fBTcl_EvalEx\fR and
+\fBTcl_EvalObjEx\fR except that the script is evaluated in the global
+namespace and its variable context consists of global variables only
+(it ignores any Tcl procedures that are active). These functions are
+equivalent to using the \fBTCL_EVAL_GLOBAL\fR flag (see below).
+.PP
+\fBTcl_VarEval\fR takes any number of string arguments
+of any length, concatenates them into a single string,
+then calls \fBTcl_Eval\fR to execute that string as a Tcl command.
+It returns the result of the command and also modifies
+\fIinterp->result\fR in the same way as \fBTcl_Eval\fR.
+The last argument to \fBTcl_VarEval\fR must be NULL to indicate the end
+of arguments. \fBTcl_VarEval\fR is now deprecated.
+.PP
+\fBTcl_VarEvalVA\fR is the same as \fBTcl_VarEval\fR except that
+instead of taking a variable number of arguments it takes an argument
+list. Like \fBTcl_VarEval\fR, \fBTcl_VarEvalVA\fR is deprecated.
+
+.SH "FLAG BITS"
+.PP
+Any ORed combination of the following values may be used for the
+\fIflags\fR argument to procedures such as \fBTcl_EvalObjEx\fR:
+.TP 23
+\fBTCL_EVAL_DIRECT\fR
+.
+This flag is only used by \fBTcl_EvalObjEx\fR; it is ignored by
+other procedures. If this flag bit is set, the script is not
+compiled to bytecodes; instead it is executed directly
+as is done by \fBTcl_EvalEx\fR. The
+\fBTCL_EVAL_DIRECT\fR flag is useful in situations where the
+contents of an object are going to change immediately, so the
+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
+means that it is evaluated in the global namespace and its variable
+context consists of global variables only (it ignores any Tcl
+procedures that are active).
+
+.SH "MISCELLANEOUS DETAILS"
+.PP
+During the processing of a Tcl command it is legal to make nested
+calls to evaluate other commands (this is how procedures and
+some control structures are implemented).
+If a code other than \fBTCL_OK\fR is returned
+from a nested \fBTcl_EvalObjEx\fR invocation,
+then the caller should normally return immediately,
+passing that same return code back to its caller,
+and so on until the top-level application is reached.
+A few commands, like \fBfor\fR, will check for certain
+return codes, like \fBTCL_BREAK\fR and \fBTCL_CONTINUE\fR, and process them
+specially without returning.
+.PP
+\fBTcl_EvalObjEx\fR keeps track of how many nested \fBTcl_EvalObjEx\fR
+invocations are in progress for \fIinterp\fR.
+If a code of \fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR is
+about to be returned from the topmost \fBTcl_EvalObjEx\fR
+invocation for \fIinterp\fR,
+it converts the return code to \fBTCL_ERROR\fR
+and sets \fIinterp\fR's result to an error message indicating that
+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.
+
+.SH KEYWORDS
+execute, file, global, object, result, script
diff --git a/library/msgcat/doc/Exit.3 b/library/msgcat/doc/Exit.3
new file mode 100644
index 0000000..fd251c7
--- /dev/null
+++ b/library/msgcat/doc/Exit.3
@@ -0,0 +1,140 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.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, Tcl_SetExitProc \- end the application or thread (and invoke exit handlers)
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_Exit\fR(\fIstatus\fR)
+.sp
+\fBTcl_Finalize\fR()
+.sp
+\fBTcl_CreateExitHandler\fR(\fIproc, clientData\fR)
+.sp
+\fBTcl_DeleteExitHandler\fR(\fIproc, clientData\fR)
+.sp
+\fBTcl_ExitThread\fR(\fIstatus\fR)
+.sp
+\fBTcl_FinalizeThread\fR()
+.sp
+\fBTcl_CreateThreadExitHandler\fR(\fIproc, clientData\fR)
+.sp
+\fBTcl_DeleteThreadExitHandler\fR(\fIproc, clientData\fR)
+.sp
+Tcl_ExitProc *
+\fBTcl_SetExitProc\fR(\fIproc\fR)
+.SH ARGUMENTS
+.AS Tcl_ExitProc clientData
+.AP int status in
+Provides information about why the application or thread exited.
+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, 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
+
+.SH DESCRIPTION
+.PP
+The procedures described here provide a graceful mechanism to end the
+execution of a \fBTcl\fR application. Exit handlers are invoked to cleanup the
+application's state before ending the execution of \fBTcl\fR code.
+.PP
+Invoke \fBTcl_Exit\fR to end a \fBTcl\fR application and to exit from this
+process. This procedure is invoked by the \fBexit\fR command, and can be
+invoked anyplace else to terminate the application.
+No-one should ever invoke the \fBexit\fR system procedure directly; always
+invoke \fBTcl_Exit\fR instead, so that it can invoke exit handlers.
+Note that if other code invokes \fBexit\fR system procedure directly, or
+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.
+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.
+.PP
+\fBTcl_Finalize\fR is similar to \fBTcl_Exit\fR except that it does not
+exit from the current process.
+It is useful for cleaning up when a process is finished using \fBTcl\fR but
+wishes to continue executing, and when \fBTcl\fR is used in a dynamically
+loaded extension that is about to be unloaded.
+Your code should always invoke \fBTcl_Finalize\fR when \fBTcl\fR is being
+unloaded, to ensure proper cleanup. \fBTcl_Finalize\fR can be safely called
+more than once.
+.PP
+\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.
+.PP
+\fBTcl_CreateExitHandler\fR arranges for \fIproc\fR to be invoked
+by \fBTcl_Finalize\fR and \fBTcl_Exit\fR.
+\fBTcl_CreateThreadExitHandler\fR arranges for \fIproc\fR to be invoked
+by \fBTcl_FinalizeThread\fR and \fBTcl_ExitThread\fR.
+This provides a hook for cleanup operations such as flushing buffers
+and freeing global memory.
+\fIProc\fR should match the type \fBTcl_ExitProc\fR:
+.PP
+.CS
+typedef void \fBTcl_ExitProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR parameter to \fIproc\fR is a
+copy of the \fIclientData\fR argument given to
+\fBTcl_CreateExitHandler\fR or \fBTcl_CreateThreadExitHandler\fR when
+the callback
+was created. Typically, \fIclientData\fR points to a data
+structure containing application-specific information about
+what to do in \fIproc\fR.
+.PP
+\fBTcl_DeleteExitHandler\fR and \fBTcl_DeleteThreadExitHandler\fR may be
+called to delete a
+previously-created exit handler. It removes the handler
+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
+\fBTcl_Finalize\fR and \fBTcl_Exit\fR execute all registered exit handlers,
+in reverse order from the order in which they were registered.
+This matches the natural order in which extensions are loaded and unloaded;
+if extension \fBA\fR loads extension \fBB\fR, it usually
+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.
+.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.
+.PP
+\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.
+.SH "SEE ALSO"
+exit(n)
+.SH KEYWORDS
+abort, callback, cleanup, dynamic loading, end application, exit, unloading, thread
diff --git a/library/msgcat/doc/ExprLong.3 b/library/msgcat/doc/ExprLong.3
new file mode 100644
index 0000000..ef93284
--- /dev/null
+++ b/library/msgcat/doc/ExprLong.3
@@ -0,0 +1,106 @@
+'\"
+'\" Copyright (c) 1989-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.
+'\"
+.so man.macros
+.TH Tcl_ExprLong 3 7.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean, Tcl_ExprString \- evaluate an expression
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_ExprLong\fR(\fIinterp, expr, longPtr\fR)
+.sp
+int
+\fBTcl_ExprDouble\fR(\fIinterp, expr, doublePtr\fR)
+.sp
+int
+\fBTcl_ExprBoolean\fR(\fIinterp, expr, booleanPtr\fR)
+.sp
+int
+\fBTcl_ExprString\fR(\fIinterp, expr\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *booleanPtr out
+.AP Tcl_Interp *interp in
+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
+expression.
+.AP int *doublePtr out
+Pointer to location in which to store the floating-point value of the
+expression.
+.AP int *booleanPtr out
+Pointer to location in which to store the 0/1 boolean value of the
+expression.
+.BE
+
+.SH DESCRIPTION
+.PP
+These four procedures all evaluate the expression
+given by the \fIexpr\fR argument
+and return the result in one of four different forms.
+The expression can have any of the forms accepted by the \fBexpr\fR command.
+Note that these procedures have been largely replaced by the
+object-based procedures \fBTcl_ExprLongObj\fR, \fBTcl_ExprDoubleObj\fR,
+\fBTcl_ExprBooleanObj\fR, and \fBTcl_ExprObj\fR.
+Those object-based procedures evaluate an expression held in a Tcl object
+instead of a string.
+The object argument can retain an internal representation
+that is more efficient to execute.
+.PP
+The \fIinterp\fR argument refers to an interpreter used to
+evaluate the expression (e.g. for variables and nested Tcl
+commands) and to return error information.
+.PP
+For all of these procedures the return value is a standard
+Tcl result: \fBTCL_OK\fR means the expression was successfully
+evaluated, and \fBTCL_ERROR\fR means that an error occurred while
+evaluating the expression.
+If \fBTCL_ERROR\fR is returned then
+the interpreter's result will hold a message describing the error.
+If an error occurs while executing a Tcl command embedded in
+the expression then that error will be returned.
+.PP
+If the expression is successfully evaluated, then its value is
+returned in one of four forms, depending on which procedure
+is invoked.
+\fBTcl_ExprLong\fR stores an integer value at \fI*longPtr\fR.
+If the expression's actual value is a floating-point number,
+then it is truncated to an integer.
+If the expression's actual value is a non-numeric string then
+an error is returned.
+.PP
+\fBTcl_ExprDouble\fR stores a floating-point value at \fI*doublePtr\fR.
+If the expression's actual value is an integer, it is converted to
+floating-point.
+If the expression's actual value is a non-numeric string then
+an error is returned.
+.PP
+\fBTcl_ExprBoolean\fR stores a 0/1 integer value at \fI*booleanPtr\fR.
+If the expression's actual value is an integer or floating-point
+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
+.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.
+
+.SH "SEE ALSO"
+Tcl_ExprLongObj, Tcl_ExprDoubleObj, Tcl_ExprBooleanObj, Tcl_ExprObj
+
+.SH KEYWORDS
+boolean, double, evaluate, expression, integer, object, string
diff --git a/library/msgcat/doc/ExprLongObj.3 b/library/msgcat/doc/ExprLongObj.3
new file mode 100644
index 0000000..c8a564d
--- /dev/null
+++ b/library/msgcat/doc/ExprLongObj.3
@@ -0,0 +1,106 @@
+'\"
+'\" Copyright (c) 1996-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 Tcl_ExprLongObj 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_ExprLongObj, Tcl_ExprDoubleObj, Tcl_ExprBooleanObj, Tcl_ExprObj \- evaluate an expression
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_ExprLongObj\fR(\fIinterp, objPtr, longPtr\fR)
+.sp
+int
+\fBTcl_ExprDoubleObj\fR(\fIinterp, objPtr, doublePtr\fR)
+.sp
+int
+\fBTcl_ExprBooleanObj\fR(\fIinterp, objPtr, booleanPtr\fR)
+.sp
+int
+\fBTcl_ExprObj\fR(\fIinterp, objPtr, resultPtrPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp **resultPtrPtr out
+.AP Tcl_Interp *interp in
+Interpreter in whose context to evaluate \fIobjPtr\fR.
+.AP Tcl_Obj *objPtr in
+Pointer to an object containing the expression to evaluate.
+.AP long *longPtr out
+Pointer to location in which to store the integer value of the
+expression.
+.AP int *doublePtr out
+Pointer to location in which to store the floating-point value of the
+expression.
+.AP int *booleanPtr out
+Pointer to location in which to store the 0/1 boolean value of the
+expression.
+.AP Tcl_Obj **resultPtrPtr out
+Pointer to location in which to store a pointer to the object
+that is the result of the expression.
+.BE
+
+.SH DESCRIPTION
+.PP
+These four procedures all evaluate an expression, returning
+the result in one of four different forms.
+The expression is given by the \fIobjPtr\fR argument, and it
+can have any of the forms accepted by the \fBexpr\fR command.
+.PP
+The \fIinterp\fR argument refers to an interpreter used to
+evaluate the expression (e.g. for variables and nested Tcl
+commands) and to return error information.
+.PP
+For all of these procedures the return value is a standard
+Tcl result: \fBTCL_OK\fR means the expression was successfully
+evaluated, and \fBTCL_ERROR\fR means that an error occurred while
+evaluating the expression.
+If \fBTCL_ERROR\fR is returned,
+then a message describing the error
+can be retrieved using \fBTcl_GetObjResult\fR.
+If an error occurs while executing a Tcl command embedded in
+the expression then that error will be returned.
+.PP
+If the expression is successfully evaluated, then its value is
+returned in one of four forms, depending on which procedure
+is invoked.
+\fBTcl_ExprLongObj\fR stores an integer value at \fI*longPtr\fR.
+If the expression's actual value is a floating-point number,
+then it is truncated to an integer.
+If the expression's actual value is a non-numeric string then
+an error is returned.
+.PP
+\fBTcl_ExprDoubleObj\fR stores a floating-point value at \fI*doublePtr\fR.
+If the expression's actual value is an integer, it is converted to
+floating-point.
+If the expression's actual value is a non-numeric string then
+an error is returned.
+.PP
+\fBTcl_ExprBooleanObj\fR stores a 0/1 integer value at \fI*booleanPtr\fR.
+If the expression's actual value is an integer or floating-point
+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
+.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
+containing the expression's value at \fI*resultPtrPtr\fR.
+In this case, the caller is responsible for calling
+\fBTcl_DecrRefCount\fR to decrement the object's reference count
+when it is finished with the object.
+
+.SH "SEE ALSO"
+Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean, Tcl_ExprString, Tcl_GetObjResult
+
+.SH KEYWORDS
+boolean, double, evaluate, expression, integer, object, string
diff --git a/library/msgcat/doc/FileSystem.3 b/library/msgcat/doc/FileSystem.3
new file mode 100644
index 0000000..d7198b1
--- /dev/null
+++ b/library/msgcat/doc/FileSystem.3
@@ -0,0 +1,1643 @@
+'\"
+'\" Copyright (c) 2001 Vincent Darley
+'\" Copyright (c) 2008-2010 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 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_FSEvalFileEx, Tcl_FSLoadFile, Tcl_FSUnloadFile, Tcl_FSMatchInDirectory, Tcl_FSLink, Tcl_FSLstat, Tcl_FSUtime, Tcl_FSFileAttrsGet, Tcl_FSFileAttrsSet, Tcl_FSFileAttrStrings, Tcl_FSStat, Tcl_FSAccess, Tcl_FSOpenFileChannel, Tcl_FSGetCwd, Tcl_FSChdir, Tcl_FSPathSeparator, Tcl_FSJoinPath, Tcl_FSSplitPath, Tcl_FSEqualPaths, Tcl_FSGetNormalizedPath, Tcl_FSJoinToPath, Tcl_FSConvertToPathType, Tcl_FSGetInternalRep, Tcl_FSGetTranslatedPath, Tcl_FSGetTranslatedStringPath, Tcl_FSNewNativePath, Tcl_FSGetNativePath, Tcl_FSFileSystemInfo, Tcl_GetAccessTimeFromStat, Tcl_GetBlockSizeFromStat, Tcl_GetBlocksFromStat, Tcl_GetChangeTimeFromStat, Tcl_GetDeviceTypeFromStat, Tcl_GetFSDeviceFromStat, Tcl_GetFSInodeFromStat, Tcl_GetGroupIdFromStat, Tcl_GetLinkCountFromStat, Tcl_GetModeFromStat, Tcl_GetModificationTimeFromStat, Tcl_GetSizeFromStat, Tcl_GetUserIdFromStat, Tcl_AllocStatBuf \- procedures to interact with any filesystem
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_FSRegister\fR(\fIclientData, fsPtr\fR)
+.sp
+int
+\fBTcl_FSUnregister\fR(\fIfsPtr\fR)
+.sp
+ClientData
+\fBTcl_FSData\fR(\fIfsPtr\fR)
+.sp
+void
+\fBTcl_FSMountsChanged\fR(\fIfsPtr\fR)
+.sp
+const Tcl_Filesystem *
+\fBTcl_FSGetFileSystemForPath\fR(\fIpathPtr\fR)
+.sp
+Tcl_PathType
+\fBTcl_FSGetPathType\fR(\fIpathPtr\fR)
+.sp
+int
+\fBTcl_FSCopyFile\fR(\fIsrcPathPtr, destPathPtr\fR)
+.sp
+int
+\fBTcl_FSCopyDirectory\fR(\fIsrcPathPtr, destPathPtr, errorPtr\fR)
+.sp
+int
+\fBTcl_FSCreateDirectory\fR(\fIpathPtr\fR)
+.sp
+int
+\fBTcl_FSDeleteFile\fR(\fIpathPtr\fR)
+.sp
+int
+\fBTcl_FSRemoveDirectory\fR(\fIpathPtr, int recursive, errorPtr\fR)
+.sp
+int
+\fBTcl_FSRenameFile\fR(\fIsrcPathPtr, destPathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSListVolumes\fR(\fIvoid\fR)
+.sp
+int
+\fBTcl_FSEvalFileEx\fR(\fIinterp, pathPtr, encodingName\fR)
+.sp
+int
+\fBTcl_FSEvalFile\fR(\fIinterp, pathPtr\fR)
+.sp
+int
+\fBTcl_FSLoadFile\fR(\fIinterp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
+ loadHandlePtr, unloadProcPtr\fR)
+.sp
+.VS 8.6
+int
+\fBTcl_FSUnloadFile\fR(\fIinterp, loadHandle\fR)
+.VE 8.6
+.sp
+int
+\fBTcl_FSMatchInDirectory\fR(\fIinterp, resultPtr, pathPtr, pattern, types\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSLink\fR(\fIlinkNamePtr, toPtr, linkAction\fR)
+.sp
+int
+\fBTcl_FSLstat\fR(\fIpathPtr, statPtr\fR)
+.sp
+int
+\fBTcl_FSUtime\fR(\fIpathPtr, tval\fR)
+.sp
+int
+\fBTcl_FSFileAttrsGet\fR(\fIinterp, int index, pathPtr, objPtrRef\fR)
+.sp
+int
+\fBTcl_FSFileAttrsSet\fR(\fIinterp, int index, pathPtr, Tcl_Obj *objPtr\fR)
+.sp
+const char **
+\fBTcl_FSFileAttrStrings\fR(\fIpathPtr, objPtrRef\fR)
+.sp
+int
+\fBTcl_FSStat\fR(\fIpathPtr, statPtr\fR)
+.sp
+int
+\fBTcl_FSAccess\fR(\fIpathPtr, mode\fR)
+.sp
+Tcl_Channel
+\fBTcl_FSOpenFileChannel\fR(\fIinterp, pathPtr, modeString, permissions\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSGetCwd\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_FSChdir\fR(\fIpathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSPathSeparator\fR(\fIpathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSJoinPath\fR(\fIlistObj, elements\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSSplitPath\fR(\fIpathPtr, lenPtr\fR)
+.sp
+int
+\fBTcl_FSEqualPaths\fR(\fIfirstPtr, secondPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSGetNormalizedPath\fR(\fIinterp, pathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSJoinToPath\fR(\fIbasePtr, objc, objv\fR)
+.sp
+int
+\fBTcl_FSConvertToPathType\fR(\fIinterp, pathPtr\fR)
+.sp
+ClientData
+\fBTcl_FSGetInternalRep\fR(\fIpathPtr, fsPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSGetTranslatedPath\fR(\fIinterp, pathPtr\fR)
+.sp
+const char *
+\fBTcl_FSGetTranslatedStringPath\fR(\fIinterp, pathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSNewNativePath\fR(\fIfsPtr, clientData\fR)
+.sp
+const void *
+\fBTcl_FSGetNativePath\fR(\fIpathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSFileSystemInfo\fR(\fIpathPtr\fR)
+.sp
+Tcl_StatBuf *
+\fBTcl_AllocStatBuf\fR()
+.sp
+.VS 8.6
+Tcl_WideInt
+\fBTcl_GetAccessTimeFromStat\fR(\fIstatPtr\fR)
+.sp
+unsigned
+\fBTcl_GetBlockSizeFromStat\fR(\fIstatPtr\fR)
+.sp
+Tcl_WideUInt
+\fBTcl_GetBlocksFromStat\fR(\fIstatPtr\fR)
+.sp
+Tcl_WideInt
+\fBTcl_GetChangeTimeFromStat\fR(\fIstatPtr\fR)
+.sp
+int
+\fBTcl_GetDeviceTypeFromStat\fR(\fIstatPtr\fR)
+.sp
+unsigned
+\fBTcl_GetFSDeviceFromStat\fR(\fIstatPtr\fR)
+.sp
+unsigned
+\fBTcl_GetFSInodeFromStat\fR(\fIstatPtr\fR)
+.sp
+int
+\fBTcl_GetGroupIdFromStat\fR(\fIstatPtr\fR)
+.sp
+int
+\fBTcl_GetLinkCountFromStat\fR(\fIstatPtr\fR)
+.sp
+unsigned
+\fBTcl_GetModeFromStat\fR(\fIstatPtr\fR)
+.sp
+Tcl_WideInt
+\fBTcl_GetModificationTimeFromStat\fR(\fIstatPtr\fR)
+.sp
+Tcl_WideUInt
+\fBTcl_GetSizeFromStat\fR(\fIstatPtr\fR)
+.sp
+int
+\fBTcl_GetUserIdFromStat\fR(\fIstatPtr\fR)
+.VE 8.6
+.SH ARGUMENTS
+.AS Tcl_GlobTypeData **srcPathPtr out
+.AP "const Tcl_Filesystem" *fsPtr in
+Points to a structure containing the addresses of procedures that
+can be called to perform the various filesystem operations.
+.AP Tcl_Obj *pathPtr in
+The path represented by this object is used for the operation in
+question. If the object does not already have an internal \fBpath\fR
+representation, it will be converted to have one.
+.AP Tcl_Obj *srcPathPtr in
+As for \fIpathPtr\fR, but used for the source file for a copy or
+rename operation.
+.AP Tcl_Obj *destPathPtr in
+As for \fIpathPtr\fR, but used for the destination filename for a copy or
+rename operation.
+.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. This parameter may be NULL.
+.AP Tcl_Interp *interp in
+Interpreter to use either for results, evaluation, or reporting error
+messages.
+.AP ClientData clientData in
+The native description of the path object to create.
+.AP Tcl_Obj *firstPtr in
+The first of two path objects to compare. The object may be converted
+to \fBpath\fR type.
+.AP Tcl_Obj *secondPtr in
+The second of two path objects to compare. The object may be converted
+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 \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 *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,
+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
+Name of a procedure to look up in the file's symbol table
+.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 ClientData *clientDataPtr out
+Filled with the clientData value to pass to this code's unload
+function when it is called.
+.AP Tcl_LoadHandle *loadHandlePtr 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 Tcl_LoadHandle loadHandle in
+Handle to the loaded library to be unloaded.
+.AP utimbuf *tval in
+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
+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
+POSIX-style permission flags such as 0644. If a new file is created, these
+permissions will be set on the created file.
+.AP int *lenPtr out
+If non-NULL, filled with the number of elements in the split path.
+.AP Tcl_Obj *basePtr in
+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
+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 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 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
+.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
+.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
+.QW files
+which are not
+native files in the native filesystem. This also means that any Tcl
+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.
+.PP
+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
+.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 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 reference count of zero to any of these functions. If such calls were
+handled, they might result
+in memory leaks (under some circumstances, the filesystem code may wish
+to retain a reference to the passed in object, and so one must not assume
+that after any of these calls return, the object still has a reference count of
+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
+.PP
+.CS
+Tcl_Obj *path = Tcl_NewStringObj(...);
+Tcl_FS\fIWhatever\fR(path);
+Tcl_DecrRefCount(path);
+.CE
+.PP
+is wrong, and may cause memory errors. The \fIpath\fR must have its
+reference count incremented before passing it in, or
+decrementing it. For this reason, objects with a reference count of zero are
+considered not to be valid filesystem paths and calling any Tcl_FS API
+function with such an object will result in no action being taken.
+.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
+.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
+.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
+\fIpathPtr\fR by calling the owning filesystem's
+.QW "create directory"
+function.
+.PP
+\fBTcl_FSDeleteFile\fR attempts to delete the file given by
+\fIpathPtr\fR by calling the owning filesystem's
+.QW "delete file"
+function.
+.PP
+\fBTcl_FSRemoveDirectory\fR attempts to remove the directory given by
+\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
+\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
+.QW "rename 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_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 reference count of 0).
+.PP
+\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 \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.
+.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 \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.
+.VS 8.6
+\fBTcl_FSUnloadFile\fR reverses the operation, asking for the library
+indicated by the \fIloadHandle\fR to be removed from the process. Note that,
+unlike with the \fBunload\fR command, this does not give the library any
+opportunity to clean up.
+.VE 8.6
+.PP
+Both the above functions return a standard Tcl completion code. If an error
+occurs, an error message is left in the \fIinterp\fR's result.
+.PP
+.VS 8.6
+The token provided via the variable indicated by \fIloadHandlePtr\fR may be
+used with \fBTcl_FindSymbol\fR.
+.VE 8.6
+.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 \fIpathPtr\fR belongs will be called.
+.PP
+The return value is a standard Tcl result indicating whether an error
+occurred in globbing. Error messages are placed in interp (unless
+interp is NULL, which is allowed), but good results are placed in the
+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 \fBstring match\fR. To handle recursion, Tcl
+will call this function frequently asking only for directories to be
+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 \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
+.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 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 is returned.
+.PP
+\fBTcl_FSLstat\fR fills the \fITcl_StatBuf\fR structure \fIstatPtr\fR with
+information about the specified file. You do not need any access rights to the
+file to get this information but you need search rights to all
+directories named in the path leading to the file. The \fITcl_StatBuf\fR
+structure includes info regarding device, inode (always 0 on Windows),
+privilege mode, nlink (always 1 on Windows), user id (always 0 on
+Windows), group id (always 0 on Windows), rdev (same as device on
+Windows), size, last access time, last modification time, and
+last metadata change time.
+See \fBPORTABLE STAT RESULT API\fR for a description of how to write
+portable code to allocate and access the \fITcl_StatBuf\fR structure.
+.PP
+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.
+.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
+\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
+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
+\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_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
+The called procedure may either return an array of strings, or may
+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
+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 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.
+.PP
+\fBTcl_FSStat\fR fills the \fITcl_StatBuf\fR structure \fIstatPtr\fR with
+information about the specified file. You do not need any access rights to the
+file to get this information but you need search rights to all
+directories named in the path leading to the file. The \fITcl_StatBuf\fR
+structure includes info regarding device, inode (always 0 on Windows),
+privilege mode, nlink (always 1 on Windows), user id (always 0 on
+Windows), group id (always 0 on Windows), rdev (same as device on
+Windows), size, last access time, last modification time, and
+last metadata change time.
+See \fBPORTABLE STAT RESULT API\fR for a description of how to write
+portable code to allocate and access the \fITcl_StatBuf\fR structure.
+.PP
+If \fIpath\fR exists, \fBTcl_FSStat\fR returns 0 and the stat structure
+is filled with data. Otherwise, -1 is returned, and no stat info is
+given.
+.PP
+\fBTcl_FSOpenFileChannel\fR opens a file specified by \fIpathPtr\fR and
+returns a channel handle that can be used to perform input and output on
+the file. This API is modeled after the \fBfopen\fR procedure of
+the Unix standard I/O library.
+The syntax and meaning of all arguments is similar to those
+given in the Tcl \fBopen\fR command when opening a file.
+If an error occurs while opening the channel, \fBTcl_FSOpenFileChannel\fR
+returns NULL and records a POSIX error code that can be
+retrieved with \fBTcl_GetErrno\fR.
+In addition, if \fIinterp\fR is non-NULL, \fBTcl_FSOpenFileChannel\fR
+leaves an error message in \fIinterp\fR's result after any error.
+.PP
+The newly created channel is not registered in the supplied interpreter; to
+register it, use \fBTcl_RegisterChannel\fR.
+If one of the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.PP
+\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, 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 \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 \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 \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 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
+an element.
+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.
+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, 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, 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
+.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
+path object, in the given filesystem. If the path object belongs to a
+different filesystem, we return NULL. If the internal representation is
+currently NULL, we attempt to generate it, by calling the filesystem's
+\fBTcl_FSCreateInternalRepProc\fR.
+.PP
+Returns NULL or a valid internal path representation. This internal
+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.
+.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
+.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
+\fBTcl_FSGetNormalizedPath\fR or \fBTcl_FSGetNativePath\fR are usually
+better functions to use for most purposes.
+.PP
+\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 \fBckfree\fR to ensure it is freed. Again,
+\fBTcl_FSGetNormalizedPath\fR or \fBTcl_FSGetNativePath\fR are usually
+better functions to use for most purposes.
+.PP
+\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.\ \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
+.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 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. 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. 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.
+.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.
+.PP
+A valid list object is returned, unless the path object is not
+recognized, when NULL will be returned.
+.PP
+\fBTcl_FSGetFileSystemForPath\fR returns a pointer to the
+\fBTcl_Filesystem\fR which accepts this path as valid.
+.PP
+If no filesystem will accept the path, NULL is returned.
+.PP
+\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 \fBTCL_PATH_ABSOLUTE\fR, \fBTCL_PATH_RELATIVE\fR, or
+\fBTCL_PATH_VOLUME_RELATIVE\fR
+.SS "PORTABLE STAT RESULT API"
+.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
+.VS 8.6
+The portable fields of a \fITcl_StatBuf\fR may be read using the following
+functions, each of which returns the value of the corresponding field listed
+in the table below. Note that on some platforms there may be other fields in
+the \fITcl_StatBuf\fR as it is an alias for a suitable system structure, but
+only the portable ones are made available here. See your system documentation
+for a full description of these fields.
+.DS
+.ta \w'\fBTcl_GetModificationTimeFromStat\fR\0\0\0\0'u
+\fIAccess Function\fR \fIField\fR
+ \fBTcl_GetFSDeviceFromStat\fR st_dev
+ \fBTcl_GetFSInodeFromStat\fR st_ino
+ \fBTcl_GetModeFromStat\fR st_mode
+ \fBTcl_GetLinkCountFromStat\fR st_nlink
+ \fBTcl_GetUserIdFromStat\fR st_uid
+ \fBTcl_GetGroupIdFromStat\fR st_gid
+ \fBTcl_GetDeviceTypeFromStat\fR st_rdev
+ \fBTcl_GetAccessTimeFromStat\fR st_atime
+ \fBTcl_GetModificationTimeFromStat\fR st_mtime
+ \fBTcl_GetChangeTimeFromStat\fR st_ctime
+ \fBTcl_GetSizeFromStat\fR st_size
+ \fBTcl_GetBlocksFromStat\fR st_blocks
+ \fBTcl_GetBlockSizeFromStat\fR st_blksize
+.DE
+.VE 8.6
+.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.
+.PP
+The \fBTcl_Filesystem\fR structures are manipulated using the following
+methods.
+.PP
+\fBTcl_FSRegister\fR takes a pointer to a filesystem structure and an
+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). \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 \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
+filesystem, if that filesystem is registered. Otherwise it will
+return NULL.
+.PP
+\fBTcl_FSMountsChanged\fR is used to inform the Tcl's core that
+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:
+.PP
+.CS
+typedef struct Tcl_Filesystem {
+ 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_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_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;
+} \fBTcl_Filesystem\fR;
+.CE
+.PP
+Except for the first three fields in this structure which contain
+simple data elements, all entries contain addresses of functions called
+by the generic filesystem layer to perform the complete range of
+filesystem related actions.
+.PP
+The many functions in this structure are broken down into three
+categories: infrastructure functions (almost all of which must be
+implemented), operational functions (which must be implemented if a
+complete filesystem is provided), and efficiency functions (which need
+only be implemented if they can be done so efficiently, or if they have
+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 \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_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 (\fBlstat\fR, \fBload\fR, \fBgetcwd\fR and \fBchdir\fR)
+for which fallbacks do in fact occur at the C level.
+.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.
+.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.
+.PP
+.CS
+static Tcl_Filesystem vfsFilesystem = {
+ "tclvfs",
+ sizeof(Tcl_Filesystem),
+ TCL_FILESYSTEM_VERSION_1,
+ &VfsPathInFilesystem,
+ &VfsDupInternalRep,
+ &VfsFreeInternalRep,
+ /* No internal to normalized, since we don't create
+ * any pure 'internal' Tcl_Obj path representations */
+ NULL,
+ /* No create native rep function, since we don't use
+ * it and don't choose to support uses of
+ * Tcl_FSNewNativePath */
+ NULL,
+ /* Normalize path isn't needed - we assume paths only
+ * have one representation */
+ NULL,
+ &VfsFilesystemPathType,
+ &VfsFilesystemSeparator,
+ &VfsStat,
+ &VfsAccess,
+ &VfsOpenFileChannel,
+ &VfsMatchInDirectory,
+ &VfsUtime,
+ /* We choose not to support symbolic links inside our
+ * VFS's */
+ NULL,
+ &VfsListVolumes,
+ &VfsFileAttrStrings,
+ &VfsFileAttrsGet,
+ &VfsFileAttrsSet,
+ &VfsCreateDirectory,
+ &VfsRemoveDirectory,
+ &VfsDeleteFile,
+ /* No copy file; use the core fallback mechanism */
+ NULL,
+ /* No rename file; use the core fallback mechanism */
+ NULL,
+ /* No copy directory; use the core fallback mechanism */
+ NULL,
+ /* Core will use stat for lstat */
+ NULL,
+ /* No load; use the core fallback mechanism */
+ NULL,
+ /* We don't need a getcwd or chdir; the core's own
+ * internal value is suitable */
+ NULL,
+ NULL
+};
+.CE
+.SH "FILESYSTEM INFRASTRUCTURE"
+.PP
+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.
+.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.
+.SS VERSION
+.PP
+The \fIversion\fR field should be set to \fBTCL_FILESYSTEM_VERSION_1\fR.
+.SS PATHINFILESYSTEMPROC
+.PP
+The \fIpathInFilesystemProc\fR field contains the address of a function
+which is called to determine whether a given path object belongs to this
+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 behavior of Tcl
+for any other return value is not defined). If \fBTCL_OK\fR is returned,
+then the optional \fIclientDataPtr\fR output parameter can be used to
+return an internal (filesystem specific) representation of the path,
+which will be cached inside the path object, and may be retrieved
+efficiently by the other filesystem functions. Tcl will simultaneously
+cache the fact that this path belongs to this filesystem. Such caches
+are invalidated when filesystem structures are added or removed from
+Tcl's internal list of known filesystems.
+.PP
+.CS
+typedef int \fBTcl_FSPathInFilesystemProc\fR(
+ Tcl_Obj *\fIpathPtr\fR,
+ ClientData *\fIclientDataPtr\fR);
+.CE
+.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
+simply not copy the internal representation, which may then need to be
+regenerated later.
+.PP
+.CS
+typedef ClientData \fBTcl_FSDupInternalRepProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.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 \fBTcl_FSFreeInternalRepProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.SS INTERNALTONORMALIZEDPROC
+.PP
+Function to convert internal representation to a normalized path. Only
+required if the filesystem creates pure path objects with no string/path
+representation. The return value is a Tcl object whose string
+representation is the normalized path.
+.PP
+.CS
+typedef Tcl_Obj *\fBTcl_FSInternalToNormalizedProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.SS CREATEINTERNALREPPROC
+.PP
+Function to take a path object, and calculate an internal
+representation for it, and store that native representation in the
+object. May be NULL if paths have no internal representation, or if
+the \fITcl_FSPathInFilesystemProc\fR for this filesystem always
+immediately creates an internal representation for paths it accepts.
+.PP
+.CS
+typedef ClientData \fBTcl_FSCreateInternalRepProc\fR(
+ Tcl_Obj *\fIpathPtr\fR);
+.CE
+.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
+.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
+.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 \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
+up to and including the file separator is known and normalized.
+.PP
+.CS
+typedef int \fBTcl_FSNormalizePathProc\fR(
+ Tcl_Interp *\fIinterp\fR,
+ Tcl_Obj *\fIpathPtr\fR,
+ int \fInextCheckpoint\fR);
+.CE
+.SH "FILESYSTEM OPERATIONS"
+.PP
+The fields in this section of the structure contain addresses of
+functions which are called to carry out the basic filesystem
+operations. A filesystem which expects to be used with the complete
+standard Tcl command set must implement all of these. If some of
+them are not implemented, then certain Tcl commands may fail when
+operating on paths within that filesystem. However, in some instances
+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).
+.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
+.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
+.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 *\fBTcl_FSFilesystemPathTypeProc\fR(
+ Tcl_Obj *\fIpathPtr\fR);
+.CE
+.SS FILESYSTEMSEPARATORPROC
+.PP
+Function to return the separator character(s) for this filesystem.
+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 *\fBTcl_FSFilesystemSeparatorProc\fR(
+ Tcl_Obj *\fIpathPtr\fR);
+.CE
+.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
+upon it (e.g.\ \fBfile atime\fR, \fBfile isdirectory\fR, \fBfile size\fR,
+\fBglob\fR).
+.PP
+.CS
+typedef int \fBTcl_FSStatProc\fR(
+ Tcl_Obj *\fIpathPtr\fR,
+ Tcl_StatBuf *\fIstatPtr\fR);
+.CE
+.PP
+The \fBTcl_FSStatProc\fR fills the stat structure \fIstatPtr\fR with
+information about the specified file. You do not need any access
+rights to the file to get this information but you need search rights
+to all directories named in the path leading to the file. The stat
+structure includes info regarding device, inode (always 0 on Windows),
+privilege mode, nlink (always 1 on Windows), user id (always 0 on
+Windows), group id (always 0 on Windows), rdev (same as device on
+Windows), size, last access time, last modification time, and
+last metadata change time.
+.PP
+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.
+.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
+upon it (e.g.\ \fBfile exists\fR, \fBfile readable\fR).
+.PP
+.CS
+typedef int \fBTcl_FSAccessProc\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 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
+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
+(e.g.\ \fBopen\fR, \fBencoding\fR, and many Tk commands).
+.PP
+.CS
+typedef Tcl_Channel \fBTcl_FSOpenFileChannelProc\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
+\fIpathPtr\fR and returns a channel handle that can be used to perform
+input and output on the file. This API is modeled after the \fBfopen\fR
+procedure of the Unix standard I/O library. The syntax and meaning of
+all arguments is similar to those given in the Tcl \fBopen\fR command
+when opening a file, where the \fImode\fR argument is a combination of
+the POSIX flags O_RDONLY, O_WRONLY, etc. If an error occurs while
+opening the channel, the \fBTcl_FSOpenFileChannelProc\fR returns NULL and
+records a POSIX error code that can be retrieved with \fBTcl_GetErrno\fR.
+In addition, if \fIinterp\fR is non-NULL, the
+\fBTcl_FSOpenFileChannelProc\fR leaves an error message in \fIinterp\fR's
+result after any error.
+.PP
+The newly created channel must not be registered in the supplied interpreter
+by a \fBTcl_FSOpenFileChannelProc\fR; that task is up to the caller of
+\fBTcl_FSOpenFileChannel\fR (if necessary). If one of
+the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it
+as a replacement for the standard channel.
+.SS MATCHINDIRECTORYPROC
+.PP
+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 \fBencoding names\fR
+which use glob functionality internally).
+.PP
+.CS
+typedef int \fBTcl_FSMatchInDirectoryProc\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
+objects) which match the given pattern and accord with the \fItypes\fR
+specification given. There are two ways in which this function may be
+called. If \fIpattern\fR is NULL, then \fIpathPtr\fR is a full path
+specification of a single file or directory which should be checked for
+existence and correct type. Otherwise, \fIpathPtr\fR is a directory, the
+contents of which the function should search for files or directories
+which have the correct type. In either case, \fIpathPtr\fR can be
+assumed to be both non-NULL and non-empty. It is not currently
+documented whether \fIpathPtr\fR will have a file separator at its end of
+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, 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
+The \fBTcl_GlobTypeData\fR structure passed in the \fItypes\fR
+parameter contains the following fields:
+.PP
+.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;
+} \fBTcl_GlobTypeData\fR;
+.CE
+.PP
+There are two specific cases which it is important to handle correctly,
+both when \fItypes\fR is non-NULL. The two cases are when \fItypes->types
+& TCL_GLOB_TYPE_DIR\fR or \fItypes->types & TCL_GLOB_TYPE_MOUNT\fR are
+true (and in particular when the other flags are false). In the first of
+these cases, the function must list the contained directories. Tcl uses
+this to implement recursive globbing, so it is critical that filesystems
+implement directory matching correctly. In the second of these cases,
+with \fBTCL_GLOB_TYPE_MOUNT\fR, the filesystem must list the mount points
+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.
+.SS UTIMEPROC
+.PP
+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 \fBTcl_FSUtimeProc\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 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
+only if the filesystem supports links, and may otherwise be NULL.
+.PP
+.CS
+typedef Tcl_Obj *\fBTcl_FSLinkProc\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 (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 reference count manipulations on either end are needed). See
+the documentation for \fBTcl_FSLink\fR for the correct interpretation
+of the \fIlinkAction\fR flags.
+.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 \fBfile volumes\fR.
+.PP
+.CS
+typedef Tcl_Obj *\fBTcl_FSListVolumesProc\fR(void);
+.CE
+.PP
+The result should be a list of volumes added by this filesystem, or
+NULL (or an empty list) if no volumes are provided. The result object
+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
+.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
+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.
+.SS FILEATTRSTRINGSPROC
+.PP
+Function to list all attribute strings which are valid for this
+filesystem. If not implemented the filesystem will not support
+the \fBfile attributes\fR command. This allows arbitrary additional
+information to be attached to files in the filesystem. If it is
+not implemented, there is no need to implement the \fBget\fR and \fBset\fR
+methods.
+.PP
+.CS
+typedef const char *const *\fBTcl_FSFileAttrStringsProc\fR(
+ 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 \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
+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 \fBfile
+attributes\fR.
+.PP
+.CS
+typedef int \fBTcl_FSFileAttrsGetProc\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 \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 reference count to ensure it is properly freed.
+.SS FILEATTRSSETPROC
+.PP
+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 \fBTcl_FSFileAttrsSetProc\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.
+.SS CREATEDIRECTORYPROC
+.PP
+Function to process a \fBTcl_FSCreateDirectory\fR call. Should be
+implemented unless the FS is read-only.
+.PP
+.CS
+typedef int \fBTcl_FSCreateDirectoryProc\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.
+.SS REMOVEDIRECTORYPROC
+.PP
+Function to process a \fBTcl_FSRemoveDirectory\fR call. Should be
+implemented unless the FS is read-only.
+.PP
+.CS
+typedef int \fBTcl_FSRemoveDirectoryProc\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 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 \fBTcl_FSDeleteFileProc\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, the file specified by
+\fIpathPtr\fR should have been removed from the filesystem. Note that,
+if the filesystem supports symbolic links, Tcl will always call this
+function and not Tcl_FSRemoveDirectoryProc when needed to delete them
+(even if they are symbolic links to directories).
+.SH "FILESYSTEM EFFICIENCY"
+.PP
+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
+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 \fBTcl_FSLstatProc\fR(
+ Tcl_Obj *\fIpathPtr\fR,
+ Tcl_StatBuf *\fIstatPtr\fR);
+.CE
+.PP
+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
+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 \fBTcl_FSCopyFileProc\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 \fBfile
+copy\fR subcommand). Note that,
+if the filesystem supports symbolic links, Tcl will always call this
+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 \fBTcl_FSRenameFileProc\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. 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 \fBTcl_FSCopyDirectoryProc\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
+occurred in the copying process. If an error does occur, the name of
+the file or directory which caused the error should be placed in
+\fIerrorPtr\fR. Note that, \fIdestPathPtr\fR is the name of the
+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 \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 \fBTCL_ERROR\fR to disable load functionality in this filesystem
+entirely.
+.PP
+.CS
+typedef int \fBTcl_FSLoadFileProc\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 \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
+cleanup action required.
+.PP
+.CS
+typedef void \fBTcl_FSUnloadFileProc\fR(
+ Tcl_LoadHandle \fIloadHandle\fR);
+.CE
+.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 \fBgetcwd\fR is
+called before \fBchdir\fR. May be NULL.
+.PP
+.CS
+typedef Tcl_Obj *\fBTcl_FSGetCwdProc\fR(
+ Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+If the filesystem supports a native notion of a current working
+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 \fIinterp\fR's result.
+.SS CHDIRPROC
+.PP
+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 \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
+\fBTcl_FSGetCwd\fR.
+Real filesystems should carry out the correct action (i.e.\ call the
+correct system \fBchdir\fR API).
+.PP
+.CS
+typedef int \fBTcl_FSChdirProc\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), filename(n), load(n), open(n), pwd(n), source(n), unload(n)
+.SH KEYWORDS
+stat, access, filesystem, vfs, virtual filesystem
diff --git a/library/msgcat/doc/FindExec.3 b/library/msgcat/doc/FindExec.3
new file mode 100644
index 0000000..e4b4ed0
--- /dev/null
+++ b/library/msgcat/doc/FindExec.3
@@ -0,0 +1,63 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_FindExecutable 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_FindExecutable, Tcl_GetNameOfExecutable \- identify or return the name of the binary file containing the application
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_FindExecutable\fR(\fIargv0\fR)
+.sp
+const char *
+\fBTcl_GetNameOfExecutable\fR()
+.SH ARGUMENTS
+.AS char *argv0
+.AP char *argv0 in
+The first command-line argument to the program, which gives the
+application's name.
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBTcl_FindExecutable\fR procedure computes the full path name of
+the executable file from which the application was invoked and saves
+it for Tcl's internal use.
+The executable's path name is needed for several purposes in
+Tcl. For example, it is needed on some platforms in the
+implementation of the \fBload\fR command.
+It is also returned by the \fBinfo nameofexecutable\fR command.
+.PP
+On UNIX platforms this procedure is typically invoked as the very
+first thing in the application's main program; it must be passed
+\fIargv[0]\fR as its argument. It is important not to change the
+working directory before the invocation.
+\fBTcl_FindExecutable\fR uses \fIargv0\fR
+along with the \fBPATH\fR environment variable to find the
+application's executable, if possible. If it fails to find
+the binary, then future calls to \fBinfo nameofexecutable\fR
+will return an empty string.
+.PP
+On Windows platforms this procedure is typically invoked as the very
+first thing in the application's main program as well; Its \fIargv[0]\fR
+argument is only used to indicate whether the executable has a stderr
+channel (any non-null value) or not (the value null). If \fBTcl_SetPanicProc\fR
+is never called and no debugger is running, this determines whether
+the panic message is sent to stderr or to a standard system dialog.
+.PP
+\fBTcl_GetNameOfExecutable\fR simply returns a pointer to the
+internal full path name of the executable file as computed by
+\fBTcl_FindExecutable\fR. This procedure call is the C API
+equivalent to the \fBinfo nameofexecutable\fR command. NULL
+is returned if the internal full path name has not been
+computed or unknown.
+
+.SH KEYWORDS
+binary, executable file
diff --git a/library/msgcat/doc/GetCwd.3 b/library/msgcat/doc/GetCwd.3
new file mode 100755
index 0000000..964e237
--- /dev/null
+++ b/library/msgcat/doc/GetCwd.3
@@ -0,0 +1,52 @@
+'\"
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_GetCwd 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_GetCwd, Tcl_Chdir \- manipulate the current working directory
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+char *
+\fBTcl_GetCwd\fR(\fIinterp\fR, \fIbufferPtr\fR)
+.sp
+int
+\fBTcl_Chdir\fR(\fIpath\fR)
+.SH ARGUMENTS
+.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
+This dynamic string is used to store the current working directory.
+At the time of the call it should be uninitialized or free. The
+caller must eventually call \fBTcl_DStringFree\fR to free up
+anything stored here.
+.AP char *path in
+File path in UTF\-8 format.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures may be used to manipulate the current working
+directory for the application. They provide C\-level access to
+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 \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.
+.PP
+\fBTcl_Chdir\fR changes the applications current working directory to
+the value specified in \fIpath\fR. The format of the passed in string
+must be UTF\-8. The function returns -1 on error or 0 on success.
+
+.SH KEYWORDS
+pwd
diff --git a/library/msgcat/doc/GetHostName.3 b/library/msgcat/doc/GetHostName.3
new file mode 100644
index 0000000..28f3a4f
--- /dev/null
+++ b/library/msgcat/doc/GetHostName.3
@@ -0,0 +1,27 @@
+'\"
+'\" Copyright (c) 1998-2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.so man.macros
+.TH Tcl_GetHostName 3 8.3 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_GetHostName \- get the name of the local host
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+const char *
+\fBTcl_GetHostName\fR()
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_GetHostName\fR is a utility procedure used by some of the
+Tcl commands. It returns a pointer to a string containing the name
+for the current machine, or an empty string if the name cannot be
+determined. The string is statically allocated, and the caller must
+not modify of free it.
+.PP
+.SH KEYWORDS
+hostname
diff --git a/library/msgcat/doc/GetIndex.3 b/library/msgcat/doc/GetIndex.3
new file mode 100644
index 0000000..f60feb5
--- /dev/null
+++ b/library/msgcat/doc/GetIndex.3
@@ -0,0 +1,98 @@
+'\"
+'\" 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 Tcl_GetIndexFromObj 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_GetIndexFromObj, Tcl_GetIndexFromObjStruct \- lookup string in table of keywords
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_GetIndexFromObj\fR(\fIinterp, objPtr, tablePtr, msg, flags,
+indexPtr\fR)
+.sp
+int
+\fBTcl_GetIndexFromObjStruct\fR(\fIinterp, objPtr, structTablePtr, offset,
+ msg, flags, indexPtr\fR)
+.SH ARGUMENTS
+.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.
+.AP Tcl_Obj *objPtr in/out
+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 *const" *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\fR type.
+The first member of the structure must be a null-terminated string.
+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.
+.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
+OR-ed combination of bits providing additional information for
+operation. The only bit that is currently defined is \fBTCL_EXACT\fR.
+.AP int *indexPtr out
+The index of the string in \fItablePtr\fR that matches the value of
+\fIobjPtr\fR is returned here.
+.BE
+.SH DESCRIPTION
+.PP
+This procedure provides an efficient way for looking up keywords,
+switch names, option names, and similar things where the value of
+an object must be one of a predefined set of values.
+\fIObjPtr\fR is compared against each of
+the strings in \fItablePtr\fR to find a match. A match occurs if
+\fIobjPtr\fR's string value is identical to one of the strings in
+\fItablePtr\fR, or if it is a non-empty unique abbreviation
+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 \fBTCL_OK\fR is returned.
+.PP
+If there is no matching entry,
+\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
+.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
+the table and the index of the matching entry. If \fBTcl_GetIndexFromObj\fR
+is invoked again with the same \fIobjPtr\fR and \fItablePtr\fR
+arguments (e.g. during a reinvocation of a Tcl command), it returns
+the matching index immediately without having to redo the lookup
+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 \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 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.
+.SH "SEE ALSO"
+prefix(n), Tcl_WrongNumArgs(3)
+.SH KEYWORDS
+index, object, table lookup
diff --git a/library/msgcat/doc/GetInt.3 b/library/msgcat/doc/GetInt.3
new file mode 100644
index 0000000..f77d337
--- /dev/null
+++ b/library/msgcat/doc/GetInt.3
@@ -0,0 +1,86 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_GetInt 3 "" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_GetInt, Tcl_GetDouble, Tcl_GetBoolean \- convert from string to integer, double, or boolean
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_GetInt\fR(\fIinterp, src, intPtr\fR)
+.sp
+int
+\fBTcl_GetDouble\fR(\fIinterp, src, doublePtr\fR)
+.sp
+int
+\fBTcl_GetBoolean\fR(\fIinterp, src, boolPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *doublePtr out
+.AP Tcl_Interp *interp in
+Interpreter to use for error reporting.
+.AP "const char" *src in
+Textual value to be converted.
+.AP int *intPtr out
+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 \fIsrc\fR.
+.AP int *boolPtr out
+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 \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
+\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 \fIsrc\fR to consist of a collection
+of integer digits, optionally signed and optionally preceded by
+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 \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
+.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
+.QW e
+is present then it must be followed by the exponent number.
+.PP
+\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 \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.
+
+.SH KEYWORDS
+boolean, conversion, double, floating-point, integer
diff --git a/library/msgcat/doc/GetOpnFl.3 b/library/msgcat/doc/GetOpnFl.3
new file mode 100644
index 0000000..38aa976
--- /dev/null
+++ b/library/msgcat/doc/GetOpnFl.3
@@ -0,0 +1,58 @@
+'\"
+'\" Copyright (c) 1996-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 Tcl_GetOpenFile 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+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, chanID, write, checkUsage, filePtr\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_Interp checkUsage out
+.AP Tcl_Interp *interp in
+Tcl interpreter from which file handle is to be obtained.
+.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 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 \fIchanID\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_GetOpenFile\fR takes as argument a file identifier of the form
+returned by the \fBopen\fR command and
+returns at \fI*filePtr\fR a pointer to the FILE structure for
+the file.
+The \fIwrite\fR argument indicates whether the FILE pointer will
+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 \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.
+.PP
+Note that this interface is only supported on the Unix platform.
+
+.SH KEYWORDS
+channel, file handle, permissions, pipeline, read, write
diff --git a/library/msgcat/doc/GetStdChan.3 b/library/msgcat/doc/GetStdChan.3
new file mode 100644
index 0000000..e76ad66
--- /dev/null
+++ b/library/msgcat/doc/GetStdChan.3
@@ -0,0 +1,86 @@
+'\"
+'\" Copyright (c) 1996 by 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_GetStdChannel 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_GetStdChannel, Tcl_SetStdChannel \- procedures for retrieving and replacing the standard channels
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Channel
+\fBTcl_GetStdChannel\fR(\fItype\fR)
+.sp
+\fBTcl_SetStdChannel\fR(\fIchannel, type\fR)
+.sp
+.SH ARGUMENTS
+.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.
+.AP Tcl_Channel channel in
+The channel to use as the new value for the specified standard channel.
+.BE
+
+.SH DESCRIPTION
+.PP
+Tcl defines three special channels that are used by various I/O related
+commands if no other channels are specified. The standard input channel
+has a channel name of \fBstdin\fR and is used by \fBread\fR and \fBgets\fR.
+The standard output channel is named \fBstdout\fR and is used by
+\fBputs\fR. The standard error channel is named \fBstderr\fR and is used for
+reporting errors. In addition, the standard channels are inherited by any
+child processes created using \fBexec\fR or \fBopen\fR in the absence of any
+other redirections.
+.PP
+The standard channels are actually aliases for other normal channels. The
+current channel associated with a standard channel can be retrieved by calling
+\fBTcl_GetStdChannel\fR with one of
+\fBTCL_STDIN\fR, \fBTCL_STDOUT\fR, or \fBTCL_STDERR\fR as the \fItype\fR. The
+return value will be a valid channel, or NULL.
+.PP
+A new channel can be set for the standard channel specified by \fItype\fR
+by calling \fBTcl_SetStdChannel\fR with a new channel or NULL in the
+\fIchannel\fR argument. If the specified channel is closed by a later call to
+\fBTcl_Close\fR, then the corresponding standard channel will automatically be
+set to NULL.
+.PP
+If a non-NULL value for \fIchannel\fR is passed to \fBTcl_SetStdChannel\fR,
+then that same value should be passed to \fBTcl_RegisterChannel\fR, like so:
+.PP
+.CS
+Tcl_RegisterChannel(NULL, channel);
+.CE
+.PP
+This is a workaround for a misfeature in \fBTcl_SetStdChannel\fR that it
+fails to do some reference counting housekeeping. This misfeature cannot
+be corrected without contradicting the assumptions of some existing
+code that calls \fBTcl_SetStdChannel\fR.
+.PP
+If \fBTcl_GetStdChannel\fR is called before \fBTcl_SetStdChannel\fR, Tcl will
+construct a new channel to wrap the appropriate platform-specific standard
+file handle. If \fBTcl_SetStdChannel\fR is called before
+\fBTcl_GetStdChannel\fR, then the default channel will not be created.
+.PP
+If one of the standard channels is set to NULL, either by calling
+\fBTcl_SetStdChannel\fR with a NULL \fIchannel\fR argument, or by calling
+\fBTcl_Close\fR on the channel, then the next call to \fBTcl_CreateChannel\fR
+will automatically set the standard channel with the newly created channel. If
+more than one standard channel is NULL, then the standard channels will be
+assigned starting with standard input, followed by standard output, with
+standard error being last.
+.PP
+See \fBTcl_StandardChannels\fR for a general treatise about standard
+channels and the behavior of the Tcl library with regard to them.
+
+.SH "SEE ALSO"
+Tcl_Close(3), Tcl_CreateChannel(3), Tcl_Main(3), tclsh(1)
+
+.SH KEYWORDS
+standard channel, standard input, standard output, standard error
diff --git a/library/msgcat/doc/GetTime.3 b/library/msgcat/doc/GetTime.3
new file mode 100644
index 0000000..f4da364
--- /dev/null
+++ b/library/msgcat/doc/GetTime.3
@@ -0,0 +1,109 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_GetTime 3 8.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_GetTime, Tcl_SetTimeProc, Tcl_QueryTimeProc \- get date and time
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\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_GetTimeProc *getProc in
+.AP Tcl_Time *timePtr out
+Points to memory in which to store the date and time information.
+.AP Tcl_GetTimeProc getProc in
+Pointer to handler function replacing \fBTcl_GetTime\fR's access to the OS.
+.AP Tcl_ScaleTimeProc scaleProc in
+Pointer to handler function for the conversion of time delays in the
+virtual domain to real-time.
+.AP ClientData clientData in
+Value passed through to the two handler functions.
+.AP Tcl_GetTimeProc *getProcPtr out
+Pointer to place the currently registered get handler function into.
+.AP Tcl_ScaleTimeProc *scaleProcPtr out
+Pointer to place the currently registered scale handler function into.
+.AP ClientData *clientDataPtr out
+Pointer to place the currently registered pass-through value into.
+.BE
+.SH DESCRIPTION
+.PP
+The \fBTcl_GetTime\fR function retrieves the current time as a
+\fITcl_Time\fR structure in memory the caller provides. This
+structure has the following definition:
+.PP
+.CS
+typedef struct Tcl_Time {
+ long \fIsec\fR;
+ long \fIusec\fR;
+} \fBTcl_Time\fR;
+.CE
+.PP
+On return, the \fIsec\fR member of the structure is filled in with the
+number of seconds that have elapsed since the \fIepoch:\fR the epoch
+is the point in time of 00:00 UTC, 1 January 1970. This number does
+\fInot\fR count leap seconds \- an interval of one day advances it by
+86400 seconds regardless of whether a leap second has been inserted.
+.PP
+The \fIusec\fR member of the structure is filled in with the number of
+microseconds that have elapsed since the start of the second
+designated by \fIsec\fR. The Tcl library makes every effort to keep
+this number as precise as possible, subject to the limitations of the
+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.)
+.SS "VIRTUALIZED TIME"
+.PP
+The \fBTcl_SetTimeProc\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_QueryTimeProc\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
+The signatures of the handler functions are as follows:
+.PP
+.CS
+typedef void \fBTcl_GetTimeProc\fR(
+ Tcl_Time *\fItimebuf\fR,
+ ClientData \fIclientData\fR);
+typedef void \fBTcl_ScaleTimeProc\fR(
+ Tcl_Time *\fItimebuf\fR,
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fItimebuf\fR fields contain the time to manipulate, and the
+\fIclientData\fR fields contain a pointer supplied at the time the handler
+functions were registered.
+.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 behavior of the Tcl core
+with regard to this situation, i.e. the existing behavior is retained.
+.SH "SEE ALSO"
+clock(n)
+.SH KEYWORDS
+date, time
diff --git a/library/msgcat/doc/GetVersion.3 b/library/msgcat/doc/GetVersion.3
new file mode 100755
index 0000000..47034d0
--- /dev/null
+++ b/library/msgcat/doc/GetVersion.3
@@ -0,0 +1,48 @@
+'\"
+'\" Copyright (c) 1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_GetVersion 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_GetVersion \- get the version of the library at runtime
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.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
+Minor version number of the Tcl library.
+.AP int *patchLevel out
+The patch level of the Tcl library (or alpha or beta number).
+.AP Tcl_ReleaseType *type out
+The type of release, also indicates the type of patch level. Can be
+one of \fBTCL_ALPHA_RELEASE\fR, \fBTCL_BETA_RELEASE\fR, or
+\fBTCL_FINAL_RELEASE\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_GetVersion\fR should be used to query the version number
+of the Tcl library at runtime. This is useful when using a
+dynamically loaded Tcl library or when writing a stubs-aware
+extension. For instance, if you write an extension that is
+linked against the Tcl stubs library, it could be loaded into
+a program linked to an older version of Tcl than you expected.
+Use \fBTcl_GetVersion\fR to verify that fact, and possibly to
+change the behavior of your extension.
+.PP
+\fBTcl_GetVersion\fR accepts NULL for any of the arguments. For instance if
+you do not care about the \fIpatchLevel\fR of the library, pass
+a NULL for the \fIpatchLevel\fR argument.
+
+.SH KEYWORDS
+version, patchlevel, major, minor, alpha, beta, release
+
diff --git a/library/msgcat/doc/Hash.3 b/library/msgcat/doc/Hash.3
new file mode 100644
index 0000000..d8e3d2c
--- /dev/null
+++ b/library/msgcat/doc/Hash.3
@@ -0,0 +1,334 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_Hash 3 "" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_InitHashTable, Tcl_InitCustomHashTable, Tcl_InitObjHashTable, Tcl_DeleteHashTable, Tcl_CreateHashEntry, Tcl_DeleteHashEntry, Tcl_FindHashEntry, Tcl_GetHashValue, Tcl_SetHashValue, Tcl_GetHashKey, Tcl_FirstHashEntry, Tcl_NextHashEntry, Tcl_HashStats \- procedures to manage hash tables
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_InitHashTable\fR(\fItablePtr, keyType\fR)
+.sp
+\fBTcl_InitCustomHashTable\fR(\fItablePtr, keyType, typePtr\fR)
+.sp
+\fBTcl_InitObjHashTable\fR(\fItablePtr\fR)
+.sp
+\fBTcl_DeleteHashTable\fR(\fItablePtr\fR)
+.sp
+Tcl_HashEntry *
+\fBTcl_CreateHashEntry\fR(\fItablePtr, key, newPtr\fR)
+.sp
+\fBTcl_DeleteHashEntry\fR(\fIentryPtr\fR)
+.sp
+Tcl_HashEntry *
+\fBTcl_FindHashEntry\fR(\fItablePtr, key\fR)
+.sp
+ClientData
+\fBTcl_GetHashValue\fR(\fIentryPtr\fR)
+.sp
+\fBTcl_SetHashValue\fR(\fIentryPtr, value\fR)
+.sp
+void *
+\fBTcl_GetHashKey\fR(\fItablePtr, entryPtr\fR)
+.sp
+Tcl_HashEntry *
+\fBTcl_FirstHashEntry\fR(\fItablePtr, searchPtr\fR)
+.sp
+Tcl_HashEntry *
+\fBTcl_NextHashEntry\fR(\fIsearchPtr\fR)
+.sp
+char *
+\fBTcl_HashStats\fR(\fItablePtr\fR)
+.SH ARGUMENTS
+.AS "const 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
+\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 behavior of the hash table.
+.AP "const void" *key in
+Key to use for probe into table. Exact form depends on
+\fIkeyType\fR used to create table.
+.AP int *newPtr out
+The word at \fI*newPtr\fR is set to 1 if a new entry was created
+and 0 if there was already an entry for \fIkey\fR.
+.AP Tcl_HashEntry *entryPtr in
+Pointer to hash table entry.
+.AP ClientData value in
+New value to assign to hash table entry. Need not have type
+ClientData, but must fit in same space as ClientData.
+.AP Tcl_HashSearch *searchPtr in
+Pointer to record to use to keep track of progress in enumerating
+all the entries in a hash table.
+.BE
+.SH DESCRIPTION
+.PP
+A hash table consists of zero or more entries, each consisting of a
+key and a value. Given the key for an entry, the hashing routines can
+very quickly locate the entry, and hence its value. There may be at
+most one entry in a hash table with a particular key, but many entries
+may have the same value. Keys can take one of four forms: strings,
+one-word values, integer arrays, or custom keys defined by a
+Tcl_HashKeyType structure (See section \fBTHE TCL_HASHKEYTYPE 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
+.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.
+.PP
+Hash tables grow gracefully as the number of entries increases, so
+that there are always less than three entries per hash bucket, on
+average. This allows for fast lookups regardless of the number of
+entries in a table.
+.PP
+The core provides three functions for the initialization of hash
+tables, Tcl_InitHashTable, Tcl_InitObjHashTable and
+Tcl_InitCustomHashTable.
+.PP
+\fBTcl_InitHashTable\fR initializes a structure that describes a new
+hash table. The space for the structure is provided by the caller,
+not by the hash module. The value of \fIkeyType\fR indicates what
+kinds of keys will be used for all entries in the table. All of the
+key types described later are allowed, with the exception of
+\fBTCL_CUSTOM_TYPE_KEYS\fR and \fBTCL_CUSTOM_PTR_KEYS\fR.
+.PP
+\fBTcl_InitObjHashTable\fR is a wrapper around
+\fBTcl_InitCustomHashTable\fR and initializes a hash table whose keys
+are Tcl_Obj *.
+.PP
+\fBTcl_InitCustomHashTable\fR initializes a structure that describes a
+new hash table. The space for the structure is provided by the
+caller, not by the hash module. The value of \fIkeyType\fR indicates
+what kinds of keys will be used for all entries in the table.
+\fIKeyType\fR must have one of the following values:
+.IP \fBTCL_STRING_KEYS\fR 25
+Keys are null-terminated strings.
+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
+.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
+and comparison is determined by \fItypePtr\fR. The Tcl_HashKeyType
+structure is described in the section
+\fBTHE TCL_HASHKEYTYPE STRUCTURE\fR below.
+.IP \fBTCL_CUSTOM_PTR_KEYS\fR 25
+Keys are pointers to an arbitrary type, and are stored in the entry. Hashing
+and comparison is determined by \fItypePtr\fR. The Tcl_HashKeyType
+structure is described in the section
+\fBTHE TCL_HASHKEYTYPE STRUCTURE\fR below.
+.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
+.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.
+Array keys are passed into hashing functions using the address
+of the first int in the array.
+.PP
+\fBTcl_DeleteHashTable\fR deletes all of the entries in a hash
+table and frees up the memory associated with the table's
+bucket array and entries.
+It does not free the actual table structure (pointed to
+by \fItablePtr\fR), since that memory is assumed to be managed
+by the client.
+\fBTcl_DeleteHashTable\fR also does not free or otherwise
+manipulate the values of the hash table entries.
+If the entry values point to dynamically-allocated memory, then
+it is the client's responsibility to free these structures
+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
+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
+value and the value of the new entry will be set to zero.
+The return value from \fBTcl_CreateHashEntry\fR is a pointer to
+the entry, which may be used to retrieve and modify the entry's
+value or to delete the entry from the table.
+.PP
+\fBTcl_DeleteHashEntry\fR will remove an existing entry from a
+table.
+The memory associated with the entry itself will be freed, but
+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 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
+.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
+.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
+.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
+.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
+empty).
+Each subsequent call to \fBTcl_NextHashEntry\fR returns the
+next entry in the table or
+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 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
+entries it contains, the number of buckets in its hash array,
+and the utilization of the buckets.
+It is the caller's responsibility to free the result string
+by passing it to \fBckfree\fR.
+.PP
+The header file \fBtcl.h\fR defines the actual data structures
+used to implement hash tables.
+This is necessary so that clients can allocate Tcl_HashTable
+structures and so that macros can be used to read and write
+the values of entries.
+However, users of the hashing routines should never refer directly
+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 \fBTcl_HashKeyType\fR structure to describe the type, and
+calling \fBTcl_InitCustomHashTable\fR. The \fBTcl_HashKeyType\fR structure is
+defined as follows:
+.PP
+.CS
+typedef struct Tcl_HashKeyType {
+ int \fIversion\fR;
+ int \fIflags\fR;
+ Tcl_HashKeyProc *\fIhashKeyProc\fR;
+ Tcl_CompareHashKeysProc *\fIcompareKeysProc\fR;
+ Tcl_AllocHashEntryProc *\fIallocEntryProc\fR;
+ Tcl_FreeHashEntryProc *\fIfreeEntryProc\fR;
+} \fBTcl_HashKeyType\fR;
+.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.
+.PP
+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 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
+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.
+.PP
+The \fIhashKeyProc\fR member contains the address of a function called to
+calculate a hash value for the key.
+.PP
+.CS
+typedef unsigned int \fBTcl_HashKeyProc\fR(
+ Tcl_HashTable *\fItablePtr\fR,
+ void *\fIkeyPtr\fR);
+.CE
+.PP
+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.
+.PP
+.CS
+typedef int \fBTcl_CompareHashKeysProc\fR(
+ void *\fIkeyPtr\fR,
+ Tcl_HashEntry *\fIhPtr\fR);
+.CE
+.PP
+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 initialize the key and clientData.
+.PP
+.CS
+typedef Tcl_HashEntry *\fBTcl_AllocHashEntryProc\fR(
+ Tcl_HashTable *\fItablePtr\fR,
+ void *\fIkeyPtr\fR);
+.CE
+.PP
+If this is NULL then Tcl_Alloc is used to allocate enough space for a
+Tcl_HashEntry, the key pointer is assigned to key.oneWordValue and the
+clientData is set to NULL. String keys and array keys use this function to
+allocate enough space for the entry and the key in one block, rather than
+doing it in two blocks. This saves space for a pointer to the key from the
+entry and another memory allocation. Tcl_Obj* keys use this function to
+allocate enough space for an entry and increment the reference count on the
+object.
+.PP
+The \fIfreeEntryProc\fR member contains the address of a function called to
+free space for an entry.
+.PP
+.CS
+typedef void \fBTcl_FreeHashEntryProc\fR(
+ Tcl_HashEntry *\fIhPtr\fR);
+.CE
+.PP
+If this is NULL then Tcl_Free is used to free the space for the entry.
+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/library/msgcat/doc/Init.3 b/library/msgcat/doc/Init.3
new file mode 100644
index 0000000..f421479
--- /dev/null
+++ b/library/msgcat/doc/Init.3
@@ -0,0 +1,34 @@
+'\"
+'\" Copyright (c) 1998-2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.so man.macros
+.TH Tcl_Init 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Init \- find and source initialization script
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+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\fRs the
+\fBinit.tcl\fR script, which should exist somewhere on the Tcl library
+path.
+.PP
+\fBTcl_Init\fR is typically called from \fBTcl_AppInit\fR procedures.
+
+.SH "SEE ALSO"
+Tcl_AppInit, Tcl_Main
+
+.SH KEYWORDS
+application, initialization, interpreter
diff --git a/library/msgcat/doc/InitStubs.3 b/library/msgcat/doc/InitStubs.3
new file mode 100644
index 0000000..5f56278
--- /dev/null
+++ b/library/msgcat/doc/InitStubs.3
@@ -0,0 +1,89 @@
+'\"
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_InitStubs 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_InitStubs \- initialize the Tcl stubs mechanism
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+const char *
+\fBTcl_InitStubs\fR(\fIinterp, version, exact\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Tcl interpreter handle.
+.AP "const char" *version in
+A version string consisting of one or more decimal numbers
+separated by dots.
+.AP int exact in
+Non-zero means that only the particular version specified by
+\fIversion\fR is acceptable.
+Zero means that versions newer than \fIversion\fR are also
+acceptable as long as they have the same major version number
+as \fIversion\fR.
+.BE
+.SH INTRODUCTION
+.PP
+The Tcl stubs mechanism defines a way to dynamically bind
+extensions to a particular Tcl implementation at run time.
+This provides two significant benefits to Tcl users:
+.IP 1) 5
+Extensions that use the stubs mechanism can be loaded into
+multiple versions of Tcl without being recompiled or
+relinked.
+.IP 2) 5
+Extensions that use the stubs mechanism can be dynamically
+loaded into statically-linked Tcl applications.
+.PP
+The stubs mechanism accomplishes this by exporting function tables
+that define an interface to the Tcl API. The extension then accesses
+the Tcl API through offsets into the function table, so there are no
+direct references to any of the Tcl library's symbols. This
+redirection is transparent to the extension, so an extension writer
+can continue to use all public Tcl functions as documented.
+.PP
+The stubs mechanism requires no changes to applications incorporating
+Tcl interpreters. Only developers creating C-based Tcl extensions
+need to take steps to use the stubs mechanism with their extensions.
+.PP
+Enabling the stubs mechanism for an extension requires the following
+steps:
+.IP 1) 5
+Call \fBTcl_InitStubs\fR in the extension before calling any other
+Tcl functions.
+.IP 2) 5
+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. For example, to use the Tcl 8.1 ABI on Unix platforms,
+the library name is \fIlibtclstub8.1.a\fR; on Windows platforms, the
+library name is \fItclstub81.lib\fR.
+.PP
+If the extension also requires the Tk API, it must also call
+\fBTk_InitStubs\fR to initialize the Tk stubs interface and link
+with the Tk stubs libraries. See the \fBTk_InitStubs\fR page for
+more information.
+.SH DESCRIPTION
+\fBTcl_InitStubs\fR attempts to initialize the stub table pointers
+and ensure that the correct version of Tcl is loaded. In addition
+to an interpreter handle, it accepts as arguments a version number
+and a Boolean flag indicating whether the extension requires
+an exact version match or not. If \fIexact\fR is 0, then the
+extension is indicating that newer versions of Tcl are acceptable
+as long as they have the same major version number as \fIversion\fR;
+non-zero means that only the specified \fIversion\fR is acceptable.
+\fBTcl_InitStubs\fR returns a string containing the actual version
+of Tcl satisfying the request, or NULL if the Tcl version is not
+acceptable, does not support stubs, or any other error condition occurred.
+.SH "SEE ALSO"
+Tk_InitStubs
+.SH KEYWORDS
+stubs
diff --git a/library/msgcat/doc/IntObj.3 b/library/msgcat/doc/IntObj.3
new file mode 100644
index 0000000..cde96f8
--- /dev/null
+++ b/library/msgcat/doc/IntObj.3
@@ -0,0 +1,151 @@
+'\"
+'\" Copyright (c) 1996-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 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, Tcl_NewBignumObj, Tcl_SetBignumObj, Tcl_GetBignumFromObj, Tcl_TakeBignumFromObj \- manipulate Tcl objects as integer values
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewIntObj\fR(\fIintValue\fR)
+.sp
+Tcl_Obj *
+\fBTcl_NewLongObj\fR(\fIlongValue\fR)
+.sp
+Tcl_Obj *
+\fBTcl_NewWideIntObj\fR(\fIwideValue\fR)
+.sp
+\fBTcl_SetIntObj\fR(\fIobjPtr, intValue\fR)
+.sp
+\fBTcl_SetLongObj\fR(\fIobjPtr, longValue\fR)
+.sp
+\fBTcl_SetWideIntObj\fR(\fIobjPtr, wideValue\fR)
+.sp
+int
+\fBTcl_GetIntFromObj\fR(\fIinterp, objPtr, intPtr\fR)
+.sp
+int
+\fBTcl_GetLongFromObj\fR(\fIinterp, objPtr, longPtr\fR)
+.sp
+int
+\fBTcl_GetWideIntFromObj\fR(\fIinterp, objPtr, widePtr\fR)
+.sp
+.sp
+\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)
+.SH ARGUMENTS
+.AS Tcl_WideInt doubleValue in/out
+.AP int intValue in
+Integer value used to initialize or set a Tcl object.
+.AP long longValue in
+Long integer value used to initialize or set a Tcl object.
+.AP Tcl_WideInt wideValue in
+Wide integer value used to initialize or set a Tcl object.
+.AP Tcl_Obj *objPtr in/out
+For \fBTcl_SetIntObj\fR, \fBTcl_SetLongObj\fR, \fBTcl_SetWideIntObj\fR,
+and \fBTcl_SetBignumObj\fR, this points to the object in which to store an
+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
+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 retrieved from \fIobjPtr\fR.
+.AP long *longPtr out
+Points to place to store the long integer value retrieved from \fIobjPtr\fR.
+.AP Tcl_WideInt *widePtr out
+Points to place to store the wide integer value retrieved from \fIobjPtr\fR.
+.AP mp_int *bigValue in/out
+Points to a multi-precision integer structure declared by the LibTomMath
+library.
+.AP double doubleValue in
+Double value from which the integer part is determined and
+used to initialize a multi-precision integer value.
+.BE
+.SH DESCRIPTION
+.PP
+These procedures are used to create, modify, and read Tcl objects
+that hold integral values.
+.PP
+The different routines exist to accommodate different integral types in C
+with which values might be exchanged. The C integral types for which Tcl
+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.
+.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/library/msgcat/doc/Interp.3 b/library/msgcat/doc/Interp.3
new file mode 100644
index 0000000..d908057
--- /dev/null
+++ b/library/msgcat/doc/Interp.3
@@ -0,0 +1,134 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_Interp 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Interp \- client-visible fields of interpreter structures
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+typedef struct {
+ char *\fIresult\fR;
+ Tcl_FreeProc *\fIfreeProc\fR;
+ int \fIerrorLine\fR;
+} \fBTcl_Interp\fR;
+
+typedef void \fBTcl_FreeProc\fR(
+ char *\fIblockPtr\fR);
+.BE
+.SH DESCRIPTION
+.PP
+The \fBTcl_CreateInterp\fR procedure returns a pointer to a Tcl_Interp
+structure. Callers of \fBTcl_CreateInterp\fR should use this pointer
+as an opaque token, suitable for nothing other than passing back to
+other routines in the Tcl interface. Accessing fields directly through
+the pointer as described below is no longer supported. The supported
+public routines \fBTcl_SetResult\fR, \fBTcl_GetResult\fR,
+\fBTcl_SetErrorLine\fR, \fBTcl_GetErrorLine\fR must be used instead.
+.PP
+For legacy programs and extensions no longer being maintained, compiles
+against the Tcl 8.6 header files are only possible with the compiler
+directives
+.CS
+#define USE_INTERP_RESULT
+.CE
+and/or
+.CS
+#define USE_INTERP_ERRORLINE
+.CE
+depending on which fields of the \fBTcl_Interp\fR struct are accessed.
+These directives may be embedded in code or supplied via compiler options.
+.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 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
+will hide all the details of managing the fields.
+The description below is for those procedures that manipulate the
+fields directly.
+.PP
+Whenever a command procedure returns, it must ensure
+that the \fIresult\fR field of its interpreter points to the string
+being returned by the command.
+The \fIresult\fR field must always point to a valid string.
+If a command wishes to return no result then \fIinterp->result\fR
+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.
+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)
+and store a pointer to it in \fIinterp->result\fR.
+In this case, the command procedure must also set \fIinterp->freeProc\fR
+to the address of a procedure that can free the value, or \fBTCL_DYNAMIC\fR
+if the storage was allocated directly by Tcl or by a call to
+\fBTcl_Alloc\fR.
+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.
+If a client procedure overwrites \fIinterp->result\fR when
+\fIinterp->freeProc\fR is non-zero, then it is responsible for calling
+\fIfreeProc\fR to free the old \fIinterp->result\fR (the \fBTcl_FreeResult\fR
+macro should be used for this purpose).
+.PP
+\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.
+In most applications \fBTCL_DYNAMIC\fR is the only non-zero value ever
+used for \fIfreeProc\fR.
+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.
+.PP
+As part of processing each command, \fBTcl_Eval\fR initializes
+\fIinterp->result\fR
+and \fIinterp->freeProc\fR just before calling the command procedure for
+the command. The \fIfreeProc\fR field will be initialized to zero,
+and \fIinterp->result\fR will point to an empty string. Commands that
+do not return any value can simply leave the fields alone.
+Furthermore, the empty string pointed to by \fIresult\fR is actually
+part of an array of \fBTCL_RESULT_SIZE\fR characters (approximately 200).
+If a command wishes to return a short string, it can simply copy
+it to the area pointed to by \fIinterp->result\fR. Or, it can use
+the sprintf procedure to generate a short result string at the location
+pointed to by \fIinterp->result\fR.
+.PP
+It is a general convention in Tcl-based applications that the result
+of an interpreter is normally in the initialized state described
+in the previous paragraph.
+Procedures that manipulate an interpreter's result (e.g. by
+returning an error) will generally assume that the result
+has been initialized when the procedure is called.
+If such a procedure is to be called after the result has been
+changed, then \fBTcl_ResetResult\fR should be called first to
+reset the result to its initialized state. The direct use of
+\fIinterp->result\fR is strongly deprecated (see \fBTcl_SetResult\fR).
+.PP
+The \fIerrorLine\fR
+field is valid only after \fBTcl_Eval\fR returns
+a \fBTCL_ERROR\fR return code. In this situation the \fIerrorLine\fR
+field identifies the line number of the command being executed when
+the error occurred. The line numbers are relative to the command
+being executed: 1 means the first line of the command passed to
+\fBTcl_Eval\fR, 2 means the second line, and so on.
+The \fIerrorLine\fR field is typically used in conjunction with
+\fBTcl_AddErrorInfo\fR to report information about where an error
+occurred.
+\fIErrorLine\fR should not normally be modified except by \fBTcl_Eval\fR.
+
+.SH KEYWORDS
+free, initialized, interpreter, malloc, result
diff --git a/library/msgcat/doc/Limit.3 b/library/msgcat/doc/Limit.3
new file mode 100644
index 0000000..2941ee8
--- /dev/null
+++ b/library/msgcat/doc/Limit.3
@@ -0,0 +1,192 @@
+'\"
+'\" 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 \fBTcl_LimitHandlerProc\fR(
+ 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 \fBTcl_LimitHandlerDeleteProc\fR(
+ 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/library/msgcat/doc/LinkVar.3 b/library/msgcat/doc/LinkVar.3
new file mode 100644
index 0000000..dc71a45
--- /dev/null
+++ b/library/msgcat/doc/LinkVar.3
@@ -0,0 +1,207 @@
+'\"
+'\" 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 Tcl_LinkVar 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_LinkVar, Tcl_UnlinkVar, Tcl_UpdateLinkedVar \- link Tcl variable to C variable
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_LinkVar\fR(\fIinterp, varName, addr, type\fR)
+.sp
+\fBTcl_UnlinkVar\fR(\fIinterp, varName\fR)
+.sp
+\fBTcl_UpdateLinkedVar\fR(\fIinterp, varName\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp writable
+.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 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 \fBTCL_LINK_INT\fR,
+\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, \fBTCL_LINK_WIDE_INT\fR,
+\fBTCL_LINK_WIDE_UINT\fR, \fBTCL_LINK_FLOAT\fR,
+\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
+.PP
+\fBTcl_LinkVar\fR uses variable traces to keep the Tcl variable
+named by \fIvarName\fR in sync with the C variable at the address
+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 \fBTCL_OK\fR; if an error occurs
+while setting up the link (e.g. because \fIvarName\fR is the
+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
+\fBTCL_LINK_READ_ONLY\fR:
+.TP
+\fBTCL_LINK_INT\fR
+The C variable is of type \fBint\fR.
+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.
+.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.
+.TP
+\fBTCL_LINK_DOUBLE\fR
+The C variable is of type \fBdouble\fR.
+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.
+.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.
+.TP
+\fBTCL_LINK_WIDE_INT\fR
+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.
+.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.
+.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
+.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
+form acceptable to \fBTcl_GetBooleanFromObj\fR; attempts to write
+non-boolean values into \fIvarName\fR will be rejected with
+Tcl errors.
+.TP
+\fBTCL_LINK_STRING\fR
+The C variable is of type \fBchar *\fR.
+If its value is not NULL then it must be a pointer to a string
+allocated with \fBTcl_Alloc\fR or \fBckalloc\fR.
+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
+.QW NULL .
+.PP
+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.
+.PP
+\fBTcl_UnlinkVar\fR removes the link previously set up for the
+variable given by \fIvarName\fR. If there does not exist a link
+for \fIvarName\fR then the procedure has no effect.
+.PP
+\fBTcl_UpdateLinkedVar\fR may be invoked after the C variable has
+changed to force the Tcl variable to be updated immediately.
+In many cases this procedure is not needed, since any attempt to
+read the Tcl variable will return the latest value of the C variable.
+However, if a trace has been set on the Tcl variable (such as a
+Tk widget that wishes to display the value of the variable), the
+trace will not trigger when the C variable has changed.
+\fBTcl_UpdateLinkedVar\fR ensures that any traces on the Tcl
+variable are invoked.
+.PP
+Note that, as with any call to a Tcl interpreter, \fBTcl_UpdateLinkedVar\fR
+must be called from the same thread that created the interpreter. The safest
+mechanism is to ensure that the C variable is only ever updated from the same
+thread that created the interpreter (possibly in response to an event posted
+with \fBTcl_ThreadQueueEvent\fR), but when it is necessary to update the
+variable in a separate thread, it is advised that \fBTcl_AsyncMark\fR be used
+to indicate to the thread hosting the interpreter that it is ready to run
+\fBTcl_UpdateLinkedVar\fR.
+.SH "SEE ALSO"
+Tcl_TraceVar(3)
+.SH KEYWORDS
+boolean, integer, link, read-only, real, string, trace, variable
diff --git a/library/msgcat/doc/ListObj.3 b/library/msgcat/doc/ListObj.3
new file mode 100644
index 0000000..b93e52b
--- /dev/null
+++ b/library/msgcat/doc/ListObj.3
@@ -0,0 +1,250 @@
+'\"
+'\" Copyright (c) 1996-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 Tcl_ListObj 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_ListObjAppendList, Tcl_ListObjAppendElement, Tcl_NewListObj, Tcl_SetListObj, Tcl_ListObjGetElements, Tcl_ListObjLength, Tcl_ListObjIndex, Tcl_ListObjReplace \- manipulate Tcl objects as lists
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_ListObjAppendList\fR(\fIinterp, listPtr, elemListPtr\fR)
+.sp
+int
+\fBTcl_ListObjAppendElement\fR(\fIinterp, listPtr, objPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_NewListObj\fR(\fIobjc, objv\fR)
+.sp
+\fBTcl_SetListObj\fR(\fIobjPtr, objc, objv\fR)
+.sp
+int
+\fBTcl_ListObjGetElements\fR(\fIinterp, listPtr, objcPtr, objvPtr\fR)
+.sp
+int
+\fBTcl_ListObjLength\fR(\fIinterp, listPtr, intPtr\fR)
+.sp
+int
+\fBTcl_ListObjIndex\fR(\fIinterp, listPtr, index, objPtrPtr\fR)
+.sp
+int
+\fBTcl_ListObjReplace\fR(\fIinterp, listPtr, first, count, objc, objv\fR)
+.SH ARGUMENTS
+.AS "Tcl_Obj *const" *elemListPtr in/out
+.AP Tcl_Interp *interp in
+If an error occurs while converting an object to be a list object,
+an error message is left in the interpreter's result object
+unless \fIinterp\fR is NULL.
+.AP Tcl_Obj *listPtr in/out
+Points to the list object to be manipulated.
+If \fIlistPtr\fR does not already point to a list object,
+an attempt will be made to convert it to one.
+.AP Tcl_Obj *elemListPtr in/out
+For \fBTcl_ListObjAppendList\fR, this points to a list object
+containing elements to be appended onto \fIlistPtr\fR.
+Each element of *\fIelemListPtr\fR will
+become a new element of \fIlistPtr\fR.
+If *\fIelemListPtr\fR is not NULL and
+does not already point to a list object,
+an attempt will be made to convert it to one.
+.AP Tcl_Obj *objPtr in
+For \fBTcl_ListObjAppendElement\fR,
+points to the Tcl object that will be appended to \fIlistPtr\fR.
+For \fBTcl_SetListObj\fR,
+this points to the Tcl object that will be converted to a list object
+containing the \fIobjc\fR elements of the array referenced by \fIobjv\fR.
+.AP int *objcPtr in
+Points to location where \fBTcl_ListObjGetElements\fR
+stores the number of element objects in \fIlistPtr\fR.
+.AP Tcl_Obj ***objvPtr out
+A location where \fBTcl_ListObjGetElements\fR stores a pointer to an array
+of pointers to the element objects of \fIlistPtr\fR.
+.AP int objc in
+The number of Tcl objects that \fBTcl_NewListObj\fR
+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.
+.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.
+.AP int *intPtr out
+Points to location where \fBTcl_ListObjLength\fR
+stores the length of the list.
+.AP int index in
+Index of the list element that \fBTcl_ListObjIndex\fR
+is to return.
+The first element has index 0.
+.AP Tcl_Obj **objPtrPtr out
+Points to place where \fBTcl_ListObjIndex\fR is to store
+a pointer to the resulting list element object.
+.AP int first in
+Index of the starting list element that \fBTcl_ListObjReplace\fR
+is to replace.
+The list's first element has index 0.
+.AP int count in
+The number of elements that \fBTcl_ListObjReplace\fR
+is to replace.
+.BE
+
+.SH DESCRIPTION
+.PP
+Tcl list objects have an internal representation that supports
+the efficient indexing and appending.
+The procedures described in this man page are used to
+create, modify, index, and append to Tcl list objects from C code.
+.PP
+\fBTcl_ListObjAppendList\fR and \fBTcl_ListObjAppendElement\fR
+both add one or more objects
+to the end of the list object referenced by \fIlistPtr\fR.
+\fBTcl_ListObjAppendList\fR appends each element of the list object
+referenced by \fIelemListPtr\fR while
+\fBTcl_ListObjAppendElement\fR appends the single object
+referenced by \fIobjPtr\fR.
+Both procedures will convert the object referenced by \fIlistPtr\fR
+to a list object if necessary.
+If an error occurs during conversion,
+both procedures return \fBTCL_ERROR\fR and leave an error message
+in the interpreter's result object if \fIinterp\fR is not NULL.
+Similarly, if \fIelemListPtr\fR does not already refer to a list object,
+\fBTcl_ListObjAppendList\fR will attempt to convert it to one
+and if an error occurs during conversion,
+will return \fBTCL_ERROR\fR
+and leave an error message in the interpreter's result object
+if interp is not NULL.
+Both procedures invalidate any old string representation of \fIlistPtr\fR
+and, if it was converted to a list object,
+free any old internal representation.
+Similarly, \fBTcl_ListObjAppendList\fR frees any old internal representation
+of \fIelemListPtr\fR if it converts it to a list object.
+After appending each element in \fIelemListPtr\fR,
+\fBTcl_ListObjAppendList\fR increments the element's reference count
+since \fIlistPtr\fR now also refers to it.
+For the same reason, \fBTcl_ListObjAppendElement\fR
+increments \fIobjPtr\fR's reference count.
+If no error occurs,
+the two procedures return \fBTCL_OK\fR after appending the objects.
+.PP
+\fBTcl_NewListObj\fR and \fBTcl_SetListObj\fR
+create a new object or modify an existing object to hold
+the \fIobjc\fR elements of the array referenced by \fIobjv\fR
+where each element is a pointer to a Tcl object.
+If \fIobjc\fR is less than or equal to zero,
+they return an empty object.
+The new object's string representation is left invalid.
+The two procedures increment the reference counts
+of the elements in \fIobjc\fR since the list object now refers to them.
+The new list object returned by \fBTcl_NewListObj\fR
+has reference count zero.
+.PP
+\fBTcl_ListObjGetElements\fR returns a count and a pointer to an array of
+the elements in a list object. It returns the count by storing it in the
+address \fIobjcPtr\fR. Similarly, it returns the array pointer by storing
+it in the address \fIobjvPtr\fR.
+The memory pointed to is managed by Tcl and should not be freed or written
+to by the caller. If the list is empty, 0 is stored at \fIobjcPtr\fR
+and NULL at \fIobjvPtr\fR.
+If \fIlistPtr\fR is not already a list object, \fBTcl_ListObjGetElements\fR
+will attempt to convert it to one; if the conversion fails, it returns
+\fBTCL_ERROR\fR and leaves an error message in the interpreter's result
+object if \fIinterp\fR is not NULL.
+Otherwise it returns \fBTCL_OK\fR after storing the count and array pointer.
+.PP
+\fBTcl_ListObjLength\fR returns the number of elements in the list object
+referenced by \fIlistPtr\fR.
+It returns this count by storing an integer in the address \fIintPtr\fR.
+If the object is not already a list object,
+\fBTcl_ListObjLength\fR will attempt to convert it to one;
+if the conversion fails, it returns \fBTCL_ERROR\fR
+and leaves an error message in the interpreter's result object
+if \fIinterp\fR is not NULL.
+Otherwise it returns \fBTCL_OK\fR after storing the list's length.
+.PP
+The procedure \fBTcl_ListObjIndex\fR returns a pointer to the object
+at element \fIindex\fR in the list referenced by \fIlistPtr\fR.
+It returns this object by storing a pointer to it
+in the address \fIobjPtrPtr\fR.
+If \fIlistPtr\fR does not already refer to a list object,
+\fBTcl_ListObjIndex\fR will attempt to convert it to one;
+if the conversion fails, it returns \fBTCL_ERROR\fR
+and leaves an error message in the interpreter's result object
+if \fIinterp\fR is not NULL.
+If the index is out of range,
+that is, \fIindex\fR is negative or
+greater than or equal to the number of elements in the list,
+\fBTcl_ListObjIndex\fR stores a NULL in \fIobjPtrPtr\fR
+and returns \fBTCL_OK\fR.
+Otherwise it returns \fBTCL_OK\fR after storing the element's
+object pointer.
+The reference count for the list element is not incremented;
+the caller must do that if it needs to retain a pointer to the element.
+.PP
+\fBTcl_ListObjReplace\fR replaces zero or more elements
+of the list referenced by \fIlistPtr\fR
+with the \fIobjc\fR objects in the array referenced by \fIobjv\fR.
+If \fIlistPtr\fR does not point to a list object,
+\fBTcl_ListObjReplace\fR will attempt to convert it to one;
+if the conversion fails, it returns \fBTCL_ERROR\fR
+and leaves an error message in the interpreter's result object
+if \fIinterp\fR is not NULL.
+Otherwise, it returns \fBTCL_OK\fR after replacing the objects.
+If \fIobjv\fR is NULL, no new elements are added.
+If the argument \fIfirst\fR is zero or negative,
+it refers to the first element.
+If \fIfirst\fR is greater than or equal to the
+number of elements in the list, then no elements are deleted;
+the new elements are appended to the list.
+\fIcount\fR gives the number of elements to replace.
+If \fIcount\fR is zero or negative then no elements are deleted;
+the new elements are simply inserted before the one
+designated by \fIfirst\fR.
+\fBTcl_ListObjReplace\fR invalidates \fIlistPtr\fR's
+old string representation.
+The reference counts of any elements inserted from \fIobjv\fR
+are incremented since the resulting list now refers to them.
+Similarly, the reference counts for any replaced objects are decremented.
+.PP
+Because \fBTcl_ListObjReplace\fR combines
+both element insertion and deletion,
+it can be used to implement a number of list operations.
+For example, the following code inserts the \fIobjc\fR objects
+referenced by the array of object pointers \fIobjv\fR
+just before the element \fIindex\fR of the list referenced by \fIlistPtr\fR:
+.PP
+.CS
+result = \fBTcl_ListObjReplace\fR(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 = \fBTcl_ListObjLength\fR(interp, listPtr, &length);
+if (result == TCL_OK) {
+ result = \fBTcl_ListObjReplace\fR(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 = \fBTcl_ListObjReplace\fR(interp, listPtr, first, count,
+ 0, NULL);
+.CE
+.SH "SEE ALSO"
+Tcl_NewObj(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3), Tcl_GetObjResult(3)
+.SH KEYWORDS
+append, index, insert, internal representation, length, list, list object, list type, object, object type, replace, string representation
diff --git a/library/msgcat/doc/Load.3 b/library/msgcat/doc/Load.3
new file mode 100644
index 0000000..c088f32
--- /dev/null
+++ b/library/msgcat/doc/Load.3
@@ -0,0 +1,69 @@
+'\"
+'\" Copyright (c) 2009-2010 Kevin B. Kenny
+'\" Copyright (c) 2010 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 Load 3 8.6 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_LoadFile, Tcl_FindSymbol \- platform-independent dynamic library loading
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_LoadFile\fR(\fIinterp, pathPtr, symbols, flags, procPtrs, loadHandlePtr\fR)
+.sp
+void *
+\fBTcl_FindSymbol\fR(\fIinterp, loadHandle, symbol\fR)
+.SH ARGUMENTS
+.AS Tcl_LoadHandle loadHandle in
+.AP Tcl_Interp *interp in
+Interpreter to use for reporting error messages.
+.AP Tcl_Obj *pathPtr in
+The name of the file to load. If it is a single name, the library search path
+of the current environment will be used to resolve it.
+.AP "const char *const" symbols[] in
+Array of names of symbols to be resolved during the load of the library, or
+NULL if no symbols are to be resolved. If an array is given, the last entry in
+the array must be NULL.
+.AP int flags in
+Reserved for future expansion. Must be 0.
+.AP void *procPtrs out
+Points to an array that will hold the addresses of the functions described in
+the \fIsymbols\fR argument. Should be NULL if no symbols are to be resolved.
+.AP Tcl_LoadHandle *loadHandlePtr out
+Points to a variable that will hold the handle to the abstract token
+describing the library that has been loaded.
+.AP Tcl_LoadHandle loadHandle in
+Abstract token describing the library to look up a symbol in.
+.AP "const char" *symbol in
+The name of the symbol to look up.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_LoadFile\fR loads a file from the filesystem (including potentially any
+virtual filesystem that has been installed) and provides a handle to it that
+may be used in further operations. The \fIsymbols\fR array, if non-NULL,
+supplies a set of names of symbols (typically functions) that must be resolved
+from the library and which will be stored in the array indicated by
+\fIprocPtrs\fR. If any of the symbols is not resolved, the loading of the file
+will fail with an error message left in the interpreter (if that is non-NULL).
+The result of \fBTcl_LoadFile\fR is a standard Tcl error code. The library may
+be unloaded with \fBTcl_FSUnloadFile\fR.
+.PP
+\fBTcl_FindSymbol\fR locates a symbol in a loaded library and returns it. If
+the symbol cannot be found, it returns NULL and sets an error message in the
+given \fIinterp\fR (if that is non-NULL). Note that it is unsafe to use this
+operation on a handle that has been passed to \fBTcl_FSUnloadFile\fR.
+.SH "SEE ALSO"
+Tcl_FSLoadFile(3), Tcl_FSUnloadFile(3), load(n), unload(n)
+.SH KEYWORDS
+binary code, loading, shared library
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/library/msgcat/doc/Method.3 b/library/msgcat/doc/Method.3
new file mode 100644
index 0000000..43b3609
--- /dev/null
+++ b/library/msgcat/doc/Method.3
@@ -0,0 +1,248 @@
+'\"
+'\" Copyright (c) 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 Tcl_Method 3 0.1 TclOO "TclOO Library Functions"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_ClassSetConstructor, Tcl_ClassSetDestructor, Tcl_MethodDeclarerClass, Tcl_MethodDeclarerObject, Tcl_MethodIsPublic, Tcl_MethodIsType, Tcl_MethodName, Tcl_NewInstanceMethod, Tcl_NewMethod, Tcl_ObjectContextInvokeNext, Tcl_ObjectContextIsFiltering, Tcl_ObjectContextMethod, Tcl_ObjectContextObject, Tcl_ObjectContextSkippedArgs \- manipulate methods and method-call contexts
+.SH SYNOPSIS
+.nf
+\fB#include <tclOO.h>\fR
+.sp
+Tcl_Method
+\fBTcl_NewMethod\fR(\fIinterp, class, nameObj, isPublic,
+ methodTypePtr, clientData\fR)
+.sp
+Tcl_Method
+\fBTcl_NewInstanceMethod\fR(\fIinterp, object, nameObj, isPublic,
+ methodTypePtr, clientData\fR)
+.sp
+\fBTcl_ClassSetConstructor\fR(\fIinterp, class, method\fR)
+.sp
+\fBTcl_ClassSetDestructor\fR(\fIinterp, class, method\fR)
+.sp
+Tcl_Class
+\fBTcl_MethodDeclarerClass\fR(\fImethod\fR)
+.sp
+Tcl_Object
+\fBTcl_MethodDeclarerObject\fR(\fImethod\fR)
+.sp
+Tcl_Obj *
+\fBTcl_MethodName\fR(\fImethod\fR)
+.sp
+int
+\fBTcl_MethodIsPublic\fR(\fImethod\fR)
+.sp
+int
+\fBTcl_MethodIsType\fR(\fImethod, methodTypePtr, clientDataPtr\fR)
+.sp
+int
+\fBTcl_ObjectContextInvokeNext\fR(\fIinterp, context, objc, objv, skip\fR)
+.sp
+int
+\fBTcl_ObjectContextIsFiltering\fR(\fIcontext\fR)
+.sp
+Tcl_Method
+\fBTcl_ObjectContextMethod\fR(\fIcontext\fR)
+.sp
+Tcl_Object
+\fBTcl_ObjectContextObject\fR(\fIcontext\fR)
+.sp
+int
+\fBTcl_ObjectContextSkippedArgs\fR(\fIcontext\fR)
+.SH ARGUMENTS
+.AS ClientData clientData in
+.AP Tcl_Interp *interp in/out
+The interpreter holding the object or class to create or update a method in.
+.AP Tcl_Object object in
+The object to create the method in.
+.AP Tcl_Class class in
+The class to create the method in.
+.AP Tcl_Obj *nameObj in
+The name of the method to create. Should not be NULL unless creating
+constructors or destructors.
+.AP int isPublic in
+A boolean flag saying whether the method is to be exported.
+.AP Tcl_MethodType *methodTypePtr in
+A description of the type of the method to create, or the type of method to
+compare against.
+.AP ClientData clientData in
+A piece of data that is passed to the implementation of the method without
+interpretation.
+.AP ClientData *clientDataPtr out
+A pointer to a variable in which to write the \fIclientData\fR value supplied
+when the method was created. If NULL, the \fIclientData\fR value will not be
+retrieved.
+.AP Tcl_Method method in
+A reference to a method to query.
+.AP Tcl_ObjectContext context in
+A reference to a method-call context. Note that client code \fImust not\fR
+retain a reference to a context.
+.AP int objc in
+The number of arguments to pass to the method implementation.
+.AP "Tcl_Obj *const" *objv in
+An array of arguments to pass to the method implementation.
+.AP int skip in
+The number of arguments passed to the method implementation that do not
+represent "real" arguments.
+.BE
+.SH DESCRIPTION
+.PP
+A method is an operation carried out on an object that is associated with the
+object. Every method must be attached to either an object or a class; methods
+attached to a class are associated with all instances (direct and indirect) of
+that class.
+.PP
+Given a method, the entity that declared it can be found using
+\fBTcl_MethodDeclarerClass\fR which returns the class that the method is
+attached to (or NULL if the method is not attached to any class) and
+\fBTcl_MethodDeclarerObject\fR which returns the object that the method is
+attached to (or NULL if the method is not attached to an object). The name of
+the method can be retrieved with \fBTcl_MethodName\fR and whether the method
+is exported is retrieved with \fBTcl_MethodIsPublic\fR. The type of the method
+can also be introspected upon to a limited degree; the function
+\fBTcl_MethodIsType\fR returns whether a method is of a particular type,
+assigning the per-method \fIclientData\fR to the variable pointed to by
+\fIclientDataPtr\fR if (that is non-NULL) if the type is matched.
+.SS "METHOD CREATION"
+.PP
+Methods are created by \fBTcl_NewMethod\fR and \fBTcl_NewInstanceMethod\fR,
+which
+create a method attached to a class or an object respectively. In both cases,
+the \fInameObj\fR argument gives the name of the method to create, the
+\fIisPublic\fR argument states whether the method should be exported
+initially, the \fImethodTypePtr\fR argument describes the implementation of
+the method (see the \fBMETHOD TYPES\fR section below) and the \fIclientData\fR
+argument gives some implementation-specific data that is passed on to the
+implementation of the method when it is called.
+.PP
+When the \fInameObj\fR argument to \fBTcl_NewMethod\fR is NULL, an
+unnamed method is created, which is used for constructors and destructors.
+Constructors should be installed into their class using the
+\fBTcl_ClassSetConstructor\fR function, and destructors (which must not
+require any arguments) should be installed into their class using the
+\fBTcl_ClassSetDestructor\fR function. Unnamed methods should not be used for
+any other purpose, and named methods should not be used as either constructors
+or destructors. Also note that a NULL \fImethodTypePtr\fR is used to provide
+internal signaling, and should not be used in client code.
+.SS "METHOD CALL CONTEXTS"
+.PP
+When a method is called, a method-call context reference is passed in as one
+of the arguments to the implementation function. This context can be inspected
+to provide information about the caller, but should not be retained beyond the
+moment when the method call terminates.
+.PP
+The method that is being called can be retrieved from the context by using
+\fBTcl_ObjectContextMethod\fR, and the object that caused the method to be
+invoked can be retrieved with \fBTcl_ObjectContextObject\fR. The number of
+arguments that are to be skipped (e.g. the object name and method name in a
+normal method call) is read with \fBTcl_ObjectContextSkippedArgs\fR, and the
+context can also report whether it is working as a filter for another method
+through \fBTcl_ObjectContextIsFiltering\fR.
+.PP
+During the execution of a method, the method implementation may choose to
+invoke the stages of the method call chain that come after the current method
+implementation. This (the core of the \fBnext\fR command) is done using
+\fBTcl_ObjectContextInvokeNext\fR. Note that this function does not manipulate
+the call-frame stack, unlike the \fBnext\fR command; if the method
+implementation has pushed one or more extra frames on the stack as part of its
+implementation, it is also responsible for temporarily popping those frames
+from the stack while the \fBTcl_ObjectContextInvokeNext\fR function is
+executing. Note also that the method-call context is \fInever\fR deleted
+during the execution of this function.
+.SH "METHOD TYPES"
+.PP
+The types of methods are described by a pointer to a Tcl_MethodType structure,
+which is defined as:
+.PP
+.CS
+typedef struct {
+ int \fIversion\fR;
+ const char *\fIname\fR;
+ Tcl_MethodCallProc *\fIcallProc\fR;
+ Tcl_MethodDeleteProc *\fIdeleteProc\fR;
+ Tcl_CloneProc *\fIcloneProc\fR;
+} \fBTcl_MethodType\fR;
+.CE
+.PP
+The \fIversion\fR field allows for future expansion of the structure, and
+should always be declared equal to TCL_OO_METHOD_VERSION_CURRENT. The
+\fIname\fR field provides a human-readable name for the type, and is reserved
+for debugging.
+.PP
+The \fIcallProc\fR field gives a function that is called when the method is
+invoked; it must never be NULL.
+.PP
+The \fIdeleteProc\fR field gives a function that is used to delete a
+particular method, and is called when the method is replaced or removed; if
+the field is NULL, it is assumed that the method's \fIclientData\fR needs no
+special action to delete.
+.PP
+The \fIcloneProc\fR field is either a function that is used to copy a method's
+\fIclientData\fR (as part of \fBTcl_CopyObjectInstance\fR) or NULL to indicate
+that the \fIclientData\fR can just be copied directly.
+.SS "TCL_METHODCALLPROC FUNCTION SIGNATURE"
+.PP
+Functions matching this signature are called when the method is invoked.
+.PP
+.CS
+typedef int \fBTcl_MethodCallProc\fR(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ Tcl_ObjectContext \fIobjectContext\fR,
+ int \fIobjc\fR,
+ Tcl_Obj *const *\fIobjv\fR);
+.CE
+.PP
+The \fIclientData\fR argument to a Tcl_MethodCallProc is the value that was
+given when the method was created, the \fIinterp\fR is a place in which to
+execute scripts and access variables as well as being where to put the result
+of the method, and the \fIobjc\fR and \fIobjv\fR fields give the parameter
+objects to the method. The calling context of the method can be discovered
+through the \fIobjectContext\fR argument, and the return value from a
+Tcl_MethodCallProc is any Tcl return code (e.g. TCL_OK, TCL_ERROR).
+.SS "TCL_METHODDELETEPROC FUNCTION SIGNATURE"
+.PP
+Functions matching this signature are used when a method is deleted, whether
+through a new method being created or because the object or class is deleted.
+.PP
+.CS
+typedef void \fBTcl_MethodDeleteProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR argument to a Tcl_MethodDeleteProc will be the same as
+the value passed to the \fIclientData\fR argument to \fBTcl_NewMethod\fR or
+\fBTcl_NewInstanceMethod\fR when the method was created.
+.SS "TCL_CLONEPROC FUNCTION SIGNATURE"
+.PP
+Functions matching this signature are used to copy a method when the object or
+class is copied using \fBTcl_CopyObjectInstance\fR (or \fBoo::copy\fR).
+.PP
+.CS
+typedef int \fBTcl_CloneProc\fR(
+ Tcl_Interp *\fIinterp\fR,
+ ClientData \fIoldClientData\fR,
+ ClientData *\fInewClientDataPtr\fR);
+.CE
+.PP
+The \fIinterp\fR argument gives a place to write an error message when the
+attempt to clone the object is to fail, in which case the clone procedure must
+also return TCL_ERROR; it should return TCL_OK otherwise.
+The \fIoldClientData\fR field to a Tcl_CloneProc gives the value from the
+method being copied from, and the \fInewClientDataPtr\fR field will point to
+a variable in which to write the value for the method being copied to.
+.SH "SEE ALSO"
+Class(3), oo::class(n), oo::define(n), oo::object(n)
+.SH KEYWORDS
+constructor, method, object
+
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/library/msgcat/doc/NRE.3 b/library/msgcat/doc/NRE.3
new file mode 100644
index 0000000..5c27491
--- /dev/null
+++ b/library/msgcat/doc/NRE.3
@@ -0,0 +1,328 @@
+.\"
+.\" Copyright (c) 2008 by Kevin B. Kenny.
+.\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH NRE 3 8.6 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_NRCreateCommand, Tcl_NRCallObjProc, Tcl_NREvalObj, Tcl_NREvalObjv, Tcl_NRCmdSwap, Tcl_NRAddCallback \- Non-Recursive (stackless) evaluation of Tcl scripts.
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Command
+\fBTcl_NRCreateCommand\fR(\fIinterp, cmdName, proc, nreProc, clientData,
+ deleteProc\fR)
+.sp
+int
+\fBTcl_NRCallObjProc\fR(\fIinterp, nreProc, clientData, objc, objv\fR)
+.sp
+int
+\fBTcl_NREvalObj\fR(\fIinterp, objPtr, flags\fR)
+.sp
+int
+\fBTcl_NREvalObjv\fR(\fIinterp, objc, objv, flags\fR)
+.sp
+int
+\fBTcl_NRCmdSwap\fR(\fIinterp, cmd, objc, objv, flags\fR)
+.sp
+int
+\fBTcl_NRExprObj\fR(\fIinterp, objPtr, resultPtr\fR)
+.sp
+void
+\fBTcl_NRAddCallback\fR(\fIinterp, postProcPtr, data0, data1, data2, data3\fR)
+.fi
+.SH ARGUMENTS
+.AS Tcl_CmdDeleteProc *interp in
+.AP Tcl_Interp *interp in
+Interpreter in which to create or evaluate a command.
+.AP char *cmdName in
+Name of a new command to create.
+.AP Tcl_ObjCmdProc *proc in
+Implementation of a command that will be called whenever \fIcmdName\fR
+is invoked as a command in the unoptimized way.
+.AP Tcl_ObjCmdProc *nreProc in
+Implementation of a command that will be called whenever \fIcmdName\fR
+is invoked and requested to conserve the C stack.
+.AP ClientData clientData in
+Arbitrary one-word value that will be passed to \fIproc\fR, \fInreProc\fR,
+\fIdeleteProc\fR and \fIobjProc\fR.
+.AP Tcl_CmdDeleteProc *deleteProc in/out
+Procedure to call before \fIcmdName\fR is deleted from the interpreter.
+This procedure allows for command-specific cleanup. If \fIdeleteProc\fR
+is \fBNULL\fR, then no procedure is called before the command is deleted.
+.AP int objc in
+Count of parameters provided to the implementation of a command.
+.AP Tcl_Obj **objv in
+Pointer to an array of Tcl objects. Each object holds the value of a
+single word in the command to execute.
+.AP Tcl_Obj *objPtr in
+Pointer to a Tcl_Obj whose value is a script or expression to execute.
+.AP int flags in
+ORed combination of flag bits that specify additional options.
+\fBTCL_EVAL_GLOBAL\fR is the only flag that is currently supported.
+.\" TODO: This is a lie. But kbk didn't grasp TCL_EVAL_INVOKE and
+.\" TCL_EVAL_NOERR well enough to document them.
+.AP Tcl_Command cmd in
+Token for a command that is to be used instead of the currently
+executing command.
+.AP Tcl_Obj *resultPtr out
+Pointer to an unshared Tcl_Obj where the result of expression
+evaluation is written.
+.AP Tcl_NRPostProc *postProcPtr in
+Pointer to a function that will be invoked when the command currently
+executing in the interpreter designated by \fIinterp\fR completes.
+.AP ClientData data0 in
+.AP ClientData data1 in
+.AP ClientData data2 in
+.AP ClientData data3 in
+\fIdata0\fR through \fIdata3\fR are four one-word values that will be passed
+to the function designated by \fIpostProcPtr\fR when it is invoked.
+.BE
+.SH DESCRIPTION
+.PP
+This series of C functions provides an interface whereby commands that
+are implemented in C can be evaluated, and invoke Tcl commands scripts
+and scripts, without consuming space on the C stack. The non-recursive
+evaluation is done by installing a \fItrampoline\fR, a small piece of
+code that invokes a command or script, and then executes a series of
+callbacks when the command or script returns.
+.PP
+The \fBTcl_NRCreateCommand\fR function creates a Tcl command in the
+interpreter designated by \fIinterp\fR that is prepared to handle
+nonrecursive evaluation with a trampoline. The \fIcmdName\fR argument
+gives the name of the new command. If \fIcmdName\fR contains any
+namespace qualifiers, then the new command is added to the specified
+namespace; otherwise, it is added to the global namespace. \fIproc\fR
+gives the procedure that will be called when the interpreter wishes to
+evaluate the command in an unoptimized manner, and \fInreProc\fR is
+the procedure that will be called when the interpreter wishes to
+evaluate the command using a trampoline. \fIdeleteProc\fR is a
+function that will be called before the command is deleted from the
+interpreter. When any of the three functions is invoked, it is passed
+the \fIclientData\fR parameter.
+.PP
+\fBTcl_NRCreateCommand\fR deletes any existing command
+\fIname\fR already associated with the interpreter
+(however see below for an exception where the existing command
+is not deleted).
+It returns a token that may be used to refer
+to the command in subsequent calls to \fBTcl_GetCommandName\fR.
+If \fBTcl_NRCreateCommand\fR is called for an interpreter that is in
+the process of being deleted, then it does not create a new command,
+does not delete any existing command of the same name, and returns NULL.
+.PP
+The \fIproc\fR and \fInreProc\fR function are expected to conform to
+all the rules set forth for the \fIproc\fR argument to
+\fBTcl_CreateObjCommand\fR(3) (\fIq.v.\fR).
+.PP
+When a command that is written to cope with evaluation via trampoline
+is invoked without a trampoline on the stack, it will usually respond
+to the invocation by creating a trampoline and calling the
+trampoline-enabled implementation of the same command. This call is done by
+means of \fBTcl_NRCallObjProc\fR. In the call to
+\fBTcl_NRCallObjProc\fR, the \fIinterp\fR, \fIclientData\fR,
+\fIobjc\fR and \fIobjv\fR parameters should be the same ones that were
+passed to \fIproc\fR. The \fInreProc\fR parameter should designate the
+trampoline-enabled implementation of the command.
+.PP
+\fBTcl_NREvalObj\fR arranges for the script contained in \fIobjPtr\fR
+to be evaluated in the interpreter designated by \fIinterp\fR after
+the current command (which must be trampoline-enabled) returns. It is
+the method by which a command may invoke a script without consuming
+space on the C stack. Similarly, \fBTcl_NREvalObjv\fR arranges to
+invoke a single Tcl command whose words have already been separated
+and substituted. The \fIobjc\fR and \fIobjv\fR parameters give the
+words of the command to be evaluated when execution reaches the
+trampoline.
+.PP
+\fBTcl_NRCmdSwap\fR allows for trampoline evaluation of a command whose
+resolution is already known. The \fIcmd\fR parameter gives a
+\fBTcl_Command\fR object (returned from \fBTcl_CreateObjCommand\fR or
+\fBTcl_GetCommandFromObj\fR) identifying the command to be invoked in
+the trampoline; this command must match the word in \fIobjv[0]\fR.
+The remaining arguments are as for \fBTcl_NREvalObj\fR.
+.PP
+\fBTcl_NREvalObj\fR, \fBTcl_NREvalObjv\fR and \fBTcl_NRCmdSwap\fR
+all accept a \fIflags\fR parameter, which is an OR-ed-together set of
+bits to control evaluation. At the present time, the only supported flag
+available to callers is \fBTCL_EVAL_GLOBAL\fR.
+.\" TODO: Again, this is a lie. Do we want to explain TCL_EVAL_INVOKE
+.\" and TCL_EVAL_NOERR?
+If the \fBTCL_EVAL_GLOBAL\fR flag is set, the script or command is
+evaluated in the global namespace. If it is not set, it is evaluated
+in the current namespace.
+.PP
+\fBTcl_NRExprObj\fR arranges for the expression contained in \fIobjPtr\fR
+to be evaluated in the interpreter designated by \fIinterp\fR after
+the current command (which must be trampoline-enabled) returns. It is
+the method by which a command may evaluate a Tcl expression without consuming
+space on the C stack. The argument \fIresultPtr\fR is a pointer to an
+unshared Tcl_Obj where the result of expression evaluation is to be written.
+If expression evaluation returns any code other than TCL_OK, the
+\fIresultPtr\fR value is left untouched.
+.PP
+All of the routines return \fBTCL_OK\fR if command or expression invocation
+has been scheduled successfully. If for any reason the scheduling cannot
+be completed (for example, if the interpreter is unable to find
+the requested command), they return \fBTCL_ERROR\fR with an
+appropriate message left in the interpreter's result.
+.PP
+\fBTcl_NRAddCallback\fR arranges to have a C function called when the
+current trampoline-enabled command in the Tcl interpreter designated
+by \fIinterp\fR returns. The \fIpostProcPtr\fR argument is a pointer
+to the callback function, which must have arguments and return value
+consistent with the \fBTcl_NRPostProc\fR data type:
+.PP
+.CS
+typedef int
+\fBTcl_NRPostProc\fR(
+ \fBClientData\fR \fIdata\fR[],
+ \fBTcl_Interp\fR *\fIinterp\fR,
+ int \fIresult\fR);
+.CE
+.PP
+When the trampoline invokes the callback function, the \fIdata\fR
+parameter will point to an array containing the four one-word
+quantities that were passed to \fBTcl_NRAddCallback\fR in the
+\fIdata0\fR through \fIdata3\fR parameters. The Tcl interpreter will
+be designated by the \fIinterp\fR parameter, and the \fIresult\fR
+parameter will contain the result (\fBTCL_OK\fR, \fBTCL_ERROR\fR,
+\fBTCL_RETURN\fR, \fBTCL_BREAK\fR or \fBTCL_CONTINUE\fR) that was
+returned by the command evaluation. The callback function is expected,
+in turn, either to return a \fIresult\fR to control further evaluation.
+.PP
+Multiple \fBTcl_NRAddCallback\fR invocations may request multiple
+callbacks, which may be to the same or different callback
+functions. If multiple callbacks are requested, they are executed in
+last-in, first-out order, that is, the most recently requested
+callback is executed first.
+.SH EXAMPLE
+.PP
+The usual pattern for Tcl commands that invoke other Tcl commands
+is something like:
+.PP
+.CS
+int
+\fITheCmdObjProc\fR(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ int result;
+ Tcl_Obj *objPtr;
+
+ \fI... preparation ...\fR
+
+ result = \fBTcl_EvalObjEx\fR(interp, objPtr, 0);
+
+ \fI... postprocessing ...\fR
+
+ return result;
+}
+\fBTcl_CreateObjCommand\fR(interp, "theCommand",
+ \fITheCmdObjProc\fR, clientData, TheCmdDeleteProc);
+.CE
+.PP
+To enable a command like this one for trampoline-based evaluation,
+it must be split into three pieces:
+.IP \(bu
+A non-trampoline implementation, \fITheCmdNewObjProc\fR,
+which will simply create a trampoline
+and invoke the trampoline-based implementation.
+.IP \(bu
+A trampoline-enabled implementation, \fITheCmdNRObjProc\fR. This
+function will perform the initialization, request that the trampoline
+call the postprocessing routine after command evaluation, and finally,
+request that the trampoline call the inner command.
+.IP \(bu
+A postprocessing routine, \fITheCmdPostProc\fR. This function will
+perform the postprocessing formerly done after the return from the
+inner command in \fITheCmdObjProc\fR.
+.PP
+The non-trampoline implementation is simple and stylized, containing
+a single statement:
+.PP
+.CS
+int
+\fITheCmdNewObjProc\fR(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ return \fBTcl_NRCallObjProc\fR(interp, name,
+ \fITheCmdNRObjProc\fR, clientData, objc, objv);
+}
+.CE
+.PP
+The trampoline-enabled implementation requests postprocessing,
+and returns to the trampoline requesting command evaluation.
+.PP
+.CS
+int
+\fITheCmdNRObjProc\fR
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ Tcl_Obj *objPtr;
+
+ \fI... preparation ...\fR
+
+ \fBTcl_NRAddCallback\fR(interp, \fITheCmdPostProc\fR,
+ data0, data1, data2, data3);
+ /* \fIdata0 .. data3\fR are up to four one-word items to
+ * pass to the postprocessing procedure */
+
+ return \fBTcl_NREvalObj\fR(interp, objPtr, 0);
+}
+.CE
+.PP
+The postprocessing procedure does whatever the original command did
+upon return from the inner evaluation.
+.PP
+.CS
+int
+\fITheCmdNRPostProc\fR(
+ ClientData data[],
+ Tcl_Interp *interp,
+ int result)
+{
+ /* \fIdata[0] .. data[3]\fR are the four words of data
+ * passed to \fBTcl_NREvalObj\fR */
+
+ \fI... postprocessing ...\fR
+
+ return result;
+}
+.CE
+.PP
+If \fItheCommand\fR is a command that results in multiple commands or
+scripts being evaluated, its postprocessing routine may schedule
+additional postprocessing and then request another command evaluation
+by means of \fBTcl_NREvalObj\fR or one of the other evaluation
+routines. Looping and sequencing constructs may be implemented in this way.
+.PP
+Finally, to install a trampoline-enabled command in the interpreter,
+\fBTcl_NRCreateCommand\fR is used in place of
+\fBTcl_CreateObjCommand\fR. It accepts two command procedures instead
+of one. The first is for use when no trampoline is yet on the stack,
+and the second is for use when there is already a trampoline in place.
+.PP
+.CS
+\fBTcl_NRCreateCommand\fR(interp, "theCommand",
+ \fITheCmdObjProc\fR, \fITheCmdNRObjProc\fR, clientData,
+ TheCmdDeleteProc);
+.CE
+.SH "SEE ALSO"
+Tcl_CreateCommand(3), Tcl_CreateObjCommand(3), Tcl_EvalObjEx(3), Tcl_GetCommandFromObj(3), Tcl_ExprObj(3)
+.SH KEYWORDS
+stackless, nonrecursive, execute, command, global, object, result, script
+.SH COPYRIGHT
+Copyright (c) 2008 by Kevin B. Kenny
diff --git a/library/msgcat/doc/Namespace.3 b/library/msgcat/doc/Namespace.3
new file mode 100644
index 0000000..50cc559
--- /dev/null
+++ b/library/msgcat/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:
+.PP
+.CS
+typedef void \fBTcl_NamespaceDeleteProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.PP
+\fBTcl_DeleteNamespace\fR deletes a namespace, calling the
+\fIdeleteProc\fR defined for the namespace (if any).
+.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(3), Tcl_ListObjAppendList(3), Tcl_SetVar(3)
+.SH KEYWORDS
+namespace, command
diff --git a/library/msgcat/doc/Notifier.3 b/library/msgcat/doc/Notifier.3
new file mode 100644
index 0000000..f65d580
--- /dev/null
+++ b/library/msgcat/doc/Notifier.3
@@ -0,0 +1,635 @@
+'\"
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\" Copyright (c) 1995-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 Notifier 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_SetMaxBlockTime, Tcl_QueueEvent, Tcl_ThreadQueueEvent, Tcl_ThreadAlert, Tcl_GetCurrentThread, Tcl_DeleteEvents, Tcl_InitNotifier, Tcl_FinalizeNotifier, Tcl_WaitForEvent, Tcl_AlertNotifier, Tcl_SetTimer, Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, Tcl_SetServiceMode, Tcl_ServiceModeHook, Tcl_SetNotifier \- the event queue and notifier interfaces
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_CreateEventSource\fR(\fIsetupProc, checkProc, clientData\fR)
+.sp
+void
+\fBTcl_DeleteEventSource\fR(\fIsetupProc, checkProc, clientData\fR)
+.sp
+void
+\fBTcl_SetMaxBlockTime\fR(\fItimePtr\fR)
+.sp
+void
+\fBTcl_QueueEvent\fR(\fIevPtr, position\fR)
+.sp
+void
+\fBTcl_ThreadQueueEvent\fR(\fIthreadId, evPtr, position\fR)
+.sp
+void
+\fBTcl_ThreadAlert\fR(\fIthreadId\fR)
+.sp
+Tcl_ThreadId
+\fBTcl_GetCurrentThread\fR()
+.sp
+void
+\fBTcl_DeleteEvents\fR(\fIdeleteProc, clientData\fR)
+.sp
+ClientData
+\fBTcl_InitNotifier\fR()
+.sp
+void
+\fBTcl_FinalizeNotifier\fR(\fIclientData\fR)
+.sp
+int
+\fBTcl_WaitForEvent\fR(\fItimePtr\fR)
+.sp
+void
+\fBTcl_AlertNotifier\fR(\fIclientData\fR)
+.sp
+void
+\fBTcl_SetTimer\fR(\fItimePtr\fR)
+.sp
+int
+\fBTcl_ServiceAll\fR()
+.sp
+int
+\fBTcl_ServiceEvent\fR(\fIflags\fR)
+.sp
+int
+\fBTcl_GetServiceMode\fR()
+.sp
+int
+\fBTcl_SetServiceMode\fR(\fImode\fR)
+.sp
+void
+\fBTcl_ServiceModeHook\fR(\fImode\fR)
+.sp
+void
+\fBTcl_SetNotifier\fR(\fInotifierProcPtr\fR)
+.SH ARGUMENTS
+.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
+Procedure for \fBTcl_DoOneEvent\fR to invoke after waiting for
+events. Checks to see if any events have occurred and, if so,
+queues them.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIsetupProc\fR, \fIcheckProc\fR, or
+\fIdeleteProc\fR.
+.AP "const Tcl_Time" *timePtr in
+Indicates the maximum amount of time to wait for an event. This
+is specified as an interval (how long to wait), not an absolute
+time (when to wakeup). If the pointer passed to \fBTcl_WaitForEvent\fR
+is NULL, it means there is no maximum wait time: wait forever if
+necessary.
+.AP Tcl_Event *evPtr in
+An event to add to the event queue. The storage for the event must
+have been allocated by the caller using \fBTcl_Alloc\fR or \fBckalloc\fR.
+.AP Tcl_QueuePosition position in
+Where to add the new event in the queue: \fBTCL_QUEUE_TAIL\fR,
+\fBTCL_QUEUE_HEAD\fR, or \fBTCL_QUEUE_MARK\fR.
+.AP Tcl_ThreadId threadId in
+A unique identifier for a thread.
+.AP Tcl_EventDeleteProc *deleteProc in
+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.
+.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.
+.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
+.PP
+The interfaces described here are used to customize the Tcl event
+loop. The two most common customizations are to add new sources of
+events and to merge Tcl's event loop with some other event loop, such
+as one provided by an application in which Tcl is embedded. Each of
+these tasks is described in a separate section below.
+.PP
+The procedures in this manual entry are the building blocks out of which
+the Tcl event notifier is constructed. The event notifier is the lowest
+layer in the Tcl event mechanism. It consists of three things:
+.IP [1]
+Event sources: these represent the ways in which events can be
+generated. For example, there is a timer event source that implements
+the \fBTcl_CreateTimerHandler\fR procedure and the \fBafter\fR
+command, and there is a file event source that implements the
+\fBTcl_CreateFileHandler\fR procedure on Unix systems. An event
+source must work with the notifier to detect events at the right
+times, record them on the event queue, and eventually notify
+higher-level software that they have occurred. The procedures
+\fBTcl_CreateEventSource\fR, \fBTcl_DeleteEventSource\fR,
+and \fBTcl_SetMaxBlockTime\fR, \fBTcl_QueueEvent\fR, and
+\fBTcl_DeleteEvents\fR are used primarily by event sources.
+.IP [2]
+The event queue: for non-threaded applications,
+there is a single queue for the whole application,
+containing events that have been detected but not yet serviced. Event
+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. Threaded applications work in a
+similar manner, except that there is a separate event queue for
+each thread containing a Tcl interpreter.
+\fBTcl_QueueEvent\fR is used (primarily
+by event sources) to add events to the event queue and
+\fBTcl_DeleteEvents\fR is used to remove events from the queue without
+processing them. In a threaded application, \fBTcl_QueueEvent\fR adds
+an event to the current thread's queue, and \fBTcl_ThreadQueueEvent\fR
+adds an event to a queue in a specific thread.
+.IP [3]
+The event loop: in order to detect and process events, the application
+enters a loop that waits for events to occur, places them on the event
+queue, and then processes them. Most applications will do this by
+calling the procedure \fBTcl_DoOneEvent\fR, which is described in a
+separate manual entry.
+.PP
+Most Tcl applications need not worry about any of the internals of
+the Tcl notifier. However, the notifier now has enough flexibility
+to be retargeted either for a new platform or to use an external event
+loop (such as the Motif event loop, when Tcl is embedded in a Motif
+application). The procedures \fBTcl_WaitForEvent\fR and
+\fBTcl_SetTimer\fR are normally implemented by Tcl, but may be
+replaced with new versions to retarget the notifier (the
+\fBTcl_InitNotifier\fR, \fBTcl_AlertNotifier\fR,
+\fBTcl_FinalizeNotifier\fR, \fBTcl_Sleep\fR,
+\fBTcl_CreateFileHandler\fR, and \fBTcl_DeleteFileHandler\fR must
+also be replaced; see CREATING A NEW NOTIFIER below for details).
+The procedures \fBTcl_ServiceAll\fR, \fBTcl_ServiceEvent\fR,
+\fBTcl_GetServiceMode\fR, and \fBTcl_SetServiceMode\fR are provided
+to help connect Tcl's event loop to an external event loop such as
+Motif's.
+.SH "NOTIFIER BASICS"
+.PP
+The easiest way to understand how the notifier works is to consider
+what happens when \fBTcl_DoOneEvent\fR is called.
+\fBTcl_DoOneEvent\fR is passed a \fIflags\fR argument that indicates
+what sort of events it is OK to process and also whether or not to
+block if no events are ready. \fBTcl_DoOneEvent\fR does the following
+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
+from the queue, and return. It does this by calling
+\fBTcl_ServiceEvent\fR and passing in the \fIflags\fR argument.
+.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
+possibly call \fBTcl_SetMaxBlockTime\fR to limit how long
+\fBTcl_WaitForEvent\fR will block if no new events occur.
+.IP [3]
+Call \fBTcl_WaitForEvent\fR. This procedure is implemented differently
+on different platforms; it waits for an event to occur, based on the
+information provided by the event sources.
+It may cause the application to block if \fItimePtr\fR specifies
+an interval other than 0.
+\fBTcl_WaitForEvent\fR returns when something has happened,
+such as a file becoming readable or the interval given by \fItimePtr\fR
+expiring. If there are no events for \fBTcl_WaitForEvent\fR to
+wait for, so that it would block forever, then it returns immediately
+and \fBTcl_DoOneEvent\fR returns 0.
+.IP [4]
+Call a \fIcheck procedure\fR in each event source. The check
+procedure determines whether any events of interest to this source
+occurred. If so, the events are added to the event queue.
+.IP [5]
+Check the event queue to see if it contains any events that can
+be serviced. If so, service the first possible event, remove it
+from the queue, and return.
+.IP [6]
+See if there are idle callbacks pending. If so, invoke all of them and
+return.
+.IP [7]
+Either return 0 to indicate that no events were ready, or go back to
+step [2] if blocking was requested by the caller.
+.SH "CREATING A NEW EVENT SOURCE"
+.PP
+An event source consists of three procedures invoked by the notifier,
+plus additional C procedures that are invoked by higher-level code
+to arrange for event-driven callbacks. The three procedures called
+by the notifier consist of the setup and check procedures described
+above, plus an additional procedure that is invoked when an event
+is removed from the event queue for servicing.
+.PP
+The procedure \fBTcl_CreateEventSource\fR creates a new event source.
+Its arguments specify the setup procedure and check procedure for
+the event source.
+\fISetupProc\fR should match the following prototype:
+.PP
+.CS
+typedef void \fBTcl_EventSetupProc\fR(
+ ClientData \fIclientData\fR,
+ int \fIflags\fR);
+.CE
+.PP
+The \fIclientData\fR argument will be the same as the \fIclientData\fR
+argument to \fBTcl_CreateEventSource\fR; it is typically used to
+point to private information managed by the event source.
+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 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.
+.PP
+\fISetupProc\fR's job is to make sure that the application wakes up
+when events of the desired type occur. This is typically done in a
+platform-dependent fashion. For example, under Unix an event source
+might call \fBTcl_CreateFileHandler\fR; under Windows it might
+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.
+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
+interval passed to \fBTcl_SetMaxBlockTime\fR by one of the event
+sources. If an event source knows that it already has events ready to
+report, it can request a zero maximum block time. For example, the
+setup procedure for the X event source looks to see if there are
+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.
+The \fItimePtr\fR argument to \fBTcl_WaitForEvent\fR points to
+a structure that describes a time interval in seconds and
+microseconds:
+.PP
+.CS
+typedef struct Tcl_Time {
+ long \fIsec\fR;
+ long \fIusec\fR;
+} \fBTcl_Time\fR;
+.CE
+.PP
+The \fIusec\fR field should be less than 1000000.
+.PP
+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.
+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
+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
+handler is registered that needs to poll for events, the event source
+may call \fBTcl_SetMaxBlockTime\fR to set the block time to zero to
+force the external event loop to call Tcl. In this case,
+\fBTcl_SetMaxBlockTime\fR invokes \fBTcl_SetTimer\fR with the shortest
+interval seen since the last call to \fBTcl_DoOneEvent\fR or
+\fBTcl_ServiceAll\fR.
+.PP
+In addition to the generic procedure \fBTcl_SetMaxBlockTime\fR, other
+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.
+.PP
+The second procedure provided by each event source is its check
+procedure, indicated by the \fIcheckProc\fR argument to
+\fBTcl_CreateEventSource\fR. \fICheckProc\fR must match the
+following prototype:
+.PP
+.CS
+typedef void \fBTcl_EventCheckProc\fR(
+ ClientData \fIclientData\fR,
+ int \fIflags\fR);
+.CE
+.PP
+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
+for events. Presumably at least one event source is now prepared to
+queue an event. \fBTcl_DoOneEvent\fR calls each of the event sources
+in turn, so they all have a chance to queue any events that are ready.
+The check procedure does two things. First, it must see if any events
+have triggered. Different event sources do this in different ways.
+.PP
+If an event source's check procedure detects an interesting event, it
+must add the event to Tcl's event queue. To do this, the event source
+calls \fBTcl_QueueEvent\fR. The \fIevPtr\fR argument is a pointer to
+a dynamically allocated structure containing the event (see below for
+more information on memory management issues). Each event source can
+define its own event structure with whatever information is relevant
+to that event source. However, the first element of the structure
+must be a structure of type \fBTcl_Event\fR, and the address of this
+structure is used when communicating between the event source and the
+rest of the notifier. A \fBTcl_Event\fR has the following definition:
+.PP
+.CS
+typedef struct {
+ Tcl_EventProc *\fIproc\fR;
+ struct Tcl_Event *\fInextPtr\fR;
+} \fBTcl_Event\fR;
+.CE
+.PP
+The event source must fill in the \fIproc\fR field of
+the event before calling \fBTcl_QueueEvent\fR.
+The \fInextPtr\fR is used to link together the events in the queue
+and should not be modified by the event source.
+.PP
+An event may be added to the queue at any of three positions, depending
+on the \fIposition\fR argument to \fBTcl_QueueEvent\fR:
+.IP \fBTCL_QUEUE_TAIL\fR 24
+Add the event at the back of the queue, so that all other pending
+events will be serviced first. This is almost always the right
+place for new events.
+.IP \fBTCL_QUEUE_HEAD\fR 24
+Add the event at the front of the queue, so that it will be serviced
+before all other queued events.
+.IP \fBTCL_QUEUE_MARK\fR 24
+Add the event at the front of the queue, unless there are other
+events at the front whose position is \fBTCL_QUEUE_MARK\fR; if so,
+add the new event just after all other \fBTCL_QUEUE_MARK\fR events.
+This value of \fIposition\fR is used to insert an ordered sequence of
+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
+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
+in the first queued \fBTcl_Event\fR structure.
+\fIProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_EventProc\fR(
+ Tcl_Event *\fIevPtr\fR,
+ int \fIflags\fR);
+.CE
+.PP
+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
+current call to \fBTcl_ServiceEvent\fR; this is used by the event source
+to return immediately if its events are not relevant.
+.PP
+It is up to \fIproc\fR to handle the event, typically by invoking
+one or more Tcl commands or C-level callbacks.
+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
+should be deferred for processing later; in this case \fBTcl_ServiceEvent\fR
+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 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
+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
+the event source (using \fBTcl_Alloc\fR or the Tcl macro \fBckalloc\fR)
+before calling \fBTcl_QueueEvent\fR, but it
+will be freed by \fBTcl_ServiceEvent\fR, not by the event source.
+.PP
+Threaded applications work in a
+similar manner, except that there is a separate event queue for
+each thread containing a Tcl interpreter.
+Calling \fBTcl_QueueEvent\fR in a multithreaded application adds
+an event to the current thread's queue.
+To add an event to another thread's queue, use \fBTcl_ThreadQueueEvent\fR.
+\fBTcl_ThreadQueueEvent\fR accepts as an argument a Tcl_ThreadId argument,
+which uniquely identifies a thread in a Tcl application. To obtain the
+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
+.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
+for each event in the queue, deleting those for with the procedure
+returns 1. Events for which the procedure returns 0 are left in the
+queue. \fIProc\fR should match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_EventDeleteProc\fR(
+ Tcl_Event *\fIevPtr\fR,
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR argument will be the same as the \fIclientData\fR
+argument to \fBTcl_DeleteEvents\fR; it is typically used to point to
+private information managed by the event source. The \fIevPtr\fR will
+point to the next event in the queue.
+.PP
+\fBTcl_DeleteEventSource\fR deletes an event source. The \fIsetupProc\fR,
+\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.
+.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
+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, 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
+procedure when initializing a Tcl interpreter. Similarly,
+\fBTcl_FinalizeNotifier\fR shuts down the notifier, and is
+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
+.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
+\fBTcl_WaitForEvent\fR gives the maximum time to block for an event,
+based on calls to \fBTcl_SetMaxBlockTime\fR made by setup procedures
+and on other information (such as the \fBTCL_DONT_WAIT\fR bit in
+\fIflags\fR).
+.PP
+Ideally, \fBTcl_WaitForEvent\fR should only wait for an event
+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 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 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
+platform where \fBTcl_WaitForEvent\fR only waits without doing any event
+processing, or \fBTcl_WaitForEvent\fR knows for sure that there are no
+additional events to process (e.g. it returned because the time
+elapsed). Finally, a return value of \-1 means that the event loop is
+no longer operational and the application should probably unwind and
+terminate. Under Windows this happens when a WM_QUIT message is received;
+under Unix it happens when \fBTcl_WaitForEvent\fR would have waited
+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
+.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
+If the notifier will be used with an external event loop, then it must
+also support the \fBTcl_SetTimer\fR interface. \fBTcl_SetTimer\fR is
+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 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
+procedures, which are described in the \fBTcl_CreateFileHandler\fR
+manual page.
+.PP
+The \fBTcl_Sleep\fR and \fBTcl_DoOneEvent\fR interfaces are described
+in their respective manual pages.
+.PP
+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:
+.PP
+.CS
+typedef struct Tcl_NotifierProcs {
+ Tcl_SetTimerProc *\fIsetTimerProc\fR;
+ Tcl_WaitForEventProc *\fIwaitForEventProc\fR;
+ Tcl_CreateFileHandlerProc *\fIcreateFileHandlerProc\fR;
+ Tcl_DeleteFileHandlerProc *\fIdeleteFileHandlerProc\fR;
+ Tcl_InitNotifierProc *\fIinitNotifierProc\fR;
+ Tcl_FinalizeNotifierProc *\fIfinalizeNotifierProc\fR;
+ Tcl_AlertNotifierProc *\fIalertNotifierProc\fR;
+ Tcl_ServiceModeHookProc *\fIserviceModeHookProc\fR;
+} \fBTcl_NotifierProcs\fR;
+.CE
+.PP
+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
+applications that have their own private event loops. In this case,
+the application does not call \fBTcl_DoOneEvent\fR except in the case
+of recursive event loops such as calls to the Tcl commands \fBupdate\fR
+or \fBvwait\fR. Most of the time is spent in the external event loop
+of the application. In this case the notifier must arrange for the
+external event loop to call back into Tcl when something
+happens on the various Tcl event sources. These callbacks should
+arrange for appropriate Tcl events to be placed on the Tcl event queue.
+.PP
+Because the external event loop is not calling \fBTcl_DoOneEvent\fR on
+a regular basis, it is up to the notifier to arrange for
+\fBTcl_ServiceEvent\fR to be called whenever events are pending on the
+Tcl event queue. The easiest way to do this is to invoke
+\fBTcl_ServiceAll\fR at the end of each callback from the external
+event loop. This will ensure that all of the event sources are
+polled, any queued events are serviced, and any pending idle handlers
+are processed before returning control to the application. In
+addition, event sources that need to poll for events can call
+\fBTcl_SetMaxBlockTime\fR to force the external event loop to call
+Tcl even if no events are available on the system event queue.
+.PP
+As a side effect of processing events detected in the main external
+event loop, Tcl may invoke \fBTcl_DoOneEvent\fR to start a recursive event
+loop in commands like \fBvwait\fR. \fBTcl_DoOneEvent\fR will invoke
+the external event loop, which will result in callbacks as described
+in the preceding paragraph, which will result in calls to
+\fBTcl_ServiceAll\fR. However, in these cases it is undesirable to
+service events in \fBTcl_ServiceAll\fR. Servicing events there is
+unnecessary because control will immediately return to the
+external event loop and hence to \fBTcl_DoOneEvent\fR, which can
+service the events itself. Furthermore, \fBTcl_DoOneEvent\fR is
+supposed to service only a single event, whereas \fBTcl_ServiceAll\fR
+normally services all pending events. To handle this situation,
+\fBTcl_DoOneEvent\fR sets a flag for \fBTcl_ServiceAll\fR
+that causes it to return without servicing any events.
+This flag is called the \fIservice mode\fR;
+\fBTcl_DoOneEvent\fR restores it to its previous value before it returns.
+.PP
+In some cases, however, it may be necessary for \fBTcl_ServiceAll\fR
+to service events
+even when it has been invoked from \fBTcl_DoOneEvent\fR. This happens
+when there is yet another recursive event loop invoked via an
+event handler called by \fBTcl_DoOneEvent\fR (such as one that is
+part of a native widget). In this case, \fBTcl_DoOneEvent\fR may not
+have a chance to service events so \fBTcl_ServiceAll\fR must service
+them all. Any recursive event loop that calls an external event
+loop rather than \fBTcl_DoOneEvent\fR must reset the service mode so
+that all events get processed in \fBTcl_ServiceAll\fR. This is done
+by invoking the \fBTcl_SetServiceMode\fR procedure. If
+\fBTcl_SetServiceMode\fR is passed \fBTCL_SERVICE_NONE\fR, then calls
+to \fBTcl_ServiceAll\fR will return immediately without processing any
+events. If \fBTcl_SetServiceMode\fR is passed \fBTCL_SERVICE_ALL\fR,
+then calls to \fBTcl_ServiceAll\fR will behave normally.
+\fBTcl_SetServiceMode\fR returns the previous value of the service
+mode, which should be restored when the recursive loop exits.
+\fBTcl_GetServiceMode\fR returns the current value of the service
+mode.
+.SH "SEE ALSO"
+Tcl_CreateFileHandler(3), Tcl_DeleteFileHandler(3), Tcl_Sleep(3),
+Tcl_DoOneEvent(3), Thread(3)
+.SH KEYWORDS
+event, notifier, event queue, event sources, file events, timer, idle, service mode, threads
diff --git a/library/msgcat/doc/Object.3 b/library/msgcat/doc/Object.3
new file mode 100644
index 0000000..1c60449
--- /dev/null
+++ b/library/msgcat/doc/Object.3
@@ -0,0 +1,350 @@
+'\"
+'\" Copyright (c) 1996-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 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
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewObj\fR()
+.sp
+Tcl_Obj *
+\fBTcl_DuplicateObj\fR(\fIobjPtr\fR)
+.sp
+\fBTcl_IncrRefCount\fR(\fIobjPtr\fR)
+.sp
+\fBTcl_DecrRefCount\fR(\fIobjPtr\fR)
+.sp
+int
+\fBTcl_IsShared\fR(\fIobjPtr\fR)
+.sp
+\fBTcl_InvalidateStringRep\fR(\fIobjPtr\fR)
+.SH ARGUMENTS
+.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.
+.BE
+.SH INTRODUCTION
+.PP
+This man page presents an overview of Tcl objects and how they are used.
+It also describes generic procedures for managing Tcl objects.
+These procedures are used to create and copy objects,
+and increment and decrement the count of references (pointers) to objects.
+The procedures are used in conjunction with ones
+that operate on specific types of objects such as
+\fBTcl_GetIntFromObj\fR and \fBTcl_ListObjAppendElement\fR.
+The individual procedures are described along with the data structures
+they manipulate.
+.PP
+Tcl's \fIdual-ported\fR objects provide a general-purpose mechanism
+for storing and exchanging Tcl values.
+They largely replace the use of strings in Tcl.
+For example, they are used to store variable values,
+command arguments, command results, and scripts.
+Tcl objects behave like strings but also hold an internal representation
+that can be manipulated more efficiently.
+For example, a Tcl list is now represented as an object
+that holds the list's string representation
+as well as an array of pointers to the objects for each list element.
+Dual-ported objects avoid most runtime type conversions.
+They also improve the speed of many operations
+since an appropriate representation is immediately available.
+The compiler itself uses Tcl objects to
+cache the instruction bytecodes resulting from compiling scripts.
+.PP
+The two representations are a cache of each other and are computed lazily.
+That is, each representation is only computed when necessary,
+it is computed from the other representation,
+and, once computed, it is saved.
+In addition, a change in one representation invalidates the other one.
+As an example, a Tcl program doing integer calculations can
+operate directly on a variable's internal machine integer
+representation without having to constantly convert
+between integers and strings.
+Only when it needs a string representing the variable's value,
+say to print it,
+will the program regenerate the string representation from the integer.
+Although objects contain an internal representation,
+their semantics are defined in terms of strings:
+an up-to-date string can always be obtained,
+and any change to the object will be reflected in that string
+when the object's string representation is fetched.
+Because of this representation invalidation and regeneration,
+it is dangerous for extension writers to access
+\fBTcl_Obj\fR fields directly.
+It is better to access Tcl_Obj information using
+procedures like \fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR.
+.PP
+Objects are allocated on the heap
+and are referenced using a pointer to their \fBTcl_Obj\fR structure.
+Objects are shared as much as possible.
+This significantly reduces storage requirements
+because some objects such as long lists are very large.
+Also, most Tcl values are only read and never modified.
+This is especially true for procedure arguments,
+which can be shared between the caller and the called procedure.
+Assignment and argument binding is done by
+simply assigning a pointer to the value.
+Reference counting is used to determine when it is safe to
+reclaim an object's storage.
+.PP
+Tcl objects are typed.
+An object's internal representation is controlled by its type.
+Several types are predefined in the Tcl core
+including integer, double, list, and bytecode.
+Extension writers can extend the set of types
+by defining their own \fBTcl_ObjType\fR structs.
+.SH "THE TCL_OBJ STRUCTURE"
+.PP
+Each Tcl object is represented by a \fBTcl_Obj\fR structure
+which is defined as follows.
+.PP
+.CS
+typedef struct Tcl_Obj {
+ int \fIrefCount\fR;
+ char *\fIbytes\fR;
+ int \fIlength\fR;
+ const 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;
+} \fBTcl_Obj\fR;
+.CE
+.PP
+The \fIbytes\fR and the \fIlength\fR members together hold
+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.)
+\fIbytes\fR points to the first byte of the string representation.
+The \fIlength\fR member gives the number of bytes.
+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.
+C programs use \fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR to get
+an object's string representation.
+If \fIbytes\fR is NULL,
+the string representation is invalid.
+.PP
+An object's type manages its internal representation.
+The member \fItypePtr\fR points to the Tcl_ObjType structure
+that describes the type.
+If \fItypePtr\fR is NULL,
+the internal representation is invalid.
+.PP
+The \fIinternalRep\fR union member holds
+an object's internal representation.
+This is either a (long) integer, a double-precision floating-point number,
+a pointer to a value containing additional information
+needed by the object's type to represent the object, a Tcl_WideInt
+integer, two arbitrary pointers, or a pair made up of an unsigned long
+integer and a pointer.
+.PP
+The \fIrefCount\fR member is used to tell when it is safe to free
+an object's storage.
+It holds the count of active references to the object.
+Maintaining the correct reference count is a key responsibility
+of extension writers.
+Reference counting is discussed below
+in the section \fBSTORAGE MANAGEMENT OF OBJECTS\fR.
+.PP
+Although extension writers can directly access
+the members of a Tcl_Obj structure,
+it is much better to use the appropriate procedures and macros.
+For example, extension writers should never
+read or update \fIrefCount\fR directly;
+they should use macros such as
+\fBTcl_IncrRefCount\fR and \fBTcl_IsShared\fR instead.
+.PP
+A key property of Tcl objects is that they hold two representations.
+An object typically starts out containing only a string representation:
+it is untyped and has a NULL \fItypePtr\fR.
+An object containing an empty string or a copy of a specified string
+is created using \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR respectively.
+An object's string value is gotten with
+\fBTcl_GetStringFromObj\fR or \fBTcl_GetString\fR
+and changed with \fBTcl_SetStringObj\fR.
+If the object is later passed to a procedure like \fBTcl_GetIntFromObj\fR
+that requires a specific internal representation,
+the procedure will create one and set the object's \fItypePtr\fR.
+The internal representation is computed from the string representation.
+An object's two representations are duals of each other:
+changes made to one are reflected in the other.
+For example, \fBTcl_ListObjReplace\fR will modify an object's
+internal representation and the next call to \fBTcl_GetStringFromObj\fR
+or \fBTcl_GetString\fR will reflect that change.
+.PP
+Representations are recomputed lazily for efficiency.
+A change to one representation made by a procedure
+such as \fBTcl_ListObjReplace\fR is not reflected immediately
+in the other representation.
+Instead, the other representation is marked invalid
+so that it is only regenerated if it is needed later.
+Most C programmers never have to be concerned with how this is done
+and simply use procedures such as \fBTcl_GetBooleanFromObj\fR or
+\fBTcl_ListObjIndex\fR.
+Programmers that implement their own object types
+must check for invalid representations
+and mark representations invalid when necessary.
+The procedure \fBTcl_InvalidateStringRep\fR is used
+to mark an object's string representation invalid and to
+free any storage associated with the old string representation.
+.PP
+Objects usually remain one type over their life,
+but occasionally an object must be converted from one type to another.
+For example, a C program might build up a string in an object
+with repeated calls to \fBTcl_AppendToObj\fR,
+and then call \fBTcl_ListObjIndex\fR to extract a list element from
+the object.
+The same object holding the same string value
+can have several different internal representations
+at different times.
+Extension writers can also force an object to be converted from one type
+to another using the \fBTcl_ConvertToType\fR procedure.
+Only programmers that create new object types need to be concerned
+about how this is done.
+A procedure defined as part of the object type's implementation
+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,
+consider the following sequence of commands:
+.PP
+.CS
+\fBset x 123\fR
+.CE
+.PP
+This assigns to \fIx\fR an untyped object whose
+\fIbytes\fR member points to \fB123\fR and \fIlength\fR member contains 3.
+The object's \fItypePtr\fR member is NULL.
+.PP
+.CS
+\fBputs "x is $x"\fR
+.CE
+.PP
+\fIx\fR's string representation is valid (since \fIbytes\fR is non-NULL)
+and is fetched for the command.
+.PP
+.CS
+\fBincr x\fR
+.CE
+.PP
+The \fBincr\fR command first gets an integer from \fIx\fR's object
+by calling \fBTcl_GetIntFromObj\fR.
+This procedure checks whether the object is already an integer object.
+Since it is not, it converts the object
+by setting the object's \fIinternalRep.longValue\fR member
+to the integer \fB123\fR
+and setting the object's \fItypePtr\fR
+to point to the integer Tcl_ObjType structure.
+Both representations are now valid.
+\fBincr\fR increments the object's integer internal representation
+then invalidates its string representation
+(by calling \fBTcl_InvalidateStringRep\fR)
+since the string representation
+no longer corresponds to the internal representation.
+.PP
+.CS
+\fBputs "x is now $x"\fR
+.CE
+.PP
+The string representation of \fIx\fR's object is needed
+and is recomputed.
+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
+to reduce storage requirements.
+Reference counting is used to determine when an object is
+no longer needed and can safely be freed.
+An object just created by \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR
+has \fIrefCount\fR 0.
+The macro \fBTcl_IncrRefCount\fR increments the reference count
+when a new reference to the object is created.
+The macro \fBTcl_DecrRefCount\fR decrements the count
+when a reference is no longer needed and,
+if the object's reference count drops to zero, frees its storage.
+An object shared by different code or data structures has
+\fIrefCount\fR greater than 1.
+Incrementing an object's reference count ensures that
+it will not be freed too early or have its value change accidentally.
+.PP
+As an example, the bytecode interpreter shares argument objects
+between calling and called Tcl procedures to avoid having to copy objects.
+It assigns the call's argument objects to the procedure's
+formal parameter variables.
+In doing so, it calls \fBTcl_IncrRefCount\fR to increment
+the reference count of each argument since there is now a new
+reference to it from the formal parameter.
+When the called procedure returns,
+the interpreter calls \fBTcl_DecrRefCount\fR to decrement
+each argument's reference count.
+When an object's reference count drops less than or equal to zero,
+\fBTcl_DecrRefCount\fR reclaims its storage.
+Most command procedures do not have to be concerned about
+reference counting since they use an object's value immediately
+and do not retain a pointer to the object after they return.
+However, if they do retain a pointer to an object in a data structure,
+they must be careful to increment its reference count
+since the retained pointer is a new reference.
+.PP
+Command procedures that directly modify objects
+such as those for \fBlappend\fR and \fBlinsert\fR must be careful to
+copy a shared object before changing it.
+They must first check whether the object is shared
+by calling \fBTcl_IsShared\fR.
+If the object is shared they must copy the object
+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
+.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 (\fBTcl_IsShared\fR(listPtr)) {
+ listPtr = \fBTcl_DuplicateObj\fR(listPtr);
+}
+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 accidentally changing values in other data structures.
+.SH "SEE ALSO"
+Tcl_ConvertToType(3), Tcl_GetIntFromObj(3), Tcl_ListObjAppendElement(3), Tcl_ListObjIndex(3), Tcl_ListObjReplace(3), Tcl_RegisterObjType(3)
+.SH KEYWORDS
+internal representation, object, object creation, object type, reference counting, string representation, type conversion
diff --git a/library/msgcat/doc/ObjectType.3 b/library/msgcat/doc/ObjectType.3
new file mode 100644
index 0000000..0c11187
--- /dev/null
+++ b/library/msgcat/doc/ObjectType.3
@@ -0,0 +1,255 @@
+'\"
+'\" Copyright (c) 1996-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 Tcl_ObjType 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_RegisterObjType, Tcl_GetObjType, Tcl_AppendAllObjTypes, Tcl_ConvertToType \- manipulate Tcl object types
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_RegisterObjType\fR(\fItypePtr\fR)
+.sp
+const Tcl_ObjType *
+\fBTcl_GetObjType\fR(\fItypeName\fR)
+.sp
+int
+\fBTcl_AppendAllObjTypes\fR(\fIinterp, objPtr\fR)
+.sp
+int
+\fBTcl_ConvertToType\fR(\fIinterp, objPtr, typePtr\fR)
+.SH ARGUMENTS
+.AS "const char" *typeName
+.AP "const 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
+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.
+.AP Tcl_Obj *objPtr in
+For \fBTcl_AppendAllObjTypes\fR, this points to the object onto which
+it appends the name of each object type as a list element.
+For \fBTcl_ConvertToType\fR, this points to an object that
+must have been the result of a previous call to \fBTcl_NewObj\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+The procedures in this man page manage Tcl object types.
+They are used to register new object types, look up types,
+and force conversions from one type to another.
+.PP
+\fBTcl_RegisterObjType\fR registers a new Tcl object type
+in the table of all object types that \fBTcl_GetObjType\fR
+can look up by name. There are other object types supported by Tcl
+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
+that implement the type.
+If the type table already contains a type
+with the same name as in \fItypePtr\fR,
+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 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 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;
+in that case \fBTCL_ERROR\fR is returned.
+.PP
+\fBTcl_ConvertToType\fR converts an object from one type to another
+if possible.
+It creates a new internal representation for \fIobjPtr\fR
+appropriate for the target type \fItypePtr\fR
+and sets its \fItypePtr\fR member as determined by calling the
+\fItypePtr->setFromAnyProc\fR routine.
+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
+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 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 {
+ const char *\fIname\fR;
+ Tcl_FreeInternalRepProc *\fIfreeIntRepProc\fR;
+ Tcl_DupInternalRepProc *\fIdupIntRepProc\fR;
+ Tcl_UpdateStringProc *\fIupdateStringProc\fR;
+ Tcl_SetFromAnyProc *\fIsetFromAnyProc\fR;
+} \fBTcl_ObjType\fR;
+.CE
+.SS "THE NAME FIELD"
+.PP
+The \fIname\fR member describes the name of the type, e.g. \fBint\fR.
+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 \fBTcl_SetFromAnyProc\fR(
+ Tcl_Interp *\fIinterp\fR,
+ Tcl_Obj *\fIobjPtr\fR);
+.CE
+.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
+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.
+.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 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 \fBTcl_ConvertToType\fR 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 \fBTcl_UpdateStringProc\fR(
+ 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,
+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.
+.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 \fBTcl_DupInternalRepProc\fR(
+ 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 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 \fBTcl_FreeInternalRepProc\fR(
+ 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.
+.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(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3)
+.SH KEYWORDS
+internal representation, object, object type, string representation, type conversion
diff --git a/library/msgcat/doc/OpenFileChnl.3 b/library/msgcat/doc/OpenFileChnl.3
new file mode 100644
index 0000000..2368492
--- /dev/null
+++ b/library/msgcat/doc/OpenFileChnl.3
@@ -0,0 +1,648 @@
+'\"
+'\" Copyright (c) 1996-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 Tcl_OpenFileChannel 3 8.3 Tcl "Tcl Library Procedures"
+.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_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
+.sp
+Tcl_Channel
+\fBTcl_OpenFileChannel\fR(\fIinterp, fileName, mode, permissions\fR)
+.sp
+Tcl_Channel
+\fBTcl_OpenCommandChannel\fR(\fIinterp, argc, argv, flags\fR)
+.sp
+Tcl_Channel
+\fBTcl_MakeFileChannel\fR(\fIhandle, readOrWrite\fR)
+.sp
+Tcl_Channel
+\fBTcl_GetChannel\fR(\fIinterp, channelName, modePtr\fR)
+.sp
+int
+\fBTcl_GetChannelNames\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_GetChannelNamesEx\fR(\fIinterp, pattern\fR)
+.sp
+void
+\fBTcl_RegisterChannel\fR(\fIinterp, channel\fR)
+.sp
+int
+\fBTcl_UnregisterChannel\fR(\fIinterp, channel\fR)
+.sp
+int
+\fBTcl_DetachChannel\fR(\fIinterp, channel\fR)
+.sp
+int
+\fBTcl_IsStandardChannel\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_Close\fR(\fIinterp, channel\fR)
+.sp
+int
+\fBTcl_ReadChars\fR(\fIchannel, readObjPtr, charsToRead, appendFlag\fR)
+.sp
+int
+\fBTcl_Read\fR(\fIchannel, readBuf, bytesToRead\fR)
+.sp
+int
+\fBTcl_GetsObj\fR(\fIchannel, lineObjPtr\fR)
+.sp
+int
+\fBTcl_Gets\fR(\fIchannel, lineRead\fR)
+.sp
+int
+\fBTcl_Ungets\fR(\fIchannel, input, inputLen, addAtEnd\fR)
+.sp
+int
+\fBTcl_WriteObj\fR(\fIchannel, writeObjPtr\fR)
+.sp
+int
+\fBTcl_WriteChars\fR(\fIchannel, charBuf, bytesToWrite\fR)
+.sp
+int
+\fBTcl_Write\fR(\fIchannel, byteBuf, bytesToWrite\fR)
+.sp
+int
+\fBTcl_ReadRaw\fR(\fIchannel, readBuf, bytesToRead\fR)
+.sp
+int
+\fBTcl_WriteRaw\fR(\fIchannel, byteBuf, bytesToWrite\fR)
+.sp
+int
+\fBTcl_Eof\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_Flush\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_InputBlocked\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_InputBuffered\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_OutputBuffered\fR(\fIchannel\fR)
+.sp
+Tcl_WideInt
+\fBTcl_Seek\fR(\fIchannel, offset, seekMode\fR)
+.sp
+Tcl_WideInt
+\fBTcl_Tell\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_TruncateChannel\fR(\fIchannel, length\fR)
+.sp
+int
+\fBTcl_GetChannelOption\fR(\fIinterp, channel, optionName, optionValue\fR)
+.sp
+int
+\fBTcl_SetChannelOption\fR(\fIinterp, channel, optionName, newValue\fR)
+.sp
+.SH ARGUMENTS
+.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
+The name of a local or network file.
+.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
+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
+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
+Specifies the disposition of the stdio handles in pipeline: OR-ed
+combination of \fBTCL_STDIN\fR, \fBTCL_STDOUT\fR, \fBTCL_STDERR\fR, and
+\fBTCL_ENFORCE_MODE\fR. If \fBTCL_STDIN\fR is set, stdin for the first child
+in the pipe is the pipe channel, otherwise it is the same as the standard
+input of the invoking process; likewise for \fBTCL_STDOUT\fR and
+\fBTCL_STDERR\fR. If \fBTCL_ENFORCE_MODE\fR is not set, then the pipe can
+redirect stdio handles to override the stdio handles for which
+\fBTCL_STDIN\fR, \fBTCL_STDOUT\fR and \fBTCL_STDERR\fR have been set. If it
+is set, then such redirections cause an error.
+.AP ClientData handle in
+Operating system specific handle for I/O to a file. For Unix this is a
+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
+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.
+.AP "const char" *pattern in
+The pattern to match on, passed to Tcl_StringMatch, or NULL.
+.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.
+.AP Tcl_Obj *readObjPtr in/out
+A pointer to a Tcl Object in which to store the characters read from the
+channel.
+.AP int charsToRead in
+The number of characters to read from the channel. If the channel's encoding
+is \fBbinary\fR, this is equivalent to the number of bytes to read from the
+channel.
+.AP int appendFlag in
+If non-zero, data read from the channel will be appended to the object.
+Otherwise, the data will replace the existing contents of the object.
+.AP char *readBuf out
+A buffer in which to store the bytes read from the channel.
+.AP int bytesToRead in
+The number of bytes to read from the channel. The buffer \fIreadBuf\fR must
+be large enough to hold this many bytes.
+.AP Tcl_Obj *lineObjPtr in/out
+A pointer to a Tcl object in which to store the line read from the
+channel. The line read will be appended to the current value of the
+object.
+.AP Tcl_DString *lineRead in/out
+A pointer to a Tcl dynamic string in which to store the line read from the
+channel. Must have been initialized by the caller. The line read will be
+appended to any data already in the dynamic string.
+.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.
+.AP Tcl_Obj *writeObjPtr in
+A pointer to a Tcl Object whose contents will be output to the channel.
+.AP "const char" *charBuf in
+A buffer containing the characters to output to the channel.
+.AP "const char" *byteBuf in
+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.
+.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
+given by \fIseekMode\fR. May be either positive or negative.
+.AP int seekMode in
+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 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
+New value for the option given by \fIoptionName\fR.
+.BE
+.SH DESCRIPTION
+.PP
+The Tcl channel mechanism provides a device-independent and
+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
+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
+channels.
+.PP
+The procedures described in this manual entry comprise the C APIs of the
+generic layer of the channel architecture. For a description of the channel
+driver architecture and how to implement channel drivers for new types of
+channels, see the manual entry for \fBTcl_CreateChannel\fR.
+.SH TCL_OPENFILECHANNEL
+.PP
+\fBTcl_OpenFileChannel\fR opens a file specified by \fIfileName\fR and
+returns a channel handle that can be used to perform input and output on
+the file. This API is modeled after the \fBfopen\fR procedure of
+the Unix standard I/O library.
+The syntax and meaning of all arguments is similar to those
+given in the Tcl \fBopen\fR command when opening a file.
+If an error occurs while opening the channel, \fBTcl_OpenFileChannel\fR
+returns NULL and records a POSIX error code that can be
+retrieved with \fBTcl_GetErrno\fR.
+In addition, if \fIinterp\fR is non-NULL, \fBTcl_OpenFileChannel\fR
+leaves an error message in \fIinterp\fR's result after any error.
+As of Tcl 8.4, the object-based API \fBTcl_FSOpenFileChannel\fR should
+be used in preference to \fBTcl_OpenFileChannel\fR wherever possible.
+.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\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.SH TCL_OPENCOMMANDCHANNEL
+.PP
+\fBTcl_OpenCommandChannel\fR provides a C-level interface to the
+functions of the \fBexec\fR and \fBopen\fR commands.
+It creates a sequence of subprocesses specified
+by the \fIargv\fR and \fIargc\fR arguments and returns a channel that can
+be used to communicate with these subprocesses.
+The \fIflags\fR argument indicates what sort of communication will
+exist with the command pipeline.
+.PP
+If the \fBTCL_STDIN\fR flag is set then the standard input for the
+first subprocess will be tied to the channel: writing to the channel
+will provide input to the subprocess. If \fBTCL_STDIN\fR is not set,
+then standard input for the first subprocess will be the same as this
+application's standard input. If \fBTCL_STDOUT\fR is set then
+standard output from the last subprocess can be read from the channel;
+otherwise it goes to this application's standard output. If
+\fBTCL_STDERR\fR is set, standard error output for all subprocesses is
+returned to the channel and results in an error when the channel is
+closed; otherwise it goes to this application's standard error. If
+\fBTCL_ENFORCE_MODE\fR is not set, then \fIargc\fR and \fIargv\fR can
+redirect the stdio handles to override \fBTCL_STDIN\fR,
+\fBTCL_STDOUT\fR, and \fBTCL_STDERR\fR; if it is set, then it is an
+error for argc and argv to override stdio channels for which
+\fBTCL_STDIN\fR, \fBTCL_STDOUT\fR, and \fBTCL_STDERR\fR have been set.
+.PP
+If an error occurs while opening the channel, \fBTcl_OpenCommandChannel\fR
+returns NULL and records a POSIX error code that can be retrieved with
+\fBTcl_GetErrno\fR.
+In addition, \fBTcl_OpenCommandChannel\fR leaves an error message in
+the interpreter's result if \fIinterp\fR is not NULL.
+.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\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.SH TCL_MAKEFILECHANNEL
+.PP
+\fBTcl_MakeFileChannel\fR makes a \fBTcl_Channel\fR from an existing,
+platform-specific, file handle.
+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\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.SH TCL_GETCHANNEL
+.PP
+\fBTcl_GetChannel\fR returns a channel given the \fIchannelName\fR used to
+create it with \fBTcl_CreateChannel\fR and a pointer to a Tcl interpreter in
+\fIinterp\fR. If a channel by that name is not registered in that interpreter,
+the procedure returns NULL. If the \fImodePtr\fR argument is not NULL, it
+points at an integer variable that will receive an OR-ed combination of
+\fBTCL_READABLE\fR and \fBTCL_WRITABLE\fR describing whether the channel is
+open for reading and writing.
+.PP
+\fBTcl_GetChannelNames\fR and \fBTcl_GetChannelNamesEx\fR write the
+names of the registered channels to the interpreter's result as a
+list object. \fBTcl_GetChannelNamesEx\fR will filter these names
+according to the \fIpattern\fR. If \fIpattern\fR is NULL, then it
+will not do any filtering. The return value is \fBTCL_OK\fR if no
+errors occurred writing to the result, otherwise it is \fBTCL_ERROR\fR,
+and the error message is left in the interpreter's result.
+.SH TCL_REGISTERCHANNEL
+.PP
+\fBTcl_RegisterChannel\fR adds a channel to the set of channels accessible
+in \fIinterp\fR. After this call, Tcl programs executing in that
+interpreter can refer to the channel in input or output operations using
+the name given in the call to \fBTcl_CreateChannel\fR. After this call,
+the channel becomes the property of the interpreter, and the caller should
+not call \fBTcl_Close\fR for the channel; the channel will be closed
+automatically when it is unregistered from the interpreter.
+.PP
+Code executing outside of any Tcl interpreter can call
+\fBTcl_RegisterChannel\fR with \fIinterp\fR as NULL, to indicate that it
+wishes to hold a reference to this channel. Subsequently, the channel can
+be registered in a Tcl interpreter and it will only be closed when the
+matching number of calls to \fBTcl_UnregisterChannel\fR have been made.
+This allows code executing outside of any interpreter to safely hold a
+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. See \fBTcl_StandardChannels\fR for a general treatise about
+standard channels and the behavior of the Tcl library with regard to
+them.
+.SH TCL_UNREGISTERCHANNEL
+.PP
+\fBTcl_UnregisterChannel\fR removes a channel from the set of channels
+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.
+If this operation removed the last registration of the channel in any
+interpreter, the channel is also closed and destroyed.
+.PP
+Code not associated with a Tcl interpreter can call
+\fBTcl_UnregisterChannel\fR with \fIinterp\fR as NULL, to indicate to Tcl
+that it no longer holds a reference to that channel. If this is the last
+reference to the channel, it will now be closed. \fBTcl_UnregisterChannel\fR
+is very similar to \fBTcl_DetachChannel\fR except that it will also
+close the channel if no further references to it exist.
+.SH TCL_DETACHCHANNEL
+.PP
+\fBTcl_DetachChannel\fR removes a channel from the set of channels
+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 (\fBstdout\fR, \fBstderr\fR, \fBstdin\fR), and will return
+\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
+that it no longer holds a reference to that channel. If this is the last
+reference to the channel, unlike \fBTcl_UnregisterChannel\fR,
+it will not be closed.
+.SH TCL_ISSTANDARDCHANNEL
+.PP
+\fBTcl_IsStandardChannel\fR tests whether a channel is one of the
+three standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR.
+If so, it returns 1, otherwise 0.
+.PP
+No attempt is made to check whether the given channel or the standard
+channels are initialized or otherwise valid.
+.SH TCL_CLOSE
+.PP
+\fBTcl_Close\fR destroys the channel \fIchannel\fR, which must denote a
+currently open channel. The channel should not be registered in any
+interpreter when \fBTcl_Close\fR is called. Buffered output is flushed to
+the channel's output device prior to destroying the channel, and any
+buffered input is discarded. If this is a blocking channel, the call does
+not return until all buffered data is successfully sent to the channel's
+output device. If this is a nonblocking channel and there is buffered
+output that cannot be written without blocking, the call returns
+immediately; output is flushed in the background and the channel will be
+closed once all of the buffered data has been output. In this case errors
+during flushing are not reported.
+.PP
+If the channel was closed successfully, \fBTcl_Close\fR returns \fBTCL_OK\fR.
+If an error occurs, \fBTcl_Close\fR returns \fBTCL_ERROR\fR and records a
+POSIX error code that can be retrieved with \fBTcl_GetErrno\fR.
+If the channel is being closed synchronously and an error occurs during
+closing of the channel and \fIinterp\fR is not NULL, an error message is
+left in the interpreter's result.
+.PP
+Note: it is not safe to call \fBTcl_Close\fR on a channel that has been
+registered using \fBTcl_RegisterChannel\fR; see the documentation for
+\fBTcl_RegisterChannel\fR, above, for details. If the channel has ever
+been given as the \fBchan\fR argument in a call to
+\fBTcl_RegisterChannel\fR, you should instead use
+\fBTcl_UnregisterChannel\fR, which will internally call \fBTcl_Close\fR
+when all calls to \fBTcl_RegisterChannel\fR have been matched by
+corresponding calls to \fBTcl_UnregisterChannel\fR.
+.SH "TCL_READCHARS AND TCL_READ"
+.PP
+\fBTcl_ReadChars\fR consumes bytes from \fIchannel\fR, converting the bytes
+to UTF-8 based on the channel's encoding and storing the produced data in
+\fIreadObjPtr\fR's string representation. The return value of
+\fBTcl_ReadChars\fR is the number of characters, up to \fIcharsToRead\fR,
+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
+all characters currently available (non-blocking) or everything until
+eof (blocking mode).
+.PP
+The return value may be smaller than the value to read, indicating that less
+data than requested was available. This is called a \fIshort read\fR. In
+blocking mode, this can only happen on an end-of-file. In nonblocking mode,
+a short read can also occur if there is not enough input currently
+available: \fBTcl_ReadChars\fR returns a short count rather than waiting
+for more data.
+.PP
+If the channel is in blocking mode, a return value of zero indicates an
+end-of-file condition. If the channel is in nonblocking mode, a return
+value of zero indicates either that no input is currently available or an
+end-of-file condition. Use \fBTcl_Eof\fR and \fBTcl_InputBlocked\fR to tell
+which of these conditions actually occurred.
+.PP
+\fBTcl_ReadChars\fR translates the various end-of-line representations into
+the canonical \fB\en\fR internal representation according to the current
+end-of-line recognition mode. End-of-line recognition and the various
+platform-specific modes are described in the manual entry for the Tcl
+\fBfconfigure\fR command.
+.PP
+As a performance optimization, when reading from a channel with the encoding
+\fBbinary\fR, the bytes are not converted to UTF-8 as they are read.
+Instead, they are stored in \fIreadObjPtr\fR's internal representation as a
+byte-array object. The string representation of this object will only be
+constructed if it is needed (e.g., because of a call to
+\fBTcl_GetStringFromObj\fR). In this way, byte-oriented data can be read
+from a channel, manipulated by calling \fBTcl_GetByteArrayFromObj\fR and
+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 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
+\fIreadBuf\fR, performing end-of-line translations on the way. The return value
+of \fBTcl_Read\fR is the number of bytes, up to \fIbytesToRead\fR, written in
+\fIreadBuf\fR. The buffer produced by \fBTcl_Read\fR is not null-terminated.
+Its contents are valid from the zeroth position up to and excluding the
+position indicated by the return value.
+.PP
+\fBTcl_ReadRaw\fR is the same as \fBTcl_Read\fR but does not
+compensate for stacking. While \fBTcl_Read\fR (and the other functions
+in the API) always get their data from the topmost channel in the
+stack the supplied channel is part of, \fBTcl_ReadRaw\fR does
+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 channel below into the transformation.
+.SH "TCL_GETSOBJ AND TCL_GETS"
+.PP
+\fBTcl_GetsObj\fR consumes bytes from \fIchannel\fR, converting the bytes to
+UTF-8 based on the channel's encoding, until a full line of input has been
+seen. If the channel's encoding is \fBbinary\fR, each byte read from the
+channel is treated as an individual Unicode character. All of the
+characters of the line except for the terminating end-of-line character(s)
+are appended to \fIlineObjPtr\fR's string representation. The end-of-line
+character(s) are read and discarded.
+.PP
+If a line was successfully read, the return value is greater than or equal
+to zero and indicates the number of bytes stored in \fIlineObjPtr\fR. If an
+error occurs, \fBTcl_GetsObj\fR returns \-1 and records a POSIX error code
+that can be retrieved with \fBTcl_GetErrno\fR. \fBTcl_GetsObj\fR also
+returns \-1 if the end of the file is reached; the \fBTcl_Eof\fR procedure
+can be used to distinguish an error from an end-of-file condition.
+.PP
+If the channel is in nonblocking mode, the return value can also be \-1 if
+no data was available or the data that was available did not contain an
+end-of-line character. When \-1 is returned, the \fBTcl_InputBlocked\fR
+procedure may be invoked to determine if the channel is blocked because
+of input unavailability.
+.PP
+\fBTcl_Gets\fR is the same as \fBTcl_GetsObj\fR except the resulting
+characters are appended to the dynamic string given by
+\fIlineRead\fR rather than a Tcl object.
+.SH "TCL_UNGETS"
+.PP
+\fBTcl_Ungets\fR is used to add data to the input queue of a channel,
+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
+.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.
+.SH "TCL_WRITECHARS, TCL_WRITEOBJ, AND TCL_WRITE"
+.PP
+\fBTcl_WriteChars\fR accepts \fIbytesToWrite\fR bytes of character data at
+\fIcharBuf\fR. The UTF-8 characters in the buffer are converted to the
+channel's encoding and queued for output to \fIchannel\fR. If
+\fIbytesToWrite\fR is negative, \fBTcl_WriteChars\fR expects \fIcharBuf\fR
+to be null-terminated and it outputs everything up to the null.
+.PP
+Data queued for output may not appear on the output device immediately, due
+to internal buffering. If the data should appear immediately, call
+\fBTcl_Flush\fR after the call to \fBTcl_WriteChars\fR, or set the
+\fB\-buffering\fR option on the channel to \fBnone\fR. If you wish the data
+to appear as soon as a complete line is accepted for output, set the
+\fB\-buffering\fR option on the channel to \fBline\fR mode.
+.PP
+The return value of \fBTcl_WriteChars\fR is a count of how many bytes were
+accepted for output to the channel. This is either greater than zero to
+indicate success or \-1 to indicate that an error occurred. If an error
+occurs, \fBTcl_WriteChars\fR records a POSIX error code that may be
+retrieved with \fBTcl_GetErrno\fR.
+.PP
+Newline characters in the output data are translated to platform-specific
+end-of-line sequences according to the \fB\-translation\fR option for the
+channel. This is done even if the channel has no encoding.
+.PP
+\fBTcl_WriteObj\fR is similar to \fBTcl_WriteChars\fR except it
+accepts a Tcl object whose contents will be output to the channel. The
+UTF-8 characters in \fIwriteObjPtr\fR's string representation are converted
+to the channel's encoding and queued for output to \fIchannel\fR.
+As a performance optimization, when writing to a channel with the encoding
+\fBbinary\fR, UTF-8 characters are not converted as they are written.
+Instead, the bytes in \fIwriteObjPtr\fR's internal representation as a
+byte-array object are written to the channel. The byte-array representation
+of the object will be constructed if it is needed. In this way,
+byte-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 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
+\fIbyteBuf\fR and queues them for output to \fIchannel\fR. If
+\fIbytesToWrite\fR is negative, \fBTcl_Write\fR expects \fIbyteBuf\fR to be
+null-terminated and it outputs everything up to the null.
+.PP
+\fBTcl_WriteRaw\fR is the same as \fBTcl_Write\fR but does not
+compensate for stacking. While \fBTcl_Write\fR (and the other
+functions in the API) always feed their input to the topmost channel
+in the stack the supplied channel is part of, \fBTcl_WriteRaw\fR does
+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.
+.SH TCL_FLUSH
+.PP
+\fBTcl_Flush\fR causes all of the buffered output data for \fIchannel\fR
+to be written to its underlying file or device as soon as possible.
+If the channel is in blocking mode, the call does not return until
+all the buffered data has been sent to the channel or some error occurred.
+The call returns immediately if the channel is nonblocking; it starts
+a background flush that will write the buffered data to the channel
+eventually, as fast as the channel is able to absorb it.
+.PP
+The return value is normally \fBTCL_OK\fR.
+If an error occurs, \fBTcl_Flush\fR returns \fBTCL_ERROR\fR and
+records a POSIX error code that can be retrieved with \fBTcl_GetErrno\fR.
+.SH TCL_SEEK
+.PP
+\fBTcl_Seek\fR moves the access point in \fIchannel\fR where subsequent
+data will be read or written. Buffered output is flushed to the channel and
+buffered input is discarded, prior to the seek operation.
+.PP
+\fBTcl_Seek\fR normally returns the new access point.
+If an error occurs, \fBTcl_Seek\fR returns \-1 and records a POSIX error
+code that can be retrieved with \fBTcl_GetErrno\fR.
+After an error, the access point may or may not have been moved.
+.SH TCL_TELL
+.PP
+\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
+\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.
+.SH TCL_GETCHANNELOPTION
+.PP
+\fBTcl_GetChannelOption\fR retrieves, in \fIoptionValue\fR, the value of one of
+the options currently in effect for a channel, or a list of all options and
+their values. The \fIchannel\fR argument identifies the channel for which
+to query an option or retrieve all options and their values.
+If \fIoptionName\fR is not NULL, it is the name of the
+option to query; the option's value is copied to the Tcl dynamic string
+denoted by \fIoptionValue\fR. If
+\fIoptionName\fR is NULL, the function stores an alternating list of option
+names and their values in \fIoptionValue\fR, using a series of calls to
+\fBTcl_DStringAppendElement\fR. The various preexisting options and
+their possible values are described in the manual entry for the Tcl
+\fBfconfigure\fR command. Other options can be added by each channel type.
+These channel type specific options are described in the manual entry for
+the Tcl command that creates a channel of that type; for example, the
+additional options for TCP based channels are described in the manual entry
+for the Tcl \fBsocket\fR command.
+The procedure normally returns \fBTCL_OK\fR. If an error occurs, it returns
+\fBTCL_ERROR\fR and calls \fBTcl_SetErrno\fR to store an appropriate POSIX
+error code.
+.SH TCL_SETCHANNELOPTION
+.PP
+\fBTcl_SetChannelOption\fR sets a new value \fInewValue\fR
+for an option \fIoptionName\fR on \fIchannel\fR.
+The procedure normally returns \fBTCL_OK\fR. If an error occurs,
+it returns \fBTCL_ERROR\fR; in addition, if \fIinterp\fR is non-NULL,
+\fBTcl_SetChannelOption\fR leaves an error message in the interpreter's result.
+.SH TCL_EOF
+.PP
+\fBTcl_Eof\fR returns a nonzero value if \fIchannel\fR encountered
+an end of file during the last input operation.
+.SH TCL_INPUTBLOCKED
+.PP
+\fBTcl_InputBlocked\fR returns a nonzero value if \fIchannel\fR is in
+nonblocking mode and the last input operation returned less data than
+requested because there was insufficient data available.
+The call always returns zero if the channel is in blocking mode.
+.SH TCL_INPUTBUFFERED
+.PP
+\fBTcl_InputBuffered\fR returns the number of bytes of input currently
+buffered in the internal buffers for a channel. If the channel is not open
+for reading, this function always returns zero.
+.SH TCL_OUTPUTBUFFERED
+.PP
+\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.
+.SH "PLATFORM ISSUES"
+.PP
+The handles returned from \fBTcl_GetChannelHandle\fR depend on the
+platform and the channel type. On Unix platforms, the handle is
+always a Unix file descriptor as returned from the \fBopen\fR system
+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.
+.SH "SEE ALSO"
+DString(3), fconfigure(n), filename(n), fopen(3), Tcl_CreateChannel(3)
+.SH KEYWORDS
+access point, blocking, buffered I/O, channel, channel driver, end of file,
+flush, input, nonblocking, output, read, seek, write
diff --git a/library/msgcat/doc/OpenTcp.3 b/library/msgcat/doc/OpenTcp.3
new file mode 100644
index 0000000..78ac70b
--- /dev/null
+++ b/library/msgcat/doc/OpenTcp.3
@@ -0,0 +1,169 @@
+'\"
+'\" Copyright (c) 1996-7 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_OpenTcpClient 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_OpenTcpClient, Tcl_MakeTcpClientChannel, Tcl_OpenTcpServer \- procedures to open channels using TCP sockets
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h> \fR
+.sp
+Tcl_Channel
+\fBTcl_OpenTcpClient\fR(\fIinterp, port, host, myaddr, myport, async\fR)
+.sp
+Tcl_Channel
+\fBTcl_MakeTcpClientChannel\fR(\fIsock\fR)
+.sp
+Tcl_Channel
+\fBTcl_OpenTcpServer\fR(\fIinterp, port, myaddr, proc, clientData\fR)
+.sp
+.SH ARGUMENTS
+.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
+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
+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.
+.AP int async in
+If nonzero, the client socket is connected asynchronously to the server.
+.AP ClientData sock in
+Platform-specific handle for client TCP socket.
+.AP Tcl_TcpAcceptProc *proc in
+Pointer to a procedure to invoke each time a new connection is
+accepted via the socket.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+These functions are convenience procedures for creating
+channels that communicate over TCP sockets.
+The operations on a channel
+are described in the manual entry for \fBTcl_OpenFileChannel\fR.
+.SS TCL_OPENTCPCLIENT
+.PP
+\fBTcl_OpenTcpClient\fR opens a client TCP socket connected to a \fIport\fR
+on a specific \fIhost\fR, and returns a channel that can be used to
+communicate with the server. The host to connect to can be specified either
+as a domain name style name (e.g. \fBwww.sunlabs.com\fR), or as a string
+containing the alphanumeric representation of its four-byte address (e.g.
+\fB127.0.0.1\fR). Use the string \fBlocalhost\fR to connect to a TCP socket on
+the host on which the function is invoked.
+.PP
+The \fImyaddr\fR and \fImyport\fR arguments allow a client to specify an
+address for the local end of the connection. If \fImyaddr\fR is NULL, then
+an interface is chosen automatically by the operating system.
+If \fImyport\fR is 0, then a port number is chosen at random by
+the operating system.
+.PP
+If \fIasync\fR is zero, the call to \fBTcl_OpenTcpClient\fR returns only
+after the client socket has either successfully connected to the server, or
+the attempted connection has failed.
+If \fIasync\fR is nonzero the socket is connected asynchronously and the
+returned channel may not yet be connected to the server when the call to
+\fBTcl_OpenTcpClient\fR returns. If the channel is in blocking mode and an
+input or output operation is done on the channel before the connection is
+completed or fails, that operation will wait until the connection either
+completes successfully or fails. If the channel is in nonblocking mode, the
+input or output operation will return immediately and a subsequent call to
+\fBTcl_InputBlocked\fR on the channel will return nonzero.
+.PP
+The returned channel is opened for reading and writing.
+If an error occurs in opening the socket, \fBTcl_OpenTcpClient\fR returns
+NULL and records a POSIX error code that can be retrieved
+with \fBTcl_GetErrno\fR.
+In addition, if \fIinterp\fR is non-NULL, an error message
+is left in the interpreter's result.
+.PP
+The newly created channel is not registered in the supplied interpreter; to
+register it, use \fBTcl_RegisterChannel\fR.
+If one of the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.SS TCL_MAKETCPCLIENTCHANNEL
+.PP
+\fBTcl_MakeTcpClientChannel\fR creates a \fBTcl_Channel\fR around an
+existing, platform specific, handle for a client TCP socket.
+.PP
+The newly created channel is not registered in the supplied interpreter; to
+register it, use \fBTcl_RegisterChannel\fR.
+If one of the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.SS TCL_OPENTCPSERVER
+.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\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:
+.PP
+.CS
+typedef void \fBTcl_TcpAcceptProc\fR(
+ 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\fR
+will contain the client's port number.
+The new channel
+is opened for both input and output.
+If \fIproc\fR raises an error, the connection is closed automatically.
+\fIProc\fR has no return value, but if it wishes to reject the
+connection it can close \fIchannel\fR.
+.PP
+\fBTcl_OpenTcpServer\fR normally returns a pointer to a channel
+representing the server socket.
+If an error occurs, \fBTcl_OpenTcpServer\fR returns NULL and
+records a POSIX error code that can be retrieved with \fBTcl_GetErrno\fR.
+In addition, if the interpreter is non-NULL, an error message
+is left in the interpreter's result.
+.PP
+The channel returned by \fBTcl_OpenTcpServer\fR cannot be used for
+either input or output.
+It is simply a handle for the socket used to accept connections.
+The caller can close the channel to shut down the server and disallow
+further connections from new clients.
+.PP
+TCP server channels operate correctly only in applications that dispatch
+events through \fBTcl_DoOneEvent\fR or through Tcl commands such as
+\fBvwait\fR; otherwise Tcl will never notice that a connection request from
+a remote client is pending.
+.PP
+The newly created channel is not registered in the supplied interpreter; to
+register it, use \fBTcl_RegisterChannel\fR.
+If one of the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.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.
+.SH "SEE ALSO"
+Tcl_OpenFileChannel(3), Tcl_RegisterChannel(3), vwait(n)
+.SH KEYWORDS
+channel, client, server, socket, TCP
diff --git a/library/msgcat/doc/Panic.3 b/library/msgcat/doc/Panic.3
new file mode 100644
index 0000000..48aed2b
--- /dev/null
+++ b/library/msgcat/doc/Panic.3
@@ -0,0 +1,89 @@
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_Panic 3 8.4 Tcl "Tcl Library Procedures"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_Panic, Tcl_PanicVA, Tcl_SetPanicProc \- report fatal error and abort
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_Panic\fR(\fIformat\fR, \fIarg\fR, \fIarg\fR, \fI...\fR)
+.sp
+void
+\fBTcl_PanicVA\fR(\fIformat\fR, \fIargList\fR)
+.sp
+void
+\fBTcl_SetPanicProc\fR(\fIpanicProc\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_PanicProc *panicProc
+.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 \fBva_start\fR,
+and cleared using \fBva_end\fR.
+.AP Tcl_PanicProc *panicProc in
+Procedure to report fatal error message and abort.
+.BE
+.SH DESCRIPTION
+.PP
+When the Tcl library detects that its internal data structures are in an
+inconsistent state, or that its C procedures have been called in a
+manner inconsistent with their documentation, it calls \fBTcl_Panic\fR
+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 built-in Tcl command
+\fBformat\fR.
+.PP
+In a freshly loaded Tcl library, \fBTcl_Panic\fR prints the formatted
+error message to the standard error file of the process, and then
+calls \fBabort\fR to terminate the process. \fBTcl_Panic\fR does not
+return. On Windows, when a debugger is running, the formatted error
+message is sent to the debugger in stead. If the windows executable
+does not have a stderr channel (e.g. \fBwish.exe\fR), then a
+system dialog box is used to display the panic message.
+.PP
+\fBTcl_SetPanicProc\fR may be used to modify the behavior of
+\fBTcl_Panic\fR. The \fIpanicProc\fR argument should match the
+type \fBTcl_PanicProc\fR:
+.PP
+.CS
+typedef void \fBTcl_PanicProc\fR(
+ const char *\fBformat\fR,
+ \fBarg\fR, \fBarg\fR,...);
+.CE
+.PP
+After \fBTcl_SetPanicProc\fR returns, any future calls to
+\fBTcl_Panic\fR will call \fIpanicProc\fR, passing along the
+\fIformat\fR and \fIarg\fR arguments. \fIpanicProc\fR should avoid
+making calls into the Tcl library, or into other libraries that may
+call the Tcl library, since the original call to \fBTcl_Panic\fR
+indicates the Tcl library is not in a state of reliable operation.
+.PP
+The typical use of \fBTcl_SetPanicProc\fR arranges for the error message
+to be displayed or reported in a manner more suitable for the
+application or the platform.
+.PP
+Although the primary callers of \fBTcl_Panic\fR are the procedures of
+the Tcl library, \fBTcl_Panic\fR is a public function and may be called
+by any extension or application that wishes to abort the process and
+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.
+.SH "SEE ALSO"
+abort(3), printf(3), exec(n), format(n)
+.SH KEYWORDS
+abort, fatal, error
diff --git a/library/msgcat/doc/ParseArgs.3 b/library/msgcat/doc/ParseArgs.3
new file mode 100644
index 0000000..dd33830
--- /dev/null
+++ b/library/msgcat/doc/ParseArgs.3
@@ -0,0 +1,198 @@
+'\"
+'\" Copyright (c) 2008 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_ParseArgsObjv 3 8.6 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_ParseArgsObjv \- parse arguments according to a tabular description
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_ParseArgsObjv\fR(\fIinterp, argTable, objcPtr, objv, remObjv\fR)
+.SH ARGUMENTS
+.AS "const Tcl_ArgvInfo" ***remObjv in/out
+.AP Tcl_Interp *interp out
+Where to store error messages.
+.AP "const Tcl_ArgvInfo" *argTable in
+Pointer to array of option descriptors.
+.AP int *objcPtr in/out
+A pointer to variable holding number of arguments in \fIobjv\fR. Will be
+modified to hold number of arguments left in the unprocessed argument list
+stored in \fIremObjv\fR.
+.AP "Tcl_Obj *const" *objv in
+The array of arguments to be parsed.
+.AP Tcl_Obj ***remObjv out
+Pointer to a variable that will hold the array of unprocessed arguments.
+Should be NULL if no return of unprocessed arguments is required. If
+\fIobjcPtr\fR is updated to a non-zero value, the array returned through this
+must be deallocated using \fBckfree\fR.
+.BE
+.SH DESCRIPTION
+.PP
+The \fBTcl_ParseArgsObjv\fR function provides a system for parsing argument
+lists of the form
+.QW "\fB\-someName \fIsomeValue\fR ..." .
+Such argument lists are commonly found both in the arguments to a program and
+in the arguments to an individual Tcl command. This parser assumes that the
+order of the arguments does not matter, other than in so far as later copies
+of a duplicated option overriding earlier ones.
+.PP
+The argument array is described by the \fIobjcPtr\fR and \fIobjv\fR
+parameters, and an array of unprocessed arguments is returned through the
+\fIobjcPtr\fR and \fIremObjv\fR parameters; if no return of unprocessed
+arguments is desired, the \fIremObjv\fR parameter should be NULL. If any
+problems happen, including if the
+.QW "generate help"
+option is selected, an error message is left in the interpreter result and
+TCL_ERROR is returned. Otherwise, the interpreter result is left unchanged and
+TCL_OK is returned.
+.PP
+The collection of arguments to be parsed is described by the \fIargTable\fR
+parameter. This points to a table of descriptor structures that is terminated
+by an entry with the \fItype\fR field set to TCL_ARGV_END. As convenience, the
+following prototypical entries are provided:
+.TP
+\fBTCL_ARGV_AUTO_HELP\fR
+.
+Enables the argument processor to provide help when passed the argument
+.QW \fB\-help\fR .
+.TP
+\fBTCL_ARGV_AUTO_REST\fR
+.
+Instructs the argument processor that arguments after
+.QW \fB\-\-\fR
+are to be unprocessed.
+.TP
+\fBTCL_ARGV_TABLE_END\fR
+.
+Marks the end of the table of argument descriptors.
+.SS "ARGUMENT DESCRIPTOR ENTRIES"
+.PP
+Each entry of the argument descriptor table must be a structure of type
+\fBTcl_ArgvInfo\fR. The structure is defined as this:
+.PP
+.CS
+typedef struct {
+ int \fItype\fR;
+ const char *\fIkeyStr\fR;
+ void *\fIsrcPtr\fR;
+ void *\fIdstPtr\fR;
+ const char *\fIhelpStr\fR;
+ ClientData \fIclientData\fR;
+} \fBTcl_ArgvInfo\fR;
+.CE
+.PP
+The \fIkeyStr\fR field contains the name of the option; by convention, this
+will normally begin with a
+.QW \fB\-\fR
+character. The \fItype\fR, \fIsrcPtr\fR, \fIdstPtr\fR and \fIclientData\fR
+fields describe the interpretation of the value of the argument, as described
+below. The \fIhelpStr\fR field gives some text that is used to provide help to
+users when they request it.
+.PP
+As noted above, the \fItype\fR field is used to describe the interpretation of
+the argument's value. The following values are acceptable values for
+\fItype\fR:
+.TP
+\fBTCL_ARGV_CONSTANT\fR
+.
+The argument does not take any following value argument. If this argument is
+present, the int pointed to by the \fIsrcPtr\fR field is copied to the
+\fIdstPtr\fR field. The \fIclientData\fR field is ignored.
+.TP
+\fBTCL_ARGV_END\fR
+.
+This value marks the end of all option descriptors in the table. All other
+fields are ignored.
+.TP
+\fBTCL_ARGV_FLOAT\fR
+.
+This argument takes a following floating point value argument. The value (once
+parsed by \fBTcl_GetDoubleFromObj\fR) will be stored as a double-precision
+value in the variable pointed to by the \fIdstPtr\fR field. The \fIsrcPtr\fR
+and \fIclientData\fR fields are ignored.
+.TP
+\fBTCL_ARGV_FUNC\fR
+.
+This argument optionally takes a following value argument; it is up to the
+handler callback function passed in \fIsrcPtr\fR to decide. That function will
+have the following signature:
+.RS
+.PP
+.CS
+typedef int (\fBTcl_ArgvFuncProc\fR)(
+ ClientData \fIclientData\fR,
+ Tcl_Obj *\fIobjPtr\fR,
+ void *\fIdstPtr\fR);
+.CE
+.PP
+The result is a boolean value indicating whether to consume the following
+argument. The \fIclientData\fR is the value from the table entry, the
+\fIobjPtr\fR is the object that represents the following argument or NULL if
+there are no following arguments at all, and the \fIdstPtr\fR argument to the
+\fBTcl_ArgvFuncProc\fR is the location to write the parsed value to.
+.RE
+.TP
+\fBTCL_ARGV_GENFUNC\fR
+.
+This argument takes zero or more following arguments; the handler callback
+function passed in \fIsrcPtr\fR returns how many (or a negative number to
+signal an error, in which case it should also set the interpreter result). The
+function will have the following signature:
+.RS
+.PP
+.CS
+typedef int (\fBTcl_ArgvGenFuncProc\fR)(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ int \fIobjc\fR,
+ Tcl_Obj *const *\fIobjv\fR,
+ void *\fIdstPtr\fR);
+.CE
+.PP
+The \fIclientData\fR is the value from the table entry, the \fIinterp\fR is
+where to store any error messages, the \fIkeyStr\fR is the name of the
+argument, \fIobjc\fR and \fIobjv\fR describe an array of all the remaining
+arguments, and \fIdstPtr\fR argument to the \fBTcl_ArgvGenFuncProc\fR is the
+location to write the parsed value (or values) to.
+.RE
+.TP
+\fBTCL_ARGV_HELP\fR
+.
+This special argument does not take any following value argument, but instead
+causes \fBTcl_ParseArgsObjv\fR to generate an error message describing the
+arguments supported. All other fields except the \fIhelpStr\fR field are
+ignored.
+.TP
+\fBTCL_ARGV_INT\fR
+.
+This argument takes a following integer value argument. The value (once parsed
+by \fBTcl_GetIntFromObj\fR) will be stored as an int in the variable pointed
+to by the \fIdstPtr\fR field. The \fIsrcPtr\fR field is ignored.
+.TP
+\fBTCL_ARGV_REST\fR
+.
+This special argument does not take any following value argument, but instead
+marks all following arguments to be left unprocessed. The \fIsrcPtr\fR,
+\fIdstPtr\fR and \fIclientData\fR fields are ignored.
+.TP
+\fBTCL_ARGV_STRING\fR
+.
+This argument takes a following string value argument. A pointer to the string
+will be stored at \fIdstPtr\fR; the string inside will have a lifetime linked
+to the lifetime of the string representation of the argument object that it
+came from, and so should be copied if it needs to be retained. The
+\fIsrcPtr\fR and \fIclientData\fR fields are ignored.
+.SH "SEE ALSO"
+Tcl_GetIndexFromObj(3), Tcl_Main(3), Tcl_CreateObjCommand(3)
+.SH KEYWORDS
+argument, parse
+'\" Local Variables:
+'\" fill-column: 78
+'\" End:
diff --git a/library/msgcat/doc/ParseCmd.3 b/library/msgcat/doc/ParseCmd.3
new file mode 100644
index 0000000..f3b3aeb
--- /dev/null
+++ b/library/msgcat/doc/ParseCmd.3
@@ -0,0 +1,467 @@
+'\"
+'\" 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 Tcl_ParseCommand 3 8.3 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_ParseCommand, Tcl_ParseExpr, Tcl_ParseBraces, Tcl_ParseQuotedString, Tcl_ParseVarName, Tcl_ParseVar, Tcl_FreeParse, Tcl_EvalTokens, Tcl_EvalTokensStandard \- parse Tcl scripts and expressions
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_ParseCommand\fR(\fIinterp, start, numBytes, nested, parsePtr\fR)
+.sp
+int
+\fBTcl_ParseExpr\fR(\fIinterp, start, numBytes, parsePtr\fR)
+.sp
+int
+\fBTcl_ParseBraces\fR(\fIinterp, start, numBytes, parsePtr, append, termPtr\fR)
+.sp
+int
+\fBTcl_ParseQuotedString\fR(\fIinterp, start, numBytes, parsePtr, append, termPtr\fR)
+.sp
+int
+\fBTcl_ParseVarName\fR(\fIinterp, start, numBytes, parsePtr, append\fR)
+.sp
+const char *
+\fBTcl_ParseVar\fR(\fIinterp, start, termPtr\fR)
+.sp
+\fBTcl_FreeParse\fR(\fIusedParsePtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_EvalTokens\fR(\fIinterp, tokenPtr, numTokens\fR)
+.sp
+int
+\fBTcl_EvalTokensStandard\fR(\fIinterp, tokenPtr, numTokens\fR)
+.SH ARGUMENTS
+.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;
+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" *start in
+Pointer to first character in string to parse.
+.AP int numBytes in
+Number of bytes in string to parse, not including any terminating null
+character. If less than 0 then the script consists of all characters
+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,
+close brackets have no special meaning.
+.AP int append in
+Non-zero means that \fI*parsePtr\fR already contains valid tokens; the new
+tokens should be appended to those already present. Zero means that
+\fI*parsePtr\fR is uninitialized; any information in it is ignored.
+This argument is normally 0.
+.AP Tcl_Parse *parsePtr out
+Points to structure to fill in with information about the parsed
+command, expression, variable name, etc.
+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
+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
+just after the terminating character (the close-brace, the last
+character of the variable name, or the close-quote (respectively))
+if the parse was successful.
+.AP Tcl_Parse *usedParsePtr in
+Points to structure that was filled in by a previous call to
+\fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseVarName\fR, etc.
+.BE
+.SH DESCRIPTION
+.PP
+These procedures parse Tcl commands or portions of Tcl commands such as
+expressions or references to variables.
+Each procedure takes a pointer to a script (or portion thereof)
+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\fR's result
+(if \fIinterp\fR is not NULL),
+and leave nothing in \fIparsePtr\fR.
+.PP
+\fBTcl_ParseCommand\fR is a procedure that parses Tcl
+scripts. Given a pointer to a script, it
+parses the first command from the script. If the command was parsed
+successfully, \fBTcl_ParseCommand\fR returns \fBTCL_OK\fR and fills in the
+structure pointed to by \fIparsePtr\fR with information about the
+structure of the command (see below for details).
+If an error occurred in parsing the command then
+\fBTCL_ERROR\fR is returned, an error message is left in \fIinterp\fR's
+result, and no information is left at \fI*parsePtr\fR.
+.PP
+\fBTcl_ParseExpr\fR parses Tcl expressions.
+Given a pointer to a script containing an expression,
+\fBTcl_ParseExpr\fR parses the expression.
+If the expression was parsed successfully,
+\fBTcl_ParseExpr\fR returns \fBTCL_OK\fR and fills in the
+structure pointed to by \fIparsePtr\fR with information about the
+structure of the expression (see below for details).
+If an error occurred in parsing the command then
+\fBTCL_ERROR\fR is returned, an error message is left in \fIinterp\fR's
+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 \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
+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
+in the location given by \fI*termPtr\fR.
+If an error occurs while parsing the string
+then \fBTCL_ERROR\fR is returned,
+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 \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\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,
+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
+\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 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 \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
+\fIinterp\fR's result.
+.PP
+The information left at \fI*parsePtr\fR
+by \fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseBraces\fR,
+\fBTcl_ParseQuotedString\fR, and \fBTcl_ParseVarName\fR
+may include dynamically allocated memory.
+If these five parsing procedures return \fBTCL_OK\fR
+then the caller must invoke \fBTcl_FreeParse\fR to release
+the storage at \fI*parsePtr\fR.
+These procedures ignore any existing information in
+\fI*parsePtr\fR (unless \fIappend\fR is non-zero),
+so if repeated calls are being made to any of them
+then \fBTcl_FreeParse\fR must be invoked once after each call.
+.PP
+\fBTcl_EvalTokensStandard\fR evaluates a sequence of parse tokens from
+a Tcl_Parse structure. The tokens typically consist
+of all the tokens in a word or all the tokens that make up the index for
+a reference to an array variable. \fBTcl_EvalTokensStandard\fR performs the
+substitutions requested by the tokens and concatenates the
+resulting values.
+The return value from \fBTcl_EvalTokensStandard\fR is a Tcl completion
+code with one of the values \fBTCL_OK\fR, \fBTCL_ERROR\fR,
+\fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR, or possibly
+some other integer value originating in an extension.
+In addition, a result value or error message is left in \fIinterp\fR's
+result; it can be retrieved using \fBTcl_GetObjResult\fR.
+.PP
+\fBTcl_EvalTokens\fR differs from \fBTcl_EvalTokensStandard\fR only in
+the return convention used: it returns the result in a new Tcl_Obj.
+The reference count of the object returned as result has been
+incremented, so the caller must
+invoke \fBTcl_DecrRefCount\fR when it is finished with the object.
+If an error or other exception occurs while evaluating the tokens
+(such as a reference to a non-existent variable) then the return value
+is NULL and an error message is left in \fIinterp\fR's result. The use
+of \fBTcl_EvalTokens\fR is deprecated.
+.SH "TCL_PARSE STRUCTURE"
+.PP
+\fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseBraces\fR,
+\fBTcl_ParseQuotedString\fR, and \fBTcl_ParseVarName\fR
+return parse information in two data structures, Tcl_Parse and Tcl_Token:
+.PP
+.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;
+ ...
+} \fBTcl_Parse\fR;
+
+typedef struct Tcl_Token {
+ int \fItype\fR;
+ const char *\fIstart\fR;
+ int \fIsize\fR;
+ int \fInumComponents\fR;
+} \fBTcl_Token\fR;
+.CE
+.PP
+The first five fields of a Tcl_Parse structure
+are filled in only by \fBTcl_ParseCommand\fR.
+These fields are not used by the other parsing procedures.
+.PP
+\fBTcl_ParseCommand\fR fills in a Tcl_Parse structure
+with information that describes one Tcl command and any comments that
+precede the command.
+If there are comments,
+the \fIcommentStart\fR field points to the \fB#\fR character that begins
+the first comment and \fIcommentSize\fR indicates the number of bytes
+in all of the comments preceding the command, including the newline
+character that terminates the last comment.
+If the command is not preceded by any comments, \fIcommentSize\fR is 0.
+\fBTcl_ParseCommand\fR also sets the \fIcommandStart\fR field
+to point to the first character of the first
+word in the command (skipping any comments and leading space) and
+\fIcommandSize\fR gives the total number of bytes in the command,
+including the character pointed to by \fIcommandStart\fR up to and
+including the newline, close bracket, or semicolon character that
+terminates the command. The \fInumWords\fR field gives the
+total number of words in the command.
+.PP
+All parsing procedures set the remaining fields,
+\fItokenPtr\fR and \fInumTokens\fR.
+The \fItokenPtr\fR field points to the first in an array of Tcl_Token
+structures that describe the components of the entity being parsed.
+The \fInumTokens\fR field gives the total number of tokens
+present in the array.
+Each token contains four fields.
+The \fItype\fR field selects one of several token types
+that are described below. The \fIstart\fR field
+points to the first character in the token and the \fIsize\fR field
+gives the total number of characters in the token. Some token types,
+such as \fBTCL_TOKEN_WORD\fR and \fBTCL_TOKEN_VARIABLE\fR, consist of
+several component tokens, which immediately follow the parent token;
+the \fInumComponents\fR field describes how many of these there are.
+The \fItype\fR field has one of the following values:
+.TP 20
+\fBTCL_TOKEN_WORD\fR
+.
+This token ordinarily describes one word of a command
+but it may also describe a quoted or braced string in an expression.
+The token describes a component of the script that is
+the result of concatenating together a sequence of subcomponents,
+each described by a separate subtoken.
+The token starts with the first non-blank
+character of the component (which may be a double-quote or open brace)
+and includes all characters in the component up to but not including the
+space, semicolon, close bracket, close quote, or close brace that
+terminates the component. The \fInumComponents\fR field counts the total
+number of sub-tokens that make up the word, including sub-tokens
+of \fBTCL_TOKEN_VARIABLE\fR and \fBTCL_TOKEN_BS\fR tokens.
+.TP
+\fBTCL_TOKEN_SIMPLE_WORD\fR
+.
+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
+.
+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.
+.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.
+.TP
+\fBTCL_TOKEN_BS\fR
+.
+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 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
+see its tokens).
+.TP
+\fBTCL_TOKEN_VARIABLE\fR
+.
+The token describes a variable substitution, including the
+\fB$\fR, variable name, and array index (if there is one) up through the
+close parenthesis that terminates the index. This token is followed
+by one or more additional tokens that describe the variable name and
+array index. If \fInumComponents\fR is 1 then the variable is a
+scalar and the next token is a \fBTCL_TOKEN_TEXT\fR token that gives the
+variable name. If \fInumComponents\fR is greater than 1 then the
+variable is an array: the first sub-token is a \fBTCL_TOKEN_TEXT\fR
+token giving the array name and the remaining sub-tokens are
+\fBTCL_TOKEN_TEXT\fR, \fBTCL_TOKEN_BS\fR, \fBTCL_TOKEN_COMMAND\fR, and
+\fBTCL_TOKEN_VARIABLE\fR tokens that must be concatenated to produce the
+array index. The \fInumComponents\fR field includes nested sub-tokens
+that are part of \fBTCL_TOKEN_VARIABLE\fR tokens in the array index.
+.TP
+\fBTCL_TOKEN_SUB_EXPR\fR
+.
+The token describes one subexpression of an expression
+(or an entire expression).
+A subexpression may consist of a value
+such as an integer literal, variable substitution,
+or parenthesized subexpression;
+it may also consist of an operator and its operands.
+The token starts with the first non-blank character of the subexpression
+up to but not including the space, brace, close-paren, or bracket
+that terminates the subexpression.
+This token is followed by one or more additional tokens
+that describe the subexpression.
+If the first sub-token after the \fBTCL_TOKEN_SUB_EXPR\fR token
+is a \fBTCL_TOKEN_OPERATOR\fR token,
+the subexpression consists of an operator and its token operands.
+If the operator has no operands, the subexpression consists of
+just the \fBTCL_TOKEN_OPERATOR\fR token.
+Each operand is described by a \fBTCL_TOKEN_SUB_EXPR\fR token.
+Otherwise, the subexpression is a value described by
+one of the token types \fBTCL_TOKEN_WORD\fR, \fBTCL_TOKEN_TEXT\fR,
+\fBTCL_TOKEN_BS\fR, \fBTCL_TOKEN_COMMAND\fR,
+\fBTCL_TOKEN_VARIABLE\fR, and \fBTCL_TOKEN_SUB_EXPR\fR.
+The \fInumComponents\fR field
+counts the total number of sub-tokens that make up the subexpression;
+this includes the sub-tokens for any nested \fBTCL_TOKEN_SUB_EXPR\fR tokens.
+.TP
+\fBTCL_TOKEN_OPERATOR\fR
+.
+The token describes one operator of an expression
+such as \fB&&\fR or \fBhypot\fR.
+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
+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
+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,
+the \fBTCL_TOKEN_OPERATOR\fR token will give its name and
+the following \fBTCL_TOKEN_SUB_EXPR\fR tokens will describe
+its operands;
+if there are no operands (as with \fBrand\fR),
+no \fBTCL_TOKEN_SUB_EXPR\fR tokens follow.
+There is one trinary operator, \fB?\fR,
+that appears in if-then-else subexpressions
+such as \fIx\fB?\fIy\fB:\fIz\fR;
+in this case, the \fB?\fR \fBTCL_TOKEN_OPERATOR\fR token
+is followed by three \fBTCL_TOKEN_SUB_EXPR\fR tokens for the operands
+\fIx\fR, \fIy\fR, and \fIz\fR.
+The \fInumComponents\fR field for a \fBTCL_TOKEN_OPERATOR\fR token
+is always 0.
+.PP
+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 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
+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.
+.PP
+After \fBTcl_ParseExpr\fR returns, the first token pointed to by
+the \fItokenPtr\fR field of the
+Tcl_Parse structure always has type \fBTCL_TOKEN_SUB_EXPR\fR.
+It is followed by the sub-tokens that must be evaluated
+to produce the value of the expression.
+Only the token information in the Tcl_Parse structure
+is modified: the \fIcommentStart\fR, \fIcommentSize\fR,
+\fIcommandStart\fR, and \fIcommandSize\fR fields are not modified
+by \fBTcl_ParseExpr\fR.
+.PP
+After \fBTcl_ParseBraces\fR returns,
+the array of tokens pointed to by the \fItokenPtr\fR field of the
+Tcl_Parse structure will contain a single \fBTCL_TOKEN_TEXT\fR token
+if the braced string does not contain any backslash-newlines.
+If the string does contain backslash-newlines,
+the array of tokens will contain one or more
+\fBTCL_TOKEN_TEXT\fR or \fBTCL_TOKEN_BS\fR sub-tokens
+that must be concatenated to produce the value of the string.
+If the braced string was just \fB{}\fR
+(that is, the string was empty),
+the single \fBTCL_TOKEN_TEXT\fR token will have a \fIsize\fR field
+containing zero;
+this ensures that at least one token appears
+to describe the braced string.
+Only the token information in the Tcl_Parse structure
+is modified: the \fIcommentStart\fR, \fIcommentSize\fR,
+\fIcommandStart\fR, and \fIcommandSize\fR fields are not modified
+by \fBTcl_ParseBraces\fR.
+.PP
+After \fBTcl_ParseQuotedString\fR returns,
+the array of tokens pointed to by the \fItokenPtr\fR field of the
+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 \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
+is modified: the \fIcommentStart\fR, \fIcommentSize\fR,
+\fIcommandStart\fR, and \fIcommandSize\fR fields are not modified.
+.PP
+After \fBTcl_ParseVarName\fR returns, the first token pointed to by
+the \fItokenPtr\fR field of the
+Tcl_Parse structure always has type \fBTCL_TOKEN_VARIABLE\fR. It
+is followed by the sub-tokens that make up the variable name as
+described above. The total length of the variable name is
+contained in the \fIsize\fR field of the first token.
+As in \fBTcl_ParseExpr\fR,
+only the token information in the Tcl_Parse structure
+is modified by \fBTcl_ParseVarName\fR:
+the \fIcommentStart\fR, \fIcommentSize\fR,
+\fIcommandStart\fR, and \fIcommandSize\fR fields are not modified.
+.PP
+All of the character pointers in the
+Tcl_Parse and Tcl_Token structures refer
+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
+There are additional fields in the Tcl_Parse structure after the
+\fInumTokens\fR field, but these are for the private use of
+\fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseBraces\fR,
+\fBTcl_ParseQuotedString\fR, and \fBTcl_ParseVarName\fR; they should not be
+referenced by code outside of these procedures.
+.SH KEYWORDS
+backslash substitution, braces, command, expression, parse, token, variable substitution
diff --git a/library/msgcat/doc/PkgRequire.3 b/library/msgcat/doc/PkgRequire.3
new file mode 100644
index 0000000..d54d7af
--- /dev/null
+++ b/library/msgcat/doc/PkgRequire.3
@@ -0,0 +1,97 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_PkgRequire 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+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 *
+\fBTcl_PkgRequire\fR(\fIinterp, name, version, exact\fR)
+.sp
+const char *
+\fBTcl_PkgRequireEx\fR(\fIinterp, name, version, exact, clientDataPtr\fR)
+.sp
+int
+\fBTcl_PkgRequireProc\fR(\fIinterp, name, objc, objv, clientDataPtr\fR)
+.sp
+const char *
+\fBTcl_PkgPresent\fR(\fIinterp, name, version, exact\fR)
+.sp
+const char *
+\fBTcl_PkgPresentEx\fR(\fIinterp, name, version, exact, clientDataPtr\fR)
+.sp
+int
+\fBTcl_PkgProvide\fR(\fIinterp, name, version\fR)
+.sp
+int
+\fBTcl_PkgProvideEx\fR(\fIinterp, name, version, clientData\fR)
+.SH ARGUMENTS
+.AS void *clientDataPtr out
+.AP Tcl_Interp *interp in
+Interpreter where package is needed or available.
+.AP "const char" *name in
+Name of package.
+.AP "const char" *version in
+A version string consisting of one or more decimal numbers
+separated by dots.
+.AP int exact in
+Non-zero means that only the particular version specified by
+\fIversion\fR is acceptable.
+Zero means that newer versions than \fIversion\fR are also
+acceptable as long as they have the same major version number
+as \fIversion\fR.
+.AP "const void" *clientData in
+Arbitrary value to be associated with the package.
+.AP void *clientDataPtr out
+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. The storage can be any pointer
+type with the same size as a void pointer.
+.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
+version management facilities.
+.PP
+\fBTcl_PkgRequire\fR is equivalent to the \fBpackage require\fR
+command, \fBTcl_PkgPresent\fR is equivalent to the \fBpackage present\fR
+command, and \fBTcl_PkgProvide\fR is equivalent to the
+\fBpackage provide\fR command.
+.PP
+See the documentation for the Tcl commands for details on what these
+procedures do.
+.PP
+If \fBTcl_PkgPresent\fR or \fBTcl_PkgRequire\fR complete successfully
+they return a pointer to the version string for the version of the package
+that is provided in the interpreter (which may be different than
+\fIversion\fR); if an error occurs they return NULL and leave an error
+message in the interpreter's result.
+.PP
+\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
+.SH "SEE ALSO"
+package(n), Tcl_StaticPackage(3)
diff --git a/library/msgcat/doc/Preserve.3 b/library/msgcat/doc/Preserve.3
new file mode 100644
index 0000000..905a31d
--- /dev/null
+++ b/library/msgcat/doc/Preserve.3
@@ -0,0 +1,110 @@
+'\"
+'\" Copyright (c) 1990 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 Tcl_Preserve 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Preserve, Tcl_Release, Tcl_EventuallyFree \- avoid freeing storage while it is being used
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_Preserve\fR(\fIclientData\fR)
+.sp
+\fBTcl_Release\fR(\fIclientData\fR)
+.sp
+\fBTcl_EventuallyFree\fR(\fIclientData, freeProc\fR)
+.SH ARGUMENTS
+.AS Tcl_FreeProc clientData
+.AP ClientData clientData in
+Token describing structure to be freed or reallocated. Usually a pointer
+to memory for structure.
+.AP Tcl_FreeProc *freeProc in
+Procedure to invoke to free \fIclientData\fR.
+.BE
+.SH DESCRIPTION
+.PP
+These three procedures help implement a simple reference count mechanism
+for managing storage. They are designed to solve a problem
+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 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
+event-handling C procedure in the button to be invoked, which in
+turn causes the button's associated Tcl command to be executed,
+which in turn causes the button to be deleted, which in turn causes
+the button's widget record to be de-allocated.
+Unfortunately, when the Tcl command returns, the button's
+event-handling procedure will need to reference the
+button's widget record.
+Because of this, the widget record must not be freed as part of the
+deletion, but must be retained until the event-handling procedure has
+finished with it.
+In other situations where the widget is deleted, it may be possible
+to free the widget record immediately.
+.PP
+\fBTcl_Preserve\fR and \fBTcl_Release\fR
+implement short-term reference counts for their \fIclientData\fR
+argument.
+The \fIclientData\fR argument identifies an object and usually
+consists of the address of a structure.
+The reference counts guarantee that an object will not be freed
+until each call to \fBTcl_Preserve\fR for the object has been
+matched by calls to \fBTcl_Release\fR.
+There may be any number of unmatched \fBTcl_Preserve\fR calls
+in effect at once.
+.PP
+\fBTcl_EventuallyFree\fR is invoked to free up its \fIclientData\fR
+argument.
+It checks to see if there are unmatched \fBTcl_Preserve\fR calls
+for the object.
+If not, then \fBTcl_EventuallyFree\fR calls \fIfreeProc\fR immediately.
+Otherwise \fBTcl_EventuallyFree\fR records the fact that \fIclientData\fR
+needs eventually to be freed.
+When all calls to \fBTcl_Preserve\fR have been matched with
+calls to \fBTcl_Release\fR then \fIfreeProc\fR will be called by
+\fBTcl_Release\fR to do the cleanup.
+.PP
+All the work of freeing the object is carried out by \fIfreeProc\fR.
+\fIFreeProc\fR must have arguments and result that match the
+type \fBTcl_FreeProc\fR:
+.PP
+.CS
+typedef void \fBTcl_FreeProc\fR(
+ char *\fIblockPtr\fR);
+.CE
+.PP
+The \fIblockPtr\fR argument to \fIfreeProc\fR will be the
+same as the \fIclientData\fR argument to \fBTcl_EventuallyFree\fR.
+The type of \fIblockPtr\fR (\fBchar *\fR) is different than the type of the
+\fIclientData\fR argument to \fBTcl_EventuallyFree\fR for historical
+reasons, but the value is the same.
+.PP
+When the \fIclientData\fR argument to \fBTcl_EventuallyFree\fR
+refers to storage allocated and returned by a prior call to
+\fBTcl_Alloc\fR, \fBckalloc\fR, or another function of the Tcl library,
+then the \fIfreeProc\fR argument should be given the special value of
+\fBTCL_DYNAMIC\fR.
+.PP
+This mechanism can be used to solve the problem described above
+by placing \fBTcl_Preserve\fR and \fBTcl_Release\fR calls around
+actions that may cause undesired storage re-allocation. The
+mechanism is intended only for short-term use (i.e. while procedures
+are pending on the stack); it will not work efficiently as a
+mechanism for long-term reference counts.
+The implementation does not depend in any way on the internal
+structure of the objects being freed; it keeps the reference
+counts in a separate structure.
+.SH "SEE ALSO"
+Tcl_Interp, Tcl_Alloc
+.SH KEYWORDS
+free, reference count, storage
diff --git a/library/msgcat/doc/PrintDbl.3 b/library/msgcat/doc/PrintDbl.3
new file mode 100644
index 0000000..99b0113
--- /dev/null
+++ b/library/msgcat/doc/PrintDbl.3
@@ -0,0 +1,51 @@
+'\"
+'\" Copyright (c) 1989-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.
+'\"
+.so man.macros
+.TH Tcl_PrintDouble 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_PrintDouble \- Convert floating value to string
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_PrintDouble\fR(\fIinterp, value, dst\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp out
+.AP Tcl_Interp *interp in
+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.
+.AP double value in
+Floating-point value to be converted.
+.AP char *dst out
+Where to store the string representing \fIvalue\fR. Must have at
+least \fBTCL_DOUBLE_SPACE\fR characters of storage.
+.BE
+.SH DESCRIPTION
+.PP
+\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
+.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 .
+.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.
+.SH KEYWORDS
+conversion, double-precision, floating-point, string
diff --git a/library/msgcat/doc/RecEvalObj.3 b/library/msgcat/doc/RecEvalObj.3
new file mode 100644
index 0000000..2eed471
--- /dev/null
+++ b/library/msgcat/doc/RecEvalObj.3
@@ -0,0 +1,53 @@
+'\"
+'\" 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 Tcl_RecordAndEvalObj 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_RecordAndEvalObj \- save command on history list before evaluating
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_RecordAndEvalObj\fR(\fIinterp, cmdPtr, flags\fR)
+.SH ARGUMENTS
+.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. \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
+
+.SH DESCRIPTION
+.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 \fBTCL_EVAL_GLOBAL\fR bit is set
+in \fIflags\fR).
+It returns a completion code such as \fBTCL_OK\fR just like \fBTcl_EvalObjEx\fR,
+as well as a result object containing additional information
+(a result value or error message)
+that can be retrieved using \fBTcl_GetObjResult\fR.
+If you do not want the command recorded on the history list then
+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 \fBTCL_NO_EVAL\fR bit then
+the command is recorded without being evaluated.
+
+.SH "SEE ALSO"
+Tcl_EvalObjEx, Tcl_GetObjResult
+
+.SH KEYWORDS
+command, event, execute, history, interpreter, object, record
diff --git a/library/msgcat/doc/RecordEval.3 b/library/msgcat/doc/RecordEval.3
new file mode 100644
index 0000000..a8f3087
--- /dev/null
+++ b/library/msgcat/doc/RecordEval.3
@@ -0,0 +1,55 @@
+'\"
+'\" Copyright (c) 1989-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.
+'\"
+.so man.macros
+.TH Tcl_RecordAndEval 3 7.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_RecordAndEval \- save command on history list before evaluating
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_RecordAndEval\fR(\fIinterp, cmd, flags\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Tcl interpreter in which to evaluate command.
+.AP "const char" *cmd in
+Command (or sequence of commands) to execute.
+.AP int flags in
+An OR'ed combination of flag bits. \fBTCL_NO_EVAL\fR means record the
+command but do not evaluate it. \fBTCL_EVAL_GLOBAL\fR means evaluate
+the command at global level instead of the current stack level.
+.BE
+
+.SH DESCRIPTION
+.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 \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 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 \fBTCL_NO_EVAL\fR bit then
+the command is recorded without being evaluated.
+.PP
+Note that \fBTcl_RecordAndEval\fR has been largely replaced by the
+object-based procedure \fBTcl_RecordAndEvalObj\fR.
+That object-based procedure records and optionally executes
+a command held in a Tcl object instead of a string.
+
+.SH "SEE ALSO"
+Tcl_RecordAndEvalObj
+
+.SH KEYWORDS
+command, event, execute, history, interpreter, record
diff --git a/library/msgcat/doc/RegConfig.3 b/library/msgcat/doc/RegConfig.3
new file mode 100644
index 0000000..063cc85
--- /dev/null
+++ b/library/msgcat/doc/RegConfig.3
@@ -0,0 +1,111 @@
+'\"
+'\" 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 "const 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 \fIconfiguration\fR 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 *\fIkey\fR;
+ const char *\fIvalue\fR;
+} \fBTcl_Config\fR;
+.CE
+.\" No cross references yet.
+.\" .SH "SEE ALSO"
+.SH KEYWORDS
+embedding, configuration, binary library
diff --git a/library/msgcat/doc/RegExp.3 b/library/msgcat/doc/RegExp.3
new file mode 100644
index 0000000..e10314a
--- /dev/null
+++ b/library/msgcat/doc/RegExp.3
@@ -0,0 +1,383 @@
+'\"
+'\" Copyright (c) 1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_RegExpMatch 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_RegExpMatch, Tcl_RegExpCompile, Tcl_RegExpExec, Tcl_RegExpRange, Tcl_GetRegExpFromObj, Tcl_RegExpMatchObj, Tcl_RegExpExecObj, Tcl_RegExpGetInfo \- Pattern matching with regular expressions
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_RegExpMatchObj\fR(\fIinterp\fR, \fItextObj\fR, \fIpatObj\fR)
+.sp
+int
+\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, \fItext\fR, \fIstart\fR)
+.sp
+void
+\fBTcl_RegExpRange\fR(\fIregexp\fR, \fIindex\fR, \fIstartPtr\fR, \fIendPtr\fR)
+.sp
+Tcl_RegExp
+\fBTcl_GetRegExpFromObj\fR(\fIinterp\fR, \fIpatObj\fR, \fIcflags\fR)
+.sp
+int
+\fBTcl_RegExpExecObj\fR(\fIinterp\fR, \fIregexp\fR, \fItextObj\fR, \fIoffset\fR, \fInmatches\fR, \fIeflags\fR)
+.sp
+void
+\fBTcl_RegExpGetInfo\fR(\fIregexp\fR, \fIinfoPtr\fR)
+.fi
+.SH ARGUMENTS
+.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.
+.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.
+.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 \fItext\fR is just a portion of some other string, this argument
+identifies the beginning of the larger string.
+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.
+.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
+The address of the character just after the last one in the range
+is stored here, or NULL if there is no such range.
+.AP int cflags in
+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 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
+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 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.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_RegExpMatch\fR determines whether its \fIpattern\fR argument
+matches \fIregexp\fR, where \fIregexp\fR is interpreted
+as a regular expression using the rules in the \fBre_syntax\fR
+reference page.
+If there is a match then \fBTcl_RegExpMatch\fR returns 1.
+If there is no match then \fBTcl_RegExpMatch\fR returns 0.
+If an error occurs in the matching process (e.g. \fIpattern\fR
+is not a valid regular expression) then \fBTcl_RegExpMatch\fR
+returns \-1 and leaves an error message in the interpreter result.
+\fBTcl_RegExpMatchObj\fR is similar to \fBTcl_RegExpMatch\fR except it
+operates on the Tcl objects \fItextObj\fR and \fIpatObj\fR instead of
+UTF strings.
+\fBTcl_RegExpMatchObj\fR is generally more efficient than
+\fBTcl_RegExpMatch\fR, so it is the preferred interface.
+.PP
+\fBTcl_RegExpCompile\fR, \fBTcl_RegExpExec\fR, and \fBTcl_RegExpRange\fR
+provide lower-level access to the regular expression pattern matcher.
+\fBTcl_RegExpCompile\fR compiles a regular expression string into
+the internal form used for efficient pattern matching.
+The return value is a token for this compiled form, which can be
+used in subsequent calls to \fBTcl_RegExpExec\fR or \fBTcl_RegExpRange\fR.
+If an error occurs while compiling the regular expression then
+\fBTcl_RegExpCompile\fR returns NULL and leaves an error message
+in the interpreter result.
+Note: the return value from \fBTcl_RegExpCompile\fR is only valid
+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 \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
+message in the interpreter result.
+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 \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 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 \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
+the string matched what parts of the pattern.
+\fBTcl_RegExpRange\fR returns a pair of pointers in \fI*startPtr\fR
+and \fI*endPtr\fR that identify a range of characters in
+the source string for the most recent call to \fBTcl_RegExpExec\fR.
+\fIIndex\fR indicates which of several ranges is desired:
+if \fIindex\fR is 0, information is returned about the overall range
+of characters that matched the entire pattern; otherwise,
+information is returned about the range of characters that matched the
+\fIindex\fR'th parenthesized subexpression within the pattern.
+If there is no range corresponding to \fIindex\fR then NULL
+is stored in \fI*startPtr\fR and \fI*endPtr\fR.
+.PP
+\fBTcl_GetRegExpFromObj\fR, \fBTcl_RegExpExecObj\fR, and
+\fBTcl_RegExpGetInfo\fR are object interfaces that provide the most
+direct control of Henry Spencer's regular expression library. For
+users that need to modify compilation and execution options directly,
+it is recommended that you use these interfaces instead of calling the
+internal regexp functions. These interfaces handle the details of UTF
+to Unicode translations as well as providing improved performance
+through caching in the pattern and string objects.
+.PP
+\fBTcl_GetRegExpFromObj\fR attempts to return a compiled regular
+expression from the \fIpatObj\fR. If the object does not already
+contain a compiled regular expression it will attempt to create one
+from the string in the object and assign it to the internal
+representation of the \fIpatObj\fR. The return value of this function
+is of type \fBTcl_RegExp\fR. The return value is a token for this
+compiled form, which can be used in subsequent calls to
+\fBTcl_RegExpExecObj\fR or \fBTcl_RegExpGetInfo\fR. If an error
+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 \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
+.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
+.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
+.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.
+.TP
+\fBTCL_REG_EXPANDED\fR
+Compile the regular expression (basic, extended, or advanced) using an
+expanded syntax that allows comments and whitespace. This mode causes
+non-backslashed non-bracket-expression white
+space and #-to-end-of-line comments to be ignored.
+.TP
+\fBTCL_REG_QUOTE\fR
+Compile a literal string, with all characters treated as ordinary characters.
+.TP
+\fBTCL_REG_NOCASE\fR
+Compile for matching that ignores upper/lower case distinctions.
+.TP
+\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,
+.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 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
+.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
+.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
+Compile for matching that reports only success or failure,
+not what was matched. This reduces compile overhead and may improve
+performance. Subsequent calls to \fBTcl_RegExpGetInfo\fR or
+\fBTcl_RegExpRange\fR will not report any match information.
+.TP
+\fBTCL_REG_CANMATCH\fR
+Compile for matching that reports the potential to complete a partial
+match given more text (see below).
+.RE
+.PP
+Only one of
+\fBTCL_REG_EXTENDED\fR,
+\fBTCL_REG_ADVANCED\fR,
+\fBTCL_REG_BASIC\fR, and
+\fBTCL_REG_QUOTE\fR may be specified.
+.PP
+\fBTcl_RegExpExecObj\fR executes the regular expression pattern
+matcher. It returns 1 if \fIobjPtr\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_RegExpExecObj\fR leaves an
+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
+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 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
+.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
+.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
+performed with a given regular expression \fIregexp\fR. The
+\fIinfoPtr\fR argument contains a pointer to a structure that is
+defined as follows:
+.PP
+.CS
+typedef struct Tcl_RegExpInfo {
+ int \fInsubs\fR;
+ Tcl_RegExpIndices *\fImatches\fR;
+ long \fIextendStart\fR;
+} \fBTcl_RegExpInfo\fR;
+.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+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
+appear in the pattern. Each element is a structure that is defined as
+follows:
+.PP
+.CS
+typedef struct Tcl_RegExpIndices {
+ long \fIstart\fR;
+ long \fIend\fR;
+} \fBTcl_RegExpIndices\fR;
+.CE
+.PP
+The \fIstart\fR and \fIend\fR values are Unicode character indices
+relative to the offset location within \fIobjPtr\fR where matching began.
+The \fIstart\fR index identifies the first character of the matched
+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.
+.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
+character in the string where a match could occur. If a match was
+found, this will be the same as the beginning of the current match.
+If no match was found, then it indicates the earliest point at which a
+match might occur if additional text is appended to the string. If it
+is no match is possible even with further text, this field will be set
+to \-1.
+.SH "SEE ALSO"
+re_syntax(n)
+.SH KEYWORDS
+match, pattern, regular expression, string, subexpression, Tcl_RegExpIndices, Tcl_RegExpInfo
diff --git a/library/msgcat/doc/SaveResult.3 b/library/msgcat/doc/SaveResult.3
new file mode 100644
index 0000000..d6ea48d
--- /dev/null
+++ b/library/msgcat/doc/SaveResult.3
@@ -0,0 +1,120 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_SaveResult 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+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
+Tcl_InterpState
+\fBTcl_SaveInterpState\fR(\fIinterp, status\fR)
+.sp
+int
+\fBTcl_RestoreInterpState\fR(\fIinterp, state\fR)
+.sp
+\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_InterpState savedPtr
+.AP Tcl_Interp *interp in
+Interpreter for which state should be saved.
+.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
+These routines allows a C procedure to take a snapshot of the current
+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
+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 \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.
+.PP
+\fBTcl_SaveResult\fR moves the string and object results
+of \fIinterp\fR into the location specified by \fIstatePtr\fR.
+\fBTcl_SaveResult\fR clears the result for \fIinterp\fR and
+leaves the result in its normal empty initialized state.
+.PP
+\fBTcl_RestoreResult\fR moves the string and object results from
+\fIstatePtr\fR back into \fIinterp\fR. Any result or error that was
+already in the interpreter will be cleared. The \fIstatePtr\fR is left
+in an uninitialized state and cannot be used until another call to
+\fBTcl_SaveResult\fR.
+.PP
+\fBTcl_DiscardResult\fR releases the saved interpreter state
+stored at \fBstatePtr\fR. The state structure is left in an
+uninitialized state and cannot be used until another call to
+\fBTcl_SaveResult\fR.
+.PP
+Once \fBTcl_SaveResult\fR is called to save the interpreter
+result, either \fBTcl_RestoreResult\fR or
+\fBTcl_DiscardResult\fR must be called to properly clean up the
+memory associated with the saved state.
+.SH KEYWORDS
+result, state, interp
diff --git a/library/msgcat/doc/SetChanErr.3 b/library/msgcat/doc/SetChanErr.3
new file mode 100644
index 0000000..0a62dac
--- /dev/null
+++ b/library/msgcat/doc/SetChanErr.3
@@ -0,0 +1,140 @@
+'\"
+'\" 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\fR defined for channels
+and interpreters. And the generic I/O layer uses \fBTcl_GetChannelError\fR and
+\fBTcl_GetChannelErrorInterp\fR to look for messages in the bypass areas and
+arrange for their return as errors. The POSIX error codes set by a driver are
+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, that is, 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, that is, 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.
+.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 \fInot\fR use
+any of the new functions.
+.IP \fBTcl_DriverGetOptionProc\fR
+Has already the ability to pass arbitrary error messages. Must
+\fInot\fR use any of the new functions.
+.IP \fBTcl_DriverWatchProc\fR
+Must \fInot\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 \fInot\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 \fInot\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; when these functions are called, the channel
+may now contain a stored arbitrary error message requiring processing by the
+caller.
+.DS
+.ta 1.9i 4i
+\fBTcl_Flush\fR \fBTcl_GetsObj\fR \fBTcl_Gets\fR
+\fBTcl_ReadChars\fR \fBTcl_ReadRaw\fR \fBTcl_Read\fR
+\fBTcl_Seek\fR \fBTcl_StackChannel\fR \fBTcl_Tell\fR
+\fBTcl_WriteChars\fR \fBTcl_WriteObj\fR \fBTcl_WriteRaw\fR
+\fBTcl_Write\fR
+.DE
+.PP
+All other API functions are unchanged. In particular, the functions below
+leave all their error information in the interpreter result.
+.DS
+.ta 1.9i 4i
+\fBTcl_Close\fR \fBTcl_UnstackChannel\fR \fBTcl_UnregisterChannel\fR
+.DE
+.SH "SEE ALSO"
+Tcl_Close(3), Tcl_OpenFileChannel(3), Tcl_SetErrno(3)
+.SH KEYWORDS
+channel driver, error messages, channel type
diff --git a/library/msgcat/doc/SetErrno.3 b/library/msgcat/doc/SetErrno.3
new file mode 100644
index 0000000..1735952
--- /dev/null
+++ b/library/msgcat/doc/SetErrno.3
@@ -0,0 +1,66 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_SetErrno 3 8.3 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SetErrno, Tcl_GetErrno, Tcl_ErrnoId, Tcl_ErrnoMsg \- manipulate errno to store and retrieve error codes
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_SetErrno\fR(\fIerrorCode\fR)
+.sp
+int
+\fBTcl_GetErrno\fR()
+.sp
+const char *
+\fBTcl_ErrnoId\fR()
+.sp
+const char *
+\fBTcl_ErrnoMsg\fR(\fIerrorCode\fR)
+.sp
+.SH ARGUMENTS
+.AS int errorCode
+.AP int errorCode in
+A POSIX error code such as \fBENOENT\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_SetErrno\fR and \fBTcl_GetErrno\fR provide portable access
+to the \fBerrno\fR variable, which is used to record a POSIX error
+code after system calls and other operations such as \fBTcl_Gets\fR.
+These procedures are necessary because global variable accesses cannot
+be made across module boundaries on some platforms.
+.PP
+\fBTcl_SetErrno\fR sets the \fBerrno\fR variable to the value of the
+\fIerrorCode\fR argument
+C procedures that wish to return error information to their callers
+via \fBerrno\fR should call \fBTcl_SetErrno\fR rather than setting
+\fBerrno\fR directly.
+.PP
+\fBTcl_GetErrno\fR returns the current value of \fBerrno\fR.
+Procedures wishing to access \fBerrno\fR should call this procedure
+instead of accessing \fBerrno\fR directly.
+.PP
+\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
+.QW EACCES
+that corresponds to the current value of \fBerrno\fR.
+\fBTcl_ErrnoMsg\fR returns a human-readable string such as
+.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
+statically allocated and the caller must not free or modify them.
+
+.SH KEYWORDS
+errno, error code, global variables
diff --git a/library/msgcat/doc/SetRecLmt.3 b/library/msgcat/doc/SetRecLmt.3
new file mode 100644
index 0000000..e38ba2f
--- /dev/null
+++ b/library/msgcat/doc/SetRecLmt.3
@@ -0,0 +1,53 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_SetRecursionLimit 3 7.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SetRecursionLimit \- set maximum allowable nesting depth in interpreter
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_SetRecursionLimit\fR(\fIinterp, depth\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Interpreter whose recursion limit is to be set.
+Must be greater than zero.
+.AP int depth in
+New limit for nested calls to \fBTcl_Eval\fR for \fIinterp\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+At any given time Tcl enforces a limit on the number of recursive
+calls that may be active for \fBTcl_Eval\fR and related procedures
+such as \fBTcl_GlobalEval\fR.
+Any call to \fBTcl_Eval\fR that exceeds this depth is aborted with
+an error.
+By default the recursion limit is 1000.
+.PP
+\fBTcl_SetRecursionLimit\fR may be used to change the maximum
+allowable nesting depth for an interpreter.
+The \fIdepth\fR argument specifies a new limit for \fIinterp\fR,
+and \fBTcl_SetRecursionLimit\fR returns the old limit.
+To read out the old limit without modifying it, invoke
+\fBTcl_SetRecursionLimit\fR with \fIdepth\fR equal to 0.
+.PP
+The \fBTcl_SetRecursionLimit\fR only sets the size of the Tcl
+call stack: 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 \fBTcl_SetRecursionLimit\fR.
+If this happens, see if there is a mechanism in your system for
+increasing the maximum size of the C stack.
+
+.SH KEYWORDS
+nesting depth, recursion
diff --git a/library/msgcat/doc/SetResult.3 b/library/msgcat/doc/SetResult.3
new file mode 100644
index 0000000..c308193
--- /dev/null
+++ b/library/msgcat/doc/SetResult.3
@@ -0,0 +1,255 @@
+'\"
+'\" Copyright (c) 1989-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.
+'\"
+.so man.macros
+.TH Tcl_SetResult 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SetObjResult, Tcl_GetObjResult, Tcl_SetResult, Tcl_GetStringResult, Tcl_AppendResult, Tcl_AppendResultVA, Tcl_AppendElement, Tcl_ResetResult, Tcl_TransferResult, Tcl_FreeResult \- manipulate Tcl result
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_SetObjResult\fR(\fIinterp, objPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetObjResult\fR(\fIinterp\fR)
+.sp
+\fBTcl_SetResult\fR(\fIinterp, result, freeProc\fR)
+.sp
+const char *
+\fBTcl_GetStringResult\fR(\fIinterp\fR)
+.sp
+\fBTcl_AppendResult\fR(\fIinterp, result, result, ... , \fB(char *) NULL\fR)
+.sp
+\fBTcl_AppendResultVA\fR(\fIinterp, argList\fR)
+.sp
+\fBTcl_ResetResult\fR(\fIinterp\fR)
+.sp
+.VS 8.6
+\fBTcl_TransferResult\fR(\fIsourceInterp, result, targetInterp\fR)
+.VE 8.6
+.sp
+\fBTcl_AppendElement\fR(\fIinterp, element\fR)
+.sp
+\fBTcl_FreeResult\fR(\fIinterp\fR)
+.SH ARGUMENTS
+.AS Tcl_FreeProc sourceInterp 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 *result in
+String value to become result for \fIinterp\fR or to be
+appended to the existing result.
+.AP "const 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
+\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 initialized using
+\fBva_start\fR, and cleared using \fBva_end\fR.
+.AP Tcl_Interp *sourceInterp in
+.VS 8.6
+Interpreter that the result and error information should be copied from.
+.VE 8.6
+.AP Tcl_Interp *targetInterp in
+.VS 8.6
+Interpreter that the result and error information should be copied to.
+.VE 8.6
+.AP int result in
+.VS 8.6
+If \fBTCL_OK\fR, only copy the result. If \fBTCL_ERROR\fR, copy the error
+information as well.
+.VE 8.6
+.BE
+.SH DESCRIPTION
+.PP
+The procedures described here are utilities for manipulating the
+result value in a Tcl interpreter.
+The interpreter result may be either a Tcl object or a string.
+For example, \fBTcl_SetObjResult\fR and \fBTcl_SetResult\fR
+set the interpreter result to, respectively, an object and a string.
+Similarly, \fBTcl_GetObjResult\fR and \fBTcl_GetStringResult\fR
+return the interpreter result as an object and as a string.
+The procedures always keep the string and object forms
+of the interpreter result consistent.
+For example, if \fBTcl_SetObjResult\fR is called to set
+the result to an object,
+then \fBTcl_GetStringResult\fR is called,
+it will return the object's string value.
+.PP
+\fBTcl_SetObjResult\fR
+arranges for \fIobjPtr\fR to be the result for \fIinterp\fR,
+replacing any existing result.
+The result is left pointing to the object
+referenced by \fIobjPtr\fR.
+\fIobjPtr\fR's reference count is incremented
+since there is now a new reference to it from \fIinterp\fR.
+The reference count for any old result object
+is decremented and the old result object is freed if no
+references to it remain.
+.PP
+\fBTcl_GetObjResult\fR returns the result for \fIinterp\fR as an object.
+The object's reference count is not incremented;
+if the caller needs to retain a long-term pointer to the object
+they should use \fBTcl_IncrRefCount\fR to increment its reference count
+in order to keep it from being freed too early or accidentally changed.
+.PP
+\fBTcl_SetResult\fR
+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 \fIresult\fR argument;
+it is discussed in the section
+\fBTHE TCL_FREEPROC ARGUMENT TO TCL_SETRESULT\fR below.
+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 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,
+this conversion will lose information.
+For this reason, programmers are encouraged to
+write their code to use the new object API procedures
+and to call \fBTcl_GetObjResult\fR instead.
+.PP
+\fBTcl_ResetResult\fR clears the result for \fIinterp\fR
+and leaves the result in its normal empty initialized state.
+If the result is an object,
+its reference count is decremented and the result is left
+pointing to an unshared object representing an empty string.
+If the result is a dynamically allocated string, its memory is free*d
+and the result is left as a empty string.
+\fBTcl_ResetResult\fR also clears the error state managed by
+\fBTcl_AddErrorInfo\fR, \fBTcl_AddObjErrorInfo\fR,
+and \fBTcl_SetErrorCode\fR.
+.PP
+\fBTcl_AppendResult\fR makes it easy to build up Tcl results in pieces.
+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 \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 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.
+.PP
+.VS 8.6
+\fBTcl_TransferResult\fR moves a result from one interpreter to another,
+optionally (dependent on the \fIresult\fR parameter) including the error
+information dictionary as well. The interpreters must be in the same thread.
+The source interpreter will have its result reset by this operation.
+.VE 8.6
+.SH "DEPRECATED INTERFACES"
+.SS "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 \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
+\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
+.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 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.
+.SS "DIRECT ACCESS TO INTERP->RESULT"
+.PP
+It used to be legal for programs to
+directly read and write \fIinterp->result\fR
+to manipulate the interpreter result. The Tcl headers no longer
+permit this access by default, and C code still doing this must
+be updated to use supported routines \fBTcl_GetObjResult\fR,
+\fBTcl_GetStringResult\fR, \fBTcl_SetObjResult\fR, and \fBTcl_SetResult\fR.
+As a migration aid, access can be restored with the compiler directive
+.CS
+#define USE_INTERP_RESULT
+.CE
+but this is meant only to offer life support to otherwise dead code.
+.SH "THE TCL_FREEPROC ARGUMENT TO TCL_SETRESULT"
+.PP
+\fBTcl_SetResult\fR's \fIfreeProc\fR argument specifies how
+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 \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 \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 \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 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.
+When Tcl no longer needs the storage for the string, it will
+call \fIfreeProc\fR. \fIFreeProc\fR should have arguments and
+result that match the type \fBTcl_FreeProc\fR:
+.PP
+.CS
+typedef void \fBTcl_FreeProc\fR(
+ char *\fIblockPtr\fR);
+.CE
+.PP
+When \fIfreeProc\fR is called, its \fIblockPtr\fR will be set to
+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/library/msgcat/doc/SetVar.3 b/library/msgcat/doc/SetVar.3
new file mode 100644
index 0000000..ce47a73
--- /dev/null
+++ b/library/msgcat/doc/SetVar.3
@@ -0,0 +1,249 @@
+'\"
+'\" Copyright (c) 1989-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.
+'\"
+.so man.macros
+.TH Tcl_SetVar 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SetVar2Ex, Tcl_SetVar, Tcl_SetVar2, Tcl_ObjSetVar2, Tcl_GetVar2Ex, Tcl_GetVar, Tcl_GetVar2, Tcl_ObjGetVar2, Tcl_UnsetVar, Tcl_UnsetVar2 \- manipulate Tcl variables
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_SetVar2Ex\fR(\fIinterp, name1, name2, newValuePtr, flags\fR)
+.sp
+const char *
+\fBTcl_SetVar\fR(\fIinterp, varName, newValue, flags\fR)
+.sp
+const char *
+\fBTcl_SetVar2\fR(\fIinterp, name1, name2, newValue, flags\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ObjSetVar2\fR(\fIinterp, part1Ptr, part2Ptr, newValuePtr, flags\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetVar2Ex\fR(\fIinterp, name1, name2, flags\fR)
+.sp
+const char *
+\fBTcl_GetVar\fR(\fIinterp, varName, flags\fR)
+.sp
+const char *
+\fBTcl_GetVar2\fR(\fIinterp, name1, name2, flags\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ObjGetVar2\fR(\fIinterp, part1Ptr, part2Ptr, flags\fR)
+.sp
+int
+\fBTcl_UnsetVar\fR(\fIinterp, varName, flags\fR)
+.sp
+int
+\fBTcl_UnsetVar2\fR(\fIinterp, name1, name2, flags\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *newValuePtr
+.AP Tcl_Interp *interp in
+Interpreter containing variable.
+.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
+If non-NULL, gives name of element within array; in this
+case \fIname1\fR must refer to an array variable.
+.AP Tcl_Obj *newValuePtr in
+Points to a Tcl object containing the new value for the variable.
+.AP int flags in
+OR-ed combination of bits providing additional information. See below
+for valid values.
+.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
+New value for variable, specified as a null-terminated string.
+A copy of this value is stored in the variable.
+.AP Tcl_Obj *part1Ptr in
+Points to a Tcl object containing the variable's name.
+The name may include a series of \fB::\fR namespace qualifiers
+to specify a variable in a particular namespace.
+May refer to a scalar variable or an element of an array variable.
+.AP Tcl_Obj *part2Ptr in
+If non-NULL, points to an object containing the name of an element
+within an array and \fIpart1Ptr\fR must refer to an array variable.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures are used to create, modify, read, and delete
+Tcl variables from C code.
+.PP
+\fBTcl_SetVar2Ex\fR, \fBTcl_SetVar\fR, \fBTcl_SetVar2\fR, and
+\fBTcl_ObjSetVar2\fR
+will create a new variable or modify an existing one.
+These procedures set the given variable to the value
+given by \fInewValuePtr\fR or \fInewValue\fR and return a
+pointer to the variable's new value, which is stored in Tcl's
+variable structure.
+\fBTcl_SetVar2Ex\fR and \fBTcl_ObjSetVar2\fR take the new value as a
+Tcl_Obj and return
+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
+\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
+\fBTcl_GetVar2Ex\fR, \fBTcl_GetVar\fR, \fBTcl_GetVar2\fR, and
+\fBTcl_ObjGetVar2\fR
+return the current value of a variable.
+The arguments to these procedures are treated in the same way
+as the arguments to the procedures described above.
+Under normal circumstances, the return value is a pointer
+to the variable's value. For \fBTcl_GetVar2Ex\fR and
+\fBTcl_ObjGetVar2\fR the value is
+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.
+If an error occurs while reading the variable (e.g. the variable
+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.
+.PP
+\fBTcl_UnsetVar\fR and \fBTcl_UnsetVar2\fR may be used to remove
+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 \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
+but the array remains.
+If an array name is specified without an index, then the entire
+array is removed.
+.PP
+The name of a variable may be specified to these procedures in
+four ways:
+.IP [1]
+If \fBTcl_SetVar\fR, \fBTcl_GetVar\fR, or \fBTcl_UnsetVar\fR
+is invoked, the variable name is given as
+a single string, \fIvarName\fR.
+If \fIvarName\fR contains an open parenthesis and ends with a
+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 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. 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).
+.PP
+The \fIflags\fR argument may be used to specify any of several
+options to the procedures.
+It consists of an OR-ed combination of the following bits.
+.TP
+\fBTCL_GLOBAL_ONLY\fR
+Under normal circumstances the procedures look up variables as follows.
+If a procedure call is active in \fIinterp\fR,
+the variable is looked up at the current level of procedure call.
+Otherwise, the variable is looked up first in the current namespace,
+then in the global namespace.
+However, if this bit is set in \fIflags\fR then the variable
+is looked up only in the global namespace
+even if there is a procedure call active.
+If both \fBTCL_GLOBAL_ONLY\fR and \fBTCL_NAMESPACE_ONLY\fR are given,
+\fBTCL_GLOBAL_ONLY\fR is ignored.
+.TP
+\fBTCL_NAMESPACE_ONLY\fR
+If this bit is set in \fIflags\fR then the variable
+is looked up only in the current namespace; if a procedure is active
+its variables are ignored, and the global namespace is also ignored unless
+it is the current namespace.
+.TP
+\fBTCL_LEAVE_ERR_MSG\fR
+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 is not set then no error message is left
+and the interpreter's result will not be modified.
+.TP
+\fBTCL_APPEND_VALUE\fR
+If this bit is set then \fInewValuePtr\fR or \fInewValue\fR is
+appended to the current value instead of replacing it.
+If the variable is currently undefined, then the bit is ignored.
+This bit is only used by the \fBTcl_Set*\fR procedures.
+.TP
+\fBTCL_LIST_ELEMENT\fR
+If this bit is set, then \fInewValue\fR is converted to a valid
+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
+.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.
+.PP
+\fBTcl_GetVar\fR and \fBTcl_GetVar2\fR
+return the current value of a variable.
+The arguments to these procedures are treated in the same way
+as the arguments to \fBTcl_SetVar\fR and \fBTcl_SetVar2\fR.
+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 \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
+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
+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 \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
+array is removed.
+
+.SH "SEE ALSO"
+Tcl_GetObjResult, Tcl_GetStringResult, Tcl_TraceVar
+
+.SH KEYWORDS
+array, get variable, interpreter, object, scalar, set, unset, variable
diff --git a/library/msgcat/doc/Signal.3 b/library/msgcat/doc/Signal.3
new file mode 100644
index 0000000..5b12654
--- /dev/null
+++ b/library/msgcat/doc/Signal.3
@@ -0,0 +1,41 @@
+'\"
+'\" Copyright (c) 2001 ActiveState Tool Corp.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_SignalId 3 8.3 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SignalId, Tcl_SignalMsg \- Convert signal codes
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+const char *
+\fBTcl_SignalId\fR(\fIsig\fR)
+.sp
+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
+
+.SH DESCRIPTION
+.PP
+\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
+.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
+signals, signal numbers
diff --git a/library/msgcat/doc/Sleep.3 b/library/msgcat/doc/Sleep.3
new file mode 100644
index 0000000..2423ba1
--- /dev/null
+++ b/library/msgcat/doc/Sleep.3
@@ -0,0 +1,34 @@
+'\"
+'\" Copyright (c) 1990 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 Tcl_Sleep 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Sleep \- delay execution for a given number of milliseconds
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.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 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/library/msgcat/doc/SourceRCFile.3 b/library/msgcat/doc/SourceRCFile.3
new file mode 100644
index 0000000..eabc47c
--- /dev/null
+++ b/library/msgcat/doc/SourceRCFile.3
@@ -0,0 +1,32 @@
+'\"
+'\" Copyright (c) 1998-2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.so man.macros
+.TH Tcl_SourceRCFile 3 8.3 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SourceRCFile \- source the Tcl rc file
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+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
+
+.SH DESCRIPTION
+.PP
+\fBTcl_SourceRCFile\fR is used to source the Tcl rc file at startup.
+It is typically invoked by Tcl_Main or Tk_Main. The name of the file
+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.
+
+.SH KEYWORDS
+application-specific initialization, main program, rc file
diff --git a/library/msgcat/doc/SplitList.3 b/library/msgcat/doc/SplitList.3
new file mode 100644
index 0000000..219dfc7
--- /dev/null
+++ b/library/msgcat/doc/SplitList.3
@@ -0,0 +1,188 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_SplitList 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SplitList, Tcl_Merge, Tcl_ScanElement, Tcl_ConvertElement, Tcl_ScanCountedElement, Tcl_ConvertCountedElement \- manipulate Tcl lists
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_SplitList\fR(\fIinterp, list, argcPtr, argvPtr\fR)
+.sp
+char *
+\fBTcl_Merge\fR(\fIargc, argv\fR)
+.sp
+int
+\fBTcl_ScanElement\fR(\fIsrc, flagsPtr\fR)
+.sp
+int
+\fBTcl_ScanCountedElement\fR(\fIsrc, length, flagsPtr\fR)
+.sp
+int
+\fBTcl_ConvertElement\fR(\fIsrc, dst, flags\fR)
+.sp
+int
+\fBTcl_ConvertCountedElement\fR(\fIsrc, length, dst, flags\fR)
+.SH ARGUMENTS
+.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.
+.AP char *list in
+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
+\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
+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
+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.
+The value of *\fIflagsPtr\fR must be passed to \fBTcl_ConvertElement\fR.
+.AP int length in
+Number of bytes in string \fIsrc\fR.
+.AP char *dst in
+Place to copy converted list element. Must contain enough characters
+to hold converted string.
+.AP int flags in
+Information about \fIsrc\fR. Must be value returned by previous
+call to \fBTcl_ScanElement\fR, possibly OR-ed
+with \fBTCL_DONT_USE_BRACES\fR.
+.BE
+.SH DESCRIPTION
+.PP
+These procedures may be used to disassemble and reassemble Tcl lists.
+\fBTcl_SplitList\fR breaks a list up into its constituent elements,
+returning an array of pointers to the elements using
+\fIargcPtr\fR and \fIargvPtr\fR.
+While extracting the arguments, \fBTcl_SplitList\fR obeys the usual
+rules for backslash substitutions and braces. The area of
+memory pointed to by \fI*argvPtr\fR is dynamically allocated; in
+addition to the array of pointers, it
+also holds copies of all the list elements. It is the caller's
+responsibility to free up all of this storage.
+For example, suppose that you have called \fBTcl_SplitList\fR with
+the following code:
+.PP
+.CS
+int argc, code;
+char *string;
+char **argv;
+\&...
+code = \fBTcl_SplitList\fR(interp, string, &argc, &argv);
+.CE
+.PP
+Then you should eventually free the storage with a call like the
+following:
+.PP
+.CS
+Tcl_Free((char *) argv);
+.CE
+.PP
+\fBTcl_SplitList\fR normally returns \fBTCL_OK\fR, which means the list was
+successfully parsed.
+If there was a syntax error in \fIlist\fR, then \fBTCL_ERROR\fR is returned
+and the interpreter's result will point to an error message describing the
+problem (if \fIinterp\fR was not NULL).
+If \fBTCL_ERROR\fR is returned then no memory is allocated and \fI*argvPtr\fR
+is not modified.
+.PP
+\fBTcl_Merge\fR is the inverse of \fBTcl_SplitList\fR: it
+takes a collection of strings given by \fIargc\fR
+and \fIargv\fR and generates a result string
+that has proper list structure.
+This means that commands like \fBindex\fR may be used to
+extract the original elements again.
+In addition, if the result of \fBTcl_Merge\fR is passed to \fBTcl_Eval\fR,
+it will be parsed into \fIargc\fR words whose values will
+be the same as the \fIargv\fR strings passed to \fBTcl_Merge\fR.
+\fBTcl_Merge\fR will modify the list elements with braces and/or
+backslashes in order to produce proper Tcl list structure.
+The result string is dynamically allocated
+using \fBTcl_Alloc\fR; the caller must eventually release the space
+using \fBTcl_Free\fR.
+.PP
+If the result of \fBTcl_Merge\fR is passed to \fBTcl_SplitList\fR,
+the elements returned by \fBTcl_SplitList\fR will be identical to
+those passed into \fBTcl_Merge\fR.
+However, the converse is not true: if \fBTcl_SplitList\fR
+is passed a given string, and the resulting \fIargc\fR and
+\fIargv\fR are passed to \fBTcl_Merge\fR, the resulting string
+may not be the same as the original string passed to \fBTcl_SplitList\fR.
+This is because \fBTcl_Merge\fR may use backslashes and braces
+differently than the original string.
+.PP
+\fBTcl_ScanElement\fR and \fBTcl_ConvertElement\fR are the
+procedures that do all of the real work of \fBTcl_Merge\fR.
+\fBTcl_ScanElement\fR scans its \fIsrc\fR argument
+and determines how to use backslashes and braces
+when converting it to a list element.
+It returns an overestimate of the number of characters
+required to represent \fIsrc\fR as a list element, and
+it stores information in \fI*flagsPtr\fR that is needed
+by \fBTcl_ConvertElement\fR.
+.PP
+\fBTcl_ConvertElement\fR is a companion procedure to \fBTcl_ScanElement\fR.
+It does the actual work of converting a string to a list element.
+Its \fIflags\fR argument must be the same as the value returned
+by \fBTcl_ScanElement\fR.
+\fBTcl_ConvertElement\fR writes a proper list element to memory
+starting at *\fIdst\fR and returns a count of the total number
+of characters written, which will be no more than the result
+returned by \fBTcl_ScanElement\fR.
+\fBTcl_ConvertElement\fR writes out only the actual list element
+without any leading or trailing spaces: it is up to the caller to
+include spaces between adjacent list elements.
+.PP
+\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 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.
+The caller may insist on the second approach by OR-ing the
+flag value returned by \fBTcl_ScanElement\fR with
+\fBTCL_DONT_USE_BRACES\fR.
+Although this will produce an uglier result, it is useful in some
+special situations, such as when \fBTcl_ConvertElement\fR is being
+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
+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.
+.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
+argument, and the string may contain embedded nulls.
+.SH "SEE ALSO"
+Tcl_ListObjGetElements(3)
+.SH KEYWORDS
+backslash, convert, element, list, merge, split, strings
diff --git a/library/msgcat/doc/SplitPath.3 b/library/msgcat/doc/SplitPath.3
new file mode 100644
index 0000000..7fdfce6
--- /dev/null
+++ b/library/msgcat/doc/SplitPath.3
@@ -0,0 +1,97 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_SplitPath 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SplitPath, Tcl_JoinPath, Tcl_GetPathType \- manipulate platform-dependent file paths
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_SplitPath\fR(\fIpath, argcPtr, argvPtr\fR)
+.sp
+char *
+\fBTcl_JoinPath\fR(\fIargc, argv, resultPtr\fR)
+.sp
+Tcl_PathType
+\fBTcl_GetPathType\fR(\fIpath\fR)
+.SH ARGUMENTS
+.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
+\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
+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
+\fBTcl_JoinPath\fR will be appended.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures have been superseded by the objectified procedures in
+the \fBFileSystem\fR man page, which are more efficient.
+.PP
+These procedures may be used to disassemble and reassemble file
+paths in a platform independent manner: they provide C-level access to
+the same functionality as the \fBfile split\fR, \fBfile join\fR, and
+\fBfile pathtype\fR commands.
+.PP
+\fBTcl_SplitPath\fR breaks a path into its constituent elements,
+returning an array of pointers to the elements using \fIargcPtr\fR and
+\fIargvPtr\fR. The area of memory pointed to by \fI*argvPtr\fR is
+dynamically allocated; in addition to the array of pointers, it also
+holds copies of all the path elements. It is the caller's
+responsibility to free all of this storage.
+For example, suppose that you have called \fBTcl_SplitPath\fR with the
+following code:
+.PP
+.CS
+int argc;
+char *path;
+char **argv;
+\&...
+Tcl_SplitPath(string, &argc, &argv);
+.CE
+.PP
+Then you should eventually free the storage with a call like the
+following:
+.PP
+.CS
+Tcl_Free((char *) argv);
+.CE
+.PP
+\fBTcl_JoinPath\fR is the inverse of \fBTcl_SplitPath\fR: it takes a
+collection of path elements given by \fIargc\fR and \fIargv\fR and
+generates a result string that is a properly constructed path. The
+result string is appended to \fIresultPtr\fR. \fIResultPtr\fR must
+refer to an initialized \fBTcl_DString\fR.
+.PP
+If the result of \fBTcl_SplitPath\fR is passed to \fBTcl_JoinPath\fR,
+the result will refer to the same location, but may not be in the same
+form. This is because \fBTcl_SplitPath\fR and \fBTcl_JoinPath\fR
+eliminate duplicate path separators and return a normalized form for
+each platform.
+.PP
+\fBTcl_GetPathType\fR returns the type of the specified \fIpath\fR,
+where \fBTcl_PathType\fR is one of \fBTCL_PATH_ABSOLUTE\fR,
+\fBTCL_PATH_RELATIVE\fR, or \fBTCL_PATH_VOLUME_RELATIVE\fR. See the
+\fBfilename\fR manual entry for a description of the path types for
+each platform.
+
+.SH KEYWORDS
+file, filename, join, path, split, type
diff --git a/library/msgcat/doc/StaticPkg.3 b/library/msgcat/doc/StaticPkg.3
new file mode 100644
index 0000000..fa6c32f
--- /dev/null
+++ b/library/msgcat/doc/StaticPkg.3
@@ -0,0 +1,70 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_StaticPackage 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_StaticPackage \- make a statically linked package available via the 'load' command
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_StaticPackage\fR(\fIinterp, pkgName, initProc, safeInitProc\fR)
+.SH ARGUMENTS
+.AS Tcl_PackageInitProc *safeInitProc
+.AP Tcl_Interp *interp in
+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
+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
+Procedure to invoke to incorporate this package into a trusted
+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
+cannot be used in safe interpreters.
+.BE
+.SH DESCRIPTION
+.PP
+This procedure may be invoked to announce that a package has been
+linked statically with a Tcl application and, optionally, that it
+has already been loaded into an interpreter.
+Once \fBTcl_StaticPackage\fR has been invoked for a package, it
+may be loaded into interpreters using the \fBload\fR command.
+\fBTcl_StaticPackage\fR is normally invoked only by the \fBTcl_AppInit\fR
+procedure for the application, not by packages for themselves
+(\fBTcl_StaticPackage\fR should only be invoked for statically
+loaded packages, and code in the package itself should not need
+to know whether the package is dynamically or statically loaded).
+.PP
+When the \fBload\fR command is used later to load the package into
+an interpreter, one of \fIinitProc\fR and \fIsafeInitProc\fR will
+be invoked, depending on whether the target interpreter is safe
+or not.
+\fIinitProc\fR and \fIsafeInitProc\fR must both match the
+following prototype:
+.PP
+.CS
+typedef int \fBTcl_PackageInitProc\fR(
+ Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+The \fIinterp\fR argument identifies the interpreter in which the package
+is to be loaded. The initialization 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. The result or error from the initialization procedure will
+be returned as the result of the \fBload\fR command that caused the
+initialization procedure to be invoked.
+.SH KEYWORDS
+initialization procedure, package, static linking
+.SH "SEE ALSO"
+load(n), package(n), Tcl_PkgRequire(3)
diff --git a/library/msgcat/doc/StdChannels.3 b/library/msgcat/doc/StdChannels.3
new file mode 100644
index 0000000..b5b020e
--- /dev/null
+++ b/library/msgcat/doc/StdChannels.3
@@ -0,0 +1,120 @@
+'\"
+'\" Copyright (c) 2001 by ActiveState Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH "Standard Channels" 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_StandardChannels \- How the Tcl library deals with the standard channels
+.BE
+
+.SH DESCRIPTION
+.PP
+This page explains the initialization and use of standard channels in
+the Tcl library.
+.PP
+The term \fIstandard channels\fR comes out of the Unix world and
+refers to the three channels automatically opened by the OS for
+each new application. They are \fBstdin\fR, \fBstdout\fR and
+\fBstderr\fR. The first is the standard input an application can read
+from, the other two refer to writable channels, one for regular
+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.
+.SS "APPLICATION PROGRAMMING INTERFACES"
+.PP
+The public API procedures dealing directly with standard channels are
+\fBTcl_GetStdChannel\fR and \fBTcl_SetStdChannel\fR. Additional public
+APIs to consider are \fBTcl_RegisterChannel\fR,
+\fBTcl_CreateChannel\fR and \fBTcl_GetChannel\fR.
+.SH "INITIALIZATION OF TCL STANDARD CHANNELS"
+.PP
+Standard channels are initialized by the Tcl library in three cases:
+when explicitly requested, when implicitly required before returning
+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
+.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 states of the
+other standard channels are unaffected.
+.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
+platform-specific default values:
+.RS
+.TP
+(a)
+when open channels are listed with \fBTcl_GetChannelNames\fR (or the
+\fBfile channels\fR script command), or
+.TP
+(b)
+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).
+.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
+the application are designated as the Tcl standard channels.
+.RE
+.TP
+3)
+All uninitialized standard channels are initialized to
+platform-specific default values when a user-requested channel is
+registered with \fBTcl_RegisterChannel\fR.
+.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.
+.SH "RE-INITIALIZATION OF TCL STANDARD CHANNELS"
+.PP
+Once a Tcl standard channel is initialized through one of the methods
+above, closing this Tcl standard channel will cause the next call to
+\fBTcl_CreateChannel\fR to make the new channel the new standard
+channel, too. If more than one Tcl standard channel was closed
+\fBTcl_CreateChannel\fR will fill the empty slots in the order
+\fBstdin\fR, \fBstdout\fR and \fBstderr\fR.
+.PP
+\fBTcl_CreateChannel\fR will not try to reinitialize an empty slot if
+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 "SHELL-SPECIFIC DETAILS"
+.SS tclsh
+.PP
+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.
+.SS wish
+.PP
+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/library/msgcat/doc/StrMatch.3 b/library/msgcat/doc/StrMatch.3
new file mode 100644
index 0000000..5adaf6e
--- /dev/null
+++ b/library/msgcat/doc/StrMatch.3
@@ -0,0 +1,49 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_StringMatch 3 8.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_StringMatch, Tcl_StringCaseMatch \- test whether a string matches a pattern
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_StringMatch\fR(\fIstr\fR, \fIpattern\fR)
+.sp
+int
+\fBTcl_StringCaseMatch\fR(\fIstr\fR, \fIpattern\fR, \fIflags\fR)
+.SH ARGUMENTS
+.AS "const char" *pattern
+.AP "const char" *str in
+String to test.
+.AP "const char" *pattern in
+Pattern to match against string. May contain special
+characters from the set *?\e[].
+.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
+.PP
+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 \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.
+.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 \fBTCL_MATCH_NOCASE\fR), then the string and
+pattern are essentially matched in the lower case.
+
+.SH KEYWORDS
+match, pattern, string
diff --git a/library/msgcat/doc/StringObj.3 b/library/msgcat/doc/StringObj.3
new file mode 100644
index 0000000..412ab78
--- /dev/null
+++ b/library/msgcat/doc/StringObj.3
@@ -0,0 +1,384 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.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_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
+.sp
+Tcl_Obj *
+\fBTcl_NewStringObj\fR(\fIbytes, length\fR)
+.sp
+Tcl_Obj *
+\fBTcl_NewUnicodeObj\fR(\fIunicode, numChars\fR)
+.sp
+void
+\fBTcl_SetStringObj\fR(\fIobjPtr, bytes, length\fR)
+.sp
+void
+\fBTcl_SetUnicodeObj\fR(\fIobjPtr, unicode, numChars\fR)
+.sp
+char *
+\fBTcl_GetStringFromObj\fR(\fIobjPtr, lengthPtr\fR)
+.sp
+char *
+\fBTcl_GetString\fR(\fIobjPtr\fR)
+.sp
+Tcl_UniChar *
+\fBTcl_GetUnicodeFromObj\fR(\fIobjPtr, lengthPtr\fR)
+.sp
+Tcl_UniChar *
+\fBTcl_GetUnicode\fR(\fIobjPtr\fR)
+.sp
+Tcl_UniChar
+\fBTcl_GetUniChar\fR(\fIobjPtr, index\fR)
+.sp
+int
+\fBTcl_GetCharLength\fR(\fIobjPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetRange\fR(\fIobjPtr, first, last\fR)
+.sp
+void
+\fBTcl_AppendToObj\fR(\fIobjPtr, bytes, length\fR)
+.sp
+void
+\fBTcl_AppendUnicodeToObj\fR(\fIobjPtr, unicode, numChars\fR)
+.sp
+void
+\fBTcl_AppendObjToObj\fR(\fIobjPtr, appendObjPtr\fR)
+.sp
+void
+\fBTcl_AppendStringsToObj\fR(\fIobjPtr, string, string, ... \fB(char *) NULL\fR)
+.sp
+void
+\fBTcl_AppendStringsToObjVA\fR(\fIobjPtr, argList\fR)
+.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
+void
+\fBTcl_AppendPrintfToObj\fR(\fIobjPtr, format, ...\fR)
+.sp
+void
+\fBTcl_SetObjLength\fR(\fIobjPtr, newLength\fR)
+.sp
+int
+\fBTcl_AttemptSetObjLength\fR(\fIobjPtr, newLength\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ConcatObj\fR(\fIobjc, objv\fR)
+.SH ARGUMENTS
+.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 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.)
+.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
+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
+unless \fInumChars\fR is negative.
+.AP int numChars in
+The number of Unicode characters to copy from \fIunicode\fR when
+initializing, setting, or appending to a string object.
+If negative, all characters up to the first null character are used.
+.AP int index in
+The index of the Unicode character to return.
+.AP int first in
+The index of the first Unicode character in the Unicode range to be
+returned as a new object.
+.AP int last in
+The index of the last Unicode character in the Unicode range to be
+returned as a new object.
+.AP Tcl_Obj *objPtr in/out
+Points to an object to manipulate.
+.AP Tcl_Obj *appendObjPtr in
+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 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 initialized using
+\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
+.QW "..."
+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.
+.BE
+.SH DESCRIPTION
+.PP
+The procedures described in this manual entry allow Tcl objects to
+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 does not have to be copied for each append.
+Also, indexing and length computations are optimized because the
+Unicode string representation is calculated and cached as needed.
+When using the \fBTcl_Append*\fR family of functions where the
+interpreter's result is the object being appended to, it is important
+to call Tcl_ResetResult first to ensure you are not unintentionally
+appending to existing data in the result object.
+.PP
+\fBTcl_NewStringObj\fR and \fBTcl_SetStringObj\fR create a new object
+or modify an existing object to hold a copy of the string given by
+\fIbytes\fR and \fIlength\fR. \fBTcl_NewUnicodeObj\fR and
+\fBTcl_SetUnicodeObj\fR create a new object or modify an existing
+object to hold a copy of the Unicode string given by \fIunicode\fR and
+\fInumChars\fR. \fBTcl_NewStringObj\fR and \fBTcl_NewUnicodeObj\fR
+return a pointer to a newly created object with reference count zero.
+All four procedures set the object to hold a copy of the specified
+string. \fBTcl_SetStringObj\fR and \fBTcl_SetUnicodeObj\fR free any
+old string representation as well as any old internal representation
+of the object.
+.PP
+\fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR return an object's
+string representation. This is given by the returned byte pointer and
+(for \fBTcl_GetStringFromObj\fR) length, which is stored in
+\fIlengthPtr\fR if it is non-NULL. If the object's UTF string
+representation is invalid (its byte pointer is NULL), the string
+representation is regenerated from the object's internal
+representation. The storage referenced by the returned byte pointer
+is owned by the object manager. It is passed back as a writable
+pointer so that extension author creating their own \fBTcl_ObjType\fR
+will be able to modify the string representation within the
+\fBTcl_UpdateStringProc\fR of their \fBTcl_ObjType\fR. Except for that
+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.
+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
+to \fBTcl_IsShared\fR and \fBTcl_DuplicateObj\fR prior to any
+in-place modification of the string representation.
+The procedure \fBTcl_GetString\fR is used in the common case
+where the caller does not need the length of the string
+representation.
+.PP
+\fBTcl_GetUnicodeFromObj\fR and \fBTcl_GetUnicode\fR return an object's
+value as a Unicode string. This is given by the returned pointer and
+(for \fBTcl_GetUnicodeFromObj\fR) length, which is stored in
+\fIlengthPtr\fR if it is non-NULL. The storage referenced by the returned
+byte pointer is owned by the object manager and should not be modified by
+the caller. The procedure \fBTcl_GetUnicode\fR is used in the common case
+where the caller does not need the length of the unicode string
+representation.
+.PP
+\fBTcl_GetUniChar\fR returns the \fIindex\fR'th character in the
+object's Unicode representation.
+.PP
+\fBTcl_GetRange\fR returns a newly created object comprised of the
+characters between \fIfirst\fR and \fIlast\fR (inclusive) in the
+object's Unicode representation. If the object's Unicode
+representation is invalid, the Unicode representation is regenerated
+from the object's string representation.
+.PP
+\fBTcl_GetCharLength\fR returns the number of characters (as opposed
+to bytes) in the string object.
+.PP
+\fBTcl_AppendToObj\fR appends the data given by \fIbytes\fR and
+\fIlength\fR to the string representation of the object specified by
+\fIobjPtr\fR. If the object has an invalid string representation,
+then an attempt is made to convert \fIbytes\fR is to the Unicode
+format. If the conversion is successful, then the converted form of
+\fIbytes\fR is appended to the object's Unicode representation.
+Otherwise, the object's Unicode representation is invalidated and
+converted to the UTF format, and \fIbytes\fR is appended to the
+object's new string representation.
+.PP
+\fBTcl_AppendUnicodeToObj\fR appends the Unicode string given by
+\fIunicode\fR and \fInumChars\fR to the object specified by
+\fIobjPtr\fR. If the object has an invalid Unicode representation,
+then \fIunicode\fR is converted to the UTF format and appended to the
+object's string representation. Appends are optimized to handle
+repeated appends relatively efficiently (it over-allocates the string
+or Unicode space to avoid repeated reallocations and copies of
+object's string value).
+.PP
+\fBTcl_AppendObjToObj\fR is similar to \fBTcl_AppendToObj\fR, but it
+appends the string or Unicode value (whichever exists and is best
+suited to be appended to \fIobjPtr\fR) of \fIappendObjPtr\fR to
+\fIobjPtr\fR.
+.PP
+\fBTcl_AppendStringsToObj\fR is similar to \fBTcl_AppendToObj\fR
+except that it can be passed more than one value to append and
+each value must be a null-terminated string (i.e. none of the
+values may contain internal null characters). Any number of
+\fIstring\fR arguments may be provided, but the last argument
+must be a NULL pointer to indicate the end of the list.
+.PP
+\fBTcl_AppendStringsToObjVA\fR is the same as \fBTcl_AppendStringsToObj\fR
+except that instead of taking a variable number of arguments it takes an
+argument list.
+.PP
+\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
+.PP
+.CS
+\fBTcl_Format\fR(interp, \fBTcl_GetString\fR(objv[1]), objc-2, objv+2);
+.CE
+.PP
+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:
+.PP
+.CS
+Tcl_Obj *newPtr = \fBTcl_Format\fR(interp, format, objc, objv);
+if (newPtr == NULL) return TCL_ERROR;
+\fBTcl_AppendObjToObj\fR(objPtr, newPtr);
+return TCL_OK;
+.CE
+.PP
+but with greater convenience and efficiency when the appending
+functionality is needed.
+.PP
+\fBTcl_ObjPrintf\fR serves as a replacement for the common sequence
+.PP
+.CS
+char buf[SOME_SUITABLE_LENGTH];
+sprintf(buf, format, ...);
+\fBTcl_NewStringObj\fR(buf, -1);
+.CE
+.PP
+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 \fBint\fR.
+.PP
+.CS
+int x = 5;
+Tcl_Obj *objPtr = \fBTcl_ObjPrintf\fR("Value is %d", x);
+.CE
+.PP
+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.
+It is impossible however to provide runtime protection against
+mismatches between the format and any subsequent arguments.
+Compile-time protection may be provided by some compilers.
+.PP
+\fBTcl_AppendPrintfToObj\fR is an appending alternative form
+of \fBTcl_ObjPrintf\fR with functionality equivalent to
+.PP
+.CS
+\fBTcl_AppendObjToObj\fR(objPtr, \fBTcl_ObjPrintf\fR(format, ...));
+.CE
+.PP
+but with greater convenience and efficiency when the appending
+functionality is needed.
+.PP
+The \fBTcl_SetObjLength\fR procedure changes the length of the
+string value of its \fIobjPtr\fR argument. If the \fInewLength\fR
+argument is greater than the space allocated for the object's
+string, then the string space is reallocated and the old value
+is copied to the new space; the bytes between the old length of
+the string and the new length may have arbitrary values.
+If the \fInewLength\fR argument is less than the current length
+of the object's string, with \fIobjPtr->length\fR is reduced without
+reallocating the string space; the original allocated size for the
+string is recorded in the object, so that the string length can be
+enlarged in a subsequent call to \fBTcl_SetObjLength\fR without
+reallocating storage. In all cases \fBTcl_SetObjLength\fR leaves
+a null character at \fIobjPtr->bytes[newLength]\fR.
+.PP
+\fBTcl_AttemptSetObjLength\fR is identical in function to
+\fBTcl_SetObjLength\fR except that if sufficient memory to satisfy the
+request cannot be allocated, it does not cause the Tcl interpreter to
+\fBpanic\fR. Thus, if \fInewLength\fR is greater than the space
+allocated for the object's string, and there is not enough memory
+available to satisfy the request, \fBTcl_AttemptSetObjLength\fR will take
+no action and return 0 to indicate failure. If there is enough memory
+to satisfy the request, \fBTcl_AttemptSetObjLength\fR behaves just like
+\fBTcl_SetObjLength\fR and returns 1 to indicate success.
+.PP
+The \fBTcl_ConcatObj\fR function returns a new string object whose
+value is the space-separated concatenation of the string
+representations of all of the objects in the \fIobjv\fR
+array. \fBTcl_ConcatObj\fR eliminates leading and trailing white space
+as it copies the string representations of the \fIobjv\fR array to the
+result. If an element of the \fIobjv\fR array consists of nothing but
+white space, then that object is ignored entirely. This white-space
+removal was added to make the output of the \fBconcat\fR command
+cleaner-looking. \fBTcl_ConcatObj\fR returns a pointer to a
+newly-created object whose ref count is zero.
+.SH "SEE ALSO"
+Tcl_NewObj(3), Tcl_IncrRefCount(3), Tcl_DecrRefCount(3), format(n), sprintf(3)
+.SH KEYWORDS
+append, internal representation, object, object type, string object,
+string type, string representation, concat, concatenate, unicode
diff --git a/library/msgcat/doc/SubstObj.3 b/library/msgcat/doc/SubstObj.3
new file mode 100644
index 0000000..786b595
--- /dev/null
+++ b/library/msgcat/doc/SubstObj.3
@@ -0,0 +1,68 @@
+'\"
+'\" Copyright (c) 2001 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_SubstObj 3 8.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SubstObj \- perform substitutions on Tcl objects
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_SubstObj\fR(\fIinterp, objPtr, flags\fR)
+.SH ARGUMENTS
+.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
+message.
+.AP Tcl_Obj *objPtr in
+A Tcl object containing the string to perform substitutions on.
+.AP int flags in
+ORed combination of flag bits that specify which substitutions to
+perform. The flags \fBTCL_SUBST_COMMANDS\fR,
+\fBTCL_SUBST_VARIABLES\fR and \fBTCL_SUBST_BACKSLASHES\fR are
+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
+strings in the fashion of the \fBsubst\fR command. It gets the value
+of the string contained in \fIobjPtr\fR and scans it, copying
+characters and performing the chosen substitutions as it goes to an
+output object which is returned as the result of the function. In the
+event of an error occurring during the execution of a command or
+variable substitution, the function returns NULL and an error message
+is left in \fIinterp\fR's result.
+.PP
+Three kinds of substitutions are supported. When the
+\fBTCL_SUBST_BACKSLASHES\fR bit is set in \fIflags\fR, sequences that
+look like backslash substitutions for Tcl commands are replaced by
+their corresponding character.
+.PP
+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 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
+.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/library/msgcat/doc/TCL_MEM_DEBUG.3 b/library/msgcat/doc/TCL_MEM_DEBUG.3
new file mode 100644
index 0000000..05d4564
--- /dev/null
+++ b/library/msgcat/doc/TCL_MEM_DEBUG.3
@@ -0,0 +1,80 @@
+'\"
+'\" Copyright (c) 1992-1999 Karl Lehenbauer and Mark Diekhans.
+'\" Copyright (c) 2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.so man.macros
+.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
+.BE
+.SH DESCRIPTION
+When Tcl is compiled with \fBTCL_MEM_DEBUG\fR defined, a powerful set
+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 (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 \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
+.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 \(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
+.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
+to isolate a corruption problem. Turning on memory validation with
+the memory command can help isolate difficult problems. If you
+suspect (or know) that corruption is occurring before the Tcl
+interpreter comes up far enough for you to issue commands, you can set
+\fBMEM_VALIDATE\fR define, recompile tclCkalloc.c and rebuild Tcl.
+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 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/library/msgcat/doc/Tcl.n b/library/msgcat/doc/Tcl.n
new file mode 100644
index 0000000..68146ab
--- /dev/null
+++ b/library/msgcat/doc/Tcl.n
@@ -0,0 +1,270 @@
+'\"
+'\" 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 Tcl n "8.6" Tcl "Tcl Built-In Commands"
+.BS
+.SH NAME
+Tcl \- Tool Command Language
+.SH SYNOPSIS
+Summary of Tcl language syntax.
+.BE
+.SH DESCRIPTION
+.PP
+The following rules define the syntax and semantics of the Tcl language:
+.IP "[1] \fBCommands.\fR"
+A Tcl script is a string containing one or more commands.
+Semi-colons and newlines are command separators unless quoted as
+described below.
+Close brackets are command terminators during command substitution
+(see below) unless quoted.
+.IP "[2] \fBEvaluation.\fR"
+A command is evaluated in two steps.
+First, the Tcl interpreter breaks the command into \fIwords\fR
+and performs substitutions as described below.
+These substitutions are performed in the same way for all
+commands.
+The first word is used to locate a command procedure to
+carry out the command, then all of the words of the command are
+passed to the command procedure.
+The command procedure is free to interpret each of its words
+in any way it likes, such as an integer, variable name, list,
+or Tcl script.
+Different commands interpret their words differently.
+.IP "[3] \fBWords.\fR"
+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
+.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] \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 {g h}}"
+is equivalent to
+.QW "cmd a b {[c]} d {$e} f {g h}" .
+.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
+quoted with a backslash then it is not counted in locating the
+matching close brace).
+No substitutions are performed on the characters between the
+braces except for backslash-newline substitutions described
+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 "[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
+.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 "[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.
+Variable substitution may take any of the following forms:
+.RS
+.TP 15
+\fB$\fIname\fR
+.
+\fIName\fR is the name of a scalar variable; the name is a sequence
+of one or more characters that are a letter, digit, underscore,
+or namespace separators (two or more colons).
+Letters and digits are \fIonly\fR the standard ASCII ones (\fB0\fR\-\fB9\fR,
+\fBA\fR\-\fBZ\fR and \fBa\fR\-\fBz\fR).
+.TP 15
+\fB$\fIname\fB(\fIindex\fB)\fR
+.
+\fIName\fR gives the name of an array variable and \fIindex\fR gives
+the name of an element within that array.
+\fIName\fR must contain only letters, digits, underscores, and
+namespace separators, and may be an empty string.
+Letters and digits are \fIonly\fR the standard ASCII ones (\fB0\fR\-\fB9\fR,
+\fBA\fR\-\fBZ\fR and \fBa\fR\-\fBz\fR).
+Command substitutions, variable substitutions, and backslash
+substitutions are performed on the characters of \fIindex\fR.
+.TP 15
+\fB${\fIname\fB}\fR
+.
+\fIName\fR is the name of a scalar variable or array element. It may contain
+any characters whatsoever except for close braces. It indicates an array
+element if \fIname\fR is in the form
+.QW \fIarrayName\fB(\fIindex\fB)\fR
+where \fIarrayName\fR does not contain any open parenthesis characters,
+.QW \fB(\fR ,
+or close brace characters,
+.QW \fB}\fR ,
+and \fIindex\fR can be any sequence of characters except for close brace
+characters. No further
+substitutions are performed during the parsing of \fIname\fR.
+.PP
+There may be any number of variable substitutions in a single word.
+Variable substitution is not performed on words enclosed in braces.
+.PP
+Note that variables may contain character sequences other than those listed
+above, but in that case other mechanisms must be used to access them (e.g.,
+via the \fBset\fR command's single-argument form).
+.RE
+.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.
+This allows characters such as double quotes, close brackets,
+and dollar signs to be included in words without triggering
+special processing.
+The following table lists the backslash sequences that are
+handled specially, along with the value that replaces each sequence.
+.RS
+.TP 7
+\e\fBa\fR
+Audible alert (bell) (0x7).
+.TP 7
+\e\fBb\fR
+Backspace (0x8).
+.TP 7
+\e\fBf\fR
+Form feed (0xc).
+.TP 7
+\e\fBn\fR
+Newline (0xa).
+.TP 7
+\e\fBr\fR
+Carriage-return (0xd).
+.TP 7
+\e\fBt\fR
+Tab (0x9).
+.TP 7
+\e\fBv\fR
+Vertical tab (0xb).
+.TP 7
+\e\fB<newline>\fIwhiteSpace\fR
+.
+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 is not
+in braces or quotes.
+.TP 7
+\e\e
+Backslash
+.PQ \e "" .
+.TP 7
+\e\fIooo\fR
+.
+The digits \fIooo\fR (one, two, or three of them) give a eight-bit octal
+value for the Unicode character that will be inserted, in the range \fI000\fR
+- \fI377\fR. The parser will stop just before this range overflows, or when
+the maximum of three digits is reached. The upper bits of the Unicode
+character will be 0.
+.TP 7
+\e\fBx\fIhh\fR
+.
+The hexadecimal digits \fIhh\fR (one or two of them) give an eight-bit
+hexadecimal value for the Unicode character that will be inserted. The upper
+bits of the Unicode character will be 0.
+.TP 7
+\e\fBu\fIhhhh\fR
+.
+The hexadecimal digits \fIhhhh\fR (one, two, three, or four of them) give a
+sixteen-bit hexadecimal value for the Unicode character that will be
+inserted. The upper bits of the Unicode character will be 0.
+.TP 7
+\e\fBU\fIhhhhhhhh\fR
+.
+The hexadecimal digits \fIhhhhhhhh\fR (one up to eight of them) give a
+twenty-one-bit hexadecimal value for the Unicode character that will be
+inserted, in the range U+0000..U+10FFFF. The parser will stop just
+before this range overflows, or when the maximum of eight digits
+is reached. The upper bits of the Unicode character will be 0.
+.PP
+The range U+010000..U+10FFFD is reserved for the future.
+.PP
+Backslash substitution is not performed on words enclosed in braces,
+except for backslash-newline as described above.
+.RE
+.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 "[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
+substitutions are performed on the value of the variable; the
+value is inserted into the word verbatim.
+If command substitution occurs then the nested command is
+processed entirely by the recursive call to the Tcl interpreter;
+no substitutions are performed before making the recursive
+call and no additional substitutions are performed on the result
+of the nested script.
+.RS
+.PP
+Substitutions take place from left to right, and each substitution is
+evaluated completely before attempting to evaluate the next. Thus, a
+sequence like
+.PP
+.CS
+set y [set x 0][incr x][incr x]
+.CE
+.PP
+will always set the variable \fIy\fR to the value, \fI012\fR.
+.RE
+.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.
+.SH KEYWORDS
+backslash, command, comment, script, substitution, variable
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/library/msgcat/doc/TclZlib.3 b/library/msgcat/doc/TclZlib.3
new file mode 100644
index 0000000..1b5e892
--- /dev/null
+++ b/library/msgcat/doc/TclZlib.3
@@ -0,0 +1,248 @@
+'\"
+'\" Copyright (c) 2008 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 TclZlib 3 8.6 Tcl "Tcl Library Procedures"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_ZlibAdler32, Tcl_ZlibCRC32, Tcl_ZlibDeflate, Tcl_ZlibInflate, Tcl_ZlibStreamChecksum, Tcl_ZlibStreamClose, Tcl_ZlibStreamEof, Tcl_ZlibStreamGet, Tcl_ZlibStreamGetCommandName, Tcl_ZlibStreamInit, Tcl_ZlibStreamPut \- compression and decompression functions
+.SH SYNOPSIS
+.nf
+#include <tcl.h>
+.sp
+int
+\fBTcl_ZlibDeflate\fR(\fIinterp, format, dataObj, level, dictObj\fR)
+.sp
+int
+\fBTcl_ZlibInflate\fR(\fIinterp, format, dataObj, dictObj\fR)
+.sp
+unsigned int
+\fBTcl_ZlibCRC32\fR(\fIinitValue, bytes, length\fR)
+.sp
+unsigned int
+\fBTcl_ZlibAdler32\fR(\fIinitValue, bytes, length\fR)
+.sp
+int
+\fBTcl_ZlibStreamInit\fR(\fIinterp, mode, format, level, dictObj, zshandlePtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ZlibStreamGetCommandName\fR(\fIzshandle\fR)
+.sp
+int
+\fBTcl_ZlibStreamEof\fR(\fIzshandle\fR)
+.sp
+int
+\fBTcl_ZlibStreamClose\fR(\fIzshandle\fR)
+.sp
+int
+\fBTcl_ZlibStreamReset\fR(\fIzshandle\fR)
+.sp
+int
+\fBTcl_ZlibStreamChecksum\fR(\fIzshandle\fR)
+.sp
+int
+\fBTcl_ZlibStreamPut\fR(\fIzshandle, dataObj, flush\fR)
+.sp
+int
+\fBTcl_ZlibStreamGet\fR(\fIzshandle, dataObj, count\fR)
+.fi
+.SH ARGUMENTS
+.AS Tcl_ZlibStream *zshandlePtr out
+.AP Tcl_Interp *interp in
+The interpreter to store resulting compressed or uncompressed data in. Also
+where any error messages are written. For \fBTcl_ZlibStreamInit\fR, this can
+be NULL to create a stream that is not bound to a command.
+.AP int format in
+What format of compressed data to work with. Must be one of
+\fBTCL_ZLIB_FORMAT_ZLIB\fR for zlib-format data, \fBTCL_ZLIB_FORMAT_GZIP\fR
+for gzip-format data, or \fBTCL_ZLIB_FORMAT_RAW\fR for raw compressed data. In
+addition, for decompression only, \fBTCL_ZLIB_FORMAT_AUTO\fR may also be
+chosen which can automatically detect whether the compressed data was in zlib
+or gzip format.
+.AP Tcl_Obj *dataObj in/out
+A byte-array object containing the data to be compressed or decompressed, or
+to which the data extracted from the stream is appended when passed to
+\fBTcl_ZlibStreamGet\fR.
+.AP int level in
+What level of compression to use. Should be a number from 0 to 9 or one of the
+following: \fBTCL_ZLIB_COMPRESS_NONE\fR for no compression,
+\fBTCL_ZLIB_COMPRESS_FAST\fR for fast but inefficient compression,
+\fBTCL_ZLIB_COMPRESS_BEST\fR for slow but maximal compression, or
+\fBTCL_ZLIB_COMPRESS_DEFAULT\fR for the level recommended by the zlib library.
+.AP Tcl_Obj *dictObj in/out
+A dictionary that contains, or which will be updated to contain, a description
+of the gzip header associated with the compressed data. Only useful when the
+\fIformat\fR is \fBTCL_ZLIB_FORMAT_GZIP\fR or \fBTCL_ZLIB_FORMAT_AUTO\fR. If
+a NULL is passed, a default header will be used on compression and the header
+will be ignored (apart from integrity checks) on decompression. See the
+section \fBGZIP OPTIONS DICTIONARY\fR for details about the contents of this
+dictionary.
+.AP "unsigned int" initValue in
+The initial value for the checksum algorithm.
+.AP "unsigned char" *bytes in
+An array of bytes to run the checksum algorithm over, or NULL to get the
+recommended initial value for the checksum algorithm.
+.AP int length in
+The number of bytes in the array.
+.AP int mode in
+What mode to operate the stream in. Should be either
+\fBTCL_ZLIB_STREAM_DEFLATE\fR for a compressing stream or
+\fBTCL_ZLIB_STREAM_INFLATE\fR for a decompressing stream.
+.AP Tcl_ZlibStream *zshandlePtr out
+A pointer to a variable in which to write the abstract token for the stream
+upon successful creation.
+.AP Tcl_ZlibStream zshandle in
+The abstract token for the stream to operate on.
+.AP int flush in
+Whether and how to flush the stream after writing the data to it. Must be one
+of: \fBTCL_ZLIB_NO_FLUSH\fR if no flushing is to be done, \fBTCL_ZLIB_FLUSH\fR
+if the currently compressed data must be made available for access using
+\fBTcl_ZlibStreamGet\fR, \fBTCL_ZLIB_FULLFLUSH\fR if the stream must be put
+into a state where the decompressor can recover from on corruption, or
+\fBTCL_ZLIB_FINALIZE\fR to ensure that the stream is finished and that any
+trailer demanded by the format is written.
+.AP int count in
+The maximum number of bytes to get from the stream, or -1 to get all remaining
+bytes from the stream's buffers.
+.BE
+.SH DESCRIPTION
+These functions form the interface from the Tcl library to the Zlib
+library by Jean-loup Gailly and Mark Adler.
+.PP
+\fBTcl_ZlibDeflate\fR and \fBTcl_ZlibInflate\fR respectively compress and
+decompress the data contained in the \fIdataObj\fR argument, according to the
+\fIformat\fR and, for compression, \fIlevel\fR arguments. The dictionary in
+the \fIdictObj\fR parameter is used to convey additional header information
+about the compressed data when the compression format supports it; currently,
+the dictionary is only used when the \fIformat\fR parameter is
+\fBTCL_ZLIB_FORMAT_GZIP\fR or \fBTCL_ZLIB_FORMAT_AUTO\fR. For details of the
+contents of the dictionary, see the \fBGZIP OPTIONS DICTIONARY\fR section
+below. Upon success, both functions leave the resulting compressed or
+decompressed data in a byte-array object that is the Tcl interpreter's result;
+the returned value is a standard Tcl result code.
+.PP
+\fBTcl_ZlibAdler32\fR and \fBTcl_ZlibCRC32\fR compute checksums on arrays of
+bytes, returning the computed checksum. Checksums are computed incrementally,
+allowing data to be processed one block at a time, but this requires the
+caller to maintain the current checksum and pass it in as the \fIinitValue\fR
+parameter; the initial value to use for this can be obtained by using NULL for
+the \fIbytes\fR parameter instead of a pointer to the array of bytes to
+compute the checksum over. Thus, typical usage in the single data block case
+is like this:
+.PP
+.CS
+checksum = \fBTcl_ZlibCRC32\fR(\fBTcl_ZlibCRC32\fR(0,NULL,0), data, length);
+.CE
+.PP
+Note that the Adler-32 algorithm is not a real checksum, but instead is a
+related type of hash that works best on longer data.
+.SS "ZLIB STREAMS"
+.PP
+\fBTcl_ZlibStreamInit\fR creates a compressing or decompressing stream that is
+linked to a Tcl command, according to its arguments, and provides an abstract
+token for the stream and returns a normal Tcl result code;
+\fBTcl_ZlibStreamGetCommandName\fR returns the name of that command given the
+stream token, or NULL if the stream has no command. Streams are not designed
+to be thread-safe; each stream should only ever be used from the thread that
+created it. When working with gzip streams, a dictionary (fields as given in
+the \fBGZIP OPTIONS DICTIONARY\fR section below) can be given via the
+\fIdictObj\fR parameter that on compression allows control over the generated
+headers, and on decompression allows discovery of the existing headers. Note
+that the dictionary will be written to on decompression once sufficient data
+has been read to have a complete header. This means that the dictionary must
+be an unshared object in that case; a blank object created with
+\fBTcl_NewObj\fR is suggested.
+.PP
+Once a stream has been constructed, \fBTcl_ZlibStreamPut\fR is used to add
+data to the stream and \fBTcl_ZlibStreamGet\fR is used to retrieve data from
+the stream after processing. Both return normal Tcl result codes and leave an
+error message in the result of the interpreter that the stream is registered
+with in the error case (if such a registration has been performed). With
+\fBTcl_ZlibStreamPut\fR, the data buffer object passed to it should not be
+modified afterwards. With \fBTcl_ZlibStreamGet\fR, the data buffer object
+passed to it will have the data bytes appended to it. Internally to the
+stream, data is kept compressed so as to minimize the cost of buffer space.
+.PP
+\fBTcl_ZlibStreamChecksum\fR returns the checksum computed over the
+uncompressed data according to the format, and \fBTcl_ZlibStreamEof\fR returns
+a boolean value indicating whether the end of the uncompressed data has been
+reached.
+.PP
+If you wish to clear a stream and reuse it for a new compression or
+decompression action, \fBTcl_ZlibStreamReset\fR will do this and return a
+normal Tcl result code to indicate whether it was successful; if the stream is
+registered with an interpreter, an error message will be left in the
+interpreter result when this function returns TCL_ERROR.
+Finally, \fBTcl_ZlibStreamClose\fR will clean up the stream and delete the
+associated command: using \fBTcl_DeleteCommand\fR on the stream's command is
+equivalent (when such a command exists).
+.SH "GZIP OPTIONS DICTIONARY"
+.PP
+The \fIdictObj\fR parameter to \fBTcl_ZlibDeflate\fR, \fBTcl_ZlibInflate\fR
+and \fBTcl_ZlibStreamInit\fR is used to pass a dictionary of options about
+that is used to describe the gzip header in the compressed data. When creating
+compressed data, the dictionary is read and when unpacking compressed data the
+dictionary is written (in which case the \fIdictObj\fR parameter must refer to
+an unshared dictionary object).
+.PP
+The following fields in the dictionary object are understood. All other fields
+are ignored. No field is required when creating a gzip-format stream.
+.TP
+\fBcomment\fR
+.
+This holds the comment field of the header, if present. If absent, no comment
+was supplied (on decompression) or will be created (on compression).
+.TP
+\fBcrc\fR
+.
+A boolean value describing whether a CRC of the header is computed. Note that
+the \fBgzip\fR program does \fInot\fR use or allow a CRC on the header.
+.TP
+\fBfilename\fR
+.
+The name of the file that held the uncompressed data. This should not contain
+any directory separators, and should be sanitized before use on decompression
+with \fBfile tail\fR.
+.TP
+\fBos\fR
+.
+The operating system type code field from the header (if not the
+.QW unknown
+value). See RFC 1952 for the meaning of these codes. On compression, if this
+is absent then the field will be set to the
+.QW unknown
+value.
+.TP
+\fBsize\fR
+.
+The size of the uncompressed data. This is ignored on compression; the size
+of the data compressed depends on how much data is supplied to the
+compression engine.
+.TP
+\fBtime\fR
+.
+The time field from the header if non-zero, expected to be the time that the
+file named by the \fBfilename\fR field was modified. Suitable for use with
+\fBclock format\fR. On creation, the right value to use is that from
+\fBclock seconds\fR or \fBfile mtime\fR.
+.TP
+\fBtype\fR
+.
+The type of the uncompressed data (either \fBbinary\fR or \fBtext\fR) if
+known.
+.SH "PORTABILITY NOTES"
+These functions will fail gracefully if Tcl is not linked with the zlib
+library.
+.SH "SEE ALSO"
+Tcl_NewByteArrayObj(3), zlib(n)
+'\"Tcl_StackChannel(3)
+.SH "KEYWORDS"
+compress, decompress, deflate, gzip, inflate
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/library/msgcat/doc/Tcl_Main.3 b/library/msgcat/doc/Tcl_Main.3
new file mode 100644
index 0000000..0a69835
--- /dev/null
+++ b/library/msgcat/doc/Tcl_Main.3
@@ -0,0 +1,196 @@
+'\"
+'\" Copyright (c) 1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Ajuba Solutions.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_Main 3 8.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Main, Tcl_SetStartupScript, Tcl_GetStartupScript, Tcl_SetMainLoop \- main program, startup script, and event loop definition for Tcl-based applications
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_Main\fR(\fIargc, argv, appInitProc\fR)
+.sp
+\fBTcl_SetStartupScript\fR(\fIpath, encoding\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetStartupScript\fR(\fIencodingPtr\fR)
+.sp
+\fBTcl_SetMainLoop\fR(\fImainLoopProc\fR)
+.SH ARGUMENTS
+.AS Tcl_MainLoopProc *mainLoopProc
+.AP int argc in
+Number of elements in \fIargv\fR.
+.AP char *argv[] in
+Array of strings containing command-line arguments. On Windows, when
+using -DUNICODE, the parameter type changes to wchar_t *.
+.AP Tcl_AppInitProc *appInitProc in
+Address of an application-specific initialization procedure.
+The value for this argument is usually \fBTcl_AppInit\fR.
+.AP Tcl_Obj *path in
+Name of file to use as startup script, or NULL.
+.AP "const char" *encoding in
+Encoding of file to use as startup script, or NULL.
+.AP "const char" **encodingPtr out
+If non-NULL, location to write a copy of the (const char *)
+pointing to the encoding name.
+.AP Tcl_MainLoopProc *mainLoopProc in
+Address of an application-specific event loop procedure.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_Main\fR can serve as the main program for Tcl-based shell
+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
+to developers of shell applications, so they do not have to
+reproduce all of the code for proper initialization of the Tcl
+library and interactive shell operation. Other styles of embedding
+Tcl in an application are not supported by \fBTcl_Main\fR. Those
+must be achieved by calling lower level functions in the Tcl library
+directly.
+.PP
+The \fBTcl_Main\fR function has been offered by the Tcl library
+since release Tcl 7.4. In older releases of Tcl, the Tcl library
+itself defined a function \fBmain\fR, but that lacks flexibility
+of embedding style and having a function \fBmain\fR in a library
+(particularly a shared library) causes problems on many systems.
+Having \fBmain\fR in the Tcl library would also make it hard to use
+Tcl in C++ programs, since C++ programs must have special C++
+\fBmain\fR functions.
+.PP
+Normally each shell application contains a small \fBmain\fR function
+that does nothing but invoke \fBTcl_Main\fR.
+\fBTcl_Main\fR then does all the work of creating and running a
+\fBtclsh\fR-like application.
+.PP
+\fBTcl_Main\fR is not provided by the public interface of Tcl's
+stub library. Programs that call \fBTcl_Main\fR must be linked
+against the standard Tcl library. Extensions (stub-enabled or
+not) are not intended to call \fBTcl_Main\fR.
+.PP
+\fBTcl_Main\fR is not thread-safe. It should only be called by
+a single master thread of a multi-threaded application. This
+restriction is not a problem with normal use described above.
+.PP
+\fBTcl_Main\fR and therefore all applications based upon it, like
+\fBtclsh\fR, use \fBTcl_GetStdChannel\fR to initialize the standard
+channels to their default values. See \fBTcl_StandardChannels\fR for
+more information.
+.PP
+\fBTcl_Main\fR supports two modes of operation, depending on
+whether the filename and encoding of a startup script has been
+established. The routines \fBTcl_SetStartupScript\fR and
+\fBTcl_GetStartupScript\fR are the tools for controlling this
+configuration of \fBTcl_Main\fR.
+.PP
+\fBTcl_SetStartupScript\fR registers the value \fIpath\fR
+as the name of the file for \fBTcl_Main\fR to evaluate as
+its startup script. The value \fIencoding\fR is Tcl's name
+for the encoding used to store the text in that file. A
+value of \fBNULL\fR for \fIencoding\fR is a signal to use
+the system encoding. A value of \fBNULL\fR for \fIpath\fR
+erases any existing registration so that \fBTcl_Main\fR
+will not evaluate any startup script.
+.PP
+\fBTcl_GetStartupScript\fR queries the registered file name
+and encoding set by the most recent \fBTcl_SetStartupScript\fR
+call in the same thread. The stored file name is returned,
+and the stored encoding name is written to space pointed to
+by \fIencodingPtr\fR, when that is not NULL.
+.PP
+The file name and encoding values managed by the routines
+\fBTcl_SetStartupScript\fR and \fBTcl_GetStartupScript\fR
+are stored per-thread. Although the storage and retrieval
+functions of these routines work in any thread, only those
+calls in the same master thread as \fBTcl_Main\fR can have
+any influence on it.
+.PP
+The caller of \fBTcl_Main\fR may call \fBTcl_SetStartupScript\fR
+first to establish its desired startup script. If \fBTcl_Main\fR
+finds that no such startup script has been established, it consults
+the first few arguments in \fIargv\fR. If they 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. \fBTcl_Main\fR
+then calls \fBTcl_SetStartupScript\fR with these values.
+.PP
+\fBTcl_Main\fR then defines in its master interpreter
+the Tcl variables \fIargc\fR, \fIargv\fR, \fIargv0\fR, and
+\fItcl_interactive\fR, as described in the documentation for \fBtclsh\fR.
+.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
+.QW hook
+for the application to perform its own initialization of the interpreter
+created by \fBTcl_Main\fR, such as defining application-specific
+commands. The application initialization routine might also
+call \fBTcl_SetStartupScript\fR to (re-)set the file and encoding
+to be used as a startup script. The procedure must have an interface
+that matches the type \fBTcl_AppInitProc\fR:
+.PP
+.CS
+typedef int \fBTcl_AppInitProc\fR(
+ Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+\fIAppInitProc\fR is almost always a pointer to \fBTcl_AppInit\fR; for more
+details on this procedure, see the documentation for \fBTcl_AppInit\fR.
+.PP
+When the \fIappInitProc\fR is finished, \fBTcl_Main\fR calls
+\fBTcl_GetStartupScript\fR to determine what startup script has
+been requested, if any. If a startup script has been provided,
+\fBTcl_Main\fR attempts to evaluate it. Otherwise, interactive
+mode begins with examination of the variable \fItcl_rcFileName\fR
+in the master interpreter. If that variable exists and holds the
+name of a readable file, the contents of that file are evaluated
+in the master interpreter. Then interactive operations begin,
+with prompts and command evaluation results written to the standard
+output channel, and commands read from the standard input channel
+and then evaluated. The prompts written to the standard output
+channel may be customized by defining the Tcl variables \fItcl_prompt1\fR
+and \fItcl_prompt2\fR as described in the documentation for \fBtclsh\fR.
+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
+\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
+are in interactive mode, setting the main loop procedure will cause the
+prompt to become fileevent based and then the loop procedure is called.
+When the loop procedure returns in interactive mode, interactive operation
+will continue.
+The main loop procedure must have an interface that matches the type
+\fBTcl_MainLoopProc\fR:
+.PP
+.CS
+typedef void \fBTcl_MainLoopProc\fR(void);
+.CE
+.PP
+\fBTcl_Main\fR does not return. Normally a program based on
+\fBTcl_Main\fR will terminate when the \fBexit\fR command is
+evaluated. In interactive mode, if an EOF or channel error
+is encountered on the standard input channel, then \fBTcl_Main\fR
+itself will evaluate the \fBexit\fR command after the main loop
+procedure (if any) returns. In non-interactive mode, after
+\fBTcl_Main\fR evaluates the startup script, and the main loop
+procedure (if any) returns, \fBTcl_Main\fR will also evaluate
+the \fBexit\fR command.
+.SH "SEE ALSO"
+tclsh(1), Tcl_GetStdChannel(3), Tcl_StandardChannels(3), Tcl_AppInit(3),
+exit(n), encoding(n)
+.SH KEYWORDS
+application-specific initialization, command-line arguments, main program
diff --git a/library/msgcat/doc/Thread.3 b/library/msgcat/doc/Thread.3
new file mode 100644
index 0000000..ca135ee
--- /dev/null
+++ b/library/msgcat/doc/Thread.3
@@ -0,0 +1,241 @@
+'\"
+'\" Copyright (c) 1999 Scriptics Corporation
+'\" 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.
+'\"
+.so man.macros
+.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
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_ConditionNotify\fR(\fIcondPtr\fR)
+.sp
+void
+\fBTcl_ConditionWait\fR(\fIcondPtr, mutexPtr, timePtr\fR)
+.sp
+void
+\fBTcl_ConditionFinalize\fR(\fIcondPtr\fR)
+.sp
+Void *
+\fBTcl_GetThreadData\fR(\fIkeyPtr, size\fR)
+.sp
+void
+\fBTcl_MutexLock\fR(\fImutexPtr\fR)
+.sp
+void
+\fBTcl_MutexUnlock\fR(\fImutexPtr\fR)
+.sp
+void
+\fBTcl_MutexFinalize\fR(\fImutexPtr\fR)
+.sp
+int
+\fBTcl_CreateThread\fR(\fIidPtr, proc, clientData, stackSize, flags\fR)
+.sp
+int
+\fBTcl_JoinThread\fR(\fIid, result\fR)
+.SH ARGUMENTS
+.AS Tcl_CreateThreadProc proc 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 "const Tcl_Time" *timePtr in
+A time limit on the condition wait. NULL to wait forever.
+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
+a different block of storage with this key.
+.AP int *size in
+The size of the thread local storage block. This amount of data
+is allocated and initialized to zero the first time each thread
+calls \fBTcl_GetThreadData\fR.
+.AP Tcl_ThreadId *idPtr out
+The referred storage will contain the id of the newly created thread as
+returned by the operating system.
+.AP Tcl_ThreadId id in
+Id of the thread waited upon.
+.AP Tcl_ThreadCreateProc *proc in
+This procedure will act as the \fBmain()\fR of the newly created
+thread. The specified \fIclientData\fR will be its sole argument.
+.AP ClientData clientData in
+Arbitrary information. Passed as sole argument to the \fIproc\fR.
+.AP int stackSize in
+The size of the stack given to the new thread.
+.AP int flags in
+Bitmask containing flags allowing the caller to modify behavior of
+the new thread.
+.AP int *result out
+The referred storage is used to place the exit code of the thread
+waited upon into it.
+.BE
+.SH INTRODUCTION
+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
+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, 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 behavior through the supplied \fIflags\fR. The value
+\fBTCL_THREAD_STACK_DEFAULT\fR for the \fIstackSize\fR indicates that
+the default size as specified by the operating system is to be used
+for the new thread. As for the flags, currently only the values
+\fBTCL_THREAD_NOFLAGS\fR and \fBTCL_THREAD_JOINABLE\fR are defined. The
+first of them invokes the default behavior with no special settings.
+Using the second value marks the new thread as \fIjoinable\fR. This
+means that another thread can wait for the such marked thread to exit
+and join it.
+.PP
+Restrictions: On some UNIX systems the pthread-library does not
+contain the functionality to specify the stack size of a thread. The
+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 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
+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
+its creation via \fBTcl_CreateThread\fR.
+.PP
+Trying to wait for the exit of a non-joinable thread or a thread which
+is already waited upon will result in an error. Waiting for a joinable
+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.
+.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 queuing in multithreaded applications. See
+the \fBNotifier\fR manual page for more information on these procedures.
+.PP
+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.
+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.
+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.
+.PP
+A condition variable is used as a signaling mechanism:
+a thread can lock a mutex and then wait on a condition variable
+with \fBTcl_ConditionWait\fR. This atomically releases the mutex lock
+and blocks the waiting thread until another thread calls
+\fBTcl_ConditionNotify\fR. The caller of \fBTcl_ConditionNotify\fR should
+have the associated mutex held by previously calling \fBTcl_MutexLock\fR,
+but this is not enforced. Notifying the
+condition variable unblocks all threads waiting on the condition variable,
+but they do not proceed until the mutex is released with \fBTcl_MutexUnlock\fR.
+The implementation of \fBTcl_ConditionWait\fR automatically locks
+the mutex before returning.
+.PP
+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
+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.
+.SS INITIALIZATION
+.PP
+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
+either cleaned up by process exit handlers (if living that long) or
+explicitly by calls to \fBTcl_MutexFinalize\fR or
+\fBTcl_ConditionFinalize\fR.
+Thread local storage is reclaimed during \fBTcl_FinalizeThread\fR.
+.SH "SCRIPT-LEVEL ACCESS TO THREADS"
+.PP
+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.
+.SH EXAMPLE
+.PP
+To create a thread with portable code, its implementation function should be
+declared as follows:
+.PP
+.CS
+static \fBTcl_ThreadCreateProc\fR MyThreadImplFunc;
+.CE
+.PP
+It should then be defined like this example, which just counts up to a given
+value and then finishes.
+.PP
+.CS
+static \fBTcl_ThreadCreateType\fR
+MyThreadImplFunc(
+ ClientData clientData)
+{
+ int i, limit = (int) clientData;
+ for (i=0 ; i<limit ; i++) {
+ /* doing nothing at all here */
+ }
+ \fBTCL_THREAD_CREATE_RETURN\fR;
+}
+.CE
+.PP
+To create the above thread, make it execute, and wait for it to finish, we
+would do this:
+.PP
+.CS
+int limit = 1000000000;
+ClientData limitData = (void*)((intptr_t) limit);
+Tcl_ThreadId id; \fI/* holds identity of thread created */\fR
+int result;
+
+if (\fBTcl_CreateThread\fR(&id, MyThreadImplFunc, limitData,
+ \fBTCL_THREAD_STACK_DEFAULT\fR,
+ \fBTCL_THREAD_JOINABLE\fR) != TCL_OK) {
+ \fI/* Thread did not create correctly */\fR
+ return;
+}
+\fI/* Do something else for a while here */\fR
+if (\fBTcl_JoinThread\fR(id, &result) != TCL_OK) {
+ \fI/* Thread did not finish properly */\fR
+ return;
+}
+\fI/* All cleaned up nicely */\fR
+.CE
+.SH "SEE ALSO"
+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/library/msgcat/doc/ToUpper.3 b/library/msgcat/doc/ToUpper.3
new file mode 100644
index 0000000..d6b3006
--- /dev/null
+++ b/library/msgcat/doc/ToUpper.3
@@ -0,0 +1,88 @@
+'\"
+'\" Copyright (c) 1997 by 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_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
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_UniChar
+\fBTcl_UniCharToUpper\fR(\fIch\fR)
+.sp
+Tcl_UniChar
+\fBTcl_UniCharToLower\fR(\fIch\fR)
+.sp
+Tcl_UniChar
+\fBTcl_UniCharToTitle\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UtfToUpper\fR(\fIstr\fR)
+.sp
+int
+\fBTcl_UtfToLower\fR(\fIstr\fR)
+.sp
+int
+\fBTcl_UtfToTitle\fR(\fIstr\fR)
+.SH ARGUMENTS
+.AS char *str in/out
+.AP int ch in
+The Tcl_UniChar to be converted.
+.AP char *str in/out
+Pointer to UTF-8 string to be converted in place.
+.BE
+
+.SH DESCRIPTION
+.PP
+The first three routines convert the case of individual Unicode characters:
+.PP
+If \fIch\fR represents a lower-case character,
+\fBTcl_UniCharToUpper\fR returns the corresponding upper-case
+character. If no upper-case character is defined, it returns the
+character unchanged.
+.PP
+If \fIch\fR represents an upper-case character,
+\fBTcl_UniCharToLower\fR returns the corresponding lower-case
+character. If no lower-case character is defined, it returns the
+character unchanged.
+.PP
+If \fIch\fR represents a lower-case character,
+\fBTcl_UniCharToTitle\fR returns the corresponding title-case
+character. If no title-case character is defined, it returns the
+corresponding upper-case character. If no upper-case character is
+defined, it returns the character unchanged. Title-case is defined
+for a small number of characters that have a different appearance when
+they are at the beginning of a capitalized word.
+.PP
+The next three routines convert the case of UTF-8 strings in place in
+memory:
+.PP
+\fBTcl_UtfToUpper\fR changes every UTF-8 character in \fIstr\fR to
+upper-case. Because changing the case of a character may change its
+size, the byte offset of each character in the resulting string may
+differ from its original location. \fBTcl_UtfToUpper\fR writes a null
+byte at the end of the converted string. \fBTcl_UtfToUpper\fR returns
+the new length of the string in bytes. This new length is guaranteed
+to be no longer than the original string length.
+.PP
+\fBTcl_UtfToLower\fR is the same as \fBTcl_UtfToUpper\fR except it
+turns each character in the string into its lower-case equivalent.
+.PP
+\fBTcl_UtfToTitle\fR is the same as \fBTcl_UtfToUpper\fR except it
+turns the first character in the string into its title-case equivalent
+and all following characters into their lower-case equivalents.
+
+.SH BUGS
+.PP
+At this time, the case conversions are only defined for the ISO8859-1
+characters. Unicode characters above 0x00ff are not modified by these
+routines.
+
+.SH KEYWORDS
+utf, unicode, toupper, tolower, totitle, case
diff --git a/library/msgcat/doc/TraceCmd.3 b/library/msgcat/doc/TraceCmd.3
new file mode 100644
index 0000000..5cc1337
--- /dev/null
+++ b/library/msgcat/doc/TraceCmd.3
@@ -0,0 +1,163 @@
+'\"
+'\" Copyright (c) 2002 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_TraceCommand 3 7.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CommandTraceInfo, Tcl_TraceCommand, Tcl_UntraceCommand \- monitor renames and deletes of a command
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+ClientData
+\fBTcl_CommandTraceInfo(\fIinterp, cmdName, flags, proc, prevClientData\fB)\fR
+.sp
+int
+\fBTcl_TraceCommand(\fIinterp, cmdName, flags, proc, clientData\fB)\fR
+.sp
+void
+\fBTcl_UntraceCommand(\fIinterp, cmdName, flags, proc, clientData\fB)\fR
+.SH ARGUMENTS
+.AS Tcl_CommandTraceProc prevClientData
+.AP Tcl_Interp *interp in
+Interpreter containing the command.
+.AP "const char" *cmdName in
+Name of command.
+.AP int flags in
+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
+Arbitrary argument to pass to \fIproc\fR.
+.AP ClientData prevClientData in
+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 \fBTCL_OK\fR. If an error
+occurred (e.g. \fIcmdName\fR specifies a non-existent command) then
+\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
+of any of the following values:
+.TP
+\fBTCL_TRACE_RENAME\fR
+Invoke \fIproc\fR whenever the command is renamed.
+.TP
+\fBTCL_TRACE_DELETE\fR
+Invoke \fIproc\fR when the command is deleted.
+.PP
+Whenever one of the specified operations occurs to the command,
+\fIproc\fR will be invoked. It should have arguments and result that
+match the type \fBTcl_CommandTraceProc\fR:
+.PP
+.CS
+typedef void \fBTcl_CommandTraceProc\fR(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ const char *\fIoldName\fR,
+ const char *\fInewName\fR,
+ int \fIflags\fR);
+.CE
+.PP
+The \fIclientData\fR and \fIinterp\fR parameters will have the same
+values as those passed to \fBTcl_TraceCommand\fR when the trace was
+created. \fIClientData\fR typically points to an application-specific
+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 \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
+\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
+\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 \fBTCL_INTERP_DESTROYED\fR
+below).
+.PP
+\fBTcl_UntraceCommand\fR may be used to remove a trace. If the
+command specified by \fIinterp\fR, \fIcmdName\fR, and \fIflags\fR has
+a trace set with \fIflags\fR, \fIproc\fR, and \fIclientData\fR, then
+the corresponding trace is removed. If no such trace exists, then the
+call to \fBTcl_UntraceCommand\fR has no effect. The same bits are
+valid for \fIflags\fR as for calls to \fBTcl_TraceCommand\fR.
+.PP
+\fBTcl_CommandTraceInfo\fR may be used to retrieve information about
+traces set on a given command.
+The return value from \fBTcl_CommandTraceInfo\fR is the \fIclientData\fR
+associated with a particular trace.
+The trace must be on the command specified by the \fIinterp\fR,
+\fIcmdName\fR, and \fIflags\fR arguments (note that currently the
+flags are ignored; \fIflags\fR should be set to 0 for future
+compatibility) 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 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
+\fIprevClientData\fR, or NULL if no trace matches \fIprevClientData\fR
+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 \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.
+When this happens, all of the trace procedures will be invoked on each
+access, in order from most-recently-created to least-recently-created.
+Attempts to delete the command during a delete trace will fail
+silently, since the command is already scheduled for deletion anyway.
+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 \fBTCL_TRACE_DESTROYED\fR bit
+is set in \fIflags\fR.
+.\" 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 \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 \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 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/library/msgcat/doc/TraceVar.3 b/library/msgcat/doc/TraceVar.3
new file mode 100644
index 0000000..6201a4f
--- /dev/null
+++ b/library/msgcat/doc/TraceVar.3
@@ -0,0 +1,380 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_TraceVar 3 7.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_TraceVar, Tcl_TraceVar2, Tcl_UntraceVar, Tcl_UntraceVar2, Tcl_VarTraceInfo, Tcl_VarTraceInfo2 \- monitor accesses to a variable
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_TraceVar(\fIinterp, varName, flags, proc, clientData\fB)\fR
+.sp
+int
+\fBTcl_TraceVar2(\fIinterp, name1, name2, flags, proc, clientData\fB)\fR
+.sp
+\fBTcl_UntraceVar(\fIinterp, varName, flags, proc, clientData\fB)\fR
+.sp
+\fBTcl_UntraceVar2(\fIinterp, name1, name2, flags, proc, clientData\fB)\fR
+.sp
+ClientData
+\fBTcl_VarTraceInfo(\fIinterp, varName, flags, proc, prevClientData\fB)\fR
+.sp
+ClientData
+\fBTcl_VarTraceInfo2(\fIinterp, name1, name2, flags, proc, prevClientData\fB)\fR
+.SH ARGUMENTS
+.AS Tcl_VarTraceProc prevClientData
+.AP Tcl_Interp *interp in
+Interpreter containing variable.
+.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 \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
+Name of scalar or array variable (without array index).
+.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.
+.AP ClientData prevClientData in
+If non-NULL, gives last value returned by \fBTcl_VarTraceInfo\fR or
+\fBTcl_VarTraceInfo2\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_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
+\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
+trace procedure is to be invoked and provides information
+for setting up the trace. It consists of an OR-ed combination
+of any of the following values:
+.TP
+\fBTCL_GLOBAL_ONLY\fR
+Normally, the variable will be looked up at the current level of
+procedure call; if this bit is set then the variable will be looked
+up at global level, ignoring any active procedures.
+.TP
+\fBTCL_NAMESPACE_ONLY\fR
+Normally, the variable will be looked up at the current level of
+procedure call; if this bit is set then the variable will be looked
+up in the current namespace, ignoring any active procedures.
+.TP
+\fBTCL_TRACE_READS\fR
+Invoke \fIproc\fR whenever an attempt is made to read the variable.
+.TP
+\fBTCL_TRACE_WRITES\fR
+Invoke \fIproc\fR whenever an attempt is made to modify the variable.
+.TP
+\fBTCL_TRACE_UNSETS\fR
+Invoke \fIproc\fR whenever the variable is unset.
+A variable may be unset either explicitly by an \fBunset\fR command,
+or implicitly when a procedure returns (its local variables are
+automatically unset) or when the interpreter is deleted (all
+variables are automatically unset).
+.TP
+\fBTCL_TRACE_ARRAY\fR
+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.
+.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
+\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 \fBTCL_TRACE_RESULT_DYNAMIC\fR.
+.PP
+Whenever one of the specified operations occurs on the variable,
+\fIproc\fR will be invoked.
+It should have arguments and result that match the type
+\fBTcl_VarTraceProc\fR:
+.PP
+.CS
+typedef char *\fBTcl_VarTraceProc\fR(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ char *\fIname1\fR,
+ char *\fIname2\fR,
+ int \fIflags\fR);
+.CE
+.PP
+The \fIclientData\fR and \fIinterp\fR parameters will
+have the same values as those passed to \fBTcl_TraceVar\fR when the
+trace was created.
+\fIClientData\fR typically points to an application-specific
+data structure that describes what to do when \fIproc\fR
+is invoked.
+\fIName1\fR and \fIname2\fR give the name of the traced variable
+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 \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 \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 \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 \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 \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 \fBTCL_INTERP_DESTROYED\fR below).
+The trace procedure's return value should normally be NULL; see
+\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
+has a trace set with \fIflags\fR, \fIproc\fR, and
+\fIclientData\fR, then the corresponding trace is removed.
+If no such trace exists, then the call to \fBTcl_UntraceVar\fR
+has no effect.
+The same bits are valid for \fIflags\fR as for calls to \fBTcl_TraceVar\fR.
+.PP
+\fBTcl_VarTraceInfo\fR may be used to retrieve information about
+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 \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 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
+\fIprevClientData\fR, or NULL if no trace matches \fIprevClientData\fR
+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
+\fBTcl_VarTraceInfo2\fR are identical to \fBTcl_TraceVar\fR,
+\fBTcl_UntraceVar\fR, and \fBTcl_VarTraceInfo\fR, respectively,
+except that the name of the variable consists of two parts.
+\fIName1\fR gives the name of a scalar variable or array,
+and \fIname2\fR gives the name of an element within an array.
+When \fIname2\fR is NULL,
+\fIname1\fR may contain both an array and an element name:
+if the name contains an open parenthesis and ends with a
+close parenthesis, then the value between the parentheses is
+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 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
+trace procedure can read, write, or unset the traced
+variable using \fBTcl_GetVar2\fR, \fBTcl_SetVar2\fR, and
+other procedures.
+While \fIproc\fR is executing, traces are temporarily disabled
+for the variable, so that calls to \fBTcl_GetVar2\fR and
+\fBTcl_SetVar2\fR will not cause \fIproc\fR or other trace procedures
+to be invoked again.
+Disabling only occurs for the variable whose trace procedure
+is active; accesses to other variables will still be traced.
+However, if a variable is unset during a read or write trace then unset
+traces will be invoked.
+.PP
+During unset traces the variable has already been completely
+expunged.
+It is possible for the trace procedure to read or write the
+variable, but this will be a new version of the variable.
+Traces are not disabled during unset traces as they are for
+read and write traces, but existing traces have been removed
+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
+procedure will be invoked whenever the variable's value is
+read. This includes \fBset\fR Tcl commands, \fB$\fR-notation
+in Tcl commands, and invocations of the \fBTcl_GetVar\fR
+and \fBTcl_GetVar2\fR procedures.
+\fIProc\fR is invoked just before the variable's value is
+returned.
+It may modify the value of the variable to affect what
+is returned by the traced access.
+If it unsets the variable then the access will return an error
+just as if the variable never existed.
+.PP
+When write tracing has been specified for a variable, the
+trace procedure will be invoked whenever the variable's value
+is modified. This includes \fBset\fR commands,
+commands that modify variables as side effects (such as
+\fBcatch\fR and \fBscan\fR), and calls to the \fBTcl_SetVar\fR
+and \fBTcl_SetVar2\fR procedures).
+\fIProc\fR will be invoked after the variable's value has been
+modified, but before the new value of the variable has been
+returned.
+It may modify the value of the variable to override the change
+and to determine the value actually returned by the traced
+access.
+If it deletes the variable then the traced access will return
+an empty string.
+.PP
+When array tracing has been specified, the trace procedure
+will be invoked at the beginning of the array command implementation,
+before any of the operations like get, set, or names have been invoked.
+The trace procedure can modify the array elements with \fBTcl_SetVar\fR
+and \fBTcl_SetVar2\fR.
+.PP
+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
+the name of an array variable without an index into the array,
+then the trace will be set on the array as a whole.
+This means that \fIproc\fR will be invoked whenever any
+element of the array is accessed in the ways specified by
+\fIflags\fR.
+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.
+When this happens, all of the trace procedures will be invoked on each
+access, in order from most-recently-created to least-recently-created.
+When there exist whole-array traces for an array as well as
+traces on individual elements, the whole-array traces are invoked
+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
+successful completion.
+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,
+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.
+If a trace procedure returns an error, no further traces are
+invoked for the access and the traced access aborts with the
+given message.
+Trace procedures can use this facility to make variables
+read-only, for example (but note that the value of the variable
+will already have been modified before the trace procedure is
+called, so the trace procedure will have to restore the correct
+value).
+.PP
+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
+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
+.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 \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 \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 \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 \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 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 \fBinfo exists\fR command,
+nor is there Tcl-level access to array traces.
+.SH "SEE ALSO"
+trace(n)
+.SH KEYWORDS
+clientData, trace, variable
diff --git a/library/msgcat/doc/Translate.3 b/library/msgcat/doc/Translate.3
new file mode 100644
index 0000000..55233c3
--- /dev/null
+++ b/library/msgcat/doc/Translate.3
@@ -0,0 +1,71 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-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_TranslateFileName 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_TranslateFileName \- convert file name to native form and replace tilde with home directory
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+char *
+\fBTcl_TranslateFileName\fR(\fIinterp\fR, \fIname\fR, \fIbufferPtr\fR)
+.SH ARGUMENTS
+.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
+.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
+caller must eventually call \fBTcl_DStringFree\fR to free up
+anything stored here.
+.BE
+.SH DESCRIPTION
+.PP
+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_FSGetNativePath\fR, there is no longer any need to use this
+procedure. In particular, \fBTcl_FSGetNativePath\fR performs all the
+necessary translation and encoding conversion, is virtual-filesystem
+aware, and caches the native result for faster repeated calls.
+Finally \fBTcl_FSGetNativePath\fR does not require you to free anything
+afterwards.
+.PP
+If
+\fBTcl_TranslateFileName\fR has to do tilde substitution or translate
+the name then it uses
+the dynamic string at \fI*bufferPtr\fR to hold the new string it
+generates.
+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 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
+name) then NULL is returned and an error message will be left
+in the interpreter's result.
+When an error occurs, \fBTcl_TranslateFileName\fR
+frees the dynamic string itself so that the caller need not call
+\fBTcl_DStringFree\fR.
+.PP
+The caller is responsible for making sure that the interpreter's result
+has its default empty value when \fBTcl_TranslateFileName\fR is invoked.
+.SH "SEE ALSO"
+filename(n)
+.SH KEYWORDS
+file name, home directory, tilde, translate, user
diff --git a/library/msgcat/doc/UniCharIsAlpha.3 b/library/msgcat/doc/UniCharIsAlpha.3
new file mode 100644
index 0000000..6029b2d
--- /dev/null
+++ b/library/msgcat/doc/UniCharIsAlpha.3
@@ -0,0 +1,91 @@
+'\"
+'\" 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 Tcl_UniCharIsAlpha 3 "8.1" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_UniCharIsAlnum, Tcl_UniCharIsAlpha, Tcl_UniCharIsControl, Tcl_UniCharIsDigit, Tcl_UniCharIsGraph, Tcl_UniCharIsLower, Tcl_UniCharIsPrint, Tcl_UniCharIsPunct, Tcl_UniCharIsSpace, Tcl_UniCharIsUpper, Tcl_UniCharIsWordChar \- routines for classification of Tcl_UniChar characters
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_UniCharIsAlnum\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsAlpha\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsControl\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsDigit\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsGraph\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsLower\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsPrint\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsPunct\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsSpace\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsUpper\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsWordChar\fR(\fIch\fR)
+.SH ARGUMENTS
+.AS int ch
+.AP int ch in
+The Tcl_UniChar to be examined.
+.BE
+
+.SH DESCRIPTION
+.PP
+All of the routines described examine Tcl_UniChars and return a
+boolean value. A non-zero return value means that the character does
+belong to the character class associated with the called routine. The
+rest of this document just describes the character classes associated
+with the various routines.
+.PP
+Note: A Tcl_UniChar is a Unicode character represented as an unsigned,
+fixed-size quantity.
+
+.SH "CHARACTER CLASSES"
+.PP
+\fBTcl_UniCharIsAlnum\fR tests if the character is an alphanumeric Unicode character.
+.PP
+\fBTcl_UniCharIsAlpha\fR tests if the character is an alphabetic Unicode character.
+.PP
+\fBTcl_UniCharIsControl\fR tests if the character is a Unicode control character.
+.PP
+\fBTcl_UniCharIsDigit\fR tests if the character is a numeric Unicode character.
+.PP
+\fBTcl_UniCharIsGraph\fR tests if the character is any Unicode print character except space.
+.PP
+\fBTcl_UniCharIsLower\fR tests if the character is a lowercase Unicode character.
+.PP
+\fBTcl_UniCharIsPrint\fR tests if the character is a Unicode print character.
+.PP
+\fBTcl_UniCharIsPunct\fR tests if the character is a Unicode punctuation character.
+.PP
+\fBTcl_UniCharIsSpace\fR tests if the character is a whitespace Unicode character.
+.PP
+\fBTcl_UniCharIsUpper\fR tests if the character is an uppercase Unicode character.
+.PP
+\fBTcl_UniCharIsWordChar\fR tests if the character is alphanumeric or
+a connector punctuation mark.
+
+.SH KEYWORDS
+unicode, classification
diff --git a/library/msgcat/doc/UpVar.3 b/library/msgcat/doc/UpVar.3
new file mode 100644
index 0000000..f1e6fe4
--- /dev/null
+++ b/library/msgcat/doc/UpVar.3
@@ -0,0 +1,74 @@
+'\"
+'\" Copyright (c) 1994 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 Tcl_UpVar 3 7.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_UpVar, Tcl_UpVar2 \- link one variable to another
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_UpVar(\fIinterp, frameName, sourceName, destName, flags\fB)\fR
+.sp
+int
+\fBTcl_UpVar2(\fIinterp, frameName, name1, name2, destName, flags\fB)\fR
+.SH ARGUMENTS
+.AS "const char" *sourceName
+.AP Tcl_Interp *interp in
+Interpreter containing variables; also used for error reporting.
+.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
+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
+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
+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
+If source variable is an element of an array, gives the index of the element.
+For scalar source variables, is NULL.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_UpVar\fR and \fBTcl_UpVar2\fR provide the same functionality
+as the \fBupvar\fR command: they make a link from a source variable
+to a destination variable, so that references to the destination are
+passed transparently through to the source.
+The name of the source variable may be specified either as a single
+string such as \fBxyx\fR or \fBa(24)\fR (by calling \fBTcl_UpVar\fR)
+or in two parts where the array name has been separated from the
+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 \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;
+if it does exist, unsetting it later does not destroy the link. The
+destination variable may exist at the time of the call, but if so
+it must exist as a linked variable.
+
+.SH KEYWORDS
+linked variable, upvar, variable
diff --git a/library/msgcat/doc/Utf.3 b/library/msgcat/doc/Utf.3
new file mode 100644
index 0000000..55906e7
--- /dev/null
+++ b/library/msgcat/doc/Utf.3
@@ -0,0 +1,259 @@
+'\"
+'\" 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 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
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+typedef ... \fBTcl_UniChar\fR;
+.sp
+int
+\fBTcl_UniCharToUtf\fR(\fIch, buf\fR)
+.sp
+int
+\fBTcl_UtfToUniChar\fR(\fIsrc, chPtr\fR)
+.sp
+char *
+\fBTcl_UniCharToUtfDString\fR(\fIuniStr, uniLength, dsPtr\fR)
+.sp
+Tcl_UniChar *
+\fBTcl_UtfToUniCharDString\fR(\fIsrc, length, dsPtr\fR)
+.sp
+int
+\fBTcl_UniCharLen\fR(\fIuniStr\fR)
+.sp
+int
+\fBTcl_UniCharNcmp\fR(\fIucs, uct, numChars\fR)
+.sp
+int
+\fBTcl_UniCharNcasecmp\fR(\fIucs, uct, numChars\fR)
+.sp
+int
+\fBTcl_UniCharCaseMatch\fR(\fIuniStr, uniPattern, nocase\fR)
+.sp
+int
+\fBTcl_UtfNcmp\fR(\fIcs, ct, numChars\fR)
+.sp
+int
+\fBTcl_UtfNcasecmp\fR(\fIcs, ct, numChars\fR)
+.sp
+int
+\fBTcl_UtfCharComplete\fR(\fIsrc, length\fR)
+.sp
+int
+\fBTcl_NumUtfChars\fR(\fIsrc, length\fR)
+.sp
+const char *
+\fBTcl_UtfFindFirst\fR(\fIsrc, ch\fR)
+.sp
+const char *
+\fBTcl_UtfFindLast\fR(\fIsrc, ch\fR)
+.sp
+const char *
+\fBTcl_UtfNext\fR(\fIsrc\fR)
+.sp
+const char *
+\fBTcl_UtfPrev\fR(\fIsrc, start\fR)
+.sp
+Tcl_UniChar
+\fBTcl_UniCharAtIndex\fR(\fIsrc, index\fR)
+.sp
+const char *
+\fBTcl_UtfAtIndex\fR(\fIsrc, index\fR)
+.sp
+int
+\fBTcl_UtfBackslash\fR(\fIsrc, readPtr, dst\fR)
+.SH ARGUMENTS
+.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
+\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
+Pointer to a UTF-8 string.
+.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
+A null-terminated Unicode string.
+.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 uniLength in
+The length of the Unicode string in characters. Must be greater than or
+equal to 0.
+.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
+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.
+.AP int *readPtr out
+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 \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).
+.BE
+
+.SH DESCRIPTION
+.PP
+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 \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
+represent one Unicode character in the UTF-8 representation.
+.PP
+\fBTcl_UniCharToUtf\fR stores the Tcl_UniChar \fIch\fR as a UTF-8 string
+in starting at \fIbuf\fR. The return value is the number of bytes stored
+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
+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
+not in proper UTF-8 format, \fBTcl_UtfToUniChar\fR will store the first
+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 \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.
+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
+is appended to the end of the \fBTcl_DString\fR. The Unicode string
+is terminated with a Unicode null character.
+.PP
+\fBTcl_UniCharLen\fR corresponds to \fBstrlen\fR for Unicode
+characters. It accepts a null-terminated Unicode string and returns
+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 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
+\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.
+.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 \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
+first string is greater than, equal to, or less than the second string
+respectively.
+.PP
+\fBTcl_UtfNcasecmp\fR corresponds to \fBstrncasecmp\fR for UTF-8
+strings. It is similar to \fBTcl_UtfNcmp\fR except comparisons ignore
+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 \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
+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 \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
+returns a pointer to the first occurrence of the Tcl_UniChar \fIch\fR
+in the null-terminated UTF-8 string \fIsrc\fR. The null terminator is
+considered part of the UTF-8 string.
+.PP
+\fBTcl_UtfFindLast\fR corresponds to \fBstrrchr\fR for UTF-8 strings. It
+returns a pointer to the last occurrence of the Tcl_UniChar \fIch\fR
+in the null-terminated UTF-8 string \fIsrc\fR. The null terminator is
+considered part of the UTF-8 string.
+.PP
+Given \fIsrc\fR, a pointer to some location in a UTF-8 string,
+\fBTcl_UtfNext\fR returns a pointer to the next UTF-8 character in the
+string. The caller must not ask for the next character after the last
+character in the string if the string is not terminated by a null
+character.
+.PP
+Given \fIsrc\fR, a pointer to some location in a UTF-8 string (or to a
+null byte immediately following such a string), \fBTcl_UtfPrev\fR
+returns a pointer to the closest preceding byte that starts a UTF-8
+character.
+This function will not back up to a position before \fIstart\fR,
+the start of the UTF-8 string. If \fIsrc\fR was already at \fIstart\fR, the
+return value will be \fIstart\fR.
+.PP
+\fBTcl_UniCharAtIndex\fR corresponds to a C string array dereference or the
+Pascal Ord() function. It returns the Tcl_UniChar represented at the
+specified character (not byte) \fIindex\fR in the UTF-8 string
+\fIsrc\fR. The source string must contain at least \fIindex\fR
+characters. Behavior is undefined if a negative \fIindex\fR is given.
+.PP
+\fBTcl_UtfAtIndex\fR returns a pointer to the specified character (not
+byte) \fIindex\fR in the UTF-8 string \fIsrc\fR. The source string must
+contain at least \fIindex\fR characters. This is equivalent to calling
+\fBTcl_UtfNext\fR \fIindex\fR times. If a negative \fIindex\fR is given,
+the return pointer points to the first character in the source string.
+.PP
+\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 \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.
+.PP
+See the \fBTcl\fR manual entry for information on the valid backslash
+sequences. All of the sequences described in the Tcl manual entry are
+supported by \fBTcl_UtfBackslash\fR.
+
+.SH KEYWORDS
+utf, unicode, backslash
diff --git a/library/msgcat/doc/WrongNumArgs.3 b/library/msgcat/doc/WrongNumArgs.3
new file mode 100644
index 0000000..a2908e9
--- /dev/null
+++ b/library/msgcat/doc/WrongNumArgs.3
@@ -0,0 +1,79 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_WrongNumArgs 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_WrongNumArgs \- generate standard error message for wrong number of arguments
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_WrongNumArgs\fR(\fIinterp, objc, objv, message\fR)
+.SH ARGUMENTS
+.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
+Arguments to command that had the wrong number of arguments.
+.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.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_WrongNumArgs\fR is a utility procedure that is invoked by
+command procedures when they discover that they have received the
+wrong number of arguments. \fBTcl_WrongNumArgs\fR generates a
+standard error message and stores it in the result object of
+\fIinterp\fR. The message includes the \fIobjc\fR initial
+elements of \fIobjv\fR plus \fImessage\fR. For example, if
+\fIobjv\fR consists of the values \fBfoo\fR and \fBbar\fR,
+\fIobjc\fR is 1, and \fImessage\fR is
+.QW "\fBfileName count\fR"
+then \fIinterp\fR's result object will be set to the following
+string:
+.PP
+.CS
+wrong # args: should be "foo fileName count"
+.CE
+.PP
+If \fIobjc\fR is 2, the result will be set to the following string:
+.PP
+.CS
+wrong # args: should be "foo bar fileName count"
+.CE
+.PP
+\fIObjc\fR is usually 1, but may be 2 or more for commands like
+\fBstring\fR and the Tk widget commands, which use the first argument
+as a subcommand.
+.PP
+Some of the objects in the \fIobjv\fR array may be abbreviations for
+a subcommand. The command
+\fBTcl_GetIndexFromObj\fR will convert the abbreviated string object
+into an \fIindexObject\fR. If an error occurs in the parsing of the
+subcommand we would like to use the full subcommand name rather than
+the abbreviation. If the \fBTcl_WrongNumArgs\fR command finds any
+\fIindexObjects\fR in the \fIobjv\fR array it will use the full subcommand
+name in the error message instead of the abbreviated name that was
+originally passed in. Using the above example, let us assume that
+\fIbar\fR is actually an abbreviation for \fIbarfly\fR and the object
+is now an indexObject because it was passed to
+\fBTcl_GetIndexFromObj\fR. In this case the error message would be:
+.PP
+.CS
+wrong # args: should be "foo barfly fileName count"
+.CE
+.SH "SEE ALSO"
+Tcl_GetIndexFromObj(3)
+.SH KEYWORDS
+command, error message, wrong number of arguments
diff --git a/library/msgcat/doc/after.n b/library/msgcat/doc/after.n
new file mode 100644
index 0000000..d6181c6
--- /dev/null
+++ b/library/msgcat/doc/after.n
@@ -0,0 +1,151 @@
+'\"
+'\" Copyright (c) 1990-1994 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 after n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+after \- Execute a command after a time delay
+.SH SYNOPSIS
+\fBafter \fIms\fR
+.sp
+\fBafter \fIms \fR?\fIscript script script ...\fR?
+.sp
+\fBafter cancel \fIid\fR
+.sp
+\fBafter cancel \fIscript script script ...\fR
+.sp
+\fBafter idle \fR?\fIscript script script ...\fR?
+.sp
+\fBafter info \fR?\fIid\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command is used to delay execution of the program or to execute
+a command in background sometime in the future. It has several forms,
+depending on the first argument to the command:
+.TP
+\fBafter \fIms\fR
+.
+\fIMs\fR must be an integer giving a time in milliseconds.
+The command sleeps for \fIms\fR milliseconds and then returns.
+While the command is sleeping the application does not respond to
+events.
+.TP
+\fBafter \fIms \fR?\fIscript script script ...\fR?
+.
+In this form the command returns immediately, but it arranges
+for a Tcl command to be executed \fIms\fR milliseconds later as an
+event handler.
+The command will be executed exactly once, at the given time.
+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 background error will be reported by the command
+registered with \fBinterp bgerror\fR.
+The \fBafter\fR command returns an identifier that can be used
+to cancel the delayed command using \fBafter cancel\fR.
+.TP
+\fBafter cancel \fIid\fR
+.
+Cancels the execution of a delayed command that
+was previously scheduled.
+\fIId\fR indicates which command should be canceled; it must have
+been the return value from a previous \fBafter\fR command.
+If the command given by \fIid\fR has already been executed then
+the \fBafter cancel\fR command has no effect.
+.TP
+\fBafter cancel \fIscript script ...\fR
+.
+This command also cancels the execution of a delayed command.
+The \fIscript\fR arguments are concatenated together with space
+separators (just as in the \fBconcat\fR command).
+If there is a pending command that matches the string, it is
+canceled and will never be executed; if no such command is
+currently pending then the \fBafter cancel\fR command has no effect.
+.TP
+\fBafter idle \fIscript \fR?\fIscript script ...\fR?
+.
+Concatenates the \fIscript\fR arguments together with space
+separators (just as in the \fBconcat\fR command), and arranges
+for the resulting script to be evaluated later as an idle callback.
+The script will be run exactly once, the next time the event
+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
+background error will be reported by the command
+registered with \fBinterp bgerror\fR.
+.TP
+\fBafter info \fR?\fIid\fR?
+.
+This command returns information about existing event handlers.
+If no \fIid\fR argument is supplied, the command returns
+a list of the identifiers for all existing
+event handlers created by the \fBafter\fR command for this
+interpreter.
+If \fIid\fR is supplied, it specifies an existing handler;
+\fIid\fR must have been the return value from some previous call
+to \fBafter\fR and it must not have triggered yet or been canceled.
+In this case the command returns a list with two elements.
+The first element of the list is the script associated
+with \fIid\fR, and the second element is either
+\fBidle\fR or \fBtimer\fR to indicate what kind of event
+handler it is.
+.LP
+The \fBafter \fIms\fR and \fBafter idle\fR forms of the command
+assume that the application is event driven: the delayed commands
+will not be executed unless the application enters the event loop.
+In applications that are not normally event-driven, such as
+\fBtclsh\fR, the event loop can be entered with the \fBvwait\fR
+and \fBupdate\fR commands.
+.SH "EXAMPLES"
+This defines a command to make Tcl do nothing at all for \fIN\fR
+seconds:
+.PP
+.CS
+proc sleep {N} {
+ \fBafter\fR [expr {int($N * 1000)}]
+}
+.CE
+.PP
+This arranges for the command \fIwake_up\fR to be run in eight hours
+(providing the event loop is active at that time):
+.PP
+.CS
+\fBafter\fR [expr {1000 * 60 * 60 * 8}] wake_up
+.CE
+.PP
+The following command can be used to do long-running calculations (as
+represented here by \fI::my_calc::one_step\fR, which is assumed to
+return a boolean indicating whether another step should be performed)
+in a step-by-step fashion, though the calculation itself needs to be
+arranged so it can work step-wise. This technique is extra careful to
+ensure that the event loop is not starved by the rescheduling of
+processing steps (arranging for the next step to be done using an
+already-triggered timer event only when the event queue has been
+drained) and is useful when you want to ensure that a Tk GUI remains
+responsive during a slow task.
+.PP
+.CS
+proc doOneStep {} {
+ if {[::my_calc::one_step]} {
+ \fBafter idle\fR [list \fBafter\fR 0 doOneStep]
+ }
+}
+doOneStep
+.CE
+.SH "SEE ALSO"
+concat(n), interp(n), update(n), vwait(n)
+.SH KEYWORDS
+cancel, delay, idle callback, sleep, time
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/append.n b/library/msgcat/doc/append.n
new file mode 100644
index 0000000..034068d
--- /dev/null
+++ b/library/msgcat/doc/append.n
@@ -0,0 +1,49 @@
+'\"
+'\" 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 append n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+append \- Append to variable
+.SH SYNOPSIS
+\fBappend \fIvarName \fR?\fIvalue value value ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Append all of the \fIvalue\fR arguments to the current value
+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,
+.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.
+.PP
+.CS
+set var 0
+for {set i 1} {$i<=10} {incr i} {
+ \fBappend\fR var "," $i
+}
+puts $var
+# Prints 0,1,2,3,4,5,6,7,8,9,10
+.CE
+.SH "SEE ALSO"
+concat(n), lappend(n)
+.SH KEYWORDS
+append, variable
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/apply.n b/library/msgcat/doc/apply.n
new file mode 100644
index 0000000..9d373e1
--- /dev/null
+++ b/library/msgcat/doc/apply.n
@@ -0,0 +1,102 @@
+'\"
+'\" 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
+.PP
+This shows how to make a simple general command that applies a transformation
+to each element of a list.
+.PP
+.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:
+.PP
+.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
+anonymous function, argument, lambda, procedure,
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/array.n b/library/msgcat/doc/array.n
new file mode 100644
index 0000000..47f9624
--- /dev/null
+++ b/library/msgcat/doc/array.n
@@ -0,0 +1,187 @@
+'\"
+'\" Copyright (c) 1993-1994 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 array n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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
+variable given by \fIarrayName\fR.
+Unless otherwise specified for individual commands below,
+\fIarrayName\fR must be the name of an existing array variable.
+The \fIoption\fR argument determines what action is carried
+out by the command.
+The legal \fIoptions\fR (which may be abbreviated) are:
+.TP
+\fBarray anymore \fIarrayName searchId\fR
+Returns 1 if there are any more elements left to be processed
+in an array search, 0 if all elements have already been
+returned.
+\fISearchId\fR indicates which search on \fIarrayName\fR to
+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 will not indicate whether the search
+has been completed.
+.TP
+\fBarray donesearch \fIarrayName searchId\fR
+This command terminates an array search and destroys all the
+state associated with that search. \fISearchId\fR indicates
+which search on \fIarrayName\fR to destroy, and must have
+been the return value from a previous invocation of
+\fBarray startsearch\fR. Returns an empty string.
+.TP
+\fBarray exists \fIarrayName\fR
+Returns 1 if \fIarrayName\fR is an array variable, 0 if there
+is no variable by that name or if it is a scalar variable.
+.TP
+\fBarray get \fIarrayName\fR ?\fIpattern\fR?
+Returns a list containing pairs of elements. The first
+element in each pair is the name of an element in \fIarrayName\fR
+and the second element of each pair is the value of the
+array element. The order of the pairs is undefined.
+If \fIpattern\fR is not specified, then all of the elements of the
+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 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
+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
+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 is not the name of an array
+variable, then an empty string is returned.
+.TP
+\fBarray nextelement \fIarrayName searchId\fR
+Returns the name of the next element in \fIarrayName\fR, or
+an empty string if all elements of \fIarrayName\fR have
+already been returned in this search. The \fIsearchId\fR
+argument identifies the search, and must have
+been the return value of an \fBarray startsearch\fR command.
+Warning: if elements are added to or deleted from the array,
+then all searches are automatically terminated just as if
+\fBarray donesearch\fR had been invoked; this will cause
+\fBarray nextelement\fR operations to fail for those searches.
+.TP
+\fBarray set \fIarrayName list\fR
+Sets the values of one or more elements in \fIarrayName\fR.
+\fIlist\fR must have a form like that returned by \fBarray get\fR,
+consisting of an even number of elements.
+Each odd-numbered element in \fIlist\fR is treated as an element
+name within \fIarrayName\fR, and the following element in \fIlist\fR
+is used as a new value for that array element.
+If the variable \fIarrayName\fR does not already exist
+and \fIlist\fR is empty,
+\fIarrayName\fR is created with an empty array value.
+.TP
+\fBarray size \fIarrayName\fR
+Returns a decimal string giving the number of elements in the
+array.
+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
+array given by \fIarrayName\fR, such that invocations of the
+\fBarray nextelement\fR command will return the names of the
+individual elements in the array.
+When the search has been completed, the \fBarray donesearch\fR
+command should be invoked.
+The return value is a
+search identifier that must be used in \fBarray nextelement\fR
+and \fBarray donesearch\fR commands; it allows multiple
+searches to be underway simultaneously for the same array.
+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.
+.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.
+.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 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.
+.SH EXAMPLES
+.CS
+\fBarray set\fR colorcount {
+ red 1
+ green 5
+ blue 4
+ white 9
+}
+
+foreach {color count} [\fBarray get\fR colorcount] {
+ puts "Color: $color Count: $count"
+}
+ \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)"
+}
+ \fB\(->\fR Color: blue Count: 4
+ Color: white Count: 9
+ Color: green Count: 5
+ Color: red Count: 1
+
+foreach color [lsort [\fBarray names\fR colorcount]] {
+ puts "Color: $color Count: $colorcount($color)"
+}
+ \fB\(->\fR Color: blue Count: 4
+ Color: green Count: 5
+ Color: red Count: 1
+ Color: white Count: 9
+
+\fBarray statistics\fR colorcount
+ \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
+ number of buckets with 3 entries: 0
+ number of buckets with 4 entries: 0
+ number of buckets with 5 entries: 0
+ number of buckets with 6 entries: 0
+ number of buckets with 7 entries: 0
+ number of buckets with 8 entries: 0
+ number of buckets with 9 entries: 0
+ 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/library/msgcat/doc/bgerror.n b/library/msgcat/doc/bgerror.n
new file mode 100644
index 0000000..ac53eca
--- /dev/null
+++ b/library/msgcat/doc/bgerror.n
@@ -0,0 +1,90 @@
+'\"
+'\" Copyright (c) 1990-1994 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 bgerror n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+bgerror \- Command invoked to process background errors
+.SH SYNOPSIS
+\fBbgerror \fImessage\fR
+.BE
+.SH DESCRIPTION
+.PP
+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.
+.PP
+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 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
+through nested Tcl command evaluations until it reaches the top-level
+code in the application; then the application can report the error
+in whatever way it wishes. When a background error occurs, the
+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 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
+implemented the \fBbgerror\fR command, and that the command will
+report the error in a way that makes sense for the application. Tcl
+will ignore any result returned by the \fBbgerror\fR command as long
+as no error is generated.
+.PP
+If another Tcl error occurs within the \fBbgerror\fR command (for
+example, because no \fBbgerror\fR command has been defined) then Tcl
+reports the error itself by writing a message to stderr.
+.PP
+If several background errors accumulate before \fBbgerror\fR is
+invoked to process them, \fBbgerror\fR will be invoked once for each
+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
+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
+to define a \fBbgerror\fR, or use other code that does and thus will
+have trouble integrating your code.
+.SH "EXAMPLE"
+.PP
+This \fBbgerror\fR procedure appends errors to a file, with a timestamp.
+.PP
+.CS
+proc bgerror {message} {
+ set timestamp [clock format [clock seconds]]
+ set fl [open mylog.txt {WRONLY CREAT APPEND}]
+ puts $fl "$timestamp: bgerror in $::argv '$message'"
+ close $fl
+}
+.CE
+.SH "SEE ALSO"
+after(n), interp(n), tclvars(n)
+.SH KEYWORDS
+background error, reporting
diff --git a/library/msgcat/doc/binary.n b/library/msgcat/doc/binary.n
new file mode 100644
index 0000000..68bf9cc
--- /dev/null
+++ b/library/msgcat/doc/binary.n
@@ -0,0 +1,892 @@
+'\"
+'\" Copyright (c) 1997 by Sun Microsystems, Inc.
+'\" Copyright (c) 2008 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.
+'\"
+.so man.macros
+.TH binary n 8.0 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+binary \- Insert and extract fields from binary strings
+.SH SYNOPSIS
+.VS 8.6
+\fBbinary decode \fIformat\fR ?\fI\-option value ...\fR? \fIdata\fR
+.br
+\fBbinary encode \fIformat\fR ?\fI\-option value ...\fR? \fIdata\fR
+.br
+.VE 8.6
+\fBbinary format \fIformatString \fR?\fIarg arg ...\fR?
+.br
+\fBbinary scan \fIstring formatString \fR?\fIvarName varName ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command provides facilities for manipulating binary data. The
+subcommand \fBbinary format\fR creates a binary string from normal
+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 subcommand
+\fBbinary scan\fR, does the opposite: it extracts data
+from a binary string and returns it as ordinary Tcl string values.
+.VS 8.6
+The \fBbinary encode\fR and \fBbinary decode\fR subcommands convert
+binary data to or from string encodings such as base64 (used in MIME
+messages for example).
+.VE 8.6
+.SH "BINARY ENCODE AND DECODE"
+.VS 8.6
+.PP
+When encoding binary data as a readable string, the starting binary data is
+passed to the \fBbinary encode\fR command, together with the name of the
+encoding to use and any encoding-specific options desired. Data which has been
+encoded can be converted back to binary form using \fBbinary decode\fR. The
+following formats and options are supported.
+.TP
+\fBbase64\fR
+.
+The \fBbase64\fR binary encoding is commonly used in mail messages and XML
+documents, and uses mostly upper and lower case letters and digits. It has the
+distinction of being able to be rewrapped arbitrarily without losing
+information.
+.RS
+.PP
+During encoding, the following options are supported:
+.TP
+\fB\-maxlen \fIlength\fR
+.
+Indicates that the output should be split into lines of no more than
+\fIlength\fR characters. By default, lines are not split.
+.TP
+\fB\-wrapchar \fIcharacter\fR
+.
+Indicates that, when lines are split because of the \fB\-maxlen\fR option,
+\fIcharacter\fR should be used to separate lines. By default, this is a
+newline character,
+.QW \en .
+.PP
+During decoding, the following options are supported:
+.TP
+\fB\-strict\fR
+.
+Instructs the decoder to throw an error if it encounters whitespace characters. Otherwise it ignores them.
+.RE
+.TP
+\fBhex\fR
+.
+The \fBhex\fR binary encoding converts each byte to a pair of hexadecimal
+digits in big-endian form.
+.RS
+.PP
+No options are supported during encoding. During decoding, the following
+options are supported:
+.TP
+\fB\-strict\fR
+.
+Instructs the decoder to throw an error if it encounters whitespace characters. Otherwise it ignores them.
+.RE
+.TP
+\fBuuencode\fR
+.
+The \fBuuencode\fR binary encoding used to be common for transfer of data
+between Unix systems and on USENET, but is less common these days, having been
+largely superseded by the \fBbase64\fR binary encoding.
+.RS
+.PP
+During encoding, the following options are supported:
+'\" This is wrong! The uuencode format had more complexity than this!
+.TP
+\fB\-maxlen \fIlength\fR
+.
+Indicates that the output should be split into lines of no more than
+\fIlength\fR characters. By default, lines are not split.
+.TP
+\fB\-wrapchar \fIcharacter\fR
+.
+Indicates that, when lines are split because of the \fB\-maxlen\fR option,
+\fIcharacter\fR should be used to separate lines. By default, this is a
+newline character,
+.QW \en .
+.PP
+During decoding, the following options are supported:
+.TP
+\fB\-strict\fR
+.
+Instructs the decoder to throw an error if it encounters whitespace characters. Otherwise it ignores them.
+.RE
+.VE 8.6
+.SH "BINARY FORMAT"
+.PP
+The \fBbinary format\fR command generates a binary string whose layout
+is specified by the \fIformatString\fR and whose contents come from
+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 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
+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. The flag character
+is ignored for \fBbinary format\fR.
+.PP
+Here is a small example to clarify the relation between the field
+specifiers and the arguments:
+.CS
+\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
+of 3 for the associated field specifier, only the first three will be
+used. The second argument is associated with the second field
+specifier. The resulting binary string contains the four numbers 1.0,
+2.0, 3.0 and 0.1.
+.PP
+Each type-count pair moves an imaginary cursor through the binary
+data, storing bytes at the current position and advancing the cursor
+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 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 \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
+\fIcount\fR is \fB*\fR, then all of the bytes in \fIarg\fR will be
+formatted. If \fIcount\fR is omitted, then one character will be
+formatted. For example,
+.RS
+.CS
+\fBbinary format\fR a7a*a alpha bravo charlie
+.CE
+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\fR A6A*A alpha bravo charlie
+.CE
+will return \fBalpha bravoc\fR.
+.RE
+.IP \fBb\fR 5
+Stores a string of \fIcount\fR binary digits in low-to-high order
+within each byte in the output string. \fIArg\fR must contain a
+sequence of \fB1\fR and \fB0\fR characters. The resulting bytes are
+emitted in first to last order with the bits being formatted in
+low-to-high order within each byte. If \fIarg\fR has fewer than
+\fIcount\fR digits, then zeros will be used for the remaining bits.
+If \fIarg\fR has more than the specified number of digits, the extra
+digits will be ignored. If \fIcount\fR is \fB*\fR, then all of the
+digits in \fIarg\fR will be formatted. If \fIcount\fR is omitted,
+then one digit will be formatted. If the number of bits formatted
+does not end at a byte boundary, the remaining bits of the last byte
+will be zeros. For example,
+.RS
+.CS
+\fBbinary format\fR b5b* 11100 111000011010
+.CE
+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\fR B5B* 11100 111000011010
+.CE
+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 high-to-low
+within each byte in the output string. \fIArg\fR must contain a
+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
+\fB*\fR, then all of the digits in \fIarg\fR will be formatted. If
+\fIcount\fR is omitted, then one digit will be formatted. If the
+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\fR H3H*H2 ab DEF 987
+.CE
+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
+low-to-high order within each byte. This is seldom required. For example,
+.RS
+.CS
+\fBbinary format\fR h3h*h2 AB def 987
+.CE
+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. 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 greater
+than \fIcount\fR, then the extra elements are ignored. For example,
+.RS
+.CS
+\fBbinary format\fR c3cc* {3 -3 128 1} 260 {2 5}
+.CE
+will return a string equivalent to
+\fB\ex03\exfd\ex80\ex04\ex02\ex05\fR, whereas
+.CS
+\fBbinary format\fR c {2 5}
+.CE
+will generate an error.
+.RE
+.IP \fBs\fR 5
+This form is the same as \fBc\fR except that it stores one or more
+16-bit integers in little-endian byte order in the output string. The
+low-order 16-bits of each integer are stored as a two-byte value at
+the cursor position with the least significant byte stored first. For
+example,
+.RS
+.CS
+\fBbinary format\fR s3 {3 -3 258 1}
+.CE
+will return a string equivalent to
+\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
+16-bit integers in big-endian byte order in the output string. For
+example,
+.RS
+.CS
+\fBbinary format\fR S3 {3 -3 258 1}
+.CE
+will return a string equivalent to
+\fB\ex00\ex03\exff\exfd\ex01\ex02\fR.
+.RE
+.IP \fBt\fR 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.
+.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
+low-order 32-bits of each integer are stored as a four-byte value at
+the cursor position with the least significant byte stored first. For
+example,
+.RS
+.CS
+\fBbinary format\fR i3 {3 -3 65536 1}
+.CE
+will return a string equivalent to
+\fB\ex03\ex00\ex00\ex00\exfd\exff\exff\exff\ex00\ex00\ex01\ex00\fR
+.RE
+.IP \fBI\fR 5
+This form is the same as \fBi\fR except that it stores one or more one
+or more 32-bit integers in big-endian byte order in the output string.
+For example,
+.RS
+.CS
+\fBbinary format\fR I3 {3 -3 65536 1}
+.CE
+will return a string equivalent to
+\fB\ex00\ex00\ex00\ex03\exff\exff\exff\exfd\ex00\ex01\ex00\ex00\fR
+.RE
+.IP \fBn\fR 5
+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.
+.IP \fBw\fR 5
+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
+the cursor position with the least significant byte stored first. For
+example,
+.RS
+.CS
+\fBbinary format\fR w 7810179016327718216
+.CE
+will return the string \fBHelloTcl\fR
+.RE
+.IP \fBW\fR 5
+This form is the same as \fBw\fR except that it stores one or more one
+or more 64-bit integers in big-endian byte order in the output string.
+For example,
+.RS
+.CS
+\fBbinary format\fR Wc 4785469626960341345 110
+.CE
+will return the string \fBBigEndian\fR
+.RE
+.IP \fBm\fR 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.
+.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 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
+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
+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\fR f2 {1.6 3.4}
+.CE
+will return a string equivalent to
+\fB\excd\excc\excc\ex3f\ex9a\ex99\ex59\ex40\fR.
+.RE
+.IP \fBr\fR 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.)
+.IP \fBR\fR 5
+This form is the same as \fBr\fR except that it stores the
+single-precision floating point numbers in big-endian order.
+.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 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\fR d1 {1.6}
+.CE
+will return a string equivalent to
+\fB\ex9a\ex99\ex99\ex99\ex99\ex99\exf9\ex3f\fR.
+.RE
+.IP \fBq\fR 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.)
+.IP \fBQ\fR 5
+This form is the same as \fBq\fR except that it stores the
+double-precision floating point numbers in big-endian order.
+.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,
+generates an error. This type does not consume an argument. For
+example,
+.RS
+.CS
+\fBbinary format\fR a3xa3x2a3 abc def ghi
+.CE
+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
+\fIcount\fR is \fB*\fR or is larger than the current cursor position,
+then the cursor is positioned at location 0 so that the next byte
+stored will be the first byte in the result string. If \fIcount\fR is
+omitted then the cursor is moved back one byte. This type does not
+consume an argument. For example,
+.RS
+.CS
+\fBbinary format\fR a3X*a3X2a3 abc def ghi
+.CE
+will return \fBdghi\fR.
+.RE
+.IP \fB@\fR 5
+Moves the cursor to the absolute location in the output string
+specified by \fIcount\fR. Position 0 refers to the first byte in the
+output string. If \fIcount\fR refers to a position beyond the last
+byte stored so far, then null bytes will be placed in the uninitialized
+locations and the cursor will be placed at the specified location. If
+\fIcount\fR is \fB*\fR, then the cursor is moved to the current end of
+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\fR a5@2a1@*a3@10a1 abcde f ghi j
+.CE
+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 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.
+.PP
+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 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
+the specified type are taken from the data. If present, the
+\fIcount\fR is a non-negative decimal integer or \fB*\fR, which
+normally indicates that all of the remaining items in the data are to
+be used. If there are not enough bytes left after the current cursor
+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. 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\fR $bytes s3s first second
+.CE
+.PP
+This command (provided the binary string in the variable \fIbytes\fR
+is long enough) assigns a list of three integers to the variable
+\fIfirst\fR and assigns a single value to the variable \fIsecond\fR.
+If \fIbytes\fR contains fewer than 8 bytes (i.e. four 2-byte
+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
+puts [\fBbinary scan\fR abcdefg s3s first second]
+puts $first
+puts $second
+.CE
+will print (assuming neither variable is set previously):
+.CS
+1
+25185 25699 26213
+can't read "second": no such variable
+.CE
+.PP
+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
+set signShort [\fBbinary format\fR s1 0x8000]
+\fBbinary scan\fR $signShort s1 val; \fI# val == 0xFFFF8000\fR
+.CE
+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
+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,
+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 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
+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\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 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\fR "abc efghi \e000" A* var1
+.CE
+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
+.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 \fIstring\fR will be scanned. If
+\fIcount\fR is omitted, then one bit will be scanned. For example,
+.RS
+.CS
+\fBbinary scan\fR \ex07\ex87\ex05 b5b* var1 var2
+.CE
+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\fR \ex70\ex87\ex05 B5B* var1 var2
+.CE
+will return \fB2\fR with \fB01110\fR stored in \fIvar1\fR and
+\fB1000011100000101\fR stored in \fIvar2\fR.
+.RE
+.IP \fBH\fR 5
+The data is turned into a string of \fIcount\fR hexadecimal digits in
+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\fR \ex07\exC6\ex05\ex1f\ex34 H3H* var1 var2
+.CE
+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
+reverse (low-to-high) order within each byte. For example,
+.RS
+.CS
+\fBbinary scan\fR \ex07\ex86\ex05\ex12\ex34 h3h* var1 var2
+.CE
+will return \fB2\fR with \fB706\fR stored in \fIvar1\fR and
+\fB502143\fR stored in \fIvar2\fR.
+.PP
+Note that most code that wishes to parse the hexadecimal digits from
+multiple bytes in order should use the \fBH\fR format.
+.RE
+.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 \fIstring\fR will be scanned. If
+\fIcount\fR is omitted, then one 8-bit integer will be scanned. For
+example,
+.RS
+.CS
+\fBbinary scan\fR \ex07\ex86\ex05 c2c* var1 var2
+.CE
+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
+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 \fIstring\fR will be scanned. If
+\fIcount\fR is omitted, then one 16-bit integer will be scanned. For
+example,
+.RS
+.CS
+\fBbinary scan\fR \ex05\ex00\ex07\ex00\exf0\exff s2s* var1 var2
+.CE
+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
+set num [expr { $num & 0xffff }]
+.CE
+.RE
+.IP \fBS\fR 5
+This form is the same as \fBs\fR except that the data is interpreted
+as \fIcount\fR 16-bit signed integers represented in big-endian byte
+order. For example,
+.RS
+.CS
+\fBbinary scan\fR \ex00\ex05\ex00\ex07\exff\exf0 S2S* var1 var2
+.CE
+will return \fB2\fR with \fB5 7\fR stored in \fIvar1\fR and \fB\-16\fR
+stored in \fIvar2\fR.
+.RE
+.IP \fBt\fR 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.
+.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 \fIstring\fR will be scanned. If
+\fIcount\fR is omitted, then one 32-bit integer will be scanned. For
+example,
+.RS
+.CS
+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 \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
+set num [expr { $num & 0xffffffff }]
+.CE
+.RE
+.IP \fBI\fR 5
+This form is the same as \fBI\fR except that the data is interpreted
+as \fIcount\fR 32-bit signed integers represented in big-endian byte
+order. For example,
+.RS
+.CS
+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 \fIvar1\fR and \fB\-16\fR
+stored in \fIvar2\fR.
+.RE
+.IP \fBn\fR 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.
+.IP \fBw\fR 5
+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 \fIstring\fR will be scanned. If
+\fIcount\fR is omitted, then one 64-bit integer will be scanned. For
+example,
+.RS
+.CS
+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 \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
+This form is the same as \fBw\fR except that the data is interpreted
+as \fIcount\fR 64-bit signed integers represented in big-endian byte
+order. For example,
+.RS
+.CS
+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 \fIvar1\fR and \fB\-16\fR
+stored in \fIvar2\fR.
+.RE
+.IP \fBm\fR 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.
+.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
+\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
+valid floating point number, the resulting value is undefined and
+compiler dependent. For example, on a Windows system running on an
+Intel Pentium processor,
+.RS
+.CS
+\fBbinary scan\fR \ex3f\excc\excc\excd f var1
+.CE
+will return \fB1\fR with \fB1.6000000238418579\fR stored in
+\fIvar1\fR.
+.RE
+.IP \fBr\fR 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.
+.IP \fBR\fR 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.
+.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
+machine's native representation. For example, on a Windows system
+running on an Intel Pentium processor,
+.RS
+.CS
+\fBbinary scan\fR \ex9a\ex99\ex99\ex99\ex99\ex99\exf9\ex3f d var1
+.CE
+will return \fB1\fR with \fB1.6000000000000001\fR
+stored in \fIvar1\fR.
+.RE
+.IP \fBq\fR 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.
+.IP \fBQ\fR 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.
+.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 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\fR \ex01\ex02\ex03\ex04 x2H* var1
+.CE
+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
+\fIcount\fR is \fB*\fR or is larger than the current cursor position,
+then the cursor is positioned at location 0 so that the next byte
+scanned will be the first byte in \fIstring\fR. If \fIcount\fR
+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\fR \ex01\ex02\ex03\ex04 c2XH* var1 var2
+.CE
+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
+by \fIcount\fR. Note that position 0 refers to the first byte in
+\fIstring\fR. If \fIcount\fR refers to a position beyond the end of
+\fIstring\fR, then the cursor is positioned after the last byte. If
+\fIcount\fR is omitted, then an error will be generated. For example,
+.RS
+.CS
+\fBbinary scan\fR \ex01\ex02\ex03\ex04 c2@1H* var1 var2
+.CE
+will return \fB2\fR with \fB1 2\fR stored in \fIvar1\fR and \fB020304\fR
+stored in \fIvar2\fR.
+.RE
+.SH "PORTABILITY ISSUES"
+.PP
+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
+.PP
+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 \fIwriteString\fR {channel string} {
+ set data [encoding convertto utf-8 $string]
+ puts -nonewline [\fBbinary format\fR Ia* \e
+ [string length $data] $data]
+}
+.CE
+.PP
+This procedure reads a string from a channel that was written by the
+previously presented \fIwriteString\fR procedure:
+.CS
+proc \fIreadString\fR {channel} {
+ if {![\fBbinary scan\fR [read $channel 4] I length]} {
+ error "missing length"
+ }
+ set data [read $channel $length]
+ return [encoding convertfrom utf-8 $data]
+}
+.CE
+.PP
+This converts the contents of a file (named in the variable \fIfilename\fR) to
+base64 and prints them:
+.CS
+set f [open $filename rb]
+set data [read $f]
+close $f
+puts [\fBbinary encode\fR base64 \-maxlen 64 $data]
+.CE
+.SH "SEE ALSO"
+format(n), scan(n), tclvars(n)
+.SH KEYWORDS
+binary, format, scan
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/break.n b/library/msgcat/doc/break.n
new file mode 100644
index 0000000..cef37c6
--- /dev/null
+++ b/library/msgcat/doc/break.n
@@ -0,0 +1,47 @@
+'\"
+'\" Copyright (c) 1993-1994 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 break n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+break \- Abort looping command
+.SH SYNOPSIS
+\fBbreak\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command is typically invoked inside the body of a looping command
+such as \fBfor\fR or \fBforeach\fR or \fBwhile\fR.
+It returns a 3 (\fBTCL_BREAK\fR) result code, which causes a break exception
+to occur.
+The exception causes the current script to be aborted
+out to the innermost containing loop command, which then
+aborts its execution and returns normally.
+Break exceptions are also handled in a few other situations, such
+as the \fBcatch\fR command, Tk event bindings, and the outermost
+scripts of procedure bodies.
+.SH EXAMPLE
+.PP
+Print a line for each of the integers from 0 to 5:
+.PP
+.CS
+for {set x 0} {$x<10} {incr x} {
+ if {$x > 5} {
+ \fBbreak\fR
+ }
+ puts "x is $x"
+}
+.CE
+.SH "SEE ALSO"
+catch(n), continue(n), for(n), foreach(n), return(n), while(n)
+.SH KEYWORDS
+abort, break, loop
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/case.n b/library/msgcat/doc/case.n
new file mode 100644
index 0000000..0155a61
--- /dev/null
+++ b/library/msgcat/doc/case.n
@@ -0,0 +1,60 @@
+'\"
+'\" 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 case n 7.0 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+case \- Evaluate one of several scripts, depending on a given value
+.SH SYNOPSIS
+\fBcase\fI string \fR?\fBin\fR? \fIpatList body \fR?\fIpatList body \fR...?
+.sp
+\fBcase\fI string \fR?\fBin\fR? {\fIpatList body \fR?\fIpatList body \fR...?}
+.BE
+
+.SH DESCRIPTION
+.PP
+\fINote: the \fBcase\fI command is obsolete and is supported only
+for backward compatibility. At some point in the future it may be
+removed entirely. You should use the \fBswitch\fI command instead.\fR
+.PP
+The \fBcase\fR command matches \fIstring\fR against each of
+the \fIpatList\fR arguments in order.
+Each \fIpatList\fR argument is a list of one or
+more patterns. If any of these patterns matches \fIstring\fR then
+\fBcase\fR evaluates the following \fIbody\fR argument
+by passing it recursively to the Tcl interpreter and returns the result
+of that evaluation.
+Each \fIpatList\fR argument consists of a single
+pattern or list of patterns. Each pattern may contain any of the wild-cards
+described under \fBstring match\fR. If a \fIpatList\fR
+argument is \fBdefault\fR, the corresponding body will be evaluated
+if no \fIpatList\fR matches \fIstring\fR. If no \fIpatList\fR argument
+matches \fIstring\fR and no default is given, then the \fBcase\fR
+command returns an empty string.
+.PP
+Two syntaxes are provided for the \fIpatList\fR and \fIbody\fR arguments.
+The first uses a separate argument for each of the patterns and commands;
+this form is convenient if substitutions are desired on some of the
+patterns or commands.
+The second form places all of the patterns and commands together into
+a single argument; the argument must have proper list structure, with
+the elements of the list being the patterns and commands.
+The second form makes it easy to construct multi-line case commands,
+since the braces around the whole list make it unnecessary to include a
+backslash at the end of each line.
+Since the \fIpatList\fR arguments are in braces in the second form,
+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.
+
+.SH "SEE ALSO"
+switch(n)
+
+.SH KEYWORDS
+case, match, regular expression
diff --git a/library/msgcat/doc/catch.n b/library/msgcat/doc/catch.n
new file mode 100644
index 0000000..a05ca71
--- /dev/null
+++ b/library/msgcat/doc/catch.n
@@ -0,0 +1,124 @@
+'\"
+'\" 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.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?\fIresultVarName\fR? ?\fIoptionsVarName\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fBcatch\fR command may be used to prevent errors from aborting command
+interpretation. The \fBcatch\fR command calls the Tcl interpreter recursively
+to execute \fIscript\fR, and always returns without raising an error,
+regardless of any errors that might occur while executing \fIscript\fR.
+.PP
+If \fIscript\fR raises an error, \fBcatch\fR will return a non-zero integer
+value corresponding to the exceptional return code returned by evaluation
+of \fIscript\fR. Tcl defines the normal return code from script
+evaluation to be zero (0), or \fBTCL_OK\fR. Tcl also defines four exceptional
+return codes: 1 (\fBTCL_ERROR\fR), 2 (\fBTCL_RETURN\fR), 3 (\fBTCL_BREAK\fR),
+and 4 (\fBTCL_CONTINUE\fR). Errors during evaluation of a script are indicated
+by a return code of \fBTCL_ERROR\fR. The other exceptional return codes are
+returned by the \fBreturn\fR, \fBbreak\fR, and \fBcontinue\fR commands
+and in other special situations as documented. Tcl packages can define
+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 \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 \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 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
+When the return code from evaluation of \fIscript\fR is
+\fBTCL_ERROR\fR, four additional entries are defined in the dictionary
+of return options stored in \fIoptionsVarName\fR: \fB\-errorinfo\fR,
+\fB\-errorcode\fR, \fB\-errorline\fR, and
+.VS 8.6
+\fB\-errorstack\fR.
+.VE 8.6
+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.
+.VS 8.6
+The value of the \fB\-errorstack\fR entry is an
+even-sized list made of token-parameter pairs accumulated while
+unwinding the stack. The token may be
+.QW \fBCALL\fR ,
+in which case the parameter is a list made of the proc name and arguments at
+the corresponding level; or it may be
+.QW \fBUP\fR ,
+in which case the parameter is
+the relative level (as in \fBuplevel\fR) of the previous \fBCALL\fR. The
+salient differences with respect to \fB\-errorinfo\fR are that:
+.IP [1]
+it is a machine-readable form that is amenable to processing with
+[\fBforeach\fR {tok prm} ...],
+.IP [2]
+it contains the true (substituted) values passed to the functions, instead of
+the static text of the calling sites, and
+.IP [3]
+it is coarser-grained, with only one element per stack frame (like procs; no
+separate elements for \fBforeach\fR constructs for example).
+.VE 8.6
+.PP
+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.
+.VS 8.6
+The value of the \fB\-errorstack\fR entry surfaces as \fBinfo errorstack\fR.
+.VE 8.6
+.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.
+.SH EXAMPLES
+.PP
+The \fBcatch\fR command may be used in an \fBif\fR to branch based on
+the success of a script.
+.PP
+.CS
+if { [\fBcatch\fR {open $someFile w} fid] } {
+ puts stderr "Could not open $someFile for writing\en$fid"
+ exit 1
+}
+.CE
+.PP
+There are more complex examples of \fBcatch\fR usage in the
+documentation for the \fBreturn\fR command.
+.SH "SEE ALSO"
+break(n), continue(n), dict(n), error(n), info(n), return(n), tclvars(n)
+.SH KEYWORDS
+catch, error, exception
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/library/msgcat/doc/cd.n b/library/msgcat/doc/cd.n
new file mode 100644
index 0000000..eb3854c
--- /dev/null
+++ b/library/msgcat/doc/cd.n
@@ -0,0 +1,43 @@
+'\"
+'\" 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 cd n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+cd \- Change working directory
+.SH SYNOPSIS
+\fBcd \fR?\fIdirName\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Change the current working directory to \fIdirName\fR, or to the
+home directory (as specified in the HOME environment variable) if
+\fIdirName\fR is not given.
+Returns an empty string.
+Note that the current working directory is a per-process resource; the
+\fBcd\fR command changes the working directory for all interpreters
+and (in a threaded environment) all threads.
+.SH EXAMPLES
+.PP
+Change to the home directory of the user \fBfred\fR:
+.PP
+.CS
+\fBcd\fR ~fred
+.CE
+.PP
+Change to the directory \fBlib\fR that is a sibling directory of the
+current one:
+.PP
+.CS
+\fBcd\fR ../lib
+.CE
+.SH "SEE ALSO"
+filename(n), glob(n), pwd(n)
+.SH KEYWORDS
+working directory
diff --git a/library/msgcat/doc/chan.n b/library/msgcat/doc/chan.n
new file mode 100644
index 0000000..c518455
--- /dev/null
+++ b/library/msgcat/doc/chan.n
@@ -0,0 +1,836 @@
+'\"
+'\" 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 ?\fIdirection\fR?
+.
+Close and destroy the channel called \fIchannelId\fR. Note that this
+deletes all existing file-events registered on the channel.
+.VS 8.6
+If the \fIdirection\fR argument (which must be \fBread\fR or \fBwrite\fR or
+any unique abbreviation of them) is present, the channel will only be
+half-closed, so that it can go from being read-write to write-only or
+read-only respectively. If a read-only channel is closed for reading, it is
+the same as if the channel is fully closed, and respectively similar for
+write-only channels. Without the \fIdirection\fR argument, the channel is
+closed for both reading and writing (but only if those directions are
+currently open). It is an error to close a read-only channel for writing, or a
+write-only channel for reading.
+.VE 8.6
+.RS
+.PP
+As part of closing the channel, all buffered output is flushed to the
+channel's output device (only if the channel is ceasing to be writable), any
+buffered input is discarded (only if the channel is ceasing to be readable),
+the underlying operating system resource is closed and \fIchannelId\fR becomes
+unavailable for future use (both only if the channel is being completely
+closed).
+.PP
+If the channel is blocking and the channel is ceasing to be writable, the
+command does not return until all output is flushed. If the channel is
+non-blocking and there is unflushed output, the channel remains open and the
+command returns immediately; output will be flushed in the background and the
+channel will be closed when all the flushing is complete.
+.PP
+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. With half-closing, the half-close of the channel only
+applies to the current interpreter's view of the channel until all channels
+have closed it in that direction (or completely).
+See the \fBinterp\fR command for a description of channel sharing.
+.PP
+Channels are automatically fully 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.)
+.PP
+.VS 8.6
+Note that half-closes of sockets and command pipelines can have important side
+effects because they result in a shutdown() or close() of the underlying
+system resource, which can change how other processes or systems respond to
+the Tcl program.
+.VE 8.6
+.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 channel
+for the options supported by that specific type of channel. For
+example, see the manual entry for the \fBsocket\fR command for additional
+options for sockets, and the \fBopen\fR command for additional options for
+serial devices.
+.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 non-blocking mode it will
+affect the operation of the \fBchan gets\fR, \fBchan read\fR, \fBchan
+puts\fR, \fBchan flush\fR, and \fBchan close\fR commands; see the
+documentation for those commands for details. For non-blocking mode to
+work correctly, the application must be using the Tcl event loop
+(e.g. by calling \fBTcl_DoOneEvent\fR or invoking the \fBvwait\fR
+command).
+.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
+\fBrefchan\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
+\fBrefchan\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 transferred
+to. While this pulls the rug out under the other thread(s) and/or
+interpreter(s), this cannot be avoided. Trying to use such a channel
+will cause the generation of a regular error about unknown channel
+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 non-blocking mode using events. A channel is also considered to be
+readable if an end of file or error condition is present on the
+underlying file or device. It is important for \fIscript\fR to check
+for these conditions and handle them appropriately; for example, if
+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
+non-blocking mode with the \fBchan configure\fR command. In blocking
+mode, a \fBchan puts\fR command may block if you give it more data
+than the underlying file or device can accept, and a \fBchan gets\fR
+or \fBchan read\fR command will block if you attempt to read more data
+than is ready; no events will be processed while the commands block.
+In non-blocking mode \fBchan puts\fR, \fBchan read\fR, and \fBchan
+gets\fR never block.
+.PP
+The script for a file event is executed at global level (outside the
+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 non-blocking mode, the command may return before all
+buffered output has been flushed; the remainder will be flushed in the
+background as fast as the underlying file or device is able to absorb
+it.
+.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-non-blocking 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 pipe\fR
+.VS 8.6
+Creates a standalone pipe whose read- and write-side channels are
+returned as a 2-element list, the first element being the read side and
+the second the write side. Can be useful e.g. to redirect
+separately \fBstderr\fR and \fBstdout\fR from a subprocess. To do
+this, spawn with "2>@" or
+">@" redirection operators onto the write side of a pipe, and then
+immediately close it in the parent. This is necessary to get an EOF on
+the read side once the child has exited or otherwise closed its output.
+.VE 8.6
+.TP
+\fBchan pop \fIchannelId\fR
+.VS 8.6
+Removes the topmost transformation from the channel \fIchannelId\fR, if there
+is any. If there are no transformations added to \fIchannelId\fR, this is
+equivalent to \fBchan close\fR of that channel. The result is normally the
+empty string, but can be an error in some situations (i.e. where the
+underlying system stream is closed and that results in an error).
+.VE 8.6
+.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 \fBrefchan\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 push \fIchannelId cmdPrefix\fR
+.VS 8.6
+Adds a new transformation on top of the channel \fIchannelId\fR. The
+\fIcmdPrefix\fR argument describes a list of one or more words which represent
+a handler that will be used to implement the transformation. The command
+prefix must provide the API described in the \fBtranschan\fR manual page.
+The result of this subcommand is a handle to the transformation. Note that it
+is important to make sure that the transformation is capable of supporting the
+channel mode that it is used with or this can make the channel neither
+readable nor writable.
+.VE 8.6
+.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 non-blocking
+mode then the \fBchan puts\fR command will not block even if the
+operating system cannot accept the data. Instead, Tcl continues to
+buffer the data and writes it in the background as fast as the
+underlying file or device can accept it. The application must use the
+Tcl event loop for non-blocking output to work; otherwise Tcl never
+finds out that the file or device is ready for more output data. It
+is possible for an arbitrarily large amount of data to be buffered for
+a channel in non-blocking mode, which could consume a large amount of
+memory. To avoid wasting memory, non-blocking I/O should normally be
+used in an event-driven fashion with the \fBchan event\fR command
+(do not invoke \fBchan puts\fR unless you have recently been notified
+via a file event that the channel is ready for more output data).
+.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 non-blocking mode, \fBchan read\fR may not
+read as many characters as requested: once all available input has
+been read, the command will return the data that is available rather
+than blocking for more input. If the channel is configured to use a
+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 non-blocking, like this:
+.PP
+.CS
+\fBchan configure \fIchannelId \fB\-blocking \fI0\fR.
+.CE
+.PP
+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 non-blocking mode. It also
+discards any buffered and unread input. This command returns an empty
+string. An error occurs if this command is applied to channels whose
+underlying file or device does not support seeking.
+.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 EXAMPLES
+.PP
+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
+.PP
+A network server that does echoing of its input line-by-line without
+preventing servicing of other connections at the same time.
+.PP
+.CS
+# This is a very simple logger...
+proc log {message} {
+ \fBchan puts\fR stdout $message
+}
+
+# This is called whenever a new client connects to the server
+proc connect {chan host port} {
+ set clientName [format <%s:%d> $host $port]
+ log "connection from $clientName"
+ \fBchan configure\fR $chan -blocking 0 -buffering line
+ \fBchan event\fR $chan readable [list echoLine $chan $clientName]
+}
+
+# This is called whenever either at least one byte of input
+# data is available, or the channel was closed by the client.
+proc echoLine {chan clientName} {
+ \fBchan gets\fR $chan line
+ if {[\fBchan eof\fR $chan]} {
+ log "finishing connection from $clientName"
+ \fBchan close\fR $chan
+ } elseif {![\fBchan blocked\fR $chan]} {
+ # Didn't block waiting for end-of-line
+ log "$clientName - $line"
+ \fBchan puts\fR $chan $line
+ }
+}
+
+# Create the server socket and enter the event-loop to wait
+# for incoming connections...
+socket -server connect 12345
+vwait forever
+.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), transchan(n)
+.SH KEYWORDS
+channel, input, output, events, offset
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/class.n b/library/msgcat/doc/class.n
new file mode 100644
index 0000000..88d1b44
--- /dev/null
+++ b/library/msgcat/doc/class.n
@@ -0,0 +1,136 @@
+'\"
+'\" Copyright (c) 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 class n 0.1 TclOO "TclOO Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+oo::class \- class of all classes
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBoo::class\fI method \fR?\fIarg ...\fR?
+.fi
+.SH "CLASS HIERARCHY"
+.nf
+\fBoo::object\fR
+ \(-> \fBoo::class\fR
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+Classes are objects that can manufacture other objects according to a pattern
+stored in the factory object (the class). An instance of the class is created
+by calling one of the class's factory methods, typically either \fBcreate\fR
+if an explicit name is being given, or \fBnew\fR if an arbitrary unique name
+is to be automatically selected.
+.PP
+The \fBoo::class\fR class is the class of all classes; every class is an
+instance of this class, which is consequently an instance of itself. This
+class is a subclass of \fBoo::object\fR, so every class is also an object.
+Additional metaclasses (i.e., classes of classes) can be defined if necessary
+by subclassing \fBoo::class\fR. Note that the \fBoo::class\fR object hides the
+\fBnew\fR method on itself, so new classes should always be made using the
+\fBcreate\fR method.
+.SS CONSTRUCTOR
+.PP
+The constructor of the \fBoo::class\fR class takes an optional argument which,
+if present, is sent to the \fBoo::define\fR command (along with the name of
+the newly-created class) to allow the class to be conveniently configured at
+creation time.
+.SS DESTRUCTOR
+The \fBoo::class\fR class does not define an explicit destructor. However,
+when a class is destroyed, all its subclasses and instances are also
+destroyed, along with all objects that it has been mixed into.
+.SS "EXPORTED METHODS"
+.TP
+\fIcls \fBcreate \fIname \fR?\fIarg ...\fR?
+.
+This creates a new instance of the class \fIcls\fR called \fIname\fR (which is
+resolved within the calling context's namespace if not fully qualified),
+passing the arguments, \fIarg ...\fR, to the constructor, and (if that returns
+a successful result) returning the fully qualified name of the created object
+(the result of the constructor is ignored). If the constructor fails (i.e.
+returns a non-OK result) then the object is destroyed and the error message is
+the result of this method call.
+.TP
+\fIcls \fBnew \fR?\fIarg ...\fR?
+.
+This creates a new instance of the class \fIcls\fR with a new unique name,
+passing the arguments, \fIarg ...\fR, to the constructor, and (if that returns
+a successful result) returning the fully qualified name of the created object
+(the result of the constructor is ignored). If the constructor fails (i.e.,
+returns a non-OK result) then the object is destroyed and the error message is
+the result of this method call.
+.RS
+.PP
+Note that this method is not exported by the \fBoo::class\fR object itself, so
+classes should not be created using this method.
+.RE
+.SS "NON-EXPORTED METHODS"
+.PP
+The \fBoo::class\fR class supports the following non-exported methods:
+.TP
+\fIcls \fBcreateWithNamespace\fI name nsName\fR ?\fIarg ...\fR?
+.
+This creates a new instance of the class \fIcls\fR called \fIname\fR (which is
+resolved within the calling context's namespace if not fully qualified),
+passing the arguments, \fIarg ...\fR, to the constructor, and (if that returns
+a successful result) returning the fully qualified name of the created object
+(the result of the constructor is ignored). The name of the instance's
+internal namespace will be \fInsName\fR unless that namespace already exists
+(when an arbitrary name will be chosen instead). If the constructor fails
+(i.e., returns a non-OK result) then the object is destroyed and the error
+message is the result of this method call.
+.SH EXAMPLES
+.PP
+This example defines a simple class hierarchy and creates a new instance of
+it. It then invokes a method of the object before destroying the hierarchy and
+showing that the destruction is transitive.
+.PP
+.CS
+\fBoo::class create\fR fruit {
+ method eat {} {
+ puts "yummy!"
+ }
+}
+\fBoo::class create\fR banana {
+ superclass fruit
+ constructor {} {
+ my variable peeled
+ set peeled 0
+ }
+ method peel {} {
+ my variable peeled
+ set peeled 1
+ puts "skin now off"
+ }
+ method edible? {} {
+ my variable peeled
+ return $peeled
+ }
+ method eat {} {
+ if {![my edible?]} {
+ my peel
+ }
+ next
+ }
+}
+set b [banana \fBnew\fR]
+$b eat \fI\(-> prints "skin now off" and "yummy!"\fR
+fruit destroy
+$b eat \fI\(-> error "unknown command"\fR
+.CE
+.SH "SEE ALSO"
+oo::define(n), oo::object(n)
+.SH KEYWORDS
+class, metaclass, object
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/library/msgcat/doc/clock.n b/library/msgcat/doc/clock.n
new file mode 100644
index 0000000..8708029
--- /dev/null
+++ b/library/msgcat/doc/clock.n
@@ -0,0 +1,937 @@
+'\"
+'\" Generated from file './doc/clock.dt' by tcllib/doctools with format 'nroff'
+'\" Copyright (c) 2004 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\"
+.so man.macros
+.TH "clock" n 8.5 Tcl "Tcl Built-In Commands"
+.BS
+.SH NAME
+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
+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
+.PP
+If the \fI\-option\fR argument is \fB\-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 \fB\-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
+.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
+.PP
+.CS
+%a %b %d %H:%M:%S %z %Y
+.CE
+.PP
+On \fBclock scan\fR, the lack of a \fB\-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
+.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
+.PP
+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"
+.PP
+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.
+.PP
+.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.
+.PP
+.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.
+.PP
+.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.
+.PP
+.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"
+.PP
+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"
+.PP
+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"
+.PP
+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"
+.PP
+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
+\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"
+.PP
+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:
+.PP
+.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
+.PP
+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
+If the Posix time zone string contains a DST (Daylight Savings Time)
+part, but doesn't contain a rule stating when DST starts or ends,
+then default rules are used. For Timezones with an offset between 0
+and +12, the current European/Russian rules are used, otherwise the
+current US rules are used. In Europe (offset +0 to +2) the switch
+to summertime is done each last Sunday in March at 1:00 GMT, and
+the switch back is each last Sunday in October at 2:00 GMT. In
+Russia (offset +3 to +12), the switch dates are the same, only
+the switch to summertime is at 2:00 local time, and the switch
+back is at 3:00 local time in all time zones. The US switch to
+summertime takes place each second Sunday in March at 2:00 local
+time, and the switch back is each first Sunday in November at
+3:00 local time. These default rules mean that in all European,
+Russian and US (or compatible) time zones, DST calculations will
+be correct for dates in 2007 and later, unless in the future the
+rules change again.
+.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"
+.PP
+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"
+.PP
+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.
+.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.
+.PP
+The \fIinputString\fR argument consists of zero or more specifications of the
+following form:
+.TP
+\fItime\fR
+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
+.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
+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.
+.TP
+\fIISO 8601 point-in-time\fR
+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
+giving an explicit \fB\-format\fR option to the \fBclock scan\fR command.
+.TP
+\fIrelative time\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.
+.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
+specified, and no absolute or relative time is given, midnight is
+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.
+.SH "SEE ALSO"
+msgcat(n)
+.SH KEYWORDS
+clock, date, time
+.SH "COPYRIGHT"
+Copyright (c) 2004 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/close.n b/library/msgcat/doc/close.n
new file mode 100644
index 0000000..2826d82
--- /dev/null
+++ b/library/msgcat/doc/close.n
@@ -0,0 +1,108 @@
+'\"
+'\" 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 close n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+close \- Close an open channel
+.SH SYNOPSIS
+\fBclose \fIchannelId\fR ?r(ead)|w(rite)?
+.BE
+.SH DESCRIPTION
+.PP
+Closes or half-closes the channel given by \fIchannelId\fR.
+.PP
+\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.
+.PP
+The single-argument form is a simple
+.QW "full-close" :
+all buffered output is flushed to the channel's output device,
+any buffered input is discarded, the underlying file or device is closed,
+and \fIchannelId\fR becomes unavailable for use.
+.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
+\fBclose\fR waits for the child processes to complete.
+.PP
+If the channel is shared between interpreters, then \fBclose\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
+\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.
+.VS 8.6
+From 8.6 on (TIP#398), nonblocking channels are no longer switched to blocking mode when exiting; this guarantees a timely exit even when the peer or a communication channel is stalled. To ensure proper flushing of stalled nonblocking channels on exit, one must now either (a) actively switch them back to blocking or (b) use the environment variable TCL_FLUSH_NONBLOCKING_ON_EXIT, which when set and not equal to "0" restores the previous behavior.
+.VE 8.6
+.PP
+The command returns an empty string, and may generate an error if
+an error occurs while flushing output. If a command in a command
+pipeline created with \fBopen\fR returns an error, \fBclose\fR
+generates an error (similar to the \fBexec\fR command.)
+.PP
+.VS 8.6
+The two-argument form is a
+.QW "half-close" :
+given a bidirectional channel like a
+socket or command pipeline and a (possibly abbreviated) direction, it closes
+only the sub-stream going in that direction. This means a shutdown() on a
+socket, and a close() of one end of a pipe for a command pipeline. Then, the
+Tcl-level channel data structure is either kept or freed depending on whether
+the other direction is still open.
+.PP
+A single-argument close on an already half-closed bidirectional channel is
+defined to just
+.QW "finish the job" .
+A half-close on an already closed half, or on a wrong-sided unidirectional
+channel, raises an error.
+.PP
+In the case of a command pipeline, the child-reaping duty falls upon the
+shoulders of the last close or half-close, which is thus allowed to report an
+abnormal exit error.
+.PP
+Currently only sockets and command pipelines support half-close. A future
+extension will allow reflected and stacked channels to do so.
+.VE 8.6
+.SH EXAMPLE
+.PP
+This illustrates how you can use Tcl to ensure that files get closed
+even when errors happen by combining \fBcatch\fR, \fBclose\fR and
+\fBreturn\fR:
+.PP
+.CS
+proc withOpenFile {filename channelVar script} {
+ upvar 1 $channelVar chan
+ set chan [open $filename]
+ catch {
+ uplevel 1 $script
+ } result options
+ \fBclose\fR $chan
+ return -options $options $result
+}
+.CE
+.SH "SEE ALSO"
+file(n), open(n), socket(n), eof(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+blocking, channel, close, nonblocking, half-close
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/library/msgcat/doc/concat.n b/library/msgcat/doc/concat.n
new file mode 100644
index 0000000..b079b30
--- /dev/null
+++ b/library/msgcat/doc/concat.n
@@ -0,0 +1,58 @@
+'\"
+'\" 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 concat n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+concat \- Join lists together
+.SH SYNOPSIS
+\fBconcat\fI \fR?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command joins each of its arguments together with spaces after
+trimming leading and trailing white-space from each of them. If all of the
+arguments are lists, this has the same effect as concatenating them
+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, flattening them in the process
+(so giving the following interactive session):
+.PP
+.CS
+\fI%\fR \fBconcat\fR a b {c d e} {f {g h}}
+\fIa b c d e f {g h}\fR
+.CE
+.PP
+it will also concatenate things that are not lists, as can be seen from this
+session:
+.PP
+.CS
+\fI%\fR \fBconcat\fR " a b {c " d " e} f"
+\fIa b {c d e} f\fR
+.CE
+.PP
+Note also that the concatenation does not remove spaces from the middle of
+values, as can be seen here:
+.PP
+.CS
+\fI%\fR \fBconcat\fR "a b c" { d e f }
+\fIa b c d e f\fR
+.CE
+.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), join(n)
+.SH KEYWORDS
+concatenate, join, list
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/continue.n b/library/msgcat/doc/continue.n
new file mode 100644
index 0000000..de2f07c
--- /dev/null
+++ b/library/msgcat/doc/continue.n
@@ -0,0 +1,47 @@
+'\"
+'\" Copyright (c) 1993-1994 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 continue n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+continue \- Skip to the next iteration of a loop
+.SH SYNOPSIS
+\fBcontinue\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command is typically invoked inside the body of a looping command
+such as \fBfor\fR or \fBforeach\fR or \fBwhile\fR.
+It returns a 4 (\fBTCL_CONTINUE\fR) result code, which causes a continue
+exception to occur.
+The exception causes the current script to be aborted
+out to the innermost containing loop command, which then
+continues with the next iteration of the loop.
+Catch exceptions are also handled in a few other situations, such
+as the \fBcatch\fR command and the outermost scripts of procedure
+bodies.
+.SH EXAMPLE
+.PP
+Print a line for each of the integers from 0 to 10 \fIexcept\fR 5:
+.PP
+.CS
+for {set x 0} {$x<10} {incr x} {
+ if {$x == 5} {
+ \fBcontinue\fR
+ }
+ puts "x is $x"
+}
+.CE
+.SH "SEE ALSO"
+break(n), for(n), foreach(n), return(n), while(n)
+.SH KEYWORDS
+continue, iteration, loop
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/copy.n b/library/msgcat/doc/copy.n
new file mode 100644
index 0000000..f5002f8
--- /dev/null
+++ b/library/msgcat/doc/copy.n
@@ -0,0 +1,66 @@
+'\"
+'\" Copyright (c) 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 copy n 0.1 TclOO "TclOO Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+oo::copy \- create copies of objects and classes
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBoo::copy\fI sourceObject \fR?\fItargetObject\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBoo::copy\fR command creates a copy of an object or class. It takes the
+name of the object or class to be copied, \fIsourceObject\fR, and optionally
+the name of the object or class to create, \fItargetObject\fR, which will be
+resolved relative to the current namespace if not an absolute qualified name.
+If \fItargetObject\fR is omitted, a new name is chosen. The copied object will
+be of the same class as the source object, and will have all its per-object
+methods copied. If it is a class, it will also have all the class methods in
+the class copied, but it will not have any of its instances copied.
+.PP
+.VS
+After the \fItargetObject\fR has been created and all definitions of its
+configuration (e.g., methods, filters, mixins) copied, the \fB<cloned>\fR
+method of \fItargetObject\fR will be invoked, to allow for customization of
+the created object such as installing related variable traces. The only
+argument given will be \fIsourceObject\fR. The default implementation of this
+method (in \fBoo::object\fR) just copies the procedures and variables in the
+namespace of \fIsourceObject\fR to the namespace of \fItargetObject\fR. If
+this method call does not return a result that is successful (i.e., an error
+or other kind of exception) then the \fItargetObject\fR will be deleted and an
+error returned.
+.VE
+.PP
+The result of the \fBoo::copy\fR command will be the fully-qualified name of
+the new object or class.
+.SH EXAMPLES
+.PP
+This example creates an object, copies it, modifies the source object, and
+then demonstrates that the copied object is indeed a copy.
+.PP
+.CS
+oo::object create src
+oo::objdefine src method msg {} {puts foo}
+\fBoo::copy\fR src dst
+oo::objdefine src method msg {} {puts bar}
+src msg \fI\(-> prints "bar"\fR
+dst msg \fI\(-> prints "foo"\fR
+.CE
+.SH "SEE ALSO"
+oo::class(n), oo::define(n), oo::object(n)
+.SH KEYWORDS
+clone, copy, duplication, object
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/library/msgcat/doc/coroutine.n b/library/msgcat/doc/coroutine.n
new file mode 100644
index 0000000..035d58a
--- /dev/null
+++ b/library/msgcat/doc/coroutine.n
@@ -0,0 +1,205 @@
+'\"
+'\" Copyright (c) 2009 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 coroutine n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+coroutine, yield, yieldto \- Create and produce values from coroutines
+.SH SYNOPSIS
+.nf
+\fBcoroutine \fIname command\fR ?\fIarg...\fR?
+\fByield\fR ?\fIvalue\fR?
+.VS TIP396
+\fByieldto\fR \fIcommand\fR ?\fIarg...\fR?
+\fIname\fR ?\fIvalue...\fR?
+.VE TIP396
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBcoroutine\fR command creates a new coroutine context (with associated
+command) named \fIname\fR and executes that context by calling \fIcommand\fR,
+passing in the other remaining arguments without further interpretation. Once
+\fIcommand\fR returns normally or with an exception (e.g., an error) the
+coroutine context \fIname\fR is deleted.
+.PP
+Within the context, values may be generated as results by using the
+\fByield\fR command; if no \fIvalue\fR is supplied, the empty string is used.
+When that is called, the context will suspend execution and the
+\fBcoroutine\fR command will return the argument to \fByield\fR. The execution
+of the context can then be resumed by calling the context command, optionally
+passing in the \fIsingle\fR value to use as the result of the \fByield\fR call
+that caused
+the context to be suspended. If the coroutine context never yields and instead
+returns conventionally, the result of the \fBcoroutine\fR command will be the
+result of the evaluation of the context.
+.PP
+.VS TIP396
+The coroutine may also suspend its execution by use of the \fByieldto\fR
+command, which instead of returning, cedes execution to some command called
+\fIcommand\fR (resolved in the context of the coroutine) and to which \fIany
+number\fR of arguments may be passed. Since every coroutine has a context
+command, \fByieldto\fR can be used to transfer control directly from one
+coroutine to another (this is only advisable if the two coroutines are
+expecting this to happen) but \fIany\fR command may be the target. If a
+coroutine is suspended by this mechanism, the coroutine processing can be
+resumed by calling the context command optionally passing in an arbitrary
+number of arguments. The return value of the \fByieldto\fR call will be the
+list of arguments passed to the context command; it is up to the caller to
+decide what to do with those values.
+.PP
+The recommended way of writing a version of \fByield\fR that allows resumption
+with multiple arguments is by using \fByieldto\fR and the \fBreturn\fR
+command, like this:
+.PP
+.CS
+proc yieldm {value} {
+ \fByieldto\fR return -level 0 $value
+}
+.CE
+.VE TIP396
+.PP
+The coroutine can also be deleted by destroying the command \fIname\fR, and
+the name of the current coroutine can be retrieved by using
+\fBinfo coroutine\fR.
+If there are deletion traces on variables in the coroutine's
+implementation, they will fire at the point when the coroutine is explicitly
+deleted (or, naturally, if the command returns conventionally).
+.PP
+At the point when \fIcommand\fR is called, the current namespace will be the
+global namespace and there will be no stack frames above it (in the sense of
+\fBupvar\fR and \fBuplevel\fR). However, which command to call will be
+determined in the namespace that the \fBcoroutine\fR command was called from.
+.SH EXAMPLES
+.PP
+This example shows a coroutine that will produce an infinite sequence of
+even values, and a loop that consumes the first ten of them.
+.PP
+.CS
+proc allNumbers {} {
+ \fByield\fR
+ set i 0
+ while 1 {
+ \fByield\fR $i
+ incr i 2
+ }
+}
+\fBcoroutine\fR nextNumber allNumbers
+for {set i 0} {$i < 10} {incr i} {
+ puts "received [\fInextNumber\fR]"
+}
+rename nextNumber {}
+.CE
+.PP
+In this example, the coroutine acts to add up the arguments passed to it.
+.PP
+.CS
+\fBcoroutine\fR accumulator apply {{} {
+ set x 0
+ while 1 {
+ incr x [\fByield\fR $x]
+ }
+}}
+for {set i 0} {$i < 10} {incr i} {
+ puts "$i -> [\fIaccumulator\fR $i]"
+}
+.CE
+.PP
+This example demonstrates the use of coroutines to implement the classic Sieve
+of Eratosthenes algorithm for finding prime numbers. Note the creation of
+coroutines inside a coroutine.
+.PP
+.CS
+proc filterByFactor {source n} {
+ \fByield\fR [info coroutine]
+ while 1 {
+ set x [\fI$source\fR]
+ if {$x % $n} {
+ \fByield\fR $x
+ }
+ }
+}
+\fBcoroutine\fR allNumbers apply {{} {while 1 {\fByield\fR [incr x]}}}
+\fBcoroutine\fR eratosthenes apply {c {
+ \fByield\fR
+ while 1 {
+ set n [\fI$c\fR]
+ \fByield\fR $n
+ set c [\fBcoroutine\fR prime$n filterByFactor $c $n]
+ }
+}} allNumbers
+for {set i 1} {$i <= 20} {incr i} {
+ puts "prime#$i = [\fIeratosthenes\fR]"
+}
+.CE
+.PP
+.VS TIP396
+This example shows how a value can be passed around a group of three
+coroutines that yield to each other:
+.PP
+.CS
+proc juggler {name target {value ""}} {
+ if {$value eq ""} {
+ set value [\fByield\fR [info coroutine]]
+ }
+ while {$value ne ""} {
+ puts "$name : $value"
+ set value [string range $value 0 end-1]
+ lassign [\fByieldto\fR $target $value] value
+ }
+}
+\fBcoroutine\fR j1 juggler Larry [
+ \fBcoroutine\fR j2 juggler Curly [
+ \fBcoroutine\fR j3 juggler Moe j1]] "Nyuck!Nyuck!Nyuck!"
+.CE
+.VE TIP396
+.SS "DETAILED SEMANTICS"
+.PP
+This example demonstrates that coroutines start from the global namespace, and
+that \fIcommand\fR resolution happens before the coroutine stack is created.
+.PP
+.CS
+proc report {where level} {
+ # Where was the caller called from?
+ set ns [uplevel 2 {namespace current}]
+ \fByield\fR "made $where $level context=$ns name=[info coroutine]"
+}
+proc example {} {
+ report outer [info level]
+}
+namespace eval demo {
+ proc example {} {
+ report inner [info level]
+ }
+ proc makeExample {} {
+ puts "making from [info level]"
+ puts [\fBcoroutine\fR coroEg example]
+ }
+ makeExample
+}
+.CE
+.PP
+Which produces the output below. In particular, we can see that stack
+manipulation has occurred (comparing the levels from the first and second
+line) and that the parent level in the coroutine is the global namespace. We
+can also see that coroutine names are local to the current namespace if not
+qualified, and that coroutines may yield at depth (e.g., in called
+procedures).
+.PP
+.CS
+making from 2
+made inner 1 context=:: name=::demo::coroEg
+.CE
+.SH "SEE ALSO"
+apply(n), info(n), proc(n), return(n)
+.SH KEYWORDS
+coroutine, generator
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/library/msgcat/doc/dde.n b/library/msgcat/doc/dde.n
new file mode 100644
index 0000000..e4b51b7
--- /dev/null
+++ b/library/msgcat/doc/dde.n
@@ -0,0 +1,184 @@
+'\"
+'\" Copyright (c) 1997 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 ActiveState Corporation.
+'\"
+'\" 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 dde n 1.4 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.4\fR
+.sp
+\fBdde servername\fR ?\fB\-force\fR? ?\fB\-handler \fIproc\fR? ?\fB\-\|\-\fR? ?\fItopic\fR?
+.sp
+.VS 8.6
+\fBdde execute\fR ?\fB\-async\fR? ?\fB\-binary\fR? \fIservice topic data\fR
+.sp
+\fBdde poke\fR ?\fB\-binary\fR? \fIservice topic item data\fR
+.VE 8.6
+.sp
+\fBdde request\fR ?\fB\-binary\fR? \fIservice topic item\fR
+.sp
+\fBdde services \fIservice topic\fR
+.sp
+\fBdde eval\fR ?\fB\-async\fR? \fItopic cmd \fR?\fIarg arg ...\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+This command allows an application to send Dynamic Data Exchange (DDE)
+command when running under Microsoft Windows. Dynamic Data Exchange is
+a mechanism where applications can exchange raw data. Each DDE
+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 names\fR and \fItopics\fR. For instance, Microsoft Excel
+has the service name \fBExcel\fR.
+.PP
+.SH "DDE COMMANDS"
+.PP
+The following commands are a subset of the full Dynamic Data Exchange
+set of commands.
+.TP
+\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. 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? ?\fB\-binary\fR? \fIservice topic data\fR
+.
+\fBdde execute\fR takes the \fIdata\fR and sends it to the server indicated
+by \fIservice\fR with the topic indicated by \fItopic\fR. Typically,
+\fIservice\fR is the name of an application, and \fItopic\fR is a file to
+work on. The \fIdata\fR field is given to the remote application.
+Typically, the application treats the \fIdata\fR field as a script, and the
+script is run in the application. The \fB\-async\fR option requests
+asynchronous invocation. The command returns an error message if the
+script did not run, unless the \fB\-async\fR flag was used, in which case
+the command returns immediately with no error.
+.VS 8.6
+The \fB\-binary\fR option treats \fIdata\fR as binary data, otherwise an utf-8
+string is sent. Combining \fB-binary\fR with the result of
+\fBencoding convertto\fR may be used to send data in arbitrary encodings.
+.VE 8.6
+.TP
+\fBdde poke ?\fB\-binary\fR? \fIservice topic item data\fR
+.
+\fBdde poke\fR passes the \fIdata\fR to the server indicated by
+\fIservice\fR using the \fItopic\fR and \fIitem\fR specified. Typically,
+\fIservice\fR is the name of an application. \fItopic\fR is application
+specific but can be a command to the server or the name of a file to work
+on. The \fIitem\fR is also application specific and is often not used, but
+it must always be non-null. The \fIdata\fR field is given to the remote
+application.
+.VS 8.6
+The \fB\-binary\fR option treats \fIdata\fR as binary data, otherwise an utf-8
+string is sent.
+.VE 8.6
+.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,
+\fItopic\fR is typically the name of the file, and \fIitem\fR is
+application-specific. The command returns the value of \fIitem\fR as
+defined in the application. Normally this is interpreted to be a
+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 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 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 send on Windows.
+.SH "DDE AND TCL"
+.PP
+A Tcl interpreter always has a service name of \fBTclEval\fR. Each
+different interpreter of all running Tcl applications must be
+given a unique
+name specified by \fBdde servername\fR. Each interp is available as a
+DDE topic only if the \fBdde servername\fR command was used to set the
+name of the topic for each interp. So a \fBdde services TclEval {}\fR
+command will return a list of service-topic pairs, where each of the
+currently running interps will be a topic.
+.PP
+When Tcl processes a \fBdde execute\fR command, the data for the
+execute is run as a script in the interp named by the topic of the
+\fBdde execute\fR command.
+.PP
+When Tcl processes a \fBdde request\fR command, it returns the value of the
+variable given in the dde command in the context of the interp named by the
+dde topic. Tcl reserves the variable \fB$TCLEVAL$EXECUTE$RESULT\fR for
+internal use, and \fBdde request\fR commands for that variable will give
+unpredictable results.
+.PP
+An external application which wishes to run a script in Tcl should have
+that script store its result in a variable, run the \fBdde execute\fR
+command, and then run \fBdde request\fR to get the value of the
+variable.
+.PP
+When using DDE, be careful to ensure that the event queue is flushed
+using either \fBupdate\fR or \fBvwait\fR. This happens by default
+when using \fBwish\fR unless a blocking command is called (such as \fBexec\fR
+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
+.PP
+This asks Internet Explorer (which must already be running) to go to a
+particularly important website:
+.PP
+.CS
+package require dde
+\fBdde execute\fR -async iexplore WWW_OpenURL http://www.tcl.tk/
+.CE
+.SH "SEE ALSO"
+tk(n), winfo(n), send(n)
+.SH KEYWORDS
+application, dde, name, remote execution
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/library/msgcat/doc/define.n b/library/msgcat/doc/define.n
new file mode 100644
index 0000000..6bdd9c5
--- /dev/null
+++ b/library/msgcat/doc/define.n
@@ -0,0 +1,404 @@
+'\"
+'\" Copyright (c) 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 define n 0.3 TclOO "TclOO Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+oo::define, oo::objdefine \- define and configure classes and objects
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBoo::define\fI class defScript\fR
+\fBoo::define\fI class subcommand arg\fR ?\fIarg ...\fR?
+\fBoo::objdefine\fI object defScript\fR
+\fBoo::objdefine\fI object subcommand arg\fR ?\fIarg ...\fR?
+.fi
+.BE
+
+.SH DESCRIPTION
+The \fBoo::define\fR command is used to control the configuration of classes,
+and the \fBoo::objdefine\fR command is used to control the configuration of
+objects (including classes as instance objects), with the configuration being
+applied to the entity named in the \fIclass\fR or the \fIobject\fR argument.
+Configuring a class also updates the
+configuration of all subclasses of the class and all objects that are
+instances of that class or which mix it in (as modified by any per-instance
+configuration). The way in which the configuration is done is controlled by
+either the \fIdefScript\fR argument or by the \fIsubcommand\fR and following
+\fIarg\fR arguments; when the second is present, it is exactly as if all the
+arguments from \fIsubcommand\fR onwards are made into a list and that list is
+used as the \fIdefScript\fR argument.
+.SS "CONFIGURING CLASSES"
+.PP
+The following commands are supported in the \fIdefScript\fR for
+\fBoo::define\fR, each of which may also be used in the \fIsubcommand\fR form:
+.TP
+\fBconstructor\fI argList bodyScript\fR
+.
+This creates or updates the constructor for a class. The formal arguments to
+the constructor (defined using the same format as for the Tcl \fBproc\fR
+command) will be \fIargList\fR, and the body of the constructor will be
+\fIbodyScript\fR. When the body of the constructor is evaluated, the current
+namespace of the constructor will be a namespace that is unique to the object
+being constructed. Within the constructor, the \fBnext\fR command should be
+used to call the superclasses' constructors. If \fIbodyScript\fR is the empty
+string, the constructor will be deleted.
+.TP
+\fBdeletemethod\fI name\fR ?\fIname ...\fR
+.
+This deletes each of the methods called \fIname\fR from a class. The methods
+must have previously existed in that class. Does not affect the superclasses
+of the class, nor does it affect the subclasses or instances of the class
+(except when they have a call chain through the class being modified).
+.TP
+\fBdestructor\fI bodyScript\fR
+.
+This creates or updates the destructor for a class. Destructors take no
+arguments, and the body of the destructor will be \fIbodyScript\fR. The
+destructor is called when objects of the class are deleted, and when called
+will have the object's unique namespace as the current namespace. Destructors
+should use the \fBnext\fR command to call the superclasses' destructors. Note
+that destructors are not called in all situations (e.g. if the interpreter is
+destroyed). If \fIbodyScript\fR is the empty string, the destructor will be
+deleted.
+.RS
+Note that errors during the evaluation of a destructor \fIare not returned\fR
+to the code that causes the destruction of an object. Instead, they are passed
+to the currently-defined \fBbgerror\fR handler.
+.RE
+.TP
+\fBexport\fI name \fR?\fIname ...\fR?
+.
+This arranges for each of the named methods, \fIname\fR, to be exported
+(i.e. usable outside an instance through the instance object's command) by the
+class being defined. Note that the methods themselves may be actually defined
+by a superclass; subclass exports override superclass visibility, and may in
+turn be overridden by instances.
+.TP
+\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+sets or updates the list of method names that are used to guard whether
+method call to instances of the class may be called and what the method's
+results are. Each \fImethodName\fR names a single filtering method (which may
+be exposed or not exposed); it is not an error for a non-existent method to be
+named since they may be defined by subclasses.
+.VS
+By default, this slot works by appending.
+.VE
+.TP
+\fBforward\fI name cmdName \fR?\fIarg ...\fR?
+.
+This creates or updates a forwarded method called \fIname\fR. The method is
+defined be forwarded to the command called \fIcmdName\fR, with additional
+arguments, \fIarg\fR etc., added before those arguments specified by the
+caller of the method. The \fIcmdName\fR will always be resolved using the
+rules of the invoking objects' namespaces, i.e., when \fIcmdName\fR is not
+fully-qualified, the command will be searched for in each object's namespace,
+using the instances' namespace's path, or by looking in the global namespace.
+The method will be exported if \fIname\fR starts with a lower-case letter, and
+non-exported otherwise.
+.TP
+\fBmethod\fI name argList bodyScript\fR
+.
+This creates or updates a method that is implemented as a procedure-like
+script. The name of the method is \fIname\fR, the formal arguments to the
+method (defined using the same format as for the Tcl \fBproc\fR command) will
+be \fIargList\fR, and the body of the method will be \fIbodyScript\fR. When
+the body of the method is evaluated, the current namespace of the method will
+be a namespace that is unique to the current object. The method will be
+exported if \fIname\fR starts with a lower-case letter, and non-exported
+otherwise; this behavior can be overridden via \fBexport\fR and
+\fBunexport\fR.
+.TP
+\fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+sets or updates the list of additional classes that are to be mixed into
+all the instances of the class being defined. Each \fIclassName\fR argument
+names a single class that is to be mixed in.
+.VS
+By default, this slot works by replacement.
+.VE
+.TP
+\fBrenamemethod\fI fromName toName\fR
+.
+This renames the method called \fIfromName\fR in a class to \fItoName\fR. The
+method must have previously existed in the class, and \fItoName\fR must not
+previously refer to a method in that class. Does not affect the superclasses
+of the class, nor does it affect the subclasses or instances of the class
+(except when they have a call chain through the class being modified). Does
+not change the export status of the method; if it was exported before, it will
+be afterwards.
+.TP
+\fBself\fI subcommand arg ...\fR
+.TP
+\fBself\fI script\fR
+.
+This command is equivalent to calling \fBoo::objdefine\fR on the class being
+defined (see \fBCONFIGURING OBJECTS\fR below for a description of the
+supported values of \fIsubcommand\fR). It follows the same general pattern of
+argument handling as the \fBoo::define\fR and \fBoo::objdefine\fR commands,
+and
+.QW "\fBoo::define \fIcls \fBself \fIsubcommand ...\fR"
+operates identically to
+.QW "\fBoo::objdefine \fIcls subcommand ...\fR" .
+.TP
+\fBsuperclass\fI ?\fI\-slotOperation\fR? \fR?\fIclassName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+allows the alteration of the superclasses of the class being defined.
+Each \fIclassName\fR argument names one class that is to be a superclass of
+the defined class. Note that objects must not be changed from being classes to
+being non-classes or vice-versa, that an empty parent class is equivalent to
+\fBoo::object\fR, and that the parent classes of \fBoo::object\fR and
+\fBoo::class\fR may not be modified.
+.VS
+By default, this slot works by replacement.
+.VE
+.TP
+\fBunexport\fI name \fR?\fIname ...\fR?
+.
+This arranges for each of the named methods, \fIname\fR, to be not exported
+(i.e. not usable outside the instance through the instance object's command,
+but instead just through the \fBmy\fR command visible in each object's
+context) by the class being defined. Note that the methods themselves may be
+actually defined by a superclass; subclass unexports override superclass
+visibility, and may be overridden by instance unexports.
+.TP
+\fBvariable\fR ?\fI\-slotOperation\fR? ?\fIname ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below) arranges for each of the named
+variables to be automatically made
+available in the methods, constructor and destructor declared by the class
+being defined. Each variable name must not have any namespace
+separators and must not look like an array access. All variables will be
+actually present in the instance object on which the method is executed. Note
+that the variable lists declared by a superclass or subclass are completely
+disjoint, as are variable lists declared by instances; the list of variable
+names is just for methods (and constructors and destructors) declared by this
+class. By default, this slot works by appending.
+.VE
+.SS "CONFIGURING OBJECTS"
+.PP
+The following commands are supported in the \fIdefScript\fR for
+\fBoo::objdefine\fR, each of which may also be used in the \fIsubcommand\fR
+form:
+.TP
+\fBclass\fI className\fR
+.
+This allows the class of an object to be changed after creation. Note that the
+class's constructors are not called when this is done, and so the object may
+well be in an inconsistent state unless additional configuration work is done.
+.TP
+\fBdeletemethod\fI name\fR ?\fIname ...\fR
+.
+This deletes each of the methods called \fIname\fR from an object. The methods
+must have previously existed in that object. Does not affect the classes that
+the object is an instance of.
+.TP
+\fBexport\fI name \fR?\fIname ...\fR?
+.
+This arranges for each of the named methods, \fIname\fR, to be exported
+(i.e. usable outside the object through the object's command) by the object
+being defined. Note that the methods themselves may be actually defined by a
+class or superclass; object exports override class visibility.
+.TP
+\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+sets or updates the list of method names that are used to guard whether a
+method call to the object may be called and what the method's results are.
+Each \fImethodName\fR names a single filtering method (which may be exposed or
+not exposed); it is not an error for a non-existent method to be named. Note
+that the actual list of filters also depends on the filters set upon any
+classes that the object is an instance of.
+.VS
+By default, this slot works by appending.
+.VE
+.TP
+\fBforward\fI name cmdName \fR?\fIarg ...\fR?
+.
+This creates or updates a forwarded object method called \fIname\fR. The
+method is defined be forwarded to the command called \fIcmdName\fR, with
+additional arguments, \fIarg\fR etc., added before those arguments specified
+by the caller of the method. Forwarded methods should be deleted using the
+\fBmethod\fR subcommand. The method will be exported if \fIname\fR starts with
+a lower-case letter, and non-exported otherwise.
+.TP
+\fBmethod\fI name argList bodyScript\fR
+.
+This creates, updates or deletes an object method. The name of the method is
+\fIname\fR, the formal arguments to the method (defined using the same format
+as for the Tcl \fBproc\fR command) will be \fIargList\fR, and the body of the
+method will be \fIbodyScript\fR. When the body of the method is evaluated, the
+current namespace of the method will be a namespace that is unique to the
+object. The method will be exported if \fIname\fR starts with a lower-case
+letter, and non-exported otherwise.
+.TP
+\fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+sets or updates a per-object list of additional classes that are to be
+mixed into the object. Each argument, \fIclassName\fR, names a single class
+that is to be mixed in.
+.VS
+By default, this slot works by replacement.
+.VE
+.TP
+\fBrenamemethod\fI fromName toName\fR
+.
+This renames the method called \fIfromName\fR in an object to \fItoName\fR.
+The method must have previously existed in the object, and \fItoName\fR must
+not previously refer to a method in that object. Does not affect the classes
+that the object is an instance of. Does not change the export status of the
+method; if it was exported before, it will be afterwards.
+.TP
+\fBunexport\fI name \fR?\fIname ...\fR?
+.
+This arranges for each of the named methods, \fIname\fR, to be not exported
+(i.e. not usable outside the object through the object's command, but instead
+just through the \fBmy\fR command visible in the object's context) by the
+object being defined. Note that the methods themselves may be actually defined
+by a class; instance unexports override class visibility.
+.TP
+\fBvariable\fR ?\fI\-slotOperation\fR? ?\fIname ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below) arranges for each of the named
+variables to be automatically made available in the methods declared by the
+object being defined. Each variable name must not have any namespace
+separators and must not look like an array access. All variables will be
+actually present in the object on which the method is executed. Note that the
+variable lists declared by the classes and mixins of which the object is an
+instance are completely disjoint; the list of variable names is just for
+methods declared by this object. By default, this slot works by appending.
+.SH "SLOTTED DEFINITIONS"
+Some of the configurable definitions of a class or object are \fIslotted
+definitions\fR. This means that the configuration is implemented by a slot
+object, that is an instance of the class \fBoo::Slot\fR, which manages a list
+of values (class names, variable names, etc.) that comprises the contents of
+the slot. The class defines three operations (as methods) that may be done on
+the slot:
+.VE
+.TP
+\fIslot\fR \fB\-append\fR ?\fImember ...\fR?
+.VS
+This appends the given \fImember\fR elements to the slot definition.
+.VE
+.TP
+\fIslot\fR \fB\-clear\fR
+.VS
+This sets the slot definition to the empty list.
+.VE
+.TP
+\fIslot\fR \fB\-set\fR ?\fImember ...\fR?
+.VS
+This replaces the slot definition with the given \fImember\fR elements.
+.PP
+A consequence of this is that any use of a slot's default operation where the
+first member argument begins with a hyphen will be an error. One of the above
+operations should be used explicitly in those circumstances.
+.SS "SLOT IMPLEMENTATION"
+Internally, slot objects also define a method \fB\-\-default\-operation\fR
+which is forwarded to the default operation of the slot (thus, for the class
+.QW \fBvariable\fR
+slot, this is forwarded to
+.QW "\fBmy \-append\fR" ),
+and these methods which provide the implementation interface:
+.VE
+.TP
+\fIslot\fR \fBGet\fR
+.VS
+Returns a list that is the current contents of the slot. This method must
+always be called from a stack frame created by a call to \fBoo::define\fR or
+\fBoo::objdefine\fR.
+.VE
+.TP
+\fIslot\fR \fBSet \fIelementList\fR
+.VS
+Sets the contents of the slot to the list \fIelementList\fR and returns the
+empty string. This method must always be called from a stack frame created by
+a call to \fBoo::define\fR or \fBoo::objdefine\fR.
+.PP
+The implementation of these methods is slot-dependent (and responsible for
+accessing the correct part of the class or object definition). Slots also have
+an unknown method handler to tie all these pieces together, and they hide
+their \fBdestroy\fR method so that it is not invoked inadvertently. It is
+\fIrecommended\fR that any user changes to the slot mechanism be restricted to
+defining new operations whose names start with a hyphen.
+.VE
+.SH EXAMPLES
+This example demonstrates how to use both forms of the \fBoo::define\fR and
+\fBoo::objdefine\fR commands (they work in the same way), as well as
+illustrating four of the subcommands of them.
+.PP
+.CS
+oo::class create c
+c create o
+\fBoo::define\fR c \fBmethod\fR foo {} {
+ puts "world"
+}
+\fBoo::objdefine\fR o {
+ \fBmethod\fR bar {} {
+ my Foo "hello "
+ my foo
+ }
+ \fBforward\fR Foo ::puts -nonewline
+ \fBunexport\fR foo
+}
+o bar \fI\(-> prints "hello world"\fR
+o foo \fI\(-> error "unknown method foo"\fR
+o Foo Bar \fI\(-> error "unknown method Foo"\fR
+\fBoo::objdefine\fR o \fBrenamemethod\fR bar lollipop
+o lollipop \fI\(-> prints "hello world"\fR
+.CE
+.PP
+This example shows how additional classes can be mixed into an object. It also
+shows how \fBmixin\fR is a slot that supports appending:
+.PP
+.CS
+oo::object create inst
+inst m1 \fI\(-> error "unknown method m1"\fR
+inst m2 \fI\(-> error "unknown method m2"\fR
+
+oo::class create A {
+ \fBmethod\fR m1 {} {
+ puts "red brick"
+ }
+}
+\fBoo::objdefine\fR inst {
+ \fBmixin\fR A
+}
+inst m1 \fI\(-> prints "red brick"\fR
+inst m2 \fI\(-> error "unknown method m2"\fR
+
+oo::class create B {
+ \fBmethod\fR m2 {} {
+ puts "blue brick"
+ }
+}
+\fBoo::objdefine\fR inst {
+ \fBmixin -append\fR B
+}
+inst m1 \fI\(-> prints "red brick"\fR
+inst m2 \fI\(-> prints "blue brick"\fR
+.CE
+.SH "SEE ALSO"
+next(n), oo::class(n), oo::object(n)
+.SH KEYWORDS
+class, definition, method, object, slot
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/library/msgcat/doc/dict.n b/library/msgcat/doc/dict.n
new file mode 100644
index 0000000..361a112
--- /dev/null
+++ b/library/msgcat/doc/dict.n
@@ -0,0 +1,416 @@
+'\"
+'\" 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\fR ?\fIglobPattern ...\fR?
+.VS 8.6
+The key rule only matches those key/value pairs whose keys match any
+of the given patterns (in the style of \fBstring match\fR.)
+.VE 8.6
+.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 \fR?\fIglobPattern ...\fR?
+.VS 8.6
+The value rule only matches those key/value pairs whose values match any
+of the given patterns (in the style of \fBstring match\fR.)
+.VE 8.6
+.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, lambda term for \fBapply\fR, or method). 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, lambda term for \fBapply\fR, or method). 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
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/encoding.n b/library/msgcat/doc/encoding.n
new file mode 100644
index 0000000..5269a18
--- /dev/null
+++ b/library/msgcat/doc/encoding.n
@@ -0,0 +1,95 @@
+'\"
+'\" Copyright (c) 1998 by Scriptics Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH encoding n "8.1" Tcl "Tcl Built-In Commands"
+.BS
+.SH NAME
+encoding \- Manipulate encodings
+.SH SYNOPSIS
+\fBencoding \fIoption\fR ?\fIarg arg ...\fR?
+.BE
+.SH INTRODUCTION
+.PP
+Strings in Tcl are encoded using 16-bit Unicode characters. Different
+operating system interfaces or applications may generate strings in
+other encodings such as Shift-JIS. The \fBencoding\fR command helps
+to bridge the gap between Unicode and these other formats.
+.SH DESCRIPTION
+.PP
+Performs one of several encoding related operations, depending on
+\fIoption\fR. The legal \fIoption\fRs are:
+.TP
+\fBencoding convertfrom\fR ?\fIencoding\fR? \fIdata\fR
+.
+Convert \fIdata\fR to Unicode from the specified \fIencoding\fR. The
+characters in \fIdata\fR are treated as binary data where the lower
+8-bits of each character is taken as a single byte. The resulting
+sequence of bytes is treated as a string in the specified
+\fIencoding\fR. If \fIencoding\fR is not specified, the current
+system encoding is used.
+.TP
+\fBencoding convertto\fR ?\fIencoding\fR? \fIstring\fR
+.
+Convert \fIstring\fR from Unicode to the specified \fIencoding\fR.
+The result is a sequence of bytes that represents the converted
+string. Each byte is stored in the lower 8-bits of a Unicode
+character. If \fIencoding\fR is not specified, the current
+system encoding is used.
+.TP
+\fBencoding dirs\fR ?\fIdirectoryList\fR?
+.
+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.
+.TP
+\fBencoding names\fR
+.
+Returns a list containing the names of all of the encodings that are
+currently available.
+.TP
+\fBencoding system\fR ?\fIencoding\fR?
+.
+Set the system encoding to \fIencoding\fR. If \fIencoding\fR is
+omitted then the command returns the current system encoding. The
+system encoding is used whenever Tcl passes strings to system calls.
+.SH EXAMPLE
+.PP
+It is common practice to write script files using a text editor that
+produces output in the euc-jp encoding, which represents the ASCII
+characters as singe bytes and Japanese characters as two bytes. This
+makes it easy to embed literal strings that correspond to non-ASCII
+characters by simply typing the strings in place in the script.
+However, because the \fBsource\fR command always reads files using the
+current system encoding, Tcl will only source such files correctly
+when the encoding used to write the file is the same. This tends not
+to be true in an internationalized setting. For example, if such a
+file was sourced in North America (where the ISO8859-1 is normally
+used), each byte in the file would be treated as a separate character
+that maps to the 00 page in Unicode. The resulting Tcl strings will
+not contain the expected Japanese characters. Instead, they will
+contain a sequence of Latin-1 characters that correspond to the bytes
+of the original string. The \fBencoding\fR command can be used to
+convert this string to the expected Japanese Unicode characters. For
+example,
+.PP
+.CS
+set s [\fBencoding convertfrom\fR euc-jp "\exA4\exCF"]
+.CE
+.PP
+would return the Unicode string
+.QW "\eu306F" ,
+which is the Hiragana letter HA.
+.SH "SEE ALSO"
+Tcl_GetEncoding(3)
+.SH KEYWORDS
+encoding, unicode
diff --git a/library/msgcat/doc/eof.n b/library/msgcat/doc/eof.n
new file mode 100644
index 0000000..017b10e
--- /dev/null
+++ b/library/msgcat/doc/eof.n
@@ -0,0 +1,61 @@
+'\"
+'\" 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 eof n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+eof \- Check for end of file condition on channel
+.SH SYNOPSIS
+\fBeof \fIchannelId\fR
+.BE
+.SH DESCRIPTION
+.PP
+Returns 1 if an end of file condition occurred during the most
+recent input operation on \fIchannelId\fR (such as \fBgets\fR),
+0 otherwise.
+.PP
+\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.
+.SH EXAMPLES
+.PP
+Read and print out the contents of a file line-by-line:
+.PP
+.CS
+set f [open somefile.txt]
+while {1} {
+ set line [gets $f]
+ if {[\fBeof\fR $f]} {
+ close $f
+ break
+ }
+ puts "Read line: $line"
+}
+.CE
+.PP
+Read and print out the contents of a file by fixed-size records:
+.PP
+.CS
+set f [open somefile.dat]
+fconfigure $f -translation binary
+set recordSize 40
+while {1} {
+ set record [read $f $recordSize]
+ if {[\fBeof\fR $f]} {
+ close $f
+ break
+ }
+ puts "Read record: $record"
+}
+.CE
+.SH "SEE ALSO"
+file(n), open(n), close(n), fblocked(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+channel, end of file
diff --git a/library/msgcat/doc/error.n b/library/msgcat/doc/error.n
new file mode 100644
index 0000000..d61bd7b
--- /dev/null
+++ b/library/msgcat/doc/error.n
@@ -0,0 +1,78 @@
+'\"
+'\" 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 error n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+error \- Generate an error
+.SH SYNOPSIS
+\fBerror \fImessage\fR ?\fIinfo\fR? ?\fIcode\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+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
+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 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:
+.PP
+.CS
+catch {...} errMsg
+set savedInfo $::errorInfo
+\&...
+\fBerror\fR $errMsg $savedInfo
+.CE
+.PP
+When working with Tcl 8.5 or later, the following code
+should be used instead:
+.PP
+.CS
+catch {...} errMsg options
+\&...
+return -options $options $errMsg
+.CE
+.PP
+If the \fIcode\fR argument is present, then its value is stored
+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
+.PP
+Generate an error if a basic mathematical operation fails:
+.PP
+.CS
+if {1+2 != 3} {
+ \fBerror\fR "something is very wrong with addition"
+}
+.CE
+.SH "SEE ALSO"
+catch(n), return(n)
+.SH KEYWORDS
+error, exception
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/eval.n b/library/msgcat/doc/eval.n
new file mode 100644
index 0000000..da88757
--- /dev/null
+++ b/library/msgcat/doc/eval.n
@@ -0,0 +1,83 @@
+'\"
+'\" 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 eval n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+eval \- Evaluate a Tcl script
+.SH SYNOPSIS
+\fBeval \fIarg \fR?\fIarg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+\fBEval\fR takes one or more arguments, which together comprise a Tcl
+script containing one or more commands.
+\fBEval\fR concatenates all its arguments in the same
+fashion as the \fBconcat\fR command, passes the concatenated string to the
+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 EXAMPLES
+.PP
+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:
+.PP
+.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
+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.
+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:
+.PP
+.CS
+proc lprepend {varName args} {
+ upvar 1 $varName var
+ # Ensure that the variable exists and contains a list
+ lappend var
+ # Now we insert all the arguments in one go
+ set var [\fBeval\fR [list linsert $var 0] $args]
+}
+.CE
+.PP
+However, the last line would now normally be written without
+\fBeval\fR, like this:
+.PP
+.CS
+set var [linsert $var 0 {*}$args]
+.CE
+.SH "SEE ALSO"
+catch(n), concat(n), error(n), interp(n), list(n), namespace(n), subst(n), tclvars(n), uplevel(n)
+.SH KEYWORDS
+concatenate, evaluate, script
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/exec.n b/library/msgcat/doc/exec.n
new file mode 100644
index 0000000..5072d61
--- /dev/null
+++ b/library/msgcat/doc/exec.n
@@ -0,0 +1,516 @@
+'\"
+'\" 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 8.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+exec \- Invoke subprocesses
+.SH SYNOPSIS
+\fBexec \fR?\fIswitches\fR? \fIarg \fR?\fIarg ...\fR? ?\fB&\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command treats its arguments as the specification
+of one or more subprocesses to execute.
+The arguments take the form of a standard shell pipeline
+where each \fIarg\fR becomes one word of a command, and
+each distinct command becomes a subprocess.
+.PP
+If the initial arguments to \fBexec\fR start with \fB\-\fR then
+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
+.
+Stops the \fBexec\fR command from treating the output of messages to the
+pipeline's standard error channel as an error case.
+.TP 13
+\fB\-keepnewline\fR
+.
+Retains a trailing newline in the pipeline's output.
+Normally a trailing newline will be deleted.
+.TP 13
+\fB\-\|\-\fR
+.
+Marks the end of switches. The argument following this one will
+be treated as the first \fIarg\fR even if it starts with a \fB\-\fR.
+.PP
+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
+.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
+\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
+\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
+\fB<<\0\fIvalue\fR
+.
+\fIValue\fR is passed to the first command as its standard input.
+.TP 15
+\fB>\0\fIfileName\fR
+.
+Standard output from the last command is redirected to the file named
+\fIfileName\fR, overwriting its previous contents.
+.TP 15
+\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
+\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
+\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
+\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
+\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
+\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
+\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
+\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
+all commands are redirected to \fIfileId\fR's file.
+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, unless
+.QW 2>@1
+was specified, in which case standard error is included as well.
+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
+\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 is not redirected
+and \fB\-ignorestderr\fR is not specified,
+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
+output.
+.PP
+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 do not
+normally end with newlines.
+However, if \fB\-keepnewline\fR is specified then the trailing
+newline is retained.
+.PP
+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
+.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 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.
+.PP
+The first word in each command is taken as the command name;
+tilde-substitution is performed on it, and if the result contains
+no slashes then the directories
+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
+.QW glob
+expansion or other shell-like substitutions
+are performed on the arguments to commands.
+.SH "PORTABILITY ISSUES"
+.TP
+\fBWindows\fR (all versions)
+.
+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.
+.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.
+.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
+as path separators. Bear in mind, however, that most Windows applications
+accept arguments with forward slashes only as option delimiters and
+backslashes only in paths. Any arguments to an application that specify a
+path name with forward slashes will not automatically be converted to use
+the backslash character. If an argument contains forward slashes as the
+path separator, it may or may not be recognized as a path name, depending on
+the program.
+.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
+.QW applba~1.def
+instead of
+.QW applbakery.default ),
+which can be obtained with the
+.QW "\fBfile attributes\fI fileName \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
+\fBc://windows/system\fR (two slashes together), which refers to the mount
+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.
+.PP
+Note that there are two general types of Win32 console applications:
+.RS
+.IP [1]
+CLI \(em CommandLine Interface, simple stdio exchange. \fBnetstat.exe\fR for
+example.
+.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.
+.RE
+.TP
+\fBWindows NT\fR
+.
+When attempting to execute an application, \fBexec\fR first searches for
+the name as it was specified. Then, in order, \fB.com\fR, \fB.exe\fR, and
+\fB.bat\fR are appended to the end of the specified name and it searches
+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:
+.RS
+.IP \(bu 3
+The directory from which the Tcl executable was loaded.
+.IP \(bu 3
+The current directory.
+.IP \(bu 3
+The Windows NT 32-bit system directory.
+.IP \(bu 3
+The Windows NT 16-bit system directory.
+.IP \(bu 3
+The Windows NT home directory.
+.IP \(bu 3
+The directories listed in the path.
+.PP
+In order to execute shell built-in commands like \fBdir\fR and \fBcopy\fR,
+the caller must prepend the desired command with
+.QW "\fBcmd.exe /c\0\fR"
+because built-in commands are not implemented using executables.
+.RE
+.TP
+\fBWindows 9x\fR
+.
+When attempting to execute an application, \fBexec\fR first searches for
+the name as it was specified. Then, in order, \fB.com\fR, \fB.exe\fR, and
+\fB.bat\fR are appended to the end of the specified name and it searches
+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:
+.RS
+.IP \(bu 3
+The directory from which the Tcl executable was loaded.
+.IP \(bu 3
+The current directory.
+.IP \(bu 3
+The Windows 9x system directory.
+.IP \(bu 3
+The Windows 9x home directory.
+.IP \(bu 3
+The directories listed in the path.
+.RE
+.RS
+.PP
+In order to execute shell built-in commands like \fBdir\fR and \fBcopy\fR,
+the caller must prepend the desired command with
+.QW "\fBcommand.com /c\0\fR"
+because built-in commands are not implemented using executables.
+.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.
+.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
+.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.
+.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
+begins executing. All standard output or error from a 16-bit DOS
+application to a pipe is collected into temporary files; the application
+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.
+.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
+output may fail, hang Tcl, or even hang the system if their own private
+console window is not available to them.
+.RE
+.TP
+\fBUnix\fR (including Mac OS X)
+.
+The \fBexec\fR command is fully functional and works as described.
+.SH "UNIX EXAMPLES"
+.PP
+Here are some examples of the use of the \fBexec\fR command on Unix.
+To execute a simple program and get its result:
+.PP
+.CS
+\fBexec\fR uname -a
+.CE
+.SS "WORKING WITH NON-ZERO RESULTS"
+.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 the contents
+of the \fB\-errorcode\fR return option if you have an error:
+.PP
+.CS
+set status 0
+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 other error; regenerate it to let caller handle
+ return -options $options -level 0 $results
+ }
+}
+.CE
+.VS 8.6
+.PP
+This is more easily written using the \fBtry\fR command, as that makes
+it simpler to trap specific types of errors. This is
+done using code like this:
+.PP
+.CS
+try {
+ set results [\fBexec\fR grep foo bar.txt]
+ set status 0
+} trap CHILDSTATUS {results options} {
+ set status [lindex [dict get $options -errorcode] 2]
+}
+.CE
+.VE 8.6
+.SS "WORKING WITH QUOTED ARGUMENTS"
+.PP
+When translating a command from a Unix shell invocation, care should
+be taken over the fact that single quote characters have no special
+significance to Tcl. Thus:
+.PP
+.CS
+awk '{sum += $1} END {print sum}' numbers.list
+.CE
+.PP
+would be translated into something like:
+.PP
+.CS
+\fBexec\fR awk {{sum += $1} END {print sum}} numbers.list
+.CE
+.SS "WORKING WITH GLOBBING"
+.PP
+If you are converting invocations involving shell globbing, you should
+remember that Tcl does not handle globbing or expand things into
+multiple arguments by default. Instead you should write things like
+this:
+.PP
+.CS
+\fBexec\fR ls -l {*}[glob *.tcl]
+.CE
+.SS "WORKING WITH USER-SUPPLIED SHELL SCRIPT FRAGMENTS"
+.PP
+One useful technique can be to expose to users of a script the ability
+to specify a fragment of shell script to execute that will have some
+data passed in on standard input that was produced by the Tcl program.
+This is a common technique for using the \fIlpr\fR program for
+printing. By far the simplest way of doing this is to pass the user's
+script to the user's shell for processing, as this avoids a lot of
+complexity with parsing other languages.
+.PP
+.CS
+set lprScript [\fIget from user...\fR]
+set postscriptData [\fIgenerate somehow...\fR]
+
+\fBexec\fR $env(SHELL) -c $lprScript << $postscriptData
+.CE
+.SH "WINDOWS EXAMPLES"
+.PP
+Here are some examples of the use of the \fBexec\fR command on Windows.
+To start an instance of \fInotepad\fR editing a file without waiting
+for the user to finish editing the file:
+.PP
+.CS
+\fBexec\fR notepad myfile.txt &
+.CE
+.PP
+To print a text file using \fInotepad\fR:
+.PP
+.CS
+\fBexec\fR notepad /p myfile.txt
+.CE
+.SS "WORKING WITH CONSOLE PROGRAMS"
+.PP
+If a program calls other programs, such as is common with compilers,
+then you may need to resort to batch files to hide the console windows
+that sometimes pop up:
+.PP
+.CS
+\fBexec\fR cmp.bat somefile.c -o somefile
+.CE
+.PP
+With the file \fIcmp.bat\fR looking something like:
+.PP
+.CS
+@gcc %1 %2 %3 %4 %5 %6 %7 %8 %9
+.CE
+.SS "WORKING WITH COMMAND BUILT-INS"
+.PP
+Sometimes you need to be careful, as different programs may have the
+same name and be in the path. It can then happen that typing a command
+at the DOS prompt finds \fIa different program\fR than the same
+command run via \fBexec\fR. This is because of the (documented)
+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
+.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:
+.PP
+.CS
+\fBexec\fR {*}[auto_execok dir] *.tcl
+.CE
+.SS "WORKING WITH NATIVE FILENAMES"
+.PP
+Many programs on Windows require filename arguments to be passed in with
+backslashes as pathname separators. This is done with the help of the
+\fBfile nativename\fR command. For example, to make a directory (on NTFS)
+encrypted so that only the current user can access it requires use of
+the \fICIPHER\fR command, like this:
+.PP
+.CS
+set secureDir "~/Desktop/Secure Directory"
+file mkdir $secureDir
+\fBexec\fR CIPHER /e /s:[file nativename $secureDir]
+.CE
+.SH "SEE ALSO"
+error(n), file(n), open(n)
+.SH KEYWORDS
+execute, pipeline, redirection, subprocess
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/exit.n b/library/msgcat/doc/exit.n
new file mode 100644
index 0000000..ceb0529
--- /dev/null
+++ b/library/msgcat/doc/exit.n
@@ -0,0 +1,51 @@
+'\"
+'\" 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 exit n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+exit \- End the application
+.SH SYNOPSIS
+\fBexit \fR?\fIreturnCode\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+Terminate the process, returning \fIreturnCode\fR to the
+system as the exit status.
+If \fIreturnCode\fR is not specified then it defaults
+to 0.
+.SH EXAMPLE
+.PP
+Since non-zero exit codes are usually interpreted as error cases by
+the calling process, the \fBexit\fR command is an important part of
+signaling that something fatal has gone wrong. This code fragment is
+useful in scripts to act as a general problem trap:
+.PP
+.CS
+proc main {} {
+ # ... put the real main code in here ...
+}
+
+if {[catch {main} msg options]} {
+ puts stderr "unexpected script error: $msg"
+ if {[info exist env(DEBUG)]} {
+ puts stderr "---- BEGIN TRACE ----"
+ puts stderr [dict get $options -errorinfo]
+ puts stderr "---- END TRACE ----"
+ }
+
+ # Reserve code 1 for "expected" error exits...
+ \fBexit\fR 2
+}
+.CE
+.SH "SEE ALSO"
+exec(n)
+.SH KEYWORDS
+abort, exit, process
diff --git a/library/msgcat/doc/expr.n b/library/msgcat/doc/expr.n
new file mode 100644
index 0000000..6d965fb
--- /dev/null
+++ b/library/msgcat/doc/expr.n
@@ -0,0 +1,463 @@
+'\"
+'\" 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.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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 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
+.PP
+.CS
+\fBexpr\fR 8.2 + 6
+.CE
+.PP
+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, 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 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 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.
+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
+Operands may be specified in any of the following ways:
+.IP [1]
+As a numeric value, either integer or floating-point.
+.IP [2]
+As a boolean value, using any form understood by \fBstring is\fR
+\fBboolean\fR.
+.IP [3]
+As a Tcl variable, using standard \fB$\fR notation.
+The variable's value will be used as the operand.
+.IP [4]
+As a string enclosed in double-quotes.
+The expression parser will perform backslash, variable, and
+command substitutions on the information between the quotes,
+and use the resulting value as the operand
+.IP [5]
+As a string enclosed in braces.
+The characters between the open brace and matching close brace
+will be used as the operand without any substitutions.
+.IP [6]
+As a Tcl command enclosed in brackets.
+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 \fBMATH FUNCTIONS\fR below for
+a discussion of how mathematical functions are handled.
+.PP
+Where the above substitutions occur (e.g. inside quoted strings), they
+are performed by the expression's instructions.
+However, the command parser may already have performed one round of
+substitution before the expression processor was called.
+As discussed below, it is usually best to enclose expressions
+in braces to prevent the command parser from performing substitutions
+on the contents.
+.PP
+For some examples of simple expressions, suppose the variable
+\fBa\fR has the value 3 and
+the variable \fBb\fR has the value 6.
+Then the command on the left side of each of the lines below
+will produce the value on the right side of the line:
+.PP
+.CS
+.ta 6c
+\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
+.SS OPERATORS
+.PP
+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
+.
+Exponentiation. Valid for any numeric operands.
+.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
+to integers.
+The remainder will always have the same sign as the divisor and
+an absolute value smaller than the absolute value of the divisor.
+.RS
+.PP
+When applied to integers, the division and remainder operators can be
+considered to partition the number line into a sequence of equal-sized
+adjacent non-overlapping pieces where each piece is the size of the divisor;
+the division result identifies which piece the divisor lay within, and the
+remainder result identifies where within that piece the divisor lay. A
+consequence of this is that the result of
+.QW "-57 \fB/\fR 10"
+is always -6, and the result of
+.QW "-57 \fB%\fR 10"
+is always 3.
+.RE
+.TP 20
+\fB+\0\0\-\fR
+.
+Add and subtract. Valid for any numeric operands.
+.TP 20
+\fB<<\0\0>>\fR
+.
+Left and right shift. Valid for integer operands only.
+A right shift always propagates the sign bit.
+.TP 20
+\fB<\0\0>\0\0<=\0\0>=\fR
+.
+Boolean less, greater, less than or equal, and greater than or equal.
+Each operator produces 1 if the condition is true, 0 otherwise.
+These operators may be applied to strings as well as numeric operands,
+in which case string comparison is used.
+.TP 20
+\fB==\0\0!=\fR
+.
+Boolean equal and not equal. Each operator produces a zero/one result.
+Valid for all operand types.
+.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.
+.TP 20
+\fBin\0\0ni\fR
+.
+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.
+.TP 20
+\fB&\fR
+.
+Bit-wise AND. Valid for integer operands only.
+.TP 20
+\fB^\fR
+.
+Bit-wise exclusive OR. Valid for integer operands only.
+.TP 20
+\fB|\fR
+.
+Bit-wise OR. Valid for integer operands only.
+.TP 20
+\fB&&\fR
+.
+Logical AND. Produces a 1 result if both operands are non-zero,
+0 otherwise.
+Valid for boolean and numeric (integers or floating-point) operands only.
+.TP 20
+\fB||\fR
+.
+Logical OR. Produces a 0 result if both operands are zero, 1 otherwise.
+Valid for boolean and numeric (integers or floating-point) operands only.
+.TP 20
+\fIx\fB?\fIy\fB:\fIz\fR
+.
+If-then-else, as in C. If \fIx\fR
+evaluates to non-zero, then the result is the value of \fIy\fR.
+Otherwise the result is the value of \fIz\fR.
+The \fIx\fR operand must have a boolean or numeric value.
+.PP
+See the C manual for more details on the results
+produced by each operator.
+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.)
+All of the binary operators but exponentiation group left-to-right
+within the same precedence level; exponentiation groups right-to-left. For example, the command
+.PP
+.CS
+\fBexpr\fR {4*2 < 7}
+.CE
+.PP
+returns 0, while
+.PP
+.CS
+\fBexpr\fR {2**3**2}
+.CE
+.PP
+returns 512.
+.PP
+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
+.PP
+.CS
+\fBexpr\fR {$v ? [a] : [b]}
+.CE
+.PP
+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
+.QW \fB[a]\fR
+and
+.QW \fB[b]\fR
+before invoking the \fBexpr\fR command.
+.SS "MATH FUNCTIONS"
+.PP
+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:
+.PP
+.CS
+\fBexpr\fR {sin($x+$y)}
+.CE
+.PP
+is the same in every way as the processing of:
+.PP
+.CS
+\fBexpr\fR {[tcl::mathfunc::sin [\fBexpr\fR {$x+$y}]]}
+.CE
+.PP
+which in turn is the same as the processing of:
+.PP
+.CS
+tcl::mathfunc::sin [\fBexpr\fR {$x+$y}]
+.CE
+.PP
+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
+See the \fBmathfunc\fR(n) manual page for the math functions that are
+available by default.
+.SS "TYPES, OVERFLOW, AND PRECISION"
+.PP
+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.
+.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 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
+Conversion among internal representations for integer, floating-point,
+and string operands is done automatically as needed.
+For arithmetic computations, integers are used until some
+floating-point number is introduced, after which floating-point is used.
+For example,
+.PP
+.CS
+\fBexpr\fR {5 / 4}
+.CE
+.PP
+returns 1, while
+.PP
+.CS
+\fBexpr\fR {5 / 4.0}
+\fBexpr\fR {5 / ( [string length "abcd"] + 0.0 )}
+.CE
+.PP
+both return 1.25.
+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,
+.PP
+.CS
+\fBexpr\fR {20.0/5.0}
+.CE
+.PP
+returns \fB4.0\fR, not \fB4\fR.
+.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,
+i.e., when all arguments to the operator allow numeric interpretations,
+except in the case of the \fBeq\fR and \fBne\fR operators.
+If one of the operands of a comparison is a string and the other
+has a numeric value, a canonical string representation of the numeric
+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
+.PP
+.CS
+\fBexpr\fR {"0x03" > "2"}
+\fBexpr\fR {"0y" > "0x12"}
+.CE
+.PP
+both return 1. The first comparison is done using integer
+comparison, and the second is done using string comparison.
+Because of Tcl's tendency to treat values as numbers whenever
+possible, it is not generally a good idea to use operators like \fB==\fR
+when you really want string comparison and the values of the
+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
+storage requirements.
+This allows the Tcl bytecode compiler to generate the best code.
+.PP
+As mentioned above, expressions are substituted twice:
+once by the Tcl parser and once by the \fBexpr\fR command.
+For example, the commands
+.PP
+.CS
+set a 3
+set b {$a + 2}
+\fBexpr\fR $b*4
+.CE
+.PP
+return 11, not a multiple of 4.
+This is because the Tcl parser will first substitute \fB$a + 2\fR for
+the variable \fBb\fR,
+then the \fBexpr\fR command will evaluate the expression \fB$a + 2*4\fR.
+.PP
+Most expressions do not require a second round of substitutions.
+Either they are enclosed in braces or, if not,
+their variable and command substitutions yield numbers or strings
+that do not themselves require substitutions.
+However, because a few unbraced expressions
+need two rounds of substitutions,
+the bytecode compiler must emit
+additional instructions to handle this situation.
+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.
+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.
+.SH EXAMPLES
+.PP
+Define a procedure that computes an
+.QW interesting
+mathematical function:
+.PP
+.CS
+proc tcl::mathfunc::calc {x y} {
+ \fBexpr\fR { ($x**2 - $y**2) / exp($x**2 + $y**2) }
+}
+.CE
+.PP
+Convert polar coordinates into cartesian coordinates:
+.PP
+.CS
+# convert from ($radius,$angle)
+set x [\fBexpr\fR { $radius * cos($angle) }]
+set y [\fBexpr\fR { $radius * sin($angle) }]
+.CE
+.PP
+Convert cartesian coordinates into polar coordinates:
+.PP
+.CS
+# convert from ($x,$y)
+set radius [\fBexpr\fR { hypot($y, $x) }]
+set angle [\fBexpr\fR { atan2($y, $x) }]
+.CE
+.PP
+Print a message describing the relationship of two string values to
+each other:
+.PP
+.CS
+puts "a and b are [\fBexpr\fR {$a eq $b ? {equal} : {different}}]"
+.CE
+.PP
+Set a variable to whether an environment variable is both defined at
+all and also set to a true boolean value:
+.PP
+.CS
+set isTrue [\fBexpr\fR {
+ [info exists ::env(SOME_ENV_VAR)] &&
+ [string is true -strict $::env(SOME_ENV_VAR)]
+}]
+.CE
+.PP
+Generate a random integer in the range 0..99 inclusive:
+.PP
+.CS
+set randNum [\fBexpr\fR { int(100 * rand()) }]
+.CE
+.SH "SEE ALSO"
+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
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/fblocked.n b/library/msgcat/doc/fblocked.n
new file mode 100644
index 0000000..2841aee
--- /dev/null
+++ b/library/msgcat/doc/fblocked.n
@@ -0,0 +1,67 @@
+'\"
+'\" 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.
+'\"
+.TH fblocked n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+fblocked \- Test whether the last input operation exhausted all available input
+.SH SYNOPSIS
+\fBfblocked \fIchannelId\fR
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBfblocked\fR command returns 1 if the most recent input operation
+on \fIchannelId\fR returned less information than requested because all
+available input was exhausted.
+For example, if \fBgets\fR is invoked when there are only three
+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
+\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.
+.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
+without preventing the servicing of other connections. This can be
+seen in this simple echo-service:
+.PP
+.CS
+# This is called whenever a new client connects to the server
+proc connect {chan host port} {
+ set clientName [format <%s:%d> $host $port]
+ puts "connection from $clientName"
+ fconfigure $chan -blocking 0 -buffering line
+ fileevent $chan readable [list echoLine $chan $clientName]
+}
+
+# This is called whenever either at least one byte of input
+# data is available, or the channel was closed by the client.
+proc echoLine {chan clientName} {
+ gets $chan line
+ if {[eof $chan]} {
+ puts "finishing connection from $clientName"
+ close $chan
+ } elseif {![\fBfblocked\fR $chan]} {
+ # Didn't block waiting for end-of-line
+ puts "$clientName - $line"
+ puts $chan $line
+ }
+}
+
+# Create the server socket and enter the event-loop to wait
+# for incoming connections...
+socket -server connect 12345
+vwait forever
+.CE
+.SH "SEE ALSO"
+gets(n), open(n), read(n), socket(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+blocking, nonblocking
diff --git a/library/msgcat/doc/fconfigure.n b/library/msgcat/doc/fconfigure.n
new file mode 100644
index 0000000..ac0366c
--- /dev/null
+++ b/library/msgcat/doc/fconfigure.n
@@ -0,0 +1,289 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH fconfigure n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+fconfigure \- Set and get options on a channel
+.SH SYNOPSIS
+.nf
+\fBfconfigure \fIchannelId\fR
+\fBfconfigure \fIchannelId\fR \fIname\fR
+\fBfconfigure \fIchannelId\fR \fIname value \fR?\fIname value ...\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBfconfigure\fR command sets and retrieves options for channels.
+.PP
+\fIChannelId\fR identifies the channel for which to set or query an
+option and must refer 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.
+.PP
+If no \fIname\fR or \fIvalue\fR arguments are supplied, the command
+returns a list containing alternating option names and values for the channel.
+If \fIname\fR is supplied but no \fIvalue\fR then the command returns
+the current value of the given option.
+If one or more pairs of \fIname\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 additional options for sockets, and
+the \fBopen\fR command for additional options for serial devices.
+.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 \fBgets\fR,
+\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
+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 \fBflush\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 between ten and one million, allowing
+buffers of ten to one million bytes in size.
+.TP
+\fB\-encoding\fR \fIname\fR
+.
+This option is used to specify the encoding of the channel, 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 \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\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.
+.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
+the translation.
+.RE
+.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
+.PP
+.SH "STANDARD CHANNELS"
+.PP
+The Tcl standard channels (\fBstdin\fR, \fBstdout\fR, and \fBstderr\fR)
+can be configured through this command like every other channel opened
+by the Tcl library. Beyond the standard options described above they
+will also support any special option according to their current type.
+If, for example, a Tcl application is started by the \fBinet\fR
+super-server common on Unix system its Tcl standard channels will be
+sockets and thus support the socket options.
+.SH EXAMPLES
+.PP
+Instruct Tcl to always send output to \fBstdout\fR immediately,
+whether or not it is to a terminal:
+.PP
+.CS
+\fBfconfigure\fR stdout -buffering none
+.CE
+.PP
+Open a socket and read lines from it without ever blocking the
+processing of other events:
+.PP
+.CS
+set s [socket some.where.com 12345]
+\fBfconfigure\fR $s -blocking 0
+fileevent $s readable "readMe $s"
+proc readMe chan {
+ if {[gets $chan line] < 0} {
+ if {[eof $chan]} {
+ close $chan
+ return
+ }
+ # Could not read a complete line this time; Tcl's
+ # internal buffering will hold the partial line for us
+ # until some more data is available over the socket.
+ } else {
+ puts stdout $line
+ }
+}
+.CE
+.PP
+Read a PPM-format image from a file:
+.PP
+.CS
+# Open the file and put it into Unix ASCII mode
+set f [open teapot.ppm]
+\fBfconfigure\fR $f \-encoding ascii \-translation lf
+
+# Get the header
+if {[gets $f] ne "P6"} {
+ error "not a raw\-bits PPM"
+}
+
+# Read lines until we have got non-comment lines
+# that supply us with three decimal values.
+set words {}
+while {[llength $words] < 3} {
+ gets $f line
+ if {[string match "#*" $line]} continue
+ 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.
+lassign $words xSize ySize depth
+
+# Now switch to binary mode to pull in the data,
+# one byte per channel (red,green,blue) per pixel.
+\fBfconfigure\fR $f \-translation binary
+set numDataBytes [expr {3 * $xSize * $ySize}]
+set data [read $f $numDataBytes]
+
+close $f
+.CE
+.SH "SEE ALSO"
+close(n), flush(n), gets(n), open(n), puts(n), read(n), socket(n),
+Tcl_StandardChannels(3)
+.SH KEYWORDS
+blocking, buffering, carriage return, end of line, flushing, linemode,
+newline, nonblocking, platform, translation, encoding, filter, byte array,
+binary
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/fcopy.n b/library/msgcat/doc/fcopy.n
new file mode 100644
index 0000000..6a4bf1a
--- /dev/null
+++ b/library/msgcat/doc/fcopy.n
@@ -0,0 +1,155 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH fcopy n 8.0 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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\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\fR
+command transfers data from \fIinchan\fR until end of file
+or \fIsize\fR bytes have been
+transferred. If no \fB\-size\fR argument is given,
+then the copy goes until end of file.
+All the data read from \fIinchan\fR is copied to \fIoutchan\fR.
+Without the \fB\-command\fR option, \fBfcopy\fR blocks until the copy is complete
+and returns the number of bytes written to \fIoutchan\fR.
+.PP
+The \fB\-command\fR argument makes \fBfcopy\fR work in the background.
+In this case it returns immediately and the \fIcallback\fR is invoked
+later when the copy completes.
+The \fIcallback\fR is called with
+one or two additional
+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\fR command takes care of that automatically.
+However, it is necessary to enter the event loop by using
+the \fBvwait\fR command or by using Tk.
+.PP
+You are not allowed to do other I/O operations with
+\fIinchan\fR or \fIoutchan\fR during a background \fBfcopy\fR.
+If either \fIinchan\fR or \fIoutchan\fR get closed
+while the copy is in progress, the current copy is stopped
+and the command callback is \fInot\fR made.
+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\fR handlers during a background
+copy so those handlers do not interfere with the copy.
+Any I/O attempted by a \fBfileevent\fR handler will get a
+.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
+for these channels.
+See the manual entry for \fBfconfigure\fR for details on the
+\fB\-translation\fR option.
+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\fR or
+as the argument to the callback for an asynchronous \fBfcopy\fR.
+.PP
+\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 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 EXAMPLES
+.PP
+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.
+.PP
+.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.
+.PP
+.CS
+proc Cleanup {in out bytes {error {}}} {
+ global total
+ set total $bytes
+ close $in
+ close $out
+ if {[string length $error] != 0} {
+ # error occurred during the copy
+ }
+}
+set in [open $file1]
+set out [socket $server $port]
+\fBfcopy\fR $in $out -command [list Cleanup $in $out]
+vwait total
+.CE
+.PP
+The third example copies in chunks and tests for end of file
+in the command callback.
+.PP
+.CS
+proc CopyMore {in out chunk bytes {error {}}} {
+ global total done
+ incr total $bytes
+ if {([string length $error] != 0) || [eof $in]} {
+ set done $total
+ close $in
+ close $out
+ } else {
+ \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
+\fBfcopy\fR $in $out -size $chunk \e
+ -command [list CopyMore $in $out $chunk]
+vwait done
+.CE
+.SH "SEE ALSO"
+eof(n), fblocked(n), fconfigure(n), file(n)
+.SH KEYWORDS
+blocking, channel, end of line, end of file, nonblocking, read, translation
diff --git a/library/msgcat/doc/file.n b/library/msgcat/doc/file.n
new file mode 100644
index 0000000..eef4647
--- /dev/null
+++ b/library/msgcat/doc/file.n
@@ -0,0 +1,543 @@
+'\"
+'\" 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 file n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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.
+\fIName\fR is the name of a file; if it starts with a tilde, then tilde
+substitution is done before executing the command (see the manual entry for
+\fBfilename\fR for details). \fIOption\fR indicates what to do with the
+file name. Any unique abbreviation for \fIoption\fR is acceptable. The
+valid options are:
+.TP
+\fBfile atime \fIname\fR ?\fBtime\fR?
+.
+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
+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
+.TP
+\fBfile attributes \fIname\fR ?\fBoption\fR?
+.TP
+\fBfile attributes \fIname\fR ?\fBoption value option value...\fR?
+.
+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
+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)
+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:
+\fBu+s,go\-rw\fR add sticky bit for user, remove read and write
+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
+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
+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
+clears the value of the system attribute of the file.
+.PP
+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
+.TP
+\fBfile channels ?\fIpattern\fR?
+.
+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.
+.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
+.
+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 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,
+or overwrite a file with a directory will all result in errors even if
+\fB\-force\fR was specified. 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.
+.TP
+\fBfile delete \fR?\fB\-force\fR? ?\fB\-\|\-\fR? ?\fIpathname\fR ... ?
+.
+Removes the file or directory specified by each \fIpathname\fR
+argument. Non-empty directories will be removed only if the
+\fB\-force\fR option is specified. When operating on symbolic links,
+the links themselves will be deleted, not the objects they point to.
+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
+.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.
+.TP
+\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
+.QW \fB.\fR .
+If \fIname\fR refers to a root directory, then the root directory is
+returned. For example,
+.RS
+.PP
+.CS
+\fBfile dirname\fR c:/
+.CE
+.PP
+returns \fBc:/\fR.
+.PP
+Note that tilde substitution will only be
+performed if it is necessary to complete the command. For example,
+.PP
+.CS
+\fBfile dirname\fR ~/src/foo.c
+.CE
+.PP
+returns \fB~/src\fR, whereas
+.PP
+.CS
+\fBfile dirname\fR ~
+.CE
+.PP
+returns \fB/home\fR (or something similar).
+.RE
+.TP
+\fBfile executable \fIname\fR
+.
+Returns \fB1\fR if file \fIname\fR is executable by the current user,
+\fB0\fR otherwise.
+.TP
+\fBfile exists \fIname\fR
+.
+Returns \fB1\fR if file \fIname\fR exists and the current user has
+search privileges for the directories leading to it, \fB0\fR otherwise.
+.TP
+\fBfile extension \fIname\fR
+.
+Returns all of the characters in \fIname\fR after and including the last
+dot in the last element of \fIname\fR. If there is no dot in the last
+element of \fIname\fR then returns the empty string.
+.TP
+\fBfile isdirectory \fIname\fR
+.
+Returns \fB1\fR if file \fIname\fR is a directory, \fB0\fR otherwise.
+.TP
+\fBfile isfile \fIname\fR
+.
+Returns \fB1\fR if file \fIname\fR is a regular file, \fB0\fR otherwise.
+.TP
+\fBfile join \fIname\fR ?\fIname ...\fR?
+.
+Takes one or more file names and combines them, using the correct path
+separator for the current platform. If a particular \fIname\fR is
+relative, then it will be joined to the previous file name argument.
+Otherwise, any earlier arguments will be discarded, and joining will
+proceed from the current argument. For example,
+.RS
+.PP
+.CS
+\fBfile join\fR a b /foo bar
+.CE
+.PP
+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.
+.RE
+.TP
+\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 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
+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
+.QW \fB\-symbolic\fR
+and
+.QW \fB\-hard\fR .
+.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
+.
+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
+do not support symbolic links this option behaves exactly the same
+as the \fBstat\fR option.
+.TP
+\fBfile mkdir ?\fIdir\fR ...?
+.
+Creates each directory specified. For each pathname \fIdir\fR specified,
+this command will create all non-existing parent directories as
+well as \fIdir\fR itself. If an existing directory is specified, then
+no action is taken and no error is returned. Trying to overwrite an existing
+file with a directory will result in an error. Arguments are processed in
+the order specified, halting at the first error, if any.
+.TP
+\fBfile mtime \fIname\fR ?\fItime\fR?
+.
+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 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 to a
+subprocess via \fBexec\fR under Windows (see \fBEXAMPLES\fR below).
+.TP
+\fBfile normalize \fIname\fR
+.
+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
+.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 \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
+.
+Returns \fB1\fR if file \fIname\fR is owned by the current user, \fB0\fR
+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.
+.TP
+\fBfile readable \fIname\fR
+.
+Returns \fB1\fR if file \fIname\fR is readable by the current user,
+\fB0\fR otherwise.
+.TP
+\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 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
+.
+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
+\fItarget\fR is an existing directory, then the second form is used.
+The second form moves each \fIsource\fR file or directory into the
+directory \fItargetDir\fR. Existing files will not be overwritten
+unless the \fB\-force\fR option is specified. When operating inside a
+single filesystem, Tcl will rename symbolic links rather than the
+things that they point to. Trying to overwrite a non-empty directory,
+overwrite a directory with a file, or a file with a directory will all
+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.
+.TP
+\fBfile rootname \fIname\fR
+.
+Returns all of the characters in \fIname\fR up to but not including the
+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?
+.
+If no argument is given, returns the character which is used to separate
+path segments for native files on this platform. If a path is given,
+the filesystem responsible for that path is asked to return its
+separator character. If no file system accepts \fIname\fR, an error
+is generated.
+.TP
+\fBfile size \fIname\fR
+.
+Returns a decimal string giving the size of file \fIname\fR in bytes. If
+the file does not exist or its size cannot be queried then an error is
+generated.
+.TP
+\fBfile split \fIname\fR
+.
+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 to ensure that an element is unambiguously relative.
+For example, under Unix
+.RS
+.PP
+.CS
+\fBfile split\fR /foo/~bar/baz
+.CE
+.PP
+returns
+.QW \fB/\0\0foo\0\0./~bar\0\0baz\fR
+to ensure that later commands
+that use the third component do not attempt to perform tilde
+substitution.
+.RE
+.TP
+\fBfile stat \fIname varName\fR
+.
+Invokes the \fBstat\fR kernel call on \fIname\fR, and uses the variable
+given by \fIvarName\fR to hold information returned from the kernel call.
+\fIVarName\fR is treated as an array variable, and the following elements
+of that variable are set: \fBatime\fR, \fBctime\fR, \fBdev\fR, \fBgid\fR,
+\fBino\fR, \fBmode\fR, \fBmtime\fR, \fBnlink\fR, \fBsize\fR, \fBtype\fR,
+\fBuid\fR. Each element except \fBtype\fR is a decimal string with the
+value of the corresponding field from the \fBstat\fR return structure;
+see the manual entry for \fBstat\fR for details on the meanings of the
+values. The \fBtype\fR element gives the type of the file in the same
+form returned by the command \fBfile type\fR. This command returns an
+empty string.
+.TP
+\fBfile system \fIname\fR
+.
+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 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 tempfile\fR ?\fInameVar\fR? ?\fItemplate\fR?
+'\" TIP #210
+.VS 8.6
+Creates a temporary file and returns a read-write channel opened on that file.
+If the \fInameVar\fR is given, it specifies a variable that the name of the
+temporary file will be written into; if absent, Tcl will attempt to arrange
+for the temporary file to be deleted once it is no longer required. If the
+\fItemplate\fR is present, it specifies parts of the template of the filename
+to use when creating it (such as the directory, base-name or extension) though
+some platforms may ignore some or all of these parts and use a built-in
+default instead.
+.RS
+.PP
+Note that temporary files are \fIonly\fR ever created on the native
+filesystem. As such, they can be relied upon to be used with operating-system
+native APIs and external programs that require a filename.
+.RE
+.VE 8.6
+.TP
+\fBfile type \fIname\fR
+.
+Returns a string giving the type of file \fIname\fR, which will be one of
+\fBfile\fR, \fBdirectory\fR, \fBcharacterSpecial\fR, \fBblockSpecial\fR,
+\fBfifo\fR, \fBlink\fR, or \fBsocket\fR.
+.TP
+\fBfile volumes\fR
+.
+Returns the absolute paths to the volumes mounted on the system, as a
+proper Tcl list. Without any virtual filesystems mounted as root
+volumes, on UNIX, the command will always return
+.QW / ,
+since all filesystems are locally mounted.
+On Windows, it will return a list of the available local drives
+(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
+.
+Returns \fB1\fR if file \fIname\fR is writable by the current user,
+\fB0\fR otherwise.
+.SH "PORTABILITY ISSUES"
+.TP
+\fBUnix\fR\0\0\0\0\0\0\0
+.
+These commands always operate using the real user and group identifiers,
+not the effective ones.
+.SH EXAMPLES
+.PP
+This procedure shows how to search for C files in a given directory
+that have a correspondingly-named object file in the current
+directory:
+.PP
+.CS
+proc findMatchingCFiles {dir} {
+ set files {}
+ switch $::tcl_platform(platform) {
+ windows {
+ set ext .obj
+ }
+ unix {
+ set ext .o
+ }
+ }
+ 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
+ }
+ }
+ return $files
+}
+.CE
+.PP
+Rename a file and leave a symbolic link pointing from the old location
+to the new place:
+.PP
+.CS
+set oldName foobar.txt
+set newName foo/bar.txt
+# Make sure that where we're going to move to exists...
+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
+.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:
+.PP
+.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, user
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/library/msgcat/doc/fileevent.n b/library/msgcat/doc/fileevent.n
new file mode 100644
index 0000000..df48d2a
--- /dev/null
+++ b/library/msgcat/doc/fileevent.n
@@ -0,0 +1,153 @@
+'\"
+'\" Copyright (c) 1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2008 Pat Thoyts
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH fileevent n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+fileevent \- Execute a script when a channel becomes readable or writable
+.SH SYNOPSIS
+\fBfileevent \fIchannelId \fBreadable \fR?\fIscript\fR?
+.sp
+\fBfileevent \fIchannelId \fBwritable \fR?\fIscript\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+This command is used to create \fIfile event handlers\fR. 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 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
+.QW "freeze up" .
+With \fBfileevent\fR, the process can
+tell when data is present and only invoke \fBgets\fR or \fBread\fR when
+they will not block.
+.PP
+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.
+.PP
+If the \fIscript\fR argument is specified, then \fBfileevent\fR
+creates a new event handler: \fIscript\fR will be evaluated
+whenever the channel becomes readable or writable (depending on the
+second argument to \fBfileevent\fR).
+In this case \fBfileevent\fR returns an empty string.
+The \fBreadable\fR and \fBwritable\fR event handlers for a file
+are independent, and may be created and deleted separately.
+However, there may be at most one \fBreadable\fR and one \fBwritable\fR
+handler for a file at a given time in a given interpreter.
+If \fBfileevent\fR is called when the specified handler already
+exists in the invoking interpreter, the new script replaces the old one.
+.PP
+If the \fIscript\fR argument is not specified, \fBfileevent\fR
+returns the current script for \fIchannelId\fR, or an empty string
+if there is none.
+If the \fIscript\fR argument is specified as an empty string
+then the event handler is deleted, so that no script will be invoked.
+A file event handler is also deleted automatically whenever
+its channel is closed or its interpreter is deleted.
+.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 \fBgets\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.
+.PP
+Event-driven I/O works best for channels that have been
+placed into nonblocking mode with the \fBfconfigure\fR command.
+In blocking mode, a \fBputs\fR command may block if you give it
+more data than the underlying file or device can accept, and a
+\fBgets\fR or \fBread\fR command will block if you attempt to read
+more data than is ready; no events will be processed while the
+commands block.
+In nonblocking mode \fBputs\fR, \fBread\fR, and \fBgets\fR never block.
+See the documentation for the individual commands for information
+on how they handle blocking and nonblocking channels.
+.PP
+Testing for the end of file condition should be done after any attempts
+read the channel data. The eof flag is set once an attempt to read the
+end of data has occurred and testing before this read will require an
+additional event to be fired.
+.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
+\fBfileevent\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.
+.SH EXAMPLE
+.PP
+In this setup \fBGetData\fR will be called with the channel as an
+argument whenever $chan becomes readable. The \fBread\fR call will
+read whatever binary data is currently available without blocking.
+Here the channel has the fileevent removed when an end of file
+occurs to avoid being continually called (see above). Alternatively
+the channel may be closed on this condition.
+.PP
+.CS
+proc GetData {chan} {
+ set data [read $chan]
+ puts "[string length $data] $data"
+ if {[eof $chan]} {
+ fileevent $chan readable {}
+ }
+}
+
+fconfigure $chan -blocking 0 -encoding binary
+\fBfileevent\fR $chan readable [list GetData $chan]
+.CE
+.PP
+The next example demonstrates use of \fBgets\fR to read line-oriented
+data.
+.PP
+.CS
+proc GetData {chan} {
+ if {[gets $chan line] >= 0} {
+ puts $line
+ }
+ if {[eof $chan]} {
+ close $chan
+ }
+}
+
+fconfigure $chan -blocking 0 -buffering line -translation crlf
+\fBfileevent\fR $chan readable [list GetData $chan]
+.CE
+.SH CREDITS
+.PP
+\fBfileevent\fR is based on the \fBaddinput\fR command created
+by Mark Diekhans.
+.SH "SEE ALSO"
+fconfigure(n), gets(n), interp(n), puts(n), read(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+asynchronous I/O, blocking, channel, event handler, nonblocking, readable,
+script, writable.
diff --git a/library/msgcat/doc/filename.n b/library/msgcat/doc/filename.n
new file mode 100644
index 0000000..d481fc9
--- /dev/null
+++ b/library/msgcat/doc/filename.n
@@ -0,0 +1,178 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH filename n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+filename \- File name conventions supported by Tcl commands
+.BE
+.SH INTRODUCTION
+.PP
+All Tcl commands and C procedures that take file names as arguments
+expect the file names to be in one of three forms, depending on the
+current platform. On each platform, Tcl supports file names in the
+standard forms(s) for that platform. In addition, on all platforms,
+Tcl supports a Unix-like syntax intended to provide a convenient way
+of constructing simple file names. However, scripts that are intended
+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
+for the path used to specify the file: absolute, relative, and
+volume-relative. Absolute names are completely qualified, giving a path to
+the file relative to a particular volume and the root directory on that
+volume. Relative names are unqualified, giving a path to the file relative
+to the current working directory. Volume-relative names are partially
+qualified, either giving the path relative to the root directory on the
+current volume, or relative to the current directory of the specified
+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
+\fBplatform\fR element of the \fBtcl_platform\fR array:
+.TP 10
+\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
+The following examples illustrate various forms of path
+names:
+.TP 15
+\fB/\fR
+Absolute path to the root directory.
+.TP 15
+\fB/etc/passwd\fR
+Absolute path to the file named \fBpasswd\fR in the directory
+\fBetc\fR in the root directory.
+.TP 15
+\fB\&.\fR
+Relative path to the current directory.
+.TP 15
+\fBfoo\fR
+Relative path to the file \fBfoo\fR in the current directory.
+.TP 15
+\fBfoo/bar\fR
+Relative path to the file \fBbar\fR in the directory \fBfoo\fR in the
+current directory.
+.TP 15
+\fB\&../foo\fR
+Relative path to the file \fBfoo\fR in the directory above the current
+directory.
+.RE
+.TP
+\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
+specifier followed by an absolute or relative path. UNC paths follow the
+general form \fB\e\eservername\esharename\epath\efile\fR, but must at
+the very least contain the server and share components, i.e.
+\fB\e\eservername\esharename\fR. In both forms,
+the file names \fB.\fR and \fB..\fR are special and refer to the current
+directory and the parent of the current directory respectively. The
+following examples illustrate various forms of path names:
+.RS
+.TP 15
+\fB\&\e\eHost\eshare/file\fR
+Absolute UNC path to a file called \fBfile\fR in the root directory of
+the export point \fBshare\fR on the host \fBHost\fR. Note that
+repeated use of \fBfile dirname\fR on this path will give
+\fB//Host/share\fR, and will never give just \fB//Host\fR.
+.TP 15
+\fBc:foo\fR
+Volume-relative path to a file \fBfoo\fR in the current directory on drive
+\fBc\fR.
+.TP 15
+\fBc:/foo\fR
+Absolute path to a file \fBfoo\fR in the root directory of drive
+\fBc\fR.
+.TP 15
+\fBfoo\ebar\fR
+Relative path to a file \fBbar\fR in the \fBfoo\fR directory in the current
+directory on the current volume.
+.TP 15
+\fB\&\efoo\fR
+Volume-relative path to a file \fBfoo\fR in the root directory of the current
+volume.
+.TP 15
+\fB\&\e\efoo\fR
+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. This works on
+Unix, MacOS X and Windows (except very old releases).
+.PP
+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.
+'\""\" 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
+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
+.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
diff --git a/library/msgcat/doc/flush.n b/library/msgcat/doc/flush.n
new file mode 100644
index 0000000..b8bf3e9
--- /dev/null
+++ b/library/msgcat/doc/flush.n
@@ -0,0 +1,45 @@
+'\"
+'\" 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 flush n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+flush \- Flush buffered output for a channel
+.SH SYNOPSIS
+\fBflush \fIchannelId\fR
+.BE
+.SH DESCRIPTION
+.PP
+Flushes any output that has been buffered for \fIchannelId\fR.
+.PP
+\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.
+.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.
+.SH EXAMPLE
+.PP
+Prompt for the user to type some information in on the console:
+.PP
+.CS
+puts -nonewline "Please type your name: "
+\fBflush\fR stdout
+gets stdin name
+puts "Hello there, $name!"
+.CE
+.SH "SEE ALSO"
+file(n), open(n), socket(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+blocking, buffer, channel, flush, nonblocking, output
diff --git a/library/msgcat/doc/for.n b/library/msgcat/doc/for.n
new file mode 100644
index 0000000..4c65793
--- /dev/null
+++ b/library/msgcat/doc/for.n
@@ -0,0 +1,87 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH for n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+for \- 'For' loop
+.SH SYNOPSIS
+\fBfor \fIstart test next body\fR
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBFor\fR is a looping command, similar in structure to the C
+\fBfor\fR statement. The \fIstart\fR, \fInext\fR, and
+\fIbody\fR arguments must be Tcl command strings, and \fItest\fR
+is an expression string.
+The \fBfor\fR command first invokes the Tcl interpreter to
+execute \fIstart\fR. Then it repeatedly evaluates \fItest\fR as
+an expression; if the result is non-zero it invokes the Tcl
+interpreter on \fIbody\fR, then invokes the Tcl interpreter on \fInext\fR,
+then repeats the loop. The command terminates when \fItest\fR evaluates
+to 0. If a \fBcontinue\fR command is invoked within \fIbody\fR then
+any remaining commands in the current execution of \fIbody\fR are skipped;
+processing continues by invoking the Tcl interpreter on \fInext\fR, then
+evaluating \fItest\fR, and so on. If a \fBbreak\fR command is invoked
+within \fIbody\fR
+or \fInext\fR,
+then the \fBfor\fR command will
+return immediately.
+The operation of \fBbreak\fR and \fBcontinue\fR are similar to the
+corresponding statements in C.
+\fBFor\fR returns an empty string.
+.PP
+Note: \fItest\fR should almost always be enclosed in braces. If not,
+variable substitutions will be made before the \fBfor\fR
+command starts executing, which means that variable changes
+made by the loop body will not be considered in the expression.
+This is likely to result in an infinite loop. If \fItest\fR is
+enclosed in braces, variable substitutions are delayed until the
+expression is evaluated (before
+each loop iteration), so changes in the variables will be visible.
+See below for an example:
+.SH EXAMPLES
+.PP
+Print a line for each of the integers from 0 to 10:
+.PP
+.CS
+\fBfor\fR {set x 0} {$x<10} {incr x} {
+ puts "x is $x"
+}
+.CE
+.PP
+Either loop infinitely or not at all because the expression being
+evaluated is actually the constant, or even generate an error! The
+actual behaviour will depend on whether the variable \fIx\fR exists
+before the \fBfor\fR command is run and whether its value is a value
+that is less than or greater than/equal to ten, and this is because
+the expression will be substituted before the \fBfor\fR command is
+executed.
+.PP
+.CS
+\fBfor\fR {set x 0} $x<10 {incr x} {
+ puts "x is $x"
+}
+.CE
+.PP
+Print out the powers of two from 1 to 1024:
+.PP
+.CS
+\fBfor\fR {set x 1} {$x<=1024} {set x [expr {$x * 2}]} {
+ puts "x is $x"
+}
+.CE
+.SH "SEE ALSO"
+break(n), continue(n), foreach(n), while(n)
+.SH KEYWORDS
+boolean, for, iteration, loop
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/foreach.n b/library/msgcat/doc/foreach.n
new file mode 100644
index 0000000..fb075d3
--- /dev/null
+++ b/library/msgcat/doc/foreach.n
@@ -0,0 +1,104 @@
+'\"
+'\" 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 foreach n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+foreach \- Iterate over all elements in one or more lists
+.SH SYNOPSIS
+\fBforeach \fIvarname list body\fR
+.br
+\fBforeach \fIvarlist1 list1\fR ?\fIvarlist2 list2 ...\fR? \fIbody\fR
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBforeach\fR command implements a loop where the loop
+variable(s) take on values from one or more lists.
+In the simplest case there is one loop variable, \fIvarname\fR,
+and one list, \fIlist\fR, that is a list of values to assign to \fIvarname\fR.
+The \fIbody\fR argument is a Tcl script.
+For each element of \fIlist\fR (in order
+from first to last), \fBforeach\fR assigns the contents of the
+element to \fIvarname\fR as if the \fBlindex\fR command had been used
+to extract the element, then calls the Tcl interpreter to execute
+\fIbody\fR.
+.PP
+In the general case there can be more than one value list
+(e.g., \fIlist1\fR and \fIlist2\fR),
+and each value list can be associated with a list of loop variables
+(e.g., \fIvarlist1\fR and \fIvarlist2\fR).
+During each iteration of the loop
+the variables of each \fIvarlist\fR are assigned
+consecutive values from the corresponding \fIlist\fR.
+Values in each \fIlist\fR are used in order from first to last,
+and each value is used exactly once.
+The total number of loop iterations is large enough to use
+up all the values from all the value lists.
+If a value list does not contain enough
+elements for each of its loop variables in each iteration,
+empty values are used for the missing elements.
+.PP
+The \fBbreak\fR and \fBcontinue\fR statements may be
+invoked inside \fIbody\fR, with the same effect as in the \fBfor\fR
+command. \fBForeach\fR returns an empty string.
+.SH EXAMPLES
+.PP
+This loop prints every value in a list together with the square and
+cube of the value:
+.PP
+.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.
+.PP
+.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.
+.CE
+.PP
+The next loop uses i and j to iterate over two lists in parallel.
+.PP
+.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.
+.CE
+.PP
+The two forms are combined in the following example.
+.PP
+.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.
+.CE
+
+.SH "SEE ALSO"
+for(n), while(n), break(n), continue(n)
+
+.SH KEYWORDS
+foreach, iteration, list, loop
diff --git a/library/msgcat/doc/format.n b/library/msgcat/doc/format.n
new file mode 100644
index 0000000..23dfe60
--- /dev/null
+++ b/library/msgcat/doc/format.n
@@ -0,0 +1,285 @@
+'\"
+'\" 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 format n 8.1 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+format \- Format a string in the style of sprintf
+.SH SYNOPSIS
+\fBformat \fIformatString \fR?\fIarg arg ...\fR?
+.BE
+
+.SH INTRODUCTION
+.PP
+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.
+The return value from \fBformat\fR is the formatted string.
+.SH "DETAILS ON FORMATTING"
+.PP
+The command operates by scanning \fIformatString\fR from left to right.
+Each character from the format string is appended to the result
+string unless it is a percent sign.
+If the character is a \fB%\fR then it is not copied to the result string.
+Instead, the characters following the \fB%\fR character are treated as
+a conversion specifier.
+The conversion specifier controls the conversion of the next successive
+\fIarg\fR to a particular format and the result is appended to
+the result string in place of the conversion specifier.
+If there are multiple conversion specifiers in the format string,
+then each one controls the conversion of one additional \fIarg\fR.
+The \fBformat\fR command must be given enough \fIarg\fRs to meet the needs
+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 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.
+.SS "OPTIONAL POSITIONAL SPECIFIER"
+.PP
+If the \fB%\fR is followed by a decimal number and a \fB$\fR, as in
+.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
+of \fB*\fR characters in the specifier then
+successive arguments are used, starting with the argument
+given by the number.
+This follows the XPG3 conventions for positional specifiers.
+If there are any positional specifiers in \fIformatString\fR
+then all of the specifiers must be positional.
+.SS "OPTIONAL FLAGS"
+.PP
+The second portion of a conversion specifier may contain any of the
+following flag characters, in any order:
+.TP 10
+\fB\-\fR
+Specifies that the converted argument should be left-justified
+in its field (numbers are normally right-justified with leading
+spaces if needed).
+.TP 10
+\fB+\fR
+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 is not a sign.
+.TP 10
+\fB0\fR
+Specifies that the number should be padded on the left with
+zeroes instead of spaces.
+.TP 10
+\fB#\fR
+Requests an alternate output form. For \fBo\fR and \fBO\fR
+conversions it guarantees that the first digit is always \fB0\fR.
+For \fBx\fR or \fBX\fR conversions, \fB0x\fR or \fB0X\fR (respectively)
+will be added to the beginning of the result unless it is zero.
+For \fBb\fR conversions, \fB0b\fR
+will be added to the beginning of the result unless it is zero.
+For all floating-point conversions (\fBe\fR, \fBE\fR, \fBf\fR,
+\fBg\fR, and \fBG\fR) it guarantees that the result always
+has a decimal point.
+For \fBg\fR and \fBG\fR conversions it specifies that
+trailing zeroes should not be removed.
+.SS "OPTIONAL FIELD WIDTH"
+.PP
+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
+minimum field width then it will be padded so that it is as wide
+as the minimum field width.
+Padding normally occurs by adding extra spaces on the left of the
+converted argument, but the \fB0\fR and \fB\-\fR flags
+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 an integer value.
+.SS "OPTIONAL PRECISION/BOUND"
+.PP
+The fourth portion of a conversion specifier is a precision,
+which consists of a period followed by a number.
+The number is used in different ways for different conversions.
+For \fBe\fR, \fBE\fR, and \fBf\fR conversions it specifies the number
+of digits to appear to the right of the decimal point.
+For \fBg\fR and \fBG\fR conversions it specifies the total number
+of digits to appear, including those on both sides of the decimal
+point (however, trailing zeroes after the decimal point will still
+be omitted unless the \fB#\fR flag has been specified).
+For integer conversions, it specifies a minimum number of digits
+to print (leading zeroes will be added if necessary).
+For \fBs\fR conversions it specifies the maximum number of characters to be
+printed; if the string is longer than this then the trailing characters will be dropped.
+If the precision is specified with \fB*\fR rather than a number
+then the next argument to the \fBformat\fR command determines the precision;
+it must be a numeric string.
+.SS "OPTIONAL SIZE MODIFIER"
+.PP
+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 the \fBwordSize\fR element of the
+\fBtcl_platform\fR array).
+.SS "MANDATORY CONVERSION TYPE"
+.PP
+The last thing in a conversion specifier is an alphabetic character
+that determines what kind of conversion to perform.
+The following conversion characters are currently supported:
+.TP 10
+\fBd\fR
+Convert integer to signed decimal string.
+.TP 10
+\fBu\fR
+Convert integer to unsigned decimal string.
+.TP 10
+\fBi\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
+.QW 0123456789abcdef
+for \fBx\fR and
+.QW 0123456789ABCDEF
+for \fBX\fR).
+.TP 10
+\fBb\fR
+Convert integer to binary string, using digits 0 and 1.
+.TP 10
+\fBc\fR
+Convert integer to the Unicode character it represents.
+.TP 10
+\fBs\fR
+No conversion; just insert string.
+.TP 10
+\fBf\fR
+Convert number to signed decimal string of
+the form \fIxx.yyy\fR, where the number of \fIy\fR's is determined by
+the precision (default: 6).
+If the precision is 0 then no decimal point is output.
+.TP 10
+\fBe\fR or \fBE\fR
+Convert number to scientific notation in the
+form \fIx.yyy\fBe\(+-\fIzz\fR, where the number of \fIy\fR's is determined
+by the precision (default: 6).
+If the precision is 0 then no decimal point is output.
+If the \fBE\fR form is used then \fBE\fR is
+printed instead of \fBe\fR.
+.TP 10
+\fBg\fR or \fBG\fR
+If the exponent is less than \-4 or greater than or equal to the
+precision, then convert number as for \fB%e\fR or
+\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.
+.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]
+Tcl guarantees that it will be working with UNICODE characters.
+.IP [2]
+\fB%p\fR and \fB%n\fR specifiers are not supported.
+.IP [3]
+For \fB%c\fR conversions the argument must be an integer value,
+which will then be converted to the corresponding character value.
+.IP [4]
+The size modifiers are ignored when formatting floating-point values.
+The \fBll\fR modifier has no \fBsprintf\fR counterpart.
+The \fBb\fR specifier has no \fBsprintf\fR counterpart.
+.SH EXAMPLES
+.PP
+Convert the numeric value of a UNICODE character to the character
+itself:
+.PP
+.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:
+.PP
+.CS
+set us [lindex [time $someTclCode] 0]
+puts [\fBformat\fR "%.2f seconds to execute" [expr {$us / 1e6}]]
+.CE
+.PP
+Create a packed X11 literal color specification:
+.PP
+.CS
+# Each color-component should be in range (0..255)
+set color [\fBformat\fR "#%02x%02x%02x" $r $g $b]
+.CE
+.PP
+Use XPG3 format codes to allow reordering of fields (a technique that
+is often used in localized message catalogs; see \fBmsgcat\fR) without
+reordering the data values passed to \fBformat\fR:
+.PP
+.CS
+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\e$s equity ($%3$.2f x %1\e$d) today"
+puts [\fBformat\fR $fmt2 123 "Global BigCorp" 19.37]
+.CE
+.PP
+Print a small table of powers of three:
+.PP
+.CS
+# Set up the column widths
+set w1 5
+set w2 10
+
+# Make a nice header (with separator) for the table first
+set sep +-[string repeat - $w1]-+-[string repeat - $w2]-+
+puts $sep
+puts [\fBformat\fR "| %-*s | %-*s |" $w1 "Index" $w2 "Power"]
+puts $sep
+
+# Print the contents of the table
+set p 1
+for {set i 0} {$i<=20} {incr i} {
+ puts [\fBformat\fR "| %*d | %*ld |" $w1 $i $w2 $p]
+ set p [expr {wide($p) * 3}]
+}
+
+# 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
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/gets.n b/library/msgcat/doc/gets.n
new file mode 100644
index 0000000..fe24058
--- /dev/null
+++ b/library/msgcat/doc/gets.n
@@ -0,0 +1,71 @@
+'\"
+'\" 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 gets n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+gets \- Read a line from a channel
+.SH SYNOPSIS
+\fBgets \fIchannelId\fR ?\fIvarName\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+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
+\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.
+.PP
+If \fIvarName\fR is omitted the line is returned as the result of the
+command.
+If \fIvarName\fR is specified then the line is placed in the variable by
+that name and the return value is a count of the number of characters
+returned.
+.PP
+If end of file occurs while scanning for an end of
+line, the command returns whatever input is available up to the end of file.
+If \fIchannelId\fR is in non-blocking mode and there is not a full
+line of input available, the command returns an empty string and
+does not consume any input.
+If \fIvarName\fR is specified and an empty string is returned in
+\fIvarName\fR because of end-of-file or because of insufficient
+data in non-blocking mode, then the return count is -1.
+Note that if \fIvarName\fR is not specified then the end-of-file
+and no-full-line-available cases can
+produce the same results as if there were an input line consisting
+only of the end-of-line character(s).
+The \fBeof\fR and \fBfblocked\fR commands can be used to distinguish
+these three cases.
+.SH "EXAMPLE"
+This example reads a file one line at a time and prints it out with
+the current line number attached to the start of each line.
+.PP
+.CS
+set chan [open "some.file.txt"]
+set lineNumber 0
+while {[\fBgets\fR $chan line] >= 0} {
+ puts "[incr lineNumber]: $line"
+}
+close $chan
+.CE
+
+.SH "SEE ALSO"
+file(n), eof(n), fblocked(n), Tcl_StandardChannels(3)
+
+.SH KEYWORDS
+blocking, channel, end of file, end of line, line, non-blocking, read
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/library/msgcat/doc/glob.n b/library/msgcat/doc/glob.n
new file mode 100644
index 0000000..7b71189
--- /dev/null
+++ b/library/msgcat/doc/glob.n
@@ -0,0 +1,273 @@
+'\"
+'\" 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 glob n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+glob \- Return names of files that match patterns
+.SH SYNOPSIS
+\fBglob \fR?\fIswitches\fR? ?\fIpattern ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command performs file name
+.QW globbing
+in a fashion similar to
+the csh shell or bash shell.
+It returns a list of the files whose names match any
+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.
+.SS OPTIONS
+.PP
+If the initial arguments to \fBglob\fR start with \fB\-\fR then
+they are treated as switches. The following switches are
+currently supported:
+.TP
+\fB\-directory\fR \fIdirectory\fR
+.
+Search for files which match the given patterns starting in the given
+\fIdirectory\fR. This allows searching of directories whose name
+contains glob-sensitive characters without the need to quote such
+characters explicitly. This option may not be used in conjunction with
+\fB\-path\fR, which is used to allow searching for complete file paths
+whose names may contain glob-sensitive characters.
+.TP
+\fB\-join\fR
+.
+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.
+.TP
+\fB\-path\fR \fIpathPrefix\fR
+.
+Search for files with the given \fIpathPrefix\fR where the rest of the name
+matches the given patterns. This allows searching for files with names
+similar to a given file (as opposed to a directory) even when the names
+contain glob-sensitive
+characters. This option may not be used in conjunction with
+\fB\-directory\fR. For example, to find all files with the same root name
+as $path, but differing extensions, you should use
+.QW "\fBglob \-path [file rootname $path] .*\fR"
+which will work even if \fB$path\fR contains
+numerous glob-sensitive characters.
+.TP
+\fB\-tails\fR
+.
+Only return the part of each file found which follows the last directory
+named in any \fB\-directory\fR or \fB\-path\fR path specification.
+Thus
+.QW "\fBglob \-tails \-directory $dir *\fR"
+is equivalent to
+.QW "\fBset pwd [pwd]; cd $dir; glob *; cd $pwd\fR" .
+For \fB\-path\fR specifications, the returned names will include the last
+path segment, so
+.QW "\fBglob \-tails \-path [file rootname ~/foo.tex] .*\fR"
+will return paths like \fBfoo.aux foo.bib foo.tex\fR etc.
+.TP
+\fB\-types\fR \fItypeList\fR
+.
+Only list files or directories which match \fItypeList\fR, where the items
+in the list have two forms. The first form is like the \-type option of
+the Unix find command:
+\fIb\fR (block special file),
+\fIc\fR (character special file),
+\fId\fR (directory),
+\fIf\fR (plain file),
+\fIl\fR (symbolic link),
+\fIp\fR (named pipe),
+or \fIs\fR (socket), where multiple types may be specified in the list.
+\fBGlob\fR will return all files which match at least one of the types given.
+Note that symbolic links will be returned both if \fB\-types l\fR is given,
+or if the target of a link matches the requested type. So, a link to
+a directory will be returned if \fB\-types d\fR was specified.
+.RS
+.PP
+The second form specifies types where all the types given must match.
+These are \fIr\fR, \fIw\fR, \fIx\fR as file permissions, and
+\fIreadonly\fR, \fIhidden\fR as special permission cases. On the
+Macintosh, MacOS types and creators are also supported, where any item
+which is four characters long is assumed to be a MacOS type
+(e.g. \fBTEXT\fR). Items which are of the form \fI{macintosh type XXXX}\fR
+or \fI{macintosh creator XXXX}\fR will match types or creators
+respectively. Unrecognized types, or specifications of multiple MacOS
+types/creators will signal an error.
+.PP
+The two forms may be mixed, so \fB\-types {d f r w}\fR will find all
+regular files OR directories that have both read AND write permissions.
+The following are equivalent:
+.PP
+.CS
+\fBglob \-type d *\fR
+\fBglob */\fR
+.CE
+.PP
+except that the first case doesn't return the trailing
+.QW /
+and is more platform independent.
+.RE
+.TP
+\fB\-\|\-\fR
+.
+Marks the end of switches. The argument following this one will
+be treated as a \fIpattern\fR even if it starts with a \fB\-\fR.
+.SS "GLOBBING PATTERNS"
+.PP
+The \fIpattern\fR arguments may contain any of the following
+special characters, which are a superset of those supported by
+\fBstring match\fR:
+.TP 10
+\fB?\fR
+.
+Matches any single character.
+.TP 10
+\fB*\fR
+.
+Matches any sequence of zero or more characters.
+.TP 10
+\fB[\fIchars\fB]\fR
+.
+Matches any single character in \fIchars\fR. If \fIchars\fR
+contains a sequence of the form \fIa\fB\-\fIb\fR then any
+character between \fIa\fR and \fIb\fR (inclusive) will match.
+.TP 10
+\fB\e\fIx\fR
+.
+Matches the character \fIx\fR.
+.TP 10
+\fB{\fIa\fB,\fIb\fB,\fI...\fR}
+.
+Matches any of the sub-patterns \fIa\fR, \fIb\fR, etc.
+.PP
+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
+.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.
+.PP
+The \fBglob\fR command differs from csh globbing in two ways.
+First, it does not sort its result list (use the \fBlsort\fR
+command if you want the list sorted).
+Second, \fBglob\fR only returns the names of files that actually
+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
+.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 "WINDOWS PORTABILITY ISSUES"
+.PP
+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
+.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 accepted patterns
+like
+.QW .../
+and
+.QW ..../
+for successively higher up parent directories, but later versions of
+Windows do not accept these forms.
+.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
+.QW \fIC:\e\efoo\e\e*\fR
+is interpreted as
+.QW \fIC:\efoo\e*\fR
+where
+.QW \fI\ef\fR
+will match the single character
+.QW \fIf\fR
+and
+.QW \fI\e*\fR
+will match the single character
+.QW \fI*\fR
+and will not be
+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
+.QW "\fBfile join\fR \fB$path\fR"
+or
+.QW "\fBfile normalize\fR \fB$path\fR" .
+.SH EXAMPLES
+.PP
+Find all the Tcl files in the current directory:
+.PP
+.CS
+\fBglob\fR *.tcl
+.CE
+.PP
+Find all the Tcl files in the user's home directory, irrespective of
+what the current directory is:
+.PP
+.CS
+\fBglob\fR \-directory ~ *.tcl
+.CE
+.PP
+Find all subdirectories of the current directory:
+.PP
+.CS
+\fBglob\fR \-type d *
+.CE
+.PP
+Find all files whose name contains an
+.QW a ,
+a
+.QW b
+or the sequence
+.QW cde :
+.PP
+.CS
+\fBglob\fR \-type f *{a,b,cde}*
+.CE
+.SH "SEE ALSO"
+file(n)
+.SH KEYWORDS
+exist, file, glob, pattern
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/global.n b/library/msgcat/doc/global.n
new file mode 100644
index 0000000..c17c370
--- /dev/null
+++ b/library/msgcat/doc/global.n
@@ -0,0 +1,58 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH global n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+global \- Access global variables
+.SH SYNOPSIS
+\fBglobal \fR?\fIvarname ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command has no effect unless executed in the context of a proc body.
+If the \fBglobal\fR command is executed in the context of a proc body, it
+creates local variables linked to the corresponding global variables (though
+these linked variables, like those created by \fBupvar\fR, are not included
+in the list returned by \fBinfo locals\fR).
+.PP
+If \fIvarname\fR contains namespace qualifiers, the local variable's name is
+the unqualified name of the global variable, as determined by the
+\fBnamespace tail\fR command.
+.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
+.PP
+This procedure sets the namespace variable \fI::a::x\fR
+.PP
+.CS
+proc reset {} {
+ \fBglobal\fR a::x
+ set x 0
+}
+.CE
+.PP
+This procedure accumulates the strings passed to it in a global
+buffer, separated by newlines. It is useful for situations when you
+want to build a message piece-by-piece (as if with \fBputs\fR) but
+send that full message in a single piece (e.g. over a connection
+opened with \fBsocket\fR or as part of a counted HTTP response).
+.PP
+.CS
+proc accum {string} {
+ \fBglobal\fR accumulator
+ append accumulator $string \en
+}
+.CE
+.SH "SEE ALSO"
+namespace(n), upvar(n), variable(n)
+.SH KEYWORDS
+global, namespace, procedure, variable
diff --git a/library/msgcat/doc/history.n b/library/msgcat/doc/history.n
new file mode 100644
index 0000000..ba507b4
--- /dev/null
+++ b/library/msgcat/doc/history.n
@@ -0,0 +1,102 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH history n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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
+.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\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
+the same as the first characters of the event, or if the string
+matches the event in the sense of the \fBstring match\fR command.
+.PP
+The \fBhistory\fR command can take any of the following forms:
+.TP
+\fBhistory\fR
+Same
+as \fBhistory info\fR, described below.
+.TP
+\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 is not specified
+then an empty string is returned as result.
+.TP
+\fBhistory change\fI newValue\fR ?\fIevent\fR?
+Replaces the value recorded for an event with \fInewValue\fR. \fIEvent\fR
+specifies the event to replace, and
+defaults to the \fIcurrent\fR event (not event \fB\-1\fR). This command
+is intended for use in commands that implement new forms of history
+substitution and wish to replace the current event (which invokes the
+substitution) with the command created through substitution. The return
+value is an empty string.
+.TP
+\fBhistory clear\fR
+Erase the history list. The current keep limit is retained.
+The history event numbers are reset.
+.TP
+\fBhistory event\fR ?\fIevent\fR?
+Returns the value of the event given by \fIevent\fR. \fIEvent\fR
+defaults to \fB\-1\fR.
+.TP
+\fBhistory info \fR?\fIcount\fR?
+Returns a formatted string (intended for humans to read) giving
+the event number and contents for each of the events in the history
+list except the current event. If \fIcount\fR is specified
+then only the most recent \fIcount\fR events are returned.
+.TP
+\fBhistory keep \fR?\fIcount\fR?
+This command may be used to change the size of the history list to
+\fIcount\fR events. Initially, 20 events are retained in the history
+list. If \fIcount\fR is not specified, the current keep limit is returned.
+.TP
+\fBhistory nextid\fR
+Returns the number of the next event to be recorded
+in the history list. It is useful for things like printing the
+event number in command-line prompts.
+.TP
+\fBhistory redo \fR?\fIevent\fR?
+Re-executes the command indicated by \fIevent\fR and returns its result.
+\fIEvent\fR defaults to \fB\-1\fR. This command results in history
+revision: see below for details.
+.SH "HISTORY REVISION"
+.PP
+Pre-8.0 Tcl had a complex history revision mechanism.
+The current mechanism is more limited, and the old
+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
+.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\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/library/msgcat/doc/http.n b/library/msgcat/doc/http.n
new file mode 100644
index 0000000..631a141
--- /dev/null
+++ b/library/msgcat/doc/http.n
@@ -0,0 +1,646 @@
+'\"
+'\" Copyright (c) 1995-1997 Sun Microsystems, Inc.
+'\" Copyright (c) 1998-2000 by Ajuba Solutions.
+'\" Copyright (c) 2004 ActiveState Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH "http" n 2.7 http "Tcl Bundled Packages"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+http \- Client-side implementation of the HTTP/1.1 protocol
+.SH SYNOPSIS
+\fBpackage require http ?2.7?\fR
+.\" See Also -useragent option documentation in body!
+.sp
+\fB::http::config ?\fI\-option value\fR ...?
+.sp
+\fB::http::geturl \fIurl\fR ?\fI\-option value\fR ...?
+.sp
+\fB::http::formatQuery\fR \fIkey value\fR ?\fIkey value\fR ...?
+.sp
+\fB::http::reset\fR \fItoken\fR ?\fIwhy\fR?
+.sp
+\fB::http::wait \fItoken\fR
+.sp
+\fB::http::status \fItoken\fR
+.sp
+\fB::http::size \fItoken\fR
+.sp
+\fB::http::code \fItoken\fR
+.sp
+\fB::http::ncode \fItoken\fR
+.sp
+\fB::http::meta \fItoken\fR
+.sp
+\fB::http::data \fItoken\fR
+.sp
+\fB::http::error \fItoken\fR
+.sp
+\fB::http::cleanup \fItoken\fR
+.sp
+\fB::http::register \fIproto port command\fR
+.sp
+\fB::http::unregister \fIproto\fR
+.BE
+.SH DESCRIPTION
+.PP
+The \fBhttp\fR package provides the client side of the HTTP/1.1
+protocol, 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
+additional HTTP transport protocols, such as HTTPS, by providing
+a custom \fBsocket\fR command, via \fB::http::register\fR.
+.PP
+The \fB::http::geturl\fR procedure does a HTTP transaction.
+Its \fIoptions \fR determine whether a GET, POST, or HEAD transaction
+is performed.
+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 \fBSTATE ARRAY\fR section.
+.PP
+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
+when the transaction completes. For this to work, the Tcl event loop
+must be active. In Tk applications this is always true. For pure-Tcl
+applications, the caller can use \fB::http::wait\fR after calling
+\fB::http::geturl\fR to start the event loop.
+.SH COMMANDS
+.TP
+\fB::http::config\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
+is returned. If a single argument is specified, then it should be one
+of the flags described below. In this case the current value of
+that setting is returned. Otherwise, the options should be a set of
+flags and values that define the configuration:
+.RS
+.TP
+\fB\-accept\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,
+.QW "image/gif, image/jpeg, text/*" .
+.TP
+\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\fR \fInumber\fR
+.
+The proxy port number.
+.TP
+\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
+host name, is added to \fIcommand\fR when it is invoked. If a proxy
+is required, the callback should return a two-element list containing
+the proxy server and proxy port. Otherwise the filter should return
+an empty list. The default filter returns the values of the
+\fB\-proxyhost\fR and \fB\-proxyport\fR settings if they are
+non-empty.
+.TP
+\fB\-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
+returned by specifying the empty string (\fB{}\fR), although
+\fIiso8859-1\fR is recommended to restore similar behavior but without the
+\fB::http::formatQuery\fR throwing an error processing non-latin-1
+characters.
+.TP
+\fB\-useragent\fR \fIstring\fR
+.
+The value of the User-Agent header in the HTTP request. The default is
+.QW "\fBTcl http client package 2.7\fR" .
+.RE
+.TP
+\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 \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\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\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\fR \fIname\fR
+.
+Copy the URL contents to channel \fIname\fR instead of saving it in
+\fBstate(body)\fR.
+.TP
+\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 \fBSTATE ARRAY\fR section. Here is a template for the
+callback:
+.RS
+.PP
+.CS
+proc httpCallback {token} {
+ upvar #0 $token state
+ # Access state as a Tcl array
+}
+.CE
+.RE
+.TP
+\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 \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
+.PP
+.CS
+proc httpHandlerCallback {socket token} {
+ upvar #0 $token state
+ # Access socket, and state as a Tcl array
+ # For example...
+ ...
+ set data [read $socket 1000]
+ set nbytes [string length $data]
+ ...
+ return $nbytes
+}
+.CE
+.RE
+.TP
+\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
+header field names. Newlines are stripped from the values so the
+header cannot be corrupted. For example, if \fIkeyvaluelist\fR is
+\fBPragma no-cache\fR then the following header is included in the
+HTTP request:
+.RS
+.PP
+.CS
+Pragma: no-cache
+.CE
+.RE
+.TP
+\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
+\fBContent-Length\fR meta-data, and the current number of bytes
+transferred so far. The expected total size may be unknown, in which
+case zero is passed to the callback. Here is a template for the
+progress callback:
+.RS
+.PP
+.CS
+proc httpProgress {token total current} {
+ upvar #0 $token state
+}
+.CE
+.RE
+.TP
+\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\fR \fIsize\fR
+.
+The block size used when posting query data to the URL.
+At most
+\fIsize\fR
+bytes are written at once. After each block, a call to the
+\fB\-queryprogress\fR
+callback is made (if that option is specified).
+.TP
+\fB\-querychannel\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\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\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\-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\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\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\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
+\fBSTATE ARRAY\fR section for details.
+.RE
+.TP
+\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\fR \fItoken\fR ?\fIwhy\fR?
+.
+This command resets the HTTP transaction identified by \fItoken\fR, if 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\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 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\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\fR \fItoken\fR
+.
+This is a convenience procedure that returns the \fBerror\fR element
+of the state array.
+.TP
+\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\fR \fItoken\fR
+.
+This is a convenience procedure that returns the \fBhttp\fR element of the
+state array.
+.TP
+\fB::http::ncode\fR \fItoken\fR
+.
+This is a convenience procedure that returns just the numeric return
+code (200, 404, etc.) from the \fBhttp\fR element of the state array.
+.TP
+\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\fR call.
+.TP
+\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\fR \fItoken\fR
+.
+This procedure cleans up the state associated with the connection
+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\fR enough times, the memory leak could cause a
+performance hit...or worse.
+.TP
+\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.:
+.RS
+.PP
+.CS
+package require http
+package require tls
+
+::http::register https 443 ::tls::socket
+
+set token [::http::geturl https://my.secure.site/]
+.CE
+.RE
+.TP
+\fB::http::unregister\fR \fIproto\fR
+.
+This procedure unregisters a protocol handler that was previously
+registered via \fB::http::register\fR.
+.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,
+or a URL at a bad port on an existing host.
+These errors mean that it
+cannot even start the network transaction.
+It will also raise an error if it gets an I/O error while
+writing out the HTTP request header.
+For synchronous \fB::http::geturl\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\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\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\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\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\fR and then check status and error, just as the
+callback does.
+.PP
+In any case, you must still call
+\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\fR.
+These are described below.
+.TP
+\fBok\fR
+.
+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
+\fBeof\fR
+.
+If the server closes the socket without replying, then no error
+is raised, but the status of the transaction will be \fBeof\fR.
+.TP
+\fBerror\fR
+.
+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\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\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\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.
+Use this construct to create an easy-to-use array variable:
+.PP
+.CS
+upvar #0 $token state
+.CE
+.PP
+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\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\fR command.
+.TP
+\fBcharset\fR
+.
+The value of the charset attribute from the \fBContent-Type\fR meta-data
+value. If none was specified, this defaults to the RFC standard
+\fBiso8859-1\fR, or the value of \fB$::http::defaultCharset\fR. Incoming
+text data will be automatically converted from this charset to utf-8.
+.TP
+\fBcoding\fR
+.
+A copy of the \fBContent-Encoding\fR meta-data value.
+.TP
+\fBcurrentsize\fR
+.
+The current number of bytes fetched from the URL.
+This value is returned by the \fB::http::size\fR command.
+.TP
+\fBerror\fR
+.
+If defined, this is the error string seen when the HTTP transaction
+was aborted.
+.TP
+\fBhttp\fR
+.
+The HTTP status reply from the server. This value
+is returned by the \fB::http::code\fR command. The format of this value is:
+.RS
+.PP
+.CS
+\fIHTTP/1.1 code string\fR
+.CE
+.PP
+The \fIcode\fR is a three-digit number defined in the HTTP standard.
+A code of 200 is OK. Codes beginning with 4 or 5 indicate errors.
+Codes beginning with 3 are redirection errors. In this case the
+\fBLocation\fR meta-data specifies a new URL that contains the
+requested information.
+.RE
+.TP
+\fBmeta\fR
+.
+The HTTP protocol returns meta-data that describes the URL contents.
+The \fBmeta\fR element of the state array is a list of the keys and
+values of the meta-data. This is in a format useful for initializing
+an array that just contains the meta-data:
+.RS
+.PP
+.CS
+array set meta $state(meta)
+.CE
+.PP
+Some of the meta-data keys are listed below, but the HTTP standard defines
+more, and servers are free to add their own.
+.TP
+\fBContent-Type\fR
+.
+The type of the URL contents. Examples include \fBtext/html\fR,
+\fBimage/gif,\fR \fBapplication/postscript\fR and
+\fBapplication/x-tcl\fR.
+.TP
+\fBContent-Length\fR
+.
+The advertised size of the contents. The actual size obtained by
+\fB::http::geturl\fR is available as \fBstate(currentsize)\fR.
+.TP
+\fBLocation\fR
+.
+An alternate URL that contains the requested data.
+.RE
+.TP
+\fBposterror\fR
+.
+The error, if any, that occurred while writing
+the post query data to the server.
+.TP
+\fBstatus\fR
+.
+Either \fBok\fR, for successful completion, \fBreset\fR for
+user-reset, \fBtimeout\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
+\fBtotalsize\fR
+.
+A copy of the \fBContent-Length\fR meta-data value.
+.TP
+\fBtype\fR
+.
+A copy of the \fBContent-Type\fR meta-data value.
+.TP
+\fBurl\fR
+.
+The requested URL.
+.RE
+.SH EXAMPLE
+.PP
+This example creates a procedure to copy a URL to a file while printing a
+progress meter, and prints the meta-data associated with the URL.
+.PP
+.CS
+proc httpcopy { url file {chunk 4096} } {
+ set out [open $file w]
+ set token [\fB::http::geturl\fR $url -channel $out \e
+ -progress httpCopyProgress -blocksize $chunk]
+ close $out
+
+ # This ends the line started by httpCopyProgress
+ puts stderr ""
+
+ upvar #0 $token state
+ set max 0
+ foreach {name value} $state(meta) {
+ if {[string length $name] > $max} {
+ set max [string length $name]
+ }
+ if {[regexp -nocase ^location$ $name]} {
+ # Handle URL redirects
+ puts stderr "Location:$value"
+ return [httpcopy [string trim $value] $file $chunk]
+ }
+ }
+ incr max
+ foreach {name value} $state(meta) {
+ puts [format "%-*s %s" $max $name: $value]
+ }
+
+ return $token
+}
+proc httpCopyProgress {args} {
+ puts -nonewline stderr .
+ flush stderr
+}
+.CE
+.SH "SEE ALSO"
+safe(n), socket(n), safesock(n)
+.SH KEYWORDS
+internet, security policy, socket, www
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/if.n b/library/msgcat/doc/if.n
new file mode 100644
index 0000000..700f325
--- /dev/null
+++ b/library/msgcat/doc/if.n
@@ -0,0 +1,88 @@
+'\"
+'\" 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 if n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+if \- Execute scripts conditionally
+.SH SYNOPSIS
+\fBif \fIexpr1 \fR?\fBthen\fR? \fIbody1 \fBelseif \fIexpr2 \fR?\fBthen\fR? \fIbody2\fR \fBelseif\fR ... ?\fBelse\fR? ?\fIbodyN\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fIif\fR command evaluates \fIexpr1\fR as an expression (in the
+same way that \fBexpr\fR evaluates its argument). The value of the
+expression must be a boolean
+(a numeric value, where 0 is false and
+anything is true, or a string value such as \fBtrue\fR or \fByes\fR
+for true and \fBfalse\fR or \fBno\fR for false);
+if it is true then \fIbody1\fR is executed by passing it to the
+Tcl interpreter.
+Otherwise \fIexpr2\fR is evaluated as an expression and if it is true
+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
+.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
+that was executed, or an empty string
+if none of the expressions was non-zero and there was no \fIbodyN\fR.
+.SH EXAMPLES
+.PP
+A simple conditional:
+.PP
+.CS
+\fBif\fR {$vbl == 1} { puts "vbl is one" }
+.CE
+.PP
+With an \fBelse\fR-clause:
+.PP
+.CS
+\fBif\fR {$vbl == 1} {
+ puts "vbl is one"
+} \fBelse\fR {
+ puts "vbl is not one"
+}
+.CE
+.PP
+With an \fBelseif\fR-clause too:
+.PP
+.CS
+\fBif\fR {$vbl == 1} {
+ puts "vbl is one"
+} \fBelseif\fR {$vbl == 2} {
+ puts "vbl is two"
+} \fBelse\fR {
+ puts "vbl is not one or two"
+}
+.CE
+.PP
+Remember, expressions can be multi-line, but in that case it can be a
+good idea to use the optional \fBthen\fR keyword for clarity:
+.PP
+.CS
+\fBif\fR {
+ $vbl == 1
+ || $vbl == 2
+ || $vbl == 3
+} \fBthen\fR {
+ puts "vbl is one, two or three"
+}
+.CE
+.SH "SEE ALSO"
+expr(n), for(n), foreach(n)
+.SH KEYWORDS
+boolean, conditional, else, false, if, true
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/incr.n b/library/msgcat/doc/incr.n
new file mode 100644
index 0000000..595cc27
--- /dev/null
+++ b/library/msgcat/doc/incr.n
@@ -0,0 +1,61 @@
+'\"
+'\" 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 incr n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+incr \- Increment the value of a variable
+.SH SYNOPSIS
+\fBincr \fIvarName \fR?\fIincrement\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Increments the value stored in the variable whose name is \fIvarName\fR.
+The value of the variable must be an integer.
+If \fIincrement\fR is supplied then its value (which must be an
+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
+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.
+.SH EXAMPLES
+.PP
+Add one to the contents of the variable \fIx\fR:
+.PP
+.CS
+\fBincr\fR x
+.CE
+.PP
+Add 42 to the contents of the variable \fIx\fR:
+.PP
+.CS
+\fBincr\fR x 42
+.CE
+.PP
+Add the contents of the variable \fIy\fR to the contents of the
+variable \fIx\fR:
+.PP
+.CS
+\fBincr\fR x $y
+.CE
+.PP
+Add nothing at all to the variable \fIx\fR (often useful for checking
+whether an argument to a procedure is actually integral and generating
+an error if it is not):
+.PP
+.CS
+\fBincr\fR x 0
+.CE
+.SH "SEE ALSO"
+expr(n), set(n)
+.SH KEYWORDS
+add, increment, variable, value
diff --git a/library/msgcat/doc/info.n b/library/msgcat/doc/info.n
new file mode 100644
index 0000000..e65a083
--- /dev/null
+++ b/library/msgcat/doc/info.n
@@ -0,0 +1,777 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\" Copyright (c) 1993-1997 Bell Labs Innovations for Lucent Technologies
+'\" Copyright (c) 1998-2000 Ajuba Solutions
+'\" Copyright (c) 2007-2012 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH info n 8.4 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+info \- Return information about the state of the Tcl interpreter
+.SH SYNOPSIS
+\fBinfo \fIoption \fR?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command provides information about various internals of the Tcl
+interpreter.
+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
+\fIprocname\fR, in order. \fIProcname\fR must be the name of a
+Tcl command procedure.
+.TP
+\fBinfo body \fIprocname\fR
+.
+Returns the body of procedure \fIprocname\fR. \fIProcname\fR must be
+the name of a Tcl command procedure.
+.TP
+\fBinfo class\fI subcommand class\fR ?\fIarg ...\fR
+.VS 8.6
+Returns information about the class, \fIclass\fR. The \fIsubcommand\fRs are
+described in \fBCLASS INTROSPECTION\fR below.
+.VE 8.6
+.TP
+\fBinfo cmdcount\fR
+.
+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 is not specified,
+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,
+only those names matching \fIpattern\fR are returned.
+Matching is determined using the same rules as for \fBstring match\fR.
+\fIpattern\fR can be a qualified name like \fBFoo::print*\fR.
+That is, it may specify a particular namespace
+using a sequence of namespace names separated by double colons (\fB::\fR),
+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, 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.
+.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 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 is not complete, the script can delay evaluating it until additional
+lines have been typed to complete the command.
+.TP
+\fBinfo coroutine\fR
+.VS 8.6
+Returns the name of the currently executing \fBcoroutine\fR, or the empty
+string if either no coroutine is currently executing, or the current coroutine
+has been deleted (but has not yet returned or yielded since deletion).
+.VE 8.6
+.TP
+\fBinfo default \fIprocname arg varname\fR
+.
+\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
+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
+\fBinfo errorstack \fR?\fIinterp\fR?
+.VS 8.6
+Returns, in a form that is programmatically easy to parse, the function names
+and arguments at each level from the call stack of the last error in the given
+\fIinterp\fR, or in the current one if not specified.
+.RS
+.PP
+This form is an even-sized list alternating tokens and parameters. Tokens are
+currently either \fBCALL\fR, \fBUP\fR, or \fBINNER\fR, but other values may be
+introduced in the future. \fBCALL\fR indicates a procedure call, and its
+parameter is the corresponding \fBinfo level\fR \fB0\fR. \fBUP\fR indicates a
+shift in variable frames generated by \fBuplevel\fR or similar, and applies to
+the previous \fBCALL\fR item. Its parameter is the level offset. \fBINNER\fR
+identifies the
+.QW "inner context" ,
+which is the innermost atomic command or bytecode instruction that raised the
+error, along with its arguments when available. While \fBCALL\fR and \fBUP\fR
+allow to follow complex call paths, \fBINNER\fR homes in on the offending
+operation in the innermost procedure call, even going to sub-expression
+granularity.
+.PP
+This information is also present in the \fB\-errorstack\fR entry of the
+options dictionary returned by 3-argument \fBcatch\fR; \fBinfo errorstack\fR
+is a convenient way of retrieving it for uncaught errors at top-level in an
+interactive \fBtclsh\fR.
+.RE
+.VE 8.6
+.TP
+\fBinfo exists \fIvarName\fR
+.
+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.
+.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 outer-most active command, 2 to the command it
+called, and so on, up to the current frame level which refers to
+\fBinfo frame\fR itself); 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 pre-compiled 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
+canonically-constructed list (e.g., as produced by the \fBlist\fR command)
+executed by \fBeval\fR it is the substituted form as they have no other
+string representation. Care is taken that the canonicality property of
+the latter is not spoiled.
+.TP
+\fBproc\fR
+.
+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, procedure definitions and \fBeval\fR within a dynamically
+\fBeval\fRuated environment count line numbers relative to the start of
+their script, even if they would be able to count relative to the
+start of the outer dynamic script. That type of number usually makes
+more sense.
+.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 line number
+within the list words as well, and otherwise all line numbers are
+counted relative to the start of each word (smallest scope)
+.RE
+.TP
+\fBinfo functions \fR?\fIpattern\fR?
+.
+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.
+.TP
+\fBinfo globals \fR?\fIpattern\fR?
+.
+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
+are returned. Matching is determined using the same rules as for
+\fBstring match\fR.
+.TP
+\fBinfo hostname\fR
+.
+Returns the name of the computer on which this invocation is being
+executed.
+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.
+.TP
+\fBinfo level\fR ?\fInumber\fR?
+.
+If \fInumber\fR is not specified, this command returns a number
+giving the stack level of the invoking procedure, or 0 if the
+command is invoked at top-level. If \fInumber\fR is specified,
+then the result is a list consisting of the name and arguments for the
+procedure call at level \fInumber\fR on the stack. If \fInumber\fR
+is positive then it selects a particular stack level (1 refers
+to the top-most active procedure, 2 to the procedure it called, and
+so on); otherwise it gives a level relative to the current level
+(0 refers to the current procedure, -1 to its caller, and so on).
+See the \fBuplevel\fR command for more information on what stack
+levels mean.
+.TP
+\fBinfo library\fR
+.
+Returns the name of the library directory in which standard Tcl
+scripts are stored.
+This is actually the value of the \fBtcl_library\fR
+variable and may be changed by setting \fBtcl_library\fR.
+See the \fBtclvars\fR manual entry for more information.
+.TP
+\fBinfo loaded \fR?\fIinterp\fR?
+.
+Returns a list describing all of the packages that have been loaded into
+\fIinterp\fR with the \fBload\fR command.
+Each list element is a sub-list with two elements consisting of the
+name of the file from which the package was loaded and the name of
+the package.
+For statically-loaded packages the file name will be an empty string.
+If \fIinterp\fR is omitted then information is returned for all packages
+loaded in any interpreter in the process.
+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 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
+\fBvariable\fR commands will not be returned.
+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.
+.TP
+\fBinfo nameofexecutable\fR
+.
+Returns the full path name of the binary file from which the application
+was invoked. If Tcl was unable to identify the file, then an empty
+string is returned.
+.TP
+\fBinfo object\fI subcommand object\fR ?\fIarg ...\fR
+.VS 8.6
+Returns information about the object, \fIobject\fR. The \fIsubcommand\fRs are
+described in \fBOBJECT INTROSPECTION\fR below.
+.VE 8.6
+.TP
+\fBinfo patchlevel\fR
+.
+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 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
+matching \fIpattern\fR are returned.
+Matching is determined using the same rules as for
+\fBstring match\fR.
+If \fIpattern\fR contains any namespace separators, they are used to
+select a namespace relative to the current namespace (or relative to
+the global namespace if \fIpattern\fR starts with \fB::\fR) to match
+within; the matching pattern is taken to be the part after the last
+namespace separator.
+.TP
+\fBinfo script\fR ?\fIfilename\fR?
+.
+If a Tcl script file is currently being evaluated (i.e. there is a
+call to \fBTcl_EvalFile\fR active or there is an active invocation
+of the \fBsource\fR command), then this command returns the name
+of the innermost file being processed. If \fIfilename\fR is specified,
+then the return value of this command will be modified for the
+duration of the active invocation to return that name. This is
+useful in virtual file system applications.
+Otherwise the command returns an empty string.
+.TP
+\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 are not supported on this platform then an empty
+string is returned.
+.TP
+\fBinfo tclversion\fR
+.
+Returns the value of the global variable \fBtcl_version\fR; see
+the \fBtclvars\fR manual entry for more information.
+.TP
+\fBinfo vars\fR ?\fIpattern\fR?
+.
+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
+are returned. Matching is determined using the same rules as for
+\fBstring match\fR.
+\fIpattern\fR can be a qualified name like \fBFoo::option*\fR.
+That is, it may specify a particular namespace
+using a sequence of namespace names separated by double colons (\fB::\fR),
+and may have pattern matching special characters
+at the end to specify a set of variables in that namespace.
+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
+.QW exist
+if it has not
+been set (e.g. a variable declared but not set by \fBvariable\fR).
+.SS "CLASS INTROSPECTION"
+.VS 8.6
+.PP
+The following \fIsubcommand\fR values are supported by \fBinfo class\fR:
+.VE 8.6
+.TP
+\fBinfo class call\fI class method\fR
+.VS
+Returns a description of the method implementations that are used to provide a
+stereotypical instance of \fIclass\fR's implementation of \fImethod\fR
+(stereotypical instances being objects instantiated by a class without having
+any object-specific definitions added). This consists of a list of lists of
+four elements, where each sublist consists of a word that describes the
+general type of method implementation (being one of \fBmethod\fR for an
+ordinary method, \fBfilter\fR for an applied filter, and \fBunknown\fR for a
+method that is invoked as part of unknown method handling), a word giving the
+name of the particular method invoked (which is always the same as
+\fImethod\fR for the \fBmethod\fR type, and
+.QW \fBunknown\fR
+for the \fBunknown\fR type), a word giving the fully qualified name of the
+class that defined the method, and a word describing the type of method
+implementation (see \fBinfo class methodtype\fR).
+.RS
+.PP
+Note that there is no inspection of whether the method implementations
+actually use \fBnext\fR to transfer control along the call chain.
+.RE
+.VE 8.6
+.TP
+\fBinfo class constructor\fI class\fR
+.VS 8.6
+This subcommand returns a description of the definition of the constructor of
+class \fIclass\fR. The definition is described as a two element list; the first
+element is the list of arguments to the constructor in a form suitable for
+passing to another call to \fBproc\fR or a method definition, and the second
+element is the body of the constructor. If no constructor is present, this
+returns the empty list.
+.VE 8.6
+.TP
+\fBinfo class definition\fI class method\fR
+.VS 8.6
+This subcommand returns a description of the definition of the method named
+\fImethod\fR of class \fIclass\fR. The definition is described as a two element
+list; the first element is the list of arguments to the method in a form
+suitable for passing to another call to \fBproc\fR or a method definition, and
+the second element is the body of the method.
+.VE 8.6
+.TP
+\fBinfo class destructor\fI class\fR
+.VS 8.6
+This subcommand returns the body of the destructor of class \fIclass\fR. If no
+destructor is present, this returns the empty string.
+.VE 8.6
+.TP
+\fBinfo class filters\fI class\fR
+.VS 8.6
+This subcommand returns the list of filter methods set on the class.
+.VE 8.6
+.TP
+\fBinfo class forward\fI class method\fR
+.VS 8.6
+This subcommand returns the argument list for the method forwarding called
+\fImethod\fR that is set on the class called \fIclass\fR.
+.VE 8.6
+.TP
+\fBinfo class instances\fI class\fR ?\fIpattern\fR?
+.VS 8.6
+This subcommand returns a list of instances of class \fIclass\fR. If the
+optional \fIpattern\fR argument is present, it constrains the list of returned
+instances to those that match it according to the rules of \fBstring match\fR.
+.VE 8.6
+.TP
+\fBinfo class methods\fI class\fR ?\fIoptions...\fR?
+.VS 8.6
+This subcommand returns a list of all public (i.e. exported) methods of the
+class called \fIclass\fR. Any of the following \fIoption\fRs may be
+specified, controlling exactly which method names are returned:
+.RS
+.VE 8.6
+.TP
+\fB\-all\fR
+.VS 8.6
+If the \fB\-all\fR flag is given, the list of methods will include those
+methods defined not just by the class, but also by the class's superclasses
+and mixins.
+.VE 8.6
+.TP
+\fB\-private\fR
+.VS 8.6
+If the \fB\-private\fR flag is given, the list of methods will also include
+the private (i.e. non-exported) methods of the class (and superclasses and
+mixins, if \fB\-all\fR is also given).
+.RE
+.VE 8.6
+.TP
+\fBinfo class methodtype\fI class method\fR
+.VS 8.6
+This subcommand returns a description of the type of implementation used for
+the method named \fImethod\fR of class \fIclass\fR. When the result is
+\fBmethod\fR, further information can be discovered with \fBinfo class
+definition\fR, and when the result is \fBforward\fR, further information can
+be discovered with \fBinfo class forward\fR.
+.VE 8.6
+.TP
+\fBinfo class mixins\fI class\fR
+.VS 8.6
+This subcommand returns a list of all classes that have been mixed into the
+class named \fIclass\fR.
+.VE 8.6
+.TP
+\fBinfo class subclasses\fI class\fR ?\fIpattern\fR?
+.VS 8.6
+This subcommand returns a list of direct subclasses of class \fIclass\fR. If
+the optional \fIpattern\fR argument is present, it constrains the list of
+returned classes to those that match it according to the rules of
+\fBstring match\fR.
+.VE 8.6
+.TP
+\fBinfo class superclasses\fI class\fR
+.VS 8.6
+This subcommand returns a list of direct superclasses of class \fIclass\fR in
+inheritance precedence order.
+.VE 8.6
+.TP
+\fBinfo class variables\fI class\fR
+.VS 8.6
+This subcommand returns a list of all variables that have been declared for
+the class named \fIclass\fR (i.e. that are automatically present in the
+class's methods, constructor and destructor).
+.SS "OBJECT INTROSPECTION"
+.PP
+The following \fIsubcommand\fR values are supported by \fBinfo object\fR:
+.VE 8.6
+.TP
+\fBinfo object call\fI object method\fR
+.VS 8.6
+Returns a description of the method implementations that are used to provide
+\fIobject\fR's implementation of \fImethod\fR. This consists of a list of
+lists of four elements, where each sublist consists of a word that describes
+the general type of method implementation (being one of \fBmethod\fR for an
+ordinary method, \fBfilter\fR for an applied filter, and \fBunknown\fR for a
+method that is invoked as part of unknown method handling), a word giving the
+name of the particular method invoked (which is always the same as
+\fImethod\fR for the \fBmethod\fR type, and
+.QW \fBunknown\fR
+for the \fBunknown\fR type), a word giving what defined the method (the fully
+qualified name of the class, or the literal string \fBobject\fR if the method
+implementation is on an instance), and a word describing the type of method
+implementation (see \fBinfo object methodtype\fR).
+.RS
+.PP
+Note that there is no inspection of whether the method implementations
+actually use \fBnext\fR to transfer control along the call chain.
+.RE
+.VE 8.6
+.TP
+\fBinfo object class\fI object\fR ?\fIclassName\fR?
+.VS 8.6
+If \fIclassName\fR is unspecified, this subcommand returns class of the
+\fIobject\fR object. If \fIclassName\fR is present, this subcommand returns a
+boolean value indicating whether the \fIobject\fR is of that class.
+.VE 8.6
+.TP
+\fBinfo object definition\fI object method\fR
+.VS 8.6
+This subcommand returns a description of the definition of the method named
+\fImethod\fR of object \fIobject\fR. The definition is described as a two
+element list; the first element is the list of arguments to the method in a
+form suitable for passing to another call to \fBproc\fR or a method definition,
+and the second element is the body of the method.
+.VE 8.6
+.TP
+\fBinfo object filters\fI object\fR
+.VS 8.6
+This subcommand returns the list of filter methods set on the object.
+.VE 8.6
+.TP
+\fBinfo object forward\fI object method\fR
+.VS 8.6
+This subcommand returns the argument list for the method forwarding called
+\fImethod\fR that is set on the object called \fIobject\fR.
+.VE 8.6
+.TP
+\fBinfo object isa\fI category object\fR ?\fIarg\fR?
+.VS 8.6
+This subcommand tests whether an object belongs to a particular category,
+returning a boolean value that indicates whether the \fIobject\fR argument
+meets the criteria for the category. The supported categories are:
+.VE 8.6
+.RS
+.TP
+\fBinfo object isa class\fI object\fR
+.VS 8.6
+This returns whether \fIobject\fR is a class (i.e. an instance of
+\fBoo::class\fR or one of its subclasses).
+.VE 8.6
+.TP
+\fBinfo object isa metaclass\fI object\fR
+.VS 8.6
+This returns whether \fIobject\fR is a class that can manufacture classes
+(i.e. is \fBoo::class\fR or a subclass of it).
+.VE 8.6
+.TP
+\fBinfo object isa mixin\fI object class\fR
+.VS 8.6
+This returns whether \fIclass\fR is directly mixed into \fIobject\fR.
+.VE 8.6
+.TP
+\fBinfo object isa object\fI object\fR
+.VS 8.6
+This returns whether \fIobject\fR really is an object.
+.VE 8.6
+.TP
+\fBinfo object isa typeof\fI object class\fR
+.VS 8.6
+This returns whether \fIclass\fR is the type of \fIobject\fR (i.e. whether
+\fIobject\fR is an instance of \fIclass\fR or one of its subclasses, whether
+direct or indirect).
+.RE
+.VE 8.6
+.TP
+\fBinfo object methods\fI object\fR ?\fIoption...\fR?
+.VS 8.6
+This subcommand returns a list of all public (i.e. exported) methods of the
+object called \fIobject\fR. Any of the following \fIoption\fRs may be
+specified, controlling exactly which method names are returned:
+.RS
+.VE 8.6
+.TP
+\fB\-all\fR
+.VS 8.6
+If the \fB\-all\fR flag is given, the list of methods will include those
+methods defined not just by the object, but also by the object's class and
+mixins, plus the superclasses of those classes.
+.VE 8.6
+.TP
+\fB\-private\fR
+.VS 8.6
+If the \fB\-private\fR flag is given, the list of methods will also include
+the private (i.e. non-exported) methods of the object (and classes, if
+\fB\-all\fR is also given).
+.RE
+.VE 8.6
+.TP
+\fBinfo object methodtype\fI object method\fR
+.VS 8.6
+This subcommand returns a description of the type of implementation used for
+the method named \fImethod\fR of object \fIobject\fR. When the result is
+\fBmethod\fR, further information can be discovered with \fBinfo object
+definition\fR, and when the result is \fBforward\fR, further information can
+be discovered with \fBinfo object forward\fR.
+.VE 8.6
+.TP
+\fBinfo object mixins\fI object\fR
+.VS 8.6
+This subcommand returns a list of all classes that have been mixed into the
+object named \fIobject\fR.
+.VE 8.6
+.TP
+\fBinfo object namespace\fI object\fR
+.VS 8.6
+This subcommand returns the name of the internal namespace of the object named
+\fIobject\fR.
+.VE 8.6
+.TP
+\fBinfo object variables\fI object\fR
+.VS 8.6
+This subcommand returns a list of all variables that have been declared for
+the object named \fIobject\fR (i.e. that are automatically present in the
+object's methods).
+.VE 8.6
+.TP
+\fBinfo object vars\fI object\fR ?\fIpattern\fR?
+.VS 8.6
+This subcommand returns a list of all variables in the private namespace of
+the object named \fIobject\fR. If the optional \fIpattern\fR argument is
+given, it is a filter (in the syntax of a \fBstring match\fR glob pattern)
+that constrains the list of variables returned. Note that this is different
+from the list returned by \fBinfo object variables\fR; that can include
+variables that are currently unset, whereas this can include variables that
+are not automatically included by any of \fIobject\fR's methods (or those of
+its class, superclasses or mixins).
+.VE 8.6
+.SH EXAMPLES
+.PP
+This command prints out a procedure suitable for saving in a Tcl
+script:
+.PP
+.CS
+proc printProc {procName} {
+ set result [list proc $procName]
+ set formals {}
+ foreach var [\fBinfo args\fR $procName] {
+ if {[\fBinfo default\fR $procName $var def]} {
+ lappend formals [list $var $def]
+ } else {
+ # Still need the list-quoting because variable
+ # names may properly contain spaces.
+ lappend formals [list $var]
+ }
+ }
+ puts [lappend result $formals [\fBinfo body\fR $procName]]
+}
+.CE
+.SS "EXAMPLES WITH OBJECTS"
+.VS 8.6
+.PP
+Every object necessarily knows what its class is; this information is
+trivially extractable through introspection:
+.PP
+.CS
+oo::class create c
+c create o
+puts [\fBinfo object class\fR o]
+ \fI\(-> prints "::c"\fR
+puts [\fBinfo object class\fR c]
+ \fI\(-> prints "::oo::class"\fR
+.CE
+.PP
+The introspection capabilities can be used to discover what class implements a
+method and get how it is defined. This procedure illustrates how:
+.PP
+.CS
+proc getDef {obj method} {
+ foreach inf [\fBinfo object call\fR $obj $method] {
+ lassign $inf calltype name locus methodtype
+ # Assume no forwards or filters, and hence no $calltype
+ # or $methodtype checks...
+ if {$locus eq "object"} {
+ return [\fBinfo object definition\fR $obj $name]
+ } else {
+ return [\fBinfo class definition\fR $locus $name]
+ }
+ }
+ error "no definition for $method"
+}
+.CE
+.PP
+This is an alternate way of looking up the definition; it is implemented by
+manually scanning the list of methods up the inheritance tree. This code
+assumes that only single inheritance is in use, and that there is no complex
+use of mixed-in classes (in such cases, using \fBinfo object call\fR as above
+is the simplest way of doing this by far):
+.PP
+.CS
+proc getDef {obj method} {
+ if {$method in [\fBinfo object methods\fR $obj]} {
+ # Assume no forwards
+ return [\fBinfo object definition\fR $obj $method]
+ }
+ set cls [\fBinfo object class\fR $obj]
+ while {$method ni [\fBinfo class methods\fR $cls]} {
+ # Assume the simple case
+ set cls [lindex [\fBinfo class superclass\fR $cls] 0]
+ if {$cls eq ""} {
+ error "no definition for $method"
+ }
+ }
+ # Assume no forwards
+ return [\fBinfo class definition\fR $cls $method]
+}
+.CE
+.VE 8.6
+.SH "SEE ALSO"
+.VS 8.6
+global(n), oo::class(n), oo::define(n), oo::object(n), proc(n), self(n)
+.VE 8.6
+.SH KEYWORDS
+command, information, interpreter, introspection, level, namespace,
+.VS 8.6
+object,
+.VE 8.6
+procedure, variable
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/library/msgcat/doc/interp.n b/library/msgcat/doc/interp.n
new file mode 100644
index 0000000..6ce10ee
--- /dev/null
+++ b/library/msgcat/doc/interp.n
@@ -0,0 +1,910 @@
+'\"
+'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2004 Donal K. Fellows
+'\" Copyright (c) 2006-2008 Joe Mistachkin.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH interp n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+interp \- Create and manipulate Tcl interpreters
+.SH SYNOPSIS
+\fBinterp \fIsubcommand \fR?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+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.
+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.
+.PP
+Each interpreter is independent from the others: it has its own name
+space for commands, procedures, and global variables.
+A master interpreter may create connections between its slaves and
+itself using a mechanism called an \fIalias\fR. An \fIalias\fR is
+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,
+and by resource limit exceeded callbacks. 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
+to another.
+.PP
+The \fBinterp\fR command also provides support for \fIsafe\fR
+interpreters. A safe interpreter is a slave whose functions have
+been greatly restricted, so that it is safe to execute untrusted
+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.
+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;
+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
+on how the alias mechanism works.
+.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
+interpreter in its immediate master. Interpreter names are relative to the
+interpreter in which they are used. For example, if
+.QW \fBa\fR
+is a slave of the current interpreter and it has a slave
+.QW \fBa1\fR ,
+which in turn has a slave
+.QW \fBa11\fR ,
+the qualified name of
+.QW \fBa11\fR
+in
+.QW \fBa\fR
+is the list
+.QW "\fBa1 a11\fR" .
+.PP
+The \fBinterp\fR command, described below, accepts qualified interpreter
+names as arguments; the interpreter in which the command is being evaluated
+can always be referred to as \fB{}\fR (the empty list or string). Note that
+it is impossible to refer to a master (ancestor) interpreter by name in a
+slave interpreter except through aliases. Also, there is no global name by
+which one can refer to the first interpreter created in an application.
+Both restrictions are motivated by safety concerns.
+.SH "THE INTERP COMMAND"
+.PP
+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 \fIsubcommand\fR argument:
+.TP
+\fBinterp\fR \fBalias\fR \fIsrcPath\fR \fIsrcToken\fR
+.
+Returns a Tcl list whose elements are the \fItargetCmd\fR and
+\fIarg\fRs associated with the alias represented by \fIsrcToken\fR
+(this is the value returned when the alias was
+created; it is possible that the name of the source command in the
+slave is different from \fIsrcToken\fR).
+.TP
+\fBinterp\fR \fBalias\fR \fIsrcPath\fR \fIsrcToken\fR \fB{}\fR
+.
+Deletes the alias for \fIsrcToken\fR in the slave interpreter identified by
+\fIsrcPath\fR.
+\fIsrcToken\fR refers to the value returned when the alias
+was created; if the source command has been renamed, the renamed
+command will be deleted.
+.TP
+\fBinterp\fR \fBalias\fR \fIsrcPath\fR \fIsrcCmd\fR \fItargetPath\fR \fItargetCmd \fR?\fIarg arg ...\fR?
+.
+This command creates an alias between one slave and another (see the
+\fBalias\fR slave command below for creating aliases between a slave
+and its master). In this command, either of the slave interpreters
+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,
+.QW "\fBa b\fR"
+identifies an interpreter
+.QW \fBb\fR ,
+which is a slave of interpreter
+.QW \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 command, which will be created in the source interpreter.
+\fITargetPath\fR and \fItargetCmd\fR specify a target interpreter
+and command, and the \fIarg\fR arguments, if any, specify additional
+arguments to \fItargetCmd\fR which are prepended to any arguments specified
+in the invocation of \fIsrcCmd\fR.
+\fITargetCmd\fR may be undefined at the time of this call, or it may
+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.
+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
+\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
+as the current names of the commands).
+.TP
+\fBinterp bgerror \fIpath\fR ?\fIcmdPrefix\fR?
+.
+This command either gets or sets the current background exception handler
+for the interpreter identified by \fIpath\fR. If \fIcmdPrefix\fR is
+absent, the current background exception 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 exception handler to. See the
+\fBBACKGROUND EXCEPTION HANDLING\fR section for more details.
+.TP
+\fBinterp\fR \fBcancel \fR?\fB\-unwind\fR? ?\fB\-\|\-\fR? ?\fIpath\fR? ?\fIresult\fR?
+.VS 8.6
+Cancels the script being evaluated in the interpreter identified by
+\fIpath\fR. Without the \fB\-unwind\fR switch the evaluation stack for
+the interpreter is unwound until an enclosing catch command is found or
+there are no further invocations of the interpreter left on the call
+stack. With the \fB\-unwind\fR switch the evaluation stack for the
+interpreter is unwound without regard to any intervening catch command
+until there are no further invocations of the interpreter left on the
+call stack. The \fB\-\|\-\fR switch can be used to mark the end of
+switches; it may be needed if \fIpath\fR is an unusual value such
+as \fB\-safe\fR. If \fIresult\fR is present, it will be used as the
+error message string; otherwise, a default error message string will be
+used.
+.VE 8.6
+.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\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
+described below. If \fIpath\fR is omitted, Tcl creates a unique name of the
+form \fBinterp\fIx\fR, where \fIx\fR is an integer, and uses it for the
+interpreter and the slave command. If the \fB\-safe\fR switch is specified
+(or if the master interpreter is a safe interpreter), the new slave
+interpreter will be created as a safe interpreter with limited
+functionality; otherwise the slave will include the full set of Tcl
+built-in commands and variables. The \fB\-\|\-\fR switch can be used to
+mark the end of switches; it may be needed if \fIpath\fR is an unusual
+value such as \fB\-safe\fR. The result of the command is the name of the
+new interpreter. The name of a slave interpreter must be unique among all
+the slaves for its master; an error occurs if a slave interpreter by the
+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 ?\fB\-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 \fB\-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.
+.RS
+.PP
+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.
+.PP
+Note that once it is on, this flag cannot be switched back off: such
+attempts are silently ignored. This is needed to maintain the
+consistency of the underlying interpreter's state.
+.RE
+.TP
+\fBinterp\fR \fBdelete \fR?\fIpath ...?\fR
+.
+Deletes zero or more interpreters given by the optional \fIpath\fR
+arguments, and for each interpreter, it also deletes its slaves. The
+command also deletes the slave command for each interpreter deleted.
+For each \fIpath\fR argument, if no interpreter by that name
+exists, the command raises an error.
+.TP
+\fBinterp\fR \fBeval\fR \fIpath arg \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 the slave interpreter identified by \fIpath\fR. 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 the
+\fIpath\fR interpreter; 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.
+.TP
+\fBinterp exists \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.
+.TP
+\fBinterp expose \fIpath\fR \fIhiddenName\fR ?\fIexposedCmdName\fR?
+.
+Makes the hidden command \fIhiddenName\fR exposed, eventually bringing
+it back under a new \fIexposedCmdName\fR name (this name is currently
+accepted only if it is a valid global name space name without any ::),
+in the interpreter
+denoted by \fIpath\fR.
+If an exposed command with the targeted name already exists, this command
+fails.
+Hidden commands are explained in more detail in \fBHIDDEN COMMANDS\fR, below.
+.TP
+\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
+by \fIpath\fR.
+If a hidden command with the targeted name already exists, this command
+fails.
+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
+prevents slaves from fooling a master interpreter into hiding the wrong
+command, by making the current namespace be different from the global one.
+Hidden commands are explained in more detail in \fBHIDDEN COMMANDS\fR, below.
+.TP
+\fBinterp\fR \fBhidden\fR \fIpath\fR
+.
+Returns a list of the names of all hidden commands in the interpreter
+identified by \fIpath\fR.
+.TP
+\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. 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.
+.TP
+\fBinterp issafe\fR ?\fIpath\fR?
+.
+Returns \fB1\fR if the interpreter identified by the specified \fIpath\fR
+is safe, \fB0\fR otherwise.
+.TP
+\fBinterp\fR \fBlimit\fR \fIpath\fR \fIlimitType\fR ?\fI\-option\fR? ?\fIvalue\fR \fI...\fR?
+.
+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.
+.TP
+\fBinterp marktrusted\fR \fIpath\fR
+.
+Marks the interpreter identified by \fIpath\fR as trusted. Does
+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.
+.TP
+\fBinterp\fR \fBrecursionlimit\fR \fIpath\fR ?\fInewlimit\fR?
+.
+Returns the maximum allowable nesting depth for the interpreter
+specified by \fIpath\fR. If \fInewlimit\fR is specified,
+the interpreter recursion limit will be set so that nesting
+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.
+.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.
+.RE
+.TP
+\fBinterp\fR \fBshare\fR \fIsrcPath channelId destPath\fR
+.
+Causes the IO channel identified by \fIchannelId\fR to become shared
+between the interpreter identified by \fIsrcPath\fR and the interpreter
+identified by \fIdestPath\fR. Both interpreters have the same permissions
+on the IO channel.
+Both interpreters must close it to close the underlying IO channel; IO
+channels accessible in an interpreter are automatically closed when an
+interpreter is destroyed.
+.TP
+\fBinterp\fR \fBslaves\fR ?\fIpath\fR?
+.
+Returns a Tcl list of the names of all the slave interpreters associated
+with the interpreter identified by \fIpath\fR. If \fIpath\fR is omitted,
+the invoking interpreter is used.
+.TP
+\fBinterp\fR \fBtarget\fR \fIpath alias\fR
+.
+Returns a Tcl list describing the target interpreter for an alias. The
+alias is specified with an interpreter path and source command name, just
+as in \fBinterp alias\fR above. The name of the target interpreter is
+returned as an interpreter path, relative to the invoking interpreter.
+If the target interpreter for the alias is the invoking interpreter then an
+empty list is returned. If the target interpreter for the alias is not the
+invoking interpreter or one of its descendants then an error is generated.
+The target command does not have to be defined at the time of this invocation.
+.TP
+\fBinterp\fR \fBtransfer\fR \fIsrcPath channelId destPath\fR
+.
+Causes the IO channel identified by \fIchannelId\fR to become available in
+the interpreter identified by \fIdestPath\fR and unavailable in the
+interpreter identified by \fIsrcPath\fR.
+.SH "SLAVE COMMAND"
+.PP
+For each slave interpreter created with the \fBinterp\fR command, a
+new Tcl command is created in the master interpreter with the same
+name as the new interpreter. This command may be used to invoke
+various operations on the interpreter. It has the following
+general form:
+.PP
+.CS
+\fIslave command \fR?\fIarg arg ...\fR?
+.CE
+.PP
+\fISlave\fR is the name of the interpreter, and \fIcommand\fR
+and the \fIarg\fRs determine the exact behavior of the command.
+The valid forms of this command are:
+.TP
+\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
+as the current names of the commands).
+.TP
+\fIslave \fBalias \fIsrcToken\fR
+.
+Returns a Tcl list whose elements are the \fItargetCmd\fR and
+\fIarg\fRs associated with the alias represented by \fIsrcToken\fR
+(this is the value returned when the alias was
+created; it is possible that the actual source command in the
+slave is different from \fIsrcToken\fR).
+.TP
+\fIslave \fBalias \fIsrcToken \fB{}\fR
+.
+Deletes the alias for \fIsrcToken\fR in the slave interpreter.
+\fIsrcToken\fR refers to the value returned when the alias
+was created; if the source command has been renamed, the renamed
+command will be deleted.
+.TP
+\fIslave \fBalias \fIsrcCmd targetCmd \fR?\fIarg ..\fR?
+.
+Creates an alias such that whenever \fIsrcCmd\fR is invoked
+in \fIslave\fR, \fItargetCmd\fR is invoked in the master.
+The \fIarg\fR arguments will be passed to \fItargetCmd\fR as additional
+arguments, prepended before any arguments passed in the invocation of
+\fIsrcCmd\fR.
+See \fBALIAS INVOCATION\fR below for 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.
+.TP
+\fIslave \fBbgerror\fR ?\fIcmdPrefix\fR?
+.
+This command either gets or sets the current background exception handler
+for the \fIslave\fR interpreter. If \fIcmdPrefix\fR is
+absent, the current background exception 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 exception handler to. See the
+\fBBACKGROUND EXCEPTION HANDLING\fR section for more details.
+.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 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.
+.TP
+\fIslave \fBexpose \fIhiddenName \fR?\fIexposedCmdName\fR?
+.
+This command exposes the hidden command \fIhiddenName\fR, eventually bringing
+it back under a new \fIexposedCmdName\fR name (this name is currently
+accepted only if it is a valid global name space name without any ::),
+in \fIslave\fR.
+If an exposed command with the targeted name already exists, this command
+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
+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
+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
+prevents slaves from fooling a master interpreter into hiding the wrong
+command, by making the current namespace be different from the global one.
+For more details on hidden commands, see \fBHIDDEN COMMANDS\fR, below.
+.TP
+\fIslave \fBhidden\fR
+.
+Returns a list of the names of all hidden commands in \fIslave\fR.
+.TP
+\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. 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.
+.TP
+\fIslave \fBissafe\fR
+.
+Returns \fB1\fR if the slave interpreter is safe, \fB0\fR otherwise.
+.TP
+\fIslave \fBlimit\fR \fIlimitType\fR ?\fI\-option\fR? ?\fIvalue\fR \fI...\fR?
+.
+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.
+.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.
+.TP
+\fIslave\fR \fBrecursionlimit\fR ?\fInewlimit\fR?
+.
+Returns the maximum allowable nesting depth for the \fIslave\fR interpreter.
+If \fInewlimit\fR is specified, the recursion limit in \fIslave\fR will be
+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.
+.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.
+.RE
+.SH "SAFE INTERPRETERS"
+.PP
+A safe interpreter is one with restricted functionality, so that
+is safe to execute an arbitrary script from your worst enemy without
+fear of that script damaging the enclosing application or the rest
+of your computing environment. In order to make an interpreter
+safe, certain commands and variables are removed from the interpreter.
+For example, commands to create files on disk are removed, and the
+\fBexec\fR command is removed, since it could be used to cause damage
+through subprocesses.
+Limited access to these facilities can be provided, by creating
+aliases to the master interpreter which check their arguments carefully
+and provide restricted access to a safe subset of facilities.
+For example, file creation might be allowed in a particular subdirectory
+and subprocess invocation might be allowed for a carefully selected and
+fixed set of programs.
+.PP
+A safe interpreter is created by specifying the \fB\-safe\fR switch
+to the \fBinterp create\fR command. Furthermore, any slave created
+by a safe interpreter will also be safe.
+.PP
+A safe interpreter is created with exactly the following set of
+built-in commands:
+.DS
+.ta 1.2i 2.4i 3.6i
+\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
+The following commands are hidden by \fBinterp create\fR when it
+creates a safe interpreter:
+.DS
+.ta 1.2i 2.4i 3.6i
+\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.
+.PP
+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\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.
+Autoload access to Tcl's commands that are normally autoloaded:
+.DS
+.ta 2.1i
+\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
+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.
+.PP
+In addition, the \fBenv\fR variable is not present in a safe interpreter,
+so it cannot share environment variables with other interpreters. The
+\fBenv\fR variable poses a security risk, because users can store
+sensitive information in an environment variable. For example, the PGP
+manual recommends storing the PGP private key protection password in
+the environment variable \fIPGPPASS\fR. Making this variable available
+to untrusted code executing in a safe interpreter would incur a
+security risk.
+.PP
+If extensions are loaded into a safe interpreter, they may also restrict
+their own functionality to eliminate unsafe commands. For a discussion of
+management of extensions for safety see the manual entries for
+\fBSafe\-Tcl\fR and the \fBload\fR Tcl command.
+.PP
+A safe interpreter may not alter the recursion limit of any interpreter,
+including itself.
+.SH "ALIAS INVOCATION"
+.PP
+The alias mechanism has been carefully designed so that it can
+be used safely when an untrusted script is executing
+in a safe slave and the target of the alias is a trusted
+master. The most important thing in guaranteeing safety is to
+ensure that information passed from the slave to the master is
+never evaluated or substituted in the master; if this were to
+occur, it would enable an evil script in the slave to invoke
+arbitrary functions in the master, which would compromise security.
+.PP
+When the source for an alias is invoked in the slave interpreter, the
+usual Tcl substitutions are performed when parsing that command.
+These substitutions are carried out in the source interpreter just
+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
+.QW "\fIsrcCmd arg1 arg2 ... argN\fR" ,
+the new set of words will be
+.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
+is invoked with the new set of arguments. An error occurs if
+there is no command named \fItargetCmd\fR in the target interpreter.
+No additional substitutions are performed on the words: the
+target command procedure is invoked directly, without
+going through the normal Tcl evaluation mechanism.
+Substitutions are thus performed on each word exactly once:
+\fItargetCmd\fR and \fIargs\fR were substituted when parsing the command
+that created the alias, and \fIarg1 - argN\fR are substituted when
+the alias's source command is parsed in the source interpreter.
+.PP
+When writing the \fItargetCmd\fRs for aliases in safe interpreters,
+it is very important that the arguments to that command never be
+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.
+.SH "HIDDEN COMMANDS"
+.PP
+Safe interpreters greatly restrict the functionality available to Tcl
+programs executing within them.
+Allowing the untrusted Tcl program to have direct access to this
+functionality is unsafe, because it can be used for a variety of
+attacks on the environment.
+However, there are times when there is a legitimate need to use the
+dangerous functionality in the context of the safe interpreter. For
+example, sometimes a program must be \fBsource\fRd into the interpreter.
+Another example is Tk, where windows are bound to the hierarchy of windows
+for a specific interpreter; some potentially dangerous functions, e.g.
+window management, must be performed on these windows within the
+interpreter context.
+.PP
+The \fBinterp\fR command provides a solution to this problem in the form of
+\fIhidden commands\fR. Instead of removing the dangerous commands entirely
+from a safe interpreter, these commands are hidden so they become
+unavailable to Tcl scripts executing in the interpreter. However, such
+hidden commands can be invoked by any trusted ancestor of the safe
+interpreter, in the context of the safe interpreter, using \fBinterp
+invoke\fR. Hidden commands and exposed commands reside in separate name
+spaces. It is possible to define a hidden command and an exposed command by
+the same name within one interpreter.
+.PP
+Hidden commands in a slave interpreter can be invoked in the body of
+procedures called in the master during alias invocation. For example, an
+alias for \fBsource\fR could be created in a slave interpreter. When it is
+invoked in the slave interpreter, a procedure is called in the master
+interpreter to check that the operation is allowable (e.g. it asks to
+source a file that the slave interpreter is allowed to access). The
+procedure then it invokes the hidden \fBsource\fR command in the slave
+interpreter to actually source in the contents of the file. Note that two
+commands named \fBsource\fR exist in the slave interpreter: the alias, and
+the hidden command.
+.PP
+Because a master interpreter may invoke a hidden command as part of
+handling an alias invocation, great care must be taken to avoid evaluating
+any arguments passed in through the alias invocation.
+Otherwise, malicious slave interpreters could cause a trusted master
+interpreter to execute dangerous commands on their behalf. See the section
+on \fBALIAS INVOCATION\fR for a more complete discussion of this topic.
+To help avoid this problem, no substitutions or evaluations are
+applied to arguments of \fBinterp invokehidden\fR.
+.PP
+Safe interpreters are not allowed to invoke hidden commands in themselves
+or in their descendants. This prevents safe slaves from gaining access to
+hidden functionality in themselves or their descendants.
+.PP
+The set of hidden commands in an interpreter can be manipulated by a trusted
+interpreter using \fBinterp expose\fR and \fBinterp hide\fR. The \fBinterp
+expose\fR command moves a hidden command to the
+set of exposed commands in the interpreter identified by \fIpath\fR,
+potentially renaming the command in the process. If an exposed command by
+the targeted name already exists, the operation fails. Similarly,
+\fBinterp hide\fR moves an exposed command to the set of hidden commands in
+that interpreter. Safe interpreters are not allowed to move commands
+between the set of hidden and exposed commands, in either themselves or
+their descendants.
+.PP
+Currently, the names of hidden commands cannot contain namespace
+qualifiers, and you must first rename a command in a namespace to the
+global namespace before you can hide it.
+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.
+.SH "RESOURCE LIMITS"
+.PP
+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.
+.TP
+\fB\-command\fR
+.
+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 exception, it
+is reported through the background exception mechanism (see
+\fBBACKGROUND EXCEPTION 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.
+.TP
+\fB\-granularity\fR
+.
+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.
+.TP
+\fB\-milliseconds\fR
+.
+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.)
+.TP
+\fB\-seconds\fR
+.
+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.
+.TP
+\fB\-value\fR
+.
+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 EXCEPTION HANDLING"
+.PP
+When an exception 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 exception is instead reported through the background exception handling mechanism.
+Every interpreter has a background exception handler registered; the default exception
+handler arranges for the \fBbgerror\fR command in the interpreter's global
+namespace to be called, but other exception handlers may be installed and process
+background exceptions in substantially different ways.
+.PP
+A background exception 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
+interpreter result at time of the exception, typically an error message,
+and the second will be the dictionary of return options at the time of
+the exception. These are the same values that \fBcatch\fR can capture
+when it controls script evaluation in a non-background situation.
+The resulting list will then be executed
+in the interpreter's global namespace without further substitutions being
+performed.
+.SH CREDITS
+The safe interpreter mechanism is based on the Safe-Tcl prototype implemented
+by Nathaniel Borenstein and Marshall Rose.
+.SH EXAMPLES
+.PP
+Creating and using an alias for a command in the current interpreter:
+.PP
+.CS
+\fBinterp alias\fR {} getIndex {} lsearch {alpha beta gamma delta}
+set idx [getIndex delta]
+.CE
+.PP
+Executing an arbitrary command in a safe interpreter where every
+invocation of \fBlappend\fR is logged:
+.PP
+.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 invocation of lappend $args"
+ \fBinterp invokehidden\fR $i lappend {*}$args
+}
+\fBinterp eval\fR $i $someUntrustedScript
+.CE
+.PP
+Setting a resource limit on an interpreter so that an infinite loop
+terminates.
+.PP
+.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
+.SH "SEE ALSO"
+bgerror(n), load(n), safe(n), Tcl_CreateSlave(3), Tcl_Eval(3), Tcl_BackgroundException(3)
+.SH KEYWORDS
+alias, master interpreter, safe interpreter, slave interpreter
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/library/msgcat/doc/join.n b/library/msgcat/doc/join.n
new file mode 100644
index 0000000..1b23667
--- /dev/null
+++ b/library/msgcat/doc/join.n
@@ -0,0 +1,44 @@
+'\"
+'\" 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 join n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+join \- Create a string by joining together list elements
+.SH SYNOPSIS
+\fBjoin \fIlist \fR?\fIjoinString\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fIlist\fR argument must be a valid Tcl list.
+This command returns the string
+formed by joining all of the elements of \fIlist\fR together with
+\fIjoinString\fR separating each adjacent pair of elements.
+The \fIjoinString\fR argument defaults to a space character.
+.SH EXAMPLES
+.PP
+Making a comma-separated list:
+.PP
+.CS
+set data {1 2 3 4 5}
+\fBjoin\fR $data ", "
+ \fB\(-> 1, 2, 3, 4, 5\fR
+.CE
+.PP
+Using \fBjoin\fR to flatten a list by a single level:
+.PP
+.CS
+set data {1 {2 3} 4 {5 {6 7} 8}}
+\fBjoin\fR $data
+ \fB\(-> 1 2 3 4 5 {6 7} 8\fR
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), split(n)
+.SH KEYWORDS
+element, join, list, separator
diff --git a/library/msgcat/doc/lappend.n b/library/msgcat/doc/lappend.n
new file mode 100644
index 0000000..9bfab72
--- /dev/null
+++ b/library/msgcat/doc/lappend.n
@@ -0,0 +1,49 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH lappend n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+lappend \- Append list elements onto a variable
+.SH SYNOPSIS
+\fBlappend \fIvarName \fR?\fIvalue value value ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+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 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,
+.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
+.PP
+Using \fBlappend\fR to build up a list of numbers.
+.PP
+.CS
+% set var 1
+1
+% \fBlappend\fR var 2
+1 2
+% \fBlappend\fR var 3 4 5
+1 2 3 4 5
+.CE
+.SH "SEE ALSO"
+list(n), lindex(n), linsert(n), llength(n), lset(n),
+lsort(n), lrange(n)
+.SH KEYWORDS
+append, element, list, variable
diff --git a/library/msgcat/doc/lassign.n b/library/msgcat/doc/lassign.n
new file mode 100644
index 0000000..6f5042b
--- /dev/null
+++ b/library/msgcat/doc/lassign.n
@@ -0,0 +1,60 @@
+'\"
+'\" 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 \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
+.PP
+An illustration of how multiple assignment works, and what happens
+when there are either too few or too many elements.
+.PP
+.CS
+\fBlassign\fR {a b c} x y z ;# Empty return
+puts $x ;# Prints "a"
+puts $y ;# Prints "b"
+puts $z ;# Prints "c"
+
+\fBlassign\fR {d e} x y z ;# Empty return
+puts $x ;# Prints "d"
+puts $y ;# Prints "e"
+puts $z ;# Prints ""
+
+\fBlassign\fR {f g h i} x y ;# Returns "h i"
+puts $x ;# Prints "f"
+puts $y ;# Prints "g"
+.CE
+.PP
+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:
+.PP
+.CS
+set ::argv [\fBlassign\fR $::argv argumentToReadOff]
+.CE
+.SH "SEE ALSO"
+lindex(n), list(n), lrange(n), lset(n), set(n)
+.SH KEYWORDS
+assign, element, list, multiple, set, variable
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/library/msgcat/doc/library.n b/library/msgcat/doc/library.n
new file mode 100644
index 0000000..2413692
--- /dev/null
+++ b/library/msgcat/doc/library.n
@@ -0,0 +1,314 @@
+'\"
+'\" Copyright (c) 1991-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 library n "8.0" Tcl "Tcl Built-In Commands"
+.BS
+.SH NAME
+auto_execok, auto_import, auto_load, auto_mkindex, auto_qualify, auto_reset, tcl_findLibrary, parray, tcl_endOfWord, tcl_startOfNextWord, tcl_startOfPreviousWord, tcl_wordBreakAfter, tcl_wordBreakBefore \- standard library of Tcl procedures
+.SH SYNOPSIS
+.nf
+\fBauto_execok \fIcmd\fR
+\fBauto_import \fIpattern\fR
+\fBauto_load \fIcmd\fR
+\fBauto_mkindex \fIdir pattern pattern ...\fR
+\fBauto_qualify \fIcommand namespace\fR
+\fBauto_reset\fR
+\fBtcl_findLibrary \fIbasename version patch initScript enVarName varName\fR
+\fBparray \fIarrayName\fR
+\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
+.BE
+.SH INTRODUCTION
+.PP
+Tcl includes a library of Tcl procedures for commonly-needed functions.
+The procedures defined in the Tcl library are generic ones suitable
+for use by many different applications.
+The location of the Tcl library is returned by the \fBinfo library\fR
+command.
+In addition to the Tcl library, each application will normally have
+its own library of support procedures as well; the location of this
+library is normally given by the value of the \fB$\fIapp\fB_library\fR
+global variable, where \fIapp\fR is the name of the application.
+For example, the location of the Tk library is kept in the variable
+\fBtk_library\fR.
+.PP
+To access the procedures in the Tcl library, an application should
+source the file \fBinit.tcl\fR in the library, for example with
+the Tcl command
+.PP
+.CS
+\fBsource [file join [info library] init.tcl]\fR
+.CE
+.PP
+If the library procedure \fBTcl_Init\fR is invoked from an application's
+\fBTcl_AppInit\fR procedure, this happens automatically.
+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:
+.TP
+\fBauto_execok \fIcmd\fR
+Determines whether there is an executable file or shell builtin
+by the name \fIcmd\fR. If so, it returns a list of arguments to be
+passed to \fBexec\fR to execute the executable file or shell builtin
+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_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
+\fBauto_execok\fR to forget its cached information.
+.TP
+\fBauto_import \fIpattern\fR
+\fBAuto_import\fR is invoked during \fBnamespace import\fR to see if
+the imported commands specified by \fIpattern\fR reside in an
+autoloaded library. If so, the commands are loaded so that they will
+be available to the interpreter for creating the import links. If the
+commands do not reside in an autoloaded library, \fBauto_import\fR
+does nothing. The pattern matching is performed according to the
+matching rules of \fBnamespace import\fR.
+.TP
+\fBauto_load \fIcmd\fR
+This command attempts to load the definition for a Tcl command named
+\fIcmd\fR. To do this, it searches an \fIauto-load path\fR, which is
+a list of one or more directories. The auto-load path is given by the
+global variable \fBauto_path\fR if it exists. If there is no
+\fBauto_path\fR variable, then the TCLLIBPATH environment variable is
+used, if it exists. Otherwise the auto-load path consists of just the
+Tcl library directory. Within each directory in the auto-load path
+there must be a file \fBtclIndex\fR that describes one or more
+commands defined in that directory and a script to evaluate to load
+each of the commands. The \fBtclIndex\fR file should be generated
+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 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
+the array \fBauto_index\fR; future calls to \fBauto_load\fR check for
+\fIcmd\fR in the array rather than re-reading the index files. The
+cached index information may be deleted with the command
+\fBauto_reset\fR. This will force the next \fBauto_load\fR command to
+reload the index database from disk.
+.TP
+\fBauto_mkindex \fIdir pattern pattern ...\fR
+.
+Generates an index suitable for use by \fBauto_load\fR. The command
+searches \fIdir\fR for all files whose names match any of the
+\fIpattern\fR arguments (matching is done with the \fBglob\fR
+command), generates an index of all the Tcl command procedures defined
+in all the matching files, and stores the index information in a file
+named \fBtclIndex\fR in \fIdir\fR. If no pattern is given a pattern of
+\fB*.tcl\fR will be assumed. For example, the command
+.RS
+.PP
+.CS
+\fBauto_mkindex foo *.tcl\fR
+.CE
+.PP
+will read all the \fB.tcl\fR files in subdirectory \fBfoo\fR and
+generate a new index file \fBfoo/tclIndex\fR.
+.PP
+\fBAuto_mkindex\fR parses the Tcl scripts by sourcing them into a
+slave interpreter and monitoring the proc and namespace commands that
+are executed. Extensions can use the (undocumented)
+auto_mkindex_parser package to register other commands that can
+contribute to the auto_load index. You will have to read through
+auto.tcl to see how this works.
+.PP
+\fBAuto_mkindex_old\fR
+(which has the same syntax as \fBauto_mkindex\fR)
+parses the Tcl scripts in a relatively
+unsophisticated way: if any line contains the word
+.QW \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 do not appear in this way (e.g.\ they
+have spaces before the \fBproc\fR) will not be indexed. If your
+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 \fBauto_mkindex_old\fR.
+.RE
+.TP
+\fBauto_reset\fR
+.
+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 are used.
+.TP
+\fBauto_qualify \fIcommand namespace\fR
+Computes a list of fully qualified names for \fIcommand\fR. This list
+mirrors the path a standard Tcl interpreter follows for command
+lookups: first it looks for the command in the current namespace, and
+then in the global namespace. Accordingly, if \fIcommand\fR is
+relative and \fInamespace\fR is not \fB::\fR, the list returned has
+two elements: \fIcommand\fR scoped by \fInamespace\fR, as if it were
+a command in the \fInamespace\fR namespace; and \fIcommand\fR as if it
+were a command in the global namespace. Otherwise, if either
+\fIcommand\fR is absolute (it begins with \fB::\fR), or
+\fInamespace\fR is \fB::\fR, the list contains only \fIcommand\fR as
+if it were a command in the global namespace.
+.RS
+.PP
+\fBAuto_qualify\fR is used by the auto-loading facilities in Tcl, both
+for producing auto-loading indexes such as \fIpkgIndex.tcl\fR, and for
+performing the actual auto-loading of functions at runtime.
+.RE
+.TP
+\fBtcl_findLibrary \fIbasename version patch initScript enVarName varName\fR
+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\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\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\fR;
+relative to the Tcl library directory;
+relative to the executable file in the standard installation
+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
+\fBparray \fIarrayName\fR
+Prints on standard output the names and values of all the elements
+in the array \fIarrayName\fR.
+\fIArrayName\fR must be an array accessible to the caller of \fBparray\fR.
+It may be either local or global.
+.TP
+\fBtcl_endOfWord \fIstr start\fR
+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
+first word character after the starting point. Returns -1 if there
+are no more end-of-word locations after the starting point. See the
+description of \fBtcl_wordchars\fR and \fBtcl_nonwordchars\fR below
+for more details on how Tcl determines which characters are word
+characters.
+.TP
+\fBtcl_startOfNextWord \fIstr start\fR
+Returns the index of the first start-of-word location that occurs
+after a starting index \fIstart\fR in the string \fIstr\fR. A
+start-of-word location is defined to be the first word character
+following a non-word character. Returns \-1 if there are no more
+start-of-word locations after the starting point.
+.TP
+\fBtcl_startOfPreviousWord \fIstr start\fR
+Returns the index of the first start-of-word location that occurs
+before a starting index \fIstart\fR in the string \fIstr\fR. Returns
+\-1 if there are no more start-of-word locations before the starting
+point.
+.TP
+\fBtcl_wordBreakAfter \fIstr start\fR
+Returns the index of the first word boundary after the starting index
+\fIstart\fR in the string \fIstr\fR. Returns \-1 if there are no more
+boundaries after the starting point in the given string. The index
+returned refers to the second character of the pair that comprises a
+boundary.
+.TP
+\fBtcl_wordBreakBefore \fIstr start\fR
+Returns the index of the first word boundary before the starting index
+\fIstart\fR in the string \fIstr\fR. Returns \-1 if there are no more
+boundaries before the starting point in the given string. The index
+returned refers to the second character of the pair that comprises a
+boundary.
+.SH "VARIABLES"
+.PP
+The following global variables are defined or used by the procedures in
+the Tcl library. They fall into two broad classes, handling unknown
+commands and packages, and determining what are words.
+.SS "AUTOLOADING AND PACKAGE MANAGEMENT VARIABLES"
+.TP
+\fBauto_execs\fR
+Used by \fBauto_execok\fR to record information about whether
+particular commands exist as executable files.
+.TP
+\fBauto_index\fR
+Used by \fBauto_load\fR to save the index information read from
+disk.
+.TP
+\fBauto_noexec\fR
+If set to any value, then \fBunknown\fR will not attempt to auto-exec
+any commands.
+.TP
+\fBauto_noload\fR
+If set to any value, then \fBunknown\fR will not attempt to auto-load
+any commands.
+.TP
+\fBauto_path\fR
+If set, then it must contain a valid Tcl list giving directories to
+search during auto-load operations.
+This variable is initialized during startup to contain, in order:
+the directories listed in the \fBTCLLIBPATH\fR environment variable,
+the directory named by the \fBtcl_library\fR variable,
+the parent directory of \fBtcl_library\fR,
+the directories listed in the \fBtcl_pkgPath\fR variable.
+.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.
+.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.
+.SS "WORD BOUNDARY DETERMINATION VARIABLES"
+These variables are only used in the \fBtcl_endOfWord\fR,
+\fBtcl_startOfNextWord\fR, \fBtcl_startOfPreviousWord\fR,
+\fBtcl_wordBreakAfter\fR, and \fBtcl_wordBreakBefore\fR commands.
+.TP
+\fBtcl_nonwordchars\fR
+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
+considered to be a non-word character. On Windows platforms, spaces,
+tabs, and newlines are considered non-word characters. Under Unix,
+everything but numbers, letters and underscores are considered
+non-word characters.
+.TP
+\fBtcl_wordchars\fR
+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
+considered to be a word character. On Windows platforms, words are
+comprised of any character that is not a space, tab, or newline. Under
+Unix, words are comprised of numbers, letters or underscores.
+.SH "SEE ALSO"
+info(n), re_syntax(n), tclvars(n)
+.SH KEYWORDS
+auto-exec, auto-load, library, unknown, word, whitespace
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/library/msgcat/doc/lindex.n b/library/msgcat/doc/lindex.n
new file mode 100644
index 0000000..bb272a6
--- /dev/null
+++ b/library/msgcat/doc/lindex.n
@@ -0,0 +1,125 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" 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.
+'\"
+.so man.macros
+.TH lindex n 8.4 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+lindex \- Retrieve an element from a list
+.SH SYNOPSIS
+\fBlindex \fIlist ?index ...?\fR
+.BE
+.SH DESCRIPTION
+.PP
+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.
+.PP
+If no indices are presented, the command takes the form:
+.PP
+.CS
+\fBlindex \fIlist\fR
+.CE
+.PP
+or
+.PP
+.CS
+\fBlindex \fIlist\fR {}
+.CE
+.PP
+In this case, the return value of \fBlindex\fR is simply the value of the
+\fIlist\fR parameter.
+.PP
+When presented with a single index, the \fBlindex\fR command
+treats \fIlist\fR as a Tcl list and returns the
+\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
+interpreter; however, variable
+substitution and command substitution do not occur.
+If \fIindex\fR is negative or greater than or equal to the number
+of elements in \fIvalue\fR, then an empty
+string is returned.
+The interpretation of each simple \fIindex\fR value is the same as
+for the command \fBstring index\fR, supporting simple index
+arithmetic and indices relative to the end of the list.
+.PP
+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,
+.PP
+.CS
+\fBlindex\fR $a 1 2 3
+.CE
+.PP
+or
+.PP
+.CS
+\fBlindex\fR $a {1 2 3}
+.CE
+.PP
+is synonymous with
+.PP
+.CS
+\fBlindex\fR [\fBlindex\fR [\fBlindex\fR $a 1] 2] 3
+.CE
+.SH EXAMPLES
+.PP
+Lists can be indexed into from either end:
+.PP
+.CS
+\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
+.CE
+.PP
+Lists or sequences of indices allow selection into lists of lists:
+.PP
+.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} {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
+.PP
+List indices may also perform limited computation, adding or subtracting fixed
+amounts from other indices:
+.PP
+.CS
+set idx 1
+\fBlindex\fR {a b c d e f} $idx+2
+ \fI\(-> d\fR
+set idx 3
+\fBlindex\fR {a b c d e f} $idx+2
+ \fI\(-> f\fR
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), linsert(n), llength(n), lsearch(n),
+lset(n), lsort(n), lrange(n), lreplace(n),
+string(n)
+.SH KEYWORDS
+element, index, list
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/library/msgcat/doc/linsert.n b/library/msgcat/doc/linsert.n
new file mode 100644
index 0000000..c722e4f
--- /dev/null
+++ b/library/msgcat/doc/linsert.n
@@ -0,0 +1,55 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH linsert n 8.2 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+linsert \- Insert elements into a list
+.SH SYNOPSIS
+\fBlinsert \fIlist index \fR?\fIelement element ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+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, and if \fIindex\fR is
+greater or equal to the length of \fIlist\fR, it is as if it was \fBend\fR.
+As with \fBstring index\fR, the \fIindex\fR value supports both simple index
+arithmetic and end-relative indexing.
+.PP
+Subject to the restrictions that indices must refer to locations inside the
+list and that the \fIelement\fRs will always be inserted in order, insertions
+are done so that when \fIindex\fR is start-relative, the first \fIelement\fR
+will be at that index in the resulting list, and when \fIindex\fR is
+end-relative, the last \fIelement\fR will be at that index in the resulting
+list.
+.SH EXAMPLE
+.PP
+Putting some values into a list, first indexing from the start and
+then indexing from the end, and then chaining them together:
+.PP
+.CS
+set oldList {the fox jumps over the dog}
+set midList [\fBlinsert\fR $oldList 1 quick]
+set newList [\fBlinsert\fR $midList end-1 lazy]
+# The old lists still exist though...
+set newerList [\fBlinsert\fR [\fBlinsert\fR $oldList end-1 quick] 1 lazy]
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), lindex(n), llength(n), lsearch(n),
+lset(n), lsort(n), lrange(n), lreplace(n),
+string(n)
+.SH KEYWORDS
+element, insert, list
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/list.n b/library/msgcat/doc/list.n
new file mode 100644
index 0000000..5705254
--- /dev/null
+++ b/library/msgcat/doc/list.n
@@ -0,0 +1,56 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH list n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+list \- Create a list
+.SH SYNOPSIS
+\fBlist \fR?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command returns a list comprised of all the \fIarg\fRs,
+or an empty string if no \fIarg\fRs are specified.
+Braces and backslashes get added as necessary, so that the \fBlindex\fR command
+may be used on the result to re-extract the original arguments, and also
+so that \fBeval\fR may be used to execute the resulting list, with
+\fIarg1\fR comprising the command's name and the other \fIarg\fRs comprising
+its arguments. \fBList\fR produces slightly different results than
+\fBconcat\fR: \fBconcat\fR removes one level of grouping before forming
+the list, while \fBlist\fR works directly from the original arguments.
+.SH EXAMPLE
+.PP
+The command
+.PP
+.CS
+\fBlist\fR a b "c d e " " f {g h}"
+.CE
+.PP
+will return
+.PP
+.CS
+\fBa b {c d e } { f {g h}}\fR
+.CE
+.PP
+while \fBconcat\fR with the same arguments will return
+.PP
+.CS
+\fBa b c d e f {g h}\fR
+.CE
+.SH "SEE ALSO"
+lappend(n), lindex(n), linsert(n), llength(n), lrange(n),
+lrepeat(n),
+lreplace(n), lsearch(n), lset(n), lsort(n)
+.SH KEYWORDS
+element, list, quoting
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/library/msgcat/doc/llength.n b/library/msgcat/doc/llength.n
new file mode 100644
index 0000000..b0ee4d9
--- /dev/null
+++ b/library/msgcat/doc/llength.n
@@ -0,0 +1,55 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH llength n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+llength \- Count the number of elements in a list
+.SH SYNOPSIS
+\fBllength \fIlist\fR
+.BE
+.SH DESCRIPTION
+.PP
+Treats \fIlist\fR as a list and returns a decimal string giving
+the number of elements in it.
+.SH EXAMPLES
+.PP
+The result is the number of elements:
+.PP
+.CS
+% \fBllength\fR {a b c d e}
+5
+% \fBllength\fR {a b c}
+3
+% \fBllength\fR {}
+0
+.CE
+.PP
+Elements are not guaranteed to be exactly words in a dictionary sense
+of course, especially when quoting is used:
+.PP
+.CS
+% \fBllength\fR {a b {c d} e}
+4
+% \fBllength\fR {a b { } c d e}
+6
+.CE
+.PP
+An empty list is not necessarily an empty string:
+.PP
+.CS
+% set var { }; puts "[string length $var],[\fBllength\fR $var]"
+1,0
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), lindex(n), linsert(n), lsearch(n),
+lset(n), lsort(n), lrange(n), lreplace(n)
+.SH KEYWORDS
+element, list, length
diff --git a/library/msgcat/doc/load.n b/library/msgcat/doc/load.n
new file mode 100644
index 0000000..c32cb65
--- /dev/null
+++ b/library/msgcat/doc/load.n
@@ -0,0 +1,180 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH load n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+load \- Load machine code and initialize new commands
+.SH SYNOPSIS
+\fBload \fIfileName\fR
+.br
+\fBload \fIfileName packageName\fR
+.br
+\fBload \fIfileName packageName interp\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command loads binary code from a file into the
+application's address space and calls an initialization procedure
+in the package to incorporate it into an interpreter. \fIfileName\fR
+is the name of the file containing the code; its exact form varies
+from system to system but on most systems it is a shared library,
+such as a \fB.so\fR file under Solaris or a DLL under Windows.
+\fIpackageName\fR is the name of the package, and is used to
+compute the name of an initialization procedure.
+\fIinterp\fR is the path name of the interpreter into which to load
+the package (see the \fBinterp\fR manual entry for details);
+if \fIinterp\fR is omitted, it defaults to the
+interpreter in which the \fBload\fR command was invoked.
+.PP
+Once the file has been loaded into the application's address space,
+one of two initialization procedures will be invoked in the new code.
+Typically the initialization procedure will add new commands to a
+Tcl interpreter.
+The name of the initialization 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_Init\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_Init\fR.
+.PP
+If the target interpreter is a safe interpreter, then the name
+of the initialization procedure will be \fIpkg\fB_SafeInit\fR
+instead of \fIpkg\fB_Init\fR.
+The \fIpkg\fB_SafeInit\fR function should be written carefully, so that it
+initializes the safe interpreter only with partial functionality provided
+by the package that is safe for use by untrusted code. For more information
+on Safe\-Tcl, see the \fBsafe\fR manual entry.
+.PP
+The initialization procedure must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_PackageInitProc\fR(
+ Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+The \fIinterp\fR argument identifies the interpreter in which the
+package is to be loaded. The initialization 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. The result of the \fBload\fR command
+will be the result returned by the initialization procedure.
+.PP
+The actual loading of a file will only be done once for each \fIfileName\fR
+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.
+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.
+.PP
+The \fBload\fR command also supports packages that are statically
+linked with the application, if those packages have been registered
+by calling the \fBTcl_StaticPackage\fR procedure.
+If \fIfileName\fR is an empty string, then \fIpackageName\fR 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 \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.
+.PP
+If \fIfileName\fR is an empty string, then \fIpackageName\fR must
+be specified.
+The \fBload\fR command first searches for a statically loaded package
+(one that has been registered by calling the \fBTcl_StaticPackage\fR
+procedure) by that name; if one is found, it is used.
+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.
+.SH "PORTABILITY ISSUES"
+.TP
+\fBWindows\fR\0\0\0\0\0
+.
+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
+.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:
+.RS
+.PP
+.CS
+\fBload\fR [file join [pwd] mylib.DLL]
+.CE
+.RE
+.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).
+.SH EXAMPLE
+.PP
+The following is a minimal extension:
+.PP
+.CS
+#include <tcl.h>
+#include <stdio.h>
+static int fooCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {
+ printf("called with %d arguments\en", objc);
+ return TCL_OK;
+}
+int Foo_Init(Tcl_Interp *interp) {
+ if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
+ return TCL_ERROR;
+ }
+ printf("creating foo command");
+ Tcl_CreateObjCommand(interp, "foo", fooCmd, NULL, NULL);
+ return TCL_OK;
+}
+.CE
+.PP
+When built into a shared/dynamic library with a suitable name
+(e.g. \fBfoo.dll\fR on Windows, \fBlibfoo.so\fR on Solaris and Linux)
+it can then be loaded into Tcl with the following:
+.PP
+.CS
+# Load the extension
+switch $tcl_platform(platform) {
+ windows {
+ \fBload\fR [file join [pwd] foo.dll]
+ }
+ unix {
+ \fBload\fR [file join [pwd] libfoo[info sharedlibextension]]
+ }
+}
+
+# Now execute the command defined by the extension
+foo
+.CE
+.SH "SEE ALSO"
+info sharedlibextension, package(n), Tcl_StaticPackage(3), safe(n)
+.SH KEYWORDS
+binary code, dynamic library, load, safe interpreter, shared library
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/library/msgcat/doc/lrange.n b/library/msgcat/doc/lrange.n
new file mode 100644
index 0000000..4f4816a
--- /dev/null
+++ b/library/msgcat/doc/lrange.n
@@ -0,0 +1,78 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH lrange n 7.4 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+lrange \- Return one or more adjacent elements from a list
+.SH SYNOPSIS
+\fBlrange \fIlist first last\fR
+.BE
+.SH DESCRIPTION
+.PP
+\fIList\fR must be a valid Tcl list. This command will
+return a new list consisting of elements
+\fIfirst\fR through \fIlast\fR, inclusive.
+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.
+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:
+.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
+.PP
+Selecting the first two elements:
+.PP
+.CS
+% \fBlrange\fR {a b c d e} 0 1
+a b
+.CE
+.PP
+Selecting the last three elements:
+.PP
+.CS
+% \fBlrange\fR {a b c d e} end-2 end
+c d e
+.CE
+.PP
+Selecting everything except the first and last element:
+.PP
+.CS
+% \fBlrange\fR {a b c d e} 1 end-1
+b c d
+.CE
+.PP
+Selecting a single element with \fBlrange\fR is not the same as doing
+so with \fBlindex\fR:
+.PP
+.CS
+% set var {some {elements to} select}
+some {elements to} select
+% lindex $var 1
+elements to
+% \fBlrange\fR $var 1 1
+{elements to}
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
+lset(n), lreplace(n), lsort(n),
+string(n)
+.SH KEYWORDS
+element, list, range, sublist
diff --git a/library/msgcat/doc/lrepeat.n b/library/msgcat/doc/lrepeat.n
new file mode 100644
index 0000000..59a1edf
--- /dev/null
+++ b/library/msgcat/doc/lrepeat.n
@@ -0,0 +1,38 @@
+'\"
+'\" 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 \fIcount \fR?\fIelement ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fBlrepeat\fR command creates a list of size \fIcount * number of
+elements\fR by repeating \fIcount\fR times the sequence of elements
+\fIelement ...\fR. \fIcount\fR must be a non-negative integer,
+\fIelement\fR can be any Tcl value. Note that \fBlrepeat 1 element ...\fR
+is identical to \fBlist element ...\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/library/msgcat/doc/lreplace.n b/library/msgcat/doc/lreplace.n
new file mode 100644
index 0000000..6e6c3ea
--- /dev/null
+++ b/library/msgcat/doc/lreplace.n
@@ -0,0 +1,86 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH lreplace n 7.4 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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 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.
+.PP
+If \fIfirst\fR is less than zero, it is considered to refer to before the
+first element of the list. For non-empty lists, the element indicated
+by \fIfirst\fR must exist or \fIfirst\fR must indicate before the
+start of the list.
+.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
+the list. If no \fIelement\fR arguments are specified, then the elements
+between \fIfirst\fR and \fIlast\fR are simply deleted. If \fIlist\fR
+is empty, any \fIelement\fR arguments are added to the end of the list.
+.SH EXAMPLES
+.PP
+Replacing an element of a list with another:
+.PP
+.CS
+% \fBlreplace\fR {a b c d e} 1 1 foo
+a foo c d e
+.CE
+.PP
+Replacing two elements of a list with three:
+.PP
+.CS
+% \fBlreplace\fR {a b c d e} 1 2 three more elements
+a three more elements d e
+.CE
+.PP
+Deleting the last element from a list in a variable:
+.PP
+.CS
+% set var {a b c d e}
+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:
+.PP
+.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"
+list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
+lset(n), lrange(n), lsort(n),
+string(n)
+.SH KEYWORDS
+element, list, replace
diff --git a/library/msgcat/doc/lreverse.n b/library/msgcat/doc/lreverse.n
new file mode 100644
index 0000000..f52db9b
--- /dev/null
+++ b/library/msgcat/doc/lreverse.n
@@ -0,0 +1,34 @@
+'\"
+'\" 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
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/lsearch.n b/library/msgcat/doc/lsearch.n
new file mode 100644
index 0000000..7835352
--- /dev/null
+++ b/library/msgcat/doc/lsearch.n
@@ -0,0 +1,220 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\" 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.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+lsearch \- See if a list contains a particular element
+.SH SYNOPSIS
+\fBlsearch \fR?\fIoptions\fR? \fIlist pattern\fR
+.BE
+.SH DESCRIPTION
+.PP
+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
+(unless the options \fB\-all\fR or \fB\-inline\fR are specified.)
+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 must have one of the values below:
+.SS "MATCHING STYLE OPTIONS"
+.PP
+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
+.
+\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\-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"
+.PP
+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
+.
+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.
+.TP
+\fB\-not\fR
+.
+This negates the sense of the match, returning the index of the first
+non-matching value in the list.
+.TP
+\fB\-start\fR\0\fIindex\fR
+.
+The list is searched starting at position \fIindex\fR.
+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.
+.SS "CONTENTS DESCRIPTION OPTIONS"
+.PP
+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.
+.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.
+.TP
+\fB\-real\fR
+.
+The list elements are to be compared as floating-point values.
+.SS "SORTED LIST OPTIONS"
+.PP
+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\-decreasing\fR
+.
+The list elements are sorted in decreasing order. This option is only
+meaningful when used with \fB\-sorted\fR.
+.TP
+\fB\-increasing\fR
+.
+The list elements are sorted in increasing order. This option is only
+meaningful when used with \fB\-sorted\fR.
+.TP
+\fB\-bisect\fR
+.VS 8.6
+Inexact search when the list elements are in sorted order. For an increasing
+list the last index where the element is less than or equal to the pattern
+is returned. For a decreasing list the last index where the element is greater
+than or equal to the pattern is returned. If the pattern is before the first
+element or the list is empty, -1 is returned.
+This option implies \fB\-sorted\fR and cannot be used with either \fB\-all\fR
+or \fB\-not\fR.
+.VE 8.6
+.SS "NESTED LIST OPTIONS"
+.PP
+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
+\fB\-index\fR is also specified, and is just a convenience short-cut.
+.SH EXAMPLES
+.PP
+Basic searching:
+.PP
+.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
+.CE
+.PP
+Using \fBlsearch\fR to filter lists:
+.PP
+.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:
+.PP
+.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:
+.PP
+.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:
+.PP
+.CS
+\fBlsearch\fR -index 1 -all -inline {{a abc} {b bcd} {c cde}} *bc*
+ \fI\(-> {a abc} {b bcd}\fR
+.CE
+.SH "SEE ALSO"
+foreach(n), list(n), lappend(n), lindex(n), linsert(n), llength(n),
+lset(n), lsort(n), lrange(n), lreplace(n),
+string(n)
+.SH KEYWORDS
+binary search, linear search,
+list, match, pattern, regular expression, search, string
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/lset.n b/library/msgcat/doc/lset.n
new file mode 100755
index 0000000..805de16
--- /dev/null
+++ b/library/msgcat/doc/lset.n
@@ -0,0 +1,146 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH lset n 8.4 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+lset \- Change an element in a list
+.SH SYNOPSIS
+\fBlset \fIvarName ?index ...? newValue\fR
+.BE
+.SH DESCRIPTION
+.PP
+The \fBlset\fR command accepts a parameter, \fIvarName\fR, which
+it interprets as the name of a variable containing a Tcl list.
+It 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.
+Finally, it accepts a new value for an element of \fIvarName\fR.
+.PP
+If no indices are presented, the command takes the form:
+.PP
+.CS
+\fBlset\fR varName newValue
+.CE
+.PP
+or
+.PP
+.CS
+\fBlset\fR varName {} newValue
+.CE
+.PP
+In this case, \fInewValue\fR replaces the old value of the variable
+\fIvarName\fR.
+.PP
+When presented with a single index, the \fBlset\fR command
+treats the content of the \fIvarName\fR variable as a Tcl list.
+It addresses the \fIindex\fR'th element in it
+(0 refers to the first element of the list).
+When interpreting the list, \fBlset\fR observes the same rules
+concerning braces and quotes and backslashes as the Tcl command
+interpreter; however, variable
+substitution and command substitution do not occur.
+The command constructs a new list in which the designated element is
+replaced with \fInewValue\fR. This new list is stored in the
+variable \fIvarName\fR, and is also the return value from the \fBlset\fR
+command.
+.PP
+If \fIindex\fR is negative or greater than the number
+of elements in \fI$varName\fR, then an error occurs.
+.PP
+If \fIindex\fR is equal to the number of elements in \fI$varName\fR,
+then the given element is appended to the list.
+.PP
+The interpretation of each simple \fIindex\fR value is the same as
+for the command \fBstring index\fR, supporting simple index
+arithmetic and indices relative to the end of the list.
+.PP
+If additional \fIindex\fR arguments are supplied, then each argument is
+used in turn to address an element within a sublist designated
+by the previous indexing operation,
+allowing the script to alter elements in sublists (or append elements
+to sublists). The command,
+.PP
+.CS
+\fBlset\fR a 1 2 newValue
+.CE
+.PP
+or
+.PP
+.CS
+\fBlset\fR a {1 2} newValue
+.CE
+.PP
+replaces element 2 of sublist 1 with \fInewValue\fR.
+.PP
+The integer appearing in each \fIindex\fR argument must be greater
+than or equal to zero. The integer appearing in each \fIindex\fR
+argument must be less than or equal to the length of the corresponding
+list. In other words, the \fBlset\fR command can change the size
+of a list only by appending an element (setting the one after the current
+end). If an index is outside the permitted range, an error is reported.
+.SH EXAMPLES
+.PP
+In each of these examples, the initial value of \fIx\fR is:
+.PP
+.CS
+set x [list [list a b c] [list d e f] [list g h i]]
+ \fI\(-> {a b c} {d e f} {g h i}\fR
+.CE
+.PP
+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.)
+.PP
+.CS
+\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
+.PP
+In the following examples, the initial value of \fIx\fR is:
+.PP
+.CS
+set x [list [list [list a b] [list c d]] \e
+ [list [list e f] [list g h]]]
+ \fI\(-> {{a b} {c d}} {{e f} {g h}}\fR
+.CE
+.PP
+The indicated return value also becomes the new value of \fIx\fR.
+.PP
+.CS
+\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),
+string(n)
+.SH KEYWORDS
+element, index, list, replace, set
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/library/msgcat/doc/lsort.n b/library/msgcat/doc/lsort.n
new file mode 100644
index 0000000..312048e
--- /dev/null
+++ b/library/msgcat/doc/lsort.n
@@ -0,0 +1,274 @@
+'\"
+'\" 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 <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.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+lsort \- Sort the elements of a list
+.SH SYNOPSIS
+\fBlsort \fR?\fIoptions\fR? \fIlist\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command sorts the elements of \fIlist\fR, returning a new
+list in sorted order. The implementation of the \fBlsort\fR command
+uses the merge\-sort algorithm which is a stable sort that has O(n log
+n) performance characteristics.
+.PP
+By default ASCII sorting is used with the result returned in
+increasing order. However, any of the following options may be
+specified before \fIlist\fR to control the sorting process (unique
+abbreviations are accepted):
+.TP
+\fB\-ascii\fR
+.
+Use string comparison with Unicode code-point collation order (the
+name is for backward-compatibility reasons.) This is the default.
+.TP
+\fB\-dictionary\fR
+.
+Use dictionary-style comparison. This is the same as \fB\-ascii\fR
+except (a) case is ignored except as a tie-breaker and (b) if two
+strings contain embedded numbers, the numbers compare as integers,
+not characters. For example, in \fB\-dictionary\fR mode, \fBbigBoy\fR
+sorts between \fBbigbang\fR and \fBbigboy\fR, and \fBx10y\fR
+sorts between \fBx9y\fR and \fBx11y\fR.
+.TP
+\fB\-integer\fR
+.
+Convert list elements to integers and use integer comparison.
+.TP
+\fB\-real\fR
+.
+Convert list elements to floating-point values and use floating comparison.
+.TP
+\fB\-command\0\fIcommand\fR
+.
+Use \fIcommand\fR as a comparison command.
+To compare two elements, evaluate a Tcl script consisting of
+\fIcommand\fR with the two elements appended as additional
+arguments. The script should return an integer less than,
+equal to, or greater than zero if the first element is to
+be considered less than, equal to, or greater than the second,
+respectively.
+.TP
+\fB\-increasing\fR
+.
+Sort the list in increasing order
+.PQ smallest "items first" .
+This is the default.
+.TP
+\fB\-decreasing\fR
+.
+Sort the list in decreasing order
+.PQ largest "items first" .
+.TP
+\fB\-indices\fR
+.
+Return a list of indices into \fIlist\fR in sorted order instead of
+the values themselves.
+.TP
+\fB\-index\0\fIindexList\fR
+.
+If this option is specified, each of the elements of \fIlist\fR must
+itself be a proper Tcl sublist (unless \fB\-stride\fR is used).
+Instead of sorting based on whole sublists, \fBlsort\fR will extract
+the \fIindexList\fR'th element from each sublist (as if the overall
+element and the \fIindexList\fR were passed to \fBlindex\fR) and sort
+based on the given element.
+For example,
+.RS
+.PP
+.CS
+\fBlsort\fR -integer -index 1 \e
+ {{First 24} {Second 18} {Third 30}}
+.CE
+.PP
+returns \fB{Second 18} {First 24} {Third 30}\fR,
+.PP
+'\"
+'\" This example is from the test suite!
+'\"
+.CS
+\fBlsort\fR -index end-1 \e
+ {{a 1 e i} {b 2 3 f g} {c 4 5 6 d h}}
+.CE
+.PP
+returns \fB{c 4 5 6 d h} {a 1 e i} {b 2 3 f g}\fR,
+and
+.PP
+.CS
+\fBlsort\fR -index {0 1} {
+ {{b i g} 12345}
+ {{d e m o} 34512}
+ {{c o d e} 54321}
+}
+.CE
+.PP
+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.)
+This option is much more efficient than using \fB\-command\fR
+to achieve the same effect.
+.RE
+.TP
+\fB\-stride\0\fIstrideLength\fR
+.
+If this option is specified, the list is treated as consisting of
+groups of \fIstrideLength\fR elements and the groups are sorted by
+either their first element or, if the \fB\-index\fR option is used,
+by the element within each group given by the first index passed to
+\fB\-index\fR (which is then ignored by \fB\-index\fR). Elements
+always remain in the same position within their group.
+.RS
+.PP
+The list length must be an integer multiple of \fIstrideLength\fR, which
+in turn must be at least 2.
+.PP
+For example,
+.PP
+.CS
+\fBlsort\fR \-stride 2 {carrot 10 apple 50 banana 25}
+.CE
+.PP
+returns
+.QW "apple 50 banana 25 carrot 10" ,
+and
+.PP
+.CS
+\fBlsort\fR \-stride 2 \-index 1 \-integer {carrot 10 apple 50 banana 25}
+.CE
+.PP
+returns
+.QW "carrot 10 banana 25 apple 50" .
+.RE
+.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.
+.TP
+\fB\-unique\fR
+.
+If this option is specified, then only the last set of duplicate
+elements found in the list will be retained. Note that duplicates are
+determined relative to the comparison used in the sort. Thus if
+\fB\-index 0\fR is used, \fB{1 a}\fR and \fB{1 b}\fR would be
+considered duplicates and only the second element, \fB{1 b}\fR, would
+be retained.
+.SH "NOTES"
+.PP
+The options to \fBlsort\fR only control what sort of comparison is
+used, and do not necessarily constrain what the values themselves
+actually are. This distinction is only noticeable when the list to be
+sorted has fewer than two elements.
+.PP
+The \fBlsort\fR command is reentrant, meaning it is safe to use as
+part of the implementation of a command used in the \fB\-command\fR
+option.
+.SH "EXAMPLES"
+.PP
+Sorting a list using ASCII sorting:
+.PP
+.CS
+\fI%\fR \fBlsort\fR {a10 B2 b1 a1 a2}
+B2 a1 a10 a2 b1
+.CE
+.PP
+Sorting a list using Dictionary sorting:
+.PP
+.CS
+\fI%\fR \fBlsort\fR -dictionary {a10 B2 b1 a1 a2}
+a1 a2 a10 b1 B2
+.CE
+.PP
+Sorting lists of integers:
+.PP
+.CS
+\fI%\fR \fBlsort\fR -integer {5 3 1 2 11 4}
+1 2 3 4 5 11
+\fI%\fR \fBlsort\fR -integer {1 2 0x5 7 0 4 -1}
+-1 0 1 2 4 0x5 7
+.CE
+.PP
+Sorting lists of floating-point numbers:
+.PP
+.CS
+\fI%\fR \fBlsort\fR -real {5 3 1 2 11 4}
+1 2 3 4 5 11
+\fI%\fR \fBlsort\fR -real {.5 0.07e1 0.4 6e-1}
+0.4 .5 6e-1 0.07e1
+.CE
+.PP
+Sorting using indices:
+.PP
+.CS
+\fI%\fR # Note the space character before the c
+\fI%\fR \fBlsort\fR {{a 5} { c 3} {b 4} {e 1} {d 2}}
+{ c 3} {a 5} {b 4} {d 2} {e 1}
+\fI%\fR \fBlsort\fR -index 0 {{a 5} { c 3} {b 4} {e 1} {d 2}}
+{a 5} {b 4} { c 3} {d 2} {e 1}
+\fI%\fR \fBlsort\fR -index 1 {{a 5} { c 3} {b 4} {e 1} {d 2}}
+{e 1} {d 2} { c 3} {b 4} {a 5}
+.CE
+.PP
+.VS 8.6
+Sorting a dictionary:
+.PP
+.CS
+\fI%\fR set d [dict create c d a b h i f g c e]
+c e a b h i f g
+\fI%\fR \fBlsort\fR -stride 2 $d
+a b c e f g h i
+.CE
+.PP
+Sorting using striding and multiple indices:
+.PP
+.CS
+\fI%\fR # Note the first index value is relative to the group
+\fI%\fR \fBlsort\fR \-stride 3 \-index {0 1} \e
+ {{Bob Smith} 25 Audi {Jane Doe} 40 Ford}
+{{Jane Doe} 40 Ford {Bob Smith} 25 Audi}
+.CE
+.VE 8.6
+.PP
+Stripping duplicate values using sorting:
+.PP
+.CS
+\fI%\fR \fBlsort\fR -unique {a b c a b c a b c}
+a b c
+.CE
+.PP
+More complex sorting using a comparison function:
+.PP
+.CS
+\fI%\fR proc compare {a b} {
+ set a0 [lindex $a 0]
+ set b0 [lindex $b 0]
+ if {$a0 < $b0} {
+ return -1
+ } elseif {$a0 > $b0} {
+ return 1
+ }
+ return [string compare [lindex $a 1] [lindex $b 1]]
+}
+\fI%\fR \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"
+list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
+lset(n), lrange(n), lreplace(n)
+.SH KEYWORDS
+element, list, order, sort
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/man.macros b/library/msgcat/doc/man.macros
new file mode 100644
index 0000000..ddd073d
--- /dev/null
+++ b/library/msgcat/doc/man.macros
@@ -0,0 +1,267 @@
+.\" The -*- nroff -*- definitions below are for supplemental macros used
+.\" in Tcl/Tk manual entries.
+.\"
+.\" .AP type name in/out ?indent?
+.\" Start paragraph describing an argument to a library procedure.
+.\" type is type of argument (int, etc.), in/out is either "in", "out",
+.\" or "in/out" to describe whether procedure reads or modifies arg,
+.\" and indent is equivalent to second arg of .IP (shouldn't ever be
+.\" needed; use .AS below instead)
+.\"
+.\" .AS ?type? ?name?
+.\" Give maximum sizes of arguments for setting tab stops. Type and
+.\" name are examples of largest possible arguments that will be passed
+.\" to .AP later. If args are omitted, default tab stops are used.
+.\"
+.\" .BS
+.\" Start box enclosure. From here until next .BE, everything will be
+.\" enclosed in one large box.
+.\"
+.\" .BE
+.\" End of box enclosure.
+.\"
+.\" .CS
+.\" Begin code excerpt.
+.\"
+.\" .CE
+.\" End code excerpt.
+.\"
+.\" .VS ?version? ?br?
+.\" Begin vertical sidebar, for use in marking newly-changed parts
+.\" of man pages. The first argument is ignored and used for recording
+.\" the version when the .VS was added, so that the sidebars can be
+.\" found and removed when they reach a certain age. If another argument
+.\" is present, then a line break is forced before starting the sidebar.
+.\"
+.\" .VE
+.\" End of vertical sidebar.
+.\"
+.\" .DS
+.\" Begin an indented unfilled display.
+.\"
+.\" .DE
+.\" End of indented unfilled display.
+.\"
+.\" .SO ?manpage?
+.\" Start of list of standard options for a Tk widget. The manpage
+.\" argument defines where to look up the standard options; if
+.\" omitted, defaults to "options". The options follow on successive
+.\" lines, in three columns separated by tabs.
+.\"
+.\" .SE
+.\" End of list of standard options for a Tk widget.
+.\"
+.\" .OP cmdName dbName dbClass
+.\" Start of description of a specific option. cmdName gives the
+.\" option's name as specified in the class command, dbName gives
+.\" the option's name in the option database, and dbClass gives
+.\" the option's class in the option database.
+.\"
+.\" .UL arg1 arg2
+.\" Print arg1 underlined, then print arg2 normally.
+.\"
+.\" .QW arg1 ?arg2?
+.\" Print arg1 in quotes, then arg2 normally (for trailing punctuation).
+.\"
+.\" .PQ arg1 ?arg2?
+.\" Print an open parenthesis, arg1 in quotes, then arg2 normally
+.\" (for trailing punctuation) and then a closing parenthesis.
+.\"
+.\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
+.if t .wh -1.3i ^B
+.nr ^l \n(.l
+.ad b
+.\" # Start an argument description
+.de AP
+.ie !"\\$4"" .TP \\$4
+.el \{\
+. ie !"\\$2"" .TP \\n()Cu
+. el .TP 15
+.\}
+.ta \\n()Au \\n()Bu
+.ie !"\\$3"" \{\
+\&\\$1 \\fI\\$2\\fP (\\$3)
+.\".b
+.\}
+.el \{\
+.br
+.ie !"\\$2"" \{\
+\&\\$1 \\fI\\$2\\fP
+.\}
+.el \{\
+\&\\fI\\$1\\fP
+.\}
+.\}
+..
+.\" # define tabbing values for .AP
+.de AS
+.nr )A 10n
+.if !"\\$1"" .nr )A \\w'\\$1'u+3n
+.nr )B \\n()Au+15n
+.\"
+.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
+.nr )C \\n()Bu+\\w'(in/out)'u+2n
+..
+.AS Tcl_Interp Tcl_CreateInterp in/out
+.\" # BS - start boxed text
+.\" # ^y = starting y location
+.\" # ^b = 1
+.de BS
+.br
+.mk ^y
+.nr ^b 1u
+.if n .nf
+.if n .ti 0
+.if n \l'\\n(.lu\(ul'
+.if n .fi
+..
+.\" # BE - end boxed text (draw box now)
+.de BE
+.nf
+.ti 0
+.mk ^t
+.ie n \l'\\n(^lu\(ul'
+.el \{\
+.\" Draw four-sided box normally, but don't draw top of
+.\" box if the box started on an earlier page.
+.ie !\\n(^b-1 \{\
+\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.el \}\
+\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.\}
+.fi
+.br
+.nr ^b 0
+..
+.\" # VS - start vertical sidebar
+.\" # ^Y = starting y location
+.\" # ^v = 1 (for troff; for nroff this doesn't matter)
+.de VS
+.if !"\\$2"" .br
+.mk ^Y
+.ie n 'mc \s12\(br\s0
+.el .nr ^v 1u
+..
+.\" # VE - end of vertical sidebar
+.de VE
+.ie n 'mc
+.el \{\
+.ev 2
+.nf
+.ti 0
+.mk ^t
+\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
+.sp -1
+.fi
+.ev
+.\}
+.nr ^v 0
+..
+.\" # Special macro to handle page bottom: finish off current
+.\" # box/sidebar if in box/sidebar mode, then invoked standard
+.\" # page bottom macro.
+.de ^B
+.ev 2
+'ti 0
+'nf
+.mk ^t
+.if \\n(^b \{\
+.\" Draw three-sided box if this is the box's first page,
+.\" draw two sides but no top otherwise.
+.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.\}
+.if \\n(^v \{\
+.nr ^x \\n(^tu+1v-\\n(^Yu
+\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
+.\}
+.bp
+'fi
+.ev
+.if \\n(^b \{\
+.mk ^y
+.nr ^b 2
+.\}
+.if \\n(^v \{\
+.mk ^Y
+.\}
+..
+.\" # DS - begin display
+.de DS
+.RS
+.nf
+.sp
+..
+.\" # DE - end display
+.de DE
+.fi
+.RE
+.sp
+..
+.\" # SO - start of list of standard options
+.de SO
+'ie '\\$1'' .ds So \\fBoptions\\fR
+'el .ds So \\fB\\$1\\fR
+.SH "STANDARD OPTIONS"
+.LP
+.nf
+.ta 5.5c 11c
+.ft B
+..
+.\" # SE - end of list of standard options
+.de SE
+.fi
+.ft R
+.LP
+See the \\*(So manual entry for details on the standard options.
+..
+.\" # OP - start of full description for a single option
+.de OP
+.LP
+.nf
+.ta 4c
+Command-Line Name: \\fB\\$1\\fR
+Database Name: \\fB\\$2\\fR
+Database Class: \\fB\\$3\\fR
+.fi
+.IP
+..
+.\" # CS - begin code excerpt
+.de CS
+.RS
+.nf
+.ta .25i .5i .75i 1i
+..
+.\" # CE - end code excerpt
+.de CE
+.fi
+.RE
+..
+.\" # UL - underline word
+.de UL
+\\$1\l'|0\(ul'\\$2
+..
+.\" # QW - apply quotation marks to word
+.de QW
+.ie '\\*(lq'"' ``\\$1''\\$2
+.\"" fix emacs highlighting
+.el \\*(lq\\$1\\*(rq\\$2
+..
+.\" # PQ - apply parens and quotation marks to word
+.de PQ
+.ie '\\*(lq'"' (``\\$1''\\$2)\\$3
+.\"" fix emacs highlighting
+.el (\\*(lq\\$1\\*(rq\\$2)\\$3
+..
+.\" # QR - quoted range
+.de QR
+.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3
+.\"" fix emacs highlighting
+.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3
+..
+.\" # MT - "empty" string
+.de MT
+.QW ""
+..
diff --git a/library/msgcat/doc/mathfunc.n b/library/msgcat/doc/mathfunc.n
new file mode 100644
index 0000000..14b448e
--- /dev/null
+++ b/library/msgcat/doc/mathfunc.n
@@ -0,0 +1,305 @@
+'\"
+'\" 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
+\fB::tcl::mathfunc::entier\fR \fIarg\fR
+.br
+\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
+.
+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.
+.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,
+approximately
+.QW "\fBsqrt\fR [\fBexpr\fR {\fIx\fB*\fIx\fB+\fIy\fB*\fIy\fR}]"
+except for being more numerically stable when the two arguments have
+substantially different magnitudes.
+.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 the \fBwordSize\fR
+element of the \fBtcl_platform\fR array.
+.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
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/library/msgcat/doc/mathop.n b/library/msgcat/doc/mathop.n
new file mode 100644
index 0000000..ac2ebc1
--- /dev/null
+++ b/library/msgcat/doc/mathop.n
@@ -0,0 +1,310 @@
+.\"
+.\" 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 (i.e., remainder) of the first argument
+with respect to the second.
+Each \fInumber\fR must have an integral value.
+Also, the sign of the result will be the same as the sign of the second
+\fInumber\fR, which must not be zero.
+.RS
+.PP
+Note that Tcl defines this operation exactly even for negative numbers, so
+that the following command returns a true value (omitting the namespace for
+clarity):
+.PP
+.CS
+\fB==\fR [\fB*\fR [\fB/\fI x y\fR] \fIy\fR] [\fB\-\fI x\fR [\fB%\fI x y\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
+.PP
+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.
+.PP
+.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
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/memory.n b/library/msgcat/doc/memory.n
new file mode 100644
index 0000000..f82c5b4
--- /dev/null
+++ b/library/msgcat/doc/memory.n
@@ -0,0 +1,115 @@
+'\"
+'\" Copyright (c) 1992-1999 by Karl Lehenbauer and Mark Diekhans
+'\" Copyright (c) 2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.so man.macros
+.TH memory n 8.1 Tcl "Tcl Built-In Commands"
+.BS
+.SH NAME
+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
+debugging capabilities. The memory command has several suboptions, which are
+described below. It is only available when Tcl has been compiled with
+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.
+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
+\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.
+.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
+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 \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\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
+of memory activity before a problem occurs, judicious use of this option
+can reduce the slowdown caused by tracing (and the amount of trace information
+produced), if you can identify a number of allocations that occur before
+the problem sets in. The current number of memory allocations that have
+occurred since Tcl started is printed on a guard zone failure.
+.TP
+\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
+allocated by \fBckalloc\fR. This has a large performance impact and
+should only be used when overwrite problems are strongly suspected.
+The advantage of enabling memory validation is that a guard zone
+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
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/library/msgcat/doc/msgcat.n b/library/msgcat/doc/msgcat.n
new file mode 100644
index 0000000..d389757
--- /dev/null
+++ b/library/msgcat/doc/msgcat.n
@@ -0,0 +1,355 @@
+'\"
+'\" Copyright (c) 1998 Mark Harrison.
+'\"
+'\" 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 "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.5\fR
+.sp
+\fBpackage require msgcat 1.4.2\fR
+.sp
+\fB::msgcat::mc \fIsrc-string\fR ?\fIarg arg ...\fR?
+.sp
+\fB::msgcat::mcmax ?\fIsrc-string src-string ...\fR?
+.sp
+\fB::msgcat::mclocale \fR?\fInewLocale\fR?
+.sp
+\fB::msgcat::mcpreferences\fR
+.sp
+\fB::msgcat::mcload \fIdirname\fR
+.sp
+\fB::msgcat::mcset \fIlocale src-string \fR?\fItranslate-string\fR?
+.sp
+\fB::msgcat::mcmset \fIlocale src-trans-list\fR
+.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
+.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
+the message catalog.
+.PP
+Use of the message catalog is optional by any application
+or package, but is encouraged if the application or package
+wishes to be enabled for multi-lingual applications.
+.SH COMMANDS
+.TP
+\fB::msgcat::mc \fIsrc-string\fR ?\fIarg arg ...\fR?
+.
+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
+none is found, it will search in the parent of the current namespace,
+and so on until it reaches the global namespace. If no translation
+string exists, \fB::msgcat::mcunknown\fR is called and the string
+returned from \fB::msgcat::mcunknown\fR is returned.
+.PP
+\fB::msgcat::mc\fR is the main function used to localize an
+application. Instead of using an English string directly, an
+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
+of the longest translated string. This is useful when designing
+localized GUIs, which may require that all buttons, for example, be a
+fixed width (which will be the width of the widest button).
+.TP
+\fB::msgcat::mclocale \fR?\fInewLocale\fR?
+.
+This function sets the locale to \fInewLocale\fR. If \fInewLocale\fR
+is omitted, the current locale is returned, otherwise the current locale
+is set to \fInewLocale\fR. msgcat stores and compares the locale in a
+case-insensitive manner, and returns locales in lowercase.
+The initial locale is determined by the locale specified in
+the user's environment. See \fBLOCALE SPECIFICATION\fR
+below for a description of the locale string format.
+.TP
+\fB::msgcat::mcpreferences\fR
+.
+Returns an ordered list of the locales preferred by
+the user, based on the user's language specification.
+The list is ordered from most specific to least
+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.
+.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
+.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
+encoded form, or by use of the backslash-u quoting recognized by Tcl
+evaluation. The number of message files which matched the specification
+and were loaded is returned.
+.TP
+\fB::msgcat::mcset \fIlocale src-string \fR?\fItranslate-string\fR?
+.
+Sets the translation for \fIsrc-string\fR to \fItranslate-string\fR
+in the specified \fIlocale\fR and the current namespace. If
+\fItranslate-string\fR is not specified, \fIsrc-string\fR is used
+for both. The function returns \fItranslate-string\fR.
+.TP
+\fB::msgcat::mcmset \fIlocale src-trans-list\fR
+.
+Sets the translation for multiple source strings in
+\fIsrc-trans-list\fR in the specified \fIlocale\fR and the current
+namespace.
+\fIsrc-trans-list\fR must have an even number of elements and is in
+the form {\fIsrc-string translate-string\fR ?\fIsrc-string
+translate-string ...\fR?} \fB::msgcat::mcmset\fR can be significantly
+faster than multiple invocations of \fB::msgcat::mcset\fR. The function
+returns the number of translations set.
+.TP
+\fB::msgcat::mcunknown \fIlocale src-string\fR
+.
+This routine is called by \fB::msgcat::mc\fR in the case when
+a translation for \fIsrc-string\fR is not defined in the
+current locale. The default action is to return
+\fIsrc-string\fR. This procedure can be redefined by the
+application, for example to log error messages for each unknown
+string. The \fB::msgcat::mcunknown\fR procedure is invoked at the
+same stack context as the call to \fB::msgcat::mc\fR. The return value
+of \fB::msgcat::mcunknown\fR is used as the return value for the call
+to \fB::msgcat::mc\fR.
+.SH "LOCALE SPECIFICATION"
+.PP
+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
+.QW _ .
+The country and language
+codes are specified in standards ISO-639 and ISO-3166.
+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,
+\fBenv(LC_MESSAGES)\fR, and \fBenv(LANG)\fR are examined in order.
+The first of them to have a non-empty value is used to determine the
+initial locale. The value is parsed according to the XPG4 pattern
+.PP
+.CS
+language[_country][.codeset][@modifier]
+.CE
+.PP
+to extract its parts. The initial locale is then set by calling
+\fB::msgcat::mclocale\fR with the argument
+.PP
+.CS
+language[_country][_modifier]
+.CE
+.PP
+On Windows, if none of those environment variables is set, msgcat will
+attempt to extract locale information from the
+registry. If all these attempts to discover an initial locale
+from the user's environment fail, msgcat defaults to an initial
+locale of
+.QW C .
+.PP
+When a locale is specified by the user, a
+.QW "best match"
+search is performed during string translation. For example, if a user
+specifies
+en_GB_Funky, the locales
+.QW en_GB_Funky ,
+.QW en_GB ,
+.QW en
+and
+.MT
+(the empty string)
+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
+to the namespace from which they were added. This allows
+multiple packages to use the same strings without fear
+of collisions with other packages. It also allows the
+source string to be shorter and less prone to typographical
+error.
+.PP
+For example, executing the code
+.PP
+.CS
+\fB::msgcat::mcset\fR en hello "hello from ::"
+namespace eval foo {
+ \fB::msgcat::mcset\fR en hello "hello from ::foo"
+}
+puts [\fB::msgcat::mc\fR hello]
+namespace eval foo {puts [\fB::msgcat::mc\fR hello]}
+.CE
+.PP
+will print
+.PP
+.CS
+hello from ::
+hello from ::foo
+.CE
+.PP
+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
+.QW inherit
+messages from their parent namespace.
+.PP
+For example, executing (in the
+.QW en
+locale) the code
+.PP
+.CS
+\fB::msgcat::mcset\fR en m1 ":: message1"
+\fB::msgcat::mcset\fR en m2 ":: message2"
+\fB::msgcat::mcset\fR en m3 ":: message3"
+namespace eval ::foo {
+ \fB::msgcat::mcset\fR en m2 "::foo message2"
+ \fB::msgcat::mcset\fR en m3 "::foo message3"
+}
+namespace eval ::foo::bar {
+ \fB::msgcat::mcset\fR en m3 "::foo::bar message3"
+}
+namespace import \fB::msgcat::mc\fR
+puts "[\fBmc\fR m1]; [\fBmc\fR m2]; [\fBmc\fR m3]"
+namespace eval ::foo {puts "[\fBmc\fR m1]; [\fBmc\fR m2]; [\fBmc\fR m3]"}
+namespace eval ::foo::bar {puts "[\fBmc\fR m1]; [\fBmc\fR m2]; [\fBmc\fR m3]"}
+.CE
+.PP
+will print
+.PP
+.CS
+:: message1; :: message2; :: message3
+:: message1; ::foo message2; ::foo message3
+:: message1; ::foo message2; ::foo::bar message3
+.CE
+.SH "LOCATION AND FORMAT OF MESSAGE FILES"
+.PP
+Message files can be located in any directory, subject
+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
+.QW .msg .
+For example:
+.PP
+.CS
+es.msg \(em spanish
+en_gb.msg \(em United Kingdom English
+.CE
+.PP
+\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.
+.IP [3]
+The file contains a series of calls to \fBmcset\fR and
+\fBmcmset\fR, setting the necessary translation strings
+for the language, likely enclosed in a \fBnamespace eval\fR
+so that all source strings are tied to the namespace of
+the package. For example, a short \fBes.msg\fR might contain:
+.PP
+.CS
+namespace eval ::mypackage {
+ \fB::msgcat::mcset\fR es "Free Beer!" "Cerveza Gracias!"
+}
+.CE
+.SH "RECOMMENDED MESSAGE SETUP FOR PACKAGES"
+.PP
+If a package is installed into a subdirectory of the
+\fBtcl_pkgPath\fR and loaded via \fBpackage require\fR, the
+following procedure is recommended.
+.IP [1]
+During package installation, create a subdirectory
+\fBmsgs\fR under your package directory.
+.IP [2]
+Copy your *.msg files into that directory.
+.IP [3]
+Add the following command to your package initialization script:
+.PP
+.CS
+# load language files, stored in msgs subdirectory
+\fB::msgcat::mcload\fR [file join [file dirname [info script]] msgs]
+.CE
+.SH "POSITIONAL CODES FOR FORMAT AND SCAN COMMANDS"
+.PP
+It is possible that a message string used as an argument
+to \fBformat\fR might have positionally dependent parameters that
+might need to be repositioned. For example, it might be
+syntactically desirable to rearrange the sentence structure
+while translating.
+.PP
+.CS
+format "We produced %d units in location %s" $num $city
+format "In location %s we produced %d units" $city $num
+.CE
+.PP
+This can be handled by using the positional
+parameters:
+.PP
+.CS
+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
+extract values from internationalized strings. Note that it is not
+necessary to pass the output of \fB::msgcat::mc\fR to \fBformat\fR
+directly; by passing the values to substitute in as arguments, the
+formatting substitution is done directly.
+.PP
+.CS
+\fBmsgcat::mc\fR {Produced %1$d at %2$s} $num $city
+# ... where that key is mapped to one of the
+# human-oriented versions by \fBmsgcat::mcset\fR
+.CE
+.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
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/library/msgcat/doc/my.n b/library/msgcat/doc/my.n
new file mode 100644
index 0000000..b5afc67
--- /dev/null
+++ b/library/msgcat/doc/my.n
@@ -0,0 +1,56 @@
+'\"
+'\" Copyright (c) 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 my n 0.1 TclOO "TclOO Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+my \- invoke any method of current object
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBmy\fI methodName\fR ?\fIarg ...\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBmy\fR command is used to allow methods of objects to invoke any method
+of the object (or its class). In particular, the set of valid values for
+\fImethodName\fR is the set of all methods supported by an object and its
+superclasses, including those that are not exported. The object upon which the
+method is invoked is always the one that is the current context of the method
+(i.e. the object that is returned by \fBself object\fR) from which the
+\fBmy\fR command is invoked.
+.PP
+Each object has its own \fBmy\fR command, contained in its instance namespace.
+.SH EXAMPLES
+.PP
+This example shows basic use of \fBmy\fR to use the \fBvariables\fR method of
+the \fBoo::object\fR class, which is not publicly visible by default:
+.PP
+.CS
+oo::class create c {
+ method count {} {
+ \fBmy\fR variable counter
+ print [incr counter]
+ }
+}
+c create o
+o count \fI\(-> prints "1"\fR
+o count \fI\(-> prints "2"\fR
+o count \fI\(-> prints "3"\fR
+.CE
+.SH "SEE ALSO"
+next(n), oo::object(n), self(n)
+.SH KEYWORDS
+method, method visibility, object, private method, public method
+
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/library/msgcat/doc/namespace.n b/library/msgcat/doc/namespace.n
new file mode 100644
index 0000000..b06d27a
--- /dev/null
+++ b/library/msgcat/doc/namespace.n
@@ -0,0 +1,969 @@
+'\"
+'\" 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.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?\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 \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
+namespace \fInamespace\fR.
+If \fInamespace\fR is not specified,
+then the children are returned for the current namespace.
+This command returns fully-qualified names,
+which start with a double colon (\fB::\fR).
+If the optional \fIpattern\fR is given,
+then this command returns only the names that match the glob-style pattern.
+The actual pattern used is determined as follows:
+a pattern that starts with double colon (\fB::\fR) is used directly,
+otherwise the namespace \fInamespace\fR
+(or the fully-qualified name of the current namespace)
+is prepended onto the pattern.
+.TP
+\fBnamespace code \fIscript\fR
+.
+Captures the current namespace context for later execution
+of the script \fIscript\fR.
+It returns a new script in which \fIscript\fR has been wrapped
+in a \fBnamespace inscope\fR command.
+The new script has two important properties.
+First, it can be evaluated in any namespace and will cause
+\fIscript\fR to be evaluated in the current namespace
+(the one where the \fBnamespace code\fR command was invoked).
+Second, additional arguments can be appended to the resulting script
+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 [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
+\fB::namespace eval ::a::b {foo bar x y}\fR.
+This command is needed because
+extensions like Tk normally execute callback scripts
+in the global namespace.
+A scoped command captures a command together with its namespace context
+in a way that allows it to be executed properly later.
+See the section \fBSCOPED SCRIPTS\fR for some examples
+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
+.MT
+(i.e., an empty string),
+but this command returns \fB::\fR for the global namespace
+as a convenience to programmers.
+.TP
+\fBnamespace delete \fR?\fInamespace namespace ...\fR?
+.
+Each namespace \fInamespace\fR is deleted
+and all variables, procedures, and child namespaces
+contained in the namespace are deleted.
+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 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?
+.
+Creates and manipulates a command that is formed out of an ensemble of
+subcommands. See the section \fBENSEMBLES\fR below for further
+details.
+.TP
+\fBnamespace eval\fR \fInamespace arg\fR ?\fIarg ...\fR?
+.
+Activates a namespace called \fInamespace\fR and evaluates some code
+in that context.
+If the namespace does not already exist, it is created.
+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.
+.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
+context, returns \fB0\fR otherwise.
+.TP
+\fBnamespace export \fR?\fB\-clear\fR? ?\fIpattern pattern ...\fR?
+.
+Specifies which commands are exported from a namespace.
+The exported commands are those that can be later imported
+into another namespace using a \fBnamespace import\fR command.
+Both commands defined in a namespace and
+commands the namespace has previously imported
+can be exported by a namespace.
+The commands do not have to be defined
+at the time the \fBnamespace export\fR command is executed.
+Each \fIpattern\fR may contain glob-style special characters,
+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 \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 \fB\-clear\fR flag is not given,
+this command returns the namespace's current export list.
+.TP
+\fBnamespace forget \fR?\fIpattern pattern ...\fR?
+.
+Removes previously imported commands from a namespace.
+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
+.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
+.QW "simple pattern"
+this command deletes the matching commands of the
+current namespace that were imported from a different namespace.
+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.
+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, 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).
+.RS
+.PP
+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
+at the end of the qualified name.
+Glob characters may not appear in a namespace name.
+When the namespace name is not fully qualified (i.e., does not start
+with a namespace separator) it is resolved as a namespace name in the
+way described in the \fBNAME RESOLUTION\fR section; it is an error if
+no namespace with that name can be found.
+.PP
+All the commands that match a \fIpattern\fR string
+and which are currently exported from their namespace
+are added to the current namespace.
+This is done by creating a new command in the current namespace
+that points to the exported command in its original namespace;
+when the new imported command is called, it invokes the exported command.
+This command normally returns an error
+if an imported command conflicts with an existing command.
+However, if the \fB\-force\fR option is given,
+imported commands will silently replace existing commands.
+The \fBnamespace import\fR command has snapshot semantics:
+that is, only requested commands that are currently defined
+in the exporting namespace are imported.
+In other words, you can import only the commands that are in a namespace
+at the time when the \fBnamespace import\fR command is executed.
+If another command is defined and exported in this namespace later on,
+it will not be imported.
+.RE
+.TP
+\fBnamespace inscope\fR \fInamespace\fR \fIscript\fR ?\fIarg ...\fR?
+.
+Executes a script in the context of the specified \fInamespace\fR.
+This command is not expected to be used directly by programmers;
+calls to it are generated implicitly when applications
+use \fBnamespace code\fR commands to create callback scripts
+that the applications then register with, e.g., Tk widgets.
+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.
+.RS
+.PP
+.CS
+\fBnamespace inscope ::foo $script $x $y $z\fR
+.CE
+.PP
+is equivalent to
+.PP
+.CS
+\fBnamespace eval ::foo [concat $script [list $x $y $z]]\fR
+.CE
+.PP
+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
+to which the imported command \fIcommand\fR refers.
+When a command is imported into a namespace,
+a new command is created in that namespace
+that points to the actual command in the exporting namespace.
+If a command is imported into a sequence of namespaces
+\fIa, b,...,n\fR where each successive namespace
+just imports the command from the previous namespace,
+this command returns the fully-qualified name of the original command
+in the first namespace, \fIa\fR.
+If \fIcommand\fR does not refer to an imported command,
+the command's own fully-qualified name is returned.
+.TP
+\fBnamespace parent\fR ?\fInamespace\fR?
+.
+Returns the fully-qualified name of the parent namespace
+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?
+.
+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.
+.TP
+\fBnamespace qualifiers\fR \fIstring\fR
+.
+Returns any leading namespace qualifiers for \fIstring\fR.
+Qualifiers are namespace names separated by double colons (\fB::\fR).
+For the \fIstring\fR \fB::foo::bar::x\fR,
+this command returns \fB::foo::bar\fR,
+and for \fB::\fR it returns an empty string.
+This command is the complement of the \fBnamespace tail\fR command.
+Note that it does not check whether the
+namespace names are, in fact,
+the names of currently defined namespaces.
+.TP
+\fBnamespace tail\fR \fIstring\fR
+.
+Returns the simple name at the end of a qualified string.
+Qualifiers are namespace names separated by double colons (\fB::\fR).
+For the \fIstring\fR \fB::foo::bar::x\fR,
+this command returns \fBx\fR,
+and for \fB::\fR it returns an empty string.
+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...
+.
+This command arranges for zero 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 the current namespace, the namespace's path nor in
+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 ?\fB\-command\fR? ?\fB\-variable\fR? \fIname\fR
+.
+Looks up \fIname\fR as either a command or variable
+and returns its fully-qualified name.
+For example, if \fIname\fR does not exist in the current namespace
+but does exist in the global namespace,
+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
+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
+the rules regarding name resolution.
+.SH "WHAT IS A NAMESPACE?"
+.PP
+A namespace is a collection of commands and variables.
+It encapsulates the commands and variables to ensure that they
+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.
+The \fBnamespace eval\fR command lets you create new namespaces.
+For example,
+.PP
+.CS
+\fBnamespace eval\fR Counter {
+ \fBnamespace export\fR bump
+ variable num 0
+
+ proc bump {} {
+ variable num
+ incr num
+ }
+}
+.CE
+.PP
+creates a new namespace containing the variable \fBnum\fR and
+the procedure \fBbump\fR.
+The commands and variables in this namespace are separate from
+other commands and variables in the same program.
+If there is a command named \fBbump\fR in the global namespace,
+for example, it will be different from the command \fBbump\fR
+in the \fBCounter\fR namespace.
+.PP
+Namespace variables resemble global variables in Tcl.
+They exist outside of the procedures in a namespace
+but can be accessed in a procedure via the \fBvariable\fR command,
+as shown in the example above.
+.PP
+Namespaces are dynamic.
+You can add and delete commands and variables at any time,
+so you can build up the contents of a
+namespace over time using a series of \fBnamespace eval\fR commands.
+For example, the following series of commands has the same effect
+as the namespace definition shown above:
+.PP
+.CS
+\fBnamespace eval\fR Counter {
+ variable num 0
+ proc bump {} {
+ variable num
+ return [incr num]
+ }
+}
+\fBnamespace eval\fR Counter {
+ proc test {args} {
+ return $args
+ }
+}
+\fBnamespace eval\fR Counter {
+ rename test ""
+}
+.CE
+.PP
+Note that the \fBtest\fR procedure is added to the \fBCounter\fR namespace,
+and later removed via the \fBrename\fR command.
+.PP
+Namespaces can have other namespaces within them,
+so they nest hierarchically.
+A nested namespace is encapsulated inside its parent namespace
+and can not interfere with other namespaces.
+.SH "QUALIFIED NAMES"
+.PP
+Each namespace has a textual name such as
+\fBhistory\fR or \fB::safe::interp\fR.
+Since namespaces may nest,
+qualified names are used to refer to
+commands, variables, and child namespaces contained inside namespaces.
+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
+.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,
+which in turn is a child of the global namespace, \fB::\fR.
+.PP
+If you want to access commands and variables from another namespace,
+you must use some extra syntax.
+Names must be qualified by the namespace that contains them.
+From the global namespace,
+we might access the \fBCounter\fR procedures like this:
+.PP
+.CS
+Counter::bump 5
+Counter::Reset
+.CE
+.PP
+We could access the current count like this:
+.PP
+.CS
+puts "count = $Counter::num"
+.CE
+.PP
+When one namespace contains another, you may need more than one
+qualifier to reach its elements.
+If we had a namespace \fBFoo\fR that contained the namespace \fBCounter\fR,
+you could invoke its \fBbump\fR procedure
+from the global namespace like this:
+.PP
+.CS
+Foo::Counter::bump 3
+.CE
+.PP
+You can also use qualified names when you create and rename commands.
+For example, you could add a procedure to the \fBFoo\fR
+namespace like this:
+.PP
+.CS
+proc Foo::Test {args} {return $args}
+.CE
+.PP
+And you could move the same procedure to another namespace like this:
+.PP
+.CS
+rename Foo::Test Bar::Test
+.CE
+.PP
+There are a few remaining points about qualified names
+that we should cover.
+Namespaces have nonempty names except for the global namespace.
+\fB::\fR is disallowed in simple command, variable, and namespace names
+except as a namespace separator.
+Extra colons in any separator part of a qualified name are ignored;
+i.e. two or more colons are treated as a namespace separator.
+A trailing \fB::\fR in a qualified variable or command name
+refers to the variable or command named {}.
+However, a trailing \fB::\fR in a qualified namespace name is ignored.
+.SH "NAME RESOLUTION"
+.PP
+In general, all Tcl commands that take variable and command names
+support qualified names.
+This means you can give qualified names to such commands as
+\fBset\fR, \fBproc\fR, \fBrename\fR, and \fBinterp alias\fR.
+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 basic rules for looking it up:
+.IP \(bu
+\fBVariable names\fR are always resolved by looking first in the current
+namespace, and then in the global namespace.
+.IP \(bu
+\fBCommand names\fR are 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 appropriate \fBnamespace unknown\fR handler.)
+.IP \(bu
+\fBNamespace names\fR are always resolved by looking in only the current
+namespace.
+.PP
+In the following example,
+.PP
+.CS
+set traceLevel 0
+\fBnamespace eval\fR Debug {
+ printTrace $traceLevel
+}
+.CE
+.PP
+Tcl looks for \fBtraceLevel\fR in the namespace \fBDebug\fR
+and then in the global namespace.
+It looks up the command \fBprintTrace\fR in the same way.
+If a variable or command name is not found in either context,
+the name is undefined.
+To make this point absolutely clear, consider the following example:
+.PP
+.CS
+set traceLevel 0
+\fBnamespace eval\fR Foo {
+ variable traceLevel 3
+
+ \fBnamespace eval\fR Debug {
+ printTrace $traceLevel
+ }
+}
+.CE
+.PP
+Here Tcl looks for \fBtraceLevel\fR first in the namespace \fBFoo::Debug\fR.
+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.
+.PP
+You can use the \fBnamespace which\fR command to clear up any question
+about name resolution.
+For example, the command:
+.PP
+.CS
+\fBnamespace eval\fR Foo::Debug {\fBnamespace which\fR \-variable traceLevel}
+.CE
+.PP
+returns \fB::traceLevel\fR.
+On the other hand, the command,
+.PP
+.CS
+\fBnamespace eval\fR Foo {\fBnamespace which\fR \-variable traceLevel}
+.CE
+.PP
+returns \fB::Foo::traceLevel\fR.
+.PP
+As mentioned above,
+namespace names are looked up differently
+than the names of variables and commands.
+Namespace names are always resolved in the current namespace.
+This means, for example,
+that a \fBnamespace eval\fR command that creates a new namespace
+always creates a child of the current namespace
+unless the new namespace name begins with \fB::\fR.
+.PP
+Tcl has no access control to limit what variables, commands,
+or namespaces you can reference.
+If you provide a qualified name that resolves to an element
+by the name resolution rule above,
+you can access the element.
+.PP
+You can access a namespace variable
+from a procedure in the same namespace
+by using the \fBvariable\fR command.
+Much like the \fBglobal\fR command,
+this creates a local link to the namespace variable.
+If necessary, it also creates the variable in the current namespace
+and initializes it.
+Note that the \fBglobal\fR command only creates links
+to variables in the global namespace.
+It is not necessary to use a \fBvariable\fR command
+if you always refer to the namespace variable using an
+appropriate qualified name.
+.SH "IMPORTING COMMANDS"
+.PP
+Namespaces are often used to represent libraries.
+Some library commands are used so frequently
+that it is a nuisance to type their qualified names.
+For example, suppose that all of the commands in a package
+like BLT are contained in a namespace called \fBBlt\fR.
+Then you might access these commands like this:
+.PP
+.CS
+Blt::graph .g \-background red
+Blt::table . .g 0,0
+.CE
+.PP
+If you use the \fBgraph\fR and \fBtable\fR commands frequently,
+you may want to access them without the \fBBlt::\fR prefix.
+You can do this by importing the commands into the current namespace,
+like this:
+.PP
+.CS
+\fBnamespace import\fR Blt::*
+.CE
+.PP
+This adds all exported commands from the \fBBlt\fR namespace
+into the current namespace context, so you can write code like this:
+.PP
+.CS
+graph .g \-background red
+table . .g 0,0
+.CE
+.PP
+The \fBnamespace import\fR command only imports commands
+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 do not know what you will get.
+It is better to import just the specific commands you need.
+For example, the command
+.PP
+.CS
+\fBnamespace import\fR Blt::graph Blt::table
+.CE
+.PP
+imports only the \fBgraph\fR and \fBtable\fR commands into the
+current context.
+.PP
+If you try to import a command that already exists, you will get an
+error. This prevents you from importing the same command from two
+different packages. But from time to time (perhaps when debugging),
+you may want to get around this restriction. You may want to
+reissue the \fBnamespace import\fR command to pick up new commands
+that have appeared in a namespace. In that case, you can use the
+\fB\-force\fR option, and existing commands will be silently overwritten:
+.PP
+.CS
+\fBnamespace import\fR \-force Blt::graph Blt::table
+.CE
+.PP
+If for some reason, you want to stop using the imported commands,
+you can remove them with a \fBnamespace forget\fR command, like this:
+.PP
+.CS
+\fBnamespace forget\fR Blt::*
+.CE
+.PP
+This searches the current namespace for any commands imported from \fBBlt\fR.
+If it finds any, it removes them. Otherwise, it does nothing.
+After this, the \fBBlt\fR commands must be accessed with the \fBBlt::\fR
+prefix.
+.PP
+When you delete a command from the exporting namespace like this:
+.PP
+.CS
+rename Blt::graph ""
+.CE
+.PP
+the command is automatically removed from all namespaces that import it.
+.SH "EXPORTING COMMANDS"
+You can export commands from a namespace like this:
+.PP
+.CS
+\fBnamespace eval\fR Counter {
+ \fBnamespace export\fR bump reset
+ variable Num 0
+ variable Max 100
+
+ proc bump {{by 1}} {
+ variable Num
+ incr Num $by
+ Check
+ return $Num
+ }
+ proc reset {} {
+ variable Num
+ set Num 0
+ }
+ proc Check {} {
+ variable Num
+ variable Max
+ if {$Num > $Max} {
+ error "too high!"
+ }
+ }
+}
+.CE
+.PP
+The procedures \fBbump\fR and \fBreset\fR are exported,
+so they are included when you import from the \fBCounter\fR namespace,
+like this:
+.PP
+.CS
+\fBnamespace import\fR Counter::*
+.CE
+.PP
+However, the \fBCheck\fR procedure is not exported,
+so it is ignored by the import operation.
+.PP
+The \fBnamespace import\fR command only imports commands
+that were declared as exported by their namespace.
+The \fBnamespace export\fR command specifies what commands
+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 \fBtrace\fR callback into the current
+namespace:
+.PP
+.CS
+\fBnamespace eval\fR a {
+ variable b
+ proc theTraceCallback { n1 n2 op } {
+ upvar 1 $n1 var
+ puts "the value of $n1 has changed to $var"
+ return
+ }
+ 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
+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); if the first word of any target is not
+fully qualified when set, it is assumed to be relative to the
+\fIcurrent\fR namespace and changed to be exactly that (that is, it is
+always fully qualified when read). When this option is empty, the mapping
+will be from the local name of the subcommand to its fully-qualified
+name. Note that when this option is non-empty and the
+\fB\-subcommands\fR option is empty, the ensemble subcommand names
+will be exactly those words that have mappings in the dictionary.
+.TP
+\fB\-parameters\fR
+.VS 8.6
+This option gives a list of named arguments (the names being used during
+generation of error messages) that are passed by the caller of the ensemble
+between the name of the ensemble and the subcommand argument. By default, it
+is the empty list.
+.VE 8.6
+.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.
+.SH EXAMPLES
+Create a namespace containing a variable and an exported command:
+.PP
+.CS
+\fBnamespace eval\fR foo {
+ variable bar 0
+ proc grill {} {
+ variable bar
+ puts "called [incr bar] times"
+ }
+ \fBnamespace export\fR grill
+}
+.CE
+.PP
+Call the command defined in the previous example in various ways.
+.PP
+.CS
+# Direct call
+::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
+\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:
+.PP
+.CS
+puts "grill came from [\fBnamespace origin\fR grill]"
+.CE
+.PP
+Remove all imported commands from the current namespace:
+.PP
+.CS
+namespace forget {*}[namespace import]
+.CE
+.PP
+.VS 8.6
+Create an ensemble for simple working with numbers, using the
+\fB\-parameters\fR option to allow the operator to be put between the first
+and second arguments.
+.PP
+.CS
+\fBnamespace eval\fR do {
+ \fBnamespace export\fR *
+ \fBnamespace ensemble\fR create -parameters x
+ proc plus {x y} {expr { $x + $y }}
+ proc minus {x y} {expr { $x - $y }}
+}
+
+# In use, the ensemble works like this:
+puts [do 1 plus [do 9 minus 7]]
+.CE
+.VE 8.6
+.SH "SEE ALSO"
+interp(n), upvar(n), variable(n)
+.SH KEYWORDS
+command, ensemble, exported, internal, variable
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/next.n b/library/msgcat/doc/next.n
new file mode 100644
index 0000000..d3f7937
--- /dev/null
+++ b/library/msgcat/doc/next.n
@@ -0,0 +1,203 @@
+'\"
+'\" Copyright (c) 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 next n 0.1 TclOO "TclOO Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+next \- invoke superclass method implementations
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBnext\fR ?\fIarg ...\fR?
+\fBnextto\fI class\fR ?\fIarg ...\fR?
+.fi
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBnext\fR command is used to call implementations of a method by a class,
+superclass or mixin that are overridden by the current method. It can only be
+used from within a method. It is also used within filters to indicate the
+point where a filter calls the actual implementation (the filter may decide to
+not go along the chain, and may process the results of going along the chain
+of methods as it chooses). The result of the \fBnext\fR command is the result
+of the next method in the method chain; if there are no further methods in the
+method chain, the result of \fBnext\fR will be an error. The arguments,
+\fIarg\fR, to \fBnext\fR are the arguments to pass to the next method in the
+chain.
+.PP
+The \fBnextto\fR command is the same as the \fBnext\fR command, except that it
+takes an additional \fIclass\fR argument that identifies a class whose
+implementation of the current method chain (see \fBinfo object\fR \fBcall\fR) should
+be used; the method implementation selected will be the one provided by the
+given class, and it must refer to an existing non-filter invocation that lies
+further along the chain than the current implementation.
+.SH "THE METHOD CHAIN"
+.PP
+When a method of an object is invoked, things happen in several stages:
+.IP [1]
+The structure of the object, its class, superclasses, filters, and mixins, are
+examined to build a \fImethod chain\fR, which contains a list of method
+implementations to invoke.
+.IP [2]
+The first method implementation on the chain is invoked.
+.IP [3]
+If that method implementation invokes the \fBnext\fR command, the next method
+implementation is invoked (with its arguments being those that were passed to
+\fBnext\fR).
+.IP [4]
+The result from the overall method call is the result from the outermost
+method implementation; inner method implementations return their results
+through \fBnext\fR.
+.IP [5]
+The method chain is cached for future use.
+.SS "METHOD SEARCH ORDER"
+.PP
+When constructing the method chain, method implementations are searched for in
+the following order:
+.IP [1]
+In the object.
+.IP [2]
+In the classes mixed into the object, in class traversal order. The list of
+mixins is checked in natural order.
+.IP [3]
+In the classes mixed into the classes of the object, with sources of mixing in
+being searched in class traversal order. Within each class, the list of mixins
+is processed in natural order.
+.IP [4]
+In the object's class.
+.IP [5]
+In the superclasses of the class, following each superclass in a depth-first
+fashion in the natural order of the superclass list.
+.PP
+Any particular method implementation always comes as \fIlate\fR in the
+resulting list of implementations as possible.
+.SS FILTERS
+.PP
+When an object has a list of filter names set upon it, or is an instance of a
+class (or has mixed in a class) that has a list of filter names set upon it,
+before every invocation of any method the filters are processed. Filter
+implementations are found in class traversal order, as are the lists of filter
+names (each of which is traversed in natural list order). Explicitly invoking
+a method used as a filter will cause that method to be invoked twice, once as
+a filter and once as a normal method.
+.PP
+Each filter should decide for itself whether to permit the execution to go
+forward to the proper implementation of the method (which it does by invoking
+the \fBnext\fR command as filters are inserted into the front of the method
+call chain) and is responsible for returning the result of \fBnext\fR.
+.PP
+Filters are not invoked when processing an invocation of the \fBunknown\fR
+method because of a failure to locate a method implementation, or when
+invoking either constructors or destructors.
+.SH EXAMPLES
+.PP
+This example demonstrates how to use the \fBnext\fR command to call the
+(super)class's implementation of a method. The script:
+.PP
+.CS
+oo::class create theSuperclass {
+ method example {args} {
+ puts "in the superclass, args = $args"
+ }
+}
+oo::class create theSubclass {
+ superclass theSuperclass
+ method example {args} {
+ puts "before chaining from subclass, args = $args"
+ \fBnext\fR a {*}$args b
+ \fBnext\fR pureSynthesis
+ puts "after chaining from subclass"
+ }
+}
+theSubclass create obj
+oo::define obj method example args {
+ puts "per-object method, args = $args"
+ \fBnext\fR x {*}$args y
+ \fBnext\fR
+}
+obj example 1 2 3
+.CE
+.PP
+prints the following:
+.PP
+.CS
+per-object method, args = 1 2 3
+before chaining from subclass, args = x 1 2 3 y
+in the superclass, args = a x 1 2 3 y b
+in the superclass, args = pureSynthesis
+after chaining from subclass
+before chaining from subclass, args =
+in the superclass, args = a b
+in the superclass, args = pureSynthesis
+after chaining from subclass
+.CE
+.PP
+This example demonstrates how to build a simple cache class that applies
+memoization to all the method calls of the objects it is mixed into, and shows
+how it can make a difference to computation times:
+.PP
+.CS
+oo::class create cache {
+ filter Memoize
+ method Memoize args {
+ \fI# Do not filter the core method implementations\fR
+ if {[lindex [self target] 0] eq "::oo::object"} {
+ return [\fBnext\fR {*}$args]
+ }
+
+ \fI# Check if the value is already in the cache\fR
+ my variable ValueCache
+ set key [self target],$args
+ if {[info exist ValueCache($key)]} {
+ return $ValueCache($key)
+ }
+
+ \fI# Compute value, insert into cache, and return it\fR
+ return [set ValueCache($key) [\fBnext\fR {*}$args]]
+ }
+ method flushCache {} {
+ my variable ValueCache
+ unset ValueCache
+ \fI# Skip the caching\fR
+ return -level 2 ""
+ }
+}
+
+oo::object create demo
+oo::define demo {
+ mixin cache
+ method compute {a b c} {
+ after 3000 \fI;# Simulate deep thought\fR
+ return [expr {$a + $b * $c}]
+ }
+ method compute2 {a b c} {
+ after 3000 \fI;# Simulate deep thought\fR
+ return [expr {$a * $b + $c}]
+ }
+}
+
+puts [demo compute 1 2 3] \fI\(-> prints "7" after delay\fR
+puts [demo compute2 4 5 6] \fI\(-> prints "26" after delay\fR
+puts [demo compute 1 2 3] \fI\(-> prints "7" instantly\fR
+puts [demo compute2 4 5 6] \fI\(-> prints "26" instantly\fR
+puts [demo compute 4 5 6] \fI\(-> prints "34" after delay\fR
+puts [demo compute 4 5 6] \fI\(-> prints "34" instantly\fR
+puts [demo compute 1 2 3] \fI\(-> prints "7" instantly\fR
+demo flushCache
+puts [demo compute 1 2 3] \fI\(-> prints "7" after delay\fR
+.CE
+.SH "SEE ALSO"
+oo::class(n), oo::define(n), oo::object(n), self(n)
+.SH KEYWORDS
+call, method, method chain
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/library/msgcat/doc/object.n b/library/msgcat/doc/object.n
new file mode 100644
index 0000000..6737e7e
--- /dev/null
+++ b/library/msgcat/doc/object.n
@@ -0,0 +1,128 @@
+'\"
+'\" Copyright (c) 2007-2008 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 object n 0.1 TclOO "TclOO Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+oo::object \- root class of the class hierarchy
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBoo::object\fI method \fR?\fIarg ...\fR?
+.fi
+.SH "CLASS HIERARCHY"
+.nf
+\fBoo::object\fR
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBoo::object\fR class is the root class of the object hierarchy; every
+object is an instance of this class. Since classes are themselves objects,
+they are instances of this class too. Objects are always referred to by their
+name, and may be \fBrename\fRd while maintaining their identity.
+.PP
+Instances of objects may be made with either the \fBcreate\fR or \fBnew\fR
+methods of the \fBoo::object\fR object itself, or by invoking those methods on
+any of the subclass objects; see \fBoo::class\fR for more details. The
+configuration of individual objects (i.e., instance-specific methods, mixed-in
+classes, etc.) may be controlled with the \fBoo::objdefine\fR command.
+.PP
+Each object has a unique namespace associated with it, the instance namespace.
+This namespace holds all the instance variables of the object, and will be the
+current namespace whenever a method of the object is invoked (including a
+method of the class of the object). When the object is destroyed, its instance
+namespace is deleted. The instance namespace contains the object's \fBmy\fR
+command, which may be used to invoke non-exported methods of the object or to
+create a reference to the object for the purpose of invocation which persists
+across renamings of the object.
+.SS CONSTRUCTOR
+The \fBoo::object\fR class does not define an explicit constructor.
+.SS DESTRUCTOR
+The \fBoo::object\fR class does not define an explicit destructor.
+.SS "EXPORTED METHODS"
+The \fBoo::object\fR class supports the following exported methods:
+.TP
+\fIobj \fBdestroy\fR
+.
+This method destroys the object, \fIobj\fR, that it is invoked upon, invoking
+any destructors on the object's class in the process. It is equivalent to
+using \fBrename\fR to delete the object command. The result of this method is
+always the empty string.
+.SS "NON-EXPORTED METHODS"
+.PP
+The \fBoo::object\fR class supports the following non-exported methods:
+.TP
+\fIobj \fBeval\fR ?\fIarg ...\fR?
+.
+This method concatenates the arguments, \fIarg\fR, as if with \fBconcat\fR,
+and then evaluates the resulting script in the namespace that is uniquely
+associated with \fIobj\fR, returning the result of the evaluation.
+.TP
+\fIobj \fBunknown ?\fImethodName\fR? ?\fIarg ...\fR?
+.
+This method is called when an attempt to invoke the method \fImethodName\fR on
+object \fIobj\fR fails. The arguments that the user supplied to the method are
+given as \fIarg\fR arguments.
+.VS
+If \fImethodName\fR is absent, the object was invoked with no method name at
+all (or any other arguments).
+.VE
+The default implementation (i.e., the one defined by the \fBoo::object\fR
+class) generates a suitable error, detailing what methods the object supports
+given whether the object was invoked by its public name or through the
+\fBmy\fR command.
+.TP
+\fIobj \fBvariable \fR?\fIvarName ...\fR?
+.
+This method arranges for each variable called \fIvarName\fR to be linked from
+the object \fIobj\fR's unique namespace into the caller's context. Thus, if it
+is invoked from inside a procedure then the namespace variable in the object
+is linked to the local variable in the procedure. Each \fIvarName\fR argument
+must not have any namespace separators in it. The result is the empty string.
+.TP
+\fIobj \fBvarname \fIvarName\fR
+.
+This method returns the globally qualified name of the variable \fIvarName\fR
+in the unique namespace for the object \fIobj\fR.
+.TP
+\fIobj \fB<cloned> \fIsourceObjectName\fR
+.VS
+This method is used by the \fBoo::object\fR command to copy the state of one
+object to another. It is responsible for copying the procedures and variables
+of the namespace of the source object (\fIsourceObjectName\fR) to the current
+object. It does not copy any other types of commands or any traces on the
+variables; that can be added if desired by overriding this method in a
+subclass.
+.VE
+.SH EXAMPLES
+.PP
+This example demonstrates basic use of an object.
+.PP
+.CS
+set obj [\fBoo::object\fR new]
+$obj foo \fI\(-> error "unknown method foo"\fR
+oo::objdefine $obj method foo {} {
+ my \fBvariable\fR count
+ puts "bar[incr count]"
+}
+$obj foo \fI\(-> prints "bar1"\fR
+$obj foo \fI\(-> prints "bar2"\fR
+$obj variable count \fI\(-> error "unknown method variable"\fR
+$obj \fBdestroy\fR
+$obj foo \fI\(-> error "unknown command obj"\fR
+.CE
+.SH "SEE ALSO"
+my(n), oo::class(n)
+.SH KEYWORDS
+base class, class, object, root class
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/library/msgcat/doc/open.n b/library/msgcat/doc/open.n
new file mode 100644
index 0000000..d4842f2
--- /dev/null
+++ b/library/msgcat/doc/open.n
@@ -0,0 +1,465 @@
+'\"
+'\" 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 open n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+open \- Open a file-based or command pipeline channel
+.SH SYNOPSIS
+.sp
+\fBopen \fIfileName\fR
+.br
+\fBopen \fIfileName access\fR
+.br
+\fBopen \fIfileName access permissions\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command opens a file, serial port, or command pipeline and returns a
+channel identifier that may be used in future invocations of commands like
+\fBread\fR, \fBputs\fR, and \fBclose\fR.
+If the first character of \fIfileName\fR is not \fB|\fR then
+the command opens a file:
+\fIfileName\fR gives the name of the file to open, and it must conform to the
+conventions described in the \fBfilename\fR manual entry.
+.PP
+The \fIaccess\fR argument, if present, indicates the way in which the file
+(or command pipeline) is to be accessed.
+In the first form \fIaccess\fR may have any of the following values:
+.TP 15
+\fBr\fR
+.
+Open the file for reading only; the file must already exist. This is the
+default value if \fIaccess\fR is not specified.
+.TP 15
+\fBr+\fR
+.
+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 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 does not exist, create a new file.
+.TP 15
+\fBa\fR
+.
+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 does not exist,
+create a new empty file.
+Set the initial access position to the end of the file.
+.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 as if with the
+\fBfconfigure\fR \fB\-translation binary\fR option, making the channel suitable for
+reading or writing of binary data.
+.PP
+In the second form, \fIaccess\fR consists of a list of any of the
+following flags, all of which have the standard POSIX meanings.
+One of the flags must be either \fBRDONLY\fR, \fBWRONLY\fR or \fBRDWR\fR.
+.TP 15
+\fBRDONLY\fR
+.
+Open the file for reading only.
+.TP 15
+\fBWRONLY\fR
+.
+Open the file for writing only.
+.TP 15
+\fBRDWR\fR
+.
+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.
+.TP 15
+\fBBINARY\fR
+.
+Configure the opened channel with the \fB\-translation binary\fR option.
+.TP 15
+\fBCREAT\fR
+.
+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
+.
+If \fBCREAT\fR is also specified, an error is returned if the
+file already exists.
+.TP 15
+\fBNOCTTY\fR
+.
+If the file is a terminal device, this flag prevents the file from
+becoming the controlling terminal of the process.
+.TP 15
+\fBNONBLOCK\fR
+.
+Prevents the process from blocking while opening the file, and
+possibly in subsequent I/O operations. The exact behavior of
+this flag is system- and device-dependent; its use is discouraged
+(it is better to use the \fBfconfigure\fR command to put a file
+in nonblocking mode).
+For details refer to your system documentation on the \fBopen\fR system
+call's \fBO_NONBLOCK\fR flag.
+.TP 15
+\fBTRUNC\fR
+.
+If the file exists it is truncated to zero length.
+.PP
+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.
+.SH "COMMAND PIPELINES"
+.PP
+If the first character of \fIfileName\fR is
+.QW \fB|\fR
+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.
+In this case, the channel identifier returned by \fBopen\fR may be used
+to write to the command's input pipe or read from its output pipe,
+depending on the value of \fIaccess\fR.
+If write-only access is used (e.g. \fIaccess\fR is
+.QW \fBw\fR ),
+then standard output for the pipeline is directed to the current standard
+output unless overridden by the command.
+If read-only access is used (e.g. \fIaccess\fR is
+.QW \fBr\fR ),
+standard input for the pipeline is taken from the current standard
+input unless overridden by the command.
+The id of the spawned process is accessible through the \fBpid\fR
+command, using the channel id returned by \fBopen\fR as argument.
+.PP
+If the command (or one of the commands) executed in the command
+pipeline returns an error (according to the definition in \fBexec\fR),
+a Tcl error is generated when \fBclose\fR is called on the channel
+unless the pipeline is in non-blocking mode then no exit status is
+returned (a silent \fBclose\fR with -blocking 0).
+.PP
+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.
+.SH "SERIAL COMMUNICATIONS"
+.PP
+If \fIfileName\fR refers to a serial port, then the specified serial port
+is opened and initialized in a platform-dependent manner. Acceptable
+values for the \fIfileName\fR to use to open a serial port are described in
+the PORTABILITY ISSUES section.
+.PP
+The \fBfconfigure\fR command can be used to query and set additional
+configuration options specific to serial ports (where supported):
+.TP
+\fB\-mode\fR \fIbaud\fB,\fIparity\fB,\fIdata\fB,\fIstop\fR
+.
+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
+.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
+\fB\-handshake\fR \fItype\fR
+.
+(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.
+.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.
+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.
+.RE
+.TP
+\fB\-queue\fR
+.
+(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
+\fB\-timeout\fR \fImsec\fR
+.
+(Windows and Unix). This option is used to set the timeout for blocking
+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
+nonblocking reads.
+This option cannot be queried.
+.TP
+\fB\-ttycontrol\fR \fI{signal boolean signal boolean ...}\fR
+.
+(Windows and Unix). This option is used to setup the handshake
+output lines (see below) permanently or to send a BREAK over the serial line.
+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 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.
+.TP
+\fB\-ttystatus\fR
+.
+(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,
+e.g. \fB{CTS 1 DSR 0 RING 1 DCD 0}\fR.
+The \fIsignal\fR names are returned upper case.
+.TP
+\fB\-xchar\fR \fI{xonChar xoffChar}\fR
+.
+(Windows and Unix). This option is used to query or change the software
+handshake characters. Normally the operating system default should be
+DC1 (0x11) and DC3 (0x13) representing the ASCII standard
+XON and XOFF characters.
+.TP
+\fB\-pollinterval\fR \fImsec\fR
+.
+(Windows only). This option is used to set the maximum time between
+polling for fileevents.
+This affects the time interval between checking for events throughout the Tcl
+interpreter (the smallest value always wins). Use this option only if
+you want to poll the serial port more or less often than 10 msec
+(the default).
+.TP
+\fB\-sysbuffer\fR \fIinSize\fR
+.TP
+\fB\-sysbuffer\fR \fI{inSize outSize}\fR
+.
+(Windows only). This option is used to change the size of Windows
+system buffers for a serial channel. Especially at higher communication
+rates the default input buffer size of 4096 bytes can overrun
+for latent systems. The first form specifies the input buffer size,
+in the second form both input and output buffers are defined.
+.TP
+\fB\-lasterror\fR
+.
+(Windows only). This option is query only.
+In case of a serial communication error, \fBread\fR or \fBputs\fR
+returns a general Tcl file I/O error.
+\fBfconfigure\fR \fB\-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
+communications. A negative voltage (-3V..-12V) define a mark (on=1) bit and
+a positive voltage (+3..+12V) define a space (off=0) bit (RS-232C). The
+following signals are specified for incoming and outgoing data, status
+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\fR(output)
+\fBTransmitted Data:\fR Outgoing serial data.
+.IP \fBRXD\fR(input)
+\fBReceived Data:\fRIncoming serial data.
+.IP \fBRTS\fR(output)
+\fBRequest To Send:\fR This hardware handshake line informs the modem that
+your workstation is ready to receive data. Your workstation may
+automatically reset this signal to indicate that the input buffer is full.
+.IP \fBCTS\fR(input)
+\fBClear To Send:\fR The complement to RTS. Indicates that the modem is
+ready to receive data.
+.IP \fBDTR\fR(output)
+\fBData Terminal Ready:\fR This signal tells the modem that the workstation
+is ready to establish a link. DTR is often enabled automatically whenever a
+serial port is opened.
+.IP \fBDSR\fR(input)
+\fBData Set Ready:\fR The complement to DTR. Tells the workstation that the
+modem is ready to establish a link.
+.IP \fBDCD\fR(input)
+\fBData Carrier Detect:\fR This line becomes active when a modem detects a
+.QW Carrier
+signal.
+.IP \fBRI\fR(input)
+\fBRing Indicator:\fR Goes active when the modem detects an incoming call.
+.IP \fBBREAK\fR
+A BREAK condition is not a hardware signal line, but a logical zero on the
+TXD or RXD lines for a long period of time, usually 250 to 500
+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 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\fR \fB\-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
+it or your system is overloaded. Use \fBfconfigure\fR \fB\-sysbuffer\fR to avoid a
+temporary bottleneck and/or make your script faster.
+.TP 10
+\fBTXFULL\fR
+.
+Windows output buffer overrun. Complement to RXOVER. This error should
+practically not happen, because Tcl cares about the output buffer status.
+.TP 10
+\fBOVERRUN\fR
+.
+UART buffer overrun (hardware) with data lost.
+The data comes faster than the system driver receives it.
+Check your advanced serial port settings to enable the FIFO (16550) buffer
+and/or setup a lower(1) interrupt threshold value.
+.TP 10
+\fBRXPARITY\fR
+.
+A parity error has been detected by your UART.
+Wrong parity settings with \fBfconfigure\fR \fB\-mode\fR or a noisy data line (RXD)
+may cause this error.
+.TP 10
+\fBFRAME\fR
+.
+A stop-bit error has been detected by your UART.
+Wrong mode settings with \fBfconfigure\fR \fB\-mode\fR or a noisy data line (RXD)
+may cause this error.
+.TP 10
+\fBBREAK\fR
+.
+A BREAK condition has been detected by your UART (see above).
+.SH "PORTABILITY ISSUES"
+.TP
+\fBWindows \fR(all versions)
+.
+Valid values for \fIfileName\fR to open a serial port are of the form
+\fBcom\fIX\fB:\fR, where \fIX\fR is a number, generally from 1 to 4.
+This notation only works for serial ports from 1 to 9, if the system
+happens to have more than four. An attempt to open a serial port that
+does not exist or has a number greater than 9 will fail. An alternate
+form of opening serial ports is to use the filename \fB\e\e.\ecomX\fR,
+where X is any number that corresponds to a serial port; please note
+that this method is considerably slower on Windows 95 and Windows 98.
+.TP
+\fBWindows NT\fR
+.
+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, some
+of the lines entered at the console will be sent to the command pipeline and
+some will be sent to the Tcl evaluator. If a command pipeline is opened for
+writing, keystrokes entered into the console are not visible until the
+pipe is closed. This behavior occurs whether the command pipeline is
+executing 16-bit or 32-bit applications. These problems only occur because
+both Tcl and the child application are competing for the console at
+the same time. If the command pipeline is started from a script, so that Tcl
+is not accessing the console, or if the command pipeline does not use
+standard input or output, but is redirected from or to a file, then the
+above problems do not occur.
+.TP
+\fBWindows 95\fR
+.
+A command pipeline that executes a 16-bit DOS application cannot be opened
+for both reading and writing, since 16-bit DOS applications that receive
+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.
+.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
+a 32-bit application, some of the keystrokes entered at the console will be
+sent to the command pipeline and some will be sent to the Tcl evaluator. If
+a command pipeline is opened for writing to a 32-bit application, no output
+is visible on the console until the pipe is closed. These problems only
+occur because both Tcl and the child application are competing for the
+console at the same time. If the command pipeline is started from a script,
+so that Tcl is not accessing the console, or if the command pipeline does
+not use standard input or output, but is redirected from or to a file, then
+the above problems do not occur.
+.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
+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.
+.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.
+Advanced configuration options are only supported for serial ports
+when Tcl is built to use the POSIX serial interface.
+.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
+of the lines entered at the console will be sent to the command pipeline and
+some will be sent to the Tcl evaluator. This problem only occurs because
+both Tcl and the child application are competing for the console at the
+same time. If the command pipeline is started from a script, so that Tcl is
+not accessing the console, or if the command pipeline does not use standard
+input, but is redirected from a file, then the above problem does not occur.
+.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"
+.PP
+Open a command pipeline and catch any errors:
+.PP
+.CS
+set fl [\fBopen\fR "| ls this_file_does_not_exist"]
+set data [read $fl]
+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
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/library/msgcat/doc/package.n b/library/msgcat/doc/package.n
new file mode 100644
index 0000000..6cf8991
--- /dev/null
+++ b/library/msgcat/doc/package.n
@@ -0,0 +1,370 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH package n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+package \- Facilities for package loading and version control
+.SH SYNOPSIS
+.nf
+\fBpackage forget\fR ?\fIpackage package ...\fR?
+\fBpackage ifneeded \fIpackage version\fR ?\fIscript\fR?
+\fBpackage names\fR
+\fBpackage present \fIpackage \fR?\fIrequirement...\fR?
+\fBpackage present \-exact \fIpackage version\fR
+\fBpackage provide \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 \fIversion requirement...\fR
+\fBpackage prefer \fR?\fBlatest\fR|\fBstable\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+This command keeps a simple database of the packages available for
+use by the current interpreter and how to load them into the
+interpreter.
+It supports multiple versions of each package and arranges
+for the correct version of a package to be loaded based on what
+is needed by the application.
+This command also detects and reports version clashes.
+Typically, only the \fBpackage require\fR and \fBpackage provide\fR
+commands are invoked in normal Tcl scripts; the other commands are used
+primarily by system scripts that maintain the package database.
+.PP
+The behavior of the \fBpackage\fR command is determined by its first argument.
+The following forms are permitted:
+.TP
+\fBpackage forget\fR ?\fIpackage package ...\fR?
+.
+Removes all information about each specified package from this interpreter,
+including information provided by both \fBpackage ifneeded\fR and
+\fBpackage provide\fR.
+.TP
+\fBpackage ifneeded \fIpackage version\fR ?\fIscript\fR?
+.
+This command typically appears only in system configuration
+scripts to set up the package database.
+It indicates that a particular version of
+a particular package is available if needed, and that the package
+can be added to the interpreter by executing \fIscript\fR.
+The script is saved in a database for use by subsequent
+\fBpackage require\fR commands; typically, \fIscript\fR
+sets up auto-loading for the commands in the package (or calls
+\fBload\fR and/or \fBsource\fR directly), then invokes
+\fBpackage provide\fR to indicate that the package is present.
+There may be information in the database for several different
+versions of a single package.
+If the database already contains information for \fIpackage\fR
+and \fIversion\fR, the new \fIscript\fR replaces the existing
+one.
+If the \fIscript\fR argument is omitted, the current script for
+version \fIversion\fR of package \fIpackage\fR is returned,
+or an empty string if no \fBpackage ifneeded\fR command has
+been invoked for this \fIpackage\fR and \fIversion\fR.
+.TP
+\fBpackage names\fR
+.
+Returns a list of the names of all packages in the
+interpreter for which a version has been provided (via
+\fBpackage provide\fR) or for which a \fBpackage ifneeded\fR
+script is available.
+The order of elements in the list is arbitrary.
+.TP
+\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
+\fBpackage provide \fIpackage \fR?\fIversion\fR?
+.
+This command is invoked to indicate that version \fIversion\fR
+of package \fIpackage\fR is now present in the interpreter.
+It is typically invoked once as part of an \fBifneeded\fR script,
+and again by the package itself when it is finally loaded.
+An error occurs if a different version of \fIpackage\fR has been
+provided by a previous \fBpackage provide\fR command.
+If the \fIversion\fR argument is omitted, then the command
+returns the version number that is currently provided, or an
+empty string if no \fBpackage provide\fR command has been
+invoked for \fIpackage\fR in this interpreter.
+.TP
+\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.
+.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 \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.
+If so, the script for the highest acceptable version number is evaluated
+in the global namespace;
+it must do whatever is necessary to load the package,
+including calling \fBpackage provide\fR for the package.
+If the \fBpackage ifneeded\fR database does not contain an acceptable
+version of the package and a \fBpackage unknown\fR command has been
+specified for the interpreter then that command is evaluated in the
+global namespace; when
+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
+.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 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 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.
+If \fIcommand\fR is specified as an empty string, then the current
+\fBpackage unknown\fR script is removed, if there is one.
+.TP
+\fBpackage vcompare \fIversion1 version2\fR
+.
+Compares the two version numbers given by \fIversion1\fR and \fIversion2\fR.
+Returns -1 if \fIversion1\fR is an earlier version than \fIversion2\fR,
+0 if they are equal, and 1 if \fIversion1\fR is later than \fIversion2\fR.
+.TP
+\fBpackage versions \fIpackage\fR
+.
+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 \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
+by dots, such as 2 or 1.162 or 3.1.13.1.
+The first number is called the major version number.
+Larger numbers correspond to later versions of a package, with
+leftmost numbers having greater significance.
+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.
+For example, Tcl scripts written for version 2.3 of a package should
+work unchanged under versions 2.3.2, 2.4, and 2.5.1.
+Changes in the major version number signify incompatible changes:
+if code is written to use version 2.1 of a package, it is not guaranteed
+to work unmodified with either version 1.7.3 or version 3.1.
+.SH "PACKAGE INDICES"
+.PP
+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 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
+.PP
+To state that a Tcl script requires the Tk and http packages, put this
+at the top of the script:
+.PP
+.CS
+\fBpackage require\fR Tk
+\fBpackage require\fR http
+.CE
+.PP
+To test to see if the Snack package is available and load if it is
+(often useful for optional enhancements to programs where the loss of
+the functionality is not critical) do this:
+.PP
+.CS
+if {[catch {\fBpackage require\fR Snack}]} {
+ # Error thrown - package not found.
+ # Set up a dummy interface to work around the absence
+} else {
+ # We have the package, configure the app to use it
+}
+.CE
+.SH "SEE ALSO"
+msgcat(n), packagens(n), pkgMkIndex(n)
+.SH KEYWORDS
+package, version
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/packagens.n b/library/msgcat/doc/packagens.n
new file mode 100644
index 0000000..30617a3
--- /dev/null
+++ b/library/msgcat/doc/packagens.n
@@ -0,0 +1,50 @@
+'\"
+'\" Copyright (c) 1998-2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.so man.macros
+.TH pkg::create n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+pkg::create \- Construct an appropriate 'package ifneeded' command for a given package specification
+.SH SYNOPSIS
+\fB::pkg::create\fR \fB\-name \fIpackageName \fB\-version \fIpackageVersion\fR ?\fB\-load \fIfilespec\fR? ... ?\fB\-source \fIfilespec\fR? ...
+.BE
+
+.SH DESCRIPTION
+.PP
+\fB::pkg::create\fR is a utility procedure that is part of the standard Tcl
+library. It is used to create an appropriate \fBpackage ifneeded\fR
+command for a given package specification. It can be used to construct a
+\fBpkgIndex.tcl\fR file for use with the \fBpackage\fR mechanism.
+
+.SH OPTIONS
+The parameters supported are:
+.TP
+\fB\-name \fIpackageName\fR
+This parameter specifies the name of the package. It is required.
+.TP
+\fB\-version \fIpackageVersion\fR
+This parameter specifies the version of the package. It is required.
+.TP
+\fB\-load \fIfilespec\fR
+This parameter specifies a binary library that must be loaded with the
+\fBload\fR command. \fIfilespec\fR is a list with two elements. The
+first element is the name of the file to load. The second, optional
+element is a list of commands supplied by loading that file. If the
+list of procedures is empty or omitted, \fB::pkg::create\fR will
+set up the library for direct loading (see \fBpkg_mkIndex\fR). Any
+number of \fB\-load\fR parameters may be specified.
+.TP
+\fB\-source \fIfilespec\fR
+This parameter is similar to the \fB\-load\fR parameter, except that it
+specifies a Tcl library that must be loaded with the
+\fBsource\fR command. Any number of \fB\-source\fR parameters may be
+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/library/msgcat/doc/pid.n b/library/msgcat/doc/pid.n
new file mode 100644
index 0000000..97a42a7
--- /dev/null
+++ b/library/msgcat/doc/pid.n
@@ -0,0 +1,48 @@
+'\"
+'\" 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 pid n 7.0 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+pid \- Retrieve process identifiers
+.SH SYNOPSIS
+\fBpid \fR?\fIfileId\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+If the \fIfileId\fR argument is given then it should normally
+refer to a process pipeline created with the \fBopen\fR command.
+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 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.
+.SH EXAMPLE
+Print process information about the processes in a pipeline using the
+SysV \fBps\fR program before reading the output of that pipeline:
+.PP
+.CS
+set pipeline [open "| zcat somefile.gz | grep foobar | sort -u"]
+# Print process information
+exec ps -fp [\fBpid\fR $pipeline] >@stdout
+# Print a separator and then the output of the pipeline
+puts [string repeat - 70]
+puts [read $pipeline]
+close $pipeline
+.CE
+
+.SH "SEE ALSO"
+exec(n), open(n)
+
+.SH KEYWORDS
+file, pipeline, process identifier
diff --git a/library/msgcat/doc/pkgMkIndex.n b/library/msgcat/doc/pkgMkIndex.n
new file mode 100644
index 0000000..2753208
--- /dev/null
+++ b/library/msgcat/doc/pkgMkIndex.n
@@ -0,0 +1,233 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH pkg_mkIndex n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+pkg_mkIndex \- Build an index for automatic loading of packages
+.SH SYNOPSIS
+.nf
+\fBpkg_mkIndex\fR ?\fIoptions...\fR? \fIdir\fR ?\fIpattern pattern ...\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+\fBPkg_mkIndex\fR is a utility procedure that is part of the standard
+Tcl library.
+It is used to create index files that allow packages to be loaded
+automatically when \fBpackage require\fR commands are executed.
+To use \fBpkg_mkIndex\fR, follow these steps:
+.IP [1]
+Create the package(s).
+Each package may consist of one or more Tcl script files or binary files.
+Binary files must be suitable for loading with the \fBload\fR command
+with a single argument; for example, if the file is \fBtest.so\fR it must
+be possible to load this file with the command \fBload test.so\fR.
+Each script file must contain a \fBpackage provide\fR command to declare
+the package and version number, and each binary file must contain
+a call to \fBTcl_PkgProvide\fR.
+.IP [2]
+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.
+The default pattern is \fB*.tcl\fR and \fB*.[info sharedlibextension]\fR.
+.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.
+It does this by loading each file into a slave
+interpreter and seeing what packages
+and new commands appear (this is why it is essential to have
+\fBpackage provide\fR commands or \fBTcl_PkgProvide\fR calls
+in the files, as described above).
+If you have a package split among scripts and binary files,
+or if you have dependencies among files,
+you may have to use the \fB\-load\fR option
+or adjust the order in which \fBpkg_mkIndex\fR processes
+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
+than one directory, machine-dependent packages (e.g., those that
+contain binary shared libraries) should normally be installed
+under the first directory and machine-independent packages (e.g.,
+those that contain only Tcl scripts) should be installed under the
+second directory.
+The subdirectory should include
+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.
+.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.
+\fBAuto_path\fR contains a list of directories that are searched
+by both the auto-loader and the package loader; by default it
+includes \fB$tcl_pkgPath\fR.
+The package loader also checks all of the subdirectories of the
+directories in \fBauto_path\fR.
+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.
+For example, if versions 2.1, 2.3, and 3.1 of package \fBTest\fR
+have been indexed by \fBpkg_mkIndex\fR, the command
+\fBpackage require Test\fR will make version 3.1 available
+and the command \fBpackage require \-exact Test 2.1\fR will
+make version 2.1 available.
+There may be many versions of a package in the various index files
+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
+\fB\-direct\fR
+The generated index will implement direct loading of the package
+upon \fBpackage require\fR. This is the default.
+.TP 15
+\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. 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\fR into the slave interpreter used to
+generate the index. The pattern match uses string match rules, but without
+making case distinctions.
+See \fBCOMPLEX CASES\fR below.
+.TP 15
+\fB\-verbose\fR
+Generate output during the indexing process. Output is via
+the \fBtclLog\fR procedure, which by default prints to stderr.
+.TP 15
+\fB\-\-\fR
+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,
+in that both arrange for files to be loaded on-demand.
+However, package management is a higher-level mechanism that uses
+the auto-loader for the last step in the loading process.
+It is generally better to index a package with \fBpkg_mkIndex\fR
+rather than \fBauto_mkindex\fR because the package mechanism provides
+version control: several versions of a package can be made available
+in the index files, with different applications using different
+versions based on \fBpackage require\fR commands.
+In contrast, \fBauto_mkindex\fR does not understand versions so
+it can only handle a single version of each package.
+It is probably not a good idea to index a given package with both
+\fBpkg_mkIndex\fR and \fBauto_mkindex\fR.
+If you use \fBpkg_mkIndex\fR to index a package, its commands cannot
+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,
+the \fBpackage ifneeded\fR command, and the auto-loader.
+The first time a \fBpackage require\fR command is invoked,
+the \fBpackage unknown\fR script is invoked.
+This is set by Tcl initialization to a script that
+evaluates all of the \fBpkgIndex.tcl\fR files in the
+\fBauto_path\fR.
+The \fBpkgIndex.tcl\fR files contain \fBpackage ifneeded\fR
+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.
+If the \fB\-lazy\fR flag was provided when the \fBpkgIndex.tcl\fR
+was generated,
+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.
+.SH "DIRECT LOADING"
+.PP
+Some packages, for instance packages which use namespaces and export
+commands or those which require special initialization, might select
+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 \fB\-lazy\fR argument.
+.SH "COMPLEX CASES"
+Most complex cases of dependencies among scripts
+and binary files, and packages being split among scripts and
+binary files are handled OK. However, you may have to adjust
+the order in which files are processed by \fBpkg_mkIndex\fR.
+These issues are described in detail below.
+.PP
+If each script or file contains one package, and packages
+are only contained in one file, then things are easy.
+You simply specify all files to be indexed in any order
+with some glob patterns.
+.PP
+In general, it is OK for scripts to have dependencies on other
+packages.
+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\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\fR API
+when loading a binary file.
+For example, suppose the BLT package requires Tk, and expresses
+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\fR and that match \fIpkgPat\fR
+into the interpreter used to process files.
+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,
+you should specify the one that has dependencies last.
+This way the one without dependencies will get loaded and indexed,
+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\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\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\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
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/library/msgcat/doc/platform.n b/library/msgcat/doc/platform.n
new file mode 100644
index 0000000..1553698
--- /dev/null
+++ b/library/msgcat/doc/platform.n
@@ -0,0 +1,86 @@
+'\"
+'\" 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.10?\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 EXAMPLE
+.PP
+This can be used to allow an application to be shipped with multiple builds of
+a shared library, so that the same package works on many versions of an
+operating system. For example:
+.PP
+.CS
+\fBpackage require platform\fR
+# Assume that app script is .../theapp/bin/theapp.tcl
+set binDir [file dirname [file normalize [info script]]]
+set libDir [file join $binDir .. lib]
+set platLibDir [file join $libDir [\fBplatform::identify\fR]]
+load [file join $platLibDir support[info sharedlibextension]]
+.CE
+.SH KEYWORDS
+operating system, cpu architecture, platform, architecture
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/platform_shell.n b/library/msgcat/doc/platform_shell.n
new file mode 100644
index 0000000..eef4d4e
--- /dev/null
+++ b/library/msgcat/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/library/msgcat/doc/prefix.n b/library/msgcat/doc/prefix.n
new file mode 100644
index 0000000..eb79996
--- /dev/null
+++ b/library/msgcat/doc/prefix.n
@@ -0,0 +1,116 @@
+'\"
+'\" Copyright (c) 2008 Peter Spjuth <pspjuth@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 prefix n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+tcl::prefix \- facilities for prefix matching
+.SH SYNOPSIS
+.nf
+\fB::tcl::prefix all\fR \fItable\fR \fIstring\fR
+\fB::tcl::prefix longest\fR \fItable\fR \fIstring\fR
+\fB::tcl::prefix match\fR \fI?option ...?\fR \fItable\fR \fIstring\fR
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+This document describes commands looking up a prefix in a list of strings.
+The following commands are supported:
+.TP
+\fB::tcl::prefix all\fR \fItable\fR \fIstring\fR
+.
+Returns a list of all elements in \fItable\fR that begin with the prefix
+\fIstring\fR.
+.TP
+\fB::tcl::prefix longest\fR \fItable\fR \fIstring\fR
+.
+Returns the longest common prefix of all elements in \fItable\fR that
+begin with the prefix \fIstring\fR.
+.TP
+\fB::tcl::prefix match\fR ?\fIoptions\fR? \fItable\fR \fIstring\fR
+.
+If \fIstring\fR equals one element in \fItable\fR or is a prefix to exactly
+one element, the matched element is returned. If not, the result depends
+on the \fB\-error\fR option. (It is recommended that the \fItable\fR be sorted
+before use with this subcommand, so that the list of matches presented in the
+error message also becomes sorted, though this is not strictly necessary for
+the operation of this subcommand itself.)
+.RS
+.TP
+\fB\-exact\fR\0
+.
+Accept only exact matches.
+.TP
+\fB\-message\0\fIstring\fR
+.
+Use \fIstring\fR in the error message at a mismatch. Default is
+.QW option .
+.TP
+\fB\-error\0\fIoptions\fR
+.
+The \fIoptions\fR are used when no match is found. If \fIoptions\fR is empty,
+no error is generated and an empty string is returned. Otherwise the
+\fIoptions\fR are used as \fBreturn\fR options when generating the error
+message. The default corresponds to setting
+.QW "\-level 0" .
+Example: If
+.QW "\fB\-error\fR {\-errorcode MyError \-level 1}"
+is used, an error would be generated as:
+.RS
+.PP
+.CS
+return \-errorcode MyError \-level 1 \-code error \e
+ "ambiguous option ..."
+.CE
+.RE
+.RE
+.SH "EXAMPLES"
+.PP
+Basic use:
+.PP
+.CS
+namespace import ::tcl::prefix
+\fBprefix match\fR {apa bepa cepa} apa
+ \fI\(-> apa\fR
+\fBprefix match\fR {apa bepa cepa} a
+ \fI\(-> apa\fR
+\fBprefix match\fR \-exact {apa bepa cepa} a
+ \fI\(-> bad option "a": must be apa, bepa, or cepa\fR
+\fBprefix match\fR \-message "switch" {apa ada bepa cepa} a
+ \fI\(-> ambiguous switch "a": must be apa, ada, bepa, or cepa\fR
+\fBprefix longest\fR {fblocked fconfigure fcopy file fileevent flush} fc
+ \fI\(-> fco\fR
+\fBprefix all\fR {fblocked fconfigure fcopy file fileevent flush} fc
+ \fI\(-> fconfigure fcopy\fR
+.CE
+.PP
+Simplifying option matching:
+.PP
+.CS
+array set opts {\-apa 1 \-bepa "" \-cepa 0}
+foreach {arg val} $args {
+ set opts([\fBprefix match\fR {\-apa \-bepa \-cepa} $arg]) $val
+}
+.CE
+.PP
+Creating a \fBswitch\fR that supports prefixes:
+.PP
+.CS
+switch [\fBprefix match\fR {apa bepa cepa} $arg] {
+ apa { }
+ bepa { }
+ cepa { }
+}
+.CE
+.SH "SEE ALSO"
+lsearch(n), namespace(n), string(n), Tcl_GetIndexFromObj(3)
+.SH "KEYWORDS"
+prefix, table lookup
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/proc.n b/library/msgcat/doc/proc.n
new file mode 100644
index 0000000..570a37d
--- /dev/null
+++ b/library/msgcat/doc/proc.n
@@ -0,0 +1,110 @@
+'\"
+'\" 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 proc n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+proc \- Create a Tcl procedure
+.SH SYNOPSIS
+\fBproc \fIname args body\fR
+.BE
+.SH DESCRIPTION
+.PP
+The \fBproc\fR command creates a new Tcl procedure named
+\fIname\fR, replacing
+any existing command or procedure there may have been by that name.
+Whenever the new command is invoked, the contents of \fIbody\fR will
+be executed by the Tcl interpreter.
+Normally, \fIname\fR is unqualified
+(does not include the names of any containing namespaces),
+and the new procedure is created in the current namespace.
+If \fIname\fR includes any namespace qualifiers,
+the procedure is created in the specified namespace.
+\fIArgs\fR specifies the formal arguments to the
+procedure. It consists of a list, possibly empty, each of whose
+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.
+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 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 formal arguments. In this case, all of the actual arguments
+starting at the one that would be assigned to \fBargs\fR are combined into
+a list (as if the \fBlist\fR command had been used); this combined value
+is assigned to the local variable \fBargs\fR.
+.PP
+When \fIbody\fR is being executed, variable names normally refer to
+local variables, which are created automatically when referenced and
+deleted when the procedure returns. One local variable is automatically
+created for each of the procedure's arguments.
+Other variables can only be accessed by invoking one of the \fBglobal\fR,
+\fBvariable\fR, \fBupvar\fR or \fBnamespace upvar\fR commands.
+The current namespace when \fIbody\fR is executed will be the
+namespace that the procedure's name exists in, which will be the
+namespace that it was created in unless it has been changed with
+\fBrename\fR.
+'\" We may change this! It makes [variable] unstable when renamed and is
+'\" frankly pretty crazy, but doing it right is harder than it looks.
+.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 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
+body, then the procedure-as-a-whole will return that same error.
+.SH EXAMPLES
+.PP
+This is a procedure that accepts arbitrarily many arguments and prints
+them out, one by one.
+.PP
+.CS
+\fBproc\fR printArguments args {
+ foreach arg $args {
+ puts $arg
+ }
+}
+.CE
+.PP
+This procedure is a bit like the \fBincr\fR command, except it
+multiplies the contents of the named variable by the value, which
+defaults to \fB2\fR:
+.PP
+.CS
+\fBproc\fR mult {varName {multiplier 2}} {
+ upvar 1 $varName var
+ set var [expr {$var * $multiplier}]
+}
+.CE
+.SH "SEE ALSO"
+info(n), unknown(n)
+.SH KEYWORDS
+argument, procedure
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/puts.n b/library/msgcat/doc/puts.n
new file mode 100644
index 0000000..4a53d44
--- /dev/null
+++ b/library/msgcat/doc/puts.n
@@ -0,0 +1,98 @@
+'\"
+'\" 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 puts n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+puts \- Write to a channel
+.SH SYNOPSIS
+\fBputs \fR?\fB\-nonewline\fR? ?\fIchannelId\fR? \fIstring\fR
+.BE
+.SH DESCRIPTION
+.PP
+Writes the characters given by \fIstring\fR to the channel given
+by \fIchannelId\fR.
+.PP
+\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.
+.PP
+If no \fIchannelId\fR is specified then it defaults to
+\fBstdout\fR. \fBPuts\fR normally outputs a newline character after
+\fIstring\fR, but this feature may be suppressed by specifying the
+\fB\-nonewline\fR switch.
+.PP
+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.
+See the \fBfconfigure\fR manual entry for a discussion on ways in
+which \fBfconfigure\fR will alter output.
+.PP
+Tcl buffers output internally, so characters written with \fBputs\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 \fBflush\fR
+command.
+.PP
+When the output buffer fills up, the \fBputs\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 \fBputs\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 \fBfileevent\fR command
+(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
+.PP
+Write a short message to the console (or wherever \fBstdout\fR is
+directed):
+.PP
+.CS
+\fBputs\fR "Hello, World!"
+.CE
+.PP
+Print a message in several parts:
+.PP
+.CS
+\fBputs\fR -nonewline "Hello, "
+\fBputs\fR "World!"
+.CE
+.PP
+Print a message to the standard error channel:
+.PP
+.CS
+\fBputs\fR stderr "Hello, World!"
+.CE
+.PP
+Append a log message to a file:
+.PP
+.CS
+set chan [open my.log a]
+set timestamp [clock format [clock seconds]]
+\fBputs\fR $chan "$timestamp - Hello, World!"
+close $chan
+.CE
+.SH "SEE ALSO"
+file(n), fileevent(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+channel, newline, output, write
diff --git a/library/msgcat/doc/pwd.n b/library/msgcat/doc/pwd.n
new file mode 100644
index 0000000..65fed84
--- /dev/null
+++ b/library/msgcat/doc/pwd.n
@@ -0,0 +1,39 @@
+'\"
+'\" 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 pwd n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+pwd \- Return the absolute path of the current working directory
+.SH SYNOPSIS
+\fBpwd\fR
+.BE
+.SH DESCRIPTION
+.PP
+Returns the absolute path name of the current working directory.
+.SH EXAMPLE
+.PP
+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 minimizes user
+confusion. The way to do this is to save the current directory while
+the external command is being run:
+.PP
+.CS
+set tarFile [file normalize somefile.tar]
+set savedDir [\fBpwd\fR]
+cd /tmp
+exec tar -xf $tarFile
+cd $savedDir
+.CE
+.SH "SEE ALSO"
+file(n), cd(n), glob(n), filename(n)
+.SH KEYWORDS
+working directory
diff --git a/library/msgcat/doc/re_syntax.n b/library/msgcat/doc/re_syntax.n
new file mode 100644
index 0000000..46a180d
--- /dev/null
+++ b/library/msgcat/doc/re_syntax.n
@@ -0,0 +1,834 @@
+'\"
+'\" Copyright (c) 1998 Sun Microsystems, Inc.
+'\" Copyright (c) 1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.ie '\w'o''\w'\C'^o''' .ds qo \C'^o'
+.el .ds qo u
+.TH re_syntax n "8.1" Tcl "Tcl Built-In Commands"
+.BS
+.SH NAME
+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 does not match others.
+.SH "DIFFERENT FLAVORS OF REs"
+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
+.PQ ARE s ,
+basically EREs with some significant extensions.
+.PP
+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
+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
+regular expressions below is copied verbatim from his manual entry.
+.PP
+An ARE is one or more \fIbranches\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.
+.SS QUANTIFIERS
+A quantified atom is an \fIatom\fR possibly followed
+by a single \fIquantifier\fR.
+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,
+but prefer the smallest number rather than the largest number
+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.
+.SS ATOMS
+An atom is one of:
+.RS 2
+.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
+.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
+.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 \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
+.TP
+\fB(?!\fIre\fB)\fR
+.
+\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
+.QW \fB\e\fR .
+.SH "BRACKET EXPRESSIONS"
+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.
+.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 incompatibility between programs.
+.PP
+To include a literal \fB]\fR or \fB\-\fR in the list, the simplest
+method is to enclose it in \fB[.\fR and \fB.]\fR to make it a
+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:
+.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 \fBalnum\fR
+and \fBpunct\fR).
+.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
+.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
+(\fINote:\fR Tcl has no multi-character collating elements. This information
+is only for illustration.)
+.RE
+.PP
+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
+.QW \fB.]\fR .)
+For example, if \fBo\fR and \fB\*(qo\fR are the members of an
+equivalence class, then
+.QW \fB[[=o=]]\fR ,
+.QW \fB[[=\*(qo=]]\fR ,
+and
+.QW \fB[o\*(qo]\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
+applications where there are multiple levels of backslash processing
+.TP
+\fB\ec\fIX\fR
+.
+(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
+.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 one up to four hexadecimal digits) the Unicode
+character \fBU+\fIwxyz\fR in the local byte ordering
+.TP
+\fB\eU\fIstuvwxyz\fR
+.
+(where \fIstuvwxyz\fR is one up to eight hexadecimal digits) reserved
+for a Unicode extension up to 21 bits. The digits are parsed until the
+first non-hexadecimal character is encountered, the maximun of eight
+hexadecimal digits are reached, or an overflow would occur in the maximum
+value of \fBU+\fI10ffff\fR.
+.TP
+\fB\ev\fR
+.
+vertical tab, as in C are all available.
+.TP
+\fB\ex\fIhh\fR
+.
+(where \fIhh\fR is one or two hexadecimal digits) the character
+whose hexadecimal value is \fB0x\fIhh\fR.
+.TP
+\fB\e0\fR
+.
+the character whose value is \fB0\fR
+.TP
+\fB\e\fIxyz\fR
+.
+(where \fIxyz\fR is exactly three octal digits, and is not a \fIback
+reference\fR (see below)) the character whose octal value is
+\fB0\fIxyz\fR. The first digit must be in the range 0-3, otherwise
+the two-digit form is assumed.
+.TP
+\fB\e\fIxy\fR
+.
+(where \fIxy\fR is exactly two octal digits, and is not a \fIback
+reference\fR (see below)) the character whose octal value is
+\fB0\fIxy\fR
+.RE
+.PP
+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 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)
+.TP
+\fB\eD\fR
+.
+\fB[^[:digit:]]\fR
+.TP
+\fB\eS\fR
+.
+\fB[^[:space:]]\fR
+.TP
+\fB\eW\fR
+.
+\fB[^[:alnum:]_]\fR (note underscore)
+.RE
+.PP
+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 \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 \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
+.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
+.RE
+.PP
+A word is defined as in the specification of
+.QW \fB[[:<:]]\fR
+and
+.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
+.QW \fBbb\fR
+or
+.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.
+.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
+.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 \fBMATCHING\fR, below)
+.TP 3
+\fBm\fR
+.
+historical synonym for \fBn\fR
+.TP 3
+\fBn\fR
+.
+newline-sensitive matching (see \fBMATCHING\fR, below)
+.TP 3
+\fBp\fR
+.
+partial newline-sensitive matching (see \fBMATCHING\fR, below)
+.TP 3
+\fBq\fR
+.
+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
+.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:
+.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
+.QW \fB(?:\fR
+or the BRE
+.QW \fB\e(\fR
+.PP
+Expanded-syntax white-space characters are blank, tab, newline, and
+any character that belongs to the \fIspace\fR character class.
+.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
+.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,
+.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
+.QW \fB(.*).*\fR
+is matched against
+.QW \fBabc\fR
+the parenthesized subexpression matches all three characters, and when
+.QW \fB(a*)*\fR
+is matched against
+.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
+.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
+.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.
+.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 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
+.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.
+.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.
+.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
+.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/library/msgcat/doc/read.n b/library/msgcat/doc/read.n
new file mode 100644
index 0000000..007c0ac
--- /dev/null
+++ b/library/msgcat/doc/read.n
@@ -0,0 +1,89 @@
+'\"
+'\" 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 read n 8.1 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+read \- Read from a channel
+.SH SYNOPSIS
+\fBread \fR?\fB\-nonewline\fR? \fIchannelId\fR
+.sp
+\fBread \fIchannelId numChars\fR
+.BE
+.SH DESCRIPTION
+.PP
+In the first form, the \fBread\fR command reads all of the data from
+\fIchannelId\fR up to the end of the file. If the \fB\-nonewline\fR
+switch is specified then the last character of the file is discarded
+if it is a newline. In the second form, the extra argument specifies
+how many characters to read. Exactly that many characters will be
+read and returned, unless there are fewer than \fInumChars\fR left in
+the file; in this case all the remaining characters are returned. If
+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
+\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.
+.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,
+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
+\fBRead\fR translates end-of-line sequences in the input into
+newline characters according to the \fB\-translation\fR option
+for the channel.
+See the \fBfconfigure\fR manual entry for a discussion on ways in
+which \fBfconfigure\fR will alter input.
+.SH "USE WITH SERIAL PORTS"
+'\" Note: this advice actually applies to many versions of Tcl
+.PP
+For most applications a channel connected to a serial port should be
+configured to be nonblocking: \fBfconfigure\fI channelId \fB\-blocking
+\fI0\fR. Then \fBread\fR behaves much like described above. Care
+must be taken when using \fBread\fR on blocking serial ports:
+.TP
+\fBread \fIchannelId numChars\fR
+.
+In this form \fBread\fR blocks until \fInumChars\fR have been received
+from the serial port.
+.TP
+\fBread \fIchannelId\fR
+.
+In this form \fBread\fR blocks until the reception of the end-of-file
+character, see \fBfconfigure\fR \fB\-eofchar\fR. If there no end-of-file
+character has been configured for the channel, then \fBread\fR will
+block forever.
+.SH "EXAMPLE"
+.PP
+This example code reads a file all at once, and splits it into a list,
+with each line in the file corresponding to an element in the list:
+.PP
+.CS
+set fl [open /proc/meminfo]
+set data [\fBread\fR $fl]
+close $fl
+set lines [split $data \en]
+.CE
+.SH "SEE ALSO"
+file(n), eof(n), fblocked(n), fconfigure(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+blocking, channel, end of line, end of file, nonblocking, read, translation, encoding
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/library/msgcat/doc/refchan.n b/library/msgcat/doc/refchan.n
new file mode 100644
index 0000000..a51c3d7
--- /dev/null
+++ b/library/msgcat/doc/refchan.n
@@ -0,0 +1,411 @@
+'\"
+'\" 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
+.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\fR \fBcreate\fR, though the implementation
+of handlers for reflected channel \fIis not\fR tied to \fBnamespace
+ensemble\fRs in any way; see \fBEXAMPLE\fR below for how to build an
+\fBoo::class\fR that supports the API). 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 \fBchan close\fR) will appear to have thrown this
+error. Any exception beyond \fBerror\fR (e.g.,\ \fBbreak\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, \fBbreak\fR, \fBcontinue\fR, 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 \fIbytes\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.
+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 \fBgets\fR, or \fBread\fR) will appear to have
+thrown this error. Any exception beyond \fBerror\fR, (e.g.,\ \fBbreak\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 \fBerror\fR (e.g.,\ \fBbreak\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
+\fBchan seek\fR and \fBchan tell\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 the same as the equivalent argument of the
+builtin \fBchan seek\fR, namely:
+.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 \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.
+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.
+If the subcommand throws an error the command which caused its
+invocation (usually \fBchan seek\fR, or \fBchan tell\fR) will appear to have
+thrown this error. Any exception beyond \fBerror\fR (e.g.,\ \fBbreak\fR,
+etc.) is treated as and converted to an error.
+.PP
+The offset/base combination of 0/\fBcurrent\fR signals a \fBchan tell\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 \fBerror\fR (e.g.,\ \fBbreak\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 or \fBchan configure\fR)
+will appear to have thrown this error. Any exception beyond \fIerror\fR
+(e.g.,\ \fBbreak\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 or \fBchan configure\fR)
+will appear to have thrown this error. Any exception beyond \fBerror\fR
+(e.g.,\ \fBbreak\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 or \fBchan configure\fR) will appear to
+have thrown this error. Any exception beyond \fBerror\fR (e.g.,\ \fBbreak\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 EXAMPLE
+.PP
+This demonstrates how to make a channel that reads from a string.
+.PP
+.CS
+oo::class create stringchan {
+ variable data pos
+ constructor {string {encoding {}}} {
+ if {$encoding eq ""} {set encoding [encoding system]}
+ set data [encoding convertto $encoding $string]
+ set pos 0
+ }
+
+ method \fBinitialize\fR {ch mode} {
+ return "initialize finalize watch read seek"
+ }
+ method \fBfinalize\fR {ch} {
+ my destroy
+ }
+ method \fBwatch\fR {ch events} {
+ # Must be present but we ignore it because we do not
+ # post any events
+ }
+
+ # Must be present on a readable channel
+ method \fBread\fR {ch count} {
+ set d [string range $data $pos [expr {$pos+$count-1}]]
+ incr pos [string length $d]
+ return $d
+ }
+
+ # This method is optional, but useful for the example below
+ method \fBseek\fR {ch offset base} {
+ switch $base {
+ start {
+ set pos $offset
+ }
+ current {
+ incr pos $offset
+ }
+ end {
+ set pos [string length $data]
+ incr pos $offset
+ }
+ }
+ if {$pos < 0} {
+ set pos 0
+ } elseif {$pos > [string length $data]} {
+ set pos [string length $data]
+ }
+ return $pos
+ }
+}
+
+# Now we create an instance...
+set string "The quick brown fox jumps over the lazy dog.\\n"
+set ch [\fBchan create\fR read [stringchan new $string]]
+
+puts [gets $ch]; # Prints the whole string
+
+seek $ch -5 end;
+puts [read $ch]; # Prints just the last word
+.CE
+.SH "SEE ALSO"
+chan(n), transchan(n)
+.SH KEYWORDS
+API, channel, ensemble, prefix, reflection
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/regexp.n b/library/msgcat/doc/regexp.n
new file mode 100644
index 0000000..5e857f8
--- /dev/null
+++ b/library/msgcat/doc/regexp.n
@@ -0,0 +1,208 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH regexp n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+regexp \- Match a regular expression against a string
+.SH SYNOPSIS
+\fBregexp \fR?\fIswitches\fR? \fIexp string \fR?\fImatchVar\fR? ?\fIsubMatchVar subMatchVar ...\fR?
+.BE
+.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 does not, unless
+\fB\-inline\fR is specified (see below).
+(Regular expression matching is described in the \fBre_syntax\fR
+reference page.)
+.PP
+If additional arguments are specified after \fIstring\fR then they
+are treated as the names of variables in which to return
+information about which part(s) of \fIstring\fR matched \fIexp\fR.
+\fIMatchVar\fR will be set to the range of \fIstring\fR that
+matched all of \fIexp\fR. The first \fIsubMatchVar\fR will contain
+the characters in \fIstring\fR that matched the leftmost parenthesized
+subexpression within \fIexp\fR, the next \fIsubMatchVar\fR will
+contain the characters that matched the next parenthesized
+subexpression to the right in \fIexp\fR, and so on.
+.PP
+If the initial arguments to \fBregexp\fR start with \fB\-\fR then
+they are treated as switches. The following switches are
+currently supported:
+.TP 15
+\fB\-about\fR
+.
+Instead of attempting to match the regular expression, returns a list
+containing information about the regular expression. The first
+element of the list is a subexpression count. The second element is a
+list of property names that describe various attributes of the regular
+expression. This switch is primarily intended for debugging purposes.
+.TP 15
+\fB\-expanded\fR
+.
+Enables use of the expanded regular expression syntax where
+whitespace and comments are ignored. This is the same as specifying
+the \fB(?x)\fR embedded option (see the \fBre_syntax\fR manual page).
+.TP 15
+\fB\-indices\fR
+.
+Changes what is stored in the \fIsubMatchVar\fRs.
+Instead of storing the matching characters from \fIstring\fR,
+each variable
+will contain a list of two decimal strings giving the indices
+in \fIstring\fR of the first and last characters in the matching
+range of characters.
+.TP 15
+\fB\-line\fR
+.
+Enables newline-sensitive matching. By default, newline is a
+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
+.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
+.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
+.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).
+.TP 15
+\fB\-nocase\fR
+.
+Causes upper-case characters in \fIstring\fR to be treated as
+lower case during the matching process.
+.TP 15
+\fB\-all\fR
+.
+Causes the regular expression to be matched as many times as possible
+in the string, returning the total number of matches found. If this
+is specified with match variables, they will contain information for
+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
+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:
+.RS
+.PP
+.CS
+\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
+.RE
+.TP 15
+\fB\-start\fR \fIindex\fR
+.
+Specifies a character index offset into the string to start
+matching the regular expression at.
+The \fIindex\fR value is interpreted in the same manner
+as the \fIindex\fR argument to \fBstring index\fR.
+When using this switch,
+.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.
+.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\fRs than parenthesized
+subexpressions within \fIexp\fR, or if a particular subexpression
+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:
+.PP
+.CS
+\fBregexp\fR {\emfoo(?!bar\eM)(\ew*)} $string \-> restOfWord
+.CE
+.PP
+Note that the whole matched substring has been placed in the variable
+.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:
+.PP
+.CS
+\fBregexp\fR \-indices {(?i)\embadger\eM} $string location
+.CE
+.PP
+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:
+.PP
+.CS
+\fBregexp\fR \-indices {(?ib)\e<badger\e>} $string location
+.CE
+.PP
+This counts the number of octal digits in a string:
+.PP
+.CS
+\fBregexp\fR \-all {[0\-7]} $string
+.CE
+.PP
+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:
+.PP
+.CS
+\fBregexp\fR \-all \-inline {\eS+} $string
+.CE
+.SH "SEE ALSO"
+re_syntax(n), regsub(n), string(n)
+.SH KEYWORDS
+match, parsing, pattern, regular expression, splitting, string
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/registry.n b/library/msgcat/doc/registry.n
new file mode 100644
index 0000000..2e69b1e
--- /dev/null
+++ b/library/msgcat/doc/registry.n
@@ -0,0 +1,218 @@
+'\"
+'\" Copyright (c) 1997 Sun Microsystems, Inc.
+'\" Copyright (c) 2002 ActiveState Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH registry n 1.1 registry "Tcl Bundled Packages"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+registry \- Manipulate the Windows registry
+.SH SYNOPSIS
+.sp
+\fBpackage require registry 1.3\fR
+.sp
+\fBregistry \fR?\fI\-mode\fR? \fIoption\fR \fIkeyName\fR ?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fBregistry\fR package provides a general set of operations for
+manipulating the Windows registry. The package implements the
+\fBregistry\fR Tcl command. This command is only supported on the
+Windows platform. Warning: this command should be used with caution
+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:
+.RS
+.PP
+\fB\e\e\fIhostname\fB\e\fIrootname\fB\e\fIkeypath\fR
+.PP
+\fIrootname\fB\e\fIkeypath\fR
+.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,
+\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
+registry key names separated by backslash (\fB\e\fR) characters.
+.PP
+.VS 8.6
+The optional \fI\-mode\fR argument indicates which registry to work
+with; when it is \fB\-32bit\fR the 32-bit registry will be used, and
+when it is \fB\-64bit\fR the 64-bit registry will be used. If this
+argument is omitted, the system's default registry will be the subject
+of the requested operation.
+.VE 8.6
+.PP
+\fIOption\fR indicates what to do with the registry key name. Any
+unique abbreviation for \fIoption\fR is acceptable. The valid options
+are:
+.TP
+\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
+keys like Environment. The timeout specifies the amount of time, in
+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 [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
+.RE
+.TP
+\fBregistry delete \fIkeyName\fR ?\fIvalueName\fR?
+.
+If the optional \fIvalueName\fR argument is present, the specified
+value under \fIkeyName\fR will be deleted from the registry. If the
+optional \fIvalueName\fR is omitted, the specified key and any subkeys
+or values beneath it in the registry hierarchy will be deleted. If
+the key could not be deleted then an error is generated. If the key
+did not exist, the command has no effect.
+.TP
+\fBregistry get \fIkeyName valueName\fR
+.
+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 \fBSUPPORTED TYPES\fR, below.
+.TP
+\fBregistry keys \fIkeyName\fR ?\fIpattern\fR?
+.
+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 match\fR. If the
+specified \fIkeyName\fR does not exist, then an error is generated.
+.TP
+\fBregistry set \fIkeyName\fR ?\fIvalueName data \fR?\fItype\fR??
+.
+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 is not specified, the type
+\fBsz\fR is assumed. For more details on the data and type arguments,
+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
+\fBSUPPORTED TYPES\fR, below.
+.TP
+\fBregistry values \fIkeyName\fR ?\fIpattern\fR?
+.
+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 match\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
+command converts between this internal representation and one that can
+be manipulated by Tcl scripts. In most cases, the data is simply
+returned as a Tcl string. The type indicates the intended use for the
+data, but does not actually change the representation. For some
+types, the \fBregistry\fR command returns the data in a different form to
+make it easier to manipulate. The following types are recognized by the
+registry command:
+.TP 17
+\fBbinary\fR
+.
+The registry value contains arbitrary binary data. The data is represented
+exactly in Tcl, including any embedded nulls.
+.TP
+\fBnone\fR
+.
+The registry value contains arbitrary binary data with no defined
+type. The data is represented exactly in Tcl, including any embedded
+nulls.
+.TP
+\fBsz\fR
+.
+The registry value contains a null-terminated string. The data is
+represented in Tcl as a string.
+.TP
+\fBexpand_sz\fR
+.
+The registry value contains a null-terminated string that contains
+unexpanded references to environment variables in the normal Windows
+style (for example,
+.QW %PATH% ).
+The data is represented in Tcl as a string.
+.TP
+\fBdword\fR
+.
+The registry value contains a little-endian 32-bit number. The data is
+represented in Tcl as a decimal string.
+.TP
+\fBdword_big_endian\fR
+.
+The registry value contains a big-endian 32-bit number. The data is
+represented in Tcl as a decimal string.
+.TP
+\fBlink\fR
+.
+The registry value contains a symbolic link. The data is represented
+exactly in Tcl, including any embedded nulls.
+.TP
+\fBmulti_sz\fR
+.
+The registry value contains an array of null-terminated strings. The
+data is represented in Tcl as a list of strings.
+.TP
+\fBresource_list\fR
+.
+The registry value contains a device-driver resource list. The data
+is represented exactly in Tcl, including any embedded nulls.
+.PP
+In addition to the symbolically named types listed above, unknown
+types are identified using a 32-bit integer that corresponds to the
+type code returned by the system interfaces. In this case, the data
+is represented exactly in Tcl, including any embedded nulls.
+.SH "PORTABILITY ISSUES"
+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
+
+# Read the type name
+set type [\fBregistry get\fR HKEY_CLASSES_ROOT\e\e$ext {}]
+# Work out where to look for the command
+set path HKEY_CLASSES_ROOT\e\e$type\e\eShell\e\eOpen\e\ecommand
+# Read the command!
+set command [\fBregistry get\fR $path {}]
+
+puts "$ext opens with $command"
+.CE
+.SH KEYWORDS
+registry
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/regsub.n b/library/msgcat/doc/regsub.n
new file mode 100644
index 0000000..fe473d9
--- /dev/null
+++ b/library/msgcat/doc/regsub.n
@@ -0,0 +1,192 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Scriptics Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH regsub n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+regsub \- Perform substitutions based on regular expression pattern matching
+.SH SYNOPSIS
+\fBregsub \fR?\fIswitches\fR? \fIexp string subSpec \fR?\fIvarName\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command matches the regular expression \fIexp\fR against
+\fIstring\fR,
+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.
+(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
+(or to the result of this command if \fIvarName\fR is not present)
+the portion of \fIstring\fR that
+matched \fIexp\fR is replaced with \fIsubSpec\fR.
+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
+parenthesized subexpression of \fIexp\fR.
+Additional backslashes may be used in \fIsubSpec\fR to prevent special
+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 is generally
+safest to enclose \fIsubSpec\fR in braces if it includes
+backslashes.
+.LP
+If the initial arguments to \fBregsub\fR start with \fB\-\fR then
+they are treated as switches. The following switches are
+currently supported:
+.TP
+\fB\-all\fR
+.
+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
+.QW &
+and
+.QW \e\fIn\fR
+sequences are handled for each substitution using the information
+from the corresponding match.
+.TP
+\fB\-expanded\fR
+.
+Enables use of the expanded regular expression syntax where
+whitespace and comments are ignored. This is the same as specifying
+the \fB(?x)\fR embedded option (see the \fBre_syntax\fR manual page).
+.TP
+\fB\-line\fR
+.
+Enables newline-sensitive matching. By default, newline is a
+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
+.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
+\fB\-linestop\fR
+.
+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
+\fB\-lineanchor\fR
+.
+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).
+.TP
+\fB\-nocase\fR
+.
+Upper-case characters in \fIstring\fR will be converted to lower-case
+before matching against \fIexp\fR; however, substitutions specified
+by \fIsubSpec\fR use the original unconverted form of \fIstring\fR.
+.TP
+\fB\-start\fR \fIindex\fR
+.
+Specifies a character index offset into the string to start
+matching the regular expression at.
+The \fIindex\fR value is interpreted in the same manner
+as the \fIindex\fR argument to \fBstring index\fR.
+When using this switch,
+.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
+\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 \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.
+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:
+.PP
+.CS
+\fBregsub\fR -all {\emfoo\eM} $string bar string
+.CE
+.PP
+or (using the
+.QW "basic regular expression"
+syntax):
+.PP
+.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 capitalized.
+.PP
+.CS
+\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:
+.PP
+.CS
+# 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. 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), string(n)
+.SH KEYWORDS
+match, pattern, quoting, regular expression, substitution
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/rename.n b/library/msgcat/doc/rename.n
new file mode 100644
index 0000000..77dc095
--- /dev/null
+++ b/library/msgcat/doc/rename.n
@@ -0,0 +1,45 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH rename n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+rename \- Rename or delete a command
+.SH SYNOPSIS
+\fBrename \fIoldName newName\fR
+.BE
+.SH DESCRIPTION
+.PP
+Rename the command that used to be called \fIoldName\fR so that it
+is now called \fInewName\fR.
+If \fInewName\fR is an empty string then \fIoldName\fR is deleted.
+\fIoldName\fR and \fInewName\fR may include namespace qualifiers
+(names of containing namespaces).
+If a command is renamed into a different namespace,
+future invocations of it will execute in the new namespace.
+The \fBrename\fR command returns an empty string as result.
+.SH EXAMPLE
+.PP
+The \fBrename\fR command can be used to wrap the standard Tcl commands
+with your own monitoring machinery. For example, you might wish to
+count how often the \fBsource\fR command is called:
+.PP
+.CS
+\fBrename\fR ::source ::theRealSource
+set sourceCount 0
+proc ::source args {
+ global sourceCount
+ puts "called source for the [incr sourceCount]'th time"
+ uplevel 1 ::theRealSource $args
+}
+.CE
+.SH "SEE ALSO"
+namespace(n), proc(n)
+.SH KEYWORDS
+command, delete, namespace, rename
diff --git a/library/msgcat/doc/return.n b/library/msgcat/doc/return.n
new file mode 100644
index 0000000..b59a93d
--- /dev/null
+++ b/library/msgcat/doc/return.n
@@ -0,0 +1,326 @@
+'\"
+'\" 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 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, or set return code of a script
+.SH SYNOPSIS
+\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
+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 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.
+\fICode\fR may have any of the following values:
+.TP 13
+\fBok\fR (or \fB0\fR)
+.
+Normal return: same as if the option is omitted. The return code
+of the procedure is 0 (\fBTCL_OK\fR).
+.TP 13
+\fBerror\fR (or \fB1\fR)
+.
+Error return: the return code of the procedure is 1 (\fBTCL_ERROR\fR).
+The procedure command behaves in its calling context as if it
+were the command \fBerror\fR \fIresult\fR. See below for additional
+options.
+.TP 13
+\fBreturn\fR (or \fB2\fR)
+.
+The return code of the procedure is 2 (\fBTCL_RETURN\fR). The
+procedure command behaves in its calling context as if it
+were the command \fBreturn\fR (with no arguments).
+.TP 13
+\fBbreak\fR (or \fB3\fR)
+.
+The return code of the procedure is 3 (\fBTCL_BREAK\fR). The
+procedure command behaves in its calling context as if it
+were the command \fBbreak\fR.
+.TP 13
+\fBcontinue\fR (or \fB4\fR)
+.
+The return code of the procedure is 4 (\fBTCL_CONTINUE\fR). The
+procedure command behaves in its calling context as if it
+were the command \fBcontinue\fR.
+.TP 13
+\fIvalue\fR
+.
+\fIValue\fR must be an integer; it will be returned as the
+return code for the current procedure.
+.LP
+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
+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.
+.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\-errorstack \fIlist\fR
+.VS 8.6
+The \fB\-errorstack\fR option receives special treatment only when the value
+of the \fB\-code\fR option is \fBTCL_ERROR\fR. Then \fIlist\fR is the initial
+error stack, recording actual argument values passed to each proc level. The error stack will
+also be reachable through \fBinfo errorstack\fR.
+If no \fB\-errorstack\fR option is provided to \fBreturn\fR when
+the \fB\-code error\fR option is provided, Tcl will provide its own
+initial error stack in the entry for \fB\-errorstack\fR. Tcl's
+initial error stack 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 \fIlist\fR value is supplied from
+the value of \fB\-errorstack\fR in a return options dictionary captured
+by the \fBcatch\fR command (or from the copy of that information from
+\fBinfo errorstack\fR).
+.VE 8.6
+.TP
+\fB\-level \fIlevel\fR
+.
+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.
+.TP
+\fB\-options \fIoptions\fR
+.
+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.
+.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
+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.
+.SH EXAMPLES
+.PP
+First, a simple example of using \fBreturn\fR to return from a
+procedure, interrupting the procedure body.
+.PP
+.CS
+proc printOneLine {} {
+ puts "line 1" ;# This line will be printed.
+ \fBreturn\fR
+ puts "line 2" ;# This line will not be printed.
+}
+.CE
+.PP
+Next, an example of using \fBreturn\fR to set the value
+returned by the procedure.
+.PP
+.CS
+proc returnX {} {\fBreturn\fR X}
+puts [returnX] ;# prints "X"
+.CE
+.PP
+Next, a more complete example, using \fBreturn -code error\fR
+to report invalid arguments.
+.PP
+.CS
+proc factorial {n} {
+ if {![string is integer $n] || ($n < 0)} {
+ \fBreturn\fR -code error \e
+ "expected non-negative integer,\e
+ but got \e"$n\e""
+ }
+ if {$n < 2} {
+ \fBreturn\fR 1
+ }
+ set m [expr {$n - 1}]
+ set code [catch {factorial $m} factor]
+ if {$code != 0} {
+ \fBreturn\fR -code $code $factor
+ }
+ set product [expr {$n * $factor}]
+ if {$product < 0} {
+ \fBreturn\fR -code error \e
+ "overflow computing factorial of $n"
+ }
+ \fBreturn\fR $product
+}
+.CE
+.PP
+Next, a procedure replacement for \fBbreak\fR.
+.PP
+.CS
+proc myBreak {} {
+ \fBreturn\fR -code break
+}
+.CE
+.PP
+With the \fB\-level 0\fR option, \fBreturn\fR itself can serve
+as a replacement for \fBbreak\fR, with the help of \fBinterp alias\fR.
+.PP
+.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:
+.PP
+.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:
+.PP
+.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
+.SH "SEE ALSO"
+break(n), catch(n), continue(n), dict(n), error(n), proc(n),
+source(n), tclvars(n), throw(n), try(n)
+.SH KEYWORDS
+break, catch, continue, error, exception, procedure, result, return
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/library/msgcat/doc/safe.n b/library/msgcat/doc/safe.n
new file mode 100644
index 0000000..ebd9b4d
--- /dev/null
+++ b/library/msgcat/doc/safe.n
@@ -0,0 +1,359 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH "Safe Tcl" n 8.0 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+safe \- Creating and manipulating safe interpreters
+.SH SYNOPSIS
+\fB::safe::interpCreate\fR ?\fIslave\fR? ?\fIoptions...\fR?
+.sp
+\fB::safe::interpInit\fR \fIslave\fR ?\fIoptions...\fR?
+.sp
+\fB::safe::interpConfigure\fR \fIslave\fR ?\fIoptions...\fR?
+.sp
+\fB::safe::interpDelete\fR \fIslave\fR
+.sp
+\fB::safe::interpAddToAccessPath\fR \fIslave\fR \fIdirectory\fR
+.sp
+\fB::safe::interpFindInAccessPath\fR \fIslave\fR \fIdirectory\fR
+.sp
+\fB::safe::setLogCmd\fR ?\fIcmd arg...\fR?
+.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
+potentially dangerous functionality.
+.PP
+Safe Tcl ensures that untrusted Tcl scripts cannot harm the
+hosting application.
+It prevents integrity and privacy attacks. Untrusted Tcl
+scripts are prevented from corrupting the state of the hosting
+application or computer. Untrusted scripts are also prevented from
+disclosing information stored on the hosting computer or in the
+hosting application to any party.
+.PP
+Safe Tcl allows a master interpreter to create safe, restricted
+interpreters that contain a set of predefined aliases for the \fBsource\fR,
+\fBload\fR, \fBfile\fR, \fBencoding\fR, and \fBexit\fR commands and
+are able to use the auto-loading and package mechanisms.
+.PP
+No knowledge of the file system structure is leaked to the
+safe interpreter, because it has access only to a virtualized path
+containing tokens. When the safe interpreter requests to source a file, it
+uses the token in the virtual path as part of the file name to source; the
+master interpreter transparently
+translates the token into a real directory name and executes the
+requested operation (see the section \fBSECURITY\fR below for details).
+Different levels of security can be selected by using the optional flags
+of the commands described below.
+.PP
+All commands provided in the master interpreter by Safe Tcl reside in
+the \fBsafe\fR namespace.
+.SH COMMANDS
+The following commands are provided in the master interpreter:
+.TP
+\fB::safe::interpCreate\fR ?\fIslave\fR? ?\fIoptions...\fR?
+Creates a safe interpreter, installs the aliases described in the section
+\fBALIASES\fR and initializes the auto-loading and package mechanism as
+specified by the supplied \fIoptions\fR.
+See the \fBOPTIONS\fR section below for a description of the
+optional arguments.
+If the \fIslave\fR argument is omitted, a name will be generated.
+\fB::safe::interpCreate\fR always returns the interpreter name.
+.TP
+\fB::safe::interpInit\fR \fIslave\fR ?\fIoptions...\fR?
+This command is similar to \fBinterpCreate\fR except it that does not
+create the safe interpreter. \fIslave\fR must have been created by some
+other means, like \fBinterp create\fR \fB\-safe\fR.
+.TP
+\fB::safe::interpConfigure\fR \fIslave\fR ?\fIoptions...\fR?
+If no \fIoptions\fR are given, returns the settings for all options for the
+named safe interpreter as a list of options and their current values
+for that \fIslave\fR.
+If a single additional argument is provided,
+it will return a list of 2 elements \fIname\fR and \fIvalue\fR where
+\fIname\fR is the full name of that option and \fIvalue\fR the current value
+for that option and the \fIslave\fR.
+If more than two additional arguments are provided, it will reconfigure the
+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 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
+.CE
+.RE
+.TP
+\fB::safe::interpDelete\fR \fIslave\fR
+Deletes the safe interpreter and cleans up the corresponding
+master interpreter data structures.
+If a \fIdeleteHook\fR script was specified for this interpreter it is
+evaluated before the interpreter is deleted, with the name of the
+interpreter as an additional argument.
+.TP
+\fB::safe::interpFindInAccessPath\fR \fIslave\fR \fIdirectory\fR
+This command finds and returns the token for the real directory
+\fIdirectory\fR in the safe interpreter's current virtual access path.
+It generates an error if the directory is not found.
+Example of use:
+.RS
+.PP
+.CS
+$slave eval [list set tk_library \e
+ [::safe::interpFindInAccessPath $name $tk_library]]
+.CE
+.RE
+.TP
+\fB::safe::interpAddToAccessPath\fR \fIslave\fR \fIdirectory\fR
+This command adds \fIdirectory\fR to the virtual path maintained for the
+safe interpreter in the master, and returns the token that can be used in
+the safe interpreter to obtain access to files in that directory.
+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 \e
+ [::safe::interpAddToAccessPath $name $tk_library]]
+.CE
+.RE
+.TP
+\fB::safe::setLogCmd\fR ?\fIcmd arg...\fR?
+This command installs a script that will be called when interesting
+life cycle events occur for a safe interpreter.
+When called with no arguments, it returns the currently installed script.
+When called with one argument, an empty string, the currently installed
+script is removed and logging is turned off.
+The script will be invoked with one additional argument, a string
+describing the event of interest.
+The main purpose is to help in debugging safe interpreters.
+Using this facility you can get complete error messages while the safe
+interpreter gets only generic error messages.
+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=()
+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
+.SS OPTIONS
+The following options are common to
+\fB::safe::interpCreate\fR, \fB::safe::interpInit\fR,
+and \fB::safe::interpConfigure\fR.
+Any option name can be abbreviated to its minimal
+non-ambiguous name.
+Option names are not case sensitive.
+.TP
+\fB\-accessPath\fR \fIdirectoryList\fR
+This option sets the list of directories from which the safe interpreter
+can \fBsource\fR and \fBload\fR files.
+If this option is not specified, or if it is given as the
+empty list, the safe interpreter will use the same directories as its
+master for auto-loading.
+See the section \fBSECURITY\fR below for more detail about virtual paths,
+tokens and access control.
+.TP
+\fB\-statics\fR \fIboolean\fR
+This option specifies if the safe interpreter will be allowed
+to load statically linked packages (like \fBload {} Tk\fR).
+The default value is \fBtrue\fR :
+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
+thus specifies that the safe interpreter will not be allowed
+to load statically linked packages.
+.TP
+\fB\-nested\fR \fIboolean\fR
+This option specifies if the safe interpreter will be allowed
+to load packages into its own sub-interpreters.
+The default value is \fBfalse\fR :
+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
+thus specifies the safe interpreter will be allowed
+to load packages into its own sub-interpreters.
+.TP
+\fB\-deleteHook\fR \fIscript\fR
+When this option is given a non-empty \fIscript\fR, it will be
+evaluated in the master with the name of
+the safe interpreter as an additional argument
+just before actually deleting the safe interpreter.
+Giving an empty value removes any currently installed deletion hook
+script for that safe interpreter.
+The default value (\fB{}\fR) is not to have any deletion call back.
+.SH ALIASES
+The following aliases are provided in a safe interpreter:
+.TP
+\fBsource\fR \fIfileName\fR
+The requested file, a Tcl source file, is sourced into the safe interpreter
+if it is found.
+The \fBsource\fR alias can only source files from directories in
+the virtual path for the safe interpreter. The \fBsource\fR alias requires
+the safe interpreter to
+use one of the token names in its virtual path to denote the directory in
+which the file to be sourced can be found.
+See the section on \fBSECURITY\fR for more discussion of restrictions on
+valid filenames.
+.TP
+\fBload\fR \fIfileName\fR
+The requested file, a shared object file, is dynamically loaded into the
+safe interpreter if it is found.
+The filename must contain a token name mentioned in the virtual path for
+the safe interpreter for it to be found successfully.
+Additionally, the shared object file must contain a safe entry point; see
+the manual page for the \fBload\fR command for more details.
+.TP
+\fBfile\fR ?\fIsubCmd args...\fR?
+The \fBfile\fR alias provides access to a safe subset of the subcommands of
+the \fBfile\fR command; it allows only \fBdirname\fR, \fBjoin\fR,
+\fBextension\fR, \fBroot\fR, \fBtail\fR, \fBpathname\fR and \fBsplit\fR
+subcommands. For more details on what these subcommands do see the manual
+page for the \fBfile\fR command.
+.TP
+\fBencoding\fR ?\fIsubCmd args...\fR?
+The \fBencoding\fR alias provides access to a safe subset of the
+subcommands of the \fBencoding\fR command; it disallows setting of
+the system encoding, but allows all other subcommands including
+\fBsystem\fR to check the current encoding.
+.TP
+\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
+Safe Tcl does not attempt to completely prevent annoyance and
+denial of service attacks. These forms of attack prevent the
+application or user from temporarily using the computer to perform
+useful work, for example by consuming all available CPU time or
+all available screen real estate.
+These attacks, while aggravating, are deemed to be of lesser importance
+in general than integrity and privacy attacks that Safe Tcl
+is to prevent.
+.PP
+The commands available in a safe interpreter, in addition to
+the safe set as defined in \fBinterp\fR manual page, are mediated aliases
+for \fBsource\fR, \fBload\fR, \fBexit\fR, and safe subsets of
+\fBfile\fR and \fBencoding\fR. The safe interpreter can also auto-load
+code and it can request that packages be loaded.
+.PP
+Because some of these commands access the local file system, there is a
+potential for information leakage about its directory structure.
+To prevent this, commands that take file names as arguments in a safe
+interpreter use tokens instead of the real directory names.
+These tokens are translated to the real directory name while a request to,
+e.g., source a file is mediated by the master interpreter.
+This virtual path system is maintained in the master interpreter for each safe
+interpreter created by \fB::safe::interpCreate\fR or initialized by
+\fB::safe::interpInit\fR and
+the path maps tokens accessible in the safe interpreter into real path
+names on the local file system thus preventing safe interpreters
+from gaining knowledge about the
+structure of the file system of the host on which the interpreter is
+executing.
+The only valid file names arguments
+for the \fBsource\fR and \fBload\fR aliases provided to the slave
+are path in the form of
+\fB[file join \fItoken filename\fB]\fR (i.e. when using the
+native file path formats: \fItoken\fB/\fIfilename\fR
+on Unix and \fItoken\fB\e\fIfilename\fR on Windows),
+where \fItoken\fR is representing one of the directories
+of the \fIaccessPath\fR list and \fIfilename\fR is
+one file in that directory (no sub directories access are allowed).
+.PP
+When a token is used in a safe interpreter in a request to source or
+load a file, the token is checked and
+translated to a real path name and the file to be
+sourced or loaded is located on the file system.
+The safe interpreter never gains knowledge of the actual path name under
+which the file is stored on the file system.
+.PP
+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
+.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
+the slave \fBauto_path\fR and the first element of that list will be set as
+the \fBtcl_library\fR for that slave.
+.PP
+If the access path argument is not given or is the empty list,
+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 cannot be dangerous
+as they run in the slave interpreter) and C extensions that
+provides a _SafeInit entry point). For that purpose, the master's
+\fBauto_path\fR will be used to construct the slave access path.
+In order that the slave successfully loads the Tcl library files
+(which includes the auto-loading mechanism itself) the \fBtcl_library\fR will be
+added or moved to the first position if necessary, in the
+slave access path, so the slave
+\fBtcl_library\fR will be the same as the master's (its real
+path will still be invisible to the slave though).
+In order that auto-loading works the same for the slave and
+the master in this by default case, the first-level
+sub directories of each directory in the master \fBauto_path\fR will
+also be added (if not already included) to the slave access path.
+You can always specify a more
+restrictive path for which sub directories will never be searched by
+explicitly specifying your directory list with the \fB\-accessPath\fR flag
+instead of relying on this default mechanism.
+.PP
+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
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/scan.n b/library/msgcat/doc/scan.n
new file mode 100644
index 0000000..cc5ed79
--- /dev/null
+++ b/library/msgcat/doc/scan.n
@@ -0,0 +1,293 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Scriptics Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH scan n 8.4 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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 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 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
+the end of the input string is reached before any conversions have been
+performed.
+.SH "DETAILS ON SCANNING"
+.PP
+\fBScan\fR operates by scanning \fIstring\fR and \fIformat\fR together.
+If the next character in \fIformat\fR is a blank or tab then it
+matches any number of white space characters in \fIstring\fR (including
+zero).
+Otherwise, if it is not a \fB%\fR character then it
+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.
+A conversion specifier contains up to four fields after the \fB%\fR:
+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.
+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
+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.
+.SS "OPTIONAL POSITIONAL SPECIFIER"
+.PP
+If the \fB%\fR is followed by a decimal number and a \fB$\fR, as in
+.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
+specifiers must be positional. Every \fIvarName\fR on the argument
+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.
+.SS "OPTIONAL SIZE MODIFIER"
+.PP
+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.
+.SS "MANDATORY CONVERSION CHARACTER"
+.PP
+The following conversion characters are supported:
+.TP
+\fBd\fR
+.
+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
+\fBo\fR
+.
+The input substring must be an octal integer. It is read in and the
+integer value is stored in the variable,
+truncated as required by the size modifier value.
+.TP
+\fBx\fR
+.
+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
+\fBb\fR
+.
+The input substring must be a binary integer.
+It is read in and the integer value is stored in the variable,
+truncated as required by the size modifier value.
+.TP
+\fBu\fR
+.
+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
+\fBi\fR
+.
+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
+\fBc\fR
+.
+A single character is read in and its Unicode value is stored in
+the variable as an integer value.
+Initial white space is not skipped in this case, so the input
+substring may be a white-space character.
+.TP
+\fBs\fR
+.
+The input substring consists of all the characters up to the next
+white-space character; the characters are copied to the variable.
+.TP
+\fBe\fR or \fBf\fR or \fBg\fR
+.
+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 value.
+.TP
+\fB[\fIchars\fB]\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
+bracket for the set.
+If \fIchars\fR
+contains a sequence of the form \fIa\fB\-\fIb\fR then any
+character between \fIa\fR and \fIb\fR (inclusive) will match.
+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
+\fB[^\fIchars\fB]\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
+the set.
+If \fIchars\fR
+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 value.
+.TP
+\fBn\fR
+.
+No input is consumed from the input string. Instead, the total number
+of characters scanned from the input string so far is stored in the variable.
+.PP
+The number of characters read from the input for a conversion is the
+largest number that makes sense for that particular conversion (e.g.
+as many decimal digits as possible for \fB%d\fR, as
+many octal digits as possible for \fB%o\fR, and so on).
+The input substring for a given conversion terminates either when a
+white-space character is encountered or when the maximum substring
+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.
+.SH "DIFFERENCES FROM ANSI SSCANF"
+.PP
+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 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 substring width may be specified for this conversion.
+.IP [3]
+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). 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
+.PP
+Convert a UNICODE character to its numeric value:
+.PP
+.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 substring sizes:
+.PP
+.CS
+set string "#08D03F"
+\fBscan\fR $string "#%2x%2x%2x" r g b
+.CE
+.PP
+Parse a \fIHH:MM\fR time string, noting that this avoids problems with
+octal numbers by forcing interpretation as decimals (if we did not
+care, we would use the \fB%i\fR conversion instead):
+.PP
+.CS
+set string "08:08" ;# *Not* octal!
+if {[\fBscan\fR $string "%d:%d" hours minutes] != 2} {
+ error "not a valid time string"
+}
+# We have to understand numeric ranges ourselves...
+if {$minutes < 0 || $minutes > 59} {
+ error "invalid number of minutes"
+}
+.CE
+.PP
+Break a string up into sequences of non-whitespace characters (note
+the use of the \fB%n\fR conversion so that we get skipping over
+leading whitespace correct):
+.PP
+.CS
+set string " a string {with braced words} + leading space "
+set words {}
+while {[\fBscan\fR $string %s%n word length] == 2} {
+ lappend words $word
+ set string [string range $string $length end]
+}
+.CE
+.PP
+Parse a simple coordinate string, checking that it is complete by
+looking for the terminating character explicitly:
+.PP
+.CS
+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 \eu0029
+if {
+ [\fBscan\fR $string " (%f ,%f %c" x y last] != 3
+ || $last != 0x0029
+} then {
+ error "invalid coordinate string"
+}
+puts "X=$x, Y=$y"
+.CE
+.PP
+An interactive session demonstrating the truncation of integer
+values determined by size modifiers:
+.PP
+.CS
+\fI%\fR set tcl_platform(wordSize)
+4
+\fI%\fR scan 20000000000000000000 %d
+2147483647
+\fI%\fR scan 20000000000000000000 %ld
+9223372036854775807
+\fI%\fR scan 20000000000000000000 %lld
+20000000000000000000
+.CE
+.SH "SEE ALSO"
+format(n), sscanf(3)
+.SH KEYWORDS
+conversion specifier, parse, scan
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/seek.n b/library/msgcat/doc/seek.n
new file mode 100644
index 0000000..96d5c4e
--- /dev/null
+++ b/library/msgcat/doc/seek.n
@@ -0,0 +1,92 @@
+'\"
+'\" 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 seek n 8.1 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+seek \- Change the access position for an open channel
+.SH SYNOPSIS
+\fBseek \fIchannelId offset \fR?\fIorigin\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Changes the current access position for \fIchannelId\fR.
+.PP
+\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.
+.PP
+The \fIoffset\fR and \fIorigin\fR
+arguments specify the position at which the next read or write will occur
+for \fIchannelId\fR. \fIOffset\fR must be an integer (which may be
+negative) and \fIorigin\fR must be one of the following:
+.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
+The command flushes all buffered output for the channel before the command
+returns, even if the channel is in non-blocking mode.
+It also discards any buffered and unread input.
+This command returns an empty string.
+An error occurs if this command is applied to channels whose underlying
+file or device does not support seeking.
+.PP
+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.
+.SH EXAMPLES
+.PP
+Read a file twice:
+.PP
+.CS
+set f [open file.txt]
+set data1 [read $f]
+\fBseek\fR $f 0
+set data2 [read $f]
+close $f
+# $data1 eq $data2 if the file wasn't updated
+.CE
+.PP
+Read the last 10 bytes from a file:
+.PP
+.CS
+set f [open file.data]
+# This is guaranteed to work with binary data but
+# may fail with other encodings...
+fconfigure $f -translation binary
+\fBseek\fR $f -10 end
+set data [read $f 10]
+close $f
+.CE
+.SH "SEE ALSO"
+file(n), open(n), close(n), gets(n), tell(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+access position, file, seek
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/library/msgcat/doc/self.n b/library/msgcat/doc/self.n
new file mode 100644
index 0000000..2a04157
--- /dev/null
+++ b/library/msgcat/doc/self.n
@@ -0,0 +1,152 @@
+'\"
+'\" Copyright (c) 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 self n 0.1 TclOO "TclOO Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+self \- method call internal introspection
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBself\fR ?\fIsubcommand\fR?
+.fi
+.BE
+.SH DESCRIPTION
+The \fBself\fR command, which should only be used from within the context of a
+call to a method (i.e. inside a method, constructor or destructor body) is
+used to allow the method to discover information about how it was called. It
+takes an argument, \fIsubcommand\fR, that tells it what sort of information is
+actually desired; if omitted the result will be the same as if \fBself
+object\fR was invoked. The supported subcommands are:
+.TP
+\fBself call\fR
+.
+This returns a two-element list describing the method implementations used to
+implement the current call chain. The first element is the same as would be
+reported by \fBinfo object\fR \fBcall\fR for the current method (except that this
+also reports useful values from within constructors and destructors, whose
+names are reported as \fB<constructor>\fR and \fB<destructor>\fR
+respectively), and the second element is an index into the first element's
+list that indicates which actual implementation is currently executing (the
+first implementation to execute is always at index 0).
+.TP
+\fBself caller\fR
+.
+When the method was invoked from inside another object method, this subcommand
+returns a three element list describing the containing object and method. The
+first element describes the declaring object or class of the method, the
+second element is the name of the object on which the containing method was
+invoked, and the third element is the name of the method (with the strings
+\fB<constructor>\fR and \fB<destructor>\fR indicating constructors and
+destructors respectively).
+.TP
+\fBself class\fR
+.
+This returns the name of the class that the current method was defined within.
+Note that this will change as the chain of method implementations is traversed
+with \fBnext\fR, and that if the method was defined on an object then this
+will fail.
+.RS
+.PP
+If you want the class of the current object, you need to use this other
+construct:
+.PP
+.CS
+info object class [\fBself object\fR]
+.CE
+.RE
+.TP
+\fBself filter\fR
+.
+When invoked inside a filter, this subcommand returns a three element list
+describing the filter. The first element gives the name of the object or class
+that declared the filter (note that this may be different from the object or
+class that provided the implementation of the filter), the second element is
+either \fBobject\fR or \fBclass\fR depending on whether the declaring entity
+was an object or class, and the third element is the name of the filter.
+.TP
+\fBself method\fR
+.
+This returns the name of the current method (with the strings
+\fB<constructor>\fR and \fB<destructor>\fR indicating constructors and
+destructors respectively).
+.TP
+\fBself namespace\fR
+.
+This returns the name of the unique namespace of the object that the method
+was invoked upon.
+.TP
+\fBself next\fR
+.
+When invoked from a method that is not at the end of a call chain (i.e. where
+the \fBnext\fR command will invoke an actual method implementation), this
+subcommand returns a two element list describing the next element in the
+method call chain; the first element is the name of the class or object that
+declares the next part of the call chain, and the second element is the name
+of the method (with the strings \fB<constructor>\fR and \fB<destructor>\fR
+indicating constructors and destructors respectively). If invoked from a
+method that is at the end of a call chain, this subcommand returns the empty
+string.
+.TP
+\fBself object\fR
+.
+This returns the name of the object that the method was invoked upon.
+.TP
+\fBself target\fR
+.
+When invoked inside a filter implementation, this subcommand returns a two
+element list describing the method being filtered. The first element will be
+the name of the declarer of the method, and the second element will be the
+actual name of the method.
+.SH EXAMPLES
+.PP
+This example shows basic use of \fBself\fR to provide information about the
+current object:
+.PP
+.CS
+oo::class create c {
+ method foo {} {
+ puts "this is the [\fBself\fR] object"
+ }
+}
+c create a
+c create b
+a foo \fI\(-> prints "this is the ::a object"\fR
+b foo \fI\(-> prints "this is the ::b object"\fR
+.CE
+.PP
+This demonstrates what a method call chain looks like, and how traversing
+along it changes the index into it:
+.PP
+.CS
+oo::class create c {
+ method x {} {
+ puts "Cls: [\fBself call\fR]"
+ }
+}
+c create a
+oo::objdefine a {
+ method x {} {
+ puts "Obj: [\fBself call\fR]"
+ next
+ puts "Obj: [\fBself call\fR]"
+ }
+}
+a x \fI\(-> Obj: {{method x object method} {method x ::c method}} 0\fR
+ \fI\(-> Cls: {{method x object method} {method x ::c method}} 1\fR
+ \fI\(-> Obj: {{method x object method} {method x ::c method}} 0\fR
+.CE
+.SH "SEE ALSO"
+info(n), next(n)
+.SH KEYWORDS
+call, introspection, object
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/library/msgcat/doc/set.n b/library/msgcat/doc/set.n
new file mode 100644
index 0000000..32a788e
--- /dev/null
+++ b/library/msgcat/doc/set.n
@@ -0,0 +1,75 @@
+'\"
+'\" 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 set n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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 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,
+and the characters between the parentheses are the index within the array.
+Otherwise \fIvarName\fR refers to a scalar variable.
+.PP
+If \fIvarName\fR includes namespace qualifiers
+(in the array name if it refers to an array element), or if \fIvarName\fR
+is unqualified (does not include the names of any containing namespaces)
+but no procedure is active,
+\fIvarName\fR refers to a namespace variable
+resolved according to the rules described under \fBNAME RESOLUTION\fR in
+the \fBnamespace\fR manual page.
+.PP
+If a procedure is active and \fIvarName\fR is unqualified, then
+\fIvarName\fR refers to a parameter or local variable of the procedure,
+unless \fIvarName\fR was declared to resolve differently through one of the
+\fBglobal\fR, \fBvariable\fR or \fBupvar\fR commands.
+.SH EXAMPLES
+.PP
+Store a random number in the variable \fIr\fR:
+.PP
+.CS
+\fBset\fR r [expr {rand()}]
+.CE
+.PP
+Store a short message in an array element:
+.PP
+.CS
+\fBset\fR anAry(msg) "Hello, World!"
+.CE
+.PP
+Store a short message in an array element specified by a variable:
+.PP
+.CS
+\fBset\fR elemName "msg"
+\fBset\fR anAry($elemName) "Hello, World!"
+.CE
+.PP
+Copy a value into the variable \fIout\fR from a variable whose name is
+stored in the \fIvbl\fR (note that it is often easier to use arrays in
+practice instead of doing double-dereferencing):
+.PP
+.CS
+\fBset\fR in0 "small random"
+\fBset\fR in1 "large random"
+\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/library/msgcat/doc/socket.n b/library/msgcat/doc/socket.n
new file mode 100644
index 0000000..0a60457
--- /dev/null
+++ b/library/msgcat/doc/socket.n
@@ -0,0 +1,227 @@
+'\"
+'\" Copyright (c) 1996 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.
+'\"
+.so man.macros
+.TH socket n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+socket \- Open a TCP network connection
+.SH SYNOPSIS
+.sp
+\fBsocket \fR?\fIoptions\fR? \fIhost port\fR
+.sp
+\fBsocket\fR \fB\-server \fIcommand\fR ?\fIoptions\fR? \fIport\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command opens a network socket and returns a channel identifier
+that may be used in future invocations of commands like \fBread\fR,
+\fBputs\fR and \fBflush\fR. At present only the TCP network protocol
+is supported over IPv4 and IPv6; future releases may include support
+for additional protocols. The \fBsocket\fR command may be used to
+open either the client or server side of a connection, depending on
+whether the \fB\-server\fR switch is specified.
+.PP
+Note that the default encoding for \fIall\fR sockets is the system
+encoding, as returned by \fBencoding system\fR. Most of the time, you
+will need to use \fBchan configure\fR to alter this to something else,
+such as \fIutf\-8\fR (ideal for communicating with other Tcl
+processes) or \fIiso8859\-1\fR (useful for many network protocols,
+especially the older ones).
+.SH "CLIENT SOCKETS"
+.PP
+If the \fB\-server\fR option is not specified, then the client side of a
+connection is opened and the command returns a channel identifier
+that can be used for both reading and writing.
+\fIPort\fR and \fIhost\fR specify a port
+to connect to; there must be a server accepting connections on
+this port. \fIPort\fR is an integer port number
+(or service name, where supported and understood by the host operating
+system) and \fIhost\fR
+is either a domain-style name such as \fBwww.tcl.tk\fR or
+a numerical IPv4 or IPv6 address such as \fB127.0.0.1\fR or \fB2001:DB8::1\fR.
+Use \fIlocalhost\fR to refer to the host on which the command is invoked.
+.PP
+The following options may also be present before \fIhost\fR
+to specify additional information about the connection:
+.TP
+\fB\-myaddr\fI addr\fR
+.
+\fIAddr\fR gives the domain-style name or numerical IP address of
+the client-side network interface to use for the connection.
+This option may be useful if the client machine has multiple network
+interfaces. If the option is omitted then the client-side interface
+will be chosen by the system software.
+.TP
+\fB\-myport\fI port\fR
+.
+\fIPort\fR specifies an integer port number (or service name, where
+supported and understood by the host operating system) to use for the
+client's
+side of the connection. If this option is omitted, the client's
+port number will be chosen at random by the system software.
+.TP
+\fB\-async\fR
+.
+This option will cause the client socket to be connected
+asynchronously. This means that the socket will be created immediately
+but may not yet be connected to the server, when the call to
+\fBsocket\fR returns.
+.RS
+.PP
+When a \fBgets\fR or \fBflush\fR is done on the socket before the
+connection attempt succeeds or fails, if the socket is in blocking
+mode, the operation will wait until the connection is completed or
+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. Synchronous client sockets may
+be switched (after they have connected) to operating in asynchronous
+mode using:
+.PP
+.CS
+\fBchan configure \fIchan \fB\-blocking 0\fR
+.CE
+.PP
+See the \fBchan configure\fR command for more details.
+.PP
+The Tcl event loop should be running while an asynchronous connection
+is in progress, because it may have to do several connection attempts
+in the background. Running the event loop also allows you to set up a
+writable channel event on the socket to get notified when the
+asynchronous connection has succeeded or failed. See the \fBvwait\fR
+and the \fBchan\fR commands for more details on the event loop and
+channel events.
+.RE
+.SH "SERVER SOCKETS"
+.PP
+If the \fB\-server\fR option is specified then the new socket will be
+a server that listens on the given \fIport\fR (either an integer or a
+service name, where supported and understood by the host operating
+system; if \fIport\fR is zero, the operating system will allocate a
+free port to the server socket which may be discovered by using
+\fBchan configure\fR to read the \fB\-sockname\fR option). If the host
+supports both, IPv4 and IPv6, the socket will listen on both address
+families. Tcl will automatically accept connections to the given port.
+For each connection Tcl will create a new channel that may be used to
+communicate with the client. Tcl then invokes \fIcommand\fR (properly
+a command prefix list, see the \fBEXAMPLES\fR below) 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 \fIport\fR:
+.TP
+\fB\-myaddr\fI addr\fR
+.
+\fIAddr\fR gives the domain-style name or numerical IP address of the
+server-side network interface to use for the connection. This option
+may be useful if the server machine has multiple network interfaces.
+If the option is omitted then the server socket is bound to the
+wildcard address so that it can accept connections from any
+interface. If \fIaddr\fR is a domain name that resolves to multiple IP
+addresses that are available on the local machine, the socket will
+listen on all of them.
+.PP
+Server channels cannot be used for input or output; their sole use is to
+accept new client connections. The channels created for each incoming
+client connection are opened for input and output. Closing the server
+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 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.
+.PP
+If \fIport\fR is specified as zero, the operating system will allocate
+an unused port for use as a server socket. The port number actually
+allocated may be retrieved from the created server socket using the
+\fBchan configure\fR command to retrieve the \fB\-sockname\fR option as
+described below.
+.SH "CONFIGURATION OPTIONS"
+.PP
+The \fBchan configure\fR command can be used to query several readonly
+configuration options for socket channels:
+.TP
+\fB\-error\fR
+.
+This option gets the current error status of the given socket. This
+is useful when you need to determine if an asynchronous connect
+operation succeeded. If there was an error, the error message is
+returned. If there was no error, an empty string is returned.
+.RS
+.PP
+Note that the error status is reset by the read operation; this mimics
+the underlying getsockopt(SO_ERROR) call.
+.RE
+.TP
+\fB\-sockname\fR
+.
+For client sockets (including the channels that get created when a
+client connects to a server socket) this option returns a list of
+three elements, the address, the host name and the port number for the
+socket. If the host name cannot be computed, the second element is
+identical to the address, the first element of the list.
+.RS
+.PP
+For server sockets this option returns a list of a multiple of three
+elements each group of which have the same meaning as described
+above. The list contains more than one group when the server socket
+was created without \fB\-myaddr\fR or with the argument to
+\fB\-myaddr\fR being a domain name that resolves multiple IP addresses
+that are local to the invoking host.
+.RE
+.TP
+\fB\-peername\fR
+.
+This option is not supported by server sockets. For client and accepted
+sockets, this option returns a list of three elements; these are the
+address, the host name and the port to which the peer socket is connected
+or bound. If the host name cannot be computed, the second element of the
+list is identical to the address, its first element.
+.PP
+.SH "EXAMPLES"
+.PP
+Here is a very simple time server:
+.PP
+.CS
+proc Server {startTime channel clientaddr clientport} {
+ puts "Connection from $clientaddr registered"
+ set now [clock seconds]
+ puts $channel [clock format $now]
+ puts $channel "[expr {$now - $startTime}] since start"
+ close $channel
+}
+
+\fBsocket -server\fR [list Server [clock seconds]] 9900
+vwait forever
+.CE
+.PP
+And here is the corresponding client to talk to the server and extract
+some information:
+.PP
+.CS
+set server localhost
+set sockChan [\fBsocket\fR $server 9900]
+gets $sockChan line1
+gets $sockChan line2
+close $sockChan
+puts "The time on $server is $line1"
+puts "That is [lindex $line2 0]s since the server started"
+.CE
+.SH "HISTORY"
+Support for IPv6 was added in Tcl 8.6.
+.SH "SEE ALSO"
+chan(n), flush(n), open(n), read(n)
+.SH KEYWORDS
+asynchronous I/O, bind, channel, connection, domain name, host, network address, socket, tcp
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/source.n b/library/msgcat/doc/source.n
new file mode 100644
index 0000000..57a9fa2
--- /dev/null
+++ b/library/msgcat/doc/source.n
@@ -0,0 +1,69 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Scriptics Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH source n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+source \- Evaluate a file or resource as a Tcl script
+.SH SYNOPSIS
+\fBsource \fIfileName\fR
+.sp
+\fBsource\fR \fB\-encoding \fIencodingName fileName\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command takes the contents of the specified file or resource
+and passes it to the Tcl interpreter as a text script. The return
+value from \fBsource\fR is the return value of the last command
+executed in the script. If an error occurs in evaluating the contents
+of the script then the \fBsource\fR command will return that error.
+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
+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
+.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 \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.
+.SH EXAMPLE
+.PP
+Run the script in the file \fBfoo.tcl\fR and then the script in the
+file \fBbar.tcl\fR:
+.PP
+.CS
+\fBsource\fR foo.tcl
+\fBsource\fR bar.tcl
+.CE
+.PP
+Alternatively:
+.PP
+.CS
+foreach scriptFile {foo.tcl bar.tcl} {
+ \fBsource\fR $scriptFile
+}
+.CE
+.SH "SEE ALSO"
+file(n), cd(n), encoding(n), info(n)
+.SH KEYWORDS
+file, script
diff --git a/library/msgcat/doc/split.n b/library/msgcat/doc/split.n
new file mode 100644
index 0000000..e3259df
--- /dev/null
+++ b/library/msgcat/doc/split.n
@@ -0,0 +1,93 @@
+'\"
+'\" 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 split n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+split \- Split a string into a proper Tcl list
+.SH SYNOPSIS
+\fBsplit \fIstring \fR?\fIsplitChars\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Returns a list created by splitting \fIstring\fR at each character
+that is in the \fIsplitChars\fR argument.
+Each element of the result list will consist of the
+characters from \fIstring\fR that lie between instances of the
+characters in \fIsplitChars\fR.
+Empty list elements will be generated if \fIstring\fR contains
+adjacent characters in \fIsplitChars\fR, or if the first or last
+character of \fIstring\fR is in \fIsplitChars\fR.
+If \fIsplitChars\fR is an empty string then each character of
+\fIstring\fR becomes a separate element of the result list.
+\fISplitChars\fR defaults to the standard white-space characters.
+.SH EXAMPLES
+.PP
+Divide up a USENET group name into its hierarchical components:
+.PP
+.CS
+\fBsplit\fR "comp.lang.tcl" .
+ \fI\(-> comp lang tcl\fR
+.CE
+.PP
+See how the \fBsplit\fR command splits on \fIevery\fR character in
+\fIsplitChars\fR, which can result in information loss if you are not
+careful:
+.PP
+.CS
+\fBsplit\fR "alpha beta gamma" "temp"
+ \fI\(-> al {ha b} {} {a ga} {} a\fR
+.CE
+.PP
+Extract the list words from a string that is not a well-formed list:
+.PP
+.CS
+\fBsplit\fR "Example with {unbalanced brace character"
+ \fI\(-> Example with \e{unbalanced brace character\fR
+.CE
+.PP
+Split a string into its constituent characters
+.PP
+.CS
+\fBsplit\fR "Hello world" {}
+ \fI\(-> H e l l o { } w o r l d\fR
+.CE
+.SS "PARSING RECORD-ORIENTED FILES"
+.PP
+Parse a Unix /etc/passwd file, which consists of one entry per line,
+with each line consisting of a colon-separated list of fields:
+.PP
+.CS
+## Read the file
+set fid [open /etc/passwd]
+set content [read $fid]
+close $fid
+
+## Split into records on newlines
+set records [\fBsplit\fR $content "\en"]
+
+## Iterate over the records
+foreach rec $records {
+
+ ## Split into fields on colons
+ set fields [\fBsplit\fR $rec ":"]
+
+ ## Assign fields to variables and print some out...
+ lassign $fields \e
+ userName password uid grp longName homeDir shell
+ puts "$longName uses [file tail $shell] for a login shell"
+}
+.CE
+.SH "SEE ALSO"
+join(n), list(n), string(n)
+.SH KEYWORDS
+list, split, string
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/string.n b/library/msgcat/doc/string.n
new file mode 100644
index 0000000..1cbea16
--- /dev/null
+++ b/library/msgcat/doc/string.n
@@ -0,0 +1,441 @@
+.\"
+.\" 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!
+.SH NAME
+string \- Manipulate strings
+.SH SYNOPSIS
+\fBstring \fIoption arg \fR?\fIarg ...?\fR
+.BE
+.SH DESCRIPTION
+.PP
+Performs one of several string operations, depending on \fIoption\fR.
+The legal \fIoption\fRs (which may be abbreviated) are:
+.TP
+\fBstring bytelength \fIstring\fR
+.
+Returns a decimal string giving the number of bytes used to represent
+\fIstring\fR in memory. Because UTF\-8 uses one to three bytes to
+represent Unicode characters, the byte length will not be the same as
+the character length in general. The cases where a script cares about
+the byte length are rare. In almost all cases, you should use the
+\fBstring length\fR operation (including determining the length of a
+Tcl ByteArray object). Refer to the \fBTcl_NumUtfChars\fR manual
+entry for more details on the UTF\-8 representation.
+.RS
+.PP
+\fICompatibility note:\fR it is likely that this subcommand will be
+withdrawn in a future version of Tcl. It is better to use the
+\fBencoding convertto\fR command to convert a string to a known
+encoding and then apply \fBstring length\fR to that.
+.RE
+.TP
+\fBstring compare\fR ?\fB\-nocase\fR? ?\fB\-length int\fR? \fIstring1 string2\fR
+.
+Perform a character-by-character comparison of strings \fIstring1\fR
+and \fIstring2\fR. Returns \-1, 0, or 1, depending on whether
+\fIstring1\fR is lexicographically less than, equal to, or greater
+than \fIstring2\fR. If \fB\-length\fR is specified, then only 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 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
+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 \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 described in \fBSTRING INDICES\fR), then the search is
+constrained to start with the character in \fIhaystackString\fR specified by
+the index. For example,
+.RS
+.PP
+.CS
+\fBstring first a 0a23456789abcdef 5\fR
+.CE
+.PP
+will return \fB10\fR, but
+.PP
+.CS
+\fBstring first a 0123456789abcdef 11\fR
+.CE
+.PP
+will return \fB\-1\fR.
+.RE
+.TP
+\fBstring index \fIstring charIndex\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 described in the
+\fBSTRING INDICES\fR section.
+.RS
+.PP
+If \fIcharIndex\fR is less than 0 or greater than or equal to the
+length of the string then this command returns an empty string.
+.RE
+.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 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
+will not be set if \fBstring is\fR returns 1. The following character
+classes are recognized (the class name can be abbreviated):
+.RS
+.IP \fBalnum\fR 12
+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 \eu0080 (those that are in the
+7\-bit ascii range).
+.IP \fBboolean\fR 12
+Any of the forms allowed to \fBTcl_GetBoolean\fR.
+.IP \fBcontrol\fR 12
+Any Unicode control character.
+.IP \fBdigit\fR 12
+Any Unicode digit character. Note that this includes characters
+outside of the [0\-9] range.
+.IP \fBdouble\fR 12
+Any of the valid forms for a double in Tcl, with optional surrounding
+whitespace. In case of under/overflow in the value, 0 is returned and
+the \fIvarname\fR will contain \-1.
+.IP \fBentier\fR 12
+.VS 8.6
+Any of the valid string formats for an integer value of arbitrary size
+in Tcl, with optional surrounding whitespace. The formats accepted are
+exactly those accepted by the C routine \fBTcl_GetBignumFromObj\fR.
+.VE
+.IP \fBfalse\fR 12
+Any of the forms allowed to \fBTcl_GetBoolean\fR where the value is
+false.
+.IP \fBgraph\fR 12
+Any Unicode printing character, except space.
+.IP \fBinteger\fR 12
+Any of the valid string formats for a 32-bit integer value in Tcl,
+with optional surrounding whitespace. In case of under/overflow in
+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
+Any Unicode printing character, including space.
+.IP \fBpunct\fR 12
+Any Unicode punctuation character.
+.IP \fBspace\fR 12
+Any Unicode space character.
+.IP \fBtrue\fR 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.
+.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.
+.IP \fBwordchar\fR 12
+Any Unicode word character. That is any alphanumeric character, and
+any Unicode connector punctuation characters (e.g. underscore).
+.IP \fBxdigit\fR 12
+Any hexadecimal digit character ([0\-9A\-Fa\-f]).
+.PP
+In the case of \fBboolean\fR, \fBtrue\fR and \fBfalse\fR, if the
+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 \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 described in \fBSTRING INDICES\fR), then only the
+characters in \fIhaystackString\fR at or before the specified \fIlastIndex\fR
+will be considered by the search. For example,
+.RS
+.PP
+.CS
+\fBstring last a 0a23456789abcdef 15\fR
+.CE
+.PP
+will return \fB10\fR, but
+.PP
+.CS
+\fBstring last a 0a23456789abcdef 9\fR
+.CE
+.PP
+will return \fB1\fR.
+.RE
+.TP
+\fBstring length \fIstring\fR
+.
+Returns a decimal string giving the number of characters in
+\fIstring\fR. Note that this is not necessarily the same as the
+number of bytes used to store the string. If the object is a
+ByteArray object (such as those returned from reading a binary encoded
+channel), then this will return the actual byte length of the object.
+.TP
+\fBstring map\fR ?\fB\-nocase\fR? \fImapping string\fR
+.
+Replaces substrings in \fIstring\fR based on the key-value pairs in
+\fImapping\fR. \fImapping\fR is a list of \fIkey value key value ...\fR
+as in the form returned by \fBarray get\fR. Each instance of a
+key in the string will be replaced with its corresponding value. If
+\fB\-nocase\fR is specified, then matching is done without regard to
+case differences. Both \fIkey\fR and \fIvalue\fR may be multiple
+characters. Replacement is done in an ordered manner, so the key
+appearing first in the list will be checked first, and so on.
+\fIstring\fR is only iterated over once, so earlier key replacements
+will have no affect for later key matches. For example,
+.RS
+.PP
+.CS
+\fBstring map {abc 1 ab 2 a 3 1 0} 1abcaababcabababc\fR
+.CE
+.PP
+will return the string \fB01321221\fR.
+.PP
+Note that if an earlier \fIkey\fR is a prefix of a later one, it will
+completely mask the later one. So if the previous example is
+reordered like this,
+.PP
+.CS
+\fBstring map {1 0 ab 2 a 3 abc 1} 1abcaababcabababc\fR
+.CE
+.PP
+it will return the string \fB02c322c222c\fR.
+.RE
+.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 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:
+.RS
+.IP \fB*\fR 10
+Matches any sequence of characters in \fIstring\fR, including a null
+string.
+.IP \fB?\fR 10
+Matches any single character in \fIstring\fR.
+.IP \fB[\fIchars\fB]\fR 10
+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
+.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
+\fIpattern\fR.
+.RE
+.TP
+\fBstring range \fIstring first last\fR
+.
+Returns a range of consecutive characters from \fIstring\fR, starting
+with the character whose index is \fIfirst\fR and ending with the
+character whose index is \fIlast\fR. An index of 0 refers to the first
+character of the string. \fIfirst\fR and \fIlast\fR may be specified
+as for the \fBindex\fR method. If \fIfirst\fR is less than zero then
+it is treated as if it were zero, 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 then an empty
+string is returned.
+.TP
+\fBstring repeat \fIstring count\fR
+.
+Returns \fIstring\fR repeated \fIcount\fR number of times.
+.TP
+\fBstring replace \fIstring first last\fR ?\fInewstring\fR?
+.
+Removes a range of consecutive characters from \fIstring\fR, starting
+with the character whose index is \fIfirst\fR and ending with the
+character whose index is \fIlast\fR. An index of 0 refers to the
+first character of the string. \fIFirst\fR and \fIlast\fR may be
+specified as for the \fBindex\fR method. If \fInewstring\fR is
+specified, then it is placed in the removed character range. If
+\fIfirst\fR is less than zero then it is treated as if it were zero,
+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.
+.TP
+\fBstring reverse \fIstring\fR
+.
+Returns a string that is the same length as \fIstring\fR but with its
+characters in the reverse order.
+.TP
+\fBstring tolower \fIstring\fR ?\fIfirst\fR? ?\fIlast\fR?
+.
+Returns a value equal to \fIstring\fR except that all upper (or title)
+case letters have been converted to lower case. If \fIfirst\fR is
+specified, it refers to the first char index in the string to start
+modifying. If \fIlast\fR is specified, it refers to the char index in
+the string to stop at (inclusive). \fIfirst\fR and \fIlast\fR may be
+specified using the forms described in \fBSTRING INDICES\fR.
+.TP
+\fBstring totitle \fIstring\fR ?\fIfirst\fR? ?\fIlast\fR?
+.
+Returns a value equal to \fIstring\fR except that the first character
+in \fIstring\fR is converted to its Unicode title case variant (or
+upper case if there is no title case variant) and the rest of the
+string is converted to lower case. If \fIfirst\fR is specified, it
+refers to the first char index in the string to start modifying. If
+\fIlast\fR is specified, it refers to the char index in the string to
+stop at (inclusive). \fIfirst\fR and \fIlast\fR may be specified
+using the forms described in \fBSTRING INDICES\fR.
+.TP
+\fBstring toupper \fIstring\fR ?\fIfirst\fR? ?\fIlast\fR?
+.
+Returns a value equal to \fIstring\fR except that all lower (or title)
+case letters have been converted to upper case. If \fIfirst\fR is
+specified, it refers to the first char index in the string to start
+modifying. If \fIlast\fR is specified, it refers to the char index in
+the string to stop at (inclusive). \fIfirst\fR and \fIlast\fR may be
+specified using the forms described in \fBSTRING INDICES\fR.
+.TP
+\fBstring trim \fIstring\fR ?\fIchars\fR?
+.
+Returns a value equal to \fIstring\fR except that any leading or
+trailing characters present in the string given by \fIchars\fR are removed. If
+\fIchars\fR is not specified then white space is removed (spaces,
+tabs, newlines, and carriage returns).
+.TP
+\fBstring trimleft \fIstring\fR ?\fIchars\fR?
+.
+Returns a value equal to \fIstring\fR except that any leading
+characters present in the string given by \fIchars\fR are removed. If
+\fIchars\fR is not specified then white space is removed (spaces,
+tabs, newlines, and carriage returns).
+.TP
+\fBstring trimright \fIstring\fR ?\fIchars\fR?
+.
+Returns a value equal to \fIstring\fR except that any trailing
+characters present in the string given by \fIchars\fR are removed. If
+\fIchars\fR is not specified then white space is removed (spaces,
+tabs, newlines, and carriage returns).
+.TP
+\fBstring wordend \fIstring charIndex\fR
+.
+Returns the index of the character just after the last one in the word
+containing character \fIcharIndex\fR of \fIstring\fR. \fIcharIndex\fR
+may be specified using the forms in \fBSTRING INDICES\fR. A word is
+considered to be any contiguous range of alphanumeric (Unicode letters
+or decimal digits) or underscore (Unicode connector punctuation)
+characters, or any single character other than these.
+.TP
+\fBstring wordstart \fIstring charIndex\fR
+.
+Returns the index of the first character in the word containing character
+\fIcharIndex\fR of \fIstring\fR. \fIcharIndex\fR may be specified using the
+forms in \fBSTRING INDICES\fR. A word is considered to be any contiguous
+range of alphanumeric (Unicode letters or decimal digits) or underscore
+(Unicode connector punctuation) characters, or any single character other than
+these.
+.SH "STRING INDICES"
+.PP
+When referring to indices into a string (e.g., for \fBstring index\fR
+or \fBstring range\fR) the following formats are supported:
+.IP \fIinteger\fR 10
+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 (e.g., \fBend\fR would refer to the
+.QW d
+in
+.QW abcd ).
+.IP \fBend\-\fIN\fR 10
+The last char of the string minus the specified integer offset \fIN\fR (e.g.,
+.QW \fBend\-1\fR
+would refer to the
+.QW c
+in
+.QW abcd ).
+.IP \fBend+\fIN\fR 10
+The last char of the string plus the specified integer offset \fIN\fR (e.g.,
+.QW \fBend+\-1\fR
+would refer to the
+.QW c
+in
+.QW abcd ).
+.IP \fIM\fB+\fIN\fR 10
+The char specified at the integral index that is the sum of
+integer values \fIM\fR and \fIN\fR (e.g.,
+.QW \fB1+1\fR
+would refer to the
+.QW c
+in
+.QW abcd ).
+.IP \fIM\fB\-\fIN\fR 10
+The char specified at the integral index that is the difference of
+integer values \fIM\fR and \fIN\fR (e.g.,
+.QW \fB2\-1\fR
+would refer to the
+.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.
+.SH EXAMPLE
+.PP
+Test if the string in the variable \fIstring\fR is a proper non-empty
+prefix of the string \fBfoobar\fR.
+.PP
+.CS
+set length [\fBstring length\fR $string]
+if {$length == 0} {
+ set isPrefix 0
+} else {
+ set isPrefix [\fBstring equal\fR \-length $length $string "foobar"]
+}
+.CE
+.SH "SEE ALSO"
+expr(n), list(n)
+.SH KEYWORDS
+case conversion, compare, index, match, pattern, string, word, equal,
+ctype, character, reverse
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/library/msgcat/doc/subst.n b/library/msgcat/doc/subst.n
new file mode 100644
index 0000000..aba2bc9
--- /dev/null
+++ b/library/msgcat/doc/subst.n
@@ -0,0 +1,164 @@
+'\"
+'\" Copyright (c) 1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 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 subst n 7.4 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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,
+and backslash substitutions on its \fIstring\fR argument and
+returns the fully-substituted result.
+The substitutions are performed in exactly the same way as for
+Tcl commands.
+As a result, the \fIstring\fR argument is actually substituted twice,
+once by the Tcl parser in the usual fashion for Tcl commands, and
+again by the \fIsubst\fR command.
+.PP
+If any of the \fB\-nobackslashes\fR, \fB\-nocommands\fR, or
+\fB\-novariables\fR are specified, then the corresponding substitutions
+are not performed.
+For example, if \fB\-nocommands\fR is specified, command substitution
+is not performed: open and close brackets are treated as ordinary characters
+with no special interpretation.
+.PP
+Note that the substitution of one kind can include substitution of
+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
+\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
+substitution, the result of the whole substitution will be the
+string (as substituted) up to the start of the substitution that
+raised the exception. If a continue exception occurs during the
+evaluation of a command or variable substitution, an empty string
+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 \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.
+.SH EXAMPLES
+.PP
+When it performs its substitutions, \fIsubst\fR does not give any
+special treatment to double quotes or curly braces (except within
+command substitutions) so the script
+.PP
+.CS
+set a 44
+\fBsubst\fR {xyz {$a}}
+.CE
+.PP
+returns
+.QW "\fBxyz {44}\fR" ,
+not
+.QW "\fBxyz {$a}\fR"
+and the script
+.PP
+.CS
+set a "p\e} q \e{r"
+\fBsubst\fR {xyz {$a}}
+.CE
+.PP
+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.
+.PP
+.CS
+set a 44
+\fBsubst\fR -novariables {$a [format $a]}
+.CE
+.PP
+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.
+.PP
+.CS
+proc b {} {return c}
+array set a {c c [b] tricky}
+\fBsubst\fR -nocommands {[b] $a([b])}
+.CE
+.PP
+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
+rest of \fIstring\fR respectively, giving script authors more options
+when processing text using \fIsubst\fR. For example, the script
+.PP
+.CS
+\fBsubst\fR {abc,[break],def}
+.CE
+.PP
+returns
+.QW \fBabc,\fR ,
+not
+.QW \fBabc,,def\fR
+and the script
+.PP
+.CS
+\fBsubst\fR {abc,[continue;expr {1+2}],def}
+.CE
+.PP
+returns
+.QW \fBabc,,def\fR ,
+not
+.QW \fBabc,3,def\fR .
+.PP
+Other exceptional return codes substitute the returned value
+.PP
+.CS
+\fBsubst\fR {abc,[return foo;expr {1+2}],def}
+.CE
+.PP
+returns
+.QW \fBabc,foo,def\fR ,
+not
+.QW \fBabc,3,def\fR
+and
+.PP
+.CS
+\fBsubst\fR {abc,[return -code 10 foo;expr {1+2}],def}
+.CE
+.PP
+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, quoting, substitution, variable substitution
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/library/msgcat/doc/switch.n b/library/msgcat/doc/switch.n
new file mode 100644
index 0000000..acde6cb
--- /dev/null
+++ b/library/msgcat/doc/switch.n
@@ -0,0 +1,186 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH switch n 8.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+switch \- Evaluate one of several scripts, depending on a given value
+.SH SYNOPSIS
+\fBswitch \fR?\fIoptions\fR?\fI string pattern body \fR?\fIpattern body \fR...?
+.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
+the \fIpattern\fR arguments in order.
+As soon as it finds a \fIpattern\fR that matches \fIstring\fR it
+evaluates the following \fIbody\fR argument by passing it recursively
+to the Tcl interpreter and returns the result of that evaluation.
+If the last \fIpattern\fR argument is \fBdefault\fR then it matches
+anything.
+If no \fIpattern\fR argument
+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
+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).
+The following options are currently supported:
+.TP 10
+\fB\-exact\fR
+.
+Use exact matching when comparing \fIstring\fR to a pattern. This
+is the default.
+.TP 10
+\fB\-glob\fR
+.
+When matching \fIstring\fR to the patterns, use glob-style matching
+(i.e. the same as implemented by the \fBstring match\fR command).
+.TP 10
+\fB\-regexp\fR
+.
+When matching \fIstring\fR to the patterns, use regular
+expression matching
+(as described in the \fBre_syntax\fR reference page).
+.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.
+.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.
+This is not required when the matching patterns and bodies are grouped
+together in a single argument.
+.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;
+this form is convenient if substitutions are desired on some of the
+patterns or commands.
+The second form places all of the patterns and commands together into
+a single argument; the argument must have proper list structure, with
+the elements of the list being the patterns and commands.
+The second form makes it easy to construct multi-line switch commands,
+since the braces around the whole list make it unnecessary to include a
+backslash at the end of each line.
+Since the \fIpattern\fR arguments are in braces in the second form,
+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
+.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
+.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.
+.PP
+Beware of how you place comments in \fBswitch\fR commands. Comments
+should only be placed \fBinside\fR the execution body of one of the
+patterns, and not intermingled with the patterns.
+.SH "EXAMPLES"
+.PP
+The \fBswitch\fR command can match against variables and not just
+literals, as shown here (the result is \fI2\fR):
+.PP
+.CS
+set foo "abc"
+\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
+writing regular expressions with alternations, as can be seen here
+(this returns \fI1\fR):
+.PP
+.CS
+\fBswitch\fR \-glob aaab {
+ a*b \-
+ b {expr {1}}
+ a* {expr {2}}
+ default {expr {3}}
+}
+.CE
+.PP
+Whenever nothing matches, the \fBdefault\fR clause (which must be
+last) is taken. This example has a result of \fI3\fR:
+.PP
+.CS
+\fBswitch\fR xyz {
+ a \-
+ b {
+ # Correct Comment Placement
+ expr {1}
+ }
+ c {
+ expr {2}
+ }
+ default {
+ expr {3}
+ }
+}
+.CE
+.PP
+When matching against regular expressions, information about what
+exactly matched is easily obtained using the \fB\-matchvar\fR option:
+.PP
+.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
+.SH "SEE ALSO"
+for(n), if(n), regexp(n)
+.SH KEYWORDS
+switch, match, regular expression
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/library/msgcat/doc/tailcall.n b/library/msgcat/doc/tailcall.n
new file mode 100644
index 0000000..6a88aca
--- /dev/null
+++ b/library/msgcat/doc/tailcall.n
@@ -0,0 +1,69 @@
+'\"
+'\" 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 tailcall n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+tailcall \- Replace the current procedure with another command
+.SH SYNOPSIS
+\fBtailcall \fIcommand\fR ?\fIarg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fBtailcall\fR command replaces the currently executing procedure, lambda
+application, or method with another command. The \fIcommand\fR, which will
+have \fIarg ...\fR passed as arguments if they are supplied, will be looked up
+in the current namespace context, not in the caller's. Apart from that
+difference in resolution, it is equivalent to:
+.PP
+.CS
+return [uplevel 1 [list \fIcommand\fR ?\fIarg ...\fR?]]
+.CE
+.PP
+This command may not be invoked from within an \fBuplevel\fR into a procedure
+or inside a \fBcatch\fR inside a procedure or lambda.
+'\" TODO: sort out the mess with the [try] command!
+.SH EXAMPLE
+.PP
+Compute the factorial of a number.
+.PP
+.CS
+proc factorial {n {accum 1}} {
+ if {$n < 2} {
+ return $accum
+ }
+ \fBtailcall\fR factorial [expr {$n - 1}] [expr {$accum * $n}]
+}
+.CE
+.PP
+Print the elements of a list with alternating lines having different
+indentations.
+.PP
+.CS
+proc printList {theList} {
+ if {[llength $theList]} {
+ puts "> [lindex $theList 0]"
+ \fBtailcall\fR printList2 [lrange $theList 1 end]
+ }
+}
+proc printList2 {theList} {
+ if {[llength $theList]} {
+ puts "< [lindex $theList 0]"
+ \fBtailcall\fR printList [lrange $theList 1 end]
+ }
+}
+.CE
+.SH "SEE ALSO"
+apply(n), proc(n), uplevel(n)
+.SH KEYWORDS
+call, recursion, tail recursion
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/library/msgcat/doc/tclsh.1 b/library/msgcat/doc/tclsh.1
new file mode 100644
index 0000000..2819408
--- /dev/null
+++ b/library/msgcat/doc/tclsh.1
@@ -0,0 +1,147 @@
+'\"
+'\" 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 tclsh 1 "" Tcl "Tcl Applications"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+tclsh \- Simple shell containing Tcl interpreter
+.SH SYNOPSIS
+\fBtclsh\fR ?-encoding \fIname\fR? ?\fIfileName arg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+\fBTclsh\fR is a shell-like application that reads Tcl commands
+from its standard input or from a file and evaluates them.
+If invoked with no arguments then it runs interactively, reading
+Tcl commands from standard input and printing command results and
+error messages to standard output.
+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, 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 few arguments
+specify the name of a script file, and, optionally, the encoding of
+the text data stored in that script file. 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.
+The end of the file may be marked either by the physical end of
+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
+.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.
+.PP
+If you create a Tcl script in a file whose first line is
+.PP
+.CS
+\fB#!/usr/local/bin/tclsh\fR
+.CE
+.PP
+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 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.
+.PP
+An even better approach is to start your script files with the
+following three lines:
+.PP
+.CS
+\fB#!/bin/sh
+# the next line restarts using tclsh \e
+exec tclsh "$0" ${1+"$@"}\fR
+.CE
+.PP
+This approach has three advantages over the approach in the previous
+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.
+Third, this approach will work even if \fBtclsh\fR is
+itself a shell script (this is done on some systems in order to
+handle multiple architectures or operating systems: the \fBtclsh\fR
+script selects one of several binaries to run). The three lines
+cause both \fBsh\fR and \fBtclsh\fR to process the script, but the
+\fBexec\fR is only executed by \fBsh\fR.
+\fBsh\fR processes the script first; it treats the second
+line as a comment and executes the third line.
+The \fBexec\fR statement cause the shell to stop processing and
+instead to start up \fBtclsh\fR to reprocess the entire script.
+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
+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.
+.SH "VARIABLES"
+.PP
+\fBTclsh\fR sets the following Tcl variables:
+.TP 15
+\fBargc\fR
+.
+Contains a count of the number of \fIarg\fR arguments (0 if none),
+not including the name of the script file.
+.TP 15
+\fBargv\fR
+.
+Contains a Tcl list whose elements are the \fIarg\fR arguments,
+in order, or an empty string if there are no \fIarg\fR arguments.
+.TP 15
+\fBargv0\fR
+.
+Contains \fIfileName\fR if it was specified.
+Otherwise, contains the name by which \fBtclsh\fR was invoked.
+.TP 15
+\fBtcl_interactive\fR
+.
+Contains 1 if \fBtclsh\fR is running interactively (no
+\fIfileName\fR was specified and standard input is a terminal-like
+device), 0 otherwise.
+.SH PROMPTS
+.PP
+When \fBtclsh\fR is invoked interactively it normally prompts for each
+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 is not yet complete;
+if \fBtcl_prompt2\fR is not set then no prompt is output for
+incomplete commands.
+.SH "STANDARD CHANNELS"
+.PP
+See \fBTcl_StandardChannels\fR for more explanations.
+.SH "SEE ALSO"
+encoding(n), fconfigure(n), tclvars(n)
+.SH KEYWORDS
+application, argument, interpreter, prompt, script file, shell
diff --git a/library/msgcat/doc/tcltest.n b/library/msgcat/doc/tcltest.n
new file mode 100644
index 0000000..731bed7
--- /dev/null
+++ b/library/msgcat/doc/tcltest.n
@@ -0,0 +1,1257 @@
+'\"
+'\" Copyright (c) 1990-1994 The Regents of the University of California
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\" Copyright (c) 2000 Ajuba Solutions
+'\" Contributions from Don Porter, NIST, 2002. (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 "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\fR ?\fB2.3\fR?
+
+\fBtcltest::test \fIname description\fR ?\fI\-option value ...\fR?
+\fBtcltest::test \fIname description\fR ?\fIconstraints\fR? \fIbody result\fR
+
+\fBtcltest::loadTestedCommands\fR
+\fBtcltest::makeDirectory \fIname\fR ?\fIdirectory\fR?
+\fBtcltest::removeDirectory \fIname\fR ?\fIdirectory\fR?
+\fBtcltest::makeFile \fIcontents name\fR ?\fIdirectory\fR?
+\fBtcltest::removeFile \fIname\fR ?\fIdirectory\fR?
+\fBtcltest::viewFile \fIname\fR ?\fIdirectory\fR?
+\fBtcltest::cleanupTests \fR?\fIrunningMultipleTests\fR?
+\fBtcltest::runAllTests\fR
+
+\fBtcltest::configure\fR
+\fBtcltest::configure \fI\-option\fR
+\fBtcltest::configure \fI\-option value\fR ?\fI\-option value ...\fR?
+\fBtcltest::customMatch \fImode command\fR
+\fBtcltest::testConstraint \fIconstraint\fR ?\fIvalue\fR?
+\fBtcltest::outputChannel \fR?\fIchannelID\fR?
+\fBtcltest::errorChannel \fR?\fIchannelID\fR?
+\fBtcltest::interpreter \fR?\fIinterp\fR?
+
+\fBtcltest::debug \fR?\fIlevel\fR?
+\fBtcltest::errorFile \fR?\fIfilename\fR?
+\fBtcltest::limitConstraints \fR?\fIboolean\fR?
+\fBtcltest::loadFile \fR?\fIfilename\fR?
+\fBtcltest::loadScript \fR?\fIscript\fR?
+\fBtcltest::match \fR?\fIpatternList\fR?
+\fBtcltest::matchDirectories \fR?\fIpatternList\fR?
+\fBtcltest::matchFiles \fR?\fIpatternList\fR?
+\fBtcltest::outputFile \fR?\fIfilename\fR?
+\fBtcltest::preserveCore \fR?\fIlevel\fR?
+\fBtcltest::singleProcess \fR?\fIboolean\fR?
+\fBtcltest::skip \fR?\fIpatternList\fR?
+\fBtcltest::skipDirectories \fR?\fIpatternList\fR?
+\fBtcltest::skipFiles \fR?\fIpatternList\fR?
+\fBtcltest::temporaryDirectory \fR?\fIdirectory\fR?
+\fBtcltest::testsDirectory \fR?\fIdirectory\fR?
+\fBtcltest::verbose \fR?\fIlevel\fR?
+
+\fBtcltest::test \fIname description optionList\fR
+\fBtcltest::bytestring \fIstring\fR
+\fBtcltest::normalizeMsg \fImsg\fR
+\fBtcltest::normalizePath \fIpathVar\fR
+\fBtcltest::workingDirectory \fR?\fIdir\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBtcltest\fR package provides several utility commands useful
+in the construction of test suites for code instrumented to be
+run by evaluation of Tcl commands. Notably the built-in commands
+of the Tcl library itself are tested by a test suite using the
+tcltest package.
+.PP
+All the commands provided by the \fBtcltest\fR package are defined
+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
+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
+test suites.
+.PP
+See \fBCREATING TEST SUITES WITH TCLTEST\fR below for an extended example
+of how to use the commands of \fBtcltest\fR to produce test suites
+for your Tcl-enabled code.
+.SH COMMANDS
+.TP
+\fBtest\fR \fIname description\fR ?\fI\-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
+test, as configured by the options of \fBtcltest\fR. The
+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.
+.TP
+\fBtest\fR \fIname description\fR ?\fIconstraints\fR? \fIbody result\fR
+.
+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
+.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
+.QW \- .
+.TP
+\fBloadTestedCommands\fR
+.
+Evaluates in the caller's context the script specified by
+\fBconfigure \-load\fR or \fBconfigure \-loadfile\fR.
+Returns the result of that script evaluation, including any error
+raised by the script. Use this command and the related
+configuration options to provide the commands to be tested to
+the interpreter running the test suite.
+.TP
+\fBmakeFile\fR \fIcontents name\fR ?\fIdirectory\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.
+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.
+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\fR ?\fIdirectory\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.
+Returns an empty string. Use this command to delete files
+created by \fBmakeFile\fR.
+.TP
+\fBmakeDirectory\fR \fIname\fR ?\fIdirectory\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 default value of \fIdirectory\fR is the directory
+\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
+\fBremoveDirectory\fR \fIname\fR ?\fIdirectory\fR?
+.
+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.
+Returns an empty string. Use this command to delete any directories
+created by \fBmakeDirectory\fR.
+.TP
+\fBviewFile\fR \fIfile\fR ?\fIdirectory\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.
+The default value of \fIdirectory\fR is the directory
+\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
+the system encoding, so its usefulness is limited to text
+files.
+.TP
+\fBcleanupTests\fR
+.
+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.
+.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 global \fBenv\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.
+.SS "CONFIGURATION COMMANDS"
+.TP
+\fBconfigure\fR
+.
+Returns the list of configurable options supported by \fBtcltest\fR.
+See \fBCONFIGURABLE OPTIONS\fR below for the full list of options,
+their valid values, and their effect on \fBtcltest\fR operations.
+.TP
+\fBconfigure \fIoption\fR
+.
+Returns the current value of the supported configurable option \fIoption\fR.
+Raises an error if \fIoption\fR is not a supported configurable option.
+.TP
+\fBconfigure \fIoption value\fR ?\fI\-option value ...\fR?
+.
+Sets the value of each configurable option \fIoption\fR to the
+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
+arguments are not processed.
+.RS
+.PP
+If the environment variable \fB::env(TCLTEST_OPTIONS)\fR exists when
+the \fBtcltest\fR package is loaded (by \fBpackage require\fR \fBtcltest\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
+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
+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.
+.TP
+\fBtestConstraint \fIconstraint\fR ?\fIboolean\fR?
+.
+Sets or returns the boolean value associated with the named \fIconstraint\fR.
+See \fBTEST CONSTRAINTS\fR below for more information.
+.TP
+\fBinterpreter\fR ?\fIexecutableName\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 ?\fIchannelID\fR?
+.
+Sets or returns the output channel ID. This defaults to \fBstdout\fR.
+Any test that prints test related output should send
+that output to \fBoutputChannel\fR rather than letting
+that output default to \fBstdout\fR.
+.TP
+\fBerrorChannel\fR ?\fIchannelID\fR?
+.
+Sets or returns the error channel ID. This defaults to \fBstderr\fR.
+Any test that prints error messages should send
+that output to \fBerrorChannel\fR rather than printing
+directly to \fBstderr\fR.
+.SS "SHORTCUT CONFIGURATION COMMANDS"
+.TP
+\fBdebug\fR ?\fIlevel\fR?
+.
+Same as
+.QW "\fBconfigure \-debug\fR ?\fIlevel\fR?" .
+.TP
+\fBerrorFile\fR ?\fIfilename\fR?
+.
+Same as
+.QW "\fBconfigure \-errfile\fR ?\fIfilename\fR?" .
+.TP
+\fBlimitConstraints\fR ?\fIboolean\fR?
+.
+Same as
+.QW "\fBconfigure \-limitconstraints\fR ?\fIboolean\fR?" .
+.TP
+\fBloadFile\fR ?\fIfilename\fR?
+.
+Same as
+.QW "\fBconfigure \-loadfile\fR ?\fIfilename\fR?" .
+.TP
+\fBloadScript\fR ?\fIscript\fR?
+.
+Same as
+.QW "\fBconfigure \-load\fR ?\fIscript\fR?" .
+.TP
+\fBmatch\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-match\fR ?\fIpatternList\fR?" .
+.TP
+\fBmatchDirectories\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-relateddir\fR ?\fIpatternList\fR?" .
+.TP
+\fBmatchFiles\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-file\fR ?\fIpatternList\fR?" .
+.TP
+\fBoutputFile\fR ?\fIfilename\fR?
+.
+Same as
+.QW "\fBconfigure \-outfile\fR ?\fIfilename\fR?" .
+.TP
+\fBpreserveCore\fR ?\fIlevel\fR?
+.
+Same as
+.QW "\fBconfigure \-preservecore\fR ?\fIlevel\fR?" .
+.TP
+\fBsingleProcess\fR ?\fIboolean\fR?
+.
+Same as
+.QW "\fBconfigure \-singleproc\fR ?\fIboolean\fR?" .
+.TP
+\fBskip\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-skip\fR ?\fIpatternList\fR?" .
+.TP
+\fBskipDirectories\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-asidefromdir\fR ?\fIpatternList\fR?" .
+.TP
+\fBskipFiles\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-notfile\fR ?\fIpatternList\fR?" .
+.TP
+\fBtemporaryDirectory\fR ?\fIdirectory\fR?
+.
+Same as
+.QW "\fBconfigure \-tmpdir\fR ?\fIdirectory\fR?" .
+.TP
+\fBtestsDirectory\fR ?\fIdirectory\fR?
+.
+Same as
+.QW "\fBconfigure \-testdir\fR ?\fIdirectory\fR?" .
+.TP
+\fBverbose\fR ?\fIlevel\fR?
+.
+Same as
+.QW "\fBconfigure \-verbose\fR ?\fIlevel\fR?" .
+.SS "OTHER COMMANDS"
+.PP
+The remaining commands provided by \fBtcltest\fR have better
+alternatives provided by \fBtcltest\fR or \fBTcl\fR itself. They
+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
+argument quoted by braces, rather than needing to backslash quote
+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
+an unfortunate attempt to overthrow Tcl's substitution rules by
+performing substitutions on some of the list elements as an attempt to
+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.
+.TP
+\fBworkingDirectory\fR ?\fIdirectoryName\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.
+.TP
+\fBnormalizeMsg \fImsg\fR
+.
+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
+results.
+.TP
+\fBnormalizePath \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
+is a sufficient replacement.
+.TP
+\fBbytestring \fIstring\fR
+.
+Construct a string that consists of the requested sequence of bytes,
+as opposed to a string of properly formed UTF-8 characters using the
+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\fR
+\fBidentity\fR.
+.SH TESTS
+.PP
+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
+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.
+.PP
+The valid options for \fBtest\fR are summarized:
+.PP
+.CS
+\fBtest\fR \fIname\fR \fIdescription\fR
+ ?\fB\-constraints \fIkeywordList|expression\fR?
+ ?\fB\-setup \fIsetupScript\fR?
+ ?\fB\-body \fItestScript\fR?
+ ?\fB\-cleanup \fIcleanupScript\fR?
+ ?\fB\-result \fIexpectedAnswer\fR?
+ ?\fB\-output \fIexpectedOutput\fR?
+ ?\fB\-errorOutput \fIexpectedError\fR?
+ ?\fB\-returnCodes \fIcodeList\fR?
+ ?\fB\-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
+.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
+to the lists of string matching patterns returned by
+\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.
+.PP
+The \fIdescription\fR should be a short textual description of the
+test. The \fIdescription\fR is included in output produced by the
+test, typically test failure messages. Good \fIdescription\fR values
+should briefly explain the purpose of the test to users of a test suite.
+The name of a Tcl or C function being tested should be included in the
+description for regression tests. If the test case exists to reproduce
+a bug, include the bug ID in the description.
+.PP
+Valid attributes and associated values are:
+.TP
+\fB\-constraints \fIkeywordList\fR|\fIexpression\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
+constraints is false or does not exist, the test is skipped. If the
+\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.
+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
+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
+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
+test, which must return a result that can be checked for correctness.
+If evaluation of \fIscript\fR raises an error, the test will fail
+(unless the \fB\-returnCodes\fR option is used to state that an error
+is expected).
+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.
+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
+values for \fImode\fR are \fBregexp\fR, \fBglob\fR, \fBexact\fR, and
+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
+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
+of the script(s) will be compared. Note that only output printed using
+the global \fBputs\fR command 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
+evaluation of the script(s) will be compared. Note that only output
+printed using the global \fBputs\fR command is used for comparison. If
+\fB\-errorOutput\fR is not specified, output sent to \fBstderr\fR and
+\fBerrorChannel\fR is not processed for comparison.
+.TP
+\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
+a code not in the \fIexpectedCodeList\fR, the test fails. All
+return codes known to \fBreturn\fR, in both numeric and symbolic
+form, including extended return codes, are acceptable elements in
+the \fIexpectedCodeList\fR. Default value is
+.QW "\fBok return\fR" .
+.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
+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
+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.
+.PP
+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.
+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
+below. Any output produced by the test scripts themselves should be
+produced using \fBputs\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.
+.SS "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
+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
+only if all constraints in the list are true-valued. Thus,
+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
+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
+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
+may appear within a test file, or within the script specified
+by the \fBconfigure \-load\fR or \fBconfigure \-loadfile\fR
+options.
+.PP
+The following is a list of constraints pre-defined by the
+\fBtcltest\fR package itself:
+.TP
+\fIsingleTestInterp\fR
+.
+This test can only be run if all test files are sourced into a single
+interpreter.
+.TP
+\fIunix\fR
+.
+This test can only be run on any Unix platform.
+.TP
+\fIwin\fR
+.
+This test can only be run on any Windows platform.
+.TP
+\fInt\fR
+.
+This test can only be run on any Windows NT platform.
+.TP
+\fI95\fR
+.
+This test can only be run on any Windows 95 platform.
+.TP
+\fI98\fR
+.
+This test can only be run on any Windows 98 platform.
+.TP
+\fImac\fR
+.
+This test can only be run on any Mac platform.
+.TP
+\fIunixOrWin\fR
+.
+This test can only be run on a Unix or Windows platform.
+.TP
+\fImacOrWin\fR
+.
+This test can only be run on a Mac or Windows platform.
+.TP
+\fImacOrUnix\fR
+.
+This test can only be run on a Mac or Unix platform.
+.TP
+\fItempNotWin\fR
+.
+This test can not be run on Windows. This flag is used to temporarily
+disable a test.
+.TP
+\fItempNotMac\fR
+.
+This test can not be run on a Mac. This flag is used
+to temporarily disable a test.
+.TP
+\fIunixCrash\fR
+.
+This test crashes if it is run on Unix. This flag is used to temporarily
+disable a test.
+.TP
+\fIwinCrash\fR
+.
+This test crashes if it is run on Windows. This flag is used to temporarily
+disable a test.
+.TP
+\fImacCrash\fR
+.
+This test crashes if it is run on a Mac. This flag is used to temporarily
+disable a test.
+.TP
+\fIemptyTest\fR
+.
+This test is empty, and so not worth running, but it remains as a
+place-holder for a test to be written in the future. This constraint
+has value false to cause tests to be skipped unless the user specifies
+otherwise.
+.TP
+\fIknownBug\fR
+.
+This test is known to fail and the bug is not yet fixed. This constraint
+has value false to cause tests to be skipped unless the user specifies
+otherwise.
+.TP
+\fInonPortable\fR
+.
+This test can only be run in some known development environment.
+Some tests are inherently non-portable because they depend on things
+like word length, file system configuration, window manager, etc.
+This constraint has value false to cause tests to be skipped unless
+the user specifies otherwise.
+.TP
+\fIuserInteraction\fR
+.
+This test requires interaction from the user. This constraint has
+value false to causes tests to be skipped unless the user specifies
+otherwise.
+.TP
+\fIinteractive\fR
+.
+This test can only be run in if the interpreter is in interactive mode
+(when the global tcl_interactive variable is set to 1).
+.TP
+\fInonBlockFiles\fR
+.
+This test can only be run if platform supports setting files into
+nonblocking mode.
+.TP
+\fIasyncPipeClose\fR
+.
+This test can only be run if platform supports async flush and async close
+on a pipe.
+.TP
+\fIunixExecs\fR
+.
+This test can only be run if this machine has Unix-style commands
+\fBcat\fR, \fBecho\fR, \fBsh\fR, \fBwc\fR, \fBrm\fR, \fBsleep\fR,
+\fBfgrep\fR, \fBps\fR, \fBchmod\fR, and \fBmkdir\fR available.
+.TP
+\fIhasIsoLocale\fR
+.
+This test can only be run if can switch to an ISO locale.
+.TP
+\fIroot\fR
+.
+This test can only run if Unix user is root.
+.TP
+\fInotRoot\fR
+.
+This test can only run if Unix user is not root.
+.TP
+\fIeformat\fR
+.
+This test can only run if app has a working version of sprintf with respect
+to the
+.QW e
+format of floating-point numbers.
+.TP
+\fIstdio\fR
+.
+This 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
+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
+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
+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.
+.SS "RUNNING ALL TESTS"
+.PP
+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.
+.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
+and sorted. Then each file will be evaluated in turn. If
+\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
+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
+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.
+.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\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
+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.
+.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
+and do not match any of the patterns in
+\fBconfigure \-asidefromdir\fR are examined. If
+a file named \fBall.tcl\fR is found in such a directory,
+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,
+many directories in a directory tree can have all their
+test files evaluated by a single \fBrunAllTests\fR
+command.
+.SH "CONFIGURABLE OPTIONS"
+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
+each test file. No spawning when \fIboolean\fR is true. Default
+value is false.
+.TP
+\fB\-debug \fIlevel\fR
+.
+Sets the debug level to \fIlevel\fR, an integer value indicating how
+much debugging information should be printed to \fBstdout\fR. Note that
+debug messages always go to \fBstdout\fR, independent of the value of
+\fBconfigure \-outfile\fR. Default value is 0. Levels are defined as:
+.RS
+.IP 0 4
+Do not display any debug information.
+.IP 1
+Display information regarding whether a test is skipped because it
+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
+Display the flag array parsed by the command line processor, the
+contents of the global \fBenv\fR array, and all user-defined variables
+that exist in the current namespace as they are used.
+.IP 3
+Display information regarding what individual procs in the test
+harness are doing.
+.RE
+.TP
+\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, \fBerror\fR and \fBline\fR. Default value
+is
+.QW "\fBbody error\fR" .
+Levels are defined as:
+.RS
+.IP "body (\fBb\fR)"
+Display the body of failed tests
+.IP "pass (\fBp\fR)"
+Print output when a test passes
+.IP "skip (\fBs\fR)"
+Print output when a test is skipped
+.IP "start (\fBt\fR)"
+Print output whenever a test starts
+.IP "error (\fBe\fR)"
+Print errorInfo and errorCode, if they exist, when a test return code
+does not match its expected return code
+.IP "line (\fBl\fR)"
+Print source file line information of failed tests
+.PP
+The single letter abbreviations noted above are also recognized
+so that
+.QW "\fBconfigure \-verbose pt\fR"
+is the same as
+.QW "\fBconfigure \-verbose {pass start}\fR" .
+.RE
+.TP
+\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 \(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.
+.IP 2
+Check for core files at all times described above, and save a
+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
+in \fBTESTS\fR above. Default value is false.
+.TP
+\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
+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
+temporary files and directories created by test files should
+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.
+.TP
+\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
+.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
+what subdirectories to search for an \fBall.tcl\fR file. Default
+value is
+.QW \fB*\fR .
+.TP
+\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
+.QW \fB*\fR .
+.TP
+\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.
+Default value is an empty script.
+.TP
+\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.
+.TP
+\fB\-outfile \fIfilename\fR
+.
+Sets the file to which all output produced by tcltest should be
+written. A file named \fIfilename\fR will be \fBopen\fRed for writing,
+and the resulting channel will be set as the value of \fBoutputChannel\fR.
+.TP
+\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\fRed
+for writing, and the resulting channel will be set as the value
+of \fBerrorChannel\fR.
+.SH "CREATING TEST SUITES WITH TCLTEST"
+.PP
+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]
+} -body {
+ file exists $file
+} -cleanup {
+ 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
+} -setup {
+ set file [makeFile {} test]
+} -body {
+ file attributes $file -owner
+} -cleanup {
+ removeFile test
+} -result $::tcl_platform(user)
+.CE
+.RE
+.PP
+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
+.QW \fB.test\fR
+extension, because that is the default pattern
+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.
+Use constraints to skip tests, rather than conditional evaluation
+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
+.RE
+.IP [6]
+Discouraged system for writing conditional tests, using \fBif\fR to
+guard:
+.RS
+.PP
+.CS
+if $myRequirement {
+ \fBtest\fR badConditionalTest {} {
+ #body
+ } result
+}
+.CE
+.RE
+.PP
+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
+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
+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.
+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
+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\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
+package require example
+namespace eval ::example::test {
+ namespace import ::tcltest::*
+ \fBtestConstraint\fR X [expr {...}]
+ variable SETUP {#common setup code}
+ variable CLEANUP {#common cleanup code}
+ \fBtest\fR example-1 {} -setup $SETUP -body {
+ # First test
+ } -cleanup $CLEANUP -result {...}
+ \fBtest\fR example-2 {} -constraints X -setup $SETUP -body {
+ # Second test; constrained
+ } -cleanup $CLEANUP -result {...}
+ \fBtest\fR example-3 {} {
+ # 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
+doing any necessary setup. This script is usually named \fBall.tcl\fR
+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 \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
+provided by earlier releases of \fBtcltest\fR have not been documented
+here. They are no longer part of the supported public interface of
+\fBtcltest\fR and should not be used in new test suites. However,
+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\fR \fBtcltest 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
+or
+.PP
+.CS
+\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.
+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 {
+ \fBtest\fR level-2.1 {level 2} {
+ }
+ }
+}
+.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\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
+.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 \fBputs\fR in your application code. Output is
+intercepted by redefining the global \fBputs\fR 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 \fBtest\fR command.
+Therefore, usage of the \fB\-output\fR and \fB\-errorOutput\fR
+options to \fBtest\fR is useful only for pure Tcl applications
+that use \fBputs\fR to produce output.
+.SH KEYWORDS
+test, test harness, test suite
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/library/msgcat/doc/tclvars.n b/library/msgcat/doc/tclvars.n
new file mode 100644
index 0000000..44a8e11
--- /dev/null
+++ b/library/msgcat/doc/tclvars.n
@@ -0,0 +1,566 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH tclvars n 8.0 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+argc, argv, argv0, auto_path, env, errorCode, errorInfo, tcl_interactive, tcl_library, tcl_nonwordchars, tcl_patchLevel, tcl_pkgPath, tcl_platform, tcl_precision, tcl_rcFileName, tcl_traceCompile, tcl_traceEval, tcl_wordchars, tcl_version \- Variables used by Tcl
+.BE
+.SH DESCRIPTION
+.PP
+The following global variables are created and managed automatically
+by the Tcl library. Except where noted below, these variables should
+normally be treated as read-only by application-specific code and by users.
+.TP
+\fBauto_path\fR
+.
+If set, then it must contain a valid Tcl list giving directories to
+search during auto-load operations (including for package index
+files when using the default \fBpackage unknown\fR handler).
+This variable is initialized during startup to contain, in order:
+the directories listed in the \fBTCLLIBPATH\fR environment variable,
+the directory named by the \fBtcl_library\fR global variable,
+the parent directory of \fBtcl_library\fR,
+the directories listed in the \fBtcl_pkgPath\fR variable.
+Additional locations to look for files and package indices should
+normally be added to this variable using \fBlappend\fR.
+.RS
+.PP
+Additional variables relating to package management exist. More
+details are listed in the \fBVARIABLES\fR section of the \fBlibrary\fR
+manual page.
+.RE
+.TP
+\fBenv\fR
+.
+This variable is maintained by Tcl as an array
+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 does not already
+exist.
+Unsetting an element of \fBenv\fR will remove the corresponding
+environment variable.
+Changes to the \fBenv\fR array will affect the environment
+passed to children by commands like \fBexec\fR.
+If the entire \fBenv\fR array is unset then Tcl will stop
+monitoring \fBenv\fR accesses and will not update environment
+variables.
+.RS
+.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
+.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
+will not work on Windows and is discouraged for cross-platform usage.
+.PP
+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
+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_TZ)\fR, \fBenv(TZ)\fR
+.
+These specify the default timezone used for parsing and formatting times and
+dates in the \fBclock\fR command. On many platforms, the TZ environment
+variable is set up by the operating system.
+.TP
+\fBenv(LC_ALL)\fR, \fBenv(LC_MESSAGES)\fR, \fBenv(LANG)\fR
+.
+These environment variables are used by the \fBmsgcat\fR package to
+determine what locale to format messages using.
+.TP
+\fBenv(TCL_INTERP_DEBUG_FRAME)\fR
+.
+If existing, it has the same effect as running \fBinterp debug\fR
+\fB{} -frame 1\fR
+as the very first command of each new Tcl interpreter.
+.RE
+.TP
+\fBerrorCode\fR
+.
+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 \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 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),
+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 \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 \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 \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 \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 \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 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 is \fBPOSIX\fR, then
+the error occurred during a POSIX kernel call.
+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 \fImsg\fR element will be a human-readable
+message corresponding to \fIerrName\fR, such as
+.QW "no such file or directory"
+for the \fBENOENT\fR case.
+.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.
+.PP
+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
+\fBerrorInfo\fR
+.
+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
+nested Tcl commands that had been invoked at the time of the error.
+.TP
+\fBtcl_library\fR
+.
+This variable holds the name of a directory containing the
+system library of Tcl scripts, such as those used for auto-loading.
+The value of this variable is returned by the \fBinfo library\fR command.
+See the \fBlibrary\fR manual entry for details of the facilities
+provided by the Tcl script library.
+Normally each application or package will have its own application-specific
+script library in addition to the Tcl script library;
+each application should set a global variable with a name like
+\fB$\fIapp\fB_library\fR (where \fIapp\fR is the application's name)
+to hold the network file name for that application's library directory.
+The initial value of \fBtcl_library\fR is set when an interpreter
+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 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
+\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.
+.TP
+\fBtcl_pkgPath\fR
+.
+This variable holds a list of directories indicating where packages are
+normally installed. It is not used on Windows. It typically contains
+either one or two entries; if it contains two entries, the first is
+normally a directory for platform-dependent packages (e.g., shared library
+binaries) and the second is normally a directory for platform-independent
+packages (e.g., script files). Typically a package is installed as a
+subdirectory of one of the entries in the \fBtcl_pkgPath\fR
+variable. The directories in the \fBtcl_pkgPath\fR variable 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 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.
+.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 could not
+retrieve any relevant information. In addition, extensions
+and applications may add additional values to the array. The
+predefined elements are:
+.RS
+.TP
+\fBbyteOrder\fR
+.
+The native byte order of this machine: either \fBlittleEndian\fR or
+\fBbigEndian\fR.
+.TP
+\fBdebug\fR
+.
+If this variable exists, then the interpreter was compiled with and linked
+to a debug-enabled C run-time. This variable will only exist on Windows,
+so extension writers can specify which package to load depending on the
+C run-time library that is in use. This is not an indication that this core
+contains symbols.
+.TP
+\fBmachine\fR
+.
+The instruction set executed by this machine, such as
+\fBintel\fR, \fBPPC\fR, \fB68k\fR, or \fBsun4m\fR. On UNIX machines, this
+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, 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
+distinguish between the two, check the \fBosVersion\fR.
+.TP
+\fBosVersion\fR
+.
+The version number for the operating system running on this machine.
+On UNIX machines, this is the value returned by \fBuname -r\fR. On
+Windows 95, the version will be 4.0; on Windows 98, the version will
+be 4.10.
+.TP
+\fBpathSeparator\fR
+.VS 8.6
+'\" Defined by TIP #315
+The character that should be used to \fBsplit\fR PATH-like environment
+variables into their corresponding list of directory names.
+.VE 8.6
+.TP
+\fBplatform\fR
+.
+Either \fBwindows\fR, or \fBunix\fR. This identifies the
+general operating environment of the machine.
+.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.)
+.TP
+\fBthreaded\fR
+.
+If this variable exists, then the interpreter
+was compiled with threads enabled.
+.TP
+\fBuser\fR
+.
+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.
+.TP
+\fBwordSize\fR
+.
+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.)
+.RE
+.TP
+\fBtcl_precision\fR
+.
+This variable controls the number of digits to generate
+when converting floating-point values to strings. It defaults
+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. 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 thread share a single \fBtcl_precision\fR value:
+changing it in one interpreter will affect all other interpreters as
+well. Safe interpreters are not allowed to modify the
+variable.
+.RE
+.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
+user-specific startup file. If it is set by application-specific
+initialization, then the Tcl startup code will check for the existence
+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_traceCompile\fR
+.
+The value of this variable can be set to control
+how much tracing information
+is displayed during bytecode compilation.
+By default, \fBtcl_traceCompile\fR is zero and no information is displayed.
+Setting \fBtcl_traceCompile\fR to 1 generates a one-line summary in \fBstdout\fR
+whenever a procedure or top-level command is compiled.
+Setting it to 2 generates a detailed listing in \fBstdout\fR of the
+bytecode instructions emitted during every compilation.
+This variable is useful in
+tracking down suspected problems with the Tcl compiler.
+.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
+how much tracing information
+is displayed during bytecode execution.
+By default, \fBtcl_traceExec\fR is zero and no information is displayed.
+Setting \fBtcl_traceExec\fR to 1 generates a one-line trace in \fBstdout\fR
+on each call to a Tcl procedure.
+Setting it to 2 generates a line of output
+whenever any Tcl command is invoked
+that contains the name of the command and its arguments.
+Setting it to 3 produces a detailed trace showing the result of
+executing each bytecode instruction.
+Note that when \fBtcl_traceExec\fR is 2 or 3,
+commands such as \fBset\fR and \fBincr\fR
+that have been entirely replaced by a sequence
+of bytecode instructions are not shown.
+Setting this variable is useful in
+tracking down suspected problems with the bytecode compiler
+and interpreter.
+.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
+.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\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
+.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\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
+.
+When an interpreter is created Tcl initializes this variable to
+hold the version number for this version of Tcl in the form \fIx.y\fR.
+Changes to \fIx\fR represent major changes with probable
+incompatibilities and changes to \fIy\fR represent small enhancements and
+bug fixes that retain backward compatibility.
+The value of this variable is returned by the \fBinfo tclversion\fR
+command.
+.SH "OTHER GLOBAL VARIABLES"
+.PP
+The following variables are only guaranteed to exist in \fBtclsh\fR
+and \fBwish\fR executables; the Tcl library does not define them
+itself but many Tcl environments do.
+.TP 6
+\fBargc\fR
+.
+The number of arguments to \fBtclsh\fR or \fBwish\fR.
+.TP 6
+\fBargv\fR
+.
+Tcl list of arguments to \fBtclsh\fR or \fBwish\fR.
+.TP 6
+\fBargv0\fR
+.
+The script that \fBtclsh\fR or \fBwish\fR started executing (if it was
+specified) or otherwise the name by which \fBtclsh\fR or \fBwish\fR
+was invoked.
+.TP 6
+\fBtcl_interactive\fR
+.
+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.
+.SH EXAMPLES
+.PP
+To add a directory to the collection of locations searched by
+\fBpackage require\fR, e.g., because of some application-specific
+packages that are used, the \fBauto_path\fR variable needs to be
+updated:
+.PP
+.CS
+lappend ::\fBauto_path\fR [file join [pwd] "theLibDir"]
+.CE
+.PP
+A simple though not very robust way to handle command line arguments
+of the form
+.QW "\-foo 1 \-bar 2"
+is to load them into an array having first loaded in the default settings:
+.CS
+array set arguments {-foo 0 -bar 0 -grill 0}
+array set arguments $::\fBargv\fR
+puts "foo is $arguments(-foo)"
+puts "bar is $arguments(-bar)"
+puts "grill is $arguments(-grill)"
+.CE
+.PP
+The \fBargv0\fR global variable can be used (in conjunction with the
+\fBinfo script\fR command) to determine whether the current script is
+being executed as the main script or loaded as a library. This is
+useful because it allows a single script to be used as both a library
+and a demonstration of that library:
+.PP
+.CS
+if {$::\fBargv0\fR eq [info script]} {
+ # running as: tclsh example.tcl
+} else {
+ package provide Example 1.0
+}
+.CE
+.SH "SEE ALSO"
+eval(n), library(n), tclsh(1), tkvars(n), wish(1)
+.SH KEYWORDS
+arithmetic, bytecode, compiler, error, environment, POSIX, precision,
+subprocess, user, variables
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/tell.n b/library/msgcat/doc/tell.n
new file mode 100644
index 0000000..87e63b0
--- /dev/null
+++ b/library/msgcat/doc/tell.n
@@ -0,0 +1,48 @@
+'\"
+'\" 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 tell n 8.1 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+tell \- Return current access position for an open channel
+.SH SYNOPSIS
+\fBtell \fIchannelId\fR
+.BE
+.SH DESCRIPTION
+.PP
+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.
+The value returned is -1 for channels that do not support
+seeking.
+.PP
+\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.
+.SH EXAMPLE
+.PP
+Read a line from a file channel only if it starts with \fBfoobar\fR:
+.PP
+.CS
+# Save the offset in case we need to undo the read...
+set offset [\fBtell\fR $chan]
+if {[read $chan 6] eq "foobar"} {
+ gets $chan line
+} else {
+ set line {}
+ # Undo the read...
+ seek $chan $offset
+}
+.CE
+.SH "SEE ALSO"
+file(n), open(n), close(n), gets(n), seek(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+access position, channel, seeking
diff --git a/library/msgcat/doc/throw.n b/library/msgcat/doc/throw.n
new file mode 100644
index 0000000..d49fb24
--- /dev/null
+++ b/library/msgcat/doc/throw.n
@@ -0,0 +1,48 @@
+'\"
+'\" Copyright (c) 2008 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 throw n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+throw \- Generate a machine-readable error
+.SH SYNOPSIS
+\fBthrow\fI type message\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command causes the current evaluation to be unwound with an error. The
+error created is described by the \fItype\fR and \fImessage\fR arguments:
+\fItype\fR must contain a list of words describing the error in a form that is
+machine-readable (and which will form the error-code part of the result
+dictionary), and \fImessage\fR should contain text that is intended for
+display to a human being.
+.PP
+The stack will be unwound until the error is trapped by a suitable \fBcatch\fR
+or \fBtry\fR command. If it reaches the event loop without being trapped, it
+will be reported through the \fBbgerror\fR mechanism. If it reaches the top
+level of script evaluation in \fBtclsh\fR, it will be printed on the console
+before, in the non-interactive case, causing an exit (the behavior in other
+programs will depend on the details of how Tcl is embedded and used).
+.PP
+By convention, the words in the \fItype\fR argument should go from most
+general to most specific.
+.SH EXAMPLES
+.PP
+The following produces an error that is identical to that produced by
+\fBexpr\fR when trying to divide a value by zero.
+.PP
+.CS
+\fBthrow\fR {ARITH DIVZERO {divide by zero}} {divide by zero}
+.CE
+.SH "SEE ALSO"
+catch(n), error(n), return(n), tclvars(n), try(n)
+.SH "KEYWORDS"
+error, exception
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/time.n b/library/msgcat/doc/time.n
new file mode 100644
index 0000000..52730a1
--- /dev/null
+++ b/library/msgcat/doc/time.n
@@ -0,0 +1,47 @@
+'\"
+'\" 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 time n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+time \- Time the execution of a script
+.SH SYNOPSIS
+\fBtime \fIscript\fR ?\fIcount\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command will call the Tcl interpreter \fIcount\fR
+times to evaluate \fIscript\fR (or once if \fIcount\fR is not
+specified). It will then return a string of the form
+.PP
+.CS
+\fB503.2 microseconds per iteration\fR
+.CE
+.PP
+which indicates the average amount of time required per iteration,
+in microseconds.
+Time is measured in elapsed time, not CPU time.
+.SH EXAMPLE
+Estimate how long it takes for a simple Tcl \fBfor\fR loop to count to
+a thousand:
+.PP
+.CS
+time {
+ for {set i 0} {$i<1000} {incr i} {
+ # empty body
+ }
+}
+.CE
+.SH "SEE ALSO"
+clock(n)
+.SH KEYWORDS
+script, time
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/library/msgcat/doc/tm.n b/library/msgcat/doc/tm.n
new file mode 100644
index 0000000..ddfbac2
--- /dev/null
+++ b/library/msgcat/doc/tm.n
@@ -0,0 +1,308 @@
+'\"
+'\" 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
+.PP
+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"
+.PP
+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:
+.PP
+.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:
+.PP
+.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:
+.PP
+.CS
+package vcompare $version 0
+.CE
+.SH "FINDING MODULES"
+.PP
+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:
+.PP
+.CS
+package ifneeded \fBPNAME PVERSION\fR [list source \fBMF\fR]
+.CE
+.PP
+and the \fIprovide script\fR embedded in the above is:
+.PP
+.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:
+.PP
+.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"
+.PP
+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:
+.PP
+.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 10
+environment variables:
+.PP
+.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
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/library/msgcat/doc/trace.n b/library/msgcat/doc/trace.n
new file mode 100644
index 0000000..940a1e9
--- /dev/null
+++ b/library/msgcat/doc/trace.n
@@ -0,0 +1,426 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Ajuba Solutions.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH trace n "8.4" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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\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 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 \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 \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 \fIcommandPrefix\fR so that the actual command is as
+follows:
+.PP
+.CS
+\fIcommandPrefix oldName newName op\fR
+.CE
+.PP
+\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
+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.
+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 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 \fIcommandPrefix\fR whenever the command \fIname\fR is executed,
+just before the actual execution takes place.
+.TP
+\fBleave\fR
+Invoke \fIcommandPrefix\fR whenever the command \fIname\fR is executed,
+just after the actual execution takes place.
+.TP
+\fBenterstep\fR
+.
+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 \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 \fIcommandPrefix\fR so that the actual
+command is as follows:
+.PP
+For \fBenter\fR and \fBenterstep\fR operations:
+.PP
+.CS
+\fIcommandPrefix command-string op\fR
+.CE
+.PP
+\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
+.QW "invalid command"
+error will occur.
+.PP
+For \fBleave\fR and \fBleavestep\fR operations:
+.PP
+.CS
+\fIcommand command-string code result op\fR
+.CE
+.PP
+\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.
+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
+\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 \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 \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
+and \fIenterstep\fR operations, the traced commands are invoked
+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
+\fIname\fR imported into another namespace.
+.RE
+.TP
+\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
+\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.
+.RS
+.PP
+\fIOps\fR indicates which operations are of interest, and is a list of
+one or more of the following items:
+.TP
+\fBarray\fR
+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 \fIcommandPrefix\fR whenever the variable is read.
+.TP
+\fBwrite\fR
+Invoke \fIcommandPrefix\fR whenever the variable is written.
+.TP
+\fBunset\fR
+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
+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
+\fIcommandPrefix\fR so that the actual command is as follows:
+.PP
+.CS
+\fIcommandPrefix name1 name2 op\fR
+.CE
+.PP
+\fIName1\fR and \fIname2\fR give the name(s) for the variable
+being accessed: if the variable is a scalar then \fIname1\fR
+gives the variable's name and \fIname2\fR is an empty string;
+if the variable is an array element then \fIname1\fR gives the
+name of the array and name2 gives the index into the array;
+if an entire array is being deleted and the trace was registered
+on the overall array, rather than a single element, then \fIname1\fR
+gives the array name and \fIname2\fR is an empty string.
+\fIName1\fR and \fIname2\fR are not necessarily the same as the
+name used in the \fBtrace variable\fR command: the \fBupvar\fR
+command allows a procedure to reference a variable under a
+different name.
+\fIOp\fR indicates what operation is being performed on the
+variable, and is one of \fBread\fR, \fBwrite\fR, or \fBunset\fR as
+defined above.
+.PP
+\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 \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 \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
+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, \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 \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, \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, \fIcommandPrefix\fR will have to restore the
+old value of the variable.
+.PP
+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 \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
+because of a procedure return, then the trace will be invoked in the
+variable context of the procedure being returned to: the stack frame
+of the returning procedure will no longer exist. Traces are not
+disabled during unset traces, so if an unset trace command creates a
+new trace and accesses the variable, the trace will be invoked. Any
+errors in unset traces are ignored.
+.PP
+If there are multiple traces on a variable they are invoked in order
+of creation, most-recent first. If one trace returns an error, then
+no further traces are invoked for the variable. If an array element
+has a trace set, and there is also a trace set on the array as a
+whole, the trace on the overall array is invoked before the one on the
+element.
+.PP
+Once created, the trace remains in effect either until the trace is
+removed with the \fBtrace remove variable\fR command described below,
+until the variable is unset, or until the interpreter is deleted.
+Unsetting an element of array will remove any traces on that element,
+but will not remove traces on the overall array.
+.PP
+This command returns an empty string.
+.RE
+.RE
+.TP
+\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 commandPrefix\fR
+If there is a trace set on command \fIname\fR with the operations and
+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 commandPrefix\fR
+If there is a trace set on command \fIname\fR with the operations and
+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 commandPrefix\fR
+If there is a trace set on variable \fIname\fR with the operations and
+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
+\fBtrace info \fItype name\fR
+Where \fItype\fR is either \fBcommand\fR, \fBexecution\fR or \fBvariable\fR.
+.RS
+.TP
+\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 \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
+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 \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
+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 \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
+.PP
+For backwards compatibility, three other subcommands are available:
+.RS
+.TP
+\fBtrace variable \fIname ops command\fR
+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
+This is equivalent to \fBtrace info variable \fIname\fR
+.RE
+.PP
+These subcommands are deprecated and will likely be removed in a
+future version of Tcl. They use an older syntax in which \fBarray\fR,
+\fBread\fR, \fBwrite\fR, \fBunset\fR are replaced by \fBa\fR, \fBr\fR,
+\fBw\fR and \fBu\fR respectively, and the \fIops\fR argument is not a
+list, but simply a string concatenation of the operations, such as
+\fBrwua\fR.
+.SH EXAMPLES
+.PP
+Print a message whenever either of the global variables \fBfoo\fR and
+\fBbar\fR are updated, even if they have a different local name at the
+time (which can be done with the \fBupvar\fR command):
+.PP
+.CS
+proc tracer {varname args} {
+ upvar #0 $varname var
+ puts "$varname was updated to be \e"$var\e""
+}
+\fBtrace add\fR variable foo write "tracer foo"
+\fBtrace add\fR variable bar write "tracer bar"
+.CE
+.PP
+Ensure that the global variable \fBfoobar\fR always contains the
+product of the global variables \fBfoo\fR and \fBbar\fR:
+.PP
+.CS
+proc doMult args {
+ global foo bar foobar
+ set foobar [expr {$foo * $bar}]
+}
+\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:
+.PP
+.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
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/library/msgcat/doc/transchan.n b/library/msgcat/doc/transchan.n
new file mode 100644
index 0000000..e308e13
--- /dev/null
+++ b/library/msgcat/doc/transchan.n
@@ -0,0 +1,160 @@
+'\"
+'\" Copyright (c) 2008 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 transchan n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+transchan \- command handler API of channel transforms
+.SH SYNOPSIS
+\fBcmdPrefix \fIoption\fR ?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The Tcl-level handler for a channel transformation has to be a command with
+subcommands (termed an \fIensemble\fR despite not implying that it must be
+created with \fBnamespace ensemble create\fR; this mechanism is not tied to
+\fBnamespace ensemble\fR in any way). Note that \fIcmdPrefix\fR is whatever
+was specified in the call to \fBchan push\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 and \fBfinalize\fR. Transformations for writable channels
+must also support \fBwrite\fR, and transformations for readable channels must
+also support \fBread\fR.
+.PP
+Note that in the descriptions below \fIcmdPrefix\fR may be more than one word,
+and \fIhandle\fR is the value returned by the \fBchan push\fR call used to
+create the transformation.
+.SS "GENERIC SUBCOMMANDS"
+.PP
+The following subcommands are relevant to all types of channel.
+.TP
+\fIcmdPrefix \fBclear \fIhandle\fR
+.
+This optional subcommand is called to signify to the transformation that any
+data stored in internal buffers (either incoming or outgoing) must be
+cleared. It is called when a \fBchan seek\fR is performed on the channel being
+transformed.
+.TP
+\fIcmdPrefix \fBfinalize \fIhandle\fR
+.
+This mandatory subcommand is called last for the given \fIhandle\fR, and then
+never again, and it exists to allow for cleaning up any Tcl-level data
+structures associated with the transformation. \fIWarning!\fR Any errors
+thrown by this subcommand will be ignored. It is not guaranteed to be called
+if the interpreter is deleted.
+.TP
+\fIcmdPrefix \fBinitialize \fIhandle mode\fR
+.
+This mandatory subcommand is called first, and then never again (for the given
+\fIhandle\fR). Its responsibility is to initialize all parts of the
+transformation at the Tcl level. The \fImode\fR is a list containing any of
+\fBread \fRand \fBwrite\fR.
+.RS
+.TP
+\fBwrite\fR
+.
+implies that the channel is writable.
+.TP
+\fBread\fR
+.
+implies that the channel is readable.
+.PP
+The return value of the subcommand should be a list containing the names of
+all subcommands supported by this handler. Any error thrown by the subcommand
+will prevent the creation of the transformation. The thrown error will appear
+as error thrown by \fBchan push\fR.
+.RE
+.SS "READ-RELATED SUBCOMMANDS"
+.PP
+These subcommands are used for handling transformations applied to readable
+channels; though strictly \fBread \fRis optional, it must be supported if any
+of the others is or the channel will be made non-readable.
+.TP
+\fIcmdPrefix \fBdrain \fIhandle\fR
+.
+This optional subcommand is called whenever data in the transformation input
+(i.e. read) buffer has to be forced upward, i.e. towards the user or script.
+The result returned by the method is taken as the \fIbinary\fR data to push
+upward to the level above this transformation (the reader or a higher-level
+transformation).
+.RS
+.PP
+In other words, when this method is called the transformation cannot defer the
+actual transformation operation anymore and has to transform all data waiting
+in its internal read buffers and return the result of that action.
+.RE
+.TP
+\fIcmdPrefix \fBlimit? \fIhandle\fR
+.
+This optional subcommand is called to allow the Tcl I/O engine to determine
+how far ahead it should read. If present, it should return an integer number
+greater than zero which indicates how many bytes ahead should be read, or an
+integer less than zero to indicate that the I/O engine may read as far ahead
+as it likes.
+.TP
+\fIcmdPrefix \fBread \fIhandle buffer\fR
+.
+This subcommand, which must be present if the transformation is to work with
+readable channels, is called whenever the base channel, or a transformation
+below this transformation, pushes data upward. The \fIbuffer\fR contains the
+binary data which has been given to us from below. It is the responsibility of
+this subcommand to actually transform the data. The result returned by the
+subcommand is taken as the binary data to push further upward to the
+transformation above this transformation. This can also be the user or script
+that originally read from the channel.
+.RS
+.PP
+Note that the result is allowed to be empty, or even less than the data we
+received; the transformation is not required to transform everything given to
+it right now. It is allowed to store incoming data in internal buffers and to
+defer the actual transformation until it has more data.
+.RE
+.SS "WRITE-RELATED SUBCOMMANDS"
+.PP
+These subcommands are used for handling transformations applied to writable
+channels; though strictly \fBwrite\fR is optional, it must be supported if any
+of the others is or the channel will be made non-writable.
+.TP
+\fIcmdPrefix \fBflush \fIhandle\fR
+.
+This optional subcommand is called whenever data in the transformation 'write'
+buffer has to be forced downward, i.e. towards the base channel. The result
+returned by the subcommand is taken as the binary data to write to the
+transformation below the current transformation. This can be the base channel
+as well.
+.RS
+.PP
+In other words, when this subcommand is called the transformation cannot defer
+the actual transformation operation anymore and has to transform all data
+waiting in its internal write buffers and return the result of that action.
+.RE
+.TP
+\fIcmdPrefix \fBwrite \fIhandle buffer\fR
+.
+This subcommand, which must be present if the transformation is to work with
+writable channels, is called whenever the user, or a transformation above this
+transformation, writes data downward. The \fIbuffer\fR contains the binary
+data which has been written to us. It is the responsibility of this subcommand
+to actually transform the data.
+.RS
+.PP
+The result returned by the subcommand is taken as the binary data to write to
+the transformation below this transformation. This can be the base channel as
+well. Note that the result is allowed to be empty, or less than the data we
+got; the transformation is not required to transform everything which was
+written to it right now. It is allowed to store this data in internal buffers
+and to defer the actual transformation until it has more data.
+.RE
+.SH "SEE ALSO"
+chan(n), refchan(n)
+.SH KEYWORDS
+API, channel, ensemble, prefix, transformation
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/try.n b/library/msgcat/doc/try.n
new file mode 100644
index 0000000..393fe5b
--- /dev/null
+++ b/library/msgcat/doc/try.n
@@ -0,0 +1,103 @@
+'\"
+'\" Copyright (c) 2008 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 try n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+try \- Trap and process errors and exceptions
+.SH SYNOPSIS
+\fBtry\fI body\fR ?\fIhandler...\fR? ?\fBfinally\fI script\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command executes the script \fIbody\fR and, depending on what the outcome
+of that script is (normal exit, error, or some other exceptional result), runs
+a handler script to deal with the case. Once that has all happened, if the
+\fBfinally\fR clause is present, the \fIscript\fR it includes will be run and
+the result of the handler (or the \fIbody\fR if no handler matched) is allowed
+to continue to propagate. Note that the \fBfinally\fR clause is processed even
+if an error occurs and irrespective of which, if any, \fIhandler\fR is used.
+.PP
+The \fIhandler\fR clauses are each expressed as several words, and must have
+one of the following forms:
+.TP
+\fBon \fIcode variableList script\fR
+.
+This clause matches if the evaluation of \fIbody\fR completed with the
+exception code \fIcode\fR. The \fIcode\fR may be expressed as an integer or
+one of the following literal words: \fBok\fR, \fBerror\fR, \fBreturn\fR,
+\fBbreak\fR, or \fBcontinue\fR. Those literals correspond to the integers 0
+through 4 respectively.
+.TP
+\fBtrap \fIpattern variableList script\fR
+.
+This clause matches if the evaluation of \fIbody\fR resulted in an error and
+the prefix of the \fB\-errorcode\fR from the interpreter's status dictionary
+is equal to the \fIpattern\fR. The number of prefix words taken from the
+\fB\-errorcode\fR is equal to the list-length of \fIpattern\fR, and inter-word
+spaces are normalized in both the \fB\-errorcode\fR and \fIpattern\fR before
+comparison.
+.PP
+The \fIvariableList\fR word in each \fIhandler\fR is always interpreted as a
+list of variable names. If the first word of the list is present and
+non-empty, it names a variable into which the result of the evaluation of
+\fIbody\fR (from the main \fBtry\fR) will be placed; this will contain the
+human-readable form of any errors. If the second word of the list is present
+and non-empty, it names a variable into which the options dictionary of the
+interpreter at the moment of completion of execution of \fIbody\fR
+will be placed.
+.PP
+The \fIscript\fR word of each \fIhandler\fR is also always interpreted the
+same: as a Tcl script to evaluate if the clause is matched. If \fIscript\fR is
+a literal
+.QW \-
+and the \fIhandler\fR is not the last one, the \fIscript\fR of the following
+\fIhandler\fR is invoked instead (just like with the \fBswitch\fR command).
+.PP
+Note that \fIhandler\fR clauses are matched against in order, and that the
+first matching one is always selected. At most one \fIhandler\fR clause will
+selected. As a consequence, an \fBon error\fR will mask any subsequent
+\fBtrap\fR in the \fBtry\fR. Also note that \fBon error\fR is equivalent to
+\fBtrap {}\fR.
+.PP
+If an exception (i.e. any non-\fBok\fR result) occurs during the evaluation of
+either the \fIhandler\fR or the \fBfinally\fR clause, the original exception's
+status dictionary will be added to the new exception's status dictionary under
+the \fB\-during\fR key.
+.SH EXAMPLES
+.PP
+Ensure that a file is closed no matter what:
+.PP
+.CS
+set f [open /some/file/name a]
+\fBtry\fR {
+ puts $f "some message"
+ # ...
+} \fBfinally\fR {
+ close $f
+}
+.CE
+.PP
+Handle different reasons for a file to not be openable for reading:
+.PP
+.CS
+\fBtry\fR {
+ set f [open /some/file/name]
+} \fBtrap\fR {POSIX EISDIR} {} {
+ puts "failed to open /some/file/name: it's a directory"
+} \fBtrap\fR {POSIX ENOENT} {} {
+ puts "failed to open /some/file/name: it doesn't exist"
+}
+.CE
+.SH "SEE ALSO"
+catch(n), error(n), return(n), throw(n)
+.SH "KEYWORDS"
+cleanup, error, exception, final, resource management
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/doc/unknown.n b/library/msgcat/doc/unknown.n
new file mode 100644
index 0000000..fc2a5a1
--- /dev/null
+++ b/library/msgcat/doc/unknown.n
@@ -0,0 +1,91 @@
+'\"
+'\" 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 unknown n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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 does not exist. The default implementation
+of \fBunknown\fR is a library procedure defined when Tcl initializes an
+interpreter. You can override the default \fBunknown\fR to change its
+functionality, or you can register a new handler for individual namespaces
+using the \fBnamespace unknown\fR command. Note that there is no default
+implementation of \fBunknown\fR in a safe interpreter.
+.PP
+If the Tcl interpreter encounters a command name for which there
+is not a defined command (in either the current namespace, or the
+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
+through library directories for a command procedure with the name
+\fIcmdName\fR, or expanding abbreviated command names to full-length,
+or automatically executing unknown commands as sub-processes.
+In some cases (such as expanding abbreviations) \fBunknown\fR will
+change the original command slightly and then (re-)execute it.
+The result of the \fBunknown\fR command is used as the result for
+the original non-existent command.
+.PP
+The default implementation of \fBunknown\fR behaves as follows.
+It first calls the \fBauto_load\fR library procedure to load the command.
+If this succeeds, then it executes the original command with its
+original arguments.
+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 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:
+\fB!!\fR, \fB!\fIevent\fR, or \fB^\fIold\fB^\fInew\fR?\fB^\fR?.
+If so, then \fBunknown\fR carries out history substitution
+in the same way that \fBcsh\fR would for these constructs.
+Finally, \fBunknown\fR checks to see if \fIcmd\fR is
+a unique abbreviation for an existing Tcl command.
+If so, it expands the command name and executes the command with
+the original arguments.
+If none of the above efforts has been able to execute
+the command, \fBunknown\fR generates an error return.
+If the global variable \fBauto_noload\fR is defined, then the auto-load
+step is skipped.
+If the global variable \fBauto_noexec\fR is defined then the
+auto-exec step is skipped.
+Under normal circumstances the return value from \fBunknown\fR
+is the return value from the command that was eventually
+executed.
+.SH EXAMPLE
+Arrange for the \fBunknown\fR command to have its standard behavior
+except for first logging the fact that a command was not found:
+.PP
+.CS
+# Save the original one so we can chain to it
+rename \fBunknown\fR _original_unknown
+
+# Provide our own implementation
+proc \fBunknown\fR args {
+ puts stderr "WARNING: unknown command: $args"
+ uplevel 1 [list _original_unknown {*}$args]
+}
+.CE
+.SH "SEE ALSO"
+info(n), proc(n), interp(n), library(n), namespace(n)
+.SH KEYWORDS
+error, non-existent command, unknown
diff --git a/library/msgcat/doc/unload.n b/library/msgcat/doc/unload.n
new file mode 100644
index 0000000..4c0b292
--- /dev/null
+++ b/library/msgcat/doc/unload.n
@@ -0,0 +1,172 @@
+'\"
+'\" 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:
+.PP
+.CS
+typedef int \fBTcl_PackageUnloadProc\fR(
+ 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
+.PP
+If an unloadable module in the file \fBfoobar.dll\fR had been loaded
+using the \fBload\fR command like this (on Windows):
+.PP
+.CS
+load c:/some/dir/foobar.dll
+.CE
+.PP
+then it would be unloaded like this:
+.PP
+.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
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/library/msgcat/doc/unset.n b/library/msgcat/doc/unset.n
new file mode 100644
index 0000000..64b334d
--- /dev/null
+++ b/library/msgcat/doc/unset.n
@@ -0,0 +1,68 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Ajuba Solutions.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH unset n 8.4 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+unset \- Delete variables
+.SH SYNOPSIS
+\fBunset \fR?\fB\-nocomplain\fR? ?\fB\-\-\fR? ?\fIname name name ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command removes one or more variables.
+Each \fIname\fR is a variable name, specified in any of the
+ways acceptable to the \fBset\fR command.
+If a \fIname\fR refers to an element of an array then that
+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.
+If \fB\-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 \fB\-\-\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.
+If an error occurs during variable deletion, any variables after the named one
+causing the error are not
+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
+.PP
+Create an array containing a mapping from some numbers to their
+squares and remove the array elements for non-prime numbers:
+.PP
+.CS
+array set squares {
+ 1 1 6 36
+ 2 4 7 49
+ 3 9 8 64
+ 4 16 9 81
+ 5 25 10 100
+}
+
+puts "The squares are:"
+parray squares
+
+\fBunset\fR squares(1) squares(4) squares(6)
+\fBunset\fR squares(8) squares(9) squares(10)
+
+puts "The prime squares are:"
+parray squares
+.CE
+.SH "SEE ALSO"
+set(n), trace(n), upvar(n)
+.SH KEYWORDS
+remove, variable
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/library/msgcat/doc/update.n b/library/msgcat/doc/update.n
new file mode 100644
index 0000000..0c77c5f
--- /dev/null
+++ b/library/msgcat/doc/update.n
@@ -0,0 +1,65 @@
+'\"
+'\" Copyright (c) 1990-1992 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 update n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+update \- Process pending events and idle callbacks
+.SH SYNOPSIS
+\fBupdate\fR ?\fBidletasks\fR?
+.BE
+.SH DESCRIPTION
+.PP
+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
+If the \fBidletasks\fR keyword is specified as an argument to the
+command, then no new events or errors are processed; only idle
+callbacks are invoked.
+This causes operations that are normally deferred, such as display
+updates and window layout calculations, to be performed immediately.
+.PP
+The \fBupdate idletasks\fR command is useful in scripts where
+changes have been made to the application's state and you want those
+changes to appear on the display immediately, rather than waiting
+for the script to complete. Most display updates are performed as
+idle callbacks, so \fBupdate idletasks\fR will cause them to run.
+However, there are some kinds of updates that only happen in
+response to events, such as those triggered by window size changes;
+these updates will not occur in \fBupdate idletasks\fR.
+.PP
+The \fBupdate\fR command with no options is useful in scripts where
+you are performing a long-running computation but you still want
+the application to respond to events such as user interactions; if
+you occasionally call \fBupdate\fR then user input will be processed
+during the next call to \fBupdate\fR.
+.SH EXAMPLE
+.PP
+Run computations for about a second and then finish:
+.PP
+.CS
+set x 1000
+set done 0
+after 1000 set done 1
+while {!$done} {
+ # A very silly example!
+ set x [expr {log($x) ** 2.8}]
+
+ # Test to see if our time-limit has been hit. This would
+ # also give a chance for serving network sockets and, if
+ # the Tk package is loaded, updating a user interface.
+ \fBupdate\fR
+}
+.CE
+.SH "SEE ALSO"
+after(n), interp(n)
+.SH KEYWORDS
+asynchronous I/O, event, flush, handler, idle, update
diff --git a/library/msgcat/doc/uplevel.n b/library/msgcat/doc/uplevel.n
new file mode 100644
index 0000000..6c8a957
--- /dev/null
+++ b/library/msgcat/doc/uplevel.n
@@ -0,0 +1,103 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH uplevel n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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
+been passed to \fBconcat\fR; the result is then evaluated in the
+variable context indicated by \fIlevel\fR. \fBUplevel\fR returns
+the result of that evaluation.
+.PP
+If \fIlevel\fR is an integer then
+it gives a distance (up the procedure calling stack) to move before
+executing the command. If \fIlevel\fR consists of \fB#\fR followed by
+a number then the number gives an absolute level number. If \fIlevel\fR
+is omitted then it defaults to \fB1\fR. \fILevel\fR cannot be
+defaulted if the first \fIcommand\fR argument starts with a digit or \fB#\fR.
+.PP
+For example, suppose that procedure \fBa\fR was invoked
+from top-level, and that it called \fBb\fR, and that \fBb\fR called \fBc\fR.
+Suppose that \fBc\fR invokes the \fBuplevel\fR command. If \fIlevel\fR
+is \fB1\fR or \fB#2\fR or omitted, then the command will be executed
+in the variable context of \fBb\fR. If \fIlevel\fR is \fB2\fR or \fB#1\fR
+then the command will be executed in the variable context of \fBa\fR.
+If \fIlevel\fR is \fB3\fR or \fB#0\fR then the command will be executed
+at top-level (only global variables will be visible).
+.PP
+The \fBuplevel\fR command causes the invoking procedure to disappear
+from the procedure calling stack while the command is being executed.
+In the above example, suppose \fBc\fR invokes the command
+.PP
+.CS
+\fBuplevel\fR 1 {set x 43; d}
+.CE
+.PP
+where \fBd\fR is another Tcl procedure. The \fBset\fR command will
+modify the variable \fBx\fR in \fBb\fR's context, and \fBd\fR will execute
+at level 3, as if called from \fBb\fR. If it in turn executes
+the command
+.PP
+.CS
+\fBuplevel\fR {set x 42}
+.CE
+.PP
+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 \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
+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
+describing a command that is either
+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).
+.SH EXAMPLE
+As stated above, the \fBuplevel\fR command is useful for creating new
+control constructs. This example shows how (without error handling)
+it can be used to create a \fBdo\fR command that is the counterpart of
+\fBwhile\fR except for always performing the test after running the
+loop body:
+.PP
+.CS
+proc do {body while condition} {
+ if {$while ne "while"} {
+ error "required word missing"
+ }
+ set conditionCmd [list expr $condition]
+ while {1} {
+ \fBuplevel\fR 1 $body
+ if {![\fBuplevel\fR 1 $conditionCmd]} {
+ break
+ }
+ }
+}
+.CE
+.SH "SEE ALSO"
+apply(n), namespace(n), upvar(n)
+.SH KEYWORDS
+context, level, namespace, stack frame, variable
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/library/msgcat/doc/upvar.n b/library/msgcat/doc/upvar.n
new file mode 100644
index 0000000..60e5324
--- /dev/null
+++ b/library/msgcat/doc/upvar.n
@@ -0,0 +1,122 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH upvar n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+upvar \- Create link to variable in a different stack frame
+.SH SYNOPSIS
+\fBupvar \fR?\fIlevel\fR? \fIotherVar myVar \fR?\fIotherVar myVar \fR...?
+.BE
+
+.SH DESCRIPTION
+.PP
+This command arranges for one or more local variables in the current
+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 (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
+in the current procedure by the name given in the corresponding
+\fImyVar\fR argument.
+The variable named by \fIotherVar\fR need not exist at the time of the
+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. 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.
+.PP
+The \fBupvar\fR command simplifies the implementation of call-by-name
+procedure calling and also makes it easier to build new control constructs
+as Tcl procedures.
+For example, consider the following procedure:
+.PP
+.CS
+proc \fIadd2\fR name {
+ \fBupvar\fR $name x
+ set x [expr {$x + 2}]
+}
+.CE
+.PP
+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 \fIadd2\fR
+to access the variable in the caller's procedure frame.
+.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.
+This means each \fBnamespace eval\fR command
+counts as another call level for \fBuplevel\fR and \fBupvar\fR commands.
+For example, \fBinfo level\fR \fB1\fR will return a list
+describing a command that is either
+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
+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
+by exiting the procedure in which it is defined. However, it is
+possible to retarget an upvar variable by executing another \fBupvar\fR
+command.
+.SH "TRACES AND UPVAR"
+.PP
+Upvar interacts with traces in a straightforward but possibly
+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
+.QW "\fIlocalVar\fR"
+rather than
+.QW "\fIoriginalVar\fR" :
+.PP
+.CS
+proc \fItraceproc\fR { name index op } {
+ puts $name
+}
+proc \fIsetByUpvar\fR { name value } {
+ \fBupvar\fR $name localVar
+ set localVar $value
+}
+set originalVar 1
+trace variable originalVar w \fItraceproc\fR
+\fIsetByUpvar\fR originalVar 2
+.CE
+.PP
+If \fIotherVar\fR refers to an element of an array, then variable
+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.
+.SH EXAMPLE
+A \fBdecr\fR command that works like \fBincr\fR except it subtracts
+the value from the variable instead of adding it:
+.PP
+.CS
+proc decr {varName {decrement 1}} {
+ \fBupvar\fR 1 $varName var
+ incr var [expr {-$decrement}]
+}
+.CE
+.SH "SEE ALSO"
+global(n), namespace(n), uplevel(n), variable(n)
+.SH KEYWORDS
+context, frame, global, level, namespace, procedure, upvar, variable
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/library/msgcat/doc/variable.n b/library/msgcat/doc/variable.n
new file mode 100644
index 0000000..96263b6
--- /dev/null
+++ b/library/msgcat/doc/variable.n
@@ -0,0 +1,100 @@
+'\"
+'\" Copyright (c) 1993-1997 Bell Labs Innovations for Lucent Technologies
+'\" 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 variable n 8.0 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+variable \- create and initialize a namespace variable
+.SH SYNOPSIS
+\fBvariable \fR\fIname\fR
+.sp
+\fBvariable \fR?\fIname value...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command is normally used within a
+\fBnamespace eval\fR command to create one or more variables
+within a namespace.
+Each variable \fIname\fR is initialized with \fIvalue\fR.
+The \fIvalue\fR for the last variable is optional.
+.PP
+If a variable \fIname\fR does not exist, it is created.
+In this case, if \fIvalue\fR is specified,
+it is assigned to the newly created variable.
+If no \fIvalue\fR is specified, the new variable is left undefined.
+If the variable already exists,
+it is set to \fIvalue\fR if \fIvalue\fR is specified
+or left unchanged if no \fIvalue\fR is given.
+Normally, \fIname\fR is unqualified
+(does not include the names of any containing namespaces),
+and the variable is created in the current namespace.
+If \fIname\fR includes any namespace qualifiers,
+the variable is created in the specified namespace. If the variable
+is not defined, it will be visible to the \fBnamespace which\fR
+command, but not to the \fBinfo exists\fR command.
+.PP
+If the \fBvariable\fR command is executed inside a Tcl procedure,
+it creates local variables
+linked to the corresponding namespace variables (and therefore these
+variables are listed by \fBinfo vars\fR.)
+In this way the \fBvariable\fR command resembles the \fBglobal\fR command,
+although the \fBglobal\fR command
+only links to variables in the global namespace.
+If any \fIvalue\fRs are given,
+they are used to modify the values of the associated namespace variables.
+If a namespace variable does not exist,
+it is created and optionally initialized.
+.PP
+A \fIname\fR argument cannot reference an element within an array.
+Instead, \fIname\fR should reference the entire array,
+and the initialization \fIvalue\fR should be left off.
+After the variable has been declared,
+elements within the array can be set using ordinary
+\fBset\fR or \fBarray\fR commands.
+.SH EXAMPLES
+.PP
+Create a variable in a namespace:
+.PP
+.CS
+namespace eval foo {
+ \fBvariable\fR bar 12345
+}
+.CE
+.PP
+Create an array in a namespace:
+.PP
+.CS
+namespace eval someNS {
+ \fBvariable\fR someAry
+ array set someAry {
+ someName someValue
+ otherName otherValue
+ }
+}
+.CE
+.PP
+Access variables in namespaces from a procedure:
+.PP
+.CS
+namespace eval foo {
+ proc spong {} {
+ # Variable in this namespace
+ \fBvariable\fR bar
+ puts "bar is $bar"
+
+ # Variable in another namespace
+ \fBvariable\fR ::someNS::someAry
+ parray someAry
+ }
+}
+.CE
+.SH "SEE ALSO"
+global(n), namespace(n), upvar(n)
+.SH KEYWORDS
+global, namespace, procedure, variable
diff --git a/library/msgcat/doc/vwait.n b/library/msgcat/doc/vwait.n
new file mode 100644
index 0000000..38a8081
--- /dev/null
+++ b/library/msgcat/doc/vwait.n
@@ -0,0 +1,246 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH vwait n 8.0 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+vwait \- Process events until a variable is written
+.SH SYNOPSIS
+\fBvwait\fR \fIvarName\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command enters the Tcl event loop to process events, blocking
+the application if no events are ready. It continues processing
+events until some event handler sets the value of the global 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. The \fIvarName\fR argument is always interpreted as
+a variable name with respect to the global namespace, but can refer to any
+namespace's variables if the fully-qualified name is given.
+.PP
+In some cases the \fBvwait\fR command may not return immediately
+after \fIvarName\fR is set. This happens if the event handler
+that sets \fIvarName\fR does not complete immediately. For example,
+if an event handler sets \fIvarName\fR and then itself calls
+\fBvwait\fR to wait for a different variable, then it may not return
+for a long time. During this time the top-level \fBvwait\fR is
+blocked waiting for the event handler to complete, so it cannot
+return either. (See the \fBNESTED VWAITS BY EXAMPLE\fR below.)
+.PP
+To be clear, \fImultiple \fBvwait\fI calls will nest and will not happen in
+parallel\fR. The outermost call to \fBvwait\fR will not return until all the
+inner ones do. It is recommended that code should never nest \fBvwait\fR
+calls (by avoiding putting them in event callbacks) but when that is not
+possible, care should be taken to add interlock variables to the code to
+prevent all reentrant calls to \fBvwait\fR that are not \fIstrictly\fR
+necessary. Be aware that the synchronous modes of operation of some Tcl
+packages (e.g.,\ \fBhttp\fR) use \fBvwait\fR internally; if using the event
+loop, it is best to use the asynchronous callback-based modes of operation of
+those packages where available.
+.SH EXAMPLES
+.PP
+Run the event-loop continually until some event calls \fBexit\fR.
+(You can use any variable not mentioned elsewhere, but the name
+\fIforever\fR reminds you at a glance of the intent.)
+.PP
+.CS
+\fBvwait\fR forever
+.CE
+.PP
+Wait five seconds for a connection to a server socket, otherwise
+close the socket and continue running the script:
+.PP
+.CS
+# Initialise the state
+after 5000 set state timeout
+set server [socket -server accept 12345]
+proc accept {args} {
+ global state connectionInfo
+ set state accepted
+ set connectionInfo $args
+}
+
+# Wait for something to happen
+\fBvwait\fR state
+
+# Clean up events that could have happened
+close $server
+after cancel set state timeout
+
+# Do something based on how the vwait finished...
+switch $state {
+ timeout {
+ puts "no connection on port 12345"
+ }
+ accepted {
+ puts "connection: $connectionInfo"
+ puts [lindex $connectionInfo 0] "Hello there!"
+ }
+}
+.CE
+.PP
+A command that will wait for some time delay by waiting for a namespace
+variable to be set. Includes an interlock to prevent nested waits.
+.PP
+.CS
+namespace eval example {
+ variable v done
+ proc wait {delay} {
+ variable v
+ if {$v ne "waiting"} {
+ set v waiting
+ after $delay [namespace code {set v done}]
+ \fBvwait\fR [namespace which -variable v]
+ }
+ return $v
+ }
+}
+.CE
+.PP
+When running inside a \fBcoroutine\fR, an alternative to using \fBvwait\fR is
+to \fByield\fR to an outer event loop and to get recommenced when the variable
+is set, or at an idle moment after that.
+.PP
+.CS
+coroutine task apply {{} {
+ # simulate [after 1000]
+ after 1000 [info coroutine]
+ yield
+
+ # schedule the setting of a global variable, as normal
+ after 2000 {set var 1}
+
+ # simulate [\fBvwait\fR var]
+ proc updatedVar {task args} {
+ after idle $task
+ trace remove variable ::var write "updatedVar $task"
+ }
+ trace add variable ::var write "updatedVar [info coroutine]"
+ yield
+}}
+.CE
+.SS "NESTED VWAITS BY EXAMPLE"
+.PP
+This example demonstrates what can happen when the \fBvwait\fR command is
+nested. The script will never finish because the waiting for the \fIa\fR
+variable never finishes; that \fBvwait\fR command is still waiting for a
+script scheduled with \fBafter\fR to complete, which just happens to be
+running an inner \fBvwait\fR (for \fIb\fR) even though the event that the
+outer \fBvwait\fR was waiting for (the setting of \fIa\fR) has occurred.
+.PP
+.CS
+after 500 {
+ puts "waiting for b"
+ \fBvwait\fR b
+ puts "b was set"
+}
+after 1000 {
+ puts "setting a"
+ set a 10
+}
+puts "waiting for a"
+\fBvwait\fR a
+puts "a was set"
+puts "setting b"
+set b 42
+.CE
+.PP
+If you run the above code, you get this output:
+.PP
+.CS
+waiting for a
+waiting for b
+setting a
+.CE
+.PP
+The script will never print
+.QW "a was set"
+until after it has printed
+.QW "b was set"
+because of the nesting of \fBvwait\fR commands, and yet \fIb\fR will not be
+set until after the outer \fBvwait\fR returns, so the script has deadlocked.
+The only ways to avoid this are to either structure the overall program in
+continuation-passing style or to use \fBcoroutine\fR to make the continuations
+implicit. The first of these options would be written as:
+.PP
+.CS
+after 500 {
+ puts "waiting for b"
+ trace add variable b write {apply {args {
+ global a b
+ trace remove variable ::b write \e
+ [lrange [info level 0] 0 1]
+ puts "b was set"
+ set ::done ok
+ }}}
+}
+after 1000 {
+ puts "setting a"
+ set a 10
+}
+puts "waiting for a"
+trace add variable a write {apply {args {
+ global a b
+ trace remove variable a write [lrange [info level 0] 0 1]
+ puts "a was set"
+ puts "setting b"
+ set b 42
+}}}
+\fBvwait\fR done
+.CE
+.PP
+The second option, with \fBcoroutine\fR and some helper procedures, is done
+like this:
+.PP
+.CS
+# A coroutine-based wait-for-variable command
+proc waitvar globalVar {
+ trace add variable ::$globalVar write \e
+ [list apply {{v c args} {
+ trace remove variable $v write \e
+ [lrange [info level 0] 0 3]
+ after 0 $c
+ }} ::$globalVar [info coroutine]]
+ yield
+}
+# A coroutine-based wait-for-some-time command
+proc waittime ms {
+ after $ms [info coroutine]
+ yield
+}
+
+coroutine task-1 eval {
+ puts "waiting for a"
+ waitvar a
+ puts "a was set"
+ puts "setting b"
+ set b 42
+}
+coroutine task-2 eval {
+ waittime 500
+ puts "waiting for b"
+ waitvar b
+ puts "b was set"
+ set done ok
+}
+coroutine task-3 eval {
+ waittime 1000
+ puts "setting a"
+ set a 10
+}
+\fBvwait\fR done
+.CE
+.SH "SEE ALSO"
+global(n), update(n)
+.SH KEYWORDS
+asynchronous I/O, event, variable, wait
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/library/msgcat/doc/while.n b/library/msgcat/doc/while.n
new file mode 100644
index 0000000..5416e25
--- /dev/null
+++ b/library/msgcat/doc/while.n
@@ -0,0 +1,65 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH while n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+while \- Execute script repeatedly as long as a condition is met
+.SH SYNOPSIS
+\fBwhile \fItest body\fR
+.BE
+.SH DESCRIPTION
+.PP
+The \fBwhile\fR command evaluates \fItest\fR as an expression
+(in the same way that \fBexpr\fR evaluates its argument).
+The value of the expression must a proper boolean
+value; if it is a true value
+then \fIbody\fR is executed by passing it to the Tcl interpreter.
+Once \fIbody\fR has been executed then \fItest\fR is evaluated
+again, and the process repeats until eventually \fItest\fR
+evaluates to a false boolean value. \fBContinue\fR
+commands may be executed inside \fIbody\fR to terminate the current
+iteration of the loop, and \fBbreak\fR
+commands may be executed inside \fIbody\fR to cause immediate
+termination of the \fBwhile\fR command. The \fBwhile\fR command
+always returns an empty string.
+.PP
+Note: \fItest\fR should almost always be enclosed in braces. If not,
+variable substitutions will be made before the \fBwhile\fR
+command starts executing, which means that variable changes
+made by the loop body will not be considered in the expression.
+This is likely to result in an infinite loop. If \fItest\fR is
+enclosed in braces, variable substitutions are delayed until the
+expression is evaluated (before
+each loop iteration), so changes in the variables will be visible.
+For an example, try the following script with and without the braces
+around \fB$x<10\fR:
+.PP
+.CS
+set x 0
+\fBwhile\fR {$x<10} {
+ puts "x is $x"
+ incr x
+}
+.CE
+.SH EXAMPLE
+.PP
+Read lines from a channel until we get to the end of the stream, and
+print them out with a line-number prepended:
+.PP
+.CS
+set lineCount 0
+\fBwhile\fR {[gets $chan line] >= 0} {
+ puts "[incr lineCount]: $line"
+}
+.CE
+.SH "SEE ALSO"
+break(n), continue(n), for(n), foreach(n)
+.SH KEYWORDS
+boolean, loop, test, while
diff --git a/library/msgcat/doc/zlib.n b/library/msgcat/doc/zlib.n
new file mode 100644
index 0000000..a4ff7f8
--- /dev/null
+++ b/library/msgcat/doc/zlib.n
@@ -0,0 +1,391 @@
+'\"
+'\" Copyright (c) 2008 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH zlib n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+zlib \- compression and decompression operations
+.SH SYNOPSIS
+.nf
+\fBzlib \fIsubcommand arg ...\fR
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBzlib\fR command provides access to the compression and check-summing
+facilities of the Zlib library by Jean-loup Gailly and Mark Adler. It has the
+following subcommands.
+.SS "COMPRESSION SUBCOMMANDS"
+.TP
+\fBzlib compress\fI string\fR ?\fIlevel\fR?
+.
+Returns the zlib-format compressed binary data of the binary string in
+\fIstring\fR. If present, \fIlevel\fR gives the compression level to use (from
+0, which is uncompressed, to 9, maximally compressed).
+.TP
+\fBzlib decompress\fI string\fR ?\fIbufferSize\fR?
+.
+Returns the uncompressed version of the raw compressed binary data in
+\fIstring\fR. If present, \fIbufferSize\fR is a hint as to what size of buffer
+is to be used to receive the data.
+.TP
+\fBzlib deflate\fI string\fR ?\fIlevel\fR?
+.
+Returns the raw compressed binary data of the binary string in \fIstring\fR.
+If present, \fIlevel\fR gives the compression level to use (from 0, which is
+uncompressed, to 9, maximally compressed).
+.TP
+\fBzlib gunzip\fI string\fR ?\fB\-headerVar \fIvarName\fR?
+.
+Return the uncompressed contents of binary string \fIstring\fR, which must
+have been in gzip format. If \fB\-headerVar\fR is given, store a dictionary
+describing the contents of the gzip header in the variable called
+\fIvarName\fR. The keys of the dictionary that may be present are:
+.RS
+.TP
+\fBcomment\fR
+.
+The comment field from the header, if present.
+.TP
+\fBcrc\fR
+.
+A boolean value describing whether a CRC of the header is computed.
+.TP
+\fBfilename\fR
+.
+The filename field from the header, if present.
+.TP
+\fBos\fR
+.
+The operating system type code field from the header (if not the
+QW unknown
+value). See RFC 1952 for the meaning of these codes.
+.TP
+\fBsize\fR
+.
+The size of the uncompressed data.
+.TP
+\fBtime\fR
+.
+The time field from the header if non-zero, expected to be time that the file
+named by the \fBfilename\fR field was modified. Suitable for use with
+\fBclock format\fR.
+.TP
+\fBtype\fR
+.
+The type of the uncompressed data (\fBbinary\fR or \fBtext\fR) if known.
+.RE
+.TP
+\fBzlib gzip\fI string\fR ?\fB\-level \fIlevel\fR? ?\fB\-header \fIdict\fR?
+.
+Return the compressed contents of binary string \fIstring\fR in gzip format.
+If \fB\-level\fR is given, \fIlevel\fR gives the compression level to use
+(from 0, which is uncompressed, to 9, maximally compressed). If \fB\-header\fR
+is given, \fIdict\fR is a dictionary containing values used for the gzip
+header. The following keys may be defined:
+.RS
+.TP
+\fBcomment\fR
+.
+Add the given comment to the header of the gzip-format data.
+.TP
+\fBcrc\fR
+.
+A boolean saying whether to compute a CRC of the header. Note that if the data
+is to be interchanged with the \fBgzip\fR program, a header CRC should
+\fInot\fR be computed.
+.TP
+\fBfilename\fR
+.
+The name of the file that the data to be compressed came from.
+.TP
+\fBos\fR
+.
+The operating system type code, which should be one of the values described in
+RFC 1952.
+.TP
+\fBtime\fR
+.
+The time that the file named in the \fBfilename\fR key was last modified. This
+will be in the same as is returned by \fBclock seconds\fR or \fBfile mtime\fR.
+.TP
+\fBtype\fR
+.
+The type of the data being compressed, being \fBbinary\fR or \fBtext\fR.
+.RE
+.TP
+\fBzlib inflate\fI string\fR ?\fIbufferSize\fR?
+.
+Returns the uncompressed version of the raw compressed binary data in
+\fIstring\fR. If present, \fIbufferSize\fR is a hint as to what size of buffer
+is to be used to receive the data.
+.SS "CHANNEL SUBCOMMAND"
+.TP
+\fBzlib push\fI mode channel\fR ?\fIoptions ...\fR?
+.
+Pushes a compressing or decompressing transformation onto the channel
+\fIchannel\fR.
+The transformation can be removed again with \fBchan pop\fR.
+The \fImode\fR argument determines what type of transformation
+is pushed; the following are supported:
+.RS
+.TP
+\fBcompress\fR
+.
+The transformation will be a compressing transformation that produces
+zlib-format data on \fIchannel\fR, which must be writable.
+.TP
+\fBdecompress\fR
+.
+The transformation will be a decompressing transformation that reads
+zlib-format data from \fIchannel\fR, which must be readable.
+.TP
+\fBdeflate\fR
+.
+The transformation will be a compressing transformation that produces raw
+compressed data on \fIchannel\fR, which must be writable.
+.TP
+\fBgunzip\fR
+.
+The transformation will be a decompressing transformation that reads
+gzip-format data from \fIchannel\fR, which must be readable.
+.TP
+\fBgzip\fR
+.
+The transformation will be a compressing transformation that produces
+gzip-format data on \fIchannel\fR, which must be writable.
+.TP
+\fBinflate\fR
+.
+The transformation will be a decompressing transformation that reads raw
+compressed data from \fIchannel\fR, which must be readable.
+.PP
+The following options may be set when creating a transformation via
+the
+.QW "\fIoptions ...\fR"
+to the \fBzlib push\fR command:
+.TP
+\fB\-header\fI dictionary\fR
+.
+Passes a description of the gzip header to create, in the same format that
+\fBzlib gzip\fR understands.
+.TP
+\fB\-level\fI compressionLevel\fR
+.
+How hard to compress the data. Must be an integer from 0 (uncompressed) to 9
+(maximally compressed).
+'\".TP
+'\"\fB\-limit\fI readaheadLimit\fR
+'\".
+'\"The maximum number of bytes ahead to read.
+'\"\fITODO: not yet implemented!\fR
+.PP
+Both compressing and decompressing channel transformations add extra
+configuration options that may be accessed through \fBchan configure\fR. Each
+option is either a read-only or a write-only option. The options are:
+.TP
+\fB\-flush\fI type\fR
+.
+This write-only operation flushes the current state of the compressor to the
+underlying channel. It is only valid for compressing transformations. The
+\fItype\fR must be either \fBsync\fR or \fBfull\fR for a normal flush or an
+expensive flush respectively. Flushing degrades the compression ratio, but
+makes it easier for a decompressor to recover more of the file in the case of
+data corruption.
+.TP
+\fB\-checksum\fR
+.
+This read-only option gets the current checksum for the uncompressed data
+that the compression engine has seen so far. It is valid for both
+compressing and decompressing transforms, but not for the raw inflate
+and deflate formats. The compression algorithm depends on what
+format is being produced or consumed.
+.TP
+\fB\-header\fR
+.
+This read-only option, only valid for decompressing transforms that are
+processing gzip-format data, returns the dictionary describing the header read
+off the data stream.
+.RE
+.SS "STREAMING SUBCOMMAND"
+.TP
+\fBzlib stream\fI mode\fR ?\fIlevel\fR?
+.
+Creates a streaming compression or decompression command based on the
+\fImode\fR, and return the name of the command. For a description of how that
+command works, see \fBSTREAMING INSTANCE COMMAND\fR below. The following modes
+are supported:
+.RS
+.TP
+\fBzlib stream compress\fR ?\fIlevel\fR?
+.
+The stream will be a compressing stream that produces zlib-format output,
+using compression level \fIlevel\fR (if specified) which will be an integer
+from 0 to 9.
+.TP
+\fBzlib stream decompress\fR
+.
+The stream will be a decompressing stream that takes zlib-format input and
+produces uncompressed output.
+.TP
+\fBzlib stream deflate\fR ?\fIlevel\fR?
+.
+The stream will be a compressing stream that produces raw output, using
+compression level \fIlevel\fR (if specified) which will be an integer from 0
+to 9.
+.TP
+\fBzlib stream gunzip\fR
+.
+The stream will be a decompressing stream that takes gzip-format input and
+produces uncompressed output.
+.TP
+\fBzlib stream gzip\fR ?\fIlevel\fR?
+.
+The stream will be a compressing stream that produces gzip-format output,
+using compression level \fIlevel\fR (if specified) which will be an integer
+from 0 to 9.
+'\" TODO: Header dictionary!
+.TP
+\fBzlib stream inflate\fR
+.
+The stream will be a decompressing stream that takes raw compressed input and
+produces uncompressed output.
+.RE
+.SS "CHECKSUMMING SUBCOMMANDS"
+.TP
+\fBzlib adler32\fI string\fR ?\fIinitValue\fR?
+.
+Compute a checksum of binary string \fIstring\fR using the Adler-32 algorithm.
+If given, \fIinitValue\fR is used to initialize the checksum engine.
+.TP
+\fBzlib crc32\fI string\fR ?\fIinitValue\fR?
+.
+Compute a checksum of binary string \fIstring\fR using the CRC-32 algorithm.
+If given, \fIinitValue\fR is used to initialize the checksum engine.
+.SH "STREAMING INSTANCE COMMAND"
+.PP
+Streaming compression instance commands are produced by the \fBzlib stream\fR
+command. They are used by calling their \fBput\fR subcommand one or more times
+to load data in, and their \fBget\fR subcommand one or more times to extract
+the transformed data.
+.PP
+The full set of subcommands supported by a streaming instance command,
+\fIstream\fR, is as follows:
+.TP
+\fIstream \fBadd\fR ?\fIoption\fR? \fIdata\fR
+.
+A short-cut for
+.QW "\fIstream \fBput \fIoption data\fR"
+followed by
+.QW "\fIstream \fBget\fR" .
+.TP
+\fIstream \fBchecksum\fR
+.
+Returns the checksum of the uncompressed data seen so far by this stream.
+.TP
+\fIstream \fBclose\fR
+.
+Deletes this stream and frees up all resources associated with it.
+.TP
+\fIstream \fBeof\fR
+.
+Returns a boolean indicating whether the end of the stream (as determined by
+the compressed data itself) has been reached. Not all formats support
+detection of the end of the stream.
+.TP
+\fIstream \fBfinalize\fR
+.
+A short-cut for
+.QW "\fIstream \fBput \-finalize {}\fR" .
+.TP
+\fIstream \fBflush\fR
+.
+A short-cut for
+.QW "\fIstream \fBput \-flush {}\fR" .
+.TP
+\fIstream \fBfullflush\fR
+.
+A short-cut for
+.QW "\fIstream \fBput \-fullflush {}\fR" .
+.TP
+\fIstream \fBget \fR?\fIcount\fR?
+.
+Return up to \fIcount\fR bytes from \fIstream\fR's internal buffers with the
+transformation applied. If \fIcount\fR is omitted, the entire contents of the
+buffers are returned.
+.TP
+\fIstream \fBput\fR ?\fIoption\fR? \fIdata\fR
+.
+Append the contents of the binary string \fIdata\fR to \fIstream\fR's internal
+buffers while applying the transformation. If present, \fIoption\fR must be
+one of the following (or an unambiguous prefix) which are used to modify the
+way in which the transformation is applied:
+.RS
+.TP
+\fB\-finalize\fR
+.
+Mark the stream as finished, ensuring that all bytes have been wholly
+compressed or decompressed. For gzip streams, this also ensures that the
+footer is written to the stream. The stream will need to be reset before
+having more data written to it after this, though data can still be read out
+of the stream with the \fBget\fR subcommand.
+.TP
+\fB\-flush\fR
+.
+Ensure that a decompressor consuming the bytes that the current (compressing)
+stream is producing will be able to produce all the bytes that have been
+compressed so far, at some performance penalty.
+.TP
+\fB\-fullflush\fR
+.
+Ensure that not only can a decompressor handle all the bytes produced so far
+(as with \fB\-flush\fR above) but also that it can restart from this point if
+it detects that the stream is partially corrupt. This incurs a substantial
+performance penalty.
+.RE
+.TP
+\fIstream \fBreset\fR
+.
+Puts any stream, including those that have been finalized or that have reached
+eof, back into a state where it can process more data. Throws away all
+internally buffered data.
+.SH EXAMPLES
+.PP
+To compress a Tcl string, it should be first converted to a particular charset
+encoding since the \fBzlib\fR command always operates on binary strings.
+.PP
+.CS
+set binData [encoding convertto utf-8 $string]
+set compData [\fBzlib compress\fR $binData]
+.CE
+.PP
+When converting back, it is also important to reverse the charset encoding:
+.PP
+.CS
+set binData [\fBzlib decompress\fR $compData]
+set string [encoding convertfrom utf-8 $binData]
+.CE
+.PP
+The compression operation from above can also be done with streams, which is
+especially helpful when you want to accumulate the data by stages:
+.PP
+.CS
+set strm [\fBzlib stream\fR compress]
+$\fIstrm \fBput\fR [encoding convertto utf-8 $string]
+# ...
+$\fIstrm \fBfinalize\fR
+set compData [$\fIstrm \fBget\fR]
+$\fIstrm \fBclose\fR
+.CE
+.SH "SEE ALSO"
+binary(n), chan(n), encoding(n), Tcl_ZlibDeflate(3), RFC1950 \- RFC1952
+.SH "KEYWORDS"
+compress, decompress, deflate, gzip, inflate
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/library/msgcat/tests/README b/library/msgcat/tests/README
new file mode 100644
index 0000000..ce2382e
--- /dev/null
+++ b/library/msgcat/tests/README
@@ -0,0 +1,107 @@
+README -- Tcl test suite design document.
+
+Contents:
+---------
+
+ 1. Introduction
+ 2. Running tests
+ 3. Adding tests
+ 4. Incompatibilities with prior Tcl versions
+
+1. Introduction:
+----------------
+
+This directory contains a set of validation tests for the Tcl commands
+and C Library procedures for Tcl. Each of the files whose name ends
+in ".test" is intended to fully exercise the functions in the C source
+file that corresponds to the file prefix. The C functions and/or Tcl
+commands tested by a given file are listed in the first line of the
+file.
+
+2. Running tests:
+-----------------
+
+We recommend that you use the "test" target of Tcl's Makefile to run
+the test suite. From the directory in which you build Tcl, simply
+type "make test". This will create a special executable named
+tcltest in which the testing scripts will be evaluated. To create
+the tcltest executable without running the test suite, simple type
+"make tcltest".
+
+All the configuration options of the tcltest package are available
+during a "make test" by defining the TESTFLAGS environment variable.
+For example,if you wish to run only those tests in the file append.test,
+you can type:
+
+ make test TESTFLAGS="-file append.test"
+
+For interactive testing, the Tcl Makefile provides the "runtest" target.
+Type "make runtest" in your build directory, and the tcltest executable
+will be created, if necessary, then it will run interactively. At the
+command prompt, you may type any Tcl commands. If you type
+"source ../tests/all.tcl", the test suite will run. You may use the
+tcltest::configure command to configure the test suite run as an
+alternative to command line options via TESTFLAGS. You might also
+wish to use the tcltest::testConstraint command to select the constraints
+that govern which tests are run. See the documentation for the tcltest
+package for details.
+
+3. Adding tests:
+----------------
+
+Please see the tcltest man page for more information regarding how to
+write and run tests.
+
+Please note that the all.tcl file will source your new test file if
+the filename matches the tests/*.test pattern (as it should). The
+names of test files that contain regression (or glass-box) tests
+should correspond to the Tcl or C code file that they are testing.
+For example, the test file for the C file "tclCmdAH.c" is
+"cmdAH.test". Test files that contain black-box tests may not
+correspond to any Tcl or C code file so they should match the pattern
+"*_bb.test".
+
+Be sure your new test file can be run from any working directory.
+
+Be sure no temporary files are left behind by your test file.
+Use [tcltest::makeFile], [tcltest::removeFile], and [tcltest::cleanupTests]
+properly to be sure of this.
+
+Be sure your tests can run cross-platform in both a build environment
+as well as an installation environment. If your test file contains
+tests that should not be run in one or more of those cases, please use
+the constraints mechanism to skip those tests.
+
+4. Incompatibilities of package tcltest 2.1 with
+ testing machinery of very old versions of Tcl:
+------------------------------------------------
+
+1) Global variables such as VERBOSE, TESTS, and testConfig of the
+ old machinery correspond to the [configure -verbose],
+ [configure -match], and [testConstraint] commands of tcltest 2.1,
+ respectively.
+
+2) VERBOSE values were longer numeric. [configure -verbose] values
+ are lists of keywords.
+
+3) When you run "make test", the working dir for the test suite is now
+ the one from which you called "make test", rather than the "tests"
+ directory. This change allows for both unix and windows test
+ suites to be run simultaneously without interference with each
+ other or with existing files. All tests must now run independently
+ of their working directory.
+
+4) The "all" file is now called "all.tcl"
+
+5) The "defs" and "defs.tcl" files no longer exist.
+
+6) Instead of creating a doAllTests file in the tests directory, to
+ run all nonPortable tests, just use the "-constraints nonPortable"
+ command line flag. If you are running interactively, you can run
+ [tcltest::testConstraint nonPortable 1] (after loading the tcltest
+ package).
+
+7) Direct evaluation of the *.test files by the "source" command is no
+ longer recommended. Instead, "source all.tcl" and use the "-file" and
+ "-notfile" options of tcltest::configure to control which *.test files
+ are evaluated.
diff --git a/library/msgcat/tests/all.tcl b/library/msgcat/tests/all.tcl
new file mode 100644
index 0000000..05d3024
--- /dev/null
+++ b/library/msgcat/tests/all.tcl
@@ -0,0 +1,19 @@
+# all.tcl --
+#
+# This file contains a top-level script to run all of the Tcl
+# tests. Execute it by invoking "source all.test" when running tcltest
+# in this directory.
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2000 by Ajuba Solutions
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package prefer latest
+package require Tcl 8.5
+package require tcltest 2.2
+namespace import tcltest::*
+configure {*}$argv -testdir [file dir [info script]]
+runAllTests
+proc exit args {}
diff --git a/library/msgcat/tests/append.test b/library/msgcat/tests/append.test
new file mode 100644
index 0000000..69c6381
--- /dev/null
+++ b/library/msgcat/tests/append.test
@@ -0,0 +1,306 @@
+# Commands covered: append lappend
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+unset -nocomplain x
+
+test append-1.1 {append command} {
+ unset -nocomplain x
+ list [append x 1 2 abc "long string"] $x
+} {{12abclong string} {12abclong string}}
+test append-1.2 {append command} {
+ set x ""
+ list [append x first] [append x second] [append x third] $x
+} {first firstsecond firstsecondthird firstsecondthird}
+test append-1.3 {append command} {
+ set x "abcd"
+ append x
+} abcd
+
+test append-2.1 {long appends} {
+ set x ""
+ for {set i 0} {$i < 1000} {set i [expr $i+1]} {
+ append x "foobar "
+ }
+ set y "foobar"
+ set y "$y $y $y $y $y $y $y $y $y $y"
+ set y "$y $y $y $y $y $y $y $y $y $y"
+ set y "$y $y $y $y $y $y $y $y $y $y "
+ expr {$x == $y}
+} 1
+
+test append-3.1 {append errors} -returnCodes error -body {
+ append
+} -result {wrong # args: should be "append varName ?value ...?"}
+test append-3.2 {append errors} -returnCodes error -body {
+ set x ""
+ append x(0) 44
+} -result {can't set "x(0)": variable isn't array}
+test append-3.3 {append errors} -returnCodes error -body {
+ unset -nocomplain x
+ append x
+} -result {can't read "x": no such variable}
+
+test append-4.1 {lappend command} {
+ unset -nocomplain x
+ list [lappend x 1 2 abc "long string"] $x
+} {{1 2 abc {long string}} {1 2 abc {long string}}}
+test append-4.2 {lappend command} {
+ set x ""
+ list [lappend x first] [lappend x second] [lappend x third] $x
+} {first {first second} {first second third} {first second third}}
+test append-4.3 {lappend command} -body {
+ proc foo {} {
+ global x
+ set x old
+ unset x
+ lappend x new
+ }
+ foo
+} -cleanup {
+ rename foo {}
+} -result {new}
+test append-4.4 {lappend command} {
+ set x {}
+ lappend x \{\ abc
+} {\{\ abc}
+test append-4.5 {lappend command} {
+ set x {}
+ lappend x \{ abc
+} {\{ abc}
+test append-4.6 {lappend command} {
+ set x {1 2 3}
+ lappend x
+} {1 2 3}
+test append-4.7 {lappend command} {
+ set x "a\{"
+ lappend x abc
+} "a\\\{ abc"
+test append-4.8 {lappend command} {
+ set x "\\\{"
+ lappend x abc
+} "\\{ abc"
+test append-4.9 {lappend command} -returnCodes error -body {
+ set x " \{"
+ lappend x abc
+} -result {unmatched open brace in list}
+test append-4.10 {lappend command} -returnCodes error -body {
+ set x " \{"
+ lappend x abc
+} -result {unmatched open brace in list}
+test append-4.11 {lappend command} -returnCodes error -body {
+ set x "\{\{\{"
+ lappend x abc
+} -result {unmatched open brace in list}
+test append-4.12 {lappend command} -returnCodes error -body {
+ set x "x \{\{\{"
+ lappend x abc
+} -result {unmatched open brace in list}
+test append-4.13 {lappend command} {
+ set x "x\{\{\{"
+ lappend x abc
+} "x\\\{\\\{\\\{ abc"
+test append-4.14 {lappend command} {
+ set x " "
+ lappend x abc
+} "abc"
+test append-4.15 {lappend command} {
+ set x "\\ "
+ lappend x abc
+} "{ } abc"
+test append-4.16 {lappend command} {
+ set x "x "
+ lappend x abc
+} "x abc"
+test append-4.17 {lappend command} {
+ unset -nocomplain x
+ lappend x
+} {}
+test append-4.18 {lappend command} {
+ unset -nocomplain x
+ lappend x {}
+} {{}}
+test append-4.19 {lappend command} {
+ unset -nocomplain x
+ lappend x(0)
+} {}
+test append-4.20 {lappend command} {
+ unset -nocomplain x
+ lappend x(0) abc
+} {abc}
+unset -nocomplain x
+test append-4.21 {lappend command} -returnCodes error -body {
+ set x \"
+ lappend x
+} -result {unmatched open quote in list}
+test append-4.22 {lappend command} -returnCodes error -body {
+ set x \"
+ lappend x abc
+} -result {unmatched open quote in list}
+
+test append-5.1 {long lappends} -setup {
+ unset -nocomplain x
+ proc check {var size} {
+ set l [llength $var]
+ if {$l != $size} {
+ return "length mismatch: should have been $size, was $l"
+ }
+ for {set i 0} {$i < $size} {set i [expr $i+1]} {
+ set j [lindex $var $i]
+ if {$j ne "item $i"} {
+ return "element $i should have been \"item $i\", was \"$j\""
+ }
+ }
+ return ok
+ }
+} -body {
+ set x ""
+ for {set i 0} {$i < 300} {incr i} {
+ lappend x "item $i"
+ }
+ check $x 300
+} -cleanup {
+ rename check {}
+} -result ok
+
+test append-6.1 {lappend errors} -returnCodes error -body {
+ lappend
+} -result {wrong # args: should be "lappend varName ?value ...?"}
+test append-6.2 {lappend errors} -returnCodes error -body {
+ set x ""
+ lappend x(0) 44
+} -result {can't set "x(0)": variable isn't array}
+
+test append-7.1 {lappend-created var and error in trace on that var} -setup {
+ catch {rename foo ""}
+ unset -nocomplain x
+} -body {
+ trace variable x w foo
+ proc foo {} {global x; unset x}
+ catch {lappend x 1}
+ proc foo {args} {global x; unset x}
+ info exists x
+ set x
+ lappend x 1
+ list [info exists x] [catch {set x} msg] $msg
+} -result {0 1 {can't read "x": no such variable}}
+test append-7.2 {lappend var triggers read trace} -setup {
+ unset -nocomplain myvar
+ unset -nocomplain ::result
+} -body {
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend myvar a
+ return $::result
+} -result {myvar {} r}
+test append-7.3 {lappend var triggers read trace, array var} -setup {
+ unset -nocomplain myvar
+ unset -nocomplain ::result
+} -body {
+ # The behavior of read triggers on lappend changed in 8.0 to not trigger
+ # them, and was changed back in 8.4.
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend myvar(b) a
+ return $::result
+} -result {myvar b r}
+test append-7.4 {lappend var triggers read trace, array var exists} -setup {
+ unset -nocomplain myvar
+ unset -nocomplain ::result
+} -body {
+ set myvar(0) 1
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend myvar(b) a
+ return $::result
+} -result {myvar b r}
+test append-7.5 {append var does not trigger read trace} -setup {
+ unset -nocomplain myvar
+ unset -nocomplain ::result
+} -body {
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ append myvar a
+ info exists ::result
+} -result {0}
+
+# THERE ARE NO append-8.* TESTS
+
+# New tests for bug 3057639 to show off the more consistent behaviour of
+# lappend in both direct-eval and bytecompiled code paths (see appendComp.test
+# for the compiled variants). lappend now behaves like append. 9.0/1 lappend -
+# 9.2/3 append
+
+test append-9.0 {bug 3057639, lappend direct eval, read trace on non-existing array variable element} -setup {
+ unset -nocomplain myvar
+} -body {
+ array set myvar {}
+ proc nonull {var key val} {
+ upvar 1 $var lvar
+ if {![info exists lvar($key)]} {
+ return -code error "no such variable"
+ }
+ }
+ trace add variable myvar read nonull
+ list [catch {
+ lappend myvar(key) "new value"
+ } msg] $msg
+} -result {0 {{new value}}}
+test append-9.1 {bug 3057639, lappend direct eval, read trace on non-existing env element} -setup {
+ unset -nocomplain ::env(__DUMMY__)
+} -body {
+ list [catch {
+ lappend ::env(__DUMMY__) "new value"
+ } msg] $msg
+} -cleanup {
+ unset -nocomplain ::env(__DUMMY__)
+} -result {0 {{new value}}}
+test append-9.2 {bug 3057639, append direct eval, read trace on non-existing array variable element} -setup {
+ unset -nocomplain myvar
+} -body {
+ array set myvar {}
+ proc nonull {var key val} {
+ upvar 1 $var lvar
+ if {![info exists lvar($key)]} {
+ return -code error "no such variable"
+ }
+ }
+ trace add variable myvar read nonull
+ list [catch {
+ append myvar(key) "new value"
+ } msg] $msg
+} -result {0 {new value}}
+test append-9.3 {bug 3057639, append direct eval, read trace on non-existing env element} -setup {
+ unset -nocomplain ::env(__DUMMY__)
+} -body {
+ list [catch {
+ append ::env(__DUMMY__) "new value"
+ } msg] $msg
+} -cleanup {
+ unset -nocomplain ::env(__DUMMY__)
+} -result {0 {new value}}
+
+unset -nocomplain i x result y
+catch {rename foo ""}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/appendComp.test b/library/msgcat/tests/appendComp.test
new file mode 100644
index 0000000..f85c3ba
--- /dev/null
+++ b/library/msgcat/tests/appendComp.test
@@ -0,0 +1,455 @@
+# Commands covered: append lappend
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+catch {unset x}
+
+test appendComp-1.1 {append command} -setup {
+ unset -nocomplain x
+} -body {
+ proc foo {} {append ::x 1 2 abc "long string"}
+ list [foo] $x
+} -result {{12abclong string} {12abclong string}}
+test appendComp-1.2 {append command} {
+ proc foo {} {
+ set x ""
+ list [append x first] [append x second] [append x third] $x
+ }
+ foo
+} {first firstsecond firstsecondthird firstsecondthird}
+test appendComp-1.3 {append command} {
+ proc foo {} {
+ set x "abcd"
+ append x
+ }
+ foo
+} abcd
+
+test appendComp-2.1 {long appends} {
+ proc foo {} {
+ set x ""
+ for {set i 0} {$i < 1000} {set i [expr $i+1]} {
+ append x "foobar "
+ }
+ set y "foobar"
+ set y "$y $y $y $y $y $y $y $y $y $y"
+ set y "$y $y $y $y $y $y $y $y $y $y"
+ set y "$y $y $y $y $y $y $y $y $y $y "
+ expr {$x == $y}
+ }
+ foo
+} 1
+
+test appendComp-3.1 {append errors} -returnCodes error -body {
+ proc foo {} {append}
+ foo
+} -result {wrong # args: should be "append varName ?value ...?"}
+test appendComp-3.2 {append errors} -returnCodes error -body {
+ proc foo {} {
+ set x ""
+ append x(0) 44
+ }
+ foo
+} -result {can't set "x(0)": variable isn't array}
+test appendComp-3.3 {append errors} -returnCodes error -body {
+ proc foo {} {
+ unset -nocomplain x
+ append x
+ }
+ foo
+} -result {can't read "x": no such variable}
+
+test appendComp-4.1 {lappend command} {
+ proc foo {} {
+ global x
+ unset -nocomplain x
+ lappend x 1 2 abc "long string"
+ }
+ list [foo] $x
+} {{1 2 abc {long string}} {1 2 abc {long string}}}
+test appendComp-4.2 {lappend command} {
+ proc foo {} {
+ set x ""
+ list [lappend x first] [lappend x second] [lappend x third] $x
+ }
+ foo
+} {first {first second} {first second third} {first second third}}
+test appendComp-4.3 {lappend command} {
+ proc foo {} {
+ global x
+ set x old
+ unset x
+ lappend x new
+ }
+ set result [foo]
+ rename foo {}
+ set result
+} {new}
+test appendComp-4.4 {lappend command} {
+ proc foo {} {
+ set x {}
+ lappend x \{\ abc
+ }
+ foo
+} {\{\ abc}
+test appendComp-4.5 {lappend command} {
+ proc foo {} {
+ set x {}
+ lappend x \{ abc
+ }
+ foo
+} {\{ abc}
+test appendComp-4.6 {lappend command} {
+ proc foo {} {
+ set x {1 2 3}
+ lappend x
+ }
+ foo
+} {1 2 3}
+test appendComp-4.7 {lappend command} {
+ proc foo {} {
+ set x "a\{"
+ lappend x abc
+ }
+ foo
+} "a\\\{ abc"
+test appendComp-4.8 {lappend command} {
+ proc foo {} {
+ set x "\\\{"
+ lappend x abc
+ }
+ foo
+} "\\{ abc"
+test appendComp-4.9 {lappend command} -returnCodes error -body {
+ proc foo {} {
+ set x " \{"
+ lappend x abc
+ }
+ foo
+} -result {unmatched open brace in list}
+test appendComp-4.10 {lappend command} -returnCodes error -body {
+ proc foo {} {
+ set x " \{"
+ lappend x abc
+ }
+ foo
+} -result {unmatched open brace in list}
+test appendComp-4.11 {lappend command} -returnCodes error -body {
+ proc foo {} {
+ set x "\{\{\{"
+ lappend x abc
+ }
+ foo
+} -result {unmatched open brace in list}
+test appendComp-4.12 {lappend command} -returnCodes error -body {
+ proc foo {} {
+ set x "x \{\{\{"
+ lappend x abc
+ }
+ foo
+} -result {unmatched open brace in list}
+test appendComp-4.13 {lappend command} {
+ proc foo {} {
+ set x "x\{\{\{"
+ lappend x abc
+ }
+ foo
+} "x\\\{\\\{\\\{ abc"
+test appendComp-4.14 {lappend command} {
+ proc foo {} {
+ set x " "
+ lappend x abc
+ }
+ foo
+} "abc"
+test appendComp-4.15 {lappend command} {
+ proc foo {} {
+ set x "\\ "
+ lappend x abc
+ }
+ foo
+} "{ } abc"
+test appendComp-4.16 {lappend command} {
+ proc foo {} {
+ set x "x "
+ lappend x abc
+ }
+ foo
+} "x abc"
+test appendComp-4.17 {lappend command} {
+ proc foo {} { lappend x }
+ foo
+} {}
+test appendComp-4.18 {lappend command} {
+ proc foo {} { lappend x {} }
+ foo
+} {{}}
+test appendComp-4.19 {lappend command} {
+ proc foo {} { lappend x(0) }
+ foo
+} {}
+test appendComp-4.20 {lappend command} {
+ proc foo {} { lappend x(0) abc }
+ foo
+} {abc}
+
+test appendComp-5.1 {long lappends} -setup {
+ unset -nocomplain x
+ proc check {var size} {
+ set l [llength $var]
+ if {$l != $size} {
+ return "length mismatch: should have been $size, was $l"
+ }
+ for {set i 0} {$i < $size} {incr i} {
+ set j [lindex $var $i]
+ if {$j ne "item $i"} {
+ return "element $i should have been \"item $i\", was \"$j\""
+ }
+ }
+ return ok
+ }
+} -body {
+ set x ""
+ for {set i 0} {$i < 300} {set i [expr $i+1]} {
+ lappend x "item $i"
+ }
+ check $x 300
+} -cleanup {
+ unset -nocomplain x
+ catch {rename check ""}
+} -result ok
+
+test appendComp-6.1 {lappend errors} -returnCodes error -body {
+ proc foo {} {lappend}
+ foo
+} -result {wrong # args: should be "lappend varName ?value ...?"}
+test appendComp-6.2 {lappend errors} -returnCodes error -body {
+ proc foo {} {
+ set x ""
+ lappend x(0) 44
+ }
+ foo
+} -result {can't set "x(0)": variable isn't array}
+
+test appendComp-7.1 {lappendComp-created var and error in trace on that var} -setup {
+ catch {rename foo ""}
+ unset -nocomplain x
+} -body {
+ proc bar {} {
+ global x
+ trace variable x w foo
+ proc foo {} {global x; unset x}
+ catch {lappend x 1}
+ proc foo {args} {global x; unset x}
+ info exists x
+ set x
+ lappend x 1
+ list [info exists x] [catch {set x} msg] $msg
+ }
+ bar
+} -result {0 1 {can't read "x": no such variable}}
+test appendComp-7.2 {lappend var triggers read trace, index var} -setup {
+ unset -nocomplain ::result
+} -body {
+ proc bar {} {
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend myvar a
+ return $::result
+ }
+ bar
+} -result {myvar {} r} -constraints {bug-3057639}
+test appendComp-7.3 {lappend var triggers read trace, stack var} -setup {
+ unset -nocomplain ::result
+ unset -nocomplain ::myvar
+} -body {
+ proc bar {} {
+ trace variable ::myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend ::myvar a
+ return $::result
+ }
+ bar
+} -result {::myvar {} r} -constraints {bug-3057639}
+test appendComp-7.4 {lappend var triggers read trace, array var} -setup {
+ unset -nocomplain ::result
+} -body {
+ # The behavior of read triggers on lappend changed in 8.0 to not trigger
+ # them. Maybe not correct, but been there a while.
+ proc bar {} {
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend myvar(b) a
+ return $::result
+ }
+ bar
+} -result {myvar b r} -constraints {bug-3057639}
+test appendComp-7.5 {lappend var triggers read trace, array var} -setup {
+ unset -nocomplain ::result
+} -body {
+ # The behavior of read triggers on lappend changed in 8.0 to not trigger
+ # them. Maybe not correct, but been there a while.
+ proc bar {} {
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend myvar(b) a b
+ return $::result
+ }
+ bar
+} -result {myvar b r}
+test appendComp-7.6 {lappend var triggers read trace, array var exists} -setup {
+ unset -nocomplain ::result
+} -body {
+ proc bar {} {
+ set myvar(0) 1
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend myvar(b) a
+ return $::result
+ }
+ bar
+} -result {myvar b r} -constraints {bug-3057639}
+test appendComp-7.7 {lappend var triggers read trace, array stack var} -setup {
+ unset -nocomplain ::myvar
+ unset -nocomplain ::result
+} -body {
+ proc bar {} {
+ trace variable ::myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend ::myvar(b) a
+ return $::result
+ }
+ bar
+} -result {::myvar b r} -constraints {bug-3057639}
+test appendComp-7.8 {lappend var triggers read trace, array stack var} -setup {
+ unset -nocomplain ::myvar
+ unset -nocomplain ::result
+} -body {
+ proc bar {} {
+ trace variable ::myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend ::myvar(b) a b
+ return $::result
+ }
+ bar
+} -result {::myvar b r}
+test appendComp-7.9 {append var does not trigger read trace} -setup {
+ unset -nocomplain ::result
+} -body {
+ proc bar {} {
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ append myvar a
+ info exists ::result
+ }
+ bar
+} -result {0}
+
+test appendComp-8.1 {defer error to runtime} -setup {
+ interp create slave
+} -body {
+ slave eval {
+ proc foo {} {
+ proc append args {}
+ append
+ }
+ foo
+ }
+} -cleanup {
+ interp delete slave
+} -result {}
+
+# New tests for bug 3057639 to show off the more consistent behaviour of
+# lappend in both direct-eval and bytecompiled code paths (see append.test for
+# the direct-eval variants). lappend now behaves like append. 9.0/1 lappend -
+# 9.2/3 append.
+
+# Note also the tests above now constrained by bug-3057639, these changed
+# behaviour with the triggering of read traces in bc mode gone.
+
+# Going back to the tests below. The direct-eval tests are ok before and after
+# patch (no read traces run for lappend, append). The compiled tests are
+# failing for lappend (9.0/1) before the patch, showing how it invokes read
+# traces in the compiled path. The append tests are good (9.2/3). After the
+# patch the failues are gone.
+
+test appendComp-9.0 {bug 3057639, lappend compiled, read trace on non-existing array variable element} -setup {
+ unset -nocomplain myvar
+ array set myvar {}
+} -body {
+ proc nonull {var key val} {
+ upvar 1 $var lvar
+ if {![info exists lvar($key)]} {
+ return -code error "BOOM. no such variable"
+ }
+ }
+ trace add variable myvar read nonull
+ proc foo {} {
+ lappend ::myvar(key) "new value"
+ }
+ list [catch { foo } msg] $msg
+} -result {0 {{new value}}}
+test appendComp-9.1 {bug 3057639, lappend direct eval, read trace on non-existing env element} -setup {
+ unset -nocomplain ::env(__DUMMY__)
+} -body {
+ proc foo {} {
+ lappend ::env(__DUMMY__) "new value"
+ }
+ list [catch { foo } msg] $msg
+} -cleanup {
+ unset -nocomplain ::env(__DUMMY__)
+} -result {0 {{new value}}}
+test appendComp-9.2 {bug 3057639, append compiled, read trace on non-existing array variable element} -setup {
+ unset -nocomplain myvar
+ array set myvar {}
+} -body {
+ proc nonull {var key val} {
+ upvar 1 $var lvar
+ if {![info exists lvar($key)]} {
+ return -code error "BOOM. no such variable"
+ }
+ }
+ trace add variable myvar read nonull
+ proc foo {} {
+ append ::myvar(key) "new value"
+ }
+ list [catch { foo } msg] $msg
+} -result {0 {new value}}
+test appendComp-9.3 {bug 3057639, append direct eval, read trace on non-existing env element} -setup {
+ unset -nocomplain ::env(__DUMMY__)
+} -body {
+ proc foo {} {
+ append ::env(__DUMMY__) "new value"
+ }
+ list [catch { foo } msg] $msg
+} -cleanup {
+ unset -nocomplain ::env(__DUMMY__)
+} -result {0 {new value}}
+
+catch {unset i x result y}
+catch {rename foo ""}
+catch {rename bar ""}
+catch {rename check ""}
+catch {rename bar {}}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/apply.test b/library/msgcat/tests/apply.test
new file mode 100644
index 0000000..ba19b81
--- /dev/null
+++ b/library/msgcat/tests/apply.test
@@ -0,0 +1,321 @@
+# Commands covered: apply
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2005-2006 Miguel Sofer
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2.2
+ namespace import -force ::tcltest::*
+}
+
+if {[info commands ::apply] eq {}} {
+ return
+}
+
+testConstraint memory [llength [info commands memory]]
+
+# Tests for wrong number of arguments
+
+test apply-1.1 {too few arguments} -returnCodes error -body {
+ apply
+} -result {wrong # args: should be "apply lambdaExpr ?arg ...?"}
+
+# Tests for malformed lambda
+
+test apply-2.0 {malformed lambda} -returnCodes error -body {
+ set lambda a
+ apply $lambda
+} -result {can't interpret "a" as a lambda expression}
+test apply-2.1 {malformed lambda} -returnCodes error -body {
+ set lambda [list a b c d]
+ apply $lambda
+} -result {can't interpret "a b c d" as a lambda expression}
+test apply-2.2 {malformed lambda} {
+ set lambda [list {{}} boo]
+ list [catch {apply $lambda} msg] $msg $::errorInfo
+} {1 {argument with no name} {argument with no name
+ (parsing lambda expression "{{}} boo")
+ invoked from within
+"apply $lambda"}}
+test apply-2.3 {malformed lambda} {
+ set lambda [list {{a b c}} boo]
+ list [catch {apply $lambda} msg] $msg $::errorInfo
+} {1 {too many fields in argument specifier "a b c"} {too many fields in argument specifier "a b c"
+ (parsing lambda expression "{{a b c}} boo")
+ invoked from within
+"apply $lambda"}}
+test apply-2.4 {malformed lambda} {
+ set lambda [list a(1) boo]
+ list [catch {apply $lambda} msg] $msg $::errorInfo
+} {1 {formal parameter "a(1)" is an array element} {formal parameter "a(1)" is an array element
+ (parsing lambda expression "a(1) boo")
+ invoked from within
+"apply $lambda"}}
+test apply-2.5 {malformed lambda} {
+ set lambda [list a::b boo]
+ list [catch {apply $lambda} msg] $msg $::errorInfo
+} {1 {formal parameter "a::b" is not a simple name} {formal parameter "a::b" is not a simple name
+ (parsing lambda expression "a::b boo")
+ invoked from within
+"apply $lambda"}}
+
+# Tests for runtime errors in the lambda expression
+
+test apply-3.1 {non-existing namespace} -body {
+ apply [list x {set x 1} ::NONEXIST::FOR::SURE] x
+} -returnCodes error -result {namespace "::NONEXIST::FOR::SURE" not found}
+test apply-3.2 {non-existing namespace} -body {
+ namespace eval ::NONEXIST::FOR::SURE {}
+ set lambda [list x {set x 1} ::NONEXIST::FOR::SURE]
+ apply $lambda x
+ namespace delete ::NONEXIST
+ apply $lambda x
+} -returnCodes error -result {namespace "::NONEXIST::FOR::SURE" not found}
+test apply-3.3 {non-existing namespace} -body {
+ apply [list x {set x 1} NONEXIST::FOR::SURE] x
+} -returnCodes error -result {namespace "::NONEXIST::FOR::SURE" not found}
+test apply-3.4 {non-existing namespace} -body {
+ namespace eval ::NONEXIST::FOR::SURE {}
+ set lambda [list x {set x 1} NONEXIST::FOR::SURE]
+ apply $lambda x
+ namespace delete ::NONEXIST
+ apply $lambda x
+} -returnCodes error -result {namespace "::NONEXIST::FOR::SURE" not found}
+
+test apply-4.1 {error in arguments to lambda expression} -body {
+ set lambda [list x {set x 1}]
+ apply $lambda
+} -returnCodes error -result {wrong # args: should be "apply lambdaExpr x"}
+test apply-4.2 {error in arguments to lambda expression} -body {
+ set lambda [list x {set x 1}]
+ apply $lambda a b
+} -returnCodes error -result {wrong # args: should be "apply lambdaExpr x"}
+test apply-4.3 {error in arguments to lambda expression} -body {
+ interp alias {} foo {} ::apply [list x {set x 1}]
+ foo a b
+} -cleanup {
+ rename foo {}
+} -returnCodes error -result {wrong # args: should be "foo x"}
+test apply-4.4 {error in arguments to lambda expression} -body {
+ interp alias {} foo {} ::apply [list x {set x 1}] a
+ foo b
+} -cleanup {
+ rename foo {}
+} -returnCodes error -result {wrong # args: should be "foo"}
+test apply-4.5 {error in arguments to lambda expression} -body {
+ set lambda [list x {set x 1}]
+ namespace eval a {
+ namespace ensemble create -command ::bar -map {id {::a::const foo}}
+ proc const val { return $val }
+ proc alias {object slot = command args} {
+ set map [namespace ensemble configure $object -map]
+ dict set map $slot [linsert $args 0 $command]
+ namespace ensemble configure $object -map $map
+ }
+ proc method {object name params body} {
+ set params [linsert $params 0 self]
+ alias $object $name = ::apply [list $params $body] $object
+ }
+ method ::bar boo x {return "[expr {$x*$x}] - $self"}
+ }
+ bar boo
+} -cleanup {
+ namespace delete ::a
+} -returnCodes error -result {wrong # args: should be "bar boo x"}
+
+test apply-5.1 {runtime error in lambda expression} {
+ set lambda [list {} {error foo}]
+ set res [catch {apply $lambda}]
+ list $res $::errorInfo
+} {1 {foo
+ while executing
+"error foo"
+ (lambda term "{} {error foo}" line 1)
+ invoked from within
+"apply $lambda"}}
+
+# Tests for correct execution; as the implementation is the same as that for
+# procs, the general functionality is mostly tested elsewhere
+
+test apply-6.1 {info level} {
+ set lev [info level]
+ set lambda [list {} {info level}]
+ expr {[apply $lambda] - $lev}
+} 1
+test apply-6.2 {info level} {
+ set lambda [list {} {info level 0}]
+ apply $lambda
+} {apply {{} {info level 0}}}
+test apply-6.3 {info level} {
+ set lambda [list args {info level 0}]
+ apply $lambda x y
+} {apply {args {info level 0}} x y}
+
+# Tests for correct namespace scope
+
+namespace eval ::testApply {
+ proc testApply args {return testApply}
+}
+
+test apply-7.1 {namespace access} {
+ set ::testApply::x 0
+ set body {set x 1; set x}
+ list [apply [list args $body ::testApply]] $::testApply::x
+} {1 0}
+test apply-7.2 {namespace access} {
+ set ::testApply::x 0
+ set body {variable x; set x}
+ list [apply [list args $body ::testApply]] $::testApply::x
+} {0 0}
+test apply-7.3 {namespace access} {
+ set ::testApply::x 0
+ set body {variable x; set x 1}
+ list [apply [list args $body ::testApply]] $::testApply::x
+} {1 1}
+test apply-7.4 {namespace access} {
+ set ::testApply::x 0
+ set body {testApply}
+ apply [list args $body ::testApply]
+} testApply
+test apply-7.5 {namespace access} {
+ set ::testApply::x 0
+ set body {set x 1; set x}
+ list [apply [list args $body testApply]] $::testApply::x
+} {1 0}
+test apply-7.6 {namespace access} {
+ set ::testApply::x 0
+ set body {variable x; set x}
+ list [apply [list args $body testApply]] $::testApply::x
+} {0 0}
+test apply-7.7 {namespace access} {
+ set ::testApply::x 0
+ set body {variable x; set x 1}
+ list [apply [list args $body testApply]] $::testApply::x
+} {1 1}
+test apply-7.8 {namespace access} {
+ set ::testApply::x 0
+ set body {testApply}
+ apply [list args $body testApply]
+} testApply
+
+# Tests for correct argument treatment
+
+set applyBody {
+ set res {}
+ foreach v [info locals] {
+ if {$v eq "res"} continue
+ lappend res [list $v [set $v]]
+ }
+ set res
+}
+
+test apply-8.1 {args treatment} {
+ apply [list args $applyBody] 1 2 3
+} {{args {1 2 3}}}
+test apply-8.2 {args treatment} {
+ apply [list {x args} $applyBody] 1 2
+} {{x 1} {args 2}}
+test apply-8.3 {args treatment} {
+ apply [list {x args} $applyBody] 1 2 3
+} {{x 1} {args {2 3}}}
+test apply-8.4 {default values} {
+ apply [list {{x 1} {y 2}} $applyBody]
+} {{x 1} {y 2}}
+test apply-8.5 {default values} {
+ apply [list {{x 1} {y 2}} $applyBody] 3 4
+} {{x 3} {y 4}}
+test apply-8.6 {default values} {
+ apply [list {{x 1} {y 2}} $applyBody] 3
+} {{x 3} {y 2}}
+test apply-8.7 {default values} {
+ apply [list {x {y 2}} $applyBody] 1
+} {{x 1} {y 2}}
+test apply-8.8 {default values} {
+ apply [list {x {y 2}} $applyBody] 1 3
+} {{x 1} {y 3}}
+test apply-8.9 {default values} {
+ apply [list {x {y 2} args} $applyBody] 1
+} {{x 1} {y 2} {args {}}}
+test apply-8.10 {default values} {
+ apply [list {x {y 2} args} $applyBody] 1 3
+} {{x 1} {y 3} {args {}}}
+
+# Tests for leaks
+
+test apply-9.1 {leaking internal rep} -setup {
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex $lines 3 3
+ }
+ set lam [list {} {set a 1}]
+} -constraints memory -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ ::apply [lrange $lam 0 end]
+ set tmp $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+ rename getbytes {}
+ unset -nocomplain lam end i tmp leakedBytes
+} -result 0
+test apply-9.2 {leaking internal rep} -setup {
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex $lines 3 3
+ }
+} -constraints memory -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ ::apply [list {} {set a 1}]
+ set tmp $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+ rename getbytes {}
+ unset -nocomplain end i tmp leakedBytes
+} -result 0
+test apply-9.3 {leaking internal rep} -setup {
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex $lines 3 3
+ }
+} -constraints memory -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ set x [list {} {set a 1} ::NS::THAT::DOES::NOT::EXIST]
+ catch {::apply $x}
+ set x {}
+ set tmp $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+ rename getbytes {}
+ unset -nocomplain end i x tmp leakedBytes
+} -result 0
+
+# Tests for the avoidance of recompilation
+
+# cleanup
+
+namespace delete testApply
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/assemble.test b/library/msgcat/tests/assemble.test
new file mode 100644
index 0000000..7d4e5d1
--- /dev/null
+++ b/library/msgcat/tests/assemble.test
@@ -0,0 +1,3293 @@
+# assemble.test --
+#
+# Test suite for the 'tcl::unsupported::assemble' command
+#
+# Copyright (c) 2010 by Ozgur Dogan Ugurlu.
+# Copyright (c) 2010 by Kevin B. Kenny.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#-----------------------------------------------------------------------------
+
+# Commands covered: assemble
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2.2
+ namespace import -force ::tcltest::*
+}
+namespace eval tcl::unsupported {namespace export assemble}
+namespace import tcl::unsupported::assemble
+
+# Procedure to make code that fills the literal and local variable tables, to
+# force instructions to spill to four bytes.
+
+proc fillTables {} {
+ set s {}
+ set sep {}
+ for {set i 0} {$i < 256} {incr i} {
+ append s $sep [list set v$i literal$i]
+ set sep \n
+ }
+ return $s
+}
+
+testConstraint memory [llength [info commands memory]]
+if {[testConstraint memory]} {
+ proc getbytes {} {
+ set lines [split [memory info] \n]
+ return [lindex $lines 3 3]
+ }
+ proc leaktest {script {iterations 3}} {
+ set end [getbytes]
+ for {set i 0} {$i < $iterations} {incr i} {
+ uplevel 1 $script
+ set tmp $end
+ set end [getbytes]
+ }
+ return [expr {$end - $tmp}]
+ }
+}
+
+# assemble-1 - TclNRAssembleObjCmd
+
+test assemble-1.1 {wrong # args, direct eval} {
+ -body {
+ eval [list assemble]
+ }
+ -returnCodes error
+ -result {wrong # args*}
+ -match glob
+}
+test assemble-1.2 {wrong # args, direct eval} {
+ -body {
+ eval [list assemble too many]
+ }
+ -returnCodes error
+ -result {wrong # args*}
+ -match glob
+}
+test assemble-1.3 {error reporting, direct eval} {
+ -body {
+ list [catch {
+ eval [list assemble {
+ # bad opcode
+ rubbish
+ }]
+ } result] $result $errorInfo
+ }
+ -match glob
+ -result {1 {bad instruction "rubbish":*} {bad instruction "rubbish":*
+ while executing
+"rubbish"
+ ("assemble" body, line 3)*}}
+ -cleanup {unset result}
+}
+test assemble-1.4 {simple direct eval} {
+ -body {
+ eval [list assemble {push {this is a test}}]
+ }
+ -result {this is a test}
+}
+
+# assemble-2 - CompileAssembleObj
+
+test assemble-2.1 {bytecode reuse, direct eval} {
+ -body {
+ set x {push "this is a test"}
+ list [eval [list assemble $x]] \
+ [eval [list assemble $x]]
+ }
+ -result {{this is a test} {this is a test}}
+}
+test assemble-2.2 {bytecode discard, direct eval} {
+ -body {
+ set x {load value}
+ proc p1 {x} {
+ set value value1
+ assemble $x
+ }
+ proc p2 {x} {
+ set a b
+ set value value2
+ assemble $x
+ }
+ list [p1 $x] [p2 $x]
+ }
+ -result {value1 value2}
+ -cleanup {
+ unset x
+ rename p1 {}
+ rename p2 {}
+ }
+}
+test assemble-2.3 {null script, direct eval} {
+ -body {
+ set x {}
+ assemble $x
+ }
+ -result {}
+ -cleanup {unset x}
+}
+
+# assemble-3 - TclCompileAssembleCmd
+
+test assemble-3.1 {wrong # args, compiled path} {
+ -body {
+ proc x {} {
+ assemble
+ }
+ x
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args:*}
+}
+test assemble-3.2 {wrong # args, compiled path} {
+ -body {
+ proc x {} {
+ assemble too many
+ }
+ x
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args:*}
+ -cleanup {
+ rename x {}
+ }
+}
+
+# assemble-4 - TclAssembleCode mainline
+
+test assemble-4.1 {syntax error} {
+ -body {
+ proc x {} {
+ assemble {
+ {}extra
+ }
+ }
+ list [catch x result] $result $::errorInfo
+ }
+ -cleanup {
+ rename x {}
+ unset result
+ }
+ -match glob
+ -result {1 {extra characters after close-brace} {extra characters after close-brace
+ while executing
+"{}extra
+ "
+ ("assemble" body, line 2)*}}
+}
+test assemble-4.2 {null command} {
+ -body {
+ proc x {} {
+ assemble {
+ push hello; pop;;push goodbye
+ }
+ }
+ x
+ }
+ -result goodbye
+ -cleanup {
+ rename x {}
+ }
+}
+
+# assemble-5 - GetNextOperand off-nominal cases
+
+test assemble-5.1 {unsupported expansion} {
+ -body {
+ proc x {y} {
+ assemble {
+ {*}$y
+ }
+ }
+ list [catch {x {push hello}} result] $result $::errorCode
+ }
+ -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+ -cleanup {
+ rename x {}
+ unset result
+ }
+}
+test assemble-5.2 {unsupported substitution} {
+ -body {
+ proc x {y} {
+ assemble {
+ $y
+ }
+ }
+ list [catch {x {nop}} result] $result $::errorCode
+ }
+ -cleanup {
+ rename x {}
+ unset result
+ }
+ -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+}
+test assemble-5.3 {unsupported substitution} {
+ -body {
+ proc x {} {
+ assemble {
+ [x]
+ }
+ }
+ list [catch {x} result] $result $::errorCode
+ }
+ -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+}
+test assemble-5.4 {backslash substitution} {
+ -body {
+ proc x {} {
+ assemble {
+ p\x75sh\
+ hello\ world
+ }
+ }
+ x
+ }
+ -cleanup {
+ rename x {}
+ }
+ -result {hello world}
+}
+
+# assemble-6 - ASSEM_PUSH
+
+test assemble-6.1 {push, wrong # args} {
+ -body {
+ assemble push
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-6.2 {push, wrong # args} {
+ -body {
+ assemble {push too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-6.3 {push} {
+ -body {
+ eval [list assemble {push hello}]
+ }
+ -result hello
+}
+test assemble-6.4 {push4} {
+ -body {
+ proc x {} "
+ [fillTables]
+ assemble {push hello}
+ "
+ x
+ }
+ -cleanup {
+ rename x {}
+ }
+ -result hello
+}
+
+# assemble-7 - ASSEM_1BYTE
+
+test assemble-7.1 {add, wrong # args} {
+ -body {
+ assemble {add excess}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-7.2 {add} {
+ -body {
+ assemble {
+ push 2
+ push 2
+ add
+ }
+ }
+ -result {4}
+}
+test assemble-7.3 {appendArrayStk} {
+ -body {
+ set a(b) {hello, }
+ assemble {
+ push a
+ push b
+ push world
+ appendArrayStk
+ }
+ set a(b)
+ }
+ -result {hello, world}
+ -cleanup {unset a}
+}
+test assemble-7.4 {appendStk} {
+ -body {
+ set a {hello, }
+ assemble {
+ push a
+ push world
+ appendStk
+ }
+ set a
+ }
+ -result {hello, world}
+ -cleanup {unset a}
+}
+test assemble-7.5 {bitwise ops} {
+ -body {
+ list \
+ [assemble {push 0b1100; push 0b1010; bitand}] \
+ [assemble {push 0b1100; bitnot}] \
+ [assemble {push 0b1100; push 0b1010; bitor}] \
+ [assemble {push 0b1100; push 0b1010; bitxor}]
+ }
+ -result {8 -13 14 6}
+}
+test assemble-7.6 {div} {
+ -body {
+ assemble {push 999999; push 7; div}
+ }
+ -result 142857
+}
+test assemble-7.7 {dup} {
+ -body {
+ assemble {
+ push 1; dup; dup; add; dup; add; dup; add; add
+ }
+ }
+ -result 9
+}
+test assemble-7.8 {eq} {
+ -body {
+ list \
+ [assemble {push able; push baker; eq}] \
+ [assemble {push able; push able; eq}]
+ }
+ -result {0 1}
+}
+test assemble-7.9 {evalStk} {
+ -body {
+ assemble {
+ push {concat test 7.3}
+ evalStk
+ }
+ }
+ -result {test 7.3}
+}
+test assemble-7.9a {evalStk, syntax} {
+ -body {
+ assemble {
+ push {{}bad}
+ evalStk
+ }
+ }
+ -returnCodes error
+ -result {extra characters after close-brace}
+}
+test assemble-7.9b {evalStk, backtrace} {
+ -body {
+ proc y {z} {
+ error testing
+ }
+ proc x {} {
+ assemble {
+ push {
+ # test error in evalStk
+ y asd
+ }
+ evalStk
+ }
+ }
+ list [catch x result] $result $errorInfo
+ }
+ -result {1 testing {testing
+ while executing
+"error testing"
+ (procedure "y" line 2)
+ invoked from within
+"y asd"*}}
+ -match glob
+ -cleanup {
+ rename y {}
+ rename x {}
+ }
+}
+test assemble-7.10 {existArrayStk} {
+ -body {
+ proc x {name key} {
+ set a(b) c
+ assemble {
+ load name; load key; existArrayStk
+ }
+ }
+ list [x a a] [x a b] [x b a] [x b b]
+ }
+ -result {0 1 0 0}
+ -cleanup {rename x {}}
+}
+test assemble-7.11 {existStk} {
+ -body {
+ proc x {name} {
+ set a b
+ assemble {
+ load name; existStk
+ }
+ }
+ list [x a] [x b]
+ }
+ -result {1 0}
+ -cleanup {rename x {}}
+}
+test assemble-7.12 {expon} {
+ -body {
+ assemble {push 3; push 4; expon}
+ }
+ -result 81
+}
+test assemble-7.13 {exprStk} {
+ -body {
+ assemble {
+ push {acos(-1)}
+ exprStk
+ }
+ }
+ -result 3.141592653589793
+}
+test assemble-7.13a {exprStk, syntax} {
+ -body {
+ assemble {
+ push {2+}
+ exprStk
+ }
+ }
+ -returnCodes error
+ -result {missing operand at _@_
+in expression "2+_@_"}
+}
+test assemble-7.13b {exprStk, backtrace} {
+ -body {
+ proc y {z} {
+ error testing
+ }
+ proc x {} {
+ assemble {
+ push {[y asd]}
+ exprStk
+ }
+ }
+ list [catch x result] $result $errorInfo
+ }
+ -result {1 testing {testing
+ while executing
+"error testing"
+ (procedure "y" line 2)
+ invoked from within
+"y asd"*}}
+ -match glob
+ -cleanup {
+ rename y {}
+ rename x {}
+ }
+}
+test assemble-7.14 {ge gt le lt} {
+ -body {
+ proc x {a b} {
+ list [assemble {load a; load b; ge}] \
+ [assemble {load a; load b; gt}] \
+ [assemble {load a; load b; le}] \
+ [assemble {load a; load b; lt}]
+ }
+ list [x 0 0] [x 0 1] [x 1 0]
+ }
+ -result {{1 0 1 0} {0 0 1 1} {1 1 0 0}}
+ -cleanup {rename x {}}
+}
+test assemble-7.15 {incrArrayStk} {
+ -body {
+ proc x {} {
+ set a(b) 5
+ assemble {
+ push a; push b; push 7; incrArrayStk
+ }
+ }
+ x
+ }
+ -result 12
+ -cleanup {rename x {}}
+}
+test assemble-7.16 {incrStk} {
+ -body {
+ proc x {} {
+ set a 5
+ assemble {
+ push a; push 7; incrStk
+ }
+ }
+ x
+ }
+ -result 12
+ -cleanup {rename x {}}
+}
+test assemble-7.17 {land/lor} {
+ -body {
+ proc x {a b} {
+ list \
+ [assemble {load a; load b; land}] \
+ [assemble {load a; load b; lor}]
+ }
+ list [x 0 0] [x 0 23] [x 35 0] [x 47 59]
+ }
+ -result {{0 0} {0 1} {0 1} {1 1}}
+ -cleanup {rename x {}}
+}
+test assemble-7.18 {lappendArrayStk} {
+ -body {
+ proc x {} {
+ set able(baker) charlie
+ assemble {
+ push able
+ push baker
+ push dog
+ lappendArrayStk
+ }
+ }
+ x
+ }
+ -result {charlie dog}
+ -cleanup {rename x {}}
+}
+test assemble-7.19 {lappendStk} {
+ -body {
+ proc x {} {
+ set able baker
+ assemble {
+ push able
+ push charlie
+ lappendStk
+ }
+ }
+ x
+ }
+ -result {baker charlie}
+ -cleanup {rename x {}}
+}
+test assemble-7.20 {listIndex} {
+ -body {
+ assemble {
+ push {a b c d}
+ push 2
+ listIndex
+ }
+ }
+ -result c
+}
+test assemble-7.21 {listLength} {
+ -body {
+ assemble {
+ push {a b c d}
+ listLength
+ }
+ }
+ -result 4
+}
+test assemble-7.22 {loadArrayStk} {
+ -body {
+ proc x {} {
+ set able(baker) charlie
+ assemble {
+ push able
+ push baker
+ loadArrayStk
+ }
+ }
+ x
+ }
+ -result charlie
+ -cleanup {rename x {}}
+}
+test assemble-7.23 {loadStk} {
+ -body {
+ proc x {} {
+ set able baker
+ assemble {
+ push able
+ loadStk
+ }
+ }
+ x
+ }
+ -result baker
+ -cleanup {rename x {}}
+}
+test assemble-7.24 {lsetList} {
+ -body {
+ proc x {} {
+ set l {{a b} {c d} {e f} {g h}}
+ assemble {
+ push {2 1}; push i; load l; lsetList
+ }
+ }
+ x
+ }
+ -result {{a b} {c d} {e i} {g h}}
+}
+test assemble-7.25 {lshift} {
+ -body {
+ assemble {push 16; push 4; lshift}
+ }
+ -result 256
+}
+test assemble-7.26 {mod} {
+ -body {
+ assemble {push 123456; push 1000; mod}
+ }
+ -result 456
+}
+test assemble-7.27 {mult} {
+ -body {
+ assemble {push 12345679; push 9; mult}
+ }
+ -result 111111111
+}
+test assemble-7.28 {neq} {
+ -body {
+ list \
+ [assemble {push able; push baker; neq}] \
+ [assemble {push able; push able; neq}]
+ }
+ -result {1 0}
+}
+test assemble-7.29 {not} {
+ -body {
+ list \
+ [assemble {push 17; not}] \
+ [assemble {push 0; not}]
+ }
+ -result {0 1}
+}
+test assemble-7.30 {pop} {
+ -body {
+ assemble {push this; pop; push that}
+ }
+ -result that
+}
+test assemble-7.31 {rshift} {
+ -body {
+ assemble {push 257; push 4; rshift}
+ }
+ -result 16
+}
+test assemble-7.32 {storeArrayStk} {
+ -body {
+ proc x {} {
+ assemble {
+ push able; push baker; push charlie; storeArrayStk
+ }
+ array get able
+ }
+ x
+ }
+ -result {baker charlie}
+ -cleanup {rename x {}}
+}
+test assemble-7.33 {storeStk} {
+ -body {
+ proc x {} {
+ assemble {
+ push able; push baker; storeStk
+ }
+ set able
+ }
+ x
+ }
+ -result {baker}
+ -cleanup {rename x {}}
+}
+test assemble-7,34 {strcmp} {
+ -body {
+ proc x {a b} {
+ assemble {
+ load a; load b; strcmp
+ }
+ }
+ list [x able baker] [x baker able] [x baker baker]
+ }
+ -result {-1 1 0}
+ -cleanup {rename x {}}
+}
+test assemble-7.35 {streq/strneq} {
+ -body {
+ proc x {a b} {
+ list \
+ [assemble {load a; load b; streq}] \
+ [assemble {load a; load b; strneq}]
+ }
+ list [x able able] [x able baker]
+ }
+ -result {{1 0} {0 1}}
+ -cleanup {rename x {}}
+}
+test assemble-7.36 {strindex} {
+ -body {
+ assemble {push testing; push 4; strindex}
+ }
+ -result i
+}
+test assemble-7.37 {strlen} {
+ -body {
+ assemble {push testing; strlen}
+ }
+ -result 7
+}
+test assemble-7.38 {sub} {
+ -body {
+ assemble {push 42; push 17; sub}
+ }
+ -result 25
+}
+test assemble-7.39 {tryCvtToNumeric} {
+ -body {
+ assemble {
+ push 42; tryCvtToNumeric
+ }
+ }
+ -result 42
+}
+# assemble-7.40 absent
+test assemble-7.41 {uminus} {
+ -body {
+ assemble {
+ push 42; uminus
+ }
+ }
+ -result -42
+}
+test assemble-7.42 {uplus} {
+ -body {
+ assemble {
+ push 42; uplus
+ }
+ }
+ -result 42
+}
+test assemble-7.43 {uplus} {
+ -body {
+ assemble {
+ push NaN; uplus
+ }
+ }
+ -returnCodes error
+ -result {can't use non-numeric floating-point value as operand of "+"}
+}
+test assemble-7.43.1 {tryCvtToNumeric} {
+ -body {
+ assemble {
+ push NaN; tryCvtToNumeric
+ }
+ }
+ -returnCodes error
+ -result {domain error: argument not in valid range}
+}
+test assemble-7.44 {listIn} {
+ -body {
+ assemble {
+ push b; push {a b c}; listIn
+ }
+ }
+ -result 1
+}
+test assemble-7.45 {listNotIn} {
+ -body {
+ assemble {
+ push d; push {a b c}; listNotIn
+ }
+ }
+ -result 1
+}
+test assemble-7.46 {nop} {
+ -body {
+ assemble { push x; nop; nop; nop}
+ }
+ -result x
+}
+
+# assemble-8 ASSEM_LVT and FindLocalVar
+
+test assemble-8.1 {load, wrong # args} {
+ -body {
+ assemble load
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-8.2 {load, wrong # args} {
+ -body {
+ assemble {load too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-8.3 {nonlocal var} {
+ -body {
+ list [catch {assemble {load ::env}} result] $result $errorCode
+ }
+ -result {1 {variable "::env" is not local} {TCL ASSEM NONLOCAL ::env}}
+ -cleanup {unset result}
+}
+test assemble-8.4 {bad context} {
+ -body {
+ set x 1
+ list [catch {assemble {load x}} result] $result $errorCode
+ }
+ -result {1 {cannot use this instruction to create a variable in a non-proc context} {TCL ASSEM LVT}}
+ -cleanup {unset result}
+}
+test assemble-8.5 {bad context} {
+ -body {
+ namespace eval assem {
+ set x 1
+ list [catch {assemble {load x}} result] $result $errorCode
+ }
+ }
+ -result {1 {cannot use this instruction to create a variable in a non-proc context} {TCL ASSEM LVT}}
+ -cleanup {namespace delete assem}
+}
+test assemble-8.6 {load1} {
+ -body {
+ proc x {a} {
+ assemble {
+ load a
+ }
+ }
+ x able
+ }
+ -result able
+ -cleanup {rename x {}}
+}
+test assemble-8.7 {load4} {
+ -body {
+ proc x {a} "
+ [fillTables]
+ set b \$a
+ assemble {load b}
+ "
+ x able
+ }
+ -result able
+ -cleanup {rename x {}}
+}
+test assemble-8.8 {loadArray1} {
+ -body {
+ proc x {} {
+ set able(baker) charlie
+ assemble {
+ push baker
+ loadArray able
+ }
+ }
+ x
+ }
+ -result charlie
+ -cleanup {rename x {}}
+}
+test assemble-8.9 {loadArray4} {
+ -body "
+ proc x {} {
+ [fillTables]
+ set able(baker) charlie
+ assemble {
+ push baker
+ loadArray able
+ }
+ }
+ x
+ "
+ -result charlie
+ -cleanup {rename x {}}
+}
+test assemble-8.10 {append1} {
+ -body {
+ proc x {} {
+ set y {hello, }
+ assemble {
+ push world; append y
+ }
+ }
+ x
+ }
+ -result {hello, world}
+ -cleanup {rename x {}}
+}
+test assemble-8.11 {append4} {
+ -body {
+ proc x {} "
+ [fillTables]
+ set y {hello, }
+ assemble {
+ push world; append y
+ }
+ "
+ x
+ }
+ -result {hello, world}
+ -cleanup {rename x {}}
+}
+test assemble-8.12 {appendArray1} {
+ -body {
+ proc x {} {
+ set y(z) {hello, }
+ assemble {
+ push z; push world; appendArray y
+ }
+ }
+ x
+ }
+ -result {hello, world}
+ -cleanup {rename x {}}
+}
+test assemble-8.13 {appendArray4} {
+ -body {
+ proc x {} "
+ [fillTables]
+ set y(z) {hello, }
+ assemble {
+ push z; push world; appendArray y
+ }
+ "
+ x
+ }
+ -result {hello, world}
+ -cleanup {rename x {}}
+}
+test assemble-8.14 {lappend1} {
+ -body {
+ proc x {} {
+ set y {hello,}
+ assemble {
+ push world; lappend y
+ }
+ }
+ x
+ }
+ -result {hello, world}
+ -cleanup {rename x {}}
+}
+test assemble-8.15 {lappend4} {
+ -body {
+ proc x {} "
+ [fillTables]
+ set y {hello,}
+ assemble {
+ push world; lappend y
+ }
+ "
+ x
+ }
+ -result {hello, world}
+ -cleanup {rename x {}}
+}
+test assemble-8.16 {lappendArray1} {
+ -body {
+ proc x {} {
+ set y(z) {hello,}
+ assemble {
+ push z; push world; lappendArray y
+ }
+ }
+ x
+ }
+ -result {hello, world}
+ -cleanup {rename x {}}
+}
+test assemble-8.17 {lappendArray4} {
+ -body {
+ proc x {} "
+ [fillTables]
+ set y(z) {hello,}
+ assemble {
+ push z; push world; lappendArray y
+ }
+ "
+ x
+ }
+ -result {hello, world}
+ -cleanup {rename x {}}
+}
+test assemble-8.18 {store1} {
+ -body {
+ proc x {} {
+ assemble {
+ push test; store y
+ }
+ set y
+ }
+ x
+ }
+ -result {test}
+ -cleanup {rename x {}}
+}
+test assemble-8.19 {store4} {
+ -body {
+ proc x {} "
+ [fillTables]
+ assemble {
+ push test; store y
+ }
+ set y
+ "
+ x
+ }
+ -result test
+ -cleanup {rename x {}}
+}
+test assemble-8.20 {storeArray1} {
+ -body {
+ proc x {} {
+ assemble {
+ push z; push test; storeArray y
+ }
+ set y(z)
+ }
+ x
+ }
+ -result test
+ -cleanup {rename x {}}
+}
+test assemble-8.21 {storeArray4} {
+ -body {
+ proc x {} "
+ [fillTables]
+ assemble {
+ push z; push test; storeArray y
+ }
+ "
+ x
+ }
+ -result test
+ -cleanup {rename x {}}
+}
+
+# assemble-9 - ASSEM_CONCAT1, GetIntegerOperand, CheckOneByte
+
+test assemble-9.1 {wrong # args} {
+ -body {assemble concat}
+ -result {wrong # args*}
+ -match glob
+ -returnCodes error
+}
+test assemble-9.2 {wrong # args} {
+ -body {assemble {concat too many}}
+ -result {wrong # args*}
+ -match glob
+ -returnCodes error
+}
+test assemble-9.3 {not a number} {
+ -body {assemble {concat rubbish}}
+ -result {expected integer but got "rubbish"}
+ -returnCodes error
+}
+test assemble-9.4 {too small} {
+ -body {assemble {concat -1}}
+ -result {operand does not fit in one byte}
+ -returnCodes error
+}
+test assemble-9.5 {too small} {
+ -body {assemble {concat 256}}
+ -result {operand does not fit in one byte}
+ -returnCodes error
+}
+test assemble-9.6 {concat} {
+ -body {
+ assemble {push h; push e; push l; push l; push o; concat 5}
+ }
+ -result hello
+}
+test assemble-9.7 {concat} {
+ -body {
+ list [catch {assemble {concat 0}} result] $result $::errorCode
+ }
+ -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+ -cleanup {unset result}
+}
+
+# assemble-10 -- eval and expr
+
+test assemble-10.1 {eval - wrong # args} {
+ -body {
+ assemble {eval}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-10.2 {eval - wrong # args} {
+ -body {
+ assemble {eval too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-10.3 {eval} {
+ -body {
+ proc x {} {
+ assemble {
+ push 3
+ store n
+ pop
+ eval {expr {3*$n + 1}}
+ push 1
+ add
+ }
+ }
+ x
+ }
+ -result 11
+ -cleanup {rename x {}}
+}
+test assemble-10.4 {expr} {
+ -body {
+ proc x {} {
+ assemble {
+ push 3
+ store n
+ pop
+ expr {3*$n + 1}
+ push 1
+ add
+ }
+ }
+ x
+ }
+ -result 11
+ -cleanup {rename x {}}
+}
+test assemble-10.5 {eval and expr - nonsimple} {
+ -body {
+ proc x {} {
+ assemble {
+ eval "s\x65t n 3"
+ pop
+ expr "\x33*\$n + 1"
+ push 1
+ add
+ }
+ }
+ x
+ }
+ -result 11
+ -cleanup {
+ rename x {}
+ }
+}
+test assemble-10.6 {eval - noncompilable} {
+ -body {
+ list [catch {assemble {eval $x}} result] $result $::errorCode
+ }
+ -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+}
+test assemble-10.7 {expr - noncompilable} {
+ -body {
+ list [catch {assemble {expr $x}} result] $result $::errorCode
+ }
+ -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+}
+
+# assemble-11 - ASSEM_LVT4 (exist, existArray, dictAppend, dictLappend,
+# nsupvar, variable, upvar)
+
+test assemble-11.1 {exist - wrong # args} {
+ -body {
+ assemble {exist}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-11.2 {exist - wrong # args} {
+ -body {
+ assemble {exist too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-11.3 {nonlocal var} {
+ -body {
+ list [catch {assemble {exist ::env}} result] $result $errorCode
+ }
+ -result {1 {variable "::env" is not local} {TCL ASSEM NONLOCAL ::env}}
+ -cleanup {unset result}
+}
+test assemble-11.4 {exist} {
+ -body {
+ proc x {} {
+ set y z
+ list [assemble {exist y}] \
+ [assemble {exist z}]
+ }
+ x
+ }
+ -result {1 0}
+ -cleanup {rename x {}}
+}
+test assemble-11.5 {existArray} {
+ -body {
+ proc x {} {
+ set a(b) c
+ list [assemble {push b; existArray a}] \
+ [assemble {push c; existArray a}] \
+ [assemble {push a; existArray b}]
+ }
+ x
+ }
+ -result {1 0 0}
+ -cleanup {rename x {}}
+}
+test assemble-11.6 {dictAppend} {
+ -body {
+ proc x {} {
+ set dict {a 1 b 2 c 3}
+ assemble {push b; push 22; dictAppend dict}
+ }
+ x
+ }
+ -result {a 1 b 222 c 3}
+ -cleanup {rename x {}}
+}
+test assemble-11.7 {dictLappend} {
+ -body {
+ proc x {} {
+ set dict {a 1 b 2 c 3}
+ assemble {push b; push 2; dictLappend dict}
+ }
+ x
+ }
+ -result {a 1 b {2 2} c 3}
+ -cleanup {rename x {}}
+}
+test assemble-11.8 {upvar} {
+ -body {
+ proc x {v} {
+ assemble {push 1; load v; upvar w; pop; load w}
+ }
+ proc y {} {
+ set z 123
+ x z
+ }
+ y
+ }
+ -result 123
+ -cleanup {rename x {}; rename y {}}
+}
+test assemble-11.9 {nsupvar} {
+ -body {
+ namespace eval q { variable v 123 }
+ proc x {} {
+ assemble {push q; push v; nsupvar y; pop; load y}
+ }
+ x
+ }
+ -result 123
+ -cleanup {namespace delete q; rename x {}}
+}
+test assemble-11.10 {variable} {
+ -body {
+ namespace eval q { namespace eval r {variable v 123}}
+ proc x {} {
+ assemble {push q::r::v; variable y; load y}
+ }
+ x
+ }
+ -result 123
+ -cleanup {namespace delete q; rename x {}}
+}
+
+# assemble-12 - ASSEM_LVT1 (incr and incrArray)
+
+test assemble-12.1 {incr - wrong # args} {
+ -body {
+ assemble {incr}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-12.2 {incr - wrong # args} {
+ -body {
+ assemble {incr too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-12.3 {incr nonlocal var} {
+ -body {
+ list [catch {assemble {incr ::env}} result] $result $errorCode
+ }
+ -result {1 {variable "::env" is not local} {TCL ASSEM NONLOCAL ::env}}
+ -cleanup {unset result}
+}
+test assemble-12.4 {incr} {
+ -body {
+ proc x {} {
+ set y 5
+ assemble {push 3; incr y}
+ }
+ x
+ }
+ -result 8
+ -cleanup {rename x {}}
+}
+test assemble-12.5 {incrArray} {
+ -body {
+ proc x {} {
+ set a(b) 5
+ assemble {push b; push 3; incrArray a}
+ }
+ x
+ }
+ -result 8
+ -cleanup {rename x {}}
+}
+test assemble-12.6 {incr, stupid stack restriction} {
+ -body {
+ proc x {} "
+ [fillTables]
+ set y 5
+ assemble {push 3; incr y}
+ "
+ list [catch {x} result] $result $errorCode
+ }
+ -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+ -cleanup {unset result; rename x {}}
+}
+
+# assemble-13 -- ASSEM_LVT1_SINT1 - incrImm and incrArrayImm
+
+test assemble-13.1 {incrImm - wrong # args} {
+ -body {
+ assemble {incrImm x}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-13.2 {incrImm - wrong # args} {
+ -body {
+ assemble {incrImm too many args}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-13.3 {incrImm nonlocal var} {
+ -body {
+ list [catch {assemble {incrImm ::env 2}} result] $result $errorCode
+ }
+ -result {1 {variable "::env" is not local} {TCL ASSEM NONLOCAL ::env}}
+ -cleanup {unset result}
+}
+test assemble-13.4 {incrImm not a number} {
+ -body {
+ proc x {} {
+ assemble {incrImm x rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-13.5 {incrImm too big} {
+ -body {
+ proc x {} {
+ assemble {incrImm x 0x80}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-13.6 {incrImm too small} {
+ -body {
+ proc x {} {
+ assemble {incrImm x -0x81}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-13.7 {incrImm} {
+ -body {
+ proc x {} {
+ set y 1
+ list [assemble {incrImm y -0x80}] [assemble {incrImm y 0x7f}]
+ }
+ x
+ }
+ -result {-127 0}
+ -cleanup {rename x {}}
+}
+test assemble-13.8 {incrArrayImm} {
+ -body {
+ proc x {} {
+ set a(b) 5
+ assemble {push b; incrArrayImm a 3}
+ }
+ x
+ }
+ -result 8
+ -cleanup {rename x {}}
+}
+test assemble-13.9 {incrImm, stupid stack restriction} {
+ -body {
+ proc x {} "
+ [fillTables]
+ set y 5
+ assemble {incrImm y 3}
+ "
+ list [catch {x} result] $result $errorCode
+ }
+ -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+ -cleanup {unset result; rename x {}}
+}
+
+# assemble-14 -- ASSEM_SINT1 (incrArrayStkImm and incrStkImm)
+
+test assemble-14.1 {incrStkImm - wrong # args} {
+ -body {
+ assemble {incrStkImm}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-14.2 {incrStkImm - wrong # args} {
+ -body {
+ assemble {incrStkImm too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-14.3 {incrStkImm not a number} {
+ -body {
+ proc x {} {
+ assemble {incrStkImm rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-14.4 {incrStkImm too big} {
+ -body {
+ proc x {} {
+ assemble {incrStkImm 0x80}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-14.5 {incrStkImm too small} {
+ -body {
+ proc x {} {
+ assemble {incrStkImm -0x81}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-14.6 {incrStkImm} {
+ -body {
+ proc x {} {
+ set y 1
+ list [assemble {push y; incrStkImm -0x80}] \
+ [assemble {push y; incrStkImm 0x7f}]
+ }
+ x
+ }
+ -result {-127 0}
+ -cleanup {rename x {}}
+}
+test assemble-14.7 {incrArrayStkImm} {
+ -body {
+ proc x {} {
+ set a(b) 5
+ assemble {push a; push b; incrArrayStkImm 3}
+ }
+ x
+ }
+ -result 8
+ -cleanup {rename x {}}
+}
+
+# assemble-15 - listIndexImm
+
+test assemble-15.1 {listIndexImm - wrong # args} {
+ -body {
+ assemble {listIndexImm}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-15.2 {listIndexImm - wrong # args} {
+ -body {
+ assemble {listIndexImm too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-15.3 {listIndexImm - bad substitution} {
+ -body {
+ list [catch {assemble {listIndexImm $foo}} result] $result $::errorCode
+ }
+ -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+ -cleanup {unset result}
+}
+test assemble-15.4 {listIndexImm - invalid index} {
+ -body {
+ assemble {listIndexImm rubbish}
+ }
+ -returnCodes error
+ -match glob
+ -result {bad index "rubbish"*}
+}
+test assemble-15.5 {listIndexImm} {
+ -body {
+ assemble {push {a b c}; listIndexImm 2}
+ }
+ -result c
+}
+test assemble-15.6 {listIndexImm} {
+ -body {
+ assemble {push {a b c}; listIndexImm end-1}
+ }
+ -result b
+}
+test assemble-15.7 {listIndexImm} {
+ -body {
+ assemble {push {a b c}; listIndexImm end}
+ }
+ -result c
+}
+
+# assemble-16 - invokeStk
+
+test assemble-16.1 {invokeStk - wrong # args} {
+ -body {
+ assemble {invokeStk}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-16.2 {invokeStk - wrong # args} {
+ -body {
+ assemble {invokeStk too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-16.3 {invokeStk - not a number} {
+ -body {
+ proc x {} {
+ assemble {invokeStk rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-16.4 {invokeStk - no operands} {
+ -body {
+ proc x {} {
+ assemble {invokeStk 0}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-16.5 {invokeStk1} {
+ -body {
+ tcl::unsupported::assemble {push concat; push 1; push 2; invokeStk 3}
+ }
+ -result {1 2}
+}
+test assemble-16.6 {invokeStk4} {
+ -body {
+ proc x {n} {
+ set code {push concat}
+ set shouldbe {}
+ for {set i 1} {$i < $n} {incr i} {
+ append code \n {push a} $i
+ lappend shouldbe a$i
+ }
+ append code \n {invokeStk} { } $n
+ set is [assemble $code]
+ expr {$is eq $shouldbe}
+ }
+ list [x 254] [x 255] [x 256] [x 257]
+ }
+ -result {1 1 1 1}
+ -cleanup {rename x {}}
+}
+
+# assemble-17 -- jumps and labels
+
+test assemble-17.1 {label, wrong # args} {
+ -body {
+ assemble {label}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-17.2 {label, wrong # args} {
+ -body {
+ assemble {label too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-17.3 {label, bad subst} {
+ -body {
+ list [catch {assemble {label $foo}} result] $result $::errorCode
+ }
+ -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+ -cleanup {unset result}
+}
+test assemble-17.4 {duplicate label} {
+ -body {
+ list [catch {assemble {label foo; label foo}} result] \
+ $result $::errorCode
+ }
+ -result {1 {duplicate definition of label "foo"} {TCL ASSEM DUPLABEL foo}}
+}
+test assemble-17.5 {jump, wrong # args} {
+ -body {
+ assemble {jump}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-17.6 {jump, wrong # args} {
+ -body {
+ assemble {jump too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-17.7 {jump, bad subst} {
+ -body {
+ list [catch {assemble {jump $foo}} result] $result $::errorCode
+ }
+ -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+ -cleanup {unset result}
+}
+test assemble-17.8 {jump - ahead and back} {
+ -body {
+ assemble {
+ jump three
+
+ label one
+ push a
+ jump four
+
+ label two
+ push b
+ jump six
+
+ label three
+ push c
+ jump five
+
+ label four
+ push d
+ jump two
+
+ label five
+ push e
+ jump one
+
+ label six
+ push f
+ concat 6
+ }
+ }
+ -result ceadbf
+}
+test assemble-17.9 {jump - resolve a label multiple times} {
+ -body {
+ proc x {} {
+ set case 0
+ set result {}
+ assemble {
+ jump common
+
+ label zero
+ pop
+ incrImm case 1
+ pop
+ push a
+ append result
+ pop
+ jump common
+
+ label one
+ pop
+ incrImm case 1
+ pop
+ push b
+ append result
+ pop
+ jump common
+
+ label common
+ load case
+ dup
+ push 0
+ eq
+ jumpTrue zero
+ dup
+ push 1
+ eq
+ jumpTrue one
+ dup
+ push 2
+ eq
+ jumpTrue two
+ dup
+ push 3
+ eq
+ jumpTrue three
+
+ label two
+ pop
+ incrImm case 1
+ pop
+ push c
+ append result
+ pop
+ jump common
+
+ label three
+ pop
+ incrImm case 1
+ pop
+ push d
+ append result
+ }
+ }
+ x
+ }
+ -result abcd
+ -cleanup {rename x {}}
+}
+test assemble-17.10 {jump4 needed} {
+ -body {
+ assemble "push x; jump one; label two; [string repeat {dup; pop;} 128]
+ jump three; label one; jump two; label three"
+ }
+ -result x
+}
+test assemble-17.11 {jumpTrue} {
+ -body {
+ proc x {y} {
+ assemble {
+ load y
+ jumpTrue then
+ push no
+ jump else
+ label then
+ push yes
+ label else
+ }
+ }
+ list [x 0] [x 1]
+ }
+ -result {no yes}
+ -cleanup {rename x {}}
+}
+test assemble-17.12 {jumpFalse} {
+ -body {
+ proc x {y} {
+ assemble {
+ load y
+ jumpFalse then
+ push no
+ jump else
+ label then
+ push yes
+ label else
+ }
+ }
+ list [x 0] [x 1]
+ }
+ -result {yes no}
+ -cleanup {rename x {}}
+}
+test assemble-17.13 {jump to undefined label} {
+ -body {
+ list [catch {assemble {jump nowhere}} result] $result $::errorCode
+ }
+ -result {1 {undefined label "nowhere"} {TCL ASSEM NOLABEL nowhere}}
+}
+test assemble-17.14 {jump to undefined label, line number correct?} {
+ -body {
+ catch {assemble {#1
+ #2
+ #3
+ jump nowhere
+ #5
+ #6
+ }}
+ set ::errorInfo
+ }
+ -match glob
+ -result {*"assemble" body, line 4*}
+}
+test assemble-17.15 {multiple passes of code resizing} {
+ -setup {
+ set body {
+ push -
+ }
+ for {set i 0} {$i < 14} {incr i} {
+ append body "label a" $i \
+ "; push a; concat 2; nop; nop; jump b" \
+ $i \n
+ }
+ append body {label a14; push a; concat 2; push 1; jumpTrue b14} \n
+ append body {label a15; push a; concat 2; push 0; jumpFalse b15} \n
+ for {set i 0} {$i < 15} {incr i} {
+ append body "label b" $i \
+ "; push b; concat 2; nop; nop; jump a" \
+ [expr {$i+1}] \n
+ }
+ append body {label c; push -; concat 2; nop; nop; nop; jump d} \n
+ append body {label b15; push b; concat 2; nop; nop; jump c} \n
+ append body {label d}
+ proc x {} [list assemble $body]
+ }
+ -body {
+ x
+ }
+ -cleanup {
+ catch {unset body}
+ catch {rename x {}}
+ }
+ -result -abababababababababababababababab-
+}
+
+# assemble-18 - lindexMulti
+
+test assemble-18.1 {lindexMulti - wrong # args} {
+ -body {
+ assemble {lindexMulti}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-18.2 {lindexMulti - wrong # args} {
+ -body {
+ assemble {lindexMulti too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-18.3 {lindexMulti - bad subst} {
+ -body {
+ assemble {lindexMulti $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-18.4 {lindexMulti - not a number} {
+ -body {
+ proc x {} {
+ assemble {lindexMulti rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-18.5 {lindexMulti - bad operand count} {
+ -body {
+ proc x {} {
+ assemble {lindexMulti 0}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-18.6 {lindexMulti} {
+ -body {
+ assemble {push {{a b c} {d e f} {g h j}}; lindexMulti 1}
+ }
+ -result {{a b c} {d e f} {g h j}}
+}
+test assemble-18.7 {lindexMulti} {
+ -body {
+ assemble {push {{a b c} {d e f} {g h j}}; push 1; lindexMulti 2}
+ }
+ -result {d e f}
+}
+test assemble-18.8 {lindexMulti} {
+ -body {
+ assemble {push {{a b c} {d e f} {g h j}}; push 2; push 1; lindexMulti 3}
+ }
+ -result h
+}
+
+# assemble-19 - list
+
+test assemble-19.1 {list - wrong # args} {
+ -body {
+ assemble {list}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-19.2 {list - wrong # args} {
+ -body {
+ assemble {list too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-19.3 {list - bad subst} {
+ -body {
+ assemble {list $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-19.4 {list - not a number} {
+ -body {
+ proc x {} {
+ assemble {list rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-19.5 {list - negative operand count} {
+ -body {
+ proc x {} {
+ assemble {list -1}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be nonnegative} {TCL ASSEM NONNEGATIVE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-19.6 {list - no args} {
+ -body {
+ assemble {list 0}
+ }
+ -result {}
+}
+test assemble-19.7 {list - 1 arg} {
+ -body {
+ assemble {push hello; list 1}
+ }
+ -result hello
+}
+test assemble-19.8 {list - 2 args} {
+ -body {
+ assemble {push hello; push world; list 2}
+ }
+ -result {hello world}
+}
+
+# assemble-20 - lsetFlat
+
+test assemble-20.1 {lsetFlat - wrong # args} {
+ -body {
+ assemble {lsetFlat}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-20.2 {lsetFlat - wrong # args} {
+ -body {
+ assemble {lsetFlat too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-20.3 {lsetFlat - bad subst} {
+ -body {
+ assemble {lsetFlat $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-20.4 {lsetFlat - not a number} {
+ -body {
+ proc x {} {
+ assemble {lsetFlat rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-20.5 {lsetFlat - negative operand count} {
+ -body {
+ proc x {} {
+ assemble {lsetFlat 1}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be >=2} {TCL ASSEM OPERAND>=2}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-20.6 {lsetFlat} {
+ -body {
+ assemble {push b; push a; lsetFlat 2}
+ }
+ -result b
+}
+test assemble-20.7 {lsetFlat} {
+ -body {
+ assemble {push 1; push d; push {a b c}; lsetFlat 3}
+ }
+ -result {a d c}
+}
+
+# assemble-21 - over
+
+test assemble-21.1 {over - wrong # args} {
+ -body {
+ assemble {over}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-21.2 {over - wrong # args} {
+ -body {
+ assemble {over too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-21.3 {over - bad subst} {
+ -body {
+ assemble {over $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-21.4 {over - not a number} {
+ -body {
+ proc x {} {
+ assemble {over rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-21.5 {over - negative operand count} {
+ -body {
+ proc x {} {
+ assemble {over -1}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be nonnegative} {TCL ASSEM NONNEGATIVE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-21.6 {over} {
+ -body {
+ proc x {} {
+ assemble {
+ push 1
+ push 2
+ push 3
+ over 0
+ store x
+ pop
+ pop
+ pop
+ pop
+ load x
+ }
+ }
+ x
+ }
+ -result 3
+ -cleanup {rename x {}}
+}
+test assemble-21.7 {over} {
+ -body {
+ proc x {} {
+ assemble {
+ push 1
+ push 2
+ push 3
+ over 2
+ store x
+ pop
+ pop
+ pop
+ pop
+ load x
+ }
+ }
+ x
+ }
+ -result 1
+ -cleanup {rename x {}}
+}
+
+# assemble-22 - reverse
+
+test assemble-22.1 {reverse - wrong # args} {
+ -body {
+ assemble {reverse}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-22.2 {reverse - wrong # args} {
+ -body {
+ assemble {reverse too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+
+test assemble-22.3 {reverse - bad subst} {
+ -body {
+ assemble {reverse $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+
+test assemble-22.4 {reverse - not a number} {
+ -body {
+ proc x {} {
+ assemble {reverse rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-22.5 {reverse - negative operand count} {
+ -body {
+ proc x {} {
+ assemble {reverse -1}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be nonnegative} {TCL ASSEM NONNEGATIVE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-22.6 {reverse - zero operand count} {
+ -body {
+ proc x {} {
+ assemble {push 1; reverse 0}
+ }
+ x
+ }
+ -result 1
+ -cleanup {rename x {}}
+}
+test assemble-22.7 {reverse} {
+ -body {
+ proc x {} {
+ assemble {
+ push 1
+ push 2
+ push 3
+ reverse 1
+ store x
+ pop
+ pop
+ pop
+ load x
+ }
+ }
+ x
+ }
+ -result 3
+ -cleanup {rename x {}}
+}
+test assemble-22.8 {reverse} {
+ -body {
+ proc x {} {
+ assemble {
+ push 1
+ push 2
+ push 3
+ reverse 3
+ store x
+ pop
+ pop
+ pop
+ load x
+ }
+ }
+ x
+ }
+ -result 1
+ -cleanup {rename x {}}
+}
+
+# assemble-23 - ASSEM_BOOL (strmatch, unsetStk, unsetArrayStk)
+
+test assemble-23.1 {strmatch - wrong # args} {
+ -body {
+ assemble {strmatch}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-23.2 {strmatch - wrong # args} {
+ -body {
+ assemble {strmatch too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-23.3 {strmatch - bad subst} {
+ -body {
+ assemble {strmatch $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-23.4 {strmatch - not a boolean} {
+ -body {
+ proc x {} {
+ assemble {strmatch rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected boolean value but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-23.5 {strmatch} {
+ -body {
+ proc x {a b} {
+ list [assemble {load a; load b; strmatch 0}] \
+ [assemble {load a; load b; strmatch 1}]
+ }
+ list [x foo*.grill fengbar.grill] [x foo*.grill foobar.grill] [x foo*.grill FOOBAR.GRILL]
+ }
+ -result {{0 0} {1 1} {0 1}}
+ -cleanup {rename x {}}
+}
+test assemble-23.6 {unsetStk} {
+ -body {
+ proc x {} {
+ set a {}
+ assemble {push a; unsetStk false}
+ info exists a
+ }
+ x
+ }
+ -result 0
+ -cleanup {rename x {}}
+}
+test assemble-23.7 {unsetStk} {
+ -body {
+ proc x {} {
+ assemble {push a; unsetStk false}
+ info exists a
+ }
+ x
+ }
+ -result 0
+ -cleanup {rename x {}}
+}
+test assemble-23.8 {unsetStk} {
+ -body {
+ proc x {} {
+ assemble {push a; unsetStk true}
+ info exists a
+ }
+ x
+ }
+ -returnCodes error
+ -result {can't unset "a": no such variable}
+ -cleanup {rename x {}}
+}
+test assemble-23.9 {unsetArrayStk} {
+ -body {
+ proc x {} {
+ set a(b) {}
+ assemble {push a; push b; unsetArrayStk false}
+ info exists a(b)
+ }
+ x
+ }
+ -result 0
+ -cleanup {rename x {}}
+}
+test assemble-23.10 {unsetArrayStk} {
+ -body {
+ proc x {} {
+ assemble {push a; push b; unsetArrayStk false}
+ info exists a(b)
+ }
+ x
+ }
+ -result 0
+ -cleanup {rename x {}}
+}
+test assemble-23.11 {unsetArrayStk} {
+ -body {
+ proc x {} {
+ assemble {push a; push b; unsetArrayStk true}
+ info exists a(b)
+ }
+ x
+ }
+ -returnCodes error
+ -result {can't unset "a(b)": no such variable}
+ -cleanup {rename x {}}
+}
+
+# assemble-24 -- ASSEM_BOOL_LVT4 (unset; unsetArray)
+
+test assemble-24.1 {unset - wrong # args} {
+ -body {
+ assemble {unset one}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-24.2 {unset - wrong # args} {
+ -body {
+ assemble {unset too many args}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-24.3 {unset - bad subst -arg 1} {
+ -body {
+ assemble {unset $foo bar}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-24.4 {unset - not a boolean} {
+ -body {
+ proc x {} {
+ assemble {unset rubbish trash}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected boolean value but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-24.5 {unset - bad subst - arg 2} {
+ -body {
+ assemble {unset true $bar}
+ }
+ -returnCodes error
+ -result {assembly code may not contain substitutions}
+}
+test assemble-24.6 {unset - nonlocal var} {
+ -body {
+ assemble {unset true ::foo::bar}
+ }
+ -returnCodes error
+ -result {variable "::foo::bar" is not local}
+}
+test assemble-24.7 {unset} {
+ -body {
+ proc x {} {
+ set a {}
+ assemble {unset false a}
+ info exists a
+ }
+ x
+ }
+ -result 0
+ -cleanup {rename x {}}
+}
+test assemble-24.8 {unset} {
+ -body {
+ proc x {} {
+ assemble {unset false a}
+ info exists a
+ }
+ x
+ }
+ -result 0
+ -cleanup {rename x {}}
+}
+test assemble-24.9 {unset} {
+ -body {
+ proc x {} {
+ assemble {unset true a}
+ info exists a
+ }
+ x
+ }
+ -returnCodes error
+ -result {can't unset "a": no such variable}
+ -cleanup {rename x {}}
+}
+test assemble-24.10 {unsetArray} {
+ -body {
+ proc x {} {
+ set a(b) {}
+ assemble {push b; unsetArray false a}
+ info exists a(b)
+ }
+ x
+ }
+ -result 0
+ -cleanup {rename x {}}
+}
+test assemble-24.11 {unsetArray} {
+ -body {
+ proc x {} {
+ assemble {push b; unsetArray false a}
+ info exists a(b)
+ }
+ x
+ }
+ -result 0
+ -cleanup {rename x {}}
+}
+test assemble-24.12 {unsetArray} {
+ -body {
+ proc x {} {
+ assemble {push b; unsetArray true a}
+ info exists a(b)
+ }
+ x
+ }
+ -returnCodes error
+ -result {can't unset "a(b)": no such variable}
+ -cleanup {rename x {}}
+}
+
+# assemble-25 - dict get
+
+test assemble-25.1 {dict get - wrong # args} {
+ -body {
+ assemble {dictGet}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-25.2 {dict get - wrong # args} {
+ -body {
+ assemble {dictGet too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-25.3 {dictGet - bad subst} {
+ -body {
+ assemble {dictGet $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-25.4 {dict get - not a number} {
+ -body {
+ proc x {} {
+ assemble {dictGet rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-25.5 {dictGet - negative operand count} {
+ -body {
+ proc x {} {
+ assemble {dictGet 0}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-25.6 {dictGet - 1 index} {
+ -body {
+ assemble {push {a 1 b 2}; push a; dictGet 1}
+ }
+ -result 1
+}
+
+# assemble-26 - dict set
+
+test assemble-26.1 {dict set - wrong # args} {
+ -body {
+ assemble {dictSet 1}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-26.2 {dict get - wrong # args} {
+ -body {
+ assemble {dictSet too many args}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-26.3 {dictSet - bad subst} {
+ -body {
+ assemble {dictSet 1 $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-26.4 {dictSet - not a number} {
+ -body {
+ proc x {} {
+ assemble {dictSet rubbish foo}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-26.5 {dictSet - zero operand count} {
+ -body {
+ proc x {} {
+ assemble {dictSet 0 foo}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-26.6 {dictSet - bad local} {
+ -body {
+ proc x {} {
+ assemble {dictSet 1 ::foo::bar}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {variable "::foo::bar" is not local} {TCL ASSEM NONLOCAL ::foo::bar}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-26.7 {dictSet} {
+ -body {
+ proc x {} {
+ set dict {a 1 b 2 c 3}
+ assemble {push b; push 4; dictSet 1 dict}
+ }
+ x
+ }
+ -result {a 1 b 4 c 3}
+ -cleanup {rename x {}}
+}
+
+# assemble-27 - dictUnset
+
+test assemble-27.1 {dictUnset - wrong # args} {
+ -body {
+ assemble {dictUnset 1}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-27.2 {dictUnset - wrong # args} {
+ -body {
+ assemble {dictUnset too many args}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-27.3 {dictUnset - bad subst} {
+ -body {
+ assemble {dictUnset 1 $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-27.4 {dictUnset - not a number} {
+ -body {
+ proc x {} {
+ assemble {dictUnset rubbish foo}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-27.5 {dictUnset - zero operand count} {
+ -body {
+ proc x {} {
+ assemble {dictUnset 0 foo}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-27.6 {dictUnset - bad local} {
+ -body {
+ proc x {} {
+ assemble {dictUnset 1 ::foo::bar}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {variable "::foo::bar" is not local} {TCL ASSEM NONLOCAL ::foo::bar}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-27.7 {dictUnset} {
+ -body {
+ proc x {} {
+ set dict {a 1 b 2 c 3}
+ assemble {push b; dictUnset 1 dict}
+ }
+ x
+ }
+ -result {a 1 c 3}
+ -cleanup {rename x {}}
+}
+
+# assemble-28 - dictIncrImm
+
+test assemble-28.1 {dictIncrImm - wrong # args} {
+ -body {
+ assemble {dictIncrImm 1}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-28.2 {dictIncrImm - wrong # args} {
+ -body {
+ assemble {dictIncrImm too many args}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-28.3 {dictIncrImm - bad subst} {
+ -body {
+ assemble {dictIncrImm 1 $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-28.4 {dictIncrImm - not a number} {
+ -body {
+ proc x {} {
+ assemble {dictIncrImm rubbish foo}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-28.5 {dictIncrImm - bad local} {
+ -body {
+ proc x {} {
+ assemble {dictIncrImm 1 ::foo::bar}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {variable "::foo::bar" is not local} {TCL ASSEM NONLOCAL ::foo::bar}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-28.6 {dictIncrImm} {
+ -body {
+ proc x {} {
+ set dict {a 1 b 2 c 3}
+ assemble {push b; dictIncrImm 42 dict}
+ }
+ x
+ }
+ -result {a 1 b 44 c 3}
+ -cleanup {rename x {}}
+}
+
+# assemble-29 - ASSEM_REGEXP
+
+test assemble-29.1 {regexp - wrong # args} {
+ -body {
+ assemble {regexp}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-29.2 {regexp - wrong # args} {
+ -body {
+ assemble {regexp too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-29.3 {regexp - bad subst} {
+ -body {
+ assemble {regexp $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-29.4 {regexp - not a boolean} {
+ -body {
+ proc x {} {
+ assemble {regexp rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected boolean value but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-29.5 {regexp} {
+ -body {
+ assemble {push br.*br; push abracadabra; regexp false}
+ }
+ -result 1
+}
+test assemble-29.6 {regexp} {
+ -body {
+ assemble {push br.*br; push aBRacadabra; regexp false}
+ }
+ -result 0
+}
+test assemble-29.7 {regexp} {
+ -body {
+ assemble {push br.*br; push aBRacadabra; regexp true}
+ }
+ -result 1
+}
+
+# assemble-30 - Catches
+
+test assemble-30.1 {simplest possible catch} {
+ -body {
+ proc x {} {
+ assemble {
+ beginCatch @bad
+ push error
+ push testing
+ invokeStk 2
+ pop
+ push 0
+ jump @ok
+ label @bad
+ push 1; # should be pushReturnCode
+ label @ok
+ endCatch
+ }
+ }
+ x
+ }
+ -result 1
+ -cleanup {rename x {}}
+}
+test assemble-30.2 {catch in external catch conntext} {
+ -body {
+ proc x {} {
+ list [catch {
+ assemble {
+ beginCatch @bad
+ push error
+ push testing
+ invokeStk 2
+ pop
+ push 0
+ jump @ok
+ label @bad
+ pushReturnCode
+ label @ok
+ endCatch
+ }
+ } result] $result
+ }
+ x
+ }
+ -result {0 1}
+ -cleanup {rename x {}}
+}
+test assemble-30.3 {embedded catches} {
+ -body {
+ proc x {} {
+ list [catch {
+ assemble {
+ beginCatch @bad
+ push error
+ eval { list [catch {error whatever} result] $result }
+ invokeStk 2
+ push 0
+ reverse 2
+ jump @done
+ label @bad
+ pushReturnCode
+ pushResult
+ label @done
+ endCatch
+ list 2
+ }
+ } result2] $result2
+ }
+ x
+ }
+ -result {0 {1 {1 whatever}}}
+ -cleanup {rename x {}}
+}
+test assemble-30.4 {throw in wrong context} {
+ -body {
+ proc x {} {
+ list [catch {
+ assemble {
+ beginCatch @bad
+ push error
+ eval { list [catch {error whatever} result] $result }
+ invokeStk 2
+ push 0
+ reverse 2
+ jump @done
+
+ label @bad
+ load x
+ pushResult
+
+ label @done
+ endCatch
+ list 2
+ }
+ } result] $result $::errorCode [split $::errorInfo \n]
+ }
+ x
+ }
+ -match glob
+ -result {1 {"loadScalar1" instruction may not appear in a context where an exception has been caught and not disposed of.} {TCL ASSEM BADTHROW} {{"loadScalar1" instruction may not appear in a context where an exception has been caught and not disposed of.} { in assembly code between lines 10 and 15}*}}
+ -cleanup {rename x {}}
+}
+test assemble-30.5 {unclosed catch} {
+ -body {
+ proc x {} {
+ assemble {
+ beginCatch @error
+ push 0
+ jump @done
+ label @error
+ push 1
+ label @done
+ push ""
+ pop
+ }
+ }
+ list [catch {x} result] $result $::errorCode $::errorInfo
+ }
+ -match glob
+ -result {1 {catch still active on exit from assembly code} {TCL ASSEM UNCLOSEDCATCH} {catch still active on exit from assembly code
+ ("assemble" body, line 2)*}}
+ -cleanup {rename x {}}
+}
+test assemble-30.6 {inconsistent catch contexts} {
+ -body {
+ proc x {y} {
+ assemble {
+ load y
+ jumpTrue @inblock
+ beginCatch @error
+ label @inblock
+ push 0
+ jump @done
+ label @error
+ push 1
+ label @done
+ }
+ }
+ list [catch {x 2} result] $::errorCode $::errorInfo
+ }
+ -match glob
+ -result {1 {TCL ASSEM BADCATCH} {execution reaches an instruction in inconsistent exception contexts
+ ("assemble" body, line 5)*}}
+ -cleanup {rename x {}}
+}
+
+# assemble-31 - Jump tables
+
+test assemble-31.1 {jumpTable, wrong # args} {
+ -body {
+ assemble {jumpTable}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-31.2 {jumpTable, wrong # args} {
+ -body {
+ assemble {jumpTable too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-31.3 {jumpTable - bad subst} {
+ -body {
+ assemble {jumpTable $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-31.4 {jumptable - not a list} {
+ -body {
+ assemble {jumpTable \{rubbish}
+ }
+ -returnCodes error
+ -result {unmatched open brace in list}
+}
+test assemble-31.5 {jumpTable, badly structured} {
+ -body {
+ list [catch {assemble {
+ # line 2
+ jumpTable {one two three};# line 3
+ }} result] \
+ $result $::errorCode $::errorInfo
+ }
+ -match glob
+ -result {1 {jump table must have an even number of list elements} {TCL ASSEM BADJUMPTABLE} {jump table must have an even number of list elements*("assemble" body, line 3)*}}
+}
+test assemble-31.6 {jumpTable, missing symbol} {
+ -body {
+ list [catch {assemble {
+ # line 2
+ jumpTable {1 a};# line 3
+ }} result] \
+ $result $::errorCode $::errorInfo
+ }
+ -match glob
+ -result {1 {undefined label "a"} {TCL ASSEM NOLABEL a} {undefined label "a"*("assemble" body, line 3)*}}
+}
+test assemble-31.7 {jumptable, actual example} {
+ -setup {
+ proc x {} {
+ set result {}
+ for {set i 0} {$i < 5} {incr i} {
+ lappend result [assemble {
+ load i
+ jumpTable {1 @one 2 @two 3 @three}
+ push {none of the above}
+ jump @done
+ label @one
+ push one
+ jump @done
+ label @two
+ push two
+ jump @done
+ label @three
+ push three
+ label @done
+ }]
+ }
+ set tcl_traceCompile 2
+ set result
+ }
+ }
+ -body x
+ -result {{none of the above} one two three {none of the above}}
+ -cleanup {set tcl_traceCompile 0; rename x {}}
+}
+
+test assemble-40.1 {unbalanced stack} {
+ -body {
+ list \
+ [catch {
+ assemble {
+ push 3
+ dup
+ mult
+ push 4
+ dup
+ mult
+ pop
+ expon
+ }
+ } result] $result $::errorInfo
+ }
+ -result {1 {stack underflow} {stack underflow
+ in assembly code between lines 1 and end of assembly code*}}
+ -match glob
+ -returnCodes ok
+}
+test assemble-40.2 {unbalanced stack} {*}{
+ -body {
+ list \
+ [catch {
+ assemble {
+ label a
+ push {}
+ label b
+ pop
+ label c
+ pop
+ label d
+ push {}
+ }
+ } result] $result $::errorInfo
+ }
+ -result {1 {stack underflow} {stack underflow
+ in assembly code between lines 7 and 9*}}
+ -match glob
+ -returnCodes ok
+}
+
+test assemble-41.1 {Inconsistent stack usage} {*}{
+ -body {
+ proc x {y} {
+ assemble {
+ load y
+ jumpFalse else
+ push 0
+ jump then
+ label else
+ push 1
+ push 2
+ label then
+ pop
+ }
+ }
+ catch {x 1}
+ set errorInfo
+ }
+ -match glob
+ -result {inconsistent stack depths on two execution paths
+ ("assemble" body, line 10)*}
+}
+test assemble-41.2 {Inconsistent stack, jumptable and default} {
+ -body {
+ proc x {y} {
+ assemble {
+ load y
+ jumpTable {0 else}
+ push 0
+ label else
+ pop
+ }
+ }
+ catch {x 1}
+ set errorInfo
+ }
+ -match glob
+ -result {inconsistent stack depths on two execution paths
+ ("assemble" body, line 6)*}
+}
+test assemble-41.3 {Inconsistent stack, two legs of jumptable} {
+ -body {
+ proc x {y} {
+ assemble {
+ load y
+ jumpTable {0 no 1 yes}
+ label no
+ push 0
+ label yes
+ pop
+ }
+ }
+ catch {x 1}
+ set errorInfo
+ }
+ -match glob
+ -result {inconsistent stack depths on two execution paths
+ ("assemble" body, line 7)*}
+}
+
+test assemble-50.1 {Ulam's 3n+1 problem, TAL implementation} {
+ -body {
+ proc ulam {n} {
+ assemble {
+ load n; # max
+ dup; # max n
+ jump start; # max n
+
+ label loop; # max n
+ over 1; # max n max
+ over 1; # max in max n
+ ge; # man n max>=n
+ jumpTrue skip; # max n
+
+ reverse 2; # n max
+ pop; # n
+ dup; # n n
+
+ label skip; # max n
+ dup; # max n n
+ push 2; # max n n 2
+ mod; # max n n%2
+ jumpTrue odd; # max n
+
+ push 2; # max n 2
+ div; # max n/2 -> max n
+ jump start; # max n
+
+ label odd; # max n
+ push 3; # max n 3
+ mult; # max 3*n
+ push 1; # max 3*n 1
+ add; # max 3*n+1
+
+ label start; # max n
+ dup; # max n n
+ push 1; # max n n 1
+ neq; # max n n>1
+ jumpTrue loop; # max n
+
+ pop; # max
+ }
+ }
+ set result {}
+ for {set i 1} {$i < 30} {incr i} {
+ lappend result [ulam $i]
+ }
+ set result
+ }
+ -result {1 2 16 4 16 16 52 8 52 16 52 16 40 52 160 16 52 52 88 20 64 52 160 24 88 40 9232 52 88}
+}
+
+test assemble-51.1 {memory leak testing} memory {
+ leaktest {
+ apply {{} {assemble {push hello}}}
+ }
+} 0
+test assemble-51.2 {memory leak testing} memory {
+ leaktest {
+ apply {{{x 0}} {assemble {incrImm x 1}}}
+ }
+} 0
+test assemble-51.3 {memory leak testing} memory {
+ leaktest {
+ apply {{n} {
+ assemble {
+ load n; # max
+ dup; # max n
+ jump start; # max n
+
+ label loop; # max n
+ over 1; # max n max
+ over 1; # max in max n
+ ge; # man n max>=n
+ jumpTrue skip; # max n
+
+ reverse 2; # n max
+ pop; # n
+ dup; # n n
+
+ label skip; # max n
+ dup; # max n n
+ push 2; # max n n 2
+ mod; # max n n%2
+ jumpTrue odd; # max n
+
+ push 2; # max n 2
+ div; # max n/2 -> max n
+ jump start; # max n
+
+ label odd; # max n
+ push 3; # max n 3
+ mult; # max 3*n
+ push 1; # max 3*n 1
+ add; # max 3*n+1
+
+ label start; # max n
+ dup; # max n n
+ push 1; # max n n 1
+ neq; # max n n>1
+ jumpTrue loop; # max n
+
+ pop; # max
+ }
+ }} 1
+ }
+} 0
+test assemble-51.4 {memory leak testing} memory {
+ leaktest {
+ catch {
+ apply {{} {
+ assemble {reverse polish notation}
+ }}
+ }
+ }
+} 0
+
+rename fillTables {}
+rename assemble {}
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/assemble1.bench b/library/msgcat/tests/assemble1.bench
new file mode 100644
index 0000000..18fd3a9
--- /dev/null
+++ b/library/msgcat/tests/assemble1.bench
@@ -0,0 +1,85 @@
+proc ulam1 {n} {
+ set max $n
+ while {$n != 1} {
+ if {$n > $max} {
+ set max $n
+ }
+ if {$n % 2} {
+ set n [expr {3 * $n + 1}]
+ } else {
+ set n [expr {$n / 2}]
+ }
+ }
+ return $max
+}
+
+set tcl_traceCompile 2; ulam1 1; set tcl_traceCompile 0
+
+proc ulam2 {n} {
+ tcl::unsupported::assemble {
+ load n; # max
+ dup; # max n
+ jump start; # max n
+
+ label loop; # max n
+ over 1; # max n max
+ over 1; # max in max n
+ ge; # man n max>=n
+ jumpTrue skip; # max n
+
+ reverse 2; # n max
+ pop; # n
+ dup; # n n
+
+ label skip; # max n
+ dup; # max n n
+ push 2; # max n n 2
+ mod; # max n n%2
+ jumpTrue odd; # max n
+
+ push 2; # max n 2
+ div; # max n/2 -> max n
+ jump start; # max n
+
+ label odd; # max n
+ push 3; # max n 3
+ mult; # max 3*n
+ push 1; # max 3*n 1
+ add; # max 3*n+1
+
+ label start; # max n
+ dup; # max n n
+ push 1; # max n n 1
+ neq; # max n n>1
+ jumpTrue loop; # max n
+
+ pop; # max
+ }
+}
+set tcl_traceCompile 2; ulam2 1; set tcl_traceCompile 0
+
+proc test1 {n} {
+ for {set i 1} {$i <= $n} {incr i} {
+ ulam1 $i
+ }
+}
+proc test2 {n} {
+ for {set i 1} {$i <= $n} {incr i} {
+ ulam2 $i
+ }
+}
+
+for {set j 0} {$j < 10} {incr j} {
+ test1 1
+ set before [clock microseconds]
+ test1 30000
+ set after [clock microseconds]
+ puts "compiled: [expr {1e-6 * ($after - $before)}]"
+
+ test2 1
+ set before [clock microseconds]
+ test2 30000
+ set after [clock microseconds]
+ puts "assembled: [expr {1e-6 * ($after - $before)}]"
+}
+ \ No newline at end of file
diff --git a/library/msgcat/tests/assocd.test b/library/msgcat/tests/assocd.test
new file mode 100644
index 0000000..1ca1c9b
--- /dev/null
+++ b/library/msgcat/tests/assocd.test
@@ -0,0 +1,61 @@
+# This file tests the AssocData facility of Tcl
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testgetassocdata [llength [info commands testgetassocdata]]
+testConstraint testsetassocdata [llength [info commands testsetassocdata]]
+testConstraint testdelassocdata [llength [info commands testdelassocdata]]
+
+test assocd-1.1 {testing setting assoc data} testsetassocdata {
+ testsetassocdata a 1
+} ""
+test assocd-1.2 {testing setting assoc data} testsetassocdata {
+ testsetassocdata a 2
+} ""
+test assocd-1.3 {testing setting assoc data} testsetassocdata {
+ testsetassocdata 123 456
+} ""
+test assocd-1.4 {testing setting assoc data} testsetassocdata {
+ testsetassocdata abc "abc d e f"
+} ""
+
+test assocd-2.1 {testing getting assoc data} testgetassocdata {
+ testgetassocdata a
+} 2
+test assocd-2.2 {testing getting assoc data} testgetassocdata {
+ testgetassocdata 123
+} 456
+test assocd-2.3 {testing getting assoc data} testgetassocdata {
+ testgetassocdata abc
+} {abc d e f}
+test assocd-2.4 {testing getting assoc data} testgetassocdata {
+ testgetassocdata xxx
+} ""
+
+test assocd-3.1 {testing deleting assoc data} testdelassocdata {
+ testdelassocdata a
+} ""
+test assocd-3.2 {testing deleting assoc data} testdelassocdata {
+ testdelassocdata 123
+} ""
+test assocd-3.3 {testing deleting assoc data} testdelassocdata {
+ list [catch {testdelassocdata nonexistent} msg] $msg
+} {0 {}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/async.test b/library/msgcat/tests/async.test
new file mode 100644
index 0000000..35dda88
--- /dev/null
+++ b/library/msgcat/tests/async.test
@@ -0,0 +1,213 @@
+# Commands covered: none
+#
+# This file contains a collection of tests for Tcl_AsyncCreate and related
+# library procedures. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testasync [llength [info commands testasync]]
+testConstraint threaded [::tcl::pkgconfig get threaded]
+
+proc async1 {result code} {
+ global aresult acode
+ set aresult $result
+ set acode $code
+ return "new result"
+}
+proc async2 {result code} {
+ global aresult acode
+ set aresult $result
+ set acode $code
+ return -code error "xyzzy"
+}
+proc async3 {result code} {
+ global aresult
+ set aresult "test pattern"
+ return -code $code $result
+}
+proc \# {result code} {
+ global aresult acode
+ set aresult $result
+ set acode $code
+ return "comment quoting"
+}
+
+if {[testConstraint testasync]} {
+ set handler1 [testasync create async1]
+ set handler2 [testasync create async2]
+ set handler3 [testasync create async3]
+ set handler4 [testasync create \#]
+}
+test async-1.1 {basic async handlers} testasync {
+ set aresult xxx
+ set acode yyy
+ list [catch {testasync mark $handler1 "original" 0} msg] $msg \
+ $acode $aresult
+} {0 {new result} 0 original}
+test async-1.2 {basic async handlers} testasync {
+ set aresult xxx
+ set acode yyy
+ list [catch {testasync mark $handler1 "original" 1} msg] $msg \
+ $acode $aresult
+} {0 {new result} 1 original}
+test async-1.3 {basic async handlers} testasync {
+ set aresult xxx
+ set acode yyy
+ list [catch {testasync mark $handler2 "old" 0} msg] $msg \
+ $acode $aresult
+} {1 xyzzy 0 old}
+test async-1.4 {basic async handlers} testasync {
+ set aresult xxx
+ set acode yyy
+ list [catch {testasync mark $handler2 "old" 3} msg] $msg \
+ $acode $aresult
+} {1 xyzzy 3 old}
+test async-1.5 {basic async handlers} testasync {
+ set aresult xxx
+ list [catch {testasync mark $handler3 "foobar" 0} msg] $msg $aresult
+} {0 foobar {test pattern}}
+test async-1.6 {basic async handlers} testasync {
+ set aresult xxx
+ list [catch {testasync mark $handler3 "foobar" 1} msg] $msg $aresult
+} {1 foobar {test pattern}}
+test async-1.7 {basic async handlers} testasync {
+ set aresult xxx
+ set acode yyy
+ list [catch {testasync mark $handler4 "original" 0} msg] $msg \
+ $acode $aresult
+} {0 {comment quoting} 0 original}
+
+proc mult1 {result code} {
+ global x
+ lappend x mult1
+ return -code 7 mult1
+}
+proc mult2 {result code} {
+ global x
+ lappend x mult2
+ return -code 9 mult2
+}
+proc mult3 {result code} {
+ global x hm1 hm2
+ lappend x [catch {testasync mark $hm2 serial2 0}]
+ lappend x [catch {testasync mark $hm1 serial1 0}]
+ lappend x mult3
+ return -code 11 mult3
+}
+if {[testConstraint testasync]} {
+ set hm1 [testasync create mult1]
+ set hm2 [testasync create mult2]
+ set hm3 [testasync create mult3]
+}
+test async-2.1 {multiple handlers} testasync {
+ set x {}
+ list [catch {testasync mark $hm3 "foobar" 5} msg] $msg $x
+} {9 mult2 {0 0 mult3 mult1 mult2}}
+
+proc del1 {result code} {
+ global x hm1 hm2 hm3 hm4
+ lappend x [catch {testasync mark $hm3 serial2 0}]
+ lappend x [catch {testasync mark $hm1 serial1 0}]
+ lappend x [catch {testasync mark $hm4 serial1 0}]
+ testasync delete $hm1
+ testasync delete $hm2
+ testasync delete $hm3
+ lappend x del1
+ return -code 13 del1
+}
+proc del2 {result code} {
+ global x
+ lappend x del2
+ return -code 3 del2
+}
+if {[testConstraint testasync]} {
+ testasync delete $handler1
+ testasync delete $hm2
+ testasync delete $hm3
+ set hm2 [testasync create del1]
+ set hm3 [testasync create mult2]
+ set hm4 [testasync create del2]
+}
+
+test async-3.1 {deleting handlers} testasync {
+ set x {}
+ list [catch {testasync mark $hm2 "foobar" 5} msg] $msg $x
+} {3 del2 {0 0 0 del1 del2}}
+
+test async-4.1 {async interrupting bytecode sequence} -constraints {
+ testasync threaded
+} -setup {
+ set hm [testasync create async3]
+ proc nothing {} {
+ # empty proc
+ }
+} -body {
+ apply {{handle} {
+ global aresult
+ set aresult {Async event not delivered}
+ testasync marklater $handle
+ for {set i 0} {
+ $i < 2500000 && $aresult eq "Async event not delivered"
+ } {incr i} {
+ nothing
+ }
+ return $aresult
+ }} $hm
+} -result {test pattern} -cleanup {
+ testasync delete $hm
+}
+test async-4.2 {async interrupting straight bytecode sequence} -constraints {
+ testasync threaded
+} -setup {
+ set hm [testasync create async3]
+} -body {
+ apply {{handle} {
+ global aresult
+ set aresult {Async event not delivered}
+ testasync marklater $handle
+ for {set i 0} {
+ $i < 2500000 && $aresult eq "Async event not delivered"
+ } {incr i} {}
+ return $aresult
+ }} $hm
+} -result {test pattern} -cleanup {
+ testasync delete $hm
+}
+test async-4.3 {async interrupting loop-less bytecode sequence} -constraints {
+ testasync threaded
+} -setup {
+ set hm [testasync create async3]
+} -body {
+ apply [list {handle} [concat {
+ global aresult
+ set aresult {Async event not delivered}
+ testasync marklater $handle
+ set i 0
+ } "[string repeat {;incr i;} 1500000]after 10;" {
+ return $aresult
+ }]] $hm
+} -result {test pattern} -cleanup {
+ testasync delete $hm
+}
+
+# cleanup
+if {[testConstraint testasync]} {
+ testasync delete
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/autoMkindex.test b/library/msgcat/tests/autoMkindex.test
new file mode 100644
index 0000000..8f29131
--- /dev/null
+++ b/library/msgcat/tests/autoMkindex.test
@@ -0,0 +1,340 @@
+# Commands covered: auto_mkindex auto_import
+#
+# This file contains tests related to autoloading and generating the
+# autoloading index.
+#
+# Copyright (c) 1998 Lucent Technologies, 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+makeFile {# Test file for:
+# auto_mkindex
+#
+# This file provides example cases for testing the Tcl autoloading facility.
+# Things are much more complicated with namespaces and classes. The
+# "auto_mkindex" facility can no longer be built on top of a simple regular
+# expression parser. It must recognize constructs like this:
+#
+# namespace eval foo {
+# proc test {x y} { ... }
+# namespace eval bar {
+# proc another {args} { ... }
+# }
+# }
+#
+# Note that procedures and itcl class definitions can be nested inside of
+# namespaces.
+#
+# Copyright (c) 1993-1998 Lucent Technologies, Inc.
+
+# This shouldn't cause any problems
+namespace import -force blt::*
+
+# Should be able to handle "proc" definitions, even if they are preceded by
+# white space.
+
+proc normal {x y} {return [expr $x+$y]}
+ proc indented {x y} {return [expr $x+$y]}
+
+#
+# Should be able to handle proc declarations within namespaces, even if they
+# have explicit namespace paths.
+#
+namespace eval buried {
+ proc inside {args} {return "inside: $args"}
+
+ namespace export pub_*
+ proc pub_one {args} {return "one: $args"}
+ proc pub_two {args} {return "two: $args"}
+}
+proc buried::within {args} {return "within: $args"}
+
+namespace eval buried {
+ namespace eval under {
+ proc neath {args} {return "neath: $args"}
+ }
+ namespace eval ::buried {
+ proc relative {args} {return "relative: $args"}
+ proc ::top {args} {return "top: $args"}
+ proc ::buried::explicit {args} {return "explicit: $args"}
+ }
+}
+
+# With proper hooks, we should be able to support other commands that create
+# procedures
+
+proc buried::myproc {name body args} {
+ ::proc $name $body $args
+}
+namespace eval ::buried {
+ proc mycmd1 args {return "mycmd"}
+ myproc mycmd2 args {return "mycmd"}
+}
+::buried::myproc mycmd3 args {return "another"}
+
+proc {buried::my proc} {name body args} {
+ ::proc $name $body $args
+}
+namespace eval ::buried {
+ proc mycmd4 args {return "mycmd"}
+ {my proc} mycmd5 args {return "mycmd"}
+}
+{::buried::my proc} mycmd6 args {return "another"}
+
+# A correctly functioning [auto_import] won't choke when a child namespace
+# [namespace import]s from its parent.
+#
+namespace eval ::parent::child {
+ namespace import ::parent::*
+}
+proc ::parent::child::test {} {}
+} autoMkindex.tcl
+
+# Save initial state of auto_mkindex_parser
+
+auto_load auto_mkindex
+if {[info exists auto_mkindex_parser::initCommands]} {
+ set saveCommands $auto_mkindex_parser::initCommands
+}
+proc AutoMkindexTestReset {} {
+ global saveCommands
+ if {[info exists saveCommands]} {
+ set auto_mkindex_parser::initCommands $saveCommands
+ } elseif {[info exists auto_mkindex_parser::initCommands]} {
+ unset auto_mkindex_parser::initCommands
+ }
+}
+
+set result ""
+
+set origDir [pwd]
+cd $::tcltest::temporaryDirectory
+
+test autoMkindex-1.1 {remove any existing tclIndex file} {
+ file delete tclIndex
+ file exists tclIndex
+} {0}
+test autoMkindex-1.2 {build tclIndex based on a test file} {
+ auto_mkindex . autoMkindex.tcl
+ file exists tclIndex
+} {1}
+set element "{source [file join . autoMkindex.tcl]}"
+test autoMkindex-1.3 {examine tclIndex} -setup {
+ file delete tclIndex
+} -body {
+ auto_mkindex . autoMkindex.tcl
+ namespace eval tcl_autoMkindex_tmp {
+ set dir "."
+ variable auto_index
+ source tclIndex
+ set ::result ""
+ foreach elem [lsort [array names auto_index]] {
+ lappend ::result [list $elem $auto_index($elem)]
+ }
+ }
+ return $result
+} -cleanup {
+ namespace delete tcl_autoMkindex_tmp
+} -result "{::buried::explicit $element} {::buried::inside $element} {{::buried::my proc} $element} {::buried::mycmd1 $element} {::buried::mycmd4 $element} {::buried::myproc $element} {::buried::pub_one $element} {::buried::pub_two $element} {::buried::relative $element} {::buried::under::neath $element} {::buried::within $element} {::parent::child::test $element} {indented $element} {normal $element} {top $element}"
+
+test autoMkindex-2.1 {commands on the autoload path can be imported} -setup {
+ file delete tclIndex
+ interp create slave
+} -body {
+ auto_mkindex . autoMkindex.tcl
+ slave eval {
+ namespace eval blt {}
+ set auto_path [linsert $auto_path 0 .]
+ set info [list [catch {namespace import buried::*} result] $result]
+ foreach name [lsort [info commands pub_*]] {
+ lappend info $name [namespace origin $name]
+ }
+ return $info
+ }
+} -cleanup {
+ interp delete slave
+} -result "0 {} pub_one ::buried::pub_one pub_two ::buried::pub_two"
+
+# Test auto_mkindex hooks
+
+# Slave hook executes interesting code in the interp used to watch code.
+test autoMkindex-3.1 {slaveHook} -setup {
+ file delete tclIndex
+} -body {
+ auto_mkindex_parser::slavehook {
+ _%@namespace eval ::blt {
+ proc foo {} {}
+ _%@namespace export foo
+ }
+ }
+ auto_mkindex_parser::slavehook { _%@namespace import -force ::blt::* }
+ auto_mkindex . autoMkindex.tcl
+ file exists tclIndex
+} -cleanup {
+ # Reset initCommands to avoid trashing other tests
+ AutoMkindexTestReset
+} -result 1
+# The auto_mkindex_parser::command is used to register commands that create
+# new commands.
+test autoMkindex-3.2 {auto_mkindex_parser::command} -setup {
+ file delete tclIndex
+} -body {
+ auto_mkindex_parser::command buried::myproc {name args} {
+ variable index
+ variable scriptFile
+ append index [list set auto_index([fullname $name])] \
+ " \[list source \[file join \$dir [list $scriptFile]\]\]\n"
+ }
+ auto_mkindex . autoMkindex.tcl
+ namespace eval tcl_autoMkindex_tmp {
+ set dir "."
+ variable auto_index
+ source tclIndex
+ set ::result ""
+ foreach elem [lsort [array names auto_index]] {
+ lappend ::result [list $elem $auto_index($elem)]
+ }
+ return $::result
+ }
+} -cleanup {
+ namespace delete tcl_autoMkindex_tmp
+ # Reset initCommands to avoid trashing other tests
+ AutoMkindexTestReset
+} -result "{::buried::explicit $element} {::buried::inside $element} {{::buried::my proc} $element} {::buried::mycmd1 $element} {::buried::mycmd2 $element} {::buried::mycmd4 $element} {::buried::myproc $element} {::buried::pub_one $element} {::buried::pub_two $element} {::buried::relative $element} {::buried::under::neath $element} {::buried::within $element} {::parent::child::test $element} {indented $element} {mycmd3 $element} {normal $element} {top $element}"
+test autoMkindex-3.3 {auto_mkindex_parser::command} -setup {
+ file delete tclIndex
+} -constraints {knownBug} -body {
+ auto_mkindex_parser::command {buried::my proc} {name args} {
+ variable index
+ variable scriptFile
+ puts "my proc $name"
+ append index [list set auto_index([fullname $name])] \
+ " \[list source \[file join \$dir [list $scriptFile]\]\]\n"
+ }
+ auto_mkindex . autoMkindex.tcl
+ namespace eval tcl_autoMkindex_tmp {
+ set dir "."
+ variable auto_index
+ source tclIndex
+ set ::result ""
+ foreach elem [lsort [array names auto_index]] {
+ lappend ::result [list $elem $auto_index($elem)]
+ }
+ }
+ list [lsearch -inline $::result *mycmd4*] \
+ [lsearch -inline $::result *mycmd5*] \
+ [lsearch -inline $::result *mycmd6*]
+} -cleanup {
+ namespace delete tcl_autoMkindex_tmp
+ # Reset initCommands to avoid trashing other tests
+ AutoMkindexTestReset
+} -result "{::buried::mycmd4 $element} {::buried::mycmd5 $element} {mycmd6 $element}"
+
+test autoMkindex-4.1 {platform independent source commands} -setup {
+ file delete tclIndex
+ makeDirectory pkg
+ makeFile {
+ package provide football 1.0
+ namespace eval ::pro:: {
+ #
+ # export only public functions.
+ #
+ namespace export {[a-z]*}
+ }
+ namespace eval ::college:: {
+ #
+ # export only public functions.
+ #
+ namespace export {[a-z]*}
+ }
+ proc ::pro::team {} {
+ puts "go packers!"
+ return true
+ }
+ proc ::college::team {} {
+ puts "go badgers!"
+ return true
+ }
+ } [file join pkg samename.tcl]
+} -body {
+ auto_mkindex . pkg/samename.tcl
+ set f [open tclIndex r]
+ lsort [lrange [split [string trim [read $f]] "\n"] end-1 end]
+} -cleanup {
+ catch {close $f}
+ removeFile [file join pkg samename.tcl]
+ removeDirectory pkg
+} -result {{set auto_index(::college::team) [list source [file join $dir pkg samename.tcl]]} {set auto_index(::pro::team) [list source [file join $dir pkg samename.tcl]]}}
+
+test autoMkindex-5.1 {escape magic tcl chars in general code} -setup {
+ file delete tclIndex
+ makeDirectory pkg
+ makeFile {
+ set dollar1 "this string contains an unescaped dollar sign -> \\$foo"
+ set dollar2 \
+ "this string contains an escaped dollar sign -> \$foo \\\$foo"
+ set bracket1 "this contains an unescaped bracket [NoSuchProc]"
+ set bracket2 "this contains an escaped bracket \[NoSuchProc\]"
+ set bracket3 \
+ "this contains nested unescaped brackets [[NoSuchProc]]"
+ proc testProc {} {}
+ } [file join pkg magicchar.tcl]
+ set result {}
+} -body {
+ auto_mkindex . pkg/magicchar.tcl
+ set f [open tclIndex r]
+ lindex [split [string trim [read $f]] "\n"] end
+} -cleanup {
+ catch {close $f}
+ removeFile [file join pkg magicchar.tcl]
+ removeDirectory pkg
+} -result {set auto_index(testProc) [list source [file join $dir pkg magicchar.tcl]]}
+test autoMkindex-5.2 {correctly locate auto loaded procs with []} -setup {
+ file delete tclIndex
+ makeDirectory pkg
+ makeFile {
+ proc {[magic mojo proc]} {} {}
+ } [file join pkg magicchar2.tcl]
+ set result {}
+ interp create slave
+} -body {
+ auto_mkindex . pkg/magicchar2.tcl
+ # Make a slave interp to test the autoloading
+ slave eval {lappend auto_path [pwd]}
+ slave eval {catch {{[magic mojo proc]}}}
+} -cleanup {
+ interp delete slave
+ removeFile [file join pkg magicchar2.tcl]
+ removeDirectory pkg
+} -result 0
+
+# Clean up.
+
+unset result
+AutoMkindexTestReset
+if {[info exists saveCommands]} {
+ unset saveCommands
+}
+rename AutoMkindexTestReset ""
+
+removeFile autoMkindex.tcl
+if {[file exists tclIndex]} {
+ file delete -force tclIndex
+}
+
+cd $origDir
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/basic.test b/library/msgcat/tests/basic.test
new file mode 100644
index 0000000..e072bea
--- /dev/null
+++ b/library/msgcat/tests/basic.test
@@ -0,0 +1,974 @@
+# This file contains tests for the tclBasic.c source file. Tests appear in
+# the same order as the C code that they test. The set of tests is
+# currently incomplete since it currently includes only new tests for
+# code changed for the addition of Tcl namespaces. Other variable-
+# related tests appear in several other test files including
+# assocd.test, cmdInfo.test, eval.test, expr.test, interp.test,
+# and trace.test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+testConstraint testevalex [llength [info commands testevalex]]
+testConstraint testcmdtoken [llength [info commands testcmdtoken]]
+testConstraint testcreatecommand [llength [info commands testcreatecommand]]
+testConstraint exec [llength [info commands exec]]
+
+catch {namespace delete test_ns_basic}
+catch {interp delete test_interp}
+catch {rename p ""}
+catch {rename q ""}
+catch {rename cmd ""}
+catch {unset x}
+
+test basic-1.1 {Tcl_CreateInterp, creates interp's global namespace} {
+ catch {interp delete test_interp}
+ interp create test_interp
+ interp eval test_interp {
+ namespace eval test_ns_basic {
+ proc p {} {
+ return [namespace current]
+ }
+ }
+ }
+ list [interp eval test_interp {test_ns_basic::p}] \
+ [interp delete test_interp]
+} {::test_ns_basic {}}
+
+test basic-2.1 {TclHideUnsafeCommands} {emptyTest} {
+} {}
+
+test basic-3.1 {Tcl_CallWhenDeleted: see dcall.test} {emptyTest} {
+} {}
+
+test basic-4.1 {Tcl_DontCallWhenDeleted: see dcall.test} {emptyTest} {
+} {}
+
+test basic-5.1 {Tcl_SetAssocData: see assoc.test} {emptyTest} {
+} {}
+
+test basic-6.1 {Tcl_DeleteAssocData: see assoc.test} {emptyTest} {
+} {}
+
+test basic-7.1 {Tcl_GetAssocData: see assoc.test} {emptyTest} {
+} {}
+
+test basic-8.1 {Tcl_InterpDeleted} {emptyTest} {
+} {}
+
+test basic-9.1 {Tcl_DeleteInterp: see interp.test} {emptyTest} {
+} {}
+
+test basic-10.1 {DeleteInterpProc, destroys interp's global namespace} {
+ catch {interp delete test_interp}
+ interp create test_interp
+ interp eval test_interp {
+ namespace eval test_ns_basic {
+ namespace export p
+ proc p {} {
+ return [namespace current]
+ }
+ }
+ namespace eval test_ns_2 {
+ namespace import ::test_ns_basic::p
+ variable v 27
+ proc q {} {
+ variable v
+ return "[p] $v"
+ }
+ }
+ }
+ list [interp eval test_interp {test_ns_2::q}] \
+ [interp eval test_interp {namespace delete ::}] \
+ [catch {interp eval test_interp {set a 123}} msg] $msg \
+ [interp delete test_interp]
+} {{::test_ns_basic 27} {} 1 {invalid command name "set"} {}}
+
+test basic-11.1 {HiddenCmdsDeleteProc, invalidate cached refs to deleted hidden cmd} {
+ catch {interp delete test_interp}
+ interp create test_interp
+ interp eval test_interp {
+ proc p {} {
+ return 27
+ }
+ }
+ interp alias {} localP test_interp p
+ list [interp eval test_interp {p}] \
+ [localP] \
+ [test_interp hide p] \
+ [catch {localP} msg] $msg \
+ [interp delete test_interp] \
+ [catch {localP} msg] $msg
+} {27 27 {} 1 {invalid command name "p"} {} 1 {invalid command name "localP"}}
+
+# NB: More tests about hide/expose are found in interp.test
+
+test basic-12.1 {Tcl_HideCommand, names of hidden cmds can't have namespace qualifiers} {
+ catch {interp delete test_interp}
+ interp create test_interp
+ interp eval test_interp {
+ namespace eval test_ns_basic {
+ proc p {} {
+ return [namespace current]
+ }
+ }
+ }
+ list [catch {test_interp hide test_ns_basic::p x} msg] $msg \
+ [catch {test_interp hide x test_ns_basic::p} msg1] $msg1 \
+ [interp delete test_interp]
+} {1 {can only hide global namespace commands (use rename then hide)} 1 {cannot use namespace qualifiers in hidden command token (rename)} {}}
+
+test basic-12.2 {Tcl_HideCommand, a hidden cmd remembers its containing namespace} {
+ catch {namespace delete test_ns_basic}
+ catch {rename cmd ""}
+ proc cmd {} { ;# note that this is global
+ return [namespace current]
+ }
+ namespace eval test_ns_basic {
+ proc hideCmd {} {
+ interp hide {} cmd
+ }
+ proc exposeCmd {} {
+ interp expose {} cmd
+ }
+ proc callCmd {} {
+ cmd
+ }
+ }
+ list [test_ns_basic::callCmd] \
+ [test_ns_basic::hideCmd] \
+ [catch {cmd} msg] $msg \
+ [test_ns_basic::exposeCmd] \
+ [test_ns_basic::callCmd] \
+ [namespace delete test_ns_basic]
+} {:: {} 1 {invalid command name "cmd"} {} :: {}}
+
+test basic-13.1 {Tcl_ExposeCommand, a command stays in the global namespace and cannot go to another namespace} {
+ catch {namespace delete test_ns_basic}
+ catch {rename cmd ""}
+ proc cmd {} { ;# note that this is global
+ return [namespace current]
+ }
+ namespace eval test_ns_basic {
+ proc hideCmd {} {
+ interp hide {} cmd
+ }
+ proc exposeCmdFailing {} {
+ interp expose {} cmd ::test_ns_basic::newCmd
+ }
+ proc exposeCmdWorkAround {} {
+ interp expose {} cmd;
+ rename cmd ::test_ns_basic::newCmd;
+ }
+ proc callCmd {} {
+ cmd
+ }
+ }
+ list [test_ns_basic::callCmd] \
+ [test_ns_basic::hideCmd] \
+ [catch {test_ns_basic::exposeCmdFailing} msg] $msg \
+ [test_ns_basic::exposeCmdWorkAround] \
+ [test_ns_basic::newCmd] \
+ [namespace delete test_ns_basic]
+} {:: {} 1 {cannot expose to a namespace (use expose to toplevel, then rename)} {} ::test_ns_basic {}}
+test basic-13.2 {Tcl_ExposeCommand, invalidate cached refs to cmd now being exposed} {
+ catch {rename p ""}
+ catch {rename cmd ""}
+ proc p {} {
+ cmd
+ }
+ proc cmd {} {
+ return 42
+ }
+ list [p] \
+ [interp hide {} cmd] \
+ [proc cmd {} {return Hello}] \
+ [cmd] \
+ [rename cmd ""] \
+ [interp expose {} cmd] \
+ [p]
+} {42 {} {} Hello {} {} 42}
+
+test basic-14.1 {Tcl_CreateCommand, new cmd goes into a namespace specified in its name, if any} {testcreatecommand} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [testcreatecommand create] \
+ [test_ns_basic::createdcommand] \
+ [testcreatecommand delete]
+} {{} {CreatedCommandProc in ::test_ns_basic} {}}
+test basic-14.2 {Tcl_CreateCommand, namespace code ignore single ":"s in middle or end of names} {testcreatecommand} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename value:at: ""}
+ list [testcreatecommand create2] \
+ [value:at:] \
+ [testcreatecommand delete2]
+} {{} {CreatedCommandProc2 in ::} {}}
+
+test basic-15.1 {Tcl_CreateObjCommand, new cmd goes into a namespace specified in its name, if any} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_basic {}
+ proc test_ns_basic::cmd {} { ;# proc requires that ns already exist
+ return [namespace current]
+ }
+ list [test_ns_basic::cmd] \
+ [namespace delete test_ns_basic]
+} {::test_ns_basic {}}
+
+test basic-16.1 {TclInvokeStringCommand} {emptyTest} {
+} {}
+
+test basic-17.1 {TclInvokeObjCommand} {emptyTest} {
+} {}
+
+test basic-18.1 {TclRenameCommand, name of existing cmd can have namespace qualifiers} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename cmd ""}
+ namespace eval test_ns_basic {
+ proc p {} {
+ return "p in [namespace current]"
+ }
+ }
+ list [test_ns_basic::p] \
+ [rename test_ns_basic::p test_ns_basic::q] \
+ [test_ns_basic::q]
+} {{p in ::test_ns_basic} {} {p in ::test_ns_basic}}
+test basic-18.2 {TclRenameCommand, existing cmd must be found} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {rename test_ns_basic::p test_ns_basic::q} msg] $msg
+} {1 {can't rename "test_ns_basic::p": command doesn't exist}}
+test basic-18.3 {TclRenameCommand, delete cmd if new name is empty} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_basic {
+ proc p {} {
+ return "p in [namespace current]"
+ }
+ }
+ list [info commands test_ns_basic::*] \
+ [rename test_ns_basic::p ""] \
+ [info commands test_ns_basic::*]
+} {::test_ns_basic::p {} {}}
+test basic-18.4 {TclRenameCommand, bad new name} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_basic {
+ proc p {} {
+ return "p in [namespace current]"
+ }
+ }
+ rename test_ns_basic::p :::george::martha
+} {}
+test basic-18.5 {TclRenameCommand, new name must not already exist} {
+ namespace eval test_ns_basic {
+ proc q {} {
+ return 42
+ }
+ }
+ list [catch {rename test_ns_basic::q :::george::martha} msg] $msg
+} {1 {can't rename to ":::george::martha": command already exists}}
+test basic-18.6 {TclRenameCommand, check for command shadowing by newly renamed cmd} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename p ""}
+ catch {rename q ""}
+ proc p {} {
+ return "p in [namespace current]"
+ }
+ proc q {} {
+ return "q in [namespace current]"
+ }
+ namespace eval test_ns_basic {
+ proc callP {} {
+ p
+ }
+ }
+ list [test_ns_basic::callP] \
+ [rename q test_ns_basic::p] \
+ [test_ns_basic::callP]
+} {{p in ::} {} {q in ::test_ns_basic}}
+
+test basic-19.1 {Tcl_SetCommandInfo} {emptyTest} {
+} {}
+
+test basic-20.1 {Tcl_GetCommandInfo, names for commands created inside namespaces} {testcmdtoken} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename p ""}
+ catch {rename q ""}
+ catch {unset x}
+ set x [namespace eval test_ns_basic::test_ns_basic2 {
+ # the following creates a cmd in the global namespace
+ testcmdtoken create p
+ }]
+ list [testcmdtoken name $x] \
+ [rename ::p q] \
+ [testcmdtoken name $x]
+} {{p ::p} {} {q ::q}}
+test basic-20.2 {Tcl_GetCommandInfo, names for commands created outside namespaces} {testcmdtoken} {
+ catch {rename q ""}
+ set x [testcmdtoken create test_ns_basic::test_ns_basic2::p]
+ list [testcmdtoken name $x] \
+ [rename test_ns_basic::test_ns_basic2::p q] \
+ [testcmdtoken name $x]
+} {{p ::test_ns_basic::test_ns_basic2::p} {} {q ::q}}
+test basic-20.3 {Tcl_GetCommandInfo, #-quoting} testcmdtoken {
+ catch {rename \# ""}
+ set x [testcmdtoken create \#]
+ testcmdtoken name $x
+} {{#} ::#}
+
+test basic-21.1 {Tcl_GetCommandName} {emptyTest} {
+} {}
+
+test basic-22.1 {Tcl_GetCommandFullName} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_basic1 {
+ namespace export cmd*
+ proc cmd1 {} {}
+ proc cmd2 {} {}
+ }
+ namespace eval test_ns_basic2 {
+ namespace export *
+ namespace import ::test_ns_basic1::*
+ proc p {} {}
+ }
+ namespace eval test_ns_basic3 {
+ namespace import ::test_ns_basic2::*
+ proc q {} {}
+ list [namespace which -command foreach] \
+ [namespace which -command q] \
+ [namespace which -command p] \
+ [namespace which -command cmd1] \
+ [namespace which -command ::test_ns_basic2::cmd2]
+ }
+} {::foreach ::test_ns_basic3::q ::test_ns_basic3::p ::test_ns_basic3::cmd1 ::test_ns_basic2::cmd2}
+
+test basic-23.1 {Tcl_DeleteCommand} {emptyTest} {
+} {}
+
+test basic-24.1 {Tcl_DeleteCommandFromToken, invalidate all compiled code if cmd has compile proc} {
+ catch {interp delete test_interp}
+ catch {unset x}
+ interp create test_interp
+ interp eval test_interp {
+ proc useSet {} {
+ return [set a 123]
+ }
+ }
+ set x [interp eval test_interp {useSet}]
+ interp eval test_interp {
+ rename set ""
+ proc set {args} {
+ return "set called with $args"
+ }
+ }
+ list $x \
+ [interp eval test_interp {useSet}] \
+ [interp delete test_interp]
+} {123 {set called with a 123} {}}
+test basic-24.2 {Tcl_DeleteCommandFromToken, deleting commands changes command epoch} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename p ""}
+ proc p {} {
+ return "global p"
+ }
+ namespace eval test_ns_basic {
+ proc p {} {
+ return "namespace p"
+ }
+ proc callP {} {
+ p
+ }
+ }
+ list [test_ns_basic::callP] \
+ [rename test_ns_basic::p ""] \
+ [test_ns_basic::callP]
+} {{namespace p} {} {global p}}
+test basic-24.3 {Tcl_DeleteCommandFromToken, delete imported cmds that refer to a deleted cmd} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename p ""}
+ namespace eval test_ns_basic {
+ namespace export p
+ proc p {} {return 42}
+ }
+ namespace eval test_ns_basic2 {
+ namespace import ::test_ns_basic::*
+ proc callP {} {
+ p
+ }
+ }
+ list [test_ns_basic2::callP] \
+ [info commands test_ns_basic2::*] \
+ [rename test_ns_basic::p ""] \
+ [catch {test_ns_basic2::callP} msg] $msg \
+ [info commands test_ns_basic2::*]
+} {42 {::test_ns_basic2::callP ::test_ns_basic2::p} {} 1 {invalid command name "p"} ::test_ns_basic2::callP}
+
+test basic-25.1 {TclCleanupCommand} {emptyTest} {
+} {}
+
+test basic-26.1 {Tcl_EvalObj: preserve object while evaling it} -setup {
+ proc myHandler {msg options} {
+ set ::x [dict get $options -errorinfo]
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+ set fName [makeFile {} test1]
+} -body {
+ # If object isn't preserved, errorInfo would be set to
+ # "foo\n while executing\n\"garbage bytes\"" because the object's
+ # string would have been freed, leaving garbage bytes for the error
+ # message.
+ set f [open $fName w]
+ fileevent $f writable "fileevent $f writable {}; error foo"
+ set x {}
+ vwait x
+ close $f
+ set x
+} -cleanup {
+ removeFile test1
+ interp bgerror {} $handler
+ rename myHandler {}
+} -result "foo\n while executing\n\"error foo\""
+
+test basic-26.2 {Tcl_EvalObjEx, pure-list branch: preserve "objv"} -body {
+ #
+ # Follow the pure-list branch in a manner that
+ # a - the pure-list internal rep is destroyed by shimmering
+ # b - the command returns an error
+ # As the error code in Tcl_EvalObjv accesses the list elements, this will
+ # cause a segfault if [Bug 1119369] has not been fixed.
+ # NOTE: a MEM_DEBUG build may be necessary to guarantee the segfault.
+ #
+
+ set SRC [list foo 1] ;# pure-list command
+ proc foo str {
+ # Shimmer pure-list to cmdName, cleanup and error
+ proc $::SRC {} {}; $::SRC
+ error "BAD CALL"
+ }
+ catch {eval $SRC}
+} -result 1 -cleanup {
+ rename foo {}
+ rename $::SRC {}
+ unset ::SRC
+}
+
+test basic-26.3 {Tcl_EvalObjEx, pure-list branch: preserve "objv"} -body {
+ #
+ # Follow the pure-list branch in a manner that
+ # a - the pure-list internal rep is destroyed by shimmering
+ # b - the command accesses its command line
+ # This will cause a segfault if [Bug 1119369] has not been fixed.
+ # NOTE: a MEM_DEBUG build may be necessary to guarantee the segfault.
+ #
+
+ set SRC [list foo 1] ;# pure-list command
+ proc foo str {
+ # Shimmer pure-list to cmdName, cleanup and error
+ proc $::SRC {} {}; $::SRC
+ info level 0
+ }
+ catch {eval $SRC}
+} -result 0 -cleanup {
+ rename foo {}
+ rename $::SRC {}
+ unset ::SRC
+}
+
+test basic-27.1 {Tcl_ExprLong} {emptyTest} {
+} {}
+
+test basic-28.1 {Tcl_ExprDouble} {emptyTest} {
+} {}
+
+test basic-29.1 {Tcl_ExprBoolean} {emptyTest} {
+} {}
+
+test basic-30.1 {Tcl_ExprLongObj} {emptyTest} {
+} {}
+
+test basic-31.1 {Tcl_ExprDoubleObj} {emptyTest} {
+} {}
+
+test basic-32.1 {Tcl_ExprBooleanObj} {emptyTest} {
+} {}
+
+test basic-36.1 {Tcl_EvalObjv, lookup of "unknown" command} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {interp delete test_interp}
+ interp create test_interp
+ interp eval test_interp {
+ proc unknown {args} {
+ return "global unknown"
+ }
+ namespace eval test_ns_basic {
+ proc unknown {args} {
+ return "namespace unknown"
+ }
+ }
+ }
+ list [interp alias test_interp newAlias test_interp doesntExist] \
+ [catch {interp eval test_interp {newAlias}} msg] $msg \
+ [interp delete test_interp]
+} {newAlias 0 {global unknown} {}}
+
+test basic-37.1 {Tcl_ExprString: see expr.test} {emptyTest} {
+} {}
+
+test basic-38.1 {Tcl_ExprObj} {emptyTest} {
+} {}
+
+# Tests basic-39.* and basic-40.* refactored into trace.test
+
+test basic-41.1 {Tcl_AddErrorInfo} {emptyTest} {
+} {}
+
+test basic-42.1 {Tcl_AddObjErrorInfo} {emptyTest} {
+} {}
+
+test basic-43.1 {Tcl_VarEval} {emptyTest} {
+} {}
+
+test basic-44.1 {Tcl_GlobalEval} {emptyTest} {
+} {}
+
+test basic-45.1 {Tcl_SetRecursionLimit: see interp.test} {emptyTest} {
+} {}
+
+test basic-46.1 {Tcl_AllowExceptions: exception return not allowed} {stdio} {
+ catch {close $f}
+ set res [catch {
+ set f [open |[list [interpreter]] w+]
+ fconfigure $f -buffering line
+ puts $f {fconfigure stdout -buffering line}
+ puts $f continue
+ puts $f {puts $::errorInfo}
+ puts $f {puts DONE}
+ set newMsg {}
+ set msg {}
+ while {$newMsg != "DONE"} {
+ set newMsg [gets $f]
+ append msg "${newMsg}\n"
+ }
+ close $f
+ } error]
+ list $res $msg
+} {1 {invoked "continue" outside of a loop
+ while executing
+"continue"
+DONE
+}}
+
+test basic-46.2 {Tcl_AllowExceptions: exception return not allowed} -setup {
+ set fName [makeFile {
+ puts hello
+ break
+ } BREAKtest]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $fName
+} -cleanup {
+ removeFile BREAKtest
+} -returnCodes error -match glob -result {hello
+invoked "break" outside of a loop
+ while executing
+"break"
+ (file "*BREAKtest" line 3)}
+
+test basic-46.3 {Tcl_AllowExceptions: exception return not allowed} -setup {
+ set fName [makeFile {
+ interp alias {} patch {} info patchlevel
+ patch
+ break
+ } BREAKtest]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $fName
+} -cleanup {
+ removeFile BREAKtest
+} -returnCodes error -match glob -result {invoked "break" outside of a loop
+ while executing
+"break"
+ (file "*BREAKtest" line 4)}
+
+test basic-46.4 {Tcl_AllowExceptions: exception return not allowed} -setup {
+ set fName [makeFile {
+ foo [set a 1] [break]
+ } BREAKtest]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $fName
+} -cleanup {
+ removeFile BREAKtest
+} -returnCodes error -match glob -result {invoked "break" outside of a loop
+ while executing*
+"foo \[set a 1] \[break]"
+ (file "*BREAKtest" line 2)}
+
+test basic-46.5 {Tcl_AllowExceptions: exception return not allowed} -setup {
+ set fName [makeFile {
+ return -code return
+ } BREAKtest]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $fName
+} -cleanup {
+ removeFile BREAKtest
+} -returnCodes error -match glob -result {command returned bad code: 2
+ while executing
+"return -code return"
+ (file "*BREAKtest" line 2)}
+
+test basic-47.1 {Tcl_EvalEx: check for missing close-bracket} -constraints {
+ testevalex
+} -body {
+ testevalex {a[set b [format cd]}
+} -returnCodes error -result {missing close-bracket}
+
+# Some lists for expansion tests to work with
+set l1 [list a {b b} c d]
+set l2 [list e f {g g} h]
+proc l3 {} {
+ list i j k {l l}
+}
+
+# Do all tests once byte compiled and once with direct string evaluation
+for {set noComp 0} {$noComp <= 1} {incr noComp} {
+
+if $noComp {
+ interp alias {} run {} testevalex
+ set constraints testevalex
+} else {
+ interp alias {} run {} if 1
+ set constraints {}
+}
+
+test basic-47.2.$noComp {Tcl_EvalEx: error during word expansion} -body {
+ run {{*}\{}
+} -constraints $constraints -returnCodes error -result {unmatched open brace in list}
+
+test basic-47.3.$noComp {Tcl_EvalEx, error during substitution} -body {
+ run {{*}[error foo]}
+} -constraints $constraints -returnCodes error -result foo
+
+test basic-47.4.$noComp {Tcl_EvalEx: no expansion} $constraints {
+ run {list {*} {*} {*}}
+} {* * *}
+
+test basic-47.5.$noComp {Tcl_EvalEx: expansion} $constraints {
+ run {list {*}{} {*} {*}x {*}"y z"}
+} {* x y z}
+
+test basic-47.6.$noComp {Tcl_EvalEx: expansion to zero args} $constraints {
+ run {list {*}{}}
+} {}
+
+test basic-47.7.$noComp {Tcl_EvalEx: expansion to one arg} $constraints {
+ run {list {*}x}
+} x
+
+test basic-47.8.$noComp {Tcl_EvalEx: expansion to many args} $constraints {
+ run {list {*}"y z"}
+} {y z}
+
+test basic-47.9.$noComp {Tcl_EvalEx: expansion and subst order} $constraints {
+ set x 0
+ run {list [incr x] {*}[incr x] [incr x] \
+ {*}[list [incr x] [incr x]] [incr x]}
+} {1 2 3 4 5 6}
+
+test basic-47.10.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+ run {concat {*}{} a b c d e f g h i j k l m n o p q r}
+} {a b c d e f g h i j k l m n o p q r}
+
+test basic-47.11.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+ run {concat {*}1 a b c d e f g h i j k l m n o p q r}
+} {1 a b c d e f g h i j k l m n o p q r}
+
+test basic-47.12.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+ run {concat {*}{1 2} a b c d e f g h i j k l m n o p q r}
+} {1 2 a b c d e f g h i j k l m n o p q r}
+
+test basic-47.13.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+ run {concat {*}{} {*}{1 2} a b c d e f g h i j k l m n o p q}
+} {1 2 a b c d e f g h i j k l m n o p q}
+
+test basic-47.14.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+ run {concat {*}{} a b c d e f g h i j k l m n o p q r s}
+} {a b c d e f g h i j k l m n o p q r s}
+
+test basic-47.15.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+ run {concat {*}1 a b c d e f g h i j k l m n o p q r s}
+} {1 a b c d e f g h i j k l m n o p q r s}
+
+test basic-47.16.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+ run {concat {*}{1 2} a b c d e f g h i j k l m n o p q r s}
+} {1 2 a b c d e f g h i j k l m n o p q r s}
+
+test basic-47.17.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+ run {concat {*}{} {*}{1 2} a b c d e f g h i j k l m n o p q r}
+} {1 2 a b c d e f g h i j k l m n o p q r}
+
+test basic-48.1.$noComp {expansion: parsing} $constraints {
+ run { # A comment
+
+ # Another comment
+ list 1 2\
+ 3 {*}$::l1
+
+ # Comment again
+ }
+} {1 2 3 a {b b} c d}
+
+test basic-48.2.$noComp {no expansion} $constraints {
+ run {list $::l1 $::l2 [l3]}
+} {{a {b b} c d} {e f {g g} h} {i j k {l l}}}
+
+test basic-48.3.$noComp {expansion} $constraints {
+ run {list {*}$::l1 $::l2 {*}[l3]}
+} {a {b b} c d {e f {g g} h} i j k {l l}}
+
+test basic-48.4.$noComp {expansion: really long cmd} $constraints {
+ set cmd [list list]
+ for {set t 0} {$t < 500} {incr t} {
+ lappend cmd {{*}$::l1}
+ }
+ llength [run [join $cmd]]
+} 2000
+
+test basic-48.5.$noComp {expansion: error detection} -setup {
+ set l "a {a b}x y"
+} -constraints $constraints -body {
+ run {list $::l1 {*}$l}
+} -cleanup {
+ unset l
+} -returnCodes 1 -result {list element in braces followed by "x" instead of space}
+
+test basic-48.6.$noComp {expansion: odd usage} $constraints {
+ run {list {*}$::l1$::l2}
+} {a {b b} c de f {g g} h}
+
+test basic-48.7.$noComp {expansion: odd usage} -constraints $constraints -body {
+ run {list {*}[l3]$::l1}
+} -returnCodes 1 -result {list element in braces followed by "a" instead of space}
+
+test basic-48.8.$noComp {expansion: odd usage} $constraints {
+ run {list {*}hej$::l1}
+} {heja {b b} c d}
+
+test basic-48.9.$noComp {expansion: Not all {*} should trigger} $constraints {
+ run {list {*}$::l1 \{*\}$::l2 "{*}$::l1" {{*} i j k}}
+} {a {b b} c d {{*}e f {g g} h} {{*}a {b b} c d} {{*} i j k}}
+
+test basic-48.10.$noComp {expansion: expansion of command word} -setup {
+ set cmd [list string range jultomte]
+} -constraints $constraints -body {
+ run {{*}$cmd 2 6}
+} -cleanup {
+ unset cmd
+} -result ltomt
+
+test basic-48.11.$noComp {expansion: expansion into nothing} -setup {
+ set cmd {}
+ set bar {}
+} -constraints $constraints -body {
+ run {{*}$cmd {*}$bar}
+} -cleanup {
+ unset cmd bar
+} -result {}
+
+test basic-48.12.$noComp {expansion: odd usage} $constraints {
+ run {list {*}$::l1 {*}"hej hopp" {*}$::l2}
+} {a {b b} c d hej hopp e f {g g} h}
+
+test basic-48.13.$noComp {expansion: odd usage} $constraints {
+ run {list {*}$::l1 {*}{hej hopp} {*}$::l2}
+} {a {b b} c d hej hopp e f {g g} h}
+
+test basic-48.14.$noComp {expansion: hash command} -setup {
+ catch {rename \# ""}
+ set cmd "#"
+ } -constraints $constraints -body {
+ run { {*}$cmd apa bepa }
+ } -cleanup {
+ unset cmd
+} -returnCodes 1 -result {invalid command name "#"}
+
+test basic-48.15.$noComp {expansion: complex words} -setup {
+ set a(x) [list a {b c} d e]
+ set b x
+ set c [list {f\ g h\ i j k} x y]
+ set d {0\ 1 2 3}
+ } -constraints $constraints -body {
+ run { lappend d {*}$a($b) {*}[lindex $c 0] }
+ } -cleanup {
+ unset a b c d
+} -result {{0 1} 2 3 a {b c} d e {f g} {h i} j k}
+
+testConstraint memory [llength [info commands memory]]
+test basic-48.16.$noComp {expansion: testing for leaks} -setup {
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex [lindex $lines 3] 3
+ }
+ # This test is made to stress the allocation, reallocation and
+ # object reference management in Tcl_EvalEx.
+ proc stress {} {
+ set a x
+ # Create free objects that should disappear
+ set l [list 1$a 2$a 3$a 4$a 5$a 6$a 7$a]
+ # A short number of words and a short result (8)
+ set l [run {list {*}$l $a$a}]
+ # A short number of words and a longer result (27)
+ set l [run {list {*}$l $a$a {*}$l $a$a {*}$l $a$a}]
+ # A short number of words and a longer result, with an error
+ # This is to stress the cleanup in the error case
+ if {![catch {run {_moo_ {*}$l $a$a {*}$l $a$a {*}$l}}]} {
+ error "An error was expected in the previous statement"
+ }
+ # Many words
+ set l [run {list {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a}]
+
+ if {[llength $l] != 19*28} {
+ error "Bad Length: [llength $l] should be [expr {19*28}]"
+ }
+ }
+ } -constraints [linsert $constraints 0 memory] -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ stress
+ set tmp $end
+ set end [getbytes]
+ }
+ set leak [expr {$end - $tmp}]
+ } -cleanup {
+ unset end i tmp
+ rename getbytes {}
+ rename stress {}
+} -result 0
+
+test basic-48.17.$noComp {expansion: object safety} -setup {
+ set old_precision $::tcl_precision
+ set ::tcl_precision 4
+ } -constraints $constraints -body {
+ set third [expr {1.0/3.0}]
+ set l [list $third $third]
+ set x [run {list $third {*}$l $third}]
+ set res [list]
+ foreach t $x {
+ lappend res [expr {$t * 3.0}]
+ }
+ set res
+ } -cleanup {
+ set ::tcl_precision $old_precision
+ unset old_precision res t l x third
+} -result {1.0 1.0 1.0 1.0}
+
+test basic-48.18.$noComp {expansion: list semantics} -constraints $constraints -body {
+ set badcmd {
+ list a b
+ set apa 10
+ }
+ set apa 0
+ list [llength [run { {*}$badcmd }]] $apa
+ } -cleanup {
+ unset apa badcmd
+} -result {5 0}
+
+test basic-48.19.$noComp {expansion: error checking order} -body {
+ set badlist "a {}x y"
+ set a 0
+ set b 0
+ catch {run {list [incr a] {*}$badlist [incr b]}}
+ list $a $b
+ } -constraints $constraints -cleanup {
+ unset badlist a b
+} -result {1 0}
+
+test basic-48.20.$noComp {expansion: odd case with word boundaries} $constraints {
+ run {list {*}$::l1 {*}"hej hopp" {*}$::l2}
+} {a {b b} c d hej hopp e f {g g} h}
+
+test basic-48.21.$noComp {expansion: odd case with word boundaries} $constraints {
+ run {list {*}$::l1 {*}{hej hopp} {*}$::l2}
+} {a {b b} c d hej hopp e f {g g} h}
+
+test basic-48.22.$noComp {expansion: odd case with word boundaries} -body {
+ run {list {*}$::l1 {*}"hej hopp {*}$::l2}
+} -constraints $constraints -returnCodes error -result {missing "}
+
+test basic-48.23.$noComp {expansion: handle return codes} -constraints $constraints -body {
+ set res {}
+ for {set t 0} {$t < 10} {incr t} {
+ run { {*}break }
+ }
+ lappend res $t
+
+ for {set t 0} {$t < 10} {incr t} {
+ run { {*}continue }
+ set t 20
+ }
+ lappend res $t
+
+ lappend res [catch { run { {*}{error Hejsan} } } err]
+ lappend res $err
+ } -cleanup {
+ unset res t
+} -result {0 10 1 Hejsan}
+
+} ;# End of noComp loop
+
+test basic-49.1 {Tcl_EvalEx: verify TCL_EVAL_GLOBAL operation} testevalex {
+ set ::x global
+ namespace eval ns {
+ variable x namespace
+ testevalex {set x changed} global
+ set ::result [list $::x $x]
+ }
+ namespace delete ns
+ set ::result
+} {changed namespace}
+test basic-49.2 {Tcl_EvalEx: verify TCL_EVAL_GLOBAL operation} testevalex {
+ set ::x global
+ namespace eval ns {
+ variable x namespace
+ testevalex {set ::context $x} global
+ }
+ namespace delete ns
+ set ::context
+} {global}
+
+# Clean up after expand tests
+unset noComp l1 l2 constraints
+rename l3 {}
+rename run {}
+
+ #cleanup
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+catch {namespace delete george}
+catch {interp delete test_interp}
+catch {rename p ""}
+catch {rename q ""}
+catch {rename cmd ""}
+catch {rename value:at: ""}
+catch {unset x}
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/binary.test b/library/msgcat/tests/binary.test
new file mode 100644
index 0000000..6c00508
--- /dev/null
+++ b/library/msgcat/tests/binary.test
@@ -0,0 +1,2781 @@
+# This file tests the tclBinary.c file and the "binary" Tcl command.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+testConstraint bigEndian [expr {$tcl_platform(byteOrder) eq "bigEndian"}]
+testConstraint littleEndian [expr {$tcl_platform(byteOrder) eq "littleEndian"}]
+
+# Big test for correct ordering of data in [expr]
+proc testIEEE {} {
+ variable ieeeValues
+ binary scan [binary format dd -1.0 1.0] c* c
+ switch -exact -- $c {
+ {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+ # little endian
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+ ieeeValues(-Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+ ieeeValues(-Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+ ieeeValues(-Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+ ieeeValues(+Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+ ieeeValues(+Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 1
+ return 1
+ }
+ {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+ binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Infinity)
+ binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Normal)
+ binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Subnormal)
+ binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Normal)
+ binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Infinity)
+ binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 0
+ return 1
+ }
+ default {
+ return 0
+ }
+ }
+}
+
+testConstraint ieeeFloatingPoint [testIEEE]
+
+# ----------------------------------------------------------------------
+
+test binary-0.1 {DupByteArrayInternalRep} {
+ set hdr [binary format cc 0 0316]
+ set buf hellomatt
+ set data $hdr
+ append data $buf
+ string length $data
+} 11
+
+test binary-1.1 {Tcl_BinaryObjCmd: bad args} -body {
+ binary
+} -returnCodes error -match glob -result {wrong # args: *}
+test binary-1.2 {Tcl_BinaryObjCmd: bad args} -returnCodes error -body {
+ binary foo
+} -match glob -result {unknown or ambiguous subcommand "foo": *}
+test binary-1.3 {Tcl_BinaryObjCmd: format error} -returnCodes error -body {
+ binary f
+} -result {wrong # args: should be "binary format formatString ?arg ...?"}
+test binary-1.4 {Tcl_BinaryObjCmd: format} -body {
+ binary format ""
+} -result {}
+
+test binary-2.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format a
+} -result {not enough arguments for all format specifiers}
+test binary-2.2 {Tcl_BinaryObjCmd: format} {
+ binary format a0 foo
+} {}
+test binary-2.3 {Tcl_BinaryObjCmd: format} {
+ binary format a f
+} {f}
+test binary-2.4 {Tcl_BinaryObjCmd: format} {
+ binary format a foo
+} {f}
+test binary-2.5 {Tcl_BinaryObjCmd: format} {
+ binary format a3 foo
+} {foo}
+test binary-2.6 {Tcl_BinaryObjCmd: format} {
+ binary format a5 foo
+} foo\x00\x00
+test binary-2.7 {Tcl_BinaryObjCmd: format} {
+ binary format a*a3 foobarbaz blat
+} foobarbazbla
+test binary-2.8 {Tcl_BinaryObjCmd: format} {
+ binary format a*X3a2 foobar x
+} foox\x00r
+
+test binary-3.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format A
+} -result {not enough arguments for all format specifiers}
+test binary-3.2 {Tcl_BinaryObjCmd: format} {
+ binary format A0 f
+} {}
+test binary-3.3 {Tcl_BinaryObjCmd: format} {
+ binary format A f
+} {f}
+test binary-3.4 {Tcl_BinaryObjCmd: format} {
+ binary format A foo
+} {f}
+test binary-3.5 {Tcl_BinaryObjCmd: format} {
+ binary format A3 foo
+} {foo}
+test binary-3.6 {Tcl_BinaryObjCmd: format} {
+ binary format A5 foo
+} {foo }
+test binary-3.7 {Tcl_BinaryObjCmd: format} {
+ binary format A*A3 foobarbaz blat
+} foobarbazbla
+test binary-3.8 {Tcl_BinaryObjCmd: format} {
+ binary format A*X3A2 foobar x
+} {foox r}
+
+test binary-4.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format B
+} -result {not enough arguments for all format specifiers}
+test binary-4.2 {Tcl_BinaryObjCmd: format} {
+ binary format B0 1
+} {}
+test binary-4.3 {Tcl_BinaryObjCmd: format} {
+ binary format B 1
+} \x80
+test binary-4.4 {Tcl_BinaryObjCmd: format} {
+ binary format B* 010011
+} \x4c
+test binary-4.5 {Tcl_BinaryObjCmd: format} {
+ binary format B8 01001101
+} \x4d
+test binary-4.6 {Tcl_BinaryObjCmd: format} {
+ binary format A2X2B9 oo 01001101
+} \x4d\x00
+test binary-4.7 {Tcl_BinaryObjCmd: format} {
+ binary format B9 010011011010
+} \x4d\x80
+test binary-4.8 {Tcl_BinaryObjCmd: format} {
+ binary format B2B3 10 010
+} \x80\x40
+test binary-4.9 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format B1B5 1 foo
+} -result {expected binary string but got "foo" instead}
+
+test binary-5.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format b
+} -result {not enough arguments for all format specifiers}
+test binary-5.2 {Tcl_BinaryObjCmd: format} {
+ binary format b0 1
+} {}
+test binary-5.3 {Tcl_BinaryObjCmd: format} {
+ binary format b 1
+} \x01
+test binary-5.4 {Tcl_BinaryObjCmd: format} {
+ binary format b* 010011
+} 2
+test binary-5.5 {Tcl_BinaryObjCmd: format} {
+ binary format b8 01001101
+} \xb2
+test binary-5.6 {Tcl_BinaryObjCmd: format} {
+ binary format A2X2b9 oo 01001101
+} \xb2\x00
+test binary-5.7 {Tcl_BinaryObjCmd: format} {
+ binary format b9 010011011010
+} \xb2\x01
+test binary-5.8 {Tcl_BinaryObjCmd: format} {
+ binary format b17 1
+} \x01\00\00
+test binary-5.9 {Tcl_BinaryObjCmd: format} {
+ binary format b2b3 10 010
+} \x01\x02
+test binary-5.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format b1b5 1 foo
+} -result {expected binary string but got "foo" instead}
+
+test binary-6.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format h
+} -result {not enough arguments for all format specifiers}
+test binary-6.2 {Tcl_BinaryObjCmd: format} {
+ binary format h0 1
+} {}
+test binary-6.3 {Tcl_BinaryObjCmd: format} {
+ binary format h 1
+} \x01
+test binary-6.4 {Tcl_BinaryObjCmd: format} {
+ binary format h c
+} \x0c
+test binary-6.5 {Tcl_BinaryObjCmd: format} {
+ binary format h* baadf00d
+} \xab\xda\x0f\xd0
+test binary-6.6 {Tcl_BinaryObjCmd: format} {
+ binary format h4 c410
+} \x4c\x01
+test binary-6.7 {Tcl_BinaryObjCmd: format} {
+ binary format h6 c4102
+} \x4c\x01\x02
+test binary-6.8 {Tcl_BinaryObjCmd: format} {
+ binary format h5 c41020304
+} \x4c\x01\x02
+test binary-6.9 {Tcl_BinaryObjCmd: format} {
+ binary format a3X3h5 foo 2
+} \x02\x00\x00
+test binary-6.10 {Tcl_BinaryObjCmd: format} {
+ binary format h2h3 23 456
+} \x32\x54\x06
+test binary-6.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format h2 foo
+} -result {expected hexadecimal string but got "foo" instead}
+
+test binary-7.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format H
+} -result {not enough arguments for all format specifiers}
+test binary-7.2 {Tcl_BinaryObjCmd: format} {
+ binary format H0 1
+} {}
+test binary-7.3 {Tcl_BinaryObjCmd: format} {
+ binary format H 1
+} \x10
+test binary-7.4 {Tcl_BinaryObjCmd: format} {
+ binary format H c
+} \xc0
+test binary-7.5 {Tcl_BinaryObjCmd: format} {
+ binary format H* baadf00d
+} \xba\xad\xf0\x0d
+test binary-7.6 {Tcl_BinaryObjCmd: format} {
+ binary format H4 c410
+} \xc4\x10
+test binary-7.7 {Tcl_BinaryObjCmd: format} {
+ binary format H6 c4102
+} \xc4\x10\x20
+test binary-7.8 {Tcl_BinaryObjCmd: format} {
+ binary format H5 c41023304
+} \xc4\x10\x20
+test binary-7.9 {Tcl_BinaryObjCmd: format} {
+ binary format a3X3H5 foo 2
+} \x20\x00\x00
+test binary-7.10 {Tcl_BinaryObjCmd: format} {
+ binary format H2H3 23 456
+} \x23\x45\x60
+test binary-7.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format H2 foo
+} -result {expected hexadecimal string but got "foo" instead}
+
+test binary-8.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format c
+} -result {not enough arguments for all format specifiers}
+test binary-8.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format c blat
+} -result {expected integer but got "blat"}
+test binary-8.3 {Tcl_BinaryObjCmd: format} {
+ binary format c0 0x50
+} {}
+test binary-8.4 {Tcl_BinaryObjCmd: format} {
+ binary format c 0x50
+} P
+test binary-8.5 {Tcl_BinaryObjCmd: format} {
+ binary format c 0x5052
+} R
+test binary-8.6 {Tcl_BinaryObjCmd: format} {
+ binary format c2 {0x50 0x52}
+} PR
+test binary-8.7 {Tcl_BinaryObjCmd: format} {
+ binary format c2 {0x50 0x52 0x53}
+} PR
+test binary-8.8 {Tcl_BinaryObjCmd: format} {
+ binary format c* {0x50 0x52}
+} PR
+test binary-8.9 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format c2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-8.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {0x50 0x51}
+ binary format c $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-8.11 {Tcl_BinaryObjCmd: format} {
+ set a {0x50 0x51}
+ binary format c1 $a
+} P
+
+test binary-9.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format s
+} -result {not enough arguments for all format specifiers}
+test binary-9.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format s blat
+} -result {expected integer but got "blat"}
+test binary-9.3 {Tcl_BinaryObjCmd: format} {
+ binary format s0 0x50
+} {}
+test binary-9.4 {Tcl_BinaryObjCmd: format} {
+ binary format s 0x50
+} P\x00
+test binary-9.5 {Tcl_BinaryObjCmd: format} {
+ binary format s 0x5052
+} RP
+test binary-9.6 {Tcl_BinaryObjCmd: format} {
+ binary format s 0x505251 0x53
+} QR
+test binary-9.7 {Tcl_BinaryObjCmd: format} {
+ binary format s2 {0x50 0x52}
+} P\x00R\x00
+test binary-9.8 {Tcl_BinaryObjCmd: format} {
+ binary format s* {0x5051 0x52}
+} QPR\x00
+test binary-9.9 {Tcl_BinaryObjCmd: format} {
+ binary format s2 {0x50 0x52 0x53} 0x54
+} P\x00R\x00
+test binary-9.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format s2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-9.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {0x50 0x51}
+ binary format s $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-9.12 {Tcl_BinaryObjCmd: format} {
+ set a {0x50 0x51}
+ binary format s1 $a
+} P\x00
+
+test binary-10.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format S
+} -result {not enough arguments for all format specifiers}
+test binary-10.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format S blat
+} -result {expected integer but got "blat"}
+test binary-10.3 {Tcl_BinaryObjCmd: format} {
+ binary format S0 0x50
+} {}
+test binary-10.4 {Tcl_BinaryObjCmd: format} {
+ binary format S 0x50
+} \x00P
+test binary-10.5 {Tcl_BinaryObjCmd: format} {
+ binary format S 0x5052
+} PR
+test binary-10.6 {Tcl_BinaryObjCmd: format} {
+ binary format S 0x505251 0x53
+} RQ
+test binary-10.7 {Tcl_BinaryObjCmd: format} {
+ binary format S2 {0x50 0x52}
+} \x00P\x00R
+test binary-10.8 {Tcl_BinaryObjCmd: format} {
+ binary format S* {0x5051 0x52}
+} PQ\x00R
+test binary-10.9 {Tcl_BinaryObjCmd: format} {
+ binary format S2 {0x50 0x52 0x53} 0x54
+} \x00P\x00R
+test binary-10.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format S2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-10.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {0x50 0x51}
+ binary format S $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-10.12 {Tcl_BinaryObjCmd: format} {
+ set a {0x50 0x51}
+ binary format S1 $a
+} \x00P
+
+test binary-11.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format i
+} -result {not enough arguments for all format specifiers}
+test binary-11.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format i blat
+} -result {expected integer but got "blat"}
+test binary-11.3 {Tcl_BinaryObjCmd: format} {
+ binary format i0 0x50
+} {}
+test binary-11.4 {Tcl_BinaryObjCmd: format} {
+ binary format i 0x50
+} P\x00\x00\x00
+test binary-11.5 {Tcl_BinaryObjCmd: format} {
+ binary format i 0x5052
+} RP\x00\x00
+test binary-11.6 {Tcl_BinaryObjCmd: format} {
+ binary format i 0x505251 0x53
+} QRP\x00
+test binary-11.7 {Tcl_BinaryObjCmd: format} {
+ binary format i1 {0x505251 0x53}
+} QRP\x00
+test binary-11.8 {Tcl_BinaryObjCmd: format} {
+ binary format i 0x53525150
+} PQRS
+test binary-11.9 {Tcl_BinaryObjCmd: format} {
+ binary format i2 {0x50 0x52}
+} P\x00\x00\x00R\x00\x00\x00
+test binary-11.10 {Tcl_BinaryObjCmd: format} {
+ binary format i* {0x50515253 0x52}
+} SRQPR\x00\x00\x00
+test binary-11.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format i2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-11.12 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {0x50 0x51}
+ binary format i $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-11.13 {Tcl_BinaryObjCmd: format} {
+ set a {0x50 0x51}
+ binary format i1 $a
+} P\x00\x00\x00
+
+test binary-12.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format I
+} -result {not enough arguments for all format specifiers}
+test binary-12.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format I blat
+} -result {expected integer but got "blat"}
+test binary-12.3 {Tcl_BinaryObjCmd: format} {
+ binary format I0 0x50
+} {}
+test binary-12.4 {Tcl_BinaryObjCmd: format} {
+ binary format I 0x50
+} \x00\x00\x00P
+test binary-12.5 {Tcl_BinaryObjCmd: format} {
+ binary format I 0x5052
+} \x00\x00PR
+test binary-12.6 {Tcl_BinaryObjCmd: format} {
+ binary format I 0x505251 0x53
+} \x00PRQ
+test binary-12.7 {Tcl_BinaryObjCmd: format} {
+ binary format I1 {0x505251 0x53}
+} \x00PRQ
+test binary-12.8 {Tcl_BinaryObjCmd: format} {
+ binary format I 0x53525150
+} SRQP
+test binary-12.9 {Tcl_BinaryObjCmd: format} {
+ binary format I2 {0x50 0x52}
+} \x00\x00\x00P\x00\x00\x00R
+test binary-12.10 {Tcl_BinaryObjCmd: format} {
+ binary format I* {0x50515253 0x52}
+} PQRS\x00\x00\x00R
+test binary-12.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format i2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-12.12 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {0x50 0x51}
+ binary format I $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-12.13 {Tcl_BinaryObjCmd: format} {
+ set a {0x50 0x51}
+ binary format I1 $a
+} \x00\x00\x00P
+
+test binary-13.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format f
+} -result {not enough arguments for all format specifiers}
+test binary-13.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format f blat
+} -result {expected floating-point number but got "blat"}
+test binary-13.3 {Tcl_BinaryObjCmd: format} {
+ binary format f0 1.6
+} {}
+test binary-13.4 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format f 1.6
+} \x3f\xcc\xcc\xcd
+test binary-13.5 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format f 1.6
+} \xcd\xcc\xcc\x3f
+test binary-13.6 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format f* {1.6 3.4}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-13.7 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format f* {1.6 3.4}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-13.8 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format f2 {1.6 3.4}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-13.9 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format f2 {1.6 3.4}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-13.10 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format f2 {1.6 3.4 5.6}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-13.11 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format f2 {1.6 3.4 5.6}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-13.12 {Tcl_BinaryObjCmd: float overflow} bigEndian {
+ binary format f -3.402825e+38
+} \xff\x7f\xff\xff
+test binary-13.13 {Tcl_BinaryObjCmd: float overflow} littleEndian {
+ binary format f -3.402825e+38
+} \xff\xff\x7f\xff
+test binary-13.14 {Tcl_BinaryObjCmd: float underflow} bigEndian {
+ binary format f -3.402825e-100
+} \x80\x00\x00\x00
+test binary-13.15 {Tcl_BinaryObjCmd: float underflow} littleEndian {
+ binary format f -3.402825e-100
+} \x00\x00\x00\x80
+test binary-13.16 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format f2 {1.6}
+} -result {number of elements in list does not match count}
+test binary-13.17 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {1.6 3.4}
+ binary format f $a
+} -result "expected floating-point number but got \"1.6 3.4\""
+test binary-13.18 {Tcl_BinaryObjCmd: format} bigEndian {
+ set a {1.6 3.4}
+ binary format f1 $a
+} \x3f\xcc\xcc\xcd
+test binary-13.19 {Tcl_BinaryObjCmd: format} littleEndian {
+ set a {1.6 3.4}
+ binary format f1 $a
+} \xcd\xcc\xcc\x3f
+
+test binary-14.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format d
+} -result {not enough arguments for all format specifiers}
+test binary-14.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format d blat
+} -result {expected floating-point number but got "blat"}
+test binary-14.3 {Tcl_BinaryObjCmd: format} {
+ binary format d0 1.6
+} {}
+test binary-14.4 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format d 1.6
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a
+test binary-14.5 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format d 1.6
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f
+test binary-14.6 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format d* {1.6 3.4}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-14.7 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format d* {1.6 3.4}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-14.8 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format d2 {1.6 3.4}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-14.9 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format d2 {1.6 3.4}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-14.10 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format d2 {1.6 3.4 5.6}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-14.11 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format d2 {1.6 3.4 5.6}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-14.14 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format d2 {1.6}
+} -result {number of elements in list does not match count}
+test binary-14.15 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {1.6 3.4}
+ binary format d $a
+} -result "expected floating-point number but got \"1.6 3.4\""
+test binary-14.16 {Tcl_BinaryObjCmd: format} bigEndian {
+ set a {1.6 3.4}
+ binary format d1 $a
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a
+test binary-14.17 {Tcl_BinaryObjCmd: format} littleEndian {
+ set a {1.6 3.4}
+ binary format d1 $a
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f
+test binary-14.18 {FormatNumber: Bug 1116542} {
+ binary scan [binary format d 1.25] d w
+ set w
+} 1.25
+
+test binary-15.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format ax*a "y" "z"
+} -result {cannot use "*" in format string with "x"}
+test binary-15.2 {Tcl_BinaryObjCmd: format} {
+ binary format axa "y" "z"
+} y\x00z
+test binary-15.3 {Tcl_BinaryObjCmd: format} {
+ binary format ax3a "y" "z"
+} y\x00\x00\x00z
+test binary-15.4 {Tcl_BinaryObjCmd: format} {
+ binary format a*X3x3a* "foo" "z"
+} \x00\x00\x00z
+test binary-15.5 {Tcl_BinaryObjCmd: format - bug #1923966} {
+ binary format x0s 1
+} \x01\x00
+test binary-15.6 {Tcl_BinaryObjCmd: format - bug #1923966} {
+ binary format x0ss 1 1
+} \x01\x00\x01\x00
+test binary-15.7 {Tcl_BinaryObjCmd: format - bug #1923966} {
+ binary format x1s 1
+} \x00\x01\x00
+test binary-15.8 {Tcl_BinaryObjCmd: format - bug #1923966} {
+ binary format x1ss 1 1
+} \x00\x01\x00\x01\x00
+
+test binary-16.1 {Tcl_BinaryObjCmd: format} {
+ binary format a*X*a "foo" "z"
+} zoo
+test binary-16.2 {Tcl_BinaryObjCmd: format} {
+ binary format aX3a "y" "z"
+} z
+test binary-16.3 {Tcl_BinaryObjCmd: format} {
+ binary format a*Xa* "foo" "zy"
+} fozy
+test binary-16.4 {Tcl_BinaryObjCmd: format} {
+ binary format a*X3a "foobar" "z"
+} foozar
+test binary-16.5 {Tcl_BinaryObjCmd: format} {
+ binary format a*X3aX2a "foobar" "z" "b"
+} fobzar
+
+test binary-17.1 {Tcl_BinaryObjCmd: format} {
+ binary format @1
+} \x00
+test binary-17.2 {Tcl_BinaryObjCmd: format} {
+ binary format @5a2 "ab"
+} \x00\x00\x00\x00\x00\x61\x62
+test binary-17.3 {Tcl_BinaryObjCmd: format} {
+ binary format {a* @0 a2 @* a*} "foobar" "ab" "blat"
+} abobarblat
+
+test binary-18.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format u0a3 abc abd
+} -result {bad field specifier "u"}
+
+test binary-19.1 {Tcl_BinaryObjCmd: errors} -returnCodes error -body {
+ binary s
+} -result {wrong # args: should be "binary scan value formatString ?varName ...?"}
+test binary-19.2 {Tcl_BinaryObjCmd: errors} -returnCodes error -body {
+ binary scan foo
+} -result {wrong # args: should be "binary scan value formatString ?varName ...?"}
+test binary-19.3 {Tcl_BinaryObjCmd: scan} {
+ binary scan {} {}
+} 0
+
+test binary-20.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc a
+} -result {not enough arguments for all format specifiers}
+test binary-20.2 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan abc a arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-20.3 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ set arg1 abc
+ list [binary scan abc a0 arg1] $arg1
+} -result {1 {}}
+test binary-20.4 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc a* arg1] $arg1
+} -result {1 abc}
+test binary-20.5 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc a5 arg1] [info exists arg1]
+} -result {0 0}
+test binary-20.6 {Tcl_BinaryObjCmd: scan} {
+ set arg1 foo
+ list [binary scan abc a2 arg1] $arg1
+} {1 ab}
+test binary-20.7 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+} -body {
+ list [binary scan abcdef a2a2 arg1 arg2] $arg1 $arg2
+} -result {2 ab cd}
+test binary-20.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc a2 arg1(a)] $arg1(a)
+} -result {1 ab}
+test binary-20.9 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc a arg1(a)] $arg1(a)
+} -result {1 a}
+
+test binary-21.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc A
+} -result {not enough arguments for all format specifiers}
+test binary-21.2 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan abc A arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-21.3 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ set arg1 abc
+ list [binary scan abc A0 arg1] $arg1
+} -result {1 {}}
+test binary-21.4 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc A* arg1] $arg1
+} -result {1 abc}
+test binary-21.5 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc A5 arg1] [info exists arg1]
+} -result {0 0}
+test binary-21.6 {Tcl_BinaryObjCmd: scan} {
+ set arg1 foo
+ list [binary scan abc A2 arg1] $arg1
+} {1 ab}
+test binary-21.7 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+} -body {
+ list [binary scan abcdef A2A2 arg1 arg2] $arg1 $arg2
+} -result {2 ab cd}
+test binary-21.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc A2 arg1(a)] $arg1(a)
+} -result {1 ab}
+test binary-21.9 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc A2 arg1(a)] $arg1(a)
+} -result {1 ab}
+test binary-21.10 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc A arg1(a)] $arg1(a)
+} -result {1 a}
+test binary-21.11 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan "abc def \x00 " A* arg1] $arg1
+} -result {1 {abc def}}
+test binary-21.12 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan "abc def \x00ghi " A* arg1] $arg1
+} -result [list 1 "abc def \x00ghi"]
+
+test binary-22.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc b
+} -result {not enough arguments for all format specifiers}
+test binary-22.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 b* arg1] $arg1
+} {1 0100101011001010}
+test binary-22.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x82\x53 b arg1] $arg1
+} {1 0}
+test binary-22.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x82\x53 b1 arg1] $arg1
+} {1 0}
+test binary-22.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x82\x53 b0 arg1] $arg1
+} {1 {}}
+test binary-22.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 b5 arg1] $arg1
+} {1 01001}
+test binary-22.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 b8 arg1] $arg1
+} {1 01001010}
+test binary-22.8 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 b14 arg1] $arg1
+} {1 01001010110010}
+test binary-22.9 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 b14 arg1] $arg1
+} {0 foo}
+test binary-22.10 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 b1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-22.11 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1 arg2
+} -body {
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x07\x87\x05 b5b* arg1 arg2] $arg1 $arg2
+} -result {2 11100 1110000110100000}
+
+test binary-23.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc B
+} -result {not enough arguments for all format specifiers}
+test binary-23.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 B* arg1] $arg1
+} {1 0101001001010011}
+test binary-23.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x82\x53 B arg1] $arg1
+} {1 1}
+test binary-23.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x82\x53 B1 arg1] $arg1
+} {1 1}
+test binary-23.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 B0 arg1] $arg1
+} {1 {}}
+test binary-23.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 B5 arg1] $arg1
+} {1 01010}
+test binary-23.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 B8 arg1] $arg1
+} {1 01010010}
+test binary-23.8 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 B14 arg1] $arg1
+} {1 01010010010100}
+test binary-23.9 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 B14 arg1] $arg1
+} {0 foo}
+test binary-23.10 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 B1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-23.11 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1 arg2
+} -body {
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x70\x87\x05 B5B* arg1 arg2] $arg1 $arg2
+} -result {2 01110 1000011100000101}
+
+test binary-24.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc h
+} -result {not enough arguments for all format specifiers}
+test binary-24.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 h* arg1] $arg1
+} {1 253a}
+test binary-24.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \xc2\xa3 h arg1] $arg1
+} {1 2}
+test binary-24.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x82\x53 h1 arg1] $arg1
+} {1 2}
+test binary-24.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 h0 arg1] $arg1
+} {1 {}}
+test binary-24.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \xf2\x53 h2 arg1] $arg1
+} {1 2f}
+test binary-24.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 h3 arg1] $arg1
+} {1 253}
+test binary-24.8 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 h3 arg1] $arg1
+} {0 foo}
+test binary-24.9 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 h1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-24.10 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1 arg2
+} -body {
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x70\x87\x05 h2h* arg1 arg2] $arg1 $arg2
+} -result {2 07 7850}
+
+test binary-25.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc H
+} -result {not enough arguments for all format specifiers}
+test binary-25.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 H* arg1] $arg1
+} {1 52a3}
+test binary-25.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \xc2\xa3 H arg1] $arg1
+} {1 c}
+test binary-25.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x82\x53 H1 arg1] $arg1
+} {1 8}
+test binary-25.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 H0 arg1] $arg1
+} {1 {}}
+test binary-25.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \xf2\x53 H2 arg1] $arg1
+} {1 f2}
+test binary-25.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 H3 arg1] $arg1
+} {1 525}
+test binary-25.8 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 H3 arg1] $arg1
+} {0 foo}
+test binary-25.9 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 H1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-25.10 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x70\x87\x05 H2H* arg1 arg2] $arg1 $arg2
+} {2 70 8705}
+
+test binary-26.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc c
+} -result {not enough arguments for all format specifiers}
+test binary-26.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 c* arg1] $arg1
+} {1 {82 -93}}
+test binary-26.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 c arg1] $arg1
+} {1 82}
+test binary-26.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 c1 arg1] $arg1
+} {1 82}
+test binary-26.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 c0 arg1] $arg1
+} {1 {}}
+test binary-26.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 c2 arg1] $arg1
+} {1 {82 -93}}
+test binary-26.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \xff c arg1] $arg1
+} {1 -1}
+test binary-26.8 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 c3 arg1] $arg1
+} {0 foo}
+test binary-26.9 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 c1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-26.10 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x70\x87\x05 c2c* arg1 arg2] $arg1 $arg2
+} {2 {112 -121} 5}
+test binary-26.11 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 cu* arg1] $arg1
+} {1 {82 163}}
+test binary-26.12 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 cu arg1] $arg1
+} {1 82}
+test binary-26.13 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \xff cu arg1] $arg1
+} {1 255}
+test binary-26.14 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x80\x80 cuc arg1 arg2] $arg1 $arg2
+} {2 128 -128}
+test binary-26.15 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x80\x80 ccu arg1 arg2] $arg1 $arg2
+} {2 -128 128}
+
+test binary-27.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc s
+} -result {not enough arguments for all format specifiers}
+test binary-27.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 s* arg1] $arg1
+} {1 {-23726 21587}}
+test binary-27.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 s arg1] $arg1
+} {1 -23726}
+test binary-27.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 s1 arg1] $arg1
+} {1 -23726}
+test binary-27.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 s0 arg1] $arg1
+} {1 {}}
+test binary-27.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 s2 arg1] $arg1
+} {1 {-23726 21587}}
+test binary-27.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 s1 arg1] $arg1
+} {0 foo}
+test binary-27.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 s1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-27.9 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x52\xa3\x53\x54\x05 s2c* arg1 arg2] $arg1 $arg2
+} {2 {-23726 21587} 5}
+test binary-27.10 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 su* arg1] $arg1
+} {1 {41810 21587}}
+test binary-27.11 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \xff\xff\xff\xff sus arg1 arg2] $arg1 $arg2
+} {2 65535 -1}
+test binary-27.12 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \xff\xff\xff\xff ssu arg1 arg2] $arg1 $arg2
+} {2 -1 65535}
+
+test binary-28.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc S
+} -result {not enough arguments for all format specifiers}
+test binary-28.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 S* arg1] $arg1
+} {1 {21155 21332}}
+test binary-28.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 S arg1] $arg1
+} {1 21155}
+test binary-28.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 S1 arg1] $arg1
+} {1 21155}
+test binary-28.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 S0 arg1] $arg1
+} {1 {}}
+test binary-28.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 S2 arg1] $arg1
+} {1 {21155 21332}}
+test binary-28.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 S1 arg1] $arg1
+} {0 foo}
+test binary-28.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 S1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-28.9 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x52\xa3\x53\x54\x05 S2c* arg1 arg2] $arg1 $arg2
+} {2 {21155 21332} 5}
+test binary-28.10 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 Su* arg1] $arg1
+} {1 {21155 21332}}
+test binary-28.11 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \xa3\x52\x54\x53 Su* arg1] $arg1
+} {1 {41810 21587}}
+
+test binary-29.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc i
+} -result {not enough arguments for all format specifiers}
+test binary-29.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 i* arg1] $arg1
+} {1 {1414767442 67305985}}
+test binary-29.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 i arg1] $arg1
+} {1 1414767442}
+test binary-29.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 i1 arg1] $arg1
+} {1 1414767442}
+test binary-29.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53 i0 arg1] $arg1
+} {1 {}}
+test binary-29.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 i2 arg1] $arg1
+} {1 {1414767442 67305985}}
+test binary-29.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 i1 arg1] $arg1
+} {0 foo}
+test binary-29.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53\x53\x54 i1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-29.9 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04\x05 i2c* arg1 arg2] $arg1 $arg2
+} {2 {1414767442 67305985} 5}
+test binary-29.10 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff iui arg1 arg2] $arg1 $arg2
+} {2 4294967295 -1}
+test binary-29.11 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff iiu arg1 arg2] $arg1 $arg2
+} {2 -1 4294967295}
+test binary-29.12 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ list [binary scan \x80\x00\x00\x00\x00\x00\x00\x80 iuiu arg1 arg2] $arg1 $arg2
+} {2 128 2147483648}
+
+test binary-30.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc I
+} -result {not enough arguments for all format specifiers}
+test binary-30.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 I* arg1] $arg1
+} {1 {1386435412 16909060}}
+test binary-30.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 I arg1] $arg1
+} {1 1386435412}
+test binary-30.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 I1 arg1] $arg1
+} {1 1386435412}
+test binary-30.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53 I0 arg1] $arg1
+} {1 {}}
+test binary-30.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 I2 arg1] $arg1
+} {1 {1386435412 16909060}}
+test binary-30.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 I1 arg1] $arg1
+} {0 foo}
+test binary-30.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53\x53\x54 I1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-30.9 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04\x05 I2c* arg1 arg2] $arg1 $arg2
+} {2 {1386435412 16909060} 5}
+test binary-30.10 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff IuI arg1 arg2] $arg1 $arg2
+} {2 4294967295 -1}
+test binary-30.11 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff IIu arg1 arg2] $arg1 $arg2
+} {2 -1 4294967295}
+test binary-30.12 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ list [binary scan \x80\x00\x00\x00\x00\x00\x00\x80 IuIu arg1 arg2] $arg1 $arg2
+} {2 2147483648 128}
+
+test binary-31.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc f
+} -result {not enough arguments for all format specifiers}
+test binary-31.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a f* arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-31.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 f* arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-31.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a f arg1] $arg1
+} {1 1.600000023841858}
+test binary-31.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 f arg1] $arg1
+} {1 1.600000023841858}
+test binary-31.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd f1 arg1] $arg1
+} {1 1.600000023841858}
+test binary-31.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f f1 arg1] $arg1
+} {1 1.600000023841858}
+test binary-31.8 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd f0 arg1] $arg1
+} {1 {}}
+test binary-31.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f f0 arg1] $arg1
+} {1 {}}
+test binary-31.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a f2 arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-31.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 f2 arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-31.12 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 f1 arg1] $arg1
+} {0 foo}
+test binary-31.13 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x3f\xcc\xcc\xcd f1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-31.14 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a\x05 f2c* arg1 arg2] $arg1 $arg2
+} {2 {1.600000023841858 3.4000000953674316} 5}
+test binary-31.15 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40\x05 f2c* arg1 arg2] $arg1 $arg2
+} {2 {1.600000023841858 3.4000000953674316} 5}
+
+test binary-32.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc d
+} -result {not enough arguments for all format specifiers}
+test binary-32.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 d* arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-32.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 d* arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-32.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 d arg1] $arg1
+} {1 1.6}
+test binary-32.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 d arg1] $arg1
+} {1 1.6}
+test binary-32.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a d1 arg1] $arg1
+} {1 1.6}
+test binary-32.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f d1 arg1] $arg1
+} {1 1.6}
+test binary-32.8 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a d0 arg1] $arg1
+} {1 {}}
+test binary-32.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f d0 arg1] $arg1
+} {1 {}}
+test binary-32.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 d2 arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-32.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 d2 arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-32.12 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 d1 arg1] $arg1
+} {0 foo}
+test binary-32.13 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a d1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-32.14 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33\x05 d2c* arg1 arg2] $arg1 $arg2
+} {2 {1.6 3.4} 5}
+test binary-32.15 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40\x05 d2c* arg1 arg2] $arg1 $arg2
+} {2 {1.6 3.4} 5}
+
+test binary-33.1 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ list [binary scan abcdefg a2xa3 arg1 arg2] $arg1 $arg2
+} {2 ab def}
+test binary-33.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ set arg2 foo
+ list [binary scan abcdefg a3x*a3 arg1 arg2] $arg1 $arg2
+} {1 abc foo}
+test binary-33.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ set arg2 foo
+ list [binary scan abcdefg a3x20a3 arg1 arg2] $arg1 $arg2
+} {1 abc foo}
+test binary-33.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ set arg2 foo
+ list [binary scan abc a3x20a3 arg1 arg2] $arg1 $arg2
+} {1 abc foo}
+test binary-33.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef x1a1 arg1] $arg1
+} {1 b}
+test binary-33.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef x5a1 arg1] $arg1
+} {1 f}
+test binary-33.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef x0a1 arg1] $arg1
+} {1 a}
+
+test binary-34.1 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ list [binary scan abcdefg a2Xa3 arg1 arg2] $arg1 $arg2
+} {2 ab bcd}
+test binary-34.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ set arg2 foo
+ list [binary scan abcdefg a3X*a3 arg1 arg2] $arg1 $arg2
+} {2 abc abc}
+test binary-34.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ set arg2 foo
+ list [binary scan abcdefg a3X20a3 arg1 arg2] $arg1 $arg2
+} {2 abc abc}
+test binary-34.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abc X20a3 arg1] $arg1
+} {1 abc}
+test binary-34.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef x*X1a1 arg1] $arg1
+} {1 f}
+test binary-34.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef x*X5a1 arg1] $arg1
+} {1 b}
+test binary-34.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef x3X0a1 arg1] $arg1
+} {1 d}
+
+test binary-35.1 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+} -returnCodes error -body {
+ binary scan abcdefg a2@a3 arg1 arg2
+} -result {missing count for "@" field specifier}
+test binary-35.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ set arg2 foo
+ list [binary scan abcdefg a3@*a3 arg1 arg2] $arg1 $arg2
+} {1 abc foo}
+test binary-35.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ set arg2 foo
+ list [binary scan abcdefg a3@20a3 arg1 arg2] $arg1 $arg2
+} {1 abc foo}
+test binary-35.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef @2a3 arg1] $arg1
+} {1 cde}
+test binary-35.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef x*@1a1 arg1] $arg1
+} {1 b}
+test binary-35.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef x*@0a1 arg1] $arg1
+} {1 a}
+
+test binary-36.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abcdef u0a3
+} -result {bad field specifier "u"}
+
+# GetFormatSpec is pretty thoroughly tested above, but there are a few cases
+# we should text explicitly
+
+test binary-37.1 {GetFormatSpec: whitespace} {
+ binary format "a3 a5 a3" foo barblat baz
+} foobarblbaz
+test binary-37.2 {GetFormatSpec: whitespace} {
+ binary format " " foo
+} {}
+test binary-37.3 {GetFormatSpec: whitespace} {
+ binary format " a3" foo
+} foo
+test binary-37.4 {GetFormatSpec: whitespace} {
+ binary format "" foo
+} {}
+test binary-37.5 {GetFormatSpec: whitespace} {
+ binary format "" foo
+} {}
+test binary-37.6 {GetFormatSpec: whitespace} {
+ binary format " a3 " foo
+} foo
+test binary-37.7 {GetFormatSpec: numbers} -returnCodes error -body {
+ binary scan abcdef "x-1" foo
+} -result {bad field specifier "-"}
+test binary-37.8 {GetFormatSpec: numbers} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan abcdef "a0x3" arg1] $arg1
+} {1 {}}
+test binary-37.9 {GetFormatSpec: numbers} {
+ # test format of neg numbers
+ # bug report/fix provided by Harald Kirsch
+ set x [binary format f* {1 -1 2 -2 0}]
+ binary scan $x f* bla
+ set bla
+} {1.0 -1.0 2.0 -2.0 0.0}
+
+test binary-38.1 {FormatNumber: word alignment} {
+ set x [binary format c1s1 1 1]
+} \x01\x01\x00
+test binary-38.2 {FormatNumber: word alignment} {
+ set x [binary format c1S1 1 1]
+} \x01\x00\x01
+test binary-38.3 {FormatNumber: word alignment} {
+ set x [binary format c1i1 1 1]
+} \x01\x01\x00\x00\x00
+test binary-38.4 {FormatNumber: word alignment} {
+ set x [binary format c1I1 1 1]
+} \x01\x00\x00\x00\x01
+test binary-38.5 {FormatNumber: word alignment} bigEndian {
+ set x [binary format c1d1 1 1.6]
+} \x01\x3f\xf9\x99\x99\x99\x99\x99\x9a
+test binary-38.6 {FormatNumber: word alignment} littleEndian {
+ set x [binary format c1d1 1 1.6]
+} \x01\x9a\x99\x99\x99\x99\x99\xf9\x3f
+test binary-38.7 {FormatNumber: word alignment} bigEndian {
+ set x [binary format c1f1 1 1.6]
+} \x01\x3f\xcc\xcc\xcd
+test binary-38.8 {FormatNumber: word alignment} littleEndian {
+ set x [binary format c1f1 1 1.6]
+} \x01\xcd\xcc\xcc\x3f
+
+test binary-39.1 {ScanNumber: sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 c2 arg1] $arg1
+} {1 {82 -93}}
+test binary-39.2 {ScanNumber: sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x01\x02\x01\x81\x82\x01\x81\x82 s4 arg1] $arg1
+} {1 {513 -32511 386 -32127}}
+test binary-39.3 {ScanNumber: sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x01\x02\x01\x81\x82\x01\x81\x82 S4 arg1] $arg1
+} {1 {258 385 -32255 -32382}}
+test binary-39.4 {ScanNumber: sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x01\x01\x01\x02\x81\x01\x01\x01\x01\x82\x01\x01\x01\x01\x82\x01\x01\x01\x01\x81 i5 arg1] $arg1
+} {1 {33620225 16843137 16876033 25297153 -2130640639}}
+test binary-39.5 {ScanNumber: sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x01\x01\x01\x02\x81\x01\x01\x01\x01\x82\x01\x01\x01\x01\x82\x01\x01\x01\x01\x81 I5 arg1] $arg1
+} {1 {16843010 -2130640639 25297153 16876033 16843137}}
+test binary-39.6 {ScanNumber: no sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 cu2 arg1] $arg1
+} {1 {82 163}}
+test binary-39.7 {ScanNumber: no sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x01\x02\x01\x81\x82\x01\x81\x82 su4 arg1] $arg1
+} {1 {513 33025 386 33409}}
+test binary-39.8 {ScanNumber: no sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x01\x02\x01\x81\x82\x01\x81\x82 Su4 arg1] $arg1
+} {1 {258 385 33281 33154}}
+test binary-39.9 {ScanNumber: no sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x01\x01\x01\x02\x81\x01\x01\x01\x01\x82\x01\x01\x01\x01\x82\x01\x01\x01\x01\x81 iu5 arg1] $arg1
+} {1 {33620225 16843137 16876033 25297153 2164326657}}
+test binary-39.10 {ScanNumber: no sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x01\x01\x01\x02\x81\x01\x01\x01\x01\x82\x01\x01\x01\x01\x82\x01\x01\x01\x01\x81 Iu5 arg1] $arg1
+} {1 {16843010 2164326657 25297153 16876033 16843137}}
+
+test binary-40.3 {ScanNumber: NaN} -body {
+ unset -nocomplain arg1
+ list [binary scan \xff\xff\xff\xff f1 arg1] $arg1
+} -match glob -result {1 -NaN*}
+test binary-40.4 {ScanNumber: NaN} -body {
+ unset -nocomplain arg1
+ list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff d arg1] $arg1
+} -match glob -result {1 -NaN*}
+
+test binary-41.1 {ScanNumber: word alignment} {
+ unset -nocomplain arg1; unset arg2
+ list [binary scan \x01\x01\x00 c1s1 arg1 arg2] $arg1 $arg2
+} {2 1 1}
+test binary-41.2 {ScanNumber: word alignment} {
+ unset -nocomplain arg1; unset arg2
+ list [binary scan \x01\x00\x01 c1S1 arg1 arg2] $arg1 $arg2
+} {2 1 1}
+test binary-41.3 {ScanNumber: word alignment} {
+ unset -nocomplain arg1; unset arg2
+ list [binary scan \x01\x01\x00\x00\x00 c1i1 arg1 arg2] $arg1 $arg2
+} {2 1 1}
+test binary-41.4 {ScanNumber: word alignment} {
+ unset -nocomplain arg1; unset arg2
+ list [binary scan \x01\x00\x00\x00\x01 c1I1 arg1 arg2] $arg1 $arg2
+} {2 1 1}
+test binary-41.5 {ScanNumber: word alignment} bigEndian {
+ unset -nocomplain arg1; unset arg2
+ list [binary scan \x01\x3f\xcc\xcc\xcd c1f1 arg1 arg2] $arg1 $arg2
+} {2 1 1.600000023841858}
+test binary-41.6 {ScanNumber: word alignment} littleEndian {
+ unset -nocomplain arg1; unset arg2
+ list [binary scan \x01\xcd\xcc\xcc\x3f c1f1 arg1 arg2] $arg1 $arg2
+} {2 1 1.600000023841858}
+test binary-41.7 {ScanNumber: word alignment} bigEndian {
+ unset -nocomplain arg1; unset arg2
+ list [binary scan \x01\x3f\xf9\x99\x99\x99\x99\x99\x9a c1d1 arg1 arg2] $arg1 $arg2
+} {2 1 1.6}
+test binary-41.8 {ScanNumber: word alignment} littleEndian {
+ unset -nocomplain arg1; unset arg2
+ list [binary scan \x01\x9a\x99\x99\x99\x99\x99\xf9\x3f c1d1 arg1 arg2] $arg1 $arg2
+} {2 1 1.6}
+
+test binary-42.1 {Tcl_BinaryObjCmd: bad arguments} -constraints {} -body {
+ binary ?
+} -returnCodes error -match glob -result {unknown or ambiguous subcommand "?": *}
+
+# Wide int (guaranteed at least 64-bit) handling
+test binary-43.1 {Tcl_BinaryObjCmd: format wide int} {} {
+ binary format w 7810179016327718216
+} HelloTcl
+test binary-43.2 {Tcl_BinaryObjCmd: format wide int} {} {
+ binary format W 7810179016327718216
+} lcTolleH
+
+test binary-44.1 {Tcl_BinaryObjCmd: scan wide int} {} {
+ binary scan HelloTcl W x
+ set x
+} 5216694956358656876
+test binary-44.2 {Tcl_BinaryObjCmd: scan wide int} {} {
+ binary scan lcTolleH w x
+ set x
+} 5216694956358656876
+test binary-44.3 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} {} {
+ binary scan [binary format w [expr {wide(3) << 31}]] w x
+ set x
+} 6442450944
+test binary-44.4 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} {} {
+ binary scan [binary format W [expr {wide(3) << 31}]] W x
+ set x
+} 6442450944
+test binary-43.5 {Tcl_BinaryObjCmd: scan wide int} {} {
+ unset -nocomplain arg1
+ list [binary scan \x80[string repeat \x00 7] W arg1] $arg1
+} {1 -9223372036854775808}
+test binary-43.6 {Tcl_BinaryObjCmd: scan unsigned wide int} {} {
+ unset -nocomplain arg1
+ list [binary scan \x80[string repeat \x00 7] Wu arg1] $arg1
+} {1 9223372036854775808}
+test binary-43.7 {Tcl_BinaryObjCmd: scan unsigned wide int} {} {
+ unset -nocomplain arg1
+ list [binary scan [string repeat \x00 7]\x80 wu arg1] $arg1
+} {1 9223372036854775808}
+test binary-43.8 {Tcl_BinaryObjCmd: scan unsigned wide int} {} {
+ unset -nocomplain arg1 arg2
+ list [binary scan \x80[string repeat \x00 7]\x80[string repeat \x00 7] WuW arg1 arg2] $arg1 $arg2
+} {2 9223372036854775808 -9223372036854775808}
+test binary-43.9 {Tcl_BinaryObjCmd: scan unsigned wide int} {} {
+ unset -nocomplain arg1 arg2
+ list [binary scan [string repeat \x00 7]\x80[string repeat \x00 7]\x80 wuw arg1 arg2] $arg1 $arg2
+} {2 9223372036854775808 -9223372036854775808}
+
+test binary-45.1 {Tcl_BinaryObjCmd: combined wide int handling} {
+ binary scan [binary format sws 16450 -1 19521] c* x
+ set x
+} {66 64 -1 -1 -1 -1 -1 -1 -1 -1 65 76}
+test binary-45.2 {Tcl_BinaryObjCmd: combined wide int handling} {
+ binary scan [binary format sWs 16450 0x7fffffff 19521] c* x
+ set x
+} {66 64 0 0 0 0 127 -1 -1 -1 65 76}
+
+test binary-46.1 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} {
+ binary format a* \u20ac
+} \u00ac
+test binary-46.2 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} {
+ list [binary scan [binary format a* \u20ac\u20bd] s x] $x
+} {1 -16980}
+test binary-46.3 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} {
+ set x {}
+ set y {}
+ set z {}
+ list [binary scan [binary format a* \u20ac\u20bd] aaa x y z] $x $y $z
+} "2 \u00ac \u00bd {}"
+test binary-46.4 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} {
+ set x [encoding convertto iso8859-15 \u20ac]
+ set y [binary format a* $x]
+ list $x $y
+} "\u00a4 \u00a4"
+test binary-46.5 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} {
+ set x [binary scan \u00a4 a* y]
+ list $x $y [encoding convertfrom iso8859-15 $y]
+} "1 \u00a4 \u20ac"
+
+test binary-47.1 {Tcl_BinaryObjCmd: number cache reference count handling} {
+ # This test is only reliable when memory debugging is turned on, but
+ # without even memory debugging it should still generate the expected
+ # answers and might therefore still pick up memory corruption caused by
+ # [Bug 851747].
+ list [binary scan aba ccc x x x] $x
+} {3 97}
+
+### TIP#129: endian specifiers ----
+
+# format t
+test binary-48.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format t
+} -result {not enough arguments for all format specifiers}
+test binary-48.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format t blat
+} -result {expected integer but got "blat"}
+test binary-48.3 {Tcl_BinaryObjCmd: format} {
+ binary format S0 0x50
+} {}
+test binary-48.4 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format t 0x50
+} \x00P
+test binary-48.5 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format t 0x50
+} P\x00
+test binary-48.6 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format t 0x5052
+} PR
+test binary-48.7 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format t 0x5052
+} RP
+test binary-48.8 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format t 0x505251 0x53
+} RQ
+test binary-48.9 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format t 0x505251 0x53
+} QR
+test binary-48.10 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format t2 {0x50 0x52}
+} \x00P\x00R
+test binary-48.11 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format t2 {0x50 0x52}
+} P\x00R\x00
+test binary-48.12 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format t* {0x5051 0x52}
+} PQ\x00R
+test binary-48.13 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format t* {0x5051 0x52}
+} QPR\x00
+test binary-48.14 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format t2 {0x50 0x52 0x53} 0x54
+} \x00P\x00R
+test binary-48.15 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format t2 {0x50 0x52 0x53} 0x54
+} P\x00R\x00
+test binary-48.16 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format t2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-48.17 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {0x50 0x51}
+ binary format t $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-48.18 {Tcl_BinaryObjCmd: format} bigEndian {
+ set a {0x50 0x51}
+ binary format t1 $a
+} \x00P
+test binary-48.19 {Tcl_BinaryObjCmd: format} littleEndian {
+ set a {0x50 0x51}
+ binary format t1 $a
+} P\x00
+
+# format n
+test binary-49.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format n
+} -result {not enough arguments for all format specifiers}
+test binary-49.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format n blat
+} -result {expected integer but got "blat"}
+test binary-49.3 {Tcl_BinaryObjCmd: format} {
+ binary format n0 0x50
+} {}
+test binary-49.4 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format n 0x50
+} P\x00\x00\x00
+test binary-49.5 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format n 0x5052
+} RP\x00\x00
+test binary-49.6 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format n 0x505251 0x53
+} QRP\x00
+test binary-49.7 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format i1 {0x505251 0x53}
+} QRP\x00
+test binary-49.8 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format n 0x53525150
+} PQRS
+test binary-49.9 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format n2 {0x50 0x52}
+} P\x00\x00\x00R\x00\x00\x00
+test binary-49.10 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format n* {0x50515253 0x52}
+} SRQPR\x00\x00\x00
+test binary-49.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format n2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-49.12 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {0x50 0x51}
+ binary format n $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-49.13 {Tcl_BinaryObjCmd: format} littleEndian {
+ set a {0x50 0x51}
+ binary format n1 $a
+} P\x00\x00\x00
+test binary-49.14 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format n 0x50
+} \x00\x00\x00P
+test binary-49.15 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format n 0x5052
+} \x00\x00PR
+test binary-49.16 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format n 0x505251 0x53
+} \x00PRQ
+test binary-49.17 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format i1 {0x505251 0x53}
+} QRP\x00
+test binary-49.18 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format n 0x53525150
+} SRQP
+test binary-49.19 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format n2 {0x50 0x52}
+} \x00\x00\x00P\x00\x00\x00R
+test binary-49.20 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format n* {0x50515253 0x52}
+} PQRS\x00\x00\x00R
+
+# format m
+test binary-50.1 {Tcl_BinaryObjCmd: format wide int} littleEndian {
+ binary format m 7810179016327718216
+} HelloTcl
+test binary-50.2 {Tcl_BinaryObjCmd: format wide int} bigEndian {
+ binary format m 7810179016327718216
+} lcTolleH
+test binary-50.3 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} littleEndian {
+ binary scan [binary format m [expr {wide(3) << 31}]] w x
+ set x
+} 6442450944
+test binary-50.4 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} bigEndian {
+ binary scan [binary format m [expr {wide(3) << 31}]] W x
+ set x
+} 6442450944
+
+# format Q/q
+test binary-51.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format Q
+} -result {not enough arguments for all format specifiers}
+test binary-51.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format q blat
+} -result {expected floating-point number but got "blat"}
+test binary-51.3 {Tcl_BinaryObjCmd: format} {
+ binary format q0 1.6
+} {}
+test binary-51.4 {Tcl_BinaryObjCmd: format} {} {
+ binary format Q 1.6
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a
+test binary-51.5 {Tcl_BinaryObjCmd: format} {} {
+ binary format q 1.6
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f
+test binary-51.6 {Tcl_BinaryObjCmd: format} {} {
+ binary format Q* {1.6 3.4}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-51.7 {Tcl_BinaryObjCmd: format} {} {
+ binary format q* {1.6 3.4}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-51.8 {Tcl_BinaryObjCmd: format} {} {
+ binary format Q2 {1.6 3.4}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-51.9 {Tcl_BinaryObjCmd: format} {} {
+ binary format q2 {1.6 3.4}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-51.10 {Tcl_BinaryObjCmd: format} {} {
+ binary format Q2 {1.6 3.4 5.6}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-51.11 {Tcl_BinaryObjCmd: format} {} {
+ binary format q2 {1.6 3.4 5.6}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-51.14 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format q2 {1.6}
+} -result {number of elements in list does not match count}
+test binary-51.15 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {1.6 3.4}
+ binary format q $a
+} -result "expected floating-point number but got \"1.6 3.4\""
+test binary-51.16 {Tcl_BinaryObjCmd: format} {} {
+ set a {1.6 3.4}
+ binary format Q1 $a
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a
+test binary-51.17 {Tcl_BinaryObjCmd: format} {} {
+ set a {1.6 3.4}
+ binary format q1 $a
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f
+
+# format R/r
+test binary-53.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format r
+} -result {not enough arguments for all format specifiers}
+test binary-53.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format r blat
+} -result {expected floating-point number but got "blat"}
+test binary-53.3 {Tcl_BinaryObjCmd: format} {
+ binary format f0 1.6
+} {}
+test binary-53.4 {Tcl_BinaryObjCmd: format} {} {
+ binary format R 1.6
+} \x3f\xcc\xcc\xcd
+test binary-53.5 {Tcl_BinaryObjCmd: format} {} {
+ binary format r 1.6
+} \xcd\xcc\xcc\x3f
+test binary-53.6 {Tcl_BinaryObjCmd: format} {} {
+ binary format R* {1.6 3.4}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-53.7 {Tcl_BinaryObjCmd: format} {} {
+ binary format r* {1.6 3.4}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-53.8 {Tcl_BinaryObjCmd: format} {} {
+ binary format R2 {1.6 3.4}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-53.9 {Tcl_BinaryObjCmd: format} {} {
+ binary format r2 {1.6 3.4}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-53.10 {Tcl_BinaryObjCmd: format} {} {
+ binary format R2 {1.6 3.4 5.6}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-53.11 {Tcl_BinaryObjCmd: format} {} {
+ binary format r2 {1.6 3.4 5.6}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-53.12 {Tcl_BinaryObjCmd: float overflow} {} {
+ binary format R -3.402825e+38
+} \xff\x7f\xff\xff
+test binary-53.13 {Tcl_BinaryObjCmd: float overflow} {} {
+ binary format r -3.402825e+38
+} \xff\xff\x7f\xff
+test binary-53.14 {Tcl_BinaryObjCmd: float underflow} {} {
+ binary format R -3.402825e-100
+} \x80\x00\x00\x00
+test binary-53.15 {Tcl_BinaryObjCmd: float underflow} {} {
+ binary format r -3.402825e-100
+} \x00\x00\x00\x80
+test binary-53.16 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format r2 {1.6}
+} -result {number of elements in list does not match count}
+test binary-53.17 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {1.6 3.4}
+ binary format r $a
+} -result "expected floating-point number but got \"1.6 3.4\""
+test binary-53.18 {Tcl_BinaryObjCmd: format} {} {
+ set a {1.6 3.4}
+ binary format R1 $a
+} \x3f\xcc\xcc\xcd
+test binary-53.19 {Tcl_BinaryObjCmd: format} {} {
+ set a {1.6 3.4}
+ binary format r1 $a
+} \xcd\xcc\xcc\x3f
+
+# scan t (s)
+test binary-54.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc t
+} -result {not enough arguments for all format specifiers}
+test binary-54.2 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 t* arg1] $arg1
+} {1 {-23726 21587}}
+test binary-54.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 t arg1] $arg1
+} {1 -23726}
+test binary-54.4 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 t1 arg1] $arg1
+} {1 -23726}
+test binary-54.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 t0 arg1] $arg1
+} {1 {}}
+test binary-54.6 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 t2 arg1] $arg1
+} {1 {-23726 21587}}
+test binary-54.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 t1 arg1] $arg1
+} {0 foo}
+test binary-54.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 t1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-54.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x52\xa3\x53\x54\x05 t2c* arg1 arg2] $arg1 $arg2
+} {2 {-23726 21587} 5}
+test binary-54.10 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x00\x80\x00\x80 tut arg1 arg2] $arg1 $arg2
+} {2 32768 -32768}
+test binary-54.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x00\x80\x00\x80 ttu arg1 arg2] $arg1 $arg2
+} {2 -32768 32768}
+
+# scan t (b)
+test binary-55.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc t
+} -result {not enough arguments for all format specifiers}
+test binary-55.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 t* arg1] $arg1
+} {1 {21155 21332}}
+test binary-55.3 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 t arg1] $arg1
+} {1 21155}
+test binary-55.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 t1 arg1] $arg1
+} {1 21155}
+test binary-55.5 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 t0 arg1] $arg1
+} {1 {}}
+test binary-55.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 t2 arg1] $arg1
+} {1 {21155 21332}}
+test binary-55.7 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 t1 arg1] $arg1
+} {0 foo}
+test binary-55.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 t1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-55.9 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x52\xa3\x53\x54\x05 t2c* arg1 arg2] $arg1 $arg2
+} {2 {21155 21332} 5}
+test binary-55.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x80\x00\x80\x00 tut arg1 arg2] $arg1 $arg2
+} {2 32768 -32768}
+test binary-55.11 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x80\x00\x80\x00 ttu arg1 arg2] $arg1 $arg2
+} {2 -32768 32768}
+
+# scan n (s)
+test binary-56.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc n
+} -result {not enough arguments for all format specifiers}
+test binary-56.2 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n* arg1] $arg1
+} {1 {1414767442 67305985}}
+test binary-56.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n arg1] $arg1
+} {1 1414767442}
+test binary-56.4 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 n1 arg1] $arg1
+} {1 1414767442}
+test binary-56.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53 n0 arg1] $arg1
+} {1 {}}
+test binary-56.6 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n2 arg1] $arg1
+} {1 {1414767442 67305985}}
+test binary-56.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 n1 arg1] $arg1
+} {0 foo}
+test binary-56.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53\x53\x54 n1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-56.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04\x05 n2c* arg1 arg2] $arg1 $arg2
+} {2 {1414767442 67305985} 5}
+test binary-56.10 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x80\x00\x00\x00\x80\x00\x00\x00 nun arg1 arg2] $arg1 $arg2
+} {2 128 128}
+test binary-56.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x00\x00\x00\x80\x00\x00\x00\x80 nun arg1 arg2] $arg1 $arg2
+} {2 2147483648 -2147483648}
+
+# scan n (b)
+test binary-57.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc n
+} -result {not enough arguments for all format specifiers}
+test binary-57.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n* arg1] $arg1
+} {1 {1386435412 16909060}}
+test binary-57.3 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n arg1] $arg1
+} {1 1386435412}
+test binary-57.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 n1 arg1] $arg1
+} {1 1386435412}
+test binary-57.5 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53 n0 arg1] $arg1
+} {1 {}}
+test binary-57.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n2 arg1] $arg1
+} {1 {1386435412 16909060}}
+test binary-57.7 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 n1 arg1] $arg1
+} {0 foo}
+test binary-57.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53\x53\x54 n1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-57.9 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04\x05 n2c* arg1 arg2] $arg1 $arg2
+} {2 {1386435412 16909060} 5}
+test binary-57.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x80\x00\x00\x00\x80\x00\x00\x00 nun arg1 arg2] $arg1 $arg2
+} {2 2147483648 -2147483648}
+test binary-57.11 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x00\x00\x00\x80\x00\x00\x00\x80 nun arg1 arg2] $arg1 $arg2
+} {2 128 128}
+
+# scan Q/q
+test binary-58.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc q
+} -result {not enough arguments for all format specifiers}
+test binary-58.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 Q* arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-58.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 q* arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-58.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 Q arg1] $arg1
+} {1 1.6}
+test binary-58.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 q arg1] $arg1
+} {1 1.6}
+test binary-58.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a Q1 arg1] $arg1
+} {1 1.6}
+test binary-58.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f q1 arg1] $arg1
+} {1 1.6}
+test binary-58.8 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a Q0 arg1] $arg1
+} {1 {}}
+test binary-58.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f q0 arg1] $arg1
+} {1 {}}
+test binary-58.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 Q2 arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-58.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 q2 arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-58.12 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 q1 arg1] $arg1
+} {0 foo}
+test binary-58.13 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a q1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-58.14 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33\x05 Q2c* arg1 arg2] $arg1 $arg2
+} {2 {1.6 3.4} 5}
+test binary-58.15 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40\x05 q2c* arg1 arg2] $arg1 $arg2
+} {2 {1.6 3.4} 5}
+
+# scan R/r
+test binary-59.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc r
+} -result {not enough arguments for all format specifiers}
+test binary-59.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a R* arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-59.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 r* arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-59.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a R arg1] $arg1
+} {1 1.600000023841858}
+test binary-59.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 r arg1] $arg1
+} {1 1.600000023841858}
+test binary-59.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd R1 arg1] $arg1
+} {1 1.600000023841858}
+test binary-59.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f r1 arg1] $arg1
+} {1 1.600000023841858}
+test binary-59.8 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd R0 arg1] $arg1
+} {1 {}}
+test binary-59.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f r0 arg1] $arg1
+} {1 {}}
+test binary-59.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a R2 arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-59.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 r2 arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-59.12 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 r1 arg1] $arg1
+} {0 foo}
+test binary-59.13 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x3f\xcc\xcc\xcd r1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-59.14 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a\x05 R2c* arg1 arg2] $arg1 $arg2
+} {2 {1.600000023841858 3.4000000953674316} 5}
+test binary-59.15 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40\x05 r2c* arg1 arg2] $arg1 $arg2
+} {2 {1.600000023841858 3.4000000953674316} 5}
+
+test binary-60.1 {[binary format] with NaN} -body {
+ binary scan [binary format dqQfrR NaN NaN NaN NaN NaN NaN] dqQfrR \
+ v1 v2 v3 v4 v5 v6
+ list $v1 $v2 $v3 $v4 $v5 $v6
+} -match regexp -result {NaN(\([[:xdigit:]]+\))? NaN(\([[:xdigit:]]+\))? NaN(\([[:xdigit:]]+\))? NaN(\([[:xdigit:]]+\))? NaN(\([[:xdigit:]]+\))? NaN(\([[:xdigit:]]+\))?}
+
+# scan m
+test binary-61.1 {Tcl_BinaryObjCmd: scan wide int} bigEndian {
+ binary scan HelloTcl m x
+ set x
+} 5216694956358656876
+test binary-61.2 {Tcl_BinaryObjCmd: scan wide int} littleEndian {
+ binary scan lcTolleH m x
+ set x
+} 5216694956358656876
+test binary-61.3 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} littleEndian {
+ binary scan [binary format w [expr {wide(3) << 31}]] m x
+ set x
+} 6442450944
+test binary-61.4 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} bigEndian {
+ binary scan [binary format W [expr {wide(3) << 31}]] m x
+ set x
+} 6442450944
+
+# scan/format infinities
+
+test binary-62.1 {infinity} ieeeFloatingPoint {
+ binary scan [binary format q Infinity] w w
+ format 0x%016lx $w
+} 0x7ff0000000000000
+test binary-62.2 {infinity} ieeeFloatingPoint {
+ binary scan [binary format q -Infinity] w w
+ format 0x%016lx $w
+} 0xfff0000000000000
+test binary-62.3 {infinity} ieeeFloatingPoint {
+ binary scan [binary format q Inf] w w
+ format 0x%016lx $w
+} 0x7ff0000000000000
+test binary-62.4 {infinity} ieeeFloatingPoint {
+ binary scan [binary format q -Infinity] w w
+ format 0x%016lx $w
+} 0xfff0000000000000
+test binary-62.5 {infinity} ieeeFloatingPoint {
+ binary scan [binary format w 0x7ff0000000000000] q d
+ set d
+} Inf
+test binary-62.6 {infinity} ieeeFloatingPoint {
+ binary scan [binary format w 0xfff0000000000000] q d
+ set d
+} -Inf
+
+# scan/format Not-a-Number
+
+test binary-63.1 {NaN} ieeeFloatingPoint {
+ binary scan [binary format q NaN] w w
+ format 0x%016lx [expr {$w & 0xfff3ffffffffffff}]
+} 0x7ff0000000000000
+test binary-63.2 {NaN} ieeeFloatingPoint {
+ binary scan [binary format q -NaN] w w
+ format 0x%016lx [expr {$w & 0xfff3ffffffffffff}]
+} 0xfff0000000000000
+test binary-63.3 {NaN} ieeeFloatingPoint {
+ binary scan [binary format q NaN(3123456789aBc)] w w
+ format 0x%016lx [expr {$w & 0xfff3ffffffffffff}]
+} 0x7ff3123456789abc
+test binary-63.4 {NaN} ieeeFloatingPoint {
+ binary scan [binary format q {NaN( 3123456789aBc)}] w w
+ format 0x%016lx [expr {$w & 0xfff3ffffffffffff}]
+} 0x7ff3123456789abc
+
+# Make sure TclParseNumber() rejects invalid nan-hex formats [Bug 3402540]
+test binary-63.5 {NaN} -constraints ieeeFloatingPoint -body {
+ binary format q Nan(
+} -returnCodes error -match glob -result {expected floating-point number*}
+test binary-63.6 {NaN} -constraints ieeeFloatingPoint -body {
+ binary format q Nan()
+} -returnCodes error -match glob -result {expected floating-point number*}
+test binary-63.7 {NaN} -constraints ieeeFloatingPoint -body {
+ binary format q Nan(g)
+} -returnCodes error -match glob -result {expected floating-point number*}
+test binary-63.8 {NaN} -constraints ieeeFloatingPoint -body {
+ binary format q Nan(1,2)
+} -returnCodes error -match glob -result {expected floating-point number*}
+test binary-63.9 {NaN} -constraints ieeeFloatingPoint -body {
+ binary format q Nan(1234567890abcd)
+} -returnCodes error -match glob -result {expected floating-point number*}
+
+test binary-64.1 {NaN} -constraints ieeeFloatingPoint -body {
+ binary scan [binary format w 0x7ff8000000000000] q d
+ set d
+} -match glob -result NaN*
+test binary-64.2 {NaN} -constraints ieeeFloatingPoint -body {
+ binary scan [binary format w 0x7ff0123456789aBc] q d
+ set d
+} -match glob -result NaN(*123456789abc)
+
+test binary-65.1 {largest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x3fcfffffffffffff] q d
+ set d
+} 0.24999999999999997
+test binary-65.2 {smallest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x3fd0000000000000] q d
+ set d
+} 0.25
+test binary-65.3 {largest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x3fdfffffffffffff] q d
+ set d
+} 0.49999999999999994
+test binary-65.4 {smallest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x3fe0000000000000] q d
+ set d
+} 0.5
+test binary-65.5 {largest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x3fffffffffffffff] q d
+ set d
+} 1.9999999999999998
+test binary-65.6 {smallest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x4000000000000000] q d
+ set d
+} 2.0
+test binary-65.7 {smallest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x434fffffffffffff] q d
+ set d
+} 18014398509481982.0
+test binary-65.8 {largest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x4350000000000000] q d
+ set d
+} 18014398509481984.0
+test binary-65.9 {largest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x4350000000000001] q d
+ set d
+} 18014398509481988.0
+
+test binary-70.1 {binary encode hex} -body {
+ binary encode hex
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-70.2 {binary encode hex} -body {
+ binary encode hex a
+} -result {61}
+test binary-70.3 {binary encode hex} -body {
+ binary encode hex {}
+} -result {}
+test binary-70.4 {binary encode hex} -body {
+ binary encode hex [string repeat a 20]
+} -result [string repeat 61 20]
+test binary-70.5 {binary encode hex} -body {
+ binary encode hex \0\1\2\3\4\0\1\2\3\4
+} -result {00010203040001020304}
+
+test binary-71.1 {binary decode hex} -body {
+ binary decode hex
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-71.2 {binary decode hex} -body {
+ binary decode hex 61
+} -result {a}
+test binary-71.3 {binary decode hex} -body {
+ binary decode hex {}
+} -result {}
+test binary-71.4 {binary decode hex} -body {
+ binary decode hex [string repeat 61 20]
+} -result [string repeat a 20]
+test binary-71.5 {binary decode hex} -body {
+ binary decode hex 00010203040001020304
+} -result "\0\1\2\3\4\0\1\2\3\4"
+test binary-71.6 {binary decode hex} -body {
+ binary decode hex "61 61"
+} -result {aa}
+test binary-71.7 {binary decode hex} -body {
+ binary decode hex "61\n\n\n61"
+} -result {aa}
+test binary-71.8 {binary decode hex} -body {
+ binary decode hex -strict "61 61"
+} -returnCodes error -result {invalid hexadecimal digit " " at position 2}
+test binary-71.9 {binary decode hex} -body {
+ set r [binary decode hex "6"]
+ list [string length $r] $r
+} -result {0 {}}
+test binary-71.10 {binary decode hex} -body {
+ string length [binary decode hex " "]
+} -result 0
+
+test binary-72.1 {binary encode base64} -body {
+ binary encode base64
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-72.2 {binary encode base64} -body {
+ binary encode base64 abc
+} -result {YWJj}
+test binary-72.3 {binary encode base64} -body {
+ binary encode base64 {}
+} -result {}
+test binary-72.4 {binary encode base64} -body {
+ binary encode base64 [string repeat abc 20]
+} -result [string repeat YWJj 20]
+test binary-72.5 {binary encode base64} -body {
+ binary encode base64 \0\1\2\3\4\0\1\2\3
+} -result {AAECAwQAAQID}
+test binary-72.6 {binary encode base64} -body {
+ binary encode base64 \0
+} -result {AA==}
+test binary-72.7 {binary encode base64} -body {
+ binary encode base64 \0\0
+} -result {AAA=}
+test binary-72.8 {binary encode base64} -body {
+ binary encode base64 \0\0\0
+} -result {AAAA}
+test binary-72.9 {binary encode base64} -body {
+ binary encode base64 \0\0\0\0
+} -result {AAAAAA==}
+test binary-72.10 {binary encode base64} -body {
+ binary encode base64 -maxlen 0 -wrapchar : abcabcabc
+} -result {YWJjYWJjYWJj}
+test binary-72.11 {binary encode base64} -body {
+ binary encode base64 -maxlen 1 -wrapchar : abcabcabc
+} -result {Y:W:J:j:Y:W:J:j:Y:W:J:j}
+test binary-72.12 {binary encode base64} -body {
+ binary encode base64 -maxlen 2 -wrapchar : abcabcabc
+} -result {YW:Jj:YW:Jj:YW:Jj}
+test binary-72.13 {binary encode base64} -body {
+ binary encode base64 -maxlen 3 -wrapchar : abcabcabc
+} -result {YWJ:jYW:JjY:WJj}
+test binary-72.14 {binary encode base64} -body {
+ binary encode base64 -maxlen 4 -wrapchar : abcabcabc
+} -result {YWJj:YWJj:YWJj}
+test binary-72.15 {binary encode base64} -body {
+ binary encode base64 -maxlen 5 -wrapchar : abcabcabc
+} -result {YWJjY:WJjYW:Jj}
+test binary-72.16 {binary encode base64} -body {
+ binary encode base64 -maxlen 6 -wrapchar : abcabcabc
+} -result {YWJjYW:JjYWJj}
+test binary-72.17 {binary encode base64} -body {
+ binary encode base64 -maxlen 7 -wrapchar : abcabcabc
+} -result {YWJjYWJ:jYWJj}
+test binary-72.18 {binary encode base64} -body {
+ binary encode base64 -maxlen 8 -wrapchar : abcabcabc
+} -result {YWJjYWJj:YWJj}
+test binary-72.19 {binary encode base64} -body {
+ binary encode base64 -maxlen 9 -wrapchar : abcabcabc
+} -result {YWJjYWJjY:WJj}
+test binary-72.20 {binary encode base64} -body {
+ binary encode base64 -maxlen 10 -wrapchar : abcabcabc
+} -result {YWJjYWJjYW:Jj}
+test binary-72.21 {binary encode base64} -body {
+ binary encode base64 -maxlen 11 -wrapchar : abcabcabc
+} -result {YWJjYWJjYWJ:j}
+test binary-72.22 {binary encode base64} -body {
+ binary encode base64 -maxlen 12 -wrapchar : abcabcabc
+} -result {YWJjYWJjYWJj}
+test binary-72.23 {binary encode base64} -body {
+ binary encode base64 -maxlen 13 -wrapchar : abcabcabc
+} -result {YWJjYWJjYWJj}
+test binary-72.24 {binary encode base64} -body {
+ binary encode base64 -maxlen 60 -wrapchar : abcabcabc
+} -result {YWJjYWJjYWJj}
+test binary-72.25 {binary encode base64} -body {
+ binary encode base64 -maxlen 2 -wrapchar * abcabcabc
+} -result {YW*Jj*YW*Jj*YW*Jj}
+test binary-72.26 {binary encode base64} -body {
+ binary encode base64 -maxlen 6 -wrapchar -*- abcabcabc
+} -result {YWJjYW-*-JjYWJj}
+test binary-72.27 {binary encode base64} -body {
+ binary encode base64 -maxlen 4 -wrapchar -*- abcabcabc
+} -result {YWJj-*-YWJj-*-YWJj}
+test binary-72.28 {binary encode base64} -body {
+ binary encode base64 -maxlen 6 -wrapchar 0123456789 abcabcabc
+} -result {YWJjYW0123456789JjYWJj}
+
+test binary-73.1 {binary decode base64} -body {
+ binary decode base64
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-73.2 {binary decode base64} -body {
+ binary decode base64 YWJj
+} -result {abc}
+test binary-73.3 {binary decode base64} -body {
+ binary decode base64 {}
+} -result {}
+test binary-73.4 {binary decode base64} -body {
+ binary decode base64 [string repeat YWJj 20]
+} -result [string repeat abc 20]
+test binary-73.5 {binary encode base64} -body {
+ binary decode base64 AAECAwQAAQID
+} -result "\0\1\2\3\4\0\1\2\3"
+test binary-73.6 {binary encode base64} -body {
+ binary decode base64 AA==
+} -result "\0"
+test binary-73.7 {binary encode base64} -body {
+ binary decode base64 AAA=
+} -result "\0\0"
+test binary-73.8 {binary encode base64} -body {
+ binary decode base64 AAAA
+} -result "\0\0\0"
+test binary-73.9 {binary encode base64} -body {
+ binary decode base64 AAAAAA==
+} -result "\0\0\0\0"
+test binary-73.10 {binary decode base64} -body {
+ set s "[string repeat YWJj 10]\n[string repeat YWJj 10]"
+ binary decode base64 $s
+} -result [string repeat abc 20]
+test binary-73.11 {binary decode base64} -body {
+ set s "[string repeat YWJj 10]\n [string repeat YWJj 10]"
+ binary decode base64 $s
+} -result [string repeat abc 20]
+test binary-73.12 {binary decode base64} -body {
+ binary decode base64 -strict ":YWJj"
+} -returnCodes error -match glob -result {invalid base64 character ":" at position 0}
+test binary-73.13 {binary decode base64} -body {
+ set s "[string repeat YWJj 10]:[string repeat YWJj 10]"
+ binary decode base64 -strict $s
+} -returnCodes error -match glob -result {invalid base64 character ":" at position 40}
+test binary-73.14 {binary decode base64} -body {
+ set s "[string repeat YWJj 10]\n [string repeat YWJj 10]"
+ binary decode base64 -strict $s
+} -returnCodes error -match glob -result {invalid base64 character *}
+test binary-73.20 {binary decode base64} -body {
+ set r [binary decode base64 Y]
+ list [string length $r] $r
+} -result {0 {}}
+test binary-73.21 {binary decode base64} -body {
+ set r [binary decode base64 YW]
+ list [string length $r] $r
+} -result {1 a}
+test binary-73.22 {binary decode base64} -body {
+ set r [binary decode base64 YWJ]
+ list [string length $r] $r
+} -result {2 ab}
+test binary-73.23 {binary decode base64} -body {
+ set r [binary decode base64 YWJj]
+ list [string length $r] $r
+} -result {3 abc}
+test binary-73.24 {binary decode base64} -body {
+ string length [binary decode base64 " "]
+} -result 0
+
+test binary-74.1 {binary encode uuencode} -body {
+ binary encode uuencode
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-74.2 {binary encode uuencode} -body {
+ binary encode uuencode abc
+} -result {86)C}
+test binary-74.3 {binary encode uuencode} -body {
+ binary encode uuencode {}
+} -result {}
+test binary-74.4 {binary encode uuencode} -body {
+ binary encode uuencode [string repeat abc 20]
+} -result [string repeat 86)C 20]
+test binary-74.5 {binary encode uuencode} -body {
+ binary encode uuencode \0\1\2\3\4\0\1\2\3
+} -result "``\$\"`P0``0(#"
+test binary-74.6 {binary encode uuencode} -body {
+ binary encode uuencode \0
+} -result {````}
+test binary-74.7 {binary encode uuencode} -body {
+ binary encode uuencode \0\0
+} -result {````}
+test binary-74.8 {binary encode uuencode} -body {
+ binary encode uuencode \0\0\0
+} -result {````}
+test binary-74.9 {binary encode uuencode} -body {
+ binary encode uuencode \0\0\0\0
+} -result {````````}
+test binary-74.10 {binary encode uuencode} -body {
+ binary encode uuencode -maxlen 0 -wrapchar | abcabcabc
+} -result {86)C86)C86)C}
+test binary-74.11 {binary encode uuencode} -body {
+ binary encode uuencode -maxlen 1 -wrapchar | abcabcabc
+} -result {8|6|)|C|8|6|)|C|8|6|)|C}
+
+test binary-75.1 {binary decode uuencode} -body {
+ binary decode uuencode
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-75.2 {binary decode uuencode} -body {
+ binary decode uuencode 86)C
+} -result {abc}
+test binary-75.3 {binary decode uuencode} -body {
+ binary decode uuencode {}
+} -result {}
+test binary-75.4 {binary decode uuencode} -body {
+ binary decode uuencode [string repeat "86)C" 20]
+} -result [string repeat abc 20]
+test binary-75.5 {binary decode uuencode} -body {
+ binary decode uuencode "``\$\"`P0``0(#"
+} -result "\0\1\2\3\4\0\1\2\3"
+test binary-75.6 {binary decode uuencode} -body {
+ string length [binary decode uuencode {`}]
+} -result 0
+test binary-75.7 {binary decode uuencode} -body {
+ string length [binary decode uuencode {``}]
+} -result 1
+test binary-75.8 {binary decode uuencode} -body {
+ string length [binary decode uuencode {```}]
+} -result 2
+test binary-75.9 {binary decode uuencode} -body {
+ string length [binary decode uuencode {````}]
+} -result 3
+test binary-75.10 {binary decode uuencode} -body {
+ set s "[string repeat 86)C 10]\n[string repeat 86)C 10]"
+ binary decode uuencode $s
+} -result [string repeat abc 20]
+test binary-75.11 {binary decode uuencode} -body {
+ set s "[string repeat 86)C 10]\n [string repeat 86)C 10]"
+ binary decode uuencode $s
+} -result [string repeat abc 20]
+test binary-75.12 {binary decode uuencode} -body {
+ binary decode uuencode -strict "|86)C"
+} -returnCodes error -match glob -result {invalid uuencode character "|" at position 0}
+test binary-75.13 {binary decode uuencode} -body {
+ set s "[string repeat 86)C 10]|[string repeat 86)C 10]"
+ binary decode uuencode -strict $s
+} -returnCodes error -match glob -result {invalid uuencode character "|" at position 40}
+test binary-75.14 {binary decode uuencode} -body {
+ set s "[string repeat 86)C 10]\n [string repeat 86)C 10]"
+ binary decode uuencode -strict $s
+} -returnCodes error -match glob -result {invalid uuencode character *}
+test binary-75.20 {binary decode uuencode} -body {
+ set r [binary decode uuencode 8]
+ list [string length $r] $r
+} -result {0 {}}
+test binary-75.21 {binary decode uuencode} -body {
+ set r [binary decode uuencode 86]
+ list [string length $r] $r
+} -result {1 a}
+test binary-75.22 {binary decode uuencode} -body {
+ set r [binary decode uuencode 86)]
+ list [string length $r] $r
+} -result {2 ab}
+test binary-75.23 {binary decode uuencode} -body {
+ set r [binary decode uuencode 86)C]
+ list [string length $r] $r
+} -result {3 abc}
+test binary-75.24 {binary decode uuencode} -body {
+ set s "04)\# "
+ binary decode uuencode $s
+} -result ABC
+test binary-75.25 {binary decode uuencode} -body {
+ set s "04)\#z"
+ binary decode uuencode $s
+} -returnCodes error -match glob -result {invalid uuencode character "z" at position 4}
+test binary-75.26 {binary decode uuencode} -body {
+ string length [binary decode uuencode " "]
+} -result 0
+
+test binary-76.1 {binary string appending growth algorithm} unix {
+ # Create zero-length byte array first
+ set f [open /dev/null rb]
+ chan configure $f -blocking 0
+ set str [read $f 2]
+ close $f
+ # Append to it
+ string length [append str [binary format a* foo]]
+} 3
+test binary-76.2 {binary string appending growth algorithm} win {
+ # Create zero-length byte array first
+ set f [open NUL rb]
+ chan configure $f -blocking 0
+ set str [read $f 2]
+ close $f
+ # Append to it
+ string length [append str [binary format a* foo]]
+} 3
+
+# ----------------------------------------------------------------------
+# cleanup
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/case.test b/library/msgcat/tests/case.test
new file mode 100644
index 0000000..6d63cea
--- /dev/null
+++ b/library/msgcat/tests/case.test
@@ -0,0 +1,89 @@
+# Commands covered: case
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test case-1.1 {simple pattern} {
+ case a in a {format 1} b {format 2} c {format 3} default {format 4}
+} 1
+test case-1.2 {simple pattern} {
+ case b a {format 1} b {format 2} c {format 3} default {format 4}
+} 2
+test case-1.3 {simple pattern} {
+ case x in a {format 1} b {format 2} c {format 3} default {format 4}
+} 4
+test case-1.4 {simple pattern} {
+ case x a {format 1} b {format 2} c {format 3}
+} {}
+test case-1.5 {simple pattern matches many times} {
+ case b a {format 1} b {format 2} b {format 3} b {format 4}
+} 2
+test case-1.6 {fancier pattern} {
+ case cx a {format 1} *c {format 2} *x {format 3} default {format 4}
+} 3
+test case-1.7 {list of patterns} {
+ case abc in {a b c} {format 1} {def abc ghi} {format 2}
+} 2
+
+test case-2.1 {error in executed command} {
+ list [catch {case a in a {error "Just a test"} default {format 1}} msg] \
+ $msg $::errorInfo
+} {1 {Just a test} {Just a test
+ while executing
+"error "Just a test""
+ ("a" arm line 1)
+ invoked from within
+"case a in a {error "Just a test"} default {format 1}"}}
+test case-2.2 {error: not enough args} {
+ list [catch {case} msg] $msg
+} {1 {wrong # args: should be "case string ?in? ?pattern body ...? ?default body?"}}
+test case-2.3 {error: pattern with no body} {
+ list [catch {case a b} msg] $msg
+} {1 {extra case pattern with no body}}
+test case-2.4 {error: pattern with no body} {
+ list [catch {case a in b {format 1} c} msg] $msg
+} {1 {extra case pattern with no body}}
+test case-2.5 {error in default command} {
+ list [catch {case foo in a {error case1} default {error case2} \
+ b {error case 3}} msg] $msg $::errorInfo
+} {1 case2 {case2
+ while executing
+"error case2"
+ ("default" arm line 1)
+ invoked from within
+"case foo in a {error case1} default {error case2} b {error case 3}"}}
+
+test case-3.1 {single-argument form for pattern/command pairs} {
+ case b in {
+ a {format 1}
+ b {format 2}
+ default {format 6}
+ }
+} {2}
+test case-3.2 {single-argument form for pattern/command pairs} {
+ case b {
+ a {format 1}
+ b {format 2}
+ default {format 6}
+ }
+} {2}
+test case-3.3 {single-argument form for pattern/command pairs} {
+ list [catch {case z in {a 2 b}} msg] $msg
+} {1 {extra case pattern with no body}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/chan.test b/library/msgcat/tests/chan.test
new file mode 100644
index 0000000..da44ffd
--- /dev/null
+++ b/library/msgcat/tests/chan.test
@@ -0,0 +1,275 @@
+# This file contains a collection of tests for the Tcl built-in 'chan'
+# command. Sourcing this file into Tcl runs the tests and generates
+# output for errors. No output means no errors were found.
+#
+# 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+#
+# Note: The tests for the chan methods "create" and "postevent"
+# currently reside in the file "ioCmd.test".
+#
+
+test chan-1.1 {chan command general syntax} -body {
+ chan
+} -returnCodes error -result "wrong # args: should be \"chan subcommand ?arg ...?\""
+test chan-1.2 {chan command general syntax} -body {
+ chan FOOBAR
+} -returnCodes error -match glob -result "unknown or ambiguous subcommand \"FOOBAR\": must be *"
+
+test chan-2.1 {chan command: blocked subcommand} -body {
+ chan blocked foo bar
+} -returnCodes error -result "wrong # args: should be \"chan blocked channelId\""
+test chan-3.1 {chan command: close subcommand} -body {
+ chan close foo bar zet
+} -returnCodes error -result "wrong # args: should be \"chan close channelId ?direction?\""
+test chan-3.2 {chan command: close subcommand} -setup {
+ set chan [open [info script] r]
+} -body {
+ chan close $chan bar
+} -cleanup {
+ close $chan
+} -returnCodes error -result "bad direction \"bar\": must be read or write"
+test chan-3.3 {chan command: close subcommand} -setup {
+ set chan [open [info script] r]
+} -body {
+ chan close $chan write
+} -cleanup {
+ close $chan
+} -returnCodes error -result "Half-close of write-side not possible, side not opened or already closed"
+test chan-4.1 {chan command: configure subcommand} -body {
+ chan configure
+} -returnCodes error -result "wrong # args: should be \"chan configure channelId ?-option value ...?\""
+test chan-4.2 {chan command: [Bug 800753]} -body {
+ chan configure stdout -eofchar \u0100
+} -returnCodes error -match glob -result {bad value*}
+test chan-4.3 {chan command: [Bug 800753]} -body {
+ chan configure stdout -eofchar \u0000
+} -returnCodes error -match glob -result {bad value*}
+test chan-4.4 {chan command: check valid inValue, no outValue} -body {
+ chan configure stdout -eofchar [list \x27 {}]
+} -returnCodes ok -result {}
+test chan-4.5 {chan command: check valid inValue, invalid outValue} -body {
+ chan configure stdout -eofchar [list \x27 \x80]
+} -returnCodes error -match glob -result {bad value for -eofchar:*}
+test chan-4.6 {chan command: check no inValue, valid outValue} -body {
+ chan configure stdout -eofchar [list {} \x27]
+} -returnCodes ok -result {}
+
+test chan-5.1 {chan command: copy subcommand} -body {
+ chan copy foo
+} -returnCodes error -result "wrong # args: should be \"chan copy input output ?-size size? ?-command callback?\""
+
+test chan-6.1 {chan command: eof subcommand} -body {
+ chan eof foo bar
+} -returnCodes error -result "wrong # args: should be \"chan eof channelId\""
+
+test chan-7.1 {chan command: event subcommand} -body {
+ chan event foo
+} -returnCodes error -result "wrong # args: should be \"chan event channelId event ?script?\""
+
+test chan-8.1 {chan command: flush subcommand} -body {
+ chan flush foo bar
+} -returnCodes error -result "wrong # args: should be \"chan flush channelId\""
+
+test chan-9.1 {chan command: gets subcommand} -body {
+ chan gets
+} -returnCodes error -result "wrong # args: should be \"chan gets channelId ?varName?\""
+
+test chan-10.1 {chan command: names subcommand} -body {
+ chan names foo bar
+} -returnCodes error -result "wrong # args: should be \"chan names ?pattern?\""
+
+test chan-11.1 {chan command: puts subcommand} -body {
+ chan puts foo bar foo bar
+} -returnCodes error -result "wrong # args: should be \"chan puts ?-nonewline? ?channelId? string\""
+
+test chan-12.1 {chan command: read subcommand} -body {
+ chan read
+} -returnCodes error -result "wrong # args: should be \"chan read channelId ?numChars?\" or \"chan read ?-nonewline? channelId\""
+
+test chan-13.1 {chan command: seek subcommand} -body {
+ chan seek foo bar foo bar
+} -returnCodes error -result "wrong # args: should be \"chan seek channelId offset ?origin?\""
+
+test chan-14.1 {chan command: tell subcommand} -body {
+ chan tell foo bar
+} -returnCodes error -result "wrong # args: should be \"chan tell channelId\""
+
+test chan-15.1 {chan command: truncate subcommand} -body {
+ chan truncate foo bar foo bar
+} -returnCodes error -result "wrong \# args: should be \"chan truncate channelId ?length?\""
+test chan-15.2 {chan command: truncate subcommand} -setup {
+ set file [makeFile {} testTruncate]
+ set f [open $file w+]
+ fconfigure $f -translation binary
+} -body {
+ seek $f 0
+ puts -nonewline $f 12345
+ seek $f 0
+ chan truncate $f 2
+ read $f
+} -result 12 -cleanup {
+ catch {close $f}
+ catch {removeFile $file}
+}
+
+# TIP 287: chan pending
+test chan-16.1 {chan command: pending subcommand} -body {
+ chan pending
+} -returnCodes error -result "wrong # args: should be \"chan pending mode channelId\""
+test chan-16.2 {chan command: pending subcommand} -body {
+ chan pending stdin
+} -returnCodes error -result "wrong # args: should be \"chan pending mode channelId\""
+test chan-16.3 {chan command: pending subcommand} -body {
+ chan pending stdin stdout stderr
+} -returnCodes error -result "wrong # args: should be \"chan pending mode channelId\""
+test chan-16.4 {chan command: pending subcommand} -body {
+ chan pending {input output} stdout
+} -returnCodes error -result "bad mode \"input output\": must be input or output"
+test chan-16.5 {chan command: pending input subcommand} -body {
+ chan pending input stdout
+} -result -1
+test chan-16.6 {chan command: pending input subcommand} -body {
+ chan pending input stdin
+} -result 0
+test chan-16.7 {chan command: pending input subcommand} -body {
+ chan pending input FOOBAR
+} -returnCodes error -result "can not find channel named \"FOOBAR\""
+test chan-16.8 {chan command: pending input subcommand} -setup {
+ set file [makeFile {} testAvailable]
+ set f [open $file w+]
+ chan configure $f -translation lf -buffering line
+} -body {
+ chan puts $f foo
+ chan puts $f bar
+ chan puts $f baz
+ chan seek $f 0
+ chan gets $f
+ chan pending input $f
+} -result 8 -cleanup {
+ catch {chan close $f}
+ catch {removeFile $file}
+}
+test chan-16.9 {chan command: pending input subcommand} -setup {
+ proc chan-16.9-accept {sock addr port} {
+ chan configure $sock -blocking 0 -buffering line -buffersize 32
+ chan event $sock readable [list chan-16.9-readable $sock]
+ }
+
+ proc chan-16.9-readable {sock} {
+ set r [chan gets $sock line]
+ set l [string length $line]
+ set e [chan eof $sock]
+ set b [chan blocked $sock]
+ set i [chan pending input $sock]
+
+ lappend ::chan-16.9-data $r $l $e $b $i
+
+ if {$r != -1 || $e || $l || !$b || $i > 128} {
+ set data [read $sock $i]
+ lappend ::chan-16.9-data [string range $data 0 2]
+ lappend ::chan-16.9-data [string range $data end-2 end]
+ set ::chan-16.9-done 1
+ chan event $sock readable {}
+ } else {
+ after idle chan-16.9-client
+ }
+ }
+
+ proc chan-16.9-client {} {
+ chan puts -nonewline $::client ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
+ chan flush $::client
+ }
+
+ set ::server [socket -server chan-16.9-accept -myaddr 127.0.0.1 0]
+ set ::client [socket 127.0.0.1 [lindex [fconfigure $::server -sockname] 2]]
+ set ::chan-16.9-data [list]
+ set ::chan-16.9-done 0
+} -body {
+ after idle chan-16.9-client
+ vwait ::chan-16.9-done
+ set ::chan-16.9-data
+} -result {-1 0 0 1 36 -1 0 0 1 72 -1 0 0 1 108 -1 0 0 1 144 ABC 890} -cleanup {
+ catch {chan close $client}
+ catch {chan close $server}
+ rename chan-16.9-accept {}
+ rename chan-16.9-readable {}
+ rename chan-16.9-client {}
+ unset -nocomplain ::chan-16.9-data
+ unset -nocomplain ::chan-16.9-done
+ unset -nocomplain ::server
+ unset -nocomplain ::client
+}
+test chan-16.10 {chan command: pending output subcommand} -body {
+ chan pending output stdin
+} -result -1
+test chan-16.11 {chan command: pending output subcommand} -body {
+ chan pending output stdout
+} -result 0
+test chan-16.12 {chan command: pending output subcommand} -body {
+ chan pending output FOOBAR
+} -returnCodes error -result "can not find channel named \"FOOBAR\""
+test chan-16.13 {chan command: pending output subcommand} -setup {
+ set file [makeFile {} testPendingOutput]
+ set f [open $file w+]
+ chan configure $f -translation lf -buffering full -buffersize 1024
+} -body {
+ set result [list]
+ chan puts $f [string repeat x 512]
+ lappend result [chan pending output $f]
+ chan flush $f
+ lappend result [chan pending output $f]
+} -result [list 513 0] -cleanup {
+ unset -nocomplain result
+ catch {chan close $f}
+ catch {removeFile $file}
+}
+
+# TIP 304: chan pipe
+
+test chan-17.1 {chan command: pipe subcommand} -body {
+ chan pipe foo
+} -returnCodes error -result "wrong # args: should be \"chan pipe \""
+
+test chan-17.2 {chan command: pipe subcommand} -body {
+ chan pipe foo bar
+} -returnCodes error -result "wrong # args: should be \"chan pipe \""
+
+test chan-17.3 {chan command: pipe subcommand} -body {
+ set l [chan pipe]
+ foreach {pr pw} $l break
+ list [llength $l] [fconfigure $pr -blocking] [fconfigure $pw -blocking]
+} -result [list 2 1 1] -cleanup {
+ close $pw
+ close $pr
+}
+
+test chan-17.4 {chan command: pipe subcommand} -body {
+ set ::done 0
+ foreach {::pr ::pw} [chan pipe] break
+ after 100 {puts $::pw foo;flush $::pw}
+ fileevent $::pr readable {set ::done 1}
+ after 500 {set ::done -1}
+ vwait ::done
+ set out nope
+ if {$::done==1} {gets $::pr out}
+ list $::done $out
+} -result [list 1 foo] -cleanup {
+ close $::pw
+ close $::pr
+}
+
+cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/chanio.test b/library/msgcat/tests/chanio.test
new file mode 100644
index 0000000..fbc9854
--- /dev/null
+++ b/library/msgcat/tests/chanio.test
@@ -0,0 +1,7716 @@
+# -*- tcl -*-
+# Functionality covered: operation of all IO commands, and all procedures
+# defined in generic/tclIO.c.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# 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.
+
+if {[catch {package require tcltest 2}]} {
+ chan puts stderr "Skipping tests in [info script]. tcltest 2 required."
+ return
+}
+namespace eval ::tcl::test::io {
+ namespace import ::tcltest::*
+
+ variable umaskValue
+ variable path
+ variable f
+ variable i
+ variable n
+ variable v
+ variable msg
+ variable expected
+
+ testConstraint testchannel [llength [info commands testchannel]]
+ testConstraint exec [llength [info commands exec]]
+ testConstraint openpipe 1
+ testConstraint fileevent [llength [info commands fileevent]]
+ testConstraint fcopy [llength [info commands fcopy]]
+ testConstraint testfevent [llength [info commands testfevent]]
+ testConstraint testchannelevent [llength [info commands testchannelevent]]
+ testConstraint testmainthread [llength [info commands testmainthread]]
+ testConstraint thread [expr {0 == [catch {package require Thread 2.6}]}]
+
+ # You need a *very* special environment to do some tests. In particular,
+ # many file systems do not support large-files...
+ testConstraint largefileSupport 0
+
+ # some tests can only be run is umask is 2 if "umask" cannot be run, the
+ # tests will be skipped.
+ set umaskValue 0
+ testConstraint umask [expr {![catch {set umaskValue [scan [exec /bin/sh -c umask] %o]}]}]
+
+ testConstraint makeFileInHome [expr {![file exists ~/_test_] && [file writable ~]}]
+
+ # set up a long data file for some of the following tests
+
+ set path(longfile) [makeFile {} longfile]
+ set f [open $path(longfile) w]
+ chan configure $f -eofchar {} -translation lf
+ for { set i 0 } { $i < 100 } { incr i} {
+ chan puts $f "#123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
+\#123456789abcdef01
+\#"
+ }
+ chan close $f
+
+ set path(cat) [makeFile {
+ set f stdin
+ if {$argv != ""} {
+ set f [open [lindex $argv 0]]
+ }
+ chan configure $f -encoding binary -translation lf -blocking 0 -eofchar \x1a
+ chan configure stdout -encoding binary -translation lf -buffering none
+ chan event $f readable "foo $f"
+ proc foo {f} {
+ set x [chan read $f]
+ catch {chan puts -nonewline $x}
+ if {[chan eof $f]} {
+ chan close $f
+ exit 0
+ }
+ }
+ vwait forever
+ } cat]
+
+ set thisScript [file join [pwd] [info script]]
+
+ proc contents {file} {
+ set f [open $file]
+ chan configure $f -translation binary
+ set a [chan read $f]
+ chan close $f
+ return $a
+ }
+
+ # Wrapper round butt-ugly pipe syntax
+ proc openpipe {{mode r+} args} {
+ open "|[list [interpreter] {*}$args]" $mode
+ }
+
+test chan-io-1.5 {Tcl_WriteChars: CheckChannelErrors} {emptyTest} {
+ # no test, need to cause an async error.
+} {}
+set path(test1) [makeFile {} test1]
+test chan-io-1.6 {Tcl_WriteChars: WriteBytes} {
+ set f [open $path(test1) w]
+ chan configure $f -encoding binary
+ chan puts -nonewline $f "a\u4e4d\0"
+ chan close $f
+ contents $path(test1)
+} "a\x4d\x00"
+test chan-io-1.7 {Tcl_WriteChars: WriteChars} {
+ set f [open $path(test1) w]
+ chan configure $f -encoding shiftjis
+ chan puts -nonewline $f "a\u4e4d\0"
+ chan close $f
+ contents $path(test1)
+} "a\x93\xe1\x00"
+set path(test2) [makeFile {} test2]
+test chan-io-1.8 {Tcl_WriteChars: WriteChars} {
+ # This test written for SF bug #506297.
+ #
+ # Executing this test without the fix for the referenced bug applied to
+ # tcl will cause tcl, more specifically WriteChars, to go into an infinite
+ # loop.
+ set f [open $path(test2) w]
+ chan configure $f -encoding iso2022-jp
+ chan puts -nonewline $f [format %s%c [string repeat " " 4] 12399]
+ chan close $f
+ contents $path(test2)
+} " \x1b\$B\$O\x1b(B"
+test chan-io-1.9 {Tcl_WriteChars: WriteChars} {
+ # When closing a channel with an encoding that appends escape bytes, check
+ # for the case where the escape bytes overflow the current IO buffer. The
+ # bytes should be moved into a new buffer.
+ set data "1234567890 [format %c 12399]"
+ set sizes [list]
+ # With default buffer size
+ set f [open $path(test2) w]
+ chan configure $f -encoding iso2022-jp
+ chan puts -nonewline $f $data
+ chan close $f
+ lappend sizes [file size $path(test2)]
+ # With buffer size equal to the length of the data, the escape bytes would
+ # go into the next buffer.
+ set f [open $path(test2) w]
+ chan configure $f -encoding iso2022-jp -buffersize 16
+ chan puts -nonewline $f $data
+ chan close $f
+ lappend sizes [file size $path(test2)]
+ # With buffer size that is large enough to hold 1 byte of escaped data,
+ # but not all 3. This should not write the escape bytes to the first
+ # buffer and then again to the second buffer.
+ set f [open $path(test2) w]
+ chan configure $f -encoding iso2022-jp -buffersize 17
+ chan puts -nonewline $f $data
+ chan close $f
+ lappend sizes [file size $path(test2)]
+ # With buffer size that can hold 2 out of 3 bytes of escaped data.
+ set f [open $path(test2) w]
+ chan configure $f -encoding iso2022-jp -buffersize 18
+ chan puts -nonewline $f $data
+ chan close $f
+ lappend sizes [file size $path(test2)]
+ # With buffer size that can hold all the data and escape bytes.
+ set f [open $path(test2) w]
+ chan configure $f -encoding iso2022-jp -buffersize 19
+ chan puts -nonewline $f $data
+ chan close $f
+ lappend sizes [file size $path(test2)]
+} {19 19 19 19 19}
+
+test chan-io-2.1 {WriteBytes} {
+ # loop until all bytes are written
+ set f [open $path(test1) w]
+ chan configure $f -encoding binary -buffersize 16 -translation crlf
+ chan puts $f "abcdefghijklmnopqrstuvwxyz"
+ chan close $f
+ contents $path(test1)
+} "abcdefghijklmnopqrstuvwxyz\r\n"
+test chan-io-2.2 {WriteBytes: savedLF > 0} {
+ # After flushing buffer, there was a \n left over from the last
+ # \n -> \r\n expansion. It gets stuck at beginning of this buffer.
+ set f [open $path(test1) w]
+ chan configure $f -encoding binary -buffersize 16 -translation crlf
+ chan puts -nonewline $f "123456789012345\n12"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "123456789012345\r" "123456789012345\r\n12"]
+test chan-io-2.3 {WriteBytes: flush on line} -body {
+ # Tcl "line" buffering has weird behavior: if current buffer contains a
+ # \n, entire buffer gets flushed. Logical behavior would be to flush only
+ # up to the \n.
+ set f [open $path(test1) w]
+ chan configure $f -encoding binary -buffering line -translation crlf
+ chan puts -nonewline $f "\n12"
+ contents $path(test1)
+} -cleanup {
+ chan close $f
+} -result "\r\n12"
+test chan-io-2.4 {WriteBytes: reset sawLF after each buffer} {
+ set f [open $path(test1) w]
+ chan configure $f -encoding binary -buffering line -translation lf \
+ -buffersize 16
+ chan puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]
+
+test chan-io-3.1 {WriteChars: compatibility with WriteBytes} {
+ # loop until all bytes are written
+ set f [open $path(test1) w]
+ chan configure $f -encoding ascii -buffersize 16 -translation crlf
+ chan puts $f "abcdefghijklmnopqrstuvwxyz"
+ chan close $f
+ contents $path(test1)
+} "abcdefghijklmnopqrstuvwxyz\r\n"
+test chan-io-3.2 {WriteChars: compatibility with WriteBytes: savedLF > 0} {
+ # After flushing buffer, there was a \n left over from the last
+ # \n -> \r\n expansion. It gets stuck at beginning of this buffer.
+ set f [open $path(test1) w]
+ chan configure $f -encoding ascii -buffersize 16 -translation crlf
+ chan puts -nonewline $f "123456789012345\n12"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "123456789012345\r" "123456789012345\r\n12"]
+test chan-io-3.3 {WriteChars: compatibility with WriteBytes: flush on line} -body {
+ # Tcl "line" buffering has weird behavior: if current buffer contains a
+ # \n, entire buffer gets flushed. Logical behavior would be to flush only
+ # up to the \n.
+ set f [open $path(test1) w]
+ chan configure $f -encoding ascii -buffering line -translation crlf
+ chan puts -nonewline $f "\n12"
+ contents $path(test1)
+} -cleanup {
+ chan close $f
+} -result "\r\n12"
+test chan-io-3.4 {WriteChars: loop over stage buffer} {
+ # stage buffer maps to more than can be queued at once.
+ set f [open $path(test1) w]
+ chan configure $f -encoding jis0208 -buffersize 16
+ chan puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test chan-io-3.5 {WriteChars: saved != 0} {
+ # Bytes produced by UtfToExternal from end of last channel buffer had to
+ # be moved to beginning of next channel buffer to preserve requested
+ # buffersize.
+ set f [open $path(test1) w]
+ chan configure $f -encoding jis0208 -buffersize 17
+ chan puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test chan-io-3.6 {WriteChars: (stageRead + dstWrote == 0)} {
+ # One incomplete UTF-8 character at end of staging buffer. Backup in src
+ # to the beginning of that UTF-8 character and try again.
+ #
+ # Translate the first 16 bytes, produce 14 bytes of output, 2 left over
+ # (first two bytes of \uff21 in UTF-8). Given those two bytes try
+ # translating them again, find that no bytes are read produced, and break
+ # to outer loop where those two bytes will have the remaining 4 bytes (the
+ # last byte of \uff21 plus the all of \uff22) appended.
+ set f [open $path(test1) w]
+ chan configure $f -encoding shiftjis -buffersize 16
+ chan puts -nonewline $f "12345678901234\uff21\uff22"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "12345678901234\x82\x60" "12345678901234\x82\x60\x82\x61"]
+test chan-io-3.7 {WriteChars: (bufPtr->nextAdded > bufPtr->length)} {
+ # When translating UTF-8 to external, the produced bytes went past end of
+ # the channel buffer. This is done on purpose - we then truncate the bytes
+ # at the end of the partial character to preserve the requested blocksize
+ # on flush. The truncated bytes are moved to the beginning of the next
+ # channel buffer.
+ set f [open $path(test1) w]
+ chan configure $f -encoding jis0208 -buffersize 17
+ chan puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test chan-io-3.8 {WriteChars: reset sawLF after each buffer} {
+ set f [open $path(test1) w]
+ chan configure $f -encoding ascii -buffering line -translation lf \
+ -buffersize 16
+ chan puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]
+
+test chan-io-4.1 {TranslateOutputEOL: lf} {
+ # search for \n
+ set f [open $path(test1) w]
+ chan configure $f -buffering line -translation lf
+ chan puts $f "abcde"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "abcde\n" "abcde\n"]
+test chan-io-4.2 {TranslateOutputEOL: cr} {
+ # search for \n, replace with \r
+ set f [open $path(test1) w]
+ chan configure $f -buffering line -translation cr
+ chan puts $f "abcde"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "abcde\r" "abcde\r"]
+test chan-io-4.3 {TranslateOutputEOL: crlf} {
+ # simple case: search for \n, replace with \r
+ set f [open $path(test1) w]
+ chan configure $f -buffering line -translation crlf
+ chan puts $f "abcde"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "abcde\r\n" "abcde\r\n"]
+test chan-io-4.4 {TranslateOutputEOL: crlf} {
+ # Keep storing more bytes in output buffer until output buffer is full. We
+ # have 13 bytes initially that would turn into 18 bytes. Fill dest buffer
+ # while (dstEnd < dstMax).
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -buffersize 16
+ chan puts -nonewline $f "1234567\n\n\n\n\nA"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "1234567\r\n\r\n\r\n\r\n\r" "1234567\r\n\r\n\r\n\r\n\r\nA"]
+test chan-io-4.5 {TranslateOutputEOL: crlf} {
+ # Check for overflow of the destination buffer
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -buffersize 12
+ chan puts -nonewline $f "12345678901\n456789012345678901234"
+ chan close $f
+ set x [contents $path(test1)]
+} "12345678901\r\n456789012345678901234"
+
+test chan-io-5.1 {CheckFlush: not full} {
+ set f [open $path(test1) w]
+ chan configure $f
+ chan puts -nonewline $f "12345678901234567890"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "" "12345678901234567890"]
+test chan-io-5.2 {CheckFlush: full} {
+ set f [open $path(test1) w]
+ chan configure $f -buffersize 16
+ chan puts -nonewline $f "12345678901234567890"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "1234567890123456" "12345678901234567890"]
+test chan-io-5.3 {CheckFlush: not line} {
+ set f [open $path(test1) w]
+ chan configure $f -buffering line
+ chan puts -nonewline $f "12345678901234567890"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "" "12345678901234567890"]
+test chan-io-5.4 {CheckFlush: line} {
+ set f [open $path(test1) w]
+ chan configure $f -buffering line -translation lf -encoding ascii
+ chan puts -nonewline $f "1234567890\n1234567890"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "1234567890\n1234567890" "1234567890\n1234567890"]
+test chan-io-5.5 {CheckFlush: none} {
+ set f [open $path(test1) w]
+ chan configure $f -buffering none
+ chan puts -nonewline $f "1234567890"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "1234567890" "1234567890"]
+
+test chan-io-6.1 {Tcl_GetsObj: working} -body {
+ set f [open $path(test1) w]
+ chan puts $f "foo\nboo"
+ chan close $f
+ set f [open $path(test1)]
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result {foo}
+test chan-io-6.2 {Tcl_GetsObj: CheckChannelErrors() != 0} emptyTest {
+ # no test, need to cause an async error.
+} {}
+test chan-io-6.3 {Tcl_GetsObj: how many have we used?} -body {
+ # if (bufPtr != NULL) {oldRemoved = bufPtr->nextRemoved}
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f "abc\ndefg"
+ chan close $f
+ set f [open $path(test1)]
+ list [chan tell $f] [chan gets $f line] [chan tell $f] [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {0 3 5 4 defg}
+test chan-io-6.4 {Tcl_GetsObj: encoding == NULL} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation binary
+ chan puts $f "\x81\u1234\0"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation binary
+ list [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 3 "\x81\x34\x00"]
+test chan-io-6.5 {Tcl_GetsObj: encoding != NULL} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation binary
+ chan puts $f "\x88\xea\x92\x9a"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding shiftjis
+ list [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 2 "\u4e00\u4e01"]
+set a "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
+append a $a
+append a $a
+test chan-io-6.6 {Tcl_GetsObj: loop test} -body {
+ # if (dst >= dstEnd)
+ set f [open $path(test1) w]
+ chan puts $f $a
+ chan puts $f hi
+ chan close $f
+ set f [open $path(test1)]
+ list [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 256 $a]
+test chan-io-6.7 {Tcl_GetsObj: error in input} -constraints {stdio openpipe} -body {
+ # if (FilterInputBytes(chanPtr, &gs) != 0)
+ set f [openpipe w+ $path(cat)]
+ chan puts -nonewline $f "hi\nwould"
+ chan flush $f
+ chan gets $f
+ chan configure $f -blocking 0
+ chan gets $f line
+} -cleanup {
+ chan close $f
+} -result {-1}
+test chan-io-6.8 {Tcl_GetsObj: remember if EOF is seen} -body {
+ set f [open $path(test1) w]
+ chan puts $f "abcdef\x1aghijk\nwombat"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -eofchar \x1a
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {6 abcdef -1 {}}
+test chan-io-6.9 {Tcl_GetsObj: remember if EOF is seen} -body {
+ set f [open $path(test1) w]
+ chan puts $f "abcdefghijk\nwom\u001abat"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -eofchar \x1a
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {11 abcdefghijk 3 wom}
+# Comprehensive tests
+test chan-io-6.10 {Tcl_GetsObj: lf mode: no chars} -body {
+ set f [open $path(test1) w]
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation lf
+ list [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {-1 {}}
+test chan-io-6.11 {Tcl_GetsObj: lf mode: lone \n} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation lf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.12 {Tcl_GetsObj: lf mode: lone \r} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation lf
+ set x [list [chan gets $f line] $line [chan gets $f line] $line]
+} -cleanup {
+ chan close $f
+} -result [list 1 "\r" -1 ""]
+test chan-io-6.13 {Tcl_GetsObj: lf mode: 1 char} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f a
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation lf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.14 {Tcl_GetsObj: lf mode: 1 char followed by EOL} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation lf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.15 {Tcl_GetsObj: lf mode: several chars} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation lf
+ list [chan gets $f line] $line [chan gets $f line] $line \
+ [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 4 "abcd" 10 "efgh\rijkl\r" 4 "mnop" -1 ""]
+test chan-io-6.16 {Tcl_GetsObj: cr mode: no chars} -body {
+ set f [open $path(test1) w]
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation cr
+ list [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {-1 {}}
+test chan-io-6.17 {Tcl_GetsObj: cr mode: lone \n} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation cr
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 1 "\n" -1 ""]
+test chan-io-6.18 {Tcl_GetsObj: cr mode: lone \r} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation cr
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.19 {Tcl_GetsObj: cr mode: 1 char} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f a
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation cr
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.20 {Tcl_GetsObj: cr mode: 1 char followed by EOL} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation cr
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.21 {Tcl_GetsObj: cr mode: several chars} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation cr
+ list [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 9 "abcd\nefgh" 4 "ijkl" 5 "\nmnop" -1 ""]
+test chan-io-6.22 {Tcl_GetsObj: crlf mode: no chars} -body {
+ set f [open $path(test1) w]
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ list [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {-1 {}}
+test chan-io-6.23 {Tcl_GetsObj: crlf mode: lone \n} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 1 "\n" -1 ""]
+test chan-io-6.24 {Tcl_GetsObj: crlf mode: lone \r} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 1 "\r" -1 ""]
+test chan-io-6.25 {Tcl_GetsObj: crlf mode: \r\r} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 2 "\r\r" -1 ""]
+test chan-io-6.26 {Tcl_GetsObj: crlf mode: \r\n} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.27 {Tcl_GetsObj: crlf mode: 1 char} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f a
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.28 {Tcl_GetsObj: crlf mode: 1 char followed by EOL} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\r\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.29 {Tcl_GetsObj: crlf mode: several chars} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ list [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 14 "abcd\nefgh\rijkl" 4 "mnop" -1 ""]
+test chan-io-6.30 {Tcl_GetsObj: crlf mode: buffer exhausted} -constraints {testchannel} -body {
+ # if (eol >= dstEnd)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456789012345\r\nabcdefghijklmnoprstuvwxyz"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf -buffersize 16
+ list [chan gets $f line] $line [testchannel inputbuffered $f]
+} -cleanup {
+ chan close $f
+} -result [list 15 "123456789012345" 15]
+test chan-io-6.31 {Tcl_GetsObj: crlf mode: buffer exhausted, blocked} -setup {
+ set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # (FilterInputBytes() != 0)
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {crlf lf} -buffering none
+ chan puts -nonewline $f "bbbbbbbbbbbbbb\r\n123456789012345\r"
+ chan configure $f -buffersize 16
+ lappend x [chan gets $f]
+ chan configure $f -blocking 0
+ lappend x [chan gets $f line] $line [chan blocked $f] \
+ [testchannel inputbuffered $f]
+} -cleanup {
+ chan close $f
+} -result {bbbbbbbbbbbbbb -1 {} 1 16}
+test chan-io-6.32 {Tcl_GetsObj: crlf mode: buffer exhausted, more data} -constraints {testchannel} -body {
+ # not (FilterInputBytes() != 0)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456789012345\r\n123"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf -buffersize 16
+ list [chan gets $f line] $line [chan tell $f] [testchannel inputbuffered $f]
+} -cleanup {
+ chan close $f
+} -result {15 123456789012345 17 3}
+test chan-io-6.33 {Tcl_GetsObj: crlf mode: buffer exhausted, at eof} -body {
+ # eol still equals dstEnd
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456789012345\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf -buffersize 16
+ list [chan gets $f line] $line [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result [list 16 "123456789012345\r" 1]
+test chan-io-6.34 {Tcl_GetsObj: crlf mode: buffer exhausted, not followed by \n} -body {
+ # not (*eol == '\n')
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456789012345\rabcd\r\nefg"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf -buffersize 16
+ list [chan gets $f line] $line [chan tell $f]
+} -cleanup {
+ chan close $f
+} -result [list 20 "123456789012345\rabcd" 22]
+test chan-io-6.35 {Tcl_GetsObj: auto mode: no chars} -body {
+ set f [open $path(test1) w]
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ list [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {-1 {}}
+test chan-io-6.36 {Tcl_GetsObj: auto mode: lone \n} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.37 {Tcl_GetsObj: auto mode: lone \r} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.38 {Tcl_GetsObj: auto mode: \r\r} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ list [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {0 {} 0 {} -1 {}}
+test chan-io-6.39 {Tcl_GetsObj: auto mode: \r\n} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.40 {Tcl_GetsObj: auto mode: 1 char} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f a
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.41 {Tcl_GetsObj: auto mode: 1 char followed by EOL} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\r\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.42 {Tcl_GetsObj: auto mode: several chars} -setup {
+ set x ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ lappend x [chan gets $f line] $line [chan gets $f line] $line
+ lappend x [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {4 abcd 4 efgh 4 ijkl 4 mnop -1 {}}
+test chan-io-6.43 {Tcl_GetsObj: input saw cr} -setup {
+ set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # if (chanPtr->flags & INPUT_SAW_CR)
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {auto lf} -buffering none
+ chan puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+ chan configure $f -buffersize 16
+ lappend x [chan gets $f]
+ chan configure $f -blocking 0
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+ chan configure $f -blocking 1
+ chan puts -nonewline $f "\nabcd\refg\x1a"
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+ lappend x [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {bbbbbbbbbbbbbbb 15 123456789abcdef 1 4 abcd 0 3 efg}
+test chan-io-6.44 {Tcl_GetsObj: input saw cr, not followed by cr} -setup {
+ set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # not (*eol == '\n')
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {auto lf} -buffering none
+ chan puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+ chan configure $f -buffersize 16
+ lappend x [chan gets $f]
+ chan configure $f -blocking 0
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+ chan configure $f -blocking 1
+ chan puts -nonewline $f "abcd\refg\x1a"
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+ lappend x [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {bbbbbbbbbbbbbbb 15 123456789abcdef 1 4 abcd 0 3 efg}
+test chan-io-6.45 {Tcl_GetsObj: input saw cr, skip right number of bytes} -setup {
+ set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # Tcl_ExternalToUtf()
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {auto lf} -buffering none
+ chan configure $f -encoding unicode
+ chan puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+ chan configure $f -buffersize 16
+ chan gets $f
+ chan configure $f -blocking 0
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+ chan configure $f -blocking 1
+ chan puts -nonewline $f "\nabcd\refg"
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+} -cleanup {
+ chan close $f
+} -result {15 123456789abcdef 1 4 abcd 0}
+test chan-io-6.46 {Tcl_GetsObj: input saw cr, followed by just \n should give eof} -setup {
+ set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # memmove()
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {auto lf} -buffering none
+ chan puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+ chan configure $f -buffersize 16
+ chan gets $f
+ chan configure $f -blocking 0
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+ chan configure $f -blocking 1
+ chan puts -nonewline $f "\n\x1a"
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+} -cleanup {
+ chan close $f
+} -result {15 123456789abcdef 1 -1 {} 0}
+test chan-io-6.47 {Tcl_GetsObj: auto mode: \r at end of buffer, peek for \n} -constraints {testchannel} -body {
+ # (eol == dstEnd)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456789012345\r\nabcdefghijklmnopq"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto -buffersize 16
+ list [chan gets $f] [testchannel inputbuffered $f]
+} -cleanup {
+ chan close $f
+} -result {123456789012345 15}
+test chan-io-6.48 {Tcl_GetsObj: auto mode: \r at end of buffer, no more avail} -constraints {testchannel} -body {
+ # PeekAhead() did not get any, so (eol >= dstEnd)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456789012345\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto -buffersize 16
+ list [chan gets $f] [testchannel queuedcr $f]
+} -cleanup {
+ chan close $f
+} -result {123456789012345 1}
+test chan-io-6.49 {Tcl_GetsObj: auto mode: \r followed by \n} -constraints {testchannel} -body {
+ # if (*eol == '\n') {skip++}
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456\r\n78901"
+ chan close $f
+ set f [open $path(test1)]
+ list [chan gets $f] [testchannel queuedcr $f] [chan tell $f] [chan gets $f]
+} -cleanup {
+ chan close $f
+} -result {123456 0 8 78901}
+test chan-io-6.50 {Tcl_GetsObj: auto mode: \r not followed by \n} -constraints {testchannel} -body {
+ # not (*eol == '\n')
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456\r78901"
+ chan close $f
+ set f [open $path(test1)]
+ list [chan gets $f] [testchannel queuedcr $f] [chan tell $f] [chan gets $f]
+} -cleanup {
+ chan close $f
+} -result {123456 0 7 78901}
+test chan-io-6.51 {Tcl_GetsObj: auto mode: \n} -body {
+ # else if (*eol == '\n') {goto gotoeol;}
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456\n78901"
+ chan close $f
+ set f [open $path(test1)]
+ list [chan gets $f] [chan tell $f] [chan gets $f]
+} -cleanup {
+ chan close $f
+} -result {123456 7 78901}
+test chan-io-6.52 {Tcl_GetsObj: saw EOF character} -constraints {testchannel} -body {
+ # if (eof != NULL)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456\x1ak9012345\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -eofchar \x1a
+ list [chan gets $f] [testchannel queuedcr $f] [chan tell $f] [chan gets $f]
+} -cleanup {
+ chan close $f
+} -result {123456 0 6 {}}
+test chan-io-6.53 {Tcl_GetsObj: device EOF} -body {
+ # didn't produce any bytes
+ set f [open $path(test1) w]
+ chan close $f
+ set f [open $path(test1)]
+ list [chan gets $f line] $line [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {-1 {} 1}
+test chan-io-6.54 {Tcl_GetsObj: device EOF} -body {
+ # got some bytes before EOF.
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abc
+ chan close $f
+ set f [open $path(test1)]
+ list [chan gets $f line] $line [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {3 abc 1}
+test chan-io-6.55 {Tcl_GetsObj: overconverted} -body {
+ # Tcl_ExternalToUtf(), make sure state updated
+ set f [open $path(test1) w]
+ chan configure $f -encoding iso2022-jp
+ chan puts $f "there\u4e00ok\n\u4e01more bytes\nhere"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding iso2022-jp
+ list [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 8 "there\u4e00ok" 11 "\u4e01more bytes" 4 "here"]
+test chan-io-6.56 {Tcl_GetsObj: incomplete lines should disable file events} -setup {
+ update
+ variable x {}
+} -constraints {stdio openpipe fileevent} -body {
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -buffering none
+ chan puts -nonewline $f "foobar"
+ chan configure $f -blocking 0
+ after 500 [namespace code {
+ lappend x timeout
+ }]
+ chan event $f readable [namespace code {
+ lappend x [chan gets $f]
+ }]
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ chan configure $f -blocking 1
+ chan puts -nonewline $f "baz\n"
+ after 500 [namespace code {
+ lappend x timeout
+ }]
+ chan configure $f -blocking 0
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ chan close $f
+} -result {{} timeout foobarbaz timeout}
+
+test chan-io-7.1 {FilterInputBytes: split up character at end of buffer} -body {
+ # (result == TCL_CONVERT_MULTIBYTE)
+ set f [open $path(test1) w]
+ chan configure $f -encoding shiftjis
+ chan puts $f "1234567890123\uff10\uff11\uff12\uff13\uff14\nend"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding shiftjis -buffersize 16
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result "1234567890123\uff10\uff11\uff12\uff13\uff14"
+test chan-io-7.2 {FilterInputBytes: split up character in middle of buffer} -body {
+ # (bufPtr->nextAdded < bufPtr->bufLength)
+ set f [open $path(test1) w]
+ chan configure $f -encoding binary
+ chan puts -nonewline $f "1234567890\n123\x82\x4f\x82\x50\x82"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding shiftjis
+ list [chan gets $f line] $line [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {10 1234567890 0}
+test chan-io-7.3 {FilterInputBytes: split up character at EOF} -setup {
+ set x ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ chan configure $f -encoding binary
+ chan puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding shiftjis
+ lappend x [chan gets $f line] $line
+ lappend x [chan tell $f] [testchannel inputbuffered $f] [chan eof $f]
+ lappend x [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 15 "1234567890123\uff10\uff11" 18 0 1 -1 ""]
+test chan-io-7.4 {FilterInputBytes: recover from split up character} -setup {
+ variable x ""
+} -constraints {stdio openpipe fileevent} -body {
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -encoding binary -buffering none
+ chan puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
+ chan configure $f -encoding shiftjis -blocking 0
+ chan event $f read [namespace code {
+ lappend x [chan gets $f line] $line [chan blocked $f]
+ }]
+ vwait [namespace which -variable x]
+ chan configure $f -encoding binary -blocking 1
+ chan puts $f "\x51\x82\x52"
+ chan configure $f -encoding shiftjis
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ chan close $f
+} -result [list -1 "" 1 17 "1234567890123\uff10\uff11\uff12\uff13" 0]
+
+test chan-io-8.1 {PeekAhead: only go to device if no more cached data} -constraints {testchannel} -body {
+ # (bufPtr->nextPtr == NULL)
+ set f [open $path(test1) w]
+ chan configure $f -encoding ascii -translation lf
+ chan puts -nonewline $f "123456789012345\r\n2345678"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding ascii -translation auto -buffersize 16
+ # here
+ chan gets $f
+ testchannel inputbuffered $f
+} -cleanup {
+ chan close $f
+} -result 7
+test chan-io-8.2 {PeekAhead: only go to device if no more cached data} -setup {
+ variable x {}
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # not (bufPtr->nextPtr == NULL)
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation lf -encoding ascii -buffering none
+ chan puts -nonewline $f "123456789012345\r\nbcdefghijklmnopqrstuvwxyz"
+ chan event $f read [namespace code {
+ lappend x [chan gets $f line] $line [testchannel inputbuffered $f]
+ }]
+ chan configure $f -encoding unicode -buffersize 16 -blocking 0
+ vwait [namespace which -variable x]
+ chan configure $f -translation auto -encoding ascii -blocking 1
+ # here
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ chan close $f
+} -result {-1 {} 42 15 123456789012345 25}
+test chan-io-8.3 {PeekAhead: no cached data available} -constraints {stdio testchannel openpipe fileevent} -body {
+ # (bytesLeft == 0)
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {auto binary}
+ chan puts -nonewline $f "abcdefghijklmno\r"
+ chan flush $f
+ list [chan gets $f line] $line [testchannel queuedcr $f]
+} -cleanup {
+ chan close $f
+} -result {15 abcdefghijklmno 1}
+set a "123456789012345678901234567890"
+append a "123456789012345678901234567890"
+append a "1234567890123456789012345678901"
+test chan-io-8.4 {PeekAhead: cached data available in this buffer} -body {
+ # not (bytesLeft == 0)
+ set f [open $path(test1) w+]
+ chan configure $f -translation binary
+ chan puts $f "${a}\r\nabcdef"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding binary -translation auto
+ # "${a}\r" was converted in one operation (because ENCODING_LINESIZE is
+ # 30). To check if "\n" follows, calls PeekAhead and determines that
+ # cached data is available in buffer w/o having to call driver.
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result $a
+unset a
+test chan-io-8.5 {PeekAhead: don't peek if last read was short} -constraints {stdio testchannel openpipe fileevent} -body {
+ # (bufPtr->nextAdded < bufPtr->length)
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {auto binary}
+ chan puts -nonewline $f "abcdefghijklmno\r"
+ chan flush $f
+ # here
+ list [chan gets $f line] $line [testchannel queuedcr $f]
+} -cleanup {
+ chan close $f
+} -result {15 abcdefghijklmno 1}
+test chan-io-8.6 {PeekAhead: change to non-blocking mode} -constraints {stdio testchannel openpipe fileevent} -body {
+ # ((chanPtr->flags & CHANNEL_NONBLOCKING) == 0)
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {auto binary} -buffersize 16
+ chan puts -nonewline $f "abcdefghijklmno\r"
+ chan flush $f
+ # here
+ list [chan gets $f line] $line [testchannel queuedcr $f]
+} -cleanup {
+ chan close $f
+} -result {15 abcdefghijklmno 1}
+test chan-io-8.7 {PeekAhead: cleanup} -setup {
+ set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # Make sure bytes are removed from buffer.
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {auto binary} -buffering none
+ chan puts -nonewline $f "abcdefghijklmno\r"
+ # here
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+ chan puts -nonewline $f "\x1a"
+ lappend x [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {15 abcdefghijklmno 1 -1 {}}
+
+test chan-io-9.1 {CommonGetsCleanup} emptyTest {
+} {}
+
+test chan-io-10.1 {Tcl_ReadChars: CheckChannelErrors} emptyTest {
+ # no test, need to cause an async error.
+} {}
+test chan-io-10.2 {Tcl_ReadChars: loop until enough copied} -body {
+ # one time
+ # for (copied = 0; (unsigned) toRead > 0; )
+ set f [open $path(test1) w]
+ chan puts $f abcdefghijklmnop
+ chan close $f
+ set f [open $path(test1)]
+ chan read $f 5
+} -cleanup {
+ chan close $f
+} -result {abcde}
+test chan-io-10.3 {Tcl_ReadChars: loop until enough copied} -body {
+ # multiple times
+ # for (copied = 0; (unsigned) toRead > 0; )
+ set f [open $path(test1) w]
+ chan puts $f abcdefghijklmnopqrstuvwxyz
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -buffersize 16
+ # here
+ chan read $f 19
+} -cleanup {
+ chan close $f
+} -result {abcdefghijklmnopqrs}
+test chan-io-10.4 {Tcl_ReadChars: no more in channel buffer} -body {
+ # (copiedNow < 0)
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abcdefghijkl
+ chan close $f
+ set f [open $path(test1)]
+ # here
+ chan read $f 1000
+} -cleanup {
+ chan close $f
+} -result {abcdefghijkl}
+test chan-io-10.5 {Tcl_ReadChars: stop on EOF} -body {
+ # (chanPtr->flags & CHANNEL_EOF)
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abcdefghijkl
+ chan close $f
+ set f [open $path(test1)]
+ # here
+ chan read $f 1000
+} -cleanup {
+ chan close $f
+} -result {abcdefghijkl}
+
+test chan-io-11.1 {ReadBytes: want to read a lot} -body {
+ # ((unsigned) toRead > (unsigned) srcLen)
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abcdefghijkl
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding binary
+ # here
+ chan read $f 1000
+} -cleanup {
+ chan close $f
+} -result {abcdefghijkl}
+test chan-io-11.2 {ReadBytes: want to read all} -body {
+ # ((unsigned) toRead > (unsigned) srcLen)
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abcdefghijkl
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding binary
+ # here
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result {abcdefghijkl}
+test chan-io-11.3 {ReadBytes: allocate more space} -body {
+ # (toRead > length - offset - 1)
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abcdefghijklmnopqrstuvwxyz
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -buffersize 16 -encoding binary
+ # here
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result {abcdefghijklmnopqrstuvwxyz}
+test chan-io-11.4 {ReadBytes: EOF char found} -body {
+ # (TranslateInputEOL() != 0)
+ set f [open $path(test1) w]
+ chan puts $f abcdefghijklmnopqrstuvwxyz
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -eofchar m -encoding binary
+ # here
+ list [chan read $f] [chan eof $f] [chan read $f] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abcdefghijkl 1 {} 1}
+
+test chan-io-12.1 {ReadChars: want to read a lot} -body {
+ # ((unsigned) toRead > (unsigned) srcLen)
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abcdefghijkl
+ chan close $f
+ set f [open $path(test1)]
+ # here
+ chan read $f 1000
+} -cleanup {
+ chan close $f
+} -result {abcdefghijkl}
+test chan-io-12.2 {ReadChars: want to read all} -body {
+ # ((unsigned) toRead > (unsigned) srcLen)
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abcdefghijkl
+ chan close $f
+ set f [open $path(test1)]
+ # here
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result {abcdefghijkl}
+test chan-io-12.3 {ReadChars: allocate more space} -body {
+ # (toRead > length - offset - 1)
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abcdefghijklmnopqrstuvwxyz
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -buffersize 16
+ # here
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result {abcdefghijklmnopqrstuvwxyz}
+test chan-io-12.4 {ReadChars: split-up char} -setup {
+ variable x {}
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # (srcRead == 0)
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -encoding binary -buffering none -buffersize 16
+ chan puts -nonewline $f "123456789012345\x96"
+ chan configure $f -encoding shiftjis -blocking 0
+ chan event $f read [namespace code {
+ lappend x [chan read $f] [testchannel inputbuffered $f]
+ }]
+ chan configure $f -encoding shiftjis
+ vwait [namespace which -variable x]
+ chan configure $f -encoding binary -blocking 1
+ chan puts -nonewline $f "\x7b"
+ after 500 ;# Give the cat process time to catch up
+ chan configure $f -encoding shiftjis -blocking 0
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ chan close $f
+} -result [list "123456789012345" 1 "\u672c" 0]
+test chan-io-12.5 {ReadChars: chan events on partial characters} -setup {
+ variable x {}
+} -constraints {stdio openpipe fileevent} -body {
+ set path(test1) [makeFile {
+ chan configure stdout -encoding binary -buffering none
+ chan gets stdin; chan puts -nonewline "\xe7"
+ chan gets stdin; chan puts -nonewline "\x89"
+ chan gets stdin; chan puts -nonewline "\xa6"
+ } test1]
+ set f [openpipe r+ $path(test1)]
+ chan event $f readable [namespace code {
+ lappend x [chan read $f]
+ if {[chan eof $f]} {
+ lappend x eof
+ }
+ }]
+ chan puts $f "go1"
+ chan flush $f
+ chan configure $f -blocking 0 -encoding utf-8
+ vwait [namespace which -variable x]
+ after 500 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ chan puts $f "go2"
+ chan flush $f
+ vwait [namespace which -variable x]
+ after 500 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ chan puts $f "go3"
+ chan flush $f
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ lappend x [catch {chan close $f} msg] $msg
+} -result "{} timeout {} timeout \u7266 {} eof 0 {}"
+
+test chan-io-13.1 {TranslateInputEOL: cr mode} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\rdef\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation cr
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\ndef\n"
+test chan-io-13.2 {TranslateInputEOL: crlf mode} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\r\ndef\r\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\ndef\n"
+test chan-io-13.3 {TranslateInputEOL: crlf mode: naked cr} -body {
+ # (src >= srcMax)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\r\ndef\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\ndef\r"
+test chan-io-13.4 {TranslateInputEOL: crlf mode: cr followed by not \n} -body {
+ # (src >= srcMax)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\r\ndef\rfgh"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\ndef\rfgh"
+test chan-io-13.5 {TranslateInputEOL: crlf mode: naked lf} -body {
+ # (src >= srcMax)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\r\ndef\nfgh"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\ndef\nfgh"
+test chan-io-13.6 {TranslateInputEOL: auto mode: saw cr in last segment} -setup {
+ variable x {}
+ variable y {}
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # (chanPtr->flags & INPUT_SAW_CR)
+ # This test may fail on slower machines.
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -blocking 0 -buffering none -translation {auto lf}
+ chan event $f read [namespace code {
+ lappend x [chan read $f] [testchannel queuedcr $f]
+ }]
+ chan puts -nonewline $f "abcdefghj\r"
+ after 500 [namespace code {set y ok}]
+ vwait [namespace which -variable y]
+ chan puts -nonewline $f "\n01234"
+ after 500 [namespace code {set y ok}]
+ vwait [namespace which -variable y]
+ return $x
+} -cleanup {
+ chan close $f
+} -result [list "abcdefghj\n" 1 "01234" 0]
+test chan-io-13.7 {TranslateInputEOL: auto mode: naked \r} -constraints {testchannel openpipe} -body {
+ # (src >= srcMax)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ list [chan read $f] [testchannel queuedcr $f]
+} -cleanup {
+ chan close $f
+} -result [list "abcd\n" 1]
+test chan-io-13.8 {TranslateInputEOL: auto mode: \r\n} -body {
+ # (*src == '\n')
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\r\ndef"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\ndef"
+test chan-io-13.9 {TranslateInputEOL: auto mode: \r followed by not \n} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\rdef"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\ndef"
+test chan-io-13.10 {TranslateInputEOL: auto mode: \n} -body {
+ # not (*src == '\r')
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\ndef"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\ndef"
+test chan-io-13.11 {TranslateInputEOL: EOF char} -body {
+ # (*chanPtr->inEofChar != '\0')
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\ndefgh"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto -eofchar e
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\nd"
+test chan-io-13.12 {TranslateInputEOL: find EOF char in src} -body {
+ # (*chanPtr->inEofChar != '\0')
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r\n\r\n\r\nab\r\n\r\ndef\r\n\r\n\r\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto -eofchar e
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "\n\n\nab\n\nd"
+
+# Test standard handle management. The functions tested are Tcl_SetStdChannel
+# and Tcl_GetStdChannel. Incidentally we are also testing channel table
+# management.
+
+if {[testConstraint testchannel]} {
+ set consoleFileNames [lsort [testchannel open]]
+} else {
+ # just to avoid an error
+ set consoleFileNames [list]
+}
+
+test chan-io-14.1 {Tcl_SetStdChannel and Tcl_GetStdChannel} {testchannel} {
+ set result ""
+ lappend result [chan configure stdin -buffering]
+ lappend result [chan configure stdout -buffering]
+ lappend result [chan configure stderr -buffering]
+ lappend result [lsort [testchannel open]]
+} [list line line none $consoleFileNames]
+test chan-io-14.2 {Tcl_SetStdChannel and Tcl_GetStdChannel} -setup {
+ interp create x
+ set result ""
+} -body {
+ lappend result [x eval {chan configure stdin -buffering}]
+ lappend result [x eval {chan configure stdout -buffering}]
+ lappend result [x eval {chan configure stderr -buffering}]
+} -cleanup {
+ interp delete x
+} -result {line line none}
+set path(test3) [makeFile {} test3]
+test chan-io-14.3 {Tcl_SetStdChannel & Tcl_GetStdChannel} -constraints {exec openpipe} -body {
+ set f [open $path(test1) w]
+ chan puts -nonewline $f {
+ chan close stdin
+ chan close stdout
+ chan close stderr
+ set f [}
+ chan puts $f [list open $path(test1) r]]
+ chan puts $f "set f2 \[[list open $path(test2) w]]"
+ chan puts $f "set f3 \[[list open $path(test3) w]]"
+ chan puts $f { chan puts stdout [chan gets stdin]
+ chan puts stdout out
+ chan puts stderr err
+ chan close $f
+ chan close $f2
+ chan close $f3
+ }
+ chan close $f
+ set result [exec [interpreter] $path(test1)]
+ set f [open $path(test2) r]
+ set f2 [open $path(test3) r]
+ lappend result [chan read $f] [chan read $f2]
+} -cleanup {
+ chan close $f
+ chan close $f2
+} -result {{
+out
+} {err
+}}
+# This test relies on the fact that stdout is used before stderr.
+test chan-io-14.4 {Tcl_SetStdChannel & Tcl_GetStdChannel} -constraints {exec} -body {
+ set f [open $path(test1) w]
+ chan puts -nonewline $f { chan close stdin
+ chan close stdout
+ chan close stderr
+ set f [}
+ chan puts $f [list open $path(test1) r]]
+ chan puts $f "set f2 \[[list open $path(test2) w]]"
+ chan puts $f "set f3 \[[list open $path(test3) w]]"
+ chan puts $f {
+ chan puts stdout [chan gets stdin]
+ chan puts stdout $f2
+ chan puts stderr $f3
+ chan close $f
+ chan close $f2
+ chan close $f3
+ }
+ chan close $f
+ set result [exec [interpreter] $path(test1)]
+ set f [open $path(test2) r]
+ set f2 [open $path(test3) r]
+ lappend result [chan read $f] [chan read $f2]
+} -cleanup {
+ chan close $f
+ chan close $f2
+} -result {{ chan close stdin
+stdout
+} {stderr
+}}
+catch {interp delete z}
+test chan-io-14.5 {Tcl_GetChannel: stdio name translation} -setup {
+ interp create z
+} -body {
+ chan eof stdin
+ catch {z eval chan flush stdin} msg1
+ catch {z eval chan close stdin} msg2
+ catch {z eval chan flush stdin} msg3
+ list $msg1 $msg2 $msg3
+} -cleanup {
+ interp delete z
+} -result {{channel "stdin" wasn't opened for writing} {} {can not find channel named "stdin"}}
+test chan-io-14.6 {Tcl_GetChannel: stdio name translation} -setup {
+ interp create z
+} -body {
+ chan eof stdout
+ catch {z eval chan flush stdout} msg1
+ catch {z eval chan close stdout} msg2
+ catch {z eval chan flush stdout} msg3
+ list $msg1 $msg2 $msg3
+} -cleanup {
+ interp delete z
+} -result {{} {} {can not find channel named "stdout"}}
+test chan-io-14.7 {Tcl_GetChannel: stdio name translation} -setup {
+ interp create z
+} -body {
+ chan eof stderr
+ catch {z eval chan flush stderr} msg1
+ catch {z eval chan close stderr} msg2
+ catch {z eval chan flush stderr} msg3
+ list $msg1 $msg2 $msg3
+} -cleanup {
+ interp delete z
+} -result {{} {} {can not find channel named "stderr"}}
+set path(script) [makeFile {} script]
+test chan-io-14.8 {reuse of stdio special channels} -setup {
+ file delete $path(script)
+ file delete $path(test1)
+} -constraints {stdio openpipe} -body {
+ set f [open $path(script) w]
+ chan puts -nonewline $f {
+ chan close stderr
+ set f [}
+ chan puts $f [list open $path(test1) w]]
+ chan puts -nonewline $f {
+ chan puts stderr hello
+ chan close $f
+ set f [}
+ chan puts $f [list open $path(test1) r]]
+ chan puts $f {
+ chan puts [chan gets $f]
+ }
+ chan close $f
+ set f [openpipe r $path(script)]
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result hello
+test chan-io-14.9 {reuse of stdio special channels} -setup {
+ file delete $path(script)
+ file delete $path(test1)
+} -constraints {stdio openpipe fileevent} -body {
+ set f [open $path(script) w]
+ chan puts $f {
+ array set path [lindex $argv 0]
+ set f [open $path(test1) w]
+ chan puts $f hello
+ chan close $f
+ chan close stderr
+ set f [open "|[list [info nameofexecutable] $path(cat) $path(test1)]" r]
+ chan puts [chan gets $f]
+ }
+ chan close $f
+ set f [openpipe r $path(script) [array get path]]
+ chan gets $f
+} -cleanup {
+ chan close $f
+ # Added delay to give Windows time to stop the spawned process and clean
+ # up its grip on the file test1. Added delete as proper test cleanup.
+ # The failing tests were 18.1 and 18.2 as first re-users of file "test1".
+ after [expr {[testConstraint win] ? 10000 : 500}]
+ file delete $path(script)
+ file delete $path(test1)
+} -result hello
+
+test chan-io-15.1 {Tcl_CreateChan CloseHandler} emptyTest {
+} {}
+
+test chan-io-16.1 {Tcl_DeleteChan CloseHandler} emptyTest {
+} {}
+
+# Test channel table management. The functions tested are GetChannelTable,
+# DeleteChannelTable, Tcl_RegisterChannel, Tcl_UnregisterChannel,
+# Tcl_GetChannel and Tcl_CreateChannel.
+#
+# These functions use "eof stdin" to ensure that the standard channels are
+# added to the channel table of the interpreter.
+
+test chan-io-17.1 {GetChannelTable, DeleteChannelTable on std handles} -setup {
+ set l ""
+} -constraints {testchannel} -body {
+ set l1 [testchannel refcount stdin]
+ chan eof stdin
+ interp create x
+ lappend l [expr {[testchannel refcount stdin] - $l1}]
+ x eval {chan eof stdin}
+ lappend l [expr {[testchannel refcount stdin] - $l1}]
+ interp delete x
+ lappend l [expr {[testchannel refcount stdin] - $l1}]
+} -result {0 1 0}
+test chan-io-17.2 {GetChannelTable, DeleteChannelTable on std handles} -setup {
+ set l ""
+} -constraints {testchannel} -body {
+ set l1 [testchannel refcount stdout]
+ chan eof stdin
+ interp create x
+ lappend l [expr {[testchannel refcount stdout] - $l1}]
+ x eval {chan eof stdout}
+ lappend l [expr {[testchannel refcount stdout] - $l1}]
+ interp delete x
+ lappend l [expr {[testchannel refcount stdout] - $l1}]
+} -result {0 1 0}
+test chan-io-17.3 {GetChannelTable, DeleteChannelTable on std handles} -setup {
+ set l ""
+} -constraints {testchannel} -body {
+ set l1 [testchannel refcount stderr]
+ chan eof stdin
+ interp create x
+ lappend l [expr {[testchannel refcount stderr] - $l1}]
+ x eval {chan eof stderr}
+ lappend l [expr {[testchannel refcount stderr] - $l1}]
+ interp delete x
+ lappend l [expr {[testchannel refcount stderr] - $l1}]
+} -result {0 1 0}
+
+test chan-io-18.1 {Tcl_RegisterChannel, Tcl_UnregisterChannel} -setup {
+ file delete -force $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ lappend l [lindex [testchannel info $f] 15]
+ chan close $f
+ if {[catch {lindex [testchannel info $f] 15} msg]} {
+ lappend l $msg
+ } else {
+ lappend l "very broken: $f found after being chan closed"
+ }
+ string equal $l [list 1 "can not find channel named \"$f\""]
+} -result 1
+test chan-io-18.2 {Tcl_RegisterChannel, Tcl_UnregisterChannel} -setup {
+ file delete -force $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ lappend l [lindex [testchannel info $f] 15]
+ interp create x
+ interp share "" $f x
+ lappend l [lindex [testchannel info $f] 15]
+ x eval chan close $f
+ lappend l [lindex [testchannel info $f] 15]
+ interp delete x
+ lappend l [lindex [testchannel info $f] 15]
+ chan close $f
+ if {[catch {lindex [testchannel info $f] 15} msg]} {
+ lappend l $msg
+ } else {
+ lappend l "very broken: $f found after being chan closed"
+ }
+ string equal $l [list 1 2 1 1 "can not find channel named \"$f\""]
+} -result 1
+test chan-io-18.3 {Tcl_RegisterChannel, Tcl_UnregisterChannel} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ lappend l [lindex [testchannel info $f] 15]
+ interp create x
+ interp share "" $f x
+ lappend l [lindex [testchannel info $f] 15]
+ interp delete x
+ lappend l [lindex [testchannel info $f] 15]
+ chan close $f
+ if {[catch {lindex [testchannel info $f] 15} msg]} {
+ lappend l $msg
+ } else {
+ lappend l "very broken: $f found after being chan closed"
+ }
+ string equal $l [list 1 2 1 "can not find channel named \"$f\""]
+} -result 1
+
+test chan-io-19.1 {Tcl_GetChannel->Tcl_GetStdChannel, standard handles} {
+ chan eof stdin
+} 0
+test chan-io-19.2 {testing Tcl_GetChannel, user opened handle} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan eof $f
+} -cleanup {
+ chan close $f
+} -result 0
+test chan-io-19.3 {Tcl_GetChannel, channel not found} -body {
+ chan eof file34
+} -returnCodes error -result {can not find channel named "file34"}
+test chan-io-19.4 {Tcl_CreateChannel, insertion into channel table} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ lappend l [chan eof $f]
+ chan close $f
+ if {[catch {lindex [testchannel info $f] 15} msg]} {
+ lappend l $msg
+ } else {
+ lappend l "very broken: $f found after being chan closed"
+ }
+ string equal $l [list 0 "can not find channel named \"$f\""]
+} -result 1
+
+test chan-io-20.1 {Tcl_CreateChannel: initial settings} -setup {
+ set old [encoding system]
+} -body {
+ set a [open $path(test2) w]
+ encoding system ascii
+ set f [open $path(test1) w]
+ chan configure $f -encoding
+} -cleanup {
+ encoding system $old
+ chan close $f
+ chan close $a
+} -result {ascii}
+test chan-io-20.2 {Tcl_CreateChannel: initial settings} -constraints {win} -body {
+ set f [open $path(test1) w+]
+ list [chan configure $f -eofchar] [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result [list [list \x1a ""] {auto crlf}]
+test chan-io-20.3 {Tcl_CreateChannel: initial settings} -constraints {unix} -body {
+ set f [open $path(test1) w+]
+ list [chan configure $f -eofchar] [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result {{{} {}} {auto lf}}
+test chan-io-20.5 {Tcl_CreateChannel: install channel in empty slot} -setup {
+ set path(stdout) [makeFile {} stdout]
+} -constraints {stdio openpipe} -body {
+ set f [open $path(script) w]
+ chan puts -nonewline $f {
+ chan close stdout
+ set f1 [}
+ chan puts $f [list open $path(stdout) w]]
+ chan puts $f {
+ chan configure $f1 -buffersize 777
+ chan puts stderr [chan configure stdout -buffersize]
+ }
+ chan close $f
+ set f [openpipe r $path(script)]
+ chan close $f
+} -cleanup {
+ removeFile $path(stdout)
+} -returnCodes error -result {777}
+
+test chan-io-21.1 {Chan CloseChannelsOnExit} emptyTest {
+} {}
+
+# Test management of attributes associated with a channel, such as its default
+# translation, its name and type, etc. The functions tested in this group are
+# Tcl_GetChannelName, Tcl_GetChannelType and Tcl_GetChannelFile.
+# Tcl_GetChannelInstanceData not tested because files do not use the instance
+# data.
+
+test chan-io-22.1 {Tcl_GetChannelMode} emptyTest {
+ # Not used anywhere in Tcl.
+} {}
+
+test chan-io-23.1 {Tcl_GetChannelName} -constraints {testchannel} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ set n [testchannel name $f]
+ expr {$n eq $f ? "ok" : "$n != $f"}
+} -cleanup {
+ chan close $f
+} -result ok
+
+test chan-io-24.1 {Tcl_GetChannelType} -constraints {testchannel} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ testchannel type $f
+} -cleanup {
+ chan close $f
+} -result "file"
+
+test chan-io-25.1 {Tcl_GetChannelHandle, input} -setup {
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f "1234567890\n098765432"
+ chan close $f
+ set f [open $path(test1) r]
+ chan gets $f
+ lappend l [testchannel inputbuffered $f]
+ lappend l [chan tell $f]
+} -cleanup {
+ chan close $f
+} -result {10 11}
+test chan-io-25.2 {Tcl_GetChannelHandle, output} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [chan tell $f]
+ chan flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [chan tell $f]
+} -cleanup {
+ chan close $f
+ file delete $path(test1)
+} -result {6 6 0 6}
+
+test chan-io-26.1 {Tcl_GetChannelInstanceData} -body {
+ # "pid" command uses Tcl_GetChannelInstanceData
+ # Don't care what pid is (but must be a number), just want to exercise it.
+ set f [openpipe r << exit]
+ pid $f
+} -constraints {stdio openpipe} -cleanup {
+ chan close $f
+} -match regexp -result {^\d+$}
+
+# Test flushing. The functions tested here are FlushChannel.
+
+test chan-io-27.1 {FlushChannel, no output buffered} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan flush $f
+ file size $path(test1)
+} -cleanup {
+ chan close $f
+} -result 0
+test chan-io-27.2 {FlushChannel, some output buffered} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f hello
+ lappend l [file size $path(test1)]
+ chan flush $f
+ lappend l [file size $path(test1)]
+ chan close $f
+ lappend l [file size $path(test1)]
+} -result {0 6 6}
+test chan-io-27.3 {FlushChannel, implicit flush on chan close} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f hello
+ lappend l [file size $path(test1)]
+ chan close $f
+ lappend l [file size $path(test1)]
+} -result {0 6}
+test chan-io-27.4 {FlushChannel, implicit flush when buffer fills} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan configure $f -buffersize 60
+ lappend l [file size $path(test1)]
+ for {set i 0} {$i < 12} {incr i} {
+ chan puts $f hello
+ }
+ lappend l [file size $path(test1)]
+ chan flush $f
+ lappend l [file size $path(test1)]
+} -cleanup {
+ chan close $f
+} -result {0 60 72}
+test chan-io-27.5 {FlushChannel, implicit flush when buffer fills and on chan close} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {unixOrPc} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -buffersize 60 -eofchar {}
+ lappend l [file size $path(test1)]
+ for {set i 0} {$i < 12} {incr i} {
+ chan puts $f hello
+ }
+ lappend l [file size $path(test1)]
+ chan close $f
+ lappend l [file size $path(test1)]
+} -result {0 60 72}
+set path(pipe) [makeFile {} pipe]
+set path(output) [makeFile {} output]
+test chan-io-27.6 {FlushChannel, async flushing, async chan close} -setup {
+ file delete $path(pipe)
+ file delete $path(output)
+} -constraints {stdio asyncPipeChan Close openpipe} -body {
+ set f [open $path(pipe) w]
+ chan puts $f "set f \[[list open $path(output) w]]"
+ chan puts $f {
+ chan configure $f -translation lf -buffering none -eofchar {}
+ while {![chan eof stdin]} {
+ after 20
+ chan puts -nonewline $f [chan read stdin 1024]
+ }
+ chan close $f
+ }
+ chan close $f
+ set x 01234567890123456789012345678901
+ for {set i 0} {$i < 11} {incr i} {
+ set x "$x$x"
+ }
+ set f [open $path(output) w]
+ chan close $f
+ set f [openpipe w $path(pipe)]
+ chan configure $f -blocking off
+ chan puts -nonewline $f $x
+ chan close $f
+ set counter 0
+ while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+ after 20 [list incr [namespace which -variable counter]]
+ vwait [namespace which -variable counter]
+ }
+ if {$counter == 1000} {
+ set result "file size only [file size $path(output)]"
+ } else {
+ set result ok
+ }
+} -result ok
+
+# Tests closing a channel. The functions tested are Chan CloseChannel and
+# Tcl_Chan Close.
+
+test chan-io-28.1 {Chan CloseChannel called when all references are dropped} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ interp create x
+ interp share "" $f x
+ lappend l [testchannel refcount $f]
+ x eval chan close $f
+ interp delete x
+ lappend l [testchannel refcount $f]
+} -cleanup {
+ chan close $f
+} -result {2 1}
+test chan-io-28.2 {Chan CloseChannel called when all references are dropped} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ interp create x
+ interp share "" $f x
+ chan puts -nonewline $f abc
+ chan close $f
+ x eval chan puts $f def
+ x eval chan close $f
+ interp delete x
+ set f [open $path(test1) r]
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result abcdef
+test chan-io-28.3 {Chan CloseChannel, not called before output queue is empty} -setup {
+ file delete $path(pipe)
+ file delete $path(output)
+} -constraints {stdio asyncPipeChan Close nonPortable openpipe} -body {
+ set f [open $path(pipe) w]
+ chan puts $f {
+ # Need to not have eof char appended on chan close, because the other
+ # side of the pipe already chan closed, so that writing would cause an
+ # error "invalid file".
+ chan configure stdout -eofchar {}
+ chan configure stderr -eofchar {}
+ set f [open $path(output) w]
+ chan configure $f -translation lf -buffering none
+ for {set x 0} {$x < 20} {incr x} {
+ after 20
+ chan puts -nonewline $f [chan read stdin 1024]
+ }
+ chan close $f
+ }
+ chan close $f
+ set x 01234567890123456789012345678901
+ for {set i 0} {$i < 11} {incr i} {
+ set x "$x$x"
+ }
+ set f [open $path(output) w]
+ chan close $f
+ set f [openpipe r+ $path(pipe)]
+ chan configure $f -blocking off -eofchar {}
+ chan puts -nonewline $f $x
+ chan close $f
+ set counter 0
+ while {([file size $path(output)] < 20480) && ($counter < 1000)} {
+ after 20 [list incr [namespace which -variable counter]]
+ vwait [namespace which -variable counter]
+ }
+ if {$counter == 1000} {
+ set result probably_broken
+ } else {
+ set result ok
+ }
+} -result ok
+test chan-io-28.4 {Tcl_Chan Close} -constraints {testchannel} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ lappend l [lsort [testchannel open]]
+ set f [open $path(test1) w]
+ lappend l [lsort [testchannel open]]
+ chan close $f
+ lappend l [lsort [testchannel open]]
+ set x [list $consoleFileNames \
+ [lsort [list {*}$consoleFileNames $f]] \
+ $consoleFileNames]
+ expr {$l eq $x ? "ok" : "{$l} != {$x}"}
+} -result ok
+test chan-io-28.5 {Tcl_Chan Close vs standard handles} -setup {
+ file delete $path(script)
+} -constraints {stdio unix testchannel openpipe} -body {
+ set f [open $path(script) w]
+ chan puts $f {
+ chan close stdin
+ chan puts [testchannel open]
+ }
+ chan close $f
+ set f [openpipe r $path(script)]
+ set l [chan gets $f]
+ chan close $f
+ lsort $l
+} -result {file1 file2}
+test chan-io-28.6 {Tcl_CloseEx (half-close) pipe} -setup {
+ set cat [makeFile {
+ fconfigure stdout -buffering line
+ while {[gets stdin line] >= 0} {puts $line}
+ puts DONE
+ exit 0
+ } cat.tcl]
+ variable done
+} -body {
+ set ff [openpipe r+ $cat]
+ puts $ff Hey
+ close $ff w
+ set timer [after 1000 [namespace code {set done Failed}]]
+ set acc {}
+ fileevent $ff readable [namespace code {
+ if {[gets $ff line] < 0} {
+ set done Succeeded
+ } else {
+ lappend acc $line
+ }
+ }]
+ vwait [namespace which -variable done]
+ after cancel $timer
+ close $ff r
+ list $done $acc
+} -cleanup {
+ removeFile cat.tcl
+} -result {Succeeded {Hey DONE}}
+test chan-io-28.7 {Tcl_CloseEx (half-close) socket} -setup {
+ set echo [makeFile {
+ proc accept {s args} {set ::sok $s}
+ set s [socket -server accept 0]
+ puts [lindex [fconfigure $s -sockname] 2]
+ flush stdout
+ vwait ::sok
+ fconfigure $sok -buffering line
+ while {[gets $sok line]>=0} {puts $sok $line}
+ puts $sok DONE
+ exit 0
+ } echo.tcl]
+} -body {
+ set ff [openpipe r $echo]
+ gets $ff port
+ set s [socket 127.0.0.1 $port]
+ puts $s Hey
+ close $s w
+ set timer [after 1000 [namespace code {set ::done Failed}]]
+ set acc {}
+ fileevent $s readable [namespace code {
+ if {[gets $s line]<0} {
+ set done Succeeded
+ } else {
+ lappend acc $line
+ }
+ }]
+ vwait [namespace which -variable done]
+ after cancel $timer
+ close $s r
+ close $ff
+ list $done $acc
+} -cleanup {
+ removeFile echo.tcl
+} -result {Succeeded {Hey DONE}}
+
+test chan-io-29.1 {Tcl_WriteChars, channel not writable} -body {
+ chan puts stdin hello
+} -returnCodes error -result {channel "stdin" wasn't opened for writing}
+test chan-io-29.2 {Tcl_WriteChars, empty string} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -eofchar {}
+ chan puts -nonewline $f ""
+ chan close $f
+ file size $path(test1)
+} -result 0
+test chan-io-29.3 {Tcl_WriteChars, nonempty string} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -eofchar {}
+ chan puts -nonewline $f hello
+ chan close $f
+ file size $path(test1)
+} -result 5
+test chan-io-29.4 {Tcl_WriteChars, buffering in full buffering mode} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -buffering full -eofchar {}
+ chan puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ chan flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+} -cleanup {
+ chan close $f
+} -result {6 0 0 6}
+test chan-io-29.5 {Tcl_WriteChars, buffering in line buffering mode} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -buffering line -eofchar {}
+ chan puts -nonewline $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ chan puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+} -cleanup {
+ chan close $f
+} -result {5 0 0 11}
+test chan-io-29.6 {Tcl_WriteChars, buffering in no buffering mode} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -buffering none -eofchar {}
+ chan puts -nonewline $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ chan puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+} -cleanup {
+ chan close $f
+} -result {0 5 0 11}
+test chan-io-29.7 {Tcl_Flush, full buffering} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -buffering full -eofchar {}
+ chan puts -nonewline $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ chan puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ chan flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+} -cleanup {
+ chan close $f
+} -result {5 0 11 0 0 11}
+test chan-io-29.8 {Tcl_Flush, full buffering} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -buffering line
+ chan puts -nonewline $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ chan flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ chan puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ chan flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+} -cleanup {
+ chan close $f
+} -result {5 0 0 5 0 11 0 11}
+test chan-io-29.9 {Tcl_Flush, channel not writable} -body {
+ chan flush stdin
+} -returnCodes error -result {channel "stdin" wasn't opened for writing}
+test chan-io-29.10 {Tcl_WriteChars, looping and buffering} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ set f2 [open $path(longfile) r]
+ for {set x 0} {$x < 10} {incr x} {
+ chan puts $f1 [chan gets $f2]
+ }
+ chan close $f2
+ chan close $f1
+ file size $path(test1)
+} -result 387
+test chan-io-29.11 {Tcl_WriteChars, no newline, implicit flush} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -eofchar {}
+ set f2 [open $path(longfile) r]
+ for {set x 0} {$x < 10} {incr x} {
+ chan puts -nonewline $f1 [chan gets $f2]
+ }
+ chan close $f1
+ chan close $f2
+ file size $path(test1)
+} -result 377
+test chan-io-29.12 {Tcl_WriteChars on a pipe} -setup {
+ file delete $path(test1)
+ file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 "set f1 \[[list open $path(longfile) r]]"
+ chan puts $f1 {
+ for {set x 0} {$x < 10} {incr x} {
+ chan puts [chan gets $f1]
+ }
+ }
+ chan close $f1
+ set f1 [openpipe r $path(pipe)]
+ set f2 [open $path(longfile) r]
+ set y ok
+ for {set x 0} {$x < 10} {incr x} {
+ set l1 [chan gets $f1]
+ set l2 [chan gets $f2]
+ if {$l1 ne $l2} {
+ set y broken:$x
+ }
+ }
+ return $y
+} -cleanup {
+ chan close $f1
+ chan close $f2
+} -result ok
+test chan-io-29.13 {Tcl_WriteChars to a pipe, line buffered} -setup {
+ file delete $path(test1)
+ file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {
+ chan puts [chan gets stdin]
+ chan puts [chan gets stdin]
+ }
+ chan close $f1
+ set y ok
+ set f1 [openpipe r+ $path(pipe)]
+ chan configure $f1 -buffering line
+ set f2 [open $path(longfile) r]
+ set line [chan gets $f2]
+ chan puts $f1 $line
+ set backline [chan gets $f1]
+ if {$line ne $backline} {
+ set y broken1
+ }
+ set line [chan gets $f2]
+ chan puts $f1 $line
+ set backline [chan gets $f1]
+ if {$line ne $backline} {
+ set y broken2
+ }
+ return $y
+} -cleanup {
+ chan close $f1
+ chan close $f2
+} -result ok
+test chan-io-29.14 {Tcl_WriteChars, buffering and implicit flush at chan close} -setup {
+ file delete $path(test3)
+} -body {
+ set f [open $path(test3) w]
+ chan puts -nonewline $f "Text1"
+ chan puts -nonewline $f " Text 2"
+ chan puts $f " Text 3"
+ chan close $f
+ set f [open $path(test3) r]
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result {Text1 Text 2 Text 3}
+test chan-io-29.15 {Tcl_Flush, channel not open for writing} -setup {
+ file delete $path(test1)
+ set fd [open $path(test1) w]
+ chan close $fd
+} -body {
+ set fd [open $path(test1) r]
+ chan flush $fd
+} -returnCodes error -cleanup {
+ catch {chan close $fd}
+} -match glob -result {channel "*" wasn't opened for writing}
+test chan-io-29.16 {Tcl_Flush on pipe opened only for reading} -setup {
+ set fd [openpipe r cat longfile]
+} -constraints {stdio openpipe} -body {
+ chan flush $fd
+} -returnCodes error -cleanup {
+ catch {chan close $fd}
+} -match glob -result {channel "*" wasn't opened for writing}
+test chan-io-29.17 {Tcl_WriteChars buffers, then Tcl_Flush flushes} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf
+ chan puts $f1 hello
+ chan puts $f1 hello
+ chan puts $f1 hello
+ chan flush $f1
+ file size $path(test1)
+} -cleanup {
+ chan close $f1
+} -result 18
+test chan-io-29.18 {Tcl_WriteChars and Tcl_Flush intermixed} -setup {
+ file delete $path(test1)
+ set x ""
+ set f1 [open $path(test1) w]
+} -body {
+ chan configure $f1 -translation lf
+ chan puts $f1 hello
+ chan puts $f1 hello
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [file size $path(test1)]
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [file size $path(test1)]
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [file size $path(test1)]
+} -cleanup {
+ chan close $f1
+} -result {18 24 30}
+test chan-io-29.19 {Explicit and implicit flushes} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ set x ""
+ chan puts $f1 hello
+ chan puts $f1 hello
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [file size $path(test1)]
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [file size $path(test1)]
+ chan puts $f1 hello
+ chan close $f1
+ lappend x [file size $path(test1)]
+} -result {18 24 30}
+test chan-io-29.20 {Implicit flush when buffer is full} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ set line "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+ for {set x 0} {$x < 100} {incr x} {
+ chan puts $f1 $line
+ }
+ set z ""
+ lappend z [file size $path(test1)]
+ for {set x 0} {$x < 100} {incr x} {
+ chan puts $f1 $line
+ }
+ lappend z [file size $path(test1)]
+ chan close $f1
+ lappend z [file size $path(test1)]
+} -result {4096 12288 12600}
+test chan-io-29.21 {Tcl_Flush to pipe} -setup {
+ file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {set x [chan read stdin 6]}
+ chan puts $f1 {set cnt [string length $x]}
+ chan puts $f1 {chan puts "read $cnt characters"}
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ chan puts $f1 hello
+ chan flush $f1
+ chan gets $f1
+} -cleanup {
+ catch {chan close $f1}
+} -result "read 6 characters"
+test chan-io-29.22 {Tcl_Flush called at other end of pipe} -setup {
+ file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {
+ chan configure stdout -buffering full
+ chan puts hello
+ chan puts hello
+ chan flush stdout
+ chan gets stdin
+ chan puts bye
+ chan flush stdout
+ }
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ set x ""
+ lappend x [chan gets $f1]
+ lappend x [chan gets $f1]
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [chan gets $f1]
+} -cleanup {
+ chan close $f1
+} -result {hello hello bye}
+test chan-io-29.23 {Tcl_Flush and line buffering at end of pipe} -setup {
+ file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {
+ chan puts hello
+ chan puts hello
+ chan gets stdin
+ chan puts bye
+ }
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ set x ""
+ lappend x [chan gets $f1]
+ lappend x [chan gets $f1]
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [chan gets $f1]
+} -cleanup {
+ chan close $f1
+} -result {hello hello bye}
+test chan-io-29.24 {Tcl_WriteChars and Tcl_Flush move end of file} -setup {
+ variable x {}
+} -body {
+ set f [open $path(test3) w]
+ chan puts $f "Line 1"
+ chan puts $f "Line 2"
+ set f2 [open $path(test3)]
+ lappend x [chan read -nonewline $f2]
+ chan close $f2
+ chan flush $f
+ set f2 [open $path(test3)]
+ lappend x [chan read -nonewline $f2]
+} -cleanup {
+ chan close $f2
+ chan close $f
+} -result "{} {Line 1\nLine 2}"
+test chan-io-29.25 {Implicit flush with Tcl_Flush to command pipelines} -setup {
+ file delete $path(test3)
+} -constraints {stdio openpipe fileevent} -body {
+ set f [openpipe w $path(cat) | [interpreter] $path(cat) > $path(test3)]
+ chan puts $f "Line 1"
+ chan puts $f "Line 2"
+ chan close $f
+ after 100
+ set f [open $path(test3) r]
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "Line 1\nLine 2\n"
+test chan-io-29.26 {Tcl_Flush, Tcl_Write on bidirectional pipelines} -constraints {stdio unixExecs openpipe} -body {
+ set f [open "|[list cat -u]" r+]
+ chan puts $f "Line1"
+ chan flush $f
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result {Line1}
+test chan-io-29.27 {Tcl_Flush on chan closed pipeline} -setup {
+ file delete $path(pipe)
+ set f [open $path(pipe) w]
+ chan puts $f {exit}
+ chan close $f
+} -constraints {stdio openpipe} -body {
+ set f [openpipe r+ $path(pipe)]
+ chan gets $f
+ chan puts $f output
+ after 50
+ #
+ # The flush below will get a SIGPIPE. This is an expected part of the test
+ # and indicates that the test operates correctly. If you run this test
+ # under a debugger, the signal will by intercepted unless you disable the
+ # debugger's signal interception.
+ #
+ if {[catch {chan flush $f} msg]} {
+ set x [list 1 $msg $::errorCode]
+ catch {chan close $f}
+ } elseif {[catch {chan close $f} msg]} {
+ set x [list 1 $msg $::errorCode]
+ } else {
+ set x {this was supposed to fail and did not}
+ }
+ string tolower $x
+} -match glob -result {1 {error flushing "*": broken pipe} {posix epipe {broken pipe}}}
+test chan-io-29.28 {Tcl_WriteChars, lf mode} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f hello\nthere\nand\nhere
+ chan flush $f
+ file size $path(test1)
+} -cleanup {
+ chan close $f
+} -result 21
+test chan-io-29.29 {Tcl_WriteChars, cr mode} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr -eofchar {}
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ file size $path(test1)
+} -result 21
+test chan-io-29.30 {Tcl_WriteChars, crlf mode} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -eofchar {}
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ file size $path(test1)
+} -result 25
+test chan-io-29.31 {Tcl_WriteChars, background flush} -setup {
+ file delete $path(pipe)
+ file delete $path(output)
+} -constraints {stdio openpipe} -body {
+ set f [open $path(pipe) w]
+ chan puts $f "set f \[[list open $path(output) w]]"
+ chan puts $f {chan configure $f -translation lf}
+ set x [list while {![chan eof stdin]}]
+ set x "$x {"
+ chan puts $f $x
+ chan puts $f { chan puts -nonewline $f [chan read stdin 4096]}
+ chan puts $f { chan flush $f}
+ chan puts $f "}"
+ chan puts $f {chan close $f}
+ chan close $f
+ set x 01234567890123456789012345678901
+ for {set i 0} {$i < 11} {incr i} {
+ set x "$x$x"
+ }
+ set f [open $path(output) w]
+ chan close $f
+ set f [openpipe r+ $path(pipe)]
+ chan configure $f -blocking off
+ chan puts -nonewline $f $x
+ chan close $f
+ set counter 0
+ while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+ after 10 [list incr [namespace which -variable counter]]
+ vwait [namespace which -variable counter]
+ }
+ if {$counter == 1000} {
+ set result "file size only [file size $path(output)]"
+ } else {
+ set result ok
+ }
+ # allow a little time for the background process to chan close.
+ # otherwise, the following test fails on the [file delete $path(output)
+ # on Windows because a process still has the file open.
+ after 100 set v 1; vwait v
+ return $result
+} -result ok
+test chan-io-29.32 {Tcl_WriteChars, background flush to slow reader} -setup {
+ file delete $path(pipe)
+ file delete $path(output)
+} -constraints {stdio asyncPipeChan Close openpipe} -body {
+ set f [open $path(pipe) w]
+ chan puts $f "set f \[[list open $path(output) w]]"
+ chan puts $f {chan configure $f -translation lf}
+ set x [list while {![chan eof stdin]}]
+ set x "$x \{"
+ chan puts $f $x
+ chan puts $f { after 20}
+ chan puts $f { chan puts -nonewline $f [chan read stdin 1024]}
+ chan puts $f { chan flush $f}
+ chan puts $f "\}"
+ chan puts $f {chan close $f}
+ chan close $f
+ set x 01234567890123456789012345678901
+ for {set i 0} {$i < 11} {incr i} {
+ set x "$x$x"
+ }
+ set f [open $path(output) w]
+ chan close $f
+ set f [openpipe r+ $path(pipe)]
+ chan configure $f -blocking off
+ chan puts -nonewline $f $x
+ chan close $f
+ set counter 0
+ while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+ after 20 [list incr [namespace which -variable counter]]
+ vwait [namespace which -variable counter]
+ }
+ if {$counter == 1000} {
+ set result "file size only [file size $path(output)]"
+ } else {
+ set result ok
+ }
+} -result ok
+test chan-io-29.33 {Tcl_Flush, implicit flush on exit} -setup {
+ set f [open $path(script) w]
+ chan puts $f "set f \[[list open $path(test1) w]]"
+ chan puts $f {chan configure $f -translation lf
+ chan puts $f hello
+ chan puts $f bye
+ chan puts $f strange
+ }
+ chan close $f
+} -constraints exec -body {
+ exec [interpreter] $path(script)
+ set f [open $path(test1) r]
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\nbye\nstrange\n"
+test chan-io-29.34 {Tcl_Chan Close, async flush on chan close, using sockets} -setup {
+ variable c 0
+ variable x running
+ set l abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
+ proc writelots {s l} {
+ for {set i 0} {$i < 2000} {incr i} {
+ chan puts $s $l
+ }
+ }
+} -constraints {socket tempNotMac fileevent} -body {
+ proc accept {s a p} {
+ variable x
+ chan event $s readable [namespace code [list readit $s]]
+ chan configure $s -blocking off
+ set x accepted
+ }
+ proc readit {s} {
+ variable c
+ variable x
+ set l [chan gets $s]
+ if {[chan eof $s]} {
+ chan close $s
+ set x done
+ } elseif {([string length $l] > 0) || ![chan blocked $s]} {
+ incr c
+ }
+ }
+ set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set cs [socket 127.0.0.1 [lindex [chan configure $ss -sockname] 2]]
+ vwait [namespace which -variable x]
+ chan configure $cs -blocking off
+ writelots $cs $l
+ chan close $cs
+ chan close $ss
+ vwait [namespace which -variable x]
+ return $c
+} -result 2000
+test chan-io-29.35 {Tcl_Chan Close vs chan event vs multiple interpreters} -setup {
+ catch {interp delete x}
+ catch {interp delete y}
+} -constraints {socket tempNotMac fileevent} -body {
+ # On Mac, this test screws up sockets such that subsequent tests using
+ # port 2828 either cause errors or panic().
+ interp create x
+ interp create y
+ set s [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ proc accept {s a p} {
+ chan puts $s hello
+ chan close $s
+ }
+ set c [socket 127.0.0.1 [lindex [chan configure $s -sockname] 2]]
+ interp share {} $c x
+ interp share {} $c y
+ chan close $c
+ x eval {
+ proc readit {s} {
+ chan gets $s
+ if {[chan eof $s]} {
+ chan close $s
+ }
+ }
+ }
+ y eval {
+ proc readit {s} {
+ chan gets $s
+ if {[chan eof $s]} {
+ chan close $s
+ }
+ }
+ }
+ x eval "chan event $c readable \{readit $c\}"
+ y eval "chan event $c readable \{readit $c\}"
+ y eval [list chan close $c]
+ update
+} -cleanup {
+ chan close $s
+ interp delete x
+ interp delete y
+} -result ""
+
+# Test end of line translations. Procedures tested are Tcl_Write, Tcl_Read.
+
+test chan-io-30.1 {Tcl_Write lf, Tcl_Read lf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\nthere\nand\nhere\n"
+test chan-io-30.2 {Tcl_Write lf, Tcl_Read cr} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\nthere\nand\nhere\n"
+test chan-io-30.3 {Tcl_Write lf, Tcl_Read crlf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\nthere\nand\nhere\n"
+test chan-io-30.4 {Tcl_Write cr, Tcl_Read cr} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\nthere\nand\nhere\n"
+test chan-io-30.5 {Tcl_Write cr, Tcl_Read lf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\rthere\rand\rhere\r"
+test chan-io-30.6 {Tcl_Write cr, Tcl_Read crlf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\rthere\rand\rhere\r"
+test chan-io-30.7 {Tcl_Write crlf, Tcl_Read crlf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\nthere\nand\nhere\n"
+test chan-io-30.8 {Tcl_Write crlf, Tcl_Read lf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\r\nthere\r\nand\r\nhere\r\n"
+test chan-io-30.9 {Tcl_Write crlf, Tcl_Read cr} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\n\nthere\n\nand\n\nhere\n\n"
+test chan-io-30.10 {Tcl_Write lf, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ list [chan read $f] [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result {{hello
+there
+and
+here
+} auto}
+test chan-io-30.11 {Tcl_Write cr, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ list [chan read $f] [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result {{hello
+there
+and
+here
+} auto}
+test chan-io-30.12 {Tcl_Write crlf, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ list [chan read $f] [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result {{hello
+there
+and
+here
+} auto}
+test chan-io-30.13 {Tcl_Write crlf on block boundary, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ set line "123456789ABCDE" ;# 14 char plus crlf
+ chan puts -nonewline $f x ;# shift crlf across block boundary
+ for {set i 0} {$i < 700} {incr i} {
+ chan puts $f $line
+ }
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto
+ string length [chan read $f]
+} -cleanup {
+ chan close $f
+} -result [expr 700*15+1]
+test chan-io-30.14 {Tcl_Write crlf on block boundary, Tcl_Read crlf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ set line "123456789ABCDE" ;# 14 char plus crlf
+ chan puts -nonewline $f x ;# shift crlf across block boundary
+ for {set i 0} {$i < 700} {incr i} {
+ chan puts $f $line
+ }
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf
+ string length [chan read $f]
+} -cleanup {
+ chan close $f
+} -result [expr 700*15+1]
+test chan-io-30.15 {Tcl_Write mixed, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\rhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result {hello
+there
+and
+here
+}
+test chan-io-30.16 {Tcl_Write ^Z at end, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f hello\nthere\nand\rhere\n\x1a
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result {hello
+there
+and
+here
+}
+test chan-io-30.17 {Tcl_Write, implicit ^Z at end, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -constraints {win} -body {
+ set f [open $path(test1) w]
+ chan configure $f -eofchar \x1a -translation lf
+ chan puts $f hello\nthere\nand\rhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result {hello
+there
+and
+here
+}
+test chan-io-30.18 {Tcl_Write, ^Z in middle, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ chan puts $f $s
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ set l ""
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1 {} 1}
+test chan-io-30.19 {Tcl_Write, ^Z no newline in middle, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ chan puts $f $s
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ set l ""
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1 {} 1}
+test chan-io-30.20 {Tcl_Write, ^Z in middle ignored, Tcl_Read lf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f [format "abc\ndef\n%cghi\nqrs" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf -eofchar {}
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result "abc def 0 \x1aghi 0 qrs 0 {} 1"
+test chan-io-30.21 {Tcl_Write, ^Z in middle ignored, Tcl_Read cr} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f [format "abc\ndef\n%cghi\nqrs" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr -eofchar {}
+ set x [chan gets $f]
+ lappend l [string equal $x "abc\ndef\n\x1aghi\nqrs\n"]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {1 1 {} 1}
+test chan-io-30.22 {Tcl_Write, ^Z in middle ignored, Tcl_Read crlf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f [format "abc\ndef\n%cghi\nqrs" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf -eofchar {}
+ set x [chan gets $f]
+ lappend l [string equal $x "abc\ndef\n\x1aghi\nqrs\n"]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {1 1 {} 1}
+test chan-io-30.23 {Tcl_Write lf, ^Z in middle, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f [format abc\ndef\n%cqrs\ntuv 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {8 1}
+test chan-io-30.24 {Tcl_Write lf, ^Z in middle, Tcl_Read lf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ chan puts $f $c
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf -eofchar \x1a
+ list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {8 1}
+test chan-io-30.25 {Tcl_Write cr, ^Z in middle, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ chan puts $f $c
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {8 1}
+test chan-io-30.26 {Tcl_Write cr, ^Z in middle, Tcl_Read cr} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ chan puts $f $c
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr -eofchar \x1a
+ list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {8 1}
+test chan-io-30.27 {Tcl_Write crlf, ^Z in middle, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ chan puts $f $c
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {8 1}
+test chan-io-30.28 {Tcl_Write crlf, ^Z in middle, Tcl_Read crlf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ chan puts $f $c
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf -eofchar \x1a
+ list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {8 1}
+
+# Test end of line translations. Functions tested are Tcl_Write and
+# Tcl_Gets.
+
+test chan-io-31.1 {Tcl_Write lf, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result {hello 6 auto there 12 auto}
+test chan-io-31.2 {Tcl_Write cr, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result {hello 6 auto there 12 auto}
+test chan-io-31.3 {Tcl_Write crlf, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result {hello 7 auto there 14 auto}
+test chan-io-31.4 {Tcl_Write lf, Tcl_Gets lf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result {hello 6 lf there 12 lf}
+test chan-io-31.5 {Tcl_Write lf, Tcl_Gets cr} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr
+ lappend l [string length [chan gets $f]]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {21 21 cr 1 {} 21 cr 1}
+test chan-io-31.6 {Tcl_Write lf, Tcl_Gets crlf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf
+ lappend l [string length [chan gets $f]]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {21 21 crlf 1 {} 21 crlf 1}
+test chan-io-31.7 {Tcl_Write cr, Tcl_Gets cr} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello 6 cr 0 there 12 cr 0}
+test chan-io-31.8 {Tcl_Write cr, Tcl_Gets lf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf
+ lappend l [string length [chan gets $f]]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {21 21 lf 1 {} 21 lf 1}
+test chan-io-31.9 {Tcl_Write cr, Tcl_Gets crlf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf
+ lappend l [string length [chan gets $f]]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {21 21 crlf 1 {} 21 crlf 1}
+test chan-io-31.10 {Tcl_Write crlf, Tcl_Gets crlf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello 7 crlf 0 there 14 crlf 0}
+test chan-io-31.11 {Tcl_Write crlf, Tcl_Gets cr} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+ lappend l [string length [chan gets $f]]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello 6 cr 0 6 13 cr 0}
+test chan-io-31.12 {Tcl_Write crlf, Tcl_Gets lf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf
+ lappend l [string length [chan gets $f]]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+ lappend l [string length [chan gets $f]]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {6 7 lf 0 6 14 lf 0}
+test chan-io-31.13 {binary mode is synonym of lf mode} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation binary
+ chan configure $f -translation
+} -cleanup {
+ chan close $f
+} -result lf
+#
+# Test chan-io-9.14 has been removed because "auto" output translation mode is
+# not supoprted.
+#
+test chan-io-31.14 {Tcl_Write mixed, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\rand\r\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.15 {Tcl_Write mixed, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f hello\nthere\rand\r\nhere\r
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.16 {Tcl_Write mixed, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f hello\nthere\rand\r\nhere\n
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.17 {Tcl_Write mixed, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f hello\nthere\rand\r\nhere\r\n
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.18 {Tcl_Write ^Z at end, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f [format "hello\nthere\nand\rhere\n\%c" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.19 {Tcl_Write, implicit ^Z at end, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -eofchar \x1a -translation lf
+ chan puts $f hello\nthere\nand\rhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.20 {Tcl_Write, ^Z in middle, Tcl_Gets auto, eofChar} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a
+ chan configure $f -translation auto
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.21 {Tcl_Write, no newline ^Z in middle, Tcl_Gets auto, eofChar} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.22 {Tcl_Write, ^Z in middle ignored, Tcl_Gets lf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf -eofchar {}
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test chan-io-31.23 {Tcl_Write, ^Z in middle ignored, Tcl_Gets cr} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr -eofchar {}
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr -eofchar {}
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test chan-io-31.24 {Tcl_Write, ^Z in middle ignored, Tcl_Gets crlf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -eofchar {}
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf -eofchar {}
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test chan-io-31.25 {Tcl_Write lf, ^Z in middle, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.26 {Tcl_Write lf, ^Z in middle, Tcl_Gets lf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf -eofchar \x1a
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.27 {Tcl_Write cr, ^Z in middle, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr -eofchar {}
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.28 {Tcl_Write cr, ^Z in middle, Tcl_Gets cr} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr -eofchar {}
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr -eofchar \x1a
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.29 {Tcl_Write crlf, ^Z in middle, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -eofchar {}
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.30 {Tcl_Write crlf, ^Z in middle, Tcl_Gets crlf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -eofchar {}
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf -eofchar \x1a
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.31 {Tcl_Write crlf on block boundary, Tcl_Gets crlf} -setup {
+ file delete $path(test1)
+ set c ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ set line "123456789ABCDE" ;# 14 char plus crlf
+ chan puts -nonewline $f x ;# shift crlf across block boundary
+ for {set i 0} {$i < 700} {incr i} {
+ chan puts $f $line
+ }
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf
+ while {[chan gets $f line] >= 0} {
+ append c $line\n
+ }
+ chan close $f
+ string length $c
+} -result [expr 700*15+1]
+test chan-io-31.32 {Tcl_Write crlf on block boundary, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set c ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ set line "123456789ABCDE" ;# 14 char plus crlf
+ chan puts -nonewline $f x ;# shift crlf across block boundary
+ for {set i 0} {$i < 700} {incr i} {
+ chan puts $f $line
+ }
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto
+ while {[chan gets $f line] >= 0} {
+ append c $line\n
+ }
+ chan close $f
+ string length $c
+} -result [expr 700*15+1]
+
+# Test Tcl_Read and buffering.
+
+test chan-io-32.1 {Tcl_Read, channel not readable} -body {
+ read stdout
+} -returnCodes error -result {channel "stdout" wasn't opened for reading}
+test chan-io-32.2 {Tcl_Read, zero byte count} {
+ chan read stdin 0
+} ""
+test chan-io-32.3 {Tcl_Read, negative byte count} -setup {
+ set f [open $path(longfile) r]
+} -body {
+ chan read $f -1
+} -returnCodes error -cleanup {
+ chan close $f
+} -result {expected non-negative integer but got "-1"}
+test chan-io-32.4 {Tcl_Read, positive byte count} -body {
+ set f [open $path(longfile) r]
+ string length [chan read $f 1024]
+} -cleanup {
+ chan close $f
+} -result 1024
+test chan-io-32.5 {Tcl_Read, multiple buffers} -body {
+ set f [open $path(longfile) r]
+ chan configure $f -buffersize 100
+ string length [chan read $f 1024]
+} -cleanup {
+ chan close $f
+} -result 1024
+test chan-io-32.6 {Tcl_Read, very large read} {
+ set f1 [open $path(longfile) r]
+ set z [chan read $f1 1000000]
+ chan close $f1
+ set l [string length $z]
+ set x ok
+ set z [file size $path(longfile)]
+ if {$z != $l} {
+ set x "$z != $l"
+ }
+ set x
+} ok
+test chan-io-32.7 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
+ set f1 [open $path(longfile) r]
+ chan configure $f1 -blocking off
+ set z [chan read $f1 20]
+ chan close $f1
+ set l [string length $z]
+ set x ok
+ if {$l != 20} {
+ set x "$l != 20"
+ }
+ set x
+} ok
+test chan-io-32.8 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
+ set f1 [open $path(longfile) r]
+ chan configure $f1 -blocking off
+ set z [chan read $f1 1000000]
+ chan close $f1
+ set x ok
+ set l [string length $z]
+ set z [file size $path(longfile)]
+ if {$z != $l} {
+ set x "$z != $l"
+ }
+ set x
+} ok
+test chan-io-32.9 {Tcl_Read, read to end of file} {
+ set f1 [open $path(longfile) r]
+ set z [chan read $f1]
+ chan close $f1
+ set l [string length $z]
+ set x ok
+ set z [file size $path(longfile)]
+ if {$z != $l} {
+ set x "$z != $l"
+ }
+ set x
+} ok
+test chan-io-32.10 {Tcl_Read from a pipe} -setup {
+ file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {chan puts [chan gets stdin]}
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ chan puts $f1 hello
+ chan flush $f1
+ chan read $f1
+} -cleanup {
+ chan close $f1
+} -result "hello\n"
+test chan-io-32.11 {Tcl_Read from a pipe} -setup {
+ file delete $path(pipe)
+ set x ""
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {chan puts [chan gets stdin]}
+ chan puts $f1 {chan puts [chan gets stdin]}
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [chan read $f1 6]
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [chan read $f1]
+} -cleanup {
+ chan close $f1
+} -result {{hello
+} {hello
+}}
+test chan-io-32.12 {Tcl_Read, -nonewline} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan puts $f1 hello
+ chan puts $f1 bye
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan read -nonewline $f1
+} -cleanup {
+ chan close $f1
+} -result {hello
+bye}
+test chan-io-32.13 {Tcl_Read, -nonewline} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan puts $f1 hello
+ chan puts $f1 bye
+ chan close $f1
+ set f1 [open $path(test1) r]
+ set c [chan read -nonewline $f1]
+ list [string length $c] $c
+} -cleanup {
+ chan close $f1
+} -result {9 {hello
+bye}}
+test chan-io-32.14 {Tcl_Read, reading in small chunks} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan puts $f "Two lines: this one"
+ chan puts $f "and this one"
+ chan close $f
+ set f [open $path(test1)]
+ list [chan read $f 1] [chan read $f 2] [chan read $f]
+} -cleanup {
+ chan close $f
+} -result {T wo { lines: this one
+and this one
+}}
+test chan-io-32.15 {Tcl_Read, asking for more input than available} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan puts $f "Two lines: this one"
+ chan puts $f "and this one"
+ chan close $f
+ set f [open $path(test1)]
+ chan read $f 100
+} -cleanup {
+ chan close $f
+} -result {Two lines: this one
+and this one
+}
+test chan-io-32.16 {Tcl_Read, read to end of file with -nonewline} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan puts $f "Two lines: this one"
+ chan puts $f "and this one"
+ chan close $f
+ set f [open $path(test1)]
+ chan read -nonewline $f
+} -cleanup {
+ chan close $f
+} -result {Two lines: this one
+and this one}
+
+# Test Tcl_Gets.
+
+test chan-io-33.1 {Tcl_Gets, reading what was written} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan puts $f1 "first line"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan gets $f1
+} -cleanup {
+ chan close $f1
+} -result {first line}
+test chan-io-33.2 {Tcl_Gets into variable} {
+ set f1 [open $path(longfile) r]
+ set c [chan gets $f1 x]
+ set l [string length x]
+ set z ok
+ if {$l != $l} {
+ set z broken
+ }
+ chan close $f1
+ set z
+} ok
+test chan-io-33.3 {Tcl_Gets from pipe} -setup {
+ file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {chan puts [chan gets stdin]}
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ chan puts $f1 hello
+ chan flush $f1
+ chan gets $f1
+} -cleanup {
+ chan close $f1
+} -result hello
+test chan-io-33.4 {Tcl_Gets with long line} -setup {
+ file delete $path(test3)
+} -body {
+ set f [open $path(test3) w]
+ chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ chan puts $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ chan close $f
+ set f [open $path(test3)]
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result {abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
+test chan-io-33.5 {Tcl_Gets with long line} {
+ set f [open $path(test3)]
+ set x [chan gets $f y]
+ chan close $f
+ list $x $y
+} {260 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
+test chan-io-33.6 {Tcl_Gets and end of file} -setup {
+ file delete $path(test3)
+ set x {}
+} -body {
+ set f [open $path(test3) w]
+ chan puts -nonewline $f "Test1\nTest2"
+ chan close $f
+ set f [open $path(test3)]
+ set y {}
+ lappend x [chan gets $f y] $y
+ set y {}
+ lappend x [chan gets $f y] $y
+ set y {}
+ lappend x [chan gets $f y] $y
+} -cleanup {
+ chan close $f
+} -result {5 Test1 5 Test2 -1 {}}
+test chan-io-33.7 {Tcl_Gets and bad variable} -setup {
+ set f [open $path(test3) w]
+ chan puts $f "Line 1"
+ chan puts $f "Line 2"
+ chan close $f
+ catch {unset x}
+ set f [open $path(test3) r]
+} -body {
+ set x 24
+ chan gets $f x(0)
+} -returnCodes error -cleanup {
+ chan close $f
+} -result {can't set "x(0)": variable isn't array}
+test chan-io-33.8 {Tcl_Gets, exercising double buffering} {
+ set f [open $path(test3) w]
+ chan configure $f -translation lf -eofchar {}
+ set x ""
+ for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+ for {set y 0} {$y < 100} {incr y} {chan puts $f $x}
+ chan close $f
+ set f [open $path(test3) r]
+ chan configure $f -translation lf
+ for {set y 0} {$y < 100} {incr y} {chan gets $f}
+ chan close $f
+ set y
+} 100
+test chan-io-33.9 {Tcl_Gets, exercising double buffering} {
+ set f [open $path(test3) w]
+ chan configure $f -translation lf -eofchar {}
+ set x ""
+ for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+ for {set y 0} {$y < 200} {incr y} {chan puts $f $x}
+ chan close $f
+ set f [open $path(test3) r]
+ chan configure $f -translation lf
+ for {set y 0} {$y < 200} {incr y} {chan gets $f}
+ chan close $f
+ set y
+} 200
+test chan-io-33.10 {Tcl_Gets, exercising double buffering} {
+ set f [open $path(test3) w]
+ chan configure $f -translation lf -eofchar {}
+ set x ""
+ for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+ for {set y 0} {$y < 300} {incr y} {chan puts $f $x}
+ chan close $f
+ set f [open $path(test3) r]
+ chan configure $f -translation lf
+ for {set y 0} {$y < 300} {incr y} {chan gets $f}
+ chan close $f
+ set y
+} 300
+
+# Test Tcl_Seek and Tcl_Tell.
+
+test chan-io-34.1 {Tcl_Seek to current position at start of file} -body {
+ set f1 [open $path(longfile) r]
+ chan seek $f1 0 current
+ chan tell $f1
+} -cleanup {
+ chan close $f1
+} -result 0
+test chan-io-34.2 {Tcl_Seek to offset from start} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan seek $f1 10 start
+ chan tell $f1
+} -cleanup {
+ chan close $f1
+} -result 10
+test chan-io-34.3 {Tcl_Seek to end of file} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan seek $f1 0 end
+ chan tell $f1
+} -cleanup {
+ chan close $f1
+} -result 54
+test chan-io-34.4 {Tcl_Seek to offset from end of file} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan seek $f1 -10 end
+ chan tell $f1
+} -cleanup {
+ chan close $f1
+} -result 44
+test chan-io-34.5 {Tcl_Seek to offset from current position} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan seek $f1 10 current
+ chan seek $f1 10 current
+ chan tell $f1
+} -cleanup {
+ chan close $f1
+} -result 20
+test chan-io-34.6 {Tcl_Seek to offset from end of file} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan seek $f1 -10 end
+ list [chan tell $f1] [chan read $f1]
+} -cleanup {
+ chan close $f1
+} -result {44 {rstuvwxyz
+}}
+test chan-io-34.7 {Tcl_Seek to offset from end of file, then to current position} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan seek $f1 -10 end
+ set c1 [chan tell $f1]
+ set r1 [chan read $f1 5]
+ chan seek $f1 0 current
+ list $c1 $r1 [chan tell $f1]
+} -cleanup {
+ chan close $f1
+} -result {44 rstuv 49}
+test chan-io-34.8 {Tcl_Seek on pipes: not supported} -setup {
+ set pipe [openpipe]
+} -constraints {stdio openpipe} -body {
+ chan seek $pipe 0 current
+} -returnCodes error -cleanup {
+ chan close $pipe
+} -match glob -result {error during seek on "*": invalid argument}
+test chan-io-34.9 {Tcl_Seek, testing buffered input flushing} -setup {
+ file delete $path(test3)
+} -body {
+ set f [open $path(test3) w]
+ chan configure $f -eofchar {}
+ chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ chan close $f
+ set f [open $path(test3) RDWR]
+ set x [chan read $f 1]
+ chan seek $f 3
+ lappend x [chan read $f 1]
+ chan seek $f 0 start
+ lappend x [chan read $f 1]
+ chan seek $f 10 current
+ lappend x [chan read $f 1]
+ chan seek $f -2 end
+ lappend x [chan read $f 1]
+ chan seek $f 50 end
+ lappend x [chan read $f 1]
+ chan seek $f 1
+ lappend x [chan read $f 1]
+} -cleanup {
+ chan close $f
+} -result {a d a l Y {} b}
+set path(test3) [makeFile {} test3]
+test chan-io-34.10 {Tcl_Seek testing flushing of buffered input} {
+ set f [open $path(test3) w]
+ chan configure $f -translation lf
+ chan puts $f xyz\n123
+ chan close $f
+ set f [open $path(test3) r+]
+ chan configure $f -translation lf
+ set x [chan gets $f]
+ chan seek $f 0 current
+ chan puts $f 456
+ chan close $f
+ list $x [viewFile test3]
+} "xyz {xyz
+456}"
+test chan-io-34.11 {Tcl_Seek testing flushing of buffered output} {
+ set f [open $path(test3) w]
+ chan puts $f xyz\n123
+ chan close $f
+ set f [open $path(test3) w+]
+ chan puts $f xyzzy
+ chan seek $f 2
+ set x [chan gets $f]
+ chan close $f
+ list $x [viewFile test3]
+} "zzy xyzzy"
+test chan-io-34.12 {Tcl_Seek testing combination of write, seek back and read} {
+ set f [open $path(test3) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f xyz\n123
+ chan close $f
+ set f [open $path(test3) a+]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f xyzzy
+ chan flush $f
+ set x [chan tell $f]
+ chan seek $f -4 cur
+ set y [chan gets $f]
+ chan close $f
+ list $x [viewFile test3] $y
+} {14 {xyz
+123
+xyzzy} zzy}
+test chan-io-34.13 {Tcl_Tell at start of file} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan tell $f1
+} -cleanup {
+ chan close $f1
+} -result 0
+test chan-io-34.14 {Tcl_Tell after seek to end of file} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan seek $f1 0 end
+ chan tell $f1
+} -cleanup {
+ chan close $f1
+} -result 54
+test chan-io-34.15 {Tcl_Tell combined with seeking} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan seek $f1 10 start
+ set c1 [chan tell $f1]
+ chan seek $f1 10 current
+ list $c1 [chan tell $f1]
+} -cleanup {
+ chan close $f1
+} -result {10 20}
+test chan-io-34.16 {Tcl_Tell on pipe: always -1} -constraints {stdio openpipe} -body {
+ set f1 [openpipe]
+ chan tell $f1
+} -cleanup {
+ chan close $f1
+} -result -1
+test chan-io-34.17 {Tcl_Tell on pipe: always -1} {stdio openpipe} {
+ set f1 [openpipe]
+ chan puts $f1 {chan puts hello}
+ chan flush $f1
+ set c [chan tell $f1]
+ chan gets $f1
+ chan close $f1
+ set c
+} -1
+test chan-io-34.18 {Tcl_Tell combined with seeking and reading} -setup {
+ file delete $path(test2)
+} -body {
+ set f [open $path(test2) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts -nonewline $f "line1\nline2\nline3\nline4\nline5\n"
+ chan close $f
+ set f [open $path(test2)]
+ chan configure $f -translation lf
+ set x [chan tell $f]
+ chan read $f 3
+ lappend x [chan tell $f]
+ chan seek $f 2
+ lappend x [chan tell $f]
+ chan seek $f 10 current
+ lappend x [chan tell $f]
+ chan seek $f 0 end
+ lappend x [chan tell $f]
+} -cleanup {
+ chan close $f
+} -result {0 3 2 12 30}
+test chan-io-34.19 {Tcl_Tell combined with opening in append mode} -body {
+ set f [open $path(test3) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f "abcdefghijklmnopqrstuvwxyz"
+ chan close $f
+ set f [open $path(test3) a]
+ chan tell $f
+} -cleanup {
+ chan close $f
+} -result 54
+test chan-io-34.20 {Tcl_Tell combined with writing} -setup {
+ set l ""
+} -body {
+ set f [open $path(test3) w]
+ chan seek $f 29 start
+ lappend l [chan tell $f]
+ chan puts -nonewline $f a
+ chan seek $f 39 start
+ lappend l [chan tell $f]
+ chan puts -nonewline $f a
+ lappend l [chan tell $f]
+ chan seek $f 407 end
+ lappend l [chan tell $f]
+} -cleanup {
+ chan close $f
+} -result {29 39 40 447}
+test chan-io-34.21 {Tcl_Seek and Tcl_Tell on large files} -setup {
+ file delete $path(test3)
+ set l ""
+} -constraints {largefileSupport} -body {
+ set f [open $path(test3) w]
+ chan configure $f -encoding binary
+ lappend l [chan tell $f]
+ chan puts -nonewline $f abcdef
+ lappend l [chan tell $f]
+ chan flush $f
+ lappend l [chan tell $f]
+ # 4GB offset!
+ chan seek $f 0x100000000
+ lappend l [chan tell $f]
+ chan puts -nonewline $f abcdef
+ lappend l [chan tell $f]
+ chan close $f
+ lappend l [file size $f]
+ # truncate...
+ chan close [open $path(test3) w]
+ lappend l [file size $f]
+} -result {0 6 6 4294967296 4294967302 4294967302 0}
+
+# Test Tcl_Eof
+
+test chan-io-35.1 {Tcl_Eof} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan puts $f hello
+ chan puts $f hello
+ chan close $f
+ set f [open $path(test1)]
+ set x [chan eof $f]
+ lappend x [chan eof $f]
+ chan gets $f
+ lappend x [chan eof $f]
+ chan gets $f
+ lappend x [chan eof $f]
+ chan gets $f
+ lappend x [chan eof $f]
+ lappend x [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {0 0 0 0 1 1}
+test chan-io-35.2 {Tcl_Eof with pipe} -constraints {stdio openpipe} -setup {
+ file delete $path(pipe)
+} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {chan gets stdin}
+ chan puts $f1 {chan puts hello}
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ chan puts $f1 hello
+ set x [chan eof $f1]
+ chan flush $f1
+ lappend x [chan eof $f1]
+ chan gets $f1
+ lappend x [chan eof $f1]
+ chan gets $f1
+ lappend x [chan eof $f1]
+} -cleanup {
+ chan close $f1
+} -result {0 0 0 1}
+test chan-io-35.3 {Tcl_Eof with pipe} -constraints {stdio openpipe} -setup {
+ file delete $path(pipe)
+} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {chan gets stdin}
+ chan puts $f1 {chan puts hello}
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ chan puts $f1 hello
+ set x [chan eof $f1]
+ chan flush $f1
+ lappend x [chan eof $f1]
+ chan gets $f1
+ lappend x [chan eof $f1]
+ chan gets $f1
+ lappend x [chan eof $f1]
+ chan gets $f1
+ lappend x [chan eof $f1]
+ chan gets $f1
+ lappend x [chan eof $f1]
+} -cleanup {
+ chan close $f1
+} -result {0 0 0 1 1 1}
+test chan-io-35.4 {Tcl_Eof, eof detection on nonblocking file} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {nonBlockFiles} -body {
+ chan close [open $path(test1) w]
+ set f [open $path(test1) r]
+ chan configure $f -blocking off
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {{} 1}
+test chan-io-35.5 {Tcl_Eof, eof detection on nonblocking pipe} -setup {
+ file delete $path(pipe)
+ set l ""
+} -constraints {stdio openpipe} -body {
+ set f [open $path(pipe) w]
+ chan puts $f {
+ exit
+ }
+ chan close $f
+ set f [openpipe r $path(pipe)]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {{} 1}
+test chan-io-35.6 {Tcl_Eof, eof char, lf write, auto read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar \x1a
+ chan puts $f abc\ndef
+ chan close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {9 8 1}
+test chan-io-35.7 {Tcl_Eof, eof char, lf write, lf read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar \x1a
+ chan puts $f abc\ndef
+ chan close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation lf -eofchar \x1a
+ list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {9 8 1}
+test chan-io-35.8 {Tcl_Eof, eof char, cr write, auto read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr -eofchar \x1a
+ chan puts $f abc\ndef
+ chan close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {9 8 1}
+test chan-io-35.9 {Tcl_Eof, eof char, cr write, cr read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr -eofchar \x1a
+ chan puts $f abc\ndef
+ chan close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation cr -eofchar \x1a
+ list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {9 8 1}
+test chan-io-35.10 {Tcl_Eof, eof char, crlf write, auto read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -eofchar \x1a
+ chan puts $f abc\ndef
+ chan close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {11 8 1}
+test chan-io-35.11 {Tcl_Eof, eof char, crlf write, crlf read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -eofchar \x1a
+ chan puts $f abc\ndef
+ chan close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf -eofchar \x1a
+ list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {11 8 1}
+test chan-io-35.12 {Tcl_Eof, eof char in middle, lf write, auto read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+ chan close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {17 8 1}
+test chan-io-35.13 {Tcl_Eof, eof char in middle, lf write, lf read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+ chan close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation lf -eofchar \x1a
+ list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {17 8 1}
+test chan-io-35.14 {Tcl_Eof, eof char in middle, cr write, auto read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr -eofchar {}
+ chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+ chan close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {17 8 1}
+test chan-io-35.15 {Tcl_Eof, eof char in middle, cr write, cr read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr -eofchar {}
+ chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+ chan close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation cr -eofchar \x1a
+ list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {17 8 1}
+test chan-io-35.16 {Tcl_Eof, eof char in middle, crlf write, auto read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -eofchar {}
+ chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+ chan close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {21 8 1}
+test chan-io-35.17 {Tcl_Eof, eof char in middle, crlf write, crlf read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -eofchar {}
+ chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+ chan close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf -eofchar \x1a
+ list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {21 8 1}
+
+# Test Tcl_InputBlocked
+
+test chan-io-36.1 {Tcl_InputBlocked on nonblocking pipe} -setup {
+ set x ""
+} -constraints {stdio openpipe} -body {
+ set f1 [openpipe]
+ chan puts $f1 {chan puts hello_from_pipe}
+ chan flush $f1
+ chan gets $f1
+ chan configure $f1 -blocking off -buffering full
+ chan puts $f1 {chan puts hello}
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+ chan flush $f1
+ after 200
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+} -cleanup {
+ chan close $f1
+} -result {{} 1 hello 0 {} 1}
+test chan-io-36.2 {Tcl_InputBlocked on blocking pipe} -setup {
+ set x ""
+} -constraints {stdio openpipe} -body {
+ set f1 [openpipe]
+ chan configure $f1 -buffering line
+ chan puts $f1 {chan puts hello_from_pipe}
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+ chan puts $f1 {exit}
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+ lappend x [chan eof $f1]
+} -cleanup {
+ chan close $f1
+} -result {hello_from_pipe 0 {} 0 1}
+test chan-io-36.3 {Tcl_InputBlocked vs files, short read} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan puts $f abcdefghijklmnop
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [chan blocked $f]
+ lappend l [chan read $f 3]
+ lappend l [chan blocked $f]
+ lappend l [chan read -nonewline $f]
+ lappend l [chan blocked $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {0 abc 0 defghijklmnop 0 1}
+test chan-io-36.4 {Tcl_InputBlocked vs files, event driven read} -setup {
+ file delete $path(test1)
+ set l ""
+ variable x
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan puts $f abcdefghijklmnop
+ chan close $f
+ set f [open $path(test1) r]
+ chan event $f readable [namespace code {
+ lappend l [chan read $f 3]
+ if {[chan eof $f]} {lappend l eof; chan close $f; set x done}
+ }]
+ vwait [namespace which -variable x]
+ return $l
+} -result {abc def ghi jkl mno {p
+} eof}
+test chan-io-36.5 {Tcl_InputBlocked vs files, short read, nonblocking} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {nonBlockFiles} -body {
+ set f [open $path(test1) w]
+ chan puts $f abcdefghijklmnop
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -blocking off
+ lappend l [chan blocked $f]
+ lappend l [chan read $f 3]
+ lappend l [chan blocked $f]
+ lappend l [chan read -nonewline $f]
+ lappend l [chan blocked $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {0 abc 0 defghijklmnop 0 1}
+test chan-io-36.6 {Tcl_InputBlocked vs files, event driven read} -setup {
+ file delete $path(test1)
+ set l ""
+ variable x
+} -constraints {nonBlockFiles fileevent} -body {
+ set f [open $path(test1) w]
+ chan puts $f abcdefghijklmnop
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -blocking off
+ chan event $f readable [namespace code {
+ lappend l [chan read $f 3]
+ if {[chan eof $f]} {lappend l eof; chan close $f; set x done}
+ }]
+ vwait [namespace which -variable x]
+ return $l
+} -result {abc def ghi jkl mno {p
+} eof}
+
+# Test Tcl_InputBuffered
+
+test chan-io-37.1 {Tcl_InputBuffered} -setup {
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(longfile) r]
+ chan configure $f -buffersize 4096
+ chan read $f 3
+ lappend l [testchannel inputbuffered $f]
+ lappend l [chan tell $f]
+} -cleanup {
+ chan close $f
+} -result {4093 3}
+test chan-io-37.2 {Tcl_InputBuffered, test input flushing on seek} -setup {
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(longfile) r]
+ chan configure $f -buffersize 4096
+ chan read $f 3
+ lappend l [testchannel inputbuffered $f]
+ lappend l [chan tell $f]
+ chan seek $f 0 current
+ lappend l [testchannel inputbuffered $f]
+ lappend l [chan tell $f]
+} -cleanup {
+ chan close $f
+} -result {4093 3 0 3}
+
+# Test Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize
+
+test chan-io-38.1 {Tcl_GetChannelBufferSize, default buffer size} -body {
+ set f [open $path(longfile) r]
+ chan configure $f -buffersize
+} -cleanup {
+ chan close $f
+} -result 4096
+test chan-io-38.2 {Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize} -setup {
+ set l ""
+} -body {
+ set f [open $path(longfile) r]
+ lappend l [chan configure $f -buffersize]
+ chan configure $f -buffersize 10000
+ lappend l [chan configure $f -buffersize]
+ chan configure $f -buffersize 1
+ lappend l [chan configure $f -buffersize]
+ chan configure $f -buffersize -1
+ lappend l [chan configure $f -buffersize]
+ chan configure $f -buffersize 0
+ lappend l [chan configure $f -buffersize]
+ chan configure $f -buffersize 100000
+ lappend l [chan configure $f -buffersize]
+ chan configure $f -buffersize 10000000
+ lappend l [chan configure $f -buffersize]
+} -cleanup {
+ chan close $f
+} -result {4096 10000 1 1 1 100000 1048576}
+test chan-io-38.3 {Tcl_SetChannelBufferSize, changing buffersize between reads} {
+ # This test crashes the interp if Bug #427196 is not fixed
+ set chan [open [info script] r]
+ chan configure $chan -buffersize 10
+ set var [chan read $chan 2]
+ chan configure $chan -buffersize 32
+ append var [chan read $chan]
+ chan close $chan
+} {}
+
+# Test Tcl_SetChannelOption, Tcl_GetChannelOption
+
+test chan-io-39.1 {Tcl_GetChannelOption} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -blocking
+} -cleanup {
+ chan close $f1
+} -result 1
+#
+# Test 17.2 was removed.
+#
+test chan-io-39.2 {Tcl_GetChannelOption} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -buffering
+} -cleanup {
+ chan close $f1
+} -result full
+test chan-io-39.3 {Tcl_GetChannelOption} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -buffering line
+ chan configure $f1 -buffering
+} -cleanup {
+ chan close $f1
+} -result line
+test chan-io-39.4 {Tcl_GetChannelOption, Tcl_SetChannelOption} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f1 [open $path(test1) w]
+ lappend l [chan configure $f1 -buffering]
+ chan configure $f1 -buffering line
+ lappend l [chan configure $f1 -buffering]
+ chan configure $f1 -buffering none
+ lappend l [chan configure $f1 -buffering]
+ chan configure $f1 -buffering line
+ lappend l [chan configure $f1 -buffering]
+ chan configure $f1 -buffering full
+ lappend l [chan configure $f1 -buffering]
+} -cleanup {
+ chan close $f1
+} -result {full line none line full}
+test chan-io-39.5 {Tcl_GetChannelOption, invariance} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f1 [open $path(test1) w]
+ lappend l [chan configure $f1 -buffering]
+ lappend l [list [catch {chan configure $f1 -buffering green} msg] $msg]
+ lappend l [chan configure $f1 -buffering]
+} -cleanup {
+ chan close $f1
+} -result {full {1 {bad value for -buffering: must be one of full, line, or none}} full}
+test chan-io-39.6 {Tcl_SetChannelOption, multiple options} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -buffering line
+ chan puts $f1 hello
+ chan puts $f1 bye
+ file size $path(test1)
+} -cleanup {
+ chan close $f1
+} -result 10
+test chan-io-39.7 {Tcl_SetChannelOption, buffering, translation} -setup {
+ file delete $path(test1)
+ set x ""
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf
+ chan puts $f1 hello
+ chan puts $f1 bye
+ chan configure $f1 -buffering line
+ lappend x [file size $path(test1)]
+ chan puts $f1 really_bye
+ lappend x [file size $path(test1)]
+} -cleanup {
+ chan close $f1
+} -result {0 21}
+test chan-io-39.8 {Tcl_SetChannelOption, different buffering options} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -buffering none -eofchar {}
+ chan puts -nonewline $f1 hello
+ lappend l [file size $path(test1)]
+ chan puts -nonewline $f1 hello
+ lappend l [file size $path(test1)]
+ chan configure $f1 -buffering full
+ chan puts -nonewline $f1 hello
+ lappend l [file size $path(test1)]
+ chan configure $f1 -buffering none
+ lappend l [file size $path(test1)]
+ chan puts -nonewline $f1 hello
+ lappend l [file size $path(test1)]
+ chan close $f1
+ lappend l [file size $path(test1)]
+} -result {5 10 10 10 20 20}
+test chan-io-39.9 {Tcl_SetChannelOption, blocking mode} -setup {
+ file delete $path(test1)
+ set x ""
+} -constraints {nonBlockFiles} -body {
+ set f1 [open $path(test1) w]
+ chan close $f1
+ set f1 [open $path(test1) r]
+ lappend x [chan configure $f1 -blocking]
+ chan configure $f1 -blocking off
+ lappend x [chan configure $f1 -blocking]
+ lappend x [chan gets $f1]
+ lappend x [chan read $f1 1000]
+ lappend x [chan blocked $f1]
+ lappend x [chan eof $f1]
+} -cleanup {
+ chan close $f1
+} -result {1 0 {} {} 0 1}
+test chan-io-39.10 {Tcl_SetChannelOption, blocking mode} -setup {
+ file delete $path(pipe)
+ set x ""
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {
+ chan gets stdin
+ after 100
+ chan puts hi
+ chan gets stdin
+ }
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ chan configure $f1 -blocking off -buffering line
+ lappend x [chan configure $f1 -blocking]
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+ chan configure $f1 -blocking on
+ chan puts $f1 hello
+ chan configure $f1 -blocking off
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+ chan configure $f1 -blocking on
+ chan puts $f1 bye
+ chan configure $f1 -blocking off
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+ chan configure $f1 -blocking on
+ lappend x [chan configure $f1 -blocking]
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+ lappend x [chan eof $f1]
+ lappend x [chan gets $f1]
+ lappend x [chan eof $f1]
+} -cleanup {
+ chan close $f1
+} -result {0 {} 1 {} 1 {} 1 1 hi 0 0 {} 1}
+test chan-io-39.11 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size clipped to lower bound} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -buffersize -10
+ chan configure $f -buffersize
+} -cleanup {
+ chan close $f
+} -result 1
+test chan-io-39.12 {Tcl_SetChannelOption, Tcl_GetChannelOption buffer size clipped to upper bound} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -buffersize 10000000
+ chan configure $f -buffersize
+} -cleanup {
+ chan close $f
+} -result 1048576
+test chan-io-39.13 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -buffersize 40000
+ chan configure $f -buffersize
+} -cleanup {
+ chan close $f
+} -result 40000
+test chan-io-39.14 {Tcl_SetChannelOption: -encoding, binary & utf-8} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -encoding {}
+ chan puts -nonewline $f \xe7\x89\xa6
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -encoding utf-8
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result \u7266
+test chan-io-39.15 {Tcl_SetChannelOption: -encoding, binary & utf-8} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -encoding binary
+ chan puts -nonewline $f \xe7\x89\xa6
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -encoding utf-8
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result \u7266
+test chan-io-39.16 {Tcl_SetChannelOption: -encoding, errors} -setup {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+} -body {
+ chan configure $f -encoding foobar
+} -returnCodes error -cleanup {
+ chan close $f
+} -result {unknown encoding "foobar"}
+test chan-io-39.17 {Tcl_SetChannelOption: -encoding, clearing CHANNEL_NEED_MORE_DATA} -setup {
+ variable x {}
+} -constraints {stdio openpipe fileevent} -body {
+ set f [openpipe r+ $path(cat)]
+ chan configure $f -encoding binary
+ chan puts -nonewline $f "\xe7"
+ chan flush $f
+ chan configure $f -encoding utf-8 -blocking 0
+ chan event $f readable [namespace code { lappend x [chan read $f] }]
+ vwait [namespace which -variable x]
+ after 300 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ chan configure $f -encoding utf-8
+ vwait [namespace which -variable x]
+ after 300 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ chan configure $f -encoding binary
+ vwait [namespace which -variable x]
+ after 300 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ chan close $f
+} -result "{} timeout {} timeout \xe7 timeout"
+test chan-io-39.18 {Tcl_SetChannelOption, setting read mode independently} \
+ -constraints {socket} -body {
+ proc accept {s a p} {chan close $s}
+ set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [chan configure $s1 -sockname] 2]
+ set s2 [socket 127.0.0.1 $port]
+ update
+ chan configure $s2 -translation {auto lf}
+ chan configure $s2 -translation
+} -cleanup {
+ chan close $s1
+ chan close $s2
+} -result {auto lf}
+test chan-io-39.19 {Tcl_SetChannelOption, setting read mode independently} \
+ -constraints {socket} -body {
+ proc accept {s a p} {chan close $s}
+ set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [chan configure $s1 -sockname] 2]
+ set s2 [socket 127.0.0.1 $port]
+ update
+ chan configure $s2 -translation {auto crlf}
+ chan configure $s2 -translation
+} -cleanup {
+ chan close $s1
+ chan close $s2
+} -result {auto crlf}
+test chan-io-39.20 {Tcl_SetChannelOption, setting read mode independently} \
+ -constraints {socket} -body {
+ proc accept {s a p} {chan close $s}
+ set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [chan configure $s1 -sockname] 2]
+ set s2 [socket 127.0.0.1 $port]
+ update
+ chan configure $s2 -translation {auto cr}
+ chan configure $s2 -translation
+} -cleanup {
+ chan close $s1
+ chan close $s2
+} -result {auto cr}
+test chan-io-39.21 {Tcl_SetChannelOption, setting read mode independently} \
+ -constraints {socket} -body {
+ proc accept {s a p} {chan close $s}
+ set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [chan configure $s1 -sockname] 2]
+ set s2 [socket 127.0.0.1 $port]
+ update
+ chan configure $s2 -translation {auto auto}
+ chan configure $s2 -translation
+} -cleanup {
+ chan close $s1
+ chan close $s2
+} -result {auto crlf}
+test chan-io-39.22 {Tcl_SetChannelOption, invariance} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {unix} -body {
+ set f1 [open $path(test1) w+]
+ lappend l [chan configure $f1 -eofchar]
+ chan configure $f1 -eofchar {ON GO}
+ lappend l [chan configure $f1 -eofchar]
+ chan configure $f1 -eofchar D
+ lappend l [chan configure $f1 -eofchar]
+} -cleanup {
+ chan close $f1
+} -result {{{} {}} {O G} {D D}}
+test chan-io-39.22a {Tcl_SetChannelOption, invariance} -setup {
+ file delete $path(test1)
+ set l [list]
+} -body {
+ set f1 [open $path(test1) w+]
+ chan configure $f1 -eofchar {ON GO}
+ lappend l [chan configure $f1 -eofchar]
+ chan configure $f1 -eofchar D
+ lappend l [chan configure $f1 -eofchar]
+ lappend l [list [catch {chan configure $f1 -eofchar {1 2 3}} msg] $msg]
+} -cleanup {
+ chan close $f1
+} -result {{O G} {D D} {1 {bad value for -eofchar: should be a list of zero, one, or two elements}}}
+test chan-io-39.23 {Tcl_GetChannelOption, server socket is not readable or\
+ writeable, it should still have valid -eofchar and -translation options} -setup {
+ set l [list]
+} -body {
+ set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ lappend l [chan configure $sock -eofchar] \
+ [chan configure $sock -translation]
+} -cleanup {
+ chan close $sock
+} -result {{{}} auto}
+test chan-io-39.24 {Tcl_SetChannelOption, server socket is not readable or\
+ writable so we can't change -eofchar or -translation} -setup {
+ set l [list]
+} -body {
+ set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ chan configure $sock -eofchar D -translation lf
+ lappend l [chan configure $sock -eofchar] \
+ [chan configure $sock -translation]
+} -cleanup {
+ chan close $sock
+} -result {{{}} auto}
+
+test chan-io-40.1 {POSIX open access modes: RDWR} -setup {
+ file delete $path(test3)
+} -body {
+ set f [open $path(test3) w]
+ chan puts $f xyzzy
+ chan close $f
+ set f [open $path(test3) RDWR]
+ chan puts -nonewline $f "ab"
+ chan seek $f 0 current
+ set x [chan gets $f]
+ chan close $f
+ set f [open $path(test3) r]
+ lappend x [chan gets $f]
+} -cleanup {
+ chan close $f
+} -result {zzy abzzy}
+test chan-io-40.2 {POSIX open access modes: CREAT} -setup {
+ file delete $path(test3)
+} -constraints {unix} -body {
+ set f [open $path(test3) {WRONLY CREAT} 0600]
+ file stat $path(test3) stats
+ set x [format "0%o" [expr $stats(mode)&0o777]]
+ chan puts $f "line 1"
+ chan close $f
+ set f [open $path(test3) r]
+ lappend x [chan gets $f]
+} -cleanup {
+ chan close $f
+} -result {0600 {line 1}}
+test chan-io-40.3 {POSIX open access modes: CREAT} -setup {
+ file delete $path(test3)
+} -constraints {unix umask} -body {
+ # This test only works if your umask is 2, like ouster's.
+ chan close [open $path(test3) {WRONLY CREAT}]
+ file stat $path(test3) stats
+ format "0%o" [expr $stats(mode)&0o777]
+} -result [format %04o [expr {0o666 & ~ $umaskValue}]]
+test chan-io-40.4 {POSIX open access modes: CREAT} -setup {
+ file delete $path(test3)
+} -body {
+ set f [open $path(test3) w]
+ chan configure $f -eofchar {}
+ chan puts $f xyzzy
+ chan close $f
+ set f [open $path(test3) {WRONLY CREAT}]
+ chan configure $f -eofchar {}
+ chan puts -nonewline $f "ab"
+ chan close $f
+ set f [open $path(test3) r]
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result abzzy
+test chan-io-40.5 {POSIX open access modes: APPEND} -setup {
+ file delete $path(test3)
+ set x ""
+} -body {
+ set f [open $path(test3) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f xyzzy
+ chan close $f
+ set f [open $path(test3) {WRONLY APPEND}]
+ chan configure $f -translation lf
+ chan puts $f "new line"
+ chan seek $f 0
+ chan puts $f "abc"
+ chan close $f
+ set f [open $path(test3) r]
+ chan configure $f -translation lf
+ chan seek $f 6 current
+ lappend x [chan gets $f]
+ lappend x [chan gets $f]
+} -cleanup {
+ chan close $f
+} -result {{new line} abc}
+test chan-io-40.6 {POSIX open access modes: EXCL} -match regexp -setup {
+ file delete $path(test3)
+} -body {
+ set f [open $path(test3) w]
+ chan puts $f xyzzy
+ chan close $f
+ open $path(test3) {WRONLY CREAT EXCL}
+} -returnCodes error -result {(?i)couldn't open ".*test3": file (already )?exists}
+test chan-io-40.7 {POSIX open access modes: EXCL} -setup {
+ file delete $path(test3)
+} -body {
+ set f [open $path(test3) {WRONLY CREAT EXCL}]
+ chan configure $f -eofchar {}
+ chan puts $f "A test line"
+ chan close $f
+ viewFile test3
+} -result {A test line}
+test chan-io-40.8 {POSIX open access modes: TRUNC} -setup {
+ file delete $path(test3)
+} -body {
+ set f [open $path(test3) w]
+ chan puts $f xyzzy
+ chan close $f
+ set f [open $path(test3) {WRONLY TRUNC}]
+ chan puts $f abc
+ chan close $f
+ set f [open $path(test3) r]
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result abc
+test chan-io-40.9 {POSIX open access modes: NONBLOCK} -setup {
+ file delete $path(test3)
+} -constraints {nonPortable unix} -body {
+ set f [open $path(test3) {WRONLY NONBLOCK CREAT}]
+ chan puts $f "NONBLOCK test"
+ chan close $f
+ set f [open $path(test3) r]
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result {NONBLOCK test}
+test chan-io-40.10 {POSIX open access modes: RDONLY} -body {
+ set f [open $path(test1) w]
+ chan puts $f "two lines: this one"
+ chan puts $f "and this"
+ chan close $f
+ set f [open $path(test1) RDONLY]
+ list [chan gets $f] [catch {chan puts $f Test} msg] $msg
+} -cleanup {
+ chan close $f
+} -match glob -result {{two lines: this one} 1 {channel "*" wasn't opened for writing}}
+test chan-io-40.11 {POSIX open access modes: RDONLY} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) RDONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test chan-io-40.12 {POSIX open access modes: WRONLY} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) WRONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test chan-io-40.13 {POSIX open access modes: WRONLY} -body {
+ makeFile xyzzy test3
+ set f [open $path(test3) WRONLY]
+ chan configure $f -eofchar {}
+ chan puts -nonewline $f "ab"
+ chan seek $f 0 current
+ set x [list [catch {chan gets $f} msg] $msg]
+ chan close $f
+ lappend x [viewFile test3]
+} -match glob -result {1 {channel "*" wasn't opened for reading} abzzy}
+test chan-io-40.14 {POSIX open access modes: RDWR} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) RDWR
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test chan-io-40.15 {POSIX open access modes: RDWR} {
+ makeFile xyzzy test3
+ set f [open $path(test3) RDWR]
+ chan puts -nonewline $f "ab"
+ chan seek $f 0 current
+ set x [chan gets $f]
+ chan close $f
+ lappend x [viewFile test3]
+} {zzy abzzy}
+test chan-io-40.16 {tilde substitution in open} -constraints makeFileInHome -setup {
+ makeFile {Some text} _test_ ~
+} -body {
+ file exists [file join $::env(HOME) _test_]
+} -cleanup {
+ removeFile _test_ ~
+} -result 1
+test chan-io-40.17 {tilde substitution in open} -setup {
+ set home $::env(HOME)
+} -body {
+ unset ::env(HOME)
+ open ~/foo
+} -returnCodes error -cleanup {
+ set ::env(HOME) $home
+} -result {couldn't find HOME environment variable to expand path}
+
+test chan-io-41.1 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
+ chan event foo
+} -returnCodes error -result {wrong # args: should be "chan event channelId event ?script?"}
+test chan-io-41.2 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
+ chan event foo bar baz q
+} -returnCodes error -result {wrong # args: should be "chan event channelId event ?script?"}
+test chan-io-41.3 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
+ chan event gorp readable
+} -returnCodes error -result {can not find channel named "gorp"}
+test chan-io-41.4 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
+ chan event gorp writable
+} -returnCodes error -result {can not find channel named "gorp"}
+test chan-io-41.5 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
+ chan event gorp who-knows
+} -returnCodes error -result {bad event name "who-knows": must be readable or writable}
+
+#
+# Test chan event on a file
+#
+
+set path(foo) [makeFile {} foo]
+set f [open $path(foo) w+]
+
+test chan-io-42.1 {Tcl_FileeventCmd: creating, deleting, querying} {fileevent} {
+ list [chan event $f readable] [chan event $f writable]
+} {{} {}}
+test chan-io-42.2 {Tcl_FileeventCmd: replacing} {fileevent} {
+ set result {}
+ chan event $f r "first script"
+ lappend result [chan event $f readable]
+ chan event $f r "new script"
+ lappend result [chan event $f readable]
+ chan event $f r "yet another"
+ lappend result [chan event $f readable]
+ chan event $f r ""
+ lappend result [chan event $f readable]
+} {{first script} {new script} {yet another} {}}
+test chan-io-42.3 {Tcl_FileeventCmd: replacing, with NULL chars in script} {fileevent} {
+ set result {}
+ chan event $f r "first scr\0ipt"
+ lappend result [string length [chan event $f readable]]
+ chan event $f r "new scr\0ipt"
+ lappend result [string length [chan event $f readable]]
+ chan event $f r "yet ano\0ther"
+ lappend result [string length [chan event $f readable]]
+ chan event $f r ""
+ lappend result [chan event $f readable]
+} {13 11 12 {}}
+
+test chan-io-43.1 {Tcl_FileeventCmd: creating, deleting, querying} {stdio unixExecs fileevent} {
+ set result {}
+ chan event $f readable "script 1"
+ lappend result [chan event $f readable] [chan event $f writable]
+ chan event $f writable "write script"
+ lappend result [chan event $f readable] [chan event $f writable]
+ chan event $f readable {}
+ lappend result [chan event $f readable] [chan event $f writable]
+ chan event $f writable {}
+ lappend result [chan event $f readable] [chan event $f writable]
+} {{script 1} {} {script 1} {write script} {} {write script} {} {}}
+test chan-io-43.2 {Tcl_FileeventCmd: deleting when many present} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+ set result {}
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+ lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
+ chan event $f r "chan read f"
+ chan event $f2 r "chan read f2"
+ chan event $f3 r "chan read f3"
+ lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
+ chan event $f2 r {}
+ lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
+ chan event $f3 r {}
+ lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
+ chan event $f r {}
+ lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
+} -cleanup {
+ catch {chan close $f2}
+ catch {chan close $f3}
+} -result {{} {} {} {chan read f} {chan read f2} {chan read f3} {chan read f} {} {chan read f3} {chan read f} {} {} {} {} {}}
+
+test chan-io-44.1 {FileEventProc procedure: normal read event} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+ chan event $f2 readable [namespace code {
+ set x [chan gets $f2]; chan event $f2 readable {}
+ }]
+ chan puts $f2 text; chan flush $f2
+ variable x initial
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ catch {chan close $f2}
+ catch {chan close $f3}
+} -result {text}
+test chan-io-44.2 {FileEventProc procedure: error in read event} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+ proc myHandler {msg options} {
+ variable x $msg
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+ chan event $f2 readable {error bogus}
+ chan puts $f2 text; chan flush $f2
+ variable x initial
+ vwait [namespace which -variable x]
+ list $x [chan event $f2 readable]
+} -cleanup {
+ interp bgerror {} $handler
+ catch {chan close $f2}
+ catch {chan close $f3}
+} -result {bogus {}}
+test chan-io-44.3 {FileEventProc procedure: normal write event} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+ chan event $f2 writable [namespace code {
+ lappend x "triggered"
+ incr count -1
+ if {$count <= 0} {
+ chan event $f2 writable {}
+ }
+ }]
+ variable x initial
+ set count 3
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ catch {chan close $f2}
+ catch {chan close $f3}
+} -result {initial triggered triggered triggered}
+test chan-io-44.4 {FileEventProc procedure: eror in write event} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+ proc myHandler {msg options} {
+ variable x $msg
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+ chan event $f2 writable {error bad-write}
+ variable x initial
+ vwait [namespace which -variable x]
+ list $x [chan event $f2 writable]
+} -cleanup {
+ interp bgerror {} $handler
+ catch {chan close $f2}
+ catch {chan close $f3}
+} -result {bad-write {}}
+test chan-io-44.5 {FileEventProc procedure: end of file} {stdio unixExecs openpipe fileevent} {
+ set f4 [openpipe r $path(cat) << foo]
+ chan event $f4 readable [namespace code {
+ if {[chan gets $f4 line] < 0} {
+ lappend x eof
+ chan event $f4 readable {}
+ } else {
+ lappend x $line
+ }
+ }]
+ variable x initial
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ chan close $f4
+ set x
+} {initial foo eof}
+
+chan close $f
+makeFile "foo bar" foo
+
+test chan-io-45.1 {DeleteFileEvent, cleanup on chan close} {fileevent} {
+ set f [open $path(foo) r]
+ chan event $f readable [namespace code {
+ lappend x "binding triggered: \"[chan gets $f]\""
+ chan event $f readable {}
+ }]
+ chan close $f
+ set x initial
+ after 100 [namespace code {
+ set y done
+ }]
+ variable y
+ vwait [namespace which -variable y]
+ set x
+} {initial}
+test chan-io-45.2 {DeleteFileEvent, cleanup on chan close} {fileevent} {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ chan event $f readable [namespace code {
+ lappend x "f triggered: \"[chan gets $f]\""
+ chan event $f readable {}
+ }]
+ chan event $f2 readable [namespace code {
+ lappend x "f2 triggered: \"[chan gets $f2]\""
+ chan event $f2 readable {}
+ }]
+ chan close $f
+ variable x initial
+ vwait [namespace which -variable x]
+ chan close $f2
+ set x
+} {initial {f2 triggered: "foo bar"}}
+test chan-io-45.3 {DeleteFileEvent, cleanup on chan close} {fileevent} {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ set f3 [open $path(foo) r]
+ chan event $f readable {f script}
+ chan event $f2 readable {f2 script}
+ chan event $f3 readable {f3 script}
+ set x {}
+ chan close $f2
+ lappend x [catch {chan event $f readable} msg] $msg \
+ [catch {chan event $f2 readable}] \
+ [catch {chan event $f3 readable} msg] $msg
+ chan close $f3
+ lappend x [catch {chan event $f readable} msg] $msg \
+ [catch {chan event $f2 readable}] \
+ [catch {chan event $f3 readable}]
+ chan close $f
+ lappend x [catch {chan event $f readable}] \
+ [catch {chan event $f2 readable}] \
+ [catch {chan event $f3 readable}]
+} {0 {f script} 1 0 {f3 script} 0 {f script} 1 1 1 1 1}
+
+# Execute these tests only if the "testfevent" command is present.
+
+test chan-io-46.1 {Tcl event loop vs multiple interpreters} {testfevent fileevent} {
+ testfevent create
+ set script "set f \[[list open $path(foo) r]]\n"
+ append script {
+ set x "no event"
+ chan event $f readable [namespace code {
+ set x "f triggered: [chan gets $f]"
+ chan event $f readable {}
+ }]
+ }
+ testfevent cmd $script
+ after 1 ;# We must delay because Windows takes a little time to notice
+ update
+ testfevent cmd {chan close $f}
+ list [testfevent cmd {set x}] [testfevent cmd {info commands after}]
+} {{f triggered: foo bar} after}
+test chan-io-46.2 {Tcl event loop vs multiple interpreters} testfevent {
+ testfevent create
+ testfevent cmd {
+ variable x 0
+ after 100 {set x triggered}
+ vwait [namespace which -variable x]
+ set x
+ }
+} {triggered}
+test chan-io-46.3 {Tcl event loop vs multiple interpreters} testfevent {
+ testfevent create
+ testfevent cmd {
+ set x 0
+ after 10 {lappend x timer}
+ after 30
+ set result $x
+ update idletasks
+ lappend result $x
+ update
+ lappend result $x
+ }
+} {0 0 {0 timer}}
+
+test chan-io-47.1 {chan event vs multiple interpreters} -setup {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ set f3 [open $path(foo) r]
+ set x {}
+} -constraints {testfevent fileevent} -body {
+ chan event $f readable {script 1}
+ testfevent create
+ testfevent share $f2
+ testfevent cmd "chan event $f2 readable {script 2}"
+ chan event $f3 readable {sript 3}
+ lappend x [chan event $f2 readable]
+ testfevent delete
+ lappend x [chan event $f readable] [chan event $f2 readable] \
+ [chan event $f3 readable]
+} -cleanup {
+ chan close $f
+ chan close $f2
+ chan close $f3
+} -result {{} {script 1} {} {sript 3}}
+test chan-io-47.2 {deleting chan event on interpreter delete} -setup {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ set f3 [open $path(foo) r]
+ set f4 [open $path(foo) r]
+} -constraints {testfevent fileevent} -body {
+ chan event $f readable {script 1}
+ testfevent create
+ testfevent share $f2
+ testfevent share $f3
+ testfevent cmd "chan event $f2 readable {script 2}
+ chan event $f3 readable {script 3}"
+ chan event $f4 readable {script 4}
+ testfevent delete
+ list [chan event $f readable] [chan event $f2 readable] \
+ [chan event $f3 readable] [chan event $f4 readable]
+} -cleanup {
+ chan close $f
+ chan close $f2
+ chan close $f3
+ chan close $f4
+} -result {{script 1} {} {} {script 4}}
+test chan-io-47.3 {deleting chan event on interpreter delete} -setup {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ set f3 [open $path(foo) r]
+ set f4 [open $path(foo) r]
+} -constraints {testfevent fileevent} -body {
+ testfevent create
+ testfevent share $f3
+ testfevent share $f4
+ chan event $f readable {script 1}
+ chan event $f2 readable {script 2}
+ testfevent cmd "chan event $f3 readable {script 3}
+ chan event $f4 readable {script 4}"
+ testfevent delete
+ list [chan event $f readable] [chan event $f2 readable] \
+ [chan event $f3 readable] [chan event $f4 readable]
+} -cleanup {
+ chan close $f
+ chan close $f2
+ chan close $f3
+ chan close $f4
+} -result {{script 1} {script 2} {} {}}
+test chan-io-47.4 {file events on shared files and multiple interpreters} -setup {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+} -constraints {testfevent fileevent} -body {
+ testfevent create
+ testfevent share $f
+ testfevent cmd "chan event $f readable {script 1}"
+ chan event $f readable {script 2}
+ chan event $f2 readable {script 3}
+ list [chan event $f2 readable] [testfevent cmd "chan event $f readable"] \
+ [chan event $f readable]
+} -cleanup {
+ testfevent delete
+ chan close $f
+ chan close $f2
+} -result {{script 3} {script 1} {script 2}}
+test chan-io-47.5 {file events on shared files, deleting file events} -setup {
+ set f [open $path(foo) r]
+} -body {
+ testfevent create
+ testfevent share $f
+ testfevent cmd "chan event $f readable {script 1}"
+ chan event $f readable {script 2}
+ testfevent cmd "chan event $f readable {}"
+ list [testfevent cmd "chan event $f readable"] [chan event $f readable]
+} -constraints {testfevent fileevent} -cleanup {
+ testfevent delete
+ chan close $f
+} -result {{} {script 2}}
+test chan-io-47.6 {file events on shared files, deleting file events} -setup {
+ set f [open $path(foo) r]
+} -body {
+ testfevent create
+ testfevent share $f
+ testfevent cmd "chan event $f readable {script 1}"
+ chan event $f readable {script 2}
+ chan event $f readable {}
+ list [testfevent cmd "chan event $f readable"] [chan event $f readable]
+} -constraints {testfevent fileevent} -cleanup {
+ testfevent delete
+ chan close $f
+} -result {{script 1} {}}
+
+set path(bar) [makeFile {} bar]
+
+test chan-io-48.1 {testing readability conditions} {fileevent} {
+ set f [open $path(bar) w]
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan close $f
+ set f [open $path(bar) r]
+ chan event $f readable [namespace code {
+ lappend l called
+ if {[chan eof $f]} {
+ chan close $f
+ set x done
+ } else {
+ chan gets $f
+ }
+ }]
+ set l ""
+ variable x not_done
+ vwait [namespace which -variable x]
+ list $x $l
+} {done {called called called called called called called}}
+test chan-io-48.2 {testing readability conditions} {nonBlockFiles fileevent} {
+ set f [open $path(bar) w]
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan close $f
+ set f [open $path(bar) r]
+ chan event $f readable [namespace code {
+ lappend l called
+ if {[chan eof $f]} {
+ chan close $f
+ set x done
+ } else {
+ chan gets $f
+ }
+ }]
+ chan configure $f -blocking off
+ set l ""
+ variable x not_done
+ vwait [namespace which -variable x]
+ list $x $l
+} {done {called called called called called called called}}
+set path(my_script) [makeFile {} my_script]
+test chan-io-48.3 {testing readability conditions} -setup {
+ set l ""
+} -constraints {stdio unix nonBlockFiles openpipe fileevent} -body {
+ set f [open $path(bar) w]
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan close $f
+ set f [open $path(my_script) w]
+ chan puts $f {
+ proc copy_slowly {f} {
+ while {![chan eof $f]} {
+ chan puts [chan gets $f]
+ after 200
+ }
+ chan close $f
+ }
+ }
+ chan close $f
+ set f [openpipe]
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ } else {
+ chan gets $f
+ lappend l [chan blocked $f]
+ chan gets $f
+ lappend l [chan blocked $f]
+ }
+ }]
+ chan configure $f -buffering line
+ chan configure $f -blocking off
+ variable x not_done
+ chan puts $f [list source $path(my_script)]
+ chan puts $f "set f \[[list open $path(bar) r]]"
+ chan puts $f {copy_slowly $f}
+ chan puts $f {exit}
+ vwait [namespace which -variable x]
+ list $x $l
+} -cleanup {
+ chan close $f
+} -result {done {0 1 0 1 0 1 0 1 0 1 0 1 0 0}}
+test chan-io-48.4 {lf write, testing readability, ^Z termination, auto read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.5 {lf write, testing readability, ^Z in middle, auto read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.6 {cr write, testing readability, ^Z termination, auto read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.7 {cr write, testing readability, ^Z in middle, auto read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.8 {crlf write, testing readability, ^Z termination, auto read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.9 {crlf write, testing readability, ^Z in middle, auto read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.10 {lf write, testing readability, ^Z in middle, lf read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation lf
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.11 {lf write, testing readability, ^Z termination, lf read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf -eofchar \x1a
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.12 {cr write, testing readability, ^Z in middle, cr read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation cr
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.13 {cr write, testing readability, ^Z termination, cr read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr -eofchar \x1a
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.14 {crlf write, testing readability, ^Z in middle, crlf read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation crlf
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.15 {crlf write, testing readability, ^Z termi, crlf read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf -eofchar \x1a
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+
+test chan-io-49.1 {testing crlf reading, leftover cr disgorgment} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\rb\rc\r\n"
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [file size $path(test1)]
+ chan configure $f -translation crlf
+ lappend l [chan read $f 1]
+ lappend l [chan tell $f]
+ lappend l [chan read $f 1]
+ lappend l [chan tell $f]
+ lappend l [chan read $f 1]
+ lappend l [chan tell $f]
+ lappend l [chan read $f 1]
+ lappend l [chan tell $f]
+ lappend l [chan read $f 1]
+ lappend l [chan tell $f]
+ lappend l [chan read $f 1]
+ lappend l [chan tell $f]
+ lappend l [chan eof $f]
+ lappend l [chan read $f 1]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result "7 a 1 [list \r] 2 b 3 [list \r] 4 c 5 {
+} 7 0 {} 1"
+test chan-io-49.2 {testing crlf reading, leftover cr disgorgment} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\rb\rc\r\n"
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [file size $path(test1)]
+ chan configure $f -translation crlf
+ lappend l [chan read $f 2]
+ lappend l [chan tell $f]
+ lappend l [chan read $f 2]
+ lappend l [chan tell $f]
+ lappend l [chan read $f 2]
+ lappend l [chan tell $f]
+ lappend l [chan eof $f]
+ lappend l [chan read $f 2]
+ lappend l [chan tell $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result "7 [list a\r] 2 [list b\r] 4 [list c\n] 7 0 {} 7 1"
+test chan-io-49.3 {testing crlf reading, leftover cr disgorgment} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\rb\rc\r\n"
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [file size $path(test1)]
+ chan configure $f -translation crlf
+ lappend l [chan read $f 3]
+ lappend l [chan tell $f]
+ lappend l [chan read $f 3]
+ lappend l [chan tell $f]
+ lappend l [chan eof $f]
+ lappend l [chan read $f 3]
+ lappend l [chan tell $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result "7 [list a\rb] 3 [list \rc\n] 7 0 {} 7 1"
+test chan-io-49.4 {testing crlf reading, leftover cr disgorgment} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\rb\rc\r\n"
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [file size $path(test1)]
+ chan configure $f -translation crlf
+ lappend l [chan read $f 3]
+ lappend l [chan tell $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result "7 [list a\rb] 3 [list \rc] 7 0 {} 7 1"
+test chan-io-49.5 {testing crlf reading, leftover cr disgorgment} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\rb\rc\r\n"
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [file size $path(test1)]
+ chan configure $f -translation crlf
+ lappend l [set x [chan gets $f]]
+ lappend l [chan tell $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result [list 7 a\rb\rc 7 {} 7 1]
+
+test chan-io-50.1 {testing handler deletion} -setup {
+ file delete $path(test1)
+} -constraints {testchannelevent} -body {
+ set f [open $path(test1) w]
+ chan close $f
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code {
+ variable z called
+ testchannelevent $f delete 0
+ }]
+ variable z not_called
+ update
+ return $z
+} -cleanup {
+ chan close $f
+} -result called
+test chan-io-50.2 {testing handler deletion with multiple handlers} -setup {
+ file delete $path(test1)
+ chan close [open $path(test1) w]
+ set z ""
+} -constraints {testchannelevent} -body {
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list delhandler $f 1]]
+ testchannelevent $f add readable [namespace code [list delhandler $f 0]]
+ proc delhandler {f i} {
+ variable z
+ lappend z "called delhandler $f $i"
+ testchannelevent $f delete 0
+ }
+ update
+ string equal $z \
+ [list [list called delhandler $f 0] [list called delhandler $f 1]]
+} -cleanup {
+ chan close $f
+} -result 1
+test chan-io-50.3 {testing handler deletion with multiple handlers} -setup {
+ file delete $path(test1)
+ chan close [open $path(test1) w]
+ set z ""
+} -constraints {testchannelevent} -body {
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list notcalled $f 1]]
+ testchannelevent $f add readable [namespace code [list delhandler $f 0]]
+ proc notcalled {f i} {
+ variable z
+ lappend z "notcalled was called!! $f $i"
+ }
+ proc delhandler {f i} {
+ variable z
+ testchannelevent $f delete 1
+ lappend z "delhandler $f $i called"
+ testchannelevent $f delete 0
+ lappend z "delhandler $f $i deleted myself"
+ }
+ update
+ string equal $z \
+ [list [list delhandler $f 0 called] \
+ [list delhandler $f 0 deleted myself]]
+} -cleanup {
+ chan close $f
+} -result 1
+test chan-io-50.4 {testing handler deletion vs reentrant calls} -setup {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ chan close $f
+} -constraints {testchannelevent} -body {
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code {
+ if {$u eq "recursive"} {
+ testchannelevent $f delete 0
+ lappend z "delrecursive deleting recursive"
+ } else {
+ lappend z "delrecursive calling recursive"
+ set u recursive
+ update
+ }
+ }]
+ variable u toplevel
+ variable z ""
+ update
+ return $z
+} -cleanup {
+ chan close $f
+} -result {{delrecursive calling recursive} {delrecursive deleting recursive}}
+test chan-io-50.5 {testing handler deletion vs reentrant calls} -setup {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ chan close $f
+} -constraints {testchannelevent} -body {
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list notcalled $f]]
+ testchannelevent $f add readable [namespace code [list del $f]]
+ proc notcalled {f} {
+ variable z
+ lappend z "notcalled was called!! $f"
+ }
+ proc del {f} {
+ variable u
+ variable z
+ if {$u eq "recursive"} {
+ testchannelevent $f delete 1
+ testchannelevent $f delete 0
+ lappend z "del deleted notcalled"
+ lappend z "del deleted myself"
+ } else {
+ set u recursive
+ lappend z "del calling recursive"
+ update
+ lappend z "del after update"
+ }
+ }
+ set z ""
+ set u toplevel
+ update
+ return $z
+} -cleanup {
+ chan close $f
+} -result [list {del calling recursive} {del deleted notcalled} \
+ {del deleted myself} {del after update}]
+test chan-io-50.6 {testing handler deletion vs reentrant calls} -setup {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ chan close $f
+} -constraints {testchannelevent} -body {
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list second $f]]
+ testchannelevent $f add readable [namespace code [list first $f]]
+ proc first {f} {
+ variable u
+ variable z
+ if {$u eq "toplevel"} {
+ lappend z "first called"
+ set u first
+ update
+ lappend z "first after update"
+ } else {
+ lappend z "first called not toplevel"
+ }
+ }
+ proc second {f} {
+ variable u
+ variable z
+ if {$u eq "first"} {
+ lappend z "second called, first time"
+ set u second
+ testchannelevent $f delete 0
+ } elseif {$u eq "second"} {
+ lappend z "second called, second time"
+ testchannelevent $f delete 0
+ } else {
+ lappend z "second called, cannot happen!"
+ testchannelevent $f removeall
+ }
+ }
+ set z ""
+ set u toplevel
+ update
+ return $z
+} -cleanup {
+ chan close $f
+} -result [list {first called} {first called not toplevel} \
+ {second called, first time} {second called, second time} \
+ {first after update}]
+
+test chan-io-51.1 {Test old socket deletion on Macintosh} -setup {
+ set x 0
+ set result ""
+ variable wait ""
+} -constraints {socket} -body {
+ proc accept {s a p} {
+ variable x
+ chan configure $s -blocking off
+ chan puts $s "sock[incr x]"
+ chan close $s
+ variable wait done
+ }
+ set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [chan configure $ss -sockname] 2]
+ set cs [socket 127.0.0.1 $port]
+ vwait [namespace which -variable wait]
+ lappend result [chan gets $cs]
+ chan close $cs
+ set cs [socket 127.0.0.1 $port]
+ vwait [namespace which -variable wait]
+ lappend result [chan gets $cs]
+ chan close $cs
+ set cs [socket 127.0.0.1 $port]
+ vwait [namespace which -variable wait]
+ lappend result [chan gets $cs]
+ chan close $cs
+ set cs [socket 127.0.0.1 $port]
+ vwait [namespace which -variable wait]
+ lappend result [chan gets $cs]
+} -cleanup {
+ chan close $cs
+ chan close $ss
+} -result {sock1 sock2 sock3 sock4}
+
+test chan-io-52.1 {TclCopyChannel} -constraints {fcopy} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan copy $f1 $f2 -command " # "
+ chan copy $f1 $f2
+} -returnCodes error -cleanup {
+ chan close $f1
+ chan close $f2
+} -match glob -result {channel "*" is busy}
+test chan-io-52.2 {TclCopyChannel} -constraints {fcopy} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ set f3 [open $thisScript]
+ chan copy $f1 $f2 -command " # "
+ chan copy $f3 $f2
+} -returnCodes error -cleanup {
+ chan close $f1
+ chan close $f2
+ chan close $f3
+} -match glob -result {channel "*" is busy}
+test chan-io-52.3 {TclCopyChannel} -constraints {fcopy} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation cr -blocking 0
+ set s0 [chan copy $f1 $f2]
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ chan close $f1
+ chan close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {($s1 == $s2) && ($s0 == $s1)} {
+ lappend result ok
+ }
+ return $result
+} -result {0 0 ok}
+test chan-io-52.4 {TclCopyChannel} -constraints {fcopy} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation cr -blocking 0
+ chan copy $f1 $f2 -size 40
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ chan close $f1
+ chan close $f2
+ lappend result [file size $path(test1)]
+} -result {0 0 40}
+test chan-io-52.5 {TclCopyChannel, all} -constraints {fcopy} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation lf -blocking 0
+ chan copy $f1 $f2 -size -1 ;# -1 means 'copy all', same as if no -size specified.
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ chan close $f1
+ chan close $f2
+ if {[file size $thisScript] == [file size $path(test1)]} {
+ lappend result ok
+ }
+ return $result
+} -result {0 0 ok}
+test chan-io-52.5a {TclCopyChannel, all, other negative value} -setup {
+ file delete $path(test1)
+} -constraints {fcopy} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation lf -blocking 0
+ chan copy $f1 $f2 -size -2 ;# < 0 behaves like -1, copy all
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ chan close $f1
+ chan close $f2
+ if {[file size $thisScript] == [file size $path(test1)]} {
+ lappend result ok
+ }
+ return $result
+} -result {0 0 ok}
+test chan-io-52.5b {TclCopyChannel, all, wrap to negative value} -setup {
+ file delete $path(test1)
+} -constraints {fcopy} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation lf -blocking 0
+ chan copy $f1 $f2 -size 3221176172 ;# Wrapped to < 0, behaves like -1, copy all
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ chan close $f1
+ chan close $f2
+ if {[file size $thisScript] == [file size $path(test1)]} {
+ lappend result ok
+ }
+ return $result
+} -result {0 0 ok}
+test chan-io-52.6 {TclCopyChannel} -setup {
+ file delete $path(test1)
+} -constraints {fcopy} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation lf -blocking 0
+ set s0 [chan copy $f1 $f2 -size [expr [file size $thisScript] + 5]]
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ chan close $f1
+ chan close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {($s1 == $s2) && ($s0 == $s1)} {
+ lappend result ok
+ }
+ return $result
+} -result {0 0 ok}
+test chan-io-52.7 {TclCopyChannel} -constraints {fcopy} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation lf -blocking 0
+ chan copy $f1 $f2
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ if {[file size $thisScript] == [file size $path(test1)]} {
+ lappend result ok
+ }
+ return $result
+} -cleanup {
+ chan close $f1
+ chan close $f2
+} -result {0 0 ok}
+test chan-io-52.8 {TclCopyChannel} -setup {
+ file delete $path(test1)
+ file delete $path(pipe)
+} -constraints {stdio openpipe fcopy} -body {
+ set f1 [open $path(pipe) w]
+ chan configure $f1 -translation lf
+ chan puts $f1 "
+ chan puts ready
+ chan gets stdin
+ set f1 \[open [list $thisScript] r\]
+ chan configure \$f1 -translation lf
+ chan puts \[chan read \$f1 100\]
+ chan close \$f1
+ "
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ chan configure $f1 -translation lf
+ chan gets $f1
+ chan puts $f1 ready
+ chan flush $f1
+ set f2 [open $path(test1) w]
+ chan configure $f2 -translation lf
+ set s0 [chan copy $f1 $f2 -size 40]
+ catch {chan close $f1}
+ chan close $f2
+ list $s0 [file size $path(test1)]
+} -result {40 40}
+# Empty files, to register them with the test facility
+set path(kyrillic.txt) [makeFile {} kyrillic.txt]
+set path(utf8-fcopy.txt) [makeFile {} utf8-fcopy.txt]
+set path(utf8-rp.txt) [makeFile {} utf8-rp.txt]
+# Create kyrillic file, use lf translation to avoid os eol issues
+set out [open $path(kyrillic.txt) w]
+chan configure $out -encoding koi8-r -translation lf
+chan puts $out "\u0410\u0410"
+chan close $out
+test chan-io-52.9 {TclCopyChannel & encodings} {fcopy} {
+ # Copy kyrillic to UTF-8, using chan copy.
+ set in [open $path(kyrillic.txt) r]
+ set out [open $path(utf8-fcopy.txt) w]
+ chan configure $in -encoding koi8-r -translation lf
+ chan configure $out -encoding utf-8 -translation lf
+ chan copy $in $out
+ chan close $in
+ chan close $out
+ # Do the same again, but differently (read/chan puts).
+ set in [open $path(kyrillic.txt) r]
+ set out [open $path(utf8-rp.txt) w]
+ chan configure $in -encoding koi8-r -translation lf
+ chan configure $out -encoding utf-8 -translation lf
+ chan puts -nonewline $out [chan read $in]
+ chan close $in
+ chan close $out
+ list [file size $path(kyrillic.txt)] \
+ [file size $path(utf8-fcopy.txt)] \
+ [file size $path(utf8-rp.txt)]
+} {3 5 5}
+test chan-io-52.10 {TclCopyChannel & encodings} {fcopy} {
+ # encoding to binary (=> implies that the internal utf-8 is written)
+ set in [open $path(kyrillic.txt) r]
+ set out [open $path(utf8-fcopy.txt) w]
+ chan configure $in -encoding koi8-r -translation lf
+ # -translation binary is also -encoding binary
+ chan configure $out -translation binary
+ chan copy $in $out
+ chan close $in
+ chan close $out
+ file size $path(utf8-fcopy.txt)
+} 5
+test chan-io-52.11 {TclCopyChannel & encodings} {fcopy} {
+ # binary to encoding => the input has to be in utf-8 to make sense to the
+ # encoder
+ set in [open $path(utf8-fcopy.txt) r]
+ set out [open $path(kyrillic.txt) w]
+ # -translation binary is also -encoding binary
+ chan configure $in -translation binary
+ chan configure $out -encoding koi8-r -translation lf
+ chan copy $in $out
+ chan close $in
+ chan close $out
+ file size $path(kyrillic.txt)
+} 3
+
+test chan-io-53.1 {CopyData} -setup {
+ file delete $path(test1)
+} -constraints {fcopy} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation cr -blocking 0
+ chan copy $f1 $f2 -size 0
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ chan close $f1
+ chan close $f2
+ lappend result [file size $path(test1)]
+} -result {0 0 0}
+test chan-io-53.2 {CopyData} -setup {
+ file delete $path(test1)
+} -constraints {fcopy} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation cr -blocking 0
+ chan copy $f1 $f2 -command [namespace code {set s0}]
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ variable s0
+ vwait [namespace which -variable s0]
+ chan close $f1
+ chan close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {($s1 == $s2) && ($s0 == $s1)} {
+ lappend result ok
+ }
+ return $result
+} -result {0 0 ok}
+test chan-io-53.3 {CopyData: background read underflow} -setup {
+ file delete $path(test1)
+ file delete $path(pipe)
+} -constraints {stdio unix openpipe fcopy} -body {
+ set f1 [open $path(pipe) w]
+ chan puts -nonewline $f1 {
+ chan puts ready
+ chan flush stdout ;# Don't assume line buffered!
+ chan copy stdin stdout -command { set x }
+ vwait x
+ set f [}
+ chan puts $f1 [list open $path(test1) w]]
+ chan puts $f1 {
+ chan configure $f -translation lf
+ chan puts $f "done"
+ chan close $f
+ }
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ set result [chan gets $f1]
+ chan puts $f1 line1
+ chan flush $f1
+ lappend result [chan gets $f1]
+ chan puts $f1 line2
+ chan flush $f1
+ lappend result [chan gets $f1]
+ chan close $f1
+ after 500
+ set f [open $path(test1)]
+ lappend result [chan read $f]
+} -cleanup {
+ chan close $f
+} -result "ready line1 line2 {done\n}"
+test chan-io-53.4 {CopyData: background write overflow} -setup {
+ set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n
+ variable x
+ for {set x 0} {$x < 12} {incr x} {
+ append big $big
+ }
+ file delete $path(test1)
+ file delete $path(pipe)
+} -constraints {stdio unix openpipe fileevent fcopy} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {
+ chan puts ready
+ chan copy stdin stdout -command { set x }
+ vwait x
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f "done"
+ chan close $f
+ }
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ set result [chan gets $f1]
+ chan configure $f1 -blocking 0
+ chan puts $f1 $big
+ chan flush $f1
+ after 500
+ set result ""
+ chan event $f1 read [namespace code {
+ append result [chan read $f1 1024]
+ if {[string length $result] >= [string length $big]} {
+ set x done
+ }
+ }]
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ set big {}
+ chan close $f1
+} -result done
+set result {}
+proc FcopyTestAccept {sock args} {
+ after 1000 "chan close $sock"
+}
+proc FcopyTestDone {bytes {error {}}} {
+ variable fcopyTestDone
+ if {[string length $error]} {
+ set fcopyTestDone 1
+ } else {
+ set fcopyTestDone 0
+ }
+}
+test chan-io-53.5 {CopyData: error during chan copy} {socket fcopy} {
+ variable fcopyTestDone
+ set listen [socket -server [namespace code FcopyTestAccept] -myaddr 127.0.0.1 0]
+ set in [open $thisScript] ;# 126 K
+ set out [socket 127.0.0.1 [lindex [chan configure $listen -sockname] 2]]
+ catch {unset fcopyTestDone}
+ chan close $listen ;# This means the socket open never really succeeds
+ chan copy $in $out -command [namespace code FcopyTestDone]
+ variable fcopyTestDone
+ if ![info exists fcopyTestDone] {
+ vwait [namespace which -variable fcopyTestDone] ;# The error occurs here in the b.g.
+ }
+ chan close $in
+ chan close $out
+ set fcopyTestDone ;# 1 for error condition
+} 1
+test chan-io-53.6 {CopyData: error during chan copy} -setup {
+ variable fcopyTestDone
+ file delete $path(pipe)
+ file delete $path(test1)
+ catch {unset fcopyTestDone}
+} -constraints {stdio openpipe fcopy} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 "exit 1"
+ chan close $f1
+ set in [openpipe r+ $path(pipe)]
+ set out [open $path(test1) w]
+ chan copy $in $out -command [namespace code FcopyTestDone]
+ variable fcopyTestDone
+ if ![info exists fcopyTestDone] {
+ vwait [namespace which -variable fcopyTestDone]
+ }
+ return $fcopyTestDone ;# 0 for plain end of file
+} -cleanup {
+ catch {chan close $in}
+ chan close $out
+} -result 0
+proc doFcopy {in out {bytes 0} {error {}}} {
+ variable fcopyTestDone
+ variable fcopyTestCount
+ incr fcopyTestCount $bytes
+ if {[string length $error]} {
+ set fcopyTestDone 1
+ } elseif {[chan eof $in]} {
+ set fcopyTestDone 0
+ } else {
+ # Delay next chan copy to wait for size>0 input bytes
+ after 100 [list chan copy $in $out -size 1000 \
+ -command [namespace code [list doFcopy $in $out]]]
+ }
+}
+test chan-io-53.7 {CopyData: Flooding chan copy from pipe} -setup {
+ variable fcopyTestDone
+ file delete $path(pipe)
+ catch {unset fcopyTestDone}
+} -constraints {stdio openpipe fcopy} -body {
+ set fcopyTestCount 0
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {
+ # Write 10 bytes / 10 msec
+ proc Write {count} {
+ chan puts -nonewline "1234567890"
+ if {[incr count -1]} {
+ after 10 [list Write $count]
+ } else {
+ set ::ready 1
+ }
+ }
+ chan configure stdout -buffering none
+ Write 345 ;# 3450 bytes ~3.45 sec
+ vwait ready
+ exit 0
+ }
+ chan close $f1
+ set in [openpipe r+ $path(pipe) &]
+ set out [open $path(test1) w]
+ doFcopy $in $out
+ variable fcopyTestDone
+ if {![info exists fcopyTestDone]} {
+ vwait [namespace which -variable fcopyTestDone]
+ }
+ # -1=error 0=script error N=number of bytes
+ expr ($fcopyTestDone == 0) ? $fcopyTestCount : -1
+} -cleanup {
+ catch {chan close $in}
+ chan close $out
+} -result {3450}
+test chan-io-53.8 {CopyData: async callback and error handling, Bug 1932639} -setup {
+ # copy progress callback. errors out intentionally
+ proc cmd args {
+ lappend ::RES "CMD $args"
+ error !STOP
+ }
+ # capture callback error here
+ proc ::bgerror args {
+ lappend ::RES "bgerror/OK $args"
+ set ::forever has-been-reached
+ return
+ }
+ # Files we use for our channels
+ set foo [makeFile ashgdfashdgfasdhgfasdhgf foo]
+ set bar [makeFile {} bar]
+ # Channels to copy between
+ set f [open $foo r] ; fconfigure $f -translation binary
+ set g [open $bar w] ; fconfigure $g -translation binary -buffering none
+} -constraints {stdio openpipe fcopy} -body {
+ # Record input size, so that result is always defined
+ lappend ::RES [file size $bar]
+ # Run the copy. Should not invoke -command now.
+ chan copy $f $g -size 2 -command [namespace code cmd]
+ # Check that -command was not called synchronously
+ set sbs [file size $bar]
+ lappend ::RES [expr {($sbs > 0) ? "sync/FAIL" : "sync/OK"}] $sbs
+ # Now let the async part happen. Should capture the error in cmd via
+ # bgerror. If not break the event loop via timer.
+ set token [after 1000 {
+ lappend ::RES {bgerror/FAIL timeout}
+ set ::forever has-been-reached
+ }]
+ vwait ::forever
+ catch {after cancel $token}
+ # Report
+ return $::RES
+} -cleanup {
+ chan close $f
+ chan close $g
+ catch {unset ::RES}
+ catch {unset ::forever}
+ rename ::bgerror {}
+ removeFile foo
+ removeFile bar
+} -result {0 sync/OK 0 {CMD 2} {bgerror/OK !STOP}}
+test chan-io-53.8a {CopyData: async callback and error handling, Bug 1932639, at eof} -setup {
+ # copy progress callback.
+ proc cmd args {
+ lappend ::RES "CMD $args"
+ set ::forever has-been-reached
+ return
+ }
+ # Files we use for our channels
+ set foo [makeFile ashgdfashdgfasdhgfasdhgf foo]
+ set bar [makeFile {} bar]
+ # Channels to copy between
+ set f [open $foo r] ; chan configure $f -translation binary
+ set g [open $bar w] ; chan configure $g -translation binary -buffering none
+} -constraints {stdio openpipe fcopy} -body {
+ # Initialize and force eof on the input.
+ chan seek $f 0 end ; chan read $f 1
+ set ::RES [chan eof $f]
+ # Run the copy. Should not invoke -command now.
+ chan copy $f $g -size 2 -command [namespace code cmd]
+ # Check that -command was not called synchronously
+ lappend ::RES [expr {([llength $::RES] > 1) ? "sync/FAIL" : "sync/OK"}]
+ # Now let the async part happen. Should capture the eof in cmd
+ # If not break the event loop via timer.
+ set token [after 1000 {
+ lappend ::RES {cmd/FAIL timeout}
+ set ::forever has-been-reached
+ }]
+ vwait ::forever
+ catch {after cancel $token}
+ # Report
+ return $::RES
+} -cleanup {
+ chan close $f
+ chan close $g
+ catch {unset ::RES}
+ catch {unset ::forever}
+ removeFile foo
+ removeFile bar
+} -result {1 sync/OK {CMD 0}}
+test chan-io-53.9 {CopyData: -size and event interaction, Bug 780533} -setup {
+ set out [makeFile {} out]
+ set err [makeFile {} err]
+ set pipe [open "|[list [info nameofexecutable] 2> $err]" r+]
+ chan configure $pipe -translation binary -buffering line
+ chan puts $pipe {
+ chan configure stdout -translation binary -buffering line
+ chan puts stderr Waiting...
+ after 1000
+ foreach x {a b c} {
+ chan puts stderr Looping...
+ chan puts $x
+ after 500
+ }
+ proc bye args {
+ if {[chan gets stdin line]<0} {
+ chan puts stderr "CHILD: EOF detected, exiting"
+ exit
+ } else {
+ chan puts stderr "CHILD: ignoring line: $line"
+ }
+ }
+ chan puts stderr Now-sleeping-forever
+ chan event stdin readable bye
+ vwait forever
+ }
+ proc ::done args {
+ set ::forever OK
+ return
+ }
+ set ::forever {}
+ set out [open $out w]
+} -constraints {stdio openpipe fcopy} -body {
+ chan copy $pipe $out -size 6 -command ::done
+ set token [after 5000 {
+ set ::forever {fcopy hangs}
+ }]
+ vwait ::forever
+ catch {after cancel $token}
+ set ::forever
+} -cleanup {
+ chan close $pipe
+ rename ::done {}
+ if {[testConstraint win]} {
+ after 1000; # Allow Windows time to figure out that the
+ # process is gone
+ }
+ catch {close $out}
+ catch {removeFile out}
+ catch {removeFile err}
+ catch {unset ::forever}
+} -result OK
+test chan-io-53.10 {Bug 1350564, multi-directional fcopy} -setup {
+ set err [makeFile {} err]
+ set pipe [open "|[list [info nameofexecutable] 2> $err]" r+]
+ chan configure $pipe -translation binary -buffering line
+ chan puts $pipe {
+ chan configure stderr -buffering line
+ # Kill server when pipe closed by invoker.
+ proc bye args {
+ if {![chan eof stdin]} { chan gets stdin ; return }
+ chan puts stderr BYE
+ exit
+ }
+ # Server code. Bi-directional copy between 2 sockets.
+ proc geof {sok} {
+ chan puts stderr DONE/$sok
+ chan close $sok
+ }
+ proc new {sok args} {
+ chan puts stderr NEW/$sok
+ global l srv
+ chan configure $sok -translation binary -buffering none
+ lappend l $sok
+ if {[llength $l] == 2} {
+ chan close $srv
+ foreach {a b} $l break
+ chan copy $a $b -command [list geof $a]
+ chan copy $b $a -command [list geof $b]
+ chan puts stderr 2COPY
+ }
+ chan puts stderr ...
+ }
+ chan puts stderr SRV
+ set l {}
+ set srv [socket -server new 9999]
+ chan puts stderr WAITING
+ chan event stdin readable bye
+ chan puts OK
+ vwait forever
+ }
+ # wait for OK from server.
+ chan gets $pipe
+ # Now the two clients.
+ proc done {sock} {
+ if {[chan eof $sock]} { chan close $sock ; return }
+ lappend ::forever [chan gets $sock]
+ return
+ }
+ set a [socket 127.0.0.1 9999]
+ set b [socket 127.0.0.1 9999]
+ chan configure $a -translation binary -buffering none
+ chan configure $b -translation binary -buffering none
+ chan event $a readable [namespace code "done $a"]
+ chan event $b readable [namespace code "done $b"]
+} -constraints {stdio openpipe fcopy} -body {
+ # Now pass data through the server in both directions.
+ set ::forever {}
+ chan puts $a AB
+ vwait ::forever
+ chan puts $b BA
+ vwait ::forever
+ set ::forever
+} -cleanup {
+ catch {chan close $a}
+ catch {chan close $b}
+ chan close $pipe
+ if {[testConstraint win]} {
+ after 1000 ;# Give Windows time to kill the process
+ }
+ removeFile err
+ catch {unset ::forever}
+} -result {AB BA}
+
+test chan-io-54.1 {Recursive channel events} {socket fileevent} {
+ # This test checks to see if file events are delivered during recursive
+ # event loops when there is buffered data on the channel.
+ proc accept {s a p} {
+ variable as
+ chan configure $s -translation lf
+ chan puts $s "line 1\nline2\nline3"
+ chan flush $s
+ set as $s
+ }
+ proc readit {s next} {
+ variable x
+ variable result
+ lappend result $next
+ if {$next == 1} {
+ chan event $s readable [namespace code [list readit $s 2]]
+ vwait [namespace which -variable x]
+ }
+ incr x
+ }
+ set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ # We need to delay on some systems until the creation of the server socket
+ # completes.
+ set done 0
+ for {set i 0} {$i < 10} {incr i} {
+ if {![catch {
+ set cs [socket 127.0.0.1 [lindex [chan configure $ss -sockname] 2]]
+ }]} then {
+ set done 1
+ break
+ }
+ after 100
+ }
+ if {$done == 0} {
+ chan close $ss
+ error "failed to connect to server"
+ }
+ variable result {}
+ variable x 0
+ variable as
+ vwait [namespace which -variable as]
+ chan configure $cs -translation lf
+ lappend result [chan gets $cs]
+ chan configure $cs -blocking off
+ chan event $cs readable [namespace code [list readit $cs 1]]
+ set a [after 2000 [namespace code { set x failure }]]
+ vwait [namespace which -variable x]
+ after cancel $a
+ chan close $as
+ chan close $ss
+ chan close $cs
+ list $result $x
+} {{{line 1} 1 2} 2}
+test chan-io-54.2 {Testing for busy-wait in recursive channel events} -setup {
+ set accept {}
+ set after {}
+ variable done 0
+} -constraints {socket fileevent} -body {
+ variable s [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ proc accept {s a p} {
+ variable counter 0
+ variable accept $s
+ chan configure $s -blocking off -buffering line -translation lf
+ chan event $s readable [namespace code "doit $s"]
+ }
+ proc doit {s} {
+ variable counter
+ variable after
+ incr counter
+ if {[chan gets $s] eq ""} {
+ chan event $s readable [namespace code "doit1 $s"]
+ set after [after 1000 [namespace code {
+ chan puts $writer hello
+ chan flush $writer
+ set done 1
+ }]]
+ }
+ }
+ proc doit1 {s} {
+ variable counter
+ variable accept
+ incr counter
+ chan gets $s
+ chan close $s
+ set accept {}
+ }
+ proc producer {} {
+ variable s
+ variable writer
+ set writer [socket 127.0.0.1 [lindex [chan configure $s -sockname] 2]]
+ chan configure $writer -buffering line
+ chan puts -nonewline $writer hello
+ chan flush $writer
+ }
+ producer
+ vwait [namespace which -variable done]
+ chan close $writer
+ chan close $s
+ after cancel $after
+ return $counter
+} -cleanup {
+ if {$accept ne {}} {chan close $accept}
+} -result 1
+
+set path(fooBar) [makeFile {} fooBar]
+
+test chan-io-55.1 {ChannelEventScriptInvoker: deletion} -constraints {
+ fileevent
+} -setup {
+ variable x
+ proc eventScript {fd} {
+ variable x
+ chan close $fd
+ error "planned error"
+ set x whoops
+ }
+ proc myHandler args {
+ variable x got_error
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+} -body {
+ set f [open $path(fooBar) w]
+ chan event $f writable [namespace code [list eventScript $f]]
+ variable x not_done
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ interp bgerror {} $handler
+} -result {got_error}
+
+test chan-io-56.1 {ChannelTimerProc} {testchannelevent} {
+ set f [open $path(fooBar) w]
+ chan puts $f "this is a test"
+ chan close $f
+ set f [open $path(fooBar) r]
+ testchannelevent $f add readable [namespace code {
+ chan read $f 1
+ incr x
+ }]
+ variable x 0
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ set result $x
+ testchannelevent $f set 0 none
+ after idle [namespace code {set y done}]
+ variable y
+ vwait [namespace which -variable y]
+ chan close $f
+ lappend result $y
+} {2 done}
+
+test chan-io-57.1 {buffered data and file events, gets} -setup {
+ variable s2
+} -constraints {fileevent} -body {
+ proc accept {sock args} {
+ variable s2
+ set s2 $sock
+ }
+ set server [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set s [socket 127.0.0.1 [lindex [chan configure $server -sockname] 2]]
+ vwait [namespace which -variable s2]
+ update
+ chan event $s2 readable [namespace code {lappend result readable}]
+ chan puts $s "12\n34567890"
+ chan flush $s
+ variable result [chan gets $s2]
+ after 1000 [namespace code {lappend result timer}]
+ vwait [namespace which -variable result]
+ lappend result [chan gets $s2]
+ vwait [namespace which -variable result]
+ return $result
+} -cleanup {
+ chan close $s
+ chan close $s2
+ chan close $server
+} -result {12 readable 34567890 timer}
+test chan-io-57.2 {buffered data and file events, read} -setup {
+ variable s2
+} -constraints {fileevent} -body {
+ proc accept {sock args} {
+ variable s2
+ set s2 $sock
+ }
+ set server [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set s [socket 127.0.0.1 [lindex [chan configure $server -sockname] 2]]
+ vwait [namespace which -variable s2]
+ update
+ chan event $s2 readable [namespace code {lappend result readable}]
+ chan puts -nonewline $s "1234567890"
+ chan flush $s
+ variable result [chan read $s2 1]
+ after 1000 [namespace code {lappend result timer}]
+ vwait [namespace which -variable result]
+ lappend result [chan read $s2 9]
+ vwait [namespace which -variable result]
+ return $result
+} -cleanup {
+ chan close $s
+ chan close $s2
+ chan close $server
+} -result {1 readable 234567890 timer}
+
+test chan-io-58.1 {Tcl_NotifyChannel and error when closing} {stdio unixOrPc openpipe fileevent} {
+ set out [open $path(script) w]
+ chan puts $out {
+ chan puts "normal message from pipe"
+ chan puts stderr "error message from pipe"
+ exit 1
+ }
+ proc readit {pipe} {
+ variable x
+ variable result
+ if {[chan eof $pipe]} {
+ set x [catch {chan close $pipe} line]
+ lappend result catch $line
+ } else {
+ chan gets $pipe line
+ lappend result chan gets $line
+ }
+ }
+ chan close $out
+ set pipe [openpipe r $path(script)]
+ chan event $pipe readable [namespace code [list readit $pipe]]
+ variable x ""
+ set result ""
+ vwait [namespace which -variable x]
+ list $x $result
+} {1 {chan gets {normal message from pipe} chan gets {} catch {error message from pipe}}}
+
+test chan-io-59.1 {Thread reference of channels} {testmainthread testchannel} {
+ # TIP #10
+ # More complicated tests (like that the reference changes as a channel is
+ # moved from thread to thread) can be done only in the extension which
+ # fully implements the moving of channels between threads, i.e. 'Threads'.
+ set f [open $path(longfile) r]
+ set result [testchannel mthread $f]
+ chan close $f
+ string equal $result [testmainthread]
+} {1}
+
+test chan-io-60.1 {writing illegal utf sequences} {openpipe fileevent} {
+ # This test will hang in older revisions of the core.
+ set out [open $path(script) w]
+ chan puts $out {
+ chan puts [encoding convertfrom identity \xe2]
+ exit 1
+ }
+ proc readit {pipe} {
+ variable x
+ variable result
+ if {[chan eof $pipe]} {
+ set x [catch {chan close $pipe} line]
+ lappend result catch $line
+ } else {
+ chan gets $pipe line
+ lappend result gets $line
+ }
+ }
+ chan close $out
+ set pipe [openpipe r $path(script)]
+ chan event $pipe readable [namespace code [list readit $pipe]]
+ variable x ""
+ set result ""
+ vwait [namespace which -variable x]
+ # cut of the remainder of the error stack, especially the filename
+ set result [lreplace $result 3 3 [lindex [split [lindex $result 3] \n] 0]]
+ list $x $result
+} {1 {gets {} catch {error writing "stdout": invalid argument}}}
+
+test chan-io-61.1 {Reset eof state after changing the eof char} -setup {
+ set datafile [makeFile {} eofchar]
+ set f [open $datafile w]
+ chan configure $f -translation binary
+ chan puts -nonewline $f [string repeat "Ho hum\n" 11]
+ chan puts $f =
+ set line [string repeat "Ge gla " 4]
+ chan puts -nonewline $f [string repeat [string trimright $line]\n 834]
+ chan close $f
+} -body {
+ set f [open $datafile r]
+ chan configure $f -eofchar =
+ set res {}
+ lappend res [chan read $f; chan tell $f]
+ chan configure $f -eofchar {}
+ lappend res [chan read $f 1]
+ lappend res [chan read $f; chan tell $f]
+ # Any seek zaps the internals into a good state.
+ #chan seek $f 0 start
+ #chan seek $f 0 current
+ #lappend res [chan read $f; chan tell $f]
+} -cleanup {
+ chan close $f
+ removeFile eofchar
+} -result {77 = 23431}
+
+# Test the cutting and splicing of channels, this is incidentially the
+# attach/detach facility of package Thread, but __without any safeguards__. It
+# can also be used to emulate transfer of channels between threads, and is
+# used for that here.
+
+test chan-io-70.0 {Cutting & Splicing channels} -setup {
+ set f [makeFile {... dummy ...} cutsplice]
+ set res {}
+} -constraints {testchannel} -body {
+ set c [open $f r]
+ lappend res [catch {chan seek $c 0 start}]
+ testchannel cut $c
+ lappend res [catch {chan seek $c 0 start}]
+ testchannel splice $c
+ lappend res [catch {chan seek $c 0 start}]
+} -cleanup {
+ chan close $c
+ removeFile cutsplice
+} -result {0 1 0}
+
+test chan-io-70.1 {Transfer channel} -setup {
+ set f [makeFile {... dummy ...} cutsplice]
+ set res {}
+} -constraints {testchannel thread} -body {
+ set c [open $f r]
+ lappend res [catch {chan seek $c 0 start}]
+ testchannel cut $c
+ lappend res [catch {chan seek $c 0 start}]
+ set tid [thread::create -preserved]
+ thread::send $tid [list set c $c]
+ thread::send $tid {load {} Tcltest}
+ lappend res [thread::send $tid {
+ testchannel splice $c
+ set res [catch {chan seek $c 0 start}]
+ chan close $c
+ set res
+ }]
+} -cleanup {
+ thread::release $tid
+ removeFile cutsplice
+} -result {0 1 0}
+
+# ### ### ### ######### ######### #########
+
+foreach {n msg expected} {
+ 0 {} {}
+ 1 {{message only}} {{message only}}
+ 2 {-options x} {-options x}
+ 3 {-options {x y} {the message}} {-options {x y} {the message}}
+
+ 4 {-code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 5 {-code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 6 {-code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 7 {-code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 8 {-code error -level 0 -f ba snarf} {-code error -level 0 -f ba snarf}
+ 9 {-code ok -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 10 {-code error -level 5 -f ba snarf} {-code error -level 0 -f ba snarf}
+ 11 {-code ok -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 12 {-code boss -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 13 {-code boss -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 14 {-code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 15 {-code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 16 {-code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 17 {-code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 18 {-code error -level 0 -f ba} {-code error -level 0 -f ba}
+ 19 {-code ok -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 20 {-code error -level 5 -f ba} {-code error -level 0 -f ba}
+ 21 {-code ok -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 22 {-code boss -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 23 {-code boss -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 24 {-code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 25 {-code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 26 {-code error -level X -f ba snarf} {-code error -level 0 -f ba snarf}
+ 27 {-code ok -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 28 {-code boss -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 29 {-code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+ 30 {-code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ 31 {-code error -level X -f ba} {-code error -level 0 -f ba}
+ 32 {-code ok -level X -f ba} {-code 1 -level 0 -f ba}
+ 33 {-code boss -level X -f ba} {-code 1 -level 0 -f ba}
+
+ 34 {-code 1 -code 1 -level 0 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 35 {-code 1 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 36 {-code 1 -code 1 -level 5 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 37 {-code 1 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 38 {-code 1 -code error -level 0 -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+ 39 {-code 1 -code ok -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 40 {-code 1 -code error -level 5 -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+ 41 {-code 1 -code ok -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 42 {-code 1 -code boss -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 43 {-code 1 -code boss -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 44 {-code 1 -code 1 -level 0 -f ba} {-code 1 -code 1 -level 0 -f ba}
+ 45 {-code 1 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 46 {-code 1 -code 1 -level 5 -f ba} {-code 1 -code 1 -level 0 -f ba}
+ 47 {-code 1 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 48 {-code 1 -code error -level 0 -f ba} {-code 1 -code error -level 0 -f ba}
+ 49 {-code 1 -code ok -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 50 {-code 1 -code error -level 5 -f ba} {-code 1 -code error -level 0 -f ba}
+ 51 {-code 1 -code ok -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 52 {-code 1 -code boss -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 53 {-code 1 -code boss -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 54 {-code 1 -code 1 -level X -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 55 {-code 1 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 56 {-code 1 -code error -level X -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+ 57 {-code 1 -code ok -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 58 {-code 1 -code boss -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 59 {-code 1 -code 1 -level X -f ba} {-code 1 -code 1 -level 0 -f ba}
+ 60 {-code 1 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ 61 {-code 1 -code error -level X -f ba} {-code 1 -code error -level 0 -f ba}
+ 62 {-code 1 -code ok -level X -f ba} {-code 1 -level 0 -f ba}
+ 63 {-code 1 -code boss -level X -f ba} {-code 1 -level 0 -f ba}
+
+ 64 {-code 0 -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 65 {-code 0 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 66 {-code 0 -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 67 {-code 0 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 68 {-code 0 -code error -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 69 {-code 0 -code ok -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 70 {-code 0 -code error -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 71 {-code 0 -code ok -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 72 {-code 0 -code boss -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 73 {-code 0 -code boss -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 74 {-code 0 -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 75 {-code 0 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 76 {-code 0 -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 77 {-code 0 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 78 {-code 0 -code error -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 79 {-code 0 -code ok -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 80 {-code 0 -code error -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 81 {-code 0 -code ok -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 82 {-code 0 -code boss -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 83 {-code 0 -code boss -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 84 {-code 0 -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 85 {-code 0 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 86 {-code 0 -code error -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 87 {-code 0 -code ok -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 88 {-code 0 -code boss -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 89 {-code 0 -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+ 90 {-code 0 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ 91 {-code 0 -code error -level X -f ba} {-code 1 -level 0 -f ba}
+ 92 {-code 0 -code ok -level X -f ba} {-code 1 -level 0 -f ba}
+ 93 {-code 0 -code boss -level X -f ba} {-code 1 -level 0 -f ba}
+
+ 94 {-code 1 -code 1 -level 0 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 95 {-code 0 -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 96 {-code 1 -code 1 -level 5 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 97 {-code 0 -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 98 {-code error -code 1 -level 0 -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+ 99 {-code ok -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ a0 {-code error -code 1 -level 5 -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+ a1 {-code ok -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ a2 {-code boss -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ a3 {-code boss -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ a4 {-code 1 -code 1 -level 0 -f ba} {-code 1 -code 1 -level 0 -f ba}
+ a5 {-code 0 -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ a6 {-code 1 -code 1 -level 5 -f ba} {-code 1 -code 1 -level 0 -f ba}
+ a7 {-code 0 -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ a8 {-code error -code 1 -level 0 -f ba} {-code error -code 1 -level 0 -f ba}
+ a9 {-code ok -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ b0 {-code error -code 1 -level 5 -f ba} {-code error -code 1 -level 0 -f ba}
+ b1 {-code ok -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ b2 {-code boss -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ b3 {-code boss -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ b4 {-code 1 -code 1 -level X -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ b5 {-code 0 -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ b6 {-code error -code 1 -level X -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+ b7 {-code ok -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ b8 {-code boss -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ b9 {-code 1 -code 1 -level X -f ba} {-code 1 -code 1 -level 0 -f ba}
+ c0 {-code 0 -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+ c1 {-code error -code 1 -level X -f ba} {-code error -code 1 -level 0 -f ba}
+ c2 {-code ok -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+ c3 {-code boss -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+
+ c4 {-code 1 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c5 {-code 0 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c6 {-code 1 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c7 {-code 0 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c8 {-code error -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c9 {-code ok -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d0 {-code error -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d1 {-code ok -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d2 {-code boss -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d3 {-code boss -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d4 {-code 1 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ d5 {-code 0 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ d6 {-code 1 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ d7 {-code 0 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ d8 {-code error -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ d9 {-code ok -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ e0 {-code error -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ e1 {-code ok -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ e2 {-code boss -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ e3 {-code boss -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ e4 {-code 1 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e5 {-code 0 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e6 {-code error -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e7 {-code ok -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e8 {-code boss -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e9 {-code 1 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ f0 {-code 0 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ f1 {-code error -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ f2 {-code ok -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ f3 {-code boss -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+} {
+ test chan-io-71.$n {Tcl_SetChannelError} -setup {
+ set f [makeFile {... dummy ...} cutsplice]
+ } -constraints {testchannel} -body {
+ set c [open $f r]
+ testchannel setchannelerror $c [lrange $msg 0 end]
+ } -cleanup {
+ chan close $c
+ removeFile cutsplice
+ } -result [lrange $expected 0 end]
+ test chan-io-72.$n {Tcl_SetChannelErrorInterp} -setup {
+ set f [makeFile {... dummy ...} cutsplice]
+ } -constraints {testchannel} -body {
+ set c [open $f r]
+ testchannel setchannelerrorinterp $c [lrange $msg 0 end]
+ } -cleanup {
+ chan close $c
+ removeFile cutsplice
+ } -result [lrange $expected 0 end]
+}
+
+test chan-io-73.1 {channel Tcl_Obj SetChannelFromAny} -body {
+ # Test for Bug 1847044 - don't spoil type unless we have a valid channel
+ chan close [lreplace [list a] 0 end]
+} -returnCodes error -match glob -result *
+
+# ### ### ### ######### ######### #########
+
+# cleanup
+foreach file [list fooBar longfile script output test1 pipe my_script \
+ test2 test3 cat kyrillic.txt utf8-fcopy.txt utf8-rp.txt] {
+ removeFile $file
+}
+cleanupTests
+}
+namespace delete ::tcl::test::io
diff --git a/library/msgcat/tests/clock.test b/library/msgcat/tests/clock.test
new file mode 100644
index 0000000..fd74512
--- /dev/null
+++ b/library/msgcat/tests/clock.test
@@ -0,0 +1,36941 @@
+# clock.test --
+#
+# This test file covers the 'clock' command that manipulates time.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+if {[testConstraint win]} {
+ if {[catch {package require registry 1.1}]
+ && [catch {load {} Registry}]
+ && [catch {
+ ::tcltest::loadTestedCommands
+ load $::reglib Registry
+ }]} {
+ namespace eval ::tcl::clock {variable NoRegistry {}}
+ }
+}
+
+package require msgcat 1.4
+
+testConstraint detroit \
+ [expr {![catch {clock format 0 -timezone :America/Detroit -format %z}]}]
+testConstraint y2038 \
+ [expr {[clock format 2158894800 -format %z -timezone :America/Detroit] eq {-0400}}]
+
+# TEST PLAN
+
+# clock-1:
+# [clock format] - tests of bad and empty arguments
+#
+# clock-2
+# formatting of year, month and day of month
+#
+# clock-3
+# formatting of fiscal year, fiscal week and day of week.
+#
+# clock-4
+# formatting of time of day.
+#
+# clock-5
+# handling of Daylight Saving Time in a known locale, formatting of
+# %z and %Z
+#
+# clock-6
+# input conversion - seconds
+#
+# clock-7
+# input conversion - Julian Day
+#
+# clock-8
+# input conversion - ccyymmdd
+#
+# clock-9
+# input conversion - ccyymmdd (test that %s and %J take precedence)
+#
+# clock-10
+# input conversion - ccyyddd
+#
+# clock-11
+# input conversion - relative precedence of ccyyddd and ccyymmdd
+# (tests the 'rightmost field' comparison)
+#
+# clock-12
+# input conversion - ccyyWwwd
+#
+# clock-13
+# input conversion - ccyyWwwd (test that %s and %J take precedence,
+# and that invalid days are rejected).
+#
+# clock-14
+# input conversion - yymmdd
+#
+# clock-15
+# precedence - yymmdd
+#
+# clock-16
+# input conversion and precedence - yyddd
+#
+# clock-17
+# input conversion - yyWwwd
+#
+# clock-18
+# precedence - yyWwwd
+#
+# clock-19
+# input conversion - mmdd
+#
+# clock-20
+# precedence - mmdd
+#
+# clock-21
+# input conversion and precedence - ddd
+#
+# clock-22
+# input conversion - Wwwd
+#
+# clock-23
+# precedence - Wwwd
+#
+# clock-24
+# input conversion - naked day of month
+#
+# clock-25
+# precedence - naked day of month
+#
+# clock-26
+# input conversion - naked day of week
+#
+# clock-27
+# precedence - day of week
+#
+# clock-28
+# scan with empty -format is midnight of base date
+#
+# clock-29
+# scanning of all time-of-day formats
+#
+# clock-30
+# [clock add]
+#
+# clock-31
+# Use of -locale system on Windows
+#
+# clock-32
+# Handling of the Julian-Gregorian transition
+#
+# clock-33
+# Legacy tests - [clock clicks]
+#
+# clock-34
+# Legacy tests - [clock scan] without -format
+#
+# clock-35
+# Legacy tests - [clock seconds]
+#
+# clock-36
+# Legacy tests - [clock scan] with 'next monthname'
+#
+# clock-37
+# Test that -gmt does not affect the value of %s
+#
+# clock-38
+# Regression test to verify that changes in TZ work
+# both east and west of Greenwich
+
+
+# Note that all code between comments '# BEGIN' and '# END' is
+# autogenerated by 'tools/makeTestCases.tcl'. DO NOT EDIT CODE BETWEEN
+# '# BEGIN' and '# END'.
+
+# Define a fictitious locale, 'en_US_roman', for formatting of clock
+# strings with localized numerics and eras. This locale will be used
+# in testing the 'clock' command.
+
+namespace eval ::tcl::clock {
+ ::msgcat::mcmset en_US_roman {
+ LOCALE_ERAS {
+ {-62164627200 {} 0}
+ {-59008867200 c 100}
+ {-55853107200 cc 200}
+ {-52697347200 ccc 300}
+ {-49541587200 cd 400}
+ {-46385827200 d 500}
+ {-43230067200 dc 600}
+ {-40074307200 dcc 700}
+ {-36918547200 dccc 800}
+ {-33762787200 cm 900}
+ {-30607027200 m 1000}
+ {-27451267200 mc 1100}
+ {-24295507200 mcc 1200}
+ {-21139747200 mccc 1300}
+ {-17983987200 mcd 1400}
+ {-14828227200 md 1500}
+ {-11672467200 mdc 1600}
+ {-8516707200 mdcc 1700}
+ {-5364662400 mdccc 1800}
+ {-2208988800 mcm 1900}
+ {946684800 mm 2000}
+ }
+ LOCALE_NUMERALS {
+ ? i ii iii iv v vi vii viii ix
+ x xi xii xiii xiv xv xvi xvii xviii xix
+ xx xxi xxii xxiii xxiv xxv xxvi xxvii xxviii xxix
+ xxx xxxi xxxii xxxiii xxxiv xxxv xxxvi xxxvii xxxviii xxxix
+ xl xli xlii xliii xliv xlv xlvi xlvii xlviii xlix
+ l li lii liii liv lv lvi lvii lviii lix
+ lx lxi lxii lxiii lxiv lxv lxvi lxvii lxviii lxix
+ lxx lxxi lxxii lxxiii lxxiv lxxv lxxvi lxxvii lxxviii lxxix
+ lxxx lxxxi lxxxii lxxxiii lxxxiv lxxxv lxxxvi lxxxvii lxxxviii
+ lxxxix
+ xc xci xcii xciii xciv xcv xcvi xcvii xcviii xcix
+ c
+ }
+ DATE_FORMAT {%m/%d/%Y}
+ TIME_FORMAT {%H:%M:%S}
+ DATE_TIME_FORMAT {%x %X}
+ LOCALE_DATE_FORMAT {die %Od mensis %Om annoque %EY}
+ LOCALE_TIME_FORMAT {%OH h %OM m %OS s}
+ LOCALE_DATE_TIME_FORMAT {%Ex %EX}
+ BCE {Before Christ}
+ CE {Anno Domini}
+ }
+}
+
+#----------------------------------------------------------------------
+#
+# The tests for the Windows platform are careful *not* to muck with
+# the system registry. Instead, the 'registry' command is overridden
+# in the '::tcl::clock' namespace.
+#
+#----------------------------------------------------------------------
+
+namespace eval ::testClock {
+ namespace export registry
+ set reg \
+ [dict create \
+ HKEY_CURRENT_USER\\Control\ Panel\\International \
+ [dict create \
+ locale 0409 \
+ sShortDate dd-MMM-yyyy \
+ sLongDate "'the' dd''' day of' MMMM yyyy" \
+ sTimeFormat "h:mm:ss tt"] \
+ HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\TimeZoneInformation \
+ [dict create \
+ Bias 300 \
+ StandardBias 0 \
+ DaylightBias -60 \
+ StandardStart \x00\x00\x0b\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00 \
+ DaylightStart \x00\x00\x03\x00\x02\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00]]
+}
+
+
+proc ::testClock::registry { cmd path key } {
+ variable reg
+ if { $cmd ne {get} } {
+ return -code error "test case attempts to write/query the registry"
+ }
+ if { ![dict exists $reg $path $key] } {
+ return -code error "test case attempts to read unknown registry entry $path $key"
+ }
+ return [dict get $reg $path $key]
+}
+
+# Test some of the basics of [clock format]
+
+test clock-1.0 "clock format - wrong # args" {
+ list [catch {clock format} msg] $msg $::errorCode
+} {1 {wrong # args: should be "clock format clockval ?-format string? ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?"} {CLOCK wrongNumArgs}}
+
+test clock-1.1 "clock format - bad time" {
+ list [catch {clock format foo} msg] $msg
+} {1 {expected integer but got "foo"}}
+
+test clock-1.2 "clock format - bad gmt val" {
+ list [catch {clock format 0 -gmt foo} msg] $msg
+} {1 {expected boolean value but got "foo"}}
+
+test clock-1.3 "clock format - empty val" {
+ clock format 0 -gmt 1 -format ""
+} {}
+
+test clock-1.4 "clock format - bad flag" {*}{
+ -body {
+ list [catch {clock format 0 -oops badflag} msg] $msg $::errorCode
+ }
+ -match glob
+ -result {1 {bad switch "-oops": must be -format, -gmt, -locale, or -timezone} {CLOCK badSwitch -oops}}
+}
+
+test clock-1.5 "clock format - bad timezone" {
+ list [catch {clock format 0 -format "%s" -timezone :NOWHERE} msg] $msg $::errorCode
+} {1 {time zone ":NOWHERE" not found} {CLOCK badTimeZone :NOWHERE}}
+
+test clock-1.6 "clock format - gmt + timezone" {
+ list [catch {clock format 0 -timezone :GMT -gmt true} msg] $msg $::errorCode
+} {1 {cannot use -gmt and -timezone in same call} {CLOCK gmtWithTimezone}}
+
+test clock-1.7 "clock format - option abbreviations" {
+ clock format 0 -g true -f "%Y-%m-%d"
+} 1970-01-01
+
+# BEGIN testcases2
+
+# Test formatting of Gregorian year, month, day, all formats
+# Formats tested: %b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y %EY
+
+test clock-2.1 {conversion of 1872-01-01} {
+ clock format -3092556304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1872 12:34:56 die i mensis i annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2404794 01 i 1 01/01/1872 die i mensis i annoque mdccclxxii 72 lxxii 1872}
+test clock-2.2 {conversion of 1872-01-31} {
+ clock format -3089964304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1872 12:34:56 die xxxi mensis i annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2404824 01 i 1 01/31/1872 die xxxi mensis i annoque mdccclxxii 72 lxxii 1872}
+test clock-2.3 {conversion of 1872-02-01} {
+ clock format -3089877904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1872 12:34:56 die i mensis ii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2404825 02 ii 2 02/01/1872 die i mensis ii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.4 {conversion of 1872-02-29} {
+ clock format -3087458704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1872 12:34:56 die xxix mensis ii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2404853 02 ii 2 02/29/1872 die xxix mensis ii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.5 {conversion of 1872-03-01} {
+ clock format -3087372304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1872 12:34:56 die i mensis iii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 061 2404854 03 iii 3 03/01/1872 die i mensis iii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.6 {conversion of 1872-03-31} {
+ clock format -3084780304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1872 12:34:56 die xxxi mensis iii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2404884 03 iii 3 03/31/1872 die xxxi mensis iii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.7 {conversion of 1872-04-01} {
+ clock format -3084693904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1872 12:34:56 die i mensis iv annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 092 2404885 04 iv 4 04/01/1872 die i mensis iv annoque mdccclxxii 72 lxxii 1872}
+test clock-2.8 {conversion of 1872-04-30} {
+ clock format -3082188304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1872 12:34:56 die xxx mensis iv annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2404914 04 iv 4 04/30/1872 die xxx mensis iv annoque mdccclxxii 72 lxxii 1872}
+test clock-2.9 {conversion of 1872-05-01} {
+ clock format -3082101904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1872 12:34:56 die i mensis v annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 122 2404915 05 v 5 05/01/1872 die i mensis v annoque mdccclxxii 72 lxxii 1872}
+test clock-2.10 {conversion of 1872-05-31} {
+ clock format -3079509904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1872 12:34:56 die xxxi mensis v annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2404945 05 v 5 05/31/1872 die xxxi mensis v annoque mdccclxxii 72 lxxii 1872}
+test clock-2.11 {conversion of 1872-06-01} {
+ clock format -3079423504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1872 12:34:56 die i mensis vi annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 153 2404946 06 vi 6 06/01/1872 die i mensis vi annoque mdccclxxii 72 lxxii 1872}
+test clock-2.12 {conversion of 1872-06-30} {
+ clock format -3076917904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1872 12:34:56 die xxx mensis vi annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2404975 06 vi 6 06/30/1872 die xxx mensis vi annoque mdccclxxii 72 lxxii 1872}
+test clock-2.13 {conversion of 1872-07-01} {
+ clock format -3076831504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1872 12:34:56 die i mensis vii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 183 2404976 07 vii 7 07/01/1872 die i mensis vii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.14 {conversion of 1872-07-31} {
+ clock format -3074239504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1872 12:34:56 die xxxi mensis vii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2405006 07 vii 7 07/31/1872 die xxxi mensis vii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.15 {conversion of 1872-08-01} {
+ clock format -3074153104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1872 12:34:56 die i mensis viii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 214 2405007 08 viii 8 08/01/1872 die i mensis viii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.16 {conversion of 1872-08-31} {
+ clock format -3071561104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1872 12:34:56 die xxxi mensis viii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2405037 08 viii 8 08/31/1872 die xxxi mensis viii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.17 {conversion of 1872-09-01} {
+ clock format -3071474704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1872 12:34:56 die i mensis ix annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 245 2405038 09 ix 9 09/01/1872 die i mensis ix annoque mdccclxxii 72 lxxii 1872}
+test clock-2.18 {conversion of 1872-09-30} {
+ clock format -3068969104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1872 12:34:56 die xxx mensis ix annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2405067 09 ix 9 09/30/1872 die xxx mensis ix annoque mdccclxxii 72 lxxii 1872}
+test clock-2.19 {conversion of 1872-10-01} {
+ clock format -3068882704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1872 12:34:56 die i mensis x annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 275 2405068 10 x 10 10/01/1872 die i mensis x annoque mdccclxxii 72 lxxii 1872}
+test clock-2.20 {conversion of 1872-10-31} {
+ clock format -3066290704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1872 12:34:56 die xxxi mensis x annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2405098 10 x 10 10/31/1872 die xxxi mensis x annoque mdccclxxii 72 lxxii 1872}
+test clock-2.21 {conversion of 1872-11-01} {
+ clock format -3066204304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1872 12:34:56 die i mensis xi annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 306 2405099 11 xi 11 11/01/1872 die i mensis xi annoque mdccclxxii 72 lxxii 1872}
+test clock-2.22 {conversion of 1872-11-30} {
+ clock format -3063698704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1872 12:34:56 die xxx mensis xi annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2405128 11 xi 11 11/30/1872 die xxx mensis xi annoque mdccclxxii 72 lxxii 1872}
+test clock-2.23 {conversion of 1872-12-01} {
+ clock format -3063612304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1872 12:34:56 die i mensis xii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 336 2405129 12 xii 12 12/01/1872 die i mensis xii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.24 {conversion of 1872-12-31} {
+ clock format -3061020304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1872 12:34:56 die xxxi mensis xii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2405159 12 xii 12 12/31/1872 die xxxi mensis xii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.25 {conversion of 1873-01-01} {
+ clock format -3060933904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1873 12:34:56 die i mensis i annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2405160 01 i 1 01/01/1873 die i mensis i annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.26 {conversion of 1873-01-31} {
+ clock format -3058341904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1873 12:34:56 die xxxi mensis i annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2405190 01 i 1 01/31/1873 die xxxi mensis i annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.27 {conversion of 1873-02-01} {
+ clock format -3058255504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1873 12:34:56 die i mensis ii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2405191 02 ii 2 02/01/1873 die i mensis ii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.28 {conversion of 1873-02-28} {
+ clock format -3055922704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1873 12:34:56 die xxviii mensis ii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2405218 02 ii 2 02/28/1873 die xxviii mensis ii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.29 {conversion of 1873-03-01} {
+ clock format -3055836304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1873 12:34:56 die i mensis iii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2405219 03 iii 3 03/01/1873 die i mensis iii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.30 {conversion of 1873-03-31} {
+ clock format -3053244304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1873 12:34:56 die xxxi mensis iii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2405249 03 iii 3 03/31/1873 die xxxi mensis iii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.31 {conversion of 1873-04-01} {
+ clock format -3053157904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1873 12:34:56 die i mensis iv annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2405250 04 iv 4 04/01/1873 die i mensis iv annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.32 {conversion of 1873-04-30} {
+ clock format -3050652304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1873 12:34:56 die xxx mensis iv annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2405279 04 iv 4 04/30/1873 die xxx mensis iv annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.33 {conversion of 1873-05-01} {
+ clock format -3050565904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1873 12:34:56 die i mensis v annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2405280 05 v 5 05/01/1873 die i mensis v annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.34 {conversion of 1873-05-31} {
+ clock format -3047973904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1873 12:34:56 die xxxi mensis v annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2405310 05 v 5 05/31/1873 die xxxi mensis v annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.35 {conversion of 1873-06-01} {
+ clock format -3047887504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1873 12:34:56 die i mensis vi annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2405311 06 vi 6 06/01/1873 die i mensis vi annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.36 {conversion of 1873-06-30} {
+ clock format -3045381904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1873 12:34:56 die xxx mensis vi annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2405340 06 vi 6 06/30/1873 die xxx mensis vi annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.37 {conversion of 1873-07-01} {
+ clock format -3045295504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1873 12:34:56 die i mensis vii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2405341 07 vii 7 07/01/1873 die i mensis vii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.38 {conversion of 1873-07-31} {
+ clock format -3042703504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1873 12:34:56 die xxxi mensis vii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2405371 07 vii 7 07/31/1873 die xxxi mensis vii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.39 {conversion of 1873-08-01} {
+ clock format -3042617104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1873 12:34:56 die i mensis viii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2405372 08 viii 8 08/01/1873 die i mensis viii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.40 {conversion of 1873-08-31} {
+ clock format -3040025104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1873 12:34:56 die xxxi mensis viii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2405402 08 viii 8 08/31/1873 die xxxi mensis viii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.41 {conversion of 1873-09-01} {
+ clock format -3039938704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1873 12:34:56 die i mensis ix annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2405403 09 ix 9 09/01/1873 die i mensis ix annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.42 {conversion of 1873-09-30} {
+ clock format -3037433104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1873 12:34:56 die xxx mensis ix annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2405432 09 ix 9 09/30/1873 die xxx mensis ix annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.43 {conversion of 1873-10-01} {
+ clock format -3037346704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1873 12:34:56 die i mensis x annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2405433 10 x 10 10/01/1873 die i mensis x annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.44 {conversion of 1873-10-31} {
+ clock format -3034754704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1873 12:34:56 die xxxi mensis x annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2405463 10 x 10 10/31/1873 die xxxi mensis x annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.45 {conversion of 1873-11-01} {
+ clock format -3034668304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1873 12:34:56 die i mensis xi annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2405464 11 xi 11 11/01/1873 die i mensis xi annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.46 {conversion of 1873-11-30} {
+ clock format -3032162704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1873 12:34:56 die xxx mensis xi annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2405493 11 xi 11 11/30/1873 die xxx mensis xi annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.47 {conversion of 1873-12-01} {
+ clock format -3032076304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1873 12:34:56 die i mensis xii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2405494 12 xii 12 12/01/1873 die i mensis xii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.48 {conversion of 1873-12-31} {
+ clock format -3029484304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1873 12:34:56 die xxxi mensis xii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2405524 12 xii 12 12/31/1873 die xxxi mensis xii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.49 {conversion of 1876-01-01} {
+ clock format -2966325904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1876 12:34:56 die i mensis i annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2406255 01 i 1 01/01/1876 die i mensis i annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.50 {conversion of 1876-01-31} {
+ clock format -2963733904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1876 12:34:56 die xxxi mensis i annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2406285 01 i 1 01/31/1876 die xxxi mensis i annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.51 {conversion of 1876-02-01} {
+ clock format -2963647504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1876 12:34:56 die i mensis ii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2406286 02 ii 2 02/01/1876 die i mensis ii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.52 {conversion of 1876-02-29} {
+ clock format -2961228304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1876 12:34:56 die xxix mensis ii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2406314 02 ii 2 02/29/1876 die xxix mensis ii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.53 {conversion of 1876-03-01} {
+ clock format -2961141904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1876 12:34:56 die i mensis iii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 061 2406315 03 iii 3 03/01/1876 die i mensis iii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.54 {conversion of 1876-03-31} {
+ clock format -2958549904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1876 12:34:56 die xxxi mensis iii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2406345 03 iii 3 03/31/1876 die xxxi mensis iii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.55 {conversion of 1876-04-01} {
+ clock format -2958463504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1876 12:34:56 die i mensis iv annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 092 2406346 04 iv 4 04/01/1876 die i mensis iv annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.56 {conversion of 1876-04-30} {
+ clock format -2955957904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1876 12:34:56 die xxx mensis iv annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2406375 04 iv 4 04/30/1876 die xxx mensis iv annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.57 {conversion of 1876-05-01} {
+ clock format -2955871504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1876 12:34:56 die i mensis v annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 122 2406376 05 v 5 05/01/1876 die i mensis v annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.58 {conversion of 1876-05-31} {
+ clock format -2953279504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1876 12:34:56 die xxxi mensis v annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2406406 05 v 5 05/31/1876 die xxxi mensis v annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.59 {conversion of 1876-06-01} {
+ clock format -2953193104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1876 12:34:56 die i mensis vi annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 153 2406407 06 vi 6 06/01/1876 die i mensis vi annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.60 {conversion of 1876-06-30} {
+ clock format -2950687504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1876 12:34:56 die xxx mensis vi annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2406436 06 vi 6 06/30/1876 die xxx mensis vi annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.61 {conversion of 1876-07-01} {
+ clock format -2950601104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1876 12:34:56 die i mensis vii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 183 2406437 07 vii 7 07/01/1876 die i mensis vii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.62 {conversion of 1876-07-31} {
+ clock format -2948009104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1876 12:34:56 die xxxi mensis vii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2406467 07 vii 7 07/31/1876 die xxxi mensis vii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.63 {conversion of 1876-08-01} {
+ clock format -2947922704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1876 12:34:56 die i mensis viii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 214 2406468 08 viii 8 08/01/1876 die i mensis viii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.64 {conversion of 1876-08-31} {
+ clock format -2945330704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1876 12:34:56 die xxxi mensis viii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2406498 08 viii 8 08/31/1876 die xxxi mensis viii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.65 {conversion of 1876-09-01} {
+ clock format -2945244304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1876 12:34:56 die i mensis ix annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 245 2406499 09 ix 9 09/01/1876 die i mensis ix annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.66 {conversion of 1876-09-30} {
+ clock format -2942738704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1876 12:34:56 die xxx mensis ix annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2406528 09 ix 9 09/30/1876 die xxx mensis ix annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.67 {conversion of 1876-10-01} {
+ clock format -2942652304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1876 12:34:56 die i mensis x annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 275 2406529 10 x 10 10/01/1876 die i mensis x annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.68 {conversion of 1876-10-31} {
+ clock format -2940060304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1876 12:34:56 die xxxi mensis x annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2406559 10 x 10 10/31/1876 die xxxi mensis x annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.69 {conversion of 1876-11-01} {
+ clock format -2939973904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1876 12:34:56 die i mensis xi annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 306 2406560 11 xi 11 11/01/1876 die i mensis xi annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.70 {conversion of 1876-11-30} {
+ clock format -2937468304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1876 12:34:56 die xxx mensis xi annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2406589 11 xi 11 11/30/1876 die xxx mensis xi annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.71 {conversion of 1876-12-01} {
+ clock format -2937381904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1876 12:34:56 die i mensis xii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 336 2406590 12 xii 12 12/01/1876 die i mensis xii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.72 {conversion of 1876-12-31} {
+ clock format -2934789904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1876 12:34:56 die xxxi mensis xii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2406620 12 xii 12 12/31/1876 die xxxi mensis xii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.73 {conversion of 1877-01-01} {
+ clock format -2934703504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1877 12:34:56 die i mensis i annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2406621 01 i 1 01/01/1877 die i mensis i annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.74 {conversion of 1877-01-31} {
+ clock format -2932111504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1877 12:34:56 die xxxi mensis i annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2406651 01 i 1 01/31/1877 die xxxi mensis i annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.75 {conversion of 1877-02-01} {
+ clock format -2932025104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1877 12:34:56 die i mensis ii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2406652 02 ii 2 02/01/1877 die i mensis ii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.76 {conversion of 1877-02-28} {
+ clock format -2929692304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1877 12:34:56 die xxviii mensis ii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2406679 02 ii 2 02/28/1877 die xxviii mensis ii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.77 {conversion of 1877-03-01} {
+ clock format -2929605904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1877 12:34:56 die i mensis iii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2406680 03 iii 3 03/01/1877 die i mensis iii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.78 {conversion of 1877-03-31} {
+ clock format -2927013904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1877 12:34:56 die xxxi mensis iii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2406710 03 iii 3 03/31/1877 die xxxi mensis iii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.79 {conversion of 1877-04-01} {
+ clock format -2926927504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1877 12:34:56 die i mensis iv annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2406711 04 iv 4 04/01/1877 die i mensis iv annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.80 {conversion of 1877-04-30} {
+ clock format -2924421904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1877 12:34:56 die xxx mensis iv annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2406740 04 iv 4 04/30/1877 die xxx mensis iv annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.81 {conversion of 1877-05-01} {
+ clock format -2924335504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1877 12:34:56 die i mensis v annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2406741 05 v 5 05/01/1877 die i mensis v annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.82 {conversion of 1877-05-31} {
+ clock format -2921743504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1877 12:34:56 die xxxi mensis v annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2406771 05 v 5 05/31/1877 die xxxi mensis v annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.83 {conversion of 1877-06-01} {
+ clock format -2921657104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1877 12:34:56 die i mensis vi annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2406772 06 vi 6 06/01/1877 die i mensis vi annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.84 {conversion of 1877-06-30} {
+ clock format -2919151504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1877 12:34:56 die xxx mensis vi annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2406801 06 vi 6 06/30/1877 die xxx mensis vi annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.85 {conversion of 1877-07-01} {
+ clock format -2919065104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1877 12:34:56 die i mensis vii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2406802 07 vii 7 07/01/1877 die i mensis vii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.86 {conversion of 1877-07-31} {
+ clock format -2916473104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1877 12:34:56 die xxxi mensis vii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2406832 07 vii 7 07/31/1877 die xxxi mensis vii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.87 {conversion of 1877-08-01} {
+ clock format -2916386704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1877 12:34:56 die i mensis viii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2406833 08 viii 8 08/01/1877 die i mensis viii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.88 {conversion of 1877-08-31} {
+ clock format -2913794704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1877 12:34:56 die xxxi mensis viii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2406863 08 viii 8 08/31/1877 die xxxi mensis viii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.89 {conversion of 1877-09-01} {
+ clock format -2913708304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1877 12:34:56 die i mensis ix annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2406864 09 ix 9 09/01/1877 die i mensis ix annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.90 {conversion of 1877-09-30} {
+ clock format -2911202704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1877 12:34:56 die xxx mensis ix annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2406893 09 ix 9 09/30/1877 die xxx mensis ix annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.91 {conversion of 1877-10-01} {
+ clock format -2911116304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1877 12:34:56 die i mensis x annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2406894 10 x 10 10/01/1877 die i mensis x annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.92 {conversion of 1877-10-31} {
+ clock format -2908524304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1877 12:34:56 die xxxi mensis x annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2406924 10 x 10 10/31/1877 die xxxi mensis x annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.93 {conversion of 1877-11-01} {
+ clock format -2908437904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1877 12:34:56 die i mensis xi annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2406925 11 xi 11 11/01/1877 die i mensis xi annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.94 {conversion of 1877-11-30} {
+ clock format -2905932304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1877 12:34:56 die xxx mensis xi annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2406954 11 xi 11 11/30/1877 die xxx mensis xi annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.95 {conversion of 1877-12-01} {
+ clock format -2905845904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1877 12:34:56 die i mensis xii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2406955 12 xii 12 12/01/1877 die i mensis xii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.96 {conversion of 1877-12-31} {
+ clock format -2903253904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1877 12:34:56 die xxxi mensis xii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2406985 12 xii 12 12/31/1877 die xxxi mensis xii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.97 {conversion of 1880-01-01} {
+ clock format -2840095504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1880 12:34:56 die i mensis i annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2407716 01 i 1 01/01/1880 die i mensis i annoque mdccclxxx 80 lxxx 1880}
+test clock-2.98 {conversion of 1880-01-31} {
+ clock format -2837503504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1880 12:34:56 die xxxi mensis i annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2407746 01 i 1 01/31/1880 die xxxi mensis i annoque mdccclxxx 80 lxxx 1880}
+test clock-2.99 {conversion of 1880-02-01} {
+ clock format -2837417104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1880 12:34:56 die i mensis ii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2407747 02 ii 2 02/01/1880 die i mensis ii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.100 {conversion of 1880-02-29} {
+ clock format -2834997904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1880 12:34:56 die xxix mensis ii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2407775 02 ii 2 02/29/1880 die xxix mensis ii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.101 {conversion of 1880-03-01} {
+ clock format -2834911504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1880 12:34:56 die i mensis iii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 061 2407776 03 iii 3 03/01/1880 die i mensis iii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.102 {conversion of 1880-03-31} {
+ clock format -2832319504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1880 12:34:56 die xxxi mensis iii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2407806 03 iii 3 03/31/1880 die xxxi mensis iii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.103 {conversion of 1880-04-01} {
+ clock format -2832233104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1880 12:34:56 die i mensis iv annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 092 2407807 04 iv 4 04/01/1880 die i mensis iv annoque mdccclxxx 80 lxxx 1880}
+test clock-2.104 {conversion of 1880-04-30} {
+ clock format -2829727504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1880 12:34:56 die xxx mensis iv annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2407836 04 iv 4 04/30/1880 die xxx mensis iv annoque mdccclxxx 80 lxxx 1880}
+test clock-2.105 {conversion of 1880-05-01} {
+ clock format -2829641104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1880 12:34:56 die i mensis v annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 122 2407837 05 v 5 05/01/1880 die i mensis v annoque mdccclxxx 80 lxxx 1880}
+test clock-2.106 {conversion of 1880-05-31} {
+ clock format -2827049104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1880 12:34:56 die xxxi mensis v annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2407867 05 v 5 05/31/1880 die xxxi mensis v annoque mdccclxxx 80 lxxx 1880}
+test clock-2.107 {conversion of 1880-06-01} {
+ clock format -2826962704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1880 12:34:56 die i mensis vi annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 153 2407868 06 vi 6 06/01/1880 die i mensis vi annoque mdccclxxx 80 lxxx 1880}
+test clock-2.108 {conversion of 1880-06-30} {
+ clock format -2824457104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1880 12:34:56 die xxx mensis vi annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2407897 06 vi 6 06/30/1880 die xxx mensis vi annoque mdccclxxx 80 lxxx 1880}
+test clock-2.109 {conversion of 1880-07-01} {
+ clock format -2824370704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1880 12:34:56 die i mensis vii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 183 2407898 07 vii 7 07/01/1880 die i mensis vii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.110 {conversion of 1880-07-31} {
+ clock format -2821778704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1880 12:34:56 die xxxi mensis vii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2407928 07 vii 7 07/31/1880 die xxxi mensis vii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.111 {conversion of 1880-08-01} {
+ clock format -2821692304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1880 12:34:56 die i mensis viii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 214 2407929 08 viii 8 08/01/1880 die i mensis viii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.112 {conversion of 1880-08-31} {
+ clock format -2819100304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1880 12:34:56 die xxxi mensis viii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2407959 08 viii 8 08/31/1880 die xxxi mensis viii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.113 {conversion of 1880-09-01} {
+ clock format -2819013904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1880 12:34:56 die i mensis ix annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 245 2407960 09 ix 9 09/01/1880 die i mensis ix annoque mdccclxxx 80 lxxx 1880}
+test clock-2.114 {conversion of 1880-09-30} {
+ clock format -2816508304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1880 12:34:56 die xxx mensis ix annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2407989 09 ix 9 09/30/1880 die xxx mensis ix annoque mdccclxxx 80 lxxx 1880}
+test clock-2.115 {conversion of 1880-10-01} {
+ clock format -2816421904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1880 12:34:56 die i mensis x annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 275 2407990 10 x 10 10/01/1880 die i mensis x annoque mdccclxxx 80 lxxx 1880}
+test clock-2.116 {conversion of 1880-10-31} {
+ clock format -2813829904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1880 12:34:56 die xxxi mensis x annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2408020 10 x 10 10/31/1880 die xxxi mensis x annoque mdccclxxx 80 lxxx 1880}
+test clock-2.117 {conversion of 1880-11-01} {
+ clock format -2813743504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1880 12:34:56 die i mensis xi annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 306 2408021 11 xi 11 11/01/1880 die i mensis xi annoque mdccclxxx 80 lxxx 1880}
+test clock-2.118 {conversion of 1880-11-30} {
+ clock format -2811237904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1880 12:34:56 die xxx mensis xi annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2408050 11 xi 11 11/30/1880 die xxx mensis xi annoque mdccclxxx 80 lxxx 1880}
+test clock-2.119 {conversion of 1880-12-01} {
+ clock format -2811151504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1880 12:34:56 die i mensis xii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 336 2408051 12 xii 12 12/01/1880 die i mensis xii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.120 {conversion of 1880-12-31} {
+ clock format -2808559504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1880 12:34:56 die xxxi mensis xii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2408081 12 xii 12 12/31/1880 die xxxi mensis xii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.121 {conversion of 1881-01-01} {
+ clock format -2808473104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1881 12:34:56 die i mensis i annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2408082 01 i 1 01/01/1881 die i mensis i annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.122 {conversion of 1881-01-31} {
+ clock format -2805881104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1881 12:34:56 die xxxi mensis i annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2408112 01 i 1 01/31/1881 die xxxi mensis i annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.123 {conversion of 1881-02-01} {
+ clock format -2805794704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1881 12:34:56 die i mensis ii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2408113 02 ii 2 02/01/1881 die i mensis ii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.124 {conversion of 1881-02-28} {
+ clock format -2803461904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1881 12:34:56 die xxviii mensis ii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2408140 02 ii 2 02/28/1881 die xxviii mensis ii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.125 {conversion of 1881-03-01} {
+ clock format -2803375504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1881 12:34:56 die i mensis iii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2408141 03 iii 3 03/01/1881 die i mensis iii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.126 {conversion of 1881-03-31} {
+ clock format -2800783504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1881 12:34:56 die xxxi mensis iii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2408171 03 iii 3 03/31/1881 die xxxi mensis iii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.127 {conversion of 1881-04-01} {
+ clock format -2800697104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1881 12:34:56 die i mensis iv annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2408172 04 iv 4 04/01/1881 die i mensis iv annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.128 {conversion of 1881-04-30} {
+ clock format -2798191504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1881 12:34:56 die xxx mensis iv annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2408201 04 iv 4 04/30/1881 die xxx mensis iv annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.129 {conversion of 1881-05-01} {
+ clock format -2798105104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1881 12:34:56 die i mensis v annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2408202 05 v 5 05/01/1881 die i mensis v annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.130 {conversion of 1881-05-31} {
+ clock format -2795513104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1881 12:34:56 die xxxi mensis v annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2408232 05 v 5 05/31/1881 die xxxi mensis v annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.131 {conversion of 1881-06-01} {
+ clock format -2795426704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1881 12:34:56 die i mensis vi annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2408233 06 vi 6 06/01/1881 die i mensis vi annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.132 {conversion of 1881-06-30} {
+ clock format -2792921104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1881 12:34:56 die xxx mensis vi annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2408262 06 vi 6 06/30/1881 die xxx mensis vi annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.133 {conversion of 1881-07-01} {
+ clock format -2792834704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1881 12:34:56 die i mensis vii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2408263 07 vii 7 07/01/1881 die i mensis vii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.134 {conversion of 1881-07-31} {
+ clock format -2790242704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1881 12:34:56 die xxxi mensis vii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2408293 07 vii 7 07/31/1881 die xxxi mensis vii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.135 {conversion of 1881-08-01} {
+ clock format -2790156304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1881 12:34:56 die i mensis viii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2408294 08 viii 8 08/01/1881 die i mensis viii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.136 {conversion of 1881-08-31} {
+ clock format -2787564304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1881 12:34:56 die xxxi mensis viii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2408324 08 viii 8 08/31/1881 die xxxi mensis viii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.137 {conversion of 1881-09-01} {
+ clock format -2787477904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1881 12:34:56 die i mensis ix annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2408325 09 ix 9 09/01/1881 die i mensis ix annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.138 {conversion of 1881-09-30} {
+ clock format -2784972304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1881 12:34:56 die xxx mensis ix annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2408354 09 ix 9 09/30/1881 die xxx mensis ix annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.139 {conversion of 1881-10-01} {
+ clock format -2784885904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1881 12:34:56 die i mensis x annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2408355 10 x 10 10/01/1881 die i mensis x annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.140 {conversion of 1881-10-31} {
+ clock format -2782293904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1881 12:34:56 die xxxi mensis x annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2408385 10 x 10 10/31/1881 die xxxi mensis x annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.141 {conversion of 1881-11-01} {
+ clock format -2782207504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1881 12:34:56 die i mensis xi annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2408386 11 xi 11 11/01/1881 die i mensis xi annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.142 {conversion of 1881-11-30} {
+ clock format -2779701904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1881 12:34:56 die xxx mensis xi annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2408415 11 xi 11 11/30/1881 die xxx mensis xi annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.143 {conversion of 1881-12-01} {
+ clock format -2779615504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1881 12:34:56 die i mensis xii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2408416 12 xii 12 12/01/1881 die i mensis xii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.144 {conversion of 1881-12-31} {
+ clock format -2777023504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1881 12:34:56 die xxxi mensis xii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2408446 12 xii 12 12/31/1881 die xxxi mensis xii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.145 {conversion of 1884-01-01} {
+ clock format -2713865104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1884 12:34:56 die i mensis i annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2409177 01 i 1 01/01/1884 die i mensis i annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.146 {conversion of 1884-01-31} {
+ clock format -2711273104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1884 12:34:56 die xxxi mensis i annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2409207 01 i 1 01/31/1884 die xxxi mensis i annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.147 {conversion of 1884-02-01} {
+ clock format -2711186704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1884 12:34:56 die i mensis ii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2409208 02 ii 2 02/01/1884 die i mensis ii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.148 {conversion of 1884-02-29} {
+ clock format -2708767504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1884 12:34:56 die xxix mensis ii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2409236 02 ii 2 02/29/1884 die xxix mensis ii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.149 {conversion of 1884-03-01} {
+ clock format -2708681104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1884 12:34:56 die i mensis iii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 061 2409237 03 iii 3 03/01/1884 die i mensis iii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.150 {conversion of 1884-03-31} {
+ clock format -2706089104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1884 12:34:56 die xxxi mensis iii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2409267 03 iii 3 03/31/1884 die xxxi mensis iii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.151 {conversion of 1884-04-01} {
+ clock format -2706002704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1884 12:34:56 die i mensis iv annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 092 2409268 04 iv 4 04/01/1884 die i mensis iv annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.152 {conversion of 1884-04-30} {
+ clock format -2703497104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1884 12:34:56 die xxx mensis iv annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2409297 04 iv 4 04/30/1884 die xxx mensis iv annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.153 {conversion of 1884-05-01} {
+ clock format -2703410704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1884 12:34:56 die i mensis v annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 122 2409298 05 v 5 05/01/1884 die i mensis v annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.154 {conversion of 1884-05-31} {
+ clock format -2700818704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1884 12:34:56 die xxxi mensis v annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2409328 05 v 5 05/31/1884 die xxxi mensis v annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.155 {conversion of 1884-06-01} {
+ clock format -2700732304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1884 12:34:56 die i mensis vi annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 153 2409329 06 vi 6 06/01/1884 die i mensis vi annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.156 {conversion of 1884-06-30} {
+ clock format -2698226704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1884 12:34:56 die xxx mensis vi annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2409358 06 vi 6 06/30/1884 die xxx mensis vi annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.157 {conversion of 1884-07-01} {
+ clock format -2698140304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1884 12:34:56 die i mensis vii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 183 2409359 07 vii 7 07/01/1884 die i mensis vii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.158 {conversion of 1884-07-31} {
+ clock format -2695548304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1884 12:34:56 die xxxi mensis vii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2409389 07 vii 7 07/31/1884 die xxxi mensis vii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.159 {conversion of 1884-08-01} {
+ clock format -2695461904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1884 12:34:56 die i mensis viii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 214 2409390 08 viii 8 08/01/1884 die i mensis viii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.160 {conversion of 1884-08-31} {
+ clock format -2692869904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1884 12:34:56 die xxxi mensis viii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2409420 08 viii 8 08/31/1884 die xxxi mensis viii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.161 {conversion of 1884-09-01} {
+ clock format -2692783504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1884 12:34:56 die i mensis ix annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 245 2409421 09 ix 9 09/01/1884 die i mensis ix annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.162 {conversion of 1884-09-30} {
+ clock format -2690277904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1884 12:34:56 die xxx mensis ix annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2409450 09 ix 9 09/30/1884 die xxx mensis ix annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.163 {conversion of 1884-10-01} {
+ clock format -2690191504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1884 12:34:56 die i mensis x annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 275 2409451 10 x 10 10/01/1884 die i mensis x annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.164 {conversion of 1884-10-31} {
+ clock format -2687599504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1884 12:34:56 die xxxi mensis x annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2409481 10 x 10 10/31/1884 die xxxi mensis x annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.165 {conversion of 1884-11-01} {
+ clock format -2687513104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1884 12:34:56 die i mensis xi annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 306 2409482 11 xi 11 11/01/1884 die i mensis xi annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.166 {conversion of 1884-11-30} {
+ clock format -2685007504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1884 12:34:56 die xxx mensis xi annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2409511 11 xi 11 11/30/1884 die xxx mensis xi annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.167 {conversion of 1884-12-01} {
+ clock format -2684921104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1884 12:34:56 die i mensis xii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 336 2409512 12 xii 12 12/01/1884 die i mensis xii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.168 {conversion of 1884-12-31} {
+ clock format -2682329104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1884 12:34:56 die xxxi mensis xii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2409542 12 xii 12 12/31/1884 die xxxi mensis xii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.169 {conversion of 1885-01-01} {
+ clock format -2682242704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1885 12:34:56 die i mensis i annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2409543 01 i 1 01/01/1885 die i mensis i annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.170 {conversion of 1885-01-31} {
+ clock format -2679650704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1885 12:34:56 die xxxi mensis i annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2409573 01 i 1 01/31/1885 die xxxi mensis i annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.171 {conversion of 1885-02-01} {
+ clock format -2679564304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1885 12:34:56 die i mensis ii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2409574 02 ii 2 02/01/1885 die i mensis ii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.172 {conversion of 1885-02-28} {
+ clock format -2677231504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1885 12:34:56 die xxviii mensis ii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2409601 02 ii 2 02/28/1885 die xxviii mensis ii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.173 {conversion of 1885-03-01} {
+ clock format -2677145104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1885 12:34:56 die i mensis iii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2409602 03 iii 3 03/01/1885 die i mensis iii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.174 {conversion of 1885-03-31} {
+ clock format -2674553104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1885 12:34:56 die xxxi mensis iii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2409632 03 iii 3 03/31/1885 die xxxi mensis iii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.175 {conversion of 1885-04-01} {
+ clock format -2674466704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1885 12:34:56 die i mensis iv annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2409633 04 iv 4 04/01/1885 die i mensis iv annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.176 {conversion of 1885-04-30} {
+ clock format -2671961104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1885 12:34:56 die xxx mensis iv annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2409662 04 iv 4 04/30/1885 die xxx mensis iv annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.177 {conversion of 1885-05-01} {
+ clock format -2671874704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1885 12:34:56 die i mensis v annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2409663 05 v 5 05/01/1885 die i mensis v annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.178 {conversion of 1885-05-31} {
+ clock format -2669282704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1885 12:34:56 die xxxi mensis v annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2409693 05 v 5 05/31/1885 die xxxi mensis v annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.179 {conversion of 1885-06-01} {
+ clock format -2669196304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1885 12:34:56 die i mensis vi annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2409694 06 vi 6 06/01/1885 die i mensis vi annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.180 {conversion of 1885-06-30} {
+ clock format -2666690704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1885 12:34:56 die xxx mensis vi annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2409723 06 vi 6 06/30/1885 die xxx mensis vi annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.181 {conversion of 1885-07-01} {
+ clock format -2666604304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1885 12:34:56 die i mensis vii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2409724 07 vii 7 07/01/1885 die i mensis vii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.182 {conversion of 1885-07-31} {
+ clock format -2664012304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1885 12:34:56 die xxxi mensis vii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2409754 07 vii 7 07/31/1885 die xxxi mensis vii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.183 {conversion of 1885-08-01} {
+ clock format -2663925904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1885 12:34:56 die i mensis viii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2409755 08 viii 8 08/01/1885 die i mensis viii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.184 {conversion of 1885-08-31} {
+ clock format -2661333904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1885 12:34:56 die xxxi mensis viii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2409785 08 viii 8 08/31/1885 die xxxi mensis viii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.185 {conversion of 1885-09-01} {
+ clock format -2661247504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1885 12:34:56 die i mensis ix annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2409786 09 ix 9 09/01/1885 die i mensis ix annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.186 {conversion of 1885-09-30} {
+ clock format -2658741904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1885 12:34:56 die xxx mensis ix annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2409815 09 ix 9 09/30/1885 die xxx mensis ix annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.187 {conversion of 1885-10-01} {
+ clock format -2658655504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1885 12:34:56 die i mensis x annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2409816 10 x 10 10/01/1885 die i mensis x annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.188 {conversion of 1885-10-31} {
+ clock format -2656063504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1885 12:34:56 die xxxi mensis x annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2409846 10 x 10 10/31/1885 die xxxi mensis x annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.189 {conversion of 1885-11-01} {
+ clock format -2655977104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1885 12:34:56 die i mensis xi annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2409847 11 xi 11 11/01/1885 die i mensis xi annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.190 {conversion of 1885-11-30} {
+ clock format -2653471504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1885 12:34:56 die xxx mensis xi annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2409876 11 xi 11 11/30/1885 die xxx mensis xi annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.191 {conversion of 1885-12-01} {
+ clock format -2653385104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1885 12:34:56 die i mensis xii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2409877 12 xii 12 12/01/1885 die i mensis xii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.192 {conversion of 1885-12-31} {
+ clock format -2650793104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1885 12:34:56 die xxxi mensis xii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2409907 12 xii 12 12/31/1885 die xxxi mensis xii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.193 {conversion of 1888-01-01} {
+ clock format -2587634704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1888 12:34:56 die i mensis i annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2410638 01 i 1 01/01/1888 die i mensis i annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.194 {conversion of 1888-01-31} {
+ clock format -2585042704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1888 12:34:56 die xxxi mensis i annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2410668 01 i 1 01/31/1888 die xxxi mensis i annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.195 {conversion of 1888-02-01} {
+ clock format -2584956304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1888 12:34:56 die i mensis ii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2410669 02 ii 2 02/01/1888 die i mensis ii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.196 {conversion of 1888-02-29} {
+ clock format -2582537104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1888 12:34:56 die xxix mensis ii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2410697 02 ii 2 02/29/1888 die xxix mensis ii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.197 {conversion of 1888-03-01} {
+ clock format -2582450704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1888 12:34:56 die i mensis iii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 061 2410698 03 iii 3 03/01/1888 die i mensis iii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.198 {conversion of 1888-03-31} {
+ clock format -2579858704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1888 12:34:56 die xxxi mensis iii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2410728 03 iii 3 03/31/1888 die xxxi mensis iii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.199 {conversion of 1888-04-01} {
+ clock format -2579772304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1888 12:34:56 die i mensis iv annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 092 2410729 04 iv 4 04/01/1888 die i mensis iv annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.200 {conversion of 1888-04-30} {
+ clock format -2577266704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1888 12:34:56 die xxx mensis iv annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2410758 04 iv 4 04/30/1888 die xxx mensis iv annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.201 {conversion of 1888-05-01} {
+ clock format -2577180304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1888 12:34:56 die i mensis v annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 122 2410759 05 v 5 05/01/1888 die i mensis v annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.202 {conversion of 1888-05-31} {
+ clock format -2574588304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1888 12:34:56 die xxxi mensis v annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2410789 05 v 5 05/31/1888 die xxxi mensis v annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.203 {conversion of 1888-06-01} {
+ clock format -2574501904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1888 12:34:56 die i mensis vi annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 153 2410790 06 vi 6 06/01/1888 die i mensis vi annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.204 {conversion of 1888-06-30} {
+ clock format -2571996304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1888 12:34:56 die xxx mensis vi annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2410819 06 vi 6 06/30/1888 die xxx mensis vi annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.205 {conversion of 1888-07-01} {
+ clock format -2571909904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1888 12:34:56 die i mensis vii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 183 2410820 07 vii 7 07/01/1888 die i mensis vii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.206 {conversion of 1888-07-31} {
+ clock format -2569317904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1888 12:34:56 die xxxi mensis vii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2410850 07 vii 7 07/31/1888 die xxxi mensis vii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.207 {conversion of 1888-08-01} {
+ clock format -2569231504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1888 12:34:56 die i mensis viii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 214 2410851 08 viii 8 08/01/1888 die i mensis viii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.208 {conversion of 1888-08-31} {
+ clock format -2566639504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1888 12:34:56 die xxxi mensis viii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2410881 08 viii 8 08/31/1888 die xxxi mensis viii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.209 {conversion of 1888-09-01} {
+ clock format -2566553104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1888 12:34:56 die i mensis ix annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 245 2410882 09 ix 9 09/01/1888 die i mensis ix annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.210 {conversion of 1888-09-30} {
+ clock format -2564047504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1888 12:34:56 die xxx mensis ix annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2410911 09 ix 9 09/30/1888 die xxx mensis ix annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.211 {conversion of 1888-10-01} {
+ clock format -2563961104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1888 12:34:56 die i mensis x annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 275 2410912 10 x 10 10/01/1888 die i mensis x annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.212 {conversion of 1888-10-31} {
+ clock format -2561369104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1888 12:34:56 die xxxi mensis x annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2410942 10 x 10 10/31/1888 die xxxi mensis x annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.213 {conversion of 1888-11-01} {
+ clock format -2561282704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1888 12:34:56 die i mensis xi annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 306 2410943 11 xi 11 11/01/1888 die i mensis xi annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.214 {conversion of 1888-11-30} {
+ clock format -2558777104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1888 12:34:56 die xxx mensis xi annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2410972 11 xi 11 11/30/1888 die xxx mensis xi annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.215 {conversion of 1888-12-01} {
+ clock format -2558690704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1888 12:34:56 die i mensis xii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 336 2410973 12 xii 12 12/01/1888 die i mensis xii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.216 {conversion of 1888-12-31} {
+ clock format -2556098704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1888 12:34:56 die xxxi mensis xii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2411003 12 xii 12 12/31/1888 die xxxi mensis xii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.217 {conversion of 1889-01-01} {
+ clock format -2556012304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1889 12:34:56 die i mensis i annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2411004 01 i 1 01/01/1889 die i mensis i annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.218 {conversion of 1889-01-31} {
+ clock format -2553420304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1889 12:34:56 die xxxi mensis i annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2411034 01 i 1 01/31/1889 die xxxi mensis i annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.219 {conversion of 1889-02-01} {
+ clock format -2553333904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1889 12:34:56 die i mensis ii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2411035 02 ii 2 02/01/1889 die i mensis ii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.220 {conversion of 1889-02-28} {
+ clock format -2551001104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1889 12:34:56 die xxviii mensis ii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2411062 02 ii 2 02/28/1889 die xxviii mensis ii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.221 {conversion of 1889-03-01} {
+ clock format -2550914704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1889 12:34:56 die i mensis iii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2411063 03 iii 3 03/01/1889 die i mensis iii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.222 {conversion of 1889-03-31} {
+ clock format -2548322704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1889 12:34:56 die xxxi mensis iii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2411093 03 iii 3 03/31/1889 die xxxi mensis iii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.223 {conversion of 1889-04-01} {
+ clock format -2548236304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1889 12:34:56 die i mensis iv annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2411094 04 iv 4 04/01/1889 die i mensis iv annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.224 {conversion of 1889-04-30} {
+ clock format -2545730704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1889 12:34:56 die xxx mensis iv annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2411123 04 iv 4 04/30/1889 die xxx mensis iv annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.225 {conversion of 1889-05-01} {
+ clock format -2545644304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1889 12:34:56 die i mensis v annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2411124 05 v 5 05/01/1889 die i mensis v annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.226 {conversion of 1889-05-31} {
+ clock format -2543052304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1889 12:34:56 die xxxi mensis v annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2411154 05 v 5 05/31/1889 die xxxi mensis v annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.227 {conversion of 1889-06-01} {
+ clock format -2542965904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1889 12:34:56 die i mensis vi annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2411155 06 vi 6 06/01/1889 die i mensis vi annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.228 {conversion of 1889-06-30} {
+ clock format -2540460304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1889 12:34:56 die xxx mensis vi annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2411184 06 vi 6 06/30/1889 die xxx mensis vi annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.229 {conversion of 1889-07-01} {
+ clock format -2540373904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1889 12:34:56 die i mensis vii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2411185 07 vii 7 07/01/1889 die i mensis vii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.230 {conversion of 1889-07-31} {
+ clock format -2537781904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1889 12:34:56 die xxxi mensis vii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2411215 07 vii 7 07/31/1889 die xxxi mensis vii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.231 {conversion of 1889-08-01} {
+ clock format -2537695504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1889 12:34:56 die i mensis viii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2411216 08 viii 8 08/01/1889 die i mensis viii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.232 {conversion of 1889-08-31} {
+ clock format -2535103504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1889 12:34:56 die xxxi mensis viii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2411246 08 viii 8 08/31/1889 die xxxi mensis viii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.233 {conversion of 1889-09-01} {
+ clock format -2535017104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1889 12:34:56 die i mensis ix annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2411247 09 ix 9 09/01/1889 die i mensis ix annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.234 {conversion of 1889-09-30} {
+ clock format -2532511504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1889 12:34:56 die xxx mensis ix annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2411276 09 ix 9 09/30/1889 die xxx mensis ix annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.235 {conversion of 1889-10-01} {
+ clock format -2532425104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1889 12:34:56 die i mensis x annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2411277 10 x 10 10/01/1889 die i mensis x annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.236 {conversion of 1889-10-31} {
+ clock format -2529833104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1889 12:34:56 die xxxi mensis x annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2411307 10 x 10 10/31/1889 die xxxi mensis x annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.237 {conversion of 1889-11-01} {
+ clock format -2529746704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1889 12:34:56 die i mensis xi annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2411308 11 xi 11 11/01/1889 die i mensis xi annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.238 {conversion of 1889-11-30} {
+ clock format -2527241104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1889 12:34:56 die xxx mensis xi annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2411337 11 xi 11 11/30/1889 die xxx mensis xi annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.239 {conversion of 1889-12-01} {
+ clock format -2527154704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1889 12:34:56 die i mensis xii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2411338 12 xii 12 12/01/1889 die i mensis xii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.240 {conversion of 1889-12-31} {
+ clock format -2524562704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1889 12:34:56 die xxxi mensis xii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2411368 12 xii 12 12/31/1889 die xxxi mensis xii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.241 {conversion of 1890-01-01} {
+ clock format -2524476304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1890 12:34:56 die i mensis i annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2411369 01 i 1 01/01/1890 die i mensis i annoque mdcccxc 90 xc 1890}
+test clock-2.242 {conversion of 1890-01-31} {
+ clock format -2521884304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1890 12:34:56 die xxxi mensis i annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2411399 01 i 1 01/31/1890 die xxxi mensis i annoque mdcccxc 90 xc 1890}
+test clock-2.243 {conversion of 1890-02-01} {
+ clock format -2521797904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1890 12:34:56 die i mensis ii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2411400 02 ii 2 02/01/1890 die i mensis ii annoque mdcccxc 90 xc 1890}
+test clock-2.244 {conversion of 1890-02-28} {
+ clock format -2519465104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1890 12:34:56 die xxviii mensis ii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2411427 02 ii 2 02/28/1890 die xxviii mensis ii annoque mdcccxc 90 xc 1890}
+test clock-2.245 {conversion of 1890-03-01} {
+ clock format -2519378704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1890 12:34:56 die i mensis iii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2411428 03 iii 3 03/01/1890 die i mensis iii annoque mdcccxc 90 xc 1890}
+test clock-2.246 {conversion of 1890-03-31} {
+ clock format -2516786704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1890 12:34:56 die xxxi mensis iii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2411458 03 iii 3 03/31/1890 die xxxi mensis iii annoque mdcccxc 90 xc 1890}
+test clock-2.247 {conversion of 1890-04-01} {
+ clock format -2516700304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1890 12:34:56 die i mensis iv annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2411459 04 iv 4 04/01/1890 die i mensis iv annoque mdcccxc 90 xc 1890}
+test clock-2.248 {conversion of 1890-04-30} {
+ clock format -2514194704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1890 12:34:56 die xxx mensis iv annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2411488 04 iv 4 04/30/1890 die xxx mensis iv annoque mdcccxc 90 xc 1890}
+test clock-2.249 {conversion of 1890-05-01} {
+ clock format -2514108304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1890 12:34:56 die i mensis v annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2411489 05 v 5 05/01/1890 die i mensis v annoque mdcccxc 90 xc 1890}
+test clock-2.250 {conversion of 1890-05-31} {
+ clock format -2511516304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1890 12:34:56 die xxxi mensis v annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2411519 05 v 5 05/31/1890 die xxxi mensis v annoque mdcccxc 90 xc 1890}
+test clock-2.251 {conversion of 1890-06-01} {
+ clock format -2511429904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1890 12:34:56 die i mensis vi annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2411520 06 vi 6 06/01/1890 die i mensis vi annoque mdcccxc 90 xc 1890}
+test clock-2.252 {conversion of 1890-06-30} {
+ clock format -2508924304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1890 12:34:56 die xxx mensis vi annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2411549 06 vi 6 06/30/1890 die xxx mensis vi annoque mdcccxc 90 xc 1890}
+test clock-2.253 {conversion of 1890-07-01} {
+ clock format -2508837904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1890 12:34:56 die i mensis vii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2411550 07 vii 7 07/01/1890 die i mensis vii annoque mdcccxc 90 xc 1890}
+test clock-2.254 {conversion of 1890-07-31} {
+ clock format -2506245904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1890 12:34:56 die xxxi mensis vii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2411580 07 vii 7 07/31/1890 die xxxi mensis vii annoque mdcccxc 90 xc 1890}
+test clock-2.255 {conversion of 1890-08-01} {
+ clock format -2506159504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1890 12:34:56 die i mensis viii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2411581 08 viii 8 08/01/1890 die i mensis viii annoque mdcccxc 90 xc 1890}
+test clock-2.256 {conversion of 1890-08-31} {
+ clock format -2503567504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1890 12:34:56 die xxxi mensis viii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2411611 08 viii 8 08/31/1890 die xxxi mensis viii annoque mdcccxc 90 xc 1890}
+test clock-2.257 {conversion of 1890-09-01} {
+ clock format -2503481104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1890 12:34:56 die i mensis ix annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2411612 09 ix 9 09/01/1890 die i mensis ix annoque mdcccxc 90 xc 1890}
+test clock-2.258 {conversion of 1890-09-30} {
+ clock format -2500975504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1890 12:34:56 die xxx mensis ix annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2411641 09 ix 9 09/30/1890 die xxx mensis ix annoque mdcccxc 90 xc 1890}
+test clock-2.259 {conversion of 1890-10-01} {
+ clock format -2500889104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1890 12:34:56 die i mensis x annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2411642 10 x 10 10/01/1890 die i mensis x annoque mdcccxc 90 xc 1890}
+test clock-2.260 {conversion of 1890-10-31} {
+ clock format -2498297104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1890 12:34:56 die xxxi mensis x annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2411672 10 x 10 10/31/1890 die xxxi mensis x annoque mdcccxc 90 xc 1890}
+test clock-2.261 {conversion of 1890-11-01} {
+ clock format -2498210704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1890 12:34:56 die i mensis xi annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2411673 11 xi 11 11/01/1890 die i mensis xi annoque mdcccxc 90 xc 1890}
+test clock-2.262 {conversion of 1890-11-30} {
+ clock format -2495705104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1890 12:34:56 die xxx mensis xi annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2411702 11 xi 11 11/30/1890 die xxx mensis xi annoque mdcccxc 90 xc 1890}
+test clock-2.263 {conversion of 1890-12-01} {
+ clock format -2495618704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1890 12:34:56 die i mensis xii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2411703 12 xii 12 12/01/1890 die i mensis xii annoque mdcccxc 90 xc 1890}
+test clock-2.264 {conversion of 1890-12-31} {
+ clock format -2493026704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1890 12:34:56 die xxxi mensis xii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2411733 12 xii 12 12/31/1890 die xxxi mensis xii annoque mdcccxc 90 xc 1890}
+test clock-2.265 {conversion of 1891-01-01} {
+ clock format -2492940304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1891 12:34:56 die i mensis i annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2411734 01 i 1 01/01/1891 die i mensis i annoque mdcccxci 91 xci 1891}
+test clock-2.266 {conversion of 1891-01-31} {
+ clock format -2490348304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1891 12:34:56 die xxxi mensis i annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2411764 01 i 1 01/31/1891 die xxxi mensis i annoque mdcccxci 91 xci 1891}
+test clock-2.267 {conversion of 1891-02-01} {
+ clock format -2490261904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1891 12:34:56 die i mensis ii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2411765 02 ii 2 02/01/1891 die i mensis ii annoque mdcccxci 91 xci 1891}
+test clock-2.268 {conversion of 1891-02-28} {
+ clock format -2487929104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1891 12:34:56 die xxviii mensis ii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2411792 02 ii 2 02/28/1891 die xxviii mensis ii annoque mdcccxci 91 xci 1891}
+test clock-2.269 {conversion of 1891-03-01} {
+ clock format -2487842704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1891 12:34:56 die i mensis iii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2411793 03 iii 3 03/01/1891 die i mensis iii annoque mdcccxci 91 xci 1891}
+test clock-2.270 {conversion of 1891-03-31} {
+ clock format -2485250704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1891 12:34:56 die xxxi mensis iii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2411823 03 iii 3 03/31/1891 die xxxi mensis iii annoque mdcccxci 91 xci 1891}
+test clock-2.271 {conversion of 1891-04-01} {
+ clock format -2485164304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1891 12:34:56 die i mensis iv annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2411824 04 iv 4 04/01/1891 die i mensis iv annoque mdcccxci 91 xci 1891}
+test clock-2.272 {conversion of 1891-04-30} {
+ clock format -2482658704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1891 12:34:56 die xxx mensis iv annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2411853 04 iv 4 04/30/1891 die xxx mensis iv annoque mdcccxci 91 xci 1891}
+test clock-2.273 {conversion of 1891-05-01} {
+ clock format -2482572304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1891 12:34:56 die i mensis v annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2411854 05 v 5 05/01/1891 die i mensis v annoque mdcccxci 91 xci 1891}
+test clock-2.274 {conversion of 1891-05-31} {
+ clock format -2479980304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1891 12:34:56 die xxxi mensis v annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2411884 05 v 5 05/31/1891 die xxxi mensis v annoque mdcccxci 91 xci 1891}
+test clock-2.275 {conversion of 1891-06-01} {
+ clock format -2479893904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1891 12:34:56 die i mensis vi annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2411885 06 vi 6 06/01/1891 die i mensis vi annoque mdcccxci 91 xci 1891}
+test clock-2.276 {conversion of 1891-06-30} {
+ clock format -2477388304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1891 12:34:56 die xxx mensis vi annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2411914 06 vi 6 06/30/1891 die xxx mensis vi annoque mdcccxci 91 xci 1891}
+test clock-2.277 {conversion of 1891-07-01} {
+ clock format -2477301904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1891 12:34:56 die i mensis vii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2411915 07 vii 7 07/01/1891 die i mensis vii annoque mdcccxci 91 xci 1891}
+test clock-2.278 {conversion of 1891-07-31} {
+ clock format -2474709904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1891 12:34:56 die xxxi mensis vii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2411945 07 vii 7 07/31/1891 die xxxi mensis vii annoque mdcccxci 91 xci 1891}
+test clock-2.279 {conversion of 1891-08-01} {
+ clock format -2474623504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1891 12:34:56 die i mensis viii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2411946 08 viii 8 08/01/1891 die i mensis viii annoque mdcccxci 91 xci 1891}
+test clock-2.280 {conversion of 1891-08-31} {
+ clock format -2472031504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1891 12:34:56 die xxxi mensis viii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2411976 08 viii 8 08/31/1891 die xxxi mensis viii annoque mdcccxci 91 xci 1891}
+test clock-2.281 {conversion of 1891-09-01} {
+ clock format -2471945104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1891 12:34:56 die i mensis ix annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2411977 09 ix 9 09/01/1891 die i mensis ix annoque mdcccxci 91 xci 1891}
+test clock-2.282 {conversion of 1891-09-30} {
+ clock format -2469439504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1891 12:34:56 die xxx mensis ix annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2412006 09 ix 9 09/30/1891 die xxx mensis ix annoque mdcccxci 91 xci 1891}
+test clock-2.283 {conversion of 1891-10-01} {
+ clock format -2469353104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1891 12:34:56 die i mensis x annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2412007 10 x 10 10/01/1891 die i mensis x annoque mdcccxci 91 xci 1891}
+test clock-2.284 {conversion of 1891-10-31} {
+ clock format -2466761104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1891 12:34:56 die xxxi mensis x annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2412037 10 x 10 10/31/1891 die xxxi mensis x annoque mdcccxci 91 xci 1891}
+test clock-2.285 {conversion of 1891-11-01} {
+ clock format -2466674704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1891 12:34:56 die i mensis xi annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2412038 11 xi 11 11/01/1891 die i mensis xi annoque mdcccxci 91 xci 1891}
+test clock-2.286 {conversion of 1891-11-30} {
+ clock format -2464169104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1891 12:34:56 die xxx mensis xi annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2412067 11 xi 11 11/30/1891 die xxx mensis xi annoque mdcccxci 91 xci 1891}
+test clock-2.287 {conversion of 1891-12-01} {
+ clock format -2464082704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1891 12:34:56 die i mensis xii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2412068 12 xii 12 12/01/1891 die i mensis xii annoque mdcccxci 91 xci 1891}
+test clock-2.288 {conversion of 1891-12-31} {
+ clock format -2461490704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1891 12:34:56 die xxxi mensis xii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2412098 12 xii 12 12/31/1891 die xxxi mensis xii annoque mdcccxci 91 xci 1891}
+test clock-2.289 {conversion of 1892-01-01} {
+ clock format -2461404304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1892 12:34:56 die i mensis i annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2412099 01 i 1 01/01/1892 die i mensis i annoque mdcccxcii 92 xcii 1892}
+test clock-2.290 {conversion of 1892-01-31} {
+ clock format -2458812304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1892 12:34:56 die xxxi mensis i annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2412129 01 i 1 01/31/1892 die xxxi mensis i annoque mdcccxcii 92 xcii 1892}
+test clock-2.291 {conversion of 1892-02-01} {
+ clock format -2458725904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1892 12:34:56 die i mensis ii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2412130 02 ii 2 02/01/1892 die i mensis ii annoque mdcccxcii 92 xcii 1892}
+test clock-2.292 {conversion of 1892-02-29} {
+ clock format -2456306704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1892 12:34:56 die xxix mensis ii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2412158 02 ii 2 02/29/1892 die xxix mensis ii annoque mdcccxcii 92 xcii 1892}
+test clock-2.293 {conversion of 1892-03-01} {
+ clock format -2456220304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1892 12:34:56 die i mensis iii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 061 2412159 03 iii 3 03/01/1892 die i mensis iii annoque mdcccxcii 92 xcii 1892}
+test clock-2.294 {conversion of 1892-03-31} {
+ clock format -2453628304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1892 12:34:56 die xxxi mensis iii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2412189 03 iii 3 03/31/1892 die xxxi mensis iii annoque mdcccxcii 92 xcii 1892}
+test clock-2.295 {conversion of 1892-04-01} {
+ clock format -2453541904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1892 12:34:56 die i mensis iv annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 092 2412190 04 iv 4 04/01/1892 die i mensis iv annoque mdcccxcii 92 xcii 1892}
+test clock-2.296 {conversion of 1892-04-30} {
+ clock format -2451036304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1892 12:34:56 die xxx mensis iv annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2412219 04 iv 4 04/30/1892 die xxx mensis iv annoque mdcccxcii 92 xcii 1892}
+test clock-2.297 {conversion of 1892-05-01} {
+ clock format -2450949904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1892 12:34:56 die i mensis v annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 122 2412220 05 v 5 05/01/1892 die i mensis v annoque mdcccxcii 92 xcii 1892}
+test clock-2.298 {conversion of 1892-05-31} {
+ clock format -2448357904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1892 12:34:56 die xxxi mensis v annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2412250 05 v 5 05/31/1892 die xxxi mensis v annoque mdcccxcii 92 xcii 1892}
+test clock-2.299 {conversion of 1892-06-01} {
+ clock format -2448271504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1892 12:34:56 die i mensis vi annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 153 2412251 06 vi 6 06/01/1892 die i mensis vi annoque mdcccxcii 92 xcii 1892}
+test clock-2.300 {conversion of 1892-06-30} {
+ clock format -2445765904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1892 12:34:56 die xxx mensis vi annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2412280 06 vi 6 06/30/1892 die xxx mensis vi annoque mdcccxcii 92 xcii 1892}
+test clock-2.301 {conversion of 1892-07-01} {
+ clock format -2445679504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1892 12:34:56 die i mensis vii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 183 2412281 07 vii 7 07/01/1892 die i mensis vii annoque mdcccxcii 92 xcii 1892}
+test clock-2.302 {conversion of 1892-07-31} {
+ clock format -2443087504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1892 12:34:56 die xxxi mensis vii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2412311 07 vii 7 07/31/1892 die xxxi mensis vii annoque mdcccxcii 92 xcii 1892}
+test clock-2.303 {conversion of 1892-08-01} {
+ clock format -2443001104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1892 12:34:56 die i mensis viii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 214 2412312 08 viii 8 08/01/1892 die i mensis viii annoque mdcccxcii 92 xcii 1892}
+test clock-2.304 {conversion of 1892-08-31} {
+ clock format -2440409104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1892 12:34:56 die xxxi mensis viii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2412342 08 viii 8 08/31/1892 die xxxi mensis viii annoque mdcccxcii 92 xcii 1892}
+test clock-2.305 {conversion of 1892-09-01} {
+ clock format -2440322704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1892 12:34:56 die i mensis ix annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 245 2412343 09 ix 9 09/01/1892 die i mensis ix annoque mdcccxcii 92 xcii 1892}
+test clock-2.306 {conversion of 1892-09-30} {
+ clock format -2437817104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1892 12:34:56 die xxx mensis ix annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2412372 09 ix 9 09/30/1892 die xxx mensis ix annoque mdcccxcii 92 xcii 1892}
+test clock-2.307 {conversion of 1892-10-01} {
+ clock format -2437730704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1892 12:34:56 die i mensis x annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 275 2412373 10 x 10 10/01/1892 die i mensis x annoque mdcccxcii 92 xcii 1892}
+test clock-2.308 {conversion of 1892-10-31} {
+ clock format -2435138704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1892 12:34:56 die xxxi mensis x annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2412403 10 x 10 10/31/1892 die xxxi mensis x annoque mdcccxcii 92 xcii 1892}
+test clock-2.309 {conversion of 1892-11-01} {
+ clock format -2435052304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1892 12:34:56 die i mensis xi annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 306 2412404 11 xi 11 11/01/1892 die i mensis xi annoque mdcccxcii 92 xcii 1892}
+test clock-2.310 {conversion of 1892-11-30} {
+ clock format -2432546704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1892 12:34:56 die xxx mensis xi annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2412433 11 xi 11 11/30/1892 die xxx mensis xi annoque mdcccxcii 92 xcii 1892}
+test clock-2.311 {conversion of 1892-12-01} {
+ clock format -2432460304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1892 12:34:56 die i mensis xii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 336 2412434 12 xii 12 12/01/1892 die i mensis xii annoque mdcccxcii 92 xcii 1892}
+test clock-2.312 {conversion of 1892-12-31} {
+ clock format -2429868304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1892 12:34:56 die xxxi mensis xii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2412464 12 xii 12 12/31/1892 die xxxi mensis xii annoque mdcccxcii 92 xcii 1892}
+test clock-2.313 {conversion of 1893-01-01} {
+ clock format -2429781904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1893 12:34:56 die i mensis i annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2412465 01 i 1 01/01/1893 die i mensis i annoque mdcccxciii 93 xciii 1893}
+test clock-2.314 {conversion of 1893-01-31} {
+ clock format -2427189904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1893 12:34:56 die xxxi mensis i annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2412495 01 i 1 01/31/1893 die xxxi mensis i annoque mdcccxciii 93 xciii 1893}
+test clock-2.315 {conversion of 1893-02-01} {
+ clock format -2427103504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1893 12:34:56 die i mensis ii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2412496 02 ii 2 02/01/1893 die i mensis ii annoque mdcccxciii 93 xciii 1893}
+test clock-2.316 {conversion of 1893-02-28} {
+ clock format -2424770704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1893 12:34:56 die xxviii mensis ii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2412523 02 ii 2 02/28/1893 die xxviii mensis ii annoque mdcccxciii 93 xciii 1893}
+test clock-2.317 {conversion of 1893-03-01} {
+ clock format -2424684304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1893 12:34:56 die i mensis iii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2412524 03 iii 3 03/01/1893 die i mensis iii annoque mdcccxciii 93 xciii 1893}
+test clock-2.318 {conversion of 1893-03-31} {
+ clock format -2422092304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1893 12:34:56 die xxxi mensis iii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2412554 03 iii 3 03/31/1893 die xxxi mensis iii annoque mdcccxciii 93 xciii 1893}
+test clock-2.319 {conversion of 1893-04-01} {
+ clock format -2422005904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1893 12:34:56 die i mensis iv annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2412555 04 iv 4 04/01/1893 die i mensis iv annoque mdcccxciii 93 xciii 1893}
+test clock-2.320 {conversion of 1893-04-30} {
+ clock format -2419500304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1893 12:34:56 die xxx mensis iv annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2412584 04 iv 4 04/30/1893 die xxx mensis iv annoque mdcccxciii 93 xciii 1893}
+test clock-2.321 {conversion of 1893-05-01} {
+ clock format -2419413904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1893 12:34:56 die i mensis v annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2412585 05 v 5 05/01/1893 die i mensis v annoque mdcccxciii 93 xciii 1893}
+test clock-2.322 {conversion of 1893-05-31} {
+ clock format -2416821904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1893 12:34:56 die xxxi mensis v annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2412615 05 v 5 05/31/1893 die xxxi mensis v annoque mdcccxciii 93 xciii 1893}
+test clock-2.323 {conversion of 1893-06-01} {
+ clock format -2416735504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1893 12:34:56 die i mensis vi annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2412616 06 vi 6 06/01/1893 die i mensis vi annoque mdcccxciii 93 xciii 1893}
+test clock-2.324 {conversion of 1893-06-30} {
+ clock format -2414229904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1893 12:34:56 die xxx mensis vi annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2412645 06 vi 6 06/30/1893 die xxx mensis vi annoque mdcccxciii 93 xciii 1893}
+test clock-2.325 {conversion of 1893-07-01} {
+ clock format -2414143504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1893 12:34:56 die i mensis vii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2412646 07 vii 7 07/01/1893 die i mensis vii annoque mdcccxciii 93 xciii 1893}
+test clock-2.326 {conversion of 1893-07-31} {
+ clock format -2411551504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1893 12:34:56 die xxxi mensis vii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2412676 07 vii 7 07/31/1893 die xxxi mensis vii annoque mdcccxciii 93 xciii 1893}
+test clock-2.327 {conversion of 1893-08-01} {
+ clock format -2411465104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1893 12:34:56 die i mensis viii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2412677 08 viii 8 08/01/1893 die i mensis viii annoque mdcccxciii 93 xciii 1893}
+test clock-2.328 {conversion of 1893-08-31} {
+ clock format -2408873104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1893 12:34:56 die xxxi mensis viii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2412707 08 viii 8 08/31/1893 die xxxi mensis viii annoque mdcccxciii 93 xciii 1893}
+test clock-2.329 {conversion of 1893-09-01} {
+ clock format -2408786704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1893 12:34:56 die i mensis ix annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2412708 09 ix 9 09/01/1893 die i mensis ix annoque mdcccxciii 93 xciii 1893}
+test clock-2.330 {conversion of 1893-09-30} {
+ clock format -2406281104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1893 12:34:56 die xxx mensis ix annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2412737 09 ix 9 09/30/1893 die xxx mensis ix annoque mdcccxciii 93 xciii 1893}
+test clock-2.331 {conversion of 1893-10-01} {
+ clock format -2406194704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1893 12:34:56 die i mensis x annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2412738 10 x 10 10/01/1893 die i mensis x annoque mdcccxciii 93 xciii 1893}
+test clock-2.332 {conversion of 1893-10-31} {
+ clock format -2403602704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1893 12:34:56 die xxxi mensis x annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2412768 10 x 10 10/31/1893 die xxxi mensis x annoque mdcccxciii 93 xciii 1893}
+test clock-2.333 {conversion of 1893-11-01} {
+ clock format -2403516304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1893 12:34:56 die i mensis xi annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2412769 11 xi 11 11/01/1893 die i mensis xi annoque mdcccxciii 93 xciii 1893}
+test clock-2.334 {conversion of 1893-11-30} {
+ clock format -2401010704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1893 12:34:56 die xxx mensis xi annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2412798 11 xi 11 11/30/1893 die xxx mensis xi annoque mdcccxciii 93 xciii 1893}
+test clock-2.335 {conversion of 1893-12-01} {
+ clock format -2400924304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1893 12:34:56 die i mensis xii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2412799 12 xii 12 12/01/1893 die i mensis xii annoque mdcccxciii 93 xciii 1893}
+test clock-2.336 {conversion of 1893-12-31} {
+ clock format -2398332304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1893 12:34:56 die xxxi mensis xii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2412829 12 xii 12 12/31/1893 die xxxi mensis xii annoque mdcccxciii 93 xciii 1893}
+test clock-2.337 {conversion of 1894-01-01} {
+ clock format -2398245904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1894 12:34:56 die i mensis i annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2412830 01 i 1 01/01/1894 die i mensis i annoque mdcccxciv 94 xciv 1894}
+test clock-2.338 {conversion of 1894-01-31} {
+ clock format -2395653904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1894 12:34:56 die xxxi mensis i annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2412860 01 i 1 01/31/1894 die xxxi mensis i annoque mdcccxciv 94 xciv 1894}
+test clock-2.339 {conversion of 1894-02-01} {
+ clock format -2395567504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1894 12:34:56 die i mensis ii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2412861 02 ii 2 02/01/1894 die i mensis ii annoque mdcccxciv 94 xciv 1894}
+test clock-2.340 {conversion of 1894-02-28} {
+ clock format -2393234704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1894 12:34:56 die xxviii mensis ii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2412888 02 ii 2 02/28/1894 die xxviii mensis ii annoque mdcccxciv 94 xciv 1894}
+test clock-2.341 {conversion of 1894-03-01} {
+ clock format -2393148304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1894 12:34:56 die i mensis iii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2412889 03 iii 3 03/01/1894 die i mensis iii annoque mdcccxciv 94 xciv 1894}
+test clock-2.342 {conversion of 1894-03-31} {
+ clock format -2390556304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1894 12:34:56 die xxxi mensis iii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2412919 03 iii 3 03/31/1894 die xxxi mensis iii annoque mdcccxciv 94 xciv 1894}
+test clock-2.343 {conversion of 1894-04-01} {
+ clock format -2390469904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1894 12:34:56 die i mensis iv annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2412920 04 iv 4 04/01/1894 die i mensis iv annoque mdcccxciv 94 xciv 1894}
+test clock-2.344 {conversion of 1894-04-30} {
+ clock format -2387964304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1894 12:34:56 die xxx mensis iv annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2412949 04 iv 4 04/30/1894 die xxx mensis iv annoque mdcccxciv 94 xciv 1894}
+test clock-2.345 {conversion of 1894-05-01} {
+ clock format -2387877904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1894 12:34:56 die i mensis v annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2412950 05 v 5 05/01/1894 die i mensis v annoque mdcccxciv 94 xciv 1894}
+test clock-2.346 {conversion of 1894-05-31} {
+ clock format -2385285904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1894 12:34:56 die xxxi mensis v annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2412980 05 v 5 05/31/1894 die xxxi mensis v annoque mdcccxciv 94 xciv 1894}
+test clock-2.347 {conversion of 1894-06-01} {
+ clock format -2385199504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1894 12:34:56 die i mensis vi annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2412981 06 vi 6 06/01/1894 die i mensis vi annoque mdcccxciv 94 xciv 1894}
+test clock-2.348 {conversion of 1894-06-30} {
+ clock format -2382693904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1894 12:34:56 die xxx mensis vi annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2413010 06 vi 6 06/30/1894 die xxx mensis vi annoque mdcccxciv 94 xciv 1894}
+test clock-2.349 {conversion of 1894-07-01} {
+ clock format -2382607504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1894 12:34:56 die i mensis vii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2413011 07 vii 7 07/01/1894 die i mensis vii annoque mdcccxciv 94 xciv 1894}
+test clock-2.350 {conversion of 1894-07-31} {
+ clock format -2380015504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1894 12:34:56 die xxxi mensis vii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2413041 07 vii 7 07/31/1894 die xxxi mensis vii annoque mdcccxciv 94 xciv 1894}
+test clock-2.351 {conversion of 1894-08-01} {
+ clock format -2379929104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1894 12:34:56 die i mensis viii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2413042 08 viii 8 08/01/1894 die i mensis viii annoque mdcccxciv 94 xciv 1894}
+test clock-2.352 {conversion of 1894-08-31} {
+ clock format -2377337104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1894 12:34:56 die xxxi mensis viii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2413072 08 viii 8 08/31/1894 die xxxi mensis viii annoque mdcccxciv 94 xciv 1894}
+test clock-2.353 {conversion of 1894-09-01} {
+ clock format -2377250704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1894 12:34:56 die i mensis ix annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2413073 09 ix 9 09/01/1894 die i mensis ix annoque mdcccxciv 94 xciv 1894}
+test clock-2.354 {conversion of 1894-09-30} {
+ clock format -2374745104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1894 12:34:56 die xxx mensis ix annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2413102 09 ix 9 09/30/1894 die xxx mensis ix annoque mdcccxciv 94 xciv 1894}
+test clock-2.355 {conversion of 1894-10-01} {
+ clock format -2374658704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1894 12:34:56 die i mensis x annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2413103 10 x 10 10/01/1894 die i mensis x annoque mdcccxciv 94 xciv 1894}
+test clock-2.356 {conversion of 1894-10-31} {
+ clock format -2372066704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1894 12:34:56 die xxxi mensis x annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2413133 10 x 10 10/31/1894 die xxxi mensis x annoque mdcccxciv 94 xciv 1894}
+test clock-2.357 {conversion of 1894-11-01} {
+ clock format -2371980304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1894 12:34:56 die i mensis xi annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2413134 11 xi 11 11/01/1894 die i mensis xi annoque mdcccxciv 94 xciv 1894}
+test clock-2.358 {conversion of 1894-11-30} {
+ clock format -2369474704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1894 12:34:56 die xxx mensis xi annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2413163 11 xi 11 11/30/1894 die xxx mensis xi annoque mdcccxciv 94 xciv 1894}
+test clock-2.359 {conversion of 1894-12-01} {
+ clock format -2369388304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1894 12:34:56 die i mensis xii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2413164 12 xii 12 12/01/1894 die i mensis xii annoque mdcccxciv 94 xciv 1894}
+test clock-2.360 {conversion of 1894-12-31} {
+ clock format -2366796304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1894 12:34:56 die xxxi mensis xii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2413194 12 xii 12 12/31/1894 die xxxi mensis xii annoque mdcccxciv 94 xciv 1894}
+test clock-2.361 {conversion of 1895-01-01} {
+ clock format -2366709904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1895 12:34:56 die i mensis i annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2413195 01 i 1 01/01/1895 die i mensis i annoque mdcccxcv 95 xcv 1895}
+test clock-2.362 {conversion of 1895-01-31} {
+ clock format -2364117904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1895 12:34:56 die xxxi mensis i annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2413225 01 i 1 01/31/1895 die xxxi mensis i annoque mdcccxcv 95 xcv 1895}
+test clock-2.363 {conversion of 1895-02-01} {
+ clock format -2364031504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1895 12:34:56 die i mensis ii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2413226 02 ii 2 02/01/1895 die i mensis ii annoque mdcccxcv 95 xcv 1895}
+test clock-2.364 {conversion of 1895-02-28} {
+ clock format -2361698704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1895 12:34:56 die xxviii mensis ii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2413253 02 ii 2 02/28/1895 die xxviii mensis ii annoque mdcccxcv 95 xcv 1895}
+test clock-2.365 {conversion of 1895-03-01} {
+ clock format -2361612304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1895 12:34:56 die i mensis iii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2413254 03 iii 3 03/01/1895 die i mensis iii annoque mdcccxcv 95 xcv 1895}
+test clock-2.366 {conversion of 1895-03-31} {
+ clock format -2359020304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1895 12:34:56 die xxxi mensis iii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2413284 03 iii 3 03/31/1895 die xxxi mensis iii annoque mdcccxcv 95 xcv 1895}
+test clock-2.367 {conversion of 1895-04-01} {
+ clock format -2358933904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1895 12:34:56 die i mensis iv annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2413285 04 iv 4 04/01/1895 die i mensis iv annoque mdcccxcv 95 xcv 1895}
+test clock-2.368 {conversion of 1895-04-30} {
+ clock format -2356428304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1895 12:34:56 die xxx mensis iv annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2413314 04 iv 4 04/30/1895 die xxx mensis iv annoque mdcccxcv 95 xcv 1895}
+test clock-2.369 {conversion of 1895-05-01} {
+ clock format -2356341904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1895 12:34:56 die i mensis v annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2413315 05 v 5 05/01/1895 die i mensis v annoque mdcccxcv 95 xcv 1895}
+test clock-2.370 {conversion of 1895-05-31} {
+ clock format -2353749904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1895 12:34:56 die xxxi mensis v annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2413345 05 v 5 05/31/1895 die xxxi mensis v annoque mdcccxcv 95 xcv 1895}
+test clock-2.371 {conversion of 1895-06-01} {
+ clock format -2353663504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1895 12:34:56 die i mensis vi annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2413346 06 vi 6 06/01/1895 die i mensis vi annoque mdcccxcv 95 xcv 1895}
+test clock-2.372 {conversion of 1895-06-30} {
+ clock format -2351157904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1895 12:34:56 die xxx mensis vi annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2413375 06 vi 6 06/30/1895 die xxx mensis vi annoque mdcccxcv 95 xcv 1895}
+test clock-2.373 {conversion of 1895-07-01} {
+ clock format -2351071504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1895 12:34:56 die i mensis vii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2413376 07 vii 7 07/01/1895 die i mensis vii annoque mdcccxcv 95 xcv 1895}
+test clock-2.374 {conversion of 1895-07-31} {
+ clock format -2348479504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1895 12:34:56 die xxxi mensis vii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2413406 07 vii 7 07/31/1895 die xxxi mensis vii annoque mdcccxcv 95 xcv 1895}
+test clock-2.375 {conversion of 1895-08-01} {
+ clock format -2348393104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1895 12:34:56 die i mensis viii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2413407 08 viii 8 08/01/1895 die i mensis viii annoque mdcccxcv 95 xcv 1895}
+test clock-2.376 {conversion of 1895-08-31} {
+ clock format -2345801104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1895 12:34:56 die xxxi mensis viii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2413437 08 viii 8 08/31/1895 die xxxi mensis viii annoque mdcccxcv 95 xcv 1895}
+test clock-2.377 {conversion of 1895-09-01} {
+ clock format -2345714704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1895 12:34:56 die i mensis ix annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2413438 09 ix 9 09/01/1895 die i mensis ix annoque mdcccxcv 95 xcv 1895}
+test clock-2.378 {conversion of 1895-09-30} {
+ clock format -2343209104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1895 12:34:56 die xxx mensis ix annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2413467 09 ix 9 09/30/1895 die xxx mensis ix annoque mdcccxcv 95 xcv 1895}
+test clock-2.379 {conversion of 1895-10-01} {
+ clock format -2343122704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1895 12:34:56 die i mensis x annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2413468 10 x 10 10/01/1895 die i mensis x annoque mdcccxcv 95 xcv 1895}
+test clock-2.380 {conversion of 1895-10-31} {
+ clock format -2340530704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1895 12:34:56 die xxxi mensis x annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2413498 10 x 10 10/31/1895 die xxxi mensis x annoque mdcccxcv 95 xcv 1895}
+test clock-2.381 {conversion of 1895-11-01} {
+ clock format -2340444304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1895 12:34:56 die i mensis xi annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2413499 11 xi 11 11/01/1895 die i mensis xi annoque mdcccxcv 95 xcv 1895}
+test clock-2.382 {conversion of 1895-11-30} {
+ clock format -2337938704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1895 12:34:56 die xxx mensis xi annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2413528 11 xi 11 11/30/1895 die xxx mensis xi annoque mdcccxcv 95 xcv 1895}
+test clock-2.383 {conversion of 1895-12-01} {
+ clock format -2337852304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1895 12:34:56 die i mensis xii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2413529 12 xii 12 12/01/1895 die i mensis xii annoque mdcccxcv 95 xcv 1895}
+test clock-2.384 {conversion of 1895-12-31} {
+ clock format -2335260304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1895 12:34:56 die xxxi mensis xii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2413559 12 xii 12 12/31/1895 die xxxi mensis xii annoque mdcccxcv 95 xcv 1895}
+test clock-2.385 {conversion of 1896-01-01} {
+ clock format -2335173904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1896 12:34:56 die i mensis i annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2413560 01 i 1 01/01/1896 die i mensis i annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.386 {conversion of 1896-01-31} {
+ clock format -2332581904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1896 12:34:56 die xxxi mensis i annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2413590 01 i 1 01/31/1896 die xxxi mensis i annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.387 {conversion of 1896-02-01} {
+ clock format -2332495504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1896 12:34:56 die i mensis ii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2413591 02 ii 2 02/01/1896 die i mensis ii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.388 {conversion of 1896-02-29} {
+ clock format -2330076304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1896 12:34:56 die xxix mensis ii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2413619 02 ii 2 02/29/1896 die xxix mensis ii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.389 {conversion of 1896-03-01} {
+ clock format -2329989904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1896 12:34:56 die i mensis iii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 061 2413620 03 iii 3 03/01/1896 die i mensis iii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.390 {conversion of 1896-03-31} {
+ clock format -2327397904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1896 12:34:56 die xxxi mensis iii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2413650 03 iii 3 03/31/1896 die xxxi mensis iii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.391 {conversion of 1896-04-01} {
+ clock format -2327311504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1896 12:34:56 die i mensis iv annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 092 2413651 04 iv 4 04/01/1896 die i mensis iv annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.392 {conversion of 1896-04-30} {
+ clock format -2324805904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1896 12:34:56 die xxx mensis iv annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2413680 04 iv 4 04/30/1896 die xxx mensis iv annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.393 {conversion of 1896-05-01} {
+ clock format -2324719504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1896 12:34:56 die i mensis v annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 122 2413681 05 v 5 05/01/1896 die i mensis v annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.394 {conversion of 1896-05-31} {
+ clock format -2322127504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1896 12:34:56 die xxxi mensis v annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2413711 05 v 5 05/31/1896 die xxxi mensis v annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.395 {conversion of 1896-06-01} {
+ clock format -2322041104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1896 12:34:56 die i mensis vi annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 153 2413712 06 vi 6 06/01/1896 die i mensis vi annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.396 {conversion of 1896-06-30} {
+ clock format -2319535504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1896 12:34:56 die xxx mensis vi annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2413741 06 vi 6 06/30/1896 die xxx mensis vi annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.397 {conversion of 1896-07-01} {
+ clock format -2319449104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1896 12:34:56 die i mensis vii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 183 2413742 07 vii 7 07/01/1896 die i mensis vii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.398 {conversion of 1896-07-31} {
+ clock format -2316857104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1896 12:34:56 die xxxi mensis vii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2413772 07 vii 7 07/31/1896 die xxxi mensis vii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.399 {conversion of 1896-08-01} {
+ clock format -2316770704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1896 12:34:56 die i mensis viii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 214 2413773 08 viii 8 08/01/1896 die i mensis viii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.400 {conversion of 1896-08-31} {
+ clock format -2314178704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1896 12:34:56 die xxxi mensis viii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2413803 08 viii 8 08/31/1896 die xxxi mensis viii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.401 {conversion of 1896-09-01} {
+ clock format -2314092304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1896 12:34:56 die i mensis ix annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 245 2413804 09 ix 9 09/01/1896 die i mensis ix annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.402 {conversion of 1896-09-30} {
+ clock format -2311586704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1896 12:34:56 die xxx mensis ix annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2413833 09 ix 9 09/30/1896 die xxx mensis ix annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.403 {conversion of 1896-10-01} {
+ clock format -2311500304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1896 12:34:56 die i mensis x annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 275 2413834 10 x 10 10/01/1896 die i mensis x annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.404 {conversion of 1896-10-31} {
+ clock format -2308908304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1896 12:34:56 die xxxi mensis x annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2413864 10 x 10 10/31/1896 die xxxi mensis x annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.405 {conversion of 1896-11-01} {
+ clock format -2308821904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1896 12:34:56 die i mensis xi annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 306 2413865 11 xi 11 11/01/1896 die i mensis xi annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.406 {conversion of 1896-11-30} {
+ clock format -2306316304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1896 12:34:56 die xxx mensis xi annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2413894 11 xi 11 11/30/1896 die xxx mensis xi annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.407 {conversion of 1896-12-01} {
+ clock format -2306229904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1896 12:34:56 die i mensis xii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 336 2413895 12 xii 12 12/01/1896 die i mensis xii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.408 {conversion of 1896-12-31} {
+ clock format -2303637904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1896 12:34:56 die xxxi mensis xii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2413925 12 xii 12 12/31/1896 die xxxi mensis xii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.409 {conversion of 1897-01-01} {
+ clock format -2303551504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1897 12:34:56 die i mensis i annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2413926 01 i 1 01/01/1897 die i mensis i annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.410 {conversion of 1897-01-31} {
+ clock format -2300959504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1897 12:34:56 die xxxi mensis i annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2413956 01 i 1 01/31/1897 die xxxi mensis i annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.411 {conversion of 1897-02-01} {
+ clock format -2300873104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1897 12:34:56 die i mensis ii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2413957 02 ii 2 02/01/1897 die i mensis ii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.412 {conversion of 1897-02-28} {
+ clock format -2298540304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1897 12:34:56 die xxviii mensis ii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2413984 02 ii 2 02/28/1897 die xxviii mensis ii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.413 {conversion of 1897-03-01} {
+ clock format -2298453904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1897 12:34:56 die i mensis iii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2413985 03 iii 3 03/01/1897 die i mensis iii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.414 {conversion of 1897-03-31} {
+ clock format -2295861904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1897 12:34:56 die xxxi mensis iii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2414015 03 iii 3 03/31/1897 die xxxi mensis iii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.415 {conversion of 1897-04-01} {
+ clock format -2295775504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1897 12:34:56 die i mensis iv annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2414016 04 iv 4 04/01/1897 die i mensis iv annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.416 {conversion of 1897-04-30} {
+ clock format -2293269904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1897 12:34:56 die xxx mensis iv annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2414045 04 iv 4 04/30/1897 die xxx mensis iv annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.417 {conversion of 1897-05-01} {
+ clock format -2293183504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1897 12:34:56 die i mensis v annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2414046 05 v 5 05/01/1897 die i mensis v annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.418 {conversion of 1897-05-31} {
+ clock format -2290591504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1897 12:34:56 die xxxi mensis v annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2414076 05 v 5 05/31/1897 die xxxi mensis v annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.419 {conversion of 1897-06-01} {
+ clock format -2290505104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1897 12:34:56 die i mensis vi annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2414077 06 vi 6 06/01/1897 die i mensis vi annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.420 {conversion of 1897-06-30} {
+ clock format -2287999504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1897 12:34:56 die xxx mensis vi annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2414106 06 vi 6 06/30/1897 die xxx mensis vi annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.421 {conversion of 1897-07-01} {
+ clock format -2287913104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1897 12:34:56 die i mensis vii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2414107 07 vii 7 07/01/1897 die i mensis vii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.422 {conversion of 1897-07-31} {
+ clock format -2285321104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1897 12:34:56 die xxxi mensis vii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2414137 07 vii 7 07/31/1897 die xxxi mensis vii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.423 {conversion of 1897-08-01} {
+ clock format -2285234704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1897 12:34:56 die i mensis viii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2414138 08 viii 8 08/01/1897 die i mensis viii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.424 {conversion of 1897-08-31} {
+ clock format -2282642704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1897 12:34:56 die xxxi mensis viii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2414168 08 viii 8 08/31/1897 die xxxi mensis viii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.425 {conversion of 1897-09-01} {
+ clock format -2282556304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1897 12:34:56 die i mensis ix annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2414169 09 ix 9 09/01/1897 die i mensis ix annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.426 {conversion of 1897-09-30} {
+ clock format -2280050704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1897 12:34:56 die xxx mensis ix annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2414198 09 ix 9 09/30/1897 die xxx mensis ix annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.427 {conversion of 1897-10-01} {
+ clock format -2279964304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1897 12:34:56 die i mensis x annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2414199 10 x 10 10/01/1897 die i mensis x annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.428 {conversion of 1897-10-31} {
+ clock format -2277372304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1897 12:34:56 die xxxi mensis x annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2414229 10 x 10 10/31/1897 die xxxi mensis x annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.429 {conversion of 1897-11-01} {
+ clock format -2277285904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1897 12:34:56 die i mensis xi annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2414230 11 xi 11 11/01/1897 die i mensis xi annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.430 {conversion of 1897-11-30} {
+ clock format -2274780304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1897 12:34:56 die xxx mensis xi annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2414259 11 xi 11 11/30/1897 die xxx mensis xi annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.431 {conversion of 1897-12-01} {
+ clock format -2274693904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1897 12:34:56 die i mensis xii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2414260 12 xii 12 12/01/1897 die i mensis xii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.432 {conversion of 1897-12-31} {
+ clock format -2272101904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1897 12:34:56 die xxxi mensis xii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2414290 12 xii 12 12/31/1897 die xxxi mensis xii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.433 {conversion of 1898-01-01} {
+ clock format -2272015504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1898 12:34:56 die i mensis i annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2414291 01 i 1 01/01/1898 die i mensis i annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.434 {conversion of 1898-01-31} {
+ clock format -2269423504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1898 12:34:56 die xxxi mensis i annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2414321 01 i 1 01/31/1898 die xxxi mensis i annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.435 {conversion of 1898-02-01} {
+ clock format -2269337104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1898 12:34:56 die i mensis ii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2414322 02 ii 2 02/01/1898 die i mensis ii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.436 {conversion of 1898-02-28} {
+ clock format -2267004304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1898 12:34:56 die xxviii mensis ii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2414349 02 ii 2 02/28/1898 die xxviii mensis ii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.437 {conversion of 1898-03-01} {
+ clock format -2266917904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1898 12:34:56 die i mensis iii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2414350 03 iii 3 03/01/1898 die i mensis iii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.438 {conversion of 1898-03-31} {
+ clock format -2264325904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1898 12:34:56 die xxxi mensis iii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2414380 03 iii 3 03/31/1898 die xxxi mensis iii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.439 {conversion of 1898-04-01} {
+ clock format -2264239504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1898 12:34:56 die i mensis iv annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2414381 04 iv 4 04/01/1898 die i mensis iv annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.440 {conversion of 1898-04-30} {
+ clock format -2261733904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1898 12:34:56 die xxx mensis iv annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2414410 04 iv 4 04/30/1898 die xxx mensis iv annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.441 {conversion of 1898-05-01} {
+ clock format -2261647504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1898 12:34:56 die i mensis v annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2414411 05 v 5 05/01/1898 die i mensis v annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.442 {conversion of 1898-05-31} {
+ clock format -2259055504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1898 12:34:56 die xxxi mensis v annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2414441 05 v 5 05/31/1898 die xxxi mensis v annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.443 {conversion of 1898-06-01} {
+ clock format -2258969104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1898 12:34:56 die i mensis vi annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2414442 06 vi 6 06/01/1898 die i mensis vi annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.444 {conversion of 1898-06-30} {
+ clock format -2256463504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1898 12:34:56 die xxx mensis vi annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2414471 06 vi 6 06/30/1898 die xxx mensis vi annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.445 {conversion of 1898-07-01} {
+ clock format -2256377104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1898 12:34:56 die i mensis vii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2414472 07 vii 7 07/01/1898 die i mensis vii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.446 {conversion of 1898-07-31} {
+ clock format -2253785104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1898 12:34:56 die xxxi mensis vii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2414502 07 vii 7 07/31/1898 die xxxi mensis vii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.447 {conversion of 1898-08-01} {
+ clock format -2253698704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1898 12:34:56 die i mensis viii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2414503 08 viii 8 08/01/1898 die i mensis viii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.448 {conversion of 1898-08-31} {
+ clock format -2251106704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1898 12:34:56 die xxxi mensis viii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2414533 08 viii 8 08/31/1898 die xxxi mensis viii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.449 {conversion of 1898-09-01} {
+ clock format -2251020304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1898 12:34:56 die i mensis ix annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2414534 09 ix 9 09/01/1898 die i mensis ix annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.450 {conversion of 1898-09-30} {
+ clock format -2248514704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1898 12:34:56 die xxx mensis ix annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2414563 09 ix 9 09/30/1898 die xxx mensis ix annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.451 {conversion of 1898-10-01} {
+ clock format -2248428304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1898 12:34:56 die i mensis x annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2414564 10 x 10 10/01/1898 die i mensis x annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.452 {conversion of 1898-10-31} {
+ clock format -2245836304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1898 12:34:56 die xxxi mensis x annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2414594 10 x 10 10/31/1898 die xxxi mensis x annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.453 {conversion of 1898-11-01} {
+ clock format -2245749904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1898 12:34:56 die i mensis xi annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2414595 11 xi 11 11/01/1898 die i mensis xi annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.454 {conversion of 1898-11-30} {
+ clock format -2243244304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1898 12:34:56 die xxx mensis xi annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2414624 11 xi 11 11/30/1898 die xxx mensis xi annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.455 {conversion of 1898-12-01} {
+ clock format -2243157904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1898 12:34:56 die i mensis xii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2414625 12 xii 12 12/01/1898 die i mensis xii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.456 {conversion of 1898-12-31} {
+ clock format -2240565904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1898 12:34:56 die xxxi mensis xii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2414655 12 xii 12 12/31/1898 die xxxi mensis xii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.457 {conversion of 1899-01-01} {
+ clock format -2240479504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1899 12:34:56 die i mensis i annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2414656 01 i 1 01/01/1899 die i mensis i annoque mdcccxcix 99 xcix 1899}
+test clock-2.458 {conversion of 1899-01-31} {
+ clock format -2237887504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1899 12:34:56 die xxxi mensis i annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2414686 01 i 1 01/31/1899 die xxxi mensis i annoque mdcccxcix 99 xcix 1899}
+test clock-2.459 {conversion of 1899-02-01} {
+ clock format -2237801104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1899 12:34:56 die i mensis ii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2414687 02 ii 2 02/01/1899 die i mensis ii annoque mdcccxcix 99 xcix 1899}
+test clock-2.460 {conversion of 1899-02-28} {
+ clock format -2235468304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1899 12:34:56 die xxviii mensis ii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2414714 02 ii 2 02/28/1899 die xxviii mensis ii annoque mdcccxcix 99 xcix 1899}
+test clock-2.461 {conversion of 1899-03-01} {
+ clock format -2235381904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1899 12:34:56 die i mensis iii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2414715 03 iii 3 03/01/1899 die i mensis iii annoque mdcccxcix 99 xcix 1899}
+test clock-2.462 {conversion of 1899-03-31} {
+ clock format -2232789904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1899 12:34:56 die xxxi mensis iii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2414745 03 iii 3 03/31/1899 die xxxi mensis iii annoque mdcccxcix 99 xcix 1899}
+test clock-2.463 {conversion of 1899-04-01} {
+ clock format -2232703504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1899 12:34:56 die i mensis iv annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2414746 04 iv 4 04/01/1899 die i mensis iv annoque mdcccxcix 99 xcix 1899}
+test clock-2.464 {conversion of 1899-04-30} {
+ clock format -2230197904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1899 12:34:56 die xxx mensis iv annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2414775 04 iv 4 04/30/1899 die xxx mensis iv annoque mdcccxcix 99 xcix 1899}
+test clock-2.465 {conversion of 1899-05-01} {
+ clock format -2230111504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1899 12:34:56 die i mensis v annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2414776 05 v 5 05/01/1899 die i mensis v annoque mdcccxcix 99 xcix 1899}
+test clock-2.466 {conversion of 1899-05-31} {
+ clock format -2227519504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1899 12:34:56 die xxxi mensis v annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2414806 05 v 5 05/31/1899 die xxxi mensis v annoque mdcccxcix 99 xcix 1899}
+test clock-2.467 {conversion of 1899-06-01} {
+ clock format -2227433104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1899 12:34:56 die i mensis vi annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2414807 06 vi 6 06/01/1899 die i mensis vi annoque mdcccxcix 99 xcix 1899}
+test clock-2.468 {conversion of 1899-06-30} {
+ clock format -2224927504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1899 12:34:56 die xxx mensis vi annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2414836 06 vi 6 06/30/1899 die xxx mensis vi annoque mdcccxcix 99 xcix 1899}
+test clock-2.469 {conversion of 1899-07-01} {
+ clock format -2224841104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1899 12:34:56 die i mensis vii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2414837 07 vii 7 07/01/1899 die i mensis vii annoque mdcccxcix 99 xcix 1899}
+test clock-2.470 {conversion of 1899-07-31} {
+ clock format -2222249104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1899 12:34:56 die xxxi mensis vii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2414867 07 vii 7 07/31/1899 die xxxi mensis vii annoque mdcccxcix 99 xcix 1899}
+test clock-2.471 {conversion of 1899-08-01} {
+ clock format -2222162704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1899 12:34:56 die i mensis viii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2414868 08 viii 8 08/01/1899 die i mensis viii annoque mdcccxcix 99 xcix 1899}
+test clock-2.472 {conversion of 1899-08-31} {
+ clock format -2219570704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1899 12:34:56 die xxxi mensis viii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2414898 08 viii 8 08/31/1899 die xxxi mensis viii annoque mdcccxcix 99 xcix 1899}
+test clock-2.473 {conversion of 1899-09-01} {
+ clock format -2219484304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1899 12:34:56 die i mensis ix annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2414899 09 ix 9 09/01/1899 die i mensis ix annoque mdcccxcix 99 xcix 1899}
+test clock-2.474 {conversion of 1899-09-30} {
+ clock format -2216978704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1899 12:34:56 die xxx mensis ix annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2414928 09 ix 9 09/30/1899 die xxx mensis ix annoque mdcccxcix 99 xcix 1899}
+test clock-2.475 {conversion of 1899-10-01} {
+ clock format -2216892304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1899 12:34:56 die i mensis x annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2414929 10 x 10 10/01/1899 die i mensis x annoque mdcccxcix 99 xcix 1899}
+test clock-2.476 {conversion of 1899-10-31} {
+ clock format -2214300304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1899 12:34:56 die xxxi mensis x annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2414959 10 x 10 10/31/1899 die xxxi mensis x annoque mdcccxcix 99 xcix 1899}
+test clock-2.477 {conversion of 1899-11-01} {
+ clock format -2214213904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1899 12:34:56 die i mensis xi annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2414960 11 xi 11 11/01/1899 die i mensis xi annoque mdcccxcix 99 xcix 1899}
+test clock-2.478 {conversion of 1899-11-30} {
+ clock format -2211708304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1899 12:34:56 die xxx mensis xi annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2414989 11 xi 11 11/30/1899 die xxx mensis xi annoque mdcccxcix 99 xcix 1899}
+test clock-2.479 {conversion of 1899-12-01} {
+ clock format -2211621904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1899 12:34:56 die i mensis xii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2414990 12 xii 12 12/01/1899 die i mensis xii annoque mdcccxcix 99 xcix 1899}
+test clock-2.480 {conversion of 1899-12-31} {
+ clock format -2209029904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1899 12:34:56 die xxxi mensis xii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2415020 12 xii 12 12/31/1899 die xxxi mensis xii annoque mdcccxcix 99 xcix 1899}
+test clock-2.481 {conversion of 1900-01-01} {
+ clock format -2208943504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1900 12:34:56 die i mensis i annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2415021 01 i 1 01/01/1900 die i mensis i annoque mcm? 00 ? 1900}
+test clock-2.482 {conversion of 1900-01-31} {
+ clock format -2206351504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1900 12:34:56 die xxxi mensis i annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2415051 01 i 1 01/31/1900 die xxxi mensis i annoque mcm? 00 ? 1900}
+test clock-2.483 {conversion of 1900-02-01} {
+ clock format -2206265104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1900 12:34:56 die i mensis ii annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2415052 02 ii 2 02/01/1900 die i mensis ii annoque mcm? 00 ? 1900}
+test clock-2.484 {conversion of 1900-02-28} {
+ clock format -2203932304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1900 12:34:56 die xxviii mensis ii annoque mcm? xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2415079 02 ii 2 02/28/1900 die xxviii mensis ii annoque mcm? 00 ? 1900}
+test clock-2.485 {conversion of 1900-03-01} {
+ clock format -2203845904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1900 12:34:56 die i mensis iii annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2415080 03 iii 3 03/01/1900 die i mensis iii annoque mcm? 00 ? 1900}
+test clock-2.486 {conversion of 1900-03-31} {
+ clock format -2201253904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1900 12:34:56 die xxxi mensis iii annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2415110 03 iii 3 03/31/1900 die xxxi mensis iii annoque mcm? 00 ? 1900}
+test clock-2.487 {conversion of 1900-04-01} {
+ clock format -2201167504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1900 12:34:56 die i mensis iv annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2415111 04 iv 4 04/01/1900 die i mensis iv annoque mcm? 00 ? 1900}
+test clock-2.488 {conversion of 1900-04-30} {
+ clock format -2198661904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1900 12:34:56 die xxx mensis iv annoque mcm? xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2415140 04 iv 4 04/30/1900 die xxx mensis iv annoque mcm? 00 ? 1900}
+test clock-2.489 {conversion of 1900-05-01} {
+ clock format -2198575504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1900 12:34:56 die i mensis v annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2415141 05 v 5 05/01/1900 die i mensis v annoque mcm? 00 ? 1900}
+test clock-2.490 {conversion of 1900-05-31} {
+ clock format -2195983504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1900 12:34:56 die xxxi mensis v annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2415171 05 v 5 05/31/1900 die xxxi mensis v annoque mcm? 00 ? 1900}
+test clock-2.491 {conversion of 1900-06-01} {
+ clock format -2195897104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1900 12:34:56 die i mensis vi annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2415172 06 vi 6 06/01/1900 die i mensis vi annoque mcm? 00 ? 1900}
+test clock-2.492 {conversion of 1900-06-30} {
+ clock format -2193391504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1900 12:34:56 die xxx mensis vi annoque mcm? xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2415201 06 vi 6 06/30/1900 die xxx mensis vi annoque mcm? 00 ? 1900}
+test clock-2.493 {conversion of 1900-07-01} {
+ clock format -2193305104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1900 12:34:56 die i mensis vii annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2415202 07 vii 7 07/01/1900 die i mensis vii annoque mcm? 00 ? 1900}
+test clock-2.494 {conversion of 1900-07-31} {
+ clock format -2190713104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1900 12:34:56 die xxxi mensis vii annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2415232 07 vii 7 07/31/1900 die xxxi mensis vii annoque mcm? 00 ? 1900}
+test clock-2.495 {conversion of 1900-08-01} {
+ clock format -2190626704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1900 12:34:56 die i mensis viii annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2415233 08 viii 8 08/01/1900 die i mensis viii annoque mcm? 00 ? 1900}
+test clock-2.496 {conversion of 1900-08-31} {
+ clock format -2188034704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1900 12:34:56 die xxxi mensis viii annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2415263 08 viii 8 08/31/1900 die xxxi mensis viii annoque mcm? 00 ? 1900}
+test clock-2.497 {conversion of 1900-09-01} {
+ clock format -2187948304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1900 12:34:56 die i mensis ix annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2415264 09 ix 9 09/01/1900 die i mensis ix annoque mcm? 00 ? 1900}
+test clock-2.498 {conversion of 1900-09-30} {
+ clock format -2185442704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1900 12:34:56 die xxx mensis ix annoque mcm? xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2415293 09 ix 9 09/30/1900 die xxx mensis ix annoque mcm? 00 ? 1900}
+test clock-2.499 {conversion of 1900-10-01} {
+ clock format -2185356304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1900 12:34:56 die i mensis x annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2415294 10 x 10 10/01/1900 die i mensis x annoque mcm? 00 ? 1900}
+test clock-2.500 {conversion of 1900-10-31} {
+ clock format -2182764304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1900 12:34:56 die xxxi mensis x annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2415324 10 x 10 10/31/1900 die xxxi mensis x annoque mcm? 00 ? 1900}
+test clock-2.501 {conversion of 1900-11-01} {
+ clock format -2182677904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1900 12:34:56 die i mensis xi annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2415325 11 xi 11 11/01/1900 die i mensis xi annoque mcm? 00 ? 1900}
+test clock-2.502 {conversion of 1900-11-30} {
+ clock format -2180172304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1900 12:34:56 die xxx mensis xi annoque mcm? xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2415354 11 xi 11 11/30/1900 die xxx mensis xi annoque mcm? 00 ? 1900}
+test clock-2.503 {conversion of 1900-12-01} {
+ clock format -2180085904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1900 12:34:56 die i mensis xii annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2415355 12 xii 12 12/01/1900 die i mensis xii annoque mcm? 00 ? 1900}
+test clock-2.504 {conversion of 1900-12-31} {
+ clock format -2177493904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1900 12:34:56 die xxxi mensis xii annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2415385 12 xii 12 12/31/1900 die xxxi mensis xii annoque mcm? 00 ? 1900}
+test clock-2.505 {conversion of 1944-01-01} {
+ clock format -820495504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1944 12:34:56 die i mensis i annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2431091 01 i 1 01/01/1944 die i mensis i annoque mcmxliv 44 xliv 1944}
+test clock-2.506 {conversion of 1944-01-31} {
+ clock format -817903504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1944 12:34:56 die xxxi mensis i annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2431121 01 i 1 01/31/1944 die xxxi mensis i annoque mcmxliv 44 xliv 1944}
+test clock-2.507 {conversion of 1944-02-01} {
+ clock format -817817104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1944 12:34:56 die i mensis ii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2431122 02 ii 2 02/01/1944 die i mensis ii annoque mcmxliv 44 xliv 1944}
+test clock-2.508 {conversion of 1944-02-29} {
+ clock format -815397904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1944 12:34:56 die xxix mensis ii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2431150 02 ii 2 02/29/1944 die xxix mensis ii annoque mcmxliv 44 xliv 1944}
+test clock-2.509 {conversion of 1944-03-01} {
+ clock format -815311504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1944 12:34:56 die i mensis iii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2431151 03 iii 3 03/01/1944 die i mensis iii annoque mcmxliv 44 xliv 1944}
+test clock-2.510 {conversion of 1944-03-31} {
+ clock format -812719504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1944 12:34:56 die xxxi mensis iii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2431181 03 iii 3 03/31/1944 die xxxi mensis iii annoque mcmxliv 44 xliv 1944}
+test clock-2.511 {conversion of 1944-04-01} {
+ clock format -812633104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1944 12:34:56 die i mensis iv annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2431182 04 iv 4 04/01/1944 die i mensis iv annoque mcmxliv 44 xliv 1944}
+test clock-2.512 {conversion of 1944-04-30} {
+ clock format -810127504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1944 12:34:56 die xxx mensis iv annoque mcmxliv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2431211 04 iv 4 04/30/1944 die xxx mensis iv annoque mcmxliv 44 xliv 1944}
+test clock-2.513 {conversion of 1944-05-01} {
+ clock format -810041104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1944 12:34:56 die i mensis v annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2431212 05 v 5 05/01/1944 die i mensis v annoque mcmxliv 44 xliv 1944}
+test clock-2.514 {conversion of 1944-05-31} {
+ clock format -807449104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1944 12:34:56 die xxxi mensis v annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2431242 05 v 5 05/31/1944 die xxxi mensis v annoque mcmxliv 44 xliv 1944}
+test clock-2.515 {conversion of 1944-06-01} {
+ clock format -807362704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1944 12:34:56 die i mensis vi annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2431243 06 vi 6 06/01/1944 die i mensis vi annoque mcmxliv 44 xliv 1944}
+test clock-2.516 {conversion of 1944-06-30} {
+ clock format -804857104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1944 12:34:56 die xxx mensis vi annoque mcmxliv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2431272 06 vi 6 06/30/1944 die xxx mensis vi annoque mcmxliv 44 xliv 1944}
+test clock-2.517 {conversion of 1944-07-01} {
+ clock format -804770704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1944 12:34:56 die i mensis vii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2431273 07 vii 7 07/01/1944 die i mensis vii annoque mcmxliv 44 xliv 1944}
+test clock-2.518 {conversion of 1944-07-31} {
+ clock format -802178704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1944 12:34:56 die xxxi mensis vii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2431303 07 vii 7 07/31/1944 die xxxi mensis vii annoque mcmxliv 44 xliv 1944}
+test clock-2.519 {conversion of 1944-08-01} {
+ clock format -802092304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1944 12:34:56 die i mensis viii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2431304 08 viii 8 08/01/1944 die i mensis viii annoque mcmxliv 44 xliv 1944}
+test clock-2.520 {conversion of 1944-08-31} {
+ clock format -799500304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1944 12:34:56 die xxxi mensis viii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2431334 08 viii 8 08/31/1944 die xxxi mensis viii annoque mcmxliv 44 xliv 1944}
+test clock-2.521 {conversion of 1944-09-01} {
+ clock format -799413904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1944 12:34:56 die i mensis ix annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2431335 09 ix 9 09/01/1944 die i mensis ix annoque mcmxliv 44 xliv 1944}
+test clock-2.522 {conversion of 1944-09-30} {
+ clock format -796908304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1944 12:34:56 die xxx mensis ix annoque mcmxliv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2431364 09 ix 9 09/30/1944 die xxx mensis ix annoque mcmxliv 44 xliv 1944}
+test clock-2.523 {conversion of 1944-10-01} {
+ clock format -796821904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1944 12:34:56 die i mensis x annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2431365 10 x 10 10/01/1944 die i mensis x annoque mcmxliv 44 xliv 1944}
+test clock-2.524 {conversion of 1944-10-31} {
+ clock format -794229904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1944 12:34:56 die xxxi mensis x annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2431395 10 x 10 10/31/1944 die xxxi mensis x annoque mcmxliv 44 xliv 1944}
+test clock-2.525 {conversion of 1944-11-01} {
+ clock format -794143504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1944 12:34:56 die i mensis xi annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2431396 11 xi 11 11/01/1944 die i mensis xi annoque mcmxliv 44 xliv 1944}
+test clock-2.526 {conversion of 1944-11-30} {
+ clock format -791637904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1944 12:34:56 die xxx mensis xi annoque mcmxliv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2431425 11 xi 11 11/30/1944 die xxx mensis xi annoque mcmxliv 44 xliv 1944}
+test clock-2.527 {conversion of 1944-12-01} {
+ clock format -791551504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1944 12:34:56 die i mensis xii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2431426 12 xii 12 12/01/1944 die i mensis xii annoque mcmxliv 44 xliv 1944}
+test clock-2.528 {conversion of 1944-12-31} {
+ clock format -788959504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1944 12:34:56 die xxxi mensis xii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2431456 12 xii 12 12/31/1944 die xxxi mensis xii annoque mcmxliv 44 xliv 1944}
+test clock-2.529 {conversion of 1945-01-01} {
+ clock format -788873104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1945 12:34:56 die i mensis i annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2431457 01 i 1 01/01/1945 die i mensis i annoque mcmxlv 45 xlv 1945}
+test clock-2.530 {conversion of 1945-01-31} {
+ clock format -786281104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1945 12:34:56 die xxxi mensis i annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2431487 01 i 1 01/31/1945 die xxxi mensis i annoque mcmxlv 45 xlv 1945}
+test clock-2.531 {conversion of 1945-02-01} {
+ clock format -786194704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1945 12:34:56 die i mensis ii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2431488 02 ii 2 02/01/1945 die i mensis ii annoque mcmxlv 45 xlv 1945}
+test clock-2.532 {conversion of 1945-02-28} {
+ clock format -783861904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1945 12:34:56 die xxviii mensis ii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2431515 02 ii 2 02/28/1945 die xxviii mensis ii annoque mcmxlv 45 xlv 1945}
+test clock-2.533 {conversion of 1945-03-01} {
+ clock format -783775504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1945 12:34:56 die i mensis iii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2431516 03 iii 3 03/01/1945 die i mensis iii annoque mcmxlv 45 xlv 1945}
+test clock-2.534 {conversion of 1945-03-31} {
+ clock format -781183504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1945 12:34:56 die xxxi mensis iii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2431546 03 iii 3 03/31/1945 die xxxi mensis iii annoque mcmxlv 45 xlv 1945}
+test clock-2.535 {conversion of 1945-04-01} {
+ clock format -781097104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1945 12:34:56 die i mensis iv annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2431547 04 iv 4 04/01/1945 die i mensis iv annoque mcmxlv 45 xlv 1945}
+test clock-2.536 {conversion of 1945-04-30} {
+ clock format -778591504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1945 12:34:56 die xxx mensis iv annoque mcmxlv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2431576 04 iv 4 04/30/1945 die xxx mensis iv annoque mcmxlv 45 xlv 1945}
+test clock-2.537 {conversion of 1945-05-01} {
+ clock format -778505104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1945 12:34:56 die i mensis v annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2431577 05 v 5 05/01/1945 die i mensis v annoque mcmxlv 45 xlv 1945}
+test clock-2.538 {conversion of 1945-05-31} {
+ clock format -775913104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1945 12:34:56 die xxxi mensis v annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2431607 05 v 5 05/31/1945 die xxxi mensis v annoque mcmxlv 45 xlv 1945}
+test clock-2.539 {conversion of 1945-06-01} {
+ clock format -775826704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1945 12:34:56 die i mensis vi annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2431608 06 vi 6 06/01/1945 die i mensis vi annoque mcmxlv 45 xlv 1945}
+test clock-2.540 {conversion of 1945-06-30} {
+ clock format -773321104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1945 12:34:56 die xxx mensis vi annoque mcmxlv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2431637 06 vi 6 06/30/1945 die xxx mensis vi annoque mcmxlv 45 xlv 1945}
+test clock-2.541 {conversion of 1945-07-01} {
+ clock format -773234704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1945 12:34:56 die i mensis vii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2431638 07 vii 7 07/01/1945 die i mensis vii annoque mcmxlv 45 xlv 1945}
+test clock-2.542 {conversion of 1945-07-31} {
+ clock format -770642704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1945 12:34:56 die xxxi mensis vii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2431668 07 vii 7 07/31/1945 die xxxi mensis vii annoque mcmxlv 45 xlv 1945}
+test clock-2.543 {conversion of 1945-08-01} {
+ clock format -770556304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1945 12:34:56 die i mensis viii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2431669 08 viii 8 08/01/1945 die i mensis viii annoque mcmxlv 45 xlv 1945}
+test clock-2.544 {conversion of 1945-08-31} {
+ clock format -767964304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1945 12:34:56 die xxxi mensis viii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2431699 08 viii 8 08/31/1945 die xxxi mensis viii annoque mcmxlv 45 xlv 1945}
+test clock-2.545 {conversion of 1945-09-01} {
+ clock format -767877904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1945 12:34:56 die i mensis ix annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2431700 09 ix 9 09/01/1945 die i mensis ix annoque mcmxlv 45 xlv 1945}
+test clock-2.546 {conversion of 1945-09-30} {
+ clock format -765372304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1945 12:34:56 die xxx mensis ix annoque mcmxlv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2431729 09 ix 9 09/30/1945 die xxx mensis ix annoque mcmxlv 45 xlv 1945}
+test clock-2.547 {conversion of 1945-10-01} {
+ clock format -765285904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1945 12:34:56 die i mensis x annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2431730 10 x 10 10/01/1945 die i mensis x annoque mcmxlv 45 xlv 1945}
+test clock-2.548 {conversion of 1945-10-31} {
+ clock format -762693904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1945 12:34:56 die xxxi mensis x annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2431760 10 x 10 10/31/1945 die xxxi mensis x annoque mcmxlv 45 xlv 1945}
+test clock-2.549 {conversion of 1945-11-01} {
+ clock format -762607504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1945 12:34:56 die i mensis xi annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2431761 11 xi 11 11/01/1945 die i mensis xi annoque mcmxlv 45 xlv 1945}
+test clock-2.550 {conversion of 1945-11-30} {
+ clock format -760101904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1945 12:34:56 die xxx mensis xi annoque mcmxlv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2431790 11 xi 11 11/30/1945 die xxx mensis xi annoque mcmxlv 45 xlv 1945}
+test clock-2.551 {conversion of 1945-12-01} {
+ clock format -760015504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1945 12:34:56 die i mensis xii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2431791 12 xii 12 12/01/1945 die i mensis xii annoque mcmxlv 45 xlv 1945}
+test clock-2.552 {conversion of 1945-12-31} {
+ clock format -757423504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1945 12:34:56 die xxxi mensis xii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2431821 12 xii 12 12/31/1945 die xxxi mensis xii annoque mcmxlv 45 xlv 1945}
+test clock-2.553 {conversion of 1948-01-01} {
+ clock format -694265104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1948 12:34:56 die i mensis i annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2432552 01 i 1 01/01/1948 die i mensis i annoque mcmxlviii 48 xlviii 1948}
+test clock-2.554 {conversion of 1948-01-31} {
+ clock format -691673104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1948 12:34:56 die xxxi mensis i annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2432582 01 i 1 01/31/1948 die xxxi mensis i annoque mcmxlviii 48 xlviii 1948}
+test clock-2.555 {conversion of 1948-02-01} {
+ clock format -691586704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1948 12:34:56 die i mensis ii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2432583 02 ii 2 02/01/1948 die i mensis ii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.556 {conversion of 1948-02-29} {
+ clock format -689167504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1948 12:34:56 die xxix mensis ii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2432611 02 ii 2 02/29/1948 die xxix mensis ii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.557 {conversion of 1948-03-01} {
+ clock format -689081104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1948 12:34:56 die i mensis iii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2432612 03 iii 3 03/01/1948 die i mensis iii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.558 {conversion of 1948-03-31} {
+ clock format -686489104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1948 12:34:56 die xxxi mensis iii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2432642 03 iii 3 03/31/1948 die xxxi mensis iii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.559 {conversion of 1948-04-01} {
+ clock format -686402704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1948 12:34:56 die i mensis iv annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2432643 04 iv 4 04/01/1948 die i mensis iv annoque mcmxlviii 48 xlviii 1948}
+test clock-2.560 {conversion of 1948-04-30} {
+ clock format -683897104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1948 12:34:56 die xxx mensis iv annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2432672 04 iv 4 04/30/1948 die xxx mensis iv annoque mcmxlviii 48 xlviii 1948}
+test clock-2.561 {conversion of 1948-05-01} {
+ clock format -683810704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1948 12:34:56 die i mensis v annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2432673 05 v 5 05/01/1948 die i mensis v annoque mcmxlviii 48 xlviii 1948}
+test clock-2.562 {conversion of 1948-05-31} {
+ clock format -681218704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1948 12:34:56 die xxxi mensis v annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2432703 05 v 5 05/31/1948 die xxxi mensis v annoque mcmxlviii 48 xlviii 1948}
+test clock-2.563 {conversion of 1948-06-01} {
+ clock format -681132304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1948 12:34:56 die i mensis vi annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2432704 06 vi 6 06/01/1948 die i mensis vi annoque mcmxlviii 48 xlviii 1948}
+test clock-2.564 {conversion of 1948-06-30} {
+ clock format -678626704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1948 12:34:56 die xxx mensis vi annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2432733 06 vi 6 06/30/1948 die xxx mensis vi annoque mcmxlviii 48 xlviii 1948}
+test clock-2.565 {conversion of 1948-07-01} {
+ clock format -678540304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1948 12:34:56 die i mensis vii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2432734 07 vii 7 07/01/1948 die i mensis vii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.566 {conversion of 1948-07-31} {
+ clock format -675948304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1948 12:34:56 die xxxi mensis vii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2432764 07 vii 7 07/31/1948 die xxxi mensis vii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.567 {conversion of 1948-08-01} {
+ clock format -675861904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1948 12:34:56 die i mensis viii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2432765 08 viii 8 08/01/1948 die i mensis viii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.568 {conversion of 1948-08-31} {
+ clock format -673269904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1948 12:34:56 die xxxi mensis viii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2432795 08 viii 8 08/31/1948 die xxxi mensis viii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.569 {conversion of 1948-09-01} {
+ clock format -673183504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1948 12:34:56 die i mensis ix annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2432796 09 ix 9 09/01/1948 die i mensis ix annoque mcmxlviii 48 xlviii 1948}
+test clock-2.570 {conversion of 1948-09-30} {
+ clock format -670677904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1948 12:34:56 die xxx mensis ix annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2432825 09 ix 9 09/30/1948 die xxx mensis ix annoque mcmxlviii 48 xlviii 1948}
+test clock-2.571 {conversion of 1948-10-01} {
+ clock format -670591504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1948 12:34:56 die i mensis x annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2432826 10 x 10 10/01/1948 die i mensis x annoque mcmxlviii 48 xlviii 1948}
+test clock-2.572 {conversion of 1948-10-31} {
+ clock format -667999504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1948 12:34:56 die xxxi mensis x annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2432856 10 x 10 10/31/1948 die xxxi mensis x annoque mcmxlviii 48 xlviii 1948}
+test clock-2.573 {conversion of 1948-11-01} {
+ clock format -667913104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1948 12:34:56 die i mensis xi annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2432857 11 xi 11 11/01/1948 die i mensis xi annoque mcmxlviii 48 xlviii 1948}
+test clock-2.574 {conversion of 1948-11-30} {
+ clock format -665407504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1948 12:34:56 die xxx mensis xi annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2432886 11 xi 11 11/30/1948 die xxx mensis xi annoque mcmxlviii 48 xlviii 1948}
+test clock-2.575 {conversion of 1948-12-01} {
+ clock format -665321104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1948 12:34:56 die i mensis xii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2432887 12 xii 12 12/01/1948 die i mensis xii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.576 {conversion of 1948-12-31} {
+ clock format -662729104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1948 12:34:56 die xxxi mensis xii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2432917 12 xii 12 12/31/1948 die xxxi mensis xii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.577 {conversion of 1949-01-01} {
+ clock format -662642704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1949 12:34:56 die i mensis i annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2432918 01 i 1 01/01/1949 die i mensis i annoque mcmxlix 49 xlix 1949}
+test clock-2.578 {conversion of 1949-01-31} {
+ clock format -660050704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1949 12:34:56 die xxxi mensis i annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2432948 01 i 1 01/31/1949 die xxxi mensis i annoque mcmxlix 49 xlix 1949}
+test clock-2.579 {conversion of 1949-02-01} {
+ clock format -659964304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1949 12:34:56 die i mensis ii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2432949 02 ii 2 02/01/1949 die i mensis ii annoque mcmxlix 49 xlix 1949}
+test clock-2.580 {conversion of 1949-02-28} {
+ clock format -657631504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1949 12:34:56 die xxviii mensis ii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2432976 02 ii 2 02/28/1949 die xxviii mensis ii annoque mcmxlix 49 xlix 1949}
+test clock-2.581 {conversion of 1949-03-01} {
+ clock format -657545104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1949 12:34:56 die i mensis iii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2432977 03 iii 3 03/01/1949 die i mensis iii annoque mcmxlix 49 xlix 1949}
+test clock-2.582 {conversion of 1949-03-31} {
+ clock format -654953104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1949 12:34:56 die xxxi mensis iii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2433007 03 iii 3 03/31/1949 die xxxi mensis iii annoque mcmxlix 49 xlix 1949}
+test clock-2.583 {conversion of 1949-04-01} {
+ clock format -654866704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1949 12:34:56 die i mensis iv annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2433008 04 iv 4 04/01/1949 die i mensis iv annoque mcmxlix 49 xlix 1949}
+test clock-2.584 {conversion of 1949-04-30} {
+ clock format -652361104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1949 12:34:56 die xxx mensis iv annoque mcmxlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2433037 04 iv 4 04/30/1949 die xxx mensis iv annoque mcmxlix 49 xlix 1949}
+test clock-2.585 {conversion of 1949-05-01} {
+ clock format -652274704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1949 12:34:56 die i mensis v annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2433038 05 v 5 05/01/1949 die i mensis v annoque mcmxlix 49 xlix 1949}
+test clock-2.586 {conversion of 1949-05-31} {
+ clock format -649682704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1949 12:34:56 die xxxi mensis v annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2433068 05 v 5 05/31/1949 die xxxi mensis v annoque mcmxlix 49 xlix 1949}
+test clock-2.587 {conversion of 1949-06-01} {
+ clock format -649596304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1949 12:34:56 die i mensis vi annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2433069 06 vi 6 06/01/1949 die i mensis vi annoque mcmxlix 49 xlix 1949}
+test clock-2.588 {conversion of 1949-06-30} {
+ clock format -647090704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1949 12:34:56 die xxx mensis vi annoque mcmxlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2433098 06 vi 6 06/30/1949 die xxx mensis vi annoque mcmxlix 49 xlix 1949}
+test clock-2.589 {conversion of 1949-07-01} {
+ clock format -647004304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1949 12:34:56 die i mensis vii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2433099 07 vii 7 07/01/1949 die i mensis vii annoque mcmxlix 49 xlix 1949}
+test clock-2.590 {conversion of 1949-07-31} {
+ clock format -644412304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1949 12:34:56 die xxxi mensis vii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2433129 07 vii 7 07/31/1949 die xxxi mensis vii annoque mcmxlix 49 xlix 1949}
+test clock-2.591 {conversion of 1949-08-01} {
+ clock format -644325904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1949 12:34:56 die i mensis viii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2433130 08 viii 8 08/01/1949 die i mensis viii annoque mcmxlix 49 xlix 1949}
+test clock-2.592 {conversion of 1949-08-31} {
+ clock format -641733904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1949 12:34:56 die xxxi mensis viii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2433160 08 viii 8 08/31/1949 die xxxi mensis viii annoque mcmxlix 49 xlix 1949}
+test clock-2.593 {conversion of 1949-09-01} {
+ clock format -641647504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1949 12:34:56 die i mensis ix annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2433161 09 ix 9 09/01/1949 die i mensis ix annoque mcmxlix 49 xlix 1949}
+test clock-2.594 {conversion of 1949-09-30} {
+ clock format -639141904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1949 12:34:56 die xxx mensis ix annoque mcmxlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2433190 09 ix 9 09/30/1949 die xxx mensis ix annoque mcmxlix 49 xlix 1949}
+test clock-2.595 {conversion of 1949-10-01} {
+ clock format -639055504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1949 12:34:56 die i mensis x annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2433191 10 x 10 10/01/1949 die i mensis x annoque mcmxlix 49 xlix 1949}
+test clock-2.596 {conversion of 1949-10-31} {
+ clock format -636463504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1949 12:34:56 die xxxi mensis x annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2433221 10 x 10 10/31/1949 die xxxi mensis x annoque mcmxlix 49 xlix 1949}
+test clock-2.597 {conversion of 1949-11-01} {
+ clock format -636377104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1949 12:34:56 die i mensis xi annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2433222 11 xi 11 11/01/1949 die i mensis xi annoque mcmxlix 49 xlix 1949}
+test clock-2.598 {conversion of 1949-11-30} {
+ clock format -633871504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1949 12:34:56 die xxx mensis xi annoque mcmxlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2433251 11 xi 11 11/30/1949 die xxx mensis xi annoque mcmxlix 49 xlix 1949}
+test clock-2.599 {conversion of 1949-12-01} {
+ clock format -633785104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1949 12:34:56 die i mensis xii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2433252 12 xii 12 12/01/1949 die i mensis xii annoque mcmxlix 49 xlix 1949}
+test clock-2.600 {conversion of 1949-12-31} {
+ clock format -631193104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1949 12:34:56 die xxxi mensis xii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2433282 12 xii 12 12/31/1949 die xxxi mensis xii annoque mcmxlix 49 xlix 1949}
+test clock-2.601 {conversion of 1952-01-01} {
+ clock format -568034704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1952 12:34:56 die i mensis i annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2434013 01 i 1 01/01/1952 die i mensis i annoque mcmlii 52 lii 1952}
+test clock-2.602 {conversion of 1952-01-31} {
+ clock format -565442704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1952 12:34:56 die xxxi mensis i annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2434043 01 i 1 01/31/1952 die xxxi mensis i annoque mcmlii 52 lii 1952}
+test clock-2.603 {conversion of 1952-02-01} {
+ clock format -565356304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1952 12:34:56 die i mensis ii annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2434044 02 ii 2 02/01/1952 die i mensis ii annoque mcmlii 52 lii 1952}
+test clock-2.604 {conversion of 1952-02-29} {
+ clock format -562937104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1952 12:34:56 die xxix mensis ii annoque mcmlii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2434072 02 ii 2 02/29/1952 die xxix mensis ii annoque mcmlii 52 lii 1952}
+test clock-2.605 {conversion of 1952-03-01} {
+ clock format -562850704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1952 12:34:56 die i mensis iii annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2434073 03 iii 3 03/01/1952 die i mensis iii annoque mcmlii 52 lii 1952}
+test clock-2.606 {conversion of 1952-03-31} {
+ clock format -560258704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1952 12:34:56 die xxxi mensis iii annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2434103 03 iii 3 03/31/1952 die xxxi mensis iii annoque mcmlii 52 lii 1952}
+test clock-2.607 {conversion of 1952-04-01} {
+ clock format -560172304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1952 12:34:56 die i mensis iv annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2434104 04 iv 4 04/01/1952 die i mensis iv annoque mcmlii 52 lii 1952}
+test clock-2.608 {conversion of 1952-04-30} {
+ clock format -557666704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1952 12:34:56 die xxx mensis iv annoque mcmlii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2434133 04 iv 4 04/30/1952 die xxx mensis iv annoque mcmlii 52 lii 1952}
+test clock-2.609 {conversion of 1952-05-01} {
+ clock format -557580304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1952 12:34:56 die i mensis v annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2434134 05 v 5 05/01/1952 die i mensis v annoque mcmlii 52 lii 1952}
+test clock-2.610 {conversion of 1952-05-31} {
+ clock format -554988304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1952 12:34:56 die xxxi mensis v annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2434164 05 v 5 05/31/1952 die xxxi mensis v annoque mcmlii 52 lii 1952}
+test clock-2.611 {conversion of 1952-06-01} {
+ clock format -554901904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1952 12:34:56 die i mensis vi annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2434165 06 vi 6 06/01/1952 die i mensis vi annoque mcmlii 52 lii 1952}
+test clock-2.612 {conversion of 1952-06-30} {
+ clock format -552396304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1952 12:34:56 die xxx mensis vi annoque mcmlii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2434194 06 vi 6 06/30/1952 die xxx mensis vi annoque mcmlii 52 lii 1952}
+test clock-2.613 {conversion of 1952-07-01} {
+ clock format -552309904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1952 12:34:56 die i mensis vii annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2434195 07 vii 7 07/01/1952 die i mensis vii annoque mcmlii 52 lii 1952}
+test clock-2.614 {conversion of 1952-07-31} {
+ clock format -549717904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1952 12:34:56 die xxxi mensis vii annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2434225 07 vii 7 07/31/1952 die xxxi mensis vii annoque mcmlii 52 lii 1952}
+test clock-2.615 {conversion of 1952-08-01} {
+ clock format -549631504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1952 12:34:56 die i mensis viii annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2434226 08 viii 8 08/01/1952 die i mensis viii annoque mcmlii 52 lii 1952}
+test clock-2.616 {conversion of 1952-08-31} {
+ clock format -547039504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1952 12:34:56 die xxxi mensis viii annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2434256 08 viii 8 08/31/1952 die xxxi mensis viii annoque mcmlii 52 lii 1952}
+test clock-2.617 {conversion of 1952-09-01} {
+ clock format -546953104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1952 12:34:56 die i mensis ix annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2434257 09 ix 9 09/01/1952 die i mensis ix annoque mcmlii 52 lii 1952}
+test clock-2.618 {conversion of 1952-09-30} {
+ clock format -544447504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1952 12:34:56 die xxx mensis ix annoque mcmlii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2434286 09 ix 9 09/30/1952 die xxx mensis ix annoque mcmlii 52 lii 1952}
+test clock-2.619 {conversion of 1952-10-01} {
+ clock format -544361104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1952 12:34:56 die i mensis x annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2434287 10 x 10 10/01/1952 die i mensis x annoque mcmlii 52 lii 1952}
+test clock-2.620 {conversion of 1952-10-31} {
+ clock format -541769104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1952 12:34:56 die xxxi mensis x annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2434317 10 x 10 10/31/1952 die xxxi mensis x annoque mcmlii 52 lii 1952}
+test clock-2.621 {conversion of 1952-11-01} {
+ clock format -541682704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1952 12:34:56 die i mensis xi annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2434318 11 xi 11 11/01/1952 die i mensis xi annoque mcmlii 52 lii 1952}
+test clock-2.622 {conversion of 1952-11-30} {
+ clock format -539177104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1952 12:34:56 die xxx mensis xi annoque mcmlii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2434347 11 xi 11 11/30/1952 die xxx mensis xi annoque mcmlii 52 lii 1952}
+test clock-2.623 {conversion of 1952-12-01} {
+ clock format -539090704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1952 12:34:56 die i mensis xii annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2434348 12 xii 12 12/01/1952 die i mensis xii annoque mcmlii 52 lii 1952}
+test clock-2.624 {conversion of 1952-12-31} {
+ clock format -536498704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1952 12:34:56 die xxxi mensis xii annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2434378 12 xii 12 12/31/1952 die xxxi mensis xii annoque mcmlii 52 lii 1952}
+test clock-2.625 {conversion of 1953-01-01} {
+ clock format -536412304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1953 12:34:56 die i mensis i annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2434379 01 i 1 01/01/1953 die i mensis i annoque mcmliii 53 liii 1953}
+test clock-2.626 {conversion of 1953-01-31} {
+ clock format -533820304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1953 12:34:56 die xxxi mensis i annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2434409 01 i 1 01/31/1953 die xxxi mensis i annoque mcmliii 53 liii 1953}
+test clock-2.627 {conversion of 1953-02-01} {
+ clock format -533733904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1953 12:34:56 die i mensis ii annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2434410 02 ii 2 02/01/1953 die i mensis ii annoque mcmliii 53 liii 1953}
+test clock-2.628 {conversion of 1953-02-28} {
+ clock format -531401104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1953 12:34:56 die xxviii mensis ii annoque mcmliii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2434437 02 ii 2 02/28/1953 die xxviii mensis ii annoque mcmliii 53 liii 1953}
+test clock-2.629 {conversion of 1953-03-01} {
+ clock format -531314704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1953 12:34:56 die i mensis iii annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2434438 03 iii 3 03/01/1953 die i mensis iii annoque mcmliii 53 liii 1953}
+test clock-2.630 {conversion of 1953-03-31} {
+ clock format -528722704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1953 12:34:56 die xxxi mensis iii annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2434468 03 iii 3 03/31/1953 die xxxi mensis iii annoque mcmliii 53 liii 1953}
+test clock-2.631 {conversion of 1953-04-01} {
+ clock format -528636304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1953 12:34:56 die i mensis iv annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2434469 04 iv 4 04/01/1953 die i mensis iv annoque mcmliii 53 liii 1953}
+test clock-2.632 {conversion of 1953-04-30} {
+ clock format -526130704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1953 12:34:56 die xxx mensis iv annoque mcmliii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2434498 04 iv 4 04/30/1953 die xxx mensis iv annoque mcmliii 53 liii 1953}
+test clock-2.633 {conversion of 1953-05-01} {
+ clock format -526044304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1953 12:34:56 die i mensis v annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2434499 05 v 5 05/01/1953 die i mensis v annoque mcmliii 53 liii 1953}
+test clock-2.634 {conversion of 1953-05-31} {
+ clock format -523452304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1953 12:34:56 die xxxi mensis v annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2434529 05 v 5 05/31/1953 die xxxi mensis v annoque mcmliii 53 liii 1953}
+test clock-2.635 {conversion of 1953-06-01} {
+ clock format -523365904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1953 12:34:56 die i mensis vi annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2434530 06 vi 6 06/01/1953 die i mensis vi annoque mcmliii 53 liii 1953}
+test clock-2.636 {conversion of 1953-06-30} {
+ clock format -520860304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1953 12:34:56 die xxx mensis vi annoque mcmliii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2434559 06 vi 6 06/30/1953 die xxx mensis vi annoque mcmliii 53 liii 1953}
+test clock-2.637 {conversion of 1953-07-01} {
+ clock format -520773904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1953 12:34:56 die i mensis vii annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2434560 07 vii 7 07/01/1953 die i mensis vii annoque mcmliii 53 liii 1953}
+test clock-2.638 {conversion of 1953-07-31} {
+ clock format -518181904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1953 12:34:56 die xxxi mensis vii annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2434590 07 vii 7 07/31/1953 die xxxi mensis vii annoque mcmliii 53 liii 1953}
+test clock-2.639 {conversion of 1953-08-01} {
+ clock format -518095504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1953 12:34:56 die i mensis viii annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2434591 08 viii 8 08/01/1953 die i mensis viii annoque mcmliii 53 liii 1953}
+test clock-2.640 {conversion of 1953-08-31} {
+ clock format -515503504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1953 12:34:56 die xxxi mensis viii annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2434621 08 viii 8 08/31/1953 die xxxi mensis viii annoque mcmliii 53 liii 1953}
+test clock-2.641 {conversion of 1953-09-01} {
+ clock format -515417104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1953 12:34:56 die i mensis ix annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2434622 09 ix 9 09/01/1953 die i mensis ix annoque mcmliii 53 liii 1953}
+test clock-2.642 {conversion of 1953-09-30} {
+ clock format -512911504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1953 12:34:56 die xxx mensis ix annoque mcmliii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2434651 09 ix 9 09/30/1953 die xxx mensis ix annoque mcmliii 53 liii 1953}
+test clock-2.643 {conversion of 1953-10-01} {
+ clock format -512825104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1953 12:34:56 die i mensis x annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2434652 10 x 10 10/01/1953 die i mensis x annoque mcmliii 53 liii 1953}
+test clock-2.644 {conversion of 1953-10-31} {
+ clock format -510233104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1953 12:34:56 die xxxi mensis x annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2434682 10 x 10 10/31/1953 die xxxi mensis x annoque mcmliii 53 liii 1953}
+test clock-2.645 {conversion of 1953-11-01} {
+ clock format -510146704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1953 12:34:56 die i mensis xi annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2434683 11 xi 11 11/01/1953 die i mensis xi annoque mcmliii 53 liii 1953}
+test clock-2.646 {conversion of 1953-11-30} {
+ clock format -507641104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1953 12:34:56 die xxx mensis xi annoque mcmliii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2434712 11 xi 11 11/30/1953 die xxx mensis xi annoque mcmliii 53 liii 1953}
+test clock-2.647 {conversion of 1953-12-01} {
+ clock format -507554704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1953 12:34:56 die i mensis xii annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2434713 12 xii 12 12/01/1953 die i mensis xii annoque mcmliii 53 liii 1953}
+test clock-2.648 {conversion of 1953-12-31} {
+ clock format -504962704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1953 12:34:56 die xxxi mensis xii annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2434743 12 xii 12 12/31/1953 die xxxi mensis xii annoque mcmliii 53 liii 1953}
+test clock-2.649 {conversion of 1956-01-01} {
+ clock format -441804304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1956 12:34:56 die i mensis i annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2435474 01 i 1 01/01/1956 die i mensis i annoque mcmlvi 56 lvi 1956}
+test clock-2.650 {conversion of 1956-01-31} {
+ clock format -439212304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1956 12:34:56 die xxxi mensis i annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2435504 01 i 1 01/31/1956 die xxxi mensis i annoque mcmlvi 56 lvi 1956}
+test clock-2.651 {conversion of 1956-02-01} {
+ clock format -439125904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1956 12:34:56 die i mensis ii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2435505 02 ii 2 02/01/1956 die i mensis ii annoque mcmlvi 56 lvi 1956}
+test clock-2.652 {conversion of 1956-02-29} {
+ clock format -436706704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1956 12:34:56 die xxix mensis ii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2435533 02 ii 2 02/29/1956 die xxix mensis ii annoque mcmlvi 56 lvi 1956}
+test clock-2.653 {conversion of 1956-03-01} {
+ clock format -436620304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1956 12:34:56 die i mensis iii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2435534 03 iii 3 03/01/1956 die i mensis iii annoque mcmlvi 56 lvi 1956}
+test clock-2.654 {conversion of 1956-03-31} {
+ clock format -434028304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1956 12:34:56 die xxxi mensis iii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2435564 03 iii 3 03/31/1956 die xxxi mensis iii annoque mcmlvi 56 lvi 1956}
+test clock-2.655 {conversion of 1956-04-01} {
+ clock format -433941904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1956 12:34:56 die i mensis iv annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2435565 04 iv 4 04/01/1956 die i mensis iv annoque mcmlvi 56 lvi 1956}
+test clock-2.656 {conversion of 1956-04-30} {
+ clock format -431436304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1956 12:34:56 die xxx mensis iv annoque mcmlvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2435594 04 iv 4 04/30/1956 die xxx mensis iv annoque mcmlvi 56 lvi 1956}
+test clock-2.657 {conversion of 1956-05-01} {
+ clock format -431349904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1956 12:34:56 die i mensis v annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2435595 05 v 5 05/01/1956 die i mensis v annoque mcmlvi 56 lvi 1956}
+test clock-2.658 {conversion of 1956-05-31} {
+ clock format -428757904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1956 12:34:56 die xxxi mensis v annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2435625 05 v 5 05/31/1956 die xxxi mensis v annoque mcmlvi 56 lvi 1956}
+test clock-2.659 {conversion of 1956-06-01} {
+ clock format -428671504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1956 12:34:56 die i mensis vi annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2435626 06 vi 6 06/01/1956 die i mensis vi annoque mcmlvi 56 lvi 1956}
+test clock-2.660 {conversion of 1956-06-30} {
+ clock format -426165904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1956 12:34:56 die xxx mensis vi annoque mcmlvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2435655 06 vi 6 06/30/1956 die xxx mensis vi annoque mcmlvi 56 lvi 1956}
+test clock-2.661 {conversion of 1956-07-01} {
+ clock format -426079504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1956 12:34:56 die i mensis vii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2435656 07 vii 7 07/01/1956 die i mensis vii annoque mcmlvi 56 lvi 1956}
+test clock-2.662 {conversion of 1956-07-31} {
+ clock format -423487504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1956 12:34:56 die xxxi mensis vii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2435686 07 vii 7 07/31/1956 die xxxi mensis vii annoque mcmlvi 56 lvi 1956}
+test clock-2.663 {conversion of 1956-08-01} {
+ clock format -423401104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1956 12:34:56 die i mensis viii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2435687 08 viii 8 08/01/1956 die i mensis viii annoque mcmlvi 56 lvi 1956}
+test clock-2.664 {conversion of 1956-08-31} {
+ clock format -420809104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1956 12:34:56 die xxxi mensis viii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2435717 08 viii 8 08/31/1956 die xxxi mensis viii annoque mcmlvi 56 lvi 1956}
+test clock-2.665 {conversion of 1956-09-01} {
+ clock format -420722704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1956 12:34:56 die i mensis ix annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2435718 09 ix 9 09/01/1956 die i mensis ix annoque mcmlvi 56 lvi 1956}
+test clock-2.666 {conversion of 1956-09-30} {
+ clock format -418217104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1956 12:34:56 die xxx mensis ix annoque mcmlvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2435747 09 ix 9 09/30/1956 die xxx mensis ix annoque mcmlvi 56 lvi 1956}
+test clock-2.667 {conversion of 1956-10-01} {
+ clock format -418130704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1956 12:34:56 die i mensis x annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2435748 10 x 10 10/01/1956 die i mensis x annoque mcmlvi 56 lvi 1956}
+test clock-2.668 {conversion of 1956-10-31} {
+ clock format -415538704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1956 12:34:56 die xxxi mensis x annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2435778 10 x 10 10/31/1956 die xxxi mensis x annoque mcmlvi 56 lvi 1956}
+test clock-2.669 {conversion of 1956-11-01} {
+ clock format -415452304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1956 12:34:56 die i mensis xi annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2435779 11 xi 11 11/01/1956 die i mensis xi annoque mcmlvi 56 lvi 1956}
+test clock-2.670 {conversion of 1956-11-30} {
+ clock format -412946704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1956 12:34:56 die xxx mensis xi annoque mcmlvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2435808 11 xi 11 11/30/1956 die xxx mensis xi annoque mcmlvi 56 lvi 1956}
+test clock-2.671 {conversion of 1956-12-01} {
+ clock format -412860304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1956 12:34:56 die i mensis xii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2435809 12 xii 12 12/01/1956 die i mensis xii annoque mcmlvi 56 lvi 1956}
+test clock-2.672 {conversion of 1956-12-31} {
+ clock format -410268304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1956 12:34:56 die xxxi mensis xii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2435839 12 xii 12 12/31/1956 die xxxi mensis xii annoque mcmlvi 56 lvi 1956}
+test clock-2.673 {conversion of 1957-01-01} {
+ clock format -410181904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1957 12:34:56 die i mensis i annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2435840 01 i 1 01/01/1957 die i mensis i annoque mcmlvii 57 lvii 1957}
+test clock-2.674 {conversion of 1957-01-31} {
+ clock format -407589904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1957 12:34:56 die xxxi mensis i annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2435870 01 i 1 01/31/1957 die xxxi mensis i annoque mcmlvii 57 lvii 1957}
+test clock-2.675 {conversion of 1957-02-01} {
+ clock format -407503504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1957 12:34:56 die i mensis ii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2435871 02 ii 2 02/01/1957 die i mensis ii annoque mcmlvii 57 lvii 1957}
+test clock-2.676 {conversion of 1957-02-28} {
+ clock format -405170704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1957 12:34:56 die xxviii mensis ii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2435898 02 ii 2 02/28/1957 die xxviii mensis ii annoque mcmlvii 57 lvii 1957}
+test clock-2.677 {conversion of 1957-03-01} {
+ clock format -405084304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1957 12:34:56 die i mensis iii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2435899 03 iii 3 03/01/1957 die i mensis iii annoque mcmlvii 57 lvii 1957}
+test clock-2.678 {conversion of 1957-03-31} {
+ clock format -402492304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1957 12:34:56 die xxxi mensis iii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2435929 03 iii 3 03/31/1957 die xxxi mensis iii annoque mcmlvii 57 lvii 1957}
+test clock-2.679 {conversion of 1957-04-01} {
+ clock format -402405904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1957 12:34:56 die i mensis iv annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2435930 04 iv 4 04/01/1957 die i mensis iv annoque mcmlvii 57 lvii 1957}
+test clock-2.680 {conversion of 1957-04-30} {
+ clock format -399900304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1957 12:34:56 die xxx mensis iv annoque mcmlvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2435959 04 iv 4 04/30/1957 die xxx mensis iv annoque mcmlvii 57 lvii 1957}
+test clock-2.681 {conversion of 1957-05-01} {
+ clock format -399813904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1957 12:34:56 die i mensis v annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2435960 05 v 5 05/01/1957 die i mensis v annoque mcmlvii 57 lvii 1957}
+test clock-2.682 {conversion of 1957-05-31} {
+ clock format -397221904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1957 12:34:56 die xxxi mensis v annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2435990 05 v 5 05/31/1957 die xxxi mensis v annoque mcmlvii 57 lvii 1957}
+test clock-2.683 {conversion of 1957-06-01} {
+ clock format -397135504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1957 12:34:56 die i mensis vi annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2435991 06 vi 6 06/01/1957 die i mensis vi annoque mcmlvii 57 lvii 1957}
+test clock-2.684 {conversion of 1957-06-30} {
+ clock format -394629904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1957 12:34:56 die xxx mensis vi annoque mcmlvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2436020 06 vi 6 06/30/1957 die xxx mensis vi annoque mcmlvii 57 lvii 1957}
+test clock-2.685 {conversion of 1957-07-01} {
+ clock format -394543504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1957 12:34:56 die i mensis vii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2436021 07 vii 7 07/01/1957 die i mensis vii annoque mcmlvii 57 lvii 1957}
+test clock-2.686 {conversion of 1957-07-31} {
+ clock format -391951504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1957 12:34:56 die xxxi mensis vii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2436051 07 vii 7 07/31/1957 die xxxi mensis vii annoque mcmlvii 57 lvii 1957}
+test clock-2.687 {conversion of 1957-08-01} {
+ clock format -391865104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1957 12:34:56 die i mensis viii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2436052 08 viii 8 08/01/1957 die i mensis viii annoque mcmlvii 57 lvii 1957}
+test clock-2.688 {conversion of 1957-08-31} {
+ clock format -389273104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1957 12:34:56 die xxxi mensis viii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2436082 08 viii 8 08/31/1957 die xxxi mensis viii annoque mcmlvii 57 lvii 1957}
+test clock-2.689 {conversion of 1957-09-01} {
+ clock format -389186704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1957 12:34:56 die i mensis ix annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2436083 09 ix 9 09/01/1957 die i mensis ix annoque mcmlvii 57 lvii 1957}
+test clock-2.690 {conversion of 1957-09-30} {
+ clock format -386681104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1957 12:34:56 die xxx mensis ix annoque mcmlvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2436112 09 ix 9 09/30/1957 die xxx mensis ix annoque mcmlvii 57 lvii 1957}
+test clock-2.691 {conversion of 1957-10-01} {
+ clock format -386594704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1957 12:34:56 die i mensis x annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2436113 10 x 10 10/01/1957 die i mensis x annoque mcmlvii 57 lvii 1957}
+test clock-2.692 {conversion of 1957-10-31} {
+ clock format -384002704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1957 12:34:56 die xxxi mensis x annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2436143 10 x 10 10/31/1957 die xxxi mensis x annoque mcmlvii 57 lvii 1957}
+test clock-2.693 {conversion of 1957-11-01} {
+ clock format -383916304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1957 12:34:56 die i mensis xi annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2436144 11 xi 11 11/01/1957 die i mensis xi annoque mcmlvii 57 lvii 1957}
+test clock-2.694 {conversion of 1957-11-30} {
+ clock format -381410704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1957 12:34:56 die xxx mensis xi annoque mcmlvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2436173 11 xi 11 11/30/1957 die xxx mensis xi annoque mcmlvii 57 lvii 1957}
+test clock-2.695 {conversion of 1957-12-01} {
+ clock format -381324304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1957 12:34:56 die i mensis xii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2436174 12 xii 12 12/01/1957 die i mensis xii annoque mcmlvii 57 lvii 1957}
+test clock-2.696 {conversion of 1957-12-31} {
+ clock format -378732304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1957 12:34:56 die xxxi mensis xii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2436204 12 xii 12 12/31/1957 die xxxi mensis xii annoque mcmlvii 57 lvii 1957}
+test clock-2.697 {conversion of 1959-01-01} {
+ clock format -347109904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1959 12:34:56 die i mensis i annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2436570 01 i 1 01/01/1959 die i mensis i annoque mcmlix 59 lix 1959}
+test clock-2.698 {conversion of 1959-01-31} {
+ clock format -344517904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1959 12:34:56 die xxxi mensis i annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2436600 01 i 1 01/31/1959 die xxxi mensis i annoque mcmlix 59 lix 1959}
+test clock-2.699 {conversion of 1959-02-01} {
+ clock format -344431504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1959 12:34:56 die i mensis ii annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2436601 02 ii 2 02/01/1959 die i mensis ii annoque mcmlix 59 lix 1959}
+test clock-2.700 {conversion of 1959-02-28} {
+ clock format -342098704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1959 12:34:56 die xxviii mensis ii annoque mcmlix xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2436628 02 ii 2 02/28/1959 die xxviii mensis ii annoque mcmlix 59 lix 1959}
+test clock-2.701 {conversion of 1959-03-01} {
+ clock format -342012304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1959 12:34:56 die i mensis iii annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2436629 03 iii 3 03/01/1959 die i mensis iii annoque mcmlix 59 lix 1959}
+test clock-2.702 {conversion of 1959-03-31} {
+ clock format -339420304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1959 12:34:56 die xxxi mensis iii annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2436659 03 iii 3 03/31/1959 die xxxi mensis iii annoque mcmlix 59 lix 1959}
+test clock-2.703 {conversion of 1959-04-01} {
+ clock format -339333904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1959 12:34:56 die i mensis iv annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2436660 04 iv 4 04/01/1959 die i mensis iv annoque mcmlix 59 lix 1959}
+test clock-2.704 {conversion of 1959-04-30} {
+ clock format -336828304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1959 12:34:56 die xxx mensis iv annoque mcmlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2436689 04 iv 4 04/30/1959 die xxx mensis iv annoque mcmlix 59 lix 1959}
+test clock-2.705 {conversion of 1959-05-01} {
+ clock format -336741904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1959 12:34:56 die i mensis v annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2436690 05 v 5 05/01/1959 die i mensis v annoque mcmlix 59 lix 1959}
+test clock-2.706 {conversion of 1959-05-31} {
+ clock format -334149904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1959 12:34:56 die xxxi mensis v annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2436720 05 v 5 05/31/1959 die xxxi mensis v annoque mcmlix 59 lix 1959}
+test clock-2.707 {conversion of 1959-06-01} {
+ clock format -334063504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1959 12:34:56 die i mensis vi annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2436721 06 vi 6 06/01/1959 die i mensis vi annoque mcmlix 59 lix 1959}
+test clock-2.708 {conversion of 1959-06-30} {
+ clock format -331557904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1959 12:34:56 die xxx mensis vi annoque mcmlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2436750 06 vi 6 06/30/1959 die xxx mensis vi annoque mcmlix 59 lix 1959}
+test clock-2.709 {conversion of 1959-07-01} {
+ clock format -331471504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1959 12:34:56 die i mensis vii annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2436751 07 vii 7 07/01/1959 die i mensis vii annoque mcmlix 59 lix 1959}
+test clock-2.710 {conversion of 1959-07-31} {
+ clock format -328879504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1959 12:34:56 die xxxi mensis vii annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2436781 07 vii 7 07/31/1959 die xxxi mensis vii annoque mcmlix 59 lix 1959}
+test clock-2.711 {conversion of 1959-08-01} {
+ clock format -328793104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1959 12:34:56 die i mensis viii annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2436782 08 viii 8 08/01/1959 die i mensis viii annoque mcmlix 59 lix 1959}
+test clock-2.712 {conversion of 1959-08-31} {
+ clock format -326201104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1959 12:34:56 die xxxi mensis viii annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2436812 08 viii 8 08/31/1959 die xxxi mensis viii annoque mcmlix 59 lix 1959}
+test clock-2.713 {conversion of 1959-09-01} {
+ clock format -326114704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1959 12:34:56 die i mensis ix annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2436813 09 ix 9 09/01/1959 die i mensis ix annoque mcmlix 59 lix 1959}
+test clock-2.714 {conversion of 1959-09-30} {
+ clock format -323609104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1959 12:34:56 die xxx mensis ix annoque mcmlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2436842 09 ix 9 09/30/1959 die xxx mensis ix annoque mcmlix 59 lix 1959}
+test clock-2.715 {conversion of 1959-10-01} {
+ clock format -323522704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1959 12:34:56 die i mensis x annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2436843 10 x 10 10/01/1959 die i mensis x annoque mcmlix 59 lix 1959}
+test clock-2.716 {conversion of 1959-10-31} {
+ clock format -320930704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1959 12:34:56 die xxxi mensis x annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2436873 10 x 10 10/31/1959 die xxxi mensis x annoque mcmlix 59 lix 1959}
+test clock-2.717 {conversion of 1959-11-01} {
+ clock format -320844304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1959 12:34:56 die i mensis xi annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2436874 11 xi 11 11/01/1959 die i mensis xi annoque mcmlix 59 lix 1959}
+test clock-2.718 {conversion of 1959-11-30} {
+ clock format -318338704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1959 12:34:56 die xxx mensis xi annoque mcmlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2436903 11 xi 11 11/30/1959 die xxx mensis xi annoque mcmlix 59 lix 1959}
+test clock-2.719 {conversion of 1959-12-01} {
+ clock format -318252304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1959 12:34:56 die i mensis xii annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2436904 12 xii 12 12/01/1959 die i mensis xii annoque mcmlix 59 lix 1959}
+test clock-2.720 {conversion of 1959-12-31} {
+ clock format -315660304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1959 12:34:56 die xxxi mensis xii annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2436934 12 xii 12 12/31/1959 die xxxi mensis xii annoque mcmlix 59 lix 1959}
+test clock-2.721 {conversion of 1960-01-01} {
+ clock format -315573904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1960 12:34:56 die i mensis i annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2436935 01 i 1 01/01/1960 die i mensis i annoque mcmlx 60 lx 1960}
+test clock-2.722 {conversion of 1960-01-31} {
+ clock format -312981904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1960 12:34:56 die xxxi mensis i annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2436965 01 i 1 01/31/1960 die xxxi mensis i annoque mcmlx 60 lx 1960}
+test clock-2.723 {conversion of 1960-02-01} {
+ clock format -312895504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1960 12:34:56 die i mensis ii annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2436966 02 ii 2 02/01/1960 die i mensis ii annoque mcmlx 60 lx 1960}
+test clock-2.724 {conversion of 1960-02-29} {
+ clock format -310476304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1960 12:34:56 die xxix mensis ii annoque mcmlx xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2436994 02 ii 2 02/29/1960 die xxix mensis ii annoque mcmlx 60 lx 1960}
+test clock-2.725 {conversion of 1960-03-01} {
+ clock format -310389904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1960 12:34:56 die i mensis iii annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2436995 03 iii 3 03/01/1960 die i mensis iii annoque mcmlx 60 lx 1960}
+test clock-2.726 {conversion of 1960-03-31} {
+ clock format -307797904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1960 12:34:56 die xxxi mensis iii annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2437025 03 iii 3 03/31/1960 die xxxi mensis iii annoque mcmlx 60 lx 1960}
+test clock-2.727 {conversion of 1960-04-01} {
+ clock format -307711504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1960 12:34:56 die i mensis iv annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2437026 04 iv 4 04/01/1960 die i mensis iv annoque mcmlx 60 lx 1960}
+test clock-2.728 {conversion of 1960-04-30} {
+ clock format -305205904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1960 12:34:56 die xxx mensis iv annoque mcmlx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2437055 04 iv 4 04/30/1960 die xxx mensis iv annoque mcmlx 60 lx 1960}
+test clock-2.729 {conversion of 1960-05-01} {
+ clock format -305119504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1960 12:34:56 die i mensis v annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2437056 05 v 5 05/01/1960 die i mensis v annoque mcmlx 60 lx 1960}
+test clock-2.730 {conversion of 1960-05-31} {
+ clock format -302527504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1960 12:34:56 die xxxi mensis v annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2437086 05 v 5 05/31/1960 die xxxi mensis v annoque mcmlx 60 lx 1960}
+test clock-2.731 {conversion of 1960-06-01} {
+ clock format -302441104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1960 12:34:56 die i mensis vi annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2437087 06 vi 6 06/01/1960 die i mensis vi annoque mcmlx 60 lx 1960}
+test clock-2.732 {conversion of 1960-06-30} {
+ clock format -299935504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1960 12:34:56 die xxx mensis vi annoque mcmlx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2437116 06 vi 6 06/30/1960 die xxx mensis vi annoque mcmlx 60 lx 1960}
+test clock-2.733 {conversion of 1960-07-01} {
+ clock format -299849104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1960 12:34:56 die i mensis vii annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2437117 07 vii 7 07/01/1960 die i mensis vii annoque mcmlx 60 lx 1960}
+test clock-2.734 {conversion of 1960-07-31} {
+ clock format -297257104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1960 12:34:56 die xxxi mensis vii annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2437147 07 vii 7 07/31/1960 die xxxi mensis vii annoque mcmlx 60 lx 1960}
+test clock-2.735 {conversion of 1960-08-01} {
+ clock format -297170704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1960 12:34:56 die i mensis viii annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2437148 08 viii 8 08/01/1960 die i mensis viii annoque mcmlx 60 lx 1960}
+test clock-2.736 {conversion of 1960-08-31} {
+ clock format -294578704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1960 12:34:56 die xxxi mensis viii annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2437178 08 viii 8 08/31/1960 die xxxi mensis viii annoque mcmlx 60 lx 1960}
+test clock-2.737 {conversion of 1960-09-01} {
+ clock format -294492304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1960 12:34:56 die i mensis ix annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2437179 09 ix 9 09/01/1960 die i mensis ix annoque mcmlx 60 lx 1960}
+test clock-2.738 {conversion of 1960-09-30} {
+ clock format -291986704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1960 12:34:56 die xxx mensis ix annoque mcmlx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2437208 09 ix 9 09/30/1960 die xxx mensis ix annoque mcmlx 60 lx 1960}
+test clock-2.739 {conversion of 1960-10-01} {
+ clock format -291900304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1960 12:34:56 die i mensis x annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2437209 10 x 10 10/01/1960 die i mensis x annoque mcmlx 60 lx 1960}
+test clock-2.740 {conversion of 1960-10-31} {
+ clock format -289308304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1960 12:34:56 die xxxi mensis x annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2437239 10 x 10 10/31/1960 die xxxi mensis x annoque mcmlx 60 lx 1960}
+test clock-2.741 {conversion of 1960-11-01} {
+ clock format -289221904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1960 12:34:56 die i mensis xi annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2437240 11 xi 11 11/01/1960 die i mensis xi annoque mcmlx 60 lx 1960}
+test clock-2.742 {conversion of 1960-11-30} {
+ clock format -286716304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1960 12:34:56 die xxx mensis xi annoque mcmlx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2437269 11 xi 11 11/30/1960 die xxx mensis xi annoque mcmlx 60 lx 1960}
+test clock-2.743 {conversion of 1960-12-01} {
+ clock format -286629904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1960 12:34:56 die i mensis xii annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2437270 12 xii 12 12/01/1960 die i mensis xii annoque mcmlx 60 lx 1960}
+test clock-2.744 {conversion of 1960-12-31} {
+ clock format -284037904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1960 12:34:56 die xxxi mensis xii annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2437300 12 xii 12 12/31/1960 die xxxi mensis xii annoque mcmlx 60 lx 1960}
+test clock-2.745 {conversion of 1961-01-01} {
+ clock format -283951504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1961 12:34:56 die i mensis i annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2437301 01 i 1 01/01/1961 die i mensis i annoque mcmlxi 61 lxi 1961}
+test clock-2.746 {conversion of 1961-01-31} {
+ clock format -281359504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1961 12:34:56 die xxxi mensis i annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2437331 01 i 1 01/31/1961 die xxxi mensis i annoque mcmlxi 61 lxi 1961}
+test clock-2.747 {conversion of 1961-02-01} {
+ clock format -281273104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1961 12:34:56 die i mensis ii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2437332 02 ii 2 02/01/1961 die i mensis ii annoque mcmlxi 61 lxi 1961}
+test clock-2.748 {conversion of 1961-02-28} {
+ clock format -278940304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1961 12:34:56 die xxviii mensis ii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2437359 02 ii 2 02/28/1961 die xxviii mensis ii annoque mcmlxi 61 lxi 1961}
+test clock-2.749 {conversion of 1961-03-01} {
+ clock format -278853904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1961 12:34:56 die i mensis iii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2437360 03 iii 3 03/01/1961 die i mensis iii annoque mcmlxi 61 lxi 1961}
+test clock-2.750 {conversion of 1961-03-31} {
+ clock format -276261904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1961 12:34:56 die xxxi mensis iii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2437390 03 iii 3 03/31/1961 die xxxi mensis iii annoque mcmlxi 61 lxi 1961}
+test clock-2.751 {conversion of 1961-04-01} {
+ clock format -276175504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1961 12:34:56 die i mensis iv annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2437391 04 iv 4 04/01/1961 die i mensis iv annoque mcmlxi 61 lxi 1961}
+test clock-2.752 {conversion of 1961-04-30} {
+ clock format -273669904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1961 12:34:56 die xxx mensis iv annoque mcmlxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2437420 04 iv 4 04/30/1961 die xxx mensis iv annoque mcmlxi 61 lxi 1961}
+test clock-2.753 {conversion of 1961-05-01} {
+ clock format -273583504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1961 12:34:56 die i mensis v annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2437421 05 v 5 05/01/1961 die i mensis v annoque mcmlxi 61 lxi 1961}
+test clock-2.754 {conversion of 1961-05-31} {
+ clock format -270991504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1961 12:34:56 die xxxi mensis v annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2437451 05 v 5 05/31/1961 die xxxi mensis v annoque mcmlxi 61 lxi 1961}
+test clock-2.755 {conversion of 1961-06-01} {
+ clock format -270905104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1961 12:34:56 die i mensis vi annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2437452 06 vi 6 06/01/1961 die i mensis vi annoque mcmlxi 61 lxi 1961}
+test clock-2.756 {conversion of 1961-06-30} {
+ clock format -268399504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1961 12:34:56 die xxx mensis vi annoque mcmlxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2437481 06 vi 6 06/30/1961 die xxx mensis vi annoque mcmlxi 61 lxi 1961}
+test clock-2.757 {conversion of 1961-07-01} {
+ clock format -268313104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1961 12:34:56 die i mensis vii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2437482 07 vii 7 07/01/1961 die i mensis vii annoque mcmlxi 61 lxi 1961}
+test clock-2.758 {conversion of 1961-07-31} {
+ clock format -265721104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1961 12:34:56 die xxxi mensis vii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2437512 07 vii 7 07/31/1961 die xxxi mensis vii annoque mcmlxi 61 lxi 1961}
+test clock-2.759 {conversion of 1961-08-01} {
+ clock format -265634704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1961 12:34:56 die i mensis viii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2437513 08 viii 8 08/01/1961 die i mensis viii annoque mcmlxi 61 lxi 1961}
+test clock-2.760 {conversion of 1961-08-31} {
+ clock format -263042704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1961 12:34:56 die xxxi mensis viii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2437543 08 viii 8 08/31/1961 die xxxi mensis viii annoque mcmlxi 61 lxi 1961}
+test clock-2.761 {conversion of 1961-09-01} {
+ clock format -262956304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1961 12:34:56 die i mensis ix annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2437544 09 ix 9 09/01/1961 die i mensis ix annoque mcmlxi 61 lxi 1961}
+test clock-2.762 {conversion of 1961-09-30} {
+ clock format -260450704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1961 12:34:56 die xxx mensis ix annoque mcmlxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2437573 09 ix 9 09/30/1961 die xxx mensis ix annoque mcmlxi 61 lxi 1961}
+test clock-2.763 {conversion of 1961-10-01} {
+ clock format -260364304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1961 12:34:56 die i mensis x annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2437574 10 x 10 10/01/1961 die i mensis x annoque mcmlxi 61 lxi 1961}
+test clock-2.764 {conversion of 1961-10-31} {
+ clock format -257772304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1961 12:34:56 die xxxi mensis x annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2437604 10 x 10 10/31/1961 die xxxi mensis x annoque mcmlxi 61 lxi 1961}
+test clock-2.765 {conversion of 1961-11-01} {
+ clock format -257685904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1961 12:34:56 die i mensis xi annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2437605 11 xi 11 11/01/1961 die i mensis xi annoque mcmlxi 61 lxi 1961}
+test clock-2.766 {conversion of 1961-11-30} {
+ clock format -255180304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1961 12:34:56 die xxx mensis xi annoque mcmlxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2437634 11 xi 11 11/30/1961 die xxx mensis xi annoque mcmlxi 61 lxi 1961}
+test clock-2.767 {conversion of 1961-12-01} {
+ clock format -255093904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1961 12:34:56 die i mensis xii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2437635 12 xii 12 12/01/1961 die i mensis xii annoque mcmlxi 61 lxi 1961}
+test clock-2.768 {conversion of 1961-12-31} {
+ clock format -252501904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1961 12:34:56 die xxxi mensis xii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2437665 12 xii 12 12/31/1961 die xxxi mensis xii annoque mcmlxi 61 lxi 1961}
+test clock-2.769 {conversion of 1962-01-01} {
+ clock format -252415504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1962 12:34:56 die i mensis i annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2437666 01 i 1 01/01/1962 die i mensis i annoque mcmlxii 62 lxii 1962}
+test clock-2.770 {conversion of 1962-01-31} {
+ clock format -249823504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1962 12:34:56 die xxxi mensis i annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2437696 01 i 1 01/31/1962 die xxxi mensis i annoque mcmlxii 62 lxii 1962}
+test clock-2.771 {conversion of 1962-02-01} {
+ clock format -249737104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1962 12:34:56 die i mensis ii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2437697 02 ii 2 02/01/1962 die i mensis ii annoque mcmlxii 62 lxii 1962}
+test clock-2.772 {conversion of 1962-02-28} {
+ clock format -247404304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1962 12:34:56 die xxviii mensis ii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2437724 02 ii 2 02/28/1962 die xxviii mensis ii annoque mcmlxii 62 lxii 1962}
+test clock-2.773 {conversion of 1962-03-01} {
+ clock format -247317904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1962 12:34:56 die i mensis iii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2437725 03 iii 3 03/01/1962 die i mensis iii annoque mcmlxii 62 lxii 1962}
+test clock-2.774 {conversion of 1962-03-31} {
+ clock format -244725904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1962 12:34:56 die xxxi mensis iii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2437755 03 iii 3 03/31/1962 die xxxi mensis iii annoque mcmlxii 62 lxii 1962}
+test clock-2.775 {conversion of 1962-04-01} {
+ clock format -244639504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1962 12:34:56 die i mensis iv annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2437756 04 iv 4 04/01/1962 die i mensis iv annoque mcmlxii 62 lxii 1962}
+test clock-2.776 {conversion of 1962-04-30} {
+ clock format -242133904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1962 12:34:56 die xxx mensis iv annoque mcmlxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2437785 04 iv 4 04/30/1962 die xxx mensis iv annoque mcmlxii 62 lxii 1962}
+test clock-2.777 {conversion of 1962-05-01} {
+ clock format -242047504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1962 12:34:56 die i mensis v annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2437786 05 v 5 05/01/1962 die i mensis v annoque mcmlxii 62 lxii 1962}
+test clock-2.778 {conversion of 1962-05-31} {
+ clock format -239455504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1962 12:34:56 die xxxi mensis v annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2437816 05 v 5 05/31/1962 die xxxi mensis v annoque mcmlxii 62 lxii 1962}
+test clock-2.779 {conversion of 1962-06-01} {
+ clock format -239369104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1962 12:34:56 die i mensis vi annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2437817 06 vi 6 06/01/1962 die i mensis vi annoque mcmlxii 62 lxii 1962}
+test clock-2.780 {conversion of 1962-06-30} {
+ clock format -236863504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1962 12:34:56 die xxx mensis vi annoque mcmlxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2437846 06 vi 6 06/30/1962 die xxx mensis vi annoque mcmlxii 62 lxii 1962}
+test clock-2.781 {conversion of 1962-07-01} {
+ clock format -236777104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1962 12:34:56 die i mensis vii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2437847 07 vii 7 07/01/1962 die i mensis vii annoque mcmlxii 62 lxii 1962}
+test clock-2.782 {conversion of 1962-07-31} {
+ clock format -234185104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1962 12:34:56 die xxxi mensis vii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2437877 07 vii 7 07/31/1962 die xxxi mensis vii annoque mcmlxii 62 lxii 1962}
+test clock-2.783 {conversion of 1962-08-01} {
+ clock format -234098704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1962 12:34:56 die i mensis viii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2437878 08 viii 8 08/01/1962 die i mensis viii annoque mcmlxii 62 lxii 1962}
+test clock-2.784 {conversion of 1962-08-31} {
+ clock format -231506704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1962 12:34:56 die xxxi mensis viii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2437908 08 viii 8 08/31/1962 die xxxi mensis viii annoque mcmlxii 62 lxii 1962}
+test clock-2.785 {conversion of 1962-09-01} {
+ clock format -231420304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1962 12:34:56 die i mensis ix annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2437909 09 ix 9 09/01/1962 die i mensis ix annoque mcmlxii 62 lxii 1962}
+test clock-2.786 {conversion of 1962-09-30} {
+ clock format -228914704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1962 12:34:56 die xxx mensis ix annoque mcmlxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2437938 09 ix 9 09/30/1962 die xxx mensis ix annoque mcmlxii 62 lxii 1962}
+test clock-2.787 {conversion of 1962-10-01} {
+ clock format -228828304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1962 12:34:56 die i mensis x annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2437939 10 x 10 10/01/1962 die i mensis x annoque mcmlxii 62 lxii 1962}
+test clock-2.788 {conversion of 1962-10-31} {
+ clock format -226236304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1962 12:34:56 die xxxi mensis x annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2437969 10 x 10 10/31/1962 die xxxi mensis x annoque mcmlxii 62 lxii 1962}
+test clock-2.789 {conversion of 1962-11-01} {
+ clock format -226149904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1962 12:34:56 die i mensis xi annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2437970 11 xi 11 11/01/1962 die i mensis xi annoque mcmlxii 62 lxii 1962}
+test clock-2.790 {conversion of 1962-11-30} {
+ clock format -223644304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1962 12:34:56 die xxx mensis xi annoque mcmlxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2437999 11 xi 11 11/30/1962 die xxx mensis xi annoque mcmlxii 62 lxii 1962}
+test clock-2.791 {conversion of 1962-12-01} {
+ clock format -223557904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1962 12:34:56 die i mensis xii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2438000 12 xii 12 12/01/1962 die i mensis xii annoque mcmlxii 62 lxii 1962}
+test clock-2.792 {conversion of 1962-12-31} {
+ clock format -220965904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1962 12:34:56 die xxxi mensis xii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2438030 12 xii 12 12/31/1962 die xxxi mensis xii annoque mcmlxii 62 lxii 1962}
+test clock-2.793 {conversion of 1963-01-01} {
+ clock format -220879504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1963 12:34:56 die i mensis i annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2438031 01 i 1 01/01/1963 die i mensis i annoque mcmlxiii 63 lxiii 1963}
+test clock-2.794 {conversion of 1963-01-31} {
+ clock format -218287504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1963 12:34:56 die xxxi mensis i annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2438061 01 i 1 01/31/1963 die xxxi mensis i annoque mcmlxiii 63 lxiii 1963}
+test clock-2.795 {conversion of 1963-02-01} {
+ clock format -218201104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1963 12:34:56 die i mensis ii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2438062 02 ii 2 02/01/1963 die i mensis ii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.796 {conversion of 1963-02-28} {
+ clock format -215868304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1963 12:34:56 die xxviii mensis ii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2438089 02 ii 2 02/28/1963 die xxviii mensis ii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.797 {conversion of 1963-03-01} {
+ clock format -215781904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1963 12:34:56 die i mensis iii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2438090 03 iii 3 03/01/1963 die i mensis iii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.798 {conversion of 1963-03-31} {
+ clock format -213189904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1963 12:34:56 die xxxi mensis iii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2438120 03 iii 3 03/31/1963 die xxxi mensis iii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.799 {conversion of 1963-04-01} {
+ clock format -213103504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1963 12:34:56 die i mensis iv annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2438121 04 iv 4 04/01/1963 die i mensis iv annoque mcmlxiii 63 lxiii 1963}
+test clock-2.800 {conversion of 1963-04-30} {
+ clock format -210597904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1963 12:34:56 die xxx mensis iv annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2438150 04 iv 4 04/30/1963 die xxx mensis iv annoque mcmlxiii 63 lxiii 1963}
+test clock-2.801 {conversion of 1963-05-01} {
+ clock format -210511504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1963 12:34:56 die i mensis v annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2438151 05 v 5 05/01/1963 die i mensis v annoque mcmlxiii 63 lxiii 1963}
+test clock-2.802 {conversion of 1963-05-31} {
+ clock format -207919504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1963 12:34:56 die xxxi mensis v annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2438181 05 v 5 05/31/1963 die xxxi mensis v annoque mcmlxiii 63 lxiii 1963}
+test clock-2.803 {conversion of 1963-06-01} {
+ clock format -207833104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1963 12:34:56 die i mensis vi annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2438182 06 vi 6 06/01/1963 die i mensis vi annoque mcmlxiii 63 lxiii 1963}
+test clock-2.804 {conversion of 1963-06-30} {
+ clock format -205327504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1963 12:34:56 die xxx mensis vi annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2438211 06 vi 6 06/30/1963 die xxx mensis vi annoque mcmlxiii 63 lxiii 1963}
+test clock-2.805 {conversion of 1963-07-01} {
+ clock format -205241104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1963 12:34:56 die i mensis vii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2438212 07 vii 7 07/01/1963 die i mensis vii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.806 {conversion of 1963-07-31} {
+ clock format -202649104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1963 12:34:56 die xxxi mensis vii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2438242 07 vii 7 07/31/1963 die xxxi mensis vii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.807 {conversion of 1963-08-01} {
+ clock format -202562704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1963 12:34:56 die i mensis viii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2438243 08 viii 8 08/01/1963 die i mensis viii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.808 {conversion of 1963-08-31} {
+ clock format -199970704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1963 12:34:56 die xxxi mensis viii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2438273 08 viii 8 08/31/1963 die xxxi mensis viii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.809 {conversion of 1963-09-01} {
+ clock format -199884304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1963 12:34:56 die i mensis ix annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2438274 09 ix 9 09/01/1963 die i mensis ix annoque mcmlxiii 63 lxiii 1963}
+test clock-2.810 {conversion of 1963-09-30} {
+ clock format -197378704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1963 12:34:56 die xxx mensis ix annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2438303 09 ix 9 09/30/1963 die xxx mensis ix annoque mcmlxiii 63 lxiii 1963}
+test clock-2.811 {conversion of 1963-10-01} {
+ clock format -197292304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1963 12:34:56 die i mensis x annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2438304 10 x 10 10/01/1963 die i mensis x annoque mcmlxiii 63 lxiii 1963}
+test clock-2.812 {conversion of 1963-10-31} {
+ clock format -194700304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1963 12:34:56 die xxxi mensis x annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2438334 10 x 10 10/31/1963 die xxxi mensis x annoque mcmlxiii 63 lxiii 1963}
+test clock-2.813 {conversion of 1963-11-01} {
+ clock format -194613904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1963 12:34:56 die i mensis xi annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2438335 11 xi 11 11/01/1963 die i mensis xi annoque mcmlxiii 63 lxiii 1963}
+test clock-2.814 {conversion of 1963-11-30} {
+ clock format -192108304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1963 12:34:56 die xxx mensis xi annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2438364 11 xi 11 11/30/1963 die xxx mensis xi annoque mcmlxiii 63 lxiii 1963}
+test clock-2.815 {conversion of 1963-12-01} {
+ clock format -192021904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1963 12:34:56 die i mensis xii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2438365 12 xii 12 12/01/1963 die i mensis xii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.816 {conversion of 1963-12-31} {
+ clock format -189429904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1963 12:34:56 die xxxi mensis xii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2438395 12 xii 12 12/31/1963 die xxxi mensis xii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.817 {conversion of 1964-01-01} {
+ clock format -189343504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1964 12:34:56 die i mensis i annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2438396 01 i 1 01/01/1964 die i mensis i annoque mcmlxiv 64 lxiv 1964}
+test clock-2.818 {conversion of 1964-01-31} {
+ clock format -186751504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1964 12:34:56 die xxxi mensis i annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2438426 01 i 1 01/31/1964 die xxxi mensis i annoque mcmlxiv 64 lxiv 1964}
+test clock-2.819 {conversion of 1964-02-01} {
+ clock format -186665104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1964 12:34:56 die i mensis ii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2438427 02 ii 2 02/01/1964 die i mensis ii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.820 {conversion of 1964-02-29} {
+ clock format -184245904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1964 12:34:56 die xxix mensis ii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2438455 02 ii 2 02/29/1964 die xxix mensis ii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.821 {conversion of 1964-03-01} {
+ clock format -184159504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1964 12:34:56 die i mensis iii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2438456 03 iii 3 03/01/1964 die i mensis iii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.822 {conversion of 1964-03-31} {
+ clock format -181567504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1964 12:34:56 die xxxi mensis iii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2438486 03 iii 3 03/31/1964 die xxxi mensis iii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.823 {conversion of 1964-04-01} {
+ clock format -181481104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1964 12:34:56 die i mensis iv annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2438487 04 iv 4 04/01/1964 die i mensis iv annoque mcmlxiv 64 lxiv 1964}
+test clock-2.824 {conversion of 1964-04-30} {
+ clock format -178975504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1964 12:34:56 die xxx mensis iv annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2438516 04 iv 4 04/30/1964 die xxx mensis iv annoque mcmlxiv 64 lxiv 1964}
+test clock-2.825 {conversion of 1964-05-01} {
+ clock format -178889104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1964 12:34:56 die i mensis v annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2438517 05 v 5 05/01/1964 die i mensis v annoque mcmlxiv 64 lxiv 1964}
+test clock-2.826 {conversion of 1964-05-31} {
+ clock format -176297104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1964 12:34:56 die xxxi mensis v annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2438547 05 v 5 05/31/1964 die xxxi mensis v annoque mcmlxiv 64 lxiv 1964}
+test clock-2.827 {conversion of 1964-06-01} {
+ clock format -176210704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1964 12:34:56 die i mensis vi annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2438548 06 vi 6 06/01/1964 die i mensis vi annoque mcmlxiv 64 lxiv 1964}
+test clock-2.828 {conversion of 1964-06-30} {
+ clock format -173705104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1964 12:34:56 die xxx mensis vi annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2438577 06 vi 6 06/30/1964 die xxx mensis vi annoque mcmlxiv 64 lxiv 1964}
+test clock-2.829 {conversion of 1964-07-01} {
+ clock format -173618704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1964 12:34:56 die i mensis vii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2438578 07 vii 7 07/01/1964 die i mensis vii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.830 {conversion of 1964-07-31} {
+ clock format -171026704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1964 12:34:56 die xxxi mensis vii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2438608 07 vii 7 07/31/1964 die xxxi mensis vii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.831 {conversion of 1964-08-01} {
+ clock format -170940304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1964 12:34:56 die i mensis viii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2438609 08 viii 8 08/01/1964 die i mensis viii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.832 {conversion of 1964-08-31} {
+ clock format -168348304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1964 12:34:56 die xxxi mensis viii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2438639 08 viii 8 08/31/1964 die xxxi mensis viii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.833 {conversion of 1964-09-01} {
+ clock format -168261904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1964 12:34:56 die i mensis ix annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2438640 09 ix 9 09/01/1964 die i mensis ix annoque mcmlxiv 64 lxiv 1964}
+test clock-2.834 {conversion of 1964-09-30} {
+ clock format -165756304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1964 12:34:56 die xxx mensis ix annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2438669 09 ix 9 09/30/1964 die xxx mensis ix annoque mcmlxiv 64 lxiv 1964}
+test clock-2.835 {conversion of 1964-10-01} {
+ clock format -165669904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1964 12:34:56 die i mensis x annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2438670 10 x 10 10/01/1964 die i mensis x annoque mcmlxiv 64 lxiv 1964}
+test clock-2.836 {conversion of 1964-10-31} {
+ clock format -163077904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1964 12:34:56 die xxxi mensis x annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2438700 10 x 10 10/31/1964 die xxxi mensis x annoque mcmlxiv 64 lxiv 1964}
+test clock-2.837 {conversion of 1964-11-01} {
+ clock format -162991504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1964 12:34:56 die i mensis xi annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2438701 11 xi 11 11/01/1964 die i mensis xi annoque mcmlxiv 64 lxiv 1964}
+test clock-2.838 {conversion of 1964-11-30} {
+ clock format -160485904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1964 12:34:56 die xxx mensis xi annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2438730 11 xi 11 11/30/1964 die xxx mensis xi annoque mcmlxiv 64 lxiv 1964}
+test clock-2.839 {conversion of 1964-12-01} {
+ clock format -160399504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1964 12:34:56 die i mensis xii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2438731 12 xii 12 12/01/1964 die i mensis xii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.840 {conversion of 1964-12-31} {
+ clock format -157807504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1964 12:34:56 die xxxi mensis xii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2438761 12 xii 12 12/31/1964 die xxxi mensis xii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.841 {conversion of 1965-01-01} {
+ clock format -157721104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1965 12:34:56 die i mensis i annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2438762 01 i 1 01/01/1965 die i mensis i annoque mcmlxv 65 lxv 1965}
+test clock-2.842 {conversion of 1965-01-31} {
+ clock format -155129104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1965 12:34:56 die xxxi mensis i annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2438792 01 i 1 01/31/1965 die xxxi mensis i annoque mcmlxv 65 lxv 1965}
+test clock-2.843 {conversion of 1965-02-01} {
+ clock format -155042704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1965 12:34:56 die i mensis ii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2438793 02 ii 2 02/01/1965 die i mensis ii annoque mcmlxv 65 lxv 1965}
+test clock-2.844 {conversion of 1965-02-28} {
+ clock format -152709904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1965 12:34:56 die xxviii mensis ii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2438820 02 ii 2 02/28/1965 die xxviii mensis ii annoque mcmlxv 65 lxv 1965}
+test clock-2.845 {conversion of 1965-03-01} {
+ clock format -152623504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1965 12:34:56 die i mensis iii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2438821 03 iii 3 03/01/1965 die i mensis iii annoque mcmlxv 65 lxv 1965}
+test clock-2.846 {conversion of 1965-03-31} {
+ clock format -150031504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1965 12:34:56 die xxxi mensis iii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2438851 03 iii 3 03/31/1965 die xxxi mensis iii annoque mcmlxv 65 lxv 1965}
+test clock-2.847 {conversion of 1965-04-01} {
+ clock format -149945104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1965 12:34:56 die i mensis iv annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2438852 04 iv 4 04/01/1965 die i mensis iv annoque mcmlxv 65 lxv 1965}
+test clock-2.848 {conversion of 1965-04-30} {
+ clock format -147439504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1965 12:34:56 die xxx mensis iv annoque mcmlxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2438881 04 iv 4 04/30/1965 die xxx mensis iv annoque mcmlxv 65 lxv 1965}
+test clock-2.849 {conversion of 1965-05-01} {
+ clock format -147353104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1965 12:34:56 die i mensis v annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2438882 05 v 5 05/01/1965 die i mensis v annoque mcmlxv 65 lxv 1965}
+test clock-2.850 {conversion of 1965-05-31} {
+ clock format -144761104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1965 12:34:56 die xxxi mensis v annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2438912 05 v 5 05/31/1965 die xxxi mensis v annoque mcmlxv 65 lxv 1965}
+test clock-2.851 {conversion of 1965-06-01} {
+ clock format -144674704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1965 12:34:56 die i mensis vi annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2438913 06 vi 6 06/01/1965 die i mensis vi annoque mcmlxv 65 lxv 1965}
+test clock-2.852 {conversion of 1965-06-30} {
+ clock format -142169104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1965 12:34:56 die xxx mensis vi annoque mcmlxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2438942 06 vi 6 06/30/1965 die xxx mensis vi annoque mcmlxv 65 lxv 1965}
+test clock-2.853 {conversion of 1965-07-01} {
+ clock format -142082704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1965 12:34:56 die i mensis vii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2438943 07 vii 7 07/01/1965 die i mensis vii annoque mcmlxv 65 lxv 1965}
+test clock-2.854 {conversion of 1965-07-31} {
+ clock format -139490704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1965 12:34:56 die xxxi mensis vii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2438973 07 vii 7 07/31/1965 die xxxi mensis vii annoque mcmlxv 65 lxv 1965}
+test clock-2.855 {conversion of 1965-08-01} {
+ clock format -139404304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1965 12:34:56 die i mensis viii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2438974 08 viii 8 08/01/1965 die i mensis viii annoque mcmlxv 65 lxv 1965}
+test clock-2.856 {conversion of 1965-08-31} {
+ clock format -136812304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1965 12:34:56 die xxxi mensis viii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2439004 08 viii 8 08/31/1965 die xxxi mensis viii annoque mcmlxv 65 lxv 1965}
+test clock-2.857 {conversion of 1965-09-01} {
+ clock format -136725904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1965 12:34:56 die i mensis ix annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2439005 09 ix 9 09/01/1965 die i mensis ix annoque mcmlxv 65 lxv 1965}
+test clock-2.858 {conversion of 1965-09-30} {
+ clock format -134220304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1965 12:34:56 die xxx mensis ix annoque mcmlxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2439034 09 ix 9 09/30/1965 die xxx mensis ix annoque mcmlxv 65 lxv 1965}
+test clock-2.859 {conversion of 1965-10-01} {
+ clock format -134133904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1965 12:34:56 die i mensis x annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2439035 10 x 10 10/01/1965 die i mensis x annoque mcmlxv 65 lxv 1965}
+test clock-2.860 {conversion of 1965-10-31} {
+ clock format -131541904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1965 12:34:56 die xxxi mensis x annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2439065 10 x 10 10/31/1965 die xxxi mensis x annoque mcmlxv 65 lxv 1965}
+test clock-2.861 {conversion of 1965-11-01} {
+ clock format -131455504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1965 12:34:56 die i mensis xi annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2439066 11 xi 11 11/01/1965 die i mensis xi annoque mcmlxv 65 lxv 1965}
+test clock-2.862 {conversion of 1965-11-30} {
+ clock format -128949904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1965 12:34:56 die xxx mensis xi annoque mcmlxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2439095 11 xi 11 11/30/1965 die xxx mensis xi annoque mcmlxv 65 lxv 1965}
+test clock-2.863 {conversion of 1965-12-01} {
+ clock format -128863504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1965 12:34:56 die i mensis xii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2439096 12 xii 12 12/01/1965 die i mensis xii annoque mcmlxv 65 lxv 1965}
+test clock-2.864 {conversion of 1965-12-31} {
+ clock format -126271504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1965 12:34:56 die xxxi mensis xii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2439126 12 xii 12 12/31/1965 die xxxi mensis xii annoque mcmlxv 65 lxv 1965}
+test clock-2.865 {conversion of 1966-01-01} {
+ clock format -126185104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1966 12:34:56 die i mensis i annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2439127 01 i 1 01/01/1966 die i mensis i annoque mcmlxvi 66 lxvi 1966}
+test clock-2.866 {conversion of 1966-01-31} {
+ clock format -123593104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1966 12:34:56 die xxxi mensis i annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2439157 01 i 1 01/31/1966 die xxxi mensis i annoque mcmlxvi 66 lxvi 1966}
+test clock-2.867 {conversion of 1966-02-01} {
+ clock format -123506704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1966 12:34:56 die i mensis ii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2439158 02 ii 2 02/01/1966 die i mensis ii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.868 {conversion of 1966-02-28} {
+ clock format -121173904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1966 12:34:56 die xxviii mensis ii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2439185 02 ii 2 02/28/1966 die xxviii mensis ii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.869 {conversion of 1966-03-01} {
+ clock format -121087504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1966 12:34:56 die i mensis iii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2439186 03 iii 3 03/01/1966 die i mensis iii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.870 {conversion of 1966-03-31} {
+ clock format -118495504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1966 12:34:56 die xxxi mensis iii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2439216 03 iii 3 03/31/1966 die xxxi mensis iii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.871 {conversion of 1966-04-01} {
+ clock format -118409104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1966 12:34:56 die i mensis iv annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2439217 04 iv 4 04/01/1966 die i mensis iv annoque mcmlxvi 66 lxvi 1966}
+test clock-2.872 {conversion of 1966-04-30} {
+ clock format -115903504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1966 12:34:56 die xxx mensis iv annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2439246 04 iv 4 04/30/1966 die xxx mensis iv annoque mcmlxvi 66 lxvi 1966}
+test clock-2.873 {conversion of 1966-05-01} {
+ clock format -115817104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1966 12:34:56 die i mensis v annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2439247 05 v 5 05/01/1966 die i mensis v annoque mcmlxvi 66 lxvi 1966}
+test clock-2.874 {conversion of 1966-05-31} {
+ clock format -113225104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1966 12:34:56 die xxxi mensis v annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2439277 05 v 5 05/31/1966 die xxxi mensis v annoque mcmlxvi 66 lxvi 1966}
+test clock-2.875 {conversion of 1966-06-01} {
+ clock format -113138704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1966 12:34:56 die i mensis vi annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2439278 06 vi 6 06/01/1966 die i mensis vi annoque mcmlxvi 66 lxvi 1966}
+test clock-2.876 {conversion of 1966-06-30} {
+ clock format -110633104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1966 12:34:56 die xxx mensis vi annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2439307 06 vi 6 06/30/1966 die xxx mensis vi annoque mcmlxvi 66 lxvi 1966}
+test clock-2.877 {conversion of 1966-07-01} {
+ clock format -110546704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1966 12:34:56 die i mensis vii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2439308 07 vii 7 07/01/1966 die i mensis vii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.878 {conversion of 1966-07-31} {
+ clock format -107954704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1966 12:34:56 die xxxi mensis vii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2439338 07 vii 7 07/31/1966 die xxxi mensis vii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.879 {conversion of 1966-08-01} {
+ clock format -107868304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1966 12:34:56 die i mensis viii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2439339 08 viii 8 08/01/1966 die i mensis viii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.880 {conversion of 1966-08-31} {
+ clock format -105276304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1966 12:34:56 die xxxi mensis viii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2439369 08 viii 8 08/31/1966 die xxxi mensis viii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.881 {conversion of 1966-09-01} {
+ clock format -105189904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1966 12:34:56 die i mensis ix annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2439370 09 ix 9 09/01/1966 die i mensis ix annoque mcmlxvi 66 lxvi 1966}
+test clock-2.882 {conversion of 1966-09-30} {
+ clock format -102684304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1966 12:34:56 die xxx mensis ix annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2439399 09 ix 9 09/30/1966 die xxx mensis ix annoque mcmlxvi 66 lxvi 1966}
+test clock-2.883 {conversion of 1966-10-01} {
+ clock format -102597904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1966 12:34:56 die i mensis x annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2439400 10 x 10 10/01/1966 die i mensis x annoque mcmlxvi 66 lxvi 1966}
+test clock-2.884 {conversion of 1966-10-31} {
+ clock format -100005904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1966 12:34:56 die xxxi mensis x annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2439430 10 x 10 10/31/1966 die xxxi mensis x annoque mcmlxvi 66 lxvi 1966}
+test clock-2.885 {conversion of 1966-11-01} {
+ clock format -99919504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1966 12:34:56 die i mensis xi annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2439431 11 xi 11 11/01/1966 die i mensis xi annoque mcmlxvi 66 lxvi 1966}
+test clock-2.886 {conversion of 1966-11-30} {
+ clock format -97413904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1966 12:34:56 die xxx mensis xi annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2439460 11 xi 11 11/30/1966 die xxx mensis xi annoque mcmlxvi 66 lxvi 1966}
+test clock-2.887 {conversion of 1966-12-01} {
+ clock format -97327504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1966 12:34:56 die i mensis xii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2439461 12 xii 12 12/01/1966 die i mensis xii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.888 {conversion of 1966-12-31} {
+ clock format -94735504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1966 12:34:56 die xxxi mensis xii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2439491 12 xii 12 12/31/1966 die xxxi mensis xii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.889 {conversion of 1967-01-01} {
+ clock format -94649104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1967 12:34:56 die i mensis i annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2439492 01 i 1 01/01/1967 die i mensis i annoque mcmlxvii 67 lxvii 1967}
+test clock-2.890 {conversion of 1967-01-31} {
+ clock format -92057104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1967 12:34:56 die xxxi mensis i annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2439522 01 i 1 01/31/1967 die xxxi mensis i annoque mcmlxvii 67 lxvii 1967}
+test clock-2.891 {conversion of 1967-02-01} {
+ clock format -91970704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1967 12:34:56 die i mensis ii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2439523 02 ii 2 02/01/1967 die i mensis ii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.892 {conversion of 1967-02-28} {
+ clock format -89637904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1967 12:34:56 die xxviii mensis ii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2439550 02 ii 2 02/28/1967 die xxviii mensis ii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.893 {conversion of 1967-03-01} {
+ clock format -89551504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1967 12:34:56 die i mensis iii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2439551 03 iii 3 03/01/1967 die i mensis iii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.894 {conversion of 1967-03-31} {
+ clock format -86959504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1967 12:34:56 die xxxi mensis iii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2439581 03 iii 3 03/31/1967 die xxxi mensis iii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.895 {conversion of 1967-04-01} {
+ clock format -86873104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1967 12:34:56 die i mensis iv annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2439582 04 iv 4 04/01/1967 die i mensis iv annoque mcmlxvii 67 lxvii 1967}
+test clock-2.896 {conversion of 1967-04-30} {
+ clock format -84367504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1967 12:34:56 die xxx mensis iv annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2439611 04 iv 4 04/30/1967 die xxx mensis iv annoque mcmlxvii 67 lxvii 1967}
+test clock-2.897 {conversion of 1967-05-01} {
+ clock format -84281104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1967 12:34:56 die i mensis v annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2439612 05 v 5 05/01/1967 die i mensis v annoque mcmlxvii 67 lxvii 1967}
+test clock-2.898 {conversion of 1967-05-31} {
+ clock format -81689104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1967 12:34:56 die xxxi mensis v annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2439642 05 v 5 05/31/1967 die xxxi mensis v annoque mcmlxvii 67 lxvii 1967}
+test clock-2.899 {conversion of 1967-06-01} {
+ clock format -81602704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1967 12:34:56 die i mensis vi annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2439643 06 vi 6 06/01/1967 die i mensis vi annoque mcmlxvii 67 lxvii 1967}
+test clock-2.900 {conversion of 1967-06-30} {
+ clock format -79097104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1967 12:34:56 die xxx mensis vi annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2439672 06 vi 6 06/30/1967 die xxx mensis vi annoque mcmlxvii 67 lxvii 1967}
+test clock-2.901 {conversion of 1967-07-01} {
+ clock format -79010704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1967 12:34:56 die i mensis vii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2439673 07 vii 7 07/01/1967 die i mensis vii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.902 {conversion of 1967-07-31} {
+ clock format -76418704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1967 12:34:56 die xxxi mensis vii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2439703 07 vii 7 07/31/1967 die xxxi mensis vii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.903 {conversion of 1967-08-01} {
+ clock format -76332304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1967 12:34:56 die i mensis viii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2439704 08 viii 8 08/01/1967 die i mensis viii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.904 {conversion of 1967-08-31} {
+ clock format -73740304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1967 12:34:56 die xxxi mensis viii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2439734 08 viii 8 08/31/1967 die xxxi mensis viii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.905 {conversion of 1967-09-01} {
+ clock format -73653904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1967 12:34:56 die i mensis ix annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2439735 09 ix 9 09/01/1967 die i mensis ix annoque mcmlxvii 67 lxvii 1967}
+test clock-2.906 {conversion of 1967-09-30} {
+ clock format -71148304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1967 12:34:56 die xxx mensis ix annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2439764 09 ix 9 09/30/1967 die xxx mensis ix annoque mcmlxvii 67 lxvii 1967}
+test clock-2.907 {conversion of 1967-10-01} {
+ clock format -71061904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1967 12:34:56 die i mensis x annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2439765 10 x 10 10/01/1967 die i mensis x annoque mcmlxvii 67 lxvii 1967}
+test clock-2.908 {conversion of 1967-10-31} {
+ clock format -68469904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1967 12:34:56 die xxxi mensis x annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2439795 10 x 10 10/31/1967 die xxxi mensis x annoque mcmlxvii 67 lxvii 1967}
+test clock-2.909 {conversion of 1967-11-01} {
+ clock format -68383504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1967 12:34:56 die i mensis xi annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2439796 11 xi 11 11/01/1967 die i mensis xi annoque mcmlxvii 67 lxvii 1967}
+test clock-2.910 {conversion of 1967-11-30} {
+ clock format -65877904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1967 12:34:56 die xxx mensis xi annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2439825 11 xi 11 11/30/1967 die xxx mensis xi annoque mcmlxvii 67 lxvii 1967}
+test clock-2.911 {conversion of 1967-12-01} {
+ clock format -65791504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1967 12:34:56 die i mensis xii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2439826 12 xii 12 12/01/1967 die i mensis xii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.912 {conversion of 1967-12-31} {
+ clock format -63199504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1967 12:34:56 die xxxi mensis xii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2439856 12 xii 12 12/31/1967 die xxxi mensis xii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.913 {conversion of 1968-01-01} {
+ clock format -63113104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1968 12:34:56 die i mensis i annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2439857 01 i 1 01/01/1968 die i mensis i annoque mcmlxviii 68 lxviii 1968}
+test clock-2.914 {conversion of 1968-01-31} {
+ clock format -60521104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1968 12:34:56 die xxxi mensis i annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2439887 01 i 1 01/31/1968 die xxxi mensis i annoque mcmlxviii 68 lxviii 1968}
+test clock-2.915 {conversion of 1968-02-01} {
+ clock format -60434704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1968 12:34:56 die i mensis ii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2439888 02 ii 2 02/01/1968 die i mensis ii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.916 {conversion of 1968-02-29} {
+ clock format -58015504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1968 12:34:56 die xxix mensis ii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2439916 02 ii 2 02/29/1968 die xxix mensis ii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.917 {conversion of 1968-03-01} {
+ clock format -57929104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1968 12:34:56 die i mensis iii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2439917 03 iii 3 03/01/1968 die i mensis iii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.918 {conversion of 1968-03-31} {
+ clock format -55337104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1968 12:34:56 die xxxi mensis iii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2439947 03 iii 3 03/31/1968 die xxxi mensis iii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.919 {conversion of 1968-04-01} {
+ clock format -55250704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1968 12:34:56 die i mensis iv annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2439948 04 iv 4 04/01/1968 die i mensis iv annoque mcmlxviii 68 lxviii 1968}
+test clock-2.920 {conversion of 1968-04-30} {
+ clock format -52745104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1968 12:34:56 die xxx mensis iv annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2439977 04 iv 4 04/30/1968 die xxx mensis iv annoque mcmlxviii 68 lxviii 1968}
+test clock-2.921 {conversion of 1968-05-01} {
+ clock format -52658704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1968 12:34:56 die i mensis v annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2439978 05 v 5 05/01/1968 die i mensis v annoque mcmlxviii 68 lxviii 1968}
+test clock-2.922 {conversion of 1968-05-31} {
+ clock format -50066704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1968 12:34:56 die xxxi mensis v annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2440008 05 v 5 05/31/1968 die xxxi mensis v annoque mcmlxviii 68 lxviii 1968}
+test clock-2.923 {conversion of 1968-06-01} {
+ clock format -49980304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1968 12:34:56 die i mensis vi annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2440009 06 vi 6 06/01/1968 die i mensis vi annoque mcmlxviii 68 lxviii 1968}
+test clock-2.924 {conversion of 1968-06-30} {
+ clock format -47474704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1968 12:34:56 die xxx mensis vi annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2440038 06 vi 6 06/30/1968 die xxx mensis vi annoque mcmlxviii 68 lxviii 1968}
+test clock-2.925 {conversion of 1968-07-01} {
+ clock format -47388304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1968 12:34:56 die i mensis vii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2440039 07 vii 7 07/01/1968 die i mensis vii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.926 {conversion of 1968-07-31} {
+ clock format -44796304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1968 12:34:56 die xxxi mensis vii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2440069 07 vii 7 07/31/1968 die xxxi mensis vii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.927 {conversion of 1968-08-01} {
+ clock format -44709904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1968 12:34:56 die i mensis viii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2440070 08 viii 8 08/01/1968 die i mensis viii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.928 {conversion of 1968-08-31} {
+ clock format -42117904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1968 12:34:56 die xxxi mensis viii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2440100 08 viii 8 08/31/1968 die xxxi mensis viii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.929 {conversion of 1968-09-01} {
+ clock format -42031504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1968 12:34:56 die i mensis ix annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2440101 09 ix 9 09/01/1968 die i mensis ix annoque mcmlxviii 68 lxviii 1968}
+test clock-2.930 {conversion of 1968-09-30} {
+ clock format -39525904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1968 12:34:56 die xxx mensis ix annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2440130 09 ix 9 09/30/1968 die xxx mensis ix annoque mcmlxviii 68 lxviii 1968}
+test clock-2.931 {conversion of 1968-10-01} {
+ clock format -39439504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1968 12:34:56 die i mensis x annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2440131 10 x 10 10/01/1968 die i mensis x annoque mcmlxviii 68 lxviii 1968}
+test clock-2.932 {conversion of 1968-10-31} {
+ clock format -36847504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1968 12:34:56 die xxxi mensis x annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2440161 10 x 10 10/31/1968 die xxxi mensis x annoque mcmlxviii 68 lxviii 1968}
+test clock-2.933 {conversion of 1968-11-01} {
+ clock format -36761104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1968 12:34:56 die i mensis xi annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2440162 11 xi 11 11/01/1968 die i mensis xi annoque mcmlxviii 68 lxviii 1968}
+test clock-2.934 {conversion of 1968-11-30} {
+ clock format -34255504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1968 12:34:56 die xxx mensis xi annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2440191 11 xi 11 11/30/1968 die xxx mensis xi annoque mcmlxviii 68 lxviii 1968}
+test clock-2.935 {conversion of 1968-12-01} {
+ clock format -34169104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1968 12:34:56 die i mensis xii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2440192 12 xii 12 12/01/1968 die i mensis xii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.936 {conversion of 1968-12-31} {
+ clock format -31577104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1968 12:34:56 die xxxi mensis xii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2440222 12 xii 12 12/31/1968 die xxxi mensis xii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.937 {conversion of 1969-01-01} {
+ clock format -31490704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1969 12:34:56 die i mensis i annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2440223 01 i 1 01/01/1969 die i mensis i annoque mcmlxix 69 lxix 1969}
+test clock-2.938 {conversion of 1969-01-31} {
+ clock format -28898704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1969 12:34:56 die xxxi mensis i annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2440253 01 i 1 01/31/1969 die xxxi mensis i annoque mcmlxix 69 lxix 1969}
+test clock-2.939 {conversion of 1969-02-01} {
+ clock format -28812304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1969 12:34:56 die i mensis ii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2440254 02 ii 2 02/01/1969 die i mensis ii annoque mcmlxix 69 lxix 1969}
+test clock-2.940 {conversion of 1969-02-28} {
+ clock format -26479504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1969 12:34:56 die xxviii mensis ii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2440281 02 ii 2 02/28/1969 die xxviii mensis ii annoque mcmlxix 69 lxix 1969}
+test clock-2.941 {conversion of 1969-03-01} {
+ clock format -26393104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1969 12:34:56 die i mensis iii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2440282 03 iii 3 03/01/1969 die i mensis iii annoque mcmlxix 69 lxix 1969}
+test clock-2.942 {conversion of 1969-03-31} {
+ clock format -23801104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1969 12:34:56 die xxxi mensis iii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2440312 03 iii 3 03/31/1969 die xxxi mensis iii annoque mcmlxix 69 lxix 1969}
+test clock-2.943 {conversion of 1969-04-01} {
+ clock format -23714704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1969 12:34:56 die i mensis iv annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2440313 04 iv 4 04/01/1969 die i mensis iv annoque mcmlxix 69 lxix 1969}
+test clock-2.944 {conversion of 1969-04-30} {
+ clock format -21209104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1969 12:34:56 die xxx mensis iv annoque mcmlxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2440342 04 iv 4 04/30/1969 die xxx mensis iv annoque mcmlxix 69 lxix 1969}
+test clock-2.945 {conversion of 1969-05-01} {
+ clock format -21122704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1969 12:34:56 die i mensis v annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2440343 05 v 5 05/01/1969 die i mensis v annoque mcmlxix 69 lxix 1969}
+test clock-2.946 {conversion of 1969-05-31} {
+ clock format -18530704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1969 12:34:56 die xxxi mensis v annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2440373 05 v 5 05/31/1969 die xxxi mensis v annoque mcmlxix 69 lxix 1969}
+test clock-2.947 {conversion of 1969-06-01} {
+ clock format -18444304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1969 12:34:56 die i mensis vi annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2440374 06 vi 6 06/01/1969 die i mensis vi annoque mcmlxix 69 lxix 1969}
+test clock-2.948 {conversion of 1969-06-30} {
+ clock format -15938704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1969 12:34:56 die xxx mensis vi annoque mcmlxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2440403 06 vi 6 06/30/1969 die xxx mensis vi annoque mcmlxix 69 lxix 1969}
+test clock-2.949 {conversion of 1969-07-01} {
+ clock format -15852304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1969 12:34:56 die i mensis vii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2440404 07 vii 7 07/01/1969 die i mensis vii annoque mcmlxix 69 lxix 1969}
+test clock-2.950 {conversion of 1969-07-31} {
+ clock format -13260304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1969 12:34:56 die xxxi mensis vii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2440434 07 vii 7 07/31/1969 die xxxi mensis vii annoque mcmlxix 69 lxix 1969}
+test clock-2.951 {conversion of 1969-08-01} {
+ clock format -13173904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1969 12:34:56 die i mensis viii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2440435 08 viii 8 08/01/1969 die i mensis viii annoque mcmlxix 69 lxix 1969}
+test clock-2.952 {conversion of 1969-08-31} {
+ clock format -10581904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1969 12:34:56 die xxxi mensis viii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2440465 08 viii 8 08/31/1969 die xxxi mensis viii annoque mcmlxix 69 lxix 1969}
+test clock-2.953 {conversion of 1969-09-01} {
+ clock format -10495504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1969 12:34:56 die i mensis ix annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2440466 09 ix 9 09/01/1969 die i mensis ix annoque mcmlxix 69 lxix 1969}
+test clock-2.954 {conversion of 1969-09-30} {
+ clock format -7989904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1969 12:34:56 die xxx mensis ix annoque mcmlxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2440495 09 ix 9 09/30/1969 die xxx mensis ix annoque mcmlxix 69 lxix 1969}
+test clock-2.955 {conversion of 1969-10-01} {
+ clock format -7903504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1969 12:34:56 die i mensis x annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2440496 10 x 10 10/01/1969 die i mensis x annoque mcmlxix 69 lxix 1969}
+test clock-2.956 {conversion of 1969-10-31} {
+ clock format -5311504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1969 12:34:56 die xxxi mensis x annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2440526 10 x 10 10/31/1969 die xxxi mensis x annoque mcmlxix 69 lxix 1969}
+test clock-2.957 {conversion of 1969-11-01} {
+ clock format -5225104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1969 12:34:56 die i mensis xi annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2440527 11 xi 11 11/01/1969 die i mensis xi annoque mcmlxix 69 lxix 1969}
+test clock-2.958 {conversion of 1969-11-30} {
+ clock format -2719504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1969 12:34:56 die xxx mensis xi annoque mcmlxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2440556 11 xi 11 11/30/1969 die xxx mensis xi annoque mcmlxix 69 lxix 1969}
+test clock-2.959 {conversion of 1969-12-01} {
+ clock format -2633104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1969 12:34:56 die i mensis xii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2440557 12 xii 12 12/01/1969 die i mensis xii annoque mcmlxix 69 lxix 1969}
+test clock-2.960 {conversion of 1969-12-31} {
+ clock format -41104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1969 12:34:56 die xxxi mensis xii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2440587 12 xii 12 12/31/1969 die xxxi mensis xii annoque mcmlxix 69 lxix 1969}
+test clock-2.961 {conversion of 1970-01-01} {
+ clock format 45296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1970 12:34:56 die i mensis i annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2440588 01 i 1 01/01/1970 die i mensis i annoque mcmlxx 70 lxx 1970}
+test clock-2.962 {conversion of 1970-01-31} {
+ clock format 2637296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1970 12:34:56 die xxxi mensis i annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2440618 01 i 1 01/31/1970 die xxxi mensis i annoque mcmlxx 70 lxx 1970}
+test clock-2.963 {conversion of 1970-02-01} {
+ clock format 2723696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1970 12:34:56 die i mensis ii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2440619 02 ii 2 02/01/1970 die i mensis ii annoque mcmlxx 70 lxx 1970}
+test clock-2.964 {conversion of 1970-02-28} {
+ clock format 5056496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1970 12:34:56 die xxviii mensis ii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2440646 02 ii 2 02/28/1970 die xxviii mensis ii annoque mcmlxx 70 lxx 1970}
+test clock-2.965 {conversion of 1970-03-01} {
+ clock format 5142896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1970 12:34:56 die i mensis iii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2440647 03 iii 3 03/01/1970 die i mensis iii annoque mcmlxx 70 lxx 1970}
+test clock-2.966 {conversion of 1970-03-31} {
+ clock format 7734896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1970 12:34:56 die xxxi mensis iii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2440677 03 iii 3 03/31/1970 die xxxi mensis iii annoque mcmlxx 70 lxx 1970}
+test clock-2.967 {conversion of 1970-04-01} {
+ clock format 7821296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1970 12:34:56 die i mensis iv annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2440678 04 iv 4 04/01/1970 die i mensis iv annoque mcmlxx 70 lxx 1970}
+test clock-2.968 {conversion of 1970-04-30} {
+ clock format 10326896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1970 12:34:56 die xxx mensis iv annoque mcmlxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2440707 04 iv 4 04/30/1970 die xxx mensis iv annoque mcmlxx 70 lxx 1970}
+test clock-2.969 {conversion of 1970-05-01} {
+ clock format 10413296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1970 12:34:56 die i mensis v annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2440708 05 v 5 05/01/1970 die i mensis v annoque mcmlxx 70 lxx 1970}
+test clock-2.970 {conversion of 1970-05-31} {
+ clock format 13005296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1970 12:34:56 die xxxi mensis v annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2440738 05 v 5 05/31/1970 die xxxi mensis v annoque mcmlxx 70 lxx 1970}
+test clock-2.971 {conversion of 1970-06-01} {
+ clock format 13091696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1970 12:34:56 die i mensis vi annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2440739 06 vi 6 06/01/1970 die i mensis vi annoque mcmlxx 70 lxx 1970}
+test clock-2.972 {conversion of 1970-06-30} {
+ clock format 15597296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1970 12:34:56 die xxx mensis vi annoque mcmlxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2440768 06 vi 6 06/30/1970 die xxx mensis vi annoque mcmlxx 70 lxx 1970}
+test clock-2.973 {conversion of 1970-07-01} {
+ clock format 15683696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1970 12:34:56 die i mensis vii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2440769 07 vii 7 07/01/1970 die i mensis vii annoque mcmlxx 70 lxx 1970}
+test clock-2.974 {conversion of 1970-07-31} {
+ clock format 18275696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1970 12:34:56 die xxxi mensis vii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2440799 07 vii 7 07/31/1970 die xxxi mensis vii annoque mcmlxx 70 lxx 1970}
+test clock-2.975 {conversion of 1970-08-01} {
+ clock format 18362096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1970 12:34:56 die i mensis viii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2440800 08 viii 8 08/01/1970 die i mensis viii annoque mcmlxx 70 lxx 1970}
+test clock-2.976 {conversion of 1970-08-31} {
+ clock format 20954096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1970 12:34:56 die xxxi mensis viii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2440830 08 viii 8 08/31/1970 die xxxi mensis viii annoque mcmlxx 70 lxx 1970}
+test clock-2.977 {conversion of 1970-09-01} {
+ clock format 21040496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1970 12:34:56 die i mensis ix annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2440831 09 ix 9 09/01/1970 die i mensis ix annoque mcmlxx 70 lxx 1970}
+test clock-2.978 {conversion of 1970-09-30} {
+ clock format 23546096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1970 12:34:56 die xxx mensis ix annoque mcmlxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2440860 09 ix 9 09/30/1970 die xxx mensis ix annoque mcmlxx 70 lxx 1970}
+test clock-2.979 {conversion of 1970-10-01} {
+ clock format 23632496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1970 12:34:56 die i mensis x annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2440861 10 x 10 10/01/1970 die i mensis x annoque mcmlxx 70 lxx 1970}
+test clock-2.980 {conversion of 1970-10-31} {
+ clock format 26224496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1970 12:34:56 die xxxi mensis x annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2440891 10 x 10 10/31/1970 die xxxi mensis x annoque mcmlxx 70 lxx 1970}
+test clock-2.981 {conversion of 1970-11-01} {
+ clock format 26310896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1970 12:34:56 die i mensis xi annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2440892 11 xi 11 11/01/1970 die i mensis xi annoque mcmlxx 70 lxx 1970}
+test clock-2.982 {conversion of 1970-11-30} {
+ clock format 28816496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1970 12:34:56 die xxx mensis xi annoque mcmlxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2440921 11 xi 11 11/30/1970 die xxx mensis xi annoque mcmlxx 70 lxx 1970}
+test clock-2.983 {conversion of 1970-12-01} {
+ clock format 28902896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1970 12:34:56 die i mensis xii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2440922 12 xii 12 12/01/1970 die i mensis xii annoque mcmlxx 70 lxx 1970}
+test clock-2.984 {conversion of 1970-12-31} {
+ clock format 31494896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1970 12:34:56 die xxxi mensis xii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2440952 12 xii 12 12/31/1970 die xxxi mensis xii annoque mcmlxx 70 lxx 1970}
+test clock-2.985 {conversion of 1971-01-01} {
+ clock format 31581296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1971 12:34:56 die i mensis i annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2440953 01 i 1 01/01/1971 die i mensis i annoque mcmlxxi 71 lxxi 1971}
+test clock-2.986 {conversion of 1971-01-31} {
+ clock format 34173296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1971 12:34:56 die xxxi mensis i annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2440983 01 i 1 01/31/1971 die xxxi mensis i annoque mcmlxxi 71 lxxi 1971}
+test clock-2.987 {conversion of 1971-02-01} {
+ clock format 34259696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1971 12:34:56 die i mensis ii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2440984 02 ii 2 02/01/1971 die i mensis ii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.988 {conversion of 1971-02-28} {
+ clock format 36592496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1971 12:34:56 die xxviii mensis ii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2441011 02 ii 2 02/28/1971 die xxviii mensis ii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.989 {conversion of 1971-03-01} {
+ clock format 36678896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1971 12:34:56 die i mensis iii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2441012 03 iii 3 03/01/1971 die i mensis iii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.990 {conversion of 1971-03-31} {
+ clock format 39270896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1971 12:34:56 die xxxi mensis iii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2441042 03 iii 3 03/31/1971 die xxxi mensis iii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.991 {conversion of 1971-04-01} {
+ clock format 39357296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1971 12:34:56 die i mensis iv annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2441043 04 iv 4 04/01/1971 die i mensis iv annoque mcmlxxi 71 lxxi 1971}
+test clock-2.992 {conversion of 1971-04-30} {
+ clock format 41862896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1971 12:34:56 die xxx mensis iv annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2441072 04 iv 4 04/30/1971 die xxx mensis iv annoque mcmlxxi 71 lxxi 1971}
+test clock-2.993 {conversion of 1971-05-01} {
+ clock format 41949296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1971 12:34:56 die i mensis v annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2441073 05 v 5 05/01/1971 die i mensis v annoque mcmlxxi 71 lxxi 1971}
+test clock-2.994 {conversion of 1971-05-31} {
+ clock format 44541296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1971 12:34:56 die xxxi mensis v annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2441103 05 v 5 05/31/1971 die xxxi mensis v annoque mcmlxxi 71 lxxi 1971}
+test clock-2.995 {conversion of 1971-06-01} {
+ clock format 44627696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1971 12:34:56 die i mensis vi annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2441104 06 vi 6 06/01/1971 die i mensis vi annoque mcmlxxi 71 lxxi 1971}
+test clock-2.996 {conversion of 1971-06-30} {
+ clock format 47133296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1971 12:34:56 die xxx mensis vi annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2441133 06 vi 6 06/30/1971 die xxx mensis vi annoque mcmlxxi 71 lxxi 1971}
+test clock-2.997 {conversion of 1971-07-01} {
+ clock format 47219696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1971 12:34:56 die i mensis vii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2441134 07 vii 7 07/01/1971 die i mensis vii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.998 {conversion of 1971-07-31} {
+ clock format 49811696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1971 12:34:56 die xxxi mensis vii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2441164 07 vii 7 07/31/1971 die xxxi mensis vii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.999 {conversion of 1971-08-01} {
+ clock format 49898096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1971 12:34:56 die i mensis viii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2441165 08 viii 8 08/01/1971 die i mensis viii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1000 {conversion of 1971-08-31} {
+ clock format 52490096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1971 12:34:56 die xxxi mensis viii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2441195 08 viii 8 08/31/1971 die xxxi mensis viii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1001 {conversion of 1971-09-01} {
+ clock format 52576496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1971 12:34:56 die i mensis ix annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2441196 09 ix 9 09/01/1971 die i mensis ix annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1002 {conversion of 1971-09-30} {
+ clock format 55082096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1971 12:34:56 die xxx mensis ix annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2441225 09 ix 9 09/30/1971 die xxx mensis ix annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1003 {conversion of 1971-10-01} {
+ clock format 55168496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1971 12:34:56 die i mensis x annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2441226 10 x 10 10/01/1971 die i mensis x annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1004 {conversion of 1971-10-31} {
+ clock format 57760496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1971 12:34:56 die xxxi mensis x annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2441256 10 x 10 10/31/1971 die xxxi mensis x annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1005 {conversion of 1971-11-01} {
+ clock format 57846896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1971 12:34:56 die i mensis xi annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2441257 11 xi 11 11/01/1971 die i mensis xi annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1006 {conversion of 1971-11-30} {
+ clock format 60352496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1971 12:34:56 die xxx mensis xi annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2441286 11 xi 11 11/30/1971 die xxx mensis xi annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1007 {conversion of 1971-12-01} {
+ clock format 60438896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1971 12:34:56 die i mensis xii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2441287 12 xii 12 12/01/1971 die i mensis xii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1008 {conversion of 1971-12-31} {
+ clock format 63030896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1971 12:34:56 die xxxi mensis xii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2441317 12 xii 12 12/31/1971 die xxxi mensis xii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1009 {conversion of 1972-01-01} {
+ clock format 63117296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1972 12:34:56 die i mensis i annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2441318 01 i 1 01/01/1972 die i mensis i annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1010 {conversion of 1972-01-31} {
+ clock format 65709296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1972 12:34:56 die xxxi mensis i annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2441348 01 i 1 01/31/1972 die xxxi mensis i annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1011 {conversion of 1972-02-01} {
+ clock format 65795696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1972 12:34:56 die i mensis ii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2441349 02 ii 2 02/01/1972 die i mensis ii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1012 {conversion of 1972-02-29} {
+ clock format 68214896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1972 12:34:56 die xxix mensis ii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2441377 02 ii 2 02/29/1972 die xxix mensis ii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1013 {conversion of 1972-03-01} {
+ clock format 68301296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1972 12:34:56 die i mensis iii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2441378 03 iii 3 03/01/1972 die i mensis iii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1014 {conversion of 1972-03-31} {
+ clock format 70893296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1972 12:34:56 die xxxi mensis iii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2441408 03 iii 3 03/31/1972 die xxxi mensis iii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1015 {conversion of 1972-04-01} {
+ clock format 70979696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1972 12:34:56 die i mensis iv annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2441409 04 iv 4 04/01/1972 die i mensis iv annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1016 {conversion of 1972-04-30} {
+ clock format 73485296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1972 12:34:56 die xxx mensis iv annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2441438 04 iv 4 04/30/1972 die xxx mensis iv annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1017 {conversion of 1972-05-01} {
+ clock format 73571696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1972 12:34:56 die i mensis v annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2441439 05 v 5 05/01/1972 die i mensis v annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1018 {conversion of 1972-05-31} {
+ clock format 76163696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1972 12:34:56 die xxxi mensis v annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2441469 05 v 5 05/31/1972 die xxxi mensis v annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1019 {conversion of 1972-06-01} {
+ clock format 76250096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1972 12:34:56 die i mensis vi annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2441470 06 vi 6 06/01/1972 die i mensis vi annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1020 {conversion of 1972-06-30} {
+ clock format 78755696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1972 12:34:56 die xxx mensis vi annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2441499 06 vi 6 06/30/1972 die xxx mensis vi annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1021 {conversion of 1972-07-01} {
+ clock format 78842096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1972 12:34:56 die i mensis vii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2441500 07 vii 7 07/01/1972 die i mensis vii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1022 {conversion of 1972-07-31} {
+ clock format 81434096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1972 12:34:56 die xxxi mensis vii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2441530 07 vii 7 07/31/1972 die xxxi mensis vii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1023 {conversion of 1972-08-01} {
+ clock format 81520496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1972 12:34:56 die i mensis viii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2441531 08 viii 8 08/01/1972 die i mensis viii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1024 {conversion of 1972-08-31} {
+ clock format 84112496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1972 12:34:56 die xxxi mensis viii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2441561 08 viii 8 08/31/1972 die xxxi mensis viii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1025 {conversion of 1972-09-01} {
+ clock format 84198896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1972 12:34:56 die i mensis ix annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2441562 09 ix 9 09/01/1972 die i mensis ix annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1026 {conversion of 1972-09-30} {
+ clock format 86704496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1972 12:34:56 die xxx mensis ix annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2441591 09 ix 9 09/30/1972 die xxx mensis ix annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1027 {conversion of 1972-10-01} {
+ clock format 86790896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1972 12:34:56 die i mensis x annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2441592 10 x 10 10/01/1972 die i mensis x annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1028 {conversion of 1972-10-31} {
+ clock format 89382896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1972 12:34:56 die xxxi mensis x annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2441622 10 x 10 10/31/1972 die xxxi mensis x annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1029 {conversion of 1972-11-01} {
+ clock format 89469296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1972 12:34:56 die i mensis xi annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2441623 11 xi 11 11/01/1972 die i mensis xi annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1030 {conversion of 1972-11-30} {
+ clock format 91974896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1972 12:34:56 die xxx mensis xi annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2441652 11 xi 11 11/30/1972 die xxx mensis xi annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1031 {conversion of 1972-12-01} {
+ clock format 92061296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1972 12:34:56 die i mensis xii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2441653 12 xii 12 12/01/1972 die i mensis xii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1032 {conversion of 1972-12-31} {
+ clock format 94653296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1972 12:34:56 die xxxi mensis xii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2441683 12 xii 12 12/31/1972 die xxxi mensis xii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1033 {conversion of 1973-01-01} {
+ clock format 94739696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1973 12:34:56 die i mensis i annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2441684 01 i 1 01/01/1973 die i mensis i annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1034 {conversion of 1973-01-31} {
+ clock format 97331696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1973 12:34:56 die xxxi mensis i annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2441714 01 i 1 01/31/1973 die xxxi mensis i annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1035 {conversion of 1973-02-01} {
+ clock format 97418096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1973 12:34:56 die i mensis ii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2441715 02 ii 2 02/01/1973 die i mensis ii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1036 {conversion of 1973-02-28} {
+ clock format 99750896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1973 12:34:56 die xxviii mensis ii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2441742 02 ii 2 02/28/1973 die xxviii mensis ii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1037 {conversion of 1973-03-01} {
+ clock format 99837296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1973 12:34:56 die i mensis iii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2441743 03 iii 3 03/01/1973 die i mensis iii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1038 {conversion of 1973-03-31} {
+ clock format 102429296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1973 12:34:56 die xxxi mensis iii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2441773 03 iii 3 03/31/1973 die xxxi mensis iii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1039 {conversion of 1973-04-01} {
+ clock format 102515696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1973 12:34:56 die i mensis iv annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2441774 04 iv 4 04/01/1973 die i mensis iv annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1040 {conversion of 1973-04-30} {
+ clock format 105021296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1973 12:34:56 die xxx mensis iv annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2441803 04 iv 4 04/30/1973 die xxx mensis iv annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1041 {conversion of 1973-05-01} {
+ clock format 105107696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1973 12:34:56 die i mensis v annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2441804 05 v 5 05/01/1973 die i mensis v annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1042 {conversion of 1973-05-31} {
+ clock format 107699696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1973 12:34:56 die xxxi mensis v annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2441834 05 v 5 05/31/1973 die xxxi mensis v annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1043 {conversion of 1973-06-01} {
+ clock format 107786096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1973 12:34:56 die i mensis vi annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2441835 06 vi 6 06/01/1973 die i mensis vi annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1044 {conversion of 1973-06-30} {
+ clock format 110291696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1973 12:34:56 die xxx mensis vi annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2441864 06 vi 6 06/30/1973 die xxx mensis vi annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1045 {conversion of 1973-07-01} {
+ clock format 110378096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1973 12:34:56 die i mensis vii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2441865 07 vii 7 07/01/1973 die i mensis vii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1046 {conversion of 1973-07-31} {
+ clock format 112970096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1973 12:34:56 die xxxi mensis vii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2441895 07 vii 7 07/31/1973 die xxxi mensis vii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1047 {conversion of 1973-08-01} {
+ clock format 113056496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1973 12:34:56 die i mensis viii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2441896 08 viii 8 08/01/1973 die i mensis viii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1048 {conversion of 1973-08-31} {
+ clock format 115648496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1973 12:34:56 die xxxi mensis viii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2441926 08 viii 8 08/31/1973 die xxxi mensis viii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1049 {conversion of 1973-09-01} {
+ clock format 115734896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1973 12:34:56 die i mensis ix annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2441927 09 ix 9 09/01/1973 die i mensis ix annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1050 {conversion of 1973-09-30} {
+ clock format 118240496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1973 12:34:56 die xxx mensis ix annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2441956 09 ix 9 09/30/1973 die xxx mensis ix annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1051 {conversion of 1973-10-01} {
+ clock format 118326896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1973 12:34:56 die i mensis x annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2441957 10 x 10 10/01/1973 die i mensis x annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1052 {conversion of 1973-10-31} {
+ clock format 120918896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1973 12:34:56 die xxxi mensis x annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2441987 10 x 10 10/31/1973 die xxxi mensis x annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1053 {conversion of 1973-11-01} {
+ clock format 121005296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1973 12:34:56 die i mensis xi annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2441988 11 xi 11 11/01/1973 die i mensis xi annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1054 {conversion of 1973-11-30} {
+ clock format 123510896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1973 12:34:56 die xxx mensis xi annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2442017 11 xi 11 11/30/1973 die xxx mensis xi annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1055 {conversion of 1973-12-01} {
+ clock format 123597296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1973 12:34:56 die i mensis xii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2442018 12 xii 12 12/01/1973 die i mensis xii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1056 {conversion of 1973-12-31} {
+ clock format 126189296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1973 12:34:56 die xxxi mensis xii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2442048 12 xii 12 12/31/1973 die xxxi mensis xii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1057 {conversion of 1974-01-01} {
+ clock format 126275696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1974 12:34:56 die i mensis i annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2442049 01 i 1 01/01/1974 die i mensis i annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1058 {conversion of 1974-01-31} {
+ clock format 128867696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1974 12:34:56 die xxxi mensis i annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2442079 01 i 1 01/31/1974 die xxxi mensis i annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1059 {conversion of 1974-02-01} {
+ clock format 128954096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1974 12:34:56 die i mensis ii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2442080 02 ii 2 02/01/1974 die i mensis ii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1060 {conversion of 1974-02-28} {
+ clock format 131286896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1974 12:34:56 die xxviii mensis ii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2442107 02 ii 2 02/28/1974 die xxviii mensis ii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1061 {conversion of 1974-03-01} {
+ clock format 131373296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1974 12:34:56 die i mensis iii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2442108 03 iii 3 03/01/1974 die i mensis iii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1062 {conversion of 1974-03-31} {
+ clock format 133965296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1974 12:34:56 die xxxi mensis iii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2442138 03 iii 3 03/31/1974 die xxxi mensis iii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1063 {conversion of 1974-04-01} {
+ clock format 134051696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1974 12:34:56 die i mensis iv annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2442139 04 iv 4 04/01/1974 die i mensis iv annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1064 {conversion of 1974-04-30} {
+ clock format 136557296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1974 12:34:56 die xxx mensis iv annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2442168 04 iv 4 04/30/1974 die xxx mensis iv annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1065 {conversion of 1974-05-01} {
+ clock format 136643696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1974 12:34:56 die i mensis v annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2442169 05 v 5 05/01/1974 die i mensis v annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1066 {conversion of 1974-05-31} {
+ clock format 139235696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1974 12:34:56 die xxxi mensis v annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2442199 05 v 5 05/31/1974 die xxxi mensis v annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1067 {conversion of 1974-06-01} {
+ clock format 139322096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1974 12:34:56 die i mensis vi annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2442200 06 vi 6 06/01/1974 die i mensis vi annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1068 {conversion of 1974-06-30} {
+ clock format 141827696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1974 12:34:56 die xxx mensis vi annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2442229 06 vi 6 06/30/1974 die xxx mensis vi annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1069 {conversion of 1974-07-01} {
+ clock format 141914096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1974 12:34:56 die i mensis vii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2442230 07 vii 7 07/01/1974 die i mensis vii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1070 {conversion of 1974-07-31} {
+ clock format 144506096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1974 12:34:56 die xxxi mensis vii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2442260 07 vii 7 07/31/1974 die xxxi mensis vii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1071 {conversion of 1974-08-01} {
+ clock format 144592496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1974 12:34:56 die i mensis viii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2442261 08 viii 8 08/01/1974 die i mensis viii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1072 {conversion of 1974-08-31} {
+ clock format 147184496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1974 12:34:56 die xxxi mensis viii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2442291 08 viii 8 08/31/1974 die xxxi mensis viii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1073 {conversion of 1974-09-01} {
+ clock format 147270896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1974 12:34:56 die i mensis ix annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2442292 09 ix 9 09/01/1974 die i mensis ix annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1074 {conversion of 1974-09-30} {
+ clock format 149776496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1974 12:34:56 die xxx mensis ix annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2442321 09 ix 9 09/30/1974 die xxx mensis ix annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1075 {conversion of 1974-10-01} {
+ clock format 149862896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1974 12:34:56 die i mensis x annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2442322 10 x 10 10/01/1974 die i mensis x annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1076 {conversion of 1974-10-31} {
+ clock format 152454896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1974 12:34:56 die xxxi mensis x annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2442352 10 x 10 10/31/1974 die xxxi mensis x annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1077 {conversion of 1974-11-01} {
+ clock format 152541296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1974 12:34:56 die i mensis xi annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2442353 11 xi 11 11/01/1974 die i mensis xi annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1078 {conversion of 1974-11-30} {
+ clock format 155046896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1974 12:34:56 die xxx mensis xi annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2442382 11 xi 11 11/30/1974 die xxx mensis xi annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1079 {conversion of 1974-12-01} {
+ clock format 155133296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1974 12:34:56 die i mensis xii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2442383 12 xii 12 12/01/1974 die i mensis xii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1080 {conversion of 1974-12-31} {
+ clock format 157725296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1974 12:34:56 die xxxi mensis xii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2442413 12 xii 12 12/31/1974 die xxxi mensis xii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1081 {conversion of 1975-01-01} {
+ clock format 157811696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1975 12:34:56 die i mensis i annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2442414 01 i 1 01/01/1975 die i mensis i annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1082 {conversion of 1975-01-31} {
+ clock format 160403696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1975 12:34:56 die xxxi mensis i annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2442444 01 i 1 01/31/1975 die xxxi mensis i annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1083 {conversion of 1975-02-01} {
+ clock format 160490096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1975 12:34:56 die i mensis ii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2442445 02 ii 2 02/01/1975 die i mensis ii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1084 {conversion of 1975-02-28} {
+ clock format 162822896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1975 12:34:56 die xxviii mensis ii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2442472 02 ii 2 02/28/1975 die xxviii mensis ii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1085 {conversion of 1975-03-01} {
+ clock format 162909296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1975 12:34:56 die i mensis iii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2442473 03 iii 3 03/01/1975 die i mensis iii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1086 {conversion of 1975-03-31} {
+ clock format 165501296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1975 12:34:56 die xxxi mensis iii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2442503 03 iii 3 03/31/1975 die xxxi mensis iii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1087 {conversion of 1975-04-01} {
+ clock format 165587696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1975 12:34:56 die i mensis iv annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2442504 04 iv 4 04/01/1975 die i mensis iv annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1088 {conversion of 1975-04-30} {
+ clock format 168093296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1975 12:34:56 die xxx mensis iv annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2442533 04 iv 4 04/30/1975 die xxx mensis iv annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1089 {conversion of 1975-05-01} {
+ clock format 168179696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1975 12:34:56 die i mensis v annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2442534 05 v 5 05/01/1975 die i mensis v annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1090 {conversion of 1975-05-31} {
+ clock format 170771696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1975 12:34:56 die xxxi mensis v annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2442564 05 v 5 05/31/1975 die xxxi mensis v annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1091 {conversion of 1975-06-01} {
+ clock format 170858096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1975 12:34:56 die i mensis vi annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2442565 06 vi 6 06/01/1975 die i mensis vi annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1092 {conversion of 1975-06-30} {
+ clock format 173363696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1975 12:34:56 die xxx mensis vi annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2442594 06 vi 6 06/30/1975 die xxx mensis vi annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1093 {conversion of 1975-07-01} {
+ clock format 173450096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1975 12:34:56 die i mensis vii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2442595 07 vii 7 07/01/1975 die i mensis vii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1094 {conversion of 1975-07-31} {
+ clock format 176042096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1975 12:34:56 die xxxi mensis vii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2442625 07 vii 7 07/31/1975 die xxxi mensis vii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1095 {conversion of 1975-08-01} {
+ clock format 176128496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1975 12:34:56 die i mensis viii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2442626 08 viii 8 08/01/1975 die i mensis viii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1096 {conversion of 1975-08-31} {
+ clock format 178720496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1975 12:34:56 die xxxi mensis viii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2442656 08 viii 8 08/31/1975 die xxxi mensis viii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1097 {conversion of 1975-09-01} {
+ clock format 178806896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1975 12:34:56 die i mensis ix annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2442657 09 ix 9 09/01/1975 die i mensis ix annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1098 {conversion of 1975-09-30} {
+ clock format 181312496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1975 12:34:56 die xxx mensis ix annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2442686 09 ix 9 09/30/1975 die xxx mensis ix annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1099 {conversion of 1975-10-01} {
+ clock format 181398896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1975 12:34:56 die i mensis x annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2442687 10 x 10 10/01/1975 die i mensis x annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1100 {conversion of 1975-10-31} {
+ clock format 183990896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1975 12:34:56 die xxxi mensis x annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2442717 10 x 10 10/31/1975 die xxxi mensis x annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1101 {conversion of 1975-11-01} {
+ clock format 184077296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1975 12:34:56 die i mensis xi annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2442718 11 xi 11 11/01/1975 die i mensis xi annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1102 {conversion of 1975-11-30} {
+ clock format 186582896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1975 12:34:56 die xxx mensis xi annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2442747 11 xi 11 11/30/1975 die xxx mensis xi annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1103 {conversion of 1975-12-01} {
+ clock format 186669296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1975 12:34:56 die i mensis xii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2442748 12 xii 12 12/01/1975 die i mensis xii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1104 {conversion of 1975-12-31} {
+ clock format 189261296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1975 12:34:56 die xxxi mensis xii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2442778 12 xii 12 12/31/1975 die xxxi mensis xii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1105 {conversion of 1976-01-01} {
+ clock format 189347696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1976 12:34:56 die i mensis i annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2442779 01 i 1 01/01/1976 die i mensis i annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1106 {conversion of 1976-01-31} {
+ clock format 191939696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1976 12:34:56 die xxxi mensis i annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2442809 01 i 1 01/31/1976 die xxxi mensis i annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1107 {conversion of 1976-02-01} {
+ clock format 192026096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1976 12:34:56 die i mensis ii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2442810 02 ii 2 02/01/1976 die i mensis ii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1108 {conversion of 1976-02-29} {
+ clock format 194445296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1976 12:34:56 die xxix mensis ii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2442838 02 ii 2 02/29/1976 die xxix mensis ii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1109 {conversion of 1976-03-01} {
+ clock format 194531696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1976 12:34:56 die i mensis iii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2442839 03 iii 3 03/01/1976 die i mensis iii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1110 {conversion of 1976-03-31} {
+ clock format 197123696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1976 12:34:56 die xxxi mensis iii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2442869 03 iii 3 03/31/1976 die xxxi mensis iii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1111 {conversion of 1976-04-01} {
+ clock format 197210096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1976 12:34:56 die i mensis iv annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2442870 04 iv 4 04/01/1976 die i mensis iv annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1112 {conversion of 1976-04-30} {
+ clock format 199715696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1976 12:34:56 die xxx mensis iv annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2442899 04 iv 4 04/30/1976 die xxx mensis iv annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1113 {conversion of 1976-05-01} {
+ clock format 199802096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1976 12:34:56 die i mensis v annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2442900 05 v 5 05/01/1976 die i mensis v annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1114 {conversion of 1976-05-31} {
+ clock format 202394096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1976 12:34:56 die xxxi mensis v annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2442930 05 v 5 05/31/1976 die xxxi mensis v annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1115 {conversion of 1976-06-01} {
+ clock format 202480496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1976 12:34:56 die i mensis vi annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2442931 06 vi 6 06/01/1976 die i mensis vi annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1116 {conversion of 1976-06-30} {
+ clock format 204986096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1976 12:34:56 die xxx mensis vi annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2442960 06 vi 6 06/30/1976 die xxx mensis vi annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1117 {conversion of 1976-07-01} {
+ clock format 205072496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1976 12:34:56 die i mensis vii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2442961 07 vii 7 07/01/1976 die i mensis vii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1118 {conversion of 1976-07-31} {
+ clock format 207664496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1976 12:34:56 die xxxi mensis vii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2442991 07 vii 7 07/31/1976 die xxxi mensis vii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1119 {conversion of 1976-08-01} {
+ clock format 207750896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1976 12:34:56 die i mensis viii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2442992 08 viii 8 08/01/1976 die i mensis viii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1120 {conversion of 1976-08-31} {
+ clock format 210342896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1976 12:34:56 die xxxi mensis viii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2443022 08 viii 8 08/31/1976 die xxxi mensis viii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1121 {conversion of 1976-09-01} {
+ clock format 210429296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1976 12:34:56 die i mensis ix annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2443023 09 ix 9 09/01/1976 die i mensis ix annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1122 {conversion of 1976-09-30} {
+ clock format 212934896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1976 12:34:56 die xxx mensis ix annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2443052 09 ix 9 09/30/1976 die xxx mensis ix annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1123 {conversion of 1976-10-01} {
+ clock format 213021296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1976 12:34:56 die i mensis x annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2443053 10 x 10 10/01/1976 die i mensis x annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1124 {conversion of 1976-10-31} {
+ clock format 215613296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1976 12:34:56 die xxxi mensis x annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2443083 10 x 10 10/31/1976 die xxxi mensis x annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1125 {conversion of 1976-11-01} {
+ clock format 215699696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1976 12:34:56 die i mensis xi annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2443084 11 xi 11 11/01/1976 die i mensis xi annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1126 {conversion of 1976-11-30} {
+ clock format 218205296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1976 12:34:56 die xxx mensis xi annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2443113 11 xi 11 11/30/1976 die xxx mensis xi annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1127 {conversion of 1976-12-01} {
+ clock format 218291696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1976 12:34:56 die i mensis xii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2443114 12 xii 12 12/01/1976 die i mensis xii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1128 {conversion of 1976-12-31} {
+ clock format 220883696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1976 12:34:56 die xxxi mensis xii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2443144 12 xii 12 12/31/1976 die xxxi mensis xii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1129 {conversion of 1977-01-01} {
+ clock format 220970096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1977 12:34:56 die i mensis i annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2443145 01 i 1 01/01/1977 die i mensis i annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1130 {conversion of 1977-01-31} {
+ clock format 223562096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1977 12:34:56 die xxxi mensis i annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2443175 01 i 1 01/31/1977 die xxxi mensis i annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1131 {conversion of 1977-02-01} {
+ clock format 223648496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1977 12:34:56 die i mensis ii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2443176 02 ii 2 02/01/1977 die i mensis ii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1132 {conversion of 1977-02-28} {
+ clock format 225981296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1977 12:34:56 die xxviii mensis ii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2443203 02 ii 2 02/28/1977 die xxviii mensis ii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1133 {conversion of 1977-03-01} {
+ clock format 226067696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1977 12:34:56 die i mensis iii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2443204 03 iii 3 03/01/1977 die i mensis iii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1134 {conversion of 1977-03-31} {
+ clock format 228659696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1977 12:34:56 die xxxi mensis iii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2443234 03 iii 3 03/31/1977 die xxxi mensis iii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1135 {conversion of 1977-04-01} {
+ clock format 228746096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1977 12:34:56 die i mensis iv annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2443235 04 iv 4 04/01/1977 die i mensis iv annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1136 {conversion of 1977-04-30} {
+ clock format 231251696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1977 12:34:56 die xxx mensis iv annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2443264 04 iv 4 04/30/1977 die xxx mensis iv annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1137 {conversion of 1977-05-01} {
+ clock format 231338096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1977 12:34:56 die i mensis v annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2443265 05 v 5 05/01/1977 die i mensis v annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1138 {conversion of 1977-05-31} {
+ clock format 233930096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1977 12:34:56 die xxxi mensis v annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2443295 05 v 5 05/31/1977 die xxxi mensis v annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1139 {conversion of 1977-06-01} {
+ clock format 234016496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1977 12:34:56 die i mensis vi annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2443296 06 vi 6 06/01/1977 die i mensis vi annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1140 {conversion of 1977-06-30} {
+ clock format 236522096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1977 12:34:56 die xxx mensis vi annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2443325 06 vi 6 06/30/1977 die xxx mensis vi annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1141 {conversion of 1977-07-01} {
+ clock format 236608496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1977 12:34:56 die i mensis vii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2443326 07 vii 7 07/01/1977 die i mensis vii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1142 {conversion of 1977-07-31} {
+ clock format 239200496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1977 12:34:56 die xxxi mensis vii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2443356 07 vii 7 07/31/1977 die xxxi mensis vii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1143 {conversion of 1977-08-01} {
+ clock format 239286896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1977 12:34:56 die i mensis viii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2443357 08 viii 8 08/01/1977 die i mensis viii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1144 {conversion of 1977-08-31} {
+ clock format 241878896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1977 12:34:56 die xxxi mensis viii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2443387 08 viii 8 08/31/1977 die xxxi mensis viii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1145 {conversion of 1977-09-01} {
+ clock format 241965296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1977 12:34:56 die i mensis ix annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2443388 09 ix 9 09/01/1977 die i mensis ix annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1146 {conversion of 1977-09-30} {
+ clock format 244470896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1977 12:34:56 die xxx mensis ix annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2443417 09 ix 9 09/30/1977 die xxx mensis ix annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1147 {conversion of 1977-10-01} {
+ clock format 244557296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1977 12:34:56 die i mensis x annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2443418 10 x 10 10/01/1977 die i mensis x annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1148 {conversion of 1977-10-31} {
+ clock format 247149296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1977 12:34:56 die xxxi mensis x annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2443448 10 x 10 10/31/1977 die xxxi mensis x annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1149 {conversion of 1977-11-01} {
+ clock format 247235696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1977 12:34:56 die i mensis xi annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2443449 11 xi 11 11/01/1977 die i mensis xi annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1150 {conversion of 1977-11-30} {
+ clock format 249741296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1977 12:34:56 die xxx mensis xi annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2443478 11 xi 11 11/30/1977 die xxx mensis xi annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1151 {conversion of 1977-12-01} {
+ clock format 249827696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1977 12:34:56 die i mensis xii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2443479 12 xii 12 12/01/1977 die i mensis xii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1152 {conversion of 1977-12-31} {
+ clock format 252419696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1977 12:34:56 die xxxi mensis xii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2443509 12 xii 12 12/31/1977 die xxxi mensis xii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1153 {conversion of 1978-01-01} {
+ clock format 252506096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1978 12:34:56 die i mensis i annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2443510 01 i 1 01/01/1978 die i mensis i annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1154 {conversion of 1978-01-31} {
+ clock format 255098096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1978 12:34:56 die xxxi mensis i annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2443540 01 i 1 01/31/1978 die xxxi mensis i annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1155 {conversion of 1978-02-01} {
+ clock format 255184496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1978 12:34:56 die i mensis ii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2443541 02 ii 2 02/01/1978 die i mensis ii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1156 {conversion of 1978-02-28} {
+ clock format 257517296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1978 12:34:56 die xxviii mensis ii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2443568 02 ii 2 02/28/1978 die xxviii mensis ii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1157 {conversion of 1978-03-01} {
+ clock format 257603696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1978 12:34:56 die i mensis iii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2443569 03 iii 3 03/01/1978 die i mensis iii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1158 {conversion of 1978-03-31} {
+ clock format 260195696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1978 12:34:56 die xxxi mensis iii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2443599 03 iii 3 03/31/1978 die xxxi mensis iii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1159 {conversion of 1978-04-01} {
+ clock format 260282096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1978 12:34:56 die i mensis iv annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2443600 04 iv 4 04/01/1978 die i mensis iv annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1160 {conversion of 1978-04-30} {
+ clock format 262787696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1978 12:34:56 die xxx mensis iv annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2443629 04 iv 4 04/30/1978 die xxx mensis iv annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1161 {conversion of 1978-05-01} {
+ clock format 262874096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1978 12:34:56 die i mensis v annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2443630 05 v 5 05/01/1978 die i mensis v annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1162 {conversion of 1978-05-31} {
+ clock format 265466096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1978 12:34:56 die xxxi mensis v annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2443660 05 v 5 05/31/1978 die xxxi mensis v annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1163 {conversion of 1978-06-01} {
+ clock format 265552496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1978 12:34:56 die i mensis vi annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2443661 06 vi 6 06/01/1978 die i mensis vi annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1164 {conversion of 1978-06-30} {
+ clock format 268058096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1978 12:34:56 die xxx mensis vi annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2443690 06 vi 6 06/30/1978 die xxx mensis vi annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1165 {conversion of 1978-07-01} {
+ clock format 268144496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1978 12:34:56 die i mensis vii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2443691 07 vii 7 07/01/1978 die i mensis vii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1166 {conversion of 1978-07-31} {
+ clock format 270736496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1978 12:34:56 die xxxi mensis vii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2443721 07 vii 7 07/31/1978 die xxxi mensis vii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1167 {conversion of 1978-08-01} {
+ clock format 270822896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1978 12:34:56 die i mensis viii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2443722 08 viii 8 08/01/1978 die i mensis viii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1168 {conversion of 1978-08-31} {
+ clock format 273414896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1978 12:34:56 die xxxi mensis viii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2443752 08 viii 8 08/31/1978 die xxxi mensis viii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1169 {conversion of 1978-09-01} {
+ clock format 273501296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1978 12:34:56 die i mensis ix annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2443753 09 ix 9 09/01/1978 die i mensis ix annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1170 {conversion of 1978-09-30} {
+ clock format 276006896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1978 12:34:56 die xxx mensis ix annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2443782 09 ix 9 09/30/1978 die xxx mensis ix annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1171 {conversion of 1978-10-01} {
+ clock format 276093296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1978 12:34:56 die i mensis x annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2443783 10 x 10 10/01/1978 die i mensis x annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1172 {conversion of 1978-10-31} {
+ clock format 278685296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1978 12:34:56 die xxxi mensis x annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2443813 10 x 10 10/31/1978 die xxxi mensis x annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1173 {conversion of 1978-11-01} {
+ clock format 278771696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1978 12:34:56 die i mensis xi annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2443814 11 xi 11 11/01/1978 die i mensis xi annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1174 {conversion of 1978-11-30} {
+ clock format 281277296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1978 12:34:56 die xxx mensis xi annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2443843 11 xi 11 11/30/1978 die xxx mensis xi annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1175 {conversion of 1978-12-01} {
+ clock format 281363696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1978 12:34:56 die i mensis xii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2443844 12 xii 12 12/01/1978 die i mensis xii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1176 {conversion of 1978-12-31} {
+ clock format 283955696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1978 12:34:56 die xxxi mensis xii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2443874 12 xii 12 12/31/1978 die xxxi mensis xii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1177 {conversion of 1979-01-01} {
+ clock format 284042096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1979 12:34:56 die i mensis i annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2443875 01 i 1 01/01/1979 die i mensis i annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1178 {conversion of 1979-01-31} {
+ clock format 286634096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1979 12:34:56 die xxxi mensis i annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2443905 01 i 1 01/31/1979 die xxxi mensis i annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1179 {conversion of 1979-02-01} {
+ clock format 286720496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1979 12:34:56 die i mensis ii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2443906 02 ii 2 02/01/1979 die i mensis ii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1180 {conversion of 1979-02-28} {
+ clock format 289053296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1979 12:34:56 die xxviii mensis ii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2443933 02 ii 2 02/28/1979 die xxviii mensis ii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1181 {conversion of 1979-03-01} {
+ clock format 289139696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1979 12:34:56 die i mensis iii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2443934 03 iii 3 03/01/1979 die i mensis iii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1182 {conversion of 1979-03-31} {
+ clock format 291731696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1979 12:34:56 die xxxi mensis iii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2443964 03 iii 3 03/31/1979 die xxxi mensis iii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1183 {conversion of 1979-04-01} {
+ clock format 291818096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1979 12:34:56 die i mensis iv annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2443965 04 iv 4 04/01/1979 die i mensis iv annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1184 {conversion of 1979-04-30} {
+ clock format 294323696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1979 12:34:56 die xxx mensis iv annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2443994 04 iv 4 04/30/1979 die xxx mensis iv annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1185 {conversion of 1979-05-01} {
+ clock format 294410096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1979 12:34:56 die i mensis v annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2443995 05 v 5 05/01/1979 die i mensis v annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1186 {conversion of 1979-05-31} {
+ clock format 297002096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1979 12:34:56 die xxxi mensis v annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2444025 05 v 5 05/31/1979 die xxxi mensis v annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1187 {conversion of 1979-06-01} {
+ clock format 297088496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1979 12:34:56 die i mensis vi annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2444026 06 vi 6 06/01/1979 die i mensis vi annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1188 {conversion of 1979-06-30} {
+ clock format 299594096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1979 12:34:56 die xxx mensis vi annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2444055 06 vi 6 06/30/1979 die xxx mensis vi annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1189 {conversion of 1979-07-01} {
+ clock format 299680496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1979 12:34:56 die i mensis vii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2444056 07 vii 7 07/01/1979 die i mensis vii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1190 {conversion of 1979-07-31} {
+ clock format 302272496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1979 12:34:56 die xxxi mensis vii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2444086 07 vii 7 07/31/1979 die xxxi mensis vii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1191 {conversion of 1979-08-01} {
+ clock format 302358896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1979 12:34:56 die i mensis viii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2444087 08 viii 8 08/01/1979 die i mensis viii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1192 {conversion of 1979-08-31} {
+ clock format 304950896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1979 12:34:56 die xxxi mensis viii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2444117 08 viii 8 08/31/1979 die xxxi mensis viii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1193 {conversion of 1979-09-01} {
+ clock format 305037296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1979 12:34:56 die i mensis ix annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2444118 09 ix 9 09/01/1979 die i mensis ix annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1194 {conversion of 1979-09-30} {
+ clock format 307542896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1979 12:34:56 die xxx mensis ix annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2444147 09 ix 9 09/30/1979 die xxx mensis ix annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1195 {conversion of 1979-10-01} {
+ clock format 307629296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1979 12:34:56 die i mensis x annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2444148 10 x 10 10/01/1979 die i mensis x annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1196 {conversion of 1979-10-31} {
+ clock format 310221296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1979 12:34:56 die xxxi mensis x annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2444178 10 x 10 10/31/1979 die xxxi mensis x annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1197 {conversion of 1979-11-01} {
+ clock format 310307696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1979 12:34:56 die i mensis xi annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2444179 11 xi 11 11/01/1979 die i mensis xi annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1198 {conversion of 1979-11-30} {
+ clock format 312813296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1979 12:34:56 die xxx mensis xi annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2444208 11 xi 11 11/30/1979 die xxx mensis xi annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1199 {conversion of 1979-12-01} {
+ clock format 312899696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1979 12:34:56 die i mensis xii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2444209 12 xii 12 12/01/1979 die i mensis xii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1200 {conversion of 1979-12-31} {
+ clock format 315491696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1979 12:34:56 die xxxi mensis xii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2444239 12 xii 12 12/31/1979 die xxxi mensis xii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1201 {conversion of 1980-01-01} {
+ clock format 315578096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1980 12:34:56 die i mensis i annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2444240 01 i 1 01/01/1980 die i mensis i annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1202 {conversion of 1980-01-31} {
+ clock format 318170096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1980 12:34:56 die xxxi mensis i annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2444270 01 i 1 01/31/1980 die xxxi mensis i annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1203 {conversion of 1980-02-01} {
+ clock format 318256496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1980 12:34:56 die i mensis ii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2444271 02 ii 2 02/01/1980 die i mensis ii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1204 {conversion of 1980-02-29} {
+ clock format 320675696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1980 12:34:56 die xxix mensis ii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2444299 02 ii 2 02/29/1980 die xxix mensis ii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1205 {conversion of 1980-03-01} {
+ clock format 320762096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1980 12:34:56 die i mensis iii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2444300 03 iii 3 03/01/1980 die i mensis iii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1206 {conversion of 1980-03-31} {
+ clock format 323354096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1980 12:34:56 die xxxi mensis iii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2444330 03 iii 3 03/31/1980 die xxxi mensis iii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1207 {conversion of 1980-04-01} {
+ clock format 323440496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1980 12:34:56 die i mensis iv annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2444331 04 iv 4 04/01/1980 die i mensis iv annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1208 {conversion of 1980-04-30} {
+ clock format 325946096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1980 12:34:56 die xxx mensis iv annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2444360 04 iv 4 04/30/1980 die xxx mensis iv annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1209 {conversion of 1980-05-01} {
+ clock format 326032496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1980 12:34:56 die i mensis v annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2444361 05 v 5 05/01/1980 die i mensis v annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1210 {conversion of 1980-05-31} {
+ clock format 328624496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1980 12:34:56 die xxxi mensis v annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2444391 05 v 5 05/31/1980 die xxxi mensis v annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1211 {conversion of 1980-06-01} {
+ clock format 328710896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1980 12:34:56 die i mensis vi annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2444392 06 vi 6 06/01/1980 die i mensis vi annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1212 {conversion of 1980-06-30} {
+ clock format 331216496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1980 12:34:56 die xxx mensis vi annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2444421 06 vi 6 06/30/1980 die xxx mensis vi annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1213 {conversion of 1980-07-01} {
+ clock format 331302896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1980 12:34:56 die i mensis vii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2444422 07 vii 7 07/01/1980 die i mensis vii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1214 {conversion of 1980-07-31} {
+ clock format 333894896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1980 12:34:56 die xxxi mensis vii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2444452 07 vii 7 07/31/1980 die xxxi mensis vii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1215 {conversion of 1980-08-01} {
+ clock format 333981296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1980 12:34:56 die i mensis viii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2444453 08 viii 8 08/01/1980 die i mensis viii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1216 {conversion of 1980-08-31} {
+ clock format 336573296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1980 12:34:56 die xxxi mensis viii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2444483 08 viii 8 08/31/1980 die xxxi mensis viii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1217 {conversion of 1980-09-01} {
+ clock format 336659696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1980 12:34:56 die i mensis ix annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2444484 09 ix 9 09/01/1980 die i mensis ix annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1218 {conversion of 1980-09-30} {
+ clock format 339165296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1980 12:34:56 die xxx mensis ix annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2444513 09 ix 9 09/30/1980 die xxx mensis ix annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1219 {conversion of 1980-10-01} {
+ clock format 339251696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1980 12:34:56 die i mensis x annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2444514 10 x 10 10/01/1980 die i mensis x annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1220 {conversion of 1980-10-31} {
+ clock format 341843696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1980 12:34:56 die xxxi mensis x annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2444544 10 x 10 10/31/1980 die xxxi mensis x annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1221 {conversion of 1980-11-01} {
+ clock format 341930096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1980 12:34:56 die i mensis xi annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2444545 11 xi 11 11/01/1980 die i mensis xi annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1222 {conversion of 1980-11-30} {
+ clock format 344435696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1980 12:34:56 die xxx mensis xi annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2444574 11 xi 11 11/30/1980 die xxx mensis xi annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1223 {conversion of 1980-12-01} {
+ clock format 344522096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1980 12:34:56 die i mensis xii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2444575 12 xii 12 12/01/1980 die i mensis xii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1224 {conversion of 1980-12-31} {
+ clock format 347114096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1980 12:34:56 die xxxi mensis xii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2444605 12 xii 12 12/31/1980 die xxxi mensis xii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1225 {conversion of 1981-01-01} {
+ clock format 347200496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1981 12:34:56 die i mensis i annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2444606 01 i 1 01/01/1981 die i mensis i annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1226 {conversion of 1981-01-31} {
+ clock format 349792496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1981 12:34:56 die xxxi mensis i annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2444636 01 i 1 01/31/1981 die xxxi mensis i annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1227 {conversion of 1981-02-01} {
+ clock format 349878896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1981 12:34:56 die i mensis ii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2444637 02 ii 2 02/01/1981 die i mensis ii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1228 {conversion of 1981-02-28} {
+ clock format 352211696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1981 12:34:56 die xxviii mensis ii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2444664 02 ii 2 02/28/1981 die xxviii mensis ii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1229 {conversion of 1981-03-01} {
+ clock format 352298096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1981 12:34:56 die i mensis iii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2444665 03 iii 3 03/01/1981 die i mensis iii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1230 {conversion of 1981-03-31} {
+ clock format 354890096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1981 12:34:56 die xxxi mensis iii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2444695 03 iii 3 03/31/1981 die xxxi mensis iii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1231 {conversion of 1981-04-01} {
+ clock format 354976496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1981 12:34:56 die i mensis iv annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2444696 04 iv 4 04/01/1981 die i mensis iv annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1232 {conversion of 1981-04-30} {
+ clock format 357482096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1981 12:34:56 die xxx mensis iv annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2444725 04 iv 4 04/30/1981 die xxx mensis iv annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1233 {conversion of 1981-05-01} {
+ clock format 357568496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1981 12:34:56 die i mensis v annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2444726 05 v 5 05/01/1981 die i mensis v annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1234 {conversion of 1981-05-31} {
+ clock format 360160496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1981 12:34:56 die xxxi mensis v annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2444756 05 v 5 05/31/1981 die xxxi mensis v annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1235 {conversion of 1981-06-01} {
+ clock format 360246896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1981 12:34:56 die i mensis vi annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2444757 06 vi 6 06/01/1981 die i mensis vi annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1236 {conversion of 1981-06-30} {
+ clock format 362752496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1981 12:34:56 die xxx mensis vi annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2444786 06 vi 6 06/30/1981 die xxx mensis vi annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1237 {conversion of 1981-07-01} {
+ clock format 362838896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1981 12:34:56 die i mensis vii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2444787 07 vii 7 07/01/1981 die i mensis vii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1238 {conversion of 1981-07-31} {
+ clock format 365430896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1981 12:34:56 die xxxi mensis vii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2444817 07 vii 7 07/31/1981 die xxxi mensis vii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1239 {conversion of 1981-08-01} {
+ clock format 365517296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1981 12:34:56 die i mensis viii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2444818 08 viii 8 08/01/1981 die i mensis viii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1240 {conversion of 1981-08-31} {
+ clock format 368109296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1981 12:34:56 die xxxi mensis viii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2444848 08 viii 8 08/31/1981 die xxxi mensis viii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1241 {conversion of 1981-09-01} {
+ clock format 368195696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1981 12:34:56 die i mensis ix annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2444849 09 ix 9 09/01/1981 die i mensis ix annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1242 {conversion of 1981-09-30} {
+ clock format 370701296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1981 12:34:56 die xxx mensis ix annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2444878 09 ix 9 09/30/1981 die xxx mensis ix annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1243 {conversion of 1981-10-01} {
+ clock format 370787696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1981 12:34:56 die i mensis x annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2444879 10 x 10 10/01/1981 die i mensis x annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1244 {conversion of 1981-10-31} {
+ clock format 373379696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1981 12:34:56 die xxxi mensis x annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2444909 10 x 10 10/31/1981 die xxxi mensis x annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1245 {conversion of 1981-11-01} {
+ clock format 373466096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1981 12:34:56 die i mensis xi annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2444910 11 xi 11 11/01/1981 die i mensis xi annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1246 {conversion of 1981-11-30} {
+ clock format 375971696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1981 12:34:56 die xxx mensis xi annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2444939 11 xi 11 11/30/1981 die xxx mensis xi annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1247 {conversion of 1981-12-01} {
+ clock format 376058096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1981 12:34:56 die i mensis xii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2444940 12 xii 12 12/01/1981 die i mensis xii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1248 {conversion of 1981-12-31} {
+ clock format 378650096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1981 12:34:56 die xxxi mensis xii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2444970 12 xii 12 12/31/1981 die xxxi mensis xii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1249 {conversion of 1984-01-01} {
+ clock format 441808496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1984 12:34:56 die i mensis i annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2445701 01 i 1 01/01/1984 die i mensis i annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1250 {conversion of 1984-01-31} {
+ clock format 444400496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1984 12:34:56 die xxxi mensis i annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2445731 01 i 1 01/31/1984 die xxxi mensis i annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1251 {conversion of 1984-02-01} {
+ clock format 444486896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1984 12:34:56 die i mensis ii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2445732 02 ii 2 02/01/1984 die i mensis ii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1252 {conversion of 1984-02-29} {
+ clock format 446906096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1984 12:34:56 die xxix mensis ii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2445760 02 ii 2 02/29/1984 die xxix mensis ii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1253 {conversion of 1984-03-01} {
+ clock format 446992496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1984 12:34:56 die i mensis iii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2445761 03 iii 3 03/01/1984 die i mensis iii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1254 {conversion of 1984-03-31} {
+ clock format 449584496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1984 12:34:56 die xxxi mensis iii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2445791 03 iii 3 03/31/1984 die xxxi mensis iii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1255 {conversion of 1984-04-01} {
+ clock format 449670896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1984 12:34:56 die i mensis iv annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2445792 04 iv 4 04/01/1984 die i mensis iv annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1256 {conversion of 1984-04-30} {
+ clock format 452176496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1984 12:34:56 die xxx mensis iv annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2445821 04 iv 4 04/30/1984 die xxx mensis iv annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1257 {conversion of 1984-05-01} {
+ clock format 452262896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1984 12:34:56 die i mensis v annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2445822 05 v 5 05/01/1984 die i mensis v annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1258 {conversion of 1984-05-31} {
+ clock format 454854896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1984 12:34:56 die xxxi mensis v annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2445852 05 v 5 05/31/1984 die xxxi mensis v annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1259 {conversion of 1984-06-01} {
+ clock format 454941296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1984 12:34:56 die i mensis vi annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2445853 06 vi 6 06/01/1984 die i mensis vi annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1260 {conversion of 1984-06-30} {
+ clock format 457446896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1984 12:34:56 die xxx mensis vi annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2445882 06 vi 6 06/30/1984 die xxx mensis vi annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1261 {conversion of 1984-07-01} {
+ clock format 457533296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1984 12:34:56 die i mensis vii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2445883 07 vii 7 07/01/1984 die i mensis vii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1262 {conversion of 1984-07-31} {
+ clock format 460125296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1984 12:34:56 die xxxi mensis vii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2445913 07 vii 7 07/31/1984 die xxxi mensis vii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1263 {conversion of 1984-08-01} {
+ clock format 460211696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1984 12:34:56 die i mensis viii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2445914 08 viii 8 08/01/1984 die i mensis viii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1264 {conversion of 1984-08-31} {
+ clock format 462803696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1984 12:34:56 die xxxi mensis viii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2445944 08 viii 8 08/31/1984 die xxxi mensis viii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1265 {conversion of 1984-09-01} {
+ clock format 462890096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1984 12:34:56 die i mensis ix annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2445945 09 ix 9 09/01/1984 die i mensis ix annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1266 {conversion of 1984-09-30} {
+ clock format 465395696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1984 12:34:56 die xxx mensis ix annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2445974 09 ix 9 09/30/1984 die xxx mensis ix annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1267 {conversion of 1984-10-01} {
+ clock format 465482096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1984 12:34:56 die i mensis x annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2445975 10 x 10 10/01/1984 die i mensis x annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1268 {conversion of 1984-10-31} {
+ clock format 468074096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1984 12:34:56 die xxxi mensis x annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2446005 10 x 10 10/31/1984 die xxxi mensis x annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1269 {conversion of 1984-11-01} {
+ clock format 468160496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1984 12:34:56 die i mensis xi annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2446006 11 xi 11 11/01/1984 die i mensis xi annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1270 {conversion of 1984-11-30} {
+ clock format 470666096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1984 12:34:56 die xxx mensis xi annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2446035 11 xi 11 11/30/1984 die xxx mensis xi annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1271 {conversion of 1984-12-01} {
+ clock format 470752496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1984 12:34:56 die i mensis xii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2446036 12 xii 12 12/01/1984 die i mensis xii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1272 {conversion of 1984-12-31} {
+ clock format 473344496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1984 12:34:56 die xxxi mensis xii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2446066 12 xii 12 12/31/1984 die xxxi mensis xii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1273 {conversion of 1985-01-01} {
+ clock format 473430896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1985 12:34:56 die i mensis i annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2446067 01 i 1 01/01/1985 die i mensis i annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1274 {conversion of 1985-01-31} {
+ clock format 476022896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1985 12:34:56 die xxxi mensis i annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2446097 01 i 1 01/31/1985 die xxxi mensis i annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1275 {conversion of 1985-02-01} {
+ clock format 476109296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1985 12:34:56 die i mensis ii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2446098 02 ii 2 02/01/1985 die i mensis ii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1276 {conversion of 1985-02-28} {
+ clock format 478442096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1985 12:34:56 die xxviii mensis ii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2446125 02 ii 2 02/28/1985 die xxviii mensis ii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1277 {conversion of 1985-03-01} {
+ clock format 478528496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1985 12:34:56 die i mensis iii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2446126 03 iii 3 03/01/1985 die i mensis iii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1278 {conversion of 1985-03-31} {
+ clock format 481120496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1985 12:34:56 die xxxi mensis iii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2446156 03 iii 3 03/31/1985 die xxxi mensis iii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1279 {conversion of 1985-04-01} {
+ clock format 481206896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1985 12:34:56 die i mensis iv annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2446157 04 iv 4 04/01/1985 die i mensis iv annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1280 {conversion of 1985-04-30} {
+ clock format 483712496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1985 12:34:56 die xxx mensis iv annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2446186 04 iv 4 04/30/1985 die xxx mensis iv annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1281 {conversion of 1985-05-01} {
+ clock format 483798896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1985 12:34:56 die i mensis v annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2446187 05 v 5 05/01/1985 die i mensis v annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1282 {conversion of 1985-05-31} {
+ clock format 486390896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1985 12:34:56 die xxxi mensis v annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2446217 05 v 5 05/31/1985 die xxxi mensis v annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1283 {conversion of 1985-06-01} {
+ clock format 486477296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1985 12:34:56 die i mensis vi annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2446218 06 vi 6 06/01/1985 die i mensis vi annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1284 {conversion of 1985-06-30} {
+ clock format 488982896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1985 12:34:56 die xxx mensis vi annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2446247 06 vi 6 06/30/1985 die xxx mensis vi annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1285 {conversion of 1985-07-01} {
+ clock format 489069296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1985 12:34:56 die i mensis vii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2446248 07 vii 7 07/01/1985 die i mensis vii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1286 {conversion of 1985-07-31} {
+ clock format 491661296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1985 12:34:56 die xxxi mensis vii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2446278 07 vii 7 07/31/1985 die xxxi mensis vii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1287 {conversion of 1985-08-01} {
+ clock format 491747696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1985 12:34:56 die i mensis viii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2446279 08 viii 8 08/01/1985 die i mensis viii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1288 {conversion of 1985-08-31} {
+ clock format 494339696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1985 12:34:56 die xxxi mensis viii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2446309 08 viii 8 08/31/1985 die xxxi mensis viii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1289 {conversion of 1985-09-01} {
+ clock format 494426096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1985 12:34:56 die i mensis ix annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2446310 09 ix 9 09/01/1985 die i mensis ix annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1290 {conversion of 1985-09-30} {
+ clock format 496931696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1985 12:34:56 die xxx mensis ix annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2446339 09 ix 9 09/30/1985 die xxx mensis ix annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1291 {conversion of 1985-10-01} {
+ clock format 497018096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1985 12:34:56 die i mensis x annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2446340 10 x 10 10/01/1985 die i mensis x annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1292 {conversion of 1985-10-31} {
+ clock format 499610096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1985 12:34:56 die xxxi mensis x annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2446370 10 x 10 10/31/1985 die xxxi mensis x annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1293 {conversion of 1985-11-01} {
+ clock format 499696496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1985 12:34:56 die i mensis xi annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2446371 11 xi 11 11/01/1985 die i mensis xi annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1294 {conversion of 1985-11-30} {
+ clock format 502202096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1985 12:34:56 die xxx mensis xi annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2446400 11 xi 11 11/30/1985 die xxx mensis xi annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1295 {conversion of 1985-12-01} {
+ clock format 502288496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1985 12:34:56 die i mensis xii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2446401 12 xii 12 12/01/1985 die i mensis xii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1296 {conversion of 1985-12-31} {
+ clock format 504880496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1985 12:34:56 die xxxi mensis xii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2446431 12 xii 12 12/31/1985 die xxxi mensis xii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1297 {conversion of 1988-01-01} {
+ clock format 568038896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1988 12:34:56 die i mensis i annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2447162 01 i 1 01/01/1988 die i mensis i annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1298 {conversion of 1988-01-31} {
+ clock format 570630896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1988 12:34:56 die xxxi mensis i annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2447192 01 i 1 01/31/1988 die xxxi mensis i annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1299 {conversion of 1988-02-01} {
+ clock format 570717296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1988 12:34:56 die i mensis ii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2447193 02 ii 2 02/01/1988 die i mensis ii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1300 {conversion of 1988-02-29} {
+ clock format 573136496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1988 12:34:56 die xxix mensis ii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2447221 02 ii 2 02/29/1988 die xxix mensis ii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1301 {conversion of 1988-03-01} {
+ clock format 573222896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1988 12:34:56 die i mensis iii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2447222 03 iii 3 03/01/1988 die i mensis iii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1302 {conversion of 1988-03-31} {
+ clock format 575814896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1988 12:34:56 die xxxi mensis iii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2447252 03 iii 3 03/31/1988 die xxxi mensis iii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1303 {conversion of 1988-04-01} {
+ clock format 575901296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1988 12:34:56 die i mensis iv annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2447253 04 iv 4 04/01/1988 die i mensis iv annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1304 {conversion of 1988-04-30} {
+ clock format 578406896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1988 12:34:56 die xxx mensis iv annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2447282 04 iv 4 04/30/1988 die xxx mensis iv annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1305 {conversion of 1988-05-01} {
+ clock format 578493296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1988 12:34:56 die i mensis v annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2447283 05 v 5 05/01/1988 die i mensis v annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1306 {conversion of 1988-05-31} {
+ clock format 581085296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1988 12:34:56 die xxxi mensis v annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2447313 05 v 5 05/31/1988 die xxxi mensis v annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1307 {conversion of 1988-06-01} {
+ clock format 581171696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1988 12:34:56 die i mensis vi annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2447314 06 vi 6 06/01/1988 die i mensis vi annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1308 {conversion of 1988-06-30} {
+ clock format 583677296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1988 12:34:56 die xxx mensis vi annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2447343 06 vi 6 06/30/1988 die xxx mensis vi annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1309 {conversion of 1988-07-01} {
+ clock format 583763696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1988 12:34:56 die i mensis vii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2447344 07 vii 7 07/01/1988 die i mensis vii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1310 {conversion of 1988-07-31} {
+ clock format 586355696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1988 12:34:56 die xxxi mensis vii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2447374 07 vii 7 07/31/1988 die xxxi mensis vii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1311 {conversion of 1988-08-01} {
+ clock format 586442096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1988 12:34:56 die i mensis viii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2447375 08 viii 8 08/01/1988 die i mensis viii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1312 {conversion of 1988-08-31} {
+ clock format 589034096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1988 12:34:56 die xxxi mensis viii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2447405 08 viii 8 08/31/1988 die xxxi mensis viii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1313 {conversion of 1988-09-01} {
+ clock format 589120496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1988 12:34:56 die i mensis ix annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2447406 09 ix 9 09/01/1988 die i mensis ix annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1314 {conversion of 1988-09-30} {
+ clock format 591626096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1988 12:34:56 die xxx mensis ix annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2447435 09 ix 9 09/30/1988 die xxx mensis ix annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1315 {conversion of 1988-10-01} {
+ clock format 591712496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1988 12:34:56 die i mensis x annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2447436 10 x 10 10/01/1988 die i mensis x annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1316 {conversion of 1988-10-31} {
+ clock format 594304496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1988 12:34:56 die xxxi mensis x annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2447466 10 x 10 10/31/1988 die xxxi mensis x annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1317 {conversion of 1988-11-01} {
+ clock format 594390896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1988 12:34:56 die i mensis xi annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2447467 11 xi 11 11/01/1988 die i mensis xi annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1318 {conversion of 1988-11-30} {
+ clock format 596896496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1988 12:34:56 die xxx mensis xi annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2447496 11 xi 11 11/30/1988 die xxx mensis xi annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1319 {conversion of 1988-12-01} {
+ clock format 596982896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1988 12:34:56 die i mensis xii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2447497 12 xii 12 12/01/1988 die i mensis xii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1320 {conversion of 1988-12-31} {
+ clock format 599574896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1988 12:34:56 die xxxi mensis xii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2447527 12 xii 12 12/31/1988 die xxxi mensis xii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1321 {conversion of 1989-01-01} {
+ clock format 599661296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1989 12:34:56 die i mensis i annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2447528 01 i 1 01/01/1989 die i mensis i annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1322 {conversion of 1989-01-31} {
+ clock format 602253296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1989 12:34:56 die xxxi mensis i annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2447558 01 i 1 01/31/1989 die xxxi mensis i annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1323 {conversion of 1989-02-01} {
+ clock format 602339696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1989 12:34:56 die i mensis ii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2447559 02 ii 2 02/01/1989 die i mensis ii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1324 {conversion of 1989-02-28} {
+ clock format 604672496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1989 12:34:56 die xxviii mensis ii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2447586 02 ii 2 02/28/1989 die xxviii mensis ii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1325 {conversion of 1989-03-01} {
+ clock format 604758896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1989 12:34:56 die i mensis iii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2447587 03 iii 3 03/01/1989 die i mensis iii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1326 {conversion of 1989-03-31} {
+ clock format 607350896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1989 12:34:56 die xxxi mensis iii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2447617 03 iii 3 03/31/1989 die xxxi mensis iii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1327 {conversion of 1989-04-01} {
+ clock format 607437296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1989 12:34:56 die i mensis iv annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2447618 04 iv 4 04/01/1989 die i mensis iv annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1328 {conversion of 1989-04-30} {
+ clock format 609942896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1989 12:34:56 die xxx mensis iv annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2447647 04 iv 4 04/30/1989 die xxx mensis iv annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1329 {conversion of 1989-05-01} {
+ clock format 610029296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1989 12:34:56 die i mensis v annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2447648 05 v 5 05/01/1989 die i mensis v annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1330 {conversion of 1989-05-31} {
+ clock format 612621296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1989 12:34:56 die xxxi mensis v annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2447678 05 v 5 05/31/1989 die xxxi mensis v annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1331 {conversion of 1989-06-01} {
+ clock format 612707696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1989 12:34:56 die i mensis vi annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2447679 06 vi 6 06/01/1989 die i mensis vi annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1332 {conversion of 1989-06-30} {
+ clock format 615213296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1989 12:34:56 die xxx mensis vi annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2447708 06 vi 6 06/30/1989 die xxx mensis vi annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1333 {conversion of 1989-07-01} {
+ clock format 615299696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1989 12:34:56 die i mensis vii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2447709 07 vii 7 07/01/1989 die i mensis vii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1334 {conversion of 1989-07-31} {
+ clock format 617891696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1989 12:34:56 die xxxi mensis vii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2447739 07 vii 7 07/31/1989 die xxxi mensis vii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1335 {conversion of 1989-08-01} {
+ clock format 617978096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1989 12:34:56 die i mensis viii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2447740 08 viii 8 08/01/1989 die i mensis viii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1336 {conversion of 1989-08-31} {
+ clock format 620570096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1989 12:34:56 die xxxi mensis viii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2447770 08 viii 8 08/31/1989 die xxxi mensis viii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1337 {conversion of 1989-09-01} {
+ clock format 620656496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1989 12:34:56 die i mensis ix annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2447771 09 ix 9 09/01/1989 die i mensis ix annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1338 {conversion of 1989-09-30} {
+ clock format 623162096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1989 12:34:56 die xxx mensis ix annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2447800 09 ix 9 09/30/1989 die xxx mensis ix annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1339 {conversion of 1989-10-01} {
+ clock format 623248496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1989 12:34:56 die i mensis x annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2447801 10 x 10 10/01/1989 die i mensis x annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1340 {conversion of 1989-10-31} {
+ clock format 625840496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1989 12:34:56 die xxxi mensis x annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2447831 10 x 10 10/31/1989 die xxxi mensis x annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1341 {conversion of 1989-11-01} {
+ clock format 625926896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1989 12:34:56 die i mensis xi annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2447832 11 xi 11 11/01/1989 die i mensis xi annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1342 {conversion of 1989-11-30} {
+ clock format 628432496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1989 12:34:56 die xxx mensis xi annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2447861 11 xi 11 11/30/1989 die xxx mensis xi annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1343 {conversion of 1989-12-01} {
+ clock format 628518896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1989 12:34:56 die i mensis xii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2447862 12 xii 12 12/01/1989 die i mensis xii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1344 {conversion of 1989-12-31} {
+ clock format 631110896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1989 12:34:56 die xxxi mensis xii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2447892 12 xii 12 12/31/1989 die xxxi mensis xii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1345 {conversion of 1992-01-01} {
+ clock format 694269296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1992 12:34:56 die i mensis i annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2448623 01 i 1 01/01/1992 die i mensis i annoque mcmxcii 92 xcii 1992}
+test clock-2.1346 {conversion of 1992-01-31} {
+ clock format 696861296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1992 12:34:56 die xxxi mensis i annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2448653 01 i 1 01/31/1992 die xxxi mensis i annoque mcmxcii 92 xcii 1992}
+test clock-2.1347 {conversion of 1992-02-01} {
+ clock format 696947696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1992 12:34:56 die i mensis ii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2448654 02 ii 2 02/01/1992 die i mensis ii annoque mcmxcii 92 xcii 1992}
+test clock-2.1348 {conversion of 1992-02-29} {
+ clock format 699366896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1992 12:34:56 die xxix mensis ii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2448682 02 ii 2 02/29/1992 die xxix mensis ii annoque mcmxcii 92 xcii 1992}
+test clock-2.1349 {conversion of 1992-03-01} {
+ clock format 699453296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1992 12:34:56 die i mensis iii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2448683 03 iii 3 03/01/1992 die i mensis iii annoque mcmxcii 92 xcii 1992}
+test clock-2.1350 {conversion of 1992-03-31} {
+ clock format 702045296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1992 12:34:56 die xxxi mensis iii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2448713 03 iii 3 03/31/1992 die xxxi mensis iii annoque mcmxcii 92 xcii 1992}
+test clock-2.1351 {conversion of 1992-04-01} {
+ clock format 702131696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1992 12:34:56 die i mensis iv annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2448714 04 iv 4 04/01/1992 die i mensis iv annoque mcmxcii 92 xcii 1992}
+test clock-2.1352 {conversion of 1992-04-30} {
+ clock format 704637296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1992 12:34:56 die xxx mensis iv annoque mcmxcii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2448743 04 iv 4 04/30/1992 die xxx mensis iv annoque mcmxcii 92 xcii 1992}
+test clock-2.1353 {conversion of 1992-05-01} {
+ clock format 704723696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1992 12:34:56 die i mensis v annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2448744 05 v 5 05/01/1992 die i mensis v annoque mcmxcii 92 xcii 1992}
+test clock-2.1354 {conversion of 1992-05-31} {
+ clock format 707315696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1992 12:34:56 die xxxi mensis v annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2448774 05 v 5 05/31/1992 die xxxi mensis v annoque mcmxcii 92 xcii 1992}
+test clock-2.1355 {conversion of 1992-06-01} {
+ clock format 707402096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1992 12:34:56 die i mensis vi annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2448775 06 vi 6 06/01/1992 die i mensis vi annoque mcmxcii 92 xcii 1992}
+test clock-2.1356 {conversion of 1992-06-30} {
+ clock format 709907696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1992 12:34:56 die xxx mensis vi annoque mcmxcii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2448804 06 vi 6 06/30/1992 die xxx mensis vi annoque mcmxcii 92 xcii 1992}
+test clock-2.1357 {conversion of 1992-07-01} {
+ clock format 709994096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1992 12:34:56 die i mensis vii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2448805 07 vii 7 07/01/1992 die i mensis vii annoque mcmxcii 92 xcii 1992}
+test clock-2.1358 {conversion of 1992-07-31} {
+ clock format 712586096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1992 12:34:56 die xxxi mensis vii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2448835 07 vii 7 07/31/1992 die xxxi mensis vii annoque mcmxcii 92 xcii 1992}
+test clock-2.1359 {conversion of 1992-08-01} {
+ clock format 712672496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1992 12:34:56 die i mensis viii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2448836 08 viii 8 08/01/1992 die i mensis viii annoque mcmxcii 92 xcii 1992}
+test clock-2.1360 {conversion of 1992-08-31} {
+ clock format 715264496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1992 12:34:56 die xxxi mensis viii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2448866 08 viii 8 08/31/1992 die xxxi mensis viii annoque mcmxcii 92 xcii 1992}
+test clock-2.1361 {conversion of 1992-09-01} {
+ clock format 715350896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1992 12:34:56 die i mensis ix annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2448867 09 ix 9 09/01/1992 die i mensis ix annoque mcmxcii 92 xcii 1992}
+test clock-2.1362 {conversion of 1992-09-30} {
+ clock format 717856496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1992 12:34:56 die xxx mensis ix annoque mcmxcii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2448896 09 ix 9 09/30/1992 die xxx mensis ix annoque mcmxcii 92 xcii 1992}
+test clock-2.1363 {conversion of 1992-10-01} {
+ clock format 717942896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1992 12:34:56 die i mensis x annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2448897 10 x 10 10/01/1992 die i mensis x annoque mcmxcii 92 xcii 1992}
+test clock-2.1364 {conversion of 1992-10-31} {
+ clock format 720534896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1992 12:34:56 die xxxi mensis x annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2448927 10 x 10 10/31/1992 die xxxi mensis x annoque mcmxcii 92 xcii 1992}
+test clock-2.1365 {conversion of 1992-11-01} {
+ clock format 720621296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1992 12:34:56 die i mensis xi annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2448928 11 xi 11 11/01/1992 die i mensis xi annoque mcmxcii 92 xcii 1992}
+test clock-2.1366 {conversion of 1992-11-30} {
+ clock format 723126896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1992 12:34:56 die xxx mensis xi annoque mcmxcii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2448957 11 xi 11 11/30/1992 die xxx mensis xi annoque mcmxcii 92 xcii 1992}
+test clock-2.1367 {conversion of 1992-12-01} {
+ clock format 723213296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1992 12:34:56 die i mensis xii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2448958 12 xii 12 12/01/1992 die i mensis xii annoque mcmxcii 92 xcii 1992}
+test clock-2.1368 {conversion of 1992-12-31} {
+ clock format 725805296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1992 12:34:56 die xxxi mensis xii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2448988 12 xii 12 12/31/1992 die xxxi mensis xii annoque mcmxcii 92 xcii 1992}
+test clock-2.1369 {conversion of 1993-01-01} {
+ clock format 725891696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1993 12:34:56 die i mensis i annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2448989 01 i 1 01/01/1993 die i mensis i annoque mcmxciii 93 xciii 1993}
+test clock-2.1370 {conversion of 1993-01-31} {
+ clock format 728483696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1993 12:34:56 die xxxi mensis i annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2449019 01 i 1 01/31/1993 die xxxi mensis i annoque mcmxciii 93 xciii 1993}
+test clock-2.1371 {conversion of 1993-02-01} {
+ clock format 728570096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1993 12:34:56 die i mensis ii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2449020 02 ii 2 02/01/1993 die i mensis ii annoque mcmxciii 93 xciii 1993}
+test clock-2.1372 {conversion of 1993-02-28} {
+ clock format 730902896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1993 12:34:56 die xxviii mensis ii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2449047 02 ii 2 02/28/1993 die xxviii mensis ii annoque mcmxciii 93 xciii 1993}
+test clock-2.1373 {conversion of 1993-03-01} {
+ clock format 730989296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1993 12:34:56 die i mensis iii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2449048 03 iii 3 03/01/1993 die i mensis iii annoque mcmxciii 93 xciii 1993}
+test clock-2.1374 {conversion of 1993-03-31} {
+ clock format 733581296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1993 12:34:56 die xxxi mensis iii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2449078 03 iii 3 03/31/1993 die xxxi mensis iii annoque mcmxciii 93 xciii 1993}
+test clock-2.1375 {conversion of 1993-04-01} {
+ clock format 733667696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1993 12:34:56 die i mensis iv annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2449079 04 iv 4 04/01/1993 die i mensis iv annoque mcmxciii 93 xciii 1993}
+test clock-2.1376 {conversion of 1993-04-30} {
+ clock format 736173296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1993 12:34:56 die xxx mensis iv annoque mcmxciii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2449108 04 iv 4 04/30/1993 die xxx mensis iv annoque mcmxciii 93 xciii 1993}
+test clock-2.1377 {conversion of 1993-05-01} {
+ clock format 736259696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1993 12:34:56 die i mensis v annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2449109 05 v 5 05/01/1993 die i mensis v annoque mcmxciii 93 xciii 1993}
+test clock-2.1378 {conversion of 1993-05-31} {
+ clock format 738851696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1993 12:34:56 die xxxi mensis v annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2449139 05 v 5 05/31/1993 die xxxi mensis v annoque mcmxciii 93 xciii 1993}
+test clock-2.1379 {conversion of 1993-06-01} {
+ clock format 738938096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1993 12:34:56 die i mensis vi annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2449140 06 vi 6 06/01/1993 die i mensis vi annoque mcmxciii 93 xciii 1993}
+test clock-2.1380 {conversion of 1993-06-30} {
+ clock format 741443696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1993 12:34:56 die xxx mensis vi annoque mcmxciii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2449169 06 vi 6 06/30/1993 die xxx mensis vi annoque mcmxciii 93 xciii 1993}
+test clock-2.1381 {conversion of 1993-07-01} {
+ clock format 741530096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1993 12:34:56 die i mensis vii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2449170 07 vii 7 07/01/1993 die i mensis vii annoque mcmxciii 93 xciii 1993}
+test clock-2.1382 {conversion of 1993-07-31} {
+ clock format 744122096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1993 12:34:56 die xxxi mensis vii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2449200 07 vii 7 07/31/1993 die xxxi mensis vii annoque mcmxciii 93 xciii 1993}
+test clock-2.1383 {conversion of 1993-08-01} {
+ clock format 744208496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1993 12:34:56 die i mensis viii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2449201 08 viii 8 08/01/1993 die i mensis viii annoque mcmxciii 93 xciii 1993}
+test clock-2.1384 {conversion of 1993-08-31} {
+ clock format 746800496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1993 12:34:56 die xxxi mensis viii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2449231 08 viii 8 08/31/1993 die xxxi mensis viii annoque mcmxciii 93 xciii 1993}
+test clock-2.1385 {conversion of 1993-09-01} {
+ clock format 746886896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1993 12:34:56 die i mensis ix annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2449232 09 ix 9 09/01/1993 die i mensis ix annoque mcmxciii 93 xciii 1993}
+test clock-2.1386 {conversion of 1993-09-30} {
+ clock format 749392496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1993 12:34:56 die xxx mensis ix annoque mcmxciii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2449261 09 ix 9 09/30/1993 die xxx mensis ix annoque mcmxciii 93 xciii 1993}
+test clock-2.1387 {conversion of 1993-10-01} {
+ clock format 749478896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1993 12:34:56 die i mensis x annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2449262 10 x 10 10/01/1993 die i mensis x annoque mcmxciii 93 xciii 1993}
+test clock-2.1388 {conversion of 1993-10-31} {
+ clock format 752070896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1993 12:34:56 die xxxi mensis x annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2449292 10 x 10 10/31/1993 die xxxi mensis x annoque mcmxciii 93 xciii 1993}
+test clock-2.1389 {conversion of 1993-11-01} {
+ clock format 752157296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1993 12:34:56 die i mensis xi annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2449293 11 xi 11 11/01/1993 die i mensis xi annoque mcmxciii 93 xciii 1993}
+test clock-2.1390 {conversion of 1993-11-30} {
+ clock format 754662896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1993 12:34:56 die xxx mensis xi annoque mcmxciii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2449322 11 xi 11 11/30/1993 die xxx mensis xi annoque mcmxciii 93 xciii 1993}
+test clock-2.1391 {conversion of 1993-12-01} {
+ clock format 754749296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1993 12:34:56 die i mensis xii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2449323 12 xii 12 12/01/1993 die i mensis xii annoque mcmxciii 93 xciii 1993}
+test clock-2.1392 {conversion of 1993-12-31} {
+ clock format 757341296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1993 12:34:56 die xxxi mensis xii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2449353 12 xii 12 12/31/1993 die xxxi mensis xii annoque mcmxciii 93 xciii 1993}
+test clock-2.1393 {conversion of 1996-01-01} {
+ clock format 820499696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1996 12:34:56 die i mensis i annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2450084 01 i 1 01/01/1996 die i mensis i annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1394 {conversion of 1996-01-31} {
+ clock format 823091696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1996 12:34:56 die xxxi mensis i annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2450114 01 i 1 01/31/1996 die xxxi mensis i annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1395 {conversion of 1996-02-01} {
+ clock format 823178096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1996 12:34:56 die i mensis ii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2450115 02 ii 2 02/01/1996 die i mensis ii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1396 {conversion of 1996-02-29} {
+ clock format 825597296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1996 12:34:56 die xxix mensis ii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2450143 02 ii 2 02/29/1996 die xxix mensis ii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1397 {conversion of 1996-03-01} {
+ clock format 825683696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1996 12:34:56 die i mensis iii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2450144 03 iii 3 03/01/1996 die i mensis iii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1398 {conversion of 1996-03-31} {
+ clock format 828275696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1996 12:34:56 die xxxi mensis iii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2450174 03 iii 3 03/31/1996 die xxxi mensis iii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1399 {conversion of 1996-04-01} {
+ clock format 828362096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1996 12:34:56 die i mensis iv annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2450175 04 iv 4 04/01/1996 die i mensis iv annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1400 {conversion of 1996-04-30} {
+ clock format 830867696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1996 12:34:56 die xxx mensis iv annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2450204 04 iv 4 04/30/1996 die xxx mensis iv annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1401 {conversion of 1996-05-01} {
+ clock format 830954096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1996 12:34:56 die i mensis v annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2450205 05 v 5 05/01/1996 die i mensis v annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1402 {conversion of 1996-05-31} {
+ clock format 833546096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1996 12:34:56 die xxxi mensis v annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2450235 05 v 5 05/31/1996 die xxxi mensis v annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1403 {conversion of 1996-06-01} {
+ clock format 833632496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1996 12:34:56 die i mensis vi annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2450236 06 vi 6 06/01/1996 die i mensis vi annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1404 {conversion of 1996-06-30} {
+ clock format 836138096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1996 12:34:56 die xxx mensis vi annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2450265 06 vi 6 06/30/1996 die xxx mensis vi annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1405 {conversion of 1996-07-01} {
+ clock format 836224496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1996 12:34:56 die i mensis vii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2450266 07 vii 7 07/01/1996 die i mensis vii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1406 {conversion of 1996-07-31} {
+ clock format 838816496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1996 12:34:56 die xxxi mensis vii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2450296 07 vii 7 07/31/1996 die xxxi mensis vii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1407 {conversion of 1996-08-01} {
+ clock format 838902896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1996 12:34:56 die i mensis viii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2450297 08 viii 8 08/01/1996 die i mensis viii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1408 {conversion of 1996-08-31} {
+ clock format 841494896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1996 12:34:56 die xxxi mensis viii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2450327 08 viii 8 08/31/1996 die xxxi mensis viii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1409 {conversion of 1996-09-01} {
+ clock format 841581296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1996 12:34:56 die i mensis ix annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2450328 09 ix 9 09/01/1996 die i mensis ix annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1410 {conversion of 1996-09-30} {
+ clock format 844086896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1996 12:34:56 die xxx mensis ix annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2450357 09 ix 9 09/30/1996 die xxx mensis ix annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1411 {conversion of 1996-10-01} {
+ clock format 844173296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1996 12:34:56 die i mensis x annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2450358 10 x 10 10/01/1996 die i mensis x annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1412 {conversion of 1996-10-31} {
+ clock format 846765296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1996 12:34:56 die xxxi mensis x annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2450388 10 x 10 10/31/1996 die xxxi mensis x annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1413 {conversion of 1996-11-01} {
+ clock format 846851696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1996 12:34:56 die i mensis xi annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2450389 11 xi 11 11/01/1996 die i mensis xi annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1414 {conversion of 1996-11-30} {
+ clock format 849357296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1996 12:34:56 die xxx mensis xi annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2450418 11 xi 11 11/30/1996 die xxx mensis xi annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1415 {conversion of 1996-12-01} {
+ clock format 849443696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1996 12:34:56 die i mensis xii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2450419 12 xii 12 12/01/1996 die i mensis xii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1416 {conversion of 1996-12-31} {
+ clock format 852035696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1996 12:34:56 die xxxi mensis xii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2450449 12 xii 12 12/31/1996 die xxxi mensis xii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1417 {conversion of 1997-01-01} {
+ clock format 852122096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1997 12:34:56 die i mensis i annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2450450 01 i 1 01/01/1997 die i mensis i annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1418 {conversion of 1997-01-31} {
+ clock format 854714096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1997 12:34:56 die xxxi mensis i annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2450480 01 i 1 01/31/1997 die xxxi mensis i annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1419 {conversion of 1997-02-01} {
+ clock format 854800496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1997 12:34:56 die i mensis ii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2450481 02 ii 2 02/01/1997 die i mensis ii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1420 {conversion of 1997-02-28} {
+ clock format 857133296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1997 12:34:56 die xxviii mensis ii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2450508 02 ii 2 02/28/1997 die xxviii mensis ii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1421 {conversion of 1997-03-01} {
+ clock format 857219696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1997 12:34:56 die i mensis iii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2450509 03 iii 3 03/01/1997 die i mensis iii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1422 {conversion of 1997-03-31} {
+ clock format 859811696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1997 12:34:56 die xxxi mensis iii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2450539 03 iii 3 03/31/1997 die xxxi mensis iii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1423 {conversion of 1997-04-01} {
+ clock format 859898096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1997 12:34:56 die i mensis iv annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2450540 04 iv 4 04/01/1997 die i mensis iv annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1424 {conversion of 1997-04-30} {
+ clock format 862403696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1997 12:34:56 die xxx mensis iv annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2450569 04 iv 4 04/30/1997 die xxx mensis iv annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1425 {conversion of 1997-05-01} {
+ clock format 862490096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1997 12:34:56 die i mensis v annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2450570 05 v 5 05/01/1997 die i mensis v annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1426 {conversion of 1997-05-31} {
+ clock format 865082096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1997 12:34:56 die xxxi mensis v annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2450600 05 v 5 05/31/1997 die xxxi mensis v annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1427 {conversion of 1997-06-01} {
+ clock format 865168496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1997 12:34:56 die i mensis vi annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2450601 06 vi 6 06/01/1997 die i mensis vi annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1428 {conversion of 1997-06-30} {
+ clock format 867674096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1997 12:34:56 die xxx mensis vi annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2450630 06 vi 6 06/30/1997 die xxx mensis vi annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1429 {conversion of 1997-07-01} {
+ clock format 867760496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1997 12:34:56 die i mensis vii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2450631 07 vii 7 07/01/1997 die i mensis vii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1430 {conversion of 1997-07-31} {
+ clock format 870352496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1997 12:34:56 die xxxi mensis vii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2450661 07 vii 7 07/31/1997 die xxxi mensis vii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1431 {conversion of 1997-08-01} {
+ clock format 870438896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1997 12:34:56 die i mensis viii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2450662 08 viii 8 08/01/1997 die i mensis viii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1432 {conversion of 1997-08-31} {
+ clock format 873030896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1997 12:34:56 die xxxi mensis viii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2450692 08 viii 8 08/31/1997 die xxxi mensis viii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1433 {conversion of 1997-09-01} {
+ clock format 873117296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1997 12:34:56 die i mensis ix annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2450693 09 ix 9 09/01/1997 die i mensis ix annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1434 {conversion of 1997-09-30} {
+ clock format 875622896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1997 12:34:56 die xxx mensis ix annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2450722 09 ix 9 09/30/1997 die xxx mensis ix annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1435 {conversion of 1997-10-01} {
+ clock format 875709296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1997 12:34:56 die i mensis x annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2450723 10 x 10 10/01/1997 die i mensis x annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1436 {conversion of 1997-10-31} {
+ clock format 878301296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1997 12:34:56 die xxxi mensis x annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2450753 10 x 10 10/31/1997 die xxxi mensis x annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1437 {conversion of 1997-11-01} {
+ clock format 878387696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1997 12:34:56 die i mensis xi annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2450754 11 xi 11 11/01/1997 die i mensis xi annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1438 {conversion of 1997-11-30} {
+ clock format 880893296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1997 12:34:56 die xxx mensis xi annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2450783 11 xi 11 11/30/1997 die xxx mensis xi annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1439 {conversion of 1997-12-01} {
+ clock format 880979696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1997 12:34:56 die i mensis xii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2450784 12 xii 12 12/01/1997 die i mensis xii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1440 {conversion of 1997-12-31} {
+ clock format 883571696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1997 12:34:56 die xxxi mensis xii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2450814 12 xii 12 12/31/1997 die xxxi mensis xii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1441 {conversion of 2000-01-01} {
+ clock format 946730096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2000 12:34:56 die i mensis i annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2451545 01 i 1 01/01/2000 die i mensis i annoque mm? 00 ? 2000}
+test clock-2.1442 {conversion of 2000-01-31} {
+ clock format 949322096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2000 12:34:56 die xxxi mensis i annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2451575 01 i 1 01/31/2000 die xxxi mensis i annoque mm? 00 ? 2000}
+test clock-2.1443 {conversion of 2000-02-01} {
+ clock format 949408496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2000 12:34:56 die i mensis ii annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2451576 02 ii 2 02/01/2000 die i mensis ii annoque mm? 00 ? 2000}
+test clock-2.1444 {conversion of 2000-02-29} {
+ clock format 951827696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2000 12:34:56 die xxix mensis ii annoque mm? xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2451604 02 ii 2 02/29/2000 die xxix mensis ii annoque mm? 00 ? 2000}
+test clock-2.1445 {conversion of 2000-03-01} {
+ clock format 951914096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2000 12:34:56 die i mensis iii annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2451605 03 iii 3 03/01/2000 die i mensis iii annoque mm? 00 ? 2000}
+test clock-2.1446 {conversion of 2000-03-31} {
+ clock format 954506096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2000 12:34:56 die xxxi mensis iii annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2451635 03 iii 3 03/31/2000 die xxxi mensis iii annoque mm? 00 ? 2000}
+test clock-2.1447 {conversion of 2000-04-01} {
+ clock format 954592496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2000 12:34:56 die i mensis iv annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2451636 04 iv 4 04/01/2000 die i mensis iv annoque mm? 00 ? 2000}
+test clock-2.1448 {conversion of 2000-04-30} {
+ clock format 957098096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2000 12:34:56 die xxx mensis iv annoque mm? xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2451665 04 iv 4 04/30/2000 die xxx mensis iv annoque mm? 00 ? 2000}
+test clock-2.1449 {conversion of 2000-05-01} {
+ clock format 957184496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2000 12:34:56 die i mensis v annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2451666 05 v 5 05/01/2000 die i mensis v annoque mm? 00 ? 2000}
+test clock-2.1450 {conversion of 2000-05-31} {
+ clock format 959776496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2000 12:34:56 die xxxi mensis v annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2451696 05 v 5 05/31/2000 die xxxi mensis v annoque mm? 00 ? 2000}
+test clock-2.1451 {conversion of 2000-06-01} {
+ clock format 959862896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2000 12:34:56 die i mensis vi annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2451697 06 vi 6 06/01/2000 die i mensis vi annoque mm? 00 ? 2000}
+test clock-2.1452 {conversion of 2000-06-30} {
+ clock format 962368496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2000 12:34:56 die xxx mensis vi annoque mm? xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2451726 06 vi 6 06/30/2000 die xxx mensis vi annoque mm? 00 ? 2000}
+test clock-2.1453 {conversion of 2000-07-01} {
+ clock format 962454896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2000 12:34:56 die i mensis vii annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2451727 07 vii 7 07/01/2000 die i mensis vii annoque mm? 00 ? 2000}
+test clock-2.1454 {conversion of 2000-07-31} {
+ clock format 965046896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2000 12:34:56 die xxxi mensis vii annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2451757 07 vii 7 07/31/2000 die xxxi mensis vii annoque mm? 00 ? 2000}
+test clock-2.1455 {conversion of 2000-08-01} {
+ clock format 965133296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2000 12:34:56 die i mensis viii annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2451758 08 viii 8 08/01/2000 die i mensis viii annoque mm? 00 ? 2000}
+test clock-2.1456 {conversion of 2000-08-31} {
+ clock format 967725296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2000 12:34:56 die xxxi mensis viii annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2451788 08 viii 8 08/31/2000 die xxxi mensis viii annoque mm? 00 ? 2000}
+test clock-2.1457 {conversion of 2000-09-01} {
+ clock format 967811696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2000 12:34:56 die i mensis ix annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2451789 09 ix 9 09/01/2000 die i mensis ix annoque mm? 00 ? 2000}
+test clock-2.1458 {conversion of 2000-09-30} {
+ clock format 970317296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2000 12:34:56 die xxx mensis ix annoque mm? xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2451818 09 ix 9 09/30/2000 die xxx mensis ix annoque mm? 00 ? 2000}
+test clock-2.1459 {conversion of 2000-10-01} {
+ clock format 970403696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2000 12:34:56 die i mensis x annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2451819 10 x 10 10/01/2000 die i mensis x annoque mm? 00 ? 2000}
+test clock-2.1460 {conversion of 2000-10-31} {
+ clock format 972995696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2000 12:34:56 die xxxi mensis x annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2451849 10 x 10 10/31/2000 die xxxi mensis x annoque mm? 00 ? 2000}
+test clock-2.1461 {conversion of 2000-11-01} {
+ clock format 973082096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2000 12:34:56 die i mensis xi annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2451850 11 xi 11 11/01/2000 die i mensis xi annoque mm? 00 ? 2000}
+test clock-2.1462 {conversion of 2000-11-30} {
+ clock format 975587696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2000 12:34:56 die xxx mensis xi annoque mm? xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2451879 11 xi 11 11/30/2000 die xxx mensis xi annoque mm? 00 ? 2000}
+test clock-2.1463 {conversion of 2000-12-01} {
+ clock format 975674096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2000 12:34:56 die i mensis xii annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2451880 12 xii 12 12/01/2000 die i mensis xii annoque mm? 00 ? 2000}
+test clock-2.1464 {conversion of 2000-12-31} {
+ clock format 978266096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2000 12:34:56 die xxxi mensis xii annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2451910 12 xii 12 12/31/2000 die xxxi mensis xii annoque mm? 00 ? 2000}
+test clock-2.1465 {conversion of 2001-01-01} {
+ clock format 978352496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2001 12:34:56 die i mensis i annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2451911 01 i 1 01/01/2001 die i mensis i annoque mmi 01 i 2001}
+test clock-2.1466 {conversion of 2001-01-31} {
+ clock format 980944496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2001 12:34:56 die xxxi mensis i annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2451941 01 i 1 01/31/2001 die xxxi mensis i annoque mmi 01 i 2001}
+test clock-2.1467 {conversion of 2001-02-01} {
+ clock format 981030896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2001 12:34:56 die i mensis ii annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2451942 02 ii 2 02/01/2001 die i mensis ii annoque mmi 01 i 2001}
+test clock-2.1468 {conversion of 2001-02-28} {
+ clock format 983363696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2001 12:34:56 die xxviii mensis ii annoque mmi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2451969 02 ii 2 02/28/2001 die xxviii mensis ii annoque mmi 01 i 2001}
+test clock-2.1469 {conversion of 2001-03-01} {
+ clock format 983450096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2001 12:34:56 die i mensis iii annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2451970 03 iii 3 03/01/2001 die i mensis iii annoque mmi 01 i 2001}
+test clock-2.1470 {conversion of 2001-03-31} {
+ clock format 986042096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2001 12:34:56 die xxxi mensis iii annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2452000 03 iii 3 03/31/2001 die xxxi mensis iii annoque mmi 01 i 2001}
+test clock-2.1471 {conversion of 2001-04-01} {
+ clock format 986128496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2001 12:34:56 die i mensis iv annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2452001 04 iv 4 04/01/2001 die i mensis iv annoque mmi 01 i 2001}
+test clock-2.1472 {conversion of 2001-04-30} {
+ clock format 988634096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2001 12:34:56 die xxx mensis iv annoque mmi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2452030 04 iv 4 04/30/2001 die xxx mensis iv annoque mmi 01 i 2001}
+test clock-2.1473 {conversion of 2001-05-01} {
+ clock format 988720496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2001 12:34:56 die i mensis v annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2452031 05 v 5 05/01/2001 die i mensis v annoque mmi 01 i 2001}
+test clock-2.1474 {conversion of 2001-05-31} {
+ clock format 991312496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2001 12:34:56 die xxxi mensis v annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2452061 05 v 5 05/31/2001 die xxxi mensis v annoque mmi 01 i 2001}
+test clock-2.1475 {conversion of 2001-06-01} {
+ clock format 991398896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2001 12:34:56 die i mensis vi annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2452062 06 vi 6 06/01/2001 die i mensis vi annoque mmi 01 i 2001}
+test clock-2.1476 {conversion of 2001-06-30} {
+ clock format 993904496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2001 12:34:56 die xxx mensis vi annoque mmi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2452091 06 vi 6 06/30/2001 die xxx mensis vi annoque mmi 01 i 2001}
+test clock-2.1477 {conversion of 2001-07-01} {
+ clock format 993990896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2001 12:34:56 die i mensis vii annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2452092 07 vii 7 07/01/2001 die i mensis vii annoque mmi 01 i 2001}
+test clock-2.1478 {conversion of 2001-07-31} {
+ clock format 996582896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2001 12:34:56 die xxxi mensis vii annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2452122 07 vii 7 07/31/2001 die xxxi mensis vii annoque mmi 01 i 2001}
+test clock-2.1479 {conversion of 2001-08-01} {
+ clock format 996669296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2001 12:34:56 die i mensis viii annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2452123 08 viii 8 08/01/2001 die i mensis viii annoque mmi 01 i 2001}
+test clock-2.1480 {conversion of 2001-08-31} {
+ clock format 999261296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2001 12:34:56 die xxxi mensis viii annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2452153 08 viii 8 08/31/2001 die xxxi mensis viii annoque mmi 01 i 2001}
+test clock-2.1481 {conversion of 2001-09-01} {
+ clock format 999347696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2001 12:34:56 die i mensis ix annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2452154 09 ix 9 09/01/2001 die i mensis ix annoque mmi 01 i 2001}
+test clock-2.1482 {conversion of 2001-09-30} {
+ clock format 1001853296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2001 12:34:56 die xxx mensis ix annoque mmi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2452183 09 ix 9 09/30/2001 die xxx mensis ix annoque mmi 01 i 2001}
+test clock-2.1483 {conversion of 2001-10-01} {
+ clock format 1001939696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2001 12:34:56 die i mensis x annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2452184 10 x 10 10/01/2001 die i mensis x annoque mmi 01 i 2001}
+test clock-2.1484 {conversion of 2001-10-31} {
+ clock format 1004531696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2001 12:34:56 die xxxi mensis x annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2452214 10 x 10 10/31/2001 die xxxi mensis x annoque mmi 01 i 2001}
+test clock-2.1485 {conversion of 2001-11-01} {
+ clock format 1004618096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2001 12:34:56 die i mensis xi annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2452215 11 xi 11 11/01/2001 die i mensis xi annoque mmi 01 i 2001}
+test clock-2.1486 {conversion of 2001-11-30} {
+ clock format 1007123696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2001 12:34:56 die xxx mensis xi annoque mmi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2452244 11 xi 11 11/30/2001 die xxx mensis xi annoque mmi 01 i 2001}
+test clock-2.1487 {conversion of 2001-12-01} {
+ clock format 1007210096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2001 12:34:56 die i mensis xii annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2452245 12 xii 12 12/01/2001 die i mensis xii annoque mmi 01 i 2001}
+test clock-2.1488 {conversion of 2001-12-31} {
+ clock format 1009802096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2001 12:34:56 die xxxi mensis xii annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2452275 12 xii 12 12/31/2001 die xxxi mensis xii annoque mmi 01 i 2001}
+test clock-2.1489 {conversion of 2002-01-01} {
+ clock format 1009888496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2002 12:34:56 die i mensis i annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2452276 01 i 1 01/01/2002 die i mensis i annoque mmii 02 ii 2002}
+test clock-2.1490 {conversion of 2002-01-31} {
+ clock format 1012480496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2002 12:34:56 die xxxi mensis i annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2452306 01 i 1 01/31/2002 die xxxi mensis i annoque mmii 02 ii 2002}
+test clock-2.1491 {conversion of 2002-02-01} {
+ clock format 1012566896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2002 12:34:56 die i mensis ii annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2452307 02 ii 2 02/01/2002 die i mensis ii annoque mmii 02 ii 2002}
+test clock-2.1492 {conversion of 2002-02-28} {
+ clock format 1014899696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2002 12:34:56 die xxviii mensis ii annoque mmii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2452334 02 ii 2 02/28/2002 die xxviii mensis ii annoque mmii 02 ii 2002}
+test clock-2.1493 {conversion of 2002-03-01} {
+ clock format 1014986096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2002 12:34:56 die i mensis iii annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2452335 03 iii 3 03/01/2002 die i mensis iii annoque mmii 02 ii 2002}
+test clock-2.1494 {conversion of 2002-03-31} {
+ clock format 1017578096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2002 12:34:56 die xxxi mensis iii annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2452365 03 iii 3 03/31/2002 die xxxi mensis iii annoque mmii 02 ii 2002}
+test clock-2.1495 {conversion of 2002-04-01} {
+ clock format 1017664496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2002 12:34:56 die i mensis iv annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2452366 04 iv 4 04/01/2002 die i mensis iv annoque mmii 02 ii 2002}
+test clock-2.1496 {conversion of 2002-04-30} {
+ clock format 1020170096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2002 12:34:56 die xxx mensis iv annoque mmii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2452395 04 iv 4 04/30/2002 die xxx mensis iv annoque mmii 02 ii 2002}
+test clock-2.1497 {conversion of 2002-05-01} {
+ clock format 1020256496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2002 12:34:56 die i mensis v annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2452396 05 v 5 05/01/2002 die i mensis v annoque mmii 02 ii 2002}
+test clock-2.1498 {conversion of 2002-05-31} {
+ clock format 1022848496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2002 12:34:56 die xxxi mensis v annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2452426 05 v 5 05/31/2002 die xxxi mensis v annoque mmii 02 ii 2002}
+test clock-2.1499 {conversion of 2002-06-01} {
+ clock format 1022934896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2002 12:34:56 die i mensis vi annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2452427 06 vi 6 06/01/2002 die i mensis vi annoque mmii 02 ii 2002}
+test clock-2.1500 {conversion of 2002-06-30} {
+ clock format 1025440496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2002 12:34:56 die xxx mensis vi annoque mmii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2452456 06 vi 6 06/30/2002 die xxx mensis vi annoque mmii 02 ii 2002}
+test clock-2.1501 {conversion of 2002-07-01} {
+ clock format 1025526896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2002 12:34:56 die i mensis vii annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2452457 07 vii 7 07/01/2002 die i mensis vii annoque mmii 02 ii 2002}
+test clock-2.1502 {conversion of 2002-07-31} {
+ clock format 1028118896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2002 12:34:56 die xxxi mensis vii annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2452487 07 vii 7 07/31/2002 die xxxi mensis vii annoque mmii 02 ii 2002}
+test clock-2.1503 {conversion of 2002-08-01} {
+ clock format 1028205296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2002 12:34:56 die i mensis viii annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2452488 08 viii 8 08/01/2002 die i mensis viii annoque mmii 02 ii 2002}
+test clock-2.1504 {conversion of 2002-08-31} {
+ clock format 1030797296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2002 12:34:56 die xxxi mensis viii annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2452518 08 viii 8 08/31/2002 die xxxi mensis viii annoque mmii 02 ii 2002}
+test clock-2.1505 {conversion of 2002-09-01} {
+ clock format 1030883696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2002 12:34:56 die i mensis ix annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2452519 09 ix 9 09/01/2002 die i mensis ix annoque mmii 02 ii 2002}
+test clock-2.1506 {conversion of 2002-09-30} {
+ clock format 1033389296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2002 12:34:56 die xxx mensis ix annoque mmii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2452548 09 ix 9 09/30/2002 die xxx mensis ix annoque mmii 02 ii 2002}
+test clock-2.1507 {conversion of 2002-10-01} {
+ clock format 1033475696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2002 12:34:56 die i mensis x annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2452549 10 x 10 10/01/2002 die i mensis x annoque mmii 02 ii 2002}
+test clock-2.1508 {conversion of 2002-10-31} {
+ clock format 1036067696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2002 12:34:56 die xxxi mensis x annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2452579 10 x 10 10/31/2002 die xxxi mensis x annoque mmii 02 ii 2002}
+test clock-2.1509 {conversion of 2002-11-01} {
+ clock format 1036154096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2002 12:34:56 die i mensis xi annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2452580 11 xi 11 11/01/2002 die i mensis xi annoque mmii 02 ii 2002}
+test clock-2.1510 {conversion of 2002-11-30} {
+ clock format 1038659696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2002 12:34:56 die xxx mensis xi annoque mmii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2452609 11 xi 11 11/30/2002 die xxx mensis xi annoque mmii 02 ii 2002}
+test clock-2.1511 {conversion of 2002-12-01} {
+ clock format 1038746096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2002 12:34:56 die i mensis xii annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2452610 12 xii 12 12/01/2002 die i mensis xii annoque mmii 02 ii 2002}
+test clock-2.1512 {conversion of 2002-12-31} {
+ clock format 1041338096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2002 12:34:56 die xxxi mensis xii annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2452640 12 xii 12 12/31/2002 die xxxi mensis xii annoque mmii 02 ii 2002}
+test clock-2.1513 {conversion of 2003-01-01} {
+ clock format 1041424496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2003 12:34:56 die i mensis i annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2452641 01 i 1 01/01/2003 die i mensis i annoque mmiii 03 iii 2003}
+test clock-2.1514 {conversion of 2003-01-31} {
+ clock format 1044016496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2003 12:34:56 die xxxi mensis i annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2452671 01 i 1 01/31/2003 die xxxi mensis i annoque mmiii 03 iii 2003}
+test clock-2.1515 {conversion of 2003-02-01} {
+ clock format 1044102896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2003 12:34:56 die i mensis ii annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2452672 02 ii 2 02/01/2003 die i mensis ii annoque mmiii 03 iii 2003}
+test clock-2.1516 {conversion of 2003-02-28} {
+ clock format 1046435696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2003 12:34:56 die xxviii mensis ii annoque mmiii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2452699 02 ii 2 02/28/2003 die xxviii mensis ii annoque mmiii 03 iii 2003}
+test clock-2.1517 {conversion of 2003-03-01} {
+ clock format 1046522096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2003 12:34:56 die i mensis iii annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2452700 03 iii 3 03/01/2003 die i mensis iii annoque mmiii 03 iii 2003}
+test clock-2.1518 {conversion of 2003-03-31} {
+ clock format 1049114096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2003 12:34:56 die xxxi mensis iii annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2452730 03 iii 3 03/31/2003 die xxxi mensis iii annoque mmiii 03 iii 2003}
+test clock-2.1519 {conversion of 2003-04-01} {
+ clock format 1049200496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2003 12:34:56 die i mensis iv annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2452731 04 iv 4 04/01/2003 die i mensis iv annoque mmiii 03 iii 2003}
+test clock-2.1520 {conversion of 2003-04-30} {
+ clock format 1051706096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2003 12:34:56 die xxx mensis iv annoque mmiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2452760 04 iv 4 04/30/2003 die xxx mensis iv annoque mmiii 03 iii 2003}
+test clock-2.1521 {conversion of 2003-05-01} {
+ clock format 1051792496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2003 12:34:56 die i mensis v annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2452761 05 v 5 05/01/2003 die i mensis v annoque mmiii 03 iii 2003}
+test clock-2.1522 {conversion of 2003-05-31} {
+ clock format 1054384496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2003 12:34:56 die xxxi mensis v annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2452791 05 v 5 05/31/2003 die xxxi mensis v annoque mmiii 03 iii 2003}
+test clock-2.1523 {conversion of 2003-06-01} {
+ clock format 1054470896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2003 12:34:56 die i mensis vi annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2452792 06 vi 6 06/01/2003 die i mensis vi annoque mmiii 03 iii 2003}
+test clock-2.1524 {conversion of 2003-06-30} {
+ clock format 1056976496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2003 12:34:56 die xxx mensis vi annoque mmiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2452821 06 vi 6 06/30/2003 die xxx mensis vi annoque mmiii 03 iii 2003}
+test clock-2.1525 {conversion of 2003-07-01} {
+ clock format 1057062896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2003 12:34:56 die i mensis vii annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2452822 07 vii 7 07/01/2003 die i mensis vii annoque mmiii 03 iii 2003}
+test clock-2.1526 {conversion of 2003-07-31} {
+ clock format 1059654896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2003 12:34:56 die xxxi mensis vii annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2452852 07 vii 7 07/31/2003 die xxxi mensis vii annoque mmiii 03 iii 2003}
+test clock-2.1527 {conversion of 2003-08-01} {
+ clock format 1059741296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2003 12:34:56 die i mensis viii annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2452853 08 viii 8 08/01/2003 die i mensis viii annoque mmiii 03 iii 2003}
+test clock-2.1528 {conversion of 2003-08-31} {
+ clock format 1062333296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2003 12:34:56 die xxxi mensis viii annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2452883 08 viii 8 08/31/2003 die xxxi mensis viii annoque mmiii 03 iii 2003}
+test clock-2.1529 {conversion of 2003-09-01} {
+ clock format 1062419696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2003 12:34:56 die i mensis ix annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2452884 09 ix 9 09/01/2003 die i mensis ix annoque mmiii 03 iii 2003}
+test clock-2.1530 {conversion of 2003-09-30} {
+ clock format 1064925296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2003 12:34:56 die xxx mensis ix annoque mmiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2452913 09 ix 9 09/30/2003 die xxx mensis ix annoque mmiii 03 iii 2003}
+test clock-2.1531 {conversion of 2003-10-01} {
+ clock format 1065011696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2003 12:34:56 die i mensis x annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2452914 10 x 10 10/01/2003 die i mensis x annoque mmiii 03 iii 2003}
+test clock-2.1532 {conversion of 2003-10-31} {
+ clock format 1067603696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2003 12:34:56 die xxxi mensis x annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2452944 10 x 10 10/31/2003 die xxxi mensis x annoque mmiii 03 iii 2003}
+test clock-2.1533 {conversion of 2003-11-01} {
+ clock format 1067690096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2003 12:34:56 die i mensis xi annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2452945 11 xi 11 11/01/2003 die i mensis xi annoque mmiii 03 iii 2003}
+test clock-2.1534 {conversion of 2003-11-30} {
+ clock format 1070195696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2003 12:34:56 die xxx mensis xi annoque mmiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2452974 11 xi 11 11/30/2003 die xxx mensis xi annoque mmiii 03 iii 2003}
+test clock-2.1535 {conversion of 2003-12-01} {
+ clock format 1070282096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2003 12:34:56 die i mensis xii annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2452975 12 xii 12 12/01/2003 die i mensis xii annoque mmiii 03 iii 2003}
+test clock-2.1536 {conversion of 2003-12-31} {
+ clock format 1072874096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2003 12:34:56 die xxxi mensis xii annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2453005 12 xii 12 12/31/2003 die xxxi mensis xii annoque mmiii 03 iii 2003}
+test clock-2.1537 {conversion of 2004-01-01} {
+ clock format 1072960496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2004 12:34:56 die i mensis i annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2453006 01 i 1 01/01/2004 die i mensis i annoque mmiv 04 iv 2004}
+test clock-2.1538 {conversion of 2004-01-31} {
+ clock format 1075552496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2004 12:34:56 die xxxi mensis i annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2453036 01 i 1 01/31/2004 die xxxi mensis i annoque mmiv 04 iv 2004}
+test clock-2.1539 {conversion of 2004-02-01} {
+ clock format 1075638896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2004 12:34:56 die i mensis ii annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2453037 02 ii 2 02/01/2004 die i mensis ii annoque mmiv 04 iv 2004}
+test clock-2.1540 {conversion of 2004-02-29} {
+ clock format 1078058096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2004 12:34:56 die xxix mensis ii annoque mmiv xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2453065 02 ii 2 02/29/2004 die xxix mensis ii annoque mmiv 04 iv 2004}
+test clock-2.1541 {conversion of 2004-03-01} {
+ clock format 1078144496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2004 12:34:56 die i mensis iii annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2453066 03 iii 3 03/01/2004 die i mensis iii annoque mmiv 04 iv 2004}
+test clock-2.1542 {conversion of 2004-03-31} {
+ clock format 1080736496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2004 12:34:56 die xxxi mensis iii annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2453096 03 iii 3 03/31/2004 die xxxi mensis iii annoque mmiv 04 iv 2004}
+test clock-2.1543 {conversion of 2004-04-01} {
+ clock format 1080822896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2004 12:34:56 die i mensis iv annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2453097 04 iv 4 04/01/2004 die i mensis iv annoque mmiv 04 iv 2004}
+test clock-2.1544 {conversion of 2004-04-30} {
+ clock format 1083328496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2004 12:34:56 die xxx mensis iv annoque mmiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2453126 04 iv 4 04/30/2004 die xxx mensis iv annoque mmiv 04 iv 2004}
+test clock-2.1545 {conversion of 2004-05-01} {
+ clock format 1083414896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2004 12:34:56 die i mensis v annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2453127 05 v 5 05/01/2004 die i mensis v annoque mmiv 04 iv 2004}
+test clock-2.1546 {conversion of 2004-05-31} {
+ clock format 1086006896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2004 12:34:56 die xxxi mensis v annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2453157 05 v 5 05/31/2004 die xxxi mensis v annoque mmiv 04 iv 2004}
+test clock-2.1547 {conversion of 2004-06-01} {
+ clock format 1086093296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2004 12:34:56 die i mensis vi annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2453158 06 vi 6 06/01/2004 die i mensis vi annoque mmiv 04 iv 2004}
+test clock-2.1548 {conversion of 2004-06-30} {
+ clock format 1088598896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2004 12:34:56 die xxx mensis vi annoque mmiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2453187 06 vi 6 06/30/2004 die xxx mensis vi annoque mmiv 04 iv 2004}
+test clock-2.1549 {conversion of 2004-07-01} {
+ clock format 1088685296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2004 12:34:56 die i mensis vii annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2453188 07 vii 7 07/01/2004 die i mensis vii annoque mmiv 04 iv 2004}
+test clock-2.1550 {conversion of 2004-07-31} {
+ clock format 1091277296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2004 12:34:56 die xxxi mensis vii annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2453218 07 vii 7 07/31/2004 die xxxi mensis vii annoque mmiv 04 iv 2004}
+test clock-2.1551 {conversion of 2004-08-01} {
+ clock format 1091363696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2004 12:34:56 die i mensis viii annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2453219 08 viii 8 08/01/2004 die i mensis viii annoque mmiv 04 iv 2004}
+test clock-2.1552 {conversion of 2004-08-31} {
+ clock format 1093955696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2004 12:34:56 die xxxi mensis viii annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2453249 08 viii 8 08/31/2004 die xxxi mensis viii annoque mmiv 04 iv 2004}
+test clock-2.1553 {conversion of 2004-09-01} {
+ clock format 1094042096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2004 12:34:56 die i mensis ix annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2453250 09 ix 9 09/01/2004 die i mensis ix annoque mmiv 04 iv 2004}
+test clock-2.1554 {conversion of 2004-09-30} {
+ clock format 1096547696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2004 12:34:56 die xxx mensis ix annoque mmiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2453279 09 ix 9 09/30/2004 die xxx mensis ix annoque mmiv 04 iv 2004}
+test clock-2.1555 {conversion of 2004-10-01} {
+ clock format 1096634096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2004 12:34:56 die i mensis x annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2453280 10 x 10 10/01/2004 die i mensis x annoque mmiv 04 iv 2004}
+test clock-2.1556 {conversion of 2004-10-31} {
+ clock format 1099226096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2004 12:34:56 die xxxi mensis x annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2453310 10 x 10 10/31/2004 die xxxi mensis x annoque mmiv 04 iv 2004}
+test clock-2.1557 {conversion of 2004-11-01} {
+ clock format 1099312496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2004 12:34:56 die i mensis xi annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2453311 11 xi 11 11/01/2004 die i mensis xi annoque mmiv 04 iv 2004}
+test clock-2.1558 {conversion of 2004-11-30} {
+ clock format 1101818096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2004 12:34:56 die xxx mensis xi annoque mmiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2453340 11 xi 11 11/30/2004 die xxx mensis xi annoque mmiv 04 iv 2004}
+test clock-2.1559 {conversion of 2004-12-01} {
+ clock format 1101904496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2004 12:34:56 die i mensis xii annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2453341 12 xii 12 12/01/2004 die i mensis xii annoque mmiv 04 iv 2004}
+test clock-2.1560 {conversion of 2004-12-31} {
+ clock format 1104496496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2004 12:34:56 die xxxi mensis xii annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2453371 12 xii 12 12/31/2004 die xxxi mensis xii annoque mmiv 04 iv 2004}
+test clock-2.1561 {conversion of 2005-01-01} {
+ clock format 1104582896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2005 12:34:56 die i mensis i annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2453372 01 i 1 01/01/2005 die i mensis i annoque mmv 05 v 2005}
+test clock-2.1562 {conversion of 2005-01-31} {
+ clock format 1107174896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2005 12:34:56 die xxxi mensis i annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2453402 01 i 1 01/31/2005 die xxxi mensis i annoque mmv 05 v 2005}
+test clock-2.1563 {conversion of 2005-02-01} {
+ clock format 1107261296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2005 12:34:56 die i mensis ii annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2453403 02 ii 2 02/01/2005 die i mensis ii annoque mmv 05 v 2005}
+test clock-2.1564 {conversion of 2005-02-28} {
+ clock format 1109594096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2005 12:34:56 die xxviii mensis ii annoque mmv xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2453430 02 ii 2 02/28/2005 die xxviii mensis ii annoque mmv 05 v 2005}
+test clock-2.1565 {conversion of 2005-03-01} {
+ clock format 1109680496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2005 12:34:56 die i mensis iii annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2453431 03 iii 3 03/01/2005 die i mensis iii annoque mmv 05 v 2005}
+test clock-2.1566 {conversion of 2005-03-31} {
+ clock format 1112272496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2005 12:34:56 die xxxi mensis iii annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2453461 03 iii 3 03/31/2005 die xxxi mensis iii annoque mmv 05 v 2005}
+test clock-2.1567 {conversion of 2005-04-01} {
+ clock format 1112358896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2005 12:34:56 die i mensis iv annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2453462 04 iv 4 04/01/2005 die i mensis iv annoque mmv 05 v 2005}
+test clock-2.1568 {conversion of 2005-04-30} {
+ clock format 1114864496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2005 12:34:56 die xxx mensis iv annoque mmv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2453491 04 iv 4 04/30/2005 die xxx mensis iv annoque mmv 05 v 2005}
+test clock-2.1569 {conversion of 2005-05-01} {
+ clock format 1114950896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2005 12:34:56 die i mensis v annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2453492 05 v 5 05/01/2005 die i mensis v annoque mmv 05 v 2005}
+test clock-2.1570 {conversion of 2005-05-31} {
+ clock format 1117542896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2005 12:34:56 die xxxi mensis v annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2453522 05 v 5 05/31/2005 die xxxi mensis v annoque mmv 05 v 2005}
+test clock-2.1571 {conversion of 2005-06-01} {
+ clock format 1117629296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2005 12:34:56 die i mensis vi annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2453523 06 vi 6 06/01/2005 die i mensis vi annoque mmv 05 v 2005}
+test clock-2.1572 {conversion of 2005-06-30} {
+ clock format 1120134896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2005 12:34:56 die xxx mensis vi annoque mmv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2453552 06 vi 6 06/30/2005 die xxx mensis vi annoque mmv 05 v 2005}
+test clock-2.1573 {conversion of 2005-07-01} {
+ clock format 1120221296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2005 12:34:56 die i mensis vii annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2453553 07 vii 7 07/01/2005 die i mensis vii annoque mmv 05 v 2005}
+test clock-2.1574 {conversion of 2005-07-31} {
+ clock format 1122813296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2005 12:34:56 die xxxi mensis vii annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2453583 07 vii 7 07/31/2005 die xxxi mensis vii annoque mmv 05 v 2005}
+test clock-2.1575 {conversion of 2005-08-01} {
+ clock format 1122899696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2005 12:34:56 die i mensis viii annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2453584 08 viii 8 08/01/2005 die i mensis viii annoque mmv 05 v 2005}
+test clock-2.1576 {conversion of 2005-08-31} {
+ clock format 1125491696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2005 12:34:56 die xxxi mensis viii annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2453614 08 viii 8 08/31/2005 die xxxi mensis viii annoque mmv 05 v 2005}
+test clock-2.1577 {conversion of 2005-09-01} {
+ clock format 1125578096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2005 12:34:56 die i mensis ix annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2453615 09 ix 9 09/01/2005 die i mensis ix annoque mmv 05 v 2005}
+test clock-2.1578 {conversion of 2005-09-30} {
+ clock format 1128083696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2005 12:34:56 die xxx mensis ix annoque mmv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2453644 09 ix 9 09/30/2005 die xxx mensis ix annoque mmv 05 v 2005}
+test clock-2.1579 {conversion of 2005-10-01} {
+ clock format 1128170096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2005 12:34:56 die i mensis x annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2453645 10 x 10 10/01/2005 die i mensis x annoque mmv 05 v 2005}
+test clock-2.1580 {conversion of 2005-10-31} {
+ clock format 1130762096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2005 12:34:56 die xxxi mensis x annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2453675 10 x 10 10/31/2005 die xxxi mensis x annoque mmv 05 v 2005}
+test clock-2.1581 {conversion of 2005-11-01} {
+ clock format 1130848496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2005 12:34:56 die i mensis xi annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2453676 11 xi 11 11/01/2005 die i mensis xi annoque mmv 05 v 2005}
+test clock-2.1582 {conversion of 2005-11-30} {
+ clock format 1133354096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2005 12:34:56 die xxx mensis xi annoque mmv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2453705 11 xi 11 11/30/2005 die xxx mensis xi annoque mmv 05 v 2005}
+test clock-2.1583 {conversion of 2005-12-01} {
+ clock format 1133440496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2005 12:34:56 die i mensis xii annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2453706 12 xii 12 12/01/2005 die i mensis xii annoque mmv 05 v 2005}
+test clock-2.1584 {conversion of 2005-12-31} {
+ clock format 1136032496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2005 12:34:56 die xxxi mensis xii annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2453736 12 xii 12 12/31/2005 die xxxi mensis xii annoque mmv 05 v 2005}
+test clock-2.1585 {conversion of 2006-01-01} {
+ clock format 1136118896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2006 12:34:56 die i mensis i annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2453737 01 i 1 01/01/2006 die i mensis i annoque mmvi 06 vi 2006}
+test clock-2.1586 {conversion of 2006-01-31} {
+ clock format 1138710896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2006 12:34:56 die xxxi mensis i annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2453767 01 i 1 01/31/2006 die xxxi mensis i annoque mmvi 06 vi 2006}
+test clock-2.1587 {conversion of 2006-02-01} {
+ clock format 1138797296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2006 12:34:56 die i mensis ii annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2453768 02 ii 2 02/01/2006 die i mensis ii annoque mmvi 06 vi 2006}
+test clock-2.1588 {conversion of 2006-02-28} {
+ clock format 1141130096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2006 12:34:56 die xxviii mensis ii annoque mmvi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2453795 02 ii 2 02/28/2006 die xxviii mensis ii annoque mmvi 06 vi 2006}
+test clock-2.1589 {conversion of 2006-03-01} {
+ clock format 1141216496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2006 12:34:56 die i mensis iii annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2453796 03 iii 3 03/01/2006 die i mensis iii annoque mmvi 06 vi 2006}
+test clock-2.1590 {conversion of 2006-03-31} {
+ clock format 1143808496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2006 12:34:56 die xxxi mensis iii annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2453826 03 iii 3 03/31/2006 die xxxi mensis iii annoque mmvi 06 vi 2006}
+test clock-2.1591 {conversion of 2006-04-01} {
+ clock format 1143894896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2006 12:34:56 die i mensis iv annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2453827 04 iv 4 04/01/2006 die i mensis iv annoque mmvi 06 vi 2006}
+test clock-2.1592 {conversion of 2006-04-30} {
+ clock format 1146400496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2006 12:34:56 die xxx mensis iv annoque mmvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2453856 04 iv 4 04/30/2006 die xxx mensis iv annoque mmvi 06 vi 2006}
+test clock-2.1593 {conversion of 2006-05-01} {
+ clock format 1146486896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2006 12:34:56 die i mensis v annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2453857 05 v 5 05/01/2006 die i mensis v annoque mmvi 06 vi 2006}
+test clock-2.1594 {conversion of 2006-05-31} {
+ clock format 1149078896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2006 12:34:56 die xxxi mensis v annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2453887 05 v 5 05/31/2006 die xxxi mensis v annoque mmvi 06 vi 2006}
+test clock-2.1595 {conversion of 2006-06-01} {
+ clock format 1149165296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2006 12:34:56 die i mensis vi annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2453888 06 vi 6 06/01/2006 die i mensis vi annoque mmvi 06 vi 2006}
+test clock-2.1596 {conversion of 2006-06-30} {
+ clock format 1151670896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2006 12:34:56 die xxx mensis vi annoque mmvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2453917 06 vi 6 06/30/2006 die xxx mensis vi annoque mmvi 06 vi 2006}
+test clock-2.1597 {conversion of 2006-07-01} {
+ clock format 1151757296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2006 12:34:56 die i mensis vii annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2453918 07 vii 7 07/01/2006 die i mensis vii annoque mmvi 06 vi 2006}
+test clock-2.1598 {conversion of 2006-07-31} {
+ clock format 1154349296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2006 12:34:56 die xxxi mensis vii annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2453948 07 vii 7 07/31/2006 die xxxi mensis vii annoque mmvi 06 vi 2006}
+test clock-2.1599 {conversion of 2006-08-01} {
+ clock format 1154435696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2006 12:34:56 die i mensis viii annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2453949 08 viii 8 08/01/2006 die i mensis viii annoque mmvi 06 vi 2006}
+test clock-2.1600 {conversion of 2006-08-31} {
+ clock format 1157027696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2006 12:34:56 die xxxi mensis viii annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2453979 08 viii 8 08/31/2006 die xxxi mensis viii annoque mmvi 06 vi 2006}
+test clock-2.1601 {conversion of 2006-09-01} {
+ clock format 1157114096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2006 12:34:56 die i mensis ix annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2453980 09 ix 9 09/01/2006 die i mensis ix annoque mmvi 06 vi 2006}
+test clock-2.1602 {conversion of 2006-09-30} {
+ clock format 1159619696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2006 12:34:56 die xxx mensis ix annoque mmvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2454009 09 ix 9 09/30/2006 die xxx mensis ix annoque mmvi 06 vi 2006}
+test clock-2.1603 {conversion of 2006-10-01} {
+ clock format 1159706096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2006 12:34:56 die i mensis x annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2454010 10 x 10 10/01/2006 die i mensis x annoque mmvi 06 vi 2006}
+test clock-2.1604 {conversion of 2006-10-31} {
+ clock format 1162298096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2006 12:34:56 die xxxi mensis x annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2454040 10 x 10 10/31/2006 die xxxi mensis x annoque mmvi 06 vi 2006}
+test clock-2.1605 {conversion of 2006-11-01} {
+ clock format 1162384496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2006 12:34:56 die i mensis xi annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2454041 11 xi 11 11/01/2006 die i mensis xi annoque mmvi 06 vi 2006}
+test clock-2.1606 {conversion of 2006-11-30} {
+ clock format 1164890096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2006 12:34:56 die xxx mensis xi annoque mmvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2454070 11 xi 11 11/30/2006 die xxx mensis xi annoque mmvi 06 vi 2006}
+test clock-2.1607 {conversion of 2006-12-01} {
+ clock format 1164976496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2006 12:34:56 die i mensis xii annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2454071 12 xii 12 12/01/2006 die i mensis xii annoque mmvi 06 vi 2006}
+test clock-2.1608 {conversion of 2006-12-31} {
+ clock format 1167568496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2006 12:34:56 die xxxi mensis xii annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2454101 12 xii 12 12/31/2006 die xxxi mensis xii annoque mmvi 06 vi 2006}
+test clock-2.1609 {conversion of 2007-01-01} {
+ clock format 1167654896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2007 12:34:56 die i mensis i annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2454102 01 i 1 01/01/2007 die i mensis i annoque mmvii 07 vii 2007}
+test clock-2.1610 {conversion of 2007-01-31} {
+ clock format 1170246896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2007 12:34:56 die xxxi mensis i annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2454132 01 i 1 01/31/2007 die xxxi mensis i annoque mmvii 07 vii 2007}
+test clock-2.1611 {conversion of 2007-02-01} {
+ clock format 1170333296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2007 12:34:56 die i mensis ii annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2454133 02 ii 2 02/01/2007 die i mensis ii annoque mmvii 07 vii 2007}
+test clock-2.1612 {conversion of 2007-02-28} {
+ clock format 1172666096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2007 12:34:56 die xxviii mensis ii annoque mmvii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2454160 02 ii 2 02/28/2007 die xxviii mensis ii annoque mmvii 07 vii 2007}
+test clock-2.1613 {conversion of 2007-03-01} {
+ clock format 1172752496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2007 12:34:56 die i mensis iii annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2454161 03 iii 3 03/01/2007 die i mensis iii annoque mmvii 07 vii 2007}
+test clock-2.1614 {conversion of 2007-03-31} {
+ clock format 1175344496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2007 12:34:56 die xxxi mensis iii annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2454191 03 iii 3 03/31/2007 die xxxi mensis iii annoque mmvii 07 vii 2007}
+test clock-2.1615 {conversion of 2007-04-01} {
+ clock format 1175430896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2007 12:34:56 die i mensis iv annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2454192 04 iv 4 04/01/2007 die i mensis iv annoque mmvii 07 vii 2007}
+test clock-2.1616 {conversion of 2007-04-30} {
+ clock format 1177936496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2007 12:34:56 die xxx mensis iv annoque mmvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2454221 04 iv 4 04/30/2007 die xxx mensis iv annoque mmvii 07 vii 2007}
+test clock-2.1617 {conversion of 2007-05-01} {
+ clock format 1178022896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2007 12:34:56 die i mensis v annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2454222 05 v 5 05/01/2007 die i mensis v annoque mmvii 07 vii 2007}
+test clock-2.1618 {conversion of 2007-05-31} {
+ clock format 1180614896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2007 12:34:56 die xxxi mensis v annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2454252 05 v 5 05/31/2007 die xxxi mensis v annoque mmvii 07 vii 2007}
+test clock-2.1619 {conversion of 2007-06-01} {
+ clock format 1180701296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2007 12:34:56 die i mensis vi annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2454253 06 vi 6 06/01/2007 die i mensis vi annoque mmvii 07 vii 2007}
+test clock-2.1620 {conversion of 2007-06-30} {
+ clock format 1183206896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2007 12:34:56 die xxx mensis vi annoque mmvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2454282 06 vi 6 06/30/2007 die xxx mensis vi annoque mmvii 07 vii 2007}
+test clock-2.1621 {conversion of 2007-07-01} {
+ clock format 1183293296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2007 12:34:56 die i mensis vii annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2454283 07 vii 7 07/01/2007 die i mensis vii annoque mmvii 07 vii 2007}
+test clock-2.1622 {conversion of 2007-07-31} {
+ clock format 1185885296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2007 12:34:56 die xxxi mensis vii annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2454313 07 vii 7 07/31/2007 die xxxi mensis vii annoque mmvii 07 vii 2007}
+test clock-2.1623 {conversion of 2007-08-01} {
+ clock format 1185971696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2007 12:34:56 die i mensis viii annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2454314 08 viii 8 08/01/2007 die i mensis viii annoque mmvii 07 vii 2007}
+test clock-2.1624 {conversion of 2007-08-31} {
+ clock format 1188563696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2007 12:34:56 die xxxi mensis viii annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2454344 08 viii 8 08/31/2007 die xxxi mensis viii annoque mmvii 07 vii 2007}
+test clock-2.1625 {conversion of 2007-09-01} {
+ clock format 1188650096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2007 12:34:56 die i mensis ix annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2454345 09 ix 9 09/01/2007 die i mensis ix annoque mmvii 07 vii 2007}
+test clock-2.1626 {conversion of 2007-09-30} {
+ clock format 1191155696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2007 12:34:56 die xxx mensis ix annoque mmvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2454374 09 ix 9 09/30/2007 die xxx mensis ix annoque mmvii 07 vii 2007}
+test clock-2.1627 {conversion of 2007-10-01} {
+ clock format 1191242096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2007 12:34:56 die i mensis x annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2454375 10 x 10 10/01/2007 die i mensis x annoque mmvii 07 vii 2007}
+test clock-2.1628 {conversion of 2007-10-31} {
+ clock format 1193834096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2007 12:34:56 die xxxi mensis x annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2454405 10 x 10 10/31/2007 die xxxi mensis x annoque mmvii 07 vii 2007}
+test clock-2.1629 {conversion of 2007-11-01} {
+ clock format 1193920496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2007 12:34:56 die i mensis xi annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2454406 11 xi 11 11/01/2007 die i mensis xi annoque mmvii 07 vii 2007}
+test clock-2.1630 {conversion of 2007-11-30} {
+ clock format 1196426096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2007 12:34:56 die xxx mensis xi annoque mmvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2454435 11 xi 11 11/30/2007 die xxx mensis xi annoque mmvii 07 vii 2007}
+test clock-2.1631 {conversion of 2007-12-01} {
+ clock format 1196512496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2007 12:34:56 die i mensis xii annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2454436 12 xii 12 12/01/2007 die i mensis xii annoque mmvii 07 vii 2007}
+test clock-2.1632 {conversion of 2007-12-31} {
+ clock format 1199104496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2007 12:34:56 die xxxi mensis xii annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2454466 12 xii 12 12/31/2007 die xxxi mensis xii annoque mmvii 07 vii 2007}
+test clock-2.1633 {conversion of 2008-01-01} {
+ clock format 1199190896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2008 12:34:56 die i mensis i annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2454467 01 i 1 01/01/2008 die i mensis i annoque mmviii 08 viii 2008}
+test clock-2.1634 {conversion of 2008-01-31} {
+ clock format 1201782896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2008 12:34:56 die xxxi mensis i annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2454497 01 i 1 01/31/2008 die xxxi mensis i annoque mmviii 08 viii 2008}
+test clock-2.1635 {conversion of 2008-02-01} {
+ clock format 1201869296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2008 12:34:56 die i mensis ii annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2454498 02 ii 2 02/01/2008 die i mensis ii annoque mmviii 08 viii 2008}
+test clock-2.1636 {conversion of 2008-02-29} {
+ clock format 1204288496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2008 12:34:56 die xxix mensis ii annoque mmviii xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2454526 02 ii 2 02/29/2008 die xxix mensis ii annoque mmviii 08 viii 2008}
+test clock-2.1637 {conversion of 2008-03-01} {
+ clock format 1204374896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2008 12:34:56 die i mensis iii annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2454527 03 iii 3 03/01/2008 die i mensis iii annoque mmviii 08 viii 2008}
+test clock-2.1638 {conversion of 2008-03-31} {
+ clock format 1206966896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2008 12:34:56 die xxxi mensis iii annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2454557 03 iii 3 03/31/2008 die xxxi mensis iii annoque mmviii 08 viii 2008}
+test clock-2.1639 {conversion of 2008-04-01} {
+ clock format 1207053296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2008 12:34:56 die i mensis iv annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2454558 04 iv 4 04/01/2008 die i mensis iv annoque mmviii 08 viii 2008}
+test clock-2.1640 {conversion of 2008-04-30} {
+ clock format 1209558896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2008 12:34:56 die xxx mensis iv annoque mmviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2454587 04 iv 4 04/30/2008 die xxx mensis iv annoque mmviii 08 viii 2008}
+test clock-2.1641 {conversion of 2008-05-01} {
+ clock format 1209645296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2008 12:34:56 die i mensis v annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2454588 05 v 5 05/01/2008 die i mensis v annoque mmviii 08 viii 2008}
+test clock-2.1642 {conversion of 2008-05-31} {
+ clock format 1212237296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2008 12:34:56 die xxxi mensis v annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2454618 05 v 5 05/31/2008 die xxxi mensis v annoque mmviii 08 viii 2008}
+test clock-2.1643 {conversion of 2008-06-01} {
+ clock format 1212323696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2008 12:34:56 die i mensis vi annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2454619 06 vi 6 06/01/2008 die i mensis vi annoque mmviii 08 viii 2008}
+test clock-2.1644 {conversion of 2008-06-30} {
+ clock format 1214829296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2008 12:34:56 die xxx mensis vi annoque mmviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2454648 06 vi 6 06/30/2008 die xxx mensis vi annoque mmviii 08 viii 2008}
+test clock-2.1645 {conversion of 2008-07-01} {
+ clock format 1214915696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2008 12:34:56 die i mensis vii annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2454649 07 vii 7 07/01/2008 die i mensis vii annoque mmviii 08 viii 2008}
+test clock-2.1646 {conversion of 2008-07-31} {
+ clock format 1217507696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2008 12:34:56 die xxxi mensis vii annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2454679 07 vii 7 07/31/2008 die xxxi mensis vii annoque mmviii 08 viii 2008}
+test clock-2.1647 {conversion of 2008-08-01} {
+ clock format 1217594096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2008 12:34:56 die i mensis viii annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2454680 08 viii 8 08/01/2008 die i mensis viii annoque mmviii 08 viii 2008}
+test clock-2.1648 {conversion of 2008-08-31} {
+ clock format 1220186096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2008 12:34:56 die xxxi mensis viii annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2454710 08 viii 8 08/31/2008 die xxxi mensis viii annoque mmviii 08 viii 2008}
+test clock-2.1649 {conversion of 2008-09-01} {
+ clock format 1220272496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2008 12:34:56 die i mensis ix annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2454711 09 ix 9 09/01/2008 die i mensis ix annoque mmviii 08 viii 2008}
+test clock-2.1650 {conversion of 2008-09-30} {
+ clock format 1222778096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2008 12:34:56 die xxx mensis ix annoque mmviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2454740 09 ix 9 09/30/2008 die xxx mensis ix annoque mmviii 08 viii 2008}
+test clock-2.1651 {conversion of 2008-10-01} {
+ clock format 1222864496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2008 12:34:56 die i mensis x annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2454741 10 x 10 10/01/2008 die i mensis x annoque mmviii 08 viii 2008}
+test clock-2.1652 {conversion of 2008-10-31} {
+ clock format 1225456496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2008 12:34:56 die xxxi mensis x annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2454771 10 x 10 10/31/2008 die xxxi mensis x annoque mmviii 08 viii 2008}
+test clock-2.1653 {conversion of 2008-11-01} {
+ clock format 1225542896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2008 12:34:56 die i mensis xi annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2454772 11 xi 11 11/01/2008 die i mensis xi annoque mmviii 08 viii 2008}
+test clock-2.1654 {conversion of 2008-11-30} {
+ clock format 1228048496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2008 12:34:56 die xxx mensis xi annoque mmviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2454801 11 xi 11 11/30/2008 die xxx mensis xi annoque mmviii 08 viii 2008}
+test clock-2.1655 {conversion of 2008-12-01} {
+ clock format 1228134896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2008 12:34:56 die i mensis xii annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2454802 12 xii 12 12/01/2008 die i mensis xii annoque mmviii 08 viii 2008}
+test clock-2.1656 {conversion of 2008-12-31} {
+ clock format 1230726896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2008 12:34:56 die xxxi mensis xii annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2454832 12 xii 12 12/31/2008 die xxxi mensis xii annoque mmviii 08 viii 2008}
+test clock-2.1657 {conversion of 2009-01-01} {
+ clock format 1230813296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2009 12:34:56 die i mensis i annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2454833 01 i 1 01/01/2009 die i mensis i annoque mmix 09 ix 2009}
+test clock-2.1658 {conversion of 2009-01-31} {
+ clock format 1233405296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2009 12:34:56 die xxxi mensis i annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2454863 01 i 1 01/31/2009 die xxxi mensis i annoque mmix 09 ix 2009}
+test clock-2.1659 {conversion of 2009-02-01} {
+ clock format 1233491696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2009 12:34:56 die i mensis ii annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2454864 02 ii 2 02/01/2009 die i mensis ii annoque mmix 09 ix 2009}
+test clock-2.1660 {conversion of 2009-02-28} {
+ clock format 1235824496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2009 12:34:56 die xxviii mensis ii annoque mmix xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2454891 02 ii 2 02/28/2009 die xxviii mensis ii annoque mmix 09 ix 2009}
+test clock-2.1661 {conversion of 2009-03-01} {
+ clock format 1235910896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2009 12:34:56 die i mensis iii annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2454892 03 iii 3 03/01/2009 die i mensis iii annoque mmix 09 ix 2009}
+test clock-2.1662 {conversion of 2009-03-31} {
+ clock format 1238502896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2009 12:34:56 die xxxi mensis iii annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2454922 03 iii 3 03/31/2009 die xxxi mensis iii annoque mmix 09 ix 2009}
+test clock-2.1663 {conversion of 2009-04-01} {
+ clock format 1238589296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2009 12:34:56 die i mensis iv annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2454923 04 iv 4 04/01/2009 die i mensis iv annoque mmix 09 ix 2009}
+test clock-2.1664 {conversion of 2009-04-30} {
+ clock format 1241094896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2009 12:34:56 die xxx mensis iv annoque mmix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2454952 04 iv 4 04/30/2009 die xxx mensis iv annoque mmix 09 ix 2009}
+test clock-2.1665 {conversion of 2009-05-01} {
+ clock format 1241181296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2009 12:34:56 die i mensis v annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2454953 05 v 5 05/01/2009 die i mensis v annoque mmix 09 ix 2009}
+test clock-2.1666 {conversion of 2009-05-31} {
+ clock format 1243773296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2009 12:34:56 die xxxi mensis v annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2454983 05 v 5 05/31/2009 die xxxi mensis v annoque mmix 09 ix 2009}
+test clock-2.1667 {conversion of 2009-06-01} {
+ clock format 1243859696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2009 12:34:56 die i mensis vi annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2454984 06 vi 6 06/01/2009 die i mensis vi annoque mmix 09 ix 2009}
+test clock-2.1668 {conversion of 2009-06-30} {
+ clock format 1246365296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2009 12:34:56 die xxx mensis vi annoque mmix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2455013 06 vi 6 06/30/2009 die xxx mensis vi annoque mmix 09 ix 2009}
+test clock-2.1669 {conversion of 2009-07-01} {
+ clock format 1246451696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2009 12:34:56 die i mensis vii annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2455014 07 vii 7 07/01/2009 die i mensis vii annoque mmix 09 ix 2009}
+test clock-2.1670 {conversion of 2009-07-31} {
+ clock format 1249043696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2009 12:34:56 die xxxi mensis vii annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2455044 07 vii 7 07/31/2009 die xxxi mensis vii annoque mmix 09 ix 2009}
+test clock-2.1671 {conversion of 2009-08-01} {
+ clock format 1249130096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2009 12:34:56 die i mensis viii annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2455045 08 viii 8 08/01/2009 die i mensis viii annoque mmix 09 ix 2009}
+test clock-2.1672 {conversion of 2009-08-31} {
+ clock format 1251722096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2009 12:34:56 die xxxi mensis viii annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2455075 08 viii 8 08/31/2009 die xxxi mensis viii annoque mmix 09 ix 2009}
+test clock-2.1673 {conversion of 2009-09-01} {
+ clock format 1251808496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2009 12:34:56 die i mensis ix annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2455076 09 ix 9 09/01/2009 die i mensis ix annoque mmix 09 ix 2009}
+test clock-2.1674 {conversion of 2009-09-30} {
+ clock format 1254314096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2009 12:34:56 die xxx mensis ix annoque mmix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2455105 09 ix 9 09/30/2009 die xxx mensis ix annoque mmix 09 ix 2009}
+test clock-2.1675 {conversion of 2009-10-01} {
+ clock format 1254400496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2009 12:34:56 die i mensis x annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2455106 10 x 10 10/01/2009 die i mensis x annoque mmix 09 ix 2009}
+test clock-2.1676 {conversion of 2009-10-31} {
+ clock format 1256992496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2009 12:34:56 die xxxi mensis x annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2455136 10 x 10 10/31/2009 die xxxi mensis x annoque mmix 09 ix 2009}
+test clock-2.1677 {conversion of 2009-11-01} {
+ clock format 1257078896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2009 12:34:56 die i mensis xi annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2455137 11 xi 11 11/01/2009 die i mensis xi annoque mmix 09 ix 2009}
+test clock-2.1678 {conversion of 2009-11-30} {
+ clock format 1259584496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2009 12:34:56 die xxx mensis xi annoque mmix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2455166 11 xi 11 11/30/2009 die xxx mensis xi annoque mmix 09 ix 2009}
+test clock-2.1679 {conversion of 2009-12-01} {
+ clock format 1259670896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2009 12:34:56 die i mensis xii annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2455167 12 xii 12 12/01/2009 die i mensis xii annoque mmix 09 ix 2009}
+test clock-2.1680 {conversion of 2009-12-31} {
+ clock format 1262262896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2009 12:34:56 die xxxi mensis xii annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2455197 12 xii 12 12/31/2009 die xxxi mensis xii annoque mmix 09 ix 2009}
+test clock-2.1681 {conversion of 2010-01-01} {
+ clock format 1262349296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2010 12:34:56 die i mensis i annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2455198 01 i 1 01/01/2010 die i mensis i annoque mmx 10 x 2010}
+test clock-2.1682 {conversion of 2010-01-31} {
+ clock format 1264941296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2010 12:34:56 die xxxi mensis i annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2455228 01 i 1 01/31/2010 die xxxi mensis i annoque mmx 10 x 2010}
+test clock-2.1683 {conversion of 2010-02-01} {
+ clock format 1265027696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2010 12:34:56 die i mensis ii annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2455229 02 ii 2 02/01/2010 die i mensis ii annoque mmx 10 x 2010}
+test clock-2.1684 {conversion of 2010-02-28} {
+ clock format 1267360496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2010 12:34:56 die xxviii mensis ii annoque mmx xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2455256 02 ii 2 02/28/2010 die xxviii mensis ii annoque mmx 10 x 2010}
+test clock-2.1685 {conversion of 2010-03-01} {
+ clock format 1267446896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2010 12:34:56 die i mensis iii annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2455257 03 iii 3 03/01/2010 die i mensis iii annoque mmx 10 x 2010}
+test clock-2.1686 {conversion of 2010-03-31} {
+ clock format 1270038896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2010 12:34:56 die xxxi mensis iii annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2455287 03 iii 3 03/31/2010 die xxxi mensis iii annoque mmx 10 x 2010}
+test clock-2.1687 {conversion of 2010-04-01} {
+ clock format 1270125296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2010 12:34:56 die i mensis iv annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2455288 04 iv 4 04/01/2010 die i mensis iv annoque mmx 10 x 2010}
+test clock-2.1688 {conversion of 2010-04-30} {
+ clock format 1272630896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2010 12:34:56 die xxx mensis iv annoque mmx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2455317 04 iv 4 04/30/2010 die xxx mensis iv annoque mmx 10 x 2010}
+test clock-2.1689 {conversion of 2010-05-01} {
+ clock format 1272717296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2010 12:34:56 die i mensis v annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2455318 05 v 5 05/01/2010 die i mensis v annoque mmx 10 x 2010}
+test clock-2.1690 {conversion of 2010-05-31} {
+ clock format 1275309296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2010 12:34:56 die xxxi mensis v annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2455348 05 v 5 05/31/2010 die xxxi mensis v annoque mmx 10 x 2010}
+test clock-2.1691 {conversion of 2010-06-01} {
+ clock format 1275395696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2010 12:34:56 die i mensis vi annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2455349 06 vi 6 06/01/2010 die i mensis vi annoque mmx 10 x 2010}
+test clock-2.1692 {conversion of 2010-06-30} {
+ clock format 1277901296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2010 12:34:56 die xxx mensis vi annoque mmx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2455378 06 vi 6 06/30/2010 die xxx mensis vi annoque mmx 10 x 2010}
+test clock-2.1693 {conversion of 2010-07-01} {
+ clock format 1277987696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2010 12:34:56 die i mensis vii annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2455379 07 vii 7 07/01/2010 die i mensis vii annoque mmx 10 x 2010}
+test clock-2.1694 {conversion of 2010-07-31} {
+ clock format 1280579696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2010 12:34:56 die xxxi mensis vii annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2455409 07 vii 7 07/31/2010 die xxxi mensis vii annoque mmx 10 x 2010}
+test clock-2.1695 {conversion of 2010-08-01} {
+ clock format 1280666096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2010 12:34:56 die i mensis viii annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2455410 08 viii 8 08/01/2010 die i mensis viii annoque mmx 10 x 2010}
+test clock-2.1696 {conversion of 2010-08-31} {
+ clock format 1283258096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2010 12:34:56 die xxxi mensis viii annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2455440 08 viii 8 08/31/2010 die xxxi mensis viii annoque mmx 10 x 2010}
+test clock-2.1697 {conversion of 2010-09-01} {
+ clock format 1283344496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2010 12:34:56 die i mensis ix annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2455441 09 ix 9 09/01/2010 die i mensis ix annoque mmx 10 x 2010}
+test clock-2.1698 {conversion of 2010-09-30} {
+ clock format 1285850096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2010 12:34:56 die xxx mensis ix annoque mmx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2455470 09 ix 9 09/30/2010 die xxx mensis ix annoque mmx 10 x 2010}
+test clock-2.1699 {conversion of 2010-10-01} {
+ clock format 1285936496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2010 12:34:56 die i mensis x annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2455471 10 x 10 10/01/2010 die i mensis x annoque mmx 10 x 2010}
+test clock-2.1700 {conversion of 2010-10-31} {
+ clock format 1288528496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2010 12:34:56 die xxxi mensis x annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2455501 10 x 10 10/31/2010 die xxxi mensis x annoque mmx 10 x 2010}
+test clock-2.1701 {conversion of 2010-11-01} {
+ clock format 1288614896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2010 12:34:56 die i mensis xi annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2455502 11 xi 11 11/01/2010 die i mensis xi annoque mmx 10 x 2010}
+test clock-2.1702 {conversion of 2010-11-30} {
+ clock format 1291120496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2010 12:34:56 die xxx mensis xi annoque mmx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2455531 11 xi 11 11/30/2010 die xxx mensis xi annoque mmx 10 x 2010}
+test clock-2.1703 {conversion of 2010-12-01} {
+ clock format 1291206896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2010 12:34:56 die i mensis xii annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2455532 12 xii 12 12/01/2010 die i mensis xii annoque mmx 10 x 2010}
+test clock-2.1704 {conversion of 2010-12-31} {
+ clock format 1293798896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2010 12:34:56 die xxxi mensis xii annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2455562 12 xii 12 12/31/2010 die xxxi mensis xii annoque mmx 10 x 2010}
+test clock-2.1705 {conversion of 2011-01-01} {
+ clock format 1293885296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2011 12:34:56 die i mensis i annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2455563 01 i 1 01/01/2011 die i mensis i annoque mmxi 11 xi 2011}
+test clock-2.1706 {conversion of 2011-01-31} {
+ clock format 1296477296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2011 12:34:56 die xxxi mensis i annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2455593 01 i 1 01/31/2011 die xxxi mensis i annoque mmxi 11 xi 2011}
+test clock-2.1707 {conversion of 2011-02-01} {
+ clock format 1296563696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2011 12:34:56 die i mensis ii annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2455594 02 ii 2 02/01/2011 die i mensis ii annoque mmxi 11 xi 2011}
+test clock-2.1708 {conversion of 2011-02-28} {
+ clock format 1298896496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2011 12:34:56 die xxviii mensis ii annoque mmxi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2455621 02 ii 2 02/28/2011 die xxviii mensis ii annoque mmxi 11 xi 2011}
+test clock-2.1709 {conversion of 2011-03-01} {
+ clock format 1298982896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2011 12:34:56 die i mensis iii annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2455622 03 iii 3 03/01/2011 die i mensis iii annoque mmxi 11 xi 2011}
+test clock-2.1710 {conversion of 2011-03-31} {
+ clock format 1301574896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2011 12:34:56 die xxxi mensis iii annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2455652 03 iii 3 03/31/2011 die xxxi mensis iii annoque mmxi 11 xi 2011}
+test clock-2.1711 {conversion of 2011-04-01} {
+ clock format 1301661296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2011 12:34:56 die i mensis iv annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2455653 04 iv 4 04/01/2011 die i mensis iv annoque mmxi 11 xi 2011}
+test clock-2.1712 {conversion of 2011-04-30} {
+ clock format 1304166896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2011 12:34:56 die xxx mensis iv annoque mmxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2455682 04 iv 4 04/30/2011 die xxx mensis iv annoque mmxi 11 xi 2011}
+test clock-2.1713 {conversion of 2011-05-01} {
+ clock format 1304253296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2011 12:34:56 die i mensis v annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2455683 05 v 5 05/01/2011 die i mensis v annoque mmxi 11 xi 2011}
+test clock-2.1714 {conversion of 2011-05-31} {
+ clock format 1306845296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2011 12:34:56 die xxxi mensis v annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2455713 05 v 5 05/31/2011 die xxxi mensis v annoque mmxi 11 xi 2011}
+test clock-2.1715 {conversion of 2011-06-01} {
+ clock format 1306931696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2011 12:34:56 die i mensis vi annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2455714 06 vi 6 06/01/2011 die i mensis vi annoque mmxi 11 xi 2011}
+test clock-2.1716 {conversion of 2011-06-30} {
+ clock format 1309437296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2011 12:34:56 die xxx mensis vi annoque mmxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2455743 06 vi 6 06/30/2011 die xxx mensis vi annoque mmxi 11 xi 2011}
+test clock-2.1717 {conversion of 2011-07-01} {
+ clock format 1309523696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2011 12:34:56 die i mensis vii annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2455744 07 vii 7 07/01/2011 die i mensis vii annoque mmxi 11 xi 2011}
+test clock-2.1718 {conversion of 2011-07-31} {
+ clock format 1312115696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2011 12:34:56 die xxxi mensis vii annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2455774 07 vii 7 07/31/2011 die xxxi mensis vii annoque mmxi 11 xi 2011}
+test clock-2.1719 {conversion of 2011-08-01} {
+ clock format 1312202096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2011 12:34:56 die i mensis viii annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2455775 08 viii 8 08/01/2011 die i mensis viii annoque mmxi 11 xi 2011}
+test clock-2.1720 {conversion of 2011-08-31} {
+ clock format 1314794096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2011 12:34:56 die xxxi mensis viii annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2455805 08 viii 8 08/31/2011 die xxxi mensis viii annoque mmxi 11 xi 2011}
+test clock-2.1721 {conversion of 2011-09-01} {
+ clock format 1314880496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2011 12:34:56 die i mensis ix annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2455806 09 ix 9 09/01/2011 die i mensis ix annoque mmxi 11 xi 2011}
+test clock-2.1722 {conversion of 2011-09-30} {
+ clock format 1317386096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2011 12:34:56 die xxx mensis ix annoque mmxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2455835 09 ix 9 09/30/2011 die xxx mensis ix annoque mmxi 11 xi 2011}
+test clock-2.1723 {conversion of 2011-10-01} {
+ clock format 1317472496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2011 12:34:56 die i mensis x annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2455836 10 x 10 10/01/2011 die i mensis x annoque mmxi 11 xi 2011}
+test clock-2.1724 {conversion of 2011-10-31} {
+ clock format 1320064496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2011 12:34:56 die xxxi mensis x annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2455866 10 x 10 10/31/2011 die xxxi mensis x annoque mmxi 11 xi 2011}
+test clock-2.1725 {conversion of 2011-11-01} {
+ clock format 1320150896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2011 12:34:56 die i mensis xi annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2455867 11 xi 11 11/01/2011 die i mensis xi annoque mmxi 11 xi 2011}
+test clock-2.1726 {conversion of 2011-11-30} {
+ clock format 1322656496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2011 12:34:56 die xxx mensis xi annoque mmxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2455896 11 xi 11 11/30/2011 die xxx mensis xi annoque mmxi 11 xi 2011}
+test clock-2.1727 {conversion of 2011-12-01} {
+ clock format 1322742896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2011 12:34:56 die i mensis xii annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2455897 12 xii 12 12/01/2011 die i mensis xii annoque mmxi 11 xi 2011}
+test clock-2.1728 {conversion of 2011-12-31} {
+ clock format 1325334896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2011 12:34:56 die xxxi mensis xii annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2455927 12 xii 12 12/31/2011 die xxxi mensis xii annoque mmxi 11 xi 2011}
+test clock-2.1729 {conversion of 2012-01-01} {
+ clock format 1325421296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2012 12:34:56 die i mensis i annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2455928 01 i 1 01/01/2012 die i mensis i annoque mmxii 12 xii 2012}
+test clock-2.1730 {conversion of 2012-01-31} {
+ clock format 1328013296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2012 12:34:56 die xxxi mensis i annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2455958 01 i 1 01/31/2012 die xxxi mensis i annoque mmxii 12 xii 2012}
+test clock-2.1731 {conversion of 2012-02-01} {
+ clock format 1328099696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2012 12:34:56 die i mensis ii annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2455959 02 ii 2 02/01/2012 die i mensis ii annoque mmxii 12 xii 2012}
+test clock-2.1732 {conversion of 2012-02-29} {
+ clock format 1330518896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2012 12:34:56 die xxix mensis ii annoque mmxii xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2455987 02 ii 2 02/29/2012 die xxix mensis ii annoque mmxii 12 xii 2012}
+test clock-2.1733 {conversion of 2012-03-01} {
+ clock format 1330605296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2012 12:34:56 die i mensis iii annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2455988 03 iii 3 03/01/2012 die i mensis iii annoque mmxii 12 xii 2012}
+test clock-2.1734 {conversion of 2012-03-31} {
+ clock format 1333197296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2012 12:34:56 die xxxi mensis iii annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2456018 03 iii 3 03/31/2012 die xxxi mensis iii annoque mmxii 12 xii 2012}
+test clock-2.1735 {conversion of 2012-04-01} {
+ clock format 1333283696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2012 12:34:56 die i mensis iv annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2456019 04 iv 4 04/01/2012 die i mensis iv annoque mmxii 12 xii 2012}
+test clock-2.1736 {conversion of 2012-04-30} {
+ clock format 1335789296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2012 12:34:56 die xxx mensis iv annoque mmxii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2456048 04 iv 4 04/30/2012 die xxx mensis iv annoque mmxii 12 xii 2012}
+test clock-2.1737 {conversion of 2012-05-01} {
+ clock format 1335875696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2012 12:34:56 die i mensis v annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2456049 05 v 5 05/01/2012 die i mensis v annoque mmxii 12 xii 2012}
+test clock-2.1738 {conversion of 2012-05-31} {
+ clock format 1338467696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2012 12:34:56 die xxxi mensis v annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2456079 05 v 5 05/31/2012 die xxxi mensis v annoque mmxii 12 xii 2012}
+test clock-2.1739 {conversion of 2012-06-01} {
+ clock format 1338554096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2012 12:34:56 die i mensis vi annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2456080 06 vi 6 06/01/2012 die i mensis vi annoque mmxii 12 xii 2012}
+test clock-2.1740 {conversion of 2012-06-30} {
+ clock format 1341059696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2012 12:34:56 die xxx mensis vi annoque mmxii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2456109 06 vi 6 06/30/2012 die xxx mensis vi annoque mmxii 12 xii 2012}
+test clock-2.1741 {conversion of 2012-07-01} {
+ clock format 1341146096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2012 12:34:56 die i mensis vii annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2456110 07 vii 7 07/01/2012 die i mensis vii annoque mmxii 12 xii 2012}
+test clock-2.1742 {conversion of 2012-07-31} {
+ clock format 1343738096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2012 12:34:56 die xxxi mensis vii annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2456140 07 vii 7 07/31/2012 die xxxi mensis vii annoque mmxii 12 xii 2012}
+test clock-2.1743 {conversion of 2012-08-01} {
+ clock format 1343824496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2012 12:34:56 die i mensis viii annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2456141 08 viii 8 08/01/2012 die i mensis viii annoque mmxii 12 xii 2012}
+test clock-2.1744 {conversion of 2012-08-31} {
+ clock format 1346416496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2012 12:34:56 die xxxi mensis viii annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2456171 08 viii 8 08/31/2012 die xxxi mensis viii annoque mmxii 12 xii 2012}
+test clock-2.1745 {conversion of 2012-09-01} {
+ clock format 1346502896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2012 12:34:56 die i mensis ix annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2456172 09 ix 9 09/01/2012 die i mensis ix annoque mmxii 12 xii 2012}
+test clock-2.1746 {conversion of 2012-09-30} {
+ clock format 1349008496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2012 12:34:56 die xxx mensis ix annoque mmxii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2456201 09 ix 9 09/30/2012 die xxx mensis ix annoque mmxii 12 xii 2012}
+test clock-2.1747 {conversion of 2012-10-01} {
+ clock format 1349094896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2012 12:34:56 die i mensis x annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2456202 10 x 10 10/01/2012 die i mensis x annoque mmxii 12 xii 2012}
+test clock-2.1748 {conversion of 2012-10-31} {
+ clock format 1351686896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2012 12:34:56 die xxxi mensis x annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2456232 10 x 10 10/31/2012 die xxxi mensis x annoque mmxii 12 xii 2012}
+test clock-2.1749 {conversion of 2012-11-01} {
+ clock format 1351773296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2012 12:34:56 die i mensis xi annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2456233 11 xi 11 11/01/2012 die i mensis xi annoque mmxii 12 xii 2012}
+test clock-2.1750 {conversion of 2012-11-30} {
+ clock format 1354278896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2012 12:34:56 die xxx mensis xi annoque mmxii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2456262 11 xi 11 11/30/2012 die xxx mensis xi annoque mmxii 12 xii 2012}
+test clock-2.1751 {conversion of 2012-12-01} {
+ clock format 1354365296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2012 12:34:56 die i mensis xii annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2456263 12 xii 12 12/01/2012 die i mensis xii annoque mmxii 12 xii 2012}
+test clock-2.1752 {conversion of 2012-12-31} {
+ clock format 1356957296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2012 12:34:56 die xxxi mensis xii annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2456293 12 xii 12 12/31/2012 die xxxi mensis xii annoque mmxii 12 xii 2012}
+test clock-2.1753 {conversion of 2013-01-01} {
+ clock format 1357043696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2013 12:34:56 die i mensis i annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2456294 01 i 1 01/01/2013 die i mensis i annoque mmxiii 13 xiii 2013}
+test clock-2.1754 {conversion of 2013-01-31} {
+ clock format 1359635696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2013 12:34:56 die xxxi mensis i annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2456324 01 i 1 01/31/2013 die xxxi mensis i annoque mmxiii 13 xiii 2013}
+test clock-2.1755 {conversion of 2013-02-01} {
+ clock format 1359722096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2013 12:34:56 die i mensis ii annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2456325 02 ii 2 02/01/2013 die i mensis ii annoque mmxiii 13 xiii 2013}
+test clock-2.1756 {conversion of 2013-02-28} {
+ clock format 1362054896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2013 12:34:56 die xxviii mensis ii annoque mmxiii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2456352 02 ii 2 02/28/2013 die xxviii mensis ii annoque mmxiii 13 xiii 2013}
+test clock-2.1757 {conversion of 2013-03-01} {
+ clock format 1362141296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2013 12:34:56 die i mensis iii annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2456353 03 iii 3 03/01/2013 die i mensis iii annoque mmxiii 13 xiii 2013}
+test clock-2.1758 {conversion of 2013-03-31} {
+ clock format 1364733296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2013 12:34:56 die xxxi mensis iii annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2456383 03 iii 3 03/31/2013 die xxxi mensis iii annoque mmxiii 13 xiii 2013}
+test clock-2.1759 {conversion of 2013-04-01} {
+ clock format 1364819696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2013 12:34:56 die i mensis iv annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2456384 04 iv 4 04/01/2013 die i mensis iv annoque mmxiii 13 xiii 2013}
+test clock-2.1760 {conversion of 2013-04-30} {
+ clock format 1367325296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2013 12:34:56 die xxx mensis iv annoque mmxiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2456413 04 iv 4 04/30/2013 die xxx mensis iv annoque mmxiii 13 xiii 2013}
+test clock-2.1761 {conversion of 2013-05-01} {
+ clock format 1367411696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2013 12:34:56 die i mensis v annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2456414 05 v 5 05/01/2013 die i mensis v annoque mmxiii 13 xiii 2013}
+test clock-2.1762 {conversion of 2013-05-31} {
+ clock format 1370003696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2013 12:34:56 die xxxi mensis v annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2456444 05 v 5 05/31/2013 die xxxi mensis v annoque mmxiii 13 xiii 2013}
+test clock-2.1763 {conversion of 2013-06-01} {
+ clock format 1370090096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2013 12:34:56 die i mensis vi annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2456445 06 vi 6 06/01/2013 die i mensis vi annoque mmxiii 13 xiii 2013}
+test clock-2.1764 {conversion of 2013-06-30} {
+ clock format 1372595696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2013 12:34:56 die xxx mensis vi annoque mmxiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2456474 06 vi 6 06/30/2013 die xxx mensis vi annoque mmxiii 13 xiii 2013}
+test clock-2.1765 {conversion of 2013-07-01} {
+ clock format 1372682096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2013 12:34:56 die i mensis vii annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2456475 07 vii 7 07/01/2013 die i mensis vii annoque mmxiii 13 xiii 2013}
+test clock-2.1766 {conversion of 2013-07-31} {
+ clock format 1375274096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2013 12:34:56 die xxxi mensis vii annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2456505 07 vii 7 07/31/2013 die xxxi mensis vii annoque mmxiii 13 xiii 2013}
+test clock-2.1767 {conversion of 2013-08-01} {
+ clock format 1375360496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2013 12:34:56 die i mensis viii annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2456506 08 viii 8 08/01/2013 die i mensis viii annoque mmxiii 13 xiii 2013}
+test clock-2.1768 {conversion of 2013-08-31} {
+ clock format 1377952496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2013 12:34:56 die xxxi mensis viii annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2456536 08 viii 8 08/31/2013 die xxxi mensis viii annoque mmxiii 13 xiii 2013}
+test clock-2.1769 {conversion of 2013-09-01} {
+ clock format 1378038896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2013 12:34:56 die i mensis ix annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2456537 09 ix 9 09/01/2013 die i mensis ix annoque mmxiii 13 xiii 2013}
+test clock-2.1770 {conversion of 2013-09-30} {
+ clock format 1380544496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2013 12:34:56 die xxx mensis ix annoque mmxiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2456566 09 ix 9 09/30/2013 die xxx mensis ix annoque mmxiii 13 xiii 2013}
+test clock-2.1771 {conversion of 2013-10-01} {
+ clock format 1380630896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2013 12:34:56 die i mensis x annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2456567 10 x 10 10/01/2013 die i mensis x annoque mmxiii 13 xiii 2013}
+test clock-2.1772 {conversion of 2013-10-31} {
+ clock format 1383222896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2013 12:34:56 die xxxi mensis x annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2456597 10 x 10 10/31/2013 die xxxi mensis x annoque mmxiii 13 xiii 2013}
+test clock-2.1773 {conversion of 2013-11-01} {
+ clock format 1383309296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2013 12:34:56 die i mensis xi annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2456598 11 xi 11 11/01/2013 die i mensis xi annoque mmxiii 13 xiii 2013}
+test clock-2.1774 {conversion of 2013-11-30} {
+ clock format 1385814896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2013 12:34:56 die xxx mensis xi annoque mmxiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2456627 11 xi 11 11/30/2013 die xxx mensis xi annoque mmxiii 13 xiii 2013}
+test clock-2.1775 {conversion of 2013-12-01} {
+ clock format 1385901296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2013 12:34:56 die i mensis xii annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2456628 12 xii 12 12/01/2013 die i mensis xii annoque mmxiii 13 xiii 2013}
+test clock-2.1776 {conversion of 2013-12-31} {
+ clock format 1388493296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2013 12:34:56 die xxxi mensis xii annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2456658 12 xii 12 12/31/2013 die xxxi mensis xii annoque mmxiii 13 xiii 2013}
+test clock-2.1777 {conversion of 2016-01-01} {
+ clock format 1451651696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2016 12:34:56 die i mensis i annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2457389 01 i 1 01/01/2016 die i mensis i annoque mmxvi 16 xvi 2016}
+test clock-2.1778 {conversion of 2016-01-31} {
+ clock format 1454243696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2016 12:34:56 die xxxi mensis i annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2457419 01 i 1 01/31/2016 die xxxi mensis i annoque mmxvi 16 xvi 2016}
+test clock-2.1779 {conversion of 2016-02-01} {
+ clock format 1454330096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2016 12:34:56 die i mensis ii annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2457420 02 ii 2 02/01/2016 die i mensis ii annoque mmxvi 16 xvi 2016}
+test clock-2.1780 {conversion of 2016-02-29} {
+ clock format 1456749296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2016 12:34:56 die xxix mensis ii annoque mmxvi xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2457448 02 ii 2 02/29/2016 die xxix mensis ii annoque mmxvi 16 xvi 2016}
+test clock-2.1781 {conversion of 2016-03-01} {
+ clock format 1456835696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2016 12:34:56 die i mensis iii annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2457449 03 iii 3 03/01/2016 die i mensis iii annoque mmxvi 16 xvi 2016}
+test clock-2.1782 {conversion of 2016-03-31} {
+ clock format 1459427696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2016 12:34:56 die xxxi mensis iii annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2457479 03 iii 3 03/31/2016 die xxxi mensis iii annoque mmxvi 16 xvi 2016}
+test clock-2.1783 {conversion of 2016-04-01} {
+ clock format 1459514096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2016 12:34:56 die i mensis iv annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2457480 04 iv 4 04/01/2016 die i mensis iv annoque mmxvi 16 xvi 2016}
+test clock-2.1784 {conversion of 2016-04-30} {
+ clock format 1462019696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2016 12:34:56 die xxx mensis iv annoque mmxvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2457509 04 iv 4 04/30/2016 die xxx mensis iv annoque mmxvi 16 xvi 2016}
+test clock-2.1785 {conversion of 2016-05-01} {
+ clock format 1462106096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2016 12:34:56 die i mensis v annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2457510 05 v 5 05/01/2016 die i mensis v annoque mmxvi 16 xvi 2016}
+test clock-2.1786 {conversion of 2016-05-31} {
+ clock format 1464698096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2016 12:34:56 die xxxi mensis v annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2457540 05 v 5 05/31/2016 die xxxi mensis v annoque mmxvi 16 xvi 2016}
+test clock-2.1787 {conversion of 2016-06-01} {
+ clock format 1464784496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2016 12:34:56 die i mensis vi annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2457541 06 vi 6 06/01/2016 die i mensis vi annoque mmxvi 16 xvi 2016}
+test clock-2.1788 {conversion of 2016-06-30} {
+ clock format 1467290096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2016 12:34:56 die xxx mensis vi annoque mmxvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2457570 06 vi 6 06/30/2016 die xxx mensis vi annoque mmxvi 16 xvi 2016}
+test clock-2.1789 {conversion of 2016-07-01} {
+ clock format 1467376496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2016 12:34:56 die i mensis vii annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2457571 07 vii 7 07/01/2016 die i mensis vii annoque mmxvi 16 xvi 2016}
+test clock-2.1790 {conversion of 2016-07-31} {
+ clock format 1469968496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2016 12:34:56 die xxxi mensis vii annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2457601 07 vii 7 07/31/2016 die xxxi mensis vii annoque mmxvi 16 xvi 2016}
+test clock-2.1791 {conversion of 2016-08-01} {
+ clock format 1470054896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2016 12:34:56 die i mensis viii annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2457602 08 viii 8 08/01/2016 die i mensis viii annoque mmxvi 16 xvi 2016}
+test clock-2.1792 {conversion of 2016-08-31} {
+ clock format 1472646896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2016 12:34:56 die xxxi mensis viii annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2457632 08 viii 8 08/31/2016 die xxxi mensis viii annoque mmxvi 16 xvi 2016}
+test clock-2.1793 {conversion of 2016-09-01} {
+ clock format 1472733296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2016 12:34:56 die i mensis ix annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2457633 09 ix 9 09/01/2016 die i mensis ix annoque mmxvi 16 xvi 2016}
+test clock-2.1794 {conversion of 2016-09-30} {
+ clock format 1475238896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2016 12:34:56 die xxx mensis ix annoque mmxvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2457662 09 ix 9 09/30/2016 die xxx mensis ix annoque mmxvi 16 xvi 2016}
+test clock-2.1795 {conversion of 2016-10-01} {
+ clock format 1475325296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2016 12:34:56 die i mensis x annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2457663 10 x 10 10/01/2016 die i mensis x annoque mmxvi 16 xvi 2016}
+test clock-2.1796 {conversion of 2016-10-31} {
+ clock format 1477917296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2016 12:34:56 die xxxi mensis x annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2457693 10 x 10 10/31/2016 die xxxi mensis x annoque mmxvi 16 xvi 2016}
+test clock-2.1797 {conversion of 2016-11-01} {
+ clock format 1478003696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2016 12:34:56 die i mensis xi annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2457694 11 xi 11 11/01/2016 die i mensis xi annoque mmxvi 16 xvi 2016}
+test clock-2.1798 {conversion of 2016-11-30} {
+ clock format 1480509296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2016 12:34:56 die xxx mensis xi annoque mmxvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2457723 11 xi 11 11/30/2016 die xxx mensis xi annoque mmxvi 16 xvi 2016}
+test clock-2.1799 {conversion of 2016-12-01} {
+ clock format 1480595696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2016 12:34:56 die i mensis xii annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2457724 12 xii 12 12/01/2016 die i mensis xii annoque mmxvi 16 xvi 2016}
+test clock-2.1800 {conversion of 2016-12-31} {
+ clock format 1483187696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2016 12:34:56 die xxxi mensis xii annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2457754 12 xii 12 12/31/2016 die xxxi mensis xii annoque mmxvi 16 xvi 2016}
+test clock-2.1801 {conversion of 2017-01-01} {
+ clock format 1483274096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2017 12:34:56 die i mensis i annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2457755 01 i 1 01/01/2017 die i mensis i annoque mmxvii 17 xvii 2017}
+test clock-2.1802 {conversion of 2017-01-31} {
+ clock format 1485866096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2017 12:34:56 die xxxi mensis i annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2457785 01 i 1 01/31/2017 die xxxi mensis i annoque mmxvii 17 xvii 2017}
+test clock-2.1803 {conversion of 2017-02-01} {
+ clock format 1485952496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2017 12:34:56 die i mensis ii annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2457786 02 ii 2 02/01/2017 die i mensis ii annoque mmxvii 17 xvii 2017}
+test clock-2.1804 {conversion of 2017-02-28} {
+ clock format 1488285296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2017 12:34:56 die xxviii mensis ii annoque mmxvii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2457813 02 ii 2 02/28/2017 die xxviii mensis ii annoque mmxvii 17 xvii 2017}
+test clock-2.1805 {conversion of 2017-03-01} {
+ clock format 1488371696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2017 12:34:56 die i mensis iii annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2457814 03 iii 3 03/01/2017 die i mensis iii annoque mmxvii 17 xvii 2017}
+test clock-2.1806 {conversion of 2017-03-31} {
+ clock format 1490963696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2017 12:34:56 die xxxi mensis iii annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2457844 03 iii 3 03/31/2017 die xxxi mensis iii annoque mmxvii 17 xvii 2017}
+test clock-2.1807 {conversion of 2017-04-01} {
+ clock format 1491050096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2017 12:34:56 die i mensis iv annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2457845 04 iv 4 04/01/2017 die i mensis iv annoque mmxvii 17 xvii 2017}
+test clock-2.1808 {conversion of 2017-04-30} {
+ clock format 1493555696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2017 12:34:56 die xxx mensis iv annoque mmxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2457874 04 iv 4 04/30/2017 die xxx mensis iv annoque mmxvii 17 xvii 2017}
+test clock-2.1809 {conversion of 2017-05-01} {
+ clock format 1493642096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2017 12:34:56 die i mensis v annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2457875 05 v 5 05/01/2017 die i mensis v annoque mmxvii 17 xvii 2017}
+test clock-2.1810 {conversion of 2017-05-31} {
+ clock format 1496234096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2017 12:34:56 die xxxi mensis v annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2457905 05 v 5 05/31/2017 die xxxi mensis v annoque mmxvii 17 xvii 2017}
+test clock-2.1811 {conversion of 2017-06-01} {
+ clock format 1496320496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2017 12:34:56 die i mensis vi annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2457906 06 vi 6 06/01/2017 die i mensis vi annoque mmxvii 17 xvii 2017}
+test clock-2.1812 {conversion of 2017-06-30} {
+ clock format 1498826096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2017 12:34:56 die xxx mensis vi annoque mmxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2457935 06 vi 6 06/30/2017 die xxx mensis vi annoque mmxvii 17 xvii 2017}
+test clock-2.1813 {conversion of 2017-07-01} {
+ clock format 1498912496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2017 12:34:56 die i mensis vii annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2457936 07 vii 7 07/01/2017 die i mensis vii annoque mmxvii 17 xvii 2017}
+test clock-2.1814 {conversion of 2017-07-31} {
+ clock format 1501504496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2017 12:34:56 die xxxi mensis vii annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2457966 07 vii 7 07/31/2017 die xxxi mensis vii annoque mmxvii 17 xvii 2017}
+test clock-2.1815 {conversion of 2017-08-01} {
+ clock format 1501590896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2017 12:34:56 die i mensis viii annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2457967 08 viii 8 08/01/2017 die i mensis viii annoque mmxvii 17 xvii 2017}
+test clock-2.1816 {conversion of 2017-08-31} {
+ clock format 1504182896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2017 12:34:56 die xxxi mensis viii annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2457997 08 viii 8 08/31/2017 die xxxi mensis viii annoque mmxvii 17 xvii 2017}
+test clock-2.1817 {conversion of 2017-09-01} {
+ clock format 1504269296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2017 12:34:56 die i mensis ix annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2457998 09 ix 9 09/01/2017 die i mensis ix annoque mmxvii 17 xvii 2017}
+test clock-2.1818 {conversion of 2017-09-30} {
+ clock format 1506774896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2017 12:34:56 die xxx mensis ix annoque mmxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2458027 09 ix 9 09/30/2017 die xxx mensis ix annoque mmxvii 17 xvii 2017}
+test clock-2.1819 {conversion of 2017-10-01} {
+ clock format 1506861296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2017 12:34:56 die i mensis x annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2458028 10 x 10 10/01/2017 die i mensis x annoque mmxvii 17 xvii 2017}
+test clock-2.1820 {conversion of 2017-10-31} {
+ clock format 1509453296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2017 12:34:56 die xxxi mensis x annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2458058 10 x 10 10/31/2017 die xxxi mensis x annoque mmxvii 17 xvii 2017}
+test clock-2.1821 {conversion of 2017-11-01} {
+ clock format 1509539696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2017 12:34:56 die i mensis xi annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2458059 11 xi 11 11/01/2017 die i mensis xi annoque mmxvii 17 xvii 2017}
+test clock-2.1822 {conversion of 2017-11-30} {
+ clock format 1512045296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2017 12:34:56 die xxx mensis xi annoque mmxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2458088 11 xi 11 11/30/2017 die xxx mensis xi annoque mmxvii 17 xvii 2017}
+test clock-2.1823 {conversion of 2017-12-01} {
+ clock format 1512131696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2017 12:34:56 die i mensis xii annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2458089 12 xii 12 12/01/2017 die i mensis xii annoque mmxvii 17 xvii 2017}
+test clock-2.1824 {conversion of 2017-12-31} {
+ clock format 1514723696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2017 12:34:56 die xxxi mensis xii annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2458119 12 xii 12 12/31/2017 die xxxi mensis xii annoque mmxvii 17 xvii 2017}
+test clock-2.1825 {conversion of 2020-01-01} {
+ clock format 1577882096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2020 12:34:56 die i mensis i annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2458850 01 i 1 01/01/2020 die i mensis i annoque mmxx 20 xx 2020}
+test clock-2.1826 {conversion of 2020-01-31} {
+ clock format 1580474096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2020 12:34:56 die xxxi mensis i annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2458880 01 i 1 01/31/2020 die xxxi mensis i annoque mmxx 20 xx 2020}
+test clock-2.1827 {conversion of 2020-02-01} {
+ clock format 1580560496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2020 12:34:56 die i mensis ii annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2458881 02 ii 2 02/01/2020 die i mensis ii annoque mmxx 20 xx 2020}
+test clock-2.1828 {conversion of 2020-02-29} {
+ clock format 1582979696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2020 12:34:56 die xxix mensis ii annoque mmxx xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2458909 02 ii 2 02/29/2020 die xxix mensis ii annoque mmxx 20 xx 2020}
+test clock-2.1829 {conversion of 2020-03-01} {
+ clock format 1583066096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2020 12:34:56 die i mensis iii annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2458910 03 iii 3 03/01/2020 die i mensis iii annoque mmxx 20 xx 2020}
+test clock-2.1830 {conversion of 2020-03-31} {
+ clock format 1585658096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2020 12:34:56 die xxxi mensis iii annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2458940 03 iii 3 03/31/2020 die xxxi mensis iii annoque mmxx 20 xx 2020}
+test clock-2.1831 {conversion of 2020-04-01} {
+ clock format 1585744496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2020 12:34:56 die i mensis iv annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2458941 04 iv 4 04/01/2020 die i mensis iv annoque mmxx 20 xx 2020}
+test clock-2.1832 {conversion of 2020-04-30} {
+ clock format 1588250096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2020 12:34:56 die xxx mensis iv annoque mmxx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2458970 04 iv 4 04/30/2020 die xxx mensis iv annoque mmxx 20 xx 2020}
+test clock-2.1833 {conversion of 2020-05-01} {
+ clock format 1588336496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2020 12:34:56 die i mensis v annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2458971 05 v 5 05/01/2020 die i mensis v annoque mmxx 20 xx 2020}
+test clock-2.1834 {conversion of 2020-05-31} {
+ clock format 1590928496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2020 12:34:56 die xxxi mensis v annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2459001 05 v 5 05/31/2020 die xxxi mensis v annoque mmxx 20 xx 2020}
+test clock-2.1835 {conversion of 2020-06-01} {
+ clock format 1591014896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2020 12:34:56 die i mensis vi annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2459002 06 vi 6 06/01/2020 die i mensis vi annoque mmxx 20 xx 2020}
+test clock-2.1836 {conversion of 2020-06-30} {
+ clock format 1593520496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2020 12:34:56 die xxx mensis vi annoque mmxx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2459031 06 vi 6 06/30/2020 die xxx mensis vi annoque mmxx 20 xx 2020}
+test clock-2.1837 {conversion of 2020-07-01} {
+ clock format 1593606896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2020 12:34:56 die i mensis vii annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2459032 07 vii 7 07/01/2020 die i mensis vii annoque mmxx 20 xx 2020}
+test clock-2.1838 {conversion of 2020-07-31} {
+ clock format 1596198896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2020 12:34:56 die xxxi mensis vii annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2459062 07 vii 7 07/31/2020 die xxxi mensis vii annoque mmxx 20 xx 2020}
+test clock-2.1839 {conversion of 2020-08-01} {
+ clock format 1596285296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2020 12:34:56 die i mensis viii annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2459063 08 viii 8 08/01/2020 die i mensis viii annoque mmxx 20 xx 2020}
+test clock-2.1840 {conversion of 2020-08-31} {
+ clock format 1598877296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2020 12:34:56 die xxxi mensis viii annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2459093 08 viii 8 08/31/2020 die xxxi mensis viii annoque mmxx 20 xx 2020}
+test clock-2.1841 {conversion of 2020-09-01} {
+ clock format 1598963696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2020 12:34:56 die i mensis ix annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2459094 09 ix 9 09/01/2020 die i mensis ix annoque mmxx 20 xx 2020}
+test clock-2.1842 {conversion of 2020-09-30} {
+ clock format 1601469296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2020 12:34:56 die xxx mensis ix annoque mmxx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2459123 09 ix 9 09/30/2020 die xxx mensis ix annoque mmxx 20 xx 2020}
+test clock-2.1843 {conversion of 2020-10-01} {
+ clock format 1601555696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2020 12:34:56 die i mensis x annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2459124 10 x 10 10/01/2020 die i mensis x annoque mmxx 20 xx 2020}
+test clock-2.1844 {conversion of 2020-10-31} {
+ clock format 1604147696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2020 12:34:56 die xxxi mensis x annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2459154 10 x 10 10/31/2020 die xxxi mensis x annoque mmxx 20 xx 2020}
+test clock-2.1845 {conversion of 2020-11-01} {
+ clock format 1604234096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2020 12:34:56 die i mensis xi annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2459155 11 xi 11 11/01/2020 die i mensis xi annoque mmxx 20 xx 2020}
+test clock-2.1846 {conversion of 2020-11-30} {
+ clock format 1606739696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2020 12:34:56 die xxx mensis xi annoque mmxx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2459184 11 xi 11 11/30/2020 die xxx mensis xi annoque mmxx 20 xx 2020}
+test clock-2.1847 {conversion of 2020-12-01} {
+ clock format 1606826096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2020 12:34:56 die i mensis xii annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2459185 12 xii 12 12/01/2020 die i mensis xii annoque mmxx 20 xx 2020}
+test clock-2.1848 {conversion of 2020-12-31} {
+ clock format 1609418096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2020 12:34:56 die xxxi mensis xii annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2459215 12 xii 12 12/31/2020 die xxxi mensis xii annoque mmxx 20 xx 2020}
+test clock-2.1849 {conversion of 2021-01-01} {
+ clock format 1609504496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2021 12:34:56 die i mensis i annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2459216 01 i 1 01/01/2021 die i mensis i annoque mmxxi 21 xxi 2021}
+test clock-2.1850 {conversion of 2021-01-31} {
+ clock format 1612096496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2021 12:34:56 die xxxi mensis i annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2459246 01 i 1 01/31/2021 die xxxi mensis i annoque mmxxi 21 xxi 2021}
+test clock-2.1851 {conversion of 2021-02-01} {
+ clock format 1612182896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2021 12:34:56 die i mensis ii annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2459247 02 ii 2 02/01/2021 die i mensis ii annoque mmxxi 21 xxi 2021}
+test clock-2.1852 {conversion of 2021-02-28} {
+ clock format 1614515696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2021 12:34:56 die xxviii mensis ii annoque mmxxi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2459274 02 ii 2 02/28/2021 die xxviii mensis ii annoque mmxxi 21 xxi 2021}
+test clock-2.1853 {conversion of 2021-03-01} {
+ clock format 1614602096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2021 12:34:56 die i mensis iii annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2459275 03 iii 3 03/01/2021 die i mensis iii annoque mmxxi 21 xxi 2021}
+test clock-2.1854 {conversion of 2021-03-31} {
+ clock format 1617194096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2021 12:34:56 die xxxi mensis iii annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2459305 03 iii 3 03/31/2021 die xxxi mensis iii annoque mmxxi 21 xxi 2021}
+test clock-2.1855 {conversion of 2021-04-01} {
+ clock format 1617280496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2021 12:34:56 die i mensis iv annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2459306 04 iv 4 04/01/2021 die i mensis iv annoque mmxxi 21 xxi 2021}
+test clock-2.1856 {conversion of 2021-04-30} {
+ clock format 1619786096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2021 12:34:56 die xxx mensis iv annoque mmxxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2459335 04 iv 4 04/30/2021 die xxx mensis iv annoque mmxxi 21 xxi 2021}
+test clock-2.1857 {conversion of 2021-05-01} {
+ clock format 1619872496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2021 12:34:56 die i mensis v annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2459336 05 v 5 05/01/2021 die i mensis v annoque mmxxi 21 xxi 2021}
+test clock-2.1858 {conversion of 2021-05-31} {
+ clock format 1622464496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2021 12:34:56 die xxxi mensis v annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2459366 05 v 5 05/31/2021 die xxxi mensis v annoque mmxxi 21 xxi 2021}
+test clock-2.1859 {conversion of 2021-06-01} {
+ clock format 1622550896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2021 12:34:56 die i mensis vi annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2459367 06 vi 6 06/01/2021 die i mensis vi annoque mmxxi 21 xxi 2021}
+test clock-2.1860 {conversion of 2021-06-30} {
+ clock format 1625056496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2021 12:34:56 die xxx mensis vi annoque mmxxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2459396 06 vi 6 06/30/2021 die xxx mensis vi annoque mmxxi 21 xxi 2021}
+test clock-2.1861 {conversion of 2021-07-01} {
+ clock format 1625142896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2021 12:34:56 die i mensis vii annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2459397 07 vii 7 07/01/2021 die i mensis vii annoque mmxxi 21 xxi 2021}
+test clock-2.1862 {conversion of 2021-07-31} {
+ clock format 1627734896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2021 12:34:56 die xxxi mensis vii annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2459427 07 vii 7 07/31/2021 die xxxi mensis vii annoque mmxxi 21 xxi 2021}
+test clock-2.1863 {conversion of 2021-08-01} {
+ clock format 1627821296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2021 12:34:56 die i mensis viii annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2459428 08 viii 8 08/01/2021 die i mensis viii annoque mmxxi 21 xxi 2021}
+test clock-2.1864 {conversion of 2021-08-31} {
+ clock format 1630413296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2021 12:34:56 die xxxi mensis viii annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2459458 08 viii 8 08/31/2021 die xxxi mensis viii annoque mmxxi 21 xxi 2021}
+test clock-2.1865 {conversion of 2021-09-01} {
+ clock format 1630499696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2021 12:34:56 die i mensis ix annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2459459 09 ix 9 09/01/2021 die i mensis ix annoque mmxxi 21 xxi 2021}
+test clock-2.1866 {conversion of 2021-09-30} {
+ clock format 1633005296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2021 12:34:56 die xxx mensis ix annoque mmxxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2459488 09 ix 9 09/30/2021 die xxx mensis ix annoque mmxxi 21 xxi 2021}
+test clock-2.1867 {conversion of 2021-10-01} {
+ clock format 1633091696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2021 12:34:56 die i mensis x annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2459489 10 x 10 10/01/2021 die i mensis x annoque mmxxi 21 xxi 2021}
+test clock-2.1868 {conversion of 2021-10-31} {
+ clock format 1635683696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2021 12:34:56 die xxxi mensis x annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2459519 10 x 10 10/31/2021 die xxxi mensis x annoque mmxxi 21 xxi 2021}
+test clock-2.1869 {conversion of 2021-11-01} {
+ clock format 1635770096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2021 12:34:56 die i mensis xi annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2459520 11 xi 11 11/01/2021 die i mensis xi annoque mmxxi 21 xxi 2021}
+test clock-2.1870 {conversion of 2021-11-30} {
+ clock format 1638275696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2021 12:34:56 die xxx mensis xi annoque mmxxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2459549 11 xi 11 11/30/2021 die xxx mensis xi annoque mmxxi 21 xxi 2021}
+test clock-2.1871 {conversion of 2021-12-01} {
+ clock format 1638362096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2021 12:34:56 die i mensis xii annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2459550 12 xii 12 12/01/2021 die i mensis xii annoque mmxxi 21 xxi 2021}
+test clock-2.1872 {conversion of 2021-12-31} {
+ clock format 1640954096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2021 12:34:56 die xxxi mensis xii annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2459580 12 xii 12 12/31/2021 die xxxi mensis xii annoque mmxxi 21 xxi 2021}
+test clock-2.1873 {conversion of 2024-01-01} {
+ clock format 1704112496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2024 12:34:56 die i mensis i annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2460311 01 i 1 01/01/2024 die i mensis i annoque mmxxiv 24 xxiv 2024}
+test clock-2.1874 {conversion of 2024-01-31} {
+ clock format 1706704496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2024 12:34:56 die xxxi mensis i annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2460341 01 i 1 01/31/2024 die xxxi mensis i annoque mmxxiv 24 xxiv 2024}
+test clock-2.1875 {conversion of 2024-02-01} {
+ clock format 1706790896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2024 12:34:56 die i mensis ii annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2460342 02 ii 2 02/01/2024 die i mensis ii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1876 {conversion of 2024-02-29} {
+ clock format 1709210096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2024 12:34:56 die xxix mensis ii annoque mmxxiv xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2460370 02 ii 2 02/29/2024 die xxix mensis ii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1877 {conversion of 2024-03-01} {
+ clock format 1709296496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2024 12:34:56 die i mensis iii annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2460371 03 iii 3 03/01/2024 die i mensis iii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1878 {conversion of 2024-03-31} {
+ clock format 1711888496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2024 12:34:56 die xxxi mensis iii annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2460401 03 iii 3 03/31/2024 die xxxi mensis iii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1879 {conversion of 2024-04-01} {
+ clock format 1711974896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2024 12:34:56 die i mensis iv annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2460402 04 iv 4 04/01/2024 die i mensis iv annoque mmxxiv 24 xxiv 2024}
+test clock-2.1880 {conversion of 2024-04-30} {
+ clock format 1714480496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2024 12:34:56 die xxx mensis iv annoque mmxxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2460431 04 iv 4 04/30/2024 die xxx mensis iv annoque mmxxiv 24 xxiv 2024}
+test clock-2.1881 {conversion of 2024-05-01} {
+ clock format 1714566896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2024 12:34:56 die i mensis v annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2460432 05 v 5 05/01/2024 die i mensis v annoque mmxxiv 24 xxiv 2024}
+test clock-2.1882 {conversion of 2024-05-31} {
+ clock format 1717158896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2024 12:34:56 die xxxi mensis v annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2460462 05 v 5 05/31/2024 die xxxi mensis v annoque mmxxiv 24 xxiv 2024}
+test clock-2.1883 {conversion of 2024-06-01} {
+ clock format 1717245296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2024 12:34:56 die i mensis vi annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2460463 06 vi 6 06/01/2024 die i mensis vi annoque mmxxiv 24 xxiv 2024}
+test clock-2.1884 {conversion of 2024-06-30} {
+ clock format 1719750896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2024 12:34:56 die xxx mensis vi annoque mmxxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2460492 06 vi 6 06/30/2024 die xxx mensis vi annoque mmxxiv 24 xxiv 2024}
+test clock-2.1885 {conversion of 2024-07-01} {
+ clock format 1719837296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2024 12:34:56 die i mensis vii annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2460493 07 vii 7 07/01/2024 die i mensis vii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1886 {conversion of 2024-07-31} {
+ clock format 1722429296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2024 12:34:56 die xxxi mensis vii annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2460523 07 vii 7 07/31/2024 die xxxi mensis vii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1887 {conversion of 2024-08-01} {
+ clock format 1722515696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2024 12:34:56 die i mensis viii annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2460524 08 viii 8 08/01/2024 die i mensis viii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1888 {conversion of 2024-08-31} {
+ clock format 1725107696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2024 12:34:56 die xxxi mensis viii annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2460554 08 viii 8 08/31/2024 die xxxi mensis viii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1889 {conversion of 2024-09-01} {
+ clock format 1725194096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2024 12:34:56 die i mensis ix annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2460555 09 ix 9 09/01/2024 die i mensis ix annoque mmxxiv 24 xxiv 2024}
+test clock-2.1890 {conversion of 2024-09-30} {
+ clock format 1727699696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2024 12:34:56 die xxx mensis ix annoque mmxxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2460584 09 ix 9 09/30/2024 die xxx mensis ix annoque mmxxiv 24 xxiv 2024}
+test clock-2.1891 {conversion of 2024-10-01} {
+ clock format 1727786096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2024 12:34:56 die i mensis x annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2460585 10 x 10 10/01/2024 die i mensis x annoque mmxxiv 24 xxiv 2024}
+test clock-2.1892 {conversion of 2024-10-31} {
+ clock format 1730378096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2024 12:34:56 die xxxi mensis x annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2460615 10 x 10 10/31/2024 die xxxi mensis x annoque mmxxiv 24 xxiv 2024}
+test clock-2.1893 {conversion of 2024-11-01} {
+ clock format 1730464496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2024 12:34:56 die i mensis xi annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2460616 11 xi 11 11/01/2024 die i mensis xi annoque mmxxiv 24 xxiv 2024}
+test clock-2.1894 {conversion of 2024-11-30} {
+ clock format 1732970096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2024 12:34:56 die xxx mensis xi annoque mmxxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2460645 11 xi 11 11/30/2024 die xxx mensis xi annoque mmxxiv 24 xxiv 2024}
+test clock-2.1895 {conversion of 2024-12-01} {
+ clock format 1733056496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2024 12:34:56 die i mensis xii annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2460646 12 xii 12 12/01/2024 die i mensis xii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1896 {conversion of 2024-12-31} {
+ clock format 1735648496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2024 12:34:56 die xxxi mensis xii annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2460676 12 xii 12 12/31/2024 die xxxi mensis xii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1897 {conversion of 2025-01-01} {
+ clock format 1735734896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2025 12:34:56 die i mensis i annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2460677 01 i 1 01/01/2025 die i mensis i annoque mmxxv 25 xxv 2025}
+test clock-2.1898 {conversion of 2025-01-31} {
+ clock format 1738326896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2025 12:34:56 die xxxi mensis i annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2460707 01 i 1 01/31/2025 die xxxi mensis i annoque mmxxv 25 xxv 2025}
+test clock-2.1899 {conversion of 2025-02-01} {
+ clock format 1738413296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2025 12:34:56 die i mensis ii annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2460708 02 ii 2 02/01/2025 die i mensis ii annoque mmxxv 25 xxv 2025}
+test clock-2.1900 {conversion of 2025-02-28} {
+ clock format 1740746096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2025 12:34:56 die xxviii mensis ii annoque mmxxv xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2460735 02 ii 2 02/28/2025 die xxviii mensis ii annoque mmxxv 25 xxv 2025}
+test clock-2.1901 {conversion of 2025-03-01} {
+ clock format 1740832496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2025 12:34:56 die i mensis iii annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2460736 03 iii 3 03/01/2025 die i mensis iii annoque mmxxv 25 xxv 2025}
+test clock-2.1902 {conversion of 2025-03-31} {
+ clock format 1743424496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2025 12:34:56 die xxxi mensis iii annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2460766 03 iii 3 03/31/2025 die xxxi mensis iii annoque mmxxv 25 xxv 2025}
+test clock-2.1903 {conversion of 2025-04-01} {
+ clock format 1743510896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2025 12:34:56 die i mensis iv annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2460767 04 iv 4 04/01/2025 die i mensis iv annoque mmxxv 25 xxv 2025}
+test clock-2.1904 {conversion of 2025-04-30} {
+ clock format 1746016496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2025 12:34:56 die xxx mensis iv annoque mmxxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2460796 04 iv 4 04/30/2025 die xxx mensis iv annoque mmxxv 25 xxv 2025}
+test clock-2.1905 {conversion of 2025-05-01} {
+ clock format 1746102896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2025 12:34:56 die i mensis v annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2460797 05 v 5 05/01/2025 die i mensis v annoque mmxxv 25 xxv 2025}
+test clock-2.1906 {conversion of 2025-05-31} {
+ clock format 1748694896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2025 12:34:56 die xxxi mensis v annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2460827 05 v 5 05/31/2025 die xxxi mensis v annoque mmxxv 25 xxv 2025}
+test clock-2.1907 {conversion of 2025-06-01} {
+ clock format 1748781296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2025 12:34:56 die i mensis vi annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2460828 06 vi 6 06/01/2025 die i mensis vi annoque mmxxv 25 xxv 2025}
+test clock-2.1908 {conversion of 2025-06-30} {
+ clock format 1751286896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2025 12:34:56 die xxx mensis vi annoque mmxxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2460857 06 vi 6 06/30/2025 die xxx mensis vi annoque mmxxv 25 xxv 2025}
+test clock-2.1909 {conversion of 2025-07-01} {
+ clock format 1751373296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2025 12:34:56 die i mensis vii annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2460858 07 vii 7 07/01/2025 die i mensis vii annoque mmxxv 25 xxv 2025}
+test clock-2.1910 {conversion of 2025-07-31} {
+ clock format 1753965296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2025 12:34:56 die xxxi mensis vii annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2460888 07 vii 7 07/31/2025 die xxxi mensis vii annoque mmxxv 25 xxv 2025}
+test clock-2.1911 {conversion of 2025-08-01} {
+ clock format 1754051696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2025 12:34:56 die i mensis viii annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2460889 08 viii 8 08/01/2025 die i mensis viii annoque mmxxv 25 xxv 2025}
+test clock-2.1912 {conversion of 2025-08-31} {
+ clock format 1756643696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2025 12:34:56 die xxxi mensis viii annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2460919 08 viii 8 08/31/2025 die xxxi mensis viii annoque mmxxv 25 xxv 2025}
+test clock-2.1913 {conversion of 2025-09-01} {
+ clock format 1756730096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2025 12:34:56 die i mensis ix annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2460920 09 ix 9 09/01/2025 die i mensis ix annoque mmxxv 25 xxv 2025}
+test clock-2.1914 {conversion of 2025-09-30} {
+ clock format 1759235696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2025 12:34:56 die xxx mensis ix annoque mmxxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2460949 09 ix 9 09/30/2025 die xxx mensis ix annoque mmxxv 25 xxv 2025}
+test clock-2.1915 {conversion of 2025-10-01} {
+ clock format 1759322096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2025 12:34:56 die i mensis x annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2460950 10 x 10 10/01/2025 die i mensis x annoque mmxxv 25 xxv 2025}
+test clock-2.1916 {conversion of 2025-10-31} {
+ clock format 1761914096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2025 12:34:56 die xxxi mensis x annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2460980 10 x 10 10/31/2025 die xxxi mensis x annoque mmxxv 25 xxv 2025}
+test clock-2.1917 {conversion of 2025-11-01} {
+ clock format 1762000496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2025 12:34:56 die i mensis xi annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2460981 11 xi 11 11/01/2025 die i mensis xi annoque mmxxv 25 xxv 2025}
+test clock-2.1918 {conversion of 2025-11-30} {
+ clock format 1764506096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2025 12:34:56 die xxx mensis xi annoque mmxxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2461010 11 xi 11 11/30/2025 die xxx mensis xi annoque mmxxv 25 xxv 2025}
+test clock-2.1919 {conversion of 2025-12-01} {
+ clock format 1764592496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2025 12:34:56 die i mensis xii annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2461011 12 xii 12 12/01/2025 die i mensis xii annoque mmxxv 25 xxv 2025}
+test clock-2.1920 {conversion of 2025-12-31} {
+ clock format 1767184496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2025 12:34:56 die xxxi mensis xii annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2461041 12 xii 12 12/31/2025 die xxxi mensis xii annoque mmxxv 25 xxv 2025}
+test clock-2.1921 {conversion of 2037-01-01} {
+ clock format 2114426096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2037 12:34:56 die i mensis i annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2465060 01 i 1 01/01/2037 die i mensis i annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1922 {conversion of 2037-01-31} {
+ clock format 2117018096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2037 12:34:56 die xxxi mensis i annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2465090 01 i 1 01/31/2037 die xxxi mensis i annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1923 {conversion of 2037-02-01} {
+ clock format 2117104496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2037 12:34:56 die i mensis ii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2465091 02 ii 2 02/01/2037 die i mensis ii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1924 {conversion of 2037-02-28} {
+ clock format 2119437296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2037 12:34:56 die xxviii mensis ii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2465118 02 ii 2 02/28/2037 die xxviii mensis ii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1925 {conversion of 2037-03-01} {
+ clock format 2119523696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2037 12:34:56 die i mensis iii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2465119 03 iii 3 03/01/2037 die i mensis iii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1926 {conversion of 2037-03-31} {
+ clock format 2122115696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2037 12:34:56 die xxxi mensis iii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2465149 03 iii 3 03/31/2037 die xxxi mensis iii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1927 {conversion of 2037-04-01} {
+ clock format 2122202096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2037 12:34:56 die i mensis iv annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2465150 04 iv 4 04/01/2037 die i mensis iv annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1928 {conversion of 2037-04-30} {
+ clock format 2124707696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2037 12:34:56 die xxx mensis iv annoque mmxxxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2465179 04 iv 4 04/30/2037 die xxx mensis iv annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1929 {conversion of 2037-05-01} {
+ clock format 2124794096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2037 12:34:56 die i mensis v annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2465180 05 v 5 05/01/2037 die i mensis v annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1930 {conversion of 2037-05-31} {
+ clock format 2127386096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2037 12:34:56 die xxxi mensis v annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2465210 05 v 5 05/31/2037 die xxxi mensis v annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1931 {conversion of 2037-06-01} {
+ clock format 2127472496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2037 12:34:56 die i mensis vi annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2465211 06 vi 6 06/01/2037 die i mensis vi annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1932 {conversion of 2037-06-30} {
+ clock format 2129978096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2037 12:34:56 die xxx mensis vi annoque mmxxxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2465240 06 vi 6 06/30/2037 die xxx mensis vi annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1933 {conversion of 2037-07-01} {
+ clock format 2130064496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2037 12:34:56 die i mensis vii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2465241 07 vii 7 07/01/2037 die i mensis vii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1934 {conversion of 2037-07-31} {
+ clock format 2132656496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2037 12:34:56 die xxxi mensis vii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2465271 07 vii 7 07/31/2037 die xxxi mensis vii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1935 {conversion of 2037-08-01} {
+ clock format 2132742896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2037 12:34:56 die i mensis viii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2465272 08 viii 8 08/01/2037 die i mensis viii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1936 {conversion of 2037-08-31} {
+ clock format 2135334896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2037 12:34:56 die xxxi mensis viii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2465302 08 viii 8 08/31/2037 die xxxi mensis viii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1937 {conversion of 2037-09-01} {
+ clock format 2135421296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2037 12:34:56 die i mensis ix annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2465303 09 ix 9 09/01/2037 die i mensis ix annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1938 {conversion of 2037-09-30} {
+ clock format 2137926896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2037 12:34:56 die xxx mensis ix annoque mmxxxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2465332 09 ix 9 09/30/2037 die xxx mensis ix annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1939 {conversion of 2037-10-01} {
+ clock format 2138013296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2037 12:34:56 die i mensis x annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2465333 10 x 10 10/01/2037 die i mensis x annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1940 {conversion of 2037-10-31} {
+ clock format 2140605296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2037 12:34:56 die xxxi mensis x annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2465363 10 x 10 10/31/2037 die xxxi mensis x annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1941 {conversion of 2037-11-01} {
+ clock format 2140691696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2037 12:34:56 die i mensis xi annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2465364 11 xi 11 11/01/2037 die i mensis xi annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1942 {conversion of 2037-11-30} {
+ clock format 2143197296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2037 12:34:56 die xxx mensis xi annoque mmxxxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2465393 11 xi 11 11/30/2037 die xxx mensis xi annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1943 {conversion of 2037-12-01} {
+ clock format 2143283696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2037 12:34:56 die i mensis xii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2465394 12 xii 12 12/01/2037 die i mensis xii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1944 {conversion of 2037-12-31} {
+ clock format 2145875696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2037 12:34:56 die xxxi mensis xii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2465424 12 xii 12 12/31/2037 die xxxi mensis xii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1945 {conversion of 2038-01-01} {
+ clock format 2145962096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2038 12:34:56 die i mensis i annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2465425 01 i 1 01/01/2038 die i mensis i annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1946 {conversion of 2038-01-31} {
+ clock format 2148554096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2038 12:34:56 die xxxi mensis i annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2465455 01 i 1 01/31/2038 die xxxi mensis i annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1947 {conversion of 2038-02-01} {
+ clock format 2148640496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2038 12:34:56 die i mensis ii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2465456 02 ii 2 02/01/2038 die i mensis ii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1948 {conversion of 2038-02-28} {
+ clock format 2150973296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2038 12:34:56 die xxviii mensis ii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2465483 02 ii 2 02/28/2038 die xxviii mensis ii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1949 {conversion of 2038-03-01} {
+ clock format 2151059696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2038 12:34:56 die i mensis iii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2465484 03 iii 3 03/01/2038 die i mensis iii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1950 {conversion of 2038-03-31} {
+ clock format 2153651696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2038 12:34:56 die xxxi mensis iii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2465514 03 iii 3 03/31/2038 die xxxi mensis iii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1951 {conversion of 2038-04-01} {
+ clock format 2153738096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2038 12:34:56 die i mensis iv annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2465515 04 iv 4 04/01/2038 die i mensis iv annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1952 {conversion of 2038-04-30} {
+ clock format 2156243696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2038 12:34:56 die xxx mensis iv annoque mmxxxviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2465544 04 iv 4 04/30/2038 die xxx mensis iv annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1953 {conversion of 2038-05-01} {
+ clock format 2156330096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2038 12:34:56 die i mensis v annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2465545 05 v 5 05/01/2038 die i mensis v annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1954 {conversion of 2038-05-31} {
+ clock format 2158922096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2038 12:34:56 die xxxi mensis v annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2465575 05 v 5 05/31/2038 die xxxi mensis v annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1955 {conversion of 2038-06-01} {
+ clock format 2159008496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2038 12:34:56 die i mensis vi annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2465576 06 vi 6 06/01/2038 die i mensis vi annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1956 {conversion of 2038-06-30} {
+ clock format 2161514096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2038 12:34:56 die xxx mensis vi annoque mmxxxviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2465605 06 vi 6 06/30/2038 die xxx mensis vi annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1957 {conversion of 2038-07-01} {
+ clock format 2161600496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2038 12:34:56 die i mensis vii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2465606 07 vii 7 07/01/2038 die i mensis vii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1958 {conversion of 2038-07-31} {
+ clock format 2164192496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2038 12:34:56 die xxxi mensis vii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2465636 07 vii 7 07/31/2038 die xxxi mensis vii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1959 {conversion of 2038-08-01} {
+ clock format 2164278896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2038 12:34:56 die i mensis viii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2465637 08 viii 8 08/01/2038 die i mensis viii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1960 {conversion of 2038-08-31} {
+ clock format 2166870896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2038 12:34:56 die xxxi mensis viii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2465667 08 viii 8 08/31/2038 die xxxi mensis viii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1961 {conversion of 2038-09-01} {
+ clock format 2166957296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2038 12:34:56 die i mensis ix annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2465668 09 ix 9 09/01/2038 die i mensis ix annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1962 {conversion of 2038-09-30} {
+ clock format 2169462896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2038 12:34:56 die xxx mensis ix annoque mmxxxviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2465697 09 ix 9 09/30/2038 die xxx mensis ix annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1963 {conversion of 2038-10-01} {
+ clock format 2169549296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2038 12:34:56 die i mensis x annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2465698 10 x 10 10/01/2038 die i mensis x annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1964 {conversion of 2038-10-31} {
+ clock format 2172141296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2038 12:34:56 die xxxi mensis x annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2465728 10 x 10 10/31/2038 die xxxi mensis x annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1965 {conversion of 2038-11-01} {
+ clock format 2172227696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2038 12:34:56 die i mensis xi annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2465729 11 xi 11 11/01/2038 die i mensis xi annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1966 {conversion of 2038-11-30} {
+ clock format 2174733296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2038 12:34:56 die xxx mensis xi annoque mmxxxviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2465758 11 xi 11 11/30/2038 die xxx mensis xi annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1967 {conversion of 2038-12-01} {
+ clock format 2174819696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2038 12:34:56 die i mensis xii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2465759 12 xii 12 12/01/2038 die i mensis xii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1968 {conversion of 2038-12-31} {
+ clock format 2177411696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2038 12:34:56 die xxxi mensis xii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2465789 12 xii 12 12/31/2038 die xxxi mensis xii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1969 {conversion of 2039-01-01} {
+ clock format 2177498096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2039 12:34:56 die i mensis i annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2465790 01 i 1 01/01/2039 die i mensis i annoque mmxxxix 39 xxxix 2039}
+test clock-2.1970 {conversion of 2039-01-31} {
+ clock format 2180090096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2039 12:34:56 die xxxi mensis i annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2465820 01 i 1 01/31/2039 die xxxi mensis i annoque mmxxxix 39 xxxix 2039}
+test clock-2.1971 {conversion of 2039-02-01} {
+ clock format 2180176496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2039 12:34:56 die i mensis ii annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2465821 02 ii 2 02/01/2039 die i mensis ii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1972 {conversion of 2039-02-28} {
+ clock format 2182509296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2039 12:34:56 die xxviii mensis ii annoque mmxxxix xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2465848 02 ii 2 02/28/2039 die xxviii mensis ii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1973 {conversion of 2039-03-01} {
+ clock format 2182595696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2039 12:34:56 die i mensis iii annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2465849 03 iii 3 03/01/2039 die i mensis iii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1974 {conversion of 2039-03-31} {
+ clock format 2185187696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2039 12:34:56 die xxxi mensis iii annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2465879 03 iii 3 03/31/2039 die xxxi mensis iii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1975 {conversion of 2039-04-01} {
+ clock format 2185274096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2039 12:34:56 die i mensis iv annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2465880 04 iv 4 04/01/2039 die i mensis iv annoque mmxxxix 39 xxxix 2039}
+test clock-2.1976 {conversion of 2039-04-30} {
+ clock format 2187779696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2039 12:34:56 die xxx mensis iv annoque mmxxxix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2465909 04 iv 4 04/30/2039 die xxx mensis iv annoque mmxxxix 39 xxxix 2039}
+test clock-2.1977 {conversion of 2039-05-01} {
+ clock format 2187866096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2039 12:34:56 die i mensis v annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2465910 05 v 5 05/01/2039 die i mensis v annoque mmxxxix 39 xxxix 2039}
+test clock-2.1978 {conversion of 2039-05-31} {
+ clock format 2190458096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2039 12:34:56 die xxxi mensis v annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2465940 05 v 5 05/31/2039 die xxxi mensis v annoque mmxxxix 39 xxxix 2039}
+test clock-2.1979 {conversion of 2039-06-01} {
+ clock format 2190544496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2039 12:34:56 die i mensis vi annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2465941 06 vi 6 06/01/2039 die i mensis vi annoque mmxxxix 39 xxxix 2039}
+test clock-2.1980 {conversion of 2039-06-30} {
+ clock format 2193050096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2039 12:34:56 die xxx mensis vi annoque mmxxxix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2465970 06 vi 6 06/30/2039 die xxx mensis vi annoque mmxxxix 39 xxxix 2039}
+test clock-2.1981 {conversion of 2039-07-01} {
+ clock format 2193136496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2039 12:34:56 die i mensis vii annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2465971 07 vii 7 07/01/2039 die i mensis vii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1982 {conversion of 2039-07-31} {
+ clock format 2195728496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2039 12:34:56 die xxxi mensis vii annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2466001 07 vii 7 07/31/2039 die xxxi mensis vii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1983 {conversion of 2039-08-01} {
+ clock format 2195814896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2039 12:34:56 die i mensis viii annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2466002 08 viii 8 08/01/2039 die i mensis viii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1984 {conversion of 2039-08-31} {
+ clock format 2198406896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2039 12:34:56 die xxxi mensis viii annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2466032 08 viii 8 08/31/2039 die xxxi mensis viii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1985 {conversion of 2039-09-01} {
+ clock format 2198493296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2039 12:34:56 die i mensis ix annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2466033 09 ix 9 09/01/2039 die i mensis ix annoque mmxxxix 39 xxxix 2039}
+test clock-2.1986 {conversion of 2039-09-30} {
+ clock format 2200998896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2039 12:34:56 die xxx mensis ix annoque mmxxxix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2466062 09 ix 9 09/30/2039 die xxx mensis ix annoque mmxxxix 39 xxxix 2039}
+test clock-2.1987 {conversion of 2039-10-01} {
+ clock format 2201085296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2039 12:34:56 die i mensis x annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2466063 10 x 10 10/01/2039 die i mensis x annoque mmxxxix 39 xxxix 2039}
+test clock-2.1988 {conversion of 2039-10-31} {
+ clock format 2203677296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2039 12:34:56 die xxxi mensis x annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2466093 10 x 10 10/31/2039 die xxxi mensis x annoque mmxxxix 39 xxxix 2039}
+test clock-2.1989 {conversion of 2039-11-01} {
+ clock format 2203763696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2039 12:34:56 die i mensis xi annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2466094 11 xi 11 11/01/2039 die i mensis xi annoque mmxxxix 39 xxxix 2039}
+test clock-2.1990 {conversion of 2039-11-30} {
+ clock format 2206269296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2039 12:34:56 die xxx mensis xi annoque mmxxxix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2466123 11 xi 11 11/30/2039 die xxx mensis xi annoque mmxxxix 39 xxxix 2039}
+test clock-2.1991 {conversion of 2039-12-01} {
+ clock format 2206355696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2039 12:34:56 die i mensis xii annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2466124 12 xii 12 12/01/2039 die i mensis xii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1992 {conversion of 2039-12-31} {
+ clock format 2208947696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2039 12:34:56 die xxxi mensis xii annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2466154 12 xii 12 12/31/2039 die xxxi mensis xii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1993 {conversion of 2040-01-01} {
+ clock format 2209034096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2040 12:34:56 die i mensis i annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2466155 01 i 1 01/01/2040 die i mensis i annoque mmxl 40 xl 2040}
+test clock-2.1994 {conversion of 2040-01-31} {
+ clock format 2211626096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2040 12:34:56 die xxxi mensis i annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2466185 01 i 1 01/31/2040 die xxxi mensis i annoque mmxl 40 xl 2040}
+test clock-2.1995 {conversion of 2040-02-01} {
+ clock format 2211712496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2040 12:34:56 die i mensis ii annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2466186 02 ii 2 02/01/2040 die i mensis ii annoque mmxl 40 xl 2040}
+test clock-2.1996 {conversion of 2040-02-29} {
+ clock format 2214131696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2040 12:34:56 die xxix mensis ii annoque mmxl xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2466214 02 ii 2 02/29/2040 die xxix mensis ii annoque mmxl 40 xl 2040}
+test clock-2.1997 {conversion of 2040-03-01} {
+ clock format 2214218096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2040 12:34:56 die i mensis iii annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2466215 03 iii 3 03/01/2040 die i mensis iii annoque mmxl 40 xl 2040}
+test clock-2.1998 {conversion of 2040-03-31} {
+ clock format 2216810096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2040 12:34:56 die xxxi mensis iii annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2466245 03 iii 3 03/31/2040 die xxxi mensis iii annoque mmxl 40 xl 2040}
+test clock-2.1999 {conversion of 2040-04-01} {
+ clock format 2216896496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2040 12:34:56 die i mensis iv annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2466246 04 iv 4 04/01/2040 die i mensis iv annoque mmxl 40 xl 2040}
+test clock-2.2000 {conversion of 2040-04-30} {
+ clock format 2219402096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2040 12:34:56 die xxx mensis iv annoque mmxl xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2466275 04 iv 4 04/30/2040 die xxx mensis iv annoque mmxl 40 xl 2040}
+test clock-2.2001 {conversion of 2040-05-01} {
+ clock format 2219488496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2040 12:34:56 die i mensis v annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2466276 05 v 5 05/01/2040 die i mensis v annoque mmxl 40 xl 2040}
+test clock-2.2002 {conversion of 2040-05-31} {
+ clock format 2222080496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2040 12:34:56 die xxxi mensis v annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2466306 05 v 5 05/31/2040 die xxxi mensis v annoque mmxl 40 xl 2040}
+test clock-2.2003 {conversion of 2040-06-01} {
+ clock format 2222166896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2040 12:34:56 die i mensis vi annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2466307 06 vi 6 06/01/2040 die i mensis vi annoque mmxl 40 xl 2040}
+test clock-2.2004 {conversion of 2040-06-30} {
+ clock format 2224672496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2040 12:34:56 die xxx mensis vi annoque mmxl xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2466336 06 vi 6 06/30/2040 die xxx mensis vi annoque mmxl 40 xl 2040}
+test clock-2.2005 {conversion of 2040-07-01} {
+ clock format 2224758896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2040 12:34:56 die i mensis vii annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2466337 07 vii 7 07/01/2040 die i mensis vii annoque mmxl 40 xl 2040}
+test clock-2.2006 {conversion of 2040-07-31} {
+ clock format 2227350896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2040 12:34:56 die xxxi mensis vii annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2466367 07 vii 7 07/31/2040 die xxxi mensis vii annoque mmxl 40 xl 2040}
+test clock-2.2007 {conversion of 2040-08-01} {
+ clock format 2227437296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2040 12:34:56 die i mensis viii annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2466368 08 viii 8 08/01/2040 die i mensis viii annoque mmxl 40 xl 2040}
+test clock-2.2008 {conversion of 2040-08-31} {
+ clock format 2230029296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2040 12:34:56 die xxxi mensis viii annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2466398 08 viii 8 08/31/2040 die xxxi mensis viii annoque mmxl 40 xl 2040}
+test clock-2.2009 {conversion of 2040-09-01} {
+ clock format 2230115696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2040 12:34:56 die i mensis ix annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2466399 09 ix 9 09/01/2040 die i mensis ix annoque mmxl 40 xl 2040}
+test clock-2.2010 {conversion of 2040-09-30} {
+ clock format 2232621296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2040 12:34:56 die xxx mensis ix annoque mmxl xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2466428 09 ix 9 09/30/2040 die xxx mensis ix annoque mmxl 40 xl 2040}
+test clock-2.2011 {conversion of 2040-10-01} {
+ clock format 2232707696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2040 12:34:56 die i mensis x annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2466429 10 x 10 10/01/2040 die i mensis x annoque mmxl 40 xl 2040}
+test clock-2.2012 {conversion of 2040-10-31} {
+ clock format 2235299696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2040 12:34:56 die xxxi mensis x annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2466459 10 x 10 10/31/2040 die xxxi mensis x annoque mmxl 40 xl 2040}
+test clock-2.2013 {conversion of 2040-11-01} {
+ clock format 2235386096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2040 12:34:56 die i mensis xi annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2466460 11 xi 11 11/01/2040 die i mensis xi annoque mmxl 40 xl 2040}
+test clock-2.2014 {conversion of 2040-11-30} {
+ clock format 2237891696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2040 12:34:56 die xxx mensis xi annoque mmxl xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2466489 11 xi 11 11/30/2040 die xxx mensis xi annoque mmxl 40 xl 2040}
+test clock-2.2015 {conversion of 2040-12-01} {
+ clock format 2237978096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2040 12:34:56 die i mensis xii annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2466490 12 xii 12 12/01/2040 die i mensis xii annoque mmxl 40 xl 2040}
+test clock-2.2016 {conversion of 2040-12-31} {
+ clock format 2240570096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2040 12:34:56 die xxxi mensis xii annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2466520 12 xii 12 12/31/2040 die xxxi mensis xii annoque mmxl 40 xl 2040}
+test clock-2.2017 {conversion of 2041-01-01} {
+ clock format 2240656496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2041 12:34:56 die i mensis i annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2466521 01 i 1 01/01/2041 die i mensis i annoque mmxli 41 xli 2041}
+test clock-2.2018 {conversion of 2041-01-31} {
+ clock format 2243248496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2041 12:34:56 die xxxi mensis i annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2466551 01 i 1 01/31/2041 die xxxi mensis i annoque mmxli 41 xli 2041}
+test clock-2.2019 {conversion of 2041-02-01} {
+ clock format 2243334896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2041 12:34:56 die i mensis ii annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2466552 02 ii 2 02/01/2041 die i mensis ii annoque mmxli 41 xli 2041}
+test clock-2.2020 {conversion of 2041-02-28} {
+ clock format 2245667696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2041 12:34:56 die xxviii mensis ii annoque mmxli xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2466579 02 ii 2 02/28/2041 die xxviii mensis ii annoque mmxli 41 xli 2041}
+test clock-2.2021 {conversion of 2041-03-01} {
+ clock format 2245754096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2041 12:34:56 die i mensis iii annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2466580 03 iii 3 03/01/2041 die i mensis iii annoque mmxli 41 xli 2041}
+test clock-2.2022 {conversion of 2041-03-31} {
+ clock format 2248346096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2041 12:34:56 die xxxi mensis iii annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2466610 03 iii 3 03/31/2041 die xxxi mensis iii annoque mmxli 41 xli 2041}
+test clock-2.2023 {conversion of 2041-04-01} {
+ clock format 2248432496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2041 12:34:56 die i mensis iv annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2466611 04 iv 4 04/01/2041 die i mensis iv annoque mmxli 41 xli 2041}
+test clock-2.2024 {conversion of 2041-04-30} {
+ clock format 2250938096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2041 12:34:56 die xxx mensis iv annoque mmxli xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2466640 04 iv 4 04/30/2041 die xxx mensis iv annoque mmxli 41 xli 2041}
+test clock-2.2025 {conversion of 2041-05-01} {
+ clock format 2251024496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2041 12:34:56 die i mensis v annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2466641 05 v 5 05/01/2041 die i mensis v annoque mmxli 41 xli 2041}
+test clock-2.2026 {conversion of 2041-05-31} {
+ clock format 2253616496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2041 12:34:56 die xxxi mensis v annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2466671 05 v 5 05/31/2041 die xxxi mensis v annoque mmxli 41 xli 2041}
+test clock-2.2027 {conversion of 2041-06-01} {
+ clock format 2253702896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2041 12:34:56 die i mensis vi annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2466672 06 vi 6 06/01/2041 die i mensis vi annoque mmxli 41 xli 2041}
+test clock-2.2028 {conversion of 2041-06-30} {
+ clock format 2256208496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2041 12:34:56 die xxx mensis vi annoque mmxli xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2466701 06 vi 6 06/30/2041 die xxx mensis vi annoque mmxli 41 xli 2041}
+test clock-2.2029 {conversion of 2041-07-01} {
+ clock format 2256294896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2041 12:34:56 die i mensis vii annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2466702 07 vii 7 07/01/2041 die i mensis vii annoque mmxli 41 xli 2041}
+test clock-2.2030 {conversion of 2041-07-31} {
+ clock format 2258886896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2041 12:34:56 die xxxi mensis vii annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2466732 07 vii 7 07/31/2041 die xxxi mensis vii annoque mmxli 41 xli 2041}
+test clock-2.2031 {conversion of 2041-08-01} {
+ clock format 2258973296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2041 12:34:56 die i mensis viii annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2466733 08 viii 8 08/01/2041 die i mensis viii annoque mmxli 41 xli 2041}
+test clock-2.2032 {conversion of 2041-08-31} {
+ clock format 2261565296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2041 12:34:56 die xxxi mensis viii annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2466763 08 viii 8 08/31/2041 die xxxi mensis viii annoque mmxli 41 xli 2041}
+test clock-2.2033 {conversion of 2041-09-01} {
+ clock format 2261651696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2041 12:34:56 die i mensis ix annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2466764 09 ix 9 09/01/2041 die i mensis ix annoque mmxli 41 xli 2041}
+test clock-2.2034 {conversion of 2041-09-30} {
+ clock format 2264157296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2041 12:34:56 die xxx mensis ix annoque mmxli xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2466793 09 ix 9 09/30/2041 die xxx mensis ix annoque mmxli 41 xli 2041}
+test clock-2.2035 {conversion of 2041-10-01} {
+ clock format 2264243696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2041 12:34:56 die i mensis x annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2466794 10 x 10 10/01/2041 die i mensis x annoque mmxli 41 xli 2041}
+test clock-2.2036 {conversion of 2041-10-31} {
+ clock format 2266835696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2041 12:34:56 die xxxi mensis x annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2466824 10 x 10 10/31/2041 die xxxi mensis x annoque mmxli 41 xli 2041}
+test clock-2.2037 {conversion of 2041-11-01} {
+ clock format 2266922096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2041 12:34:56 die i mensis xi annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2466825 11 xi 11 11/01/2041 die i mensis xi annoque mmxli 41 xli 2041}
+test clock-2.2038 {conversion of 2041-11-30} {
+ clock format 2269427696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2041 12:34:56 die xxx mensis xi annoque mmxli xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2466854 11 xi 11 11/30/2041 die xxx mensis xi annoque mmxli 41 xli 2041}
+test clock-2.2039 {conversion of 2041-12-01} {
+ clock format 2269514096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2041 12:34:56 die i mensis xii annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2466855 12 xii 12 12/01/2041 die i mensis xii annoque mmxli 41 xli 2041}
+test clock-2.2040 {conversion of 2041-12-31} {
+ clock format 2272106096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2041 12:34:56 die xxxi mensis xii annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2466885 12 xii 12 12/31/2041 die xxxi mensis xii annoque mmxli 41 xli 2041}
+test clock-2.2041 {conversion of 2042-01-01} {
+ clock format 2272192496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2042 12:34:56 die i mensis i annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2466886 01 i 1 01/01/2042 die i mensis i annoque mmxlii 42 xlii 2042}
+test clock-2.2042 {conversion of 2042-01-31} {
+ clock format 2274784496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2042 12:34:56 die xxxi mensis i annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2466916 01 i 1 01/31/2042 die xxxi mensis i annoque mmxlii 42 xlii 2042}
+test clock-2.2043 {conversion of 2042-02-01} {
+ clock format 2274870896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2042 12:34:56 die i mensis ii annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2466917 02 ii 2 02/01/2042 die i mensis ii annoque mmxlii 42 xlii 2042}
+test clock-2.2044 {conversion of 2042-02-28} {
+ clock format 2277203696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2042 12:34:56 die xxviii mensis ii annoque mmxlii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2466944 02 ii 2 02/28/2042 die xxviii mensis ii annoque mmxlii 42 xlii 2042}
+test clock-2.2045 {conversion of 2042-03-01} {
+ clock format 2277290096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2042 12:34:56 die i mensis iii annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2466945 03 iii 3 03/01/2042 die i mensis iii annoque mmxlii 42 xlii 2042}
+test clock-2.2046 {conversion of 2042-03-31} {
+ clock format 2279882096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2042 12:34:56 die xxxi mensis iii annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2466975 03 iii 3 03/31/2042 die xxxi mensis iii annoque mmxlii 42 xlii 2042}
+test clock-2.2047 {conversion of 2042-04-01} {
+ clock format 2279968496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2042 12:34:56 die i mensis iv annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2466976 04 iv 4 04/01/2042 die i mensis iv annoque mmxlii 42 xlii 2042}
+test clock-2.2048 {conversion of 2042-04-30} {
+ clock format 2282474096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2042 12:34:56 die xxx mensis iv annoque mmxlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2467005 04 iv 4 04/30/2042 die xxx mensis iv annoque mmxlii 42 xlii 2042}
+test clock-2.2049 {conversion of 2042-05-01} {
+ clock format 2282560496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2042 12:34:56 die i mensis v annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2467006 05 v 5 05/01/2042 die i mensis v annoque mmxlii 42 xlii 2042}
+test clock-2.2050 {conversion of 2042-05-31} {
+ clock format 2285152496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2042 12:34:56 die xxxi mensis v annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2467036 05 v 5 05/31/2042 die xxxi mensis v annoque mmxlii 42 xlii 2042}
+test clock-2.2051 {conversion of 2042-06-01} {
+ clock format 2285238896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2042 12:34:56 die i mensis vi annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2467037 06 vi 6 06/01/2042 die i mensis vi annoque mmxlii 42 xlii 2042}
+test clock-2.2052 {conversion of 2042-06-30} {
+ clock format 2287744496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2042 12:34:56 die xxx mensis vi annoque mmxlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2467066 06 vi 6 06/30/2042 die xxx mensis vi annoque mmxlii 42 xlii 2042}
+test clock-2.2053 {conversion of 2042-07-01} {
+ clock format 2287830896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2042 12:34:56 die i mensis vii annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2467067 07 vii 7 07/01/2042 die i mensis vii annoque mmxlii 42 xlii 2042}
+test clock-2.2054 {conversion of 2042-07-31} {
+ clock format 2290422896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2042 12:34:56 die xxxi mensis vii annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2467097 07 vii 7 07/31/2042 die xxxi mensis vii annoque mmxlii 42 xlii 2042}
+test clock-2.2055 {conversion of 2042-08-01} {
+ clock format 2290509296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2042 12:34:56 die i mensis viii annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2467098 08 viii 8 08/01/2042 die i mensis viii annoque mmxlii 42 xlii 2042}
+test clock-2.2056 {conversion of 2042-08-31} {
+ clock format 2293101296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2042 12:34:56 die xxxi mensis viii annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2467128 08 viii 8 08/31/2042 die xxxi mensis viii annoque mmxlii 42 xlii 2042}
+test clock-2.2057 {conversion of 2042-09-01} {
+ clock format 2293187696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2042 12:34:56 die i mensis ix annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2467129 09 ix 9 09/01/2042 die i mensis ix annoque mmxlii 42 xlii 2042}
+test clock-2.2058 {conversion of 2042-09-30} {
+ clock format 2295693296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2042 12:34:56 die xxx mensis ix annoque mmxlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2467158 09 ix 9 09/30/2042 die xxx mensis ix annoque mmxlii 42 xlii 2042}
+test clock-2.2059 {conversion of 2042-10-01} {
+ clock format 2295779696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2042 12:34:56 die i mensis x annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2467159 10 x 10 10/01/2042 die i mensis x annoque mmxlii 42 xlii 2042}
+test clock-2.2060 {conversion of 2042-10-31} {
+ clock format 2298371696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2042 12:34:56 die xxxi mensis x annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2467189 10 x 10 10/31/2042 die xxxi mensis x annoque mmxlii 42 xlii 2042}
+test clock-2.2061 {conversion of 2042-11-01} {
+ clock format 2298458096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2042 12:34:56 die i mensis xi annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2467190 11 xi 11 11/01/2042 die i mensis xi annoque mmxlii 42 xlii 2042}
+test clock-2.2062 {conversion of 2042-11-30} {
+ clock format 2300963696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2042 12:34:56 die xxx mensis xi annoque mmxlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2467219 11 xi 11 11/30/2042 die xxx mensis xi annoque mmxlii 42 xlii 2042}
+test clock-2.2063 {conversion of 2042-12-01} {
+ clock format 2301050096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2042 12:34:56 die i mensis xii annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2467220 12 xii 12 12/01/2042 die i mensis xii annoque mmxlii 42 xlii 2042}
+test clock-2.2064 {conversion of 2042-12-31} {
+ clock format 2303642096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2042 12:34:56 die xxxi mensis xii annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2467250 12 xii 12 12/31/2042 die xxxi mensis xii annoque mmxlii 42 xlii 2042}
+test clock-2.2065 {conversion of 2043-01-01} {
+ clock format 2303728496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2043 12:34:56 die i mensis i annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2467251 01 i 1 01/01/2043 die i mensis i annoque mmxliii 43 xliii 2043}
+test clock-2.2066 {conversion of 2043-01-31} {
+ clock format 2306320496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2043 12:34:56 die xxxi mensis i annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2467281 01 i 1 01/31/2043 die xxxi mensis i annoque mmxliii 43 xliii 2043}
+test clock-2.2067 {conversion of 2043-02-01} {
+ clock format 2306406896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2043 12:34:56 die i mensis ii annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2467282 02 ii 2 02/01/2043 die i mensis ii annoque mmxliii 43 xliii 2043}
+test clock-2.2068 {conversion of 2043-02-28} {
+ clock format 2308739696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2043 12:34:56 die xxviii mensis ii annoque mmxliii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2467309 02 ii 2 02/28/2043 die xxviii mensis ii annoque mmxliii 43 xliii 2043}
+test clock-2.2069 {conversion of 2043-03-01} {
+ clock format 2308826096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2043 12:34:56 die i mensis iii annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2467310 03 iii 3 03/01/2043 die i mensis iii annoque mmxliii 43 xliii 2043}
+test clock-2.2070 {conversion of 2043-03-31} {
+ clock format 2311418096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2043 12:34:56 die xxxi mensis iii annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2467340 03 iii 3 03/31/2043 die xxxi mensis iii annoque mmxliii 43 xliii 2043}
+test clock-2.2071 {conversion of 2043-04-01} {
+ clock format 2311504496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2043 12:34:56 die i mensis iv annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2467341 04 iv 4 04/01/2043 die i mensis iv annoque mmxliii 43 xliii 2043}
+test clock-2.2072 {conversion of 2043-04-30} {
+ clock format 2314010096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2043 12:34:56 die xxx mensis iv annoque mmxliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2467370 04 iv 4 04/30/2043 die xxx mensis iv annoque mmxliii 43 xliii 2043}
+test clock-2.2073 {conversion of 2043-05-01} {
+ clock format 2314096496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2043 12:34:56 die i mensis v annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2467371 05 v 5 05/01/2043 die i mensis v annoque mmxliii 43 xliii 2043}
+test clock-2.2074 {conversion of 2043-05-31} {
+ clock format 2316688496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2043 12:34:56 die xxxi mensis v annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2467401 05 v 5 05/31/2043 die xxxi mensis v annoque mmxliii 43 xliii 2043}
+test clock-2.2075 {conversion of 2043-06-01} {
+ clock format 2316774896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2043 12:34:56 die i mensis vi annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2467402 06 vi 6 06/01/2043 die i mensis vi annoque mmxliii 43 xliii 2043}
+test clock-2.2076 {conversion of 2043-06-30} {
+ clock format 2319280496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2043 12:34:56 die xxx mensis vi annoque mmxliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2467431 06 vi 6 06/30/2043 die xxx mensis vi annoque mmxliii 43 xliii 2043}
+test clock-2.2077 {conversion of 2043-07-01} {
+ clock format 2319366896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2043 12:34:56 die i mensis vii annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2467432 07 vii 7 07/01/2043 die i mensis vii annoque mmxliii 43 xliii 2043}
+test clock-2.2078 {conversion of 2043-07-31} {
+ clock format 2321958896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2043 12:34:56 die xxxi mensis vii annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2467462 07 vii 7 07/31/2043 die xxxi mensis vii annoque mmxliii 43 xliii 2043}
+test clock-2.2079 {conversion of 2043-08-01} {
+ clock format 2322045296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2043 12:34:56 die i mensis viii annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2467463 08 viii 8 08/01/2043 die i mensis viii annoque mmxliii 43 xliii 2043}
+test clock-2.2080 {conversion of 2043-08-31} {
+ clock format 2324637296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2043 12:34:56 die xxxi mensis viii annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2467493 08 viii 8 08/31/2043 die xxxi mensis viii annoque mmxliii 43 xliii 2043}
+test clock-2.2081 {conversion of 2043-09-01} {
+ clock format 2324723696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2043 12:34:56 die i mensis ix annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2467494 09 ix 9 09/01/2043 die i mensis ix annoque mmxliii 43 xliii 2043}
+test clock-2.2082 {conversion of 2043-09-30} {
+ clock format 2327229296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2043 12:34:56 die xxx mensis ix annoque mmxliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2467523 09 ix 9 09/30/2043 die xxx mensis ix annoque mmxliii 43 xliii 2043}
+test clock-2.2083 {conversion of 2043-10-01} {
+ clock format 2327315696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2043 12:34:56 die i mensis x annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2467524 10 x 10 10/01/2043 die i mensis x annoque mmxliii 43 xliii 2043}
+test clock-2.2084 {conversion of 2043-10-31} {
+ clock format 2329907696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2043 12:34:56 die xxxi mensis x annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2467554 10 x 10 10/31/2043 die xxxi mensis x annoque mmxliii 43 xliii 2043}
+test clock-2.2085 {conversion of 2043-11-01} {
+ clock format 2329994096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2043 12:34:56 die i mensis xi annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2467555 11 xi 11 11/01/2043 die i mensis xi annoque mmxliii 43 xliii 2043}
+test clock-2.2086 {conversion of 2043-11-30} {
+ clock format 2332499696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2043 12:34:56 die xxx mensis xi annoque mmxliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2467584 11 xi 11 11/30/2043 die xxx mensis xi annoque mmxliii 43 xliii 2043}
+test clock-2.2087 {conversion of 2043-12-01} {
+ clock format 2332586096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2043 12:34:56 die i mensis xii annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2467585 12 xii 12 12/01/2043 die i mensis xii annoque mmxliii 43 xliii 2043}
+test clock-2.2088 {conversion of 2043-12-31} {
+ clock format 2335178096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2043 12:34:56 die xxxi mensis xii annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2467615 12 xii 12 12/31/2043 die xxxi mensis xii annoque mmxliii 43 xliii 2043}
+test clock-2.2089 {conversion of 2044-01-01} {
+ clock format 2335264496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2044 12:34:56 die i mensis i annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2467616 01 i 1 01/01/2044 die i mensis i annoque mmxliv 44 xliv 2044}
+test clock-2.2090 {conversion of 2044-01-31} {
+ clock format 2337856496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2044 12:34:56 die xxxi mensis i annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2467646 01 i 1 01/31/2044 die xxxi mensis i annoque mmxliv 44 xliv 2044}
+test clock-2.2091 {conversion of 2044-02-01} {
+ clock format 2337942896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2044 12:34:56 die i mensis ii annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2467647 02 ii 2 02/01/2044 die i mensis ii annoque mmxliv 44 xliv 2044}
+test clock-2.2092 {conversion of 2044-02-29} {
+ clock format 2340362096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2044 12:34:56 die xxix mensis ii annoque mmxliv xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2467675 02 ii 2 02/29/2044 die xxix mensis ii annoque mmxliv 44 xliv 2044}
+test clock-2.2093 {conversion of 2044-03-01} {
+ clock format 2340448496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2044 12:34:56 die i mensis iii annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2467676 03 iii 3 03/01/2044 die i mensis iii annoque mmxliv 44 xliv 2044}
+test clock-2.2094 {conversion of 2044-03-31} {
+ clock format 2343040496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2044 12:34:56 die xxxi mensis iii annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2467706 03 iii 3 03/31/2044 die xxxi mensis iii annoque mmxliv 44 xliv 2044}
+test clock-2.2095 {conversion of 2044-04-01} {
+ clock format 2343126896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2044 12:34:56 die i mensis iv annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2467707 04 iv 4 04/01/2044 die i mensis iv annoque mmxliv 44 xliv 2044}
+test clock-2.2096 {conversion of 2044-04-30} {
+ clock format 2345632496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2044 12:34:56 die xxx mensis iv annoque mmxliv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2467736 04 iv 4 04/30/2044 die xxx mensis iv annoque mmxliv 44 xliv 2044}
+test clock-2.2097 {conversion of 2044-05-01} {
+ clock format 2345718896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2044 12:34:56 die i mensis v annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2467737 05 v 5 05/01/2044 die i mensis v annoque mmxliv 44 xliv 2044}
+test clock-2.2098 {conversion of 2044-05-31} {
+ clock format 2348310896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2044 12:34:56 die xxxi mensis v annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2467767 05 v 5 05/31/2044 die xxxi mensis v annoque mmxliv 44 xliv 2044}
+test clock-2.2099 {conversion of 2044-06-01} {
+ clock format 2348397296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2044 12:34:56 die i mensis vi annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2467768 06 vi 6 06/01/2044 die i mensis vi annoque mmxliv 44 xliv 2044}
+test clock-2.2100 {conversion of 2044-06-30} {
+ clock format 2350902896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2044 12:34:56 die xxx mensis vi annoque mmxliv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2467797 06 vi 6 06/30/2044 die xxx mensis vi annoque mmxliv 44 xliv 2044}
+test clock-2.2101 {conversion of 2044-07-01} {
+ clock format 2350989296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2044 12:34:56 die i mensis vii annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2467798 07 vii 7 07/01/2044 die i mensis vii annoque mmxliv 44 xliv 2044}
+test clock-2.2102 {conversion of 2044-07-31} {
+ clock format 2353581296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2044 12:34:56 die xxxi mensis vii annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2467828 07 vii 7 07/31/2044 die xxxi mensis vii annoque mmxliv 44 xliv 2044}
+test clock-2.2103 {conversion of 2044-08-01} {
+ clock format 2353667696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2044 12:34:56 die i mensis viii annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2467829 08 viii 8 08/01/2044 die i mensis viii annoque mmxliv 44 xliv 2044}
+test clock-2.2104 {conversion of 2044-08-31} {
+ clock format 2356259696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2044 12:34:56 die xxxi mensis viii annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2467859 08 viii 8 08/31/2044 die xxxi mensis viii annoque mmxliv 44 xliv 2044}
+test clock-2.2105 {conversion of 2044-09-01} {
+ clock format 2356346096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2044 12:34:56 die i mensis ix annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2467860 09 ix 9 09/01/2044 die i mensis ix annoque mmxliv 44 xliv 2044}
+test clock-2.2106 {conversion of 2044-09-30} {
+ clock format 2358851696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2044 12:34:56 die xxx mensis ix annoque mmxliv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2467889 09 ix 9 09/30/2044 die xxx mensis ix annoque mmxliv 44 xliv 2044}
+test clock-2.2107 {conversion of 2044-10-01} {
+ clock format 2358938096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2044 12:34:56 die i mensis x annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2467890 10 x 10 10/01/2044 die i mensis x annoque mmxliv 44 xliv 2044}
+test clock-2.2108 {conversion of 2044-10-31} {
+ clock format 2361530096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2044 12:34:56 die xxxi mensis x annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2467920 10 x 10 10/31/2044 die xxxi mensis x annoque mmxliv 44 xliv 2044}
+test clock-2.2109 {conversion of 2044-11-01} {
+ clock format 2361616496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2044 12:34:56 die i mensis xi annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2467921 11 xi 11 11/01/2044 die i mensis xi annoque mmxliv 44 xliv 2044}
+test clock-2.2110 {conversion of 2044-11-30} {
+ clock format 2364122096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2044 12:34:56 die xxx mensis xi annoque mmxliv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2467950 11 xi 11 11/30/2044 die xxx mensis xi annoque mmxliv 44 xliv 2044}
+test clock-2.2111 {conversion of 2044-12-01} {
+ clock format 2364208496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2044 12:34:56 die i mensis xii annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2467951 12 xii 12 12/01/2044 die i mensis xii annoque mmxliv 44 xliv 2044}
+test clock-2.2112 {conversion of 2044-12-31} {
+ clock format 2366800496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2044 12:34:56 die xxxi mensis xii annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2467981 12 xii 12 12/31/2044 die xxxi mensis xii annoque mmxliv 44 xliv 2044}
+test clock-2.2113 {conversion of 2045-01-01} {
+ clock format 2366886896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2045 12:34:56 die i mensis i annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2467982 01 i 1 01/01/2045 die i mensis i annoque mmxlv 45 xlv 2045}
+test clock-2.2114 {conversion of 2045-01-31} {
+ clock format 2369478896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2045 12:34:56 die xxxi mensis i annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2468012 01 i 1 01/31/2045 die xxxi mensis i annoque mmxlv 45 xlv 2045}
+test clock-2.2115 {conversion of 2045-02-01} {
+ clock format 2369565296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2045 12:34:56 die i mensis ii annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2468013 02 ii 2 02/01/2045 die i mensis ii annoque mmxlv 45 xlv 2045}
+test clock-2.2116 {conversion of 2045-02-28} {
+ clock format 2371898096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2045 12:34:56 die xxviii mensis ii annoque mmxlv xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2468040 02 ii 2 02/28/2045 die xxviii mensis ii annoque mmxlv 45 xlv 2045}
+test clock-2.2117 {conversion of 2045-03-01} {
+ clock format 2371984496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2045 12:34:56 die i mensis iii annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2468041 03 iii 3 03/01/2045 die i mensis iii annoque mmxlv 45 xlv 2045}
+test clock-2.2118 {conversion of 2045-03-31} {
+ clock format 2374576496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2045 12:34:56 die xxxi mensis iii annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2468071 03 iii 3 03/31/2045 die xxxi mensis iii annoque mmxlv 45 xlv 2045}
+test clock-2.2119 {conversion of 2045-04-01} {
+ clock format 2374662896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2045 12:34:56 die i mensis iv annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2468072 04 iv 4 04/01/2045 die i mensis iv annoque mmxlv 45 xlv 2045}
+test clock-2.2120 {conversion of 2045-04-30} {
+ clock format 2377168496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2045 12:34:56 die xxx mensis iv annoque mmxlv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2468101 04 iv 4 04/30/2045 die xxx mensis iv annoque mmxlv 45 xlv 2045}
+test clock-2.2121 {conversion of 2045-05-01} {
+ clock format 2377254896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2045 12:34:56 die i mensis v annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2468102 05 v 5 05/01/2045 die i mensis v annoque mmxlv 45 xlv 2045}
+test clock-2.2122 {conversion of 2045-05-31} {
+ clock format 2379846896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2045 12:34:56 die xxxi mensis v annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2468132 05 v 5 05/31/2045 die xxxi mensis v annoque mmxlv 45 xlv 2045}
+test clock-2.2123 {conversion of 2045-06-01} {
+ clock format 2379933296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2045 12:34:56 die i mensis vi annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2468133 06 vi 6 06/01/2045 die i mensis vi annoque mmxlv 45 xlv 2045}
+test clock-2.2124 {conversion of 2045-06-30} {
+ clock format 2382438896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2045 12:34:56 die xxx mensis vi annoque mmxlv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2468162 06 vi 6 06/30/2045 die xxx mensis vi annoque mmxlv 45 xlv 2045}
+test clock-2.2125 {conversion of 2045-07-01} {
+ clock format 2382525296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2045 12:34:56 die i mensis vii annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2468163 07 vii 7 07/01/2045 die i mensis vii annoque mmxlv 45 xlv 2045}
+test clock-2.2126 {conversion of 2045-07-31} {
+ clock format 2385117296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2045 12:34:56 die xxxi mensis vii annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2468193 07 vii 7 07/31/2045 die xxxi mensis vii annoque mmxlv 45 xlv 2045}
+test clock-2.2127 {conversion of 2045-08-01} {
+ clock format 2385203696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2045 12:34:56 die i mensis viii annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2468194 08 viii 8 08/01/2045 die i mensis viii annoque mmxlv 45 xlv 2045}
+test clock-2.2128 {conversion of 2045-08-31} {
+ clock format 2387795696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2045 12:34:56 die xxxi mensis viii annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2468224 08 viii 8 08/31/2045 die xxxi mensis viii annoque mmxlv 45 xlv 2045}
+test clock-2.2129 {conversion of 2045-09-01} {
+ clock format 2387882096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2045 12:34:56 die i mensis ix annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2468225 09 ix 9 09/01/2045 die i mensis ix annoque mmxlv 45 xlv 2045}
+test clock-2.2130 {conversion of 2045-09-30} {
+ clock format 2390387696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2045 12:34:56 die xxx mensis ix annoque mmxlv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2468254 09 ix 9 09/30/2045 die xxx mensis ix annoque mmxlv 45 xlv 2045}
+test clock-2.2131 {conversion of 2045-10-01} {
+ clock format 2390474096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2045 12:34:56 die i mensis x annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2468255 10 x 10 10/01/2045 die i mensis x annoque mmxlv 45 xlv 2045}
+test clock-2.2132 {conversion of 2045-10-31} {
+ clock format 2393066096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2045 12:34:56 die xxxi mensis x annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2468285 10 x 10 10/31/2045 die xxxi mensis x annoque mmxlv 45 xlv 2045}
+test clock-2.2133 {conversion of 2045-11-01} {
+ clock format 2393152496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2045 12:34:56 die i mensis xi annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2468286 11 xi 11 11/01/2045 die i mensis xi annoque mmxlv 45 xlv 2045}
+test clock-2.2134 {conversion of 2045-11-30} {
+ clock format 2395658096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2045 12:34:56 die xxx mensis xi annoque mmxlv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2468315 11 xi 11 11/30/2045 die xxx mensis xi annoque mmxlv 45 xlv 2045}
+test clock-2.2135 {conversion of 2045-12-01} {
+ clock format 2395744496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2045 12:34:56 die i mensis xii annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2468316 12 xii 12 12/01/2045 die i mensis xii annoque mmxlv 45 xlv 2045}
+test clock-2.2136 {conversion of 2045-12-31} {
+ clock format 2398336496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2045 12:34:56 die xxxi mensis xii annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2468346 12 xii 12 12/31/2045 die xxxi mensis xii annoque mmxlv 45 xlv 2045}
+test clock-2.2137 {conversion of 2046-01-01} {
+ clock format 2398422896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2046 12:34:56 die i mensis i annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2468347 01 i 1 01/01/2046 die i mensis i annoque mmxlvi 46 xlvi 2046}
+test clock-2.2138 {conversion of 2046-01-31} {
+ clock format 2401014896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2046 12:34:56 die xxxi mensis i annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2468377 01 i 1 01/31/2046 die xxxi mensis i annoque mmxlvi 46 xlvi 2046}
+test clock-2.2139 {conversion of 2046-02-01} {
+ clock format 2401101296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2046 12:34:56 die i mensis ii annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2468378 02 ii 2 02/01/2046 die i mensis ii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2140 {conversion of 2046-02-28} {
+ clock format 2403434096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2046 12:34:56 die xxviii mensis ii annoque mmxlvi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2468405 02 ii 2 02/28/2046 die xxviii mensis ii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2141 {conversion of 2046-03-01} {
+ clock format 2403520496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2046 12:34:56 die i mensis iii annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2468406 03 iii 3 03/01/2046 die i mensis iii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2142 {conversion of 2046-03-31} {
+ clock format 2406112496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2046 12:34:56 die xxxi mensis iii annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2468436 03 iii 3 03/31/2046 die xxxi mensis iii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2143 {conversion of 2046-04-01} {
+ clock format 2406198896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2046 12:34:56 die i mensis iv annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2468437 04 iv 4 04/01/2046 die i mensis iv annoque mmxlvi 46 xlvi 2046}
+test clock-2.2144 {conversion of 2046-04-30} {
+ clock format 2408704496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2046 12:34:56 die xxx mensis iv annoque mmxlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2468466 04 iv 4 04/30/2046 die xxx mensis iv annoque mmxlvi 46 xlvi 2046}
+test clock-2.2145 {conversion of 2046-05-01} {
+ clock format 2408790896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2046 12:34:56 die i mensis v annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2468467 05 v 5 05/01/2046 die i mensis v annoque mmxlvi 46 xlvi 2046}
+test clock-2.2146 {conversion of 2046-05-31} {
+ clock format 2411382896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2046 12:34:56 die xxxi mensis v annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2468497 05 v 5 05/31/2046 die xxxi mensis v annoque mmxlvi 46 xlvi 2046}
+test clock-2.2147 {conversion of 2046-06-01} {
+ clock format 2411469296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2046 12:34:56 die i mensis vi annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2468498 06 vi 6 06/01/2046 die i mensis vi annoque mmxlvi 46 xlvi 2046}
+test clock-2.2148 {conversion of 2046-06-30} {
+ clock format 2413974896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2046 12:34:56 die xxx mensis vi annoque mmxlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2468527 06 vi 6 06/30/2046 die xxx mensis vi annoque mmxlvi 46 xlvi 2046}
+test clock-2.2149 {conversion of 2046-07-01} {
+ clock format 2414061296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2046 12:34:56 die i mensis vii annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2468528 07 vii 7 07/01/2046 die i mensis vii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2150 {conversion of 2046-07-31} {
+ clock format 2416653296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2046 12:34:56 die xxxi mensis vii annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2468558 07 vii 7 07/31/2046 die xxxi mensis vii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2151 {conversion of 2046-08-01} {
+ clock format 2416739696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2046 12:34:56 die i mensis viii annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2468559 08 viii 8 08/01/2046 die i mensis viii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2152 {conversion of 2046-08-31} {
+ clock format 2419331696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2046 12:34:56 die xxxi mensis viii annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2468589 08 viii 8 08/31/2046 die xxxi mensis viii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2153 {conversion of 2046-09-01} {
+ clock format 2419418096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2046 12:34:56 die i mensis ix annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2468590 09 ix 9 09/01/2046 die i mensis ix annoque mmxlvi 46 xlvi 2046}
+test clock-2.2154 {conversion of 2046-09-30} {
+ clock format 2421923696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2046 12:34:56 die xxx mensis ix annoque mmxlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2468619 09 ix 9 09/30/2046 die xxx mensis ix annoque mmxlvi 46 xlvi 2046}
+test clock-2.2155 {conversion of 2046-10-01} {
+ clock format 2422010096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2046 12:34:56 die i mensis x annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2468620 10 x 10 10/01/2046 die i mensis x annoque mmxlvi 46 xlvi 2046}
+test clock-2.2156 {conversion of 2046-10-31} {
+ clock format 2424602096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2046 12:34:56 die xxxi mensis x annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2468650 10 x 10 10/31/2046 die xxxi mensis x annoque mmxlvi 46 xlvi 2046}
+test clock-2.2157 {conversion of 2046-11-01} {
+ clock format 2424688496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2046 12:34:56 die i mensis xi annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2468651 11 xi 11 11/01/2046 die i mensis xi annoque mmxlvi 46 xlvi 2046}
+test clock-2.2158 {conversion of 2046-11-30} {
+ clock format 2427194096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2046 12:34:56 die xxx mensis xi annoque mmxlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2468680 11 xi 11 11/30/2046 die xxx mensis xi annoque mmxlvi 46 xlvi 2046}
+test clock-2.2159 {conversion of 2046-12-01} {
+ clock format 2427280496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2046 12:34:56 die i mensis xii annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2468681 12 xii 12 12/01/2046 die i mensis xii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2160 {conversion of 2046-12-31} {
+ clock format 2429872496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2046 12:34:56 die xxxi mensis xii annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2468711 12 xii 12 12/31/2046 die xxxi mensis xii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2161 {conversion of 2047-01-01} {
+ clock format 2429958896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2047 12:34:56 die i mensis i annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2468712 01 i 1 01/01/2047 die i mensis i annoque mmxlvii 47 xlvii 2047}
+test clock-2.2162 {conversion of 2047-01-31} {
+ clock format 2432550896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2047 12:34:56 die xxxi mensis i annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2468742 01 i 1 01/31/2047 die xxxi mensis i annoque mmxlvii 47 xlvii 2047}
+test clock-2.2163 {conversion of 2047-02-01} {
+ clock format 2432637296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2047 12:34:56 die i mensis ii annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2468743 02 ii 2 02/01/2047 die i mensis ii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2164 {conversion of 2047-02-28} {
+ clock format 2434970096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2047 12:34:56 die xxviii mensis ii annoque mmxlvii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2468770 02 ii 2 02/28/2047 die xxviii mensis ii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2165 {conversion of 2047-03-01} {
+ clock format 2435056496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2047 12:34:56 die i mensis iii annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2468771 03 iii 3 03/01/2047 die i mensis iii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2166 {conversion of 2047-03-31} {
+ clock format 2437648496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2047 12:34:56 die xxxi mensis iii annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2468801 03 iii 3 03/31/2047 die xxxi mensis iii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2167 {conversion of 2047-04-01} {
+ clock format 2437734896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2047 12:34:56 die i mensis iv annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2468802 04 iv 4 04/01/2047 die i mensis iv annoque mmxlvii 47 xlvii 2047}
+test clock-2.2168 {conversion of 2047-04-30} {
+ clock format 2440240496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2047 12:34:56 die xxx mensis iv annoque mmxlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2468831 04 iv 4 04/30/2047 die xxx mensis iv annoque mmxlvii 47 xlvii 2047}
+test clock-2.2169 {conversion of 2047-05-01} {
+ clock format 2440326896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2047 12:34:56 die i mensis v annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2468832 05 v 5 05/01/2047 die i mensis v annoque mmxlvii 47 xlvii 2047}
+test clock-2.2170 {conversion of 2047-05-31} {
+ clock format 2442918896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2047 12:34:56 die xxxi mensis v annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2468862 05 v 5 05/31/2047 die xxxi mensis v annoque mmxlvii 47 xlvii 2047}
+test clock-2.2171 {conversion of 2047-06-01} {
+ clock format 2443005296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2047 12:34:56 die i mensis vi annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2468863 06 vi 6 06/01/2047 die i mensis vi annoque mmxlvii 47 xlvii 2047}
+test clock-2.2172 {conversion of 2047-06-30} {
+ clock format 2445510896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2047 12:34:56 die xxx mensis vi annoque mmxlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2468892 06 vi 6 06/30/2047 die xxx mensis vi annoque mmxlvii 47 xlvii 2047}
+test clock-2.2173 {conversion of 2047-07-01} {
+ clock format 2445597296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2047 12:34:56 die i mensis vii annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2468893 07 vii 7 07/01/2047 die i mensis vii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2174 {conversion of 2047-07-31} {
+ clock format 2448189296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2047 12:34:56 die xxxi mensis vii annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2468923 07 vii 7 07/31/2047 die xxxi mensis vii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2175 {conversion of 2047-08-01} {
+ clock format 2448275696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2047 12:34:56 die i mensis viii annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2468924 08 viii 8 08/01/2047 die i mensis viii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2176 {conversion of 2047-08-31} {
+ clock format 2450867696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2047 12:34:56 die xxxi mensis viii annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2468954 08 viii 8 08/31/2047 die xxxi mensis viii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2177 {conversion of 2047-09-01} {
+ clock format 2450954096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2047 12:34:56 die i mensis ix annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2468955 09 ix 9 09/01/2047 die i mensis ix annoque mmxlvii 47 xlvii 2047}
+test clock-2.2178 {conversion of 2047-09-30} {
+ clock format 2453459696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2047 12:34:56 die xxx mensis ix annoque mmxlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2468984 09 ix 9 09/30/2047 die xxx mensis ix annoque mmxlvii 47 xlvii 2047}
+test clock-2.2179 {conversion of 2047-10-01} {
+ clock format 2453546096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2047 12:34:56 die i mensis x annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2468985 10 x 10 10/01/2047 die i mensis x annoque mmxlvii 47 xlvii 2047}
+test clock-2.2180 {conversion of 2047-10-31} {
+ clock format 2456138096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2047 12:34:56 die xxxi mensis x annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2469015 10 x 10 10/31/2047 die xxxi mensis x annoque mmxlvii 47 xlvii 2047}
+test clock-2.2181 {conversion of 2047-11-01} {
+ clock format 2456224496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2047 12:34:56 die i mensis xi annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2469016 11 xi 11 11/01/2047 die i mensis xi annoque mmxlvii 47 xlvii 2047}
+test clock-2.2182 {conversion of 2047-11-30} {
+ clock format 2458730096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2047 12:34:56 die xxx mensis xi annoque mmxlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2469045 11 xi 11 11/30/2047 die xxx mensis xi annoque mmxlvii 47 xlvii 2047}
+test clock-2.2183 {conversion of 2047-12-01} {
+ clock format 2458816496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2047 12:34:56 die i mensis xii annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2469046 12 xii 12 12/01/2047 die i mensis xii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2184 {conversion of 2047-12-31} {
+ clock format 2461408496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2047 12:34:56 die xxxi mensis xii annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2469076 12 xii 12 12/31/2047 die xxxi mensis xii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2185 {conversion of 2048-01-01} {
+ clock format 2461494896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2048 12:34:56 die i mensis i annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2469077 01 i 1 01/01/2048 die i mensis i annoque mmxlviii 48 xlviii 2048}
+test clock-2.2186 {conversion of 2048-01-31} {
+ clock format 2464086896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2048 12:34:56 die xxxi mensis i annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2469107 01 i 1 01/31/2048 die xxxi mensis i annoque mmxlviii 48 xlviii 2048}
+test clock-2.2187 {conversion of 2048-02-01} {
+ clock format 2464173296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2048 12:34:56 die i mensis ii annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2469108 02 ii 2 02/01/2048 die i mensis ii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2188 {conversion of 2048-02-29} {
+ clock format 2466592496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2048 12:34:56 die xxix mensis ii annoque mmxlviii xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2469136 02 ii 2 02/29/2048 die xxix mensis ii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2189 {conversion of 2048-03-01} {
+ clock format 2466678896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2048 12:34:56 die i mensis iii annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2469137 03 iii 3 03/01/2048 die i mensis iii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2190 {conversion of 2048-03-31} {
+ clock format 2469270896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2048 12:34:56 die xxxi mensis iii annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2469167 03 iii 3 03/31/2048 die xxxi mensis iii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2191 {conversion of 2048-04-01} {
+ clock format 2469357296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2048 12:34:56 die i mensis iv annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2469168 04 iv 4 04/01/2048 die i mensis iv annoque mmxlviii 48 xlviii 2048}
+test clock-2.2192 {conversion of 2048-04-30} {
+ clock format 2471862896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2048 12:34:56 die xxx mensis iv annoque mmxlviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2469197 04 iv 4 04/30/2048 die xxx mensis iv annoque mmxlviii 48 xlviii 2048}
+test clock-2.2193 {conversion of 2048-05-01} {
+ clock format 2471949296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2048 12:34:56 die i mensis v annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2469198 05 v 5 05/01/2048 die i mensis v annoque mmxlviii 48 xlviii 2048}
+test clock-2.2194 {conversion of 2048-05-31} {
+ clock format 2474541296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2048 12:34:56 die xxxi mensis v annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2469228 05 v 5 05/31/2048 die xxxi mensis v annoque mmxlviii 48 xlviii 2048}
+test clock-2.2195 {conversion of 2048-06-01} {
+ clock format 2474627696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2048 12:34:56 die i mensis vi annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2469229 06 vi 6 06/01/2048 die i mensis vi annoque mmxlviii 48 xlviii 2048}
+test clock-2.2196 {conversion of 2048-06-30} {
+ clock format 2477133296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2048 12:34:56 die xxx mensis vi annoque mmxlviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2469258 06 vi 6 06/30/2048 die xxx mensis vi annoque mmxlviii 48 xlviii 2048}
+test clock-2.2197 {conversion of 2048-07-01} {
+ clock format 2477219696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2048 12:34:56 die i mensis vii annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2469259 07 vii 7 07/01/2048 die i mensis vii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2198 {conversion of 2048-07-31} {
+ clock format 2479811696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2048 12:34:56 die xxxi mensis vii annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2469289 07 vii 7 07/31/2048 die xxxi mensis vii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2199 {conversion of 2048-08-01} {
+ clock format 2479898096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2048 12:34:56 die i mensis viii annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2469290 08 viii 8 08/01/2048 die i mensis viii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2200 {conversion of 2048-08-31} {
+ clock format 2482490096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2048 12:34:56 die xxxi mensis viii annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2469320 08 viii 8 08/31/2048 die xxxi mensis viii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2201 {conversion of 2048-09-01} {
+ clock format 2482576496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2048 12:34:56 die i mensis ix annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2469321 09 ix 9 09/01/2048 die i mensis ix annoque mmxlviii 48 xlviii 2048}
+test clock-2.2202 {conversion of 2048-09-30} {
+ clock format 2485082096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2048 12:34:56 die xxx mensis ix annoque mmxlviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2469350 09 ix 9 09/30/2048 die xxx mensis ix annoque mmxlviii 48 xlviii 2048}
+test clock-2.2203 {conversion of 2048-10-01} {
+ clock format 2485168496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2048 12:34:56 die i mensis x annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2469351 10 x 10 10/01/2048 die i mensis x annoque mmxlviii 48 xlviii 2048}
+test clock-2.2204 {conversion of 2048-10-31} {
+ clock format 2487760496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2048 12:34:56 die xxxi mensis x annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2469381 10 x 10 10/31/2048 die xxxi mensis x annoque mmxlviii 48 xlviii 2048}
+test clock-2.2205 {conversion of 2048-11-01} {
+ clock format 2487846896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2048 12:34:56 die i mensis xi annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2469382 11 xi 11 11/01/2048 die i mensis xi annoque mmxlviii 48 xlviii 2048}
+test clock-2.2206 {conversion of 2048-11-30} {
+ clock format 2490352496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2048 12:34:56 die xxx mensis xi annoque mmxlviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2469411 11 xi 11 11/30/2048 die xxx mensis xi annoque mmxlviii 48 xlviii 2048}
+test clock-2.2207 {conversion of 2048-12-01} {
+ clock format 2490438896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2048 12:34:56 die i mensis xii annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2469412 12 xii 12 12/01/2048 die i mensis xii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2208 {conversion of 2048-12-31} {
+ clock format 2493030896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2048 12:34:56 die xxxi mensis xii annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2469442 12 xii 12 12/31/2048 die xxxi mensis xii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2209 {conversion of 2049-01-01} {
+ clock format 2493117296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2049 12:34:56 die i mensis i annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2469443 01 i 1 01/01/2049 die i mensis i annoque mmxlix 49 xlix 2049}
+test clock-2.2210 {conversion of 2049-01-31} {
+ clock format 2495709296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2049 12:34:56 die xxxi mensis i annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2469473 01 i 1 01/31/2049 die xxxi mensis i annoque mmxlix 49 xlix 2049}
+test clock-2.2211 {conversion of 2049-02-01} {
+ clock format 2495795696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2049 12:34:56 die i mensis ii annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2469474 02 ii 2 02/01/2049 die i mensis ii annoque mmxlix 49 xlix 2049}
+test clock-2.2212 {conversion of 2049-02-28} {
+ clock format 2498128496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2049 12:34:56 die xxviii mensis ii annoque mmxlix xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2469501 02 ii 2 02/28/2049 die xxviii mensis ii annoque mmxlix 49 xlix 2049}
+test clock-2.2213 {conversion of 2049-03-01} {
+ clock format 2498214896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2049 12:34:56 die i mensis iii annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2469502 03 iii 3 03/01/2049 die i mensis iii annoque mmxlix 49 xlix 2049}
+test clock-2.2214 {conversion of 2049-03-31} {
+ clock format 2500806896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2049 12:34:56 die xxxi mensis iii annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2469532 03 iii 3 03/31/2049 die xxxi mensis iii annoque mmxlix 49 xlix 2049}
+test clock-2.2215 {conversion of 2049-04-01} {
+ clock format 2500893296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2049 12:34:56 die i mensis iv annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2469533 04 iv 4 04/01/2049 die i mensis iv annoque mmxlix 49 xlix 2049}
+test clock-2.2216 {conversion of 2049-04-30} {
+ clock format 2503398896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2049 12:34:56 die xxx mensis iv annoque mmxlix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2469562 04 iv 4 04/30/2049 die xxx mensis iv annoque mmxlix 49 xlix 2049}
+test clock-2.2217 {conversion of 2049-05-01} {
+ clock format 2503485296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2049 12:34:56 die i mensis v annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2469563 05 v 5 05/01/2049 die i mensis v annoque mmxlix 49 xlix 2049}
+test clock-2.2218 {conversion of 2049-05-31} {
+ clock format 2506077296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2049 12:34:56 die xxxi mensis v annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2469593 05 v 5 05/31/2049 die xxxi mensis v annoque mmxlix 49 xlix 2049}
+test clock-2.2219 {conversion of 2049-06-01} {
+ clock format 2506163696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2049 12:34:56 die i mensis vi annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2469594 06 vi 6 06/01/2049 die i mensis vi annoque mmxlix 49 xlix 2049}
+test clock-2.2220 {conversion of 2049-06-30} {
+ clock format 2508669296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2049 12:34:56 die xxx mensis vi annoque mmxlix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2469623 06 vi 6 06/30/2049 die xxx mensis vi annoque mmxlix 49 xlix 2049}
+test clock-2.2221 {conversion of 2049-07-01} {
+ clock format 2508755696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2049 12:34:56 die i mensis vii annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2469624 07 vii 7 07/01/2049 die i mensis vii annoque mmxlix 49 xlix 2049}
+test clock-2.2222 {conversion of 2049-07-31} {
+ clock format 2511347696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2049 12:34:56 die xxxi mensis vii annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2469654 07 vii 7 07/31/2049 die xxxi mensis vii annoque mmxlix 49 xlix 2049}
+test clock-2.2223 {conversion of 2049-08-01} {
+ clock format 2511434096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2049 12:34:56 die i mensis viii annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2469655 08 viii 8 08/01/2049 die i mensis viii annoque mmxlix 49 xlix 2049}
+test clock-2.2224 {conversion of 2049-08-31} {
+ clock format 2514026096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2049 12:34:56 die xxxi mensis viii annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2469685 08 viii 8 08/31/2049 die xxxi mensis viii annoque mmxlix 49 xlix 2049}
+test clock-2.2225 {conversion of 2049-09-01} {
+ clock format 2514112496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2049 12:34:56 die i mensis ix annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2469686 09 ix 9 09/01/2049 die i mensis ix annoque mmxlix 49 xlix 2049}
+test clock-2.2226 {conversion of 2049-09-30} {
+ clock format 2516618096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2049 12:34:56 die xxx mensis ix annoque mmxlix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2469715 09 ix 9 09/30/2049 die xxx mensis ix annoque mmxlix 49 xlix 2049}
+test clock-2.2227 {conversion of 2049-10-01} {
+ clock format 2516704496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2049 12:34:56 die i mensis x annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2469716 10 x 10 10/01/2049 die i mensis x annoque mmxlix 49 xlix 2049}
+test clock-2.2228 {conversion of 2049-10-31} {
+ clock format 2519296496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2049 12:34:56 die xxxi mensis x annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2469746 10 x 10 10/31/2049 die xxxi mensis x annoque mmxlix 49 xlix 2049}
+test clock-2.2229 {conversion of 2049-11-01} {
+ clock format 2519382896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2049 12:34:56 die i mensis xi annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2469747 11 xi 11 11/01/2049 die i mensis xi annoque mmxlix 49 xlix 2049}
+test clock-2.2230 {conversion of 2049-11-30} {
+ clock format 2521888496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2049 12:34:56 die xxx mensis xi annoque mmxlix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2469776 11 xi 11 11/30/2049 die xxx mensis xi annoque mmxlix 49 xlix 2049}
+test clock-2.2231 {conversion of 2049-12-01} {
+ clock format 2521974896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2049 12:34:56 die i mensis xii annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2469777 12 xii 12 12/01/2049 die i mensis xii annoque mmxlix 49 xlix 2049}
+test clock-2.2232 {conversion of 2049-12-31} {
+ clock format 2524566896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2049 12:34:56 die xxxi mensis xii annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2469807 12 xii 12 12/31/2049 die xxxi mensis xii annoque mmxlix 49 xlix 2049}
+test clock-2.2233 {conversion of 2052-01-01} {
+ clock format 2587725296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2052 12:34:56 die i mensis i annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2470538 01 i 1 01/01/2052 die i mensis i annoque mmlii 52 lii 2052}
+test clock-2.2234 {conversion of 2052-01-31} {
+ clock format 2590317296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2052 12:34:56 die xxxi mensis i annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2470568 01 i 1 01/31/2052 die xxxi mensis i annoque mmlii 52 lii 2052}
+test clock-2.2235 {conversion of 2052-02-01} {
+ clock format 2590403696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2052 12:34:56 die i mensis ii annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2470569 02 ii 2 02/01/2052 die i mensis ii annoque mmlii 52 lii 2052}
+test clock-2.2236 {conversion of 2052-02-29} {
+ clock format 2592822896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2052 12:34:56 die xxix mensis ii annoque mmlii xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2470597 02 ii 2 02/29/2052 die xxix mensis ii annoque mmlii 52 lii 2052}
+test clock-2.2237 {conversion of 2052-03-01} {
+ clock format 2592909296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2052 12:34:56 die i mensis iii annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2470598 03 iii 3 03/01/2052 die i mensis iii annoque mmlii 52 lii 2052}
+test clock-2.2238 {conversion of 2052-03-31} {
+ clock format 2595501296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2052 12:34:56 die xxxi mensis iii annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2470628 03 iii 3 03/31/2052 die xxxi mensis iii annoque mmlii 52 lii 2052}
+test clock-2.2239 {conversion of 2052-04-01} {
+ clock format 2595587696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2052 12:34:56 die i mensis iv annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2470629 04 iv 4 04/01/2052 die i mensis iv annoque mmlii 52 lii 2052}
+test clock-2.2240 {conversion of 2052-04-30} {
+ clock format 2598093296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2052 12:34:56 die xxx mensis iv annoque mmlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2470658 04 iv 4 04/30/2052 die xxx mensis iv annoque mmlii 52 lii 2052}
+test clock-2.2241 {conversion of 2052-05-01} {
+ clock format 2598179696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2052 12:34:56 die i mensis v annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2470659 05 v 5 05/01/2052 die i mensis v annoque mmlii 52 lii 2052}
+test clock-2.2242 {conversion of 2052-05-31} {
+ clock format 2600771696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2052 12:34:56 die xxxi mensis v annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2470689 05 v 5 05/31/2052 die xxxi mensis v annoque mmlii 52 lii 2052}
+test clock-2.2243 {conversion of 2052-06-01} {
+ clock format 2600858096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2052 12:34:56 die i mensis vi annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2470690 06 vi 6 06/01/2052 die i mensis vi annoque mmlii 52 lii 2052}
+test clock-2.2244 {conversion of 2052-06-30} {
+ clock format 2603363696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2052 12:34:56 die xxx mensis vi annoque mmlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2470719 06 vi 6 06/30/2052 die xxx mensis vi annoque mmlii 52 lii 2052}
+test clock-2.2245 {conversion of 2052-07-01} {
+ clock format 2603450096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2052 12:34:56 die i mensis vii annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2470720 07 vii 7 07/01/2052 die i mensis vii annoque mmlii 52 lii 2052}
+test clock-2.2246 {conversion of 2052-07-31} {
+ clock format 2606042096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2052 12:34:56 die xxxi mensis vii annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2470750 07 vii 7 07/31/2052 die xxxi mensis vii annoque mmlii 52 lii 2052}
+test clock-2.2247 {conversion of 2052-08-01} {
+ clock format 2606128496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2052 12:34:56 die i mensis viii annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2470751 08 viii 8 08/01/2052 die i mensis viii annoque mmlii 52 lii 2052}
+test clock-2.2248 {conversion of 2052-08-31} {
+ clock format 2608720496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2052 12:34:56 die xxxi mensis viii annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2470781 08 viii 8 08/31/2052 die xxxi mensis viii annoque mmlii 52 lii 2052}
+test clock-2.2249 {conversion of 2052-09-01} {
+ clock format 2608806896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2052 12:34:56 die i mensis ix annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2470782 09 ix 9 09/01/2052 die i mensis ix annoque mmlii 52 lii 2052}
+test clock-2.2250 {conversion of 2052-09-30} {
+ clock format 2611312496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2052 12:34:56 die xxx mensis ix annoque mmlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2470811 09 ix 9 09/30/2052 die xxx mensis ix annoque mmlii 52 lii 2052}
+test clock-2.2251 {conversion of 2052-10-01} {
+ clock format 2611398896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2052 12:34:56 die i mensis x annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2470812 10 x 10 10/01/2052 die i mensis x annoque mmlii 52 lii 2052}
+test clock-2.2252 {conversion of 2052-10-31} {
+ clock format 2613990896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2052 12:34:56 die xxxi mensis x annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2470842 10 x 10 10/31/2052 die xxxi mensis x annoque mmlii 52 lii 2052}
+test clock-2.2253 {conversion of 2052-11-01} {
+ clock format 2614077296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2052 12:34:56 die i mensis xi annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2470843 11 xi 11 11/01/2052 die i mensis xi annoque mmlii 52 lii 2052}
+test clock-2.2254 {conversion of 2052-11-30} {
+ clock format 2616582896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2052 12:34:56 die xxx mensis xi annoque mmlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2470872 11 xi 11 11/30/2052 die xxx mensis xi annoque mmlii 52 lii 2052}
+test clock-2.2255 {conversion of 2052-12-01} {
+ clock format 2616669296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2052 12:34:56 die i mensis xii annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2470873 12 xii 12 12/01/2052 die i mensis xii annoque mmlii 52 lii 2052}
+test clock-2.2256 {conversion of 2052-12-31} {
+ clock format 2619261296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2052 12:34:56 die xxxi mensis xii annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2470903 12 xii 12 12/31/2052 die xxxi mensis xii annoque mmlii 52 lii 2052}
+test clock-2.2257 {conversion of 2053-01-01} {
+ clock format 2619347696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2053 12:34:56 die i mensis i annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2470904 01 i 1 01/01/2053 die i mensis i annoque mmliii 53 liii 2053}
+test clock-2.2258 {conversion of 2053-01-31} {
+ clock format 2621939696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2053 12:34:56 die xxxi mensis i annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2470934 01 i 1 01/31/2053 die xxxi mensis i annoque mmliii 53 liii 2053}
+test clock-2.2259 {conversion of 2053-02-01} {
+ clock format 2622026096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2053 12:34:56 die i mensis ii annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2470935 02 ii 2 02/01/2053 die i mensis ii annoque mmliii 53 liii 2053}
+test clock-2.2260 {conversion of 2053-02-28} {
+ clock format 2624358896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2053 12:34:56 die xxviii mensis ii annoque mmliii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2470962 02 ii 2 02/28/2053 die xxviii mensis ii annoque mmliii 53 liii 2053}
+test clock-2.2261 {conversion of 2053-03-01} {
+ clock format 2624445296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2053 12:34:56 die i mensis iii annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2470963 03 iii 3 03/01/2053 die i mensis iii annoque mmliii 53 liii 2053}
+test clock-2.2262 {conversion of 2053-03-31} {
+ clock format 2627037296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2053 12:34:56 die xxxi mensis iii annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2470993 03 iii 3 03/31/2053 die xxxi mensis iii annoque mmliii 53 liii 2053}
+test clock-2.2263 {conversion of 2053-04-01} {
+ clock format 2627123696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2053 12:34:56 die i mensis iv annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2470994 04 iv 4 04/01/2053 die i mensis iv annoque mmliii 53 liii 2053}
+test clock-2.2264 {conversion of 2053-04-30} {
+ clock format 2629629296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2053 12:34:56 die xxx mensis iv annoque mmliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2471023 04 iv 4 04/30/2053 die xxx mensis iv annoque mmliii 53 liii 2053}
+test clock-2.2265 {conversion of 2053-05-01} {
+ clock format 2629715696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2053 12:34:56 die i mensis v annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2471024 05 v 5 05/01/2053 die i mensis v annoque mmliii 53 liii 2053}
+test clock-2.2266 {conversion of 2053-05-31} {
+ clock format 2632307696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2053 12:34:56 die xxxi mensis v annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2471054 05 v 5 05/31/2053 die xxxi mensis v annoque mmliii 53 liii 2053}
+test clock-2.2267 {conversion of 2053-06-01} {
+ clock format 2632394096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2053 12:34:56 die i mensis vi annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2471055 06 vi 6 06/01/2053 die i mensis vi annoque mmliii 53 liii 2053}
+test clock-2.2268 {conversion of 2053-06-30} {
+ clock format 2634899696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2053 12:34:56 die xxx mensis vi annoque mmliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2471084 06 vi 6 06/30/2053 die xxx mensis vi annoque mmliii 53 liii 2053}
+test clock-2.2269 {conversion of 2053-07-01} {
+ clock format 2634986096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2053 12:34:56 die i mensis vii annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2471085 07 vii 7 07/01/2053 die i mensis vii annoque mmliii 53 liii 2053}
+test clock-2.2270 {conversion of 2053-07-31} {
+ clock format 2637578096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2053 12:34:56 die xxxi mensis vii annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2471115 07 vii 7 07/31/2053 die xxxi mensis vii annoque mmliii 53 liii 2053}
+test clock-2.2271 {conversion of 2053-08-01} {
+ clock format 2637664496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2053 12:34:56 die i mensis viii annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2471116 08 viii 8 08/01/2053 die i mensis viii annoque mmliii 53 liii 2053}
+test clock-2.2272 {conversion of 2053-08-31} {
+ clock format 2640256496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2053 12:34:56 die xxxi mensis viii annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2471146 08 viii 8 08/31/2053 die xxxi mensis viii annoque mmliii 53 liii 2053}
+test clock-2.2273 {conversion of 2053-09-01} {
+ clock format 2640342896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2053 12:34:56 die i mensis ix annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2471147 09 ix 9 09/01/2053 die i mensis ix annoque mmliii 53 liii 2053}
+test clock-2.2274 {conversion of 2053-09-30} {
+ clock format 2642848496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2053 12:34:56 die xxx mensis ix annoque mmliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2471176 09 ix 9 09/30/2053 die xxx mensis ix annoque mmliii 53 liii 2053}
+test clock-2.2275 {conversion of 2053-10-01} {
+ clock format 2642934896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2053 12:34:56 die i mensis x annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2471177 10 x 10 10/01/2053 die i mensis x annoque mmliii 53 liii 2053}
+test clock-2.2276 {conversion of 2053-10-31} {
+ clock format 2645526896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2053 12:34:56 die xxxi mensis x annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2471207 10 x 10 10/31/2053 die xxxi mensis x annoque mmliii 53 liii 2053}
+test clock-2.2277 {conversion of 2053-11-01} {
+ clock format 2645613296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2053 12:34:56 die i mensis xi annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2471208 11 xi 11 11/01/2053 die i mensis xi annoque mmliii 53 liii 2053}
+test clock-2.2278 {conversion of 2053-11-30} {
+ clock format 2648118896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2053 12:34:56 die xxx mensis xi annoque mmliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2471237 11 xi 11 11/30/2053 die xxx mensis xi annoque mmliii 53 liii 2053}
+test clock-2.2279 {conversion of 2053-12-01} {
+ clock format 2648205296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2053 12:34:56 die i mensis xii annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2471238 12 xii 12 12/01/2053 die i mensis xii annoque mmliii 53 liii 2053}
+test clock-2.2280 {conversion of 2053-12-31} {
+ clock format 2650797296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2053 12:34:56 die xxxi mensis xii annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2471268 12 xii 12 12/31/2053 die xxxi mensis xii annoque mmliii 53 liii 2053}
+test clock-2.2281 {conversion of 2056-01-01} {
+ clock format 2713955696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2056 12:34:56 die i mensis i annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2471999 01 i 1 01/01/2056 die i mensis i annoque mmlvi 56 lvi 2056}
+test clock-2.2282 {conversion of 2056-01-31} {
+ clock format 2716547696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2056 12:34:56 die xxxi mensis i annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2472029 01 i 1 01/31/2056 die xxxi mensis i annoque mmlvi 56 lvi 2056}
+test clock-2.2283 {conversion of 2056-02-01} {
+ clock format 2716634096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2056 12:34:56 die i mensis ii annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2472030 02 ii 2 02/01/2056 die i mensis ii annoque mmlvi 56 lvi 2056}
+test clock-2.2284 {conversion of 2056-02-29} {
+ clock format 2719053296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2056 12:34:56 die xxix mensis ii annoque mmlvi xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2472058 02 ii 2 02/29/2056 die xxix mensis ii annoque mmlvi 56 lvi 2056}
+test clock-2.2285 {conversion of 2056-03-01} {
+ clock format 2719139696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2056 12:34:56 die i mensis iii annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2472059 03 iii 3 03/01/2056 die i mensis iii annoque mmlvi 56 lvi 2056}
+test clock-2.2286 {conversion of 2056-03-31} {
+ clock format 2721731696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2056 12:34:56 die xxxi mensis iii annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2472089 03 iii 3 03/31/2056 die xxxi mensis iii annoque mmlvi 56 lvi 2056}
+test clock-2.2287 {conversion of 2056-04-01} {
+ clock format 2721818096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2056 12:34:56 die i mensis iv annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2472090 04 iv 4 04/01/2056 die i mensis iv annoque mmlvi 56 lvi 2056}
+test clock-2.2288 {conversion of 2056-04-30} {
+ clock format 2724323696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2056 12:34:56 die xxx mensis iv annoque mmlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2472119 04 iv 4 04/30/2056 die xxx mensis iv annoque mmlvi 56 lvi 2056}
+test clock-2.2289 {conversion of 2056-05-01} {
+ clock format 2724410096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2056 12:34:56 die i mensis v annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2472120 05 v 5 05/01/2056 die i mensis v annoque mmlvi 56 lvi 2056}
+test clock-2.2290 {conversion of 2056-05-31} {
+ clock format 2727002096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2056 12:34:56 die xxxi mensis v annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2472150 05 v 5 05/31/2056 die xxxi mensis v annoque mmlvi 56 lvi 2056}
+test clock-2.2291 {conversion of 2056-06-01} {
+ clock format 2727088496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2056 12:34:56 die i mensis vi annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2472151 06 vi 6 06/01/2056 die i mensis vi annoque mmlvi 56 lvi 2056}
+test clock-2.2292 {conversion of 2056-06-30} {
+ clock format 2729594096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2056 12:34:56 die xxx mensis vi annoque mmlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2472180 06 vi 6 06/30/2056 die xxx mensis vi annoque mmlvi 56 lvi 2056}
+test clock-2.2293 {conversion of 2056-07-01} {
+ clock format 2729680496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2056 12:34:56 die i mensis vii annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2472181 07 vii 7 07/01/2056 die i mensis vii annoque mmlvi 56 lvi 2056}
+test clock-2.2294 {conversion of 2056-07-31} {
+ clock format 2732272496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2056 12:34:56 die xxxi mensis vii annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2472211 07 vii 7 07/31/2056 die xxxi mensis vii annoque mmlvi 56 lvi 2056}
+test clock-2.2295 {conversion of 2056-08-01} {
+ clock format 2732358896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2056 12:34:56 die i mensis viii annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2472212 08 viii 8 08/01/2056 die i mensis viii annoque mmlvi 56 lvi 2056}
+test clock-2.2296 {conversion of 2056-08-31} {
+ clock format 2734950896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2056 12:34:56 die xxxi mensis viii annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2472242 08 viii 8 08/31/2056 die xxxi mensis viii annoque mmlvi 56 lvi 2056}
+test clock-2.2297 {conversion of 2056-09-01} {
+ clock format 2735037296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2056 12:34:56 die i mensis ix annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2472243 09 ix 9 09/01/2056 die i mensis ix annoque mmlvi 56 lvi 2056}
+test clock-2.2298 {conversion of 2056-09-30} {
+ clock format 2737542896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2056 12:34:56 die xxx mensis ix annoque mmlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2472272 09 ix 9 09/30/2056 die xxx mensis ix annoque mmlvi 56 lvi 2056}
+test clock-2.2299 {conversion of 2056-10-01} {
+ clock format 2737629296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2056 12:34:56 die i mensis x annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2472273 10 x 10 10/01/2056 die i mensis x annoque mmlvi 56 lvi 2056}
+test clock-2.2300 {conversion of 2056-10-31} {
+ clock format 2740221296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2056 12:34:56 die xxxi mensis x annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2472303 10 x 10 10/31/2056 die xxxi mensis x annoque mmlvi 56 lvi 2056}
+test clock-2.2301 {conversion of 2056-11-01} {
+ clock format 2740307696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2056 12:34:56 die i mensis xi annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2472304 11 xi 11 11/01/2056 die i mensis xi annoque mmlvi 56 lvi 2056}
+test clock-2.2302 {conversion of 2056-11-30} {
+ clock format 2742813296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2056 12:34:56 die xxx mensis xi annoque mmlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2472333 11 xi 11 11/30/2056 die xxx mensis xi annoque mmlvi 56 lvi 2056}
+test clock-2.2303 {conversion of 2056-12-01} {
+ clock format 2742899696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2056 12:34:56 die i mensis xii annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2472334 12 xii 12 12/01/2056 die i mensis xii annoque mmlvi 56 lvi 2056}
+test clock-2.2304 {conversion of 2056-12-31} {
+ clock format 2745491696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2056 12:34:56 die xxxi mensis xii annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2472364 12 xii 12 12/31/2056 die xxxi mensis xii annoque mmlvi 56 lvi 2056}
+test clock-2.2305 {conversion of 2057-01-01} {
+ clock format 2745578096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2057 12:34:56 die i mensis i annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2472365 01 i 1 01/01/2057 die i mensis i annoque mmlvii 57 lvii 2057}
+test clock-2.2306 {conversion of 2057-01-31} {
+ clock format 2748170096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2057 12:34:56 die xxxi mensis i annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2472395 01 i 1 01/31/2057 die xxxi mensis i annoque mmlvii 57 lvii 2057}
+test clock-2.2307 {conversion of 2057-02-01} {
+ clock format 2748256496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2057 12:34:56 die i mensis ii annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2472396 02 ii 2 02/01/2057 die i mensis ii annoque mmlvii 57 lvii 2057}
+test clock-2.2308 {conversion of 2057-02-28} {
+ clock format 2750589296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2057 12:34:56 die xxviii mensis ii annoque mmlvii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2472423 02 ii 2 02/28/2057 die xxviii mensis ii annoque mmlvii 57 lvii 2057}
+test clock-2.2309 {conversion of 2057-03-01} {
+ clock format 2750675696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2057 12:34:56 die i mensis iii annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2472424 03 iii 3 03/01/2057 die i mensis iii annoque mmlvii 57 lvii 2057}
+test clock-2.2310 {conversion of 2057-03-31} {
+ clock format 2753267696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2057 12:34:56 die xxxi mensis iii annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2472454 03 iii 3 03/31/2057 die xxxi mensis iii annoque mmlvii 57 lvii 2057}
+test clock-2.2311 {conversion of 2057-04-01} {
+ clock format 2753354096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2057 12:34:56 die i mensis iv annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2472455 04 iv 4 04/01/2057 die i mensis iv annoque mmlvii 57 lvii 2057}
+test clock-2.2312 {conversion of 2057-04-30} {
+ clock format 2755859696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2057 12:34:56 die xxx mensis iv annoque mmlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2472484 04 iv 4 04/30/2057 die xxx mensis iv annoque mmlvii 57 lvii 2057}
+test clock-2.2313 {conversion of 2057-05-01} {
+ clock format 2755946096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2057 12:34:56 die i mensis v annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2472485 05 v 5 05/01/2057 die i mensis v annoque mmlvii 57 lvii 2057}
+test clock-2.2314 {conversion of 2057-05-31} {
+ clock format 2758538096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2057 12:34:56 die xxxi mensis v annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2472515 05 v 5 05/31/2057 die xxxi mensis v annoque mmlvii 57 lvii 2057}
+test clock-2.2315 {conversion of 2057-06-01} {
+ clock format 2758624496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2057 12:34:56 die i mensis vi annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2472516 06 vi 6 06/01/2057 die i mensis vi annoque mmlvii 57 lvii 2057}
+test clock-2.2316 {conversion of 2057-06-30} {
+ clock format 2761130096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2057 12:34:56 die xxx mensis vi annoque mmlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2472545 06 vi 6 06/30/2057 die xxx mensis vi annoque mmlvii 57 lvii 2057}
+test clock-2.2317 {conversion of 2057-07-01} {
+ clock format 2761216496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2057 12:34:56 die i mensis vii annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2472546 07 vii 7 07/01/2057 die i mensis vii annoque mmlvii 57 lvii 2057}
+test clock-2.2318 {conversion of 2057-07-31} {
+ clock format 2763808496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2057 12:34:56 die xxxi mensis vii annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2472576 07 vii 7 07/31/2057 die xxxi mensis vii annoque mmlvii 57 lvii 2057}
+test clock-2.2319 {conversion of 2057-08-01} {
+ clock format 2763894896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2057 12:34:56 die i mensis viii annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2472577 08 viii 8 08/01/2057 die i mensis viii annoque mmlvii 57 lvii 2057}
+test clock-2.2320 {conversion of 2057-08-31} {
+ clock format 2766486896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2057 12:34:56 die xxxi mensis viii annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2472607 08 viii 8 08/31/2057 die xxxi mensis viii annoque mmlvii 57 lvii 2057}
+test clock-2.2321 {conversion of 2057-09-01} {
+ clock format 2766573296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2057 12:34:56 die i mensis ix annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2472608 09 ix 9 09/01/2057 die i mensis ix annoque mmlvii 57 lvii 2057}
+test clock-2.2322 {conversion of 2057-09-30} {
+ clock format 2769078896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2057 12:34:56 die xxx mensis ix annoque mmlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2472637 09 ix 9 09/30/2057 die xxx mensis ix annoque mmlvii 57 lvii 2057}
+test clock-2.2323 {conversion of 2057-10-01} {
+ clock format 2769165296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2057 12:34:56 die i mensis x annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2472638 10 x 10 10/01/2057 die i mensis x annoque mmlvii 57 lvii 2057}
+test clock-2.2324 {conversion of 2057-10-31} {
+ clock format 2771757296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2057 12:34:56 die xxxi mensis x annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2472668 10 x 10 10/31/2057 die xxxi mensis x annoque mmlvii 57 lvii 2057}
+test clock-2.2325 {conversion of 2057-11-01} {
+ clock format 2771843696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2057 12:34:56 die i mensis xi annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2472669 11 xi 11 11/01/2057 die i mensis xi annoque mmlvii 57 lvii 2057}
+test clock-2.2326 {conversion of 2057-11-30} {
+ clock format 2774349296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2057 12:34:56 die xxx mensis xi annoque mmlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2472698 11 xi 11 11/30/2057 die xxx mensis xi annoque mmlvii 57 lvii 2057}
+test clock-2.2327 {conversion of 2057-12-01} {
+ clock format 2774435696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2057 12:34:56 die i mensis xii annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2472699 12 xii 12 12/01/2057 die i mensis xii annoque mmlvii 57 lvii 2057}
+test clock-2.2328 {conversion of 2057-12-31} {
+ clock format 2777027696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2057 12:34:56 die xxxi mensis xii annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2472729 12 xii 12 12/31/2057 die xxxi mensis xii annoque mmlvii 57 lvii 2057}
+test clock-2.2329 {conversion of 2060-01-01} {
+ clock format 2840186096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2060 12:34:56 die i mensis i annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2473460 01 i 1 01/01/2060 die i mensis i annoque mmlx 60 lx 2060}
+test clock-2.2330 {conversion of 2060-01-31} {
+ clock format 2842778096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2060 12:34:56 die xxxi mensis i annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2473490 01 i 1 01/31/2060 die xxxi mensis i annoque mmlx 60 lx 2060}
+test clock-2.2331 {conversion of 2060-02-01} {
+ clock format 2842864496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2060 12:34:56 die i mensis ii annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2473491 02 ii 2 02/01/2060 die i mensis ii annoque mmlx 60 lx 2060}
+test clock-2.2332 {conversion of 2060-02-29} {
+ clock format 2845283696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2060 12:34:56 die xxix mensis ii annoque mmlx xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2473519 02 ii 2 02/29/2060 die xxix mensis ii annoque mmlx 60 lx 2060}
+test clock-2.2333 {conversion of 2060-03-01} {
+ clock format 2845370096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2060 12:34:56 die i mensis iii annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2473520 03 iii 3 03/01/2060 die i mensis iii annoque mmlx 60 lx 2060}
+test clock-2.2334 {conversion of 2060-03-31} {
+ clock format 2847962096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2060 12:34:56 die xxxi mensis iii annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2473550 03 iii 3 03/31/2060 die xxxi mensis iii annoque mmlx 60 lx 2060}
+test clock-2.2335 {conversion of 2060-04-01} {
+ clock format 2848048496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2060 12:34:56 die i mensis iv annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2473551 04 iv 4 04/01/2060 die i mensis iv annoque mmlx 60 lx 2060}
+test clock-2.2336 {conversion of 2060-04-30} {
+ clock format 2850554096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2060 12:34:56 die xxx mensis iv annoque mmlx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2473580 04 iv 4 04/30/2060 die xxx mensis iv annoque mmlx 60 lx 2060}
+test clock-2.2337 {conversion of 2060-05-01} {
+ clock format 2850640496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2060 12:34:56 die i mensis v annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2473581 05 v 5 05/01/2060 die i mensis v annoque mmlx 60 lx 2060}
+test clock-2.2338 {conversion of 2060-05-31} {
+ clock format 2853232496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2060 12:34:56 die xxxi mensis v annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2473611 05 v 5 05/31/2060 die xxxi mensis v annoque mmlx 60 lx 2060}
+test clock-2.2339 {conversion of 2060-06-01} {
+ clock format 2853318896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2060 12:34:56 die i mensis vi annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2473612 06 vi 6 06/01/2060 die i mensis vi annoque mmlx 60 lx 2060}
+test clock-2.2340 {conversion of 2060-06-30} {
+ clock format 2855824496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2060 12:34:56 die xxx mensis vi annoque mmlx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2473641 06 vi 6 06/30/2060 die xxx mensis vi annoque mmlx 60 lx 2060}
+test clock-2.2341 {conversion of 2060-07-01} {
+ clock format 2855910896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2060 12:34:56 die i mensis vii annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2473642 07 vii 7 07/01/2060 die i mensis vii annoque mmlx 60 lx 2060}
+test clock-2.2342 {conversion of 2060-07-31} {
+ clock format 2858502896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2060 12:34:56 die xxxi mensis vii annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2473672 07 vii 7 07/31/2060 die xxxi mensis vii annoque mmlx 60 lx 2060}
+test clock-2.2343 {conversion of 2060-08-01} {
+ clock format 2858589296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2060 12:34:56 die i mensis viii annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2473673 08 viii 8 08/01/2060 die i mensis viii annoque mmlx 60 lx 2060}
+test clock-2.2344 {conversion of 2060-08-31} {
+ clock format 2861181296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2060 12:34:56 die xxxi mensis viii annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2473703 08 viii 8 08/31/2060 die xxxi mensis viii annoque mmlx 60 lx 2060}
+test clock-2.2345 {conversion of 2060-09-01} {
+ clock format 2861267696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2060 12:34:56 die i mensis ix annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2473704 09 ix 9 09/01/2060 die i mensis ix annoque mmlx 60 lx 2060}
+test clock-2.2346 {conversion of 2060-09-30} {
+ clock format 2863773296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2060 12:34:56 die xxx mensis ix annoque mmlx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2473733 09 ix 9 09/30/2060 die xxx mensis ix annoque mmlx 60 lx 2060}
+test clock-2.2347 {conversion of 2060-10-01} {
+ clock format 2863859696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2060 12:34:56 die i mensis x annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2473734 10 x 10 10/01/2060 die i mensis x annoque mmlx 60 lx 2060}
+test clock-2.2348 {conversion of 2060-10-31} {
+ clock format 2866451696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2060 12:34:56 die xxxi mensis x annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2473764 10 x 10 10/31/2060 die xxxi mensis x annoque mmlx 60 lx 2060}
+test clock-2.2349 {conversion of 2060-11-01} {
+ clock format 2866538096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2060 12:34:56 die i mensis xi annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2473765 11 xi 11 11/01/2060 die i mensis xi annoque mmlx 60 lx 2060}
+test clock-2.2350 {conversion of 2060-11-30} {
+ clock format 2869043696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2060 12:34:56 die xxx mensis xi annoque mmlx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2473794 11 xi 11 11/30/2060 die xxx mensis xi annoque mmlx 60 lx 2060}
+test clock-2.2351 {conversion of 2060-12-01} {
+ clock format 2869130096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2060 12:34:56 die i mensis xii annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2473795 12 xii 12 12/01/2060 die i mensis xii annoque mmlx 60 lx 2060}
+test clock-2.2352 {conversion of 2060-12-31} {
+ clock format 2871722096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2060 12:34:56 die xxxi mensis xii annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2473825 12 xii 12 12/31/2060 die xxxi mensis xii annoque mmlx 60 lx 2060}
+test clock-2.2353 {conversion of 2061-01-01} {
+ clock format 2871808496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2061 12:34:56 die i mensis i annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2473826 01 i 1 01/01/2061 die i mensis i annoque mmlxi 61 lxi 2061}
+test clock-2.2354 {conversion of 2061-01-31} {
+ clock format 2874400496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2061 12:34:56 die xxxi mensis i annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2473856 01 i 1 01/31/2061 die xxxi mensis i annoque mmlxi 61 lxi 2061}
+test clock-2.2355 {conversion of 2061-02-01} {
+ clock format 2874486896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2061 12:34:56 die i mensis ii annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2473857 02 ii 2 02/01/2061 die i mensis ii annoque mmlxi 61 lxi 2061}
+test clock-2.2356 {conversion of 2061-02-28} {
+ clock format 2876819696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2061 12:34:56 die xxviii mensis ii annoque mmlxi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2473884 02 ii 2 02/28/2061 die xxviii mensis ii annoque mmlxi 61 lxi 2061}
+test clock-2.2357 {conversion of 2061-03-01} {
+ clock format 2876906096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2061 12:34:56 die i mensis iii annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2473885 03 iii 3 03/01/2061 die i mensis iii annoque mmlxi 61 lxi 2061}
+test clock-2.2358 {conversion of 2061-03-31} {
+ clock format 2879498096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2061 12:34:56 die xxxi mensis iii annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2473915 03 iii 3 03/31/2061 die xxxi mensis iii annoque mmlxi 61 lxi 2061}
+test clock-2.2359 {conversion of 2061-04-01} {
+ clock format 2879584496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2061 12:34:56 die i mensis iv annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2473916 04 iv 4 04/01/2061 die i mensis iv annoque mmlxi 61 lxi 2061}
+test clock-2.2360 {conversion of 2061-04-30} {
+ clock format 2882090096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2061 12:34:56 die xxx mensis iv annoque mmlxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2473945 04 iv 4 04/30/2061 die xxx mensis iv annoque mmlxi 61 lxi 2061}
+test clock-2.2361 {conversion of 2061-05-01} {
+ clock format 2882176496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2061 12:34:56 die i mensis v annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2473946 05 v 5 05/01/2061 die i mensis v annoque mmlxi 61 lxi 2061}
+test clock-2.2362 {conversion of 2061-05-31} {
+ clock format 2884768496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2061 12:34:56 die xxxi mensis v annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2473976 05 v 5 05/31/2061 die xxxi mensis v annoque mmlxi 61 lxi 2061}
+test clock-2.2363 {conversion of 2061-06-01} {
+ clock format 2884854896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2061 12:34:56 die i mensis vi annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2473977 06 vi 6 06/01/2061 die i mensis vi annoque mmlxi 61 lxi 2061}
+test clock-2.2364 {conversion of 2061-06-30} {
+ clock format 2887360496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2061 12:34:56 die xxx mensis vi annoque mmlxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2474006 06 vi 6 06/30/2061 die xxx mensis vi annoque mmlxi 61 lxi 2061}
+test clock-2.2365 {conversion of 2061-07-01} {
+ clock format 2887446896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2061 12:34:56 die i mensis vii annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2474007 07 vii 7 07/01/2061 die i mensis vii annoque mmlxi 61 lxi 2061}
+test clock-2.2366 {conversion of 2061-07-31} {
+ clock format 2890038896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2061 12:34:56 die xxxi mensis vii annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2474037 07 vii 7 07/31/2061 die xxxi mensis vii annoque mmlxi 61 lxi 2061}
+test clock-2.2367 {conversion of 2061-08-01} {
+ clock format 2890125296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2061 12:34:56 die i mensis viii annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2474038 08 viii 8 08/01/2061 die i mensis viii annoque mmlxi 61 lxi 2061}
+test clock-2.2368 {conversion of 2061-08-31} {
+ clock format 2892717296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2061 12:34:56 die xxxi mensis viii annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2474068 08 viii 8 08/31/2061 die xxxi mensis viii annoque mmlxi 61 lxi 2061}
+test clock-2.2369 {conversion of 2061-09-01} {
+ clock format 2892803696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2061 12:34:56 die i mensis ix annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2474069 09 ix 9 09/01/2061 die i mensis ix annoque mmlxi 61 lxi 2061}
+test clock-2.2370 {conversion of 2061-09-30} {
+ clock format 2895309296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2061 12:34:56 die xxx mensis ix annoque mmlxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2474098 09 ix 9 09/30/2061 die xxx mensis ix annoque mmlxi 61 lxi 2061}
+test clock-2.2371 {conversion of 2061-10-01} {
+ clock format 2895395696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2061 12:34:56 die i mensis x annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2474099 10 x 10 10/01/2061 die i mensis x annoque mmlxi 61 lxi 2061}
+test clock-2.2372 {conversion of 2061-10-31} {
+ clock format 2897987696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2061 12:34:56 die xxxi mensis x annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2474129 10 x 10 10/31/2061 die xxxi mensis x annoque mmlxi 61 lxi 2061}
+test clock-2.2373 {conversion of 2061-11-01} {
+ clock format 2898074096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2061 12:34:56 die i mensis xi annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2474130 11 xi 11 11/01/2061 die i mensis xi annoque mmlxi 61 lxi 2061}
+test clock-2.2374 {conversion of 2061-11-30} {
+ clock format 2900579696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2061 12:34:56 die xxx mensis xi annoque mmlxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2474159 11 xi 11 11/30/2061 die xxx mensis xi annoque mmlxi 61 lxi 2061}
+test clock-2.2375 {conversion of 2061-12-01} {
+ clock format 2900666096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2061 12:34:56 die i mensis xii annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2474160 12 xii 12 12/01/2061 die i mensis xii annoque mmlxi 61 lxi 2061}
+test clock-2.2376 {conversion of 2061-12-31} {
+ clock format 2903258096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2061 12:34:56 die xxxi mensis xii annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2474190 12 xii 12 12/31/2061 die xxxi mensis xii annoque mmlxi 61 lxi 2061}
+test clock-2.2377 {conversion of 2064-01-01} {
+ clock format 2966416496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2064 12:34:56 die i mensis i annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2474921 01 i 1 01/01/2064 die i mensis i annoque mmlxiv 64 lxiv 2064}
+test clock-2.2378 {conversion of 2064-01-31} {
+ clock format 2969008496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2064 12:34:56 die xxxi mensis i annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2474951 01 i 1 01/31/2064 die xxxi mensis i annoque mmlxiv 64 lxiv 2064}
+test clock-2.2379 {conversion of 2064-02-01} {
+ clock format 2969094896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2064 12:34:56 die i mensis ii annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2474952 02 ii 2 02/01/2064 die i mensis ii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2380 {conversion of 2064-02-29} {
+ clock format 2971514096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2064 12:34:56 die xxix mensis ii annoque mmlxiv xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2474980 02 ii 2 02/29/2064 die xxix mensis ii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2381 {conversion of 2064-03-01} {
+ clock format 2971600496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2064 12:34:56 die i mensis iii annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2474981 03 iii 3 03/01/2064 die i mensis iii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2382 {conversion of 2064-03-31} {
+ clock format 2974192496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2064 12:34:56 die xxxi mensis iii annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2475011 03 iii 3 03/31/2064 die xxxi mensis iii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2383 {conversion of 2064-04-01} {
+ clock format 2974278896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2064 12:34:56 die i mensis iv annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2475012 04 iv 4 04/01/2064 die i mensis iv annoque mmlxiv 64 lxiv 2064}
+test clock-2.2384 {conversion of 2064-04-30} {
+ clock format 2976784496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2064 12:34:56 die xxx mensis iv annoque mmlxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2475041 04 iv 4 04/30/2064 die xxx mensis iv annoque mmlxiv 64 lxiv 2064}
+test clock-2.2385 {conversion of 2064-05-01} {
+ clock format 2976870896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2064 12:34:56 die i mensis v annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2475042 05 v 5 05/01/2064 die i mensis v annoque mmlxiv 64 lxiv 2064}
+test clock-2.2386 {conversion of 2064-05-31} {
+ clock format 2979462896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2064 12:34:56 die xxxi mensis v annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2475072 05 v 5 05/31/2064 die xxxi mensis v annoque mmlxiv 64 lxiv 2064}
+test clock-2.2387 {conversion of 2064-06-01} {
+ clock format 2979549296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2064 12:34:56 die i mensis vi annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2475073 06 vi 6 06/01/2064 die i mensis vi annoque mmlxiv 64 lxiv 2064}
+test clock-2.2388 {conversion of 2064-06-30} {
+ clock format 2982054896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2064 12:34:56 die xxx mensis vi annoque mmlxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2475102 06 vi 6 06/30/2064 die xxx mensis vi annoque mmlxiv 64 lxiv 2064}
+test clock-2.2389 {conversion of 2064-07-01} {
+ clock format 2982141296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2064 12:34:56 die i mensis vii annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2475103 07 vii 7 07/01/2064 die i mensis vii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2390 {conversion of 2064-07-31} {
+ clock format 2984733296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2064 12:34:56 die xxxi mensis vii annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2475133 07 vii 7 07/31/2064 die xxxi mensis vii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2391 {conversion of 2064-08-01} {
+ clock format 2984819696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2064 12:34:56 die i mensis viii annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2475134 08 viii 8 08/01/2064 die i mensis viii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2392 {conversion of 2064-08-31} {
+ clock format 2987411696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2064 12:34:56 die xxxi mensis viii annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2475164 08 viii 8 08/31/2064 die xxxi mensis viii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2393 {conversion of 2064-09-01} {
+ clock format 2987498096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2064 12:34:56 die i mensis ix annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2475165 09 ix 9 09/01/2064 die i mensis ix annoque mmlxiv 64 lxiv 2064}
+test clock-2.2394 {conversion of 2064-09-30} {
+ clock format 2990003696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2064 12:34:56 die xxx mensis ix annoque mmlxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2475194 09 ix 9 09/30/2064 die xxx mensis ix annoque mmlxiv 64 lxiv 2064}
+test clock-2.2395 {conversion of 2064-10-01} {
+ clock format 2990090096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2064 12:34:56 die i mensis x annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2475195 10 x 10 10/01/2064 die i mensis x annoque mmlxiv 64 lxiv 2064}
+test clock-2.2396 {conversion of 2064-10-31} {
+ clock format 2992682096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2064 12:34:56 die xxxi mensis x annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2475225 10 x 10 10/31/2064 die xxxi mensis x annoque mmlxiv 64 lxiv 2064}
+test clock-2.2397 {conversion of 2064-11-01} {
+ clock format 2992768496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2064 12:34:56 die i mensis xi annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2475226 11 xi 11 11/01/2064 die i mensis xi annoque mmlxiv 64 lxiv 2064}
+test clock-2.2398 {conversion of 2064-11-30} {
+ clock format 2995274096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2064 12:34:56 die xxx mensis xi annoque mmlxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2475255 11 xi 11 11/30/2064 die xxx mensis xi annoque mmlxiv 64 lxiv 2064}
+test clock-2.2399 {conversion of 2064-12-01} {
+ clock format 2995360496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2064 12:34:56 die i mensis xii annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2475256 12 xii 12 12/01/2064 die i mensis xii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2400 {conversion of 2064-12-31} {
+ clock format 2997952496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2064 12:34:56 die xxxi mensis xii annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2475286 12 xii 12 12/31/2064 die xxxi mensis xii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2401 {conversion of 2065-01-01} {
+ clock format 2998038896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2065 12:34:56 die i mensis i annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2475287 01 i 1 01/01/2065 die i mensis i annoque mmlxv 65 lxv 2065}
+test clock-2.2402 {conversion of 2065-01-31} {
+ clock format 3000630896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2065 12:34:56 die xxxi mensis i annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2475317 01 i 1 01/31/2065 die xxxi mensis i annoque mmlxv 65 lxv 2065}
+test clock-2.2403 {conversion of 2065-02-01} {
+ clock format 3000717296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2065 12:34:56 die i mensis ii annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2475318 02 ii 2 02/01/2065 die i mensis ii annoque mmlxv 65 lxv 2065}
+test clock-2.2404 {conversion of 2065-02-28} {
+ clock format 3003050096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2065 12:34:56 die xxviii mensis ii annoque mmlxv xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2475345 02 ii 2 02/28/2065 die xxviii mensis ii annoque mmlxv 65 lxv 2065}
+test clock-2.2405 {conversion of 2065-03-01} {
+ clock format 3003136496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2065 12:34:56 die i mensis iii annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2475346 03 iii 3 03/01/2065 die i mensis iii annoque mmlxv 65 lxv 2065}
+test clock-2.2406 {conversion of 2065-03-31} {
+ clock format 3005728496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2065 12:34:56 die xxxi mensis iii annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2475376 03 iii 3 03/31/2065 die xxxi mensis iii annoque mmlxv 65 lxv 2065}
+test clock-2.2407 {conversion of 2065-04-01} {
+ clock format 3005814896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2065 12:34:56 die i mensis iv annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2475377 04 iv 4 04/01/2065 die i mensis iv annoque mmlxv 65 lxv 2065}
+test clock-2.2408 {conversion of 2065-04-30} {
+ clock format 3008320496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2065 12:34:56 die xxx mensis iv annoque mmlxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2475406 04 iv 4 04/30/2065 die xxx mensis iv annoque mmlxv 65 lxv 2065}
+test clock-2.2409 {conversion of 2065-05-01} {
+ clock format 3008406896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2065 12:34:56 die i mensis v annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2475407 05 v 5 05/01/2065 die i mensis v annoque mmlxv 65 lxv 2065}
+test clock-2.2410 {conversion of 2065-05-31} {
+ clock format 3010998896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2065 12:34:56 die xxxi mensis v annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2475437 05 v 5 05/31/2065 die xxxi mensis v annoque mmlxv 65 lxv 2065}
+test clock-2.2411 {conversion of 2065-06-01} {
+ clock format 3011085296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2065 12:34:56 die i mensis vi annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2475438 06 vi 6 06/01/2065 die i mensis vi annoque mmlxv 65 lxv 2065}
+test clock-2.2412 {conversion of 2065-06-30} {
+ clock format 3013590896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2065 12:34:56 die xxx mensis vi annoque mmlxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2475467 06 vi 6 06/30/2065 die xxx mensis vi annoque mmlxv 65 lxv 2065}
+test clock-2.2413 {conversion of 2065-07-01} {
+ clock format 3013677296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2065 12:34:56 die i mensis vii annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2475468 07 vii 7 07/01/2065 die i mensis vii annoque mmlxv 65 lxv 2065}
+test clock-2.2414 {conversion of 2065-07-31} {
+ clock format 3016269296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2065 12:34:56 die xxxi mensis vii annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2475498 07 vii 7 07/31/2065 die xxxi mensis vii annoque mmlxv 65 lxv 2065}
+test clock-2.2415 {conversion of 2065-08-01} {
+ clock format 3016355696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2065 12:34:56 die i mensis viii annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2475499 08 viii 8 08/01/2065 die i mensis viii annoque mmlxv 65 lxv 2065}
+test clock-2.2416 {conversion of 2065-08-31} {
+ clock format 3018947696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2065 12:34:56 die xxxi mensis viii annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2475529 08 viii 8 08/31/2065 die xxxi mensis viii annoque mmlxv 65 lxv 2065}
+test clock-2.2417 {conversion of 2065-09-01} {
+ clock format 3019034096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2065 12:34:56 die i mensis ix annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2475530 09 ix 9 09/01/2065 die i mensis ix annoque mmlxv 65 lxv 2065}
+test clock-2.2418 {conversion of 2065-09-30} {
+ clock format 3021539696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2065 12:34:56 die xxx mensis ix annoque mmlxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2475559 09 ix 9 09/30/2065 die xxx mensis ix annoque mmlxv 65 lxv 2065}
+test clock-2.2419 {conversion of 2065-10-01} {
+ clock format 3021626096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2065 12:34:56 die i mensis x annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2475560 10 x 10 10/01/2065 die i mensis x annoque mmlxv 65 lxv 2065}
+test clock-2.2420 {conversion of 2065-10-31} {
+ clock format 3024218096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2065 12:34:56 die xxxi mensis x annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2475590 10 x 10 10/31/2065 die xxxi mensis x annoque mmlxv 65 lxv 2065}
+test clock-2.2421 {conversion of 2065-11-01} {
+ clock format 3024304496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2065 12:34:56 die i mensis xi annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2475591 11 xi 11 11/01/2065 die i mensis xi annoque mmlxv 65 lxv 2065}
+test clock-2.2422 {conversion of 2065-11-30} {
+ clock format 3026810096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2065 12:34:56 die xxx mensis xi annoque mmlxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2475620 11 xi 11 11/30/2065 die xxx mensis xi annoque mmlxv 65 lxv 2065}
+test clock-2.2423 {conversion of 2065-12-01} {
+ clock format 3026896496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2065 12:34:56 die i mensis xii annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2475621 12 xii 12 12/01/2065 die i mensis xii annoque mmlxv 65 lxv 2065}
+test clock-2.2424 {conversion of 2065-12-31} {
+ clock format 3029488496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2065 12:34:56 die xxxi mensis xii annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2475651 12 xii 12 12/31/2065 die xxxi mensis xii annoque mmlxv 65 lxv 2065}
+# END testcases2
+
+# BEGIN testcases3
+test clock-3.1 {ISO week-based calendar 1871-W52-1} {
+ clock format -3093206400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1871-W52-1
+} {Mon Monday 71 1871 1 52 52 1 52}
+test clock-3.2 {ISO week-based calendar 1871-W52-6} {
+ clock format -3092774400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1871-W52-6
+} {Sat Saturday 71 1871 6 52 52 6 52}
+test clock-3.3 {ISO week-based calendar 1871-W52-7} {
+ clock format -3092688000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1871-W52-7
+} {Sun Sunday 71 1871 7 53 52 0 52}
+test clock-3.4 {ISO week-based calendar 1872-W01-1} {
+ clock format -3092601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W01-1
+} {Mon Monday 72 1872 1 00 01 1 01}
+test clock-3.5 {ISO week-based calendar 1872-W01-6} {
+ clock format -3092169600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W01-6
+} {Sat Saturday 72 1872 6 00 01 6 01}
+test clock-3.6 {ISO week-based calendar 1872-W01-7} {
+ clock format -3092083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W01-7
+} {Sun Sunday 72 1872 7 01 01 0 01}
+test clock-3.7 {ISO week-based calendar 1872-W02-1} {
+ clock format -3091996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W02-1
+} {Mon Monday 72 1872 1 01 02 1 02}
+test clock-3.8 {ISO week-based calendar 1872-W52-1} {
+ clock format -3061756800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W52-1
+} {Mon Monday 72 1872 1 51 52 1 52}
+test clock-3.9 {ISO week-based calendar 1872-W52-6} {
+ clock format -3061324800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W52-6
+} {Sat Saturday 72 1872 6 51 52 6 52}
+test clock-3.10 {ISO week-based calendar 1872-W52-7} {
+ clock format -3061238400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W52-7
+} {Sun Sunday 72 1872 7 52 52 0 52}
+test clock-3.11 {ISO week-based calendar 1873-W01-1} {
+ clock format -3061152000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1873-W01-1
+} {Mon Monday 73 1873 1 52 01 1 53}
+test clock-3.12 {ISO week-based calendar 1873-W01-3} {
+ clock format -3060979200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1873-W01-3
+} {Wed Wednesday 73 1873 3 00 01 3 00}
+test clock-3.13 {ISO week-based calendar 1873-W01-6} {
+ clock format -3060720000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1873-W01-6
+} {Sat Saturday 73 1873 6 00 01 6 00}
+test clock-3.14 {ISO week-based calendar 1873-W01-7} {
+ clock format -3060633600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1873-W01-7
+} {Sun Sunday 73 1873 7 01 01 0 00}
+test clock-3.15 {ISO week-based calendar 1873-W02-1} {
+ clock format -3060547200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1873-W02-1
+} {Mon Monday 73 1873 1 01 02 1 01}
+test clock-3.16 {ISO week-based calendar 1875-W52-1} {
+ clock format -2966803200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1875-W52-1
+} {Mon Monday 75 1875 1 52 52 1 52}
+test clock-3.17 {ISO week-based calendar 1875-W52-6} {
+ clock format -2966371200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1875-W52-6
+} {Sat Saturday 75 1875 6 00 52 6 00}
+test clock-3.18 {ISO week-based calendar 1875-W52-7} {
+ clock format -2966284800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1875-W52-7
+} {Sun Sunday 75 1875 7 01 52 0 00}
+test clock-3.19 {ISO week-based calendar 1876-W01-1} {
+ clock format -2966198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W01-1
+} {Mon Monday 76 1876 1 01 01 1 01}
+test clock-3.20 {ISO week-based calendar 1876-W01-6} {
+ clock format -2965766400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W01-6
+} {Sat Saturday 76 1876 6 01 01 6 01}
+test clock-3.21 {ISO week-based calendar 1876-W01-7} {
+ clock format -2965680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W01-7
+} {Sun Sunday 76 1876 7 02 01 0 01}
+test clock-3.22 {ISO week-based calendar 1876-W02-1} {
+ clock format -2965593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W02-1
+} {Mon Monday 76 1876 1 02 02 1 02}
+test clock-3.23 {ISO week-based calendar 1876-W52-1} {
+ clock format -2935353600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W52-1
+} {Mon Monday 76 1876 1 52 52 1 52}
+test clock-3.24 {ISO week-based calendar 1876-W52-6} {
+ clock format -2934921600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W52-6
+} {Sat Saturday 76 1876 6 52 52 6 52}
+test clock-3.25 {ISO week-based calendar 1876-W52-7} {
+ clock format -2934835200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W52-7
+} {Sun Sunday 76 1876 7 53 52 0 52}
+test clock-3.26 {ISO week-based calendar 1877-W01-1} {
+ clock format -2934748800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1877-W01-1
+} {Mon Monday 77 1877 1 00 01 1 01}
+test clock-3.27 {ISO week-based calendar 1877-W01-6} {
+ clock format -2934316800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1877-W01-6
+} {Sat Saturday 77 1877 6 00 01 6 01}
+test clock-3.28 {ISO week-based calendar 1877-W01-7} {
+ clock format -2934230400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1877-W01-7
+} {Sun Sunday 77 1877 7 01 01 0 01}
+test clock-3.29 {ISO week-based calendar 1877-W02-1} {
+ clock format -2934144000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1877-W02-1
+} {Mon Monday 77 1877 1 01 02 1 02}
+test clock-3.30 {ISO week-based calendar 1879-W52-1} {
+ clock format -2841004800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1879-W52-1
+} {Mon Monday 79 1879 1 51 52 1 51}
+test clock-3.31 {ISO week-based calendar 1879-W52-6} {
+ clock format -2840572800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1879-W52-6
+} {Sat Saturday 79 1879 6 51 52 6 51}
+test clock-3.32 {ISO week-based calendar 1879-W52-7} {
+ clock format -2840486400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1879-W52-7
+} {Sun Sunday 79 1879 7 52 52 0 51}
+test clock-3.33 {ISO week-based calendar 1880-W01-1} {
+ clock format -2840400000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W01-1
+} {Mon Monday 80 1880 1 52 01 1 52}
+test clock-3.34 {ISO week-based calendar 1880-W01-4} {
+ clock format -2840140800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W01-4
+} {Thu Thursday 80 1880 4 00 01 4 00}
+test clock-3.35 {ISO week-based calendar 1880-W01-6} {
+ clock format -2839968000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W01-6
+} {Sat Saturday 80 1880 6 00 01 6 00}
+test clock-3.36 {ISO week-based calendar 1880-W01-7} {
+ clock format -2839881600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W01-7
+} {Sun Sunday 80 1880 7 01 01 0 00}
+test clock-3.37 {ISO week-based calendar 1880-W02-1} {
+ clock format -2839795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W02-1
+} {Mon Monday 80 1880 1 01 02 1 01}
+test clock-3.38 {ISO week-based calendar 1880-W53-1} {
+ clock format -2808950400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W53-1
+} {Mon Monday 80 1880 1 52 53 1 52}
+test clock-3.39 {ISO week-based calendar 1880-W53-6} {
+ clock format -2808518400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W53-6
+} {Sat Saturday 80 1880 6 00 53 6 00}
+test clock-3.40 {ISO week-based calendar 1880-W53-7} {
+ clock format -2808432000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W53-7
+} {Sun Sunday 80 1880 7 01 53 0 00}
+test clock-3.41 {ISO week-based calendar 1881-W01-1} {
+ clock format -2808345600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1881-W01-1
+} {Mon Monday 81 1881 1 01 01 1 01}
+test clock-3.42 {ISO week-based calendar 1881-W01-6} {
+ clock format -2807913600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1881-W01-6
+} {Sat Saturday 81 1881 6 01 01 6 01}
+test clock-3.43 {ISO week-based calendar 1881-W01-7} {
+ clock format -2807827200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1881-W01-7
+} {Sun Sunday 81 1881 7 02 01 0 01}
+test clock-3.44 {ISO week-based calendar 1881-W02-1} {
+ clock format -2807740800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1881-W02-1
+} {Mon Monday 81 1881 1 02 02 1 02}
+test clock-3.45 {ISO week-based calendar 1883-W52-1} {
+ clock format -2714601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1883-W52-1
+} {Mon Monday 83 1883 1 51 52 1 52}
+test clock-3.46 {ISO week-based calendar 1883-W52-6} {
+ clock format -2714169600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1883-W52-6
+} {Sat Saturday 83 1883 6 51 52 6 52}
+test clock-3.47 {ISO week-based calendar 1883-W52-7} {
+ clock format -2714083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1883-W52-7
+} {Sun Sunday 83 1883 7 52 52 0 52}
+test clock-3.48 {ISO week-based calendar 1884-W01-1} {
+ clock format -2713996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W01-1
+} {Mon Monday 84 1884 1 52 01 1 53}
+test clock-3.49 {ISO week-based calendar 1884-W01-2} {
+ clock format -2713910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W01-2
+} {Tue Tuesday 84 1884 2 00 01 2 00}
+test clock-3.50 {ISO week-based calendar 1884-W01-6} {
+ clock format -2713564800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W01-6
+} {Sat Saturday 84 1884 6 00 01 6 00}
+test clock-3.51 {ISO week-based calendar 1884-W01-7} {
+ clock format -2713478400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W01-7
+} {Sun Sunday 84 1884 7 01 01 0 00}
+test clock-3.52 {ISO week-based calendar 1884-W02-1} {
+ clock format -2713392000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W02-1
+} {Mon Monday 84 1884 1 01 02 1 01}
+test clock-3.53 {ISO week-based calendar 1884-W52-1} {
+ clock format -2683152000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W52-1
+} {Mon Monday 84 1884 1 51 52 1 51}
+test clock-3.54 {ISO week-based calendar 1884-W52-6} {
+ clock format -2682720000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W52-6
+} {Sat Saturday 84 1884 6 51 52 6 51}
+test clock-3.55 {ISO week-based calendar 1884-W52-7} {
+ clock format -2682633600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W52-7
+} {Sun Sunday 84 1884 7 52 52 0 51}
+test clock-3.56 {ISO week-based calendar 1885-W01-1} {
+ clock format -2682547200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1885-W01-1
+} {Mon Monday 85 1885 1 52 01 1 52}
+test clock-3.57 {ISO week-based calendar 1885-W01-4} {
+ clock format -2682288000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1885-W01-4
+} {Thu Thursday 85 1885 4 00 01 4 00}
+test clock-3.58 {ISO week-based calendar 1885-W01-6} {
+ clock format -2682115200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1885-W01-6
+} {Sat Saturday 85 1885 6 00 01 6 00}
+test clock-3.59 {ISO week-based calendar 1885-W01-7} {
+ clock format -2682028800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1885-W01-7
+} {Sun Sunday 85 1885 7 01 01 0 00}
+test clock-3.60 {ISO week-based calendar 1885-W02-1} {
+ clock format -2681942400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1885-W02-1
+} {Mon Monday 85 1885 1 01 02 1 01}
+test clock-3.61 {ISO week-based calendar 1887-W52-1} {
+ clock format -2588198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1887-W52-1
+} {Mon Monday 87 1887 1 52 52 1 52}
+test clock-3.62 {ISO week-based calendar 1887-W52-6} {
+ clock format -2587766400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1887-W52-6
+} {Sat Saturday 87 1887 6 52 52 6 52}
+test clock-3.63 {ISO week-based calendar 1887-W52-7} {
+ clock format -2587680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1887-W52-7
+} {Sun Sunday 87 1887 7 01 52 0 00}
+test clock-3.64 {ISO week-based calendar 1888-W01-1} {
+ clock format -2587593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W01-1
+} {Mon Monday 88 1888 1 01 01 1 01}
+test clock-3.65 {ISO week-based calendar 1888-W01-6} {
+ clock format -2587161600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W01-6
+} {Sat Saturday 88 1888 6 01 01 6 01}
+test clock-3.66 {ISO week-based calendar 1888-W01-7} {
+ clock format -2587075200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W01-7
+} {Sun Sunday 88 1888 7 02 01 0 01}
+test clock-3.67 {ISO week-based calendar 1888-W02-1} {
+ clock format -2586988800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W02-1
+} {Mon Monday 88 1888 1 02 02 1 02}
+test clock-3.68 {ISO week-based calendar 1888-W52-1} {
+ clock format -2556748800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W52-1
+} {Mon Monday 88 1888 1 52 52 1 52}
+test clock-3.69 {ISO week-based calendar 1888-W52-6} {
+ clock format -2556316800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W52-6
+} {Sat Saturday 88 1888 6 52 52 6 52}
+test clock-3.70 {ISO week-based calendar 1888-W52-7} {
+ clock format -2556230400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W52-7
+} {Sun Sunday 88 1888 7 53 52 0 52}
+test clock-3.71 {ISO week-based calendar 1889-W01-1} {
+ clock format -2556144000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W01-1
+} {Mon Monday 89 1889 1 53 01 1 53}
+test clock-3.72 {ISO week-based calendar 1889-W01-2} {
+ clock format -2556057600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W01-2
+} {Tue Tuesday 89 1889 2 00 01 2 00}
+test clock-3.73 {ISO week-based calendar 1889-W01-6} {
+ clock format -2555712000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W01-6
+} {Sat Saturday 89 1889 6 00 01 6 00}
+test clock-3.74 {ISO week-based calendar 1889-W01-7} {
+ clock format -2555625600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W01-7
+} {Sun Sunday 89 1889 7 01 01 0 00}
+test clock-3.75 {ISO week-based calendar 1889-W02-1} {
+ clock format -2555539200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W02-1
+} {Mon Monday 89 1889 1 01 02 1 01}
+test clock-3.76 {ISO week-based calendar 1889-W52-1} {
+ clock format -2525299200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W52-1
+} {Mon Monday 89 1889 1 51 52 1 51}
+test clock-3.77 {ISO week-based calendar 1889-W52-6} {
+ clock format -2524867200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W52-6
+} {Sat Saturday 89 1889 6 51 52 6 51}
+test clock-3.78 {ISO week-based calendar 1889-W52-7} {
+ clock format -2524780800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W52-7
+} {Sun Sunday 89 1889 7 52 52 0 51}
+test clock-3.79 {ISO week-based calendar 1890-W01-1} {
+ clock format -2524694400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W01-1
+} {Mon Monday 90 1890 1 52 01 1 52}
+test clock-3.80 {ISO week-based calendar 1890-W01-3} {
+ clock format -2524521600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W01-3
+} {Wed Wednesday 90 1890 3 00 01 3 00}
+test clock-3.81 {ISO week-based calendar 1890-W01-6} {
+ clock format -2524262400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W01-6
+} {Sat Saturday 90 1890 6 00 01 6 00}
+test clock-3.82 {ISO week-based calendar 1890-W01-7} {
+ clock format -2524176000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W01-7
+} {Sun Sunday 90 1890 7 01 01 0 00}
+test clock-3.83 {ISO week-based calendar 1890-W02-1} {
+ clock format -2524089600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W02-1
+} {Mon Monday 90 1890 1 01 02 1 01}
+test clock-3.84 {ISO week-based calendar 1890-W52-1} {
+ clock format -2493849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W52-1
+} {Mon Monday 90 1890 1 51 52 1 51}
+test clock-3.85 {ISO week-based calendar 1890-W52-6} {
+ clock format -2493417600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W52-6
+} {Sat Saturday 90 1890 6 51 52 6 51}
+test clock-3.86 {ISO week-based calendar 1890-W52-7} {
+ clock format -2493331200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W52-7
+} {Sun Sunday 90 1890 7 52 52 0 51}
+test clock-3.87 {ISO week-based calendar 1891-W01-1} {
+ clock format -2493244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W01-1
+} {Mon Monday 91 1891 1 52 01 1 52}
+test clock-3.88 {ISO week-based calendar 1891-W01-4} {
+ clock format -2492985600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W01-4
+} {Thu Thursday 91 1891 4 00 01 4 00}
+test clock-3.89 {ISO week-based calendar 1891-W01-6} {
+ clock format -2492812800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W01-6
+} {Sat Saturday 91 1891 6 00 01 6 00}
+test clock-3.90 {ISO week-based calendar 1891-W01-7} {
+ clock format -2492726400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W01-7
+} {Sun Sunday 91 1891 7 01 01 0 00}
+test clock-3.91 {ISO week-based calendar 1891-W02-1} {
+ clock format -2492640000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W02-1
+} {Mon Monday 91 1891 1 01 02 1 01}
+test clock-3.92 {ISO week-based calendar 1891-W53-1} {
+ clock format -2461795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W53-1
+} {Mon Monday 91 1891 1 52 53 1 52}
+test clock-3.93 {ISO week-based calendar 1891-W53-5} {
+ clock format -2461449600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W53-5
+} {Fri Friday 91 1891 5 00 53 5 00}
+test clock-3.94 {ISO week-based calendar 1891-W53-6} {
+ clock format -2461363200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W53-6
+} {Sat Saturday 91 1891 6 00 53 6 00}
+test clock-3.95 {ISO week-based calendar 1891-W53-7} {
+ clock format -2461276800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W53-7
+} {Sun Sunday 91 1891 7 01 53 0 00}
+test clock-3.96 {ISO week-based calendar 1892-W01-1} {
+ clock format -2461190400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W01-1
+} {Mon Monday 92 1892 1 01 01 1 01}
+test clock-3.97 {ISO week-based calendar 1892-W01-6} {
+ clock format -2460758400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W01-6
+} {Sat Saturday 92 1892 6 01 01 6 01}
+test clock-3.98 {ISO week-based calendar 1892-W01-7} {
+ clock format -2460672000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W01-7
+} {Sun Sunday 92 1892 7 02 01 0 01}
+test clock-3.99 {ISO week-based calendar 1892-W02-1} {
+ clock format -2460585600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W02-1
+} {Mon Monday 92 1892 1 02 02 1 02}
+test clock-3.100 {ISO week-based calendar 1892-W52-1} {
+ clock format -2430345600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W52-1
+} {Mon Monday 92 1892 1 52 52 1 52}
+test clock-3.101 {ISO week-based calendar 1892-W52-6} {
+ clock format -2429913600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W52-6
+} {Sat Saturday 92 1892 6 52 52 6 52}
+test clock-3.102 {ISO week-based calendar 1892-W52-7} {
+ clock format -2429827200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W52-7
+} {Sun Sunday 92 1892 7 01 52 0 00}
+test clock-3.103 {ISO week-based calendar 1893-W01-1} {
+ clock format -2429740800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W01-1
+} {Mon Monday 93 1893 1 01 01 1 01}
+test clock-3.104 {ISO week-based calendar 1893-W01-6} {
+ clock format -2429308800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W01-6
+} {Sat Saturday 93 1893 6 01 01 6 01}
+test clock-3.105 {ISO week-based calendar 1893-W01-7} {
+ clock format -2429222400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W01-7
+} {Sun Sunday 93 1893 7 02 01 0 01}
+test clock-3.106 {ISO week-based calendar 1893-W02-1} {
+ clock format -2429136000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W02-1
+} {Mon Monday 93 1893 1 02 02 1 02}
+test clock-3.107 {ISO week-based calendar 1893-W52-1} {
+ clock format -2398896000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W52-1
+} {Mon Monday 93 1893 1 52 52 1 52}
+test clock-3.108 {ISO week-based calendar 1893-W52-6} {
+ clock format -2398464000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W52-6
+} {Sat Saturday 93 1893 6 52 52 6 52}
+test clock-3.109 {ISO week-based calendar 1893-W52-7} {
+ clock format -2398377600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W52-7
+} {Sun Sunday 93 1893 7 53 52 0 52}
+test clock-3.110 {ISO week-based calendar 1894-W01-1} {
+ clock format -2398291200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W01-1
+} {Mon Monday 94 1894 1 00 01 1 01}
+test clock-3.111 {ISO week-based calendar 1894-W01-6} {
+ clock format -2397859200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W01-6
+} {Sat Saturday 94 1894 6 00 01 6 01}
+test clock-3.112 {ISO week-based calendar 1894-W01-7} {
+ clock format -2397772800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W01-7
+} {Sun Sunday 94 1894 7 01 01 0 01}
+test clock-3.113 {ISO week-based calendar 1894-W02-1} {
+ clock format -2397686400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W02-1
+} {Mon Monday 94 1894 1 01 02 1 02}
+test clock-3.114 {ISO week-based calendar 1894-W52-1} {
+ clock format -2367446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W52-1
+} {Mon Monday 94 1894 1 51 52 1 52}
+test clock-3.115 {ISO week-based calendar 1894-W52-6} {
+ clock format -2367014400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W52-6
+} {Sat Saturday 94 1894 6 51 52 6 52}
+test clock-3.116 {ISO week-based calendar 1894-W52-7} {
+ clock format -2366928000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W52-7
+} {Sun Sunday 94 1894 7 52 52 0 52}
+test clock-3.117 {ISO week-based calendar 1895-W01-1} {
+ clock format -2366841600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W01-1
+} {Mon Monday 95 1895 1 52 01 1 53}
+test clock-3.118 {ISO week-based calendar 1895-W01-2} {
+ clock format -2366755200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W01-2
+} {Tue Tuesday 95 1895 2 00 01 2 00}
+test clock-3.119 {ISO week-based calendar 1895-W01-6} {
+ clock format -2366409600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W01-6
+} {Sat Saturday 95 1895 6 00 01 6 00}
+test clock-3.120 {ISO week-based calendar 1895-W01-7} {
+ clock format -2366323200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W01-7
+} {Sun Sunday 95 1895 7 01 01 0 00}
+test clock-3.121 {ISO week-based calendar 1895-W02-1} {
+ clock format -2366236800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W02-1
+} {Mon Monday 95 1895 1 01 02 1 01}
+test clock-3.122 {ISO week-based calendar 1895-W52-1} {
+ clock format -2335996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W52-1
+} {Mon Monday 95 1895 1 51 52 1 51}
+test clock-3.123 {ISO week-based calendar 1895-W52-6} {
+ clock format -2335564800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W52-6
+} {Sat Saturday 95 1895 6 51 52 6 51}
+test clock-3.124 {ISO week-based calendar 1895-W52-7} {
+ clock format -2335478400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W52-7
+} {Sun Sunday 95 1895 7 52 52 0 51}
+test clock-3.125 {ISO week-based calendar 1896-W01-1} {
+ clock format -2335392000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W01-1
+} {Mon Monday 96 1896 1 52 01 1 52}
+test clock-3.126 {ISO week-based calendar 1896-W01-3} {
+ clock format -2335219200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W01-3
+} {Wed Wednesday 96 1896 3 00 01 3 00}
+test clock-3.127 {ISO week-based calendar 1896-W01-6} {
+ clock format -2334960000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W01-6
+} {Sat Saturday 96 1896 6 00 01 6 00}
+test clock-3.128 {ISO week-based calendar 1896-W01-7} {
+ clock format -2334873600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W01-7
+} {Sun Sunday 96 1896 7 01 01 0 00}
+test clock-3.129 {ISO week-based calendar 1896-W02-1} {
+ clock format -2334787200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W02-1
+} {Mon Monday 96 1896 1 01 02 1 01}
+test clock-3.130 {ISO week-based calendar 1896-W53-1} {
+ clock format -2303942400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W53-1
+} {Mon Monday 96 1896 1 52 53 1 52}
+test clock-3.131 {ISO week-based calendar 1896-W53-5} {
+ clock format -2303596800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W53-5
+} {Fri Friday 96 1896 5 00 53 5 00}
+test clock-3.132 {ISO week-based calendar 1896-W53-6} {
+ clock format -2303510400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W53-6
+} {Sat Saturday 96 1896 6 00 53 6 00}
+test clock-3.133 {ISO week-based calendar 1896-W53-7} {
+ clock format -2303424000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W53-7
+} {Sun Sunday 96 1896 7 01 53 0 00}
+test clock-3.134 {ISO week-based calendar 1897-W01-1} {
+ clock format -2303337600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W01-1
+} {Mon Monday 97 1897 1 01 01 1 01}
+test clock-3.135 {ISO week-based calendar 1897-W01-6} {
+ clock format -2302905600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W01-6
+} {Sat Saturday 97 1897 6 01 01 6 01}
+test clock-3.136 {ISO week-based calendar 1897-W01-7} {
+ clock format -2302819200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W01-7
+} {Sun Sunday 97 1897 7 02 01 0 01}
+test clock-3.137 {ISO week-based calendar 1897-W02-1} {
+ clock format -2302732800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W02-1
+} {Mon Monday 97 1897 1 02 02 1 02}
+test clock-3.138 {ISO week-based calendar 1897-W52-1} {
+ clock format -2272492800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W52-1
+} {Mon Monday 97 1897 1 52 52 1 52}
+test clock-3.139 {ISO week-based calendar 1897-W52-6} {
+ clock format -2272060800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W52-6
+} {Sat Saturday 97 1897 6 00 52 6 00}
+test clock-3.140 {ISO week-based calendar 1897-W52-7} {
+ clock format -2271974400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W52-7
+} {Sun Sunday 97 1897 7 01 52 0 00}
+test clock-3.141 {ISO week-based calendar 1898-W01-1} {
+ clock format -2271888000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W01-1
+} {Mon Monday 98 1898 1 01 01 1 01}
+test clock-3.142 {ISO week-based calendar 1898-W01-6} {
+ clock format -2271456000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W01-6
+} {Sat Saturday 98 1898 6 01 01 6 01}
+test clock-3.143 {ISO week-based calendar 1898-W01-7} {
+ clock format -2271369600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W01-7
+} {Sun Sunday 98 1898 7 02 01 0 01}
+test clock-3.144 {ISO week-based calendar 1898-W02-1} {
+ clock format -2271283200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W02-1
+} {Mon Monday 98 1898 1 02 02 1 02}
+test clock-3.145 {ISO week-based calendar 1898-W52-1} {
+ clock format -2241043200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W52-1
+} {Mon Monday 98 1898 1 52 52 1 52}
+test clock-3.146 {ISO week-based calendar 1898-W52-6} {
+ clock format -2240611200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W52-6
+} {Sat Saturday 98 1898 6 52 52 6 52}
+test clock-3.147 {ISO week-based calendar 1898-W52-7} {
+ clock format -2240524800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W52-7
+} {Sun Sunday 98 1898 7 01 52 0 00}
+test clock-3.148 {ISO week-based calendar 1899-W01-1} {
+ clock format -2240438400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W01-1
+} {Mon Monday 99 1899 1 01 01 1 01}
+test clock-3.149 {ISO week-based calendar 1899-W01-6} {
+ clock format -2240006400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W01-6
+} {Sat Saturday 99 1899 6 01 01 6 01}
+test clock-3.150 {ISO week-based calendar 1899-W01-7} {
+ clock format -2239920000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W01-7
+} {Sun Sunday 99 1899 7 02 01 0 01}
+test clock-3.151 {ISO week-based calendar 1899-W02-1} {
+ clock format -2239833600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W02-1
+} {Mon Monday 99 1899 1 02 02 1 02}
+test clock-3.152 {ISO week-based calendar 1899-W52-1} {
+ clock format -2209593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W52-1
+} {Mon Monday 99 1899 1 52 52 1 52}
+test clock-3.153 {ISO week-based calendar 1899-W52-6} {
+ clock format -2209161600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W52-6
+} {Sat Saturday 99 1899 6 52 52 6 52}
+test clock-3.154 {ISO week-based calendar 1899-W52-7} {
+ clock format -2209075200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W52-7
+} {Sun Sunday 99 1899 7 53 52 0 52}
+test clock-3.155 {ISO week-based calendar 1900-W01-1} {
+ clock format -2208988800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1900-W01-1
+} {Mon Monday 00 1900 1 00 01 1 01}
+test clock-3.156 {ISO week-based calendar 1900-W01-6} {
+ clock format -2208556800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1900-W01-6
+} {Sat Saturday 00 1900 6 00 01 6 01}
+test clock-3.157 {ISO week-based calendar 1900-W01-7} {
+ clock format -2208470400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1900-W01-7
+} {Sun Sunday 00 1900 7 01 01 0 01}
+test clock-3.158 {ISO week-based calendar 1900-W02-1} {
+ clock format -2208384000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1900-W02-1
+} {Mon Monday 00 1900 1 01 02 1 02}
+test clock-3.159 {ISO week-based calendar 1943-W52-1} {
+ clock format -820972800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1943-W52-1
+} {Mon Monday 43 1943 1 52 52 1 52}
+test clock-3.160 {ISO week-based calendar 1943-W52-6} {
+ clock format -820540800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1943-W52-6
+} {Sat Saturday 43 1943 6 00 52 6 00}
+test clock-3.161 {ISO week-based calendar 1943-W52-7} {
+ clock format -820454400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1943-W52-7
+} {Sun Sunday 43 1943 7 01 52 0 00}
+test clock-3.162 {ISO week-based calendar 1944-W01-1} {
+ clock format -820368000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W01-1
+} {Mon Monday 44 1944 1 01 01 1 01}
+test clock-3.163 {ISO week-based calendar 1944-W01-6} {
+ clock format -819936000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W01-6
+} {Sat Saturday 44 1944 6 01 01 6 01}
+test clock-3.164 {ISO week-based calendar 1944-W01-7} {
+ clock format -819849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W01-7
+} {Sun Sunday 44 1944 7 02 01 0 01}
+test clock-3.165 {ISO week-based calendar 1944-W02-1} {
+ clock format -819763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W02-1
+} {Mon Monday 44 1944 1 02 02 1 02}
+test clock-3.166 {ISO week-based calendar 1944-W52-1} {
+ clock format -789523200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W52-1
+} {Mon Monday 44 1944 1 52 52 1 52}
+test clock-3.167 {ISO week-based calendar 1944-W52-6} {
+ clock format -789091200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W52-6
+} {Sat Saturday 44 1944 6 52 52 6 52}
+test clock-3.168 {ISO week-based calendar 1944-W52-7} {
+ clock format -789004800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W52-7
+} {Sun Sunday 44 1944 7 53 52 0 52}
+test clock-3.169 {ISO week-based calendar 1945-W01-1} {
+ clock format -788918400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1945-W01-1
+} {Mon Monday 45 1945 1 00 01 1 01}
+test clock-3.170 {ISO week-based calendar 1945-W01-6} {
+ clock format -788486400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1945-W01-6
+} {Sat Saturday 45 1945 6 00 01 6 01}
+test clock-3.171 {ISO week-based calendar 1945-W01-7} {
+ clock format -788400000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1945-W01-7
+} {Sun Sunday 45 1945 7 01 01 0 01}
+test clock-3.172 {ISO week-based calendar 1945-W02-1} {
+ clock format -788313600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1945-W02-1
+} {Mon Monday 45 1945 1 01 02 1 02}
+test clock-3.173 {ISO week-based calendar 1947-W52-1} {
+ clock format -695174400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1947-W52-1
+} {Mon Monday 47 1947 1 51 52 1 51}
+test clock-3.174 {ISO week-based calendar 1947-W52-6} {
+ clock format -694742400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1947-W52-6
+} {Sat Saturday 47 1947 6 51 52 6 51}
+test clock-3.175 {ISO week-based calendar 1947-W52-7} {
+ clock format -694656000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1947-W52-7
+} {Sun Sunday 47 1947 7 52 52 0 51}
+test clock-3.176 {ISO week-based calendar 1948-W01-1} {
+ clock format -694569600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W01-1
+} {Mon Monday 48 1948 1 52 01 1 52}
+test clock-3.177 {ISO week-based calendar 1948-W01-4} {
+ clock format -694310400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W01-4
+} {Thu Thursday 48 1948 4 00 01 4 00}
+test clock-3.178 {ISO week-based calendar 1948-W01-6} {
+ clock format -694137600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W01-6
+} {Sat Saturday 48 1948 6 00 01 6 00}
+test clock-3.179 {ISO week-based calendar 1948-W01-7} {
+ clock format -694051200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W01-7
+} {Sun Sunday 48 1948 7 01 01 0 00}
+test clock-3.180 {ISO week-based calendar 1948-W02-1} {
+ clock format -693964800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W02-1
+} {Mon Monday 48 1948 1 01 02 1 01}
+test clock-3.181 {ISO week-based calendar 1948-W53-1} {
+ clock format -663120000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W53-1
+} {Mon Monday 48 1948 1 52 53 1 52}
+test clock-3.182 {ISO week-based calendar 1948-W53-6} {
+ clock format -662688000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W53-6
+} {Sat Saturday 48 1948 6 00 53 6 00}
+test clock-3.183 {ISO week-based calendar 1948-W53-7} {
+ clock format -662601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W53-7
+} {Sun Sunday 48 1948 7 01 53 0 00}
+test clock-3.184 {ISO week-based calendar 1949-W01-1} {
+ clock format -662515200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1949-W01-1
+} {Mon Monday 49 1949 1 01 01 1 01}
+test clock-3.185 {ISO week-based calendar 1949-W01-6} {
+ clock format -662083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1949-W01-6
+} {Sat Saturday 49 1949 6 01 01 6 01}
+test clock-3.186 {ISO week-based calendar 1949-W01-7} {
+ clock format -661996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1949-W01-7
+} {Sun Sunday 49 1949 7 02 01 0 01}
+test clock-3.187 {ISO week-based calendar 1949-W02-1} {
+ clock format -661910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1949-W02-1
+} {Mon Monday 49 1949 1 02 02 1 02}
+test clock-3.188 {ISO week-based calendar 1951-W52-1} {
+ clock format -568771200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1951-W52-1
+} {Mon Monday 51 1951 1 51 52 1 52}
+test clock-3.189 {ISO week-based calendar 1951-W52-6} {
+ clock format -568339200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1951-W52-6
+} {Sat Saturday 51 1951 6 51 52 6 52}
+test clock-3.190 {ISO week-based calendar 1951-W52-7} {
+ clock format -568252800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1951-W52-7
+} {Sun Sunday 51 1951 7 52 52 0 52}
+test clock-3.191 {ISO week-based calendar 1952-W01-1} {
+ clock format -568166400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W01-1
+} {Mon Monday 52 1952 1 52 01 1 53}
+test clock-3.192 {ISO week-based calendar 1952-W01-2} {
+ clock format -568080000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W01-2
+} {Tue Tuesday 52 1952 2 00 01 2 00}
+test clock-3.193 {ISO week-based calendar 1952-W01-6} {
+ clock format -567734400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W01-6
+} {Sat Saturday 52 1952 6 00 01 6 00}
+test clock-3.194 {ISO week-based calendar 1952-W01-7} {
+ clock format -567648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W01-7
+} {Sun Sunday 52 1952 7 01 01 0 00}
+test clock-3.195 {ISO week-based calendar 1952-W02-1} {
+ clock format -567561600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W02-1
+} {Mon Monday 52 1952 1 01 02 1 01}
+test clock-3.196 {ISO week-based calendar 1952-W52-1} {
+ clock format -537321600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W52-1
+} {Mon Monday 52 1952 1 51 52 1 51}
+test clock-3.197 {ISO week-based calendar 1952-W52-6} {
+ clock format -536889600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W52-6
+} {Sat Saturday 52 1952 6 51 52 6 51}
+test clock-3.198 {ISO week-based calendar 1952-W52-7} {
+ clock format -536803200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W52-7
+} {Sun Sunday 52 1952 7 52 52 0 51}
+test clock-3.199 {ISO week-based calendar 1953-W01-1} {
+ clock format -536716800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1953-W01-1
+} {Mon Monday 53 1953 1 52 01 1 52}
+test clock-3.200 {ISO week-based calendar 1953-W01-4} {
+ clock format -536457600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1953-W01-4
+} {Thu Thursday 53 1953 4 00 01 4 00}
+test clock-3.201 {ISO week-based calendar 1953-W01-6} {
+ clock format -536284800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1953-W01-6
+} {Sat Saturday 53 1953 6 00 01 6 00}
+test clock-3.202 {ISO week-based calendar 1953-W01-7} {
+ clock format -536198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1953-W01-7
+} {Sun Sunday 53 1953 7 01 01 0 00}
+test clock-3.203 {ISO week-based calendar 1953-W02-1} {
+ clock format -536112000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1953-W02-1
+} {Mon Monday 53 1953 1 01 02 1 01}
+test clock-3.204 {ISO week-based calendar 1955-W52-1} {
+ clock format -442368000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1955-W52-1
+} {Mon Monday 55 1955 1 52 52 1 52}
+test clock-3.205 {ISO week-based calendar 1955-W52-6} {
+ clock format -441936000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1955-W52-6
+} {Sat Saturday 55 1955 6 52 52 6 52}
+test clock-3.206 {ISO week-based calendar 1955-W52-7} {
+ clock format -441849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1955-W52-7
+} {Sun Sunday 55 1955 7 01 52 0 00}
+test clock-3.207 {ISO week-based calendar 1956-W01-1} {
+ clock format -441763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W01-1
+} {Mon Monday 56 1956 1 01 01 1 01}
+test clock-3.208 {ISO week-based calendar 1956-W01-6} {
+ clock format -441331200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W01-6
+} {Sat Saturday 56 1956 6 01 01 6 01}
+test clock-3.209 {ISO week-based calendar 1956-W01-7} {
+ clock format -441244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W01-7
+} {Sun Sunday 56 1956 7 02 01 0 01}
+test clock-3.210 {ISO week-based calendar 1956-W02-1} {
+ clock format -441158400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W02-1
+} {Mon Monday 56 1956 1 02 02 1 02}
+test clock-3.211 {ISO week-based calendar 1956-W52-1} {
+ clock format -410918400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W52-1
+} {Mon Monday 56 1956 1 52 52 1 52}
+test clock-3.212 {ISO week-based calendar 1956-W52-6} {
+ clock format -410486400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W52-6
+} {Sat Saturday 56 1956 6 52 52 6 52}
+test clock-3.213 {ISO week-based calendar 1956-W52-7} {
+ clock format -410400000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W52-7
+} {Sun Sunday 56 1956 7 53 52 0 52}
+test clock-3.214 {ISO week-based calendar 1957-W01-1} {
+ clock format -410313600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1957-W01-1
+} {Mon Monday 57 1957 1 53 01 1 53}
+test clock-3.215 {ISO week-based calendar 1957-W01-2} {
+ clock format -410227200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1957-W01-2
+} {Tue Tuesday 57 1957 2 00 01 2 00}
+test clock-3.216 {ISO week-based calendar 1957-W01-6} {
+ clock format -409881600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1957-W01-6
+} {Sat Saturday 57 1957 6 00 01 6 00}
+test clock-3.217 {ISO week-based calendar 1957-W01-7} {
+ clock format -409795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1957-W01-7
+} {Sun Sunday 57 1957 7 01 01 0 00}
+test clock-3.218 {ISO week-based calendar 1957-W02-1} {
+ clock format -409708800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1957-W02-1
+} {Mon Monday 57 1957 1 01 02 1 01}
+test clock-3.219 {ISO week-based calendar 1958-W52-1} {
+ clock format -348019200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1958-W52-1
+} {Mon Monday 58 1958 1 51 52 1 51}
+test clock-3.220 {ISO week-based calendar 1958-W52-6} {
+ clock format -347587200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1958-W52-6
+} {Sat Saturday 58 1958 6 51 52 6 51}
+test clock-3.221 {ISO week-based calendar 1958-W52-7} {
+ clock format -347500800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1958-W52-7
+} {Sun Sunday 58 1958 7 52 52 0 51}
+test clock-3.222 {ISO week-based calendar 1959-W01-1} {
+ clock format -347414400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W01-1
+} {Mon Monday 59 1959 1 52 01 1 52}
+test clock-3.223 {ISO week-based calendar 1959-W01-4} {
+ clock format -347155200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W01-4
+} {Thu Thursday 59 1959 4 00 01 4 00}
+test clock-3.224 {ISO week-based calendar 1959-W01-6} {
+ clock format -346982400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W01-6
+} {Sat Saturday 59 1959 6 00 01 6 00}
+test clock-3.225 {ISO week-based calendar 1959-W01-7} {
+ clock format -346896000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W01-7
+} {Sun Sunday 59 1959 7 01 01 0 00}
+test clock-3.226 {ISO week-based calendar 1959-W02-1} {
+ clock format -346809600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W02-1
+} {Mon Monday 59 1959 1 01 02 1 01}
+test clock-3.227 {ISO week-based calendar 1959-W53-1} {
+ clock format -315964800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W53-1
+} {Mon Monday 59 1959 1 52 53 1 52}
+test clock-3.228 {ISO week-based calendar 1959-W53-5} {
+ clock format -315619200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W53-5
+} {Fri Friday 59 1959 5 00 53 5 00}
+test clock-3.229 {ISO week-based calendar 1959-W53-6} {
+ clock format -315532800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W53-6
+} {Sat Saturday 59 1959 6 00 53 6 00}
+test clock-3.230 {ISO week-based calendar 1959-W53-7} {
+ clock format -315446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W53-7
+} {Sun Sunday 59 1959 7 01 53 0 00}
+test clock-3.231 {ISO week-based calendar 1960-W01-1} {
+ clock format -315360000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W01-1
+} {Mon Monday 60 1960 1 01 01 1 01}
+test clock-3.232 {ISO week-based calendar 1960-W01-6} {
+ clock format -314928000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W01-6
+} {Sat Saturday 60 1960 6 01 01 6 01}
+test clock-3.233 {ISO week-based calendar 1960-W01-7} {
+ clock format -314841600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W01-7
+} {Sun Sunday 60 1960 7 02 01 0 01}
+test clock-3.234 {ISO week-based calendar 1960-W02-1} {
+ clock format -314755200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W02-1
+} {Mon Monday 60 1960 1 02 02 1 02}
+test clock-3.235 {ISO week-based calendar 1960-W52-1} {
+ clock format -284515200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W52-1
+} {Mon Monday 60 1960 1 52 52 1 52}
+test clock-3.236 {ISO week-based calendar 1960-W52-6} {
+ clock format -284083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W52-6
+} {Sat Saturday 60 1960 6 52 52 6 52}
+test clock-3.237 {ISO week-based calendar 1960-W52-7} {
+ clock format -283996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W52-7
+} {Sun Sunday 60 1960 7 01 52 0 00}
+test clock-3.238 {ISO week-based calendar 1961-W01-1} {
+ clock format -283910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W01-1
+} {Mon Monday 61 1961 1 01 01 1 01}
+test clock-3.239 {ISO week-based calendar 1961-W01-6} {
+ clock format -283478400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W01-6
+} {Sat Saturday 61 1961 6 01 01 6 01}
+test clock-3.240 {ISO week-based calendar 1961-W01-7} {
+ clock format -283392000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W01-7
+} {Sun Sunday 61 1961 7 02 01 0 01}
+test clock-3.241 {ISO week-based calendar 1961-W02-1} {
+ clock format -283305600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W02-1
+} {Mon Monday 61 1961 1 02 02 1 02}
+test clock-3.242 {ISO week-based calendar 1961-W52-1} {
+ clock format -253065600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W52-1
+} {Mon Monday 61 1961 1 52 52 1 52}
+test clock-3.243 {ISO week-based calendar 1961-W52-6} {
+ clock format -252633600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W52-6
+} {Sat Saturday 61 1961 6 52 52 6 52}
+test clock-3.244 {ISO week-based calendar 1961-W52-7} {
+ clock format -252547200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W52-7
+} {Sun Sunday 61 1961 7 53 52 0 52}
+test clock-3.245 {ISO week-based calendar 1962-W01-1} {
+ clock format -252460800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W01-1
+} {Mon Monday 62 1962 1 00 01 1 01}
+test clock-3.246 {ISO week-based calendar 1962-W01-6} {
+ clock format -252028800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W01-6
+} {Sat Saturday 62 1962 6 00 01 6 01}
+test clock-3.247 {ISO week-based calendar 1962-W01-7} {
+ clock format -251942400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W01-7
+} {Sun Sunday 62 1962 7 01 01 0 01}
+test clock-3.248 {ISO week-based calendar 1962-W02-1} {
+ clock format -251856000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W02-1
+} {Mon Monday 62 1962 1 01 02 1 02}
+test clock-3.249 {ISO week-based calendar 1962-W52-1} {
+ clock format -221616000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W52-1
+} {Mon Monday 62 1962 1 51 52 1 52}
+test clock-3.250 {ISO week-based calendar 1962-W52-6} {
+ clock format -221184000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W52-6
+} {Sat Saturday 62 1962 6 51 52 6 52}
+test clock-3.251 {ISO week-based calendar 1962-W52-7} {
+ clock format -221097600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W52-7
+} {Sun Sunday 62 1962 7 52 52 0 52}
+test clock-3.252 {ISO week-based calendar 1963-W01-1} {
+ clock format -221011200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W01-1
+} {Mon Monday 63 1963 1 52 01 1 53}
+test clock-3.253 {ISO week-based calendar 1963-W01-2} {
+ clock format -220924800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W01-2
+} {Tue Tuesday 63 1963 2 00 01 2 00}
+test clock-3.254 {ISO week-based calendar 1963-W01-6} {
+ clock format -220579200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W01-6
+} {Sat Saturday 63 1963 6 00 01 6 00}
+test clock-3.255 {ISO week-based calendar 1963-W01-7} {
+ clock format -220492800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W01-7
+} {Sun Sunday 63 1963 7 01 01 0 00}
+test clock-3.256 {ISO week-based calendar 1963-W02-1} {
+ clock format -220406400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W02-1
+} {Mon Monday 63 1963 1 01 02 1 01}
+test clock-3.257 {ISO week-based calendar 1963-W52-1} {
+ clock format -190166400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W52-1
+} {Mon Monday 63 1963 1 51 52 1 51}
+test clock-3.258 {ISO week-based calendar 1963-W52-6} {
+ clock format -189734400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W52-6
+} {Sat Saturday 63 1963 6 51 52 6 51}
+test clock-3.259 {ISO week-based calendar 1963-W52-7} {
+ clock format -189648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W52-7
+} {Sun Sunday 63 1963 7 52 52 0 51}
+test clock-3.260 {ISO week-based calendar 1964-W01-1} {
+ clock format -189561600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W01-1
+} {Mon Monday 64 1964 1 52 01 1 52}
+test clock-3.261 {ISO week-based calendar 1964-W01-3} {
+ clock format -189388800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W01-3
+} {Wed Wednesday 64 1964 3 00 01 3 00}
+test clock-3.262 {ISO week-based calendar 1964-W01-6} {
+ clock format -189129600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W01-6
+} {Sat Saturday 64 1964 6 00 01 6 00}
+test clock-3.263 {ISO week-based calendar 1964-W01-7} {
+ clock format -189043200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W01-7
+} {Sun Sunday 64 1964 7 01 01 0 00}
+test clock-3.264 {ISO week-based calendar 1964-W02-1} {
+ clock format -188956800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W02-1
+} {Mon Monday 64 1964 1 01 02 1 01}
+test clock-3.265 {ISO week-based calendar 1964-W53-1} {
+ clock format -158112000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W53-1
+} {Mon Monday 64 1964 1 52 53 1 52}
+test clock-3.266 {ISO week-based calendar 1964-W53-5} {
+ clock format -157766400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W53-5
+} {Fri Friday 64 1964 5 00 53 5 00}
+test clock-3.267 {ISO week-based calendar 1964-W53-6} {
+ clock format -157680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W53-6
+} {Sat Saturday 64 1964 6 00 53 6 00}
+test clock-3.268 {ISO week-based calendar 1964-W53-7} {
+ clock format -157593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W53-7
+} {Sun Sunday 64 1964 7 01 53 0 00}
+test clock-3.269 {ISO week-based calendar 1965-W01-1} {
+ clock format -157507200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W01-1
+} {Mon Monday 65 1965 1 01 01 1 01}
+test clock-3.270 {ISO week-based calendar 1965-W01-6} {
+ clock format -157075200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W01-6
+} {Sat Saturday 65 1965 6 01 01 6 01}
+test clock-3.271 {ISO week-based calendar 1965-W01-7} {
+ clock format -156988800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W01-7
+} {Sun Sunday 65 1965 7 02 01 0 01}
+test clock-3.272 {ISO week-based calendar 1965-W02-1} {
+ clock format -156902400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W02-1
+} {Mon Monday 65 1965 1 02 02 1 02}
+test clock-3.273 {ISO week-based calendar 1965-W52-1} {
+ clock format -126662400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W52-1
+} {Mon Monday 65 1965 1 52 52 1 52}
+test clock-3.274 {ISO week-based calendar 1965-W52-6} {
+ clock format -126230400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W52-6
+} {Sat Saturday 65 1965 6 00 52 6 00}
+test clock-3.275 {ISO week-based calendar 1965-W52-7} {
+ clock format -126144000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W52-7
+} {Sun Sunday 65 1965 7 01 52 0 00}
+test clock-3.276 {ISO week-based calendar 1966-W01-1} {
+ clock format -126057600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W01-1
+} {Mon Monday 66 1966 1 01 01 1 01}
+test clock-3.277 {ISO week-based calendar 1966-W01-6} {
+ clock format -125625600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W01-6
+} {Sat Saturday 66 1966 6 01 01 6 01}
+test clock-3.278 {ISO week-based calendar 1966-W01-7} {
+ clock format -125539200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W01-7
+} {Sun Sunday 66 1966 7 02 01 0 01}
+test clock-3.279 {ISO week-based calendar 1966-W02-1} {
+ clock format -125452800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W02-1
+} {Mon Monday 66 1966 1 02 02 1 02}
+test clock-3.280 {ISO week-based calendar 1966-W52-1} {
+ clock format -95212800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W52-1
+} {Mon Monday 66 1966 1 52 52 1 52}
+test clock-3.281 {ISO week-based calendar 1966-W52-6} {
+ clock format -94780800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W52-6
+} {Sat Saturday 66 1966 6 52 52 6 52}
+test clock-3.282 {ISO week-based calendar 1966-W52-7} {
+ clock format -94694400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W52-7
+} {Sun Sunday 66 1966 7 01 52 0 00}
+test clock-3.283 {ISO week-based calendar 1967-W01-1} {
+ clock format -94608000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W01-1
+} {Mon Monday 67 1967 1 01 01 1 01}
+test clock-3.284 {ISO week-based calendar 1967-W01-6} {
+ clock format -94176000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W01-6
+} {Sat Saturday 67 1967 6 01 01 6 01}
+test clock-3.285 {ISO week-based calendar 1967-W01-7} {
+ clock format -94089600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W01-7
+} {Sun Sunday 67 1967 7 02 01 0 01}
+test clock-3.286 {ISO week-based calendar 1967-W02-1} {
+ clock format -94003200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W02-1
+} {Mon Monday 67 1967 1 02 02 1 02}
+test clock-3.287 {ISO week-based calendar 1967-W52-1} {
+ clock format -63763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W52-1
+} {Mon Monday 67 1967 1 52 52 1 52}
+test clock-3.288 {ISO week-based calendar 1967-W52-6} {
+ clock format -63331200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W52-6
+} {Sat Saturday 67 1967 6 52 52 6 52}
+test clock-3.289 {ISO week-based calendar 1967-W52-7} {
+ clock format -63244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W52-7
+} {Sun Sunday 67 1967 7 53 52 0 52}
+test clock-3.290 {ISO week-based calendar 1968-W01-1} {
+ clock format -63158400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W01-1
+} {Mon Monday 68 1968 1 00 01 1 01}
+test clock-3.291 {ISO week-based calendar 1968-W01-6} {
+ clock format -62726400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W01-6
+} {Sat Saturday 68 1968 6 00 01 6 01}
+test clock-3.292 {ISO week-based calendar 1968-W01-7} {
+ clock format -62640000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W01-7
+} {Sun Sunday 68 1968 7 01 01 0 01}
+test clock-3.293 {ISO week-based calendar 1968-W02-1} {
+ clock format -62553600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W02-1
+} {Mon Monday 68 1968 1 01 02 1 02}
+test clock-3.294 {ISO week-based calendar 1968-W52-1} {
+ clock format -32313600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W52-1
+} {Mon Monday 68 1968 1 51 52 1 52}
+test clock-3.295 {ISO week-based calendar 1968-W52-6} {
+ clock format -31881600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W52-6
+} {Sat Saturday 68 1968 6 51 52 6 52}
+test clock-3.296 {ISO week-based calendar 1968-W52-7} {
+ clock format -31795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W52-7
+} {Sun Sunday 68 1968 7 52 52 0 52}
+test clock-3.297 {ISO week-based calendar 1969-W01-1} {
+ clock format -31708800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W01-1
+} {Mon Monday 69 1969 1 52 01 1 53}
+test clock-3.298 {ISO week-based calendar 1969-W01-3} {
+ clock format -31536000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W01-3
+} {Wed Wednesday 69 1969 3 00 01 3 00}
+test clock-3.299 {ISO week-based calendar 1969-W01-6} {
+ clock format -31276800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W01-6
+} {Sat Saturday 69 1969 6 00 01 6 00}
+test clock-3.300 {ISO week-based calendar 1969-W01-7} {
+ clock format -31190400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W01-7
+} {Sun Sunday 69 1969 7 01 01 0 00}
+test clock-3.301 {ISO week-based calendar 1969-W02-1} {
+ clock format -31104000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W02-1
+} {Mon Monday 69 1969 1 01 02 1 01}
+test clock-3.302 {ISO week-based calendar 1969-W52-1} {
+ clock format -864000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W52-1
+} {Mon Monday 69 1969 1 51 52 1 51}
+test clock-3.303 {ISO week-based calendar 1969-W52-6} {
+ clock format -432000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W52-6
+} {Sat Saturday 69 1969 6 51 52 6 51}
+test clock-3.304 {ISO week-based calendar 1969-W52-7} {
+ clock format -345600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W52-7
+} {Sun Sunday 69 1969 7 52 52 0 51}
+test clock-3.305 {ISO week-based calendar 1970-W01-1} {
+ clock format -259200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W01-1
+} {Mon Monday 70 1970 1 52 01 1 52}
+test clock-3.306 {ISO week-based calendar 1970-W01-4} {
+ clock format 0 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W01-4
+} {Thu Thursday 70 1970 4 00 01 4 00}
+test clock-3.307 {ISO week-based calendar 1970-W01-6} {
+ clock format 172800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W01-6
+} {Sat Saturday 70 1970 6 00 01 6 00}
+test clock-3.308 {ISO week-based calendar 1970-W01-7} {
+ clock format 259200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W01-7
+} {Sun Sunday 70 1970 7 01 01 0 00}
+test clock-3.309 {ISO week-based calendar 1970-W02-1} {
+ clock format 345600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W02-1
+} {Mon Monday 70 1970 1 01 02 1 01}
+test clock-3.310 {ISO week-based calendar 1970-W53-1} {
+ clock format 31190400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W53-1
+} {Mon Monday 70 1970 1 52 53 1 52}
+test clock-3.311 {ISO week-based calendar 1970-W53-5} {
+ clock format 31536000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W53-5
+} {Fri Friday 70 1970 5 00 53 5 00}
+test clock-3.312 {ISO week-based calendar 1970-W53-6} {
+ clock format 31622400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W53-6
+} {Sat Saturday 70 1970 6 00 53 6 00}
+test clock-3.313 {ISO week-based calendar 1970-W53-7} {
+ clock format 31708800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W53-7
+} {Sun Sunday 70 1970 7 01 53 0 00}
+test clock-3.314 {ISO week-based calendar 1971-W01-1} {
+ clock format 31795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W01-1
+} {Mon Monday 71 1971 1 01 01 1 01}
+test clock-3.315 {ISO week-based calendar 1971-W01-6} {
+ clock format 32227200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W01-6
+} {Sat Saturday 71 1971 6 01 01 6 01}
+test clock-3.316 {ISO week-based calendar 1971-W01-7} {
+ clock format 32313600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W01-7
+} {Sun Sunday 71 1971 7 02 01 0 01}
+test clock-3.317 {ISO week-based calendar 1971-W02-1} {
+ clock format 32400000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W02-1
+} {Mon Monday 71 1971 1 02 02 1 02}
+test clock-3.318 {ISO week-based calendar 1971-W52-1} {
+ clock format 62640000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W52-1
+} {Mon Monday 71 1971 1 52 52 1 52}
+test clock-3.319 {ISO week-based calendar 1971-W52-6} {
+ clock format 63072000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W52-6
+} {Sat Saturday 71 1971 6 00 52 6 00}
+test clock-3.320 {ISO week-based calendar 1971-W52-7} {
+ clock format 63158400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W52-7
+} {Sun Sunday 71 1971 7 01 52 0 00}
+test clock-3.321 {ISO week-based calendar 1972-W01-1} {
+ clock format 63244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W01-1
+} {Mon Monday 72 1972 1 01 01 1 01}
+test clock-3.322 {ISO week-based calendar 1972-W01-6} {
+ clock format 63676800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W01-6
+} {Sat Saturday 72 1972 6 01 01 6 01}
+test clock-3.323 {ISO week-based calendar 1972-W01-7} {
+ clock format 63763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W01-7
+} {Sun Sunday 72 1972 7 02 01 0 01}
+test clock-3.324 {ISO week-based calendar 1972-W02-1} {
+ clock format 63849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W02-1
+} {Mon Monday 72 1972 1 02 02 1 02}
+test clock-3.325 {ISO week-based calendar 1972-W52-1} {
+ clock format 94089600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W52-1
+} {Mon Monday 72 1972 1 52 52 1 52}
+test clock-3.326 {ISO week-based calendar 1972-W52-6} {
+ clock format 94521600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W52-6
+} {Sat Saturday 72 1972 6 52 52 6 52}
+test clock-3.327 {ISO week-based calendar 1972-W52-7} {
+ clock format 94608000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W52-7
+} {Sun Sunday 72 1972 7 53 52 0 52}
+test clock-3.328 {ISO week-based calendar 1973-W01-1} {
+ clock format 94694400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W01-1
+} {Mon Monday 73 1973 1 00 01 1 01}
+test clock-3.329 {ISO week-based calendar 1973-W01-6} {
+ clock format 95126400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W01-6
+} {Sat Saturday 73 1973 6 00 01 6 01}
+test clock-3.330 {ISO week-based calendar 1973-W01-7} {
+ clock format 95212800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W01-7
+} {Sun Sunday 73 1973 7 01 01 0 01}
+test clock-3.331 {ISO week-based calendar 1973-W02-1} {
+ clock format 95299200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W02-1
+} {Mon Monday 73 1973 1 01 02 1 02}
+test clock-3.332 {ISO week-based calendar 1973-W52-1} {
+ clock format 125539200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W52-1
+} {Mon Monday 73 1973 1 51 52 1 52}
+test clock-3.333 {ISO week-based calendar 1973-W52-6} {
+ clock format 125971200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W52-6
+} {Sat Saturday 73 1973 6 51 52 6 52}
+test clock-3.334 {ISO week-based calendar 1973-W52-7} {
+ clock format 126057600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W52-7
+} {Sun Sunday 73 1973 7 52 52 0 52}
+test clock-3.335 {ISO week-based calendar 1974-W01-1} {
+ clock format 126144000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W01-1
+} {Mon Monday 74 1974 1 52 01 1 53}
+test clock-3.336 {ISO week-based calendar 1974-W01-2} {
+ clock format 126230400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W01-2
+} {Tue Tuesday 74 1974 2 00 01 2 00}
+test clock-3.337 {ISO week-based calendar 1974-W01-6} {
+ clock format 126576000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W01-6
+} {Sat Saturday 74 1974 6 00 01 6 00}
+test clock-3.338 {ISO week-based calendar 1974-W01-7} {
+ clock format 126662400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W01-7
+} {Sun Sunday 74 1974 7 01 01 0 00}
+test clock-3.339 {ISO week-based calendar 1974-W02-1} {
+ clock format 126748800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W02-1
+} {Mon Monday 74 1974 1 01 02 1 01}
+test clock-3.340 {ISO week-based calendar 1974-W52-1} {
+ clock format 156988800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W52-1
+} {Mon Monday 74 1974 1 51 52 1 51}
+test clock-3.341 {ISO week-based calendar 1974-W52-6} {
+ clock format 157420800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W52-6
+} {Sat Saturday 74 1974 6 51 52 6 51}
+test clock-3.342 {ISO week-based calendar 1974-W52-7} {
+ clock format 157507200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W52-7
+} {Sun Sunday 74 1974 7 52 52 0 51}
+test clock-3.343 {ISO week-based calendar 1975-W01-1} {
+ clock format 157593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W01-1
+} {Mon Monday 75 1975 1 52 01 1 52}
+test clock-3.344 {ISO week-based calendar 1975-W01-3} {
+ clock format 157766400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W01-3
+} {Wed Wednesday 75 1975 3 00 01 3 00}
+test clock-3.345 {ISO week-based calendar 1975-W01-6} {
+ clock format 158025600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W01-6
+} {Sat Saturday 75 1975 6 00 01 6 00}
+test clock-3.346 {ISO week-based calendar 1975-W01-7} {
+ clock format 158112000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W01-7
+} {Sun Sunday 75 1975 7 01 01 0 00}
+test clock-3.347 {ISO week-based calendar 1975-W02-1} {
+ clock format 158198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W02-1
+} {Mon Monday 75 1975 1 01 02 1 01}
+test clock-3.348 {ISO week-based calendar 1975-W52-1} {
+ clock format 188438400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W52-1
+} {Mon Monday 75 1975 1 51 52 1 51}
+test clock-3.349 {ISO week-based calendar 1975-W52-6} {
+ clock format 188870400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W52-6
+} {Sat Saturday 75 1975 6 51 52 6 51}
+test clock-3.350 {ISO week-based calendar 1975-W52-7} {
+ clock format 188956800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W52-7
+} {Sun Sunday 75 1975 7 52 52 0 51}
+test clock-3.351 {ISO week-based calendar 1976-W01-1} {
+ clock format 189043200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W01-1
+} {Mon Monday 76 1976 1 52 01 1 52}
+test clock-3.352 {ISO week-based calendar 1976-W01-4} {
+ clock format 189302400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W01-4
+} {Thu Thursday 76 1976 4 00 01 4 00}
+test clock-3.353 {ISO week-based calendar 1976-W01-6} {
+ clock format 189475200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W01-6
+} {Sat Saturday 76 1976 6 00 01 6 00}
+test clock-3.354 {ISO week-based calendar 1976-W01-7} {
+ clock format 189561600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W01-7
+} {Sun Sunday 76 1976 7 01 01 0 00}
+test clock-3.355 {ISO week-based calendar 1976-W02-1} {
+ clock format 189648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W02-1
+} {Mon Monday 76 1976 1 01 02 1 01}
+test clock-3.356 {ISO week-based calendar 1976-W53-1} {
+ clock format 220492800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W53-1
+} {Mon Monday 76 1976 1 52 53 1 52}
+test clock-3.357 {ISO week-based calendar 1976-W53-6} {
+ clock format 220924800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W53-6
+} {Sat Saturday 76 1976 6 00 53 6 00}
+test clock-3.358 {ISO week-based calendar 1976-W53-7} {
+ clock format 221011200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W53-7
+} {Sun Sunday 76 1976 7 01 53 0 00}
+test clock-3.359 {ISO week-based calendar 1977-W01-1} {
+ clock format 221097600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W01-1
+} {Mon Monday 77 1977 1 01 01 1 01}
+test clock-3.360 {ISO week-based calendar 1977-W01-6} {
+ clock format 221529600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W01-6
+} {Sat Saturday 77 1977 6 01 01 6 01}
+test clock-3.361 {ISO week-based calendar 1977-W01-7} {
+ clock format 221616000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W01-7
+} {Sun Sunday 77 1977 7 02 01 0 01}
+test clock-3.362 {ISO week-based calendar 1977-W02-1} {
+ clock format 221702400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W02-1
+} {Mon Monday 77 1977 1 02 02 1 02}
+test clock-3.363 {ISO week-based calendar 1977-W52-1} {
+ clock format 251942400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W52-1
+} {Mon Monday 77 1977 1 52 52 1 52}
+test clock-3.364 {ISO week-based calendar 1977-W52-6} {
+ clock format 252374400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W52-6
+} {Sat Saturday 77 1977 6 52 52 6 52}
+test clock-3.365 {ISO week-based calendar 1977-W52-7} {
+ clock format 252460800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W52-7
+} {Sun Sunday 77 1977 7 01 52 0 00}
+test clock-3.366 {ISO week-based calendar 1978-W01-1} {
+ clock format 252547200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W01-1
+} {Mon Monday 78 1978 1 01 01 1 01}
+test clock-3.367 {ISO week-based calendar 1978-W01-6} {
+ clock format 252979200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W01-6
+} {Sat Saturday 78 1978 6 01 01 6 01}
+test clock-3.368 {ISO week-based calendar 1978-W01-7} {
+ clock format 253065600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W01-7
+} {Sun Sunday 78 1978 7 02 01 0 01}
+test clock-3.369 {ISO week-based calendar 1978-W02-1} {
+ clock format 253152000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W02-1
+} {Mon Monday 78 1978 1 02 02 1 02}
+test clock-3.370 {ISO week-based calendar 1978-W52-1} {
+ clock format 283392000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W52-1
+} {Mon Monday 78 1978 1 52 52 1 52}
+test clock-3.371 {ISO week-based calendar 1978-W52-6} {
+ clock format 283824000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W52-6
+} {Sat Saturday 78 1978 6 52 52 6 52}
+test clock-3.372 {ISO week-based calendar 1978-W52-7} {
+ clock format 283910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W52-7
+} {Sun Sunday 78 1978 7 53 52 0 52}
+test clock-3.373 {ISO week-based calendar 1979-W01-1} {
+ clock format 283996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W01-1
+} {Mon Monday 79 1979 1 00 01 1 01}
+test clock-3.374 {ISO week-based calendar 1979-W01-6} {
+ clock format 284428800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W01-6
+} {Sat Saturday 79 1979 6 00 01 6 01}
+test clock-3.375 {ISO week-based calendar 1979-W01-7} {
+ clock format 284515200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W01-7
+} {Sun Sunday 79 1979 7 01 01 0 01}
+test clock-3.376 {ISO week-based calendar 1979-W02-1} {
+ clock format 284601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W02-1
+} {Mon Monday 79 1979 1 01 02 1 02}
+test clock-3.377 {ISO week-based calendar 1979-W52-1} {
+ clock format 314841600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W52-1
+} {Mon Monday 79 1979 1 51 52 1 52}
+test clock-3.378 {ISO week-based calendar 1979-W52-6} {
+ clock format 315273600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W52-6
+} {Sat Saturday 79 1979 6 51 52 6 52}
+test clock-3.379 {ISO week-based calendar 1979-W52-7} {
+ clock format 315360000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W52-7
+} {Sun Sunday 79 1979 7 52 52 0 52}
+test clock-3.380 {ISO week-based calendar 1980-W01-1} {
+ clock format 315446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W01-1
+} {Mon Monday 80 1980 1 52 01 1 53}
+test clock-3.381 {ISO week-based calendar 1980-W01-2} {
+ clock format 315532800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W01-2
+} {Tue Tuesday 80 1980 2 00 01 2 00}
+test clock-3.382 {ISO week-based calendar 1980-W01-6} {
+ clock format 315878400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W01-6
+} {Sat Saturday 80 1980 6 00 01 6 00}
+test clock-3.383 {ISO week-based calendar 1980-W01-7} {
+ clock format 315964800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W01-7
+} {Sun Sunday 80 1980 7 01 01 0 00}
+test clock-3.384 {ISO week-based calendar 1980-W02-1} {
+ clock format 316051200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W02-1
+} {Mon Monday 80 1980 1 01 02 1 01}
+test clock-3.385 {ISO week-based calendar 1980-W52-1} {
+ clock format 346291200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W52-1
+} {Mon Monday 80 1980 1 51 52 1 51}
+test clock-3.386 {ISO week-based calendar 1980-W52-6} {
+ clock format 346723200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W52-6
+} {Sat Saturday 80 1980 6 51 52 6 51}
+test clock-3.387 {ISO week-based calendar 1980-W52-7} {
+ clock format 346809600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W52-7
+} {Sun Sunday 80 1980 7 52 52 0 51}
+test clock-3.388 {ISO week-based calendar 1981-W01-1} {
+ clock format 346896000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1981-W01-1
+} {Mon Monday 81 1981 1 52 01 1 52}
+test clock-3.389 {ISO week-based calendar 1981-W01-4} {
+ clock format 347155200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1981-W01-4
+} {Thu Thursday 81 1981 4 00 01 4 00}
+test clock-3.390 {ISO week-based calendar 1981-W01-6} {
+ clock format 347328000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1981-W01-6
+} {Sat Saturday 81 1981 6 00 01 6 00}
+test clock-3.391 {ISO week-based calendar 1981-W01-7} {
+ clock format 347414400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1981-W01-7
+} {Sun Sunday 81 1981 7 01 01 0 00}
+test clock-3.392 {ISO week-based calendar 1981-W02-1} {
+ clock format 347500800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1981-W02-1
+} {Mon Monday 81 1981 1 01 02 1 01}
+test clock-3.393 {ISO week-based calendar 1983-W52-1} {
+ clock format 441244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1983-W52-1
+} {Mon Monday 83 1983 1 52 52 1 52}
+test clock-3.394 {ISO week-based calendar 1983-W52-6} {
+ clock format 441676800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1983-W52-6
+} {Sat Saturday 83 1983 6 52 52 6 52}
+test clock-3.395 {ISO week-based calendar 1983-W52-7} {
+ clock format 441763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1983-W52-7
+} {Sun Sunday 83 1983 7 01 52 0 00}
+test clock-3.396 {ISO week-based calendar 1984-W01-1} {
+ clock format 441849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W01-1
+} {Mon Monday 84 1984 1 01 01 1 01}
+test clock-3.397 {ISO week-based calendar 1984-W01-6} {
+ clock format 442281600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W01-6
+} {Sat Saturday 84 1984 6 01 01 6 01}
+test clock-3.398 {ISO week-based calendar 1984-W01-7} {
+ clock format 442368000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W01-7
+} {Sun Sunday 84 1984 7 02 01 0 01}
+test clock-3.399 {ISO week-based calendar 1984-W02-1} {
+ clock format 442454400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W02-1
+} {Mon Monday 84 1984 1 02 02 1 02}
+test clock-3.400 {ISO week-based calendar 1984-W52-1} {
+ clock format 472694400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W52-1
+} {Mon Monday 84 1984 1 52 52 1 52}
+test clock-3.401 {ISO week-based calendar 1984-W52-6} {
+ clock format 473126400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W52-6
+} {Sat Saturday 84 1984 6 52 52 6 52}
+test clock-3.402 {ISO week-based calendar 1984-W52-7} {
+ clock format 473212800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W52-7
+} {Sun Sunday 84 1984 7 53 52 0 52}
+test clock-3.403 {ISO week-based calendar 1985-W01-1} {
+ clock format 473299200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1985-W01-1
+} {Mon Monday 85 1985 1 53 01 1 53}
+test clock-3.404 {ISO week-based calendar 1985-W01-2} {
+ clock format 473385600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1985-W01-2
+} {Tue Tuesday 85 1985 2 00 01 2 00}
+test clock-3.405 {ISO week-based calendar 1985-W01-6} {
+ clock format 473731200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1985-W01-6
+} {Sat Saturday 85 1985 6 00 01 6 00}
+test clock-3.406 {ISO week-based calendar 1985-W01-7} {
+ clock format 473817600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1985-W01-7
+} {Sun Sunday 85 1985 7 01 01 0 00}
+test clock-3.407 {ISO week-based calendar 1985-W02-1} {
+ clock format 473904000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1985-W02-1
+} {Mon Monday 85 1985 1 01 02 1 01}
+test clock-3.408 {ISO week-based calendar 1987-W53-1} {
+ clock format 567648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1987-W53-1
+} {Mon Monday 87 1987 1 52 53 1 52}
+test clock-3.409 {ISO week-based calendar 1987-W53-5} {
+ clock format 567993600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1987-W53-5
+} {Fri Friday 87 1987 5 00 53 5 00}
+test clock-3.410 {ISO week-based calendar 1987-W53-6} {
+ clock format 568080000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1987-W53-6
+} {Sat Saturday 87 1987 6 00 53 6 00}
+test clock-3.411 {ISO week-based calendar 1987-W53-7} {
+ clock format 568166400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1987-W53-7
+} {Sun Sunday 87 1987 7 01 53 0 00}
+test clock-3.412 {ISO week-based calendar 1988-W01-1} {
+ clock format 568252800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W01-1
+} {Mon Monday 88 1988 1 01 01 1 01}
+test clock-3.413 {ISO week-based calendar 1988-W01-6} {
+ clock format 568684800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W01-6
+} {Sat Saturday 88 1988 6 01 01 6 01}
+test clock-3.414 {ISO week-based calendar 1988-W01-7} {
+ clock format 568771200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W01-7
+} {Sun Sunday 88 1988 7 02 01 0 01}
+test clock-3.415 {ISO week-based calendar 1988-W02-1} {
+ clock format 568857600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W02-1
+} {Mon Monday 88 1988 1 02 02 1 02}
+test clock-3.416 {ISO week-based calendar 1988-W52-1} {
+ clock format 599097600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W52-1
+} {Mon Monday 88 1988 1 52 52 1 52}
+test clock-3.417 {ISO week-based calendar 1988-W52-6} {
+ clock format 599529600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W52-6
+} {Sat Saturday 88 1988 6 52 52 6 52}
+test clock-3.418 {ISO week-based calendar 1988-W52-7} {
+ clock format 599616000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W52-7
+} {Sun Sunday 88 1988 7 01 52 0 00}
+test clock-3.419 {ISO week-based calendar 1989-W01-1} {
+ clock format 599702400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1989-W01-1
+} {Mon Monday 89 1989 1 01 01 1 01}
+test clock-3.420 {ISO week-based calendar 1989-W01-6} {
+ clock format 600134400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1989-W01-6
+} {Sat Saturday 89 1989 6 01 01 6 01}
+test clock-3.421 {ISO week-based calendar 1989-W01-7} {
+ clock format 600220800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1989-W01-7
+} {Sun Sunday 89 1989 7 02 01 0 01}
+test clock-3.422 {ISO week-based calendar 1989-W02-1} {
+ clock format 600307200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1989-W02-1
+} {Mon Monday 89 1989 1 02 02 1 02}
+test clock-3.423 {ISO week-based calendar 1991-W52-1} {
+ clock format 693446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1991-W52-1
+} {Mon Monday 91 1991 1 51 52 1 51}
+test clock-3.424 {ISO week-based calendar 1991-W52-6} {
+ clock format 693878400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1991-W52-6
+} {Sat Saturday 91 1991 6 51 52 6 51}
+test clock-3.425 {ISO week-based calendar 1991-W52-7} {
+ clock format 693964800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1991-W52-7
+} {Sun Sunday 91 1991 7 52 52 0 51}
+test clock-3.426 {ISO week-based calendar 1992-W01-1} {
+ clock format 694051200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W01-1
+} {Mon Monday 92 1992 1 52 01 1 52}
+test clock-3.427 {ISO week-based calendar 1992-W01-3} {
+ clock format 694224000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W01-3
+} {Wed Wednesday 92 1992 3 00 01 3 00}
+test clock-3.428 {ISO week-based calendar 1992-W01-6} {
+ clock format 694483200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W01-6
+} {Sat Saturday 92 1992 6 00 01 6 00}
+test clock-3.429 {ISO week-based calendar 1992-W01-7} {
+ clock format 694569600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W01-7
+} {Sun Sunday 92 1992 7 01 01 0 00}
+test clock-3.430 {ISO week-based calendar 1992-W02-1} {
+ clock format 694656000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W02-1
+} {Mon Monday 92 1992 1 01 02 1 01}
+test clock-3.431 {ISO week-based calendar 1992-W53-1} {
+ clock format 725500800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W53-1
+} {Mon Monday 92 1992 1 52 53 1 52}
+test clock-3.432 {ISO week-based calendar 1992-W53-5} {
+ clock format 725846400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W53-5
+} {Fri Friday 92 1992 5 00 53 5 00}
+test clock-3.433 {ISO week-based calendar 1992-W53-6} {
+ clock format 725932800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W53-6
+} {Sat Saturday 92 1992 6 00 53 6 00}
+test clock-3.434 {ISO week-based calendar 1992-W53-7} {
+ clock format 726019200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W53-7
+} {Sun Sunday 92 1992 7 01 53 0 00}
+test clock-3.435 {ISO week-based calendar 1993-W01-1} {
+ clock format 726105600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1993-W01-1
+} {Mon Monday 93 1993 1 01 01 1 01}
+test clock-3.436 {ISO week-based calendar 1993-W01-6} {
+ clock format 726537600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1993-W01-6
+} {Sat Saturday 93 1993 6 01 01 6 01}
+test clock-3.437 {ISO week-based calendar 1993-W01-7} {
+ clock format 726624000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1993-W01-7
+} {Sun Sunday 93 1993 7 02 01 0 01}
+test clock-3.438 {ISO week-based calendar 1993-W02-1} {
+ clock format 726710400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1993-W02-1
+} {Mon Monday 93 1993 1 02 02 1 02}
+test clock-3.439 {ISO week-based calendar 1995-W52-1} {
+ clock format 819849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1995-W52-1
+} {Mon Monday 95 1995 1 52 52 1 52}
+test clock-3.440 {ISO week-based calendar 1995-W52-6} {
+ clock format 820281600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1995-W52-6
+} {Sat Saturday 95 1995 6 52 52 6 52}
+test clock-3.441 {ISO week-based calendar 1995-W52-7} {
+ clock format 820368000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1995-W52-7
+} {Sun Sunday 95 1995 7 53 52 0 52}
+test clock-3.442 {ISO week-based calendar 1996-W01-1} {
+ clock format 820454400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W01-1
+} {Mon Monday 96 1996 1 00 01 1 01}
+test clock-3.443 {ISO week-based calendar 1996-W01-6} {
+ clock format 820886400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W01-6
+} {Sat Saturday 96 1996 6 00 01 6 01}
+test clock-3.444 {ISO week-based calendar 1996-W01-7} {
+ clock format 820972800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W01-7
+} {Sun Sunday 96 1996 7 01 01 0 01}
+test clock-3.445 {ISO week-based calendar 1996-W02-1} {
+ clock format 821059200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W02-1
+} {Mon Monday 96 1996 1 01 02 1 02}
+test clock-3.446 {ISO week-based calendar 1996-W52-1} {
+ clock format 851299200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W52-1
+} {Mon Monday 96 1996 1 51 52 1 52}
+test clock-3.447 {ISO week-based calendar 1996-W52-6} {
+ clock format 851731200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W52-6
+} {Sat Saturday 96 1996 6 51 52 6 52}
+test clock-3.448 {ISO week-based calendar 1996-W52-7} {
+ clock format 851817600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W52-7
+} {Sun Sunday 96 1996 7 52 52 0 52}
+test clock-3.449 {ISO week-based calendar 1997-W01-1} {
+ clock format 851904000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1997-W01-1
+} {Mon Monday 97 1997 1 52 01 1 53}
+test clock-3.450 {ISO week-based calendar 1997-W01-3} {
+ clock format 852076800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1997-W01-3
+} {Wed Wednesday 97 1997 3 00 01 3 00}
+test clock-3.451 {ISO week-based calendar 1997-W01-6} {
+ clock format 852336000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1997-W01-6
+} {Sat Saturday 97 1997 6 00 01 6 00}
+test clock-3.452 {ISO week-based calendar 1997-W01-7} {
+ clock format 852422400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1997-W01-7
+} {Sun Sunday 97 1997 7 01 01 0 00}
+test clock-3.453 {ISO week-based calendar 1997-W02-1} {
+ clock format 852508800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1997-W02-1
+} {Mon Monday 97 1997 1 01 02 1 01}
+test clock-3.454 {ISO week-based calendar 1999-W52-1} {
+ clock format 946252800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1999-W52-1
+} {Mon Monday 99 1999 1 52 52 1 52}
+test clock-3.455 {ISO week-based calendar 1999-W52-6} {
+ clock format 946684800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1999-W52-6
+} {Sat Saturday 99 1999 6 00 52 6 00}
+test clock-3.456 {ISO week-based calendar 1999-W52-7} {
+ clock format 946771200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1999-W52-7
+} {Sun Sunday 99 1999 7 01 52 0 00}
+test clock-3.457 {ISO week-based calendar 2000-W01-1} {
+ clock format 946857600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W01-1
+} {Mon Monday 00 2000 1 01 01 1 01}
+test clock-3.458 {ISO week-based calendar 2000-W01-6} {
+ clock format 947289600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W01-6
+} {Sat Saturday 00 2000 6 01 01 6 01}
+test clock-3.459 {ISO week-based calendar 2000-W01-7} {
+ clock format 947376000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W01-7
+} {Sun Sunday 00 2000 7 02 01 0 01}
+test clock-3.460 {ISO week-based calendar 2000-W02-1} {
+ clock format 947462400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W02-1
+} {Mon Monday 00 2000 1 02 02 1 02}
+test clock-3.461 {ISO week-based calendar 2000-W52-1} {
+ clock format 977702400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W52-1
+} {Mon Monday 00 2000 1 52 52 1 52}
+test clock-3.462 {ISO week-based calendar 2000-W52-6} {
+ clock format 978134400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W52-6
+} {Sat Saturday 00 2000 6 52 52 6 52}
+test clock-3.463 {ISO week-based calendar 2000-W52-7} {
+ clock format 978220800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W52-7
+} {Sun Sunday 00 2000 7 53 52 0 52}
+test clock-3.464 {ISO week-based calendar 2001-W01-1} {
+ clock format 978307200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W01-1
+} {Mon Monday 01 2001 1 00 01 1 01}
+test clock-3.465 {ISO week-based calendar 2001-W01-6} {
+ clock format 978739200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W01-6
+} {Sat Saturday 01 2001 6 00 01 6 01}
+test clock-3.466 {ISO week-based calendar 2001-W01-7} {
+ clock format 978825600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W01-7
+} {Sun Sunday 01 2001 7 01 01 0 01}
+test clock-3.467 {ISO week-based calendar 2001-W02-1} {
+ clock format 978912000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W02-1
+} {Mon Monday 01 2001 1 01 02 1 02}
+test clock-3.468 {ISO week-based calendar 2001-W52-1} {
+ clock format 1009152000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W52-1
+} {Mon Monday 01 2001 1 51 52 1 52}
+test clock-3.469 {ISO week-based calendar 2001-W52-6} {
+ clock format 1009584000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W52-6
+} {Sat Saturday 01 2001 6 51 52 6 52}
+test clock-3.470 {ISO week-based calendar 2001-W52-7} {
+ clock format 1009670400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W52-7
+} {Sun Sunday 01 2001 7 52 52 0 52}
+test clock-3.471 {ISO week-based calendar 2002-W01-1} {
+ clock format 1009756800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W01-1
+} {Mon Monday 02 2002 1 52 01 1 53}
+test clock-3.472 {ISO week-based calendar 2002-W01-2} {
+ clock format 1009843200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W01-2
+} {Tue Tuesday 02 2002 2 00 01 2 00}
+test clock-3.473 {ISO week-based calendar 2002-W01-6} {
+ clock format 1010188800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W01-6
+} {Sat Saturday 02 2002 6 00 01 6 00}
+test clock-3.474 {ISO week-based calendar 2002-W01-7} {
+ clock format 1010275200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W01-7
+} {Sun Sunday 02 2002 7 01 01 0 00}
+test clock-3.475 {ISO week-based calendar 2002-W02-1} {
+ clock format 1010361600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W02-1
+} {Mon Monday 02 2002 1 01 02 1 01}
+test clock-3.476 {ISO week-based calendar 2002-W52-1} {
+ clock format 1040601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W52-1
+} {Mon Monday 02 2002 1 51 52 1 51}
+test clock-3.477 {ISO week-based calendar 2002-W52-6} {
+ clock format 1041033600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W52-6
+} {Sat Saturday 02 2002 6 51 52 6 51}
+test clock-3.478 {ISO week-based calendar 2002-W52-7} {
+ clock format 1041120000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W52-7
+} {Sun Sunday 02 2002 7 52 52 0 51}
+test clock-3.479 {ISO week-based calendar 2003-W01-1} {
+ clock format 1041206400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W01-1
+} {Mon Monday 03 2003 1 52 01 1 52}
+test clock-3.480 {ISO week-based calendar 2003-W01-3} {
+ clock format 1041379200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W01-3
+} {Wed Wednesday 03 2003 3 00 01 3 00}
+test clock-3.481 {ISO week-based calendar 2003-W01-6} {
+ clock format 1041638400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W01-6
+} {Sat Saturday 03 2003 6 00 01 6 00}
+test clock-3.482 {ISO week-based calendar 2003-W01-7} {
+ clock format 1041724800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W01-7
+} {Sun Sunday 03 2003 7 01 01 0 00}
+test clock-3.483 {ISO week-based calendar 2003-W02-1} {
+ clock format 1041811200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W02-1
+} {Mon Monday 03 2003 1 01 02 1 01}
+test clock-3.484 {ISO week-based calendar 2003-W52-1} {
+ clock format 1072051200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W52-1
+} {Mon Monday 03 2003 1 51 52 1 51}
+test clock-3.485 {ISO week-based calendar 2003-W52-6} {
+ clock format 1072483200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W52-6
+} {Sat Saturday 03 2003 6 51 52 6 51}
+test clock-3.486 {ISO week-based calendar 2003-W52-7} {
+ clock format 1072569600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W52-7
+} {Sun Sunday 03 2003 7 52 52 0 51}
+test clock-3.487 {ISO week-based calendar 2004-W01-1} {
+ clock format 1072656000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W01-1
+} {Mon Monday 04 2004 1 52 01 1 52}
+test clock-3.488 {ISO week-based calendar 2004-W01-4} {
+ clock format 1072915200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W01-4
+} {Thu Thursday 04 2004 4 00 01 4 00}
+test clock-3.489 {ISO week-based calendar 2004-W01-6} {
+ clock format 1073088000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W01-6
+} {Sat Saturday 04 2004 6 00 01 6 00}
+test clock-3.490 {ISO week-based calendar 2004-W01-7} {
+ clock format 1073174400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W01-7
+} {Sun Sunday 04 2004 7 01 01 0 00}
+test clock-3.491 {ISO week-based calendar 2004-W02-1} {
+ clock format 1073260800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W02-1
+} {Mon Monday 04 2004 1 01 02 1 01}
+test clock-3.492 {ISO week-based calendar 2004-W53-1} {
+ clock format 1104105600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W53-1
+} {Mon Monday 04 2004 1 52 53 1 52}
+test clock-3.493 {ISO week-based calendar 2004-W53-6} {
+ clock format 1104537600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W53-6
+} {Sat Saturday 04 2004 6 00 53 6 00}
+test clock-3.494 {ISO week-based calendar 2004-W53-7} {
+ clock format 1104624000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W53-7
+} {Sun Sunday 04 2004 7 01 53 0 00}
+test clock-3.495 {ISO week-based calendar 2005-W01-1} {
+ clock format 1104710400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W01-1
+} {Mon Monday 05 2005 1 01 01 1 01}
+test clock-3.496 {ISO week-based calendar 2005-W01-6} {
+ clock format 1105142400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W01-6
+} {Sat Saturday 05 2005 6 01 01 6 01}
+test clock-3.497 {ISO week-based calendar 2005-W01-7} {
+ clock format 1105228800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W01-7
+} {Sun Sunday 05 2005 7 02 01 0 01}
+test clock-3.498 {ISO week-based calendar 2005-W02-1} {
+ clock format 1105315200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W02-1
+} {Mon Monday 05 2005 1 02 02 1 02}
+test clock-3.499 {ISO week-based calendar 2005-W52-1} {
+ clock format 1135555200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W52-1
+} {Mon Monday 05 2005 1 52 52 1 52}
+test clock-3.500 {ISO week-based calendar 2005-W52-6} {
+ clock format 1135987200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W52-6
+} {Sat Saturday 05 2005 6 52 52 6 52}
+test clock-3.501 {ISO week-based calendar 2005-W52-7} {
+ clock format 1136073600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W52-7
+} {Sun Sunday 05 2005 7 01 52 0 00}
+test clock-3.502 {ISO week-based calendar 2006-W01-1} {
+ clock format 1136160000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W01-1
+} {Mon Monday 06 2006 1 01 01 1 01}
+test clock-3.503 {ISO week-based calendar 2006-W01-6} {
+ clock format 1136592000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W01-6
+} {Sat Saturday 06 2006 6 01 01 6 01}
+test clock-3.504 {ISO week-based calendar 2006-W01-7} {
+ clock format 1136678400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W01-7
+} {Sun Sunday 06 2006 7 02 01 0 01}
+test clock-3.505 {ISO week-based calendar 2006-W02-1} {
+ clock format 1136764800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W02-1
+} {Mon Monday 06 2006 1 02 02 1 02}
+test clock-3.506 {ISO week-based calendar 2006-W52-1} {
+ clock format 1167004800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W52-1
+} {Mon Monday 06 2006 1 52 52 1 52}
+test clock-3.507 {ISO week-based calendar 2006-W52-6} {
+ clock format 1167436800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W52-6
+} {Sat Saturday 06 2006 6 52 52 6 52}
+test clock-3.508 {ISO week-based calendar 2006-W52-7} {
+ clock format 1167523200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W52-7
+} {Sun Sunday 06 2006 7 53 52 0 52}
+test clock-3.509 {ISO week-based calendar 2007-W01-1} {
+ clock format 1167609600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W01-1
+} {Mon Monday 07 2007 1 00 01 1 01}
+test clock-3.510 {ISO week-based calendar 2007-W01-6} {
+ clock format 1168041600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W01-6
+} {Sat Saturday 07 2007 6 00 01 6 01}
+test clock-3.511 {ISO week-based calendar 2007-W01-7} {
+ clock format 1168128000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W01-7
+} {Sun Sunday 07 2007 7 01 01 0 01}
+test clock-3.512 {ISO week-based calendar 2007-W02-1} {
+ clock format 1168214400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W02-1
+} {Mon Monday 07 2007 1 01 02 1 02}
+test clock-3.513 {ISO week-based calendar 2007-W52-1} {
+ clock format 1198454400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W52-1
+} {Mon Monday 07 2007 1 51 52 1 52}
+test clock-3.514 {ISO week-based calendar 2007-W52-6} {
+ clock format 1198886400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W52-6
+} {Sat Saturday 07 2007 6 51 52 6 52}
+test clock-3.515 {ISO week-based calendar 2007-W52-7} {
+ clock format 1198972800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W52-7
+} {Sun Sunday 07 2007 7 52 52 0 52}
+test clock-3.516 {ISO week-based calendar 2008-W01-1} {
+ clock format 1199059200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W01-1
+} {Mon Monday 08 2008 1 52 01 1 53}
+test clock-3.517 {ISO week-based calendar 2008-W01-2} {
+ clock format 1199145600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W01-2
+} {Tue Tuesday 08 2008 2 00 01 2 00}
+test clock-3.518 {ISO week-based calendar 2008-W01-6} {
+ clock format 1199491200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W01-6
+} {Sat Saturday 08 2008 6 00 01 6 00}
+test clock-3.519 {ISO week-based calendar 2008-W01-7} {
+ clock format 1199577600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W01-7
+} {Sun Sunday 08 2008 7 01 01 0 00}
+test clock-3.520 {ISO week-based calendar 2008-W02-1} {
+ clock format 1199664000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W02-1
+} {Mon Monday 08 2008 1 01 02 1 01}
+test clock-3.521 {ISO week-based calendar 2008-W52-1} {
+ clock format 1229904000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W52-1
+} {Mon Monday 08 2008 1 51 52 1 51}
+test clock-3.522 {ISO week-based calendar 2008-W52-6} {
+ clock format 1230336000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W52-6
+} {Sat Saturday 08 2008 6 51 52 6 51}
+test clock-3.523 {ISO week-based calendar 2008-W52-7} {
+ clock format 1230422400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W52-7
+} {Sun Sunday 08 2008 7 52 52 0 51}
+test clock-3.524 {ISO week-based calendar 2009-W01-1} {
+ clock format 1230508800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W01-1
+} {Mon Monday 09 2009 1 52 01 1 52}
+test clock-3.525 {ISO week-based calendar 2009-W01-4} {
+ clock format 1230768000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W01-4
+} {Thu Thursday 09 2009 4 00 01 4 00}
+test clock-3.526 {ISO week-based calendar 2009-W01-6} {
+ clock format 1230940800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W01-6
+} {Sat Saturday 09 2009 6 00 01 6 00}
+test clock-3.527 {ISO week-based calendar 2009-W01-7} {
+ clock format 1231027200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W01-7
+} {Sun Sunday 09 2009 7 01 01 0 00}
+test clock-3.528 {ISO week-based calendar 2009-W02-1} {
+ clock format 1231113600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W02-1
+} {Mon Monday 09 2009 1 01 02 1 01}
+test clock-3.529 {ISO week-based calendar 2009-W53-1} {
+ clock format 1261958400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W53-1
+} {Mon Monday 09 2009 1 52 53 1 52}
+test clock-3.530 {ISO week-based calendar 2009-W53-5} {
+ clock format 1262304000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W53-5
+} {Fri Friday 09 2009 5 00 53 5 00}
+test clock-3.531 {ISO week-based calendar 2009-W53-6} {
+ clock format 1262390400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W53-6
+} {Sat Saturday 09 2009 6 00 53 6 00}
+test clock-3.532 {ISO week-based calendar 2009-W53-7} {
+ clock format 1262476800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W53-7
+} {Sun Sunday 09 2009 7 01 53 0 00}
+test clock-3.533 {ISO week-based calendar 2010-W01-1} {
+ clock format 1262563200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W01-1
+} {Mon Monday 10 2010 1 01 01 1 01}
+test clock-3.534 {ISO week-based calendar 2010-W01-6} {
+ clock format 1262995200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W01-6
+} {Sat Saturday 10 2010 6 01 01 6 01}
+test clock-3.535 {ISO week-based calendar 2010-W01-7} {
+ clock format 1263081600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W01-7
+} {Sun Sunday 10 2010 7 02 01 0 01}
+test clock-3.536 {ISO week-based calendar 2010-W02-1} {
+ clock format 1263168000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W02-1
+} {Mon Monday 10 2010 1 02 02 1 02}
+test clock-3.537 {ISO week-based calendar 2010-W52-1} {
+ clock format 1293408000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W52-1
+} {Mon Monday 10 2010 1 52 52 1 52}
+test clock-3.538 {ISO week-based calendar 2010-W52-6} {
+ clock format 1293840000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W52-6
+} {Sat Saturday 10 2010 6 00 52 6 00}
+test clock-3.539 {ISO week-based calendar 2010-W52-7} {
+ clock format 1293926400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W52-7
+} {Sun Sunday 10 2010 7 01 52 0 00}
+test clock-3.540 {ISO week-based calendar 2011-W01-1} {
+ clock format 1294012800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W01-1
+} {Mon Monday 11 2011 1 01 01 1 01}
+test clock-3.541 {ISO week-based calendar 2011-W01-6} {
+ clock format 1294444800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W01-6
+} {Sat Saturday 11 2011 6 01 01 6 01}
+test clock-3.542 {ISO week-based calendar 2011-W01-7} {
+ clock format 1294531200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W01-7
+} {Sun Sunday 11 2011 7 02 01 0 01}
+test clock-3.543 {ISO week-based calendar 2011-W02-1} {
+ clock format 1294617600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W02-1
+} {Mon Monday 11 2011 1 02 02 1 02}
+test clock-3.544 {ISO week-based calendar 2011-W52-1} {
+ clock format 1324857600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W52-1
+} {Mon Monday 11 2011 1 52 52 1 52}
+test clock-3.545 {ISO week-based calendar 2011-W52-6} {
+ clock format 1325289600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W52-6
+} {Sat Saturday 11 2011 6 52 52 6 52}
+test clock-3.546 {ISO week-based calendar 2011-W52-7} {
+ clock format 1325376000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W52-7
+} {Sun Sunday 11 2011 7 01 52 0 00}
+test clock-3.547 {ISO week-based calendar 2012-W01-1} {
+ clock format 1325462400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W01-1
+} {Mon Monday 12 2012 1 01 01 1 01}
+test clock-3.548 {ISO week-based calendar 2012-W01-6} {
+ clock format 1325894400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W01-6
+} {Sat Saturday 12 2012 6 01 01 6 01}
+test clock-3.549 {ISO week-based calendar 2012-W01-7} {
+ clock format 1325980800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W01-7
+} {Sun Sunday 12 2012 7 02 01 0 01}
+test clock-3.550 {ISO week-based calendar 2012-W02-1} {
+ clock format 1326067200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W02-1
+} {Mon Monday 12 2012 1 02 02 1 02}
+test clock-3.551 {ISO week-based calendar 2012-W52-1} {
+ clock format 1356307200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W52-1
+} {Mon Monday 12 2012 1 52 52 1 52}
+test clock-3.552 {ISO week-based calendar 2012-W52-6} {
+ clock format 1356739200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W52-6
+} {Sat Saturday 12 2012 6 52 52 6 52}
+test clock-3.553 {ISO week-based calendar 2012-W52-7} {
+ clock format 1356825600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W52-7
+} {Sun Sunday 12 2012 7 53 52 0 52}
+test clock-3.554 {ISO week-based calendar 2013-W01-1} {
+ clock format 1356912000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2013-W01-1
+} {Mon Monday 13 2013 1 53 01 1 53}
+test clock-3.555 {ISO week-based calendar 2013-W01-2} {
+ clock format 1356998400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2013-W01-2
+} {Tue Tuesday 13 2013 2 00 01 2 00}
+test clock-3.556 {ISO week-based calendar 2013-W01-6} {
+ clock format 1357344000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2013-W01-6
+} {Sat Saturday 13 2013 6 00 01 6 00}
+test clock-3.557 {ISO week-based calendar 2013-W01-7} {
+ clock format 1357430400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2013-W01-7
+} {Sun Sunday 13 2013 7 01 01 0 00}
+test clock-3.558 {ISO week-based calendar 2013-W02-1} {
+ clock format 1357516800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2013-W02-1
+} {Mon Monday 13 2013 1 01 02 1 01}
+test clock-3.559 {ISO week-based calendar 2015-W53-1} {
+ clock format 1451260800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2015-W53-1
+} {Mon Monday 15 2015 1 52 53 1 52}
+test clock-3.560 {ISO week-based calendar 2015-W53-5} {
+ clock format 1451606400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2015-W53-5
+} {Fri Friday 15 2015 5 00 53 5 00}
+test clock-3.561 {ISO week-based calendar 2015-W53-6} {
+ clock format 1451692800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2015-W53-6
+} {Sat Saturday 15 2015 6 00 53 6 00}
+test clock-3.562 {ISO week-based calendar 2015-W53-7} {
+ clock format 1451779200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2015-W53-7
+} {Sun Sunday 15 2015 7 01 53 0 00}
+test clock-3.563 {ISO week-based calendar 2016-W01-1} {
+ clock format 1451865600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W01-1
+} {Mon Monday 16 2016 1 01 01 1 01}
+test clock-3.564 {ISO week-based calendar 2016-W01-6} {
+ clock format 1452297600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W01-6
+} {Sat Saturday 16 2016 6 01 01 6 01}
+test clock-3.565 {ISO week-based calendar 2016-W01-7} {
+ clock format 1452384000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W01-7
+} {Sun Sunday 16 2016 7 02 01 0 01}
+test clock-3.566 {ISO week-based calendar 2016-W02-1} {
+ clock format 1452470400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W02-1
+} {Mon Monday 16 2016 1 02 02 1 02}
+test clock-3.567 {ISO week-based calendar 2016-W52-1} {
+ clock format 1482710400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W52-1
+} {Mon Monday 16 2016 1 52 52 1 52}
+test clock-3.568 {ISO week-based calendar 2016-W52-6} {
+ clock format 1483142400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W52-6
+} {Sat Saturday 16 2016 6 52 52 6 52}
+test clock-3.569 {ISO week-based calendar 2016-W52-7} {
+ clock format 1483228800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W52-7
+} {Sun Sunday 16 2016 7 01 52 0 00}
+test clock-3.570 {ISO week-based calendar 2017-W01-1} {
+ clock format 1483315200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2017-W01-1
+} {Mon Monday 17 2017 1 01 01 1 01}
+test clock-3.571 {ISO week-based calendar 2017-W01-6} {
+ clock format 1483747200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2017-W01-6
+} {Sat Saturday 17 2017 6 01 01 6 01}
+test clock-3.572 {ISO week-based calendar 2017-W01-7} {
+ clock format 1483833600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2017-W01-7
+} {Sun Sunday 17 2017 7 02 01 0 01}
+test clock-3.573 {ISO week-based calendar 2017-W02-1} {
+ clock format 1483920000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2017-W02-1
+} {Mon Monday 17 2017 1 02 02 1 02}
+test clock-3.574 {ISO week-based calendar 2019-W52-1} {
+ clock format 1577059200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2019-W52-1
+} {Mon Monday 19 2019 1 51 52 1 51}
+test clock-3.575 {ISO week-based calendar 2019-W52-6} {
+ clock format 1577491200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2019-W52-6
+} {Sat Saturday 19 2019 6 51 52 6 51}
+test clock-3.576 {ISO week-based calendar 2019-W52-7} {
+ clock format 1577577600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2019-W52-7
+} {Sun Sunday 19 2019 7 52 52 0 51}
+test clock-3.577 {ISO week-based calendar 2020-W01-1} {
+ clock format 1577664000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W01-1
+} {Mon Monday 20 2020 1 52 01 1 52}
+test clock-3.578 {ISO week-based calendar 2020-W01-3} {
+ clock format 1577836800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W01-3
+} {Wed Wednesday 20 2020 3 00 01 3 00}
+test clock-3.579 {ISO week-based calendar 2020-W01-6} {
+ clock format 1578096000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W01-6
+} {Sat Saturday 20 2020 6 00 01 6 00}
+test clock-3.580 {ISO week-based calendar 2020-W01-7} {
+ clock format 1578182400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W01-7
+} {Sun Sunday 20 2020 7 01 01 0 00}
+test clock-3.581 {ISO week-based calendar 2020-W02-1} {
+ clock format 1578268800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W02-1
+} {Mon Monday 20 2020 1 01 02 1 01}
+test clock-3.582 {ISO week-based calendar 2020-W53-1} {
+ clock format 1609113600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W53-1
+} {Mon Monday 20 2020 1 52 53 1 52}
+test clock-3.583 {ISO week-based calendar 2020-W53-5} {
+ clock format 1609459200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W53-5
+} {Fri Friday 20 2020 5 00 53 5 00}
+test clock-3.584 {ISO week-based calendar 2020-W53-6} {
+ clock format 1609545600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W53-6
+} {Sat Saturday 20 2020 6 00 53 6 00}
+test clock-3.585 {ISO week-based calendar 2020-W53-7} {
+ clock format 1609632000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W53-7
+} {Sun Sunday 20 2020 7 01 53 0 00}
+test clock-3.586 {ISO week-based calendar 2021-W01-1} {
+ clock format 1609718400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2021-W01-1
+} {Mon Monday 21 2021 1 01 01 1 01}
+test clock-3.587 {ISO week-based calendar 2021-W01-6} {
+ clock format 1610150400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2021-W01-6
+} {Sat Saturday 21 2021 6 01 01 6 01}
+test clock-3.588 {ISO week-based calendar 2021-W01-7} {
+ clock format 1610236800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2021-W01-7
+} {Sun Sunday 21 2021 7 02 01 0 01}
+test clock-3.589 {ISO week-based calendar 2021-W02-1} {
+ clock format 1610323200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2021-W02-1
+} {Mon Monday 21 2021 1 02 02 1 02}
+test clock-3.590 {ISO week-based calendar 2023-W52-1} {
+ clock format 1703462400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2023-W52-1
+} {Mon Monday 23 2023 1 52 52 1 52}
+test clock-3.591 {ISO week-based calendar 2023-W52-6} {
+ clock format 1703894400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2023-W52-6
+} {Sat Saturday 23 2023 6 52 52 6 52}
+test clock-3.592 {ISO week-based calendar 2023-W52-7} {
+ clock format 1703980800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2023-W52-7
+} {Sun Sunday 23 2023 7 53 52 0 52}
+test clock-3.593 {ISO week-based calendar 2024-W01-1} {
+ clock format 1704067200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W01-1
+} {Mon Monday 24 2024 1 00 01 1 01}
+test clock-3.594 {ISO week-based calendar 2024-W01-6} {
+ clock format 1704499200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W01-6
+} {Sat Saturday 24 2024 6 00 01 6 01}
+test clock-3.595 {ISO week-based calendar 2024-W01-7} {
+ clock format 1704585600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W01-7
+} {Sun Sunday 24 2024 7 01 01 0 01}
+test clock-3.596 {ISO week-based calendar 2024-W02-1} {
+ clock format 1704672000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W02-1
+} {Mon Monday 24 2024 1 01 02 1 02}
+test clock-3.597 {ISO week-based calendar 2024-W52-1} {
+ clock format 1734912000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W52-1
+} {Mon Monday 24 2024 1 51 52 1 52}
+test clock-3.598 {ISO week-based calendar 2024-W52-6} {
+ clock format 1735344000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W52-6
+} {Sat Saturday 24 2024 6 51 52 6 52}
+test clock-3.599 {ISO week-based calendar 2024-W52-7} {
+ clock format 1735430400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W52-7
+} {Sun Sunday 24 2024 7 52 52 0 52}
+test clock-3.600 {ISO week-based calendar 2025-W01-1} {
+ clock format 1735516800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2025-W01-1
+} {Mon Monday 25 2025 1 52 01 1 53}
+test clock-3.601 {ISO week-based calendar 2025-W01-3} {
+ clock format 1735689600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2025-W01-3
+} {Wed Wednesday 25 2025 3 00 01 3 00}
+test clock-3.602 {ISO week-based calendar 2025-W01-6} {
+ clock format 1735948800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2025-W01-6
+} {Sat Saturday 25 2025 6 00 01 6 00}
+test clock-3.603 {ISO week-based calendar 2025-W01-7} {
+ clock format 1736035200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2025-W01-7
+} {Sun Sunday 25 2025 7 01 01 0 00}
+test clock-3.604 {ISO week-based calendar 2025-W02-1} {
+ clock format 1736121600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2025-W02-1
+} {Mon Monday 25 2025 1 01 02 1 01}
+test clock-3.605 {ISO week-based calendar 2036-W52-1} {
+ clock format 2113516800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2036-W52-1
+} {Mon Monday 36 2036 1 51 52 1 51}
+test clock-3.606 {ISO week-based calendar 2036-W52-6} {
+ clock format 2113948800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2036-W52-6
+} {Sat Saturday 36 2036 6 51 52 6 51}
+test clock-3.607 {ISO week-based calendar 2036-W52-7} {
+ clock format 2114035200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2036-W52-7
+} {Sun Sunday 36 2036 7 52 52 0 51}
+test clock-3.608 {ISO week-based calendar 2037-W01-1} {
+ clock format 2114121600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W01-1
+} {Mon Monday 37 2037 1 52 01 1 52}
+test clock-3.609 {ISO week-based calendar 2037-W01-4} {
+ clock format 2114380800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W01-4
+} {Thu Thursday 37 2037 4 00 01 4 00}
+test clock-3.610 {ISO week-based calendar 2037-W01-6} {
+ clock format 2114553600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W01-6
+} {Sat Saturday 37 2037 6 00 01 6 00}
+test clock-3.611 {ISO week-based calendar 2037-W01-7} {
+ clock format 2114640000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W01-7
+} {Sun Sunday 37 2037 7 01 01 0 00}
+test clock-3.612 {ISO week-based calendar 2037-W02-1} {
+ clock format 2114726400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W02-1
+} {Mon Monday 37 2037 1 01 02 1 01}
+test clock-3.613 {ISO week-based calendar 2037-W53-1} {
+ clock format 2145571200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W53-1
+} {Mon Monday 37 2037 1 52 53 1 52}
+test clock-3.614 {ISO week-based calendar 2037-W53-5} {
+ clock format 2145916800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W53-5
+} {Fri Friday 37 2037 5 00 53 5 00}
+test clock-3.615 {ISO week-based calendar 2037-W53-6} {
+ clock format 2146003200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W53-6
+} {Sat Saturday 37 2037 6 00 53 6 00}
+test clock-3.616 {ISO week-based calendar 2037-W53-7} {
+ clock format 2146089600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W53-7
+} {Sun Sunday 37 2037 7 01 53 0 00}
+test clock-3.617 {ISO week-based calendar 2038-W01-1} {
+ clock format 2146176000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W01-1
+} {Mon Monday 38 2038 1 01 01 1 01}
+test clock-3.618 {ISO week-based calendar 2038-W01-6} {
+ clock format 2146608000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W01-6
+} {Sat Saturday 38 2038 6 01 01 6 01}
+test clock-3.619 {ISO week-based calendar 2038-W01-7} {
+ clock format 2146694400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W01-7
+} {Sun Sunday 38 2038 7 02 01 0 01}
+test clock-3.620 {ISO week-based calendar 2038-W02-1} {
+ clock format 2146780800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W02-1
+} {Mon Monday 38 2038 1 02 02 1 02}
+test clock-3.621 {ISO week-based calendar 2038-W52-1} {
+ clock format 2177020800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W52-1
+} {Mon Monday 38 2038 1 52 52 1 52}
+test clock-3.622 {ISO week-based calendar 2038-W52-6} {
+ clock format 2177452800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W52-6
+} {Sat Saturday 38 2038 6 00 52 6 00}
+test clock-3.623 {ISO week-based calendar 2038-W52-7} {
+ clock format 2177539200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W52-7
+} {Sun Sunday 38 2038 7 01 52 0 00}
+test clock-3.624 {ISO week-based calendar 2039-W01-1} {
+ clock format 2177625600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W01-1
+} {Mon Monday 39 2039 1 01 01 1 01}
+test clock-3.625 {ISO week-based calendar 2039-W01-6} {
+ clock format 2178057600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W01-6
+} {Sat Saturday 39 2039 6 01 01 6 01}
+test clock-3.626 {ISO week-based calendar 2039-W01-7} {
+ clock format 2178144000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W01-7
+} {Sun Sunday 39 2039 7 02 01 0 01}
+test clock-3.627 {ISO week-based calendar 2039-W02-1} {
+ clock format 2178230400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W02-1
+} {Mon Monday 39 2039 1 02 02 1 02}
+test clock-3.628 {ISO week-based calendar 2039-W52-1} {
+ clock format 2208470400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W52-1
+} {Mon Monday 39 2039 1 52 52 1 52}
+test clock-3.629 {ISO week-based calendar 2039-W52-6} {
+ clock format 2208902400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W52-6
+} {Sat Saturday 39 2039 6 52 52 6 52}
+test clock-3.630 {ISO week-based calendar 2039-W52-7} {
+ clock format 2208988800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W52-7
+} {Sun Sunday 39 2039 7 01 52 0 00}
+test clock-3.631 {ISO week-based calendar 2040-W01-1} {
+ clock format 2209075200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W01-1
+} {Mon Monday 40 2040 1 01 01 1 01}
+test clock-3.632 {ISO week-based calendar 2040-W01-6} {
+ clock format 2209507200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W01-6
+} {Sat Saturday 40 2040 6 01 01 6 01}
+test clock-3.633 {ISO week-based calendar 2040-W01-7} {
+ clock format 2209593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W01-7
+} {Sun Sunday 40 2040 7 02 01 0 01}
+test clock-3.634 {ISO week-based calendar 2040-W02-1} {
+ clock format 2209680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W02-1
+} {Mon Monday 40 2040 1 02 02 1 02}
+test clock-3.635 {ISO week-based calendar 2040-W52-1} {
+ clock format 2239920000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W52-1
+} {Mon Monday 40 2040 1 52 52 1 52}
+test clock-3.636 {ISO week-based calendar 2040-W52-6} {
+ clock format 2240352000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W52-6
+} {Sat Saturday 40 2040 6 52 52 6 52}
+test clock-3.637 {ISO week-based calendar 2040-W52-7} {
+ clock format 2240438400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W52-7
+} {Sun Sunday 40 2040 7 53 52 0 52}
+test clock-3.638 {ISO week-based calendar 2041-W01-1} {
+ clock format 2240524800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W01-1
+} {Mon Monday 41 2041 1 53 01 1 53}
+test clock-3.639 {ISO week-based calendar 2041-W01-2} {
+ clock format 2240611200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W01-2
+} {Tue Tuesday 41 2041 2 00 01 2 00}
+test clock-3.640 {ISO week-based calendar 2041-W01-6} {
+ clock format 2240956800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W01-6
+} {Sat Saturday 41 2041 6 00 01 6 00}
+test clock-3.641 {ISO week-based calendar 2041-W01-7} {
+ clock format 2241043200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W01-7
+} {Sun Sunday 41 2041 7 01 01 0 00}
+test clock-3.642 {ISO week-based calendar 2041-W02-1} {
+ clock format 2241129600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W02-1
+} {Mon Monday 41 2041 1 01 02 1 01}
+test clock-3.643 {ISO week-based calendar 2041-W52-1} {
+ clock format 2271369600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W52-1
+} {Mon Monday 41 2041 1 51 52 1 51}
+test clock-3.644 {ISO week-based calendar 2041-W52-6} {
+ clock format 2271801600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W52-6
+} {Sat Saturday 41 2041 6 51 52 6 51}
+test clock-3.645 {ISO week-based calendar 2041-W52-7} {
+ clock format 2271888000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W52-7
+} {Sun Sunday 41 2041 7 52 52 0 51}
+test clock-3.646 {ISO week-based calendar 2042-W01-1} {
+ clock format 2271974400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W01-1
+} {Mon Monday 42 2042 1 52 01 1 52}
+test clock-3.647 {ISO week-based calendar 2042-W01-3} {
+ clock format 2272147200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W01-3
+} {Wed Wednesday 42 2042 3 00 01 3 00}
+test clock-3.648 {ISO week-based calendar 2042-W01-6} {
+ clock format 2272406400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W01-6
+} {Sat Saturday 42 2042 6 00 01 6 00}
+test clock-3.649 {ISO week-based calendar 2042-W01-7} {
+ clock format 2272492800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W01-7
+} {Sun Sunday 42 2042 7 01 01 0 00}
+test clock-3.650 {ISO week-based calendar 2042-W02-1} {
+ clock format 2272579200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W02-1
+} {Mon Monday 42 2042 1 01 02 1 01}
+test clock-3.651 {ISO week-based calendar 2042-W52-1} {
+ clock format 2302819200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W52-1
+} {Mon Monday 42 2042 1 51 52 1 51}
+test clock-3.652 {ISO week-based calendar 2042-W52-6} {
+ clock format 2303251200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W52-6
+} {Sat Saturday 42 2042 6 51 52 6 51}
+test clock-3.653 {ISO week-based calendar 2042-W52-7} {
+ clock format 2303337600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W52-7
+} {Sun Sunday 42 2042 7 52 52 0 51}
+test clock-3.654 {ISO week-based calendar 2043-W01-1} {
+ clock format 2303424000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W01-1
+} {Mon Monday 43 2043 1 52 01 1 52}
+test clock-3.655 {ISO week-based calendar 2043-W01-4} {
+ clock format 2303683200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W01-4
+} {Thu Thursday 43 2043 4 00 01 4 00}
+test clock-3.656 {ISO week-based calendar 2043-W01-6} {
+ clock format 2303856000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W01-6
+} {Sat Saturday 43 2043 6 00 01 6 00}
+test clock-3.657 {ISO week-based calendar 2043-W01-7} {
+ clock format 2303942400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W01-7
+} {Sun Sunday 43 2043 7 01 01 0 00}
+test clock-3.658 {ISO week-based calendar 2043-W02-1} {
+ clock format 2304028800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W02-1
+} {Mon Monday 43 2043 1 01 02 1 01}
+test clock-3.659 {ISO week-based calendar 2043-W53-1} {
+ clock format 2334873600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W53-1
+} {Mon Monday 43 2043 1 52 53 1 52}
+test clock-3.660 {ISO week-based calendar 2043-W53-5} {
+ clock format 2335219200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W53-5
+} {Fri Friday 43 2043 5 00 53 5 00}
+test clock-3.661 {ISO week-based calendar 2043-W53-6} {
+ clock format 2335305600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W53-6
+} {Sat Saturday 43 2043 6 00 53 6 00}
+test clock-3.662 {ISO week-based calendar 2043-W53-7} {
+ clock format 2335392000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W53-7
+} {Sun Sunday 43 2043 7 01 53 0 00}
+test clock-3.663 {ISO week-based calendar 2044-W01-1} {
+ clock format 2335478400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W01-1
+} {Mon Monday 44 2044 1 01 01 1 01}
+test clock-3.664 {ISO week-based calendar 2044-W01-6} {
+ clock format 2335910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W01-6
+} {Sat Saturday 44 2044 6 01 01 6 01}
+test clock-3.665 {ISO week-based calendar 2044-W01-7} {
+ clock format 2335996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W01-7
+} {Sun Sunday 44 2044 7 02 01 0 01}
+test clock-3.666 {ISO week-based calendar 2044-W02-1} {
+ clock format 2336083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W02-1
+} {Mon Monday 44 2044 1 02 02 1 02}
+test clock-3.667 {ISO week-based calendar 2044-W52-1} {
+ clock format 2366323200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W52-1
+} {Mon Monday 44 2044 1 52 52 1 52}
+test clock-3.668 {ISO week-based calendar 2044-W52-6} {
+ clock format 2366755200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W52-6
+} {Sat Saturday 44 2044 6 52 52 6 52}
+test clock-3.669 {ISO week-based calendar 2044-W52-7} {
+ clock format 2366841600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W52-7
+} {Sun Sunday 44 2044 7 01 52 0 00}
+test clock-3.670 {ISO week-based calendar 2045-W01-1} {
+ clock format 2366928000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W01-1
+} {Mon Monday 45 2045 1 01 01 1 01}
+test clock-3.671 {ISO week-based calendar 2045-W01-6} {
+ clock format 2367360000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W01-6
+} {Sat Saturday 45 2045 6 01 01 6 01}
+test clock-3.672 {ISO week-based calendar 2045-W01-7} {
+ clock format 2367446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W01-7
+} {Sun Sunday 45 2045 7 02 01 0 01}
+test clock-3.673 {ISO week-based calendar 2045-W02-1} {
+ clock format 2367532800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W02-1
+} {Mon Monday 45 2045 1 02 02 1 02}
+test clock-3.674 {ISO week-based calendar 2045-W52-1} {
+ clock format 2397772800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W52-1
+} {Mon Monday 45 2045 1 52 52 1 52}
+test clock-3.675 {ISO week-based calendar 2045-W52-6} {
+ clock format 2398204800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W52-6
+} {Sat Saturday 45 2045 6 52 52 6 52}
+test clock-3.676 {ISO week-based calendar 2045-W52-7} {
+ clock format 2398291200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W52-7
+} {Sun Sunday 45 2045 7 53 52 0 52}
+test clock-3.677 {ISO week-based calendar 2046-W01-1} {
+ clock format 2398377600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W01-1
+} {Mon Monday 46 2046 1 00 01 1 01}
+test clock-3.678 {ISO week-based calendar 2046-W01-6} {
+ clock format 2398809600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W01-6
+} {Sat Saturday 46 2046 6 00 01 6 01}
+test clock-3.679 {ISO week-based calendar 2046-W01-7} {
+ clock format 2398896000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W01-7
+} {Sun Sunday 46 2046 7 01 01 0 01}
+test clock-3.680 {ISO week-based calendar 2046-W02-1} {
+ clock format 2398982400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W02-1
+} {Mon Monday 46 2046 1 01 02 1 02}
+test clock-3.681 {ISO week-based calendar 2046-W52-1} {
+ clock format 2429222400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W52-1
+} {Mon Monday 46 2046 1 51 52 1 52}
+test clock-3.682 {ISO week-based calendar 2046-W52-6} {
+ clock format 2429654400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W52-6
+} {Sat Saturday 46 2046 6 51 52 6 52}
+test clock-3.683 {ISO week-based calendar 2046-W52-7} {
+ clock format 2429740800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W52-7
+} {Sun Sunday 46 2046 7 52 52 0 52}
+test clock-3.684 {ISO week-based calendar 2047-W01-1} {
+ clock format 2429827200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W01-1
+} {Mon Monday 47 2047 1 52 01 1 53}
+test clock-3.685 {ISO week-based calendar 2047-W01-2} {
+ clock format 2429913600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W01-2
+} {Tue Tuesday 47 2047 2 00 01 2 00}
+test clock-3.686 {ISO week-based calendar 2047-W01-6} {
+ clock format 2430259200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W01-6
+} {Sat Saturday 47 2047 6 00 01 6 00}
+test clock-3.687 {ISO week-based calendar 2047-W01-7} {
+ clock format 2430345600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W01-7
+} {Sun Sunday 47 2047 7 01 01 0 00}
+test clock-3.688 {ISO week-based calendar 2047-W02-1} {
+ clock format 2430432000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W02-1
+} {Mon Monday 47 2047 1 01 02 1 01}
+test clock-3.689 {ISO week-based calendar 2047-W52-1} {
+ clock format 2460672000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W52-1
+} {Mon Monday 47 2047 1 51 52 1 51}
+test clock-3.690 {ISO week-based calendar 2047-W52-6} {
+ clock format 2461104000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W52-6
+} {Sat Saturday 47 2047 6 51 52 6 51}
+test clock-3.691 {ISO week-based calendar 2047-W52-7} {
+ clock format 2461190400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W52-7
+} {Sun Sunday 47 2047 7 52 52 0 51}
+test clock-3.692 {ISO week-based calendar 2048-W01-1} {
+ clock format 2461276800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W01-1
+} {Mon Monday 48 2048 1 52 01 1 52}
+test clock-3.693 {ISO week-based calendar 2048-W01-3} {
+ clock format 2461449600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W01-3
+} {Wed Wednesday 48 2048 3 00 01 3 00}
+test clock-3.694 {ISO week-based calendar 2048-W01-6} {
+ clock format 2461708800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W01-6
+} {Sat Saturday 48 2048 6 00 01 6 00}
+test clock-3.695 {ISO week-based calendar 2048-W01-7} {
+ clock format 2461795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W01-7
+} {Sun Sunday 48 2048 7 01 01 0 00}
+test clock-3.696 {ISO week-based calendar 2048-W02-1} {
+ clock format 2461881600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W02-1
+} {Mon Monday 48 2048 1 01 02 1 01}
+test clock-3.697 {ISO week-based calendar 2048-W53-1} {
+ clock format 2492726400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W53-1
+} {Mon Monday 48 2048 1 52 53 1 52}
+test clock-3.698 {ISO week-based calendar 2048-W53-5} {
+ clock format 2493072000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W53-5
+} {Fri Friday 48 2048 5 00 53 5 00}
+test clock-3.699 {ISO week-based calendar 2048-W53-6} {
+ clock format 2493158400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W53-6
+} {Sat Saturday 48 2048 6 00 53 6 00}
+test clock-3.700 {ISO week-based calendar 2048-W53-7} {
+ clock format 2493244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W53-7
+} {Sun Sunday 48 2048 7 01 53 0 00}
+test clock-3.701 {ISO week-based calendar 2049-W01-1} {
+ clock format 2493331200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2049-W01-1
+} {Mon Monday 49 2049 1 01 01 1 01}
+test clock-3.702 {ISO week-based calendar 2049-W01-6} {
+ clock format 2493763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2049-W01-6
+} {Sat Saturday 49 2049 6 01 01 6 01}
+test clock-3.703 {ISO week-based calendar 2049-W01-7} {
+ clock format 2493849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2049-W01-7
+} {Sun Sunday 49 2049 7 02 01 0 01}
+test clock-3.704 {ISO week-based calendar 2049-W02-1} {
+ clock format 2493936000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2049-W02-1
+} {Mon Monday 49 2049 1 02 02 1 02}
+test clock-3.705 {ISO week-based calendar 2051-W52-1} {
+ clock format 2587075200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2051-W52-1
+} {Mon Monday 51 2051 1 52 52 1 52}
+test clock-3.706 {ISO week-based calendar 2051-W52-6} {
+ clock format 2587507200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2051-W52-6
+} {Sat Saturday 51 2051 6 52 52 6 52}
+test clock-3.707 {ISO week-based calendar 2051-W52-7} {
+ clock format 2587593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2051-W52-7
+} {Sun Sunday 51 2051 7 53 52 0 52}
+test clock-3.708 {ISO week-based calendar 2052-W01-1} {
+ clock format 2587680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W01-1
+} {Mon Monday 52 2052 1 00 01 1 01}
+test clock-3.709 {ISO week-based calendar 2052-W01-6} {
+ clock format 2588112000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W01-6
+} {Sat Saturday 52 2052 6 00 01 6 01}
+test clock-3.710 {ISO week-based calendar 2052-W01-7} {
+ clock format 2588198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W01-7
+} {Sun Sunday 52 2052 7 01 01 0 01}
+test clock-3.711 {ISO week-based calendar 2052-W02-1} {
+ clock format 2588284800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W02-1
+} {Mon Monday 52 2052 1 01 02 1 02}
+test clock-3.712 {ISO week-based calendar 2052-W52-1} {
+ clock format 2618524800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W52-1
+} {Mon Monday 52 2052 1 51 52 1 52}
+test clock-3.713 {ISO week-based calendar 2052-W52-6} {
+ clock format 2618956800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W52-6
+} {Sat Saturday 52 2052 6 51 52 6 52}
+test clock-3.714 {ISO week-based calendar 2052-W52-7} {
+ clock format 2619043200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W52-7
+} {Sun Sunday 52 2052 7 52 52 0 52}
+test clock-3.715 {ISO week-based calendar 2053-W01-1} {
+ clock format 2619129600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2053-W01-1
+} {Mon Monday 53 2053 1 52 01 1 53}
+test clock-3.716 {ISO week-based calendar 2053-W01-3} {
+ clock format 2619302400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2053-W01-3
+} {Wed Wednesday 53 2053 3 00 01 3 00}
+test clock-3.717 {ISO week-based calendar 2053-W01-6} {
+ clock format 2619561600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2053-W01-6
+} {Sat Saturday 53 2053 6 00 01 6 00}
+test clock-3.718 {ISO week-based calendar 2053-W01-7} {
+ clock format 2619648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2053-W01-7
+} {Sun Sunday 53 2053 7 01 01 0 00}
+test clock-3.719 {ISO week-based calendar 2053-W02-1} {
+ clock format 2619734400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2053-W02-1
+} {Mon Monday 53 2053 1 01 02 1 01}
+test clock-3.720 {ISO week-based calendar 2055-W52-1} {
+ clock format 2713478400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2055-W52-1
+} {Mon Monday 55 2055 1 52 52 1 52}
+test clock-3.721 {ISO week-based calendar 2055-W52-6} {
+ clock format 2713910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2055-W52-6
+} {Sat Saturday 55 2055 6 00 52 6 00}
+test clock-3.722 {ISO week-based calendar 2055-W52-7} {
+ clock format 2713996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2055-W52-7
+} {Sun Sunday 55 2055 7 01 52 0 00}
+test clock-3.723 {ISO week-based calendar 2056-W01-1} {
+ clock format 2714083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W01-1
+} {Mon Monday 56 2056 1 01 01 1 01}
+test clock-3.724 {ISO week-based calendar 2056-W01-6} {
+ clock format 2714515200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W01-6
+} {Sat Saturday 56 2056 6 01 01 6 01}
+test clock-3.725 {ISO week-based calendar 2056-W01-7} {
+ clock format 2714601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W01-7
+} {Sun Sunday 56 2056 7 02 01 0 01}
+test clock-3.726 {ISO week-based calendar 2056-W02-1} {
+ clock format 2714688000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W02-1
+} {Mon Monday 56 2056 1 02 02 1 02}
+test clock-3.727 {ISO week-based calendar 2056-W52-1} {
+ clock format 2744928000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W52-1
+} {Mon Monday 56 2056 1 52 52 1 52}
+test clock-3.728 {ISO week-based calendar 2056-W52-6} {
+ clock format 2745360000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W52-6
+} {Sat Saturday 56 2056 6 52 52 6 52}
+test clock-3.729 {ISO week-based calendar 2056-W52-7} {
+ clock format 2745446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W52-7
+} {Sun Sunday 56 2056 7 53 52 0 52}
+test clock-3.730 {ISO week-based calendar 2057-W01-1} {
+ clock format 2745532800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2057-W01-1
+} {Mon Monday 57 2057 1 00 01 1 01}
+test clock-3.731 {ISO week-based calendar 2057-W01-6} {
+ clock format 2745964800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2057-W01-6
+} {Sat Saturday 57 2057 6 00 01 6 01}
+test clock-3.732 {ISO week-based calendar 2057-W01-7} {
+ clock format 2746051200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2057-W01-7
+} {Sun Sunday 57 2057 7 01 01 0 01}
+test clock-3.733 {ISO week-based calendar 2057-W02-1} {
+ clock format 2746137600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2057-W02-1
+} {Mon Monday 57 2057 1 01 02 1 02}
+test clock-3.734 {ISO week-based calendar 2059-W52-1} {
+ clock format 2839276800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2059-W52-1
+} {Mon Monday 59 2059 1 51 52 1 51}
+test clock-3.735 {ISO week-based calendar 2059-W52-6} {
+ clock format 2839708800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2059-W52-6
+} {Sat Saturday 59 2059 6 51 52 6 51}
+test clock-3.736 {ISO week-based calendar 2059-W52-7} {
+ clock format 2839795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2059-W52-7
+} {Sun Sunday 59 2059 7 52 52 0 51}
+test clock-3.737 {ISO week-based calendar 2060-W01-1} {
+ clock format 2839881600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W01-1
+} {Mon Monday 60 2060 1 52 01 1 52}
+test clock-3.738 {ISO week-based calendar 2060-W01-4} {
+ clock format 2840140800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W01-4
+} {Thu Thursday 60 2060 4 00 01 4 00}
+test clock-3.739 {ISO week-based calendar 2060-W01-6} {
+ clock format 2840313600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W01-6
+} {Sat Saturday 60 2060 6 00 01 6 00}
+test clock-3.740 {ISO week-based calendar 2060-W01-7} {
+ clock format 2840400000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W01-7
+} {Sun Sunday 60 2060 7 01 01 0 00}
+test clock-3.741 {ISO week-based calendar 2060-W02-1} {
+ clock format 2840486400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W02-1
+} {Mon Monday 60 2060 1 01 02 1 01}
+test clock-3.742 {ISO week-based calendar 2060-W53-1} {
+ clock format 2871331200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W53-1
+} {Mon Monday 60 2060 1 52 53 1 52}
+test clock-3.743 {ISO week-based calendar 2060-W53-6} {
+ clock format 2871763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W53-6
+} {Sat Saturday 60 2060 6 00 53 6 00}
+test clock-3.744 {ISO week-based calendar 2060-W53-7} {
+ clock format 2871849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W53-7
+} {Sun Sunday 60 2060 7 01 53 0 00}
+test clock-3.745 {ISO week-based calendar 2061-W01-1} {
+ clock format 2871936000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2061-W01-1
+} {Mon Monday 61 2061 1 01 01 1 01}
+test clock-3.746 {ISO week-based calendar 2061-W01-6} {
+ clock format 2872368000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2061-W01-6
+} {Sat Saturday 61 2061 6 01 01 6 01}
+test clock-3.747 {ISO week-based calendar 2061-W01-7} {
+ clock format 2872454400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2061-W01-7
+} {Sun Sunday 61 2061 7 02 01 0 01}
+test clock-3.748 {ISO week-based calendar 2061-W02-1} {
+ clock format 2872540800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2061-W02-1
+} {Mon Monday 61 2061 1 02 02 1 02}
+test clock-3.749 {ISO week-based calendar 2063-W52-1} {
+ clock format 2965680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2063-W52-1
+} {Mon Monday 63 2063 1 51 52 1 52}
+test clock-3.750 {ISO week-based calendar 2063-W52-6} {
+ clock format 2966112000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2063-W52-6
+} {Sat Saturday 63 2063 6 51 52 6 52}
+test clock-3.751 {ISO week-based calendar 2063-W52-7} {
+ clock format 2966198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2063-W52-7
+} {Sun Sunday 63 2063 7 52 52 0 52}
+test clock-3.752 {ISO week-based calendar 2064-W01-1} {
+ clock format 2966284800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W01-1
+} {Mon Monday 64 2064 1 52 01 1 53}
+test clock-3.753 {ISO week-based calendar 2064-W01-2} {
+ clock format 2966371200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W01-2
+} {Tue Tuesday 64 2064 2 00 01 2 00}
+test clock-3.754 {ISO week-based calendar 2064-W01-6} {
+ clock format 2966716800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W01-6
+} {Sat Saturday 64 2064 6 00 01 6 00}
+test clock-3.755 {ISO week-based calendar 2064-W01-7} {
+ clock format 2966803200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W01-7
+} {Sun Sunday 64 2064 7 01 01 0 00}
+test clock-3.756 {ISO week-based calendar 2064-W02-1} {
+ clock format 2966889600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W02-1
+} {Mon Monday 64 2064 1 01 02 1 01}
+test clock-3.757 {ISO week-based calendar 2064-W52-1} {
+ clock format 2997129600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W52-1
+} {Mon Monday 64 2064 1 51 52 1 51}
+test clock-3.758 {ISO week-based calendar 2064-W52-6} {
+ clock format 2997561600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W52-6
+} {Sat Saturday 64 2064 6 51 52 6 51}
+test clock-3.759 {ISO week-based calendar 2064-W52-7} {
+ clock format 2997648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W52-7
+} {Sun Sunday 64 2064 7 52 52 0 51}
+test clock-3.760 {ISO week-based calendar 2065-W01-1} {
+ clock format 2997734400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2065-W01-1
+} {Mon Monday 65 2065 1 52 01 1 52}
+test clock-3.761 {ISO week-based calendar 2065-W01-4} {
+ clock format 2997993600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2065-W01-4
+} {Thu Thursday 65 2065 4 00 01 4 00}
+test clock-3.762 {ISO week-based calendar 2065-W01-6} {
+ clock format 2998166400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2065-W01-6
+} {Sat Saturday 65 2065 6 00 01 6 00}
+test clock-3.763 {ISO week-based calendar 2065-W01-7} {
+ clock format 2998252800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2065-W01-7
+} {Sun Sunday 65 2065 7 01 01 0 00}
+test clock-3.764 {ISO week-based calendar 2065-W02-1} {
+ clock format 2998339200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2065-W02-1
+} {Mon Monday 65 2065 1 01 02 1 01}
+# END testcases3
+
+# BEGIN testcases4
+
+# Test formatting of time of day
+# Format groups tested: %H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+
+
+test clock-4.1 { format time of day 00:00:00 } {
+ clock format 0 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 00 ? AM am 12:00:00 am 00:00 00 ? 00:00:00 00:00:00 ? h ? m ? s Thu Jan 1 00:00:00 GMT 1970}
+test clock-4.2 { format time of day 00:00:01 } {
+ clock format 1 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 00 ? AM am 12:00:01 am 00:00 01 i 00:00:01 00:00:01 ? h ? m i s Thu Jan 1 00:00:01 GMT 1970}
+test clock-4.3 { format time of day 00:00:58 } {
+ clock format 58 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 00 ? AM am 12:00:58 am 00:00 58 lviii 00:00:58 00:00:58 ? h ? m lviii s Thu Jan 1 00:00:58 GMT 1970}
+test clock-4.4 { format time of day 00:00:59 } {
+ clock format 59 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 00 ? AM am 12:00:59 am 00:00 59 lix 00:00:59 00:00:59 ? h ? m lix s Thu Jan 1 00:00:59 GMT 1970}
+test clock-4.5 { format time of day 00:01:00 } {
+ clock format 60 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 01 i AM am 12:01:00 am 00:01 00 ? 00:01:00 00:01:00 ? h i m ? s Thu Jan 1 00:01:00 GMT 1970}
+test clock-4.6 { format time of day 00:01:01 } {
+ clock format 61 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 01 i AM am 12:01:01 am 00:01 01 i 00:01:01 00:01:01 ? h i m i s Thu Jan 1 00:01:01 GMT 1970}
+test clock-4.7 { format time of day 00:01:58 } {
+ clock format 118 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 01 i AM am 12:01:58 am 00:01 58 lviii 00:01:58 00:01:58 ? h i m lviii s Thu Jan 1 00:01:58 GMT 1970}
+test clock-4.8 { format time of day 00:01:59 } {
+ clock format 119 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 01 i AM am 12:01:59 am 00:01 59 lix 00:01:59 00:01:59 ? h i m lix s Thu Jan 1 00:01:59 GMT 1970}
+test clock-4.9 { format time of day 00:58:00 } {
+ clock format 3480 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 58 lviii AM am 12:58:00 am 00:58 00 ? 00:58:00 00:58:00 ? h lviii m ? s Thu Jan 1 00:58:00 GMT 1970}
+test clock-4.10 { format time of day 00:58:01 } {
+ clock format 3481 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 58 lviii AM am 12:58:01 am 00:58 01 i 00:58:01 00:58:01 ? h lviii m i s Thu Jan 1 00:58:01 GMT 1970}
+test clock-4.11 { format time of day 00:58:58 } {
+ clock format 3538 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 58 lviii AM am 12:58:58 am 00:58 58 lviii 00:58:58 00:58:58 ? h lviii m lviii s Thu Jan 1 00:58:58 GMT 1970}
+test clock-4.12 { format time of day 00:58:59 } {
+ clock format 3539 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 58 lviii AM am 12:58:59 am 00:58 59 lix 00:58:59 00:58:59 ? h lviii m lix s Thu Jan 1 00:58:59 GMT 1970}
+test clock-4.13 { format time of day 00:59:00 } {
+ clock format 3540 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 59 lix AM am 12:59:00 am 00:59 00 ? 00:59:00 00:59:00 ? h lix m ? s Thu Jan 1 00:59:00 GMT 1970}
+test clock-4.14 { format time of day 00:59:01 } {
+ clock format 3541 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 59 lix AM am 12:59:01 am 00:59 01 i 00:59:01 00:59:01 ? h lix m i s Thu Jan 1 00:59:01 GMT 1970}
+test clock-4.15 { format time of day 00:59:58 } {
+ clock format 3598 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 59 lix AM am 12:59:58 am 00:59 58 lviii 00:59:58 00:59:58 ? h lix m lviii s Thu Jan 1 00:59:58 GMT 1970}
+test clock-4.16 { format time of day 00:59:59 } {
+ clock format 3599 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 59 lix AM am 12:59:59 am 00:59 59 lix 00:59:59 00:59:59 ? h lix m lix s Thu Jan 1 00:59:59 GMT 1970}
+test clock-4.17 { format time of day 01:00:00 } {
+ clock format 3600 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 00 ? AM am 01:00:00 am 01:00 00 ? 01:00:00 01:00:00 i h ? m ? s Thu Jan 1 01:00:00 GMT 1970}
+test clock-4.18 { format time of day 01:00:01 } {
+ clock format 3601 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 00 ? AM am 01:00:01 am 01:00 01 i 01:00:01 01:00:01 i h ? m i s Thu Jan 1 01:00:01 GMT 1970}
+test clock-4.19 { format time of day 01:00:58 } {
+ clock format 3658 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 00 ? AM am 01:00:58 am 01:00 58 lviii 01:00:58 01:00:58 i h ? m lviii s Thu Jan 1 01:00:58 GMT 1970}
+test clock-4.20 { format time of day 01:00:59 } {
+ clock format 3659 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 00 ? AM am 01:00:59 am 01:00 59 lix 01:00:59 01:00:59 i h ? m lix s Thu Jan 1 01:00:59 GMT 1970}
+test clock-4.21 { format time of day 01:01:00 } {
+ clock format 3660 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 01 i AM am 01:01:00 am 01:01 00 ? 01:01:00 01:01:00 i h i m ? s Thu Jan 1 01:01:00 GMT 1970}
+test clock-4.22 { format time of day 01:01:01 } {
+ clock format 3661 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 01 i AM am 01:01:01 am 01:01 01 i 01:01:01 01:01:01 i h i m i s Thu Jan 1 01:01:01 GMT 1970}
+test clock-4.23 { format time of day 01:01:58 } {
+ clock format 3718 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 01 i AM am 01:01:58 am 01:01 58 lviii 01:01:58 01:01:58 i h i m lviii s Thu Jan 1 01:01:58 GMT 1970}
+test clock-4.24 { format time of day 01:01:59 } {
+ clock format 3719 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 01 i AM am 01:01:59 am 01:01 59 lix 01:01:59 01:01:59 i h i m lix s Thu Jan 1 01:01:59 GMT 1970}
+test clock-4.25 { format time of day 01:58:00 } {
+ clock format 7080 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 58 lviii AM am 01:58:00 am 01:58 00 ? 01:58:00 01:58:00 i h lviii m ? s Thu Jan 1 01:58:00 GMT 1970}
+test clock-4.26 { format time of day 01:58:01 } {
+ clock format 7081 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 58 lviii AM am 01:58:01 am 01:58 01 i 01:58:01 01:58:01 i h lviii m i s Thu Jan 1 01:58:01 GMT 1970}
+test clock-4.27 { format time of day 01:58:58 } {
+ clock format 7138 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 58 lviii AM am 01:58:58 am 01:58 58 lviii 01:58:58 01:58:58 i h lviii m lviii s Thu Jan 1 01:58:58 GMT 1970}
+test clock-4.28 { format time of day 01:58:59 } {
+ clock format 7139 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 58 lviii AM am 01:58:59 am 01:58 59 lix 01:58:59 01:58:59 i h lviii m lix s Thu Jan 1 01:58:59 GMT 1970}
+test clock-4.29 { format time of day 01:59:00 } {
+ clock format 7140 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 59 lix AM am 01:59:00 am 01:59 00 ? 01:59:00 01:59:00 i h lix m ? s Thu Jan 1 01:59:00 GMT 1970}
+test clock-4.30 { format time of day 01:59:01 } {
+ clock format 7141 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 59 lix AM am 01:59:01 am 01:59 01 i 01:59:01 01:59:01 i h lix m i s Thu Jan 1 01:59:01 GMT 1970}
+test clock-4.31 { format time of day 01:59:58 } {
+ clock format 7198 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 59 lix AM am 01:59:58 am 01:59 58 lviii 01:59:58 01:59:58 i h lix m lviii s Thu Jan 1 01:59:58 GMT 1970}
+test clock-4.32 { format time of day 01:59:59 } {
+ clock format 7199 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 59 lix AM am 01:59:59 am 01:59 59 lix 01:59:59 01:59:59 i h lix m lix s Thu Jan 1 01:59:59 GMT 1970}
+test clock-4.33 { format time of day 11:00:00 } {
+ clock format 39600 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:00 am 11:00 00 ? 11:00:00 11:00:00 xi h ? m ? s Thu Jan 1 11:00:00 GMT 1970}
+test clock-4.34 { format time of day 11:00:01 } {
+ clock format 39601 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:01 am 11:00 01 i 11:00:01 11:00:01 xi h ? m i s Thu Jan 1 11:00:01 GMT 1970}
+test clock-4.35 { format time of day 11:00:58 } {
+ clock format 39658 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:58 am 11:00 58 lviii 11:00:58 11:00:58 xi h ? m lviii s Thu Jan 1 11:00:58 GMT 1970}
+test clock-4.36 { format time of day 11:00:59 } {
+ clock format 39659 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:59 am 11:00 59 lix 11:00:59 11:00:59 xi h ? m lix s Thu Jan 1 11:00:59 GMT 1970}
+test clock-4.37 { format time of day 11:01:00 } {
+ clock format 39660 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:00 am 11:01 00 ? 11:01:00 11:01:00 xi h i m ? s Thu Jan 1 11:01:00 GMT 1970}
+test clock-4.38 { format time of day 11:01:01 } {
+ clock format 39661 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:01 am 11:01 01 i 11:01:01 11:01:01 xi h i m i s Thu Jan 1 11:01:01 GMT 1970}
+test clock-4.39 { format time of day 11:01:58 } {
+ clock format 39718 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:58 am 11:01 58 lviii 11:01:58 11:01:58 xi h i m lviii s Thu Jan 1 11:01:58 GMT 1970}
+test clock-4.40 { format time of day 11:01:59 } {
+ clock format 39719 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:59 am 11:01 59 lix 11:01:59 11:01:59 xi h i m lix s Thu Jan 1 11:01:59 GMT 1970}
+test clock-4.41 { format time of day 11:58:00 } {
+ clock format 43080 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:00 am 11:58 00 ? 11:58:00 11:58:00 xi h lviii m ? s Thu Jan 1 11:58:00 GMT 1970}
+test clock-4.42 { format time of day 11:58:01 } {
+ clock format 43081 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:01 am 11:58 01 i 11:58:01 11:58:01 xi h lviii m i s Thu Jan 1 11:58:01 GMT 1970}
+test clock-4.43 { format time of day 11:58:58 } {
+ clock format 43138 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:58 am 11:58 58 lviii 11:58:58 11:58:58 xi h lviii m lviii s Thu Jan 1 11:58:58 GMT 1970}
+test clock-4.44 { format time of day 11:58:59 } {
+ clock format 43139 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:59 am 11:58 59 lix 11:58:59 11:58:59 xi h lviii m lix s Thu Jan 1 11:58:59 GMT 1970}
+test clock-4.45 { format time of day 11:59:00 } {
+ clock format 43140 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:00 am 11:59 00 ? 11:59:00 11:59:00 xi h lix m ? s Thu Jan 1 11:59:00 GMT 1970}
+test clock-4.46 { format time of day 11:59:01 } {
+ clock format 43141 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:01 am 11:59 01 i 11:59:01 11:59:01 xi h lix m i s Thu Jan 1 11:59:01 GMT 1970}
+test clock-4.47 { format time of day 11:59:58 } {
+ clock format 43198 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:58 am 11:59 58 lviii 11:59:58 11:59:58 xi h lix m lviii s Thu Jan 1 11:59:58 GMT 1970}
+test clock-4.48 { format time of day 11:59:59 } {
+ clock format 43199 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:59 am 11:59 59 lix 11:59:59 11:59:59 xi h lix m lix s Thu Jan 1 11:59:59 GMT 1970}
+test clock-4.49 { format time of day 12:00:00 } {
+ clock format 43200 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:00 pm 12:00 00 ? 12:00:00 12:00:00 xii h ? m ? s Thu Jan 1 12:00:00 GMT 1970}
+test clock-4.50 { format time of day 12:00:01 } {
+ clock format 43201 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:01 pm 12:00 01 i 12:00:01 12:00:01 xii h ? m i s Thu Jan 1 12:00:01 GMT 1970}
+test clock-4.51 { format time of day 12:00:58 } {
+ clock format 43258 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:58 pm 12:00 58 lviii 12:00:58 12:00:58 xii h ? m lviii s Thu Jan 1 12:00:58 GMT 1970}
+test clock-4.52 { format time of day 12:00:59 } {
+ clock format 43259 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:59 pm 12:00 59 lix 12:00:59 12:00:59 xii h ? m lix s Thu Jan 1 12:00:59 GMT 1970}
+test clock-4.53 { format time of day 12:01:00 } {
+ clock format 43260 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:00 pm 12:01 00 ? 12:01:00 12:01:00 xii h i m ? s Thu Jan 1 12:01:00 GMT 1970}
+test clock-4.54 { format time of day 12:01:01 } {
+ clock format 43261 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:01 pm 12:01 01 i 12:01:01 12:01:01 xii h i m i s Thu Jan 1 12:01:01 GMT 1970}
+test clock-4.55 { format time of day 12:01:58 } {
+ clock format 43318 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:58 pm 12:01 58 lviii 12:01:58 12:01:58 xii h i m lviii s Thu Jan 1 12:01:58 GMT 1970}
+test clock-4.56 { format time of day 12:01:59 } {
+ clock format 43319 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:59 pm 12:01 59 lix 12:01:59 12:01:59 xii h i m lix s Thu Jan 1 12:01:59 GMT 1970}
+test clock-4.57 { format time of day 12:58:00 } {
+ clock format 46680 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:00 pm 12:58 00 ? 12:58:00 12:58:00 xii h lviii m ? s Thu Jan 1 12:58:00 GMT 1970}
+test clock-4.58 { format time of day 12:58:01 } {
+ clock format 46681 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:01 pm 12:58 01 i 12:58:01 12:58:01 xii h lviii m i s Thu Jan 1 12:58:01 GMT 1970}
+test clock-4.59 { format time of day 12:58:58 } {
+ clock format 46738 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:58 pm 12:58 58 lviii 12:58:58 12:58:58 xii h lviii m lviii s Thu Jan 1 12:58:58 GMT 1970}
+test clock-4.60 { format time of day 12:58:59 } {
+ clock format 46739 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:59 pm 12:58 59 lix 12:58:59 12:58:59 xii h lviii m lix s Thu Jan 1 12:58:59 GMT 1970}
+test clock-4.61 { format time of day 12:59:00 } {
+ clock format 46740 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:00 pm 12:59 00 ? 12:59:00 12:59:00 xii h lix m ? s Thu Jan 1 12:59:00 GMT 1970}
+test clock-4.62 { format time of day 12:59:01 } {
+ clock format 46741 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:01 pm 12:59 01 i 12:59:01 12:59:01 xii h lix m i s Thu Jan 1 12:59:01 GMT 1970}
+test clock-4.63 { format time of day 12:59:58 } {
+ clock format 46798 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:58 pm 12:59 58 lviii 12:59:58 12:59:58 xii h lix m lviii s Thu Jan 1 12:59:58 GMT 1970}
+test clock-4.64 { format time of day 12:59:59 } {
+ clock format 46799 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:59 pm 12:59 59 lix 12:59:59 12:59:59 xii h lix m lix s Thu Jan 1 12:59:59 GMT 1970}
+test clock-4.65 { format time of day 13:00:00 } {
+ clock format 46800 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 00 ? PM pm 01:00:00 pm 13:00 00 ? 13:00:00 13:00:00 xiii h ? m ? s Thu Jan 1 13:00:00 GMT 1970}
+test clock-4.66 { format time of day 13:00:01 } {
+ clock format 46801 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 00 ? PM pm 01:00:01 pm 13:00 01 i 13:00:01 13:00:01 xiii h ? m i s Thu Jan 1 13:00:01 GMT 1970}
+test clock-4.67 { format time of day 13:00:58 } {
+ clock format 46858 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 00 ? PM pm 01:00:58 pm 13:00 58 lviii 13:00:58 13:00:58 xiii h ? m lviii s Thu Jan 1 13:00:58 GMT 1970}
+test clock-4.68 { format time of day 13:00:59 } {
+ clock format 46859 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 00 ? PM pm 01:00:59 pm 13:00 59 lix 13:00:59 13:00:59 xiii h ? m lix s Thu Jan 1 13:00:59 GMT 1970}
+test clock-4.69 { format time of day 13:01:00 } {
+ clock format 46860 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 01 i PM pm 01:01:00 pm 13:01 00 ? 13:01:00 13:01:00 xiii h i m ? s Thu Jan 1 13:01:00 GMT 1970}
+test clock-4.70 { format time of day 13:01:01 } {
+ clock format 46861 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 01 i PM pm 01:01:01 pm 13:01 01 i 13:01:01 13:01:01 xiii h i m i s Thu Jan 1 13:01:01 GMT 1970}
+test clock-4.71 { format time of day 13:01:58 } {
+ clock format 46918 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 01 i PM pm 01:01:58 pm 13:01 58 lviii 13:01:58 13:01:58 xiii h i m lviii s Thu Jan 1 13:01:58 GMT 1970}
+test clock-4.72 { format time of day 13:01:59 } {
+ clock format 46919 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 01 i PM pm 01:01:59 pm 13:01 59 lix 13:01:59 13:01:59 xiii h i m lix s Thu Jan 1 13:01:59 GMT 1970}
+test clock-4.73 { format time of day 13:58:00 } {
+ clock format 50280 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 58 lviii PM pm 01:58:00 pm 13:58 00 ? 13:58:00 13:58:00 xiii h lviii m ? s Thu Jan 1 13:58:00 GMT 1970}
+test clock-4.74 { format time of day 13:58:01 } {
+ clock format 50281 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 58 lviii PM pm 01:58:01 pm 13:58 01 i 13:58:01 13:58:01 xiii h lviii m i s Thu Jan 1 13:58:01 GMT 1970}
+test clock-4.75 { format time of day 13:58:58 } {
+ clock format 50338 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 58 lviii PM pm 01:58:58 pm 13:58 58 lviii 13:58:58 13:58:58 xiii h lviii m lviii s Thu Jan 1 13:58:58 GMT 1970}
+test clock-4.76 { format time of day 13:58:59 } {
+ clock format 50339 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 58 lviii PM pm 01:58:59 pm 13:58 59 lix 13:58:59 13:58:59 xiii h lviii m lix s Thu Jan 1 13:58:59 GMT 1970}
+test clock-4.77 { format time of day 13:59:00 } {
+ clock format 50340 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 59 lix PM pm 01:59:00 pm 13:59 00 ? 13:59:00 13:59:00 xiii h lix m ? s Thu Jan 1 13:59:00 GMT 1970}
+test clock-4.78 { format time of day 13:59:01 } {
+ clock format 50341 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 59 lix PM pm 01:59:01 pm 13:59 01 i 13:59:01 13:59:01 xiii h lix m i s Thu Jan 1 13:59:01 GMT 1970}
+test clock-4.79 { format time of day 13:59:58 } {
+ clock format 50398 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 59 lix PM pm 01:59:58 pm 13:59 58 lviii 13:59:58 13:59:58 xiii h lix m lviii s Thu Jan 1 13:59:58 GMT 1970}
+test clock-4.80 { format time of day 13:59:59 } {
+ clock format 50399 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 59 lix PM pm 01:59:59 pm 13:59 59 lix 13:59:59 13:59:59 xiii h lix m lix s Thu Jan 1 13:59:59 GMT 1970}
+test clock-4.81 { format time of day 23:00:00 } {
+ clock format 82800 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:00 pm 23:00 00 ? 23:00:00 23:00:00 xxiii h ? m ? s Thu Jan 1 23:00:00 GMT 1970}
+test clock-4.82 { format time of day 23:00:01 } {
+ clock format 82801 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:01 pm 23:00 01 i 23:00:01 23:00:01 xxiii h ? m i s Thu Jan 1 23:00:01 GMT 1970}
+test clock-4.83 { format time of day 23:00:58 } {
+ clock format 82858 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:58 pm 23:00 58 lviii 23:00:58 23:00:58 xxiii h ? m lviii s Thu Jan 1 23:00:58 GMT 1970}
+test clock-4.84 { format time of day 23:00:59 } {
+ clock format 82859 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:59 pm 23:00 59 lix 23:00:59 23:00:59 xxiii h ? m lix s Thu Jan 1 23:00:59 GMT 1970}
+test clock-4.85 { format time of day 23:01:00 } {
+ clock format 82860 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:00 pm 23:01 00 ? 23:01:00 23:01:00 xxiii h i m ? s Thu Jan 1 23:01:00 GMT 1970}
+test clock-4.86 { format time of day 23:01:01 } {
+ clock format 82861 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:01 pm 23:01 01 i 23:01:01 23:01:01 xxiii h i m i s Thu Jan 1 23:01:01 GMT 1970}
+test clock-4.87 { format time of day 23:01:58 } {
+ clock format 82918 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:58 pm 23:01 58 lviii 23:01:58 23:01:58 xxiii h i m lviii s Thu Jan 1 23:01:58 GMT 1970}
+test clock-4.88 { format time of day 23:01:59 } {
+ clock format 82919 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:59 pm 23:01 59 lix 23:01:59 23:01:59 xxiii h i m lix s Thu Jan 1 23:01:59 GMT 1970}
+test clock-4.89 { format time of day 23:58:00 } {
+ clock format 86280 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:00 pm 23:58 00 ? 23:58:00 23:58:00 xxiii h lviii m ? s Thu Jan 1 23:58:00 GMT 1970}
+test clock-4.90 { format time of day 23:58:01 } {
+ clock format 86281 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:01 pm 23:58 01 i 23:58:01 23:58:01 xxiii h lviii m i s Thu Jan 1 23:58:01 GMT 1970}
+test clock-4.91 { format time of day 23:58:58 } {
+ clock format 86338 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:58 pm 23:58 58 lviii 23:58:58 23:58:58 xxiii h lviii m lviii s Thu Jan 1 23:58:58 GMT 1970}
+test clock-4.92 { format time of day 23:58:59 } {
+ clock format 86339 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:59 pm 23:58 59 lix 23:58:59 23:58:59 xxiii h lviii m lix s Thu Jan 1 23:58:59 GMT 1970}
+test clock-4.93 { format time of day 23:59:00 } {
+ clock format 86340 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:00 pm 23:59 00 ? 23:59:00 23:59:00 xxiii h lix m ? s Thu Jan 1 23:59:00 GMT 1970}
+test clock-4.94 { format time of day 23:59:01 } {
+ clock format 86341 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:01 pm 23:59 01 i 23:59:01 23:59:01 xxiii h lix m i s Thu Jan 1 23:59:01 GMT 1970}
+test clock-4.95 { format time of day 23:59:58 } {
+ clock format 86398 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:58 pm 23:59 58 lviii 23:59:58 23:59:58 xxiii h lix m lviii s Thu Jan 1 23:59:58 GMT 1970}
+test clock-4.96 { format time of day 23:59:59 } {
+ clock format 86399 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:59 pm 23:59 59 lix 23:59:59 23:59:59 xxiii h lix m lix s Thu Jan 1 23:59:59 GMT 1970}
+# END testcases4
+
+# BEGIN testcases5
+
+# Test formatting of Daylight Saving Time
+
+test clock-5.1 {does Detroit exist} {
+ clock format 0 -format {} -timezone :America/Detroit
+ concat
+} {}
+test clock-5.2 {does Detroit have a Y2038 problem} detroit {
+ if { [clock format 2158894800 -format %z -timezone :America/Detroit] ne {-0400} } {
+ concat {y2038 problem}
+ } else {
+ concat {ok}
+ }
+} ok
+test clock-5.3 {time zone boundary case 1904-12-31 23:59:59} detroit {
+ clock format -2051202470 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {23:59:59 -053211 LMT}
+test clock-5.4 {time zone boundary case 1904-12-31 23:32:11} detroit {
+ clock format -2051202469 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {23:32:11 -0600 CST}
+test clock-5.5 {time zone boundary case 1904-12-31 23:32:12} detroit {
+ clock format -2051202468 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {23:32:12 -0600 CST}
+test clock-5.6 {time zone boundary case 1915-05-15 01:59:59} detroit {
+ clock format -1724083201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0600 CST}
+test clock-5.7 {time zone boundary case 1915-05-15 03:00:00} detroit {
+ clock format -1724083200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0500 EST}
+test clock-5.8 {time zone boundary case 1915-05-15 03:00:01} detroit {
+ clock format -1724083199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0500 EST}
+test clock-5.9 {time zone boundary case 1941-12-31 23:59:59} detroit {
+ clock format -883594801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {23:59:59 -0500 EST}
+test clock-5.10 {time zone boundary case 1942-01-01 00:00:00} detroit {
+ clock format -883594800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {00:00:00 -0500 EST}
+test clock-5.11 {time zone boundary case 1942-01-01 00:00:01} detroit {
+ clock format -883594799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {00:00:01 -0500 EST}
+test clock-5.12 {time zone boundary case 1942-02-09 01:59:59} detroit {
+ clock format -880218001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.13 {time zone boundary case 1942-02-09 03:00:00} detroit {
+ clock format -880218000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EWT}
+test clock-5.14 {time zone boundary case 1942-02-09 03:00:01} detroit {
+ clock format -880217999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EWT}
+test clock-5.15 {time zone boundary case 1945-08-14 18:59:59} detroit {
+ clock format -769395601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {18:59:59 -0400 EWT}
+test clock-5.16 {time zone boundary case 1945-08-14 19:00:00} detroit {
+ clock format -769395600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {19:00:00 -0400 EPT}
+test clock-5.17 {time zone boundary case 1945-08-14 19:00:01} detroit {
+ clock format -769395599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {19:00:01 -0400 EPT}
+test clock-5.18 {time zone boundary case 1945-09-30 01:59:59} detroit {
+ clock format -765396001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EPT}
+test clock-5.19 {time zone boundary case 1945-09-30 01:00:00} detroit {
+ clock format -765396000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.20 {time zone boundary case 1945-09-30 01:00:01} detroit {
+ clock format -765395999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.21 {time zone boundary case 1945-12-31 23:59:59} detroit {
+ clock format -757364401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {23:59:59 -0500 EST}
+test clock-5.22 {time zone boundary case 1946-01-01 00:00:00} detroit {
+ clock format -757364400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {00:00:00 -0500 EST}
+test clock-5.23 {time zone boundary case 1946-01-01 00:00:01} detroit {
+ clock format -757364399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {00:00:01 -0500 EST}
+test clock-5.24 {time zone boundary case 1948-04-25 01:59:59} detroit {
+ clock format -684349201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.25 {time zone boundary case 1948-04-25 03:00:00} detroit {
+ clock format -684349200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.26 {time zone boundary case 1948-04-25 03:00:01} detroit {
+ clock format -684349199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.27 {time zone boundary case 1948-09-26 01:59:59} detroit {
+ clock format -671047201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.28 {time zone boundary case 1948-09-26 01:00:00} detroit {
+ clock format -671047200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.29 {time zone boundary case 1948-09-26 01:00:01} detroit {
+ clock format -671047199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.30 {time zone boundary case 1967-06-14 01:59:59} detroit {
+ clock format -80499601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.31 {time zone boundary case 1967-06-14 03:00:00} detroit {
+ clock format -80499600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.32 {time zone boundary case 1967-06-14 03:00:01} detroit {
+ clock format -80499599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.33 {time zone boundary case 1967-10-29 01:59:59} detroit {
+ clock format -68666401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.34 {time zone boundary case 1967-10-29 01:00:00} detroit {
+ clock format -68666400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.35 {time zone boundary case 1967-10-29 01:00:01} detroit {
+ clock format -68666399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.36 {time zone boundary case 1972-12-31 23:59:59} detroit {
+ clock format 94712399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {23:59:59 -0500 EST}
+test clock-5.37 {time zone boundary case 1973-01-01 00:00:00} detroit {
+ clock format 94712400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {00:00:00 -0500 EST}
+test clock-5.38 {time zone boundary case 1973-01-01 00:00:01} detroit {
+ clock format 94712401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {00:00:01 -0500 EST}
+test clock-5.39 {time zone boundary case 1973-04-29 01:59:59} detroit {
+ clock format 104914799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.40 {time zone boundary case 1973-04-29 03:00:00} detroit {
+ clock format 104914800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.41 {time zone boundary case 1973-04-29 03:00:01} detroit {
+ clock format 104914801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.42 {time zone boundary case 1973-10-28 01:59:59} detroit {
+ clock format 120635999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.43 {time zone boundary case 1973-10-28 01:00:00} detroit {
+ clock format 120636000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.44 {time zone boundary case 1973-10-28 01:00:01} detroit {
+ clock format 120636001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.45 {time zone boundary case 1974-01-06 01:59:59} detroit {
+ clock format 126687599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.46 {time zone boundary case 1974-01-06 03:00:00} detroit {
+ clock format 126687600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.47 {time zone boundary case 1974-01-06 03:00:01} detroit {
+ clock format 126687601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.48 {time zone boundary case 1974-10-27 01:59:59} detroit {
+ clock format 152085599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.49 {time zone boundary case 1974-10-27 01:00:00} detroit {
+ clock format 152085600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.50 {time zone boundary case 1974-10-27 01:00:01} detroit {
+ clock format 152085601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.51 {time zone boundary case 1974-12-31 23:59:59} detroit {
+ clock format 157784399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {23:59:59 -0500 EST}
+test clock-5.52 {time zone boundary case 1975-01-01 00:00:00} detroit {
+ clock format 157784400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {00:00:00 -0500 EST}
+test clock-5.53 {time zone boundary case 1975-01-01 00:00:01} detroit {
+ clock format 157784401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {00:00:01 -0500 EST}
+test clock-5.54 {time zone boundary case 1975-04-27 01:59:59} detroit {
+ clock format 167813999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.55 {time zone boundary case 1975-04-27 03:00:00} detroit {
+ clock format 167814000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.56 {time zone boundary case 1975-04-27 03:00:01} detroit {
+ clock format 167814001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.57 {time zone boundary case 1975-10-26 01:59:59} detroit {
+ clock format 183535199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.58 {time zone boundary case 1975-10-26 01:00:00} detroit {
+ clock format 183535200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.59 {time zone boundary case 1975-10-26 01:00:01} detroit {
+ clock format 183535201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.60 {time zone boundary case 1976-04-25 01:59:59} detroit {
+ clock format 199263599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.61 {time zone boundary case 1976-04-25 03:00:00} detroit {
+ clock format 199263600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.62 {time zone boundary case 1976-04-25 03:00:01} detroit {
+ clock format 199263601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.63 {time zone boundary case 1976-10-31 01:59:59} detroit {
+ clock format 215589599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.64 {time zone boundary case 1976-10-31 01:00:00} detroit {
+ clock format 215589600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.65 {time zone boundary case 1976-10-31 01:00:01} detroit {
+ clock format 215589601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.66 {time zone boundary case 1977-04-24 01:59:59} detroit {
+ clock format 230713199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.67 {time zone boundary case 1977-04-24 03:00:00} detroit {
+ clock format 230713200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.68 {time zone boundary case 1977-04-24 03:00:01} detroit {
+ clock format 230713201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.69 {time zone boundary case 1977-10-30 01:59:59} detroit {
+ clock format 247039199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.70 {time zone boundary case 1977-10-30 01:00:00} detroit {
+ clock format 247039200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.71 {time zone boundary case 1977-10-30 01:00:01} detroit {
+ clock format 247039201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.72 {time zone boundary case 1978-04-30 01:59:59} detroit {
+ clock format 262767599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.73 {time zone boundary case 1978-04-30 03:00:00} detroit {
+ clock format 262767600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.74 {time zone boundary case 1978-04-30 03:00:01} detroit {
+ clock format 262767601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.75 {time zone boundary case 1978-10-29 01:59:59} detroit {
+ clock format 278488799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.76 {time zone boundary case 1978-10-29 01:00:00} detroit {
+ clock format 278488800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.77 {time zone boundary case 1978-10-29 01:00:01} detroit {
+ clock format 278488801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.78 {time zone boundary case 1979-04-29 01:59:59} detroit {
+ clock format 294217199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.79 {time zone boundary case 1979-04-29 03:00:00} detroit {
+ clock format 294217200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.80 {time zone boundary case 1979-04-29 03:00:01} detroit {
+ clock format 294217201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.81 {time zone boundary case 1979-10-28 01:59:59} detroit {
+ clock format 309938399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.82 {time zone boundary case 1979-10-28 01:00:00} detroit {
+ clock format 309938400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.83 {time zone boundary case 1979-10-28 01:00:01} detroit {
+ clock format 309938401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.84 {time zone boundary case 1980-04-27 01:59:59} detroit {
+ clock format 325666799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.85 {time zone boundary case 1980-04-27 03:00:00} detroit {
+ clock format 325666800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.86 {time zone boundary case 1980-04-27 03:00:01} detroit {
+ clock format 325666801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.87 {time zone boundary case 1980-10-26 01:59:59} detroit {
+ clock format 341387999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.88 {time zone boundary case 1980-10-26 01:00:00} detroit {
+ clock format 341388000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.89 {time zone boundary case 1980-10-26 01:00:01} detroit {
+ clock format 341388001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.90 {time zone boundary case 1981-04-26 01:59:59} detroit {
+ clock format 357116399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.91 {time zone boundary case 1981-04-26 03:00:00} detroit {
+ clock format 357116400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.92 {time zone boundary case 1981-04-26 03:00:01} detroit {
+ clock format 357116401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.93 {time zone boundary case 1981-10-25 01:59:59} detroit {
+ clock format 372837599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.94 {time zone boundary case 1981-10-25 01:00:00} detroit {
+ clock format 372837600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.95 {time zone boundary case 1981-10-25 01:00:01} detroit {
+ clock format 372837601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.96 {time zone boundary case 1982-04-25 01:59:59} detroit {
+ clock format 388565999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.97 {time zone boundary case 1982-04-25 03:00:00} detroit {
+ clock format 388566000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.98 {time zone boundary case 1982-04-25 03:00:01} detroit {
+ clock format 388566001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.99 {time zone boundary case 1982-10-31 01:59:59} detroit {
+ clock format 404891999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.100 {time zone boundary case 1982-10-31 01:00:00} detroit {
+ clock format 404892000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.101 {time zone boundary case 1982-10-31 01:00:01} detroit {
+ clock format 404892001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.102 {time zone boundary case 1983-04-24 01:59:59} detroit {
+ clock format 420015599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.103 {time zone boundary case 1983-04-24 03:00:00} detroit {
+ clock format 420015600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.104 {time zone boundary case 1983-04-24 03:00:01} detroit {
+ clock format 420015601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.105 {time zone boundary case 1983-10-30 01:59:59} detroit {
+ clock format 436341599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.106 {time zone boundary case 1983-10-30 01:00:00} detroit {
+ clock format 436341600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.107 {time zone boundary case 1983-10-30 01:00:01} detroit {
+ clock format 436341601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.108 {time zone boundary case 1984-04-29 01:59:59} detroit {
+ clock format 452069999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.109 {time zone boundary case 1984-04-29 03:00:00} detroit {
+ clock format 452070000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.110 {time zone boundary case 1984-04-29 03:00:01} detroit {
+ clock format 452070001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.111 {time zone boundary case 1984-10-28 01:59:59} detroit {
+ clock format 467791199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.112 {time zone boundary case 1984-10-28 01:00:00} detroit {
+ clock format 467791200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.113 {time zone boundary case 1984-10-28 01:00:01} detroit {
+ clock format 467791201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.114 {time zone boundary case 1985-04-28 01:59:59} detroit {
+ clock format 483519599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.115 {time zone boundary case 1985-04-28 03:00:00} detroit {
+ clock format 483519600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.116 {time zone boundary case 1985-04-28 03:00:01} detroit {
+ clock format 483519601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.117 {time zone boundary case 1985-10-27 01:59:59} detroit {
+ clock format 499240799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.118 {time zone boundary case 1985-10-27 01:00:00} detroit {
+ clock format 499240800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.119 {time zone boundary case 1985-10-27 01:00:01} detroit {
+ clock format 499240801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.120 {time zone boundary case 1986-04-27 01:59:59} detroit {
+ clock format 514969199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.121 {time zone boundary case 1986-04-27 03:00:00} detroit {
+ clock format 514969200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.122 {time zone boundary case 1986-04-27 03:00:01} detroit {
+ clock format 514969201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.123 {time zone boundary case 1986-10-26 01:59:59} detroit {
+ clock format 530690399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.124 {time zone boundary case 1986-10-26 01:00:00} detroit {
+ clock format 530690400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.125 {time zone boundary case 1986-10-26 01:00:01} detroit {
+ clock format 530690401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.126 {time zone boundary case 1987-04-05 01:59:59} detroit {
+ clock format 544604399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.127 {time zone boundary case 1987-04-05 03:00:00} detroit {
+ clock format 544604400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.128 {time zone boundary case 1987-04-05 03:00:01} detroit {
+ clock format 544604401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.129 {time zone boundary case 1987-10-25 01:59:59} detroit {
+ clock format 562139999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.130 {time zone boundary case 1987-10-25 01:00:00} detroit {
+ clock format 562140000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.131 {time zone boundary case 1987-10-25 01:00:01} detroit {
+ clock format 562140001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.132 {time zone boundary case 1988-04-03 01:59:59} detroit {
+ clock format 576053999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.133 {time zone boundary case 1988-04-03 03:00:00} detroit {
+ clock format 576054000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.134 {time zone boundary case 1988-04-03 03:00:01} detroit {
+ clock format 576054001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.135 {time zone boundary case 1988-10-30 01:59:59} detroit {
+ clock format 594194399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.136 {time zone boundary case 1988-10-30 01:00:00} detroit {
+ clock format 594194400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.137 {time zone boundary case 1988-10-30 01:00:01} detroit {
+ clock format 594194401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.138 {time zone boundary case 1989-04-02 01:59:59} detroit {
+ clock format 607503599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.139 {time zone boundary case 1989-04-02 03:00:00} detroit {
+ clock format 607503600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.140 {time zone boundary case 1989-04-02 03:00:01} detroit {
+ clock format 607503601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.141 {time zone boundary case 1989-10-29 01:59:59} detroit {
+ clock format 625643999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.142 {time zone boundary case 1989-10-29 01:00:00} detroit {
+ clock format 625644000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.143 {time zone boundary case 1989-10-29 01:00:01} detroit {
+ clock format 625644001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.144 {time zone boundary case 1990-04-01 01:59:59} detroit {
+ clock format 638953199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.145 {time zone boundary case 1990-04-01 03:00:00} detroit {
+ clock format 638953200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.146 {time zone boundary case 1990-04-01 03:00:01} detroit {
+ clock format 638953201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.147 {time zone boundary case 1990-10-28 01:59:59} detroit {
+ clock format 657093599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.148 {time zone boundary case 1990-10-28 01:00:00} detroit {
+ clock format 657093600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.149 {time zone boundary case 1990-10-28 01:00:01} detroit {
+ clock format 657093601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.150 {time zone boundary case 1991-04-07 01:59:59} detroit {
+ clock format 671007599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.151 {time zone boundary case 1991-04-07 03:00:00} detroit {
+ clock format 671007600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.152 {time zone boundary case 1991-04-07 03:00:01} detroit {
+ clock format 671007601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.153 {time zone boundary case 1991-10-27 01:59:59} detroit {
+ clock format 688543199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.154 {time zone boundary case 1991-10-27 01:00:00} detroit {
+ clock format 688543200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.155 {time zone boundary case 1991-10-27 01:00:01} detroit {
+ clock format 688543201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.156 {time zone boundary case 1992-04-05 01:59:59} detroit {
+ clock format 702457199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.157 {time zone boundary case 1992-04-05 03:00:00} detroit {
+ clock format 702457200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.158 {time zone boundary case 1992-04-05 03:00:01} detroit {
+ clock format 702457201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.159 {time zone boundary case 1992-10-25 01:59:59} detroit {
+ clock format 719992799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.160 {time zone boundary case 1992-10-25 01:00:00} detroit {
+ clock format 719992800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.161 {time zone boundary case 1992-10-25 01:00:01} detroit {
+ clock format 719992801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.162 {time zone boundary case 1993-04-04 01:59:59} detroit {
+ clock format 733906799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.163 {time zone boundary case 1993-04-04 03:00:00} detroit {
+ clock format 733906800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.164 {time zone boundary case 1993-04-04 03:00:01} detroit {
+ clock format 733906801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.165 {time zone boundary case 1993-10-31 01:59:59} detroit {
+ clock format 752047199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.166 {time zone boundary case 1993-10-31 01:00:00} detroit {
+ clock format 752047200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.167 {time zone boundary case 1993-10-31 01:00:01} detroit {
+ clock format 752047201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.168 {time zone boundary case 1994-04-03 01:59:59} detroit {
+ clock format 765356399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.169 {time zone boundary case 1994-04-03 03:00:00} detroit {
+ clock format 765356400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.170 {time zone boundary case 1994-04-03 03:00:01} detroit {
+ clock format 765356401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.171 {time zone boundary case 1994-10-30 01:59:59} detroit {
+ clock format 783496799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.172 {time zone boundary case 1994-10-30 01:00:00} detroit {
+ clock format 783496800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.173 {time zone boundary case 1994-10-30 01:00:01} detroit {
+ clock format 783496801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.174 {time zone boundary case 1995-04-02 01:59:59} detroit {
+ clock format 796805999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.175 {time zone boundary case 1995-04-02 03:00:00} detroit {
+ clock format 796806000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.176 {time zone boundary case 1995-04-02 03:00:01} detroit {
+ clock format 796806001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.177 {time zone boundary case 1995-10-29 01:59:59} detroit {
+ clock format 814946399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.178 {time zone boundary case 1995-10-29 01:00:00} detroit {
+ clock format 814946400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.179 {time zone boundary case 1995-10-29 01:00:01} detroit {
+ clock format 814946401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.180 {time zone boundary case 1996-04-07 01:59:59} detroit {
+ clock format 828860399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.181 {time zone boundary case 1996-04-07 03:00:00} detroit {
+ clock format 828860400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.182 {time zone boundary case 1996-04-07 03:00:01} detroit {
+ clock format 828860401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.183 {time zone boundary case 1996-10-27 01:59:59} detroit {
+ clock format 846395999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.184 {time zone boundary case 1996-10-27 01:00:00} detroit {
+ clock format 846396000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.185 {time zone boundary case 1996-10-27 01:00:01} detroit {
+ clock format 846396001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.186 {time zone boundary case 1997-04-06 01:59:59} detroit {
+ clock format 860309999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.187 {time zone boundary case 1997-04-06 03:00:00} detroit {
+ clock format 860310000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.188 {time zone boundary case 1997-04-06 03:00:01} detroit {
+ clock format 860310001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.189 {time zone boundary case 1997-10-26 01:59:59} detroit {
+ clock format 877845599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.190 {time zone boundary case 1997-10-26 01:00:00} detroit {
+ clock format 877845600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.191 {time zone boundary case 1997-10-26 01:00:01} detroit {
+ clock format 877845601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.192 {time zone boundary case 1998-04-05 01:59:59} detroit {
+ clock format 891759599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.193 {time zone boundary case 1998-04-05 03:00:00} detroit {
+ clock format 891759600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.194 {time zone boundary case 1998-04-05 03:00:01} detroit {
+ clock format 891759601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.195 {time zone boundary case 1998-10-25 01:59:59} detroit {
+ clock format 909295199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.196 {time zone boundary case 1998-10-25 01:00:00} detroit {
+ clock format 909295200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.197 {time zone boundary case 1998-10-25 01:00:01} detroit {
+ clock format 909295201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.198 {time zone boundary case 1999-04-04 01:59:59} detroit {
+ clock format 923209199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.199 {time zone boundary case 1999-04-04 03:00:00} detroit {
+ clock format 923209200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.200 {time zone boundary case 1999-04-04 03:00:01} detroit {
+ clock format 923209201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.201 {time zone boundary case 1999-10-31 01:59:59} detroit {
+ clock format 941349599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.202 {time zone boundary case 1999-10-31 01:00:00} detroit {
+ clock format 941349600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.203 {time zone boundary case 1999-10-31 01:00:01} detroit {
+ clock format 941349601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.204 {time zone boundary case 2000-04-02 01:59:59} detroit {
+ clock format 954658799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.205 {time zone boundary case 2000-04-02 03:00:00} detroit {
+ clock format 954658800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.206 {time zone boundary case 2000-04-02 03:00:01} detroit {
+ clock format 954658801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.207 {time zone boundary case 2000-10-29 01:59:59} detroit {
+ clock format 972799199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.208 {time zone boundary case 2000-10-29 01:00:00} detroit {
+ clock format 972799200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.209 {time zone boundary case 2000-10-29 01:00:01} detroit {
+ clock format 972799201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.210 {time zone boundary case 2001-04-01 01:59:59} detroit {
+ clock format 986108399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.211 {time zone boundary case 2001-04-01 03:00:00} detroit {
+ clock format 986108400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.212 {time zone boundary case 2001-04-01 03:00:01} detroit {
+ clock format 986108401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.213 {time zone boundary case 2001-10-28 01:59:59} detroit {
+ clock format 1004248799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.214 {time zone boundary case 2001-10-28 01:00:00} detroit {
+ clock format 1004248800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.215 {time zone boundary case 2001-10-28 01:00:01} detroit {
+ clock format 1004248801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.216 {time zone boundary case 2002-04-07 01:59:59} detroit {
+ clock format 1018162799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.217 {time zone boundary case 2002-04-07 03:00:00} detroit {
+ clock format 1018162800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.218 {time zone boundary case 2002-04-07 03:00:01} detroit {
+ clock format 1018162801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.219 {time zone boundary case 2002-10-27 01:59:59} detroit {
+ clock format 1035698399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.220 {time zone boundary case 2002-10-27 01:00:00} detroit {
+ clock format 1035698400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.221 {time zone boundary case 2002-10-27 01:00:01} detroit {
+ clock format 1035698401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.222 {time zone boundary case 2003-04-06 01:59:59} detroit {
+ clock format 1049612399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.223 {time zone boundary case 2003-04-06 03:00:00} detroit {
+ clock format 1049612400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.224 {time zone boundary case 2003-04-06 03:00:01} detroit {
+ clock format 1049612401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.225 {time zone boundary case 2003-10-26 01:59:59} detroit {
+ clock format 1067147999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.226 {time zone boundary case 2003-10-26 01:00:00} detroit {
+ clock format 1067148000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.227 {time zone boundary case 2003-10-26 01:00:01} detroit {
+ clock format 1067148001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.228 {time zone boundary case 2004-04-04 01:59:59} detroit {
+ clock format 1081061999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.229 {time zone boundary case 2004-04-04 03:00:00} detroit {
+ clock format 1081062000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.230 {time zone boundary case 2004-04-04 03:00:01} detroit {
+ clock format 1081062001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.231 {time zone boundary case 2004-10-31 01:59:59} detroit {
+ clock format 1099202399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.232 {time zone boundary case 2004-10-31 01:00:00} detroit {
+ clock format 1099202400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.233 {time zone boundary case 2004-10-31 01:00:01} detroit {
+ clock format 1099202401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.234 {time zone boundary case 2005-04-03 01:59:59} detroit {
+ clock format 1112511599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.235 {time zone boundary case 2005-04-03 03:00:00} detroit {
+ clock format 1112511600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.236 {time zone boundary case 2005-04-03 03:00:01} detroit {
+ clock format 1112511601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.237 {time zone boundary case 2005-10-30 01:59:59} detroit {
+ clock format 1130651999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.238 {time zone boundary case 2005-10-30 01:00:00} detroit {
+ clock format 1130652000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.239 {time zone boundary case 2005-10-30 01:00:01} detroit {
+ clock format 1130652001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.240 {time zone boundary case 2006-04-02 01:59:59} detroit {
+ clock format 1143961199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.241 {time zone boundary case 2006-04-02 03:00:00} detroit {
+ clock format 1143961200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.242 {time zone boundary case 2006-04-02 03:00:01} detroit {
+ clock format 1143961201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.243 {time zone boundary case 2006-10-29 01:59:59} detroit {
+ clock format 1162101599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.244 {time zone boundary case 2006-10-29 01:00:00} detroit {
+ clock format 1162101600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.245 {time zone boundary case 2006-10-29 01:00:01} detroit {
+ clock format 1162101601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.246 {time zone boundary case 2007-03-11 01:59:59} detroit {
+ clock format 1173596399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.247 {time zone boundary case 2007-03-11 03:00:00} detroit {
+ clock format 1173596400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.248 {time zone boundary case 2007-03-11 03:00:01} detroit {
+ clock format 1173596401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.249 {time zone boundary case 2007-11-04 01:59:59} detroit {
+ clock format 1194155999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.250 {time zone boundary case 2007-11-04 01:00:00} detroit {
+ clock format 1194156000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.251 {time zone boundary case 2007-11-04 01:00:01} detroit {
+ clock format 1194156001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.252 {time zone boundary case 2008-03-09 01:59:59} detroit {
+ clock format 1205045999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.253 {time zone boundary case 2008-03-09 03:00:00} detroit {
+ clock format 1205046000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.254 {time zone boundary case 2008-03-09 03:00:01} detroit {
+ clock format 1205046001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.255 {time zone boundary case 2008-11-02 01:59:59} detroit {
+ clock format 1225605599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.256 {time zone boundary case 2008-11-02 01:00:00} detroit {
+ clock format 1225605600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.257 {time zone boundary case 2008-11-02 01:00:01} detroit {
+ clock format 1225605601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.258 {time zone boundary case 2009-03-08 01:59:59} detroit {
+ clock format 1236495599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.259 {time zone boundary case 2009-03-08 03:00:00} detroit {
+ clock format 1236495600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.260 {time zone boundary case 2009-03-08 03:00:01} detroit {
+ clock format 1236495601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.261 {time zone boundary case 2009-11-01 01:59:59} detroit {
+ clock format 1257055199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.262 {time zone boundary case 2009-11-01 01:00:00} detroit {
+ clock format 1257055200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.263 {time zone boundary case 2009-11-01 01:00:01} detroit {
+ clock format 1257055201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.264 {time zone boundary case 2010-03-14 01:59:59} detroit {
+ clock format 1268549999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.265 {time zone boundary case 2010-03-14 03:00:00} detroit {
+ clock format 1268550000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.266 {time zone boundary case 2010-03-14 03:00:01} detroit {
+ clock format 1268550001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.267 {time zone boundary case 2010-11-07 01:59:59} detroit {
+ clock format 1289109599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.268 {time zone boundary case 2010-11-07 01:00:00} detroit {
+ clock format 1289109600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.269 {time zone boundary case 2010-11-07 01:00:01} detroit {
+ clock format 1289109601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.270 {time zone boundary case 2011-03-13 01:59:59} detroit {
+ clock format 1299999599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.271 {time zone boundary case 2011-03-13 03:00:00} detroit {
+ clock format 1299999600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.272 {time zone boundary case 2011-03-13 03:00:01} detroit {
+ clock format 1299999601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.273 {time zone boundary case 2011-11-06 01:59:59} detroit {
+ clock format 1320559199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.274 {time zone boundary case 2011-11-06 01:00:00} detroit {
+ clock format 1320559200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.275 {time zone boundary case 2011-11-06 01:00:01} detroit {
+ clock format 1320559201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.276 {time zone boundary case 2012-03-11 01:59:59} detroit {
+ clock format 1331449199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.277 {time zone boundary case 2012-03-11 03:00:00} detroit {
+ clock format 1331449200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.278 {time zone boundary case 2012-03-11 03:00:01} detroit {
+ clock format 1331449201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.279 {time zone boundary case 2012-11-04 01:59:59} detroit {
+ clock format 1352008799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.280 {time zone boundary case 2012-11-04 01:00:00} detroit {
+ clock format 1352008800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.281 {time zone boundary case 2012-11-04 01:00:01} detroit {
+ clock format 1352008801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.282 {time zone boundary case 2013-03-10 01:59:59} detroit {
+ clock format 1362898799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.283 {time zone boundary case 2013-03-10 03:00:00} detroit {
+ clock format 1362898800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.284 {time zone boundary case 2013-03-10 03:00:01} detroit {
+ clock format 1362898801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.285 {time zone boundary case 2013-11-03 01:59:59} detroit {
+ clock format 1383458399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.286 {time zone boundary case 2013-11-03 01:00:00} detroit {
+ clock format 1383458400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.287 {time zone boundary case 2013-11-03 01:00:01} detroit {
+ clock format 1383458401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.288 {time zone boundary case 2014-03-09 01:59:59} detroit {
+ clock format 1394348399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.289 {time zone boundary case 2014-03-09 03:00:00} detroit {
+ clock format 1394348400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.290 {time zone boundary case 2014-03-09 03:00:01} detroit {
+ clock format 1394348401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.291 {time zone boundary case 2014-11-02 01:59:59} detroit {
+ clock format 1414907999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.292 {time zone boundary case 2014-11-02 01:00:00} detroit {
+ clock format 1414908000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.293 {time zone boundary case 2014-11-02 01:00:01} detroit {
+ clock format 1414908001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.294 {time zone boundary case 2015-03-08 01:59:59} detroit {
+ clock format 1425797999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.295 {time zone boundary case 2015-03-08 03:00:00} detroit {
+ clock format 1425798000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.296 {time zone boundary case 2015-03-08 03:00:01} detroit {
+ clock format 1425798001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.297 {time zone boundary case 2015-11-01 01:59:59} detroit {
+ clock format 1446357599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.298 {time zone boundary case 2015-11-01 01:00:00} detroit {
+ clock format 1446357600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.299 {time zone boundary case 2015-11-01 01:00:01} detroit {
+ clock format 1446357601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.300 {time zone boundary case 2016-03-13 01:59:59} detroit {
+ clock format 1457852399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.301 {time zone boundary case 2016-03-13 03:00:00} detroit {
+ clock format 1457852400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.302 {time zone boundary case 2016-03-13 03:00:01} detroit {
+ clock format 1457852401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.303 {time zone boundary case 2016-11-06 01:59:59} detroit {
+ clock format 1478411999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.304 {time zone boundary case 2016-11-06 01:00:00} detroit {
+ clock format 1478412000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.305 {time zone boundary case 2016-11-06 01:00:01} detroit {
+ clock format 1478412001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.306 {time zone boundary case 2017-03-12 01:59:59} detroit {
+ clock format 1489301999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.307 {time zone boundary case 2017-03-12 03:00:00} detroit {
+ clock format 1489302000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.308 {time zone boundary case 2017-03-12 03:00:01} detroit {
+ clock format 1489302001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.309 {time zone boundary case 2017-11-05 01:59:59} detroit {
+ clock format 1509861599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.310 {time zone boundary case 2017-11-05 01:00:00} detroit {
+ clock format 1509861600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.311 {time zone boundary case 2017-11-05 01:00:01} detroit {
+ clock format 1509861601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.312 {time zone boundary case 2018-03-11 01:59:59} detroit {
+ clock format 1520751599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.313 {time zone boundary case 2018-03-11 03:00:00} detroit {
+ clock format 1520751600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.314 {time zone boundary case 2018-03-11 03:00:01} detroit {
+ clock format 1520751601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.315 {time zone boundary case 2018-11-04 01:59:59} detroit {
+ clock format 1541311199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.316 {time zone boundary case 2018-11-04 01:00:00} detroit {
+ clock format 1541311200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.317 {time zone boundary case 2018-11-04 01:00:01} detroit {
+ clock format 1541311201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.318 {time zone boundary case 2019-03-10 01:59:59} detroit {
+ clock format 1552201199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.319 {time zone boundary case 2019-03-10 03:00:00} detroit {
+ clock format 1552201200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.320 {time zone boundary case 2019-03-10 03:00:01} detroit {
+ clock format 1552201201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.321 {time zone boundary case 2019-11-03 01:59:59} detroit {
+ clock format 1572760799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.322 {time zone boundary case 2019-11-03 01:00:00} detroit {
+ clock format 1572760800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.323 {time zone boundary case 2019-11-03 01:00:01} detroit {
+ clock format 1572760801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.324 {time zone boundary case 2020-03-08 01:59:59} detroit {
+ clock format 1583650799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.325 {time zone boundary case 2020-03-08 03:00:00} detroit {
+ clock format 1583650800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.326 {time zone boundary case 2020-03-08 03:00:01} detroit {
+ clock format 1583650801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.327 {time zone boundary case 2020-11-01 01:59:59} detroit {
+ clock format 1604210399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.328 {time zone boundary case 2020-11-01 01:00:00} detroit {
+ clock format 1604210400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.329 {time zone boundary case 2020-11-01 01:00:01} detroit {
+ clock format 1604210401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.330 {time zone boundary case 2021-03-14 01:59:59} detroit {
+ clock format 1615705199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.331 {time zone boundary case 2021-03-14 03:00:00} detroit {
+ clock format 1615705200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.332 {time zone boundary case 2021-03-14 03:00:01} detroit {
+ clock format 1615705201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.333 {time zone boundary case 2021-11-07 01:59:59} detroit {
+ clock format 1636264799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.334 {time zone boundary case 2021-11-07 01:00:00} detroit {
+ clock format 1636264800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.335 {time zone boundary case 2021-11-07 01:00:01} detroit {
+ clock format 1636264801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.336 {time zone boundary case 2022-03-13 01:59:59} detroit {
+ clock format 1647154799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.337 {time zone boundary case 2022-03-13 03:00:00} detroit {
+ clock format 1647154800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.338 {time zone boundary case 2022-03-13 03:00:01} detroit {
+ clock format 1647154801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.339 {time zone boundary case 2022-11-06 01:59:59} detroit {
+ clock format 1667714399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.340 {time zone boundary case 2022-11-06 01:00:00} detroit {
+ clock format 1667714400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.341 {time zone boundary case 2022-11-06 01:00:01} detroit {
+ clock format 1667714401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.342 {time zone boundary case 2023-03-12 01:59:59} detroit {
+ clock format 1678604399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.343 {time zone boundary case 2023-03-12 03:00:00} detroit {
+ clock format 1678604400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.344 {time zone boundary case 2023-03-12 03:00:01} detroit {
+ clock format 1678604401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.345 {time zone boundary case 2023-11-05 01:59:59} detroit {
+ clock format 1699163999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.346 {time zone boundary case 2023-11-05 01:00:00} detroit {
+ clock format 1699164000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.347 {time zone boundary case 2023-11-05 01:00:01} detroit {
+ clock format 1699164001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.348 {time zone boundary case 2024-03-10 01:59:59} detroit {
+ clock format 1710053999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.349 {time zone boundary case 2024-03-10 03:00:00} detroit {
+ clock format 1710054000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.350 {time zone boundary case 2024-03-10 03:00:01} detroit {
+ clock format 1710054001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.351 {time zone boundary case 2024-11-03 01:59:59} detroit {
+ clock format 1730613599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.352 {time zone boundary case 2024-11-03 01:00:00} detroit {
+ clock format 1730613600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.353 {time zone boundary case 2024-11-03 01:00:01} detroit {
+ clock format 1730613601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.354 {time zone boundary case 2025-03-09 01:59:59} detroit {
+ clock format 1741503599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.355 {time zone boundary case 2025-03-09 03:00:00} detroit {
+ clock format 1741503600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.356 {time zone boundary case 2025-03-09 03:00:01} detroit {
+ clock format 1741503601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.357 {time zone boundary case 2025-11-02 01:59:59} detroit {
+ clock format 1762063199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.358 {time zone boundary case 2025-11-02 01:00:00} detroit {
+ clock format 1762063200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.359 {time zone boundary case 2025-11-02 01:00:01} detroit {
+ clock format 1762063201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.360 {time zone boundary case 2026-03-08 01:59:59} detroit {
+ clock format 1772953199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.361 {time zone boundary case 2026-03-08 03:00:00} detroit {
+ clock format 1772953200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.362 {time zone boundary case 2026-03-08 03:00:01} detroit {
+ clock format 1772953201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.363 {time zone boundary case 2026-11-01 01:59:59} detroit {
+ clock format 1793512799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.364 {time zone boundary case 2026-11-01 01:00:00} detroit {
+ clock format 1793512800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.365 {time zone boundary case 2026-11-01 01:00:01} detroit {
+ clock format 1793512801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.366 {time zone boundary case 2027-03-14 01:59:59} detroit {
+ clock format 1805007599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.367 {time zone boundary case 2027-03-14 03:00:00} detroit {
+ clock format 1805007600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.368 {time zone boundary case 2027-03-14 03:00:01} detroit {
+ clock format 1805007601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.369 {time zone boundary case 2027-11-07 01:59:59} detroit {
+ clock format 1825567199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.370 {time zone boundary case 2027-11-07 01:00:00} detroit {
+ clock format 1825567200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.371 {time zone boundary case 2027-11-07 01:00:01} detroit {
+ clock format 1825567201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.372 {time zone boundary case 2028-03-12 01:59:59} detroit {
+ clock format 1836457199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.373 {time zone boundary case 2028-03-12 03:00:00} detroit {
+ clock format 1836457200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.374 {time zone boundary case 2028-03-12 03:00:01} detroit {
+ clock format 1836457201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.375 {time zone boundary case 2028-11-05 01:59:59} detroit {
+ clock format 1857016799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.376 {time zone boundary case 2028-11-05 01:00:00} detroit {
+ clock format 1857016800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.377 {time zone boundary case 2028-11-05 01:00:01} detroit {
+ clock format 1857016801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.378 {time zone boundary case 2029-03-11 01:59:59} detroit {
+ clock format 1867906799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.379 {time zone boundary case 2029-03-11 03:00:00} detroit {
+ clock format 1867906800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.380 {time zone boundary case 2029-03-11 03:00:01} detroit {
+ clock format 1867906801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.381 {time zone boundary case 2029-11-04 01:59:59} detroit {
+ clock format 1888466399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.382 {time zone boundary case 2029-11-04 01:00:00} detroit {
+ clock format 1888466400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.383 {time zone boundary case 2029-11-04 01:00:01} detroit {
+ clock format 1888466401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.384 {time zone boundary case 2030-03-10 01:59:59} detroit {
+ clock format 1899356399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.385 {time zone boundary case 2030-03-10 03:00:00} detroit {
+ clock format 1899356400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.386 {time zone boundary case 2030-03-10 03:00:01} detroit {
+ clock format 1899356401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.387 {time zone boundary case 2030-11-03 01:59:59} detroit {
+ clock format 1919915999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.388 {time zone boundary case 2030-11-03 01:00:00} detroit {
+ clock format 1919916000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.389 {time zone boundary case 2030-11-03 01:00:01} detroit {
+ clock format 1919916001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.390 {time zone boundary case 2031-03-09 01:59:59} detroit {
+ clock format 1930805999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.391 {time zone boundary case 2031-03-09 03:00:00} detroit {
+ clock format 1930806000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.392 {time zone boundary case 2031-03-09 03:00:01} detroit {
+ clock format 1930806001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.393 {time zone boundary case 2031-11-02 01:59:59} detroit {
+ clock format 1951365599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.394 {time zone boundary case 2031-11-02 01:00:00} detroit {
+ clock format 1951365600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.395 {time zone boundary case 2031-11-02 01:00:01} detroit {
+ clock format 1951365601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.396 {time zone boundary case 2032-03-14 01:59:59} detroit {
+ clock format 1962860399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.397 {time zone boundary case 2032-03-14 03:00:00} detroit {
+ clock format 1962860400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.398 {time zone boundary case 2032-03-14 03:00:01} detroit {
+ clock format 1962860401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.399 {time zone boundary case 2032-11-07 01:59:59} detroit {
+ clock format 1983419999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.400 {time zone boundary case 2032-11-07 01:00:00} detroit {
+ clock format 1983420000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.401 {time zone boundary case 2032-11-07 01:00:01} detroit {
+ clock format 1983420001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.402 {time zone boundary case 2033-03-13 01:59:59} detroit {
+ clock format 1994309999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.403 {time zone boundary case 2033-03-13 03:00:00} detroit {
+ clock format 1994310000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.404 {time zone boundary case 2033-03-13 03:00:01} detroit {
+ clock format 1994310001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.405 {time zone boundary case 2033-11-06 01:59:59} detroit {
+ clock format 2014869599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.406 {time zone boundary case 2033-11-06 01:00:00} detroit {
+ clock format 2014869600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.407 {time zone boundary case 2033-11-06 01:00:01} detroit {
+ clock format 2014869601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.408 {time zone boundary case 2034-03-12 01:59:59} detroit {
+ clock format 2025759599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.409 {time zone boundary case 2034-03-12 03:00:00} detroit {
+ clock format 2025759600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.410 {time zone boundary case 2034-03-12 03:00:01} detroit {
+ clock format 2025759601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.411 {time zone boundary case 2034-11-05 01:59:59} detroit {
+ clock format 2046319199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.412 {time zone boundary case 2034-11-05 01:00:00} detroit {
+ clock format 2046319200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.413 {time zone boundary case 2034-11-05 01:00:01} detroit {
+ clock format 2046319201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.414 {time zone boundary case 2035-03-11 01:59:59} detroit {
+ clock format 2057209199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.415 {time zone boundary case 2035-03-11 03:00:00} detroit {
+ clock format 2057209200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.416 {time zone boundary case 2035-03-11 03:00:01} detroit {
+ clock format 2057209201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.417 {time zone boundary case 2035-11-04 01:59:59} detroit {
+ clock format 2077768799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.418 {time zone boundary case 2035-11-04 01:00:00} detroit {
+ clock format 2077768800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.419 {time zone boundary case 2035-11-04 01:00:01} detroit {
+ clock format 2077768801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.420 {time zone boundary case 2036-03-09 01:59:59} detroit {
+ clock format 2088658799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.421 {time zone boundary case 2036-03-09 03:00:00} detroit {
+ clock format 2088658800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.422 {time zone boundary case 2036-03-09 03:00:01} detroit {
+ clock format 2088658801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.423 {time zone boundary case 2036-11-02 01:59:59} detroit {
+ clock format 2109218399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.424 {time zone boundary case 2036-11-02 01:00:00} detroit {
+ clock format 2109218400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.425 {time zone boundary case 2036-11-02 01:00:01} detroit {
+ clock format 2109218401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.426 {time zone boundary case 2037-03-08 01:59:59} detroit {
+ clock format 2120108399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.427 {time zone boundary case 2037-03-08 03:00:00} detroit {
+ clock format 2120108400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.428 {time zone boundary case 2037-03-08 03:00:01} detroit {
+ clock format 2120108401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.429 {time zone boundary case 2037-11-01 01:59:59} detroit {
+ clock format 2140667999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.430 {time zone boundary case 2037-11-01 01:00:00} detroit {
+ clock format 2140668000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.431 {time zone boundary case 2037-11-01 01:00:01} detroit {
+ clock format 2140668001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.432 {time zone boundary case 2038-03-14 01:59:59} {detroit y2038} {
+ clock format 2152162799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.433 {time zone boundary case 2038-03-14 03:00:00} {detroit y2038} {
+ clock format 2152162800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.434 {time zone boundary case 2038-03-14 03:00:01} {detroit y2038} {
+ clock format 2152162801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.435 {time zone boundary case 2038-11-07 01:59:59} {detroit y2038} {
+ clock format 2172722399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.436 {time zone boundary case 2038-11-07 01:00:00} {detroit y2038} {
+ clock format 2172722400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.437 {time zone boundary case 2038-11-07 01:00:01} {detroit y2038} {
+ clock format 2172722401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.438 {time zone boundary case 2039-03-13 01:59:59} {detroit y2038} {
+ clock format 2183612399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.439 {time zone boundary case 2039-03-13 03:00:00} {detroit y2038} {
+ clock format 2183612400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.440 {time zone boundary case 2039-03-13 03:00:01} {detroit y2038} {
+ clock format 2183612401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.441 {time zone boundary case 2039-11-06 01:59:59} {detroit y2038} {
+ clock format 2204171999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.442 {time zone boundary case 2039-11-06 01:00:00} {detroit y2038} {
+ clock format 2204172000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.443 {time zone boundary case 2039-11-06 01:00:01} {detroit y2038} {
+ clock format 2204172001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.444 {time zone boundary case 2040-03-11 01:59:59} {detroit y2038} {
+ clock format 2215061999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.445 {time zone boundary case 2040-03-11 03:00:00} {detroit y2038} {
+ clock format 2215062000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.446 {time zone boundary case 2040-03-11 03:00:01} {detroit y2038} {
+ clock format 2215062001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.447 {time zone boundary case 2040-11-04 01:59:59} {detroit y2038} {
+ clock format 2235621599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.448 {time zone boundary case 2040-11-04 01:00:00} {detroit y2038} {
+ clock format 2235621600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.449 {time zone boundary case 2040-11-04 01:00:01} {detroit y2038} {
+ clock format 2235621601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.450 {time zone boundary case 2041-03-10 01:59:59} {detroit y2038} {
+ clock format 2246511599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.451 {time zone boundary case 2041-03-10 03:00:00} {detroit y2038} {
+ clock format 2246511600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.452 {time zone boundary case 2041-03-10 03:00:01} {detroit y2038} {
+ clock format 2246511601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.453 {time zone boundary case 2041-11-03 01:59:59} {detroit y2038} {
+ clock format 2267071199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.454 {time zone boundary case 2041-11-03 01:00:00} {detroit y2038} {
+ clock format 2267071200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.455 {time zone boundary case 2041-11-03 01:00:01} {detroit y2038} {
+ clock format 2267071201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.456 {time zone boundary case 2042-03-09 01:59:59} {detroit y2038} {
+ clock format 2277961199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.457 {time zone boundary case 2042-03-09 03:00:00} {detroit y2038} {
+ clock format 2277961200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.458 {time zone boundary case 2042-03-09 03:00:01} {detroit y2038} {
+ clock format 2277961201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.459 {time zone boundary case 2042-11-02 01:59:59} {detroit y2038} {
+ clock format 2298520799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.460 {time zone boundary case 2042-11-02 01:00:00} {detroit y2038} {
+ clock format 2298520800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.461 {time zone boundary case 2042-11-02 01:00:01} {detroit y2038} {
+ clock format 2298520801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.462 {time zone boundary case 2043-03-08 01:59:59} {detroit y2038} {
+ clock format 2309410799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.463 {time zone boundary case 2043-03-08 03:00:00} {detroit y2038} {
+ clock format 2309410800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.464 {time zone boundary case 2043-03-08 03:00:01} {detroit y2038} {
+ clock format 2309410801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.465 {time zone boundary case 2043-11-01 01:59:59} {detroit y2038} {
+ clock format 2329970399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.466 {time zone boundary case 2043-11-01 01:00:00} {detroit y2038} {
+ clock format 2329970400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.467 {time zone boundary case 2043-11-01 01:00:01} {detroit y2038} {
+ clock format 2329970401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.468 {time zone boundary case 2044-03-13 01:59:59} {detroit y2038} {
+ clock format 2341465199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.469 {time zone boundary case 2044-03-13 03:00:00} {detroit y2038} {
+ clock format 2341465200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.470 {time zone boundary case 2044-03-13 03:00:01} {detroit y2038} {
+ clock format 2341465201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.471 {time zone boundary case 2044-11-06 01:59:59} {detroit y2038} {
+ clock format 2362024799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.472 {time zone boundary case 2044-11-06 01:00:00} {detroit y2038} {
+ clock format 2362024800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.473 {time zone boundary case 2044-11-06 01:00:01} {detroit y2038} {
+ clock format 2362024801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.474 {time zone boundary case 2045-03-12 01:59:59} {detroit y2038} {
+ clock format 2372914799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.475 {time zone boundary case 2045-03-12 03:00:00} {detroit y2038} {
+ clock format 2372914800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.476 {time zone boundary case 2045-03-12 03:00:01} {detroit y2038} {
+ clock format 2372914801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.477 {time zone boundary case 2045-11-05 01:59:59} {detroit y2038} {
+ clock format 2393474399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.478 {time zone boundary case 2045-11-05 01:00:00} {detroit y2038} {
+ clock format 2393474400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.479 {time zone boundary case 2045-11-05 01:00:01} {detroit y2038} {
+ clock format 2393474401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.480 {time zone boundary case 2046-03-11 01:59:59} {detroit y2038} {
+ clock format 2404364399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.481 {time zone boundary case 2046-03-11 03:00:00} {detroit y2038} {
+ clock format 2404364400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.482 {time zone boundary case 2046-03-11 03:00:01} {detroit y2038} {
+ clock format 2404364401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.483 {time zone boundary case 2046-11-04 01:59:59} {detroit y2038} {
+ clock format 2424923999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.484 {time zone boundary case 2046-11-04 01:00:00} {detroit y2038} {
+ clock format 2424924000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.485 {time zone boundary case 2046-11-04 01:00:01} {detroit y2038} {
+ clock format 2424924001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.486 {time zone boundary case 2047-03-10 01:59:59} {detroit y2038} {
+ clock format 2435813999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.487 {time zone boundary case 2047-03-10 03:00:00} {detroit y2038} {
+ clock format 2435814000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.488 {time zone boundary case 2047-03-10 03:00:01} {detroit y2038} {
+ clock format 2435814001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.489 {time zone boundary case 2047-11-03 01:59:59} {detroit y2038} {
+ clock format 2456373599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.490 {time zone boundary case 2047-11-03 01:00:00} {detroit y2038} {
+ clock format 2456373600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.491 {time zone boundary case 2047-11-03 01:00:01} {detroit y2038} {
+ clock format 2456373601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.492 {time zone boundary case 2048-03-08 01:59:59} {detroit y2038} {
+ clock format 2467263599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.493 {time zone boundary case 2048-03-08 03:00:00} {detroit y2038} {
+ clock format 2467263600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.494 {time zone boundary case 2048-03-08 03:00:01} {detroit y2038} {
+ clock format 2467263601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.495 {time zone boundary case 2048-11-01 01:59:59} {detroit y2038} {
+ clock format 2487823199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.496 {time zone boundary case 2048-11-01 01:00:00} {detroit y2038} {
+ clock format 2487823200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.497 {time zone boundary case 2048-11-01 01:00:01} {detroit y2038} {
+ clock format 2487823201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.498 {time zone boundary case 2049-03-14 01:59:59} {detroit y2038} {
+ clock format 2499317999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.499 {time zone boundary case 2049-03-14 03:00:00} {detroit y2038} {
+ clock format 2499318000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.500 {time zone boundary case 2049-03-14 03:00:01} {detroit y2038} {
+ clock format 2499318001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.501 {time zone boundary case 2049-11-07 01:59:59} {detroit y2038} {
+ clock format 2519877599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.502 {time zone boundary case 2049-11-07 01:00:00} {detroit y2038} {
+ clock format 2519877600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.503 {time zone boundary case 2049-11-07 01:00:01} {detroit y2038} {
+ clock format 2519877601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.504 {time zone boundary case 2050-03-13 01:59:59} {detroit y2038} {
+ clock format 2530767599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.505 {time zone boundary case 2050-03-13 03:00:00} {detroit y2038} {
+ clock format 2530767600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.506 {time zone boundary case 2050-03-13 03:00:01} {detroit y2038} {
+ clock format 2530767601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.507 {time zone boundary case 2050-11-06 01:59:59} {detroit y2038} {
+ clock format 2551327199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.508 {time zone boundary case 2050-11-06 01:00:00} {detroit y2038} {
+ clock format 2551327200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.509 {time zone boundary case 2050-11-06 01:00:01} {detroit y2038} {
+ clock format 2551327201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.510 {time zone boundary case 2051-03-12 01:59:59} {detroit y2038} {
+ clock format 2562217199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.511 {time zone boundary case 2051-03-12 03:00:00} {detroit y2038} {
+ clock format 2562217200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.512 {time zone boundary case 2051-03-12 03:00:01} {detroit y2038} {
+ clock format 2562217201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.513 {time zone boundary case 2051-11-05 01:59:59} {detroit y2038} {
+ clock format 2582776799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.514 {time zone boundary case 2051-11-05 01:00:00} {detroit y2038} {
+ clock format 2582776800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.515 {time zone boundary case 2051-11-05 01:00:01} {detroit y2038} {
+ clock format 2582776801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.516 {time zone boundary case 2052-03-10 01:59:59} {detroit y2038} {
+ clock format 2593666799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.517 {time zone boundary case 2052-03-10 03:00:00} {detroit y2038} {
+ clock format 2593666800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.518 {time zone boundary case 2052-03-10 03:00:01} {detroit y2038} {
+ clock format 2593666801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.519 {time zone boundary case 2052-11-03 01:59:59} {detroit y2038} {
+ clock format 2614226399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.520 {time zone boundary case 2052-11-03 01:00:00} {detroit y2038} {
+ clock format 2614226400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.521 {time zone boundary case 2052-11-03 01:00:01} {detroit y2038} {
+ clock format 2614226401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.522 {time zone boundary case 2053-03-09 01:59:59} {detroit y2038} {
+ clock format 2625116399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.523 {time zone boundary case 2053-03-09 03:00:00} {detroit y2038} {
+ clock format 2625116400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.524 {time zone boundary case 2053-03-09 03:00:01} {detroit y2038} {
+ clock format 2625116401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.525 {time zone boundary case 2053-11-02 01:59:59} {detroit y2038} {
+ clock format 2645675999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.526 {time zone boundary case 2053-11-02 01:00:00} {detroit y2038} {
+ clock format 2645676000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.527 {time zone boundary case 2053-11-02 01:00:01} {detroit y2038} {
+ clock format 2645676001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.528 {time zone boundary case 2054-03-08 01:59:59} {detroit y2038} {
+ clock format 2656565999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.529 {time zone boundary case 2054-03-08 03:00:00} {detroit y2038} {
+ clock format 2656566000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.530 {time zone boundary case 2054-03-08 03:00:01} {detroit y2038} {
+ clock format 2656566001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.531 {time zone boundary case 2054-11-01 01:59:59} {detroit y2038} {
+ clock format 2677125599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.532 {time zone boundary case 2054-11-01 01:00:00} {detroit y2038} {
+ clock format 2677125600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.533 {time zone boundary case 2054-11-01 01:00:01} {detroit y2038} {
+ clock format 2677125601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.534 {time zone boundary case 2055-03-14 01:59:59} {detroit y2038} {
+ clock format 2688620399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.535 {time zone boundary case 2055-03-14 03:00:00} {detroit y2038} {
+ clock format 2688620400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.536 {time zone boundary case 2055-03-14 03:00:01} {detroit y2038} {
+ clock format 2688620401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.537 {time zone boundary case 2055-11-07 01:59:59} {detroit y2038} {
+ clock format 2709179999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.538 {time zone boundary case 2055-11-07 01:00:00} {detroit y2038} {
+ clock format 2709180000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.539 {time zone boundary case 2055-11-07 01:00:01} {detroit y2038} {
+ clock format 2709180001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.540 {time zone boundary case 2056-03-12 01:59:59} {detroit y2038} {
+ clock format 2720069999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.541 {time zone boundary case 2056-03-12 03:00:00} {detroit y2038} {
+ clock format 2720070000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.542 {time zone boundary case 2056-03-12 03:00:01} {detroit y2038} {
+ clock format 2720070001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.543 {time zone boundary case 2056-11-05 01:59:59} {detroit y2038} {
+ clock format 2740629599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.544 {time zone boundary case 2056-11-05 01:00:00} {detroit y2038} {
+ clock format 2740629600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.545 {time zone boundary case 2056-11-05 01:00:01} {detroit y2038} {
+ clock format 2740629601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.546 {time zone boundary case 2057-03-11 01:59:59} {detroit y2038} {
+ clock format 2751519599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.547 {time zone boundary case 2057-03-11 03:00:00} {detroit y2038} {
+ clock format 2751519600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.548 {time zone boundary case 2057-03-11 03:00:01} {detroit y2038} {
+ clock format 2751519601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.549 {time zone boundary case 2057-11-04 01:59:59} {detroit y2038} {
+ clock format 2772079199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.550 {time zone boundary case 2057-11-04 01:00:00} {detroit y2038} {
+ clock format 2772079200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.551 {time zone boundary case 2057-11-04 01:00:01} {detroit y2038} {
+ clock format 2772079201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.552 {time zone boundary case 2058-03-10 01:59:59} {detroit y2038} {
+ clock format 2782969199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.553 {time zone boundary case 2058-03-10 03:00:00} {detroit y2038} {
+ clock format 2782969200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.554 {time zone boundary case 2058-03-10 03:00:01} {detroit y2038} {
+ clock format 2782969201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.555 {time zone boundary case 2058-11-03 01:59:59} {detroit y2038} {
+ clock format 2803528799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.556 {time zone boundary case 2058-11-03 01:00:00} {detroit y2038} {
+ clock format 2803528800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.557 {time zone boundary case 2058-11-03 01:00:01} {detroit y2038} {
+ clock format 2803528801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.558 {time zone boundary case 2059-03-09 01:59:59} {detroit y2038} {
+ clock format 2814418799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.559 {time zone boundary case 2059-03-09 03:00:00} {detroit y2038} {
+ clock format 2814418800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.560 {time zone boundary case 2059-03-09 03:00:01} {detroit y2038} {
+ clock format 2814418801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.561 {time zone boundary case 2059-11-02 01:59:59} {detroit y2038} {
+ clock format 2834978399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.562 {time zone boundary case 2059-11-02 01:00:00} {detroit y2038} {
+ clock format 2834978400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.563 {time zone boundary case 2059-11-02 01:00:01} {detroit y2038} {
+ clock format 2834978401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.564 {time zone boundary case 2060-03-14 01:59:59} {detroit y2038} {
+ clock format 2846473199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.565 {time zone boundary case 2060-03-14 03:00:00} {detroit y2038} {
+ clock format 2846473200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.566 {time zone boundary case 2060-03-14 03:00:01} {detroit y2038} {
+ clock format 2846473201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.567 {time zone boundary case 2060-11-07 01:59:59} {detroit y2038} {
+ clock format 2867032799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.568 {time zone boundary case 2060-11-07 01:00:00} {detroit y2038} {
+ clock format 2867032800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.569 {time zone boundary case 2060-11-07 01:00:01} {detroit y2038} {
+ clock format 2867032801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.570 {time zone boundary case 2061-03-13 01:59:59} {detroit y2038} {
+ clock format 2877922799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.571 {time zone boundary case 2061-03-13 03:00:00} {detroit y2038} {
+ clock format 2877922800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.572 {time zone boundary case 2061-03-13 03:00:01} {detroit y2038} {
+ clock format 2877922801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.573 {time zone boundary case 2061-11-06 01:59:59} {detroit y2038} {
+ clock format 2898482399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.574 {time zone boundary case 2061-11-06 01:00:00} {detroit y2038} {
+ clock format 2898482400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.575 {time zone boundary case 2061-11-06 01:00:01} {detroit y2038} {
+ clock format 2898482401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.576 {time zone boundary case 2062-03-12 01:59:59} {detroit y2038} {
+ clock format 2909372399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.577 {time zone boundary case 2062-03-12 03:00:00} {detroit y2038} {
+ clock format 2909372400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.578 {time zone boundary case 2062-03-12 03:00:01} {detroit y2038} {
+ clock format 2909372401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.579 {time zone boundary case 2062-11-05 01:59:59} {detroit y2038} {
+ clock format 2929931999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.580 {time zone boundary case 2062-11-05 01:00:00} {detroit y2038} {
+ clock format 2929932000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.581 {time zone boundary case 2062-11-05 01:00:01} {detroit y2038} {
+ clock format 2929932001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.582 {time zone boundary case 2063-03-11 01:59:59} {detroit y2038} {
+ clock format 2940821999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.583 {time zone boundary case 2063-03-11 03:00:00} {detroit y2038} {
+ clock format 2940822000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.584 {time zone boundary case 2063-03-11 03:00:01} {detroit y2038} {
+ clock format 2940822001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.585 {time zone boundary case 2063-11-04 01:59:59} {detroit y2038} {
+ clock format 2961381599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.586 {time zone boundary case 2063-11-04 01:00:00} {detroit y2038} {
+ clock format 2961381600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.587 {time zone boundary case 2063-11-04 01:00:01} {detroit y2038} {
+ clock format 2961381601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.588 {time zone boundary case 2064-03-09 01:59:59} {detroit y2038} {
+ clock format 2972271599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.589 {time zone boundary case 2064-03-09 03:00:00} {detroit y2038} {
+ clock format 2972271600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.590 {time zone boundary case 2064-03-09 03:00:01} {detroit y2038} {
+ clock format 2972271601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.591 {time zone boundary case 2064-11-02 01:59:59} {detroit y2038} {
+ clock format 2992831199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.592 {time zone boundary case 2064-11-02 01:00:00} {detroit y2038} {
+ clock format 2992831200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.593 {time zone boundary case 2064-11-02 01:00:01} {detroit y2038} {
+ clock format 2992831201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.594 {time zone boundary case 2065-03-08 01:59:59} {detroit y2038} {
+ clock format 3003721199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.595 {time zone boundary case 2065-03-08 03:00:00} {detroit y2038} {
+ clock format 3003721200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.596 {time zone boundary case 2065-03-08 03:00:01} {detroit y2038} {
+ clock format 3003721201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.597 {time zone boundary case 2065-11-01 01:59:59} {detroit y2038} {
+ clock format 3024280799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.598 {time zone boundary case 2065-11-01 01:00:00} {detroit y2038} {
+ clock format 3024280800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.599 {time zone boundary case 2065-11-01 01:00:01} {detroit y2038} {
+ clock format 3024280801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.600 {time zone boundary case 2066-03-14 01:59:59} {detroit y2038} {
+ clock format 3035775599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.601 {time zone boundary case 2066-03-14 03:00:00} {detroit y2038} {
+ clock format 3035775600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.602 {time zone boundary case 2066-03-14 03:00:01} {detroit y2038} {
+ clock format 3035775601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.603 {time zone boundary case 2066-11-07 01:59:59} {detroit y2038} {
+ clock format 3056335199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.604 {time zone boundary case 2066-11-07 01:00:00} {detroit y2038} {
+ clock format 3056335200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.605 {time zone boundary case 2066-11-07 01:00:01} {detroit y2038} {
+ clock format 3056335201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.606 {time zone boundary case 2067-03-13 01:59:59} {detroit y2038} {
+ clock format 3067225199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.607 {time zone boundary case 2067-03-13 03:00:00} {detroit y2038} {
+ clock format 3067225200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.608 {time zone boundary case 2067-03-13 03:00:01} {detroit y2038} {
+ clock format 3067225201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.609 {time zone boundary case 2067-11-06 01:59:59} {detroit y2038} {
+ clock format 3087784799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.610 {time zone boundary case 2067-11-06 01:00:00} {detroit y2038} {
+ clock format 3087784800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.611 {time zone boundary case 2067-11-06 01:00:01} {detroit y2038} {
+ clock format 3087784801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.612 {time zone boundary case 2068-03-11 01:59:59} {detroit y2038} {
+ clock format 3098674799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.613 {time zone boundary case 2068-03-11 03:00:00} {detroit y2038} {
+ clock format 3098674800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.614 {time zone boundary case 2068-03-11 03:00:01} {detroit y2038} {
+ clock format 3098674801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.615 {time zone boundary case 2068-11-04 01:59:59} {detroit y2038} {
+ clock format 3119234399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.616 {time zone boundary case 2068-11-04 01:00:00} {detroit y2038} {
+ clock format 3119234400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.617 {time zone boundary case 2068-11-04 01:00:01} {detroit y2038} {
+ clock format 3119234401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.618 {time zone boundary case 2069-03-10 01:59:59} {detroit y2038} {
+ clock format 3130124399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.619 {time zone boundary case 2069-03-10 03:00:00} {detroit y2038} {
+ clock format 3130124400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.620 {time zone boundary case 2069-03-10 03:00:01} {detroit y2038} {
+ clock format 3130124401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.621 {time zone boundary case 2069-11-03 01:59:59} {detroit y2038} {
+ clock format 3150683999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.622 {time zone boundary case 2069-11-03 01:00:00} {detroit y2038} {
+ clock format 3150684000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.623 {time zone boundary case 2069-11-03 01:00:01} {detroit y2038} {
+ clock format 3150684001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.624 {time zone boundary case 2070-03-09 01:59:59} {detroit y2038} {
+ clock format 3161573999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.625 {time zone boundary case 2070-03-09 03:00:00} {detroit y2038} {
+ clock format 3161574000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.626 {time zone boundary case 2070-03-09 03:00:01} {detroit y2038} {
+ clock format 3161574001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.627 {time zone boundary case 2070-11-02 01:59:59} {detroit y2038} {
+ clock format 3182133599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.628 {time zone boundary case 2070-11-02 01:00:00} {detroit y2038} {
+ clock format 3182133600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.629 {time zone boundary case 2070-11-02 01:00:01} {detroit y2038} {
+ clock format 3182133601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.630 {time zone boundary case 2071-03-08 01:59:59} {detroit y2038} {
+ clock format 3193023599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.631 {time zone boundary case 2071-03-08 03:00:00} {detroit y2038} {
+ clock format 3193023600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.632 {time zone boundary case 2071-03-08 03:00:01} {detroit y2038} {
+ clock format 3193023601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.633 {time zone boundary case 2071-11-01 01:59:59} {detroit y2038} {
+ clock format 3213583199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.634 {time zone boundary case 2071-11-01 01:00:00} {detroit y2038} {
+ clock format 3213583200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.635 {time zone boundary case 2071-11-01 01:00:01} {detroit y2038} {
+ clock format 3213583201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.636 {time zone boundary case 2072-03-13 01:59:59} {detroit y2038} {
+ clock format 3225077999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.637 {time zone boundary case 2072-03-13 03:00:00} {detroit y2038} {
+ clock format 3225078000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.638 {time zone boundary case 2072-03-13 03:00:01} {detroit y2038} {
+ clock format 3225078001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.639 {time zone boundary case 2072-11-06 01:59:59} {detroit y2038} {
+ clock format 3245637599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.640 {time zone boundary case 2072-11-06 01:00:00} {detroit y2038} {
+ clock format 3245637600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.641 {time zone boundary case 2072-11-06 01:00:01} {detroit y2038} {
+ clock format 3245637601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.642 {time zone boundary case 2073-03-12 01:59:59} {detroit y2038} {
+ clock format 3256527599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.643 {time zone boundary case 2073-03-12 03:00:00} {detroit y2038} {
+ clock format 3256527600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.644 {time zone boundary case 2073-03-12 03:00:01} {detroit y2038} {
+ clock format 3256527601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.645 {time zone boundary case 2073-11-05 01:59:59} {detroit y2038} {
+ clock format 3277087199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.646 {time zone boundary case 2073-11-05 01:00:00} {detroit y2038} {
+ clock format 3277087200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.647 {time zone boundary case 2073-11-05 01:00:01} {detroit y2038} {
+ clock format 3277087201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.648 {time zone boundary case 2074-03-11 01:59:59} {detroit y2038} {
+ clock format 3287977199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.649 {time zone boundary case 2074-03-11 03:00:00} {detroit y2038} {
+ clock format 3287977200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.650 {time zone boundary case 2074-03-11 03:00:01} {detroit y2038} {
+ clock format 3287977201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.651 {time zone boundary case 2074-11-04 01:59:59} {detroit y2038} {
+ clock format 3308536799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.652 {time zone boundary case 2074-11-04 01:00:00} {detroit y2038} {
+ clock format 3308536800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.653 {time zone boundary case 2074-11-04 01:00:01} {detroit y2038} {
+ clock format 3308536801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.654 {time zone boundary case 2075-03-10 01:59:59} {detroit y2038} {
+ clock format 3319426799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.655 {time zone boundary case 2075-03-10 03:00:00} {detroit y2038} {
+ clock format 3319426800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.656 {time zone boundary case 2075-03-10 03:00:01} {detroit y2038} {
+ clock format 3319426801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.657 {time zone boundary case 2075-11-03 01:59:59} {detroit y2038} {
+ clock format 3339986399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.658 {time zone boundary case 2075-11-03 01:00:00} {detroit y2038} {
+ clock format 3339986400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.659 {time zone boundary case 2075-11-03 01:00:01} {detroit y2038} {
+ clock format 3339986401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.660 {time zone boundary case 2076-03-08 01:59:59} {detroit y2038} {
+ clock format 3350876399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.661 {time zone boundary case 2076-03-08 03:00:00} {detroit y2038} {
+ clock format 3350876400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.662 {time zone boundary case 2076-03-08 03:00:01} {detroit y2038} {
+ clock format 3350876401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.663 {time zone boundary case 2076-11-01 01:59:59} {detroit y2038} {
+ clock format 3371435999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.664 {time zone boundary case 2076-11-01 01:00:00} {detroit y2038} {
+ clock format 3371436000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.665 {time zone boundary case 2076-11-01 01:00:01} {detroit y2038} {
+ clock format 3371436001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.666 {time zone boundary case 2077-03-14 01:59:59} {detroit y2038} {
+ clock format 3382930799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.667 {time zone boundary case 2077-03-14 03:00:00} {detroit y2038} {
+ clock format 3382930800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.668 {time zone boundary case 2077-03-14 03:00:01} {detroit y2038} {
+ clock format 3382930801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.669 {time zone boundary case 2077-11-07 01:59:59} {detroit y2038} {
+ clock format 3403490399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.670 {time zone boundary case 2077-11-07 01:00:00} {detroit y2038} {
+ clock format 3403490400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.671 {time zone boundary case 2077-11-07 01:00:01} {detroit y2038} {
+ clock format 3403490401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.672 {time zone boundary case 2078-03-13 01:59:59} {detroit y2038} {
+ clock format 3414380399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.673 {time zone boundary case 2078-03-13 03:00:00} {detroit y2038} {
+ clock format 3414380400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.674 {time zone boundary case 2078-03-13 03:00:01} {detroit y2038} {
+ clock format 3414380401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.675 {time zone boundary case 2078-11-06 01:59:59} {detroit y2038} {
+ clock format 3434939999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.676 {time zone boundary case 2078-11-06 01:00:00} {detroit y2038} {
+ clock format 3434940000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.677 {time zone boundary case 2078-11-06 01:00:01} {detroit y2038} {
+ clock format 3434940001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.678 {time zone boundary case 2079-03-12 01:59:59} {detroit y2038} {
+ clock format 3445829999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.679 {time zone boundary case 2079-03-12 03:00:00} {detroit y2038} {
+ clock format 3445830000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.680 {time zone boundary case 2079-03-12 03:00:01} {detroit y2038} {
+ clock format 3445830001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.681 {time zone boundary case 2079-11-05 01:59:59} {detroit y2038} {
+ clock format 3466389599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.682 {time zone boundary case 2079-11-05 01:00:00} {detroit y2038} {
+ clock format 3466389600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.683 {time zone boundary case 2079-11-05 01:00:01} {detroit y2038} {
+ clock format 3466389601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.684 {time zone boundary case 2080-03-10 01:59:59} {detroit y2038} {
+ clock format 3477279599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.685 {time zone boundary case 2080-03-10 03:00:00} {detroit y2038} {
+ clock format 3477279600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.686 {time zone boundary case 2080-03-10 03:00:01} {detroit y2038} {
+ clock format 3477279601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.687 {time zone boundary case 2080-11-03 01:59:59} {detroit y2038} {
+ clock format 3497839199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.688 {time zone boundary case 2080-11-03 01:00:00} {detroit y2038} {
+ clock format 3497839200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.689 {time zone boundary case 2080-11-03 01:00:01} {detroit y2038} {
+ clock format 3497839201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.690 {time zone boundary case 2081-03-09 01:59:59} {detroit y2038} {
+ clock format 3508729199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.691 {time zone boundary case 2081-03-09 03:00:00} {detroit y2038} {
+ clock format 3508729200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.692 {time zone boundary case 2081-03-09 03:00:01} {detroit y2038} {
+ clock format 3508729201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.693 {time zone boundary case 2081-11-02 01:59:59} {detroit y2038} {
+ clock format 3529288799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.694 {time zone boundary case 2081-11-02 01:00:00} {detroit y2038} {
+ clock format 3529288800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.695 {time zone boundary case 2081-11-02 01:00:01} {detroit y2038} {
+ clock format 3529288801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.696 {time zone boundary case 2082-03-08 01:59:59} {detroit y2038} {
+ clock format 3540178799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.697 {time zone boundary case 2082-03-08 03:00:00} {detroit y2038} {
+ clock format 3540178800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.698 {time zone boundary case 2082-03-08 03:00:01} {detroit y2038} {
+ clock format 3540178801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.699 {time zone boundary case 2082-11-01 01:59:59} {detroit y2038} {
+ clock format 3560738399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.700 {time zone boundary case 2082-11-01 01:00:00} {detroit y2038} {
+ clock format 3560738400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.701 {time zone boundary case 2082-11-01 01:00:01} {detroit y2038} {
+ clock format 3560738401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.702 {time zone boundary case 2083-03-14 01:59:59} {detroit y2038} {
+ clock format 3572233199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.703 {time zone boundary case 2083-03-14 03:00:00} {detroit y2038} {
+ clock format 3572233200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.704 {time zone boundary case 2083-03-14 03:00:01} {detroit y2038} {
+ clock format 3572233201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.705 {time zone boundary case 2083-11-07 01:59:59} {detroit y2038} {
+ clock format 3592792799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.706 {time zone boundary case 2083-11-07 01:00:00} {detroit y2038} {
+ clock format 3592792800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.707 {time zone boundary case 2083-11-07 01:00:01} {detroit y2038} {
+ clock format 3592792801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.708 {time zone boundary case 2084-03-12 01:59:59} {detroit y2038} {
+ clock format 3603682799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.709 {time zone boundary case 2084-03-12 03:00:00} {detroit y2038} {
+ clock format 3603682800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.710 {time zone boundary case 2084-03-12 03:00:01} {detroit y2038} {
+ clock format 3603682801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.711 {time zone boundary case 2084-11-05 01:59:59} {detroit y2038} {
+ clock format 3624242399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.712 {time zone boundary case 2084-11-05 01:00:00} {detroit y2038} {
+ clock format 3624242400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.713 {time zone boundary case 2084-11-05 01:00:01} {detroit y2038} {
+ clock format 3624242401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.714 {time zone boundary case 2085-03-11 01:59:59} {detroit y2038} {
+ clock format 3635132399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.715 {time zone boundary case 2085-03-11 03:00:00} {detroit y2038} {
+ clock format 3635132400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.716 {time zone boundary case 2085-03-11 03:00:01} {detroit y2038} {
+ clock format 3635132401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.717 {time zone boundary case 2085-11-04 01:59:59} {detroit y2038} {
+ clock format 3655691999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.718 {time zone boundary case 2085-11-04 01:00:00} {detroit y2038} {
+ clock format 3655692000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.719 {time zone boundary case 2085-11-04 01:00:01} {detroit y2038} {
+ clock format 3655692001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.720 {time zone boundary case 2086-03-10 01:59:59} {detroit y2038} {
+ clock format 3666581999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.721 {time zone boundary case 2086-03-10 03:00:00} {detroit y2038} {
+ clock format 3666582000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.722 {time zone boundary case 2086-03-10 03:00:01} {detroit y2038} {
+ clock format 3666582001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.723 {time zone boundary case 2086-11-03 01:59:59} {detroit y2038} {
+ clock format 3687141599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.724 {time zone boundary case 2086-11-03 01:00:00} {detroit y2038} {
+ clock format 3687141600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.725 {time zone boundary case 2086-11-03 01:00:01} {detroit y2038} {
+ clock format 3687141601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.726 {time zone boundary case 2087-03-09 01:59:59} {detroit y2038} {
+ clock format 3698031599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.727 {time zone boundary case 2087-03-09 03:00:00} {detroit y2038} {
+ clock format 3698031600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.728 {time zone boundary case 2087-03-09 03:00:01} {detroit y2038} {
+ clock format 3698031601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.729 {time zone boundary case 2087-11-02 01:59:59} {detroit y2038} {
+ clock format 3718591199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.730 {time zone boundary case 2087-11-02 01:00:00} {detroit y2038} {
+ clock format 3718591200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.731 {time zone boundary case 2087-11-02 01:00:01} {detroit y2038} {
+ clock format 3718591201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.732 {time zone boundary case 2088-03-14 01:59:59} {detroit y2038} {
+ clock format 3730085999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.733 {time zone boundary case 2088-03-14 03:00:00} {detroit y2038} {
+ clock format 3730086000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.734 {time zone boundary case 2088-03-14 03:00:01} {detroit y2038} {
+ clock format 3730086001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.735 {time zone boundary case 2088-11-07 01:59:59} {detroit y2038} {
+ clock format 3750645599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.736 {time zone boundary case 2088-11-07 01:00:00} {detroit y2038} {
+ clock format 3750645600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.737 {time zone boundary case 2088-11-07 01:00:01} {detroit y2038} {
+ clock format 3750645601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.738 {time zone boundary case 2089-03-13 01:59:59} {detroit y2038} {
+ clock format 3761535599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.739 {time zone boundary case 2089-03-13 03:00:00} {detroit y2038} {
+ clock format 3761535600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.740 {time zone boundary case 2089-03-13 03:00:01} {detroit y2038} {
+ clock format 3761535601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.741 {time zone boundary case 2089-11-06 01:59:59} {detroit y2038} {
+ clock format 3782095199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.742 {time zone boundary case 2089-11-06 01:00:00} {detroit y2038} {
+ clock format 3782095200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.743 {time zone boundary case 2089-11-06 01:00:01} {detroit y2038} {
+ clock format 3782095201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.744 {time zone boundary case 2090-03-12 01:59:59} {detroit y2038} {
+ clock format 3792985199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.745 {time zone boundary case 2090-03-12 03:00:00} {detroit y2038} {
+ clock format 3792985200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.746 {time zone boundary case 2090-03-12 03:00:01} {detroit y2038} {
+ clock format 3792985201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.747 {time zone boundary case 2090-11-05 01:59:59} {detroit y2038} {
+ clock format 3813544799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.748 {time zone boundary case 2090-11-05 01:00:00} {detroit y2038} {
+ clock format 3813544800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.749 {time zone boundary case 2090-11-05 01:00:01} {detroit y2038} {
+ clock format 3813544801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.750 {time zone boundary case 2091-03-11 01:59:59} {detroit y2038} {
+ clock format 3824434799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.751 {time zone boundary case 2091-03-11 03:00:00} {detroit y2038} {
+ clock format 3824434800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.752 {time zone boundary case 2091-03-11 03:00:01} {detroit y2038} {
+ clock format 3824434801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.753 {time zone boundary case 2091-11-04 01:59:59} {detroit y2038} {
+ clock format 3844994399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.754 {time zone boundary case 2091-11-04 01:00:00} {detroit y2038} {
+ clock format 3844994400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.755 {time zone boundary case 2091-11-04 01:00:01} {detroit y2038} {
+ clock format 3844994401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.756 {time zone boundary case 2092-03-09 01:59:59} {detroit y2038} {
+ clock format 3855884399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.757 {time zone boundary case 2092-03-09 03:00:00} {detroit y2038} {
+ clock format 3855884400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.758 {time zone boundary case 2092-03-09 03:00:01} {detroit y2038} {
+ clock format 3855884401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.759 {time zone boundary case 2092-11-02 01:59:59} {detroit y2038} {
+ clock format 3876443999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.760 {time zone boundary case 2092-11-02 01:00:00} {detroit y2038} {
+ clock format 3876444000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.761 {time zone boundary case 2092-11-02 01:00:01} {detroit y2038} {
+ clock format 3876444001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.762 {time zone boundary case 2093-03-08 01:59:59} {detroit y2038} {
+ clock format 3887333999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.763 {time zone boundary case 2093-03-08 03:00:00} {detroit y2038} {
+ clock format 3887334000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.764 {time zone boundary case 2093-03-08 03:00:01} {detroit y2038} {
+ clock format 3887334001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.765 {time zone boundary case 2093-11-01 01:59:59} {detroit y2038} {
+ clock format 3907893599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.766 {time zone boundary case 2093-11-01 01:00:00} {detroit y2038} {
+ clock format 3907893600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.767 {time zone boundary case 2093-11-01 01:00:01} {detroit y2038} {
+ clock format 3907893601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.768 {time zone boundary case 2094-03-14 01:59:59} {detroit y2038} {
+ clock format 3919388399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.769 {time zone boundary case 2094-03-14 03:00:00} {detroit y2038} {
+ clock format 3919388400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.770 {time zone boundary case 2094-03-14 03:00:01} {detroit y2038} {
+ clock format 3919388401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.771 {time zone boundary case 2094-11-07 01:59:59} {detroit y2038} {
+ clock format 3939947999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.772 {time zone boundary case 2094-11-07 01:00:00} {detroit y2038} {
+ clock format 3939948000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.773 {time zone boundary case 2094-11-07 01:00:01} {detroit y2038} {
+ clock format 3939948001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.774 {time zone boundary case 2095-03-13 01:59:59} {detroit y2038} {
+ clock format 3950837999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.775 {time zone boundary case 2095-03-13 03:00:00} {detroit y2038} {
+ clock format 3950838000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.776 {time zone boundary case 2095-03-13 03:00:01} {detroit y2038} {
+ clock format 3950838001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.777 {time zone boundary case 2095-11-06 01:59:59} {detroit y2038} {
+ clock format 3971397599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.778 {time zone boundary case 2095-11-06 01:00:00} {detroit y2038} {
+ clock format 3971397600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.779 {time zone boundary case 2095-11-06 01:00:01} {detroit y2038} {
+ clock format 3971397601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.780 {time zone boundary case 2096-03-11 01:59:59} {detroit y2038} {
+ clock format 3982287599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.781 {time zone boundary case 2096-03-11 03:00:00} {detroit y2038} {
+ clock format 3982287600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.782 {time zone boundary case 2096-03-11 03:00:01} {detroit y2038} {
+ clock format 3982287601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.783 {time zone boundary case 2096-11-04 01:59:59} {detroit y2038} {
+ clock format 4002847199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.784 {time zone boundary case 2096-11-04 01:00:00} {detroit y2038} {
+ clock format 4002847200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.785 {time zone boundary case 2096-11-04 01:00:01} {detroit y2038} {
+ clock format 4002847201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.786 {time zone boundary case 2097-03-10 01:59:59} {detroit y2038} {
+ clock format 4013737199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.787 {time zone boundary case 2097-03-10 03:00:00} {detroit y2038} {
+ clock format 4013737200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.788 {time zone boundary case 2097-03-10 03:00:01} {detroit y2038} {
+ clock format 4013737201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.789 {time zone boundary case 2097-11-03 01:59:59} {detroit y2038} {
+ clock format 4034296799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.790 {time zone boundary case 2097-11-03 01:00:00} {detroit y2038} {
+ clock format 4034296800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.791 {time zone boundary case 2097-11-03 01:00:01} {detroit y2038} {
+ clock format 4034296801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.792 {time zone boundary case 2098-03-09 01:59:59} {detroit y2038} {
+ clock format 4045186799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.793 {time zone boundary case 2098-03-09 03:00:00} {detroit y2038} {
+ clock format 4045186800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.794 {time zone boundary case 2098-03-09 03:00:01} {detroit y2038} {
+ clock format 4045186801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.795 {time zone boundary case 2098-11-02 01:59:59} {detroit y2038} {
+ clock format 4065746399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.796 {time zone boundary case 2098-11-02 01:00:00} {detroit y2038} {
+ clock format 4065746400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.797 {time zone boundary case 2098-11-02 01:00:01} {detroit y2038} {
+ clock format 4065746401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.798 {time zone boundary case 2099-03-08 01:59:59} {detroit y2038} {
+ clock format 4076636399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.799 {time zone boundary case 2099-03-08 03:00:00} {detroit y2038} {
+ clock format 4076636400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.800 {time zone boundary case 2099-03-08 03:00:01} {detroit y2038} {
+ clock format 4076636401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.801 {time zone boundary case 2099-11-01 01:59:59} {detroit y2038} {
+ clock format 4097195999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.802 {time zone boundary case 2099-11-01 01:00:00} {detroit y2038} {
+ clock format 4097196000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.803 {time zone boundary case 2099-11-01 01:00:01} {detroit y2038} {
+ clock format 4097196001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+# END testcases5
+
+# Test input conversions.
+
+test clock-6.0 {input of seconds} {
+ clock scan {-9223372036854775808} -format %s -gmt true
+} -9223372036854775808
+
+test clock-6.1 {input of seconds} {
+ clock scan {-2147483649} -format %s -gmt true
+} -2147483649
+
+test clock-6.2 {input of seconds} {
+ clock scan {-2147483648} -format %s -gmt true
+} -2147483648
+
+test clock-6.3 {input of seconds} {
+ clock scan {-1} -format %s -gmt true
+} -1
+
+test clock-6.4 {input of seconds} {
+ clock scan {0} -format %s -gmt true
+} 0
+
+test clock-6.5 {input of seconds} {
+ clock scan {1} -format %s -gmt true
+} 1
+
+test clock-6.6 {input of seconds} {
+ clock scan {2147483647} -format %s -gmt true
+} 2147483647
+
+test clock-6.7 {input of seconds} {
+ clock scan {2147483648} -format %s -gmt true
+} 2147483648
+
+test clock-6.8 {input of seconds} {
+ clock scan {9223372036854775807} -format %s -gmt true
+} 9223372036854775807
+
+test clock-6.9 {input of seconds - overflow} {
+ list [catch {clock scan -9223372036854775809 -format %s -gmt true} result] $result
+} {1 {integer value too large to represent}}
+
+test clock-6.10 {input of seconds - overflow} {
+ list [catch {clock scan 9223372036854775808 -format %s -gmt true} result] $result
+} {1 {integer value too large to represent}}
+
+test clock-6.11 {input of seconds - two values} {
+ clock scan {1 2} -format {%s %s} -gmt true
+} 2
+
+test clock-7.1 {Julian Day} {
+ clock scan 0 -format %J -gmt true
+} -210866803200
+
+test clock-7.2 {Julian Day} {
+ clock format [clock scan 2440588 -format %J -gmt true] \
+ -format %Y-%m-%d -gmt true
+} 1970-01-01
+
+test clock-7.3 {Julian Day} {
+ clock format [clock scan 2451545 -format %J -gmt true] \
+ -format %Y-%m-%d -gmt true
+} 2000-01-01
+
+test clock-7.3.1 {Julian Day} {
+ clock format [clock scan 2488070 -format %J -gmt true] \
+ -format %Y-%m-%d -gmt true
+} 2100-01-01
+
+test clock-7.4 {Julian Day} {
+ clock format [clock scan 5373484 -format %J -gmt true] \
+ -format %Y-%m-%d -gmt true
+} 9999-12-31
+
+test clock-7.5 {Julian Day, bad} {
+ list [catch {
+ clock scan bogus -format %J
+ } result] $result $errorCode
+} {1 {input string does not match supplied format} {CLOCK badInputString}}
+
+test clock-7.6 {Julian Day, overflow} {
+ list [catch {
+ clock scan 5373485 -format %J
+ } result] $result $errorCode
+} {1 {requested date too large to represent} {CLOCK dateTooLarge}}
+
+test clock-7.7 {Julian Day, overflow} {
+ list [catch {
+ clock scan 2147483648 -format %J
+ } result] $result $errorCode
+} {1 {requested date too large to represent} {CLOCK dateTooLarge}}
+
+test clock-7.8 {Julian Day, precedence below seconds} {
+ list [clock scan {2440588 86400} -format {%J %s} -gmt true] \
+ [clock scan {2440589 0} -format {%J %s} -gmt true] \
+ [clock scan {86400 2440588} -format {%s %J} -gmt true] \
+ [clock scan {0 2440589} -format {%s %J} -gmt true]
+} {86400 0 86400 0}
+
+test clock-7.9 {Julian Day, two values} {
+ clock scan {2440588 2440589} -format {%J %J} -gmt true
+} 86400
+
+# BEGIN testcases8
+
+# Test parsing of ccyymmdd
+
+test clock-8.1 {parse ccyymmdd} {
+ clock scan {1970 Jan 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.2 {parse ccyymmdd} {
+ clock scan {1970 Jan ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.3 {parse ccyymmdd} {
+ clock scan {1970 Jan 2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.4 {parse ccyymmdd} {
+ clock scan {1970 Jan ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.5 {parse ccyymmdd} {
+ clock scan {1970 January 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.6 {parse ccyymmdd} {
+ clock scan {1970 January ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.7 {parse ccyymmdd} {
+ clock scan {1970 January 2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.8 {parse ccyymmdd} {
+ clock scan {1970 January ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.9 {parse ccyymmdd} {
+ clock scan {1970 Jan 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.10 {parse ccyymmdd} {
+ clock scan {1970 Jan ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.11 {parse ccyymmdd} {
+ clock scan {1970 Jan 2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.12 {parse ccyymmdd} {
+ clock scan {1970 Jan ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.13 {parse ccyymmdd} {
+ clock scan {1970 01 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.14 {parse ccyymmdd} {
+ clock scan {1970 01 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.15 {parse ccyymmdd} {
+ clock scan {1970 01 2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.16 {parse ccyymmdd} {
+ clock scan {1970 01 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.17 {parse ccyymmdd} {
+ clock scan {1970 i 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.18 {parse ccyymmdd} {
+ clock scan {1970 i ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.19 {parse ccyymmdd} {
+ clock scan {1970 i 2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.20 {parse ccyymmdd} {
+ clock scan {1970 i ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.21 {parse ccyymmdd} {
+ clock scan {1970 1 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.22 {parse ccyymmdd} {
+ clock scan {1970 1 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.23 {parse ccyymmdd} {
+ clock scan {1970 1 2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.24 {parse ccyymmdd} {
+ clock scan {1970 1 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.25 {parse ccyymmdd} {
+ clock scan {1970 Jan 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.26 {parse ccyymmdd} {
+ clock scan {1970 Jan ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.27 {parse ccyymmdd} {
+ clock scan {1970 Jan 2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.28 {parse ccyymmdd} {
+ clock scan {1970 Jan ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.29 {parse ccyymmdd} {
+ clock scan {1970 January 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.30 {parse ccyymmdd} {
+ clock scan {1970 January ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.31 {parse ccyymmdd} {
+ clock scan {1970 January 2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.32 {parse ccyymmdd} {
+ clock scan {1970 January ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.33 {parse ccyymmdd} {
+ clock scan {1970 Jan 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.34 {parse ccyymmdd} {
+ clock scan {1970 Jan ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.35 {parse ccyymmdd} {
+ clock scan {1970 Jan 2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.36 {parse ccyymmdd} {
+ clock scan {1970 Jan ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.37 {parse ccyymmdd} {
+ clock scan {1970 01 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.38 {parse ccyymmdd} {
+ clock scan {1970 01 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.39 {parse ccyymmdd} {
+ clock scan {1970 01 2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.40 {parse ccyymmdd} {
+ clock scan {1970 01 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.41 {parse ccyymmdd} {
+ clock scan {1970 i 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.42 {parse ccyymmdd} {
+ clock scan {1970 i ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.43 {parse ccyymmdd} {
+ clock scan {1970 i 2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.44 {parse ccyymmdd} {
+ clock scan {1970 i ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.45 {parse ccyymmdd} {
+ clock scan {1970 1 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.46 {parse ccyymmdd} {
+ clock scan {1970 1 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.47 {parse ccyymmdd} {
+ clock scan {1970 1 2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.48 {parse ccyymmdd} {
+ clock scan {1970 1 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.49 {parse ccyymmdd} {
+ clock scan 01/02/1970 -format %x -locale en_US_roman -gmt 1
+} 86400
+test clock-8.50 {parse ccyymmdd} {
+ clock scan 01/02/1970 -format %D -locale en_US_roman -gmt 1
+} 86400
+test clock-8.51 {parse ccyymmdd} {
+ clock scan {1970 Jan 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.52 {parse ccyymmdd} {
+ clock scan {1970 Jan xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.53 {parse ccyymmdd} {
+ clock scan {1970 Jan 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.54 {parse ccyymmdd} {
+ clock scan {1970 Jan xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.55 {parse ccyymmdd} {
+ clock scan {1970 January 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.56 {parse ccyymmdd} {
+ clock scan {1970 January xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.57 {parse ccyymmdd} {
+ clock scan {1970 January 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.58 {parse ccyymmdd} {
+ clock scan {1970 January xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.59 {parse ccyymmdd} {
+ clock scan {1970 Jan 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.60 {parse ccyymmdd} {
+ clock scan {1970 Jan xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.61 {parse ccyymmdd} {
+ clock scan {1970 Jan 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.62 {parse ccyymmdd} {
+ clock scan {1970 Jan xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.63 {parse ccyymmdd} {
+ clock scan {1970 01 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.64 {parse ccyymmdd} {
+ clock scan {1970 01 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.65 {parse ccyymmdd} {
+ clock scan {1970 01 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.66 {parse ccyymmdd} {
+ clock scan {1970 01 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.67 {parse ccyymmdd} {
+ clock scan {1970 i 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.68 {parse ccyymmdd} {
+ clock scan {1970 i xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.69 {parse ccyymmdd} {
+ clock scan {1970 i 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.70 {parse ccyymmdd} {
+ clock scan {1970 i xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.71 {parse ccyymmdd} {
+ clock scan {1970 1 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.72 {parse ccyymmdd} {
+ clock scan {1970 1 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.73 {parse ccyymmdd} {
+ clock scan {1970 1 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.74 {parse ccyymmdd} {
+ clock scan {1970 1 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.75 {parse ccyymmdd} {
+ clock scan {1970 Jan 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.76 {parse ccyymmdd} {
+ clock scan {1970 Jan xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.77 {parse ccyymmdd} {
+ clock scan {1970 Jan 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.78 {parse ccyymmdd} {
+ clock scan {1970 Jan xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.79 {parse ccyymmdd} {
+ clock scan {1970 January 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.80 {parse ccyymmdd} {
+ clock scan {1970 January xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.81 {parse ccyymmdd} {
+ clock scan {1970 January 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.82 {parse ccyymmdd} {
+ clock scan {1970 January xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.83 {parse ccyymmdd} {
+ clock scan {1970 Jan 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.84 {parse ccyymmdd} {
+ clock scan {1970 Jan xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.85 {parse ccyymmdd} {
+ clock scan {1970 Jan 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.86 {parse ccyymmdd} {
+ clock scan {1970 Jan xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.87 {parse ccyymmdd} {
+ clock scan {1970 01 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.88 {parse ccyymmdd} {
+ clock scan {1970 01 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.89 {parse ccyymmdd} {
+ clock scan {1970 01 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.90 {parse ccyymmdd} {
+ clock scan {1970 01 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.91 {parse ccyymmdd} {
+ clock scan {1970 i 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.92 {parse ccyymmdd} {
+ clock scan {1970 i xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.93 {parse ccyymmdd} {
+ clock scan {1970 i 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.94 {parse ccyymmdd} {
+ clock scan {1970 i xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.95 {parse ccyymmdd} {
+ clock scan {1970 1 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.96 {parse ccyymmdd} {
+ clock scan {1970 1 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.97 {parse ccyymmdd} {
+ clock scan {1970 1 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.98 {parse ccyymmdd} {
+ clock scan {1970 1 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.99 {parse ccyymmdd} {
+ clock scan 01/31/1970 -format %x -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.100 {parse ccyymmdd} {
+ clock scan 01/31/1970 -format %D -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.101 {parse ccyymmdd} {
+ clock scan {1970 Dec 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.102 {parse ccyymmdd} {
+ clock scan {1970 Dec ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.103 {parse ccyymmdd} {
+ clock scan {1970 Dec 2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.104 {parse ccyymmdd} {
+ clock scan {1970 Dec ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.105 {parse ccyymmdd} {
+ clock scan {1970 December 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.106 {parse ccyymmdd} {
+ clock scan {1970 December ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.107 {parse ccyymmdd} {
+ clock scan {1970 December 2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.108 {parse ccyymmdd} {
+ clock scan {1970 December ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.109 {parse ccyymmdd} {
+ clock scan {1970 Dec 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.110 {parse ccyymmdd} {
+ clock scan {1970 Dec ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.111 {parse ccyymmdd} {
+ clock scan {1970 Dec 2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.112 {parse ccyymmdd} {
+ clock scan {1970 Dec ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.113 {parse ccyymmdd} {
+ clock scan {1970 12 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.114 {parse ccyymmdd} {
+ clock scan {1970 12 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.115 {parse ccyymmdd} {
+ clock scan {1970 12 2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.116 {parse ccyymmdd} {
+ clock scan {1970 12 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.117 {parse ccyymmdd} {
+ clock scan {1970 xii 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.118 {parse ccyymmdd} {
+ clock scan {1970 xii ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.119 {parse ccyymmdd} {
+ clock scan {1970 xii 2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.120 {parse ccyymmdd} {
+ clock scan {1970 xii ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.121 {parse ccyymmdd} {
+ clock scan {1970 12 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.122 {parse ccyymmdd} {
+ clock scan {1970 12 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.123 {parse ccyymmdd} {
+ clock scan {1970 12 2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.124 {parse ccyymmdd} {
+ clock scan {1970 12 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.125 {parse ccyymmdd} {
+ clock scan {1970 Dec 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.126 {parse ccyymmdd} {
+ clock scan {1970 Dec ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.127 {parse ccyymmdd} {
+ clock scan {1970 Dec 2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.128 {parse ccyymmdd} {
+ clock scan {1970 Dec ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.129 {parse ccyymmdd} {
+ clock scan {1970 December 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.130 {parse ccyymmdd} {
+ clock scan {1970 December ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.131 {parse ccyymmdd} {
+ clock scan {1970 December 2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.132 {parse ccyymmdd} {
+ clock scan {1970 December ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.133 {parse ccyymmdd} {
+ clock scan {1970 Dec 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.134 {parse ccyymmdd} {
+ clock scan {1970 Dec ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.135 {parse ccyymmdd} {
+ clock scan {1970 Dec 2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.136 {parse ccyymmdd} {
+ clock scan {1970 Dec ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.137 {parse ccyymmdd} {
+ clock scan {1970 12 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.138 {parse ccyymmdd} {
+ clock scan {1970 12 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.139 {parse ccyymmdd} {
+ clock scan {1970 12 2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.140 {parse ccyymmdd} {
+ clock scan {1970 12 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.141 {parse ccyymmdd} {
+ clock scan {1970 xii 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.142 {parse ccyymmdd} {
+ clock scan {1970 xii ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.143 {parse ccyymmdd} {
+ clock scan {1970 xii 2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.144 {parse ccyymmdd} {
+ clock scan {1970 xii ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.145 {parse ccyymmdd} {
+ clock scan {1970 12 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.146 {parse ccyymmdd} {
+ clock scan {1970 12 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.147 {parse ccyymmdd} {
+ clock scan {1970 12 2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.148 {parse ccyymmdd} {
+ clock scan {1970 12 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.149 {parse ccyymmdd} {
+ clock scan 12/02/1970 -format %x -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.150 {parse ccyymmdd} {
+ clock scan 12/02/1970 -format %D -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.151 {parse ccyymmdd} {
+ clock scan {1970 Dec 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.152 {parse ccyymmdd} {
+ clock scan {1970 Dec xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.153 {parse ccyymmdd} {
+ clock scan {1970 Dec 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.154 {parse ccyymmdd} {
+ clock scan {1970 Dec xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.155 {parse ccyymmdd} {
+ clock scan {1970 December 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.156 {parse ccyymmdd} {
+ clock scan {1970 December xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.157 {parse ccyymmdd} {
+ clock scan {1970 December 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.158 {parse ccyymmdd} {
+ clock scan {1970 December xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.159 {parse ccyymmdd} {
+ clock scan {1970 Dec 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.160 {parse ccyymmdd} {
+ clock scan {1970 Dec xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.161 {parse ccyymmdd} {
+ clock scan {1970 Dec 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.162 {parse ccyymmdd} {
+ clock scan {1970 Dec xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.163 {parse ccyymmdd} {
+ clock scan {1970 12 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.164 {parse ccyymmdd} {
+ clock scan {1970 12 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.165 {parse ccyymmdd} {
+ clock scan {1970 12 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.166 {parse ccyymmdd} {
+ clock scan {1970 12 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.167 {parse ccyymmdd} {
+ clock scan {1970 xii 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.168 {parse ccyymmdd} {
+ clock scan {1970 xii xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.169 {parse ccyymmdd} {
+ clock scan {1970 xii 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.170 {parse ccyymmdd} {
+ clock scan {1970 xii xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.171 {parse ccyymmdd} {
+ clock scan {1970 12 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.172 {parse ccyymmdd} {
+ clock scan {1970 12 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.173 {parse ccyymmdd} {
+ clock scan {1970 12 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.174 {parse ccyymmdd} {
+ clock scan {1970 12 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.175 {parse ccyymmdd} {
+ clock scan {1970 Dec 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.176 {parse ccyymmdd} {
+ clock scan {1970 Dec xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.177 {parse ccyymmdd} {
+ clock scan {1970 Dec 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.178 {parse ccyymmdd} {
+ clock scan {1970 Dec xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.179 {parse ccyymmdd} {
+ clock scan {1970 December 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.180 {parse ccyymmdd} {
+ clock scan {1970 December xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.181 {parse ccyymmdd} {
+ clock scan {1970 December 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.182 {parse ccyymmdd} {
+ clock scan {1970 December xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.183 {parse ccyymmdd} {
+ clock scan {1970 Dec 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.184 {parse ccyymmdd} {
+ clock scan {1970 Dec xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.185 {parse ccyymmdd} {
+ clock scan {1970 Dec 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.186 {parse ccyymmdd} {
+ clock scan {1970 Dec xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.187 {parse ccyymmdd} {
+ clock scan {1970 12 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.188 {parse ccyymmdd} {
+ clock scan {1970 12 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.189 {parse ccyymmdd} {
+ clock scan {1970 12 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.190 {parse ccyymmdd} {
+ clock scan {1970 12 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.191 {parse ccyymmdd} {
+ clock scan {1970 xii 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.192 {parse ccyymmdd} {
+ clock scan {1970 xii xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.193 {parse ccyymmdd} {
+ clock scan {1970 xii 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.194 {parse ccyymmdd} {
+ clock scan {1970 xii xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.195 {parse ccyymmdd} {
+ clock scan {1970 12 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.196 {parse ccyymmdd} {
+ clock scan {1970 12 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.197 {parse ccyymmdd} {
+ clock scan {1970 12 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.198 {parse ccyymmdd} {
+ clock scan {1970 12 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.199 {parse ccyymmdd} {
+ clock scan 12/31/1970 -format %x -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.200 {parse ccyymmdd} {
+ clock scan 12/31/1970 -format %D -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.201 {parse ccyymmdd} {
+ clock scan {1971 Jan 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.202 {parse ccyymmdd} {
+ clock scan {1971 Jan ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.203 {parse ccyymmdd} {
+ clock scan {1971 Jan 2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.204 {parse ccyymmdd} {
+ clock scan {1971 Jan ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.205 {parse ccyymmdd} {
+ clock scan {1971 January 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.206 {parse ccyymmdd} {
+ clock scan {1971 January ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.207 {parse ccyymmdd} {
+ clock scan {1971 January 2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.208 {parse ccyymmdd} {
+ clock scan {1971 January ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.209 {parse ccyymmdd} {
+ clock scan {1971 Jan 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.210 {parse ccyymmdd} {
+ clock scan {1971 Jan ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.211 {parse ccyymmdd} {
+ clock scan {1971 Jan 2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.212 {parse ccyymmdd} {
+ clock scan {1971 Jan ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.213 {parse ccyymmdd} {
+ clock scan {1971 01 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.214 {parse ccyymmdd} {
+ clock scan {1971 01 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.215 {parse ccyymmdd} {
+ clock scan {1971 01 2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.216 {parse ccyymmdd} {
+ clock scan {1971 01 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.217 {parse ccyymmdd} {
+ clock scan {1971 i 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.218 {parse ccyymmdd} {
+ clock scan {1971 i ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.219 {parse ccyymmdd} {
+ clock scan {1971 i 2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.220 {parse ccyymmdd} {
+ clock scan {1971 i ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.221 {parse ccyymmdd} {
+ clock scan {1971 1 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.222 {parse ccyymmdd} {
+ clock scan {1971 1 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.223 {parse ccyymmdd} {
+ clock scan {1971 1 2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.224 {parse ccyymmdd} {
+ clock scan {1971 1 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.225 {parse ccyymmdd} {
+ clock scan {1971 Jan 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.226 {parse ccyymmdd} {
+ clock scan {1971 Jan ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.227 {parse ccyymmdd} {
+ clock scan {1971 Jan 2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.228 {parse ccyymmdd} {
+ clock scan {1971 Jan ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.229 {parse ccyymmdd} {
+ clock scan {1971 January 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.230 {parse ccyymmdd} {
+ clock scan {1971 January ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.231 {parse ccyymmdd} {
+ clock scan {1971 January 2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.232 {parse ccyymmdd} {
+ clock scan {1971 January ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.233 {parse ccyymmdd} {
+ clock scan {1971 Jan 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.234 {parse ccyymmdd} {
+ clock scan {1971 Jan ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.235 {parse ccyymmdd} {
+ clock scan {1971 Jan 2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.236 {parse ccyymmdd} {
+ clock scan {1971 Jan ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.237 {parse ccyymmdd} {
+ clock scan {1971 01 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.238 {parse ccyymmdd} {
+ clock scan {1971 01 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.239 {parse ccyymmdd} {
+ clock scan {1971 01 2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.240 {parse ccyymmdd} {
+ clock scan {1971 01 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.241 {parse ccyymmdd} {
+ clock scan {1971 i 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.242 {parse ccyymmdd} {
+ clock scan {1971 i ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.243 {parse ccyymmdd} {
+ clock scan {1971 i 2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.244 {parse ccyymmdd} {
+ clock scan {1971 i ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.245 {parse ccyymmdd} {
+ clock scan {1971 1 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.246 {parse ccyymmdd} {
+ clock scan {1971 1 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.247 {parse ccyymmdd} {
+ clock scan {1971 1 2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.248 {parse ccyymmdd} {
+ clock scan {1971 1 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.249 {parse ccyymmdd} {
+ clock scan 01/02/1971 -format %x -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.250 {parse ccyymmdd} {
+ clock scan 01/02/1971 -format %D -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.251 {parse ccyymmdd} {
+ clock scan {1971 Jan 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.252 {parse ccyymmdd} {
+ clock scan {1971 Jan xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.253 {parse ccyymmdd} {
+ clock scan {1971 Jan 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.254 {parse ccyymmdd} {
+ clock scan {1971 Jan xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.255 {parse ccyymmdd} {
+ clock scan {1971 January 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.256 {parse ccyymmdd} {
+ clock scan {1971 January xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.257 {parse ccyymmdd} {
+ clock scan {1971 January 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.258 {parse ccyymmdd} {
+ clock scan {1971 January xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.259 {parse ccyymmdd} {
+ clock scan {1971 Jan 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.260 {parse ccyymmdd} {
+ clock scan {1971 Jan xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.261 {parse ccyymmdd} {
+ clock scan {1971 Jan 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.262 {parse ccyymmdd} {
+ clock scan {1971 Jan xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.263 {parse ccyymmdd} {
+ clock scan {1971 01 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.264 {parse ccyymmdd} {
+ clock scan {1971 01 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.265 {parse ccyymmdd} {
+ clock scan {1971 01 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.266 {parse ccyymmdd} {
+ clock scan {1971 01 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.267 {parse ccyymmdd} {
+ clock scan {1971 i 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.268 {parse ccyymmdd} {
+ clock scan {1971 i xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.269 {parse ccyymmdd} {
+ clock scan {1971 i 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.270 {parse ccyymmdd} {
+ clock scan {1971 i xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.271 {parse ccyymmdd} {
+ clock scan {1971 1 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.272 {parse ccyymmdd} {
+ clock scan {1971 1 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.273 {parse ccyymmdd} {
+ clock scan {1971 1 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.274 {parse ccyymmdd} {
+ clock scan {1971 1 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.275 {parse ccyymmdd} {
+ clock scan {1971 Jan 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.276 {parse ccyymmdd} {
+ clock scan {1971 Jan xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.277 {parse ccyymmdd} {
+ clock scan {1971 Jan 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.278 {parse ccyymmdd} {
+ clock scan {1971 Jan xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.279 {parse ccyymmdd} {
+ clock scan {1971 January 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.280 {parse ccyymmdd} {
+ clock scan {1971 January xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.281 {parse ccyymmdd} {
+ clock scan {1971 January 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.282 {parse ccyymmdd} {
+ clock scan {1971 January xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.283 {parse ccyymmdd} {
+ clock scan {1971 Jan 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.284 {parse ccyymmdd} {
+ clock scan {1971 Jan xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.285 {parse ccyymmdd} {
+ clock scan {1971 Jan 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.286 {parse ccyymmdd} {
+ clock scan {1971 Jan xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.287 {parse ccyymmdd} {
+ clock scan {1971 01 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.288 {parse ccyymmdd} {
+ clock scan {1971 01 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.289 {parse ccyymmdd} {
+ clock scan {1971 01 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.290 {parse ccyymmdd} {
+ clock scan {1971 01 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.291 {parse ccyymmdd} {
+ clock scan {1971 i 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.292 {parse ccyymmdd} {
+ clock scan {1971 i xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.293 {parse ccyymmdd} {
+ clock scan {1971 i 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.294 {parse ccyymmdd} {
+ clock scan {1971 i xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.295 {parse ccyymmdd} {
+ clock scan {1971 1 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.296 {parse ccyymmdd} {
+ clock scan {1971 1 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.297 {parse ccyymmdd} {
+ clock scan {1971 1 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.298 {parse ccyymmdd} {
+ clock scan {1971 1 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.299 {parse ccyymmdd} {
+ clock scan 01/31/1971 -format %x -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.300 {parse ccyymmdd} {
+ clock scan 01/31/1971 -format %D -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.301 {parse ccyymmdd} {
+ clock scan {1971 Dec 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.302 {parse ccyymmdd} {
+ clock scan {1971 Dec ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.303 {parse ccyymmdd} {
+ clock scan {1971 Dec 2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.304 {parse ccyymmdd} {
+ clock scan {1971 Dec ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.305 {parse ccyymmdd} {
+ clock scan {1971 December 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.306 {parse ccyymmdd} {
+ clock scan {1971 December ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.307 {parse ccyymmdd} {
+ clock scan {1971 December 2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.308 {parse ccyymmdd} {
+ clock scan {1971 December ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.309 {parse ccyymmdd} {
+ clock scan {1971 Dec 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.310 {parse ccyymmdd} {
+ clock scan {1971 Dec ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.311 {parse ccyymmdd} {
+ clock scan {1971 Dec 2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.312 {parse ccyymmdd} {
+ clock scan {1971 Dec ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.313 {parse ccyymmdd} {
+ clock scan {1971 12 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.314 {parse ccyymmdd} {
+ clock scan {1971 12 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.315 {parse ccyymmdd} {
+ clock scan {1971 12 2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.316 {parse ccyymmdd} {
+ clock scan {1971 12 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.317 {parse ccyymmdd} {
+ clock scan {1971 xii 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.318 {parse ccyymmdd} {
+ clock scan {1971 xii ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.319 {parse ccyymmdd} {
+ clock scan {1971 xii 2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.320 {parse ccyymmdd} {
+ clock scan {1971 xii ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.321 {parse ccyymmdd} {
+ clock scan {1971 12 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.322 {parse ccyymmdd} {
+ clock scan {1971 12 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.323 {parse ccyymmdd} {
+ clock scan {1971 12 2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.324 {parse ccyymmdd} {
+ clock scan {1971 12 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.325 {parse ccyymmdd} {
+ clock scan {1971 Dec 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.326 {parse ccyymmdd} {
+ clock scan {1971 Dec ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.327 {parse ccyymmdd} {
+ clock scan {1971 Dec 2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.328 {parse ccyymmdd} {
+ clock scan {1971 Dec ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.329 {parse ccyymmdd} {
+ clock scan {1971 December 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.330 {parse ccyymmdd} {
+ clock scan {1971 December ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.331 {parse ccyymmdd} {
+ clock scan {1971 December 2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.332 {parse ccyymmdd} {
+ clock scan {1971 December ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.333 {parse ccyymmdd} {
+ clock scan {1971 Dec 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.334 {parse ccyymmdd} {
+ clock scan {1971 Dec ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.335 {parse ccyymmdd} {
+ clock scan {1971 Dec 2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.336 {parse ccyymmdd} {
+ clock scan {1971 Dec ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.337 {parse ccyymmdd} {
+ clock scan {1971 12 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.338 {parse ccyymmdd} {
+ clock scan {1971 12 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.339 {parse ccyymmdd} {
+ clock scan {1971 12 2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.340 {parse ccyymmdd} {
+ clock scan {1971 12 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.341 {parse ccyymmdd} {
+ clock scan {1971 xii 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.342 {parse ccyymmdd} {
+ clock scan {1971 xii ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.343 {parse ccyymmdd} {
+ clock scan {1971 xii 2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.344 {parse ccyymmdd} {
+ clock scan {1971 xii ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.345 {parse ccyymmdd} {
+ clock scan {1971 12 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.346 {parse ccyymmdd} {
+ clock scan {1971 12 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.347 {parse ccyymmdd} {
+ clock scan {1971 12 2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.348 {parse ccyymmdd} {
+ clock scan {1971 12 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.349 {parse ccyymmdd} {
+ clock scan 12/02/1971 -format %x -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.350 {parse ccyymmdd} {
+ clock scan 12/02/1971 -format %D -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.351 {parse ccyymmdd} {
+ clock scan {1971 Dec 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.352 {parse ccyymmdd} {
+ clock scan {1971 Dec xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.353 {parse ccyymmdd} {
+ clock scan {1971 Dec 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.354 {parse ccyymmdd} {
+ clock scan {1971 Dec xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.355 {parse ccyymmdd} {
+ clock scan {1971 December 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.356 {parse ccyymmdd} {
+ clock scan {1971 December xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.357 {parse ccyymmdd} {
+ clock scan {1971 December 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.358 {parse ccyymmdd} {
+ clock scan {1971 December xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.359 {parse ccyymmdd} {
+ clock scan {1971 Dec 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.360 {parse ccyymmdd} {
+ clock scan {1971 Dec xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.361 {parse ccyymmdd} {
+ clock scan {1971 Dec 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.362 {parse ccyymmdd} {
+ clock scan {1971 Dec xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.363 {parse ccyymmdd} {
+ clock scan {1971 12 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.364 {parse ccyymmdd} {
+ clock scan {1971 12 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.365 {parse ccyymmdd} {
+ clock scan {1971 12 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.366 {parse ccyymmdd} {
+ clock scan {1971 12 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.367 {parse ccyymmdd} {
+ clock scan {1971 xii 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.368 {parse ccyymmdd} {
+ clock scan {1971 xii xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.369 {parse ccyymmdd} {
+ clock scan {1971 xii 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.370 {parse ccyymmdd} {
+ clock scan {1971 xii xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.371 {parse ccyymmdd} {
+ clock scan {1971 12 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.372 {parse ccyymmdd} {
+ clock scan {1971 12 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.373 {parse ccyymmdd} {
+ clock scan {1971 12 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.374 {parse ccyymmdd} {
+ clock scan {1971 12 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.375 {parse ccyymmdd} {
+ clock scan {1971 Dec 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.376 {parse ccyymmdd} {
+ clock scan {1971 Dec xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.377 {parse ccyymmdd} {
+ clock scan {1971 Dec 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.378 {parse ccyymmdd} {
+ clock scan {1971 Dec xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.379 {parse ccyymmdd} {
+ clock scan {1971 December 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.380 {parse ccyymmdd} {
+ clock scan {1971 December xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.381 {parse ccyymmdd} {
+ clock scan {1971 December 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.382 {parse ccyymmdd} {
+ clock scan {1971 December xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.383 {parse ccyymmdd} {
+ clock scan {1971 Dec 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.384 {parse ccyymmdd} {
+ clock scan {1971 Dec xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.385 {parse ccyymmdd} {
+ clock scan {1971 Dec 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.386 {parse ccyymmdd} {
+ clock scan {1971 Dec xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.387 {parse ccyymmdd} {
+ clock scan {1971 12 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.388 {parse ccyymmdd} {
+ clock scan {1971 12 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.389 {parse ccyymmdd} {
+ clock scan {1971 12 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.390 {parse ccyymmdd} {
+ clock scan {1971 12 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.391 {parse ccyymmdd} {
+ clock scan {1971 xii 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.392 {parse ccyymmdd} {
+ clock scan {1971 xii xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.393 {parse ccyymmdd} {
+ clock scan {1971 xii 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.394 {parse ccyymmdd} {
+ clock scan {1971 xii xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.395 {parse ccyymmdd} {
+ clock scan {1971 12 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.396 {parse ccyymmdd} {
+ clock scan {1971 12 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.397 {parse ccyymmdd} {
+ clock scan {1971 12 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.398 {parse ccyymmdd} {
+ clock scan {1971 12 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.399 {parse ccyymmdd} {
+ clock scan 12/31/1971 -format %x -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.400 {parse ccyymmdd} {
+ clock scan 12/31/1971 -format %D -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.401 {parse ccyymmdd} {
+ clock scan {2000 Jan 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.402 {parse ccyymmdd} {
+ clock scan {2000 Jan ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.403 {parse ccyymmdd} {
+ clock scan {2000 Jan 2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.404 {parse ccyymmdd} {
+ clock scan {2000 Jan ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.405 {parse ccyymmdd} {
+ clock scan {2000 January 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.406 {parse ccyymmdd} {
+ clock scan {2000 January ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.407 {parse ccyymmdd} {
+ clock scan {2000 January 2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.408 {parse ccyymmdd} {
+ clock scan {2000 January ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.409 {parse ccyymmdd} {
+ clock scan {2000 Jan 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.410 {parse ccyymmdd} {
+ clock scan {2000 Jan ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.411 {parse ccyymmdd} {
+ clock scan {2000 Jan 2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.412 {parse ccyymmdd} {
+ clock scan {2000 Jan ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.413 {parse ccyymmdd} {
+ clock scan {2000 01 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.414 {parse ccyymmdd} {
+ clock scan {2000 01 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.415 {parse ccyymmdd} {
+ clock scan {2000 01 2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.416 {parse ccyymmdd} {
+ clock scan {2000 01 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.417 {parse ccyymmdd} {
+ clock scan {2000 i 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.418 {parse ccyymmdd} {
+ clock scan {2000 i ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.419 {parse ccyymmdd} {
+ clock scan {2000 i 2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.420 {parse ccyymmdd} {
+ clock scan {2000 i ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.421 {parse ccyymmdd} {
+ clock scan {2000 1 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.422 {parse ccyymmdd} {
+ clock scan {2000 1 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.423 {parse ccyymmdd} {
+ clock scan {2000 1 2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.424 {parse ccyymmdd} {
+ clock scan {2000 1 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.425 {parse ccyymmdd} {
+ clock scan {2000 Jan 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.426 {parse ccyymmdd} {
+ clock scan {2000 Jan ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.427 {parse ccyymmdd} {
+ clock scan {2000 Jan 2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.428 {parse ccyymmdd} {
+ clock scan {2000 Jan ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.429 {parse ccyymmdd} {
+ clock scan {2000 January 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.430 {parse ccyymmdd} {
+ clock scan {2000 January ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.431 {parse ccyymmdd} {
+ clock scan {2000 January 2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.432 {parse ccyymmdd} {
+ clock scan {2000 January ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.433 {parse ccyymmdd} {
+ clock scan {2000 Jan 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.434 {parse ccyymmdd} {
+ clock scan {2000 Jan ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.435 {parse ccyymmdd} {
+ clock scan {2000 Jan 2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.436 {parse ccyymmdd} {
+ clock scan {2000 Jan ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.437 {parse ccyymmdd} {
+ clock scan {2000 01 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.438 {parse ccyymmdd} {
+ clock scan {2000 01 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.439 {parse ccyymmdd} {
+ clock scan {2000 01 2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.440 {parse ccyymmdd} {
+ clock scan {2000 01 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.441 {parse ccyymmdd} {
+ clock scan {2000 i 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.442 {parse ccyymmdd} {
+ clock scan {2000 i ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.443 {parse ccyymmdd} {
+ clock scan {2000 i 2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.444 {parse ccyymmdd} {
+ clock scan {2000 i ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.445 {parse ccyymmdd} {
+ clock scan {2000 1 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.446 {parse ccyymmdd} {
+ clock scan {2000 1 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.447 {parse ccyymmdd} {
+ clock scan {2000 1 2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.448 {parse ccyymmdd} {
+ clock scan {2000 1 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.449 {parse ccyymmdd} {
+ clock scan 01/02/2000 -format %x -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.450 {parse ccyymmdd} {
+ clock scan 01/02/2000 -format %D -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.451 {parse ccyymmdd} {
+ clock scan {2000 Jan 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.452 {parse ccyymmdd} {
+ clock scan {2000 Jan xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.453 {parse ccyymmdd} {
+ clock scan {2000 Jan 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.454 {parse ccyymmdd} {
+ clock scan {2000 Jan xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.455 {parse ccyymmdd} {
+ clock scan {2000 January 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.456 {parse ccyymmdd} {
+ clock scan {2000 January xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.457 {parse ccyymmdd} {
+ clock scan {2000 January 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.458 {parse ccyymmdd} {
+ clock scan {2000 January xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.459 {parse ccyymmdd} {
+ clock scan {2000 Jan 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.460 {parse ccyymmdd} {
+ clock scan {2000 Jan xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.461 {parse ccyymmdd} {
+ clock scan {2000 Jan 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.462 {parse ccyymmdd} {
+ clock scan {2000 Jan xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.463 {parse ccyymmdd} {
+ clock scan {2000 01 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.464 {parse ccyymmdd} {
+ clock scan {2000 01 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.465 {parse ccyymmdd} {
+ clock scan {2000 01 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.466 {parse ccyymmdd} {
+ clock scan {2000 01 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.467 {parse ccyymmdd} {
+ clock scan {2000 i 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.468 {parse ccyymmdd} {
+ clock scan {2000 i xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.469 {parse ccyymmdd} {
+ clock scan {2000 i 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.470 {parse ccyymmdd} {
+ clock scan {2000 i xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.471 {parse ccyymmdd} {
+ clock scan {2000 1 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.472 {parse ccyymmdd} {
+ clock scan {2000 1 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.473 {parse ccyymmdd} {
+ clock scan {2000 1 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.474 {parse ccyymmdd} {
+ clock scan {2000 1 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.475 {parse ccyymmdd} {
+ clock scan {2000 Jan 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.476 {parse ccyymmdd} {
+ clock scan {2000 Jan xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.477 {parse ccyymmdd} {
+ clock scan {2000 Jan 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.478 {parse ccyymmdd} {
+ clock scan {2000 Jan xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.479 {parse ccyymmdd} {
+ clock scan {2000 January 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.480 {parse ccyymmdd} {
+ clock scan {2000 January xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.481 {parse ccyymmdd} {
+ clock scan {2000 January 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.482 {parse ccyymmdd} {
+ clock scan {2000 January xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.483 {parse ccyymmdd} {
+ clock scan {2000 Jan 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.484 {parse ccyymmdd} {
+ clock scan {2000 Jan xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.485 {parse ccyymmdd} {
+ clock scan {2000 Jan 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.486 {parse ccyymmdd} {
+ clock scan {2000 Jan xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.487 {parse ccyymmdd} {
+ clock scan {2000 01 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.488 {parse ccyymmdd} {
+ clock scan {2000 01 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.489 {parse ccyymmdd} {
+ clock scan {2000 01 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.490 {parse ccyymmdd} {
+ clock scan {2000 01 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.491 {parse ccyymmdd} {
+ clock scan {2000 i 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.492 {parse ccyymmdd} {
+ clock scan {2000 i xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.493 {parse ccyymmdd} {
+ clock scan {2000 i 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.494 {parse ccyymmdd} {
+ clock scan {2000 i xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.495 {parse ccyymmdd} {
+ clock scan {2000 1 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.496 {parse ccyymmdd} {
+ clock scan {2000 1 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.497 {parse ccyymmdd} {
+ clock scan {2000 1 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.498 {parse ccyymmdd} {
+ clock scan {2000 1 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.499 {parse ccyymmdd} {
+ clock scan 01/31/2000 -format %x -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.500 {parse ccyymmdd} {
+ clock scan 01/31/2000 -format %D -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.501 {parse ccyymmdd} {
+ clock scan {2000 Dec 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.502 {parse ccyymmdd} {
+ clock scan {2000 Dec ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.503 {parse ccyymmdd} {
+ clock scan {2000 Dec 2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.504 {parse ccyymmdd} {
+ clock scan {2000 Dec ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.505 {parse ccyymmdd} {
+ clock scan {2000 December 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.506 {parse ccyymmdd} {
+ clock scan {2000 December ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.507 {parse ccyymmdd} {
+ clock scan {2000 December 2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.508 {parse ccyymmdd} {
+ clock scan {2000 December ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.509 {parse ccyymmdd} {
+ clock scan {2000 Dec 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.510 {parse ccyymmdd} {
+ clock scan {2000 Dec ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.511 {parse ccyymmdd} {
+ clock scan {2000 Dec 2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.512 {parse ccyymmdd} {
+ clock scan {2000 Dec ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.513 {parse ccyymmdd} {
+ clock scan {2000 12 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.514 {parse ccyymmdd} {
+ clock scan {2000 12 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.515 {parse ccyymmdd} {
+ clock scan {2000 12 2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.516 {parse ccyymmdd} {
+ clock scan {2000 12 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.517 {parse ccyymmdd} {
+ clock scan {2000 xii 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.518 {parse ccyymmdd} {
+ clock scan {2000 xii ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.519 {parse ccyymmdd} {
+ clock scan {2000 xii 2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.520 {parse ccyymmdd} {
+ clock scan {2000 xii ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.521 {parse ccyymmdd} {
+ clock scan {2000 12 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.522 {parse ccyymmdd} {
+ clock scan {2000 12 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.523 {parse ccyymmdd} {
+ clock scan {2000 12 2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.524 {parse ccyymmdd} {
+ clock scan {2000 12 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.525 {parse ccyymmdd} {
+ clock scan {2000 Dec 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.526 {parse ccyymmdd} {
+ clock scan {2000 Dec ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.527 {parse ccyymmdd} {
+ clock scan {2000 Dec 2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.528 {parse ccyymmdd} {
+ clock scan {2000 Dec ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.529 {parse ccyymmdd} {
+ clock scan {2000 December 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.530 {parse ccyymmdd} {
+ clock scan {2000 December ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.531 {parse ccyymmdd} {
+ clock scan {2000 December 2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.532 {parse ccyymmdd} {
+ clock scan {2000 December ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.533 {parse ccyymmdd} {
+ clock scan {2000 Dec 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.534 {parse ccyymmdd} {
+ clock scan {2000 Dec ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.535 {parse ccyymmdd} {
+ clock scan {2000 Dec 2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.536 {parse ccyymmdd} {
+ clock scan {2000 Dec ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.537 {parse ccyymmdd} {
+ clock scan {2000 12 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.538 {parse ccyymmdd} {
+ clock scan {2000 12 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.539 {parse ccyymmdd} {
+ clock scan {2000 12 2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.540 {parse ccyymmdd} {
+ clock scan {2000 12 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.541 {parse ccyymmdd} {
+ clock scan {2000 xii 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.542 {parse ccyymmdd} {
+ clock scan {2000 xii ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.543 {parse ccyymmdd} {
+ clock scan {2000 xii 2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.544 {parse ccyymmdd} {
+ clock scan {2000 xii ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.545 {parse ccyymmdd} {
+ clock scan {2000 12 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.546 {parse ccyymmdd} {
+ clock scan {2000 12 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.547 {parse ccyymmdd} {
+ clock scan {2000 12 2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.548 {parse ccyymmdd} {
+ clock scan {2000 12 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.549 {parse ccyymmdd} {
+ clock scan 12/02/2000 -format %x -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.550 {parse ccyymmdd} {
+ clock scan 12/02/2000 -format %D -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.551 {parse ccyymmdd} {
+ clock scan {2000 Dec 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.552 {parse ccyymmdd} {
+ clock scan {2000 Dec xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.553 {parse ccyymmdd} {
+ clock scan {2000 Dec 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.554 {parse ccyymmdd} {
+ clock scan {2000 Dec xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.555 {parse ccyymmdd} {
+ clock scan {2000 December 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.556 {parse ccyymmdd} {
+ clock scan {2000 December xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.557 {parse ccyymmdd} {
+ clock scan {2000 December 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.558 {parse ccyymmdd} {
+ clock scan {2000 December xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.559 {parse ccyymmdd} {
+ clock scan {2000 Dec 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.560 {parse ccyymmdd} {
+ clock scan {2000 Dec xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.561 {parse ccyymmdd} {
+ clock scan {2000 Dec 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.562 {parse ccyymmdd} {
+ clock scan {2000 Dec xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.563 {parse ccyymmdd} {
+ clock scan {2000 12 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.564 {parse ccyymmdd} {
+ clock scan {2000 12 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.565 {parse ccyymmdd} {
+ clock scan {2000 12 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.566 {parse ccyymmdd} {
+ clock scan {2000 12 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.567 {parse ccyymmdd} {
+ clock scan {2000 xii 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.568 {parse ccyymmdd} {
+ clock scan {2000 xii xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.569 {parse ccyymmdd} {
+ clock scan {2000 xii 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.570 {parse ccyymmdd} {
+ clock scan {2000 xii xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.571 {parse ccyymmdd} {
+ clock scan {2000 12 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.572 {parse ccyymmdd} {
+ clock scan {2000 12 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.573 {parse ccyymmdd} {
+ clock scan {2000 12 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.574 {parse ccyymmdd} {
+ clock scan {2000 12 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.575 {parse ccyymmdd} {
+ clock scan {2000 Dec 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.576 {parse ccyymmdd} {
+ clock scan {2000 Dec xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.577 {parse ccyymmdd} {
+ clock scan {2000 Dec 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.578 {parse ccyymmdd} {
+ clock scan {2000 Dec xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.579 {parse ccyymmdd} {
+ clock scan {2000 December 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.580 {parse ccyymmdd} {
+ clock scan {2000 December xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.581 {parse ccyymmdd} {
+ clock scan {2000 December 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.582 {parse ccyymmdd} {
+ clock scan {2000 December xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.583 {parse ccyymmdd} {
+ clock scan {2000 Dec 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.584 {parse ccyymmdd} {
+ clock scan {2000 Dec xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.585 {parse ccyymmdd} {
+ clock scan {2000 Dec 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.586 {parse ccyymmdd} {
+ clock scan {2000 Dec xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.587 {parse ccyymmdd} {
+ clock scan {2000 12 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.588 {parse ccyymmdd} {
+ clock scan {2000 12 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.589 {parse ccyymmdd} {
+ clock scan {2000 12 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.590 {parse ccyymmdd} {
+ clock scan {2000 12 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.591 {parse ccyymmdd} {
+ clock scan {2000 xii 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.592 {parse ccyymmdd} {
+ clock scan {2000 xii xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.593 {parse ccyymmdd} {
+ clock scan {2000 xii 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.594 {parse ccyymmdd} {
+ clock scan {2000 xii xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.595 {parse ccyymmdd} {
+ clock scan {2000 12 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.596 {parse ccyymmdd} {
+ clock scan {2000 12 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.597 {parse ccyymmdd} {
+ clock scan {2000 12 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.598 {parse ccyymmdd} {
+ clock scan {2000 12 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.599 {parse ccyymmdd} {
+ clock scan 12/31/2000 -format %x -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.600 {parse ccyymmdd} {
+ clock scan 12/31/2000 -format %D -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.601 {parse ccyymmdd} {
+ clock scan {2001 Jan 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.602 {parse ccyymmdd} {
+ clock scan {2001 Jan ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.603 {parse ccyymmdd} {
+ clock scan {2001 Jan 2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.604 {parse ccyymmdd} {
+ clock scan {2001 Jan ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.605 {parse ccyymmdd} {
+ clock scan {2001 January 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.606 {parse ccyymmdd} {
+ clock scan {2001 January ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.607 {parse ccyymmdd} {
+ clock scan {2001 January 2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.608 {parse ccyymmdd} {
+ clock scan {2001 January ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.609 {parse ccyymmdd} {
+ clock scan {2001 Jan 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.610 {parse ccyymmdd} {
+ clock scan {2001 Jan ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.611 {parse ccyymmdd} {
+ clock scan {2001 Jan 2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.612 {parse ccyymmdd} {
+ clock scan {2001 Jan ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.613 {parse ccyymmdd} {
+ clock scan {2001 01 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.614 {parse ccyymmdd} {
+ clock scan {2001 01 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.615 {parse ccyymmdd} {
+ clock scan {2001 01 2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.616 {parse ccyymmdd} {
+ clock scan {2001 01 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.617 {parse ccyymmdd} {
+ clock scan {2001 i 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.618 {parse ccyymmdd} {
+ clock scan {2001 i ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.619 {parse ccyymmdd} {
+ clock scan {2001 i 2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.620 {parse ccyymmdd} {
+ clock scan {2001 i ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.621 {parse ccyymmdd} {
+ clock scan {2001 1 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.622 {parse ccyymmdd} {
+ clock scan {2001 1 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.623 {parse ccyymmdd} {
+ clock scan {2001 1 2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.624 {parse ccyymmdd} {
+ clock scan {2001 1 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.625 {parse ccyymmdd} {
+ clock scan {2001 Jan 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.626 {parse ccyymmdd} {
+ clock scan {2001 Jan ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.627 {parse ccyymmdd} {
+ clock scan {2001 Jan 2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.628 {parse ccyymmdd} {
+ clock scan {2001 Jan ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.629 {parse ccyymmdd} {
+ clock scan {2001 January 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.630 {parse ccyymmdd} {
+ clock scan {2001 January ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.631 {parse ccyymmdd} {
+ clock scan {2001 January 2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.632 {parse ccyymmdd} {
+ clock scan {2001 January ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.633 {parse ccyymmdd} {
+ clock scan {2001 Jan 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.634 {parse ccyymmdd} {
+ clock scan {2001 Jan ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.635 {parse ccyymmdd} {
+ clock scan {2001 Jan 2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.636 {parse ccyymmdd} {
+ clock scan {2001 Jan ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.637 {parse ccyymmdd} {
+ clock scan {2001 01 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.638 {parse ccyymmdd} {
+ clock scan {2001 01 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.639 {parse ccyymmdd} {
+ clock scan {2001 01 2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.640 {parse ccyymmdd} {
+ clock scan {2001 01 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.641 {parse ccyymmdd} {
+ clock scan {2001 i 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.642 {parse ccyymmdd} {
+ clock scan {2001 i ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.643 {parse ccyymmdd} {
+ clock scan {2001 i 2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.644 {parse ccyymmdd} {
+ clock scan {2001 i ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.645 {parse ccyymmdd} {
+ clock scan {2001 1 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.646 {parse ccyymmdd} {
+ clock scan {2001 1 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.647 {parse ccyymmdd} {
+ clock scan {2001 1 2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.648 {parse ccyymmdd} {
+ clock scan {2001 1 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.649 {parse ccyymmdd} {
+ clock scan 01/02/2001 -format %x -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.650 {parse ccyymmdd} {
+ clock scan 01/02/2001 -format %D -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.651 {parse ccyymmdd} {
+ clock scan {2001 Jan 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.652 {parse ccyymmdd} {
+ clock scan {2001 Jan xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.653 {parse ccyymmdd} {
+ clock scan {2001 Jan 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.654 {parse ccyymmdd} {
+ clock scan {2001 Jan xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.655 {parse ccyymmdd} {
+ clock scan {2001 January 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.656 {parse ccyymmdd} {
+ clock scan {2001 January xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.657 {parse ccyymmdd} {
+ clock scan {2001 January 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.658 {parse ccyymmdd} {
+ clock scan {2001 January xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.659 {parse ccyymmdd} {
+ clock scan {2001 Jan 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.660 {parse ccyymmdd} {
+ clock scan {2001 Jan xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.661 {parse ccyymmdd} {
+ clock scan {2001 Jan 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.662 {parse ccyymmdd} {
+ clock scan {2001 Jan xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.663 {parse ccyymmdd} {
+ clock scan {2001 01 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.664 {parse ccyymmdd} {
+ clock scan {2001 01 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.665 {parse ccyymmdd} {
+ clock scan {2001 01 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.666 {parse ccyymmdd} {
+ clock scan {2001 01 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.667 {parse ccyymmdd} {
+ clock scan {2001 i 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.668 {parse ccyymmdd} {
+ clock scan {2001 i xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.669 {parse ccyymmdd} {
+ clock scan {2001 i 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.670 {parse ccyymmdd} {
+ clock scan {2001 i xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.671 {parse ccyymmdd} {
+ clock scan {2001 1 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.672 {parse ccyymmdd} {
+ clock scan {2001 1 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.673 {parse ccyymmdd} {
+ clock scan {2001 1 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.674 {parse ccyymmdd} {
+ clock scan {2001 1 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.675 {parse ccyymmdd} {
+ clock scan {2001 Jan 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.676 {parse ccyymmdd} {
+ clock scan {2001 Jan xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.677 {parse ccyymmdd} {
+ clock scan {2001 Jan 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.678 {parse ccyymmdd} {
+ clock scan {2001 Jan xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.679 {parse ccyymmdd} {
+ clock scan {2001 January 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.680 {parse ccyymmdd} {
+ clock scan {2001 January xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.681 {parse ccyymmdd} {
+ clock scan {2001 January 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.682 {parse ccyymmdd} {
+ clock scan {2001 January xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.683 {parse ccyymmdd} {
+ clock scan {2001 Jan 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.684 {parse ccyymmdd} {
+ clock scan {2001 Jan xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.685 {parse ccyymmdd} {
+ clock scan {2001 Jan 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.686 {parse ccyymmdd} {
+ clock scan {2001 Jan xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.687 {parse ccyymmdd} {
+ clock scan {2001 01 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.688 {parse ccyymmdd} {
+ clock scan {2001 01 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.689 {parse ccyymmdd} {
+ clock scan {2001 01 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.690 {parse ccyymmdd} {
+ clock scan {2001 01 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.691 {parse ccyymmdd} {
+ clock scan {2001 i 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.692 {parse ccyymmdd} {
+ clock scan {2001 i xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.693 {parse ccyymmdd} {
+ clock scan {2001 i 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.694 {parse ccyymmdd} {
+ clock scan {2001 i xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.695 {parse ccyymmdd} {
+ clock scan {2001 1 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.696 {parse ccyymmdd} {
+ clock scan {2001 1 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.697 {parse ccyymmdd} {
+ clock scan {2001 1 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.698 {parse ccyymmdd} {
+ clock scan {2001 1 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.699 {parse ccyymmdd} {
+ clock scan 01/31/2001 -format %x -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.700 {parse ccyymmdd} {
+ clock scan 01/31/2001 -format %D -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.701 {parse ccyymmdd} {
+ clock scan {2001 Dec 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.702 {parse ccyymmdd} {
+ clock scan {2001 Dec ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.703 {parse ccyymmdd} {
+ clock scan {2001 Dec 2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.704 {parse ccyymmdd} {
+ clock scan {2001 Dec ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.705 {parse ccyymmdd} {
+ clock scan {2001 December 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.706 {parse ccyymmdd} {
+ clock scan {2001 December ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.707 {parse ccyymmdd} {
+ clock scan {2001 December 2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.708 {parse ccyymmdd} {
+ clock scan {2001 December ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.709 {parse ccyymmdd} {
+ clock scan {2001 Dec 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.710 {parse ccyymmdd} {
+ clock scan {2001 Dec ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.711 {parse ccyymmdd} {
+ clock scan {2001 Dec 2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.712 {parse ccyymmdd} {
+ clock scan {2001 Dec ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.713 {parse ccyymmdd} {
+ clock scan {2001 12 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.714 {parse ccyymmdd} {
+ clock scan {2001 12 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.715 {parse ccyymmdd} {
+ clock scan {2001 12 2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.716 {parse ccyymmdd} {
+ clock scan {2001 12 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.717 {parse ccyymmdd} {
+ clock scan {2001 xii 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.718 {parse ccyymmdd} {
+ clock scan {2001 xii ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.719 {parse ccyymmdd} {
+ clock scan {2001 xii 2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.720 {parse ccyymmdd} {
+ clock scan {2001 xii ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.721 {parse ccyymmdd} {
+ clock scan {2001 12 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.722 {parse ccyymmdd} {
+ clock scan {2001 12 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.723 {parse ccyymmdd} {
+ clock scan {2001 12 2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.724 {parse ccyymmdd} {
+ clock scan {2001 12 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.725 {parse ccyymmdd} {
+ clock scan {2001 Dec 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.726 {parse ccyymmdd} {
+ clock scan {2001 Dec ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.727 {parse ccyymmdd} {
+ clock scan {2001 Dec 2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.728 {parse ccyymmdd} {
+ clock scan {2001 Dec ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.729 {parse ccyymmdd} {
+ clock scan {2001 December 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.730 {parse ccyymmdd} {
+ clock scan {2001 December ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.731 {parse ccyymmdd} {
+ clock scan {2001 December 2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.732 {parse ccyymmdd} {
+ clock scan {2001 December ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.733 {parse ccyymmdd} {
+ clock scan {2001 Dec 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.734 {parse ccyymmdd} {
+ clock scan {2001 Dec ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.735 {parse ccyymmdd} {
+ clock scan {2001 Dec 2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.736 {parse ccyymmdd} {
+ clock scan {2001 Dec ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.737 {parse ccyymmdd} {
+ clock scan {2001 12 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.738 {parse ccyymmdd} {
+ clock scan {2001 12 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.739 {parse ccyymmdd} {
+ clock scan {2001 12 2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.740 {parse ccyymmdd} {
+ clock scan {2001 12 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.741 {parse ccyymmdd} {
+ clock scan {2001 xii 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.742 {parse ccyymmdd} {
+ clock scan {2001 xii ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.743 {parse ccyymmdd} {
+ clock scan {2001 xii 2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.744 {parse ccyymmdd} {
+ clock scan {2001 xii ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.745 {parse ccyymmdd} {
+ clock scan {2001 12 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.746 {parse ccyymmdd} {
+ clock scan {2001 12 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.747 {parse ccyymmdd} {
+ clock scan {2001 12 2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.748 {parse ccyymmdd} {
+ clock scan {2001 12 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.749 {parse ccyymmdd} {
+ clock scan 12/02/2001 -format %x -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.750 {parse ccyymmdd} {
+ clock scan 12/02/2001 -format %D -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.751 {parse ccyymmdd} {
+ clock scan {2001 Dec 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.752 {parse ccyymmdd} {
+ clock scan {2001 Dec xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.753 {parse ccyymmdd} {
+ clock scan {2001 Dec 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.754 {parse ccyymmdd} {
+ clock scan {2001 Dec xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.755 {parse ccyymmdd} {
+ clock scan {2001 December 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.756 {parse ccyymmdd} {
+ clock scan {2001 December xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.757 {parse ccyymmdd} {
+ clock scan {2001 December 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.758 {parse ccyymmdd} {
+ clock scan {2001 December xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.759 {parse ccyymmdd} {
+ clock scan {2001 Dec 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.760 {parse ccyymmdd} {
+ clock scan {2001 Dec xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.761 {parse ccyymmdd} {
+ clock scan {2001 Dec 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.762 {parse ccyymmdd} {
+ clock scan {2001 Dec xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.763 {parse ccyymmdd} {
+ clock scan {2001 12 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.764 {parse ccyymmdd} {
+ clock scan {2001 12 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.765 {parse ccyymmdd} {
+ clock scan {2001 12 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.766 {parse ccyymmdd} {
+ clock scan {2001 12 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.767 {parse ccyymmdd} {
+ clock scan {2001 xii 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.768 {parse ccyymmdd} {
+ clock scan {2001 xii xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.769 {parse ccyymmdd} {
+ clock scan {2001 xii 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.770 {parse ccyymmdd} {
+ clock scan {2001 xii xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.771 {parse ccyymmdd} {
+ clock scan {2001 12 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.772 {parse ccyymmdd} {
+ clock scan {2001 12 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.773 {parse ccyymmdd} {
+ clock scan {2001 12 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.774 {parse ccyymmdd} {
+ clock scan {2001 12 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.775 {parse ccyymmdd} {
+ clock scan {2001 Dec 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.776 {parse ccyymmdd} {
+ clock scan {2001 Dec xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.777 {parse ccyymmdd} {
+ clock scan {2001 Dec 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.778 {parse ccyymmdd} {
+ clock scan {2001 Dec xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.779 {parse ccyymmdd} {
+ clock scan {2001 December 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.780 {parse ccyymmdd} {
+ clock scan {2001 December xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.781 {parse ccyymmdd} {
+ clock scan {2001 December 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.782 {parse ccyymmdd} {
+ clock scan {2001 December xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.783 {parse ccyymmdd} {
+ clock scan {2001 Dec 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.784 {parse ccyymmdd} {
+ clock scan {2001 Dec xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.785 {parse ccyymmdd} {
+ clock scan {2001 Dec 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.786 {parse ccyymmdd} {
+ clock scan {2001 Dec xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.787 {parse ccyymmdd} {
+ clock scan {2001 12 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.788 {parse ccyymmdd} {
+ clock scan {2001 12 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.789 {parse ccyymmdd} {
+ clock scan {2001 12 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.790 {parse ccyymmdd} {
+ clock scan {2001 12 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.791 {parse ccyymmdd} {
+ clock scan {2001 xii 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.792 {parse ccyymmdd} {
+ clock scan {2001 xii xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.793 {parse ccyymmdd} {
+ clock scan {2001 xii 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.794 {parse ccyymmdd} {
+ clock scan {2001 xii xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.795 {parse ccyymmdd} {
+ clock scan {2001 12 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.796 {parse ccyymmdd} {
+ clock scan {2001 12 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.797 {parse ccyymmdd} {
+ clock scan {2001 12 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.798 {parse ccyymmdd} {
+ clock scan {2001 12 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.799 {parse ccyymmdd} {
+ clock scan 12/31/2001 -format %x -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.800 {parse ccyymmdd} {
+ clock scan 12/31/2001 -format %D -locale en_US_roman -gmt 1
+} 1009756800
+# END testcases8
+
+test clock-9.1 {seconds take precedence over ccyymmdd} {
+ clock scan {0 20000101} -format {%s %Y%m%d} -gmt true
+} 0
+
+test clock-9.2 {Julian day takes precedence over ccyymmdd} {
+ clock scan {2440588 20000101} -format {%J %Y%m%d} -gmt true
+} 0
+
+# Test parsing of ccyyddd
+
+test clock-10.1 {parse ccyyddd} {
+ clock scan {1970 001} -format {%Y %j} -locale en_US_roman -gmt 1
+} 0
+test clock-10.2 {parse ccyyddd} {
+ clock scan {1970 365} -format {%Y %j} -locale en_US_roman -gmt 1
+} 31449600
+test clock-10.3 {parse ccyyddd} {
+ clock scan {1971 001} -format {%Y %j} -locale en_US_roman -gmt 1
+} 31536000
+test clock-10.4 {parse ccyyddd} {
+ clock scan {1971 365} -format {%Y %j} -locale en_US_roman -gmt 1
+} 62985600
+test clock-10.5 {parse ccyyddd} {
+ clock scan {2000 001} -format {%Y %j} -locale en_US_roman -gmt 1
+} 946684800
+test clock-10.6 {parse ccyyddd} {
+ clock scan {2000 365} -format {%Y %j} -locale en_US_roman -gmt 1
+} 978134400
+test clock-10.7 {parse ccyyddd} {
+ clock scan {2001 001} -format {%Y %j} -locale en_US_roman -gmt 1
+} 978307200
+test clock-10.8 {parse ccyyddd} {
+ clock scan {2001 365} -format {%Y %j} -locale en_US_roman -gmt 1
+} 1009756800
+
+
+test clock-10.9 {seconds take precedence over ccyyddd} {
+ list [clock scan {0 2000001} -format {%s %Y%j} -gmt true] \
+ [clock scan {2000001 0} -format {%Y%j %s} -gmt true]
+} {0 0}
+test clock-10.10 {julian day takes precedence over ccyyddd} {
+ list [clock scan {2440588 2000001} -format {%J %Y%j} -gmt true] \
+ [clock scan {2000001 2440588} -format {%Y%j %J} -gmt true]
+} {0 0}
+
+# BEGIN testcases11
+
+# Test precedence among yyyymmdd and yyyyddd
+
+test clock-11.1 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 19700101002 -format %Y%m%d%j -gmt 1
+} 86400
+test clock-11.2 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01197001002 -format %m%Y%d%j -gmt 1
+} 86400
+test clock-11.3 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01197001002 -format %d%Y%m%j -gmt 1
+} 86400
+test clock-11.4 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 00219700101 -format %j%Y%m%d -gmt 1
+} 0
+test clock-11.5 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 19700100201 -format %Y%m%j%d -gmt 1
+} 0
+test clock-11.6 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01197000201 -format %m%Y%j%d -gmt 1
+} 0
+test clock-11.7 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01197000201 -format %d%Y%j%m -gmt 1
+} 0
+test clock-11.8 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 00219700101 -format %j%Y%d%m -gmt 1
+} 0
+test clock-11.9 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 19700101002 -format %Y%d%m%j -gmt 1
+} 86400
+test clock-11.10 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01011970002 -format %m%d%Y%j -gmt 1
+} 86400
+test clock-11.11 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01011970002 -format %d%m%Y%j -gmt 1
+} 86400
+test clock-11.12 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 00201197001 -format %j%m%Y%d -gmt 1
+} 0
+test clock-11.13 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 19700100201 -format %Y%d%j%m -gmt 1
+} 0
+test clock-11.14 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01010021970 -format %m%d%j%Y -gmt 1
+} 86400
+test clock-11.15 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01010021970 -format %d%m%j%Y -gmt 1
+} 86400
+test clock-11.16 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 00201011970 -format %j%m%d%Y -gmt 1
+} 0
+test clock-11.17 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 19700020101 -format %Y%j%m%d -gmt 1
+} 0
+test clock-11.18 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01002197001 -format %m%j%Y%d -gmt 1
+} 0
+test clock-11.19 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01002197001 -format %d%j%Y%m -gmt 1
+} 0
+test clock-11.20 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 00201197001 -format %j%d%Y%m -gmt 1
+} 0
+test clock-11.21 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 19700020101 -format %Y%j%d%m -gmt 1
+} 0
+test clock-11.22 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01002011970 -format %m%j%d%Y -gmt 1
+} 0
+test clock-11.23 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01002011970 -format %d%j%m%Y -gmt 1
+} 0
+test clock-11.24 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 00201011970 -format %j%d%m%Y -gmt 1
+} 0
+# END testcases11
+
+# BEGIN testcases12
+
+# Test parsing of ccyyWwwd
+
+test clock-12.1 {parse ccyyWwwd} {
+ clock scan {1970 W01 Fri} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.2 {parse ccyyWwwd} {
+ clock scan {1970 W01 Friday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.3 {parse ccyyWwwd} {
+ clock scan {1970 W01 5} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.4 {parse ccyyWwwd} {
+ clock scan {1970 W01 5} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.5 {parse ccyyWwwd} {
+ clock scan {1970 W01 v} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.6 {parse ccyyWwwd} {
+ clock scan {1970 W01 v} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.7 {parse ccyyWwwd} {
+ clock scan {1970 W05 Sat} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.8 {parse ccyyWwwd} {
+ clock scan {1970 W05 Saturday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.9 {parse ccyyWwwd} {
+ clock scan {1970 W05 6} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.10 {parse ccyyWwwd} {
+ clock scan {1970 W05 6} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.11 {parse ccyyWwwd} {
+ clock scan {1970 W05 vi} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.12 {parse ccyyWwwd} {
+ clock scan {1970 W05 vi} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.13 {parse ccyyWwwd} {
+ clock scan {1970 W49 Wed} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.14 {parse ccyyWwwd} {
+ clock scan {1970 W49 Wednesday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.15 {parse ccyyWwwd} {
+ clock scan {1970 W49 3} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.16 {parse ccyyWwwd} {
+ clock scan {1970 W49 3} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.17 {parse ccyyWwwd} {
+ clock scan {1970 W49 iii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.18 {parse ccyyWwwd} {
+ clock scan {1970 W49 iii} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.19 {parse ccyyWwwd} {
+ clock scan {1970 W53 Thu} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.20 {parse ccyyWwwd} {
+ clock scan {1970 W53 Thursday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.21 {parse ccyyWwwd} {
+ clock scan {1970 W53 4} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.22 {parse ccyyWwwd} {
+ clock scan {1970 W53 4} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.23 {parse ccyyWwwd} {
+ clock scan {1970 W53 iv} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.24 {parse ccyyWwwd} {
+ clock scan {1970 W53 iv} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.25 {parse ccyyWwwd} {
+ clock scan {1970 W53 Sat} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.26 {parse ccyyWwwd} {
+ clock scan {1970 W53 Saturday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.27 {parse ccyyWwwd} {
+ clock scan {1970 W53 6} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.28 {parse ccyyWwwd} {
+ clock scan {1970 W53 6} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.29 {parse ccyyWwwd} {
+ clock scan {1970 W53 vi} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.30 {parse ccyyWwwd} {
+ clock scan {1970 W53 vi} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.31 {parse ccyyWwwd} {
+ clock scan {1971 W04 Sun} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.32 {parse ccyyWwwd} {
+ clock scan {1971 W04 Sunday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.33 {parse ccyyWwwd} {
+ clock scan {1971 W04 7} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.34 {parse ccyyWwwd} {
+ clock scan {1971 W04 0} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.35 {parse ccyyWwwd} {
+ clock scan {1971 W04 vii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.36 {parse ccyyWwwd} {
+ clock scan {1971 W04 ?} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.37 {parse ccyyWwwd} {
+ clock scan {1971 W48 Thu} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.38 {parse ccyyWwwd} {
+ clock scan {1971 W48 Thursday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.39 {parse ccyyWwwd} {
+ clock scan {1971 W48 4} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.40 {parse ccyyWwwd} {
+ clock scan {1971 W48 4} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.41 {parse ccyyWwwd} {
+ clock scan {1971 W48 iv} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.42 {parse ccyyWwwd} {
+ clock scan {1971 W48 iv} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.43 {parse ccyyWwwd} {
+ clock scan {1971 W52 Fri} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.44 {parse ccyyWwwd} {
+ clock scan {1971 W52 Friday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.45 {parse ccyyWwwd} {
+ clock scan {1971 W52 5} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.46 {parse ccyyWwwd} {
+ clock scan {1971 W52 5} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.47 {parse ccyyWwwd} {
+ clock scan {1971 W52 v} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.48 {parse ccyyWwwd} {
+ clock scan {1971 W52 v} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.49 {parse ccyyWwwd} {
+ clock scan {1999 W52 Sun} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.50 {parse ccyyWwwd} {
+ clock scan {1999 W52 Sunday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.51 {parse ccyyWwwd} {
+ clock scan {1999 W52 7} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.52 {parse ccyyWwwd} {
+ clock scan {1999 W52 0} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.53 {parse ccyyWwwd} {
+ clock scan {1999 W52 vii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.54 {parse ccyyWwwd} {
+ clock scan {1999 W52 ?} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.55 {parse ccyyWwwd} {
+ clock scan {2000 W05 Mon} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.56 {parse ccyyWwwd} {
+ clock scan {2000 W05 Monday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.57 {parse ccyyWwwd} {
+ clock scan {2000 W05 1} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.58 {parse ccyyWwwd} {
+ clock scan {2000 W05 1} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.59 {parse ccyyWwwd} {
+ clock scan {2000 W05 i} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.60 {parse ccyyWwwd} {
+ clock scan {2000 W05 i} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.61 {parse ccyyWwwd} {
+ clock scan {2000 W48 Sat} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.62 {parse ccyyWwwd} {
+ clock scan {2000 W48 Saturday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.63 {parse ccyyWwwd} {
+ clock scan {2000 W48 6} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.64 {parse ccyyWwwd} {
+ clock scan {2000 W48 6} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.65 {parse ccyyWwwd} {
+ clock scan {2000 W48 vi} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.66 {parse ccyyWwwd} {
+ clock scan {2000 W48 vi} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.67 {parse ccyyWwwd} {
+ clock scan {2000 W52 Sun} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.68 {parse ccyyWwwd} {
+ clock scan {2000 W52 Sunday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.69 {parse ccyyWwwd} {
+ clock scan {2000 W52 7} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.70 {parse ccyyWwwd} {
+ clock scan {2000 W52 0} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.71 {parse ccyyWwwd} {
+ clock scan {2000 W52 vii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.72 {parse ccyyWwwd} {
+ clock scan {2000 W52 ?} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.73 {parse ccyyWwwd} {
+ clock scan {2001 W01 Tue} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.74 {parse ccyyWwwd} {
+ clock scan {2001 W01 Tuesday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.75 {parse ccyyWwwd} {
+ clock scan {2001 W01 2} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.76 {parse ccyyWwwd} {
+ clock scan {2001 W01 2} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.77 {parse ccyyWwwd} {
+ clock scan {2001 W01 ii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.78 {parse ccyyWwwd} {
+ clock scan {2001 W01 ii} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.79 {parse ccyyWwwd} {
+ clock scan {2001 W05 Wed} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.80 {parse ccyyWwwd} {
+ clock scan {2001 W05 Wednesday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.81 {parse ccyyWwwd} {
+ clock scan {2001 W05 3} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.82 {parse ccyyWwwd} {
+ clock scan {2001 W05 3} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.83 {parse ccyyWwwd} {
+ clock scan {2001 W05 iii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.84 {parse ccyyWwwd} {
+ clock scan {2001 W05 iii} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.85 {parse ccyyWwwd} {
+ clock scan {2001 W48 Sun} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.86 {parse ccyyWwwd} {
+ clock scan {2001 W48 Sunday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.87 {parse ccyyWwwd} {
+ clock scan {2001 W48 7} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.88 {parse ccyyWwwd} {
+ clock scan {2001 W48 0} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.89 {parse ccyyWwwd} {
+ clock scan {2001 W48 vii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.90 {parse ccyyWwwd} {
+ clock scan {2001 W48 ?} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.91 {parse ccyyWwwd} {
+ clock scan {2002 W01 Mon} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-12.92 {parse ccyyWwwd} {
+ clock scan {2002 W01 Monday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-12.93 {parse ccyyWwwd} {
+ clock scan {2002 W01 1} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-12.94 {parse ccyyWwwd} {
+ clock scan {2002 W01 1} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-12.95 {parse ccyyWwwd} {
+ clock scan {2002 W01 i} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-12.96 {parse ccyyWwwd} {
+ clock scan {2002 W01 i} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 1009756800
+# END testcases12
+
+test clock-13.1 {test that %s takes precedence over ccyyWwwd} {
+ list [clock scan {0 2000W011} -format {%s %GW%V%u} -gmt true] \
+ [clock scan {2000W011 0} -format {%GW%V%u %s} -gmt true]
+} {0 0}
+test clock-13.2 {test that %J takes precedence over ccyyWwwd} {
+ list [clock scan {2440588 2000W011} -format {%J %GW%V%u} -gmt true] \
+ [clock scan {2000W011 2440588} -format {%GW%V%u %J} -gmt true]
+} {0 0}
+test clock-13.3 {invalid weekday} {
+ catch {clock scan 2000W018 -format %GW%V%u -gmt true} result
+ list $result $::errorCode
+} {{day of week is greater than 7} {CLOCK badDayOfWeek}}
+test clock-13.4 {invalid weekday} {
+ catch {
+ clock scan {2000 W01 viii} \
+ -format {%G W%V %Ou} -gmt true -locale en_US_roman
+ } result
+ list $result $::errorCode
+} {{day of week is greater than 7} {CLOCK badDayOfWeek}}
+
+# BEGIN testcases14
+
+# Test parsing of yymmdd
+
+test clock-14.1 {parse yymmdd} {
+ clock scan {38 Jan 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.2 {parse yymmdd} {
+ clock scan {38 Jan ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.3 {parse yymmdd} {
+ clock scan {38 Jan 2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.4 {parse yymmdd} {
+ clock scan {38 Jan ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.5 {parse yymmdd} {
+ clock scan {38 January 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.6 {parse yymmdd} {
+ clock scan {38 January ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.7 {parse yymmdd} {
+ clock scan {38 January 2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.8 {parse yymmdd} {
+ clock scan {38 January ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.9 {parse yymmdd} {
+ clock scan {38 Jan 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.10 {parse yymmdd} {
+ clock scan {38 Jan ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.11 {parse yymmdd} {
+ clock scan {38 Jan 2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.12 {parse yymmdd} {
+ clock scan {38 Jan ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.13 {parse yymmdd} {
+ clock scan {38 01 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.14 {parse yymmdd} {
+ clock scan {38 01 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.15 {parse yymmdd} {
+ clock scan {38 01 2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.16 {parse yymmdd} {
+ clock scan {38 01 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.17 {parse yymmdd} {
+ clock scan {38 i 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.18 {parse yymmdd} {
+ clock scan {38 i ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.19 {parse yymmdd} {
+ clock scan {38 i 2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.20 {parse yymmdd} {
+ clock scan {38 i ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.21 {parse yymmdd} {
+ clock scan {38 1 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.22 {parse yymmdd} {
+ clock scan {38 1 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.23 {parse yymmdd} {
+ clock scan {38 1 2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.24 {parse yymmdd} {
+ clock scan {38 1 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.25 {parse yymmdd} {
+ clock scan {xxxviii Jan 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.26 {parse yymmdd} {
+ clock scan {xxxviii Jan ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.27 {parse yymmdd} {
+ clock scan {xxxviii Jan 2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.28 {parse yymmdd} {
+ clock scan {xxxviii Jan ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.29 {parse yymmdd} {
+ clock scan {xxxviii January 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.30 {parse yymmdd} {
+ clock scan {xxxviii January ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.31 {parse yymmdd} {
+ clock scan {xxxviii January 2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.32 {parse yymmdd} {
+ clock scan {xxxviii January ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.33 {parse yymmdd} {
+ clock scan {xxxviii Jan 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.34 {parse yymmdd} {
+ clock scan {xxxviii Jan ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.35 {parse yymmdd} {
+ clock scan {xxxviii Jan 2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.36 {parse yymmdd} {
+ clock scan {xxxviii Jan ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.37 {parse yymmdd} {
+ clock scan {xxxviii 01 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.38 {parse yymmdd} {
+ clock scan {xxxviii 01 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.39 {parse yymmdd} {
+ clock scan {xxxviii 01 2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.40 {parse yymmdd} {
+ clock scan {xxxviii 01 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.41 {parse yymmdd} {
+ clock scan {xxxviii i 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.42 {parse yymmdd} {
+ clock scan {xxxviii i ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.43 {parse yymmdd} {
+ clock scan {xxxviii i 2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.44 {parse yymmdd} {
+ clock scan {xxxviii i ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.45 {parse yymmdd} {
+ clock scan {xxxviii 1 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.46 {parse yymmdd} {
+ clock scan {xxxviii 1 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.47 {parse yymmdd} {
+ clock scan {xxxviii 1 2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.48 {parse yymmdd} {
+ clock scan {xxxviii 1 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.49 {parse yymmdd} {
+ clock scan {38 Jan 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.50 {parse yymmdd} {
+ clock scan {38 Jan xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.51 {parse yymmdd} {
+ clock scan {38 Jan 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.52 {parse yymmdd} {
+ clock scan {38 Jan xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.53 {parse yymmdd} {
+ clock scan {38 January 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.54 {parse yymmdd} {
+ clock scan {38 January xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.55 {parse yymmdd} {
+ clock scan {38 January 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.56 {parse yymmdd} {
+ clock scan {38 January xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.57 {parse yymmdd} {
+ clock scan {38 Jan 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.58 {parse yymmdd} {
+ clock scan {38 Jan xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.59 {parse yymmdd} {
+ clock scan {38 Jan 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.60 {parse yymmdd} {
+ clock scan {38 Jan xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.61 {parse yymmdd} {
+ clock scan {38 01 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.62 {parse yymmdd} {
+ clock scan {38 01 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.63 {parse yymmdd} {
+ clock scan {38 01 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.64 {parse yymmdd} {
+ clock scan {38 01 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.65 {parse yymmdd} {
+ clock scan {38 i 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.66 {parse yymmdd} {
+ clock scan {38 i xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.67 {parse yymmdd} {
+ clock scan {38 i 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.68 {parse yymmdd} {
+ clock scan {38 i xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.69 {parse yymmdd} {
+ clock scan {38 1 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.70 {parse yymmdd} {
+ clock scan {38 1 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.71 {parse yymmdd} {
+ clock scan {38 1 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.72 {parse yymmdd} {
+ clock scan {38 1 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.73 {parse yymmdd} {
+ clock scan {xxxviii Jan 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.74 {parse yymmdd} {
+ clock scan {xxxviii Jan xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.75 {parse yymmdd} {
+ clock scan {xxxviii Jan 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.76 {parse yymmdd} {
+ clock scan {xxxviii Jan xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.77 {parse yymmdd} {
+ clock scan {xxxviii January 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.78 {parse yymmdd} {
+ clock scan {xxxviii January xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.79 {parse yymmdd} {
+ clock scan {xxxviii January 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.80 {parse yymmdd} {
+ clock scan {xxxviii January xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.81 {parse yymmdd} {
+ clock scan {xxxviii Jan 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.82 {parse yymmdd} {
+ clock scan {xxxviii Jan xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.83 {parse yymmdd} {
+ clock scan {xxxviii Jan 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.84 {parse yymmdd} {
+ clock scan {xxxviii Jan xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.85 {parse yymmdd} {
+ clock scan {xxxviii 01 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.86 {parse yymmdd} {
+ clock scan {xxxviii 01 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.87 {parse yymmdd} {
+ clock scan {xxxviii 01 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.88 {parse yymmdd} {
+ clock scan {xxxviii 01 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.89 {parse yymmdd} {
+ clock scan {xxxviii i 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.90 {parse yymmdd} {
+ clock scan {xxxviii i xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.91 {parse yymmdd} {
+ clock scan {xxxviii i 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.92 {parse yymmdd} {
+ clock scan {xxxviii i xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.93 {parse yymmdd} {
+ clock scan {xxxviii 1 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.94 {parse yymmdd} {
+ clock scan {xxxviii 1 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.95 {parse yymmdd} {
+ clock scan {xxxviii 1 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.96 {parse yymmdd} {
+ clock scan {xxxviii 1 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.97 {parse yymmdd} {
+ clock scan {38 Dec 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.98 {parse yymmdd} {
+ clock scan {38 Dec ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.99 {parse yymmdd} {
+ clock scan {38 Dec 2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.100 {parse yymmdd} {
+ clock scan {38 Dec ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.101 {parse yymmdd} {
+ clock scan {38 December 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.102 {parse yymmdd} {
+ clock scan {38 December ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.103 {parse yymmdd} {
+ clock scan {38 December 2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.104 {parse yymmdd} {
+ clock scan {38 December ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.105 {parse yymmdd} {
+ clock scan {38 Dec 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.106 {parse yymmdd} {
+ clock scan {38 Dec ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.107 {parse yymmdd} {
+ clock scan {38 Dec 2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.108 {parse yymmdd} {
+ clock scan {38 Dec ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.109 {parse yymmdd} {
+ clock scan {38 12 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.110 {parse yymmdd} {
+ clock scan {38 12 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.111 {parse yymmdd} {
+ clock scan {38 12 2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.112 {parse yymmdd} {
+ clock scan {38 12 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.113 {parse yymmdd} {
+ clock scan {38 xii 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.114 {parse yymmdd} {
+ clock scan {38 xii ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.115 {parse yymmdd} {
+ clock scan {38 xii 2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.116 {parse yymmdd} {
+ clock scan {38 xii ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.117 {parse yymmdd} {
+ clock scan {38 12 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.118 {parse yymmdd} {
+ clock scan {38 12 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.119 {parse yymmdd} {
+ clock scan {38 12 2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.120 {parse yymmdd} {
+ clock scan {38 12 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.121 {parse yymmdd} {
+ clock scan {xxxviii Dec 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.122 {parse yymmdd} {
+ clock scan {xxxviii Dec ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.123 {parse yymmdd} {
+ clock scan {xxxviii Dec 2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.124 {parse yymmdd} {
+ clock scan {xxxviii Dec ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.125 {parse yymmdd} {
+ clock scan {xxxviii December 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.126 {parse yymmdd} {
+ clock scan {xxxviii December ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.127 {parse yymmdd} {
+ clock scan {xxxviii December 2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.128 {parse yymmdd} {
+ clock scan {xxxviii December ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.129 {parse yymmdd} {
+ clock scan {xxxviii Dec 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.130 {parse yymmdd} {
+ clock scan {xxxviii Dec ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.131 {parse yymmdd} {
+ clock scan {xxxviii Dec 2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.132 {parse yymmdd} {
+ clock scan {xxxviii Dec ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.133 {parse yymmdd} {
+ clock scan {xxxviii 12 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.134 {parse yymmdd} {
+ clock scan {xxxviii 12 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.135 {parse yymmdd} {
+ clock scan {xxxviii 12 2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.136 {parse yymmdd} {
+ clock scan {xxxviii 12 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.137 {parse yymmdd} {
+ clock scan {xxxviii xii 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.138 {parse yymmdd} {
+ clock scan {xxxviii xii ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.139 {parse yymmdd} {
+ clock scan {xxxviii xii 2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.140 {parse yymmdd} {
+ clock scan {xxxviii xii ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.141 {parse yymmdd} {
+ clock scan {xxxviii 12 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.142 {parse yymmdd} {
+ clock scan {xxxviii 12 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.143 {parse yymmdd} {
+ clock scan {xxxviii 12 2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.144 {parse yymmdd} {
+ clock scan {xxxviii 12 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.145 {parse yymmdd} {
+ clock scan {38 Dec 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.146 {parse yymmdd} {
+ clock scan {38 Dec xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.147 {parse yymmdd} {
+ clock scan {38 Dec 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.148 {parse yymmdd} {
+ clock scan {38 Dec xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.149 {parse yymmdd} {
+ clock scan {38 December 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.150 {parse yymmdd} {
+ clock scan {38 December xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.151 {parse yymmdd} {
+ clock scan {38 December 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.152 {parse yymmdd} {
+ clock scan {38 December xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.153 {parse yymmdd} {
+ clock scan {38 Dec 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.154 {parse yymmdd} {
+ clock scan {38 Dec xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.155 {parse yymmdd} {
+ clock scan {38 Dec 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.156 {parse yymmdd} {
+ clock scan {38 Dec xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.157 {parse yymmdd} {
+ clock scan {38 12 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.158 {parse yymmdd} {
+ clock scan {38 12 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.159 {parse yymmdd} {
+ clock scan {38 12 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.160 {parse yymmdd} {
+ clock scan {38 12 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.161 {parse yymmdd} {
+ clock scan {38 xii 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.162 {parse yymmdd} {
+ clock scan {38 xii xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.163 {parse yymmdd} {
+ clock scan {38 xii 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.164 {parse yymmdd} {
+ clock scan {38 xii xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.165 {parse yymmdd} {
+ clock scan {38 12 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.166 {parse yymmdd} {
+ clock scan {38 12 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.167 {parse yymmdd} {
+ clock scan {38 12 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.168 {parse yymmdd} {
+ clock scan {38 12 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.169 {parse yymmdd} {
+ clock scan {xxxviii Dec 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.170 {parse yymmdd} {
+ clock scan {xxxviii Dec xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.171 {parse yymmdd} {
+ clock scan {xxxviii Dec 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.172 {parse yymmdd} {
+ clock scan {xxxviii Dec xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.173 {parse yymmdd} {
+ clock scan {xxxviii December 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.174 {parse yymmdd} {
+ clock scan {xxxviii December xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.175 {parse yymmdd} {
+ clock scan {xxxviii December 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.176 {parse yymmdd} {
+ clock scan {xxxviii December xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.177 {parse yymmdd} {
+ clock scan {xxxviii Dec 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.178 {parse yymmdd} {
+ clock scan {xxxviii Dec xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.179 {parse yymmdd} {
+ clock scan {xxxviii Dec 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.180 {parse yymmdd} {
+ clock scan {xxxviii Dec xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.181 {parse yymmdd} {
+ clock scan {xxxviii 12 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.182 {parse yymmdd} {
+ clock scan {xxxviii 12 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.183 {parse yymmdd} {
+ clock scan {xxxviii 12 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.184 {parse yymmdd} {
+ clock scan {xxxviii 12 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.185 {parse yymmdd} {
+ clock scan {xxxviii xii 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.186 {parse yymmdd} {
+ clock scan {xxxviii xii xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.187 {parse yymmdd} {
+ clock scan {xxxviii xii 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.188 {parse yymmdd} {
+ clock scan {xxxviii xii xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.189 {parse yymmdd} {
+ clock scan {xxxviii 12 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.190 {parse yymmdd} {
+ clock scan {xxxviii 12 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.191 {parse yymmdd} {
+ clock scan {xxxviii 12 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.192 {parse yymmdd} {
+ clock scan {xxxviii 12 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.193 {parse yymmdd} {
+ clock scan {70 Jan 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.194 {parse yymmdd} {
+ clock scan {70 Jan ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.195 {parse yymmdd} {
+ clock scan {70 Jan 2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.196 {parse yymmdd} {
+ clock scan {70 Jan ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.197 {parse yymmdd} {
+ clock scan {70 January 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.198 {parse yymmdd} {
+ clock scan {70 January ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.199 {parse yymmdd} {
+ clock scan {70 January 2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.200 {parse yymmdd} {
+ clock scan {70 January ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.201 {parse yymmdd} {
+ clock scan {70 Jan 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.202 {parse yymmdd} {
+ clock scan {70 Jan ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.203 {parse yymmdd} {
+ clock scan {70 Jan 2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.204 {parse yymmdd} {
+ clock scan {70 Jan ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.205 {parse yymmdd} {
+ clock scan {70 01 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.206 {parse yymmdd} {
+ clock scan {70 01 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.207 {parse yymmdd} {
+ clock scan {70 01 2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.208 {parse yymmdd} {
+ clock scan {70 01 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.209 {parse yymmdd} {
+ clock scan {70 i 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.210 {parse yymmdd} {
+ clock scan {70 i ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.211 {parse yymmdd} {
+ clock scan {70 i 2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.212 {parse yymmdd} {
+ clock scan {70 i ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.213 {parse yymmdd} {
+ clock scan {70 1 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.214 {parse yymmdd} {
+ clock scan {70 1 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.215 {parse yymmdd} {
+ clock scan {70 1 2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.216 {parse yymmdd} {
+ clock scan {70 1 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.217 {parse yymmdd} {
+ clock scan {lxx Jan 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.218 {parse yymmdd} {
+ clock scan {lxx Jan ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.219 {parse yymmdd} {
+ clock scan {lxx Jan 2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.220 {parse yymmdd} {
+ clock scan {lxx Jan ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.221 {parse yymmdd} {
+ clock scan {lxx January 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.222 {parse yymmdd} {
+ clock scan {lxx January ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.223 {parse yymmdd} {
+ clock scan {lxx January 2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.224 {parse yymmdd} {
+ clock scan {lxx January ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.225 {parse yymmdd} {
+ clock scan {lxx Jan 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.226 {parse yymmdd} {
+ clock scan {lxx Jan ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.227 {parse yymmdd} {
+ clock scan {lxx Jan 2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.228 {parse yymmdd} {
+ clock scan {lxx Jan ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.229 {parse yymmdd} {
+ clock scan {lxx 01 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.230 {parse yymmdd} {
+ clock scan {lxx 01 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.231 {parse yymmdd} {
+ clock scan {lxx 01 2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.232 {parse yymmdd} {
+ clock scan {lxx 01 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.233 {parse yymmdd} {
+ clock scan {lxx i 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.234 {parse yymmdd} {
+ clock scan {lxx i ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.235 {parse yymmdd} {
+ clock scan {lxx i 2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.236 {parse yymmdd} {
+ clock scan {lxx i ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.237 {parse yymmdd} {
+ clock scan {lxx 1 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.238 {parse yymmdd} {
+ clock scan {lxx 1 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.239 {parse yymmdd} {
+ clock scan {lxx 1 2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.240 {parse yymmdd} {
+ clock scan {lxx 1 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.241 {parse yymmdd} {
+ clock scan {70 Jan 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.242 {parse yymmdd} {
+ clock scan {70 Jan xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.243 {parse yymmdd} {
+ clock scan {70 Jan 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.244 {parse yymmdd} {
+ clock scan {70 Jan xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.245 {parse yymmdd} {
+ clock scan {70 January 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.246 {parse yymmdd} {
+ clock scan {70 January xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.247 {parse yymmdd} {
+ clock scan {70 January 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.248 {parse yymmdd} {
+ clock scan {70 January xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.249 {parse yymmdd} {
+ clock scan {70 Jan 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.250 {parse yymmdd} {
+ clock scan {70 Jan xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.251 {parse yymmdd} {
+ clock scan {70 Jan 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.252 {parse yymmdd} {
+ clock scan {70 Jan xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.253 {parse yymmdd} {
+ clock scan {70 01 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.254 {parse yymmdd} {
+ clock scan {70 01 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.255 {parse yymmdd} {
+ clock scan {70 01 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.256 {parse yymmdd} {
+ clock scan {70 01 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.257 {parse yymmdd} {
+ clock scan {70 i 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.258 {parse yymmdd} {
+ clock scan {70 i xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.259 {parse yymmdd} {
+ clock scan {70 i 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.260 {parse yymmdd} {
+ clock scan {70 i xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.261 {parse yymmdd} {
+ clock scan {70 1 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.262 {parse yymmdd} {
+ clock scan {70 1 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.263 {parse yymmdd} {
+ clock scan {70 1 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.264 {parse yymmdd} {
+ clock scan {70 1 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.265 {parse yymmdd} {
+ clock scan {lxx Jan 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.266 {parse yymmdd} {
+ clock scan {lxx Jan xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.267 {parse yymmdd} {
+ clock scan {lxx Jan 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.268 {parse yymmdd} {
+ clock scan {lxx Jan xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.269 {parse yymmdd} {
+ clock scan {lxx January 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.270 {parse yymmdd} {
+ clock scan {lxx January xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.271 {parse yymmdd} {
+ clock scan {lxx January 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.272 {parse yymmdd} {
+ clock scan {lxx January xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.273 {parse yymmdd} {
+ clock scan {lxx Jan 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.274 {parse yymmdd} {
+ clock scan {lxx Jan xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.275 {parse yymmdd} {
+ clock scan {lxx Jan 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.276 {parse yymmdd} {
+ clock scan {lxx Jan xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.277 {parse yymmdd} {
+ clock scan {lxx 01 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.278 {parse yymmdd} {
+ clock scan {lxx 01 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.279 {parse yymmdd} {
+ clock scan {lxx 01 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.280 {parse yymmdd} {
+ clock scan {lxx 01 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.281 {parse yymmdd} {
+ clock scan {lxx i 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.282 {parse yymmdd} {
+ clock scan {lxx i xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.283 {parse yymmdd} {
+ clock scan {lxx i 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.284 {parse yymmdd} {
+ clock scan {lxx i xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.285 {parse yymmdd} {
+ clock scan {lxx 1 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.286 {parse yymmdd} {
+ clock scan {lxx 1 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.287 {parse yymmdd} {
+ clock scan {lxx 1 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.288 {parse yymmdd} {
+ clock scan {lxx 1 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.289 {parse yymmdd} {
+ clock scan {70 Dec 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.290 {parse yymmdd} {
+ clock scan {70 Dec ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.291 {parse yymmdd} {
+ clock scan {70 Dec 2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.292 {parse yymmdd} {
+ clock scan {70 Dec ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.293 {parse yymmdd} {
+ clock scan {70 December 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.294 {parse yymmdd} {
+ clock scan {70 December ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.295 {parse yymmdd} {
+ clock scan {70 December 2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.296 {parse yymmdd} {
+ clock scan {70 December ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.297 {parse yymmdd} {
+ clock scan {70 Dec 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.298 {parse yymmdd} {
+ clock scan {70 Dec ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.299 {parse yymmdd} {
+ clock scan {70 Dec 2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.300 {parse yymmdd} {
+ clock scan {70 Dec ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.301 {parse yymmdd} {
+ clock scan {70 12 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.302 {parse yymmdd} {
+ clock scan {70 12 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.303 {parse yymmdd} {
+ clock scan {70 12 2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.304 {parse yymmdd} {
+ clock scan {70 12 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.305 {parse yymmdd} {
+ clock scan {70 xii 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.306 {parse yymmdd} {
+ clock scan {70 xii ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.307 {parse yymmdd} {
+ clock scan {70 xii 2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.308 {parse yymmdd} {
+ clock scan {70 xii ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.309 {parse yymmdd} {
+ clock scan {70 12 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.310 {parse yymmdd} {
+ clock scan {70 12 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.311 {parse yymmdd} {
+ clock scan {70 12 2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.312 {parse yymmdd} {
+ clock scan {70 12 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.313 {parse yymmdd} {
+ clock scan {lxx Dec 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.314 {parse yymmdd} {
+ clock scan {lxx Dec ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.315 {parse yymmdd} {
+ clock scan {lxx Dec 2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.316 {parse yymmdd} {
+ clock scan {lxx Dec ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.317 {parse yymmdd} {
+ clock scan {lxx December 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.318 {parse yymmdd} {
+ clock scan {lxx December ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.319 {parse yymmdd} {
+ clock scan {lxx December 2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.320 {parse yymmdd} {
+ clock scan {lxx December ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.321 {parse yymmdd} {
+ clock scan {lxx Dec 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.322 {parse yymmdd} {
+ clock scan {lxx Dec ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.323 {parse yymmdd} {
+ clock scan {lxx Dec 2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.324 {parse yymmdd} {
+ clock scan {lxx Dec ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.325 {parse yymmdd} {
+ clock scan {lxx 12 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.326 {parse yymmdd} {
+ clock scan {lxx 12 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.327 {parse yymmdd} {
+ clock scan {lxx 12 2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.328 {parse yymmdd} {
+ clock scan {lxx 12 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.329 {parse yymmdd} {
+ clock scan {lxx xii 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.330 {parse yymmdd} {
+ clock scan {lxx xii ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.331 {parse yymmdd} {
+ clock scan {lxx xii 2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.332 {parse yymmdd} {
+ clock scan {lxx xii ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.333 {parse yymmdd} {
+ clock scan {lxx 12 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.334 {parse yymmdd} {
+ clock scan {lxx 12 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.335 {parse yymmdd} {
+ clock scan {lxx 12 2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.336 {parse yymmdd} {
+ clock scan {lxx 12 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.337 {parse yymmdd} {
+ clock scan {70 Dec 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.338 {parse yymmdd} {
+ clock scan {70 Dec xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.339 {parse yymmdd} {
+ clock scan {70 Dec 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.340 {parse yymmdd} {
+ clock scan {70 Dec xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.341 {parse yymmdd} {
+ clock scan {70 December 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.342 {parse yymmdd} {
+ clock scan {70 December xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.343 {parse yymmdd} {
+ clock scan {70 December 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.344 {parse yymmdd} {
+ clock scan {70 December xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.345 {parse yymmdd} {
+ clock scan {70 Dec 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.346 {parse yymmdd} {
+ clock scan {70 Dec xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.347 {parse yymmdd} {
+ clock scan {70 Dec 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.348 {parse yymmdd} {
+ clock scan {70 Dec xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.349 {parse yymmdd} {
+ clock scan {70 12 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.350 {parse yymmdd} {
+ clock scan {70 12 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.351 {parse yymmdd} {
+ clock scan {70 12 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.352 {parse yymmdd} {
+ clock scan {70 12 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.353 {parse yymmdd} {
+ clock scan {70 xii 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.354 {parse yymmdd} {
+ clock scan {70 xii xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.355 {parse yymmdd} {
+ clock scan {70 xii 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.356 {parse yymmdd} {
+ clock scan {70 xii xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.357 {parse yymmdd} {
+ clock scan {70 12 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.358 {parse yymmdd} {
+ clock scan {70 12 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.359 {parse yymmdd} {
+ clock scan {70 12 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.360 {parse yymmdd} {
+ clock scan {70 12 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.361 {parse yymmdd} {
+ clock scan {lxx Dec 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.362 {parse yymmdd} {
+ clock scan {lxx Dec xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.363 {parse yymmdd} {
+ clock scan {lxx Dec 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.364 {parse yymmdd} {
+ clock scan {lxx Dec xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.365 {parse yymmdd} {
+ clock scan {lxx December 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.366 {parse yymmdd} {
+ clock scan {lxx December xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.367 {parse yymmdd} {
+ clock scan {lxx December 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.368 {parse yymmdd} {
+ clock scan {lxx December xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.369 {parse yymmdd} {
+ clock scan {lxx Dec 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.370 {parse yymmdd} {
+ clock scan {lxx Dec xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.371 {parse yymmdd} {
+ clock scan {lxx Dec 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.372 {parse yymmdd} {
+ clock scan {lxx Dec xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.373 {parse yymmdd} {
+ clock scan {lxx 12 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.374 {parse yymmdd} {
+ clock scan {lxx 12 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.375 {parse yymmdd} {
+ clock scan {lxx 12 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.376 {parse yymmdd} {
+ clock scan {lxx 12 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.377 {parse yymmdd} {
+ clock scan {lxx xii 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.378 {parse yymmdd} {
+ clock scan {lxx xii xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.379 {parse yymmdd} {
+ clock scan {lxx xii 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.380 {parse yymmdd} {
+ clock scan {lxx xii xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.381 {parse yymmdd} {
+ clock scan {lxx 12 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.382 {parse yymmdd} {
+ clock scan {lxx 12 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.383 {parse yymmdd} {
+ clock scan {lxx 12 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.384 {parse yymmdd} {
+ clock scan {lxx 12 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.385 {parse yymmdd} {
+ clock scan {00 Jan 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.386 {parse yymmdd} {
+ clock scan {00 Jan ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.387 {parse yymmdd} {
+ clock scan {00 Jan 2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.388 {parse yymmdd} {
+ clock scan {00 Jan ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.389 {parse yymmdd} {
+ clock scan {00 January 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.390 {parse yymmdd} {
+ clock scan {00 January ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.391 {parse yymmdd} {
+ clock scan {00 January 2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.392 {parse yymmdd} {
+ clock scan {00 January ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.393 {parse yymmdd} {
+ clock scan {00 Jan 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.394 {parse yymmdd} {
+ clock scan {00 Jan ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.395 {parse yymmdd} {
+ clock scan {00 Jan 2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.396 {parse yymmdd} {
+ clock scan {00 Jan ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.397 {parse yymmdd} {
+ clock scan {00 01 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.398 {parse yymmdd} {
+ clock scan {00 01 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.399 {parse yymmdd} {
+ clock scan {00 01 2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.400 {parse yymmdd} {
+ clock scan {00 01 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.401 {parse yymmdd} {
+ clock scan {00 i 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.402 {parse yymmdd} {
+ clock scan {00 i ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.403 {parse yymmdd} {
+ clock scan {00 i 2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.404 {parse yymmdd} {
+ clock scan {00 i ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.405 {parse yymmdd} {
+ clock scan {00 1 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.406 {parse yymmdd} {
+ clock scan {00 1 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.407 {parse yymmdd} {
+ clock scan {00 1 2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.408 {parse yymmdd} {
+ clock scan {00 1 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.409 {parse yymmdd} {
+ clock scan {? Jan 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.410 {parse yymmdd} {
+ clock scan {? Jan ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.411 {parse yymmdd} {
+ clock scan {? Jan 2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.412 {parse yymmdd} {
+ clock scan {? Jan ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.413 {parse yymmdd} {
+ clock scan {? January 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.414 {parse yymmdd} {
+ clock scan {? January ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.415 {parse yymmdd} {
+ clock scan {? January 2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.416 {parse yymmdd} {
+ clock scan {? January ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.417 {parse yymmdd} {
+ clock scan {? Jan 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.418 {parse yymmdd} {
+ clock scan {? Jan ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.419 {parse yymmdd} {
+ clock scan {? Jan 2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.420 {parse yymmdd} {
+ clock scan {? Jan ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.421 {parse yymmdd} {
+ clock scan {? 01 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.422 {parse yymmdd} {
+ clock scan {? 01 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.423 {parse yymmdd} {
+ clock scan {? 01 2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.424 {parse yymmdd} {
+ clock scan {? 01 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.425 {parse yymmdd} {
+ clock scan {? i 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.426 {parse yymmdd} {
+ clock scan {? i ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.427 {parse yymmdd} {
+ clock scan {? i 2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.428 {parse yymmdd} {
+ clock scan {? i ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.429 {parse yymmdd} {
+ clock scan {? 1 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.430 {parse yymmdd} {
+ clock scan {? 1 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.431 {parse yymmdd} {
+ clock scan {? 1 2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.432 {parse yymmdd} {
+ clock scan {? 1 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.433 {parse yymmdd} {
+ clock scan {00 Jan 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.434 {parse yymmdd} {
+ clock scan {00 Jan xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.435 {parse yymmdd} {
+ clock scan {00 Jan 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.436 {parse yymmdd} {
+ clock scan {00 Jan xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.437 {parse yymmdd} {
+ clock scan {00 January 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.438 {parse yymmdd} {
+ clock scan {00 January xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.439 {parse yymmdd} {
+ clock scan {00 January 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.440 {parse yymmdd} {
+ clock scan {00 January xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.441 {parse yymmdd} {
+ clock scan {00 Jan 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.442 {parse yymmdd} {
+ clock scan {00 Jan xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.443 {parse yymmdd} {
+ clock scan {00 Jan 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.444 {parse yymmdd} {
+ clock scan {00 Jan xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.445 {parse yymmdd} {
+ clock scan {00 01 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.446 {parse yymmdd} {
+ clock scan {00 01 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.447 {parse yymmdd} {
+ clock scan {00 01 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.448 {parse yymmdd} {
+ clock scan {00 01 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.449 {parse yymmdd} {
+ clock scan {00 i 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.450 {parse yymmdd} {
+ clock scan {00 i xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.451 {parse yymmdd} {
+ clock scan {00 i 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.452 {parse yymmdd} {
+ clock scan {00 i xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.453 {parse yymmdd} {
+ clock scan {00 1 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.454 {parse yymmdd} {
+ clock scan {00 1 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.455 {parse yymmdd} {
+ clock scan {00 1 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.456 {parse yymmdd} {
+ clock scan {00 1 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.457 {parse yymmdd} {
+ clock scan {? Jan 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.458 {parse yymmdd} {
+ clock scan {? Jan xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.459 {parse yymmdd} {
+ clock scan {? Jan 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.460 {parse yymmdd} {
+ clock scan {? Jan xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.461 {parse yymmdd} {
+ clock scan {? January 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.462 {parse yymmdd} {
+ clock scan {? January xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.463 {parse yymmdd} {
+ clock scan {? January 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.464 {parse yymmdd} {
+ clock scan {? January xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.465 {parse yymmdd} {
+ clock scan {? Jan 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.466 {parse yymmdd} {
+ clock scan {? Jan xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.467 {parse yymmdd} {
+ clock scan {? Jan 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.468 {parse yymmdd} {
+ clock scan {? Jan xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.469 {parse yymmdd} {
+ clock scan {? 01 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.470 {parse yymmdd} {
+ clock scan {? 01 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.471 {parse yymmdd} {
+ clock scan {? 01 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.472 {parse yymmdd} {
+ clock scan {? 01 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.473 {parse yymmdd} {
+ clock scan {? i 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.474 {parse yymmdd} {
+ clock scan {? i xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.475 {parse yymmdd} {
+ clock scan {? i 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.476 {parse yymmdd} {
+ clock scan {? i xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.477 {parse yymmdd} {
+ clock scan {? 1 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.478 {parse yymmdd} {
+ clock scan {? 1 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.479 {parse yymmdd} {
+ clock scan {? 1 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.480 {parse yymmdd} {
+ clock scan {? 1 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.481 {parse yymmdd} {
+ clock scan {00 Dec 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.482 {parse yymmdd} {
+ clock scan {00 Dec ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.483 {parse yymmdd} {
+ clock scan {00 Dec 2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.484 {parse yymmdd} {
+ clock scan {00 Dec ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.485 {parse yymmdd} {
+ clock scan {00 December 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.486 {parse yymmdd} {
+ clock scan {00 December ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.487 {parse yymmdd} {
+ clock scan {00 December 2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.488 {parse yymmdd} {
+ clock scan {00 December ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.489 {parse yymmdd} {
+ clock scan {00 Dec 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.490 {parse yymmdd} {
+ clock scan {00 Dec ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.491 {parse yymmdd} {
+ clock scan {00 Dec 2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.492 {parse yymmdd} {
+ clock scan {00 Dec ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.493 {parse yymmdd} {
+ clock scan {00 12 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.494 {parse yymmdd} {
+ clock scan {00 12 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.495 {parse yymmdd} {
+ clock scan {00 12 2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.496 {parse yymmdd} {
+ clock scan {00 12 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.497 {parse yymmdd} {
+ clock scan {00 xii 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.498 {parse yymmdd} {
+ clock scan {00 xii ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.499 {parse yymmdd} {
+ clock scan {00 xii 2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.500 {parse yymmdd} {
+ clock scan {00 xii ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.501 {parse yymmdd} {
+ clock scan {00 12 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.502 {parse yymmdd} {
+ clock scan {00 12 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.503 {parse yymmdd} {
+ clock scan {00 12 2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.504 {parse yymmdd} {
+ clock scan {00 12 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.505 {parse yymmdd} {
+ clock scan {? Dec 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.506 {parse yymmdd} {
+ clock scan {? Dec ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.507 {parse yymmdd} {
+ clock scan {? Dec 2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.508 {parse yymmdd} {
+ clock scan {? Dec ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.509 {parse yymmdd} {
+ clock scan {? December 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.510 {parse yymmdd} {
+ clock scan {? December ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.511 {parse yymmdd} {
+ clock scan {? December 2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.512 {parse yymmdd} {
+ clock scan {? December ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.513 {parse yymmdd} {
+ clock scan {? Dec 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.514 {parse yymmdd} {
+ clock scan {? Dec ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.515 {parse yymmdd} {
+ clock scan {? Dec 2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.516 {parse yymmdd} {
+ clock scan {? Dec ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.517 {parse yymmdd} {
+ clock scan {? 12 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.518 {parse yymmdd} {
+ clock scan {? 12 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.519 {parse yymmdd} {
+ clock scan {? 12 2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.520 {parse yymmdd} {
+ clock scan {? 12 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.521 {parse yymmdd} {
+ clock scan {? xii 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.522 {parse yymmdd} {
+ clock scan {? xii ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.523 {parse yymmdd} {
+ clock scan {? xii 2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.524 {parse yymmdd} {
+ clock scan {? xii ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.525 {parse yymmdd} {
+ clock scan {? 12 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.526 {parse yymmdd} {
+ clock scan {? 12 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.527 {parse yymmdd} {
+ clock scan {? 12 2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.528 {parse yymmdd} {
+ clock scan {? 12 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.529 {parse yymmdd} {
+ clock scan {00 Dec 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.530 {parse yymmdd} {
+ clock scan {00 Dec xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.531 {parse yymmdd} {
+ clock scan {00 Dec 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.532 {parse yymmdd} {
+ clock scan {00 Dec xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.533 {parse yymmdd} {
+ clock scan {00 December 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.534 {parse yymmdd} {
+ clock scan {00 December xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.535 {parse yymmdd} {
+ clock scan {00 December 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.536 {parse yymmdd} {
+ clock scan {00 December xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.537 {parse yymmdd} {
+ clock scan {00 Dec 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.538 {parse yymmdd} {
+ clock scan {00 Dec xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.539 {parse yymmdd} {
+ clock scan {00 Dec 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.540 {parse yymmdd} {
+ clock scan {00 Dec xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.541 {parse yymmdd} {
+ clock scan {00 12 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.542 {parse yymmdd} {
+ clock scan {00 12 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.543 {parse yymmdd} {
+ clock scan {00 12 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.544 {parse yymmdd} {
+ clock scan {00 12 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.545 {parse yymmdd} {
+ clock scan {00 xii 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.546 {parse yymmdd} {
+ clock scan {00 xii xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.547 {parse yymmdd} {
+ clock scan {00 xii 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.548 {parse yymmdd} {
+ clock scan {00 xii xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.549 {parse yymmdd} {
+ clock scan {00 12 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.550 {parse yymmdd} {
+ clock scan {00 12 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.551 {parse yymmdd} {
+ clock scan {00 12 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.552 {parse yymmdd} {
+ clock scan {00 12 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.553 {parse yymmdd} {
+ clock scan {? Dec 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.554 {parse yymmdd} {
+ clock scan {? Dec xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.555 {parse yymmdd} {
+ clock scan {? Dec 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.556 {parse yymmdd} {
+ clock scan {? Dec xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.557 {parse yymmdd} {
+ clock scan {? December 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.558 {parse yymmdd} {
+ clock scan {? December xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.559 {parse yymmdd} {
+ clock scan {? December 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.560 {parse yymmdd} {
+ clock scan {? December xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.561 {parse yymmdd} {
+ clock scan {? Dec 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.562 {parse yymmdd} {
+ clock scan {? Dec xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.563 {parse yymmdd} {
+ clock scan {? Dec 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.564 {parse yymmdd} {
+ clock scan {? Dec xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.565 {parse yymmdd} {
+ clock scan {? 12 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.566 {parse yymmdd} {
+ clock scan {? 12 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.567 {parse yymmdd} {
+ clock scan {? 12 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.568 {parse yymmdd} {
+ clock scan {? 12 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.569 {parse yymmdd} {
+ clock scan {? xii 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.570 {parse yymmdd} {
+ clock scan {? xii xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.571 {parse yymmdd} {
+ clock scan {? xii 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.572 {parse yymmdd} {
+ clock scan {? xii xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.573 {parse yymmdd} {
+ clock scan {? 12 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.574 {parse yymmdd} {
+ clock scan {? 12 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.575 {parse yymmdd} {
+ clock scan {? 12 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.576 {parse yymmdd} {
+ clock scan {? 12 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.577 {parse yymmdd} {
+ clock scan {37 Jan 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.578 {parse yymmdd} {
+ clock scan {37 Jan ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.579 {parse yymmdd} {
+ clock scan {37 Jan 2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.580 {parse yymmdd} {
+ clock scan {37 Jan ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.581 {parse yymmdd} {
+ clock scan {37 January 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.582 {parse yymmdd} {
+ clock scan {37 January ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.583 {parse yymmdd} {
+ clock scan {37 January 2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.584 {parse yymmdd} {
+ clock scan {37 January ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.585 {parse yymmdd} {
+ clock scan {37 Jan 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.586 {parse yymmdd} {
+ clock scan {37 Jan ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.587 {parse yymmdd} {
+ clock scan {37 Jan 2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.588 {parse yymmdd} {
+ clock scan {37 Jan ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.589 {parse yymmdd} {
+ clock scan {37 01 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.590 {parse yymmdd} {
+ clock scan {37 01 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.591 {parse yymmdd} {
+ clock scan {37 01 2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.592 {parse yymmdd} {
+ clock scan {37 01 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.593 {parse yymmdd} {
+ clock scan {37 i 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.594 {parse yymmdd} {
+ clock scan {37 i ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.595 {parse yymmdd} {
+ clock scan {37 i 2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.596 {parse yymmdd} {
+ clock scan {37 i ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.597 {parse yymmdd} {
+ clock scan {37 1 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.598 {parse yymmdd} {
+ clock scan {37 1 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.599 {parse yymmdd} {
+ clock scan {37 1 2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.600 {parse yymmdd} {
+ clock scan {37 1 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.601 {parse yymmdd} {
+ clock scan {xxxvii Jan 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.602 {parse yymmdd} {
+ clock scan {xxxvii Jan ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.603 {parse yymmdd} {
+ clock scan {xxxvii Jan 2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.604 {parse yymmdd} {
+ clock scan {xxxvii Jan ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.605 {parse yymmdd} {
+ clock scan {xxxvii January 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.606 {parse yymmdd} {
+ clock scan {xxxvii January ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.607 {parse yymmdd} {
+ clock scan {xxxvii January 2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.608 {parse yymmdd} {
+ clock scan {xxxvii January ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.609 {parse yymmdd} {
+ clock scan {xxxvii Jan 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.610 {parse yymmdd} {
+ clock scan {xxxvii Jan ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.611 {parse yymmdd} {
+ clock scan {xxxvii Jan 2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.612 {parse yymmdd} {
+ clock scan {xxxvii Jan ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.613 {parse yymmdd} {
+ clock scan {xxxvii 01 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.614 {parse yymmdd} {
+ clock scan {xxxvii 01 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.615 {parse yymmdd} {
+ clock scan {xxxvii 01 2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.616 {parse yymmdd} {
+ clock scan {xxxvii 01 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.617 {parse yymmdd} {
+ clock scan {xxxvii i 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.618 {parse yymmdd} {
+ clock scan {xxxvii i ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.619 {parse yymmdd} {
+ clock scan {xxxvii i 2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.620 {parse yymmdd} {
+ clock scan {xxxvii i ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.621 {parse yymmdd} {
+ clock scan {xxxvii 1 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.622 {parse yymmdd} {
+ clock scan {xxxvii 1 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.623 {parse yymmdd} {
+ clock scan {xxxvii 1 2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.624 {parse yymmdd} {
+ clock scan {xxxvii 1 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.625 {parse yymmdd} {
+ clock scan {37 Jan 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.626 {parse yymmdd} {
+ clock scan {37 Jan xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.627 {parse yymmdd} {
+ clock scan {37 Jan 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.628 {parse yymmdd} {
+ clock scan {37 Jan xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.629 {parse yymmdd} {
+ clock scan {37 January 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.630 {parse yymmdd} {
+ clock scan {37 January xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.631 {parse yymmdd} {
+ clock scan {37 January 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.632 {parse yymmdd} {
+ clock scan {37 January xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.633 {parse yymmdd} {
+ clock scan {37 Jan 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.634 {parse yymmdd} {
+ clock scan {37 Jan xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.635 {parse yymmdd} {
+ clock scan {37 Jan 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.636 {parse yymmdd} {
+ clock scan {37 Jan xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.637 {parse yymmdd} {
+ clock scan {37 01 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.638 {parse yymmdd} {
+ clock scan {37 01 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.639 {parse yymmdd} {
+ clock scan {37 01 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.640 {parse yymmdd} {
+ clock scan {37 01 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.641 {parse yymmdd} {
+ clock scan {37 i 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.642 {parse yymmdd} {
+ clock scan {37 i xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.643 {parse yymmdd} {
+ clock scan {37 i 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.644 {parse yymmdd} {
+ clock scan {37 i xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.645 {parse yymmdd} {
+ clock scan {37 1 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.646 {parse yymmdd} {
+ clock scan {37 1 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.647 {parse yymmdd} {
+ clock scan {37 1 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.648 {parse yymmdd} {
+ clock scan {37 1 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.649 {parse yymmdd} {
+ clock scan {xxxvii Jan 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.650 {parse yymmdd} {
+ clock scan {xxxvii Jan xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.651 {parse yymmdd} {
+ clock scan {xxxvii Jan 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.652 {parse yymmdd} {
+ clock scan {xxxvii Jan xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.653 {parse yymmdd} {
+ clock scan {xxxvii January 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.654 {parse yymmdd} {
+ clock scan {xxxvii January xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.655 {parse yymmdd} {
+ clock scan {xxxvii January 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.656 {parse yymmdd} {
+ clock scan {xxxvii January xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.657 {parse yymmdd} {
+ clock scan {xxxvii Jan 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.658 {parse yymmdd} {
+ clock scan {xxxvii Jan xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.659 {parse yymmdd} {
+ clock scan {xxxvii Jan 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.660 {parse yymmdd} {
+ clock scan {xxxvii Jan xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.661 {parse yymmdd} {
+ clock scan {xxxvii 01 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.662 {parse yymmdd} {
+ clock scan {xxxvii 01 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.663 {parse yymmdd} {
+ clock scan {xxxvii 01 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.664 {parse yymmdd} {
+ clock scan {xxxvii 01 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.665 {parse yymmdd} {
+ clock scan {xxxvii i 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.666 {parse yymmdd} {
+ clock scan {xxxvii i xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.667 {parse yymmdd} {
+ clock scan {xxxvii i 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.668 {parse yymmdd} {
+ clock scan {xxxvii i xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.669 {parse yymmdd} {
+ clock scan {xxxvii 1 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.670 {parse yymmdd} {
+ clock scan {xxxvii 1 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.671 {parse yymmdd} {
+ clock scan {xxxvii 1 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.672 {parse yymmdd} {
+ clock scan {xxxvii 1 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.673 {parse yymmdd} {
+ clock scan {37 Dec 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.674 {parse yymmdd} {
+ clock scan {37 Dec ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.675 {parse yymmdd} {
+ clock scan {37 Dec 2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.676 {parse yymmdd} {
+ clock scan {37 Dec ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.677 {parse yymmdd} {
+ clock scan {37 December 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.678 {parse yymmdd} {
+ clock scan {37 December ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.679 {parse yymmdd} {
+ clock scan {37 December 2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.680 {parse yymmdd} {
+ clock scan {37 December ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.681 {parse yymmdd} {
+ clock scan {37 Dec 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.682 {parse yymmdd} {
+ clock scan {37 Dec ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.683 {parse yymmdd} {
+ clock scan {37 Dec 2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.684 {parse yymmdd} {
+ clock scan {37 Dec ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.685 {parse yymmdd} {
+ clock scan {37 12 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.686 {parse yymmdd} {
+ clock scan {37 12 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.687 {parse yymmdd} {
+ clock scan {37 12 2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.688 {parse yymmdd} {
+ clock scan {37 12 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.689 {parse yymmdd} {
+ clock scan {37 xii 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.690 {parse yymmdd} {
+ clock scan {37 xii ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.691 {parse yymmdd} {
+ clock scan {37 xii 2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.692 {parse yymmdd} {
+ clock scan {37 xii ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.693 {parse yymmdd} {
+ clock scan {37 12 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.694 {parse yymmdd} {
+ clock scan {37 12 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.695 {parse yymmdd} {
+ clock scan {37 12 2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.696 {parse yymmdd} {
+ clock scan {37 12 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.697 {parse yymmdd} {
+ clock scan {xxxvii Dec 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.698 {parse yymmdd} {
+ clock scan {xxxvii Dec ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.699 {parse yymmdd} {
+ clock scan {xxxvii Dec 2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.700 {parse yymmdd} {
+ clock scan {xxxvii Dec ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.701 {parse yymmdd} {
+ clock scan {xxxvii December 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.702 {parse yymmdd} {
+ clock scan {xxxvii December ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.703 {parse yymmdd} {
+ clock scan {xxxvii December 2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.704 {parse yymmdd} {
+ clock scan {xxxvii December ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.705 {parse yymmdd} {
+ clock scan {xxxvii Dec 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.706 {parse yymmdd} {
+ clock scan {xxxvii Dec ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.707 {parse yymmdd} {
+ clock scan {xxxvii Dec 2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.708 {parse yymmdd} {
+ clock scan {xxxvii Dec ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.709 {parse yymmdd} {
+ clock scan {xxxvii 12 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.710 {parse yymmdd} {
+ clock scan {xxxvii 12 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.711 {parse yymmdd} {
+ clock scan {xxxvii 12 2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.712 {parse yymmdd} {
+ clock scan {xxxvii 12 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.713 {parse yymmdd} {
+ clock scan {xxxvii xii 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.714 {parse yymmdd} {
+ clock scan {xxxvii xii ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.715 {parse yymmdd} {
+ clock scan {xxxvii xii 2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.716 {parse yymmdd} {
+ clock scan {xxxvii xii ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.717 {parse yymmdd} {
+ clock scan {xxxvii 12 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.718 {parse yymmdd} {
+ clock scan {xxxvii 12 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.719 {parse yymmdd} {
+ clock scan {xxxvii 12 2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.720 {parse yymmdd} {
+ clock scan {xxxvii 12 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.721 {parse yymmdd} {
+ clock scan {37 Dec 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.722 {parse yymmdd} {
+ clock scan {37 Dec xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.723 {parse yymmdd} {
+ clock scan {37 Dec 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.724 {parse yymmdd} {
+ clock scan {37 Dec xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.725 {parse yymmdd} {
+ clock scan {37 December 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.726 {parse yymmdd} {
+ clock scan {37 December xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.727 {parse yymmdd} {
+ clock scan {37 December 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.728 {parse yymmdd} {
+ clock scan {37 December xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.729 {parse yymmdd} {
+ clock scan {37 Dec 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.730 {parse yymmdd} {
+ clock scan {37 Dec xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.731 {parse yymmdd} {
+ clock scan {37 Dec 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.732 {parse yymmdd} {
+ clock scan {37 Dec xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.733 {parse yymmdd} {
+ clock scan {37 12 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.734 {parse yymmdd} {
+ clock scan {37 12 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.735 {parse yymmdd} {
+ clock scan {37 12 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.736 {parse yymmdd} {
+ clock scan {37 12 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.737 {parse yymmdd} {
+ clock scan {37 xii 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.738 {parse yymmdd} {
+ clock scan {37 xii xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.739 {parse yymmdd} {
+ clock scan {37 xii 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.740 {parse yymmdd} {
+ clock scan {37 xii xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.741 {parse yymmdd} {
+ clock scan {37 12 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.742 {parse yymmdd} {
+ clock scan {37 12 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.743 {parse yymmdd} {
+ clock scan {37 12 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.744 {parse yymmdd} {
+ clock scan {37 12 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.745 {parse yymmdd} {
+ clock scan {xxxvii Dec 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.746 {parse yymmdd} {
+ clock scan {xxxvii Dec xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.747 {parse yymmdd} {
+ clock scan {xxxvii Dec 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.748 {parse yymmdd} {
+ clock scan {xxxvii Dec xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.749 {parse yymmdd} {
+ clock scan {xxxvii December 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.750 {parse yymmdd} {
+ clock scan {xxxvii December xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.751 {parse yymmdd} {
+ clock scan {xxxvii December 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.752 {parse yymmdd} {
+ clock scan {xxxvii December xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.753 {parse yymmdd} {
+ clock scan {xxxvii Dec 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.754 {parse yymmdd} {
+ clock scan {xxxvii Dec xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.755 {parse yymmdd} {
+ clock scan {xxxvii Dec 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.756 {parse yymmdd} {
+ clock scan {xxxvii Dec xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.757 {parse yymmdd} {
+ clock scan {xxxvii 12 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.758 {parse yymmdd} {
+ clock scan {xxxvii 12 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.759 {parse yymmdd} {
+ clock scan {xxxvii 12 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.760 {parse yymmdd} {
+ clock scan {xxxvii 12 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.761 {parse yymmdd} {
+ clock scan {xxxvii xii 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.762 {parse yymmdd} {
+ clock scan {xxxvii xii xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.763 {parse yymmdd} {
+ clock scan {xxxvii xii 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.764 {parse yymmdd} {
+ clock scan {xxxvii xii xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.765 {parse yymmdd} {
+ clock scan {xxxvii 12 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.766 {parse yymmdd} {
+ clock scan {xxxvii 12 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.767 {parse yymmdd} {
+ clock scan {xxxvii 12 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.768 {parse yymmdd} {
+ clock scan {xxxvii 12 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+# END testcases14
+
+test clock-15.1 {yymmdd precedence below seconds} {
+ list [clock scan {0 000101} -format {%s %y%m%d} -gmt true] \
+ [clock scan {000101 0} -format {%y%m%d %s} -gmt true]
+} {0 0}
+
+test clock-15.2 {yymmdd precedence below julian day} {
+ list [clock scan {2440588 000101} -format {%J %y%m%d} -gmt true] \
+ [clock scan {000101 2440588} -format {%y%m%d %J} -gmt true]
+} {0 0}
+
+test clock-15.3 {yymmdd precedence below yyyyWwwd} {
+ list [clock scan {1970W014000101} -format {%GW%V%u%y%m%d} -gmt true] \
+ [clock scan {0001011970W014} -format {%y%m%d%GW%V%u} -gmt true]
+} {0 0}
+
+# Test parsing of yyddd
+
+test clock-16.1 {parse yyddd} {
+ clock scan {70 001} -format {%y %j} -locale en_US_roman -gmt 1
+} 0
+test clock-16.2 {parse yyddd} {
+ clock scan {70 365} -format {%y %j} -locale en_US_roman -gmt 1
+} 31449600
+test clock-16.3 {parse yyddd} {
+ clock scan {71 001} -format {%y %j} -locale en_US_roman -gmt 1
+} 31536000
+test clock-16.4 {parse yyddd} {
+ clock scan {71 365} -format {%y %j} -locale en_US_roman -gmt 1
+} 62985600
+test clock-16.5 {parse yyddd} {
+ clock scan {00 001} -format {%y %j} -locale en_US_roman -gmt 1
+} 946684800
+test clock-16.6 {parse yyddd} {
+ clock scan {00 365} -format {%y %j} -locale en_US_roman -gmt 1
+} 978134400
+test clock-16.7 {parse yyddd} {
+ clock scan {01 001} -format {%y %j} -locale en_US_roman -gmt 1
+} 978307200
+test clock-16.8 {parse yyddd} {
+ clock scan {01 365} -format {%y %j} -locale en_US_roman -gmt 1
+} 1009756800
+
+test clock-16.9 {seconds take precedence over yyddd} {
+ list [clock scan {0 00001} -format {%s %y%j} -gmt true] \
+ [clock scan {00001 0} -format {%y%j %s} -gmt true]
+} {0 0}
+test clock-16.10 {julian day takes precedence over yyddd} {
+ list [clock scan {2440588 00001} -format {%J %y%j} -gmt true] \
+ [clock scan {00001 2440588} -format {%Y%j %J} -gmt true]
+} {0 0}
+test clock-16.11 {yyddd precedence below yyyyWwwd} {
+ list [clock scan {1970W01400001} -format {%GW%V%u%y%j} -gmt true] \
+ [clock scan {000011970W014} -format {%y%j%GW%V%u} -gmt true]
+} {0 0}
+
+# BEGIN testcases17
+
+# Test parsing of yyWwwd
+
+test clock-17.1 {parse yyWwwd} {
+ clock scan {70 W01 Fri} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.2 {parse yyWwwd} {
+ clock scan {70 W01 Friday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.3 {parse yyWwwd} {
+ clock scan {70 W01 5} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.4 {parse yyWwwd} {
+ clock scan {70 W01 5} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.5 {parse yyWwwd} {
+ clock scan {70 W01 v} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.6 {parse yyWwwd} {
+ clock scan {70 W01 v} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.7 {parse yyWwwd} {
+ clock scan {70 W05 Sat} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.8 {parse yyWwwd} {
+ clock scan {70 W05 Saturday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.9 {parse yyWwwd} {
+ clock scan {70 W05 6} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.10 {parse yyWwwd} {
+ clock scan {70 W05 6} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.11 {parse yyWwwd} {
+ clock scan {70 W05 vi} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.12 {parse yyWwwd} {
+ clock scan {70 W05 vi} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.13 {parse yyWwwd} {
+ clock scan {70 W49 Wed} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.14 {parse yyWwwd} {
+ clock scan {70 W49 Wednesday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.15 {parse yyWwwd} {
+ clock scan {70 W49 3} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.16 {parse yyWwwd} {
+ clock scan {70 W49 3} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.17 {parse yyWwwd} {
+ clock scan {70 W49 iii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.18 {parse yyWwwd} {
+ clock scan {70 W49 iii} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.19 {parse yyWwwd} {
+ clock scan {70 W53 Thu} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.20 {parse yyWwwd} {
+ clock scan {70 W53 Thursday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.21 {parse yyWwwd} {
+ clock scan {70 W53 4} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.22 {parse yyWwwd} {
+ clock scan {70 W53 4} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.23 {parse yyWwwd} {
+ clock scan {70 W53 iv} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.24 {parse yyWwwd} {
+ clock scan {70 W53 iv} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.25 {parse yyWwwd} {
+ clock scan {70 W53 Sat} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.26 {parse yyWwwd} {
+ clock scan {70 W53 Saturday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.27 {parse yyWwwd} {
+ clock scan {70 W53 6} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.28 {parse yyWwwd} {
+ clock scan {70 W53 6} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.29 {parse yyWwwd} {
+ clock scan {70 W53 vi} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.30 {parse yyWwwd} {
+ clock scan {70 W53 vi} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.31 {parse yyWwwd} {
+ clock scan {71 W04 Sun} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.32 {parse yyWwwd} {
+ clock scan {71 W04 Sunday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.33 {parse yyWwwd} {
+ clock scan {71 W04 7} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.34 {parse yyWwwd} {
+ clock scan {71 W04 0} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.35 {parse yyWwwd} {
+ clock scan {71 W04 vii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.36 {parse yyWwwd} {
+ clock scan {71 W04 ?} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.37 {parse yyWwwd} {
+ clock scan {71 W48 Thu} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.38 {parse yyWwwd} {
+ clock scan {71 W48 Thursday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.39 {parse yyWwwd} {
+ clock scan {71 W48 4} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.40 {parse yyWwwd} {
+ clock scan {71 W48 4} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.41 {parse yyWwwd} {
+ clock scan {71 W48 iv} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.42 {parse yyWwwd} {
+ clock scan {71 W48 iv} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.43 {parse yyWwwd} {
+ clock scan {71 W52 Fri} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.44 {parse yyWwwd} {
+ clock scan {71 W52 Friday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.45 {parse yyWwwd} {
+ clock scan {71 W52 5} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.46 {parse yyWwwd} {
+ clock scan {71 W52 5} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.47 {parse yyWwwd} {
+ clock scan {71 W52 v} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.48 {parse yyWwwd} {
+ clock scan {71 W52 v} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.49 {parse yyWwwd} {
+ clock scan {99 W52 Sun} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.50 {parse yyWwwd} {
+ clock scan {99 W52 Sunday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.51 {parse yyWwwd} {
+ clock scan {99 W52 7} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.52 {parse yyWwwd} {
+ clock scan {99 W52 0} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.53 {parse yyWwwd} {
+ clock scan {99 W52 vii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.54 {parse yyWwwd} {
+ clock scan {99 W52 ?} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.55 {parse yyWwwd} {
+ clock scan {00 W05 Mon} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.56 {parse yyWwwd} {
+ clock scan {00 W05 Monday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.57 {parse yyWwwd} {
+ clock scan {00 W05 1} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.58 {parse yyWwwd} {
+ clock scan {00 W05 1} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.59 {parse yyWwwd} {
+ clock scan {00 W05 i} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.60 {parse yyWwwd} {
+ clock scan {00 W05 i} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.61 {parse yyWwwd} {
+ clock scan {00 W48 Sat} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.62 {parse yyWwwd} {
+ clock scan {00 W48 Saturday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.63 {parse yyWwwd} {
+ clock scan {00 W48 6} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.64 {parse yyWwwd} {
+ clock scan {00 W48 6} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.65 {parse yyWwwd} {
+ clock scan {00 W48 vi} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.66 {parse yyWwwd} {
+ clock scan {00 W48 vi} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.67 {parse yyWwwd} {
+ clock scan {00 W52 Sun} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.68 {parse yyWwwd} {
+ clock scan {00 W52 Sunday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.69 {parse yyWwwd} {
+ clock scan {00 W52 7} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.70 {parse yyWwwd} {
+ clock scan {00 W52 0} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.71 {parse yyWwwd} {
+ clock scan {00 W52 vii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.72 {parse yyWwwd} {
+ clock scan {00 W52 ?} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.73 {parse yyWwwd} {
+ clock scan {01 W01 Tue} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.74 {parse yyWwwd} {
+ clock scan {01 W01 Tuesday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.75 {parse yyWwwd} {
+ clock scan {01 W01 2} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.76 {parse yyWwwd} {
+ clock scan {01 W01 2} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.77 {parse yyWwwd} {
+ clock scan {01 W01 ii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.78 {parse yyWwwd} {
+ clock scan {01 W01 ii} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.79 {parse yyWwwd} {
+ clock scan {01 W05 Wed} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.80 {parse yyWwwd} {
+ clock scan {01 W05 Wednesday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.81 {parse yyWwwd} {
+ clock scan {01 W05 3} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.82 {parse yyWwwd} {
+ clock scan {01 W05 3} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.83 {parse yyWwwd} {
+ clock scan {01 W05 iii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.84 {parse yyWwwd} {
+ clock scan {01 W05 iii} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.85 {parse yyWwwd} {
+ clock scan {01 W48 Sun} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.86 {parse yyWwwd} {
+ clock scan {01 W48 Sunday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.87 {parse yyWwwd} {
+ clock scan {01 W48 7} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.88 {parse yyWwwd} {
+ clock scan {01 W48 0} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.89 {parse yyWwwd} {
+ clock scan {01 W48 vii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.90 {parse yyWwwd} {
+ clock scan {01 W48 ?} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.91 {parse yyWwwd} {
+ clock scan {02 W01 Mon} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-17.92 {parse yyWwwd} {
+ clock scan {02 W01 Monday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-17.93 {parse yyWwwd} {
+ clock scan {02 W01 1} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-17.94 {parse yyWwwd} {
+ clock scan {02 W01 1} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-17.95 {parse yyWwwd} {
+ clock scan {02 W01 i} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-17.96 {parse yyWwwd} {
+ clock scan {02 W01 i} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 1009756800
+# END testcases17
+
+# Test precedence of yyWwwd
+
+test clock-18.1 {seconds take precedence over yyWwwd} {
+ list [clock scan {0 00W014} -format {%s %gW%V%u} -gmt true] \
+ [clock scan {00W014 0} -format {%gW%V%u %s} -gmt true]
+} {0 0}
+test clock-18.2 {julian day takes precedence over yyddd} {
+ list [clock scan {2440588 00W014} -format {%J %gW%V%u} -gmt true] \
+ [clock scan {00W014 2440588} -format {%gW%V%u %J} -gmt true]
+} {0 0}
+test clock-18.3 {yyWwwd precedence below yyyymmdd} {
+ list [clock scan {19700101 00W014} -format {%Y%m%d %gW%V%u} -gmt true] \
+ [clock scan {00W014 19700101} -format {%gW%V%u %Y%m%d} -gmt true]
+} {0 0}
+test clock-18.4 {yyWwwd precedence below yyyyddd} {
+ list [clock scan {1970001 00W014} -format {%Y%j %gW%V%u} -gmt true] \
+ [clock scan {00W014 1970001} -format {%gW%V%u %Y%j} -gmt true]
+} {0 0}
+
+# BEGIN testcases19
+
+# Test parsing of mmdd
+
+test clock-19.1 {parse mmdd} {
+ clock scan {Jan 02} -format {%b %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.2 {parse mmdd} {
+ clock scan {Jan ii} -format {%b %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.3 {parse mmdd} {
+ clock scan {Jan 2} -format {%b %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.4 {parse mmdd} {
+ clock scan {Jan ii} -format {%b %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.5 {parse mmdd} {
+ clock scan {January 02} -format {%B %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.6 {parse mmdd} {
+ clock scan {January ii} -format {%B %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.7 {parse mmdd} {
+ clock scan {January 2} -format {%B %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.8 {parse mmdd} {
+ clock scan {January ii} -format {%B %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.9 {parse mmdd} {
+ clock scan {Jan 02} -format {%h %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.10 {parse mmdd} {
+ clock scan {Jan ii} -format {%h %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.11 {parse mmdd} {
+ clock scan {Jan 2} -format {%h %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.12 {parse mmdd} {
+ clock scan {Jan ii} -format {%h %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.13 {parse mmdd} {
+ clock scan {01 02} -format {%m %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.14 {parse mmdd} {
+ clock scan {01 ii} -format {%m %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.15 {parse mmdd} {
+ clock scan {01 2} -format {%m %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.16 {parse mmdd} {
+ clock scan {01 ii} -format {%m %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.17 {parse mmdd} {
+ clock scan {i 02} -format {%Om %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.18 {parse mmdd} {
+ clock scan {i ii} -format {%Om %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.19 {parse mmdd} {
+ clock scan {i 2} -format {%Om %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.20 {parse mmdd} {
+ clock scan {i ii} -format {%Om %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.21 {parse mmdd} {
+ clock scan { 1 02} -format {%N %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.22 {parse mmdd} {
+ clock scan { 1 ii} -format {%N %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.23 {parse mmdd} {
+ clock scan { 1 2} -format {%N %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.24 {parse mmdd} {
+ clock scan { 1 ii} -format {%N %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.25 {parse mmdd} {
+ clock scan {Jan 31} -format {%b %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.26 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%b %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.27 {parse mmdd} {
+ clock scan {Jan 31} -format {%b %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.28 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%b %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.29 {parse mmdd} {
+ clock scan {January 31} -format {%B %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.30 {parse mmdd} {
+ clock scan {January xxxi} -format {%B %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.31 {parse mmdd} {
+ clock scan {January 31} -format {%B %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.32 {parse mmdd} {
+ clock scan {January xxxi} -format {%B %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.33 {parse mmdd} {
+ clock scan {Jan 31} -format {%h %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.34 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%h %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.35 {parse mmdd} {
+ clock scan {Jan 31} -format {%h %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.36 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%h %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.37 {parse mmdd} {
+ clock scan {01 31} -format {%m %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.38 {parse mmdd} {
+ clock scan {01 xxxi} -format {%m %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.39 {parse mmdd} {
+ clock scan {01 31} -format {%m %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.40 {parse mmdd} {
+ clock scan {01 xxxi} -format {%m %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.41 {parse mmdd} {
+ clock scan {i 31} -format {%Om %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.42 {parse mmdd} {
+ clock scan {i xxxi} -format {%Om %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.43 {parse mmdd} {
+ clock scan {i 31} -format {%Om %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.44 {parse mmdd} {
+ clock scan {i xxxi} -format {%Om %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.45 {parse mmdd} {
+ clock scan { 1 31} -format {%N %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.46 {parse mmdd} {
+ clock scan { 1 xxxi} -format {%N %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.47 {parse mmdd} {
+ clock scan { 1 31} -format {%N %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.48 {parse mmdd} {
+ clock scan { 1 xxxi} -format {%N %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.49 {parse mmdd} {
+ clock scan {Dec 02} -format {%b %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.50 {parse mmdd} {
+ clock scan {Dec ii} -format {%b %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.51 {parse mmdd} {
+ clock scan {Dec 2} -format {%b %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.52 {parse mmdd} {
+ clock scan {Dec ii} -format {%b %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.53 {parse mmdd} {
+ clock scan {December 02} -format {%B %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.54 {parse mmdd} {
+ clock scan {December ii} -format {%B %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.55 {parse mmdd} {
+ clock scan {December 2} -format {%B %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.56 {parse mmdd} {
+ clock scan {December ii} -format {%B %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.57 {parse mmdd} {
+ clock scan {Dec 02} -format {%h %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.58 {parse mmdd} {
+ clock scan {Dec ii} -format {%h %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.59 {parse mmdd} {
+ clock scan {Dec 2} -format {%h %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.60 {parse mmdd} {
+ clock scan {Dec ii} -format {%h %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.61 {parse mmdd} {
+ clock scan {12 02} -format {%m %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.62 {parse mmdd} {
+ clock scan {12 ii} -format {%m %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.63 {parse mmdd} {
+ clock scan {12 2} -format {%m %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.64 {parse mmdd} {
+ clock scan {12 ii} -format {%m %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.65 {parse mmdd} {
+ clock scan {xii 02} -format {%Om %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.66 {parse mmdd} {
+ clock scan {xii ii} -format {%Om %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.67 {parse mmdd} {
+ clock scan {xii 2} -format {%Om %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.68 {parse mmdd} {
+ clock scan {xii ii} -format {%Om %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.69 {parse mmdd} {
+ clock scan {12 02} -format {%N %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.70 {parse mmdd} {
+ clock scan {12 ii} -format {%N %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.71 {parse mmdd} {
+ clock scan {12 2} -format {%N %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.72 {parse mmdd} {
+ clock scan {12 ii} -format {%N %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.73 {parse mmdd} {
+ clock scan {Dec 31} -format {%b %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.74 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%b %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.75 {parse mmdd} {
+ clock scan {Dec 31} -format {%b %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.76 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%b %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.77 {parse mmdd} {
+ clock scan {December 31} -format {%B %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.78 {parse mmdd} {
+ clock scan {December xxxi} -format {%B %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.79 {parse mmdd} {
+ clock scan {December 31} -format {%B %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.80 {parse mmdd} {
+ clock scan {December xxxi} -format {%B %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.81 {parse mmdd} {
+ clock scan {Dec 31} -format {%h %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.82 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%h %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.83 {parse mmdd} {
+ clock scan {Dec 31} -format {%h %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.84 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%h %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.85 {parse mmdd} {
+ clock scan {12 31} -format {%m %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.86 {parse mmdd} {
+ clock scan {12 xxxi} -format {%m %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.87 {parse mmdd} {
+ clock scan {12 31} -format {%m %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.88 {parse mmdd} {
+ clock scan {12 xxxi} -format {%m %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.89 {parse mmdd} {
+ clock scan {xii 31} -format {%Om %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.90 {parse mmdd} {
+ clock scan {xii xxxi} -format {%Om %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.91 {parse mmdd} {
+ clock scan {xii 31} -format {%Om %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.92 {parse mmdd} {
+ clock scan {xii xxxi} -format {%Om %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.93 {parse mmdd} {
+ clock scan {12 31} -format {%N %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.94 {parse mmdd} {
+ clock scan {12 xxxi} -format {%N %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.95 {parse mmdd} {
+ clock scan {12 31} -format {%N %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.96 {parse mmdd} {
+ clock scan {12 xxxi} -format {%N %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.97 {parse mmdd} {
+ clock scan {Jan 02} -format {%b %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.98 {parse mmdd} {
+ clock scan {Jan ii} -format {%b %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.99 {parse mmdd} {
+ clock scan {Jan 2} -format {%b %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.100 {parse mmdd} {
+ clock scan {Jan ii} -format {%b %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.101 {parse mmdd} {
+ clock scan {January 02} -format {%B %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.102 {parse mmdd} {
+ clock scan {January ii} -format {%B %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.103 {parse mmdd} {
+ clock scan {January 2} -format {%B %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.104 {parse mmdd} {
+ clock scan {January ii} -format {%B %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.105 {parse mmdd} {
+ clock scan {Jan 02} -format {%h %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.106 {parse mmdd} {
+ clock scan {Jan ii} -format {%h %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.107 {parse mmdd} {
+ clock scan {Jan 2} -format {%h %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.108 {parse mmdd} {
+ clock scan {Jan ii} -format {%h %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.109 {parse mmdd} {
+ clock scan {01 02} -format {%m %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.110 {parse mmdd} {
+ clock scan {01 ii} -format {%m %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.111 {parse mmdd} {
+ clock scan {01 2} -format {%m %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.112 {parse mmdd} {
+ clock scan {01 ii} -format {%m %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.113 {parse mmdd} {
+ clock scan {i 02} -format {%Om %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.114 {parse mmdd} {
+ clock scan {i ii} -format {%Om %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.115 {parse mmdd} {
+ clock scan {i 2} -format {%Om %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.116 {parse mmdd} {
+ clock scan {i ii} -format {%Om %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.117 {parse mmdd} {
+ clock scan { 1 02} -format {%N %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.118 {parse mmdd} {
+ clock scan { 1 ii} -format {%N %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.119 {parse mmdd} {
+ clock scan { 1 2} -format {%N %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.120 {parse mmdd} {
+ clock scan { 1 ii} -format {%N %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.121 {parse mmdd} {
+ clock scan {Jan 31} -format {%b %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.122 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%b %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.123 {parse mmdd} {
+ clock scan {Jan 31} -format {%b %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.124 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%b %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.125 {parse mmdd} {
+ clock scan {January 31} -format {%B %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.126 {parse mmdd} {
+ clock scan {January xxxi} -format {%B %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.127 {parse mmdd} {
+ clock scan {January 31} -format {%B %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.128 {parse mmdd} {
+ clock scan {January xxxi} -format {%B %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.129 {parse mmdd} {
+ clock scan {Jan 31} -format {%h %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.130 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%h %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.131 {parse mmdd} {
+ clock scan {Jan 31} -format {%h %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.132 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%h %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.133 {parse mmdd} {
+ clock scan {01 31} -format {%m %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.134 {parse mmdd} {
+ clock scan {01 xxxi} -format {%m %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.135 {parse mmdd} {
+ clock scan {01 31} -format {%m %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.136 {parse mmdd} {
+ clock scan {01 xxxi} -format {%m %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.137 {parse mmdd} {
+ clock scan {i 31} -format {%Om %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.138 {parse mmdd} {
+ clock scan {i xxxi} -format {%Om %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.139 {parse mmdd} {
+ clock scan {i 31} -format {%Om %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.140 {parse mmdd} {
+ clock scan {i xxxi} -format {%Om %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.141 {parse mmdd} {
+ clock scan { 1 31} -format {%N %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.142 {parse mmdd} {
+ clock scan { 1 xxxi} -format {%N %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.143 {parse mmdd} {
+ clock scan { 1 31} -format {%N %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.144 {parse mmdd} {
+ clock scan { 1 xxxi} -format {%N %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.145 {parse mmdd} {
+ clock scan {Dec 02} -format {%b %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.146 {parse mmdd} {
+ clock scan {Dec ii} -format {%b %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.147 {parse mmdd} {
+ clock scan {Dec 2} -format {%b %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.148 {parse mmdd} {
+ clock scan {Dec ii} -format {%b %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.149 {parse mmdd} {
+ clock scan {December 02} -format {%B %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.150 {parse mmdd} {
+ clock scan {December ii} -format {%B %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.151 {parse mmdd} {
+ clock scan {December 2} -format {%B %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.152 {parse mmdd} {
+ clock scan {December ii} -format {%B %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.153 {parse mmdd} {
+ clock scan {Dec 02} -format {%h %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.154 {parse mmdd} {
+ clock scan {Dec ii} -format {%h %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.155 {parse mmdd} {
+ clock scan {Dec 2} -format {%h %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.156 {parse mmdd} {
+ clock scan {Dec ii} -format {%h %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.157 {parse mmdd} {
+ clock scan {12 02} -format {%m %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.158 {parse mmdd} {
+ clock scan {12 ii} -format {%m %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.159 {parse mmdd} {
+ clock scan {12 2} -format {%m %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.160 {parse mmdd} {
+ clock scan {12 ii} -format {%m %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.161 {parse mmdd} {
+ clock scan {xii 02} -format {%Om %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.162 {parse mmdd} {
+ clock scan {xii ii} -format {%Om %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.163 {parse mmdd} {
+ clock scan {xii 2} -format {%Om %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.164 {parse mmdd} {
+ clock scan {xii ii} -format {%Om %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.165 {parse mmdd} {
+ clock scan {12 02} -format {%N %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.166 {parse mmdd} {
+ clock scan {12 ii} -format {%N %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.167 {parse mmdd} {
+ clock scan {12 2} -format {%N %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.168 {parse mmdd} {
+ clock scan {12 ii} -format {%N %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.169 {parse mmdd} {
+ clock scan {Dec 31} -format {%b %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.170 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%b %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.171 {parse mmdd} {
+ clock scan {Dec 31} -format {%b %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.172 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%b %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.173 {parse mmdd} {
+ clock scan {December 31} -format {%B %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.174 {parse mmdd} {
+ clock scan {December xxxi} -format {%B %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.175 {parse mmdd} {
+ clock scan {December 31} -format {%B %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.176 {parse mmdd} {
+ clock scan {December xxxi} -format {%B %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.177 {parse mmdd} {
+ clock scan {Dec 31} -format {%h %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.178 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%h %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.179 {parse mmdd} {
+ clock scan {Dec 31} -format {%h %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.180 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%h %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.181 {parse mmdd} {
+ clock scan {12 31} -format {%m %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.182 {parse mmdd} {
+ clock scan {12 xxxi} -format {%m %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.183 {parse mmdd} {
+ clock scan {12 31} -format {%m %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.184 {parse mmdd} {
+ clock scan {12 xxxi} -format {%m %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.185 {parse mmdd} {
+ clock scan {xii 31} -format {%Om %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.186 {parse mmdd} {
+ clock scan {xii xxxi} -format {%Om %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.187 {parse mmdd} {
+ clock scan {xii 31} -format {%Om %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.188 {parse mmdd} {
+ clock scan {xii xxxi} -format {%Om %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.189 {parse mmdd} {
+ clock scan {12 31} -format {%N %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.190 {parse mmdd} {
+ clock scan {12 xxxi} -format {%N %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.191 {parse mmdd} {
+ clock scan {12 31} -format {%N %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.192 {parse mmdd} {
+ clock scan {12 xxxi} -format {%N %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.193 {parse mmdd} {
+ clock scan {Jan 02} -format {%b %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.194 {parse mmdd} {
+ clock scan {Jan ii} -format {%b %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.195 {parse mmdd} {
+ clock scan {Jan 2} -format {%b %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.196 {parse mmdd} {
+ clock scan {Jan ii} -format {%b %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.197 {parse mmdd} {
+ clock scan {January 02} -format {%B %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.198 {parse mmdd} {
+ clock scan {January ii} -format {%B %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.199 {parse mmdd} {
+ clock scan {January 2} -format {%B %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.200 {parse mmdd} {
+ clock scan {January ii} -format {%B %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.201 {parse mmdd} {
+ clock scan {Jan 02} -format {%h %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.202 {parse mmdd} {
+ clock scan {Jan ii} -format {%h %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.203 {parse mmdd} {
+ clock scan {Jan 2} -format {%h %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.204 {parse mmdd} {
+ clock scan {Jan ii} -format {%h %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.205 {parse mmdd} {
+ clock scan {01 02} -format {%m %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.206 {parse mmdd} {
+ clock scan {01 ii} -format {%m %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.207 {parse mmdd} {
+ clock scan {01 2} -format {%m %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.208 {parse mmdd} {
+ clock scan {01 ii} -format {%m %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.209 {parse mmdd} {
+ clock scan {i 02} -format {%Om %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.210 {parse mmdd} {
+ clock scan {i ii} -format {%Om %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.211 {parse mmdd} {
+ clock scan {i 2} -format {%Om %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.212 {parse mmdd} {
+ clock scan {i ii} -format {%Om %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.213 {parse mmdd} {
+ clock scan { 1 02} -format {%N %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.214 {parse mmdd} {
+ clock scan { 1 ii} -format {%N %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.215 {parse mmdd} {
+ clock scan { 1 2} -format {%N %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.216 {parse mmdd} {
+ clock scan { 1 ii} -format {%N %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.217 {parse mmdd} {
+ clock scan {Jan 31} -format {%b %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.218 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%b %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.219 {parse mmdd} {
+ clock scan {Jan 31} -format {%b %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.220 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%b %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.221 {parse mmdd} {
+ clock scan {January 31} -format {%B %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.222 {parse mmdd} {
+ clock scan {January xxxi} -format {%B %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.223 {parse mmdd} {
+ clock scan {January 31} -format {%B %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.224 {parse mmdd} {
+ clock scan {January xxxi} -format {%B %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.225 {parse mmdd} {
+ clock scan {Jan 31} -format {%h %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.226 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%h %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.227 {parse mmdd} {
+ clock scan {Jan 31} -format {%h %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.228 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%h %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.229 {parse mmdd} {
+ clock scan {01 31} -format {%m %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.230 {parse mmdd} {
+ clock scan {01 xxxi} -format {%m %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.231 {parse mmdd} {
+ clock scan {01 31} -format {%m %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.232 {parse mmdd} {
+ clock scan {01 xxxi} -format {%m %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.233 {parse mmdd} {
+ clock scan {i 31} -format {%Om %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.234 {parse mmdd} {
+ clock scan {i xxxi} -format {%Om %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.235 {parse mmdd} {
+ clock scan {i 31} -format {%Om %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.236 {parse mmdd} {
+ clock scan {i xxxi} -format {%Om %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.237 {parse mmdd} {
+ clock scan { 1 31} -format {%N %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.238 {parse mmdd} {
+ clock scan { 1 xxxi} -format {%N %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.239 {parse mmdd} {
+ clock scan { 1 31} -format {%N %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.240 {parse mmdd} {
+ clock scan { 1 xxxi} -format {%N %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.241 {parse mmdd} {
+ clock scan {Dec 02} -format {%b %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.242 {parse mmdd} {
+ clock scan {Dec ii} -format {%b %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.243 {parse mmdd} {
+ clock scan {Dec 2} -format {%b %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.244 {parse mmdd} {
+ clock scan {Dec ii} -format {%b %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.245 {parse mmdd} {
+ clock scan {December 02} -format {%B %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.246 {parse mmdd} {
+ clock scan {December ii} -format {%B %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.247 {parse mmdd} {
+ clock scan {December 2} -format {%B %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.248 {parse mmdd} {
+ clock scan {December ii} -format {%B %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.249 {parse mmdd} {
+ clock scan {Dec 02} -format {%h %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.250 {parse mmdd} {
+ clock scan {Dec ii} -format {%h %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.251 {parse mmdd} {
+ clock scan {Dec 2} -format {%h %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.252 {parse mmdd} {
+ clock scan {Dec ii} -format {%h %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.253 {parse mmdd} {
+ clock scan {12 02} -format {%m %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.254 {parse mmdd} {
+ clock scan {12 ii} -format {%m %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.255 {parse mmdd} {
+ clock scan {12 2} -format {%m %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.256 {parse mmdd} {
+ clock scan {12 ii} -format {%m %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.257 {parse mmdd} {
+ clock scan {xii 02} -format {%Om %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.258 {parse mmdd} {
+ clock scan {xii ii} -format {%Om %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.259 {parse mmdd} {
+ clock scan {xii 2} -format {%Om %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.260 {parse mmdd} {
+ clock scan {xii ii} -format {%Om %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.261 {parse mmdd} {
+ clock scan {12 02} -format {%N %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.262 {parse mmdd} {
+ clock scan {12 ii} -format {%N %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.263 {parse mmdd} {
+ clock scan {12 2} -format {%N %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.264 {parse mmdd} {
+ clock scan {12 ii} -format {%N %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.265 {parse mmdd} {
+ clock scan {Dec 31} -format {%b %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.266 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%b %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.267 {parse mmdd} {
+ clock scan {Dec 31} -format {%b %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.268 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%b %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.269 {parse mmdd} {
+ clock scan {December 31} -format {%B %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.270 {parse mmdd} {
+ clock scan {December xxxi} -format {%B %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.271 {parse mmdd} {
+ clock scan {December 31} -format {%B %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.272 {parse mmdd} {
+ clock scan {December xxxi} -format {%B %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.273 {parse mmdd} {
+ clock scan {Dec 31} -format {%h %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.274 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%h %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.275 {parse mmdd} {
+ clock scan {Dec 31} -format {%h %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.276 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%h %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.277 {parse mmdd} {
+ clock scan {12 31} -format {%m %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.278 {parse mmdd} {
+ clock scan {12 xxxi} -format {%m %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.279 {parse mmdd} {
+ clock scan {12 31} -format {%m %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.280 {parse mmdd} {
+ clock scan {12 xxxi} -format {%m %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.281 {parse mmdd} {
+ clock scan {xii 31} -format {%Om %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.282 {parse mmdd} {
+ clock scan {xii xxxi} -format {%Om %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.283 {parse mmdd} {
+ clock scan {xii 31} -format {%Om %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.284 {parse mmdd} {
+ clock scan {xii xxxi} -format {%Om %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.285 {parse mmdd} {
+ clock scan {12 31} -format {%N %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.286 {parse mmdd} {
+ clock scan {12 xxxi} -format {%N %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.287 {parse mmdd} {
+ clock scan {12 31} -format {%N %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.288 {parse mmdd} {
+ clock scan {12 xxxi} -format {%N %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.289 {parse mmdd} {
+ clock scan {Jan 02} -format {%b %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.290 {parse mmdd} {
+ clock scan {Jan ii} -format {%b %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.291 {parse mmdd} {
+ clock scan {Jan 2} -format {%b %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.292 {parse mmdd} {
+ clock scan {Jan ii} -format {%b %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.293 {parse mmdd} {
+ clock scan {January 02} -format {%B %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.294 {parse mmdd} {
+ clock scan {January ii} -format {%B %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.295 {parse mmdd} {
+ clock scan {January 2} -format {%B %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.296 {parse mmdd} {
+ clock scan {January ii} -format {%B %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.297 {parse mmdd} {
+ clock scan {Jan 02} -format {%h %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.298 {parse mmdd} {
+ clock scan {Jan ii} -format {%h %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.299 {parse mmdd} {
+ clock scan {Jan 2} -format {%h %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.300 {parse mmdd} {
+ clock scan {Jan ii} -format {%h %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.301 {parse mmdd} {
+ clock scan {01 02} -format {%m %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.302 {parse mmdd} {
+ clock scan {01 ii} -format {%m %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.303 {parse mmdd} {
+ clock scan {01 2} -format {%m %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.304 {parse mmdd} {
+ clock scan {01 ii} -format {%m %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.305 {parse mmdd} {
+ clock scan {i 02} -format {%Om %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.306 {parse mmdd} {
+ clock scan {i ii} -format {%Om %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.307 {parse mmdd} {
+ clock scan {i 2} -format {%Om %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.308 {parse mmdd} {
+ clock scan {i ii} -format {%Om %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.309 {parse mmdd} {
+ clock scan { 1 02} -format {%N %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.310 {parse mmdd} {
+ clock scan { 1 ii} -format {%N %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.311 {parse mmdd} {
+ clock scan { 1 2} -format {%N %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.312 {parse mmdd} {
+ clock scan { 1 ii} -format {%N %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.313 {parse mmdd} {
+ clock scan {Jan 31} -format {%b %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.314 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%b %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.315 {parse mmdd} {
+ clock scan {Jan 31} -format {%b %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.316 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%b %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.317 {parse mmdd} {
+ clock scan {January 31} -format {%B %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.318 {parse mmdd} {
+ clock scan {January xxxi} -format {%B %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.319 {parse mmdd} {
+ clock scan {January 31} -format {%B %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.320 {parse mmdd} {
+ clock scan {January xxxi} -format {%B %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.321 {parse mmdd} {
+ clock scan {Jan 31} -format {%h %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.322 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%h %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.323 {parse mmdd} {
+ clock scan {Jan 31} -format {%h %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.324 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%h %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.325 {parse mmdd} {
+ clock scan {01 31} -format {%m %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.326 {parse mmdd} {
+ clock scan {01 xxxi} -format {%m %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.327 {parse mmdd} {
+ clock scan {01 31} -format {%m %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.328 {parse mmdd} {
+ clock scan {01 xxxi} -format {%m %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.329 {parse mmdd} {
+ clock scan {i 31} -format {%Om %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.330 {parse mmdd} {
+ clock scan {i xxxi} -format {%Om %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.331 {parse mmdd} {
+ clock scan {i 31} -format {%Om %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.332 {parse mmdd} {
+ clock scan {i xxxi} -format {%Om %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.333 {parse mmdd} {
+ clock scan { 1 31} -format {%N %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.334 {parse mmdd} {
+ clock scan { 1 xxxi} -format {%N %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.335 {parse mmdd} {
+ clock scan { 1 31} -format {%N %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.336 {parse mmdd} {
+ clock scan { 1 xxxi} -format {%N %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.337 {parse mmdd} {
+ clock scan {Dec 02} -format {%b %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.338 {parse mmdd} {
+ clock scan {Dec ii} -format {%b %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.339 {parse mmdd} {
+ clock scan {Dec 2} -format {%b %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.340 {parse mmdd} {
+ clock scan {Dec ii} -format {%b %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.341 {parse mmdd} {
+ clock scan {December 02} -format {%B %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.342 {parse mmdd} {
+ clock scan {December ii} -format {%B %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.343 {parse mmdd} {
+ clock scan {December 2} -format {%B %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.344 {parse mmdd} {
+ clock scan {December ii} -format {%B %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.345 {parse mmdd} {
+ clock scan {Dec 02} -format {%h %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.346 {parse mmdd} {
+ clock scan {Dec ii} -format {%h %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.347 {parse mmdd} {
+ clock scan {Dec 2} -format {%h %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.348 {parse mmdd} {
+ clock scan {Dec ii} -format {%h %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.349 {parse mmdd} {
+ clock scan {12 02} -format {%m %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.350 {parse mmdd} {
+ clock scan {12 ii} -format {%m %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.351 {parse mmdd} {
+ clock scan {12 2} -format {%m %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.352 {parse mmdd} {
+ clock scan {12 ii} -format {%m %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.353 {parse mmdd} {
+ clock scan {xii 02} -format {%Om %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.354 {parse mmdd} {
+ clock scan {xii ii} -format {%Om %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.355 {parse mmdd} {
+ clock scan {xii 2} -format {%Om %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.356 {parse mmdd} {
+ clock scan {xii ii} -format {%Om %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.357 {parse mmdd} {
+ clock scan {12 02} -format {%N %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.358 {parse mmdd} {
+ clock scan {12 ii} -format {%N %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.359 {parse mmdd} {
+ clock scan {12 2} -format {%N %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.360 {parse mmdd} {
+ clock scan {12 ii} -format {%N %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.361 {parse mmdd} {
+ clock scan {Dec 31} -format {%b %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.362 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%b %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.363 {parse mmdd} {
+ clock scan {Dec 31} -format {%b %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.364 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%b %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.365 {parse mmdd} {
+ clock scan {December 31} -format {%B %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.366 {parse mmdd} {
+ clock scan {December xxxi} -format {%B %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.367 {parse mmdd} {
+ clock scan {December 31} -format {%B %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.368 {parse mmdd} {
+ clock scan {December xxxi} -format {%B %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.369 {parse mmdd} {
+ clock scan {Dec 31} -format {%h %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.370 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%h %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.371 {parse mmdd} {
+ clock scan {Dec 31} -format {%h %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.372 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%h %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.373 {parse mmdd} {
+ clock scan {12 31} -format {%m %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.374 {parse mmdd} {
+ clock scan {12 xxxi} -format {%m %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.375 {parse mmdd} {
+ clock scan {12 31} -format {%m %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.376 {parse mmdd} {
+ clock scan {12 xxxi} -format {%m %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.377 {parse mmdd} {
+ clock scan {xii 31} -format {%Om %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.378 {parse mmdd} {
+ clock scan {xii xxxi} -format {%Om %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.379 {parse mmdd} {
+ clock scan {xii 31} -format {%Om %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.380 {parse mmdd} {
+ clock scan {xii xxxi} -format {%Om %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.381 {parse mmdd} {
+ clock scan {12 31} -format {%N %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.382 {parse mmdd} {
+ clock scan {12 xxxi} -format {%N %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.383 {parse mmdd} {
+ clock scan {12 31} -format {%N %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.384 {parse mmdd} {
+ clock scan {12 xxxi} -format {%N %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+# END testcases19
+
+test clock-20.1 {seconds take precedence over mmdd} {
+ list [clock scan {0 0201} -format {%s %m%d} -gmt true -base 0] \
+ [clock scan {0201 0} -format {%m%d %s} -gmt true -base 0]
+} {0 0}
+test clock-20.2 {julian day takes precedence over yyddd} {
+ list [clock scan {2440588 0201} -format {%J %m%d} -gmt true -base 0] \
+ [clock scan {0201 2440588} -format {%m%d %J} -gmt true -base 0]
+} {0 0}
+test clock-20.3 {yyyyWwwd over mmdd} {
+ list [clock scan {1970W014 0201} -format {%GW%V%u %m%d} -gmt true -base 0] \
+ [clock scan {0201 1970W014} -format {%m%d %GW%V%u} -gmt true -base 0]
+} {0 0}
+test clock-20.4 {yyWwwd over mmdd} {
+ list [clock scan {70W014 0201} -format {%gW%V%u %m%d} -gmt true -base 0] \
+ [clock scan {0201 70W014} -format {%m%d %gW%V%u} -gmt true -base 0]
+} {0 0}
+
+# Test parsing of ddd
+
+test clock-21.1 {parse ddd} {
+ clock scan {001} -format {%j} -locale en_US_roman -gmt 1 -base 0
+} 0
+test clock-21.2 {parse ddd} {
+ clock scan {365} -format {%j} -locale en_US_roman -gmt 1 -base 0
+} 31449600
+test clock-21.3 {parse ddd} {
+ clock scan {001} -format {%j} -locale en_US_roman -gmt 1 -base 31536000
+} 31536000
+test clock-21.4 {parse ddd} {
+ clock scan {365} -format {%j} -locale en_US_roman -gmt 1 -base 31536000
+} 62985600
+test clock-21.5 {seconds take precedence over ddd} {
+ list [clock scan {0 002} -format {%s %j} -gmt true -base 0] \
+ [clock scan {002 0} -format {%j %s} -gmt true -base 0]
+} {0 0}
+test clock-21.6 {julian day takes precedence over yyddd} {
+ list [clock scan {2440588 002} -format {%J %j} -gmt true -base 0] \
+ [clock scan {002 2440588} -format {%j %J} -gmt true -base 0]
+} {0 0}
+test clock-21.7 {yyyyWwwd over ddd} {
+ list [clock scan {1970W014 002} -format {%GW%V%u %j} -gmt true -base 0] \
+ [clock scan {002 1970W014} -format {%j %GW%V%u} -gmt true -base 0]
+} {0 0}
+test clock-21.8 {yyWwwd over ddd} {
+ list [clock scan {70W014 002} -format {%gW%V%u %j} -gmt true -base 0] \
+ [clock scan {002 70W014} -format {%j %gW%V%u} -gmt true -base 0]
+} {0 0}
+
+# BEGIN testcases22
+
+# Test parsing of Wwwd
+
+test clock-22.1 {parse Wwwd} {
+ clock scan {W09 Sun} -format {W%V %a} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.2 {parse Wwwd} {
+ clock scan {W09 Sunday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.3 {parse Wwwd} {
+ clock scan {W09 7} -format {W%V %u} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.4 {parse Wwwd} {
+ clock scan {W09 0} -format {W%V %w} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.5 {parse Wwwd} {
+ clock scan {W09 vii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.6 {parse Wwwd} {
+ clock scan {W09 ?} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.7 {parse Wwwd} {
+ clock scan {W14 Tue} -format {W%V %a} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.8 {parse Wwwd} {
+ clock scan {W14 Tuesday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.9 {parse Wwwd} {
+ clock scan {W14 2} -format {W%V %u} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.10 {parse Wwwd} {
+ clock scan {W14 2} -format {W%V %w} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.11 {parse Wwwd} {
+ clock scan {W14 ii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.12 {parse Wwwd} {
+ clock scan {W14 ii} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.13 {parse Wwwd} {
+ clock scan {W40 Thu} -format {W%V %a} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.14 {parse Wwwd} {
+ clock scan {W40 Thursday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.15 {parse Wwwd} {
+ clock scan {W40 4} -format {W%V %u} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.16 {parse Wwwd} {
+ clock scan {W40 4} -format {W%V %w} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.17 {parse Wwwd} {
+ clock scan {W40 iv} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.18 {parse Wwwd} {
+ clock scan {W40 iv} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.19 {parse Wwwd} {
+ clock scan {W44 Sat} -format {W%V %a} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.20 {parse Wwwd} {
+ clock scan {W44 Saturday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.21 {parse Wwwd} {
+ clock scan {W44 6} -format {W%V %u} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.22 {parse Wwwd} {
+ clock scan {W44 6} -format {W%V %w} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.23 {parse Wwwd} {
+ clock scan {W44 vi} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.24 {parse Wwwd} {
+ clock scan {W44 vi} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.25 {parse Wwwd} {
+ clock scan {W09 Mon} -format {W%V %a} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.26 {parse Wwwd} {
+ clock scan {W09 Monday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.27 {parse Wwwd} {
+ clock scan {W09 1} -format {W%V %u} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.28 {parse Wwwd} {
+ clock scan {W09 1} -format {W%V %w} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.29 {parse Wwwd} {
+ clock scan {W09 i} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.30 {parse Wwwd} {
+ clock scan {W09 i} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.31 {parse Wwwd} {
+ clock scan {W13 Wed} -format {W%V %a} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.32 {parse Wwwd} {
+ clock scan {W13 Wednesday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.33 {parse Wwwd} {
+ clock scan {W13 3} -format {W%V %u} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.34 {parse Wwwd} {
+ clock scan {W13 3} -format {W%V %w} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.35 {parse Wwwd} {
+ clock scan {W13 iii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.36 {parse Wwwd} {
+ clock scan {W13 iii} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.37 {parse Wwwd} {
+ clock scan {W39 Fri} -format {W%V %a} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.38 {parse Wwwd} {
+ clock scan {W39 Friday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.39 {parse Wwwd} {
+ clock scan {W39 5} -format {W%V %u} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.40 {parse Wwwd} {
+ clock scan {W39 5} -format {W%V %w} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.41 {parse Wwwd} {
+ clock scan {W39 v} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.42 {parse Wwwd} {
+ clock scan {W39 v} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.43 {parse Wwwd} {
+ clock scan {W43 Sun} -format {W%V %a} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.44 {parse Wwwd} {
+ clock scan {W43 Sunday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.45 {parse Wwwd} {
+ clock scan {W43 7} -format {W%V %u} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.46 {parse Wwwd} {
+ clock scan {W43 0} -format {W%V %w} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.47 {parse Wwwd} {
+ clock scan {W43 vii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.48 {parse Wwwd} {
+ clock scan {W43 ?} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.49 {parse Wwwd} {
+ clock scan {W09 Wed} -format {W%V %a} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.50 {parse Wwwd} {
+ clock scan {W09 Wednesday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.51 {parse Wwwd} {
+ clock scan {W09 3} -format {W%V %u} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.52 {parse Wwwd} {
+ clock scan {W09 3} -format {W%V %w} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.53 {parse Wwwd} {
+ clock scan {W09 iii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.54 {parse Wwwd} {
+ clock scan {W09 iii} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.55 {parse Wwwd} {
+ clock scan {W13 Fri} -format {W%V %a} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.56 {parse Wwwd} {
+ clock scan {W13 Friday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.57 {parse Wwwd} {
+ clock scan {W13 5} -format {W%V %u} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.58 {parse Wwwd} {
+ clock scan {W13 5} -format {W%V %w} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.59 {parse Wwwd} {
+ clock scan {W13 v} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.60 {parse Wwwd} {
+ clock scan {W13 v} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.61 {parse Wwwd} {
+ clock scan {W39 Sun} -format {W%V %a} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.62 {parse Wwwd} {
+ clock scan {W39 Sunday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.63 {parse Wwwd} {
+ clock scan {W39 7} -format {W%V %u} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.64 {parse Wwwd} {
+ clock scan {W39 0} -format {W%V %w} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.65 {parse Wwwd} {
+ clock scan {W39 vii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.66 {parse Wwwd} {
+ clock scan {W39 ?} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.67 {parse Wwwd} {
+ clock scan {W44 Tue} -format {W%V %a} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.68 {parse Wwwd} {
+ clock scan {W44 Tuesday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.69 {parse Wwwd} {
+ clock scan {W44 2} -format {W%V %u} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.70 {parse Wwwd} {
+ clock scan {W44 2} -format {W%V %w} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.71 {parse Wwwd} {
+ clock scan {W44 ii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.72 {parse Wwwd} {
+ clock scan {W44 ii} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.73 {parse Wwwd} {
+ clock scan {W09 Thu} -format {W%V %a} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.74 {parse Wwwd} {
+ clock scan {W09 Thursday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.75 {parse Wwwd} {
+ clock scan {W09 4} -format {W%V %u} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.76 {parse Wwwd} {
+ clock scan {W09 4} -format {W%V %w} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.77 {parse Wwwd} {
+ clock scan {W09 iv} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.78 {parse Wwwd} {
+ clock scan {W09 iv} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.79 {parse Wwwd} {
+ clock scan {W13 Sat} -format {W%V %a} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.80 {parse Wwwd} {
+ clock scan {W13 Saturday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.81 {parse Wwwd} {
+ clock scan {W13 6} -format {W%V %u} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.82 {parse Wwwd} {
+ clock scan {W13 6} -format {W%V %w} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.83 {parse Wwwd} {
+ clock scan {W13 vi} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.84 {parse Wwwd} {
+ clock scan {W13 vi} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.85 {parse Wwwd} {
+ clock scan {W40 Mon} -format {W%V %a} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.86 {parse Wwwd} {
+ clock scan {W40 Monday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.87 {parse Wwwd} {
+ clock scan {W40 1} -format {W%V %u} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.88 {parse Wwwd} {
+ clock scan {W40 1} -format {W%V %w} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.89 {parse Wwwd} {
+ clock scan {W40 i} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.90 {parse Wwwd} {
+ clock scan {W40 i} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.91 {parse Wwwd} {
+ clock scan {W44 Wed} -format {W%V %a} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+test clock-22.92 {parse Wwwd} {
+ clock scan {W44 Wednesday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+test clock-22.93 {parse Wwwd} {
+ clock scan {W44 3} -format {W%V %u} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+test clock-22.94 {parse Wwwd} {
+ clock scan {W44 3} -format {W%V %w} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+test clock-22.95 {parse Wwwd} {
+ clock scan {W44 iii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+test clock-22.96 {parse Wwwd} {
+ clock scan {W44 iii} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+# END testcases22
+
+# Test precedence of Wwwd
+test clock-23.1 {seconds take precedence over Wwwd} {
+ list [clock scan {0 W024} -format {%s W%V%u} -gmt true -base 0] \
+ [clock scan {W024 0} -format {W%V%u %s} -gmt true -base 0]
+} {0 0}
+test clock-23.2 {julian day takes precedence over Wwwd} {
+ list [clock scan {2440588 W024} -format {%J W%V%u} -gmt true -base 0] \
+ [clock scan {W024 2440588} -format {W%V%u %J} -gmt true -base 0]
+} {0 0}
+test clock-23.3 {Wwwd precedence below yyyymmdd} {
+ list [clock scan {19700101 W014} -format {%Y%m%d W%V%u} -gmt true -base 0] \
+ [clock scan {W014 19700101} -format {W%V%u %Y%m%d} -gmt true -base 0]
+} {0 0}
+test clock-23.4 {Wwwd precedence below yyyyddd} {
+ list [clock scan {1970001 W014} -format {%Y%j W%V%u} -gmt true -base 0] \
+ [clock scan {W014 1970001} -format {W%V%u %Y%j} -gmt true -base 0]
+} {0 0}
+test clock-23.5 {Wwwd precedence below yymmdd} {
+ list [clock scan {700101 W014} -format {%y%m%d W%V%u} -gmt true -base 0] \
+ [clock scan {W014 700101} -format {W%V%u %y%m%d} -gmt true -base 0]
+} {0 0}
+test clock-23.6 {Wwwd precedence below yyddd} {
+ list [clock scan {70001 W014} -format {%y%j W%V%u} -gmt true -base 0] \
+ [clock scan {W014 70001} -format {W%V%u %y%j} -gmt true -base 0]
+} {0 0}
+
+# BEGIN testcases24
+
+# Test parsing of naked day-of-month
+
+test clock-24.1 {parse naked day of month} {
+ clock scan 02 -format %d -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-24.2 {parse naked day of month} {
+ clock scan ii -format %Od -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-24.3 {parse naked day of month} {
+ clock scan { 2} -format %e -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-24.4 {parse naked day of month} {
+ clock scan ii -format %Oe -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-24.5 {parse naked day of month} {
+ clock scan 28 -format %d -locale en_US_roman -base 0 -gmt 1
+} 2332800
+test clock-24.6 {parse naked day of month} {
+ clock scan xxviii -format %Od -locale en_US_roman -base 0 -gmt 1
+} 2332800
+test clock-24.7 {parse naked day of month} {
+ clock scan 28 -format %e -locale en_US_roman -base 0 -gmt 1
+} 2332800
+test clock-24.8 {parse naked day of month} {
+ clock scan xxviii -format %Oe -locale en_US_roman -base 0 -gmt 1
+} 2332800
+test clock-24.9 {parse naked day of month} {
+ clock scan 02 -format %d -locale en_US_roman -base 28857600 -gmt 1
+} 28944000
+test clock-24.10 {parse naked day of month} {
+ clock scan ii -format %Od -locale en_US_roman -base 28857600 -gmt 1
+} 28944000
+test clock-24.11 {parse naked day of month} {
+ clock scan { 2} -format %e -locale en_US_roman -base 28857600 -gmt 1
+} 28944000
+test clock-24.12 {parse naked day of month} {
+ clock scan ii -format %Oe -locale en_US_roman -base 28857600 -gmt 1
+} 28944000
+test clock-24.13 {parse naked day of month} {
+ clock scan 28 -format %d -locale en_US_roman -base 28857600 -gmt 1
+} 31190400
+test clock-24.14 {parse naked day of month} {
+ clock scan xxviii -format %Od -locale en_US_roman -base 28857600 -gmt 1
+} 31190400
+test clock-24.15 {parse naked day of month} {
+ clock scan 28 -format %e -locale en_US_roman -base 28857600 -gmt 1
+} 31190400
+test clock-24.16 {parse naked day of month} {
+ clock scan xxviii -format %Oe -locale en_US_roman -base 28857600 -gmt 1
+} 31190400
+test clock-24.17 {parse naked day of month} {
+ clock scan 02 -format %d -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-24.18 {parse naked day of month} {
+ clock scan ii -format %Od -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-24.19 {parse naked day of month} {
+ clock scan { 2} -format %e -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-24.20 {parse naked day of month} {
+ clock scan ii -format %Oe -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-24.21 {parse naked day of month} {
+ clock scan 28 -format %d -locale en_US_roman -base 946684800 -gmt 1
+} 949017600
+test clock-24.22 {parse naked day of month} {
+ clock scan xxviii -format %Od -locale en_US_roman -base 946684800 -gmt 1
+} 949017600
+test clock-24.23 {parse naked day of month} {
+ clock scan 28 -format %e -locale en_US_roman -base 946684800 -gmt 1
+} 949017600
+test clock-24.24 {parse naked day of month} {
+ clock scan xxviii -format %Oe -locale en_US_roman -base 946684800 -gmt 1
+} 949017600
+test clock-24.25 {parse naked day of month} {
+ clock scan 02 -format %d -locale en_US_roman -base 975628800 -gmt 1
+} 975715200
+test clock-24.26 {parse naked day of month} {
+ clock scan ii -format %Od -locale en_US_roman -base 975628800 -gmt 1
+} 975715200
+test clock-24.27 {parse naked day of month} {
+ clock scan { 2} -format %e -locale en_US_roman -base 975628800 -gmt 1
+} 975715200
+test clock-24.28 {parse naked day of month} {
+ clock scan ii -format %Oe -locale en_US_roman -base 975628800 -gmt 1
+} 975715200
+test clock-24.29 {parse naked day of month} {
+ clock scan 28 -format %d -locale en_US_roman -base 975628800 -gmt 1
+} 977961600
+test clock-24.30 {parse naked day of month} {
+ clock scan xxviii -format %Od -locale en_US_roman -base 975628800 -gmt 1
+} 977961600
+test clock-24.31 {parse naked day of month} {
+ clock scan 28 -format %e -locale en_US_roman -base 975628800 -gmt 1
+} 977961600
+test clock-24.32 {parse naked day of month} {
+ clock scan xxviii -format %Oe -locale en_US_roman -base 975628800 -gmt 1
+} 977961600
+# END testcases24
+
+test clock-25.1 {seconds take precedence over dd} {
+ list [clock scan {0 02} -format {%s %d} -gmt true -base 0] \
+ [clock scan {02 0} -format {%d %s} -gmt true -base 0]
+} {0 0}
+test clock-25.2 {julian day takes precedence over dd} {
+ list [clock scan {2440588 02} -format {%J %d} -gmt true -base 0] \
+ [clock scan {02 2440588} -format {%d %J} -gmt true -base 0]
+} {0 0}
+test clock-25.3 {yyyyddd over dd} {
+ list [clock scan {1970001 02} -format {%Y%j %d} -gmt true -base 0] \
+ [clock scan {02 1970001} -format {%d %Y%j} -gmt true -base 0]
+} {0 0}
+test clock-25.4 {yyyyWwwd over dd} {
+ list [clock scan {1970W014 02} -format {%GW%V%u %d} -gmt true -base 0] \
+ [clock scan {02 1970W014} -format {%d %GW%V%u} -gmt true -base 0]
+} {0 0}
+test clock-25.5 {yyWwwd over dd} {
+ list [clock scan {70W014 02} -format {%gW%V%u %d} -gmt true -base 0] \
+ [clock scan {02 70W014} -format {%d %gW%V%u} -gmt true -base 0]
+} {0 0}
+test clock-25.6 {yyddd over dd} {
+ list [clock scan {70001 02} -format {%y%j %d} -gmt true -base 0] \
+ [clock scan {02 70001} -format {%d %y%j} -gmt true -base 0]
+} {0 0}
+test clock-25.7 {ddd over dd} {
+ list [clock scan {001 02} -format {%j %d} -gmt true -base 0] \
+ [clock scan {02 001} -format {%d %j} -gmt true -base 0]
+} {0 0}
+
+# BEGIN testcases26
+
+# Test parsing of naked day of week
+
+test clock-26.1 {parse naked day of week} {
+ clock scan Mon -format %a -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.2 {parse naked day of week} {
+ clock scan Monday -format %A -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.3 {parse naked day of week} {
+ clock scan 1 -format %u -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.4 {parse naked day of week} {
+ clock scan 1 -format %w -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.5 {parse naked day of week} {
+ clock scan i -format %Ou -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.6 {parse naked day of week} {
+ clock scan i -format %Ow -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.7 {parse naked day of week} {
+ clock scan Sun -format %a -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.8 {parse naked day of week} {
+ clock scan Sunday -format %A -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.9 {parse naked day of week} {
+ clock scan 7 -format %u -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.10 {parse naked day of week} {
+ clock scan 0 -format %w -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.11 {parse naked day of week} {
+ clock scan vii -format %Ou -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.12 {parse naked day of week} {
+ clock scan ? -format %Ow -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.13 {parse naked day of week} {
+ clock scan Mon -format %a -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.14 {parse naked day of week} {
+ clock scan Monday -format %A -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.15 {parse naked day of week} {
+ clock scan 1 -format %u -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.16 {parse naked day of week} {
+ clock scan 1 -format %w -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.17 {parse naked day of week} {
+ clock scan i -format %Ou -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.18 {parse naked day of week} {
+ clock scan i -format %Ow -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.19 {parse naked day of week} {
+ clock scan Sun -format %a -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.20 {parse naked day of week} {
+ clock scan Sunday -format %A -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.21 {parse naked day of week} {
+ clock scan 7 -format %u -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.22 {parse naked day of week} {
+ clock scan 0 -format %w -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.23 {parse naked day of week} {
+ clock scan vii -format %Ou -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.24 {parse naked day of week} {
+ clock scan ? -format %Ow -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.25 {parse naked day of week} {
+ clock scan Mon -format %a -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.26 {parse naked day of week} {
+ clock scan Monday -format %A -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.27 {parse naked day of week} {
+ clock scan 1 -format %u -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.28 {parse naked day of week} {
+ clock scan 1 -format %w -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.29 {parse naked day of week} {
+ clock scan i -format %Ou -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.30 {parse naked day of week} {
+ clock scan i -format %Ow -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.31 {parse naked day of week} {
+ clock scan Sun -format %a -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.32 {parse naked day of week} {
+ clock scan Sunday -format %A -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.33 {parse naked day of week} {
+ clock scan 7 -format %u -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.34 {parse naked day of week} {
+ clock scan 0 -format %w -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.35 {parse naked day of week} {
+ clock scan vii -format %Ou -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.36 {parse naked day of week} {
+ clock scan ? -format %Ow -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.37 {parse naked day of week} {
+ clock scan Mon -format %a -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.38 {parse naked day of week} {
+ clock scan Monday -format %A -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.39 {parse naked day of week} {
+ clock scan 1 -format %u -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.40 {parse naked day of week} {
+ clock scan 1 -format %w -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.41 {parse naked day of week} {
+ clock scan i -format %Ou -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.42 {parse naked day of week} {
+ clock scan i -format %Ow -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.43 {parse naked day of week} {
+ clock scan Sun -format %a -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+test clock-26.44 {parse naked day of week} {
+ clock scan Sunday -format %A -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+test clock-26.45 {parse naked day of week} {
+ clock scan 7 -format %u -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+test clock-26.46 {parse naked day of week} {
+ clock scan 0 -format %w -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+test clock-26.47 {parse naked day of week} {
+ clock scan vii -format %Ou -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+test clock-26.48 {parse naked day of week} {
+ clock scan ? -format %Ow -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+# END testcases26
+
+test clock-27.1 {seconds take precedence over naked weekday} {
+ list [clock scan {0 1} -format {%s %u} -gmt true -base 0] \
+ [clock scan {1 0} -format {%u %s} -gmt true -base 0]
+} {0 0}
+test clock-27.2 {julian day takes precedence over naked weekday} {
+ list [clock scan {2440588 1} -format {%J %u} -gmt true -base 0] \
+ [clock scan {1 2440588} -format {%u %J} -gmt true -base 0]
+} {0 0}
+test clock-27.3 {yyyymmdd over naked weekday} {
+ list [clock scan {19700101 1} -format {%Y%m%d %u} -gmt true -base 0] \
+ [clock scan {1 19700101} -format {%u %Y%m%d} -gmt true -base 0]
+} {0 0}
+test clock-27.4 {yyyyddd over naked weekday} {
+ list [clock scan {1970001 1} -format {%Y%j %u} -gmt true -base 0] \
+ [clock scan {1 1970001} -format {%u %Y%j} -gmt true -base 0]
+} {0 0}
+test clock-27.5 {yymmdd over naked weekday} {
+ list [clock scan {700101 1} -format {%y%m%d %u} -gmt true -base 0] \
+ [clock scan {1 700101} -format {%u %y%m%d} -gmt true -base 0]
+} {0 0}
+test clock-27.6 {yyddd over naked weekday} {
+ list [clock scan {70001 1} -format {%y%j %u} -gmt true -base 0] \
+ [clock scan {1 70001} -format {%u %y%j} -gmt true -base 0]
+} {0 0}
+test clock-27.7 {mmdd over naked weekday} {
+ list [clock scan {0101 1} -format {%m%d %u} -gmt true -base 0] \
+ [clock scan {1 0101} -format {%u %m%d} -gmt true -base 0]
+} {0 0}
+test clock-27.8 {ddd over naked weekday} {
+ list [clock scan {001 1} -format {%j %u} -gmt true -base 0] \
+ [clock scan {1 001} -format {%u %j} -gmt true -base 0]
+} {0 0}
+test clock-27.9 {naked day of month over naked weekday} {
+ list [clock scan {01 1} -format {%d %u} -gmt true -base 0] \
+ [clock scan {1 01} -format {%u %d} -gmt true -base 0]
+} {0 0}
+
+test clock-28.1 {base date} {
+ clock scan {} -format {} -gmt true -base 1234567890
+} 1234483200
+
+# BEGIN testcases29
+
+# Test parsing of time of day
+
+test clock-29.1 {time parsing} {
+ clock scan {2440588 00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H }
+} 0
+test clock-29.2 {time parsing} {
+ clock scan {2440588 00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 0
+test clock-29.3 {time parsing} {
+ clock scan {2440588 00:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 0
+test clock-29.4 {time parsing} {
+ clock scan {2440588 00:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 0
+test clock-29.5 {time parsing} {
+ clock scan {2440588 00:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 0
+test clock-29.6 {time parsing} {
+ clock scan {2440588 0 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k }
+} 0
+test clock-29.7 {time parsing} {
+ clock scan {2440588 0:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 0
+test clock-29.8 {time parsing} {
+ clock scan {2440588 0:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 0
+test clock-29.9 {time parsing} {
+ clock scan {2440588 0:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 0
+test clock-29.10 {time parsing} {
+ clock scan {2440588 0:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 0
+test clock-29.11 {time parsing} {
+ clock scan {2440588 ? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH }
+} 0
+test clock-29.12 {time parsing} {
+ clock scan {2440588 ?:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 0
+test clock-29.13 {time parsing} {
+ clock scan {2440588 ?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 0
+test clock-29.14 {time parsing} {
+ clock scan {2440588 ?:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 0
+test clock-29.15 {time parsing} {
+ clock scan {2440588 ?:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 0
+test clock-29.16 {time parsing} {
+ clock scan {2440588 ? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok }
+} 0
+test clock-29.17 {time parsing} {
+ clock scan {2440588 ?:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 0
+test clock-29.18 {time parsing} {
+ clock scan {2440588 ?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 0
+test clock-29.19 {time parsing} {
+ clock scan {2440588 ?:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 0
+test clock-29.20 {time parsing} {
+ clock scan {2440588 ?:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 0
+test clock-29.21 {time parsing} {
+ clock scan {2440588 12 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %p}
+} 0
+test clock-29.22 {time parsing} {
+ clock scan {2440588 12:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 0
+test clock-29.23 {time parsing} {
+ clock scan {2440588 12:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 0
+test clock-29.24 {time parsing} {
+ clock scan {2440588 12:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 0
+test clock-29.25 {time parsing} {
+ clock scan {2440588 12:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 0
+test clock-29.26 {time parsing} {
+ clock scan {2440588 12 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %p}
+} 0
+test clock-29.27 {time parsing} {
+ clock scan {2440588 12:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 0
+test clock-29.28 {time parsing} {
+ clock scan {2440588 12:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 0
+test clock-29.29 {time parsing} {
+ clock scan {2440588 12:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 0
+test clock-29.30 {time parsing} {
+ clock scan {2440588 12:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 0
+test clock-29.31 {time parsing} {
+ clock scan {2440588 xii AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %p}
+} 0
+test clock-29.32 {time parsing} {
+ clock scan {2440588 xii:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 0
+test clock-29.33 {time parsing} {
+ clock scan {2440588 xii:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 0
+test clock-29.34 {time parsing} {
+ clock scan {2440588 xii:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 0
+test clock-29.35 {time parsing} {
+ clock scan {2440588 xii:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 0
+test clock-29.36 {time parsing} {
+ clock scan {2440588 xii AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %p}
+} 0
+test clock-29.37 {time parsing} {
+ clock scan {2440588 xii:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 0
+test clock-29.38 {time parsing} {
+ clock scan {2440588 xii:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 0
+test clock-29.39 {time parsing} {
+ clock scan {2440588 xii:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 0
+test clock-29.40 {time parsing} {
+ clock scan {2440588 xii:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 0
+test clock-29.41 {time parsing} {
+ clock scan {2440588 12 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %P}
+} 0
+test clock-29.42 {time parsing} {
+ clock scan {2440588 12:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 0
+test clock-29.43 {time parsing} {
+ clock scan {2440588 12:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 0
+test clock-29.44 {time parsing} {
+ clock scan {2440588 12:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 0
+test clock-29.45 {time parsing} {
+ clock scan {2440588 12:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 0
+test clock-29.46 {time parsing} {
+ clock scan {2440588 12 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %P}
+} 0
+test clock-29.47 {time parsing} {
+ clock scan {2440588 12:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 0
+test clock-29.48 {time parsing} {
+ clock scan {2440588 12:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 0
+test clock-29.49 {time parsing} {
+ clock scan {2440588 12:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 0
+test clock-29.50 {time parsing} {
+ clock scan {2440588 12:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 0
+test clock-29.51 {time parsing} {
+ clock scan {2440588 xii am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %P}
+} 0
+test clock-29.52 {time parsing} {
+ clock scan {2440588 xii:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 0
+test clock-29.53 {time parsing} {
+ clock scan {2440588 xii:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 0
+test clock-29.54 {time parsing} {
+ clock scan {2440588 xii:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 0
+test clock-29.55 {time parsing} {
+ clock scan {2440588 xii:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 0
+test clock-29.56 {time parsing} {
+ clock scan {2440588 xii am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %P}
+} 0
+test clock-29.57 {time parsing} {
+ clock scan {2440588 xii:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 0
+test clock-29.58 {time parsing} {
+ clock scan {2440588 xii:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 0
+test clock-29.59 {time parsing} {
+ clock scan {2440588 xii:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 0
+test clock-29.60 {time parsing} {
+ clock scan {2440588 xii:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 0
+test clock-29.61 {time parsing} {
+ clock scan {2440588 00:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 1
+test clock-29.62 {time parsing} {
+ clock scan {2440588 00:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 1
+test clock-29.63 {time parsing} {
+ clock scan {2440588 0:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 1
+test clock-29.64 {time parsing} {
+ clock scan {2440588 0:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 1
+test clock-29.65 {time parsing} {
+ clock scan {2440588 ?:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 1
+test clock-29.66 {time parsing} {
+ clock scan {2440588 ?:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 1
+test clock-29.67 {time parsing} {
+ clock scan {2440588 ?:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 1
+test clock-29.68 {time parsing} {
+ clock scan {2440588 ?:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 1
+test clock-29.69 {time parsing} {
+ clock scan {2440588 12:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 1
+test clock-29.70 {time parsing} {
+ clock scan {2440588 12:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 1
+test clock-29.71 {time parsing} {
+ clock scan {2440588 12:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 1
+test clock-29.72 {time parsing} {
+ clock scan {2440588 12:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 1
+test clock-29.73 {time parsing} {
+ clock scan {2440588 xii:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 1
+test clock-29.74 {time parsing} {
+ clock scan {2440588 xii:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 1
+test clock-29.75 {time parsing} {
+ clock scan {2440588 xii:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 1
+test clock-29.76 {time parsing} {
+ clock scan {2440588 xii:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 1
+test clock-29.77 {time parsing} {
+ clock scan {2440588 12:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 1
+test clock-29.78 {time parsing} {
+ clock scan {2440588 12:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 1
+test clock-29.79 {time parsing} {
+ clock scan {2440588 12:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 1
+test clock-29.80 {time parsing} {
+ clock scan {2440588 12:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 1
+test clock-29.81 {time parsing} {
+ clock scan {2440588 xii:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 1
+test clock-29.82 {time parsing} {
+ clock scan {2440588 xii:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 1
+test clock-29.83 {time parsing} {
+ clock scan {2440588 xii:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 1
+test clock-29.84 {time parsing} {
+ clock scan {2440588 xii:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 1
+test clock-29.85 {time parsing} {
+ clock scan {2440588 00:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 59
+test clock-29.86 {time parsing} {
+ clock scan {2440588 00:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 59
+test clock-29.87 {time parsing} {
+ clock scan {2440588 0:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 59
+test clock-29.88 {time parsing} {
+ clock scan {2440588 0:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 59
+test clock-29.89 {time parsing} {
+ clock scan {2440588 ?:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 59
+test clock-29.90 {time parsing} {
+ clock scan {2440588 ?:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 59
+test clock-29.91 {time parsing} {
+ clock scan {2440588 ?:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 59
+test clock-29.92 {time parsing} {
+ clock scan {2440588 ?:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 59
+test clock-29.93 {time parsing} {
+ clock scan {2440588 12:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 59
+test clock-29.94 {time parsing} {
+ clock scan {2440588 12:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 59
+test clock-29.95 {time parsing} {
+ clock scan {2440588 12:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 59
+test clock-29.96 {time parsing} {
+ clock scan {2440588 12:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 59
+test clock-29.97 {time parsing} {
+ clock scan {2440588 xii:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 59
+test clock-29.98 {time parsing} {
+ clock scan {2440588 xii:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 59
+test clock-29.99 {time parsing} {
+ clock scan {2440588 xii:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 59
+test clock-29.100 {time parsing} {
+ clock scan {2440588 xii:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 59
+test clock-29.101 {time parsing} {
+ clock scan {2440588 12:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 59
+test clock-29.102 {time parsing} {
+ clock scan {2440588 12:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 59
+test clock-29.103 {time parsing} {
+ clock scan {2440588 12:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 59
+test clock-29.104 {time parsing} {
+ clock scan {2440588 12:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 59
+test clock-29.105 {time parsing} {
+ clock scan {2440588 xii:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 59
+test clock-29.106 {time parsing} {
+ clock scan {2440588 xii:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 59
+test clock-29.107 {time parsing} {
+ clock scan {2440588 xii:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 59
+test clock-29.108 {time parsing} {
+ clock scan {2440588 xii:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 59
+test clock-29.109 {time parsing} {
+ clock scan {2440588 00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 60
+test clock-29.110 {time parsing} {
+ clock scan {2440588 00:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 60
+test clock-29.111 {time parsing} {
+ clock scan {2440588 00:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 60
+test clock-29.112 {time parsing} {
+ clock scan {2440588 00:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 60
+test clock-29.113 {time parsing} {
+ clock scan {2440588 0:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 60
+test clock-29.114 {time parsing} {
+ clock scan {2440588 0:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 60
+test clock-29.115 {time parsing} {
+ clock scan {2440588 0:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 60
+test clock-29.116 {time parsing} {
+ clock scan {2440588 0:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 60
+test clock-29.117 {time parsing} {
+ clock scan {2440588 ?:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 60
+test clock-29.118 {time parsing} {
+ clock scan {2440588 ?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 60
+test clock-29.119 {time parsing} {
+ clock scan {2440588 ?:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 60
+test clock-29.120 {time parsing} {
+ clock scan {2440588 ?:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 60
+test clock-29.121 {time parsing} {
+ clock scan {2440588 ?:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 60
+test clock-29.122 {time parsing} {
+ clock scan {2440588 ?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 60
+test clock-29.123 {time parsing} {
+ clock scan {2440588 ?:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 60
+test clock-29.124 {time parsing} {
+ clock scan {2440588 ?:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 60
+test clock-29.125 {time parsing} {
+ clock scan {2440588 12:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 60
+test clock-29.126 {time parsing} {
+ clock scan {2440588 12:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 60
+test clock-29.127 {time parsing} {
+ clock scan {2440588 12:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 60
+test clock-29.128 {time parsing} {
+ clock scan {2440588 12:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 60
+test clock-29.129 {time parsing} {
+ clock scan {2440588 12:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 60
+test clock-29.130 {time parsing} {
+ clock scan {2440588 12:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 60
+test clock-29.131 {time parsing} {
+ clock scan {2440588 12:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 60
+test clock-29.132 {time parsing} {
+ clock scan {2440588 12:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 60
+test clock-29.133 {time parsing} {
+ clock scan {2440588 xii:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 60
+test clock-29.134 {time parsing} {
+ clock scan {2440588 xii:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 60
+test clock-29.135 {time parsing} {
+ clock scan {2440588 xii:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 60
+test clock-29.136 {time parsing} {
+ clock scan {2440588 xii:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 60
+test clock-29.137 {time parsing} {
+ clock scan {2440588 xii:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 60
+test clock-29.138 {time parsing} {
+ clock scan {2440588 xii:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 60
+test clock-29.139 {time parsing} {
+ clock scan {2440588 xii:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 60
+test clock-29.140 {time parsing} {
+ clock scan {2440588 xii:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 60
+test clock-29.141 {time parsing} {
+ clock scan {2440588 12:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 60
+test clock-29.142 {time parsing} {
+ clock scan {2440588 12:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 60
+test clock-29.143 {time parsing} {
+ clock scan {2440588 12:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 60
+test clock-29.144 {time parsing} {
+ clock scan {2440588 12:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 60
+test clock-29.145 {time parsing} {
+ clock scan {2440588 12:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 60
+test clock-29.146 {time parsing} {
+ clock scan {2440588 12:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 60
+test clock-29.147 {time parsing} {
+ clock scan {2440588 12:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 60
+test clock-29.148 {time parsing} {
+ clock scan {2440588 12:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 60
+test clock-29.149 {time parsing} {
+ clock scan {2440588 xii:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 60
+test clock-29.150 {time parsing} {
+ clock scan {2440588 xii:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 60
+test clock-29.151 {time parsing} {
+ clock scan {2440588 xii:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 60
+test clock-29.152 {time parsing} {
+ clock scan {2440588 xii:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 60
+test clock-29.153 {time parsing} {
+ clock scan {2440588 xii:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 60
+test clock-29.154 {time parsing} {
+ clock scan {2440588 xii:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 60
+test clock-29.155 {time parsing} {
+ clock scan {2440588 xii:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 60
+test clock-29.156 {time parsing} {
+ clock scan {2440588 xii:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 60
+test clock-29.157 {time parsing} {
+ clock scan {2440588 00:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 61
+test clock-29.158 {time parsing} {
+ clock scan {2440588 00:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 61
+test clock-29.159 {time parsing} {
+ clock scan {2440588 0:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 61
+test clock-29.160 {time parsing} {
+ clock scan {2440588 0:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 61
+test clock-29.161 {time parsing} {
+ clock scan {2440588 ?:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 61
+test clock-29.162 {time parsing} {
+ clock scan {2440588 ?:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 61
+test clock-29.163 {time parsing} {
+ clock scan {2440588 ?:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 61
+test clock-29.164 {time parsing} {
+ clock scan {2440588 ?:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 61
+test clock-29.165 {time parsing} {
+ clock scan {2440588 12:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 61
+test clock-29.166 {time parsing} {
+ clock scan {2440588 12:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 61
+test clock-29.167 {time parsing} {
+ clock scan {2440588 12:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 61
+test clock-29.168 {time parsing} {
+ clock scan {2440588 12:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 61
+test clock-29.169 {time parsing} {
+ clock scan {2440588 xii:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 61
+test clock-29.170 {time parsing} {
+ clock scan {2440588 xii:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 61
+test clock-29.171 {time parsing} {
+ clock scan {2440588 xii:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 61
+test clock-29.172 {time parsing} {
+ clock scan {2440588 xii:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 61
+test clock-29.173 {time parsing} {
+ clock scan {2440588 12:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 61
+test clock-29.174 {time parsing} {
+ clock scan {2440588 12:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 61
+test clock-29.175 {time parsing} {
+ clock scan {2440588 12:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 61
+test clock-29.176 {time parsing} {
+ clock scan {2440588 12:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 61
+test clock-29.177 {time parsing} {
+ clock scan {2440588 xii:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 61
+test clock-29.178 {time parsing} {
+ clock scan {2440588 xii:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 61
+test clock-29.179 {time parsing} {
+ clock scan {2440588 xii:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 61
+test clock-29.180 {time parsing} {
+ clock scan {2440588 xii:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 61
+test clock-29.181 {time parsing} {
+ clock scan {2440588 00:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 119
+test clock-29.182 {time parsing} {
+ clock scan {2440588 00:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 119
+test clock-29.183 {time parsing} {
+ clock scan {2440588 0:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 119
+test clock-29.184 {time parsing} {
+ clock scan {2440588 0:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 119
+test clock-29.185 {time parsing} {
+ clock scan {2440588 ?:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 119
+test clock-29.186 {time parsing} {
+ clock scan {2440588 ?:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 119
+test clock-29.187 {time parsing} {
+ clock scan {2440588 ?:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 119
+test clock-29.188 {time parsing} {
+ clock scan {2440588 ?:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 119
+test clock-29.189 {time parsing} {
+ clock scan {2440588 12:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 119
+test clock-29.190 {time parsing} {
+ clock scan {2440588 12:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 119
+test clock-29.191 {time parsing} {
+ clock scan {2440588 12:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 119
+test clock-29.192 {time parsing} {
+ clock scan {2440588 12:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 119
+test clock-29.193 {time parsing} {
+ clock scan {2440588 xii:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 119
+test clock-29.194 {time parsing} {
+ clock scan {2440588 xii:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 119
+test clock-29.195 {time parsing} {
+ clock scan {2440588 xii:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 119
+test clock-29.196 {time parsing} {
+ clock scan {2440588 xii:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 119
+test clock-29.197 {time parsing} {
+ clock scan {2440588 12:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 119
+test clock-29.198 {time parsing} {
+ clock scan {2440588 12:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 119
+test clock-29.199 {time parsing} {
+ clock scan {2440588 12:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 119
+test clock-29.200 {time parsing} {
+ clock scan {2440588 12:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 119
+test clock-29.201 {time parsing} {
+ clock scan {2440588 xii:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 119
+test clock-29.202 {time parsing} {
+ clock scan {2440588 xii:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 119
+test clock-29.203 {time parsing} {
+ clock scan {2440588 xii:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 119
+test clock-29.204 {time parsing} {
+ clock scan {2440588 xii:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 119
+test clock-29.205 {time parsing} {
+ clock scan {2440588 00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 3540
+test clock-29.206 {time parsing} {
+ clock scan {2440588 00:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 3540
+test clock-29.207 {time parsing} {
+ clock scan {2440588 00:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3540
+test clock-29.208 {time parsing} {
+ clock scan {2440588 00:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3540
+test clock-29.209 {time parsing} {
+ clock scan {2440588 0:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 3540
+test clock-29.210 {time parsing} {
+ clock scan {2440588 0:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 3540
+test clock-29.211 {time parsing} {
+ clock scan {2440588 0:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3540
+test clock-29.212 {time parsing} {
+ clock scan {2440588 0:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3540
+test clock-29.213 {time parsing} {
+ clock scan {2440588 ?:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 3540
+test clock-29.214 {time parsing} {
+ clock scan {2440588 ?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 3540
+test clock-29.215 {time parsing} {
+ clock scan {2440588 ?:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3540
+test clock-29.216 {time parsing} {
+ clock scan {2440588 ?:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3540
+test clock-29.217 {time parsing} {
+ clock scan {2440588 ?:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 3540
+test clock-29.218 {time parsing} {
+ clock scan {2440588 ?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 3540
+test clock-29.219 {time parsing} {
+ clock scan {2440588 ?:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3540
+test clock-29.220 {time parsing} {
+ clock scan {2440588 ?:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3540
+test clock-29.221 {time parsing} {
+ clock scan {2440588 12:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 3540
+test clock-29.222 {time parsing} {
+ clock scan {2440588 12:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 3540
+test clock-29.223 {time parsing} {
+ clock scan {2440588 12:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3540
+test clock-29.224 {time parsing} {
+ clock scan {2440588 12:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3540
+test clock-29.225 {time parsing} {
+ clock scan {2440588 12:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 3540
+test clock-29.226 {time parsing} {
+ clock scan {2440588 12:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 3540
+test clock-29.227 {time parsing} {
+ clock scan {2440588 12:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3540
+test clock-29.228 {time parsing} {
+ clock scan {2440588 12:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3540
+test clock-29.229 {time parsing} {
+ clock scan {2440588 xii:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 3540
+test clock-29.230 {time parsing} {
+ clock scan {2440588 xii:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 3540
+test clock-29.231 {time parsing} {
+ clock scan {2440588 xii:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3540
+test clock-29.232 {time parsing} {
+ clock scan {2440588 xii:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3540
+test clock-29.233 {time parsing} {
+ clock scan {2440588 xii:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 3540
+test clock-29.234 {time parsing} {
+ clock scan {2440588 xii:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 3540
+test clock-29.235 {time parsing} {
+ clock scan {2440588 xii:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3540
+test clock-29.236 {time parsing} {
+ clock scan {2440588 xii:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3540
+test clock-29.237 {time parsing} {
+ clock scan {2440588 12:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 3540
+test clock-29.238 {time parsing} {
+ clock scan {2440588 12:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 3540
+test clock-29.239 {time parsing} {
+ clock scan {2440588 12:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3540
+test clock-29.240 {time parsing} {
+ clock scan {2440588 12:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3540
+test clock-29.241 {time parsing} {
+ clock scan {2440588 12:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 3540
+test clock-29.242 {time parsing} {
+ clock scan {2440588 12:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 3540
+test clock-29.243 {time parsing} {
+ clock scan {2440588 12:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3540
+test clock-29.244 {time parsing} {
+ clock scan {2440588 12:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3540
+test clock-29.245 {time parsing} {
+ clock scan {2440588 xii:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 3540
+test clock-29.246 {time parsing} {
+ clock scan {2440588 xii:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 3540
+test clock-29.247 {time parsing} {
+ clock scan {2440588 xii:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3540
+test clock-29.248 {time parsing} {
+ clock scan {2440588 xii:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3540
+test clock-29.249 {time parsing} {
+ clock scan {2440588 xii:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 3540
+test clock-29.250 {time parsing} {
+ clock scan {2440588 xii:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 3540
+test clock-29.251 {time parsing} {
+ clock scan {2440588 xii:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3540
+test clock-29.252 {time parsing} {
+ clock scan {2440588 xii:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3540
+test clock-29.253 {time parsing} {
+ clock scan {2440588 00:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3541
+test clock-29.254 {time parsing} {
+ clock scan {2440588 00:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3541
+test clock-29.255 {time parsing} {
+ clock scan {2440588 0:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3541
+test clock-29.256 {time parsing} {
+ clock scan {2440588 0:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3541
+test clock-29.257 {time parsing} {
+ clock scan {2440588 ?:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3541
+test clock-29.258 {time parsing} {
+ clock scan {2440588 ?:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3541
+test clock-29.259 {time parsing} {
+ clock scan {2440588 ?:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3541
+test clock-29.260 {time parsing} {
+ clock scan {2440588 ?:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3541
+test clock-29.261 {time parsing} {
+ clock scan {2440588 12:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3541
+test clock-29.262 {time parsing} {
+ clock scan {2440588 12:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3541
+test clock-29.263 {time parsing} {
+ clock scan {2440588 12:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3541
+test clock-29.264 {time parsing} {
+ clock scan {2440588 12:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3541
+test clock-29.265 {time parsing} {
+ clock scan {2440588 xii:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3541
+test clock-29.266 {time parsing} {
+ clock scan {2440588 xii:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3541
+test clock-29.267 {time parsing} {
+ clock scan {2440588 xii:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3541
+test clock-29.268 {time parsing} {
+ clock scan {2440588 xii:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3541
+test clock-29.269 {time parsing} {
+ clock scan {2440588 12:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3541
+test clock-29.270 {time parsing} {
+ clock scan {2440588 12:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3541
+test clock-29.271 {time parsing} {
+ clock scan {2440588 12:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3541
+test clock-29.272 {time parsing} {
+ clock scan {2440588 12:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3541
+test clock-29.273 {time parsing} {
+ clock scan {2440588 xii:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3541
+test clock-29.274 {time parsing} {
+ clock scan {2440588 xii:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3541
+test clock-29.275 {time parsing} {
+ clock scan {2440588 xii:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3541
+test clock-29.276 {time parsing} {
+ clock scan {2440588 xii:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3541
+test clock-29.277 {time parsing} {
+ clock scan {2440588 00:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3599
+test clock-29.278 {time parsing} {
+ clock scan {2440588 00:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3599
+test clock-29.279 {time parsing} {
+ clock scan {2440588 0:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3599
+test clock-29.280 {time parsing} {
+ clock scan {2440588 0:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3599
+test clock-29.281 {time parsing} {
+ clock scan {2440588 ?:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3599
+test clock-29.282 {time parsing} {
+ clock scan {2440588 ?:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3599
+test clock-29.283 {time parsing} {
+ clock scan {2440588 ?:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3599
+test clock-29.284 {time parsing} {
+ clock scan {2440588 ?:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3599
+test clock-29.285 {time parsing} {
+ clock scan {2440588 12:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3599
+test clock-29.286 {time parsing} {
+ clock scan {2440588 12:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3599
+test clock-29.287 {time parsing} {
+ clock scan {2440588 12:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3599
+test clock-29.288 {time parsing} {
+ clock scan {2440588 12:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3599
+test clock-29.289 {time parsing} {
+ clock scan {2440588 xii:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3599
+test clock-29.290 {time parsing} {
+ clock scan {2440588 xii:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3599
+test clock-29.291 {time parsing} {
+ clock scan {2440588 xii:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3599
+test clock-29.292 {time parsing} {
+ clock scan {2440588 xii:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3599
+test clock-29.293 {time parsing} {
+ clock scan {2440588 12:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3599
+test clock-29.294 {time parsing} {
+ clock scan {2440588 12:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3599
+test clock-29.295 {time parsing} {
+ clock scan {2440588 12:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3599
+test clock-29.296 {time parsing} {
+ clock scan {2440588 12:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3599
+test clock-29.297 {time parsing} {
+ clock scan {2440588 xii:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3599
+test clock-29.298 {time parsing} {
+ clock scan {2440588 xii:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3599
+test clock-29.299 {time parsing} {
+ clock scan {2440588 xii:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3599
+test clock-29.300 {time parsing} {
+ clock scan {2440588 xii:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3599
+test clock-29.301 {time parsing} {
+ clock scan {2440588 01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H }
+} 3600
+test clock-29.302 {time parsing} {
+ clock scan {2440588 01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 3600
+test clock-29.303 {time parsing} {
+ clock scan {2440588 01:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 3600
+test clock-29.304 {time parsing} {
+ clock scan {2440588 01:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3600
+test clock-29.305 {time parsing} {
+ clock scan {2440588 01:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3600
+test clock-29.306 {time parsing} {
+ clock scan {2440588 1 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k }
+} 3600
+test clock-29.307 {time parsing} {
+ clock scan {2440588 1:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 3600
+test clock-29.308 {time parsing} {
+ clock scan {2440588 1:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 3600
+test clock-29.309 {time parsing} {
+ clock scan {2440588 1:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3600
+test clock-29.310 {time parsing} {
+ clock scan {2440588 1:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3600
+test clock-29.311 {time parsing} {
+ clock scan {2440588 i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH }
+} 3600
+test clock-29.312 {time parsing} {
+ clock scan {2440588 i:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 3600
+test clock-29.313 {time parsing} {
+ clock scan {2440588 i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 3600
+test clock-29.314 {time parsing} {
+ clock scan {2440588 i:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3600
+test clock-29.315 {time parsing} {
+ clock scan {2440588 i:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3600
+test clock-29.316 {time parsing} {
+ clock scan {2440588 i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok }
+} 3600
+test clock-29.317 {time parsing} {
+ clock scan {2440588 i:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 3600
+test clock-29.318 {time parsing} {
+ clock scan {2440588 i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 3600
+test clock-29.319 {time parsing} {
+ clock scan {2440588 i:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3600
+test clock-29.320 {time parsing} {
+ clock scan {2440588 i:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3600
+test clock-29.321 {time parsing} {
+ clock scan {2440588 01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %p}
+} 3600
+test clock-29.322 {time parsing} {
+ clock scan {2440588 01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 3600
+test clock-29.323 {time parsing} {
+ clock scan {2440588 01:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 3600
+test clock-29.324 {time parsing} {
+ clock scan {2440588 01:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3600
+test clock-29.325 {time parsing} {
+ clock scan {2440588 01:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3600
+test clock-29.326 {time parsing} {
+ clock scan {2440588 1 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %p}
+} 3600
+test clock-29.327 {time parsing} {
+ clock scan {2440588 1:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 3600
+test clock-29.328 {time parsing} {
+ clock scan {2440588 1:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 3600
+test clock-29.329 {time parsing} {
+ clock scan {2440588 1:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3600
+test clock-29.330 {time parsing} {
+ clock scan {2440588 1:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3600
+test clock-29.331 {time parsing} {
+ clock scan {2440588 i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %p}
+} 3600
+test clock-29.332 {time parsing} {
+ clock scan {2440588 i:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 3600
+test clock-29.333 {time parsing} {
+ clock scan {2440588 i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 3600
+test clock-29.334 {time parsing} {
+ clock scan {2440588 i:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3600
+test clock-29.335 {time parsing} {
+ clock scan {2440588 i:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3600
+test clock-29.336 {time parsing} {
+ clock scan {2440588 i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %p}
+} 3600
+test clock-29.337 {time parsing} {
+ clock scan {2440588 i:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 3600
+test clock-29.338 {time parsing} {
+ clock scan {2440588 i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 3600
+test clock-29.339 {time parsing} {
+ clock scan {2440588 i:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3600
+test clock-29.340 {time parsing} {
+ clock scan {2440588 i:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3600
+test clock-29.341 {time parsing} {
+ clock scan {2440588 01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %P}
+} 3600
+test clock-29.342 {time parsing} {
+ clock scan {2440588 01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 3600
+test clock-29.343 {time parsing} {
+ clock scan {2440588 01:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 3600
+test clock-29.344 {time parsing} {
+ clock scan {2440588 01:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3600
+test clock-29.345 {time parsing} {
+ clock scan {2440588 01:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3600
+test clock-29.346 {time parsing} {
+ clock scan {2440588 1 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %P}
+} 3600
+test clock-29.347 {time parsing} {
+ clock scan {2440588 1:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 3600
+test clock-29.348 {time parsing} {
+ clock scan {2440588 1:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 3600
+test clock-29.349 {time parsing} {
+ clock scan {2440588 1:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3600
+test clock-29.350 {time parsing} {
+ clock scan {2440588 1:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3600
+test clock-29.351 {time parsing} {
+ clock scan {2440588 i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %P}
+} 3600
+test clock-29.352 {time parsing} {
+ clock scan {2440588 i:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 3600
+test clock-29.353 {time parsing} {
+ clock scan {2440588 i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 3600
+test clock-29.354 {time parsing} {
+ clock scan {2440588 i:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3600
+test clock-29.355 {time parsing} {
+ clock scan {2440588 i:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3600
+test clock-29.356 {time parsing} {
+ clock scan {2440588 i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %P}
+} 3600
+test clock-29.357 {time parsing} {
+ clock scan {2440588 i:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 3600
+test clock-29.358 {time parsing} {
+ clock scan {2440588 i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 3600
+test clock-29.359 {time parsing} {
+ clock scan {2440588 i:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3600
+test clock-29.360 {time parsing} {
+ clock scan {2440588 i:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3600
+test clock-29.361 {time parsing} {
+ clock scan {2440588 01:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3601
+test clock-29.362 {time parsing} {
+ clock scan {2440588 01:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3601
+test clock-29.363 {time parsing} {
+ clock scan {2440588 1:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3601
+test clock-29.364 {time parsing} {
+ clock scan {2440588 1:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3601
+test clock-29.365 {time parsing} {
+ clock scan {2440588 i:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3601
+test clock-29.366 {time parsing} {
+ clock scan {2440588 i:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3601
+test clock-29.367 {time parsing} {
+ clock scan {2440588 i:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3601
+test clock-29.368 {time parsing} {
+ clock scan {2440588 i:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3601
+test clock-29.369 {time parsing} {
+ clock scan {2440588 01:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3601
+test clock-29.370 {time parsing} {
+ clock scan {2440588 01:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3601
+test clock-29.371 {time parsing} {
+ clock scan {2440588 1:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3601
+test clock-29.372 {time parsing} {
+ clock scan {2440588 1:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3601
+test clock-29.373 {time parsing} {
+ clock scan {2440588 i:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3601
+test clock-29.374 {time parsing} {
+ clock scan {2440588 i:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3601
+test clock-29.375 {time parsing} {
+ clock scan {2440588 i:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3601
+test clock-29.376 {time parsing} {
+ clock scan {2440588 i:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3601
+test clock-29.377 {time parsing} {
+ clock scan {2440588 01:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3601
+test clock-29.378 {time parsing} {
+ clock scan {2440588 01:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3601
+test clock-29.379 {time parsing} {
+ clock scan {2440588 1:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3601
+test clock-29.380 {time parsing} {
+ clock scan {2440588 1:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3601
+test clock-29.381 {time parsing} {
+ clock scan {2440588 i:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3601
+test clock-29.382 {time parsing} {
+ clock scan {2440588 i:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3601
+test clock-29.383 {time parsing} {
+ clock scan {2440588 i:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3601
+test clock-29.384 {time parsing} {
+ clock scan {2440588 i:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3601
+test clock-29.385 {time parsing} {
+ clock scan {2440588 01:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3659
+test clock-29.386 {time parsing} {
+ clock scan {2440588 01:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3659
+test clock-29.387 {time parsing} {
+ clock scan {2440588 1:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3659
+test clock-29.388 {time parsing} {
+ clock scan {2440588 1:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3659
+test clock-29.389 {time parsing} {
+ clock scan {2440588 i:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3659
+test clock-29.390 {time parsing} {
+ clock scan {2440588 i:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3659
+test clock-29.391 {time parsing} {
+ clock scan {2440588 i:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3659
+test clock-29.392 {time parsing} {
+ clock scan {2440588 i:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3659
+test clock-29.393 {time parsing} {
+ clock scan {2440588 01:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3659
+test clock-29.394 {time parsing} {
+ clock scan {2440588 01:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3659
+test clock-29.395 {time parsing} {
+ clock scan {2440588 1:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3659
+test clock-29.396 {time parsing} {
+ clock scan {2440588 1:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3659
+test clock-29.397 {time parsing} {
+ clock scan {2440588 i:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3659
+test clock-29.398 {time parsing} {
+ clock scan {2440588 i:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3659
+test clock-29.399 {time parsing} {
+ clock scan {2440588 i:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3659
+test clock-29.400 {time parsing} {
+ clock scan {2440588 i:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3659
+test clock-29.401 {time parsing} {
+ clock scan {2440588 01:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3659
+test clock-29.402 {time parsing} {
+ clock scan {2440588 01:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3659
+test clock-29.403 {time parsing} {
+ clock scan {2440588 1:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3659
+test clock-29.404 {time parsing} {
+ clock scan {2440588 1:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3659
+test clock-29.405 {time parsing} {
+ clock scan {2440588 i:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3659
+test clock-29.406 {time parsing} {
+ clock scan {2440588 i:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3659
+test clock-29.407 {time parsing} {
+ clock scan {2440588 i:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3659
+test clock-29.408 {time parsing} {
+ clock scan {2440588 i:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3659
+test clock-29.409 {time parsing} {
+ clock scan {2440588 01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 3660
+test clock-29.410 {time parsing} {
+ clock scan {2440588 01:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 3660
+test clock-29.411 {time parsing} {
+ clock scan {2440588 01:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3660
+test clock-29.412 {time parsing} {
+ clock scan {2440588 01:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3660
+test clock-29.413 {time parsing} {
+ clock scan {2440588 1:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 3660
+test clock-29.414 {time parsing} {
+ clock scan {2440588 1:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 3660
+test clock-29.415 {time parsing} {
+ clock scan {2440588 1:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3660
+test clock-29.416 {time parsing} {
+ clock scan {2440588 1:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3660
+test clock-29.417 {time parsing} {
+ clock scan {2440588 i:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 3660
+test clock-29.418 {time parsing} {
+ clock scan {2440588 i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 3660
+test clock-29.419 {time parsing} {
+ clock scan {2440588 i:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3660
+test clock-29.420 {time parsing} {
+ clock scan {2440588 i:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3660
+test clock-29.421 {time parsing} {
+ clock scan {2440588 i:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 3660
+test clock-29.422 {time parsing} {
+ clock scan {2440588 i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 3660
+test clock-29.423 {time parsing} {
+ clock scan {2440588 i:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3660
+test clock-29.424 {time parsing} {
+ clock scan {2440588 i:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3660
+test clock-29.425 {time parsing} {
+ clock scan {2440588 01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 3660
+test clock-29.426 {time parsing} {
+ clock scan {2440588 01:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 3660
+test clock-29.427 {time parsing} {
+ clock scan {2440588 01:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3660
+test clock-29.428 {time parsing} {
+ clock scan {2440588 01:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3660
+test clock-29.429 {time parsing} {
+ clock scan {2440588 1:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 3660
+test clock-29.430 {time parsing} {
+ clock scan {2440588 1:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 3660
+test clock-29.431 {time parsing} {
+ clock scan {2440588 1:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3660
+test clock-29.432 {time parsing} {
+ clock scan {2440588 1:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3660
+test clock-29.433 {time parsing} {
+ clock scan {2440588 i:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 3660
+test clock-29.434 {time parsing} {
+ clock scan {2440588 i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 3660
+test clock-29.435 {time parsing} {
+ clock scan {2440588 i:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3660
+test clock-29.436 {time parsing} {
+ clock scan {2440588 i:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3660
+test clock-29.437 {time parsing} {
+ clock scan {2440588 i:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 3660
+test clock-29.438 {time parsing} {
+ clock scan {2440588 i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 3660
+test clock-29.439 {time parsing} {
+ clock scan {2440588 i:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3660
+test clock-29.440 {time parsing} {
+ clock scan {2440588 i:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3660
+test clock-29.441 {time parsing} {
+ clock scan {2440588 01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 3660
+test clock-29.442 {time parsing} {
+ clock scan {2440588 01:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 3660
+test clock-29.443 {time parsing} {
+ clock scan {2440588 01:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3660
+test clock-29.444 {time parsing} {
+ clock scan {2440588 01:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3660
+test clock-29.445 {time parsing} {
+ clock scan {2440588 1:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 3660
+test clock-29.446 {time parsing} {
+ clock scan {2440588 1:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 3660
+test clock-29.447 {time parsing} {
+ clock scan {2440588 1:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3660
+test clock-29.448 {time parsing} {
+ clock scan {2440588 1:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3660
+test clock-29.449 {time parsing} {
+ clock scan {2440588 i:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 3660
+test clock-29.450 {time parsing} {
+ clock scan {2440588 i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 3660
+test clock-29.451 {time parsing} {
+ clock scan {2440588 i:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3660
+test clock-29.452 {time parsing} {
+ clock scan {2440588 i:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3660
+test clock-29.453 {time parsing} {
+ clock scan {2440588 i:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 3660
+test clock-29.454 {time parsing} {
+ clock scan {2440588 i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 3660
+test clock-29.455 {time parsing} {
+ clock scan {2440588 i:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3660
+test clock-29.456 {time parsing} {
+ clock scan {2440588 i:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3660
+test clock-29.457 {time parsing} {
+ clock scan {2440588 01:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3661
+test clock-29.458 {time parsing} {
+ clock scan {2440588 01:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3661
+test clock-29.459 {time parsing} {
+ clock scan {2440588 1:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3661
+test clock-29.460 {time parsing} {
+ clock scan {2440588 1:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3661
+test clock-29.461 {time parsing} {
+ clock scan {2440588 i:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3661
+test clock-29.462 {time parsing} {
+ clock scan {2440588 i:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3661
+test clock-29.463 {time parsing} {
+ clock scan {2440588 i:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3661
+test clock-29.464 {time parsing} {
+ clock scan {2440588 i:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3661
+test clock-29.465 {time parsing} {
+ clock scan {2440588 01:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3661
+test clock-29.466 {time parsing} {
+ clock scan {2440588 01:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3661
+test clock-29.467 {time parsing} {
+ clock scan {2440588 1:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3661
+test clock-29.468 {time parsing} {
+ clock scan {2440588 1:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3661
+test clock-29.469 {time parsing} {
+ clock scan {2440588 i:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3661
+test clock-29.470 {time parsing} {
+ clock scan {2440588 i:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3661
+test clock-29.471 {time parsing} {
+ clock scan {2440588 i:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3661
+test clock-29.472 {time parsing} {
+ clock scan {2440588 i:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3661
+test clock-29.473 {time parsing} {
+ clock scan {2440588 01:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3661
+test clock-29.474 {time parsing} {
+ clock scan {2440588 01:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3661
+test clock-29.475 {time parsing} {
+ clock scan {2440588 1:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3661
+test clock-29.476 {time parsing} {
+ clock scan {2440588 1:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3661
+test clock-29.477 {time parsing} {
+ clock scan {2440588 i:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3661
+test clock-29.478 {time parsing} {
+ clock scan {2440588 i:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3661
+test clock-29.479 {time parsing} {
+ clock scan {2440588 i:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3661
+test clock-29.480 {time parsing} {
+ clock scan {2440588 i:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3661
+test clock-29.481 {time parsing} {
+ clock scan {2440588 01:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3719
+test clock-29.482 {time parsing} {
+ clock scan {2440588 01:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3719
+test clock-29.483 {time parsing} {
+ clock scan {2440588 1:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3719
+test clock-29.484 {time parsing} {
+ clock scan {2440588 1:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3719
+test clock-29.485 {time parsing} {
+ clock scan {2440588 i:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3719
+test clock-29.486 {time parsing} {
+ clock scan {2440588 i:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3719
+test clock-29.487 {time parsing} {
+ clock scan {2440588 i:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3719
+test clock-29.488 {time parsing} {
+ clock scan {2440588 i:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3719
+test clock-29.489 {time parsing} {
+ clock scan {2440588 01:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3719
+test clock-29.490 {time parsing} {
+ clock scan {2440588 01:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3719
+test clock-29.491 {time parsing} {
+ clock scan {2440588 1:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3719
+test clock-29.492 {time parsing} {
+ clock scan {2440588 1:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3719
+test clock-29.493 {time parsing} {
+ clock scan {2440588 i:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3719
+test clock-29.494 {time parsing} {
+ clock scan {2440588 i:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3719
+test clock-29.495 {time parsing} {
+ clock scan {2440588 i:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3719
+test clock-29.496 {time parsing} {
+ clock scan {2440588 i:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3719
+test clock-29.497 {time parsing} {
+ clock scan {2440588 01:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3719
+test clock-29.498 {time parsing} {
+ clock scan {2440588 01:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3719
+test clock-29.499 {time parsing} {
+ clock scan {2440588 1:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3719
+test clock-29.500 {time parsing} {
+ clock scan {2440588 1:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3719
+test clock-29.501 {time parsing} {
+ clock scan {2440588 i:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3719
+test clock-29.502 {time parsing} {
+ clock scan {2440588 i:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3719
+test clock-29.503 {time parsing} {
+ clock scan {2440588 i:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3719
+test clock-29.504 {time parsing} {
+ clock scan {2440588 i:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3719
+test clock-29.505 {time parsing} {
+ clock scan {2440588 01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 7140
+test clock-29.506 {time parsing} {
+ clock scan {2440588 01:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 7140
+test clock-29.507 {time parsing} {
+ clock scan {2440588 01:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 7140
+test clock-29.508 {time parsing} {
+ clock scan {2440588 01:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 7140
+test clock-29.509 {time parsing} {
+ clock scan {2440588 1:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 7140
+test clock-29.510 {time parsing} {
+ clock scan {2440588 1:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 7140
+test clock-29.511 {time parsing} {
+ clock scan {2440588 1:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 7140
+test clock-29.512 {time parsing} {
+ clock scan {2440588 1:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 7140
+test clock-29.513 {time parsing} {
+ clock scan {2440588 i:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 7140
+test clock-29.514 {time parsing} {
+ clock scan {2440588 i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 7140
+test clock-29.515 {time parsing} {
+ clock scan {2440588 i:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 7140
+test clock-29.516 {time parsing} {
+ clock scan {2440588 i:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 7140
+test clock-29.517 {time parsing} {
+ clock scan {2440588 i:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 7140
+test clock-29.518 {time parsing} {
+ clock scan {2440588 i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 7140
+test clock-29.519 {time parsing} {
+ clock scan {2440588 i:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 7140
+test clock-29.520 {time parsing} {
+ clock scan {2440588 i:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 7140
+test clock-29.521 {time parsing} {
+ clock scan {2440588 01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 7140
+test clock-29.522 {time parsing} {
+ clock scan {2440588 01:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 7140
+test clock-29.523 {time parsing} {
+ clock scan {2440588 01:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 7140
+test clock-29.524 {time parsing} {
+ clock scan {2440588 01:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 7140
+test clock-29.525 {time parsing} {
+ clock scan {2440588 1:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 7140
+test clock-29.526 {time parsing} {
+ clock scan {2440588 1:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 7140
+test clock-29.527 {time parsing} {
+ clock scan {2440588 1:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 7140
+test clock-29.528 {time parsing} {
+ clock scan {2440588 1:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 7140
+test clock-29.529 {time parsing} {
+ clock scan {2440588 i:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 7140
+test clock-29.530 {time parsing} {
+ clock scan {2440588 i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 7140
+test clock-29.531 {time parsing} {
+ clock scan {2440588 i:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 7140
+test clock-29.532 {time parsing} {
+ clock scan {2440588 i:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 7140
+test clock-29.533 {time parsing} {
+ clock scan {2440588 i:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 7140
+test clock-29.534 {time parsing} {
+ clock scan {2440588 i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 7140
+test clock-29.535 {time parsing} {
+ clock scan {2440588 i:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 7140
+test clock-29.536 {time parsing} {
+ clock scan {2440588 i:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 7140
+test clock-29.537 {time parsing} {
+ clock scan {2440588 01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 7140
+test clock-29.538 {time parsing} {
+ clock scan {2440588 01:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 7140
+test clock-29.539 {time parsing} {
+ clock scan {2440588 01:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 7140
+test clock-29.540 {time parsing} {
+ clock scan {2440588 01:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 7140
+test clock-29.541 {time parsing} {
+ clock scan {2440588 1:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 7140
+test clock-29.542 {time parsing} {
+ clock scan {2440588 1:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 7140
+test clock-29.543 {time parsing} {
+ clock scan {2440588 1:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 7140
+test clock-29.544 {time parsing} {
+ clock scan {2440588 1:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 7140
+test clock-29.545 {time parsing} {
+ clock scan {2440588 i:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 7140
+test clock-29.546 {time parsing} {
+ clock scan {2440588 i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 7140
+test clock-29.547 {time parsing} {
+ clock scan {2440588 i:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 7140
+test clock-29.548 {time parsing} {
+ clock scan {2440588 i:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 7140
+test clock-29.549 {time parsing} {
+ clock scan {2440588 i:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 7140
+test clock-29.550 {time parsing} {
+ clock scan {2440588 i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 7140
+test clock-29.551 {time parsing} {
+ clock scan {2440588 i:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 7140
+test clock-29.552 {time parsing} {
+ clock scan {2440588 i:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 7140
+test clock-29.553 {time parsing} {
+ clock scan {2440588 01:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 7141
+test clock-29.554 {time parsing} {
+ clock scan {2440588 01:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 7141
+test clock-29.555 {time parsing} {
+ clock scan {2440588 1:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 7141
+test clock-29.556 {time parsing} {
+ clock scan {2440588 1:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 7141
+test clock-29.557 {time parsing} {
+ clock scan {2440588 i:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 7141
+test clock-29.558 {time parsing} {
+ clock scan {2440588 i:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 7141
+test clock-29.559 {time parsing} {
+ clock scan {2440588 i:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 7141
+test clock-29.560 {time parsing} {
+ clock scan {2440588 i:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 7141
+test clock-29.561 {time parsing} {
+ clock scan {2440588 01:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 7141
+test clock-29.562 {time parsing} {
+ clock scan {2440588 01:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 7141
+test clock-29.563 {time parsing} {
+ clock scan {2440588 1:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 7141
+test clock-29.564 {time parsing} {
+ clock scan {2440588 1:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 7141
+test clock-29.565 {time parsing} {
+ clock scan {2440588 i:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 7141
+test clock-29.566 {time parsing} {
+ clock scan {2440588 i:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 7141
+test clock-29.567 {time parsing} {
+ clock scan {2440588 i:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 7141
+test clock-29.568 {time parsing} {
+ clock scan {2440588 i:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 7141
+test clock-29.569 {time parsing} {
+ clock scan {2440588 01:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 7141
+test clock-29.570 {time parsing} {
+ clock scan {2440588 01:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 7141
+test clock-29.571 {time parsing} {
+ clock scan {2440588 1:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 7141
+test clock-29.572 {time parsing} {
+ clock scan {2440588 1:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 7141
+test clock-29.573 {time parsing} {
+ clock scan {2440588 i:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 7141
+test clock-29.574 {time parsing} {
+ clock scan {2440588 i:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 7141
+test clock-29.575 {time parsing} {
+ clock scan {2440588 i:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 7141
+test clock-29.576 {time parsing} {
+ clock scan {2440588 i:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 7141
+test clock-29.577 {time parsing} {
+ clock scan {2440588 01:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 7199
+test clock-29.578 {time parsing} {
+ clock scan {2440588 01:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 7199
+test clock-29.579 {time parsing} {
+ clock scan {2440588 1:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 7199
+test clock-29.580 {time parsing} {
+ clock scan {2440588 1:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 7199
+test clock-29.581 {time parsing} {
+ clock scan {2440588 i:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 7199
+test clock-29.582 {time parsing} {
+ clock scan {2440588 i:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 7199
+test clock-29.583 {time parsing} {
+ clock scan {2440588 i:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 7199
+test clock-29.584 {time parsing} {
+ clock scan {2440588 i:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 7199
+test clock-29.585 {time parsing} {
+ clock scan {2440588 01:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 7199
+test clock-29.586 {time parsing} {
+ clock scan {2440588 01:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 7199
+test clock-29.587 {time parsing} {
+ clock scan {2440588 1:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 7199
+test clock-29.588 {time parsing} {
+ clock scan {2440588 1:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 7199
+test clock-29.589 {time parsing} {
+ clock scan {2440588 i:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 7199
+test clock-29.590 {time parsing} {
+ clock scan {2440588 i:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 7199
+test clock-29.591 {time parsing} {
+ clock scan {2440588 i:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 7199
+test clock-29.592 {time parsing} {
+ clock scan {2440588 i:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 7199
+test clock-29.593 {time parsing} {
+ clock scan {2440588 01:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 7199
+test clock-29.594 {time parsing} {
+ clock scan {2440588 01:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 7199
+test clock-29.595 {time parsing} {
+ clock scan {2440588 1:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 7199
+test clock-29.596 {time parsing} {
+ clock scan {2440588 1:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 7199
+test clock-29.597 {time parsing} {
+ clock scan {2440588 i:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 7199
+test clock-29.598 {time parsing} {
+ clock scan {2440588 i:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 7199
+test clock-29.599 {time parsing} {
+ clock scan {2440588 i:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 7199
+test clock-29.600 {time parsing} {
+ clock scan {2440588 i:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 7199
+test clock-29.601 {time parsing} {
+ clock scan {2440588 11 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H }
+} 39600
+test clock-29.602 {time parsing} {
+ clock scan {2440588 11:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 39600
+test clock-29.603 {time parsing} {
+ clock scan {2440588 11:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 39600
+test clock-29.604 {time parsing} {
+ clock scan {2440588 11:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 39600
+test clock-29.605 {time parsing} {
+ clock scan {2440588 11:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 39600
+test clock-29.606 {time parsing} {
+ clock scan {2440588 11 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k }
+} 39600
+test clock-29.607 {time parsing} {
+ clock scan {2440588 11:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 39600
+test clock-29.608 {time parsing} {
+ clock scan {2440588 11:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 39600
+test clock-29.609 {time parsing} {
+ clock scan {2440588 11:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 39600
+test clock-29.610 {time parsing} {
+ clock scan {2440588 11:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 39600
+test clock-29.611 {time parsing} {
+ clock scan {2440588 xi } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH }
+} 39600
+test clock-29.612 {time parsing} {
+ clock scan {2440588 xi:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 39600
+test clock-29.613 {time parsing} {
+ clock scan {2440588 xi:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 39600
+test clock-29.614 {time parsing} {
+ clock scan {2440588 xi:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 39600
+test clock-29.615 {time parsing} {
+ clock scan {2440588 xi:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 39600
+test clock-29.616 {time parsing} {
+ clock scan {2440588 xi } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok }
+} 39600
+test clock-29.617 {time parsing} {
+ clock scan {2440588 xi:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 39600
+test clock-29.618 {time parsing} {
+ clock scan {2440588 xi:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 39600
+test clock-29.619 {time parsing} {
+ clock scan {2440588 xi:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 39600
+test clock-29.620 {time parsing} {
+ clock scan {2440588 xi:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 39600
+test clock-29.621 {time parsing} {
+ clock scan {2440588 11 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %p}
+} 39600
+test clock-29.622 {time parsing} {
+ clock scan {2440588 11:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 39600
+test clock-29.623 {time parsing} {
+ clock scan {2440588 11:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 39600
+test clock-29.624 {time parsing} {
+ clock scan {2440588 11:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 39600
+test clock-29.625 {time parsing} {
+ clock scan {2440588 11:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 39600
+test clock-29.626 {time parsing} {
+ clock scan {2440588 11 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %p}
+} 39600
+test clock-29.627 {time parsing} {
+ clock scan {2440588 11:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 39600
+test clock-29.628 {time parsing} {
+ clock scan {2440588 11:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 39600
+test clock-29.629 {time parsing} {
+ clock scan {2440588 11:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 39600
+test clock-29.630 {time parsing} {
+ clock scan {2440588 11:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 39600
+test clock-29.631 {time parsing} {
+ clock scan {2440588 xi AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %p}
+} 39600
+test clock-29.632 {time parsing} {
+ clock scan {2440588 xi:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 39600
+test clock-29.633 {time parsing} {
+ clock scan {2440588 xi:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 39600
+test clock-29.634 {time parsing} {
+ clock scan {2440588 xi:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 39600
+test clock-29.635 {time parsing} {
+ clock scan {2440588 xi:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 39600
+test clock-29.636 {time parsing} {
+ clock scan {2440588 xi AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %p}
+} 39600
+test clock-29.637 {time parsing} {
+ clock scan {2440588 xi:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 39600
+test clock-29.638 {time parsing} {
+ clock scan {2440588 xi:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 39600
+test clock-29.639 {time parsing} {
+ clock scan {2440588 xi:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 39600
+test clock-29.640 {time parsing} {
+ clock scan {2440588 xi:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 39600
+test clock-29.641 {time parsing} {
+ clock scan {2440588 11 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %P}
+} 39600
+test clock-29.642 {time parsing} {
+ clock scan {2440588 11:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 39600
+test clock-29.643 {time parsing} {
+ clock scan {2440588 11:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 39600
+test clock-29.644 {time parsing} {
+ clock scan {2440588 11:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 39600
+test clock-29.645 {time parsing} {
+ clock scan {2440588 11:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 39600
+test clock-29.646 {time parsing} {
+ clock scan {2440588 11 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %P}
+} 39600
+test clock-29.647 {time parsing} {
+ clock scan {2440588 11:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 39600
+test clock-29.648 {time parsing} {
+ clock scan {2440588 11:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 39600
+test clock-29.649 {time parsing} {
+ clock scan {2440588 11:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 39600
+test clock-29.650 {time parsing} {
+ clock scan {2440588 11:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 39600
+test clock-29.651 {time parsing} {
+ clock scan {2440588 xi am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %P}
+} 39600
+test clock-29.652 {time parsing} {
+ clock scan {2440588 xi:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 39600
+test clock-29.653 {time parsing} {
+ clock scan {2440588 xi:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 39600
+test clock-29.654 {time parsing} {
+ clock scan {2440588 xi:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 39600
+test clock-29.655 {time parsing} {
+ clock scan {2440588 xi:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 39600
+test clock-29.656 {time parsing} {
+ clock scan {2440588 xi am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %P}
+} 39600
+test clock-29.657 {time parsing} {
+ clock scan {2440588 xi:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 39600
+test clock-29.658 {time parsing} {
+ clock scan {2440588 xi:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 39600
+test clock-29.659 {time parsing} {
+ clock scan {2440588 xi:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 39600
+test clock-29.660 {time parsing} {
+ clock scan {2440588 xi:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 39600
+test clock-29.661 {time parsing} {
+ clock scan {2440588 11:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 39601
+test clock-29.662 {time parsing} {
+ clock scan {2440588 11:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 39601
+test clock-29.663 {time parsing} {
+ clock scan {2440588 11:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 39601
+test clock-29.664 {time parsing} {
+ clock scan {2440588 11:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 39601
+test clock-29.665 {time parsing} {
+ clock scan {2440588 xi:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 39601
+test clock-29.666 {time parsing} {
+ clock scan {2440588 xi:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 39601
+test clock-29.667 {time parsing} {
+ clock scan {2440588 xi:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 39601
+test clock-29.668 {time parsing} {
+ clock scan {2440588 xi:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 39601
+test clock-29.669 {time parsing} {
+ clock scan {2440588 11:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 39601
+test clock-29.670 {time parsing} {
+ clock scan {2440588 11:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 39601
+test clock-29.671 {time parsing} {
+ clock scan {2440588 11:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 39601
+test clock-29.672 {time parsing} {
+ clock scan {2440588 11:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 39601
+test clock-29.673 {time parsing} {
+ clock scan {2440588 xi:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 39601
+test clock-29.674 {time parsing} {
+ clock scan {2440588 xi:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 39601
+test clock-29.675 {time parsing} {
+ clock scan {2440588 xi:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 39601
+test clock-29.676 {time parsing} {
+ clock scan {2440588 xi:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 39601
+test clock-29.677 {time parsing} {
+ clock scan {2440588 11:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 39601
+test clock-29.678 {time parsing} {
+ clock scan {2440588 11:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 39601
+test clock-29.679 {time parsing} {
+ clock scan {2440588 11:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 39601
+test clock-29.680 {time parsing} {
+ clock scan {2440588 11:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 39601
+test clock-29.681 {time parsing} {
+ clock scan {2440588 xi:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 39601
+test clock-29.682 {time parsing} {
+ clock scan {2440588 xi:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 39601
+test clock-29.683 {time parsing} {
+ clock scan {2440588 xi:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 39601
+test clock-29.684 {time parsing} {
+ clock scan {2440588 xi:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 39601
+test clock-29.685 {time parsing} {
+ clock scan {2440588 11:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 39659
+test clock-29.686 {time parsing} {
+ clock scan {2440588 11:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 39659
+test clock-29.687 {time parsing} {
+ clock scan {2440588 11:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 39659
+test clock-29.688 {time parsing} {
+ clock scan {2440588 11:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 39659
+test clock-29.689 {time parsing} {
+ clock scan {2440588 xi:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 39659
+test clock-29.690 {time parsing} {
+ clock scan {2440588 xi:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 39659
+test clock-29.691 {time parsing} {
+ clock scan {2440588 xi:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 39659
+test clock-29.692 {time parsing} {
+ clock scan {2440588 xi:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 39659
+test clock-29.693 {time parsing} {
+ clock scan {2440588 11:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 39659
+test clock-29.694 {time parsing} {
+ clock scan {2440588 11:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 39659
+test clock-29.695 {time parsing} {
+ clock scan {2440588 11:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 39659
+test clock-29.696 {time parsing} {
+ clock scan {2440588 11:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 39659
+test clock-29.697 {time parsing} {
+ clock scan {2440588 xi:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 39659
+test clock-29.698 {time parsing} {
+ clock scan {2440588 xi:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 39659
+test clock-29.699 {time parsing} {
+ clock scan {2440588 xi:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 39659
+test clock-29.700 {time parsing} {
+ clock scan {2440588 xi:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 39659
+test clock-29.701 {time parsing} {
+ clock scan {2440588 11:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 39659
+test clock-29.702 {time parsing} {
+ clock scan {2440588 11:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 39659
+test clock-29.703 {time parsing} {
+ clock scan {2440588 11:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 39659
+test clock-29.704 {time parsing} {
+ clock scan {2440588 11:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 39659
+test clock-29.705 {time parsing} {
+ clock scan {2440588 xi:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 39659
+test clock-29.706 {time parsing} {
+ clock scan {2440588 xi:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 39659
+test clock-29.707 {time parsing} {
+ clock scan {2440588 xi:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 39659
+test clock-29.708 {time parsing} {
+ clock scan {2440588 xi:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 39659
+test clock-29.709 {time parsing} {
+ clock scan {2440588 11:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 39660
+test clock-29.710 {time parsing} {
+ clock scan {2440588 11:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 39660
+test clock-29.711 {time parsing} {
+ clock scan {2440588 11:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 39660
+test clock-29.712 {time parsing} {
+ clock scan {2440588 11:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 39660
+test clock-29.713 {time parsing} {
+ clock scan {2440588 11:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 39660
+test clock-29.714 {time parsing} {
+ clock scan {2440588 11:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 39660
+test clock-29.715 {time parsing} {
+ clock scan {2440588 11:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 39660
+test clock-29.716 {time parsing} {
+ clock scan {2440588 11:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 39660
+test clock-29.717 {time parsing} {
+ clock scan {2440588 xi:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 39660
+test clock-29.718 {time parsing} {
+ clock scan {2440588 xi:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 39660
+test clock-29.719 {time parsing} {
+ clock scan {2440588 xi:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 39660
+test clock-29.720 {time parsing} {
+ clock scan {2440588 xi:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 39660
+test clock-29.721 {time parsing} {
+ clock scan {2440588 xi:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 39660
+test clock-29.722 {time parsing} {
+ clock scan {2440588 xi:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 39660
+test clock-29.723 {time parsing} {
+ clock scan {2440588 xi:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 39660
+test clock-29.724 {time parsing} {
+ clock scan {2440588 xi:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 39660
+test clock-29.725 {time parsing} {
+ clock scan {2440588 11:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 39660
+test clock-29.726 {time parsing} {
+ clock scan {2440588 11:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 39660
+test clock-29.727 {time parsing} {
+ clock scan {2440588 11:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 39660
+test clock-29.728 {time parsing} {
+ clock scan {2440588 11:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 39660
+test clock-29.729 {time parsing} {
+ clock scan {2440588 11:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 39660
+test clock-29.730 {time parsing} {
+ clock scan {2440588 11:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 39660
+test clock-29.731 {time parsing} {
+ clock scan {2440588 11:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 39660
+test clock-29.732 {time parsing} {
+ clock scan {2440588 11:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 39660
+test clock-29.733 {time parsing} {
+ clock scan {2440588 xi:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 39660
+test clock-29.734 {time parsing} {
+ clock scan {2440588 xi:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 39660
+test clock-29.735 {time parsing} {
+ clock scan {2440588 xi:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 39660
+test clock-29.736 {time parsing} {
+ clock scan {2440588 xi:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 39660
+test clock-29.737 {time parsing} {
+ clock scan {2440588 xi:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 39660
+test clock-29.738 {time parsing} {
+ clock scan {2440588 xi:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 39660
+test clock-29.739 {time parsing} {
+ clock scan {2440588 xi:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 39660
+test clock-29.740 {time parsing} {
+ clock scan {2440588 xi:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 39660
+test clock-29.741 {time parsing} {
+ clock scan {2440588 11:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 39660
+test clock-29.742 {time parsing} {
+ clock scan {2440588 11:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 39660
+test clock-29.743 {time parsing} {
+ clock scan {2440588 11:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 39660
+test clock-29.744 {time parsing} {
+ clock scan {2440588 11:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 39660
+test clock-29.745 {time parsing} {
+ clock scan {2440588 11:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 39660
+test clock-29.746 {time parsing} {
+ clock scan {2440588 11:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 39660
+test clock-29.747 {time parsing} {
+ clock scan {2440588 11:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 39660
+test clock-29.748 {time parsing} {
+ clock scan {2440588 11:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 39660
+test clock-29.749 {time parsing} {
+ clock scan {2440588 xi:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 39660
+test clock-29.750 {time parsing} {
+ clock scan {2440588 xi:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 39660
+test clock-29.751 {time parsing} {
+ clock scan {2440588 xi:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 39660
+test clock-29.752 {time parsing} {
+ clock scan {2440588 xi:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 39660
+test clock-29.753 {time parsing} {
+ clock scan {2440588 xi:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 39660
+test clock-29.754 {time parsing} {
+ clock scan {2440588 xi:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 39660
+test clock-29.755 {time parsing} {
+ clock scan {2440588 xi:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 39660
+test clock-29.756 {time parsing} {
+ clock scan {2440588 xi:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 39660
+test clock-29.757 {time parsing} {
+ clock scan {2440588 11:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 39661
+test clock-29.758 {time parsing} {
+ clock scan {2440588 11:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 39661
+test clock-29.759 {time parsing} {
+ clock scan {2440588 11:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 39661
+test clock-29.760 {time parsing} {
+ clock scan {2440588 11:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 39661
+test clock-29.761 {time parsing} {
+ clock scan {2440588 xi:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 39661
+test clock-29.762 {time parsing} {
+ clock scan {2440588 xi:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 39661
+test clock-29.763 {time parsing} {
+ clock scan {2440588 xi:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 39661
+test clock-29.764 {time parsing} {
+ clock scan {2440588 xi:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 39661
+test clock-29.765 {time parsing} {
+ clock scan {2440588 11:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 39661
+test clock-29.766 {time parsing} {
+ clock scan {2440588 11:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 39661
+test clock-29.767 {time parsing} {
+ clock scan {2440588 11:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 39661
+test clock-29.768 {time parsing} {
+ clock scan {2440588 11:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 39661
+test clock-29.769 {time parsing} {
+ clock scan {2440588 xi:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 39661
+test clock-29.770 {time parsing} {
+ clock scan {2440588 xi:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 39661
+test clock-29.771 {time parsing} {
+ clock scan {2440588 xi:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 39661
+test clock-29.772 {time parsing} {
+ clock scan {2440588 xi:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 39661
+test clock-29.773 {time parsing} {
+ clock scan {2440588 11:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 39661
+test clock-29.774 {time parsing} {
+ clock scan {2440588 11:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 39661
+test clock-29.775 {time parsing} {
+ clock scan {2440588 11:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 39661
+test clock-29.776 {time parsing} {
+ clock scan {2440588 11:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 39661
+test clock-29.777 {time parsing} {
+ clock scan {2440588 xi:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 39661
+test clock-29.778 {time parsing} {
+ clock scan {2440588 xi:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 39661
+test clock-29.779 {time parsing} {
+ clock scan {2440588 xi:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 39661
+test clock-29.780 {time parsing} {
+ clock scan {2440588 xi:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 39661
+test clock-29.781 {time parsing} {
+ clock scan {2440588 11:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 39719
+test clock-29.782 {time parsing} {
+ clock scan {2440588 11:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 39719
+test clock-29.783 {time parsing} {
+ clock scan {2440588 11:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 39719
+test clock-29.784 {time parsing} {
+ clock scan {2440588 11:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 39719
+test clock-29.785 {time parsing} {
+ clock scan {2440588 xi:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 39719
+test clock-29.786 {time parsing} {
+ clock scan {2440588 xi:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 39719
+test clock-29.787 {time parsing} {
+ clock scan {2440588 xi:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 39719
+test clock-29.788 {time parsing} {
+ clock scan {2440588 xi:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 39719
+test clock-29.789 {time parsing} {
+ clock scan {2440588 11:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 39719
+test clock-29.790 {time parsing} {
+ clock scan {2440588 11:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 39719
+test clock-29.791 {time parsing} {
+ clock scan {2440588 11:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 39719
+test clock-29.792 {time parsing} {
+ clock scan {2440588 11:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 39719
+test clock-29.793 {time parsing} {
+ clock scan {2440588 xi:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 39719
+test clock-29.794 {time parsing} {
+ clock scan {2440588 xi:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 39719
+test clock-29.795 {time parsing} {
+ clock scan {2440588 xi:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 39719
+test clock-29.796 {time parsing} {
+ clock scan {2440588 xi:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 39719
+test clock-29.797 {time parsing} {
+ clock scan {2440588 11:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 39719
+test clock-29.798 {time parsing} {
+ clock scan {2440588 11:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 39719
+test clock-29.799 {time parsing} {
+ clock scan {2440588 11:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 39719
+test clock-29.800 {time parsing} {
+ clock scan {2440588 11:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 39719
+test clock-29.801 {time parsing} {
+ clock scan {2440588 xi:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 39719
+test clock-29.802 {time parsing} {
+ clock scan {2440588 xi:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 39719
+test clock-29.803 {time parsing} {
+ clock scan {2440588 xi:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 39719
+test clock-29.804 {time parsing} {
+ clock scan {2440588 xi:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 39719
+test clock-29.805 {time parsing} {
+ clock scan {2440588 11:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 43140
+test clock-29.806 {time parsing} {
+ clock scan {2440588 11:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 43140
+test clock-29.807 {time parsing} {
+ clock scan {2440588 11:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43140
+test clock-29.808 {time parsing} {
+ clock scan {2440588 11:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43140
+test clock-29.809 {time parsing} {
+ clock scan {2440588 11:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 43140
+test clock-29.810 {time parsing} {
+ clock scan {2440588 11:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 43140
+test clock-29.811 {time parsing} {
+ clock scan {2440588 11:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43140
+test clock-29.812 {time parsing} {
+ clock scan {2440588 11:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43140
+test clock-29.813 {time parsing} {
+ clock scan {2440588 xi:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 43140
+test clock-29.814 {time parsing} {
+ clock scan {2440588 xi:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 43140
+test clock-29.815 {time parsing} {
+ clock scan {2440588 xi:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43140
+test clock-29.816 {time parsing} {
+ clock scan {2440588 xi:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43140
+test clock-29.817 {time parsing} {
+ clock scan {2440588 xi:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 43140
+test clock-29.818 {time parsing} {
+ clock scan {2440588 xi:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 43140
+test clock-29.819 {time parsing} {
+ clock scan {2440588 xi:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43140
+test clock-29.820 {time parsing} {
+ clock scan {2440588 xi:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43140
+test clock-29.821 {time parsing} {
+ clock scan {2440588 11:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 43140
+test clock-29.822 {time parsing} {
+ clock scan {2440588 11:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 43140
+test clock-29.823 {time parsing} {
+ clock scan {2440588 11:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43140
+test clock-29.824 {time parsing} {
+ clock scan {2440588 11:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43140
+test clock-29.825 {time parsing} {
+ clock scan {2440588 11:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 43140
+test clock-29.826 {time parsing} {
+ clock scan {2440588 11:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 43140
+test clock-29.827 {time parsing} {
+ clock scan {2440588 11:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43140
+test clock-29.828 {time parsing} {
+ clock scan {2440588 11:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43140
+test clock-29.829 {time parsing} {
+ clock scan {2440588 xi:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 43140
+test clock-29.830 {time parsing} {
+ clock scan {2440588 xi:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 43140
+test clock-29.831 {time parsing} {
+ clock scan {2440588 xi:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43140
+test clock-29.832 {time parsing} {
+ clock scan {2440588 xi:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43140
+test clock-29.833 {time parsing} {
+ clock scan {2440588 xi:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 43140
+test clock-29.834 {time parsing} {
+ clock scan {2440588 xi:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 43140
+test clock-29.835 {time parsing} {
+ clock scan {2440588 xi:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43140
+test clock-29.836 {time parsing} {
+ clock scan {2440588 xi:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43140
+test clock-29.837 {time parsing} {
+ clock scan {2440588 11:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 43140
+test clock-29.838 {time parsing} {
+ clock scan {2440588 11:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 43140
+test clock-29.839 {time parsing} {
+ clock scan {2440588 11:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43140
+test clock-29.840 {time parsing} {
+ clock scan {2440588 11:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43140
+test clock-29.841 {time parsing} {
+ clock scan {2440588 11:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 43140
+test clock-29.842 {time parsing} {
+ clock scan {2440588 11:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 43140
+test clock-29.843 {time parsing} {
+ clock scan {2440588 11:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43140
+test clock-29.844 {time parsing} {
+ clock scan {2440588 11:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43140
+test clock-29.845 {time parsing} {
+ clock scan {2440588 xi:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 43140
+test clock-29.846 {time parsing} {
+ clock scan {2440588 xi:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 43140
+test clock-29.847 {time parsing} {
+ clock scan {2440588 xi:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43140
+test clock-29.848 {time parsing} {
+ clock scan {2440588 xi:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43140
+test clock-29.849 {time parsing} {
+ clock scan {2440588 xi:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 43140
+test clock-29.850 {time parsing} {
+ clock scan {2440588 xi:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 43140
+test clock-29.851 {time parsing} {
+ clock scan {2440588 xi:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43140
+test clock-29.852 {time parsing} {
+ clock scan {2440588 xi:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43140
+test clock-29.853 {time parsing} {
+ clock scan {2440588 11:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43141
+test clock-29.854 {time parsing} {
+ clock scan {2440588 11:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43141
+test clock-29.855 {time parsing} {
+ clock scan {2440588 11:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43141
+test clock-29.856 {time parsing} {
+ clock scan {2440588 11:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43141
+test clock-29.857 {time parsing} {
+ clock scan {2440588 xi:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43141
+test clock-29.858 {time parsing} {
+ clock scan {2440588 xi:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43141
+test clock-29.859 {time parsing} {
+ clock scan {2440588 xi:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43141
+test clock-29.860 {time parsing} {
+ clock scan {2440588 xi:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43141
+test clock-29.861 {time parsing} {
+ clock scan {2440588 11:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43141
+test clock-29.862 {time parsing} {
+ clock scan {2440588 11:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43141
+test clock-29.863 {time parsing} {
+ clock scan {2440588 11:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43141
+test clock-29.864 {time parsing} {
+ clock scan {2440588 11:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43141
+test clock-29.865 {time parsing} {
+ clock scan {2440588 xi:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43141
+test clock-29.866 {time parsing} {
+ clock scan {2440588 xi:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43141
+test clock-29.867 {time parsing} {
+ clock scan {2440588 xi:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43141
+test clock-29.868 {time parsing} {
+ clock scan {2440588 xi:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43141
+test clock-29.869 {time parsing} {
+ clock scan {2440588 11:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43141
+test clock-29.870 {time parsing} {
+ clock scan {2440588 11:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43141
+test clock-29.871 {time parsing} {
+ clock scan {2440588 11:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43141
+test clock-29.872 {time parsing} {
+ clock scan {2440588 11:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43141
+test clock-29.873 {time parsing} {
+ clock scan {2440588 xi:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43141
+test clock-29.874 {time parsing} {
+ clock scan {2440588 xi:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43141
+test clock-29.875 {time parsing} {
+ clock scan {2440588 xi:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43141
+test clock-29.876 {time parsing} {
+ clock scan {2440588 xi:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43141
+test clock-29.877 {time parsing} {
+ clock scan {2440588 11:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43199
+test clock-29.878 {time parsing} {
+ clock scan {2440588 11:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43199
+test clock-29.879 {time parsing} {
+ clock scan {2440588 11:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43199
+test clock-29.880 {time parsing} {
+ clock scan {2440588 11:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43199
+test clock-29.881 {time parsing} {
+ clock scan {2440588 xi:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43199
+test clock-29.882 {time parsing} {
+ clock scan {2440588 xi:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43199
+test clock-29.883 {time parsing} {
+ clock scan {2440588 xi:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43199
+test clock-29.884 {time parsing} {
+ clock scan {2440588 xi:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43199
+test clock-29.885 {time parsing} {
+ clock scan {2440588 11:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43199
+test clock-29.886 {time parsing} {
+ clock scan {2440588 11:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43199
+test clock-29.887 {time parsing} {
+ clock scan {2440588 11:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43199
+test clock-29.888 {time parsing} {
+ clock scan {2440588 11:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43199
+test clock-29.889 {time parsing} {
+ clock scan {2440588 xi:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43199
+test clock-29.890 {time parsing} {
+ clock scan {2440588 xi:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43199
+test clock-29.891 {time parsing} {
+ clock scan {2440588 xi:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43199
+test clock-29.892 {time parsing} {
+ clock scan {2440588 xi:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43199
+test clock-29.893 {time parsing} {
+ clock scan {2440588 11:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43199
+test clock-29.894 {time parsing} {
+ clock scan {2440588 11:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43199
+test clock-29.895 {time parsing} {
+ clock scan {2440588 11:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43199
+test clock-29.896 {time parsing} {
+ clock scan {2440588 11:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43199
+test clock-29.897 {time parsing} {
+ clock scan {2440588 xi:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43199
+test clock-29.898 {time parsing} {
+ clock scan {2440588 xi:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43199
+test clock-29.899 {time parsing} {
+ clock scan {2440588 xi:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43199
+test clock-29.900 {time parsing} {
+ clock scan {2440588 xi:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43199
+test clock-29.901 {time parsing} {
+ clock scan {2440588 12 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H }
+} 43200
+test clock-29.902 {time parsing} {
+ clock scan {2440588 12:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 43200
+test clock-29.903 {time parsing} {
+ clock scan {2440588 12:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 43200
+test clock-29.904 {time parsing} {
+ clock scan {2440588 12:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43200
+test clock-29.905 {time parsing} {
+ clock scan {2440588 12:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43200
+test clock-29.906 {time parsing} {
+ clock scan {2440588 12 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k }
+} 43200
+test clock-29.907 {time parsing} {
+ clock scan {2440588 12:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 43200
+test clock-29.908 {time parsing} {
+ clock scan {2440588 12:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 43200
+test clock-29.909 {time parsing} {
+ clock scan {2440588 12:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43200
+test clock-29.910 {time parsing} {
+ clock scan {2440588 12:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43200
+test clock-29.911 {time parsing} {
+ clock scan {2440588 xii } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH }
+} 43200
+test clock-29.912 {time parsing} {
+ clock scan {2440588 xii:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 43200
+test clock-29.913 {time parsing} {
+ clock scan {2440588 xii:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 43200
+test clock-29.914 {time parsing} {
+ clock scan {2440588 xii:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43200
+test clock-29.915 {time parsing} {
+ clock scan {2440588 xii:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43200
+test clock-29.916 {time parsing} {
+ clock scan {2440588 xii } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok }
+} 43200
+test clock-29.917 {time parsing} {
+ clock scan {2440588 xii:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 43200
+test clock-29.918 {time parsing} {
+ clock scan {2440588 xii:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 43200
+test clock-29.919 {time parsing} {
+ clock scan {2440588 xii:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43200
+test clock-29.920 {time parsing} {
+ clock scan {2440588 xii:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43200
+test clock-29.921 {time parsing} {
+ clock scan {2440588 12 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %p}
+} 43200
+test clock-29.922 {time parsing} {
+ clock scan {2440588 12:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 43200
+test clock-29.923 {time parsing} {
+ clock scan {2440588 12:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 43200
+test clock-29.924 {time parsing} {
+ clock scan {2440588 12:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43200
+test clock-29.925 {time parsing} {
+ clock scan {2440588 12:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43200
+test clock-29.926 {time parsing} {
+ clock scan {2440588 12 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %p}
+} 43200
+test clock-29.927 {time parsing} {
+ clock scan {2440588 12:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 43200
+test clock-29.928 {time parsing} {
+ clock scan {2440588 12:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 43200
+test clock-29.929 {time parsing} {
+ clock scan {2440588 12:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43200
+test clock-29.930 {time parsing} {
+ clock scan {2440588 12:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43200
+test clock-29.931 {time parsing} {
+ clock scan {2440588 xii PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %p}
+} 43200
+test clock-29.932 {time parsing} {
+ clock scan {2440588 xii:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 43200
+test clock-29.933 {time parsing} {
+ clock scan {2440588 xii:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 43200
+test clock-29.934 {time parsing} {
+ clock scan {2440588 xii:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43200
+test clock-29.935 {time parsing} {
+ clock scan {2440588 xii:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43200
+test clock-29.936 {time parsing} {
+ clock scan {2440588 xii PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %p}
+} 43200
+test clock-29.937 {time parsing} {
+ clock scan {2440588 xii:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 43200
+test clock-29.938 {time parsing} {
+ clock scan {2440588 xii:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 43200
+test clock-29.939 {time parsing} {
+ clock scan {2440588 xii:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43200
+test clock-29.940 {time parsing} {
+ clock scan {2440588 xii:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43200
+test clock-29.941 {time parsing} {
+ clock scan {2440588 12 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %P}
+} 43200
+test clock-29.942 {time parsing} {
+ clock scan {2440588 12:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 43200
+test clock-29.943 {time parsing} {
+ clock scan {2440588 12:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 43200
+test clock-29.944 {time parsing} {
+ clock scan {2440588 12:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43200
+test clock-29.945 {time parsing} {
+ clock scan {2440588 12:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43200
+test clock-29.946 {time parsing} {
+ clock scan {2440588 12 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %P}
+} 43200
+test clock-29.947 {time parsing} {
+ clock scan {2440588 12:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 43200
+test clock-29.948 {time parsing} {
+ clock scan {2440588 12:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 43200
+test clock-29.949 {time parsing} {
+ clock scan {2440588 12:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43200
+test clock-29.950 {time parsing} {
+ clock scan {2440588 12:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43200
+test clock-29.951 {time parsing} {
+ clock scan {2440588 xii pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %P}
+} 43200
+test clock-29.952 {time parsing} {
+ clock scan {2440588 xii:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 43200
+test clock-29.953 {time parsing} {
+ clock scan {2440588 xii:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 43200
+test clock-29.954 {time parsing} {
+ clock scan {2440588 xii:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43200
+test clock-29.955 {time parsing} {
+ clock scan {2440588 xii:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43200
+test clock-29.956 {time parsing} {
+ clock scan {2440588 xii pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %P}
+} 43200
+test clock-29.957 {time parsing} {
+ clock scan {2440588 xii:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 43200
+test clock-29.958 {time parsing} {
+ clock scan {2440588 xii:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 43200
+test clock-29.959 {time parsing} {
+ clock scan {2440588 xii:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43200
+test clock-29.960 {time parsing} {
+ clock scan {2440588 xii:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43200
+test clock-29.961 {time parsing} {
+ clock scan {2440588 12:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43201
+test clock-29.962 {time parsing} {
+ clock scan {2440588 12:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43201
+test clock-29.963 {time parsing} {
+ clock scan {2440588 12:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43201
+test clock-29.964 {time parsing} {
+ clock scan {2440588 12:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43201
+test clock-29.965 {time parsing} {
+ clock scan {2440588 xii:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43201
+test clock-29.966 {time parsing} {
+ clock scan {2440588 xii:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43201
+test clock-29.967 {time parsing} {
+ clock scan {2440588 xii:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43201
+test clock-29.968 {time parsing} {
+ clock scan {2440588 xii:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43201
+test clock-29.969 {time parsing} {
+ clock scan {2440588 12:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43201
+test clock-29.970 {time parsing} {
+ clock scan {2440588 12:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43201
+test clock-29.971 {time parsing} {
+ clock scan {2440588 12:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43201
+test clock-29.972 {time parsing} {
+ clock scan {2440588 12:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43201
+test clock-29.973 {time parsing} {
+ clock scan {2440588 xii:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43201
+test clock-29.974 {time parsing} {
+ clock scan {2440588 xii:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43201
+test clock-29.975 {time parsing} {
+ clock scan {2440588 xii:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43201
+test clock-29.976 {time parsing} {
+ clock scan {2440588 xii:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43201
+test clock-29.977 {time parsing} {
+ clock scan {2440588 12:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43201
+test clock-29.978 {time parsing} {
+ clock scan {2440588 12:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43201
+test clock-29.979 {time parsing} {
+ clock scan {2440588 12:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43201
+test clock-29.980 {time parsing} {
+ clock scan {2440588 12:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43201
+test clock-29.981 {time parsing} {
+ clock scan {2440588 xii:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43201
+test clock-29.982 {time parsing} {
+ clock scan {2440588 xii:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43201
+test clock-29.983 {time parsing} {
+ clock scan {2440588 xii:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43201
+test clock-29.984 {time parsing} {
+ clock scan {2440588 xii:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43201
+test clock-29.985 {time parsing} {
+ clock scan {2440588 12:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43259
+test clock-29.986 {time parsing} {
+ clock scan {2440588 12:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43259
+test clock-29.987 {time parsing} {
+ clock scan {2440588 12:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43259
+test clock-29.988 {time parsing} {
+ clock scan {2440588 12:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43259
+test clock-29.989 {time parsing} {
+ clock scan {2440588 xii:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43259
+test clock-29.990 {time parsing} {
+ clock scan {2440588 xii:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43259
+test clock-29.991 {time parsing} {
+ clock scan {2440588 xii:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43259
+test clock-29.992 {time parsing} {
+ clock scan {2440588 xii:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43259
+test clock-29.993 {time parsing} {
+ clock scan {2440588 12:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43259
+test clock-29.994 {time parsing} {
+ clock scan {2440588 12:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43259
+test clock-29.995 {time parsing} {
+ clock scan {2440588 12:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43259
+test clock-29.996 {time parsing} {
+ clock scan {2440588 12:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43259
+test clock-29.997 {time parsing} {
+ clock scan {2440588 xii:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43259
+test clock-29.998 {time parsing} {
+ clock scan {2440588 xii:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43259
+test clock-29.999 {time parsing} {
+ clock scan {2440588 xii:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43259
+test clock-29.1000 {time parsing} {
+ clock scan {2440588 xii:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43259
+test clock-29.1001 {time parsing} {
+ clock scan {2440588 12:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43259
+test clock-29.1002 {time parsing} {
+ clock scan {2440588 12:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43259
+test clock-29.1003 {time parsing} {
+ clock scan {2440588 12:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43259
+test clock-29.1004 {time parsing} {
+ clock scan {2440588 12:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43259
+test clock-29.1005 {time parsing} {
+ clock scan {2440588 xii:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43259
+test clock-29.1006 {time parsing} {
+ clock scan {2440588 xii:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43259
+test clock-29.1007 {time parsing} {
+ clock scan {2440588 xii:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43259
+test clock-29.1008 {time parsing} {
+ clock scan {2440588 xii:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43259
+test clock-29.1009 {time parsing} {
+ clock scan {2440588 12:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 43260
+test clock-29.1010 {time parsing} {
+ clock scan {2440588 12:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 43260
+test clock-29.1011 {time parsing} {
+ clock scan {2440588 12:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43260
+test clock-29.1012 {time parsing} {
+ clock scan {2440588 12:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43260
+test clock-29.1013 {time parsing} {
+ clock scan {2440588 12:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 43260
+test clock-29.1014 {time parsing} {
+ clock scan {2440588 12:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 43260
+test clock-29.1015 {time parsing} {
+ clock scan {2440588 12:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43260
+test clock-29.1016 {time parsing} {
+ clock scan {2440588 12:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43260
+test clock-29.1017 {time parsing} {
+ clock scan {2440588 xii:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 43260
+test clock-29.1018 {time parsing} {
+ clock scan {2440588 xii:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 43260
+test clock-29.1019 {time parsing} {
+ clock scan {2440588 xii:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43260
+test clock-29.1020 {time parsing} {
+ clock scan {2440588 xii:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43260
+test clock-29.1021 {time parsing} {
+ clock scan {2440588 xii:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 43260
+test clock-29.1022 {time parsing} {
+ clock scan {2440588 xii:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 43260
+test clock-29.1023 {time parsing} {
+ clock scan {2440588 xii:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43260
+test clock-29.1024 {time parsing} {
+ clock scan {2440588 xii:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43260
+test clock-29.1025 {time parsing} {
+ clock scan {2440588 12:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 43260
+test clock-29.1026 {time parsing} {
+ clock scan {2440588 12:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 43260
+test clock-29.1027 {time parsing} {
+ clock scan {2440588 12:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43260
+test clock-29.1028 {time parsing} {
+ clock scan {2440588 12:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43260
+test clock-29.1029 {time parsing} {
+ clock scan {2440588 12:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 43260
+test clock-29.1030 {time parsing} {
+ clock scan {2440588 12:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 43260
+test clock-29.1031 {time parsing} {
+ clock scan {2440588 12:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43260
+test clock-29.1032 {time parsing} {
+ clock scan {2440588 12:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43260
+test clock-29.1033 {time parsing} {
+ clock scan {2440588 xii:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 43260
+test clock-29.1034 {time parsing} {
+ clock scan {2440588 xii:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 43260
+test clock-29.1035 {time parsing} {
+ clock scan {2440588 xii:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43260
+test clock-29.1036 {time parsing} {
+ clock scan {2440588 xii:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43260
+test clock-29.1037 {time parsing} {
+ clock scan {2440588 xii:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 43260
+test clock-29.1038 {time parsing} {
+ clock scan {2440588 xii:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 43260
+test clock-29.1039 {time parsing} {
+ clock scan {2440588 xii:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43260
+test clock-29.1040 {time parsing} {
+ clock scan {2440588 xii:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43260
+test clock-29.1041 {time parsing} {
+ clock scan {2440588 12:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 43260
+test clock-29.1042 {time parsing} {
+ clock scan {2440588 12:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 43260
+test clock-29.1043 {time parsing} {
+ clock scan {2440588 12:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43260
+test clock-29.1044 {time parsing} {
+ clock scan {2440588 12:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43260
+test clock-29.1045 {time parsing} {
+ clock scan {2440588 12:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 43260
+test clock-29.1046 {time parsing} {
+ clock scan {2440588 12:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 43260
+test clock-29.1047 {time parsing} {
+ clock scan {2440588 12:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43260
+test clock-29.1048 {time parsing} {
+ clock scan {2440588 12:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43260
+test clock-29.1049 {time parsing} {
+ clock scan {2440588 xii:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 43260
+test clock-29.1050 {time parsing} {
+ clock scan {2440588 xii:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 43260
+test clock-29.1051 {time parsing} {
+ clock scan {2440588 xii:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43260
+test clock-29.1052 {time parsing} {
+ clock scan {2440588 xii:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43260
+test clock-29.1053 {time parsing} {
+ clock scan {2440588 xii:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 43260
+test clock-29.1054 {time parsing} {
+ clock scan {2440588 xii:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 43260
+test clock-29.1055 {time parsing} {
+ clock scan {2440588 xii:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43260
+test clock-29.1056 {time parsing} {
+ clock scan {2440588 xii:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43260
+test clock-29.1057 {time parsing} {
+ clock scan {2440588 12:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43261
+test clock-29.1058 {time parsing} {
+ clock scan {2440588 12:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43261
+test clock-29.1059 {time parsing} {
+ clock scan {2440588 12:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43261
+test clock-29.1060 {time parsing} {
+ clock scan {2440588 12:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43261
+test clock-29.1061 {time parsing} {
+ clock scan {2440588 xii:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43261
+test clock-29.1062 {time parsing} {
+ clock scan {2440588 xii:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43261
+test clock-29.1063 {time parsing} {
+ clock scan {2440588 xii:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43261
+test clock-29.1064 {time parsing} {
+ clock scan {2440588 xii:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43261
+test clock-29.1065 {time parsing} {
+ clock scan {2440588 12:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43261
+test clock-29.1066 {time parsing} {
+ clock scan {2440588 12:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43261
+test clock-29.1067 {time parsing} {
+ clock scan {2440588 12:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43261
+test clock-29.1068 {time parsing} {
+ clock scan {2440588 12:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43261
+test clock-29.1069 {time parsing} {
+ clock scan {2440588 xii:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43261
+test clock-29.1070 {time parsing} {
+ clock scan {2440588 xii:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43261
+test clock-29.1071 {time parsing} {
+ clock scan {2440588 xii:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43261
+test clock-29.1072 {time parsing} {
+ clock scan {2440588 xii:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43261
+test clock-29.1073 {time parsing} {
+ clock scan {2440588 12:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43261
+test clock-29.1074 {time parsing} {
+ clock scan {2440588 12:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43261
+test clock-29.1075 {time parsing} {
+ clock scan {2440588 12:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43261
+test clock-29.1076 {time parsing} {
+ clock scan {2440588 12:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43261
+test clock-29.1077 {time parsing} {
+ clock scan {2440588 xii:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43261
+test clock-29.1078 {time parsing} {
+ clock scan {2440588 xii:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43261
+test clock-29.1079 {time parsing} {
+ clock scan {2440588 xii:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43261
+test clock-29.1080 {time parsing} {
+ clock scan {2440588 xii:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43261
+test clock-29.1081 {time parsing} {
+ clock scan {2440588 12:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43319
+test clock-29.1082 {time parsing} {
+ clock scan {2440588 12:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43319
+test clock-29.1083 {time parsing} {
+ clock scan {2440588 12:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43319
+test clock-29.1084 {time parsing} {
+ clock scan {2440588 12:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43319
+test clock-29.1085 {time parsing} {
+ clock scan {2440588 xii:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43319
+test clock-29.1086 {time parsing} {
+ clock scan {2440588 xii:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43319
+test clock-29.1087 {time parsing} {
+ clock scan {2440588 xii:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43319
+test clock-29.1088 {time parsing} {
+ clock scan {2440588 xii:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43319
+test clock-29.1089 {time parsing} {
+ clock scan {2440588 12:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43319
+test clock-29.1090 {time parsing} {
+ clock scan {2440588 12:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43319
+test clock-29.1091 {time parsing} {
+ clock scan {2440588 12:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43319
+test clock-29.1092 {time parsing} {
+ clock scan {2440588 12:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43319
+test clock-29.1093 {time parsing} {
+ clock scan {2440588 xii:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43319
+test clock-29.1094 {time parsing} {
+ clock scan {2440588 xii:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43319
+test clock-29.1095 {time parsing} {
+ clock scan {2440588 xii:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43319
+test clock-29.1096 {time parsing} {
+ clock scan {2440588 xii:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43319
+test clock-29.1097 {time parsing} {
+ clock scan {2440588 12:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43319
+test clock-29.1098 {time parsing} {
+ clock scan {2440588 12:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43319
+test clock-29.1099 {time parsing} {
+ clock scan {2440588 12:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43319
+test clock-29.1100 {time parsing} {
+ clock scan {2440588 12:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43319
+test clock-29.1101 {time parsing} {
+ clock scan {2440588 xii:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43319
+test clock-29.1102 {time parsing} {
+ clock scan {2440588 xii:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43319
+test clock-29.1103 {time parsing} {
+ clock scan {2440588 xii:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43319
+test clock-29.1104 {time parsing} {
+ clock scan {2440588 xii:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43319
+test clock-29.1105 {time parsing} {
+ clock scan {2440588 12:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 46740
+test clock-29.1106 {time parsing} {
+ clock scan {2440588 12:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 46740
+test clock-29.1107 {time parsing} {
+ clock scan {2440588 12:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46740
+test clock-29.1108 {time parsing} {
+ clock scan {2440588 12:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46740
+test clock-29.1109 {time parsing} {
+ clock scan {2440588 12:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 46740
+test clock-29.1110 {time parsing} {
+ clock scan {2440588 12:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 46740
+test clock-29.1111 {time parsing} {
+ clock scan {2440588 12:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46740
+test clock-29.1112 {time parsing} {
+ clock scan {2440588 12:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46740
+test clock-29.1113 {time parsing} {
+ clock scan {2440588 xii:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 46740
+test clock-29.1114 {time parsing} {
+ clock scan {2440588 xii:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 46740
+test clock-29.1115 {time parsing} {
+ clock scan {2440588 xii:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46740
+test clock-29.1116 {time parsing} {
+ clock scan {2440588 xii:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46740
+test clock-29.1117 {time parsing} {
+ clock scan {2440588 xii:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 46740
+test clock-29.1118 {time parsing} {
+ clock scan {2440588 xii:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 46740
+test clock-29.1119 {time parsing} {
+ clock scan {2440588 xii:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46740
+test clock-29.1120 {time parsing} {
+ clock scan {2440588 xii:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46740
+test clock-29.1121 {time parsing} {
+ clock scan {2440588 12:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 46740
+test clock-29.1122 {time parsing} {
+ clock scan {2440588 12:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 46740
+test clock-29.1123 {time parsing} {
+ clock scan {2440588 12:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46740
+test clock-29.1124 {time parsing} {
+ clock scan {2440588 12:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46740
+test clock-29.1125 {time parsing} {
+ clock scan {2440588 12:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 46740
+test clock-29.1126 {time parsing} {
+ clock scan {2440588 12:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 46740
+test clock-29.1127 {time parsing} {
+ clock scan {2440588 12:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46740
+test clock-29.1128 {time parsing} {
+ clock scan {2440588 12:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46740
+test clock-29.1129 {time parsing} {
+ clock scan {2440588 xii:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 46740
+test clock-29.1130 {time parsing} {
+ clock scan {2440588 xii:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 46740
+test clock-29.1131 {time parsing} {
+ clock scan {2440588 xii:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46740
+test clock-29.1132 {time parsing} {
+ clock scan {2440588 xii:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46740
+test clock-29.1133 {time parsing} {
+ clock scan {2440588 xii:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 46740
+test clock-29.1134 {time parsing} {
+ clock scan {2440588 xii:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 46740
+test clock-29.1135 {time parsing} {
+ clock scan {2440588 xii:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46740
+test clock-29.1136 {time parsing} {
+ clock scan {2440588 xii:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46740
+test clock-29.1137 {time parsing} {
+ clock scan {2440588 12:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 46740
+test clock-29.1138 {time parsing} {
+ clock scan {2440588 12:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 46740
+test clock-29.1139 {time parsing} {
+ clock scan {2440588 12:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46740
+test clock-29.1140 {time parsing} {
+ clock scan {2440588 12:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46740
+test clock-29.1141 {time parsing} {
+ clock scan {2440588 12:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 46740
+test clock-29.1142 {time parsing} {
+ clock scan {2440588 12:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 46740
+test clock-29.1143 {time parsing} {
+ clock scan {2440588 12:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46740
+test clock-29.1144 {time parsing} {
+ clock scan {2440588 12:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46740
+test clock-29.1145 {time parsing} {
+ clock scan {2440588 xii:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 46740
+test clock-29.1146 {time parsing} {
+ clock scan {2440588 xii:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 46740
+test clock-29.1147 {time parsing} {
+ clock scan {2440588 xii:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46740
+test clock-29.1148 {time parsing} {
+ clock scan {2440588 xii:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46740
+test clock-29.1149 {time parsing} {
+ clock scan {2440588 xii:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 46740
+test clock-29.1150 {time parsing} {
+ clock scan {2440588 xii:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 46740
+test clock-29.1151 {time parsing} {
+ clock scan {2440588 xii:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46740
+test clock-29.1152 {time parsing} {
+ clock scan {2440588 xii:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46740
+test clock-29.1153 {time parsing} {
+ clock scan {2440588 12:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46741
+test clock-29.1154 {time parsing} {
+ clock scan {2440588 12:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46741
+test clock-29.1155 {time parsing} {
+ clock scan {2440588 12:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46741
+test clock-29.1156 {time parsing} {
+ clock scan {2440588 12:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46741
+test clock-29.1157 {time parsing} {
+ clock scan {2440588 xii:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46741
+test clock-29.1158 {time parsing} {
+ clock scan {2440588 xii:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46741
+test clock-29.1159 {time parsing} {
+ clock scan {2440588 xii:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46741
+test clock-29.1160 {time parsing} {
+ clock scan {2440588 xii:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46741
+test clock-29.1161 {time parsing} {
+ clock scan {2440588 12:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46741
+test clock-29.1162 {time parsing} {
+ clock scan {2440588 12:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46741
+test clock-29.1163 {time parsing} {
+ clock scan {2440588 12:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46741
+test clock-29.1164 {time parsing} {
+ clock scan {2440588 12:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46741
+test clock-29.1165 {time parsing} {
+ clock scan {2440588 xii:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46741
+test clock-29.1166 {time parsing} {
+ clock scan {2440588 xii:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46741
+test clock-29.1167 {time parsing} {
+ clock scan {2440588 xii:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46741
+test clock-29.1168 {time parsing} {
+ clock scan {2440588 xii:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46741
+test clock-29.1169 {time parsing} {
+ clock scan {2440588 12:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46741
+test clock-29.1170 {time parsing} {
+ clock scan {2440588 12:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46741
+test clock-29.1171 {time parsing} {
+ clock scan {2440588 12:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46741
+test clock-29.1172 {time parsing} {
+ clock scan {2440588 12:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46741
+test clock-29.1173 {time parsing} {
+ clock scan {2440588 xii:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46741
+test clock-29.1174 {time parsing} {
+ clock scan {2440588 xii:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46741
+test clock-29.1175 {time parsing} {
+ clock scan {2440588 xii:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46741
+test clock-29.1176 {time parsing} {
+ clock scan {2440588 xii:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46741
+test clock-29.1177 {time parsing} {
+ clock scan {2440588 12:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46799
+test clock-29.1178 {time parsing} {
+ clock scan {2440588 12:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46799
+test clock-29.1179 {time parsing} {
+ clock scan {2440588 12:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46799
+test clock-29.1180 {time parsing} {
+ clock scan {2440588 12:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46799
+test clock-29.1181 {time parsing} {
+ clock scan {2440588 xii:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46799
+test clock-29.1182 {time parsing} {
+ clock scan {2440588 xii:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46799
+test clock-29.1183 {time parsing} {
+ clock scan {2440588 xii:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46799
+test clock-29.1184 {time parsing} {
+ clock scan {2440588 xii:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46799
+test clock-29.1185 {time parsing} {
+ clock scan {2440588 12:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46799
+test clock-29.1186 {time parsing} {
+ clock scan {2440588 12:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46799
+test clock-29.1187 {time parsing} {
+ clock scan {2440588 12:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46799
+test clock-29.1188 {time parsing} {
+ clock scan {2440588 12:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46799
+test clock-29.1189 {time parsing} {
+ clock scan {2440588 xii:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46799
+test clock-29.1190 {time parsing} {
+ clock scan {2440588 xii:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46799
+test clock-29.1191 {time parsing} {
+ clock scan {2440588 xii:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46799
+test clock-29.1192 {time parsing} {
+ clock scan {2440588 xii:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46799
+test clock-29.1193 {time parsing} {
+ clock scan {2440588 12:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46799
+test clock-29.1194 {time parsing} {
+ clock scan {2440588 12:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46799
+test clock-29.1195 {time parsing} {
+ clock scan {2440588 12:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46799
+test clock-29.1196 {time parsing} {
+ clock scan {2440588 12:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46799
+test clock-29.1197 {time parsing} {
+ clock scan {2440588 xii:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46799
+test clock-29.1198 {time parsing} {
+ clock scan {2440588 xii:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46799
+test clock-29.1199 {time parsing} {
+ clock scan {2440588 xii:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46799
+test clock-29.1200 {time parsing} {
+ clock scan {2440588 xii:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46799
+test clock-29.1201 {time parsing} {
+ clock scan {2440588 13 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H }
+} 46800
+test clock-29.1202 {time parsing} {
+ clock scan {2440588 13:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 46800
+test clock-29.1203 {time parsing} {
+ clock scan {2440588 13:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 46800
+test clock-29.1204 {time parsing} {
+ clock scan {2440588 13:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46800
+test clock-29.1205 {time parsing} {
+ clock scan {2440588 13:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46800
+test clock-29.1206 {time parsing} {
+ clock scan {2440588 13 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k }
+} 46800
+test clock-29.1207 {time parsing} {
+ clock scan {2440588 13:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 46800
+test clock-29.1208 {time parsing} {
+ clock scan {2440588 13:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 46800
+test clock-29.1209 {time parsing} {
+ clock scan {2440588 13:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46800
+test clock-29.1210 {time parsing} {
+ clock scan {2440588 13:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46800
+test clock-29.1211 {time parsing} {
+ clock scan {2440588 xiii } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH }
+} 46800
+test clock-29.1212 {time parsing} {
+ clock scan {2440588 xiii:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 46800
+test clock-29.1213 {time parsing} {
+ clock scan {2440588 xiii:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 46800
+test clock-29.1214 {time parsing} {
+ clock scan {2440588 xiii:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46800
+test clock-29.1215 {time parsing} {
+ clock scan {2440588 xiii:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46800
+test clock-29.1216 {time parsing} {
+ clock scan {2440588 xiii } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok }
+} 46800
+test clock-29.1217 {time parsing} {
+ clock scan {2440588 xiii:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 46800
+test clock-29.1218 {time parsing} {
+ clock scan {2440588 xiii:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 46800
+test clock-29.1219 {time parsing} {
+ clock scan {2440588 xiii:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46800
+test clock-29.1220 {time parsing} {
+ clock scan {2440588 xiii:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46800
+test clock-29.1221 {time parsing} {
+ clock scan {2440588 01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %p}
+} 46800
+test clock-29.1222 {time parsing} {
+ clock scan {2440588 01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 46800
+test clock-29.1223 {time parsing} {
+ clock scan {2440588 01:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 46800
+test clock-29.1224 {time parsing} {
+ clock scan {2440588 01:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46800
+test clock-29.1225 {time parsing} {
+ clock scan {2440588 01:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46800
+test clock-29.1226 {time parsing} {
+ clock scan {2440588 1 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %p}
+} 46800
+test clock-29.1227 {time parsing} {
+ clock scan {2440588 1:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 46800
+test clock-29.1228 {time parsing} {
+ clock scan {2440588 1:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 46800
+test clock-29.1229 {time parsing} {
+ clock scan {2440588 1:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46800
+test clock-29.1230 {time parsing} {
+ clock scan {2440588 1:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46800
+test clock-29.1231 {time parsing} {
+ clock scan {2440588 i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %p}
+} 46800
+test clock-29.1232 {time parsing} {
+ clock scan {2440588 i:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 46800
+test clock-29.1233 {time parsing} {
+ clock scan {2440588 i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 46800
+test clock-29.1234 {time parsing} {
+ clock scan {2440588 i:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46800
+test clock-29.1235 {time parsing} {
+ clock scan {2440588 i:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46800
+test clock-29.1236 {time parsing} {
+ clock scan {2440588 i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %p}
+} 46800
+test clock-29.1237 {time parsing} {
+ clock scan {2440588 i:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 46800
+test clock-29.1238 {time parsing} {
+ clock scan {2440588 i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 46800
+test clock-29.1239 {time parsing} {
+ clock scan {2440588 i:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46800
+test clock-29.1240 {time parsing} {
+ clock scan {2440588 i:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46800
+test clock-29.1241 {time parsing} {
+ clock scan {2440588 01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %P}
+} 46800
+test clock-29.1242 {time parsing} {
+ clock scan {2440588 01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 46800
+test clock-29.1243 {time parsing} {
+ clock scan {2440588 01:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 46800
+test clock-29.1244 {time parsing} {
+ clock scan {2440588 01:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46800
+test clock-29.1245 {time parsing} {
+ clock scan {2440588 01:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46800
+test clock-29.1246 {time parsing} {
+ clock scan {2440588 1 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %P}
+} 46800
+test clock-29.1247 {time parsing} {
+ clock scan {2440588 1:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 46800
+test clock-29.1248 {time parsing} {
+ clock scan {2440588 1:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 46800
+test clock-29.1249 {time parsing} {
+ clock scan {2440588 1:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46800
+test clock-29.1250 {time parsing} {
+ clock scan {2440588 1:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46800
+test clock-29.1251 {time parsing} {
+ clock scan {2440588 i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %P}
+} 46800
+test clock-29.1252 {time parsing} {
+ clock scan {2440588 i:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 46800
+test clock-29.1253 {time parsing} {
+ clock scan {2440588 i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 46800
+test clock-29.1254 {time parsing} {
+ clock scan {2440588 i:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46800
+test clock-29.1255 {time parsing} {
+ clock scan {2440588 i:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46800
+test clock-29.1256 {time parsing} {
+ clock scan {2440588 i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %P}
+} 46800
+test clock-29.1257 {time parsing} {
+ clock scan {2440588 i:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 46800
+test clock-29.1258 {time parsing} {
+ clock scan {2440588 i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 46800
+test clock-29.1259 {time parsing} {
+ clock scan {2440588 i:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46800
+test clock-29.1260 {time parsing} {
+ clock scan {2440588 i:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46800
+test clock-29.1261 {time parsing} {
+ clock scan {2440588 13:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46801
+test clock-29.1262 {time parsing} {
+ clock scan {2440588 13:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46801
+test clock-29.1263 {time parsing} {
+ clock scan {2440588 13:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46801
+test clock-29.1264 {time parsing} {
+ clock scan {2440588 13:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46801
+test clock-29.1265 {time parsing} {
+ clock scan {2440588 xiii:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46801
+test clock-29.1266 {time parsing} {
+ clock scan {2440588 xiii:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46801
+test clock-29.1267 {time parsing} {
+ clock scan {2440588 xiii:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46801
+test clock-29.1268 {time parsing} {
+ clock scan {2440588 xiii:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46801
+test clock-29.1269 {time parsing} {
+ clock scan {2440588 01:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46801
+test clock-29.1270 {time parsing} {
+ clock scan {2440588 01:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46801
+test clock-29.1271 {time parsing} {
+ clock scan {2440588 1:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46801
+test clock-29.1272 {time parsing} {
+ clock scan {2440588 1:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46801
+test clock-29.1273 {time parsing} {
+ clock scan {2440588 i:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46801
+test clock-29.1274 {time parsing} {
+ clock scan {2440588 i:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46801
+test clock-29.1275 {time parsing} {
+ clock scan {2440588 i:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46801
+test clock-29.1276 {time parsing} {
+ clock scan {2440588 i:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46801
+test clock-29.1277 {time parsing} {
+ clock scan {2440588 01:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46801
+test clock-29.1278 {time parsing} {
+ clock scan {2440588 01:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46801
+test clock-29.1279 {time parsing} {
+ clock scan {2440588 1:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46801
+test clock-29.1280 {time parsing} {
+ clock scan {2440588 1:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46801
+test clock-29.1281 {time parsing} {
+ clock scan {2440588 i:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46801
+test clock-29.1282 {time parsing} {
+ clock scan {2440588 i:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46801
+test clock-29.1283 {time parsing} {
+ clock scan {2440588 i:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46801
+test clock-29.1284 {time parsing} {
+ clock scan {2440588 i:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46801
+test clock-29.1285 {time parsing} {
+ clock scan {2440588 13:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46859
+test clock-29.1286 {time parsing} {
+ clock scan {2440588 13:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46859
+test clock-29.1287 {time parsing} {
+ clock scan {2440588 13:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46859
+test clock-29.1288 {time parsing} {
+ clock scan {2440588 13:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46859
+test clock-29.1289 {time parsing} {
+ clock scan {2440588 xiii:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46859
+test clock-29.1290 {time parsing} {
+ clock scan {2440588 xiii:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46859
+test clock-29.1291 {time parsing} {
+ clock scan {2440588 xiii:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46859
+test clock-29.1292 {time parsing} {
+ clock scan {2440588 xiii:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46859
+test clock-29.1293 {time parsing} {
+ clock scan {2440588 01:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46859
+test clock-29.1294 {time parsing} {
+ clock scan {2440588 01:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46859
+test clock-29.1295 {time parsing} {
+ clock scan {2440588 1:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46859
+test clock-29.1296 {time parsing} {
+ clock scan {2440588 1:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46859
+test clock-29.1297 {time parsing} {
+ clock scan {2440588 i:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46859
+test clock-29.1298 {time parsing} {
+ clock scan {2440588 i:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46859
+test clock-29.1299 {time parsing} {
+ clock scan {2440588 i:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46859
+test clock-29.1300 {time parsing} {
+ clock scan {2440588 i:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46859
+test clock-29.1301 {time parsing} {
+ clock scan {2440588 01:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46859
+test clock-29.1302 {time parsing} {
+ clock scan {2440588 01:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46859
+test clock-29.1303 {time parsing} {
+ clock scan {2440588 1:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46859
+test clock-29.1304 {time parsing} {
+ clock scan {2440588 1:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46859
+test clock-29.1305 {time parsing} {
+ clock scan {2440588 i:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46859
+test clock-29.1306 {time parsing} {
+ clock scan {2440588 i:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46859
+test clock-29.1307 {time parsing} {
+ clock scan {2440588 i:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46859
+test clock-29.1308 {time parsing} {
+ clock scan {2440588 i:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46859
+test clock-29.1309 {time parsing} {
+ clock scan {2440588 13:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 46860
+test clock-29.1310 {time parsing} {
+ clock scan {2440588 13:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 46860
+test clock-29.1311 {time parsing} {
+ clock scan {2440588 13:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46860
+test clock-29.1312 {time parsing} {
+ clock scan {2440588 13:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46860
+test clock-29.1313 {time parsing} {
+ clock scan {2440588 13:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 46860
+test clock-29.1314 {time parsing} {
+ clock scan {2440588 13:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 46860
+test clock-29.1315 {time parsing} {
+ clock scan {2440588 13:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46860
+test clock-29.1316 {time parsing} {
+ clock scan {2440588 13:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46860
+test clock-29.1317 {time parsing} {
+ clock scan {2440588 xiii:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 46860
+test clock-29.1318 {time parsing} {
+ clock scan {2440588 xiii:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 46860
+test clock-29.1319 {time parsing} {
+ clock scan {2440588 xiii:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46860
+test clock-29.1320 {time parsing} {
+ clock scan {2440588 xiii:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46860
+test clock-29.1321 {time parsing} {
+ clock scan {2440588 xiii:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 46860
+test clock-29.1322 {time parsing} {
+ clock scan {2440588 xiii:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 46860
+test clock-29.1323 {time parsing} {
+ clock scan {2440588 xiii:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46860
+test clock-29.1324 {time parsing} {
+ clock scan {2440588 xiii:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46860
+test clock-29.1325 {time parsing} {
+ clock scan {2440588 01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 46860
+test clock-29.1326 {time parsing} {
+ clock scan {2440588 01:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 46860
+test clock-29.1327 {time parsing} {
+ clock scan {2440588 01:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46860
+test clock-29.1328 {time parsing} {
+ clock scan {2440588 01:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46860
+test clock-29.1329 {time parsing} {
+ clock scan {2440588 1:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 46860
+test clock-29.1330 {time parsing} {
+ clock scan {2440588 1:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 46860
+test clock-29.1331 {time parsing} {
+ clock scan {2440588 1:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46860
+test clock-29.1332 {time parsing} {
+ clock scan {2440588 1:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46860
+test clock-29.1333 {time parsing} {
+ clock scan {2440588 i:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 46860
+test clock-29.1334 {time parsing} {
+ clock scan {2440588 i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 46860
+test clock-29.1335 {time parsing} {
+ clock scan {2440588 i:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46860
+test clock-29.1336 {time parsing} {
+ clock scan {2440588 i:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46860
+test clock-29.1337 {time parsing} {
+ clock scan {2440588 i:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 46860
+test clock-29.1338 {time parsing} {
+ clock scan {2440588 i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 46860
+test clock-29.1339 {time parsing} {
+ clock scan {2440588 i:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46860
+test clock-29.1340 {time parsing} {
+ clock scan {2440588 i:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46860
+test clock-29.1341 {time parsing} {
+ clock scan {2440588 01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 46860
+test clock-29.1342 {time parsing} {
+ clock scan {2440588 01:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 46860
+test clock-29.1343 {time parsing} {
+ clock scan {2440588 01:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46860
+test clock-29.1344 {time parsing} {
+ clock scan {2440588 01:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46860
+test clock-29.1345 {time parsing} {
+ clock scan {2440588 1:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 46860
+test clock-29.1346 {time parsing} {
+ clock scan {2440588 1:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 46860
+test clock-29.1347 {time parsing} {
+ clock scan {2440588 1:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46860
+test clock-29.1348 {time parsing} {
+ clock scan {2440588 1:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46860
+test clock-29.1349 {time parsing} {
+ clock scan {2440588 i:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 46860
+test clock-29.1350 {time parsing} {
+ clock scan {2440588 i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 46860
+test clock-29.1351 {time parsing} {
+ clock scan {2440588 i:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46860
+test clock-29.1352 {time parsing} {
+ clock scan {2440588 i:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46860
+test clock-29.1353 {time parsing} {
+ clock scan {2440588 i:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 46860
+test clock-29.1354 {time parsing} {
+ clock scan {2440588 i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 46860
+test clock-29.1355 {time parsing} {
+ clock scan {2440588 i:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46860
+test clock-29.1356 {time parsing} {
+ clock scan {2440588 i:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46860
+test clock-29.1357 {time parsing} {
+ clock scan {2440588 13:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46861
+test clock-29.1358 {time parsing} {
+ clock scan {2440588 13:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46861
+test clock-29.1359 {time parsing} {
+ clock scan {2440588 13:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46861
+test clock-29.1360 {time parsing} {
+ clock scan {2440588 13:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46861
+test clock-29.1361 {time parsing} {
+ clock scan {2440588 xiii:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46861
+test clock-29.1362 {time parsing} {
+ clock scan {2440588 xiii:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46861
+test clock-29.1363 {time parsing} {
+ clock scan {2440588 xiii:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46861
+test clock-29.1364 {time parsing} {
+ clock scan {2440588 xiii:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46861
+test clock-29.1365 {time parsing} {
+ clock scan {2440588 01:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46861
+test clock-29.1366 {time parsing} {
+ clock scan {2440588 01:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46861
+test clock-29.1367 {time parsing} {
+ clock scan {2440588 1:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46861
+test clock-29.1368 {time parsing} {
+ clock scan {2440588 1:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46861
+test clock-29.1369 {time parsing} {
+ clock scan {2440588 i:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46861
+test clock-29.1370 {time parsing} {
+ clock scan {2440588 i:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46861
+test clock-29.1371 {time parsing} {
+ clock scan {2440588 i:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46861
+test clock-29.1372 {time parsing} {
+ clock scan {2440588 i:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46861
+test clock-29.1373 {time parsing} {
+ clock scan {2440588 01:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46861
+test clock-29.1374 {time parsing} {
+ clock scan {2440588 01:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46861
+test clock-29.1375 {time parsing} {
+ clock scan {2440588 1:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46861
+test clock-29.1376 {time parsing} {
+ clock scan {2440588 1:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46861
+test clock-29.1377 {time parsing} {
+ clock scan {2440588 i:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46861
+test clock-29.1378 {time parsing} {
+ clock scan {2440588 i:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46861
+test clock-29.1379 {time parsing} {
+ clock scan {2440588 i:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46861
+test clock-29.1380 {time parsing} {
+ clock scan {2440588 i:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46861
+test clock-29.1381 {time parsing} {
+ clock scan {2440588 13:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46919
+test clock-29.1382 {time parsing} {
+ clock scan {2440588 13:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46919
+test clock-29.1383 {time parsing} {
+ clock scan {2440588 13:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46919
+test clock-29.1384 {time parsing} {
+ clock scan {2440588 13:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46919
+test clock-29.1385 {time parsing} {
+ clock scan {2440588 xiii:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46919
+test clock-29.1386 {time parsing} {
+ clock scan {2440588 xiii:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46919
+test clock-29.1387 {time parsing} {
+ clock scan {2440588 xiii:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46919
+test clock-29.1388 {time parsing} {
+ clock scan {2440588 xiii:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46919
+test clock-29.1389 {time parsing} {
+ clock scan {2440588 01:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46919
+test clock-29.1390 {time parsing} {
+ clock scan {2440588 01:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46919
+test clock-29.1391 {time parsing} {
+ clock scan {2440588 1:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46919
+test clock-29.1392 {time parsing} {
+ clock scan {2440588 1:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46919
+test clock-29.1393 {time parsing} {
+ clock scan {2440588 i:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46919
+test clock-29.1394 {time parsing} {
+ clock scan {2440588 i:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46919
+test clock-29.1395 {time parsing} {
+ clock scan {2440588 i:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46919
+test clock-29.1396 {time parsing} {
+ clock scan {2440588 i:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46919
+test clock-29.1397 {time parsing} {
+ clock scan {2440588 01:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46919
+test clock-29.1398 {time parsing} {
+ clock scan {2440588 01:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46919
+test clock-29.1399 {time parsing} {
+ clock scan {2440588 1:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46919
+test clock-29.1400 {time parsing} {
+ clock scan {2440588 1:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46919
+test clock-29.1401 {time parsing} {
+ clock scan {2440588 i:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46919
+test clock-29.1402 {time parsing} {
+ clock scan {2440588 i:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46919
+test clock-29.1403 {time parsing} {
+ clock scan {2440588 i:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46919
+test clock-29.1404 {time parsing} {
+ clock scan {2440588 i:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46919
+test clock-29.1405 {time parsing} {
+ clock scan {2440588 13:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 50340
+test clock-29.1406 {time parsing} {
+ clock scan {2440588 13:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 50340
+test clock-29.1407 {time parsing} {
+ clock scan {2440588 13:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 50340
+test clock-29.1408 {time parsing} {
+ clock scan {2440588 13:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 50340
+test clock-29.1409 {time parsing} {
+ clock scan {2440588 13:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 50340
+test clock-29.1410 {time parsing} {
+ clock scan {2440588 13:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 50340
+test clock-29.1411 {time parsing} {
+ clock scan {2440588 13:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 50340
+test clock-29.1412 {time parsing} {
+ clock scan {2440588 13:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 50340
+test clock-29.1413 {time parsing} {
+ clock scan {2440588 xiii:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 50340
+test clock-29.1414 {time parsing} {
+ clock scan {2440588 xiii:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 50340
+test clock-29.1415 {time parsing} {
+ clock scan {2440588 xiii:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 50340
+test clock-29.1416 {time parsing} {
+ clock scan {2440588 xiii:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 50340
+test clock-29.1417 {time parsing} {
+ clock scan {2440588 xiii:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 50340
+test clock-29.1418 {time parsing} {
+ clock scan {2440588 xiii:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 50340
+test clock-29.1419 {time parsing} {
+ clock scan {2440588 xiii:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 50340
+test clock-29.1420 {time parsing} {
+ clock scan {2440588 xiii:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 50340
+test clock-29.1421 {time parsing} {
+ clock scan {2440588 01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 50340
+test clock-29.1422 {time parsing} {
+ clock scan {2440588 01:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 50340
+test clock-29.1423 {time parsing} {
+ clock scan {2440588 01:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 50340
+test clock-29.1424 {time parsing} {
+ clock scan {2440588 01:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 50340
+test clock-29.1425 {time parsing} {
+ clock scan {2440588 1:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 50340
+test clock-29.1426 {time parsing} {
+ clock scan {2440588 1:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 50340
+test clock-29.1427 {time parsing} {
+ clock scan {2440588 1:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 50340
+test clock-29.1428 {time parsing} {
+ clock scan {2440588 1:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 50340
+test clock-29.1429 {time parsing} {
+ clock scan {2440588 i:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 50340
+test clock-29.1430 {time parsing} {
+ clock scan {2440588 i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 50340
+test clock-29.1431 {time parsing} {
+ clock scan {2440588 i:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 50340
+test clock-29.1432 {time parsing} {
+ clock scan {2440588 i:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 50340
+test clock-29.1433 {time parsing} {
+ clock scan {2440588 i:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 50340
+test clock-29.1434 {time parsing} {
+ clock scan {2440588 i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 50340
+test clock-29.1435 {time parsing} {
+ clock scan {2440588 i:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 50340
+test clock-29.1436 {time parsing} {
+ clock scan {2440588 i:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 50340
+test clock-29.1437 {time parsing} {
+ clock scan {2440588 01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 50340
+test clock-29.1438 {time parsing} {
+ clock scan {2440588 01:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 50340
+test clock-29.1439 {time parsing} {
+ clock scan {2440588 01:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 50340
+test clock-29.1440 {time parsing} {
+ clock scan {2440588 01:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 50340
+test clock-29.1441 {time parsing} {
+ clock scan {2440588 1:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 50340
+test clock-29.1442 {time parsing} {
+ clock scan {2440588 1:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 50340
+test clock-29.1443 {time parsing} {
+ clock scan {2440588 1:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 50340
+test clock-29.1444 {time parsing} {
+ clock scan {2440588 1:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 50340
+test clock-29.1445 {time parsing} {
+ clock scan {2440588 i:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 50340
+test clock-29.1446 {time parsing} {
+ clock scan {2440588 i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 50340
+test clock-29.1447 {time parsing} {
+ clock scan {2440588 i:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 50340
+test clock-29.1448 {time parsing} {
+ clock scan {2440588 i:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 50340
+test clock-29.1449 {time parsing} {
+ clock scan {2440588 i:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 50340
+test clock-29.1450 {time parsing} {
+ clock scan {2440588 i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 50340
+test clock-29.1451 {time parsing} {
+ clock scan {2440588 i:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 50340
+test clock-29.1452 {time parsing} {
+ clock scan {2440588 i:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 50340
+test clock-29.1453 {time parsing} {
+ clock scan {2440588 13:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 50341
+test clock-29.1454 {time parsing} {
+ clock scan {2440588 13:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 50341
+test clock-29.1455 {time parsing} {
+ clock scan {2440588 13:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 50341
+test clock-29.1456 {time parsing} {
+ clock scan {2440588 13:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 50341
+test clock-29.1457 {time parsing} {
+ clock scan {2440588 xiii:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 50341
+test clock-29.1458 {time parsing} {
+ clock scan {2440588 xiii:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 50341
+test clock-29.1459 {time parsing} {
+ clock scan {2440588 xiii:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 50341
+test clock-29.1460 {time parsing} {
+ clock scan {2440588 xiii:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 50341
+test clock-29.1461 {time parsing} {
+ clock scan {2440588 01:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 50341
+test clock-29.1462 {time parsing} {
+ clock scan {2440588 01:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 50341
+test clock-29.1463 {time parsing} {
+ clock scan {2440588 1:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 50341
+test clock-29.1464 {time parsing} {
+ clock scan {2440588 1:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 50341
+test clock-29.1465 {time parsing} {
+ clock scan {2440588 i:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 50341
+test clock-29.1466 {time parsing} {
+ clock scan {2440588 i:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 50341
+test clock-29.1467 {time parsing} {
+ clock scan {2440588 i:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 50341
+test clock-29.1468 {time parsing} {
+ clock scan {2440588 i:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 50341
+test clock-29.1469 {time parsing} {
+ clock scan {2440588 01:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 50341
+test clock-29.1470 {time parsing} {
+ clock scan {2440588 01:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 50341
+test clock-29.1471 {time parsing} {
+ clock scan {2440588 1:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 50341
+test clock-29.1472 {time parsing} {
+ clock scan {2440588 1:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 50341
+test clock-29.1473 {time parsing} {
+ clock scan {2440588 i:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 50341
+test clock-29.1474 {time parsing} {
+ clock scan {2440588 i:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 50341
+test clock-29.1475 {time parsing} {
+ clock scan {2440588 i:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 50341
+test clock-29.1476 {time parsing} {
+ clock scan {2440588 i:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 50341
+test clock-29.1477 {time parsing} {
+ clock scan {2440588 13:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 50399
+test clock-29.1478 {time parsing} {
+ clock scan {2440588 13:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 50399
+test clock-29.1479 {time parsing} {
+ clock scan {2440588 13:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 50399
+test clock-29.1480 {time parsing} {
+ clock scan {2440588 13:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 50399
+test clock-29.1481 {time parsing} {
+ clock scan {2440588 xiii:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 50399
+test clock-29.1482 {time parsing} {
+ clock scan {2440588 xiii:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 50399
+test clock-29.1483 {time parsing} {
+ clock scan {2440588 xiii:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 50399
+test clock-29.1484 {time parsing} {
+ clock scan {2440588 xiii:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 50399
+test clock-29.1485 {time parsing} {
+ clock scan {2440588 01:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 50399
+test clock-29.1486 {time parsing} {
+ clock scan {2440588 01:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 50399
+test clock-29.1487 {time parsing} {
+ clock scan {2440588 1:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 50399
+test clock-29.1488 {time parsing} {
+ clock scan {2440588 1:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 50399
+test clock-29.1489 {time parsing} {
+ clock scan {2440588 i:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 50399
+test clock-29.1490 {time parsing} {
+ clock scan {2440588 i:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 50399
+test clock-29.1491 {time parsing} {
+ clock scan {2440588 i:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 50399
+test clock-29.1492 {time parsing} {
+ clock scan {2440588 i:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 50399
+test clock-29.1493 {time parsing} {
+ clock scan {2440588 01:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 50399
+test clock-29.1494 {time parsing} {
+ clock scan {2440588 01:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 50399
+test clock-29.1495 {time parsing} {
+ clock scan {2440588 1:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 50399
+test clock-29.1496 {time parsing} {
+ clock scan {2440588 1:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 50399
+test clock-29.1497 {time parsing} {
+ clock scan {2440588 i:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 50399
+test clock-29.1498 {time parsing} {
+ clock scan {2440588 i:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 50399
+test clock-29.1499 {time parsing} {
+ clock scan {2440588 i:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 50399
+test clock-29.1500 {time parsing} {
+ clock scan {2440588 i:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 50399
+test clock-29.1501 {time parsing} {
+ clock scan {2440588 23 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H }
+} 82800
+test clock-29.1502 {time parsing} {
+ clock scan {2440588 23:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 82800
+test clock-29.1503 {time parsing} {
+ clock scan {2440588 23:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 82800
+test clock-29.1504 {time parsing} {
+ clock scan {2440588 23:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 82800
+test clock-29.1505 {time parsing} {
+ clock scan {2440588 23:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 82800
+test clock-29.1506 {time parsing} {
+ clock scan {2440588 23 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k }
+} 82800
+test clock-29.1507 {time parsing} {
+ clock scan {2440588 23:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 82800
+test clock-29.1508 {time parsing} {
+ clock scan {2440588 23:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 82800
+test clock-29.1509 {time parsing} {
+ clock scan {2440588 23:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 82800
+test clock-29.1510 {time parsing} {
+ clock scan {2440588 23:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 82800
+test clock-29.1511 {time parsing} {
+ clock scan {2440588 xxiii } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH }
+} 82800
+test clock-29.1512 {time parsing} {
+ clock scan {2440588 xxiii:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 82800
+test clock-29.1513 {time parsing} {
+ clock scan {2440588 xxiii:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 82800
+test clock-29.1514 {time parsing} {
+ clock scan {2440588 xxiii:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 82800
+test clock-29.1515 {time parsing} {
+ clock scan {2440588 xxiii:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 82800
+test clock-29.1516 {time parsing} {
+ clock scan {2440588 xxiii } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok }
+} 82800
+test clock-29.1517 {time parsing} {
+ clock scan {2440588 xxiii:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 82800
+test clock-29.1518 {time parsing} {
+ clock scan {2440588 xxiii:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 82800
+test clock-29.1519 {time parsing} {
+ clock scan {2440588 xxiii:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 82800
+test clock-29.1520 {time parsing} {
+ clock scan {2440588 xxiii:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 82800
+test clock-29.1521 {time parsing} {
+ clock scan {2440588 11 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %p}
+} 82800
+test clock-29.1522 {time parsing} {
+ clock scan {2440588 11:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 82800
+test clock-29.1523 {time parsing} {
+ clock scan {2440588 11:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 82800
+test clock-29.1524 {time parsing} {
+ clock scan {2440588 11:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 82800
+test clock-29.1525 {time parsing} {
+ clock scan {2440588 11:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 82800
+test clock-29.1526 {time parsing} {
+ clock scan {2440588 11 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %p}
+} 82800
+test clock-29.1527 {time parsing} {
+ clock scan {2440588 11:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 82800
+test clock-29.1528 {time parsing} {
+ clock scan {2440588 11:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 82800
+test clock-29.1529 {time parsing} {
+ clock scan {2440588 11:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 82800
+test clock-29.1530 {time parsing} {
+ clock scan {2440588 11:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 82800
+test clock-29.1531 {time parsing} {
+ clock scan {2440588 xi PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %p}
+} 82800
+test clock-29.1532 {time parsing} {
+ clock scan {2440588 xi:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 82800
+test clock-29.1533 {time parsing} {
+ clock scan {2440588 xi:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 82800
+test clock-29.1534 {time parsing} {
+ clock scan {2440588 xi:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 82800
+test clock-29.1535 {time parsing} {
+ clock scan {2440588 xi:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 82800
+test clock-29.1536 {time parsing} {
+ clock scan {2440588 xi PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %p}
+} 82800
+test clock-29.1537 {time parsing} {
+ clock scan {2440588 xi:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 82800
+test clock-29.1538 {time parsing} {
+ clock scan {2440588 xi:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 82800
+test clock-29.1539 {time parsing} {
+ clock scan {2440588 xi:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 82800
+test clock-29.1540 {time parsing} {
+ clock scan {2440588 xi:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 82800
+test clock-29.1541 {time parsing} {
+ clock scan {2440588 11 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %P}
+} 82800
+test clock-29.1542 {time parsing} {
+ clock scan {2440588 11:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 82800
+test clock-29.1543 {time parsing} {
+ clock scan {2440588 11:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 82800
+test clock-29.1544 {time parsing} {
+ clock scan {2440588 11:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 82800
+test clock-29.1545 {time parsing} {
+ clock scan {2440588 11:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 82800
+test clock-29.1546 {time parsing} {
+ clock scan {2440588 11 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %P}
+} 82800
+test clock-29.1547 {time parsing} {
+ clock scan {2440588 11:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 82800
+test clock-29.1548 {time parsing} {
+ clock scan {2440588 11:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 82800
+test clock-29.1549 {time parsing} {
+ clock scan {2440588 11:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 82800
+test clock-29.1550 {time parsing} {
+ clock scan {2440588 11:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 82800
+test clock-29.1551 {time parsing} {
+ clock scan {2440588 xi pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %P}
+} 82800
+test clock-29.1552 {time parsing} {
+ clock scan {2440588 xi:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 82800
+test clock-29.1553 {time parsing} {
+ clock scan {2440588 xi:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 82800
+test clock-29.1554 {time parsing} {
+ clock scan {2440588 xi:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 82800
+test clock-29.1555 {time parsing} {
+ clock scan {2440588 xi:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 82800
+test clock-29.1556 {time parsing} {
+ clock scan {2440588 xi pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %P}
+} 82800
+test clock-29.1557 {time parsing} {
+ clock scan {2440588 xi:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 82800
+test clock-29.1558 {time parsing} {
+ clock scan {2440588 xi:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 82800
+test clock-29.1559 {time parsing} {
+ clock scan {2440588 xi:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 82800
+test clock-29.1560 {time parsing} {
+ clock scan {2440588 xi:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 82800
+test clock-29.1561 {time parsing} {
+ clock scan {2440588 23:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 82801
+test clock-29.1562 {time parsing} {
+ clock scan {2440588 23:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 82801
+test clock-29.1563 {time parsing} {
+ clock scan {2440588 23:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 82801
+test clock-29.1564 {time parsing} {
+ clock scan {2440588 23:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 82801
+test clock-29.1565 {time parsing} {
+ clock scan {2440588 xxiii:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 82801
+test clock-29.1566 {time parsing} {
+ clock scan {2440588 xxiii:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 82801
+test clock-29.1567 {time parsing} {
+ clock scan {2440588 xxiii:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 82801
+test clock-29.1568 {time parsing} {
+ clock scan {2440588 xxiii:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 82801
+test clock-29.1569 {time parsing} {
+ clock scan {2440588 11:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 82801
+test clock-29.1570 {time parsing} {
+ clock scan {2440588 11:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 82801
+test clock-29.1571 {time parsing} {
+ clock scan {2440588 11:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 82801
+test clock-29.1572 {time parsing} {
+ clock scan {2440588 11:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 82801
+test clock-29.1573 {time parsing} {
+ clock scan {2440588 xi:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 82801
+test clock-29.1574 {time parsing} {
+ clock scan {2440588 xi:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 82801
+test clock-29.1575 {time parsing} {
+ clock scan {2440588 xi:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 82801
+test clock-29.1576 {time parsing} {
+ clock scan {2440588 xi:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 82801
+test clock-29.1577 {time parsing} {
+ clock scan {2440588 11:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 82801
+test clock-29.1578 {time parsing} {
+ clock scan {2440588 11:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 82801
+test clock-29.1579 {time parsing} {
+ clock scan {2440588 11:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 82801
+test clock-29.1580 {time parsing} {
+ clock scan {2440588 11:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 82801
+test clock-29.1581 {time parsing} {
+ clock scan {2440588 xi:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 82801
+test clock-29.1582 {time parsing} {
+ clock scan {2440588 xi:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 82801
+test clock-29.1583 {time parsing} {
+ clock scan {2440588 xi:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 82801
+test clock-29.1584 {time parsing} {
+ clock scan {2440588 xi:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 82801
+test clock-29.1585 {time parsing} {
+ clock scan {2440588 23:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 82859
+test clock-29.1586 {time parsing} {
+ clock scan {2440588 23:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 82859
+test clock-29.1587 {time parsing} {
+ clock scan {2440588 23:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 82859
+test clock-29.1588 {time parsing} {
+ clock scan {2440588 23:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 82859
+test clock-29.1589 {time parsing} {
+ clock scan {2440588 xxiii:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 82859
+test clock-29.1590 {time parsing} {
+ clock scan {2440588 xxiii:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 82859
+test clock-29.1591 {time parsing} {
+ clock scan {2440588 xxiii:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 82859
+test clock-29.1592 {time parsing} {
+ clock scan {2440588 xxiii:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 82859
+test clock-29.1593 {time parsing} {
+ clock scan {2440588 11:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 82859
+test clock-29.1594 {time parsing} {
+ clock scan {2440588 11:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 82859
+test clock-29.1595 {time parsing} {
+ clock scan {2440588 11:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 82859
+test clock-29.1596 {time parsing} {
+ clock scan {2440588 11:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 82859
+test clock-29.1597 {time parsing} {
+ clock scan {2440588 xi:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 82859
+test clock-29.1598 {time parsing} {
+ clock scan {2440588 xi:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 82859
+test clock-29.1599 {time parsing} {
+ clock scan {2440588 xi:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 82859
+test clock-29.1600 {time parsing} {
+ clock scan {2440588 xi:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 82859
+test clock-29.1601 {time parsing} {
+ clock scan {2440588 11:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 82859
+test clock-29.1602 {time parsing} {
+ clock scan {2440588 11:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 82859
+test clock-29.1603 {time parsing} {
+ clock scan {2440588 11:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 82859
+test clock-29.1604 {time parsing} {
+ clock scan {2440588 11:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 82859
+test clock-29.1605 {time parsing} {
+ clock scan {2440588 xi:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 82859
+test clock-29.1606 {time parsing} {
+ clock scan {2440588 xi:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 82859
+test clock-29.1607 {time parsing} {
+ clock scan {2440588 xi:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 82859
+test clock-29.1608 {time parsing} {
+ clock scan {2440588 xi:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 82859
+test clock-29.1609 {time parsing} {
+ clock scan {2440588 23:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 82860
+test clock-29.1610 {time parsing} {
+ clock scan {2440588 23:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 82860
+test clock-29.1611 {time parsing} {
+ clock scan {2440588 23:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 82860
+test clock-29.1612 {time parsing} {
+ clock scan {2440588 23:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 82860
+test clock-29.1613 {time parsing} {
+ clock scan {2440588 23:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 82860
+test clock-29.1614 {time parsing} {
+ clock scan {2440588 23:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 82860
+test clock-29.1615 {time parsing} {
+ clock scan {2440588 23:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 82860
+test clock-29.1616 {time parsing} {
+ clock scan {2440588 23:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 82860
+test clock-29.1617 {time parsing} {
+ clock scan {2440588 xxiii:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 82860
+test clock-29.1618 {time parsing} {
+ clock scan {2440588 xxiii:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 82860
+test clock-29.1619 {time parsing} {
+ clock scan {2440588 xxiii:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 82860
+test clock-29.1620 {time parsing} {
+ clock scan {2440588 xxiii:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 82860
+test clock-29.1621 {time parsing} {
+ clock scan {2440588 xxiii:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 82860
+test clock-29.1622 {time parsing} {
+ clock scan {2440588 xxiii:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 82860
+test clock-29.1623 {time parsing} {
+ clock scan {2440588 xxiii:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 82860
+test clock-29.1624 {time parsing} {
+ clock scan {2440588 xxiii:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 82860
+test clock-29.1625 {time parsing} {
+ clock scan {2440588 11:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 82860
+test clock-29.1626 {time parsing} {
+ clock scan {2440588 11:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 82860
+test clock-29.1627 {time parsing} {
+ clock scan {2440588 11:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 82860
+test clock-29.1628 {time parsing} {
+ clock scan {2440588 11:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 82860
+test clock-29.1629 {time parsing} {
+ clock scan {2440588 11:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 82860
+test clock-29.1630 {time parsing} {
+ clock scan {2440588 11:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 82860
+test clock-29.1631 {time parsing} {
+ clock scan {2440588 11:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 82860
+test clock-29.1632 {time parsing} {
+ clock scan {2440588 11:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 82860
+test clock-29.1633 {time parsing} {
+ clock scan {2440588 xi:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 82860
+test clock-29.1634 {time parsing} {
+ clock scan {2440588 xi:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 82860
+test clock-29.1635 {time parsing} {
+ clock scan {2440588 xi:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 82860
+test clock-29.1636 {time parsing} {
+ clock scan {2440588 xi:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 82860
+test clock-29.1637 {time parsing} {
+ clock scan {2440588 xi:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 82860
+test clock-29.1638 {time parsing} {
+ clock scan {2440588 xi:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 82860
+test clock-29.1639 {time parsing} {
+ clock scan {2440588 xi:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 82860
+test clock-29.1640 {time parsing} {
+ clock scan {2440588 xi:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 82860
+test clock-29.1641 {time parsing} {
+ clock scan {2440588 11:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 82860
+test clock-29.1642 {time parsing} {
+ clock scan {2440588 11:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 82860
+test clock-29.1643 {time parsing} {
+ clock scan {2440588 11:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 82860
+test clock-29.1644 {time parsing} {
+ clock scan {2440588 11:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 82860
+test clock-29.1645 {time parsing} {
+ clock scan {2440588 11:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 82860
+test clock-29.1646 {time parsing} {
+ clock scan {2440588 11:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 82860
+test clock-29.1647 {time parsing} {
+ clock scan {2440588 11:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 82860
+test clock-29.1648 {time parsing} {
+ clock scan {2440588 11:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 82860
+test clock-29.1649 {time parsing} {
+ clock scan {2440588 xi:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 82860
+test clock-29.1650 {time parsing} {
+ clock scan {2440588 xi:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 82860
+test clock-29.1651 {time parsing} {
+ clock scan {2440588 xi:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 82860
+test clock-29.1652 {time parsing} {
+ clock scan {2440588 xi:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 82860
+test clock-29.1653 {time parsing} {
+ clock scan {2440588 xi:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 82860
+test clock-29.1654 {time parsing} {
+ clock scan {2440588 xi:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 82860
+test clock-29.1655 {time parsing} {
+ clock scan {2440588 xi:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 82860
+test clock-29.1656 {time parsing} {
+ clock scan {2440588 xi:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 82860
+test clock-29.1657 {time parsing} {
+ clock scan {2440588 23:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 82861
+test clock-29.1658 {time parsing} {
+ clock scan {2440588 23:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 82861
+test clock-29.1659 {time parsing} {
+ clock scan {2440588 23:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 82861
+test clock-29.1660 {time parsing} {
+ clock scan {2440588 23:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 82861
+test clock-29.1661 {time parsing} {
+ clock scan {2440588 xxiii:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 82861
+test clock-29.1662 {time parsing} {
+ clock scan {2440588 xxiii:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 82861
+test clock-29.1663 {time parsing} {
+ clock scan {2440588 xxiii:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 82861
+test clock-29.1664 {time parsing} {
+ clock scan {2440588 xxiii:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 82861
+test clock-29.1665 {time parsing} {
+ clock scan {2440588 11:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 82861
+test clock-29.1666 {time parsing} {
+ clock scan {2440588 11:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 82861
+test clock-29.1667 {time parsing} {
+ clock scan {2440588 11:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 82861
+test clock-29.1668 {time parsing} {
+ clock scan {2440588 11:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 82861
+test clock-29.1669 {time parsing} {
+ clock scan {2440588 xi:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 82861
+test clock-29.1670 {time parsing} {
+ clock scan {2440588 xi:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 82861
+test clock-29.1671 {time parsing} {
+ clock scan {2440588 xi:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 82861
+test clock-29.1672 {time parsing} {
+ clock scan {2440588 xi:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 82861
+test clock-29.1673 {time parsing} {
+ clock scan {2440588 11:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 82861
+test clock-29.1674 {time parsing} {
+ clock scan {2440588 11:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 82861
+test clock-29.1675 {time parsing} {
+ clock scan {2440588 11:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 82861
+test clock-29.1676 {time parsing} {
+ clock scan {2440588 11:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 82861
+test clock-29.1677 {time parsing} {
+ clock scan {2440588 xi:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 82861
+test clock-29.1678 {time parsing} {
+ clock scan {2440588 xi:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 82861
+test clock-29.1679 {time parsing} {
+ clock scan {2440588 xi:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 82861
+test clock-29.1680 {time parsing} {
+ clock scan {2440588 xi:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 82861
+test clock-29.1681 {time parsing} {
+ clock scan {2440588 23:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 82919
+test clock-29.1682 {time parsing} {
+ clock scan {2440588 23:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 82919
+test clock-29.1683 {time parsing} {
+ clock scan {2440588 23:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 82919
+test clock-29.1684 {time parsing} {
+ clock scan {2440588 23:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 82919
+test clock-29.1685 {time parsing} {
+ clock scan {2440588 xxiii:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 82919
+test clock-29.1686 {time parsing} {
+ clock scan {2440588 xxiii:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 82919
+test clock-29.1687 {time parsing} {
+ clock scan {2440588 xxiii:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 82919
+test clock-29.1688 {time parsing} {
+ clock scan {2440588 xxiii:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 82919
+test clock-29.1689 {time parsing} {
+ clock scan {2440588 11:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 82919
+test clock-29.1690 {time parsing} {
+ clock scan {2440588 11:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 82919
+test clock-29.1691 {time parsing} {
+ clock scan {2440588 11:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 82919
+test clock-29.1692 {time parsing} {
+ clock scan {2440588 11:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 82919
+test clock-29.1693 {time parsing} {
+ clock scan {2440588 xi:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 82919
+test clock-29.1694 {time parsing} {
+ clock scan {2440588 xi:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 82919
+test clock-29.1695 {time parsing} {
+ clock scan {2440588 xi:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 82919
+test clock-29.1696 {time parsing} {
+ clock scan {2440588 xi:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 82919
+test clock-29.1697 {time parsing} {
+ clock scan {2440588 11:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 82919
+test clock-29.1698 {time parsing} {
+ clock scan {2440588 11:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 82919
+test clock-29.1699 {time parsing} {
+ clock scan {2440588 11:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 82919
+test clock-29.1700 {time parsing} {
+ clock scan {2440588 11:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 82919
+test clock-29.1701 {time parsing} {
+ clock scan {2440588 xi:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 82919
+test clock-29.1702 {time parsing} {
+ clock scan {2440588 xi:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 82919
+test clock-29.1703 {time parsing} {
+ clock scan {2440588 xi:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 82919
+test clock-29.1704 {time parsing} {
+ clock scan {2440588 xi:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 82919
+test clock-29.1705 {time parsing} {
+ clock scan {2440588 23:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 86340
+test clock-29.1706 {time parsing} {
+ clock scan {2440588 23:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 86340
+test clock-29.1707 {time parsing} {
+ clock scan {2440588 23:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 86340
+test clock-29.1708 {time parsing} {
+ clock scan {2440588 23:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 86340
+test clock-29.1709 {time parsing} {
+ clock scan {2440588 23:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 86340
+test clock-29.1710 {time parsing} {
+ clock scan {2440588 23:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 86340
+test clock-29.1711 {time parsing} {
+ clock scan {2440588 23:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 86340
+test clock-29.1712 {time parsing} {
+ clock scan {2440588 23:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 86340
+test clock-29.1713 {time parsing} {
+ clock scan {2440588 xxiii:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 86340
+test clock-29.1714 {time parsing} {
+ clock scan {2440588 xxiii:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 86340
+test clock-29.1715 {time parsing} {
+ clock scan {2440588 xxiii:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 86340
+test clock-29.1716 {time parsing} {
+ clock scan {2440588 xxiii:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 86340
+test clock-29.1717 {time parsing} {
+ clock scan {2440588 xxiii:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 86340
+test clock-29.1718 {time parsing} {
+ clock scan {2440588 xxiii:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 86340
+test clock-29.1719 {time parsing} {
+ clock scan {2440588 xxiii:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 86340
+test clock-29.1720 {time parsing} {
+ clock scan {2440588 xxiii:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 86340
+test clock-29.1721 {time parsing} {
+ clock scan {2440588 11:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 86340
+test clock-29.1722 {time parsing} {
+ clock scan {2440588 11:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 86340
+test clock-29.1723 {time parsing} {
+ clock scan {2440588 11:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 86340
+test clock-29.1724 {time parsing} {
+ clock scan {2440588 11:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 86340
+test clock-29.1725 {time parsing} {
+ clock scan {2440588 11:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 86340
+test clock-29.1726 {time parsing} {
+ clock scan {2440588 11:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 86340
+test clock-29.1727 {time parsing} {
+ clock scan {2440588 11:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 86340
+test clock-29.1728 {time parsing} {
+ clock scan {2440588 11:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 86340
+test clock-29.1729 {time parsing} {
+ clock scan {2440588 xi:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 86340
+test clock-29.1730 {time parsing} {
+ clock scan {2440588 xi:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 86340
+test clock-29.1731 {time parsing} {
+ clock scan {2440588 xi:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 86340
+test clock-29.1732 {time parsing} {
+ clock scan {2440588 xi:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 86340
+test clock-29.1733 {time parsing} {
+ clock scan {2440588 xi:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 86340
+test clock-29.1734 {time parsing} {
+ clock scan {2440588 xi:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 86340
+test clock-29.1735 {time parsing} {
+ clock scan {2440588 xi:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 86340
+test clock-29.1736 {time parsing} {
+ clock scan {2440588 xi:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 86340
+test clock-29.1737 {time parsing} {
+ clock scan {2440588 11:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 86340
+test clock-29.1738 {time parsing} {
+ clock scan {2440588 11:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 86340
+test clock-29.1739 {time parsing} {
+ clock scan {2440588 11:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 86340
+test clock-29.1740 {time parsing} {
+ clock scan {2440588 11:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 86340
+test clock-29.1741 {time parsing} {
+ clock scan {2440588 11:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 86340
+test clock-29.1742 {time parsing} {
+ clock scan {2440588 11:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 86340
+test clock-29.1743 {time parsing} {
+ clock scan {2440588 11:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 86340
+test clock-29.1744 {time parsing} {
+ clock scan {2440588 11:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 86340
+test clock-29.1745 {time parsing} {
+ clock scan {2440588 xi:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 86340
+test clock-29.1746 {time parsing} {
+ clock scan {2440588 xi:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 86340
+test clock-29.1747 {time parsing} {
+ clock scan {2440588 xi:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 86340
+test clock-29.1748 {time parsing} {
+ clock scan {2440588 xi:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 86340
+test clock-29.1749 {time parsing} {
+ clock scan {2440588 xi:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 86340
+test clock-29.1750 {time parsing} {
+ clock scan {2440588 xi:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 86340
+test clock-29.1751 {time parsing} {
+ clock scan {2440588 xi:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 86340
+test clock-29.1752 {time parsing} {
+ clock scan {2440588 xi:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 86340
+test clock-29.1753 {time parsing} {
+ clock scan {2440588 23:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 86341
+test clock-29.1754 {time parsing} {
+ clock scan {2440588 23:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 86341
+test clock-29.1755 {time parsing} {
+ clock scan {2440588 23:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 86341
+test clock-29.1756 {time parsing} {
+ clock scan {2440588 23:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 86341
+test clock-29.1757 {time parsing} {
+ clock scan {2440588 xxiii:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 86341
+test clock-29.1758 {time parsing} {
+ clock scan {2440588 xxiii:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 86341
+test clock-29.1759 {time parsing} {
+ clock scan {2440588 xxiii:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 86341
+test clock-29.1760 {time parsing} {
+ clock scan {2440588 xxiii:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 86341
+test clock-29.1761 {time parsing} {
+ clock scan {2440588 11:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 86341
+test clock-29.1762 {time parsing} {
+ clock scan {2440588 11:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 86341
+test clock-29.1763 {time parsing} {
+ clock scan {2440588 11:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 86341
+test clock-29.1764 {time parsing} {
+ clock scan {2440588 11:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 86341
+test clock-29.1765 {time parsing} {
+ clock scan {2440588 xi:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 86341
+test clock-29.1766 {time parsing} {
+ clock scan {2440588 xi:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 86341
+test clock-29.1767 {time parsing} {
+ clock scan {2440588 xi:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 86341
+test clock-29.1768 {time parsing} {
+ clock scan {2440588 xi:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 86341
+test clock-29.1769 {time parsing} {
+ clock scan {2440588 11:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 86341
+test clock-29.1770 {time parsing} {
+ clock scan {2440588 11:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 86341
+test clock-29.1771 {time parsing} {
+ clock scan {2440588 11:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 86341
+test clock-29.1772 {time parsing} {
+ clock scan {2440588 11:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 86341
+test clock-29.1773 {time parsing} {
+ clock scan {2440588 xi:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 86341
+test clock-29.1774 {time parsing} {
+ clock scan {2440588 xi:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 86341
+test clock-29.1775 {time parsing} {
+ clock scan {2440588 xi:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 86341
+test clock-29.1776 {time parsing} {
+ clock scan {2440588 xi:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 86341
+test clock-29.1777 {time parsing} {
+ clock scan {2440588 23:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 86399
+test clock-29.1778 {time parsing} {
+ clock scan {2440588 23:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 86399
+test clock-29.1779 {time parsing} {
+ clock scan {2440588 23:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 86399
+test clock-29.1780 {time parsing} {
+ clock scan {2440588 23:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 86399
+test clock-29.1781 {time parsing} {
+ clock scan {2440588 xxiii:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 86399
+test clock-29.1782 {time parsing} {
+ clock scan {2440588 xxiii:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 86399
+test clock-29.1783 {time parsing} {
+ clock scan {2440588 xxiii:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 86399
+test clock-29.1784 {time parsing} {
+ clock scan {2440588 xxiii:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 86399
+test clock-29.1785 {time parsing} {
+ clock scan {2440588 11:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 86399
+test clock-29.1786 {time parsing} {
+ clock scan {2440588 11:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 86399
+test clock-29.1787 {time parsing} {
+ clock scan {2440588 11:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 86399
+test clock-29.1788 {time parsing} {
+ clock scan {2440588 11:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 86399
+test clock-29.1789 {time parsing} {
+ clock scan {2440588 xi:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 86399
+test clock-29.1790 {time parsing} {
+ clock scan {2440588 xi:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 86399
+test clock-29.1791 {time parsing} {
+ clock scan {2440588 xi:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 86399
+test clock-29.1792 {time parsing} {
+ clock scan {2440588 xi:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 86399
+test clock-29.1793 {time parsing} {
+ clock scan {2440588 11:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 86399
+test clock-29.1794 {time parsing} {
+ clock scan {2440588 11:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 86399
+test clock-29.1795 {time parsing} {
+ clock scan {2440588 11:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 86399
+test clock-29.1796 {time parsing} {
+ clock scan {2440588 11:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 86399
+test clock-29.1797 {time parsing} {
+ clock scan {2440588 xi:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 86399
+test clock-29.1798 {time parsing} {
+ clock scan {2440588 xi:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 86399
+test clock-29.1799 {time parsing} {
+ clock scan {2440588 xi:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 86399
+test clock-29.1800 {time parsing} {
+ clock scan {2440588 xi:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 86399
+# END testcases29
+
+test clock-30.1 {clock add years} {
+ set t [clock scan 2000-01-01 -format %Y-%m-%d -timezone :UTC]
+ set f [clock add $t 1 year -timezone :UTC]
+ clock format $f -format %Y-%m-%d -timezone :UTC
+} {2001-01-01}
+test clock-30.2 {clock add years - leap day} {
+ set t [clock scan 2000-02-29 -format %Y-%m-%d -timezone :UTC]
+ set f [clock add $t 1 years -timezone :UTC]
+ clock format $f -format %Y-%m-%d -timezone :UTC
+} {2001-02-28}
+test clock-30.3 {clock add months} {
+ set t [clock scan 2000-01-01 -format %Y-%m-%d -timezone :UTC]
+ set f [clock add $t 1 month -timezone :UTC]
+ clock format $f -format %Y-%m-%d -timezone :UTC
+} {2000-02-01}
+test clock-30.4 {clock add months, short month} {
+ set t [clock scan 2000-01-31 -format %Y-%m-%d -timezone :UTC]
+ set f [clock add $t 1 months -timezone :UTC]
+ clock format $f -format %Y-%m-%d -timezone :UTC
+} {2000-02-29}
+test clock-30.5 {clock add months, end of year} {
+ set t [clock scan 2000-12-01 -format %Y-%m-%d -timezone :UTC]
+ set f [clock add $t 1 month -timezone :UTC]
+ clock format $f -format %Y-%m-%d -timezone :UTC
+} {2001-01-01}
+test clock-30.6 {clock add months, one year one month vs 13 months} {
+ set t [clock scan 2000-02-29 -format %Y-%m-%d -timezone :UTC]
+ set f1 [clock add $t 1 year 1 month -timezone :UTC]
+ set f2 [clock add $t 13 months -timezone :UTC]
+ set x1 [clock format $f1 -format %Y-%m-%d -timezone :UTC]
+ set x2 [clock format $f2 -format %Y-%m-%d -timezone :UTC]
+ list $x1 $x2
+} {2001-03-28 2001-03-29}
+test clock-30.7 {clock add months, 1 year 1 month vs 1 month 1 year} {
+ set t [clock scan 2000-02-29 -format %Y-%m-%d -timezone :UTC]
+ set f1 [clock add $t 1 year 1 month -timezone :UTC]
+ set f2 [clock add $t 1 month 1 year -timezone :UTC]
+ set x1 [clock format $f1 -format %Y-%m-%d -timezone :UTC]
+ set x2 [clock format $f2 -format %Y-%m-%d -timezone :UTC]
+ list $x1 $x2
+} {2001-03-28 2001-03-29}
+test clock-30.8 {clock add months, negative} {
+ set t [clock scan 2000-03-31 -format %Y-%m-%d -timezone :UTC]
+ set f1 [clock add $t -1 month -timezone :UTC]
+ set f2 [clock add $t -2 month -timezone :UTC]
+ set f3 [clock add $t -3 month -timezone :UTC]
+ set f4 [clock add $t -4 month -timezone :UTC]
+ set x1 [clock format $f1 -format %Y-%m-%d -timezone :UTC]
+ set x2 [clock format $f2 -format %Y-%m-%d -timezone :UTC]
+ set x3 [clock format $f3 -format %Y-%m-%d -timezone :UTC]
+ set x4 [clock format $f4 -format %Y-%m-%d -timezone :UTC]
+ list $x1 $x2 $x3 $x4
+} {2000-02-29 2000-01-31 1999-12-31 1999-11-30}
+test clock-30.9 {clock add days} {
+ set t [clock scan {2000-01-01 12:34:56} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone :UTC]
+ set f1 [clock add $t 1 day -timezone :UTC]
+ set f2 [clock add $t -1 day -timezone :UTC]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ list $x1 $x2
+} {{2000-01-02 12:34:56} {1999-12-31 12:34:56}}
+test clock-30.10 {clock add days, spring DST conversion, before} {
+ set t [clock scan {2004-04-03 01:59:59} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 1 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f2 [clock add $t 2 days \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ list $x1 $x2
+} {{2004-04-04 01:59:59 -0500} {2004-04-05 01:59:59 -0400}}
+test clock-30.11 {clock add days, spring DST conversion, bad case} {
+ set t [clock scan {2004-04-03 02:30:00} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 1 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f2 [clock add $t 2 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ list $x1 $x2
+} {{2004-04-04 03:30:00 -0400} {2004-04-05 02:30:00 -0400}}
+test clock-30.12 {clock add days, spring DST conversion, after} {
+ set t [clock scan {2004-04-03 03:00:00} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 1 day -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f2 [clock add $t 2 day -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ list $x1 $x2
+} {{2004-04-04 03:00:00 -0400} {2004-04-05 03:00:00 -0400}}
+test clock-30.13 {clock add days, fall DST conversion, before} {
+ set t [clock scan {2004-10-30 00:59:59} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 1 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f2 [clock add $t 2 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ list $x1 $x2
+} {{2004-10-31 00:59:59 -0400} {2004-11-01 00:59:59 -0500}}
+test clock-30.14 {clock add days, fall DST conversion, bad case} {
+ set t [clock scan {2004-10-30 01:30:00} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 1 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f2 [clock add $t 2 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ list $x1 $x2
+} {{2004-10-31 01:30:00 -0400} {2004-11-01 01:30:00 -0500}}
+test clock-30.15 {clock add days, fall DST conversion, after} {
+ set t [clock scan {2004-10-30 02:30:00} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 1 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f2 [clock add $t 2 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ list $x1 $x2
+} {{2004-10-31 02:30:00 -0500} {2004-11-01 02:30:00 -0500}}
+test clock-30.16 {clock add weeks} {
+ set t [clock scan {2000-01-01 12:34:56} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone :UTC]
+ set f1 [clock add $t 1 week -timezone :UTC]
+ set f2 [clock add $t -1 weeks -timezone :UTC]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ list $x1 $x2
+} {{2000-01-08 12:34:56} {1999-12-25 12:34:56}}
+test clock-30.17 {clock add hours} {
+ set t [clock scan {2000-01-01 12:34:56} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone :UTC]
+ set f1 [clock add $t 1 hour -timezone :UTC]
+ set f2 [clock add $t -1 hours -timezone :UTC]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ list $x1 $x2
+} {{2000-01-01 13:34:56} {2000-01-01 11:34:56}}
+test clock-30.18 {clock add hours at DST conversion} {
+ set t [clock scan {2004-04-04 01:00:00 -0500} \
+ -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 1 hour -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-04-04 03:00:00 -0400}
+test clock-30.19 {clock add hours at DST conversion} {
+ set t [clock scan {2004-10-31 01:00:00 -0400} \
+ -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 1 hour \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-10-31 01:00:00 -0500}
+test clock-30.20 {clock add minutes} {
+ set t [clock scan {2000-01-01 12:34:56} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone :UTC]
+ set f1 [clock add $t 60 minute -timezone :UTC]
+ set f2 [clock add $t -60 minutes -timezone :UTC]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ list $x1 $x2
+} {{2000-01-01 13:34:56} {2000-01-01 11:34:56}}
+test clock-30.21 {clock add minutes at DST conversion} {
+ set t [clock scan {2004-04-04 01:00:00 -0500} \
+ -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 60 minutes \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-04-04 03:00:00 -0400}
+test clock-30.22 {clock add minutes at DST conversion} {
+ set t [clock scan {2004-10-31 01:00:00 -0400} \
+ -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 60 minutes \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-10-31 01:00:00 -0500}
+test clock-30.23 {clock add seconds} {
+ set t [clock scan {2000-01-01 12:34:56} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone :UTC]
+ set f1 [clock add $t 3600 second -timezone :UTC]
+ set f2 [clock add $t -3600 seconds -timezone :UTC]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ list $x1 $x2
+} {{2000-01-01 13:34:56} {2000-01-01 11:34:56}}
+test clock-30.24 {clock add seconds at DST conversion} {
+ set t [clock scan {2004-04-04 01:00:00 -0500} \
+ -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 3600 seconds \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-04-04 03:00:00 -0400}
+test clock-30.25 {clock add seconds at DST conversion} {
+ set t [clock scan {2004-10-31 01:00:00 -0400} \
+ -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 3600 seconds -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-10-31 01:00:00 -0500}
+
+test clock-31.1 {system locale} \
+ -constraints win \
+ -setup {
+ namespace eval ::tcl::clock {
+ namespace import -force ::testClock::registry
+ }
+ set noreg [info exists ::tcl::clock::NoRegistry]
+ if {$noreg} {unset ::tcl::clock::NoRegistry}
+ ::tcl::clock::ClearCaches
+ } \
+ -body {
+ clock format 0 -timezone :UTC -locale system -format %x
+ } \
+ -cleanup {
+ namespace eval ::tcl::clock {
+ rename registry {}
+ }
+ if {$noreg} {set ::tcl::clock::NoRegistry {}}
+ ::tcl::clock::ClearCaches
+ } \
+ -result [clock format 0 -timezone :UTC -locale current \
+ -format {%d-%b-%Y}]
+
+test clock-31.2 {system locale} \
+ -constraints win \
+ -setup {
+ namespace eval ::tcl::clock {
+ namespace import -force ::testClock::registry
+ }
+ set noreg [info exists ::tcl::clock::NoRegistry]
+ if {$noreg} {unset ::tcl::clock::NoRegistry}
+ ::tcl::clock::ClearCaches
+ } \
+ -body {
+ clock format 0 -timezone :UTC -locale system -format %Ex
+ } \
+ -cleanup {
+ namespace eval ::tcl::clock {
+ rename registry {}
+ }
+ if {$noreg} {set ::tcl::clock::NoRegistry {}}
+ ::tcl::clock::ClearCaches
+ } \
+ -result [clock format 0 -timezone :UTC -locale current \
+ -format {the %d' day of %B %Y}]
+
+test clock-31.3 {system locale} \
+ -constraints win \
+ -setup {
+ namespace eval ::tcl::clock {
+ namespace import -force ::testClock::registry
+ }
+ set noreg [info exists ::tcl::clock::NoRegistry]
+ if {$noreg} {unset ::tcl::clock::NoRegistry}
+ ::tcl::clock::ClearCaches
+ } \
+ -body {
+ clock format 0 -timezone :UTC -locale system -format %X
+ } \
+ -cleanup {
+ namespace eval ::tcl::clock {
+ rename registry {}
+ }
+ if {$noreg} {set ::tcl::clock::NoRegistry {}}
+ ::tcl::clock::ClearCaches
+ } \
+ -result [clock format 0 -timezone :UTC -locale current \
+ -format {%l:%M:%S %p}]
+
+test clock-31.4 {system locale} \
+ -constraints win \
+ -setup {
+ namespace eval ::tcl::clock {
+ namespace import -force ::testClock::registry
+ }
+ set noreg [info exists ::tcl::clock::NoRegistry]
+ if {$noreg} {unset ::tcl::clock::NoRegistry}
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ unset env(TZ)
+ }
+ if { [info exists env(TCL_TZ)] } {
+ set oldTclTZ $env(TCL_TZ)
+ unset env(TCL_TZ)
+ }
+ ::tcl::clock::ClearCaches
+ } \
+ -body {
+ clock format 0 -locale system -format %x
+ } \
+ -cleanup {
+ namespace eval ::tcl::clock {
+ rename registry {}
+ }
+ if { [info exists oldTclTZ] } {
+ set env(TCL_TZ) $oldTclTZ
+ }
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ }
+ if {$noreg} {set ::tcl::clock::NoRegistry {}}
+ ::tcl::clock::ClearCaches
+ } \
+ -result [clock format 0 -locale current -timezone EST5 \
+ -format {%d-%b-%Y}]
+
+test clock-31.5 {system locale} \
+ -constraints win \
+ -setup {
+ namespace eval ::tcl::clock {
+ namespace import -force ::testClock::registry
+ }
+ set noreg [info exists ::tcl::clock::NoRegistry]
+ if {$noreg} {unset ::tcl::clock::NoRegistry}
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ unset env(TZ)
+ }
+ if { [info exists env(TCL_TZ)] } {
+ set oldTclTZ $env(TCL_TZ)
+ unset env(TCL_TZ)
+ }
+ ::tcl::clock::ClearCaches
+ } \
+ -body {
+ clock format 0 -locale system -format %Ex
+ } \
+ -cleanup {
+ namespace eval ::tcl::clock {
+ rename registry {}
+ }
+ if {$noreg} {set ::tcl::clock::NoRegistry {}}
+ if { [info exists oldTclTZ] } {
+ set env(TCL_TZ) $oldTclTZ
+ }
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ }
+ ::tcl::clock::ClearCaches
+ } \
+ -result [clock format 0 -locale current -timezone EST5 \
+ -format {the %d' day of %B %Y}]
+
+test clock-31.6 {system locale} \
+ -constraints win \
+ -setup {
+ namespace eval ::tcl::clock {
+ namespace import -force ::testClock::registry
+ }
+ set noreg [info exists ::tcl::clock::NoRegistry]
+ if {$noreg} {unset ::tcl::clock::NoRegistry}
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ unset env(TZ)
+ }
+ if { [info exists env(TCL_TZ)] } {
+ set oldTclTZ $env(TCL_TZ)
+ unset env(TCL_TZ)
+ }
+ ::tcl::clock::ClearCaches
+ } \
+ -body {
+ clock format 0 -locale system -format "%X %Z"
+ } \
+ -cleanup {
+ namespace eval ::tcl::clock {
+ rename registry {}
+ }
+ if {$noreg} {set ::tcl::clock::NoRegistry {}}
+ if { [info exists oldTclTZ] } {
+ set env(TCL_TZ) $oldTclTZ
+ }
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ }
+ ::tcl::clock::ClearCaches
+ } \
+ -result [clock format 0 -locale current -timezone EST5 \
+ -format {%l:%M:%S %p %Z}]
+
+test clock-32.1 {scan/format across the Gregorian change} {
+ set problems {}
+ set t [expr { wide(-6857395200) }]
+ foreach d { 1 2 14 15 16
+ 17 18 19 20 21 22 23
+ 24 25 26 27 28 29 30 } \
+ j { 245 246 258 259 260
+ 261 262 263 264 265 266 267
+ 268 269 270 271 272 273 274 } {
+ set u [format 1752-09-%02d $d]
+ set s [clock format $t -format %Y-%m-%d \
+ -locale en_US_roman -timezone :UTC]
+ if { $s ne $u } {
+ append problems "formatting $t: $s should be $u\n"
+ }
+ set v [clock scan $u -format %Y-%m-%d \
+ -locale en_US_roman -timezone :UTC]
+ if { $t ne $v } {
+ append problems "scanning $u: $t should be $v\n"
+ }
+ set u [format 1752-%03d $j]
+ set s [clock format $t -format %Y-%j \
+ -locale en_US_roman -timezone :UTC]
+ if { $s ne $u } {
+ append problems "formatting $t: $s should be $u\n"
+ }
+ set v [clock scan $u -format %Y-%j \
+ -locale en_US_roman -timezone :UTC]
+ if { $t ne $v } {
+ append problems "scanning $u: $t should be $v\n"
+ }
+ incr t 86400
+ }
+ set problems
+} {}
+
+# Legacy tests
+
+# clock clicks
+test clock-33.1 {clock clicks tests} {
+ expr [clock clicks]+1
+ concat {}
+} {}
+test clock-33.2 {clock clicks tests} {
+ set start [clock clicks]
+ after 10
+ set end [clock clicks]
+ expr "$end > $start"
+} {1}
+test clock-33.3 {clock clicks tests} {
+ list [catch {clock clicks foo} msg] $msg
+} {1 {bad switch "foo": must be -milliseconds or -microseconds}}
+test clock-33.4 {clock clicks tests} {
+ expr [clock clicks -milliseconds]+1
+ concat {}
+} {}
+test clock-33.4a {clock milliseconds} {
+ expr { [clock milliseconds] + 1 }
+ concat {}
+} {}
+test clock-33.5 {clock clicks tests, millisecond timing test} {
+ # This test can fail on a system that is so heavily loaded that
+ # the test takes >60 ms to run.
+ set start [clock clicks -milli]
+ after 10
+ set end [clock clicks -milli]
+ # 60 msecs seems to be the max time slice under Windows 95/98
+ expr {
+ ($end > $start) && (($end - $start) <= 60) ?
+ "ok" :
+ "test should have taken 0-60 ms, actually took [expr $end - $start]"}
+} {ok}
+test clock-33.5a {clock tests, millisecond timing test} {
+ # This test can fail on a system that is so heavily loaded that
+ # the test takes >60 ms to run.
+ set start [clock milliseconds]
+ after 10
+ set end [clock milliseconds]
+ # 60 msecs seems to be the max time slice under Windows 95/98
+ expr {
+ ($end > $start) && (($end - $start) <= 60) ?
+ "ok" :
+ "test should have taken 0-60 ms, actually took [expr $end - $start]"}
+} {ok}
+test clock-33.6 {clock clicks, milli with too much abbreviation} {
+ list [catch { clock clicks ? } msg] $msg
+} {1 {bad switch "?": must be -milliseconds or -microseconds}}
+test clock-33.7 {clock clicks, milli with too much abbreviation} {
+ list [catch { clock clicks - } msg] $msg
+} {1 {ambiguous switch "-": must be -milliseconds or -microseconds}}
+
+test clock-33.8 {clock clicks test, microsecond timing test} {
+ # This test can fail on a system that is so heavily loaded that
+ # the test takes >60 ms to run.
+ set start [clock clicks -micro]
+ after 10
+ set end [clock clicks -micro]
+ expr {($end > $start) && (($end - $start) <= 60000)}
+} {1}
+test clock-33.8a {clock test, microsecond timing test} {
+ # This test can fail on a system that is so heavily loaded that
+ # the test takes >60 ms to run.
+ set start [clock microseconds]
+ after 10
+ set end [clock microseconds]
+ expr {($end > $start) && (($end - $start) <= 60000)}
+} {1}
+
+test clock-33.9 {clock clicks test, millis align with seconds} {
+ set t1 [clock seconds]
+ while { 1 } {
+ set t2 [clock clicks -millis]
+ set t3 [clock seconds]
+ if { $t3 == $t1 } break
+ set t1 $t3
+ }
+ expr { $t2 / 1000 == $t3 }
+} {1}
+test clock-33.9a {clock test, millis align with seconds} {
+ set t1 [clock seconds]
+ while { 1 } {
+ set t2 [clock milliseconds]
+ set t3 [clock seconds]
+ if { $t3 == $t1 } break
+ set t1 $t3
+ }
+ expr { $t2 / 1000 == $t3 }
+} {1}
+
+test clock-33.10 {clock clicks test, micros align with seconds} {
+ set t1 [clock seconds]
+ while { 1 } {
+ set t2 [clock clicks -micros]
+ set t3 [clock seconds]
+ if { $t3 == $t1 } break
+ set t1 $t3
+ }
+ expr { $t2 / 1000000 == $t3 }
+} {1}
+test clock-33.10a {clock test, micros align with seconds} {
+ set t1 [clock seconds]
+ while { 1 } {
+ set t2 [clock microseconds]
+ set t3 [clock seconds]
+ if { $t3 == $t1 } break
+ set t1 $t3
+ }
+ expr { $t2 / 1000000 == $t3 }
+} {1}
+
+test clock-33.11 {clock clicks test, millis align with micros} {
+ set t1 [clock clicks -millis]
+ while { 1 } {
+ set t2 [clock clicks -micros]
+ set t3 [clock clicks -millis]
+ if { $t3 == $t1 } break
+ set t1 $t3
+ }
+ expr { $t2 / 1000 == $t3 }
+} {1}
+test clock-33.11a {clock test, millis align with micros} {
+ set t1 [clock milliseconds]
+ while { 1 } {
+ set t2 [clock microseconds]
+ set t3 [clock milliseconds]
+ if { $t3 == $t1 } break
+ set t1 $t3
+ }
+ expr { $t2 / 1000 == $t3 }
+} {1}
+
+# clock scan
+test clock-34.1 {clock scan tests} {
+ list [catch {clock scan} msg] $msg
+} {1 {wrong # args: should be "clock scan string ?-base seconds? ?-format string? ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?"}}
+test clock-34.2 {clock scan tests} {*}{
+ -body {clock scan "bad-string"}
+ -returnCodes error
+ -match glob
+ -result {unable to convert date-time string "bad-string"*}
+}
+test clock-34.3 {clock scan tests} {
+ clock format [clock scan "14 Feb 92" -gmt true] \
+ -format {%m/%d/%y %I:%M:%S %p} -gmt true
+} {02/14/92 12:00:00 AM}
+test clock-34.4 {clock scan tests} {
+ clock format [clock scan "Feb 14, 1992 12:20 PM" -gmt true] \
+ -format {%m/%d/%y %I:%M:%S %p} -gmt true
+} {02/14/92 12:20:00 PM}
+test clock-34.5 {clock scan tests} {
+ clock format \
+ [clock scan "Feb 14, 1992 12:20 PM" -base 319363200 -gmt true] \
+ -format {%m/%d/%y %I:%M:%S %p} -gmt true
+} {02/14/92 12:20:00 PM}
+test clock-34.6 {clock scan tests} {
+ set time [clock scan "Oct 23,1992 15:00"]
+ clock format $time -format {%b %d,%Y %H:%M}
+} {Oct 23,1992 15:00}
+test clock-34.7 {clock scan tests} {
+ set time [clock scan "Oct 23,1992 15:00 GMT"]
+ clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
+} {Oct 23,1992 15:00 GMT}
+test clock-34.8 {clock scan tests} {
+ set time [clock scan "Oct 23,1992 15:00" -gmt true]
+ clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
+} {Oct 23,1992 15:00 GMT}
+test clock-34.9 {clock scan tests} {
+ list [catch {clock scan "Jan 12" -bad arg} msg] $msg
+} {1 {bad switch "-bad", must be -base, -format, -gmt, -locale or -timezone}}
+# The following two two tests test the two year date policy
+test clock-34.10 {clock scan tests} {
+ set time [clock scan "1/1/71" -gmt true]
+ clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
+} {Jan 01,1971 00:00 GMT}
+test clock-34.11 {clock scan tests} {
+ set time [clock scan "1/1/37" -gmt true]
+ clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
+} {Jan 01,2037 00:00 GMT}
+
+test clock-34.12 {clock scan, relative times} {
+ set time [clock scan "Oct 23, 1992 -1 day"]
+ clock format $time -format {%b %d, %Y}
+} "Oct 22, 1992"
+test clock-34.13 {clock scan, ISO 8601 base date format} {
+ set time [clock scan "19921023"]
+ clock format $time -format {%b %d, %Y}
+} "Oct 23, 1992"
+test clock-34.14 {clock scan, ISO 8601 expanded date format} {
+ set time [clock scan "1992-10-23"]
+ clock format $time -format {%b %d, %Y}
+} "Oct 23, 1992"
+test clock-34.15 {clock scan, DD-Mon-YYYY format} {
+ set time [clock scan "23-Oct-1992"]
+ clock format $time -format {%b %d, %Y}
+} "Oct 23, 1992"
+test clock-34.16 {clock scan, ISO 8601 point in time format} {
+ set time [clock scan "19921023T235959"]
+ clock format $time -format {%b %d, %Y %H:%M:%S}
+} "Oct 23, 1992 23:59:59"
+test clock-34.17 {clock scan, ISO 8601 point in time format} {
+ set time [clock scan "19921023 235959"]
+ clock format $time -format {%b %d, %Y %H:%M:%S}
+} "Oct 23, 1992 23:59:59"
+test clock-34.18 {clock scan, ISO 8601 point in time format} {
+ set time [clock scan "19921023T000000"]
+ clock format $time -format {%b %d, %Y %H:%M:%S}
+} "Oct 23, 1992 00:00:00"
+
+# CLOCK SCAN REAL TESTS
+# We use 5am PST, 31-12-1999 as the base for these scans because irrespective
+# of your local timezone it should always give us times on December 31, 1999
+set 5amPST 946645200
+test clock-34.19 {clock scan, number meridian} {
+ set t1 [clock scan "5 am" -base $5amPST -gmt true]
+ set t2 [clock scan "5 pm" -base $5amPST -gmt true]
+ set t3 [clock scan "5 a.m." -base $5amPST -gmt true]
+ set t4 [clock scan "5 p.m." -base $5amPST -gmt true]
+ list \
+ [clock format $t1 -format {%b %d, %Y %H:%M:%S} -gmt true] \
+ [clock format $t2 -format {%b %d, %Y %H:%M:%S} -gmt true] \
+ [clock format $t3 -format {%b %d, %Y %H:%M:%S} -gmt true] \
+ [clock format $t4 -format {%b %d, %Y %H:%M:%S} -gmt true]
+} [list "Dec 31, 1999 05:00:00" "Dec 31, 1999 17:00:00" \
+ "Dec 31, 1999 05:00:00" "Dec 31, 1999 17:00:00"]
+test clock-34.20 {clock scan, number:number meridian} {
+ clock format [clock scan "5:30 pm" -base $5amPST -gmt true] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 17:30:00"
+test clock-34.21 {clock scan, number:number-timezone} {
+ clock format [clock scan "00:00-0800" -gmt true -base $5amPST] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 08:00:00"
+test clock-34.22 {clock scan, number:number:number o_merid} {
+ clock format [clock scan "8:00:00" -gmt true -base $5amPST] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 08:00:00"
+test clock-34.23 {clock scan, number:number:number o_merid} {
+ clock format [clock scan "8:00:00 am" -gmt true -base $5amPST] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 08:00:00"
+test clock-34.24 {clock scan, number:number:number o_merid} {
+ clock format [clock scan "8:00:00 pm" -gmt true -base $5amPST] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 20:00:00"
+test clock-34.25 {clock scan, number:number:number-timezone} {
+ clock format [clock scan "00:00:30-0800" -gmt true -base $5amPST] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 08:00:30"
+test clock-34.26 {clock scan, DST for days} {
+ clock scan "tomorrow" -base [clock scan "19991031 00:00:00"]
+} [clock scan "19991101 00:00:00"]
+test clock-34.27 {clock scan, DST for days} {
+ clock scan "yesterday" -base [clock scan "19991101 00:00:00"]
+} [clock scan "19991031 00:00:00"]
+test clock-34.28 {clock scan, day} {
+ clock format [clock scan "Monday" -gmt true -base 946627200] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Jan 03, 2000 00:00:00"
+test clock-34.29 {clock scan, number/number} {
+ clock format [clock scan "1/1" -gmt true -base 946627200] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Jan 01, 1999 00:00:00"
+test clock-34.30 {clock scan, number/number} {
+ clock format [clock scan "1/1/1999" -gmt true -base 946627200] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Jan 01, 1999 00:00:00"
+test clock-34.31 {clock scan, number/number} {
+ clock format [clock scan "19990101" -gmt true -base 946627200] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Jan 01, 1999 00:00:00"
+test clock-34.32 {clock scan, relative minutes} {
+ clock scan "now + 1 minute" -base 946627200
+} 946627260
+test clock-34.33 {clock scan, relative minutes} {
+ clock scan "now +1 minute" -base 946627200
+} 946627260
+test clock-34.34 {clock scan, relative minutes} {
+ clock scan "now 1 minute" -base 946627200
+} 946627260
+test clock-34.35 {clock scan, relative minutes} {
+ clock scan "now - 1 minute" -base 946627200
+} 946627140
+test clock-34.36 {clock scan, relative minutes} {
+ clock scan "now -1 minute" -base 946627200
+} 946627140
+test clock-34.37 {clock scan, day of week} {
+ clock format [clock scan "wednesday" -base [clock scan 20000112]] \
+ -format {%b %d, %Y}
+} "Jan 12, 2000"
+test clock-34.38 {clock scan, next day of week} {
+ clock format [clock scan "next wednesday" -base [clock scan 20000112]] \
+ -format {%b %d, %Y}
+} "Jan 19, 2000"
+test clock-34.39 {clock scan, day of week} {
+ clock format [clock scan "thursday" -base [clock scan 20000112]] \
+ -format {%b %d, %Y}
+} "Jan 13, 2000"
+test clock-34.40 {clock scan, next day of week} {
+ clock format [clock scan "next thursday" -base [clock scan 20000112]] \
+ -format {%b %d, %Y}
+} "Jan 20, 2000"
+
+# weekday specification and base.
+test clock-34.41 {2nd monday in november} {
+ set res {}
+ foreach i {91 92 93 94 95 96} {
+ set nov8th [clock scan 11/8/$i]
+ set monday [clock scan monday -base $nov8th]
+ lappend res [clock format $monday -format %Y-%m-%d]
+ }
+ set res
+} {1991-11-11 1992-11-09 1993-11-08 1994-11-14 1995-11-13 1996-11-11}
+test clock-34.42 {2nd monday in november (2nd try)} {
+ set res {}
+ foreach i {91 92 93 94 95 96} {
+ set nov1th [clock scan 11/1/$i]
+ set monday [clock scan "2 monday" -base $nov1th]
+ lappend res [clock format $monday -format %Y-%m-%d]
+ }
+ set res
+} {1991-11-11 1992-11-09 1993-11-08 1994-11-14 1995-11-13 1996-11-11}
+test clock-34.43 {last monday in november} {
+ set res {}
+ foreach i {91 92 93 94 95 96} {
+ set dec1th [clock scan 12/1/$i]
+ set monday [clock scan "monday 1 week ago" -base $dec1th]
+ lappend res [clock format $monday -format %Y-%m-%d]
+ }
+ set res
+} {1991-11-25 1992-11-30 1993-11-29 1994-11-28 1995-11-27 1996-11-25}
+
+test clock-34.44 {2nd monday in november} {
+ set res {}
+ foreach i {91 92 93 94 95 96} {
+ set nov8th [clock scan 11/8/$i -gmt 1]
+ set monday [clock scan monday -base $nov8th -gmt 1]
+ lappend res [clock format $monday -format %Y-%m-%d -gmt 1]
+ }
+ set res
+} {1991-11-11 1992-11-09 1993-11-08 1994-11-14 1995-11-13 1996-11-11}
+test clock-34.45 {2nd monday in november (2nd try)} {
+ set res {}
+ foreach i {91 92 93 94 95 96} {
+ set nov1th [clock scan 11/1/$i -gmt 1]
+ set monday [clock scan "2 monday" -base $nov1th -gmt 1]
+ lappend res [clock format $monday -format %Y-%m-%d -gmt 1]
+ }
+ set res
+} {1991-11-11 1992-11-09 1993-11-08 1994-11-14 1995-11-13 1996-11-11}
+test clock-34.46 {last monday in november} {
+ set res {}
+ foreach i {91 92 93 94 95 96} {
+ set dec1th [clock scan 12/1/$i -gmt 1]
+ set monday [clock scan "monday 1 week ago" -base $dec1th -gmt 1]
+ lappend res [clock format $monday -format %Y-%m-%d -gmt 1]
+ }
+ set res
+} {1991-11-25 1992-11-30 1993-11-29 1994-11-28 1995-11-27 1996-11-25}
+test clock-34.47 {ago with multiple relative units} {
+ set base [clock scan "12/31/1999 00:00:00"]
+ set res [clock scan "2 days 2 hours ago" -base $base]
+ expr {$base - $res}
+} 180000
+
+test clock-34.48 {more than one ToD} {*}{
+ -body {clock scan {10:00 11:00}}
+ -returnCodes error
+ -result {unable to convert date-time string "10:00 11:00": more than one time of day in string}
+}
+
+test clock-34.49 {more than one date} {*}{
+ -body {clock scan {1/1/2001 2/2/2002}}
+ -returnCodes error
+ -result {unable to convert date-time string "1/1/2001 2/2/2002": more than one date in string}
+}
+
+test clock-34.50 {more than one time zone} {*}{
+ -body {clock scan {10:00 EST CST}}
+ -returnCodes error
+ -result {unable to convert date-time string "10:00 EST CST": more than one time zone in string}
+}
+
+test clock-34.51 {more than one weekday} {*}{
+ -body {clock scan {Monday Tuesday}}
+ -returnCodes error
+ -result {unable to convert date-time string "Monday Tuesday": more than one weekday in string}
+}
+
+test clock-34.52 {more than one ordinal month} {*}{
+ -body {clock scan {next January next March}}
+ -returnCodes error
+ -result {unable to convert date-time string "next January next March": more than one ordinal month in string}
+}
+
+
+
+# clock seconds
+test clock-35.1 {clock seconds tests} {
+ expr [clock seconds]+1
+ concat {}
+} {}
+test clock-35.2 {clock seconds tests} {
+ list [catch {clock seconds foo} msg] $msg
+} {1 {wrong # args: should be "clock seconds"}}
+test clock-35.3 {clock seconds tests} {
+ set start [clock seconds]
+ after 2000
+ set end [clock seconds]
+ expr "$end > $start"
+} {1}
+
+
+test clock-36.1 {clock scan next monthname} {
+ clock format [clock scan "next june" -base [clock scan "june 1, 2000"]] \
+ -format %m.%Y
+} "06.2001"
+test clock-36.2 {clock scan next monthname} {
+ clock format [clock scan "next july" -base [clock scan "june 1, 2000"]] \
+ -format %m.%Y
+} "07.2000"
+test clock-36.3 {clock scan next monthname} {
+ clock format [clock scan "next may" -base [clock scan "june 1, 2000"]] \
+ -format %m.%Y
+} "05.2001"
+
+test clock-37.1 {%s gmt testing} {
+ set s [clock seconds]
+ set a [clock format $s -format %s -gmt 0]
+ set b [clock format $s -format %s -gmt 1]
+ # %s, being the difference between local and Greenwich, does not
+ # depend on the time zone.
+ set c [expr {$b-$a}]
+} {0}
+
+test clock-38.1 {regression - convertUTCToLocalViaC - east of Greenwich} \
+ -setup {
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ }
+ set env(TZ) CET-01:00CEST-02:00,M3.5.0/02:00,M10.5.0/03:00
+ } \
+ -body {
+ clock format 0 -format %H:%M:%S -timezone :localtime
+ } \
+ -cleanup {
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ unset oldTZ
+ } else {
+ unset env(TZ)
+ }
+ } \
+ -result {01:00:00}
+
+test clock-38.2 {make sure TZ is not cached after unset} \
+ -setup {
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ unset env(TZ)
+ }
+ if { [info exists env(TCL_TZ)] } {
+ set oldTCLTZ $env(TCL_TZ)
+ unset env(TCL_TZ)
+ }
+ } \
+ -body {
+ set t1 [clock format 0]
+ # a time zone that is unlikely to anywhere
+ set env(TZ) "+04:20"
+ set t2 [clock format 0]
+ unset env(TZ)
+ set t3 [clock format 0]
+ expr {$t1 eq $t3 && $t1 ne $t2}
+ } \
+ -cleanup {
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ unset oldTZ
+ }
+ if { [info exists oldTclTZ] } {
+ set env(TCL_TZ) $oldTclTZ
+ unset oldTclTZ
+ }
+ } \
+ -result 1
+
+
+test clock-39.1 {regression - synonym timezones} {
+ clock format 0 -format {%H:%M:%S} -timezone :US/Eastern
+} {19:00:00}
+
+test clock-40.1 {regression - bad month with -timezone :localtime} \
+ -setup {
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ }
+ set env(TZ) UTC0
+ } \
+ -body {
+ clock scan 2000-01-01T00:00:00 -timezone :localtime \
+ -format %Y-%m-%dT%H:%M:%S
+ } \
+ -cleanup {
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ unset oldTZ
+ } else {
+ unset env(TZ)
+ }
+ } \
+ -result 946684800
+
+test clock-41.1 {regression test - format group %k when hour is 0 } {
+ clock format 0 -format %k -gmt true
+} { 0}
+
+test clock-42.1 {regression test - %z in :localtime when west of Greenwich } \
+ -setup {
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ }
+ set env(TZ) EST5
+ } \
+ -body {
+ clock format 0 -format %z -timezone :localtime
+ } \
+ -cleanup {
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ unset oldTZ
+ } else {
+ unset env(TZ)
+ }
+ } \
+ -result {-0500}
+
+# 43.1 was a bad test - mktime returning -1 is an error according to posix.
+
+test clock-44.1 {regression test - time zone name containing hyphen } \
+ -setup {
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ }
+ set env(TZ) US/East-Indiana
+ } \
+ -body {
+ clock format 1098466496 -format %H:%M:%S%z -timezone US/East-Indiana
+ } \
+ -cleanup {
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ unset oldTZ
+ } else {
+ unset env(TZ)
+ }
+ } \
+ -result {12:34:56-0500}
+
+test clock-45.1 {regression test - time zone containing only two digits} \
+ -body {
+ clock scan 1985-04-12T10:15:30+04 -format %Y-%m-%dT%H:%M:%S%Z
+ } \
+ -result 482134530
+
+test clock-46.1 {regression test - month zero} \
+ -body {
+ clock scan 2004-00-00 -format %Y-%m-%d
+ } -result [clock scan 2003-11-30 -format %Y-%m-%d]
+test clock-46.2 {regression test - month zero} \
+ -body {
+ clock scan 20040000
+ } -result [clock scan 2003-11-30 -format %Y-%m-%d]
+test clock-46.3 {regression test - month thirteen} \
+ -body {
+ clock scan 2004-13-01 -format %Y-%m-%d
+ } -result [clock scan 2005-01-01 -format %Y-%m-%d]
+test clock-46.4 {regression test - month thirteen} \
+ -body {
+ clock scan 20041301
+ } -result [clock scan 2005-01-01 -format %Y-%m-%d]
+
+test clock-47.1 {regression test - four-digit time} {
+ clock scan 0012
+} [clock scan 0012 -format %H%M]
+test clock-47.2 {regression test - four digit time} {
+ clock scan 0039
+} [clock scan 0039 -format %H%M]
+
+test clock-48.1 {Bug 1185933: 'i' destroyed by clock init} -setup {
+ interp create child
+} -body {
+ interp eval child {
+ set i 12345
+ clock format 0
+ list [catch { set i } result] $result
+ }
+} -cleanup {
+ interp delete child
+} -result {0 12345}
+
+test clock-49.1 {regression test - localtime with negative arg (Bug 1237907)} \
+ -body {
+ list [catch {
+ clock format -86400 -timezone :localtime -format %Y
+ } result] $result
+ } \
+ -match regexp \
+ -result {0 1969|1 {localtime failed \(clock value may be too large/small to represent\)}}
+
+test clock-49.2 {regression test - missing time zone file (Bug 1237907)} \
+ -constraints win \
+ -setup {
+ # override the registry so that the test takes place in New York time
+ namespace eval ::tcl::clock {
+ namespace import -force ::testClock::registry
+ }
+ set noreg [info exists ::tcl::clock::NoRegistry]
+ if {$noreg} {unset ::tcl::clock::NoRegistry}
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ unset env(TZ)
+ }
+ if { [info exists env(TCL_TZ)] } {
+ set oldTclTZ $env(TCL_TZ)
+ unset env(TCL_TZ)
+ }
+ # make it so New York time is a missing file
+ dict set ::tcl::clock::WinZoneInfo \
+ {-18000 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} \
+ :No/Such/File
+ ::tcl::clock::ClearCaches
+ } \
+ -body {
+ list [::tcl::clock::GuessWindowsTimeZone] \
+ [clock format 0 -locale system -format "%H:%M:%S %Z"] \
+ [clock format -86400 -format "%Y"]
+ } \
+ -cleanup {
+ # restore the registry and environment
+ namespace eval ::tcl::clock {
+ rename registry {}
+ }
+ if {$noreg} {set ::tcl::clock::NoRegistry {}}
+ if { [info exists oldTclTZ] } {
+ set env(TCL_TZ) $oldTclTZ
+ }
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ }
+ # put New York back on the map
+ dict set ::tcl::clock::WinZoneInfo \
+ {-18000 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} \
+ :America/New_York
+ ::tcl::clock::ClearCaches
+ } \
+ -result {<-0500>+05:00:00<-0400>+04:00:00,M3.2.0/02:00:00,M11.1.0/02:00:00 {19:00:00 -0500} 1969}
+
+test clock-50.1 {format / scan -1 as a local time} {
+ if {[catch {
+ clock scan \
+ [clock format -1 -format %Y%m%d%H%M%S -timezone :localtime] \
+ -format %Y%m%d%H%M%S -timezone :localtime
+ } result]} {
+ if { [regexp " too large" $result] } {
+ set result -1
+ }
+ }
+ set result
+} -1
+test clock-50.2 {format / scan -2 as a local time} {
+ if {[catch {
+ clock scan \
+ [clock format -2 -format %Y%m%d%H%M%S -timezone :localtime] \
+ -format %Y%m%d%H%M%S -timezone :localtime
+ } result]} {
+ if { [regexp " too large" $result] } {
+ set result -2
+ }
+ }
+ set result
+} -2
+
+test clock-51.1 {correct conversion of times in Sydney} {
+ # Paul Mackerras reported a bug where DST rollover in New South Wales
+ # was miscalculated. The problem was that tclZIC.tcl had a
+ # typo in the switch case where DST begins/ends at a given time
+ # Standard Time (that is, winter time).
+ set result {}
+ foreach t {1130601599 1130601600 1130637599 1130637600} {
+ lappend result [clock format $t -format %H:%M:%S \
+ -timezone :Australia/Sydney]
+ }
+ set result
+} {01:59:59 03:00:00 12:59:59 13:00:00}
+
+test clock-52.1 {Posix timezone and conversion on last Sunday} {
+ # Martin Lemburg reported a bug where if tzdata is missing, then
+ # times are converted incorrectly in locales where DST conversion
+ # happens in the last (nominal 5th) week of a month.
+ set result {}
+ set timezone <MEZ>-01:00:00<MESZ>-02:00:00,M3.5.0/02:00:00,M10.5.0/01:00:00
+ foreach t {1143334799 1143334800} {
+ lappend result [clock format $t -format %H:%M:%S -timezone $timezone] \
+ [clock format $t -format %H:%M:%S -timezone :Europe/Berlin]
+ }
+ set result
+} {01:59:59 01:59:59 03:00:00 03:00:00}
+
+test clock-52.2 {correct conversion of times in Europe} {
+ # [Bug 2207436]
+ set result {}
+ foreach t [list 1206838799 1206838800 1224982799 1224982800] {
+ lappend result [clock format $t -format %H:%M:%S \
+ -timezone MET-1METDST]
+ lappend result [clock format $t -format %H:%M:%S \
+ -timezone MET0METDST]
+ }
+ set result
+} {01:59:59 00:59:59 03:00:00 02:00:00 02:59:59 01:59:59 02:00:00 01:00:00}
+
+test clock-52.3 {correct conversion of times in Russia} {
+ # [Bug 2207436]
+ set result {}
+ foreach t [list 1206799199 1206799200 1224943199 1224943200] {
+ lappend result [clock format $t -format %H:%M:%S \
+ -timezone WST-12WSTDST]
+ }
+ set result
+} {01:59:59 03:00:00 02:59:59 02:00:00}
+
+test clock-52.4 {correct conversion of times in USA} {
+ # [Bug 2207436]
+ set result {}
+ foreach t [list 1268549999 1268550000 1257055199 1257055200] {
+ lappend result [clock format $t -format %H:%M:%S \
+ -timezone EST5EDT]
+ }
+ set result
+} {01:59:59 03:00:00 01:59:59 01:00:00}
+
+# Regression test for Bug # 1505383
+
+test clock-53.1 {%EC %Ey} {
+ clock format 0 -gmt true -locale en_US_roman -format %EC%Ey
+} mcmlxx
+
+# Test that glob-special characters can be handled in [clock]
+
+test clock-54.1 {glob specials in [clock format]} \
+ -setup {
+ clock format 0 -gmt 1 -format %Y
+ } \
+ -body {
+ clock format 0 -gmt 1 -format {*[%Y%m%d]*}
+ } \
+ -result {*[19700101]*}
+test clock-54.2 {glob specials in [clock scan]} \
+ -setup {
+ clock scan 1970 -gmt 1 -format %Y
+ } \
+ -body {
+ clock scan {*[19700101]*} -format {*[%Y%m%d]*} -gmt 1
+ } \
+ -result 0
+
+test clock-55.1 {Common Era} {
+ clock format -62135769600 -gmt 1 -format {%d %m %Y %EE}
+} {01 01 0001 C.E.}
+test clock-55.2 {Common Era} {
+ clock format -62135769600 -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} {01 01 0001 Anno Domini}
+test clock-55.3 {Before the Common Era} {
+ clock format -62135769601 -gmt 1 -format {%d %m %Y %EE}
+} {31 12 0001 B.C.E.}
+test clock-55.4 {Before the Common Era} {
+ clock format -62135769601 -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} {31 12 0001 Before Christ}
+test clock-55.5 {Common Era} {
+ clock scan {01 01 0001 C.E.} \
+ -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135769600
+test clock-55.6 {Common Era} {
+ clock scan {01 01 0001 A.D.} \
+ -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135769600
+test clock-55.7 {Common Era} {
+ clock scan {01 01 0001 Anno Domini} \
+ -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135769600
+test clock-55.8 {Before the Common Era} {
+ clock scan {31 12 0001 B.C.E.} \
+ -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135856000
+test clock-55.9 {Common Era} {
+ clock scan {31 12 0001 B.C.} \
+ -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135856000
+test clock-55.10 {Common Era} {
+ clock scan {31 12 0001 Before Christ} \
+ -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135856000
+
+test clock-56.1 {use of zoneinfo, version 1} {*}{
+ -setup {
+ clock format [clock seconds]
+ set tzdir [makeDirectory zoneinfo]
+ set tzdir2 [makeDirectory Test $tzdir]
+ set tzfile [makeFile {} PhoenixOne $tzdir2]
+ set f [open $tzfile wb]
+ puts -nonewline $f [binary format c* {
+ 0x54 0x5a 0x69 0x66 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x03
+ 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0a
+ 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x0c 0x9e 0xa6 0x3a 0x90
+ 0x9f 0xbb 0x07 0x80 0xa0 0x86 0x1c 0x90 0xa1 0x9a 0xe9 0x80
+ 0xcb 0x89 0x0c 0x90 0xcf 0x17 0xdf 0x1c 0xcf 0x8f 0xe5 0xac
+ 0xd0 0x81 0x1a 0x1c 0xfa 0xf8 0x75 0x10 0xfb 0xe8 0x58 0x00
+ 0x00 0x01 0x00 0x01 0x02 0x01 0x02 0x01 0x00 0x01 0xff 0xff
+ 0xab 0xa0 0x01 0x00 0xff 0xff 0x9d 0x90 0x00 0x04 0xff 0xff
+ 0xab 0xa0 0x01 0x08 0x4d 0x44 0x54 0x00 0x4d 0x53 0x54 0x00
+ 0x4d 0x57 0x54 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ }]
+ close $f
+ set ::tcl::clock::ZoneinfoPaths \
+ [linsert $::tcl::clock::ZoneinfoPaths 0 $tzdir]
+ ::tcl::clock::ClearCaches
+ }
+ -cleanup {
+ set ::tcl::clock::ZoneinfoPaths \
+ [lrange $::tcl::clock::ZoneinfoPaths 1 end]
+ ::tcl::clock::ClearCaches
+ removeFile PhoenixOne $tzdir2
+ removeDirectory Test $tzdir
+ removeDirectory zoneinfo
+ }
+ -body {
+ clock format 1072940400 -timezone :Test/PhoenixOne \
+ -format {%Y-%m-%d %H:%M:%S %Z}
+ }
+ -result {2004-01-01 00:00:00 MST}
+}
+
+test clock-56.2 {use of zoneinfo, version 2} {*}{
+ -setup {
+ clock format [clock seconds]
+ set tzdir [makeDirectory zoneinfo]
+ set tzdir2 [makeDirectory Test $tzdir]
+ set tzfile [makeFile {} PhoenixTwo $tzdir2]
+ set f [open $tzfile wb]
+ puts -nonewline $f [binary format c* {
+ 0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x03
+ 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0a
+ 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x0c 0x9e 0xa6 0x3a 0x90
+ 0x9f 0xbb 0x07 0x80 0xa0 0x86 0x1c 0x90 0xa1 0x9a 0xe9 0x80
+ 0xcb 0x89 0x0c 0x90 0xcf 0x17 0xdf 0x1c 0xcf 0x8f 0xe5 0xac
+ 0xd0 0x81 0x1a 0x1c 0xfa 0xf8 0x75 0x10 0xfb 0xe8 0x58 0x00
+ 0x00 0x01 0x00 0x01 0x02 0x01 0x02 0x01 0x00 0x01 0xff 0xff
+ 0xab 0xa0 0x01 0x00 0xff 0xff 0x9d 0x90 0x00 0x04 0xff 0xff
+ 0xab 0xa0 0x01 0x08 0x4d 0x44 0x54 0x00 0x4d 0x53 0x54 0x00
+ 0x4d 0x57 0x54 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x54 0x5a
+ 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x04 0x00 0x00
+ 0x00 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0b 0x00 0x00
+ 0x00 0x04 0x00 0x00 0x00 0x10 0xff 0xff 0xff 0xff 0x5e 0x04
+ 0x0c 0xb0 0xff 0xff 0xff 0xff 0x9e 0xa6 0x3a 0x90 0xff 0xff
+ 0xff 0xff 0x9f 0xbb 0x07 0x80 0xff 0xff 0xff 0xff 0xa0 0x86
+ 0x1c 0x90 0xff 0xff 0xff 0xff 0xa1 0x9a 0xe9 0x80 0xff 0xff
+ 0xff 0xff 0xcb 0x89 0x0c 0x90 0xff 0xff 0xff 0xff 0xcf 0x17
+ 0xdf 0x1c 0xff 0xff 0xff 0xff 0xcf 0x8f 0xe5 0xac 0xff 0xff
+ 0xff 0xff 0xd0 0x81 0x1a 0x1c 0xff 0xff 0xff 0xff 0xfa 0xf8
+ 0x75 0x10 0xff 0xff 0xff 0xff 0xfb 0xe8 0x58 0x00 0x02 0x01
+ 0x02 0x01 0x02 0x03 0x02 0x03 0x02 0x01 0x02 0xff 0xff 0x96
+ 0xee 0x00 0x00 0xff 0xff 0xab 0xa0 0x01 0x04 0xff 0xff 0x9d
+ 0x90 0x00 0x08 0xff 0xff 0xab 0xa0 0x01 0x0c 0x4c 0x4d 0x54
+ 0x00 0x4d 0x44 0x54 0x00 0x4d 0x53 0x54 0x00 0x4d 0x57 0x54
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0a 0x4d 0x53
+ 0x54 0x37 0x0a
+ }]
+ close $f
+ set ::tcl::clock::ZoneinfoPaths \
+ [linsert $::tcl::clock::ZoneinfoPaths 0 $tzdir]
+ ::tcl::clock::ClearCaches
+ }
+ -cleanup {
+ set ::tcl::clock::ZoneinfoPaths \
+ [lrange $::tcl::clock::ZoneinfoPaths 1 end]
+ ::tcl::clock::ClearCaches
+ removeFile PhoenixTwo $tzdir2
+ removeDirectory Test $tzdir
+ removeDirectory zoneinfo
+ }
+ -body {
+ clock format 1072940400 -timezone :Test/PhoenixTwo \
+ -format {%Y-%m-%d %H:%M:%S %Z}
+ }
+ -result {2004-01-01 00:00:00 MST}
+}
+
+test clock-56.3 {use of zoneinfo, version 2, Y2038 compliance} {*}{
+ -setup {
+ clock format [clock seconds]
+ set tzdir [makeDirectory zoneinfo]
+ set tzdir2 [makeDirectory Test $tzdir]
+ set tzfile [makeFile {} TijuanaTwo $tzdir2]
+ set f [open $tzfile wb]
+ puts -nonewline $f [binary format c* {
+ 0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x06 0x00 0x00
+ 0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x95 0x00 0x00 0x00
+ 0x06 0x00 0x00 0x00 0x18 0xa5 0xb6 0xf6 0x80 0xa9 0x79 0x4f 0x70
+ 0xaf 0xf2 0x7c 0xf0 0xb6 0x66 0x64 0x70 0xb7 0x1b 0x10 0x00 0xb8
+ 0x0a 0xf2 0xf0 0xcb 0xea 0x8d 0x80 0xd2 0x23 0xf4 0x70 0xd2 0x99
+ 0xba 0x70 0xd7 0x1b 0x59 0x00 0xd8 0x91 0xb4 0xf0 0xe2 0x7e 0x59
+ 0xa0 0xe3 0x49 0x52 0x90 0xe4 0x5e 0x3b 0xa0 0xe5 0x29 0x34 0x90
+ 0xe6 0x47 0x58 0x20 0xe7 0x12 0x51 0x10 0xe8 0x27 0x3a 0x20 0xe8
+ 0xf2 0x33 0x10 0xea 0x07 0x1c 0x20 0xea 0xd2 0x15 0x10 0xeb 0xe6
+ 0xfe 0x20 0xec 0xb1 0xf7 0x10 0xed 0xc6 0xe0 0x20 0xee 0x91 0xd9
+ 0x10 0x0b 0xe0 0xaf 0xa0 0x0c 0xd9 0xcd 0x10 0x0d 0xc0 0x91 0xa0
+ 0x0e 0xb9 0xaf 0x10 0x0f 0xa9 0xae 0x20 0x10 0x99 0x91 0x10 0x11
+ 0x89 0x90 0x20 0x12 0x79 0x73 0x10 0x13 0x69 0x72 0x20 0x14 0x59
+ 0x55 0x10 0x15 0x49 0x54 0x20 0x16 0x39 0x37 0x10 0x17 0x29 0x36
+ 0x20 0x18 0x22 0x53 0x90 0x19 0x09 0x18 0x20 0x1a 0x02 0x35 0x90
+ 0x1a 0xf2 0x34 0xa0 0x1b 0xe2 0x17 0x90 0x1c 0xd2 0x16 0xa0 0x1d
+ 0xc1 0xf9 0x90 0x1e 0xb1 0xf8 0xa0 0x1f 0xa1 0xdb 0x90 0x20 0x76
+ 0x2b 0x20 0x21 0x81 0xbd 0x90 0x22 0x56 0x0d 0x20 0x23 0x6a 0xda
+ 0x10 0x24 0x35 0xef 0x20 0x25 0x4a 0xbc 0x10 0x26 0x15 0xd1 0x20
+ 0x27 0x2a 0x9e 0x10 0x27 0xfe 0xed 0xa0 0x29 0x0a 0x80 0x10 0x29
+ 0xde 0xcf 0xa0 0x2a 0xea 0x62 0x10 0x2b 0xbe 0xb1 0xa0 0x2c 0xd3
+ 0x7e 0x90 0x2d 0x9e 0x93 0xa0 0x2e 0xb3 0x60 0x90 0x2f 0x7e 0x75
+ 0xa0 0x30 0x93 0x42 0x90 0x31 0x67 0x92 0x20 0x32 0x73 0x24 0x90
+ 0x33 0x47 0x74 0x20 0x34 0x53 0x06 0x90 0x35 0x27 0x56 0x20 0x36
+ 0x32 0xe8 0x90 0x37 0x07 0x38 0x20 0x38 0x1c 0x05 0x10 0x38 0xe7
+ 0x1a 0x20 0x39 0xfb 0xe7 0x10 0x3a 0xc6 0xfc 0x20 0x3b 0xdb 0xc9
+ 0x10 0x3c 0xb0 0x18 0xa0 0x3d 0xbb 0xab 0x10 0x3e 0x8f 0xfa 0xa0
+ 0x3f 0x9b 0x8d 0x10 0x40 0x6f 0xdc 0xa0 0x41 0x84 0xa9 0x90 0x42
+ 0x4f 0xbe 0xa0 0x43 0x64 0x8b 0x90 0x44 0x2f 0xa0 0xa0 0x45 0x44
+ 0x6d 0x90 0x46 0x0f 0x82 0xa0 0x47 0x24 0x4f 0x90 0x47 0xf8 0x9f
+ 0x20 0x49 0x04 0x31 0x90 0x49 0xd8 0x81 0x20 0x4a 0xe4 0x13 0x90
+ 0x4b 0xb8 0x63 0x20 0x4c 0xcd 0x30 0x10 0x4d 0x98 0x45 0x20 0x4e
+ 0xad 0x12 0x10 0x4f 0x78 0x27 0x20 0x50 0x8c 0xf4 0x10 0x51 0x61
+ 0x43 0xa0 0x52 0x6c 0xd6 0x10 0x53 0x41 0x25 0xa0 0x54 0x4c 0xb8
+ 0x10 0x55 0x21 0x07 0xa0 0x56 0x2c 0x9a 0x10 0x57 0x00 0xe9 0xa0
+ 0x58 0x15 0xb6 0x90 0x58 0xe0 0xcb 0xa0 0x59 0xf5 0x98 0x90 0x5a
+ 0xc0 0xad 0xa0 0x5b 0xd5 0x7a 0x90 0x5c 0xa9 0xca 0x20 0x5d 0xb5
+ 0x5c 0x90 0x5e 0x89 0xac 0x20 0x5f 0x95 0x3e 0x90 0x60 0x69 0x8e
+ 0x20 0x61 0x7e 0x5b 0x10 0x62 0x49 0x70 0x20 0x63 0x5e 0x3d 0x10
+ 0x64 0x29 0x52 0x20 0x65 0x3e 0x1f 0x10 0x66 0x12 0x6e 0xa0 0x67
+ 0x1e 0x01 0x10 0x67 0xf2 0x50 0xa0 0x68 0xfd 0xe3 0x10 0x69 0xd2
+ 0x32 0xa0 0x6a 0xdd 0xc5 0x10 0x6b 0xb2 0x14 0xa0 0x6c 0xc6 0xe1
+ 0x90 0x6d 0x91 0xf6 0xa0 0x6e 0xa6 0xc3 0x90 0x6f 0x71 0xd8 0xa0
+ 0x70 0x86 0xa5 0x90 0x71 0x5a 0xf5 0x20 0x72 0x66 0x87 0x90 0x73
+ 0x3a 0xd7 0x20 0x74 0x46 0x69 0x90 0x75 0x1a 0xb9 0x20 0x76 0x2f
+ 0x86 0x10 0x76 0xfa 0x9b 0x20 0x78 0x0f 0x68 0x10 0x78 0xda 0x7d
+ 0x20 0x79 0xef 0x4a 0x10 0x7a 0xba 0x5f 0x20 0x7b 0xcf 0x2c 0x10
+ 0x7c 0xa3 0x7b 0xa0 0x7d 0xaf 0x0e 0x10 0x7e 0x83 0x5d 0xa0 0x7f
+ 0x8e 0xf0 0x10 0x01 0x02 0x01 0x02 0x03 0x02 0x04 0x05 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0xff 0xff 0x92 0x4c
+ 0x00 0x00 0xff 0xff 0x9d 0x90 0x00 0x04 0xff 0xff 0x8f 0x80 0x00
+ 0x08 0xff 0xff 0x9d 0x90 0x01 0x0c 0xff 0xff 0x9d 0x90 0x01 0x10
+ 0xff 0xff 0x9d 0x90 0x01 0x14 0x4c 0x4d 0x54 0x00 0x4d 0x53 0x54
+ 0x00 0x50 0x53 0x54 0x00 0x50 0x44 0x54 0x00 0x50 0x57 0x54 0x00
+ 0x50 0x50 0x54 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00
+ 0x00 0x00 0x01 0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x06 0x00 0x00 0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x95
+ 0x00 0x00 0x00 0x06 0x00 0x00 0x00 0x18 0xff 0xff 0xff 0xff 0xa5
+ 0xb6 0xf6 0x80 0xff 0xff 0xff 0xff 0xa9 0x79 0x4f 0x70 0xff 0xff
+ 0xff 0xff 0xaf 0xf2 0x7c 0xf0 0xff 0xff 0xff 0xff 0xb6 0x66 0x64
+ 0x70 0xff 0xff 0xff 0xff 0xb7 0x1b 0x10 0x00 0xff 0xff 0xff 0xff
+ 0xb8 0x0a 0xf2 0xf0 0xff 0xff 0xff 0xff 0xcb 0xea 0x8d 0x80 0xff
+ 0xff 0xff 0xff 0xd2 0x23 0xf4 0x70 0xff 0xff 0xff 0xff 0xd2 0x99
+ 0xba 0x70 0xff 0xff 0xff 0xff 0xd7 0x1b 0x59 0x00 0xff 0xff 0xff
+ 0xff 0xd8 0x91 0xb4 0xf0 0xff 0xff 0xff 0xff 0xe2 0x7e 0x59 0xa0
+ 0xff 0xff 0xff 0xff 0xe3 0x49 0x52 0x90 0xff 0xff 0xff 0xff 0xe4
+ 0x5e 0x3b 0xa0 0xff 0xff 0xff 0xff 0xe5 0x29 0x34 0x90 0xff 0xff
+ 0xff 0xff 0xe6 0x47 0x58 0x20 0xff 0xff 0xff 0xff 0xe7 0x12 0x51
+ 0x10 0xff 0xff 0xff 0xff 0xe8 0x27 0x3a 0x20 0xff 0xff 0xff 0xff
+ 0xe8 0xf2 0x33 0x10 0xff 0xff 0xff 0xff 0xea 0x07 0x1c 0x20 0xff
+ 0xff 0xff 0xff 0xea 0xd2 0x15 0x10 0xff 0xff 0xff 0xff 0xeb 0xe6
+ 0xfe 0x20 0xff 0xff 0xff 0xff 0xec 0xb1 0xf7 0x10 0xff 0xff 0xff
+ 0xff 0xed 0xc6 0xe0 0x20 0xff 0xff 0xff 0xff 0xee 0x91 0xd9 0x10
+ 0x00 0x00 0x00 0x00 0x0b 0xe0 0xaf 0xa0 0x00 0x00 0x00 0x00 0x0c
+ 0xd9 0xcd 0x10 0x00 0x00 0x00 0x00 0x0d 0xc0 0x91 0xa0 0x00 0x00
+ 0x00 0x00 0x0e 0xb9 0xaf 0x10 0x00 0x00 0x00 0x00 0x0f 0xa9 0xae
+ 0x20 0x00 0x00 0x00 0x00 0x10 0x99 0x91 0x10 0x00 0x00 0x00 0x00
+ 0x11 0x89 0x90 0x20 0x00 0x00 0x00 0x00 0x12 0x79 0x73 0x10 0x00
+ 0x00 0x00 0x00 0x13 0x69 0x72 0x20 0x00 0x00 0x00 0x00 0x14 0x59
+ 0x55 0x10 0x00 0x00 0x00 0x00 0x15 0x49 0x54 0x20 0x00 0x00 0x00
+ 0x00 0x16 0x39 0x37 0x10 0x00 0x00 0x00 0x00 0x17 0x29 0x36 0x20
+ 0x00 0x00 0x00 0x00 0x18 0x22 0x53 0x90 0x00 0x00 0x00 0x00 0x19
+ 0x09 0x18 0x20 0x00 0x00 0x00 0x00 0x1a 0x02 0x35 0x90 0x00 0x00
+ 0x00 0x00 0x1a 0xf2 0x34 0xa0 0x00 0x00 0x00 0x00 0x1b 0xe2 0x17
+ 0x90 0x00 0x00 0x00 0x00 0x1c 0xd2 0x16 0xa0 0x00 0x00 0x00 0x00
+ 0x1d 0xc1 0xf9 0x90 0x00 0x00 0x00 0x00 0x1e 0xb1 0xf8 0xa0 0x00
+ 0x00 0x00 0x00 0x1f 0xa1 0xdb 0x90 0x00 0x00 0x00 0x00 0x20 0x76
+ 0x2b 0x20 0x00 0x00 0x00 0x00 0x21 0x81 0xbd 0x90 0x00 0x00 0x00
+ 0x00 0x22 0x56 0x0d 0x20 0x00 0x00 0x00 0x00 0x23 0x6a 0xda 0x10
+ 0x00 0x00 0x00 0x00 0x24 0x35 0xef 0x20 0x00 0x00 0x00 0x00 0x25
+ 0x4a 0xbc 0x10 0x00 0x00 0x00 0x00 0x26 0x15 0xd1 0x20 0x00 0x00
+ 0x00 0x00 0x27 0x2a 0x9e 0x10 0x00 0x00 0x00 0x00 0x27 0xfe 0xed
+ 0xa0 0x00 0x00 0x00 0x00 0x29 0x0a 0x80 0x10 0x00 0x00 0x00 0x00
+ 0x29 0xde 0xcf 0xa0 0x00 0x00 0x00 0x00 0x2a 0xea 0x62 0x10 0x00
+ 0x00 0x00 0x00 0x2b 0xbe 0xb1 0xa0 0x00 0x00 0x00 0x00 0x2c 0xd3
+ 0x7e 0x90 0x00 0x00 0x00 0x00 0x2d 0x9e 0x93 0xa0 0x00 0x00 0x00
+ 0x00 0x2e 0xb3 0x60 0x90 0x00 0x00 0x00 0x00 0x2f 0x7e 0x75 0xa0
+ 0x00 0x00 0x00 0x00 0x30 0x93 0x42 0x90 0x00 0x00 0x00 0x00 0x31
+ 0x67 0x92 0x20 0x00 0x00 0x00 0x00 0x32 0x73 0x24 0x90 0x00 0x00
+ 0x00 0x00 0x33 0x47 0x74 0x20 0x00 0x00 0x00 0x00 0x34 0x53 0x06
+ 0x90 0x00 0x00 0x00 0x00 0x35 0x27 0x56 0x20 0x00 0x00 0x00 0x00
+ 0x36 0x32 0xe8 0x90 0x00 0x00 0x00 0x00 0x37 0x07 0x38 0x20 0x00
+ 0x00 0x00 0x00 0x38 0x1c 0x05 0x10 0x00 0x00 0x00 0x00 0x38 0xe7
+ 0x1a 0x20 0x00 0x00 0x00 0x00 0x39 0xfb 0xe7 0x10 0x00 0x00 0x00
+ 0x00 0x3a 0xc6 0xfc 0x20 0x00 0x00 0x00 0x00 0x3b 0xdb 0xc9 0x10
+ 0x00 0x00 0x00 0x00 0x3c 0xb0 0x18 0xa0 0x00 0x00 0x00 0x00 0x3d
+ 0xbb 0xab 0x10 0x00 0x00 0x00 0x00 0x3e 0x8f 0xfa 0xa0 0x00 0x00
+ 0x00 0x00 0x3f 0x9b 0x8d 0x10 0x00 0x00 0x00 0x00 0x40 0x6f 0xdc
+ 0xa0 0x00 0x00 0x00 0x00 0x41 0x84 0xa9 0x90 0x00 0x00 0x00 0x00
+ 0x42 0x4f 0xbe 0xa0 0x00 0x00 0x00 0x00 0x43 0x64 0x8b 0x90 0x00
+ 0x00 0x00 0x00 0x44 0x2f 0xa0 0xa0 0x00 0x00 0x00 0x00 0x45 0x44
+ 0x6d 0x90 0x00 0x00 0x00 0x00 0x46 0x0f 0x82 0xa0 0x00 0x00 0x00
+ 0x00 0x47 0x24 0x4f 0x90 0x00 0x00 0x00 0x00 0x47 0xf8 0x9f 0x20
+ 0x00 0x00 0x00 0x00 0x49 0x04 0x31 0x90 0x00 0x00 0x00 0x00 0x49
+ 0xd8 0x81 0x20 0x00 0x00 0x00 0x00 0x4a 0xe4 0x13 0x90 0x00 0x00
+ 0x00 0x00 0x4b 0xb8 0x63 0x20 0x00 0x00 0x00 0x00 0x4c 0xcd 0x30
+ 0x10 0x00 0x00 0x00 0x00 0x4d 0x98 0x45 0x20 0x00 0x00 0x00 0x00
+ 0x4e 0xad 0x12 0x10 0x00 0x00 0x00 0x00 0x4f 0x78 0x27 0x20 0x00
+ 0x00 0x00 0x00 0x50 0x8c 0xf4 0x10 0x00 0x00 0x00 0x00 0x51 0x61
+ 0x43 0xa0 0x00 0x00 0x00 0x00 0x52 0x6c 0xd6 0x10 0x00 0x00 0x00
+ 0x00 0x53 0x41 0x25 0xa0 0x00 0x00 0x00 0x00 0x54 0x4c 0xb8 0x10
+ 0x00 0x00 0x00 0x00 0x55 0x21 0x07 0xa0 0x00 0x00 0x00 0x00 0x56
+ 0x2c 0x9a 0x10 0x00 0x00 0x00 0x00 0x57 0x00 0xe9 0xa0 0x00 0x00
+ 0x00 0x00 0x58 0x15 0xb6 0x90 0x00 0x00 0x00 0x00 0x58 0xe0 0xcb
+ 0xa0 0x00 0x00 0x00 0x00 0x59 0xf5 0x98 0x90 0x00 0x00 0x00 0x00
+ 0x5a 0xc0 0xad 0xa0 0x00 0x00 0x00 0x00 0x5b 0xd5 0x7a 0x90 0x00
+ 0x00 0x00 0x00 0x5c 0xa9 0xca 0x20 0x00 0x00 0x00 0x00 0x5d 0xb5
+ 0x5c 0x90 0x00 0x00 0x00 0x00 0x5e 0x89 0xac 0x20 0x00 0x00 0x00
+ 0x00 0x5f 0x95 0x3e 0x90 0x00 0x00 0x00 0x00 0x60 0x69 0x8e 0x20
+ 0x00 0x00 0x00 0x00 0x61 0x7e 0x5b 0x10 0x00 0x00 0x00 0x00 0x62
+ 0x49 0x70 0x20 0x00 0x00 0x00 0x00 0x63 0x5e 0x3d 0x10 0x00 0x00
+ 0x00 0x00 0x64 0x29 0x52 0x20 0x00 0x00 0x00 0x00 0x65 0x3e 0x1f
+ 0x10 0x00 0x00 0x00 0x00 0x66 0x12 0x6e 0xa0 0x00 0x00 0x00 0x00
+ 0x67 0x1e 0x01 0x10 0x00 0x00 0x00 0x00 0x67 0xf2 0x50 0xa0 0x00
+ 0x00 0x00 0x00 0x68 0xfd 0xe3 0x10 0x00 0x00 0x00 0x00 0x69 0xd2
+ 0x32 0xa0 0x00 0x00 0x00 0x00 0x6a 0xdd 0xc5 0x10 0x00 0x00 0x00
+ 0x00 0x6b 0xb2 0x14 0xa0 0x00 0x00 0x00 0x00 0x6c 0xc6 0xe1 0x90
+ 0x00 0x00 0x00 0x00 0x6d 0x91 0xf6 0xa0 0x00 0x00 0x00 0x00 0x6e
+ 0xa6 0xc3 0x90 0x00 0x00 0x00 0x00 0x6f 0x71 0xd8 0xa0 0x00 0x00
+ 0x00 0x00 0x70 0x86 0xa5 0x90 0x00 0x00 0x00 0x00 0x71 0x5a 0xf5
+ 0x20 0x00 0x00 0x00 0x00 0x72 0x66 0x87 0x90 0x00 0x00 0x00 0x00
+ 0x73 0x3a 0xd7 0x20 0x00 0x00 0x00 0x00 0x74 0x46 0x69 0x90 0x00
+ 0x00 0x00 0x00 0x75 0x1a 0xb9 0x20 0x00 0x00 0x00 0x00 0x76 0x2f
+ 0x86 0x10 0x00 0x00 0x00 0x00 0x76 0xfa 0x9b 0x20 0x00 0x00 0x00
+ 0x00 0x78 0x0f 0x68 0x10 0x00 0x00 0x00 0x00 0x78 0xda 0x7d 0x20
+ 0x00 0x00 0x00 0x00 0x79 0xef 0x4a 0x10 0x00 0x00 0x00 0x00 0x7a
+ 0xba 0x5f 0x20 0x00 0x00 0x00 0x00 0x7b 0xcf 0x2c 0x10 0x00 0x00
+ 0x00 0x00 0x7c 0xa3 0x7b 0xa0 0x00 0x00 0x00 0x00 0x7d 0xaf 0x0e
+ 0x10 0x00 0x00 0x00 0x00 0x7e 0x83 0x5d 0xa0 0x00 0x00 0x00 0x00
+ 0x7f 0x8e 0xf0 0x10 0x01 0x02 0x01 0x02 0x03 0x02 0x04 0x05 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0xff 0xff 0x92
+ 0x4c 0x00 0x00 0xff 0xff 0x9d 0x90 0x00 0x04 0xff 0xff 0x8f 0x80
+ 0x00 0x08 0xff 0xff 0x9d 0x90 0x01 0x0c 0xff 0xff 0x9d 0x90 0x01
+ 0x10 0xff 0xff 0x9d 0x90 0x01 0x14 0x4c 0x4d 0x54 0x00 0x4d 0x53
+ 0x54 0x00 0x50 0x53 0x54 0x00 0x50 0x44 0x54 0x00 0x50 0x57 0x54
+ 0x00 0x50 0x50 0x54 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x00 0x00
+ 0x00 0x00 0x00 0x01 0x0a 0x50 0x53 0x54 0x38 0x50 0x44 0x54 0x2c
+ 0x4d 0x34 0x2e 0x31 0x2e 0x30 0x2c 0x4d 0x31 0x30 0x2e 0x35 0x2e
+ 0x30 0x0a
+ }]
+ close $f
+ set ::tcl::clock::ZoneinfoPaths \
+ [linsert $::tcl::clock::ZoneinfoPaths 0 $tzdir]
+ ::tcl::clock::ClearCaches
+ }
+ -cleanup {
+ set ::tcl::clock::ZoneinfoPaths \
+ [lrange $::tcl::clock::ZoneinfoPaths 1 end]
+ ::tcl::clock::ClearCaches
+ removeFile TijuanaTwo $tzdir2
+ removeDirectory Test $tzdir
+ removeDirectory zoneinfo
+ }
+ -body {
+ clock format 2224738800 -timezone :Test/TijuanaTwo \
+ -format {%Y-%m-%d %H:%M:%S %Z}
+ }
+ -result {2040-07-01 00:00:00 PDT}
+}
+
+test clock-56.4 {Bug 3470928} {*}{
+ -setup {
+ clock format [clock seconds]
+ set tzdir [makeDirectory zoneinfo]
+ set tzdir2 [makeDirectory Test $tzdir]
+ set tzfile [makeFile {} Windhoek $tzdir2]
+ set f [open $tzfile wb]
+ puts -nonewline $f [binary format c* {
+ 0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x06 0x00 0x00
+ 0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x5c 0x00 0x00 0x00
+ 0x06 0x00 0x00 0x00 0x13 0x82 0x46 0xcf 0x68 0xcc 0xae 0x8c 0x80
+ 0xcd 0x9e 0x6f 0x70 0x26 0x06 0xa7 0xe0 0x2d 0x9d 0xea 0xe0 0x2e
+ 0x69 0x1c 0x10 0x2f 0x7d 0xe9 0x00 0x30 0x48 0xfe 0x10 0x31 0x67
+ 0x05 0x80 0x32 0x28 0xe0 0x10 0x33 0x46 0xe7 0x80 0x34 0x11 0xfc
+ 0x90 0x35 0x26 0xc9 0x80 0x35 0xf1 0xde 0x90 0x37 0x06 0xab 0x80
+ 0x37 0xd1 0xc0 0x90 0x38 0xe6 0x8d 0x80 0x39 0xb1 0xa2 0x90 0x3a
+ 0xc6 0x6f 0x80 0x3b 0x91 0x84 0x90 0x3c 0xaf 0x8c 0x00 0x3d 0x71
+ 0x66 0x90 0x3e 0x8f 0x6e 0x00 0x3f 0x5a 0x83 0x10 0x40 0x6f 0x50
+ 0x00 0x41 0x3a 0x65 0x10 0x42 0x4f 0x32 0x00 0x43 0x1a 0x47 0x10
+ 0x44 0x2f 0x14 0x00 0x44 0xfa 0x29 0x10 0x46 0x0e 0xf6 0x00 0x46
+ 0xda 0x0b 0x10 0x47 0xf8 0x12 0x80 0x48 0xc3 0x27 0x90 0x49 0xd7
+ 0xf4 0x80 0x4a 0xa3 0x09 0x90 0x4b 0xb7 0xd6 0x80 0x4c 0x82 0xeb
+ 0x90 0x4d 0x97 0xb8 0x80 0x4e 0x62 0xcd 0x90 0x4f 0x77 0x9a 0x80
+ 0x50 0x42 0xaf 0x90 0x51 0x60 0xb7 0x00 0x52 0x22 0x91 0x90 0x53
+ 0x40 0x99 0x00 0x54 0x0b 0xae 0x10 0x55 0x20 0x7b 0x00 0x55 0xeb
+ 0x90 0x10 0x57 0x00 0x5d 0x00 0x57 0xcb 0x72 0x10 0x58 0xe0 0x3f
+ 0x00 0x59 0xab 0x54 0x10 0x5a 0xc0 0x21 0x00 0x5b 0x8b 0x36 0x10
+ 0x5c 0xa9 0x3d 0x80 0x5d 0x6b 0x18 0x10 0x5e 0x89 0x1f 0x80 0x5f
+ 0x54 0x34 0x90 0x60 0x69 0x01 0x80 0x61 0x34 0x16 0x90 0x62 0x48
+ 0xe3 0x80 0x63 0x13 0xf8 0x90 0x64 0x28 0xc5 0x80 0x64 0xf3 0xda
+ 0x90 0x66 0x11 0xe2 0x00 0x66 0xd3 0xbc 0x90 0x67 0xf1 0xc4 0x00
+ 0x68 0xbc 0xd9 0x10 0x69 0xd1 0xa6 0x00 0x6a 0x9c 0xbb 0x10 0x6b
+ 0xb1 0x88 0x00 0x6c 0x7c 0x9d 0x10 0x6d 0x91 0x6a 0x00 0x6e 0x5c
+ 0x7f 0x10 0x6f 0x71 0x4c 0x00 0x70 0x3c 0x61 0x10 0x71 0x5a 0x68
+ 0x80 0x72 0x1c 0x43 0x10 0x73 0x3a 0x4a 0x80 0x74 0x05 0x5f 0x90
+ 0x75 0x1a 0x2c 0x80 0x75 0xe5 0x41 0x90 0x76 0xfa 0x0e 0x80 0x77
+ 0xc5 0x23 0x90 0x78 0xd9 0xf0 0x80 0x79 0xa5 0x05 0x90 0x7a 0xb9
+ 0xd2 0x80 0x7b 0x84 0xe7 0x90 0x7c 0xa2 0xef 0x00 0x7d 0x6e 0x04
+ 0x10 0x7e 0x82 0xd1 0x00 0x7f 0x4d 0xe6 0x10 0x01 0x02 0x01 0x03
+ 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
+ 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
+ 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
+ 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
+ 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
+ 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
+ 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x00 0x00 0x15
+ 0x18 0x00 0x00 0x00 0x00 0x1c 0x20 0x00 0x05 0x00 0x00 0x2a 0x30
+ 0x01 0x05 0x00 0x00 0x1c 0x20 0x00 0x0a 0x00 0x00 0x1c 0x20 0x01
+ 0x0e 0x00 0x00 0x0e 0x10 0x00 0x01 0x53 0x57 0x41 0x54 0x00 0x53
+ 0x41 0x53 0x54 0x00 0x43 0x41 0x54 0x00 0x57 0x41 0x53 0x54 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x54
+ 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x07 0x00 0x00 0x00
+ 0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x5d 0x00 0x00 0x00 0x07
+ 0x00 0x00 0x00 0x17 0xff 0xff 0xff 0xff 0x6d 0x7b 0x4b 0x78 0xff
+ 0xff 0xff 0xff 0x82 0x46 0xcf 0x68 0xff 0xff 0xff 0xff 0xcc 0xae
+ 0x8c 0x80 0xff 0xff 0xff 0xff 0xcd 0x9e 0x6f 0x70 0x00 0x00 0x00
+ 0x00 0x26 0x06 0xa7 0xe0 0x00 0x00 0x00 0x00 0x2d 0x9d 0xea 0xe0
+ 0x00 0x00 0x00 0x00 0x2e 0x69 0x1c 0x10 0x00 0x00 0x00 0x00 0x2f
+ 0x7d 0xe9 0x00 0x00 0x00 0x00 0x00 0x30 0x48 0xfe 0x10 0x00 0x00
+ 0x00 0x00 0x31 0x67 0x05 0x80 0x00 0x00 0x00 0x00 0x32 0x28 0xe0
+ 0x10 0x00 0x00 0x00 0x00 0x33 0x46 0xe7 0x80 0x00 0x00 0x00 0x00
+ 0x34 0x11 0xfc 0x90 0x00 0x00 0x00 0x00 0x35 0x26 0xc9 0x80 0x00
+ 0x00 0x00 0x00 0x35 0xf1 0xde 0x90 0x00 0x00 0x00 0x00 0x37 0x06
+ 0xab 0x80 0x00 0x00 0x00 0x00 0x37 0xd1 0xc0 0x90 0x00 0x00 0x00
+ 0x00 0x38 0xe6 0x8d 0x80 0x00 0x00 0x00 0x00 0x39 0xb1 0xa2 0x90
+ 0x00 0x00 0x00 0x00 0x3a 0xc6 0x6f 0x80 0x00 0x00 0x00 0x00 0x3b
+ 0x91 0x84 0x90 0x00 0x00 0x00 0x00 0x3c 0xaf 0x8c 0x00 0x00 0x00
+ 0x00 0x00 0x3d 0x71 0x66 0x90 0x00 0x00 0x00 0x00 0x3e 0x8f 0x6e
+ 0x00 0x00 0x00 0x00 0x00 0x3f 0x5a 0x83 0x10 0x00 0x00 0x00 0x00
+ 0x40 0x6f 0x50 0x00 0x00 0x00 0x00 0x00 0x41 0x3a 0x65 0x10 0x00
+ 0x00 0x00 0x00 0x42 0x4f 0x32 0x00 0x00 0x00 0x00 0x00 0x43 0x1a
+ 0x47 0x10 0x00 0x00 0x00 0x00 0x44 0x2f 0x14 0x00 0x00 0x00 0x00
+ 0x00 0x44 0xfa 0x29 0x10 0x00 0x00 0x00 0x00 0x46 0x0e 0xf6 0x00
+ 0x00 0x00 0x00 0x00 0x46 0xda 0x0b 0x10 0x00 0x00 0x00 0x00 0x47
+ 0xf8 0x12 0x80 0x00 0x00 0x00 0x00 0x48 0xc3 0x27 0x90 0x00 0x00
+ 0x00 0x00 0x49 0xd7 0xf4 0x80 0x00 0x00 0x00 0x00 0x4a 0xa3 0x09
+ 0x90 0x00 0x00 0x00 0x00 0x4b 0xb7 0xd6 0x80 0x00 0x00 0x00 0x00
+ 0x4c 0x82 0xeb 0x90 0x00 0x00 0x00 0x00 0x4d 0x97 0xb8 0x80 0x00
+ 0x00 0x00 0x00 0x4e 0x62 0xcd 0x90 0x00 0x00 0x00 0x00 0x4f 0x77
+ 0x9a 0x80 0x00 0x00 0x00 0x00 0x50 0x42 0xaf 0x90 0x00 0x00 0x00
+ 0x00 0x51 0x60 0xb7 0x00 0x00 0x00 0x00 0x00 0x52 0x22 0x91 0x90
+ 0x00 0x00 0x00 0x00 0x53 0x40 0x99 0x00 0x00 0x00 0x00 0x00 0x54
+ 0x0b 0xae 0x10 0x00 0x00 0x00 0x00 0x55 0x20 0x7b 0x00 0x00 0x00
+ 0x00 0x00 0x55 0xeb 0x90 0x10 0x00 0x00 0x00 0x00 0x57 0x00 0x5d
+ 0x00 0x00 0x00 0x00 0x00 0x57 0xcb 0x72 0x10 0x00 0x00 0x00 0x00
+ 0x58 0xe0 0x3f 0x00 0x00 0x00 0x00 0x00 0x59 0xab 0x54 0x10 0x00
+ 0x00 0x00 0x00 0x5a 0xc0 0x21 0x00 0x00 0x00 0x00 0x00 0x5b 0x8b
+ 0x36 0x10 0x00 0x00 0x00 0x00 0x5c 0xa9 0x3d 0x80 0x00 0x00 0x00
+ 0x00 0x5d 0x6b 0x18 0x10 0x00 0x00 0x00 0x00 0x5e 0x89 0x1f 0x80
+ 0x00 0x00 0x00 0x00 0x5f 0x54 0x34 0x90 0x00 0x00 0x00 0x00 0x60
+ 0x69 0x01 0x80 0x00 0x00 0x00 0x00 0x61 0x34 0x16 0x90 0x00 0x00
+ 0x00 0x00 0x62 0x48 0xe3 0x80 0x00 0x00 0x00 0x00 0x63 0x13 0xf8
+ 0x90 0x00 0x00 0x00 0x00 0x64 0x28 0xc5 0x80 0x00 0x00 0x00 0x00
+ 0x64 0xf3 0xda 0x90 0x00 0x00 0x00 0x00 0x66 0x11 0xe2 0x00 0x00
+ 0x00 0x00 0x00 0x66 0xd3 0xbc 0x90 0x00 0x00 0x00 0x00 0x67 0xf1
+ 0xc4 0x00 0x00 0x00 0x00 0x00 0x68 0xbc 0xd9 0x10 0x00 0x00 0x00
+ 0x00 0x69 0xd1 0xa6 0x00 0x00 0x00 0x00 0x00 0x6a 0x9c 0xbb 0x10
+ 0x00 0x00 0x00 0x00 0x6b 0xb1 0x88 0x00 0x00 0x00 0x00 0x00 0x6c
+ 0x7c 0x9d 0x10 0x00 0x00 0x00 0x00 0x6d 0x91 0x6a 0x00 0x00 0x00
+ 0x00 0x00 0x6e 0x5c 0x7f 0x10 0x00 0x00 0x00 0x00 0x6f 0x71 0x4c
+ 0x00 0x00 0x00 0x00 0x00 0x70 0x3c 0x61 0x10 0x00 0x00 0x00 0x00
+ 0x71 0x5a 0x68 0x80 0x00 0x00 0x00 0x00 0x72 0x1c 0x43 0x10 0x00
+ 0x00 0x00 0x00 0x73 0x3a 0x4a 0x80 0x00 0x00 0x00 0x00 0x74 0x05
+ 0x5f 0x90 0x00 0x00 0x00 0x00 0x75 0x1a 0x2c 0x80 0x00 0x00 0x00
+ 0x00 0x75 0xe5 0x41 0x90 0x00 0x00 0x00 0x00 0x76 0xfa 0x0e 0x80
+ 0x00 0x00 0x00 0x00 0x77 0xc5 0x23 0x90 0x00 0x00 0x00 0x00 0x78
+ 0xd9 0xf0 0x80 0x00 0x00 0x00 0x00 0x79 0xa5 0x05 0x90 0x00 0x00
+ 0x00 0x00 0x7a 0xb9 0xd2 0x80 0x00 0x00 0x00 0x00 0x7b 0x84 0xe7
+ 0x90 0x00 0x00 0x00 0x00 0x7c 0xa2 0xef 0x00 0x00 0x00 0x00 0x00
+ 0x7d 0x6e 0x04 0x10 0x00 0x00 0x00 0x00 0x7e 0x82 0xd1 0x00 0x00
+ 0x00 0x00 0x00 0x7f 0x4d 0xe6 0x10 0x01 0x02 0x03 0x02 0x04 0x06
+ 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
+ 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
+ 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
+ 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
+ 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
+ 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
+ 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x00 0x00 0x10 0x08
+ 0x00 0x00 0x00 0x00 0x15 0x18 0x00 0x04 0x00 0x00 0x1c 0x20 0x00
+ 0x09 0x00 0x00 0x2a 0x30 0x01 0x09 0x00 0x00 0x1c 0x20 0x00 0x0e
+ 0x00 0x00 0x1c 0x20 0x01 0x12 0x00 0x00 0x0e 0x10 0x00 0x05 0x4c
+ 0x4d 0x54 0x00 0x53 0x57 0x41 0x54 0x00 0x53 0x41 0x53 0x54 0x00
+ 0x43 0x41 0x54 0x00 0x57 0x41 0x53 0x54 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0a 0x57 0x41
+ 0x54 0x2d 0x31 0x57 0x41 0x53 0x54 0x2c 0x4d 0x39 0x2e 0x31 0x2e
+ 0x30 0x2c 0x4d 0x34 0x2e 0x31 0x2e 0x30 0x0a
+ }]
+ close $f
+ set ::tcl::clock::ZoneinfoPaths \
+ [linsert $::tcl::clock::ZoneinfoPaths 0 $tzdir]
+ ::tcl::clock::ClearCaches
+ }
+ -body {
+ clock format 1326054606 -timezone :Test/Windhoek
+ }
+ -cleanup {
+ set ::tcl::clock::ZoneinfoPaths \
+ [lrange $::tcl::clock::ZoneinfoPaths 1 end]
+ ::tcl::clock::ClearCaches
+ removeFile Windhoek $tzdir2
+ removeDirectory Test $tzdir
+ removeDirectory zoneinfo
+ }
+ -result {Sun Jan 08 22:30:06 WAST 2012}
+}
+
+test clock-57.1 {clock scan - abbreviated options} {
+ clock scan 1970-01-01 -f %Y-%m-%d -g true
+} 0
+
+test clock-58.1 {clock l10n - Japanese localisation} {*}{
+ -setup {
+ proc backslashify { string } {
+
+ set retval {}
+ foreach char [split $string {}] {
+ scan $char %c ccode
+ if { $ccode >= 0x0020 && $ccode < 0x007f
+ && $char ne "\{" && $char ne "\}" && $char ne "\["
+ && $char ne "\]" && $char ne "\\" && $char ne "\$" } {
+ append retval $char
+ } else {
+ append retval \\u [format %04x $ccode]
+ }
+ }
+ return $retval
+ }
+ }
+ -body {
+ set trouble {}
+ foreach {date jdate} [list \
+ 1872-12-31 \u897f\u66a61872\u5e7412\u670831\u65e5 \
+ 1873-01-01 \u660e\u6cbb06\u5e7401\u670801\u65e5 \
+ 1912-07-29 \u660e\u6cbb45\u5e7407\u670829\u65e5 \
+ 1912-07-30 \u5927\u6b6301\u5e7407\u670830\u65e5 \
+ 1926-12-24 \u5927\u6b6315\u5e7412\u670824\u65e5 \
+ 1926-12-25 \u662d\u548c01\u5e7412\u670825\u65e5 \
+ 1989-01-07 \u662d\u548c64\u5e7401\u670807\u65e5 \
+ 1989-01-08 \u5e73\u621001\u5e7401\u670808\u65e5 \
+ ] {
+ set status [catch {
+ set secs [clock scan $date \
+ -timezone +0900 \
+ -locale ja_JP \
+ -format %Y-%m-%d]
+ set jda [clock format $secs \
+ -timezone +0900 \
+ -locale ja_JP \
+ -format %Ex]
+ } result]
+ if {$status != 0} {
+ append trouble \n $date " gives error " $result
+ } elseif {$jda ne $jdate} {
+ append trouble \n $date " converts to " \
+ [backslashify $jda] " and should be " \
+ [backslashify $jdate]
+ }
+ # There is no code for scanning dates on the locale's
+ # alternative calendar.
+ continue
+ set status [catch {
+ set secs [clock scan $jdate \
+ -timezone +0900 \
+ -locale ja_JP \
+ -format %Ex]
+ set da [clock format $secs \
+ -timezone +0900 \
+ -locale ja_JP \
+ -format %Y-%m-%d]
+ } result]
+ if {$status != 0} {
+ append trouble \n [backslashify $jdate] " gives error " $result
+ } elseif {$da ne $date} {
+ append trouble \n [backslashify $jdate] " converts to " \
+ $da " and should be " $date
+ }
+ }
+ set trouble
+ }
+ -cleanup {
+ rename backslashify {}
+ }
+ -result {}
+}
+
+test clock-59.1 {military time zones} {
+ set hour 0
+ set base [clock scan "20000101 000000" -format "%Y%m%d %H%M%S" -gmt 1]
+ set trouble {}
+ foreach {pzone mzone} {
+ Z Z A N B O C P D Q E R F S G T H U I V K W L X M Y
+ } {
+ catch {clock scan "20000101 000000 $pzone" \
+ -format "%Y%m%d %H%M%S %Z"} ps1
+ catch {clock scan "20000101 000000 $pzone"} ps2
+ catch {clock scan "20000101 000000 $mzone" \
+ -format "%Y%m%d %H%M%S %Z"} ms1
+ catch {clock scan "20000101 000000 $mzone"} ms2
+ if {$ps1 != $base - 3600 * $hour} {
+ lappend trouble [list pzone $pzone hour $hour ps1 is $ps1]
+ }
+ if {$ps2 != $base - 3600 * $hour} {
+ lappend trouble [list pzone $pzone ps2 is $ps2]
+ }
+ if {$ms1 != $base + 3600 * $hour} {
+ lappend trouble [list mzone $mzone ms1 is $ms1]
+ }
+ if {$ms2 != $base + 3600 * $hour} {
+ lappend trouble [list mzone $mzone ms2 is $ms2]
+ }
+ incr hour
+ }
+ join $trouble \n
+} {}
+
+# case-insensitive matching of weekday and month names [Bug 1781282]
+
+test clock-60.1 {case insensitive weekday names} {
+ clock scan "2000-W01 monday" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-1" -gmt true -format "%G-W%V-%u"]
+test clock-60.2 {case insensitive weekday names} {
+ clock scan "2000-W01 Monday" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-1" -gmt true -format "%G-W%V-%u"]
+test clock-60.3 {case insensitive weekday names} {
+ clock scan "2000-W01 MONDAY" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-1" -gmt true -format "%G-W%V-%u"]
+test clock-60.4 {case insensitive weekday names} {
+ clock scan "2000-W01 friday" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-5" -gmt true -format "%G-W%V-%u"]
+test clock-60.5 {case insensitive weekday names} {
+ clock scan "2000-W01 Friday" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-5" -gmt true -format "%G-W%V-%u"]
+test clock-60.6 {case insensitive weekday names} {
+ clock scan "2000-W01 FRIDAY" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-5" -gmt true -format "%G-W%V-%u"]
+test clock-60.7 {case insensitive month names} {
+ clock scan "1 january 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-01-01" -gmt true -format "%Y-%m-%d"]
+test clock-60.8 {case insensitive month names} {
+ clock scan "1 January 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-01-01" -gmt true -format "%Y-%m-%d"]
+test clock-60.9 {case insensitive month names} {
+ clock scan "1 JANUARY 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-01-01" -gmt true -format "%Y-%m-%d"]
+test clock-60.10 {case insensitive month names} {
+ clock scan "1 december 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-12-01" -gmt true -format "%Y-%m-%d"]
+test clock-60.11 {case insensitive month names} {
+ clock scan "1 December 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-12-01" -gmt true -format "%Y-%m-%d"]
+test clock-60.12 {case insensitive month names} {
+ clock scan "1 DECEMBER 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-12-01" -gmt true -format "%Y-%m-%d"]
+
+test clock-61.1 {overflow of a wide integer on output} {*}{
+ -body {
+ clock format 0x8000000000000000 -format %s -gmt true
+ }
+ -result {integer value too large to represent}
+ -returnCodes error
+}
+test clock-61.2 {overflow of a wide integer on output} {*}{
+ -body {
+ clock format -0x8000000000000001 -format %s -gmt true
+ }
+ -result {integer value too large to represent}
+ -returnCodes error
+}
+test clock-61.3 {near-miss overflow of a wide integer on output} {
+ clock format 0x7fffffffffffffff -format %s -gmt true
+} [expr 0x7fffffffffffffff]
+test clock-61.4 {near-miss overflow of a wide integer on output} {
+ clock format -0x8000000000000000 -format %s -gmt true
+} [expr -0x8000000000000000]
+
+test clock-62.1 {Bug 1902423} {*}{
+ -setup {::tcl::clock::ClearCaches}
+ -body {
+ set s 1204049747
+ set f1 [clock format $s -format {%Y-%m-%d %T} -locale C]
+ set f2 [clock format $s -format {%Y-%m-%d %H:%M:%S} -locale C]
+ if {$f1 ne $f2} {
+ subst "$f2 is not $f1"
+ } else {
+ subst "ok"
+ }
+ }
+ -result ok
+}
+
+test clock-63.1 {Incorrect use of internal ConvertLocalToUTC command} {*}{
+ -body {
+ ::tcl::clock::ConvertLocalToUTC {immaterial stuff} {} 12345
+ }
+ -returnCodes error
+ -result {key "localseconds" not found in dictionary}
+}
+
+test clock-64.1 {:: in format string [Bug 2362156]} {*}{
+ -body {
+ clock scan 2001-02-03::04:05:06 -gmt 1 -format %Y-%m-%d::%H:%M:%S
+ }
+ -result 981173106
+}
+test clock-64.2 {:: in format string [Bug 2362156]} {*}{
+ -body {
+ clock format 981173106 -gmt 1 -format %Y-%m-%d::%H:%M:%S
+ }
+ -result 2001-02-03::04:05:06
+}
+
+test clock-65.1 {clock add, bad option [Bug 2481670]} {*}{
+ -body {
+ clock add 0 1 year -foo bar
+ }
+ -match glob
+ -returnCodes error
+ -result {bad switch "-foo"*}
+}
+
+test clock-66.1 {clock scan, no date, never-before-seen timezone} {*}{
+ -setup {
+ ::tcl::clock::ClearCaches
+ }
+ -body {
+ clock scan 1200 \
+ -timezone {<EST>+05:00:00<EDT>+04:00:00,M3.2.0/02:00:00,M11.1.0/02:00:00} \
+ -base 1256529600 \
+ -format %H%M
+ }
+ -result 1256572800
+}
+
+test clock-67.1 {clock format, %% with a letter following [Bug 2819334]} {
+ clock format [clock seconds] -format %%r
+} %r
+
+# cleanup
+
+namespace delete ::testClock
+::tcl::clock::ClearCaches
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/cmdAH.test b/library/msgcat/tests/cmdAH.test
new file mode 100644
index 0000000..291df8d
--- /dev/null
+++ b/library/msgcat/tests/cmdAH.test
@@ -0,0 +1,1578 @@
+# The file tests the tclCmdAH.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1996-1998 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2.1
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testchmod [llength [info commands testchmod]]
+testConstraint testsetplatform [llength [info commands testsetplatform]]
+testConstraint testvolumetype [llength [info commands testvolumetype]]
+testConstraint linkDirectory [expr {
+ ![testConstraint win] ||
+ ([string index $tcl_platform(osVersion) 0] >= 5
+ && [lindex [file system [temporaryDirectory]] 1] eq "NTFS")
+}]
+
+global env
+set cmdAHwd [pwd]
+catch {set platform [testgetplatform]}
+
+proc waitForEvenSecondForFAT {} {
+ # Windows 9x uses filesystems (the FAT* family of FSes) without enough
+ # data in its timestamps for even per-second-accurate timings. :^(
+ # This procedure based on work by Helmut Giese
+ if {
+ [testConstraint win] &&
+ [lindex [file system [temporaryDirectory]] 1] ne "NTFS"
+ } then {
+ # Assume non-NTFS means FAT{12,16,32} and hence in need of special
+ # help...
+ set start [clock seconds]
+ while {1} {
+ set now [clock seconds]
+ if {$now!=$start && !($now & 1)} {
+ break
+ }
+ after 50
+ }
+ }
+}
+
+test cmdAH-0.1 {Tcl_BreakObjCmd, errors} -body {
+ break foo
+} -returnCodes error -result {wrong # args: should be "break"}
+test cmdAH-0.2 {Tcl_BreakObjCmd, success} {
+ list [catch {break} msg] $msg
+} {3 {}}
+
+# Tcl_CaseObjCmd is tested in case.test
+
+test cmdAH-1.1 {Tcl_CatchObjCmd, errors} -returnCodes error -body {
+ catch
+} -result {wrong # args: should be "catch script ?resultVarName? ?optionVarName?"}
+test cmdAH-1.2 {Tcl_CatchObjCmd, errors} {
+ list [catch {catch foo bar baz} msg] $msg
+} {0 1}
+test cmdAH-1.3 {Tcl_CatchObjCmd, errors} -returnCodes error -body {
+ catch foo bar baz spaz
+} -result {wrong # args: should be "catch script ?resultVarName? ?optionVarName?"}
+
+test cmdAH-2.1 {Tcl_CdObjCmd} -returnCodes error -body {
+ cd foo bar
+} -result {wrong # args: should be "cd ?dirName?"}
+set foodir [file join [temporaryDirectory] foo]
+test cmdAH-2.2 {Tcl_CdObjCmd} -setup {
+ file delete -force $foodir
+ set oldpwd [pwd]
+} -body {
+ file mkdir $foodir
+ cd $foodir
+ file tail [pwd]
+} -cleanup {
+ cd $oldpwd
+ file delete $foodir
+} -result foo
+test cmdAH-2.3 {Tcl_CdObjCmd} -setup {
+ global env
+ set oldpwd [pwd]
+ set temp $env(HOME)
+ file delete -force $foodir
+} -body {
+ set env(HOME) $oldpwd
+ file mkdir $foodir
+ cd $foodir
+ cd ~
+ string equal [pwd] $oldpwd
+} -cleanup {
+ cd $oldpwd
+ file delete $foodir
+ set env(HOME) $temp
+} -result 1
+test cmdAH-2.4 {Tcl_CdObjCmd} -setup {
+ global env
+ set oldpwd [pwd]
+ set temp $env(HOME)
+ file delete -force $foodir
+} -body {
+ set env(HOME) $oldpwd
+ file mkdir $foodir
+ cd $foodir
+ cd
+ string equal [pwd] $oldpwd
+} -cleanup {
+ cd $oldpwd
+ file delete $foodir
+ set env(HOME) $temp
+} -result 1
+test cmdAH-2.5 {Tcl_CdObjCmd} -returnCodes error -body {
+ cd ~~
+} -result {user "~" doesn't exist}
+test cmdAH-2.6 {Tcl_CdObjCmd} -returnCodes error -body {
+ cd _foobar
+} -result {couldn't change working directory to "_foobar": no such file or directory}
+test cmdAH-2.6.1 {Tcl_CdObjCmd} -returnCodes error -body {
+ cd ""
+} -result {couldn't change working directory to "": no such file or directory}
+test cmdAH-2.6.2 {cd} -constraints {unix nonPortable} -setup {
+ set dir [pwd]
+} -body {
+ cd /
+ pwd
+} -cleanup {
+ cd $dir
+} -result {/}
+test cmdAH-2.7 {Tcl_ConcatObjCmd} {
+ concat
+} {}
+test cmdAH-2.8 {Tcl_ConcatObjCmd} {
+ concat a
+} a
+test cmdAH-2.9 {Tcl_ConcatObjCmd} {
+ concat a {b c}
+} {a b c}
+
+test cmdAH-3.1 {Tcl_ContinueObjCmd, errors} -returnCodes error -body {
+ continue foo
+} -result {wrong # args: should be "continue"}
+test cmdAH-3.2 {Tcl_ContinueObjCmd, success} {
+ list [catch {continue} msg] $msg
+} {4 {}}
+
+test cmdAH-4.1 {Tcl_EncodingObjCmd} -returnCodes error -body {
+ encoding
+} -result {wrong # args: should be "encoding option ?arg ...?"}
+test cmdAH-4.2 {Tcl_EncodingObjCmd} -returnCodes error -body {
+ encoding foo
+} -result {bad option "foo": must be convertfrom, convertto, dirs, names, or system}
+test cmdAH-4.3 {Tcl_EncodingObjCmd} -returnCodes error -body {
+ encoding convertto
+} -result {wrong # args: should be "encoding convertto ?encoding? data"}
+test cmdAH-4.4 {Tcl_EncodingObjCmd} -returnCodes error -body {
+ encoding convertto foo bar
+} -result {unknown encoding "foo"}
+test cmdAH-4.5 {Tcl_EncodingObjCmd} -setup {
+ set system [encoding system]
+} -body {
+ encoding system jis0208
+ encoding convertto \u4e4e
+} -cleanup {
+ encoding system $system
+} -result 8C
+test cmdAH-4.6 {Tcl_EncodingObjCmd} -setup {
+ set system [encoding system]
+} -body {
+ encoding system identity
+ encoding convertto jis0208 \u4e4e
+} -cleanup {
+ encoding system $system
+} -result 8C
+test cmdAH-4.7 {Tcl_EncodingObjCmd} -returnCodes error -body {
+ encoding convertfrom
+} -result {wrong # args: should be "encoding convertfrom ?encoding? data"}
+test cmdAH-4.8 {Tcl_EncodingObjCmd} -returnCodes error -body {
+ encoding convertfrom foo bar
+} -result {unknown encoding "foo"}
+test cmdAH-4.9 {Tcl_EncodingObjCmd} -setup {
+ set system [encoding system]
+} -body {
+ encoding system jis0208
+ encoding convertfrom 8C
+} -cleanup {
+ encoding system $system
+} -result \u4e4e
+test cmdAH-4.10 {Tcl_EncodingObjCmd} -setup {
+ set system [encoding system]
+} -body {
+ encoding system identity
+ encoding convertfrom jis0208 8C
+} -cleanup {
+ encoding system $system
+} -result \u4e4e
+test cmdAH-4.11 {Tcl_EncodingObjCmd} -returnCodes error -body {
+ encoding names foo
+} -result {wrong # args: should be "encoding names"}
+test cmdAH-4.12 {Tcl_EncodingObjCmd} -returnCodes error -body {
+ encoding system foo bar
+} -result {wrong # args: should be "encoding system ?encoding?"}
+test cmdAH-4.13 {Tcl_EncodingObjCmd} -setup {
+ set system [encoding system]
+} -body {
+ encoding system identity
+ encoding system
+} -cleanup {
+ encoding system $system
+} -result identity
+
+test cmdAH-5.1 {Tcl_FileObjCmd} -returnCodes error -body {
+ file
+} -result {wrong # args: should be "file subcommand ?arg ...?"}
+test cmdAH-5.2 {Tcl_FileObjCmd} -returnCodes error -body {
+ file x
+} -result {unknown or ambiguous subcommand "x": must be atime, attributes, channels, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, link, lstat, mkdir, mtime, nativename, normalize, owned, pathtype, readable, readlink, rename, rootname, separator, size, split, stat, system, tail, tempfile, type, volumes, or writable}
+test cmdAH-5.3 {Tcl_FileObjCmd} -returnCodes error -body {
+ file exists
+} -result {wrong # args: should be "file exists name"}
+test cmdAH-5.4 {Tcl_FileObjCmd} {
+ file exists ""
+} 0
+
+# volume
+test cmdAH-6.1 {Tcl_FileObjCmd: volumes} -returnCodes error -body {
+ file volumes x
+} -result {wrong # args: should be "file volumes"}
+test cmdAH-6.2 {Tcl_FileObjCmd: volumes} -body {
+ lindex [file volumes] 0
+} -match glob -result ?*
+test cmdAH-6.3 {Tcl_FileObjCmd: volumes} -constraints unix -body {
+ set volumeList [file volumes]
+ glob -nocomplain [lindex $volumeList 0]*
+} -match glob -result *
+test cmdAH-6.4 {Tcl_FileObjCmd: volumes} -constraints win -body {
+ set volumeList [string tolower [file volumes]]
+ set element [lsearch -exact $volumeList "c:/"]
+ list [expr {$element>-1}] [glob -nocomplain [lindex $volumeList $element]*]
+} -match glob -result {1 *}
+
+# attributes
+test cmdAH-7.1 {Tcl_FileObjCmd - file attrs} -setup {
+ set foofile [makeFile abcde foo.file]
+ catch {file delete -force $foofile}
+} -body {
+ close [open $foofile w]
+ file attributes $foofile
+} -cleanup {
+ # We used [makeFile] so we undo with [removeFile]
+ removeFile $foofile
+} -match glob -result *
+
+# dirname
+test cmdAH-8.1 {Tcl_FileObjCmd: dirname} -returnCodes error -body {
+ file dirname a b
+} -result {wrong # args: should be "file dirname name"}
+test cmdAH-8.2 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname /a/b
+} /a
+test cmdAH-8.3 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname {}
+} .
+test cmdAH-8.5 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform win
+ file dirname {}
+} .
+test cmdAH-8.6 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname .def
+} .
+test cmdAH-8.8 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform win
+ file dirname a
+} .
+test cmdAH-8.9 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname a/b/c.d
+} a/b
+test cmdAH-8.10 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname a/b.c/d
+} a/b.c
+test cmdAH-8.11 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname /.
+} /
+test cmdAH-8.12 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname /
+} /
+test cmdAH-8.13 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname /foo
+} /
+test cmdAH-8.14 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname //foo
+} /
+test cmdAH-8.15 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname //foo/bar
+} /foo
+test cmdAH-8.16 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname {//foo\/bar/baz}
+} {/foo\/bar}
+test cmdAH-8.17 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname {//foo\/bar/baz/blat}
+} {/foo\/bar/baz}
+test cmdAH-8.18 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname /foo//
+} /
+test cmdAH-8.19 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname ./a
+} .
+test cmdAH-8.20 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname a/.a
+} a
+test cmdAH-8.21 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform windows
+ file dirname c:foo
+} c:
+test cmdAH-8.22 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform windows
+ file dirname c:
+} c:
+test cmdAH-8.23 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform windows
+ file dirname c:/
+} c:/
+test cmdAH-8.24 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform windows
+ file dirname {c:\foo}
+} c:/
+test cmdAH-8.25 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform windows
+ file dirname {//foo/bar/baz}
+} //foo/bar
+test cmdAH-8.26 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform windows
+ file dirname {//foo/bar}
+} //foo/bar
+test cmdAH-8.38 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname ~/foo
+} ~
+test cmdAH-8.39 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname ~bar/foo
+} ~bar
+test cmdAH-8.43 {Tcl_FileObjCmd: dirname} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints testsetplatform -body {
+ set env(HOME) "/homewontexist/test"
+ testsetplatform unix
+ file dirname ~
+} -cleanup {
+ set env(HOME) $temp
+} -result /homewontexist
+test cmdAH-8.44 {Tcl_FileObjCmd: dirname} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints testsetplatform -body {
+ set env(HOME) "~"
+ testsetplatform unix
+ file dirname ~
+} -cleanup {
+ set env(HOME) $temp
+} -result ~
+test cmdAH-8.45 {Tcl_FileObjCmd: dirname} -setup {
+ set temp $::env(HOME)
+} -constraints {win testsetplatform} -match regexp -body {
+ set ::env(HOME) "/homewontexist/test"
+ testsetplatform windows
+ file dirname ~
+} -cleanup {
+ set ::env(HOME) $temp
+} -result {([a-zA-Z]:?)/homewontexist}
+test cmdAH-8.46 {Tcl_FileObjCmd: dirname} {
+ set f [file normalize [info nameof]]
+ file exists $f
+ set res1 [file dirname [file join $f foo/bar]]
+ set res2 [file dirname "${f}/foo/bar"]
+ if {$res1 eq $res2} {
+ return "ok"
+ }
+ return "file dirname problem, $res1, $res2 not equal"
+} {ok}
+
+# tail
+test cmdAH-9.1 {Tcl_FileObjCmd: tail} -returnCodes error -body {
+ file tail a b
+} -result {wrong # args: should be "file tail name"}
+test cmdAH-9.2 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail /a/b
+} b
+test cmdAH-9.3 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail {}
+} {}
+test cmdAH-9.5 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform win
+ file tail {}
+} {}
+test cmdAH-9.6 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail .def
+} .def
+test cmdAH-9.8 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform win
+ file tail a
+} a
+test cmdAH-9.9 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file ta a/b/c.d
+} c.d
+test cmdAH-9.10 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail a/b.c/d
+} d
+test cmdAH-9.11 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail /.
+} .
+test cmdAH-9.12 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail /
+} {}
+test cmdAH-9.13 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail /foo
+} foo
+test cmdAH-9.14 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail //foo
+} foo
+test cmdAH-9.15 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail //foo/bar
+} bar
+test cmdAH-9.16 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail {//foo\/bar/baz}
+} baz
+test cmdAH-9.17 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail {//foo\/bar/baz/blat}
+} blat
+test cmdAH-9.18 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail /foo//
+} foo
+test cmdAH-9.19 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail ./a
+} a
+test cmdAH-9.20 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail a/.a
+} .a
+test cmdAH-9.21 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail c:foo
+} foo
+test cmdAH-9.22 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail c:
+} {}
+test cmdAH-9.23 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail c:/
+} {}
+test cmdAH-9.24 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail {c:\foo}
+} foo
+test cmdAH-9.25 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail {//foo/bar/baz}
+} baz
+test cmdAH-9.26 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail {//foo/bar}
+} {}
+test cmdAH-9.42 {Tcl_FileObjCmd: tail} -constraints testsetplatform -setup {
+ global env
+ set temp $env(HOME)
+} -body {
+ set env(HOME) "/home/test"
+ testsetplatform unix
+ file tail ~
+} -cleanup {
+ set env(HOME) $temp
+} -result test
+test cmdAH-9.43 {Tcl_FileObjCmd: tail} -constraints testsetplatform -setup {
+ global env
+ set temp $env(HOME)
+} -body {
+ set env(HOME) "~"
+ testsetplatform unix
+ file tail ~
+} -cleanup {
+ set env(HOME) $temp
+} -result {}
+test cmdAH-9.44 {Tcl_FileObjCmd: tail} -constraints testsetplatform -setup {
+ global env
+ set temp $env(HOME)
+} -body {
+ set env(HOME) "/home/test"
+ testsetplatform windows
+ file tail ~
+} -cleanup {
+ set env(HOME) $temp
+} -result test
+test cmdAH-9.46 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail {f.oo\bar/baz.bat}
+} baz.bat
+test cmdAH-9.47 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail c:foo
+} foo
+test cmdAH-9.48 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail c:
+} {}
+test cmdAH-9.49 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail c:/foo
+} foo
+test cmdAH-9.50 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail {c:/foo\bar}
+} bar
+test cmdAH-9.51 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail {foo\bar}
+} bar
+
+# rootname
+test cmdAH-10.1 {Tcl_FileObjCmd: rootname} -returnCodes error -body {
+ file rootname a b
+} -result {wrong # args: should be "file rootname name"}
+test cmdAH-10.2 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file rootname {}
+} {}
+test cmdAH-10.3 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file ro foo
+} foo
+test cmdAH-10.4 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file rootname foo.
+} foo
+test cmdAH-10.5 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file rootname .foo
+} {}
+test cmdAH-10.6 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file rootname abc.def
+} abc
+test cmdAH-10.7 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file rootname abc.def.ghi
+} abc.def
+test cmdAH-10.8 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file rootname a/b/c.d
+} a/b/c
+test cmdAH-10.9 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file rootname a/b.c/d
+} a/b.c/d
+test cmdAH-10.10 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file rootname a/b.c/
+} a/b.c/
+test cmdAH-10.23 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname {}
+} {}
+test cmdAH-10.24 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file ro foo
+} foo
+test cmdAH-10.25 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname foo.
+} foo
+test cmdAH-10.26 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname .foo
+} {}
+test cmdAH-10.27 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname abc.def
+} abc
+test cmdAH-10.28 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname abc.def.ghi
+} abc.def
+test cmdAH-10.29 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname a/b/c.d
+} a/b/c
+test cmdAH-10.30 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname a/b.c/d
+} a/b.c/d
+test cmdAH-10.31 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname a\\b.c\\
+} a\\b.c\\
+test cmdAH-10.32 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname a\\b\\c.d
+} a\\b\\c
+test cmdAH-10.33 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname a\\b.c\\d
+} a\\b.c\\d
+test cmdAH-10.34 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname a\\b.c\\
+} a\\b.c\\
+set num 35
+foreach outer { {} a .a a. a.a } {
+ foreach inner { {} a .a a. a.a } {
+ set thing [format %s/%s $outer $inner]
+ ;test cmdAH-10.$num {Tcl_FileObjCmd: rootname and extension options} testsetplatform "
+ testsetplatform unix
+ [list format %s%s [file rootname $thing] [file ext $thing]]
+ " $thing
+ incr num
+ }
+}
+
+# extension
+test cmdAH-11.1 {Tcl_FileObjCmd: extension} -returnCodes error -body {
+ file extension a b
+} -result {wrong # args: should be "file extension name"}
+test cmdAH-11.2 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file extension {}
+} {}
+test cmdAH-11.3 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file ext foo
+} {}
+test cmdAH-11.4 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file extension foo.
+} .
+test cmdAH-11.5 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file extension .foo
+} .foo
+test cmdAH-11.6 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file extension abc.def
+} .def
+test cmdAH-11.7 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file extension abc.def.ghi
+} .ghi
+test cmdAH-11.8 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file extension a/b/c.d
+} .d
+test cmdAH-11.9 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file extension a/b.c/d
+} {}
+test cmdAH-11.10 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file extension a/b.c/
+} {}
+test cmdAH-11.23 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension {}
+} {}
+test cmdAH-11.24 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file ext foo
+} {}
+test cmdAH-11.25 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension foo.
+} .
+test cmdAH-11.26 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension .foo
+} .foo
+test cmdAH-11.27 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension abc.def
+} .def
+test cmdAH-11.28 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension abc.def.ghi
+} .ghi
+test cmdAH-11.29 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension a/b/c.d
+} .d
+test cmdAH-11.30 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension a/b.c/d
+} {}
+test cmdAH-11.31 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension a\\b.c\\
+} {}
+test cmdAH-11.32 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension a\\b\\c.d
+} .d
+test cmdAH-11.33 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension a\\b.c\\d
+} {}
+test cmdAH-11.34 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension a\\b.c\\
+} {}
+foreach {test onPlatform value result} {
+ cmdAH-11.35 unix a..b .b
+ cmdAH-11.36 windows a..b .b
+ cmdAH-11.37 unix a...b .b
+ cmdAH-11.38 windows a...b .b
+ cmdAH-11.39 unix a.c..b .b
+ cmdAH-11.40 windows a.c..b .b
+ cmdAH-11.41 unix ..b .b
+ cmdAH-11.42 windows ..b .b
+} {
+ test $test {Tcl_FileObjCmd: extension} testsetplatform "
+ testsetplatform $onPlatform
+ file extension $value
+ " $result
+}
+
+# pathtype
+test cmdAH-12.1 {Tcl_FileObjCmd: pathtype} -returnCodes error -body {
+ file pathtype a b
+} -result {wrong # args: should be "file pathtype name"}
+test cmdAH-12.2 {Tcl_FileObjCmd: pathtype} testsetplatform {
+ testsetplatform unix
+ file pathtype /a
+} absolute
+test cmdAH-12.3 {Tcl_FileObjCmd: pathtype} testsetplatform {
+ testsetplatform unix
+ file p a
+} relative
+test cmdAH-12.4 {Tcl_FileObjCmd: pathtype} testsetplatform {
+ testsetplatform windows
+ file pathtype c:a
+} volumerelative
+
+# split
+test cmdAH-13.1 {Tcl_FileObjCmd: split} -returnCodes error -body {
+ file split a b
+} -result {wrong # args: should be "file split name"}
+test cmdAH-13.2 {Tcl_FileObjCmd: split} testsetplatform {
+ testsetplatform unix
+ file split a
+} a
+test cmdAH-13.3 {Tcl_FileObjCmd: split} testsetplatform {
+ testsetplatform unix
+ file split a/b
+} {a b}
+
+# join
+test cmdAH-14.1 {Tcl_FileObjCmd: join} testsetplatform {
+ testsetplatform unix
+ file join a
+} a
+test cmdAH-14.2 {Tcl_FileObjCmd: join} testsetplatform {
+ testsetplatform unix
+ file join a b
+} a/b
+test cmdAH-14.3 {Tcl_FileObjCmd: join} testsetplatform {
+ testsetplatform unix
+ file join a b c d
+} a/b/c/d
+
+# error handling of Tcl_TranslateFileName
+test cmdAH-15.1 {Tcl_FileObjCmd} -constraints testsetplatform -body {
+ testsetplatform unix
+ file atime ~_bad_user
+} -returnCodes error -result {user "_bad_user" doesn't exist}
+
+catch {testsetplatform $platform}
+
+# readable
+set gorpfile [makeFile abcde gorp.file]
+set dirfile [makeDirectory dir.file]
+test cmdAH-16.1 {Tcl_FileObjCmd: readable} {
+ -returnCodes error
+ -body {file readable a b}
+ -result {wrong # args: should be "file readable name"}
+}
+test cmdAH-16.2 {Tcl_FileObjCmd: readable} {
+ -constraints testchmod
+ -setup {testchmod 0444 $gorpfile}
+ -body {file readable $gorpfile}
+ -result 1
+}
+test cmdAH-16.3 {Tcl_FileObjCmd: readable} {
+ -constraints {unix notRoot testchmod}
+ -setup {testchmod 0333 $gorpfile}
+ -body {file readable $gorpfile}
+ -result 0
+}
+
+# writable
+test cmdAH-17.1 {Tcl_FileObjCmd: writable} {
+ -returnCodes error
+ -body {file writable a b}
+ -result {wrong # args: should be "file writable name"}
+}
+test cmdAH-17.2 {Tcl_FileObjCmd: writable} {
+ -constraints {notRoot testchmod}
+ -setup {testchmod 0555 $gorpfile}
+ -body {file writable $gorpfile}
+ -result 0
+}
+test cmdAH-17.3 {Tcl_FileObjCmd: writable} {
+ -constraints testchmod
+ -setup {testchmod 0222 $gorpfile}
+ -body {file writable $gorpfile}
+ -result 1
+}
+
+# executable
+removeFile $gorpfile
+removeDirectory $dirfile
+set dirfile [makeDirectory dir.file]
+set gorpfile [makeFile abcde gorp.file]
+test cmdAH-18.1 {Tcl_FileObjCmd: executable} -returnCodes error -body {
+ file executable a b
+} -result {wrong # args: should be "file executable name"}
+test cmdAH-18.2 {Tcl_FileObjCmd: executable} {notRoot} {
+ file executable $gorpfile
+} 0
+test cmdAH-18.3 {Tcl_FileObjCmd: executable} {unix testchmod} {
+ # Only on unix will setting the execute bit on a regular file cause that
+ # file to be executable.
+ testchmod 0775 $gorpfile
+ file exe $gorpfile
+} 1
+test cmdAH-18.5 {Tcl_FileObjCmd: executable} -constraints {win} -body {
+ # On pc, must be a .exe, .com, etc.
+ set x [file exe $gorpfile]
+ set gorpexe [makeFile foo gorp.exe]
+ lappend x [file exe $gorpexe]
+} -cleanup {
+ removeFile $gorpexe
+} -result {0 1}
+test cmdAH-18.5.1 {Tcl_FileObjCmd: executable} -constraints {win} -body {
+ # On pc, must be a .exe, .com, etc.
+ set x [file exe $gorpfile]
+ set gorpexe [makeFile foo gorp.exe]
+ lappend x [file exe [string toupper $gorpexe]]
+} -cleanup {
+ removeFile $gorpexe
+} -result {0 1}
+test cmdAH-18.6 {Tcl_FileObjCmd: executable} {} {
+ # Directories are always executable.
+ file exe $dirfile
+} 1
+
+removeDirectory $dirfile
+removeFile $gorpfile
+set linkfile [file join [temporaryDirectory] link.file]
+file delete $linkfile
+
+# exists
+test cmdAH-19.1 {Tcl_FileObjCmd: exists} -returnCodes error -body {
+ file exists a b
+} -result {wrong # args: should be "file exists name"}
+test cmdAH-19.2 {Tcl_FileObjCmd: exists} {file exists $gorpfile} 0
+test cmdAH-19.3 {Tcl_FileObjCmd: exists} {
+ file exists [file join [temporaryDirectory] dir.file gorp.file]
+} 0
+catch {
+ set gorpfile [makeFile abcde gorp.file]
+ set dirfile [makeDirectory dir.file]
+ set subgorp [makeFile 12345 [file join $dirfile gorp.file]]
+}
+test cmdAH-19.4 {Tcl_FileObjCmd: exists} {
+ file exists $gorpfile
+} 1
+test cmdAH-19.5 {Tcl_FileObjCmd: exists} {
+ file exists $subgorp
+} 1
+# nativename
+test cmdAH-19.6 {Tcl_FileObjCmd: nativename} -body {
+ testsetplatform unix
+ file nativename a/b
+} -constraints testsetplatform -cleanup {
+ testsetplatform $platform
+} -result a/b
+test cmdAH-19.7 {Tcl_FileObjCmd: nativename} -body {
+ testsetplatform windows
+ file nativename a/b
+} -constraints testsetplatform -cleanup {
+ testsetplatform $platform
+} -result {a\b}
+test cmdAH-19.9 {Tcl_FileObjCmd: ~ : exists} {
+ file exists ~nOsUcHuSeR
+} 0
+test cmdAH-19.10 {Tcl_FileObjCmd: ~ : nativename} -body {
+ # should probably be a non-error in fact...
+ file nativename ~nOsUcHuSeR
+} -returnCodes error -match glob -result *
+# The test below has to be done in /tmp rather than the current directory in
+# order to guarantee (?) a local file system: some NFS file systems won't do
+# the stuff below correctly.
+test cmdAH-19.11 {Tcl_FileObjCmd: exists} -constraints {unix notRoot} -setup {
+ file delete -force /tmp/tcl.foo.dir/file
+ file delete -force /tmp/tcl.foo.dir
+} -body {
+ makeDirectory /tmp/tcl.foo.dir
+ makeFile 12345 /tmp/tcl.foo.dir/file
+ file attributes /tmp/tcl.foo.dir -permissions 0000
+ file exists /tmp/tcl.foo.dir/file
+} -cleanup {
+ file attributes /tmp/tcl.foo.dir -permissions 0775
+ removeFile /tmp/tcl.foo.dir/file
+ removeDirectory /tmp/tcl.foo.dir
+} -result 0
+
+# Stat related commands
+
+catch {testsetplatform $platform}
+removeFile $gorpfile
+set gorpfile [makeFile "Test string" gorp.file]
+catch {file attributes $gorpfile -permissions 0765}
+
+# avoid problems with non-local filesystems
+if {[testConstraint unix] && [file exists /tmp]} {
+ set file [makeFile "data" touch.me /tmp]
+} else {
+ set file [makeFile "data" touch.me]
+}
+
+# atime
+test cmdAH-20.1 {Tcl_FileObjCmd: atime} -returnCodes error -body {
+ file atime a b c
+} -result {wrong # args: should be "file atime name ?time?"}
+test cmdAH-20.2 {Tcl_FileObjCmd: atime} -setup {
+ unset -nocomplain stat
+} -body {
+ file stat $gorpfile stat
+ list [expr {[file mtime $gorpfile] == $stat(mtime)}] \
+ [expr {[file atime $gorpfile] == $stat(atime)}]
+} -result {1 1}
+test cmdAH-20.3 {Tcl_FileObjCmd: atime} {
+ list [catch {file atime _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-20.4 {Tcl_FileObjCmd: atime} -returnCodes error -body {
+ file atime $file notint
+} -result {expected integer but got "notint"}
+test cmdAH-20.5 {Tcl_FileObjCmd: atime touch} {unix} {
+ set atime [file atime $file]
+ after 1100; # pause a sec to notice change in atime
+ set newatime [clock seconds]
+ set modatime [file atime $file $newatime]
+ expr {$newatime == $modatime ? 1 : "$newatime != $modatime"}
+} 1
+test cmdAH-20.6 {Tcl_FileObjCmd: atime touch} -setup {
+ set old [pwd]
+ cd $::tcltest::temporaryDirectory
+ set volumetype [testvolumetype]
+ cd $old
+} -constraints {win testvolumetype} -body {
+ if {"NTFS" ne $volumetype} {
+ # Windows FAT doesn't understand atime, but NTFS does. May also fail
+ # for Windows on NFS mounted disks.
+ return 1
+ }
+ cd $old
+ set atime [file atime $file]
+ after 1100; # pause a sec to notice change in atime
+ set newatime [clock seconds]
+ set modatime [file atime $file $newatime]
+ expr {$newatime == $modatime ? 1 : "$newatime != $modatime"}
+} -result 1
+
+if {[testConstraint unix] && [file exists /tmp]} {
+ removeFile touch.me /tmp
+} else {
+ removeFile touch.me
+}
+
+# isdirectory
+test cmdAH-21.1 {Tcl_FileObjCmd: isdirectory} -returnCodes error -body {
+ file isdirectory a b
+} -result {wrong # args: should be "file isdirectory name"}
+test cmdAH-21.2 {Tcl_FileObjCmd: isdirectory} {file isdirectory $gorpfile} 0
+test cmdAH-21.3 {Tcl_FileObjCmd: isdirectory} {file isdirectory $dirfile} 1
+
+# isfile
+test cmdAH-22.1 {Tcl_FileObjCmd: isfile} -returnCodes error -body {
+ file isfile a b
+} -result {wrong # args: should be "file isfile name"}
+test cmdAH-22.2 {Tcl_FileObjCmd: isfile} {file isfile $gorpfile} 1
+test cmdAH-22.3 {Tcl_FileObjCmd: isfile} {file isfile $dirfile} 0
+
+# lstat and readlink: don't run these tests everywhere, since not all sites
+# will have symbolic links
+catch {file link -symbolic $linkfile $gorpfile}
+test cmdAH-23.1 {Tcl_FileObjCmd: lstat} -returnCodes error -body {
+ file lstat a
+} -result {wrong # args: should be "file lstat name varName"}
+test cmdAH-23.2 {Tcl_FileObjCmd: lstat} -returnCodes error -body {
+ file lstat a b c
+} -result {wrong # args: should be "file lstat name varName"}
+test cmdAH-23.3 {Tcl_FileObjCmd: lstat} -setup {
+ unset -nocomplain stat
+} -constraints {unix nonPortable} -body {
+ file lstat $linkfile stat
+ lsort [array names stat]
+} -result {atime ctime dev gid ino mode mtime nlink size type uid}
+test cmdAH-23.4 {Tcl_FileObjCmd: lstat} -setup {
+ unset -nocomplain stat
+} -constraints {unix nonPortable} -body {
+ file lstat $linkfile stat
+ list $stat(nlink) [expr $stat(mode)&0777] $stat(type)
+} -result {1 511 link}
+test cmdAH-23.5 {Tcl_FileObjCmd: lstat errors} {nonPortable} {
+ list [catch {file lstat _bogus_ stat} msg] [string tolower $msg] \
+ $errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-23.6 {Tcl_FileObjCmd: lstat errors} -setup {
+ unset -nocomplain x
+} -body {
+ set x 44
+ list [catch {file lstat $gorpfile x} msg] $msg $errorCode
+} -result {1 {can't set "x(dev)": variable isn't array} {TCL LOOKUP VARNAME x}}
+unset -nocomplain stat
+# mkdir
+set dirA [file join [temporaryDirectory] a]
+set dirB [file join [temporaryDirectory] a]
+test cmdAH-23.7 {Tcl_FileObjCmd: mkdir} -setup {
+ catch {file delete -force $dirA}
+} -body {
+ file mkdir $dirA
+ file isdirectory $dirA
+} -cleanup {
+ file delete $dirA
+} -result {1}
+test cmdAH-23.8 {Tcl_FileObjCmd: mkdir} -setup {
+ catch {file delete -force $dirA}
+} -body {
+ file mkdir $dirA/b
+ file isdirectory $dirA/b
+} -cleanup {
+ file delete -force $dirA
+} -result {1}
+test cmdAH-23.9 {Tcl_FileObjCmd: mkdir} -setup {
+ catch {file delete -force $dirA}
+} -body {
+ file mkdir $dirA/b/c
+ file isdirectory $dirA/b/c
+} -cleanup {
+ file delete -force $dirA
+} -result {1}
+test cmdAH-23.10 {Tcl_FileObjCmd: mkdir} -setup {
+ catch {file delete -force $dirA}
+ catch {file delete -force $dirB}
+} -body {
+ file mkdir $dirA/b $dirB/a/c
+ list [file isdirectory $dirA/b] [file isdirectory $dirB/a/c]
+} -cleanup {
+ file delete -force $dirA
+ file delete -force $dirB
+} -result {1 1}
+test cmdAH-23.11 {Tcl_FileObjCmd: mkdir} {
+ # Allow zero arguments (TIP 323)
+ file mkdir
+} {}
+
+set file [makeFile "data" touch.me]
+# mtime
+test cmdAH-24.1 {Tcl_FileObjCmd: mtime} -returnCodes error -body {
+ file mtime a b c
+} -result {wrong # args: should be "file mtime name ?time?"}
+test cmdAH-24.2 {Tcl_FileObjCmd: mtime} -setup {
+ # Check (allowing for clock-skew and OS interrupts as best we can) that
+ # the change in mtime on a file being written is the time elapsed between
+ # writes. Note that this can still fail on very busy systems if there are
+ # long preemptions between the writes and the reading of the clock, but
+ # there's not much you can do about that other than the completely
+ # horrible "keep on trying to write until you managed to do it all in less
+ # than a second." - DKF
+ waitForEvenSecondForFAT
+} -body {
+ set f [open $gorpfile w]
+ puts $f "More text"
+ close $f
+ set clockOld [clock seconds]
+ set fileOld [file mtime $gorpfile]
+ after 2000
+ set f [open $gorpfile w]
+ puts $f "More text"
+ close $f
+ set clockNew [clock seconds]
+ set fileNew [file mtime $gorpfile]
+ expr {
+ (($fileNew > $fileOld) && ($clockNew > $clockOld) &&
+ (abs(($fileNew-$fileOld) - ($clockNew-$clockOld)) <= 1)) ? "1" :
+ "file:($fileOld=>$fileNew) clock:($clockOld=>$clockNew)"
+ }
+} -result {1}
+test cmdAH-24.3 {Tcl_FileObjCmd: mtime} -setup {
+ unset -nocomplain stat
+} -body {
+ file stat $gorpfile stat
+ list [expr {[file mtime $gorpfile] == $stat(mtime)}] \
+ [expr {[file atime $gorpfile] == $stat(atime)}]
+} -result {1 1}
+test cmdAH-24.4 {Tcl_FileObjCmd: mtime} {
+ list [catch {file mtime _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-24.5 {Tcl_FileObjCmd: mtime} -setup {
+ # Under Unix, use a file in /tmp to avoid clock skew due to NFS. On other
+ # platforms, just use a file in the local directory.
+ if {[testConstraint unix]} {
+ set name /tmp/tcl.test.[pid]
+ } else {
+ set name [file join [temporaryDirectory] tf]
+ }
+} -body {
+ # Make sure that a new file's time is correct. 10 seconds variance is
+ # allowed used due to slow networks or clock skew on a network drive.
+ file delete -force $name
+ close [open $name w]
+ expr {abs([clock seconds]-[file mtime $name])<10}
+} -cleanup {
+ file delete $name
+} -result {1}
+test cmdAH-24.7 {Tcl_FileObjCmd: mtime} -returnCodes error -body {
+ file mtime $file notint
+} -result {expected integer but got "notint"}
+test cmdAH-24.8 {Tcl_FileObjCmd: mtime touch} unix {
+ set mtime [file mtime $file]
+ after 1100; # pause a sec to notice change in mtime
+ set newmtime [clock seconds]
+ set modmtime [file mtime $file $newmtime]
+ expr {$newmtime == $modmtime ? 1 : "$newmtime != $modmtime"}
+} 1
+test cmdAH-24.9 {Tcl_FileObjCmd: mtime touch with non-ascii chars} -setup {
+ set oldfile $file
+} -constraints unix -body {
+ # introduce some non-ascii characters.
+ append file \u2022
+ file delete -force $file
+ file rename $oldfile $file
+ set mtime [file mtime $file]
+ after 1100; # pause a sec to notice change in mtime
+ set newmtime [clock seconds]
+ set modmtime [file mtime $file $newmtime]
+ expr {$newmtime == $modmtime ? 1 : "$newmtime != $modmtime"}
+} -cleanup {
+ file rename $file $oldfile
+} -result 1
+test cmdAH-24.10 {Tcl_FileObjCmd: mtime touch} -constraints win -setup {
+ waitForEvenSecondForFAT
+} -body {
+ set mtime [file mtime $file]
+ after 2100; # pause two secs to notice change in mtime on FAT fs'es
+ set newmtime [clock seconds]
+ set modmtime [file mtime $file $newmtime]
+ expr {$newmtime == $modmtime ? 1 : "$newmtime != $modmtime"}
+} -result 1
+test cmdAH-24.11 {Tcl_FileObjCmd: mtime touch with non-ascii chars} -setup {
+ waitForEvenSecondForFAT
+ set oldfile $file
+} -constraints win -body {
+ # introduce some non-ascii characters.
+ append file \u2022
+ file delete -force $file
+ file rename $oldfile $file
+ set mtime [file mtime $file]
+ after 2100; # pause two secs to notice change in mtime on FAT fs'es
+ set newmtime [clock seconds]
+ set modmtime [file mtime $file $newmtime]
+ expr {$newmtime == $modmtime ? 1 : "$newmtime != $modmtime"}
+} -cleanup {
+ file rename $file $oldfile
+} -result 1
+removeFile touch.me
+rename waitForEvenSecondForFAT {}
+test cmdAH-24.12 {Tcl_FileObjCmd: mtime and daylight savings} -setup {
+ set name [file join [temporaryDirectory] clockchange]
+ file delete -force $name
+ close [open $name w]
+} -body {
+ set time [clock scan "21:00:00 October 30 2004 GMT"]
+ file mtime $name $time
+ set newmtime [file mtime $name]
+ expr {$newmtime == $time ? 1 : "$newmtime != $time"}
+} -cleanup {
+ file delete $name
+} -result {1}
+# bug 1420432: setting mtime fails for directories on windows.
+test cmdAH-24.13 {Tcl_FileObjCmd: directory mtime} -setup {
+ set dirname [file join [temporaryDirectory] tmp[pid]]
+ file delete -force $dirname
+} -constraints tempNotWin -body {
+ file mkdir $dirname
+ set old [file mtime $dirname]
+ file mtime $dirname 0
+ set new [file mtime $dirname]
+ list $new [expr {$old != $new}]
+} -cleanup {
+ file delete -force $dirname
+} -result {0 1}
+
+# owned
+test cmdAH-25.1 {Tcl_FileObjCmd: owned} -returnCodes error -body {
+ file owned a b
+} -result {wrong # args: should be "file owned name"}
+test cmdAH-25.2 {Tcl_FileObjCmd: owned} -constraints win -body {
+ file owned $gorpfile
+} -result 1
+test cmdAH-25.2.1 {Tcl_FileObjCmd: owned} -constraints unix -setup {
+ # Avoid problems with AFS
+ set tmpfile [makeFile "data" touch.me /tmp]
+} -body {
+ file owned $tmpfile
+} -cleanup {
+ removeFile touch.me /tmp
+} -result 1
+test cmdAH-25.3 {Tcl_FileObjCmd: owned} {unix notRoot} {
+ file owned /
+} 0
+
+# readlink
+test cmdAH-26.1 {Tcl_FileObjCmd: readlink} -returnCodes error -body {
+ file readlink a b
+} -result {wrong # args: should be "file readlink name"}
+test cmdAH-26.2 {Tcl_FileObjCmd: readlink} {unix nonPortable} {
+ file readlink $linkfile
+} $gorpfile
+test cmdAH-26.3 {Tcl_FileObjCmd: readlink errors} {unix nonPortable} {
+ list [catch {file readlink _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not readlink "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-26.5 {Tcl_FileObjCmd: readlink errors} {win nonPortable} {
+ list [catch {file readlink _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not readlink "_bogus_": invalid argument} {POSIX EINVAL {invalid argument}}}
+
+# size
+test cmdAH-27.1 {Tcl_FileObjCmd: size} -returnCodes error -body {
+ file size a b
+} -result {wrong # args: should be "file size name"}
+test cmdAH-27.2 {Tcl_FileObjCmd: size} {
+ set oldsize [file size $gorpfile]
+ set f [open $gorpfile a]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f "More text"
+ close $f
+ expr {[file size $gorpfile] - $oldsize}
+} {10}
+test cmdAH-27.3 {Tcl_FileObjCmd: size} {
+ list [catch {file size _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+
+catch {testsetplatform $platform}
+removeFile $gorpfile
+set gorpfile [makeFile "Test string" gorp.file]
+catch {file attributes $gorpfile -permissions 0765}
+
+# stat
+test cmdAH-28.1 {Tcl_FileObjCmd: stat} -returnCodes error -body {
+ file stat _bogus_
+} -result {wrong # args: should be "file stat name varName"}
+test cmdAH-28.2 {Tcl_FileObjCmd: stat} -returnCodes error -body {
+ file stat _bogus_ a b
+} -result {wrong # args: should be "file stat name varName"}
+test cmdAH-28.3 {Tcl_FileObjCmd: stat} -setup {
+ unset -nocomplain stat
+ set stat(blocks) [set stat(blksize) {}]
+} -body {
+ file stat $gorpfile stat
+ unset stat(blocks) stat(blksize); # Ignore these fields; not always set
+ lsort [array names stat]
+} -result {atime ctime dev gid ino mode mtime nlink size type uid}
+test cmdAH-28.4 {Tcl_FileObjCmd: stat} -setup {
+ unset -nocomplain stat
+} -body {
+ file stat $gorpfile stat
+ list $stat(nlink) $stat(size) $stat(type)
+} -result {1 12 file}
+test cmdAH-28.5 {Tcl_FileObjCmd: stat} -constraints {unix} -setup {
+ unset -nocomplain stat
+} -body {
+ file stat $gorpfile stat
+ expr {$stat(mode) & 0o777}
+} -result {501}
+test cmdAH-28.6 {Tcl_FileObjCmd: stat} {
+ list [catch {file stat _bogus_ stat} msg] [string tolower $msg] $errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-28.7 {Tcl_FileObjCmd: stat} -setup {
+ unset -nocomplain x
+} -returnCodes error -body {
+ set x 44
+ file stat $gorpfile x
+} -result {can't set "x(dev)": variable isn't array}
+test cmdAH-28.8 {Tcl_FileObjCmd: stat} -setup {
+ set filename [makeFile "" foo.text]
+} -body {
+ # Sign extension of purported unsigned short to int.
+ file stat $filename stat
+ expr {$stat(mode) > 0}
+} -cleanup {
+ removeFile $filename
+} -result 1
+test cmdAH-28.9 {Tcl_FileObjCmd: stat} win {
+ # stat of root directory was failing. Don't care about answer, just that
+ # test runs. Relative paths that resolve to root
+ set old [pwd]
+ cd c:/
+ file stat c: stat
+ file stat c:. stat
+ file stat . stat
+ cd $old
+ file stat / stat
+ file stat c:/ stat
+ file stat c:/. stat
+} {}
+test cmdAH-28.10 {Tcl_FileObjCmd: stat} {win nonPortable} {
+ # stat of root directory was failing. Don't care about answer, just that
+ # test runs.
+ file stat //pop/$env(USERNAME) stat
+ file stat //pop/$env(USERNAME)/ stat
+ file stat //pop/$env(USERNAME)/. stat
+} {}
+test cmdAH-28.11 {Tcl_FileObjCmd: stat} -setup {
+ set old [pwd]
+} -constraints {win nonPortable} -body {
+ # stat of network directory was returning id of current local drive.
+ cd c:/
+ file stat //pop/$env(USERNAME) stat
+ expr {$stat(dev) == 2}
+} -cleanup {
+ cd $old
+} -result 0
+test cmdAH-28.12 {Tcl_FileObjCmd: stat} -setup {
+ set filename [makeFile "" foo.test]
+} -body {
+ # stat(mode) with S_IFREG flag was returned as a negative number if mode_t
+ # was a short instead of an unsigned short.
+ file stat $filename stat
+ expr {$stat(mode) > 0}
+} -cleanup {
+ removeFile $filename
+} -result 1
+unset -nocomplain stat
+
+# type
+test cmdAH-29.1 {Tcl_FileObjCmd: type} -returnCodes error -body {
+ file size a b
+} -result {wrong # args: should be "file size name"}
+test cmdAH-29.2 {Tcl_FileObjCmd: type} {
+ file type $dirfile
+} directory
+test cmdAH-29.3.0 {Tcl_FileObjCmd: delete removes link not file} {unix nonPortable} {
+ set exists [list [file exists $linkfile] [file exists $gorpfile]]
+ file delete $linkfile
+ set exists2 [list [file exists $linkfile] [file exists $gorpfile]]
+ list $exists $exists2
+} {{1 1} {0 1}}
+test cmdAH-29.3 {Tcl_FileObjCmd: type} {
+ file type $gorpfile
+} file
+test cmdAH-29.4 {Tcl_FileObjCmd: type} -constraints {unix} -setup {
+ catch {file delete $linkfile}
+} -body {
+ # Unlike [exec ln -s], [file link] requires an existing target
+ file link -symbolic $linkfile $gorpfile
+ file type $linkfile
+} -cleanup {
+ file delete $linkfile
+} -result link
+test cmdAH-29.4.1 {Tcl_FileObjCmd: type} -constraints {linkDirectory} -setup {
+ set tempdir [makeDirectory temp]
+} -body {
+ set linkdir [file join [temporaryDirectory] link.dir]
+ file link -symbolic $linkdir $tempdir
+ file type $linkdir
+} -cleanup {
+ file delete $linkdir
+ removeDirectory $tempdir
+} -result link
+test cmdAH-29.5 {Tcl_FileObjCmd: type} {
+ list [catch {file type _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+
+# Error conditions
+test cmdAH-30.1 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+ file gorp x
+} -result {unknown or ambiguous subcommand "gorp": must be atime, attributes, channels, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, link, lstat, mkdir, mtime, nativename, normalize, owned, pathtype, readable, readlink, rename, rootname, separator, size, split, stat, system, tail, tempfile, type, volumes, or writable}
+test cmdAH-30.2 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+ file ex x
+} -match glob -result {unknown or ambiguous subcommand "ex": must be *}
+test cmdAH-30.3 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+ file is x
+} -match glob -result {unknown or ambiguous subcommand "is": must be *}
+test cmdAH-30.4 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+ file z x
+} -match glob -result {unknown or ambiguous subcommand "z": must be *}
+test cmdAH-30.5 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+ file read x
+} -match glob -result {unknown or ambiguous subcommand "read": must be *}
+test cmdAH-30.6 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+ file s x
+} -match glob -result {unknown or ambiguous subcommand "s": must be *}
+test cmdAH-30.7 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+ file t x
+} -match glob -result {unknown or ambiguous subcommand "t": must be *}
+test cmdAH-30.8 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+ file dirname ~woohgy
+} -result {user "woohgy" doesn't exist}
+
+# channels
+# In testing 'file channels', we need to make sure that a channel created in
+# one interp isn't visible in another.
+
+interp create simpleInterp
+interp create -safe safeInterp
+interp create
+catch {safeInterp expose file file}
+
+test cmdAH-31.1 {Tcl_FileObjCmd: channels, too many args} -body {
+ file channels a b
+} -returnCodes error -result {wrong # args: should be "file channels ?pattern?"}
+test cmdAH-31.2 {Tcl_FileObjCmd: channels, too many args} {
+ # Normal interps start out with only the standard channels
+ lsort [simpleInterp eval [list file chan]]
+} {stderr stdin stdout}
+test cmdAH-31.3 {Tcl_FileObjCmd: channels, globbing} {
+ string equal [file channels] [file channels *]
+} {1}
+test cmdAH-31.4 {Tcl_FileObjCmd: channels, globbing} {
+ lsort [file channels std*]
+} {stderr stdin stdout}
+set newFileId [open $gorpfile w]
+test cmdAH-31.5 {Tcl_FileObjCmd: channels} {
+ set res [file channels $newFileId]
+ string equal $newFileId $res
+} {1}
+test cmdAH-31.6 {Tcl_FileObjCmd: channels in other interp} {
+ # Safe interps start out with no channels
+ safeInterp eval [list file channels]
+} {}
+test cmdAH-31.7 {Tcl_FileObjCmd: channels in other interp} -body {
+ safeInterp eval [list puts $newFileId "hello"]
+} -returnCodes error -result "can not find channel named \"$newFileId\""
+interp share {} $newFileId safeInterp
+interp share {} stdout safeInterp
+test cmdAH-31.8 {Tcl_FileObjCmd: channels in other interp} {
+ # $newFileId should now be visible in both interps
+ list [file channels $newFileId] \
+ [safeInterp eval [list file channels $newFileId]]
+} [list $newFileId $newFileId]
+test cmdAH-31.9 {Tcl_FileObjCmd: channels in other interp} {
+ lsort [safeInterp eval [list file channels]]
+} [lsort [list stdout $newFileId]]
+test cmdAH-31.10 {Tcl_FileObjCmd: channels in other interp} {
+ # we can now write to $newFileId from slave
+ safeInterp eval [list puts $newFileId "hello"]
+} {}
+interp transfer {} $newFileId safeInterp
+test cmdAH-31.11 {Tcl_FileObjCmd: channels in other interp} {
+ # $newFileId should now be visible only in safeInterp
+ list [file channels $newFileId] \
+ [safeInterp eval [list file channels $newFileId]]
+} [list {} $newFileId]
+test cmdAH-31.12 {Tcl_FileObjCmd: channels in other interp} {
+ lsort [safeInterp eval [list file channels]]
+} [lsort [list stdout $newFileId]]
+test cmdAH-31.13 {Tcl_FileObjCmd: channels in other interp} {
+ safeInterp eval [list close $newFileId]
+ safeInterp eval [list file channels]
+} {stdout}
+
+# Temp files (TIP#210)
+test cmdAH-32.1 {file tempfile - usage} -returnCodes error -body {
+ file tempfile a b c
+} -result {wrong # args: should be "file tempfile ?nameVar? ?template?"}
+test cmdAH-32.2 {file tempfile - returns a read/write channel} -body {
+ set f [file tempfile]
+ puts $f ok
+ seek $f 0
+ gets $f
+} -cleanup {
+ catch {close $f}
+} -result ok
+test cmdAH-32.3 {file tempfile - makes filenames} -setup {
+ unset -nocomplain name
+} -body {
+ set result [info exists name]
+ set f [file tempfile name]
+ lappend result [info exists name] [file exists $name]
+ close $f
+ lappend result [file exists $name]
+} -cleanup {
+ catch {close $f}
+ catch {file delete $name}
+} -result {0 1 1 1}
+# We try to obey the template on Unix, but don't (currently) bother on Win
+test cmdAH-32.4 {file tempfile - templates} -constraints unix -body {
+ close [file tempfile name foo]
+ expr {[string match foo* [file tail $name]] ? "ok" : "foo produced $name"}
+} -cleanup {
+ catch {file delete $name}
+} -result ok
+test cmdAH-32.5 {file tempfile - templates} -constraints unix -body {
+ set template [file join $dirfile foo]
+ close [file tempfile name $template]
+ expr {[string match $template* $name] ? "ok" : "$template produced $name"}
+} -cleanup {
+ catch {file delete $name}
+} -result ok
+# Not portable; not all unix systems have mkstemps()
+test cmdAH-32.6 {file tempfile - templates} -body {
+ set template [file join $dirfile foo]
+ close [file tempfile name $template.bar]
+ expr {[string match $template*.bar $name] ? "ok" :
+ "$template.bar produced $name"}
+} -constraints {unix nonPortable} -cleanup {
+ catch {file delete $name}
+} -result ok
+
+# This shouldn't work, but just in case a test above failed...
+catch {close $newFileId}
+
+interp delete safeInterp
+interp delete simpleInterp
+
+# cleanup
+catch {testsetplatform $platform}
+unset -nocomplain platform
+
+# Tcl_ForObjCmd is tested in for.test
+
+catch {file attributes $dirfile -permissions 0777}
+removeDirectory $dirfile
+removeFile $gorpfile
+# No idea how well [removeFile] copes with links...
+file delete $linkfile
+
+cd $cmdAHwd
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/cmdIL.test b/library/msgcat/tests/cmdIL.test
new file mode 100644
index 0000000..4b1002a
--- /dev/null
+++ b/library/msgcat/tests/cmdIL.test
@@ -0,0 +1,723 @@
+# This file contains a collection of tests for the procedures in the file
+# tclCmdIL.c. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Used for constraining memory leak tests
+testConstraint memory [llength [info commands memory]]
+testConstraint testobj [llength [info commands testobj]]
+
+test cmdIL-1.1 {Tcl_LsortObjCmd procedure} -returnCodes error -body {
+ lsort
+} -result {wrong # args: should be "lsort ?-option value ...? list"}
+test cmdIL-1.2 {Tcl_LsortObjCmd procedure} -returnCodes error -body {
+ lsort -foo {1 3 2 5}
+} -result {bad option "-foo": must be -ascii, -command, -decreasing, -dictionary, -increasing, -index, -indices, -integer, -nocase, -real, -stride, or -unique}
+test cmdIL-1.3 {Tcl_LsortObjCmd procedure, default options} {
+ lsort {d e c b a \{ d35 d300}
+} {a b c d d300 d35 e \{}
+test cmdIL-1.4 {Tcl_LsortObjCmd procedure, -ascii option} {
+ lsort -integer -ascii {d e c b a d35 d300}
+} {a b c d d300 d35 e}
+test cmdIL-1.5 {Tcl_LsortObjCmd procedure, -command option} -body {
+ lsort -command {1 3 2 5}
+} -returnCodes error -result {"-command" option must be followed by comparison command}
+test cmdIL-1.6 {Tcl_LsortObjCmd procedure, -command option} -setup {
+ proc cmp {a b} {
+ expr {[string match x* $b] - [string match x* $a]}
+ }
+} -body {
+ lsort -command cmp {x1 abc x2 def x3 x4}
+} -result {x1 x2 x3 x4 abc def} -cleanup {
+ rename cmp ""
+}
+test cmdIL-1.7 {Tcl_LsortObjCmd procedure, -decreasing option} {
+ lsort -decreasing {d e c b a d35 d300}
+} {e d35 d300 d c b a}
+test cmdIL-1.8 {Tcl_LsortObjCmd procedure, -dictionary option} {
+ lsort -dictionary {d e c b a d35 d300}
+} {a b c d d35 d300 e}
+test cmdIL-1.9 {Tcl_LsortObjCmd procedure, -dictionary option} {
+ lsort -dictionary {1k 0k 10k}
+} {0k 1k 10k}
+test cmdIL-1.10 {Tcl_LsortObjCmd procedure, -increasing option} {
+ lsort -decreasing -increasing {d e c b a d35 d300}
+} {a b c d d300 d35 e}
+test cmdIL-1.11 {Tcl_LsortObjCmd procedure, -index option} -body {
+ lsort -index {1 3 2 5}
+} -returnCodes error -result {"-index" option must be followed by list index}
+test cmdIL-1.12 {Tcl_LsortObjCmd procedure, -index option} -body {
+ lsort -index foo {1 3 2 5}
+} -returnCodes error -result {bad index "foo": must be integer?[+-]integer? or end?[+-]integer?}
+test cmdIL-1.13 {Tcl_LsortObjCmd procedure, -index option} {
+ lsort -index end -integer {{2 25} {10 20 50 100} {3 16 42} 1}
+} {1 {2 25} {3 16 42} {10 20 50 100}}
+test cmdIL-1.14 {Tcl_LsortObjCmd procedure, -index option} {
+ lsort -index 1 -integer {{1 25 100} {3 16 42} {10 20 50}}
+} {{3 16 42} {10 20 50} {1 25 100}}
+test cmdIL-1.15 {Tcl_LsortObjCmd procedure, -integer option} {
+ lsort -integer {24 6 300 18}
+} {6 18 24 300}
+test cmdIL-1.16 {Tcl_LsortObjCmd procedure, -integer option} -body {
+ lsort -integer {1 3 2.4}
+} -returnCodes error -result {expected integer but got "2.4"}
+test cmdIL-1.17 {Tcl_LsortObjCmd procedure, -real option} {
+ lsort -real {24.2 6e3 150e-1}
+} {150e-1 24.2 6e3}
+test cmdIL-1.18 {Tcl_LsortObjCmd procedure, bogus list} -body {
+ lsort "1 2 3 \{ 4"
+} -returnCodes error -result {unmatched open brace in list}
+test cmdIL-1.19 {Tcl_LsortObjCmd procedure, empty list} {
+ lsort {}
+} {}
+test cmdIL-1.22 {Tcl_LsortObjCmd procedure, unique sort} {
+ lsort -integer -unique {3 1 2 3 1 4 3}
+} {1 2 3 4}
+test cmdIL-1.23 {Tcl_LsortObjCmd procedure, unique sort with index} {
+ # lsort -unique should return the last unique item
+ lsort -unique -index 0 {{a b} {c b} {a c} {d a}}
+} {{a c} {c b} {d a}}
+test cmdIL-1.24 {Tcl_LsortObjCmd procedure, order of -index and -command} -setup {
+ catch {rename 1 ""}
+ proc testcmp {a b} {return [string compare $a $b]}
+} -body {
+ set l [list [list a b] [list c d]]
+ lsort -command testcmp -index 1 $l
+} -cleanup {
+ rename testcmp ""
+} -result [list [list a b] [list c d]]
+test cmdIL-1.25 {Tcl_LsortObjCmd procedure, order of -index and -command} -setup {
+ catch {rename 1 ""}
+ proc testcmp {a b} {return [string compare $a $b]}
+} -body {
+ set l [list [list a b] [list c d]]
+ lsort -index 1 -command testcmp $l
+} -cleanup {
+ rename testcmp ""
+} -result [list [list a b] [list c d]]
+# Note that the required order only exists in the end-1'th element; indexing
+# using the end element or any fixed offset from the start will not work...
+test cmdIL-1.26 {Tcl_LsortObjCmd procedure, offset indexing from end} {
+ lsort -index end-1 {{a 1 e i} {b 2 3 f g} {c 4 5 6 d h}}
+} {{c 4 5 6 d h} {a 1 e i} {b 2 3 f g}}
+test cmdIL-1.27 {Tcl_LsortObjCmd procedure, returning indices} {
+ lsort -indices {a c b}
+} {0 2 1}
+test cmdIL-1.28 {Tcl_LsortObjCmd procedure, returning indices} {
+ lsort -indices -unique -decreasing -real {1.2 34.5 34.5 5.6}
+} {2 3 0}
+test cmdIL-1.29 {Tcl_LsortObjCmd procedure, loss of list rep during sorting} {
+ set l {1 2 3}
+ string length [lsort -command {apply {args {string length $::l}}} $l]
+} 5
+test cmdIL-1.30 {Tcl_LsortObjCmd procedure, -stride option} {
+ lsort -stride 2 {f e d c b a}
+} {b a d c f e}
+test cmdIL-1.31 {Tcl_LsortObjCmd procedure, -stride option} {
+ lsort -stride 3 {f e d c b a}
+} {c b a f e d}
+test cmdIL-1.32 {lsort -stride errors} -returnCodes error -body {
+ lsort -stride foo bar
+} -result {expected integer but got "foo"}
+test cmdIL-1.33 {lsort -stride errors} -returnCodes error -body {
+ lsort -stride 1 bar
+} -result {stride length must be at least 2}
+test cmdIL-1.34 {lsort -stride errors} -returnCodes error -body {
+ lsort -stride 2 {a b c}
+} -result {list size must be a multiple of the stride length}
+test cmdIL-1.35 {lsort -stride errors} -returnCodes error -body {
+ lsort -stride 2 -index 3 {a b c d}
+} -result {when used with "-stride", the leading "-index" value must be within the group}
+test cmdIL-1.36 {lsort -stride and -index: Bug 2918962} {
+ lsort -stride 2 -index {0 1} {
+ {{c o d e} 54321} {{b l a h} 94729}
+ {{b i g} 12345} {{d e m o} 34512}
+ }
+} {{{b i g} 12345} {{d e m o} 34512} {{c o d e} 54321} {{b l a h} 94729}}
+
+# Can't think of any good tests for the MergeSort and MergeLists procedures,
+# except a bunch of random lists to sort.
+
+test cmdIL-2.1 {MergeSort and MergeLists procedures} -setup {
+ set result {}
+ set r 1435753299
+ proc rand {} {
+ global r
+ set r [expr {(16807 * $r) % (0x7fffffff)}]
+ }
+} -body {
+ for {set i 0} {$i < 150} {incr i} {
+ set x {}
+ for {set j 0} {$j < $i} {incr j} {
+ lappend x [expr {[rand] & 0xfff}]
+ }
+ set y [lsort -integer $x]
+ set old -1
+ foreach el $y {
+ if {$el < $old} {
+ append result "list {$x} sorted to {$y}, element $el out of order\n"
+ break
+ }
+ set old $el
+ }
+ }
+ string trim $result
+} -cleanup {
+ rename rand ""
+} -result {}
+
+test cmdIL-3.1 {SortCompare procedure, skip comparisons after error} -body {
+ set ::x 0
+ list [catch {
+ lsort -integer -command {apply {{a b} {
+ incr ::x
+ error "error #$::x"
+ }}} {48 6 28 190 16 2 3 6 1}
+ } msg] $msg $::x
+} -result {1 {error #1} 1}
+test cmdIL-3.2 {SortCompare procedure, -index option} -body {
+ lsort -integer -index 2 "\\\{ {30 40 50}"
+} -returnCodes error -result {unmatched open brace in list}
+test cmdIL-3.3 {SortCompare procedure, -index option} -body {
+ lsort -integer -index 2 {{20 10} {15 30 40}}
+} -returnCodes error -result {element 2 missing from sublist "20 10"}
+test cmdIL-3.4 {SortCompare procedure, -index option} -body {
+ lsort -integer -index 2 "{a b c} \\\{"
+} -returnCodes error -result {expected integer but got "c"}
+test cmdIL-3.4.1 {SortCompare procedure, -index option} -body {
+ lsort -integer -index 2 "{1 2 3} \\\{"
+} -returnCodes error -result {unmatched open brace in list}
+test cmdIL-3.5 {SortCompare procedure, -index option} -body {
+ lsort -integer -index 2 {{20 10 13} {15}}
+} -returnCodes error -result {element 2 missing from sublist "15"}
+test cmdIL-3.6 {SortCompare procedure, -index option} {
+ lsort -integer -index 2 {{1 15 30} {2 5 25} {3 25 20}}
+} {{3 25 20} {2 5 25} {1 15 30}}
+test cmdIL-3.7 {SortCompare procedure, -ascii option} {
+ lsort -ascii {d e c b a d35 d300 100 20}
+} {100 20 a b c d d300 d35 e}
+test cmdIL-3.8 {SortCompare procedure, -dictionary option} {
+ lsort -dictionary {d e c b a d35 d300 100 20}
+} {20 100 a b c d d35 d300 e}
+test cmdIL-3.9 {SortCompare procedure, -integer option} -body {
+ lsort -integer {x 3}
+} -returnCodes error -result {expected integer but got "x"}
+test cmdIL-3.10 {SortCompare procedure, -integer option} -body {
+ lsort -integer {3 q}
+} -returnCodes error -result {expected integer but got "q"}
+test cmdIL-3.11 {SortCompare procedure, -integer option} {
+ lsort -integer {35 21 0x20 30 0o23 100 8}
+} {8 0o23 21 30 0x20 35 100}
+test cmdIL-3.12 {SortCompare procedure, -real option} -body {
+ lsort -real {6...4 3}
+} -returnCodes error -result {expected floating-point number but got "6...4"}
+test cmdIL-3.13 {SortCompare procedure, -real option} -body {
+ lsort -real {3 1x7}
+} -returnCodes error -result {expected floating-point number but got "1x7"}
+test cmdIL-3.14 {SortCompare procedure, -real option} {
+ lsort -real {24 2.5e01 16.7 85e-1 10.004}
+} {85e-1 10.004 16.7 24 2.5e01}
+test cmdIL-3.15 {SortCompare procedure, -command option} -body {
+ proc cmp {a b} {
+ error "comparison error"
+ }
+ list [catch {lsort -command cmp {48 6}} msg] $msg $::errorInfo
+} -cleanup {
+ rename cmp ""
+} -result {1 {comparison error} {comparison error
+ while executing
+"error "comparison error""
+ (procedure "cmp" line 2)
+ invoked from within
+"cmp 48 6"
+ (-compare command)
+ invoked from within
+"lsort -command cmp {48 6}"}}
+test cmdIL-3.16 {SortCompare procedure, -command option, long command} -body {
+ proc cmp {dummy a b} {
+ string compare $a $b
+ }
+ lsort -command {cmp {this argument is very very long in order to make the dstring overflow its statically allocated space}} {{this first element is also long in order to help expand the dstring} {the second element, last but not least, is quite long also, in order to make absolutely sure that space is allocated dynamically for the dstring}}
+} -cleanup {
+ rename cmp ""
+} -result {{the second element, last but not least, is quite long also, in order to make absolutely sure that space is allocated dynamically for the dstring} {this first element is also long in order to help expand the dstring}}
+test cmdIL-3.17 {SortCompare procedure, -command option, non-integer result} -body {
+ proc cmp {a b} {
+ return foow
+ }
+ lsort -command cmp {48 6}
+} -returnCodes error -cleanup {
+ rename cmp ""
+} -result {-compare command returned non-integer result}
+test cmdIL-3.18 {SortCompare procedure, -command option} -body {
+ proc cmp {a b} {
+ expr {$b - $a}
+ }
+ lsort -command cmp {48 6 18 22 21 35 36}
+} -cleanup {
+ rename cmp ""
+} -result {48 36 35 22 21 18 6}
+test cmdIL-3.19 {SortCompare procedure, -decreasing option} {
+ lsort -decreasing -integer {35 21 0x20 30 0o23 100 8}
+} {100 35 0x20 30 21 0o23 8}
+
+test cmdIL-4.1 {DictionaryCompare procedure, numerics, leading zeros} {
+ lsort -dictionary {a003b a03b}
+} {a03b a003b}
+test cmdIL-4.2 {DictionaryCompare procedure, numerics, leading zeros} {
+ lsort -dictionary {a3b a03b}
+} {a3b a03b}
+test cmdIL-4.3 {DictionaryCompare procedure, numerics, leading zeros} {
+ lsort -dictionary {a3b A03b}
+} {A03b a3b}
+test cmdIL-4.4 {DictionaryCompare procedure, numerics, leading zeros} {
+ lsort -dictionary {a3b a03B}
+} {a3b a03B}
+test cmdIL-4.5 {DictionaryCompare procedure, numerics, leading zeros} {
+ lsort -dictionary {00000 000}
+} {000 00000}
+test cmdIL-4.6 {DictionaryCompare procedure, numerics, different lengths} {
+ lsort -dictionary {a321b a03210b}
+} {a321b a03210b}
+test cmdIL-4.7 {DictionaryCompare procedure, numerics, different lengths} {
+ lsort -dictionary {a03210b a321b}
+} {a321b a03210b}
+test cmdIL-4.8 {DictionaryCompare procedure, numerics} {
+ lsort -dictionary {48 6a 18b 22a 21aa 35 36}
+} {6a 18b 21aa 22a 35 36 48}
+test cmdIL-4.9 {DictionaryCompare procedure, numerics} {
+ lsort -dictionary {a123x a123b}
+} {a123b a123x}
+test cmdIL-4.10 {DictionaryCompare procedure, numerics} {
+ lsort -dictionary {a123b a123x}
+} {a123b a123x}
+test cmdIL-4.11 {DictionaryCompare procedure, numerics} {
+ lsort -dictionary {a1b aab}
+} {a1b aab}
+test cmdIL-4.12 {DictionaryCompare procedure, numerics} {
+ lsort -dictionary {a1b a!b}
+} {a!b a1b}
+test cmdIL-4.13 {DictionaryCompare procedure, numerics} {
+ lsort -dictionary {a1b2c a1b1c}
+} {a1b1c a1b2c}
+test cmdIL-4.14 {DictionaryCompare procedure, numerics} {
+ lsort -dictionary {a1b2c a1b3c}
+} {a1b2c a1b3c}
+test cmdIL-4.15 {DictionaryCompare procedure, long numbers} {
+ lsort -dictionary {a7654884321988762b a7654884321988761b}
+} {a7654884321988761b a7654884321988762b}
+test cmdIL-4.16 {DictionaryCompare procedure, long numbers} {
+ lsort -dictionary {a8765488432198876b a7654884321988761b}
+} {a7654884321988761b a8765488432198876b}
+test cmdIL-4.17 {DictionaryCompare procedure, case} {
+ lsort -dictionary {aBCd abcc}
+} {abcc aBCd}
+test cmdIL-4.18 {DictionaryCompare procedure, case} {
+ lsort -dictionary {aBCd abce}
+} {aBCd abce}
+test cmdIL-4.19 {DictionaryCompare procedure, case} {
+ lsort -dictionary {abcd ABcc}
+} {ABcc abcd}
+test cmdIL-4.20 {DictionaryCompare procedure, case} {
+ lsort -dictionary {abcd ABce}
+} {abcd ABce}
+test cmdIL-4.21 {DictionaryCompare procedure, case} {
+ lsort -dictionary {abCD ABcd}
+} {ABcd abCD}
+test cmdIL-4.22 {DictionaryCompare procedure, case} {
+ lsort -dictionary {ABcd aBCd}
+} {ABcd aBCd}
+test cmdIL-4.23 {DictionaryCompare procedure, case} {
+ lsort -dictionary {ABcd AbCd}
+} {ABcd AbCd}
+test cmdIL-4.24 {DictionaryCompare procedure, international characters} {hasIsoLocale} {
+ ::tcltest::set_iso8859_1_locale
+ set result [lsort -dictionary "a b c A B C \xe3 \xc4"]
+ ::tcltest::restore_locale
+ set result
+} "A a B b C c \xe3 \xc4"
+test cmdIL-4.25 {DictionaryCompare procedure, international characters} {hasIsoLocale} {
+ ::tcltest::set_iso8859_1_locale
+ set result [lsort -dictionary "a23\xe3 a23\xc5 a23\xe4"]
+ ::tcltest::restore_locale
+ set result
+} "a23\xe3 a23\xe4 a23\xc5"
+test cmdIL-4.26 {DefaultCompare procedure, signed characters} {
+ set l [lsort [list "abc\200" "abc"]]
+ set viewlist {}
+ foreach s $l {
+ set viewelem ""
+ set len [string length $s]
+ for {set i 0} {$i < $len} {incr i} {
+ set c [string index $s $i]
+ scan $c %c d
+ if {$d > 0 && $d < 128} {
+ append viewelem $c
+ } else {
+ append viewelem "\\[format %03o $d]"
+ }
+ }
+ lappend viewlist $viewelem
+ }
+ set viewlist
+} [list "abc" "abc\\200"]
+test cmdIL-4.27 {DictionaryCompare procedure, signed characters} {
+ set l [lsort -dictionary [list "abc\200" "abc"]]
+ set viewlist {}
+ foreach s $l {
+ set viewelem ""
+ set len [string length $s]
+ for {set i 0} {$i < $len} {incr i} {
+ set c [string index $s $i]
+ scan $c %c d
+ if {$d > 0 && $d < 128} {
+ append viewelem $c
+ } else {
+ append viewelem "\\[format %03o $d]"
+ }
+ }
+ lappend viewlist $viewelem
+ }
+ set viewlist
+} [list "abc" "abc\\200"]
+test cmdIL-4.28 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+ lsort -dictionary [list AA ` c CC]
+} [list ` AA c CC]
+test cmdIL-4.29 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+ lsort -dictionary [list AA ` c ^ \\ CC \[ \]]
+} [list \[ \\ \] ^ ` AA c CC]
+test cmdIL-4.30 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+ lsort -dictionary [list AA ` c ^ _ \\ CC \[ dude \] funky]
+} [list \[ \\ \] ^ _ ` AA c CC dude funky]
+test cmdIL-4.31 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+ lsort -dictionary [list AA c ` CC]
+} [list ` AA c CC]
+test cmdIL-4.32 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+ lsort -dictionary [list AA c CC `]
+} [list ` AA c CC]
+test cmdIL-4.33 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+ lsort -dictionary [list AA ! c CC `]
+} [list ! ` AA c CC]
+test cmdIL-4.34 {SortCompare procedure, -ascii option with -nocase option} {
+ lsort -ascii -nocase {d e c b a d35 d300 100 20}
+} {100 20 a b c d d300 d35 e}
+test cmdIL-4.35 {SortCompare procedure, -ascii option with -nocase option} {
+ lsort -ascii -nocase {d E c B a D35 d300 100 20}
+} {100 20 a B c d d300 D35 E}
+
+test cmdIL-5.1 {lsort with list style index} {
+ lsort -ascii -decreasing -index {0 1} {
+ {{Jim Alpha} 20000410}
+ {{Joe Bravo} 19990320}
+ {{Jacky Charlie} 19390911}
+ }
+} {{{Jacky Charlie} 19390911} {{Joe Bravo} 19990320} {{Jim Alpha} 20000410}}
+test cmdIL-5.2 {lsort with list style index} {
+ lsort -decreasing -index {0 1} {
+ {{Jim Alpha} 20000410}
+ {{Joe Bravo} 19990320}
+ {{Jacky Charlie} 19390911}
+ }
+} {{{Jacky Charlie} 19390911} {{Joe Bravo} 19990320} {{Jim Alpha} 20000410}}
+test cmdIL-5.3 {lsort with list style index} {
+ lsort -integer -increasing -index {1 end} {
+ {{Jim Alpha} 20000410}
+ {{Joe Bravo} 19990320}
+ {{Jacky Charlie} 19390911}
+ }
+} {{{Jacky Charlie} 19390911} {{Joe Bravo} 19990320} {{Jim Alpha} 20000410}}
+test cmdIL-5.4 {lsort with list style index} {
+ lsort -integer -index {1 end-1} {
+ {the {0 1 2 3 4 5} quick}
+ {brown {0 1 2 3 4} fox}
+ {jumps {30 31 2 33} over}
+ {the {0 1 2} lazy}
+ {dogs {0 1}}
+ }
+} {{dogs {0 1}} {the {0 1 2} lazy} {jumps {30 31 2 33} over} {brown {0 1 2 3 4} fox} {the {0 1 2 3 4 5} quick}}
+test cmdIL-5.5 {lsort with list style index and sharing} -body {
+ proc test_lsort {l} {
+ set n $l
+ foreach e $l {lappend n [list [expr {rand()}] $e]}
+ lindex [lsort -real -index $l $n] 1 1
+ }
+ expr srand(1)
+ test_lsort 0
+} -result 0 -cleanup {
+ rename test_lsort ""
+}
+test cmdIL-5.6 {lsort with multiple list-style index options} {
+ lsort -index {1 2 3} -index 0 {{a b} {c d} {b e}}
+} {{a b} {b e} {c d}}
+
+# Compiled version
+test cmdIL-6.1 {lassign command syntax} -returnCodes error -body {
+ apply {{} { lassign }}
+} -result {wrong # args: should be "lassign list ?varName ...?"}
+test cmdIL-6.2 {lassign command syntax} {
+ apply {{} { lassign x }}
+} x
+test cmdIL-6.3 {lassign command} -body {
+ apply {{} {
+ set x FAIL
+ list [lassign a x] $x
+ }}
+} -result {{} a}
+test cmdIL-6.4 {lassign command} -body {
+ apply {{} {
+ set x FAIL
+ set y FAIL
+ list [lassign a x y] $x $y
+ }}
+} -result {{} a {}}
+test cmdIL-6.5 {lassign command} -body {
+ apply {{} {
+ set x FAIL
+ set y FAIL
+ list [lassign {a b} x y] $x $y
+ }}
+} -result {{} a b}
+test cmdIL-6.6 {lassign command} -body {
+ apply {{} {
+ set x FAIL
+ set y FAIL
+ list [lassign {a b c} x y] $x $y
+ }}
+} -result {c a b}
+test cmdIL-6.7 {lassign command} -body {
+ apply {{} {
+ set x FAIL
+ set y FAIL
+ list [lassign {a b c d} x y] $x $y
+ }}
+} -result {{c d} a b}
+test cmdIL-6.8 {lassign command - list format error} -body {
+ apply {{} {
+ set x FAIL
+ set y FAIL
+ list [catch {lassign {a {b}c d} x y} msg] $msg $x $y
+ }}
+} -result {1 {list element in braces followed by "c" instead of space} FAIL FAIL}
+test cmdIL-6.9 {lassign command - assignment to arrays} -body {
+ apply {{} {
+ list [lassign {a b} x(x)] $x(x)
+ }}
+} -result {b a}
+test cmdIL-6.10 {lassign command - variable update error} -body {
+ apply {{} {
+ set x(x) {}
+ lassign a x
+ }}
+} -returnCodes error -result {can't set "x": variable is array}
+test cmdIL-6.11 {lassign command - variable update error} -body {
+ apply {{} {
+ set x(x) {}
+ set y FAIL
+ list [catch {lassign a y x} msg] $msg $y
+ }}
+} -result {1 {can't set "x": variable is array} a}
+test cmdIL-6.12 {lassign command - memory leak testing} -setup {
+ unset -nocomplain x y
+ set x(x) {}
+ set y FAIL
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex [lindex $lines 3] 3
+ }
+ proc stress {} {
+ global x y
+ lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y
+ catch {lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y x}
+ catch {lassign {} x}
+ }
+} -constraints memory -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ stress
+ set tmp $end
+ set end [getbytes]
+ }
+ expr {$end - $tmp}
+} -result 0 -cleanup {
+ unset -nocomplain x y i tmp end
+ rename getbytes {}
+ rename stress {}
+}
+# Force non-compiled version
+test cmdIL-6.13 {lassign command syntax} -returnCodes error -body {
+ apply {{} {
+ set lassign lassign
+ $lassign
+ }}
+} -result {wrong # args: should be "lassign list ?varName ...?"}
+test cmdIL-6.14 {lassign command syntax} {
+ apply {{} {
+ set lassign lassign
+ $lassign x
+ }}
+} x
+test cmdIL-6.15 {lassign command} -body {
+ apply {{} {
+ set lassign lassign
+ set x FAIL
+ list [$lassign a x] $x
+ }}
+} -result {{} a}
+test cmdIL-6.16 {lassign command} -body {
+ apply {{} {
+ set lassign lassign
+ set x FAIL
+ set y FAIL
+ list [$lassign a x y] $x $y
+ }}
+} -result {{} a {}}
+test cmdIL-6.17 {lassign command} -body {
+ apply {{} {
+ set lassign lassign
+ set x FAIL
+ set y FAIL
+ list [$lassign {a b} x y] $x $y
+ }}
+} -result {{} a b}
+test cmdIL-6.18 {lassign command} -body {
+ apply {{} {
+ set lassign lassign
+ set x FAIL
+ set y FAIL
+ list [$lassign {a b c} x y] $x $y
+ }}
+} -result {c a b}
+test cmdIL-6.19 {lassign command} -body {
+ apply {{} {
+ set lassign lassign
+ set x FAIL
+ set y FAIL
+ list [$lassign {a b c d} x y] $x $y
+ }}
+} -result {{c d} a b}
+test cmdIL-6.20 {lassign command - list format error} -body {
+ apply {{} {
+ set lassign lassign
+ set x FAIL
+ set y FAIL
+ list [catch {$lassign {a {b}c d} x y} msg] $msg $x $y
+ }}
+} -result {1 {list element in braces followed by "c" instead of space} FAIL FAIL}
+test cmdIL-6.21 {lassign command - assignment to arrays} -body {
+ apply {{} {
+ set lassign lassign
+ list [$lassign {a b} x(x)] $x(x)
+ }}
+} -result {b a}
+test cmdIL-6.22 {lassign command - variable update error} -body {
+ apply {{} {
+ set lassign lassign
+ set x(x) {}
+ $lassign a x
+ }}
+} -returnCodes 1 -result {can't set "x": variable is array}
+test cmdIL-6.23 {lassign command - variable update error} -body {
+ apply {{} {
+ set lassign lassign
+ set x(x) {}
+ set y FAIL
+ list [catch {$lassign a y x} msg] $msg $y
+ }}
+} -result {1 {can't set "x": variable is array} a}
+test cmdIL-6.24 {lassign command - memory leak testing} -setup {
+ set x(x) {}
+ set y FAIL
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex [lindex $lines 3] 3
+ }
+ proc stress {} {
+ global x y
+ set lassign lassign
+ $lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y
+ catch {$lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y x}
+ catch {$lassign {} x}
+ }
+} -constraints memory -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ stress
+ set tmp $end
+ set end [getbytes]
+ }
+ expr {$end - $tmp}
+} -result 0 -cleanup {
+ unset -nocomplain x y i tmp end
+ rename getbytes {}
+ rename stress {}
+}
+# Assorted shimmering problems
+test cmdIL-6.25 {lassign command - shimmering protection} -body {
+ apply {{} {
+ set x {a b c}
+ list [lassign $x $x y] $x [set $x] $y
+ }}
+} -result {c {a b c} a b}
+test cmdIL-6.26 {lassign command - shimmering protection} -body {
+ apply {{} {
+ set x {a b c}
+ set lassign lassign
+ list [$lassign $x $x y] $x [set $x] $y
+ }}
+} -result {c {a b c} a b}
+
+test cmdIL-7.1 {lreverse command} -body {
+ lreverse
+} -returnCodes error -result "wrong # args: should be \"lreverse list\""
+test cmdIL-7.2 {lreverse command} -body {
+ lreverse a b
+} -returnCodes error -result "wrong # args: should be \"lreverse list\""
+test cmdIL-7.3 {lreverse command} -body {
+ lreverse "not \{a list"
+} -returnCodes error -result {unmatched open brace in list}
+test cmdIL-7.4 {lreverse command - shared object} {
+ set x {a b {c d} e f}
+ lreverse $x
+} {f e {c d} b a}
+test cmdIL-7.5 {lreverse command - unshared object} {
+ lreverse [list a b {c d} e f]
+} {f e {c d} b a}
+test cmdIL-7.6 {lreverse command - unshared object [Bug 1672585]} {
+ lreverse [set x {1 2 3}][unset x]
+} {3 2 1}
+test cmdIL-7.7 {lreverse command - empty object [Bug 1876793]} {
+ lreverse [list]
+} {}
+test cmdIL-7.8 {lreverse command - shared intrep [Bug 1675044]} -setup {
+ teststringobj set 1 {1 2 3}
+ testobj convert 1 list
+ testobj duplicate 1 2
+ variable x [teststringobj get 1]
+ variable y [teststringobj get 2]
+ testobj freeallvars
+ proc K {a b} {return $a}
+} -constraints testobj -body {
+ lreverse [K $y [unset y]]
+ lindex $x 0
+} -cleanup {
+ unset -nocomplain x y
+ rename K {}
+} -result 1
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/cmdInfo.test b/library/msgcat/tests/cmdInfo.test
new file mode 100644
index 0000000..86aa6e1
--- /dev/null
+++ b/library/msgcat/tests/cmdInfo.test
@@ -0,0 +1,106 @@
+# Commands covered: none
+#
+# This file contains a collection of tests for Tcl_GetCommandInfo,
+# Tcl_SetCommandInfo, Tcl_CreateCommand, Tcl_DeleteCommand, and
+# Tcl_NameOfCommand. Sourcing this file into Tcl runs the tests
+# and generates output for errors. No output means no errors were
+# found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testcmdinfo [llength [info commands testcmdinfo]]
+testConstraint testcmdtoken [llength [info commands testcmdtoken]]
+
+test cmdinfo-1.1 {command procedure and clientData} {testcmdinfo} {
+ testcmdinfo create x1
+ testcmdinfo get x1
+} {CmdProc1 original CmdDelProc1 original :: stringProc}
+test cmdinfo-1.2 {command procedure and clientData} {testcmdinfo} {
+ testcmdinfo create x1
+ x1
+} {CmdProc1 original}
+test cmdinfo-1.3 {command procedure and clientData} {testcmdinfo} {
+ testcmdinfo create x1
+ testcmdinfo modify x1
+ testcmdinfo get x1
+} {CmdProc2 new_command_data CmdDelProc2 new_delete_data :: stringProc}
+test cmdinfo-1.4 {command procedure and clientData} {testcmdinfo} {
+ testcmdinfo create x1
+ testcmdinfo modify x1
+ x1
+} {CmdProc2 new_command_data}
+
+test cmdinfo-2.1 {command deletion callbacks} {testcmdinfo} {
+ testcmdinfo create x1
+ testcmdinfo delete x1
+} {CmdDelProc1 original}
+test cmdinfo-2.2 {command deletion callbacks} {testcmdinfo} {
+ testcmdinfo create x1
+ testcmdinfo modify x1
+ testcmdinfo delete x1
+} {CmdDelProc2 new_delete_data}
+
+test cmdinfo-3.1 {Tcl_Get/SetCommandInfo return values} {testcmdinfo} {
+ testcmdinfo get non_existent
+} {??}
+test cmdinfo-3.2 {Tcl_Get/SetCommandInfo return values} {testcmdinfo} {
+ testcmdinfo create x1
+ testcmdinfo modify x1
+} 1
+test cmdinfo-3.3 {Tcl_Get/SetCommandInfo return values} {testcmdinfo} {
+ testcmdinfo modify non_existent
+} 0
+
+test cmdinfo-4.1 {Tcl_GetCommandName/Tcl_GetCommandFullName procedures} \
+ {testcmdtoken} {
+ set x [testcmdtoken create x1]
+ rename x1 newName
+ set y [testcmdtoken name $x]
+ rename newName x1
+ lappend y {*}[testcmdtoken name $x]
+} {newName ::newName x1 ::x1}
+
+catch {rename newTestCmd {}}
+catch {rename newTestCmd2 {}}
+
+test cmdinfo-5.1 {Names for commands created when inside namespaces} \
+ {testcmdtoken} {
+ # create namespace cmdInfoNs1
+ namespace eval cmdInfoNs1 {} ;# creates namespace cmdInfoNs1
+ # create namespace cmdInfoNs1::cmdInfoNs2 and execute a script in it
+ set x [namespace eval cmdInfoNs1::cmdInfoNs2 {
+ # the following creates a cmd in the global namespace
+ testcmdtoken create testCmd
+ }]
+ set y [testcmdtoken name $x]
+ rename ::testCmd newTestCmd
+ lappend y {*}[testcmdtoken name $x]
+} {testCmd ::testCmd newTestCmd ::newTestCmd}
+
+test cmdinfo-6.1 {Names for commands created when outside namespaces} \
+ {testcmdtoken} {
+ set x [testcmdtoken create cmdInfoNs1::cmdInfoNs2::testCmd]
+ set y [testcmdtoken name $x]
+ rename cmdInfoNs1::cmdInfoNs2::testCmd newTestCmd2
+ lappend y {*}[testcmdtoken name $x]
+} {testCmd ::cmdInfoNs1::cmdInfoNs2::testCmd newTestCmd2 ::newTestCmd2}
+
+# cleanup
+catch {namespace delete cmdInfoNs1::cmdInfoNs2 cmdInfoNs1}
+catch {rename x1 ""}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/cmdMZ.test b/library/msgcat/tests/cmdMZ.test
new file mode 100644
index 0000000..2d68138
--- /dev/null
+++ b/library/msgcat/tests/cmdMZ.test
@@ -0,0 +1,355 @@
+# The tests in this file cover the procedures in tclCmdMZ.c.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[catch {package require tcltest 2.1}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2.1 required."
+ return
+}
+
+namespace eval ::tcl::test::cmdMZ {
+ namespace import ::tcltest::cleanupTests
+ namespace import ::tcltest::customMatch
+ namespace import ::tcltest::makeFile
+ namespace import ::tcltest::removeFile
+ namespace import ::tcltest::temporaryDirectory
+ namespace import ::tcltest::test
+
+ proc ListGlobMatch {expected actual} {
+ if {[llength $expected] != [llength $actual]} {
+ return 0
+ }
+ foreach e $expected a $actual {
+ if {![string match $e $a]} {
+ return 0
+ }
+ }
+ return 1
+ }
+ customMatch listGlob [namespace which ListGlobMatch]
+
+# Tcl_PwdObjCmd
+
+test cmdMZ-1.1 {Tcl_PwdObjCmd} -returnCodes error -body {
+ pwd a
+} -result {wrong # args: should be "pwd"}
+test cmdMZ-1.2 {Tcl_PwdObjCmd: simple pwd} {
+ catch pwd
+} 0
+test cmdMZ-1.3 {Tcl_PwdObjCmd: simple pwd} -body {
+ pwd
+} -match glob -result {?*}
+test cmdMZ-1.4 {Tcl_PwdObjCmd: failure} -setup {
+ set cwd [pwd]
+ set foodir [file join [temporaryDirectory] foo]
+ file delete -force $foodir
+ file mkdir $foodir
+ cd $foodir
+} -constraints {unix nonPortable} -body {
+ # This test fails on various unix platforms (eg Linux) where permissions
+ # caching causes this to fail. The caching is strictly incorrect, but we
+ # have no control over that.
+ file attr . -permissions 000
+ pwd
+} -returnCodes error -cleanup {
+ cd $cwd
+ file delete -force $foodir
+} -result {error getting working directory name: permission denied}
+
+# The tests for Tcl_RegexpObjCmd, Tcl_RegsubObjCmd are in regexp.test
+
+# Tcl_RenameObjCmd
+
+test cmdMZ-2.1 {Tcl_RenameObjCmd: error conditions} -returnCodes error -body {
+ rename r1
+} -result {wrong # args: should be "rename oldName newName"}
+test cmdMZ-2.2 {Tcl_RenameObjCmd: error conditions} -returnCodes error -body {
+ rename r1 r2 r3
+} -result {wrong # args: should be "rename oldName newName"}
+test cmdMZ-2.3 {Tcl_RenameObjCmd: success} -setup {
+ catch {rename r2 {}}
+} -body {
+ proc r1 {} {return "r1"}
+ rename r1 r2
+ r2
+} -result {r1}
+test cmdMZ-2.4 {Tcl_RenameObjCmd: success} {
+ proc r1 {} {return "r1"}
+ rename r1 {}
+ list [catch {r1} msg] $msg
+} {1 {invalid command name "r1"}}
+
+# Some tests for Tcl_ReturnObjCmd are in proc-old.test
+
+test cmdMZ-return-1.0 {return checks for bad option values} -body {
+ return -options foo
+} -returnCodes error -match glob -result {bad -options value:*}
+test cmdMZ-return-1.1 {return checks for bad option values} -body {
+ return -code err
+} -returnCodes error -match glob -result {bad completion code "err": must be ok, error, return, break, continue*, or an integer}
+test cmdMZ-return-1.2 {return checks for bad option values} -body {
+ return -code 0x100000000
+} -returnCodes error -match glob -result {bad completion code "0x100000000": must be ok, error, return, break, continue*, or an integer}
+test cmdMZ-return-1.3 {return checks for bad option values} -body {
+ return -level foo
+} -returnCodes error -match glob -result {bad -level value: *}
+test cmdMZ-return-1.4 {return checks for bad option values} -body {
+ return -level -1
+} -returnCodes error -match glob -result {bad -level value: *}
+test cmdMZ-return-1.5 {return checks for bad option values} -body {
+ return -level 3.1415926
+} -returnCodes error -match glob -result {bad -level value: *}
+
+proc dictSort {d} {
+ set result {}
+ foreach k [lsort [dict keys $d]] {
+ dict set result $k [dict get $d $k]
+ }
+ return $result
+}
+
+test cmdMZ-return-2.0 {return option handling} {
+ list [catch return -> foo] [dictSort $foo]
+} {2 {-code 0 -level 1}}
+test cmdMZ-return-2.1 {return option handling} {
+ list [catch {return -bar soom} -> foo] [dictSort $foo]
+} {2 {-bar soom -code 0 -level 1}}
+test cmdMZ-return-2.2 {return option handling} {
+ list [catch {return -code return} -> foo] [dictSort $foo]
+} {2 {-code 0 -level 2}}
+test cmdMZ-return-2.3 {return option handling} {
+ list [catch {return -code return -level 10} -> foo] [dictSort $foo]
+} {2 {-code 0 -level 11}}
+test cmdMZ-return-2.4 {return option handling} -body {
+ return -level 0 -code error
+} -returnCodes error -result {}
+test cmdMZ-return-2.5 {return option handling} -body {
+ return -level 0 -code return
+} -returnCodes return -result {}
+test cmdMZ-return-2.6 {return option handling} -body {
+ return -level 0 -code break
+} -returnCodes break -result {}
+test cmdMZ-return-2.7 {return option handling} -body {
+ return -level 0 -code continue
+} -returnCodes continue -result {}
+test cmdMZ-return-2.8 {return option handling} -body {
+ return -level 0 -code -1
+} -returnCodes -1 -result {}
+test cmdMZ-return-2.9 {return option handling} -body {
+ return -level 0 -code 10
+} -returnCodes 10 -result {}
+test cmdMZ-return-2.10 {return option handling} -body {
+ list [catch {return -level 0 -code error} -> foo] [dictSort $foo]
+} -match glob -result {1 {-code 1 -errorcode NONE -errorinfo {
+ while executing
+"return -level 0 -code error"} -errorline 1 -errorstack * -level 0}}
+test cmdMZ-return-2.11 {return option handling} {
+ list [catch {return -level 0 -code break} -> foo] [dictSort $foo]
+} {3 {-code 3 -level 0}}
+test cmdMZ-return-2.12 {return option handling} -body {
+ return -level 0 -code error -options {-code ok}
+} -returnCodes ok -result {}
+test cmdMZ-return-2.13 {return option handling} -body {
+ return -level 0 -code error -options {-code err}
+} -returnCodes error -match glob -result {bad completion code "err": must be ok, error, return, break, continue*, or an integer}
+test cmdMZ-return-2.14 {return option handling} -body {
+ return -level 0 -code error -options {-code foo -options {-code break}}
+} -returnCodes break -result {}
+test cmdMZ-return-2.15 {return opton handling} {
+ list [catch {
+ apply {{} {
+ return -code error -errorcode {a b} c
+ }}
+ } result] $result $::errorCode
+} {1 c {a b}}
+test cmdMZ-return-2.16 {return opton handling} {
+ list [catch {
+ apply {{} {
+ return -code error -errorcode [list a b] c
+ }}
+ } result] $result $::errorCode
+} {1 c {a b}}
+test cmdMZ-return-2.17 {return opton handling} {
+ list [catch {
+ apply {{} {
+ return -code error -errorcode a\ b c
+ }}
+ } result] $result $::errorCode
+} {1 c {a b}}
+test cmdMZ-return-2.18 {return option handling} {
+ list [catch {
+ return -code error -errorstack [list CALL a CALL b] yo
+ } -> foo] [dictSort $foo] [info errorstack]
+} {2 {-code 1 -errorcode NONE -errorstack {CALL a CALL b} -level 1} {CALL a CALL b}}
+
+# Check that the result of a [return -options $opts $result] is
+# indistinguishable from that of the originally caught script, no matter what
+# the script is/does. (TIP 90)
+foreach {testid script} {
+ cmdMZ-return-3.0 {}
+ cmdMZ-return-3.1 {format x}
+ cmdMZ-return-3.2 {set}
+ cmdMZ-return-3.3 {set a 1}
+ cmdMZ-return-3.4 {error}
+ cmdMZ-return-3.5 {error foo}
+ cmdMZ-return-3.6 {error foo bar}
+ cmdMZ-return-3.7 {error foo bar baz}
+ cmdMZ-return-3.8 {return -level 0}
+ cmdMZ-return-3.9 {return -code error}
+ cmdMZ-return-3.10 {return -code error -errorinfo foo}
+ cmdMZ-return-3.11 {return -code error -errorinfo foo -errorcode bar}
+ cmdMZ-return-3.12 {return -code error -errorinfo foo -errorcode bar -errorline 10}
+ cmdMZ-return-3.12.1 {return -code error -errorinfo foo -errorcode bar -errorline 10 -errorstack baz}
+ cmdMZ-return-3.13 {return -options {x y z 2}}
+ cmdMZ-return-3.14 {return -level 3 -code break sdf}
+} {
+ test $testid "check that return after a catch is same:\n$script" {
+ set one [list [catch $script foo bar] $foo [dictSort $bar] \
+ $::errorCode $::errorInfo]
+ set two [list [catch {return -options $bar $foo} foo2 bar2] \
+ $foo2 [dictSort $bar2] $::errorCode $::errorInfo]
+ string equal $one $two
+ } 1
+}
+
+# The tests for Tcl_ScanObjCmd are in scan.test
+
+# Tcl_SourceObjCmd
+# More tests of Tcl_SourceObjCmd are in source.test
+
+test cmdMZ-3.3 {Tcl_SourceObjCmd: error conditions} -constraints {
+ unixOrPc
+} -returnCodes error -body {
+ source
+} -match glob -result {wrong # args: should be "source*fileName"}
+test cmdMZ-3.4 {Tcl_SourceObjCmd: error conditions} -constraints {
+ unixOrPc
+} -returnCodes error -body {
+ source a b
+} -match glob -result {wrong # args: should be "source*fileName"}
+test cmdMZ-3.5 {Tcl_SourceObjCmd: error in script} -body {
+ set file [makeFile {
+ set x 146
+ error "error in sourced file"
+ set y $x
+ } source.file]
+ list [catch {source $file} msg] $msg $::errorInfo
+} -cleanup {
+ removeFile source.file
+} -match listGlob -result {1 {error in sourced file} {error in sourced file
+ while executing
+"error "error in sourced file""
+ (file "*" line 3)
+ invoked from within
+"source $file"}}
+test cmdMZ-3.6 {Tcl_SourceObjCmd: simple script} -body {
+ set file [makeFile {list ok} source.file]
+ source $file
+} -cleanup {
+ removeFile source.file
+} -result ok
+
+# Tcl_SplitObjCmd
+
+test cmdMZ-4.1 {Tcl_SplitObjCmd: split errors} -returnCodes error -body {
+ split
+} -result {wrong # args: should be "split string ?splitChars?"}
+test cmdMZ-4.2 {Tcl_SplitObjCmd: split errors} -returnCodes error -body {
+ split a b c
+} -result {wrong # args: should be "split string ?splitChars?"}
+test cmdMZ-4.3 {Tcl_SplitObjCmd: basic split commands} {
+ split "a\n b\t\r c\n "
+} {a {} b {} {} c {} {}}
+test cmdMZ-4.4 {Tcl_SplitObjCmd: basic split commands} {
+ split "word 1xyzword 2zword 3" xyz
+} {{word 1} {} {} {word 2} {word 3}}
+test cmdMZ-4.5 {Tcl_SplitObjCmd: basic split commands} {
+ split "12345" {}
+} {1 2 3 4 5}
+test cmdMZ-4.6 {Tcl_SplitObjCmd: basic split commands} {
+ split "a\}b\[c\{\]\$"
+} "a\\\}b\\\[c\\\{\\\]\\\$"
+test cmdMZ-4.7 {Tcl_SplitObjCmd: basic split commands} {
+ split {} {}
+} {}
+test cmdMZ-4.8 {Tcl_SplitObjCmd: basic split commands} {
+ split {}
+} {}
+test cmdMZ-4.9 {Tcl_SplitObjCmd: basic split commands} {
+ split { }
+} {{} {} {} {}}
+test cmdMZ-4.10 {Tcl_SplitObjCmd: basic split commands} {
+ apply {{} {
+ set x {}
+ foreach f [split {]\n} {}] {
+ append x $f
+ }
+ return $x
+ }}
+} {]\n}
+test cmdMZ-4.11 {Tcl_SplitObjCmd: basic split commands} {
+ apply {{} {
+ set x ab\000c
+ set y [split $x {}]
+ binary scan $y c* z
+ return $z
+ }}
+} {97 32 98 32 0 32 99}
+test cmdMZ-4.12 {Tcl_SplitObjCmd: basic split commands} {
+ split "a0ab1b2bbb3\000c4" ab\000c
+} {{} 0 {} 1 2 {} {} 3 {} 4}
+test cmdMZ-4.13 {Tcl_SplitObjCmd: basic split commands} {
+ # if not UTF-8 aware, result is "a {} {} b qw\xe5 {} N wq"
+ split "a\u4e4eb qw\u5e4e\x4e wq" " \u4e4e"
+} "a b qw\u5e4eN wq"
+
+# The tests for Tcl_StringObjCmd are in string.test
+# The tests for Tcl_SubstObjCmd are in subst.test
+# The tests for Tcl_SwitchObjCmd are in switch.test
+
+test cmdMZ-5.1 {Tcl_TimeObjCmd: basic format of command} -body {
+ time
+} -returnCodes error -result {wrong # args: should be "time command ?count?"}
+test cmdMZ-5.2 {Tcl_TimeObjCmd: basic format of command} -body {
+ time a b c
+} -returnCodes error -result {wrong # args: should be "time command ?count?"}
+test cmdMZ-5.3 {Tcl_TimeObjCmd: basic format of command} -body {
+ time a b
+} -returnCodes error -result {expected integer but got "b"}
+test cmdMZ-5.4 {Tcl_TimeObjCmd: nothing happens with negative iteration counts} {
+ time bogusCmd -12456
+} {0 microseconds per iteration}
+test cmdMZ-5.5 {Tcl_TimeObjCmd: result format} -body {
+ time {format 1}
+} -match regexp -result {^\d+ microseconds per iteration}
+test cmdMZ-5.6 {Tcl_TimeObjCmd: slower commands take longer} {
+ expr {[lindex [time {after 2}] 0] < [lindex [time {after 1000}] 0]}
+} 1
+test cmdMZ-5.7 {Tcl_TimeObjCmd: errors generate right trace} {
+ list [catch {time {error foo}} msg] $msg $::errorInfo
+} {1 foo {foo
+ while executing
+"error foo"
+ invoked from within
+"time {error foo}"}}
+
+# The tests for Tcl_WhileObjCmd are in while.test
+
+# cleanup
+cleanupTests
+}
+namespace delete ::tcl::test::cmdMZ
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/compExpr-old.test b/library/msgcat/tests/compExpr-old.test
new file mode 100644
index 0000000..bb19151
--- /dev/null
+++ b/library/msgcat/tests/compExpr-old.test
@@ -0,0 +1,674 @@
+# Commands covered: expr
+#
+# This file contains the original set of tests for the compilation (and
+# indirectly execution) of Tcl's expr command. A new set of tests covering
+# the new implementation are in the files "parseExpr.test" and
+# "compExpr.test". Sourcing this file into Tcl runs the tests and generates
+# output for errors. No output means no errors were found.
+#
+# Copyright (c) 1996-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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+if {[catch {expr T1()} msg] && $msg eq {invalid command name "tcl::mathfunc::T1"}} {
+ testConstraint testmathfunctions 0
+} else {
+ testConstraint testmathfunctions 1
+}
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+ variable ieeeValues
+ binary scan [binary format dd -1.0 1.0] c* c
+ switch -exact -- $c {
+ {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+ # little endian
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+ ieeeValues(-Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+ ieeeValues(-Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+ ieeeValues(-Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+ ieeeValues(+Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+ ieeeValues(+Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 1
+ return 1
+ }
+ {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+ binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Infinity)
+ binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Normal)
+ binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Subnormal)
+ binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Normal)
+ binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Infinity)
+ binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 0
+ return 1
+ }
+ default {
+ return 0
+ }
+ }
+}
+testConstraint ieeeFloatingPoint [testIEEE]
+
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}]
+
+# procedures used below
+
+proc put_hello_char {c} {
+ global a
+ append a [format %c $c]
+ return $c
+}
+proc hello_world {} {
+ global a
+ set a ""
+ set L1 [set l0 [set h_1 [set q 0]]]
+ for {put_hello_char [expr [put_hello_char [expr [set h 7]*10+2]]+29]} {$l0?[put_hello_char $l0]
+ :!$h_1} {put_hello_char $ll;expr {$L1==2?[set ll [expr 32+0-0+[set bar 0]]]:0}} {expr {[incr L1]==[expr 1+([string length "abc"]-[string length "abc"])]
+ ?[set ll [set l0 [expr 54<<1]]]:$ll==108&&$L1<3?
+ [incr ll [expr 1|1<<1]; set ll $ll; set ll $ll; set ll $ll; set ll $ll; set l0 [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]; set l0; set l0 $l0; set l0; set l0]:$L1==4&&$ll==32?[set ll [expr 19+$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+[set foo [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]]]]
+ :[set q [expr $q-$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]};expr {$L1==5?[incr ll -8; set ll $ll; set ll]:$q&&$h1&&1};expr {$L1==4+2
+ ?[incr ll 3]:[expr ([string length "abc"]-[string length "abc"])+1]};expr {$ll==($h<<4)+2+0&&$L1!=6?[incr ll -6]:[set h1 [expr 100+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]}
+ expr {$L1!=1<<3?[incr q [expr ([string length "abc"]-[string length "abc"])-1]]:[set h_1 [set ll $h1]]}
+ }
+ set a
+}
+
+proc 12days {a b c} {
+ global xxx
+ expr {1<$a?[expr {$a<3?[12days -79 -13 [string range $c [12days -87 \
+ [expr 1-$b] [string range $c [12days -86 0 [string range $c 1 end]] \
+ end]] end]]:1};expr {$a<$b?[12days [expr $a+1] $b $c]:3};expr {[12days \
+ -94 [expr $a-27] $c]&&$a==2?$b<13?[12days 2 [expr $b+1] "%s %d %d\n"]:9
+ :16}]:$a<0?$a<-72?[12days $b $a "@n'+,#'/*\{\}w+/w#cdnr/+,\{\}r/*de\}+,/*\{*+,/w\{%+,/w#q#n+,/#\{l+,/n\{n+,/+#n+,/#;#q#n+,/+k#;*+,/'r :'d*'3,\}\{w+K w'K:'+\}e#';dq#'l q#'+d'K#!/+k#;q#'r\}eKK#\}w'r\}eKK\{nl\]'/#;#q#n')\{)#\}w')\{)\{nl\]'/+#n';d\}rw' i;# )\{nl\]!/n\{n#'; r\{#w'r nc\{nl\]'/#\{l,+'K \{rw' iK\{;\[\{nl\]'/w#q#n'wk nw' iwk\{KK\{nl\]!/w\{%'l##w#' i; :\{nl\]'/*\{q#'ld;r'\}\{nlwb!/*de\}'c ;;\{nl'-\{\}rw\]'/+,\}##'*\}#nc,',#nw\]'/+kd'+e\}+;#'rdq#w! nr'/ ') \}+\}\{rl#'\{n' ')# \}'+\}##(!!/"]
+ :$a<-50?[string compare [format %c $b] [string index $c 0]]==0?[append \
+ xxx [string index $c 31];scan [string index $c 31] %c x;set x]
+ :[12days -65 $b [string range $c 1 end]]:[12days [expr ([string compare \
+ [string index $c 0] "/"]==0)+$a] $b [string range $c 1 end]]:0<$a
+ ?[12days 2 2 "%s"]:[string compare [string index $c 0] "/"]==0||
+ [12days 0 [12days -61 [scan [string index $c 0] %c x; set x] \
+ "!ek;dc i@bK'(q)-\[w\]*%n+r3#l,\{\}:\nuwloca-O;m .vpbks,fxntdCeghiry"] \
+ [string range $c 1 end]]}
+}
+proc do_twelve_days {} {
+ global xxx
+ set xxx ""
+ 12days 1 1 1
+ set result [string length $xxx]
+ unset xxx
+ return $result
+}
+
+# start of tests
+
+catch {unset a b i x}
+
+test compExpr-old-1.1 {TclCompileExprCmd: no expression} {
+ list [catch {expr } msg] $msg
+} {1 {wrong # args: should be "expr arg ?arg ...?"}}
+test compExpr-old-1.2 {TclCompileExprCmd: one expression word} {
+ expr -25
+} -25
+test compExpr-old-1.3 {TclCompileExprCmd: two expression words} {
+ expr -8.2 -6
+} -14.2
+test compExpr-old-1.4 {TclCompileExprCmd: five expression words} {
+ expr 20 - 5 +10 -7
+} 18
+test compExpr-old-1.5 {TclCompileExprCmd: quoted expression word} {
+ expr "0005"
+} 5
+test compExpr-old-1.6 {TclCompileExprCmd: quoted expression word} {
+ catch {expr "0005"zxy} msg
+ set msg
+} {extra characters after close-quote}
+test compExpr-old-1.7 {TclCompileExprCmd: expression word in braces} {
+ expr {-0005}
+} -5
+test compExpr-old-1.8 {TclCompileExprCmd: expression word in braces} {
+ expr {{-0x1234}}
+} -4660
+test compExpr-old-1.9 {TclCompileExprCmd: expression word in braces} {
+ catch {expr {-0005}foo} msg
+ set msg
+} {extra characters after close-brace}
+test compExpr-old-1.10 {TclCompileExprCmd: other expression word in braces} {
+ expr 4*[llength "6 2"]
+} 8
+test compExpr-old-1.11 {TclCompileExprCmd: expression word terminated by ;} {
+ expr 4*[llength "6 2"];
+} 8
+test compExpr-old-1.12 {TclCompileExprCmd: inlined expr (in "catch") inside other catch} {
+ set a xxx
+ catch {
+ # Might not be a number
+ set a [expr 10*$a]
+ }
+} 1
+test compExpr-old-1.13 {TclCompileExprCmd: second level of substitutions in expr not in braces with single var reference} {
+ set a xxx
+ set x 27; set bool {$x}; if $bool {set a foo}
+ set a
+} foo
+test compExpr-old-1.14 {TclCompileExprCmd: second level of substitutions in expr with comparison as top-level operator} {
+ set a xxx
+ set x 2; set b {$x}; set a [expr $b == 2]
+ set a
+} 1
+
+test compExpr-old-2.1 {TclCompileExpr: are builtin functions registered?} {
+ expr double(5*[llength "6 2"])
+} 10.0
+test compExpr-old-2.2 {TclCompileExpr: error in expr} -body {
+ expr 2***3
+} -returnCodes error -match glob -result *
+test compExpr-old-2.3 {TclCompileExpr: junk after legal expr} -body {
+ expr 7*[llength "a b"]foo
+} -returnCodes error -match glob -result *
+test compExpr-old-2.4 {TclCompileExpr: numeric expr string rep == formatted int rep} {
+ expr {0001}
+} 1
+
+test compExpr-old-3.1 {CompileCondExpr: just lor expr} {expr 3||0} 1
+test compExpr-old-3.2 {CompileCondExpr: error in lor expr} -body {
+ expr x||3
+} -returnCodes error -match glob -result *
+test compExpr-old-3.3 {CompileCondExpr: test true arm} {expr 3>2?44:66} 44
+test compExpr-old-3.4 {CompileCondExpr: error compiling true arm} -body {
+ expr 3>2?2***3:66
+} -returnCodes error -match glob -result *
+test compExpr-old-3.5 {CompileCondExpr: test false arm} {expr 2>3?44:66} 66
+test compExpr-old-3.6 {CompileCondExpr: error compiling false arm} -body {
+ expr 2>3?44:2***3
+} -returnCodes error -match glob -result *
+test compExpr-old-3.7 {CompileCondExpr: long arms & nested cond exprs} {
+ hello_world
+} {Hello world}
+test compExpr-old-3.8 {CompileCondExpr: long arms & nested cond exprs} unix {
+ # Fails with a stack overflow on threaded Windows builds
+ do_twelve_days
+} 2358
+
+test compExpr-old-4.1 {CompileLorExpr: just land expr} {expr 1.3&&3.3} 1
+test compExpr-old-4.2 {CompileLorExpr: error in land expr} -body {
+ expr x&&3
+} -returnCodes error -match glob -result *
+test compExpr-old-4.3 {CompileLorExpr: simple lor exprs} {expr 0||1.0} 1
+test compExpr-old-4.4 {CompileLorExpr: simple lor exprs} {expr 3.0||0.0} 1
+test compExpr-old-4.5 {CompileLorExpr: simple lor exprs} {expr 0||0||1} 1
+test compExpr-old-4.6 {CompileLorExpr: error compiling lor arm} -body {
+ expr 2***3||4.0
+} -returnCodes error -match glob -result *
+test compExpr-old-4.7 {CompileLorExpr: error compiling lor arm} -body {
+ expr 1.3||2***3
+} -returnCodes error -match glob -result *
+test compExpr-old-4.8 {CompileLorExpr: error compiling lor arms} {
+ list [catch {expr {"a"||"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test compExpr-old-4.9 {CompileLorExpr: long lor arm} {
+ set a "abcdefghijkl"
+ set i 7
+ expr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]}
+} 1
+
+test compExpr-old-5.1 {CompileLandExpr: just bitor expr} {expr 7|0x13} 23
+test compExpr-old-5.2 {CompileLandExpr: error in bitor expr} -body {
+ expr x|3
+} -returnCodes error -match glob -result *
+test compExpr-old-5.3 {CompileLandExpr: simple land exprs} {expr 0&&1.0} 0
+test compExpr-old-5.4 {CompileLandExpr: simple land exprs} {expr 0&&0} 0
+test compExpr-old-5.5 {CompileLandExpr: simple land exprs} {expr 3.0&&1.2} 1
+test compExpr-old-5.6 {CompileLandExpr: simple land exprs} {expr 1&&1&&2} 1
+test compExpr-old-5.7 {CompileLandExpr: error compiling land arm} -body {
+ expr 2***3&&4.0
+} -returnCodes error -match glob -result *
+test compExpr-old-5.8 {CompileLandExpr: error compiling land arm} -body {
+ expr 1.3&&2***3
+} -returnCodes error -match glob -result *
+test compExpr-old-5.9 {CompileLandExpr: error compiling land arm} {
+ list [catch {expr {"a"&&"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test compExpr-old-5.10 {CompileLandExpr: long land arms} {
+ set a "abcdefghijkl"
+ set i 7
+ expr {[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]}
+} 1
+
+test compExpr-old-6.1 {CompileBitXorExpr: just bitand expr} {expr 7&0x13} 3
+test compExpr-old-6.2 {CompileBitXorExpr: error in bitand expr} -body {
+ expr x|3
+} -returnCodes error -match glob -result *
+test compExpr-old-6.3 {CompileBitXorExpr: simple bitxor exprs} {expr 7^0x13} 20
+test compExpr-old-6.4 {CompileBitXorExpr: simple bitxor exprs} {expr 3^0x10} 19
+test compExpr-old-6.5 {CompileBitXorExpr: simple bitxor exprs} {expr 0^7} 7
+test compExpr-old-6.6 {CompileBitXorExpr: simple bitxor exprs} {expr -1^7} -8
+test compExpr-old-6.7 {CompileBitXorExpr: error compiling bitxor arm} -body {
+ expr 2***3|6
+} -returnCodes error -match glob -result *
+test compExpr-old-6.8 {CompileBitXorExpr: error compiling bitxor arm} -body {
+ expr 2^x
+} -returnCodes error -match glob -result *
+test compExpr-old-6.9 {CompileBitXorExpr: runtime error in bitxor arm} {
+ list [catch {expr {24.0^3}} msg] $msg
+} {1 {can't use floating-point value as operand of "^"}}
+test compExpr-old-6.10 {CompileBitXorExpr: runtime error in bitxor arm} {
+ list [catch {expr {"a"^"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "^"}}
+
+test compExpr-old-7.1 {CompileBitAndExpr: just equality expr} {expr 3==2} 0
+test compExpr-old-7.2 {CompileBitAndExpr: just equality expr} {expr 2.0==2} 1
+test compExpr-old-7.3 {CompileBitAndExpr: just equality expr} {expr 3.2!=2.2} 1
+test compExpr-old-7.4 {CompileBitAndExpr: just equality expr} {expr {"abc" == "abd"}} 0
+test compExpr-old-7.5 {CompileBitAndExpr: error in equality expr} -body {
+ expr x==3
+} -returnCodes error -match glob -result *
+test compExpr-old-7.6 {CompileBitAndExpr: simple bitand exprs} {expr 7&0x13} 3
+test compExpr-old-7.7 {CompileBitAndExpr: simple bitand exprs} {expr 0xf2&0x53} 82
+test compExpr-old-7.8 {CompileBitAndExpr: simple bitand exprs} {expr 3&6} 2
+test compExpr-old-7.9 {CompileBitAndExpr: simple bitand exprs} {expr -1&-7} -7
+test compExpr-old-7.10 {CompileBitAndExpr: error compiling bitand arm} -body {
+ expr 2***3&6
+} -returnCodes error -match glob -result *
+test compExpr-old-7.11 {CompileBitAndExpr: error compiling bitand arm} -body {
+ expr 2&x
+} -returnCodes error -match glob -result *
+test compExpr-old-7.12 {CompileBitAndExpr: runtime error in bitand arm} {
+ list [catch {expr {24.0&3}} msg] $msg
+} {1 {can't use floating-point value as operand of "&"}}
+test compExpr-old-7.13 {CompileBitAndExpr: runtime error in bitand arm} {
+ list [catch {expr {"a"&"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "&"}}
+
+test compExpr-old-8.1 {CompileEqualityExpr: just relational expr} {expr 3>=2} 1
+test compExpr-old-8.2 {CompileEqualityExpr: just relational expr} {expr 2<=2.1} 1
+test compExpr-old-8.3 {CompileEqualityExpr: just relational expr} {expr 3.2>"2.2"} 1
+test compExpr-old-8.4 {CompileEqualityExpr: just relational expr} {expr {"0y"<"0x12"}} 0
+test compExpr-old-8.5 {CompileEqualityExpr: error in relational expr} -body {
+ expr x>3
+} -returnCodes error -match glob -result *
+test compExpr-old-8.6 {CompileEqualityExpr: simple equality exprs} {expr 7==0x13} 0
+test compExpr-old-8.7 {CompileEqualityExpr: simple equality exprs} {expr -0xf2!=0x53} 1
+test compExpr-old-8.8 {CompileEqualityExpr: simple equality exprs} {expr {"12398712938788234-1298379" != ""}} 1
+test compExpr-old-8.9 {CompileEqualityExpr: simple equality exprs} {expr -1!="abc"} 1
+test compExpr-old-8.10 {CompileEqualityExpr: error compiling equality arm} -body {
+ expr 2***3==6
+} -returnCodes error -match glob -result *
+test compExpr-old-8.11 {CompileEqualityExpr: error compiling equality arm} -body {
+ expr 2!=x
+} -returnCodes error -match glob -result *
+
+
+test compExpr-old-9.1 {CompileRelationalExpr: just shift expr} {expr 3<<2} 12
+test compExpr-old-9.2 {CompileRelationalExpr: just shift expr} {expr 0xff>>2} 63
+test compExpr-old-9.3 {CompileRelationalExpr: just shift expr} {expr -1>>2} -1
+test compExpr-old-9.4 {CompileRelationalExpr: just shift expr} {expr {1<<3}} 8
+
+# The following test is different for 32-bit versus 64-bit
+# architectures because LONG_MIN is different
+
+test compExpr-old-9.5a {CompileRelationalExpr: shift expr producing LONG_MIN} longIs64bit {
+ expr {int(1<<63)}
+} -9223372036854775808
+test compExpr-old-9.5b {CompileRelationalExpr: shift expr producing LONG_MIN} longIs32bit {
+ expr {int(1<<31)}
+} -2147483648
+
+test compExpr-old-9.6 {CompileRelationalExpr: error in shift expr} -body {
+ expr x>>3
+} -returnCodes error -match glob -result *
+test compExpr-old-9.7 {CompileRelationalExpr: simple relational exprs} {expr 0xff>=+0x3} 1
+test compExpr-old-9.8 {CompileRelationalExpr: simple relational exprs} {expr -0xf2<0x3} 1
+test compExpr-old-9.9 {CompileRelationalExpr: error compiling relational arm} -body {
+ expr 2***3>6
+} -returnCodes error -match glob -result *
+test compExpr-old-9.10 {CompileRelationalExpr: error compiling relational arm} -body {
+ expr 2<x
+} -returnCodes error -match glob -result *
+
+test compExpr-old-10.1 {CompileShiftExpr: just add expr} {expr 4+-2} 2
+test compExpr-old-10.2 {CompileShiftExpr: just add expr} {expr 0xff-2} 253
+test compExpr-old-10.3 {CompileShiftExpr: just add expr} {expr -1--2} 1
+test compExpr-old-10.4 {CompileShiftExpr: just add expr} {expr 1-0o123} -82
+test compExpr-old-10.5 {CompileShiftExpr: error in add expr} -body {
+ expr x+3
+} -returnCodes error -match glob -result *
+test compExpr-old-10.6 {CompileShiftExpr: simple shift exprs} {expr 0xff>>0x3} 31
+test compExpr-old-10.7 {CompileShiftExpr: simple shift exprs} {expr -0xf2<<0x3} -1936
+test compExpr-old-10.8 {CompileShiftExpr: error compiling shift arm} -body {
+ expr 2***3>>6
+} -returnCodes error -match glob -result *
+test compExpr-old-10.9 {CompileShiftExpr: error compiling shift arm} -body {
+ expr 2<<x
+} -returnCodes error -match glob -result *
+test compExpr-old-10.10 {CompileShiftExpr: runtime error} {
+ list [catch {expr {24.0>>43}} msg] $msg
+} {1 {can't use floating-point value as operand of ">>"}}
+test compExpr-old-10.11 {CompileShiftExpr: runtime error} {
+ list [catch {expr {"a"<<"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "<<"}}
+
+test compExpr-old-11.1 {CompileAddExpr: just multiply expr} {expr 4*-2} -8
+test compExpr-old-11.2 {CompileAddExpr: just multiply expr} {expr 0xff%2} 1
+test compExpr-old-11.3 {CompileAddExpr: just multiply expr} {expr -1/2} -1
+test compExpr-old-11.4 {CompileAddExpr: just multiply expr} {expr 7891%0o123} 6
+test compExpr-old-11.5 {CompileAddExpr: error in multiply expr} -body {
+ expr x*3
+} -returnCodes error -match glob -result *
+test compExpr-old-11.6 {CompileAddExpr: simple add exprs} {expr 0xff++0x3} 258
+test compExpr-old-11.7 {CompileAddExpr: simple add exprs} {expr -0xf2--0x3} -239
+test compExpr-old-11.8 {CompileAddExpr: error compiling add arm} -body {
+ expr 2***3+6
+} -returnCodes error -match glob -result *
+test compExpr-old-11.9 {CompileAddExpr: error compiling add arm} -body {
+ expr 2-x
+} -returnCodes error -match glob -result *
+test compExpr-old-11.10 {CompileAddExpr: runtime error} {
+ list [catch {expr {24.0+"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test compExpr-old-11.11 {CompileAddExpr: runtime error} {
+ list [catch {expr {"a"-"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+test compExpr-old-11.12 {CompileAddExpr: runtime error} {
+ list [catch {expr {3/0}} msg] $msg
+} {1 {divide by zero}}
+test compExpr-old-11.13a {CompileAddExpr: runtime error} ieeeFloatingPoint {
+ list [catch {expr {2.3/0.0}} msg] $msg
+} {0 Inf}
+test compExpr-old-11.13b {CompileAddExpr: runtime error} !ieeeFloatingPoint {
+ list [catch {expr {2.3/0.0}} msg] $msg
+} {1 {divide by zero}}
+
+test compExpr-old-12.1 {CompileMultiplyExpr: just unary expr} {expr ~4} -5
+test compExpr-old-12.2 {CompileMultiplyExpr: just unary expr} {expr --5} 5
+test compExpr-old-12.3 {CompileMultiplyExpr: just unary expr} {expr !27} 0
+test compExpr-old-12.4 {CompileMultiplyExpr: just unary expr} {expr ~0xff00ff} -16711936
+test compExpr-old-12.5 {CompileMultiplyExpr: error in unary expr} -body {
+ expr ~x
+} -returnCodes error -match glob -result *
+test compExpr-old-12.6 {CompileMultiplyExpr: simple multiply exprs} {expr 0xff*0x3} 765
+test compExpr-old-12.7 {CompileMultiplyExpr: simple multiply exprs} {expr -0xf2%-0x3} -2
+test compExpr-old-12.8 {CompileMultiplyExpr: error compiling multiply arm} -body {
+ expr 2*3%%6
+} -returnCodes error -match glob -result *
+test compExpr-old-12.9 {CompileMultiplyExpr: error compiling multiply arm} -body {
+ expr 2*x
+} -returnCodes error -match glob -result *
+test compExpr-old-12.10 {CompileMultiplyExpr: runtime error} {
+ list [catch {expr {24.0*"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "*"}}
+test compExpr-old-12.11 {CompileMultiplyExpr: runtime error} {
+ list [catch {expr {"a"/"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+
+test compExpr-old-13.1 {CompileUnaryExpr: unary exprs} {expr -0xff} -255
+test compExpr-old-13.2 {CompileUnaryExpr: unary exprs} {expr +0o00123} 83
+test compExpr-old-13.3 {CompileUnaryExpr: unary exprs} {expr +--++36} 36
+test compExpr-old-13.4 {CompileUnaryExpr: unary exprs} {expr !2} 0
+test compExpr-old-13.5 {CompileUnaryExpr: unary exprs} {expr +--+-62.0} -62.0
+test compExpr-old-13.6 {CompileUnaryExpr: unary exprs} {expr !0.0} 1
+test compExpr-old-13.7 {CompileUnaryExpr: unary exprs} {expr !0xef} 0
+test compExpr-old-13.8 {CompileUnaryExpr: error compiling unary expr} -body {
+ expr ~x
+} -returnCodes error -match glob -result *
+test compExpr-old-13.9 {CompileUnaryExpr: error compiling unary expr} -body {
+ expr !1.x
+ set msg
+} -returnCodes error -match glob -result *
+test compExpr-old-13.10 {CompileUnaryExpr: runtime error} {
+ list [catch {expr {~"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "~"}}
+test compExpr-old-13.11 {CompileUnaryExpr: runtime error} {
+ list [catch {expr ~4.0} msg] $msg
+} {1 {can't use floating-point value as operand of "~"}}
+test compExpr-old-13.12 {CompileUnaryExpr: just primary expr} {expr 0x123} 291
+test compExpr-old-13.13 {CompileUnaryExpr: just primary expr} {
+ set a 27
+ expr $a
+} 27
+test compExpr-old-13.14 {CompileUnaryExpr: just primary expr} {
+ expr double(27)
+} 27.0
+test compExpr-old-13.15 {CompileUnaryExpr: just primary expr} {expr "123"} 123
+test compExpr-old-13.16 {CompileUnaryExpr: error in primary expr} {
+ catch {expr [set]} msg
+ set msg
+} {wrong # args: should be "set varName ?newValue?"}
+test compExpr-old-14.1 {CompilePrimaryExpr: literal primary} {expr 1} 1
+test compExpr-old-14.2 {CompilePrimaryExpr: literal primary} {expr 123} 123
+test compExpr-old-14.3 {CompilePrimaryExpr: literal primary} {expr 0xff} 255
+test compExpr-old-14.4 {CompilePrimaryExpr: literal primary} {expr 0o0010} 8
+test compExpr-old-14.5 {CompilePrimaryExpr: literal primary} {expr 62.0} 62.0
+test compExpr-old-14.6 {CompilePrimaryExpr: literal primary} {
+ expr 3.1400000
+} 3.14
+test compExpr-old-14.7 {CompilePrimaryExpr: literal primary} {expr {{abcde}<{abcdef}}} 1
+test compExpr-old-14.8 {CompilePrimaryExpr: literal primary} {expr {{abc\
+def} < {abcdef}}} 1
+test compExpr-old-14.9 {CompilePrimaryExpr: literal primary} {expr {{abc\tde} > {abc\tdef}}} 0
+test compExpr-old-14.10 {CompilePrimaryExpr: literal primary} {expr {{123}}} 123
+test compExpr-old-14.11 {CompilePrimaryExpr: var reference primary} {
+ set i 789
+ list [expr {$i}] [expr $i]
+} {789 789}
+test compExpr-old-14.12 {CompilePrimaryExpr: var reference primary} {
+ set i {789} ;# test expr's aggressive conversion to numeric semantics
+ list [expr {$i}] [expr $i]
+} {789 789}
+test compExpr-old-14.13 {CompilePrimaryExpr: var reference primary} {
+ catch {unset a}
+ set a(foo) foo
+ set a(bar) bar
+ set a(123) 123
+ set result ""
+ lappend result [expr $a(123)] [expr {$a(bar)<$a(foo)}]
+ catch {unset a}
+ set result
+} {123 1}
+test compExpr-old-14.14 {CompilePrimaryExpr: var reference primary} {
+ set i 123 ;# test "$var.0" floating point conversion hack
+ list [expr $i] [expr $i.0] [expr $i.0/12.0]
+} {123 123.0 10.25}
+test compExpr-old-14.15 {CompilePrimaryExpr: var reference primary} {
+ set i 123
+ catch {expr $i.2} msg
+ set msg
+} 123.2
+test compExpr-old-14.16 {CompilePrimaryExpr: error compiling var reference primary} -body {
+ expr {$a(foo}
+} -returnCodes error -match glob -result *
+test compExpr-old-14.17 {CompilePrimaryExpr: string primary that looks like var ref} -body {
+ expr $
+} -returnCodes error -match glob -result *
+test compExpr-old-14.18 {CompilePrimaryExpr: quoted string primary} {
+ expr "21"
+} 21
+test compExpr-old-14.19 {CompilePrimaryExpr: quoted string primary} {
+ set i 123
+ set x 456
+ expr "$i+$x"
+} 579
+test compExpr-old-14.20 {CompilePrimaryExpr: quoted string primary} {
+ set i 3
+ set x 6
+ expr 2+"$i.$x"
+} 5.6
+test compExpr-old-14.21 {CompilePrimaryExpr: error in quoted string primary} {
+ catch {expr "[set]"} msg
+ set msg
+} {wrong # args: should be "set varName ?newValue?"}
+test compExpr-old-14.22 {CompilePrimaryExpr: subcommand primary} {
+ expr {[set i 123; set i]}
+} 123
+test compExpr-old-14.23 {CompilePrimaryExpr: error in subcommand primary} -body {
+ catch {expr {[set]}} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test compExpr-old-14.24 {CompilePrimaryExpr: error in subcommand primary} -body {
+ expr {[set i}
+} -returnCodes error -match glob -result *
+test compExpr-old-14.25 {CompilePrimaryExpr: math function primary} {
+ format %.6g [expr exp(1.0)]
+} 2.71828
+test compExpr-old-14.26 {CompilePrimaryExpr: math function primary} {
+ format %.6g [expr pow(2.0+0.1,3.0+0.1)]
+} 9.97424
+test compExpr-old-14.27 {CompilePrimaryExpr: error in math function primary} -body {
+ expr sinh::(2.0)
+} -returnCodes error -match glob -result *
+test compExpr-old-14.28 {CompilePrimaryExpr: subexpression primary} {
+ expr 2+(3*4)
+} 14
+test compExpr-old-14.29 {CompilePrimaryExpr: error in subexpression primary} -body {
+ catch {expr 2+(3*[set])} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test compExpr-old-14.30 {CompilePrimaryExpr: missing paren in subexpression primary} -body {
+ expr 2+(3*(4+5)
+} -returnCodes error -match glob -result *
+test compExpr-old-14.31 {CompilePrimaryExpr: just var ref in subexpression primary} {
+ set i "5+10"
+ list "[expr $i] == 15" "[expr ($i)] == 15" "[eval expr ($i)] == 15"
+} {{15 == 15} {15 == 15} {15 == 15}}
+test compExpr-old-14.32 {CompilePrimaryExpr: unexpected token} -body {
+ expr @
+} -returnCodes error -match glob -result *
+
+test compExpr-old-15.1 {CompileMathFuncCall: missing parenthesis} -body {
+ expr sinh2.0)
+} -returnCodes error -match glob -result *
+test compExpr-old-15.2 {CompileMathFuncCall: unknown math function} -body {
+ catch {expr whazzathuh(1)} msg
+ set ::errorInfo
+} -match glob -result {* "*whazzathuh"
+ while *ing
+"expr whazzathuh(1)"}
+test compExpr-old-15.3 {CompileMathFuncCall: too many arguments} -body {
+ catch {expr sin(1,2,3)} msg
+ set ::errorInfo
+} -match glob -result {too many arguments for math function*
+ while *ing
+"expr sin(1,2,3)"}
+test compExpr-old-15.4 {CompileMathFuncCall: ')' found before last required arg} -body {
+ catch {expr sin()} msg
+ set ::errorInfo
+} -match glob -result {too few arguments for math function*
+ while *ing
+"expr sin()"}
+test compExpr-old-15.5 {CompileMathFuncCall: too few arguments} -body {
+ catch {expr pow(1)} msg
+ set ::errorInfo
+} -match glob -result {too few arguments for math function*
+ while *ing
+"expr pow(1)"}
+test compExpr-old-15.6 {CompileMathFuncCall: missing ')'} -body {
+ expr sin(1
+} -returnCodes error -match glob -result *
+test compExpr-old-15.7 {CompileMathFuncCall: call registered math function} testmathfunctions {
+ expr 2*T1()
+} 246
+test compExpr-old-15.8 {CompileMathFuncCall: call registered math function} testmathfunctions {
+ expr T2()*3
+} 1035
+test compExpr-old-15.9 {CompileMathFuncCall: call registered math function} testmathfunctions {
+ expr T3(21, 37)
+} 37
+test compExpr-old-15.10 {CompileMathFuncCall: call registered math function} testmathfunctions {
+ expr T3(21.2, 37)
+} 37.0
+test compExpr-old-15.11 {CompileMathFuncCall: call registered math function} testmathfunctions {
+ expr T3(-21.2, -17.5)
+} -17.5
+
+test compExpr-old-16.1 {GetToken: checks whether integer token starting with "0x" (e.g., "0x$") is invalid} {
+ catch {unset a}
+ set a(VALUE) ff15
+ set i 123
+ if {[expr 0x$a(VALUE)] & 16} {
+ set i {}
+ }
+ set i
+} {}
+test compExpr-old-16.2 {GetToken: check for string literal in braces} {
+ expr {{1}}
+} {1}
+
+# Check "expr" and computed command names.
+
+test compExpr-old-17.1 {expr and computed command names} {
+ set i 0
+ set z expr
+ $z 1+2
+} 3
+
+# Check correct conversion of operands to numbers: If the string looks like
+# an integer, convert to integer. Otherwise, if the string looks like a
+# double, convert to double.
+
+test compExpr-old-18.1 {expr and conversion of operands to numbers} {
+ set x [lindex 11 0]
+ catch {expr int($x)}
+ expr {$x}
+} 11
+
+# Check "expr" and interpreter result object resetting before appending
+# an error msg during evaluation of exprs not in {}s
+
+test compExpr-old-19.1 {expr and interpreter result object resetting} {
+ proc p {} {
+ set t 10.0
+ set x 2.0
+ set dx 0.2
+ set f {$dx-$x/10}
+ set g {-$x/5}
+ set center 1.0
+ set x [expr $x-$center]
+ set dx [expr $dx+$g]
+ set x [expr $x+$f+$center]
+ set x [expr $x+$f+$center]
+ set y [expr round($x)]
+ }
+ p
+} 3
+
+# cleanup
+if {[info exists a]} {
+ unset a
+}
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/compExpr.test b/library/msgcat/tests/compExpr.test
new file mode 100644
index 0000000..8e27f1f
--- /dev/null
+++ b/library/msgcat/tests/compExpr.test
@@ -0,0 +1,393 @@
+# This file contains a collection of tests for the procedures in the file
+# tclCompExpr.c. Sourcing this file into Tcl runs the tests and generates
+# output for errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+if {[catch {expr T1()} msg] && $msg eq {invalid command name "tcl::mathfunc::T1"}} {
+ testConstraint testmathfunctions 0
+} else {
+ testConstraint testmathfunctions 1
+}
+
+# Constrain memory leak tests
+testConstraint memory [llength [info commands memory]]
+
+catch {unset a}
+
+test compExpr-1.1 {TclCompileExpr procedure, successful expr parse and compile} {
+ expr 1+2
+} 3
+test compExpr-1.2 {TclCompileExpr procedure, error parsing expr} -body {
+ expr 1+2+
+} -returnCodes error -match glob -result *
+test compExpr-1.3 {TclCompileExpr procedure, error compiling expr} -body {
+ list [catch {expr "foo(123)"} msg] $msg
+} -match glob -result {1 {* "*foo"}}
+test compExpr-1.4 {TclCompileExpr procedure, expr has no operators} {
+ set a {0o00123}
+ expr {$a}
+} 83
+
+test compExpr-2.1 {CompileSubExpr procedure, TCL_TOKEN_WORD parse token} -setup {
+ unset -nocomplain a
+} -body {
+ set a 27
+ expr {"foo$a" < "bar"}
+} -result 0
+test compExpr-2.2 {CompileSubExpr procedure, error compiling TCL_TOKEN_WORD parse token} -body {
+ expr {"00[expr 1+]" + 17}
+} -returnCodes error -match glob -result *
+test compExpr-2.3 {CompileSubExpr procedure, TCL_TOKEN_TEXT parse token} {
+ expr {{12345}}
+} 12345
+test compExpr-2.4 {CompileSubExpr procedure, empty TCL_TOKEN_TEXT parse token} {
+ expr {{}}
+} {}
+test compExpr-2.5 {CompileSubExpr procedure, TCL_TOKEN_BS parse token} {
+ expr "\{ \\
+ +123 \}"
+} 123
+test compExpr-2.6 {CompileSubExpr procedure, TCL_TOKEN_COMMAND parse token} {
+ expr {[info tclversion] != ""}
+} 1
+test compExpr-2.7 {CompileSubExpr procedure, TCL_TOKEN_COMMAND parse token} {
+ expr {[]}
+} {}
+test compExpr-2.8 {CompileSubExpr procedure, error in TCL_TOKEN_COMMAND parse token} -body {
+ expr {[foo "bar"xxx] + 17}
+} -returnCodes error -match glob -result *
+test compExpr-2.9 {CompileSubExpr procedure, TCL_TOKEN_VARIABLE parse token} -setup {
+ unset -nocomplain a
+} -body {
+ set a 123
+ expr {$a*2}
+} -result 246
+test compExpr-2.10 {CompileSubExpr procedure, TCL_TOKEN_VARIABLE parse token} -setup {
+ unset -nocomplain a
+ unset -nocomplain b
+} -body {
+ set a(george) martha
+ set b geo
+ expr {$a(${b}rge)}
+} -result martha
+test compExpr-2.11 {CompileSubExpr procedure, error in TCL_TOKEN_VARIABLE parse token} -body {
+ unset -nocomplain a
+ expr {$a + 17}
+} -returnCodes error -result {can't read "a": no such variable}
+test compExpr-2.12 {CompileSubExpr procedure, TCL_TOKEN_SUB_EXPR parse token} {
+ expr {27||3? 3<<(1+4) : 4&&9}
+} 96
+test compExpr-2.13 {CompileSubExpr procedure, error in TCL_TOKEN_SUB_EXPR parse token} -setup {
+ unset -nocomplain a
+} -body {
+ set a 15
+ list [catch {expr {27 || "$a[expr 1+]00"}} msg] $msg
+} -result {0 1}
+test compExpr-2.14 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, op found} {
+ expr {5*6}
+} 30
+test compExpr-2.15 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, math function found} {
+ format %.6g [expr {sin(2.0)}]
+} 0.909297
+test compExpr-2.16 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, math function not found} -body {
+ list [catch {expr {fred(2.0)}} msg] $msg
+} -match glob -result {1 {* "*fred"}}
+test compExpr-2.17 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4*2}
+} 8
+test compExpr-2.18 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4/2}
+} 2
+test compExpr-2.19 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4%2}
+} 0
+test compExpr-2.20 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4<<2}
+} 16
+test compExpr-2.21 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4>>2}
+} 1
+test compExpr-2.22 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4<2}
+} 0
+test compExpr-2.23 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4>2}
+} 1
+test compExpr-2.24 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4<=2}
+} 0
+test compExpr-2.25 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4>=2}
+} 1
+test compExpr-2.26 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4==2}
+} 0
+test compExpr-2.27 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4!=2}
+} 1
+test compExpr-2.28 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4&2}
+} 0
+test compExpr-2.29 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4^2}
+} 6
+test compExpr-2.30 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4|2}
+} 6
+test compExpr-2.31 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator, 1 operand} {
+ expr {!4}
+} 0
+test compExpr-2.32 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator, 1 operand} {
+ expr {~4}
+} -5
+test compExpr-2.33 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator, comparison} -setup {
+ unset -nocomplain a
+} -body {
+ set a 15
+ expr {$a==15} ;# compiled out-of-line to runtime call on Tcl_ExprObjCmd
+} -result 1
+test compExpr-2.34 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
+ expr {+2}
+} 2
+test compExpr-2.35 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, error in special operator} -body {
+ expr {+[expr 1+]}
+} -returnCodes error -match glob -result *
+test compExpr-2.36 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
+ expr {4+2}
+} 6
+test compExpr-2.37 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, error in special operator} -body {
+ expr {[expr 1+]+5}
+} -returnCodes error -match glob -result *
+test compExpr-2.38 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, error in special operator} -body {
+ expr {5+[expr 1+]}
+} -returnCodes error -match glob -result *
+test compExpr-2.39 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
+ expr {-2}
+} -2
+test compExpr-2.40 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
+ expr {4-2}
+} 2
+test compExpr-2.41 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} -setup {
+ unset -nocomplain a
+} -body {
+ set a true
+ expr {0||$a}
+} -result 1
+test compExpr-2.42 {CompileSubExpr procedure, error in TCL_TOKEN_SUB_EXPR parse token} -setup {
+ unset -nocomplain a
+} -body {
+ set a 15
+ list [catch {expr {27 || "$a[expr 1+]00"}} msg] $msg
+} -result {0 1}
+test compExpr-2.43 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} -setup {
+ unset -nocomplain a
+} -body {
+ set a false
+ expr {3&&$a}
+} -result 0
+test compExpr-2.44 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} -setup {
+ unset -nocomplain a
+} -body {
+ set a false
+ expr {$a||1? 1 : 0}
+} -result 1
+test compExpr-2.45 {CompileSubExpr procedure, error in TCL_TOKEN_SUB_EXPR parse token} -setup {
+ unset -nocomplain a
+} -body {
+ set a 15
+ list [catch {expr {1? 54 : "$a[expr 1+]00"}} msg] $msg
+} -result {0 54}
+
+test compExpr-3.1 {CompileLandOrLorExpr procedure, numeric 1st operand} -setup {
+ unset -nocomplain a
+} -body {
+ set a 2
+ expr {[set a]||0}
+} -result 1
+test compExpr-3.2 {CompileLandOrLorExpr procedure, nonnumeric 1st operand} -setup {
+ unset -nocomplain a
+} -body {
+ set a no
+ expr {$a&&1}
+} -result 0
+test compExpr-3.3 {CompileSubExpr procedure, error in 1st operand} -body {
+ expr {[expr *2]||0}
+} -returnCodes error -match glob -result *
+test compExpr-3.4 {CompileLandOrLorExpr procedure, result is 1 or 0} -setup {
+ unset -nocomplain a
+ unset -nocomplain b
+} -body {
+ set a no
+ set b true
+ expr {$a || $b}
+} -result 1
+test compExpr-3.5 {CompileLandOrLorExpr procedure, short-circuit semantics} -setup {
+ unset -nocomplain a
+} -body {
+ set a yes
+ expr {$a || [exit]}
+} -result 1
+test compExpr-3.6 {CompileLandOrLorExpr procedure, short-circuit semantics} -setup {
+ unset -nocomplain a
+} -body {
+ set a no
+ expr {$a && [exit]}
+} -result 0
+test compExpr-3.7 {CompileLandOrLorExpr procedure, numeric 2nd operand} -setup {
+ unset -nocomplain a
+} -body {
+ set a 2
+ expr {0||[set a]}
+} -result 1
+test compExpr-3.8 {CompileLandOrLorExpr procedure, nonnumeric 2nd operand} -setup {
+ unset -nocomplain a
+} -body {
+ set a no
+ expr {1&&$a}
+} -result 0
+test compExpr-3.9 {CompileLandOrLorExpr procedure, error in 2nd operand} -body {
+ expr {0||[expr %2]}
+} -returnCodes error -match glob -result *
+test compExpr-3.10 {CompileLandOrLorExpr procedure, long lor/land arm} {
+ set a "abcdefghijkl"
+ set i 7
+ expr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]}
+} 1
+
+test compExpr-4.1 {CompileCondExpr procedure, simple test} -setup {
+ unset -nocomplain a
+} -body {
+ set a 2
+ expr {($a > 1)? "ok" : "nope"}
+} -result ok
+test compExpr-4.2 {CompileCondExpr procedure, complex test, convert to numeric} -setup {
+ unset -nocomplain a
+} -body {
+ set a no
+ expr {[set a]? 27 : -54}
+} -result -54
+test compExpr-4.3 {CompileCondExpr procedure, error in test} -body {
+ expr {[expr *2]? +1 : -1}
+} -returnCodes error -match glob -result *
+test compExpr-4.4 {CompileCondExpr procedure, simple "true" clause} -setup {
+ unset -nocomplain a
+} -body {
+ set a no
+ expr {1? (27-2) : -54}
+} -result 25
+test compExpr-4.5 {CompileCondExpr procedure, convert "true" clause to numeric} -setup {
+ unset -nocomplain a
+} -body {
+ set a no
+ expr {1? $a : -54}
+} -result no
+test compExpr-4.6 {CompileCondExpr procedure, error in "true" clause} -body {
+ expr {1? [expr *2] : -127}
+} -returnCodes error -match glob -result *
+test compExpr-4.7 {CompileCondExpr procedure, simple "false" clause} -setup {
+ unset -nocomplain a
+} -body {
+ set a no
+ expr {(2-2)? -3.14159 : "nope"}
+} -result nope
+test compExpr-4.8 {CompileCondExpr procedure, convert "false" clause to numeric} -setup {
+ unset -nocomplain a
+} -body {
+ set a 0o0123
+ expr {0? 42 : $a}
+} -result 83
+test compExpr-4.9 {CompileCondExpr procedure, error in "false" clause} {
+ list [catch {expr {1? 15 : [expr *2]}} msg] $msg
+} {0 15}
+
+test compExpr-5.1 {CompileMathFuncCall procedure, math function found} {
+ format %.6g [expr atan2(1.0, 2.0)]
+} 0.463648
+test compExpr-5.2 {CompileMathFuncCall procedure, math function not found} -body {
+ expr {do_it()}
+} -returnCodes error -match glob -result {* "*do_it"}
+test compExpr-5.3 {CompileMathFuncCall: call registered math function} testmathfunctions {
+ expr 3*T1()-1
+} 368
+test compExpr-5.4 {CompileMathFuncCall: call registered math function} testmathfunctions {
+ expr T2()*3
+} 1035
+test compExpr-5.5 {CompileMathFuncCall procedure, too few arguments} -body {
+ expr {atan2(1.0)}
+} -returnCodes error -match glob -result {too few arguments for math function*}
+test compExpr-5.6 {CompileMathFuncCall procedure, complex argument} {
+ format %.6g [expr pow(2.1, 27.5-(24.4*(5%2)))]
+} 9.97424
+test compExpr-5.7 {CompileMathFuncCall procedure, error in argument} -body {
+ expr {sinh(2.*)}
+} -returnCodes error -match glob -result *
+test compExpr-5.8 {CompileMathFuncCall procedure, too many arguments} -body {
+ expr {sinh(2.0, 3.0)}
+} -returnCodes error -match glob -result {too many arguments for math function*}
+test compExpr-5.9 {CompileMathFuncCall procedure, too many arguments} -body {
+ expr {0 <= rand(5.2)}
+} -returnCodes error -match glob -result {too many arguments for math function*}
+
+test compExpr-6.1 {LogSyntaxError procedure, error in expr longer than 60 chars} -body {
+ expr {(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)/} -1 foo 3
+} -returnCodes error -match glob -result *
+
+test compExpr-7.1 {Memory Leak} -constraints memory -setup {
+ proc getbytes {} {
+ set lines [split [memory info] \n]
+ lindex $lines 3 3
+ }
+} -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ interp create slave
+ slave eval expr 1+2+3+4+5+6+7+8+9+10+11+12+13
+ interp delete slave
+ set tmp $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+ unset end i tmp
+ rename getbytes {}
+} -result 0
+
+test compExpr-7.2 {[Bug 1869989]: expr parser memleak} -constraints memory -setup {
+ proc getbytes {} {
+ set lines [split [memory info] \n]
+ lindex $lines 3 3
+ }
+} -body {
+ set i 5
+ set end [getbytes]
+ while {[incr i -1]} {
+ expr ${i}000
+ set tmp $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+ unset end i tmp
+ rename getbytes {}
+} -result 0
+
+# cleanup
+catch {unset a}
+catch {unset b}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/compile.test b/library/msgcat/tests/compile.test
new file mode 100644
index 0000000..d6048be
--- /dev/null
+++ b/library/msgcat/tests/compile.test
@@ -0,0 +1,721 @@
+# This file contains tests for the files tclCompile.c, tclCompCmds.c and
+# tclLiteral.c
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+testConstraint exec [llength [info commands exec]]
+testConstraint memory [llength [info commands memory]]
+testConstraint testevalex [llength [info commands testevalex]]
+
+# The following tests are very incomplete, although the rest of the
+# test suite covers this file fairly well.
+
+catch {rename p ""}
+catch {namespace delete test_ns_compile}
+catch {unset x}
+catch {unset y}
+catch {unset a}
+
+test compile-1.1 {TclCompileString: look up cmds in proc ns, not current ns} -setup {
+ catch {namespace delete test_ns_compile}
+ catch {unset x}
+} -body {
+ set x 123
+ namespace eval test_ns_compile {
+ proc set {args} {
+ global x
+ lappend x test_ns_compile::set
+ }
+ proc p {} {
+ set 0
+ }
+ }
+ list [test_ns_compile::p] [set x]
+} -result {{123 test_ns_compile::set} {123 test_ns_compile::set}}
+test compile-1.2 {TclCompileString, error result is reset if TclGetLong determines word isn't an integer} {
+ proc p {x} {info commands 3m}
+ list [catch {p} msg] $msg
+} {1 {wrong # args: should be "p x"}}
+
+test compile-2.1 {TclCompileDollarVar: global scalar name with ::s} -setup {
+ catch {unset x}
+} -body {
+ set x 123
+ list $::x [expr {"x" in [info globals]}]
+} -result {123 1}
+test compile-2.2 {TclCompileDollarVar: global scalar name with ::s} -setup {
+ catch {unset y}
+} -body {
+ proc p {} {
+ set ::y 789
+ return $::y
+ }
+ list [p] $::y [expr {"y" in [info globals]}]
+} -result {789 789 1}
+test compile-2.3 {TclCompileDollarVar: global array name with ::s} -setup {
+ catch {unset a}
+} -body {
+ set ::a(1) 2
+ list $::a(1) [set ::a($::a(1)) 3] $::a(2) [expr {"a" in [info globals]}]
+} -result {2 3 3 1}
+test compile-2.4 {TclCompileDollarVar: global scalar name with ::s} -setup {
+ catch {unset a}
+} -body {
+ proc p {} {
+ set ::a(1) 1
+ return $::a($::a(1))
+ }
+ list [p] $::a(1) [expr {"a" in [info globals]}]
+} -result {1 1 1}
+test compile-2.5 {TclCompileDollarVar: global array, called as ${arrName(0)}} -setup {
+ catch {unset a}
+} -body {
+ proc p {} {
+ global a
+ set a(1) 1
+ return ${a(1)}$::a(1)$a(1)
+ }
+ list [p] $::a(1) [expr {"a" in [info globals]}]
+} -result {111 1 1}
+
+test compile-3.1 {TclCompileCatchCmd: only catch cmds with scalar vars are compiled inline} -setup {
+ catch {unset a}
+} -body {
+ set a(1) xyzzyx
+ proc p {} {
+ global a
+ catch {set x 123} a(1)
+ }
+ list [p] $a(1)
+} -result {0 123}
+test compile-3.2 {TclCompileCatchCmd: non-local variables} {
+ set ::foo 1
+ proc catch-test {} {
+ catch {set x 3} ::foo
+ }
+ catch-test
+ return $::foo
+} 3
+test compile-3.3 {TclCompileCatchCmd: overagressive compiling [bug 219184]} {
+ proc catch-test {str} {
+ catch [eval $str GOOD]
+ error BAD
+ }
+ catch {catch-test error} ::foo
+ return $::foo
+} {GOOD}
+test compile-3.4 {TclCompileCatchCmd: bcc'ed [return] is caught} {
+ proc foo {} {
+ set fail [catch {
+ return 1
+ }] ; # {}
+ return 2
+ }
+ foo
+} {2}
+test compile-3.5 {TclCompileCatchCmd: recover from error, [Bug 705406]} {
+ proc foo {} {
+ catch {
+ if {[a]} {
+ if b {}
+ }
+ }
+ }
+ list [catch foo msg] $msg
+} {0 1}
+test compile-3.6 {TclCompileCatchCmd: error in storing result [Bug 3098302]} {*}{
+ -setup {
+ namespace eval catchtest {
+ variable result1 {}
+ }
+ trace add variable catchtest::result1 write catchtest::failtrace
+ proc catchtest::failtrace {n1 n2 op} {
+ return -code error "trace on $n1 fails by request"
+ }
+ }
+ -body {
+ proc catchtest::x {} {
+ variable result1
+ set count 0
+ for {set i 0} {$i < 10} {incr i} {
+ set status2 [catch {
+ set status1 [catch {
+ return -code error -level 0 "original failure"
+ } result1 options1]
+ } result2 options2]
+ incr count
+ }
+ list $count $result2
+ }
+ catchtest::x
+ }
+ -result {10 {can't set "result1": trace on result1 fails by request}}
+ -cleanup {namespace delete catchtest}
+}
+
+test compile-4.1 {TclCompileForCmd: command substituted test expression} {
+ set i 0
+ set j 0
+ # Should be "forever"
+ for {} [expr $i < 3] {} {
+ set j [incr i]
+ if {$j > 3} break
+ }
+ set j
+} {4}
+
+test compile-5.1 {TclCompileForeachCmd: exception stack} {
+ proc foreach-exception-test {} {
+ foreach array(index) [list 1 2 3] break
+ foreach array(index) [list 1 2 3] break
+ foreach scalar [list 1 2 3] break
+ }
+ list [catch foreach-exception-test result] $result
+} {0 {}}
+test compile-5.2 {TclCompileForeachCmd: non-local variables} {
+ set ::foo 1
+ proc foreach-test {} {
+ foreach ::foo {1 2 3} {}
+ }
+ foreach-test
+ set ::foo
+} 3
+
+test compile-6.1 {TclCompileSetCmd: global scalar names with ::s} -setup {
+ catch {unset x}
+ catch {unset y}
+} -body {
+ set x 123
+ proc p {} {
+ set ::y 789
+ return $::y
+ }
+ list $::x [expr {"x" in [info globals]}] \
+ [p] $::y [expr {"y" in [info globals]}]
+} -result {123 1 789 789 1}
+test compile-6.2 {TclCompileSetCmd: global array names with ::s} -setup {
+ catch {unset a}
+} -body {
+ set ::a(1) 2
+ proc p {} {
+ set ::a(1) 1
+ return $::a($::a(1))
+ }
+ list $::a(1) [p] [set ::a($::a(1)) 3] $::a(1) [expr {"a" in [info globals]}]
+} -result {2 1 3 3 1}
+test compile-6.3 {TclCompileSetCmd: namespace var names with ::s} -setup {
+ catch {namespace delete test_ns_compile}
+ catch {unset x}
+} -body {
+ namespace eval test_ns_compile {
+ variable v hello
+ variable arr
+ set ::x $::test_ns_compile::v
+ set ::test_ns_compile::arr(1) 123
+ }
+ list $::x $::test_ns_compile::arr(1)
+} -result {hello 123}
+
+test compile-7.1 {TclCompileWhileCmd: command substituted test expression} {
+ set i 0
+ set j 0
+ # Should be "forever"
+ while [expr $i < 3] {
+ set j [incr i]
+ if {$j > 3} break
+ }
+ set j
+} {4}
+
+test compile-8.1 {CollectArgInfo: binary data} {
+ list [catch "string length \000foo" msg] $msg
+} {0 4}
+test compile-8.2 {CollectArgInfo: binary data} {
+ list [catch "string length foo\000" msg] $msg
+} {0 4}
+test compile-8.3 {CollectArgInfo: handle "]" at end of command properly} {
+ set x ]
+} {]}
+
+test compile-9.1 {UpdateStringOfByteCode: called for duplicate of compiled empty object} {
+ proc p {} {
+ set x {}
+ eval $x
+ append x { }
+ eval $x
+ }
+ p
+} {}
+
+test compile-10.1 {BLACKBOX: exception stack overflow} {
+ set x {{0}}
+ set y 0
+ while {$y < 100} {
+ if !$x {incr y}
+ }
+} {}
+
+test compile-11.1 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} {
+ # shared object - Interp result && Var 'r'
+ set r [list foobar]
+ # command that will add error to result
+ lindex a bogus
+ }}
+} -returnCodes error -result {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}
+test compile-11.2 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} { set r [list foobar] ; string index a bogus }}
+} -returnCodes error -result {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}
+test compile-11.3 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} { set r [list foobar] ; string index a 0o9 }}
+} -returnCodes error -match glob -result {*invalid octal number*}
+test compile-11.4 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} { set r [list foobar] ; array set var {one two many} }}
+} -returnCodes error -result {list must have an even number of elements}
+test compile-11.5 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} { set r [list foobar] ; incr foo bar baz}}
+} -returnCodes error -result {wrong # args: should be "incr varName ?increment?"}
+test compile-11.6 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} { set r [list foobar] ; incr}}
+} -returnCodes error -result {wrong # args: should be "incr varName ?increment?"}
+test compile-11.7 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} { set r [list foobar] ; expr !a }}
+} -returnCodes error -match glob -result *
+test compile-11.8 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} { set r [list foobar] ; expr {!a} }}
+} -returnCodes error -match glob -result *
+test compile-11.9 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} { set r [list foobar] ; llength "\{" }}
+ list [catch {p} msg] $msg
+} -returnCodes error -result {unmatched open brace in list}
+
+#
+# Special section for tests of tclLiteral.c
+# The following tests check for incorrect memory handling in
+# TclReleaseLiteral. They are only effective when tcl is compiled with
+# TCL_MEM_DEBUG
+#
+# Special test for leak on interp delete [Bug 467523].
+test compile-12.1 {testing literal leak on interp delete} -setup {
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex $lines 3 3
+ }
+} -constraints memory -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ interp create foo
+ foo eval {
+ namespace eval bar {}
+ }
+ interp delete foo
+ set tmp $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+ rename getbytes {}
+ unset -nocomplain end i tmp leakedBytes
+} -result 0
+# Special test for a memory error in a preliminary fix of [Bug 467523]. It
+# requires executing a helpfile. Presumably the child process is used because
+# when this test fails, it crashes.
+test compile-12.2 {testing error on literal deletion} -constraints {memory exec} -body {
+ set sourceFile [makeFile {
+ for {set i 0} {$i < 5} {incr i} {
+ namespace eval bar {}
+ namespace delete bar
+ }
+ puts 0
+ } source.file]
+ exec [interpreter] $sourceFile
+} -cleanup {
+ catch {removeFile $sourceFile}
+} -result 0
+# Test to catch buffer overrun in TclCompileTokens from buf 530320
+test compile-12.3 {check for a buffer overrun} -body {
+ proc crash {} {
+ puts $array([expr {a+2}])
+ }
+ crash
+} -returnCodes error -cleanup {
+ rename crash {}
+} -match glob -result *
+test compile-12.4 {TclCleanupLiteralTable segfault} -body {
+ # Tcl Bug 1001997
+ # Here, we're trying to test a case that causes a crash in
+ # TclCleanupLiteralTable. The conditions that we're trying to establish
+ # are:
+ # - TclCleanupLiteralTable is attempting to clean up a bytecode object in
+ # the literal table.
+ # - The bytecode object in question contains the only reference to another
+ # literal.
+ # - The literal in question is in the same hash bucket as the bytecode
+ # object, and immediately follows it in the chain.
+ # Since newly registered literals are added at the FRONT of the bucket
+ # chains, and since the bytecode object is registered before its literals,
+ # this is difficult to achieve. What we do is:
+ # (a) do a [namespace eval] of a string that's calculated to hash into
+ # the same bucket as a literal that it contains. In this case, the
+ # script and the variable 'bugbug' land in the same bucket.
+ # (b) do a [namespace eval] of a string that contains enough literals to
+ # force TclRegisterLiteral to rebuild the global literal table. The
+ # newly created hash buckets will contain the literals, IN REVERSE
+ # ORDER, thus putting the bytecode immediately ahead of 'bugbug' and
+ # 'bug4345bug'. The bytecode object will contain the only references
+ # to those two literals.
+ # (c) Delete the interpreter to invoke TclCleanupLiteralTable and tickle
+ # the bug.
+ proc foo {} {
+ set i [interp create]
+ $i eval {
+ namespace eval ::w {concat 4649; variable bugbug}
+ namespace eval ::w {
+ concat x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 \
+ x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 \
+ x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 \
+ x31 x32 X33 X34 X35 X36 X37 X38 X39 X40 \
+ x41 x42 x43 x44 x45 x46 x47 x48 x49 x50 \
+ x51 x52 x53 x54 x55 x56 x57 x58 x59 x60 \
+ x61 x62 x63 x64
+ concat y1 y2 y3 y4 y5 y6 y7 y8 y9 y10 \
+ y11 y12 y13 y14 y15 y16 y17 y18 y19 y20 \
+ y21 y22 y23 y24 y25 y26 y27 y28 y29 y30 \
+ y31 y32 Y33 Y34 Y35 Y36 Y37 Y38 Y39 Y40 \
+ y41 y42 y43 y44 y45 y46 y47 y48 y49 y50 \
+ y51 y52 y53 y54 y55 y56 y57 y58 y59 y60 \
+ y61 y62 y63 y64
+ concat z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 \
+ z11 z12 z13 z14 z15 z16 z17 z18 z19 z20 \
+ z21 z22 z23 z24 z25 z26 z27 z28 z29 z30 \
+ z31 z32
+ }
+ }
+ interp delete $i; # must not crash
+ return ok
+ }
+ foo
+} -cleanup {
+ rename foo {}
+} -result ok
+
+# Special test for underestimating the maxStackSize required for a compiled
+# command. A failure will cause a segfault in the child process.
+test compile-13.1 {testing underestimate of maxStackSize in list cmd} {exec} {
+ set body {set x [list}
+ for {set i 0} {$i < 3000} {incr i} {
+ append body " $i"
+ }
+ append body {]; puts OK}
+ regsub BODY {proc crash {} {BODY}; crash} $body script
+ list [catch {exec [interpreter] << $script} msg] $msg
+} {0 OK}
+
+# Special test for compiling tokens from a copy of the source string. [Bug
+# 599788]
+test compile-14.1 {testing errors in element name; segfault?} {} {
+ catch {set a([error])} msg1
+ catch {set bubba([join $abba $jubba]) $vol} msg2
+ list $msg1 $msg2
+} {{wrong # args: should be "error message ?errorInfo? ?errorCode?"} {can't read "abba": no such variable}}
+
+# Tests compile-15.* cover Tcl Bug 633204
+test compile-15.1 {proper TCL_RETURN code from [return]} {
+ apply {{} {catch return}}
+} 2
+test compile-15.2 {proper TCL_RETURN code from [return]} {
+ apply {{} {catch {return foo}}}
+} 2
+test compile-15.3 {proper TCL_RETURN code from [return]} {
+ apply {{} {catch {return $::tcl_library}}}
+} 2
+test compile-15.4 {proper TCL_RETURN code from [return]} {
+ apply {{} {catch {return [info library]}}}
+} 2
+test compile-15.5 {proper TCL_RETURN code from [return]} {
+ apply {{} {catch {set a 1}; return}}
+} ""
+
+for {set noComp 0} {$noComp <= 1} {incr noComp} {
+
+if $noComp {
+ interp alias {} run {} testevalex
+ set constraints testevalex
+} else {
+ interp alias {} run {} if 1
+ set constraints {}
+}
+
+test compile-16.1.$noComp {TclCompileScript: word expansion} $constraints {
+ run "list [string repeat {{*}a } 255]"
+} [lrepeat 255 a]
+test compile-16.2.$noComp {TclCompileScript: word expansion} $constraints {
+ run "list [string repeat {{*}a } 256]"
+} [lrepeat 256 a]
+test compile-16.3.$noComp {TclCompileScript: word expansion} $constraints {
+ run "list [string repeat {{*}a } 257]"
+} [lrepeat 257 a]
+test compile-16.4.$noComp {TclCompileScript: word expansion} $constraints {
+ run {{*}list}
+} {}
+test compile-16.5.$noComp {TclCompileScript: word expansion} $constraints {
+ run {{*}list {*}{x y z}}
+} {x y z}
+test compile-16.6.$noComp {TclCompileScript: word expansion} $constraints {
+ run {{*}list {*}[list x y z]}
+} {x y z}
+test compile-16.7.$noComp {TclCompileScript: word expansion} $constraints {
+ run {{*}list {*}[list x y z][list x y z]}
+} {x y zx y z}
+test compile-16.8.$noComp {TclCompileScript: word expansion} -body {
+ set l {x y z}
+ run {{*}list {*}$l}
+} -constraints $constraints -cleanup {
+ unset l
+} -result {x y z}
+test compile-16.9.$noComp {TclCompileScript: word expansion} -body {
+ set l {x y z}
+ run {{*}list {*}$l$l}
+} -constraints $constraints -cleanup {
+ unset l
+} -result {x y zx y z}
+test compile-16.10.$noComp {TclCompileScript: word expansion} -body {
+ run {{*}\{}
+} -constraints $constraints -returnCodes error \
+-result {unmatched open brace in list}
+test compile-16.11.$noComp {TclCompileScript: word expansion} -body {
+ proc badList {} {return \{}
+ run {{*}[badList]}
+} -constraints $constraints -cleanup {
+ rename badList {}
+} -returnCodes error -result {unmatched open brace in list}
+test compile-16.12.$noComp {TclCompileScript: word expansion} $constraints {
+ run {{*}list x y z}
+} {x y z}
+test compile-16.13.$noComp {TclCompileScript: word expansion} $constraints {
+ run {{*}list x y {*}z}
+} {x y z}
+test compile-16.14.$noComp {TclCompileScript: word expansion} $constraints {
+ run {{*}list x {*}y z}
+} {x y z}
+test compile-16.15.$noComp {TclCompileScript: word expansion} $constraints {
+ run {list x y {*}z}
+} {x y z}
+test compile-16.16.$noComp {TclCompileScript: word expansion} $constraints {
+ run {list x {*}y z}
+} {x y z}
+test compile-16.17.$noComp {TclCompileScript: word expansion} $constraints {
+ run {list {*}x y z}
+} {x y z}
+
+# These tests note that expansion can in theory cause the number of arguments
+# to a command to exceed INT_MAX, which is as big as objc is allowed to get.
+#
+# In practice, it seems we will run out of memory before we confront this
+# issue. Note that compiled operations run out of memory at smaller objc
+# values than direct string evaluation.
+#
+# These tests are constrained as knownBug because they are likely to cause
+# memory allocation panics somewhere, and we don't want panics in the test
+# suite.
+#
+test compile-16.18.$noComp {TclCompileScript: word expansion} -body {
+ proc LongList {} {return [lrepeat [expr {1<<10}] x]}
+ llength [run "list [string repeat {{*}[LongList] } [expr {1<<10}]]"]
+} -constraints [linsert $constraints 0 knownBug] -cleanup {
+ rename LongList {}
+} -returnCodes ok -result [expr {1<<20}]
+test compile-16.19.$noComp {TclCompileScript: word expansion} -body {
+ proc LongList {} {return [lrepeat [expr {1<<11}] x]}
+ llength [run "list [string repeat {{*}[LongList] } [expr {1<<11}]]"]
+} -constraints [linsert $constraints 0 knownBug] -cleanup {
+ rename LongList {}
+} -returnCodes ok -result [expr {1<<22}]
+test compile-16.20.$noComp {TclCompileScript: word expansion} -body {
+ proc LongList {} {return [lrepeat [expr {1<<12}] x]}
+ llength [run "list [string repeat {{*}[LongList] } [expr {1<<12}]]"]
+} -constraints [linsert $constraints 0 knownBug] -cleanup {
+ rename LongList {}
+} -returnCodes ok -result [expr {1<<24}]
+# This is the one that should cause overflow
+test compile-16.21.$noComp {TclCompileScript: word expansion} -body {
+ proc LongList {} {return [lrepeat [expr {1<<16}] x]}
+ llength [run "list [string repeat {{*}[LongList] } [expr {1<<16}]]"]
+} -constraints [linsert $constraints 0 knownBug] -cleanup {
+ rename LongList {}
+} -returnCodes ok -result [expr {wide(1)<<32}]
+test compile-16.22.$noComp {
+ Bug 845412: TclCompileScript: word expansion not mandatory
+} -body {
+ # This test may crash and will fail unless Bug 845412 is fixed.
+ proc ReturnResults args {return $args}
+ run "ReturnResults [string repeat {x } 260]"
+} -constraints $constraints -cleanup {
+ rename ReturnResults {}
+} -returnCodes ok -result [string trim [string repeat {x } 260]]
+test compile-16.23.$noComp {
+ Bug 1032805: defer parse error until run time
+} -constraints $constraints -body {
+ namespace eval x {
+ run {
+ proc if {a b} {uplevel 1 [list set $a $b]}
+ if 1 {syntax {}{}}
+ }
+ }
+} -cleanup {
+ namespace delete x
+} -returnCodes ok -result {syntax {}{}}
+test compile-16.24.$noComp {
+ Bug 1638414: bad list constant as first expanded term
+} -constraints $constraints -body {
+ run "{*}\"\{foo bar\""
+} -returnCodes error -result {unmatched open brace in list}
+test compile-16.25.$noComp {TclCompileScript: word expansion, naked backslashes} $constraints {
+ run {list {*}{a \n b}}
+} {a {
+} b}
+test compile-16.26.$noComp {TclCompileScript: word expansion, protected backslashes} $constraints {
+ run {list {*}{a {\n} b}}
+} {a {\n} b}
+} ;# End of noComp loop
+
+# These tests are messy because it wrecks the interpreter it runs in! They
+# demonstrate issues arising from [FRQ 1101710]
+test compile-17.1 {Command interpretation binding for compiled code} -constraints knownBug -setup {
+ set i [interp create]
+} -body {
+ $i eval {
+ if 1 {
+ expr [
+ proc expr args {return substituted}
+ format {[subst compiled]}
+ ]
+ }
+ }
+} -cleanup {
+ interp delete $i
+} -result substituted
+test compile-17.2 {Command interpretation binding for non-compiled code} -setup {
+ set i [interp create]
+} -body {
+ $i eval {
+ if 1 {
+ [subst expr] [
+ proc expr args {return substituted}
+ format {[subst compiled]}
+ ]
+ }
+ }
+} -cleanup {
+ interp delete $i
+} -result substituted
+
+# This tests the supported parts of the unsupported [disassemble] command. It
+# does not check the format of disassembled bytecode though; that's liable to
+# change without warning.
+
+test compile-18.1 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble
+} -match glob -result {wrong # args: should be "*"}
+test compile-18.2 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble ?
+} -match glob -result {bad type "?": must be *}
+test compile-18.3 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble lambda
+} -match glob -result {wrong # args: should be "* lambda lambdaTerm"}
+test compile-18.4 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble lambda \{
+} -result "can't interpret \"\{\" as a lambda expression"
+test compile-18.5 {disassembler - basics} -body {
+ # Allow any string: the result format is not defined anywhere!
+ tcl::unsupported::disassemble lambda {{} {}}
+} -match glob -result *
+test compile-18.6 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble proc
+} -match glob -result {wrong # args: should be "* proc procName"}
+test compile-18.7 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble proc nosuchproc
+} -result {"nosuchproc" isn't a procedure}
+test compile-18.8 {disassembler - basics} -setup {
+ proc chewonthis {} {}
+} -body {
+ # Allow any string: the result format is not defined anywhere!
+ tcl::unsupported::disassemble proc chewonthis
+} -cleanup {
+ rename chewonthis {}
+} -match glob -result *
+test compile-18.9 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble script
+} -match glob -result {wrong # args: should be "* script script"}
+test compile-18.10 {disassembler - basics} -body {
+ # Allow any string: the result format is not defined anywhere!
+ tcl::unsupported::disassemble script {}
+} -match glob -result *
+test compile-18.11 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble method
+} -match glob -result {wrong # args: should be "* method className methodName"}
+test compile-18.12 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble method nosuchclass foo
+} -result {nosuchclass does not refer to an object}
+test compile-18.13 {disassembler - basics} -returnCodes error -setup {
+ oo::object create justanobject
+} -body {
+ tcl::unsupported::disassemble method justanobject foo
+} -cleanup {
+ justanobject destroy
+} -result {"justanobject" is not a class}
+test compile-18.14 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble method oo::object nosuchmethod
+} -result {unknown method "nosuchmethod"}
+test compile-18.15 {disassembler - basics} -setup {
+ oo::class create foo {method bar {} {}}
+} -body {
+ # Allow any string: the result format is not defined anywhere!
+ tcl::unsupported::disassemble method foo bar
+} -cleanup {
+ foo destroy
+} -match glob -result *
+test compile-18.16 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble objmethod
+} -match glob -result {wrong # args: should be "* objmethod objectName methodName"}
+test compile-18.17 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble objmethod nosuchobject foo
+} -result {nosuchobject does not refer to an object}
+test compile-18.18 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble objmethod oo::object nosuchmethod
+} -result {unknown method "nosuchmethod"}
+test compile-18.19 {disassembler - basics} -setup {
+ oo::object create foo
+ oo::objdefine foo {method bar {} {}}
+} -body {
+ # Allow any string: the result format is not defined anywhere!
+ tcl::unsupported::disassemble objmethod foo bar
+} -cleanup {
+ foo destroy
+} -match glob -result *
+# TODO sometime - check that bytecode from tbcload is *not* disassembled.
+
+# cleanup
+catch {rename p ""}
+catch {namespace delete test_ns_compile}
+catch {unset x}
+catch {unset y}
+catch {unset a}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/concat.test b/library/msgcat/tests/concat.test
new file mode 100644
index 0000000..eeb11ca
--- /dev/null
+++ b/library/msgcat/tests/concat.test
@@ -0,0 +1,57 @@
+# Commands covered: concat
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test concat-1.1 {simple concatenation} {
+ concat a b c d e f g
+} {a b c d e f g}
+test concat-1.2 {merging lists together} {
+ concat a {b c d} {e f g h}
+} {a b c d e f g h}
+test concat-1.3 {merge lists, retain sub-lists} {
+ concat a {b {c d}} {{e f}} g h
+} {a b {c d} {e f} g h}
+test concat-1.4 {special characters} {
+ concat a\{ {b \{c d} \{d
+} "a{ b \\{c d {d"
+
+test concat-2.1 {error: one empty argument} {
+ concat {}
+} {}
+
+test concat-3.1 {error: no arguments} {
+ list [catch concat msg] $msg
+} {0 {}}
+
+test concat-4.1 {pruning off extra white space} {
+ concat {} {a b c}
+} {a b c}
+test concat-4.2 {pruning off extra white space} {
+ concat x y " a b c \n\t " " " " def "
+} {x y a b c def}
+test concat-4.3 {pruning off extra white space sets length correctly} {
+ llength [concat { {{a}} }]
+} 1
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/config.test b/library/msgcat/tests/config.test
new file mode 100644
index 0000000..d14837e
--- /dev/null
+++ b/library/msgcat/tests/config.test
@@ -0,0 +1,60 @@
+# -*- tcl -*-
+# Commands covered: pkgconfig
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test pkgconfig-1.1 {query keys} {
+ lsort [::tcl::pkgconfig list]
+} {64bit bindir,install bindir,runtime compile_debug compile_stats debug docdir,install docdir,runtime includedir,install includedir,runtime libdir,install libdir,runtime mem_debug optimized profiled scriptdir,install scriptdir,runtime threaded}
+test pkgconfig-1.2 {query keys multiple times} {
+ string compare [::tcl::pkgconfig list] [::tcl::pkgconfig list]
+} 0
+test pkgconfig-1.3 {query value multiple times} {
+ string compare \
+ [::tcl::pkgconfig get bindir,install] \
+ [::tcl::pkgconfig get bindir,install]
+} 0
+
+
+test pkgconfig-2.0 {error: missing subcommand} {
+ catch {::tcl::pkgconfig} msg
+ set msg
+} {wrong # args: should be "::tcl::pkgconfig subcommand ?arg?"}
+test pkgconfig-2.1 {error: illegal subcommand} {
+ catch {::tcl::pkgconfig foo} msg
+ set msg
+} {bad subcommand "foo": must be get or list}
+test pkgconfig-2.2 {error: list with arguments} {
+ catch {::tcl::pkgconfig list foo} msg
+ set msg
+} {wrong # args: should be "::tcl::pkgconfig list"}
+test pkgconfig-2.3 {error: get without arguments} {
+ catch {::tcl::pkgconfig get} msg
+ set msg
+} {wrong # args: should be "::tcl::pkgconfig get key"}
+test pkgconfig-2.4 {error: query unknown key} {
+ catch {::tcl::pkgconfig get foo} msg
+ set msg
+} {key not known}
+test pkgconfig-2.5 {error: query with to many arguments} {
+ catch {::tcl::pkgconfig get foo bar} msg
+ set msg
+} {wrong # args: should be "::tcl::pkgconfig subcommand ?arg?"}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/coroutine.test b/library/msgcat/tests/coroutine.test
new file mode 100644
index 0000000..7f40a7b
--- /dev/null
+++ b/library/msgcat/tests/coroutine.test
@@ -0,0 +1,618 @@
+# Commands covered: coroutine, yield, [info coroutine]
+#
+# This file contains a collection of tests for experimental commands that are
+# found in ::tcl::unsupported. The tests will migrate to normal test files
+# if/when the commands find their way into the core.
+#
+# Copyright (c) 2008 by Miguel Sofer.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testnrelevels [llength [info commands testnrelevels]]
+testConstraint memory [llength [info commands memory]]
+
+set lambda [list {{start 0} {stop 10}} {
+ # init
+ set i $start
+ set imax $stop
+ yield
+ while {$i < $imax} {
+ yield [expr {$i*$stop}]
+ incr i
+ }
+}]
+
+test coroutine-1.1 {coroutine basic} -setup {
+ coroutine foo ::apply $lambda
+ set res {}
+} -body {
+ for {set k 1} {$k < 4} {incr k} {
+ lappend res [foo]
+ }
+ set res
+} -cleanup {
+ rename foo {}
+ unset res
+} -result {0 10 20}
+test coroutine-1.2 {coroutine basic} -setup {
+ coroutine foo ::apply $lambda 2 8
+ set res {}
+} -body {
+ for {set k 1} {$k < 4} {incr k} {
+ lappend res [foo]
+ }
+ set res
+} -cleanup {
+ rename foo {}
+ unset res
+} -result {16 24 32}
+test coroutine-1.3 {yield returns new arg} -setup {
+ set body {
+ # init
+ set i $start
+ set imax $stop
+ yield
+ while {$i < $imax} {
+ set stop [yield [expr {$i*$stop}]]
+ incr i
+ }
+ }
+ coroutine foo ::apply [list {{start 2} {stop 10}} $body]
+ set res {}
+} -body {
+ for {set k 1} {$k < 4} {incr k} {
+ lappend res [foo $k]
+ }
+ set res
+} -cleanup {
+ rename foo {}
+ unset res
+} -result {20 6 12}
+test coroutine-1.4 {yield in nested proc} -setup {
+ proc moo {} {
+ upvar 1 i i stop stop
+ yield [expr {$i*$stop}]
+ }
+ set body {
+ # init
+ set i $start
+ set imax $stop
+ yield
+ while {$i < $imax} {
+ moo
+ incr i
+ }
+ }
+ coroutine foo ::apply [list {{start 0} {stop 10}} $body]
+ set res {}
+} -body {
+ for {set k 1} {$k < 4} {incr k} {
+ lappend res [foo $k]
+ }
+ set res
+} -cleanup {
+ rename foo {}
+ rename moo {}
+ unset body res
+} -result {0 10 20}
+test coroutine-1.5 {just yield} -body {
+ coroutine foo yield
+ list [foo] [catch foo msg] $msg
+} -cleanup {
+ unset msg
+} -result {{} 1 {invalid command name "foo"}}
+test coroutine-1.6 {just yield} -body {
+ coroutine foo [list yield]
+ list [foo] [catch foo msg] $msg
+} -cleanup {
+ unset msg
+} -result {{} 1 {invalid command name "foo"}}
+test coroutine-1.7 {yield in nested uplevel} -setup {
+ set body {
+ # init
+ set i $start
+ set imax $stop
+ yield
+ while {$i < $imax} {
+ uplevel 0 [list yield [expr {$i*$stop}]]
+ incr i
+ }
+ }
+ coroutine foo ::apply [list {{start 0} {stop 10}} $body]
+ set res {}
+} -body {
+ for {set k 1} {$k < 4} {incr k} {
+ lappend res [eval foo $k]
+ }
+ set res
+} -cleanup {
+ rename foo {}
+ unset body res
+} -result {0 10 20}
+test coroutine-1.8 {yield in nested uplevel} -setup {
+ set body {
+ # init
+ set i $start
+ set imax $stop
+ yield
+ while {$i < $imax} {
+ uplevel 0 yield [expr {$i*$stop}]
+ incr i
+ }
+ }
+ coroutine foo ::apply [list {{start 0} {stop 10}} $body]
+ set res {}
+} -body {
+ for {set k 1} {$k < 4} {incr k} {
+ lappend res [eval foo $k]
+ }
+ set res
+} -cleanup {
+ rename foo {}
+ unset body res
+} -result {0 10 20}
+test coroutine-1.9 {yield in nested eval} -setup {
+ proc moo {} {
+ upvar 1 i i stop stop
+ yield [expr {$i*$stop}]
+ }
+ set body {
+ # init
+ set i $start
+ set imax $stop
+ yield
+ while {$i < $imax} {
+ eval moo
+ incr i
+ }
+ }
+ coroutine foo ::apply [list {{start 0} {stop 10}} $body]
+ set res {}
+} -body {
+ for {set k 1} {$k < 4} {incr k} {
+ lappend res [foo $k]
+ }
+ set res
+} -cleanup {
+ rename moo {}
+ unset body res
+} -result {0 10 20}
+test coroutine-1.10 {yield in nested eval} -setup {
+ set body {
+ # init
+ set i $start
+ set imax $stop
+ yield
+ while {$i < $imax} {
+ eval yield [expr {$i*$stop}]
+ incr i
+ }
+ }
+ coroutine foo ::apply [list {{start 0} {stop 10}} $body]
+ set res {}
+} -body {
+ for {set k 1} {$k < 4} {incr k} {
+ lappend res [eval foo $k]
+ }
+ set res
+} -cleanup {
+ unset body res
+} -result {0 10 20}
+test coroutine-1.11 {yield outside coroutine} -setup {
+ proc moo {} {
+ upvar 1 i i stop stop
+ yield [expr {$i*$stop}]
+ }
+} -body {
+ variable i 5 stop 6
+ moo
+} -cleanup {
+ rename moo {}
+ unset i stop
+} -returnCodes error -result {yield can only be called in a coroutine}
+test coroutine-1.12 {proc as coroutine} -setup {
+ set body {
+ # init
+ set i $start
+ set imax $stop
+ yield
+ while {$i < $imax} {
+ uplevel 0 [list yield [expr {$i*$stop}]]
+ incr i
+ }
+ }
+ proc moo {{start 0} {stop 10}} $body
+ coroutine foo moo 2 8
+} -body {
+ list [foo] [foo]
+} -cleanup {
+ unset body
+ rename moo {}
+ rename foo {}
+} -result {16 24}
+test coroutine-1.13 {subst as coroutine: literal} {
+ list [coroutine foo eval {subst {>>[yield a],[yield b]<<}}] [foo x] [foo y]
+} {a b >>x,y<<}
+test coroutine-1.14 {subst as coroutine: in variable} {
+ set pattern {>>[yield c],[yield d]<<}
+ list [coroutine foo eval {subst $pattern}] [foo p] [foo q]
+} {c d >>p,q<<}
+
+test coroutine-2.1 {self deletion on return} -body {
+ coroutine foo set x 3
+ foo
+} -returnCodes error -result {invalid command name "foo"}
+test coroutine-2.2 {self deletion on return} -body {
+ coroutine foo ::apply [list {} {yield; yield 1; return 2}]
+ list [foo] [foo] [catch foo msg] $msg
+} -result {1 2 1 {invalid command name "foo"}}
+test coroutine-2.3 {self deletion on error return} -body {
+ coroutine foo ::apply [list {} {yield;yield 1; error ouch!}]
+ list [foo] [catch foo msg] $msg [catch foo msg] $msg
+} -result {1 1 ouch! 1 {invalid command name "foo"}}
+test coroutine-2.4 {self deletion on other return} -body {
+ coroutine foo ::apply [list {} {yield;yield 1; return -code 100 ouch!}]
+ list [foo] [catch foo msg] $msg [catch foo msg] $msg
+} -result {1 100 ouch! 1 {invalid command name "foo"}}
+test coroutine-2.5 {deletion of suspended coroutine} -body {
+ coroutine foo ::apply [list {} {yield; yield 1; return 2}]
+ list [foo] [rename foo {}] [catch foo msg] $msg
+} -result {1 {} 1 {invalid command name "foo"}}
+test coroutine-2.6 {deletion of running coroutine} -body {
+ coroutine foo ::apply [list {} {yield; rename foo {}; yield 1; return 2}]
+ list [foo] [catch foo msg] $msg
+} -result {1 1 {invalid command name "foo"}}
+
+test coroutine-3.1 {info level computation} -setup {
+ proc a {} {while 1 {yield [info level]}}
+ proc b {} foo
+} -body {
+ # note that coroutines execute in uplevel #0
+ set l0 [coroutine foo a]
+ set l1 [foo]
+ set l2 [b]
+ list $l0 $l1 $l2
+} -cleanup {
+ rename a {}
+ rename b {}
+} -result {1 1 1}
+test coroutine-3.2 {info frame computation} -setup {
+ proc a {} {while 1 {yield [info frame]}}
+ proc b {} foo
+} -body {
+ set l0 [coroutine foo a]
+ set l1 [foo]
+ set l2 [b]
+ expr {$l2 - $l1}
+} -cleanup {
+ rename a {}
+ rename b {}
+} -result 1
+test coroutine-3.3 {info coroutine} -setup {
+ proc a {} {info coroutine}
+ proc b {} a
+} -body {
+ b
+} -cleanup {
+ rename a {}
+ rename b {}
+} -result {}
+test coroutine-3.4 {info coroutine} -setup {
+ proc a {} {info coroutine}
+ proc b {} a
+} -body {
+ coroutine foo b
+} -cleanup {
+ rename a {}
+ rename b {}
+} -result ::foo
+test coroutine-3.5 {info coroutine} -setup {
+ proc a {} {info coroutine}
+ proc b {} {rename [info coroutine] {}; a}
+} -body {
+ coroutine foo b
+} -cleanup {
+ rename a {}
+ rename b {}
+} -result {}
+test coroutine-3.6 {info frame, bug #2910094} -setup {
+ proc stack {} {
+ set res [list "LEVEL:[set lev [info frame]]"]
+ for {set i 1} {$i < $lev} {incr i} {
+ lappend res [info frame $i]
+ }
+ set res
+ # the precise command depends on line numbers and such, is likely not
+ # to be stable: just check that the test completes!
+ return
+ }
+ proc a {} stack
+} -body {
+ coroutine aa a
+} -cleanup {
+ rename stack {}
+ rename a {}
+} -result {}
+
+test coroutine-4.1 {bug #2093188} -setup {
+ proc foo {} {
+ set v 1
+ trace add variable v {write unset} bar
+ yield
+ set v 2
+ yield
+ set v 3
+ }
+ proc bar args {lappend ::res $args}
+ coroutine a foo
+} -body {
+ list [a] [a] $::res
+} -cleanup {
+ rename foo {}
+ rename bar {}
+ unset ::res
+} -result {{} 3 {{v {} write} {v {} write} {v {} unset}}}
+test coroutine-4.2 {bug #2093188} -setup {
+ proc foo {} {
+ set v 1
+ trace add variable v {read unset} bar
+ yield
+ set v 2
+ set v
+ yield
+ set v 3
+ }
+ proc bar args {lappend ::res $args}
+ coroutine a foo
+} -body {
+ list [a] [a] $::res
+} -cleanup {
+ rename foo {}
+ rename bar {}
+ unset ::res
+} -result {{} 3 {{v {} read} {v {} unset}}}
+
+test coroutine-4.3 {bug #2093947} -setup {
+ proc foo {} {
+ set v 1
+ trace add variable v {write unset} bar
+ yield
+ set v 2
+ yield
+ set v 3
+ }
+ proc bar args {lappend ::res $args}
+} -body {
+ coroutine a foo
+ a
+ a
+ coroutine a foo
+ a
+ rename a {}
+ set ::res
+} -cleanup {
+ rename foo {}
+ rename bar {}
+ unset ::res
+} -result {{v {} write} {v {} write} {v {} unset} {v {} write} {v {} unset}}
+
+test coroutine-4.4 {bug #2917627: cmd resolution} -setup {
+ proc a {} {return global}
+ namespace eval b {proc a {} {return local}}
+} -body {
+ namespace eval b {coroutine foo a}
+} -cleanup {
+ rename a {}
+ namespace delete b
+} -result local
+
+test coroutine-4.5 {bug #2724403} -constraints {memory} \
+-setup {
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex $lines 3 3
+ }
+} -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ set ns ::y$i
+ namespace eval $ns {}
+ proc ${ns}::start {} {yield; puts hello}
+ coroutine ${ns}::run ${ns}::start
+ namespace delete $ns
+ set start $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $start}]
+} -cleanup {
+ rename getbytes {}
+ unset i ns start end
+} -result 0
+
+test coroutine-4.6 {compile context, bug #3282869} -setup {
+ unset ::x
+ proc f x {
+ coroutine D eval {yield X$x;yield Y}
+ }
+} -body {
+ f 12
+} -cleanup {
+ rename f {}
+} -returnCodes error -match glob -result {can't read *}
+
+test coroutine-4.7 {compile context, bug #3282869} -setup {
+ proc f x {
+ coroutine D eval {yield X$x;yield Y$x}
+ }
+} -body {
+ set ::x 15
+ set ::x [f 12]
+ D
+} -cleanup {
+ D
+ unset ::x
+ rename f {}
+} -result YX15
+
+test coroutine-5.1 {right numLevels on coro return} -constraints {testnrelevels} \
+-setup {
+ proc nestedYield {{val {}}} {
+ yield $val
+ }
+ proc getNumLevel {} {
+ # remove the level for this proc's call
+ expr {[lindex [testnrelevels] 1] - 1}
+ }
+ proc relativeLevel base {
+ # remove the level for this proc's call
+ expr {[getNumLevel] - $base - 1}
+ }
+ proc foo {} {
+ while 1 {
+ nestedYield
+ }
+ }
+ set res {}
+} -body {
+ set base [getNumLevel]
+ lappend res [relativeLevel $base]
+ eval {coroutine a foo}
+ # back to base level
+ lappend res [relativeLevel $base]
+ a
+ lappend res [relativeLevel $base]
+ eval a
+ lappend res [relativeLevel $base]
+ eval {eval a}
+ lappend res [relativeLevel $base]
+ rename a {}
+ lappend res [relativeLevel $base]
+ set res
+} -cleanup {
+ rename foo {}
+ rename nestedYield {}
+ rename getNumLevel {}
+ rename relativeLevel {}
+ unset res
+} -result {0 0 0 0 0 0}
+test coroutine-5.2 {right numLevels within coro} -constraints {testnrelevels} \
+-setup {
+ proc nestedYield {{val {}}} {
+ yield $val
+ }
+ proc getNumLevel {} {
+ # remove the level for this proc's call
+ expr {[lindex [testnrelevels] 1] - 1}
+ }
+ proc relativeLevel base {
+ # remove the level for this proc's call
+ expr {[getNumLevel] - $base - 1}
+ }
+ proc foo base {
+ while 1 {
+ set base [nestedYield [relativeLevel $base]]
+ }
+ }
+ set res {}
+} -body {
+ lappend res [eval {coroutine a foo [getNumLevel]}]
+ lappend res [a [getNumLevel]]
+ lappend res [eval {a [getNumLevel]}]
+ lappend res [eval {eval {a [getNumLevel]}}]
+ set base [lindex $res 0]
+ foreach x $res[set res {}] {
+ lappend res [expr {$x-$base}]
+ }
+ set res
+} -cleanup {
+ rename a {}
+ rename foo {}
+ rename nestedYield {}
+ rename getNumLevel {}
+ rename relativeLevel {}
+ unset res
+} -result {0 0 0 0}
+
+test coroutine-6.1 {coroutine nargs} -body {
+ coroutine a ::apply $lambda
+ a
+} -cleanup {
+ rename a {}
+} -result 0
+test coroutine-6.2 {coroutine nargs} -body {
+ coroutine a ::apply $lambda
+ a a
+} -cleanup {
+ rename a {}
+} -result 0
+test coroutine-6.3 {coroutine nargs} -body {
+ coroutine a ::apply $lambda
+ a a a
+} -cleanup {
+ rename a {}
+} -returnCodes error -result {wrong # args: should be "a ?arg?"}
+
+test coroutine-7.1 {yieldto} -body {
+ coroutine c apply {{} {
+ yield
+ yieldto return -level 0 -code 1 quux
+ return quuy
+ }}
+ set res [list [catch c msg] $msg]
+ lappend res [catch c msg] $msg
+ lappend res [catch c msg] $msg
+} -cleanup {
+ unset res
+} -result [list 1 quux 0 quuy 1 {invalid command name "c"}]
+test coroutine-7.2 {multi-argument yielding with yieldto} -body {
+ proc corobody {} {
+ set a 1
+ while 1 {
+ set a [yield $a]
+ set a [yieldto return -level 0 $a]
+ lappend a [llength $a]
+ }
+ }
+ coroutine a corobody
+ coroutine b corobody
+ list [a x] [a y z] [a \{p] [a \{q r] [a] [a] [rename a {}] \
+ [b ok] [rename b {}]
+} -cleanup {
+ rename corobody {}
+} -result {x {y z 2} \{p {\{q r 2} {} 0 {} ok {}}
+test coroutine-7.3 {yielding between coroutines} -body {
+ proc juggler {target {value ""}} {
+ if {$value eq ""} {
+ set value [yield [info coroutine]]
+ }
+ while {[llength $value]} {
+ lappend ::result $value [info coroutine]
+ set value [lrange $value 0 end-1]
+ lassign [yieldto $target $value] value
+ }
+ # Clear nested collection of coroutines
+ catch $target
+ }
+ set result ""
+ coroutine j1 juggler [coroutine j2 juggler [coroutine j3 juggler j1]]\
+ {a b c d e}
+ list $result [info command j1] [info command j2] [info command j3]
+} -cleanup {
+ catch {rename juggler ""}
+} -result {{{a b c d e} ::j1 {a b c d} ::j2 {a b c} ::j3 {a b} ::j1 a ::j2} {} {} {}}
+
+# cleanup
+unset lambda
+::tcltest::cleanupTests
+
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/dcall.test b/library/msgcat/tests/dcall.test
new file mode 100644
index 0000000..8977c31
--- /dev/null
+++ b/library/msgcat/tests/dcall.test
@@ -0,0 +1,42 @@
+# Commands covered: none
+#
+# This file contains a collection of tests for Tcl_CallWhenDeleted.
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testdcall [llength [info commands testdcall]]
+
+test dcall-1.1 {deletion callbacks} testdcall {
+ lsort -increasing [testdcall 1 2 3]
+} {1 2 3}
+test dcall-1.2 {deletion callbacks} testdcall {
+ testdcall
+} {}
+test dcall-1.3 {deletion callbacks} testdcall {
+ lsort -increasing [testdcall 20 21 22 -22]
+} {20 21}
+test dcall-1.4 {deletion callbacks} testdcall {
+ lsort -increasing [testdcall 20 21 22 -20]
+} {21 22}
+test dcall-1.5 {deletion callbacks} testdcall {
+ lsort -increasing [testdcall 20 21 22 -21]
+} {20 22}
+test dcall-1.6 {deletion callbacks} testdcall {
+ lsort -increasing [testdcall 20 21 22 -21 -22 -20]
+} {}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/dict.test b/library/msgcat/tests/dict.test
new file mode 100644
index 0000000..77bacf6
--- /dev/null
+++ b/library/msgcat/tests/dict.test
@@ -0,0 +1,1531 @@
+# This test file covers the dictionary object type and the dict command used
+# to work with values of that type.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 2003-2009 Donal K. Fellows
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Used for constraining memory leak tests
+testConstraint memory [llength [info commands memory]]
+if {[testConstraint memory]} {
+ proc memtest script {
+ set end [lindex [split [memory info] \n] 3 3]
+ for {set i 0} {$i < 5} {incr i} {
+ uplevel 1 $script
+ set tmp $end
+ set end [lindex [split [memory info] \n] 3 3]
+ }
+ expr {$end - $tmp}
+ }
+}
+
+test dict-1.1 {dict command basic syntax} -returnCodes error -body {
+ dict
+} -result {wrong # args: should be "dict subcommand ?arg ...?"}
+test dict-1.2 {dict command basic syntax} -returnCodes error -body {
+ dict ?
+} -match glob -result {unknown or ambiguous subcommand "?": must be *}
+
+test dict-2.1 {dict create command} {
+ dict create
+} {}
+test dict-2.2 {dict create command} {
+ dict create a b
+} {a b}
+test dict-2.3 {dict create command} -body {
+ set result {}
+ set dict [dict create a b c d]
+ # Can't compare directly as ordering of values is undefined
+ foreach key {a c} {
+ set idx [lsearch -exact $dict $key]
+ if {$idx & 1} {
+ error "found $key at odd index $idx in $dict"
+ }
+ lappend result [lindex $dict [expr {$idx+1}]]
+ }
+ return $result
+} -cleanup {
+ unset result dict key idx
+} -result {b d}
+test dict-2.4 {dict create command} -returnCodes error -body {
+ dict create a
+} -result {wrong # args: should be "dict create ?key value ...?"}
+test dict-2.5 {dict create command} -returnCodes error -body {
+ dict create a b c
+} -result {wrong # args: should be "dict create ?key value ...?"}
+test dict-2.6 {dict create command - initialse refcount field!} -body {
+ # Bug 715751 will show up in memory debuggers like purify
+ for {set i 0} {$i<10} {incr i} {
+ set dictv [dict create a 0]
+ set share [dict values $dictv]
+ list [dict incr dictv a]
+ }
+} -cleanup {
+ unset i dictv share
+} -result {}
+test dict-2.7 {dict create command - #-quoting in string rep} {
+ dict create # #comment
+} {{#} #comment}
+test dict-2.8 {dict create command - #-quoting in string rep} -body {
+ dict create #a x #b x
+} -match glob -result {{#?} x #? x}
+
+test dict-3.1 {dict get command} {dict get {a b} a} b
+test dict-3.2 {dict get command} {dict get {a b c d} a} b
+test dict-3.3 {dict get command} {dict get {a b c d} c} d
+test dict-3.4 {dict get command} -returnCodes error -body {
+ dict get {a b c d} b
+} -result {key "b" not known in dictionary}
+test dict-3.5 {dict get command} {dict get {a {p q r s} b {u v x y}} a p} q
+test dict-3.6 {dict get command} {dict get {a {p q r s} b {u v x y}} a r} s
+test dict-3.7 {dict get command} {dict get {a {p q r s} b {u v x y}} b u} v
+test dict-3.8 {dict get command} {dict get {a {p q r s} b {u v x y}} b x} y
+test dict-3.9 {dict get command} -returnCodes error -body {
+ dict get {a {p q r s} b {u v x y}} a z
+} -result {key "z" not known in dictionary}
+test dict-3.10 {dict get command} -returnCodes error -body {
+ dict get {a {p q r s} b {u v x y}} c z
+} -result {key "c" not known in dictionary}
+test dict-3.11 {dict get command} {dict get [dict create a b c d] a} b
+test dict-3.12 {dict get command} -returnCodes error -body {
+ dict get
+} -result {wrong # args: should be "dict get dictionary ?key ...?"}
+test dict-3.13 {dict get command} -body {
+ set dict [dict get {a b c d}]
+ if {$dict eq "a b c d"} {
+ return OK
+ } elseif {$dict eq "c d a b"} {
+ return reordered
+ } else {
+ return $dict
+ }
+} -cleanup {
+ unset dict
+} -result OK
+test dict-3.14 {dict get command} -returnCodes error -body {
+ dict get {a b c d} a c
+} -result {missing value to go with key}
+test dict-3.15 {compiled dict get error cleanliness - Bug 2431847} -body {
+ apply {{} {
+ dict set a(z) b c
+ dict get $a(z) d
+ }}
+} -returnCodes error -result {key "d" not known in dictionary}
+test dict-3.16 {dict/list shimmering - Bug 3004007} {set l [list p 1 p 2 q 3];dict get $l q;set l} {p 1 p 2 q 3}
+test dict-3.17 {dict/list shimmering - Bug 3004007} {set l [list p 1 p 2 q 3];dict get $l q;llength $l} 6
+
+test dict-4.1 {dict replace command} {
+ dict replace {a b c d}
+} {a b c d}
+test dict-4.2 {dict replace command} {
+ dict replace {a b c d} e f
+} {a b c d e f}
+test dict-4.3 {dict replace command} {
+ dict replace {a b c d} c f
+} {a b c f}
+test dict-4.4 {dict replace command} {
+ dict replace {a b c d} c x a y
+} {a y c x}
+test dict-4.5 {dict replace command} -returnCodes error -body {
+ dict replace
+} -result {wrong # args: should be "dict replace dictionary ?key value ...?"}
+test dict-4.6 {dict replace command} -returnCodes error -body {
+ dict replace {a a} a
+} -result {wrong # args: should be "dict replace dictionary ?key value ...?"}
+test dict-4.7 {dict replace command} -returnCodes error -body {
+ dict replace {a a a} a b
+} -result {missing value to go with key}
+test dict-4.8 {dict replace command} -returnCodes error -body {
+ dict replace [list a a a] a b
+} -result {missing value to go with key}
+test dict-4.9 {dict replace command} {dict replace [list a a] a b} {a b}
+test dict-4.10 {dict replace command} {dict replace [list a a] a b a c} {a c}
+
+test dict-5.1 {dict remove command} {dict remove {a b c d} a} {c d}
+test dict-5.2 {dict remove command} {dict remove {a b c d} c} {a b}
+test dict-5.3 {dict remove command} {dict remove {a b c d} a c} {}
+test dict-5.4 {dict remove command} {dict remove {a b c d} c a} {}
+test dict-5.5 {dict remove command} {
+ dict remove {a b c d}
+} {a b c d}
+test dict-5.6 {dict remove command} {dict remove {a b} c} {a b}
+test dict-5.7 {dict remove command} -returnCodes error -body {
+ dict remove
+} -result {wrong # args: should be "dict remove dictionary ?key ...?"}
+
+test dict-6.1 {dict keys command} {dict keys {a b}} a
+test dict-6.2 {dict keys command} {dict keys {c d}} c
+test dict-6.3 {dict keys command} {lsort [dict keys {a b c d}]} {a c}
+test dict-6.4 {dict keys command} {dict keys {a b c d} a} a
+test dict-6.5 {dict keys command} {dict keys {a b c d} c} c
+test dict-6.6 {dict keys command} {dict keys {a b c d} e} {}
+test dict-6.7 {dict keys command} {lsort [dict keys {a b c d ca da} c*]} {c ca}
+test dict-6.8 {dict keys command} -returnCodes error -body {
+ dict keys
+} -result {wrong # args: should be "dict keys dictionary ?pattern?"}
+test dict-6.9 {dict keys command} -returnCodes error -body {
+ dict keys {} a b
+} -result {wrong # args: should be "dict keys dictionary ?pattern?"}
+test dict-6.10 {dict keys command} -returnCodes error -body {
+ dict keys a
+} -result {missing value to go with key}
+
+test dict-7.1 {dict values command} {dict values {a b}} b
+test dict-7.2 {dict values command} {dict values {c d}} d
+test dict-7.3 {dict values command} {lsort [dict values {a b c d}]} {b d}
+test dict-7.4 {dict values command} {dict values {a b c d} b} b
+test dict-7.5 {dict values command} {dict values {a b c d} d} d
+test dict-7.6 {dict values command} {dict values {a b c d} e} {}
+test dict-7.7 {dict values command} {lsort [dict values {a b c d ca da} d*]} {d da}
+test dict-7.8 {dict values command} -returnCodes error -body {
+ dict values
+} -result {wrong # args: should be "dict values dictionary ?pattern?"}
+test dict-7.9 {dict values command} -returnCodes error -body {
+ dict values {} a b
+} -result {wrong # args: should be "dict values dictionary ?pattern?"}
+test dict-7.10 {dict values command} -returnCodes error -body {
+ dict values a
+} -result {missing value to go with key}
+
+test dict-8.1 {dict size command} {dict size {}} 0
+test dict-8.2 {dict size command} {dict size {a b}} 1
+test dict-8.3 {dict size command} {dict size {a b c d}} 2
+test dict-8.4 {dict size command} -returnCodes error -body {
+ dict size
+} -result {wrong # args: should be "dict size dictionary"}
+test dict-8.5 {dict size command} -returnCodes error -body {
+ dict size a b
+} -result {wrong # args: should be "dict size dictionary"}
+test dict-8.6 {dict size command} -returnCodes error -body {
+ dict size a
+} -result {missing value to go with key}
+
+test dict-9.1 {dict exists command} {dict exists {a b} a} 1
+test dict-9.2 {dict exists command} {dict exists {a b} b} 0
+test dict-9.3 {dict exists command} {dict exists {a {b c}} a b} 1
+test dict-9.4 {dict exists command} {dict exists {a {b c}} a c} 0
+test dict-9.5 {dict exists command} {dict exists {a {b c}} b c} 0
+test dict-9.6 {dict exists command} {dict exists {a {b c d}} a c} 0
+test dict-9.7 {dict exists command} -returnCodes error -body {
+ dict exists
+} -result {wrong # args: should be "dict exists dictionary key ?key ...?"}
+test dict-9.8 {dict exists command} -returnCodes error -body {
+ dict exists {}
+} -result {wrong # args: should be "dict exists dictionary key ?key ...?"}
+
+test dict-10.1 {dict info command} -body {
+ # Actual string returned by this command is undefined; it is
+ # intended for human consumption and not for use by scripts.
+ dict info {}
+} -match glob -result *
+test dict-10.2 {dict info command} -returnCodes error -body {
+ dict info
+} -result {wrong # args: should be "dict info dictionary"}
+test dict-10.3 {dict info command} -returnCodes error -body {
+ dict info {} x
+} -result {wrong # args: should be "dict info dictionary"}
+test dict-10.4 {dict info command} -returnCodes error -body {
+ dict info x
+} -result {missing value to go with key}
+
+test dict-11.1 {dict incr command: unshared value} -body {
+ set dictv [dict create \
+ a [string index "=0=" 1] \
+ b [expr {1+2}] \
+ c [expr {wide(0x80000000)+1}]]
+ dict incr dictv a
+} -cleanup {
+ unset dictv
+} -result {a 1 b 3 c 2147483649}
+test dict-11.2 {dict incr command: unshared value} -body {
+ set dictv [dict create \
+ a [string index "=0=" 1] \
+ b [expr {1+2}] \
+ c [expr {wide(0x80000000)+1}]]
+ dict incr dictv b
+} -cleanup {
+ unset dictv
+} -result {a 0 b 4 c 2147483649}
+test dict-11.3 {dict incr command: unshared value} -body {
+ set dictv [dict create \
+ a [string index "=0=" 1] \
+ b [expr {1+2}] \
+ c [expr {wide(0x80000000)+1}]]
+ dict incr dictv c
+} -cleanup {
+ unset dictv
+} -result {a 0 b 3 c 2147483650}
+test dict-11.4 {dict incr command: shared value} -body {
+ set dictv [dict create a 0 b [expr {1+2}] c [expr {wide(0x80000000)+1}]]
+ set sharing [dict values $dictv]
+ dict incr dictv a
+} -cleanup {
+ unset dictv sharing
+} -result {a 1 b 3 c 2147483649}
+test dict-11.5 {dict incr command: shared value} -body {
+ set dictv [dict create a 0 b [expr {1+2}] c [expr {wide(0x80000000)+1}]]
+ set sharing [dict values $dictv]
+ dict incr dictv b
+} -cleanup {
+ unset dictv sharing
+} -result {a 0 b 4 c 2147483649}
+test dict-11.6 {dict incr command: shared value} -body {
+ set dictv [dict create a 0 b [expr {1+2}] c [expr {wide(0x80000000)+1}]]
+ set sharing [dict values $dictv]
+ dict incr dictv c
+} -cleanup {
+ unset dictv sharing
+} -result {a 0 b 3 c 2147483650}
+test dict-11.7 {dict incr command: unknown values} -body {
+ set dictv [dict create a 0 b [expr {1+2}] c [expr {wide(0x80000000)+1}]]
+ dict incr dictv d
+} -cleanup {
+ unset dictv
+} -result {a 0 b 3 c 2147483649 d 1}
+test dict-11.8 {dict incr command} -body {
+ set dictv {a 1}
+ dict incr dictv a 2
+} -cleanup {
+ unset dictv
+} -result {a 3}
+test dict-11.9 {dict incr command} -returnCodes error -body {
+ set dictv {a dummy}
+ dict incr dictv a
+} -cleanup {
+ unset dictv
+} -result {expected integer but got "dummy"}
+test dict-11.10 {dict incr command} -returnCodes error -body {
+ set dictv {a 1}
+ dict incr dictv a dummy
+} -cleanup {
+ unset dictv
+} -result {expected integer but got "dummy"}
+test dict-11.11 {dict incr command} -setup {
+ unset -nocomplain dictv
+} -body {
+ dict incr dictv a
+} -cleanup {
+ unset dictv
+} -result {a 1}
+test dict-11.12 {dict incr command} -returnCodes error -body {
+ set dictv a
+ dict incr dictv a
+} -cleanup {
+ unset dictv
+} -result {missing value to go with key}
+test dict-11.13 {dict incr command} -returnCodes error -body {
+ set dictv a
+ dict incr dictv a a a
+} -cleanup {
+ unset dictv
+} -result {wrong # args: should be "dict incr varName key ?increment?"}
+test dict-11.14 {dict incr command} -returnCodes error -body {
+ set dictv a
+ dict incr dictv
+} -cleanup {
+ unset dictv
+} -result {wrong # args: should be "dict incr varName key ?increment?"}
+test dict-11.15 {dict incr command: write failure} -setup {
+ unset -nocomplain dictVar
+} -body {
+ set dictVar(block) {}
+ dict incr dictVar a
+} -returnCodes error -cleanup {
+ unset dictVar
+} -result {can't set "dictVar": variable is array}
+test dict-11.16 {dict incr command: compilation} {
+ apply {{} {
+ set v {a 0 b 0 c 0}
+ dict incr v a
+ dict incr v b 1
+ dict incr v c 2
+ dict incr v d 3
+ list [dict get $v a] [dict get $v b] [dict get $v c] [dict get $v d]
+ }}
+} {1 1 2 3}
+test dict-11.17 {dict incr command: compilation} {
+ apply {{} {
+ set dictv {a 1}
+ dict incr dictv a 2
+ }}
+} {a 3}
+
+test dict-12.1 {dict lappend command} -body {
+ set dictv {a a}
+ dict lappend dictv a
+} -cleanup {
+ unset dictv
+} -result {a a}
+test dict-12.2 {dict lappend command} -body {
+ set dictv {a a}
+ set sharing [dict values $dictv]
+ dict lappend dictv a b
+} -cleanup {
+ unset dictv sharing
+} -result {a {a b}}
+test dict-12.3 {dict lappend command} -body {
+ set dictv {a a}
+ dict lappend dictv a b c
+} -cleanup {
+ unset dictv
+} -result {a {a b c}}
+test dict-12.2.1 {dict lappend command} -body {
+ set dictv [dict create a [string index =a= 1]]
+ dict lappend dictv a b
+} -cleanup {
+ unset dictv
+} -result {a {a b}}
+test dict-12.4 {dict lappend command} -body {
+ set dictv {}
+ dict lappend dictv a x y z
+} -cleanup {
+ unset dictv
+} -result {a {x y z}}
+test dict-12.5 {dict lappend command} -body {
+ unset -nocomplain dictv
+ dict lappend dictv a b
+} -cleanup {
+ unset dictv
+} -result {a b}
+test dict-12.6 {dict lappend command} -returnCodes error -body {
+ set dictv a
+ dict lappend dictv a a
+} -cleanup {
+ unset dictv
+} -result {missing value to go with key}
+test dict-12.7 {dict lappend command} -returnCodes error -body {
+ dict lappend
+} -result {wrong # args: should be "dict lappend varName key ?value ...?"}
+test dict-12.8 {dict lappend command} -returnCodes error -body {
+ dict lappend dictv
+} -result {wrong # args: should be "dict lappend varName key ?value ...?"}
+test dict-12.9 {dict lappend command} -returnCodes error -body {
+ set dictv [dict create a "\{"]
+ dict lappend dictv a a
+} -cleanup {
+ unset dictv
+} -result {unmatched open brace in list}
+test dict-12.10 {dict lappend command: write failure} -setup {
+ unset -nocomplain dictVar
+} -body {
+ set dictVar(block) {}
+ dict lappend dictVar a x
+} -returnCodes error -cleanup {
+ unset dictVar
+} -result {can't set "dictVar": variable is array}
+test dict-12.11 {compiled dict append: invalidate string rep - Bug 3079830} {
+ apply {{} {set d {a 1 b 2 c 3}; dict lappend d b 22}}
+} {a 1 b {2 22} c 3}
+
+test dict-13.1 {dict append command} -body {
+ set dictv {a a}
+ dict append dictv a
+} -cleanup {
+ unset dictv
+} -result {a a}
+test dict-13.2 {dict append command} -body {
+ set dictv {a a}
+ set sharing [dict values $dictv]
+ dict append dictv a b
+} -cleanup {
+ unset dictv sharing
+} -result {a ab}
+test dict-13.3 {dict append command} -body {
+ set dictv {a a}
+ dict append dictv a b c
+} -cleanup {
+ unset dictv
+} -result {a abc}
+test dict-13.2.1 {dict append command} -body {
+ set dictv [dict create a [string index =a= 1]]
+ dict append dictv a b
+} -cleanup {
+ unset dictv
+} -result {a ab}
+test dict-13.4 {dict append command} -body {
+ set dictv {}
+ dict append dictv a x y z
+} -cleanup {
+ unset dictv
+} -result {a xyz}
+test dict-13.5 {dict append command} -body {
+ unset -nocomplain dictv
+ dict append dictv a b
+} -cleanup {
+ unset dictv
+} -result {a b}
+test dict-13.6 {dict append command} -returnCodes error -body {
+ set dictv a
+ dict append dictv a a
+} -cleanup {
+ unset dictv
+} -result {missing value to go with key}
+test dict-13.7 {dict append command} -returnCodes error -body {
+ dict append
+} -result {wrong # args: should be "dict append varName key ?value ...?"}
+test dict-13.8 {dict append command} -returnCodes error -body {
+ dict append dictv
+} -result {wrong # args: should be "dict append varName key ?value ...?"}
+test dict-13.9 {dict append command: write failure} -setup {
+ unset -nocomplain dictVar
+} -body {
+ set dictVar(block) {}
+ dict append dictVar a x
+} -returnCodes error -cleanup {
+ unset dictVar
+} -result {can't set "dictVar": variable is array}
+test dict-13.10 {compiled dict append: crash case} {
+ apply {{} {dict append dictVar a o k}}
+} {a ok}
+test dict-13.11 {compiled dict append: invalidate string rep - Bug 3079830} {
+ apply {{} {set d {a 1 b 2 c 3}; dict append d b 22}}
+} {a 1 b 222 c 3}
+
+test dict-14.1 {dict for command: syntax} -returnCodes error -body {
+ dict for
+} -result {wrong # args: should be "dict for {keyVar valueVar} dictionary script"}
+test dict-14.2 {dict for command: syntax} -returnCodes error -body {
+ dict for x
+} -result {wrong # args: should be "dict for {keyVar valueVar} dictionary script"}
+test dict-14.3 {dict for command: syntax} -returnCodes error -body {
+ dict for x x
+} -result {wrong # args: should be "dict for {keyVar valueVar} dictionary script"}
+test dict-14.4 {dict for command: syntax} -returnCodes error -body {
+ dict for x x x x
+} -result {wrong # args: should be "dict for {keyVar valueVar} dictionary script"}
+test dict-14.5 {dict for command: syntax} -returnCodes error -body {
+ dict for x x x
+} -result {must have exactly two variable names}
+test dict-14.6 {dict for command: syntax} -returnCodes error -body {
+ dict for {x x x} x x
+} -result {must have exactly two variable names}
+test dict-14.7 {dict for command: syntax} -returnCodes error -body {
+ dict for "\{x" x x
+} -result {unmatched open brace in list}
+test dict-14.8 {dict for command} -body {
+ # This test confirms that [dict keys], [dict values] and [dict for]
+ # all traverse a dictionary in the same order.
+ set dictv {a A b B c C}
+ set keys {}
+ set values {}
+ dict for {k v} $dictv {
+ lappend keys $k
+ lappend values $v
+ }
+ set result [expr {
+ $keys eq [dict keys $dictv] && $values eq [dict values $dictv]
+ }]
+ expr {$result ? "YES" : [list "NO" $dictv $keys $values]}
+} -cleanup {
+ unset result keys values k v dictv
+} -result YES
+test dict-14.9 {dict for command} {
+ dict for {k v} {} {
+ error "unexpected execution of 'dict for' body"
+ }
+} {}
+test dict-14.10 {dict for command: script results} -body {
+ set times 0
+ dict for {k v} {a a b b} {
+ incr times
+ continue
+ error "shouldn't get here"
+ }
+ return $times
+} -cleanup {
+ unset times k v
+} -result 2
+test dict-14.11 {dict for command: script results} -body {
+ set times 0
+ dict for {k v} {a a b b} {
+ incr times
+ break
+ error "shouldn't get here"
+ }
+ return $times
+} -cleanup {
+ unset times k v
+} -result 1
+test dict-14.12 {dict for command: script results} -body {
+ set times 0
+ list [catch {
+ dict for {k v} {a a b b} {
+ incr times
+ error test
+ }
+ } msg] $msg $times $::errorInfo
+} -cleanup {
+ unset times k v msg
+} -result {1 test 1 {test
+ while executing
+"error test"
+ ("dict for" body line 3)
+ invoked from within
+"dict for {k v} {a a b b} {
+ incr times
+ error test
+ }"}}
+test dict-14.13 {dict for command: script results} {
+ apply {{} {
+ dict for {k v} {a b} {
+ return ok,$k,$v
+ error "skipped return completely"
+ }
+ error "return didn't go far enough"
+ }}
+} ok,a,b
+test dict-14.14 {dict for command: handle representation loss} -body {
+ set dictVar {a b c d e f g h}
+ set keys {}
+ set values {}
+ dict for {k v} $dictVar {
+ if {[llength $dictVar]} {
+ lappend keys $k
+ lappend values $v
+ }
+ }
+ list [lsort $keys] [lsort $values]
+} -cleanup {
+ unset dictVar keys values k v
+} -result {{a c e g} {b d f h}}
+test dict-14.15 {dict for command: keys are unique and iterated over once only} -setup {
+ unset -nocomplain accum
+ array set accum {}
+} -body {
+ set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+ dict for {k v} $dictVar {
+ append accum($k) $v,
+ }
+ set result [lsort [array names accum]]
+ lappend result :
+ foreach k $result {
+ catch {lappend result $accum($k)}
+ }
+ return $result
+} -cleanup {
+ unset dictVar k v result accum
+} -result {a1 a2 b1 b2 bar foo : a, b, c, d, foo, bar,}
+test dict-14.16 {dict for command in compilation context} {
+ apply {{} {
+ set res {x x x x x x}
+ dict for {k v} {a 0 b 1 c 2 d 3 e 4 f 5} {
+ lset res $v $k
+ continue
+ }
+ return $res
+ }}
+} {a b c d e f}
+test dict-14.17 {dict for command in compilation context} {
+ # Bug 1379349
+ apply {{} {
+ set d [dict create a 1] ;# Dict must be unshared!
+ dict for {k v} $d {
+ dict set d $k 0 ;# Any modification will do
+ }
+ return $d
+ }}
+} {a 0}
+test dict-14.18 {dict for command in compilation context} {
+ # Bug 1382528
+ apply {{} {
+ dict for {k v} {} {} ;# Note empty dict
+ catch { error foo } ;# Note compiled [catch]
+ }}
+} 1
+test dict-14.19 {dict for and invalid dicts: bug 1531184} -body {
+ di[list]ct for {k v} x {}
+} -returnCodes 1 -result {missing value to go with key}
+test dict-14.20 {dict for stack space compilation: bug 1903325} {
+ apply {{x y args} {
+ dict for {a b} $x {}
+ concat "c=$y,$args"
+ }} {} 1 2 3
+} {c=1,2 3}
+# There's probably a lot more tests to add here. Really ought to use a
+# coverage tool for this job...
+
+test dict-15.1 {dict set command} -body {
+ set dictVar {}
+ dict set dictVar a x
+} -cleanup {
+ unset dictVar
+} -result {a x}
+test dict-15.2 {dict set command} -body {
+ set dictvar {a {}}
+ dict set dictvar a b x
+} -cleanup {
+ unset dictvar
+} -result {a {b x}}
+test dict-15.3 {dict set command} -body {
+ set dictvar {a {b {}}}
+ dict set dictvar a b c x
+} -cleanup {
+ unset dictvar
+} -result {a {b {c x}}}
+test dict-15.4 {dict set command} -body {
+ set dictVar {a y}
+ dict set dictVar a x
+} -cleanup {
+ unset dictVar
+} -result {a x}
+test dict-15.5 {dict set command} -body {
+ set dictVar {a {b y}}
+ dict set dictVar a b x
+} -cleanup {
+ unset dictVar
+} -result {a {b x}}
+test dict-15.6 {dict set command} -body {
+ set dictVar {a {b {c y}}}
+ dict set dictVar a b c x
+} -cleanup {
+ unset dictVar
+} -result {a {b {c x}}}
+test dict-15.7 {dict set command: path creation} -body {
+ set dictVar {}
+ dict set dictVar a b x
+} -cleanup {
+ unset dictVar
+} -result {a {b x}}
+test dict-15.8 {dict set command: creates variables} -setup {
+ unset -nocomplain dictVar
+} -body {
+ dict set dictVar a x
+ return $dictVar
+} -cleanup {
+ unset dictVar
+} -result {a x}
+test dict-15.9 {dict set command: write failure} -setup {
+ unset -nocomplain dictVar
+} -body {
+ set dictVar(block) {}
+ dict set dictVar a x
+} -returnCodes error -cleanup {
+ unset dictVar
+} -result {can't set "dictVar": variable is array}
+test dict-15.10 {dict set command: syntax} -returnCodes error -body {
+ dict set
+} -result {wrong # args: should be "dict set varName key ?key ...? value"}
+test dict-15.11 {dict set command: syntax} -returnCodes error -body {
+ dict set a
+} -result {wrong # args: should be "dict set varName key ?key ...? value"}
+test dict-15.12 {dict set command: syntax} -returnCodes error -body {
+ dict set a a
+} -result {wrong # args: should be "dict set varName key ?key ...? value"}
+test dict-15.13 {dict set command} -returnCodes error -body {
+ set dictVar a
+ dict set dictVar b c
+} -cleanup {
+ unset dictVar
+} -result {missing value to go with key}
+
+test dict-16.1 {dict unset command} -body {
+ set dictVar {a b c d}
+ dict unset dictVar a
+} -cleanup {
+ unset dictVar
+} -result {c d}
+test dict-16.2 {dict unset command} -body {
+ set dictVar {a b c d}
+ dict unset dictVar c
+} -cleanup {
+ unset dictVar
+} -result {a b}
+test dict-16.3 {dict unset command} -body {
+ set dictVar {a b}
+ dict unset dictVar c
+} -cleanup {
+ unset dictVar
+} -result {a b}
+test dict-16.4 {dict unset command} -body {
+ set dictVar {a {b c d e}}
+ dict unset dictVar a b
+} -cleanup {
+ unset dictVar
+} -result {a {d e}}
+test dict-16.5 {dict unset command} -returnCodes error -body {
+ set dictVar a
+ dict unset dictVar a
+} -cleanup {
+ unset dictVar
+} -result {missing value to go with key}
+test dict-16.6 {dict unset command} -returnCodes error -body {
+ set dictVar {a b}
+ dict unset dictVar c d
+} -cleanup {
+ unset dictVar
+} -result {key "c" not known in dictionary}
+test dict-16.7 {dict unset command} -setup {
+ unset -nocomplain dictVar
+} -body {
+ list [info exists dictVar] [dict unset dictVar a] [info exists dictVar]
+} -cleanup {
+ unset dictVar
+} -result {0 {} 1}
+test dict-16.8 {dict unset command} -returnCodes error -body {
+ dict unset dictVar
+} -result {wrong # args: should be "dict unset varName key ?key ...?"}
+test dict-16.9 {dict unset command: write failure} -setup {
+ unset -nocomplain dictVar
+} -body {
+ set dictVar(block) {}
+ dict unset dictVar a
+} -returnCodes error -cleanup {
+ unset dictVar
+} -result {can't set "dictVar": variable is array}
+
+test dict-17.1 {dict filter command: key} -body {
+ set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+ dict filter $dictVar key a2
+} -cleanup {
+ unset dictVar
+} -result {a2 b}
+test dict-17.2 {dict filter command: key} -body {
+ set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+ dict size [dict filter $dictVar key *]
+} -cleanup {
+ unset dictVar
+} -result 6
+test dict-17.3 {dict filter command: key} -body {
+ set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+ dict filter $dictVar key ???
+} -cleanup {
+ unset dictVar
+} -result {foo bar bar foo}
+test dict-17.4 {dict filter command: key - no patterns} {
+ dict filter {a b c d} key
+} {}
+test dict-17.4.1 {dict filter command: key - many patterns} {
+ dict filter {a1 a a2 b b1 c b2 d foo bar bar foo} key a? b?
+} {a1 a a2 b b1 c b2 d}
+test dict-17.5 {dict filter command: key - bad dict} -returnCodes error -body {
+ dict filter {a b c} key
+} -result {missing value to go with key}
+test dict-17.6 {dict filter command: value} -body {
+ set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+ dict filter $dictVar value c
+} -cleanup {
+ unset dictVar
+} -result {b1 c}
+test dict-17.7 {dict filter command: value} -body {
+ set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+ dict size [dict filter $dictVar value *]
+} -cleanup {
+ unset dictVar
+} -result 6
+test dict-17.8 {dict filter command: value} -body {
+ set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+ dict filter $dictVar value ???
+} -cleanup {
+ unset dictVar
+} -result {foo bar bar foo}
+test dict-17.9 {dict filter command: value - no patterns} {
+ dict filter {a b c d} value
+} {}
+test dict-17.9.1 {dict filter command: value - many patterns} {
+ dict filter {a a1 b a2 c b1 foo bar bar foo d b2} value a? b?
+} {a a1 b a2 c b1 d b2}
+test dict-17.10 {dict filter command: value - bad dict} -body {
+ dict filter {a b c} value a
+} -returnCodes error -result {missing value to go with key}
+test dict-17.11 {dict filter command: script} -body {
+ set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+ set n 0
+ list [dict filter $dictVar script {k v} {
+ incr n
+ expr {[string length $k] == [string length $v]}
+ }] $n
+} -cleanup {
+ unset dictVar n k v
+} -result {{foo bar bar foo} 6}
+test dict-17.12 {dict filter command: script} -returnCodes error -body {
+ dict filter {a b} script {k v} {
+ concat $k $v
+ }
+} -cleanup {
+ unset k v
+} -result {expected boolean value but got "a b"}
+test dict-17.13 {dict filter command: script} -body {
+ list [catch {dict filter {a b} script {k v} {error x}} msg] $msg \
+ $::errorInfo
+} -cleanup {
+ unset k v msg
+} -result {1 x {x
+ while executing
+"error x"
+ ("dict filter" script line 1)
+ invoked from within
+"dict filter {a b} script {k v} {error x}"}}
+test dict-17.14 {dict filter command: script} -setup {
+ set n 0
+} -body {
+ list [dict filter {a b c d} script {k v} {
+ incr n
+ break
+ error boom!
+ }] $n
+} -cleanup {
+ unset n k v
+} -result {{} 1}
+test dict-17.15 {dict filter command: script} -setup {
+ set n 0
+} -body {
+ list [dict filter {a b c d} script {k v} {
+ incr n
+ continue
+ error boom!
+ }] $n
+} -cleanup {
+ unset n k v
+} -result {{} 2}
+test dict-17.16 {dict filter command: script} {
+ apply {{} {
+ dict filter {a b} script {k v} {
+ return ok,$k,$v
+ error "skipped return completely"
+ }
+ error "return didn't go far enough"
+ }}
+} ok,a,b
+test dict-17.17 {dict filter command: script} -body {
+ dict filter {a b} script {k k} {continue}
+ return $k
+} -cleanup {
+ unset k
+} -result b
+test dict-17.18 {dict filter command: script} -returnCodes error -body {
+ dict filter {a b} script {k k}
+} -result {wrong # args: should be "dict filter dictionary script {keyVar valueVar} filterScript"}
+test dict-17.19 {dict filter command: script} -returnCodes error -body {
+ dict filter {a b} script k {continue}
+} -result {must have exactly two variable names}
+test dict-17.20 {dict filter command: script} -returnCodes error -body {
+ dict filter {a b} script "\{k v" {continue}
+} -result {unmatched open brace in list}
+test dict-17.21 {dict filter command} -returnCodes error -body {
+ dict filter {a b}
+} -result {wrong # args: should be "dict filter dictionary filterType ?arg ...?"}
+test dict-17.22 {dict filter command} -returnCodes error -body {
+ dict filter {a b} JUNK
+} -result {bad filterType "JUNK": must be key, script, or value}
+test dict-17.23 {dict filter command} -returnCodes error -body {
+ dict filter a key *
+} -result {missing value to go with key}
+
+test dict-18.1 {dict-list relationship} -body {
+ # Test that any internal conversion between list and dict does not change
+ # the object
+ set l [list 1 2 3 4 5 6 7 8 9 0 q w e r t y]
+ dict values $l
+ return $l
+} -cleanup {
+ unset l
+} -result {1 2 3 4 5 6 7 8 9 0 q w e r t y}
+test dict-18.2 {dict-list relationship} -body {
+ # Test that the dictionary is a valid list
+ set d [dict create "abc def" 0 "a\{b" 1 "c\}d" 2]
+ for {set t 0} {$t < 5} {incr t} {
+ llength $d
+ dict lappend d "abc def" "\}\{"
+ dict append d "a\{b" "\}"
+ dict incr d "c\}d" 1
+ }
+ llength $d
+} -cleanup {
+ unset d t
+} -result 6
+test dict-18.3 {dict-list relationship} -body {
+ set ld [list a b c d c e f g]
+ list [string length $ld] [dict size $ld] [llength $ld]
+} -cleanup {
+ unset ld
+} -result {15 3 8}
+test dict-18.4 {dict-list relationship} -body {
+ set ld [list a b c d c e f g]
+ list [llength $ld] [dict size $ld] [llength $ld]
+} -cleanup {
+ unset ld
+} -result {8 3 8}
+
+# This is a test for a specific bug.
+# It shows a bad ref counter when running with memdebug on.
+test dict-19.1 {memory bug} {
+ apply {{} {
+ set successors [dict create x {c d}]
+ dict set successors x a b
+ dict get $successors x
+ }}
+} [dict create c d a b]
+test dict-19.2 {dict: testing for leaks} -constraints memory -body {
+ # This test is made to stress object reference management
+ memtest {
+ apply {{} {
+ # A shared invalid dictinary
+ set apa {a {}b c d}
+ set bepa $apa
+ catch {dict replace $apa e f}
+ catch {dict remove $apa c d}
+ catch {dict incr apa a 5}
+ catch {dict lappend apa a 5}
+ catch {dict append apa a 5}
+ catch {dict set apa a 5}
+ catch {dict unset apa a}
+
+ # A shared valid dictionary, invalid incr
+ set apa {a b c d}
+ set bepa $apa
+ catch {dict incr bepa a 5}
+
+ # An error during write to an unshared object, incr
+ set apa {a 1 b 2}
+ set bepa [lrange $apa 0 end]
+ trace add variable bepa write {error hej}
+ catch {dict incr bepa a 5}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # An error during write to a shared object, incr
+ set apa {a 1 b 2}
+ set bepa $apa
+ trace add variable bepa write {error hej}
+ catch {dict incr bepa a 5}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # A shared valid dictionary, invalid lappend
+ set apa [list a {{}b} c d]
+ set bepa $apa
+ catch {dict lappend bepa a 5}
+
+ # An error during write to an unshared object, lappend
+ set apa {a 1 b 2}
+ set bepa [lrange $apa 0 end]
+ trace add variable bepa write {error hej}
+ catch {dict lappend bepa a 5}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # An error during write to a shared object, lappend
+ set apa {a 1 b 2}
+ set bepa $apa
+ trace add variable bepa write {error hej}
+ catch {dict lappend bepa a 5}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # An error during write to an unshared object, append
+ set apa {a 1 b 2}
+ set bepa [lrange $apa 0 end]
+ trace add variable bepa write {error hej}
+ catch {dict append bepa a 5}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # An error during write to a shared object, append
+ set apa {a 1 b 2}
+ set bepa $apa
+ trace add variable bepa write {error hej}
+ catch {dict append bepa a 5}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # An error during write to an unshared object, set
+ set apa {a 1 b 2}
+ set bepa [lrange $apa 0 end]
+ trace add variable bepa write {error hej}
+ catch {dict set bepa a 5}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # An error during write to a shared object, set
+ set apa {a 1 b 2}
+ set bepa $apa
+ trace add variable bepa write {error hej}
+ catch {dict set bepa a 5}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # An error during write to an unshared object, unset
+ set apa {a 1 b 2}
+ set bepa [lrange $apa 0 end]
+ trace add variable bepa write {error hej}
+ catch {dict unset bepa a}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # An error during write to a shared object, unset
+ set apa {a 1 b 2}
+ set bepa $apa
+ trace add variable bepa write {error hej}
+ catch {dict unset bepa a}
+ trace remove variable bepa write {error hej}
+ unset bepa
+ }}
+ }
+} -result 0
+test dict-19.3 {testing for leaks - Bug 2874678} -constraints memory -body {
+ set d aDictVar; # Force interpreted [dict incr]
+ memtest {
+ dict incr $d aKey 0
+ unset $d
+ }
+} -cleanup {
+ unset d
+} -result 0
+
+test dict-20.1 {dict merge command} {
+ dict merge
+} {}
+test dict-20.2 {dict merge command} {
+ dict merge {a b c d e f}
+} {a b c d e f}
+test dict-20.3 {dict merge command} -body {
+ dict merge {a b c d e}
+} -result {missing value to go with key} -returnCodes error
+test dict-20.4 {dict merge command} {
+ dict merge {a b c d} {e f g h}
+} {a b c d e f g h}
+test dict-20.5 {dict merge command} -body {
+ dict merge {a b c d e} {e f g h}
+} -result {missing value to go with key} -returnCodes error
+test dict-20.6 {dict merge command} -body {
+ dict merge {a b c d} {e f g h i}
+} -result {missing value to go with key} -returnCodes error
+test dict-20.7 {dict merge command} {
+ dict merge {a b c d e f} {e x g h}
+} {a b c d e x g h}
+test dict-20.8 {dict merge command} {
+ dict merge {a b c d} {a x c y}
+} {a x c y}
+test dict-20.9 {dict merge command} {
+ dict merge {a b c d} {c y a x}
+} {a x c y}
+test dict-20.10 {dict merge command} {
+ dict merge {a b c d e f} {a x 1 2 3 4} {a - 1 -}
+} {a - c d e f 1 - 3 4}
+
+test dict-21.1 {dict update command} -returnCodes 1 -body {
+ dict update
+} -result {wrong # args: should be "dict update varName key varName ?key varName ...? script"}
+test dict-21.2 {dict update command} -returnCodes 1 -body {
+ dict update v
+} -result {wrong # args: should be "dict update varName key varName ?key varName ...? script"}
+test dict-21.3 {dict update command} -returnCodes 1 -body {
+ dict update v k
+} -result {wrong # args: should be "dict update varName key varName ?key varName ...? script"}
+test dict-21.4 {dict update command} -returnCodes 1 -body {
+ dict update v k v
+} -result {wrong # args: should be "dict update varName key varName ?key varName ...? script"}
+test dict-21.5 {dict update command} -body {
+ set a {b c}
+ set result {}
+ set bb {}
+ dict update a b bb {
+ lappend result $a $bb
+ }
+ lappend result $a
+} -cleanup {
+ unset a result bb
+} -result {{b c} c {b c}}
+test dict-21.6 {dict update command} -body {
+ set a {b c}
+ set result {}
+ set bb {}
+ dict update a b bb {
+ lappend result $a $bb [set bb d]
+ }
+ lappend result $a
+} -cleanup {
+ unset a result bb
+} -result {{b c} c d {b d}}
+test dict-21.7 {dict update command} -body {
+ set a {b c}
+ set result {}
+ set bb {}
+ dict update a b bb {
+ lappend result $a $bb [unset bb]
+ }
+ lappend result $a
+} -cleanup {
+ unset a result
+} -result {{b c} c {} {}}
+test dict-21.8 {dict update command} -body {
+ set a {b c d e}
+ dict update a b v1 d v2 {
+ lassign "$v1 $v2" v2 v1
+ }
+ return $a
+} -cleanup {
+ unset a v1 v2
+} -result {b e d c}
+test dict-21.9 {dict update command} -body {
+ set a {b c d e}
+ dict update a b v1 d v2 {unset a}
+ info exist a
+} -cleanup {
+ unset v1 v2
+} -result 0
+test dict-21.10 {dict update command} -body {
+ set a {b {c d}}
+ dict update a b v1 {
+ dict update v1 c v2 {
+ set v2 foo
+ }
+ }
+ return $a
+} -cleanup {
+ unset a v1 v2
+} -result {b {c foo}}
+test dict-21.11 {dict update command} -body {
+ set a {b c d e}
+ dict update a b v1 d v2 {
+ dict set a f g
+ }
+ return $a
+} -cleanup {
+ unset a v1 v2
+} -result {b c d e f g}
+test dict-21.12 {dict update command} -body {
+ set a {b c d e}
+ dict update a b v1 d v2 f v3 {
+ set v3 g
+ }
+ return $a
+} -cleanup {
+ unset a v1 v2 v3
+} -result {b c d e f g}
+test dict-21.13 {dict update command: compilation} {
+ apply {d {
+ while 1 {
+ dict update d a alpha b beta {
+ set beta $alpha
+ unset alpha
+ break
+ }
+ }
+ return $d
+ }} {a 1 c 2}
+} {c 2 b 1}
+test dict-21.14 {dict update command: compilation} {
+ apply {x {
+ set indices {2 3}
+ trace add variable aa write "string length \$indices ;#"
+ dict update x k aa l bb {}
+ }} {k 1 l 2}
+} {}
+test dict-21.15 {dict update command: compilation} {
+ apply {x {
+ set indices {2 3}
+ trace add variable aa read "string length \$indices ;#"
+ dict update x k aa l bb {}
+ }} {k 1 l 2}
+} {}
+test dict-21.16 {dict update command: no recursive structures [Bug 1786481]} -body {
+ set foo {a {b {c {d {e 1}}}}}
+ dict update foo a t {
+ dict update t b t {
+ dict update t c t {
+ dict update t d t {
+ dict incr t e
+ }
+ }
+ }
+ }
+ string range [append foo OK] end-1 end
+} -cleanup {
+ unset foo t
+} -result OK
+test dict-21.17 {dict update command: no recursive structures [Bug 1786481]} {
+ apply {{} {
+ set foo {a {b {c {d {e 1}}}}}
+ dict update foo a t {
+ dict update t b t {
+ dict update t c t {
+ dict update t d t {
+ dict incr t e
+ }
+ }
+ }
+ }
+ string range [append foo OK] end-1 end
+ }}
+} OK
+
+test dict-22.1 {dict with command} -body {
+ dict with
+} -returnCodes 1 -result {wrong # args: should be "dict with dictVar ?key ...? script"}
+test dict-22.2 {dict with command} -body {
+ dict with v
+} -returnCodes 1 -result {wrong # args: should be "dict with dictVar ?key ...? script"}
+test dict-22.3 {dict with command} -body {
+ unset -nocomplain v
+ dict with v {error "in body"}
+} -returnCodes 1 -result {can't read "v": no such variable}
+test dict-22.4 {dict with command} -body {
+ set a {b c d e}
+ unset -nocomplain b d
+ set result [list [info exist b] [info exist d]]
+ dict with a {
+ lappend result [info exist b] [info exist d] $b $d
+ }
+ return $result
+} -cleanup {
+ unset a b d result
+} -result {0 0 1 1 c e}
+test dict-22.5 {dict with command} -body {
+ set a {b c d e}
+ dict with a {
+ lassign "$b $d" d b
+ }
+ return $a
+} -cleanup {
+ unset a b d
+} -result {b e d c}
+test dict-22.6 {dict with command} -body {
+ set a {b c d e}
+ dict with a {
+ unset b
+ # This *won't* go into the dict...
+ set f g
+ }
+ return $a
+} -cleanup {
+ unset a d f
+} -result {d e}
+test dict-22.7 {dict with command} -body {
+ set a {b c d e}
+ dict with a {
+ dict unset a b
+ }
+ return $a
+} -cleanup {
+ unset a
+} -result {d e b c}
+test dict-22.8 {dict with command} -body {
+ set a [dict create b c]
+ dict with a {
+ set b $a
+ }
+ return $a
+} -cleanup {
+ unset a b
+} -result {b {b c}}
+test dict-22.9 {dict with command} -body {
+ set a {b {c d}}
+ dict with a b {
+ set c $c$c
+ }
+ return $a
+} -cleanup {
+ unset a c
+} -result {b {c dd}}
+test dict-22.10 {dict with command: result handling tricky case} -body {
+ set a {b {c d}}
+ foreach i {0 1} {
+ if {$i} break
+ dict with a b {
+ set a {}
+ # We're checking to see if we lose this break
+ break
+ }
+ }
+ list $i $a
+} -cleanup {
+ unset a i c
+} -result {0 {}}
+test dict-22.11 {dict with command: no recursive structures [Bug 1786481]} -body {
+ set foo {t {t {t {inner 1}}}}
+ dict with foo {
+ dict with t {
+ dict with t {
+ dict with t {
+ incr inner
+ }
+ }
+ }
+ }
+ string range [append foo OK] end-1 end
+} -cleanup {
+ unset foo t inner
+} -result OK
+test dict-22.12 {dict with: compiled} {
+ apply {{} {
+ set d {a 1 b 2}
+ list [dict with d {
+ set a $b
+ unset b
+ dict set d c 3
+ list ok
+ }] $d
+ }}
+} {ok {a 2 c 3}}
+test dict-22.13 {dict with: compiled} {
+ apply {i {
+ set d($i) {a 1 b 2}
+ list [dict with d($i) {
+ set a $b
+ unset b
+ dict set d($i) c 3
+ list ok
+ }] [array get d]
+ }} e
+} {ok {e {a 2 c 3}}}
+test dict-22.14 {dict with: compiled} {
+ apply {{} {
+ set d {a 1 b 2}
+ foreach x {1 2 3} {
+ dict with d {
+ incr a $b
+ if {$x == 2} break
+ }
+ unset a b
+ }
+ list $a $b $x $d
+ }}
+} {5 2 2 {a 5 b 2}}
+test dict-22.15 {dict with: compiled} {
+ apply {i {
+ set d($i) {a 1 b 2}
+ foreach x {1 2 3} {
+ dict with d($i) {
+ incr a $b
+ if {$x == 2} break
+ }
+ unset a b
+ }
+ list $a $b $x [array get d]
+ }} e
+} {5 2 2 {e {a 5 b 2}}}
+test dict-22.16 {dict with: compiled} {
+ apply {{} {
+ set d {p {q {a 1 b 2}}}
+ dict with d p q {
+ set a $b.$a
+ }
+ return $d
+ }}
+} {p {q {a 2.1 b 2}}}
+test dict-22.17 {dict with: compiled} {
+ apply {i {
+ set d($i) {p {q {a 1 b 2}}}
+ dict with d($i) p q {
+ set a $b.$a
+ }
+ array get d
+ }} e
+} {e {p {q {a 2.1 b 2}}}}
+test dict-22.18 {dict with: compiled} {
+ set ::d {a 1 b 2}
+ apply {{} {
+ dict with ::d {
+ set a $b.$a
+ }
+ return $::d
+ }}
+} {a 2.1 b 2}
+test dict-22.19 {dict with: compiled} {
+ set ::d {p {q {r {a 1 b 2}}}}
+ apply {{} {
+ dict with ::d p q r {
+ set a $b.$a
+ }
+ return $::d
+ }}
+} {p {q {r {a 2.1 b 2}}}}
+test dict-22.20 {dict with: compiled} {
+ apply {d {
+ dict with d {
+ }
+ return $a,$b
+ }} {a 1 b 2}
+} 1,2
+test dict-22.21 {dict with: compiled} {
+ apply {d {
+ dict with d p q {
+ }
+ return $a,$b
+ }} {p {q {a 1 b 2}}}
+} 1,2
+test dict-22.22 {dict with: compiled} {
+ set ::d {a 1 b 2}
+ apply {{} {
+ dict with ::d {
+ }
+ return $a,$b
+ }}
+} 1,2
+test dict-22.23 {dict with: compiled} {
+ set ::d {p {q {a 1 b 2}}}
+ apply {{} {
+ dict with ::d p q {
+ }
+ return $a,$b
+ }}
+} 1,2
+
+proc linenumber {} {
+ dict get [info frame -1] line
+}
+test dict-23.1 {dict compilation crash: Bug 3487626} {
+ apply {{} {apply {n {
+ set e {}
+ set k {}
+ dict for {a b} {c {d {e {f g}}}} {
+ ::tcl::dict::for {h i} $b {
+ dict update i e j {
+ ::tcl::dict::update j f k {
+ return [expr {$n - [linenumber]}]
+ }
+ }
+ }
+ }
+ }} [linenumber]}}
+} 5
+test dict-23.2 {dict compilation crash: Bug 3487626} knownBug {
+ # Something isn't quite right in line number and continuation line
+ # tracking; at time of writing, this test produces 7, not 5, which
+ # indicates that the extra newlines in the non-script argument are
+ # confusing things.
+ apply {{} {apply {n {
+ set e {}
+ set k {}
+ dict for {a {
+b
+}} {c {d {e {f g}}}} {
+ ::tcl::dict::for {h {
+i
+}} ${
+b
+} {
+ dict update {
+i
+} e {
+j
+} {
+ ::tcl::dict::update {
+j
+} f k {
+ return [expr {$n - [linenumber]}]
+ }
+ }
+ }
+ }
+ }} [linenumber]}}
+} 5
+rename linenumber {}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/dstring.test b/library/msgcat/tests/dstring.test
new file mode 100644
index 0000000..bcc304d
--- /dev/null
+++ b/library/msgcat/tests/dstring.test
@@ -0,0 +1,436 @@
+# Commands covered: none
+#
+# This file contains a collection of tests for Tcl's dynamic string library
+# procedures. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testdstring [llength [info commands testdstring]]
+if {[testConstraint testdstring]} {
+ testdstring free
+}
+
+test dstring-1.1 {appending and retrieving} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append "abc" -1
+ list [testdstring get] [testdstring length]
+} -cleanup {
+ testdstring free
+} -result {abc 3}
+test dstring-1.2 {appending and retrieving} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append "abc" -1
+ testdstring append " xyzzy" 3
+ testdstring append " 12345" -1
+ list [testdstring get] [testdstring length]
+} -cleanup {
+ testdstring free
+} -result {{abc xy 12345} 12}
+test dstring-1.3 {appending and retrieving} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ foreach l {a b c d e f g h i j k l m n o p} {
+ testdstring append $l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l\n -1
+ }
+ list [testdstring get] [testdstring length]
+} -cleanup {
+ testdstring free
+} -result {{aaaaaaaaaaaaaaaaaaaaa
+bbbbbbbbbbbbbbbbbbbbb
+ccccccccccccccccccccc
+ddddddddddddddddddddd
+eeeeeeeeeeeeeeeeeeeee
+fffffffffffffffffffff
+ggggggggggggggggggggg
+hhhhhhhhhhhhhhhhhhhhh
+iiiiiiiiiiiiiiiiiiiii
+jjjjjjjjjjjjjjjjjjjjj
+kkkkkkkkkkkkkkkkkkkkk
+lllllllllllllllllllll
+mmmmmmmmmmmmmmmmmmmmm
+nnnnnnnnnnnnnnnnnnnnn
+ooooooooooooooooooooo
+ppppppppppppppppppppp
+} 352}
+
+test dstring-2.1 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring element "abc"
+ testdstring element "d e f"
+ list [testdstring get] [testdstring length]
+} -cleanup {
+ testdstring free
+} -result {{abc {d e f}} 11}
+test dstring-2.2 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring element "x"
+ testdstring element "\{"
+ testdstring element "ab\}"
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {x \{ ab\}}
+test dstring-2.3 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ foreach l {a b c d e f g h i j k l m n o p} {
+ testdstring element $l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l
+ }
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {aaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbb ccccccccccccccccccccc ddddddddddddddddddddd eeeeeeeeeeeeeeeeeeeee fffffffffffffffffffff ggggggggggggggggggggg hhhhhhhhhhhhhhhhhhhhh iiiiiiiiiiiiiiiiiiiii jjjjjjjjjjjjjjjjjjjjj kkkkkkkkkkkkkkkkkkkkk lllllllllllllllllllll mmmmmmmmmmmmmmmmmmmmm nnnnnnnnnnnnnnnnnnnnn ooooooooooooooooooooo ppppppppppppppppppppp}
+test dstring-2.4 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append "a\{" -1
+ testdstring element abc
+ testdstring append " \{" -1
+ testdstring element xyzzy
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result "a{ abc {xyzzy"
+test dstring-2.5 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append " \{" -1
+ testdstring element abc
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result " {abc"
+test dstring-2.6 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append " " -1
+ testdstring element abc
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result { abc}
+test dstring-2.7 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append "\\ " -1
+ testdstring element abc
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result "\\ abc"
+test dstring-2.8 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append "x " -1
+ testdstring element abc
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {x abc}
+test dstring-2.9 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring element #
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {{#}}
+test dstring-2.10 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append " " -1
+ testdstring element #
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result { {#}}
+test dstring-2.11 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append \t -1
+ testdstring element #
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result \t{#}
+test dstring-2.12 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append x -1
+ testdstring element #
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {x #}
+test dstring-2.13 {appending list elements} -constraints testdstring -body {
+ # This test shows lack of sophistication in Tcl_DStringAppendElement's
+ # decision about whether #-quoting can be disabled.
+ testdstring free
+ testdstring append "x " -1
+ testdstring element #
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {x {#}}
+
+test dstring-3.1 {nested sublists} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring start
+ testdstring element foo
+ testdstring element bar
+ testdstring end
+ testdstring element another
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {{foo bar} another}
+test dstring-3.2 {nested sublists} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring start
+ testdstring start
+ testdstring element abc
+ testdstring element def
+ testdstring end
+ testdstring end
+ testdstring element ghi
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {{{abc def}} ghi}
+test dstring-3.3 {nested sublists} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring start
+ testdstring start
+ testdstring start
+ testdstring element foo
+ testdstring element foo2
+ testdstring end
+ testdstring end
+ testdstring element foo3
+ testdstring end
+ testdstring element foo4
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {{{{foo foo2}} foo3} foo4}
+test dstring-3.4 {nested sublists} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring element before
+ testdstring start
+ testdstring element during
+ testdstring element more
+ testdstring end
+ testdstring element last
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {before {during more} last}
+test dstring-3.5 {nested sublists} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring element "\{"
+ testdstring start
+ testdstring element first
+ testdstring element second
+ testdstring end
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {\{ {first second}}
+test dstring-3.6 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append x -1
+ testdstring start
+ testdstring element #
+ testdstring end
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {x {{#}}}
+test dstring-3.7 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append x -1
+ testdstring start
+ testdstring append " " -1
+ testdstring element #
+ testdstring end
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {x { {#}}}
+test dstring-3.8 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append x -1
+ testdstring start
+ testdstring append \t -1
+ testdstring element #
+ testdstring end
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result "x {\t{#}}"
+test dstring-3.9 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append x -1
+ testdstring start
+ testdstring append x -1
+ testdstring element #
+ testdstring end
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {x {x #}}
+test dstring-3.10 {appending list elements} -constraints testdstring -body {
+ # This test shows lack of sophistication in Tcl_DStringAppendElement's
+ # decision about whether #-quoting can be disabled.
+ testdstring free
+ testdstring append x -1
+ testdstring start
+ testdstring append "x " -1
+ testdstring element #
+ testdstring end
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {x {x {#}}}
+
+test dstring-4.1 {truncation} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append "abcdefg" -1
+ testdstring trunc 3
+ list [testdstring get] [testdstring length]
+} -cleanup {
+ testdstring free
+} -result {abc 3}
+test dstring-4.2 {truncation} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append "xyzzy" -1
+ testdstring trunc 0
+ list [testdstring get] [testdstring length]
+} -cleanup {
+ testdstring free
+} -result {{} 0}
+
+test dstring-5.1 {copying to result} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append xyz -1
+ testdstring result
+} -cleanup {
+ testdstring free
+} -result xyz
+test dstring-5.2 {copying to result} -constraints testdstring -setup {
+ testdstring free
+ unset -nocomplain a
+} -body {
+ foreach l {a b c d e f g h i j k l m n o p} {
+ testdstring append $l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l\n -1
+ }
+ set a [testdstring result]
+ testdstring append abc -1
+ list $a [testdstring get]
+} -cleanup {
+ testdstring free
+} -result {{aaaaaaaaaaaaaaaaaaaaa
+bbbbbbbbbbbbbbbbbbbbb
+ccccccccccccccccccccc
+ddddddddddddddddddddd
+eeeeeeeeeeeeeeeeeeeee
+fffffffffffffffffffff
+ggggggggggggggggggggg
+hhhhhhhhhhhhhhhhhhhhh
+iiiiiiiiiiiiiiiiiiiii
+jjjjjjjjjjjjjjjjjjjjj
+kkkkkkkkkkkkkkkkkkkkk
+lllllllllllllllllllll
+mmmmmmmmmmmmmmmmmmmmm
+nnnnnnnnnnnnnnnnnnnnn
+ooooooooooooooooooooo
+ppppppppppppppppppppp
+} abc}
+
+test dstring-6.1 {Tcl_DStringGetResult} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ list [testdstring gresult staticsmall] [testdstring get]
+} -cleanup {
+ testdstring free
+} -result {{} short}
+test dstring-6.2 {Tcl_DStringGetResult} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ foreach l {a b c d e f g h i j k l m n o p} {
+ testdstring append $l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l\n -1
+ }
+ list [testdstring gresult staticsmall] [testdstring get]
+} -cleanup {
+ testdstring free
+} -result {{} short}
+test dstring-6.3 {Tcl_DStringGetResult} -constraints testdstring -body {
+ set result {}
+ lappend result [testdstring gresult staticlarge]
+ testdstring append x 1
+ lappend result [testdstring get]
+} -cleanup {
+ testdstring free
+} -result {{} {first0 first1 first2 first3 first4 first5 first6 first7 first8 first9
+second0 second1 second2 second3 second4 second5 second6 second7 second8 second9
+third0 third1 third2 third3 third4 third5 third6 third7 third8 third9
+fourth0 fourth1 fourth2 fourth3 fourth4 fourth5 fourth6 fourth7 fourth8 fourth9
+fifth0 fifth1 fifth2 fifth3 fifth4 fifth5 fifth6 fifth7 fifth8 fifth9
+sixth0 sixth1 sixth2 sixth3 sixth4 sixth5 sixth6 sixth7 sixth8 sixth9
+seventh0 seventh1 seventh2 seventh3 seventh4 seventh5 seventh6 seventh7 seventh8 seventh9
+x}}
+test dstring-6.4 {Tcl_DStringGetResult} -constraints testdstring -body {
+ set result {}
+ lappend result [testdstring gresult free]
+ testdstring append y 1
+ lappend result [testdstring get]
+} -cleanup {
+ testdstring free
+} -result {{} {This is a malloc-ed stringy}}
+test dstring-6.5 {Tcl_DStringGetResult} -constraints testdstring -body {
+ set result {}
+ lappend result [testdstring gresult special]
+ testdstring append z 1
+ lappend result [testdstring get]
+} -cleanup {
+ testdstring free
+} -result {{} {This is a specially-allocated stringz}}
+
+# cleanup
+if {[testConstraint testdstring]} {
+ testdstring free
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/encoding.test b/library/msgcat/tests/encoding.test
new file mode 100644
index 0000000..51b7aa1
--- /dev/null
+++ b/library/msgcat/tests/encoding.test
@@ -0,0 +1,597 @@
+# This file contains a collection of tests for tclEncoding.c
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+
+namespace eval ::tcl::test::encoding {
+ variable x
+
+namespace import -force ::tcltest::*
+
+proc toutf {args} {
+ variable x
+ lappend x "toutf $args"
+}
+proc fromutf {args} {
+ variable x
+ lappend x "fromutf $args"
+}
+
+proc runtests {} {
+ variable x
+
+# Some tests require the testencoding command
+testConstraint testencoding [llength [info commands testencoding]]
+testConstraint exec [llength [info commands exec]]
+testConstraint testgetdefenc [llength [info commands testgetdefenc]]
+testConstraint testfinexit [llength [info commands testfinexit]]
+
+# TclInitEncodingSubsystem is tested by the rest of this file
+# TclFinalizeEncodingSubsystem is not currently tested
+
+test encoding-1.1 {Tcl_GetEncoding: system encoding} -setup {
+ set old [encoding system]
+} -constraints {testencoding} -body {
+ testencoding create foo [namespace origin toutf] [namespace origin fromutf]
+ encoding system foo
+ set x {}
+ encoding convertto abcd
+ return $x
+} -cleanup {
+ encoding system $old
+ testencoding delete foo
+} -result {{fromutf }}
+test encoding-1.2 {Tcl_GetEncoding: existing encoding} {testencoding} {
+ testencoding create foo [namespace origin toutf] [namespace origin fromutf]
+ set x {}
+ encoding convertto foo abcd
+ testencoding delete foo
+ return $x
+} {{fromutf }}
+test encoding-1.3 {Tcl_GetEncoding: load encoding} {
+ list [encoding convertto jis0208 \u4e4e] \
+ [encoding convertfrom jis0208 8C]
+} "8C \u4e4e"
+
+test encoding-2.1 {Tcl_FreeEncoding: refcount == 0} {
+ encoding convertto jis0208 \u4e4e
+} {8C}
+test encoding-2.2 {Tcl_FreeEncoding: refcount != 0} -setup {
+ set system [encoding system]
+ set path [encoding dirs]
+} -constraints {testencoding} -body {
+ encoding system shiftjis ;# incr ref count
+ encoding dirs [list [pwd]]
+ set x [encoding convertto shiftjis \u4e4e] ;# old one found
+ encoding system identity
+ llength shiftjis ;# Shimmer away any cache of Tcl_Encoding
+ lappend x [catch {encoding convertto shiftjis \u4e4e} msg] $msg
+} -cleanup {
+ encoding system identity
+ encoding dirs $path
+ encoding system $system
+} -result "\u008c\u00c1 1 {unknown encoding \"shiftjis\"}"
+
+test encoding-3.1 {Tcl_GetEncodingName, NULL} -setup {
+ set old [encoding system]
+} -body {
+ encoding system shiftjis
+ encoding system
+} -cleanup {
+ encoding system $old
+} -result {shiftjis}
+test encoding-3.2 {Tcl_GetEncodingName, non-null} -setup {
+ set old [fconfigure stdout -encoding]
+} -body {
+ fconfigure stdout -encoding jis0208
+ fconfigure stdout -encoding
+} -cleanup {
+ fconfigure stdout -encoding $old
+} -result {jis0208}
+
+test encoding-4.1 {Tcl_GetEncodingNames} -constraints {testencoding} -setup {
+ cd [makeDirectory tmp]
+ makeDirectory [file join tmp encoding]
+ set path [encoding dirs]
+ encoding dirs {}
+ catch {unset encodings}
+ catch {unset x}
+} -body {
+ foreach encoding [encoding names] {
+ set encodings($encoding) 1
+ }
+ makeFile {} [file join tmp encoding junk.enc]
+ makeFile {} [file join tmp encoding junk2.enc]
+ encoding dirs [list [file join [pwd] encoding]]
+ foreach encoding [encoding names] {
+ if {![info exists encodings($encoding)]} {
+ lappend x $encoding
+ }
+ }
+ lsort $x
+} -cleanup {
+ encoding dirs $path
+ cd [workingDirectory]
+ removeFile [file join tmp encoding junk2.enc]
+ removeFile [file join tmp encoding junk.enc]
+ removeDirectory [file join tmp encoding]
+ removeDirectory tmp
+} -result {junk junk2}
+
+test encoding-5.1 {Tcl_SetSystemEncoding} -setup {
+ set old [encoding system]
+} -body {
+ encoding system jis0208
+ encoding convertto \u4e4e
+} -cleanup {
+ encoding system identity
+ encoding system $old
+} -result {8C}
+test encoding-5.2 {Tcl_SetSystemEncoding: test ref count} {
+ set old [encoding system]
+ encoding system $old
+ string compare $old [encoding system]
+} {0}
+
+test encoding-6.1 {Tcl_CreateEncoding: new} {testencoding} {
+ testencoding create foo [namespace code {toutf 1}] \
+ [namespace code {fromutf 2}]
+ set x {}
+ encoding convertfrom foo abcd
+ encoding convertto foo abcd
+ testencoding delete foo
+ return $x
+} {{toutf 1} {fromutf 2}}
+test encoding-6.2 {Tcl_CreateEncoding: replace encoding} {testencoding} {
+ testencoding create foo [namespace code {toutf a}] \
+ [namespace code {fromutf b}]
+ set x {}
+ encoding convertfrom foo abcd
+ encoding convertto foo abcd
+ testencoding delete foo
+ return $x
+} {{toutf a} {fromutf b}}
+
+test encoding-7.1 {Tcl_ExternalToUtfDString: small buffer} {
+ encoding convertfrom jis0208 8c8c8c8c
+} "\u543e\u543e\u543e\u543e"
+test encoding-7.2 {Tcl_UtfToExternalDString: big buffer} {
+ set a 8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C
+ append a $a
+ append a $a
+ append a $a
+ append a $a
+ set x [encoding convertfrom jis0208 $a]
+ list [string length $x] [string index $x 0]
+} "512 \u4e4e"
+
+test encoding-8.1 {Tcl_ExternalToUtf} {
+ set f [open [file join [temporaryDirectory] dummy] w]
+ fconfigure $f -translation binary -encoding iso8859-1
+ puts -nonewline $f "ab\x8c\xc1g"
+ close $f
+ set f [open [file join [temporaryDirectory] dummy] r]
+ fconfigure $f -translation binary -encoding shiftjis
+ set x [read $f]
+ close $f
+ file delete [file join [temporaryDirectory] dummy]
+ return $x
+} "ab\u4e4eg"
+
+test encoding-9.1 {Tcl_UtfToExternalDString: small buffer} {
+ encoding convertto jis0208 "\u543e\u543e\u543e\u543e"
+} {8c8c8c8c}
+test encoding-9.2 {Tcl_UtfToExternalDString: big buffer} {
+ set a \u4e4e\u4e4e\u4e4e\u4e4e\u4e4e\u4e4e\u4e4e\u4e4e
+ append a $a
+ append a $a
+ append a $a
+ append a $a
+ append a $a
+ append a $a
+ set x [encoding convertto jis0208 $a]
+ list [string length $x] [string range $x 0 1]
+} "1024 8C"
+
+test encoding-10.1 {Tcl_UtfToExternal} {
+ set f [open [file join [temporaryDirectory] dummy] w]
+ fconfigure $f -translation binary -encoding shiftjis
+ puts -nonewline $f "ab\u4e4eg"
+ close $f
+ set f [open [file join [temporaryDirectory] dummy] r]
+ fconfigure $f -translation binary -encoding iso8859-1
+ set x [read $f]
+ close $f
+ file delete [file join [temporaryDirectory] dummy]
+ return $x
+} "ab\x8c\xc1g"
+
+proc viewable {str} {
+ set res ""
+ foreach c [split $str {}] {
+ if {[string is print $c] && [string is ascii $c]} {
+ append res $c
+ } else {
+ append res "\\u[format %4.4x [scan $c %c]]"
+ }
+ }
+ return "$str ($res)"
+}
+
+test encoding-11.1 {LoadEncodingFile: unknown encoding} {testencoding} {
+ set system [encoding system]
+ set path [encoding dirs]
+ encoding system iso8859-1
+ encoding dirs {}
+ llength jis0208 ;# Shimmer any cached Tcl_Encoding in shared literal
+ set x [list [catch {encoding convertto jis0208 \u4e4e} msg] $msg]
+ encoding dirs $path
+ encoding system $system
+ lappend x [encoding convertto jis0208 \u4e4e]
+} {1 {unknown encoding "jis0208"} 8C}
+test encoding-11.2 {LoadEncodingFile: single-byte} {
+ encoding convertfrom jis0201 \xa1
+} "\uff61"
+test encoding-11.3 {LoadEncodingFile: double-byte} {
+ encoding convertfrom jis0208 8C
+} "\u4e4e"
+test encoding-11.4 {LoadEncodingFile: multi-byte} {
+ encoding convertfrom shiftjis \x8c\xc1
+} "\u4e4e"
+test encoding-11.5 {LoadEncodingFile: escape file} {
+ viewable [encoding convertto iso2022 \u4e4e]
+} [viewable "\x1b\$B8C\x1b(B"]
+test encoding-11.5.1 {LoadEncodingFile: escape file} {
+ viewable [encoding convertto iso2022-jp \u4e4e]
+} [viewable "\x1b\$B8C\x1b(B"]
+test encoding-11.6 {LoadEncodingFile: invalid file} -constraints {testencoding} -setup {
+ set system [encoding system]
+ set path [encoding dirs]
+ encoding system identity
+} -body {
+ cd [temporaryDirectory]
+ encoding dirs [file join tmp encoding]
+ makeDirectory tmp
+ makeDirectory [file join tmp encoding]
+ set f [open [file join tmp encoding splat.enc] w]
+ fconfigure $f -translation binary
+ puts $f "abcdefghijklmnop"
+ close $f
+ encoding convertto splat \u4e4e
+} -returnCodes error -cleanup {
+ file delete [file join [temporaryDirectory] tmp encoding splat.enc]
+ removeDirectory [file join tmp encoding]
+ removeDirectory tmp
+ cd [workingDirectory]
+ encoding dirs $path
+ encoding system $system
+} -result {invalid encoding file "splat"}
+
+# OpenEncodingFile is fully tested by the rest of the tests in this file.
+
+test encoding-12.1 {LoadTableEncoding: normal encoding} {
+ set x [encoding convertto iso8859-3 \u120]
+ append x [encoding convertto iso8859-3 \ud5]
+ append x [encoding convertfrom iso8859-3 \xd5]
+} "\xd5?\u120"
+test encoding-12.2 {LoadTableEncoding: single-byte encoding} {
+ set x [encoding convertto iso8859-3 ab\u0120g]
+ append x [encoding convertfrom iso8859-3 ab\xd5g]
+} "ab\xd5gab\u120g"
+test encoding-12.3 {LoadTableEncoding: multi-byte encoding} {
+ set x [encoding convertto shiftjis ab\u4e4eg]
+ append x [encoding convertfrom shiftjis ab\x8c\xc1g]
+} "ab\x8c\xc1gab\u4e4eg"
+test encoding-12.4 {LoadTableEncoding: double-byte encoding} {
+ set x [encoding convertto jis0208 \u4e4e\u3b1]
+ append x [encoding convertfrom jis0208 8C&A]
+} "8C&A\u4e4e\u3b1"
+test encoding-12.5 {LoadTableEncoding: symbol encoding} {
+ set x [encoding convertto symbol \u3b3]
+ append x [encoding convertto symbol \u67]
+ append x [encoding convertfrom symbol \x67]
+} "\x67\x67\u3b3"
+
+test encoding-13.1 {LoadEscapeTable} {
+ viewable [set x [encoding convertto iso2022 ab\u4e4e\u68d9g]]
+} [viewable "ab\x1b\$B8C\x1b\$\(DD%\x1b(Bg"]
+
+test encoding-14.1 {BinaryProc} {
+ encoding convertto identity \x12\x34\x56\xff\x69
+} "\x12\x34\x56\xc3\xbf\x69"
+
+test encoding-15.1 {UtfToUtfProc} {
+ encoding convertto utf-8 \xa3
+} "\xc2\xa3"
+test encoding-15.2 {UtfToUtfProc null character output} {
+ set x \u0000
+ set y [encoding convertto utf-8 \u0000]
+ set y [encoding convertfrom identity $y]
+ binary scan $y H* z
+ list [string bytelength $x] [string bytelength $y] $z
+} {2 1 00}
+test encoding-15.3 {UtfToUtfProc null character input} {
+ set x [encoding convertfrom identity \x00]
+ set y [encoding convertfrom utf-8 $x]
+ binary scan [encoding convertto identity $y] H* z
+ list [string bytelength $x] [string bytelength $y] $z
+} {1 2 c080}
+
+test encoding-16.1 {UnicodeToUtfProc} {
+ set val [encoding convertfrom unicode NN]
+ list $val [format %x [scan $val %c]]
+} "\u4e4e 4e4e"
+
+test encoding-17.1 {UtfToUnicodeProc} {
+} {}
+
+test encoding-18.1 {TableToUtfProc} {
+} {}
+
+test encoding-19.1 {TableFromUtfProc} {
+} {}
+
+test encoding-20.1 {TableFreefProc} {
+} {}
+
+test encoding-21.1 {EscapeToUtfProc} {
+} {}
+
+test encoding-22.1 {EscapeFromUtfProc} {
+} {}
+
+set iso2022encData "\u001b\$B;d\$I\$b\$G\$O!\"%A%C%W\$49XF~;~\$K\$4EPO?\$\$\$?\$@\$\$\$?\$4=;=j\$r%-%c%C%7%e%\"%&%H\$N:]\$N\u001b(B
+\u001b\$B>.@Z<jAwIU@h\$H\$7\$F;HMQ\$7\$F\$*\$j\$^\$9!#62\$lF~\$j\$^\$9\$,!\"@5\$7\$\$=;=j\$r\$4EPO?\$7\$J\$*\u001b(B
+\u001b\$B\$*4j\$\$\$\$\$?\$7\$^\$9!#\$^\$?!\"BgJQ62=L\$G\$9\$,!\"=;=jJQ99\$N\$\"\$H!\"F|K\\8l%5!<%S%9It!J\u001b(B
+casino_japanese@___.com \u001b\$B!K\$^\$G\$4=;=jJQ99:Q\$NO\"Mm\$r\$\$\$?\$@\$1\$J\$\$\$G\u001b(B
+\u001b\$B\$7\$g\$&\$+!)\u001b(B"
+
+set iso2022uniData [encoding convertfrom iso2022-jp $iso2022encData]
+set iso2022uniData2 "\u79c1\u3069\u3082\u3067\u306f\u3001\u30c1\u30c3\u30d7\u3054\u8cfc\u5165\u6642\u306b\u3054\u767b\u9332\u3044\u305f\u3060\u3044\u305f\u3054\u4f4f\u6240\u3092\u30ad\u30e3\u30c3\u30b7\u30e5\u30a2\u30a6\u30c8\u306e\u969b\u306e
+\u5c0f\u5207\u624b\u9001\u4ed8\u5148\u3068\u3057\u3066\u4f7f\u7528\u3057\u3066\u304a\u308a\u307e\u3059\u3002\u6050\u308c\u5165\u308a\u307e\u3059\u304c\u3001\u6b63\u3057\u3044\u4f4f\u6240\u3092\u3054\u767b\u9332\u3057\u306a\u304a
+\u304a\u9858\u3044\u3044\u305f\u3057\u307e\u3059\u3002\u307e\u305f\u3001\u5927\u5909\u6050\u7e2e\u3067\u3059\u304c\u3001\u4f4f\u6240\u5909\u66f4\u306e\u3042\u3068\u3001\u65e5\u672c\u8a9e\u30b5\u30fc\u30d3\u30b9\u90e8\uff08
+\u0063\u0061\u0073\u0069\u006e\u006f\u005f\u006a\u0061\u0070\u0061\u006e\u0065\u0073\u0065\u0040\u005f\u005f\u005f\u002e\u0063\u006f\u006d\u0020\uff09\u307e\u3067\u3054\u4f4f\u6240\u5909\u66f4\u6e08\u306e\u9023\u7d61\u3092\u3044\u305f\u3060\u3051\u306a\u3044\u3067
+\u3057\u3087\u3046\u304b\uff1f"
+
+cd [temporaryDirectory]
+set fid [open iso2022.txt w]
+fconfigure $fid -encoding binary
+puts -nonewline $fid $iso2022encData
+close $fid
+
+test encoding-23.1 {iso2022-jp escape encoding test} {
+ string equal $iso2022uniData $iso2022uniData2
+} 1
+test encoding-23.2 {iso2022-jp escape encoding test} {
+ # This checks that 'gets' isn't resetting the encoding inappropriately.
+ # [Bug #523988]
+ set fid [open iso2022.txt r]
+ fconfigure $fid -encoding iso2022-jp
+ set out ""
+ set count 0
+ while {[set num [gets $fid line]] >= 0} {
+ if {$count} {
+ incr count 1 ; # account for newline
+ append out \n
+ }
+ append out $line
+ incr count $num
+ }
+ close $fid
+ if {[string compare $iso2022uniData $out]} {
+ return -code error "iso2022-jp read in doesn't match original"
+ }
+ list $count $out
+} [list [string length $iso2022uniData] $iso2022uniData]
+test encoding-23.3 {iso2022-jp escape encoding test} {
+ # read $fis <size> reads size in chars, not raw bytes.
+ set fid [open iso2022.txt r]
+ fconfigure $fid -encoding iso2022-jp
+ set data [read $fid 50]
+ close $fid
+ return $data
+} [string range $iso2022uniData 0 49] ; # 0 .. 49 inclusive == 50
+cd [workingDirectory]
+
+# Code to make the next few tests more intelligible; the code being tested
+# should be in the body of the test!
+proc runInSubprocess {contents {filename iso2022.tcl}} {
+ set theFile [makeFile $contents $filename]
+ try {
+ exec [interpreter] $theFile
+ } finally {
+ removeFile $theFile
+ }
+}
+
+test encoding-24.1 {EscapeFreeProc on open channels} exec {
+ runInSubprocess {
+ set f [open [file join [file dirname [info script]] iso2022.txt]]
+ fconfigure $f -encoding iso2022-jp
+ gets $f
+ }
+} {}
+test encoding-24.2 {EscapeFreeProc on open channels} {exec testfinexit} {
+ # Bug #524674 output
+ viewable [runInSubprocess {
+ encoding system cp1252; # Bug #2891556 crash revelator
+ fconfigure stdout -encoding iso2022-jp
+ puts ab\u4e4e\u68d9g
+ testfinexit
+ }]
+} "ab\x1b\$B8C\x1b\$(DD%\x1b(Bg (ab\\u001b\$B8C\\u001b\$(DD%\\u001b(Bg)"
+test encoding-24.3 {EscapeFreeProc on open channels} {stdio} {
+ # Bug #219314 - if we don't free escape encodings correctly on channel
+ # closure, we go boom
+ set file [makeFile {
+ encoding system iso2022-jp
+ set a "\u4e4e\u4e5e\u4e5f"; # 3 Japanese Kanji letters
+ puts $a
+ } iso2022.tcl]
+ set f [open "|[list [interpreter] $file]"]
+ fconfigure $f -encoding iso2022-jp
+ set count [gets $f line]
+ close $f
+ removeFile iso2022.tcl
+ list $count [viewable $line]
+} [list 3 "\u4e4e\u4e5e\u4e5f (\\u4e4e\\u4e5e\\u4e5f)"]
+
+file delete [file join [temporaryDirectory] iso2022.txt]
+
+#
+# Begin jajp encoding round-trip conformity tests
+#
+proc foreach-jisx0208 {varName command} {
+ upvar 1 $varName code
+ foreach range {
+ {2121 217E}
+ {2221 222E}
+ {223A 2241}
+ {224A 2250}
+ {225C 226A}
+ {2272 2279}
+ {227E 227E}
+ {2330 2339}
+ {2421 2473}
+ {2521 2576}
+ {2821 2821}
+ {282C 282C}
+ {2837 2837}
+
+ {30 21 4E 7E}
+ {4F21 4F53}
+
+ {50 21 73 7E}
+ {7421 7426}
+ } {
+ if {[llength $range] == 2} {
+ # for adhoc range. simple {first last}. inclusive.
+ scan $range %x%x first last
+ for {set i $first} {$i <= $last} {incr i} {
+ set code $i
+ uplevel 1 $command
+ }
+ } elseif {[llength $range] == 4} {
+ # for uniform range.
+ scan $range %x%x%x%x h0 l0 hend lend
+ for {set hi $h0} {$hi <= $hend} {incr hi} {
+ for {set lo $l0} {$lo <= $lend} {incr lo} {
+ set code [expr {$hi << 8 | ($lo & 0xff)}]
+ uplevel 1 $command
+ }
+ }
+ } else {
+ error "really?"
+ }
+ }
+}
+proc gen-jisx0208-euc-jp {code} {
+ binary format cc \
+ [expr {($code >> 8) | 0x80}] [expr {($code & 0xff) | 0x80}]
+}
+proc gen-jisx0208-iso2022-jp {code} {
+ binary format a3cca3 \
+ "\x1b\$B" [expr {$code >> 8}] [expr {$code & 0xff}] "\x1b(B"
+}
+proc gen-jisx0208-cp932 {code} {
+ set c1 [expr {($code >> 8) | 0x80}]
+ set c2 [expr {($code & 0xff)| 0x80}]
+ if {$c1 % 2} {
+ set c1 [expr {($c1 >> 1) + ($c1 < 0xdf ? 0x31 : 0x71)}]
+ incr c2 [expr {- (0x60 + ($c2 < 0xe0))}]
+ } else {
+ set c1 [expr {($c1 >> 1) + ($c1 < 0xdf ? 0x30 : 0x70)}]
+ incr c2 -2
+ }
+ binary format cc $c1 $c2
+}
+proc channel-diff {fa fb} {
+ set diff {}
+ while {[gets $fa la] >= 0 && [gets $fb lb] >= 0} {
+ if {[string compare $la $lb] == 0} continue
+ # lappend diff $la $lb
+
+ # For more readable (easy to analyze) output.
+ set code [lindex $la 0]
+ binary scan [lindex $la 1] H* expected
+ binary scan [lindex $lb 1] H* got
+ lappend diff [list $code $expected $got]
+ }
+ return $diff
+}
+
+# Create char tables.
+cd [temporaryDirectory]
+foreach enc {cp932 euc-jp iso2022-jp} {
+ set f [open $enc.chars w]
+ fconfigure $f -encoding binary
+ foreach-jisx0208 code {
+ puts $f [format "%04X %s" $code [gen-jisx0208-$enc $code]]
+ }
+ close $f
+}
+# shiftjis == cp932 for jisx0208.
+file copy -force cp932.chars shiftjis.chars
+
+set NUM 0
+foreach from {cp932 shiftjis euc-jp iso2022-jp} {
+ foreach to {cp932 shiftjis euc-jp iso2022-jp} {
+ test encoding-25.[incr NUM] "jisx0208 $from => $to" -setup {
+ cd [temporaryDirectory]
+ } -body {
+ set f [open $from.chars]
+ fconfigure $f -encoding $from
+ set out [open $from.$to.tcltestout w]
+ fconfigure $out -encoding $to
+ puts -nonewline $out [read $f]
+ close $out
+ close $f
+ # then compare $to.chars <=> $from.to.tcltestout as binary.
+ set fa [open $to.chars rb]
+ set fb [open $from.$to.tcltestout rb]
+ channel-diff $fa $fb
+ # Difference should be empty.
+ } -cleanup {
+ close $fa
+ close $fb
+ } -result {}
+ }
+}
+
+test encoding-26.0 {Tcl_GetDefaultEncodingDir} -constraints {
+ testgetdefenc
+} -setup {
+ set origDir [testgetdefenc]
+ testsetdefenc slappy
+} -body {
+ testgetdefenc
+} -cleanup {
+ testsetdefenc $origDir
+} -result slappy
+
+file delete {*}[glob -directory [temporaryDirectory] *.chars *.tcltestout]
+# ===> Cut here <===
+
+# EscapeFreeProc, GetTableEncoding, unilen are fully tested by the rest of
+# this file.
+
+}
+runtests
+
+}
+
+# cleanup
+namespace delete ::tcl::test::encoding
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/env.test b/library/msgcat/tests/env.test
new file mode 100644
index 0000000..9010f52
--- /dev/null
+++ b/library/msgcat/tests/env.test
@@ -0,0 +1,308 @@
+# Commands covered: none (tests environment variable implementation)
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Some tests require the "exec" command.
+# Skip them if exec is not defined.
+testConstraint exec [llength [info commands exec]]
+
+#
+# These tests will run on any platform (and indeed crashed on the Mac). So put
+# them before you test for the existance of exec.
+#
+test env-1.1 {propagation of env values to child interpreters} -setup {
+ catch {interp delete child}
+ catch {unset env(test)}
+} -body {
+ interp create child
+ set env(test) garbage
+ child eval {set env(test)}
+} -cleanup {
+ interp delete child
+ unset env(test)
+} -result {garbage}
+#
+# This one crashed on Solaris under Tcl8.0, so we only want to make sure it
+# runs.
+#
+test env-1.2 {lappend to env value} -setup {
+ catch {unset env(test)}
+} -body {
+ set env(test) aaaaaaaaaaaaaaaa
+ append env(test) bbbbbbbbbbbbbb
+ unset env(test)
+}
+test env-1.3 {reflection of env by "array names"} -setup {
+ catch {interp delete child}
+ catch {unset env(test)}
+} -body {
+ interp create child
+ child eval {set env(test) garbage}
+ expr {"test" in [array names env]}
+} -cleanup {
+ interp delete child
+ catch {unset env(test)}
+} -result {1}
+
+set printenvScript [makeFile {
+ encoding system iso8859-1
+ proc lrem {listname name} {
+ upvar $listname list
+ set i [lsearch -nocase $list $name]
+ if {$i >= 0} {
+ set list [lreplace $list $i $i]
+ }
+ return $list
+ }
+ proc mangle s {
+ regsub -all {\[|\\|\]} $s {\\&} s
+ regsub -all {[\u0000-\u001f\u007f-\uffff]} $s {[manglechar &]} s
+ return [subst -novariables $s]
+ }
+ proc manglechar c {
+ return [format {\u%04x} [scan $c %c]]
+ }
+
+ set names [lsort [array names env]]
+ if {$tcl_platform(platform) eq "windows"} {
+ lrem names HOME
+ lrem names COMSPEC
+ lrem names ComSpec
+ lrem names ""
+ }
+ foreach name {
+ TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH PURE_PROG_NAME DISPLAY
+ SHLIB_PATH SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH
+ DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING
+ __CF_USER_TEXT_ENCODING SECURITYSESSIONID LANG WINDIR TERM
+ CommonProgramFiles ProgramFiles
+ } {
+ lrem names $name
+ }
+ foreach p $names {
+ puts "[mangle $p]=[mangle $env($p)]"
+ }
+ exit
+} printenv]
+
+# [exec] is required here to see the actual environment received by child
+# processes.
+proc getenv {} {
+ global printenvScript tcltest
+ catch {exec [interpreter] $printenvScript} out
+ if {$out eq "child process exited abnormally"} {
+ set out {}
+ }
+ return $out
+}
+
+# Save the current environment variables at the start of the test.
+
+set env2 [array get env]
+foreach name [array names env] {
+ # Keep some environment variables that support operation of the tcltest
+ # package.
+ if {[string toupper $name] ni {
+ TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH DISPLAY SHLIB_PATH
+ SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH
+ DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING
+ SECURITYSESSIONID LANG WINDIR TERM
+ CommonProgramFiles ProgramFiles
+ }} {
+ unset env($name)
+ }
+}
+
+# Need to run 'getenv' in known encoding, so save the current one here...
+set sysenc [encoding system]
+
+test env-2.1 {adding environment variables} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ getenv
+} -cleanup {
+ encoding system $sysenc
+} -result {}
+test env-2.2 {adding environment variables} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ set env(NAME1) "test string"
+ getenv
+} -cleanup {
+ encoding system $sysenc
+} -result {NAME1=test string}
+test env-2.3 {adding environment variables} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ set env(NAME2) "more"
+ getenv
+} -cleanup {
+ encoding system $sysenc
+} -result {NAME1=test string
+NAME2=more}
+test env-2.4 {adding environment variables} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ set env(XYZZY) "garbage"
+ getenv
+} -cleanup {
+ encoding system $sysenc
+} -result {NAME1=test string
+NAME2=more
+XYZZY=garbage}
+
+set env(NAME2) "new value"
+test env-3.1 {changing environment variables} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ set result [getenv]
+ unset env(NAME2)
+ set result
+} -cleanup {
+ encoding system $sysenc
+} -result {NAME1=test string
+NAME2=new value
+XYZZY=garbage}
+
+test env-4.1 {unsetting environment variables: default} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ getenv
+} -cleanup {
+ encoding system $sysenc
+} -result {NAME1=test string
+XYZZY=garbage}
+test env-4.2 {unsetting environment variables} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ unset env(NAME1)
+ getenv
+} -cleanup {
+ unset env(XYZZY)
+ encoding system $sysenc
+} -result {XYZZY=garbage}
+test env-4.3 {setting international environment variables} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ set env(\ua7) \ub6
+ getenv
+} -cleanup {
+ encoding system $sysenc
+} -result {\u00a7=\u00b6}
+test env-4.4 {changing international environment variables} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ set env(\ua7) \ua7
+ getenv
+} -cleanup {
+ encoding system $sysenc
+} -result {\u00a7=\u00a7}
+test env-4.5 {unsetting international environment variables} -setup {
+ encoding system iso8859-1
+} -body {
+ set env(\ub6) \ua7
+ unset env(\ua7)
+ getenv
+} -constraints {exec} -cleanup {
+ encoding system $sysenc
+ unset env(\ub6)
+} -result {\u00b6=\u00a7}
+
+test env-5.0 {corner cases - set a value, it should exist} -body {
+ set env(temp) a
+ set env(temp)
+} -cleanup {
+ unset env(temp)
+} -result {a}
+test env-5.1 {corner cases - remove one elem at a time} -setup {
+ set x [array get env]
+} -body {
+ # When no environment variables exist, the env var will contain no
+ # entries. The "array names" call synchs up the C-level environ array with
+ # the Tcl level env array. Make sure an empty Tcl array is created.
+ foreach e [array names env] {
+ unset env($e)
+ }
+ array size env
+} -cleanup {
+ array set env $x
+} -result {0}
+test env-5.2 {corner cases - unset the env array} -setup {
+ interp create i
+} -body {
+ # Unsetting a variable in an interp detaches the C-level traces from the
+ # Tcl "env" variable.
+ i eval {
+ unset env
+ set env(THIS_SHOULDNT_EXIST) a
+ }
+ info exists env(THIS_SHOULDNT_EXIST)
+} -cleanup {
+ interp delete i
+} -result {0}
+test env-5.3 {corner cases: unset the env in master should unset child} -setup {
+ interp create i
+} -body {
+ # Variables deleted in a master interp should be deleted in child interp
+ # too.
+ i eval { set env(THIS_SHOULD_EXIST) a}
+ set result [set env(THIS_SHOULD_EXIST)]
+ unset env(THIS_SHOULD_EXIST)
+ lappend result [i eval {catch {set env(THIS_SHOULD_EXIST)}}]
+} -cleanup {
+ interp delete i
+} -result {a 1}
+test env-5.4 {corner cases - unset the env array} -setup {
+ interp create i
+} -body {
+ # The info exists command should be in synch with the env array.
+ # Know Bug: 1737
+ i eval { set env(THIS_SHOULD_EXIST) a}
+ set result [info exists env(THIS_SHOULD_EXIST)]
+ lappend result [set env(THIS_SHOULD_EXIST)]
+ lappend result [info exists env(THIS_SHOULD_EXIST)]
+} -cleanup {
+ interp delete i
+} -result {1 a 1}
+test env-5.5 {corner cases - cannot have null entries on Windows} {win} {
+ set env() a
+ catch {set env()}
+} {1}
+
+test env-6.1 {corner cases - add lots of env variables} {} {
+ set size [array size env]
+ for {set i 0} {$i < 100} {incr i} {
+ set env(BOGUS$i) $i
+ }
+ expr {[array size env] - $size}
+} 100
+
+# Restore the environment variables at the end of the test.
+
+foreach name [array names env] {
+ unset env($name)
+}
+array set env $env2
+
+# cleanup
+removeFile $printenvScript
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/error.test b/library/msgcat/tests/error.test
new file mode 100644
index 0000000..97bcc0a
--- /dev/null
+++ b/library/msgcat/tests/error.test
@@ -0,0 +1,1061 @@
+# Commands covered: error, catch, throw, try
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint memory [llength [info commands memory]]
+namespace eval ::tcl::test::error {
+if {[testConstraint memory]} {
+ proc getbytes {} {
+ set lines [split [memory info] \n]
+ return [lindex $lines 3 3]
+ }
+ proc leaktest {script {iterations 3}} {
+ set end [getbytes]
+ for {set i 0} {$i < $iterations} {incr i} {
+ uplevel 1 $script
+ set tmp $end
+ set end [getbytes]
+ }
+ return [expr {$end - $tmp}]
+ }
+}
+
+proc foo {} {
+ global errorInfo
+ set a [catch {format [error glorp2]} b]
+ error {Human-generated}
+}
+
+proc foo2 {} {
+ global errorInfo
+ set a [catch {format [error glorp2]} b]
+ error {Human-generated} $errorInfo
+}
+
+# Catch errors occurring in commands and errors from "error" command
+
+test error-1.1 {simple errors from commands} {
+ catch {format [string index]} b
+} 1
+test error-1.2 {simple errors from commands} {
+ catch {format [string index]} b
+ set b
+} {wrong # args: should be "string index string charIndex"}
+test error-1.3 {simple errors from commands} {
+ catch {format [string index]} b
+ set ::errorInfo
+ # This used to return '... while executing ...', but string index is fully
+ # compiled as of 8.4a3
+} {wrong # args: should be "string index string charIndex"
+ while executing
+"string index"}
+test error-1.4 {simple errors from commands} {
+ catch {error glorp} b
+} 1
+test error-1.5 {simple errors from commands} {
+ catch {error glorp} b
+ set b
+} glorp
+test error-1.6 {simple errors from commands} {
+ catch {catch a b c d} b
+} 1
+test error-1.7 {simple errors from commands} {
+ catch {catch a b c d} b
+ set b
+} {wrong # args: should be "catch script ?resultVarName? ?optionVarName?"}
+test error-1.8 {simple errors from commands} {
+ # This test is non-portable: it generates a memory fault on machines like
+ # DEC Alphas (infinite recursion overflows stack?)
+ #
+ # That claims sounds like a bug to be fixed rather than a portability
+ # problem. Anyhow, I believe it's out of date (bug's been fixed) so this
+ # test is re-enabled.
+ proc p {} {
+ uplevel 1 catch p error
+ }
+ p
+} 0
+
+# Check errors nested in procedures. Also check the optional argument to
+# "error" to generate a new error trace.
+
+test error-2.1 {errors in nested procedures} {
+ catch foo b
+} 1
+test error-2.2 {errors in nested procedures} {
+ catch foo b
+ set b
+} {Human-generated}
+test error-2.3 {errors in nested procedures} {
+ catch foo b
+ set ::errorInfo
+} {Human-generated
+ while executing
+"error {Human-generated}"
+ (procedure "foo" line 4)
+ invoked from within
+"foo"}
+test error-2.4 {errors in nested procedures} {
+ catch foo2 b
+} 1
+test error-2.5 {errors in nested procedures} {
+ catch foo2 b
+ set b
+} {Human-generated}
+test error-2.6 {errors in nested procedures} {
+ catch foo2 b
+ set ::errorInfo
+} {glorp2
+ while executing
+"error glorp2"
+ (procedure "foo2" line 3)
+ invoked from within
+"foo2"}
+
+# Error conditions related to "catch".
+
+test error-3.1 {errors in catch command} {
+ list [catch {catch} msg] $msg
+} {1 {wrong # args: should be "catch script ?resultVarName? ?optionVarName?"}}
+test error-3.2 {errors in catch command} {
+ list [catch {catch a b c} msg] $msg
+} {0 1}
+test error-3.3 {errors in catch command} {
+ catch {unset a}
+ set a(0) 22
+ list [catch {catch {format 44} a} msg] $msg
+} {1 {can't set "a": variable is array}}
+catch {unset a}
+
+# More tests related to errorInfo and errorCode
+
+test error-4.1 {errorInfo and errorCode variables} {
+ list [catch {error msg1 msg2 msg3} msg] $msg $::errorInfo $::errorCode
+} {1 msg1 msg2 msg3}
+test error-4.2 {errorInfo and errorCode variables} {
+ list [catch {error msg1 {} msg3} msg] $msg $::errorInfo $::errorCode
+} {1 msg1 {msg1
+ while executing
+"error msg1 {} msg3"} msg3}
+test error-4.3 {errorInfo and errorCode variables} {
+ list [catch {error msg1 {}} msg] $msg $::errorInfo $::errorCode
+} {1 msg1 {msg1
+ while executing
+"error msg1 {}"} NONE}
+test error-4.4 {errorInfo and errorCode variables} {
+ set ::errorCode bogus
+ list [catch {error msg1} msg] $msg $::errorInfo $::errorCode
+} {1 msg1 {msg1
+ while executing
+"error msg1"} NONE}
+test error-4.5 {errorInfo and errorCode variables} {
+ set ::errorCode bogus
+ list [catch {error msg1 msg2 {}} msg] $msg $::errorInfo $::errorCode
+} {1 msg1 msg2 {}}
+
+test error-4.6 {errorstack via info } -body {
+ proc f x {g $x$x}
+ proc g x {error G:$x}
+ catch {f 12}
+ info errorstack
+} -match glob -result {INNER * CALL {g 1212} CALL {f 12} UP 1}
+test error-4.7 {errorstack via options dict } -body {
+ proc f x {g $x$x}
+ proc g x {error G:$x}
+ catch {f 12} m d
+ dict get $d -errorstack
+} -match glob -result {INNER * CALL {g 1212} CALL {f 12} UP 1}
+
+# Errors in error command itself
+
+test error-5.1 {errors in error command} {
+ list [catch {error} msg] $msg
+} {1 {wrong # args: should be "error message ?errorInfo? ?errorCode?"}}
+test error-5.2 {errors in error command} {
+ list [catch {error a b c d} msg] $msg
+} {1 {wrong # args: should be "error message ?errorInfo? ?errorCode?"}}
+
+# Make sure that catch resets error information
+
+test error-6.1 {catch must reset error state} {
+ catch {error outer [catch {error inner inner.errorInfo inner.errorCode}]}
+ list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.2 {catch must reset error state} {
+ catch {error outer [catch {return -level 0 -code error -errorcode BUG}]}
+ list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.3 {catch must reset error state} {
+ set ::errorCode BUG
+ catch {error outer [catch set]}
+ list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.4 {catch must reset error state} {
+ catch {error [catch {error foo bar baz}] 1}
+ list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.5 {catch must reset error state} {
+ catch {error [catch {return -level 0 -code error -errorcode BUG}] 1}
+ list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.6 {catch must reset error state} {
+ catch {return -level 0 -code error -errorinfo [catch {error foo bar baz}]}
+ list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.7 {catch must reset error state} {
+ proc foo {} {
+ return -code error -errorinfo [catch {error foo bar baz}]
+ }
+ catch foo
+ list $::errorCode
+} {NONE}
+test error-6.8 {catch must reset error state} {
+ catch {return -level 0 -code error [catch {error foo bar baz}]}
+ list $::errorCode
+} {NONE}
+test error-6.9 {catch must reset error state} {
+ proc foo {} {
+ return -code error [catch {error foo bar baz}]
+ }
+ catch foo
+ list $::errorCode
+} {NONE}
+test error-6.10 {catch must reset errorstack} -body {
+ proc f x {g $x$x}
+ proc g x {error G:$x}
+ catch {f 12}
+ set e1 [info errorstack]
+ catch {f 13}
+ set e2 [info errorstack]
+ list $e1 $e2
+} -match glob -result {{INNER * CALL {g 1212} CALL {f 12} UP 1} {INNER * CALL {g 1313} CALL {f 13} UP 1}}
+
+test error-7.1 {Bug 1397843} -body {
+ variable cmds
+ proc EIWrite args {
+ variable cmds
+ lappend cmds [lindex [info level -2] 0]
+ }
+ proc BadProc {} {
+ set i a
+ incr i
+ }
+ trace add variable ::errorInfo write [namespace code EIWrite]
+ catch BadProc
+ trace remove variable ::errorInfo write [namespace code EIWrite]
+ set cmds
+} -match glob -result {*BadProc*}
+
+# throw tests
+
+test error-8.1 {throw produces error 1 at level 0} {
+ catch { throw FOO bar }
+} {1}
+test error-8.2 {throw behaves as error does at level 0} {
+ catch { throw FOO bar } em1 opts1
+ catch { error bar {} FOO } em2 opts2
+ dict set opts1 -result $em1
+ dict set opts2 -result $em2
+ foreach key {-code -level -result -errorcode} {
+ if { [dict get $opts1 $key] ne [dict get $opts2 $key] } {
+ error "error/throw outcome differs on '$key'"
+ }
+ }
+} {}
+test error-8.3 {throw produces error 1 at level > 0} {
+ proc throw_foo {} {
+ throw FOO bar
+ }
+ catch { throw_foo }
+} {1}
+test error-8.4 {throw behaves as error does at level > 0} {
+ proc throw_foo {} {
+ throw FOO bar
+ }
+ proc error_foo {} {
+ error bar {} FOO
+ }
+ catch { throw_foo } em1 opts1
+ catch { error_foo } em2 opts2
+ dict set opts1 -result $em1
+ dict set opts2 -result $em2
+ foreach key {-code -level -result -errorcode} {
+ if { [dict get $opts1 $key] ne [dict get $opts2 $key] } {
+ error "error/throw outcome differs on '$key'"
+ }
+ }
+} {}
+test error-8.5 {throw syntax checks} -returnCodes error -body {
+ throw
+} -result {wrong # args: should be "throw type message"}
+test error-8.6 {throw syntax checks} -returnCodes error -body {
+ throw a
+} -result {wrong # args: should be "throw type message"}
+test error-8.7 {throw syntax checks} -returnCodes error -body {
+ throw a b c
+} -result {wrong # args: should be "throw type message"}
+test error-8.8 {throw syntax checks} -returnCodes error -body {
+ throw "not a \{ list" foo
+} -result {unmatched open brace in list}
+test error-8.9 {throw syntax checks} -returnCodes error -body {
+ throw {} foo
+} -result {type must be non-empty list}
+
+# simple try tests: body completes with code ok
+
+test error-9.1 {try (ok, empty result) with no handlers} {
+ try list
+} {}
+test error-9.2 {try (ok, non-empty result) with no handlers} {
+ try { list a b c }
+} {a b c}
+test error-9.3 {try (ok, non-empty result) with trap handler} {
+ try { list a b c } trap {} {} { list d e f }
+} {a b c}
+test error-9.4 {try (ok, non-empty result) with on handler} {
+ try { list a b c } on break {} { list d e f }
+} {a b c}
+test error-9.5 {try (ok, non-empty result) with on ok handler} {
+ try { list a b c } on ok {} { list d e f }
+} {d e f}
+
+# simple try tests - "on" handler matching
+
+test error-10.1 {try with on ok} {
+ try { list a b c } on ok {} { list d e f }
+} {d e f}
+test error-10.2 {try with on 0} {
+ try { list a b c } on 0 {} { list d e f }
+} {d e f}
+test error-10.3 {try with on error (using error)} {
+ try { error a b c } on error {} { list d e f }
+} {d e f}
+test error-10.4 {try with on error (using return -code)} {
+ try { return -level 0 -code 1 a } on error {} { list d e f }
+} {d e f}
+test error-10.5 {try with on error (using throw)} {
+ try { throw c a } on error {} { list d e f }
+} {d e f}
+test error-10.6 {try with on 1 (using error)} {
+ try { error a b c } on 1 {} { list d e f }
+} {d e f}
+test error-10.7 {try with on return} {
+ try { return [list a b c] } on return {} { list d e f }
+} {d e f}
+test error-10.8 {try with on break} {
+ try { break } on break {} { list d e f }
+} {d e f}
+test error-10.9 {try with on continue} {
+ try { continue } on continue {} { list d e f }
+} {d e f}
+test error-10.10 {try with on for arbitrary (decimal) return code} {
+ try { return -level 0 -code 123456 } on 123456 {} { list d e f }
+} {d e f}
+test error-10.11 {try with on for arbitrary (hex) return code} {
+ try { return -level 0 -code 0x123456 } on 0x123456 {} { list d e f }
+} {d e f}
+test error-10.12 {try with on for arbitrary return code (mixed number representations)} {
+ try { return -level 0 -code 0x10 } on 16 {} { list d e f }
+} {d e f}
+
+# simple try tests - "trap" handler matching
+
+test error-11.1 {try with trap all} {
+ try { throw FOO bar } trap {} {} { list d e f }
+} {d e f}
+test error-11.2 {try with trap (exact)} {
+ try { throw FOO bar } trap {FOO} {} { list d e f }
+} {d e f}
+test error-11.3 {try with trap (prefix 1)} {
+ try { throw [list FOO A B C D] bar } trap {FOO} {} { list d e f }
+} {d e f}
+test error-11.4 {try with trap (prefix 2)} {
+ try { throw [list FOO A B C D] bar } trap {FOO A} {} { list d e f }
+} {d e f}
+test error-11.5 {try with trap (prefix 3)} {
+ try { throw [list FOO A B C D] bar } trap {FOO A B} {} { list d e f }
+} {d e f}
+test error-11.6 {try with trap (prefix 4)} {
+ try { throw [list FOO A B C D] bar } trap {FOO A B C} {} { list d e f }
+} {d e f}
+test error-11.7 {try with trap (exact, 5 elements)} {
+ try { throw [list FOO A B C D] bar } trap {FOO A B C D} {} { list d e f }
+} {d e f}
+
+# simple try tests - variable assignment and result handling
+
+test error-12.1 {try with no variable assignment in on handler} {
+ try { throw FOO bar } on error {} { list d e f }
+} {d e f}
+test error-12.2 {try with result variable assignment in on handler} {
+ try { throw FOO bar } on error {res} { set res }
+} {bar}
+test error-12.3 {try with result variable assignment in on handler, var remains in scope} {
+ try { throw FOO bar } on error {res} { list d e f }
+ set res
+} {bar}
+test error-12.4 {try with result/opts variable assignment in on handler} {
+ try {
+ throw FOO bar
+ } on error {res opts} {
+ set r "$res,[dict get $opts -errorcode]"
+ }
+} {bar,FOO}
+test error-12.5 {try with result/opts variable assignment in on handler, vars remain in scope} {
+ try { throw FOO bar } on error {res opts} { list d e f }
+ set r "$res,[dict get $opts -errorcode]"
+} {bar,FOO}
+test error-12.6 {try result is propagated if no matching handler} {
+ try { list a b c } on error {} { list d e f }
+} {a b c}
+test error-12.7 {handler result is propagated if handler executes} {
+ try { throw FOO bar } on error {} { list d e f }
+} {d e f}
+
+# negative case try tests - bad args to try
+
+test error-13.1 {try with no arguments} -body {
+ # warning: error message may change
+ try
+} -returnCodes error -match glob -result {wrong # args: *}
+test error-13.2 {try with body only (ok)} {
+ try list
+} {}
+test error-13.3 {try with missing finally body} -body {
+ # warning: error message may change
+ try list finally
+} -returnCodes error -match glob -result {wrong # args to finally clause: *}
+test error-13.4 {try with bad handler keyword} -body {
+ # warning: error message may change
+ try list then a b c
+} -returnCodes error -match glob -result {bad handler *}
+test error-13.5 {try with partial handler #1} -body {
+ # warning: error message may change
+ try list on
+} -returnCodes error -match glob -result {wrong # args to on clause: *}
+test error-13.6 {try with partial handler #2} -body {
+ # warning: error message may change
+ try list on error
+} -returnCodes error -match glob -result {wrong # args to on clause: *}
+test error-13.7 {try with partial handler #3} -body {
+ # warning: error message may change
+ try list on error {em opts}
+} -returnCodes error -match glob -result {wrong # args to on clause: *}
+test error-13.8 {try with multiple handlers and finally (ok)} {
+ try list on error {} {} trap {} {} {} finally {}
+} {}
+test error-13.9 {last handler body can't be a fallthrough #1} -body {
+ try list on error {} {} on break {} -
+} -returnCodes error -result {last non-finally clause must not have a body of "-"}
+test error-13.10 {last handler body can't be a fallthrough #2} -body {
+ try list on error {} {} on break {} - finally { list d e f }
+} -returnCodes error -result {last non-finally clause must not have a body of "-"}
+
+# try tests - multiple handlers (left-to-right matching, only one runs)
+
+test error-14.1 {try with multiple handlers (only one matches) #1} {
+ try { throw FOO bar } on ok {} { list a b c } trap FOO {} { list d e f }
+} {d e f}
+test error-14.2 {try with multiple handlers (only one matches) #2} {
+ try { throw FOO bar } trap FOO {} { list d e f } on ok {} { list a b c }
+} {d e f}
+test error-14.3 {try with multiple handlers (only one matches) #3} {
+ try {
+ throw FOO bar
+ } on break {} {
+ list x y z
+ } trap FOO {} {
+ list d e f
+ } on ok {} {
+ list a b c
+ }
+} {d e f}
+test error-14.4 {try with multiple matching handlers (only the first in left-to-right order runs) #1} {
+ try { throw FOO bar } on error {} { list a b c } trap FOO {} { list d e f }
+} {a b c}
+test error-14.5 {try with multiple matching handlers (only the first in left-to-right order runs) #2} {
+ try { throw FOO bar } trap FOO {} { list d e f } on error {} { list a b c }
+} {d e f}
+test error-14.6 {try with multiple matching handlers (only the first in left-to-right order runs) #3} {
+ try { throw FOO bar } trap {} {} { list d e f } on 1 {} { list a b c }
+} {d e f}
+test error-14.7 {try with multiple matching handlers (only the first in left-to-right order runs) #4} {
+ try { throw FOO bar } on 1 {} { list a b c } trap {} {} { list d e f }
+} {a b c}
+test error-14.8 {try with handler-of-last-resort "trap {}"} {
+ try { throw FOO bar } trap FOX {} { list a b c } trap {} {} { list d e f }
+} {d e f}
+test error-14.9 {try with handler-of-last-resort "on error"} {
+ try { foo } trap FOX {} { list a b c } on error {} { list d e f }
+} {d e f}
+
+# try tests - propagation (no matching handlers)
+
+test error-15.1 {try with no handler (ok result propagates)} {
+ try { list a b c }
+} {a b c}
+test error-15.2 {try with no matching handler (ok result propagates)} {
+ try { list a b c } on error {} { list d e f }
+} {a b c}
+test error-15.3 {try with no handler (error result propagates)} -body {
+ try { throw FOO bar }
+} -returnCodes error -result {bar}
+test error-15.4 {try with no matching handler (error result propagates)} -body {
+ try { throw FOO bar } trap FOX {} { list a b c }
+} -returnCodes error -result {bar}
+test error-15.5 {try with no handler (return result propagates)} -body {
+ try { return bar }
+} -returnCodes 2 -result {bar}
+test error-15.6 {try with no matching handler (break result propagates)} -body {
+ try { if {1} break } on error {} { list a b c }
+} -returnCodes 3 -result {}
+test error-15.7 {try with no matching handler (unknown integer result propagates)} -body {
+ try { return -level 0 -code 123456 } trap {} {} { list a b c }
+} -returnCodes 123456 -result {}
+
+foreach level {0 1 2 3} {
+ foreach code {0 1 2 3 4 5} {
+
+ # Following cases have different -errorinfo; avoid false alarms
+ # TODO: examine whether these difference are as they ought to be.
+ if {$level == 0 && $code == 1} continue
+
+ foreach extras {{} {-bar soom}} {
+
+test error-15.8.$level.$code.[llength $extras] {[try] coverage} {
+ set script {return -level $level -code $code {*}$extras foo}
+ catch $script m1 o1
+ catch {try $script} m2 o2
+ set o1 [lsort -stride 2 $o1]
+ set o2 [lsort -stride 2 $o2]
+ expr {$o1 eq $o2 ? "ok" : "$o1\n\tis not equal to\n$o2"}
+} ok
+
+test error-15.9.$level.$code.[llength $extras] {[try] coverage} {
+ set script {return -level $level -code $code {*}$extras foo}
+ catch $script m1 o1
+ catch {try $script finally {}} m2 o2
+ set o1 [lsort -stride 2 $o1]
+ set o2 [lsort -stride 2 $o2]
+ expr {$o1 eq $o2 ? "ok" : "$o1\n\tis not equal to\n$o2"}
+} ok
+
+test error-15.10.$level.$code.[llength $extras] {[try] coverage} {
+ set script {return -level $level -code $code {*}$extras foo}
+ catch $script m1 o1
+ catch {try $script on $code {x y} {return -options $y $x}} m2 o2
+ set o1 [lsort -stride 2 $o1]
+ set o2 [lsort -stride 2 $o2]
+ expr {$o1 eq $o2 ? "ok" : "$o1\n\tis not equal to\n$o2"}
+} ok
+
+ }
+ }
+}
+
+# try tests - propagation (exceptions in handlers, exception chaining)
+
+test error-16.1 {try with successfully executed handler} {
+ try { throw FOO bar } trap FOO {} { list a b c }
+} {a b c}
+test error-16.2 {try with exception (error) in handler} -body {
+ try { throw FOO bar } trap FOO {} { throw BAR foo }
+} -returnCodes error -result {foo}
+test error-16.3 {try with exception (return) in handler} -body {
+ try { throw FOO bar } trap FOO {} { return BAR }
+} -returnCodes 2 -result {BAR}
+test error-16.4 {try with exception (break) in handler #1} -body {
+ try { throw FOO bar } trap FOO {} { break }
+} -returnCodes 3 -result {}
+test error-16.5 {try with exception (break) in handler #2} {
+ for { set i 5 } { $i < 10 } { incr i } {
+ try { throw FOO bar } trap FOO {} { break }
+ }
+ set i
+} {5}
+test error-16.6 {try with variable assignment and propagation #1} {
+ # Ensure that the handler variables preserve the exception off the
+ # try-body, and are not modified by the exception off the handler
+ catch {
+ try { throw FOO bar } trap FOO {em} { throw BAR baz }
+ }
+ set em
+} {bar}
+test error-16.7 {try with variable assignment and propagation #2} {
+ catch {
+ try { throw FOO bar } trap FOO {em opts} { throw BAR baz }
+ }
+ list $em [dict get $opts -errorcode]
+} {bar FOO}
+test error-16.8 {exception chaining (try=ok, handler=error)} {
+ #FIXME is the intent of this test correct?
+ catch {
+ try { list a b c } on ok {em opts} { throw BAR baz }
+ } tryem tryopts
+ string equal $opts [dict get $tryopts -during]
+} {1}
+test error-16.9 {exception chaining (try=error, handler=error)} {
+ # The exception off the handler should chain to the exception off the
+ # try-body (using the -during option)
+ catch {
+ try { throw FOO bar } trap {} {em opts} { throw BAR baz }
+ } tryem tryopts
+ string equal $opts [dict get $tryopts -during]
+} {1}
+test error-16.10 {no exception chaining when handler is successful} {
+ catch {
+ try { throw FOO bar } trap {} {em opts} { list d e f }
+ } tryem tryopts
+ dict exists $tryopts -during
+} {0}
+test error-16.11 {no exception chaining when handler is a non-error exception} {
+ catch {
+ try { throw FOO bar } trap {} {em opts} { break }
+ } tryem tryopts
+ dict exists $tryopts -during
+} {0}
+
+# try tests - finally
+
+test error-17.1 {finally always runs (try with ok result)} {
+ set RES {}
+ try { list a b c } finally { set RES done }
+ set RES
+} {done}
+test error-17.2 {finally always runs (try with error result)} {
+ set RES {}
+ catch {
+ try { throw FOO bar } finally { set RES done }
+ }
+ set RES
+} {done}
+test error-17.3 {finally always runs (try with matching handler)} {
+ set RES {}
+ try { throw FOO bar } trap FOO {} { list a b c } finally { set RES done }
+ set RES
+} {done}
+test error-17.4 {finally always runs (try with exception in handler)} {
+ set RES {}
+ catch {
+ try {
+ throw FOO bar
+ } trap FOO {} {
+ throw BAR baz
+ } finally {
+ set RES done
+ }
+ }
+ set RES
+} {done}
+test error-17.5 {successful finally doesn't modify try outcome (try=ok)} {
+ try { list a b c } finally { list d e f }
+} {a b c}
+test error-17.6 {successful finally doesn't modify try outcome (try=return)} -body {
+ try { return c } finally { list d e f }
+} -returnCodes 2 -result {c}
+test error-17.7 {successful finally doesn't modify try outcome (try=error)} -body {
+ try { error bar } finally { list d e f }
+} -returnCodes 1 -result {bar}
+test error-17.8 {successful finally doesn't modify handler outcome (handler=ok)} {
+ try { throw FOO bar } trap FOO {} { list a b c } finally { list d e f }
+} {a b c}
+test error-17.9 {successful finally doesn't modify handler outcome (handler=error)} -body {
+ try { throw FOO bar } trap FOO {} { throw BAR baz } finally { list d e f }
+} -returnCodes error -result {baz}
+test error-17.10 {successful finally doesn't affect variable assignment} {
+ catch {
+ try { throw FOO bar } trap FOO {em opts} { list d e f } finally { list d e f }
+ } result
+ list $em $result
+} {bar {d e f}}
+test error-17.11 {successful finally doesn't affect variable assignment or propagation} {
+ catch {
+ try { throw FOO bar } trap FOO {em opts} { throw BAR baz } finally { list d e f }
+ }
+ list $em [dict get $opts -errorcode]
+} {bar FOO}
+
+# try tests - propagation (exceptions in finally, exception chaining)
+
+test error-18.1 {try (ok) with exception in finally (error)} -body {
+ try { list a b c } finally { throw BAR foo }
+} -returnCodes error -result {foo}
+test error-18.2 {try (error) with exception in finally (break)} -body {
+ try { throw FOO bar } finally { break }
+} -returnCodes 3 -result {}
+test error-18.3 {try (ok) with handler (ok) and exception in finally (error)} -body {
+ try { list a b c } on ok {} { list d e f } finally { throw BAR foo }
+} -returnCodes error -result {foo}
+test error-18.4 {try (error) with exception in handler (error) and in finally (arb code)} -body {
+ try { throw FOO bar } on error {} { throw BAR baz } finally { return -level 0 -code 99 zing }
+} -returnCodes 99 -result {zing}
+test error-18.5 {exception in finally doesn't affect variable assignment} {
+ catch {
+ try { throw FOO bar } trap FOO {em opts} { throw BAR baz } finally { throw BAZ zing }
+ }
+ list $em [dict get $opts -errorcode]
+} {bar FOO}
+test error-18.6 {exception chaining in finally (try=ok)} {
+ catch {
+ list a b c
+ } em expopts
+ catch {
+ try { list a b c } finally { throw BAR foo }
+ } em opts
+ string equal $expopts [dict get $opts -during]
+} {1}
+test error-18.7 {exception chaining in finally (try=error)} {
+ catch {
+ try { throw FOO bar } finally { throw BAR baz }
+ } em opts
+ dict get $opts -during -errorcode
+} {FOO}
+test error-18.8 {exception chaining in finally (try=ok, handler=ok)} {
+ catch {
+ try { list a b c } on ok {} { list d e f } finally { throw BAR baz }
+ } em opts
+ list [dict get $opts -during -code] [dict exists $opts -during -during]
+} {0 0}
+test error-18.9 {exception chaining in finally (try=error, handler=ok)} {
+ catch {
+ try {
+ throw FOO bar
+ } on error {} {
+ list d e f
+ } finally {
+ throw BAR baz
+ }
+ } em opts
+ list [dict get $opts -during -code] [dict exists $opts -during -during]
+} {0 0}
+test error-18.10 {exception chaining in finally (try=error, handler=error)} {
+ catch {
+ try {
+ throw FOO bar
+ } on error {} {
+ throw BAR baz
+ } finally {
+ throw BAR baz
+ }
+ } em opts
+ list [dict get $opts -during -errorcode] [dict get $opts -during -during -errorcode]
+} {BAR FOO}
+test error-18.11 {no exception chaining if finally produces a non-error exception} {
+ catch {
+ try { throw FOO bar } on error {} { throw BAR baz } finally { break }
+ } em opts
+ dict exists $opts -during
+} {0}
+test error-18.12 {variable assignment unaffected by exception in finally} {
+ catch {
+ try {
+ throw FOO bar
+ } on error {em opts} {
+ list a b c
+ } finally {
+ throw BAR baz
+ }
+ }
+ list $em [dict get $opts -errorcode]
+} {bar FOO}
+
+# try tests - fallthough body cases
+
+test error-19.1 {try with fallthrough body #1} {
+ set RES {}
+ try { list a b c } on ok { set RES 0 } - on error {} { set RES 1 }
+ set RES
+} {1}
+test error-19.2 {try with fallthrough body #2} {
+ set RES {}
+ try {
+ throw FOO bar
+ } trap BAR {} {
+ } trap FOO {} - trap {} {} {
+ set RES foo
+ } on error {} {
+ set RES err
+ }
+ set RES
+} {foo}
+test error-19.3 {try with cascade fallthrough} {
+ set RES {}
+ try {
+ throw FOO bar
+ } trap FOO {} - trap BAR {} - trap {} {} {
+ set RES trap
+ } on error {} { set RES err }
+ set RES
+} {trap}
+test error-19.4 {multiple unrelated fallthroughs #1} {
+ set RES {}
+ try {
+ throw FOO bar
+ } trap FOO {} - trap BAR {} {
+ set RES foo
+ } trap {} {} - on error {} {
+ set RES err
+ }
+ set RES
+} {foo}
+test error-19.5 {multiple unrelated fallthroughs #2} {
+ set RES {}
+ try {
+ throw BAZ zing
+ } trap FOO {} - trap BAR {} {
+ set RES foo
+ } trap {} {} - on error {} {
+ set RES err
+ }
+ set RES
+} {err}
+proc addmsg msg {
+ variable RES
+ lappend RES $msg
+}
+test error-19.6 {compiled try executes all clauses} -setup {
+ set RES {}
+} -body {
+ apply {{} {
+ try {
+ addmsg a
+ throw bar hello
+ } trap bar {res opt} {
+ addmsg b
+ } finally {
+ addmsg c
+ }
+ addmsg d
+ } ::tcl::test::error}
+} -cleanup {
+ unset RES
+} -result {a b c d}
+test error-19.7 {compiled try executes all clauses} -setup {
+ set RES {}
+} -body {
+ apply {{} {
+ try {
+ addmsg a
+ } on error {res opt} {
+ addmsg b
+ } on ok {} {
+ addmsg c
+ } finally {
+ addmsg d
+ }
+ addmsg e
+ } ::tcl::test::error}
+} -cleanup {
+ unset RES
+} -result {a c d e}
+test error-19.8 {compiled try executes all clauses} -setup {
+ set RES {}
+} -body {
+ apply {{} {
+ try {
+ addmsg a
+ throw bar hello
+ } trap bar {res opt} {
+ addmsg b
+ }
+ addmsg c
+ } ::tcl::test::error}
+} -cleanup {
+ unset RES
+} -result {a b c}
+test error-19.9 {compiled try executes all clauses} -setup {
+ set RES {}
+} -body {
+ apply {{} {
+ try {
+ addmsg a
+ } on error {res opt} {
+ addmsg b
+ } on ok {} {
+ addmsg c
+ }
+ addmsg d
+ } ::tcl::test::error}
+} -cleanup {
+ unset RES
+} -result {a c d}
+test error-19.10 {compiled try with chained clauses} -setup {
+ set RES {}
+} -body {
+ list [apply {{} {
+ try {
+ return good
+ } on return {res} - on ok {res} {
+ addmsg ok
+ addmsg $res
+ return handler
+ } finally {
+ addmsg finally
+ }
+ } ::tcl::test::error}] $RES
+} -cleanup {
+ unset RES
+} -result {handler {ok good finally}}
+test error-19.11 {compiled try and errors on variable write} -setup {
+ set RES {}
+} -body {
+ apply {{} {
+ array set foo {bar boo}
+ set bar unset
+ catch {
+ try {
+ addmsg body
+ return a
+ } on return {bar foo} {
+ addmsg handler
+ return b
+ } finally {
+ addmsg finally,$bar
+ }
+ } msg
+ addmsg $msg
+ } ::tcl::test::error}
+} -cleanup {
+ unset RES
+} -result {body finally,a {can't set "foo": variable is array}}
+test error-19.12 {interpreted try and errors on variable write} -setup {
+ set RES {}
+} -body {
+ apply {try {
+ array set foo {bar boo}
+ set bar unset
+ catch {
+ $try {
+ addmsg body
+ return a
+ } on return {bar foo} {
+ addmsg handler
+ return b
+ } finally {
+ addmsg finally,$bar
+ }
+ } msg
+ addmsg $msg
+ } ::tcl::test::error} try
+} -cleanup {
+ unset RES
+} -result {body finally,a {can't set "foo": variable is array}}
+test error-19.13 {compiled try and errors on variable write} -setup {
+ set RES {}
+} -body {
+ apply {{} {
+ array set foo {bar boo}
+ set bar unset
+ catch {
+ try {
+ addmsg body
+ return a
+ } on return {bar foo} - on error {bar foo} {
+ addmsg handler
+ return b
+ } finally {
+ addmsg finally,$bar
+ }
+ } msg
+ addmsg $msg
+ } ::tcl::test::error}
+} -cleanup {
+ unset RES
+} -result {body finally,a {can't set "foo": variable is array}}
+rename addmsg {}
+
+# FIXME test what vars get set on fallthough ... what is the correct behavior?
+# It would seem appropriate to set at least those for the matching handler and
+# the executed body; possibly for each handler we fall through as well?
+
+# negative case try tests - bad "on" handler
+
+test error-20.1 {bad code name in on handler} -body {
+ try { list a b c } on err {} {}
+} -returnCodes error -match glob -result {bad completion code "err": must be ok, error, return, break, continue*, or an integer}
+test error-20.2 {bad code value in on handler} -body {
+ try { list a b c } on 34985723094872345 {} {}
+} -returnCodes error -match glob -result {bad completion code "34985723094872345": must be ok, error, return, break, continue*, or an integer}
+
+test error-21.1 {memory leaks in try: Bug 2910044} memory {
+ leaktest {
+ try {string repeat x 10} on ok {} {}
+ }
+} 0
+test error-21.2 {memory leaks in try: Bug 2910044} memory {
+ leaktest {
+ try {error [string repeat x 10]} on error {} {}
+ }
+} 0
+test error-21.3 {memory leaks in try: Bug 2910044} memory {
+ leaktest {
+ try {throw FOO [string repeat x 10]} trap FOO {} {}
+ }
+} 0
+test error-21.4 {memory leaks in try: Bug 2910044} memory {
+ leaktest {
+ try {string repeat x 10}
+ }
+} 0
+test error-21.5 {memory leaks in try: Bug 2910044} memory {
+ leaktest {
+ try {string repeat x 10} on ok {} {} finally {string repeat y 10}
+ }
+} 0
+test error-21.6 {memory leaks in try: Bug 2910044} memory {
+ leaktest {
+ try {
+ error [string repeat x 10]
+ } on error {} {} finally {
+ string repeat y 10
+ }
+ }
+} 0
+test error-21.7 {memory leaks in try: Bug 2910044} memory {
+ leaktest {
+ try {
+ throw FOO [string repeat x 10]
+ } trap FOO {} {} finally {
+ string repeat y 10
+ }
+ }
+} 0
+test error-21.8 {memory leaks in try: Bug 2910044} memory {
+ leaktest {
+ try {string repeat x 10} finally {string repeat y 10}
+ }
+} 0
+
+# negative case try tests - bad "trap" handler
+# what is the effect if we attempt to trap an errorcode that is not a list?
+# nested try
+# catch inside try
+# no tests for bad varslist?
+# -errorcode but code!=1 doesn't trap
+# throw negative case tests (no args, too many args, etc)
+
+}
+namespace delete ::tcl::test::error
+
+# cleanup
+catch {rename p ""}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/eval.test b/library/msgcat/tests/eval.test
new file mode 100644
index 0000000..70ceac8
--- /dev/null
+++ b/library/msgcat/tests/eval.test
@@ -0,0 +1,89 @@
+# Commands covered: eval
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test eval-1.1 {single argument} {
+ eval {format 22}
+} 22
+test eval-1.2 {multiple arguments} {
+ set a {$b}
+ set b xyzzy
+ eval format $a
+} xyzzy
+test eval-1.3 {single argument} {
+ eval concat a b c d e f g
+} {a b c d e f g}
+
+test eval-2.1 {error: not enough arguments} {catch eval} 1
+test eval-2.2 {error: not enough arguments} {
+ catch eval msg
+ set msg
+} {wrong # args: should be "eval arg ?arg ...?"}
+test eval-2.3 {error in eval'ed command} {
+ catch {eval {error "test error"}}
+} 1
+test eval-2.4 {error in eval'ed command} {
+ catch {eval {error "test error"}} msg
+ set msg
+} {test error}
+test eval-2.5 {error in eval'ed command: setting errorInfo} {
+ catch {eval {
+ set a 1
+ error "test error"
+ }} msg
+ set ::errorInfo
+} "test error
+ while executing
+\"error \"test error\"\"
+ (\"eval\" body line 3)
+ invoked from within
+\"eval {
+ set a 1
+ error \"test error\"
+ }\""
+
+test eval-3.1 {eval and pure lists} {
+ eval [list list 1 2 3 4 5]
+} {1 2 3 4 5}
+test eval-3.2 {concatenating eval and pure lists} {
+ eval [list list 1] [list 2 3 4 5]
+} {1 2 3 4 5}
+test eval-3.3 {eval and canonical lists} {
+ set cmd [list list 1 2 3 4 5]
+ # Force existance of utf-8 rep
+ set dummy($cmd) $cmd
+ unset dummy
+ eval $cmd
+} {1 2 3 4 5}
+test eval-3.4 {concatenating eval and canonical lists} {
+ set cmd [list list 1]
+ set cmd2 [list 2 3 4 5]
+ # Force existance of utf-8 rep
+ set dummy($cmd) $cmd
+ set dummy($cmd2) $cmd2
+ unset dummy
+ eval $cmd $cmd2
+} {1 2 3 4 5}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/event.test b/library/msgcat/tests/event.test
new file mode 100644
index 0000000..0ee7558
--- /dev/null
+++ b/library/msgcat/tests/event.test
@@ -0,0 +1,921 @@
+# This file contains a collection of tests for the procedures in the file
+# tclEvent.c, which includes the "update", and "vwait" Tcl commands. Sourcing
+# this file into Tcl runs the tests and generates output for errors. No
+# output means no errors were found.
+#
+# Copyright (c) 1995-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+testConstraint testfilehandler [llength [info commands testfilehandler]]
+testConstraint testexithandler [llength [info commands testexithandler]]
+testConstraint testfilewait [llength [info commands testfilewait]]
+testConstraint exec [llength [info commands exec]]
+
+test event-1.1 {Tcl_CreateFileHandler, reading} -setup {
+ testfilehandler close
+ set result ""
+} -constraints {testfilehandler} -body {
+ testfilehandler create 0 readable off
+ testfilehandler clear 0
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+ testfilehandler fillpartial 0
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+} -cleanup {
+ testfilehandler close
+} -result {{0 0} {1 0} {2 0}}
+test event-1.2 {Tcl_CreateFileHandler, writing} -setup {
+ testfilehandler close
+ set result ""
+} -constraints {testfilehandler nonPortable} -body {
+ # This test is non-portable because on some systems (e.g., SunOS 4.1.3)
+ # pipes seem to be writable always.
+ testfilehandler create 0 off writable
+ testfilehandler clear 0
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+ testfilehandler fillpartial 0
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+ testfilehandler fill 0
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+} -cleanup {
+ testfilehandler close
+} -result {{0 1} {0 2} {0 2}}
+test event-1.3 {Tcl_DeleteFileHandler} -setup {
+ testfilehandler close
+ set result ""
+} -constraints {testfilehandler nonPortable} -body {
+ testfilehandler create 2 disabled disabled
+ testfilehandler create 1 readable writable
+ testfilehandler create 0 disabled disabled
+ testfilehandler fillpartial 1
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler create 1 off off
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+} -cleanup {
+ testfilehandler close
+} -result {{0 1} {1 1} {1 2} {0 0}}
+
+test event-2.1 {Tcl_DeleteFileHandler} -setup {
+ testfilehandler close
+ set result ""
+} -constraints {testfilehandler nonPortable} -body {
+ testfilehandler create 2 disabled disabled
+ testfilehandler create 1 readable writable
+ testfilehandler fillpartial 1
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler create 1 off off
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+} -cleanup {
+ testfilehandler close
+} -result {{0 1} {1 1} {1 2} {0 0}}
+test event-2.2 {Tcl_DeleteFileHandler, fd reused & events still pending} -setup {
+ testfilehandler close
+ set result ""
+} -constraints {testfilehandler nonPortable} -body {
+ testfilehandler create 0 readable writable
+ testfilehandler fillpartial 0
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+ testfilehandler close
+ testfilehandler create 0 readable writable
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+} -cleanup {
+ testfilehandler close
+} -result {{0 1} {0 0}}
+
+test event-3.1 {FileHandlerCheckProc, TCL_FILE_EVENTS off} -setup {
+ testfilehandler close
+} -constraints {testfilehandler} -body {
+ testfilehandler create 1 readable writable
+ testfilehandler fillpartial 1
+ testfilehandler windowevent
+ testfilehandler counts 1
+} -cleanup {
+ testfilehandler close
+} -result {0 0}
+
+test event-4.1 {FileHandlerEventProc, race between event and disabling} -setup {
+ update
+ testfilehandler close
+ set result ""
+} -constraints {testfilehandler nonPortable} -body {
+ testfilehandler create 2 disabled disabled
+ testfilehandler create 1 readable writable
+ testfilehandler fillpartial 1
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler create 1 disabled disabled
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+} -cleanup {
+ testfilehandler close
+} -result {{0 1} {1 1} {1 2} {0 0}}
+test event-4.2 {FileHandlerEventProc, TCL_FILE_EVENTS off} -setup {
+ update
+ testfilehandler close
+} -constraints {testfilehandler nonPortable} -body {
+ testfilehandler create 1 readable writable
+ testfilehandler create 2 readable writable
+ testfilehandler fillpartial 1
+ testfilehandler fillpartial 2
+ testfilehandler oneevent
+ set result ""
+ lappend result [testfilehandler counts 1] [testfilehandler counts 2]
+ testfilehandler windowevent
+ lappend result [testfilehandler counts 1] [testfilehandler counts 2]
+} -cleanup {
+ testfilehandler close
+} -result {{0 0} {0 1} {0 0} {0 1}}
+update
+
+test event-5.1 {Tcl_BackgroundError, HandleBgErrors procedures} -setup {
+ catch {rename bgerror {}}
+} -body {
+ proc bgerror msg {
+ global errorInfo errorCode x
+ lappend x [list $msg $errorInfo $errorCode]
+ }
+ after idle {error "a simple error"}
+ after idle {open non_existent}
+ after idle {set errorInfo foobar; set errorCode xyzzy}
+ set x {}
+ update idletasks
+ regsub -all [file join {} non_existent] $x "non_existent"
+} -cleanup {
+ rename bgerror {}
+} -result {{{a simple error} {a simple error
+ while executing
+"error "a simple error""
+ ("after" script)} NONE} {{couldn't open "non_existent": no such file or directory} {couldn't open "non_existent": no such file or directory
+ while executing
+"open non_existent"
+ ("after" script)} {POSIX ENOENT {no such file or directory}}}}
+test event-5.2 {Tcl_BackgroundError, HandleBgErrors procedures} -setup {
+ catch {rename bgerror {}}
+} -body {
+ proc bgerror msg {
+ global x
+ lappend x $msg
+ return -code break
+ }
+ after idle {error "a simple error"}
+ after idle {open non_existent}
+ set x {}
+ update idletasks
+ return $x
+} -cleanup {
+ rename bgerror {}
+} -result {{a simple error}}
+test event-5.3 {HandleBgErrors: [Bug 1670155]} -setup {
+ variable x
+ proc demo args {variable x done}
+ variable target [list [namespace which demo] x]
+ proc trial args {variable target; string length $target}
+ trace add execution demo enter [namespace code trial]
+ variable save [interp bgerror {}]
+ interp bgerror {} $target
+} -body {
+ after 0 {error bar}
+ vwait [namespace which -variable x]
+} -cleanup {
+ interp bgerror {} $save
+ unset x target save
+ rename demo {}
+ rename trial {}
+} -result {}
+test event-5.3.1 {Default [interp bgerror] handler} -body {
+ ::tcl::Bgerror
+} -returnCodes error -match glob -result {*msg options*}
+test event-5.4 {Default [interp bgerror] handler} -body {
+ ::tcl::Bgerror {}
+} -returnCodes error -match glob -result {*msg options*}
+test event-5.5 {Default [interp bgerror] handler} -body {
+ ::tcl::Bgerror {} {} {}
+} -returnCodes error -match glob -result {*msg options*}
+test event-5.6 {Default [interp bgerror] handler} -body {
+ ::tcl::Bgerror {} {}
+} -returnCodes error -match glob -result {*-level*}
+test event-5.7 {Default [interp bgerror] handler} -body {
+ ::tcl::Bgerror {} {-level foo}
+} -returnCodes error -match glob -result {*expected integer*}
+test event-5.8 {Default [interp bgerror] handler} -body {
+ ::tcl::Bgerror {} {-level 0}
+} -returnCodes error -match glob -result {*-code*}
+test event-5.9 {Default [interp bgerror] handler} -body {
+ ::tcl::Bgerror {} {-level 0 -code ok}
+} -returnCodes error -match glob -result {*expected integer*}
+test event-5.10 {Default [interp bgerror] handler} -body {
+ proc bgerror {m} {append ::res $m}
+ set ::res {}
+ ::tcl::Bgerror {} {-level 0 -code 0}
+ return $::res
+} -cleanup {
+ rename bgerror {}
+} -result {}
+test event-5.11 {Default [interp bgerror] handler} -body {
+ proc bgerror {m} {append ::res $m}
+ set ::res {}
+ ::tcl::Bgerror msg {-level 0 -code 1}
+ return $::res
+} -cleanup {
+ rename bgerror {}
+} -result {msg}
+test event-5.12 {Default [interp bgerror] handler} -body {
+ proc bgerror {m} {append ::res $m}
+ set ::res {}
+ ::tcl::Bgerror msg {-level 0 -code 2}
+ return $::res
+} -cleanup {
+ rename bgerror {}
+} -result {command returned bad code: 2}
+test event-5.13 {Default [interp bgerror] handler} -body {
+ proc bgerror {m} {append ::res $m}
+ set ::res {}
+ ::tcl::Bgerror msg {-level 0 -code 3}
+ return $::res
+} -cleanup {
+ rename bgerror {}
+} -result {invoked "break" outside of a loop}
+test event-5.14 {Default [interp bgerror] handler} -body {
+ proc bgerror {m} {append ::res $m}
+ set ::res {}
+ ::tcl::Bgerror msg {-level 0 -code 4}
+ return $::res
+} -cleanup {
+ rename bgerror {}
+} -result {invoked "continue" outside of a loop}
+test event-5.15 {Default [interp bgerror] handler} -body {
+ proc bgerror {m} {append ::res $m}
+ set ::res {}
+ ::tcl::Bgerror msg {-level 0 -code 5}
+ return $::res
+} -cleanup {
+ rename bgerror {}
+} -result {command returned bad code: 5}
+
+test event-6.1 {BgErrorDeleteProc procedure} -setup {
+ catch {interp delete foo}
+ interp create foo
+ set erroutfile [makeFile Unmodified err.out]
+} -body {
+ foo eval [list set erroutfile $erroutfile]
+ foo eval {
+ proc bgerror args {
+ global errorInfo erroutfile
+ set f [open $erroutfile r+]
+ seek $f 0 end
+ puts $f "$args $errorInfo"
+ close $f
+ }
+ after 100 {error "first error"}
+ after 100 {error "second error"}
+ }
+ after 100 {interp delete foo}
+ after 200
+ update
+ set f [open $erroutfile r]
+ set result [read $f]
+ close $f
+ return $result
+} -cleanup {
+ removeFile $erroutfile
+} -result {Unmodified
+}
+
+test event-7.1 {bgerror / regular} {
+ set errRes {}
+ proc bgerror {err} {
+ global errRes
+ set errRes $err
+ }
+ after 0 {error err1}
+ vwait errRes
+ return $errRes
+} err1
+test event-7.2 {bgerror / accumulation} {
+ set errRes {}
+ proc bgerror {err} {
+ global errRes
+ lappend errRes $err
+ }
+ after 0 {error err1}
+ after 0 {error err2}
+ after 0 {error err3}
+ update
+ return $errRes
+} {err1 err2 err3}
+test event-7.3 {bgerror / accumulation / break} {
+ set errRes {}
+ proc bgerror {err} {
+ global errRes
+ lappend errRes $err
+ return -code break "skip!"
+ }
+ after 0 {error err1}
+ after 0 {error err2}
+ after 0 {error err3}
+ update
+ return $errRes
+} err1
+test event-7.4 {tkerror is nothing special anymore to tcl} -body {
+ set errRes {}
+ # we don't just rename bgerror to empty because it could then
+ # be autoloaded...
+ proc bgerror {err} {
+ global errRes
+ lappend errRes "bg:$err"
+ }
+ proc tkerror {err} {
+ global errRes
+ lappend errRes "tk:$err"
+ }
+ after 0 {error err1}
+ update
+ return $errRes
+} -cleanup {
+ rename tkerror {}
+} -result bg:err1
+test event-7.5 {correct behaviour when there is no bgerror [Bug 219142]} -body {
+ exec [interpreter] << {
+ after 1000 error hello
+ after 2000 set a 0
+ vwait a
+ }
+} -constraints {exec} -returnCodes error -result {hello
+ while executing
+"error hello"
+ ("after" script)}
+test event-7.6 {safe hidden bgerror fallback} -setup {
+ variable result {}
+ interp create -safe safe
+} -body {
+ safe alias puts puts
+ safe alias result ::append [namespace which -variable result]
+ safe eval {proc bgerror m {result $m\n$::errorCode\n$::errorInfo\n}}
+ safe hide bgerror
+ safe eval after 0 error foo
+ update
+ return $result
+} -cleanup {
+ interp delete safe
+} -result {foo
+NONE
+foo
+ while executing
+"error foo"
+ ("after" script)
+}
+test event-7.7 {safe hidden bgerror fallback} -setup {
+ variable result {}
+ interp create -safe safe
+} -body {
+ safe alias puts puts
+ safe alias result ::append [namespace which -variable result]
+ safe eval {proc bgerror m {result $m\n$::errorCode\n$::errorInfo\n}}
+ safe hide bgerror
+ safe eval {proc bgerror m {error bar soom baz}}
+ safe eval after 0 error foo
+ update
+ return $result
+} -cleanup {
+ interp delete safe
+} -result {foo
+NONE
+foo
+ while executing
+"error foo"
+ ("after" script)
+}
+
+# someday : add a test checking that when there is no bgerror, an error msg
+# goes to stderr ideally one would use sub interp and transfer a fake stderr
+# to it, unfortunatly the current interp tcl API does not allow that. The
+# other option would be to use fork a test but it then becomes more a
+# file/exec test than a bgerror test.
+
+# end of bgerror tests
+catch {rename bgerror {}}
+
+test event-8.1 {Tcl_CreateExitHandler procedure} {stdio testexithandler} {
+ set child [open |[list [interpreter]] r+]
+ puts $child "testexithandler create 41; testexithandler create 4"
+ puts $child "testexithandler create 6; exit"
+ flush $child
+ set result [read $child]
+ close $child
+ return $result
+} {even 6
+even 4
+odd 41
+}
+
+test event-9.1 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
+ set child [open |[list [interpreter]] r+]
+ puts $child "testexithandler create 41; testexithandler create 4"
+ puts $child "testexithandler create 6; testexithandler delete 41"
+ puts $child "testexithandler create 16; exit"
+ flush $child
+ set result [read $child]
+ close $child
+ return $result
+} {even 16
+even 6
+even 4
+}
+test event-9.2 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
+ set child [open |[list [interpreter]] r+]
+ puts $child "testexithandler create 41; testexithandler create 4"
+ puts $child "testexithandler create 6; testexithandler delete 4"
+ puts $child "testexithandler create 16; exit"
+ flush $child
+ set result [read $child]
+ close $child
+ return $result
+} {even 16
+even 6
+odd 41
+}
+test event-9.3 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
+ set child [open |[list [interpreter]] r+]
+ puts $child "testexithandler create 41; testexithandler create 4"
+ puts $child "testexithandler create 6; testexithandler delete 6"
+ puts $child "testexithandler create 16; exit"
+ flush $child
+ set result [read $child]
+ close $child
+ return $result
+} {even 16
+even 4
+odd 41
+}
+test event-9.4 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
+ set child [open |[list [interpreter]] r+]
+ puts $child "testexithandler create 41; testexithandler delete 41"
+ puts $child "testexithandler create 16; exit"
+ flush $child
+ set result [read $child]
+ close $child
+ return $result
+} {even 16
+}
+
+test event-10.1 {Tcl_Exit procedure} {stdio} {
+ set child [open |[list [interpreter]] r+]
+ puts $child "exit 3"
+ list [catch {close $child} msg] $msg [lindex $::errorCode 0] \
+ [lindex $::errorCode 2]
+} {1 {child process exited abnormally} CHILDSTATUS 3}
+
+test event-11.1 {Tcl_VwaitCmd procedure} -returnCodes error -body {
+ vwait
+} -result {wrong # args: should be "vwait name"}
+test event-11.2 {Tcl_VwaitCmd procedure} -returnCodes error -body {
+ vwait a b
+} -result {wrong # args: should be "vwait name"}
+test event-11.3 {Tcl_VwaitCmd procedure} -setup {
+ catch {unset x}
+} -body {
+ set x 1
+ vwait x(1)
+} -returnCodes error -result {can't trace "x(1)": variable isn't array}
+test event-11.4 {Tcl_VwaitCmd procedure} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+ after 10; update; # On Mac make sure update won't take long
+} -body {
+ after 100 {set x x-done}
+ after 200 {set y y-done}
+ after 300 {set z z-done}
+ after idle {set q q-done}
+ set x before
+ set y before
+ set z before
+ set q before
+ list [vwait y] $x $y $z $q
+} -cleanup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {{} x-done y-done before q-done}
+test event-11.5 {Tcl_VwaitCmd procedure: round robin scheduling, 2 sources} -setup {
+ set test1file [makeFile "" test1]
+} -constraints {socket} -body {
+ set f1 [open $test1file w]
+ proc accept {s args} {
+ puts $s foobar
+ close $s
+ }
+ set s1 [socket -server accept -myaddr 127.0.0.1 0]
+ after 1000
+ set s2 [socket 127.0.0.1 [lindex [fconfigure $s1 -sockname] 2]]
+ close $s1
+ set x 0
+ set y 0
+ set z 0
+ fileevent $s2 readable {incr z}
+ vwait z
+ fileevent $f1 writable {incr x; if {$y == 3} {set z done}}
+ fileevent $s2 readable {incr y; if {$x == 3} {set z done}}
+ vwait z
+ close $f1
+ close $s2
+ list $x $y $z
+} -cleanup {
+ removeFile $test1file
+} -result {3 3 done}
+test event-11.6 {Tcl_VwaitCmd procedure: round robin scheduling, same source} {
+ set test1file [makeFile "" test1]
+ set test2file [makeFile "" test2]
+ set f1 [open $test1file w]
+ set f2 [open $test2file w]
+ set x 0
+ set y 0
+ set z 0
+ update
+ fileevent $f1 writable {incr x; if {$y == 3} {set z done}}
+ fileevent $f2 writable {incr y; if {$x == 3} {set z done}}
+ vwait z
+ close $f1
+ close $f2
+ removeFile $test1file
+ removeFile $test2file
+ list $x $y $z
+} {3 3 done}
+
+test event-12.1 {Tcl_UpdateCmd procedure} -returnCodes error -body {
+ update a b
+} -result {wrong # args: should be "update ?idletasks?"}
+test event-12.2 {Tcl_UpdateCmd procedure} -returnCodes error -body {
+ update bogus
+} -result {bad option "bogus": must be idletasks}
+test event-12.3 {Tcl_UpdateCmd procedure} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ after 500 {set x after}
+ after idle {set y after}
+ after idle {set z "after, y = $y"}
+ set x before
+ set y before
+ set z before
+ update idletasks
+ list $x $y $z
+} -cleanup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {before after {after, y = after}}
+test event-12.4 {Tcl_UpdateCmd procedure} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ after 10; update; # On Mac make sure update won't take long
+ after 200 {set x x-done}
+ after 600 {set y y-done}
+ after idle {set z z-done}
+ set x before
+ set y before
+ set z before
+ after 300
+ update
+ list $x $y $z
+} -cleanup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {x-done before z-done}
+
+test event-13.1 {Tcl_WaitForFile procedure, readable} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+ testfilehandler close
+} -constraints {testfilehandler} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ set x "no timeout"
+ set result [testfilehandler wait 1 readable 0]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {{} {no timeout}}
+test event-13.2 {Tcl_WaitForFile procedure, readable} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+ testfilehandler close
+} -constraints testfilehandler -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ set x "no timeout"
+ set result [testfilehandler wait 1 readable 100]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {{} timeout}
+test event-13.3 {Tcl_WaitForFile procedure, readable} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+ testfilehandler close
+} -constraints testfilehandler -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ testfilehandler fillpartial 1
+ set x "no timeout"
+ set result [testfilehandler wait 1 readable 100]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {readable {no timeout}}
+test event-13.4 {Tcl_WaitForFile procedure, writable} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+ testfilehandler close
+} -constraints {testfilehandler nonPortable} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ testfilehandler fill 1
+ set x "no timeout"
+ set result [testfilehandler wait 1 writable 0]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {{} {no timeout}}
+test event-13.5 {Tcl_WaitForFile procedure, writable} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+ testfilehandler close
+} -constraints {testfilehandler nonPortable} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ testfilehandler fill 1
+ set x "no timeout"
+ set result [testfilehandler wait 1 writable 100]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {{} timeout}
+test event-13.6 {Tcl_WaitForFile procedure, writable} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+ testfilehandler close
+} -constraints testfilehandler -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ set x "no timeout"
+ set result [testfilehandler wait 1 writable 100]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {writable {no timeout}}
+test event-13.7 {Tcl_WaitForFile procedure, don't call other event handlers} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+ testfilehandler close
+} -constraints testfilehandler -body {
+ after 100 lappend x timeout
+ after idle lappend x idle
+ testfilehandler create 1 off off
+ set x ""
+ set result [list [testfilehandler wait 1 readable 200] $x]
+ update
+ lappend result $x
+} -cleanup {
+ testfilehandler close
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {{} {} {timeout idle}}
+test event-13.8 {Tcl_WaitForFile procedure, waiting indefinitely} testfilewait {
+ set f [open "|sleep 2" r]
+ set result ""
+ lappend result [testfilewait $f readable 100]
+ lappend result [testfilewait $f readable -1]
+ close $f
+ return $result
+} {{} readable}
+
+test event-14.1 {Tcl_WaitForFile procedure, readable, big fd} -setup {
+ set chanList {}
+ for {set i 0} {$i < 32} {incr i} {
+ lappend chanList [open /dev/null r]
+ }
+ foreach i [after info] {after cancel $i}
+ testfilehandler close
+} -constraints {testfilehandler unix} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ set x "no timeout"
+ set result [testfilehandler wait 1 readable 0]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach chan $chanList {close $chan}
+ foreach i [after info] {after cancel $i}
+} -result {{} {no timeout}}
+test event-14.2 {Tcl_WaitForFile procedure, readable, big fd} -setup {
+ set chanList {}
+ for {set i 0} {$i < 32} {incr i} {
+ lappend chanList [open /dev/null r]
+ }
+ foreach i [after info] {after cancel $i}
+ testfilehandler close
+} -constraints {testfilehandler unix} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ set x "no timeout"
+ set result [testfilehandler wait 1 readable 100]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach chan $chanList {close $chan}
+ foreach i [after info] {after cancel $i}
+} -result {{} timeout}
+test event-14.3 {Tcl_WaitForFile procedure, readable, big fd} -setup {
+ set chanList {}
+ for {set i 0} {$i < 32} {incr i} {
+ lappend chanList [open /dev/null r]
+ }
+ foreach i [after info] {after cancel $i}
+ testfilehandler close
+} -constraints {testfilehandler unix} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ testfilehandler fillpartial 1
+ set x "no timeout"
+ set result [testfilehandler wait 1 readable 100]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach chan $chanList {close $chan}
+ foreach i [after info] {after cancel $i}
+} -result {readable {no timeout}}
+test event-14.4 {Tcl_WaitForFile procedure, writable, big fd} -setup {
+ set chanList {}
+ for {set i 0} {$i < 32} {incr i} {
+ lappend chanList [open /dev/null r]
+ }
+ foreach i [after info] {after cancel $i}
+ testfilehandler close
+} -constraints {testfilehandler unix nonPortable} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ testfilehandler fill 1
+ set x "no timeout"
+ set result [testfilehandler wait 1 writable 0]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach chan $chanList {close $chan}
+ foreach i [after info] {after cancel $i}
+} -result {{} {no timeout}}
+test event-14.5 {Tcl_WaitForFile procedure, writable, big fd} -setup {
+ set chanList {}
+ for {set i 0} {$i < 32} {incr i} {
+ lappend chanList [open /dev/null r]
+ }
+ foreach i [after info] {after cancel $i}
+ testfilehandler close
+} -constraints {testfilehandler unix nonPortable} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ testfilehandler fill 1
+ set x "no timeout"
+ set result [testfilehandler wait 1 writable 100]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach chan $chanList {close $chan}
+ foreach i [after info] {after cancel $i}
+} -result {{} timeout}
+test event-14.6 {Tcl_WaitForFile procedure, writable, big fd} -setup {
+ set chanList {}
+ for {set i 0} {$i < 32} {incr i} {
+ lappend chanList [open /dev/null r]
+ }
+ foreach i [after info] {after cancel $i}
+ testfilehandler close
+} -constraints {testfilehandler unix} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ set x "no timeout"
+ set result [testfilehandler wait 1 writable 100]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach chan $chanList {close $chan}
+ foreach i [after info] {after cancel $i}
+} -result {writable {no timeout}}
+test event-14.7 {Tcl_WaitForFile, don't call other event handlers, big fd} -setup {
+ set chanList {}
+ for {set i 0} {$i < 32} {incr i} {
+ lappend chanList [open /dev/null r]
+ }
+ foreach i [after info] {after cancel $i}
+ testfilehandler close
+} -constraints {testfilehandler unix} -body {
+ after 100 lappend x timeout
+ after idle lappend x idle
+ testfilehandler create 1 off off
+ set x ""
+ set result [list [testfilehandler wait 1 readable 200] $x]
+ update
+ lappend result $x
+} -cleanup {
+ testfilehandler close
+ foreach chan $chanList {close $chan}
+ foreach i [after info] {after cancel $i}
+} -result {{} {} {timeout idle}}
+test event-14.8 {Tcl_WaitForFile procedure, waiting indefinitely, big fd} -setup {
+ set chanList {}
+ for {set i 0} {$i < 32} {incr i} {
+ lappend chanList [open /dev/null r]
+ }
+} -constraints {testfilewait unix} -body {
+ set f [open "|sleep 2" r]
+ set result ""
+ lappend result [testfilewait $f readable 100]
+ lappend result [testfilewait $f readable -1]
+ close $f
+ return $result
+} -cleanup {
+ foreach chan $chanList {close $chan}
+} -result {{} readable}
+
+# cleanup
+foreach i [after info] {
+ after cancel $i
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/exec.test b/library/msgcat/tests/exec.test
new file mode 100644
index 0000000..64d3517
--- /dev/null
+++ b/library/msgcat/tests/exec.test
@@ -0,0 +1,699 @@
+# Commands covered: exec
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+# All tests require the "exec" command.
+# Skip them if exec is not defined.
+testConstraint exec [llength [info commands exec]]
+unset -nocomplain path
+
+# Utilities that are like bourne shell stalwarts, but cross-platform.
+set path(echo) [makeFile {
+ puts -nonewline [lindex $argv 0]
+ foreach str [lrange $argv 1 end] {
+ puts -nonewline " $str"
+ }
+ puts {}
+ exit
+} echo]
+set path(echo2) [makeFile {
+ puts stdout [join $argv]
+ puts stderr [lindex $argv 1]
+ exit
+} echo2]
+set path(cat) [makeFile {
+ if {$argv eq ""} {
+ set argv -
+ }
+ fconfigure stdout -translation binary
+ foreach name $argv {
+ if {$name eq "-"} {
+ set f stdin
+ } elseif {[catch {open $name r} f] != 0} {
+ puts stderr $f
+ continue
+ }
+ fconfigure $f -translation binary
+ while {[eof $f] == 0} {
+ puts -nonewline [read $f]
+ }
+ if {$f ne "stdin"} {
+ close $f
+ }
+ }
+ exit
+} cat]
+set path(wc) [makeFile {
+ set data [read stdin]
+ set lines [regsub -all "\n" $data {} dummy]
+ set words [regsub -all "\[^ \t\n]+" $data {} dummy]
+ set chars [string length $data]
+ puts [format "%8.d%8.d%8.d" $lines $words $chars]
+ exit
+} wc]
+set path(sh) [makeFile {
+ if {[lindex $argv 0] ne "-c"} {
+ error "sh: unexpected arguments $argv"
+ }
+ set cmd [lindex $argv 1]
+ lappend cmd ";"
+ set newcmd {}
+ foreach arg $cmd {
+ if {$arg eq ";"} {
+ exec >@stdout 2>@stderr [info nameofexecutable] {*}$newcmd
+ set newcmd {}
+ continue
+ }
+ if {$arg eq "1>&2"} {
+ set arg >@stderr
+ }
+ lappend newcmd $arg
+ }
+ exit
+} sh]
+set path(sh2) [makeFile {
+ if {[lindex $argv 0] ne "-c"} {
+ error "sh: unexpected arguments $argv"
+ }
+ set cmd [lindex $argv 1]
+ lappend cmd ";"
+ set newcmd {}
+ foreach arg $cmd {
+ if {$arg eq ";"} {
+ exec -ignorestderr >@stdout [info nameofexecutable] {*}$newcmd
+ set newcmd {}
+ continue
+ }
+ lappend newcmd $arg
+ }
+ exit
+} sh2]
+set path(sleep) [makeFile {
+ after [expr $argv*1000]
+ exit
+} sleep]
+set path(exit) [makeFile {
+ exit $argv
+} exit]
+
+proc readfile filename {
+ set f [open $filename]
+ set d [read $f]
+ close $f
+ return [string trimright $d \n]
+}
+
+# ----------------------------------------------------------------------
+# Basic operations.
+
+test exec-1.1 {basic exec operation} {exec} {
+ exec [interpreter] $path(echo) a b c
+} "a b c"
+test exec-1.2 {pipelining} {exec stdio} {
+ exec [interpreter] $path(echo) a b c d | [interpreter] $path(cat) | [interpreter] $path(cat)
+} "a b c d"
+test exec-1.3 {pipelining} {exec stdio} {
+ set a [exec [interpreter] $path(echo) a b c d | [interpreter] $path(cat) | [interpreter] $path(wc)]
+ list [scan $a "%d %d %d" b c d] $b $c
+} {3 1 4}
+set arg {12345678901234567890123456789012345678901234567890}
+set arg "$arg$arg$arg$arg$arg$arg"
+test exec-1.4 {long command lines} {exec} {
+ exec [interpreter] $path(echo) $arg
+} $arg
+set arg {}
+
+# I/O redirection: input from Tcl command.
+
+test exec-2.1 {redirecting input from immediate source} {exec stdio} {
+ exec [interpreter] $path(cat) << "Sample text"
+} {Sample text}
+test exec-2.2 {redirecting input from immediate source} {exec stdio} {
+ exec << "Sample text" [interpreter] $path(cat) | [interpreter] $path(cat)
+} {Sample text}
+test exec-2.3 {redirecting input from immediate source} {exec stdio} {
+ exec [interpreter] $path(cat) << "Sample text" | [interpreter] $path(cat)
+} {Sample text}
+test exec-2.4 {redirecting input from immediate source} {exec stdio} {
+ exec [interpreter] $path(cat) | [interpreter] $path(cat) << "Sample text"
+} {Sample text}
+test exec-2.5 {redirecting input from immediate source} {exec} {
+ exec [interpreter] $path(cat) "<<Joined to arrows"
+} {Joined to arrows}
+test exec-2.6 {redirecting input from immediate source, with UTF} -setup {
+ set sysenc [encoding system]
+ encoding system iso8859-1
+ proc quotenonascii s {
+ regsub -all {\[|\\|\]} $s {\\&} s
+ regsub -all {[\u007f-\uffff]} $s \
+ {[apply {c {format {\u%04x} [scan $c %c]}} &]} s
+ return [subst -novariables $s]
+ }
+} -constraints {exec} -body {
+ # If this fails, it may give back: "\uC3\uA9\uC3\uA0\uC3\uBC\uC3\uB1"
+ # If it does, this means that the UTF -> external conversion did not occur
+ # before writing out the temp file.
+ quotenonascii [exec [interpreter] $path(cat) << "\uE9\uE0\uFC\uF1"]
+} -cleanup {
+ encoding system $sysenc
+ rename quotenonascii {}
+} -result {\u00e9\u00e0\u00fc\u00f1}
+
+# I/O redirection: output to file.
+
+set path(gorp.file) [makeFile {} gorp.file]
+file delete $path(gorp.file)
+
+test exec-3.1 {redirecting output to file} {exec} {
+ exec [interpreter] $path(echo) "Some simple words" > $path(gorp.file)
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "Some simple words"
+test exec-3.2 {redirecting output to file} {exec stdio} {
+ exec [interpreter] $path(echo) "More simple words" | >$path(gorp.file) [interpreter] $path(cat) | [interpreter] $path(cat)
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "More simple words"
+test exec-3.3 {redirecting output to file} {exec stdio} {
+ exec > $path(gorp.file) [interpreter] $path(echo) "Different simple words" | [interpreter] $path(cat) | [interpreter] $path(cat)
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "Different simple words"
+test exec-3.4 {redirecting output to file} {exec} {
+ exec [interpreter] $path(echo) "Some simple words" >$path(gorp.file)
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "Some simple words"
+test exec-3.5 {redirecting output to file} {exec} {
+ exec [interpreter] $path(echo) "First line" >$path(gorp.file)
+ exec [interpreter] $path(echo) "Second line" >> $path(gorp.file)
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "First line\nSecond line"
+test exec-3.6 {redirecting output to file} {exec} {
+ exec [interpreter] $path(echo) "First line" >$path(gorp.file)
+ exec [interpreter] $path(echo) "Second line" >>$path(gorp.file)
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "First line\nSecond line"
+test exec-3.7 {redirecting output to file} {exec} {
+ set f [open $path(gorp.file) w]
+ puts $f "Line 1"
+ flush $f
+ exec [interpreter] $path(echo) "More text" >@ $f
+ exec [interpreter] $path(echo) >@$f "Even more"
+ puts $f "Line 3"
+ close $f
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "Line 1\nMore text\nEven more\nLine 3"
+
+# I/O redirection: output and stderr to file.
+
+file delete $path(gorp.file)
+
+test exec-4.1 {redirecting output and stderr to file} {exec} {
+ exec [interpreter] $path(echo) "test output" >& $path(gorp.file)
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "test output"
+test exec-4.2 {redirecting output and stderr to file} {exec} {
+ list [exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" >&$path(gorp.file)] \
+ [exec [interpreter] $path(cat) $path(gorp.file)]
+} {{} {foo bar}}
+test exec-4.3 {redirecting output and stderr to file} {exec} {
+ exec [interpreter] $path(echo) "first line" > $path(gorp.file)
+ list [exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" >>&$path(gorp.file)] \
+ [exec [interpreter] $path(cat) $path(gorp.file)]
+} "{} {first line\nfoo bar}"
+test exec-4.4 {redirecting output and stderr to file} {exec} {
+ set f [open $path(gorp.file) w]
+ puts $f "Line 1"
+ flush $f
+ exec [interpreter] $path(echo) "More text" >&@ $f
+ exec [interpreter] $path(echo) >&@$f "Even more"
+ puts $f "Line 3"
+ close $f
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "Line 1\nMore text\nEven more\nLine 3"
+test exec-4.5 {redirecting output and stderr to file} {exec} {
+ set f [open $path(gorp.file) w]
+ puts $f "Line 1"
+ flush $f
+ exec >&@ $f [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2"
+ exec >&@$f [interpreter] $path(sh) -c "\"$path(echo)\" xyzzy 1>&2"
+ puts $f "Line 3"
+ close $f
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "Line 1\nfoo bar\nxyzzy\nLine 3"
+
+# I/O redirection: input from file.
+
+if {[testConstraint exec]} {
+ exec [interpreter] $path(echo) "Just a few thoughts" > $path(gorp.file)
+}
+test exec-5.1 {redirecting input from file} {exec} {
+ exec [interpreter] $path(cat) < $path(gorp.file)
+} {Just a few thoughts}
+test exec-5.2 {redirecting input from file} {exec stdio} {
+ exec [interpreter] $path(cat) | [interpreter] $path(cat) < $path(gorp.file)
+} {Just a few thoughts}
+test exec-5.3 {redirecting input from file} {exec stdio} {
+ exec [interpreter] $path(cat) < $path(gorp.file) | [interpreter] $path(cat)
+} {Just a few thoughts}
+test exec-5.4 {redirecting input from file} {exec stdio} {
+ exec < $path(gorp.file) [interpreter] $path(cat) | [interpreter] $path(cat)
+} {Just a few thoughts}
+test exec-5.5 {redirecting input from file} {exec} {
+ exec [interpreter] $path(cat) <$path(gorp.file)
+} {Just a few thoughts}
+test exec-5.6 {redirecting input from file} -constraints {exec} -body {
+ set f [open $path(gorp.file) r]
+ exec [interpreter] $path(cat) <@ $f
+} -cleanup {
+ close $f
+} -result {Just a few thoughts}
+test exec-5.7 {redirecting input from file} -constraints {exec} -body {
+ set f [open $path(gorp.file) r]
+ exec <@$f [interpreter] $path(cat)
+} -cleanup {
+ close $f
+} -result {Just a few thoughts}
+
+# I/O redirection: standard error through a pipeline.
+
+test exec-6.1 {redirecting stderr through a pipeline} {exec stdio} {
+ exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar" |& [interpreter] $path(cat)
+} "foo bar"
+test exec-6.2 {redirecting stderr through a pipeline} {exec stdio} {
+ exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" |& [interpreter] $path(cat)
+} "foo bar"
+test exec-6.3 {redirecting stderr through a pipeline} {exec stdio} {
+ exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" \
+ |& [interpreter] $path(sh) -c "\"$path(echo)\" second msg 1>&2 ; \"$path(cat)\"" |& [interpreter] $path(cat)
+} "second msg\nfoo bar"
+
+# I/O redirection: combinations.
+
+set path(gorp.file2) [makeFile {} gorp.file2]
+file delete $path(gorp.file2)
+
+test exec-7.1 {multiple I/O redirections} {exec} {
+ exec << "command input" > $path(gorp.file2) [interpreter] $path(cat) < $path(gorp.file)
+ exec [interpreter] $path(cat) $path(gorp.file2)
+} {Just a few thoughts}
+test exec-7.2 {multiple I/O redirections} {exec} {
+ exec < $path(gorp.file) << "command input" [interpreter] $path(cat)
+} {command input}
+
+# Long input to command and output from command.
+set a "0123456789 xxxxxxxxx abcdefghi ABCDEFGHIJK\n"
+set a [concat $a $a $a $a]
+set a [concat $a $a $a $a]
+set a [concat $a $a $a $a]
+set a [concat $a $a $a $a]
+test exec-8.1 {long input and output} {exec} {
+ exec [interpreter] $path(cat) << $a
+} $a
+# More than 20 arguments to exec.
+test exec-8.2 {long input and output} {exec} {
+ exec [interpreter] $path(echo) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23}
+
+# Commands that return errors.
+
+test exec-9.1 {commands returning errors} {exec} {
+ set x [catch {exec gorp456} msg]
+ list $x [string tolower $msg] [string tolower $errorCode]
+} {1 {couldn't execute "gorp456": no such file or directory} {posix enoent {no such file or directory}}}
+test exec-9.2 {commands returning errors} {exec} {
+ string tolower [list [catch {exec [interpreter] echo foo | foo123} msg] $msg $errorCode]
+} {1 {couldn't execute "foo123": no such file or directory} {posix enoent {no such file or directory}}}
+test exec-9.3 {commands returning errors} -constraints {exec stdio} -body {
+ exec [interpreter] $path(sleep) 1 | [interpreter] $path(exit) 43 | [interpreter] $path(sleep) 1
+} -returnCodes error -result {child process exited abnormally}
+test exec-9.4 {commands returning errors} -constraints {exec stdio} -body {
+ exec [interpreter] $path(exit) 43 | [interpreter] $path(echo) "foo bar"
+} -returnCodes error -result {foo bar
+child process exited abnormally}
+test exec-9.5 {commands returning errors} -constraints {exec stdio} -body {
+ exec gorp456 | [interpreter] echo a b c
+} -returnCodes error -result {couldn't execute "gorp456": no such file or directory}
+test exec-9.6 {commands returning errors} -constraints {exec} -body {
+ exec [interpreter] $path(sh) -c "\"$path(echo)\" error msg 1>&2"
+} -returnCodes error -result {error msg}
+test exec-9.7 {commands returning errors} -constraints {exec stdio nonPortable} -body {
+ # This test can fail easily on multiprocessor machines
+ exec [interpreter] $path(sh) -c "\"$path(echo)\" error msg 1>&2 ; \"$path(sleep)\" 1" \
+ | [interpreter] $path(sh) -c "\"$path(echo)\" error msg 1>&2 ; \"$path(sleep)\" 1"
+} -returnCodes error -result {error msg
+error msg}
+set path(err) [makeFile {} err]
+test exec-9.8 {commands returning errors} -constraints {exec} -setup {
+ set f [open $path(err) w]
+ puts $f {
+ puts stdout out
+ puts stderr err
+ }
+ close $f
+} -body {
+ exec [interpreter] $path(err)
+} -returnCodes error -result {out
+err}
+
+# Errors in executing the Tcl command, as opposed to errors in the processes
+# that are invoked.
+
+test exec-10.1 {errors in exec invocation} -constraints {exec} -body {
+ exec
+} -returnCodes error -result {wrong # args: should be "exec ?-switch ...? arg ?arg ...?"}
+test exec-10.2 {errors in exec invocation} -constraints {exec} -body {
+ exec | cat
+} -returnCodes error -result {illegal use of | or |& in command}
+test exec-10.3 {errors in exec invocation} -constraints {exec} -body {
+ exec cat |
+} -returnCodes error -result {illegal use of | or |& in command}
+test exec-10.4 {errors in exec invocation} -constraints {exec} -body {
+ exec cat | | cat
+} -returnCodes error -result {illegal use of | or |& in command}
+test exec-10.5 {errors in exec invocation} -constraints {exec} -body {
+ exec cat | |& cat
+} -returnCodes error -result {illegal use of | or |& in command}
+test exec-10.6 {errors in exec invocation} -constraints {exec} -body {
+ exec cat |&
+} -returnCodes error -result {illegal use of | or |& in command}
+test exec-10.7 {errors in exec invocation} -constraints {exec} -body {
+ exec cat <
+} -returnCodes error -result {can't specify "<" as last word in command}
+test exec-10.8 {errors in exec invocation} -constraints {exec} -body {
+ exec cat >
+} -returnCodes error -result {can't specify ">" as last word in command}
+test exec-10.9 {errors in exec invocation} -constraints {exec} -body {
+ exec cat <<
+} -returnCodes error -result {can't specify "<<" as last word in command}
+test exec-10.10 {errors in exec invocation} -constraints {exec} -body {
+ exec cat >>
+} -returnCodes error -result {can't specify ">>" as last word in command}
+test exec-10.11 {errors in exec invocation} -constraints {exec} -body {
+ exec cat >&
+} -returnCodes error -result {can't specify ">&" as last word in command}
+test exec-10.12 {errors in exec invocation} -constraints {exec} -body {
+ exec cat >>&
+} -returnCodes error -result {can't specify ">>&" as last word in command}
+test exec-10.13 {errors in exec invocation} -constraints {exec} -body {
+ exec cat >@
+} -returnCodes error -result {can't specify ">@" as last word in command}
+test exec-10.14 {errors in exec invocation} -constraints {exec} -body {
+ exec cat <@
+} -returnCodes error -result {can't specify "<@" as last word in command}
+test exec-10.15 {errors in exec invocation} -constraints {exec} -body {
+ exec cat < a/b/c
+} -returnCodes error -result {couldn't read file "a/b/c": no such file or directory}
+test exec-10.16 {errors in exec invocation} -constraints {exec} -body {
+ exec cat << foo > a/b/c
+} -returnCodes error -result {couldn't write file "a/b/c": no such file or directory}
+test exec-10.17 {errors in exec invocation} -constraints {exec} -body {
+ exec cat << foo > a/b/c
+} -returnCodes error -result {couldn't write file "a/b/c": no such file or directory}
+set f [open $path(gorp.file) w]
+test exec-10.18 {errors in exec invocation} -constraints {exec} -body {
+ exec cat <@ $f
+} -returnCodes error -result "channel \"$f\" wasn't opened for reading"
+close $f
+set f [open $path(gorp.file) r]
+test exec-10.19 {errors in exec invocation} -constraints {exec} -body {
+ exec cat >@ $f
+} -returnCodes error -result "channel \"$f\" wasn't opened for writing"
+close $f
+test exec-10.20 {errors in exec invocation} -constraints {exec} -body {
+ exec ~non_existent_user/foo/bar
+} -returnCodes error -result {user "non_existent_user" doesn't exist}
+test exec-10.21 {errors in exec invocation} -constraints {exec} -body {
+ exec [interpreter] true | ~xyzzy_bad_user/x | false
+} -returnCodes error -result {user "xyzzy_bad_user" doesn't exist}
+test exec-10.22 {errors in exec invocation} -constraints exec -body {
+ exec echo test > ~non_existent_user/foo/bar
+} -returnCodes error -result {user "non_existent_user" doesn't exist}
+# Commands in background.
+
+test exec-11.1 {commands in background} {exec} {
+ set time [time {exec [interpreter] $path(sleep) 2 &}]
+ expr {[lindex $time 0] < 1000000}
+} 1
+test exec-11.2 {commands in background} -constraints {exec} -body {
+ exec [interpreter] $path(echo) a &b
+} -result {a &b}
+test exec-11.3 {commands in background} {exec} {
+ llength [exec [interpreter] $path(sleep) 1 &]
+} 1
+test exec-11.4 {commands in background} {exec stdio} {
+ llength [exec [interpreter] $path(sleep) 1 | [interpreter] $path(sleep) 1 | [interpreter] $path(sleep) 1 &]
+} 3
+test exec-11.5 {commands in background} {exec} {
+ set f [open $path(gorp.file) w]
+ puts $f [list catch [list exec [info nameofexecutable] $path(echo) foo &]]
+ close $f
+ exec [interpreter] $path(gorp.file)
+} foo
+
+# Make sure that background commands are properly reaped when they
+# eventually die.
+
+if {[testConstraint exec] && [testConstraint nonPortable]} {
+ after 1300
+ exec [interpreter] $path(sleep) 1
+}
+test exec-12.1 {reaping background processes} {exec unix nonPortable} {
+ for {set i 0} {$i < 20} {incr i} {
+ exec echo foo > /dev/null &
+ }
+ after 1000
+ catch {exec ps | fgrep "echo foo" | fgrep -v fgrep | wc} msg
+ lindex $msg 0
+} 0
+test exec-12.2 {reaping background processes} {exec unix nonPortable} {
+ exec sleep 2 | sleep 2 | sleep 2 &
+ catch {exec ps | fgrep -i "sleep" | fgrep -i -v fgrep | wc} msg
+ set x [lindex $msg 0]
+ after 3000
+ catch {exec ps | fgrep -i "sleep" | fgrep -i -v fgrep | wc} msg
+ list $x [lindex $msg 0]
+} {3 0}
+test exec-12.3 {reaping background processes} {exec unix nonPortable} {
+ exec sleep 1000 &
+ exec sleep 1000 &
+ set x [exec ps | fgrep "sleep" | fgrep -v fgrep]
+ set pids {}
+ foreach i [split $x \n] {
+ lappend pids [lindex $i 0]
+ }
+ foreach i $pids {
+ catch {exec kill -STOP $i}
+ }
+ catch {exec ps | fgrep "sleep" | fgrep -v fgrep | wc} msg
+ set x [lindex $msg 0]
+ foreach i $pids {
+ catch {exec kill -KILL $i}
+ }
+ catch {exec ps | fgrep "sleep" | fgrep -v fgrep | wc} msg
+ list $x [lindex $msg 0]
+} {2 0}
+
+# Make sure "errorCode" is set correctly.
+
+test exec-13.1 {setting errorCode variable} {exec} {
+ list [catch {exec [interpreter] $path(cat) < a/b/c} msg] [string tolower $errorCode]
+} {1 {posix enoent {no such file or directory}}}
+test exec-13.2 {setting errorCode variable} {exec} {
+ list [catch {exec [interpreter] $path(cat) > a/b/c} msg] [string tolower $errorCode]
+} {1 {posix enoent {no such file or directory}}}
+test exec-13.3 {setting errorCode variable} {exec} {
+ set x [catch {exec _weird_cmd_} msg]
+ list $x [string tolower $msg] [lindex $errorCode 0] \
+ [string tolower [lrange $errorCode 2 end]]
+} {1 {couldn't execute "_weird_cmd_": no such file or directory} POSIX {{no such file or directory}}}
+test exec-13.4 {extended exit result codes} -setup {
+ set tmp [makeFile {exit 0x00000101} tmpfile.exec-13.4]
+} -constraints {win} -body {
+ list [catch {exec [interpreter] $tmp} err] [lreplace $::errorCode 1 1 {}]
+} -cleanup {
+ removeFile $tmp
+} -result {1 {CHILDSTATUS {} 257}}
+test exec-13.5 {extended exit result codes: max value} -setup {
+ set tmp [makeFile {exit 0x3fffffff} tmpfile.exec-13.5]
+} -constraints {win} -body {
+ list [catch {exec [interpreter] $tmp} err] [lreplace $::errorCode 1 1 {}]
+} -cleanup {
+ removeFile $tmp
+} -result {1 {CHILDSTATUS {} 1073741823}}
+test exec-13.6 {extended exit result codes: signalled} -setup {
+ set tmp [makeFile {exit 0xC0000016} tmpfile.exec-13.6]
+} -constraints {win} -body {
+ list [catch {exec [interpreter] $tmp} err] [lreplace $::errorCode 1 1 {}]
+} -cleanup {
+ removeFile $tmp
+} -result {1 {CHILDKILLED {} SIGABRT SIGABRT}}
+
+# Switches before the first argument
+
+test exec-14.1 {-keepnewline switch} {exec} {
+ exec -keepnewline [interpreter] $path(echo) foo
+} "foo\n"
+test exec-14.2 {-keepnewline switch} -constraints {exec} -body {
+ exec -keepnewline
+} -returnCodes error -result {wrong # args: should be "exec ?-switch ...? arg ?arg ...?"}
+test exec-14.3 {unknown switch} -constraints {exec} -body {
+ exec -gorp
+} -returnCodes error -result {bad switch "-gorp": must be -ignorestderr, -keepnewline, or --}
+test exec-14.4 {-- switch} -constraints {exec} -body {
+ exec -- -gorp
+} -returnCodes error -result {couldn't execute "-gorp": no such file or directory}
+test exec-14.5 {-ignorestderr switch} {exec} {
+ # Alas, the use of -ignorestderr is buried here :-(
+ exec [interpreter] $path(sh2) -c [list $path(echo2) foo bar] 2>@1
+} "foo bar\nbar"
+
+# Redirecting standard error separately from standard output
+
+test exec-15.1 {standard error redirection} {exec} {
+ exec [interpreter] $path(echo) "First line" > $path(gorp.file)
+ list [exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" 2> $path(gorp.file)] \
+ [exec [interpreter] $path(cat) $path(gorp.file)]
+} {{} {foo bar}}
+test exec-15.2 {standard error redirection} {exec stdio} {
+ list [exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" \
+ | [interpreter] $path(echo) biz baz >$path(gorp.file) 2> $path(gorp.file2)] \
+ [exec [interpreter] $path(cat) $path(gorp.file)] \
+ [exec [interpreter] $path(cat) $path(gorp.file2)]
+} {{} {biz baz} {foo bar}}
+test exec-15.3 {standard error redirection} {exec stdio} {
+ list [exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" \
+ | [interpreter] $path(echo) biz baz 2>$path(gorp.file) > $path(gorp.file2)] \
+ [exec [interpreter] $path(cat) $path(gorp.file)] \
+ [exec [interpreter] $path(cat) $path(gorp.file2)]
+} {{} {foo bar} {biz baz}}
+test exec-15.4 {standard error redirection} {exec} {
+ set f [open $path(gorp.file) w]
+ puts $f "Line 1"
+ flush $f
+ exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" 2>@ $f
+ puts $f "Line 3"
+ close $f
+ readfile $path(gorp.file)
+} {Line 1
+foo bar
+Line 3}
+test exec-15.5 {standard error redirection} {exec} {
+ exec [interpreter] $path(echo) "First line" > "$path(gorp.file)"
+ exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" 2>> "$path(gorp.file)"
+ readfile $path(gorp.file)
+} {First line
+foo bar}
+test exec-15.6 {standard error redirection} {exec stdio} {
+ exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" > "$path(gorp.file2)" 2> "$path(gorp.file)" \
+ >& "$path(gorp.file)" 2> "$path(gorp.file2)" | [interpreter] $path(echo) biz baz
+ list [readfile $path(gorp.file)] [readfile $path(gorp.file2)]
+} {{biz baz} {foo bar}}
+test exec-15.7 {standard error redirection 2>@1} {exec stdio} {
+ # This redirects stderr output into normal result output from exec
+ exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" 2>@1
+} {foo bar}
+
+test exec-16.1 {flush output before exec} {exec} {
+ set f [open $path(gorp.file) w]
+ puts $f "First line"
+ exec [interpreter] $path(echo) "Second line" >@ $f
+ puts $f "Third line"
+ close $f
+ readfile $path(gorp.file)
+} {First line
+Second line
+Third line}
+test exec-16.2 {flush output before exec} {exec} {
+ set f [open $path(gorp.file) w]
+ puts $f "First line"
+ exec [interpreter] << {puts stderr {Second line}} >&@ $f > $path(gorp.file2)
+ puts $f "Third line"
+ close $f
+ readfile $path(gorp.file)
+} {First line
+Second line
+Third line}
+
+test exec-17.1 {inheriting standard I/O} -constraints {exec} -setup {
+ set path(script) [makeFile {} script]
+ set f [open $path(script) w]
+ puts $f [list lassign [list \
+ [info nameofexecutable] $path(gorp.file) $path(echo) $path(sleep) \
+ ] exe file echo sleep]
+ puts $f {
+ close stdout
+ set f [open $file w]
+ catch {exec $exe $echo foobar &}
+ exec $exe $sleep 2
+ close $f
+ }
+ close $f
+} -body {
+ catch {exec [interpreter] $path(script)} result
+ list $result [readfile $path(gorp.file)]
+} -cleanup {
+ removeFile $path(script)
+} -result {{} foobar}
+
+test exec-18.1 {exec deals with weird file names} -body {
+ set path(fooblah) [makeFile {contents} "foo\[\{blah"]
+ exec [interpreter] $path(cat) $path(fooblah)
+} -constraints {exec} -cleanup {
+ removeFile $path(fooblah)
+} -result contents
+test exec-18.2 {exec cat deals with weird file names} -body {
+ # This is cross-platform, but the cat isn't predictably correct on
+ # Windows.
+ set path(fooblah) [makeFile {contents} "foo\[\{blah"]
+ exec cat $path(fooblah)
+} -constraints {exec tempNotWin} -cleanup {
+ removeFile $path(fooblah)
+} -result contents
+
+# Note that this test cannot be adapted to work on Windows; that platform has
+# no kernel support for an analog of O_APPEND. OTOH, that means we can assume
+# that there is a POSIX shell...
+test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix} -setup {
+ set tmpfile [makeFile {0} tmpfile.exec-19.1]
+} -body {
+ # Note that we have to allow for the current contents of the temporary
+ # file, which is why the result is 14 and not 12
+ exec /bin/sh -c \
+ {for a in 1 2 3; do sleep 1; echo $a; done} >>$tmpfile &
+ exec /bin/sh -c \
+ {for a in a b c; do sleep 1; echo $a; done} >>$tmpfile &
+ # The above two shell invokations take about 3 seconds to finish, so allow
+ # 5s (in case the machine is busy)
+ after 5000
+ # Check that no bytes have got lost through mixups with overlapping
+ # appends, which is only guaranteed to work when we set O_APPEND on the
+ # file descriptor in the [exec >>...]
+ file size $tmpfile
+} -cleanup {
+ removeFile $tmpfile
+} -result 14
+
+# ----------------------------------------------------------------------
+# cleanup
+
+foreach file {gorp.file gorp.file2 echo echo2 cat wc sh sh2 sleep exit err} {
+ removeFile $file
+}
+unset -nocomplain path
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/execute.test b/library/msgcat/tests/execute.test
new file mode 100644
index 0000000..012b3a7
--- /dev/null
+++ b/library/msgcat/tests/execute.test
@@ -0,0 +1,1062 @@
+# This file contains tests for the tclExecute.c source file. Tests appear in
+# the same order as the C code that they test. The set of tests is currently
+# incomplete since it currently includes only new tests for code changed for
+# the addition of Tcl namespaces. Other execution-related tests appear in
+# several other test files including namespace.test, basic.test, eval.test,
+# for.test, etc.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+catch {rename foo ""}
+catch {unset x}
+catch {unset y}
+catch {unset msg}
+
+testConstraint testobj [expr {
+ [llength [info commands testobj]]
+ && [llength [info commands testdoubleobj]]
+ && [llength [info commands teststringobj]]
+}]
+
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+testConstraint testexprlongobj [llength [info commands testexprlongobj]]
+
+# Tests for the omnibus TclExecuteByteCode function:
+
+# INST_DONE not tested
+# INST_PUSH1 not tested
+# INST_PUSH4 not tested
+# INST_POP not tested
+# INST_DUP not tested
+# INST_INVOKE_STK4 not tested
+# INST_INVOKE_STK1 not tested
+# INST_EVAL_STK not tested
+# INST_EXPR_STK not tested
+
+# INST_LOAD_SCALAR1
+test execute-1.1 {TclExecuteByteCode, INST_LOAD_SCALAR1, small opnd} {
+ proc foo {} {
+ set x 1
+ return $x
+ }
+ foo
+} 1
+test execute-1.2 {TclExecuteByteCode, INST_LOAD_SCALAR1, large opnd} {
+ # Bug: 2243
+ set body {}
+ for {set i 0} {$i < 129} {incr i} {
+ append body "set x$i x\n"
+ }
+ append body {
+ set y 1
+ return $y
+ }
+ proc foo {} $body
+ foo
+} 1
+test execute-1.3 {TclExecuteByteCode, INST_LOAD_SCALAR1, error} {
+ proc foo {} {
+ set x 1
+ unset x
+ return $x
+ }
+ list [catch {foo} msg] $msg
+} {1 {can't read "x": no such variable}}
+
+# INST_LOAD_SCALAR4
+test execute-2.1 {TclExecuteByteCode, INST_LOAD_SCALAR4, simple case} {
+ set body {}
+ for {set i 0} {$i < 256} {incr i} {
+ append body "set x$i x\n"
+ }
+ append body {
+ set y 1
+ return $y
+ }
+ proc foo {} $body
+ foo
+} 1
+test execute-2.2 {TclExecuteByteCode, INST_LOAD_SCALAR4, error} {
+ set body {}
+ for {set i 0} {$i < 256} {incr i} {
+ append body "set x$i x\n"
+ }
+ append body {
+ set y 1
+ unset y
+ return $y
+ }
+ proc foo {} $body
+ list [catch {foo} msg] $msg
+} {1 {can't read "y": no such variable}}
+
+# INST_LOAD_SCALAR_STK not tested
+# INST_LOAD_ARRAY4 not tested
+# INST_LOAD_ARRAY1 not tested
+# INST_LOAD_ARRAY_STK not tested
+# INST_LOAD_STK not tested
+# INST_STORE_SCALAR4 not tested
+# INST_STORE_SCALAR1 not tested
+# INST_STORE_SCALAR_STK not tested
+# INST_STORE_ARRAY4 not tested
+# INST_STORE_ARRAY1 not tested
+# INST_STORE_ARRAY_STK not tested
+# INST_STORE_STK not tested
+# INST_INCR_SCALAR1 not tested
+# INST_INCR_SCALAR_STK not tested
+# INST_INCR_STK not tested
+# INST_INCR_ARRAY1 not tested
+# INST_INCR_ARRAY_STK not tested
+# INST_INCR_SCALAR1_IMM not tested
+# INST_INCR_SCALAR_STK_IMM not tested
+# INST_INCR_STK_IMM not tested
+# INST_INCR_ARRAY1_IMM not tested
+# INST_INCR_ARRAY_STK_IMM not tested
+# INST_JUMP1 not tested
+# INST_JUMP4 not tested
+# INST_JUMP_TRUE4 not tested
+# INST_JUMP_TRUE1 not tested
+# INST_JUMP_FALSE4 not tested
+# INST_JUMP_FALSE1 not tested
+# INST_LOR not tested
+# INST_LAND not tested
+# INST_EQ not tested
+# INST_NEQ not tested
+# INST_LT not tested
+# INST_GT not tested
+# INST_LE not tested
+# INST_GE not tested
+# INST_MOD not tested
+# INST_LSHIFT not tested
+# INST_RSHIFT not tested
+# INST_BITOR not tested
+# INST_BITXOR not tested
+# INST_BITAND not tested
+
+# INST_ADD is partially tested:
+test execute-3.1 {TclExecuteByteCode, INST_ADD, op1 is int} {testobj} {
+ set x [testintobj set 0 1]
+ expr {$x + 1}
+} 2
+test execute-3.2 {TclExecuteByteCode, INST_ADD, op1 is double} {testobj} {
+ set x [testdoubleobj set 0 1]
+ expr {$x + 1}
+} 2.0
+test execute-3.3 {TclExecuteByteCode, INST_ADD, op1 is double with string} {testobj} {
+ set x [testintobj set 0 1]
+ testobj convert 0 double
+ expr {$x + 1}
+} 2
+test execute-3.4 {TclExecuteByteCode, INST_ADD, op1 is string int} {testobj} {
+ set x [teststringobj set 0 1]
+ expr {$x + 1}
+} 2
+test execute-3.5 {TclExecuteByteCode, INST_ADD, op1 is string double} {testobj} {
+ set x [teststringobj set 0 1.0]
+ expr {$x + 1}
+} 2.0
+test execute-3.6 {TclExecuteByteCode, INST_ADD, op1 is non-numeric} {testobj} {
+ set x [teststringobj set 0 foo]
+ list [catch {expr {$x + 1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test execute-3.7 {TclExecuteByteCode, INST_ADD, op2 is int} {testobj} {
+ set x [testintobj set 0 1]
+ expr {1 + $x}
+} 2
+test execute-3.8 {TclExecuteByteCode, INST_ADD, op2 is double} {testobj} {
+ set x [testdoubleobj set 0 1]
+ expr {1 + $x}
+} 2.0
+test execute-3.9 {TclExecuteByteCode, INST_ADD, op2 is double with string} {testobj} {
+ set x [testintobj set 0 1]
+ testobj convert 0 double
+ expr {1 + $x}
+} 2
+test execute-3.10 {TclExecuteByteCode, INST_ADD, op2 is string int} {testobj} {
+ set x [teststringobj set 0 1]
+ expr {1 + $x}
+} 2
+test execute-3.11 {TclExecuteByteCode, INST_ADD, op2 is string double} {testobj} {
+ set x [teststringobj set 0 1.0]
+ expr {1 + $x}
+} 2.0
+test execute-3.12 {TclExecuteByteCode, INST_ADD, op2 is non-numeric} {testobj} {
+ set x [teststringobj set 0 foo]
+ list [catch {expr {1 + $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+
+# INST_SUB is partially tested:
+test execute-3.13 {TclExecuteByteCode, INST_SUB, op1 is int} {testobj} {
+ set x [testintobj set 0 1]
+ expr {$x - 1}
+} 0
+test execute-3.14 {TclExecuteByteCode, INST_SUB, op1 is double} {testobj} {
+ set x [testdoubleobj set 0 1]
+ expr {$x - 1}
+} 0.0
+test execute-3.15 {TclExecuteByteCode, INST_SUB, op1 is double with string} {testobj} {
+ set x [testintobj set 0 1]
+ testobj convert 0 double
+ expr {$x - 1}
+} 0
+test execute-3.16 {TclExecuteByteCode, INST_SUB, op1 is string int} {testobj} {
+ set x [teststringobj set 0 1]
+ expr {$x - 1}
+} 0
+test execute-3.17 {TclExecuteByteCode, INST_SUB, op1 is string double} {testobj} {
+ set x [teststringobj set 0 1.0]
+ expr {$x - 1}
+} 0.0
+test execute-3.18 {TclExecuteByteCode, INST_SUB, op1 is non-numeric} {testobj} {
+ set x [teststringobj set 0 foo]
+ list [catch {expr {$x - 1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+test execute-3.19 {TclExecuteByteCode, INST_SUB, op2 is int} {testobj} {
+ set x [testintobj set 0 1]
+ expr {1 - $x}
+} 0
+test execute-3.20 {TclExecuteByteCode, INST_SUB, op2 is double} {testobj} {
+ set x [testdoubleobj set 0 1]
+ expr {1 - $x}
+} 0.0
+test execute-3.21 {TclExecuteByteCode, INST_SUB, op2 is double with string} {testobj} {
+ set x [testintobj set 0 1]
+ testobj convert 0 double
+ expr {1 - $x}
+} 0
+test execute-3.22 {TclExecuteByteCode, INST_SUB, op2 is string int} {testobj} {
+ set x [teststringobj set 0 1]
+ expr {1 - $x}
+} 0
+test execute-3.23 {TclExecuteByteCode, INST_SUB, op2 is string double} {testobj} {
+ set x [teststringobj set 0 1.0]
+ expr {1 - $x}
+} 0.0
+test execute-3.24 {TclExecuteByteCode, INST_SUB, op2 is non-numeric} {testobj} {
+ set x [teststringobj set 0 foo]
+ list [catch {expr {1 - $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+
+# INST_MULT is partially tested:
+test execute-3.25 {TclExecuteByteCode, INST_MULT, op1 is int} {testobj} {
+ set x [testintobj set 1 1]
+ expr {$x * 1}
+} 1
+test execute-3.26 {TclExecuteByteCode, INST_MULT, op1 is double} {testobj} {
+ set x [testdoubleobj set 1 2.0]
+ expr {$x * 1}
+} 2.0
+test execute-3.27 {TclExecuteByteCode, INST_MULT, op1 is double with string} {testobj} {
+ set x [testintobj set 1 2]
+ testobj convert 1 double
+ expr {$x * 1}
+} 2
+test execute-3.28 {TclExecuteByteCode, INST_MULT, op1 is string int} {testobj} {
+ set x [teststringobj set 1 1]
+ expr {$x * 1}
+} 1
+test execute-3.29 {TclExecuteByteCode, INST_MULT, op1 is string double} {testobj} {
+ set x [teststringobj set 1 1.0]
+ expr {$x * 1}
+} 1.0
+test execute-3.30 {TclExecuteByteCode, INST_MULT, op1 is non-numeric} {testobj} {
+ set x [teststringobj set 1 foo]
+ list [catch {expr {$x * 1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "*"}}
+test execute-3.31 {TclExecuteByteCode, INST_MULT, op2 is int} {testobj} {
+ set x [testintobj set 1 1]
+ expr {1 * $x}
+} 1
+test execute-3.32 {TclExecuteByteCode, INST_MULT, op2 is double} {testobj} {
+ set x [testdoubleobj set 1 2.0]
+ expr {1 * $x}
+} 2.0
+test execute-3.33 {TclExecuteByteCode, INST_MULT, op2 is double with string} {testobj} {
+ set x [testintobj set 1 2]
+ testobj convert 1 double
+ expr {1 * $x}
+} 2
+test execute-3.34 {TclExecuteByteCode, INST_MULT, op2 is string int} {testobj} {
+ set x [teststringobj set 1 1]
+ expr {1 * $x}
+} 1
+test execute-3.35 {TclExecuteByteCode, INST_MULT, op2 is string double} {testobj} {
+ set x [teststringobj set 1 1.0]
+ expr {1 * $x}
+} 1.0
+test execute-3.36 {TclExecuteByteCode, INST_MULT, op2 is non-numeric} {testobj} {
+ set x [teststringobj set 1 foo]
+ list [catch {expr {1 * $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "*"}}
+
+# INST_DIV is partially tested:
+test execute-3.37 {TclExecuteByteCode, INST_DIV, op1 is int} {testobj} {
+ set x [testintobj set 1 1]
+ expr {$x / 1}
+} 1
+test execute-3.38 {TclExecuteByteCode, INST_DIV, op1 is double} {testobj} {
+ set x [testdoubleobj set 1 2.0]
+ expr {$x / 1}
+} 2.0
+test execute-3.39 {TclExecuteByteCode, INST_DIV, op1 is double with string} {testobj} {
+ set x [testintobj set 1 2]
+ testobj convert 1 double
+ expr {$x / 1}
+} 2
+test execute-3.40 {TclExecuteByteCode, INST_DIV, op1 is string int} {testobj} {
+ set x [teststringobj set 1 1]
+ expr {$x / 1}
+} 1
+test execute-3.41 {TclExecuteByteCode, INST_DIV, op1 is string double} {testobj} {
+ set x [teststringobj set 1 1.0]
+ expr {$x / 1}
+} 1.0
+test execute-3.42 {TclExecuteByteCode, INST_DIV, op1 is non-numeric} {testobj} {
+ set x [teststringobj set 1 foo]
+ list [catch {expr {$x / 1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+test execute-3.43 {TclExecuteByteCode, INST_DIV, op2 is int} {testobj} {
+ set x [testintobj set 1 1]
+ expr {2 / $x}
+} 2
+test execute-3.44 {TclExecuteByteCode, INST_DIV, op2 is double} {testobj} {
+ set x [testdoubleobj set 1 1.0]
+ expr {2 / $x}
+} 2.0
+test execute-3.45 {TclExecuteByteCode, INST_DIV, op2 is double with string} {testobj} {
+ set x [testintobj set 1 1]
+ testobj convert 1 double
+ expr {2 / $x}
+} 2
+test execute-3.46 {TclExecuteByteCode, INST_DIV, op2 is string int} {testobj} {
+ set x [teststringobj set 1 1]
+ expr {2 / $x}
+} 2
+test execute-3.47 {TclExecuteByteCode, INST_DIV, op2 is string double} {testobj} {
+ set x [teststringobj set 1 1.0]
+ expr {2 / $x}
+} 2.0
+test execute-3.48 {TclExecuteByteCode, INST_DIV, op2 is non-numeric} {testobj} {
+ set x [teststringobj set 1 foo]
+ list [catch {expr {1 / $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+
+# INST_UPLUS is partially tested:
+test execute-3.49 {TclExecuteByteCode, INST_UPLUS, op is int} {testobj} {
+ set x [testintobj set 1 1]
+ expr {+ $x}
+} 1
+test execute-3.50 {TclExecuteByteCode, INST_UPLUS, op is double} {testobj} {
+ set x [testdoubleobj set 1 1.0]
+ expr {+ $x}
+} 1.0
+test execute-3.51 {TclExecuteByteCode, INST_UPLUS, op is double with string} {testobj} {
+ set x [testintobj set 1 1]
+ testobj convert 1 double
+ expr {+ $x}
+} 1
+test execute-3.52 {TclExecuteByteCode, INST_UPLUS, op is string int} {testobj} {
+ set x [teststringobj set 1 1]
+ expr {+ $x}
+} 1
+test execute-3.53 {TclExecuteByteCode, INST_UPLUS, op is string double} {testobj} {
+ set x [teststringobj set 1 1.0]
+ expr {+ $x}
+} 1.0
+test execute-3.54 {TclExecuteByteCode, INST_UPLUS, op is non-numeric} {testobj} {
+ set x [teststringobj set 1 foo]
+ list [catch {expr {+ $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+
+# INST_UMINUS is partially tested:
+test execute-3.55 {TclExecuteByteCode, INST_UMINUS, op is int} {testobj} {
+ set x [testintobj set 1 1]
+ expr {- $x}
+} -1
+test execute-3.56 {TclExecuteByteCode, INST_UMINUS, op is double} {testobj} {
+ set x [testdoubleobj set 1 1.0]
+ expr {- $x}
+} -1.0
+test execute-3.57 {TclExecuteByteCode, INST_UMINUS, op is double with string} {testobj} {
+ set x [testintobj set 1 1]
+ testobj convert 1 double
+ expr {- $x}
+} -1
+test execute-3.58 {TclExecuteByteCode, INST_UMINUS, op is string int} {testobj} {
+ set x [teststringobj set 1 1]
+ expr {- $x}
+} -1
+test execute-3.59 {TclExecuteByteCode, INST_UMINUS, op is string double} {testobj} {
+ set x [teststringobj set 1 1.0]
+ expr {- $x}
+} -1.0
+test execute-3.60 {TclExecuteByteCode, INST_UMINUS, op is non-numeric} {testobj} {
+ set x [teststringobj set 1 foo]
+ list [catch {expr {- $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+
+# INST_LNOT is partially tested:
+test execute-3.61 {TclExecuteByteCode, INST_LNOT, op is int} {testobj} {
+ set x [testintobj set 1 2]
+ expr {! $x}
+} 0
+test execute-3.62 {TclExecuteByteCode, INST_LNOT, op is int} {testobj} {
+ set x [testintobj set 1 0]
+ expr {! $x}
+} 1
+test execute-3.63 {TclExecuteByteCode, INST_LNOT, op is double} {testobj} {
+ set x [testdoubleobj set 1 1.0]
+ expr {! $x}
+} 0
+test execute-3.64 {TclExecuteByteCode, INST_LNOT, op is double} {testobj} {
+ set x [testdoubleobj set 1 0.0]
+ expr {! $x}
+} 1
+test execute-3.65 {TclExecuteByteCode, INST_LNOT, op is double with string} {testobj} {
+ set x [testintobj set 1 1]
+ testobj convert 1 double
+ expr {! $x}
+} 0
+test execute-3.66 {TclExecuteByteCode, INST_LNOT, op is double with string} {testobj} {
+ set x [testintobj set 1 0]
+ testobj convert 1 double
+ expr {! $x}
+} 1
+test execute-3.67 {TclExecuteByteCode, INST_LNOT, op is string int} {testobj} {
+ set x [teststringobj set 1 1]
+ expr {! $x}
+} 0
+test execute-3.68 {TclExecuteByteCode, INST_LNOT, op is string int} {testobj} {
+ set x [teststringobj set 1 0]
+ expr {! $x}
+} 1
+test execute-3.69 {TclExecuteByteCode, INST_LNOT, op is string double} {testobj} {
+ set x [teststringobj set 1 1.0]
+ expr {! $x}
+} 0
+test execute-3.70 {TclExecuteByteCode, INST_LNOT, op is string double} {testobj} {
+ set x [teststringobj set 1 0.0]
+ expr {! $x}
+} 1
+test execute-3.71 {TclExecuteByteCode, INST_LNOT, op is non-numeric} {testobj} {
+ set x [teststringobj set 1 foo]
+ list [catch {expr {! $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "!"}}
+
+# INST_BITNOT not tested
+# INST_CALL_BUILTIN_FUNC1 not tested
+# INST_CALL_FUNC1 not tested
+
+# INST_TRY_CVT_TO_NUMERIC is partially tested:
+test execute-3.72 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is int} {testobj} {
+ set x [testintobj set 1 1]
+ expr {$x}
+} 1
+test execute-3.73 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is double} {testobj} {
+ set x [testdoubleobj set 1 1.0]
+ expr {$x}
+} 1.0
+test execute-3.74 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is double with string} {testobj} {
+ set x [testintobj set 1 1]
+ testobj convert 1 double
+ expr {$x}
+} 1
+test execute-3.75 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is string int} {testobj} {
+ set x [teststringobj set 1 1]
+ expr {$x}
+} 1
+test execute-3.76 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is string double} {testobj} {
+ set x [teststringobj set 1 1.0]
+ expr {$x}
+} 1.0
+test execute-3.77 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is non-numeric} {testobj} {
+ set x [teststringobj set 1 foo]
+ expr {$x}
+} foo
+
+# INST_BREAK not tested
+# INST_CONTINUE not tested
+# INST_FOREACH_START4 not tested
+# INST_FOREACH_STEP4 not tested
+# INST_BEGIN_CATCH4 not tested
+# INST_END_CATCH not tested
+# INST_PUSH_RESULT not tested
+# INST_PUSH_RETURN_CODE not tested
+
+test execute-4.1 {Tcl_GetCommandFromObj, convert to tclCmdNameType} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ unset -nocomplain x
+ unset -nocomplain y
+} -body {
+ namespace eval test_ns_1 {
+ namespace export cmd1
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ }
+ namespace eval test_ns_1::test_ns_2 {
+ namespace import ::test_ns_1::*
+ }
+ set x "test_ns_1::"
+ set y "test_ns_2::"
+ list [namespace which -command ${x}${y}cmd1] \
+ [catch {namespace which -command ${x}${y}cmd2} msg] $msg \
+ [catch {namespace which -command ${x}${y}:cmd2} msg] $msg
+} -result {::test_ns_1::test_ns_2::cmd1 0 {} 0 {}}
+test execute-4.2 {Tcl_GetCommandFromObj, check if cached tclCmdNameType is invalid} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename foo ""}
+ unset -nocomplain l
+} -body {
+ proc foo {} {
+ return "global foo"
+ }
+ namespace eval test_ns_1 {
+ proc whichFoo {} {
+ return [namespace which -command foo]
+ }
+ }
+ set l ""
+ lappend l [test_ns_1::whichFoo]
+ namespace eval test_ns_1 {
+ proc foo {} {
+ return "namespace foo"
+ }
+ }
+ lappend l [test_ns_1::whichFoo]
+} -result {::foo ::test_ns_1::foo}
+test execute-4.3 {Tcl_GetCommandFromObj, command never found} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename foo ""}
+} -body {
+ namespace eval test_ns_1 {
+ proc foo {} {
+ return "namespace foo"
+ }
+ }
+ namespace eval test_ns_1 {
+ proc foo {} {
+ return "namespace foo"
+ }
+ }
+ list [namespace eval test_ns_1 {namespace which -command foo}] \
+ [rename test_ns_1::foo ""] \
+ [catch {namespace eval test_ns_1 {namespace which -command foo}} msg] $msg
+} -result {::test_ns_1::foo {} 0 {}}
+
+test execute-5.1 {SetCmdNameFromAny, set cmd name to empty heap string if NULL} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ unset -nocomplain l
+} -body {
+ proc {} {} {return {}}
+ {}
+ set l {}
+ lindex {} 0
+ {}
+} -result {}
+
+test execute-6.1 {UpdateStringOfCmdName: called for duplicate of empty cmdName object} {
+ proc {} {} {}
+ proc { } {} {}
+ proc p {} {
+ set x {}
+ $x
+ append x { }
+ $x
+ }
+ p
+} {}
+test execute-6.2 {Evaluate an expression in a variable; compile the first time, do not the second} {
+ set w {3*5}
+ proc a {obj} {expr $obj}
+ set res "[a $w]:[a $w]"
+} {15:15}
+test execute-6.3 {Tcl_ExprObj: don't use cached script bytecode [Bug 1899164]} -setup {
+ proc 0+0 {} {return SCRIPT}
+} -body {
+ set e { 0+0 }
+ if 1 $e
+ if 1 {expr $e}
+} -cleanup {
+ rename 0+0 {}
+} -result 0
+test execute-6.4 {TclCompEvalObj: don't use cached expr bytecode [Bug 1899164]} -setup {
+ proc 0+0 {} {return SCRIPT}
+} -body {
+ set e { 0+0 }
+ if 1 {expr $e}
+ if 1 $e
+} -cleanup {
+ rename 0+0 {}
+} -result SCRIPT
+test execute-6.5 {TclCompEvalObj: bytecode epoch validation} -body {
+ set script { llength {} }
+ set result {}
+ lappend result [if 1 $script]
+ set origName [namespace which llength]
+ rename $origName llength.orig
+ proc $origName {args} {return AHA!}
+ lappend result [if 1 $script]
+} -cleanup {
+ rename $origName {}
+ rename llength.orig $origName
+} -result {0 AHA!}
+test execute-6.6 {TclCompEvalObj: proc-body bytecode invalid for script} -body {
+ proc foo {} {set a 1}
+ set a untouched
+ set result {}
+ lappend result [foo] $a
+ lappend result [if 1 [info body foo]] $a
+} -cleanup {
+ rename foo {}
+} -result {1 untouched 1 1}
+test execute-6.7 {TclCompEvalObj: bytecode context validation} -setup {
+ namespace eval foo {}
+} -body {
+ set script { llength {} }
+ namespace eval foo {
+ proc llength {args} {return AHA!}
+ }
+ set result {}
+ lappend result [if 1 $script]
+ lappend result [namespace eval foo $script]
+} -cleanup {
+ namespace delete foo
+} -result {0 AHA!}
+test execute-6.8 {TclCompEvalObj: bytecode name resolution epoch validation} -setup {
+ namespace eval foo {}
+} -body {
+ set script { llength {} }
+ set result {}
+ lappend result [namespace eval foo $script]
+ namespace eval foo {
+ proc llength {args} {return AHA!}
+ }
+ lappend result [namespace eval foo $script]
+} -cleanup {
+ namespace delete foo
+} -result {0 AHA!}
+test execute-6.9 {TclCompEvalObj: bytecode interp validation} -setup {
+ interp create slave
+} -body {
+ set script { llength {} }
+ slave eval {proc llength args {return AHA!}}
+ set result {}
+ lappend result [if 1 $script]
+ lappend result [slave eval $script]
+} -cleanup {
+ interp delete slave
+} -result {0 AHA!}
+test execute-6.10 {TclCompEvalObj: bytecode interp validation} -body {
+ set script { llength {} }
+ interp create slave
+ set result {}
+ lappend result [slave eval $script]
+ interp delete slave
+ interp create slave
+ lappend result [slave eval $script]
+} -cleanup {
+ catch {interp delete slave}
+} -result {0 0}
+test execute-6.11 {Tcl_ExprObj: exprcode interp validation} -setup {
+ interp create slave
+} -constraints testexprlongobj -body {
+ set e { [llength {}]+1 }
+ set result {}
+ load {} Tcltest slave
+ interp alias {} e slave testexprlongobj
+ lappend result [e $e]
+ interp delete slave
+ interp create slave
+ load {} Tcltest slave
+ interp alias {} e slave testexprlongobj
+ lappend result [e $e]
+} -cleanup {
+ interp delete slave
+} -result {{This is a result: 1} {This is a result: 1}}
+test execute-6.12 {Tcl_ExprObj: exprcode interp validation} -setup {
+ interp create slave
+} -body {
+ set e { [llength {}]+1 }
+ set result {}
+ interp alias {} e slave expr
+ lappend result [e $e]
+ interp delete slave
+ interp create slave
+ interp alias {} e slave expr
+ lappend result [e $e]
+} -cleanup {
+ interp delete slave
+} -result {1 1}
+test execute-6.13 {Tcl_ExprObj: exprcode epoch validation} -body {
+ set e { [llength {}]+1 }
+ set result {}
+ lappend result [expr $e]
+ set origName [namespace which llength]
+ rename $origName llength.orig
+ proc $origName {args} {return 1}
+ lappend result [expr $e]
+} -cleanup {
+ rename $origName {}
+ rename llength.orig $origName
+} -result {1 2}
+test execute-6.14 {Tcl_ExprObj: exprcode context validation} -setup {
+ namespace eval foo {}
+} -body {
+ set e { [llength {}]+1 }
+ namespace eval foo {
+ proc llength {args} {return 1}
+ }
+ set result {}
+ lappend result [expr $e]
+ lappend result [namespace eval foo {expr $e}]
+} -cleanup {
+ namespace delete foo
+} -result {1 2}
+test execute-6.15 {Tcl_ExprObj: exprcode name resolution epoch validation} -setup {
+ namespace eval foo {}
+} -body {
+ set e { [llength {}]+1 }
+ set result {}
+ lappend result [namespace eval foo {expr $e}]
+ namespace eval foo {
+ proc llength {args} {return 1}
+ }
+ lappend result [namespace eval foo {expr $e}]
+} -cleanup {
+ namespace delete foo
+} -result {1 2}
+test execute-6.16 {Tcl_ExprObj: exprcode interp validation} -setup {
+ interp create slave
+} -body {
+ set e { [llength {}]+1 }
+ interp alias {} e slave expr
+ slave eval {proc llength args {return 1}}
+ set result {}
+ lappend result [expr $e]
+ lappend result [e $e]
+} -cleanup {
+ interp delete slave
+} -result {1 2}
+test execute-6.17 {Tcl_ExprObj: exprcode context validation} -body {
+ proc foo e {set v 0; expr $e}
+ proc bar e {set v 1; expr $e}
+ set e { $v }
+ set result {}
+ lappend result [foo $e]
+ lappend result [bar $e]
+} -cleanup {
+ rename foo {}
+ rename bar {}
+} -result {0 1}
+test execute-6.18 {Tcl_ExprObj: exprcode context validation} -body {
+ proc foo e {set v {}; expr $e}
+ proc bar e {set v v; expr $e}
+ set e { [llength $v] }
+ set result {}
+ lappend result [foo $e]
+ lappend result [bar $e]
+} -cleanup {
+ rename foo {}
+ rename bar {}
+} -result {0 1}
+
+test execute-7.0 {Wide int handling in INST_JUMP_FALSE/LAND} {
+ set x 0x100000000
+ expr {$x && 1}
+} 1
+test execute-7.1 {Wide int handling in INST_JUMP_FALSE/LAND} {
+ expr {0x100000000 && 1}
+} 1
+test execute-7.2 {Wide int handling in INST_JUMP_FALSE/LAND} {
+ expr {1 && 0x100000000}
+} 1
+test execute-7.3 {Wide int handling in INST_JUMP_FALSE/LAND} {
+ expr {wide(0x100000000) && 1}
+} 1
+test execute-7.4 {Wide int handling in INST_JUMP_FALSE/LAND} {
+ expr {1 && wide(0x100000000)}
+} 1
+test execute-7.5 {Wide int handling in INST_EQ} {
+ expr {4 == (wide(1)+wide(3))}
+} 1
+test execute-7.6 {Wide int handling in INST_EQ and [incr]} {
+ set x 399999999999
+ expr {400000000000 == [incr x]}
+} 1
+# wide ints have more bits of precision than doubles, but we convert anyway
+test execute-7.7 {Wide int handling in INST_EQ and [incr]} {
+ set x [expr {wide(1)<<62}]
+ set y [expr {$x+1}]
+ expr {double($x) == double($y)}
+} 1
+test execute-7.8 {Wide int conversions can change sign} longIs32bit {
+ set x 0x80000000
+ expr {int($x) < wide($x)}
+} 1
+test execute-7.9 {Wide int handling in INST_MOD} {
+ expr {(wide(1)<<60) % ((wide(47)<<45)-1)}
+} 316659348800185
+test execute-7.10 {Wide int handling in INST_MOD} {
+ expr {((wide(1)<<60)-1) % 0x400000000}
+} 17179869183
+test execute-7.11 {Wide int handling in INST_LSHIFT} {
+ expr wide(42)<<30
+} 45097156608
+test execute-7.12 {Wide int handling in INST_LSHIFT} {
+ expr 12345678901<<3
+} 98765431208
+test execute-7.13 {Wide int handling in INST_RSHIFT} {
+ expr 0x543210febcda9876>>7
+} 47397893236700464
+test execute-7.14 {Wide int handling in INST_RSHIFT} {
+ expr wide(0x9876543210febcda)>>7
+} -58286587177206407
+test execute-7.15 {Wide int handling in INST_BITOR} {
+ expr wide(0x9876543210febcda) | 0x543210febcda9876
+} -2560765885044310786
+test execute-7.16 {Wide int handling in INST_BITXOR} {
+ expr wide(0x9876543210febcda) ^ 0x543210febcda9876
+} -3727778945703861076
+test execute-7.17 {Wide int handling in INST_BITAND} {
+ expr wide(0x9876543210febcda) & 0x543210febcda9876
+} 1167013060659550290
+test execute-7.18 {Wide int handling in INST_ADD} {
+ expr wide(0x7fffffff)+wide(0x7fffffff)
+} 4294967294
+test execute-7.19 {Wide int handling in INST_ADD} {
+ expr 0x7fffffff+wide(0x7fffffff)
+} 4294967294
+test execute-7.20 {Wide int handling in INST_ADD} {
+ expr wide(0x7fffffff)+0x7fffffff
+} 4294967294
+test execute-7.21 {Wide int handling in INST_ADD} {
+ expr double(0x7fffffff)+wide(0x7fffffff)
+} 4294967294.0
+test execute-7.22 {Wide int handling in INST_ADD} {
+ expr wide(0x7fffffff)+double(0x7fffffff)
+} 4294967294.0
+test execute-7.23 {Wide int handling in INST_SUB} {
+ expr 0x123456789a-0x20406080a
+} 69530054800
+test execute-7.24 {Wide int handling in INST_MULT} {
+ expr 0x123456789a*193
+} 15090186251290
+test execute-7.25 {Wide int handling in INST_DIV} {
+ expr 0x123456789a/193
+} 405116546
+test execute-7.26 {Wide int handling in INST_UPLUS} {
+ set x 0x123456871234568
+ expr {+ $x}
+} 81985533099853160
+test execute-7.27 {Wide int handling in INST_UMINUS} {
+ set x 0x123456871234568
+ expr {- $x}
+} -81985533099853160
+test execute-7.28 {Wide int handling in INST_LNOT} {
+ set x 0x123456871234568
+ expr {! $x}
+} 0
+test execute-7.29 {Wide int handling in INST_BITNOT} {
+ set x 0x123456871234568
+ expr {~ $x}
+} -81985533099853161
+test execute-7.30 {Wide int handling in function call} {
+ set x 0x12345687123456
+ incr x
+ expr {log($x) == log(double($x))}
+} 1
+test execute-7.31 {Wide int handling in abs()} {
+ set x 0xa23456871234568
+ incr x
+ set y 0x123456871234568
+ concat [expr {abs($x)}] [expr {abs($y)}]
+} {730503879441204585 81985533099853160}
+test execute-7.32 {Wide int handling} longIs32bit {
+ expr {int(1024 * 1024 * 1024 * 1024)}
+} 0
+test execute-7.33 {Wide int handling} longIs32bit {
+ expr {int(0x1 * 1024 * 1024 * 1024 * 1024)}
+} 0
+test execute-7.34 {Wide int handling} {
+ expr {wide(0x1) * 1024 * 1024 * 1024 * 1024}
+} 1099511627776
+
+test execute-8.1 {Stack protection} -setup {
+ # If [Bug #804681] has not been properly taken care of, this should
+ # segfault
+ proc whatever args {llength $args}
+ trace add variable ::errorInfo {write unset} whatever
+} -body {
+ expr {1+9/0}
+} -cleanup {
+ trace remove variable ::errorInfo {write unset} whatever
+ rename whatever {}
+} -returnCodes error -match glob -result *
+test execute-8.2 {Stack restoration} -setup {
+ # Avoid crashes when system stack size is limited (thread-enabled!)
+ set limit [interp recursionlimit {}]
+ interp recursionlimit {} 100
+} -body {
+ # Test for [Bug #816641], correct restoration of the stack top after the
+ # stack is grown
+ proc f {args} { f bee bop }
+ catch f msg
+ set msg
+} -cleanup {
+ interp recursionlimit {} $limit
+} -result {too many nested evaluations (infinite loop?)}
+test execute-8.3 {Stack restoration} -setup {
+ # Avoid crashes when system stack size is limited (thread-enabled!)
+ set limit [interp recursionlimit {}]
+ interp recursionlimit {} 100
+} -body {
+ # Test for [Bug #1055676], correct restoration of the stack top after the
+ # epoch is bumped and the stack is grown in a call from a nested
+ # evaluation
+ set arglst [string repeat "a " 1000]
+ proc f {args} "f $arglst"
+ proc run {} {
+ # bump the interp's epoch
+ rename ::set ::dummy
+ rename ::dummy ::set
+ catch f msg
+ set msg
+ }
+ run
+} -cleanup {
+ interp recursionlimit {} $limit
+} -result {too many nested evaluations (infinite loop?)}
+test execute-8.4 {Compile epoch bump effect on stack trace} -setup {
+ proc foo {} {
+ error bar
+ }
+ proc FOO {} {
+ catch {error bar} m o
+ rename ::set ::dummy
+ rename ::dummy ::set
+ return -options $o $m
+ }
+} -body {
+ catch foo m o
+ set stack1 [dict get $o -errorinfo]
+ catch FOO m o
+ set stack2 [string map {FOO foo} [dict get $o -errorinfo]]
+ expr {$stack1 eq $stack2 ? {} : "These differ:\n$stack1\n$stack2"}
+} -cleanup {
+ rename foo {}
+ rename FOO {}
+ unset -nocomplain m o stack1 stack2
+} -result {}
+test execute-8.5 {Bug 2038069} -setup {
+ proc demo {} {
+ catch [list error FOO] m o
+ return $o
+ }
+} -body {
+ demo
+} -cleanup {
+ rename demo {}
+} -match glob -result {-code 1 -level 0 -errorstack * -errorcode NONE -errorinfo {FOO
+ while executing
+"error FOO"
+ invoked from within
+"catch \[list error FOO\] m o"} -errorline 2}
+
+test execute-9.1 {Interp result resetting [Bug 1522803]} {
+ set c 0
+ catch {
+ catch {set foo}
+ expr {1/$c}
+ }
+ if {[string match *foo* $::errorInfo]} {
+ set result "Bad errorInfo: $::errorInfo"
+ } else {
+ set result SUCCESS
+ }
+ set result
+} SUCCESS
+
+test execute-10.1 {TclExecuteByteCode, INST_CONCAT1, bytearrays} {
+ apply {s {binary scan $s c x; list $x [scan $s$s %c%c]}} \u0130
+} {48 {304 304}}
+test execute-10.2 {Bug 2802881} -setup {
+ interp create slave
+} -body {
+ # If [Bug 2802881] is not fixed, this will segfault
+ slave eval {
+ trace add variable ::errorInfo write {expr {$foo} ;#}
+ proc demo {} {a {}{}}
+ demo
+ }
+} -cleanup {
+ interp delete slave
+} -returnCodes error -match glob -result *
+test execute-10.3 {Bug 3072640} -setup {
+ proc generate {n} {
+ for {set i 0} {$i < $n} {incr i} {
+ yield $i
+ }
+ }
+ proc t {args} {
+ incr ::foo
+ }
+ trace add execution ::generate enterstep ::t
+} -body {
+ coroutine coro generate 5
+ trace remove execution ::generate enterstep ::t
+ set ::foo
+} -cleanup {
+ unset ::foo
+ rename generate {}
+ rename t {}
+ rename coro {}
+} -result 4
+
+test execute-11.1 {Bug 3142026: GrowEvaluationStack off-by-one} -setup {
+ interp create slave
+} -body {
+ slave eval {
+ set x [lrepeat 1320 199]
+ for {set i 0} {$i < 20} {incr i} {
+ lappend x $i
+ lsort -integer $x
+ }
+ # Crashes on failure
+ return ok
+ }
+} -cleanup {
+ interp delete slave
+} -result ok
+
+# cleanup
+if {[info commands testobj] != {}} {
+ testobj freeallvars
+}
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+catch {rename foo ""}
+catch {rename p ""}
+catch {rename {} ""}
+catch {rename { } ""}
+catch {unset x}
+catch {unset y}
+catch {unset msg}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/expr-old.test b/library/msgcat/tests/expr-old.test
new file mode 100644
index 0000000..c05a925
--- /dev/null
+++ b/library/msgcat/tests/expr-old.test
@@ -0,0 +1,1207 @@
+# Commands covered: expr
+#
+# This file contains the original set of tests for Tcl's expr command.
+# Since the expr command is now compiled, a new set of tests covering
+# the new implementation are in the files "parseExpr.test" and
+# "compExpr.test". Sourcing this file into Tcl runs the tests and generates
+# output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2.1
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testexprlong [llength [info commands testexprlong]]
+testConstraint testexprdouble [llength [info commands testexprdouble]]
+testConstraint testexprstring [llength [info commands testexprstring]]
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+
+if {[catch {expr T1()} msg] && $msg eq {invalid command name "tcl::mathfunc::T1"}} {
+ testConstraint testmathfunctions 0
+} else {
+ testConstraint testmathfunctions 1
+}
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+ variable ieeeValues
+ binary scan [binary format dd -1.0 1.0] c* c
+ switch -exact -- $c {
+ {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+ # little endian
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+ ieeeValues(-Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+ ieeeValues(-Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+ ieeeValues(-Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+ ieeeValues(+Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+ ieeeValues(+Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 1
+ return 1
+ }
+ {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+ binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Infinity)
+ binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Normal)
+ binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Subnormal)
+ binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Normal)
+ binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Infinity)
+ binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 0
+ return 1
+ }
+ default {
+ return 0
+ }
+ }
+}
+testConstraint ieeeFloatingPoint [testIEEE]
+
+# First, test all of the integer operators individually.
+
+test expr-old-1.1 {integer operators} {expr -4} -4
+test expr-old-1.2 {integer operators} {expr -(1+4)} -5
+test expr-old-1.3 {integer operators} {expr ~3} -4
+test expr-old-1.4 {integer operators} {expr !2} 0
+test expr-old-1.5 {integer operators} {expr !0} 1
+test expr-old-1.6 {integer operators} {expr 4*6} 24
+test expr-old-1.7 {integer operators} {expr 36/12} 3
+test expr-old-1.8 {integer operators} {expr 27/4} 6
+test expr-old-1.9 {integer operators} {expr 27%4} 3
+test expr-old-1.10 {integer operators} {expr 2+2} 4
+test expr-old-1.11 {integer operators} {expr 2-6} -4
+test expr-old-1.12 {integer operators} {expr 1<<3} 8
+test expr-old-1.13 {integer operators} {expr 0xff>>2} 63
+test expr-old-1.14 {integer operators} {expr -1>>2} -1
+test expr-old-1.15 {integer operators} {expr 3>2} 1
+test expr-old-1.16 {integer operators} {expr 2>2} 0
+test expr-old-1.17 {integer operators} {expr 1>2} 0
+test expr-old-1.18 {integer operators} {expr 3<2} 0
+test expr-old-1.19 {integer operators} {expr 2<2} 0
+test expr-old-1.20 {integer operators} {expr 1<2} 1
+test expr-old-1.21 {integer operators} {expr 3>=2} 1
+test expr-old-1.22 {integer operators} {expr 2>=2} 1
+test expr-old-1.23 {integer operators} {expr 1>=2} 0
+test expr-old-1.24 {integer operators} {expr 3<=2} 0
+test expr-old-1.25 {integer operators} {expr 2<=2} 1
+test expr-old-1.26 {integer operators} {expr 1<=2} 1
+test expr-old-1.27 {integer operators} {expr 3==2} 0
+test expr-old-1.28 {integer operators} {expr 2==2} 1
+test expr-old-1.29 {integer operators} {expr 3!=2} 1
+test expr-old-1.30 {integer operators} {expr 2!=2} 0
+test expr-old-1.31 {integer operators} {expr 7&0x13} 3
+test expr-old-1.32 {integer operators} {expr 7^0x13} 20
+test expr-old-1.33 {integer operators} {expr 7|0x13} 23
+test expr-old-1.34 {integer operators} {expr 0&&1} 0
+test expr-old-1.35 {integer operators} {expr 0&&0} 0
+test expr-old-1.36 {integer operators} {expr 1&&3} 1
+test expr-old-1.37 {integer operators} {expr 0||1} 1
+test expr-old-1.38 {integer operators} {expr 3||0} 1
+test expr-old-1.39 {integer operators} {expr 0||0} 0
+test expr-old-1.40 {integer operators} {expr 3>2?44:66} 44
+test expr-old-1.41 {integer operators} {expr 2>3?44:66} 66
+test expr-old-1.42 {integer operators} {expr 36/5} 7
+test expr-old-1.43 {integer operators} {expr 36%5} 1
+test expr-old-1.44 {integer operators} {expr -36/5} -8
+test expr-old-1.45 {integer operators} {expr -36%5} 4
+test expr-old-1.46 {integer operators} {expr 36/-5} -8
+test expr-old-1.47 {integer operators} {expr 36%-5} -4
+test expr-old-1.48 {integer operators} {expr -36/-5} 7
+test expr-old-1.49 {integer operators} {expr -36%-5} -1
+test expr-old-1.50 {integer operators} {expr +36} 36
+test expr-old-1.51 {integer operators} {expr +--++36} 36
+test expr-old-1.52 {integer operators} {expr +36%+5} 1
+test expr-old-1.53 {integer operators} {
+ catch {unset x}
+ set x yes
+ list [expr {1 && $x}] [expr {$x && 1}] \
+ [expr {0 || $x}] [expr {$x || 0}]
+} {1 1 1 1}
+
+# Check the floating-point operators individually, along with
+# automatic conversion to integers where needed.
+
+test expr-old-2.1 {floating-point operators} {expr -4.2} -4.2
+test expr-old-2.2 {floating-point operators} {expr -(1.125+4.25)} -5.375
+test expr-old-2.3 {floating-point operators} {expr +5.7} 5.7
+test expr-old-2.4 {floating-point operators} {expr +--+-62.0} -62.0
+test expr-old-2.5 {floating-point operators} {expr !2.1} 0
+test expr-old-2.6 {floating-point operators} {expr !0.0} 1
+test expr-old-2.7 {floating-point operators} {expr 4.2*6.3} 26.46
+test expr-old-2.8 {floating-point operators} {expr 36.0/12.0} 3.0
+test expr-old-2.9 {floating-point operators} {expr 27/4.0} 6.75
+test expr-old-2.10 {floating-point operators} {expr 2.3+2.1} 4.4
+test expr-old-2.11 {floating-point operators} {expr 2.3-6.5} -4.2
+test expr-old-2.12 {floating-point operators} {expr 3.1>2.1} 1
+test expr-old-2.13 {floating-point operators} {expr {2.1 > 2.1}} 0
+test expr-old-2.14 {floating-point operators} {expr 1.23>2.34e+1} 0
+test expr-old-2.15 {floating-point operators} {expr 3.45<2.34} 0
+test expr-old-2.16 {floating-point operators} {expr 0.002e3<--200e-2} 0
+test expr-old-2.17 {floating-point operators} {expr 1.1<2.1} 1
+test expr-old-2.18 {floating-point operators} {expr 3.1>=2.2} 1
+test expr-old-2.19 {floating-point operators} {expr 2.345>=2.345} 1
+test expr-old-2.20 {floating-point operators} {expr 1.1>=2.2} 0
+test expr-old-2.21 {floating-point operators} {expr 3.0<=2.0} 0
+test expr-old-2.22 {floating-point operators} {expr 2.2<=2.2} 1
+test expr-old-2.23 {floating-point operators} {expr 2.2<=2.2001} 1
+test expr-old-2.24 {floating-point operators} {expr 3.2==2.2} 0
+test expr-old-2.25 {floating-point operators} {expr 2.2==2.2} 1
+test expr-old-2.26 {floating-point operators} {expr 3.2!=2.2} 1
+test expr-old-2.27 {floating-point operators} {expr 2.2!=2.2} 0
+test expr-old-2.28 {floating-point operators} {expr 0.0&&0.0} 0
+test expr-old-2.29 {floating-point operators} {expr 0.0&&1.3} 0
+test expr-old-2.30 {floating-point operators} {expr 1.3&&0.0} 0
+test expr-old-2.31 {floating-point operators} {expr 1.3&&3.3} 1
+test expr-old-2.32 {floating-point operators} {expr 0.0||0.0} 0
+test expr-old-2.33 {floating-point operators} {expr 0.0||1.3} 1
+test expr-old-2.34 {floating-point operators} {expr 1.3||0.0} 1
+test expr-old-2.35 {floating-point operators} {expr 3.3||0.0} 1
+test expr-old-2.36 {floating-point operators} {expr 3.3>2.3?44.3:66.3} 44.3
+test expr-old-2.37 {floating-point operators} {expr 2.3>3.3?44.3:66.3} 66.3
+test expr-old-2.38 {floating-point operators} {
+ list [catch {expr 028.1 + 09.2} msg] $msg
+} {0 37.3}
+
+# Operators that aren't legal on floating-point numbers
+
+test expr-old-3.1 {illegal floating-point operations} {
+ list [catch {expr ~4.0} msg] $msg
+} {1 {can't use floating-point value as operand of "~"}}
+test expr-old-3.2 {illegal floating-point operations} {
+ list [catch {expr 27%4.0} msg] $msg
+} {1 {can't use floating-point value as operand of "%"}}
+test expr-old-3.3 {illegal floating-point operations} {
+ list [catch {expr 27.0%4} msg] $msg
+} {1 {can't use floating-point value as operand of "%"}}
+test expr-old-3.4 {illegal floating-point operations} {
+ list [catch {expr 1.0<<3} msg] $msg
+} {1 {can't use floating-point value as operand of "<<"}}
+test expr-old-3.5 {illegal floating-point operations} {
+ list [catch {expr 3<<1.0} msg] $msg
+} {1 {can't use floating-point value as operand of "<<"}}
+test expr-old-3.6 {illegal floating-point operations} {
+ list [catch {expr 24.0>>3} msg] $msg
+} {1 {can't use floating-point value as operand of ">>"}}
+test expr-old-3.7 {illegal floating-point operations} {
+ list [catch {expr 24>>3.0} msg] $msg
+} {1 {can't use floating-point value as operand of ">>"}}
+test expr-old-3.8 {illegal floating-point operations} {
+ list [catch {expr 24&3.0} msg] $msg
+} {1 {can't use floating-point value as operand of "&"}}
+test expr-old-3.9 {illegal floating-point operations} {
+ list [catch {expr 24.0|3} msg] $msg
+} {1 {can't use floating-point value as operand of "|"}}
+test expr-old-3.10 {illegal floating-point operations} {
+ list [catch {expr 24.0^3} msg] $msg
+} {1 {can't use floating-point value as operand of "^"}}
+
+# Check the string operators individually.
+
+test expr-old-4.1 {string operators} {expr {"abc" > "def"}} 0
+test expr-old-4.2 {string operators} {expr {"def" > "def"}} 0
+test expr-old-4.3 {string operators} {expr {"g" > "def"}} 1
+test expr-old-4.4 {string operators} {expr {"abc" < "abd"}} 1
+test expr-old-4.5 {string operators} {expr {"abd" < "abd"}} 0
+test expr-old-4.6 {string operators} {expr {"abe" < "abd"}} 0
+test expr-old-4.7 {string operators} {expr {"abc" >= "def"}} 0
+test expr-old-4.8 {string operators} {expr {"def" >= "def"}} 1
+test expr-old-4.9 {string operators} {expr {"g" >= "def"}} 1
+test expr-old-4.10 {string operators} {expr {"abc" <= "abd"}} 1
+test expr-old-4.11 {string operators} {expr {"abd" <= "abd"}} 1
+test expr-old-4.12 {string operators} {expr {"abe" <= "abd"}} 0
+test expr-old-4.13 {string operators} {expr {"abc" == "abd"}} 0
+test expr-old-4.14 {string operators} {expr {"abd" == "abd"}} 1
+test expr-old-4.15 {string operators} {expr {"abc" != "abd"}} 1
+test expr-old-4.16 {string operators} {expr {"abd" != "abd"}} 0
+test expr-old-4.17 {string operators} {expr {"0y" < "0x12"}} 0
+test expr-old-4.18 {string operators} {expr {"." < " "}} 0
+test expr-old-4.19 {string operators} {expr {"abc" eq "abd"}} 0
+test expr-old-4.20 {string operators} {expr {"abd" eq "abd"}} 1
+test expr-old-4.21 {string operators} {expr {"abc" ne "abd"}} 1
+test expr-old-4.22 {string operators} {expr {"abd" ne "abd"}} 0
+test expr-old-4.23 {string operators} {expr {"" eq "abd"}} 0
+test expr-old-4.24 {string operators} {expr {"" eq ""}} 1
+test expr-old-4.25 {string operators} {expr {"abd" ne ""}} 1
+test expr-old-4.26 {string operators} {expr {"" ne ""}} 0
+test expr-old-4.27 {string operators} {expr {"longerstring" eq "shorter"}} 0
+test expr-old-4.28 {string operators} {expr {"longerstring" ne "shorter"}} 1
+test expr-old-4.29 {string operators} {expr {"0" == "+"}} 0
+test expr-old-4.30 {string operators} {expr {"0" == "-"}} 0
+test expr-old-4.31 {string operators} {expr {1?"foo":"bar"}} foo
+test expr-old-4.32 {string operators} {expr {0?"foo":"bar"}} bar
+
+# Operators that aren't legal on string operands.
+
+test expr-old-5.1 {illegal string operations} {
+ list [catch {expr {-"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+test expr-old-5.2 {illegal string operations} {
+ list [catch {expr {+"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-5.3 {illegal string operations} {
+ list [catch {expr {~"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "~"}}
+test expr-old-5.4 {illegal string operations} {
+ list [catch {expr {!"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-old-5.5 {illegal string operations} {
+ list [catch {expr {"a"*"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "*"}}
+test expr-old-5.6 {illegal string operations} {
+ list [catch {expr {"a"/"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+test expr-old-5.7 {illegal string operations} {
+ list [catch {expr {"a"%"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "%"}}
+test expr-old-5.8 {illegal string operations} {
+ list [catch {expr {"a"+"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-5.9 {illegal string operations} {
+ list [catch {expr {"a"-"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+test expr-old-5.10 {illegal string operations} {
+ list [catch {expr {"a"<<"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "<<"}}
+test expr-old-5.11 {illegal string operations} {
+ list [catch {expr {"a">>"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of ">>"}}
+test expr-old-5.12 {illegal string operations} {
+ list [catch {expr {"a"&"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "&"}}
+test expr-old-5.13 {illegal string operations} {
+ list [catch {expr {"a"^"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "^"}}
+test expr-old-5.14 {illegal string operations} {
+ list [catch {expr {"a"|"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "|"}}
+test expr-old-5.15 {illegal string operations} {
+ list [catch {expr {"a"&&"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test expr-old-5.16 {illegal string operations} {
+ list [catch {expr {"a"||"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test expr-old-5.17 {illegal string operations} {
+ list [catch {expr {"a"?4:2}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+
+# Check precedence pairwise.
+
+test expr-old-6.1 {precedence checks} {expr -~3} 4
+test expr-old-6.2 {precedence checks} {expr -!3} 0
+test expr-old-6.3 {precedence checks} {expr -~0} 1
+
+test expr-old-7.1 {precedence checks} {expr 2*4/6} 1
+test expr-old-7.2 {precedence checks} {expr 24/6*3} 12
+test expr-old-7.3 {precedence checks} {expr 24/6/2} 2
+
+test expr-old-8.1 {precedence checks} {expr -2+4} 2
+test expr-old-8.2 {precedence checks} {expr -2-4} -6
+test expr-old-8.3 {precedence checks} {expr +2-4} -2
+
+test expr-old-9.1 {precedence checks} {expr 2*3+4} 10
+test expr-old-9.2 {precedence checks} {expr 8/2+4} 8
+test expr-old-9.3 {precedence checks} {expr 8%3+4} 6
+test expr-old-9.4 {precedence checks} {expr 2*3-1} 5
+test expr-old-9.5 {precedence checks} {expr 8/2-1} 3
+test expr-old-9.6 {precedence checks} {expr 8%3-1} 1
+
+test expr-old-10.1 {precedence checks} {expr 6-3-2} 1
+
+test expr-old-11.1 {precedence checks} {expr 7+1>>2} 2
+test expr-old-11.2 {precedence checks} {expr 7+1<<2} 32
+test expr-old-11.3 {precedence checks} {expr 7>>3-2} 3
+test expr-old-11.4 {precedence checks} {expr 7<<3-2} 14
+
+test expr-old-12.1 {precedence checks} {expr 6>>1>4} 0
+test expr-old-12.2 {precedence checks} {expr 6>>1<2} 0
+test expr-old-12.3 {precedence checks} {expr 6>>1>=3} 1
+test expr-old-12.4 {precedence checks} {expr 6>>1<=2} 0
+test expr-old-12.5 {precedence checks} {expr 6<<1>5} 1
+test expr-old-12.6 {precedence checks} {expr 6<<1<5} 0
+test expr-old-12.7 {precedence checks} {expr 5<=6<<1} 1
+test expr-old-12.8 {precedence checks} {expr 5>=6<<1} 0
+
+test expr-old-13.1 {precedence checks} {expr 2<3<4} 1
+test expr-old-13.2 {precedence checks} {expr 0<4>2} 0
+test expr-old-13.3 {precedence checks} {expr 4>2<1} 0
+test expr-old-13.4 {precedence checks} {expr 4>3>2} 0
+test expr-old-13.5 {precedence checks} {expr 4>3>=2} 0
+test expr-old-13.6 {precedence checks} {expr 4>=3>2} 0
+test expr-old-13.7 {precedence checks} {expr 4>=3>=2} 0
+test expr-old-13.8 {precedence checks} {expr 0<=4>=2} 0
+test expr-old-13.9 {precedence checks} {expr 4>=2<=0} 0
+test expr-old-13.10 {precedence checks} {expr 2<=3<=4} 1
+
+test expr-old-14.1 {precedence checks} {expr 1==4>3} 1
+test expr-old-14.2 {precedence checks} {expr 0!=4>3} 1
+test expr-old-14.3 {precedence checks} {expr 1==3<4} 1
+test expr-old-14.4 {precedence checks} {expr 0!=3<4} 1
+test expr-old-14.5 {precedence checks} {expr 1==4>=3} 1
+test expr-old-14.6 {precedence checks} {expr 0!=4>=3} 1
+test expr-old-14.7 {precedence checks} {expr 1==3<=4} 1
+test expr-old-14.8 {precedence checks} {expr 0!=3<=4} 1
+test expr-old-14.9 {precedence checks} {expr 1eq4>3} 1
+test expr-old-14.10 {precedence checks} {expr 0ne4>3} 1
+test expr-old-14.11 {precedence checks} {expr 1eq3<4} 1
+test expr-old-14.12 {precedence checks} {expr 0ne3<4} 1
+test expr-old-14.13 {precedence checks} {expr 1eq4>=3} 1
+test expr-old-14.14 {precedence checks} {expr 0ne4>=3} 1
+test expr-old-14.15 {precedence checks} {expr 1eq3<=4} 1
+test expr-old-14.16 {precedence checks} {expr 0ne3<=4} 1
+
+test expr-old-15.1 {precedence checks} {expr 1==3==3} 0
+test expr-old-15.2 {precedence checks} {expr 3==3!=2} 1
+test expr-old-15.3 {precedence checks} {expr 2!=3==3} 0
+test expr-old-15.4 {precedence checks} {expr 2!=1!=1} 0
+test expr-old-15.5 {precedence checks} {expr 1eq3eq3} 0
+test expr-old-15.6 {precedence checks} {expr 3eq3ne2} 1
+test expr-old-15.7 {precedence checks} {expr 2ne3eq3} 0
+test expr-old-15.8 {precedence checks} {expr 2ne1ne1} 0
+
+test expr-old-16.1 {precedence checks} {expr 2&3eq2} 0
+test expr-old-16.2 {precedence checks} {expr 1&3ne3} 0
+test expr-old-16.3 {precedence checks} {expr 2&3eq2} 0
+test expr-old-16.4 {precedence checks} {expr 1&3ne3} 0
+
+test expr-old-17.1 {precedence checks} {expr 7&3^0x10} 19
+test expr-old-17.2 {precedence checks} {expr 7^0x10&3} 7
+
+test expr-old-18.1 {precedence checks} {expr 7^0x10|3} 23
+test expr-old-18.2 {precedence checks} {expr 7|0x10^3} 23
+
+test expr-old-19.1 {precedence checks} {expr 7|3&&1} 1
+test expr-old-19.2 {precedence checks} {expr 1&&3|7} 1
+test expr-old-19.3 {precedence checks} {expr 0&&1||1} 1
+test expr-old-19.4 {precedence checks} {expr 1||1&&0} 1
+
+test expr-old-20.1 {precedence checks} {expr 1||0?3:4} 3
+test expr-old-20.2 {precedence checks} {expr 1?0:4||1} 0
+test expr-old-20.3 {precedence checks} {expr 1?2:0?3:4} 2
+test expr-old-20.4 {precedence checks} {expr 0?2:0?3:4} 4
+test expr-old-20.5 {precedence checks} {expr 1?2?3:4:0} 3
+test expr-old-20.6 {precedence checks} {expr 0?2?3:4:0} 0
+
+# Parentheses.
+
+test expr-old-21.1 {parenthesization} {expr (2+4)*6} 36
+test expr-old-21.2 {parenthesization} {expr (1?0:4)||1} 1
+test expr-old-21.3 {parenthesization} {expr +(3-4)} -1
+
+# Embedded commands and variable names.
+
+set a 16
+test expr-old-22.1 {embedded variables} {expr {2*$a}} 32
+test expr-old-22.2 {embedded variables} {
+ set x -5
+ set y 10
+ expr {$x + $y}
+} {5}
+test expr-old-22.3 {embedded variables} {
+ set x " -5"
+ set y " +10"
+ expr {$x + $y}
+} {5}
+test expr-old-22.4 {embedded commands and variables} {expr {[set a] - 14}} 2
+test expr-old-22.5 {embedded commands and variables} {
+ list [catch {expr {12 - [bad_command_name]}} msg] $msg
+} {1 {invalid command name "bad_command_name"}}
+
+# Double-quotes and things inside them.
+
+test expr-old-23.1 {double quotes} {expr {"abc"}} abc
+test expr-old-23.2 {double quotes} {
+ set a 189
+ expr {"$a.bc"}
+} 189.bc
+test expr-old-23.3 {double quotes} {
+ set b2 xyx
+ expr {"$b2$b2$b2.[set b2].[set b2]"}
+} xyxxyxxyx.xyx.xyx
+test expr-old-23.4 {double quotes} {expr {"11\}\}22"}} 11}}22
+test expr-old-23.5 {double quotes} {expr {"\*bc"}} {*bc}
+test expr-old-23.6 {double quotes} {
+ catch {unset bogus__}
+ list [catch {expr {"$bogus__"}} msg] $msg
+} {1 {can't read "bogus__": no such variable}}
+test expr-old-23.7 {double quotes} {
+ list [catch {expr {"a[error Testing]bc"}} msg] $msg
+} {1 Testing}
+test expr-old-23.8 {double quotes} {
+ list [catch {expr {"12398712938788234-1298379" != ""}} msg] $msg
+} {0 1}
+
+# Numbers in various bases.
+
+test expr-old-24.1 {numbers in different bases} {expr 0x20} 32
+test expr-old-24.2 {numbers in different bases} {expr 0o15} 13
+
+# Conversions between various data types.
+
+test expr-old-25.1 {type conversions} {expr 2+2.5} 4.5
+test expr-old-25.2 {type conversions} {expr 2.5+2} 4.5
+test expr-old-25.3 {type conversions} {expr 2-2.5} -0.5
+test expr-old-25.4 {type conversions} {expr 2/2.5} 0.8
+test expr-old-25.5 {type conversions} {expr 2>2.5} 0
+test expr-old-25.6 {type conversions} {expr 2.5>2} 1
+test expr-old-25.7 {type conversions} {expr 2<2.5} 1
+test expr-old-25.8 {type conversions} {expr 2>=2.5} 0
+test expr-old-25.9 {type conversions} {expr 2<=2.5} 1
+test expr-old-25.10 {type conversions} {expr 2==2.5} 0
+test expr-old-25.11 {type conversions} {expr 2!=2.5} 1
+test expr-old-25.12 {type conversions} {expr 2>"ab"} 0
+test expr-old-25.13 {type conversions} {expr {2>" "}} 1
+test expr-old-25.14 {type conversions} {expr {"24.1a" > 24.1}} 1
+test expr-old-25.15 {type conversions} {expr {24.1 > "24.1a"}} 0
+test expr-old-25.16 {type conversions} {expr 2+2.5} 4.5
+test expr-old-25.17 {type conversions} {expr 2+2.5} 4.5
+test expr-old-25.18 {type conversions} {expr 2.0e2} 200.0
+test expr-old-25.19 {type conversions} {expr 2.0e15} 2000000000000000.0
+test expr-old-25.20 {type conversions} {expr 10.0} 10.0
+
+# Various error conditions.
+
+test expr-old-26.1 {error conditions} {
+ list [catch {expr 2+"a"} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-26.2 {error conditions} -body {
+ expr 2+4*
+} -returnCodes error -match glob -result *
+test expr-old-26.3 {error conditions} -body {
+ expr 2+4*(
+} -returnCodes error -match glob -result *
+catch {unset _non_existent_}
+test expr-old-26.4 {error conditions} {
+ list [catch {expr 2+$_non_existent_} msg] $msg
+} {1 {can't read "_non_existent_": no such variable}}
+set a xx
+test expr-old-26.5 {error conditions} {
+ list [catch {expr {2+$a}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-26.6 {error conditions} {
+ list [catch {expr {2+[set a]}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-26.7 {error conditions} -body {
+ expr {2+(4}
+} -returnCodes error -match glob -result *
+test expr-old-26.8 {error conditions} {
+ list [catch {expr 2/0} msg] $msg $errorCode
+} {1 {divide by zero} {ARITH DIVZERO {divide by zero}}}
+test expr-old-26.9 {error conditions} {
+ list [catch {expr 2%0} msg] $msg $errorCode
+} {1 {divide by zero} {ARITH DIVZERO {divide by zero}}}
+test expr-old-26.10a {error conditions} !ieeeFloatingPoint {
+ list [catch {expr 2.0/0.0} msg] $msg $errorCode
+} {1 {divide by zero} {ARITH DIVZERO {divide by zero}}}
+test expr-old-26.10b {error conditions} ieeeFloatingPoint {
+ list [catch {expr 2.0/0.0} msg] $msg
+} {0 Inf}
+test expr-old-26.11 {error conditions} -body {
+ expr 2#
+} -returnCodes error -match glob -result *
+test expr-old-26.12 {error conditions} -body {
+ expr a.b
+} -returnCodes error -match glob -result *
+test expr-old-26.13 {error conditions} {
+ list [catch {expr {"a"/"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+test expr-old-26.14 {error conditions} -body {
+ expr 2:3
+} -returnCodes error -match glob -result *
+test expr-old-26.15 {error conditions} -body {
+ expr a@b
+} -returnCodes error -match glob -result *
+test expr-old-26.16 {error conditions} {
+ list [catch {expr a[b} msg] $msg
+} {1 {missing close-bracket}}
+test expr-old-26.17 {error conditions} -body {
+ expr a`b
+} -returnCodes error -match glob -result *
+test expr-old-26.18 {error conditions} -body {
+ expr \"a\"\{b
+} -returnCodes error -match glob -result *
+test expr-old-26.19 {error conditions} -body {
+ expr a
+} -returnCodes error -match glob -result *
+test expr-old-26.20 {error conditions} {
+ list [catch expr msg] $msg
+} {1 {wrong # args: should be "expr arg ?arg ...?"}}
+
+# Cancelled evaluation.
+
+test expr-old-27.1 {cancelled evaluation} {
+ set a 1
+ expr {0&&[set a 2]}
+ set a
+} 1
+test expr-old-27.2 {cancelled evaluation} {
+ set a 1
+ expr {1||[set a 2]}
+ set a
+} 1
+test expr-old-27.3 {cancelled evaluation} {
+ set a 1
+ expr {0?[set a 2]:1}
+ set a
+} 1
+test expr-old-27.4 {cancelled evaluation} {
+ set a 1
+ expr {1?2:[set a 2]}
+ set a
+} 1
+catch {unset x}
+test expr-old-27.5 {cancelled evaluation} {
+ list [catch {expr {[info exists x] && $x}} msg] $msg
+} {0 0}
+test expr-old-27.6 {cancelled evaluation} {
+ list [catch {expr {0 && [concat $x]}} msg] $msg
+} {0 0}
+test expr-old-27.7 {cancelled evaluation} {
+ set one 1
+ list [catch {expr {1 || 1/$one}} msg] $msg
+} {0 1}
+test expr-old-27.8 {cancelled evaluation} {
+ list [catch {expr {1 || -"string"}} msg] $msg
+} {0 1}
+test expr-old-27.9 {cancelled evaluation} {
+ list [catch {expr {1 || ("string" * ("x" && "y"))}} msg] $msg
+} {0 1}
+test expr-old-27.10 {cancelled evaluation} {
+ set x -1.0
+ list [catch {expr {($x > 0) ? round(log($x)) : 0}} msg] $msg
+} {0 0}
+test expr-old-27.11 {cancelled evaluation} -body {
+ expr {0 && foo}
+} -returnCodes error -match glob -result *
+test expr-old-27.12 {cancelled evaluation} -body {
+ expr {0 ? 1 : foo}
+} -returnCodes error -match glob -result *
+
+# Tcl_ExprBool as used in "if" statements
+
+test expr-old-28.1 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {2} {set a 2}
+ set a
+} 2
+test expr-old-28.2 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {0} {set a 2}
+ set a
+} 1
+test expr-old-28.3 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {1.2} {set a 2}
+ set a
+} 2
+test expr-old-28.4 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {-1.1} {set a 2}
+ set a
+} 2
+test expr-old-28.5 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {0.0} {set a 2}
+ set a
+} 1
+test expr-old-28.6 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"YES"} {set a 2}
+ set a
+} 2
+test expr-old-28.7 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"no"} {set a 2}
+ set a
+} 1
+test expr-old-28.8 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"true"} {set a 2}
+ set a
+} 2
+test expr-old-28.9 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"fAlse"} {set a 2}
+ set a
+} 1
+test expr-old-28.10 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"on"} {set a 2}
+ set a
+} 2
+test expr-old-28.11 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"Off"} {set a 2}
+ set a
+} 1
+test expr-old-28.12 {Tcl_ExprBool usage} {
+ list [catch {if {"abc"} {}} msg] $msg
+} {1 {expected boolean value but got "abc"}}
+test expr-old-28.13 {Tcl_ExprBool usage} {
+ list [catch {if {"ogle"} {}} msg] $msg
+} {1 {expected boolean value but got "ogle"}}
+test expr-old-28.14 {Tcl_ExprBool usage} {
+ list [catch {if {"o"} {}} msg] $msg
+} {1 {expected boolean value but got "o"}}
+
+# Operands enclosed in braces
+
+test expr-old-29.1 {braces} {expr {{abc}}} abc
+test expr-old-29.2 {braces} {expr {{0o0010}}} 8
+test expr-old-29.3 {braces} {expr {{3.1200000}}} 3.12
+test expr-old-29.4 {braces} {expr {{a{b}{1 {2 3}}c}}} "a{b}{1 {2 3}}c"
+test expr-old-29.5 {braces} -body {
+ expr "\{abc"
+} -returnCodes error -match glob -result *
+
+# Very long values
+
+test expr-old-30.1 {long values} {
+ set a "0000 1111 2222 3333 4444"
+ set a "$a | $a | $a | $a | $a"
+ set a "$a || $a || $a || $a || $a"
+ expr {$a}
+} {0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 || 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 || 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 || 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 || 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444}
+test expr-old-30.2 {long values} {
+ set a "000000000000000000000000000000"
+ set a "$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a${a}5"
+ expr $a
+} 5
+
+# Expressions spanning multiple arguments
+
+test expr-old-31.1 {multiple arguments to expr command} {
+ expr 4 + ( 6 *12) -3
+} 73
+test expr-old-31.2 {multiple arguments to expr command} -body {
+ expr 2 + (3 + 4
+} -returnCodes error -match glob -result *
+test expr-old-31.3 {multiple arguments to expr command} -body {
+ expr 2 + 3 +
+} -returnCodes error -match glob -result *
+test expr-old-31.4 {multiple arguments to expr command} -body {
+ expr 2 + 3 )
+} -returnCodes error -match glob -result *
+
+# Math functions
+
+test expr-old-32.1 {math functions in expressions} {
+ format %.6g [expr acos(0.5)]
+} {1.0472}
+test expr-old-32.2 {math functions in expressions} {
+ format %.6g [expr asin(0.5)]
+} {0.523599}
+test expr-old-32.3 {math functions in expressions} {
+ format %.6g [expr atan(1.0)]
+} {0.785398}
+test expr-old-32.4 {math functions in expressions} {
+ format %.6g [expr atan2(2.0, 2.0)]
+} {0.785398}
+test expr-old-32.5 {math functions in expressions} {
+ format %.6g [expr ceil(1.999)]
+} {2}
+test expr-old-32.6 {math functions in expressions} {
+ format %.6g [expr cos(.1)]
+} {0.995004}
+test expr-old-32.7 {math functions in expressions} {
+ format %.6g [expr cosh(.1)]
+} {1.005}
+test expr-old-32.8 {math functions in expressions} {
+ format %.6g [expr exp(1.0)]
+} {2.71828}
+test expr-old-32.9 {math functions in expressions} {
+ format %.6g [expr floor(2.000)]
+} {2}
+test expr-old-32.10 {math functions in expressions} {
+ format %.6g [expr floor(2.001)]
+} {2}
+test expr-old-32.11 {math functions in expressions} {
+ format %.6g [expr fmod(7.3, 3.2)]
+} {0.9}
+test expr-old-32.12 {math functions in expressions} {
+ format %.6g [expr hypot(3.0, 4.0)]
+} {5}
+test expr-old-32.13 {math functions in expressions} {
+ format %.6g [expr log(2.8)]
+} {1.02962}
+test expr-old-32.14 {math functions in expressions} {
+ format %.6g [expr log10(2.8)]
+} {0.447158}
+test expr-old-32.15 {math functions in expressions} {
+ format %.6g [expr pow(2.1, 3.1)]
+} {9.97424}
+test expr-old-32.16 {math functions in expressions} {
+ format %.6g [expr sin(.1)]
+} {0.0998334}
+test expr-old-32.17 {math functions in expressions} {
+ format %.6g [expr sinh(.1)]
+} {0.100167}
+test expr-old-32.18 {math functions in expressions} {
+ format %.6g [expr sqrt(2.0)]
+} {1.41421}
+test expr-old-32.19 {math functions in expressions} {
+ format %.6g [expr tan(0.8)]
+} {1.02964}
+test expr-old-32.20 {math functions in expressions} {
+ format %.6g [expr tanh(0.8)]
+} {0.664037}
+test expr-old-32.21 {math functions in expressions} {
+ format %.6g [expr abs(-1.8)]
+} {1.8}
+test expr-old-32.22 {math functions in expressions} {
+ expr abs(10.0)
+} {10.0}
+test expr-old-32.23 {math functions in expressions} {
+ format %.6g [expr abs(-4)]
+} {4}
+test expr-old-32.24 {math functions in expressions} {
+ format %.6g [expr abs(66)]
+} {66}
+
+test expr-old-32.25a {math functions in expressions} {
+ expr abs(0x8000000000000000)
+} [expr 1<<63]
+
+test expr-old-32.25b {math functions in expressions} {
+ expr abs(0x80000000)
+} 2147483648
+
+test expr-old-32.26 {math functions in expressions} {
+ expr double(1)
+} {1.0}
+test expr-old-32.27 {math functions in expressions} {
+ expr double(1.1)
+} {1.1}
+test expr-old-32.28 {math functions in expressions} {
+ expr int(1)
+} {1}
+test expr-old-32.29 {math functions in expressions} {
+ expr int(1.4)
+} {1}
+test expr-old-32.30 {math functions in expressions} {
+ expr int(1.6)
+} {1}
+test expr-old-32.31 {math functions in expressions} {
+ expr int(-1.4)
+} {-1}
+test expr-old-32.32 {math functions in expressions} {
+ expr int(-1.6)
+} {-1}
+test expr-old-32.33 {math functions in expressions} {
+ expr int(1e60)
+} 0
+test expr-old-32.34 {math functions in expressions} {
+ expr int(-1e60)
+} 0
+test expr-old-32.35 {math functions in expressions} {
+ expr round(1.49)
+} {1}
+test expr-old-32.36 {math functions in expressions} {
+ expr round(1.51)
+} {2}
+test expr-old-32.37 {math functions in expressions} {
+ expr round(-1.49)
+} {-1}
+test expr-old-32.38 {math functions in expressions} {
+ expr round(-1.51)
+} {-2}
+test expr-old-32.39 {math functions in expressions} {
+ expr round(1e60)
+} 999999999999999949387135297074018866963645011013410073083904
+test expr-old-32.40 {math functions in expressions} {
+ expr round(-1e60)
+} -999999999999999949387135297074018866963645011013410073083904
+test expr-old-32.41 {math functions in expressions} {
+ list [catch {expr pow(1.0 + 3.0 - 2, .8 * 5)} msg] $msg
+} {0 16.0}
+test expr-old-32.42 {math functions in expressions} {
+ list [catch {expr hypot(5*.8,3)} msg] $msg
+} {0 5.0}
+test expr-old-32.43 {math functions in expressions} testmathfunctions {
+ expr 2*T1()
+} 246
+test expr-old-32.44 {math functions in expressions} testmathfunctions {
+ expr T2()*3
+} 1035
+test expr-old-32.45 {math functions in expressions} {
+ expr (0 <= rand()) && (rand() < 1)
+} {1}
+test expr-old-32.46 {math functions in expressions} -body {
+ list [catch {expr rand(24)} msg] $msg
+} -match glob -result {1 {too many arguments for math function*}}
+test expr-old-32.47 {math functions in expressions} -body {
+ list [catch {expr srand()} msg] $msg
+} -match glob -result {1 {too few arguments for math function*}}
+test expr-old-32.48 {math functions in expressions} -body {
+ expr srand(3.79)
+} -returnCodes error -match glob -result *
+test expr-old-32.49 {math functions in expressions} -body {
+ expr srand("")
+} -returnCodes error -match glob -result *
+test expr-old-32.50 {math functions in expressions} {
+ set result [expr round(srand(12345) * 1000)]
+ for {set i 0} {$i < 10} {incr i} {
+ lappend result [expr round(rand() * 1000)]
+ }
+ set result
+} {97 834 948 36 12 51 766 585 914 784 333}
+test expr-old-32.51 {math functions in expressions} -body {
+ expr {srand([lindex "6ty" 0])}
+} -returnCodes error -match glob -result *
+test expr-old-32.52 {math functions in expressions} {
+ expr {srand(int(1<<37)) < 1}
+} {1}
+test expr-old-32.53 {math functions in expressions} {
+ expr {srand((1<<31) - 1) > 0}
+} {1}
+
+test expr-old-33.1 {conversions and fancy args to math functions} {
+ expr hypot ( 3 , 4 )
+} 5.0
+test expr-old-33.2 {conversions and fancy args to math functions} {
+ expr hypot ( (2.0+1.0) , 4 )
+} 5.0
+test expr-old-33.3 {conversions and fancy args to math functions} {
+ expr hypot ( 3 , (3.0 + 1.0) )
+} 5.0
+test expr-old-33.4 {conversions and fancy args to math functions} {
+ format %.6g [expr cos(acos(0.1))]
+} 0.1
+
+test expr-old-34.1 {errors in math functions} -body {
+ list [catch {expr func_2(1.0)} msg] $msg
+} -match glob -result {1 {* "*func_2"}}
+test expr-old-34.2 {errors in math functions} -body {
+ expr func|(1.0)
+} -returnCodes error -match glob -result *
+test expr-old-34.3 {errors in math functions} {
+ list [catch {expr {hypot("a b", 2.0)}} msg] $msg
+} {1 {expected floating-point number but got "a b"}}
+test expr-old-34.4 {errors in math functions} -body {
+ expr hypot(1.0 2.0)
+} -returnCodes error -match glob -result *
+test expr-old-34.5 {errors in math functions} -body {
+ expr hypot(1.0, 2.0
+} -returnCodes error -match glob -result *
+test expr-old-34.6 {errors in math functions} -body {
+ expr hypot(1.0 ,
+} -returnCodes error -match glob -result *
+test expr-old-34.7 {errors in math functions} -body {
+ list [catch {expr hypot(1.0)} msg] $msg
+} -match glob -result {1 {too few arguments for math function*}}
+test expr-old-34.8 {errors in math functions} -body {
+ list [catch {expr hypot(1.0, 2.0, 3.0)} msg] $msg
+} -match glob -result {1 {too many arguments for math function*}}
+test expr-old-34.9 {errors in math functions} {
+ list [catch {expr acos(-2.0)} msg] $msg $errorCode
+} {1 {domain error: argument not in valid range} {ARITH DOMAIN {domain error: argument not in valid range}}}
+test expr-old-34.10 {errors in math functions} {
+ list [catch {expr pow(-3, 1000001)} msg] $msg
+} {0 -Inf}
+test expr-old-34.11a {errors in math functions} !ieeeFloatingPoint {
+ list [catch {expr pow(3, 1000001)} msg] $msg $errorCode
+} {1 {floating-point value too large to represent} {ARITH OVERFLOW {floating-point value too large to represent}}}
+test expr-old-34.11b {errors in math functions} ieeeFloatingPoint {
+ list [catch {expr pow(3, 1000001)} msg] $msg
+} {0 Inf}
+test expr-old-34.12a {errors in math functions} !ieeeFloatingPoint {
+ list [catch {expr -14.0*exp(100000)} msg] $msg $errorCode
+} {1 {floating-point value too large to represent} {ARITH OVERFLOW {floating-point value too large to represent}}}
+test expr-old-34.12b {errors in math functions} ieeeFloatingPoint {
+ list [catch {expr -14.0*exp(100000)} msg] $msg
+} {0 -Inf}
+test expr-old-34.13 {errors in math functions} {
+ expr wide(1.0e30)
+} 5076964154930102272
+test expr-old-34.14 {errors in math functions} {
+ expr wide(-1.0e30)
+} -5076964154930102272
+test expr-old-34.15 {errors in math functions} {
+ expr round(1.0e30)
+} 1000000000000000019884624838656
+test expr-old-34.16 {errors in math functions} {
+ expr round(-1.0e30)
+} -1000000000000000019884624838656
+test expr-old-34.17 {errors in math functions} -constraints testmathfunctions \
+ -body {
+ list [catch {expr T1(4)} msg] $msg
+ } -match glob -result {1 {too many arguments for math function*}}
+
+test expr-old-36.1 {ExprLooksLikeInt procedure} -body {
+ expr 0o289
+} -returnCodes error -match glob -result {*invalid octal number*}
+test expr-old-36.2 {ExprLooksLikeInt procedure} {
+ set x 0o289
+ list [catch {expr {$x+1}} msg] $msg
+} {1 {can't use invalid octal number as operand of "+"}}
+test expr-old-36.3 {ExprLooksLikeInt procedure} {
+ list [catch {expr 0289.1} msg] $msg
+} {0 289.1}
+test expr-old-36.4 {ExprLooksLikeInt procedure} {
+ set x 0289.1
+ list [catch {expr {$x+1}} msg] $msg
+} {0 290.1}
+test expr-old-36.5 {ExprLooksLikeInt procedure} {
+ set x { +22}
+ list [catch {expr {$x+1}} msg] $msg
+} {0 23}
+test expr-old-36.6 {ExprLooksLikeInt procedure} {
+ set x { -22}
+ list [catch {expr {$x+1}} msg] $msg
+} {0 -21}
+test expr-old-36.7 {ExprLooksLikeInt procedure} {
+ list [catch {expr nan} msg] $msg
+} {1 {domain error: argument not in valid range}}
+test expr-old-36.8 {ExprLooksLikeInt procedure} {
+ list [catch {expr 78e1} msg] $msg
+} {0 780.0}
+test expr-old-36.9 {ExprLooksLikeInt procedure} {
+ list [catch {expr 24E1} msg] $msg
+} {0 240.0}
+test expr-old-36.10 {ExprLooksLikeInt procedure} -body {
+ expr 78e
+} -returnCodes error -match glob -result *
+
+# test for [Bug #542588]
+test expr-old-36.11 {ExprLooksLikeInt procedure} {
+ # define a "too large integer"; this one works also for 64bit arith
+ set x 665802003400000000000000
+ expr {$x+1}
+} 665802003400000000000001
+
+# tests for [Bug #587140]
+test expr-old-36.12 {ExprLooksLikeInt procedure} {
+ set x "10;"
+ list [catch {expr {$x+1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-36.13 {ExprLooksLikeInt procedure} {
+ set x " +"
+ list [catch {expr {$x+1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-36.14 {ExprLooksLikeInt procedure} {
+ set x "123456789012345678901234567890 "
+ expr {$x+1}
+} 123456789012345678901234567891
+test expr-old-36.15 {ExprLooksLikeInt procedure} {
+ set x "0o99 "
+ list [catch {expr {$x+1}} msg] $msg
+} {1 {can't use invalid octal number as operand of "+"}}
+test expr-old-36.16 {ExprLooksLikeInt procedure} {
+ set x " 0xffffffffffffffffffffffffffffffffffffff "
+ expr {$x+1}
+} [expr 0x100000000000000000000000000000000000000]
+
+test expr-old-37.1 {Check that Tcl_ExprLong doesn't modify interpreter result if no error} testexprlong {
+ testexprlong 4+1
+} {This is a result: 5}
+#Check for [Bug 1109484]
+test expr-old-37.2 {Tcl_ExprLong handles wide ints gracefully} testexprlong {
+ testexprlong wide(1)+2
+} {This is a result: 3}
+
+test expr-old-37.3 {Tcl_ExprLong on the empty string} testexprlong {
+ testexprlong ""
+} {This is a result: 0}
+test expr-old-37.4 {Tcl_ExprLong coerces doubles} testexprlong {
+ testexprlong 3+.14159
+} {This is a result: 3}
+test expr-old-37.5 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit} {
+ testexprlong 0x80000000
+} {This is a result: -2147483648}
+test expr-old-37.6 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit} {
+ testexprlong 0xffffffff
+} {This is a result: -1}
+test expr-old-37.7 {Tcl_ExprLong handles overflows} \
+ -constraints {testexprlong longIs32bit} \
+ -match glob \
+ -body {
+ list [catch {testexprlong 0x100000000} result] $result
+ } \
+ -result {1 {integer value too large to represent*}}
+test expr-old-37.8 {Tcl_ExprLong handles overflows} testexprlong {
+ testexprlong -0x80000000
+} {This is a result: -2147483648}
+test expr-old-37.9 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit} {
+ testexprlong -0xffffffff
+} {This is a result: 1}
+test expr-old-37.10 {Tcl_ExprLong handles overflows} \
+ -constraints {testexprlong longIs32bit} \
+ -match glob \
+ -body {
+ list [catch {testexprlong -0x100000000} result] $result
+ } \
+ -result {1 {integer value too large to represent*}}
+test expr-old-37.11 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit} {
+ testexprlong 2147483648.
+} {This is a result: -2147483648}
+test expr-old-37.12 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit} {
+ testexprlong 4294967295.
+} {This is a result: -1}
+test expr-old-37.13 {Tcl_ExprLong handles overflows} \
+ -constraints {testexprlong longIs32bit} \
+ -match glob \
+ -body {
+ list [catch {testexprlong 4294967296.} result] $result
+ } \
+ -result {1 {integer value too large to represent*}}
+test expr-old-37.14 {Tcl_ExprLong handles overflows} testexprlong {
+ testexprlong -2147483648.
+} {This is a result: -2147483648}
+test expr-old-37.15 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit} {
+ testexprlong -4294967295.
+} {This is a result: 1}
+test expr-old-37.16 {Tcl_ExprLong handles overflows} \
+ -constraints {testexprlong longIs32bit} \
+ -match glob \
+ -body {
+ list [catch {testexprlong 4294967296.} result] $result
+ } \
+ -result {1 {integer value too large to represent*}}
+
+test expr-old-37.17 {Check that Tcl_ExprDouble doesn't modify interpreter result if no error} testexprdouble {
+ testexprdouble 4.+1.
+} {This is a result: 5.0}
+#Check for [Bug 1109484]
+test expr-old-37.18 {Tcl_ExprDouble on the empty string} testexprdouble {
+ testexprdouble ""
+} {This is a result: 0.0}
+test expr-old-37.19 {Tcl_ExprDouble coerces wides} testexprdouble {
+ testexprdouble 1[string repeat 0 17]
+} {This is a result: 1e+17}
+test expr-old-37.20 {Tcl_ExprDouble coerces bignums} testexprdouble {
+ testexprdouble 1[string repeat 0 38]
+} {This is a result: 1e+38}
+test expr-old-37.21 {Tcl_ExprDouble handles overflows} testexprdouble {
+ testexprdouble 17976931348623157[string repeat 0 292].
+} {This is a result: 1.7976931348623157e+308}
+test expr-old-37.22 {Tcl_ExprDouble handles overflows that look like int} \
+ testexprdouble {
+ testexprdouble 17976931348623157[string repeat 0 292]
+ } {This is a result: 1.7976931348623157e+308}
+test expr-old-37.23 {Tcl_ExprDouble handles overflows} \
+ ieeeFloatingPoint&&testexprdouble {
+ testexprdouble 17976931348623165[string repeat 0 292].
+ } {This is a result: Inf}
+test expr-old-37.24 {Tcl_ExprDouble handles overflows that look like int} \
+ ieeeFloatingPoint&&testexprdouble {
+ testexprdouble 17976931348623165[string repeat 0 292]
+ } {This is a result: Inf}
+test expr-old-37.25 {Tcl_ExprDouble and NaN} \
+ {ieeeFloatingPoint testexprdouble} {
+ list [catch {testexprdouble 0.0/0.0} result] $result
+ } {1 {domain error: argument not in valid range}}
+
+test expr-old-38.1 {Verify Tcl_ExprString's basic operation} -constraints {testexprstring} -body {
+ list [testexprstring "1+4"] [testexprstring "2*3+4.2"] \
+ [catch {testexprstring "1+"} msg] $msg
+} -match glob -result {5 10.2 1 *}
+test expr-old-38.2 {Tcl_ExprString} testexprstring {
+ # This one is "magical"
+ testexprstring {}
+} 0
+test expr-old-38.3 {Tcl_ExprString} -constraints testexprstring -body {
+ testexprstring { }
+} -returnCodes error -match glob -result *
+
+#
+# Test for bug #908375: rounding numbers that do not fit in a
+# long but do fit in a wide
+#
+
+test expr-old-39.1 {Rounding with wide result} {
+ set x 1.0e10
+ set y [expr $x + 0.1]
+ catch {
+ set x [list [expr {$x == round($y)}] [expr $x == -round(-$y)]]
+ }
+ set x
+} {1 1}
+unset -nocomplain x y
+
+#
+# TIP #255 min and max math functions
+#
+
+test expr-old-40.1 {min math function} -body {
+ expr {min(0)}
+} -result 0
+test expr-old-40.2 {min math function} -body {
+ expr {min(0.0)}
+} -result 0.0
+test expr-old-40.3 {min math function} -body {
+ list [catch {expr {min()}} msg] $msg
+} -result {1 {too few arguments to math function "min"}}
+test expr-old-40.4 {min math function} -body {
+ expr {min(wide(-1) << 30, 4.5, -10)}
+} -result [expr {wide(-1) << 30}]
+test expr-old-40.5 {min math function} -body {
+ expr {min("a", 0)}
+} -returnCodes error -match glob -result *
+test expr-old-40.6 {min math function} -body {
+ expr {min(300, "0xFF")}
+} -result 255
+
+test expr-old-41.1 {max math function} -body {
+ expr {max(0)}
+} -result 0
+test expr-old-41.2 {max math function} -body {
+ expr {max(0.0)}
+} -result 0.0
+test expr-old-41.3 {max math function} -body {
+ list [catch {expr {max()}} msg] $msg
+} -result {1 {too few arguments to math function "max"}}
+test expr-old-41.4 {max math function} -body {
+ expr {max(wide(1) << 30, 4.5, -10)}
+} -result [expr {wide(1) << 30}]
+test expr-old-41.5 {max math function} -body {
+ expr {max("a", 0)}
+} -returnCodes error -match glob -result *
+test expr-old-41.6 {max math function} -body {
+ expr {max(200, "0xFF")}
+} -result 255
+
+# Special test for Pentium arithmetic bug of 1994:
+
+if {(4195835.0 - (4195835.0/3145727.0)*3145727.0) == 256.0} {
+ puts "Warning: this machine contains a defective Pentium processor"
+ puts "that performs arithmetic incorrectly. I recommend that you"
+ puts "call Intel customer service immediately at 1-800-628-8686"
+ puts "to request a replacement processor."
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/expr.test b/library/msgcat/tests/expr.test
new file mode 100644
index 0000000..6679569
--- /dev/null
+++ b/library/msgcat/tests/expr.test
@@ -0,0 +1,7187 @@
+# Commands covered: expr
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1996-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2.1
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testmathfunctions [expr {
+ ([catch {expr T1()} msg] != 1) || ($msg ne {invalid command name "tcl::mathfunc::T1"})
+}]
+
+# Determine if "long int" type is a 32 bit number and if the wide
+# type is a 64 bit number on this machine.
+
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}]
+testConstraint wideIs64bit \
+ [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}]
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+ variable ieeeValues
+ binary scan [binary format dd -1.0 1.0] c* c
+ switch -exact -- $c {
+ {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+ # little endian
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+ ieeeValues(-Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+ ieeeValues(-Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+ ieeeValues(-Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+ ieeeValues(+Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+ ieeeValues(+Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+ ieeeValues(NaN)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\xff d \
+ ieeeValues(-NaN)
+ set ieeeValues(littleEndian) 1
+ return 1
+ }
+ {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+ binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Infinity)
+ binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Normal)
+ binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Subnormal)
+ binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Normal)
+ binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Infinity)
+ binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(NaN)
+ binary scan \xff\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-NaN)
+ set ieeeValues(littleEndian) 0
+ return 1
+ }
+ default {
+ return 0
+ }
+ }
+}
+
+testConstraint ieeeFloatingPoint [testIEEE]
+# procedures used below
+
+proc put_hello_char {c} {
+ global a
+ append a [format %c $c]
+ return $c
+}
+proc hello_world {} {
+ global a
+ set a ""
+ set L1 [set l0 [set h_1 [set q 0]]]
+ for {put_hello_char [expr [put_hello_char [expr [set h 7]*10+2]]+29]} {$l0?[put_hello_char $l0]
+ :!$h_1} {put_hello_char $ll;expr {$L1==2?[set ll [expr 32+0-0+[set bar 0]]]:0}} {expr {[incr L1]==[expr 1+([string length "abc"]-[string length "abc"])]
+ ?[set ll [set l0 [expr 54<<1]]]:$ll==108&&$L1<3?
+ [incr ll [expr 1|1<<1]; set ll $ll; set ll $ll; set ll $ll; set ll $ll; set l0 [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]; set l0; set l0 $l0; set l0; set l0]:$L1==4&&$ll==32?[set ll [expr 19+$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+[set foo [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]]]]
+ :[set q [expr $q-$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]};expr {$L1==5?[incr ll -8; set ll $ll; set ll]:$q&&$h1&&1};expr {$L1==4+2
+ ?[incr ll 3]:[expr ([string length "abc"]-[string length "abc"])+1]};expr {$ll==($h<<4)+2+0&&$L1!=6?[incr ll -6]:[set h1 [expr 100+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]}
+ expr {$L1!=1<<3?[incr q [expr ([string length "abc"]-[string length "abc"])-1]]:[set h_1 [set ll $h1]]}
+ }
+ set a
+}
+
+proc 12days {a b c} {
+ global xxx
+ expr {1<$a?[expr {$a<3?[12days -79 -13 [string range $c [12days -87 \
+ [expr 1-$b] [string range $c [12days -86 0 [string range $c 1 end]] \
+ end]] end]]:1};expr {$a<$b?[12days [expr $a+1] $b $c]:3};expr {[12days \
+ -94 [expr $a-27] $c]&&$a==2?$b<13?[12days 2 [expr $b+1] "%s %d %d\n"]:9
+ :16}]:$a<0?$a<-72?[12days $b $a "@n'+,#'/*\{\}w+/w#cdnr/+,\{\}r/*de\}+,/*\{*+,/w\{%+,/w#q#n+,/#\{l+,/n\{n+,/+#n+,/#;#q#n+,/+k#;*+,/'r :'d*'3,\}\{w+K w'K:'+\}e#';dq#'l q#'+d'K#!/+k#;q#'r\}eKK#\}w'r\}eKK\{nl\]'/#;#q#n')\{)#\}w')\{)\{nl\]'/+#n';d\}rw' i;# )\{nl\]!/n\{n#'; r\{#w'r nc\{nl\]'/#\{l,+'K \{rw' iK\{;\[\{nl\]'/w#q#n'wk nw' iwk\{KK\{nl\]!/w\{%'l##w#' i; :\{nl\]'/*\{q#'ld;r'\}\{nlwb!/*de\}'c ;;\{nl'-\{\}rw\]'/+,\}##'*\}#nc,',#nw\]'/+kd'+e\}+;#'rdq#w! nr'/ ') \}+\}\{rl#'\{n' ')# \}'+\}##(!!/"]
+ :$a<-50?[string compare [format %c $b] [string index $c 0]]==0?[append \
+ xxx [string index $c 31];scan [string index $c 31] %c x;set x]
+ :[12days -65 $b [string range $c 1 end]]:[12days [expr ([string compare \
+ [string index $c 0] "/"]==0)+$a] $b [string range $c 1 end]]:0<$a
+ ?[12days 2 2 "%s"]:[string compare [string index $c 0] "/"]==0||
+ [12days 0 [12days -61 [scan [string index $c 0] %c x; set x] \
+ "!ek;dc i@bK'(q)-\[w\]*%n+r3#l,\{\}:\nuwloca-O;m .vpbks,fxntdCeghiry"] \
+ [string range $c 1 end]]}
+}
+proc do_twelve_days {} {
+ global xxx
+ set xxx ""
+ 12days 1 1 1
+ set result [string length $xxx]
+ unset xxx
+ return $result
+}
+
+# start of tests
+
+catch {unset a b i x}
+
+test expr-1.1 {TclCompileExprCmd: no expression} {
+ list [catch {expr } msg] $msg
+} {1 {wrong # args: should be "expr arg ?arg ...?"}}
+test expr-1.2 {TclCompileExprCmd: one expression word} {
+ expr -25
+} -25
+test expr-1.3 {TclCompileExprCmd: two expression words} {
+ expr -8.2 -6
+} -14.2
+test expr-1.4 {TclCompileExprCmd: five expression words} {
+ expr 20 - 5 +10 -7
+} 18
+test expr-1.5 {TclCompileExprCmd: quoted expression word} {
+ expr "0005"
+} 5
+test expr-1.6 {TclCompileExprCmd: quoted expression word} {
+ catch {expr "0005"zxy} msg
+ set msg
+} {extra characters after close-quote}
+test expr-1.7 {TclCompileExprCmd: expression word in braces} {
+ expr {-0005}
+} -5
+test expr-1.8 {TclCompileExprCmd: expression word in braces} {
+ expr {{-0x1234}}
+} -4660
+test expr-1.9 {TclCompileExprCmd: expression word in braces} {
+ catch {expr {-0005}foo} msg
+ set msg
+} {extra characters after close-brace}
+test expr-1.10 {TclCompileExprCmd: other expression word in braces} {
+ expr 4*[llength "6 2"]
+} 8
+test expr-1.11 {TclCompileExprCmd: expression word terminated by ;} {
+ expr 4*[llength "6 2"];
+} 8
+test expr-1.12 {TclCompileExprCmd: inlined expr (in "catch") inside other catch} {
+ set a xxx
+ catch {
+ # Might not be a number
+ set a [expr 10*$a]
+ }
+} 1
+test expr-1.13 {TclCompileExprCmd: second level of substitutions in expr not in braces with single var reference} {
+ set a xxx
+ set x 27; set bool {$x}; if $bool {set a foo}
+ set a
+} foo
+test expr-1.14 {TclCompileExprCmd: second level of substitutions in expr with comparison as top-level operator} {
+ set a xxx
+ set x 2; set b {$x}; set a [expr $b == 2]
+ set a
+} 1
+test expr-1.15 {TclCompileExprCmd: second level of substitutions in expr with comparison as top-level operator} {
+ set a xxx
+ set x 2; set b {$x}; set a [expr $b eq 2]
+ set a
+} 1
+
+test expr-2.1 {TclCompileExpr: are builtin functions registered?} {
+ expr double(5*[llength "6 2"])
+} 10.0
+test expr-2.2 {TclCompileExpr: error in expr} -body {
+ expr 2***3
+} -returnCodes error -match glob -result *
+test expr-2.3 {TclCompileExpr: junk after legal expr} -body {
+ expr 7*[llength "a b"]foo
+} -returnCodes error -match glob -result *
+test expr-2.4 {TclCompileExpr: numeric expr string rep == formatted int rep} {
+ expr {0001}
+} 1
+
+test expr-3.1 {CompileCondExpr: just lor expr} {expr 3||0} 1
+test expr-3.2 {CompileCondExpr: error in lor expr} -body {
+ expr x||3
+} -returnCodes error -match glob -result *
+test expr-3.3 {CompileCondExpr: test true arm} {expr 3>2?44:66} 44
+test expr-3.4 {CompileCondExpr: error compiling true arm} -body {
+ expr 3>2?2***3:66
+} -returnCodes error -match glob -result *
+test expr-3.5 {CompileCondExpr: test false arm} {expr 2>3?44:66} 66
+test expr-3.6 {CompileCondExpr: error compiling false arm} -body {
+ expr 2>3?44:2***3
+} -returnCodes error -match glob -result *
+test expr-3.7 {CompileCondExpr: long arms & nested cond exprs} {
+ hello_world
+} {Hello world}
+test expr-3.8 {CompileCondExpr: long arms & nested cond exprs} unix {
+ # Fails with a stack overflow on threaded Windows builds
+ do_twelve_days
+} 2358
+
+test expr-4.1 {CompileLorExpr: just land expr} {expr 1.3&&3.3} 1
+test expr-4.2 {CompileLorExpr: error in land expr} -body {
+ expr x&&3
+} -returnCodes error -match glob -result *
+test expr-4.3 {CompileLorExpr: simple lor exprs} {expr 0||1.0} 1
+test expr-4.4 {CompileLorExpr: simple lor exprs} {expr 3.0||0.0} 1
+test expr-4.5 {CompileLorExpr: simple lor exprs} {expr 0||0||1} 1
+test expr-4.6 {CompileLorExpr: error compiling lor arm} -body {
+ expr 2***3||4.0
+} -returnCodes error -match glob -result *
+test expr-4.7 {CompileLorExpr: error compiling lor arm} -body {
+ expr 1.3||2***3
+} -returnCodes error -match glob -result *
+test expr-4.8 {CompileLorExpr: error compiling lor arms} {
+ list [catch {expr {"a"||"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test expr-4.9 {CompileLorExpr: long lor arm} {
+ set a "abcdefghijkl"
+ set i 7
+ expr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]}
+} 1
+test expr-4.10 {CompileLorExpr: error compiling ! operand} {
+ list [catch {expr {!"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-4.11 {CompileLorExpr: error compiling land arms} {
+ list [catch {expr {"a"||0}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test expr-4.12 {CompileLorExpr: error compiling land arms} {
+ list [catch {expr {0||"a"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+
+test expr-5.1 {CompileLandExpr: just bitor expr} {expr 7|0x13} 23
+test expr-5.2 {CompileLandExpr: error in bitor expr} -body {
+ expr x|3
+} -returnCodes error -match glob -result *
+test expr-5.3 {CompileLandExpr: simple land exprs} {expr 0&&1.0} 0
+test expr-5.4 {CompileLandExpr: simple land exprs} {expr 0&&0} 0
+test expr-5.5 {CompileLandExpr: simple land exprs} {expr 3.0&&1.2} 1
+test expr-5.6 {CompileLandExpr: simple land exprs} {expr 1&&1&&2} 1
+test expr-5.7 {CompileLandExpr: error compiling land arm} -body {
+ expr 2***3&&4.0
+} -returnCodes error -match glob -result *
+test expr-5.8 {CompileLandExpr: error compiling land arm} -body {
+ expr 1.3&&2***3
+} -returnCodes error -match glob -result *
+test expr-5.9 {CompileLandExpr: error compiling land arm} {
+ list [catch {expr {"a"&&"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test expr-5.10 {CompileLandExpr: long land arms} {
+ set a "abcdefghijkl"
+ set i 7
+ expr {[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]}
+} 1
+
+test expr-6.1 {CompileBitXorExpr: just bitand expr} {expr 7&0x13} 3
+test expr-6.2 {CompileBitXorExpr: error in bitand expr} -body {
+ expr x|3
+} -returnCodes error -match glob -result *
+test expr-6.3 {CompileBitXorExpr: simple bitxor exprs} {expr 7^0x13} 20
+test expr-6.4 {CompileBitXorExpr: simple bitxor exprs} {expr 3^0x10} 19
+test expr-6.5 {CompileBitXorExpr: simple bitxor exprs} {expr 0^7} 7
+test expr-6.6 {CompileBitXorExpr: simple bitxor exprs} {expr -1^7} -8
+test expr-6.7 {CompileBitXorExpr: error compiling bitxor arm} -body {
+ expr 2***3|6
+} -returnCodes error -match glob -result *
+test expr-6.8 {CompileBitXorExpr: error compiling bitxor arm} -body {
+ expr 2^x
+} -returnCodes error -match glob -result *
+test expr-6.9 {CompileBitXorExpr: runtime error in bitxor arm} {
+ list [catch {expr {24.0^3}} msg] $msg
+} {1 {can't use floating-point value as operand of "^"}}
+test expr-6.10 {CompileBitXorExpr: runtime error in bitxor arm} {
+ list [catch {expr {"a"^"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "^"}}
+
+test expr-7.1 {CompileBitAndExpr: just equality expr} {expr 3==2} 0
+test expr-7.2 {CompileBitAndExpr: just equality expr} {expr 2.0==2} 1
+test expr-7.3 {CompileBitAndExpr: just equality expr} {expr 3.2!=2.2} 1
+test expr-7.4 {CompileBitAndExpr: just equality expr} {expr {"abc" == "abd"}} 0
+test expr-7.5 {CompileBitAndExpr: error in equality expr} -body {
+ expr x==3
+} -returnCodes error -match glob -result *
+test expr-7.6 {CompileBitAndExpr: simple bitand exprs} {expr 7&0x13} 3
+test expr-7.7 {CompileBitAndExpr: simple bitand exprs} {expr 0xf2&0x53} 82
+test expr-7.8 {CompileBitAndExpr: simple bitand exprs} {expr 3&6} 2
+test expr-7.9 {CompileBitAndExpr: simple bitand exprs} {expr -1&-7} -7
+test expr-7.10 {CompileBitAndExpr: error compiling bitand arm} -body {
+ expr 2***3&6
+} -returnCodes error -match glob -result *
+test expr-7.11 {CompileBitAndExpr: error compiling bitand arm} -body {
+ expr 2&x
+} -returnCodes error -match glob -result *
+test expr-7.12 {CompileBitAndExpr: runtime error in bitand arm} {
+ list [catch {expr {24.0&3}} msg] $msg
+} {1 {can't use floating-point value as operand of "&"}}
+test expr-7.13 {CompileBitAndExpr: runtime error in bitand arm} {
+ list [catch {expr {"a"&"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "&"}}
+test expr-7.14 {CompileBitAndExpr: equality expr} {expr 3eq2} 0
+test expr-7.18 {CompileBitAndExpr: equality expr} {expr {"abc" eq "abd"}} 0
+test expr-7.20 {CompileBitAndExpr: error in equality expr} -body {
+ expr xne3
+} -returnCodes error -match glob -result *
+
+test expr-8.1 {CompileEqualityExpr: just relational expr} {expr 3>=2} 1
+test expr-8.2 {CompileEqualityExpr: just relational expr} {expr 2<=2.1} 1
+test expr-8.3 {CompileEqualityExpr: just relational expr} {expr 3.2>"2.2"} 1
+test expr-8.4 {CompileEqualityExpr: just relational expr} {expr {"0y"<"0x12"}} 0
+test expr-8.5 {CompileEqualityExpr: error in relational expr} -body {
+ expr x>3
+} -returnCodes error -match glob -result *
+test expr-8.6 {CompileEqualityExpr: simple equality exprs} {expr 7==0x13} 0
+test expr-8.7 {CompileEqualityExpr: simple equality exprs} {expr -0xf2!=0x53} 1
+test expr-8.8 {CompileEqualityExpr: simple equality exprs} {expr {"12398712938788234-1298379" != ""}} 1
+test expr-8.9 {CompileEqualityExpr: simple equality exprs} {expr -1!="abc"} 1
+test expr-8.10 {CompileEqualityExpr: error compiling equality arm} -body {
+ expr 2***3==6
+} -returnCodes error -match glob -result *
+test expr-8.11 {CompileEqualityExpr: error compiling equality arm} -body {
+ expr 2!=x
+} -returnCodes error -match glob -result *
+test expr-8.12 {CompileBitAndExpr: equality expr} {expr {"a"eq"a"}} 1
+test expr-8.13 {CompileBitAndExpr: equality expr} {expr {"\374" eq [set s \u00fc]}} 1
+test expr-8.14 {CompileBitAndExpr: equality expr} {expr 3eq2} 0
+test expr-8.15 {CompileBitAndExpr: equality expr} {expr 2.0eq2} 0
+test expr-8.16 {CompileBitAndExpr: equality expr} {expr 3.2ne2.2} 1
+test expr-8.17 {CompileBitAndExpr: equality expr} {expr 01eq1} 0
+test expr-8.18 {CompileBitAndExpr: equality expr} {expr {"abc" eq "abd"}} 0
+test expr-8.19 {CompileBitAndExpr: equality expr} {expr {"abc" ne "abd"}} 1
+test expr-8.20 {CompileBitAndExpr: error in equality expr} -body {
+ expr x ne3
+} -returnCodes error -match glob -result *
+test expr-8.21 {CompileBitAndExpr: error in equality expr} -body {
+ # These should be ""ed to avoid the error
+ expr a eq b
+} -returnCodes error -match glob -result *
+test expr-8.22 {CompileBitAndExpr: error in equality expr} -body {
+ expr {false eqfalse}
+} -returnCodes error -match glob -result *
+test expr-8.23 {CompileBitAndExpr: error in equality expr} -body {
+ expr {false nefalse}
+} -returnCodes error -match glob -result *
+test expr-8.24 {CompileEqualityExpr: simple equality exprs} {
+ set x 12398712938788234
+ expr {$x == 100}
+} 0
+test expr-8.25 {CompileEqualityExpr: simple equality exprs} {
+ expr {"0x12 " == "0x12"}
+} 1
+test expr-8.26 {CompileEqualityExpr: simple equality exprs} {
+ expr {"0x12 " eq "0x12"}
+} 0
+test expr-8.27 {CompileEqualityExpr: simple equality exprs} {
+ expr {"1.0e100000000" == "0.0"}
+} 0
+test expr-8.28 {CompileEqualityExpr: just relational expr} {
+ expr {"0y" == "0x0"}
+} 0
+test expr-8.29 {CompileEqualityExpr: just relational expr} {
+ # Compare original strings from variables.
+ set v1 "0y"
+ set v2 "0x12"
+ expr {$v1 < $v2}
+} 0
+test expr-8.30 {CompileEqualityExpr: simple equality exprs} {
+ expr {"fake" != "bob"}
+} 1
+test expr-8.31 {expr edge cases} -body {
+ expr {1e}
+} -returnCodes error -match glob -result *
+test expr-8.32 {expr edge cases} -body {
+ expr {1E}
+} -returnCodes error -match glob -result *
+test expr-8.33 {expr edge cases} -body {
+ expr {1e+}
+} -returnCodes error -match glob -result *
+test expr-8.34 {expr edge cases} -body {
+ expr {1E+}
+} -returnCodes error -match glob -result *
+test expr-8.35 {expr edge cases} -body {
+ expr {1ea}
+} -returnCodes error -match glob -result *
+
+test expr-9.1 {CompileRelationalExpr: just shift expr} {expr 3<<2} 12
+test expr-9.2 {CompileRelationalExpr: just shift expr} {expr 0xff>>2} 63
+test expr-9.3 {CompileRelationalExpr: just shift expr} {expr -1>>2} -1
+test expr-9.4 {CompileRelationalExpr: just shift expr} {expr {1<<3}} 8
+test expr-9.5a {CompileRelationalExpr: shift expr producing LONG_MIN} longIs64bit {
+ expr {int(1<<63)}
+} -9223372036854775808
+test expr-9.5b {CompileRelationalExpr: shift expr producing LONG_MIN} longIs32bit {
+ expr {int(1<<31)}
+} -2147483648
+test expr-9.6 {CompileRelationalExpr: error in shift expr} -body {
+ expr x>>3
+} -returnCodes error -match glob -result *
+test expr-9.7 {CompileRelationalExpr: simple relational exprs} {expr 0xff>=+0x3} 1
+test expr-9.8 {CompileRelationalExpr: simple relational exprs} {expr -0xf2<0x3} 1
+test expr-9.9 {CompileRelationalExpr: error compiling relational arm} -body {
+ expr 2***3>6
+} -returnCodes error -match glob -result *
+test expr-9.10 {CompileRelationalExpr: error compiling relational arm} -body {
+ expr 2<x
+} -returnCodes error -match glob -result *
+
+test expr-10.1 {CompileShiftExpr: just add expr} {expr 4+-2} 2
+test expr-10.2 {CompileShiftExpr: just add expr} {expr 0xff-2} 253
+test expr-10.3 {CompileShiftExpr: just add expr} {expr -1--2} 1
+test expr-10.4 {CompileShiftExpr: just add expr} {expr 1-0o123} -82
+test expr-10.5 {CompileShiftExpr: error in add expr} -body {
+ expr x+3
+} -returnCodes error -match glob -result *
+test expr-10.6 {CompileShiftExpr: simple shift exprs} {expr 0xff>>0x3} 31
+test expr-10.7 {CompileShiftExpr: simple shift exprs} {expr -0xf2<<0x3} -1936
+test expr-10.8 {CompileShiftExpr: error compiling shift arm} -body {
+ expr 2***3>>6
+} -returnCodes error -match glob -result *
+test expr-10.9 {CompileShiftExpr: error compiling shift arm} -body {
+ expr 2<<x
+} -returnCodes error -match glob -result *
+test expr-10.10 {CompileShiftExpr: runtime error} {
+ list [catch {expr {24.0>>43}} msg] $msg
+} {1 {can't use floating-point value as operand of ">>"}}
+test expr-10.11 {CompileShiftExpr: runtime error} {
+ list [catch {expr {"a"<<"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "<<"}}
+
+test expr-11.1 {CompileAddExpr: just multiply expr} {expr 4*-2} -8
+test expr-11.2 {CompileAddExpr: just multiply expr} {expr 0xff%2} 1
+test expr-11.3 {CompileAddExpr: just multiply expr} {expr -1/2} -1
+test expr-11.4 {CompileAddExpr: just multiply expr} {expr 7891%0o123} 6
+test expr-11.5 {CompileAddExpr: error in multiply expr} -body {
+ expr x*3
+} -returnCodes error -match glob -result *
+test expr-11.6 {CompileAddExpr: simple add exprs} {expr 0xff++0x3} 258
+test expr-11.7 {CompileAddExpr: simple add exprs} {expr -0xf2--0x3} -239
+test expr-11.8 {CompileAddExpr: error compiling add arm} -body {
+ expr 2***3+6
+} -returnCodes error -match glob -result *
+test expr-11.9 {CompileAddExpr: error compiling add arm} -body {
+ expr 2-x
+} -returnCodes error -match glob -result *
+test expr-11.10 {CompileAddExpr: runtime error} {
+ list [catch {expr {24.0+"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-11.11 {CompileAddExpr: runtime error} {
+ list [catch {expr {"a"-"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+test expr-11.12 {CompileAddExpr: runtime error} {
+ list [catch {expr {3/0}} msg] $msg
+} {1 {divide by zero}}
+test expr-11.13a {CompileAddExpr: runtime error} !ieeeFloatingPoint {
+ list [catch {expr {2.3/0.0}} msg] $msg
+} {1 {divide by zero}}
+test expr-11.13b {CompileAddExpr: runtime error} ieeeFloatingPoint {
+ list [catch {expr {2.3/0.0}} msg] $msg
+} {0 Inf}
+
+test expr-12.1 {CompileMultiplyExpr: just unary expr} {expr ~4} -5
+test expr-12.2 {CompileMultiplyExpr: just unary expr} {expr --5} 5
+test expr-12.3 {CompileMultiplyExpr: just unary expr} {expr !27} 0
+test expr-12.4 {CompileMultiplyExpr: just unary expr} {expr ~0xff00ff} -16711936
+test expr-12.5 {CompileMultiplyExpr: error in unary expr} -body {
+ expr ~x
+} -returnCodes error -match glob -result *
+test expr-12.6 {CompileMultiplyExpr: simple multiply exprs} {expr 0xff*0x3} 765
+test expr-12.7 {CompileMultiplyExpr: simple multiply exprs} {expr -0xf2%-0x3} -2
+test expr-12.8 {CompileMultiplyExpr: error compiling multiply arm} -body {
+ expr 2*3%%6
+} -returnCodes error -match glob -result *
+test expr-12.9 {CompileMultiplyExpr: error compiling multiply arm} -body {
+ expr 2*x
+} -returnCodes error -match glob -result *
+test expr-12.10 {CompileMultiplyExpr: runtime error} {
+ list [catch {expr {24.0*"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "*"}}
+test expr-12.11 {CompileMultiplyExpr: runtime error} {
+ list [catch {expr {"a"/"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+
+test expr-13.1 {CompileUnaryExpr: unary exprs} {expr -0xff} -255
+test expr-13.2 {CompileUnaryExpr: unary exprs} {expr +0o00123} 83
+test expr-13.3 {CompileUnaryExpr: unary exprs} {expr +--++36} 36
+test expr-13.4 {CompileUnaryExpr: unary exprs} {expr !2} 0
+test expr-13.5 {CompileUnaryExpr: unary exprs} {expr +--+-62.0} -62.0
+test expr-13.6 {CompileUnaryExpr: unary exprs} {expr !0.0} 1
+test expr-13.7 {CompileUnaryExpr: unary exprs} {expr !0xef} 0
+test expr-13.8 {CompileUnaryExpr: error compiling unary expr} -body {
+ expr ~x
+} -returnCodes error -match glob -result *
+test expr-13.9 {CompileUnaryExpr: error compiling unary expr} -body {
+ expr !1.x
+} -returnCodes error -match glob -result *
+test expr-13.10 {CompileUnaryExpr: runtime error} {
+ list [catch {expr {~"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "~"}}
+test expr-13.11 {CompileUnaryExpr: runtime error} {
+ list [catch {expr ~4.0} msg] $msg
+} {1 {can't use floating-point value as operand of "~"}}
+test expr-13.12 {CompileUnaryExpr: just primary expr} {expr 0x123} 291
+test expr-13.13 {CompileUnaryExpr: just primary expr} {
+ set a 27
+ expr $a
+} 27
+test expr-13.14 {CompileUnaryExpr: just primary expr} {
+ expr double(27)
+} 27.0
+test expr-13.15 {CompileUnaryExpr: just primary expr} {expr "123"} 123
+test expr-13.16 {CompileUnaryExpr: error in primary expr} {
+ catch {expr [set]} msg
+ set msg
+} {wrong # args: should be "set varName ?newValue?"}
+test expr-13.17 {CompileUnaryExpr: negating non-numeric boolean literals} {
+ set a1 yes; set a0 no; set b1 true; set b0 false
+ list [expr {!$a1}] [expr {!$a0}] [expr {!$b1}] [expr {!$b0}]
+} {0 1 0 1}
+
+test expr-14.1 {CompilePrimaryExpr: literal primary} {expr 1} 1
+test expr-14.2 {CompilePrimaryExpr: literal primary} {expr 123} 123
+test expr-14.3 {CompilePrimaryExpr: literal primary} {expr 0xff} 255
+test expr-14.4 {CompilePrimaryExpr: literal primary} {expr 0o0010} 8
+test expr-14.5 {CompilePrimaryExpr: literal primary} {expr 62.0} 62.0
+test expr-14.6 {CompilePrimaryExpr: literal primary} {
+ expr 3.1400000
+} 3.14
+test expr-14.7 {CompilePrimaryExpr: literal primary} {expr {{abcde}<{abcdef}}} 1
+test expr-14.8 {CompilePrimaryExpr: literal primary} {expr {{abc\
+def} < {abcdef}}} 1
+test expr-14.9 {CompilePrimaryExpr: literal primary} {expr {{abc\tde} > {abc\tdef}}} 0
+test expr-14.10 {CompilePrimaryExpr: literal primary} {expr {{123}}} 123
+test expr-14.11 {CompilePrimaryExpr: var reference primary} {
+ set i 789
+ list [expr {$i}] [expr $i]
+} {789 789}
+test expr-14.12 {CompilePrimaryExpr: var reference primary} {
+ set i {789} ;# test expr's aggressive conversion to numeric semantics
+ list [expr {$i}] [expr $i]
+} {789 789}
+test expr-14.13 {CompilePrimaryExpr: var reference primary} {
+ catch {unset a}
+ set a(foo) foo
+ set a(bar) bar
+ set a(123) 123
+ set result ""
+ lappend result [expr $a(123)] [expr {$a(bar)<$a(foo)}]
+ catch {unset a}
+ set result
+} {123 1}
+test expr-14.14 {CompilePrimaryExpr: var reference primary} {
+ set i 123 ;# test "$var.0" floating point conversion hack
+ list [expr $i] [expr $i.0] [expr $i.0/12.0]
+} {123 123.0 10.25}
+test expr-14.15 {CompilePrimaryExpr: var reference primary} {
+ set i 123
+ catch {expr $i.2} msg
+ set msg
+} 123.2
+test expr-14.16 {CompilePrimaryExpr: error compiling var reference primary} -body {
+ expr {$a(foo}
+} -returnCodes error -match glob -result *
+test expr-14.17 {CompilePrimaryExpr: string primary that looks like var ref} -body {
+ expr $
+} -returnCodes error -match glob -result *
+test expr-14.18 {CompilePrimaryExpr: quoted string primary} {
+ expr "21"
+} 21
+test expr-14.19 {CompilePrimaryExpr: quoted string primary} {
+ set i 123
+ set x 456
+ expr "$i+$x"
+} 579
+test expr-14.20 {CompilePrimaryExpr: quoted string primary} {
+ set i 3
+ set x 6
+ expr 2+"$i.$x"
+} 5.6
+test expr-14.21 {CompilePrimaryExpr: error in quoted string primary} {
+ catch {expr "[set]"} msg
+ set msg
+} {wrong # args: should be "set varName ?newValue?"}
+test expr-14.22 {CompilePrimaryExpr: subcommand primary} {
+ expr {[set i 123; set i]}
+} 123
+test expr-14.23 {CompilePrimaryExpr: error in subcommand primary} -body {
+ catch {expr {[set]}} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test expr-14.24 {CompilePrimaryExpr: error in subcommand primary} -body {
+ expr {[set i}
+} -returnCodes error -match glob -result *
+test expr-14.25 {CompilePrimaryExpr: math function primary} {
+ format %.6g [expr exp(1.0)]
+} 2.71828
+test expr-14.26 {CompilePrimaryExpr: math function primary} {
+ format %.6g [expr pow(2.0+0.1,3.0+0.1)]
+} 9.97424
+test expr-14.27 {CompilePrimaryExpr: error in math function primary} -body {
+ expr sinh::(2.0)
+} -returnCodes error -match glob -result *
+test expr-14.28 {CompilePrimaryExpr: subexpression primary} {
+ expr 2+(3*4)
+} 14
+test expr-14.29 {CompilePrimaryExpr: error in subexpression primary} -body {
+ catch {expr 2+(3*[set])} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test expr-14.30 {CompilePrimaryExpr: missing paren in subexpression primary} -body {
+ expr 2+(3*(4+5)
+} -returnCodes error -match glob -result *
+test expr-14.31 {CompilePrimaryExpr: just var ref in subexpression primary} {
+ set i "5+10"
+ list "[expr $i] == 15" "[expr ($i)] == 15" "[eval expr ($i)] == 15"
+} {{15 == 15} {15 == 15} {15 == 15}}
+test expr-14.32 {CompilePrimaryExpr: unexpected token} -body {
+ expr @
+} -returnCodes error -match glob -result *
+
+test expr-15.1 {CompileMathFuncCall: missing parenthesis} -body {
+ expr sinh2.0)
+} -returnCodes error -match glob -result *
+test expr-15.2 {CompileMathFuncCall: unknown math function} -body {
+ catch {expr whazzathuh(1)} msg
+ set ::errorInfo
+} -match glob -result {* "*whazzathuh"
+ while *ing
+"expr whazzathuh(1)"}
+test expr-15.3 {CompileMathFuncCall: too many arguments} -body {
+ catch {expr sin(1,2,3)} msg
+ set ::errorInfo
+} -match glob -result {too many arguments for math function*
+ while *ing
+"expr sin(1,2,3)"}
+test expr-15.4 {CompileMathFuncCall: ')' found before last required arg} -body {
+ catch {expr sin()} msg
+ set ::errorInfo
+} -match glob -result {too few arguments for math function*
+ while *ing
+"expr sin()"}
+test expr-15.5 {CompileMathFuncCall: too few arguments} -body {
+ catch {expr pow(1)} msg
+ set ::errorInfo
+} -match glob -result {too few arguments for math function*
+ while *ing
+"expr pow(1)"}
+test expr-15.6 {CompileMathFuncCall: missing ')'} -body {
+ expr sin(1
+} -returnCodes error -match glob -result *
+test expr-15.7 {CompileMathFuncCall: call registered math function} {testmathfunctions} {
+ expr 2*T1()
+} 246
+test expr-15.8 {CompileMathFuncCall: call registered math function} {testmathfunctions} {
+ expr T2()*3
+} 1035
+test expr-15.9 {CompileMathFuncCall: call registered math function} {testmathfunctions} {
+ expr T3(21, 37)
+} 37
+test expr-15.10 {CompileMathFuncCall: call registered math function} {testmathfunctions} {
+ expr T3(21.2, 37)
+} 37.0
+test expr-15.11 {CompileMathFuncCall: call registered math function} {testmathfunctions} {
+ expr T3(-21.2, -17.5)
+} -17.5
+test expr-15.12 {ExprCallMathFunc: call registered math function} {testmathfunctions} {
+ expr T3(21, wide(37))
+} 37
+test expr=15.13 {ExprCallMathFunc: call registered math function} {testmathfunctions} {
+ expr T3(wide(21), 37)
+} 37
+test expr=15.14 {ExprCallMathFunc: call registered math function} {testmathfunctions} {
+ expr T3(wide(21), wide(37))
+} 37
+test expr-15.15 {ExprCallMathFunc: call registered math function} {testmathfunctions} {
+ expr T3(21.0, wide(37))
+} 37.0
+test expr-15.16 {ExprCallMathFunc: call registered math function} {testmathfunctions} {
+ expr T3(wide(21), 37.0)
+} 37.0
+test expr-15.17 {ExprCallMathFunc: non-numeric arg} -constraints {
+ testmathfunctions
+} -body {
+ expr T3(0,"a")
+} -returnCodes error -result {argument to math function didn't have numeric value}
+
+
+test expr-16.1 {GetToken: checks whether integer token starting with "0x" (e.g., "0x$") is invalid} {
+ catch {unset a}
+ set a(VALUE) ff15
+ set i 123
+ if {[expr 0x$a(VALUE)] & 16} {
+ set i {}
+ }
+ set i
+} {}
+test expr-16.2 {GetToken: check for string literal in braces} {
+ expr {{1}}
+} {1}
+
+# Check "expr" and computed command names.
+
+test expr-17.1 {expr and computed command names} {
+ set i 0
+ set z expr
+ $z 1+2
+} 3
+
+# Check correct conversion of operands to numbers: If the string looks like
+# an integer, convert to integer. Otherwise, if the string looks like a
+# double, convert to double.
+
+test expr-18.1 {expr and conversion of operands to numbers} {
+ set x [lindex 11 0]
+ catch {expr int($x)}
+ expr {$x}
+} 11
+test expr-18.2 {whitespace strings should not be == 0 (buggy strtod)} {
+ expr {" "}
+} { }
+
+# Check "expr" and interpreter result object resetting before appending
+# an error msg during evaluation of exprs not in {}s
+
+test expr-19.1 {expr and interpreter result object resetting} {
+ proc p {} {
+ set t 10.0
+ set x 2.0
+ set dx 0.2
+ set f {$dx-$x/10}
+ set g {-$x/5}
+ set center 1.0
+ set x [expr $x-$center]
+ set dx [expr $dx+$g]
+ set x [expr $x+$f+$center]
+ set x [expr $x+$f+$center]
+ set y [expr round($x)]
+ }
+ p
+} 3
+
+# Test for incorrect "double evaluation" semantics
+
+test expr-20.1 {wrong brace matching} {
+ catch {unset l}
+ catch {unset r}
+ catch {unset q}
+ catch {unset cmd}
+ catch {unset a}
+ set l "\{"; set r "\}"; set q "\""
+ set cmd "expr $l$q|$q == $q$r$q$r"
+ list [catch $cmd a] $a
+} {1 {extra characters after close-brace}}
+test expr-20.2 {double invocation of variable traces} -body {
+ set exprtracecounter 0
+ proc exprtraceproc {args} {
+ upvar #0 exprtracecounter counter
+ set argc [llength $args]
+ set extraargs [lrange $args 0 [expr {$argc - 4}]]
+ set name [lindex $args [expr {$argc - 3}]]
+ upvar 1 $name var
+ if {[incr counter] % 2 == 1} {
+ set var "$counter oops [concat $extraargs]"
+ } else {
+ set var "$counter + [concat $extraargs]"
+ }
+ }
+ trace variable exprtracevar r [list exprtraceproc 10]
+ list [catch {expr "$exprtracevar + 20"} a] $a \
+ [catch {expr "$exprtracevar + 20"} b] $b \
+ [unset exprtracevar exprtracecounter]
+} -match glob -result {1 * 0 32 {}}
+test expr-20.3 {broken substitution of integer digits} {
+ # fails with 8.0.x, but not 8.1b2
+ list [set a 000; expr 0x1$a] [set a 1; expr ${a}000]
+} {4096 1000}
+test expr-20.4 {proper double evaluation compilation, error case} {
+ catch {unset a}; # make sure $a doesn't exist
+ list [catch {expr 1?{$a}:0} msg] $msg
+} {1 {can't read "a": no such variable}}
+test expr-20.5 {proper double evaluation compilation, working case} {
+ set a yellow
+ expr 1?{$a}:0
+} yellow
+test expr-20.6 {handling of compile error in trial compile} {
+ list [catch {expr + {[incr]}} msg] $msg
+} {1 {wrong # args: should be "incr varName ?increment?"}}
+test expr-20.7 {handling of compile error in runtime case} {
+ list [catch {expr + {[error foo]}} msg] $msg
+} {1 foo}
+
+# Test for non-numeric boolean literal handling
+test expr-21.1 {non-numeric boolean literals} {expr false } false
+test expr-21.2 {non-numeric boolean literals} {expr true } true
+test expr-21.3 {non-numeric boolean literals} {expr off } off
+test expr-21.4 {non-numeric boolean literals} {expr on } on
+test expr-21.5 {non-numeric boolean literals} {expr no } no
+test expr-21.6 {non-numeric boolean literals} {expr yes } yes
+test expr-21.7 {non-numeric boolean literals} {expr !false} 1
+test expr-21.8 {non-numeric boolean literals} {expr !true } 0
+test expr-21.9 {non-numeric boolean literals} {expr !off } 1
+test expr-21.10 {non-numeric boolean literals} {expr !on } 0
+test expr-21.11 {non-numeric boolean literals} {expr !no } 1
+test expr-21.12 {non-numeric boolean literals} {expr !yes } 0
+test expr-21.13 {non-numeric boolean literals} -body {
+ expr !truef
+} -returnCodes error -match glob -result *
+test expr-21.14 {non-numeric boolean literals} {
+ list [catch {expr !"truef"} err] $err
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-21.15 {non-numeric boolean variables} {
+ set v truef
+ list [catch {expr {!$v}} err] $err
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-21.16 {non-numeric boolean variables} {
+ set v "true "
+ list [catch {expr {!$v}} err] $err
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-21.17 {non-numeric boolean variables} {
+ set v "tru"
+ list [catch {expr {!$v}} err] $err
+} {0 0}
+test expr-21.18 {non-numeric boolean variables} {
+ set v "fal"
+ list [catch {expr {!$v}} err] $err
+} {0 1}
+test expr-21.19 {non-numeric boolean variables} {
+ set v "y"
+ list [catch {expr {!$v}} err] $err
+} {0 0}
+test expr-21.20 {non-numeric boolean variables} {
+ set v "of"
+ list [catch {expr {!$v}} err] $err
+} {0 1}
+test expr-21.21 {non-numeric boolean variables} {
+ set v "o"
+ list [catch {expr {!$v}} err] $err
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-21.22 {non-numeric boolean variables} {
+ set v ""
+ list [catch {expr {!$v}} err] $err
+} {1 {can't use empty string as operand of "!"}}
+
+# Test for non-numeric float handling.
+test expr-22.1 {non-numeric floats} {
+ list [catch {expr {NaN + 1}} msg] $msg
+} {1 {can't use non-numeric floating-point value as operand of "+"}}
+test expr-22.2 {non-numeric floats} !ieeeFloatingPoint {
+ list [catch {expr {Inf + 1}} msg] $msg
+} {1 {can't use infinite floating-point value as operand of "+"}}
+test expr-22.3 {non-numeric floats} {
+ set nan NaN
+ list [catch {expr {$nan + 1}} msg] $msg
+} {1 {can't use non-numeric floating-point value as operand of "+"}}
+test expr-22.4 {non-numeric floats} !ieeeFloatingPoint {
+ set inf Inf
+ list [catch {expr {$inf + 1}} msg] $msg
+} {1 {can't use infinite floating-point value as operand of "+"}}
+test expr-22.5 {non-numeric floats} {
+ list [catch {expr NaN} msg] $msg
+} {1 {domain error: argument not in valid range}}
+test expr-22.6 {non-numeric floats} !ieeeFloatingPoint {
+ list [catch {expr Inf} msg] $msg
+} {1 {floating-point value too large to represent}}
+test expr-22.7 {non-numeric floats} {
+ list [catch {expr {1 / NaN}} msg] $msg
+} {1 {can't use non-numeric floating-point value as operand of "/"}}
+test expr-22.8 {non-numeric floats} !ieeeFloatingPoint {
+ list [catch {expr {1 / Inf}} msg] $msg
+} {1 {can't use infinite floating-point value as operand of "/"}}
+# Make sure [Bug 761471] stays fixed.
+test expr-22.9 {non-numeric floats: shared object equality and NaN} {
+ set x NaN
+ expr {$x == $x}
+} 0
+
+# Tests for exponentiation handling
+test expr-23.1 {CompileExponentialExpr: just exponential expr} {expr 4**2} 16
+test expr-23.2 {CompileExponentialExpr: just exponential expr} {expr 0xff**2} 65025
+test expr-23.3 {CompileExponentialExpr: just exponential expr} {expr -1**2} 1
+test expr-23.4 {CompileExponentialExpr: just exponential expr} {expr 18**07} 612220032
+test expr-23.5 {CompileExponentialExpr: error in exponential expr} -body {
+ expr x**3
+} -returnCodes error -match glob -result *
+test expr-23.6 {CompileExponentialExpr: simple expo exprs} {expr 0xff**0x3} 16581375
+test expr-23.7 {CompileExponentialExpr: error compiling expo arm} -body {
+ expr (-3-)**6
+} -returnCodes error -match glob -result *
+test expr-23.8 {CompileExponentialExpr: error compiling expo arm} -body {
+ expr 2**x
+} -returnCodes error -match glob -result *
+test expr-23.9 {CompileExponentialExpr: runtime error} {
+ list [catch {expr {24.0**"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "**"}}
+test expr-23.10 {CompileExponentialExpr: runtime error} {
+ list [catch {expr {"a"**2}} msg] $msg
+} {1 {can't use non-numeric string as operand of "**"}}
+test expr-23.11 {CompileExponentialExpr: runtime error} {
+ list [catch {expr {0**-1}} msg] $msg
+} {1 {exponentiation of zero by negative power}}
+test expr-23.12 {CompileExponentialExpr: runtime error} {
+ list [catch {expr {0.0**-1.0}} msg] $msg
+} {1 {exponentiation of zero by negative power}}
+test expr-23.13 {CompileExponentialExpr: runtime error} {
+ list [catch {expr {wide(0)**wide(-1)}} msg] $msg
+} {1 {exponentiation of zero by negative power}}
+test expr-23.14 {INST_EXPON: special cases} {expr {0**1}} 0
+test expr-23.15 {INST_EXPON: special cases} {expr {0**0}} 1
+test expr-23.16 {INST_EXPON: special cases} {expr {-2**-1}} 0
+test expr-23.17 {INST_EXPON: special cases} {expr {-2**0}} 1
+test expr-23.18 {INST_EXPON: special cases} {expr {-1**1}} -1
+test expr-23.19 {INST_EXPON: special cases} {expr {-1**0}} 1
+test expr-23.20 {INST_EXPON: special cases} {expr {-1**2}} 1
+test expr-23.21 {INST_EXPON: special cases} {expr {-1**-1}} -1
+test expr-23.22 {INST_EXPON: special cases} {expr {1**1234567}} 1
+test expr-23.23 {INST_EXPON: special cases} {expr {2**-2}} 0
+test expr-23.24 {INST_EXPON: special cases} {expr {wide(0)**wide(1)}} 0
+test expr-23.25 {INST_EXPON: special cases} {expr {wide(0)**wide(0)}} 1
+test expr-23.26 {INST_EXPON: special cases} {expr {wide(-2)**wide(-1)}} 0
+test expr-23.27 {INST_EXPON: special cases} {expr {wide(-2)**wide(0)}} 1
+test expr-23.28 {INST_EXPON: special cases} {expr {wide(-1)**wide(1)}} -1
+test expr-23.29 {INST_EXPON: special cases} {expr {wide(-1)**wide(0)}} 1
+test expr-23.30 {INST_EXPON: special cases} {expr {wide(-1)**wide(2)}} 1
+test expr-23.31 {INST_EXPON: special cases} {expr {wide(-1)**wide(-1)}} -1
+test expr-23.32 {INST_EXPON: special cases} {expr {wide(1)**wide(1234567)}} 1
+test expr-23.33 {INST_EXPON: special cases} {expr {wide(2)**wide(-2)}} 0
+test expr-23.34 {INST_EXPON: special cases} {expr {2**0}} 1
+test expr-23.35 {INST_EXPON: special cases} {expr {wide(2)**0}} 1
+test expr-23.36 {INST_EXPON: big integer} {expr {10**17}} 1[string repeat 0 17]
+test expr-23.37 {INST_EXPON: big integer} {expr {10**18}} 1[string repeat 0 18]
+test expr-23.38 {INST_EXPON: big integer} {expr {10**19}} 1[string repeat 0 19]
+test expr-23.39 {INST_EXPON: big integer} {
+ expr 1[string repeat 0 30]**2
+} 1[string repeat 0 60]
+test expr-23.40 {INST_EXPON: overflow to big integer} {expr {(-10)**3}} -1000
+test expr-23.41 {INST_EXPON: overflow to big integer} {expr 2**64} [expr 1<<64]
+test expr-23.42 {INST_EXPON: overflow to big integer} {expr 4**32} [expr 1<<64]
+test expr-23.43 {INST_EXPON: overflow to big integer} {expr 16**16} [expr 1<<64]
+test expr-23.44 {INST_EXPON: overflow to big integer} {expr 256**8} [expr 1<<64]
+test expr-23.45 {INST_EXPON: Bug 1555371} {expr 2**1} 2
+test expr-23.46 {INST_EXPON: Bug 1561260} -body {
+ expr 5**28
+} -match glob -result *5
+test expr-23.47 {INST_EXPON: Bug 1561260} {
+ expr 2**32*5**32
+} 1[string repeat 0 32]
+test expr-23.48 {INST_EXPON: TIP 274: right assoc} {
+expr 2**3**4
+} 2417851639229258349412352
+test expr-23.49 {INST_EXPON: optimize powers of 2} {
+ set trouble {test powers of 2}
+ for {set tval 0} {$tval <= 66} {incr tval} {
+ set is [expr {2 ** $tval}]
+ set sb [expr {1 << $tval}]
+ if {$is != $sb} {
+ append trouble \n "2**" $tval " is " $is " should be " $sb
+ }
+ if {$tval >= 1} {
+ set is [expr {-2 ** $tval}]
+ set sb [expr {1 << $tval}]
+ if {$tval & 1} {
+ set sb [expr {-$sb}]
+ }
+ if {$is != $sb} {
+ append trouble \n "-2**" $tval " is " $is " should be " $sb
+ }
+ }
+ }
+ set trouble
+} {test powers of 2}
+test expr-23.50 {INST_EXPON: small powers of 32-bit integers} {
+ set trouble {test small powers of 32-bit ints}
+ for {set base 3} {$base <= 45} {incr base} {
+ set sb $base
+ set sbm [expr {-$base}]
+ for {set expt 2} {$expt <= 8} {incr expt} {
+ set sb [expr {$sb * $base}]
+ set is [expr {$base ** $expt}]
+ if {$sb != $is} {
+ append trouble \n $base ** $expt " is " $is " should be " $sb
+ }
+ set sbm [expr {-$sbm * $base}]
+ set ism [expr {(-$base) ** $expt}]
+ if {$sbm != $ism} {
+ append trouble \n - $base ** $expt " is " $ism \
+ " should be " $sbm
+ }
+ }
+ }
+ set trouble
+} {test small powers of 32-bit ints}
+test expr-23.51 {INST_EXPON: intermediate powers of 32-bit integers} {
+ set trouble {test intermediate powers of 32-bit ints}
+ for {set base 3} {$base <= 11} {incr base} {
+ set sb [expr {$base ** 8}]
+ set sbm $sb
+ for {set expt 9} {$expt <= 21} {incr expt} {
+ set sb [expr {$sb * $base}]
+ set sbm [expr {$sbm * -$base}]
+ set is [expr {$base ** $expt}]
+ set ism [expr {-$base ** $expt}]
+ if {$sb != $is} {
+ append trouble \n $base ** $expt " is " $is " should be " $sb
+ }
+ if {$sbm != $ism} {
+ append trouble \n - $base ** $expt " is " $ism \
+ " should be " $sbm
+ }
+ }
+ }
+ set trouble
+} {test intermediate powers of 32-bit ints}
+test expr-23.52 {INST_EXPON: small integer powers with 64-bit results} {
+ set trouble {test small int powers with 64-bit results}
+ for {set exp 2} {$exp <= 16} {incr exp} {
+ set base [expr {entier(pow(double(0x7fffffffffffffff),(1.0/$exp)))}]
+ set sb 1
+ set sbm 1
+ for {set i 0} {$i < $exp} {incr i} {
+ set sb [expr {$sb * $base}]
+ set sbm [expr {$sbm * -$base}]
+ }
+ set is [expr {$base ** $exp}]
+ set ism [expr {-$base ** $exp}]
+ if {$sb != $is} {
+ append trouble \n $base ** $exp " is " $is " should be " $sb
+ }
+ if {$sbm != $ism} {
+ append trouble \n - $base ** $exp " is " $ism " should be " $sbm
+ }
+ incr base
+ set sb 1
+ set sbm 1
+ for {set i 0} {$i < $exp} {incr i} {
+ set sb [expr {$sb * $base}]
+ set sbm [expr {$sbm * -$base}]
+ }
+ set is [expr {$base ** $exp}]
+ set ism [expr {-$base ** $exp}]
+ if {$sb != $is} {
+ append trouble \n $base ** $exp " is " $is " should be " $sb
+ }
+ if {$sbm != $ism} {
+ append trouble \n - $base ** $exp " is " $ism " should be " $sbm
+ }
+ }
+ set trouble
+} {test small int powers with 64-bit results}
+test expr-23.53 {INST_EXPON: intermediate powers of 64-bit integers} {
+ set trouble {test intermediate powers of 64-bit ints}
+ for {set base 3} {$base <= 13} {incr base} {
+ set sb [expr {$base ** 15}]
+ set sbm [expr {-$sb}]
+ for {set expt 16} {$expt <= 39} {incr expt} {
+ set sb [expr {$sb * $base}]
+ set sbm [expr {$sbm * -$base}]
+ set is [expr {$base ** $expt}]
+ set ism [expr {-$base ** $expt}]
+ if {$sb != $is} {
+ append trouble \n $base ** $expt " is " $is " should be " $sb
+ }
+ if {$sbm != $ism} {
+ append trouble \n - $base ** $expt " is " $ism \
+ " should be " $sbm
+ }
+ }
+ }
+ set trouble
+} {test intermediate powers of 64-bit ints}
+test expr-23.54.0 {INST_EXPON: Bug 2798543} {
+ expr {3**9 == 3**65545}
+} 0
+test expr-23.54.1 {INST_EXPON: Bug 2798543} {
+ expr {3**10 == 3**65546}
+} 0
+test expr-23.54.2 {INST_EXPON: Bug 2798543} {
+ expr {3**11 == 3**65547}
+} 0
+test expr-23.54.3 {INST_EXPON: Bug 2798543} {
+ expr {3**12 == 3**65548}
+} 0
+test expr-23.54.4 {INST_EXPON: Bug 2798543} {
+ expr {3**13 == 3**65549}
+} 0
+test expr-23.54.5 {INST_EXPON: Bug 2798543} {
+ expr {3**14 == 3**65550}
+} 0
+test expr-23.54.6 {INST_EXPON: Bug 2798543} {
+ expr {3**15 == 3**65551}
+} 0
+test expr-23.54.7 {INST_EXPON: Bug 2798543} {
+ expr {3**16 == 3**65552}
+} 0
+test expr-23.54.8 {INST_EXPON: Bug 2798543} {
+ expr {3**17 == 3**65553}
+} 0
+test expr-23.54.9 {INST_EXPON: Bug 2798543} {
+ expr {3**18 == 3**65554}
+} 0
+test expr-23.54.10 {INST_EXPON: Bug 2798543} {
+ expr {3**19 == 3**65555}
+} 0
+test expr-23.54.11 {INST_EXPON: Bug 2798543} {
+ expr {3**9 == 3**131081}
+} 0
+test expr-23.54.12 {INST_EXPON: Bug 2798543} -body {
+ expr {3**9 == 3**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.54.13 {INST_EXPON: Bug 2798543} {
+ expr {(-3)**9 == (-3)**65545}
+} 0
+test expr-23.55.0 {INST_EXPON: Bug 2798543} {
+ expr {4**9 == 4**65545}
+} 0
+test expr-23.55.1 {INST_EXPON: Bug 2798543} {
+ expr {4**15 == 4**65551}
+} 0
+test expr-23.55.2 {INST_EXPON: Bug 2798543} {
+ expr {4**9 == 4**131081}
+} 0
+test expr-23.55.3 {INST_EXPON: Bug 2798543} -body {
+ expr {4**9 == 4**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.55.4 {INST_EXPON: Bug 2798543} {
+ expr {(-4)**9 == (-4)**65545}
+} 0
+test expr-23.56.0 {INST_EXPON: Bug 2798543} {
+ expr {5**9 == 5**65545}
+} 0
+test expr-23.56.1 {INST_EXPON: Bug 2798543} {
+ expr {5**13 == 5**65549}
+} 0
+test expr-23.56.2 {INST_EXPON: Bug 2798543} {
+ expr {5**9 == 5**131081}
+} 0
+test expr-23.56.3 {INST_EXPON: Bug 2798543} -body {
+ expr {5**9 == 5**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.56.4 {INST_EXPON: Bug 2798543} {
+ expr {(-5)**9 == (-5)**65545}
+} 0
+test expr-23.57.0 {INST_EXPON: Bug 2798543} {
+ expr {6**9 == 6**65545}
+} 0
+test expr-23.57.1 {INST_EXPON: Bug 2798543} {
+ expr {6**11 == 6**65547}
+} 0
+test expr-23.57.2 {INST_EXPON: Bug 2798543} {
+ expr {6**9 == 6**131081}
+} 0
+test expr-23.57.3 {INST_EXPON: Bug 2798543} -body {
+ expr {6**9 == 6**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.57.4 {INST_EXPON: Bug 2798543} {
+ expr {(-6)**9 == (-6)**65545}
+} 0
+test expr-23.58.0 {INST_EXPON: Bug 2798543} {
+ expr {7**9 == 7**65545}
+} 0
+test expr-23.58.1 {INST_EXPON: Bug 2798543} {
+ expr {7**11 == 7**65547}
+} 0
+test expr-23.58.2 {INST_EXPON: Bug 2798543} {
+ expr {7**9 == 7**131081}
+} 0
+test expr-23.58.3 {INST_EXPON: Bug 2798543} -body {
+ expr {7**9 == 7**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.58.4 {INST_EXPON: Bug 2798543} {
+ expr {(-7)**9 == (-7)**65545}
+} 0
+test expr-23.59.0 {INST_EXPON: Bug 2798543} {
+ expr {8**9 == 8**65545}
+} 0
+test expr-23.59.1 {INST_EXPON: Bug 2798543} {
+ expr {8**10 == 8**65546}
+} 0
+test expr-23.59.2 {INST_EXPON: Bug 2798543} {
+ expr {8**9 == 8**131081}
+} 0
+test expr-23.59.3 {INST_EXPON: Bug 2798543} -body {
+ expr {8**9 == 8**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.59.4 {INST_EXPON: Bug 2798543} {
+ expr {(-8)**9 == (-8)**65545}
+} 0
+test expr-23.60.0 {INST_EXPON: Bug 2798543} {
+ expr {9**9 == 9**65545}
+} 0
+test expr-23.60.1 {INST_EXPON: Bug 2798543} {
+ expr {9**9 == 9**131081}
+} 0
+test expr-23.60.2 {INST_EXPON: Bug 2798543} -body {
+ expr {9**9 == 9**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.60.3 {INST_EXPON: Bug 2798543} {
+ expr {(-9)**9 == (-9)**65545}
+} 0
+test expr-23.61.0 {INST_EXPON: Bug 2798543} {
+ expr {10**9 == 10**65545}
+} 0
+test expr-23.61.1 {INST_EXPON: Bug 2798543} {
+ expr {10**9 == 10**131081}
+} 0
+test expr-23.61.2 {INST_EXPON: Bug 2798543} -body {
+ expr {10**9 == 10**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.61.3 {INST_EXPON: Bug 2798543} {
+ expr {(-10)**9 == (-10)**65545}
+} 0
+test expr-23.62.0 {INST_EXPON: Bug 2798543} {
+ expr {11**9 == 11**65545}
+} 0
+test expr-23.62.1 {INST_EXPON: Bug 2798543} {
+ expr {11**9 == 11**131081}
+} 0
+test expr-23.62.2 {INST_EXPON: Bug 2798543} -body {
+ expr {11**9 == 11**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.62.3 {INST_EXPON: Bug 2798543} {
+ expr {(-11)**9 == (-11)**65545}
+} 0
+test expr-23.63.0 {INST_EXPON: Bug 2798543} {
+ expr {3**20 == 3**65556}
+} 0
+test expr-23.63.1 {INST_EXPON: Bug 2798543} {
+ expr {3**39 == 3**65575}
+} 0
+test expr-23.63.2 {INST_EXPON: Bug 2798543} {
+ expr {3**20 == 3**131092}
+} 0
+test expr-23.63.3 {INST_EXPON: Bug 2798543} -body {
+ expr {3**20 == 3**268435476}
+} -returnCodes error -result {exponent too large}
+test expr-23.63.4 {INST_EXPON: Bug 2798543} {
+ expr {(-3)**20 == (-3)**65556}
+} 0
+test expr-23.64.0 {INST_EXPON: Bug 2798543} {
+ expr {4**17 == 4**65553}
+} 0
+test expr-23.64.1 {INST_EXPON: Bug 2798543} {
+ expr {4**31 == 4**65567}
+} 0
+test expr-23.64.2 {INST_EXPON: Bug 2798543} {
+ expr {4**17 == 4**131089}
+} 0
+test expr-23.64.3 {INST_EXPON: Bug 2798543} -body {
+ expr {4**17 == 4**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.64.4 {INST_EXPON: Bug 2798543} {
+ expr {(-4)**17 == (-4)**65553}
+} 0
+test expr-23.65.0 {INST_EXPON: Bug 2798543} {
+ expr {5**17 == 5**65553}
+} 0
+test expr-23.65.1 {INST_EXPON: Bug 2798543} {
+ expr {5**27 == 5**65563}
+} 0
+test expr-23.65.2 {INST_EXPON: Bug 2798543} {
+ expr {5**17 == 5**131089}
+} 0
+test expr-23.65.3 {INST_EXPON: Bug 2798543} -body {
+ expr {5**17 == 5**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.65.4 {INST_EXPON: Bug 2798543} {
+ expr {(-5)**17 == (-5)**65553}
+} 0
+test expr-23.66.0 {INST_EXPON: Bug 2798543} {
+ expr {6**17 == 6**65553}
+} 0
+test expr-23.66.1 {INST_EXPON: Bug 2798543} {
+ expr {6**24 == 6**65560}
+} 0
+test expr-23.66.2 {INST_EXPON: Bug 2798543} {
+ expr {6**17 == 6**131089}
+} 0
+test expr-23.66.3 {INST_EXPON: Bug 2798543} -body {
+ expr {6**17 == 6**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.66.4 {INST_EXPON: Bug 2798543} {
+ expr {(-6)**17 == (-6)**65553}
+} 0
+test expr-23.67.0 {INST_EXPON: Bug 2798543} {
+ expr {7**17 == 7**65553}
+} 0
+test expr-23.67.1 {INST_EXPON: Bug 2798543} {
+ expr {7**22 == 7**65558}
+} 0
+test expr-23.67.2 {INST_EXPON: Bug 2798543} {
+ expr {7**17 == 7**131089}
+} 0
+test expr-23.67.3 {INST_EXPON: Bug 2798543} -body {
+ expr {7**17 == 7**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.67.4 {INST_EXPON: Bug 2798543} {
+ expr {(-7)**17 == (-7)**65553}
+} 0
+test expr-23.68.0 {INST_EXPON: Bug 2798543} {
+ expr {8**17 == 8**65553}
+} 0
+test expr-23.68.1 {INST_EXPON: Bug 2798543} {
+ expr {8**20 == 8**65556}
+} 0
+test expr-23.68.2 {INST_EXPON: Bug 2798543} {
+ expr {8**17 == 8**131089}
+} 0
+test expr-23.68.3 {INST_EXPON: Bug 2798543} -body {
+ expr {8**17 == 8**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.68.4 {INST_EXPON: Bug 2798543} {
+ expr {(-8)**17 == (-8)**65553}
+} 0
+test expr-23.69.0 {INST_EXPON: Bug 2798543} {
+ expr {9**17 == 9**65553}
+} 0
+test expr-23.69.1 {INST_EXPON: Bug 2798543} {
+ expr {9**19 == 9**65555}
+} 0
+test expr-23.69.2 {INST_EXPON: Bug 2798543} {
+ expr {9**17 == 9**131089}
+} 0
+test expr-23.69.3 {INST_EXPON: Bug 2798543} -body {
+ expr {9**17 == 9**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.69.4 {INST_EXPON: Bug 2798543} {
+ expr {(-9)**17 == (-9)**65553}
+} 0
+test expr-23.70.0 {INST_EXPON: Bug 2798543} {
+ expr {10**17 == 10**65553}
+} 0
+test expr-23.70.1 {INST_EXPON: Bug 2798543} {
+ expr {10**18 == 10**65554}
+} 0
+test expr-23.70.2 {INST_EXPON: Bug 2798543} {
+ expr {10**17 == 10**131089}
+} 0
+test expr-23.70.3 {INST_EXPON: Bug 2798543} -body {
+ expr {10**17 == 10**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.70.4 {INST_EXPON: Bug 2798543} {
+ expr {(-10)**17 == (-10)**65553}
+} 0
+test expr-23.71.0 {INST_EXPON: Bug 2798543} {
+ expr {11**17 == 11**65553}
+} 0
+test expr-23.71.1 {INST_EXPON: Bug 2798543} {
+ expr {11**18 == 11**65554}
+} 0
+test expr-23.71.2 {INST_EXPON: Bug 2798543} {
+ expr {11**17 == 11**131089}
+} 0
+test expr-23.71.3 {INST_EXPON: Bug 2798543} -body {
+ expr {11**17 == 11**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.71.4 {INST_EXPON: Bug 2798543} {
+ expr {(-11)**17 == (-11)**65553}
+} 0
+test expr-23.72.0 {INST_EXPON: Bug 2798543} {
+ expr {12**17 == 12**65553}
+} 0
+test expr-23.72.1 {INST_EXPON: Bug 2798543} {
+ expr {12**17 == 12**131089}
+} 0
+test expr-23.72.2 {INST_EXPON: Bug 2798543} -body {
+ expr {12**17 == 12**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.72.3 {INST_EXPON: Bug 2798543} {
+ expr {(-12)**17 == (-12)**65553}
+} 0
+test expr-23.73.0 {INST_EXPON: Bug 2798543} {
+ expr {13**17 == 13**65553}
+} 0
+test expr-23.73.1 {INST_EXPON: Bug 2798543} {
+ expr {13**17 == 13**131089}
+} 0
+test expr-23.73.2 {INST_EXPON: Bug 2798543} -body {
+ expr {13**17 == 13**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.73.3 {INST_EXPON: Bug 2798543} {
+ expr {(-13)**17 == (-13)**65553}
+} 0
+test expr-23.74.0 {INST_EXPON: Bug 2798543} {
+ expr {14**17 == 14**65553}
+} 0
+test expr-23.74.1 {INST_EXPON: Bug 2798543} {
+ expr {14**17 == 14**131089}
+} 0
+test expr-23.74.2 {INST_EXPON: Bug 2798543} -body {
+ expr {14**17 == 14**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.74.3 {INST_EXPON: Bug 2798543} {
+ expr {(-14)**17 == (-14)**65553}
+} 0
+
+
+# Some compilers get this wrong; ensure that we work around it correctly
+test expr-24.1 {expr edge cases; shifting} {expr int(5)>>32} 0
+test expr-24.2 {expr edge cases; shifting} {expr int(5)>>63} 0
+test expr-24.3 {expr edge cases; shifting} {expr wide(5)>>32} 0
+test expr-24.4 {expr edge cases; shifting} {expr wide(5)>>63} 0
+test expr-24.5 {expr edge cases; shifting} longIs32bit {expr int(5<<32)} 0
+test expr-24.6 {expr edge cases; shifting} longIs32bit {expr int(5<<63)} 0
+test expr-24.7 {expr edge cases; shifting} {expr wide(5)<<32} 21474836480
+test expr-24.8 {expr edge cases; shifting} {expr wide(10<<63)} 0
+test expr-24.9 {expr edge cases; shifting} {expr 5>>32} 0
+
+test expr-24.10 {INST_LSHIFT: Bug 1567222} {expr 500000000000000<<28} 134217728000000000000000
+
+# List membership tests
+test expr-25.1 {'in' operator} {expr {"a" in "a b c"}} 1
+test expr-25.2 {'in' operator} {expr {"a" in "b a c"}} 1
+test expr-25.3 {'in' operator} {expr {"a" in "b c a"}} 1
+test expr-25.4 {'in' operator} {expr {"a" in ""}} 0
+test expr-25.5 {'in' operator} {expr {"" in {a b c ""}}} 1
+test expr-25.6 {'in' operator} {expr {"" in "a b c"}} 0
+test expr-25.7 {'in' operator} {expr {"" in ""}} 0
+
+test expr-26.1 {'ni' operator} {expr {"a" ni "a b c"}} 0
+test expr-26.2 {'ni' operator} {expr {"a" ni "b a c"}} 0
+test expr-26.3 {'ni' operator} {expr {"a" ni "b c a"}} 0
+test expr-26.4 {'ni' operator} {expr {"a" ni ""}} 1
+test expr-26.5 {'ni' operator} {expr {"" ni {a b c ""}}} 0
+test expr-26.6 {'ni' operator} {expr {"" ni "a b c"}} 1
+test expr-26.7 {'ni' operator} {expr {"" ni ""}} 1
+
+foreach op {< <= == != > >=} {
+ proc test$op {a b} [list expr "\$a $op \$b"]
+}
+
+test expr-27.1 {expr - correct ordering - not compiled} ieeeFloatingPoint {
+ set problems {}
+ # Ordering should be: -Infinity < -Normal < Subnormal < -0
+ # < +0 < +Subnormal < +Normal < +Infinity
+ # with equality within each class.
+ set names {
+ -Infinity -Normal -Subnormal -0 +0 +Subnormal +Normal +Infinity
+ }
+ set weights {
+ -3 -2 -1 0 0 1 2 3
+ }
+ foreach name1 $names weight1 $weights {
+ foreach name2 $names weight2 $weights {
+ foreach op {< <= == != >= >} {
+ set shouldBe [expr "$weight1 $op $weight2"]
+ set is [expr "\$ieeeValues($name1) $op \$ieeeValues($name2)"]
+ if { $is != $shouldBe } {
+ append problems $name1 { } $op { } $name2 \
+ ":result is " $is ", should be $shouldBe" \n
+ }
+ }
+ }
+ }
+ set problems
+} {}
+test expr-27.2 {expr - correct ordering - compiled} ieeeFloatingPoint {
+ set problems {}
+ # Ordering should be: -Infinity < -Normal < Subnormal < -0
+ # < +0 < +Subnormal < +Normal < +Infinity
+ # with equality within each class.
+ set names {
+ -Infinity -Normal -Subnormal -0 +0 +Subnormal +Normal +Infinity
+ }
+ set weights {
+ -3 -2 -1 0 0 1 2 3
+ }
+ foreach name1 $names weight1 $weights {
+ foreach name2 $names weight2 $weights {
+ foreach op {< <= == != >= >} {
+ set shouldBe [expr "$weight1 $op $weight2"]
+ set is [test$op $ieeeValues($name1) $ieeeValues($name2)]
+ if { $is != $shouldBe } {
+ append problems $name1 { } $op { } $name2 \
+ ":result is " $is ", should be $shouldBe" \n
+ }
+ }
+ }
+ }
+ set problems
+} {}
+test expr-27.3 {expr - NaN is unordered - not compiled} {
+ set problems {}
+ set names {
+ -Infinity -Normal -Subnormal -0 +0 +Subnormal +Normal +Infinity NaN
+ }
+ foreach name1 $names {
+ foreach op {< <= == != >= >} sb {0 0 0 1 0 0} {
+ if "(\$ieeeValues($name1) $op \$ieeeValues(NaN)) != $sb " {
+ append problems $name1 { } $op { } NaN \
+ ": result is 1, should be $sb" \n
+ }
+ if "(\$ieeeValues(NaN) $op \$ieeeValues($name1)) != $sb" {
+ append problems NaN { } $op { } $name1 \
+ ": result is 1, should be $sb" \n
+ }
+ }
+ }
+ set problems
+} {}
+test expr-27.4 {expr - NaN is unordered - compiled} {
+ set problems {}
+ set names {
+ -Infinity -Normal -Subnormal -0 +0 +Subnormal +Normal +Infinity NaN
+ }
+ foreach name1 $names {
+ foreach op {< <= == != >= >} sb {0 0 0 1 0 0} {
+ if { [test$op $ieeeValues($name1) $ieeeValues(NaN)] != $sb } {
+ append problems $ieeeValues($name1) { } $op { } $ieeeValues(NaN) \
+ ": result is 1, should be $sb" \n
+ }
+ if { [test$op $ieeeValues(NaN) $ieeeValues($name1)] != $sb } {
+ append problems NaN { } $op { } $ieeeValues($name1) \
+ ": result is 1, should be $sb" \n
+ }
+ }
+ }
+ set problems
+} {}
+
+proc convertToDouble { x } {
+ variable ieeeValues
+ binary scan [binary format d $x] c* bytes
+ set result 0x
+ if { $ieeeValues(littleEndian) } {
+ for { set i 7 } { $i >= 0 } { incr i -1 } {
+ append result [format %02x [expr { [lindex $bytes $i] & 0xff }]]
+ }
+ } else {
+ foreach byte $bytes {
+ append result [format %02x [expr { $byte & 0xff }]]
+ }
+ }
+ return $result
+}
+
+test expr-28.1 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 0 E0 OK 00000000000000 E-1023
+ convertToDouble 0E0
+} 0x0000000000000000
+test expr-28.2 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL -0 E0 OK -0000000000000 E-1023
+ convertToDouble -0E0
+} 0x8000000000000000
+test expr-28.3 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 1 E0 OK 10000000000000 E0
+ convertToDouble 1E0
+} 0x3ff0000000000000
+test expr-28.4 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 15 E-1 OK 18000000000000 E0
+ convertToDouble 15E-1
+} 0x3ff8000000000000
+test expr-28.5 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 125 E-2 OK 14000000000000 E0
+ convertToDouble 125E-2
+} 0x3ff4000000000000
+test expr-28.6 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 1125 E-3 OK 12000000000000 E0
+ convertToDouble 1125E-3
+} 0x3ff2000000000000
+test expr-28.7 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 10625 E-4 OK 11000000000000 E0
+ convertToDouble 10625E-4
+} 0x3ff1000000000000
+test expr-28.8 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 103125 E-5 OK 10800000000000 E0
+ convertToDouble 103125E-5
+} 0x3ff0800000000000
+test expr-28.9 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 1015625 E-6 OK 10400000000000 E0
+ convertToDouble 1015625E-6
+} 0x3ff0400000000000
+test expr-28.10 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 10078125 E-7 OK 10200000000000 E0
+ convertToDouble 10078125E-7
+} 0x3ff0200000000000
+test expr-28.11 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 100390625 E-8 OK 10100000000000 E0
+ convertToDouble 100390625E-8
+} 0x3ff0100000000000
+test expr-28.12 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee ALL 1001953125 E-9 OK 10080000000000 E0
+ convertToDouble 1001953125E-9
+} 0x3ff0080000000000
+test expr-28.13 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee ALL 10009765625 E-10 OK 10040000000000 E0
+ convertToDouble 10009765625E-10
+} 0x3ff0040000000000
+test expr-28.14 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee ALL 100048828125 E-11 OK 10020000000000 E0
+ convertToDouble 100048828125E-11
+} 0x3ff0020000000000
+test expr-28.15 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee ALL 1000244140625 E-12 OK 10010000000000 E0
+ convertToDouble 1000244140625E-12
+} 0x3ff0010000000000
+test expr-28.16 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee ALL 10001220703125 E-13 OK 10008000000000 E0
+ convertToDouble 10001220703125E-13
+} 0x3ff0008000000000
+test expr-28.17 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee ALL 100006103515625 E-14 OK 10004000000000 E0
+ convertToDouble 100006103515625E-14
+} 0x3ff0004000000000
+test expr-28.18 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee ALL 1000030517578125 E-15 OK 10002000000000 E0
+ convertToDouble 1000030517578125E-15
+} 0x3ff0002000000000
+test expr-28.19 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee ALL 10000152587890625 E-16 OK 10001000000000 E0
+ convertToDouble 10000152587890625E-16
+} 0x3ff0001000000000
+test expr-28.20 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8 E153 x 1317e5ef3ab327_0000000001& E511
+ convertToDouble +8E153
+} 0x5fe317e5ef3ab327
+test expr-28.21 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1 E153 x -1317e5ef3ab327_0000000001& E508
+ convertToDouble -1E153
+} 0xdfb317e5ef3ab327
+test expr-28.22 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9 E306 x 19a2028368022e_00000000001& E1019
+ convertToDouble +9E306
+} 0x7fa9a2028368022e
+test expr-28.23 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -2 E153 x -1317e5ef3ab327_0000000001& E509
+ convertToDouble -2E153
+} 0xdfc317e5ef3ab327
+test expr-28.24 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7 E-304 x 1eb8e84fa0b278_00000000001& E-1008
+ convertToDouble +7E-304
+} 0x00feb8e84fa0b278
+test expr-28.25 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3 E-49 x -1c0f92a6276c9d_000000001& E-162
+ convertToDouble -3E-49
+} 0xb5dc0f92a6276c9d
+test expr-28.26 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7 E-303 x 13339131c46f8b_00000000001& E-1004
+ convertToDouble +7E-303
+} 0x0133339131c46f8b
+test expr-28.27 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -6 E-49 x -1c0f92a6276c9d_000000001& E-161
+ convertToDouble -6E-49
+} 0xb5ec0f92a6276c9d
+test expr-28.28 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9 E43 x 102498ea6df0c3_11111111110& E146
+ convertToDouble +9E43
+} 0x49102498ea6df0c4
+test expr-28.29 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9 E44 x -142dbf25096cf4_1111111110& E149
+ convertToDouble -9E44
+} 0xc9442dbf25096cf5
+test expr-28.30 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8 E303 x 1754e31cd072d9_1111111110& E1009
+ convertToDouble +8E303
+} 0x7f0754e31cd072da
+test expr-28.31 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1 E303 x -1754e31cd072d9_1111111110& E1006
+ convertToDouble -1E303
+} 0xfed754e31cd072da
+test expr-28.32 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7 E-287 x 1551603777f798_111111110& E-951
+ convertToDouble +7E-287
+} 0x048551603777f799
+test expr-28.33 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -2 E-204 x -1410d9f9b2f7f2_11111110& E-677
+ convertToDouble -2E-204
+} 0x95a410d9f9b2f7f3
+test expr-28.34 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2 E-205 x 100d7b2e28c65b_11111110& E-680
+ convertToDouble +2E-205
+} 0x15700d7b2e28c65c
+test expr-28.35 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9 E-47 x -10711fed5b19a3_11111110& E-153
+ convertToDouble -9E-47
+} 0xb660711fed5b19a4
+test expr-28.36 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +34 E195 x 1d1c26db7d0dae_000000000001& E652
+ convertToDouble +34E195
+} 0x68bd1c26db7d0dae
+test expr-28.37 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -68 E195 x -1d1c26db7d0dae_000000000001& E653
+ convertToDouble -68E195
+} 0xe8cd1c26db7d0dae
+test expr-28.38 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +85 E194 x 1d1c26db7d0dae_000000000001& E650
+ convertToDouble +85E194
+} 0x689d1c26db7d0dae
+test expr-28.39 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -67 E97 x -139ac1ce2cc95f_000000000001& E328
+ convertToDouble -67E97
+} 0xd4739ac1ce2cc95f
+test expr-28.40 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +93 E-234 x 127b2e4f210075_0000000000000001& E-771
+ convertToDouble +93E-234
+} 0x0fc27b2e4f210075
+test expr-28.41 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -19 E-87 x -12e5f5dfa4fe9d_00000000000001& E-285
+ convertToDouble -19E-87
+} 0xae22e5f5dfa4fe9d
+test expr-28.42 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +38 E-87 x 12e5f5dfa4fe9d_00000000000001& E-284
+ convertToDouble +38E-87
+} 0x2e32e5f5dfa4fe9d
+test expr-28.43 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -38 E-88 x -1e3cbc9907fdc8_00000000000001& E-288
+ convertToDouble -38E-88
+} 0xadfe3cbc9907fdc8
+test expr-28.44 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -69 E220 x -1e8aa8823a5db3_11111111110& E736
+ convertToDouble -69E220
+} 0xedfe8aa8823a5db4
+test expr-28.45 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +18 E43 x 102498ea6df0c3_11111111110& E147
+ convertToDouble +18E43
+} 0x49202498ea6df0c4
+test expr-28.46 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -36 E43 x -102498ea6df0c3_11111111110& E148
+ convertToDouble -36E43
+} 0xc9302498ea6df0c4
+test expr-28.47 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +61 E-99 x 10ad836f269a16_11111111111110& E-323
+ convertToDouble +61E-99
+} 0x2bc0ad836f269a17
+test expr-28.48 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -43 E-92 x -1c0794d9d40e95_111111111111110& E-301
+ convertToDouble -43E-92
+} 0xad2c0794d9d40e96
+test expr-28.49 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +86 E-92 x 1c0794d9d40e95_111111111111110& E-300
+ convertToDouble +86E-92
+} 0x2d3c0794d9d40e96
+test expr-28.50 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -51 E-74 x -1cd5bee57763e5_1111111111111110& E-241
+ convertToDouble -51E-74
+} 0xb0ecd5bee57763e6
+test expr-28.51 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +283 E85 x 16c309024bab4b_00000000000000001& E290
+ convertToDouble +283E85
+} 0x5216c309024bab4b
+test expr-28.52 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -566 E85 x -16c309024bab4b_00000000000000001& E291
+ convertToDouble -566E85
+} 0xd226c309024bab4b
+test expr-28.53 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +589 E187 x 1526be9c22eb17_00000000000000001& E630
+ convertToDouble +589E187
+} 0x675526be9c22eb17
+test expr-28.54 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -839 E143 x -1ae03f245703e2_000000000000001& E484
+ convertToDouble -839E143
+} 0xde3ae03f245703e2
+test expr-28.55 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -744 E-234 x -127b2e4f210075_0000000000000001& E-768
+ convertToDouble -744E-234
+} 0x8ff27b2e4f210075
+test expr-28.56 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +930 E-235 x 127b2e4f210075_0000000000000001& E-771
+ convertToDouble +930E-235
+} 0x0fc27b2e4f210075
+test expr-28.57 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -186 E-234 x -127b2e4f210075_0000000000000001& E-770
+ convertToDouble -186E-234
+} 0x8fd27b2e4f210075
+test expr-28.58 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +604 E175 x 17d93193f78fc5_1111111111111111110& E590
+ convertToDouble +604E175
+} 0x64d7d93193f78fc6
+test expr-28.59 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -302 E175 x -17d93193f78fc5_1111111111111111110& E589
+ convertToDouble -302E175
+} 0xe4c7d93193f78fc6
+test expr-28.60 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +755 E174 x 17d93193f78fc5_1111111111111111110& E587
+ convertToDouble +755E174
+} 0x64a7d93193f78fc6
+test expr-28.61 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -151 E175 x -17d93193f78fc5_1111111111111111110& E588
+ convertToDouble -151E175
+} 0xe4b7d93193f78fc6
+test expr-28.62 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +662 E-213 x 1bdb90e62a8cbc_1111111111111110& E-699
+ convertToDouble +662E-213
+} 0x144bdb90e62a8cbd
+test expr-28.63 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -408 E-74 x -1cd5bee57763e5_1111111111111110& E-238
+ convertToDouble -408E-74
+} 0xb11cd5bee57763e6
+test expr-28.64 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +510 E-75 x 1cd5bee57763e5_1111111111111110& E-241
+ convertToDouble +510E-75
+} 0x30ecd5bee57763e6
+test expr-28.65 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6782 E55 x 159bd3ad46e346_0000000000000000001& E195
+ convertToDouble +6782E55
+} 0x4c259bd3ad46e346
+test expr-28.66 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -2309 E92 x -1bac6f7d64d119_000000000000000001& E316
+ convertToDouble -2309E92
+} 0xd3bbac6f7d64d119
+test expr-28.67 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7963 E34 x 1df4170f0fdecc_00000000000000000001& E125
+ convertToDouble +7963E34
+} 0x47cdf4170f0fdecc
+test expr-28.68 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3391 E55 x -159bd3ad46e346_0000000000000000001& E194
+ convertToDouble -3391E55
+} 0xcc159bd3ad46e346
+test expr-28.69 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7903 E-96 x 107c2d27a5b989_0000000000000000001& E-306
+ convertToDouble +7903E-96
+} 0x2cd07c2d27a5b989
+test expr-28.70 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7611 E-226 x -119b8744033457_0000000000000000001& E-738
+ convertToDouble -7611E-226
+} 0x91d19b8744033457
+test expr-28.71 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +4907 E-196 x 11e90a8711440f_000000000000000001& E-639
+ convertToDouble +4907E-196
+} 0x1801e90a8711440f
+test expr-28.72 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5547 E-311 x -13f190452a29f4_000000000000000001& E-1021
+ convertToDouble -5547E-311
+} 0x8023f190452a29f4
+test expr-28.73 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +5311 E241 x 1f1ce3c887c25f_11111111111111111110& E812
+ convertToDouble +5311E241
+} 0x72bf1ce3c887c260
+test expr-28.74 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5311 E243 x -184e91f4aa0fda_11111111111111111110& E819
+ convertToDouble -5311E243
+} 0xf3284e91f4aa0fdb
+test expr-28.75 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +5311 E242 x 13720e5d54d97b_11111111111111111110& E816
+ convertToDouble +5311E242
+} 0x72f3720e5d54d97c
+test expr-28.76 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9269 E-45 x 19d69455a53bd8_111111111111111111110& E-137
+ convertToDouble +9269E-45
+} 0x3769d69455a53bd9
+test expr-28.77 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8559 E-289 x -104a81d35952fe_11111111111111111110& E-947
+ convertToDouble -8559E-289
+} 0x84c04a81d35952ff
+test expr-28.78 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8699 E-276 x 12d2df246ecd2c_1111111111111111111110& E-904
+ convertToDouble +8699E-276
+} 0x0772d2df246ecd2d
+test expr-28.79 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8085 E-64 x -14c98fce16152d_1111111111111111110& E-200
+ convertToDouble -8085E-64
+} 0xb374c98fce16152e
+test expr-28.80 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +74819 E201 x 1dd455061eb3f1_0000000000000000000001& E683
+ convertToDouble +74819E201
+} 0x6aadd455061eb3f1
+test expr-28.81 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -82081 E41 x -170105df3d47cb_000000000000000000000000001& E152
+ convertToDouble -82081E41
+} 0xc9770105df3d47cb
+test expr-28.82 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +51881 E37 x 17d2950dc76da4_000000000000000000001& E138
+ convertToDouble +51881E37
+} 0x4897d2950dc76da4
+test expr-28.83 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -55061 E157 x -1394fc0f33536c_000000000000000000001& E537
+ convertToDouble -55061E157
+} 0xe18394fc0f33536c
+test expr-28.84 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +77402 E-215 x 10492a4a8a37fd_0000000000000000000000001& E-698
+ convertToDouble +77402E-215
+} 0x1450492a4a8a37fd
+test expr-28.85 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -33891 E-92 x -1592f9932c06bd_00000000000000000000001& E-291
+ convertToDouble -33891E-92
+} 0xadc592f9932c06bd
+test expr-28.86 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +38701 E-215 x 10492a4a8a37fd_0000000000000000000000001& E-699
+ convertToDouble +38701E-215
+} 0x1440492a4a8a37fd
+test expr-28.87 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -82139 E-76 x -1d0681489839d5_00000000000000000000001& E-237
+ convertToDouble -82139E-76
+} 0xb12d0681489839d5
+test expr-28.88 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +75859 E25 x 132645e1ba93ef_11111111111111111111110& E99
+ convertToDouble +75859E25
+} 0x46232645e1ba93f0
+test expr-28.89 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +89509 E140 x 16f02bee68670c_1111111111111111111110& E481
+ convertToDouble +89509E140
+} 0x5e06f02bee68670d
+test expr-28.90 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -57533 E287 x -1272ed2307f569_1111111111111111111110& E969
+ convertToDouble -57533E287
+} 0xfc8272ed2307f56a
+test expr-28.91 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +46073 E-32 x 12405b773fbdf2_11111111111111111111110& E-91
+ convertToDouble +46073E-32
+} 0x3a42405b773fbdf3
+test expr-28.92 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -92146 E-32 x -12405b773fbdf2_11111111111111111111110& E-90
+ convertToDouble -92146E-32
+} 0xba52405b773fbdf3
+test expr-28.93 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +83771 E-74 x 17206bfc4ccabd_11111111111111111111110& E-230
+ convertToDouble +83771E-74
+} 0x3197206bfc4ccabe
+test expr-28.94 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -34796 E-276 x -12d2df246ecd2c_1111111111111111111110& E-902
+ convertToDouble -34796E-276
+} 0x8792d2df246ecd2d
+test expr-28.95 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +584169 E229 x 1d657059dc79aa_00000000000000000000000000001& E779
+ convertToDouble +584169E229
+} 0x70ad657059dc79aa
+test expr-28.96 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +164162 E41 x 170105df3d47cb_000000000000000000000000001& E153
+ convertToDouble +164162E41
+} 0x49870105df3d47cb
+test expr-28.97 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -328324 E41 x -170105df3d47cb_000000000000000000000000001& E154
+ convertToDouble -328324E41
+} 0xc9970105df3d47cb
+test expr-28.98 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +209901 E-11 x 119b96f36ec68b_00000000000000000000000001& E-19
+ convertToDouble +209901E-11
+} 0x3ec19b96f36ec68b
+test expr-28.99 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -419802 E-11 x -119b96f36ec68b_00000000000000000000000001& E-18
+ convertToDouble -419802E-11
+} 0xbed19b96f36ec68b
+test expr-28.100 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +940189 E-112 x 1b99d6240c1a28_00000000000000000000000001& E-353
+ convertToDouble +940189E-112
+} 0x29eb99d6240c1a28
+test expr-28.101 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -892771 E-213 x -125818c7294f27_0000000000000000000000000001& E-688
+ convertToDouble -892771E-213
+} 0x94f25818c7294f27
+test expr-28.102 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +757803 E120 x 11e968b555bb80_11111111111111111111111111110& E418
+ convertToDouble +757803E120
+} 0x5a11e968b555bb81
+test expr-28.103 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -252601 E120 x -17e1e0f1c7a4ab_11111111111111111111111111110& E416
+ convertToDouble -252601E120
+} 0xd9f7e1e0f1c7a4ac
+test expr-28.104 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +252601 E121 x 1dda592e398dd6_1111111111111111111111111110& E419
+ convertToDouble +252601E121
+} 0x5a2dda592e398dd7
+test expr-28.105 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -505202 E120 x -17e1e0f1c7a4ab_11111111111111111111111111110& E417
+ convertToDouble -505202E120
+} 0xda07e1e0f1c7a4ac
+test expr-28.106 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +970811 E-264 x 1dda6b965c9629_11111111111111111111111110& E-858
+ convertToDouble +970811E-264
+} 0x0a5dda6b965c962a
+test expr-28.107 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -654839 E-60 x -100e7db3b3f241_111111111111111111111111110& E-180
+ convertToDouble -654839E-60
+} 0xb4b00e7db3b3f242
+test expr-28.108 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +289767 E-178 x 1caad28f23a100_11111111111111111111111110& E-574
+ convertToDouble +289767E-178
+} 0x1c1caad28f23a101
+test expr-28.109 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -579534 E-178 x -1caad28f23a100_11111111111111111111111110& E-573
+ convertToDouble -579534E-178
+} 0x9c2caad28f23a101
+test expr-28.110 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8823691 E130 x -1e597c0b94b7ae_00000000000000000000000000000001& E454
+ convertToDouble -8823691E130
+} 0xdc5e597c0b94b7ae
+test expr-28.111 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9346704 E229 x 1d657059dc79aa_00000000000000000000000000001& E783
+ convertToDouble +9346704E229
+} 0x70ed657059dc79aa
+test expr-28.112 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1168338 E229 x -1d657059dc79aa_00000000000000000000000000001& E780
+ convertToDouble -1168338E229
+} 0xf0bd657059dc79aa
+test expr-28.113 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -6063369 E-136 x -1ae6148e3902b3_000000000000000000000000000001& E-430
+ convertToDouble -6063369E-136
+} 0xa51ae6148e3902b3
+test expr-28.114 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3865421 E-225 x 15d4fe53afec65_00000000000000000000000000001& E-726
+ convertToDouble +3865421E-225
+} 0x1295d4fe53afec65
+test expr-28.115 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5783893 E-127 x -17e5902ce0e151_000000000000000000000000000000001& E-400
+ convertToDouble -5783893E-127
+} 0xa6f7e5902ce0e151
+test expr-28.116 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2572231 E223 x 10f73be1dff9ac_111111111111111111111111111110& E762
+ convertToDouble +2572231E223
+} 0x6f90f73be1dff9ad
+test expr-28.117 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5144462 E223 x -10f73be1dff9ac_111111111111111111111111111110& E763
+ convertToDouble -5144462E223
+} 0xefa0f73be1dff9ad
+test expr-28.118 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +1817623 E109 x 1d85f96f3fe659_11111111111111111111111111110& E382
+ convertToDouble +1817623E109
+} 0x57dd85f96f3fe65a
+test expr-28.119 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6431543 E-97 x 14f6493f34a0bc_11111111111111111111111111110& E-300
+ convertToDouble +6431543E-97
+} 0x2d34f6493f34a0bd
+test expr-28.120 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -5444097 E-21 x -18849dd33c95ae_11111111111111111111111111110& E-48
+ convertToDouble -5444097E-21
+} 0xbcf8849dd33c95af
+test expr-28.121 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8076999 E-121 x 1fd332f7e2e3b2_11111111111111111111111111110& E-380
+ convertToDouble +8076999E-121
+} 0x283fd332f7e2e3b3
+test expr-28.122 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9997649 E-270 x -1425e9d29e558d_1111111111111111111111111110& E-874
+ convertToDouble -9997649E-270
+} 0x895425e9d29e558e
+test expr-28.123 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +50609263 E157 x 1193aff1f1c8e3_000000000000000000000000000000001& E547
+ convertToDouble +50609263E157
+} 0x622193aff1f1c8e3
+test expr-28.124 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +70589528 E130 x 1e597c0b94b7ae_00000000000000000000000000000001& E457
+ convertToDouble +70589528E130
+} 0x5c8e597c0b94b7ae
+test expr-28.125 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -88236910 E129 x -1e597c0b94b7ae_00000000000000000000000000000001& E454
+ convertToDouble -88236910E129
+} 0xdc5e597c0b94b7ae
+test expr-28.126 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +87575437 E-310 x 1805c19e680456_0000000000000000000000000000000000001& E-1004
+ convertToDouble +87575437E-310
+} 0x013805c19e680456
+test expr-28.127 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -23135572 E-127 x -17e5902ce0e151_000000000000000000000000000000001& E-398
+ convertToDouble -23135572E-127
+} 0xa717e5902ce0e151
+test expr-28.128 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +85900881 E177 x 14375b2214e1b4_111111111111111111111111111111110& E614
+ convertToDouble +85900881E177
+} 0x6654375b2214e1b5
+test expr-28.129 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -84863171 E113 x -1a4a8e56474b8b_111111111111111111111111111111110& E401
+ convertToDouble -84863171E113
+} 0xd90a4a8e56474b8c
+test expr-28.130 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +68761586 E232 x 1a662c350f37f2_1111111111111111111111111111110& E796
+ convertToDouble +68761586E232
+} 0x71ba662c350f37f3
+test expr-28.131 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -50464069 E286 x -1948dd06de561e_1111111111111111111111111111110& E975
+ convertToDouble -50464069E286
+} 0xfce948dd06de561f
+test expr-28.132 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +27869147 E-248 x 1dbbac6f83a820_111111111111111111111111111111111110& E-800
+ convertToDouble +27869147E-248
+} 0x0dfdbbac6f83a821
+test expr-28.133 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -55738294 E-248 x -1dbbac6f83a820_111111111111111111111111111111111110& E-799
+ convertToDouble -55738294E-248
+} 0x8e0dbbac6f83a821
+test expr-28.134 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +70176353 E-53 x 100683a21de854_1111111111111111111111111111111110& E-150
+ convertToDouble +70176353E-53
+} 0x36900683a21de855
+test expr-28.135 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -80555086 E-32 x -1f29ca0ff893b0_111111111111111111111111111111110& E-81
+ convertToDouble -80555086E-32
+} 0xbaef29ca0ff893b1
+test expr-28.136 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -491080654 E121 x -1c569e968e0944_00000000000000000000000000000000000000001& E430
+ convertToDouble -491080654E121
+} 0xdadc569e968e0944
+test expr-28.137 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +526250918 E287 x 14997a298b2f2e_0000000000000000000000000000000000001& E982
+ convertToDouble +526250918E287
+} 0x7d54997a298b2f2e
+test expr-28.138 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -245540327 E121 x -1c569e968e0944_00000000000000000000000000000000000000001& E429
+ convertToDouble -245540327E121
+} 0xdacc569e968e0944
+test expr-28.139 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -175150874 E-310 x -1805c19e680456_0000000000000000000000000000000000001& E-1003
+ convertToDouble -175150874E-310
+} 0x814805c19e680456
+test expr-28.140 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +350301748 E-310 x 1805c19e680456_0000000000000000000000000000000000001& E-1002
+ convertToDouble +350301748E-310
+} 0x015805c19e680456
+test expr-28.141 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -437877185 E-311 x -1805c19e680456_0000000000000000000000000000000000001& E-1005
+ convertToDouble -437877185E-311
+} 0x812805c19e680456
+test expr-28.142 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +458117166 E52 x 16ce94febdc7a4_1111111111111111111111111111111111110& E201
+ convertToDouble +458117166E52
+} 0x4c86ce94febdc7a5
+test expr-28.143 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -916234332 E52 x -16ce94febdc7a4_1111111111111111111111111111111111110& E202
+ convertToDouble -916234332E52
+} 0xcc96ce94febdc7a5
+test expr-28.144 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +229058583 E52 x 16ce94febdc7a4_1111111111111111111111111111111111110& E200
+ convertToDouble +229058583E52
+} 0x4c76ce94febdc7a5
+test expr-28.145 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -525789935 E98 x -16ecdc2a58fc64_11111111111111111111111111111111110& E354
+ convertToDouble -525789935E98
+} 0xd616ecdc2a58fc65
+test expr-28.146 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +282926897 E-227 x 1ff5a70d3d2fee_1111111111111111111111111111111111110& E-727
+ convertToDouble +282926897E-227
+} 0x128ff5a70d3d2fef
+test expr-28.147 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -565853794 E-227 x -1ff5a70d3d2fee_1111111111111111111111111111111111110& E-726
+ convertToDouble -565853794E-227
+} 0x929ff5a70d3d2fef
+test expr-28.148 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +667284113 E-240 x 109355f8050c01_111111111111111111111111111111111110& E-768
+ convertToDouble +667284113E-240
+} 0x0ff09355f8050c02
+test expr-28.149 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -971212611 E-126 x -1397d3c9745d2e_111111111111111111111111111111111111110& E-389
+ convertToDouble -971212611E-126
+} 0xa7a397d3c9745d2f
+test expr-28.150 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9981396317 E-182 x 18afe10a2a66aa_0000000000000000000000000000000000000001& E-572
+ convertToDouble +9981396317E-182
+} 0x1c38afe10a2a66aa
+test expr-28.151 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5035231965 E-156 x -101891fc4717fd_00000000000000000000000000000000000001& E-486
+ convertToDouble -5035231965E-156
+} 0xa1901891fc4717fd
+test expr-28.152 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8336960483 E-153 x 1a06a1024b95e1_000000000000000000000000000000000000001& E-476
+ convertToDouble +8336960483E-153
+} 0x223a06a1024b95e1
+test expr-28.153 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8056371144 E-155 x -101891fc4717fd_00000000000000000000000000000000000001& E-482
+ convertToDouble -8056371144E-155
+} 0xa1d01891fc4717fd
+test expr-28.154 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6418488827 E79 x 1021f14ed7b3f9_11111111111111111111111111111111111111110& E295
+ convertToDouble +6418488827E79
+} 0x526021f14ed7b3fa
+test expr-28.155 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3981006983 E252 x -102ebaf189d5f1_1111111111111111111111111111111111111110& E869
+ convertToDouble -3981006983E252
+} 0xf6402ebaf189d5f2
+test expr-28.156 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7962013966 E252 x 102ebaf189d5f1_1111111111111111111111111111111111111110& E870
+ convertToDouble +7962013966E252
+} 0x76502ebaf189d5f2
+test expr-28.157 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -4713898551 E261 x -11d8813536e0df_11111111111111111111111111111111111110& E899
+ convertToDouble -4713898551E261
+} 0xf821d8813536e0e0
+test expr-28.158 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8715380633 E-58 x 14614c3219891e_11111111111111111111111111111111111111110& E-160
+ convertToDouble +8715380633E-58
+} 0x35f4614c3219891f
+test expr-28.159 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9078555839 E-109 x -1fc575867314ed_111111111111111111111111111111111111111111110& E-330
+ convertToDouble -9078555839E-109
+} 0xab5fc575867314ee
+test expr-28.160 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9712126110 E-127 x 1397d3c9745d2e_111111111111111111111111111111111111110& E-389
+ convertToDouble +9712126110E-127
+} 0x27a397d3c9745d2f
+test expr-28.161 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +42333842451 E201 x 10189a26df575f_000000000000000000000000000000000000000000001& E703
+ convertToDouble +42333842451E201
+} 0x6be0189a26df575f
+test expr-28.162 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -84667684902 E201 x -10189a26df575f_000000000000000000000000000000000000000000001& E704
+ convertToDouble -84667684902E201
+} 0xebf0189a26df575f
+test expr-28.163 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +23792120709 E-315 x 10b517dc5d3212_00000000000000000000000000000000000000001& E-1012
+ convertToDouble +23792120709E-315
+} 0x00b0b517dc5d3212
+test expr-28.164 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -78564021519 E-227 x -1155515fd37265_00000000000000000000000000000000000000000001& E-718
+ convertToDouble -78564021519E-227
+} 0x931155515fd37265
+test expr-28.165 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +71812054883 E-188 x 1747b46d78c6fe_00000000000000000000000000000000000000001& E-589
+ convertToDouble +71812054883E-188
+} 0x1b2747b46d78c6fe
+test expr-28.166 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -30311163631 E-116 x -163ef6f560afe7_00000000000000000000000000000000000000001& E-351
+ convertToDouble -30311163631E-116
+} 0xaa063ef6f560afe7
+test expr-28.167 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +71803914657 E292 x 10c0c44cdc2c05_11111111111111111111111111111111111111111110& E1006
+ convertToDouble +71803914657E292
+} 0x7ed0c0c44cdc2c06
+test expr-28.168 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +36314223356 E-109 x 1fc575867314ed_111111111111111111111111111111111111111111110& E-328
+ convertToDouble +36314223356E-109
+} 0x2b7fc575867314ee
+test expr-28.169 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +18157111678 E-109 x 1fc575867314ed_111111111111111111111111111111111111111111110& E-329
+ convertToDouble +18157111678E-109
+} 0x2b6fc575867314ee
+test expr-28.170 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -45392779195 E-110 x -1fc575867314ed_111111111111111111111111111111111111111111110& E-331
+ convertToDouble -45392779195E-110
+} 0xab4fc575867314ee
+test expr-28.171 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +778380362293 E218 x 19ab8261990292_0000000000000000000000000000000000000000000000000001& E763
+ convertToDouble +778380362293E218
+} 0x6fa9ab8261990292
+test expr-28.172 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -685763015669 E280 x -15fd7aa44d9477_000000000000000000000000000000000000000000000001& E969
+ convertToDouble -685763015669E280
+} 0xfc85fd7aa44d9477
+test expr-28.173 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +952918668151 E70 x 14177a9915fbf8_00000000000000000000000000000000000000000000001& E272
+ convertToDouble +952918668151E70
+} 0x50f4177a9915fbf8
+test expr-28.174 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -548357443505 E32 x -13abde2775e9b5_0000000000000000000000000000000000000000000001& E145
+ convertToDouble -548357443505E32
+} 0xc903abde2775e9b5
+test expr-28.175 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +384865004907 E-285 x 1aa65b58639e69_00000000000000000000000000000000000000000000001& E-909
+ convertToDouble +384865004907E-285
+} 0x072aa65b58639e69
+test expr-28.176 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -769730009814 E-285 x -1aa65b58639e69_00000000000000000000000000000000000000000000001& E-908
+ convertToDouble -769730009814E-285
+} 0x873aa65b58639e69
+test expr-28.177 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +697015418417 E-93 x 152847dad80453_0000000000000000000000000000000000000000000001& E-270
+ convertToDouble +697015418417E-93
+} 0x2f152847dad80453
+test expr-28.178 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -915654049301 E-28 x -1a645598d05989_0000000000000000000000000000000000000000000001& E-54
+ convertToDouble -915654049301E-28
+} 0xbc9a645598d05989
+test expr-28.179 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +178548656339 E169 x 1b89d67c5b6d24_111111111111111111111111111111111111111111110& E598
+ convertToDouble +178548656339E169
+} 0x655b89d67c5b6d25
+test expr-28.180 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -742522891517 E259 x -1c1c352fc3c308_11111111111111111111111111111111111111111111110& E899
+ convertToDouble -742522891517E259
+} 0xf82c1c352fc3c309
+test expr-28.181 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +742522891517 E258 x 167cf7596968d3_11111111111111111111111111111111111111111111110& E896
+ convertToDouble +742522891517E258
+} 0x77f67cf7596968d4
+test expr-28.182 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -357097312678 E169 x -1b89d67c5b6d24_111111111111111111111111111111111111111111110& E599
+ convertToDouble -357097312678E169
+} 0xe56b89d67c5b6d25
+test expr-28.183 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3113521449172 E218 x -19ab8261990292_0000000000000000000000000000000000000000000000000001& E765
+ convertToDouble -3113521449172E218
+} 0xefc9ab8261990292
+test expr-28.184 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3891901811465 E217 x 19ab8261990292_0000000000000000000000000000000000000000000000000001& E762
+ convertToDouble +3891901811465E217
+} 0x6f99ab8261990292
+test expr-28.185 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1556760724586 E218 x -19ab8261990292_0000000000000000000000000000000000000000000000000001& E764
+ convertToDouble -1556760724586E218
+} 0xefb9ab8261990292
+test expr-28.186 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9997878507563 E-195 x 153db2fea1ea31_0000000000000000000000000000000000000000000000001& E-605
+ convertToDouble +9997878507563E-195
+} 0x1a253db2fea1ea31
+test expr-28.187 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7247563029154 E-319 x -10493f056e9ef3_0000000000000000000000000000000000000000000000001& E-1017
+ convertToDouble -7247563029154E-319
+} 0x8060493f056e9ef3
+test expr-28.188 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3623781514577 E-319 x 10493f056e9ef3_0000000000000000000000000000000000000000000000001& E-1018
+ convertToDouble +3623781514577E-319
+} 0x0050493f056e9ef3
+test expr-28.189 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3092446298323 E-200 x -113918353bbc47_0000000000000000000000000000000000000000000000001& E-623
+ convertToDouble -3092446298323E-200
+} 0x99013918353bbc47
+test expr-28.190 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6363857920591 E145 x 128a61cf9483b6_1111111111111111111111111111111111111111111111111110& E524
+ convertToDouble +6363857920591E145
+} 0x60b28a61cf9483b7
+test expr-28.191 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8233559360849 E94 x -11f324d11d4861_1111111111111111111111111111111111111111111111110& E355
+ convertToDouble -8233559360849E94
+} 0xd621f324d11d4862
+test expr-28.192 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2689845954547 E49 x 10bd2bfd34f98a_1111111111111111111111111111111111111111111111110& E204
+ convertToDouble +2689845954547E49
+} 0x4cb0bd2bfd34f98b
+test expr-28.193 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5379691909094 E49 x -10bd2bfd34f98a_1111111111111111111111111111111111111111111111110& E205
+ convertToDouble -5379691909094E49
+} 0xccc0bd2bfd34f98b
+test expr-28.194 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +5560322501926 E-301 x 15acc2053064c1_11111111111111111111111111111111111111111111111110& E-958
+ convertToDouble +5560322501926E-301
+} 0x0415acc2053064c2
+test expr-28.195 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7812878489261 E-179 x -126dae7bbeda74_11111111111111111111111111111111111111111111111111110& E-552
+ convertToDouble -7812878489261E-179
+} 0x9d726dae7bbeda75
+test expr-28.196 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8439398533053 E-256 x 170cc285f2d209_1111111111111111111111111111111111111111111111110& E-808
+ convertToDouble +8439398533053E-256
+} 0x0d770cc285f2d20a
+test expr-28.197 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -2780161250963 E-301 x -15acc2053064c1_11111111111111111111111111111111111111111111111110& E-959
+ convertToDouble -2780161250963E-301
+} 0x8405acc2053064c2
+test expr-28.198 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -87605699161665 E155 x -12920f96e7f9ef_00000000000000000000000000000000000000000000000000001& E561
+ convertToDouble -87605699161665E155
+} 0xe302920f96e7f9ef
+test expr-28.199 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -17521139832333 E156 x -12920f96e7f9ef_00000000000000000000000000000000000000000000000000001& E562
+ convertToDouble -17521139832333E156
+} 0xe312920f96e7f9ef
+test expr-28.200 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -88218101363513 E-170 x -18395688592faf_0000000000000000000000000000000000000000000000000001& E-519
+ convertToDouble -88218101363513E-170
+} 0x9f88395688592faf
+test expr-28.201 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +38639244311627 E-115 x 114ef3e205c817_0000000000000000000000000000000000000000000000000001& E-337
+ convertToDouble +38639244311627E-115
+} 0x2ae14ef3e205c817
+test expr-28.202 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +35593959807306 E261 x 1072f3819c1320_11111111111111111111111111111111111111111111111111110& E912
+ convertToDouble +35593959807306E261
+} 0x78f072f3819c1321
+test expr-28.203 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -53390939710959 E260 x -13bd243521b08d_11111111111111111111111111111111111111111111111111110& E909
+ convertToDouble -53390939710959E260
+} 0xf8c3bd243521b08e
+test expr-28.204 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +71187919614612 E261 x 1072f3819c1320_11111111111111111111111111111111111111111111111111110& E913
+ convertToDouble +71187919614612E261
+} 0x790072f3819c1321
+test expr-28.205 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -88984899518265 E260 x -1072f3819c1320_11111111111111111111111111111111111111111111111111110& E910
+ convertToDouble -88984899518265E260
+} 0xf8d072f3819c1321
+test expr-28.206 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +77003665618895 E-73 x 18bf7e7fa6f029_111111111111111111111111111111111111111111111111111111110& E-197
+ convertToDouble +77003665618895E-73
+} 0x33a8bf7e7fa6f02a
+test expr-28.207 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -15400733123779 E-72 x -18bf7e7fa6f029_111111111111111111111111111111111111111111111111111111110& E-196
+ convertToDouble -15400733123779E-72
+} 0xb3b8bf7e7fa6f02a
+test expr-28.208 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +61602932495116 E-72 x 18bf7e7fa6f029_111111111111111111111111111111111111111111111111111111110& E-194
+ convertToDouble +61602932495116E-72
+} 0x33d8bf7e7fa6f02a
+test expr-28.209 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -30801466247558 E-72 x -18bf7e7fa6f029_111111111111111111111111111111111111111111111111111111110& E-195
+ convertToDouble -30801466247558E-72
+} 0xb3c8bf7e7fa6f02a
+test expr-28.210 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +834735494917063 E-300 x 1fc6c26f899dd1_0000000000000000000000000000000000000000000000000000000001& E-948
+ convertToDouble +834735494917063E-300
+} 0x04bfc6c26f899dd1
+test expr-28.211 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -589795149206434 E-151 x -15f2df5e675a0f_0000000000000000000000000000000000000000000000000000000001& E-453
+ convertToDouble -589795149206434E-151
+} 0xa3a5f2df5e675a0f
+test expr-28.212 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +475603213226859 E-42 x 12d73088f4050a_000000000000000000000000000000000000000000000000000000001& E-91
+ convertToDouble +475603213226859E-42
+} 0x3a42d73088f4050a
+test expr-28.213 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -294897574603217 E-151 x -15f2df5e675a0f_0000000000000000000000000000000000000000000000000000000001& E-454
+ convertToDouble -294897574603217E-151
+} 0xa395f2df5e675a0f
+test expr-28.214 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +850813008001913 E93 x 172f7a1831ad70_11111111111111111111111111111111111111111111111111111110& E358
+ convertToDouble +850813008001913E93
+} 0x56572f7a1831ad71
+test expr-28.215 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -203449172043339 E185 x -1102b47e4af987_11111111111111111111111111111111111111111111111111111110& E662
+ convertToDouble -203449172043339E185
+} 0xe95102b47e4af988
+test expr-28.216 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +406898344086678 E185 x 1102b47e4af987_11111111111111111111111111111111111111111111111111111110& E663
+ convertToDouble +406898344086678E185
+} 0x696102b47e4af988
+test expr-28.217 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -813796688173356 E185 x -1102b47e4af987_11111111111111111111111111111111111111111111111111111110& E664
+ convertToDouble -813796688173356E185
+} 0xe97102b47e4af988
+test expr-28.218 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6045338514609393 E244 x 1f746182e6cd5d_00000000000000000000000000000000000000000000000000000000001& E862
+ convertToDouble +6045338514609393E244
+} 0x75df746182e6cd5d
+test expr-28.219 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5145963778954906 E142 x -1dfc11fbf46087_00000000000000000000000000000000000000000000000000000000001& E523
+ convertToDouble -5145963778954906E142
+} 0xe0adfc11fbf46087
+test expr-28.220 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2572981889477453 E142 x 1dfc11fbf46087_00000000000000000000000000000000000000000000000000000000001& E522
+ convertToDouble +2572981889477453E142
+} 0x609dfc11fbf46087
+test expr-28.221 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -6965949469487146 E74 x -15e2c10ad970b0_0000000000000000000000000000000000000000000000000000000001& E298
+ convertToDouble -6965949469487146E74
+} 0xd295e2c10ad970b0
+test expr-28.222 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6182410494241627 E-119 x 11b96458445d07_0000000000000000000000000000000000000000000000000000000000001& E-343
+ convertToDouble +6182410494241627E-119
+} 0x2a81b96458445d07
+test expr-28.223 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8510309498186985 E-277 x -1acc46749dccfe_000000000000000000000000000000000000000000000000000000000001& E-868
+ convertToDouble -8510309498186985E-277
+} 0x89bacc46749dccfe
+test expr-28.224 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6647704637273331 E-212 x 13e07d2c0cb1e9_0000000000000000000000000000000000000000000000000000000000001& E-652
+ convertToDouble +6647704637273331E-212
+} 0x1733e07d2c0cb1e9
+test expr-28.225 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -2215901545757777 E-212 x -1a80a6e566428c_000000000000000000000000000000000000000000000000000000000001& E-654
+ convertToDouble -2215901545757777E-212
+} 0x971a80a6e566428c
+test expr-28.226 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3771476185376383 E276 x 183010aba78a53_111111111111111111111111111111111111111111111111111111111110& E968
+ convertToDouble +3771476185376383E276
+} 0x7c783010aba78a54
+test expr-28.227 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3729901848043846 E212 x -1f7d6721f7f143_111111111111111111111111111111111111111111111111111111111110& E755
+ convertToDouble -3729901848043846E212
+} 0xef2f7d6721f7f144
+test expr-28.228 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3771476185376383 E277 x 1e3c14d6916ce8_111111111111111111111111111111111111111111111111111111111110& E971
+ convertToDouble +3771476185376383E277
+} 0x7cae3c14d6916ce9
+test expr-28.229 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9977830465649166 E119 x -15f6de9d5d6b5a_111111111111111111111111111111111111111111111111111111111110& E448
+ convertToDouble -9977830465649166E119
+} 0xdbf5f6de9d5d6b5b
+test expr-28.230 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8439928496349319 E-142 x 12483a0f125699_111111111111111111111111111111111111111111111111111111111110& E-419
+ convertToDouble +8439928496349319E-142
+} 0x25c2483a0f12569a
+test expr-28.231 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8204230082070882 E-59 x -1d460f4fca1d36_1111111111111111111111111111111111111111111111111111111110& E-144
+ convertToDouble -8204230082070882E-59
+} 0xb6fd460f4fca1d37
+test expr-28.232 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8853686434843997 E-244 x 157a340eb5d4f0_11111111111111111111111111111111111111111111111111111111110& E-758
+ convertToDouble +8853686434843997E-244
+} 0x10957a340eb5d4f1
+test expr-28.233 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5553274272288559 E-104 x -1c47d20a19d1ed_1111111111111111111111111111111111111111111111111111111110& E-294
+ convertToDouble -5553274272288559E-104
+} 0xad9c47d20a19d1ee
+test expr-28.234 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +36149023611096162 E144 x 1491daad0ba280_0000000000000000000000000000000000000000000000000000000000000001& E533
+ convertToDouble +36149023611096162E144
+} 0x614491daad0ba280
+test expr-28.235 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -36149023611096162 E147 x -14166f8cfd5cb1_0000000000000000000000000000000000000000000000000000000000000001& E543
+ convertToDouble -36149023611096162E147
+} 0xe1e4166f8cfd5cb1
+test expr-28.236 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +18074511805548081 E146 x 1011f2d73116f4_0000000000000000000000000000000000000000000000000000000000000001& E539
+ convertToDouble +18074511805548081E146
+} 0x61a011f2d73116f4
+test expr-28.237 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -18074511805548081 E147 x -14166f8cfd5cb1_0000000000000000000000000000000000000000000000000000000000000001& E542
+ convertToDouble -18074511805548081E147
+} 0xe1d4166f8cfd5cb1
+test expr-28.238 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +97338774138954421 E-290 x 10d9b828199006_0000000000000000000000000000000000000000000000000000000000000001& E-907
+ convertToDouble +97338774138954421E-290
+} 0x0740d9b828199006
+test expr-28.239 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -88133809804950961 E-308 x -119710dc581911_000000000000000000000000000000000000000000000000000000000000001& E-967
+ convertToDouble -88133809804950961E-308
+} 0x83819710dc581911
+test expr-28.240 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +94080055902682397 E-243 x 11d467e94b856e_0000000000000000000000000000000000000000000000000000000000000001& E-751
+ convertToDouble +94080055902682397E-243
+} 0x1101d467e94b856e
+test expr-28.241 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -24691002732654881 E-115 x -159a2783ce70ab_000000000000000000000000000000000000000000000000000000000000001& E-328
+ convertToDouble -24691002732654881E-115
+} 0xab759a2783ce70ab
+test expr-28.242 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +52306490527514614 E49 x 13de005bd620de_111111111111111111111111111111111111111111111111111111111111111110& E218
+ convertToDouble +52306490527514614E49
+} 0x4d93de005bd620df
+test expr-28.243 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -26153245263757307 E49 x -13de005bd620de_111111111111111111111111111111111111111111111111111111111111111110& E217
+ convertToDouble -26153245263757307E49
+} 0xcd83de005bd620df
+test expr-28.244 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +55188692254193604 E165 x 1a999ddec72ac9_11111111111111111111111111111111111111111111111111111111111110& E603
+ convertToDouble +55188692254193604E165
+} 0x65aa999ddec72aca
+test expr-28.245 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -68985865317742005 E164 x -1a999ddec72ac9_11111111111111111111111111111111111111111111111111111111111110& E600
+ convertToDouble -68985865317742005E164
+} 0xe57a999ddec72aca
+test expr-28.246 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +27176258005319167 E-261 x 17c0747bd76fa0_11111111111111111111111111111111111111111111111111111111111111110& E-813
+ convertToDouble +27176258005319167E-261
+} 0x0d27c0747bd76fa1
+test expr-28.247 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -73169230107256116 E-248 x -122cea327fa99c_1111111111111111111111111111111111111111111111111111111111110& E-768
+ convertToDouble -73169230107256116E-248
+} 0x8ff22cea327fa99d
+test expr-28.248 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +91461537634070145 E-249 x 122cea327fa99c_1111111111111111111111111111111111111111111111111111111111110& E-771
+ convertToDouble +91461537634070145E-249
+} 0x0fc22cea327fa99d
+test expr-28.249 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -54352516010638334 E-261 x -17c0747bd76fa0_11111111111111111111111111111111111111111111111111111111111111110& E-812
+ convertToDouble -54352516010638334E-261
+} 0x8d37c0747bd76fa1
+test expr-28.250 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +586144289638535878 E280 x 11eccbd6f62709_0000000000000000000000000000000000000000000000000000000000000000001& E989
+ convertToDouble +586144289638535878E280
+} 0x7dc1eccbd6f62709
+test expr-28.251 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -601117006785295431 E245 x -1e8b3525b3737e_000000000000000000000000000000000000000000000000000000000000000001& E872
+ convertToDouble -601117006785295431E245
+} 0xf67e8b3525b3737e
+test expr-28.252 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +293072144819267939 E280 x 11eccbd6f62709_0000000000000000000000000000000000000000000000000000000000000000001& E988
+ convertToDouble +293072144819267939E280
+} 0x7db1eccbd6f62709
+test expr-28.253 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -953184713238516652 E272 x -138fd93f1f5342_00000000000000000000000000000000000000000000000000000000000000001& E963
+ convertToDouble -953184713238516652E272
+} 0xfc238fd93f1f5342
+test expr-28.254 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +902042358290366539 E-281 x 122dc01ca1cb8c_0000000000000000000000000000000000000000000000000000000000000000001& E-874
+ convertToDouble +902042358290366539E-281
+} 0x09522dc01ca1cb8c
+test expr-28.255 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -557035730189854663 E-294 x -13bfac6bc4767b_00000000000000000000000000000000000000000000000000000000000000000001& E-918
+ convertToDouble -557035730189854663E-294
+} 0x8693bfac6bc4767b
+test expr-28.256 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +902042358290366539 E-280 x 16b93023ca3e6f_0000000000000000000000000000000000000000000000000000000000000000001& E-871
+ convertToDouble +902042358290366539E-280
+} 0x0986b93023ca3e6f
+test expr-28.257 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -354944100507554393 E-238 x -19a91cece6ad07_000000000000000000000000000000000000000000000000000000000000000001& E-733
+ convertToDouble -354944100507554393E-238
+} 0x9229a91cece6ad07
+test expr-28.258 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +272104041512242479 E199 x 1f92bacb3cb40b_11111111111111111111111111111111111111111111111111111111111111111111110& E718
+ convertToDouble +272104041512242479E199
+} 0x6cdf92bacb3cb40c
+test expr-28.259 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -816312124536727437 E199 x -17ae0c186d8708_11111111111111111111111111111111111111111111111111111111111111111111110& E720
+ convertToDouble -816312124536727437E199
+} 0xecf7ae0c186d8709
+test expr-28.260 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +544208083024484958 E199 x 1f92bacb3cb40b_11111111111111111111111111111111111111111111111111111111111111111111110& E719
+ convertToDouble +544208083024484958E199
+} 0x6cef92bacb3cb40c
+test expr-28.261 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -792644927852378159 E78 x -17bff336d8ff05_111111111111111111111111111111111111111111111111111111111111111111110& E318
+ convertToDouble -792644927852378159E78
+} 0xd3d7bff336d8ff06
+test expr-28.262 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -679406450132979175 E-263 x -17c0747bd76fa0_11111111111111111111111111111111111111111111111111111111111111110& E-815
+ convertToDouble -679406450132979175E-263
+} 0x8d07c0747bd76fa1
+test expr-28.263 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +543525160106383340 E-262 x 17c0747bd76fa0_11111111111111111111111111111111111111111111111111111111111111110& E-812
+ convertToDouble +543525160106383340E-262
+} 0x0d37c0747bd76fa1
+test expr-28.264 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7400253695682920196 E215 x 1dca94e3990085_00000000000000000000000000000000000000000000000000000000000000000000001& E776
+ convertToDouble +7400253695682920196E215
+} 0x707dca94e3990085
+test expr-28.265 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1850063423920730049 E215 x -1dca94e3990085_00000000000000000000000000000000000000000000000000000000000000000000001& E774
+ convertToDouble -1850063423920730049E215
+} 0xf05dca94e3990085
+test expr-28.266 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3700126847841460098 E215 x 1dca94e3990085_00000000000000000000000000000000000000000000000000000000000000000000001& E775
+ convertToDouble +3700126847841460098E215
+} 0x706dca94e3990085
+test expr-28.267 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9250317119603650245 E214 x -1dca94e3990085_00000000000000000000000000000000000000000000000000000000000000000000001& E773
+ convertToDouble -9250317119603650245E214
+} 0xf04dca94e3990085
+test expr-28.268 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8396094300569779681 E-252 x 1ab223efcee35a_0000000000000000000000000000000000000000000000000000000000000000000000001& E-775
+ convertToDouble +8396094300569779681E-252
+} 0x0f8ab223efcee35a
+test expr-28.269 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3507665085003296281 E-75 x -160499b881ea50_00000000000000000000000000000000000000000000000000000000000000000000001& E-188
+ convertToDouble -3507665085003296281E-75
+} 0xb4360499b881ea50
+test expr-28.270 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7015330170006592562 E-75 x 160499b881ea50_00000000000000000000000000000000000000000000000000000000000000000000001& E-187
+ convertToDouble +7015330170006592562E-75
+} 0x34460499b881ea50
+test expr-28.271 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7015330170006592562 E-74 x -1b85c026a264e4_00000000000000000000000000000000000000000000000000000000000000000000001& E-184
+ convertToDouble -7015330170006592562E-74
+} 0xb47b85c026a264e4
+test expr-28.272 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7185620434951919351 E205 x 18d92d2bcc7a80_1111111111111111111111111111111111111111111111111111111111111111111111110& E743
+ convertToDouble +7185620434951919351E205
+} 0x6e68d92d2bcc7a81
+test expr-28.273 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1360520207561212395 E198 x -1f92bacb3cb40b_11111111111111111111111111111111111111111111111111111111111111111111110& E717
+ convertToDouble -1360520207561212395E198
+} 0xeccf92bacb3cb40c
+test expr-28.274 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2178999185345151731 E-184 x 19b2c4d2a82335_1111111111111111111111111111111111111111111111111111111111111111111110& E-551
+ convertToDouble +2178999185345151731E-184
+} 0x1d89b2c4d2a82336
+test expr-28.275 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8691089486201567102 E-218 x -1a9c42e5b6d89e_1111111111111111111111111111111111111111111111111111111111111111111110& E-662
+ convertToDouble -8691089486201567102E-218
+} 0x969a9c42e5b6d89f
+test expr-28.276 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +4345544743100783551 E-218 x 1a9c42e5b6d89e_1111111111111111111111111111111111111111111111111111111111111111111110& E-663
+ convertToDouble +4345544743100783551E-218
+} 0x168a9c42e5b6d89f
+test expr-28.277 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -4357998370690303462 E-184 x -19b2c4d2a82335_1111111111111111111111111111111111111111111111111111111111111111111110& E-550
+ convertToDouble -4357998370690303462E-184
+} 0x9d99b2c4d2a82336
+test expr-28.278 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +59825267349106892461 E177 x 199c476d7868df_000000000000000000000000000000000000000000000000000000000000000000000001& E653
+ convertToDouble +59825267349106892461E177
+} 0x68c99c476d7868df
+test expr-28.279 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -62259110684423957791 E47 x -1d8f2cfc20d6e8_0000000000000000000000000000000000000000000000000000000000000000000000001& E221
+ convertToDouble -62259110684423957791E47
+} 0xcdcd8f2cfc20d6e8
+test expr-28.280 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +58380168477038565599 E265 x 1f686e9efbe48d_00000000000000000000000000000000000000000000000000000000000000000000000001& E945
+ convertToDouble +58380168477038565599E265
+} 0x7b0f686e9efbe48d
+test expr-28.281 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -62259110684423957791 E48 x -12797c1d948651_0000000000000000000000000000000000000000000000000000000000000000000000001& E225
+ convertToDouble -62259110684423957791E48
+} 0xce02797c1d948651
+test expr-28.282 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -33584377202279118724 E-252 x -1ab223efcee35a_0000000000000000000000000000000000000000000000000000000000000000000000001& E-773
+ convertToDouble -33584377202279118724E-252
+} 0x8faab223efcee35a
+test expr-28.283 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -57484963479615354808 E205 x -18d92d2bcc7a80_1111111111111111111111111111111111111111111111111111111111111111111111110& E746
+ convertToDouble -57484963479615354808E205
+} 0xee98d92d2bcc7a81
+test expr-28.284 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +71856204349519193510 E204 x 18d92d2bcc7a80_1111111111111111111111111111111111111111111111111111111111111111111111110& E743
+ convertToDouble +71856204349519193510E204
+} 0x6e68d92d2bcc7a81
+test expr-28.285 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -14371240869903838702 E205 x -18d92d2bcc7a80_1111111111111111111111111111111111111111111111111111111111111111111111110& E744
+ convertToDouble -14371240869903838702E205
+} 0xee78d92d2bcc7a81
+test expr-28.286 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +36992084760177624177 E-318 x 18c5f9551c2f99_111111111111111111111111111111111111111111111111111111111111111111111110& E-992
+ convertToDouble +36992084760177624177E-318
+} 0x01f8c5f9551c2f9a
+test expr-28.287 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -73984169520355248354 E-318 x -18c5f9551c2f99_111111111111111111111111111111111111111111111111111111111111111111111110& E-991
+ convertToDouble -73984169520355248354E-318
+} 0x8208c5f9551c2f9a
+test expr-28.288 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +99257763227713890244 E-115 x 15338a554b9ce0_11111111111111111111111111111111111111111111111111111111111111111111110& E-316
+ convertToDouble +99257763227713890244E-115
+} 0x2c35338a554b9ce1
+test expr-28.289 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -87336362425182547697 E-280 x -1130304e7d9c32_11111111111111111111111111111111111111111111111111111111111111111111110& E-864
+ convertToDouble -87336362425182547697E-280
+} 0x89f130304e7d9c33
+test expr-28.290 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7 E289 x 1cbb547777a284_10000000001& E962
+ convertToDouble +7E289
+} 0x7c1cbb547777a285
+test expr-28.291 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3 E153 x -1ca3d8e6d80cba_100000001& E509
+ convertToDouble -3E153
+} 0xdfcca3d8e6d80cbb
+test expr-28.292 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6 E153 x 1ca3d8e6d80cba_100000001& E510
+ convertToDouble +6E153
+} 0x5fdca3d8e6d80cbb
+test expr-28.293 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5 E243 x -176ec98994f488_10000001& E809
+ convertToDouble -5E243
+} 0xf2876ec98994f489
+test expr-28.294 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7 E-161 x 1f7e0db3799aa2_10000000001& E-533
+ convertToDouble +7E-161
+} 0x1eaf7e0db3799aa3
+test expr-28.295 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7 E-172 x -15a4337446ef2a_1000000001& E-569
+ convertToDouble -7E-172
+} 0x9c65a4337446ef2b
+test expr-28.296 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8 E-63 x 1a53fc9631d10c_10000001& E-207
+ convertToDouble +8E-63
+} 0x330a53fc9631d10d
+test expr-28.297 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7 E-113 x -158c47e6eea282_10000001& E-373
+ convertToDouble -7E-113
+} 0xa8a58c47e6eea283
+test expr-28.298 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8 E126 x 17a2ecc414a03f_0111111111110& E421
+ convertToDouble +8E126
+} 0x5a47a2ecc414a03f
+test expr-28.299 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -4 E126 x -17a2ecc414a03f_0111111111110& E420
+ convertToDouble -4E126
+} 0xda37a2ecc414a03f
+test expr-28.300 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +5 E125 x 17a2ecc414a03f_0111111111110& E417
+ convertToDouble +5E125
+} 0x5a07a2ecc414a03f
+test expr-28.301 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1 E126 x -17a2ecc414a03f_0111111111110& E418
+ convertToDouble -1E126
+} 0xda17a2ecc414a03f
+test expr-28.302 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8 E-163 x 1708d0f84d3de7_011111110& E-539
+ convertToDouble +8E-163
+} 0x1e4708d0f84d3de7
+test expr-28.303 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1 E-163 x -1708d0f84d3de7_011111110& E-542
+ convertToDouble -1E-163
+} 0x9e1708d0f84d3de7
+test expr-28.304 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2 E-163 x 1708d0f84d3de7_011111110& E-541
+ convertToDouble +2E-163
+} 0x1e2708d0f84d3de7
+test expr-28.305 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -4 E-163 x -1708d0f84d3de7_011111110& E-540
+ convertToDouble -4E-163
+} 0x9e3708d0f84d3de7
+test expr-28.306 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +51 E195 x 15d51d249dca42_1000000000001& E653
+ convertToDouble +51E195
+} 0x68c5d51d249dca43
+test expr-28.307 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -37 E46 x -1033d7eca0adee_100000000000001& E158
+ convertToDouble -37E46
+} 0xc9d033d7eca0adef
+test expr-28.308 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +74 E46 x 1033d7eca0adee_100000000000001& E159
+ convertToDouble +74E46
+} 0x49e033d7eca0adef
+test expr-28.309 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -56 E289 x -1cbb547777a284_10000000001& E965
+ convertToDouble -56E289
+} 0xfc4cbb547777a285
+test expr-28.310 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +69 E-145 x 158a41b31c9a9a_100000000001& E-476
+ convertToDouble +69E-145
+} 0x22358a41b31c9a9b
+test expr-28.311 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -70 E-162 x -1f7e0db3799aa2_10000000001& E-533
+ convertToDouble -70E-162
+} 0x9eaf7e0db3799aa3
+test expr-28.312 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +56 E-161 x 1f7e0db3799aa2_10000000001& E-530
+ convertToDouble +56E-161
+} 0x1edf7e0db3799aa3
+test expr-28.313 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -21 E-303 x -1ccd59caa6a750_10000000001& E-1003
+ convertToDouble -21E-303
+} 0x814ccd59caa6a751
+test expr-28.314 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +34 E-276 x 12d5a4350d30ff_011111111110& E-912
+ convertToDouble +34E-276
+} 0x06f2d5a4350d30ff
+test expr-28.315 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -68 E-276 x -12d5a4350d30ff_011111111110& E-911
+ convertToDouble -68E-276
+} 0x8702d5a4350d30ff
+test expr-28.316 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +85 E-277 x 12d5a4350d30ff_011111111110& E-914
+ convertToDouble +85E-277
+} 0x06d2d5a4350d30ff
+test expr-28.317 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -87 E-274 x -12d36cf48e7abd_011111111111110& E-904
+ convertToDouble -87E-274
+} 0x8772d36cf48e7abd
+test expr-28.318 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +829 E102 x 17221a79cdd1d8_1000000000000001& E348
+ convertToDouble +829E102
+} 0x55b7221a79cdd1d9
+test expr-28.319 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -623 E100 x -1640a62f3a83de_10000000000000000001& E341
+ convertToDouble -623E100
+} 0xd54640a62f3a83df
+test expr-28.320 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +723 E-162 x 145457ee24abd2_1000000000000001& E-529
+ convertToDouble +723E-162
+} 0x1ee45457ee24abd3
+test expr-28.321 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -457 E-102 x -1ffc81bc29f02a_100000000000000001& E-331
+ convertToDouble -457E-102
+} 0xab4ffc81bc29f02b
+test expr-28.322 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +914 E-102 x 1ffc81bc29f02a_100000000000000001& E-330
+ convertToDouble +914E-102
+} 0x2b5ffc81bc29f02b
+test expr-28.323 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -323 E-135 x -1d589ae4d70218_10000000000001& E-441
+ convertToDouble -323E-135
+} 0xa46d589ae4d70219
+test expr-28.324 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +151 E176 x 1dcf7df8f573b7_0111111111111111110& E591
+ convertToDouble +151E176
+} 0x64edcf7df8f573b7
+test expr-28.325 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -302 E176 x -1dcf7df8f573b7_0111111111111111110& E592
+ convertToDouble -302E176
+} 0xe4fdcf7df8f573b7
+test expr-28.326 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +921 E90 x 1c420a45fd70ff_0111111111111110& E308
+ convertToDouble +921E90
+} 0x533c420a45fd70ff
+test expr-28.327 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -604 E176 x -1dcf7df8f573b7_0111111111111111110& E593
+ convertToDouble -604E176
+} 0xe50dcf7df8f573b7
+test expr-28.328 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +823 E-206 x 14a48933c208ad_0111111111111110& E-675
+ convertToDouble +823E-206
+} 0x15c4a48933c208ad
+test expr-28.329 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -463 E-114 x -11d0c83f6378a5_011111111111110& E-370
+ convertToDouble -463E-114
+} 0xa8d1d0c83f6378a5
+test expr-28.330 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +348 E-274 x 12d36cf48e7abd_011111111111110& E-902
+ convertToDouble +348E-274
+} 0x0792d36cf48e7abd
+test expr-28.331 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9968 E100 x 1640a62f3a83de_10000000000000000001& E345
+ convertToDouble +9968E100
+} 0x558640a62f3a83df
+test expr-28.332 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -6230 E99 x -1640a62f3a83de_10000000000000000001& E341
+ convertToDouble -6230E99
+} 0xd54640a62f3a83df
+test expr-28.333 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +1246 E100 x 1640a62f3a83de_10000000000000000001& E342
+ convertToDouble +1246E100
+} 0x555640a62f3a83df
+test expr-28.334 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6676 E-296 x 15519ac5142aaa_1000000000000000000001& E-971
+ convertToDouble +6676E-296
+} 0x0345519ac5142aab
+test expr-28.335 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8345 E-297 x -15519ac5142aaa_1000000000000000000001& E-974
+ convertToDouble -8345E-297
+} 0x8315519ac5142aab
+test expr-28.336 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +1669 E-296 x 15519ac5142aaa_1000000000000000000001& E-973
+ convertToDouble +1669E-296
+} 0x0325519ac5142aab
+test expr-28.337 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3338 E-296 x -15519ac5142aaa_1000000000000000000001& E-972
+ convertToDouble -3338E-296
+} 0x8335519ac5142aab
+test expr-28.338 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3257 E58 x 1444b34a6fb3eb_01111111111111111110& E204
+ convertToDouble +3257E58
+} 0x4cb444b34a6fb3eb
+test expr-28.339 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -6514 E58 x -1444b34a6fb3eb_01111111111111111110& E205
+ convertToDouble -6514E58
+} 0xccc444b34a6fb3eb
+test expr-28.340 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2416 E176 x 1dcf7df8f573b7_0111111111111111110& E595
+ convertToDouble +2416E176
+} 0x652dcf7df8f573b7
+test expr-28.341 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8085 E-63 x 19fbf3c19b9a79_0111111111111111110& E-197
+ convertToDouble +8085E-63
+} 0x33a9fbf3c19b9a79
+test expr-28.342 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3234 E-62 x -19fbf3c19b9a79_0111111111111111110& E-195
+ convertToDouble -3234E-62
+} 0xb3c9fbf3c19b9a79
+test expr-28.343 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +1617 E-62 x 19fbf3c19b9a79_0111111111111111110& E-196
+ convertToDouble +1617E-62
+} 0x33b9fbf3c19b9a79
+test expr-28.344 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -6468 E-62 x -19fbf3c19b9a79_0111111111111111110& E-194
+ convertToDouble -6468E-62
+} 0xb3d9fbf3c19b9a79
+test expr-28.345 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +53418 E111 x 15b1051df943a8_1000000000000000000001& E384
+ convertToDouble +53418E111
+} 0x57f5b1051df943a9
+test expr-28.346 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -60513 E160 x -15043b64e56c72_1000000000000000000001& E547
+ convertToDouble -60513E160
+} 0xe225043b64e56c73
+test expr-28.347 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +26709 E111 x 15b1051df943a8_1000000000000000000001& E383
+ convertToDouble +26709E111
+} 0x57e5b1051df943a9
+test expr-28.348 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -99447 E166 x -10782189b336ae_1000000000000000000001& E568
+ convertToDouble -99447E166
+} 0xe370782189b336af
+test expr-28.349 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +12549 E48 x 10c52fe6dc6a1b_011111111111111111111110& E173
+ convertToDouble +12549E48
+} 0x4ac0c52fe6dc6a1b
+test expr-28.350 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -25098 E48 x -10c52fe6dc6a1b_011111111111111111111110& E174
+ convertToDouble -25098E48
+} 0xcad0c52fe6dc6a1b
+test expr-28.351 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +50196 E48 x 10c52fe6dc6a1b_011111111111111111111110& E175
+ convertToDouble +50196E48
+} 0x4ae0c52fe6dc6a1b
+test expr-28.352 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -62745 E47 x -10c52fe6dc6a1b_011111111111111111111110& E172
+ convertToDouble -62745E47
+} 0xcab0c52fe6dc6a1b
+test expr-28.353 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +83771 E-73 x 1ce886fb5ffd6d_0111111111111111111110& E-227
+ convertToDouble +83771E-73
+} 0x31cce886fb5ffd6d
+test expr-28.354 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -97451 E-167 x -1c0f220fb1c70d_01111111111111111111110& E-539
+ convertToDouble -97451E-167
+} 0x9e4c0f220fb1c70d
+test expr-28.355 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +86637 E-203 x 10943edb4e81db_0111111111111111111110& E-658
+ convertToDouble +86637E-203
+} 0x16d0943edb4e81db
+test expr-28.356 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -75569 E-254 x -15a462d91c6ab3_0111111111111111111111111110& E-828
+ convertToDouble -75569E-254
+} 0x8c35a462d91c6ab3
+test expr-28.357 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +473806 E83 x 17d15bf3186080_1000000000000000000000001& E294
+ convertToDouble +473806E83
+} 0x5257d15bf3186081
+test expr-28.358 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -947612 E83 x -17d15bf3186080_1000000000000000000000001& E295
+ convertToDouble -947612E83
+} 0xd267d15bf3186081
+test expr-28.359 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +292369 E76 x 18a85eb277e644_100000000000000000000000001& E270
+ convertToDouble +292369E76
+} 0x50d8a85eb277e645
+test expr-28.360 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -584738 E76 x -18a85eb277e644_100000000000000000000000001& E271
+ convertToDouble -584738E76
+} 0xd0e8a85eb277e645
+test expr-28.361 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +933587 E-140 x 1b248728b9c116_100000000000000000000000001& E-446
+ convertToDouble +933587E-140
+} 0x241b248728b9c117
+test expr-28.362 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -720919 E-14 x -1ef696965cbf04_10000000000000000000000001& E-28
+ convertToDouble -720919E-14
+} 0xbe3ef696965cbf05
+test expr-28.363 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +535001 E-149 x 10b38e07c745ae_1000000000000000000000001& E-476
+ convertToDouble +535001E-149
+} 0x2230b38e07c745af
+test expr-28.364 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -890521 E-235 x -114828ee39c852_1000000000000000000000001& E-761
+ convertToDouble -890521E-235
+} 0x90614828ee39c853
+test expr-28.365 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +548057 E81 x 11a1d9135cca53_0111111111111111111111110& E288
+ convertToDouble +548057E81
+} 0x51f1a1d9135cca53
+test expr-28.366 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -706181 E88 x -1b156ac4c2d1e5_0111111111111111111111110& E311
+ convertToDouble -706181E88
+} 0xd36b156ac4c2d1e5
+test expr-28.367 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +820997 E106 x 1b4f8b64fa125d_0111111111111111111111110& E371
+ convertToDouble +820997E106
+} 0x572b4f8b64fa125d
+test expr-28.368 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -320681 E63 x -17ca18a876c5ef_0111111111111111111111110& E227
+ convertToDouble -320681E63
+} 0xce27ca18a876c5ef
+test expr-28.369 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +928609 E-261 x 1be2dd66200bef_011111111111111111111111111110& E-848
+ convertToDouble +928609E-261
+} 0x0afbe2dd66200bef
+test expr-28.370 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -302276 E-254 x -15a462d91c6ab3_0111111111111111111111111110& E-826
+ convertToDouble -302276E-254
+} 0x8c55a462d91c6ab3
+test expr-28.371 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +151138 E-254 x 15a462d91c6ab3_0111111111111111111111111110& E-827
+ convertToDouble +151138E-254
+} 0x0c45a462d91c6ab3
+test expr-28.372 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +4691773 E45 x 19147b9330eaae_1000000000000000000000000001& E171
+ convertToDouble +4691773E45
+} 0x4aa9147b9330eaaf
+test expr-28.373 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9383546 E45 x -19147b9330eaae_1000000000000000000000000001& E172
+ convertToDouble -9383546E45
+} 0xcab9147b9330eaaf
+test expr-28.374 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3059949 E-243 x 13ecf22ea07862_10000000000000000000000000001& E-786
+ convertToDouble +3059949E-243
+} 0x0ed3ecf22ea07863
+test expr-28.375 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -6119898 E-243 x -13ecf22ea07862_10000000000000000000000000001& E-785
+ convertToDouble -6119898E-243
+} 0x8ee3ecf22ea07863
+test expr-28.376 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +5356626 E-213 x 1b84252abdf6ba_100000000000000000000000001& E-686
+ convertToDouble +5356626E-213
+} 0x151b84252abdf6bb
+test expr-28.377 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -4877378 E-199 x -11cd5cd90cb200_100000000000000000000000001& E-639
+ convertToDouble -4877378E-199
+} 0x9801cd5cd90cb201
+test expr-28.378 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7716693 E223 x 1972d9d2cff683_01111111111111111111111111110& E763
+ convertToDouble +7716693E223
+} 0x6fa972d9d2cff683
+test expr-28.379 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5452869 E109 x -16247b136fecc3_01111111111111111111111111110& E384
+ convertToDouble -5452869E109
+} 0xd7f6247b136fecc3
+test expr-28.380 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +4590831 E156 x 14689b4a5fa201_011111111111111111111111111110& E540
+ convertToDouble +4590831E156
+} 0x61b4689b4a5fa201
+test expr-28.381 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9181662 E156 x -14689b4a5fa201_011111111111111111111111111110& E541
+ convertToDouble -9181662E156
+} 0xe1c4689b4a5fa201
+test expr-28.382 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3714436 E-261 x -1be2dd66200bef_011111111111111111111111111110& E-846
+ convertToDouble -3714436E-261
+} 0x8b1be2dd66200bef
+test expr-28.383 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +4643045 E-262 x 1be2dd66200bef_011111111111111111111111111110& E-849
+ convertToDouble +4643045E-262
+} 0x0aebe2dd66200bef
+test expr-28.384 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7428872 E-261 x -1be2dd66200bef_011111111111111111111111111110& E-845
+ convertToDouble -7428872E-261
+} 0x8b2be2dd66200bef
+test expr-28.385 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +52942146 E130 x 16c31d08af89c2_10000000000000000000000000000001& E457
+ convertToDouble +52942146E130
+} 0x5c86c31d08af89c3
+test expr-28.386 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -27966061 E145 x -155bcf72fd10f8_1000000000000000000000000000000001& E506
+ convertToDouble -27966061E145
+} 0xdf955bcf72fd10f9
+test expr-28.387 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +26471073 E130 x 16c31d08af89c2_10000000000000000000000000000001& E456
+ convertToDouble +26471073E130
+} 0x5c76c31d08af89c3
+test expr-28.388 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -55932122 E145 x -155bcf72fd10f8_1000000000000000000000000000000001& E507
+ convertToDouble -55932122E145
+} 0xdfa55bcf72fd10f9
+test expr-28.389 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +95412548 E-99 x 18e0bfb98864c8_100000000000000000000000000000001& E-303
+ convertToDouble +95412548E-99
+} 0x2d08e0bfb98864c9
+test expr-28.390 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -47706274 E-99 x -18e0bfb98864c8_100000000000000000000000000000001& E-304
+ convertToDouble -47706274E-99
+} 0xacf8e0bfb98864c9
+test expr-28.391 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +23853137 E-99 x 18e0bfb98864c8_100000000000000000000000000000001& E-305
+ convertToDouble +23853137E-99
+} 0x2ce8e0bfb98864c9
+test expr-28.392 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -78493654 E-301 x -140d76077b648e_10000000000000000000000000000001& E-974
+ convertToDouble -78493654E-301
+} 0x83140d76077b648f
+test expr-28.393 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +65346417 E29 x 13aa1ad778f23b_0111111111111111111111111111110& E122
+ convertToDouble +65346417E29
+} 0x4793aa1ad778f23b
+test expr-28.394 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -51083099 E167 x -14a75eb58df47b_0111111111111111111111111111110& E580
+ convertToDouble -51083099E167
+} 0xe434a75eb58df47b
+test expr-28.395 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +89396333 E264 x 1526f061ca9053_0111111111111111111111111111111110& E903
+ convertToDouble +89396333E264
+} 0x786526f061ca9053
+test expr-28.396 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -84863171 E114 x -106e98f5ec8f37_0111111111111111111111111111111110& E405
+ convertToDouble -84863171E114
+} 0xd9406e98f5ec8f37
+test expr-28.397 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +59540836 E-251 x 10430c2d075c07_011111111111111111111111111111110& E-808
+ convertToDouble +59540836E-251
+} 0x0d70430c2d075c07
+test expr-28.398 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -74426045 E-252 x -10430c2d075c07_011111111111111111111111111111110& E-811
+ convertToDouble -74426045E-252
+} 0x8d40430c2d075c07
+test expr-28.399 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +14885209 E-251 x 10430c2d075c07_011111111111111111111111111111110& E-810
+ convertToDouble +14885209E-251
+} 0x0d50430c2d075c07
+test expr-28.400 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -29770418 E-251 x -10430c2d075c07_011111111111111111111111111111110& E-809
+ convertToDouble -29770418E-251
+} 0x8d60430c2d075c07
+test expr-28.401 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +982161308 E122 x 11b6231e18c5ca_100000000000000000000000000000000000000001& E435
+ convertToDouble +982161308E122
+} 0x5b21b6231e18c5cb
+test expr-28.402 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -245540327 E122 x -11b6231e18c5ca_100000000000000000000000000000000000000001& E433
+ convertToDouble -245540327E122
+} 0xdb01b6231e18c5cb
+test expr-28.403 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +491080654 E122 x 11b6231e18c5ca_100000000000000000000000000000000000000001& E434
+ convertToDouble +491080654E122
+} 0x5b11b6231e18c5cb
+test expr-28.404 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +525452622 E-310 x 12045136ce0340_1000000000000000000000000000000000001& E-1001
+ convertToDouble +525452622E-310
+} 0x0162045136ce0341
+test expr-28.405 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -771837113 E-134 x -14e61f991c4ed0_100000000000000000000000000000000001& E-416
+ convertToDouble -771837113E-134
+} 0xa5f4e61f991c4ed1
+test expr-28.406 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +820858081 E-150 x 14050669985a86_10000000000000000000000000000000001& E-469
+ convertToDouble +820858081E-150
+} 0x22a4050669985a87
+test expr-28.407 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -262726311 E-310 x -12045136ce0340_1000000000000000000000000000000000001& E-1002
+ convertToDouble -262726311E-310
+} 0x8152045136ce0341
+test expr-28.408 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +923091487 E209 x 10bc60e6896717_011111111111111111111111111111111110& E724
+ convertToDouble +923091487E209
+} 0x6d30bc60e6896717
+test expr-28.409 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -653777767 E273 x -120223f2b3a881_0111111111111111111111111111111111111110& E936
+ convertToDouble -653777767E273
+} 0xfa720223f2b3a881
+test expr-28.410 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +842116236 E-53 x 1809c5732cdc7f_0111111111111111111111111111111110& E-147
+ convertToDouble +842116236E-53
+} 0x36c809c5732cdc7f
+test expr-28.411 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -741111169 E-202 x -15a3e1d1b73099_01111111111111111111111111111111110& E-642
+ convertToDouble -741111169E-202
+} 0x97d5a3e1d1b73099
+test expr-28.412 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +839507247 E-284 x 129a1effc50859_0111111111111111111111111111111110& E-914
+ convertToDouble +839507247E-284
+} 0x06d29a1effc50859
+test expr-28.413 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -951487269 E-264 x -1c92befccb5f59_0111111111111111111111111111111110& E-848
+ convertToDouble -951487269E-264
+} 0x8afc92befccb5f59
+test expr-28.414 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9821613080 E121 x -11b6231e18c5ca_100000000000000000000000000000000000000001& E435
+ convertToDouble -9821613080E121
+} 0xdb21b6231e18c5cb
+test expr-28.415 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6677856011 E-31 x 193a6d11077292_100000000000000000000000000000000000001& E-71
+ convertToDouble +6677856011E-31
+} 0x3b893a6d11077293
+test expr-28.416 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3573796826 E-266 x -112be2041a79fc_100000000000000000000000000000000000001& E-852
+ convertToDouble -3573796826E-266
+} 0x8ab12be2041a79fd
+test expr-28.417 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7147593652 E-266 x 112be2041a79fc_100000000000000000000000000000000000001& E-851
+ convertToDouble +7147593652E-266
+} 0x0ac12be2041a79fd
+test expr-28.418 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9981396317 E-181 x -1edbd94cb50054_100000000000000000000000000000000000001& E-569
+ convertToDouble -9981396317E-181
+} 0x9c6edbd94cb50055
+test expr-28.419 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3268888835 E272 x 120223f2b3a881_0111111111111111111111111111111111111110& E935
+ convertToDouble +3268888835E272
+} 0x7a620223f2b3a881
+test expr-28.420 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -2615111068 E273 x -120223f2b3a881_0111111111111111111111111111111111111110& E938
+ convertToDouble -2615111068E273
+} 0xfa920223f2b3a881
+test expr-28.421 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +1307555534 E273 x 120223f2b3a881_0111111111111111111111111111111111111110& E937
+ convertToDouble +1307555534E273
+} 0x7a820223f2b3a881
+test expr-28.422 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2990671154 E-190 x 13db11ac608107_01111111111111111111111111111111111111110& E-600
+ convertToDouble +2990671154E-190
+} 0x1a73db11ac608107
+test expr-28.423 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1495335577 E-190 x -13db11ac608107_01111111111111111111111111111111111111110& E-601
+ convertToDouble -1495335577E-190
+} 0x9a63db11ac608107
+test expr-28.424 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +5981342308 E-190 x 13db11ac608107_01111111111111111111111111111111111111110& E-599
+ convertToDouble +5981342308E-190
+} 0x1a83db11ac608107
+test expr-28.425 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7476677885 E-191 x -13db11ac608107_01111111111111111111111111111111111111110& E-602
+ convertToDouble -7476677885E-191
+} 0x9a53db11ac608107
+test expr-28.426 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +82259684194 E-202 x 12c3e72d179606_1000000000000000000000000000000000000000001& E-635
+ convertToDouble +82259684194E-202
+} 0x1842c3e72d179607
+test expr-28.427 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -93227267727 E-49 x -1960fe08d5847e_100000000000000000000000000000000000000001& E-127
+ convertToDouble -93227267727E-49
+} 0xb80960fe08d5847f
+test expr-28.428 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +41129842097 E-202 x 12c3e72d179606_1000000000000000000000000000000000000000001& E-636
+ convertToDouble +41129842097E-202
+} 0x1832c3e72d179607
+test expr-28.429 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -47584241418 E-314 x -14e25dd3747e96_10000000000000000000000000000000000000001& E-1008
+ convertToDouble -47584241418E-314
+} 0x80f4e25dd3747e97
+test expr-28.430 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -79360293406 E92 x -1c58a00bb31863_01111111111111111111111111111111111111110& E341
+ convertToDouble -79360293406E92
+} 0xd54c58a00bb31863
+test expr-28.431 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +57332259349 E225 x 120811f528378b_01111111111111111111111111111111111111110& E783
+ convertToDouble +57332259349E225
+} 0x70e20811f528378b
+test expr-28.432 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -57202326162 E111 x -1626f1c480545b_01111111111111111111111111111111111111110& E404
+ convertToDouble -57202326162E111
+} 0xd93626f1c480545b
+test expr-28.433 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +86860597053 E-206 x 103b77d2b969d9_0111111111111111111111111111111111111111110& E-648
+ convertToDouble +86860597053E-206
+} 0x17703b77d2b969d9
+test expr-28.434 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -53827010643 E-200 x -132fa69a69bd6d_0111111111111111111111111111111111111111110& E-629
+ convertToDouble -53827010643E-200
+} 0x98a32fa69a69bd6d
+test expr-28.435 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +53587107423 E-61 x 100a19a3ffd981_011111111111111111111111111111111111111111110& E-167
+ convertToDouble +53587107423E-61
+} 0x35800a19a3ffd981
+test expr-28.436 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +635007636765 E200 x 1824e73a4f030e_100000000000000000000000000000000000000000001& E703
+ convertToDouble +635007636765E200
+} 0x6be824e73a4f030f
+test expr-28.437 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +508006109412 E201 x 1824e73a4f030e_100000000000000000000000000000000000000000001& E706
+ convertToDouble +508006109412E201
+} 0x6c1824e73a4f030f
+test expr-28.438 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -254003054706 E201 x -1824e73a4f030e_100000000000000000000000000000000000000000001& E705
+ convertToDouble -254003054706E201
+} 0xec0824e73a4f030f
+test expr-28.439 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +561029718715 E-72 x 1cd96a6972a14a_100000000000000000000000000000000000000000001& E-201
+ convertToDouble +561029718715E-72
+} 0x336cd96a6972a14b
+test expr-28.440 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -897647549944 E-71 x -1cd96a6972a14a_100000000000000000000000000000000000000000001& E-197
+ convertToDouble -897647549944E-71
+} 0xb3acd96a6972a14b
+test expr-28.441 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +112205943743 E-71 x 1cd96a6972a14a_100000000000000000000000000000000000000000001& E-200
+ convertToDouble +112205943743E-71
+} 0x337cd96a6972a14b
+test expr-28.442 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -873947086081 E-236 x -19e117541d04e6_1000000000000000000000000000000000000000000001& E-745
+ convertToDouble -873947086081E-236
+} 0x9169e117541d04e7
+test expr-28.443 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +809184709177 E116 x 1de27e59fb0679_011111111111111111111111111111111111111111110& E424
+ convertToDouble +809184709177E116
+} 0x5a7de27e59fb0679
+test expr-28.444 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -573112917422 E81 x -11958b36c5102b_01111111111111111111111111111111111111111111110& E308
+ convertToDouble -573112917422E81
+} 0xd331958b36c5102b
+test expr-28.445 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +286556458711 E81 x 11958b36c5102b_01111111111111111111111111111111111111111111110& E307
+ convertToDouble +286556458711E81
+} 0x5321958b36c5102b
+test expr-28.446 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +952805821491 E-259 x 1551767ef8a9a3_011111111111111111111111111111111111111111110& E-821
+ convertToDouble +952805821491E-259
+} 0x0ca551767ef8a9a3
+test expr-28.447 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -132189992873 E-44 x -1b746cf242410b_011111111111111111111111111111111111111111110& E-110
+ convertToDouble -132189992873E-44
+} 0xb91b746cf242410b
+test expr-28.448 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -173696038493 E-144 x -1f8fefbb3249d3_011111111111111111111111111111111111111111110& E-442
+ convertToDouble -173696038493E-144
+} 0xa45f8fefbb3249d3
+test expr-28.449 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +1831132757599 E-107 x 138e6edd48f2a2_1000000000000000000000000000000000000000000000001& E-315
+ convertToDouble +1831132757599E-107
+} 0x2c438e6edd48f2a3
+test expr-28.450 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9155663787995 E-108 x -138e6edd48f2a2_1000000000000000000000000000000000000000000000001& E-316
+ convertToDouble -9155663787995E-108
+} 0xac338e6edd48f2a3
+test expr-28.451 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7324531030396 E-107 x 138e6edd48f2a2_1000000000000000000000000000000000000000000000001& E-313
+ convertToDouble +7324531030396E-107
+} 0x2c638e6edd48f2a3
+test expr-28.452 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9277338894969 E-200 x -19d5a44fd99a6a_1000000000000000000000000000000000000000000000001& E-622
+ convertToDouble -9277338894969E-200
+} 0x9919d5a44fd99a6b
+test expr-28.453 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8188292423973 E287 x 1390273bf8f983_0111111111111111111111111111111111111111111111110& E996
+ convertToDouble +8188292423973E287
+} 0x7e3390273bf8f983
+test expr-28.454 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5672557437938 E59 x -148c2bd60a1523_011111111111111111111111111111111111111111111110& E238
+ convertToDouble -5672557437938E59
+} 0xced48c2bd60a1523
+test expr-28.455 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2836278718969 E59 x 148c2bd60a1523_011111111111111111111111111111111111111111111110& E237
+ convertToDouble +2836278718969E59
+} 0x4ec48c2bd60a1523
+test expr-28.456 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9995153153494 E54 x -17ba37c4fbe993_01111111111111111111111111111111111111111111110& E222
+ convertToDouble -9995153153494E54
+} 0xcdd7ba37c4fbe993
+test expr-28.457 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9224786422069 E-291 x 14ee5d56b32957_011111111111111111111111111111111111111111111111110& E-924
+ convertToDouble +9224786422069E-291
+} 0x0634ee5d56b32957
+test expr-28.458 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3142213164987 E-294 x -1d3409dfbca26f_011111111111111111111111111111111111111111111111110& E-936
+ convertToDouble -3142213164987E-294
+} 0x857d3409dfbca26f
+test expr-28.459 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6284426329974 E-294 x 1d3409dfbca26f_011111111111111111111111111111111111111111111111110& E-935
+ convertToDouble +6284426329974E-294
+} 0x058d3409dfbca26f
+test expr-28.460 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8340483752889 E-301 x -10419183e44b91_01111111111111111111111111111111111111111111111110& E-957
+ convertToDouble -8340483752889E-301
+} 0x8420419183e44b91
+test expr-28.461 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +67039371486466 E89 x 17f203339c9628_10000000000000000000000000000000000000000000000000001& E341
+ convertToDouble +67039371486466E89
+} 0x5547f203339c9629
+test expr-28.462 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -62150786615239 E197 x -12e79a035b9714_1000000000000000000000000000000000000000000000000001& E700
+ convertToDouble -62150786615239E197
+} 0xebb2e79a035b9715
+test expr-28.463 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +33519685743233 E89 x 17f203339c9628_10000000000000000000000000000000000000000000000000001& E340
+ convertToDouble +33519685743233E89
+} 0x5537f203339c9629
+test expr-28.464 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -52563419496999 E156 x -1bdb17625bf6e6_1000000000000000000000000000000000000000000000000001& E563
+ convertToDouble -52563419496999E156
+} 0xe32bdb17625bf6e7
+test expr-28.465 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +32599460466991 E-65 x 1f395d4c779d8e_1000000000000000000000000000000000000000000000000001& E-172
+ convertToDouble +32599460466991E-65
+} 0x353f395d4c779d8f
+test expr-28.466 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -41010988798007 E-133 x -152e1c9e04ee06_100000000000000000000000000000000000000000000000001& E-397
+ convertToDouble -41010988798007E-133
+} 0xa7252e1c9e04ee07
+test expr-28.467 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +65198920933982 E-65 x 1f395d4c779d8e_1000000000000000000000000000000000000000000000000001& E-171
+ convertToDouble +65198920933982E-65
+} 0x354f395d4c779d8f
+test expr-28.468 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -82021977596014 E-133 x -152e1c9e04ee06_100000000000000000000000000000000000000000000000001& E-396
+ convertToDouble -82021977596014E-133
+} 0xa7352e1c9e04ee07
+test expr-28.469 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +80527976643809 E61 x 1c7c5aea080a49_0111111111111111111111111111111111111111111111111110& E248
+ convertToDouble +80527976643809E61
+} 0x4f7c7c5aea080a49
+test expr-28.470 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -74712611505209 E158 x -1eeebe9ea010f3_011111111111111111111111111111111111111111111111110& E570
+ convertToDouble -74712611505209E158
+} 0xe39eeebe9ea010f3
+test expr-28.471 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +53390939710959 E261 x 18ac6d426a1cb1_0111111111111111111111111111111111111111111111111110& E912
+ convertToDouble +53390939710959E261
+} 0x78f8ac6d426a1cb1
+test expr-28.472 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -69277302659155 E225 x -1547166a3a2b0f_011111111111111111111111111111111111111111111111110& E793
+ convertToDouble -69277302659155E225
+} 0xf18547166a3a2b0f
+test expr-28.473 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +46202199371337 E-72 x 128f9edfbd341f_0111111111111111111111111111111111111111111111111111111110& E-194
+ convertToDouble +46202199371337E-72
+} 0x33d28f9edfbd341f
+test expr-28.474 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -23438635467783 E-179 x -1ba485b99e47af_0111111111111111111111111111111111111111111111111110& E-551
+ convertToDouble -23438635467783E-179
+} 0x9d8ba485b99e47af
+test expr-28.475 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +41921560615349 E-67 x 19b2a5c4041e4b_0111111111111111111111111111111111111111111111111110& E-178
+ convertToDouble +41921560615349E-67
+} 0x34d9b2a5c4041e4b
+test expr-28.476 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -92404398742674 E-72 x -128f9edfbd341f_0111111111111111111111111111111111111111111111111111111110& E-193
+ convertToDouble -92404398742674E-72
+} 0xb3e28f9edfbd341f
+test expr-28.477 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +738545606647197 E124 x 13d8886a766a20_100000000000000000000000000000000000000000000000000001& E461
+ convertToDouble +738545606647197E124
+} 0x5cc3d8886a766a21
+test expr-28.478 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -972708181182949 E117 x -15ed1f039cebfe_1000000000000000000000000000000000000000000000000000001& E438
+ convertToDouble -972708181182949E117
+} 0xdb55ed1f039cebff
+test expr-28.479 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -837992143580825 E87 x -17f203339c9628_10000000000000000000000000000000000000000000000000001& E338
+ convertToDouble -837992143580825E87
+} 0xd517f203339c9629
+test expr-28.480 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +609610927149051 E-255 x 104273b18918b0_100000000000000000000000000000000000000000000000000000001& E-798
+ convertToDouble +609610927149051E-255
+} 0x0e104273b18918b1
+test expr-28.481 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -475603213226859 E-41 x -178cfcab31064c_10000000000000000000000000000000000000000000000000000001& E-88
+ convertToDouble -475603213226859E-41
+} 0xba778cfcab31064d
+test expr-28.482 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +563002800671023 E-177 x 1035e7b5183922_10000000000000000000000000000000000000000000000000000001& E-539
+ convertToDouble +563002800671023E-177
+} 0x1e4035e7b5183923
+test expr-28.483 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -951206426453718 E-41 x -178cfcab31064c_10000000000000000000000000000000000000000000000000000001& E-87
+ convertToDouble -951206426453718E-41
+} 0xba878cfcab31064d
+test expr-28.484 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +805416432656519 E202 x 175d226331d039_01111111111111111111111111111111111111111111111111111110& E720
+ convertToDouble +805416432656519E202
+} 0x6cf75d226331d039
+test expr-28.485 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -530658674694337 E159 x -112a13daa46fe3_0111111111111111111111111111111111111111111111111111110& E577
+ convertToDouble -530658674694337E159
+} 0xe4012a13daa46fe3
+test expr-28.486 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +946574173863918 E208 x 1a2fbffdb7580b_011111111111111111111111111111111111111111111111111110& E740
+ convertToDouble +946574173863918E208
+} 0x6e3a2fbffdb7580b
+test expr-28.487 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -318329953318553 E113 x -178358811cbc95_011111111111111111111111111111111111111111111111111110& E423
+ convertToDouble -318329953318553E113
+} 0xda678358811cbc95
+test expr-28.488 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -462021993713370 E-73 x -128f9edfbd341f_0111111111111111111111111111111111111111111111111111111110& E-194
+ convertToDouble -462021993713370E-73
+} 0xb3d28f9edfbd341f
+test expr-28.489 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +369617594970696 E-72 x 128f9edfbd341f_0111111111111111111111111111111111111111111111111111111110& E-191
+ convertToDouble +369617594970696E-72
+} 0x34028f9edfbd341f
+test expr-28.490 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3666156212014994 E233 x 1a37935f3b71c8_100000000000000000000000000000000000000000000000000000001& E825
+ convertToDouble +3666156212014994E233
+} 0x738a37935f3b71c9
+test expr-28.491 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1833078106007497 E233 x -1a37935f3b71c8_100000000000000000000000000000000000000000000000000000001& E824
+ convertToDouble -1833078106007497E233
+} 0xf37a37935f3b71c9
+test expr-28.492 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8301790508624232 E174 x 1dcfee6690ffc6_100000000000000000000000000000000000000000000000000000001& E630
+ convertToDouble +8301790508624232E174
+} 0x675dcfee6690ffc7
+test expr-28.493 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1037723813578029 E174 x -1dcfee6690ffc6_100000000000000000000000000000000000000000000000000000001& E627
+ convertToDouble -1037723813578029E174
+} 0xe72dcfee6690ffc7
+test expr-28.494 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7297662880581139 E-286 x 18ac8c79e1ff18_1000000000000000000000000000000000000000000000000000000000001& E-898
+ convertToDouble +7297662880581139E-286
+} 0x07d8ac8c79e1ff19
+test expr-28.495 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5106185698912191 E-276 x -141934d77659be_1000000000000000000000000000000000000000000000000000000000001& E-865
+ convertToDouble -5106185698912191E-276
+} 0x89e41934d77659bf
+test expr-28.496 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7487252720986826 E-165 x 18823a57adbef8_100000000000000000000000000000000000000000000000000000000000001& E-496
+ convertToDouble +7487252720986826E-165
+} 0x20f8823a57adbef9
+test expr-28.497 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3743626360493413 E-165 x -18823a57adbef8_100000000000000000000000000000000000000000000000000000000000001& E-497
+ convertToDouble -3743626360493413E-165
+} 0xa0e8823a57adbef9
+test expr-28.498 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3773057430100257 E230 x 1ba10d818fdafd_0111111111111111111111111111111111111111111111111111111110& E815
+ convertToDouble +3773057430100257E230
+} 0x72eba10d818fdafd
+test expr-28.499 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7546114860200514 E230 x -1ba10d818fdafd_0111111111111111111111111111111111111111111111111111111110& E816
+ convertToDouble -7546114860200514E230
+} 0xf2fba10d818fdafd
+test expr-28.500 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +4321222892463822 E58 x 18750ea732fdad_011111111111111111111111111111111111111111111111111111110& E244
+ convertToDouble +4321222892463822E58
+} 0x4f38750ea732fdad
+test expr-28.501 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7793560217139653 E51 x -1280461b856ec5_0111111111111111111111111111111111111111111111111111111110& E222
+ convertToDouble -7793560217139653E51
+} 0xcdd280461b856ec5
+test expr-28.502 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +26525993941010681 E112 x 187dcbf6ad5cf8_10000000000000000000000000000000000000000000000000000000000001& E426
+ convertToDouble +26525993941010681E112
+} 0x5a987dcbf6ad5cf9
+test expr-28.503 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -53051987882021362 E112 x -187dcbf6ad5cf8_10000000000000000000000000000000000000000000000000000000000001& E427
+ convertToDouble -53051987882021362E112
+} 0xdaa87dcbf6ad5cf9
+test expr-28.504 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +72844871414247907 E77 x 1bf00baf60b70c_100000000000000000000000000000000000000000000000000000000001& E311
+ convertToDouble +72844871414247907E77
+} 0x536bf00baf60b70d
+test expr-28.505 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -88839359596763261 E105 x -1133b1a33a1108_100000000000000000000000000000000000000000000000000000000001& E405
+ convertToDouble -88839359596763261E105
+} 0xd94133b1a33a1109
+test expr-28.506 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +18718131802467065 E-166 x 18823a57adbef8_100000000000000000000000000000000000000000000000000000000000001& E-498
+ convertToDouble +18718131802467065E-166
+} 0x20d8823a57adbef9
+test expr-28.507 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -14974505441973652 E-165 x -18823a57adbef8_100000000000000000000000000000000000000000000000000000000000001& E-495
+ convertToDouble -14974505441973652E-165
+} 0xa108823a57adbef9
+test expr-28.508 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +73429396004640239 E106 x 11c5cb19ef3451_01111111111111111111111111111111111111111111111111111111111110& E408
+ convertToDouble +73429396004640239E106
+} 0x5971c5cb19ef3451
+test expr-28.509 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -58483921078398283 E57 x -108ce499519ce3_0111111111111111111111111111111111111111111111111111111111111110& E245
+ convertToDouble -58483921078398283E57
+} 0xcf408ce499519ce3
+test expr-28.510 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +41391519190645203 E165 x 13f33667156017_011111111111111111111111111111111111111111111111111111111111110& E603
+ convertToDouble +41391519190645203E165
+} 0x65a3f33667156017
+test expr-28.511 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -82783038381290406 E165 x -13f33667156017_011111111111111111111111111111111111111111111111111111111111110& E604
+ convertToDouble -82783038381290406E165
+} 0xe5b3f33667156017
+test expr-28.512 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +58767043776702677 E-163 x 12c92fee3a3867_0111111111111111111111111111111111111111111111111111111111110& E-486
+ convertToDouble +58767043776702677E-163
+} 0x2192c92fee3a3867
+test expr-28.513 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -90506231831231999 E-129 x -1bdc4114397ff3_01111111111111111111111111111111111111111111111111111111111110& E-373
+ convertToDouble -90506231831231999E-129
+} 0xa8abdc4114397ff3
+test expr-28.514 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +64409240769861689 E-159 x 192238f7987779_011111111111111111111111111111111111111111111111111111111111110& E-473
+ convertToDouble +64409240769861689E-159
+} 0x22692238f7987779
+test expr-28.515 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -77305427432277771 E-190 x -1e978b7780b613_0111111111111111111111111111111111111111111111111111111111110& E-576
+ convertToDouble -77305427432277771E-190
+} 0x9bfe978b7780b613
+test expr-28.516 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +476592356619258326 E273 x 1873cf8ee72812_10000000000000000000000000000000000000000000000000000000000000001& E965
+ convertToDouble +476592356619258326E273
+} 0x7c4873cf8ee72813
+test expr-28.517 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -953184713238516652 E273 x -1873cf8ee72812_10000000000000000000000000000000000000000000000000000000000000001& E966
+ convertToDouble -953184713238516652E273
+} 0xfc5873cf8ee72813
+test expr-28.518 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +899810892172646163 E283 x 1adf51fa055e02_100000000000000000000000000000000000000000000000000000000000000000001& E999
+ convertToDouble +899810892172646163E283
+} 0x7e6adf51fa055e03
+test expr-28.519 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -929167076892018333 E187 x -1da2c42fce2bc4_10000000000000000000000000000000000000000000000000000000000000000001& E680
+ convertToDouble -929167076892018333E187
+} 0xea7da2c42fce2bc5
+test expr-28.520 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +647761278967534239 E-312 x 1a7a2476ec0b3e_10000000000000000000000000000000000000000000000000000000000000001& E-978
+ convertToDouble +647761278967534239E-312
+} 0x02da7a2476ec0b3f
+test expr-28.521 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -644290479820542942 E-180 x -128d1407dfa832_10000000000000000000000000000000000000000000000000000000000000001& E-539
+ convertToDouble -644290479820542942E-180
+} 0x9e428d1407dfa833
+test expr-28.522 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +926145344610700019 E-225 x 1307a67f1f69fe_10000000000000000000000000000000000000000000000000000000000000000001& E-688
+ convertToDouble +926145344610700019E-225
+} 0x14f307a67f1f69ff
+test expr-28.523 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -958507931896511964 E-246 x -17406753df2f0c_10000000000000000000000000000000000000000000000000000000000000001& E-758
+ convertToDouble -958507931896511964E-246
+} 0x9097406753df2f0d
+test expr-28.524 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +272104041512242479 E200 x 13bbb4bf05f087_011111111111111111111111111111111111111111111111111111111111111111111110& E722
+ convertToDouble +272104041512242479E200
+} 0x6d13bbb4bf05f087
+test expr-28.525 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -792644927852378159 E79 x -1daff0048f3ec7_011111111111111111111111111111111111111111111111111111111111111111110& E321
+ convertToDouble -792644927852378159E79
+} 0xd40daff0048f3ec7
+test expr-28.526 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +544208083024484958 E200 x 13bbb4bf05f087_011111111111111111111111111111111111111111111111111111111111111111111110& E723
+ convertToDouble +544208083024484958E200
+} 0x6d23bbb4bf05f087
+test expr-28.527 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -929963218616126365 E290 x -108dcc0c505461_01111111111111111111111111111111111111111111111111111111111111110& E1023
+ convertToDouble -929963218616126365E290
+} 0xffe08dcc0c505461
+test expr-28.528 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +305574339166810102 E-219 x 17f399fe02c4b9_011111111111111111111111111111111111111111111111111111111111111110& E-670
+ convertToDouble +305574339166810102E-219
+} 0x1617f399fe02c4b9
+test expr-28.529 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -152787169583405051 E-219 x -17f399fe02c4b9_011111111111111111111111111111111111111111111111111111111111111110& E-671
+ convertToDouble -152787169583405051E-219
+} 0x9607f399fe02c4b9
+test expr-28.530 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +611148678333620204 E-219 x 17f399fe02c4b9_011111111111111111111111111111111111111111111111111111111111111110& E-669
+ convertToDouble +611148678333620204E-219
+} 0x1627f399fe02c4b9
+test expr-28.531 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -763935847917025255 E-220 x -17f399fe02c4b9_011111111111111111111111111111111111111111111111111111111111111110& E-672
+ convertToDouble -763935847917025255E-220
+} 0x95f7f399fe02c4b9
+test expr-28.532 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7439550220920798612 E158 x 177fe14f40159a_10000000000000000000000000000000000000000000000000000000000000000000001& E587
+ convertToDouble +7439550220920798612E158
+} 0x64a77fe14f40159b
+test expr-28.533 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3719775110460399306 E158 x -177fe14f40159a_10000000000000000000000000000000000000000000000000000000000000000000001& E586
+ convertToDouble -3719775110460399306E158
+} 0xe4977fe14f40159b
+test expr-28.534 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9299437776150998265 E157 x 177fe14f40159a_10000000000000000000000000000000000000000000000000000000000000000000001& E584
+ convertToDouble +9299437776150998265E157
+} 0x64777fe14f40159b
+test expr-28.535 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7120190517612959703 E120 x -13220dcd5899fc_1000000000000000000000000000000000000000000000000000000000000000000000001& E461
+ convertToDouble -7120190517612959703E120
+} 0xdcc3220dcd5899fd
+test expr-28.536 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3507665085003296281 E-73 x 11339818257f0e_100000000000000000000000000000000000000000000000000000000000000000000001& E-181
+ convertToDouble +3507665085003296281E-73
+} 0x34a1339818257f0f
+test expr-28.537 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7015330170006592562 E-73 x -11339818257f0e_100000000000000000000000000000000000000000000000000000000000000000000001& E-180
+ convertToDouble -7015330170006592562E-73
+} 0xb4b1339818257f0f
+test expr-28.538 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -6684428762278255956 E-294 x -1d9f82a1a6b1b8_10000000000000000000000000000000000000000000000000000000000000000001& E-915
+ convertToDouble -6684428762278255956E-294
+} 0x86cd9f82a1a6b1b9
+test expr-28.539 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1088416166048969916 E200 x -13bbb4bf05f087_011111111111111111111111111111111111111111111111111111111111111111111110& E724
+ convertToDouble -1088416166048969916E200
+} 0xed33bbb4bf05f087
+test expr-28.540 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8707329328391759328 E200 x -13bbb4bf05f087_011111111111111111111111111111111111111111111111111111111111111111111110& E727
+ convertToDouble -8707329328391759328E200
+} 0xed63bbb4bf05f087
+test expr-28.541 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +4439021781608558002 E-65 x 1038168b71e2c9_01111111111111111111111111111111111111111111111111111111111111111110& E-154
+ convertToDouble +4439021781608558002E-65
+} 0x365038168b71e2c9
+test expr-28.542 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8878043563217116004 E-65 x -1038168b71e2c9_01111111111111111111111111111111111111111111111111111111111111111110& E-153
+ convertToDouble -8878043563217116004E-65
+} 0xb66038168b71e2c9
+test expr-28.543 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2219510890804279001 E-65 x 1038168b71e2c9_01111111111111111111111111111111111111111111111111111111111111111110& E-155
+ convertToDouble +2219510890804279001E-65
+} 0x364038168b71e2c9
+test expr-28.544 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +33051223951904955802 E55 x 1762068a24fd54_1000000000000000000000000000000000000000000000000000000000000000000000001& E247
+ convertToDouble +33051223951904955802E55
+} 0x4f6762068a24fd55
+test expr-28.545 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -56961524140903677624 E120 x -13220dcd5899fc_1000000000000000000000000000000000000000000000000000000000000000000000001& E464
+ convertToDouble -56961524140903677624E120
+} 0xdcf3220dcd5899fd
+test expr-28.546 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +71201905176129597030 E119 x 13220dcd5899fc_1000000000000000000000000000000000000000000000000000000000000000000000001& E461
+ convertToDouble +71201905176129597030E119
+} 0x5cc3220dcd5899fd
+test expr-28.547 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +14030660340013185124 E-73 x 11339818257f0e_100000000000000000000000000000000000000000000000000000000000000000000001& E-179
+ convertToDouble +14030660340013185124E-73
+} 0x34c1339818257f0f
+test expr-28.548 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -17538325425016481405 E-74 x -11339818257f0e_100000000000000000000000000000000000000000000000000000000000000000000001& E-182
+ convertToDouble -17538325425016481405E-74
+} 0xb491339818257f0f
+test expr-28.549 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +67536228609141569109 E-133 x 10a1b35cf2a635_01111111111111111111111111111111111111111111111111111111111111111111110& E-376
+ convertToDouble +67536228609141569109E-133
+} 0x2870a1b35cf2a635
+test expr-28.550 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -35620497849450218807 E-306 x -15b22082529425_0111111111111111111111111111111111111111111111111111111111111111111111110& E-952
+ convertToDouble -35620497849450218807E-306
+} 0x8475b22082529425
+test expr-28.551 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +66550376797582521751 E-126 x 13897c0ede6c69_01111111111111111111111111111111111111111111111111111111111111111111110& E-353
+ convertToDouble +66550376797582521751E-126
+} 0x29e3897c0ede6c69
+test expr-28.552 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -71240995698900437614 E-306 x -15b22082529425_0111111111111111111111111111111111111111111111111111111111111111111111110& E-951
+ convertToDouble -71240995698900437614E-306
+} 0x8485b22082529425
+test expr-28.553 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +3 E24 x 13da329b633647_0001& E81
+ convertToDouble +3E24
+} 0x4503da329b633647
+test expr-28.554 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -6 E24 x -13da329b633647_0001& E82
+ convertToDouble -6E24
+} 0xc513da329b633647
+test expr-28.555 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6 E26 x 1f04ef12cb04cf_0001& E88
+ convertToDouble +6E26
+} 0x457f04ef12cb04cf
+test expr-28.556 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -7 E25 x -1cf389cd46047d_0000001& E85
+ convertToDouble -7E25
+} 0xc54cf389cd46047d
+test expr-28.557 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +1 E-14 x 16849b86a12b9b_00000001& E-47
+ convertToDouble +1E-14
+} 0x3d06849b86a12b9b
+test expr-28.558 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2 E-14 x -16849b86a12b9b_00000001& E-46
+ convertToDouble -2E-14
+} 0xbd16849b86a12b9b
+test expr-28.559 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4 E-14 x 16849b86a12b9b_00000001& E-45
+ convertToDouble +4E-14
+} 0x3d26849b86a12b9b
+test expr-28.560 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8 E-14 x -16849b86a12b9b_00000001& E-44
+ convertToDouble -8E-14
+} 0xbd36849b86a12b9b
+test expr-28.561 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +5 E26 x 19d971e4fe8401_1110& E88
+ convertToDouble +5E26
+} 0x4579d971e4fe8402
+test expr-28.562 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8 E27 x -19d971e4fe8401_1110& E92
+ convertToDouble -8E27
+} 0xc5b9d971e4fe8402
+test expr-28.563 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +1 E27 x 19d971e4fe8401_1110& E89
+ convertToDouble +1E27
+} 0x4589d971e4fe8402
+test expr-28.564 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4 E27 x -19d971e4fe8401_1110& E91
+ convertToDouble -4E27
+} 0xc5a9d971e4fe8402
+test expr-28.565 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9 E-13 x 1faa7ab552a551_111110& E-41
+ convertToDouble +9E-13
+} 0x3d6faa7ab552a552
+test expr-28.566 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -7 E-20 x -14a90ceafff9de_11110& E-64
+ convertToDouble -7E-20
+} 0xbbf4a90ceafff9df
+test expr-28.567 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +56 E25 x 1cf389cd46047d_0000001& E88
+ convertToDouble +56E25
+} 0x457cf389cd46047d
+test expr-28.568 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -70 E24 x -1cf389cd46047d_0000001& E85
+ convertToDouble -70E24
+} 0xc54cf389cd46047d
+test expr-28.569 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +51 E26 x 107a9f01fbda8e_0000001& E92
+ convertToDouble +51E26
+} 0x45b07a9f01fbda8e
+test expr-28.570 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +71 E-17 x 19949819f693d7_00000000001& E-51
+ convertToDouble +71E-17
+} 0x3cc9949819f693d7
+test expr-28.571 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -31 E-5 x -1450efdc9c4da9_00000000001& E-12
+ convertToDouble -31E-5
+} 0xbf3450efdc9c4da9
+test expr-28.572 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +62 E-5 x 1450efdc9c4da9_00000000001& E-11
+ convertToDouble +62E-5
+} 0x3f4450efdc9c4da9
+test expr-28.573 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -94 E-8 x -1f8a89dc374df5_0000000001& E-21
+ convertToDouble -94E-8
+} 0xbeaf8a89dc374df5
+test expr-28.574 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +67 E27 x 1b0fa33bba7231_11111110& E95
+ convertToDouble +67E27
+} 0x45eb0fa33bba7232
+test expr-28.575 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -81 E24 x -10c01ab31bb5cb_1111110& E86
+ convertToDouble -81E24
+} 0xc550c01ab31bb5cc
+test expr-28.576 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +54 E23 x 11ddfa58a6173f_111110& E82
+ convertToDouble +54E23
+} 0x4511ddfa58a61740
+test expr-28.577 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -54 E25 x -1bead72a838453_111110& E88
+ convertToDouble -54E25
+} 0xc57bead72a838454
+test expr-28.578 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +63 E-22 x 1dc03b8fd70169_11111111110& E-68
+ convertToDouble +63E-22
+} 0x3bbdc03b8fd7016a
+test expr-28.579 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -63 E-23 x -17ccfc73126787_11111111110& E-71
+ convertToDouble -63E-23
+} 0xbb87ccfc73126788
+test expr-28.580 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +43 E-4 x 119ce075f6fd21_111111110& E-8
+ convertToDouble +43E-4
+} 0x3f719ce075f6fd22
+test expr-28.581 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -86 E-4 x -119ce075f6fd21_111111110& E-7
+ convertToDouble -86E-4
+} 0xbf819ce075f6fd22
+test expr-28.582 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +942 E26 x 1306069e8681f3_00000000001& E96
+ convertToDouble +942E26
+} 0x45f306069e8681f3
+test expr-28.583 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -471 E25 x -1e700a973d9cb8_0000000001& E91
+ convertToDouble -471E25
+} 0xc5ae700a973d9cb8
+test expr-28.584 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +803 E24 x 14c1cee9cd666b_000000000001& E89
+ convertToDouble +803E24
+} 0x4584c1cee9cd666b
+test expr-28.585 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -471 E26 x -1306069e8681f3_00000000001& E95
+ convertToDouble -471E26
+} 0xc5e306069e8681f3
+test expr-28.586 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -409 E-21 x -1e2dcaa4115622_000000000001& E-62
+ convertToDouble -409E-21
+} 0xbc1e2dcaa4115622
+test expr-28.587 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +818 E-21 x 1e2dcaa4115622_000000000001& E-61
+ convertToDouble +818E-21
+} 0x3c2e2dcaa4115622
+test expr-28.588 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -867 E-8 x -122eabba029aba_000000000001& E-17
+ convertToDouble -867E-8
+} 0xbee22eabba029aba
+test expr-28.589 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +538 E27 x 1b297cad9f70b5_1111111111111110& E98
+ convertToDouble +538E27
+} 0x461b297cad9f70b6
+test expr-28.590 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -857 E24 x -16272678ba603b_11111111110& E89
+ convertToDouble -857E24
+} 0xc586272678ba603c
+test expr-28.591 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +269 E27 x 1b297cad9f70b5_1111111111111110& E97
+ convertToDouble +269E27
+} 0x460b297cad9f70b6
+test expr-28.592 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -403 E26 x -1046ec1e31dd85_1111111110& E95
+ convertToDouble -403E26
+} 0xc5e046ec1e31dd86
+test expr-28.593 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +959 E-7 x 1923bd746a3527_11111111111110& E-14
+ convertToDouble +959E-7
+} 0x3f1923bd746a3528
+test expr-28.594 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -959 E-6 x -1f6cacd184c271_1111111111110& E-11
+ convertToDouble -959E-6
+} 0xbf4f6cacd184c272
+test expr-28.595 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +373 E-27 x 1cdc06b20ef182_1111111111110& E-82
+ convertToDouble +373E-27
+} 0x3adcdc06b20ef183
+test expr-28.596 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -746 E-27 x -1cdc06b20ef182_1111111111110& E-81
+ convertToDouble -746E-27
+} 0xbaecdc06b20ef183
+test expr-28.597 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4069 E24 x 1a4b9887fbfe7a_0000000000001& E91
+ convertToDouble +4069E24
+} 0x45aa4b9887fbfe7a
+test expr-28.598 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4069 E23 x -150946d32ffec8_0000000000001& E88
+ convertToDouble -4069E23
+} 0xc5750946d32ffec8
+test expr-28.599 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8138 E24 x -1a4b9887fbfe7a_0000000000001& E92
+ convertToDouble -8138E24
+} 0xc5ba4b9887fbfe7a
+test expr-28.600 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8294 E-15 x 123d1b5eb1d778_000000000000000001& E-37
+ convertToDouble +8294E-15
+} 0x3da23d1b5eb1d778
+test expr-28.601 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4147 E-14 x -16cc62365e4d56_00000000000000001& E-35
+ convertToDouble -4147E-14
+} 0xbdc6cc62365e4d56
+test expr-28.602 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4147 E-15 x 123d1b5eb1d778_000000000000000001& E-38
+ convertToDouble +4147E-15
+} 0x3d923d1b5eb1d778
+test expr-28.603 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8294 E-14 x -16cc62365e4d56_00000000000000001& E-34
+ convertToDouble -8294E-14
+} 0xbdd6cc62365e4d56
+test expr-28.604 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +538 E27 x 1b297cad9f70b5_1111111111111110& E98
+ convertToDouble +538E27
+} 0x461b297cad9f70b6
+test expr-28.605 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2690 E26 x -1b297cad9f70b5_1111111111111110& E97
+ convertToDouble -2690E26
+} 0xc60b297cad9f70b6
+test expr-28.606 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +269 E27 x 1b297cad9f70b5_1111111111111110& E97
+ convertToDouble +269E27
+} 0x460b297cad9f70b6
+test expr-28.607 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2152 E27 x -1b297cad9f70b5_1111111111111110& E100
+ convertToDouble -2152E27
+} 0xc63b297cad9f70b6
+test expr-28.608 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +1721 E-17 x 136071dcae4564_111111111111110& E-46
+ convertToDouble +1721E-17
+} 0x3d136071dcae4565
+test expr-28.609 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -7979 E-27 x -134ac304747faf_111111111111110& E-77
+ convertToDouble -7979E-27
+} 0xbb234ac304747fb0
+test expr-28.610 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6884 E-17 x 136071dcae4564_111111111111110& E-44
+ convertToDouble +6884E-17
+} 0x3d336071dcae4565
+test expr-28.611 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8605 E-18 x -136071dcae4564_111111111111110& E-47
+ convertToDouble -8605E-18
+} 0xbd036071dcae4565
+test expr-28.612 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +82854 E27 x 10570ed9e3cecc_00000000000000001& E106
+ convertToDouble +82854E27
+} 0x4690570ed9e3cecc
+test expr-28.613 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -55684 E24 x -167d9735144ae3_00000000000000001& E95
+ convertToDouble -55684E24
+} 0xc5e67d9735144ae3
+test expr-28.614 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +27842 E24 x 167d9735144ae3_00000000000000001& E94
+ convertToDouble +27842E24
+} 0x45d67d9735144ae3
+test expr-28.615 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -48959 E25 x -18b7cd6ca56f85_00000000000000001& E98
+ convertToDouble -48959E25
+} 0xc618b7cd6ca56f85
+test expr-28.616 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +81921 E-17 x 1cd2c9a6cdd003_000000000000000000001& E-41
+ convertToDouble +81921E-17
+} 0x3d6cd2c9a6cdd003
+test expr-28.617 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -76207 E-8 x -18f8b4dd16f1df_0000000000000000001& E-11
+ convertToDouble -76207E-8
+} 0xbf48f8b4dd16f1df
+test expr-28.618 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4147 E-15 x 123d1b5eb1d778_000000000000000001& E-38
+ convertToDouble +4147E-15
+} 0x3d923d1b5eb1d778
+test expr-28.619 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -41470 E-16 x -123d1b5eb1d778_000000000000000001& E-38
+ convertToDouble -41470E-16
+} 0xbd923d1b5eb1d778
+test expr-28.620 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +89309 E24 x 12092ac5f2019e_1111111111111111110& E96
+ convertToDouble +89309E24
+} 0x45f2092ac5f2019f
+test expr-28.621 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +75859 E26 x 17efd75a2938eb_1111111111111111111110& E102
+ convertToDouble +75859E26
+} 0x4657efd75a2938ec
+test expr-28.622 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -75859 E25 x -132645e1ba93ef_1111111111111111111110& E99
+ convertToDouble -75859E25
+} 0xc6232645e1ba93f0
+test expr-28.623 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +14257 E-23 x 150a246ecd44f2_1111111111111111110& E-63
+ convertToDouble +14257E-23
+} 0x3c050a246ecd44f3
+test expr-28.624 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -28514 E-23 x -150a246ecd44f2_1111111111111111110& E-62
+ convertToDouble -28514E-23
+} 0xbc150a246ecd44f3
+test expr-28.625 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +57028 E-23 x 150a246ecd44f2_1111111111111111110& E-61
+ convertToDouble +57028E-23
+} 0x3c250a246ecd44f3
+test expr-28.626 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -71285 E-24 x -150a246ecd44f2_1111111111111111110& E-64
+ convertToDouble -71285E-24
+} 0xbbf50a246ecd44f3
+test expr-28.627 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +344863 E27 x 1100c873963d6d_00000000000000000001& E108
+ convertToDouble +344863E27
+} 0x46b100c873963d6d
+test expr-28.628 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -951735 E27 x -17764ad224e24a_000000000000000000001& E109
+ convertToDouble -951735E27
+} 0xc6c7764ad224e24a
+test expr-28.629 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +200677 E23 x 1035e73135b834_0000000000000000001& E94
+ convertToDouble +200677E23
+} 0x45d035e73135b834
+test expr-28.630 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -401354 E24 x -144360fd832641_0000000000000000001& E98
+ convertToDouble -401354E24
+} 0xc6144360fd832641
+test expr-28.631 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +839604 E-11 x 119b96f36ec68b_00000000000000000000000001& E-17
+ convertToDouble +839604E-11
+} 0x3ee19b96f36ec68b
+test expr-28.632 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -209901 E-11 x -119b96f36ec68b_00000000000000000000000001& E-19
+ convertToDouble -209901E-11
+} 0xbec19b96f36ec68b
+test expr-28.633 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +419802 E-11 x 119b96f36ec68b_00000000000000000000000001& E-18
+ convertToDouble +419802E-11
+} 0x3ed19b96f36ec68b
+test expr-28.634 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -537734 E-24 x -13d6c1088ae40e_0000000000000000000001& E-61
+ convertToDouble -537734E-24
+} 0xbc23d6c1088ae40e
+test expr-28.635 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +910308 E26 x 11f3e1839eeab0_11111111111111111111110& E106
+ convertToDouble +910308E26
+} 0x4691f3e1839eeab1
+test expr-28.636 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -227577 E26 x -11f3e1839eeab0_11111111111111111111110& E104
+ convertToDouble -227577E26
+} 0xc671f3e1839eeab1
+test expr-28.637 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +455154 E26 x 11f3e1839eeab0_11111111111111111111110& E105
+ convertToDouble +455154E26
+} 0x4681f3e1839eeab1
+test expr-28.638 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -531013 E25 x -10c17d25834171_11111111111111111111110& E102
+ convertToDouble -531013E25
+} 0xc650c17d25834172
+test expr-28.639 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +963019 E-21 x 11592429784914_11111111111111111111110& E-50
+ convertToDouble +963019E-21
+} 0x3cd1592429784915
+test expr-28.640 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -519827 E-13 x -1be872a8b30d7c_11111111111111111111110& E-25
+ convertToDouble -519827E-13
+} 0xbe6be872a8b30d7d
+test expr-28.641 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +623402 E-27 x 178d2c97bde2a0_11111111111111111111110& E-71
+ convertToDouble +623402E-27
+} 0x3b878d2c97bde2a1
+test expr-28.642 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -311701 E-27 x -178d2c97bde2a0_11111111111111111111110& E-72
+ convertToDouble -311701E-27
+} 0xbb778d2c97bde2a1
+test expr-28.643 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9613651 E26 x 17b31116270d9b_000000000000000000000001& E109
+ convertToDouble +9613651E26
+} 0x46c7b31116270d9b
+test expr-28.644 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -9191316 E23 x -1733bfae0801fd_0000000000000000000001& E99
+ convertToDouble -9191316E23
+} 0xc62733bfae0801fd
+test expr-28.645 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4595658 E23 x 1733bfae0801fd_0000000000000000000001& E98
+ convertToDouble +4595658E23
+} 0x461733bfae0801fd
+test expr-28.646 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2297829 E23 x -1733bfae0801fd_0000000000000000000001& E97
+ convertToDouble -2297829E23
+} 0xc60733bfae0801fd
+test expr-28.647 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -1679208 E-11 x -119b96f36ec68b_00000000000000000000000001& E-16
+ convertToDouble -1679208E-11
+} 0xbef19b96f36ec68b
+test expr-28.648 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +3379223 E27 x 14d3794ce2fc25_1111111111111111111111110& E111
+ convertToDouble +3379223E27
+} 0x46e4d3794ce2fc26
+test expr-28.649 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -6758446 E27 x -14d3794ce2fc25_1111111111111111111111110& E112
+ convertToDouble -6758446E27
+} 0xc6f4d3794ce2fc26
+test expr-28.650 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +5444097 E-21 x 18849dd33c95ae_11111111111111111111111111110& E-48
+ convertToDouble +5444097E-21
+} 0x3cf8849dd33c95af
+test expr-28.651 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8399969 E-27 x -13d5783e85fcf7_1111111111111111111111110& E-67
+ convertToDouble -8399969E-27
+} 0xbbc3d5783e85fcf8
+test expr-28.652 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8366487 E-16 x 1cbf3d630403af_1111111111111111111111110& E-31
+ convertToDouble +8366487E-16
+} 0x3e0cbf3d630403b0
+test expr-28.653 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8366487 E-15 x -11f7865de2824d_11111111111111111111111110& E-27
+ convertToDouble -8366487E-15
+} 0xbe41f7865de2824e
+test expr-28.654 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +65060671 E25 x 1009e7d474572a_0000000000000000000000000001& E109
+ convertToDouble +65060671E25
+} 0x46c009e7d474572a
+test expr-28.655 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +65212389 E23 x 1493d098d37657_000000000000000000000000001& E102
+ convertToDouble +65212389E23
+} 0x465493d098d37657
+test expr-28.656 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +55544957 E-13 x 174c1826f3010c_00000000000000000000000000001& E-18
+ convertToDouble +55544957E-13
+} 0x3ed74c1826f3010c
+test expr-28.657 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -51040905 E-20 x -11f55b23c8bf2d_0000000000000000000000000001& E-41
+ convertToDouble -51040905E-20
+} 0xbd61f55b23c8bf2d
+test expr-28.658 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +99585767 E-22 x 166cba8699f0f2_0000000000000000000000000001& E-47
+ convertToDouble +99585767E-22
+} 0x3d066cba8699f0f2
+test expr-28.659 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -99585767 E-23 x -11f095387b2728_0000000000000000000000000001& E-50
+ convertToDouble -99585767E-23
+} 0xbcd1f095387b2728
+test expr-28.660 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +40978393 E26 x 1941401cca2bfd_1111111111111111111111111110& E111
+ convertToDouble +40978393E26
+} 0x46e941401cca2bfe
+test expr-28.661 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -67488159 E24 x -1a9e90059d12db_11111111111111111111111111110& E105
+ convertToDouble -67488159E24
+} 0xc68a9e90059d12dc
+test expr-28.662 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +69005339 E23 x 15c634f6ef1f95_111111111111111111111111110& E102
+ convertToDouble +69005339E23
+} 0x4655c634f6ef1f96
+test expr-28.663 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -81956786 E26 x -1941401cca2bfd_1111111111111111111111111110& E112
+ convertToDouble -81956786E26
+} 0xc6f941401cca2bfe
+test expr-28.664 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -87105552 E-21 x -18849dd33c95ae_11111111111111111111111111110& E-44
+ convertToDouble -87105552E-21
+} 0xbd38849dd33c95af
+test expr-28.665 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +10888194 E-21 x 18849dd33c95ae_11111111111111111111111111110& E-47
+ convertToDouble +10888194E-21
+} 0x3d08849dd33c95af
+test expr-28.666 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -21776388 E-21 x -18849dd33c95ae_11111111111111111111111111110& E-46
+ convertToDouble -21776388E-21
+} 0xbd18849dd33c95af
+test expr-28.667 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +635806667 E27 x 1e9cec176c96f8_000000000000000000000000000000001& E118
+ convertToDouble +635806667E27
+} 0x475e9cec176c96f8
+test expr-28.668 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -670026614 E25 x -14a593f89f4194_00000000000000000000000000000001& E112
+ convertToDouble -670026614E25
+} 0xc6f4a593f89f4194
+test expr-28.669 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +335013307 E26 x 19cef8f6c711f9_0000000000000000000000000000001& E114
+ convertToDouble +335013307E26
+} 0x4719cef8f6c711f9
+test expr-28.670 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -335013307 E25 x -14a593f89f4194_00000000000000000000000000000001& E111
+ convertToDouble -335013307E25
+} 0xc6e4a593f89f4194
+test expr-28.671 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +371790617 E-24 x 1aca538c61ba9c_000000000000000000000000000000001& E-52
+ convertToDouble +371790617E-24
+} 0x3cbaca538c61ba9c
+test expr-28.672 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -371790617 E-25 x -156ea93d1afbb0_0000000000000000000000000000000001& E-55
+ convertToDouble -371790617E-25
+} 0xbc856ea93d1afbb0
+test expr-28.673 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +743581234 E-24 x 1aca538c61ba9c_000000000000000000000000000000001& E-51
+ convertToDouble +743581234E-24
+} 0x3ccaca538c61ba9c
+test expr-28.674 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -743581234 E-25 x -156ea93d1afbb0_0000000000000000000000000000000001& E-54
+ convertToDouble -743581234E-25
+} 0xbc956ea93d1afbb0
+test expr-28.675 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +202464477 E24 x 13f6ec0435ce24_111111111111111111111111111110& E107
+ convertToDouble +202464477E24
+} 0x46a3f6ec0435ce25
+test expr-28.676 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -404928954 E24 x -13f6ec0435ce24_111111111111111111111111111110& E108
+ convertToDouble -404928954E24
+} 0xc6b3f6ec0435ce25
+test expr-28.677 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +997853758 E27 x 1805bfa33b98fa_111111111111111111111111111110& E119
+ convertToDouble +997853758E27
+} 0x476805bfa33b98fb
+test expr-28.678 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -997853758 E26 x -1337cc829613fb_111111111111111111111111111110& E116
+ convertToDouble -997853758E26
+} 0xc73337cc829613fc
+test expr-28.679 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +405498418 E-17 x 116a8093df66a6_111111111111111111111111111111110& E-28
+ convertToDouble +405498418E-17
+} 0x3e316a8093df66a7
+test expr-28.680 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -582579084 E-14 x -186f653140a658_111111111111111111111111111111110& E-18
+ convertToDouble -582579084E-14
+} 0xbed86f653140a659
+test expr-28.681 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +608247627 E-18 x 14e633e4a5ae61_111111111111111111111111111111110& E-31
+ convertToDouble +608247627E-18
+} 0x3e04e633e4a5ae62
+test expr-28.682 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -291289542 E-14 x -186f653140a658_111111111111111111111111111111110& E-19
+ convertToDouble -291289542E-14
+} 0xbec86f653140a659
+test expr-28.683 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -9537100005 E26 x -16f5b11191713a_000000000000000000000000000000001& E119
+ convertToDouble -9537100005E26
+} 0xc766f5b11191713a
+test expr-28.684 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6358066670 E27 x 1322138ea3de5b_000000000000000000000000000000001& E122
+ convertToDouble +6358066670E27
+} 0x479322138ea3de5b
+test expr-28.685 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -1271613334 E27 x -1e9cec176c96f8_000000000000000000000000000000001& E119
+ convertToDouble -1271613334E27
+} 0xc76e9cec176c96f8
+test expr-28.686 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +5229646999 E-16 x 118c3b89731f3d_000000000000000000000000000000000001& E-21
+ convertToDouble +5229646999E-16
+} 0x3ea18c3b89731f3d
+test expr-28.687 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +5229646999 E-17 x 1c13927584fec8_00000000000000000000000000000000001& E-25
+ convertToDouble +5229646999E-17
+} 0x3e6c13927584fec8
+test expr-28.688 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4429943614 E24 x 1b4d37fa06864a_1111111111111111111111111111111110& E111
+ convertToDouble +4429943614E24
+} 0x46eb4d37fa06864b
+test expr-28.689 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8859887228 E24 x -1b4d37fa06864a_1111111111111111111111111111111110& E112
+ convertToDouble -8859887228E24
+} 0xc6fb4d37fa06864b
+test expr-28.690 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +2214971807 E24 x 1b4d37fa06864a_1111111111111111111111111111111110& E110
+ convertToDouble +2214971807E24
+} 0x46db4d37fa06864b
+test expr-28.691 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4176887093 E26 x -141c692c5bd07a_111111111111111111111111111111110& E118
+ convertToDouble -4176887093E26
+} 0xc7541c692c5bd07b
+test expr-28.692 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4003495257 E-20 x 16026b2e07ec06_111111111111111111111111111111111110& E-35
+ convertToDouble +4003495257E-20
+} 0x3dc6026b2e07ec07
+test expr-28.693 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4361901637 E-23 x -188e29a9d7c5b8_11111111111111111111111111111111110& E-45
+ convertToDouble -4361901637E-23
+} 0xbd288e29a9d7c5b9
+test expr-28.694 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8723803274 E-23 x 188e29a9d7c5b8_11111111111111111111111111111111110& E-44
+ convertToDouble +8723803274E-23
+} 0x3d388e29a9d7c5b9
+test expr-28.695 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8006990514 E-20 x -16026b2e07ec06_111111111111111111111111111111111110& E-34
+ convertToDouble -8006990514E-20
+} 0xbdd6026b2e07ec07
+test expr-28.696 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +72835110098 E27 x 1b65c41711fb6d_0000000000000000000000000000000000001& E125
+ convertToDouble +72835110098E27
+} 0x47cb65c41711fb6d
+test expr-28.697 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -36417555049 E27 x -1b65c41711fb6d_0000000000000000000000000000000000001& E124
+ convertToDouble -36417555049E27
+} 0xc7bb65c41711fb6d
+test expr-28.698 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +84279630104 E25 x 144a221b1cf62e_000000000000000000000000000000000001& E119
+ convertToDouble +84279630104E25
+} 0x47644a221b1cf62e
+test expr-28.699 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -84279630104 E24 x -103b4e7c172b58_000000000000000000000000000000000001& E116
+ convertToDouble -84279630104E24
+} 0xc7303b4e7c172b58
+test expr-28.700 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +21206176437 E-27 x 1872f563ae0cc9_0000000000000000000000000000000000001& E-56
+ convertToDouble +21206176437E-27
+} 0x3c7872f563ae0cc9
+test expr-28.701 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -66461566917 E-22 x -1d3ae83e4322b3_00000000000000000000000000000000000001& E-38
+ convertToDouble -66461566917E-22
+} 0xbd9d3ae83e4322b3
+test expr-28.702 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +64808355539 E-16 x 1b2ebe83265fbf_00000000000000000000000000000000000001& E-18
+ convertToDouble +64808355539E-16
+} 0x3edb2ebe83265fbf
+test expr-28.703 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -84932679673 E-19 x -123d39339f1bf6_00000000000000000000000000000000000001& E-27
+ convertToDouble -84932679673E-19
+} 0xbe423d39339f1bf6
+test expr-28.704 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +65205430094 E26 x 139f3e5d7fd76a_1111111111111111111111111111111111110& E122
+ convertToDouble +65205430094E26
+} 0x47939f3e5d7fd76b
+test expr-28.705 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -68384463429 E25 x -107684982f634e_1111111111111111111111111111111111111110& E119
+ convertToDouble -68384463429E25
+} 0xc7607684982f634f
+test expr-28.706 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +32602715047 E26 x 139f3e5d7fd76a_1111111111111111111111111111111111110& E121
+ convertToDouble +32602715047E26
+} 0x47839f3e5d7fd76b
+test expr-28.707 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -62662203426 E27 x -1792269424688d_111111111111111111111111111111111110& E125
+ convertToDouble -62662203426E27
+} 0xc7c792269424688e
+test expr-28.708 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +58784444678 E-18 x 1f8f45c64b4682_111111111111111111111111111111111111110& E-25
+ convertToDouble +58784444678E-18
+} 0x3e6f8f45c64b4683
+test expr-28.709 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -50980203373 E-21 x -1c06d366394440_11111111111111111111111111111111111111111110& E-35
+ convertToDouble -50980203373E-21
+} 0xbdcc06d366394441
+test expr-28.710 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +29392222339 E-18 x 1f8f45c64b4682_111111111111111111111111111111111111110& E-26
+ convertToDouble +29392222339E-18
+} 0x3e5f8f45c64b4683
+test expr-28.711 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -75529940323 E-27 x -15c5203c0aad52_1111111111111111111111111111111111111110& E-54
+ convertToDouble -75529940323E-27
+} 0xbc95c5203c0aad53
+test expr-28.712 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -937495906299 E26 x -11a1e0ebb6af11_000000000000000000000000000000000000000001& E126
+ convertToDouble -937495906299E26
+} 0xc7d1a1e0ebb6af11
+test expr-28.713 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +842642485799 E-20 x 121879decdd7cb_000000000000000000000000000000000000000001& E-27
+ convertToDouble +842642485799E-20
+} 0x3e421879decdd7cb
+test expr-28.714 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -387824150699 E-23 x -110e8302245571_00000000000000000000000000000000000000001& E-38
+ convertToDouble -387824150699E-23
+} 0xbd910e8302245571
+test expr-28.715 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +924948814726 E-27 x 10a992d1fc6ded_00000000000000000000000000000000000000001& E-50
+ convertToDouble +924948814726E-27
+} 0x3cd0a992d1fc6ded
+test expr-28.716 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -775648301398 E-23 x -110e8302245571_00000000000000000000000000000000000000001& E-37
+ convertToDouble -775648301398E-23
+} 0xbda10e8302245571
+test expr-28.717 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +547075707432 E25 x 107684982f634e_1111111111111111111111111111111111111110& E122
+ convertToDouble +547075707432E25
+} 0x47907684982f634f
+test expr-28.718 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +683844634290 E24 x 107684982f634e_1111111111111111111111111111111111111110& E119
+ convertToDouble +683844634290E24
+} 0x47607684982f634f
+test expr-28.719 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -136768926858 E25 x -107684982f634e_1111111111111111111111111111111111111110& E120
+ convertToDouble -136768926858E25
+} 0xc7707684982f634f
+test expr-28.720 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +509802033730 E-22 x 1c06d366394440_11111111111111111111111111111111111111111110& E-35
+ convertToDouble +509802033730E-22
+} 0x3dcc06d366394441
+test expr-28.721 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +101960406746 E-21 x 1c06d366394440_11111111111111111111111111111111111111111110& E-34
+ convertToDouble +101960406746E-21
+} 0x3ddc06d366394441
+test expr-28.722 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -815683253968 E-21 x -1c06d366394440_11111111111111111111111111111111111111111110& E-31
+ convertToDouble -815683253968E-21
+} 0xbe0c06d366394441
+test expr-28.723 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +7344124123524 E24 x 1619b519dd6833_00000000000000000000000000000000000000000001& E122
+ convertToDouble +7344124123524E24
+} 0x479619b519dd6833
+test expr-28.724 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -9180155154405 E23 x -1619b519dd6833_00000000000000000000000000000000000000000001& E119
+ convertToDouble -9180155154405E23
+} 0xc76619b519dd6833
+test expr-28.725 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6479463327323 E27 x 130a9b3e9bd05e_00000000000000000000000000000000000000000001& E132
+ convertToDouble +6479463327323E27
+} 0x48330a9b3e9bd05e
+test expr-28.726 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -1836031030881 E24 x -1619b519dd6833_00000000000000000000000000000000000000000001& E120
+ convertToDouble -1836031030881E24
+} 0xc77619b519dd6833
+test expr-28.727 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4337269293039 E-19 x 1d1b5f354c63d6_00000000000000000000000000000000000000000001& E-22
+ convertToDouble +4337269293039E-19
+} 0x3e9d1b5f354c63d6
+test expr-28.728 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4599163554373 E-23 x -1948bf4d34088d_00000000000000000000000000000000000000000001& E-35
+ convertToDouble -4599163554373E-23
+} 0xbdc948bf4d34088d
+test expr-28.729 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9198327108746 E-23 x 1948bf4d34088d_00000000000000000000000000000000000000000001& E-34
+ convertToDouble +9198327108746E-23
+} 0x3dd948bf4d34088d
+test expr-28.730 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4812803938347 E27 x 1c4980a4ee94ce_111111111111111111111111111111111111111111110& E131
+ convertToDouble +4812803938347E27
+} 0x482c4980a4ee94cf
+test expr-28.731 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8412030890011 E23 x -14405075e52db9_11111111111111111111111111111111111111111110& E119
+ convertToDouble -8412030890011E23
+} 0xc764405075e52dba
+test expr-28.732 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9625607876694 E27 x 1c4980a4ee94ce_111111111111111111111111111111111111111111110& E132
+ convertToDouble +9625607876694E27
+} 0x483c4980a4ee94cf
+test expr-28.733 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4739968828249 E24 x -1c87140cdf8a1d_1111111111111111111111111111111111111111110& E121
+ convertToDouble -4739968828249E24
+} 0xc78c87140cdf8a1e
+test expr-28.734 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9697183891673 E-23 x 1aa7c959b6a666_11111111111111111111111111111111111111111111110& E-34
+ convertToDouble +9697183891673E-23
+} 0x3ddaa7c959b6a667
+test expr-28.735 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -7368108517543 E-20 x -13c7535bbd85a1_1111111111111111111111111111111111111111111110& E-24
+ convertToDouble -7368108517543E-20
+} 0xbe73c7535bbd85a2
+test expr-28.736 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +51461358161422 E25 x 18326f87d4cae0_0000000000000000000000000000000000000000000000001& E128
+ convertToDouble +51461358161422E25
+} 0x47f8326f87d4cae0
+test expr-28.737 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -77192037242133 E26 x -16af488f577e32_0000000000000000000000000000000000000000000000001& E132
+ convertToDouble -77192037242133E26
+} 0xc836af488f577e32
+test expr-28.738 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +77192037242133 E25 x 1225d3a5df9828_0000000000000000000000000000000000000000000000001& E129
+ convertToDouble +77192037242133E25
+} 0x480225d3a5df9828
+test expr-28.739 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -51461358161422 E27 x -12e767221e3e7f_0000000000000000000000000000000000000000000000001& E135
+ convertToDouble -51461358161422E27
+} 0xc862e767221e3e7f
+test expr-28.740 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +43999661561541 E-21 x 179f4476d372a3_0000000000000000000000000000000000000000000000001& E-25
+ convertToDouble +43999661561541E-21
+} 0x3e679f4476d372a3
+test expr-28.741 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -87999323123082 E-21 x -179f4476d372a3_0000000000000000000000000000000000000000000000001& E-24
+ convertToDouble -87999323123082E-21
+} 0xbe779f4476d372a3
+test expr-28.742 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +48374886826137 E-26 x 110538f23350d5_00000000000000000000000000000000000000000000001& E-41
+ convertToDouble +48374886826137E-26
+} 0x3d610538f23350d5
+test expr-28.743 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -57684246567111 E-23 x -13d1f5c1b8a912_00000000000000000000000000000000000000000000001& E-31
+ convertToDouble -57684246567111E-23
+} 0xbe03d1f5c1b8a912
+test expr-28.744 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +87192805957686 E23 x 1a3d16e55a9664_1111111111111111111111111111111111111111111110& E122
+ convertToDouble +87192805957686E23
+} 0x479a3d16e55a9665
+test expr-28.745 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -75108713005913 E24 x -1c40b4baa79655_11111111111111111111111111111111111111111111110& E125
+ convertToDouble -75108713005913E24
+} 0xc7cc40b4baa79656
+test expr-28.746 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +64233110587487 E27 x 179873e38669a6_1111111111111111111111111111111111111111111110& E135
+ convertToDouble +64233110587487E27
+} 0x48679873e38669a7
+test expr-28.747 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -77577471133384 E-23 x -1aa7c959b6a666_11111111111111111111111111111111111111111111110& E-31
+ convertToDouble -77577471133384E-23
+} 0xbe0aa7c959b6a667
+test expr-28.748 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +48485919458365 E-24 x 1aa7c959b6a666_11111111111111111111111111111111111111111111110& E-35
+ convertToDouble +48485919458365E-24
+} 0x3dcaa7c959b6a667
+test expr-28.749 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -56908598265713 E-26 x -1405deef4bdef5_111111111111111111111111111111111111111111111110& E-41
+ convertToDouble -56908598265713E-26
+} 0xbd6405deef4bdef6
+test expr-28.750 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +589722294620133 E23 x 162ed1b287caef_00000000000000000000000000000000000000000000000001& E125
+ convertToDouble +589722294620133E23
+} 0x47c62ed1b287caef
+test expr-28.751 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +652835804449289 E-22 x 118640e490b087_0000000000000000000000000000000000000000000000000001& E-24
+ convertToDouble +652835804449289E-22
+} 0x3e718640e490b087
+test expr-28.752 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -656415363936202 E-23 x -1c315cfe25d201_00000000000000000000000000000000000000000000000001& E-28
+ convertToDouble -656415363936202E-23
+} 0xbe3c315cfe25d201
+test expr-28.753 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +579336749585745 E-25 x 1fd9709d9aeb19_00000000000000000000000000000000000000000000000001& E-35
+ convertToDouble +579336749585745E-25
+} 0x3dcfd9709d9aeb19
+test expr-28.754 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -381292764980839 E-26 x -10c4f9921c3f8f_00000000000000000000000000000000000000000000000001& E-38
+ convertToDouble -381292764980839E-26
+} 0xbd90c4f9921c3f8f
+test expr-28.755 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +965265859649698 E23 x 12279607edcb0c_1111111111111111111111111111111111111111111111110& E126
+ convertToDouble +965265859649698E23
+} 0x47d2279607edcb0d
+test expr-28.756 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -848925235434882 E27 x -137d88ba4b43e3_1111111111111111111111111111111111111111111111111110& E139
+ convertToDouble -848925235434882E27
+} 0xc8a37d88ba4b43e4
+test expr-28.757 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +536177612222491 E23 x 142b33dd3acafd_11111111111111111111111111111111111111111111111110& E125
+ convertToDouble +536177612222491E23
+} 0x47c42b33dd3acafe
+test expr-28.758 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -424462617717441 E27 x -137d88ba4b43e3_1111111111111111111111111111111111111111111111111110& E138
+ convertToDouble -424462617717441E27
+} 0xc8937d88ba4b43e4
+test expr-28.759 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +276009279888989 E-27 x 136c242313c288_111111111111111111111111111111111111111111111111110& E-42
+ convertToDouble +276009279888989E-27
+} 0x3d536c242313c289
+test expr-28.760 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -608927158043691 E-26 x -1ac7e909c22f09_11111111111111111111111111111111111111111111111110& E-38
+ convertToDouble -608927158043691E-26
+} 0xbd9ac7e909c22f0a
+test expr-28.761 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +552018559777978 E-27 x 136c242313c288_111111111111111111111111111111111111111111111111110& E-41
+ convertToDouble +552018559777978E-27
+} 0x3d636c242313c289
+test expr-28.762 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -425678377667758 E-22 x -16da7aa49bdcd5_1111111111111111111111111111111111111111111111110& E-25
+ convertToDouble -425678377667758E-22
+} 0xbe66da7aa49bdcd6
+test expr-28.763 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8013702726927119 E26 x 126607f8f1b29e_00000000000000000000000000000000000000000000000000001& E139
+ convertToDouble +8013702726927119E26
+} 0x48a26607f8f1b29e
+test expr-28.764 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8862627962362001 E27 x 196f3b0e7787c2_00000000000000000000000000000000000000000000000000001& E142
+ convertToDouble +8862627962362001E27
+} 0x48d96f3b0e7787c2
+test expr-28.765 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -5068007907757162 E26 x -17456a27848397_00000000000000000000000000000000000000000000000000001& E138
+ convertToDouble -5068007907757162E26
+} 0xc897456a27848397
+test expr-28.766 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -7379714799828406 E-23 x -13cf4d2839e036_00000000000000000000000000000000000000000000000000001& E-24
+ convertToDouble -7379714799828406E-23
+} 0xbe73cf4d2839e036
+test expr-28.767 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4114538064016107 E-27 x 12188eda98010c_0000000000000000000000000000000000000000000000000001& E-38
+ convertToDouble +4114538064016107E-27
+} 0x3d92188eda98010c
+test expr-28.768 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -3689857399914203 E-23 x -13cf4d2839e036_00000000000000000000000000000000000000000000000000001& E-25
+ convertToDouble -3689857399914203E-23
+} 0xbe63cf4d2839e036
+test expr-28.769 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +5575954851815478 E23 x 1a37cfbf2ffdb5_1111111111111111111111111111111111111111111111111110& E128
+ convertToDouble +5575954851815478E23
+} 0x47fa37cfbf2ffdb6
+test expr-28.770 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +3395700941739528 E27 x 137d88ba4b43e3_1111111111111111111111111111111111111111111111111110& E141
+ convertToDouble +3395700941739528E27
+} 0x48c37d88ba4b43e4
+test expr-28.771 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4115535777581961 E-23 x 1618596be30fe4_111111111111111111111111111111111111111111111111111110& E-25
+ convertToDouble +4115535777581961E-23
+} 0x3e6618596be30fe5
+test expr-28.772 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8231071555163922 E-23 x -1618596be30fe4_111111111111111111111111111111111111111111111111111110& E-24
+ convertToDouble -8231071555163922E-23
+} 0xbe7618596be30fe5
+test expr-28.773 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6550246696190871 E-26 x 1201538b0f8c69_111111111111111111111111111111111111111111111111111110& E-34
+ convertToDouble +6550246696190871E-26
+} 0x3dd201538b0f8c6a
+test expr-28.774 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -68083046403986701 E27 x -186c70ba8ba28d_000000000000000000000000000000000000000000000000000000001& E145
+ convertToDouble -68083046403986701E27
+} 0xc9086c70ba8ba28d
+test expr-28.775 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +43566388595783643 E27 x 1f41e1bf48b03f_111111111111111111111111111111111111111111111111111111110& E144
+ convertToDouble +43566388595783643E27
+} 0x48ff41e1bf48b040
+test expr-28.776 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -87132777191567286 E27 x -1f41e1bf48b03f_111111111111111111111111111111111111111111111111111111110& E145
+ convertToDouble -87132777191567286E27
+} 0xc90f41e1bf48b040
+test expr-28.777 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +59644881059342141 E25 x 1b6338d9d8ae38_11111111111111111111111111111111111111111111111111111110& E138
+ convertToDouble +59644881059342141E25
+} 0x489b6338d9d8ae39
+test expr-28.778 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -83852770718576667 E23 x -18a4619ed6f442_111111111111111111111111111111111111111111111111111111110& E132
+ convertToDouble -83852770718576667E23
+} 0xc838a4619ed6f443
+test expr-28.779 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +99482967418206961 E-25 x 155d224bfed7ac_11111111111111111111111111111111111111111111111111111111110& E-27
+ convertToDouble +99482967418206961E-25
+} 0x3e455d224bfed7ad
+test expr-28.780 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -99482967418206961 E-26 x -11174ea3324623_11111111111111111111111111111111111111111111111111111111110& E-30
+ convertToDouble -99482967418206961E-26
+} 0xbe11174ea3324624
+test expr-28.781 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +87446669969994614 E-27 x 1809832942376d_11111111111111111111111111111111111111111111111111111110& E-34
+ convertToDouble +87446669969994614E-27
+} 0x3dd809832942376e
+test expr-28.782 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -43723334984997307 E-27 x -1809832942376d_11111111111111111111111111111111111111111111111111111110& E-35
+ convertToDouble -43723334984997307E-27
+} 0xbdc809832942376e
+test expr-28.783 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +5 E24 x 108b2a2c280290_1001& E82
+ convertToDouble +5E24
+} 0x45108b2a2c280291
+test expr-28.784 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8 E25 x -108b2a2c280290_1001& E86
+ convertToDouble -8E25
+} 0xc5508b2a2c280291
+test expr-28.785 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +1 E25 x 108b2a2c280290_1001& E83
+ convertToDouble +1E25
+} 0x45208b2a2c280291
+test expr-28.786 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4 E25 x -108b2a2c280290_1001& E85
+ convertToDouble -4E25
+} 0xc5408b2a2c280291
+test expr-28.787 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +2 E-5 x 14f8b588e368f0_100001& E-16
+ convertToDouble +2E-5
+} 0x3ef4f8b588e368f1
+test expr-28.788 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -5 E-6 x -14f8b588e368f0_100001& E-18
+ convertToDouble -5E-6
+} 0xbed4f8b588e368f1
+test expr-28.789 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4 E-5 x 14f8b588e368f0_100001& E-15
+ convertToDouble +4E-5
+} 0x3f04f8b588e368f1
+test expr-28.790 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -3 E-20 x -11b578c96db19a_100001& E-65
+ convertToDouble -3E-20
+} 0xbbe1b578c96db19b
+test expr-28.791 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +3 E27 x 1363156bbee301_0110& E91
+ convertToDouble +3E27
+} 0x45a363156bbee301
+test expr-28.792 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -9 E26 x -1743b34e18439b_010& E89
+ convertToDouble -9E26
+} 0xc58743b34e18439b
+test expr-28.793 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +7 E25 x 1cf389cd46047d_00& E85
+ convertToDouble +7E25
+} 0x454cf389cd46047d
+test expr-28.794 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -6 E27 x -1363156bbee301_0110& E92
+ convertToDouble -6E27
+} 0xc5b363156bbee301
+test expr-28.795 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +2 E-21 x 12e3b40a0e9b4f_0111110& E-69
+ convertToDouble +2E-21
+} 0x3ba2e3b40a0e9b4f
+test expr-28.796 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -5 E-22 x -12e3b40a0e9b4f_0111110& E-71
+ convertToDouble -5E-22
+} 0xbb82e3b40a0e9b4f
+test expr-28.797 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4 E-21 x -12e3b40a0e9b4f_0111110& E-68
+ convertToDouble -4E-21
+} 0xbbb2e3b40a0e9b4f
+test expr-28.798 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +87 E25 x 167d2d5406637c_10001& E89
+ convertToDouble +87E25
+} 0x45867d2d5406637d
+test expr-28.799 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -97 E24 x -140f232256e982_1000000001& E86
+ convertToDouble -97E24
+} 0xc5540f232256e983
+test expr-28.800 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +82 E-24 x 18c87154dff6c6_1000000001& E-74
+ convertToDouble +82E-24
+} 0x3b58c87154dff6c7
+test expr-28.801 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -41 E-24 x -18c87154dff6c6_1000000001& E-75
+ convertToDouble -41E-24
+} 0xbb48c87154dff6c7
+test expr-28.802 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +76 E-23 x 1cb644dc1633c0_10000001& E-71
+ convertToDouble +76E-23
+} 0x3b8cb644dc1633c1
+test expr-28.803 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +83 E25 x 15747ab143e353_011111111110& E89
+ convertToDouble +83E25
+} 0x4585747ab143e353
+test expr-28.804 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -50 E27 x -1431e0fae6d721_0111110& E95
+ convertToDouble -50E27
+} 0xc5e431e0fae6d721
+test expr-28.805 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +25 E27 x 1431e0fae6d721_0111110& E94
+ convertToDouble +25E27
+} 0x45d431e0fae6d721
+test expr-28.806 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -99 E27 x -13fe2e171cda19_011110& E96
+ convertToDouble -99E27
+} 0xc5f3fe2e171cda19
+test expr-28.807 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +97 E-10 x 14d4a1a3157dc7_011111110& E-27
+ convertToDouble +97E-10
+} 0x3e44d4a1a3157dc7
+test expr-28.808 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -57 E-20 x -15077f6f3242e7_011111110& E-61
+ convertToDouble -57E-20
+} 0xbc25077f6f3242e7
+test expr-28.809 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +997 E23 x 149e12f51c1a3c_10000000001& E86
+ convertToDouble +997E23
+} 0x45549e12f51c1a3d
+test expr-28.810 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +776 E24 x 140f232256e982_1000000001& E89
+ convertToDouble +776E24
+} 0x45840f232256e983
+test expr-28.811 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -388 E24 x -140f232256e982_1000000001& E88
+ convertToDouble -388E24
+} 0xc5740f232256e983
+test expr-28.812 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +521 E-10 x 1bf891c92c0890_100000000001& E-25
+ convertToDouble +521E-10
+} 0x3e6bf891c92c0891
+test expr-28.813 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -506 E-26 x -1877fa0260beb2_10000000001& E-78
+ convertToDouble -506E-26
+} 0xbb1877fa0260beb3
+test expr-28.814 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +739 E-10 x 13d65e8c76722c_10000000001& E-24
+ convertToDouble +739E-10
+} 0x3e73d65e8c76722d
+test expr-28.815 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -867 E-7 x -16ba56a8834168_100000000001& E-14
+ convertToDouble -867E-7
+} 0xbf16ba56a8834169
+test expr-28.816 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -415 E24 x -15747ab143e353_011111111110& E88
+ convertToDouble -415E24
+} 0xc575747ab143e353
+test expr-28.817 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +332 E25 x 15747ab143e353_011111111110& E91
+ convertToDouble +332E25
+} 0x45a5747ab143e353
+test expr-28.818 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -664 E25 x -15747ab143e353_011111111110& E92
+ convertToDouble -664E25
+} 0xc5b5747ab143e353
+test expr-28.819 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +291 E-13 x 1ffeebfc8b81b5_01111111111110& E-36
+ convertToDouble +291E-13
+} 0x3dbffeebfc8b81b5
+test expr-28.820 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -982 E-8 x -14981285e98e79_0111111111110& E-17
+ convertToDouble -982E-8
+} 0xbee4981285e98e79
+test expr-28.821 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +582 E-13 x 1ffeebfc8b81b5_01111111111110& E-35
+ convertToDouble +582E-13
+} 0x3dcffeebfc8b81b5
+test expr-28.822 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -491 E-8 x -14981285e98e79_0111111111110& E-18
+ convertToDouble -491E-8
+} 0xbed4981285e98e79
+test expr-28.823 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4574 E26 x 1717c1a612f954_100000000001& E98
+ convertToDouble +4574E26
+} 0x461717c1a612f955
+test expr-28.824 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8609 E26 x -15bb6f942546ee_1000000000001& E99
+ convertToDouble -8609E26
+} 0xc625bb6f942546ef
+test expr-28.825 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +2287 E26 x 1717c1a612f954_100000000001& E97
+ convertToDouble +2287E26
+} 0x460717c1a612f955
+test expr-28.826 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4818 E24 x -1f22b65eb419a0_10000000001& E91
+ convertToDouble -4818E24
+} 0xc5af22b65eb419a1
+test expr-28.827 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6529 E-8 x 111d89a8b5c142_100000000000001& E-14
+ convertToDouble +6529E-8
+} 0x3f111d89a8b5c143
+test expr-28.828 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8151 E-21 x -12cb804b61b898_1000000000000001& E-57
+ convertToDouble -8151E-21
+} 0xbc62cb804b61b899
+test expr-28.829 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +1557 E-12 x 1abfc227ab1026_10000000000001& E-30
+ convertToDouble +1557E-12
+} 0x3e1abfc227ab1027
+test expr-28.830 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2573 E-18 x -172cef1ebbca44_10000000000001& E-49
+ convertToDouble -2573E-18
+} 0xbce72cef1ebbca45
+test expr-28.831 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4929 E-16 x 1157a604ed019f_0111111111111110& E-41
+ convertToDouble +4929E-16
+} 0x3d6157a604ed019f
+test expr-28.832 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -3053 E-22 x -1686f435fe6b6b_011111111111110& E-62
+ convertToDouble -3053E-22
+} 0xbc1686f435fe6b6b
+test expr-28.833 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9858 E-16 x 1157a604ed019f_0111111111111110& E-40
+ convertToDouble +9858E-16
+} 0x3d7157a604ed019f
+test expr-28.834 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -7767 E-11 x -14d971170ed055_011111111111110& E-24
+ convertToDouble -7767E-11
+} 0xbe74d971170ed055
+test expr-28.835 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +54339 E26 x 1125782ec15cbe_100000000000000001& E102
+ convertToDouble +54339E26
+} 0x465125782ec15cbf
+test expr-28.836 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -62409 E25 x -1f822c980d4bb2_100000000000000001& E98
+ convertToDouble -62409E25
+} 0xc61f822c980d4bb3
+test expr-28.837 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +32819 E27 x 19e3be885fc16a_100000000000001& E104
+ convertToDouble +32819E27
+} 0x4679e3be885fc16b
+test expr-28.838 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -89849 E27 x -11b8371b6dda04_1000000000000001& E106
+ convertToDouble -89849E27
+} 0xc691b8371b6dda05
+test expr-28.839 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +63876 E-20 x 1703856844bdbe_1000000000000000000001& E-51
+ convertToDouble +63876E-20
+} 0x3cc703856844bdbf
+test expr-28.840 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -15969 E-20 x -1703856844bdbe_1000000000000000000001& E-53
+ convertToDouble -15969E-20
+} 0xbca703856844bdbf
+test expr-28.841 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +31938 E-20 x 1703856844bdbe_1000000000000000000001& E-52
+ convertToDouble +31938E-20
+} 0x3cb703856844bdbf
+test expr-28.842 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -79845 E-21 x -1703856844bdbe_1000000000000000000001& E-54
+ convertToDouble -79845E-21
+} 0xbc9703856844bdbf
+test expr-28.843 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +89306 E27 x 119cccff237e17_011111111111110& E106
+ convertToDouble +89306E27
+} 0x46919cccff237e17
+test expr-28.844 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -25487 E24 x -1496968ba07117_01111111111110& E94
+ convertToDouble -25487E24
+} 0xc5d496968ba07117
+test expr-28.845 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +79889 E24 x 10222a1c7e27d3_01111111111110& E96
+ convertToDouble +79889E24
+} 0x45f0222a1c7e27d3
+test expr-28.846 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -97379 E26 x -1eba3685911519_011111111111111110& E102
+ convertToDouble -97379E26
+} 0xc65eba3685911519
+test expr-28.847 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +81002 E-8 x 1a8af0b45d9531_0111111111111111110& E-11
+ convertToDouble +81002E-8
+} 0x3f4a8af0b45d9531
+test expr-28.848 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -43149 E-25 x -146064de6ecbed_011111111111111110& E-68
+ convertToDouble -43149E-25
+} 0xbbb46064de6ecbed
+test expr-28.849 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +40501 E-8 x 1a8af0b45d9531_0111111111111111110& E-12
+ convertToDouble +40501E-8
+} 0x3f3a8af0b45d9531
+test expr-28.850 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -60318 E-10 x -194c988f217e51_011111111111111110& E-18
+ convertToDouble -60318E-10
+} 0xbed94c988f217e51
+test expr-28.851 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -648299 E27 x -1ff6af0bf00100_10000000000000000001& E108
+ convertToDouble -648299E27
+} 0xc6bff6af0bf00101
+test expr-28.852 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +780649 E24 x 13b4d36f9edd18_10000000000000000001& E99
+ convertToDouble +780649E24
+} 0x4623b4d36f9edd19
+test expr-28.853 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +720919 E-14 x 1ef696965cbf04_10000000000000000000000001& E-28
+ convertToDouble +720919E-14
+} 0x3e3ef696965cbf05
+test expr-28.854 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -629703 E-11 x -1a69626d2629d0_1000000000000000000000001& E-18
+ convertToDouble -629703E-11
+} 0xbeda69626d2629d1
+test expr-28.855 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +557913 E24 x 1c2adb44b394bf_01111111111111111110& E98
+ convertToDouble +557913E24
+} 0x461c2adb44b394bf
+test expr-28.856 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -847899 E23 x -111f88fb93dce9_011111111111111111110& E96
+ convertToDouble -847899E23
+} 0xc5f11f88fb93dce9
+test expr-28.857 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +565445 E27 x 1be0eb55770d4d_0111111111111111110& E108
+ convertToDouble +565445E27
+} 0x46bbe0eb55770d4d
+test expr-28.858 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -736531 E24 x -1297b853d64ac7_01111111111111111110& E99
+ convertToDouble -736531E24
+} 0xc62297b853d64ac7
+test expr-28.859 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +680013 E-19 x 13240293e95c3b_01111111111111111111110& E-44
+ convertToDouble +680013E-19
+} 0x3d33240293e95c3b
+test expr-28.860 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -529981 E-10 x -1bc948d999ac11_011111111111111111110& E-15
+ convertToDouble -529981E-10
+} 0xbf0bc948d999ac11
+test expr-28.861 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +382923 E-23 x 11a8c1c10a1fc5_011111111111111111110& E-58
+ convertToDouble +382923E-23
+} 0x3c51a8c1c10a1fc5
+test expr-28.862 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -633614 E-18 x -164b166995a9b7_011111111111111111110& E-41
+ convertToDouble -633614E-18
+} 0xbd664b166995a9b7
+test expr-28.863 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +2165479 E27 x 1ab10c016c34b8_100000000000000000000001& E110
+ convertToDouble +2165479E27
+} 0x46dab10c016c34b9
+test expr-28.864 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8661916 E27 x -1ab10c016c34b8_100000000000000000000001& E112
+ convertToDouble -8661916E27
+} 0xc6fab10c016c34b9
+test expr-28.865 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4330958 E27 x 1ab10c016c34b8_100000000000000000000001& E111
+ convertToDouble +4330958E27
+} 0x46eab10c016c34b9
+test expr-28.866 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -9391993 E22 x -12f78bec748c98_1000000000000000000001& E96
+ convertToDouble -9391993E22
+} 0xc5f2f78bec748c99
+test expr-28.867 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -5767352 E-14 x -1ef696965cbf04_10000000000000000000000001& E-25
+ convertToDouble -5767352E-14
+} 0xbe6ef696965cbf05
+test expr-28.868 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +7209190 E-15 x 1ef696965cbf04_10000000000000000000000001& E-28
+ convertToDouble +7209190E-15
+} 0x3e3ef696965cbf05
+test expr-28.869 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -1441838 E-14 x -1ef696965cbf04_10000000000000000000000001& E-27
+ convertToDouble -1441838E-14
+} 0xbe4ef696965cbf05
+test expr-28.870 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8478990 E22 x 111f88fb93dce9_011111111111111111110& E96
+ convertToDouble +8478990E22
+} 0x45f11f88fb93dce9
+test expr-28.871 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +1473062 E24 x 1297b853d64ac7_01111111111111111110& E100
+ convertToDouble +1473062E24
+} 0x463297b853d64ac7
+test expr-28.872 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8366487 E-14 x 167567f55b22e1_0111111111111111111111110& E-24
+ convertToDouble +8366487E-14
+} 0x3e767567f55b22e1
+test expr-28.873 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8399969 E-25 x -1efd8be1b15b43_011111111111111111111110& E-61
+ convertToDouble -8399969E-25
+} 0xbc2efd8be1b15b43
+test expr-28.874 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9366737 E-12 x 13a4ba87ddc13f_011111111111111111111110& E-17
+ convertToDouble +9366737E-12
+} 0x3ee3a4ba87ddc13f
+test expr-28.875 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -9406141 E-13 x -1f8fd047c84d49_0111111111111111111111110& E-21
+ convertToDouble -9406141E-13
+} 0xbeaf8fd047c84d49
+test expr-28.876 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +65970979 E24 x 1a055dd68f3e3c_1000000000000000000000000001& E105
+ convertToDouble +65970979E24
+} 0x468a055dd68f3e3d
+test expr-28.877 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -65060671 E26 x -140c61c9916cf4_100000000000000000000000001& E112
+ convertToDouble -65060671E26
+} 0xc6f40c61c9916cf5
+test expr-28.878 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +54923002 E27 x 1527d37d8b38ea_10000000000000000000000001& E115
+ convertToDouble +54923002E27
+} 0x472527d37d8b38eb
+test expr-28.879 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -63846927 E25 x -1f7a9d79dad9b4_10000000000000000000000001& E108
+ convertToDouble -63846927E25
+} 0xc6bf7a9d79dad9b5
+test expr-28.880 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +99585767 E-21 x 1c07e928406d2e_100000000000000000000000001& E-44
+ convertToDouble +99585767E-21
+} 0x3d3c07e928406d2f
+test expr-28.881 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +67488159 E25 x 10a31a03822bc9_011111111111111111111111111110& E109
+ convertToDouble +67488159E25
+} 0x46c0a31a03822bc9
+test expr-28.882 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -69005339 E24 x -1b37c234aae77b_011111111111111111111111110& E105
+ convertToDouble -69005339E24
+} 0xc68b37c234aae77b
+test expr-28.883 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +81956786 E27 x 1f919023fcb6fd_0111111111111111111111111110& E115
+ convertToDouble +81956786E27
+} 0x472f919023fcb6fd
+test expr-28.884 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -40978393 E27 x -1f919023fcb6fd_0111111111111111111111111110& E114
+ convertToDouble -40978393E27
+} 0xc71f919023fcb6fd
+test expr-28.885 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +77505754 E-12 x 145152b6f85e09_0111111111111111111111111110& E-14
+ convertToDouble +77505754E-12
+} 0x3f145152b6f85e09
+test expr-28.886 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -38752877 E-12 x -145152b6f85e09_0111111111111111111111111110& E-15
+ convertToDouble -38752877E-12
+} 0xbf045152b6f85e09
+test expr-28.887 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +82772981 E-15 x 16381dae63505f_0111111111111111111111111111110& E-24
+ convertToDouble +82772981E-15
+} 0x3e76381dae63505f
+test expr-28.888 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -95593517 E-25 x -160ad862d8537d_0111111111111111111111111110& E-57
+ convertToDouble -95593517E-25
+} 0xbc660ad862d8537d
+test expr-28.889 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +200036989 E25 x 18a80dedbc575e_10000000000000000000000000001& E110
+ convertToDouble +200036989E25
+} 0x46d8a80dedbc575f
+test expr-28.890 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -772686455 E27 x -129a0c45ceca7a_1000000000000000000000000000001& E119
+ convertToDouble -772686455E27
+} 0xc7629a0c45ceca7b
+test expr-28.891 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +859139907 E23 x 10f18c4dd0ffe2_10000000000000000000000000001& E106
+ convertToDouble +859139907E23
+} 0x4690f18c4dd0ffe3
+test expr-28.892 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -400073978 E25 x -18a80dedbc575e_10000000000000000000000000001& E111
+ convertToDouble -400073978E25
+} 0xc6e8a80dedbc575f
+test expr-28.893 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +569014327 E-14 x 17ddbeac19d3b2_100000000000000000000000000001& E-18
+ convertToDouble +569014327E-14
+} 0x3ed7ddbeac19d3b3
+test expr-28.894 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -794263862 E-15 x -1aa6acb41dfc52_1000000000000000000000000000001& E-21
+ convertToDouble -794263862E-15
+} 0xbeaaa6acb41dfc53
+test expr-28.895 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +397131931 E-15 x 1aa6acb41dfc52_1000000000000000000000000000001& E-22
+ convertToDouble +397131931E-15
+} 0x3e9aa6acb41dfc53
+test expr-28.896 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -380398957 E-16 x -146c29d8331024_100000000000000000000000000001& E-25
+ convertToDouble -380398957E-16
+} 0xbe646c29d8331025
+test expr-28.897 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +567366773 E27 x 1b5155dd5417f9_0111111111111111111111111111110& E118
+ convertToDouble +567366773E27
+} 0x475b5155dd5417f9
+test expr-28.898 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -337440795 E24 x -10a31a03822bc9_011111111111111111111111111110& E108
+ convertToDouble -337440795E24
+} 0xc6b0a31a03822bc9
+test expr-28.899 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +134976318 E25 x 10a31a03822bc9_011111111111111111111111111110& E110
+ convertToDouble +134976318E25
+} 0x46d0a31a03822bc9
+test expr-28.900 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -269952636 E25 x -10a31a03822bc9_011111111111111111111111111110& E111
+ convertToDouble -269952636E25
+} 0xc6e0a31a03822bc9
+test expr-28.901 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +932080597 E-20 x 147f25b4941e5b_0111111111111111111111111111110& E-37
+ convertToDouble +932080597E-20
+} 0x3da47f25b4941e5b
+test expr-28.902 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -331091924 E-15 x -16381dae63505f_0111111111111111111111111111110& E-22
+ convertToDouble -331091924E-15
+} 0xbe96381dae63505f
+test expr-28.903 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -413864905 E-16 x -16381dae63505f_0111111111111111111111111111110& E-25
+ convertToDouble -413864905E-16
+} 0xbe66381dae63505f
+test expr-28.904 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8539246247 E26 x 148eb7813eaeba_10000000000000000000000000000001& E119
+ convertToDouble +8539246247E26
+} 0x47648eb7813eaebb
+test expr-28.905 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -5859139791 E26 x -1c35f28719d478_10000000000000000000000000000001& E118
+ convertToDouble -5859139791E26
+} 0xc75c35f28719d479
+test expr-28.906 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6105010149 E24 x 12d000fb2b138a_1000000000000000000000000000000001& E112
+ convertToDouble +6105010149E24
+} 0x46f2d000fb2b138b
+test expr-28.907 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -3090745820 E27 x -129a0c45ceca7a_1000000000000000000000000000001& E121
+ convertToDouble -3090745820E27
+} 0xc7829a0c45ceca7b
+test expr-28.908 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +3470877773 E-20 x 1314d381f2c31e_1000000000000000000000000000000001& E-35
+ convertToDouble +3470877773E-20
+} 0x3dc314d381f2c31f
+test expr-28.909 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -6136309089 E-27 x -1c4c799fab4328_1000000000000000000000000000000001& E-58
+ convertToDouble -6136309089E-27
+} 0xbc5c4c799fab4329
+test expr-28.910 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8917758713 E-19 x 1ea424bda7d7f4_100000000000000000000000000000001& E-31
+ convertToDouble +8917758713E-19
+} 0x3e0ea424bda7d7f5
+test expr-28.911 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -6941755546 E-20 x -1314d381f2c31e_1000000000000000000000000000000001& E-34
+ convertToDouble -6941755546E-20
+} 0xbdd314d381f2c31f
+test expr-28.912 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9194900535 E25 x 11b56f9c090dfb_011111111111111111111111111111111110& E116
+ convertToDouble +9194900535E25
+} 0x4731b56f9c090dfb
+test expr-28.913 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -1838980107 E26 x -11b56f9c090dfb_011111111111111111111111111111111110& E117
+ convertToDouble -1838980107E26
+} 0xc741b56f9c090dfb
+test expr-28.914 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +7355920428 E26 x 11b56f9c090dfb_011111111111111111111111111111111110& E119
+ convertToDouble +7355920428E26
+} 0x4761b56f9c090dfb
+test expr-28.915 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -3677960214 E26 x -11b56f9c090dfb_011111111111111111111111111111111110& E118
+ convertToDouble -3677960214E26
+} 0xc751b56f9c090dfb
+test expr-28.916 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8473634343 E-17 x 16bf0984b232b7_0111111111111111111111111111111110& E-24
+ convertToDouble +8473634343E-17
+} 0x3e76bf0984b232b7
+test expr-28.917 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8870766274 E-16 x -1dc3ee22137269_0111111111111111111111111111111110& E-21
+ convertToDouble -8870766274E-16
+} 0xbeadc3ee22137269
+test expr-28.918 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4435383137 E-16 x 1dc3ee22137269_0111111111111111111111111111111110& E-22
+ convertToDouble +4435383137E-16
+} 0x3e9dc3ee22137269
+test expr-28.919 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -9598990129 E-15 x -14216b286031e7_01111111111111111111111111111111110& E-17
+ convertToDouble -9598990129E-15
+} 0xbee4216b286031e7
+test expr-28.920 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +71563496764 E26 x 15890d1ef6a0da_10000000000000000000000000000000000001& E122
+ convertToDouble +71563496764E26
+} 0x4795890d1ef6a0db
+test expr-28.921 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -89454370955 E25 x -15890d1ef6a0da_10000000000000000000000000000000000001& E119
+ convertToDouble -89454370955E25
+} 0xc765890d1ef6a0db
+test expr-28.922 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +17890874191 E26 x 15890d1ef6a0da_10000000000000000000000000000000000001& E120
+ convertToDouble +17890874191E26
+} 0x4775890d1ef6a0db
+test expr-28.923 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -35781748382 E26 x -15890d1ef6a0da_10000000000000000000000000000000000001& E121
+ convertToDouble -35781748382E26
+} 0xc785890d1ef6a0db
+test expr-28.924 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +57973447842 E-19 x 18e63f7cf5313c_1000000000000000000000000000000000000001& E-28
+ convertToDouble +57973447842E-19
+} 0x3e38e63f7cf5313d
+test expr-28.925 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -28986723921 E-19 x -18e63f7cf5313c_1000000000000000000000000000000000000001& E-29
+ convertToDouble -28986723921E-19
+} 0xbe28e63f7cf5313d
+test expr-28.926 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +76822711313 E-19 x 107f5f8b3bf818_100000000000000000000000000000000001& E-27
+ convertToDouble +76822711313E-19
+} 0x3e407f5f8b3bf819
+test expr-28.927 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -97699466874 E-20 x -10c8de34de806e_10000000000000000000000000000000001& E-30
+ convertToDouble -97699466874E-20
+} 0xbe10c8de34de806f
+test expr-28.928 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +67748656762 E27 x 197bf5559b31fd_01111111111111111111111111111111111110& E125
+ convertToDouble +67748656762E27
+} 0x47c97bf5559b31fd
+test expr-28.929 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -19394840991 E24 x -1de1ea791a6e7d_0111111111111111111111111111111111110& E113
+ convertToDouble -19394840991E24
+} 0xc70de1ea791a6e7d
+test expr-28.930 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +38789681982 E24 x 1de1ea791a6e7d_0111111111111111111111111111111111110& E114
+ convertToDouble +38789681982E24
+} 0x471de1ea791a6e7d
+test expr-28.931 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -33874328381 E27 x -197bf5559b31fd_01111111111111111111111111111111111110& E124
+ convertToDouble -33874328381E27
+} 0xc7b97bf5559b31fd
+test expr-28.932 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +54323763886 E-27 x 1f50c5c63e5441_0111111111111111111111111111111111110& E-55
+ convertToDouble +54323763886E-27
+} 0x3c8f50c5c63e5441
+test expr-28.933 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -58987193887 E-20 x -14449185a4c829_011111111111111111111111111111111111110& E-31
+ convertToDouble -58987193887E-20
+} 0xbe04449185a4c829
+test expr-28.934 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +27161881943 E-27 x 1f50c5c63e5441_0111111111111111111111111111111111110& E-56
+ convertToDouble +27161881943E-27
+} 0x3c7f50c5c63e5441
+test expr-28.935 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -93042648033 E-19 x -13fb12dc023fd3_0111111111111111111111111111111111110& E-27
+ convertToDouble -93042648033E-19
+} 0xbe43fb12dc023fd3
+test expr-28.936 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +520831059055 E27 x 187d469cb69dd0_10000000000000000000000000000000000000001& E128
+ convertToDouble +520831059055E27
+} 0x47f87d469cb69dd1
+test expr-28.937 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -768124264394 E25 x -171d6a019edae8_1000000000000000000000000000000000000001& E122
+ convertToDouble -768124264394E25
+} 0xc7971d6a019edae9
+test expr-28.938 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +384062132197 E25 x 171d6a019edae8_1000000000000000000000000000000000000001& E121
+ convertToDouble +384062132197E25
+} 0x47871d6a019edae9
+test expr-28.939 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +765337749889 E-25 x 158ad6f5d0a854_100000000000000000000000000000000000000001& E-44
+ convertToDouble +765337749889E-25
+} 0x3d358ad6f5d0a855
+test expr-28.940 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +794368912771 E25 x 17e79872f2f7ef_01111111111111111111111111111111111111110& E122
+ convertToDouble +794368912771E25
+} 0x4797e79872f2f7ef
+test expr-28.941 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -994162090146 E23 x -132598f85e658b_011111111111111111111111111111111111110& E116
+ convertToDouble -994162090146E23
+} 0xc7332598f85e658b
+test expr-28.942 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +781652779431 E26 x 1d670adf52038f_01111111111111111111111111111111111110& E125
+ convertToDouble +781652779431E26
+} 0x47cd670adf52038f
+test expr-28.943 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +910077190046 E-26 x 147e3ce1871d79_01111111111111111111111111111111111111110& E-47
+ convertToDouble +910077190046E-26
+} 0x3d047e3ce1871d79
+test expr-28.944 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -455038595023 E-26 x -147e3ce1871d79_01111111111111111111111111111111111111110& E-48
+ convertToDouble -455038595023E-26
+} 0xbcf47e3ce1871d79
+test expr-28.945 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +471897551096 E-20 x 14449185a4c829_011111111111111111111111111111111111110& E-28
+ convertToDouble +471897551096E-20
+} 0x3e34449185a4c829
+test expr-28.946 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -906698409911 E-21 x -1f27674f7d5745_0111111111111111111111111111111111111110& E-31
+ convertToDouble -906698409911E-21
+} 0xbe0f27674f7d5745
+test expr-28.947 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8854128003935 E25 x 10a71b8948faac_100000000000000000000000000000000000000001& E126
+ convertToDouble +8854128003935E25
+} 0x47d0a71b8948faad
+test expr-28.948 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8146122716299 E27 x -17f0762ac05654_1000000000000000000000000000000000000000001& E132
+ convertToDouble -8146122716299E27
+} 0xc837f0762ac05655
+test expr-28.949 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +7083302403148 E26 x 10a71b8948faac_100000000000000000000000000000000000000001& E129
+ convertToDouble +7083302403148E26
+} 0x4800a71b8948faad
+test expr-28.950 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -3541651201574 E26 x -10a71b8948faac_100000000000000000000000000000000000000001& E128
+ convertToDouble -3541651201574E26
+} 0xc7f0a71b8948faad
+test expr-28.951 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8394920649291 E-25 x 1d8978e8c1cc78_100000000000000000000000000000000000000000001& E-41
+ convertToDouble +8394920649291E-25
+} 0x3d6d8978e8c1cc79
+test expr-28.952 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -7657975756753 E-22 x -1a5006d695fef0_1000000000000000000000000000000000000000000001& E-31
+ convertToDouble -7657975756753E-22
+} 0xbe0a5006d695fef1
+test expr-28.953 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +5473834002228 E-20 x 1d632e1f745624_100000000000000000000000000000000000000000001& E-25
+ convertToDouble +5473834002228E-20
+} 0x3e6d632e1f745625
+test expr-28.954 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -6842292502785 E-21 x -1d632e1f745624_100000000000000000000000000000000000000000001& E-28
+ convertToDouble -6842292502785E-21
+} 0xbe3d632e1f745625
+test expr-28.955 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2109568884597 E25 x -1fbdc386609b13_011111111111111111111111111111111111111110& E123
+ convertToDouble -2109568884597E25
+} 0xc7afbdc386609b13
+test expr-28.956 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8438275538388 E25 x 1fbdc386609b13_011111111111111111111111111111111111111110& E125
+ convertToDouble +8438275538388E25
+} 0x47cfbdc386609b13
+test expr-28.957 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4219137769194 E25 x -1fbdc386609b13_011111111111111111111111111111111111111110& E124
+ convertToDouble -4219137769194E25
+} 0xc7bfbdc386609b13
+test expr-28.958 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +3200141789841 E-25 x 1684dcea3829f7_0111111111111111111111111111111111111111110& E-42
+ convertToDouble +3200141789841E-25
+} 0x3d5684dcea3829f7
+test expr-28.959 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8655689322607 E-22 x -1dbd9ff5dc8991_011111111111111111111111111111111111111110& E-31
+ convertToDouble -8655689322607E-22
+} 0xbe0dbd9ff5dc8991
+test expr-28.960 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6400283579682 E-25 x 1684dcea3829f7_0111111111111111111111111111111111111111110& E-41
+ convertToDouble +6400283579682E-25
+} 0x3d6684dcea3829f7
+test expr-28.961 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8837719634493 E-21 x -12fa9676d2585b_011111111111111111111111111111111111111110& E-27
+ convertToDouble -8837719634493E-21
+} 0xbe42fa9676d2585b
+test expr-28.962 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +19428217075297 E24 x 1d3b7a1d154aba_10000000000000000000000000000000000000000000001& E123
+ convertToDouble +19428217075297E24
+} 0x47ad3b7a1d154abb
+test expr-28.963 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -38856434150594 E24 x -1d3b7a1d154aba_10000000000000000000000000000000000000000000001& E124
+ convertToDouble -38856434150594E24
+} 0xc7bd3b7a1d154abb
+test expr-28.964 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +77712868301188 E24 x 1d3b7a1d154aba_10000000000000000000000000000000000000000000001& E125
+ convertToDouble +77712868301188E24
+} 0x47cd3b7a1d154abb
+test expr-28.965 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -77192037242133 E27 x -1c5b1ab32d5dbe_1000000000000000000000000000000000000000000000001& E135
+ convertToDouble -77192037242133E27
+} 0xc86c5b1ab32d5dbf
+test expr-28.966 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +76579757567530 E-23 x 1a5006d695fef0_1000000000000000000000000000000000000000000001& E-31
+ convertToDouble +76579757567530E-23
+} 0x3e0a5006d695fef1
+test expr-28.967 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +15315951513506 E-22 x 1a5006d695fef0_1000000000000000000000000000000000000000000001& E-30
+ convertToDouble +15315951513506E-22
+} 0x3e1a5006d695fef1
+test expr-28.968 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -38289878783765 E-23 x -1a5006d695fef0_1000000000000000000000000000000000000000000001& E-32
+ convertToDouble -38289878783765E-23
+} 0xbdfa5006d695fef1
+test expr-28.969 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +49378033925202 E25 x 1737aa2567167b_0111111111111111111111111111111111111111111110& E128
+ convertToDouble +49378033925202E25
+} 0x47f737aa2567167b
+test expr-28.970 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -50940527102367 E24 x -132964f2944b05_0111111111111111111111111111111111111111111111110& E125
+ convertToDouble -50940527102367E24
+} 0xc7c32964f2944b05
+test expr-28.971 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +98756067850404 E25 x 1737aa2567167b_0111111111111111111111111111111111111111111110& E129
+ convertToDouble +98756067850404E25
+} 0x480737aa2567167b
+test expr-28.972 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -99589397544892 E26 x -1d4446075c4933_0111111111111111111111111111111111111111111110& E132
+ convertToDouble -99589397544892E26
+} 0xc83d4446075c4933
+test expr-28.973 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -56908598265713 E-25 x -190756ab1ed6b3_011111111111111111111111111111111111111111111110& E-38
+ convertToDouble -56908598265713E-25
+} 0xbd990756ab1ed6b3
+test expr-28.974 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +97470695699657 E-22 x 14ee821710e655_01111111111111111111111111111111111111111111110& E-27
+ convertToDouble +97470695699657E-22
+} 0x3e44ee821710e655
+test expr-28.975 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -35851901247343 E-25 x -1f8921657e1581_0111111111111111111111111111111111111111111110& E-39
+ convertToDouble -35851901247343E-25
+} 0xbd8f8921657e1581
+test expr-28.976 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +154384074484266 E27 x 1c5b1ab32d5dbe_1000000000000000000000000000000000000000000000001& E136
+ convertToDouble +154384074484266E27
+} 0x487c5b1ab32d5dbf
+test expr-28.977 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -308768148968532 E27 x -1c5b1ab32d5dbe_1000000000000000000000000000000000000000000000001& E137
+ convertToDouble -308768148968532E27
+} 0xc88c5b1ab32d5dbf
+test expr-28.978 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +910990389005985 E23 x 112242592ae54a_100000000000000000000000000000000000000000000001& E126
+ convertToDouble +910990389005985E23
+} 0x47d12242592ae54b
+test expr-28.979 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +271742424169201 E-27 x 131f46bcf7b452_10000000000000000000000000000000000000000000000001& E-42
+ convertToDouble +271742424169201E-27
+} 0x3d531f46bcf7b453
+test expr-28.980 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -543484848338402 E-27 x -131f46bcf7b452_10000000000000000000000000000000000000000000000001& E-41
+ convertToDouble -543484848338402E-27
+} 0xbd631f46bcf7b453
+test expr-28.981 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +162192083357563 E-26 x 1c887b68658760_1000000000000000000000000000000000000000000000001& E-40
+ convertToDouble +162192083357563E-26
+} 0x3d7c887b68658761
+test expr-28.982 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -869254552770081 E-23 x -12aac70665485e_1000000000000000000000000000000000000000000000000001& E-27
+ convertToDouble -869254552770081E-23
+} 0xbe42aac70665485f
+test expr-28.983 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +664831007626046 E24 x 1f429cb67eb075_011111111111111111111111111111111111111111111111110& E128
+ convertToDouble +664831007626046E24
+} 0x47ff429cb67eb075
+test expr-28.984 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -332415503813023 E24 x -1f429cb67eb075_011111111111111111111111111111111111111111111111110& E127
+ convertToDouble -332415503813023E24
+} 0xc7ef429cb67eb075
+test expr-28.985 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +943701829041427 E24 x 162fb2e38ee461_01111111111111111111111111111111111111111111111110& E129
+ convertToDouble +943701829041427E24
+} 0x48062fb2e38ee461
+test expr-28.986 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -101881054204734 E24 x -132964f2944b05_0111111111111111111111111111111111111111111111110& E126
+ convertToDouble -101881054204734E24
+} 0xc7d32964f2944b05
+test expr-28.987 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +828027839666967 E-27 x 1d2236349da3cd_011111111111111111111111111111111111111111111111110& E-41
+ convertToDouble +828027839666967E-27
+} 0x3d6d2236349da3cd
+test expr-28.988 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -280276135608777 E-27 x -13b901892fd0bf_0111111111111111111111111111111111111111111111110& E-42
+ convertToDouble -280276135608777E-27
+} 0xbd53b901892fd0bf
+test expr-28.989 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +212839188833879 E-21 x 1c91194dc2d40b_0111111111111111111111111111111111111111111111110& E-23
+ convertToDouble +212839188833879E-21
+} 0x3e8c91194dc2d40b
+test expr-28.990 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -113817196531426 E-25 x -190756ab1ed6b3_011111111111111111111111111111111111111111111110& E-37
+ convertToDouble -113817196531426E-25
+} 0xbda90756ab1ed6b3
+test expr-28.991 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9711553197796883 E27 x 1bdeec25c0f03e_10000000000000000000000000000000000000000000000000001& E142
+ convertToDouble +9711553197796883E27
+} 0x48dbdeec25c0f03f
+test expr-28.992 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2739849386524269 E26 x -19295ade212370_1000000000000000000000000000000000000000000000000001& E137
+ convertToDouble -2739849386524269E26
+} 0xc889295ade212371
+test expr-28.993 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +5479698773048538 E26 x 19295ade212370_1000000000000000000000000000000000000000000000000001& E138
+ convertToDouble +5479698773048538E26
+} 0x4899295ade212371
+test expr-28.994 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6124568318523113 E-25 x 150b3a2e0aff14_1000000000000000000000000000000000000000000000000000001& E-31
+ convertToDouble +6124568318523113E-25
+} 0x3e050b3a2e0aff15
+test expr-28.995 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -1139777988171071 E-24 x -1394cbee428ea4_10000000000000000000000000000000000000000000000000001& E-30
+ convertToDouble -1139777988171071E-24
+} 0xbe1394cbee428ea5
+test expr-28.996 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6322612303128019 E-27 x 1bcea0ec21e250_1000000000000000000000000000000000000000000000000000001& E-38
+ convertToDouble +6322612303128019E-27
+} 0x3d9bcea0ec21e251
+test expr-28.997 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2955864564844617 E-25 x -1450030e26c6dc_10000000000000000000000000000000000000000000000000001& E-32
+ convertToDouble -2955864564844617E-25
+} 0xbdf450030e26c6dd
+test expr-28.998 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -9994029144998961 E25 x -125b2b7fed4a61_0111111111111111111111111111111111111111111111111110& E136
+ convertToDouble -9994029144998961E25
+} 0xc8725b2b7fed4a61
+test expr-28.999 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2971238324022087 E27 x -110dd7a301db67_0111111111111111111111111111111111111111111111111110& E141
+ convertToDouble -2971238324022087E27
+} 0xc8c10dd7a301db67
+test expr-28.1000 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -1656055679333934 E-27 x -1d2236349da3cd_011111111111111111111111111111111111111111111111110& E-40
+ convertToDouble -1656055679333934E-27
+} 0xbd7d2236349da3cd
+test expr-28.1001 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -1445488709150234 E-26 x -1fc960c59526c7_0111111111111111111111111111111111111111111111110& E-37
+ convertToDouble -1445488709150234E-26
+} 0xbdafc960c59526c7
+test expr-28.1002 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +55824717499885172 E27 x 1406b0cd17fd56_1000000000000000000000000000000000000000000000000000000001& E145
+ convertToDouble +55824717499885172E27
+} 0x490406b0cd17fd57
+test expr-28.1003 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -69780896874856465 E26 x -1406b0cd17fd56_1000000000000000000000000000000000000000000000000000000001& E142
+ convertToDouble -69780896874856465E26
+} 0xc8d406b0cd17fd57
+test expr-28.1004 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +84161538867545199 E25 x 13529217bdce6c_10000000000000000000000000000000000000000000000000000000001& E139
+ convertToDouble +84161538867545199E25
+} 0x48a3529217bdce6d
+test expr-28.1005 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -27912358749942586 E27 x -1406b0cd17fd56_1000000000000000000000000000000000000000000000000000000001& E144
+ convertToDouble -27912358749942586E27
+} 0xc8f406b0cd17fd57
+test expr-28.1006 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +24711112462926331 E-25 x 153a07f6040d22_100000000000000000000000000000000000000000000000000000001& E-29
+ convertToDouble +24711112462926331E-25
+} 0x3e253a07f6040d23
+test expr-28.1007 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -12645224606256038 E-27 x -1bcea0ec21e250_1000000000000000000000000000000000000000000000000000001& E-37
+ convertToDouble -12645224606256038E-27
+} 0xbdabcea0ec21e251
+test expr-28.1008 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -12249136637046226 E-25 x -150b3a2e0aff14_1000000000000000000000000000000000000000000000000000001& E-30
+ convertToDouble -12249136637046226E-25
+} 0xbe150b3a2e0aff15
+test expr-28.1009 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +74874448287465757 E27 x 1adc21d1d50b09_01111111111111111111111111111111111111111111111111111110& E145
+ convertToDouble +74874448287465757E27
+} 0x490adc21d1d50b09
+test expr-28.1010 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -35642836832753303 E24 x -1a2fac2b421f53_0111111111111111111111111111111111111111111111111111110& E134
+ convertToDouble -35642836832753303E24
+} 0xc85a2fac2b421f53
+test expr-28.1011 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -71285673665506606 E24 x -1a2fac2b421f53_0111111111111111111111111111111111111111111111111111110& E135
+ convertToDouble -71285673665506606E24
+} 0xc86a2fac2b421f53
+test expr-28.1012 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +43723334984997307 E-26 x 1e0be3f392c549_01111111111111111111111111111111111111111111111111111110& E-32
+ convertToDouble +43723334984997307E-26
+} 0x3dfe0be3f392c549
+test expr-28.1013 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +10182419849537963 E-24 x 15ddd831ebbe53_011111111111111111111111111111111111111111111111111110& E-27
+ convertToDouble +10182419849537963E-24
+} 0x3e45ddd831ebbe53
+test expr-28.1014 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -93501703572661982 E-26 x -10103f97ea6e13_0111111111111111111111111111111111111111111111111110& E-30
+ convertToDouble -93501703572661982E-26
+} 0xbe10103f97ea6e13
+
+test expr-29.1 {smallest representible number} {ieeeFloatingPoint} {
+ list [catch {convertToDouble 4.9406564584124654e-324} result] \
+ $result \
+ [catch {convertToDouble 2.4703282292062327e-324} result] \
+ $result \
+ [catch {convertToDouble 2.47032822920623e-324} result] \
+ $result
+} {0 0x0000000000000001 0 0x0000000000000001 0 0x0000000000000000}
+test expr-29.2 {smallest representible number} {ieeeFloatingPoint} {
+ list [catch {convertToDouble -4.9406564584124654e-324} result] \
+ $result \
+ [catch {convertToDouble -2.4703282292062327e-324} result] \
+ $result \
+ [catch {convertToDouble -2.47032822920623e-324} result] \
+ $result
+} {0 0x8000000000000001 0 0x8000000000000001 0 0x8000000000000000}
+test expr-29.3 {silent underflow on input conversion} {ieeeFloatingPoint} {
+ set v ?
+ list [scan 2.47032822920623e-324 %g v] $v
+} {1 0.0}
+test expr-29.4 {silent underflow on input conversion} {ieeeFloatingPoint} {
+ set v ?
+ list [scan -2.47032822920623e-324 %g v] $v
+} {1 -0.0}
+
+test expr-30.1 {largest representible number} {ieeeFloatingPoint} {
+ list [catch {convertToDouble 1.7976931348623155e+308} result] \
+ $result \
+ [catch {convertToDouble 1.7976931348623157e+308} result] \
+ $result \
+ [catch {convertToDouble 1.7976931348623159e+308} result] \
+ $result
+} {0 0x7feffffffffffffe 0 0x7fefffffffffffff 0 0x7ff0000000000000}
+test expr-30.2 {largest representible number} {ieeeFloatingPoint} {
+ list [catch {convertToDouble -1.7976931348623155e+308} result] \
+ $result \
+ [catch {convertToDouble -1.7976931348623157e+308} result] \
+ $result \
+ [catch {convertToDouble -1.7976931348623159e+308} result] \
+ $result
+} {0 0xffeffffffffffffe 0 0xffefffffffffffff 0 0xfff0000000000000}
+test expr-30.3 {silent overflow on input conversion} {ieeeFloatingPoint} {
+ set v ?
+ list [scan 1.7976931348623159e+308 %f v] $v
+} {1 Inf}
+test expr-30.4 {silent overflow on input conversion} {ieeeFloatingPoint} {
+ set v ?
+ list [scan -1.7976931348623159e+308 %f v] $v
+} {1 -Inf}
+
+# bool() tests (TIP #182)
+set i 0
+foreach s {yes true on} {
+ test expr-31.$i.0 {boolean conversion} {expr bool($s)} 1
+ test expr-31.$i.1 {boolean conversion} {expr bool(!$s)} 0
+ test expr-31.$i.2 {boolean conversion} {expr bool("$s")} 1
+ test expr-31.$i.3 {boolean conversion} {expr bool(!"$s")} 0
+ set j 1
+ while {$j < [string length $s]-1} {
+ test expr-31.$i.4.$j {boolean conversion} {
+ expr bool([string range $s 0 $j])
+ } 1
+ test expr-31.$i.5.$j {boolean conversion} {
+ expr bool("[string range $s 0 $j]")
+ } 1
+ incr j
+ }
+ incr i
+}
+test expr-31.0.4.0 {boolean conversion} {expr bool(y)} 1
+test expr-31.0.5.0 {boolean conversion} {expr bool("y")} 1
+test expr-31.1.4.0 {boolean conversion} {expr bool(t)} 1
+test expr-31.1.5.0 {boolean conversion} {expr bool("t")} 1
+test expr-31.2.4.0 {boolean conversion} -body {
+ expr bool(o)
+} -returnCodes error -match glob -result *
+test expr-31.2.5.0 {boolean conversion} -body {
+ expr bool("o")
+} -returnCodes error -match glob -result *
+foreach s {no false off} {
+ test expr-31.$i.0 {boolean conversion} {expr bool($s)} 0
+ test expr-31.$i.1 {boolean conversion} {expr bool(!$s)} 1
+ test expr-31.$i.2 {boolean conversion} {expr bool("$s")} 0
+ test expr-31.$i.3 {boolean conversion} {expr bool(!"$s")} 1
+ set j 1
+ while {$j < [string length $s]-1} {
+ test expr-31.$i.4.$j {boolean conversion} {
+ expr bool([string range $s 0 $j])
+ } 0
+ test expr-31.$i.5.$j {boolean conversion} {
+ expr bool("[string range $s 0 $j]")
+ } 0
+ incr j
+ }
+ incr i
+}
+test expr-31.3.4.0 {boolean conversion} {expr bool(n)} 0
+test expr-31.3.5.0 {boolean conversion} {expr bool("n")} 0
+test expr-31.4.4.0 {boolean conversion} {expr bool(f)} 0
+test expr-31.4.5.0 {boolean conversion} {expr bool("f")} 0
+test expr-31.6 {boolean conversion} {expr bool(-1 + 1)} 0
+test expr-31.7 {boolean conversion} {expr bool(0 + 1)} 1
+test expr-31.8 {boolean conversion} {expr bool(0.0)} 0
+test expr-31.9 {boolean conversion} {expr bool(0x0)} 0
+test expr-31.10 {boolean conversion} {expr bool(wide(0))} 0
+test expr-31.11 {boolean conversion} {expr bool(5.0)} 1
+test expr-31.12 {boolean conversion} {expr bool(5)} 1
+test expr-31.13 {boolean conversion} {expr bool(0x5)} 1
+test expr-31.14 {boolean conversion} {expr bool(wide(5))} 1
+test expr-31.15 {boolean conversion} -body {
+ expr bool("fred")
+} -returnCodes error -match glob -result *
+
+test expr-32.1 {expr mod basics} {
+ set mod_nums [list \
+ {-3 1} {-3 2} {-3 3} {-3 4} {-3 5} \
+ {-3 -1} {-3 -2} {-3 -3} {-3 -4} {-3 -5} \
+ {-2 1} {-2 2} {-2 3} {-2 4} {-2 5} \
+ {-2 -1} {-2 -2} {-2 -3} {-2 -4} {-2 -5} \
+ {-1 1} {-1 2} {-1 3} {-1 4} {-1 5} \
+ {-1 -1} {-1 -2} {-1 -3} {-1 -4} {-1 -5} \
+ {0 -100} {0 -1} {0 1} {0 100} \
+ {1 1} {1 2} {1 3} {1 4} {1 5} \
+ {1 -1} {1 -2} {1 -3} {1 -4} {1 -5} \
+ {2 1} {2 2} {2 3} {2 4} {2 5} \
+ {2 -1} {2 -2} {2 -3} {2 -4} {2 -5} \
+ {3 1} {3 2} {3 3} {3 4} {3 5} \
+ {3 -1} {3 -2} {3 -3} {3 -4} {3 -5} \
+ ]
+ set results [list]
+ foreach pair $mod_nums {
+ set dividend [lindex $pair 0]
+ set divisor [lindex $pair 1]
+ lappend results [expr {$dividend % $divisor}]
+ }
+ set results
+} [list \
+ 0 1 0 1 2 \
+ 0 -1 0 -3 -3 \
+ 0 0 1 2 3 \
+ 0 0 -2 -2 -2 \
+ 0 1 2 3 4 \
+ 0 -1 -1 -1 -1 \
+ 0 0 0 0 \
+ 0 1 1 1 1 \
+ 0 -1 -2 -3 -4 \
+ 0 0 2 2 2 \
+ 0 0 -1 -2 -3 \
+ 0 1 0 3 3 \
+ 0 -1 0 -1 -2 \
+ ]
+
+test expr-32.2 {expr div basics} {
+ set mod_nums [list \
+ {-3 1} {-3 2} {-3 3} {-3 4} {-3 5} \
+ {-3 -1} {-3 -2} {-3 -3} {-3 -4} {-3 -5} \
+ {-2 1} {-2 2} {-2 3} {-2 4} {-2 5} \
+ {-2 -1} {-2 -2} {-2 -3} {-2 -4} {-2 -5} \
+ {-1 1} {-1 2} {-1 3} {-1 4} {-1 5} \
+ {-1 -1} {-1 -2} {-1 -3} {-1 -4} {-1 -5} \
+ {0 -100} {0 -1} {0 1} {0 100} \
+ {1 1} {1 2} {1 3} {1 4} {1 5} \
+ {1 -1} {1 -2} {1 -3} {1 -4} {1 -5} \
+ {2 1} {2 2} {2 3} {2 4} {2 5} \
+ {2 -1} {2 -2} {2 -3} {2 -4} {2 -5} \
+ {3 1} {3 2} {3 3} {3 4} {3 5} \
+ {3 -1} {3 -2} {3 -3} {3 -4} {3 -5} \
+ ]
+ set results [list]
+ foreach pair $mod_nums {
+ set dividend [lindex $pair 0]
+ set divisor [lindex $pair 1]
+ lappend results [expr {$dividend / $divisor}]
+ }
+ set results
+} [list \
+ -3 -2 -1 -1 -1 \
+ 3 1 1 0 0 \
+ -2 -1 -1 -1 -1 \
+ 2 1 0 0 0 \
+ -1 -1 -1 -1 -1 \
+ 1 0 0 0 0 \
+ 0 0 0 0 \
+ 1 0 0 0 0 \
+ -1 -1 -1 -1 -1 \
+ 2 1 0 0 0 \
+ -2 -1 -1 -1 -1 \
+ 3 1 1 0 0 \
+ -3 -2 -1 -1 -1 \
+ ]
+
+test expr-32.3 {Bug 1585704} {
+ expr 1%(1<<63)
+} 1
+test expr-32.4 {Bug 1585704} {
+ expr -1%(1<<63)
+} [expr (1<<63)-1]
+test expr-32.5 {Bug 1585704} {
+ expr (1<<32)%(1<<63)
+} [expr 1<<32]
+test expr-32.6 {Bug 1585704} {
+ expr -(1<<32)%(1<<63)
+} [expr (1<<63)-(1<<32)]
+
+test expr-33.1 {parse largest long value} longIs32bit {
+ set max_long_str 2147483647
+ set max_long_hex "0x7FFFFFFF "
+
+ # Convert to integer (long, not wide) internal rep
+ set max_long 2147483647
+ string is integer $max_long
+
+ list \
+ [expr {" $max_long_str "}] \
+ [expr {$max_long_str + 0}] \
+ [expr {$max_long + 0}] \
+ [expr {2147483647 + 0}] \
+ [expr {$max_long == $max_long_hex}] \
+ [expr {int(2147483647 + 1) < 0}] \
+
+} {2147483647 2147483647 2147483647 2147483647 1 1}
+test expr-33.2 {parse smallest long value} longIs32bit {
+ set min_long_str -2147483648
+ set min_long_hex "-0x80000000 "
+
+ set min_long -2147483648
+ # This will convert to integer (not wide) internal rep
+ string is integer $min_long
+
+ # Note: If the final expression returns 0 then the
+ # expression literal is being promoted to a wide type
+ # when it should be parsed as a long type.
+ list \
+ [expr {" $min_long_str "}] \
+ [expr {$min_long_str + 0}] \
+ [expr {$min_long + 0}] \
+ [expr {-2147483648 + 0}] \
+ [expr {$min_long == $min_long_hex}] \
+ [expr {int(-2147483648 - 1) == 0x7FFFFFFF}] \
+
+} {-2147483648 -2147483648 -2147483648 -2147483648 1 1}
+test expr-33.3 {parse largest wide value} wideIs64bit {
+ set max_wide_str 9223372036854775807
+ set max_wide_hex "0x7FFFFFFFFFFFFFFF "
+
+ # Convert to wide integer
+ set max_wide 9223372036854775807
+ string is integer $max_wide
+
+ list \
+ [expr {" $max_wide_str "}] \
+ [expr {$max_wide_str + 0}] \
+ [expr {$max_wide + 0}] \
+ [expr {9223372036854775807 + 0}] \
+ [expr {$max_wide == $max_wide_hex}] \
+ [expr {wide(9223372036854775807 + 1) < 0}] \
+
+} {9223372036854775807 9223372036854775807 9223372036854775807 9223372036854775807 1 1}
+test expr-33.4 {parse smallest wide value} wideIs64bit {
+ set min_wide_str -9223372036854775808
+ set min_wide_hex "-0x8000000000000000 "
+
+ set min_wide -9223372036854775808
+ # Convert to wide integer
+ string is integer $min_wide
+
+ # Note: If the final expression returns 0 then the
+ # wide integer is not being parsed correctly with
+ # the leading - sign.
+ list \
+ [expr {" $min_wide_str "}] \
+ [expr {$min_wide_str + 0}] \
+ [expr {$min_wide + 0}] \
+ [expr {-9223372036854775808 + 0}] \
+ [expr {$min_wide == $min_wide_hex}] \
+ [expr {wide(-9223372036854775808 - 1) == 0x7FFFFFFFFFFFFFFF}] \
+
+} {-9223372036854775808 -9223372036854775808 -9223372036854775808 -9223372036854775808 1 1}
+
+set min -2147483648
+set max 2147483647
+
+test expr-34.1 {expr edge cases} {
+ expr {$min / $min}
+} {1}
+test expr-34.2 {expr edge cases} {
+ expr {$min % $min}
+} {0}
+test expr-34.3 {expr edge cases} {
+ expr {$min / ($min + 1)}
+} {1}
+test expr-34.4 {expr edge cases} {
+ expr {$min % ($min + 1)}
+} {-1}
+test expr-34.5 {expr edge cases} {
+ expr {$min / ($min + 2)}
+} {1}
+test expr-34.6 {expr edge cases} {
+ expr {$min % ($min + 2)}
+} {-2}
+test expr-34.7 {expr edge cases} {
+ expr {$min / ($min + 3)}
+} {1}
+test expr-34.8 {expr edge cases} {
+ expr {$min % ($min + 3)}
+} {-3}
+test expr-34.9 {expr edge cases} {
+ expr {$min / -3}
+} {715827882}
+test expr-34.10 {expr edge cases} {
+ expr {$min % -3}
+} {-2}
+test expr-34.11 {expr edge cases} {
+ expr {$min / -2}
+} {1073741824}
+test expr-34.12 {expr edge cases} {
+ expr {$min % -2}
+} {0}
+test expr-34.13 {expr edge cases} longIs32bit {
+ expr {int($min / -1)}
+} {-2147483648}
+test expr-34.14 {expr edge cases} {
+ expr {$min % -1}
+} {0}
+test expr-34.15 {expr edge cases} longIs32bit {
+ expr {int($min * -1)}
+} $min
+test expr-34.16 {expr edge cases} longIs32bit {
+ expr {int(-$min)}
+} $min
+test expr-34.17 {expr edge cases} {
+ expr {$min / 1}
+} $min
+test expr-34.18 {expr edge cases} {
+ expr {$min % 1}
+} {0}
+test expr-34.19 {expr edge cases} {
+ expr {$min / 2}
+} {-1073741824}
+test expr-34.20 {expr edge cases} {
+ expr {$min % 2}
+} {0}
+test expr-34.21 {expr edge cases} {
+ expr {$min / 3}
+} {-715827883}
+test expr-34.22 {expr edge cases} {
+ expr {$min % 3}
+} {1}
+test expr-34.23 {expr edge cases} {
+ expr {$min / ($max - 3)}
+} {-2}
+test expr-34.24 {expr edge cases} {
+ expr {$min % ($max - 3)}
+} {2147483640}
+test expr-34.25 {expr edge cases} {
+ expr {$min / ($max - 2)}
+} {-2}
+test expr-34.26 {expr edge cases} {
+ expr {$min % ($max - 2)}
+} {2147483642}
+test expr-34.27 {expr edge cases} {
+ expr {$min / ($max - 1)}
+} {-2}
+test expr-34.28 {expr edge cases} {
+ expr {$min % ($max - 1)}
+} {2147483644}
+test expr-34.29 {expr edge cases} {
+ expr {$min / $max}
+} {-2}
+test expr-34.30 {expr edge cases} {
+ expr {$min % $max}
+} {2147483646}
+test expr-34.31 {expr edge cases} {
+ expr {$max / $max}
+} {1}
+test expr-34.32 {expr edge cases} {
+ expr {$max % $max}
+} {0}
+test expr-34.33 {expr edge cases} {
+ expr {$max / ($max - 1)}
+} {1}
+test expr-34.34 {expr edge cases} {
+ expr {$max % ($max - 1)}
+} {1}
+test expr-34.35 {expr edge cases} {
+ expr {$max / ($max - 2)}
+} {1}
+test expr-34.36 {expr edge cases} {
+ expr {$max % ($max - 2)}
+} {2}
+test expr-34.37 {expr edge cases} {
+ expr {$max / ($max - 3)}
+} {1}
+test expr-34.38 {expr edge cases} {
+ expr {$max % ($max - 3)}
+} {3}
+test expr-34.39 {expr edge cases} {
+ expr {$max / 3}
+} {715827882}
+test expr-34.40 {expr edge cases} {
+ expr {$max % 3}
+} {1}
+test expr-34.41 {expr edge cases} {
+ expr {$max / 2}
+} {1073741823}
+test expr-34.42 {expr edge cases} {
+ expr {$max % 2}
+} {1}
+test expr-34.43 {expr edge cases} {
+ expr {$max / 1}
+} $max
+test expr-34.44 {expr edge cases} {
+ expr {$max % 1}
+} {0}
+test expr-34.45 {expr edge cases} {
+ expr {$max / -1}
+} "-$max"
+test expr-34.46 {expr edge cases} {
+ expr {$max % -1}
+} {0}
+test expr-34.47 {expr edge cases} {
+ expr {$max / -2}
+} {-1073741824}
+test expr-34.48 {expr edge cases} {
+ expr {$max % -2}
+} {-1}
+test expr-34.49 {expr edge cases} {
+ expr {$max / -3}
+} {-715827883}
+test expr-34.50 {expr edge cases} {
+ expr {$max % -3}
+} {-2}
+test expr-34.51 {expr edge cases} {
+ expr {$max / ($min + 3)}
+} {-2}
+test expr-34.52 {expr edge cases} {
+ expr {$max % ($min + 3)}
+} {-2147483643}
+test expr-34.53 {expr edge cases} {
+ expr {$max / ($min + 2)}
+} {-2}
+test expr-34.54 {expr edge cases} {
+ expr {$max % ($min + 2)}
+} {-2147483645}
+test expr-34.55 {expr edge cases} {
+ expr {$max / ($min + 1)}
+} {-1}
+test expr-34.56 {expr edge cases} {
+ expr {$max % ($min + 1)}
+} {0}
+test expr-34.57 {expr edge cases} {
+ expr {$max / $min}
+} {-1}
+test expr-34.58 {expr edge cases} {
+ expr {$max % $min}
+} {-1}
+test expr-34.59 {expr edge cases} {
+ expr {($min + 1) / ($max - 1)}
+} {-2}
+test expr-34.60 {expr edge cases} {
+ expr {($min + 1) % ($max - 1)}
+} {2147483645}
+test expr-34.61 {expr edge cases} {
+ expr {($max - 1) / ($min + 1)}
+} {-1}
+test expr-34.62 {expr edge cases} {
+ expr {($max - 1) % ($min + 1)}
+} {-1}
+test expr-34.63 {expr edge cases} {
+ expr {($max - 1) / $min}
+} {-1}
+test expr-34.64 {expr edge cases} {
+ expr {($max - 1) % $min}
+} {-2}
+test expr-34.65 {expr edge cases} {
+ expr {($max - 2) / $min}
+} {-1}
+test expr-34.66 {expr edge cases} {
+ expr {($max - 2) % $min}
+} {-3}
+test expr-34.67 {expr edge cases} {
+ expr {($max - 3) / $min}
+} {-1}
+test expr-34.68 {expr edge cases} {
+ expr {($max - 3) % $min}
+} {-4}
+test expr-34.69 {expr edge cases} {
+ expr {-3 / $min}
+} {0}
+test expr-34.70 {expr edge cases} {
+ expr {-3 % $min}
+} {-3}
+test expr-34.71 {expr edge cases} {
+ expr {-2 / $min}
+} {0}
+test expr-34.72 {expr edge cases} {
+ expr {-2 % $min}
+} {-2}
+test expr-34.73 {expr edge cases} {
+ expr {-1 / $min}
+} {0}
+test expr-34.74 {expr edge cases} {
+ expr {-1 % $min}
+} {-1}
+test expr-34.75 {expr edge cases} {
+ expr {0 / $min}
+} {0}
+test expr-34.76 {expr edge cases} {
+ expr {0 % $min}
+} {0}
+test expr-34.77 {expr edge cases} {
+ expr {0 / ($min + 1)}
+} {0}
+test expr-34.78 {expr edge cases} {
+ expr {0 % ($min + 1)}
+} {0}
+test expr-34.79 {expr edge cases} {
+ expr {1 / $min}
+} {-1}
+test expr-34.80 {expr edge cases} {
+ expr {1 % $min}
+} {-2147483647}
+test expr-34.81 {expr edge cases} {
+ expr {1 / ($min + 1)}
+} {-1}
+test expr-34.82 {expr edge cases} {
+ expr {1 % ($min + 1)}
+} {-2147483646}
+test expr-34.83 {expr edge cases} {
+ expr {2 / $min}
+} {-1}
+test expr-34.84 {expr edge cases} {
+ expr {2 % $min}
+} {-2147483646}
+test expr-34.85 {expr edge cases} {
+ expr {2 / ($min + 1)}
+} {-1}
+test expr-34.86 {expr edge cases} {
+ expr {2 % ($min + 1)}
+} {-2147483645}
+test expr-34.87 {expr edge cases} {
+ expr {3 / $min}
+} {-1}
+test expr-34.88 {expr edge cases} {
+ expr {3 % $min}
+} {-2147483645}
+test expr-34.89 {expr edge cases} {
+ expr {3 / ($min + 1)}
+} {-1}
+test expr-34.90 {expr edge cases} {
+ expr {3 % ($min + 1)}
+} {-2147483644}
+
+# Euclidean property:
+# quotient * divisor + remainder = dividend
+
+test expr-35.1 {expr edge cases} {
+ set dividend $max
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($divisor * $q) + $r}]
+} {1073741823 * 2 + 1 = 2147483647}
+test expr-35.2 {expr edge cases} {
+ set dividend [expr {$max - 1}]
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1073741823 * 2 + 0 = 2147483646}
+test expr-35.3 {expr edge cases} {
+ set dividend [expr {$max - 2}]
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1073741822 * 2 + 1 = 2147483645}
+test expr-35.4 {expr edge cases} {
+ set dividend $max
+ set divisor 3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {715827882 * 3 + 1 = 2147483647}
+test expr-35.5 {expr edge cases} {
+ set dividend [expr {$max - 1}]
+ set divisor 3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {715827882 * 3 + 0 = 2147483646}
+test expr-35.6 {expr edge cases} {
+ set dividend [expr {$max - 2}]
+ set divisor 3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {715827881 * 3 + 2 = 2147483645}
+test expr-35.7 {expr edge cases} {
+ set dividend $min
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-1073741824 * 2 + 0 = -2147483648}
+test expr-35.8 {expr edge cases} {
+ set dividend [expr {$min + 1}]
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-1073741824 * 2 + 1 = -2147483647}
+test expr-35.9 {expr edge cases} {
+ set dividend [expr {$min + 2}]
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-1073741823 * 2 + 0 = -2147483646}
+test expr-35.10 {expr edge cases} {
+ # Two things could happen here. The multiplication
+ # could overflow a 32 bit type, so that when
+ # 1 is added it overflows again back to min.
+ # The multiplication could also use a wide type
+ # to hold ($min - 1) until 1 is added and
+ # the number becomes $min again.
+ set dividend $min
+ set divisor 3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-715827883 * 3 + 1 = -2147483648}
+test expr-35.11 {expr edge cases} {
+ set dividend $min
+ set divisor -3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {715827882 * -3 + -2 = -2147483648}
+test expr-35.12 {expr edge cases} {
+ set dividend $min
+ set divisor $min
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -2147483648 + 0 = -2147483648}
+test expr-35.13 {expr edge cases} {
+ set dividend $min
+ set divisor [expr {$min + 1}]
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -2147483647 + -1 = -2147483648}
+test expr-35.14 {expr edge cases} {
+ set dividend $min
+ set divisor [expr {$min + 2}]
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -2147483646 + -2 = -2147483648}
+
+# 64bit wide integer checks
+
+set min -9223372036854775808
+set max 9223372036854775807
+
+test expr-36.1 {expr edge cases} {wideIs64bit} {
+ expr {$min / $min}
+} {1}
+test expr-36.2 {expr edge cases} {wideIs64bit} {
+ expr {$min % $min}
+} {0}
+test expr-36.3 {expr edge cases} {wideIs64bit} {
+ expr {$min / ($min + 1)}
+} {1}
+test expr-36.4 {expr edge cases} {wideIs64bit} {
+ expr {$min % ($min + 1)}
+} {-1}
+test expr-36.5 {expr edge cases} {wideIs64bit} {
+ expr {$min / ($min + 2)}
+} {1}
+test expr-36.6 {expr edge cases} {wideIs64bit} {
+ expr {$min % ($min + 2)}
+} {-2}
+test expr-36.7 {expr edge cases} {wideIs64bit} {
+ expr {$min / ($min + 3)}
+} {1}
+test expr-36.8 {expr edge cases} {wideIs64bit} {
+ expr {$min % ($min + 3)}
+} {-3}
+test expr-36.9 {expr edge cases} {wideIs64bit} {
+ expr {$min / -3}
+} {3074457345618258602}
+test expr-36.10 {expr edge cases} {wideIs64bit} {
+ expr {$min % -3}
+} {-2}
+test expr-36.11 {expr edge cases} {wideIs64bit} {
+ expr {$min / -2}
+} {4611686018427387904}
+test expr-36.12 {expr edge cases} {wideIs64bit} {
+ expr {$min % -2}
+} {0}
+test expr-36.13 {expr edge cases} wideIs64bit {
+ expr {wide($min / -1)}
+} $min
+test expr-36.14 {expr edge cases} {wideIs64bit} {
+ expr {$min % -1}
+} {0}
+test expr-36.15 {expr edge cases} wideIs64bit {
+ expr {wide($min * -1)}
+} $min
+test expr-36.16 {expr edge cases} wideIs64bit {
+ expr {wide(-$min)}
+} $min
+test expr-36.17 {expr edge cases} {wideIs64bit} {
+ expr {$min / 1}
+} $min
+test expr-36.18 {expr edge cases} {wideIs64bit} {
+ expr {$min % 1}
+} {0}
+test expr-36.19 {expr edge cases} {wideIs64bit} {
+ expr {$min / 2}
+} {-4611686018427387904}
+test expr-36.20 {expr edge cases} {wideIs64bit} {
+ expr {$min % 2}
+} {0}
+test expr-36.21 {expr edge cases} {wideIs64bit} {
+ expr {$min / 3}
+} {-3074457345618258603}
+test expr-36.22 {expr edge cases} {wideIs64bit} {
+ expr {$min % 3}
+} {1}
+test expr-36.23 {expr edge cases} {wideIs64bit} {
+ expr {$min / ($max - 3)}
+} {-2}
+test expr-36.24 {expr edge cases} {wideIs64bit} {
+ expr {$min % ($max - 3)}
+} {9223372036854775800}
+test expr-36.25 {expr edge cases} {wideIs64bit} {
+ expr {$min / ($max - 2)}
+} {-2}
+test expr-36.26 {expr edge cases} {wideIs64bit} {
+ expr {$min % ($max - 2)}
+} {9223372036854775802}
+test expr-36.27 {expr edge cases} {wideIs64bit} {
+ expr {$min / ($max - 1)}
+} {-2}
+test expr-36.28 {expr edge cases} {wideIs64bit} {
+ expr {$min % ($max - 1)}
+} {9223372036854775804}
+test expr-36.29 {expr edge cases} {wideIs64bit} {
+ expr {$min / $max}
+} {-2}
+test expr-36.30 {expr edge cases} {wideIs64bit} {
+ expr {$min % $max}
+} {9223372036854775806}
+test expr-36.31 {expr edge cases} {wideIs64bit} {
+ expr {$max / $max}
+} {1}
+test expr-36.32 {expr edge cases} {wideIs64bit} {
+ expr {$max % $max}
+} {0}
+test expr-36.33 {expr edge cases} {wideIs64bit} {
+ expr {$max / ($max - 1)}
+} {1}
+test expr-36.34 {expr edge cases} {wideIs64bit} {
+ expr {$max % ($max - 1)}
+} {1}
+test expr-36.35 {expr edge cases} {wideIs64bit} {
+ expr {$max / ($max - 2)}
+} {1}
+test expr-36.36 {expr edge cases} {wideIs64bit} {
+ expr {$max % ($max - 2)}
+} {2}
+test expr-36.37 {expr edge cases} {wideIs64bit} {
+ expr {$max / ($max - 3)}
+} {1}
+test expr-36.38 {expr edge cases} {wideIs64bit} {
+ expr {$max % ($max - 3)}
+} {3}
+test expr-36.39 {expr edge cases} {wideIs64bit} {
+ expr {$max / 3}
+} {3074457345618258602}
+test expr-36.40 {expr edge cases} {wideIs64bit} {
+ expr {$max % 3}
+} {1}
+test expr-36.41 {expr edge cases} {wideIs64bit} {
+ expr {$max / 2}
+} {4611686018427387903}
+test expr-36.42 {expr edge cases} {wideIs64bit} {
+ expr {$max % 2}
+} {1}
+test expr-36.43 {expr edge cases} {wideIs64bit} {
+ expr {$max / 1}
+} $max
+test expr-36.44 {expr edge cases} {wideIs64bit} {
+ expr {$max % 1}
+} {0}
+test expr-36.45 {expr edge cases} {wideIs64bit} {
+ expr {$max / -1}
+} "-$max"
+test expr-36.46 {expr edge cases} {wideIs64bit} {
+ expr {$max % -1}
+} {0}
+test expr-36.47 {expr edge cases} {wideIs64bit} {
+ expr {$max / -2}
+} {-4611686018427387904}
+test expr-36.48 {expr edge cases} {wideIs64bit} {
+ expr {$max % -2}
+} {-1}
+test expr-36.49 {expr edge cases} {wideIs64bit} {
+ expr {$max / -3}
+} {-3074457345618258603}
+test expr-36.50 {expr edge cases} {wideIs64bit} {
+ expr {$max % -3}
+} {-2}
+test expr-36.51 {expr edge cases} {wideIs64bit} {
+ expr {$max / ($min + 3)}
+} {-2}
+test expr-36.52 {expr edge cases} {wideIs64bit} {
+ expr {$max % ($min + 3)}
+} {-9223372036854775803}
+test expr-36.53 {expr edge cases} {wideIs64bit} {
+ expr {$max / ($min + 2)}
+} {-2}
+test expr-36.54 {expr edge cases} {wideIs64bit} {
+ expr {$max % ($min + 2)}
+} {-9223372036854775805}
+test expr-36.55 {expr edge cases} {wideIs64bit} {
+ expr {$max / ($min + 1)}
+} {-1}
+test expr-36.56 {expr edge cases} {wideIs64bit} {
+ expr {$max % ($min + 1)}
+} {0}
+test expr-36.57 {expr edge cases} {wideIs64bit} {
+ expr {$max / $min}
+} {-1}
+test expr-36.58 {expr edge cases} {wideIs64bit} {
+ expr {$max % $min}
+} {-1}
+test expr-36.59 {expr edge cases} {wideIs64bit} {
+ expr {($min + 1) / ($max - 1)}
+} {-2}
+test expr-36.60 {expr edge cases} {wideIs64bit} {
+ expr {($min + 1) % ($max - 1)}
+} {9223372036854775805}
+test expr-36.61 {expr edge cases} {wideIs64bit} {
+ expr {($max - 1) / ($min + 1)}
+} {-1}
+test expr-36.62 {expr edge cases} {wideIs64bit} {
+ expr {($max - 1) % ($min + 1)}
+} {-1}
+test expr-36.63 {expr edge cases} {wideIs64bit} {
+ expr {($max - 1) / $min}
+} {-1}
+test expr-36.64 {expr edge cases} {wideIs64bit} {
+ expr {($max - 1) % $min}
+} {-2}
+test expr-36.65 {expr edge cases} {wideIs64bit} {
+ expr {($max - 2) / $min}
+} {-1}
+test expr-36.66 {expr edge cases} {wideIs64bit} {
+ expr {($max - 2) % $min}
+} {-3}
+test expr-36.67 {expr edge cases} {wideIs64bit} {
+ expr {($max - 3) / $min}
+} {-1}
+test expr-36.68 {expr edge cases} {wideIs64bit} {
+ expr {($max - 3) % $min}
+} {-4}
+test expr-36.69 {expr edge cases} {wideIs64bit} {
+ expr {-3 / $min}
+} {0}
+test expr-36.70 {expr edge cases} {wideIs64bit} {
+ expr {-3 % $min}
+} {-3}
+test expr-36.71 {expr edge cases} {wideIs64bit} {
+ expr {-2 / $min}
+} {0}
+test expr-36.72 {expr edge cases} {wideIs64bit} {
+ expr {-2 % $min}
+} {-2}
+test expr-36.73 {expr edge cases} {wideIs64bit} {
+ expr {-1 / $min}
+} {0}
+test expr-36.74 {expr edge cases} {wideIs64bit} {
+ expr {-1 % $min}
+} {-1}
+test expr-36.75 {expr edge cases} {wideIs64bit} {
+ expr {0 / $min}
+} {0}
+test expr-36.76 {expr edge cases} {wideIs64bit} {
+ expr {0 % $min}
+} {0}
+test expr-36.77 {expr edge cases} {wideIs64bit} {
+ expr {0 / ($min + 1)}
+} {0}
+test expr-36.78 {expr edge cases} {wideIs64bit} {
+ expr {0 % ($min + 1)}
+} {0}
+test expr-36.79 {expr edge cases} {wideIs64bit} {
+ expr {1 / $min}
+} {-1}
+test expr-36.80 {expr edge cases} {wideIs64bit} {
+ expr {1 % $min}
+} {-9223372036854775807}
+test expr-36.81 {expr edge cases} {wideIs64bit} {
+ expr {1 / ($min + 1)}
+} {-1}
+test expr-36.82 {expr edge cases} {wideIs64bit} {
+ expr {1 % ($min + 1)}
+} {-9223372036854775806}
+test expr-36.83 {expr edge cases} {wideIs64bit} {
+ expr {2 / $min}
+} {-1}
+test expr-36.84 {expr edge cases} {wideIs64bit} {
+ expr {2 % $min}
+} {-9223372036854775806}
+test expr-36.85 {expr edge cases} {wideIs64bit} {
+ expr {2 / ($min + 1)}
+} {-1}
+test expr-36.86 {expr edge cases} {wideIs64bit} {
+ expr {2 % ($min + 1)}
+} {-9223372036854775805}
+test expr-36.87 {expr edge cases} {wideIs64bit} {
+ expr {3 / $min}
+} {-1}
+test expr-36.88 {expr edge cases} {wideIs64bit} {
+ expr {3 % $min}
+} {-9223372036854775805}
+test expr-36.89 {expr edge cases} {wideIs64bit} {
+ expr {3 / ($min + 1)}
+} {-1}
+test expr-36.90 {expr edge cases} {wideIs64bit} {
+ expr {3 % ($min + 1)}
+} {-9223372036854775804}
+
+test expr-37.1 {expr edge cases} {wideIs64bit} {
+ set dividend $max
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($divisor * $q) + $r}]
+} {4611686018427387903 * 2 + 1 = 9223372036854775807}
+test expr-37.2 {expr edge cases} {wideIs64bit} {
+ set dividend [expr {$max - 1}]
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {4611686018427387903 * 2 + 0 = 9223372036854775806}
+test expr-37.3 {expr edge cases} {wideIs64bit} {
+ set dividend [expr {$max - 2}]
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {4611686018427387902 * 2 + 1 = 9223372036854775805}
+test expr-37.4 {expr edge cases} {wideIs64bit} {
+ set dividend $max
+ set divisor 3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {3074457345618258602 * 3 + 1 = 9223372036854775807}
+test expr-37.5 {expr edge cases} {wideIs64bit} {
+ set dividend [expr {$max - 1}]
+ set divisor 3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {3074457345618258602 * 3 + 0 = 9223372036854775806}
+test expr-37.6 {expr edge cases} {wideIs64bit} {
+ set dividend [expr {$max - 2}]
+ set divisor 3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {3074457345618258601 * 3 + 2 = 9223372036854775805}
+test expr-37.7 {expr edge cases} {wideIs64bit} {
+ set dividend $min
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-4611686018427387904 * 2 + 0 = -9223372036854775808}
+test expr-37.8 {expr edge cases} {wideIs64bit} {
+ set dividend [expr {$min + 1}]
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-4611686018427387904 * 2 + 1 = -9223372036854775807}
+test expr-37.9 {expr edge cases} {wideIs64bit} {
+ set dividend [expr {$min + 2}]
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-4611686018427387903 * 2 + 0 = -9223372036854775806}
+test expr-37.10 {expr edge cases} {wideIs64bit} {
+ # Multiplication overflows 64 bit type here,
+ # so when the 1 is added it overflows
+ # again and we end up back at min.
+ set dividend $min
+ set divisor 3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-3074457345618258603 * 3 + 1 = -9223372036854775808}
+test expr-37.11 {expr edge cases} {wideIs64bit} {
+ set dividend $min
+ set divisor -3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {3074457345618258602 * -3 + -2 = -9223372036854775808}
+test expr-37.12 {expr edge cases} {wideIs64bit} {
+ set dividend $min
+ set divisor $min
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -9223372036854775808 + 0 = -9223372036854775808}
+test expr-37.13 {expr edge cases} {wideIs64bit} {
+ set dividend $min
+ set divisor [expr {$min + 1}]
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -9223372036854775807 + -1 = -9223372036854775808}
+test expr-37.14 {expr edge cases} {wideIs64bit} {
+ set dividend $min
+ set divisor [expr {$min + 2}]
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -9223372036854775806 + -2 = -9223372036854775808}
+
+test expr-38.1 {abs of smallest 32-bit integer [Bug 1241572]} {wideIs64bit} {
+ expr {abs(-2147483648)}
+} 2147483648
+test expr-38.2 {abs and -0 [Bug 1893815]} {
+ expr {abs(-0)}
+} 0
+test expr-38.3 {abs and -0 [Bug 1893815]} {
+ expr {abs(-0.0)}
+} 0.0
+test expr-38.4 {abs and -0 [Bug 1893815]} {
+ expr {abs(-1e-324)}
+} 0.0
+test expr-38.5 {abs and -0 [Bug 1893815]} {
+ ::tcl::mathfunc::abs -0
+} 0
+test expr-38.6 {abs and -0 [Bug 1893815]} {
+ ::tcl::mathfunc::abs -0.0
+} 0.0
+test expr-38.7 {abs and -0 [Bug 1893815]} {
+ ::tcl::mathfunc::abs -1e-324
+} 0.0
+test expr-38.8 {abs and 0.0 [Bug 2954959]} {
+ ::tcl::mathfunc::abs 0.0
+} 0.0
+test expr-38.9 {abs and 0.0 [Bug 2954959]} {
+ expr {abs(0.0)}
+} 0.0
+test expr-38.10 {abs and -0x0 [Bug 2954959]} {
+ expr {abs(-0x0)}
+} 0
+test expr-38.11 {abs and 0x0 [Bug 2954959]} {
+ ::tcl::mathfunc::abs { 0x0}
+} { 0x0}
+test expr-38.12 {abs and -0x0 [Bug 2954959]} {
+ ::tcl::mathfunc::abs { -0x0}
+} 0
+test expr-38.13 {abs and 0.0 [Bug 2954959]} {
+ ::tcl::mathfunc::abs 1e-324
+} 1e-324
+
+testConstraint testexprlongobj [llength [info commands testexprlongobj]]
+testConstraint testexprdoubleobj [llength [info commands testexprdoubleobj]]
+
+test expr-39.1 {Check that Tcl_ExprLongObj doesn't modify interpreter result if no error} testexprlongobj {
+ testexprlongobj 4+1
+} {This is a result: 5}
+#Check for [Bug 1109484]
+test expr-39.2 {Tcl_ExprLongObj handles wide ints gracefully} testexprlongobj {
+ testexprlongobj wide(1)+2
+} {This is a result: 3}
+
+test expr-39.3 {Tcl_ExprLongObj on the empty string} \
+ -constraints {testexprlongobj}\
+ -body {testexprlongobj ""} \
+ -match glob \
+ -returnCodes error -result *
+test expr-39.4 {Tcl_ExprLongObj coerces doubles} testexprlongobj {
+ testexprlongobj 3+.14159
+} {This is a result: 3}
+test expr-39.5 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+ testexprlongobj 0x80000000
+} {This is a result: -2147483648}
+test expr-39.6 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+ testexprlongobj 0xffffffff
+} {This is a result: -1}
+test expr-39.7 {Tcl_ExprLongObj handles overflows} \
+ -constraints {testexprlongobj longIs32bit} \
+ -match glob \
+ -body {
+ list [catch {testexprlongobj 0x100000000} result] $result
+ } \
+ -result {1 {integer value too large to represent*}}
+test expr-39.8 {Tcl_ExprLongObj handles overflows} testexprlongobj {
+ testexprlongobj -0x80000000
+} {This is a result: -2147483648}
+test expr-39.9 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+ testexprlongobj -0xffffffff
+} {This is a result: 1}
+test expr-39.10 {Tcl_ExprLongObj handles overflows} \
+ -constraints {testexprlongobj longIs32bit} \
+ -match glob \
+ -body {
+ list [catch {testexprlongobj -0x100000000} result] $result
+ } \
+ -result {1 {integer value too large to represent*}}
+test expr-39.11 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+ testexprlongobj 2147483648.
+} {This is a result: -2147483648}
+test expr-39.12 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+ testexprlongobj 4294967295.
+} {This is a result: -1}
+test expr-39.13 {Tcl_ExprLongObj handles overflows} \
+ -constraints {testexprlongobj longIs32bit} \
+ -match glob \
+ -body {
+ list [catch {testexprlongobj 4294967296.} result] $result
+ } \
+ -result {1 {integer value too large to represent*}}
+test expr-39.14 {Tcl_ExprLongObj handles overflows} testexprlongobj {
+ testexprlongobj -2147483648.
+} {This is a result: -2147483648}
+test expr-39.15 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+ testexprlongobj -4294967295.
+} {This is a result: 1}
+test expr-39.16 {Tcl_ExprLongObj handles overflows} \
+ -constraints {testexprlongobj longIs32bit} \
+ -match glob \
+ -body {
+ list [catch {testexprlongobj 4294967296.} result] $result
+ } \
+ -result {1 {integer value too large to represent*}}
+
+test expr-39.17 {Check that Tcl_ExprDoubleObj doesn't modify interpreter result if no error} testexprdoubleobj {
+ testexprdoubleobj 4.+1.
+} {This is a result: 5.0}
+#Check for [Bug 1109484]
+test expr-39.18 {Tcl_ExprDoubleObj on the empty string} \
+ -constraints {testexprdoubleobj} \
+ -match glob \
+ -body {testexprdoubleobj ""} \
+ -returnCodes error -result *
+test expr-39.19 {Tcl_ExprDoubleObj coerces wides} testexprdoubleobj {
+ testexprdoubleobj 1[string repeat 0 17]
+} {This is a result: 1e+17}
+test expr-39.20 {Tcl_ExprDoubleObj coerces bignums} testexprdoubleobj {
+ testexprdoubleobj 1[string repeat 0 38]
+} {This is a result: 1e+38}
+test expr-39.21 {Tcl_ExprDoubleObj handles overflows} \
+ testexprdoubleobj&&ieeeFloatingPoint {
+ testexprdoubleobj 17976931348623157[string repeat 0 292].
+ } {This is a result: 1.7976931348623157e+308}
+test expr-39.22 {Tcl_ExprDoubleObj handles overflows that look like int} \
+ testexprdoubleobj&&ieeeFloatingPoint {
+ testexprdoubleobj 17976931348623157[string repeat 0 292]
+ } {This is a result: 1.7976931348623157e+308}
+test expr-39.23 {Tcl_ExprDoubleObj handles overflows} \
+ testexprdoubleobj&&ieeeFloatingPoint {
+ testexprdoubleobj 17976931348623165[string repeat 0 292].
+ } {This is a result: Inf}
+test expr-39.24 {Tcl_ExprDoubleObj handles overflows that look like int} \
+ testexprdoubleobj&&ieeeFloatingPoint {
+ testexprdoubleobj 17976931348623165[string repeat 0 292]
+ } {This is a result: Inf}
+test expr-39.25 {Tcl_ExprDoubleObj and NaN} \
+ {testexprdoubleobj ieeeFloatingPoint} {
+ list [catch {testexprdoubleobj 0.0/0.0} result] $result
+ } {1 {domain error: argument not in valid range}}
+
+test expr-40.1 {large octal shift} {
+ expr 0o100000000000000000000000000000000
+} [expr 0x1000000000000000000000000]
+test expr-40.2 {large octal shift} {
+ expr 0o100000000000000000000000000000001
+} [expr 0x1000000000000000000000001]
+
+test expr-41.1 {exponent overflow} {
+ expr 1.0e2147483630
+} Inf
+test expr-41.2 {exponent underflow} {
+ expr 1.0e-2147483630
+} 0.0
+
+test expr-42.1 {denormals} ieeeFloatingPoint {
+ expr 7e-324
+} 5e-324
+
+# TIP 114
+
+test expr-43.1 {0b notation} {
+ expr 0b0
+} 0
+test expr-43.2 {0b notation} {
+ expr 0b1
+} 1
+test expr-43.3 {0b notation} {
+ expr 0b10
+} 2
+test expr-43.4 {0b notation} {
+ expr 0b11
+} 3
+test expr-43.5 {0b notation} {
+ expr 0b100
+} 4
+test expr-43.6 {0b notation} {
+ expr 0b101
+} 5
+test expr-43.7 {0b notation} {
+ expr 0b1000
+} 8
+test expr-43.8 {0b notation} {
+ expr 0b1001
+} 9
+test expr-43.9 {0b notation} {
+ expr 0b1[string repeat 0 31]
+} 2147483648
+test expr-43.10 {0b notation} {
+ expr 0b1[string repeat 0 30]1
+} 2147483649
+test expr-43.11 {0b notation} {
+ expr 0b[string repeat 1 64]
+} 18446744073709551615
+test expr-43.12 {0b notation} {
+ expr 0b1[string repeat 0 64]
+} 18446744073709551616
+test expr-43.13 {0b notation} {
+ expr 0b1[string repeat 0 63]1
+} 18446744073709551617
+
+test expr-44.1 {0o notation} {
+ expr 0o0
+} 0
+test expr-44.2 {0o notation} {
+ expr 0o1
+} 1
+test expr-44.3 {0o notation} {
+ expr 0o7
+} 7
+test expr-44.4 {0o notation} {
+ expr 0o10
+} 8
+test expr-44.5 {0o notation} {
+ expr 0o11
+} 9
+test expr-44.6 {0o notation} {
+ expr 0o100
+} 64
+test expr-44.7 {0o notation} {
+ expr 0o101
+} 65
+test expr-44.8 {0o notation} {
+ expr 0o1000
+} 512
+test expr-44.9 {0o notation} {
+ expr 0o1001
+} 513
+test expr-44.10 {0o notation} {
+ expr 0o1[string repeat 7 21]
+} 18446744073709551615
+test expr-44.11 {0o notation} {
+ expr 0o2[string repeat 0 21]
+} 18446744073709551616
+test expr-44.12 {0o notation} {
+ expr 0o2[string repeat 0 20]1
+} 18446744073709551617
+
+# TIP 237 again
+
+test expr-45.1 {entier} {
+ expr entier(0)
+} 0
+test expr-45.2 {entier} {
+ expr entier(0.5)
+} 0
+test expr-45.3 {entier} {
+ expr entier(1.0)
+} 1
+test expr-45.4 {entier} {
+ expr entier(1.5)
+} 1
+test expr-45.5 {entier} {
+ expr entier(2.0)
+} 2
+test expr-45.6 {entier} {
+ expr entier(1e+22)
+} 10000000000000000000000
+test expr-45.7 {entier} {
+ list [catch {expr entier(Inf)} result] $result
+} {1 {integer value too large to represent}}
+test expr-45.8 {entier} ieeeFloatingPoint {
+ list [catch {expr {entier($ieeeValues(NaN))}} result] $result
+} {1 {floating point value is Not a Number}}
+test expr-45.9 {entier} ieeeFloatingPoint {
+ list [catch {expr {entier($ieeeValues(-NaN))}} result] $result
+} {1 {floating point value is Not a Number}}
+
+test expr-46.1 {round() rounds to +-infinity} {
+ expr round(0.5)
+} 1
+test expr-46.2 {round() rounds to +-infinity} {
+ expr round(1.5)
+} 2
+test expr-46.3 {round() rounds to +-infinity} {
+ expr round(-0.5)
+} -1
+test expr-46.4 {round() rounds to +-infinity} {
+ expr round(-1.5)
+} -2
+test expr-46.5 {round() overflow} {
+ expr round(9.2233720368547758e+018)
+} 9223372036854775808
+test expr-46.6 {round() overflow} {
+ expr round(-9.2233720368547758e+018)
+} -9223372036854775808
+test expr-46.7 {round() bad value} -body {
+ set x trash
+ expr {round($x)}
+} -returnCodes error -match glob -result *
+test expr-46.8 {round() already an integer} {
+ set x 123456789012
+ incr x
+ expr round($x)
+} 123456789013
+test expr-46.9 {round() boundary case - 1/2 - 1 ulp} {
+ set x 0.25
+ set bit 0.125
+ while 1 {
+ set newx [expr {$x + $bit}]
+ if { $newx == $x || $newx == 0.5 } break
+ set x $newx
+ set bit [expr { $bit / 2.0 }]
+ }
+ expr {round($x)}
+} 0
+test expr-46.10 {round() boundary case - 1/2 + 1 ulp} {
+ set x 0.75
+ set bit 0.125
+ while 1 {
+ set newx [expr {$x - $bit}]
+ if { $newx == $x || $newx == 0.5 } break
+ set x $newx
+ set bit [expr { $bit / 2.0 }]
+ }
+ expr {round($x)}
+} 1
+test expr-46.11 {round() boundary case - -1/2 - 1 ulp} {
+ set x -0.75
+ set bit 0.125
+ while 1 {
+ set newx [expr {$x + $bit}]
+ if { $newx == $x || $newx == -0.5 } break
+ set x $newx
+ set bit [expr { $bit / 2.0 }]
+ }
+ expr {round($x)}
+} -1
+test expr-46.12 {round() boundary case - -1/2 + 1 ulp} {
+ set x -0.25
+ set bit 0.125
+ while 1 {
+ set newx [expr {$x - $bit}]
+ if { $newx == $x || $newx == -0.5 } break
+ set x $newx
+ set bit [expr { $bit / 2.0 }]
+ }
+ expr {round($x)}
+} 0
+test expr-46.13 {round() boundary case - round down} {
+ expr {round(2147483647 - 0.51)}
+} 2147483646
+
+test expr-46.14 {round() boundary case - round up} {
+ expr {round(2147483647 - 0.50)}
+} 2147483647
+
+test expr-46.15 {round() boundary case - round up to wide} {
+ expr {round(2147483647 + 0.50)}
+} [expr {wide(2147483647) + 1}]
+
+test expr-46.16 {round() boundary case - round up} {
+ expr {round(-2147483648 + 0.51)}
+} -2147483647
+
+test expr-46.17 {round() boundary case - round down} {
+ expr {round(-2147483648 + 0.50)}
+} -2147483648
+test expr-46.18 {round() boundary case - round down to wide} {
+ expr {round(-2147483648 - 0.50)}
+} [expr {wide(-2147483648) - 1}]
+
+test expr-46.19 {round() handling of long/bignum boundary} {
+ expr {round(double(0x7fffffffffffffff))}
+} 9223372036854775808
+
+test expr-47.1 {isqrt() - arg count} {
+ list [catch {expr {isqrt(1,2)}} result] $result
+} {1 {too many arguments for math function "isqrt"}}
+
+test expr-47.2 {isqrt() - non-number} {
+ list [catch {expr {isqrt({rubbish})}} result] $result
+} {1 {expected number but got "rubbish"}}
+
+test expr-47.3 {isqrt() - NaN} ieeeFloatingPoint {
+ list [catch {expr {isqrt(NaN)}} result] $result
+} {1 {floating point value is Not a Number}}
+
+test expr-47.4 {isqrt() of negative floating point number} {
+ list [catch {expr {isqrt(-1.0)}} result] $result
+} {1 {square root of negative argument}}
+
+test expr-47.5 {isqrt() of floating point zero} {
+ expr isqrt(0.0)
+} 0
+
+test expr-47.6 {isqrt() of exact floating point numbers} {
+ set trouble {}
+ for {set i 0} {$i < 16} {incr i} {
+ set root [expr {1 << $i}]
+ set rm1 [expr {$root - 1}]
+ set arg [expr {pow(2., (2 * $i))}]
+ if {isqrt($arg-1) != $rm1} {
+ append trouble "i = " $i ": isqrt( " $arg "-1) != " $rm1 "\n"
+ }
+ if {isqrt($arg) != $root} {
+ append trouble "i = " $i ": isqrt( " $arg ") != " $root "\n"
+ }
+ if {isqrt($arg+1) != $root} {
+ append trouble "i = " $i ": isqrt( " $arg "+1) != " $root "\n"
+ }
+ }
+ set trouble
+} {}
+
+test expr-47.7 {isqrt() of exact floating point numbers} ieeeFloatingPoint {
+ set trouble {}
+ for {set i 17} {$i < 27} {incr i} {
+ set root [expr {1 << $i}]
+ set rm1 [expr {$root - 1}]
+ set arg [expr {pow(2., (2 * $i))}]
+ if {isqrt($arg-1.0) != $rm1} {
+ append trouble "i = " $i ": isqrt( " $arg "-1) != " $rm1 "\n"
+ }
+ if {isqrt($arg) != $root} {
+ append trouble "i = " $i ": isqrt( " $arg ") != " $root "\n"
+ }
+ if {isqrt($arg+1.0) != $root} {
+ append trouble "i = " $i ": isqrt( " $arg "+1) != " $root "\n"
+ }
+ }
+ set trouble
+} {}
+
+test expr-47.8 {isqrt of inexact floating point number} ieeeFloatingPoint {
+ expr isqrt(2[string repeat 0 34])
+} 141421356237309504
+
+test expr-47.9 {isqrt of negative int} {
+ list [catch {expr isqrt(-1)} result] $result
+} {1 {square root of negative argument}}
+
+test expr-47.10 {isqrt of negative bignum} {
+ list [catch {expr isqrt(-1[string repeat 0 1000])} result] $result
+} {1 {square root of negative argument}}
+
+test expr-47.11 {isqrt of zero} {
+ expr {isqrt(0)}
+} 0
+
+test expr-47.12 {isqrt of various sizes of integer} {
+ set faults 0
+ set trouble {}
+ for {set i 0} {$faults < 10 && $i <= 1024} {incr i} {
+ set root [expr {1 << $i}]
+ set rm1 [expr {$root - 1}]
+ set arg [expr {1 << (2 * $i)}]
+ set tval [expr {isqrt($arg-1)}]
+ if {$tval != $rm1} {
+ append trouble "i = " $i ": isqrt(" $arg "-1) == " $tval \
+ " != " $rm1 "\n"
+ incr faults
+ }
+ set tval [expr {isqrt($arg)}]
+ if {$tval != $root} {
+ append trouble "i = " $i ": isqrt(" $arg ") == " $tval \
+ " != " $root "\n"
+ incr faults
+ }
+ set tval [expr {isqrt($arg+1)}]
+ if {$tval != $root} {
+ append trouble "i = " $i ": isqrt(" $arg "+1) == " $tval \
+ " != " $root "\n"
+ incr faults
+ }
+ }
+ set trouble
+} {}
+
+test expr-47.13 {isqrt and floating point rounding (Bug 2143288)} {
+ set trouble {}
+ set faults 0
+ for {set i 0} {$i < 29 && $faults < 10} {incr i} {
+ for {set j 0} {$j <= $i} {incr j} {
+ set k [expr {isqrt((1<<56)+(1<<$i)+(1<<$j))}]
+ if {$k != (1<<28)} {
+ append trouble "i = $i, j = $j, k = $k\n"
+ incr faults
+ }
+ }
+ set k [expr {isqrt((1<<56)+(1<<29)+(1<<$i))}]
+ if {$k != (1<<28)+1} {
+ append trouble "i = $i, k = $k\n"
+ incr faults
+ }
+ }
+ set trouble
+} {}
+
+test expr-48.1 {Bug 1770224} {
+ expr {-0x8000000000000001 >> 0x8000000000000000}
+} -1
+
+test expr-49.1 {Bug 2823282} {
+ coroutine foo apply {{} {set expr expr; $expr {[yield]}}}
+ foo 1
+} 1
+
+test expr-50.1 {test sqrt() of bignums with non-Inf answer} {
+ expr {sqrt("1[string repeat 0 616]") == 1e308}
+} 1
+
+
+
+# cleanup
+if {[info exists a]} {
+ unset a
+}
+catch {unset min}
+catch {unset max}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/fCmd.test b/library/msgcat/tests/fCmd.test
new file mode 100644
index 0000000..72b7da9
--- /dev/null
+++ b/library/msgcat/tests/fCmd.test
@@ -0,0 +1,2601 @@
+# This file tests the tclFCmd.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1996-1997 Sun Microsystems, Inc.
+# Copyright (c) 1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+cd [temporaryDirectory]
+
+testConstraint testsetplatform [llength [info commands testsetplatform]]
+testConstraint testchmod [llength [info commands testchmod]]
+testConstraint winVista 0
+testConstraint win2000orXP 0
+# Don't know how to determine this constraint correctly
+testConstraint notNetworkFilesystem 0
+testConstraint reg 0
+if {[testConstraint win]} {
+ catch {
+ # Is the registry extension already static to this shell?
+ try {
+ load {} Registry
+ set ::reglib {}
+ } on error {} {
+ # try the location given to use on the commandline to tcltest
+ ::tcltest::loadTestedCommands
+ load $::reglib Registry
+ }
+ testConstraint reg 1
+ }
+}
+
+set tmpspace /tmp;# default value
+# Find a group that exists on this Unix system, or else skip tests that
+# require Unix groups.
+testConstraint foundGroup [expr {![testConstraint unix]}]
+if {[testConstraint unix]} {
+ catch {
+ set groupList [exec groups]
+ set group [lindex $groupList 0]
+ testConstraint foundGroup 1
+ }
+
+ proc dev dir {
+ file stat $dir stat
+ return $stat(dev)
+ }
+
+ if {[catch {makeDirectory tcl[pid] /tmp} tmpspace] == 0} {
+ testConstraint xdev [expr {([dev .] != [dev $tmpspace])}]
+ }
+}
+
+# Also used in winFCmd...
+if {[testConstraint win]} {
+ set major [string index $tcl_platform(osVersion) 0]
+ if {[testConstraint nt] && $major > 4} {
+ if {$major > 5} {
+ testConstraint winVista 1
+ } elseif {$major == 5} {
+ testConstraint win2000orXP 1
+ }
+ }
+}
+
+testConstraint darwin9 [expr {
+ [testConstraint unix]
+ && $tcl_platform(os) eq "Darwin"
+ && [package vsatisfies 1.$tcl_platform(osVersion) 1.9]
+}]
+testConstraint notDarwin9 [expr {![testConstraint darwin9]}]
+
+testConstraint fileSharing 0
+testConstraint notFileSharing 1
+testConstraint linkFile 1
+testConstraint linkDirectory 1
+
+# Several tests require need to match results against the unix username
+set user {}
+if {[testConstraint unix]} {
+ catch {
+ set user [exec whoami]
+ }
+ if {$user eq ""} {
+ catch {
+ regexp {^[^(]*\(([^)]*)\)} [exec id] -> user
+ }
+ }
+ if {$user eq ""} {
+ set user "root"
+ }
+}
+
+proc createfile {file {string a}} {
+ set f [open $file w]
+ puts -nonewline $f $string
+ close $f
+ return $string
+}
+
+#
+# checkcontent --
+#
+# Ensures that file "file" contains only the string "matchString" returns 0
+# if the file does not exist, or has a different content
+#
+proc checkcontent {file matchString} {
+ try {
+ set f [open $file]
+ set fileString [read $f]
+ close $f
+ } on error {} {
+ return 0
+ }
+ return [string match $matchString $fileString]
+}
+
+proc openup {path} {
+ testchmod 777 $path
+ if {[file isdirectory $path]} {
+ catch {
+ foreach p [glob -directory $path *] {
+ openup $p
+ }
+ }
+ }
+}
+
+proc cleanup {args} {
+ set wd [list .]
+ foreach p [concat $wd $args] {
+ set x ""
+ catch {
+ set x [glob -directory $p tf* td*]
+ }
+ foreach file $x {
+ if {
+ [catch {file delete -force -- $file}]
+ && [testConstraint testchmod]
+ } then {
+ catch {openup $file}
+ catch {file delete -force -- $file}
+ }
+ }
+ }
+}
+
+proc contents {file} {
+ set f [open $file]
+ set r [read $f]
+ close $f
+ return $r
+}
+
+
+set root [lindex [file split [pwd]] 0]
+
+# A really long file name.
+# Length of long is 1216 chars, which should be greater than any static buffer
+# or allowable filename.
+
+set long "abcdefghihjllmnopqrstuvwxyz01234567890"
+append long $long
+append long $long
+append long $long
+append long $long
+append long $long
+
+test fCmd-1.1 {TclFileRenameCmd} -constraints {notRoot} -setup {
+ cleanup
+} -body {
+ createfile tf1
+ file rename tf1 tf2
+ glob tf*
+} -result {tf2}
+
+test fCmd-2.1 {TclFileCopyCmd} -constraints {notRoot} -setup {
+ cleanup
+} -body {
+ createfile tf1
+ file copy tf1 tf2
+ lsort [glob tf*]
+} -result {tf1 tf2}
+
+test fCmd-3.1 {FileCopyRename: FileForceOption fails} -constraints {notRoot} -body {
+ file rename -xyz
+} -returnCodes error -result {bad option "-xyz": must be -force or --}
+test fCmd-3.2 {FileCopyRename: not enough args} -constraints {notRoot} -body {
+ file rename xyz
+} -returnCodes error -result {wrong # args: should be "file rename ?-option value ...? source ?source ...? target"}
+test fCmd-3.3 {FileCopyRename: Tcl_TranslateFileName fails} -constraints {notRoot} -body {
+ file rename xyz ~_totally_bogus_user
+} -returnCodes error -result {user "_totally_bogus_user" doesn't exist}
+test fCmd-3.4 {FileCopyRename: Tcl_TranslateFileName passes} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file copy tf1 ~
+} -result {error copying "tf1": no such file or directory}
+test fCmd-3.5 {FileCopyRename: target doesn't exist: stat(target) != 0} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file rename tf1 tf2 tf3
+} -result {error renaming: target "tf3" is not a directory}
+test fCmd-3.6 {FileCopyRename: target tf3 is not a dir: !S_ISDIR(target)} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ createfile tf3
+ file rename tf1 tf2 tf3
+} -result {error renaming: target "tf3" is not a directory}
+test fCmd-3.7 {FileCopyRename: target exists & is directory} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir td1
+ createfile tf1 tf1
+ file rename tf1 td1
+ contents [file join td1 tf1]
+} -result {tf1}
+test fCmd-3.8 {FileCopyRename: too many arguments: argc - i > 2} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file rename tf1 tf2 tf3
+} -result {error renaming: target "tf3" is not a directory}
+test fCmd-3.9 {FileCopyRename: too many arguments: argc - i > 2} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file copy -force -- tf1 tf2 tf3
+} -result {error copying: target "tf3" is not a directory}
+test fCmd-3.10 {FileCopyRename: just 2 arguments} -constraints notRoot -setup {
+ cleanup
+} -body {
+ createfile tf1 tf1
+ file rename tf1 tf2
+ contents tf2
+} -result {tf1}
+test fCmd-3.11 {FileCopyRename: just 2 arguments} -constraints notRoot -setup {
+ cleanup
+} -body {
+ createfile tf1 tf1
+ file rename -force -force -- tf1 tf2
+ contents tf2
+} -result {tf1}
+test fCmd-3.12 {FileCopyRename: move each source: 1 source} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ createfile tf1 tf1
+ file mkdir td1
+ file rename tf1 td1
+ contents [file join td1 tf1]
+} -result {tf1}
+test fCmd-3.13 {FileCopyRename: move each source: multiple sources} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ createfile tf1 tf1
+ createfile tf2 tf2
+ createfile tf3 tf3
+ createfile tf4 tf4
+ file mkdir td1
+ file rename tf1 tf2 tf3 tf4 td1
+ list [contents [file join td1 tf1]] [contents [file join td1 tf2]] \
+ [contents [file join td1 tf3]] [contents [file join td1 tf4]]
+} -result {tf1 tf2 tf3 tf4}
+test fCmd-3.14 {FileCopyRename: FileBasename fails} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir td1
+ file rename ~_totally_bogus_user td1
+} -result {user "_totally_bogus_user" doesn't exist}
+test fCmd-3.15 {FileCopyRename: source[0] == '\0'} -setup {
+ cleanup
+} -constraints {notRoot unixOrPc} -returnCodes error -body {
+ file mkdir td1
+ file rename / td1
+} -result {error renaming "/" to "td1": file already exists}
+test fCmd-3.16 {FileCopyRename: break on first error} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ createfile tf1
+ createfile tf2
+ createfile tf3
+ createfile tf4
+ file mkdir td1
+ createfile [file join td1 tf3]
+ file rename tf1 tf2 tf3 tf4 td1
+} -result [subst {error renaming "tf3" to "[file join td1 tf3]": file already exists}]
+
+test fCmd-4.1 {TclFileMakeDirsCmd: make each dir: 1 dir} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir td1
+ glob td*
+} -result {td1}
+test fCmd-4.2 {TclFileMakeDirsCmd: make each dir: multiple dirs} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir td1 td2 td3
+ lsort [glob td*]
+} -result {td1 td2 td3}
+test fCmd-4.3 {TclFileMakeDirsCmd: stops on first error} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ createfile tf1
+ catch {file mkdir td1 td2 tf1 td3 td4}
+ glob td1 td2 tf1 td3 td4
+} -result {td1 td2 tf1}
+test fCmd-4.4 {TclFileMakeDirsCmd: Tcl_TranslateFileName fails} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir ~_totally_bogus_user
+} -result {user "_totally_bogus_user" doesn't exist}
+test fCmd-4.5 {TclFileMakeDirsCmd: Tcl_SplitPath returns 0: *name == '\0'} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir ""
+} -result {can't create directory "": no such file or directory}
+test fCmd-4.6 {TclFileMakeDirsCmd: one level deep} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir td1
+ glob td1
+} -result {td1}
+test fCmd-4.7 {TclFileMakeDirsCmd: multi levels deep} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir [file join td1 td2 td3 td4]
+ glob td1 [file join td1 td2]
+} -result "td1 [file join td1 td2]"
+test fCmd-4.8 {TclFileMakeDirsCmd: already exist: lstat(target) == 0} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir td1
+ set x [file exists td1]
+ file mkdir td1
+ list $x [file exists td1]
+} -result {1 1}
+test fCmd-4.9 {TclFileMakeDirsCmd: exists, not dir} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ createfile tf1
+ file mkdir tf1
+} -result [subst {can't create directory "[file join tf1]": file already exists}]
+test fCmd-4.10 {TclFileMakeDirsCmd: exists, is dir} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir td1
+ set x [file exists td1]
+ file mkdir td1
+ list $x [file exists td1]
+} -result {1 1}
+test fCmd-4.11 {TclFileMakeDirsCmd: doesn't exist: errno != ENOENT} -setup {
+ cleanup
+} -constraints {unix notRoot testchmod} -returnCodes error -body {
+ file mkdir td1/td2/td3
+ testchmod 000 td1/td2
+ file mkdir td1/td2/td3/td4
+} -cleanup {
+ testchmod 755 td1/td2
+ cleanup
+} -result {can't create directory "td1/td2/td3": permission denied}
+test fCmd-4.13 {TclFileMakeDirsCmd: doesn't exist: errno == ENOENT} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ set x [file exists td1]
+ file mkdir td1
+ list $x [file exists td1]
+} -result {0 1}
+test fCmd-4.14 {TclFileMakeDirsCmd: TclpCreateDirectory fails} -setup {
+ cleanup
+ file delete -force foo
+} -constraints {unix notRoot} -body {
+ file mkdir foo
+ file attr foo -perm 040000
+ file mkdir foo/tf1
+} -returnCodes error -cleanup {
+ file delete -force foo
+} -result {can't create directory "foo/tf1": permission denied}
+test fCmd-4.16 {TclFileMakeDirsCmd: TclpCreateDirectory succeeds} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir tf1
+ file exists tf1
+} -result {1}
+
+test fCmd-5.1 {TclFileDeleteCmd: FileForceOption fails} -constraints {notRoot} -body {
+ file delete -xyz
+} -returnCodes error -result {bad option "-xyz": must be -force or --}
+test fCmd-5.2 {TclFileDeleteCmd: accept 0 files (TIP 323)} -body {
+ file delete -force -force
+} -result {}
+test fCmd-5.3 {TclFileDeleteCmd: 1 file} -constraints {notRoot} -setup {
+ cleanup
+} -body {
+ createfile tf1
+ createfile tf2
+ file mkdir td1
+ file delete tf2
+ glob tf* td*
+} -result {tf1 td1}
+test fCmd-5.4 {TclFileDeleteCmd: multiple files} -constraints notRoot -setup {
+ cleanup
+} -body {
+ createfile tf1
+ createfile tf2
+ file mkdir td1
+ set x [list [file exists tf1] [file exists tf2] [file exists td1]]
+ file delete tf1 td1 tf2
+ lappend x [file exists tf1] [file exists tf2] [file exists tf3]
+} -cleanup {cleanup} -result {1 1 1 0 0 0}
+test fCmd-5.5 {TclFileDeleteCmd: stop at first error} -setup {
+ cleanup
+} -constraints {notRoot unixOrPc} -body {
+ createfile tf1
+ createfile tf2
+ file mkdir td1
+ catch {file delete tf1 td1 $root tf2}
+ list [file exists tf1] [file exists tf2] [file exists td1]
+} -cleanup {cleanup} -result {0 1 0}
+test fCmd-5.6 {TclFileDeleteCmd: Tcl_TranslateFileName fails} -constraints {notRoot} -body {
+ file delete ~_totally_bogus_user
+} -returnCodes error -result {user "_totally_bogus_user" doesn't exist}
+test fCmd-5.7 {TclFileDeleteCmd: Tcl_TranslateFileName succeeds} -setup {
+ catch {file delete ~/tf1}
+} -constraints {notRoot} -body {
+ createfile ~/tf1
+ file delete ~/tf1
+} -result {}
+test fCmd-5.8 {TclFileDeleteCmd: file doesn't exist: lstat(name) != 0} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ set x [file exists tf1]
+ file delete tf1
+ list $x [file exists tf1]
+} -result {0 0}
+test fCmd-5.9 {TclFileDeleteCmd: is directory} -constraints {notRoot} -setup {
+ cleanup
+} -body {
+ file mkdir td1
+ file delete td1
+ file exists td1
+} -result {0}
+test fCmd-5.10 {TclFileDeleteCmd: TclpRemoveDirectory fails} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir [file join td1 td2]
+ file delete td1
+} -result {error deleting "td1": directory not empty}
+test fCmd-5.11 {TclFileDeleteCmd: TclpRemoveDirectory with cwd inside} -setup {
+ cleanup
+ set dir [pwd]
+} -constraints {notRoot} -body {
+ file mkdir [file join td1 td2]
+ cd [file join td1 td2]
+ set res [list [catch {file delete -force [file dirname [pwd]]} msg]]
+ cd $dir
+ lappend res [file exists td1] $msg
+} -cleanup {
+ cd $dir
+} -result {0 0 {}}
+test fCmd-5.12 {TclFileDeleteCmd: TclpRemoveDirectory with bad perms} -setup {
+ cleanup
+} -constraints {unix} -body {
+ file mkdir [file join td1 td2]
+ file attributes [file join td1 td2] -permissions u+rwx
+ set res [list [catch {file delete -force td1} msg]]
+ lappend res [file exists td1] $msg
+} -result {0 0 {}}
+
+test fCmd-6.1 {CopyRenameOneFile: bad source} {notRoot emptyTest} {
+ # can't test this, because it's caught by FileCopyRename
+} {}
+test fCmd-6.2 {CopyRenameOneFile: bad target} {notRoot emptyTest} {
+ # can't test this, because it's caught by FileCopyRename
+} {}
+test fCmd-6.3 {CopyRenameOneFile: lstat(source) != 0} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file rename tf1 tf2
+} -result {error renaming "tf1": no such file or directory}
+test fCmd-6.4 {CopyRenameOneFile: lstat(source) == 0} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ createfile tf1
+ file rename tf1 tf2
+ glob tf*
+} -result {tf2}
+test fCmd-6.5 {CopyRenameOneFile: lstat(target) != 0} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ createfile tf1
+ file rename tf1 tf2
+ glob tf*
+} -result {tf2}
+test fCmd-6.6 {CopyRenameOneFile: errno != ENOENT} -setup {
+ cleanup
+} -constraints {unix notRoot testchmod} -body {
+ file mkdir td1
+ testchmod 000 td1
+ createfile tf1
+ file rename tf1 td1
+} -returnCodes error -cleanup {
+ testchmod 755 td1
+} -result {error renaming "tf1" to "td1/tf1": permission denied}
+test fCmd-6.7 {CopyRenameOneFile: errno != ENOENT} -setup {
+ cleanup
+} -constraints {win 95} -returnCodes error -body {
+ createfile tf1
+ file rename tf1 $long
+} -result [subst {error renaming "tf1" to "$long": file name too long}]
+test fCmd-6.9 {CopyRenameOneFile: errno == ENOENT} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ createfile tf1
+ file rename tf1 tf2
+ glob tf*
+} -result {tf2}
+test fCmd-6.10 {CopyRenameOneFile: lstat(target) == 0} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ createfile tf1
+ createfile tf2
+ file rename tf1 tf2
+} -result {error renaming "tf1" to "tf2": file already exists}
+test fCmd-6.11 {CopyRenameOneFile: force == 0} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ createfile tf1
+ createfile tf2
+ file rename tf1 tf2
+} -result {error renaming "tf1" to "tf2": file already exists}
+test fCmd-6.12 {CopyRenameOneFile: force != 0} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ createfile tf1
+ createfile tf2
+ file rename -force tf1 tf2
+ glob tf*
+} -result {tf2}
+test fCmd-6.13 {CopyRenameOneFile: source is dir, target is file} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir td1
+ file mkdir td2
+ createfile [file join td2 td1]
+ file rename -force td1 td2
+} -result [subst {can't overwrite file "[file join td2 td1]" with directory "td1"}]
+test fCmd-6.14 {CopyRenameOneFile: source is file, target is dir} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ createfile tf1
+ file mkdir [file join td1 tf1]
+ file rename -force tf1 td1
+} -result [subst {can't overwrite directory "[file join td1 tf1]" with file "tf1"}]
+test fCmd-6.15 {CopyRenameOneFile: TclpRenameFile succeeds} -setup {
+ cleanup
+} -constraints {notRoot notNetworkFilesystem} -body {
+ file mkdir [file join td1 td2]
+ file mkdir td2
+ createfile [file join td2 tf1]
+ file rename -force td2 td1
+ file exists [file join td1 td2 tf1]
+} -result 1
+test fCmd-6.16 {CopyRenameOneFile: TclpCopyRenameOneFile fails} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir [file join td1 td2]
+ createfile [file join td1 td2 tf1]
+ file mkdir td2
+ file rename -force td2 td1
+} -returnCodes error -match glob -result \
+ [subst {error renaming "td2" to "[file join td1 td2]": file *}]
+test fCmd-6.17 {CopyRenameOneFile: errno == EINVAL} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file rename -force $root tf1
+} -result [subst {error renaming "$root" to "tf1": trying to rename a volume or move a directory into itself}]
+test fCmd-6.18 {CopyRenameOneFile: errno != EXDEV} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir [file join td1 td2]
+ createfile [file join td1 td2 tf1]
+ file mkdir td2
+ file rename -force td2 td1
+} -returnCodes error -match glob -result \
+ [subst {error renaming "td2" to "[file join td1 td2]": file *}]
+test fCmd-6.19 {CopyRenameOneFile: errno == EXDEV} -setup {
+ cleanup $tmpspace
+} -constraints {unix notRoot} -body {
+ createfile tf1
+ file rename tf1 $tmpspace
+ glob -nocomplain tf* [file join $tmpspace tf1]
+} -result [file join $tmpspace tf1]
+test fCmd-6.20 {CopyRenameOneFile: errno == EXDEV} -constraints {win} -setup {
+ catch {file delete -force c:/tcl8975@ d:/tcl8975@}
+} -body {
+ file mkdir c:/tcl8975@
+ if {[catch {file rename c:/tcl8975@ d:/}]} {
+ return d:/tcl8975@
+ }
+ glob c:/tcl8975@ d:/tcl8975@
+} -cleanup {
+ file delete -force c:/tcl8975@
+ catch {file delete -force d:/tcl8975@}
+} -result {d:/tcl8975@}
+test fCmd-6.21 {CopyRenameOneFile: copy/rename: S_ISDIR(source)} -setup {
+ cleanup $tmpspace
+} -constraints {unix notRoot} -body {
+ file mkdir td1
+ file rename td1 $tmpspace
+ glob -nocomplain td* [file join $tmpspace td*]
+} -result [file join $tmpspace td1]
+test fCmd-6.22 {CopyRenameOneFile: copy/rename: !S_ISDIR(source)} -setup {
+ cleanup $tmpspace
+} -constraints {unix notRoot} -body {
+ createfile tf1
+ file rename tf1 $tmpspace
+ glob -nocomplain tf* [file join $tmpspace tf*]
+} -result [file join $tmpspace tf1]
+test fCmd-6.23 {CopyRenameOneFile: TclpCopyDirectory failed} -setup {
+ cleanup $tmpspace
+} -constraints {xdev notRoot} -body {
+ file mkdir td1/td2/td3
+ file attributes td1 -permissions 0000
+ file rename td1 $tmpspace
+} -returnCodes error -cleanup {
+ file attributes td1 -permissions 0755
+ cleanup
+} -match regexp -result {^error renaming "td1"( to "/tmp/tcl\d+/td1")?: permission denied$}
+test fCmd-6.24 {CopyRenameOneFile: error uses original name} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir ~/td1/td2
+ set td1name [file join [file dirname ~] [file tail ~] td1]
+ file attributes $td1name -permissions 0000
+ file copy ~/td1 td1
+} -returnCodes error -cleanup {
+ file attributes $td1name -permissions 0755
+ file delete -force ~/td1
+} -result {error copying "~/td1": permission denied}
+test fCmd-6.25 {CopyRenameOneFile: error uses original name} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir td2
+ file mkdir ~/td1
+ set td1name [file join [file dirname ~] [file tail ~] td1]
+ file attributes $td1name -permissions 0000
+ file copy td2 ~/td1
+} -returnCodes error -cleanup {
+ file attributes $td1name -permissions 0755
+ file delete -force ~/td1
+} -result {error copying "td2" to "~/td1/td2": permission denied}
+test fCmd-6.26 {CopyRenameOneFile: doesn't use original name} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir ~/td1/td2
+ set td2name [file join [file dirname ~] [file tail ~] td1 td2]
+ file attributes $td2name -permissions 0000
+ file copy ~/td1 td1
+} -returnCodes error -cleanup {
+ file attributes $td2name -permissions 0755
+ file delete -force ~/td1
+} -result "error copying \"~/td1\" to \"td1\": \"[file join $::env(HOME) td1 td2]\": permission denied"
+test fCmd-6.27 {CopyRenameOneFile: TclpCopyDirectory failed} -setup {
+ cleanup $tmpspace
+} -constraints {notRoot xdev} -returnCodes error -body {
+ file mkdir td1/td2/td3
+ file mkdir [file join $tmpspace td1]
+ createfile [file join $tmpspace td1 tf1]
+ file rename -force td1 $tmpspace
+} -match glob -result {error renaming "td1" to "/tmp/tcl*/td1": file already exists}
+test fCmd-6.28 {CopyRenameOneFile: TclpCopyDirectory failed} -setup {
+ cleanup $tmpspace
+} -constraints {notRoot xdev} -body {
+ file mkdir td1/td2/td3
+ file attributes td1/td2/td3 -permissions 0000
+ file rename td1 $tmpspace
+} -returnCodes error -cleanup {
+ file attributes td1/td2/td3 -permissions 0755
+ cleanup $tmpspace
+} -match glob -result {error renaming "td1" to "/tmp/tcl*/td1": "td1/td2/td3": permission denied}
+test fCmd-6.29 {CopyRenameOneFile: TclpCopyDirectory passed} -setup {
+ cleanup $tmpspace
+} -constraints {notRoot xdev} -body {
+ file mkdir td1/td2/td3
+ file rename td1 $tmpspace
+ glob td* [file join $tmpspace td1 t*]
+} -result [file join $tmpspace td1 td2]
+test fCmd-6.30 {CopyRenameOneFile: TclpRemoveDirectory failed} -setup {
+ cleanup $tmpspace
+} -constraints {unix notRoot} -body {
+ file mkdir foo/bar
+ file attr foo -perm 040555
+ file rename foo/bar $tmpspace
+} -returnCodes error -cleanup {
+ catch {file delete [file join $tmpspace bar]}
+ catch {file attr foo -perm 040777}
+ catch {file delete -force foo}
+} -match glob -result {*: permission denied}
+test fCmd-6.31 {CopyRenameOneFile: TclpDeleteFile passed} -setup {
+ cleanup $tmpspace
+} -constraints {notRoot xdev} -body {
+ file mkdir [file join $tmpspace td1]
+ createfile [file join $tmpspace td1 tf1]
+ file rename [file join $tmpspace td1 tf1] tf1
+ list [file exists [file join $tmpspace td1 tf1]] [file exists tf1]
+} -result {0 1}
+test fCmd-6.32 {CopyRenameOneFile: copy} -constraints {notRoot} -setup {
+ cleanup
+} -returnCodes error -body {
+ file copy tf1 tf2
+} -result {error copying "tf1": no such file or directory}
+
+test fCmd-7.1 {FileForceOption: none} -constraints {notRoot} -setup {
+ cleanup
+} -returnCodes error -body {
+ file mkdir [file join tf1 tf2]
+ file delete tf1
+} -result {error deleting "tf1": directory not empty}
+test fCmd-7.2 {FileForceOption: -force} -constraints {notRoot} -setup {
+ cleanup
+} -body {
+ file mkdir [file join tf1 tf2]
+ file delete -force tf1
+} -result {}
+test fCmd-7.3 {FileForceOption: --} -constraints {notRoot} -body {
+ createfile -tf1
+ file delete -- -tf1
+} -result {}
+test fCmd-7.4 {FileForceOption: bad option} -constraints {notRoot} -setup {
+ createfile -tf1
+} -body {
+ file delete -tf1
+} -returnCodes error -cleanup {
+ file delete -- -tf1
+} -result {bad option "-tf1": must be -force or --}
+test fCmd-7.5 {FileForceOption: multiple times through loop} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ createfile --
+ createfile -force
+ file delete -force -force -- -- -force
+ glob -- -- -force
+} -result {no files matched glob patterns "-- -force"}
+
+test fCmd-8.1 {FileBasename: basename of ~user: argc == 1 && *path == ~} \
+ -constraints {unix notRoot knownBug} -body {
+ # Labelled knownBug because it is dangerous [Bug: 3881]
+ file mkdir td1
+ file attr td1 -perm 040000
+ file rename ~$user td1
+} -returnCodes error -cleanup {
+ file delete -force td1
+} -result "error renaming \"~$user\" to \"td1/[file tail ~$user]\": permission denied"
+test fCmd-8.2 {FileBasename: basename of ~user: argc == 1 && *path == ~} \
+ -constraints {unix notRoot} -body {
+ string equal [file tail ~$user] ~$user
+} -result 0
+test fCmd-8.3 {file copy and path translation: ensure correct error} -body {
+ file copy ~ [file join this file doesnt exist]
+} -returnCodes error -result [subst \
+ {error copying "~" to "[file join this file doesnt exist]": no such file or directory}]
+
+test fCmd-9.1 {file rename: comprehensive: EACCES} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir td1
+ file mkdir td2
+ file attr td2 -perm 040000
+ file rename td1 td2/
+} -returnCodes error -cleanup {
+ file delete -force td2
+ file delete -force td1
+} -result {error renaming "td1" to "td2/td1": permission denied}
+test fCmd-9.2 {file rename: comprehensive: source doesn't exist} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file rename tf1 tf2
+} -result {error renaming "tf1": no such file or directory}
+test fCmd-9.3 {file rename: comprehensive: file to new name} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ createfile tf1
+ createfile tf2
+ testchmod 444 tf2
+ file rename tf1 tf3
+ file rename tf2 tf4
+ list [lsort [glob tf*]] [file writable tf3] [file writable tf4]
+} -result {{tf3 tf4} 1 0}
+test fCmd-9.4.a {file rename: comprehensive: dir to new name} -setup {
+ cleanup
+} -constraints {win win2000orXP testchmod} -body {
+ file mkdir td1 td2
+ testchmod 555 td2
+ file rename td1 td3
+ file rename td2 td4
+ list [lsort [glob td*]] [file writable td3] [file writable td4]
+} -cleanup {
+ cleanup
+} -result {{td3 td4} 1 0}
+test fCmd-9.4.b {file rename: comprehensive: dir to new name} -setup {
+ cleanup
+} -constraints {unix notRoot testchmod notDarwin9} -body {
+ file mkdir td1 td2
+ testchmod 555 td2
+ file rename td1 td3
+ file rename td2 td4
+ list [lsort [glob td*]] [file writable td3] [file writable td4]
+} -cleanup {
+ cleanup
+} -result {{td3 td4} 1 0}
+test fCmd-9.5 {file rename: comprehensive: file to self} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ createfile tf1 tf1
+ createfile tf2 tf2
+ testchmod 444 tf2
+ file rename -force tf1 tf1
+ file rename -force tf2 tf2
+ list [contents tf1] [contents tf2] [file writable tf1] [file writable tf2]
+} -result {tf1 tf2 1 0}
+test fCmd-9.6.a {file rename: comprehensive: dir to self} -setup {
+ cleanup
+} -constraints {win win2000orXP testchmod} -body {
+ file mkdir td1
+ file mkdir td2
+ testchmod 555 td2
+ file rename -force td1 .
+ file rename -force td2 .
+ list [lsort [glob td*]] [file writable td1] [file writable td2]
+} -result {{td1 td2} 1 0}
+test fCmd-9.6.b {file rename: comprehensive: dir to self} -setup {
+ cleanup
+} -constraints {unix notRoot testchmod} -body {
+ file mkdir td1
+ file mkdir td2
+ testchmod 555 td2
+ file rename -force td1 .
+ file rename -force td2 .
+ list [lsort [glob td*]] [file writable td1] [file writable td2]
+} -result {{td1 td2} 1 0}
+test fCmd-9.7 {file rename: comprehensive: file to existing file} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ createfile tf1
+ createfile tf2
+ createfile tfs1
+ createfile tfs2
+ createfile tfs3
+ createfile tfs4
+ createfile tfd1
+ createfile tfd2
+ createfile tfd3
+ createfile tfd4
+ testchmod 444 tfs3
+ testchmod 444 tfs4
+ testchmod 444 tfd2
+ testchmod 444 tfd4
+ set msg [list [catch {file rename tf1 tf2} msg] $msg]
+ file rename -force tfs1 tfd1
+ file rename -force tfs2 tfd2
+ file rename -force tfs3 tfd3
+ file rename -force tfs4 tfd4
+ list [lsort [glob tf*]] $msg [file writable tfd1] [file writable tfd2] [file writable tfd3] [file writable tfd4]
+} -result {{tf1 tf2 tfd1 tfd2 tfd3 tfd4} {1 {error renaming "tf1" to "tf2": file already exists}} 1 1 0 0}
+test fCmd-9.8 {file rename: comprehensive: dir to empty dir} -setup {
+ cleanup
+} -constraints {notRoot testchmod notNetworkFilesystem} -body {
+ # Under unix, you can rename a read-only directory, but you can't move it
+ # into another directory.
+ file mkdir td1
+ file mkdir [file join td2 td1]
+ file mkdir tds1
+ file mkdir tds2
+ file mkdir tds3
+ file mkdir tds4
+ file mkdir [file join tdd1 tds1]
+ file mkdir [file join tdd2 tds2]
+ file mkdir [file join tdd3 tds3]
+ file mkdir [file join tdd4 tds4]
+ if {![testConstraint unix]} {
+ testchmod 555 tds3
+ testchmod 555 tds4
+ }
+ testchmod 555 [file join tdd2 tds2]
+ testchmod 555 [file join tdd4 tds4]
+ set msg [list [catch {file rename td1 td2} msg] $msg]
+ file rename -force tds1 tdd1
+ file rename -force tds2 tdd2
+ file rename -force tds3 tdd3
+ file rename -force tds4 tdd4
+ if {[testConstraint unix]} {
+ set w3 0
+ set w4 0
+ } else {
+ set w3 [file writable [file join tdd3 tds3]]
+ set w4 [file writable [file join tdd4 tds4]]
+ }
+ list [lsort [glob td*]] $msg [file writable [file join tdd1 tds1]] \
+ [file writable [file join tdd2 tds2]] $w3 $w4
+} -result [subst {{td1 td2 tdd1 tdd2 tdd3 tdd4} {1 {error renaming "td1" to "[file join td2 td1]": file already exists}} 1 1 0 0}]
+# Test can hit EEXIST or EBUSY, depending on underlying filesystem
+test fCmd-9.9 {file rename: comprehensive: dir to non-empty dir} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ file mkdir tds1
+ file mkdir tds2
+ file mkdir [file join tdd1 tds1 xxx]
+ file mkdir [file join tdd2 tds2 xxx]
+ if {!([testConstraint unix] || [testConstraint winVista])} {
+ testchmod 555 tds2
+ }
+ set a1 [list [catch {file rename -force tds1 tdd1} msg] $msg]
+ set a2 [list [catch {file rename -force tds2 tdd2} msg] $msg]
+ if {[testConstraint unix] || [testConstraint winVista]} {
+ set w2 0
+ } else {
+ set w2 [file writable tds2]
+ }
+ list [lsort [glob td*]] $a1 $a2 [file writable tds1] $w2
+} -match glob -result \
+ [subst {{tdd1 tdd2 tds1 tds2} {1 {error renaming "tds1" to "[file join tdd1 tds1]": file *}} {1 {error renaming "tds2" to "[file join tdd2 tds2]": file *}} 1 0}]
+test fCmd-9.10 {file rename: comprehensive: file to new name and dir} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ createfile tf1
+ createfile tf2
+ file mkdir td1
+ testchmod 444 tf2
+ file rename tf1 [file join td1 tf3]
+ file rename tf2 [file join td1 tf4]
+ list [catch {glob tf*}] [lsort [glob -directory td1 t*]] \
+ [file writable [file join td1 tf3]] [file writable [file join td1 tf4]]
+} -result [subst {1 {[file join td1 tf3] [file join td1 tf4]} 1 0}]
+test fCmd-9.11 {file rename: comprehensive: dir to new name and dir} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ file mkdir td1
+ file mkdir td2
+ file mkdir td3
+ if {!([testConstraint unix] || [testConstraint winVista])} {
+ testchmod 555 td2
+ }
+ file rename td1 [file join td3 td3]
+ file rename td2 [file join td3 td4]
+ if {[testConstraint unix] || [testConstraint winVista]} {
+ set w4 0
+ } else {
+ set w4 [file writable [file join td3 td4]]
+ }
+ list [lsort [glob td*]] [lsort [glob -directory td3 t*]] \
+ [file writable [file join td3 td3]] $w4
+} -result [subst {td3 {[file join td3 td3] [file join td3 td4]} 1 0}]
+test fCmd-9.12 {file rename: comprehensive: target exists} -setup {
+ cleanup
+} -constraints {notRoot testchmod notNetworkFilesystem} -body {
+ file mkdir [file join td1 td2] [file join td2 td1]
+ testchmod 555 [file join td2 td1]
+ file mkdir [file join td3 td4] [file join td4 td3]
+ file rename -force td3 td4
+ list [file exists td3] [file exists [file join td4 td3 td4]] \
+ [catch {file rename td1 td2} msg] $msg
+} -cleanup {
+ testchmod 755 [file join td2 td1]
+} -result [subst {0 1 1 {error renaming "td1" to "[file join td2 td1]": file already exists}}]
+# Test can hit EEXIST or EBUSY, depending on underlying filesystem
+test fCmd-9.13 {file rename: comprehensive: can't overwrite target} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir [file join td1 td2] [file join td2 td1 td4]
+ file rename -force td1 td2
+} -returnCodes error -match glob -result \
+ [subst {error renaming "td1" to "[file join td2 td1]": file *}]
+test fCmd-9.14 {file rename: comprehensive: dir into self} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir td1
+ list [glob td*] [list [catch {file rename td1 td1} msg] $msg]
+} -result [subst {td1 {1 {error renaming "td1" to "[file join td1 td1]": trying to rename a volume or move a directory into itself}}}]
+test fCmd-9.14.1 {file rename: comprehensive: dir into self} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir td1
+ file rename td1 td1x
+ file rename td1x td1
+ set msg "ok"
+} -result {ok}
+test fCmd-9.14.2 {file rename: comprehensive: dir into self} -setup {
+ cleanup
+ set dir [pwd]
+} -constraints {nonPortable notRoot} -body {
+ file mkdir td1
+ cd td1
+ file rename [file join .. td1] [file join .. td1x]
+} -returnCodes error -cleanup {
+ cd $dir
+} -result [subst {error renaming "[file join .. td1]" to "[file join .. td1x]": permission denied}]
+test fCmd-9.14.3 {file rename: comprehensive: dir into self} -setup {
+ cleanup
+ set dir [pwd]
+} -constraints {notRoot} -body {
+ file mkdir td1
+ cd td1
+ file rename [file join .. td1] [file join .. td1 foo]
+} -returnCodes error -cleanup {
+ cd $dir
+} -result [subst {error renaming "[file join .. td1]" to "[file join .. td1 foo]": trying to rename a volume or move a directory into itself}]
+test fCmd-9.15 {file rename: comprehensive: source and target incompatible} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir td1
+ createfile tf1
+ file rename -force td1 tf1
+} -cleanup {
+ cleanup
+} -result {can't overwrite file "tf1" with directory "td1"}
+test fCmd-9.16 {file rename: comprehensive: source and target incompatible} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir td1/tf1
+ createfile tf1
+ file rename -force tf1 td1
+} -result [subst {can't overwrite directory "[file join td1 tf1]" with file "tf1"}]
+
+test fCmd-10.1 {file copy: comprehensive: source doesn't exist} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file copy tf1 tf2
+} -result {error copying "tf1": no such file or directory}
+test fCmd-10.2 {file copy: comprehensive: file to new name} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ createfile tf1 tf1
+ createfile tf2 tf2
+ testchmod 444 tf2
+ file copy tf1 tf3
+ file copy tf2 tf4
+ list [lsort [glob tf*]] [contents tf3] [contents tf4] [file writable tf3] [file writable tf4]
+} -result {{tf1 tf2 tf3 tf4} tf1 tf2 1 0}
+test fCmd-10.3 {file copy: comprehensive: dir to new name} -setup {
+ cleanup
+} -constraints {unix notRoot testchmod} -body {
+ file mkdir [file join td1 tdx]
+ file mkdir [file join td2 tdy]
+ testchmod 555 td2
+ file copy td1 td3
+ file copy td2 td4
+ list [lsort [glob td*]] [glob -directory td3 t*] \
+ [glob -directory td4 t*] [file writable td3] [file writable td4]
+} -cleanup {
+ testchmod 755 td2
+ testchmod 755 td4
+} -result [list {td1 td2 td3 td4} [file join td3 tdx] [file join td4 tdy] 1 0]
+test fCmd-10.3.1 {file copy: comprehensive: dir to new name} -setup {
+ cleanup
+} -constraints {win notRoot testchmod} -body {
+ # On Windows with ACLs, copying a directory is defined like this
+ file mkdir [file join td1 tdx]
+ file mkdir [file join td2 tdy]
+ testchmod 555 td2
+ file copy td1 td3
+ file copy td2 td4
+ list [lsort [glob td*]] [glob -directory td3 t*] \
+ [glob -directory td4 t*] [file writable td3] [file writable td4]
+} -cleanup {
+ testchmod 755 td2
+ testchmod 755 td4
+} -result [list {td1 td2 td3 td4} [file join td3 tdx] [file join td4 tdy] 1 1]
+test fCmd-10.4 {file copy: comprehensive: file to existing file} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ createfile tf1
+ createfile tf2
+ createfile tfs1
+ createfile tfs2
+ createfile tfs3
+ createfile tfs4
+ createfile tfd1
+ createfile tfd2
+ createfile tfd3
+ createfile tfd4
+ testchmod 444 tfs3
+ testchmod 444 tfs4
+ testchmod 444 tfd2
+ testchmod 444 tfd4
+ set msg [list [catch {file copy tf1 tf2} msg] $msg]
+ file copy -force tfs1 tfd1
+ file copy -force tfs2 tfd2
+ file copy -force tfs3 tfd3
+ file copy -force tfs4 tfd4
+ list [lsort [glob tf*]] $msg [file writable tfd1] [file writable tfd2] [file writable tfd3] [file writable tfd4]
+} -result {{tf1 tf2 tfd1 tfd2 tfd3 tfd4 tfs1 tfs2 tfs3 tfs4} {1 {error copying "tf1" to "tf2": file already exists}} 1 1 0 0}
+test fCmd-10.5 {file copy: comprehensive: dir to empty dir} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ file mkdir td1
+ file mkdir [file join td2 td1]
+ file mkdir tds1
+ file mkdir tds2
+ file mkdir tds3
+ file mkdir tds4
+ file mkdir [file join tdd1 tds1]
+ file mkdir [file join tdd2 tds2]
+ file mkdir [file join tdd3 tds3]
+ file mkdir [file join tdd4 tds4]
+ testchmod 555 tds3
+ testchmod 555 tds4
+ testchmod 555 [file join tdd2 tds2]
+ testchmod 555 [file join tdd4 tds4]
+ set a1 [list [catch {file copy td1 td2} msg] $msg]
+ set a2 [list [catch {file copy -force tds1 tdd1} msg] $msg]
+ set a3 [catch {file copy -force tds2 tdd2}]
+ set a4 [catch {file copy -force tds3 tdd3}]
+ set a5 [catch {file copy -force tds4 tdd4}]
+ list [lsort [glob td*]] $a1 $a2 $a3 $a4 $a5
+} -result [subst {{td1 td2 tdd1 tdd2 tdd3 tdd4 tds1 tds2 tds3 tds4} {1 {error copying "td1" to "[file join td2 td1]": file already exists}} {1 {error copying "tds1" to "[file join tdd1 tds1]": file already exists}} 1 1 1}]
+test fCmd-10.6 {file copy: comprehensive: dir to non-empty dir} -setup {
+ cleanup
+} -constraints {notRoot unixOrPc testchmod} -body {
+ file mkdir tds1
+ file mkdir tds2
+ file mkdir [file join tdd1 tds1 xxx]
+ file mkdir [file join tdd2 tds2 xxx]
+ testchmod 555 tds2
+ set a1 [list [catch {file copy -force tds1 tdd1} msg] $msg]
+ set a2 [list [catch {file copy -force tds2 tdd2} msg] $msg]
+ list [lsort [glob td*]] $a1 $a2 [file writable tds1] [file writable tds2]
+} -result [subst {{tdd1 tdd2 tds1 tds2} {1 {error copying "tds1" to "[file join tdd1 tds1]": file already exists}} {1 {error copying "tds2" to "[file join tdd2 tds2]": file already exists}} 1 0}]
+test fCmd-10.7 {file rename: comprehensive: file to new name and dir} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ createfile tf1
+ createfile tf2
+ file mkdir td1
+ testchmod 444 tf2
+ file copy tf1 [file join td1 tf3]
+ file copy tf2 [file join td1 tf4]
+ list [lsort [glob tf*]] [lsort [glob -directory td1 t*]] \
+ [file writable [file join td1 tf3]] [file writable [file join td1 tf4]]
+} -result [subst {{tf1 tf2} {[file join td1 tf3] [file join td1 tf4]} 1 0}]
+test fCmd-10.8 {file rename: comprehensive: dir to new name and dir} -setup {
+ cleanup
+} -constraints {unix notRoot testchmod} -body {
+ file mkdir td1
+ file mkdir td2
+ file mkdir td3
+ testchmod 555 td2
+ file copy td1 [file join td3 td3]
+ file copy td2 [file join td3 td4]
+ list [lsort [glob td*]] [lsort [glob -directory td3 t*]] \
+ [file writable [file join td3 td3]] [file writable [file join td3 td4]]
+} -result [subst {{td1 td2 td3} {[file join td3 td3] [file join td3 td4]} 1 0}]
+test fCmd-10.8.1 {file rename: comprehensive: dir to new name and dir} -setup {
+ cleanup
+} -constraints {win notRoot testchmod} -body {
+ # On Windows with ACLs, copying a directory is defined like this
+ file mkdir td1
+ file mkdir td2
+ file mkdir td3
+ testchmod 555 td2
+ file copy td1 [file join td3 td3]
+ file copy td2 [file join td3 td4]
+ list [lsort [glob td*]] [lsort [glob -directory td3 t*]] \
+ [file writable [file join td3 td3]] [file writable [file join td3 td4]]
+} -result [subst {{td1 td2 td3} {[file join td3 td3] [file join td3 td4]} 1 1}]
+test fCmd-10.9 {file copy: comprehensive: source and target incompatible} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir td1
+ createfile tf1
+ file copy -force td1 tf1
+} -result {can't overwrite file "tf1" with directory "td1"}
+test fCmd-10.10 {file copy: comprehensive: source and target incompatible} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir [file join td1 tf1]
+ createfile tf1
+ file copy -force tf1 td1
+} -result [subst {can't overwrite directory "[file join td1 tf1]" with file "tf1"}]
+test fCmd-10.11 {file copy: copy to empty file name} -setup {
+ cleanup
+} -returnCodes error -body {
+ createfile tf1
+ file copy tf1 ""
+} -result {error copying "tf1" to "": no such file or directory}
+test fCmd-10.12 {file rename: rename to empty file name} -setup {
+ cleanup
+} -returnCodes error -body {
+ createfile tf1
+ file rename tf1 ""
+} -result {error renaming "tf1" to "": no such file or directory}
+cleanup
+
+# old tests
+
+test fCmd-11.1 {TclFileRenameCmd: -- option} -constraints notRoot -setup {
+ catch {file delete -force -- -tfa1}
+} -body {
+ set s [createfile -tfa1]
+ file rename -- -tfa1 tfa2
+ list [checkcontent tfa2 $s] [file exists -tfa1]
+} -cleanup {
+ file delete tfa2
+} -result {1 0}
+test fCmd-11.2 {TclFileRenameCmd: bad option} -constraints notRoot -setup {
+ catch {file delete -force -- tfa1}
+} -body {
+ set s [createfile tfa1]
+ list [catch {file rename -x tfa1 tfa2}] \
+ [checkcontent tfa1 $s] [file exists tfa2]
+} -cleanup {
+ file delete tfa1
+} -result {1 1 0}
+test fCmd-11.3 {TclFileRenameCmd: bad \# args} -returnCodes error -body {
+ file rename --
+} -match glob -result *
+test fCmd-11.4 {TclFileRenameCmd: target filename translation failing} -setup {
+ set temp $::env(HOME)
+} -constraints notRoot -body {
+ global env
+ unset env(HOME)
+ catch { file rename tfa ~/foobar }
+} -cleanup {
+ set ::env(HOME) $temp
+} -result 1
+test fCmd-11.5 {TclFileRenameCmd: > 1 source & target is not a dir} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {notRoot} -body {
+ createfile tfa1
+ createfile tfa2
+ createfile tfa3
+ catch {file rename tfa1 tfa2 tfa3}
+} -cleanup {
+ file delete tfa1 tfa2 tfa3
+} -result {1}
+test fCmd-11.6 {TclFileRenameCmd: : single file into directory} -setup {
+ catch {file delete -force -- tfa1 tfad}
+} -constraints {notRoot} -body {
+ set s [createfile tfa1]
+ file mkdir tfad
+ file rename tfa1 tfad
+ list [checkcontent tfad/tfa1 $s] [file exists tfa1]
+} -cleanup {
+ file delete -force tfad
+} -result {1 0}
+test fCmd-11.7 {TclFileRenameCmd: : multiple files into directory} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfad}
+} -constraints {notRoot} -body {
+ set s1 [createfile tfa1]
+ set s2 [createfile tfa2]
+ file mkdir tfad
+ file rename tfa1 tfa2 tfad
+ list [checkcontent tfad/tfa1 $s1] [checkcontent tfad/tfa2 $s2] \
+ [file exists tfa1] [file exists tfa2]
+} -cleanup {
+ file delete -force tfad
+} -result {1 1 0 0}
+test fCmd-11.8 {TclFileRenameCmd: error renaming file to directory} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ set s [createfile tfa]
+ file mkdir tfad
+ file mkdir tfad/tfa
+ list [catch {file rename tfa tfad}] [checkcontent tfa $s] [file isdir tfad]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1}
+
+#
+# Coverage tests for renamefile() ;
+#
+test fCmd-12.1 {renamefile: source filename translation failing} -setup {
+ set temp $::env(HOME)
+} -constraints {notRoot} -body {
+ global env
+ unset env(HOME)
+ catch {file rename ~/tfa1 tfa2}
+} -cleanup {
+ set ::env(HOME) $temp
+} -result {1}
+test fCmd-12.2 {renamefile: src filename translation failing} -setup {
+ set temp $::env(HOME)
+} -constraints {notRoot} -body {
+ global env
+ unset env(HOME)
+ set s [createfile tfa1]
+ file mkdir tfad
+ catch {file rename tfa1 ~/tfa2 tfad}
+} -cleanup {
+ set ::env(HOME) $temp
+ file delete -force tfad
+} -result {1}
+test fCmd-12.3 {renamefile: stat failing on source} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ list [catch {file rename tfa1 tfa2}] [file exists tfa1] [file exists tfa2]
+} -result {1 0 0}
+test fCmd-12.4 {renamefile: error renaming file to directory} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ set s1 [createfile tfa]
+ file mkdir tfad
+ file mkdir tfad/tfa
+ list [catch {file rename tfa tfad}] [checkcontent tfa $s1] \
+ [file isdir tfad/tfa]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1}
+test fCmd-12.5 {renamefile: error renaming directory to file} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ file mkdir tfa
+ file mkdir tfad
+ set s [createfile tfad/tfa]
+ list [catch {file rename tfa tfad}] [checkcontent tfad/tfa $s] \
+ [file isdir tfad] [file isdir tfa]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1 1}
+test fCmd-12.6 {renamefile: TclRenameFile succeeding} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ set s [createfile tfa1]
+ file rename tfa1 tfa2
+ list [checkcontent tfa2 $s] [file exists tfa1]
+} -cleanup {
+ file delete tfa2
+} -result {1 0}
+test fCmd-12.7 {renamefile: renaming directory into offspring} -setup {
+ catch {file delete -force -- tfad}
+} -constraints {notRoot} -body {
+ file mkdir tfad
+ file mkdir tfad/dir
+ catch {file rename tfad tfad/dir}
+} -cleanup {
+ file delete -force tfad
+} -result {1}
+test fCmd-12.8 {renamefile: generic error} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa
+ file mkdir tfa/dir
+ file attributes tfa -permissions 0555
+ catch {file rename tfa/dir tfa2}
+} -cleanup {
+ catch {file attributes tfa -permissions 0777}
+ file delete -force tfa
+} -result {1}
+test fCmd-12.9 {renamefile: moving a file across volumes} -setup {
+ cleanup $tmpspace
+} -constraints {unix notRoot} -body {
+ set s [createfile tfa]
+ file rename tfa $tmpspace
+ list [checkcontent [file join $tmpspace tfa] $s] [file exists tfa]
+} -cleanup {
+ cleanup $tmpspace
+} -result {1 0}
+test fCmd-12.10 {renamefile: moving a directory across volumes} -setup {
+ cleanup $tmpspace
+} -constraints {xdev notRoot} -body {
+ file mkdir tfad
+ set s [createfile tfad/a]
+ file rename tfad $tmpspace
+ list [checkcontent [file join $tmpspace tfad a] $s] [file exists tfad]
+} -cleanup {
+ cleanup $tmpspace
+} -result {1 0}
+
+#
+# Coverage tests for TclCopyFilesCmd()
+#
+test fCmd-13.1 {TclCopyFilesCmd: -force option} -constraints notRoot -setup {
+ catch {file delete -force -- tfa1}
+} -body {
+ set s [createfile tfa1]
+ file copy -force tfa1 tfa2
+ list [checkcontent tfa2 $s] [checkcontent tfa1 $s]
+} -cleanup {
+ file delete tfa1 tfa2
+} -result {1 1}
+test fCmd-13.2 {TclCopyFilesCmd: -- option} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa1}
+} -body {
+ set s [createfile -tfa1]
+ file copy -- -tfa1 tfa2
+ list [checkcontent tfa2 $s] [checkcontent -tfa1 $s]
+} -cleanup {
+ file delete -- -tfa1 tfa2
+} -result {1 1}
+test fCmd-13.3 {TclCopyFilesCmd: bad option} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa1}
+} -body {
+ set s [createfile tfa1]
+ list [catch {file copy -x tfa1 tfa2}] \
+ [checkcontent tfa1 $s] [file exists tfa2]
+} -cleanup {
+ file delete tfa1
+} -result {1 1 0}
+test fCmd-13.4 {TclCopyFilesCmd: bad \# args} -constraints {notRoot} -body {
+ file copy --
+} -returnCodes error -match glob -result *
+test fCmd-13.5 {TclCopyFilesCmd: target filename translation failing} -setup {
+ set temp $::env(HOME)
+} -body {
+ global env
+ unset env(HOME)
+ catch { file copy tfa ~/foobar }
+} -cleanup {
+ set ::env(HOME) $temp
+} -result {1}
+test fCmd-13.6 {TclCopyFilesCmd: > 1 source & target is not a dir} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {notRoot} -body {
+ createfile tfa1
+ createfile tfa2
+ createfile tfa3
+ catch {file copy tfa1 tfa2 tfa3}
+} -cleanup {
+ file delete tfa1 tfa2 tfa3
+} -result {1}
+test fCmd-13.7 {TclCopyFilesCmd: single file into directory} -setup {
+ catch {file delete -force -- tfa1 tfad}
+} -constraints {notRoot} -body {
+ set s [createfile tfa1]
+ file mkdir tfad
+ file copy tfa1 tfad
+ list [checkcontent tfad/tfa1 $s] [checkcontent tfa1 $s]
+} -cleanup {
+ file delete -force tfad tfa1
+} -result {1 1}
+test fCmd-13.8 {TclCopyFilesCmd: multiple files into directory} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfad}
+} -constraints {notRoot} -body {
+ set s1 [createfile tfa1]
+ set s2 [createfile tfa2]
+ file mkdir tfad
+ file copy tfa1 tfa2 tfad
+ list [checkcontent tfad/tfa1 $s1] [checkcontent tfad/tfa2 $s2] \
+ [checkcontent tfa1 $s1] [checkcontent tfa2 $s2]
+} -cleanup {
+ file delete -force tfad tfa1 tfa2
+} -result {1 1 1 1}
+test fCmd-13.9 {TclCopyFilesCmd: error copying file to directory} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ set s [createfile tfa]
+ file mkdir tfad
+ file mkdir tfad/tfa
+ list [catch {file copy tfa tfad}] [checkcontent tfa $s] \
+ [file isdir tfad/tfa] [file isdir tfad]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1 1}
+
+#
+# Coverage tests for copyfile()
+#
+test fCmd-14.1 {copyfile: source filename translation failing} -setup {
+ set temp $::env(HOME)
+} -constraints {notRoot} -body {
+ global env
+ unset env(HOME)
+ catch {file copy ~/tfa1 tfa2}
+} -cleanup {
+ set ::env(HOME) $temp
+} -result {1}
+test fCmd-14.2 {copyfile: dst filename translation failing} -setup {
+ set temp $::env(HOME)
+} -constraints {notRoot} -body {
+ global env
+ unset env(HOME)
+ set s [createfile tfa1]
+ file mkdir tfad
+ list [catch {file copy tfa1 ~/tfa2 tfad}] [checkcontent tfad/tfa1 $s]
+} -cleanup {
+ set ::env(HOME) $temp
+ file delete -force tfa1 tfad
+} -result {1 1}
+test fCmd-14.3 {copyfile: stat failing on source} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints notRoot -body {
+ list [catch {file copy tfa1 tfa2}] [file exists tfa1] [file exists tfa2]
+} -result {1 0 0}
+test fCmd-14.4 {copyfile: error copying file to directory} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ set s1 [createfile tfa]
+ file mkdir tfad
+ file mkdir tfad/tfa
+ list [catch {file copy tfa tfad}] [checkcontent tfa $s1] \
+ [file isdir tfad] [file isdir tfad/tfa]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1 1}
+test fCmd-14.5 {copyfile: error copying directory to file} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ file mkdir tfa
+ file mkdir tfad
+ set s [createfile tfad/tfa]
+ list [catch {file copy tfa tfad}] [checkcontent tfad/tfa $s] \
+ [file isdir tfad] [file isdir tfa]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1 1}
+test fCmd-14.6 {copyfile: copy file succeeding} -constraints notRoot -setup {
+ catch {file delete -force -- tfa tfa2}
+} -body {
+ set s [createfile tfa]
+ file copy tfa tfa2
+ list [checkcontent tfa $s] [checkcontent tfa2 $s]
+} -cleanup {
+ file delete tfa tfa2
+} -result {1 1}
+test fCmd-14.7 {copyfile: copy directory succeeding} -setup {
+ catch {file delete -force -- tfa tfa2}
+} -constraints {notRoot} -body {
+ file mkdir tfa
+ set s [createfile tfa/file]
+ file copy tfa tfa2
+ list [checkcontent tfa/file $s] [checkcontent tfa2/file $s]
+} -cleanup {
+ file delete -force tfa tfa2
+} -result {1 1}
+test fCmd-14.8 {copyfile: copy directory failing} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa/dir/a/b/c
+ file attributes tfa/dir -permissions 0000
+ catch {file copy tfa tfa2}
+} -cleanup {
+ file attributes tfa/dir -permissions 0777
+ file delete -force tfa tfa2
+} -result {1}
+
+#
+# Coverage tests for TclMkdirCmd()
+#
+test fCmd-15.1 {TclMakeDirsCmd: target filename translation failing} -setup {
+ set temp $::env(HOME)
+} -constraints {notRoot} -body {
+ global env
+ unset env(HOME)
+ catch {file mkdir ~/tfa}
+} -cleanup {
+ set ::env(HOME) $temp
+} -result {1}
+#
+# Can Tcl_SplitPath return argc == 0? If so them we need a test for that code.
+#
+test fCmd-15.2 {TclMakeDirsCmd - one directory} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+ file mkdir tfa
+ file isdirectory tfa
+} -cleanup {
+ file delete tfa
+} -result {1}
+test fCmd-15.3 {TclMakeDirsCmd: - two directories} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ file mkdir tfa1 tfa2
+ list [file isdirectory tfa1] [file isdirectory tfa2]
+} -cleanup {
+ file delete tfa1 tfa2
+} -result {1 1}
+test fCmd-15.4 {TclMakeDirsCmd - stat failing} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa
+ createfile tfa/file
+ file attributes tfa -permissions 0000
+ catch {file mkdir tfa/file}
+} -cleanup {
+ file attributes tfa -permissions 0777
+ file delete -force tfa
+} -result {1}
+test fCmd-15.5 {TclMakeDirsCmd: - making a directory several levels deep} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+ file mkdir tfa/a/b/c
+ file isdir tfa/a/b/c
+} -cleanup {
+ file delete -force tfa
+} -result {1}
+test fCmd-15.6 {TclMakeDirsCmd: - trying to overwrite a file} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+ set s [createfile tfa]
+ list [catch {file mkdir tfa}] [file isdir tfa] [file exists tfa] \
+ [checkcontent tfa $s]
+} -cleanup {
+ file delete tfa
+} -result {1 0 1 1}
+test fCmd-15.7 {TclMakeDirsCmd - making several directories} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ file mkdir tfa1 tfa2/a/b/c
+ list [file isdir tfa1] [file isdir tfa2/a/b/c]
+} -cleanup {
+ file delete -force tfa1 tfa2
+} -result {1 1}
+test fCmd-15.8 {TclFileMakeDirsCmd: trying to create an existing dir} -body {
+ file mkdir tfa
+ file mkdir tfa
+ file isdir tfa
+} -constraints {notRoot} -cleanup {
+ file delete tfa
+} -result {1}
+
+# Coverage tests for TclDeleteFilesCommand()
+test fCmd-16.1 {test the -- argument} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa}
+} -body {
+ createfile tfa
+ file delete -- tfa
+ file exists tfa
+} -result 0
+test fCmd-16.2 {test the -force and -- arguments} -constraints notRoot -setup {
+ catch {file delete -force -- tfa}
+} -body {
+ createfile tfa
+ file delete -force -- tfa
+ file exists tfa
+} -result 0
+test fCmd-16.3 {test bad option} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa}
+} -body {
+ createfile tfa
+ catch {file delete -dog tfa}
+} -cleanup {
+ file delete tfa
+} -result {1}
+test fCmd-16.4 {accept zero files (TIP 323)} -body {
+ file delete
+} -result {}
+test fCmd-16.5 {accept zero files (TIP 323)} -body {
+ file delete --
+} -result {}
+test fCmd-16.6 {delete: source filename translation failing} -setup {
+ set temp $::env(HOME)
+} -constraints {notRoot} -body {
+ global env
+ unset env(HOME)
+ catch {file delete ~/tfa}
+} -cleanup {
+ set ::env(HOME) $temp
+} -result {1}
+test fCmd-16.7 {remove a non-empty directory without -force} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+ file mkdir tfa
+ createfile tfa/a
+ catch {file delete tfa}
+} -cleanup {
+ file delete -force tfa
+} -result {1}
+test fCmd-16.8 {remove a normal file} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa}
+} -body {
+ file mkdir tfa
+ createfile tfa/a
+ catch {file delete tfa}
+} -cleanup {
+ file delete -force tfa
+} -result {1}
+test fCmd-16.9 {error while deleting file} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa
+ createfile tfa/a
+ file attributes tfa -permissions 0555
+ catch {file delete tfa/a}
+ #######
+ ####### If any directory in a tree that is being removed does not have
+ ####### write permission, the process will fail! This is also the case
+ ####### with "rm -rf"
+ #######
+} -cleanup {
+ file attributes tfa -permissions 0777
+ file delete -force tfa
+} -result {1}
+test fCmd-16.10 {deleting multiple files} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -body {
+ createfile tfa1
+ createfile tfa2
+ file delete tfa1 tfa2
+ list [file exists tfa1] [file exists tfa2]
+} -result {0 0}
+test fCmd-16.11 {TclFileDeleteCmd: removing a nonexistant file} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+ file delete tfa
+} -result {}
+
+# More coverage tests for mkpath()
+test fCmd-17.1 {mkdir stat failing on target but not ENOENT} -setup {
+ catch {file delete -force -- tfa1}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa1
+ file attributes tfa1 -permissions 0555
+ catch {file mkdir tfa1/tfa2}
+} -cleanup {
+ file attributes tfa1 -permissions 0777
+ file delete -force tfa1
+} -result {1}
+test fCmd-17.2 {mkdir several levels deep - relative} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+ file mkdir tfa/a/b
+ file isdir tfa/a/b
+} -cleanup {
+ file delete tfa/a/b tfa/a tfa
+} -result 1
+test fCmd-17.3 {mkdir several levels deep - absolute} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+ set f [file join [pwd] tfa a]
+ file mkdir $f
+ file isdir $f
+} -cleanup {
+ file delete $f [file join [pwd] tfa]
+} -result {1}
+
+#
+# Functionality tests for TclFileRenameCmd()
+#
+test fCmd-18.1 {TclFileRenameCmd: rename (first form) in the same directory} \
+ -setup {
+ catch {file delete -force -- tfad}
+ set savedDir [pwd]
+} -constraints {notRoot} -body {
+ file mkdir tfad/dir
+ cd tfad/dir
+ set s [createfile foo]
+ file rename foo bar
+ file rename bar ./foo
+ file rename ./foo bar
+ file rename ./bar ./foo
+ file rename foo ../dir/bar
+ file rename ../dir/bar ./foo
+ file rename ../../tfad/dir/foo ../../tfad/dir/bar
+ file rename [file join [pwd] bar] foo
+ file rename foo [file join [pwd] bar]
+ list [checkcontent bar $s] [file exists foo]
+} -cleanup {
+ cd $savedDir
+ file delete -force tfad
+} -result {1 0}
+test fCmd-18.2 {TclFileRenameCmd: single dir to nonexistant} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ file mkdir tfa1
+ file rename tfa1 tfa2
+ list [file exists tfa2] [file exists tfa1]
+} -cleanup {
+ file delete tfa2
+} -result {1 0}
+test fCmd-18.3 {TclFileRenameCmd: mixed dirs and files into directory} -setup {
+ catch {file delete -force -- tfa1 tfad1 tfad2}
+} -constraints {notRoot} -body {
+ set s [createfile tfa1]
+ file mkdir tfad1 tfad2
+ file rename tfa1 tfad1 tfad2
+ list [checkcontent tfad2/tfa1 $s] [file isdir tfad2/tfad1] \
+ [file exists tfa1] [file exists tfad1]
+} -cleanup {
+ file delete tfad2/tfa1
+ file delete -force tfad2
+} -result {1 1 0 0}
+test fCmd-18.4 {TclFileRenameCmd: attempt to replace non-dir with dir} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ set s [createfile tfa]
+ file mkdir tfad
+ list [catch {file rename tfad tfa}] [checkcontent tfa $s] [file isdir tfad]
+} -cleanup {
+ file delete tfa tfad
+} -result {1 1 1}
+test fCmd-18.5 {TclFileRenameCmd: attempt to replace dir with non-dir} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ set s [createfile tfa]
+ file mkdir tfad/tfa
+ list [catch {file rename tfa tfad}] [checkcontent tfa $s] \
+ [file isdir tfad/tfa]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1}
+#
+# On Windows there is no easy way to determine if two files are the same
+#
+test fCmd-18.6 {TclFileRenameCmd: rename a file to itself} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+ set s [createfile tfa]
+ list [catch {file rename tfa tfa}] [checkcontent tfa $s]
+} -cleanup {
+ file delete tfa
+} -result {1 1}
+test fCmd-18.7 {TclFileRenameCmd: rename dir on top of another empty dir w/o -force} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ file mkdir tfa tfad/tfa
+ list [catch {file rename tfa tfad}] [file isdir tfa]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1}
+test fCmd-18.8 {TclFileRenameCmd: rename dir on top of another empty dir w/ -force} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot notNetworkFilesystem} -body {
+ file mkdir tfa tfad/tfa
+ file rename -force tfa tfad
+ file isdir tfa
+} -cleanup {
+ file delete -force tfad
+} -result 0
+test fCmd-18.9 {TclFileRenameCmd: rename dir on top of a non-empty dir w/o -force} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ file mkdir tfa tfad/tfa/file
+ list [catch {file rename tfa tfad}] [file isdir tfa] \
+ [file isdir tfad/tfa/file]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1}
+test fCmd-18.10 {TclFileRenameCmd: rename dir on top of a non-empty dir w/ -force} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot notNetworkFilesystem} -body {
+ file mkdir tfa tfad/tfa/file
+ list [catch {file rename -force tfa tfad}] [file isdir tfa] \
+ [file isdir tfad/tfa/file]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1}
+test fCmd-18.11 {TclFileRenameCmd: rename a non-existant file} -setup {
+ catch {file delete -force -- tfa1}
+} -constraints {notRoot} -body {
+ list [catch {file rename tfa1 tfa2}] [file exists tfa1] [file exists tfa2]
+} -result {1 0 0}
+test fCmd-18.12 {TclFileRenameCmd : rename a symbolic link to file} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {unix notRoot} -body {
+ set s [createfile tfa1]
+ file link -symbolic tfa2 tfa1
+ file rename tfa2 tfa3
+ file type tfa3
+} -cleanup {
+ file delete tfa1 tfa3
+} -result link
+test fCmd-18.13 {TclFileRenameCmd : rename a symbolic link to dir} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa1
+ file link -symbolic tfa2 tfa1
+ file rename tfa2 tfa3
+ file type tfa3
+} -cleanup {
+ file delete tfa1 tfa3
+} -result link
+test fCmd-18.14 {TclFileRenameCmd : rename a path with sym link} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa1/a/b/c/d
+ file mkdir tfa2
+ set f [file join [pwd] tfa1/a/b]
+ set f2 [file join [pwd] {tfa2/b alias}]
+ file link -symbolic $f2 $f
+ file rename {tfa2/b alias/c} tfa3
+ list [file isdir tfa3] [file exists tfa1/a/b/c]
+} -cleanup {
+ file delete -force tfa1 tfa2 tfa3
+} -result {1 0}
+test fCmd-18.15 {TclFileRenameCmd : rename a file to a symlink dir} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfalink}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa1
+ set s [createfile tfa2]
+ file link -symbolic tfalink tfa1
+ file rename tfa2 tfalink
+ checkcontent tfa1/tfa2 $s
+} -cleanup {
+ file delete -force tfa1 tfalink
+} -result {1}
+test fCmd-18.16 {TclFileRenameCmd: rename a dangling symlink} -setup {
+ catch {file delete -force -- tfa1 tfalink}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa1
+ file link -symbolic tfalink tfa1
+ file delete tfa1
+ file rename tfalink tfa2
+ file type tfa2
+} -cleanup {
+ file delete tfa2
+} -result link
+
+#
+# Coverage tests for TclUnixRmdir
+#
+test fCmd-19.1 {remove empty directory} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa}
+} -body {
+ file mkdir tfa
+ file delete tfa
+ file exists tfa
+} -result {0}
+test fCmd-19.2 {rmdir error besides EEXIST} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa
+ file mkdir tfa/a
+ file attributes tfa -permissions 0555
+ catch {file delete tfa/a}
+} -cleanup {
+ file attributes tfa -permissions 0777
+ file delete -force tfa
+} -result {1}
+test fCmd-19.3 {recursive remove} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa}
+} -body {
+ file mkdir tfa
+ file mkdir tfa/a
+ file delete -force tfa
+ file exists tfa
+} -result {0}
+
+#
+# TclUnixDeleteFile and TraversalDelete are covered by tests from the
+# TclDeleteFilesCmd suite
+#
+
+#
+# Coverage tests for TraverseUnixTree(), called from TclDeleteFilesCmd
+#
+test fCmd-20.1 {TraverseUnixTree : failure opening a subdirectory directory} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa
+ file mkdir tfa/a
+ file attributes tfa/a -permissions 0000
+ catch {file delete -force tfa}
+} -cleanup {
+ file attributes tfa/a -permissions 0777
+ file delete -force tfa
+} -result {1}
+test fCmd-20.2 {TraverseUnixTree : recursive delete of large directory: Bug 1034337} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa
+ for {set i 1} {$i <= 300} {incr i} {
+ createfile tfa/testfile_$i
+ }
+ file delete -force tfa
+} -cleanup {
+ while {[catch {file delete -force tfa}]} {}
+} -result {}
+
+#
+# Feature testing for TclCopyFilesCmd
+#
+test fCmd-21.1 {copy : single file to nonexistant} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ set s [createfile tfa1]
+ file copy tfa1 tfa2
+ list [checkcontent tfa2 $s] [checkcontent tfa1 $s]
+} -cleanup {
+ file delete tfa1 tfa2
+} -result {1 1}
+test fCmd-21.2 {copy : single dir to nonexistant} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ file mkdir tfa1
+ file copy tfa1 tfa2
+ list [file isdir tfa2] [file isdir tfa1]
+} -cleanup {
+ file delete tfa1 tfa2
+} -result {1 1}
+test fCmd-21.3 {copy : single file into directory} -setup {
+ catch {file delete -force -- tfa1 tfad}
+} -constraints {notRoot} -body {
+ set s [createfile tfa1]
+ file mkdir tfad
+ file copy tfa1 tfad
+ list [checkcontent tfad/tfa1 $s] [checkcontent tfa1 $s]
+} -cleanup {
+ file delete -force tfa1 tfad
+} -result {1 1}
+test fCmd-21.4 {copy : more than one source and target is not a directory} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {notRoot} -body {
+ createfile tfa1
+ createfile tfa2
+ createfile tfa3
+ catch {file copy tfa1 tfa2 tfa3}
+} -cleanup {
+ file delete tfa1 tfa2 tfa3
+} -result {1}
+test fCmd-21.5 {copy : multiple files into directory} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfad}
+} -body {
+ set s1 [createfile tfa1]
+ set s2 [createfile tfa2]
+ file mkdir tfad
+ file copy tfa1 tfa2 tfad
+ list [checkcontent tfad/tfa1 $s1] [checkcontent tfad/tfa2 $s2] \
+ [checkcontent tfa1 $s1] [checkcontent tfa2 $s2]
+} -cleanup {
+ file delete -force tfa1 tfa2 tfad
+} -result {1 1 1 1}
+test fCmd-21.6 {copy: mixed dirs and files into directory} -setup {
+ catch {file delete -force -- tfa1 tfad1 tfad2}
+} -constraints {notRoot notFileSharing} -body {
+ set s [createfile tfa1]
+ file mkdir tfad1 tfad2
+ file copy tfa1 tfad1 tfad2
+ list [checkcontent [file join tfad2 tfa1] $s] \
+ [file isdir [file join tfad2 tfad1]] \
+ [checkcontent tfa1 $s] [file isdir tfad1]
+} -cleanup {
+ file delete -force tfa1 tfad1 tfad2
+} -result {1 1 1 1}
+test fCmd-21.7.1 {TclCopyFilesCmd: copy a dangling link} -setup {
+ catch {file delete -force tfad1 tfalink tfalink2}
+} -constraints {unix notRoot dontCopyLinks} -body {
+ file mkdir tfad1
+ file link -symbolic tfalink tfad1
+ file delete tfad1
+ file copy tfalink tfalink2
+} -returnCodes error -cleanup {
+ file delete -force tfalink tfalink2
+} -result {error copying "tfalink": the target of this link doesn't exist}
+test fCmd-21.7.2 {TclCopyFilesCmd: copy a dangling link} -setup {
+ catch {file delete -force tfad1 tfalink tfalink2}
+} -constraints {unix notRoot} -body {
+ file mkdir tfad1
+ file link -symbolic tfalink tfad1
+ file delete tfad1
+ file copy tfalink tfalink2
+ file type tfalink2
+} -cleanup {
+ file delete tfalink tfalink2
+} -result link
+test fCmd-21.8.1 {TclCopyFilesCmd: copy a link} -setup {
+ catch {file delete -force tfad1 tfalink tfalink2}
+} -constraints {unix notRoot dontCopyLinks} -body {
+ file mkdir tfad1
+ file link -symbolic tfalink tfad1
+ file copy tfalink tfalink2
+ list [file type tfalink] [file type tfalink2] [file isdir tfad1]
+} -cleanup {
+ file delete -force tfad1 tfalink tfalink2
+} -result {link directory 1}
+test fCmd-21.8.2 {TclCopyFilesCmd: copy a link} -setup {
+ catch {file delete -force tfad1 tfalink tfalink2}
+} -constraints {unix notRoot} -body {
+ file mkdir tfad1
+ file link -symbolic tfalink tfad1
+ file copy tfalink tfalink2
+ list [file type tfalink] [file type tfalink2] [file isdir tfad1]
+} -cleanup {
+ file delete -force tfad1 tfalink tfalink2
+} -result {link link 1}
+test fCmd-21.9 {TclCopyFilesCmd: copy dir with a link in it} -setup {
+ catch {file delete -force tfad1 tfad2}
+} -constraints {unix notRoot} -body {
+ file mkdir tfad1
+ file link -symbolic tfad1/tfalink "[pwd]/tfad1"
+ file copy tfad1 tfad2
+ file type tfad2/tfalink
+} -cleanup {
+ file delete -force tfad1 tfad2
+} -result link
+test fCmd-21.10 {TclFileCopyCmd: copy dir on top of another empty dir w/o -force} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ file mkdir tfa [file join tfad tfa]
+ list [catch {file copy tfa tfad}] [file isdir tfa]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1}
+test fCmd-21.11 {TclFileCopyCmd: copy dir on top of a dir w/o -force} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ file mkdir tfa [file join tfad tfa file]
+ list [catch {file copy tfa tfad}] [file isdir tfa] \
+ [file isdir [file join tfad tfa file]]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1}
+test fCmd-21.12 {TclFileCopyCmd: copy dir on top of a non-empty dir w/ -force} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ file mkdir tfa [file join tfad tfa file]
+ list [catch {file copy -force tfa tfad}] [file isdir tfa] \
+ [file isdir [file join tfad tfa file]]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1}
+
+#
+# Coverage testing for TclpRenameFile
+#
+test fCmd-22.1 {TclpRenameFile: rename and overwrite in a single dir} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ set s [createfile tfa1]
+ set s2 [createfile tfa2 q]
+ set result [catch {file rename tfa1 tfa2}]
+ file rename -force tfa1 tfa2
+ lappend result [checkcontent tfa2 $s]
+} -cleanup {
+ file delete [glob tfa1 tfa2]
+} -result {1 1}
+test fCmd-22.2 {TclpRenameFile: attempt to overwrite itself} -setup {
+ catch {file delete -force -- tfa1}
+} -constraints {unix notRoot} -body {
+ set s [createfile tfa1]
+ file rename -force tfa1 tfa1
+ checkcontent tfa1 $s
+} -cleanup {
+ file delete tfa1
+} -result {1}
+test fCmd-22.3 {TclpRenameFile: rename dir to existing dir} -setup {
+ catch {file delete -force -- d1 tfad}
+} -constraints {notRoot} -body {
+ file mkdir d1 [file join tfad d1]
+ list [catch {file rename d1 tfad}] [file isdir d1] \
+ [file isdir [file join tfad d1]]
+} -cleanup {
+ file delete -force d1 tfad
+} -result {1 1 1}
+test fCmd-22.4 {TclpRenameFile: rename dir to dir several levels deep} -setup {
+ catch {file delete -force -- d1 tfad}
+} -constraints {notRoot} -body {
+ file mkdir d1 [file join tfad a b c]
+ file rename d1 [file join tfad a b c d1]
+ list [file isdir d1] [file isdir [file join tfad a b c d1]]
+} -cleanup {
+ file delete -force [glob d1 tfad]
+} -result {0 1}
+#
+# TclMacCopyFile needs to be redone.
+#
+test fCmd-22.5 {TclMacCopyFile: copy and overwrite in a single dir} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ set s [createfile tfa1]
+ set s2 [createfile tfa2 q]
+ set result [catch {file copy tfa1 tfa2}]
+ file copy -force tfa1 tfa2
+ lappend result [checkcontent tfa2 $s] [checkcontent tfa1 $s]
+} -cleanup {
+ file delete tfa1 tfa2
+} -result {1 1 1}
+
+#
+# TclMacMkdir - basic cases are covered elsewhere.
+# Error cases are not covered.
+#
+
+#
+# TclMacRmdir
+# Error cases are not covered.
+#
+test fCmd-23.1 {TclMacRmdir: trying to remove a nonempty directory} -setup {
+ catch {file delete -force -- tfad}
+} -constraints {notRoot} -body {
+ file mkdir [file join tfad dir]
+ list [catch {file delete tfad}] [file delete -force tfad]
+} -cleanup {
+ catch {file delete -force tfad}
+} -result {1 {}}
+
+#
+# TclMacDeleteFile
+# Error cases are not covered.
+#
+test fCmd-24.1 {TclMacDeleteFile: deleting a normal file} -setup {
+ catch {file delete -force -- tfa1}
+} -constraints {notRoot} -body {
+ createfile tfa1
+ file delete tfa1
+ file exists tfa1
+} -cleanup {
+ catch {file delete -force tfa1}
+} -result {0}
+
+#
+# TclMacCopyDirectory
+# Error cases are not covered.
+#
+test fCmd-25.1 {TclMacCopyDirectory: copying a normal directory} -setup {
+ catch {file delete -force -- tfad1 tfad2}
+} -constraints {notRoot notFileSharing} -body {
+ file mkdir [file join tfad1 a b c]
+ file copy tfad1 tfad2
+ list [file isdir [file join tfad1 a b c]] \
+ [file isdir [file join tfad2 a b c]]
+} -cleanup {
+ file delete -force tfad1 tfad2
+} -result {1 1}
+test fCmd-25.2 {TclMacCopyDirectory: copying a short path normal directory} -setup {
+ catch {file delete -force -- tfad1 tfad2}
+} -constraints {notRoot notFileSharing} -body {
+ file mkdir tfad1
+ file copy tfad1 tfad2
+ list [file isdir tfad1] [file isdir tfad2]
+} -cleanup {
+ file delete tfad1 tfad2
+} -result {1 1}
+test fCmd-25.3 {TclMacCopyDirectory: copying dirs between different dirs} -setup {
+ catch {file delete -force -- tfad1 tfad2}
+} -constraints {notRoot notFileSharing} -body {
+ file mkdir [file join tfad1 x y z]
+ file mkdir [file join tfad2 dir]
+ file copy tfad1 [file join tfad2 dir]
+ list [file isdir [file join tfad1 x y z]] \
+ [file isdir [file join tfad2 dir tfad1 x y z]]
+} -cleanup {
+ file delete -force tfad1 tfad2
+} -result {1 1}
+
+#
+# Functionality tests for TclDeleteFilesCmd
+#
+test fCmd-26.1 {TclDeleteFilesCmd: delete symlink} -setup {
+ catch {file delete -force -- tfad1 tfad2}
+} -constraints {unix notRoot} -body {
+ file mkdir tfad1
+ file link -symbolic tfalink tfad1
+ file delete tfalink
+ list [file isdir tfad1] [file exists tfalink]
+} -cleanup {
+ file delete tfad1
+ catch {file delete tfalink}
+} -result {1 0}
+test fCmd-26.2 {TclDeleteFilesCmd: delete dir with symlink} -setup {
+ catch {file delete -force -- tfad1 tfad2}
+} -constraints {unix notRoot} -body {
+ file mkdir tfad1
+ file mkdir tfad2
+ file link -symbolic [file join tfad2 link] [file join .. tfad1]
+ file delete -force tfad2
+ list [file isdir tfad1] [file exists tfad2]
+} -cleanup {
+ file delete tfad1
+} -result {1 0}
+test fCmd-26.3 {TclDeleteFilesCmd: delete dangling symlink} -setup {
+ catch {file delete -force -- tfad1 tfad2}
+} -constraints {unix notRoot} -body {
+ file mkdir tfad1
+ file link -symbolic tfad2 tfad1
+ file delete tfad1
+ file delete tfad2
+ list [file exists tfad1] [file exists tfad2]
+} -result {0 0}
+
+# There is no fCmd-27.1
+test fCmd-27.2 {TclFileAttrsCmd - Tcl_TranslateFileName fails} -setup {
+ set platform [testgetplatform]
+} -constraints {testsetplatform} -body {
+ testsetplatform unix
+ file attributes ~_totally_bogus_user
+} -returnCodes error -cleanup {
+ testsetplatform $platform
+} -result {user "_totally_bogus_user" doesn't exist}
+test fCmd-27.3 {TclFileAttrsCmd - all attributes} -setup {
+ catch {file delete -force -- foo.tmp}
+} -body {
+ createfile foo.tmp
+ file attributes foo.tmp
+ # Must be non-empty result
+} -cleanup {
+ file delete -force -- foo.tmp
+} -match glob -result {?*}
+test fCmd-27.4 {TclFileAttrsCmd - getting one option} -setup {
+ catch {file delete -force -- foo.tmp}
+} -body {
+ createfile foo.tmp
+ set attrs [file attributes foo.tmp]
+ file attributes foo.tmp {*}[lindex $attrs 0]
+ # Any successful result will do
+} -cleanup {
+ file delete -force -- foo.tmp
+} -match glob -result *
+test fCmd-27.5 {TclFileAttrsCmd - setting one option} -setup {
+ catch {file delete -force -- foo.tmp}
+} -constraints {foundGroup} -body {
+ createfile foo.tmp
+ set attrs [file attributes foo.tmp]
+ file attributes foo.tmp {*}[lrange $attrs 0 1]
+} -cleanup {
+ file delete -force -- foo.tmp
+} -result {}
+test fCmd-27.6 {TclFileAttrsCmd - setting more than one option} -setup {
+ catch {file delete -force -- foo.tmp}
+} -constraints {foundGroup} -body {
+ createfile foo.tmp
+ set attrs [file attributes foo.tmp]
+ file attributes foo.tmp {*}[lrange $attrs 0 3]
+} -cleanup {
+ file delete -force -- foo.tmp
+} -result {}
+
+if {
+ [testConstraint win] &&
+ ([string index $tcl_platform(osVersion) 0] < 5
+ || [lindex [file system [temporaryDirectory]] 1] ne "NTFS")
+} then {
+ testConstraint linkDirectory 0
+ testConstraint linkFile 0
+}
+
+test fCmd-28.1 {file link} -returnCodes error -body {
+ file link
+} -result {wrong # args: should be "file link ?-linktype? linkname ?target?"}
+test fCmd-28.2 {file link} -returnCodes error -body {
+ file link a b c d
+} -result {wrong # args: should be "file link ?-linktype? linkname ?target?"}
+test fCmd-28.3 {file link} -returnCodes error -body {
+ file link abc b c
+} -result {bad switch "abc": must be -symbolic or -hard}
+test fCmd-28.4 {file link} -returnCodes error -body {
+ file link -abc b c
+} -result {bad switch "-abc": must be -symbolic or -hard}
+cd [workingDirectory]
+makeDirectory abc.dir
+makeDirectory abc2.dir
+makeFile contents abc.file
+makeFile contents abc2.file
+cd [temporaryDirectory]
+test fCmd-28.5 {file link: source already exists} -setup {
+ cd [temporaryDirectory]
+} -constraints {linkDirectory} -body {
+ file link abc.dir abc2.dir
+} -returnCodes error -cleanup {
+ cd [workingDirectory]
+} -result {could not create new link "abc.dir": that path already exists}
+test fCmd-28.6 {file link: unsupported operation} -setup {
+ cd [temporaryDirectory]
+} -constraints {linkDirectory win} -body {
+ file link -hard abc.link abc.dir
+} -returnCodes error -cleanup {
+ cd [workingDirectory]
+} -result {could not create new link "abc.link" pointing to "abc.dir": illegal operation on a directory}
+test fCmd-28.7 {file link: source already exists} -setup {
+ cd [temporaryDirectory]
+} -constraints {linkFile} -body {
+ file link abc.file abc2.file
+} -returnCodes error -cleanup {
+ cd [workingDirectory]
+} -result {could not create new link "abc.file": that path already exists}
+test fCmd-28.8 {file link} -constraints {linkFile win} -setup {
+ cd [temporaryDirectory]
+} -body {
+ file link -symbolic abc.link abc.file
+} -returnCodes error -cleanup {
+ cd [workingDirectory]
+} -result {could not create new link "abc.link" pointing to "abc.file": not a directory}
+test fCmd-28.9 {file link: success with file} -constraints {linkFile} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -body {
+ file link abc.link abc.file
+} -cleanup {
+ cd [workingDirectory]
+} -result abc.file
+test fCmd-28.9.1 {file link: success with file} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -constraints {linkFile win} -body {
+ file stat abc.file arr
+ set res $arr(nlink)
+ lappend res [catch {file link abc.link abc.file} msg] $msg
+ file stat abc.file arr
+ lappend res $arr(nlink)
+} -cleanup {
+ cd [workingDirectory]
+} -result {1 0 abc.file 2}
+cd [temporaryDirectory]
+catch {file delete -force abc.link}
+cd [workingDirectory]
+test fCmd-28.10 {file link: linking to nonexistent path} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -constraints {linkDirectory} -body {
+ file link abc.link abc2.doesnt
+} -returnCodes error -cleanup {
+ cd [workingDirectory]
+} -result {could not create new link "abc.link": target "abc2.doesnt" doesn't exist}
+test fCmd-28.10.1 {file link: linking to nonexistent path} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -constraints {linkDirectory} -body {
+ file link doesnt/abc.link abc.dir
+} -returnCodes error -cleanup {
+ cd [workingDirectory]
+} -result {could not create new link "doesnt/abc.link": no such file or directory}
+test fCmd-28.11 {file link: success with directory} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -constraints {linkDirectory} -body {
+ file link abc.link abc.dir
+} -cleanup {
+ cd [workingDirectory]
+} -result abc.dir
+test fCmd-28.12 {file link: cd into a link} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -constraints {linkDirectory} -body {
+ file link abc.link abc.dir
+ set orig [pwd]
+ cd abc.link
+ set dir [pwd]
+ cd ..
+ set up [pwd]
+ cd $orig
+ # Now '$up' should be either $orig or [file dirname abc.dir], depending on
+ # whether 'cd' actually moves to the destination of a link, or simply
+ # treats the link as a directory. (On windows the former, on unix the
+ # latter, I believe)
+ if {
+ ([file normalize $up] ne [file normalize $orig]) &&
+ ([file normalize $up] ne [file normalize [file dirname abc.dir]])
+ } then {
+ return "wrong directory with 'cd abc.link ; cd ..': \
+ \"[file normalize $up]\" should be \"[file normalize $orig]\"\
+ or \"[file normalize [file dirname abc.dir]]\""
+ } else {
+ return "ok"
+ }
+} -cleanup {
+ cd [workingDirectory]
+} -result ok
+test fCmd-28.13 {file link} -constraints {linkDirectory} -setup {
+ cd [temporaryDirectory]
+} -body {
+ # duplicate link throws error
+ file link abc.link abc.dir
+} -returnCodes error -cleanup {
+ cd [workingDirectory]
+} -result {could not create new link "abc.link": that path already exists}
+test fCmd-28.14 {file link: deletes link not dir} -setup {
+ cd [temporaryDirectory]
+} -constraints {linkDirectory} -body {
+ file delete -force abc.link
+ list [file exists abc.link] [file exists abc.dir]
+} -cleanup {
+ cd [workingDirectory]
+} -result {0 1}
+test fCmd-28.15.1 {file link: copies link not dir} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -constraints {linkDirectory dontCopyLinks} -body {
+ file link abc.link abc.dir
+ file copy abc.link abc2.link
+ # abc2.linkdir was a copy of a link to a dir, so it should end up as a
+ # directory, not a link (links trace to endpoint).
+ list [file type abc2.link] [file tail [file link abc.link]]
+} -cleanup {
+ cd [workingDirectory]
+} -result {directory abc.dir}
+test fCmd-28.15.2 {file link: copies link not dir} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -constraints {linkDirectory} -body {
+ file link abc.link abc.dir
+ file copy abc.link abc2.link
+ list [file type abc2.link] [file tail [file link abc2.link]]
+} -cleanup {
+ cd [workingDirectory]
+} -result {link abc.dir}
+cd [temporaryDirectory]
+file delete -force abc.link
+file delete -force abc2.link
+cd abc.dir
+file delete -force abc.file
+file delete -force abc2.file
+cd ..
+file copy abc.file abc.dir
+file copy abc2.file abc.dir
+cd [workingDirectory]
+test fCmd-28.16 {file link: glob inside link} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -constraints {linkDirectory} -body {
+ file link abc.link abc.dir
+ lsort [glob -dir abc.link -tails *]
+} -cleanup {
+ cd [workingDirectory]
+} -result {abc.file abc2.file}
+test fCmd-28.17 {file link: glob -type l} -setup {
+ cd [temporaryDirectory]
+} -constraints {linkDirectory} -body {
+ glob -dir [pwd] -type l -tails abc*
+} -cleanup {
+ cd [workingDirectory]
+} -result {abc.link}
+test fCmd-28.18 {file link: glob -type d} -constraints linkDirectory -setup {
+ cd [temporaryDirectory]
+} -body {
+ lsort [glob -dir [pwd] -type d -tails abc*]
+} -cleanup {
+ cd [workingDirectory]
+} -result [lsort [list abc.link abc.dir abc2.dir]]
+test fCmd-28.19 {file link: relative paths} -setup {
+ cd [temporaryDirectory]
+} -constraints {win linkDirectory} -body {
+ file mkdir d1/d2/d3
+ file link d1/l2 d1/d2
+} -cleanup {
+ catch {file delete -force d1}
+ cd [workingDirectory]
+} -result d1/d2
+test fCmd-28.20 {file link: relative paths} -setup {
+ cd [temporaryDirectory]
+} -constraints {unix linkDirectory} -body {
+ file mkdir d1/d2/d3
+ file link d1/l2 d1/d2
+} -returnCodes error -cleanup {
+ catch {file delete -force d1}
+ cd [workingDirectory]
+} -result {could not create new link "d1/l2": target "d1/d2" doesn't exist}
+test fCmd-28.21 {file link: relative paths} -setup {
+ cd [temporaryDirectory]
+} -constraints {unix linkDirectory} -body {
+ file mkdir d1/d2/d3
+ file link d1/l2 d2
+} -cleanup {
+ catch {file delete -force d1}
+ cd [workingDirectory]
+} -result d2
+test fCmd-28.22 {file link: relative paths} -setup {
+ cd [temporaryDirectory]
+} -constraints {unix linkDirectory} -body {
+ file mkdir d1/d2/d3
+ catch {file delete -force d1/l2}
+ file link d1/l2 d2/d3
+} -cleanup {
+ catch {file delete -force d1}
+ cd [workingDirectory]
+} -result d2/d3
+try {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+ file delete -force d1/d2
+ file delete -force d1
+} finally {
+ cd [workingDirectory]
+}
+removeFile abc2.file
+removeFile abc.file
+removeDirectory abc2.dir
+removeDirectory abc.dir
+
+test fCmd-29.1 {weird memory corruption fault} -body {
+ open [file join ~a_totally_bogus_user_id/foo bar]
+} -returnCodes error -match glob -result *
+
+test fCmd-30.1 {file writable on 'My Documents'} -setup {
+ # Get the localized version of the folder name by looking in the registry.
+ set mydocsname [registry get {HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders} Personal]
+} -constraints {win reg} -body {
+ file writable $mydocsname
+} -result 1
+test fCmd-30.2 {file readable on 'NTUSER.DAT'} -constraints {win} -body {
+ expr {[info exists env(USERPROFILE)]
+ && [file exists $env(USERPROFILE)/NTUSER.DAT]
+ && [file readable $env(USERPROFILE)/NTUSER.DAT]}
+} -result {1}
+test fCmd-30.3 {file readable on 'pagefile.sys'} -constraints {win} -body {
+ set r {}
+ if {[info exists env(SystemDrive)]} {
+ set path $env(SystemDrive)/pagefile.sys
+ lappend r exists [file exists $path]
+ lappend r readable [file readable $path]
+ lappend r stat [catch {file stat $path a} e] $e
+ }
+ return $r
+} -result {exists 1 readable 0 stat 0 {}}
+
+# cleanup
+cleanup
+if {[testConstraint unix]} {
+ removeDirectory tcl[pid] /tmp
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/fileName.test b/library/msgcat/tests/fileName.test
new file mode 100644
index 0000000..affacff
--- /dev/null
+++ b/library/msgcat/tests/fileName.test
@@ -0,0 +1,1627 @@
+# This file tests the filename manipulation routines.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testsetplatform [llength [info commands testsetplatform]]
+testConstraint testtranslatefilename [llength [info commands testtranslatefilename]]
+testConstraint linkDirectory 1
+testConstraint symbolicLinkFile 1
+if {[testConstraint win]} {
+ if {[string index $tcl_platform(osVersion) 0] < 5 \
+ || [lindex [file system [temporaryDirectory]] 1] ne "NTFS"} {
+ testConstraint linkDirectory 0
+ }
+ testConstraint symbolicLinkFile 0
+ testConstraint sharedCdrive [expr {![catch {cd //[info hostname]/c}]}]
+}
+# This match compares the first two words of the result. If the wanted result
+# is "equal", then this is successful if the words are equal. If the wanted
+# result is "not equal", then this is successful if the words are different.
+customMatch compareWords {apply {{a b} {
+ lassign $b w1 w2
+ expr {$a eq "equal" ? $w1 eq $w2 : $w1 ne $w2}
+}}}
+
+proc touch filename {catch {close [open $filename w]}}
+global env
+if {[testConstraint testsetplatform]} {
+ set platform [testgetplatform]
+}
+
+# Caution: when using 'testsetplatform' to test different file name platform
+# descriptions in this file, one must be very careful not to combine such
+# platform manipulation with commands like 'cd', 'pwd'. That is because the
+# latter commands operate on the real filesystem but will potentially have
+# their logic routed through the wrong generic code paths if we've used
+# 'testsetplatform'. This can lead to serious problems, even crashes.
+test filename-1.1 {Tcl_GetPathType: unix} {testsetplatform} {
+ testsetplatform unix
+ file pathtype /
+} absolute
+test filename-1.2 {Tcl_GetPathType: unix} {testsetplatform} {
+ testsetplatform unix
+ file pathtype /foo
+} absolute
+test filename-1.3 {Tcl_GetPathType: unix} {testsetplatform} {
+ testsetplatform unix
+ file pathtype foo
+} relative
+test filename-1.4 {Tcl_GetPathType: unix} {testsetplatform} {
+ testsetplatform unix
+ file pathtype c:/foo
+} relative
+test filename-1.5 {Tcl_GetPathType: unix} {testsetplatform} {
+ testsetplatform unix
+ file pathtype ~
+} absolute
+test filename-1.6 {Tcl_GetPathType: unix} {testsetplatform} {
+ testsetplatform unix
+ file pathtype ~/foo
+} absolute
+test filename-1.7 {Tcl_GetPathType: unix} {testsetplatform} {
+ testsetplatform unix
+ file pathtype ~foo
+} absolute
+test filename-1.8 {Tcl_GetPathType: unix} {testsetplatform} {
+ testsetplatform unix
+ file pathtype ./~foo
+} relative
+
+test filename-3.1 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype /
+} volumerelative
+test filename-3.2 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype \\
+} volumerelative
+test filename-3.3 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype /foo
+} volumerelative
+test filename-3.4 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype \\foo
+} volumerelative
+test filename-3.5 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype c:/
+} absolute
+test filename-3.6 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype c:\\
+} absolute
+test filename-3.7 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype c:/foo
+} absolute
+test filename-3.8 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype c:\\foo
+} absolute
+test filename-3.9 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype c:
+} volumerelative
+test filename-3.10 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype c:foo
+} volumerelative
+test filename-3.11 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype foo
+} relative
+test filename-3.12 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype //foo/bar
+} absolute
+test filename-3.13 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype ~foo
+} absolute
+test filename-3.14 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype ~
+} absolute
+test filename-3.15 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype ~/foo
+} absolute
+test filename-3.16 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype ./~foo
+} relative
+
+test filename-4.1 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split /
+} {/}
+test filename-4.2 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split /foo
+} {/ foo}
+test filename-4.3 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split /foo/bar
+} {/ foo bar}
+test filename-4.4 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split /foo/bar/baz
+} {/ foo bar baz}
+test filename-4.5 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split foo/bar
+} {foo bar}
+test filename-4.6 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split ./foo/bar
+} {. foo bar}
+test filename-4.7 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split /foo/../././foo/bar
+} {/ foo .. . . foo bar}
+test filename-4.8 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split ../foo/bar
+} {.. foo bar}
+test filename-4.9 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split {}
+} {}
+test filename-4.10 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split .
+} {.}
+test filename-4.11 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split ../
+} {..}
+test filename-4.12 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split ../..
+} {.. ..}
+test filename-4.13 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split //foo
+} {/ foo}
+test filename-4.14 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split foo//bar
+} {foo bar}
+test filename-4.15 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split ~foo
+} {~foo}
+test filename-4.16 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split ~foo/~bar
+} {~foo ./~bar}
+test filename-4.17 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split ~foo/~bar/~baz
+} {~foo ./~bar ./~baz}
+test filename-4.18 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split foo/bar~/baz
+} {foo bar~ baz}
+if {[testConstraint testsetplatform]} {
+ testsetplatform $platform
+}
+test filename-4.19 {Tcl_SplitPath} -setup {
+ set oldDir [pwd]
+ cd [temporaryDirectory]
+} -body {
+ file mkdir tildetmp
+ set nastydir [file join tildetmp ./~tilde]
+ file mkdir $nastydir
+ set norm [file normalize $nastydir]
+ cd tildetmp
+ cd ./~tilde
+ glob -nocomplain *
+ set idx [string first tildetmp $norm]
+ set norm [string range $norm $idx end]
+ # fix path away so all platforms are the same
+ regsub {(.*):$} $norm {\1} norm
+ regsub -all ":" $norm "/" norm
+ # make sure we can delete the directory we created
+ cd $oldDir
+ file delete -force $nastydir
+ return $norm
+} -cleanup {
+ cd $oldDir
+ catch {file delete -force [file join [temporaryDirectory] tildetmp]}
+} -result {tildetmp/~tilde}
+
+test filename-6.1 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split /
+} {/}
+test filename-6.2 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split /foo
+} {/ foo}
+test filename-6.3 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split /foo/bar
+} {/ foo bar}
+test filename-6.4 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split /foo/bar/baz
+} {/ foo bar baz}
+test filename-6.5 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split foo/bar
+} {foo bar}
+test filename-6.6 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split ./foo/bar
+} {. foo bar}
+test filename-6.7 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split /foo/../././foo/bar
+} {/ foo .. . . foo bar}
+test filename-6.8 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split ../foo/bar
+} {.. foo bar}
+test filename-6.9 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split {}
+} {}
+test filename-6.10 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split .
+} {.}
+test filename-6.11 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split ../
+} {..}
+test filename-6.12 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split ../..
+} {.. ..}
+test filename-6.13 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split //foo
+} {/ foo}
+test filename-6.14 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split foo//bar
+} {foo bar}
+test filename-6.15 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split /\\/foo//bar
+} {//foo/bar}
+test filename-6.16 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split /\\/foo//bar
+} {//foo/bar}
+test filename-6.17 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split /\\/foo//bar
+} {//foo/bar}
+test filename-6.18 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split \\\\foo\\bar
+} {//foo/bar}
+test filename-6.19 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split \\\\foo\\bar/baz
+} {//foo/bar baz}
+test filename-6.20 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split c:/foo
+} {c:/ foo}
+test filename-6.21 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split c:foo
+} {c: foo}
+test filename-6.22 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split c:
+} {c:}
+test filename-6.23 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split c:\\
+} {c:/}
+test filename-6.24 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split c:/
+} {c:/}
+test filename-6.25 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split c:/./..
+} {c:/ . ..}
+test filename-6.26 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split ~foo
+} {~foo}
+test filename-6.27 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split ~foo/~bar
+} {~foo ./~bar}
+test filename-6.28 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split ~foo/~bar/~baz
+} {~foo ./~bar ./~baz}
+test filename-6.29 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split foo/bar~/baz
+} {foo bar~ baz}
+test filename-6.30 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split c:~foo
+} {c: ./~foo}
+
+test filename-7.1 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join / a
+} {/a}
+test filename-7.2 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join a b
+} {a/b}
+test filename-7.3 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join /a c /b d
+} {/b/d}
+test filename-7.4 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join /
+} {/}
+test filename-7.5 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join a
+} {a}
+test filename-7.6 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join {}
+} {}
+test filename-7.7 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join /a/ b
+} {/a/b}
+test filename-7.8 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join /a// b
+} {/a/b}
+test filename-7.9 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join /a/./../. b
+} {/a/./.././b}
+test filename-7.10 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join ~ a
+} {~/a}
+test filename-7.11 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join ~a ~b
+} {~b}
+test filename-7.12 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join ./~a b
+} {./~a/b}
+test filename-7.13 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join ./~a ~b
+} {~b}
+test filename-7.14 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join ./~a ./~b
+} {./~a/~b}
+test filename-7.15 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join a . b
+} {a/./b}
+test filename-7.16 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join a . ./~b
+} {a/./~b}
+test filename-7.17 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join //a b
+} {/a/b}
+test filename-7.18 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join /// a b
+} {/a/b}
+
+test filename-9.1 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join a b
+} {a/b}
+test filename-9.2 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join /a b
+} {/a/b}
+test filename-9.3 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join /a /b
+} {/b}
+test filename-9.4 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join c: foo
+} {c:foo}
+test filename-9.5 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join c:/ foo
+} {c:/foo}
+test filename-9.6 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join c:\\bar foo
+} {c:/bar/foo}
+test filename-9.7 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join /foo c:bar
+} {c:bar}
+test filename-9.8 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join ///host//share dir
+} {//host/share/dir}
+test filename-9.9 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join ~ foo
+} {~/foo}
+test filename-9.10 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join ~/~foo
+} {~/~foo}
+test filename-9.11 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join ~ ./~foo
+} {~/~foo}
+test filename-9.12 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join / ~foo
+} {~foo}
+test filename-9.13 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join ./a/ b c
+} {./a/b/c}
+test filename-9.14 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join ./~a/ b c
+} {./~a/b/c}
+test filename-9.15 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join // host share path
+} {/host/share/path}
+test filename-9.16 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join foo . bar
+} {foo/./bar}
+test filename-9.17 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join foo .. bar
+} {foo/../bar}
+test filename-9.18 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join foo/./bar
+} {foo/./bar}
+test filename-9.19 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ set res {}
+ lappend res \
+ [file join {C:\foo\bar}] \
+ [file join C:/blah {C:\foo\bar}] \
+ [file join C:/blah C:/blah {C:\foo\bar}]
+} {C:/foo/bar C:/foo/bar C:/foo/bar}
+test filename-9.19.1 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ set res {}
+ lappend res \
+ [file join {foo\bar}] \
+ [file join C:/blah {foo\bar}] \
+ [file join C:/blah C:/blah {foo\bar}]
+} {foo/bar C:/blah/foo/bar C:/blah/foo/bar}
+test filename-9.19.2 {Tcl_JoinPath: win} {testsetplatform win} {
+ testsetplatform win
+ set res {}
+ lappend res \
+ [file join {foo\bar}] \
+ [file join [pwd] {foo\bar}] \
+ [file join [pwd] [pwd] {foo\bar}]
+ set nres {}
+ foreach elt $res {
+ lappend nres [string map [list [pwd] pwd] $elt]
+ }
+ set nres
+} {foo/bar pwd/foo/bar pwd/foo/bar}
+test filename-9.20 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ set res {}
+ lappend res \
+ [file join {/foo/bar}] \
+ [file join /x {/foo/bar}] \
+ [file join /x /x {/foo/bar}]
+} {/foo/bar /foo/bar /foo/bar}
+test filename-9.23 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ set res {}
+ lappend res \
+ [file join {foo\bar}] \
+ [file join C:/blah {foo\bar}] \
+ [file join C:/blah C:/blah {foo\bar}]
+ string map [list C:/blah ""] $res
+} {foo/bar /foo/bar /foo/bar}
+test filename-9.24 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ set res {}
+ lappend res \
+ [file join {foo/bar}] \
+ [file join /x {foo/bar}] \
+ [file join /x /x {foo/bar}]
+ string map [list /x ""] $res
+} {foo/bar /foo/bar /foo/bar}
+
+test filename-10.1 {Tcl_TranslateFileName} -body {
+ testsetplatform unix
+ testtranslatefilename foo
+} -result {foo} -constraints {testsetplatform testtranslatefilename}
+test filename-10.2 {Tcl_TranslateFileName} -body {
+ testsetplatform windows
+ testtranslatefilename {c:/foo}
+} -result {c:\foo} -constraints {testsetplatform testtranslatefilename}
+test filename-10.3 {Tcl_TranslateFileName} -body {
+ testsetplatform windows
+ testtranslatefilename {c:/\\foo/}
+} -result {c:\foo} -constraints {testsetplatform testtranslatefilename}
+test filename-10.3.1 {Tcl_TranslateFileName} -body {
+ testsetplatform windows
+ testtranslatefilename {c://///}
+} -result c:\\ -constraints {testsetplatform testtranslatefilename}
+test filename-10.6 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ set env(HOME) "/home/test"
+ testsetplatform unix
+ testtranslatefilename ~/foo
+} -cleanup {
+ set env(HOME) $temp
+} -result {/home/test/foo}
+test filename-10.7 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ unset env(HOME)
+ testsetplatform unix
+ testtranslatefilename ~/foo
+} -returnCodes error -cleanup {
+ set env(HOME) $temp
+} -result {couldn't find HOME environment variable to expand path}
+test filename-10.8 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ set env(HOME) "/home/test"
+ testsetplatform unix
+ testtranslatefilename ~
+} -cleanup {
+ set env(HOME) $temp
+} -result {/home/test}
+test filename-10.9 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ set env(HOME) "/home/test/"
+ testsetplatform unix
+ testtranslatefilename ~
+} -cleanup {
+ set env(HOME) $temp
+} -result {/home/test}
+test filename-10.10 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ set env(HOME) "/home/test/"
+ testsetplatform unix
+ testtranslatefilename ~/foo
+} -cleanup {
+ set env(HOME) $temp
+} -result {/home/test/foo}
+test filename-10.17 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ set env(HOME) "\\home\\"
+ testsetplatform windows
+ testtranslatefilename ~/foo
+} -cleanup {
+ set env(HOME) $temp
+} -result {\home\foo}
+test filename-10.18 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ set env(HOME) "\\home\\"
+ testsetplatform windows
+ testtranslatefilename ~/foo\\bar
+} -cleanup {
+ set env(HOME) $temp
+} -result {\home\foo\bar}
+test filename-10.19 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ set env(HOME) "c:"
+ testsetplatform windows
+ testtranslatefilename ~/foo
+} -cleanup {
+ set env(HOME) $temp
+} -result {c:foo}
+test filename-10.20 {Tcl_TranslateFileName} -returnCodes error -body {
+ testtranslatefilename ~blorp/foo
+} -constraints {testtranslatefilename testtranslatefilename} \
+ -result {user "blorp" doesn't exist}
+test filename-10.21 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ set env(HOME) "c:\\"
+ testsetplatform windows
+ testtranslatefilename ~/foo
+} -cleanup {
+ set env(HOME) $temp
+} -result {c:\foo}
+test filename-10.22 {Tcl_TranslateFileName} -body {
+ testsetplatform windows
+ testtranslatefilename foo//bar
+} -constraints {testsetplatform testtranslatefilename} -result {foo\bar}
+if {[testConstraint testsetplatform]} {
+ testsetplatform $platform
+}
+test filename-10.23 {Tcl_TranslateFileName} -body {
+ # this test fails if ~ouster is not /home/ouster
+ testtranslatefilename ~ouster
+} -constraints {nonPortable testtranslatefilename} -result {/home/ouster}
+test filename-10.24 {Tcl_TranslateFileName} -body {
+ # this test fails if ~ouster is not /home/ouster
+ testtranslatefilename ~ouster/foo
+} -result {/home/ouster/foo} -constraints {nonPortable testtranslatefilename}
+
+test filename-11.1 {Tcl_GlobCmd} -returnCodes error -body {
+ glob
+} -result {no files matched glob patterns ""}
+test filename-11.2 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -gorp
+} -result {bad option "-gorp": must be -directory, -join, -nocomplain, -path, -tails, -types, or --}
+test filename-11.3 {Tcl_GlobCmd} -body {
+ glob -nocomplai
+} -result {}
+test filename-11.4 {Tcl_GlobCmd} -body {
+ glob -nocomplain
+} -result {}
+test filename-11.5 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -nocomplain * ~xyqrszzz
+} -result {user "xyqrszzz" doesn't exist}
+test filename-11.6 {Tcl_GlobCmd} -returnCodes error -body {
+ glob ~xyqrszzz
+} -result {user "xyqrszzz" doesn't exist}
+test filename-11.7 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -- -nocomplain
+} -result {no files matched glob pattern "-nocomplain"}
+test filename-11.8 {Tcl_GlobCmd} -body {
+ glob -nocomplain -- -nocomplain
+} -result {}
+test filename-11.9 {Tcl_GlobCmd} -constraints {testsetplatform} -body {
+ testsetplatform unix
+ glob ~\\xyqrszzz/bar
+} -returnCodes error -result {user "\xyqrszzz" doesn't exist}
+test filename-11.10 {Tcl_GlobCmd} -constraints {testsetplatform} -body {
+ testsetplatform unix
+ glob -nocomplain ~\\xyqrszzz/bar
+} -returnCodes error -result {user "\xyqrszzz" doesn't exist}
+test filename-11.11 {Tcl_GlobCmd} -constraints {testsetplatform} -body {
+ testsetplatform unix
+ glob ~xyqrszzz\\/\\bar
+} -returnCodes error -result {user "xyqrszzz" doesn't exist}
+test filename-11.12 {Tcl_GlobCmd} -constraints {testsetplatform} -setup {
+ testsetplatform unix
+ set home $env(HOME)
+} -body {
+ unset env(HOME)
+ glob ~/*
+} -returnCodes error -cleanup {
+ set env(HOME) $home
+} -result {couldn't find HOME environment variable to expand path}
+if {[testConstraint testsetplatform]} {
+ testsetplatform $platform
+}
+test filename-11.13 {Tcl_GlobCmd} {
+ file join [lindex [glob ~] 0]
+} [file join $env(HOME)]
+set oldpwd [pwd]
+set oldhome $env(HOME)
+cd [temporaryDirectory]
+set env(HOME) [pwd]
+file delete -force globTest
+file mkdir globTest/a1/b1
+file mkdir globTest/a1/b2
+file mkdir globTest/a2/b3
+file mkdir globTest/a3
+touch globTest/x1.c
+touch globTest/y1.c
+touch globTest/z1.c
+touch "globTest/weird name.c"
+touch globTest/a1/b1/x2.c
+touch globTest/a1/b2/y2.c
+touch globTest/.1
+touch globTest/x,z1.c
+test filename-11.14 {Tcl_GlobCmd} {
+ glob ~/globTest
+} [list [file join $env(HOME) globTest]]
+test filename-11.15 {Tcl_GlobCmd} {
+ glob ~\\/globTest
+} [list [file join $env(HOME) globTest]]
+test filename-11.16 {Tcl_GlobCmd} {
+ glob globTest
+} {globTest}
+set globname "globTest"
+set horribleglobname "glob\[\{Test"
+test filename-11.17 {Tcl_GlobCmd} {unix} {
+ lsort [glob -directory $globname *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.17.1 {Tcl_GlobCmd} {win} {
+ lsort [glob -directory $globname *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname .1]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.17.2 {Tcl_GlobCmd} -setup {
+ set dir [pwd]
+} -constraints {notRoot linkDirectory} -body {
+ cd $globname
+ file link -symbolic link a1
+ cd $dir
+ lsort [glob -directory $globname -join * b1]
+} -cleanup {
+ cd $dir
+ file delete [file join $globname link]
+} -result [list [file join $globname a1 b1] \
+ [file join $globname link b1]]
+# Simpler version of the above test to illustrate a given bug.
+test filename-11.17.3 {Tcl_GlobCmd} -setup {
+ set dir [pwd]
+} -constraints {notRoot linkDirectory} -body {
+ cd $globname
+ file link -symbolic link a1
+ cd $dir
+ lsort [glob -directory $globname -type d *]
+} -cleanup {
+ cd $dir
+ file delete [file join $globname link]
+} -result [list [file join $globname a1] \
+ [file join $globname a2] \
+ [file join $globname a3] \
+ [file join $globname link]]
+# Make sure the bugfix isn't too simple. We don't want to break 'glob -type l'
+test filename-11.17.4 {Tcl_GlobCmd} -setup {
+ set dir [pwd]
+} -constraints {notRoot linkDirectory} -body {
+ cd $globname
+ file link -symbolic link a1
+ cd $dir
+ lsort [glob -directory $globname -type l *]
+} -cleanup {
+ cd $dir
+ file delete [file join $globname link]
+} -result [list [file join $globname link]]
+test filename-11.17.5 {Tcl_GlobCmd} {
+ lsort [glob -directory $globname -tails *.c]
+} [lsort [list "weird name.c" x,z1.c x1.c y1.c z1.c]]
+test filename-11.17.6 {Tcl_GlobCmd} {
+ lsort [glob -directory $globname -tails *.c *.c]
+} [lsort [concat [list "weird name.c" x,z1.c x1.c y1.c z1.c] \
+ [list "weird name.c" x,z1.c x1.c y1.c z1.c]]]
+test filename-11.17.7 {Tcl_GlobCmd: broken link and glob -l} -setup {
+ set dir [pwd]
+} -constraints {linkDirectory} -body {
+ cd $globname
+ file mkdir nonexistent
+ file link -symbolic link nonexistent
+ file delete nonexistent
+ cd $dir
+ lsort [glob -nocomplain -directory $globname -type l *]
+} -cleanup {
+ cd $dir
+ file delete [file join $globname link]
+} -result [list [file join $globname link]]
+test filename-11.17.8 {Tcl_GlobCmd: broken link and glob -l} -setup {
+ set dir [pwd]
+} -constraints {symbolicLinkFile} -body {
+ cd $globname
+ touch "nonexistent"
+ file link -symbolic link nonexistent
+ file delete nonexistent
+ cd $dir
+ lsort [glob -nocomplain -directory $globname -type l *]
+} -cleanup {
+ cd $dir
+ file delete [file join $globname link]
+} -result [list [file join $globname link]]
+test filename-11.18 {Tcl_GlobCmd} {unix} {
+ lsort [glob -path $globname/ *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.18.1 {Tcl_GlobCmd} {win} {
+ lsort [glob -path $globname/ *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname .1]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.19 {Tcl_GlobCmd} {unix} {
+ lsort [glob -join -path [string range $globname 0 5] * *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.19.1 {Tcl_GlobCmd} {win} {
+ lsort [glob -join -path [string range $globname 0 5] * *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname .1]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.20 {Tcl_GlobCmd} {
+ lsort [glob -type d -dir $globname *]
+} [lsort [list [file join $globname a1]\
+ [file join $globname a2]\
+ [file join $globname a3]]]
+test filename-11.21 {Tcl_GlobCmd} {
+ lsort [glob -type d -path $globname *]
+} [list $globname]
+test filename-11.21.1 {Tcl_GlobCmd} -body {
+ touch {[tcl].testremains}
+ lsort [glob -path {[tcl]} *]
+} -cleanup {
+ file delete -force {[tcl].testremains}
+} -result {{[tcl].testremains}}
+# Get rid of file/dir if it exists, since it will have been left behind by a
+# previous failed run.
+if {[file exists $horribleglobname]} {
+ file delete -force $horribleglobname
+}
+file rename globTest $horribleglobname
+set globname $horribleglobname
+test filename-11.22 {Tcl_GlobCmd} {unix} {
+ lsort [glob -dir $globname *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.22.1 {Tcl_GlobCmd} {win} {
+ lsort [glob -dir $globname *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname .1]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.23 {Tcl_GlobCmd} {unix} {
+ lsort [glob -path $globname/ *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.23.1 {Tcl_GlobCmd} {win} {
+ lsort [glob -path $globname/ *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname .1]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.24 {Tcl_GlobCmd} {unix} {
+ lsort [glob -join -path [string range $globname 0 5] * *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.24.1 {Tcl_GlobCmd} {win} {
+ lsort [glob -join -path [string range $globname 0 5] * *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname .1]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.25 {Tcl_GlobCmd} {
+ lsort [glob -type d -dir $globname *]
+} [lsort [list [file join $globname a1]\
+ [file join $globname a2]\
+ [file join $globname a3]]]
+test filename-11.25.1 {Tcl_GlobCmd} {
+ lsort [glob -type {d r} -dir $globname *]
+} [lsort [list [file join $globname a1]\
+ [file join $globname a2]\
+ [file join $globname a3]]]
+test filename-11.25.2 {Tcl_GlobCmd} {
+ lsort [glob -type {d r w} -dir $globname *]
+} [lsort [list [file join $globname a1]\
+ [file join $globname a2]\
+ [file join $globname a3]]]
+test filename-11.26 {Tcl_GlobCmd} {
+ glob -type d -path $globname *
+} [list $globname]
+test filename-11.27 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types abcde *
+} -result {bad argument to "-types": abcde}
+test filename-11.28 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types z *
+} -result {bad argument to "-types": z}
+test filename-11.29 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types {abcd efgh} *
+} -result {only one MacOS type or creator argument to "-types" allowed}
+test filename-11.30 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types {{macintosh type TEXT} {macintosh creator ALFA} efgh} *
+} -result {only one MacOS type or creator argument to "-types" allowed}
+test filename-11.31 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types
+} -result {missing argument to "-types"}
+test filename-11.32 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -path hello -dir hello *
+} -result {"-directory" cannot be used with "-path"}
+test filename-11.33 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -path
+} -result {missing argument to "-path"}
+test filename-11.34 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -direct
+} -result {missing argument to "-directory"}
+test filename-11.35 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -paths *
+} -result {bad option "-paths": must be -directory, -join, -nocomplain, -path, -tails, -types, or --}
+# Test '-tails' flag to glob.
+test filename-11.36 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -tails *
+} -result {"-tails" must be used with either "-directory" or "-path"}
+test filename-11.37 {Tcl_GlobCmd} {
+ glob -type d -tails -path $globname *
+} [list $globname]
+test filename-11.38 {Tcl_GlobCmd} {
+ glob -tails -path $globname *
+} [list $globname]
+test filename-11.39 {Tcl_GlobCmd} {
+ glob -tails -join -path $globname *
+} [list $globname]
+test filename-11.40 {Tcl_GlobCmd} -body {
+ list [glob -dir [pwd] -tails *] [glob *]
+} -match compareWords -result equal
+test filename-11.41 {Tcl_GlobCmd} -body {
+ list [glob -dir [pwd] -tails *] [glob -dir [pwd] *]
+} -match compareWords -result "not equal"
+test filename-11.42 {Tcl_GlobCmd} -body {
+ set res [list]
+ foreach f [glob -dir [pwd] *] {
+ lappend res [file tail $f]
+ }
+ list $res [glob *]
+} -match compareWords -result equal
+test filename-11.43 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -t *
+} -result {ambiguous option "-t": must be -directory, -join, -nocomplain, -path, -tails, -types, or --}
+test filename-11.44 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -tails -path hello -directory hello *
+} -result {"-directory" cannot be used with "-path"}
+test filename-11.45 {Tcl_GlobCmd on root volume} -setup {
+ set res1 ""
+ set res2 ""
+ set tmpd [pwd]
+} -body {
+ catch {
+ set res1 [glob -dir [lindex [file volumes] 0] -tails *]
+ }
+ catch {
+ cd [lindex [file volumes] 0]
+ set res2 [glob *]
+ }
+ list $res1 $res2
+} -cleanup {
+ cd $tmpd
+} -match compareWords -result equal
+test filename-11.46 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types abcde -dir foo *
+} -result {bad argument to "-types": abcde}
+test filename-11.47 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types abcde -path foo *
+} -result {bad argument to "-types": abcde}
+test filename-11.48 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types abcde -dir foo -join * *
+} -result {bad argument to "-types": abcde}
+test filename-11.49 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types abcde -path foo -join * *
+} -result {bad argument to "-types": abcde}
+
+file rename $horribleglobname globTest
+set globname globTest
+unset horribleglobname
+
+test filename-12.1 {simple globbing} {unixOrPc} {
+ glob {}
+} {.}
+test filename-12.1.1 {simple globbing} -constraints {unixOrPc} -body {
+ glob -types f {}
+} -returnCodes error -result {no files matched glob pattern ""}
+test filename-12.1.2 {simple globbing} {unixOrPc} {
+ glob -types d {}
+} {.}
+test filename-12.1.3 {simple globbing} {unix} {
+ glob -types hidden {}
+} {.}
+test filename-12.1.4 {simple globbing} -constraints {win} -body {
+ glob -types hidden {}
+} -returnCodes error -result {no files matched glob pattern ""}
+test filename-12.1.5 {simple globbing} -constraints {win} -body {
+ glob -types hidden c:/
+} -returnCodes error -result {no files matched glob pattern "c:/"}
+test filename-12.1.6 {simple globbing} {win} {
+ glob c:/
+} {c:/}
+test filename-12.3 {simple globbing} {
+ glob -nocomplain \{a1,a2\}
+} {}
+set globPreResult globTest/
+set x1 x1.c
+set y1 y1.c
+test filename-12.4 {simple globbing} {unixOrPc} {
+ lsort [glob globTest/x1.c globTest/y1.c globTest/foo]
+} "$globPreResult$x1 $globPreResult$y1"
+test filename-12.5 {simple globbing} {
+ glob globTest\\/x1.c
+} "$globPreResult$x1"
+test filename-12.6 {simple globbing} {
+ glob globTest\\/\\x1.c
+} "$globPreResult$x1"
+test filename-12.7 {globbing at filesystem root} -constraints {unix} -body {
+ list [glob -nocomplain /*] [glob -path / *]
+} -match compareWords -result equal
+test filename-12.8 {globbing at filesystem root} -constraints {unix} -body {
+ set first [string range [lindex [glob -type d /*] 0] 0 1]
+ list [glob -nocomplain ${first}*] [glob -path $first *]
+} -match compareWords -result equal
+test filename-12.9 {globbing at filesystem root} -constraints {win} -body {
+ # Can't grab just anything from 'file volumes' because we need a dir that
+ # has subdirs - assume that C:/ exists across Windows machines.
+ set first [string range [lindex [glob -type d C:/*] 0] 0 3]
+ list [glob -nocomplain ${first}*] [glob -path $first *]
+} -match compareWords -result equal
+test filename-12.10 {globbing with volume relative paths} -setup {
+ set pwd [pwd]
+} -body {
+ set dir [lindex [glob -type d C:/*] 0]
+ cd C:/
+ list [glob -nocomplain [string range $dir 2 end]] [list $dir]
+} -cleanup {
+ cd $pwd
+} -constraints {win} -match compareWords -result equal
+
+test filename-13.1 {globbing with brace substitution} {
+ glob globTest/\{\}
+} "$globPreResult"
+test filename-13.2 {globbing with brace substitution} -body {
+ glob globTest/\{
+} -returnCodes error -result {unmatched open-brace in file name}
+test filename-13.3 {globbing with brace substitution} -body {
+ glob globTest/\{\\\}
+} -returnCodes error -result {unmatched open-brace in file name}
+test filename-13.4 {globbing with brace substitution} -body {
+ glob globTest/\{\\
+} -returnCodes error -result {unmatched open-brace in file name}
+test filename-13.5 {globbing with brace substitution} -body {
+ glob globTest/\}
+} -returnCodes error -result {unmatched close-brace in file name}
+test filename-13.6 {globbing with brace substitution} {
+ glob globTest/\{\}x1.c
+} "$globPreResult$x1"
+test filename-13.7 {globbing with brace substitution} {
+ glob globTest/\{x\}1.c
+} "$globPreResult$x1"
+test filename-13.8 {globbing with brace substitution} {
+ glob globTest/\{x\{\}\}1.c
+} "$globPreResult$x1"
+test filename-13.9 {globbing with brace substitution} {
+ lsort [glob globTest/\{x,y\}1.c]
+} [list $globPreResult$x1 $globPreResult$y1]
+test filename-13.10 {globbing with brace substitution} {
+ lsort [glob globTest/\{x,,y\}1.c]
+} [list $globPreResult$x1 $globPreResult$y1]
+test filename-13.11 {globbing with brace substitution} {unixOrPc} {
+ lsort [glob globTest/\{x,x\\,z,z\}1.c]
+} [lsort {globTest/x1.c globTest/x,z1.c globTest/z1.c}]
+test filename-13.13 {globbing with brace substitution} {
+ lsort [glob globTest/{a,b,x,y}1.c]
+} [list $globPreResult$x1 $globPreResult$y1]
+test filename-13.14 {globbing with brace substitution} {unixOrPc} {
+ lsort [glob {globTest/{x1,y2,weird name}.c}]
+} {{globTest/weird name.c} globTest/x1.c}
+test filename-13.16 {globbing with brace substitution} {unixOrPc} {
+ lsort [glob globTest/{x1.c,a1/*}]
+} {globTest/a1/b1 globTest/a1/b2 globTest/x1.c}
+test filename-13.18 {globbing with brace substitution} {unixOrPc} {
+ lsort [glob globTest/{x1.c,{a},a1/*}]
+} {globTest/a1/b1 globTest/a1/b2 globTest/x1.c}
+test filename-13.20 {globbing with brace substitution} {unixOrPc} {
+ lsort [glob globTest/{a,x}1/*/{x,y}*]
+} {globTest/a1/b1/x2.c globTest/a1/b2/y2.c}
+test filename-13.22 {globbing with brace substitution} -body {
+ glob globTest/\{a,x\}1/*/\{
+} -returnCodes error -result {unmatched open-brace in file name}
+
+test filename-14.1 {asterisks, question marks, and brackets} {unixOrPc} {
+ lsort [glob glo*/*.c]
+} {{globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}
+test filename-14.3 {asterisks, question marks, and brackets} {unixOrPc} {
+ lsort [glob globTest/?1.c]
+} {globTest/x1.c globTest/y1.c globTest/z1.c}
+test filename-14.5 {asterisks, question marks, and brackets} -setup {
+ # The current directory could be anywhere; do this to stop spurious
+ # matches
+ file mkdir globTestContext
+ file rename globTest [file join globTestContext globTest]
+ set savepwd [pwd]
+ cd globTestContext
+} -constraints {unixOrPc} -body {
+ lsort [glob */*/*/*.c]
+} -cleanup {
+ # Reset to where we were
+ cd $savepwd
+ file rename [file join globTestContext globTest] globTest
+ file delete globTestContext
+} -result {globTest/a1/b1/x2.c globTest/a1/b2/y2.c}
+test filename-14.7 {asterisks, question marks, and brackets} {unix} {
+ lsort [glob globTest/*]
+} {globTest/a1 globTest/a2 globTest/a3 {globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}
+test filename-14.7.1 {asterisks, question marks, and brackets} {win} {
+ lsort [glob globTest/*]
+} {globTest/.1 globTest/a1 globTest/a2 globTest/a3 {globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}
+test filename-14.9 {asterisks, question marks, and brackets} {unixOrPc} {
+ lsort [glob globTest/.*]
+} {globTest/. globTest/.. globTest/.1}
+test filename-14.11 {asterisks, question marks, and brackets} {unixOrPc} {
+ lsort [glob globTest/*/*]
+} {globTest/a1/b1 globTest/a1/b2 globTest/a2/b3}
+test filename-14.13 {asterisks, question marks, and brackets} {unixOrPc} {
+ lsort [glob {globTest/[xyab]1.*}]
+} {globTest/x1.c globTest/y1.c}
+test filename-14.15 {asterisks, question marks, and brackets} {unixOrPc} {
+ lsort [glob globTest/*/]
+} {globTest/a1/ globTest/a2/ globTest/a3/}
+test filename-14.17 {asterisks, question marks, and brackets} -setup {
+ global env
+ set temp $env(HOME)
+} -body {
+ set env(HOME) [file join $env(HOME) globTest]
+ glob ~/z*
+} -cleanup {
+ set env(HOME) $temp
+} -result [list [file join $env(HOME) globTest z1.c]]
+test filename-14.18 {asterisks, question marks, and brackets} {unixOrPc} {
+ lsort [glob globTest/*.c goo/*]
+} {{globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}
+test filename-14.20 {asterisks, question marks, and brackets} {
+ glob -nocomplain goo/*
+} {}
+test filename-14.21 {asterisks, question marks, and brackets} -body {
+ glob globTest/*/gorp
+} -returnCodes error -result {no files matched glob pattern "globTest/*/gorp"}
+test filename-14.22 {asterisks, question marks, and brackets} -body {
+ glob goo/* x*z foo?q
+} -returnCodes error -result {no files matched glob patterns "goo/* x*z foo?q"}
+test filename-14.23 {slash globbing} {unix} {
+ glob /
+} /
+test filename-14.23.2 {slash globbing} {win} {
+ glob /
+} [file norm /]
+test filename-14.24 {slash globbing} {win} {
+ glob {\\}
+} [file norm /]
+test filename-14.25 {type specific globbing} {unix} {
+ lsort [glob -dir globTest -types f *]
+} [lsort [list \
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-14.25.1 {type specific globbing} {win} {
+ lsort [glob -dir globTest -types f *]
+} [lsort [list \
+ [file join $globname .1]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-14.26 {type specific globbing} {
+ glob -nocomplain -dir globTest -types {readonly} *
+} {}
+test filename-14.27 {Bug 2710920} {unixOrPc} {
+ file tail [lindex [lsort [glob globTest/*/]] 0]
+} a1
+test filename-14.28 {Bug 2710920} {unixOrPc} {
+ file dirname [lindex [lsort [glob globTest/*/]] 0]
+} globTest
+test filename-14.29 {Bug 2710920} {unixOrPc} {
+ file extension [lindex [lsort [glob globTest/*/]] 0]
+} {}
+test filename-14.30 {Bug 2710920} {unixOrPc} {
+ file rootname [lindex [lsort [glob globTest/*/]] 0]
+} globTest/a1/
+
+test filename-14.31 {Bug 2918610} -setup {
+ set d [makeDirectory foo]
+ makeFile {} bar.soom $d
+} -body {
+ foreach fn [glob $d/bar.soom] {
+ set root [file rootname $fn]
+ close [open $root {WRONLY CREAT}]
+ }
+ llength [glob -directory $d *]
+} -cleanup {
+ file delete -force $d/bar
+ removeFile bar.soom $d
+ removeDirectory foo
+} -result 2
+
+unset globname
+
+# The following tests are only valid for Unix systems. On some systems, like
+# AFS, "000" protection doesn't prevent access by owner, so the following test
+# is not portable.
+
+catch {file attributes globTest/a1 -permissions 0000}
+test filename-15.1 {unix specific globbing} {unix nonPortable} {
+ string tolower [list [catch {glob globTest/a1/*} msg] $msg $errorCode]
+} {1 {couldn't read directory "globtest/a1": permission denied} {posix eacces {permission denied}}}
+test filename-15.2 {unix specific no complain: no errors} {unix nonPortable} {
+ glob -nocomplain globTest/a1/*
+} {}
+test filename-15.3 {unix specific no complain: no errors, good result} \
+ {unix nonPortable} {
+ # test fails because if an error occurs, the interp's result is reset...
+ glob -nocomplain globTest/a2 globTest/a1/* globTest/a3
+} {globTest/a2 globTest/a3}
+catch {file attributes globTest/a1 -permissions 0755}
+test filename-15.4 {unix specific no complain: no errors, good result} \
+ {unix nonPortable} {
+ # test fails because if an error occurs, the interp's result is reset...
+ # or you don't run at scriptics where the outser and welch users exists
+ glob -nocomplain ~ouster ~foo ~welch
+} {/home/ouster /home/welch}
+test filename-15.4.1 {no complain: errors, sequencing} {
+ # test used to fail because if an error occurs, the interp's result is
+ # reset... But, the sequence means we throw a different error first.
+ list [catch {glob -nocomplain ~wontexist ~blahxyz ~} res1] $res1 \
+ [catch {glob -nocomplain ~ ~blahxyz ~wontexist} res2] $res2
+} {1 {user "wontexist" doesn't exist} 1 {user "blahxyz" doesn't exist}}
+test filename-15.4.2 {no complain: errors, sequencing} -body {
+ # test used to fail because if an error occurs, the interp's result is
+ # reset...
+ list [list [catch {glob -nocomplain ~wontexist *} res1] $res1] \
+ [list [catch {glob -nocomplain * ~wontexist} res2] $res2]
+} -match compareWords -result equal
+test filename-15.5 {unix specific globbing} {unix nonPortable} {
+ glob ~ouster/.csh*
+} "/home/ouster/.cshrc"
+touch globTest/odd\\\[\]*?\{\}name
+test filename-15.6 {unix specific globbing} -constraints {unix} -setup {
+ global env
+ set temp $env(HOME)
+} -body {
+ set env(HOME) $env(HOME)/globTest/odd\\\[\]*?\{\}name
+ glob ~
+} -cleanup {
+ set env(HOME) $temp
+} -result [list [lindex [glob ~] 0]/globTest/odd\\\[\]*?\{\}name]
+catch {file delete -force globTest/odd\\\[\]*?\{\}name}
+test filename-15.7 {win specific globbing} -constraints {win} -body {
+ glob ~
+} -match regexp -result {[^/]$}
+test filename-15.8 {win and unix specific globbing} -constraints {unixOrWin} -setup {
+ global env
+ set temp $env(HOME)
+} -body {
+ touch $env(HOME)/globTest/anyname
+ set env(HOME) $env(HOME)/globTest/anyname
+ glob ~
+} -cleanup {
+ set env(HOME) $temp
+ catch {file delete -force $env(HOME)/globTest/anyname}
+} -result [list [lindex [glob ~] 0]/globTest/anyname]
+
+# The following tests are only valid for Windows systems.
+set oldDir [pwd]
+if {[testConstraint win]} {
+ cd c:/
+ file delete -force globTest
+ file mkdir globTest
+ touch globTest/x1.BAT
+ touch globTest/y1.Bat
+ touch globTest/z1.bat
+}
+
+test filename-16.1 {windows specific globbing} {win} {
+ lsort [glob globTest/*.bat]
+} {globTest/x1.BAT globTest/y1.Bat globTest/z1.bat}
+test filename-16.2 {windows specific globbing} {win} {
+ glob c:
+} c:
+test filename-16.2.1 {windows specific globbing} -constraints {win} -setup {
+ set dir [pwd]
+} -body {
+ cd C:/
+ glob c:
+} -cleanup {
+ cd $dir
+} -result c:
+test filename-16.3 {windows specific globbing} {win} {
+ glob -nocomplain c:\\\\
+} c:/
+test filename-16.4 {windows specific globbing} {win} {
+ glob -nocomplain c:/
+} c:/
+test filename-16.5 {windows specific globbing} {win} {
+ glob -nocomplain c:*bTest
+} c:globTest
+test filename-16.6 {windows specific globbing} {win} {
+ glob -nocomplain c:\\\\*bTest
+} c:/globTest
+test filename-16.7 {windows specific globbing} {win} {
+ glob -nocomplain c:/*bTest
+} c:/globTest
+test filename-16.8 {windows specific globbing} {win} {
+ lsort [glob -nocomplain c:globTest/*.bat]
+} {c:globTest/x1.BAT c:globTest/y1.Bat c:globTest/z1.bat}
+test filename-16.9 {windows specific globbing} {win} {
+ lsort [glob -nocomplain c:/globTest/*.bat]
+} {c:/globTest/x1.BAT c:/globTest/y1.Bat c:/globTest/z1.bat}
+test filename-16.10 {windows specific globbing} {win} {
+ lsort [glob -nocomplain c:globTest\\\\*.bat]
+} {c:globTest/x1.BAT c:globTest/y1.Bat c:globTest/z1.bat}
+test filename-16.11 {windows specific globbing} {win} {
+ lsort [glob -nocomplain c:\\\\globTest\\\\*.bat]
+} {c:/globTest/x1.BAT c:/globTest/y1.Bat c:/globTest/z1.bat}
+# some tests require a shared C drive
+test filename-16.12 {windows specific globbing} {win sharedCdrive} {
+ cd //[info hostname]/c
+ glob //[info hostname]/c/*Test
+} //[info hostname]/c/globTest
+test filename-16.13 {windows specific globbing} {win sharedCdrive} {
+ cd //[info hostname]/c
+ glob "\\\\\\\\[info hostname]\\\\c\\\\*Test"
+} //[info hostname]/c/globTest
+test filename-16.14 {windows specific globbing} {win} {
+ cd [lindex [glob -types d -dir C:/ *] 0]
+ expr {".." in [glob {{.,*}*}]}
+} {1}
+test filename-16.15 {windows specific globbing} {win} {
+ cd [lindex [glob -types d -dir C:/ *] 0]
+ glob ..
+} {..}
+test filename-16.16 {windows specific globbing} {win} {
+ file tail [lindex [glob -nocomplain "[lindex [glob -types d -dir C:/ *] 0]/.."] 0]
+} {..}
+test filename-16.17 {windows specific globbing} -constraints {win} -body {
+ cd C:/
+ # Ensure correct trimming of tails with absolute and volume relative
+ # globbing.
+ list [glob -nocomplain -tails -dir C:/ *] \
+ [glob -nocomplain -tails -dir C: *]
+} -match compareWords -result equal
+
+# Put the working directory back now that we're done with globbing in C:/
+if {[testConstraint win]} {
+ cd $oldDir
+}
+
+test filename-17.1 {windows specific special files} {testsetplatform} {
+ testsetplatform win
+ list [file pathtype com1] [file pathtype con] [file pathtype lpt3] \
+ [file pathtype prn] [file pathtype nul] [file pathtype aux] \
+ [file pathtype foo]
+} {absolute absolute absolute absolute absolute absolute relative}
+if {[testConstraint testsetplatform]} {
+ testsetplatform $platform
+}
+test filename-17.2 {windows specific glob with executable} -body {
+ makeDirectory execglob
+ makeFile contents execglob/abc.exe
+ makeFile contents execglob/abc.notexecutable
+ glob -nocomplain -dir [temporaryDirectory]/execglob -tails -types x *
+} -constraints {win} -cleanup {
+ removeFile execglob/abc.exe
+ removeFile execglob/abc.notexecutable
+ removeDirectory execglob
+} -result {abc.exe}
+test filename-17.3 {Bug 2571597} win {
+ set p /a
+ file pathtype $p
+ file normalize $p
+ file pathtype $p
+} volumerelative
+
+test fileName-18.1 {windows - split ADS name correctly} {win} {
+ # bug 1194458
+ set x [file split c:/c:d]
+ list $x [file join {*}$x]
+} {{c:/ ./c:d} c:/c:d}
+
+test fileName-19.1 {ensure that [Bug 1325099] stays fixed} {
+ # Any non-crashing result is OK
+ list [file exists ~//.nonexistant_file] [file exists ~///.nonexistant_file]
+} {0 0}
+
+test fileName-20.1 {Bug 1750300} -setup {
+ set d [makeDirectory foo]
+ makeFile {} TAGS $d
+} -body {
+ llength [glob -nocomplain -directory $d -- TAGS one two]
+} -cleanup {
+ removeFile TAGS $d
+ removeDirectory foo
+} -result 1
+test fileName-20.2 {Bug 1750300} -setup {
+ set d [makeDirectory foo]
+ makeFile {} TAGS $d
+} -body {
+ llength [glob -nocomplain -directory $d -types {} -- TAGS one two]
+} -cleanup {
+ removeFile TAGS $d
+ removeDirectory foo
+} -result 1
+test fileName-20.3 {Bug 1750300} -setup {
+ set d [makeDirectory foo]
+ makeFile {} TAGS $d
+} -body {
+ llength [glob -nocomplain -directory $d -types {} -- *U*]
+} -cleanup {
+ removeFile TAGS $d
+ removeDirectory foo
+} -result 0
+test fileName-20.4 {Bug 1750300} -setup {
+ set d [makeDirectory foo]
+ makeFile {} TAGS $d
+} -body {
+ llength [glob -nocomplain -directory $d -types {} -- URGENT Urkle]
+} -cleanup {
+ removeFile TAGS $d
+ removeDirectory foo
+} -result 0
+test fileName-20.5 {Bug 2837800} -setup {
+ set dd [makeDirectory isolate]
+ set d [makeDirectory ./~foo $dd]
+ makeFile {} test $d
+ set savewd [pwd]
+ cd $dd
+} -body {
+ glob -nocomplain */test
+} -cleanup {
+ cd $savewd
+ removeFile test $d
+ removeDirectory ./~foo $dd
+ removeDirectory isolate
+} -result ~foo/test
+test fileName-20.6 {Bug 2837800} -setup {
+ # Recall that we have $env(HOME) set so that references
+ # to ~ point to [temporaryDirectory]
+ makeFile {} test ~
+ set dd [makeDirectory isolate]
+ set d [makeDirectory ./~ $dd]
+ set savewd [pwd]
+ cd $dd
+} -body {
+ glob -nocomplain */test
+} -cleanup {
+ cd $savewd
+ removeDirectory ./~ $dd
+ removeDirectory isolate
+ removeFile test ~
+} -result {}
+test fileName-20.7 {Bug 2806250} -setup {
+ set savewd [pwd]
+ cd [temporaryDirectory]
+ set d [makeDirectory isolate]
+ makeFile {} ./~test $d
+} -body {
+ file exists [lindex [glob -nocomplain isolate/*] 0]
+} -cleanup {
+ removeFile ./~test $d
+ removeDirectory isolate
+ cd $savewd
+} -result 1
+test fileName-20.8 {Bug 2806250} -setup {
+ set savewd [pwd]
+ cd [temporaryDirectory]
+ set d [makeDirectory isolate]
+ makeFile {} ./~test $d
+} -body {
+ file tail [lindex [glob -nocomplain isolate/*] 0]
+} -cleanup {
+ removeFile ./~test $d
+ removeDirectory isolate
+ cd $savewd
+} -result ./~test
+test fileName-20.9 {globbing for special chars} -setup {
+ makeFile {} test ~
+ set d [makeDirectory isolate]
+ set savewd [pwd]
+ cd $d
+} -body {
+ glob -nocomplain -directory ~ test
+} -cleanup {
+ cd $savewd
+ removeDirectory isolate
+ removeFile test ~
+} -result ~/test
+test fileName-20.10 {globbing for special chars} -setup {
+ set s [makeDirectory sub ~]
+ makeFile {} fileName-20.10 $s
+ set d [makeDirectory isolate]
+ set savewd [pwd]
+ cd $d
+} -body {
+ glob -nocomplain -directory ~ -join * fileName-20.10
+} -cleanup {
+ cd $savewd
+ removeDirectory isolate
+ removeFile fileName-20.10 $s
+ removeDirectory sub ~
+} -result ~/sub/fileName-20.10
+
+# cleanup
+catch {file delete -force C:/globTest}
+cd [temporaryDirectory]
+file delete -force globTest
+cd $oldpwd
+set env(HOME) $oldhome
+if {[testConstraint testsetplatform]} {
+ testsetplatform $platform
+ catch {unset platform}
+}
+catch {unset oldhome temp result globPreResult}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/fileSystem.test b/library/msgcat/tests/fileSystem.test
new file mode 100644
index 0000000..9950dde
--- /dev/null
+++ b/library/msgcat/tests/fileSystem.test
@@ -0,0 +1,935 @@
+# This file tests the filesystem and vfs internals.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 2002 Vincent Darley.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace eval ::tcl::test::fileSystem {
+ namespace import ::tcltest::*
+
+ catch {
+ file delete -force link.file
+ file delete -force dir.link
+ file delete -force [file join dir.dir linkinside.file]
+ }
+
+# Test for commands defined in Tcltest executable
+testConstraint testfilesystem [llength [info commands ::testfilesystem]]
+testConstraint testsetplatform [llength [info commands ::testsetplatform]]
+testConstraint testsimplefilesystem [llength [info commands ::testsimplefilesystem]]
+
+cd [tcltest::temporaryDirectory]
+makeFile "test file" gorp.file
+makeDirectory dir.dir
+makeDirectory [file join dir.dir dirinside.dir]
+makeFile "test file in directory" [file join dir.dir inside.file]
+
+testConstraint unusedDrive 0
+testConstraint moreThanOneDrive 0
+apply {{} {
+ # The variables 'drive' and 'drives' will be used below.
+ variable drive {} drives {}
+ if {[testConstraint win]} {
+ set vols [string map [list :/ {}] [file volumes]]
+ for {set i 0} {$i < 26} {incr i} {
+ set drive [format %c [expr {$i + 65}]]
+ if {$drive ni $vols} {
+ testConstraint unusedDrive 1
+ break
+ }
+ }
+
+ set dir [pwd]
+ try {
+ foreach vol [file volumes] {
+ if {![catch {cd $vol}]} {
+ lappend drives $vol
+ }
+ }
+ testConstraint moreThanOneDrive [llength $drives]
+ } finally {
+ cd $dir
+ }
+ }
+} ::tcl::test::fileSystem}
+
+proc testPathEqual {one two} {
+ if {$one eq $two} {
+ return "ok"
+ }
+ return "not equal: $one $two"
+}
+
+testConstraint hasLinks [expr {![catch {
+ file link link.file gorp.file
+ cd dir.dir
+ file link \
+ [file join linkinside.file] \
+ [file join inside.file]
+ cd ..
+ file link dir.link dir.dir
+ cd dir.dir
+ file link [file join dirinside.link] \
+ [file join dirinside.dir]
+ cd ..
+}]}]
+
+if {[testConstraint testsetplatform]} {
+ set platform [testgetplatform]
+}
+
+# ----------------------------------------------------------------------
+
+test filesystem-1.0 {link normalisation} {hasLinks} {
+ string equal [file normalize gorp.file] [file normalize link.file]
+} {0}
+test filesystem-1.1 {link normalisation} {hasLinks} {
+ string equal [file normalize dir.dir] [file normalize dir.link]
+} {0}
+test filesystem-1.2 {link normalisation} {hasLinks unix} {
+ testPathEqual [file normalize [file join gorp.file foo]] \
+ [file normalize [file join link.file foo]]
+} ok
+test filesystem-1.3 {link normalisation} {hasLinks} {
+ testPathEqual [file normalize [file join dir.dir foo]] \
+ [file normalize [file join dir.link foo]]
+} ok
+test filesystem-1.4 {link normalisation} {hasLinks} {
+ testPathEqual [file normalize [file join dir.dir inside.file]] \
+ [file normalize [file join dir.link inside.file]]
+} ok
+test filesystem-1.5 {link normalisation} {hasLinks} {
+ testPathEqual [file normalize [file join dir.dir linkinside.file]] \
+ [file normalize [file join dir.dir linkinside.file]]
+} ok
+test filesystem-1.6 {link normalisation} {hasLinks} {
+ string equal [file normalize [file join dir.dir linkinside.file]] \
+ [file normalize [file join dir.link inside.file]]
+} {0}
+test filesystem-1.7 {link normalisation} {hasLinks unix} {
+ testPathEqual [file normalize [file join dir.link linkinside.file foo]] \
+ [file normalize [file join dir.dir inside.file foo]]
+} ok
+test filesystem-1.8 {link normalisation} {hasLinks} {
+ string equal [file normalize [file join dir.dir linkinside.filefoo]] \
+ [file normalize [file join dir.link inside.filefoo]]
+} {0}
+test filesystem-1.9 {link normalisation} -setup {
+ file delete -force dir.link
+} -constraints {unix hasLinks} -body {
+ file link dir.link [file nativename dir.dir]
+ testPathEqual [file normalize [file join dir.dir linkinside.file foo]] \
+ [file normalize [file join dir.link inside.file foo]]
+} -result ok
+test filesystem-1.10 {link normalisation: double link} {unix hasLinks} {
+ file link dir2.link dir.link
+ testPathEqual [file normalize [file join dir.dir linkinside.file foo]] \
+ [file normalize [file join dir2.link inside.file foo]]
+} ok
+makeDirectory dir2.file
+test filesystem-1.11 {link normalisation: double link, back in tree} {unix hasLinks} {
+ file link [file join dir2.file dir2.link] [file join .. dir2.link]
+ testPathEqual [file normalize [file join dir.dir linkinside.file foo]] \
+ [file normalize [file join dir2.file dir2.link inside.file foo]]
+} ok
+test filesystem-1.12 {file new native path} {} {
+ for {set i 0} {$i < 10} {incr i} {
+ foreach f [lsort [glob -nocomplain -type l *]] {
+ catch {file readlink $f}
+ }
+ }
+ # If we reach here we've succeeded. We used to crash above.
+ expr 1
+} {1}
+test filesystem-1.13 {file normalisation} {win} {
+ # This used to be broken
+ file normalize C:/thislongnamedoesntexist
+} {C:/thislongnamedoesntexist}
+test filesystem-1.14 {file normalisation} {win} {
+ # This used to be broken
+ file normalize c:/
+} {C:/}
+test filesystem-1.15 {file normalisation} {win} {
+ file normalize c:/../
+} {C:/}
+test filesystem-1.16 {file normalisation} {win} {
+ file normalize c:/.
+} {C:/}
+test filesystem-1.17 {file normalisation} {win} {
+ file normalize c:/..
+} {C:/}
+test filesystem-1.17.1 {file normalisation} {win} {
+ file normalize c:\\..
+} {C:/}
+test filesystem-1.18 {file normalisation} {win} {
+ file normalize c:/./
+} {C:/}
+test filesystem-1.19 {file normalisation} {win unusedDrive} {
+ file normalize ${drive}:/./../../..
+} "${drive}:/"
+test filesystem-1.20 {file normalisation} {win} {
+ file normalize //name/foo/../
+} {//name/foo}
+test filesystem-1.21 {file normalisation} {win} {
+ file normalize C:///foo/./
+} {C:/foo}
+test filesystem-1.22 {file normalisation} {win} {
+ file normalize //name/foo/.
+} {//name/foo}
+test filesystem-1.23 {file normalisation} {win} {
+ file normalize c:/./foo
+} {C:/foo}
+test filesystem-1.24 {file normalisation} {win unusedDrive} {
+ file normalize ${drive}:/./../../../a
+} "${drive}:/a"
+test filesystem-1.25 {file normalisation} {win unusedDrive} {
+ file normalize ${drive}:/./.././../../a
+} "${drive}:/a"
+test filesystem-1.25.1 {file normalisation} {win unusedDrive} {
+ file normalize ${drive}:/./.././..\\..\\a\\bb
+} "${drive}:/a/bb"
+test filesystem-1.26 {link normalisation: link and ..} -setup {
+ file delete -force dir2.link
+} -constraints {hasLinks} -body {
+ set dir [file join dir2 foo bar]
+ file mkdir $dir
+ file link dir2.link [file join dir2 foo bar]
+ testPathEqual [file normalize [file join dir2 foo x]] \
+ [file normalize [file join dir2.link .. x]]
+} -result ok
+test filesystem-1.27 {file normalisation: up and down with ..} {
+ set dir [file join dir2 foo bar]
+ file mkdir $dir
+ set dir2 [file join dir2 .. dir2 foo .. foo bar]
+ list [testPathEqual [file normalize $dir] [file normalize $dir2]] \
+ [file exists $dir] [file exists $dir2]
+} {ok 1 1}
+test filesystem-1.28 {link normalisation: link with .. and ..} -setup {
+ file delete -force dir2.link
+} -constraints {hasLinks} -body {
+ set dir [file join dir2 foo bar]
+ file mkdir $dir
+ set to [file join dir2 .. dir2 foo .. foo bar]
+ file link dir2.link $to
+ testPathEqual [file normalize [file join dir2 foo x]] \
+ [file normalize [file join dir2.link .. x]]
+} -result ok
+test filesystem-1.29 {link normalisation: link with ..} -setup {
+ file delete -force dir2.link
+} -constraints {hasLinks} -body {
+ set dir [file join dir2 foo bar]
+ file mkdir $dir
+ set to [file join dir2 .. dir2 foo .. foo bar]
+ file link dir2.link $to
+ set res [file normalize [file join dir2.link x yyy z]]
+ if {[string match *..* $res]} {
+ return "$res must not contain '..'"
+ }
+ return "ok"
+} -result {ok}
+test filesystem-1.29.1 {link normalisation with two consecutive links} {hasLinks} {
+ testPathEqual [file normalize [file join dir.link dirinside.link abc]] \
+ [file normalize [file join dir.dir dirinside.dir abc]]
+} ok
+file delete -force dir2.file
+file delete -force dir2.link
+file delete -force link.file dir.link
+file delete -force dir2
+file delete -force [file join dir.dir dirinside.link]
+removeFile [file join dir.dir inside.file]
+removeDirectory [file join dir.dir dirinside.dir]
+removeDirectory dir.dir
+test filesystem-1.30 {normalisation of nonexistent user} -body {
+ file normalize ~noonewiththisname
+} -returnCodes error -result {user "noonewiththisname" doesn't exist}
+test filesystem-1.31 {link normalisation: link near filesystem root} {testsetplatform} {
+ testsetplatform unix
+ file normalize /foo/../bar
+} {/bar}
+test filesystem-1.32 {link normalisation: link near filesystem root} {testsetplatform} {
+ testsetplatform unix
+ file normalize /../bar
+} {/bar}
+test filesystem-1.33 {link normalisation: link near filesystem root} {testsetplatform} {
+ testsetplatform windows
+ set res [file normalize C:/../bar]
+ if {[testConstraint unix]} {
+ # Some unices go further in normalizing this -- not really a problem
+ # since this is a Windows test.
+ regexp {C:/bar$} $res res
+ }
+ set res
+} {C:/bar}
+if {[testConstraint testsetplatform]} {
+ testsetplatform $platform
+}
+test filesystem-1.34 {file normalisation with '/./'} -body {
+ file normalize /foo/bar/anc/./.tml
+} -match regexp -result {^(?:(?!/\./).)*$}
+test filesystem-1.35a {file normalisation with '/./'} -body {
+ file normalize /ffo/bar/anc/./foo/.tml
+} -match regexp -result {^(?:(?!/\./).)*$}
+test filesystem-1.35b {file normalisation with '/./'} {
+ llength [regexp -all foo [file normalize /ffo/bar/anc/./foo/.tml]]
+} 1
+test filesystem-1.36a {file normalisation with '/./'} -body {
+ file normalize /foo/bar/anc/././asdasd/.tml
+} -match regexp -result {^(?:(?!/\./).)*$}
+test filesystem-1.36b {file normalisation with '/./'} {
+ llength [regexp -all asdasd [file normalize /foo/bar/anc/././asdasd/.tml]]
+} 1
+test filesystem-1.37 {file normalisation with '/./'} -body {
+ set fname "/abc/./def/./ghi/./asda/.././.././asd/x/../../../../....."
+ file norm $fname
+} -match regexp -result {^(?:[^/]|/(?:[^/]|$))+$}
+test filesystem-1.38 {file normalisation with volume relative} -setup {
+ set dir [pwd]
+} -constraints {win moreThanOneDrive} -body {
+ set path "[string range [lindex $drives 0] 0 1]foo"
+ cd [lindex $drives 1]
+ file norm $path
+} -cleanup {
+ cd $dir
+} -result "[lindex $drives 0]foo"
+test filesystem-1.39 {file normalisation with volume relative} -setup {
+ set old [pwd]
+} -constraints {win} -body {
+ set drv C:/
+ cd [lindex [glob -type d -dir $drv *] 0]
+ file norm [string range $drv 0 1]
+} -cleanup {
+ cd $old
+} -match glob -result {*[^/]}
+test filesystem-1.40 {file normalisation with repeated separators} {
+ testPathEqual [file norm foo////bar] [file norm foo/bar]
+} ok
+test filesystem-1.41 {file normalisation with repeated separators} {win} {
+ testPathEqual [file norm foo\\\\\\bar] [file norm foo/bar]
+} ok
+test filesystem-1.42 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /xxx/..] [file norm /]
+} ok
+test filesystem-1.42.1 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /xxx/../] [file norm /]
+} ok
+test filesystem-1.43 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /xxx/foo/../..] [file norm /]
+} ok
+test filesystem-1.43.1 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /xxx/foo/../../] [file norm /]
+} ok
+test filesystem-1.44 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /xxx/foo/../../bar] [file norm /bar]
+} ok
+test filesystem-1.45 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /xxx/../../bar] [file norm /bar]
+} ok
+test filesystem-1.46 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /xxx/../bar] [file norm /bar]
+} ok
+test filesystem-1.47 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /..] [file norm /]
+} ok
+test filesystem-1.48 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /../] [file norm /]
+} ok
+test filesystem-1.49 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /.] [file norm /]
+} ok
+test filesystem-1.50 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /./] [file norm /]
+} ok
+test filesystem-1.51 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /../..] [file norm /]
+} ok
+test filesystem-1.51.1 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /../../] [file norm /]
+} ok
+
+test filesystem-2.0 {new native path} {unix} {
+ foreach f [lsort [glob -nocomplain /usr/bin/c*]] {
+ catch {file readlink $f}
+ }
+ # If we reach here we've succeeded. We used to crash above.
+ return ok
+} ok
+
+# Make sure the testfilesystem hasn't been registered.
+if {[testConstraint testfilesystem]} {
+ while {![catch {testfilesystem 0}]} {}
+}
+
+test filesystem-3.1 {Tcl_FSRegister & Tcl_FSUnregister} testfilesystem {
+ set result {}
+ lappend result [testfilesystem 1]
+ lappend result [testfilesystem 0]
+ lappend result [catch {testfilesystem 0} msg] $msg
+} {registered unregistered 1 failed}
+test filesystem-3.3 {Tcl_FSRegister} testfilesystem {
+ testfilesystem 1
+ testfilesystem 1
+ testfilesystem 0
+ testfilesystem 0
+} {unregistered}
+test filesystem-3.4 {Tcl_FSRegister} testfilesystem {
+ testfilesystem 1
+ file system bar
+} {reporting}
+test filesystem-3.5 {Tcl_FSUnregister} testfilesystem {
+ testfilesystem 0
+ lindex [file system bar] 0
+} {native}
+
+test filesystem-4.0 {testfilesystem} -constraints testfilesystem -body {
+ testfilesystem 1
+ set filesystemReport {}
+ file exists foo
+ testfilesystem 0
+ return $filesystemReport
+} -match glob -result {*{access foo}}
+test filesystem-4.1 {testfilesystem} -constraints testfilesystem -body {
+ testfilesystem 1
+ set filesystemReport {}
+ catch {file stat foo bar}
+ testfilesystem 0
+ return $filesystemReport
+} -match glob -result {*{stat foo}}
+test filesystem-4.2 {testfilesystem} -constraints testfilesystem -body {
+ testfilesystem 1
+ set filesystemReport {}
+ catch {file lstat foo bar}
+ testfilesystem 0
+ return $filesystemReport
+} -match glob -result {*{lstat foo}}
+test filesystem-4.3 {testfilesystem} -constraints testfilesystem -body {
+ testfilesystem 1
+ set filesystemReport {}
+ catch {glob *}
+ testfilesystem 0
+ return $filesystemReport
+} -match glob -result {*{matchindirectory *}*}
+
+test filesystem-5.1 {cache and ~} -constraints testfilesystem -setup {
+ set orig $::env(HOME)
+} -body {
+ set ::env(HOME) /foo/bar/blah
+ set testdir ~
+ set res1 "Parent of ~ (/foo/bar/blah) is [file dirname $testdir]"
+ set ::env(HOME) /a/b/c
+ set res2 "Parent of ~ (/a/b/c) is [file dirname $testdir]"
+ list $res1 $res2
+} -cleanup {
+ set ::env(HOME) $orig
+} -match regexp -result {{Parent of ~ \(/foo/bar/blah\) is ([a-zA-Z]:)?(/cygwin)?(/foo/bar|foo:bar)} {Parent of ~ \(/a/b/c\) is ([a-zA-Z]:)?(/cygwin)?(/a/b|a:b)}}
+
+test filesystem-6.1 {empty file name} -returnCodes error -body {
+ open ""
+} -result {couldn't open "": no such file or directory}
+test filesystem-6.2 {empty file name} -returnCodes error -body {
+ file stat "" arr
+} -result {could not read "": no such file or directory}
+test filesystem-6.3 {empty file name} -returnCodes error -body {
+ file atime ""
+} -result {could not read "": no such file or directory}
+test filesystem-6.4 {empty file name} -returnCodes error -body {
+ file attributes ""
+} -result {could not read "": no such file or directory}
+test filesystem-6.5 {empty file name} -returnCodes error -body {
+ file copy "" ""
+} -result {error copying "": no such file or directory}
+test filesystem-6.6 {empty file name} {file delete ""} {}
+test filesystem-6.7 {empty file name} {file dirname ""} .
+test filesystem-6.8 {empty file name} {file executable ""} 0
+test filesystem-6.9 {empty file name} {file exists ""} 0
+test filesystem-6.10 {empty file name} {file extension ""} {}
+test filesystem-6.11 {empty file name} {file isdirectory ""} 0
+test filesystem-6.12 {empty file name} {file isfile ""} 0
+test filesystem-6.13 {empty file name} {file join ""} {}
+test filesystem-6.14 {empty file name} -returnCodes error -body {
+ file link ""
+} -result {could not read link "": no such file or directory}
+test filesystem-6.15 {empty file name} -returnCodes error -body {
+ file lstat "" arr
+} -result {could not read "": no such file or directory}
+test filesystem-6.16 {empty file name} -returnCodes error -body {
+ file mtime ""
+} -result {could not read "": no such file or directory}
+test filesystem-6.17 {empty file name} -returnCodes error -body {
+ file mtime "" 0
+} -result {could not read "": no such file or directory}
+test filesystem-6.18 {empty file name} -returnCodes error -body {
+ file mkdir ""
+} -result {can't create directory "": no such file or directory}
+test filesystem-6.19 {empty file name} {file nativename ""} {}
+test filesystem-6.20 {empty file name} {file normalize ""} {}
+test filesystem-6.21 {empty file name} {file owned ""} 0
+test filesystem-6.22 {empty file name} {file pathtype ""} relative
+test filesystem-6.23 {empty file name} {file readable ""} 0
+test filesystem-6.24 {empty file name} -returnCodes error -body {
+ file readlink ""
+} -result {could not readlink "": no such file or directory}
+test filesystem-6.25 {empty file name} -returnCodes error -body {
+ file rename "" ""
+} -result {error renaming "": no such file or directory}
+test filesystem-6.26 {empty file name} {file rootname ""} {}
+test filesystem-6.27 {empty file name} -returnCodes error -body {
+ file separator ""
+} -result {unrecognised path}
+test filesystem-6.28 {empty file name} -returnCodes error -body {
+ file size ""
+} -result {could not read "": no such file or directory}
+test filesystem-6.29 {empty file name} {file split ""} {}
+test filesystem-6.30 {empty file name} -returnCodes error -body {
+ file system ""
+} -result {unrecognised path}
+test filesystem-6.31 {empty file name} {file tail ""} {}
+test filesystem-6.32 {empty file name} -returnCodes error -body {
+ file type ""
+} -result {could not read "": no such file or directory}
+test filesystem-6.33 {empty file name} {file writable ""} 0
+
+# Make sure the testfilesystem hasn't been registered.
+if {[testConstraint testfilesystem]} {
+ while {![catch {testfilesystem 0}]} {}
+}
+
+test filesystem-7.1.1 {load from vfs} -setup {
+ set dir [pwd]
+} -constraints {win testsimplefilesystem} -body {
+ # This may cause a crash on exit
+ cd [file dirname [info nameof]]
+ set dde [lindex [glob *dde*[info sharedlib]] 0]
+ testsimplefilesystem 1
+ # This loads dde via a complex copy-to-temp operation
+ load simplefs:/$dde dde
+ testsimplefilesystem 0
+ return ok
+ # The real result of this test is what happens when Tcl exits.
+} -cleanup {
+ cd $dir
+} -result ok
+test filesystem-7.1.2 {load from vfs, and then unload again} -setup {
+ set dir [pwd]
+} -constraints {win testsimplefilesystem} -body {
+ # This may cause a crash on exit
+ cd [file dirname [info nameof]]
+ set reg [lindex [glob tclreg*[info sharedlib]] 0]
+ testsimplefilesystem 1
+ # This loads reg via a complex copy-to-temp operation
+ load simplefs:/$reg Registry
+ unload simplefs:/$reg
+ testsimplefilesystem 0
+ return ok
+ # The real result of this test is what happens when Tcl exits.
+} -cleanup {
+ cd $dir
+} -result ok
+test filesystem-7.2 {cross-filesystem copy from vfs maintains mtime} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -constraints testsimplefilesystem -body {
+ # We created this file several tests ago.
+ set origtime [file mtime gorp.file]
+ set res [file exists gorp.file]
+ testsimplefilesystem 1
+ file delete -force theCopy
+ file copy simplefs:/gorp.file theCopy
+ testsimplefilesystem 0
+ set newtime [file mtime theCopy]
+ lappend res [expr {$origtime == $newtime ? 1 : "$origtime != $newtime"}]
+} -cleanup {
+ catch {file delete theCopy}
+ cd $dir
+} -result {1 1}
+test filesystem-7.3 {glob in simplefs} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -constraints testsimplefilesystem -body {
+ file mkdir simpledir
+ close [open [file join simpledir simplefile] w]
+ testsimplefilesystem 1
+ glob -nocomplain -dir simplefs:/simpledir *
+} -cleanup {
+ catch {testsimplefilesystem 0}
+ file delete -force simpledir
+ cd $dir
+} -result {simplefs:/simpledir/simplefile}
+test filesystem-7.3.1 {glob in simplefs: no path/dir} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -constraints testsimplefilesystem -body {
+ file mkdir simpledir
+ close [open [file join simpledir simplefile] w]
+ testsimplefilesystem 1
+ set res [glob -nocomplain simplefs:/simpledir/*]
+ lappend res {*}[glob -nocomplain simplefs:/simpledir]
+} -cleanup {
+ catch {testsimplefilesystem 0}
+ file delete -force simpledir
+ cd $dir
+} -result {simplefs:/simpledir/simplefile simplefs:/simpledir}
+test filesystem-7.3.2 {glob in simplefs: no path/dir, no subdirectory} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -constraints testsimplefilesystem -body {
+ file mkdir simpledir
+ close [open [file join simpledir simplefile] w]
+ testsimplefilesystem 1
+ glob -nocomplain simplefs:/s*
+} -cleanup {
+ catch {testsimplefilesystem 0}
+ file delete -force simpledir
+ cd $dir
+} -match glob -result ?*
+test filesystem-7.3.3 {glob in simplefs: pattern is a volume} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -constraints testsimplefilesystem -body {
+ file mkdir simpledir
+ close [open [file join simpledir simplefile] w]
+ testsimplefilesystem 1
+ glob -nocomplain simplefs:/*
+} -cleanup {
+ testsimplefilesystem 0
+ file delete -force simpledir
+ cd $dir
+} -match glob -result ?*
+test filesystem-7.4 {cross-filesystem file copy with -force} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+ set fout [open [file join simplefile] w]
+ puts -nonewline $fout "1234567890"
+ close $fout
+ testsimplefilesystem 1
+} -constraints testsimplefilesystem -body {
+ # First copy should succeed
+ set res [catch {file copy simplefs:/simplefile file2} err]
+ lappend res $err
+ # Second copy should fail (no -force)
+ lappend res [catch {file copy simplefs:/simplefile file2} err]
+ lappend res $err
+ # Third copy should succeed (-force)
+ lappend res [catch {file copy -force simplefs:/simplefile file2} err]
+ lappend res $err
+ lappend res [file exists file2]
+} -cleanup {
+ catch {testsimplefilesystem 0}
+ file delete -force simplefile
+ file delete -force file2
+ cd $dir
+} -result {0 10 1 {error copying "simplefs:/simplefile" to "file2": file already exists} 0 10 1}
+test filesystem-7.5 {cross-filesystem file copy with -force} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+ set fout [open [file join simplefile] w]
+ puts -nonewline $fout "1234567890"
+ close $fout
+ testsimplefilesystem 1
+} -constraints {testsimplefilesystem unix} -body {
+ # First copy should succeed
+ set res [catch {file copy simplefs:/simplefile file2} err]
+ lappend res $err
+ file attributes file2 -permissions 0000
+ # Second copy should fail (no -force)
+ lappend res [catch {file copy simplefs:/simplefile file2} err]
+ lappend res $err
+ # Third copy should succeed (-force)
+ lappend res [catch {file copy -force simplefs:/simplefile file2} err]
+ lappend res $err
+ lappend res [file exists file2]
+} -cleanup {
+ testsimplefilesystem 0
+ file delete -force simplefile
+ file delete -force file2
+ cd $dir
+} -result {0 10 1 {error copying "simplefs:/simplefile" to "file2": file already exists} 0 10 1}
+test filesystem-7.6 {cross-filesystem dir copy with -force} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+ file delete -force simpledir
+ file mkdir simpledir
+ file mkdir dir2
+ set fout [open [file join simpledir simplefile] w]
+ puts -nonewline $fout "1234567890"
+ close $fout
+ testsimplefilesystem 1
+} -constraints testsimplefilesystem -body {
+ # First copy should succeed
+ set res [catch {file copy simplefs:/simpledir dir2} err]
+ lappend res $err
+ # Second copy should fail (no -force)
+ lappend res [catch {file copy simplefs:/simpledir dir2} err]
+ lappend res $err
+ # Third copy should succeed (-force)
+ lappend res [catch {file copy -force simplefs:/simpledir dir2} err]
+ lappend res $err
+ lappend res [file exists [file join dir2 simpledir]] \
+ [file exists [file join dir2 simpledir simplefile]]
+} -cleanup {
+ testsimplefilesystem 0
+ file delete -force simpledir
+ file delete -force dir2
+ cd $dir
+} -result {0 {} 1 {error copying "simplefs:/simpledir" to "dir2/simpledir": file already exists} 0 {} 1 1}
+test filesystem-7.7 {cross-filesystem dir copy with -force} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+ file delete -force simpledir
+ file mkdir simpledir
+ file mkdir dir2
+ set fout [open [file join simpledir simplefile] w]
+ puts -nonewline $fout "1234567890"
+ close $fout
+ testsimplefilesystem 1
+} -constraints {testsimplefilesystem unix} -body {
+ # First copy should succeed
+ set res [catch {file copy simplefs:/simpledir dir2} err]
+ lappend res $err
+ # Second copy should fail (no -force)
+ lappend res [catch {file copy simplefs:/simpledir dir2} err]
+ lappend res $err
+ # Third copy should succeed (-force)
+ # I've noticed on some Unices that this only succeeds intermittently (some
+ # runs work, some fail). This needs examining further.
+ lappend res [catch {file copy -force simplefs:/simpledir dir2} err]
+ lappend res $err
+ lappend res [file exists [file join dir2 simpledir]] \
+ [file exists [file join dir2 simpledir simplefile]]
+} -cleanup {
+ testsimplefilesystem 0
+ file delete -force simpledir
+ file delete -force dir2
+ cd $dir
+} -result {0 {} 1 {error copying "simplefs:/simpledir" to "dir2/simpledir": file already exists} 0 {} 1 1}
+removeFile gorp.file
+test filesystem-7.8 {vfs cd} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+ file delete -force simpledir
+ file mkdir simpledir
+ testsimplefilesystem 1
+} -constraints testsimplefilesystem -body {
+ # This can variously cause an infinite loop or simply have no effect at
+ # all (before certain bugs were fixed, of course).
+ cd simplefs:/simpledir
+ pwd
+} -cleanup {
+ cd [tcltest::temporaryDirectory]
+ testsimplefilesystem 0
+ file delete -force simpledir
+ cd $dir
+} -result {simplefs:/simpledir}
+
+test filesystem-8.1 {relative path objects and caching of pwd} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ makeDirectory abc
+ makeDirectory def
+ makeFile "contents" [file join abc foo]
+ cd abc
+ set f "foo"
+ set res {}
+ lappend res [file exists $f]
+ lappend res [file exists $f]
+ cd ..
+ cd def
+ # If we haven't cleared the object's cwd cache, Tcl will think it still
+ # exists.
+ lappend res [file exists $f]
+ lappend res [file exists $f]
+} -cleanup {
+ removeFile [file join abc foo]
+ removeDirectory abc
+ removeDirectory def
+ cd $dir
+} -result {1 1 0 0}
+test filesystem-8.2 {relative path objects and use of pwd} -setup {
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ set dir "abc"
+ makeDirectory $dir
+ makeFile "contents" [file join abc foo]
+ cd $dir
+ file exists [lindex [glob *] 0]
+} -cleanup {
+ cd [tcltest::temporaryDirectory]
+ removeFile [file join abc foo]
+ removeDirectory abc
+ cd $origdir
+} -result 1
+test filesystem-8.3 {path objects and empty string} {
+ set anchor ""
+ set dst foo
+ set res $dst
+ set yyy [file split $anchor]
+ set dst [file join $anchor $dst]
+ lappend res $dst $yyy
+} {foo foo {}}
+
+proc TestFind1 {d f} {
+ set r1 [file exists [file join $d $f]]
+ lappend res "[file join $d $f] found: $r1"
+ lappend res "is dir a dir? [file isdirectory $d]"
+ set r2 [file exists [file join $d $f]]
+ lappend res "[file join $d $f] found: $r2"
+ return $res
+}
+proc TestFind2 {d f} {
+ set r1 [file exists [file join $d $f]]
+ lappend res "[file join $d $f] found: $r1"
+ lappend res "is dir a dir? [file isdirectory [file join $d]]"
+ set r2 [file exists [file join $d $f]]
+ lappend res "[file join $d $f] found: $r2"
+ return $res
+}
+
+test filesystem-9.1 {path objects and join and object rep} -setup {
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir [file join a b c]
+ TestFind1 a [file join b . c]
+} -cleanup {
+ file delete -force a
+ cd $origdir
+} -result {{a/b/./c found: 1} {is dir a dir? 1} {a/b/./c found: 1}}
+test filesystem-9.2 {path objects and join and object rep} -setup {
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir [file join a b c]
+ TestFind2 a [file join b . c]
+} -cleanup {
+ file delete -force a
+ cd $origdir
+} -result {{a/b/./c found: 1} {is dir a dir? 1} {a/b/./c found: 1}}
+test filesystem-9.2.1 {path objects and join and object rep} -setup {
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir [file join a b c]
+ TestFind2 a [file join b .]
+} -cleanup {
+ file delete -force a
+ cd $origdir
+} -result {{a/b/. found: 1} {is dir a dir? 1} {a/b/. found: 1}}
+test filesystem-9.3 {path objects and join and object rep} -setup {
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir [file join a b c]
+ TestFind1 a [file join b .. b c]
+} -cleanup {
+ file delete -force a
+ cd $origdir
+} -result {{a/b/../b/c found: 1} {is dir a dir? 1} {a/b/../b/c found: 1}}
+test filesystem-9.4 {path objects and join and object rep} -setup {
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir [file join a b c]
+ TestFind2 a [file join b .. b c]
+} -cleanup {
+ file delete -force a
+ cd $origdir
+} -result {{a/b/../b/c found: 1} {is dir a dir? 1} {a/b/../b/c found: 1}}
+test filesystem-9.5 {path objects and file tail and object rep} -setup {
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir dgp
+ close [open dgp/test w]
+ foreach relative [glob -nocomplain [file join * test]] {
+ set absolute [file join [pwd] $relative]
+ set res [list [file tail $absolute] "test"]
+ }
+ return $res
+} -cleanup {
+ file delete -force dgp
+ cd $origdir
+} -result {test test}
+test filesystem-9.6 {path objects and file tail and object rep} win {
+ set res {}
+ set p "C:\\toto"
+ lappend res [file join $p toto]
+ file isdirectory $p
+ lappend res [file join $p toto]
+} {C:/toto/toto C:/toto/toto}
+test filesystem-9.7 {path objects and glob and file tail and tilde} -setup {
+ set res {}
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir tilde
+ close [open tilde/~testNotExist w]
+ cd tilde
+ set file [lindex [glob *test*] 0]
+ lappend res [file exists $file] [catch {file tail $file} r] $r
+ lappend res $file
+ lappend res [file exists $file] [catch {file tail $file} r] $r
+ lappend res [catch {file tail $file} r] $r
+} -cleanup {
+ cd [tcltest::temporaryDirectory]
+ file delete -force tilde
+ cd $origdir
+} -result {0 1 {user "testNotExist" doesn't exist} ~testNotExist 0 1 {user "testNotExist" doesn't exist} 1 {user "testNotExist" doesn't exist}}
+test filesystem-9.8 {path objects and glob and file tail and tilde} -setup {
+ set res {}
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir tilde
+ close [open tilde/~testNotExist w]
+ cd tilde
+ set file1 [lindex [glob *test*] 0]
+ set file2 "~testNotExist"
+ lappend res $file1 $file2
+ lappend res [catch {file tail $file1} r] $r
+ lappend res [catch {file tail $file2} r] $r
+} -cleanup {
+ cd [tcltest::temporaryDirectory]
+ file delete -force tilde
+ cd $origdir
+} -result {~testNotExist ~testNotExist 1 {user "testNotExist" doesn't exist} 1 {user "testNotExist" doesn't exist}}
+test filesystem-9.9 {path objects and glob and file tail and tilde} -setup {
+ set res {}
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir tilde
+ close [open tilde/~testNotExist w]
+ cd tilde
+ set file1 [lindex [glob *test*] 0]
+ set file2 "~testNotExist"
+ lappend res [catch {file exists $file1} r] $r
+ lappend res [catch {file exists $file2} r] $r
+ lappend res [string equal $file1 $file2]
+} -cleanup {
+ cd [tcltest::temporaryDirectory]
+ file delete -force tilde
+ cd $origdir
+} -result {0 0 0 0 1}
+
+# ----------------------------------------------------------------------
+
+test filesystem-10.1 {Bug 3414754} {
+ string match */ [file join [pwd] foo/]
+} 0
+
+cleanupTests
+unset -nocomplain drive drives
+}
+namespace delete ::tcl::test::fileSystem
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/for-old.test b/library/msgcat/tests/for-old.test
new file mode 100644
index 0000000..a11a791
--- /dev/null
+++ b/library/msgcat/tests/for-old.test
@@ -0,0 +1,71 @@
+# Commands covered: for, continue, break
+#
+# This file contains the original set of tests for Tcl's for command.
+# Since the for command is now compiled, a new set of tests covering
+# the new implementation is in the file "for.test". Sourcing this file
+# into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# Check "for" and its use of continue and break.
+
+catch {unset a i}
+test for-old-1.1 {for tests} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} {
+ set a [concat $a $i]
+ }
+ set a
+} {1 2 3 4 5}
+test for-old-1.2 {for tests} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} {
+ if $i==4 continue
+ set a [concat $a $i]
+ }
+ set a
+} {1 2 3 5}
+test for-old-1.3 {for tests} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} {
+ if $i==4 break
+ set a [concat $a $i]
+ }
+ set a
+} {1 2 3}
+test for-old-1.4 {for tests} {catch {for 1 2 3} msg} 1
+test for-old-1.5 {for tests} {
+ catch {for 1 2 3} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-old-1.6 {for tests} {catch {for 1 2 3 4 5} msg} 1
+test for-old-1.7 {for tests} {
+ catch {for 1 2 3 4 5} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-old-1.8 {for tests} {
+ set a {xyz}
+ for {set i 1} {$i<6} {set i [expr $i+1]} {}
+ set a
+} xyz
+test for-old-1.9 {for tests} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]; if $i==4 break} {
+ set a [concat $a $i]
+ }
+ set a
+} {1 2 3}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/for.test b/library/msgcat/tests/for.test
new file mode 100644
index 0000000..ff4dc0e
--- /dev/null
+++ b/library/msgcat/tests/for.test
@@ -0,0 +1,830 @@
+# Commands covered: for, continue, break
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Basic "for" operation.
+
+test for-1.1 {TclCompileForCmd: missing initial command} {
+ list [catch {for} msg] $msg
+} {1 {wrong # args: should be "for start test next command"}}
+test for-1.2 {TclCompileForCmd: error in initial command} -body {
+ list [catch {for {set}} msg] $msg $::errorInfo
+} -match glob -result {1 {wrong # args: should be "for start test next command"} {wrong # args: should be "for start test next command"
+ while *ing
+"for {set}"}}
+catch {unset i}
+test for-1.3 {TclCompileForCmd: missing test expression} {
+ catch {for {set i 0}} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-1.4 {TclCompileForCmd: error in test expression} -body {
+ catch {for {set i 0} {$i<}} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "for start test next command"
+ while *ing
+"for {set i 0} {$i<}"}
+test for-1.5 {TclCompileForCmd: test expression is enclosed in quotes} {
+ set i 0
+ for {} "$i > 5" {incr i} {}
+} {}
+test for-1.6 {TclCompileForCmd: missing "next" command} {
+ catch {for {set i 0} {$i < 5}} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-1.7 {TclCompileForCmd: missing command body} {
+ catch {for {set i 0} {$i < 5} {incr i}} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-1.8 {TclCompileForCmd: error compiling command body} -body {
+ catch {for {set i 0} {$i < 5} {incr i} {set}} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+catch {unset a}
+test for-1.9 {TclCompileForCmd: simple command body} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} {
+ if $i==4 break
+ set a [concat $a $i]
+ }
+ set a
+} {1 2 3}
+test for-1.10 {TclCompileForCmd: command body in quotes} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} "append a x"
+ set a
+} {xxxxx}
+test for-1.11 {TclCompileForCmd: computed command body} {
+ catch {unset x1}
+ catch {unset bb}
+ catch {unset x2}
+ set x1 {append a x1; }
+ set bb {break}
+ set x2 {; append a x2}
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} $x1$bb$x2
+ set a
+} {x1}
+test for-1.12 {TclCompileForCmd: error in "next" command} -body {
+ catch {for {set i 0} {$i < 5} {set} {format $i}} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test for-1.13 {TclCompileForCmd: long command body} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} {
+ if $i==4 break
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ }
+ set a
+} {1 2 3}
+test for-1.14 {TclCompileForCmd: for command result} {
+ set a [for {set i 0} {$i < 5} {incr i} {}]
+ set a
+} {}
+test for-1.15 {TclCompileForCmd: for command result} {
+ set a [for {set i 0} {$i < 5} {incr i} {if $i==3 break}]
+ set a
+} {}
+
+# Check "for" and "continue".
+
+test for-2.1 {TclCompileContinueCmd: arguments after "continue"} {
+ catch {continue foo} msg
+ set msg
+} {wrong # args: should be "continue"}
+test for-2.2 {TclCompileContinueCmd: continue result} {
+ catch continue
+} 4
+test for-2.3 {continue tests} {
+ set a {}
+ for {set i 1} {$i <= 4} {set i [expr $i+1]} {
+ if {$i == 2} continue
+ set a [concat $a $i]
+ }
+ set a
+} {1 3 4}
+test for-2.4 {continue tests} {
+ set a {}
+ for {set i 1} {$i <= 4} {set i [expr $i+1]} {
+ if {$i != 2} continue
+ set a [concat $a $i]
+ }
+ set a
+} {2}
+test for-2.5 {continue tests, nested loops} {
+ set msg {}
+ for {set i 1} {$i <= 4} {incr i} {
+ for {set a 1} {$a <= 2} {incr a} {
+ if {$i>=2 && $a>=2} continue
+ set msg [concat $msg "$i.$a"]
+ }
+ }
+ set msg
+} {1.1 1.2 2.1 3.1 4.1}
+test for-2.6 {continue tests, long command body} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} {
+ if $i==2 continue
+ if $i==4 break
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ }
+ set a
+} {1 3}
+test for-2.7 {continue tests, uncompiled [for]} -body {
+ set file [makeFile {
+ set guard 0
+ for {set i 20} {$i > 0} {incr i -1} {
+ if {[incr guard]>30} {return BAD}
+ continue
+ }
+ return GOOD
+ } source.file]
+ source $file
+} -cleanup {
+ removeFile source.file
+} -result GOOD
+
+# Check "for" and "break".
+
+test for-3.1 {TclCompileBreakCmd: arguments after "break"} {
+ catch {break foo} msg
+ set msg
+} {wrong # args: should be "break"}
+test for-3.2 {TclCompileBreakCmd: break result} {
+ catch break
+} 3
+test for-3.3 {break tests} {
+ set a {}
+ for {set i 1} {$i <= 4} {incr i} {
+ if {$i == 3} break
+ set a [concat $a $i]
+ }
+ set a
+} {1 2}
+test for-3.4 {break tests, nested loops} {
+ set msg {}
+ for {set i 1} {$i <= 4} {incr i} {
+ for {set a 1} {$a <= 2} {incr a} {
+ if {$i>=2 && $a>=2} break
+ set msg [concat $msg "$i.$a"]
+ }
+ }
+ set msg
+} {1.1 1.2 2.1 3.1 4.1}
+test for-3.5 {break tests, long command body} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} {
+ if $i==2 continue
+ if $i==5 break
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if $i==4 break
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ }
+ set a
+} {1 3}
+# A simplified version of exmh's mail formatting routine to stress "for",
+# "break", "while", and "if".
+proc formatMail {} {
+ array set lines {
+ 0 {Return-path: george@tcl} \
+ 1 {Return-path: <george@tcl>} \
+ 2 {Received: from tcl by tcl.Somewhere.COM (SMI-8.6/SMI-SVR4)} \
+ 3 { id LAA10027; Wed, 11 Sep 1996 11:14:53 -0700} \
+ 4 {Message-id: <199609111814.LAA10027@tcl.Somewhere.COM>} \
+ 5 {X-mailer: exmh version 1.6.9 8/22/96} \
+ 6 {Mime-version: 1.0} \
+ 7 {Content-type: text/plain; charset=iso-8859-1} \
+ 8 {Content-transfer-encoding: quoted-printable} \
+ 9 {Content-length: 2162} \
+ 10 {To: fred} \
+ 11 {Subject: tcl7.6} \
+ 12 {Date: Wed, 11 Sep 1996 11:14:53 -0700} \
+ 13 {From: George <george@tcl>} \
+ 14 {The Tcl 7.6 and Tk 4.2 releases} \
+ 15 {} \
+ 16 {This page contains information about Tcl 7.6 and Tk4.2, which are the most recent} \
+ 17 {releases of the Tcl scripting language and the Tk toolkit. The first beta versions of these} \
+ 18 {releases were released on August 30, 1996. These releases contain only minor changes,} \
+ 19 {so we hope to have only a single beta release and to go final in early October, 1996. } \
+ 20 {} \
+ 21 {} \
+ 22 {What's new } \
+ 23 {} \
+ 24 {The most important changes in the releases are summarized below. See the README} \
+ 25 {and changes files in the distributions for more complete information on what has} \
+ 26 {changed, including both feature changes and bug fixes. } \
+ 27 {} \
+ 28 { There are new options to the file command for copying files (file copy),} \
+ 29 { deleting files and directories (file delete), creating directories (file} \
+ 30 { mkdir), and renaming files (file rename). } \
+ 31 { The implementation of exec has been improved greatly for Windows 95 and} \
+ 32 { Windows NT. } \
+ 33 { There is a new memory allocator for the Macintosh version, which should be} \
+ 34 { more efficient than the old one. } \
+ 35 { Tk's grid geometry manager has been completely rewritten. The layout} \
+ 36 { algorithm produces much better layouts than before, especially where rows or} \
+ 37 { columns were stretchable. } \
+ 38 { There are new commands for creating common dialog boxes:} \
+ 39 { tk_chooseColor, tk_getOpenFile, tk_getSaveFile and} \
+ 40 { tk_messageBox. These use native dialog boxes if they are available. } \
+ 41 { There is a new virtual event mechanism for handling events in a more portable} \
+ 42 { way. See the new command event. It also allows events (both physical and} \
+ 43 { virtual) to be generated dynamically. } \
+ 44 {} \
+ 45 {Tcl 7.6 and Tk 4.2 are backwards-compatible with Tcl 7.5 and Tk 4.1 except for} \
+ 46 {changes in the C APIs for custom channel drivers. Scripts written for earlier releases} \
+ 47 {should work on these new releases as well. } \
+ 48 {} \
+ 49 {Obtaining The Releases} \
+ 50 {} \
+ 51 {Binary Releases} \
+ 52 {} \
+ 53 {Pre-compiled releases are available for the following platforms: } \
+ 54 {} \
+ 55 { Windows 3.1, Windows 95, and Windows NT: Fetch} \
+ 56 { ftp://ftp.sunlabs.com/pub/tcl/win42b1.exe, then execute it. The file is a} \
+ 57 { self-extracting executable. It will install the Tcl and Tk libraries, the wish and} \
+ 58 { tclsh programs, and documentation. } \
+ 59 { Macintosh (both 68K and PowerPC): Fetch} \
+ 60 { ftp://ftp.sunlabs.com/pub/tcl/mactk4.2b1.sea.hqx. The file is in binhex format,} \
+ 61 { which is understood by Fetch, StuffIt, and many other Mac utilities. The} \
+ 62 { unpacked file is a self-installing executable: double-click on it and it will create a} \
+ 63 { folder containing all that you need to run Tcl and Tk. } \
+ 64 { UNIX (Solaris 2.* and SunOS, other systems soon to follow). Easy to install} \
+ 65 { binary packages are now for sale at the Sun Labs Tcl/Tk Shop. Check it out!} \
+ }
+
+ set result ""
+ set NL "
+"
+ set tag {level= type=text/plain part=0 sel Charset}
+ set ix [lsearch -regexp $tag text/enriched]
+ if {$ix < 0} {
+ set ranges {}
+ set quote 0
+ }
+ set breakrange {6.42 78.0}
+ set F1 [lindex $breakrange 0]
+ set F2 [lindex $breakrange 1]
+ set breakrange [lrange $breakrange 2 end]
+ if {[string length $F1] == 0} {
+ set F1 -1
+ set break 0
+ } else {
+ set break 1
+ }
+
+ set xmailer 0
+ set inheaders 1
+ set last [array size lines]
+ set plen 2
+ for {set L 1} {$L < $last} {incr L} {
+ set line $lines($L)
+ if {$inheaders} {
+ # Blank or empty line terminates headers
+ # Leading --- terminates headers
+ if {[regexp {^[ ]*$} $line] || [regexp {^--+} $line]} {
+ set inheaders 0
+ }
+ if {[regexp -nocase {^x-mailer:} $line]} {
+ continue
+ }
+ }
+ if $inheaders {
+ set limit 55
+ } else {
+ set limit 55
+
+ # Decide whether or not to break the body line
+
+ if {$plen > 0} {
+ if {[string first {> } $line] == 0} {
+ # This is quoted text from previous message, don't reformat
+ append result $line $NL
+ if {$quote && !$inheaders} {
+ # Fix from <sarr@umich.edu> to handle text/enriched
+ if {$L > $L1 && $L < $L2 && $line != {}} {
+ # enriched requires two newlines for each one.
+ append result $NL
+ } elseif {$L > $L2} {
+ set L1 [lindex $ranges 0]
+ set L2 [lindex $ranges 1]
+ set ranges [lrange $ranges 2 end]
+ set quote [llength $L1]
+ }
+ }
+ continue
+ }
+ }
+ if {$F1 < 0} {
+ # Nothing left to format
+ append result $line $NL
+ continue
+ } elseif {$L < $F1} {
+ # Not yet to formatted block
+ append result $line $NL
+ continue
+ } elseif {$L > $F2} {
+ # Past formatted block
+ set F1 [lindex $breakrange 0]
+ set F2 [lindex $breakrange 1]
+ set breakrange [lrange $breakrange 2 end]
+ append result $line $NL
+ if {[string length $F1] == 0} {
+ set F1 -1
+ }
+ continue
+ }
+ }
+ set climit [expr $limit-1]
+ set cutoff 50
+ set continuation 0
+
+ while {[string length $line] > $limit} {
+ for {set c [expr $limit-1]} {$c >= $cutoff} {incr c -1} {
+ set char [string index $line $c]
+ if {$char == " " || $char == "\t"} {
+ break
+ }
+ if {$char == ">"} { ;# Hack for enriched formatting
+ break
+ }
+ }
+ if {$c < $cutoff} {
+ if {! $inheaders} {
+ set c [expr $limit-1]
+ } else {
+ set c [string length $line]
+ }
+ }
+ set newline [string range $line 0 $c]
+ if {! $continuation} {
+ append result $newline $NL
+ } else {
+ append result \ $newline $NL
+ }
+ incr c
+ set line [string trimright [string range $line $c end]]
+ if {$inheaders} {
+ set continuation 1
+ set limit $climit
+ }
+ }
+ if {$continuation} {
+ if {[string length $line] != 0} {
+ append result \ $line $NL
+ }
+ } else {
+ append result $line $NL
+ if {$quote && !$inheaders} {
+ if {$L > $L1 && $L < $L2 && $line != {}} {
+ # enriched requires two newlines for each one.
+ append result "" $NL
+ } elseif {$L > $L2} {
+ set L1 [lindex $ranges 0]
+ set L2 [lindex $ranges 1]
+ set ranges [lrange $ranges 2 end]
+ set quote [llength $L1]
+ }
+ }
+ }
+ }
+ return $result
+}
+test for-3.6 {break tests} {
+ formatMail
+} {Return-path: <george@tcl>
+Received: from tcl by tcl.Somewhere.COM (SMI-8.6/SMI-SVR4)
+ id LAA10027; Wed, 11 Sep 1996 11:14:53 -0700
+Message-id: <199609111814.LAA10027@tcl.Somewhere.COM>
+Mime-version: 1.0
+Content-type: text/plain; charset=iso-8859-1
+Content-transfer-encoding: quoted-printable
+Content-length: 2162
+To: fred
+Subject: tcl7.6
+Date: Wed, 11 Sep 1996 11:14:53 -0700
+From: George <george@tcl>
+The Tcl 7.6 and Tk 4.2 releases
+
+This page contains information about Tcl 7.6 and Tk4.2,
+ which are the most recent
+releases of the Tcl scripting language and the Tk toolk
+it. The first beta versions of these
+releases were released on August 30, 1996. These releas
+es contain only minor changes,
+so we hope to have only a single beta release and to
+go final in early October, 1996.
+
+
+What's new
+
+The most important changes in the releases are summariz
+ed below. See the README
+and changes files in the distributions for more complet
+e information on what has
+changed, including both feature changes and bug fixes.
+
+ There are new options to the file command for
+copying files (file copy),
+ deleting files and directories (file delete),
+creating directories (file
+ mkdir), and renaming files (file rename).
+ The implementation of exec has been improved great
+ly for Windows 95 and
+ Windows NT.
+ There is a new memory allocator for the Macintosh
+version, which should be
+ more efficient than the old one.
+ Tk's grid geometry manager has been completely
+rewritten. The layout
+ algorithm produces much better layouts than before
+, especially where rows or
+ columns were stretchable.
+ There are new commands for creating common dialog
+boxes:
+ tk_chooseColor, tk_getOpenFile, tk_getSaveFile and
+ tk_messageBox. These use native dialog boxes if
+they are available.
+ There is a new virtual event mechanism for handlin
+g events in a more portable
+ way. See the new command event. It also allows
+events (both physical and
+ virtual) to be generated dynamically.
+
+Tcl 7.6 and Tk 4.2 are backwards-compatible with Tcl
+7.5 and Tk 4.1 except for
+changes in the C APIs for custom channel drivers. Scrip
+ts written for earlier releases
+should work on these new releases as well.
+
+Obtaining The Releases
+
+Binary Releases
+
+Pre-compiled releases are available for the following
+platforms:
+
+ Windows 3.1, Windows 95, and Windows NT: Fetch
+ ftp://ftp.sunlabs.com/pub/tcl/win42b1.exe, then
+execute it. The file is a
+ self-extracting executable. It will install the
+Tcl and Tk libraries, the wish and
+ tclsh programs, and documentation.
+ Macintosh (both 68K and PowerPC): Fetch
+ ftp://ftp.sunlabs.com/pub/tcl/mactk4.2b1.sea.hqx.
+The file is in binhex format,
+ which is understood by Fetch, StuffIt, and many
+other Mac utilities. The
+ unpacked file is a self-installing executable:
+double-click on it and it will create a
+ folder containing all that you need to run Tcl
+and Tk.
+ UNIX (Solaris 2.* and SunOS, other systems
+soon to follow). Easy to install
+ binary packages are now for sale at the Sun Labs
+Tcl/Tk Shop. Check it out!
+}
+
+# Check that "break" resets the interpreter's result
+
+test for-4.1 {break must reset the interp result} {
+ catch {
+ set z GLOBTESTDIR/dir2/file2.c
+ if [string match GLOBTESTDIR/dir2/* $z] {
+ break
+ }
+ } j
+ set j
+} {}
+
+# Test for incorrect "double evaluation" semantics
+
+test for-5.1 {possible delayed substitution of increment command} {
+ # Increment should be 5, and lappend should always append $a
+ catch {unset a}
+ catch {unset i}
+ set a 5
+ set i {}
+ for {set a 1} {$a < 12} "incr a $a" {lappend i $a}
+ set i
+} {1 6 11}
+
+test for-5.2 {possible delayed substitution of increment command} {
+ # Increment should be 5, and lappend should always append $a
+ catch {rename p ""}
+ proc p {} {
+ set a 5
+ set i {}
+ for {set a 1} {$a < 12} "incr a $a" {lappend i $a}
+ set i
+ }
+ p
+} {1 6 11}
+test for-5.3 {possible delayed substitution of body command} {
+ # Increment should be $a, and lappend should always append 5
+ set a 5
+ set i {}
+ for {set a 1} {$a < 12} {incr a $a} "lappend i $a"
+ set i
+} {5 5 5 5}
+test for-5.4 {possible delayed substitution of body command} {
+ # Increment should be $a, and lappend should always append 5
+ catch {rename p ""}
+ proc p {} {
+ set a 5
+ set i {}
+ for {set a 1} {$a < 12} {incr a $a} "lappend i $a"
+ set i
+ }
+ p
+} {5 5 5 5}
+
+# In the following tests we need to bypass the bytecode compiler by
+# substituting the command from a variable. This ensures that command
+# procedure is invoked directly.
+
+test for-6.1 {Tcl_ForObjCmd: number of args} {
+ set z for
+ catch {$z} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-6.2 {Tcl_ForObjCmd: number of args} {
+ set z for
+ catch {$z {set i 0}} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-6.3 {Tcl_ForObjCmd: number of args} {
+ set z for
+ catch {$z {set i 0} {$i < 5}} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-6.4 {Tcl_ForObjCmd: number of args} {
+ set z for
+ catch {$z {set i 0} {$i < 5} {incr i}} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-6.5 {Tcl_ForObjCmd: number of args} {
+ set z for
+ catch {$z {set i 0} {$i < 5} {incr i} {body} extra} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-6.6 {Tcl_ForObjCmd: error in initial command} -body {
+ set z for
+ list [catch {$z {set} {$i < 5} {incr i} {body}} msg] $msg $::errorInfo
+} -match glob -result {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"
+ ("for" initial command)
+ invoked from within
+"$z {set} {$i < 5} {incr i} {body}"}}
+test for-6.7 {Tcl_ForObjCmd: error in test expression} -body {
+ set z for
+ catch {$z {set i 0} {i < 5} {incr i} {body}}
+ set ::errorInfo
+} -match glob -result {*"$z {set i 0} {i < 5} {incr i} {body}"}
+test for-6.8 {Tcl_ForObjCmd: test expression is enclosed in quotes} {
+ set z for
+ set i 0
+ $z {set i 6} "$i > 5" {incr i} {set y $i}
+ set i
+} 6
+test for-6.9 {Tcl_ForObjCmd: error executing command body} -body {
+ set z for
+ catch {$z {set i 0} {$i < 5} {incr i} {set}} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"
+ ("for" body line 1)
+ invoked from within
+"$z {set i 0} {$i < 5} {incr i} {set}"}
+test for-6.10 {Tcl_ForObjCmd: simple command body} {
+ set z for
+ set a {}
+ $z {set i 1} {$i<6} {set i [expr $i+1]} {
+ if $i==4 break
+ set a [concat $a $i]
+ }
+ set a
+} {1 2 3}
+test for-6.11 {Tcl_ForObjCmd: command body in quotes} {
+ set z for
+ set a {}
+ $z {set i 1} {$i<6} {set i [expr $i+1]} "append a x"
+ set a
+} {xxxxx}
+test for-6.12 {Tcl_ForObjCmd: computed command body} {
+ set z for
+ catch {unset x1}
+ catch {unset bb}
+ catch {unset x2}
+ set x1 {append a x1; }
+ set bb {break}
+ set x2 {; append a x2}
+ set a {}
+ $z {set i 1} {$i<6} {set i [expr $i+1]} $x1$bb$x2
+ set a
+} {x1}
+test for-6.13 {Tcl_ForObjCmd: error in "next" command} -body {
+ set z for
+ catch {$z {set i 0} {$i < 5} {set} {set j 4}} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"
+ ("for" loop-end command)
+ invoked from within
+"$z {set i 0} {$i < 5} {set} {set j 4}"}
+test for-6.14 {Tcl_ForObjCmd: long command body} {
+ set z for
+ set a {}
+ $z {set i 1} {$i<6} {set i [expr $i+1]} {
+ if $i==4 break
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ }
+ set a
+} {1 2 3}
+test for-6.15 {Tcl_ForObjCmd: for command result} {
+ set z for
+ set a [$z {set i 0} {$i < 5} {incr i} {}]
+ set a
+} {}
+test for-6.16 {Tcl_ForObjCmd: for command result} {
+ set z for
+ set a [$z {set i 0} {$i < 5} {incr i} {if $i==3 break}]
+ set a
+} {}
+test for-6.17 {Tcl_ForObjCmd: for command result} {
+ list \
+ [catch {for {break} {1} {} {}} err] $err \
+ [catch {for {continue} {1} {} {}} err] $err \
+ [catch {for {} {[break]} {} {}} err] $err \
+ [catch {for {} {[continue]} {} {}} err] $err \
+ [catch {for {} {1} {break} {}} err] $err \
+ [catch {for {} {1} {continue} {}} err] $err \
+} [list \
+ 3 {} \
+ 4 {} \
+ 3 {} \
+ 4 {} \
+ 0 {} \
+ 4 {} \
+ ]
+test for-6.18 {Tcl_ForObjCmd: for command result} {
+ proc p6181 {} {
+ for {break} {1} {} {}
+ }
+ proc p6182 {} {
+ for {continue} {1} {} {}
+ }
+ proc p6183 {} {
+ for {} {[break]} {} {}
+ }
+ proc p6184 {} {
+ for {} {[continue]} {} {}
+ }
+ proc p6185 {} {
+ for {} {1} {break} {}
+ }
+ proc p6186 {} {
+ for {} {1} {continue} {}
+ }
+ list \
+ [catch {p6181} err] $err \
+ [catch {p6182} err] $err \
+ [catch {p6183} err] $err \
+ [catch {p6184} err] $err \
+ [catch {p6185} err] $err \
+ [catch {p6186} err] $err
+} [list \
+ 1 {invoked "break" outside of a loop} \
+ 1 {invoked "continue" outside of a loop} \
+ 1 {invoked "break" outside of a loop} \
+ 1 {invoked "continue" outside of a loop} \
+ 0 {} \
+ 1 {invoked "continue" outside of a loop} \
+ ]
+
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/foreach.test b/library/msgcat/tests/foreach.test
new file mode 100644
index 0000000..a4b652a
--- /dev/null
+++ b/library/msgcat/tests/foreach.test
@@ -0,0 +1,274 @@
+# Commands covered: foreach, continue, break
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+catch {unset a}
+catch {unset x}
+
+# Basic "foreach" operation.
+
+test foreach-1.1 {basic foreach tests} {
+ set a {}
+ foreach i {a b c d} {
+ set a [concat $a $i]
+ }
+ set a
+} {a b c d}
+test foreach-1.2 {basic foreach tests} {
+ set a {}
+ foreach i {a b {{c d} e} {123 {{x}}}} {
+ set a [concat $a $i]
+ }
+ set a
+} {a b {c d} e 123 {{x}}}
+test foreach-1.3 {basic foreach tests} {catch {foreach} msg} 1
+test foreach-1.4 {basic foreach tests} {
+ catch {foreach} msg
+ set msg
+} {wrong # args: should be "foreach varList list ?varList list ...? command"}
+test foreach-1.5 {basic foreach tests} {catch {foreach i} msg} 1
+test foreach-1.6 {basic foreach tests} {
+ catch {foreach i} msg
+ set msg
+} {wrong # args: should be "foreach varList list ?varList list ...? command"}
+test foreach-1.7 {basic foreach tests} {catch {foreach i j} msg} 1
+test foreach-1.8 {basic foreach tests} {
+ catch {foreach i j} msg
+ set msg
+} {wrong # args: should be "foreach varList list ?varList list ...? command"}
+test foreach-1.9 {basic foreach tests} {catch {foreach i j k l} msg} 1
+test foreach-1.10 {basic foreach tests} {
+ catch {foreach i j k l} msg
+ set msg
+} {wrong # args: should be "foreach varList list ?varList list ...? command"}
+test foreach-1.11 {basic foreach tests} {
+ set a {}
+ foreach i {} {
+ set a [concat $a $i]
+ }
+ set a
+} {}
+test foreach-1.12 {foreach errors} {
+ list [catch {foreach {{a}{b}} {1 2 3} {}} msg] $msg
+} {1 {list element in braces followed by "{b}" instead of space}}
+test foreach-1.13 {foreach errors} {
+ list [catch {foreach a {{1 2}3} {}} msg] $msg
+} {1 {list element in braces followed by "3" instead of space}}
+catch {unset a}
+test foreach-1.14 {foreach errors} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {foreach a {1 2 3} {}} msg o] $msg $::errorInfo
+} {1 {can't set "a": variable is array} {can't set "a": variable is array
+ (setting foreach loop variable "a")
+ invoked from within
+"foreach a {1 2 3} {}"}}
+test foreach-1.15 {foreach errors} {
+ list [catch {foreach {} {} {}} msg] $msg
+} {1 {foreach varlist is empty}}
+catch {unset a}
+
+test foreach-2.1 {parallel foreach tests} {
+ set x {}
+ foreach {a b} {1 2 3 4} {
+ append x $b $a
+ }
+ set x
+} {2143}
+test foreach-2.2 {parallel foreach tests} {
+ set x {}
+ foreach {a b} {1 2 3 4 5} {
+ append x $b $a
+ }
+ set x
+} {21435}
+test foreach-2.3 {parallel foreach tests} {
+ set x {}
+ foreach a {1 2 3} b {4 5 6} {
+ append x $b $a
+ }
+ set x
+} {415263}
+test foreach-2.4 {parallel foreach tests} {
+ set x {}
+ foreach a {1 2 3} b {4 5 6 7 8} {
+ append x $b $a
+ }
+ set x
+} {41526378}
+test foreach-2.5 {parallel foreach tests} {
+ set x {}
+ foreach {a b} {a b A B aa bb} c {c C cc CC} {
+ append x $a $b $c
+ }
+ set x
+} {abcABCaabbccCC}
+test foreach-2.6 {parallel foreach tests} {
+ set x {}
+ foreach a {1 2 3} b {1 2 3} c {1 2 3} d {1 2 3} e {1 2 3} {
+ append x $a $b $c $d $e
+ }
+ set x
+} {111112222233333}
+test foreach-2.7 {parallel foreach tests} {
+ set x {}
+ foreach a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
+ append x $a $b $c $d $e
+ }
+ set x
+} {1111 2222334}
+test foreach-2.8 {foreach only sets vars if repeating loop} {
+ proc foo {} {
+ set rgb {65535 0 0}
+ foreach {r g b} [set rgb] {}
+ return "r=$r, g=$g, b=$b"
+ }
+ foo
+} {r=65535, g=0, b=0}
+test foreach-2.9 {foreach only supports local scalar variables} {
+ proc foo {} {
+ set x {}
+ foreach {a(3)} {1 2 3 4} {lappend x [set {a(3)}]}
+ set x
+ }
+ foo
+} {1 2 3 4}
+
+test foreach-3.1 {compiled foreach backward jump works correctly} {
+ catch {unset x}
+ proc foo {arrayName} {
+ upvar 1 $arrayName a
+ set l {}
+ foreach member [array names a] {
+ lappend l [list $member [set a($member)]]
+ }
+ return $l
+ }
+ array set x {0 zero 1 one 2 two 3 three}
+ lsort [foo x]
+} [lsort {{0 zero} {1 one} {2 two} {3 three}}]
+
+test foreach-4.1 {noncompiled foreach and shared variable or value list objects that are converted to another type} {
+ catch {unset x}
+ foreach {12.0} {a b c} {
+ set x 12.0
+ set x [expr $x + 1]
+ }
+ set x
+} 13.0
+
+# Check "continue".
+
+test foreach-5.1 {continue tests} {catch continue} 4
+test foreach-5.2 {continue tests} {
+ set a {}
+ foreach i {a b c d} {
+ if {[string compare $i "b"] == 0} continue
+ set a [concat $a $i]
+ }
+ set a
+} {a c d}
+test foreach-5.3 {continue tests} {
+ set a {}
+ foreach i {a b c d} {
+ if {[string compare $i "b"] != 0} continue
+ set a [concat $a $i]
+ }
+ set a
+} {b}
+test foreach-5.4 {continue tests} {catch {continue foo} msg} 1
+test foreach-5.5 {continue tests} {
+ catch {continue foo} msg
+ set msg
+} {wrong # args: should be "continue"}
+
+# Check "break".
+
+test foreach-6.1 {break tests} {catch break} 3
+test foreach-6.2 {break tests} {
+ set a {}
+ foreach i {a b c d} {
+ if {[string compare $i "c"] == 0} break
+ set a [concat $a $i]
+ }
+ set a
+} {a b}
+test foreach-6.3 {break tests} {catch {break foo} msg} 1
+test foreach-6.4 {break tests} {
+ catch {break foo} msg
+ set msg
+} {wrong # args: should be "break"}
+# Check for bug #406709
+test foreach-6.5 {break tests} {
+ proc a {} {
+ set a 1
+ foreach b b {list [concat a; break]; incr a}
+ incr a
+ }
+ a
+} {2}
+
+# Test for incorrect "double evaluation" semantics
+test foreach-7.1 {delayed substitution of body} {
+ proc foo {} {
+ set a 0
+ foreach a [list 1 2 3] "
+ set x $a
+ "
+ set x
+ }
+ foo
+} {0}
+
+# Test for [Bug 1189274]; crash on failure
+test foreach-8.1 {empty list handling} {
+ proc crash {} {
+ rename crash {}
+ set a "x y z"
+ set b ""
+ foreach aa $a bb $b { set x "aa = $aa bb = $bb" }
+ }
+ crash
+} {}
+
+# [Bug 1671138]; infinite loop with empty var list in bytecompiled version
+test foreach-9.1 {compiled empty var list} {
+ proc foo {} {
+ foreach {} x {
+ error "reached body"
+ }
+ }
+ list [catch { foo } msg] $msg
+} {1 {foreach varlist is empty}}
+
+test foreach-10.1 {foreach: [Bug 1671087]} -setup {
+ proc demo {} {
+ set vals {1 2 3 4}
+ trace add variable x write {string length $vals ;# }
+ foreach {x y} $vals {format $y}
+ }
+} -body {
+ demo
+} -cleanup {
+ rename demo {}
+} -result {}
+
+# cleanup
+catch {unset a}
+catch {unset x}
+catch {rename foo {}}
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/format.test b/library/msgcat/tests/format.test
new file mode 100644
index 0000000..2d53eba
--- /dev/null
+++ b/library/msgcat/tests/format.test
@@ -0,0 +1,584 @@
+# Commands covered: format
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# %u output depends on word length, so this test is not portable.
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}]
+testConstraint wideIs64bit \
+ [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}]
+testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}]
+
+test format-1.1 {integer formatting} {
+ format "%*d %d %d %d" 6 34 16923 -12 -1
+} { 34 16923 -12 -1}
+test format-1.2 {integer formatting} {
+ format "%4d %4d %4d %4d %d %#x %#X" 6 34 16923 -12 -1 14 12
+} { 6 34 16923 -12 -1 0xe 0XC}
+test format-1.3 {integer formatting} longIs32bit {
+ format "%4u %4u %4u %4u %d %#o" 6 34 16923 -12 -1 0
+} { 6 34 16923 4294967284 -1 0}
+test format-1.3.1 {integer formatting} longIs64bit {
+ format "%4u %4u %4u %4u %d %#o" 6 34 16923 -12 -1 0
+} { 6 34 16923 18446744073709551604 -1 0}
+test format-1.4 {integer formatting} {
+ format "%-4d %-4i %-4d %-4ld" 6 34 16923 -12 -1
+} {6 34 16923 -12 }
+test format-1.5 {integer formatting} {
+ format "%04d %04d %04d %04i" 6 34 16923 -12 -1
+} {0006 0034 16923 -012}
+test format-1.6 {integer formatting} {
+ format "%00*d" 6 34
+} {000034}
+# Printing negative numbers in hex or octal format depends on word
+# length, so these tests are not portable.
+test format-1.7 {integer formatting} longIs32bit {
+ format "%4x %4x %4x %4x" 6 34 16923 -12 -1
+} { 6 22 421b fffffff4}
+test format-1.7.1 {integer formatting} longIs64bit {
+ format "%4x %4x %4x %4x" 6 34 16923 -12 -1
+} { 6 22 421b fffffffffffffff4}
+test format-1.8 {integer formatting} longIs32bit {
+ format "%#x %#X %#X %#x" 6 34 16923 -12 -1
+} {0x6 0X22 0X421B 0xfffffff4}
+test format-1.8.1 {integer formatting} longIs64bit {
+ format "%#x %#X %#X %#x" 6 34 16923 -12 -1
+} {0x6 0X22 0X421B 0xfffffffffffffff4}
+test format-1.9 {integer formatting} longIs32bit {
+ format "%#20x %#20x %#20x %#20x" 6 34 16923 -12 -1
+} { 0x6 0x22 0x421b 0xfffffff4}
+test format-1.9.1 {integer formatting} longIs64bit {
+ format "%#20x %#20x %#20x %#20x" 6 34 16923 -12 -1
+} { 0x6 0x22 0x421b 0xfffffffffffffff4}
+test format-1.10 {integer formatting} longIs32bit {
+ format "%-#20x %-#20x %-#20x %-#20x" 6 34 16923 -12 -1
+} {0x6 0x22 0x421b 0xfffffff4 }
+test format-1.10.1 {integer formatting} longIs64bit {
+ format "%-#20x %-#20x %-#20x %-#20x" 6 34 16923 -12 -1
+} {0x6 0x22 0x421b 0xfffffffffffffff4 }
+test format-1.11 {integer formatting} longIs32bit {
+ format "%-#20o %#-20o %#-20o %#-20o" 6 34 16923 -12 -1
+} {06 042 041033 037777777764 }
+test format-1.11.1 {integer formatting} longIs64bit {
+ format "%-#20o %#-20o %#-20o %#-20o" 6 34 16923 -12 -1
+} {06 042 041033 01777777777777777777764}
+test format-1.12 {integer formatting} {
+ format "%b %#b %llb" 5 5 [expr {2**100}]
+} {101 0b101 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000}
+
+test format-2.1 {string formatting} {
+ format "%s %s %c %s" abcd {This is a very long test string.} 120 x
+} {abcd This is a very long test string. x x}
+test format-2.2 {string formatting} {
+ format "%20s %20s %20c %20s" abcd {This is a very long test string.} 120 x
+} { abcd This is a very long test string. x x}
+test format-2.3 {string formatting} {
+ format "%.10s %.10s %c %.10s" abcd {This is a very long test string.} 120 x
+} {abcd This is a x x}
+test format-2.4 {string formatting} {
+ format "%s %s %% %c %s" abcd {This is a very long test string.} 120 x
+} {abcd This is a very long test string. % x x}
+test format-2.5 {string formatting, embedded nulls} {
+ format "%10s" abc\0def
+} " abc\0def"
+test format-2.6 {string formatting, international chars} {
+ format "%10s" abc\ufeffdef
+} " abc\ufeffdef"
+test format-2.7 {string formatting, international chars} {
+ format "%.5s" abc\ufeffdef
+} "abc\ufeffd"
+test format-2.8 {string formatting, international chars} {
+ format "foo\ufeffbar%s" baz
+} "foo\ufeffbarbaz"
+test format-2.9 {string formatting, width} {
+ format "a%5sa" f
+} "a fa"
+test format-2.10 {string formatting, width} {
+ format "a%-5sa" f
+} "af a"
+test format-2.11 {string formatting, width} {
+ format "a%2sa" foo
+} "afooa"
+test format-2.12 {string formatting, width} {
+ format "a%0sa" foo
+} "afooa"
+test format-2.13 {string formatting, precision} {
+ format "a%.2sa" foobarbaz
+} "afoa"
+test format-2.14 {string formatting, precision} {
+ format "a%.sa" foobarbaz
+} "aa"
+test format-2.15 {string formatting, precision} {
+ list [catch {format "a%.-2sa" foobarbaz} msg] $msg
+} {1 {bad field specifier "-"}}
+test format-2.16 {string formatting, width and precision} {
+ format "a%5.2sa" foobarbaz
+} "a foa"
+test format-2.17 {string formatting, width and precision} {
+ format "a%5.7sa" foobarbaz
+} "afoobarba"
+
+test format-3.1 {Tcl_FormatObjCmd: character formatting} {
+ format "|%c|%0c|%-1c|%1c|%-6c|%6c|%*c|%*c|" 65 65 65 65 65 65 3 65 -4 65
+} "|A|A|A|A|A | A| A|A |"
+test format-3.2 {Tcl_FormatObjCmd: international character formatting} {
+ format "|%c|%0c|%-1c|%1c|%-6c|%6c|%*c|%*c|" 0xa2 0x4e4e 0x25a 0xc3 0xff08 0 3 0x6575 -4 0x4e4f
+} "|\ua2|\u4e4e|\u25a|\uc3|\uff08 | \0| \u6575|\u4e4f |"
+
+test format-4.1 {e and f formats} {eformat} {
+ format "%e %e %e %e" 34.2e12 68.514 -.125 -16000. .000053
+} {3.420000e+13 6.851400e+01 -1.250000e-01 -1.600000e+04}
+test format-4.2 {e and f formats} {eformat} {
+ format "%20e %20e %20e %20e" 34.2e12 68.514 -.125 -16000. .000053
+} { 3.420000e+13 6.851400e+01 -1.250000e-01 -1.600000e+04}
+test format-4.3 {e and f formats} {eformat} {
+ format "%.1e %.1e %.1e %.1e" 34.2e12 68.514 -.126 -16000. .000053
+} {3.4e+13 6.9e+01 -1.3e-01 -1.6e+04}
+test format-4.4 {e and f formats} {eformat} {
+ format "%020e %020e %020e %020e" 34.2e12 68.514 -.126 -16000. .000053
+} {000000003.420000e+13 000000006.851400e+01 -00000001.260000e-01 -00000001.600000e+04}
+test format-4.5 {e and f formats} {eformat} {
+ format "%7.1e %7.1e %7.1e %7.1e" 34.2e12 68.514 -.126 -16000. .000053
+} {3.4e+13 6.9e+01 -1.3e-01 -1.6e+04}
+test format-4.6 {e and f formats} {
+ format "%f %f %f %f" 34.2e12 68.514 -.125 -16000. .000053
+} {34200000000000.000000 68.514000 -0.125000 -16000.000000}
+test format-4.7 {e and f formats} {
+ format "%.4f %.4f %.4f %.4f %.4f" 34.2e12 68.514 -.125 -16000. .000053
+} {34200000000000.0000 68.5140 -0.1250 -16000.0000 0.0001}
+test format-4.8 {e and f formats} {eformat} {
+ format "%.4e %.5e %.6e" -9.99996 -9.99996 9.99996
+} {-1.0000e+01 -9.99996e+00 9.999960e+00}
+test format-4.9 {e and f formats} {
+ format "%.4f %.5f %.6f" -9.99996 -9.99996 9.99996
+} {-10.0000 -9.99996 9.999960}
+test format-4.10 {e and f formats} {
+ format "%20f %-20f %020f" -9.99996 -9.99996 9.99996
+} { -9.999960 -9.999960 0000000000009.999960}
+test format-4.11 {e and f formats} {
+ format "%-020f %020f" -9.99996 -9.99996 9.99996
+} {-9.999960 -000000000009.999960}
+test format-4.12 {e and f formats} {eformat} {
+ format "%.0e %#.0e" -9.99996 -9.99996 9.99996
+} {-1e+01 -1.e+01}
+test format-4.13 {e and f formats} {
+ format "%.0f %#.0f" -9.99996 -9.99996 9.99996
+} {-10 -10.}
+test format-4.14 {e and f formats} {
+ format "%.4f %.5f %.6f" -9.99996 -9.99996 9.99996
+} {-10.0000 -9.99996 9.999960}
+test format-4.15 {e and f formats} {
+ format "%3.0f %3.0f %3.0f %3.0f" 1.0 1.1 1.01 1.001
+} { 1 1 1 1}
+test format-4.16 {e and f formats} {
+ format "%3.1f %3.1f %3.1f %3.1f" 0.0 0.1 0.01 0.001
+} {0.0 0.1 0.0 0.0}
+
+test format-5.1 {g-format} {eformat} {
+ format "%.3g" 12341.0
+} {1.23e+04}
+test format-5.2 {g-format} {eformat} {
+ format "%.3G" 1234.12345
+} {1.23E+03}
+test format-5.3 {g-format} {
+ format "%.3g" 123.412345
+} {123}
+test format-5.4 {g-format} {
+ format "%.3g" 12.3412345
+} {12.3}
+test format-5.5 {g-format} {
+ format "%.3g" 1.23412345
+} {1.23}
+test format-5.6 {g-format} {
+ format "%.3g" 1.23412345
+} {1.23}
+test format-5.7 {g-format} {
+ format "%.3g" .123412345
+} {0.123}
+test format-5.8 {g-format} {
+ format "%.3g" .012341
+} {0.0123}
+test format-5.9 {g-format} {
+ format "%.3g" .0012341
+} {0.00123}
+test format-5.10 {g-format} {
+ format "%.3g" .00012341
+} {0.000123}
+test format-5.11 {g-format} {eformat} {
+ format "%.3g" .00001234
+} {1.23e-05}
+test format-5.12 {g-format} {eformat} {
+ format "%.4g" 9999.6
+} {1e+04}
+test format-5.13 {g-format} {
+ format "%.4g" 999.96
+} {1000}
+test format-5.14 {g-format} {
+ format "%.3g" 1.0
+} {1}
+test format-5.15 {g-format} {
+ format "%.3g" .1
+} {0.1}
+test format-5.16 {g-format} {
+ format "%.3g" .01
+} {0.01}
+test format-5.17 {g-format} {
+ format "%.3g" .001
+} {0.001}
+test format-5.18 {g-format} {eformat} {
+ format "%.3g" .00001
+} {1e-05}
+test format-5.19 {g-format} {eformat} {
+ format "%#.3g" 1234.0
+} {1.23e+03}
+test format-5.20 {g-format} {eformat} {
+ format "%#.3G" 9999.5
+} {1.00E+04}
+
+test format-6.1 {floating-point zeroes} {eformat} {
+ format "%e %f %g" 0.0 0.0 0.0 0.0
+} {0.000000e+00 0.000000 0}
+test format-6.2 {floating-point zeroes} {eformat} {
+ format "%.4e %.4f %.4g" 0.0 0.0 0.0 0.0
+} {0.0000e+00 0.0000 0}
+test format-6.3 {floating-point zeroes} {eformat} {
+ format "%#.4e %#.4f %#.4g" 0.0 0.0 0.0 0.0
+} {0.0000e+00 0.0000 0.000}
+test format-6.4 {floating-point zeroes} {eformat} {
+ format "%.0e %.0f %.0g" 0.0 0.0 0.0 0.0
+} {0e+00 0 0}
+test format-6.5 {floating-point zeroes} {eformat} {
+ format "%#.0e %#.0f %#.0g" 0.0 0.0 0.0 0.0
+} {0.e+00 0. 0.}
+test format-6.6 {floating-point zeroes} {
+ format "%3.0f %3.0f %3.0f %3.0f" 0.0 0.0 0.0 0.0
+} { 0 0 0 0}
+test format-6.7 {floating-point zeroes} {
+ format "%3.0f %3.0f %3.0f %3.0f" 1.0 1.1 1.01 1.001
+} { 1 1 1 1}
+test format-6.8 {floating-point zeroes} {
+ format "%3.1f %3.1f %3.1f %3.1f" 0.0 0.1 0.01 0.001
+} {0.0 0.1 0.0 0.0}
+
+test format-7.1 {various syntax features} {
+ format "%*.*f" 12 3 12.345678901
+} { 12.346}
+test format-7.2 {various syntax features} {
+ format "%0*.*f" 12 3 12.345678901
+} {00000012.346}
+test format-7.3 {various syntax features} {
+ format "\*\t\\n"
+} {* \n}
+
+test format-8.1 {error conditions} {
+ catch format
+} 1
+test format-8.2 {error conditions} {
+ catch format msg
+ set msg
+} {wrong # args: should be "format formatString ?arg ...?"}
+test format-8.3 {error conditions} {
+ catch {format %*d}
+} 1
+test format-8.4 {error conditions} {
+ catch {format %*d} msg
+ set msg
+} {not enough arguments for all format specifiers}
+test format-8.5 {error conditions} {
+ catch {format %*.*f 12}
+} 1
+test format-8.6 {error conditions} {
+ catch {format %*.*f 12} msg
+ set msg
+} {not enough arguments for all format specifiers}
+test format-8.7 {error conditions} {
+ catch {format %*.*f 12 3}
+} 1
+test format-8.8 {error conditions} {
+ catch {format %*.*f 12 3} msg
+ set msg
+} {not enough arguments for all format specifiers}
+test format-8.9 {error conditions} {
+ list [catch {format %*d x 3} msg] $msg
+} {1 {expected integer but got "x"}}
+test format-8.10 {error conditions} {
+ list [catch {format %*.*f 2 xyz 3} msg] $msg
+} {1 {expected integer but got "xyz"}}
+test format-8.11 {error conditions} {
+ catch {format %d 2a}
+} 1
+test format-8.12 {error conditions} {
+ catch {format %d 2a} msg
+ set msg
+} {expected integer but got "2a"}
+test format-8.13 {error conditions} {
+ catch {format %c 2x}
+} 1
+test format-8.14 {error conditions} {
+ catch {format %c 2x} msg
+ set msg
+} {expected integer but got "2x"}
+test format-8.15 {error conditions} {
+ catch {format %f 2.1z}
+} 1
+test format-8.16 {error conditions} {
+ catch {format %f 2.1z} msg
+ set msg
+} {expected floating-point number but got "2.1z"}
+test format-8.17 {error conditions} {
+ catch {format ab%}
+} 1
+test format-8.18 {error conditions} {
+ catch {format ab% 12} msg
+ set msg
+} {format string ended in middle of field specifier}
+test format-8.19 {error conditions} {
+ catch {format %q x}
+} 1
+test format-8.20 {error conditions} {
+ catch {format %q x} msg
+ set msg
+} {bad field specifier "q"}
+test format-8.21 {error conditions} {
+ catch {format %d}
+} 1
+test format-8.22 {error conditions} {
+ catch {format %d} msg
+ set msg
+} {not enough arguments for all format specifiers}
+test format-8.23 {error conditions} {
+ catch {format "%d %d" 24 xyz} msg
+ set msg
+} {expected integer but got "xyz"}
+
+test format-9.1 {long result} {
+ set a {1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z}
+ format {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG %s %s} $a $a
+} {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z}
+
+test format-10.1 {"h" format specifier} {
+ format %hd 0xffff
+} -1
+test format-10.2 {"h" format specifier} {
+ format %hx 0x10fff
+} fff
+test format-10.3 {"h" format specifier} {
+ format %hd 0x10000
+} 0
+test format-10.4 {"h" format specifier} {
+ # Bug 1154163: This is minimal behaviour for %hx specifier!
+ format %hx 1
+} 1
+test format-10.5 {"h" format specifier} {
+ # Bug 1284178: Highly out-of-range values shouldn't cause errors
+ format %hu 0x100000000
+} 0
+
+test format-11.1 {XPG3 %$n specifiers} {
+ format {%2$d %1$d} 4 5
+} {5 4}
+test format-11.2 {XPG3 %$n specifiers} {
+ format {%2$d %1$d %1$d %3$d} 4 5 6
+} {5 4 4 6}
+test format-11.3 {XPG3 %$n specifiers} {
+ list [catch {format {%2$d %3$d} 4 5} msg] $msg
+} {1 {"%n$" argument index out of range}}
+test format-11.4 {XPG3 %$n specifiers} {
+ list [catch {format {%2$d %0$d} 4 5 6} msg] $msg
+} {1 {"%n$" argument index out of range}}
+test format-11.5 {XPG3 %$n specifiers} {
+ list [catch {format {%d %1$d} 4 5 6} msg] $msg
+} {1 {cannot mix "%" and "%n$" conversion specifiers}}
+test format-11.6 {XPG3 %$n specifiers} {
+ list [catch {format {%2$d %d} 4 5 6} msg] $msg
+} {1 {cannot mix "%" and "%n$" conversion specifiers}}
+test format-11.7 {XPG3 %$n specifiers} {
+ list [catch {format {%2$d %3d} 4 5 6} msg] $msg
+} {1 {cannot mix "%" and "%n$" conversion specifiers}}
+test format-11.8 {XPG3 %$n specifiers} {
+ format {%2$*d %3$d} 1 10 4
+} { 4 4}
+test format-11.9 {XPG3 %$n specifiers} {
+ format {%2$.*s %4$d} 1 5 abcdefghijklmnop 44
+} {abcde 44}
+test format-11.10 {XPG3 %$n specifiers} {
+ list [catch {format {%2$*d} 4} msg] $msg
+} {1 {"%n$" argument index out of range}}
+test format-11.11 {XPG3 %$n specifiers} {
+ list [catch {format {%2$*d} 4 5} msg] $msg
+} {1 {"%n$" argument index out of range}}
+test format-11.12 {XPG3 %$n specifiers} {
+ list [catch {format {%2$*d} 4 5 6} msg] $msg
+} {0 { 6}}
+
+test format-12.1 {negative width specifiers} {
+ format "%*d" -47 25
+} {25 }
+
+test format-13.1 {tcl_precision fuzzy comparison} {
+ catch {unset a}
+ catch {unset b}
+ catch {unset c}
+ catch {unset d}
+ set a 0.0000000000001
+ set b 0.00000000000001
+ set c 0.00000000000000001
+ set d [expr $a + $b + $c]
+ format {%0.10f %0.12f %0.15f %0.17f} $d $d $d $d
+} {0.0000000000 0.000000000000 0.000000000000110 0.00000000000011001}
+test format-13.2 {tcl_precision fuzzy comparison} {
+ catch {unset a}
+ catch {unset b}
+ catch {unset c}
+ catch {unset d}
+ set a 0.000000000001
+ set b 0.000000000000005
+ set c 0.0000000000000008
+ set d [expr $a + $b + $c]
+ format {%0.10f %0.12f %0.15f %0.17f} $d $d $d $d
+} {0.0000000000 0.000000000001 0.000000000001006 0.00000000000100580}
+test format-13.3 {tcl_precision fuzzy comparison} {
+ catch {unset a}
+ catch {unset b}
+ catch {unset c}
+ set a 0.00000000000099
+ set b 0.000000000000011
+ set c [expr $a + $b]
+ format {%0.10f %0.12f %0.15f %0.17f} $c $c $c $c
+} {0.0000000000 0.000000000001 0.000000000001001 0.00000000000100100}
+test format-13.4 {tcl_precision fuzzy comparison} {
+ catch {unset a}
+ catch {unset b}
+ catch {unset c}
+ set a 0.444444444444
+ set b 0.33333333333333
+ set c [expr $a + $b]
+ format {%0.10f %0.12f %0.15f %0.16f} $c $c $c $c
+} {0.7777777778 0.777777777777 0.777777777777330 0.7777777777773300}
+test format-13.5 {tcl_precision fuzzy comparison} {
+ catch {unset a}
+ catch {unset b}
+ catch {unset c}
+ set a 0.444444444444
+ set b 0.99999999999999
+ set c [expr $a + $b]
+ format {%0.10f %0.12f %0.15f} $c $c $c
+} {1.4444444444 1.444444444444 1.444444444443990}
+
+test format-14.1 {testing MAX_FLOAT_SIZE for 0 and 1} {
+ format {%s} ""
+} {}
+test format-14.2 {testing MAX_FLOAT_SIZE for 0 and 1} {
+ format {%s} "a"
+} {a}
+
+test format-15.1 {testing %0..s 0 padding for chars/strings} {
+ format %05s a
+} {0000a}
+test format-15.2 {testing %0..s 0 padding for chars/strings} {
+ format "% 5s" a
+} { a}
+test format-15.3 {testing %0..s 0 padding for chars/strings} {
+ format %5s a
+} { a}
+test format-15.4 {testing %0..s 0 padding for chars/strings} {
+ format %05c 61
+} {0000=}
+test format-15.5 {testing %d space padding for integers} {
+ format "(% 1d) (% 1d)" 10 -10
+} {( 10) (-10)}
+test format-15.6 {testing %d plus padding for integers} {
+ format "(%+1d) (%+1d)" 10 -10
+} {(+10) (-10)}
+
+set a "0123456789"
+set b ""
+for {set i 0} {$i < 290} {incr i} {
+ append b $a
+}
+for {set i 290} {$i < 400} {incr i} {
+ test format-16.[expr $i -289] {testing MAX_FLOAT_SIZE} {
+ format {%s} $b
+ } $b
+ append b "x"
+}
+
+test format-17.1 {testing %d with wide} {wideIs64bit wideBiggerThanInt} {
+ format %d 7810179016327718216
+} 1819043144
+test format-17.2 {testing %ld with wide} {wideIs64bit} {
+ format %ld 7810179016327718216
+} 7810179016327718216
+test format-17.3 {testing %ld with non-wide} {wideIs64bit} {
+ format %ld 42
+} 42
+test format-17.4 {testing %l with non-integer} {
+ format %lf 1
+} 1.000000
+
+test format-18.1 {do not demote existing numeric values} {
+ set a 0xaaaaaaaa
+ # Ensure $a and $b are separate objects
+ set b 0xaaaa
+ append b aaaa
+ set result [expr {$a == $b}]
+ format %08lx $b
+ lappend result [expr {$a == $b}]
+ set b 0xaaaa
+ append b aaaa
+ lappend result [expr {$a == $b}]
+ format %08x $b
+ lappend result [expr {$a == $b}]
+} {1 1 1 1}
+test format-18.2 {do not demote existing numeric values} {wideBiggerThanInt} {
+ set a [expr {0xaaaaaaaaaa + 1}]
+ set b 0xaaaaaaaaab
+ list [format %08x $a] [expr {$a == $b}]
+} {aaaaaaab 1}
+
+test format-19.1 {
+ regression test - tcl-core message by Brian Griffin on
+ 26 0ctober 2004
+} -body {
+ set x 0x8fedc654
+ list [expr { ~ $x }] [format %08x [expr { ~$x }]]
+} -match regexp -result {-2414724693 f*701239ab}
+test format-19.2 {Bug 1867855} {
+ format %llx 0
+} 0
+test format-19.3 {Bug 2830354} {
+ string length [format %340f 0]
+} 340
+
+# Note that this test may fail in future versions
+test format-20.1 {Bug 2932421: plain %s caused intrep change of args} -body {
+ set x [dict create a b c d]
+ format %s $x
+ # After this, obj in $x should be a dict with a non-NULL bytes field
+ tcl::unsupported::representation $x
+} -match glob -result {value is a dict with *, string representation "*".}
+
+# cleanup
+catch {unset a}
+catch {unset b}
+catch {unset c}
+catch {unset d}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/get.test b/library/msgcat/tests/get.test
new file mode 100644
index 0000000..40ec98f
--- /dev/null
+++ b/library/msgcat/tests/get.test
@@ -0,0 +1,98 @@
+# Commands covered: none
+#
+# This file contains a collection of tests for the procedures in the
+# file tclGet.c. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1995-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testgetint [llength [info commands testgetint]]
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}]
+
+test get-1.1 {Tcl_GetInt procedure} testgetint {
+ testgetint 44 { 22}
+} {66}
+test get-1.2 {Tcl_GetInt procedure} testgetint {
+ testgetint 44 -3
+} {41}
+test get-1.3 {Tcl_GetInt procedure} testgetint {
+ testgetint 44 +8
+} {52}
+test get-1.4 {Tcl_GetInt procedure} testgetint {
+ list [catch {testgetint 44 foo} msg] $msg
+} {1 {expected integer but got "foo"}}
+test get-1.5 {Tcl_GetInt procedure} testgetint {
+ list [catch {testgetint 44 {16 }} msg] $msg
+} {0 60}
+test get-1.6 {Tcl_GetInt procedure} testgetint {
+ list [catch {testgetint 44 {16 x}} msg] $msg
+} {1 {expected integer but got "16 x"}}
+test get-1.7 {Tcl_GetInt procedure} {testgetint longIs64bit} {
+ list [catch {testgetint 44 18446744073709551616} msg] $msg $errorCode
+} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
+test get-1.8 {Tcl_GetInt procedure} {testgetint longIs64bit} {
+ list [catch {testgetint 18446744073709551614} msg] $msg
+} {0 -2}
+test get-1.9 {Tcl_GetInt procedure} {testgetint longIs64bit} {
+ list [catch {testgetint +18446744073709551614} msg] $msg
+} {0 -2}
+test get-1.10 {Tcl_GetInt procedure} {testgetint longIs64bit} {
+ list [catch {testgetint -18446744073709551614} msg] $msg
+} {0 2}
+test get-1.11 {Tcl_GetInt procedure} {testgetint longIs32bit} {
+ list [catch {testgetint 44 4294967296} msg] $msg $errorCode
+} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
+test get-1.12 {Tcl_GetInt procedure} {testgetint longIs32bit} {
+ list [catch {testgetint 4294967294} msg] $msg
+} {0 -2}
+test get-1.13 {Tcl_GetInt procedure} {testgetint longIs32bit} {
+ list [catch {testgetint +4294967294} msg] $msg
+} {0 -2}
+test get-1.14 {Tcl_GetInt procedure} {testgetint longIs32bit} {
+ list [catch {testgetint -4294967294} msg] $msg
+} {0 2}
+
+test get-2.1 {Tcl_GetInt procedure} {
+ format %g 1.23
+} {1.23}
+test get-2.2 {Tcl_GetInt procedure} {
+ format %g { 1.23 }
+} {1.23}
+test get-2.3 {Tcl_GetInt procedure} {
+ list [catch {format %g clip} msg] $msg
+} {1 {expected floating-point number but got "clip"}}
+test get-2.4 {Tcl_GetInt procedure} {
+ format %g .000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
+} 0
+
+test get-3.1 {Tcl_GetInt(FromObj), bad numbers} {
+ # SF bug #634856
+ set result ""
+ set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1" "+12345678987654321" "++12345678987654321"]
+ foreach num $numbers {
+ lappend result [catch {format %ld $num} msg] $msg
+ }
+ set result
+} {0 1 0 1 1 {expected integer but got "++1"} 1 {expected integer but got "+-1"} 1 {expected integer but got "-+1"} 0 -1 1 {expected integer but got "--1"} 1 {expected integer but got "- +1"} 0 12345678987654321 1 {expected integer but got "++12345678987654321"}}
+test get-3.2 {Tcl_GetDouble(FromObj), bad numbers} {
+ set result ""
+ set numbers [list 1.0 +1.0 ++1.0 +-1.0 -+1.0 -1.0 --1.0 "- +1.0"]
+ foreach num $numbers {
+ lappend result [catch {format %g $num} msg] $msg
+ }
+ set result
+} {0 1 0 1 1 {expected floating-point number but got "++1.0"} 1 {expected floating-point number but got "+-1.0"} 1 {expected floating-point number but got "-+1.0"} 0 -1 1 {expected floating-point number but got "--1.0"} 1 {expected floating-point number but got "- +1.0"}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/history.test b/library/msgcat/tests/history.test
new file mode 100644
index 0000000..c562796
--- /dev/null
+++ b/library/msgcat/tests/history.test
@@ -0,0 +1,250 @@
+# Commands covered: history
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# The history command might be autoloaded...
+if {[catch {history}]} {
+ testConstraint history 0
+} else {
+ testConstraint history 1
+}
+
+if {[testConstraint history]} {
+ set num [history nextid]
+ history keep 3
+ history add {set a 12345}
+ history add {set b [format {A test %s} string]}
+ history add {Another test}
+} else {
+ # Dummy value, must be numeric
+ set num 0
+}
+
+# "history event"
+
+test history-1.1 {event option} history {history event -1} \
+ {set b [format {A test %s} string]}
+test history-1.2 {event option} history {history event $num} \
+ {set a 12345}
+test history-1.3 {event option} history {history event [expr $num+2]} \
+ {Another test}
+test history-1.4 {event option} history {history event set} \
+ {set b [format {A test %s} string]}
+test history-1.5 {event option} history {history e "* a*"} \
+ {set a 12345}
+test history-1.6 {event option} history {catch {history event *gorp} msg} 1
+test history-1.7 {event option} history {
+ catch {history event *gorp} msg
+ set msg
+} {no event matches "*gorp"}
+test history-1.8 {event option} history {history event} \
+ {set b [format {A test %s} string]}
+test history-1.9 {event option} history {catch {history event 123 456} msg} 1
+test history-1.10 {event option} history {
+ catch {history event 123 456} msg
+ set msg
+} {wrong # args: should be "history event ?event?"}
+
+# "history redo"
+
+if {[testConstraint history]} {
+ set a 0
+ history redo -2
+}
+test history-2.1 {redo option} history {set a} 12345
+if {[testConstraint history]} {
+ set b 0
+ history redo
+}
+test history-2.2 {redo option} history {set b} {A test string}
+test history-2.3 {redo option} history {catch {history redo -3 -4}} 1
+test history-2.4 {redo option} history {
+ catch {history redo -3 -4} msg
+ set msg
+} {wrong # args: should be "history redo ?event?"}
+
+# "history add"
+
+if {[testConstraint history]} {
+ history add "set a 444" exec
+}
+test history-3.1 {add option} history {set a} 444
+test history-3.2 {add option} history {catch {history add "set a 444" execGorp}} 1
+test history-3.3 {add option} history {
+ catch {history add "set a 444" execGorp} msg
+ set msg
+} {bad argument "execGorp": should be "exec"}
+test history-3.4 {add option} history {catch {history add "set a 444" a} msg} 1
+test history-3.5 {add option} history {
+ catch {history add "set a 444" a} msg
+ set msg
+} {bad argument "a": should be "exec"}
+if {[testConstraint history]} {
+ history add "set a 555" e
+}
+test history-3.6 {add option} history {set a} 555
+if {[testConstraint history]} {
+ history add "set a 666"
+}
+test history-3.7 {add option} history {set a} 555
+test history-3.8 {add option} history {catch {history add "set a 666" e f} msg} 1
+test history-3.9 {add option} history {
+ catch {history add "set a 666" e f} msg
+ set msg
+} {wrong # args: should be "history add event ?exec?"}
+
+# "history change"
+
+if {[testConstraint history]} {
+ history change "A test value"
+}
+test history-4.1 {change option} history {history event [expr {[history n]-1}]} \
+ "A test value"
+if {[testConstraint history]} {
+ history ch "Another test" -1
+}
+test history-4.2 {change option} history {history e} "Another test"
+test history-4.3 {change option} history {history event [expr {[history n]-1}]} \
+ "A test value"
+test history-4.4 {change option} history {catch {history change Foo 4 10}} 1
+test history-4.5 {change option} history {
+ catch {history change Foo 4 10} msg
+ set msg
+} {wrong # args: should be "history change newValue ?event?"}
+test history-4.6 {change option} history {
+ catch {history change Foo [expr {[history n]-4}]}
+} 1
+if {[testConstraint history]} {
+ set num [expr {[history n]-4}]
+}
+test history-4.7 {change option} history {
+ catch {history change Foo $num} msg
+ set msg
+} "event \"$num\" is too far in the past"
+
+# "history info"
+
+if {[testConstraint history]} {
+ set num [history n]
+ history add set\ a\ {b\nc\ d\ e}
+ history add {set b 1234}
+ history add set\ c\ {a\nb\nc}
+}
+test history-5.1 {info option} history {history info} [format {%6d set a {b
+ c d e}
+%6d set b 1234
+%6d set c {a
+ b
+ c}} $num [expr $num+1] [expr $num+2]]
+test history-5.2 {info option} history {history i 2} [format {%6d set b 1234
+%6d set c {a
+ b
+ c}} [expr $num+1] [expr $num+2]]
+test history-5.3 {info option} history {catch {history i 2 3}} 1
+test history-5.4 {info option} history {
+ catch {history i 2 3} msg
+ set msg
+} {wrong # args: should be "history info ?count?"}
+test history-5.5 {info option} history {history} [format {%6d set a {b
+ c d e}
+%6d set b 1234
+%6d set c {a
+ b
+ c}} $num [expr $num+1] [expr $num+2]]
+
+# "history keep"
+
+if {[testConstraint history]} {
+ history add "foo1"
+ history add "foo2"
+ history add "foo3"
+ history keep 2
+}
+test history-6.1 {keep option} history {history event [expr [history n]-1]} foo3
+test history-6.2 {keep option} history {history event -1} foo2
+test history-6.3 {keep option} history {catch {history event -3}} 1
+test history-6.4 {keep option} history {
+ catch {history event -3} msg
+ set msg
+} {event "-3" is too far in the past}
+if {[testConstraint history]} {
+ history k 5
+}
+test history-6.5 {keep option} history {history event -1} foo2
+test history-6.6 {keep option} history {history event -2} {}
+test history-6.7 {keep option} history {history event -3} {}
+test history-6.8 {keep option} history {history event -4} {}
+test history-6.9 {keep option} history {catch {history event -5}} 1
+test history-6.10 {keep option} history {catch {history keep 4 6}} 1
+test history-6.11 {keep option} history {
+ catch {history keep 4 6} msg
+ set msg
+} {wrong # args: should be "history keep ?count?"}
+test history-6.12 {keep option} history {catch {history keep}} 0
+test history-6.13 {keep option} history {
+ history keep
+} {5}
+test history-6.14 {keep option} history {catch {history keep -3}} 1
+test history-6.15 {keep option} history {
+ catch {history keep -3} msg
+ set msg
+} {illegal keep count "-3"}
+test history-6.16 {keep option} history {
+ catch {history keep butter} msg
+ set msg
+} {illegal keep count "butter"}
+
+# "history nextid"
+
+if {[testConstraint history]} {
+ set num [history n]
+ history add "Testing"
+ history add "Testing2"
+}
+test history-7.1 {nextid option} history {history event} "Testing"
+test history-7.2 {nextid option} history {history next} [expr $num+2]
+test history-7.3 {nextid option} history {catch {history nextid garbage}} 1
+test history-7.4 {nextid option} history {
+ catch {history nextid garbage} msg
+ set msg
+} {wrong # args: should be "history nextid"}
+
+# "history clear"
+
+if {[testConstraint history]} {
+ set num [history n]
+ history add "Testing"
+ history add "Testing2"
+}
+test history-8.1 {clear option} history {catch {history clear junk}} 1
+test history-8.2 {clear option} history {history clear} {}
+if {[testConstraint history]} {
+ history add "Testing"
+}
+test history-8.3 {clear option} history {history} { 1 Testing}
+
+# miscellaneous
+
+test history-9.1 {miscellaneous} history {catch {history gorp} msg} 1
+test history-9.2 {miscellaneous} history {
+ catch {history gorp} msg
+ set msg
+} {unknown or ambiguous subcommand "gorp": must be add, change, clear, event, info, keep, nextid, or redo}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/http.test b/library/msgcat/tests/http.test
new file mode 100644
index 0000000..37d4a05
--- /dev/null
+++ b/library/msgcat/tests/http.test
@@ -0,0 +1,632 @@
+# Commands covered: http::config, http::geturl, http::wait, http::reset
+#
+# This file contains a collection of tests for the http script library.
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 by Ajuba Solutions.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+if {[catch {package require http 2} version]} {
+ if {[info exists http2]} {
+ catch {puts "Cannot load http 2.* package"}
+ return
+ } else {
+ catch {puts "Running http 2.* tests in slave interp"}
+ set interp [interp create http2]
+ $interp eval [list set http2 "running"]
+ $interp eval [list set argv $argv]
+ $interp eval [list source [info script]]
+ interp delete $interp
+ return
+ }
+}
+
+proc bgerror {args} {
+ global errorInfo
+ puts stderr "http.test bgerror"
+ puts stderr [join $args]
+ puts stderr $errorInfo
+}
+
+set port 8010
+set bindata "This is binary data\x0d\x0amore\x0dmore\x0amore\x00null"
+catch {unset data}
+
+# Ensure httpd file exists
+
+set origFile [file join [pwd] [file dirname [info script]] httpd]
+set httpdFile [file join [temporaryDirectory] httpd_[pid]]
+if {![file exists $httpdFile]} {
+ makeFile "" $httpdFile
+ file delete $httpdFile
+ file copy $origFile $httpdFile
+ set removeHttpd 1
+}
+
+catch {package require Thread 2.6}
+if {[catch {package present Thread}] == 0 && [file exists $httpdFile]} {
+ set httpthread [thread::create -preserved]
+ thread::send $httpthread [list source $httpdFile]
+ thread::send $httpthread [list set port $port]
+ thread::send $httpthread [list set bindata $bindata]
+ thread::send $httpthread {httpd_init $port}
+ puts "Running httpd in thread $httpthread"
+} else {
+ if {![file exists $httpdFile]} {
+ puts "Cannot read $httpdFile script, http test skipped"
+ unset port
+ return
+ }
+ source $httpdFile
+ # Let the OS pick the port; that's much more flexible
+ if {[catch {httpd_init 0} listen]} {
+ puts "Cannot start http server, http test skipped"
+ unset port
+ return
+ } else {
+ set port [lindex [fconfigure $listen -sockname] 2]
+ }
+}
+
+test http-1.1 {http::config} {
+ http::config -useragent UserAgent
+ http::config
+} [list -accept */* -proxyfilter http::ProxyRequired -proxyhost {} -proxyport {} -urlencoding utf-8 -useragent "UserAgent"]
+test http-1.2 {http::config} {
+ http::config -proxyfilter
+} http::ProxyRequired
+test http-1.3 {http::config} {
+ catch {http::config -junk}
+} 1
+test http-1.4 {http::config} {
+ set savedconf [http::config]
+ http::config -proxyhost nowhere.come -proxyport 8080 \
+ -proxyfilter myFilter -useragent "Tcl Test Suite" \
+ -urlencoding iso8859-1
+ set x [http::config]
+ http::config {*}$savedconf
+ set x
+} {-accept */* -proxyfilter myFilter -proxyhost nowhere.come -proxyport 8080 -urlencoding iso8859-1 -useragent {Tcl Test Suite}}
+test http-1.5 {http::config} -returnCodes error -body {
+ http::config -proxyhost {} -junk 8080
+} -result {Unknown option -junk, must be: -accept, -proxyfilter, -proxyhost, -proxyport, -urlencoding, -useragent}
+test http-1.6 {http::config} -setup {
+ set oldenc [http::config -urlencoding]
+} -body {
+ set enc [list [http::config -urlencoding]]
+ http::config -urlencoding iso8859-1
+ lappend enc [http::config -urlencoding]
+} -cleanup {
+ http::config -urlencoding $oldenc
+} -result {utf-8 iso8859-1}
+
+test http-2.1 {http::reset} {
+ catch {http::reset http#1}
+} 0
+
+test http-3.1 {http::geturl} -returnCodes error -body {
+ http::geturl -bogus flag
+} -result {Unknown option flag, can be: -binary, -blocksize, -channel, -command, -handler, -headers, -keepalive, -method, -myaddr, -progress, -protocol, -query, -queryblocksize, -querychannel, -queryprogress, -strict, -timeout, -type, -validate}
+test http-3.2 {http::geturl} -returnCodes error -body {
+ http::geturl http:junk
+} -result {Unsupported URL: http:junk}
+set url //[info hostname]:$port
+set badurl //[info hostname]:6666
+test http-3.3 {http::geturl} -body {
+ set token [http::geturl $url]
+ http::data $token
+} -cleanup {
+ http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET /</h2>
+</body></html>"
+set tail /a/b/c
+set url //[info hostname]:$port/a/b/c
+set fullurl http://user:pass@[info hostname]:$port/a/b/c
+set binurl //[info hostname]:$port/binary
+set posturl //[info hostname]:$port/post
+set badposturl //[info hostname]:$port/droppost
+test http-3.4 {http::geturl} -body {
+ set token [http::geturl $url]
+ http::data $token
+} -cleanup {
+ http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+proc selfproxy {host} {
+ global port
+ return [list [info hostname] $port]
+}
+test http-3.5 {http::geturl} -body {
+ http::config -proxyfilter selfproxy
+ set token [http::geturl $url]
+ http::data $token
+} -cleanup {
+ http::config -proxyfilter http::ProxyRequired
+ http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET http:$url</h2>
+</body></html>"
+test http-3.6 {http::geturl} -body {
+ http::config -proxyfilter bogus
+ set token [http::geturl $url]
+ http::data $token
+} -cleanup {
+ http::config -proxyfilter http::ProxyRequired
+ http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+test http-3.7 {http::geturl} -body {
+ set token [http::geturl $url -headers {Pragma no-cache}]
+ http::data $token
+} -cleanup {
+ http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+test http-3.8 {http::geturl} -body {
+ set token [http::geturl $url -query Name=Value&Foo=Bar -timeout 2000]
+ http::data $token
+} -cleanup {
+ http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>POST $tail</h2>
+<h2>Query</h2>
+<dl>
+<dt>Name<dd>Value
+<dt>Foo<dd>Bar
+</dl>
+</body></html>"
+test http-3.9 {http::geturl} -body {
+ set token [http::geturl $url -validate 1]
+ http::code $token
+} -cleanup {
+ http::cleanup $token
+} -result "HTTP/1.0 200 OK"
+test http-3.10 {http::geturl queryprogress} -setup {
+ set query foo=bar
+ set sep ""
+ set i 0
+ # Create about 120K of query data
+ while {$i < 14} {
+ incr i
+ append query $sep$query
+ set sep &
+ }
+} -body {
+ proc postProgress {token x y} {
+ global postProgress
+ lappend postProgress $y
+ }
+ set postProgress {}
+ set t [http::geturl $posturl -keepalive 0 -query $query \
+ -queryprogress postProgress -queryblocksize 16384]
+ http::wait $t
+ list [http::status $t] [string length $query] $postProgress [http::data $t]
+} -cleanup {
+ http::cleanup $t
+} -result {ok 122879 {16384 32768 49152 65536 81920 98304 114688 122879} {Got 122879 bytes}}
+test http-3.11 {http::geturl querychannel with -command} -setup {
+ set query foo=bar
+ set sep ""
+ set i 0
+ # Create about 120K of query data
+ while {$i < 14} {
+ incr i
+ append query $sep$query
+ set sep &
+ }
+ set file [makeFile $query outdata]
+} -body {
+ set fp [open $file]
+ proc asyncCB {token} {
+ global postResult
+ lappend postResult [http::data $token]
+ }
+ set postResult [list ]
+ set t [http::geturl $posturl -querychannel $fp]
+ http::wait $t
+ set testRes [list [http::status $t] [string length $query] [http::data $t]]
+ # Now do async
+ http::cleanup $t
+ close $fp
+ set fp [open $file]
+ set t [http::geturl $posturl -querychannel $fp -command asyncCB]
+ set postResult [list PostStart]
+ http::wait $t
+ close $fp
+ lappend testRes [http::status $t] $postResult
+} -cleanup {
+ removeFile outdata
+ http::cleanup $t
+} -result {ok 122879 {Got 122880 bytes} ok {PostStart {Got 122880 bytes}}}
+# On Linux platforms when the client and server are on the same host, the
+# client is unable to read the server's response one it hits the write error.
+# The status is "eof".
+# On Windows, the http::wait procedure gets a "connection reset by peer" error
+# while reading the reply.
+test http-3.12 {http::geturl querychannel with aborted request} -setup {
+ set query foo=bar
+ set sep ""
+ set i 0
+ # Create about 120K of query data
+ while {$i < 14} {
+ incr i
+ append query $sep$query
+ set sep &
+ }
+ set file [makeFile $query outdata]
+} -constraints {nonPortable} -body {
+ set fp [open $file]
+ proc asyncCB {token} {
+ global postResult
+ lappend postResult [http::data $token]
+ }
+ proc postProgress {token x y} {
+ global postProgress
+ lappend postProgress $y
+ }
+ set postProgress {}
+ # Now do async
+ set postResult [list PostStart]
+ if {[catch {
+ set t [http::geturl $badposturl -querychannel $fp -command asyncCB \
+ -queryprogress postProgress]
+ http::wait $t
+ upvar #0 $t state
+ } err]} {
+ puts $::errorInfo
+ error $err
+ }
+ list [http::status $t] [http::code $t]
+} -cleanup {
+ removeFile outdata
+ http::cleanup $t
+} -result {ok {HTTP/1.0 200 Data follows}}
+test http-3.13 {http::geturl socket leak test} {
+ set chanCount [llength [file channels]]
+ for {set i 0} {$i < 3} {incr i} {
+ catch {http::geturl $badurl -timeout 5000}
+ }
+
+ # No extra channels should be taken
+ expr {[llength [file channels]] == $chanCount}
+} 1
+test http-3.14 "http::geturl $fullurl" -body {
+ set token [http::geturl $fullurl -validate 1]
+ http::code $token
+} -cleanup {
+ http::cleanup $token
+} -result "HTTP/1.0 200 OK"
+test http-3.15 {http::geturl parse failures} -body {
+ http::geturl "{invalid}:url"
+} -returnCodes error -result {Unsupported URL: {invalid}:url}
+test http-3.16 {http::geturl parse failures} -body {
+ http::geturl http:relative/url
+} -returnCodes error -result {Unsupported URL: http:relative/url}
+test http-3.17 {http::geturl parse failures} -body {
+ http::geturl /absolute/url
+} -returnCodes error -result {Missing host part: /absolute/url}
+test http-3.18 {http::geturl parse failures} -body {
+ http::geturl http://somewhere:123456789/
+} -returnCodes error -result {Invalid port number: 123456789}
+test http-3.19 {http::geturl parse failures} -body {
+ http::geturl http://{user}@somewhere
+} -returnCodes error -result {Illegal characters in URL user}
+test http-3.20 {http::geturl parse failures} -body {
+ http::geturl http://%user@somewhere
+} -returnCodes error -result {Illegal encoding character usage "%us" in URL user}
+test http-3.21 {http::geturl parse failures} -body {
+ http::geturl http://somewhere/{path}
+} -returnCodes error -result {Illegal characters in URL path}
+test http-3.22 {http::geturl parse failures} -body {
+ http::geturl http://somewhere/%path
+} -returnCodes error -result {Illegal encoding character usage "%pa" in URL path}
+test http-3.23 {http::geturl parse failures} -body {
+ http::geturl http://somewhere/path?{query}?
+} -returnCodes error -result {Illegal characters in URL path}
+test http-3.24 {http::geturl parse failures} -body {
+ http::geturl http://somewhere/path?%query
+} -returnCodes error -result {Illegal encoding character usage "%qu" in URL path}
+test http-3.25 {http::meta} -setup {
+ unset -nocomplain m token
+} -body {
+ set token [http::geturl $url -timeout 2000]
+ array set m [http::meta $token]
+ lsort [array names m]
+} -cleanup {
+ http::cleanup $token
+ unset -nocomplain m token
+} -result {Content-Length Content-Type Date}
+test http-3.26 {http::meta} -setup {
+ unset -nocomplain m token
+} -body {
+ set token [http::geturl $url -headers {X-Check 1} -timeout 2000]
+ array set m [http::meta $token]
+ lsort [array names m]
+} -cleanup {
+ http::cleanup $token
+ unset -nocomplain m token
+} -result {Content-Length Content-Type Date X-Check}
+test http-3.27 {http::geturl: -headers override -type} -body {
+ set token [http::geturl $url/headers -type "text/plain" -query dummy \
+ -headers [list "Content-Type" "text/plain;charset=utf-8"]]
+ http::data $token
+} -cleanup {
+ http::cleanup $token
+} -match regexp -result {(?n)Accept \*/\*
+Host .*
+User-Agent .*
+Connection close
+Content-Type {text/plain;charset=utf-8}
+Accept-Encoding .*
+Content-Length 5}
+test http-3.28 {http::geturl: -headers override -type default} -body {
+ set token [http::geturl $url/headers -query dummy \
+ -headers [list "Content-Type" "text/plain;charset=utf-8"]]
+ http::data $token
+} -cleanup {
+ http::cleanup $token
+} -match regexp -result {(?n)Accept \*/\*
+Host .*
+User-Agent .*
+Connection close
+Content-Type {text/plain;charset=utf-8}
+Accept-Encoding .*
+Content-Length 5}
+
+test http-4.1 {http::Event} -body {
+ set token [http::geturl $url -keepalive 0]
+ upvar #0 $token data
+ array set meta $data(meta)
+ expr {($data(totalsize) == $meta(Content-Length))}
+} -cleanup {
+ http::cleanup $token
+} -result 1
+test http-4.2 {http::Event} -body {
+ set token [http::geturl $url]
+ upvar #0 $token data
+ array set meta $data(meta)
+ string compare $data(type) [string trim $meta(Content-Type)]
+} -cleanup {
+ http::cleanup $token
+} -result 0
+test http-4.3 {http::Event} -body {
+ set token [http::geturl $url]
+ http::code $token
+} -cleanup {
+ http::cleanup $token
+} -result {HTTP/1.0 200 Data follows}
+test http-4.4 {http::Event} -setup {
+ set testfile [makeFile "" testfile]
+} -body {
+ set out [open $testfile w]
+ set token [http::geturl $url -channel $out]
+ close $out
+ set in [open $testfile]
+ set x [read $in]
+} -cleanup {
+ catch {close $in}
+ catch {close $out}
+ removeFile $testfile
+ http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+test http-4.5 {http::Event} -setup {
+ set testfile [makeFile "" testfile]
+} -body {
+ set out [open $testfile w]
+ fconfigure $out -translation lf
+ set token [http::geturl $url -channel $out]
+ close $out
+ upvar #0 $token data
+ expr {$data(currentsize) == $data(totalsize)}
+} -cleanup {
+ removeFile $testfile
+ http::cleanup $token
+} -result 1
+test http-4.6 {http::Event} -setup {
+ set testfile [makeFile "" testfile]
+} -body {
+ set out [open $testfile w]
+ set token [http::geturl $binurl -channel $out]
+ close $out
+ set in [open $testfile]
+ fconfigure $in -translation binary
+ read $in
+} -cleanup {
+ catch {close $in}
+ catch {close $out}
+ removeFile $testfile
+ http::cleanup $token
+} -result "$bindata[string trimleft $binurl /]"
+proc myProgress {token total current} {
+ global progress httpLog
+ if {[info exists httpLog] && $httpLog} {
+ puts "progress $total $current"
+ }
+ set progress [list $total $current]
+}
+if 0 {
+ # This test hangs on Windows95 because the client never gets EOF
+ set httpLog 1
+ test http-4.6.1 {http::Event} knownBug {
+ set token [http::geturl $url -blocksize 50 -progress myProgress]
+ return $progress
+ } {111 111}
+}
+test http-4.7 {http::Event} -body {
+ set token [http::geturl $url -keepalive 0 -progress myProgress]
+ return $progress
+} -cleanup {
+ http::cleanup $token
+} -result {111 111}
+test http-4.8 {http::Event} -body {
+ set token [http::geturl $url]
+ http::status $token
+} -cleanup {
+ http::cleanup $token
+} -result {ok}
+test http-4.9 {http::Event} -body {
+ set token [http::geturl $url -progress myProgress]
+ http::code $token
+} -cleanup {
+ http::cleanup $token
+} -result {HTTP/1.0 200 Data follows}
+test http-4.10 {http::Event} -body {
+ set token [http::geturl $url -progress myProgress]
+ http::size $token
+} -cleanup {
+ http::cleanup $token
+} -result {111}
+# Timeout cases
+# Short timeout to working server (the test server). This lets us try a
+# reset during the connection.
+test http-4.11 {http::Event} -body {
+ set token [http::geturl $url -timeout 1 -keepalive 0 -command \#]
+ http::reset $token
+ http::status $token
+} -cleanup {
+ http::cleanup $token
+} -result {reset}
+# Longer timeout with reset.
+test http-4.12 {http::Event} -body {
+ set token [http::geturl $url/?timeout=10 -keepalive 0 -command \#]
+ http::reset $token
+ http::status $token
+} -cleanup {
+ http::cleanup $token
+} -result {reset}
+# Medium timeout to working server that waits even longer. The timeout
+# hits while waiting for a reply.
+test http-4.13 {http::Event} -body {
+ set token [http::geturl $url?timeout=30 -keepalive 0 -timeout 10 -command \#]
+ http::wait $token
+ http::status $token
+} -cleanup {
+ http::cleanup $token
+} -result {timeout}
+# Longer timeout to good host, bad port, gets an error after the
+# connection "completes" but the socket is bad.
+test http-4.14 {http::Event} -body {
+ set token [http::geturl $badurl/?timeout=10 -timeout 10000 -command \#]
+ if {$token eq ""} {
+ error "bogus return from http::geturl"
+ }
+ http::wait $token
+ http::status $token
+ # error code varies among platforms.
+} -returnCodes 1 -match regexp -cleanup {
+ catch {http::cleanup $token}
+} -result {(connect failed|couldn't open socket)}
+# Bogus host
+test http-4.15 {http::Event} -body {
+ # This test may fail if you use a proxy server. That is to be
+ # expected and is not a problem with Tcl.
+ set token [http::geturl //not_a_host.tcl.tk -timeout 1000 -command \#]
+ http::wait $token
+ http::status $token
+ # error codes vary among platforms.
+} -cleanup {
+ catch {http::cleanup $token}
+} -returnCodes 1 -match glob -result "couldn't open socket*"
+
+test http-5.1 {http::formatQuery} {
+ http::formatQuery name1 value1 name2 "value two"
+} {name1=value1&name2=value%20two}
+# test http-5.2 obsoleted by 5.4 and 5.5 with http 2.5
+test http-5.3 {http::formatQuery} {
+ http::formatQuery lines "line1\nline2\nline3"
+} {lines=line1%0D%0Aline2%0D%0Aline3}
+test http-5.4 {http::formatQuery} {
+ http::formatQuery name1 ~bwelch name2 \xa1\xa2\xa2
+} {name1=~bwelch&name2=%C2%A1%C2%A2%C2%A2}
+test http-5.5 {http::formatQuery} {
+ set enc [http::config -urlencoding]
+ http::config -urlencoding iso8859-1
+ set res [http::formatQuery name1 ~bwelch name2 \xa1\xa2\xa2]
+ http::config -urlencoding $enc
+ set res
+} {name1=~bwelch&name2=%A1%A2%A2}
+
+test http-6.1 {http::ProxyRequired} -body {
+ http::config -proxyhost [info hostname] -proxyport $port
+ set token [http::geturl $url]
+ http::wait $token
+ upvar #0 $token data
+ set data(body)
+} -cleanup {
+ http::config -proxyhost {} -proxyport {}
+ http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET http:$url</h2>
+</body></html>"
+
+test http-7.1 {http::mapReply} {
+ http::mapReply "abc\$\[\]\"\\()\}\{"
+} {abc%24%5B%5D%22%5C%28%29%7D%7B}
+test http-7.2 {http::mapReply} {
+ # RFC 2718 specifies that we pass urlencoding on utf-8 chars by default,
+ # so make sure this gets converted to utf-8 then urlencoded.
+ http::mapReply "\u2208"
+} {%E2%88%88}
+test http-7.3 {http::formatQuery} -setup {
+ set enc [http::config -urlencoding]
+} -returnCodes error -body {
+ # this would be reverting to http <=2.4 behavior
+ http::config -urlencoding ""
+ http::mapReply "\u2208"
+} -cleanup {
+ http::config -urlencoding $enc
+} -result "can't read \"formMap(\u2208)\": no such element in array"
+test http-7.4 {http::formatQuery} -setup {
+ set enc [http::config -urlencoding]
+} -body {
+ # this would be reverting to http <=2.4 behavior w/o errors
+ # (unknown chars become '?')
+ http::config -urlencoding "iso8859-1"
+ http::mapReply "\u2208"
+} -cleanup {
+ http::config -urlencoding $enc
+} -result {%3F}
+
+# cleanup
+catch {unset url}
+catch {unset badurl}
+catch {unset port}
+catch {unset data}
+if {[info exists httpthread]} {
+ thread::release $httpthread
+} else {
+ close $listen
+}
+
+if {[info exists removeHttpd]} {
+ removeFile $httpdFile
+}
+
+rename bgerror {}
+::tcltest::cleanupTests
+
+# Local variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/http11.test b/library/msgcat/tests/http11.test
new file mode 100644
index 0000000..230ce5a
--- /dev/null
+++ b/library/msgcat/tests/http11.test
@@ -0,0 +1,656 @@
+# http11.test -- -*- tcl-*-
+#
+# Test HTTP/1.1 features.
+#
+# Copyright (C) 2009 Pat Thoyts <patthoyts@users.sourceforge.net>
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+package require http 2.8
+
+# start the server
+variable httpd_output
+proc create_httpd {} {
+ proc httpd_read {chan} {
+ variable httpd_output
+ if {[gets $chan line] != -1} {
+ #puts stderr "read '$line'"
+ set httpd_output $line
+ }
+ if {[eof $chan]} {
+ puts stderr "eof from httpd"
+ fileevent $chan readable {}
+ close $chan
+ }
+ }
+ variable httpd_output
+ set httpd_script [file join [pwd] [file dirname [info script]] httpd11.tcl]
+ set httpd [open "|[list [interpreter] -encoding utf-8 $httpd_script]" r+]
+ fconfigure $httpd -buffering line -blocking 0
+ fileevent $httpd readable [list httpd_read $httpd]
+ vwait httpd_output
+ variable httpd_port [lindex $httpd_output 2]
+ return $httpd
+}
+
+proc halt_httpd {} {
+ variable httpd_output
+ variable httpd
+ if {[info exists httpd]} {
+ puts $httpd "quit"
+ vwait httpd_output
+ close $httpd
+ }
+ unset -nocomplain httpd_output httpd
+}
+
+proc meta {tok {key ""}} {
+ set meta [http::meta $tok]
+ if {$key ne ""} {
+ if {[dict exists $meta $key]} {
+ return [dict get $meta $key]
+ } else {
+ return ""
+ }
+ }
+ return $meta
+}
+
+proc check_crc {tok args} {
+ set crc [meta $tok x-crc32]
+ set data [expr {[llength $args] ? [lindex $args 0] : [http::data $tok]}]
+ set chk [format %x [zlib crc32 $data]]
+ if {$crc ne $chk} {
+ return "crc32 mismatch: $crc ne $chk"
+ }
+ return "ok"
+}
+
+makeFile "<html><head><title>test</title></head>\
+<body><p>this is a test</p>\n\
+[string repeat {<p>This is a tcl test file.</p>} 4192]\n\
+</body></html>" testdoc.html
+
+# -------------------------------------------------------------------------
+
+test http11-1.0 "normal request for document " -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html -timeout 10000]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] [meta $tok connection]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close}
+
+test http11-1.1 "normal,gzip,non-chunked" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 10000 -headers {accept-encoding gzip}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok gzip {}}
+
+test http11-1.2 "normal,deflated,non-chunked" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 10000 -headers {accept-encoding deflate}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok deflate {}}
+
+test http11-1.3 "normal,compressed,non-chunked" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 10000 -headers {accept-encoding compress}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok compress {}}
+
+test http11-1.4 "normal,identity,non-chunked" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 10000 -headers {accept-encoding identity}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {} {}}
+
+test http11-1.5 "normal request for document, unsupported coding" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 10000 -headers {accept-encoding unsupported}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {}}
+
+test http11-1.6 "normal, specify 1.1 " -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -protocol 1.1 -timeout 10000]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok connection] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close chunked}
+
+test http11-1.7 "normal, 1.1 and keepalive " -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -protocol 1.1 -keepalive 1 -timeout 10000]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok connection] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {} chunked}
+
+test http11-1.8 "normal, 1.1 and keepalive, server close" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -protocol 1.1 -keepalive 1 -timeout 10000]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok connection] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close {}}
+
+test http11-1.9 "normal,gzip,chunked" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 10000 -headers {accept-encoding gzip}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok gzip chunked}
+
+test http11-1.10 "normal,deflate,chunked" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 10000 -headers {accept-encoding deflate}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok deflate chunked}
+
+test http11-1.11 "normal,compress,chunked" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 10000 -headers {accept-encoding compress}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok compress chunked}
+
+test http11-1.12 "normal,identity,chunked" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 10000 -headers {accept-encoding identity}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {} chunked}
+
+# -------------------------------------------------------------------------
+
+test http11-2.0 "-channel" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 5000 -channel $chan]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close chunked}
+
+test http11-2.1 "-channel, encoding gzip" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 5000 -channel $chan -headers {accept-encoding gzip}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close gzip chunked}
+
+test http11-2.2 "-channel, encoding deflate" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 5000 -channel $chan -headers {accept-encoding deflate}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close deflate chunked}
+
+test http11-2.3 "-channel,encoding compress" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 5000 -channel $chan \
+ -headers {accept-encoding compress}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close compress chunked}
+
+test http11-2.4 "-channel,encoding identity" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 5000 -channel $chan \
+ -headers {accept-encoding identity}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close {} chunked}
+
+test http11-2.5 "-channel,encoding unsupported" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 5000 -channel $chan \
+ -headers {accept-encoding unsupported}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close {} chunked}
+
+test http11-2.6 "-channel,encoding gzip,non-chunked" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 5000 -channel $chan -headers {accept-encoding gzip}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]\
+ [expr {[file size testdoc.html]-[file size testfile.tmp]}]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close gzip {} 0}
+
+test http11-2.7 "-channel,encoding deflate,non-chunked" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 5000 -channel $chan -headers {accept-encoding deflate}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]\
+ [expr {[file size testdoc.html]-[file size testfile.tmp]}]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close deflate {} 0}
+
+test http11-2.8 "-channel,encoding compress,non-chunked" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 5000 -channel $chan -headers {accept-encoding compress}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]\
+ [expr {[file size testdoc.html]-[file size testfile.tmp]}]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close compress {} 0}
+
+test http11-2.9 "-channel,encoding identity,non-chunked" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 5000 -channel $chan -headers {accept-encoding identity}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]\
+ [expr {[file size testdoc.html]-[file size testfile.tmp]}]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close {} {} 0}
+
+test http11-2.10 "-channel,deflate,keepalive" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 5000 -channel $chan -keepalive 1]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]\
+ [expr {[file size testdoc.html]-[file size testfile.tmp]}]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {} deflate chunked 0}
+
+test http11-2.11 "-channel,identity,keepalive" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -headers {accept-encoding identity} \
+ -timeout 5000 -channel $chan -keepalive 1]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {} {} chunked}
+
+# -------------------------------------------------------------------------
+#
+# The following tests for the -handler option will require changes in
+# the future. At the moment we cannot handler chunked data with this
+# option. Therefore we currently force HTTP/1.0 protocol version.
+#
+# Once this is solved, these tests should be fixed to assume chunked
+# returns in 3.2 and 3.3 and HTTP/1.1 in all but test 3.1
+
+proc handler {var sock token} {
+ upvar #0 $var data
+ set chunk [read $sock]
+ append data $chunk
+ #::http::Log "handler read [string length $chunk] ([chan configure $sock -buffersize])"
+ if {[eof $sock]} {
+ #::http::Log "handler eof $sock"
+ chan event $sock readable {}
+ }
+}
+
+test http11-3.0 "-handler,close,identity" -setup {
+ variable httpd [create_httpd]
+ set testdata ""
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 10000 -handler [namespace code [list handler testdata]]]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
+ [meta $tok connection] [meta $tok content-encoding] \
+ [meta $tok transfer-encoding] \
+ [expr {[file size testdoc.html]-[string length $testdata]}]
+} -cleanup {
+ http::cleanup $tok
+ unset -nocomplain testdata
+ halt_httpd
+} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}
+
+test http11-3.1 "-handler,protocol1.0" -setup {
+ variable httpd [create_httpd]
+ set testdata ""
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 10000 -protocol 1.0 \
+ -handler [namespace code [list handler testdata]]]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
+ [meta $tok connection] [meta $tok content-encoding] \
+ [meta $tok transfer-encoding] \
+ [expr {[file size testdoc.html]-[string length $testdata]}]
+} -cleanup {
+ http::cleanup $tok
+ unset -nocomplain testdata
+ halt_httpd
+} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}
+
+test http11-3.2 "-handler,close,chunked" -setup {
+ variable httpd [create_httpd]
+ set testdata ""
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 10000 -keepalive 0 -binary 1\
+ -handler [namespace code [list handler testdata]]]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
+ [meta $tok connection] [meta $tok content-encoding] \
+ [meta $tok transfer-encoding] \
+ [expr {[file size testdoc.html]-[string length $testdata]}]
+} -cleanup {
+ http::cleanup $tok
+ unset -nocomplain testdata
+ halt_httpd
+} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}
+
+test http11-3.3 "-handler,keepalive,chunked" -setup {
+ variable httpd [create_httpd]
+ set testdata ""
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 10000 -keepalive 1 -binary 1\
+ -handler [namespace code [list handler testdata]]]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
+ [meta $tok connection] [meta $tok content-encoding] \
+ [meta $tok transfer-encoding] \
+ [expr {[file size testdoc.html]-[string length $testdata]}]
+} -cleanup {
+ http::cleanup $tok
+ unset -nocomplain testdata
+ halt_httpd
+} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}
+
+test http11-4.0 "normal post request" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set query [http::formatQuery q 1 z 2]
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -query $query -timeout 10000]
+ http::wait $tok
+ list status [http::status $tok] code [http::code $tok]\
+ crc [check_crc $tok]\
+ connection [meta $tok connection]\
+ query-length [meta $tok x-query-length]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 7}
+
+test http11-4.1 "normal post request, check query length" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set query [http::formatQuery q 1 z 2]
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -headers [list x-check-query yes] \
+ -query $query -timeout 10000]
+ http::wait $tok
+ list status [http::status $tok] code [http::code $tok]\
+ crc [check_crc $tok]\
+ connection [meta $tok connection]\
+ query-length [meta $tok x-query-length]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 7}
+
+test http11-4.2 "normal post request, check long query length" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set query [string repeat a 24576]
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html\
+ -headers [list x-check-query yes]\
+ -query $query -timeout 10000]
+ http::wait $tok
+ list status [http::status $tok] code [http::code $tok]\
+ crc [check_crc $tok]\
+ connection [meta $tok connection]\
+ query-length [meta $tok x-query-length]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 24576}
+
+test http11-4.3 "normal post request, check channel query length" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+ puts -nonewline $chan [string repeat [encoding convertto utf-8 "This is a test\n"] 8192]
+ flush $chan
+ seek $chan 0
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html\
+ -headers [list x-check-query yes]\
+ -querychannel $chan -timeout 10000]
+ http::wait $tok
+ list status [http::status $tok] code [http::code $tok]\
+ crc [check_crc $tok]\
+ connection [meta $tok connection]\
+ query-length [meta $tok x-query-length]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 122880}
+
+# -------------------------------------------------------------------------
+
+foreach p {create_httpd httpd_read halt_httpd meta check_crc} {
+ if {[llength [info proc $p]]} {rename $p {}}
+}
+removeFile testdoc.html
+unset -nocomplain httpd_port httpd p
+
+::tcltest::cleanupTests
diff --git a/library/msgcat/tests/httpd b/library/msgcat/tests/httpd
new file mode 100644
index 0000000..f810797
--- /dev/null
+++ b/library/msgcat/tests/httpd
@@ -0,0 +1,236 @@
+# -*- tcl -*-
+#
+# The httpd_ procedures implement a stub http server.
+#
+# Copyright (c) 1997-1998 Sun Microsystems, Inc.
+# Copyright (c) 1999-2000 Scriptics Corporation
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+#set httpLog 1
+
+proc httpd_init {{port 8015}} {
+ socket -server httpdAccept $port
+}
+proc httpd_log {args} {
+ global httpLog
+ if {[info exists httpLog] && $httpLog} {
+ puts stderr "httpd: [join $args { }]"
+ }
+}
+array set httpdErrors {
+ 204 {No Content}
+ 400 {Bad Request}
+ 401 {Authorization Required}
+ 404 {Not Found}
+ 503 {Service Unavailable}
+ 504 {Service Temporarily Unavailable}
+}
+
+proc httpdError {sock code args} {
+ global httpdErrors
+ puts $sock "$code $httpdErrors($code)"
+ httpd_log "error: [join $args { }]"
+}
+proc httpdAccept {newsock ipaddr port} {
+ global httpd
+ upvar #0 httpd$newsock data
+
+ fconfigure $newsock -blocking 0 -translation {auto crlf}
+ httpd_log $newsock Connect $ipaddr $port
+ set data(ipaddr) $ipaddr
+ fileevent $newsock readable [list httpdRead $newsock]
+}
+
+# read data from a client request
+
+proc httpdRead { sock } {
+ upvar #0 httpd$sock data
+
+ if {[eof $sock]} {
+ set readCount -1
+ } elseif {![info exists data(state)]} {
+
+ # Read the protocol line and parse out the URL and query
+
+ set readCount [gets $sock line]
+ if {[regexp {(POST|GET|HEAD) ([^?]+)\??([^ ]*) HTTP/(1.[01])} $line \
+ -> data(proto) data(url) data(query) data(httpversion)]} {
+ set data(state) mime
+ httpd_log $sock Query $line
+ } else {
+ httpdError $sock 400
+ httpd_log $sock Error "bad first line:$line"
+ httpdSockDone $sock
+ }
+ return
+ } elseif {$data(state) == "mime"} {
+
+ # Read the HTTP headers
+
+ set readCount [gets $sock line]
+ if {[regexp {^([^:]+):(.*)$} $line -> key val]} {
+ lappend data(meta) $key [string trim $val]
+ }
+
+ } elseif {$data(state) == "query"} {
+
+ # Read the query data
+
+ if {![info exists data(length_orig)]} {
+ set data(length_orig) $data(length)
+ }
+ set line [read $sock $data(length)]
+ set readCount [string length $line]
+ incr data(length) -$readCount
+ }
+
+ # string compare $readCount 0 maps -1 to -1, 0 to 0, and > 0 to 1
+
+ set state [string compare $readCount 0],$data(state),$data(proto)
+ httpd_log $sock $state
+ switch -- $state {
+ -1,mime,HEAD -
+ -1,mime,GET -
+ -1,mime,POST {
+ # gets would block
+ return
+ }
+ 0,mime,HEAD -
+ 0,mime,GET -
+ 0,query,POST {
+ # Empty line at end of headers,
+ # or eof after query data
+ httpdRespond $sock
+ }
+ 0,mime,POST {
+ # Empty line between headers and query data
+ if {![info exists data(mime,content-length)]} {
+ httpd_log $sock Error "No Content-Length for POST"
+ httpdError $sock 400
+ httpdSockDone $sock
+ } else {
+ set data(state) query
+ set data(length) $data(mime,content-length)
+
+ # Special case to simulate servers that respond
+ # without reading the post data.
+
+ if {[string match *droppost* $data(url)]} {
+ fileevent $sock readable {}
+ httpdRespond $sock
+ }
+ }
+ }
+ 1,mime,HEAD -
+ 1,mime,POST -
+ 1,mime,GET {
+ # A line of HTTP headers
+ if {[regexp {([^:]+):[ ]*(.*)} $line dummy key value]} {
+ set data(mime,[string tolower $key]) $value
+ }
+ }
+ -1,query,POST {
+ httpd_log $sock Error "unexpected eof on <$data(url)> request"
+ httpdError $sock 400
+ httpdSockDone $sock
+ }
+ 1,query,POST {
+ append data(query) $line
+ if {$data(length) <= 0} {
+ set data(length) $data(length_orig)
+ httpdRespond $sock
+ }
+ }
+ default {
+ if {[eof $sock]} {
+ httpd_log $sock Error "unexpected eof on <$data(url)> request"
+ } else {
+ httpd_log $sock Error "unhandled state <$state> fetching <$data(url)>"
+ }
+ httpdError $sock 404
+ httpdSockDone $sock
+ }
+ }
+}
+proc httpdSockDone { sock } {
+ upvar #0 httpd$sock data
+ unset data
+ catch {close $sock}
+}
+
+# Respond to the query.
+
+proc httpdRespond { sock } {
+ global httpd bindata port
+ upvar #0 httpd$sock data
+
+ switch -glob -- $data(url) {
+ *binary* {
+ set html "$bindata[info hostname]:$port$data(url)"
+ set type application/octet-stream
+ }
+ *post* {
+ set html "Got [string length $data(query)] bytes"
+ set type text/plain
+ }
+ *headers* {
+ set html ""
+ set type text/plain
+ foreach {key value} $data(meta) {
+ append html [list $key $value] "\n"
+ }
+ set html [string trim $html]
+ }
+ default {
+ set type text/html
+
+ set html "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>$data(proto) $data(url)</h2>
+"
+ if {[info exists data(query)] && [string length $data(query)]} {
+ append html "<h2>Query</h2>\n<dl>\n"
+ foreach {key value} [split $data(query) &=] {
+ append html "<dt>$key<dd>$value\n"
+ if {$key == "timeout"} {
+ after $value ;# pause
+ }
+ }
+ append html </dl>\n
+ }
+ append html </body></html>
+ }
+ }
+
+ # Catch errors from premature client closes
+
+ catch {
+ if {$data(proto) == "HEAD"} {
+ puts $sock "HTTP/1.0 200 OK"
+ } else {
+ # Split the response to test for [Bug 26245326]
+ puts -nonewline $sock "HT"
+ flush $sock
+ puts $sock "TP/1.0 200 Data follows"
+ }
+ puts $sock "Date: [clock format [clock seconds] \
+ -format {%a, %d %b %Y %H:%M:%S %Z}]"
+ puts $sock "Content-Type: $type"
+ puts $sock "Content-Length: [string length $html]"
+ foreach {key val} $data(meta) {
+ if {[string match "X-*" $key]} {
+ puts $sock "$key: $val"
+ }
+ }
+ puts $sock ""
+ flush $sock
+ if {$data(proto) != "HEAD"} {
+ fconfigure $sock -translation binary
+ puts -nonewline $sock $html
+ }
+ }
+ httpd_log $sock Done ""
+ httpdSockDone $sock
+}
diff --git a/library/msgcat/tests/httpd11.tcl b/library/msgcat/tests/httpd11.tcl
new file mode 100644
index 0000000..9c543dc
--- /dev/null
+++ b/library/msgcat/tests/httpd11.tcl
@@ -0,0 +1,254 @@
+# httpd11.tcl -- -*- tcl -*-
+#
+# A simple httpd for testing HTTP/1.1 client features.
+# Not suitable for use on a internet connected port.
+#
+# Copyright (C) 2009 Pat Thoyts <patthoyts@users.sourceforge.net>
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require Tcl 8.6
+
+proc ::tcl::dict::get? {dict key} {
+ if {[dict exists $dict $key]} {
+ return [dict get $dict $key]
+ }
+ return
+}
+namespace ensemble configure dict \
+ -map [linsert [namespace ensemble configure dict -map] end get? ::tcl::dict::get?]
+
+proc make-chunk-generator {data {size 4096}} {
+ variable _chunk_gen_uid
+ if {![info exists _chunk_gen_uid]} {set _chunk_gen_uid 0}
+ set lambda {{data size} {
+ set pos 0
+ yield
+ while {1} {
+ set payload [string range $data $pos [expr {$pos + $size - 1}]]
+ incr pos $size
+ set chunk [format %x [string length $payload]]\r\n$payload\r\n
+ yield $chunk
+ if {![string length $payload]} {return}
+ }
+ }}
+ set name chunker[incr _chunk_gen_uid]
+ coroutine $name ::apply $lambda $data $size
+ return $name
+}
+
+proc get-chunks {data {compression gzip}} {
+ switch -exact -- $compression {
+ gzip { set data [zlib gzip $data] }
+ deflate { set data [zlib deflate $data] }
+ compress { set data [zlib compress $data] }
+ }
+
+ set data ""
+ set chunker [make-chunk-generator $data 512]
+ while {[string length [set chunk [$chunker]]]} {
+ append data $chunk
+ }
+ return $data
+}
+
+proc blow-chunks {data {ochan stdout} {compression gzip}} {
+ switch -exact -- $compression {
+ gzip { set data [zlib gzip $data] }
+ deflate { set data [zlib deflate $data] }
+ compress { set data [zlib compress $data] }
+ }
+
+ set chunker [make-chunk-generator $data 512]
+ while {[string length [set chunk [$chunker]]]} {
+ puts -nonewline $ochan $chunk
+ }
+ return
+}
+
+proc mime-type {filename} {
+ switch -exact -- [file extension $filename] {
+ .htm - .html { return {text text/html}}
+ .png { return {binary image/png} }
+ .jpg { return {binary image/jpeg} }
+ .gif { return {binary image/gif} }
+ .css { return {text text/css} }
+ .xml { return {text text/xml} }
+ .xhtml {return {text application/xml+html} }
+ .svg { return {text image/svg+xml} }
+ .txt - .tcl - .c - .h { return {text text/plain}}
+ }
+ return {binary text/plain}
+}
+
+proc Puts {chan s} {puts $chan $s; puts $s}
+
+proc Service {chan addr port} {
+ chan event $chan readable [info coroutine]
+ while {1} {
+ set meta {}
+ chan configure $chan -buffering line -encoding iso8859-1 -translation crlf
+ chan configure $chan -blocking 0
+ yield
+ while {[gets $chan line] < 0} {
+ if {[eof $chan]} {chan event $chan readable {}; close $chan; return}
+ yield
+ }
+ if {[eof $chan]} {chan event $chan readable {}; close $chan; return}
+ foreach {req url protocol} {GET {} HTTP/1.1} break
+ regexp {^(\S+)\s+(.*)\s(\S+)?$} $line -> req url protocol
+
+ puts $line
+ while {[gets $chan line] > 0} {
+ if {[regexp {^([^:]+):(.*)$} $line -> key val]} {
+ puts [list $key [string trim $val]]
+ lappend meta [string tolower $key] [string trim $val]
+ }
+ yield
+ }
+
+ set encoding identity
+ set transfer ""
+ set close 1
+ set type text/html
+ set code "404 Not Found"
+ set data "<html><head><title>Error 404</title></head>"
+ append data "<body><h1>Not Found</h1><p>Try again.</p></body></html>"
+
+ if {[scan $url {%[^?]?%s} path query] < 2} {
+ set query ""
+ }
+
+ switch -exact -- $req {
+ GET - HEAD {
+ }
+ POST {
+ # Read the query.
+ set qlen [dict get? $meta content-length]
+ if {[string is integer -strict $qlen]} {
+ chan configure $chan -buffering none -translation binary
+ while {[string length $query] < $qlen} {
+ append query [read $chan $qlen]
+ if {[string length $query] < $qlen} {yield}
+ }
+ # Check for excess query bytes [Bug 2715421]
+ if {[dict get? $meta x-check-query] eq "yes"} {
+ chan configure $chan -blocking 0
+ append query [read $chan]
+ }
+ }
+ }
+ default {
+ # invalid request error 5??
+ }
+ }
+ if {$query ne ""} {puts $query}
+
+ set path [string trimleft $path /]
+ set path [file join [pwd] $path]
+ if {[file exists $path] && [file isfile $path]} {
+ foreach {what type} [mime-type $path] break
+ set f [open $path r]
+ if {$what eq "binary"} {chan configure $f -translation binary}
+ set data [read $f]
+ close $f
+ set code "200 OK"
+ set close [expr {[dict get? $meta connection] eq "close"}]
+ }
+
+ if {$protocol eq "HTTP/1.1"} {
+ if {[string match "*deflate*" [dict get? $meta accept-encoding]]} {
+ set encoding deflate
+ } elseif {[string match "*gzip*" [dict get? $meta accept-encoding]]} {
+ set encoding gzip
+ } elseif {[string match "*compress*" [dict get? $meta accept-encoding]]} {
+ set encoding compress
+ }
+ set transfer chunked
+ } else {
+ set close 1
+ }
+
+ foreach pair [split $query &] {
+ if {[scan $pair {%[^=]=%s} key val] != 2} {set val ""}
+ switch -exact -- $key {
+ close {set close 1 ; set transfer 0}
+ transfer {set transfer $val}
+ content-type {set type $val}
+ }
+ }
+
+ chan configure $chan -buffering line -encoding iso8859-1 -translation crlf
+ Puts $chan "$protocol $code"
+ Puts $chan "content-type: $type"
+ Puts $chan [format "x-crc32: %08x" [zlib crc32 $data]]
+ if {$req eq "POST"} {
+ Puts $chan [format "x-query-length: %d" [string length $query]]
+ }
+ if {$close} {
+ Puts $chan "connection: close"
+ }
+ if {$encoding eq "identity"} {
+ Puts $chan "content-length: [string length $data]"
+ } else {
+ Puts $chan "content-encoding: $encoding"
+ }
+ if {$transfer eq "chunked"} {
+ Puts $chan "transfer-encoding: chunked"
+ }
+ puts $chan ""
+ flush $chan
+
+ chan configure $chan -buffering full -translation binary
+ if {$transfer eq "chunked"} {
+ blow-chunks $data $chan $encoding
+ } elseif {$encoding ne "identity"} {
+ puts -nonewline $chan [zlib $encoding $data]
+ } else {
+ puts -nonewline $chan $data
+ }
+
+ if {$close} {
+ chan event $chan readable {}
+ close $chan
+ puts "close $chan"
+ return
+ } else {
+ flush $chan
+ }
+ puts "pipeline $chan"
+ }
+}
+
+proc Accept {chan addr port} {
+ coroutine client$chan Service $chan $addr $port
+ return
+}
+
+proc Control {chan} {
+ if {[gets $chan line] != -1} {
+ if {[string trim $line] eq "quit"} {
+ set ::forever 1
+ }
+ }
+ if {[eof $chan]} {
+ chan event $chan readable {}
+ }
+}
+
+proc Main {{port 0}} {
+ set server [socket -server Accept -myaddr localhost $port]
+ puts [chan configure $server -sockname]
+ flush stdout
+ chan event stdin readable [list Control stdin]
+ vwait ::forever
+ close $server
+ return "done"
+}
+
+if {!$tcl_interactive} {
+ set r [catch [linsert $argv 0 Main] err]
+ if {$r} {puts stderr $errorInfo} elseif {[string length $err]} {puts $err}
+ exit $r
+}
diff --git a/library/msgcat/tests/httpold.test b/library/msgcat/tests/httpold.test
new file mode 100644
index 0000000..aeba311
--- /dev/null
+++ b/library/msgcat/tests/httpold.test
@@ -0,0 +1,293 @@
+# Commands covered: http_config, http_get, http_wait, http_reset
+#
+# This file contains a collection of tests for the http script library.
+# Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+if {[catch {package require http 1.0}]} {
+ if {[info exists httpold]} {
+ catch {puts "Cannot load http 1.0 package"}
+ ::tcltest::cleanupTests
+ return
+ } else {
+ catch {puts "Running http 1.0 tests in slave interp"}
+ set interp [interp create httpold]
+ $interp eval [list set httpold "running"]
+ $interp eval [list set argv $argv]
+ $interp eval [list source [info script]]
+ interp delete $interp
+ ::tcltest::cleanupTests
+ return
+ }
+}
+
+set bindata "This is binary data\x0d\x0amore\x0dmore\x0amore\x00null"
+catch {unset data}
+
+##
+## The httpd script implement a stub http server
+##
+source [file join [file dirname [info script]] httpd]
+
+set port 8010
+if [catch {httpd_init $port} listen] {
+ puts "Cannot start http server, http test skipped"
+ unset port
+ ::tcltest::cleanupTests
+ return
+}
+
+test httpold-1.1 {http_config} {
+ http_config
+} {-accept */* -proxyfilter httpProxyRequired -proxyhost {} -proxyport {} -useragent {Tcl http client package 1.0}}
+
+test httpold-1.2 {http_config} {
+ http_config -proxyfilter
+} httpProxyRequired
+
+test httpold-1.3 {http_config} {
+ catch {http_config -junk}
+} 1
+
+test httpold-1.4 {http_config} {
+ http_config -proxyhost nowhere.come -proxyport 8080 -proxyfilter myFilter -useragent "Tcl Test Suite"
+ set x [http_config]
+ http_config -proxyhost {} -proxyport {} -proxyfilter httpProxyRequired \
+ -useragent "Tcl http client package 1.0"
+ set x
+} {-accept */* -proxyfilter myFilter -proxyhost nowhere.come -proxyport 8080 -useragent {Tcl Test Suite}}
+
+test httpold-1.5 {http_config} {
+ catch {http_config -proxyhost {} -junk 8080}
+} 1
+
+test httpold-2.1 {http_reset} {
+ catch {http_reset http#1}
+} 0
+
+test httpold-3.1 {http_get} {
+ catch {http_get -bogus flag}
+} 1
+test httpold-3.2 {http_get} {
+ catch {http_get http:junk} err
+ set err
+} {Unsupported URL: http:junk}
+
+set url [info hostname]:$port
+test httpold-3.3 {http_get} {
+ set token [http_get $url]
+ http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET /</h2>
+</body></html>"
+
+set tail /a/b/c
+set url [info hostname]:$port/a/b/c
+set binurl [info hostname]:$port/binary
+
+test httpold-3.4 {http_get} {
+ set token [http_get $url]
+ http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+
+proc selfproxy {host} {
+ global port
+ return [list [info hostname] $port]
+}
+test httpold-3.5 {http_get} {
+ http_config -proxyfilter selfproxy
+ set token [http_get $url]
+ http_config -proxyfilter httpProxyRequired
+ http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET http://$url</h2>
+</body></html>"
+
+test httpold-3.6 {http_get} {
+ http_config -proxyfilter bogus
+ set token [http_get $url]
+ http_config -proxyfilter httpProxyRequired
+ http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+
+test httpold-3.7 {http_get} {
+ set token [http_get $url -headers {Pragma no-cache}]
+ http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+
+test httpold-3.8 {http_get} {
+ set token [http_get $url -query Name=Value&Foo=Bar]
+ http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>POST $tail</h2>
+<h2>Query</h2>
+<dl>
+<dt>Name<dd>Value
+<dt>Foo<dd>Bar
+</dl>
+</body></html>"
+
+test httpold-3.9 {http_get} {
+ set token [http_get $url -validate 1]
+ http_code $token
+} "HTTP/1.0 200 OK"
+
+
+test httpold-4.1 {httpEvent} {
+ set token [http_get $url]
+ upvar #0 $token data
+ array set meta $data(meta)
+ expr ($data(totalsize) == $meta(Content-Length))
+} 1
+
+test httpold-4.2 {httpEvent} {
+ set token [http_get $url]
+ upvar #0 $token data
+ array set meta $data(meta)
+ string compare $data(type) [string trim $meta(Content-Type)]
+} 0
+
+test httpold-4.3 {httpEvent} {
+ set token [http_get $url]
+ http_code $token
+} {HTTP/1.0 200 Data follows}
+
+test httpold-4.4 {httpEvent} {
+ set testfile [makeFile "" testfile]
+ set out [open $testfile w]
+ set token [http_get $url -channel $out]
+ close $out
+ set in [open $testfile]
+ set x [read $in]
+ close $in
+ removeFile $testfile
+ set x
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+
+test httpold-4.5 {httpEvent} {
+ set testfile [makeFile "" testfile]
+ set out [open $testfile w]
+ set token [http_get $url -channel $out]
+ close $out
+ upvar #0 $token data
+ removeFile $testfile
+ expr $data(currentsize) == $data(totalsize)
+} 1
+
+test httpold-4.6 {httpEvent} {
+ set testfile [makeFile "" testfile]
+ set out [open $testfile w]
+ set token [http_get $binurl -channel $out]
+ close $out
+ set in [open $testfile]
+ fconfigure $in -translation binary
+ set x [read $in]
+ close $in
+ removeFile $testfile
+ set x
+} "$bindata$binurl"
+
+proc myProgress {token total current} {
+ global progress httpLog
+ if {[info exists httpLog] && $httpLog} {
+ puts "progress $total $current"
+ }
+ set progress [list $total $current]
+}
+if 0 {
+ # This test hangs on Windows95 because the client never gets EOF
+ set httpLog 1
+ test httpold-4.6 {httpEvent} {
+ set token [http_get $url -blocksize 50 -progress myProgress]
+ set progress
+ } {111 111}
+}
+test httpold-4.7 {httpEvent} {
+ set token [http_get $url -progress myProgress]
+ set progress
+} {111 111}
+test httpold-4.8 {httpEvent} {
+ set token [http_get $url]
+ http_status $token
+} {ok}
+test httpold-4.9 {httpEvent} {
+ set token [http_get $url -progress myProgress]
+ http_code $token
+} {HTTP/1.0 200 Data follows}
+test httpold-4.10 {httpEvent} {
+ set token [http_get $url -progress myProgress]
+ http_size $token
+} {111}
+test httpold-4.11 {httpEvent} {
+ set token [http_get $url -timeout 1 -command {#}]
+ http_reset $token
+ http_status $token
+} {reset}
+test httpold-4.12 {httpEvent} {
+ update
+ set x {}
+ after 500 {lappend x ok}
+ set token [http_get $url -timeout 1 -command {lappend x fail}]
+ vwait x
+ list [http_status $token] $x
+} {timeout ok}
+
+test httpold-5.1 {http_formatQuery} {
+ http_formatQuery name1 value1 name2 "value two"
+} {name1=value1&name2=value+two}
+
+test httpold-5.2 {http_formatQuery} {
+ http_formatQuery name1 ~bwelch name2 \xa1\xa2\xa2
+} {name1=%7ebwelch&name2=%a1%a2%a2}
+
+test httpold-5.3 {http_formatQuery} {
+ http_formatQuery lines "line1\nline2\nline3"
+} {lines=line1%0d%0aline2%0d%0aline3}
+
+test httpold-6.1 {httpProxyRequired} {
+ update
+ http_config -proxyhost [info hostname] -proxyport $port
+ set token [http_get $url]
+ http_wait $token
+ http_config -proxyhost {} -proxyport {}
+ upvar #0 $token data
+ set data(body)
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET http://$url</h2>
+</body></html>"
+
+# cleanup
+catch {unset url}
+catch {unset port}
+catch {unset data}
+close $listen
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/if-old.test b/library/msgcat/tests/if-old.test
new file mode 100644
index 0000000..fbcf56c
--- /dev/null
+++ b/library/msgcat/tests/if-old.test
@@ -0,0 +1,162 @@
+# Commands covered: if
+#
+# This file contains the original set of tests for Tcl's if command.
+# Since the if command is now compiled, a new set of tests covering
+# the new implementation is in the file "if.test". Sourcing this file
+# into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test if-old-1.1 {taking proper branch} {
+ set a {}
+ if 0 {set a 1} else {set a 2}
+ set a
+} 2
+test if-old-1.2 {taking proper branch} {
+ set a {}
+ if 1 {set a 1} else {set a 2}
+ set a
+} 1
+test if-old-1.3 {taking proper branch} {
+ set a {}
+ if 1<2 {set a 1}
+ set a
+} 1
+test if-old-1.4 {taking proper branch} {
+ set a {}
+ if 1>2 {set a 1}
+ set a
+} {}
+test if-old-1.5 {taking proper branch} {
+ set a {}
+ if 0 {set a 1} else {}
+ set a
+} {}
+test if-old-1.6 {taking proper branch} {
+ set a {}
+ if 0 {set a 1} elseif 1 {set a 2} elseif 1 {set a 3} else {set a 4}
+ set a
+} {2}
+test if-old-1.7 {taking proper branch} {
+ set a {}
+ if 0 {set a 1} elseif 0 {set a 2} elseif 1 {set a 3} else {set a 4}
+ set a
+} {3}
+test if-old-1.8 {taking proper branch} {
+ set a {}
+ if 0 {set a 1} elseif 0 {set a 2} elseif 0 {set a 3} else {set a 4}
+ set a
+} {4}
+test if-old-1.9 {taking proper branch, multiline test expr} {
+ set a {}
+ if {($tcl_platform(platform) != "foobar1") && \
+ ($tcl_platform(platform) != "foobar2")} {set a 3} else {set a 4}
+ set a
+} {3}
+
+
+test if-old-2.1 {optional then-else args} {
+ set a 44
+ if 0 then {set a 1} elseif 0 then {set a 3} else {set a 2}
+ set a
+} 2
+test if-old-2.2 {optional then-else args} {
+ set a 44
+ if 1 then {set a 1} else {set a 2}
+ set a
+} 1
+test if-old-2.3 {optional then-else args} {
+ set a 44
+ if 0 {set a 1} else {set a 2}
+ set a
+} 2
+test if-old-2.4 {optional then-else args} {
+ set a 44
+ if 1 {set a 1} else {set a 2}
+ set a
+} 1
+test if-old-2.5 {optional then-else args} {
+ set a 44
+ if 0 then {set a 1} {set a 2}
+ set a
+} 2
+test if-old-2.6 {optional then-else args} {
+ set a 44
+ if 1 then {set a 1} {set a 2}
+ set a
+} 1
+test if-old-2.7 {optional then-else args} {
+ set a 44
+ if 0 then {set a 1} else {set a 2}
+ set a
+} 2
+test if-old-2.8 {optional then-else args} {
+ set a 44
+ if 0 then {set a 1} elseif 0 {set a 2} elseif 0 {set a 3} {set a 4}
+ set a
+} 4
+
+test if-old-3.1 {return value} {
+ if 1 then {set a 22; concat abc}
+} abc
+test if-old-3.2 {return value} {
+ if 0 then {set a 22; concat abc} elseif 1 {concat def} {concat ghi}
+} def
+test if-old-3.3 {return value} {
+ if 0 then {set a 22; concat abc} else {concat def}
+} def
+test if-old-3.4 {return value} {
+ if 0 then {set a 22; concat abc}
+} {}
+test if-old-3.5 {return value} {
+ if 0 then {set a 22; concat abc} elseif 0 {concat def}
+} {}
+
+test if-old-4.1 {error conditions} {
+ list [catch {if} msg] $msg
+} {1 {wrong # args: no expression after "if" argument}}
+test if-old-4.2 {error conditions} {
+ list [catch {if {[error "error in condition"]} foo} msg] $msg
+} {1 {error in condition}}
+test if-old-4.3 {error conditions} {
+ list [catch {if 2} msg] $msg
+} {1 {wrong # args: no script following "2" argument}}
+test if-old-4.4 {error conditions} {
+ list [catch {if 2 then} msg] $msg
+} {1 {wrong # args: no script following "then" argument}}
+test if-old-4.5 {error conditions} {
+ list [catch {if 2 the} msg] $msg
+} {1 {invalid command name "the"}}
+test if-old-4.6 {error conditions} {
+ list [catch {if 2 then {[error "error in then clause"]}} msg] $msg
+} {1 {error in then clause}}
+test if-old-4.7 {error conditions} {
+ list [catch {if 0 then foo elseif} msg] $msg
+} {1 {wrong # args: no expression after "elseif" argument}}
+test if-old-4.8 {error conditions} {
+ list [catch {if 0 then foo elsei} msg] $msg
+} {1 {invalid command name "elsei"}}
+test if-old-4.9 {error conditions} {
+ list [catch {if 0 then foo elseif 0 bar else} msg] $msg
+} {1 {wrong # args: no script following "else" argument}}
+test if-old-4.10 {error conditions} {
+ list [catch {if 0 then foo elseif 0 bar els} msg] $msg
+} {1 {invalid command name "els"}}
+test if-old-4.11 {error conditions} {
+ list [catch {if 0 then foo elseif 0 bar else {[error "error in else clause"]}} msg] $msg
+} {1 {error in else clause}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/if.test b/library/msgcat/tests/if.test
new file mode 100644
index 0000000..040364a
--- /dev/null
+++ b/library/msgcat/tests/if.test
@@ -0,0 +1,1282 @@
+# Commands covered: if
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Basic "if" operation.
+
+catch {unset a}
+test if-1.1 {TclCompileIfCmd: missing if/elseif test} -body {
+ if
+} -returnCodes error -result {wrong # args: no expression after "if" argument}
+test if-1.2 {TclCompileIfCmd: error in if/elseif test} -body {
+ if {[error "error in condition"]} foo
+} -returnCodes error -result {error in condition}
+test if-1.3 {TclCompileIfCmd: error in if/elseif test} -body {
+ list [catch {if {1+}} msg] $msg $::errorInfo
+} -match glob -cleanup {
+ unset msg
+} -result {1 * {*"if {1+}"}}
+test if-1.4 {TclCompileIfCmd: if/elseif test in braces} -body {
+ set a {}
+ if {1<2} {set a 1}
+ return $a
+} -cleanup {
+ unset a
+} -result {1}
+test if-1.5 {TclCompileIfCmd: if/elseif test not in braces} -body {
+ set a {}
+ if 1<2 {set a 1}
+ return $a
+} -cleanup {
+ unset a
+} -result {1}
+test if-1.6 {TclCompileIfCmd: multiline test expr} -setup {
+ set a {}
+} -body {
+ if {($tcl_platform(platform) != "foobar1") && \
+ ($tcl_platform(platform) != "foobar2")} {set a 3} else {set a 4}
+ return $a
+} -cleanup {
+ unset a
+} -result 3
+test if-1.7 {TclCompileIfCmd: "then" after if/elseif test} -body {
+ set a {}
+ if 4>3 then {set a 1}
+ return $a
+} -cleanup {
+ unset a
+} -result {1}
+test if-1.8 {TclCompileIfCmd: keyword other than "then" after if/elseif test} -setup {
+ set a {}
+} -body {
+ if 1<2 therefore {set a 1}
+} -cleanup {
+ unset a
+} -returnCodes error -result {invalid command name "therefore"}
+test if-1.9 {TclCompileIfCmd: missing "then" body} -setup {
+ set a {}
+} -body {
+ if 1<2 then
+} -cleanup {
+ unset a
+} -returnCodes error -result {wrong # args: no script following "then" argument}
+test if-1.10 {TclCompileIfCmd: error in "then" body} -body {
+ set a {}
+ list [catch {if {$a!="xxx"} then {set}} msg] $msg $::errorInfo
+} -match glob -cleanup {
+ unset a msg
+} -result {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}}
+test if-1.11 {TclCompileIfCmd: error in "then" body} -body {
+ if 2 then {[error "error in then clause"]}
+} -returnCodes error -result {error in then clause}
+test if-1.12 {TclCompileIfCmd: "then" body in quotes} -body {
+ set a {}
+ if 27>17 "append a x"
+ return $a
+} -cleanup {
+ unset a
+} -result {x}
+test if-1.13 {TclCompileIfCmd: computed "then" body} -setup {
+ catch {unset x1}
+ catch {unset x2}
+} -body {
+ set x1 {append a x1}
+ set x2 {; append a x2}
+ set a {}
+ if 1 $x1$x2
+ return $a
+} -cleanup {
+ unset a x1 x2
+} -result {x1x2}
+test if-1.14 {TclCompileIfCmd: taking proper branch} -body {
+ set a {}
+ if 1<2 {set a 1}
+ return $a
+} -cleanup {
+ unset a
+} -result 1
+test if-1.15 {TclCompileIfCmd: taking proper branch} -body {
+ set a {}
+ if 1>2 {set a 1}
+ return $a
+} -cleanup {
+ unset a
+} -result {}
+test if-1.16 {TclCompileIfCmd: test jumpFalse instruction replacement after long "then" body} -setup {
+ catch {unset i}
+ set a {}
+} -body {
+ if 1<2 {
+ set a 1
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 2
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 3
+ }
+ return $a
+} -cleanup {
+ unset a
+ unset -nocomplain i
+} -result 3
+test if-1.17 {TclCompileIfCmd: if/elseif test in quotes} -setup {
+ set a {}
+} -body {
+ if {"0 < 3"} {set a 1}
+} -returnCodes error -cleanup {
+ unset a
+} -result {expected boolean value but got "0 < 3"}
+
+test if-2.1 {TclCompileIfCmd: "elseif" after if/elseif test} -setup {
+ set a {}
+} -body {
+ if 3>4 {set a 1} elseif 1 {set a 2}
+ return $a
+} -cleanup {
+ unset a
+} -result {2}
+# Since "else" is optional, the "elwood" below is treated as a command.
+# But then there shouldn't be any additional argument words for the "if".
+test if-2.2 {TclCompileIfCmd: keyword other than "elseif"} -setup {
+ set a {}
+} -body {
+ if 1<2 {set a 1} elwood {set a 2}
+} -returnCodes error -cleanup {
+ unset a
+} -result {wrong # args: extra words after "else" clause in "if" command}
+test if-2.3 {TclCompileIfCmd: missing expression after "elseif"} -setup {
+ set a {}
+} -body {
+ if 1<2 {set a 1} elseif
+} -returnCodes error -cleanup {
+ unset a
+} -result {wrong # args: no expression after "elseif" argument}
+test if-2.4 {TclCompileIfCmd: error in expression after "elseif"} -setup {
+ set a {}
+} -body {
+ list [catch {if 3>4 {set a 1} elseif {1>}} msg] $msg $::errorInfo
+} -match glob -cleanup {
+ unset a msg
+} -result {1 * {*"if 3>4 {set a 1} elseif {1>}"}}
+test if-2.5 {TclCompileIfCmd: test jumpFalse instruction replacement after long "elseif" body} -setup {
+ catch {unset i}
+ set a {}
+} -body {
+ if 1>2 {
+ set a 1
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 2
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 3
+ } elseif 1<2 then { #; this if arm should be taken
+ set a 4
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 5
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 6
+ }
+ return $a
+} -cleanup {
+ unset a
+ unset -nocomplain i
+} -result 6
+
+test if-3.1 {TclCompileIfCmd: "else" clause} -body {
+ set a {}
+ if 3>4 {set a 1} elseif {$a == "foo"} {set a 2} else {set a 3}
+ return $a
+} -cleanup {
+ unset a
+} -result 3
+# Since "else" is optional, the "elsex" below is treated as a command.
+# But then there shouldn't be any additional argument words for the "if".
+test if-3.2 {TclCompileIfCmd: keyword other than "else"} -setup {
+ set a {}
+} -body {
+ if 1<2 then {set a 1} elsex {set a 2}
+} -returnCodes error -cleanup {
+ unset a
+} -result {wrong # args: extra words after "else" clause in "if" command}
+test if-3.3 {TclCompileIfCmd: missing body after "else"} -setup {
+ set a {}
+} -body {
+ if 2<1 {set a 1} else
+} -returnCodes error -cleanup {
+ unset a
+} -result {wrong # args: no script following "else" argument}
+test if-3.4 {TclCompileIfCmd: error compiling body after "else"} -setup {
+ set a {}
+} -body {
+ catch {if 2<1 {set a 1} else {set}}
+ set ::errorInfo
+} -match glob -cleanup {
+ unset a
+} -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test if-3.5 {TclCompileIfCmd: extra arguments after "else" argument} -setup {
+ set a {}
+} -body {
+ if 2<1 {set a 1} else {set a 2} or something
+} -returnCodes error -cleanup {
+ unset a
+} -result {wrong # args: extra words after "else" clause in "if" command}
+# The following test also checks whether contained loops and other
+# commands are properly relocated because a short jump must be replaced
+# by a "long distance" one.
+test if-3.6 {TclCompileIfCmd: test jumpFalse instruction replacement after long "else" clause} -setup {
+ catch {unset i}
+ set a {}
+} -body {
+ if 1>2 {
+ set a 1
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 2
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 3
+ } elseif 1==2 then { #; this if arm should be taken
+ set a 4
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 5
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 6
+ } else {
+ set a 7
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 8
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 9
+ }
+ return $a
+} -cleanup {
+ unset a
+ unset -nocomplain i
+} -result 9
+
+test if-4.1 {TclCompileIfCmd: "if" command result} -setup {
+ set a {}
+} -body {
+ set a [if 3<4 {set i 27}]
+ return $a
+} -cleanup {
+ unset a
+ unset -nocomplain i
+} -result 27
+test if-4.2 {TclCompileIfCmd: "if" command result} -setup {
+ set a {}
+} -body {
+ set a [if 3>4 {set i 27}]
+ return $a
+} -cleanup {
+ unset a
+ unset -nocomplain i
+} -result {}
+test if-4.3 {TclCompileIfCmd: "if" command result} -setup {
+ set a {}
+} -body {
+ set a [if 0 {set i 1} elseif 1 {set i 2}]
+ return $a
+} -cleanup {
+ unset a
+ unset -nocomplain i
+} -result 2
+test if-4.4 {TclCompileIfCmd: "if" command result} -setup {
+ set a {}
+} -body {
+ set a [if 0 {set i 1} elseif 0 {set i 2} elseif 2>5 {set i 3} else {set i 4}]
+ return $a
+} -cleanup {
+ unset a i
+} -result 4
+test if-4.5 {TclCompileIfCmd: return value} -body {
+ if 0 then {set a 22; concat abc} elseif 1 {concat def} {concat ghi}
+} -cleanup {
+ unset -nocomplain a
+} -result def
+
+# Check "if" and computed command names.
+
+test if-5.1 {if cmd with computed command names: missing if/elseif test} -body {
+ set z if
+ $z
+} -returnCodes error -cleanup {
+ unset z
+} -result {wrong # args: no expression after "if" argument}
+test if-5.2 {if cmd with computed command names: error in if/elseif test} -body {
+ set z if
+ $z {[error "error in condition"]} foo
+} -returnCodes error -cleanup {
+ unset z
+} -result {error in condition}
+test if-5.3 {if cmd with computed command names: error in if/elseif test} -body {
+ set z if
+ list [catch {$z {1+}}] $::errorInfo
+} -match glob -cleanup {
+ unset z
+} -result {1 {*"$z {1+}"}}
+test if-5.4 {if cmd with computed command names: if/elseif test in braces} -setup {
+ set a {}
+} -body {
+ set z if
+ $z {1<2} {set a 1}
+ return $a
+} -cleanup {
+ unset a z
+} -result {1}
+test if-5.5 {if cmd with computed command names: if/elseif test not in braces} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 1<2 {set a 1}
+ return $a
+} -cleanup {
+ unset a z
+} -result {1}
+test if-5.6 {if cmd with computed command names: multiline test expr} -body {
+ set z if
+ $z {($tcl_platform(platform) != "foobar1") && \
+ ($tcl_platform(platform) != "foobar2")} {set a 3} else {set a 4}
+ return $a
+} -cleanup {
+ unset a z
+} -result 3
+test if-5.7 {if cmd with computed command names: "then" after if/elseif test} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 4>3 then {set a 1}
+ return $a
+} -cleanup {
+ unset a z
+} -result {1}
+test if-5.8 {if cmd with computed command names: keyword other than "then" after if/elseif test} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 1<2 therefore {set a 1}
+} -returnCodes error -cleanup {
+ unset a z
+} -result {invalid command name "therefore"}
+test if-5.9 {if cmd with computed command names: missing "then" body} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 1<2 then
+} -returnCodes error -cleanup {
+ unset a z
+} -result {wrong # args: no script following "then" argument}
+test if-5.10 {if cmd with computed command names: error in "then" body} -body {
+ set z if
+ set a {}
+ list [catch {$z {$a!="xxx"} then {set}} msg] $msg $::errorInfo
+} -match glob -cleanup {
+ unset a z msg
+} -result {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"
+ invoked from within
+"$z {$a!="xxx"} then {set}"}}
+test if-5.11 {if cmd with computed command names: error in "then" body} -body {
+ set z if
+ $z 2 then {[error "error in then clause"]}
+} -returnCodes error -cleanup {
+ unset z
+} -result {error in then clause}
+test if-5.12 {if cmd with computed command names: "then" body in quotes} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 27>17 "append a x"
+ return $a
+} -cleanup {
+ unset a z
+} -result {x}
+test if-5.13 {if cmd with computed command names: computed "then" body} -setup {
+ catch {unset x1}
+ catch {unset x2}
+} -body {
+ set z if
+ set x1 {append a x1}
+ set x2 {; append a x2}
+ set a {}
+ $z 1 $x1$x2
+ return $a
+} -cleanup {
+ unset a z x1 x2
+} -result {x1x2}
+test if-5.14 {if cmd with computed command names: taking proper branch} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 1<2 {set a 1}
+ return $a
+} -cleanup {
+ unset a z
+} -result 1
+test if-5.15 {if cmd with computed command names: taking proper branch} -body {
+ set a {}
+ set z if
+ $z 1>2 {set a 1}
+ return $a
+} -cleanup {
+ unset a z
+} -result {}
+test if-5.16 {if cmd with computed command names: test jumpFalse instruction replacement after long "then" body} -setup {
+ catch {unset i}
+ set a {}
+} -body {
+ set z if
+ $z 1<2 {
+ set a 1
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 2
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 3
+ }
+ return $a
+} -cleanup {
+ unset a z
+ unset -nocomplain i
+} -result 3
+test if-5.17 {if cmd with computed command names: if/elseif test in quotes} -setup {
+ set a {}
+} -body {
+ set z if
+ $z {"0 < 3"} {set a 1}
+} -returnCodes error -cleanup {
+ unset a z
+} -result {expected boolean value but got "0 < 3"}
+
+test if-6.1 {if cmd with computed command names: "elseif" after if/elseif test} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 3>4 {set a 1} elseif 1 {set a 2}
+ return $a
+} -cleanup {
+ unset a z
+} -result {2}
+# Since "else" is optional, the "elwood" below is treated as a command.
+# But then there shouldn't be any additional argument words for the "if".
+test if-6.2 {if cmd with computed command names: keyword other than "elseif"} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 1<2 {set a 1} elwood {set a 2}
+} -returnCodes error -cleanup {
+ unset a z
+} -result {wrong # args: extra words after "else" clause in "if" command}
+test if-6.3 {if cmd with computed command names: missing expression after "elseif"} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 1<2 {set a 1} elseif
+} -returnCodes error -cleanup {
+ unset a z
+} -result {wrong # args: no expression after "elseif" argument}
+test if-6.4 {if cmd with computed command names: error in expression after "elseif"} -setup {
+ set a {}
+} -body {
+ set z if
+ list [catch {$z 3>4 {set a 1} elseif {1>}}] $::errorInfo
+} -match glob -cleanup {
+ unset a z
+} -result {1 {*"$z 3>4 {set a 1} elseif {1>}"}}
+test if-6.5 {if cmd with computed command names: test jumpFalse instruction replacement after long "elseif" body} -setup {
+ catch {unset i}
+ set a {}
+} -body {
+ set z if
+ $z 1>2 {
+ set a 1
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 2
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 3
+ } elseif 1<2 then { #; this if arm should be taken
+ set a 4
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 5
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 6
+ }
+ return $a
+} -cleanup {
+ unset a z
+ unset -nocomplain i
+} -result 6
+
+test if-7.1 {if cmd with computed command names: "else" clause} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 3>4 {set a 1} elseif {$a == "foo"} {set a 2} else {set a 3}
+ return $a
+} -cleanup {
+ unset a z
+} -result 3
+# Since "else" is optional, the "elsex" below is treated as a command.
+# But then there shouldn't be any additional argument words for the "if".
+test if-7.2 {if cmd with computed command names: keyword other than "else"} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 1<2 then {set a 1} elsex {set a 2}
+} -returnCodes error -cleanup {
+ unset a z
+} -result {wrong # args: extra words after "else" clause in "if" command}
+test if-7.3 {if cmd with computed command names: missing body after "else"} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 2<1 {set a 1} else
+} -returnCodes error -cleanup {
+ unset a z
+} -result {wrong # args: no script following "else" argument}
+test if-7.4 {if cmd with computed command names: error compiling body after "else"} -setup {
+ set a {}
+} -body {
+ set z if
+ catch {$z 2<1 {set a 1} else {set}}
+ return $::errorInfo
+} -match glob -cleanup {
+ unset a z
+} -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"
+ invoked from within
+"$z 2<1 {set a 1} else {set}"}
+test if-7.5 {if cmd with computed command names: extra arguments after "else" argument} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 2<1 {set a 1} else {set a 2} or something
+} -returnCodes error -cleanup {
+ unset a z
+} -result {wrong # args: extra words after "else" clause in "if" command}
+# The following test also checks whether contained loops and other
+# commands are properly relocated because a short jump must be replaced
+# by a "long distance" one.
+test if-7.6 {if cmd with computed command names: test jumpFalse instruction replacement after long "else" clause} -setup {
+ catch {unset i}
+ set a {}
+} -body {
+ set z if
+ $z 1>2 {
+ set a 1
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 2
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 3
+ } elseif 1==2 then { #; this if arm should be taken
+ set a 4
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 5
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 6
+ } else {
+ set a 7
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 8
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 9
+ }
+ return $a
+} -cleanup {
+ unset a z
+ unset -nocomplain i
+} -result 9
+
+test if-8.1 {if cmd with computed command names: "if" command result} -setup {
+ set a {}
+} -body {
+ set z if
+ set a [$z 3<4 {set i 27}]
+ return $a
+} -cleanup {
+ unset a z
+ unset -nocomplain i
+} -result 27
+test if-8.2 {if cmd with computed command names: "if" command result} -setup {
+ set a {}
+} -body {
+ set z if
+ set a [$z 3>4 {set i 27}]
+ return $a
+} -cleanup {
+ unset a z
+ unset -nocomplain i
+} -result {}
+test if-8.3 {if cmd with computed command names: "if" command result} -setup {
+ set a {}
+} -body {
+ set z if
+ set a [$z 0 {set i 1} elseif 1 {set i 2}]
+ return $a
+} -cleanup {
+ unset a z
+ unset -nocomplain i
+} -result 2
+test if-8.4 {if cmd with computed command names: "if" command result} -setup {
+ set a {}
+} -body {
+ set z if
+ set a [$z 0 {set i 1} elseif 0 {set i 2} elseif 2>5 {set i 3} else {set i 4}]
+ return $a
+} -cleanup {
+ unset a z
+ unset -nocomplain i
+} -result 4
+test if-8.5 {if cmd with computed command names: return value} -body {
+ set z if
+ $z 0 then {set a 22; concat abc} elseif 1 {concat def} {concat ghi}
+} -cleanup {
+ unset z
+ unset -nocomplain a
+} -result def
+
+test if-9.1 {if cmd with namespace qualifiers} -body {
+ ::if {1} {set x 4}
+} -cleanup {
+ unset x
+} -result 4
+
+# Test for incorrect "double evaluation semantics"
+
+test if-10.1 {delayed substitution of then body} -body {
+ set j 0
+ set if if
+ # this is not compiled
+ $if {[incr j] == 1} "
+ set result $j
+ "
+ # this will be compiled
+ proc p {} {
+ set j 0
+ if {[incr j]} "
+ set result $j
+ "
+ set result
+ }
+ append result [p]
+} -cleanup {
+ unset j if result
+ rename p {}
+} -result {00}
+test if-10.2 {delayed substitution of elseif expression} -body {
+ set j 0
+ set if if
+ # this is not compiled
+ $if {[incr j] == 0} {
+ set result badthen
+ } elseif "$j == 1" {
+ set result badelseif
+ } else {
+ set result 0
+ }
+ # this will be compiled
+ proc p {} {
+ set j 0
+ if {[incr j] == 0} {
+ set result badthen
+ } elseif "$j == 1" {
+ set result badelseif
+ } else {
+ set result 0
+ }
+ set result
+ }
+ append result [p]
+} -cleanup {
+ unset j if result
+ rename p {}
+} -result {00}
+test if-10.3 {delayed substitution of elseif body} -body {
+ set j 0
+ set if if
+ # this is not compiled
+ $if {[incr j] == 0} {
+ set result badthen
+ } elseif {1} "
+ set result $j
+ "
+ # this will be compiled
+ proc p {} {
+ set j 0
+ if {[incr j] == 0} {
+ set result badthen
+ } elseif {1} "
+ set result $j
+ "
+ }
+ append result [p]
+} -cleanup {
+ unset j if result
+ rename p {}
+} -result {00}
+test if-10.4 {delayed substitution of else body} -body {
+ set j 0
+ if {[incr j] == 0} {
+ set result badthen
+ } else "
+ set result $j
+ "
+ return $result
+} -cleanup {
+ unset j result
+} -result {0}
+test if-10.5 {substituted control words} -body {
+ set then then; proc then {} {return badthen}
+ set else else; proc else {} {return badelse}
+ set elseif elseif; proc elseif {} {return badelseif}
+ list [catch {if 1 $then {if 0 {} $elseif 1 {if 0 {} $else {list ok}}}} a] $a
+} -cleanup {
+ unset then else elseif a
+} -result {0 ok}
+test if-10.6 {double invocation of variable traces} -body {
+ set iftracecounter 0
+ proc iftraceproc {args} {
+ upvar #0 iftracecounter counter
+ set argc [llength $args]
+ set extraargs [lrange $args 0 [expr {$argc - 4}]]
+ set name [lindex $args [expr {$argc - 3}]]
+ upvar 1 $name var
+ if {[incr counter] % 2 == 1} {
+ set var "$counter oops [concat $extraargs]"
+ } else {
+ set var "$counter + [concat $extraargs]"
+ }
+ }
+ trace variable iftracevar r [list iftraceproc 10]
+ list [catch {if "$iftracevar + 20" {}} a] $a \
+ [catch {if "$iftracevar + 20" {}} b] $b
+} -cleanup {
+ unset iftracevar iftracecounter a b
+} -match glob -result {1 {*} 0 {}}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/incr-old.test b/library/msgcat/tests/incr-old.test
new file mode 100644
index 0000000..ed457cf
--- /dev/null
+++ b/library/msgcat/tests/incr-old.test
@@ -0,0 +1,92 @@
+# Commands covered: incr
+#
+# This file contains the original set of tests for Tcl's incr command.
+# Since the incr command is now compiled, a new set of tests covering
+# the new implementation is in the file "incr.test". Sourcing this file
+# into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+catch {unset x}
+
+test incr-old-1.1 {basic incr operation} {
+ set x 23
+ list [incr x] $x
+} {24 24}
+test incr-old-1.2 {basic incr operation} {
+ set x 106
+ list [incr x -5] $x
+} {101 101}
+test incr-old-1.3 {basic incr operation} {
+ set x " -106"
+ list [incr x 1] $x
+} {-105 -105}
+test incr-old-1.4 {basic incr operation} {
+ set x " +106"
+ list [incr x 1] $x
+} {107 107}
+
+test incr-old-2.1 {incr errors} {
+ list [catch incr msg] $msg
+} {1 {wrong # args: should be "incr varName ?increment?"}}
+test incr-old-2.2 {incr errors} {
+ list [catch {incr a b c} msg] $msg
+} {1 {wrong # args: should be "incr varName ?increment?"}}
+test incr-old-2.3 {incr errors} {
+ catch {unset x}
+ incr x
+} 1
+test incr-old-2.4 {incr errors} {
+ set x abc
+ list [catch {incr x} msg] $msg $::errorInfo
+} {1 {expected integer but got "abc"} {expected integer but got "abc"
+ while executing
+"incr x"}}
+test incr-old-2.5 {incr errors} {
+ set x 123
+ list [catch {incr x 1a} msg] $msg $::errorInfo
+} {1 {expected integer but got "1a"} {expected integer but got "1a"
+ (reading increment)
+ invoked from within
+"incr x 1a"}}
+test incr-old-2.6 {incr errors} -body {
+ proc readonly args {error "variable is read-only"}
+ set x 123
+ trace var x w readonly
+ list [catch {incr x 1} msg] $msg $::errorInfo
+} -match glob -result {1 {can't set "x": variable is read-only} {*variable is read-only
+ while executing
+*
+"incr x 1"}}
+catch {unset x}
+test incr-old-2.7 {incr errors} {
+ set x -
+ list [catch {incr x 1} msg] $msg
+} {1 {expected integer but got "-"}}
+test incr-old-2.8 {incr errors} {
+ set x { - }
+ list [catch {incr x 1} msg] $msg
+} {1 {expected integer but got " - "}}
+test incr-old-2.9 {incr errors} {
+ set x +
+ list [catch {incr x 1} msg] $msg
+} {1 {expected integer but got "+"}}
+test incr-old-2.10 {incr errors} {
+ set x {20 x}
+ list [catch {incr x 1} msg] $msg
+} {1 {expected integer but got "20 x"}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/incr.test b/library/msgcat/tests/incr.test
new file mode 100644
index 0000000..9243be0
--- /dev/null
+++ b/library/msgcat/tests/incr.test
@@ -0,0 +1,522 @@
+# Commands covered: incr
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+unset -nocomplain x i
+proc readonly varName {
+ upvar 1 $varName var
+ trace add variable var write \
+ {apply {{args} {error "variable is read-only"}}}
+}
+
+# Basic "incr" operation.
+
+test incr-1.1 {TclCompileIncrCmd: missing variable name} -returnCodes error -body {
+ incr
+} -result {wrong # args: should be "incr varName ?increment?"}
+test incr-1.2 {TclCompileIncrCmd: simple variable name} {
+ set i 10
+ list [incr i] $i
+} {11 11}
+test incr-1.3 {TclCompileIncrCmd: error compiling variable name} -body {
+ set i 10
+ incr "i"xxx
+} -returnCodes error -result {extra characters after close-quote}
+test incr-1.4 {TclCompileIncrCmd: simple variable name in quotes} {
+ set i 17
+ list [incr "i"] $i
+} {18 18}
+test incr-1.5 {TclCompileIncrCmd: simple variable name in braces} -setup {
+ unset -nocomplain {a simple var}
+} -body {
+ set {a simple var} 27
+ list [incr {a simple var}] ${a simple var}
+} -result {28 28}
+test incr-1.6 {TclCompileIncrCmd: simple array variable name} -setup {
+ unset -nocomplain a
+} -body {
+ set a(foo) 37
+ list [incr a(foo)] $a(foo)
+} -result {38 38}
+test incr-1.7 {TclCompileIncrCmd: non-simple (computed) variable name} {
+ set x "i"
+ set i 77
+ list [incr $x 2] $i
+} {79 79}
+test incr-1.8 {TclCompileIncrCmd: non-simple (computed) variable name} {
+ set x "i"
+ set i 77
+ list [incr [set x] +2] $i
+} {79 79}
+test incr-1.9 {TclCompileIncrCmd: increment given} {
+ set i 10
+ list [incr i +07] $i
+} {17 17}
+test incr-1.10 {TclCompileIncrCmd: no increment given} {
+ set i 10
+ list [incr i] $i
+} {11 11}
+test incr-1.11 {TclCompileIncrCmd: simple global name} {
+ proc p {} {
+ global i
+ set i 54
+ incr i
+ }
+ p
+} {55}
+test incr-1.12 {TclCompileIncrCmd: simple local name} {
+ proc p {} {
+ set foo 100
+ incr foo
+ }
+ p
+} {101}
+test incr-1.13 {TclCompileIncrCmd: simple but new (unknown) local name} {
+ proc p {} {
+ incr bar
+ }
+ p
+} 1
+test incr-1.14 {TclCompileIncrCmd: simple local name, >255 locals} {
+ proc 260locals {} {
+ # create 260 locals
+ set a0 0; set a1 0; set a2 0; set a3 0; set a4 0
+ set a5 0; set a6 0; set a7 0; set a8 0; set a9 0
+ set b0 0; set b1 0; set b2 0; set b3 0; set b4 0
+ set b5 0; set b6 0; set b7 0; set b8 0; set b9 0
+ set c0 0; set c1 0; set c2 0; set c3 0; set c4 0
+ set c5 0; set c6 0; set c7 0; set c8 0; set c9 0
+ set d0 0; set d1 0; set d2 0; set d3 0; set d4 0
+ set d5 0; set d6 0; set d7 0; set d8 0; set d9 0
+ set e0 0; set e1 0; set e2 0; set e3 0; set e4 0
+ set e5 0; set e6 0; set e7 0; set e8 0; set e9 0
+ set f0 0; set f1 0; set f2 0; set f3 0; set f4 0
+ set f5 0; set f6 0; set f7 0; set f8 0; set f9 0
+ set g0 0; set g1 0; set g2 0; set g3 0; set g4 0
+ set g5 0; set g6 0; set g7 0; set g8 0; set g9 0
+ set h0 0; set h1 0; set h2 0; set h3 0; set h4 0
+ set h5 0; set h6 0; set h7 0; set h8 0; set h9 0
+ set i0 0; set i1 0; set i2 0; set i3 0; set i4 0
+ set i5 0; set i6 0; set i7 0; set i8 0; set i9 0
+ set j0 0; set j1 0; set j2 0; set j3 0; set j4 0
+ set j5 0; set j6 0; set j7 0; set j8 0; set j9 0
+ set k0 0; set k1 0; set k2 0; set k3 0; set k4 0
+ set k5 0; set k6 0; set k7 0; set k8 0; set k9 0
+ set l0 0; set l1 0; set l2 0; set l3 0; set l4 0
+ set l5 0; set l6 0; set l7 0; set l8 0; set l9 0
+ set m0 0; set m1 0; set m2 0; set m3 0; set m4 0
+ set m5 0; set m6 0; set m7 0; set m8 0; set m9 0
+ set n0 0; set n1 0; set n2 0; set n3 0; set n4 0
+ set n5 0; set n6 0; set n7 0; set n8 0; set n9 0
+ set o0 0; set o1 0; set o2 0; set o3 0; set o4 0
+ set o5 0; set o6 0; set o7 0; set o8 0; set o9 0
+ set p0 0; set p1 0; set p2 0; set p3 0; set p4 0
+ set p5 0; set p6 0; set p7 0; set p8 0; set p9 0
+ set q0 0; set q1 0; set q2 0; set q3 0; set q4 0
+ set q5 0; set q6 0; set q7 0; set q8 0; set q9 0
+ set r0 0; set r1 0; set r2 0; set r3 0; set r4 0
+ set r5 0; set r6 0; set r7 0; set r8 0; set r9 0
+ set s0 0; set s1 0; set s2 0; set s3 0; set s4 0
+ set s5 0; set s6 0; set s7 0; set s8 0; set s9 0
+ set t0 0; set t1 0; set t2 0; set t3 0; set t4 0
+ set t5 0; set t6 0; set t7 0; set t8 0; set t9 0
+ set u0 0; set u1 0; set u2 0; set u3 0; set u4 0
+ set u5 0; set u6 0; set u7 0; set u8 0; set u9 0
+ set v0 0; set v1 0; set v2 0; set v3 0; set v4 0
+ set v5 0; set v6 0; set v7 0; set v8 0; set v9 0
+ set w0 0; set w1 0; set w2 0; set w3 0; set w4 0
+ set w5 0; set w6 0; set w7 0; set w8 0; set w9 0
+ set x0 0; set x1 0; set x2 0; set x3 0; set x4 0
+ set x5 0; set x6 0; set x7 0; set x8 0; set x9 0
+ set y0 0; set y1 0; set y2 0; set y3 0; set y4 0
+ set y5 0; set y6 0; set y7 0; set y8 0; set y9 0
+ set z0 0; set z1 0; set z2 0; set z3 0; set z4 0
+ set z5 0; set z6 0; set z7 0; set z8 0; set z9 0
+ # now increment the last one (local var index > 255)
+ incr z9
+ }
+ 260locals
+} {1}
+test incr-1.15 {TclCompileIncrCmd: variable is array} -setup {
+ unset -nocomplain a
+} -body {
+ set a(foo) 27
+ incr a(foo) 11
+} -cleanup {
+ unset -nocomplain a
+} -result 38
+test incr-1.16 {TclCompileIncrCmd: variable is array, elem substitutions} -setup {
+ unset -nocomplain a
+} -body {
+ set i 5
+ set a(foo5) 27
+ incr a(foo$i) 11
+} -cleanup {
+ unset -nocomplain a
+} -result 38
+test incr-1.17 {TclCompileIncrCmd: increment given, simple int} {
+ set i 5
+ incr i 123
+} 128
+test incr-1.18 {TclCompileIncrCmd: increment given, simple int} {
+ set i 5
+ incr i -100
+} -95
+test incr-1.19 {TclCompileIncrCmd: increment given, but erroneous} -body {
+ set i 5
+ catch {incr i [set]} -> opts
+ dict get $opts -errorinfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test incr-1.20 {TclCompileIncrCmd: increment given, in quotes} {
+ set i 25
+ incr i "-100"
+} -75
+test incr-1.21 {TclCompileIncrCmd: increment given, in braces} {
+ set i 24
+ incr i {126}
+} 150
+test incr-1.22 {TclCompileIncrCmd: increment given, large int} {
+ set i 5
+ incr i 200000
+} 200005
+test incr-1.23 {TclCompileIncrCmd: increment given, formatted int != int} {
+ set i 25
+ incr i 0o00012345 ;# an octal literal
+} 5374
+test incr-1.24 {TclCompileIncrCmd: increment given, formatted int != int} -body {
+ set i 25
+ incr i 1a
+} -returnCodes error -result {expected integer but got "1a"}
+test incr-1.25 {TclCompileIncrCmd: too many arguments} -body {
+ set i 10
+ incr i 10 20
+} -returnCodes error -result {wrong # args: should be "incr varName ?increment?"}
+test incr-1.26 {TclCompileIncrCmd: runtime error, bad variable name} {
+ unset -nocomplain {"foo}
+ incr {"foo}
+} 1
+test incr-1.27 {TclCompileIncrCmd: runtime error, bad variable name} -body {
+ list [catch {incr [set]} msg] $msg $::errorInfo
+} -match glob -result {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}}
+test incr-1.28 {TclCompileIncrCmd: runtime error, readonly variable} -body {
+ set x 123
+ readonly x
+ list [catch {incr x 1} msg] $msg $::errorInfo
+} -match glob -cleanup {
+ unset -nocomplain x
+} -result {1 {can't set "x": variable is read-only} {*variable is read-only
+ while executing
+*
+"incr x 1"}}
+test incr-1.29 {TclCompileIncrCmd: runtime error, bad variable value} -body {
+ set x " - "
+ incr x 1
+} -returnCodes error -result {expected integer but got " - "}
+test incr-1.30 {TclCompileIncrCmd: array var, braced (no subs)} -setup {
+ catch {unset array}
+} -body {
+ set array(\$foo) 4
+ incr {array($foo)}
+} -result 5
+
+# Check "incr" and computed command names.
+
+unset -nocomplain x i
+test incr-2.0 {incr and computed command names} {
+ set i 5
+ set z incr
+ $z i -1
+ return $i
+} 4
+test incr-2.1 {incr command (not compiled): missing variable name} -body {
+ set z incr
+ $z
+} -returnCodes error -result {wrong # args: should be "incr varName ?increment?"}
+test incr-2.2 {incr command (not compiled): simple variable name} {
+ set z incr
+ set i 10
+ list [$z i] $i
+} {11 11}
+test incr-2.3 {incr command (not compiled): error compiling variable name} -body {
+ set z incr
+ set i 10
+ $z "i"xxx
+} -returnCodes error -result {extra characters after close-quote}
+test incr-2.4 {incr command (not compiled): simple variable name in quotes} {
+ set z incr
+ set i 17
+ list [$z "i"] $i
+} {18 18}
+test incr-2.5 {incr command (not compiled): simple variable name in braces} -setup {
+ unset -nocomplain {a simple var}
+} -body {
+ set z incr
+ set {a simple var} 27
+ list [$z {a simple var}] ${a simple var}
+} -result {28 28}
+test incr-2.6 {incr command (not compiled): simple array variable name} -setup {
+ unset -nocomplain a
+} -body {
+ set z incr
+ set a(foo) 37
+ list [$z a(foo)] $a(foo)
+} -result {38 38}
+test incr-2.7 {incr command (not compiled): non-simple (computed) variable name} {
+ set z incr
+ set x "i"
+ set i 77
+ list [$z $x 2] $i
+} {79 79}
+test incr-2.8 {incr command (not compiled): non-simple (computed) variable name} {
+ set z incr
+ set x "i"
+ set i 77
+ list [$z [set x] +2] $i
+} {79 79}
+test incr-2.9 {incr command (not compiled): increment given} {
+ set z incr
+ set i 10
+ list [$z i +07] $i
+} {17 17}
+test incr-2.10 {incr command (not compiled): no increment given} {
+ set z incr
+ set i 10
+ list [$z i] $i
+} {11 11}
+test incr-2.11 {incr command (not compiled): simple global name} {
+ proc p {} {
+ set z incr
+ global i
+ set i 54
+ $z i
+ }
+ p
+} {55}
+test incr-2.12 {incr command (not compiled): simple local name} {
+ proc p {} {
+ set z incr
+ set foo 100
+ $z foo
+ }
+ p
+} {101}
+test incr-2.13 {incr command (not compiled): simple but new (unknown) local name} {
+ proc p {} {
+ set z incr
+ $z bar
+ }
+ p
+} 1
+test incr-2.14 {incr command (not compiled): simple local name, >255 locals} {
+ proc 260locals {} {
+ set z incr
+ # create 260 locals
+ set a0 0; set a1 0; set a2 0; set a3 0; set a4 0
+ set a5 0; set a6 0; set a7 0; set a8 0; set a9 0
+ set b0 0; set b1 0; set b2 0; set b3 0; set b4 0
+ set b5 0; set b6 0; set b7 0; set b8 0; set b9 0
+ set c0 0; set c1 0; set c2 0; set c3 0; set c4 0
+ set c5 0; set c6 0; set c7 0; set c8 0; set c9 0
+ set d0 0; set d1 0; set d2 0; set d3 0; set d4 0
+ set d5 0; set d6 0; set d7 0; set d8 0; set d9 0
+ set e0 0; set e1 0; set e2 0; set e3 0; set e4 0
+ set e5 0; set e6 0; set e7 0; set e8 0; set e9 0
+ set f0 0; set f1 0; set f2 0; set f3 0; set f4 0
+ set f5 0; set f6 0; set f7 0; set f8 0; set f9 0
+ set g0 0; set g1 0; set g2 0; set g3 0; set g4 0
+ set g5 0; set g6 0; set g7 0; set g8 0; set g9 0
+ set h0 0; set h1 0; set h2 0; set h3 0; set h4 0
+ set h5 0; set h6 0; set h7 0; set h8 0; set h9 0
+ set i0 0; set i1 0; set i2 0; set i3 0; set i4 0
+ set i5 0; set i6 0; set i7 0; set i8 0; set i9 0
+ set j0 0; set j1 0; set j2 0; set j3 0; set j4 0
+ set j5 0; set j6 0; set j7 0; set j8 0; set j9 0
+ set k0 0; set k1 0; set k2 0; set k3 0; set k4 0
+ set k5 0; set k6 0; set k7 0; set k8 0; set k9 0
+ set l0 0; set l1 0; set l2 0; set l3 0; set l4 0
+ set l5 0; set l6 0; set l7 0; set l8 0; set l9 0
+ set m0 0; set m1 0; set m2 0; set m3 0; set m4 0
+ set m5 0; set m6 0; set m7 0; set m8 0; set m9 0
+ set n0 0; set n1 0; set n2 0; set n3 0; set n4 0
+ set n5 0; set n6 0; set n7 0; set n8 0; set n9 0
+ set o0 0; set o1 0; set o2 0; set o3 0; set o4 0
+ set o5 0; set o6 0; set o7 0; set o8 0; set o9 0
+ set p0 0; set p1 0; set p2 0; set p3 0; set p4 0
+ set p5 0; set p6 0; set p7 0; set p8 0; set p9 0
+ set q0 0; set q1 0; set q2 0; set q3 0; set q4 0
+ set q5 0; set q6 0; set q7 0; set q8 0; set q9 0
+ set r0 0; set r1 0; set r2 0; set r3 0; set r4 0
+ set r5 0; set r6 0; set r7 0; set r8 0; set r9 0
+ set s0 0; set s1 0; set s2 0; set s3 0; set s4 0
+ set s5 0; set s6 0; set s7 0; set s8 0; set s9 0
+ set t0 0; set t1 0; set t2 0; set t3 0; set t4 0
+ set t5 0; set t6 0; set t7 0; set t8 0; set t9 0
+ set u0 0; set u1 0; set u2 0; set u3 0; set u4 0
+ set u5 0; set u6 0; set u7 0; set u8 0; set u9 0
+ set v0 0; set v1 0; set v2 0; set v3 0; set v4 0
+ set v5 0; set v6 0; set v7 0; set v8 0; set v9 0
+ set w0 0; set w1 0; set w2 0; set w3 0; set w4 0
+ set w5 0; set w6 0; set w7 0; set w8 0; set w9 0
+ set x0 0; set x1 0; set x2 0; set x3 0; set x4 0
+ set x5 0; set x6 0; set x7 0; set x8 0; set x9 0
+ set y0 0; set y1 0; set y2 0; set y3 0; set y4 0
+ set y5 0; set y6 0; set y7 0; set y8 0; set y9 0
+ set z0 0; set z1 0; set z2 0; set z3 0; set z4 0
+ set z5 0; set z6 0; set z7 0; set z8 0; set z9 0
+ # now increment the last one (local var index > 255)
+ $z z9
+ }
+ 260locals
+} {1}
+test incr-2.15 {incr command (not compiled): variable is array} -setup {
+ unset -nocomplain a
+} -body {
+ set z incr
+ set a(foo) 27
+ $z a(foo) 11
+} -cleanup {
+ unset -nocomplain a
+} -result 38
+test incr-2.16 {incr command (not compiled): variable is array, elem substitutions} -setup {
+ unset -nocomplain a
+} -body {
+ set z incr
+ set i 5
+ set a(foo5) 27
+ $z a(foo$i) 11
+} -cleanup {
+ unset -nocomplain a
+} -result 38
+test incr-2.17 {incr command (not compiled): increment given, simple int} {
+ set z incr
+ set i 5
+ $z i 123
+} 128
+test incr-2.18 {incr command (not compiled): increment given, simple int} {
+ set z incr
+ set i 5
+ $z i -100
+} -95
+test incr-2.19 {incr command (not compiled): increment given, but erroneous} -body {
+ set z incr
+ set i 5
+ catch {$z i [set]} -> opts
+ dict get $opts -errorinfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test incr-2.20 {incr command (not compiled): increment given, in quotes} {
+ set z incr
+ set i 25
+ $z i "-100"
+} -75
+test incr-2.21 {incr command (not compiled): increment given, in braces} {
+ set z incr
+ set i 24
+ $z i {126}
+} 150
+test incr-2.22 {incr command (not compiled): increment given, large int} {
+ set z incr
+ set i 5
+ $z i 200000
+} 200005
+test incr-2.23 {incr command (not compiled): increment given, formatted int != int} {
+ set z incr
+ set i 25
+ $z i 0o00012345 ;# an octal literal
+} 5374
+test incr-2.24 {incr command (not compiled): increment given, formatted int != int} -body {
+ set z incr
+ set i 25
+ $z i 1a
+} -returnCodes error -result {expected integer but got "1a"}
+test incr-2.25 {incr command (not compiled): too many arguments} -body {
+ set z incr
+ set i 10
+ $z i 10 20
+} -returnCodes error -result {wrong # args: should be "incr varName ?increment?"}
+test incr-2.26 {incr command (not compiled): runtime error, bad variable name} -setup {
+ unset -nocomplain {"foo}
+} -body {
+ set z incr
+ $z {"foo}
+} -result 1
+test incr-2.27 {incr command (not compiled): runtime error, bad variable name} -body {
+ set z incr
+ list [catch {$z [set]} msg] $msg $::errorInfo
+} -match glob -result {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}}
+test incr-2.28 {incr command (not compiled): runtime error, readonly variable} -body {
+ set z incr
+ set x 123
+ readonly x
+ list [catch {$z x 1} msg] $msg $::errorInfo
+} -match glob -cleanup {
+ unset -nocomplain x
+} -result {1 {can't set "x": variable is read-only} {*variable is read-only
+ while executing
+*
+"$z x 1"}}
+test incr-2.29 {incr command (not compiled): runtime error, bad variable value} -body {
+ set z incr
+ set x " - "
+ $z x 1
+} -returnCodes error -result {expected integer but got " - "}
+test incr-2.30 {incr command (not compiled): bad increment} {
+ set z incr
+ set x 0
+ list [catch {$z x 1a} msg] $msg $::errorInfo
+} {1 {expected integer but got "1a"} {expected integer but got "1a"
+ (reading increment)
+ invoked from within
+"$z x 1a"}}
+test incr-2.31 {incr command (compiled): bad increment} {
+ list [catch {incr x 1a} msg] $msg $::errorInfo
+} {1 {expected integer but got "1a"} {expected integer but got "1a"
+ (reading increment)
+ invoked from within
+"incr x 1a"}}
+
+test incr-3.1 {increment by wide amount: bytecode route} {
+ set x 0
+ incr x 123123123123
+} 123123123123
+test incr-3.2 {increment by wide amount: command route} {
+ set z incr
+ set x 0
+ $z x 123123123123
+} 123123123123
+
+test incr-4.1 {increment non-existing array element [Bug 1445454]} -body {
+ proc x {} {incr a(1)}
+ x
+} -cleanup {
+ rename x {}
+} -result 1
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/indexObj.test b/library/msgcat/tests/indexObj.test
new file mode 100644
index 0000000..479cc3b
--- /dev/null
+++ b/library/msgcat/tests/indexObj.test
@@ -0,0 +1,163 @@
+# This file is a Tcl script to test out the the procedures in file
+# tkIndexObj.c, which implement indexed table lookups. The tests here are
+# organized in the standard fashion for Tcl tests.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testindexobj [llength [info commands testindexobj]]
+testConstraint testparseargs [llength [info commands testparseargs]]
+
+test indexObj-1.1 {exact match} testindexobj {
+ testindexobj 1 1 xyz abc def xyz alm
+} {2}
+test indexObj-1.2 {exact match} testindexobj {
+ testindexobj 1 1 abc abc def xyz alm
+} {0}
+test indexObj-1.3 {exact match} testindexobj {
+ testindexobj 1 1 alm abc def xyz alm
+} {3}
+test indexObj-1.4 {unique abbreviation} testindexobj {
+ testindexobj 1 1 xy abc def xalb xyz alm
+} {3}
+test indexObj-1.5 {multiple abbreviations and exact match} testindexobj {
+ testindexobj 1 1 x abc def xalb xyz alm x
+} {5}
+test indexObj-1.6 {forced exact match} testindexobj {
+ testindexobj 1 0 xy abc def xalb xy alm
+} {3}
+test indexObj-1.7 {forced exact match} testindexobj {
+ testindexobj 1 0 x abc def xalb xyz alm x
+} {5}
+test indexObj-1.8 {exact match of empty values} testindexobj {
+ testindexobj 1 1 {} a aa aaa {} b bb bbb
+} 3
+test indexObj-1.9 {exact match of empty values} testindexobj {
+ testindexobj 1 0 {} a aa aaa {} b bb bbb
+} 3
+
+test indexObj-2.1 {no match} testindexobj {
+ list [catch {testindexobj 1 1 dddd abc def xalb xyz alm x} msg] $msg
+} {1 {bad token "dddd": must be abc, def, xalb, xyz, alm, or x}}
+test indexObj-2.2 {no match} testindexobj {
+ list [catch {testindexobj 1 1 dddd abc} msg] $msg
+} {1 {bad token "dddd": must be abc}}
+test indexObj-2.3 {no match: no abbreviations} testindexobj {
+ list [catch {testindexobj 1 0 xy abc def xalb xyz alm} msg] $msg
+} {1 {bad token "xy": must be abc, def, xalb, xyz, or alm}}
+test indexObj-2.4 {ambiguous value} testindexobj {
+ list [catch {testindexobj 1 1 d dumb daughter a c} msg] $msg
+} {1 {ambiguous token "d": must be dumb, daughter, a, or c}}
+test indexObj-2.5 {omit error message} testindexobj {
+ list [catch {testindexobj 0 1 d x} msg] $msg
+} {1 {}}
+test indexObj-2.6 {TCL_EXACT => no "ambiguous" error message} testindexobj {
+ list [catch {testindexobj 1 0 d dumb daughter a c} msg] $msg
+} {1 {bad token "d": must be dumb, daughter, a, or c}}
+test indexObj-2.7 {exact match of empty values} testindexobj {
+ list [catch {testindexobj 1 1 {} a b c} msg] $msg
+} {1 {ambiguous token "": must be a, b, or c}}
+test indexObj-2.8 {exact match of empty values: singleton case} testindexobj {
+ list [catch {testindexobj 1 0 {} a} msg] $msg
+} {1 {bad token "": must be a}}
+test indexObj-2.9 {non-exact match of empty values: singleton case} testindexobj {
+ # NOTE this is a special case. Although the empty string is a
+ # unique prefix, we have an established history of rejecting
+ # empty lookup keys, requiring any unique prefix match to have
+ # at least one character.
+ list [catch {testindexobj 1 1 {} a} msg] $msg
+} {1 {bad token "": must be a}}
+
+test indexObj-3.1 {cache result to skip next lookup} testindexobj {
+ testindexobj check 42
+} {42}
+
+test indexObj-4.1 {free old internal representation} testindexobj {
+ set x {a b}
+ lindex $x 1
+ testindexobj 1 1 $x abc def {a b} zzz
+} {2}
+
+test indexObj-5.1 {Tcl_WrongNumArgs} testindexobj {
+ testwrongnumargs 1 "?-switch?" mycmd
+} "wrong # args: should be \"mycmd ?-switch?\""
+test indexObj-5.2 {Tcl_WrongNumArgs} testindexobj {
+ testwrongnumargs 2 "bar" mycmd foo
+} "wrong # args: should be \"mycmd foo bar\""
+test indexObj-5.3 {Tcl_WrongNumArgs} testindexobj {
+ testwrongnumargs 0 "bar" mycmd foo
+} "wrong # args: should be \"bar\""
+test indexObj-5.4 {Tcl_WrongNumArgs} testindexobj {
+ testwrongnumargs 0 "" mycmd foo
+} "wrong # args: should be \"\""
+test indexObj-5.5 {Tcl_WrongNumArgs} testindexobj {
+ testwrongnumargs 1 "" mycmd foo
+} "wrong # args: should be \"mycmd\""
+test indexObj-5.6 {Tcl_WrongNumArgs} testindexobj {
+ testwrongnumargs 2 "" mycmd foo
+} "wrong # args: should be \"mycmd foo\""
+# Contrast this with test proc-3.6; they have to be like this because
+# of [Bug 1066837] so Itcl won't break.
+test indexObj-5.7 {Tcl_WrongNumArgs} testindexobj {
+ testwrongnumargs 2 "fee fi" "fo fum" foo bar
+} "wrong # args: should be \"fo fum foo fee fi\""
+
+test indexObj-6.1 {Tcl_GetIndexFromObjStruct} testindexobj {
+ set x a
+ testgetindexfromobjstruct $x 0
+} "wrong # args: should be \"testgetindexfromobjstruct a 0\""
+test indexObj-6.2 {Tcl_GetIndexFromObjStruct} testindexobj {
+ set x a
+ testgetindexfromobjstruct $x 0
+ testgetindexfromobjstruct $x 0
+} "wrong # args: should be \"testgetindexfromobjstruct a 0\""
+test indexObj-6.3 {Tcl_GetIndexFromObjStruct} testindexobj {
+ set x c
+ testgetindexfromobjstruct $x 1
+} "wrong # args: should be \"testgetindexfromobjstruct c 1\""
+test indexObj-6.4 {Tcl_GetIndexFromObjStruct} testindexobj {
+ set x c
+ testgetindexfromobjstruct $x 1
+ testgetindexfromobjstruct $x 1
+} "wrong # args: should be \"testgetindexfromobjstruct c 1\""
+
+test indexObj-7.1 {Tcl_ParseArgsObjv} testparseargs {
+ testparseargs
+} {0 1 testparseargs}
+test indexObj-7.2 {Tcl_ParseArgsObjv} testparseargs {
+ testparseargs -bool
+} {1 1 testparseargs}
+test indexObj-7.3 {Tcl_ParseArgsObjv} testparseargs {
+ testparseargs -bool bar
+} {1 2 {testparseargs bar}}
+test indexObj-7.4 {Tcl_ParseArgsObjv} testparseargs {
+ testparseargs bar
+} {0 2 {testparseargs bar}}
+test indexObj-7.5 {Tcl_ParseArgsObjv} -constraints testparseargs -body {
+ testparseargs -help
+} -returnCodes error -result {Command-specific options:
+ -bool: booltest
+ --: Marks the end of the options
+ -help: Print summary of command-line options and abort}
+test indexObj-7.6 {Tcl_ParseArgsObjv} testparseargs {
+ testparseargs -- -bool -help
+} {0 3 {testparseargs -bool -help}}
+test indexObj-7.7 {Tcl_ParseArgsObjv memory management} testparseargs {
+ testparseargs 1 2 3 4 5 6 7 8 9 0 -bool 1 2 3 4 5 6 7 8 9 0
+} {1 21 {testparseargs 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0}}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/info.test b/library/msgcat/tests/info.test
new file mode 100644
index 0000000..3323281
--- /dev/null
+++ b/library/msgcat/tests/info.test
@@ -0,0 +1,1964 @@
+# -*- tcl -*-
+# Commands covered: info
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2006 ActiveState
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# DO NOT DELETE THIS LINE
+
+if {{::tcltest} ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Set up namespaces needed to test operation of "info args", "info body",
+# "info default", and "info procs" with imported procedures.
+
+catch {namespace delete test_ns_info1 test_ns_info2}
+
+namespace eval test_ns_info1 {
+ namespace export *
+ proc p {x} {return "x=$x"}
+ proc q {{y 27} {z {}}} {return "y=$y"}
+}
+
+test info-1.1 {info args option} {
+ proc t1 {a bbb c} {return foo}
+ info args t1
+} {a bbb c}
+test info-1.2 {info args option} {
+ proc t1 {{a default1} {bbb default2} {c default3} args} {return foo}
+ info a t1
+} {a bbb c args}
+test info-1.3 {info args option} {
+ proc t1 "" {return foo}
+ info args t1
+} {}
+test info-1.4 {info args option} -body {
+ catch {rename t1 {}}
+ info args t1
+} -returnCodes error -result {"t1" isn't a procedure}
+test info-1.5 {info args option} -body {
+ info args set
+} -returnCodes error -result {"set" isn't a procedure}
+test info-1.6 {info args option} {
+ proc t1 {a b} {set c 123; set d $c}
+ t1 1 2
+ info args t1
+} {a b}
+test info-1.7 {info args option} {
+ catch {namespace delete test_ns_info2}
+ namespace eval test_ns_info2 {
+ namespace import ::test_ns_info1::*
+ list [info args p] [info args q]
+ }
+} {x {y z}}
+
+test info-2.1 {info body option} {
+ proc t1 {} {body of t1}
+ info body t1
+} {body of t1}
+test info-2.2 {info body option} -body {
+ info body set
+} -returnCodes error -result {"set" isn't a procedure}
+test info-2.3 {info body option} -body {
+ info args set 1
+} -returnCodes error -result {wrong # args: should be "info args procname"}
+test info-2.4 {info body option} {
+ catch {namespace delete test_ns_info2}
+ namespace eval test_ns_info2 {
+ namespace import ::test_ns_info1::*
+ list [info body p] [info body q]
+ }
+} {{return "x=$x"} {return "y=$y"}}
+# Prior to 8.3.0 this would cause a crash because [info body]
+# would return the bytecompiled version of foo, which the catch
+# would then try and eval out of the foo context, accessing
+# compiled local indices
+test info-2.5 {info body option, returning bytecompiled bodies} -body {
+ catch {unset args}
+ proc foo {args} {
+ foreach v $args {
+ upvar $v var
+ return "variable $v existence: [info exists var]"
+ }
+ }
+ foo a
+ eval [info body foo]
+} -returnCodes error -result {can't read "args": no such variable}
+# Fix for problem tested for in info-2.5 caused problems when
+# procedure body had no string rep (i.e. was not yet bytecode)
+# causing an empty string to be returned [Bug #545644]
+test info-2.6 {info body option, returning list bodies} {
+ proc foo args [list subst bar]
+ list [string bytelength [info body foo]] \
+ [foo; string bytelength [info body foo]]
+} {9 9}
+
+proc testinfocmdcount {} {
+ set x [info cmdcount]
+ set y 12345
+ set z [info cm]
+ expr {$z-$x}
+}
+test info-3.1 {info cmdcount compiled} {
+ testinfocmdcount
+} 4
+test info-3.2 {info cmdcount evaled} -body {
+ set x [info cmdcount]
+ set y 12345
+ set z [info cm]
+ expr {$z-$x}
+} -cleanup {unset x y z} -result 4
+test info-3.3 {info cmdcount evaled} -body [info body testinfocmdcount] -cleanup {unset x y z} -result 4
+test info-3.4 {info cmdcount option} -body {
+ info cmdcount 1
+} -returnCodes error -result {wrong # args: should be "info cmdcount"}
+
+test info-4.1 {info commands option} -body {
+ proc t1 {} {}
+ proc t2 {} {}
+ set x " [info commands] "
+ list [string match {* t1 *} $x] [string match {* t2 *} $x] \
+ [string match {* set *} $x] [string match {* list *} $x]
+} -cleanup {unset x} -result {1 1 1 1}
+test info-4.2 {info commands option} -body {
+ proc t1 {} {}
+ rename t1 {}
+ string match {* t1 *} \
+ [info comm]
+} -result 0
+test info-4.3 {info commands option} {
+ proc _t1_ {} {}
+ proc _t2_ {} {}
+ info commands _t1_
+} _t1_
+test info-4.4 {info commands option} {
+ proc _t1_ {} {}
+ proc _t2_ {} {}
+ lsort [info commands _t*]
+} {_t1_ _t2_}
+catch {rename _t1_ {}}
+catch {rename _t2_ {}}
+test info-4.5 {info commands option} -returnCodes error -body {
+ info commands a b
+} -result {wrong # args: should be "info commands ?pattern?"}
+# Also some tests in namespace.test
+
+test info-5.1 {info complete option} -body {
+ info complete
+} -returnCodes error -result {wrong # args: should be "info complete command"}
+test info-5.2 {info complete option} {
+ info complete abc
+} 1
+test info-5.3 {info complete option} {
+ info complete "\{abcd "
+} 0
+test info-5.4 {info complete option} {
+ info complete {# Comment should be complete command}
+} 1
+test info-5.5 {info complete option} {
+ info complete {[a [b] }
+} 0
+test info-5.6 {info complete option} {
+ info complete {[a [b]}
+} 0
+
+test info-6.1 {info default option} {
+ proc t1 {a b {c d} {e "long default value"}} {}
+ info default t1 a value
+} 0
+test info-6.2 {info default option} -body {
+ proc t1 {a b {c d} {e "long default value"}} {}
+ set value 12345
+ info d t1 a value
+ return $value
+} -cleanup {unset value} -result {}
+test info-6.3 {info default option} -body {
+ proc t1 {a b {c d} {e "long default value"}} {}
+ info default t1 c value
+} -cleanup {unset value} -result 1
+test info-6.4 {info default option} -body {
+ proc t1 {a b {c d} {e "long default value"}} {}
+ set value 12345
+ info default t1 c value
+ return $value
+} -cleanup {unset value} -result d
+test info-6.5 {info default option} -body {
+ proc t1 {a b {c d} {e "long default value"}} {}
+ set value 12345
+ set x [info default t1 e value]
+ list $x $value
+} -cleanup {unset x value} -result {1 {long default value}}
+test info-6.6 {info default option} -returnCodes error -body {
+ info default a b
+} -result {wrong # args: should be "info default procname arg varname"}
+test info-6.7 {info default option} -returnCodes error -body {
+ info default _nonexistent_ a b
+} -result {"_nonexistent_" isn't a procedure}
+test info-6.8 {info default option} -returnCodes error -body {
+ proc t1 {a b} {}
+ info default t1 x value
+} -result {procedure "t1" doesn't have an argument "x"}
+test info-6.9 {info default option} -returnCodes error -setup {
+ catch {unset a}
+} -cleanup {unset a} -body {
+ set a(0) 88
+ proc t1 {a b} {}
+ info default t1 a a
+} -returnCodes error -result {can't set "a": variable is array}
+test info-6.10 {info default option} -setup {
+ catch {unset a}
+} -cleanup {unset a} -body {
+ set a(0) 88
+ proc t1 {{a 18} b} {}
+ info default t1 a a
+} -returnCodes error -result {can't set "a": variable is array}
+test info-6.11 {info default option} {
+ catch {namespace delete test_ns_info2}
+ namespace eval test_ns_info2 {
+ namespace import ::test_ns_info1::*
+ list [info default p x foo] $foo [info default q y bar] $bar
+ }
+} {0 {} 1 27}
+
+
+test info-7.1 {info exists option} -body {
+ set value foo
+ info exists value
+} -cleanup {unset value} -result 1
+
+test info-7.2 {info exists option} -setup {catch {unset _nonexistent_}} -body {
+ info exists _nonexistent_
+} -result 0
+test info-7.3 {info exists option} {
+ proc t1 {x} {return [info exists x]}
+ t1 2
+} 1
+test info-7.4 {info exists option} -body {
+ proc t1 {x} {
+ global _nonexistent_
+ return [info exists _nonexistent_]
+ }
+ t1 2
+} -setup {unset -nocomplain _nonexistent_} -result 0
+test info-7.5 {info exists option} {
+ proc t1 {x} {
+ set y 47
+ return [info exists y]
+ }
+ t1 2
+} 1
+test info-7.6 {info exists option} {
+ proc t1 {x} {return [info exists value]}
+ t1 2
+} 0
+test info-7.7 {info exists option} -setup {
+ catch {unset x}
+} -body {
+ set x(2) 44
+ list [info exists x] [info exists x(1)] [info exists x(2)]
+} -result {1 0 1}
+catch {unset x}
+test info-7.8 {info exists option} -body {
+ info exists
+} -returnCodes error -result {wrong # args: should be "info exists varName"}
+test info-7.9 {info exists option} -body {
+ info exists 1 2
+} -returnCodes error -result {wrong # args: should be "info exists varName"}
+
+test info-8.1 {info globals option} -body {
+ set x 1
+ set y 2
+ set value 23
+ set a " [info globals] "
+ list [string match {* x *} $a] [string match {* y *} $a] \
+ [string match {* value *} $a] [string match {* _foobar_ *} $a]
+} -cleanup {unset x y value a} -result {1 1 1 0}
+test info-8.2 {info globals option} -body {
+ set _xxx1 1
+ set _xxx2 2
+ lsort [info g _xxx*]
+} -cleanup {unset _xxx1 _xxx2} -result {_xxx1 _xxx2}
+test info-8.3 {info globals option} -returnCodes error -body {
+ info globals 1 2
+} -result {wrong # args: should be "info globals ?pattern?"}
+test info-8.4 {info globals option: may have leading namespace qualifiers} -body {
+ set x 0
+ list [info globals x] [info globals :x] [info globals ::x] [info globals :::x] [info globals ::::x]
+} -cleanup {unset x} -result {x {} x x x}
+test info-8.5 {info globals option: only return existing global variables} {
+ -setup {
+ unset -nocomplain ::NO_SUCH_VAR
+ proc evalInProc script {eval $script}
+ }
+ -body {
+ evalInProc {global NO_SUCH_VAR; info globals NO_SUCH_VAR}
+ }
+ -cleanup {
+ rename evalInProc {}
+ }
+ -result {}
+}
+
+test info-9.1 {info level option} {
+ info level
+} 0
+test info-9.2 {info level option} {
+ proc t1 {a b} {
+ set x [info le]
+ set y [info level 1]
+ list $x $y
+ }
+ t1 146 testString
+} {1 {t1 146 testString}}
+test info-9.3 {info level option} {
+ proc t1 {a b} {
+ t2 [expr $a*2] $b
+ }
+ proc t2 {x y} {
+ list [info level] [info level 1] [info level 2] [info level -1] \
+ [info level 0]
+ }
+ t1 146 {a {b c} {{{c}}}}
+} {2 {t1 146 {a {b c} {{{c}}}}} {t2 292 {a {b c} {{{c}}}}} {t1 146 {a {b c} {{{c}}}}} {t2 292 {a {b c} {{{c}}}}}}
+test info-9.4 {info level option} {
+ proc t1 {} {
+ set x [info level]
+ set y [info level 1]
+ list $x $y
+ }
+ t1
+} {1 t1}
+test info-9.5 {info level option} -body {
+ info level 1 2
+} -returnCodes error -result {wrong # args: should be "info level ?number?"}
+test info-9.6 {info level option} -body {
+ info level 123a
+} -returnCodes error -result {expected integer but got "123a"}
+test info-9.7 {info level option} -body {
+ info level 0
+} -returnCodes error -result {bad level "0"}
+test info-9.8 {info level option} -body {
+ proc t1 {} {info level -1}
+ t1
+} -returnCodes error -result {bad level "-1"}
+test info-9.9 {info level option} -body {
+ proc t1 {x} {info level $x}
+ t1 -3
+} -returnCodes error -result {bad level "-3"}
+test info-9.10 {info level option, namespaces} -body {
+ namespace eval t {info level 0}
+} -cleanup {
+ namespace delete t
+} -result {namespace eval t {info level 0}}
+test info-9.11 {info level option, aliases} -constraints knownBug -setup {
+ proc w {x y z} {info level 0}
+ interp alias {} a {} w a b
+} -body {
+ a c
+} -cleanup {
+ rename a {}
+ rename w {}
+} -result {a c}
+test info-9.12 {info level option, ensembles} -constraints knownBug -setup {
+ proc w {x y z} {info level 0}
+ namespace ensemble create -command a -map {foo ::w}
+} -body {
+ a foo 1 2 3
+} -cleanup {
+ rename a {}
+ rename w {}
+} -result {a foo 1 2 3}
+
+set savedLibrary $tcl_library
+test info-10.1 {info library option} -body {
+ info library x
+} -returnCodes error -result {wrong # args: should be "info library"}
+test info-10.2 {info library option} {
+ set tcl_library 12345
+ info library
+} {12345}
+test info-10.3 {info library option} -body {
+ unset tcl_library
+ info library
+} -returnCodes error -result {no library has been specified for Tcl}
+set tcl_library $savedLibrary; unset savedLibrary
+
+test info-11.1 {info loaded option} -body {
+ info loaded a b
+} -returnCodes error -result {wrong # args: should be "info loaded ?interp?"}
+test info-11.2 {info loaded option} -body {
+ info loaded {}; info loaded gorp
+} -returnCodes error -result {could not find interpreter "gorp"}
+
+test info-12.1 {info locals option} -body {
+ set a 22
+ proc t1 {x y} {
+ set b 13
+ set c testing
+ global a
+ global aa
+ set aa 23
+ return [info locals]
+ }
+ lsort [t1 23 24]
+} -cleanup {unset a aa} -result {b c x y}
+test info-12.2 {info locals option} {
+ proc t1 {x y} {
+ set xx1 2
+ set xx2 3
+ set y 4
+ return [info loc x*]
+ }
+ lsort [t1 2 3]
+} {x xx1 xx2}
+test info-12.3 {info locals option} -body {
+ info locals 1 2
+} -returnCodes error -result {wrong # args: should be "info locals ?pattern?"}
+test info-12.4 {info locals option} {
+ info locals
+} {}
+test info-12.5 {info locals option} {
+ proc t1 {} {return [info locals]}
+ t1
+} {}
+test info-12.6 {info locals vs unset compiled locals} {
+ proc t1 {lst} {
+ foreach $lst $lst {}
+ unset lst
+ return [info locals]
+ }
+ lsort [t1 {a b c c d e f}]
+} {a b c d e f}
+test info-12.7 {info locals with temporary variables} {
+ proc t1 {} {
+ foreach a {b c} {}
+ info locals
+ }
+ t1
+} {a}
+
+test info-13.1 {info nameofexecutable option} -returnCodes error -body {
+ info nameofexecutable foo
+} -result {wrong # args: should be "info nameofexecutable"}
+
+test info-14.1 {info patchlevel option} -body {
+ set a [info patchlevel]
+ regexp {[0-9]+\.[0-9]+([p[0-9]+)?} $a
+} -cleanup {unset a} -result 1
+test info-14.2 {info patchlevel option} -returnCodes error -body {
+ info patchlevel a
+} -result {wrong # args: should be "info patchlevel"}
+test info-14.3 {info patchlevel option} -setup {
+ set t $tcl_patchLevel
+} -body {
+ unset tcl_patchLevel
+ info patchlevel
+} -cleanup {
+ set tcl_patchLevel $t; unset t
+} -returnCodes error -result {can't read "tcl_patchLevel": no such variable}
+
+test info-15.1 {info procs option} -body {
+ proc t1 {} {}
+ proc t2 {} {}
+ set x " [info procs] "
+ list [string match {* t1 *} $x] [string match {* t2 *} $x] \
+ [string match {* _undefined_ *} $x]
+} -cleanup {unset x} -result {1 1 0}
+test info-15.2 {info procs option} {
+ proc _tt1 {} {}
+ proc _tt2 {} {}
+ lsort [info pr _tt*]
+} {_tt1 _tt2}
+catch {rename _tt1 {}}
+catch {rename _tt2 {}}
+test info-15.3 {info procs option} -body {
+ info procs 2 3
+} -returnCodes error -result {wrong # args: should be "info procs ?pattern?"}
+test info-15.4 {info procs option} -setup {
+ catch {namespace delete test_ns_info2}
+} -body {
+ namespace eval test_ns_info2 {
+ namespace import ::test_ns_info1::*
+ proc r {} {}
+ list [lsort [info procs]] [info procs p*]
+ }
+} -result {{p q r} p}
+test info-15.5 {info procs option with a proc in a namespace} -setup {
+ catch {namespace delete test_ns_info2}
+} -body {
+ namespace eval test_ns_info2 {
+ proc p1 { arg } {
+ puts cmd
+ }
+ proc p2 { arg } {
+ puts cmd
+ }
+ }
+ info procs ::test_ns_info2::p1
+} -result {::test_ns_info2::p1}
+test info-15.6 {info procs option with a pattern in a namespace} -setup {
+ catch {namespace delete test_ns_info2}
+} -body {
+ namespace eval test_ns_info2 {
+ proc p1 { arg } {
+ puts cmd
+ }
+ proc p2 { arg } {
+ puts cmd
+ }
+ }
+ lsort [info procs ::test_ns_info2::p*]
+} -result [lsort [list ::test_ns_info2::p1 ::test_ns_info2::p2]]
+test info-15.7 {info procs option with a global shadowing proc} -setup {
+ catch {namespace delete test_ns_info2}
+} -body {
+ proc string_cmd { arg } {
+ puts cmd
+ }
+ namespace eval test_ns_info2 {
+ proc string_cmd { arg } {
+ puts cmd
+ }
+ }
+ info procs test_ns_info2::string*
+} -result {::test_ns_info2::string_cmd}
+# This regression test is currently commented out because it requires
+# that the implementation of "info procs" looks into the global namespace,
+# which it does not (in contrast to "info commands")
+test info-15.8 {info procs option with a global shadowing proc} -setup {
+ catch {namespace delete test_ns_info2}
+} -constraints knownBug -body {
+ proc string_cmd { arg } {
+ puts cmd
+ }
+ proc string_cmd2 { arg } {
+ puts cmd
+ }
+ namespace eval test_ns_info2 {
+ proc string_cmd { arg } {
+ puts cmd
+ }
+ }
+ namespace eval test_ns_info2 {
+ lsort [info procs string*]
+ }
+} -result [lsort [list string_cmd string_cmd2]]
+
+test info-16.1 {info script option} -returnCodes error -body {
+ info script x x
+} -result {wrong # args: should be "info script ?filename?"}
+test info-16.2 {info script option} {
+ file tail [info sc]
+} "info.test"
+set gorpfile [makeFile "info script\n" gorp.info]
+test info-16.3 {info script option} {
+ list [source $gorpfile] [file tail [info script]]
+} [list $gorpfile info.test]
+test info-16.4 {resetting "info script" after errors} {
+ catch {source ~_nobody_/foo}
+ file tail [info script]
+} "info.test"
+test info-16.5 {resetting "info script" after errors} {
+ catch {source _nonexistent_}
+ file tail [info script]
+} "info.test"
+test info-16.6 {info script option} -body {
+ set script [info script]
+ list [file tail [info script]] \
+ [info script newname.txt] \
+ [file tail [info script $script]]
+} -result [list info.test newname.txt info.test] -cleanup {unset script}
+test info-16.7 {info script option} -body {
+ set script [info script]
+ info script newname.txt
+ list [source $gorpfile] [file tail [info script]] \
+ [file tail [info script $script]]
+} -result [list $gorpfile newname.txt info.test] -cleanup {unset script}
+removeFile gorp.info
+set gorpfile [makeFile {list [info script] [info script foo.bar]} gorp.info]
+test info-16.8 {info script option} {
+ list [source $gorpfile] [file tail [info script]]
+} [list [list $gorpfile foo.bar] info.test]
+removeFile gorp.info; unset gorpfile
+
+test info-17.1 {info sharedlibextension option} -returnCodes error -body {
+ info sharedlibextension foo
+} -result {wrong # args: should be "info sharedlibextension"}
+
+test info-18.1 {info tclversion option} -body {
+ scan [info tclversion] "%d.%d%c" a b c
+} -cleanup {unset -nocomplain a b c} -result 2
+test info-18.2 {info tclversion option} -body {
+ info t 2
+} -returnCodes error -result {wrong # args: should be "info tclversion"}
+test info-18.3 {info tclversion option} -body {
+ unset tcl_version
+ info tclversion
+} -returnCodes error -setup {
+ set t $tcl_version
+} -cleanup {
+ set tcl_version $t; unset t
+} -result {can't read "tcl_version": no such variable}
+
+test info-19.1 {info vars option} -body {
+ set a 1
+ set b 2
+ proc t1 {x y} {
+ global a b
+ set c 33
+ return [info vars]
+ }
+ lsort [t1 18 19]
+} -cleanup {unset a b} -result {a b c x y}
+test info-19.2 {info vars option} -body {
+ set xxx1 1
+ set xxx2 2
+ proc t1 {xxa y} {
+ global xxx1 xxx2
+ set c 33
+ return [info vars x*]
+ }
+ lsort [t1 18 19]
+} -cleanup {unset xxx1 xxx2} -result {xxa xxx1 xxx2}
+test info-19.3 {info vars option} {
+ lsort [info vars]
+} [lsort [info globals]]
+test info-19.4 {info vars option} -returnCodes error -body {
+ info vars a b
+} -result {wrong # args: should be "info vars ?pattern?"}
+test info-19.5 {info vars with temporary variables} {
+ proc t1 {} {
+ foreach a {b c} {}
+ info vars
+ }
+ t1
+} {a}
+test info-19.6 {info vars: Bug 1072654} -setup {
+ namespace eval :: unset -nocomplain foo
+ catch {namespace delete x}
+} -body {
+ namespace eval x info vars foo
+} -cleanup {
+ namespace delete x
+} -result {}
+
+set functions {abs acos asin atan atan2 bool ceil cos cosh double entier exp floor fmod hypot int isqrt log log10 max min pow rand round sin sinh sqrt srand tan tanh wide}
+# Check whether the extra testing functions are defined...
+if {!([catch {expr T1()} msg] && ($msg eq {invalid command name "tcl::mathfunc::T1"}))} {
+ set functions "T1 T2 T3 $functions" ;# A lazy way of prepending!
+}
+test info-20.1 {info functions option} {info functions sin} sin
+test info-20.2 {info functions option} {lsort [info functions]} $functions
+test info-20.3 {info functions option} {
+ lsort [info functions a*]
+} {abs acos asin atan atan2}
+test info-20.4 {info functions option} {
+ lsort [info functions *tan*]
+} {atan atan2 tan tanh}
+test info-20.5 {info functions option} -returnCodes error -body {
+ info functions raise an error
+} -result {wrong # args: should be "info functions ?pattern?"}
+unset functions msg
+
+test info-21.1 {miscellaneous error conditions} -returnCodes error -body {
+ info
+} -result {wrong # args: should be "info subcommand ?arg ...?"}
+test info-21.2 {miscellaneous error conditions} -returnCodes error -body {
+ info gorp
+} -result {unknown or ambiguous subcommand "gorp": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars}
+test info-21.3 {miscellaneous error conditions} -returnCodes error -body {
+ info c
+} -result {unknown or ambiguous subcommand "c": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars}
+test info-21.4 {miscellaneous error conditions} -returnCodes error -body {
+ info l
+} -result {unknown or ambiguous subcommand "l": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars}
+test info-21.5 {miscellaneous error conditions} -returnCodes error -body {
+ info s
+} -result {unknown or ambiguous subcommand "s": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars}
+
+##
+# ### ### ### ######### ######### #########
+## info frame
+## Helper
+# For the more complex results we cut the file name down to remove path
+# dependencies, and we use only part of the first line of the reported
+# command. The latter is required because otherwise the whole test case may
+# appear in some results, but the result is part of the testcase. An infinite
+# string would be required to describe that. The cutting-down breaks this.
+proc reduce {frame} {
+ set pos [lsearch -exact $frame cmd]
+ incr pos
+ set cmd [lindex $frame $pos]
+ if {[regexp \n $cmd]} {
+ set first [string range [lindex [split $cmd \n] 0] 0 end-4]
+ set frame [lreplace $frame $pos $pos $first]
+ }
+ set pos [lsearch -exact $frame file]
+ if {$pos >=0} {
+ incr pos
+ set tail [file tail [lindex $frame $pos]]
+ set frame [lreplace $frame $pos $pos $tail]
+ }
+ set frame
+}
+proc subinterp {} { interp create sub ; interp debug sub -frame 1;
+ interp eval sub [list proc reduce [info args reduce] [info body reduce]]
+}
+## Helper
+# Generate a stacktrace from the current location to top. This code
+# not only depends on the exact location of things, but also on the
+# implementation of tcltest. Any changes and these tests will have to
+# be updated.
+
+proc etrace {} {
+ set res {}
+ set level [info frame]
+ while {$level} {
+ lappend res [list $level [reduce [info frame $level]]]
+ incr level -1
+ }
+ return $res
+}
+
+##
+
+test info-22.0 {info frame, levels} {!singleTestInterp} {
+ info frame
+} 7
+test info-22.1 {info frame, bad level relative} {!singleTestInterp} {
+ # catch is another level!, i.e. we have 8, not 7
+ catch {info frame -8} msg
+ set msg
+} {bad level "-8"}
+test info-22.2 {info frame, bad level absolute} {!singleTestInterp} {
+ # catch is another level!, i.e. we have 8, not 7
+ catch {info frame 9} msg
+ set msg
+} {bad level "9"}
+test info-22.3 {info frame, current, relative} -match glob -body {
+ info frame 0
+} -result {type source line 750 file */info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-22.4 {info frame, current, relative, nested} -match glob -body {
+ set res [info frame 0]
+} -result {type source line 753 file */info.test cmd {info frame 0} proc ::tcltest::RunTest} -cleanup {unset res}
+test info-22.5 {info frame, current, absolute} -constraints {!singleTestInterp} -match glob -body {
+ reduce [info frame 7]
+} -result {type source line 756 file info.test cmd {info frame 7} proc ::tcltest::RunTest}
+test info-22.6 {info frame, global, relative} {!singleTestInterp} {
+ reduce [info frame -6]
+} {type source line 758 file info.test cmd test\ info-22.6\ \{info\ frame,\ global,\ relative\}\ \{!singleTestInter level 0}
+test info-22.7 {info frame, global, absolute} {!singleTestInterp} {
+ reduce [info frame 1]
+} {type source line 761 file info.test cmd test\ info-22.7\ \{info\ frame,\ global,\ absolute\}\ \{!singleTestInter level 0}
+test info-22.8 {info frame, basic trace} -match glob -body {
+ join [lrange [etrace] 0 2] \n
+} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type source line 765 file info.test cmd etrace proc ::tcltest::RunTest}
+* {type source line * file tcltest* cmd {uplevel 1 $script} proc ::tcltest::RunTest}}
+unset -nocomplain msg
+
+test info-23.0.0 {eval'd info frame} {!singleTestInterp} {
+ eval {info frame}
+} 8
+test info-23.0.1 {eval'd info frame} -constraints {singleTestInterp} -match glob -body {
+ eval {info frame}
+} -result {1[12]} ;# SingleTestInterp results changes depending on running the whole suite, or info.test alone.
+test info-23.1.0 {eval'd info frame, semi-dynamic} {!singleTestInterp} {
+ eval info frame
+} 8
+test info-23.1.1 {eval'd info frame, semi-dynamic} -constraints {singleTestInterp} -match glob -body {
+ eval info frame
+} -result {1[12]}
+test info-23.2.0 {eval'd info frame, dynamic} -constraints {!singleTestInterp} -body {
+ set script {info frame}
+ eval $script
+} -cleanup {unset script} -result 8
+test info-23.2.1 {eval'd info frame, dynamic} -constraints {singleTestInterp} -match glob -body {
+ set script {info frame}
+ eval $script
+} -cleanup {unset script} -result {1[12]}
+test info-23.3 {eval'd info frame, literal} -match glob -body {
+ eval {
+ info frame 0
+ }
+} -result {type source line 793 file * cmd {info frame 0} proc ::tcltest::RunTest}
+test info-23.4 {eval'd info frame, semi-dynamic} {
+ eval info frame 0
+} {type eval line 1 cmd {info frame 0} proc ::tcltest::RunTest}
+test info-23.5 {eval'd info frame, dynamic} -cleanup {unset script} -body {
+ set script {info frame 0}
+ eval $script
+} -result {type eval line 1 cmd {info frame 0} proc ::tcltest::RunTest}
+test info-23.6 {eval'd info frame, trace} -match glob -cleanup {unset script} -body {
+ set script {etrace}
+ join [lrange [eval $script] 0 2] \n
+} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type eval line 1 cmd etrace proc ::tcltest::RunTest}
+* {type source line 805 file info.test cmd {eval $script} proc ::tcltest::RunTest}}
+
+# -------------------------------------------------------------------------
+
+# Procedures defined in scripts which are arguments to control
+# structures (like 'namespace eval', 'interp eval', 'if', 'while',
+# 'switch', 'catch', 'for', 'foreach', etc.) have no absolute
+# location. The command implementations execute such scripts through
+# Tcl_EvalObjEx. Flag 0 causes it to use the bytecode compiler. This
+# causes the connection to the context to be lost. Currently only
+# procedure bodies are able to remember their context.
+
+# NOTE THAT THESE DO NOT USE THE -setup OPTION TO [test]
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {
+ proc bar {} {info frame 0}
+}
+
+test info-24.0 {info frame, interaction, namespace eval} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 825 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+set flag 1
+if {$flag} {
+ namespace eval foo {}
+ proc ::foo::bar {} {info frame 0}
+}
+
+test info-24.1 {info frame, interaction, if} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 839 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+set flag 1
+while {$flag} {
+ namespace eval foo {}
+ proc ::foo::bar {} {info frame 0}
+ set flag 0
+};unset flag
+
+test info-24.2 {info frame, interaction, while} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 853 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+catch {
+ namespace eval foo {}
+ proc ::foo::bar {} {info frame 0}
+}
+
+test info-24.3 {info frame, interaction, catch} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 867 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+foreach var val {
+ namespace eval foo {}
+ proc ::foo::bar {} {info frame 0}
+ break
+}; unset var
+
+test info-24.4 {info frame, interaction, foreach} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 880 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+for {} {1} {} {
+ namespace eval foo {}
+ proc ::foo::bar {} {info frame 0}
+ break
+}
+
+test info-24.5 {info frame, interaction, for} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 894 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+set x foo
+switch -exact -- $x {
+ foo {
+ proc ::foo::bar {} {info frame 0}
+ }
+}
+
+test info-24.6.0 {info frame, interaction, switch, list body} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+ unset x
+} -result {type source line 910 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+set x foo
+switch -exact -- $x foo {
+ proc ::foo::bar {} {info frame 0}
+}
+
+test info-24.6.1 {info frame, interaction, switch, multi-body} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+ unset x
+} -result {type source line 926 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+set x foo
+switch -exact -- $x [list foo {
+ proc ::foo::bar {} {info frame 0}
+}]
+
+test info-24.6.2 {info frame, interaction, switch, list body, dynamic} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+ unset x
+} -result {type proc line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+dict for {k v} {foo bar} {
+ proc ::foo::bar {} {info frame 0}
+}
+
+test info-24.7 {info frame, interaction, dict for} {
+ reduce [foo::bar]
+} {type source line 955 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo; unset k v
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+set thedict {foo bar}
+dict with thedict {
+ proc ::foo::bar {} {info frame 0}
+}
+
+test info-24.8 {info frame, interaction, dict with} {
+ reduce [foo::bar]
+} {type source line 969 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+unset thedict foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+dict filter {foo bar} script {k v} {
+ proc ::foo::bar {} {info frame 0}
+ set x 1
+}; unset k v x
+
+test info-24.9 {info frame, interaction, dict filter} {
+ reduce [foo::bar]
+} {type source line 983 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+#unset x
+
+# -------------------------------------------------------------------------
+
+eval {
+ proc bar {} {info frame 0}
+}
+
+test info-25.0 {info frame, proc in eval} {
+ reduce [bar]
+} {type source line 997 file info.test cmd {info frame 0} proc ::bar level 0}
+# Don't need to clean up yet...
+
+proc bar {} {info frame 0}
+
+test info-25.1 {info frame, regular proc} {
+ reduce [bar]
+} {type source line 1005 file info.test cmd {info frame 0} proc ::bar level 0}
+
+rename bar {}
+
+# -------------------------------------------------------------------------
+# More info-30.x test cases at the end of the file.
+test info-30.0 {bs+nl in literal words} -cleanup {unset res} -body {
+ if {1} {
+ set res \
+ [reduce [info frame 0]];#1018
+ }
+ return $res
+ # This was reporting line 3 instead of the correct 4 because the
+ # bs+nl combination is subst by the parser before the 'if'
+ # command, and the bcc, see the word. Fixed by recording the
+ # offsets of all bs+nl sequences in literal words, then using the
+ # information in the bcc and other places to bump line numbers when
+ # parsing over the location. Also affected: testcases 22.8 and 23.6.
+} -result {type source line 1018 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+# -------------------------------------------------------------------------
+# See 24.0 - 24.5 for similar situations, using literal scripts.
+
+set body {set flag 0
+ set a c
+ set res [info frame 0]} ;# line 3!
+
+test info-31.0 {ns eval, script in variable} -body {namespace eval foo {variable res {}}
+ namespace eval foo $body
+ return $foo::res
+} -result {type eval line 3 cmd {info frame 0} level 0} -cleanup {
+ catch {namespace delete foo}
+}
+test info-31.1 {if, script in variable} -cleanup {unset res a flag} -body {
+ if 1 $body
+ return $res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-31.1a {if, script in variable} -cleanup {unset res a flag} -body {
+ if 1 then $body
+ return $res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-31.2 {while, script in variable} -cleanup {unset flag res a} -body {
+ set flag 1
+ while {$flag} $body
+ return $res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+# .3 - proc - scoping prevent return of result ...
+
+test info-31.4 {foreach, script in variable} -cleanup {unset var res a flag} -body {
+ foreach var val $body
+ set res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-31.5 {for, script in variable} -cleanup {unset flag res a} -body {
+ set flag 1
+ for {} {$flag} {} $body
+ return $res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-31.6 {eval, script in variable} -cleanup {unset res a flag} -body {
+ eval $body
+ return $res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+# -------------------------------------------------------------------------
+
+set body {
+ foo {
+ proc ::foo::bar {} {info frame 0}
+ }
+}
+
+namespace eval foo {}
+set x foo
+switch -exact -- $x $body; unset body
+
+test info-31.7 {info frame, interaction, switch, dynamic} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+ unset x
+} -result {type proc line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+set body {
+ proc ::foo::bar {} {info frame 0}
+}
+
+namespace eval foo {}
+eval $body
+
+test info-32.0 {info frame, dynamic procedure} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type proc line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace {*}{
+ eval
+ foo
+ {proc bar {} {info frame 0}}
+}
+test info-33.0 {{*}, literal, direct} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 1115 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+ set flag 1
+ if {*}{
+ {$flag}
+ {info frame 0}
+ }
+}
+test info-33.1 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 1130 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace {*}"
+ eval
+ foo
+ {proc bar {} {info frame 0}}
+"
+test info-33.2 {{*}, literal, direct} {
+ reduce [foo::bar]
+} {type source line 1144 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace {*}"eval\nfoo\n{proc bar {} {info frame 0}}\n"
+
+test info-33.2a {{*}, literal, not simple, direct} {
+ reduce [foo::bar]
+} {type proc line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+ set flag 1
+ if {*}"
+ {1}
+ {info frame 0}
+ "
+}
+test info-33.3 {{*}, literal, simple, bytecompiled} {
+ reduce [foo::bar]
+} {type source line 1169 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+ set flag 1
+ if {*}"\n{1}\n{info frame 0}"
+}
+test info-33.3a {{*}, literal, not simple, bytecompiled} {
+ reduce [foo::bar]
+} {type eval line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+set body {
+ eval
+ foo
+ {proc bar {} {
+ info frame 0
+ }}
+}
+namespace {*}$body
+test info-34.0 {{*}, dynamic, direct} {
+ reduce [foo::bar]
+} {type proc line 2 cmd {info frame 0} proc ::foo::bar level 0}
+
+unset body
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+set body {
+ {$flag}
+ {info frame 0}
+}
+proc foo::bar {} {
+ global body ; set flag 1
+ if {*}$body
+}
+test info-34.1 {{*}, literal, bytecompiled} {
+ reduce [foo::bar]
+} {type eval line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+unset body
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+proc foo {} {
+ apply {
+ {x y}
+ {info frame 0}
+ } 0 0
+}
+test info-35.0 {apply, literal} {
+ reduce [foo]
+} {type source line 1231 file info.test cmd {info frame 0} lambda {
+ {x y}
+ {info frame 0}
+ } level 0}
+rename foo {}
+
+set lambda {
+ {x y}
+ {info frame 0}
+}
+test info-35.1 {apply, dynamic} {
+ reduce [apply $lambda 0 0]
+} {type proc line 1 cmd {info frame 0} lambda {
+ {x y}
+ {info frame 0}
+} level 0}
+unset lambda
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+ dict for {k v} {foo bar} {
+ set x [info frame 0]
+ }
+ set x
+}
+test info-36.0 {info frame, dict for, bcc} -body {
+ reduce [foo::bar]
+} -result {type source line 1259 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+ set x foo
+ switch -exact -- $x {
+ foo {set y [info frame 0]}
+ }
+ set y
+}
+
+test info-36.1.0 {switch, list literal, bcc} -body {
+ reduce [foo::bar]
+} -result {type source line 1275 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+ set x foo
+ switch -exact -- $x foo {set y [info frame 0]}
+ set y
+}
+
+test info-36.1.1 {switch, multi-body literals, bcc} -body {
+ reduce [foo::bar]
+} -result {type source line 1291 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+test info-37.0 {eval pure list, single line} -match glob -body {
+ # Basically, counting the newline in the word seen through $foo
+ # doesn't really make sense. It makes a bit of sense if the word
+ # would have been a string literal in the command list.
+ #
+ # Problem: At the point where we see the list elements we cannot
+ # distinguish the two cases, thus we cannot switch between
+ # count/not-count, it is has to be one or the other for all
+ # cases. Of the two possibilities miguel convinced me that 'not
+ # counting' is the more proper.
+ set foo {b
+ c}
+ set cmd [list foreach $foo {x y} {
+ set res [join [lrange [etrace] 0 2] \n]
+ break
+ }]
+ eval $cmd
+ return $res
+} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type eval line 2 cmd etrace proc ::tcltest::RunTest}
+* {type eval line 1 cmd foreac proc ::tcltest::RunTest}} -cleanup {unset foo cmd res b c}
+
+# -------------------------------------------------------------------------
+
+# 6 cases.
+## DV. direct-var - unchanged
+## DPV direct-proc-var - ditto
+## PPV proc-proc-var - ditto
+## DL. direct-literal - now tracking absolute location
+## DPL direct-proc-literal - ditto
+## PPL proc-proc-literal - ditto
+## ### ### ### ######### ######### #########"
+
+proc control {vv script} {
+ upvar 1 $vv var
+ return [uplevel 1 $script]
+}
+
+proc datal {} {
+ control y {
+ set y PPL
+ etrace
+ }
+}
+
+proc datav {} {
+ set script {
+ set y PPV
+ etrace
+ }
+ control y $script
+}
+
+test info-38.1 {location information for uplevel, dv, direct-var} -match glob -body {
+ set script {
+ set y DV.
+ etrace
+ }
+ join [lrange [uplevel \#0 $script] 0 2] \n
+} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type eval line 3 cmd etrace proc ::tcltest::RunTest}
+* {type source line 1361 file info.test cmd {uplevel \\#0 $script} proc ::tcltest::RunTest}} -cleanup {unset script y}
+
+# 38.2 moved to bottom to not disturb other tests with the necessary changes to this one.
+
+
+
+
+
+
+
+
+test info-38.3 {location information for uplevel, dpv, direct-proc-var} -match glob -body {
+ set script {
+ set y DPV
+ etrace
+ }
+ join [lrange [control y $script] 0 3] \n
+} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type eval line 3 cmd etrace proc ::control}
+* {type source line 1338 file info.test cmd {uplevel 1 $script} proc ::control}
+* {type source line 1380 file info.test cmd {control y $script} proc ::tcltest::RunTest}} -cleanup {unset script y}
+
+# 38.4 moved to bottom to not disturb other tests with the necessary changes to this one.
+
+
+
+
+
+
+
+
+
+test info-38.5 {location information for uplevel, ppv, proc-proc-var} -match glob -body {
+ join [lrange [datav] 0 4] \n
+} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type eval line 3 cmd etrace proc ::control}
+* {type source line 1338 file info.test cmd {uplevel 1 $script} proc ::control}
+* {type source line 1353 file info.test cmd {control y $script} proc ::datav level 1}
+* {type source line 1397 file info.test cmd datav proc ::tcltest::RunTest}}
+
+# 38.6 moved to bottom to not disturb other tests with the necessary changes to this one.
+
+
+
+
+
+
+
+testConstraint testevalex [llength [info commands testevalex]]
+test info-38.7 {location information for arg substitution} -constraints testevalex -match glob -body {
+ join [lrange [testevalex {return -level 0 [etrace]}] 0 3] \n
+} -result {* {type source line 728 file info.test cmd {info frame \$level} proc ::etrace level 0}
+* {type eval line 1 cmd etrace proc ::tcltest::RunTest}
+* {type source line 1414 file info.test cmd {testevalex {return -level 0 \[etrace]}} proc ::tcltest::RunTest}
+* {type source line * file tcltest* cmd {uplevel 1 $script} proc ::tcltest::RunTest}}
+
+# -------------------------------------------------------------------------
+# literal sharing
+
+test info-39.0 {location information not confused by literal sharing} -body {
+ namespace eval ::foo {}
+ proc ::foo::bar {} {
+ lappend res {}
+ lappend res [reduce [eval {info frame 0}]]
+ lappend res [reduce [eval {info frame 0}]]
+ return $res
+ }
+ set res [::foo::bar]
+ namespace delete ::foo
+ join $res \n
+} -cleanup {unset res} -result {
+type source line 1427 file info.test cmd {info frame 0} proc ::foo::bar level 0
+type source line 1428 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+# Additional tests for info-30.*, handling of continuation lines (bs+nl sequences).
+
+test info-30.1 {bs+nl in literal words, procedure body, compiled} -body {
+ proc abra {} {
+ if {1} \
+ {
+ return \
+ [reduce [info frame 0]];# line 1446
+ }
+ }
+ abra
+} -cleanup {
+ rename abra {}
+} -result {type source line 1446 file info.test cmd {info frame 0} proc ::abra level 0}
+
+test info-30.2 {bs+nl in literal words, namespace script} {
+ namespace eval xxx {
+ variable res \
+ [reduce [info frame 0]];# line 1457
+ }
+ return $xxx::res
+} {type source line 1457 file info.test cmd {info frame 0} level 0}
+
+test info-30.3 {bs+nl in literal words, namespace multi-word script} {
+ namespace eval xxx variable res \
+ [list [reduce [info frame 0]]];# line 1464
+ return $xxx::res
+} {type source line 1464 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.4 {bs+nl in literal words, eval script} -cleanup {unset res} -body {
+ eval {
+ set ::res \
+ [reduce [info frame 0]];# line 1471
+ }
+ return $res
+} -result {type source line 1471 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.5 {bs+nl in literal words, eval script, with nested words} -body {
+ eval {
+ if {1} \
+ {
+ set ::res \
+ [reduce [info frame 0]];# line 1481
+ }
+ }
+ return $res
+} -cleanup {unset res} -result {type source line 1481 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.6 {bs+nl in computed word} -cleanup {unset res} -body {
+ set res "\
+[reduce [info frame 0]]";# line 1489
+} -result { type source line 1489 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.7 {bs+nl in computed word, in proc} -body {
+ proc abra {} {
+ return "\
+[reduce [info frame 0]]";# line 1495
+ }
+ abra
+} -cleanup {
+ rename abra {}
+} -result { type source line 1495 file info.test cmd {info frame 0} proc ::abra level 0}
+
+test info-30.8 {bs+nl in computed word, nested eval} -body {
+ eval {
+ set \
+ res "\
+[reduce [info frame 0]]";# line 1506
+}
+} -cleanup {unset res} -result { type source line 1506 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.9 {bs+nl in computed word, nested eval} -body {
+ eval {
+ set \
+ res "\
+[reduce \
+ [info frame 0]]";# line 1515
+}
+} -cleanup {unset res} -result { type source line 1515 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.10 {bs+nl in computed word, key to array} -body {
+ set tmp([set \
+ res "\
+[reduce \
+ [info frame 0]]"]) x ; #1523
+ unset tmp
+ set res
+} -cleanup {unset res} -result { type source line 1523 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.11 {bs+nl in subst arguments} -body {
+ subst {[set \
+ res "\
+[reduce \
+ [info frame 0]]"]} ; #1532
+} -cleanup {unset res} -result { type source line 1532 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.12 {bs+nl in computed word, nested eval} -body {
+ eval {
+ set \
+ res "\
+[set x {}] \
+[reduce \
+ [info frame 0]]";# line 1541
+}
+} -cleanup {unset res x} -result { type source line 1541 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.13 {bs+nl in literal words, uplevel script, with nested words} -body {
+ subinterp ; set res [interp eval sub { uplevel #0 {
+ if {1} \
+ {
+ set ::res \
+ [reduce [info frame 0]];# line 1550
+ }
+ }
+ set res }] ; interp delete sub ; set res
+} -cleanup {unset res} -result {type source line 1550 file info.test cmd {info frame 0} level 0}
+
+test info-30.14 {bs+nl, literal word, uplevel through proc} {
+ subinterp ; set res [interp eval sub { proc abra {script} {
+ uplevel 1 $script
+ }
+ set res [abra {
+ return "\
+[reduce [info frame 0]]";# line 1562
+ }]
+ rename abra {}
+ set res }] ; interp delete sub ; set res
+} { type source line 1562 file info.test cmd {info frame 0} proc ::abra}
+
+test info-30.15 {bs+nl in literal words, nested proc body, compiled} {
+ proc a {} {
+ proc b {} {
+ if {1} \
+ {
+ return \
+ [reduce [info frame 0]];# line 1574
+ }
+ }
+ }
+ a ; set res [b]
+ rename a {}
+ rename b {}
+ set res
+} {type source line 1574 file info.test cmd {info frame 0} proc ::b level 0}
+
+test info-30.16 {bs+nl in multi-body switch, compiled} {
+ proc a {value} {
+ switch -regexp -- $value \
+ ^key { info frame 0; # 1587 } \
+ \t### { info frame 0; # 1588 } \
+ {[0-9]*} { info frame 0; # 1589 }
+ }
+ set res {}
+ lappend res [reduce [a {key }]]
+ lappend res [reduce [a {1alpha}]]
+ set res "\n[join $res \n]"
+} {
+type source line 1587 file info.test cmd {info frame 0} proc ::a level 0
+type source line 1589 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.17 {bs+nl in multi-body switch, direct} {
+ switch -regexp -- {key } \
+ ^key { reduce [info frame 0] ;# 1601 } \
+ \t### { } \
+ {[0-9]*} { }
+} {type source line 1601 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.18 {bs+nl, literal word, uplevel through proc, appended, loss of primary tracking data} {
+ proc abra {script} {
+ append script "\n# end of script"
+ uplevel 1 $script
+ }
+ set res [abra {
+ return "\
+[reduce [info frame 0]]";# line 1613, still line of 3 appended script
+ }]
+ rename abra {}
+ set res
+} { type eval line 3 cmd {info frame 0} proc ::abra}
+# { type source line 1606 file info.test cmd {info frame 0} proc ::abra}
+
+test info-30.19 {bs+nl in single-body switch, compiled} {
+ proc a {value} {
+ switch -regexp -- $value {
+ ^key { reduce \
+ [info frame 0] }
+ \t { reduce \
+ [info frame 0] }
+ {[0-9]*} { reduce \
+ [info frame 0] }
+ }
+ }
+ set res {}
+ lappend res [a {key }]
+ lappend res [a {1alpha}]
+ set res "\n[join $res \n]"
+} {
+type source line 1624 file info.test cmd {info frame 0} proc ::a level 0
+type source line 1628 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.20 {bs+nl in single-body switch, direct} {
+ switch -regexp -- {key } { \
+
+ ^key { reduce \
+ [info frame 0] }
+ \t### { }
+ {[0-9]*} { }
+ }
+} {type source line 1643 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.21 {bs+nl in if, full compiled} {
+ proc a {value} {
+ if {$value} \
+ {info frame 0} \
+ {info frame 0} ; # 1653
+ }
+ set res {}
+ lappend res [reduce [a 1]]
+ lappend res [reduce [a 0]]
+ set res "\n[join $res \n]"
+} {
+type source line 1652 file info.test cmd {info frame 0} proc ::a level 0
+type source line 1653 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.22 {bs+nl in computed word, key to array, compiled} {
+ proc a {} {
+ set tmp([set \
+ res "\
+[reduce \
+ [info frame 0]]"]) x ; #1668
+ unset tmp
+ set res
+ }
+ set res [a]
+ rename a {}
+ set res
+} { type source line 1668 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.23 {bs+nl in multi-body switch, full compiled} {
+ proc a {value} {
+ switch -exact -- $value \
+ key { info frame 0; # 1680 } \
+ xxx { info frame 0; # 1681 } \
+ 000 { info frame 0; # 1682 }
+ }
+ set res {}
+ lappend res [reduce [a key]]
+ lappend res [reduce [a 000]]
+ set res "\n[join $res \n]"
+} {
+type source line 1680 file info.test cmd {info frame 0} proc ::a level 0
+type source line 1682 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.24 {bs+nl in single-body switch, full compiled} {
+ proc a {value} {
+ switch -exact -- $value {
+ key { reduce \
+ [info frame 0] }
+ xxx { reduce \
+ [info frame 0] }
+ 000 { reduce \
+ [info frame 0] }
+ }
+ }
+ set res {}
+ lappend res [a key]
+ lappend res [a 000]
+ set res "\n[join $res \n]"
+} {
+type source line 1696 file info.test cmd {info frame 0} proc ::a level 0
+type source line 1700 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.25 {TIP 280 for compiled [subst]} {
+ subst {[reduce [info frame 0]]} ; # 1712
+} {type source line 1712 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.26 {TIP 280 for compiled [subst]} {
+ subst \
+ {[reduce [info frame 0]]} ; # 1716
+} {type source line 1716 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.27 {TIP 280 for compiled [subst]} {
+ subst {
+[reduce [info frame 0]]} ; # 1720
+} {
+type source line 1720 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.28 {TIP 280 for compiled [subst]} {
+ subst {\
+[reduce [info frame 0]]} ; # 1725
+} { type source line 1725 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.29 {TIP 280 for compiled [subst]} {
+ subst {foo\
+[reduce [info frame 0]]} ; # 1729
+} {foo type source line 1729 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.30 {TIP 280 for compiled [subst]} {
+ subst {foo
+[reduce [info frame 0]]} ; # 1733
+} {foo
+type source line 1733 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.31 {TIP 280 for compiled [subst]} {
+ subst {[][reduce [info frame 0]]} ; # 1737
+} {type source line 1737 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.32 {TIP 280 for compiled [subst]} {
+ subst {[\
+][reduce [info frame 0]]} ; # 1741
+} {type source line 1741 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.33 {TIP 280 for compiled [subst]} {
+ subst {[
+][reduce [info frame 0]]} ; # 1745
+} {type source line 1745 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.34 {TIP 280 for compiled [subst]} {
+ subst {[format %s {}
+][reduce [info frame 0]]} ; # 1749
+} {type source line 1749 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.35 {TIP 280 for compiled [subst]} {
+ subst {[format %s {}
+]
+[reduce [info frame 0]]} ; # 1754
+} {
+type source line 1754 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.36 {TIP 280 for compiled [subst]} {
+ subst {
+[format %s {}][reduce [info frame 0]]} ; # 1759
+} {
+type source line 1759 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.37 {TIP 280 for compiled [subst]} {
+ subst {
+[format %s {}]
+[reduce [info frame 0]]} ; # 1765
+} {
+
+type source line 1765 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.38 {TIP 280 for compiled [subst]} {
+ subst {\
+[format %s {}][reduce [info frame 0]]} ; # 1771
+} { type source line 1771 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.39 {TIP 280 for compiled [subst]} {
+ subst {\
+[format %s {}]\
+[reduce [info frame 0]]} ; # 1776
+} { type source line 1776 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.40 {TIP 280 for compiled [subst]} -setup {
+ unset -nocomplain empty
+} -body {
+ set empty {}
+ subst {$empty[reduce [info frame 0]]} ; # 1782
+} -cleanup {
+ unset empty
+} -result {type source line 1782 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.41 {TIP 280 for compiled [subst]} -setup {
+ unset -nocomplain empty
+} -body {
+ set empty {}
+ subst {$empty
+[reduce [info frame 0]]} ; # 1791
+} -cleanup {
+ unset empty
+} -result {
+type source line 1791 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.42 {TIP 280 for compiled [subst]} -setup {
+ unset -nocomplain empty
+} -body {
+ set empty {}; subst {$empty\
+[reduce [info frame 0]]} ; # 1800
+} -cleanup {
+ unset empty
+} -result { type source line 1800 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.43 {TIP 280 for compiled [subst]} -body {
+ unset -nocomplain a\nb
+ set a\nb {}
+ subst {${a
+b}[reduce [info frame 0]]} ; # 1808
+} -cleanup {unset a\nb} -result {type source line 1808 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.44 {TIP 280 for compiled [subst]} {
+ unset -nocomplain a
+ set a(\n) {}
+ subst {$a(
+)[reduce [info frame 0]]} ; # 1814
+} {type source line 1814 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.45 {TIP 280 for compiled [subst]} {
+ unset -nocomplain a
+ set a() {}
+ subst {$a([
+return -level 0])[reduce [info frame 0]]} ; # 1820
+} {type source line 1820 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.46 {TIP 280 for compiled [subst]} {
+ unset -nocomplain a
+ set a(1825) YES; set a(1824) 1824; set a(1826) 1826
+ subst {$a([dict get [info frame 0] line])} ; # 1825
+} YES
+test info-30.47 {TIP 280 for compiled [subst]} {
+ unset -nocomplain a
+ set a(\n1831) YES; set a(\n1830) 1830; set a(\n1832) 1832
+ subst {$a(
+[dict get [info frame 0] line])} ; # 1831
+} YES
+unset -nocomplain a
+
+test info-30.48 {Bug 2850901} testevalex {
+ testevalex {return -level 0 [format %s {}
+][reduce [info frame 0]]} ; # line 2 of the eval
+} {type eval line 2 cmd {info frame 0} proc ::tcltest::RunTest}
+
+
+# -------------------------------------------------------------------------
+# literal sharing 2, bug 2933089
+
+test info-39.1 {location information not confused by literal sharing, bug 2933089} -setup {
+ set result {}
+
+ proc print_one {} {}
+ proc test_info_frame {} {
+ set x 1
+ set y x
+
+ if "$x != 1" {
+ } else {
+ print_one
+ } ;#line 1854^
+
+ if "$$y != 1" {
+ } else {
+ print_one
+ } ;#line 1859^
+ # Do not put the comments listing the line numbers into the
+ # branches. We need shared literals, and the comments would
+ # make them different, thus unshared.
+ }
+
+ proc get_frame_info { cmd_str op } {
+ lappend ::result [reduce [eval {info frame -3}]]
+ }
+ trace add execution print_one enter get_frame_info
+} -body {
+ test_info_frame;
+ join $result \n
+} -cleanup {
+ trace remove execution print_one enter get_frame_info
+ rename get_frame_info {}
+ rename test_info_frame {}
+ rename print_one {}
+} -result {type source line 1854 file info.test cmd print_one proc ::test_info_frame level 1
+type source line 1859 file info.test cmd print_one proc ::test_info_frame level 1}
+
+# -------------------------------------------------------------------------
+# Tests moved to the end to not disturb other tests and their locations.
+
+test info-38.6 {location information for uplevel, ppl, proc-proc-literal} -match glob -setup {subinterp} -body {
+ interp eval sub {
+ proc etrace {} {
+ set res {}
+ set level [info frame]
+ while {$level} {
+ lappend res [list $level [reduce [info frame $level]]]
+ incr level -1
+ }
+ return $res
+ }
+ proc control {vv script} {
+ upvar 1 $vv var
+ return [uplevel 1 $script]
+ }
+ proc datal {} {
+ control y {
+ set y PPL
+ etrace
+ }
+ }
+ join [lrange [datal] 0 4] \n
+ }
+} -result {* {type source line 1890 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type source line 1902 file info.test cmd etrace proc ::control}
+* {type source line 1897 file info.test cmd {uplevel 1 $script} proc ::control}
+* {type source line 1900 file info.test cmd control proc ::datal level 1}
+* {type source line 1905 file info.test cmd datal level 2}} -cleanup {interp delete sub}
+
+test info-38.4 {location information for uplevel, dpv, direct-proc-literal} -match glob -setup {subinterp} -body {
+ interp eval sub {
+ proc etrace {} {
+ set res {}
+ set level [info frame]
+ while {$level} {
+ lappend res [list $level [reduce [info frame $level]]]
+ incr level -1
+ }
+ return $res
+ }
+ proc control {vv script} {
+ upvar 1 $vv var
+ return [uplevel 1 $script]
+ }
+ join [lrange [control y {
+ set y DPL
+ etrace
+ }] 0 3] \n
+ }
+} -result {* {type source line 1919 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type source line 1930 file info.test cmd etrace proc ::control}
+* {type source line 1926 file info.test cmd {uplevel 1 $script} proc ::control}
+* {type source line 1928 file info.test cmd control level 1}} -cleanup {interp delete sub}
+
+test info-38.2 {location information for uplevel, dl, direct-literal} -match glob -setup {subinterp} -body {
+ interp eval sub {
+ proc etrace {} {
+ set res {}
+ set level [info frame]
+ while {$level} {
+ lappend res [list $level [reduce [info frame $level]]]
+ incr level -1
+ }
+ return $res
+ }
+ join [lrange [uplevel \#0 {
+ set y DL.
+ etrace
+ }] 0 2] \n
+ }
+} -result {* {type source line 1944 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type source line 1951 file info.test cmd etrace level 1}
+* {type source line 1949 file info.test cmd uplevel\\ \\\\ level 1}} -cleanup {interp delete sub}
+
+# -------------------------------------------------------------------------
+unset -nocomplain res
+
+# cleanup
+catch {namespace delete test_ns_info1 test_ns_info2}
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/init.test b/library/msgcat/tests/init.test
new file mode 100644
index 0000000..41b8624
--- /dev/null
+++ b/library/msgcat/tests/init.test
@@ -0,0 +1,195 @@
+# Functionality covered: this file contains a collection of tests for the auto
+# loading and namespaces.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2.3.4
+ namespace import -force ::tcltest::*
+}
+
+# Clear out any namespaces called test_ns_*
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+
+# Six cases - white box testing
+
+test init-1.1 {auto_qualify - absolute cmd - namespace} {
+ auto_qualify ::foo::bar ::blue
+} ::foo::bar
+test init-1.2 {auto_qualify - absolute cmd - global} {
+ auto_qualify ::global ::sub
+} global
+test init-1.3 {auto_qualify - no colons cmd - global} {
+ auto_qualify nocolons ::
+} nocolons
+test init-1.4 {auto_qualify - no colons cmd - namespace} {
+ auto_qualify nocolons ::sub
+} {::sub::nocolons nocolons}
+test init-1.5 {auto_qualify - colons in cmd - global} {
+ auto_qualify foo::bar ::
+} ::foo::bar
+test init-1.6 {auto_qualify - colons in cmd - namespace} {
+ auto_qualify foo::bar ::sub
+} {::sub::foo::bar ::foo::bar}
+# Some additional tests
+test init-1.7 {auto_qualify - multiples colons 1} {
+ auto_qualify :::foo::::bar ::blue
+} ::foo::bar
+test init-1.8 {auto_qualify - multiple colons 2} {
+ auto_qualify :::foo ::bar
+} foo
+
+# We use a sub-interp and auto_reset and double the tests because there is 2
+# places where auto_loading occur (before loading the indexes files and after)
+
+set testInterp [interp create]
+tcltest::loadIntoSlaveInterpreter $testInterp {*}$argv
+interp eval $testInterp {
+ namespace import -force ::tcltest::*
+ customMatch pairwise {apply {{mode pair} {
+ if {[llength $pair] != 2} {error "need a pair of values to check"}
+ string $mode [lindex $pair 0] [lindex $pair 1]
+ }}}
+
+ auto_reset
+ catch {rename parray {}}
+
+test init-2.0 {load parray - stage 1} -body {
+ parray
+} -returnCodes error -cleanup {
+ rename parray {} ;# remove it, for the next test - that should not fail.
+} -result {wrong # args: should be "parray a ?pattern?"}
+test init-2.1 {load parray - stage 2} -body {
+ parray
+} -returnCodes error -result {wrong # args: should be "parray a ?pattern?"}
+auto_reset
+catch {rename ::safe::setLogCmd {}}
+#unset -nocomplain auto_index(::safe::setLogCmd) auto_oldpath
+test init-2.2 {load ::safe::setLogCmd - stage 1} {
+ ::safe::setLogCmd
+ rename ::safe::setLogCmd {} ;# should not fail
+} {}
+test init-2.3 {load ::safe::setLogCmd - stage 2} {
+ ::safe::setLogCmd
+ rename ::safe::setLogCmd {} ;# should not fail
+} {}
+auto_reset
+catch {rename ::safe::setLogCmd {}}
+test init-2.4 {load safe:::setLogCmd - stage 1} {
+ safe:::setLogCmd ;# intentionally 3 :
+ rename ::safe::setLogCmd {} ;# should not fail
+} {}
+test init-2.5 {load safe:::setLogCmd - stage 2} {
+ safe:::setLogCmd ;# intentionally 3 :
+ rename ::safe::setLogCmd {} ;# should not fail
+} {}
+auto_reset
+catch {rename ::safe::setLogCmd {}}
+test init-2.6 {load setLogCmd from safe:: - stage 1} {
+ namespace eval safe setLogCmd
+ rename ::safe::setLogCmd {} ;# should not fail
+} {}
+test init-2.7 {oad setLogCmd from safe:: - stage 2} {
+ namespace eval safe setLogCmd
+ rename ::safe::setLogCmd {} ;# should not fail
+} {}
+test init-2.8 {load tcl::HistAdd} -setup {
+ auto_reset
+ catch {rename ::tcl::HistAdd {}}
+} -body {
+ # 3 ':' on purpose
+ tcl:::HistAdd
+} -returnCodes error -cleanup {
+ rename ::tcl::HistAdd {}
+} -result {wrong # args: should be "tcl:::HistAdd event ?exec?"}
+
+test init-3.0 {random stuff in the auto_index, should still work} {
+ set auto_index(foo:::bar::blah) {
+ namespace eval foo {namespace eval bar {proc blah {} {return 1}}}
+ }
+ foo:::bar::blah
+} 1
+
+# Tests that compare the error stack trace generated when autoloading with
+# that generated when no autoloading is necessary. Ideally they should be the
+# same.
+
+set count 0
+foreach arg [subst -nocommands -novariables {
+ c
+ {argument
+ which spans
+ multiple lines}
+ {argument which is all on one line but which is of such great length that the Tcl C library will truncate it when appending it onto the global error stack}
+ {argument which spans multiple lines
+ and is long enough to be truncated and
+" <- includes a false lead in the prune point search
+ and must be longer still to force truncation}
+ {contrived example: rare circumstance
+ where the point at which to prune the
+ error stack cannot be uniquely determined.
+ foo bar foo
+"}
+ {contrived example: rare circumstance
+ where the point at which to prune the
+ error stack cannot be uniquely determined.
+ foo bar
+"}
+ {argument that contains non-ASCII character, \u20ac, and which is of such great length that it will be longer than 150 bytes so it will be truncated by the Tcl C library}
+ }] { ;# emacs needs -> "
+
+ test init-4.$count.0 {::errorInfo produced by [unknown]} -setup {
+ auto_reset
+ } -body {
+ catch {parray a b $arg}
+ set first $::errorInfo
+ catch {parray a b $arg}
+ list $first $::errorInfo
+ } -match pairwise -result equal
+ test init-4.$count.1 {::errorInfo produced by [unknown]} -setup {
+ auto_reset
+ } -body {
+ namespace eval junk [list array set $arg [list 1 2 3 4]]
+ trace variable ::junk::$arg r \
+ "[list error [subst {Variable \"$arg\" is write-only}]] ;# "
+ catch {parray ::junk::$arg}
+ set first $::errorInfo
+ catch {parray ::junk::$arg}
+ list $first $::errorInfo
+ } -match pairwise -result equal
+
+ incr count
+}
+
+test init-5.0 {return options passed through ::unknown} -setup {
+ catch {rename xxx {}}
+ set ::auto_index(::xxx) {proc ::xxx {} {
+ return -code error -level 2 xxx
+ }}
+} -body {
+ set code [catch {::xxx} foo bar]
+ set code2 [catch {::xxx} foo2 bar2]
+ list $code $foo $bar $code2 $foo2 $bar2
+} -cleanup {
+ unset ::auto_index(::xxx)
+} -match glob -result {2 xxx {-errorcode NONE -code 1 -level 1} 2 xxx {-code 1 -level 1 -errorcode NONE}}
+
+cleanupTests
+} ;# End of [interp eval $testInterp]
+
+# cleanup
+interp delete $testInterp
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/interp.test b/library/msgcat/tests/interp.test
new file mode 100644
index 0000000..ab91f77
--- /dev/null
+++ b/library/msgcat/tests/interp.test
@@ -0,0 +1,3630 @@
+# This file tests the multiple interpreter facility of Tcl
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1995-1996 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2.1
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testinterpdelete [llength [info commands testinterpdelete]]
+
+set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempfile tcl:file:type tcl:file:volumes tcl:file:writable unload}
+
+foreach i [interp slaves] {
+ interp delete $i
+}
+
+# Part 0: Check out options for interp command
+test interp-1.1 {options for interp command} -returnCodes error -body {
+ interp
+} -result {wrong # args: should be "interp cmd ?arg ...?"}
+test interp-1.2 {options for interp command} -returnCodes error -body {
+ interp frobox
+} -result {bad option "frobox": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
+test interp-1.3 {options for interp command} {
+ interp delete
+} ""
+test interp-1.4 {options for interp command} -returnCodes error -body {
+ interp delete foo bar
+} -result {could not find interpreter "foo"}
+test interp-1.5 {options for interp command} -returnCodes error -body {
+ interp exists foo bar
+} -result {wrong # args: should be "interp exists ?path?"}
+#
+# test interp-0.6 was removed
+#
+test interp-1.6 {options for interp command} -returnCodes error -body {
+ interp slaves foo bar zop
+} -result {wrong # args: should be "interp slaves ?path?"}
+test interp-1.7 {options for interp command} -returnCodes error -body {
+ interp hello
+} -result {bad option "hello": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
+test interp-1.8 {options for interp command} -returnCodes error -body {
+ interp -froboz
+} -result {bad option "-froboz": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
+test interp-1.9 {options for interp command} -returnCodes error -body {
+ interp -froboz -safe
+} -result {bad option "-froboz": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
+test interp-1.10 {options for interp command} -returnCodes error -body {
+ interp target
+} -result {wrong # args: should be "interp target path alias"}
+
+# Part 1: Basic interpreter creation tests:
+test interp-2.1 {basic interpreter creation} {
+ interp create a
+} a
+test interp-2.2 {basic interpreter creation} {
+ catch {interp create}
+} 0
+test interp-2.3 {basic interpreter creation} {
+ catch {interp create -safe}
+} 0
+test interp-2.4 {basic interpreter creation} {
+ list [catch {interp create a} msg] $msg
+} {1 {interpreter named "a" already exists, cannot create}}
+test interp-2.5 {basic interpreter creation} {
+ interp create b -safe
+} b
+test interp-2.6 {basic interpreter creation} {
+ interp create d -safe
+} d
+test interp-2.7 {basic interpreter creation} {
+ list [catch {interp create -froboz} msg] $msg
+} {1 {bad option "-froboz": must be -safe or --}}
+test interp-2.8 {basic interpreter creation} {
+ interp create -- -froboz
+} -froboz
+test interp-2.9 {basic interpreter creation} {
+ interp create -safe -- -froboz1
+} -froboz1
+test interp-2.10 {basic interpreter creation} {
+ interp create {a x1}
+ interp create {a x2}
+ interp create {a x3} -safe
+} {a x3}
+test interp-2.11 {anonymous interps vs existing procs} {
+ set x [interp create]
+ regexp "interp(\[0-9]+)" $x dummy thenum
+ interp delete $x
+ proc interp$thenum {} {}
+ set x [interp create]
+ regexp "interp(\[0-9]+)" $x dummy anothernum
+ expr $anothernum > $thenum
+} 1
+test interp-2.12 {anonymous interps vs existing procs} {
+ set x [interp create -safe]
+ regexp "interp(\[0-9]+)" $x dummy thenum
+ interp delete $x
+ proc interp$thenum {} {}
+ set x [interp create -safe]
+ regexp "interp(\[0-9]+)" $x dummy anothernum
+ expr $anothernum - $thenum
+} 1
+test interp-2.13 {correct default when no $path arg is given} -body {
+ interp create --
+} -match regexp -result {interp[0-9]+}
+
+foreach i [interp slaves] {
+ interp delete $i
+}
+
+# Part 2: Testing "interp slaves" and "interp exists"
+test interp-3.1 {testing interp exists and interp slaves} {
+ interp slaves
+} ""
+test interp-3.2 {testing interp exists and interp slaves} {
+ interp create a
+ interp exists a
+} 1
+test interp-3.3 {testing interp exists and interp slaves} {
+ interp exists nonexistent
+} 0
+test interp-3.4 {testing interp exists and interp slaves} -body {
+ interp slaves a b c
+} -returnCodes error -result {wrong # args: should be "interp slaves ?path?"}
+test interp-3.5 {testing interp exists and interp slaves} -body {
+ interp exists a b c
+} -returnCodes error -result {wrong # args: should be "interp exists ?path?"}
+test interp-3.6 {testing interp exists and interp slaves} {
+ interp exists
+} 1
+test interp-3.7 {testing interp exists and interp slaves} {
+ interp slaves
+} a
+test interp-3.8 {testing interp exists and interp slaves} -body {
+ interp slaves a b c
+} -returnCodes error -result {wrong # args: should be "interp slaves ?path?"}
+test interp-3.9 {testing interp exists and interp slaves} {
+ interp create {a a2} -safe
+ expr {"a2" in [interp slaves a]}
+} 1
+test interp-3.10 {testing interp exists and interp slaves} {
+ interp exists {a a2}
+} 1
+
+# Part 3: Testing "interp delete"
+test interp-3.11 {testing interp delete} {
+ interp delete
+} ""
+test interp-4.1 {testing interp delete} {
+ catch {interp create a}
+ interp delete a
+} ""
+test interp-4.2 {testing interp delete} -returnCodes error -body {
+ interp delete nonexistent
+} -result {could not find interpreter "nonexistent"}
+test interp-4.3 {testing interp delete} -returnCodes error -body {
+ interp delete x y z
+} -result {could not find interpreter "x"}
+test interp-4.4 {testing interp delete} {
+ interp delete
+} ""
+test interp-4.5 {testing interp delete} {
+ interp create a
+ interp create {a x1}
+ interp delete {a x1}
+ expr {"x1" in [interp slaves a]}
+} 0
+test interp-4.6 {testing interp delete} {
+ interp create c1
+ interp create c2
+ interp create c3
+ interp delete c1 c2 c3
+} ""
+test interp-4.7 {testing interp delete} -returnCodes error -body {
+ interp create c1
+ interp create c2
+ interp delete c1 c2 c3
+} -result {could not find interpreter "c3"}
+test interp-4.8 {testing interp delete} -returnCodes error -body {
+ interp delete {}
+} -result {cannot delete the current interpreter}
+
+foreach i [interp slaves] {
+ interp delete $i
+}
+
+# Part 4: Consistency checking - all nondeleted interpreters should be
+# there:
+test interp-5.1 {testing consistency} {
+ interp slaves
+} ""
+test interp-5.2 {testing consistency} {
+ interp exists a
+} 0
+test interp-5.3 {testing consistency} {
+ interp exists nonexistent
+} 0
+
+# Recreate interpreter "a"
+interp create a
+
+# Part 5: Testing eval in interpreter object command and with interp command
+test interp-6.1 {testing eval} {
+ a eval expr 3 + 5
+} 8
+test interp-6.2 {testing eval} -returnCodes error -body {
+ a eval foo
+} -result {invalid command name "foo"}
+test interp-6.3 {testing eval} {
+ a eval {proc foo {} {expr 3 + 5}}
+ a eval foo
+} 8
+test interp-6.4 {testing eval} {
+ interp eval a foo
+} 8
+test interp-6.5 {testing eval} {
+ interp create {a x2}
+ interp eval {a x2} {proc frob {} {expr 4 * 9}}
+ interp eval {a x2} frob
+} 36
+test interp-6.6 {testing eval} -returnCodes error -body {
+ interp eval {a x2} foo
+} -result {invalid command name "foo"}
+
+# UTILITY PROCEDURE RUNNING IN MASTER INTERPRETER:
+proc in_master {args} {
+ return [list seen in master: $args]
+}
+
+# Part 6: Testing basic alias creation
+test interp-7.1 {testing basic alias creation} {
+ a alias foo in_master
+} foo
+test interp-7.2 {testing basic alias creation} {
+ a alias bar in_master a1 a2 a3
+} bar
+# Test 6.3 has been deleted.
+test interp-7.3 {testing basic alias creation} {
+ a alias foo
+} in_master
+test interp-7.4 {testing basic alias creation} {
+ a alias bar
+} {in_master a1 a2 a3}
+test interp-7.5 {testing basic alias creation} {
+ lsort [a aliases]
+} {bar foo}
+test interp-7.6 {testing basic aliases arg checking} -returnCodes error -body {
+ a aliases too many args
+} -result {wrong # args: should be "a aliases"}
+
+# Part 7: testing basic alias invocation
+test interp-8.1 {testing basic alias invocation} {
+ catch {interp create a}
+ a alias foo in_master
+ a eval foo s1 s2 s3
+} {seen in master: {s1 s2 s3}}
+test interp-8.2 {testing basic alias invocation} {
+ catch {interp create a}
+ a alias bar in_master a1 a2 a3
+ a eval bar s1 s2 s3
+} {seen in master: {a1 a2 a3 s1 s2 s3}}
+test interp-8.3 {testing basic alias invocation} -returnCodes error -body {
+ catch {interp create a}
+ a alias
+} -result {wrong # args: should be "a alias aliasName ?targetName? ?arg ...?"}
+
+# Part 8: Testing aliases for non-existent or hidden targets
+test interp-9.1 {testing aliases for non-existent targets} {
+ catch {interp create a}
+ a alias zop nonexistent-command-in-master
+ list [catch {a eval zop} msg] $msg
+} {1 {invalid command name "nonexistent-command-in-master"}}
+test interp-9.2 {testing aliases for non-existent targets} {
+ catch {interp create a}
+ a alias zop nonexistent-command-in-master
+ proc nonexistent-command-in-master {} {return i_exist!}
+ a eval zop
+} i_exist!
+test interp-9.3 {testing aliases for hidden commands} {
+ catch {interp create a}
+ a eval {proc p {} {return ENTER_A}}
+ interp alias {} p a p
+ set res {}
+ lappend res [list [catch p msg] $msg]
+ interp hide a p
+ lappend res [list [catch p msg] $msg]
+ rename p {}
+ interp delete a
+ set res
+ } {{0 ENTER_A} {1 {invalid command name "p"}}}
+test interp-9.4 {testing aliases and namespace commands} {
+ proc p {} {return GLOBAL}
+ namespace eval tst {
+ proc p {} {return NAMESPACE}
+ }
+ interp alias {} a {} p
+ set res [a]
+ lappend res [namespace eval tst a]
+ rename p {}
+ rename a {}
+ namespace delete tst
+ set res
+ } {GLOBAL GLOBAL}
+
+if {[info command nonexistent-command-in-master] != ""} {
+ rename nonexistent-command-in-master {}
+}
+
+# Part 9: Aliasing between interpreters
+test interp-10.1 {testing aliasing between interpreters} {
+ catch {interp delete a}
+ catch {interp delete b}
+ interp create a
+ interp create b
+ interp alias a a_alias b b_alias 1 2 3
+} a_alias
+test interp-10.2 {testing aliasing between interpreters} {
+ catch {interp delete a}
+ catch {interp delete b}
+ interp create a
+ interp create b
+ b eval {proc b_alias {args} {return [list got $args]}}
+ interp alias a a_alias b b_alias 1 2 3
+ a eval a_alias a b c
+} {got {1 2 3 a b c}}
+test interp-10.3 {testing aliasing between interpreters} {
+ catch {interp delete a}
+ catch {interp delete b}
+ interp create a
+ interp create b
+ interp alias a a_alias b b_alias 1 2 3
+ list [catch {a eval a_alias a b c} msg] $msg
+} {1 {invalid command name "b_alias"}}
+test interp-10.4 {testing aliasing between interpreters} {
+ catch {interp delete a}
+ interp create a
+ a alias a_alias puts
+ a aliases
+} a_alias
+test interp-10.5 {testing aliasing between interpreters} {
+ catch {interp delete a}
+ catch {interp delete b}
+ interp create a
+ interp create b
+ a alias a_alias puts
+ interp alias a a_del b b_del
+ interp delete b
+ a aliases
+} a_alias
+test interp-10.6 {testing aliasing between interpreters} {
+ catch {interp delete a}
+ catch {interp delete b}
+ interp create a
+ interp create b
+ interp alias a a_command b b_command a1 a2 a3
+ b alias b_command in_master b1 b2 b3
+ a eval a_command m1 m2 m3
+} {seen in master: {b1 b2 b3 a1 a2 a3 m1 m2 m3}}
+test interp-10.7 {testing aliases between interpreters} {
+ catch {interp delete a}
+ interp create a
+ interp alias "" foo a zoppo
+ a eval {proc zoppo {x} {list $x $x $x}}
+ set x [foo 33]
+ a eval {rename zoppo {}}
+ interp alias "" foo a {}
+ return $x
+} {33 33 33}
+
+# Part 10: Testing "interp target"
+test interp-11.1 {testing interp target} {
+ list [catch {interp target} msg] $msg
+} {1 {wrong # args: should be "interp target path alias"}}
+test interp-11.2 {testing interp target} {
+ list [catch {interp target nosuchinterpreter foo} msg] $msg
+} {1 {could not find interpreter "nosuchinterpreter"}}
+test interp-11.3 {testing interp target} {
+ catch {interp delete a}
+ interp create a
+ a alias boo no_command
+ interp target a boo
+} ""
+test interp-11.4 {testing interp target} {
+ catch {interp delete x1}
+ interp create x1
+ x1 eval interp create x2
+ x1 eval x2 eval interp create x3
+ catch {interp delete y1}
+ interp create y1
+ y1 eval interp create y2
+ y1 eval y2 eval interp create y3
+ interp alias {x1 x2 x3} xcommand {y1 y2 y3} ycommand
+ interp target {x1 x2 x3} xcommand
+} {y1 y2 y3}
+test interp-11.5 {testing interp target} {
+ catch {interp delete x1}
+ interp create x1
+ interp create {x1 x2}
+ interp create {x1 x2 x3}
+ catch {interp delete y1}
+ interp create y1
+ interp create {y1 y2}
+ interp create {y1 y2 y3}
+ interp alias {x1 x2 x3} xcommand {y1 y2 y3} ycommand
+ list [catch {x1 eval {interp target {x2 x3} xcommand}} msg] $msg
+} {1 {target interpreter for alias "xcommand" in path "x2 x3" is not my descendant}}
+test interp-11.6 {testing interp target} {
+ foreach a [interp aliases] {
+ rename $a {}
+ }
+ list [catch {interp target {} foo} msg] $msg
+} {1 {alias "foo" in path "" not found}}
+test interp-11.7 {testing interp target} {
+ catch {interp delete a}
+ interp create a
+ list [catch {interp target a foo} msg] $msg
+} {1 {alias "foo" in path "a" not found}}
+
+# Part 11: testing "interp issafe"
+test interp-12.1 {testing interp issafe} {
+ interp issafe
+} 0
+test interp-12.2 {testing interp issafe} {
+ catch {interp delete a}
+ interp create a
+ interp issafe a
+} 0
+test interp-12.3 {testing interp issafe} {
+ catch {interp delete a}
+ interp create a
+ interp create {a x3} -safe
+ interp issafe {a x3}
+} 1
+test interp-12.4 {testing interp issafe} {
+ catch {interp delete a}
+ interp create a
+ interp create {a x3} -safe
+ interp create {a x3 foo}
+ interp issafe {a x3 foo}
+} 1
+
+# Part 12: testing interpreter object command "issafe" sub-command
+test interp-13.1 {testing foo issafe} {
+ catch {interp delete a}
+ interp create a
+ a issafe
+} 0
+test interp-13.2 {testing foo issafe} {
+ catch {interp delete a}
+ interp create a
+ interp create {a x3} -safe
+ a eval x3 issafe
+} 1
+test interp-13.3 {testing foo issafe} {
+ catch {interp delete a}
+ interp create a
+ interp create {a x3} -safe
+ interp create {a x3 foo}
+ a eval x3 eval foo issafe
+} 1
+test interp-13.4 {testing issafe arg checking} {
+ catch {interp create a}
+ list [catch {a issafe too many args} msg] $msg
+} {1 {wrong # args: should be "a issafe"}}
+
+# part 14: testing interp aliases
+test interp-14.1 {testing interp aliases} {
+ interp aliases
+} ""
+test interp-14.2 {testing interp aliases} {
+ catch {interp delete a}
+ interp create a
+ a alias a1 puts
+ a alias a2 puts
+ a alias a3 puts
+ lsort [interp aliases a]
+} {a1 a2 a3}
+test interp-14.3 {testing interp aliases} {
+ catch {interp delete a}
+ interp create a
+ interp create {a x3}
+ interp alias {a x3} froboz "" puts
+ interp aliases {a x3}
+} froboz
+test interp-14.4 {testing interp alias - alias over master} {
+ # SF Bug 641195
+ catch {interp delete a}
+ interp create a
+ list [catch {interp alias "" a a eval} msg] $msg [info commands a]
+} {1 {cannot define or rename alias "a": interpreter deleted} {}}
+test interp-14.5 {testing interp-alias: wrong # args} -body {
+ proc setx x {set x}
+ interp alias {} a {} setx
+ catch {a 1 2}
+ set ::errorInfo
+} -cleanup {
+ rename setx {}
+ rename a {}
+} -result {wrong # args: should be "a x"
+ while executing
+"a 1 2"}
+test interp-14.6 {testing interp-alias: wrong # args} -setup {
+ proc setx x {set x}
+ catch {interp delete a}
+ interp create a
+} -body {
+ interp alias a a {} setx
+ catch {a eval a 1 2}
+ set ::errorInfo
+} -cleanup {
+ rename setx {}
+ interp delete a
+} -result {wrong # args: should be "a x"
+ invoked from within
+"a 1 2"
+ invoked from within
+"a eval a 1 2"}
+test interp-14.7 {testing interp-alias: wrong # args} -setup {
+ proc setx x {set x}
+ catch {interp delete a}
+ interp create a
+} -body {
+ interp alias a a {} setx
+ a eval {
+ catch {a 1 2}
+ set ::errorInfo
+ }
+} -cleanup {
+ rename setx {}
+ interp delete a
+} -result {wrong # args: should be "a x"
+ invoked from within
+"a 1 2"}
+test interp-14.8 {testing interp-alias: error messages} -body {
+ proc setx x {return -code error x}
+ interp alias {} a {} setx
+ catch {a 1}
+ set ::errorInfo
+} -cleanup {
+ rename setx {}
+ rename a {}
+} -result {x
+ while executing
+"a 1"}
+test interp-14.9 {testing interp-alias: error messages} -setup {
+ proc setx x {return -code error x}
+ catch {interp delete a}
+ interp create a
+} -body {
+ interp alias a a {} setx
+ catch {a eval a 1}
+ set ::errorInfo
+} -cleanup {
+ rename setx {}
+ interp delete a
+} -result {x
+ invoked from within
+"a 1"
+ invoked from within
+"a eval a 1"}
+test interp-14.10 {testing interp-alias: error messages} -setup {
+ proc setx x {return -code error x}
+ catch {interp delete a}
+ interp create a
+} -body {
+ interp alias a a {} setx
+ a eval {
+ catch {a 1}
+ set ::errorInfo
+ }
+} -cleanup {
+ rename setx {}
+ interp delete a
+} -result {x
+ invoked from within
+"a 1"}
+
+# part 15: testing file sharing
+test interp-15.1 {testing file sharing} {
+ catch {interp delete z}
+ interp create z
+ z eval close stdout
+ list [catch {z eval puts hello} msg] $msg
+} {1 {can not find channel named "stdout"}}
+test interp-15.2 {testing file sharing} -body {
+ catch {interp delete z}
+ interp create z
+ set f [open [makeFile {} file-15.2] w]
+ interp share "" $f z
+ z eval puts $f hello
+ z eval close $f
+ close $f
+} -cleanup {
+ removeFile file-15.2
+} -result ""
+test interp-15.3 {testing file sharing} {
+ catch {interp delete xsafe}
+ interp create xsafe -safe
+ list [catch {xsafe eval puts hello} msg] $msg
+} {1 {can not find channel named "stdout"}}
+test interp-15.4 {testing file sharing} -body {
+ catch {interp delete xsafe}
+ interp create xsafe -safe
+ set f [open [makeFile {} file-15.4] w]
+ interp share "" $f xsafe
+ xsafe eval puts $f hello
+ xsafe eval close $f
+ close $f
+} -cleanup {
+ removeFile file-15.4
+} -result ""
+test interp-15.5 {testing file sharing} {
+ catch {interp delete xsafe}
+ interp create xsafe -safe
+ interp share "" stdout xsafe
+ list [catch {xsafe eval gets stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test interp-15.6 {testing file sharing} -body {
+ catch {interp delete xsafe}
+ interp create xsafe -safe
+ set f [open [makeFile {} file-15.6] w]
+ interp share "" $f xsafe
+ set x [list [catch [list xsafe eval gets $f] msg] $msg]
+ xsafe eval close $f
+ close $f
+ string compare [string tolower $x] \
+ [list 1 [format "channel \"%s\" wasn't opened for reading" $f]]
+} -cleanup {
+ removeFile file-15.6
+} -result 0
+test interp-15.7 {testing file transferring} -body {
+ catch {interp delete xsafe}
+ interp create xsafe -safe
+ set f [open [makeFile {} file-15.7] w]
+ interp transfer "" $f xsafe
+ xsafe eval puts $f hello
+ xsafe eval close $f
+} -cleanup {
+ removeFile file-15.7
+} -result ""
+test interp-15.8 {testing file transferring} -body {
+ catch {interp delete xsafe}
+ interp create xsafe -safe
+ set f [open [makeFile {} file-15.8] w]
+ interp transfer "" $f xsafe
+ xsafe eval close $f
+ set x [list [catch {close $f} msg] $msg]
+ string compare [string tolower $x] \
+ [list 1 [format "can not find channel named \"%s\"" $f]]
+} -cleanup {
+ removeFile file-15.8
+} -result 0
+
+#
+# Torture tests for interpreter deletion order
+#
+proc kill {} {interp delete xxx}
+test interp-16.0 {testing deletion order} {
+ catch {interp delete xxx}
+ interp create xxx
+ xxx alias kill kill
+ list [catch {xxx eval kill} msg] $msg
+} {0 {}}
+test interp-16.1 {testing deletion order} {
+ catch {interp delete xxx}
+ interp create xxx
+ interp create {xxx yyy}
+ interp alias {xxx yyy} kill "" kill
+ list [catch {interp eval {xxx yyy} kill} msg] $msg
+} {0 {}}
+test interp-16.2 {testing deletion order} {
+ catch {interp delete xxx}
+ interp create xxx
+ interp create {xxx yyy}
+ interp alias {xxx yyy} kill "" kill
+ list [catch {xxx eval yyy eval kill} msg] $msg
+} {0 {}}
+test interp-16.3 {testing deletion order} {
+ catch {interp delete xxx}
+ interp create xxx
+ interp create ddd
+ xxx alias kill kill
+ interp alias ddd kill xxx kill
+ set x [ddd eval kill]
+ interp delete ddd
+ set x
+} ""
+test interp-16.4 {testing deletion order} {
+ catch {interp delete xxx}
+ interp create xxx
+ interp create {xxx yyy}
+ interp alias {xxx yyy} kill "" kill
+ interp create ddd
+ interp alias ddd kill {xxx yyy} kill
+ set x [ddd eval kill]
+ interp delete ddd
+ set x
+} ""
+test interp-16.5 {testing deletion order, bgerror} {
+ catch {interp delete xxx}
+ interp create xxx
+ xxx eval {proc bgerror {args} {exit}}
+ xxx alias exit kill xxx
+ proc kill {i} {interp delete $i}
+ xxx eval after 100 expr a + b
+ after 200
+ update
+ interp exists xxx
+} 0
+
+#
+# Alias loop prevention testing.
+#
+
+test interp-17.1 {alias loop prevention} {
+ list [catch {interp alias {} a {} a} msg] $msg
+} {1 {cannot define or rename alias "a": would create a loop}}
+test interp-17.2 {alias loop prevention} {
+ catch {interp delete x}
+ interp create x
+ x alias a loop
+ list [catch {interp alias {} loop x a} msg] $msg
+} {1 {cannot define or rename alias "loop": would create a loop}}
+test interp-17.3 {alias loop prevention} {
+ catch {interp delete x}
+ interp create x
+ interp alias x a x b
+ list [catch {interp alias x b x a} msg] $msg
+} {1 {cannot define or rename alias "b": would create a loop}}
+test interp-17.4 {alias loop prevention} {
+ catch {interp delete x}
+ interp create x
+ interp alias x b x a
+ list [catch {x eval rename b a} msg] $msg
+} {1 {cannot define or rename alias "a": would create a loop}}
+test interp-17.5 {alias loop prevention} {
+ catch {interp delete x}
+ interp create x
+ x alias z l1
+ interp alias {} l2 x z
+ list [catch {rename l2 l1} msg] $msg
+} {1 {cannot define or rename alias "l1": would create a loop}}
+test interp-17.6 {alias loop prevention} {
+ catch {interp delete x}
+ interp create x
+ interp alias x a x b
+ x eval rename a c
+ list [catch {x eval rename c b} msg] $msg
+} {1 {cannot define or rename alias "b": would create a loop}}
+
+#
+# Test robustness of Tcl_DeleteInterp when applied to a slave interpreter.
+# If there are bugs in the implementation these tests are likely to expose
+# the bugs as a core dump.
+#
+
+test interp-18.1 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+ list [catch {testinterpdelete} msg] $msg
+} {1 {wrong # args: should be "testinterpdelete path"}}
+test interp-18.2 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+ catch {interp delete a}
+ interp create a
+ testinterpdelete a
+} ""
+test interp-18.3 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+ catch {interp delete a}
+ interp create a
+ interp create {a b}
+ testinterpdelete {a b}
+} ""
+test interp-18.4 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+ catch {interp delete a}
+ interp create a
+ interp create {a b}
+ testinterpdelete a
+} ""
+test interp-18.5 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+ catch {interp delete a}
+ interp create a
+ interp create {a b}
+ interp alias {a b} dodel {} dodel
+ proc dodel {x} {testinterpdelete $x}
+ list [catch {interp eval {a b} {dodel {a b}}} msg] $msg
+} {0 {}}
+test interp-18.6 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+ catch {interp delete a}
+ interp create a
+ interp create {a b}
+ interp alias {a b} dodel {} dodel
+ proc dodel {x} {testinterpdelete $x}
+ list [catch {interp eval {a b} {dodel a}} msg] $msg
+} {0 {}}
+test interp-18.7 {eval in deleted interp} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ proc dodel {} {
+ delme
+ dosomething else
+ }
+ proc dosomething args {
+ puts "I should not have been called!!"
+ }
+ }
+ a alias delme dela
+ proc dela {} {interp delete a}
+ list [catch {a eval dodel} msg] $msg
+} {1 {attempt to call eval in deleted interpreter}}
+test interp-18.8 {eval in deleted interp} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ interp create b
+ b eval {
+ proc dodel {} {
+ dela
+ }
+ }
+ proc foo {} {
+ b eval dela
+ dosomething else
+ }
+ proc dosomething args {
+ puts "I should not have been called!!"
+ }
+ }
+ interp alias {a b} dela {} dela
+ proc dela {} {interp delete a}
+ list [catch {a eval foo} msg] $msg
+} {1 {attempt to call eval in deleted interpreter}}
+test interp-18.9 {eval in deleted interp, bug 495830} {
+ interp create tst
+ interp alias tst suicide {} interp delete tst
+ list [catch {tst eval {suicide; set a 5}} msg] $msg
+} {1 {attempt to call eval in deleted interpreter}}
+test interp-18.10 {eval in deleted interp, bug 495830} {
+ interp create tst
+ interp alias tst suicide {} interp delete tst
+ list [catch {tst eval {set set set; suicide; $set a 5}} msg] $msg
+} {1 {attempt to call eval in deleted interpreter}}
+
+# Test alias deletion
+
+test interp-19.1 {alias deletion} {
+ catch {interp delete a}
+ interp create a
+ interp alias a foo a bar
+ set s [interp alias a foo {}]
+ interp delete a
+ set s
+} {}
+test interp-19.2 {alias deletion} {
+ catch {interp delete a}
+ interp create a
+ catch {interp alias a foo {}} msg
+ interp delete a
+ set msg
+} {alias "foo" not found}
+test interp-19.3 {alias deletion} {
+ catch {interp delete a}
+ interp create a
+ interp alias a foo a bar
+ interp eval a {rename foo zop}
+ interp alias a foo a zop
+ catch {interp eval a foo} msg
+ interp delete a
+ set msg
+} {invalid command name "bar"}
+test interp-19.4 {alias deletion} {
+ catch {interp delete a}
+ interp create a
+ interp alias a foo a bar
+ interp eval a {rename foo zop}
+ catch {interp eval a foo} msg
+ interp delete a
+ set msg
+} {invalid command name "foo"}
+test interp-19.5 {alias deletion} {
+ catch {interp delete a}
+ interp create a
+ interp eval a {proc bar {} {return 1}}
+ interp alias a foo a bar
+ interp eval a {rename foo zop}
+ catch {interp eval a zop} msg
+ interp delete a
+ set msg
+} 1
+test interp-19.6 {alias deletion} {
+ catch {interp delete a}
+ interp create a
+ interp alias a foo a bar
+ interp eval a {rename foo zop}
+ interp alias a foo a zop
+ set s [interp aliases a]
+ interp delete a
+ set s
+} {::foo foo}
+test interp-19.7 {alias deletion, renaming} {
+ catch {interp delete a}
+ interp create a
+ interp alias a foo a bar
+ interp eval a rename foo blotz
+ interp alias a foo {}
+ set s [interp aliases a]
+ interp delete a
+ set s
+} {}
+test interp-19.8 {alias deletion, renaming} {
+ catch {interp delete a}
+ interp create a
+ interp alias a foo a bar
+ interp eval a rename foo blotz
+ set l ""
+ lappend l [interp aliases a]
+ interp alias a foo {}
+ lappend l [interp aliases a]
+ interp delete a
+ set l
+} {foo {}}
+test interp-19.9 {alias deletion, renaming} {
+ catch {interp delete a}
+ interp create a
+ interp alias a foo a bar
+ interp eval a rename foo blotz
+ interp eval a {proc foo {} {expr 34 * 34}}
+ interp alias a foo {}
+ set l [interp eval a foo]
+ interp delete a
+ set l
+} 1156
+
+test interp-20.1 {interp hide, interp expose and interp invokehidden} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ $a eval {proc foo {} {}}
+ $a hide foo
+ catch {$a eval foo something} msg
+ interp delete $a
+ set msg
+} {invalid command name "foo"}
+test interp-20.2 {interp hide, interp expose and interp invokehidden} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ $a hide list
+ set l ""
+ lappend l [catch {$a eval {list 1 2 3}} msg] $msg
+ $a expose list
+ lappend l [catch {$a eval {list 1 2 3}} msg] $msg
+ interp delete $a
+ set l
+} {1 {invalid command name "list"} 0 {1 2 3}}
+test interp-20.3 {interp hide, interp expose and interp invokehidden} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ $a hide list
+ set l ""
+ lappend l [catch { $a eval {list 1 2 3} } msg] $msg
+ lappend l [catch { $a invokehidden list 1 2 3 } msg] $msg
+ $a expose list
+ lappend l [catch { $a eval {list 1 2 3} } msg] $msg
+ interp delete $a
+ set l
+} {1 {invalid command name "list"} 0 {1 2 3} 0 {1 2 3}}
+test interp-20.4 {interp hide, interp expose and interp invokehidden -- passing {}} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ $a hide list
+ set l ""
+ lappend l [catch { $a eval {list 1 2 3} } msg] $msg
+ lappend l [catch { $a invokehidden list {"" 1 2 3} } msg] $msg
+ $a expose list
+ lappend l [catch { $a eval {list 1 2 3} } msg] $msg
+ interp delete $a
+ set l
+} {1 {invalid command name "list"} 0 {{"" 1 2 3}} 0 {1 2 3}}
+test interp-20.5 {interp hide, interp expose and interp invokehidden -- passing {}} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ $a hide list
+ set l ""
+ lappend l [catch { $a eval {list 1 2 3} } msg] $msg
+ lappend l [catch { $a invokehidden list {{} 1 2 3} } msg] $msg
+ $a expose list
+ lappend l [catch { $a eval {list 1 2 3} } msg] $msg
+ interp delete $a
+ set l
+} {1 {invalid command name "list"} 0 {{{} 1 2 3}} 0 {1 2 3}}
+test interp-20.6 {interp invokehidden -- eval args} {
+ set a [interp create]
+ $a hide list
+ set l ""
+ set z 45
+ lappend l [catch { $a invokehidden list $z 1 2 3 } msg] $msg
+ $a expose list
+ lappend l [catch { $a eval list $z 1 2 3 } msg] $msg
+ interp delete $a
+ set l
+} {0 {45 1 2 3} 0 {45 1 2 3}}
+test interp-20.7 {interp invokehidden vs variable eval} {
+ set a [interp create]
+ $a hide list
+ set z 45
+ set l [list [catch {$a invokehidden list {$z a b c}} msg] $msg]
+ interp delete $a
+ set l
+} {0 {{$z a b c}}}
+test interp-20.8 {interp invokehidden vs variable eval} {
+ set a [interp create]
+ $a hide list
+ $a eval set z 89
+ set z 45
+ set l [list [catch {$a invokehidden list {$z a b c}} msg] $msg]
+ interp delete $a
+ set l
+} {0 {{$z a b c}}}
+test interp-20.9 {interp invokehidden vs variable eval} {
+ set a [interp create]
+ $a hide list
+ $a eval set z 89
+ set z 45
+ set l ""
+ lappend l [catch {$a invokehidden list $z {$z a b c}} msg] $msg
+ interp delete $a
+ set l
+} {0 {45 {$z a b c}}}
+test interp-20.10 {interp hide, interp expose and interp invokehidden} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ $a eval {proc foo {} {}}
+ interp hide $a foo
+ catch {interp eval $a foo something} msg
+ interp delete $a
+ set msg
+} {invalid command name "foo"}
+test interp-20.11 {interp hide, interp expose and interp invokehidden} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ interp hide $a list
+ set l ""
+ lappend l [catch {interp eval $a {list 1 2 3}} msg] $msg
+ interp expose $a list
+ lappend l [catch {interp eval $a {list 1 2 3}} msg] $msg
+ interp delete $a
+ set l
+} {1 {invalid command name "list"} 0 {1 2 3}}
+test interp-20.12 {interp hide, interp expose and interp invokehidden} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ interp hide $a list
+ set l ""
+ lappend l [catch {interp eval $a {list 1 2 3} } msg] $msg
+ lappend l [catch {interp invokehidden $a list 1 2 3} msg] $msg
+ interp expose $a list
+ lappend l [catch {interp eval $a {list 1 2 3} } msg] $msg
+ interp delete $a
+ set l
+} {1 {invalid command name "list"} 0 {1 2 3} 0 {1 2 3}}
+test interp-20.13 {interp hide, interp expose, interp invokehidden -- passing {}} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ interp hide $a list
+ set l ""
+ lappend l [catch {interp eval $a {list 1 2 3} } msg] $msg
+ lappend l [catch {interp invokehidden $a list {"" 1 2 3}} msg] $msg
+ interp expose $a list
+ lappend l [catch {interp eval $a {list 1 2 3} } msg] $msg
+ interp delete $a
+ set l
+} {1 {invalid command name "list"} 0 {{"" 1 2 3}} 0 {1 2 3}}
+test interp-20.14 {interp hide, interp expose, interp invokehidden -- passing {}} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ interp hide $a list
+ set l ""
+ lappend l [catch {interp eval $a {list 1 2 3} } msg] $msg
+ lappend l [catch {interp invokehidden $a list {{} 1 2 3}} msg] $msg
+ interp expose $a list
+ lappend l [catch {$a eval {list 1 2 3} } msg] $msg
+ interp delete $a
+ set l
+} {1 {invalid command name "list"} 0 {{{} 1 2 3}} 0 {1 2 3}}
+test interp-20.15 {interp invokehidden -- eval args} {
+ catch {interp delete a}
+ interp create a
+ interp hide a list
+ set l ""
+ set z 45
+ lappend l [catch {interp invokehidden a list $z 1 2 3} msg]
+ lappend l $msg
+ a expose list
+ lappend l [catch {interp eval a list $z 1 2 3} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {45 1 2 3} 0 {45 1 2 3}}
+test interp-20.16 {interp invokehidden vs variable eval} {
+ catch {interp delete a}
+ interp create a
+ interp hide a list
+ set z 45
+ set l ""
+ lappend l [catch {interp invokehidden a list {$z a b c}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {{$z a b c}}}
+test interp-20.17 {interp invokehidden vs variable eval} {
+ catch {interp delete a}
+ interp create a
+ interp hide a list
+ a eval set z 89
+ set z 45
+ set l ""
+ lappend l [catch {interp invokehidden a list {$z a b c}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {{$z a b c}}}
+test interp-20.18 {interp invokehidden vs variable eval} {
+ catch {interp delete a}
+ interp create a
+ interp hide a list
+ a eval set z 89
+ set z 45
+ set l ""
+ lappend l [catch {interp invokehidden a list $z {$z a b c}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {45 {$z a b c}}}
+test interp-20.19 {interp invokehidden vs nested commands} {
+ catch {interp delete a}
+ interp create a
+ a hide list
+ set l [a invokehidden list {[list x y z] f g h} z]
+ interp delete a
+ set l
+} {{[list x y z] f g h} z}
+test interp-20.20 {interp invokehidden vs nested commands} {
+ catch {interp delete a}
+ interp create a
+ a hide list
+ set l [interp invokehidden a list {[list x y z] f g h} z]
+ interp delete a
+ set l
+} {{[list x y z] f g h} z}
+test interp-20.21 {interp hide vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [catch {a hide list} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {}}
+test interp-20.22 {interp hide vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [catch {interp hide a list} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {}}
+test interp-20.23 {interp hide vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [catch {a eval {interp hide {} list}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {1 {permission denied: safe interpreter cannot hide commands}}
+test interp-20.24 {interp hide vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ interp create {a b}
+ set l ""
+ lappend l [catch {a eval {interp hide b list}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {1 {permission denied: safe interpreter cannot hide commands}}
+test interp-20.25 {interp hide vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ interp create {a b}
+ set l ""
+ lappend l [catch {interp hide {a b} list} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {}}
+test interp-20.26 {interp expoose vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [catch {a hide list} msg]
+ lappend l $msg
+ lappend l [catch {a expose list} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {} 0 {}}
+test interp-20.27 {interp expose vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [catch {interp hide a list} msg]
+ lappend l $msg
+ lappend l [catch {interp expose a list} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {} 0 {}}
+test interp-20.28 {interp expose vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [catch {a hide list} msg]
+ lappend l $msg
+ lappend l [catch {a eval {interp expose {} list}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {} 1 {permission denied: safe interpreter cannot expose commands}}
+test interp-20.29 {interp expose vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [catch {interp hide a list} msg]
+ lappend l $msg
+ lappend l [catch {a eval {interp expose {} list}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {} 1 {permission denied: safe interpreter cannot expose commands}}
+test interp-20.30 {interp expose vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ interp create {a b}
+ set l ""
+ lappend l [catch {interp hide {a b} list} msg]
+ lappend l $msg
+ lappend l [catch {a eval {interp expose b list}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {} 1 {permission denied: safe interpreter cannot expose commands}}
+test interp-20.31 {interp expose vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ interp create {a b}
+ set l ""
+ lappend l [catch {interp hide {a b} list} msg]
+ lappend l $msg
+ lappend l [catch {interp expose {a b} list} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {} 0 {}}
+test interp-20.32 {interp invokehidden vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ interp hide a list
+ set l ""
+ lappend l [catch {a eval {interp invokehidden {} list a b c}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {1 {not allowed to invoke hidden commands from safe interpreter}}
+test interp-20.33 {interp invokehidden vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ interp hide a list
+ set l ""
+ lappend l [catch {a eval {interp invokehidden {} list a b c}} msg]
+ lappend l $msg
+ lappend l [catch {a invokehidden list a b c} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {1 {not allowed to invoke hidden commands from safe interpreter}\
+0 {a b c}}
+test interp-20.34 {interp invokehidden vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ interp create {a b}
+ interp hide {a b} list
+ set l ""
+ lappend l [catch {a eval {interp invokehidden b list a b c}} msg]
+ lappend l $msg
+ lappend l [catch {interp invokehidden {a b} list a b c} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {1 {not allowed to invoke hidden commands from safe interpreter}\
+0 {a b c}}
+test interp-20.35 {invokehidden at local level} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ proc p1 {} {
+ set z 90
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a h1
+ }
+ set r [interp eval a p1]
+ interp delete a
+ set r
+} 91
+test interp-20.36 {invokehidden at local level} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ set z 90
+ proc p1 {} {
+ global z
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a h1
+ }
+ set r [interp eval a p1]
+ interp delete a
+ set r
+} 91
+test interp-20.37 {invokehidden at local level} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ proc p1 {} {
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a h1
+ }
+ set r [interp eval a p1]
+ interp delete a
+ set r
+} 91
+test interp-20.38 {invokehidden at global level} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ proc p1 {} {
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a -global h1
+ }
+ set r [catch {interp eval a p1} msg]
+ interp delete a
+ list $r $msg
+} {1 {can't read "z": no such variable}}
+test interp-20.39 {invokehidden at global level} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ proc p1 {} {
+ global z
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a -global h1
+ }
+ set r [catch {interp eval a p1} msg]
+ interp delete a
+ list $r $msg
+} {0 91}
+test interp-20.40 {safe, invokehidden at local level} {
+ catch {interp delete a}
+ interp create a -safe
+ a eval {
+ proc p1 {} {
+ set z 90
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a h1
+ }
+ set r [interp eval a p1]
+ interp delete a
+ set r
+} 91
+test interp-20.41 {safe, invokehidden at local level} {
+ catch {interp delete a}
+ interp create a -safe
+ a eval {
+ set z 90
+ proc p1 {} {
+ global z
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a h1
+ }
+ set r [interp eval a p1]
+ interp delete a
+ set r
+} 91
+test interp-20.42 {safe, invokehidden at local level} {
+ catch {interp delete a}
+ interp create a -safe
+ a eval {
+ proc p1 {} {
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a h1
+ }
+ set r [interp eval a p1]
+ interp delete a
+ set r
+} 91
+test interp-20.43 {invokehidden at global level} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ proc p1 {} {
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a -global h1
+ }
+ set r [catch {interp eval a p1} msg]
+ interp delete a
+ list $r $msg
+} {1 {can't read "z": no such variable}}
+test interp-20.44 {invokehidden at global level} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ proc p1 {} {
+ global z
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a -global h1
+ }
+ set r [catch {interp eval a p1} msg]
+ interp delete a
+ list $r $msg
+} {0 91}
+test interp-20.45 {interp hide vs namespaces} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ namespace eval foo {}
+ proc foo::x {} {}
+ }
+ set l [list [catch {interp hide a foo::x} msg] $msg]
+ interp delete a
+ set l
+} {1 {cannot use namespace qualifiers in hidden command token (rename)}}
+test interp-20.46 {interp hide vs namespaces} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ namespace eval foo {}
+ proc foo::x {} {}
+ }
+ set l [list [catch {interp hide a foo::x x} msg] $msg]
+ interp delete a
+ set l
+} {1 {can only hide global namespace commands (use rename then hide)}}
+test interp-20.47 {interp hide vs namespaces} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ proc x {} {}
+ }
+ set l [list [catch {interp hide a x foo::x} msg] $msg]
+ interp delete a
+ set l
+} {1 {cannot use namespace qualifiers in hidden command token (rename)}}
+test interp-20.48 {interp hide vs namespaces} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ namespace eval foo {}
+ proc foo::x {} {}
+ }
+ set l [list [catch {interp hide a foo::x bar::x} msg] $msg]
+ interp delete a
+ set l
+} {1 {cannot use namespace qualifiers in hidden command token (rename)}}
+test interp-20.49 {interp invokehidden -namespace} -setup {
+ set script [makeFile {
+ set x [namespace current]
+ } script]
+ interp create -safe slave
+} -body {
+ slave invokehidden -namespace ::foo source $script
+ slave eval {set ::foo::x}
+} -cleanup {
+ interp delete slave
+ removeFile script
+} -result ::foo
+test interp-20.50 {Bug 2486550} -setup {
+ interp create slave
+} -body {
+ slave hide coroutine
+ slave invokehidden coroutine
+} -cleanup {
+ interp delete slave
+} -returnCodes error -match glob -result *
+
+test interp-21.1 {interp hidden} {
+ interp hidden {}
+} ""
+test interp-21.2 {interp hidden} {
+ interp hidden
+} ""
+test interp-21.3 {interp hidden vs interp hide, interp expose} -setup {
+ set l ""
+} -body {
+ lappend l [interp hidden]
+ interp hide {} pwd
+ lappend l [interp hidden]
+ interp expose {} pwd
+ lappend l [interp hidden]
+} -result {{} pwd {}}
+test interp-21.4 {interp hidden} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a
+ interp hidden a
+} -cleanup {
+ interp delete a
+} -result ""
+test interp-21.5 {interp hidden} -setup {
+ catch {interp delete a}
+} -body {
+ interp create -safe a
+ lsort [interp hidden a]
+} -cleanup {
+ interp delete a
+} -result $hidden_cmds
+test interp-21.6 {interp hidden vs interp hide, interp expose} -setup {
+ catch {interp delete a}
+ set l ""
+} -body {
+ interp create a
+ lappend l [interp hidden a]
+ interp hide a pwd
+ lappend l [interp hidden a]
+ interp expose a pwd
+ lappend l [interp hidden a]
+} -cleanup {
+ interp delete a
+} -result {{} pwd {}}
+test interp-21.7 {interp hidden} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a
+ a hidden
+} -cleanup {
+ interp delete a
+} -result ""
+test interp-21.8 {interp hidden} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a -safe
+ lsort [a hidden]
+} -cleanup {
+ interp delete a
+} -result $hidden_cmds
+test interp-21.9 {interp hidden vs interp hide, interp expose} -setup {
+ catch {interp delete a}
+ set l ""
+} -body {
+ interp create a
+ lappend l [a hidden]
+ a hide pwd
+ lappend l [a hidden]
+ a expose pwd
+ lappend l [a hidden]
+} -cleanup {
+ interp delete a
+} -result {{} pwd {}}
+
+test interp-22.1 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a
+ set l ""
+ lappend l [a issafe]
+ lappend l [a marktrusted]
+ lappend l [a issafe]
+ interp delete a
+ set l
+} {0 {} 0}
+test interp-22.2 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a
+ set l ""
+ lappend l [interp issafe a]
+ lappend l [interp marktrusted a]
+ lappend l [interp issafe a]
+ interp delete a
+ set l
+} {0 {} 0}
+test interp-22.3 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [a issafe]
+ lappend l [a marktrusted]
+ lappend l [a issafe]
+ interp delete a
+ set l
+} {1 {} 0}
+test interp-22.4 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [interp issafe a]
+ lappend l [interp marktrusted a]
+ lappend l [interp issafe a]
+ interp delete a
+ set l
+} {1 {} 0}
+test interp-22.5 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a -safe
+ interp create {a b}
+ catch {a eval {interp marktrusted b}} msg
+ interp delete a
+ set msg
+} {permission denied: safe interpreter cannot mark trusted}
+test interp-22.6 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a -safe
+ interp create {a b}
+ catch {a eval {b marktrusted}} msg
+ interp delete a
+ set msg
+} {permission denied: safe interpreter cannot mark trusted}
+test interp-22.7 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [interp issafe a]
+ interp marktrusted a
+ interp create {a b}
+ lappend l [interp issafe a]
+ lappend l [interp issafe {a b}]
+ interp delete a
+ set l
+} {1 0 0}
+test interp-22.8 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [interp issafe a]
+ interp create {a b}
+ lappend l [interp issafe {a b}]
+ interp marktrusted a
+ interp create {a c}
+ lappend l [interp issafe a]
+ lappend l [interp issafe {a c}]
+ interp delete a
+ set l
+} {1 1 0 0}
+test interp-22.9 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [interp issafe a]
+ interp create {a b}
+ lappend l [interp issafe {a b}]
+ interp marktrusted {a b}
+ lappend l [interp issafe a]
+ lappend l [interp issafe {a b}]
+ interp create {a b c}
+ lappend l [interp issafe {a b c}]
+ interp delete a
+ set l
+} {1 1 1 0 0}
+
+test interp-23.1 {testing hiding vs aliases: unsafe interp} -setup {
+ catch {interp delete a}
+ set l ""
+} -body {
+ interp create a
+ lappend l [interp hidden a]
+ a alias bar bar
+ lappend l [interp aliases a] [interp hidden a]
+ a hide bar
+ lappend l [interp aliases a] [interp hidden a]
+ a alias bar {}
+ lappend l [interp aliases a] [interp hidden a]
+} -cleanup {
+ interp delete a
+} -result {{} bar {} bar bar {} {}}
+test interp-23.2 {testing hiding vs aliases: safe interp} -setup {
+ catch {interp delete a}
+ set l ""
+} -constraints {unixOrPc} -body {
+ interp create a -safe
+ lappend l [lsort [interp hidden a]]
+ a alias bar bar
+ lappend l [lsort [interp aliases a]] [lsort [interp hidden a]]
+ a hide bar
+ lappend l [lsort [interp aliases a]] [lsort [interp hidden a]]
+ a alias bar {}
+ lappend l [lsort [interp aliases a]] [lsort [interp hidden a]]
+} -cleanup {
+ interp delete a
+} -result [list $hidden_cmds {::tcl::mathfunc::max ::tcl::mathfunc::min bar clock} $hidden_cmds {::tcl::mathfunc::max ::tcl::mathfunc::min bar clock} [lsort [concat $hidden_cmds bar]] {::tcl::mathfunc::max ::tcl::mathfunc::min clock} $hidden_cmds]
+
+test interp-24.1 {result resetting on error} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a
+ interp alias a foo {} apply {args {error $args}}
+ interp eval a {
+ lappend l [catch {foo 1 2 3} msg] $msg
+ lappend l [catch {foo 3 4 5} msg] $msg
+ }
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.2 {result resetting on error} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a -safe
+ interp alias a foo {} apply {args {error $args}}
+ interp eval a {
+ lappend l [catch {foo 1 2 3} msg] $msg
+ lappend l [catch {foo 3 4 5} msg] $msg
+ }
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.3 {result resetting on error} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a
+ interp create {a b}
+ interp eval a {
+ proc foo args {error $args}
+ }
+ interp alias {a b} foo a foo
+ interp eval {a b} {
+ lappend l [catch {foo 1 2 3} msg] $msg
+ lappend l [catch {foo 3 4 5} msg] $msg
+ }
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.4 {result resetting on error} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a -safe
+ interp create {a b}
+ interp eval a {
+ proc foo args {error $args}
+ }
+ interp alias {a b} foo a foo
+ interp eval {a b} {
+ lappend l [catch {foo 1 2 3} msg]
+ lappend l $msg
+ lappend l [catch {foo 3 4 5} msg]
+ lappend l $msg
+ }
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.5 {result resetting on error} -setup {
+ catch {interp delete a}
+ catch {interp delete b}
+} -body {
+ interp create a
+ interp create b
+ interp eval a {
+ proc foo args {error $args}
+ }
+ interp alias b foo a foo
+ interp eval b {
+ lappend l [catch {foo 1 2 3} msg] $msg
+ lappend l [catch {foo 3 4 5} msg] $msg
+ }
+} -cleanup {
+ interp delete a
+ interp delete b
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.6 {result resetting on error} -setup {
+ catch {interp delete a}
+ catch {interp delete b}
+} -body {
+ interp create a -safe
+ interp create b -safe
+ interp eval a {
+ proc foo args {error $args}
+ }
+ interp alias b foo a foo
+ interp eval b {
+ lappend l [catch {foo 1 2 3} msg] $msg
+ lappend l [catch {foo 3 4 5} msg] $msg
+ }
+} -cleanup {
+ interp delete a
+ interp delete b
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.7 {result resetting on error} -setup {
+ catch {interp delete a}
+ set l {}
+} -body {
+ interp create a
+ interp eval a {
+ proc foo args {error $args}
+ }
+ lappend l [catch {interp eval a foo 1 2 3} msg] $msg
+ lappend l [catch {interp eval a foo 3 4 5} msg] $msg
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.8 {result resetting on error} -setup {
+ catch {interp delete a}
+ set l {}
+} -body {
+ interp create a -safe
+ interp eval a {
+ proc foo args {error $args}
+ }
+ lappend l [catch {interp eval a foo 1 2 3} msg] $msg
+ lappend l [catch {interp eval a foo 3 4 5} msg] $msg
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.9 {result resetting on error} -setup {
+ catch {interp delete a}
+ set l {}
+} -body {
+ interp create a
+ interp create {a b}
+ interp eval {a b} {
+ proc foo args {error $args}
+ }
+ interp eval a {
+ proc foo args {
+ eval interp eval b foo $args
+ }
+ }
+ lappend l [catch {interp eval a foo 1 2 3} msg] $msg
+ lappend l [catch {interp eval a foo 3 4 5} msg] $msg
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.10 {result resetting on error} -setup {
+ catch {interp delete a}
+ set l {}
+} -body {
+ interp create a -safe
+ interp create {a b}
+ interp eval {a b} {
+ proc foo args {error $args}
+ }
+ interp eval a {
+ proc foo args {
+ eval interp eval b foo $args
+ }
+ }
+ lappend l [catch {interp eval a foo 1 2 3} msg] $msg
+ lappend l [catch {interp eval a foo 3 4 5} msg] $msg
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.11 {result resetting on error} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a
+ interp create {a b}
+ interp eval {a b} {
+ proc foo args {error $args}
+ }
+ interp eval a {
+ proc foo args {
+ lappend l [catch {eval interp eval b foo $args} msg] $msg
+ lappend l [catch {eval interp eval b foo $args} msg] $msg
+ }
+ }
+ interp eval a foo 1 2 3
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {1 2 3}}
+test interp-24.12 {result resetting on error} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a -safe
+ interp create {a b}
+ interp eval {a b} {
+ proc foo args {error $args}
+ }
+ interp eval a {
+ proc foo args {
+ lappend l [catch {eval interp eval b foo $args} msg] $msg
+ lappend l [catch {eval interp eval b foo $args} msg] $msg
+ }
+ }
+ interp eval a foo 1 2 3
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {1 2 3}}
+
+test interp-25.1 {testing aliasing of string commands} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a
+ a alias exec foo ;# Relies on exec being a string command!
+ interp delete a
+} -result ""
+
+#
+# Interps result transmission
+#
+
+test interp-26.1 {result code transmission : interp eval direct} {
+ # Test that all the possibles error codes from Tcl get passed up
+ # from the slave interp's context to the master, even though the
+ # slave nominally thinks the command is running at the root level.
+ catch {interp delete a}
+ interp create a
+ set res {}
+ # use a for so if a return -code break 'escapes' we would notice
+ for {set code -1} {$code<=5} {incr code} {
+ lappend res [catch {interp eval a return -code $code} msg]
+ }
+ interp delete a
+ set res
+} {-1 0 1 2 3 4 5}
+test interp-26.2 {result code transmission : interp eval indirect} {
+ # retcode == 2 == return is special
+ catch {interp delete a}
+ interp create a
+ interp eval a {proc retcode {code} {return -code $code ret$code}}
+ set res {}
+ # use a for so if a return -code break 'escapes' we would notice
+ for {set code -1} {$code<=5} {incr code} {
+ lappend res [catch {interp eval a retcode $code} msg] $msg
+ }
+ interp delete a
+ set res
+} {-1 ret-1 0 ret0 1 ret1 0 ret2 3 ret3 4 ret4 5 ret5}
+test interp-26.3 {result code transmission : aliases} {
+ # Test that all the possibles error codes from Tcl get passed up from the
+ # slave interp's context to the master, even though the slave nominally
+ # thinks the command is running at the root level.
+ catch {interp delete a}
+ interp create a
+ set res {}
+ proc MyTestAlias {code} {
+ return -code $code ret$code
+ }
+ interp alias a Test {} MyTestAlias
+ for {set code -1} {$code<=5} {incr code} {
+ lappend res [interp eval a [list catch [list Test $code] msg]]
+ }
+ interp delete a
+ set res
+} {-1 0 1 2 3 4 5}
+test interp-26.4 {result code transmission: invoke hidden direct--bug 1637} \
+ {knownBug} {
+ # The known bug is that code 2 is returned, not the -code argument
+ catch {interp delete a}
+ interp create a
+ set res {}
+ interp hide a return
+ for {set code -1} {$code<=5} {incr code} {
+ lappend res [catch {interp invokehidden a return -code $code ret$code}]
+ }
+ interp delete a
+ set res
+} {-1 0 1 2 3 4 5}
+test interp-26.5 {result code transmission: invoke hidden indirect--bug 1637} -setup {
+ catch {interp delete a}
+ interp create a
+} -body {
+ # The known bug is that the break and continue should raise errors that
+ # they are used outside a loop.
+ set res {}
+ interp eval a {proc retcode {code} {return -code $code ret$code}}
+ interp hide a retcode
+ for {set code -1} {$code<=5} {incr code} {
+ lappend res [catch {interp invokehidden a retcode $code} msg] $msg
+ }
+ return $res
+} -cleanup {
+ interp delete a
+} -result {-1 ret-1 0 ret0 1 ret1 2 ret2 3 ret3 4 ret4 5 ret5}
+test interp-26.6 {result code transmission: all combined--bug 1637} -setup {
+ set interp [interp create]
+} -constraints knownBug -body {
+ # Test that all the possibles error codes from Tcl get passed in both
+ # directions. This doesn't work.
+ proc MyTestAlias {interp args} {
+ global aliasTrace
+ lappend aliasTrace $args
+ interp invokehidden $interp {*}$args
+ }
+ foreach c {return} {
+ interp hide $interp $c
+ interp alias $interp $c {} MyTestAlias $interp $c
+ }
+ interp eval $interp {proc ret {code} {return -code $code ret$code}}
+ set res {}
+ set aliasTrace {}
+ for {set code -1} {$code<=5} {incr code} {
+ lappend res [catch {interp eval $interp ret $code} msg] $msg
+ }
+ return $res
+} -cleanup {
+ interp delete $interp
+} -result {-1 ret-1 0 ret0 1 ret1 0 ret2 3 ret3 4 ret4 5 ret5}
+# Some tests might need to be added to check for difference between toplevel
+# and non-toplevel evals.
+# End of return code transmission section
+test interp-26.7 {errorInfo transmission: regular interps} -setup {
+ set interp [interp create]
+} -body {
+ proc MyError {secret} {
+ return -code error "msg"
+ }
+ proc MyTestAlias {interp args} {
+ MyError "some secret"
+ }
+ interp alias $interp test {} MyTestAlias $interp
+ interp eval $interp {catch test;set ::errorInfo}
+} -cleanup {
+ interp delete $interp
+} -result {msg
+ while executing
+"MyError "some secret""
+ (procedure "MyTestAlias" line 2)
+ invoked from within
+"test"}
+test interp-26.8 {errorInfo transmission: safe interps--bug 1637} -setup {
+ set interp [interp create -safe]
+} -constraints knownBug -body {
+ # this test fails because the errorInfo is fully transmitted whether the
+ # interp is safe or not. The errorInfo should never report data from the
+ # master interpreter because it could contain sensitive information.
+ proc MyError {secret} {
+ return -code error "msg"
+ }
+ proc MyTestAlias {interp args} {
+ MyError "some secret"
+ }
+ interp alias $interp test {} MyTestAlias $interp
+ interp eval $interp {catch test;set ::errorInfo}
+} -cleanup {
+ interp delete $interp
+} -result {msg
+ while executing
+"test"}
+
+# Interps & Namespaces
+test interp-27.1 {interp aliases & namespaces} -setup {
+ set i [interp create]
+} -body {
+ set aliasTrace {}
+ proc tstAlias {args} {
+ global aliasTrace
+ lappend aliasTrace [list [namespace current] $args]
+ }
+ $i alias foo::bar tstAlias foo::bar
+ $i eval foo::bar test
+ return $aliasTrace
+} -cleanup {
+ interp delete $i
+} -result {{:: {foo::bar test}}}
+test interp-27.2 {interp aliases & namespaces} -setup {
+ set i [interp create]
+} -body {
+ set aliasTrace {}
+ proc tstAlias {args} {
+ global aliasTrace
+ lappend aliasTrace [list [namespace current] $args]
+ }
+ $i alias foo::bar tstAlias foo::bar
+ $i eval namespace eval foo {bar test}
+ return $aliasTrace
+} -cleanup {
+ interp delete $i
+} -result {{:: {foo::bar test}}}
+test interp-27.3 {interp aliases & namespaces} -setup {
+ set i [interp create]
+} -body {
+ set aliasTrace {}
+ proc tstAlias {args} {
+ global aliasTrace
+ lappend aliasTrace [list [namespace current] $args]
+ }
+ interp eval $i {namespace eval foo {proc bar {} {error "bar called"}}}
+ interp alias $i foo::bar {} tstAlias foo::bar
+ interp eval $i {namespace eval foo {bar test}}
+ return $aliasTrace
+} -cleanup {
+ interp delete $i
+} -result {{:: {foo::bar test}}}
+test interp-27.4 {interp aliases & namespaces} -setup {
+ set i [interp create]
+} -body {
+ namespace eval foo2 {
+ variable aliasTrace {}
+ proc bar {args} {
+ variable aliasTrace
+ lappend aliasTrace [list [namespace current] $args]
+ }
+ }
+ $i alias foo::bar foo2::bar foo::bar
+ $i eval namespace eval foo {bar test}
+ return $foo2::aliasTrace
+} -cleanup {
+ namespace delete foo2
+ interp delete $i
+} -result {{::foo2 {foo::bar test}}}
+test interp-27.5 {interp hidden & namespaces} -setup {
+ set i [interp create]
+} -constraints knownBug -body {
+ interp eval $i {
+ namespace eval foo {
+ proc bar {args} {
+ return "bar called ([namespace current]) ($args)"
+ }
+ }
+ }
+ set res [list [interp eval $i {namespace eval foo {bar test1}}]]
+ interp hide $i foo::bar
+ lappend res [list [catch {interp eval $i {namespace eval foo {bar test2}}} msg] $msg]
+} -cleanup {
+ interp delete $i
+} -result {{bar called (::foo) (test1)} {1 {invalid command name "bar"}}}
+test interp-27.6 {interp hidden & aliases & namespaces} -setup {
+ set i [interp create]
+} -constraints knownBug -body {
+ set v root-master
+ namespace eval foo {
+ variable v foo-master
+ proc bar {interp args} {
+ variable v
+ list "master bar called ($v) ([namespace current]) ($args)"\
+ [interp invokehidden $interp foo::bar $args]
+ }
+ }
+ interp eval $i {
+ namespace eval foo {
+ namespace export *
+ variable v foo-slave
+ proc bar {args} {
+ variable v
+ return "slave bar called ($v) ([namespace current]) ($args)"
+ }
+ }
+ }
+ set res [list [interp eval $i {namespace eval foo {bar test1}}]]
+ $i hide foo::bar
+ $i alias foo::bar foo::bar $i
+ set res [concat $res [interp eval $i {
+ set v root-slave
+ namespace eval test {
+ variable v foo-test
+ namespace import ::foo::*
+ bar test2
+ }
+ }]]
+} -cleanup {
+ namespace delete foo
+ interp delete $i
+} -result {{slave bar called (foo-slave) (::foo) (test1)} {master bar called (foo-master) (::foo) (test2)} {slave bar called (foo-slave) (::foo) (test2)}}
+test interp-27.7 {interp hidden & aliases & imports & namespaces} -setup {
+ set i [interp create]
+} -constraints knownBug -body {
+ set v root-master
+ namespace eval mfoo {
+ variable v foo-master
+ proc bar {interp args} {
+ variable v
+ list "master bar called ($v) ([namespace current]) ($args)"\
+ [interp invokehidden $interp test::bar $args]
+ }
+ }
+ interp eval $i {
+ namespace eval foo {
+ namespace export *
+ variable v foo-slave
+ proc bar {args} {
+ variable v
+ return "slave bar called ($v) ([info level 0]) ([uplevel namespace current]) ([namespace current]) ($args)"
+ }
+ }
+ set v root-slave
+ namespace eval test {
+ variable v foo-test
+ namespace import ::foo::*
+ }
+ }
+ set res [list [interp eval $i {namespace eval test {bar test1}}]]
+ $i hide test::bar
+ $i alias test::bar mfoo::bar $i
+ set res [concat $res [interp eval $i {test::bar test2}]]
+} -cleanup {
+ namespace delete mfoo
+ interp delete $i
+} -result {{slave bar called (foo-slave) (bar test1) (::tcltest) (::foo) (test1)} {master bar called (foo-master) (::mfoo) (test2)} {slave bar called (foo-slave) (test::bar test2) (::) (::foo) (test2)}}
+test interp-27.8 {hiding, namespaces and integrity} knownBug {
+ namespace eval foo {
+ variable v 3
+ proc bar {} {variable v; set v}
+ # next command would currently generate an unknown command "bar" error.
+ interp hide {} bar
+ }
+ namespace delete foo
+ list [catch {interp invokehidden {} foo::bar} msg] $msg
+} {1 {invalid hidden command name "foo"}}
+
+test interp-28.1 {getting fooled by slave's namespace ?} -setup {
+ set i [interp create -safe]
+ proc master {interp args} {interp hide $interp list}
+} -body {
+ $i alias master master $i
+ set r [interp eval $i {
+ namespace eval foo {
+ proc list {args} {
+ return "dummy foo::list"
+ }
+ master
+ }
+ info commands list
+ }]
+} -cleanup {
+ rename master {}
+ interp delete $i
+} -result {}
+test interp-28.2 {master's nsName cache should not cross} -setup {
+ set i [interp create]
+ $i eval {proc filter lst {lsearch -all -inline -not $lst "::tcl"}}
+} -body {
+ $i eval {
+ set x {namespace children ::}
+ set y [list namespace children ::]
+ namespace delete {*}[filter [{*}$y]]
+ set j [interp create]
+ $j alias filter filter
+ $j eval {namespace delete {*}[filter [namespace children ::]]}
+ namespace eval foo {}
+ list [filter [eval $x]] [filter [eval $y]] [filter [$j eval $x]] [filter [$j eval $y]]
+ }
+} -cleanup {
+ interp delete $i
+} -result {::foo ::foo {} {}}
+
+# Part 29: recursion limit
+# 29.1.* Argument checking
+# 29.2.* Reading and setting the recursion limit
+# 29.3.* Does the recursion limit work?
+# 29.4.* Recursion limit inheritance by sub-interpreters
+# 29.5.* Confirming the recursionlimit command does not affect the parent
+# 29.6.* Safe interpreter restriction
+
+test interp-29.1.1 {interp recursionlimit argument checking} {
+ list [catch {interp recursionlimit} msg] $msg
+} {1 {wrong # args: should be "interp recursionlimit path ?newlimit?"}}
+test interp-29.1.2 {interp recursionlimit argument checking} {
+ list [catch {interp recursionlimit foo bar} msg] $msg
+} {1 {could not find interpreter "foo"}}
+test interp-29.1.3 {interp recursionlimit argument checking} {
+ list [catch {interp recursionlimit foo bar baz} msg] $msg
+} {1 {wrong # args: should be "interp recursionlimit path ?newlimit?"}}
+test interp-29.1.4 {interp recursionlimit argument checking} {
+ interp create moo
+ set result [catch {interp recursionlimit moo bar} msg]
+ interp delete moo
+ list $result $msg
+} {1 {expected integer but got "bar"}}
+test interp-29.1.5 {interp recursionlimit argument checking} {
+ interp create moo
+ set result [catch {interp recursionlimit moo 0} msg]
+ interp delete moo
+ list $result $msg
+} {1 {recursion limit must be > 0}}
+test interp-29.1.6 {interp recursionlimit argument checking} {
+ interp create moo
+ set result [catch {interp recursionlimit moo -1} msg]
+ interp delete moo
+ list $result $msg
+} {1 {recursion limit must be > 0}}
+test interp-29.1.7 {interp recursionlimit argument checking} {
+ interp create moo
+ set result [catch {interp recursionlimit moo [expr {wide(1)<<32}]} msg]
+ interp delete moo
+ list $result [string range $msg 0 35]
+} {1 {integer value too large to represent}}
+test interp-29.1.8 {slave recursionlimit argument checking} {
+ interp create moo
+ set result [catch {moo recursionlimit foo bar} msg]
+ interp delete moo
+ list $result $msg
+} {1 {wrong # args: should be "moo recursionlimit ?newlimit?"}}
+test interp-29.1.9 {slave recursionlimit argument checking} {
+ interp create moo
+ set result [catch {moo recursionlimit foo} msg]
+ interp delete moo
+ list $result $msg
+} {1 {expected integer but got "foo"}}
+test interp-29.1.10 {slave recursionlimit argument checking} {
+ interp create moo
+ set result [catch {moo recursionlimit 0} msg]
+ interp delete moo
+ list $result $msg
+} {1 {recursion limit must be > 0}}
+test interp-29.1.11 {slave recursionlimit argument checking} {
+ interp create moo
+ set result [catch {moo recursionlimit -1} msg]
+ interp delete moo
+ list $result $msg
+} {1 {recursion limit must be > 0}}
+test interp-29.1.12 {slave recursionlimit argument checking} {
+ interp create moo
+ set result [catch {moo recursionlimit [expr {wide(1)<<32}]} msg]
+ interp delete moo
+ list $result [string range $msg 0 35]
+} {1 {integer value too large to represent}}
+test interp-29.2.1 {query recursion limit} {
+ interp recursionlimit {}
+} 1000
+test interp-29.2.2 {query recursion limit} {
+ set i [interp create]
+ set n [interp recursionlimit $i]
+ interp delete $i
+ set n
+} 1000
+test interp-29.2.3 {query recursion limit} {
+ set i [interp create]
+ set n [$i recursionlimit]
+ interp delete $i
+ set n
+} 1000
+test interp-29.2.4 {query recursion limit} {
+ set i [interp create]
+ set r [$i eval {
+ set n1 [interp recursionlimit {} 42]
+ set n2 [interp recursionlimit {}]
+ list $n1 $n2
+ }]
+ interp delete $i
+ set r
+} {42 42}
+test interp-29.2.5 {query recursion limit} {
+ set i [interp create]
+ set n1 [interp recursionlimit $i 42]
+ set n2 [interp recursionlimit $i]
+ interp delete $i
+ list $n1 $n2
+} {42 42}
+test interp-29.2.6 {query recursion limit} {
+ set i [interp create]
+ set n1 [interp recursionlimit $i 42]
+ set n2 [$i recursionlimit]
+ interp delete $i
+ list $n1 $n2
+} {42 42}
+test interp-29.2.7 {query recursion limit} {
+ set i [interp create]
+ set n1 [$i recursionlimit 42]
+ set n2 [interp recursionlimit $i]
+ interp delete $i
+ list $n1 $n2
+} {42 42}
+test interp-29.2.8 {query recursion limit} {
+ set i [interp create]
+ set n1 [$i recursionlimit 42]
+ set n2 [$i recursionlimit]
+ interp delete $i
+ list $n1 $n2
+} {42 42}
+test interp-29.3.1 {recursion limit} {
+ set i [interp create]
+ set r [interp eval $i {
+ interp recursionlimit {} 50
+ proc p {} {incr ::i; p}
+ set i 0
+ list [catch p msg] $msg $i
+ }]
+ interp delete $i
+ set r
+} {1 {too many nested evaluations (infinite loop?)} 49}
+test interp-29.3.2 {recursion limit} {
+ set i [interp create]
+ interp recursionlimit $i 50
+ set r [interp eval $i {
+ proc p {} {incr ::i; p}
+ set i 0
+ list [catch p msg] $msg $i
+ }]
+ interp delete $i
+ set r
+} {1 {too many nested evaluations (infinite loop?)} 49}
+test interp-29.3.3 {recursion limit} {
+ set i [interp create]
+ $i recursionlimit 50
+ set r [interp eval $i {
+ proc p {} {incr ::i; p}
+ set i 0
+ list [catch p msg] $msg $i
+ }]
+ interp delete $i
+ set r
+} {1 {too many nested evaluations (infinite loop?)} 49}
+test interp-29.3.4 {recursion limit error reporting} {
+ interp create slave
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ interp recursionlimit {} 5
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {1 {falling back due to new recursion limit}}
+test interp-29.3.5 {recursion limit error reporting} {
+ interp create slave
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ interp recursionlimit {} 4
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {1 {falling back due to new recursion limit}}
+test interp-29.3.6 {recursion limit error reporting} {
+ interp create slave
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ interp recursionlimit {} 6
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+#
+# Note that TEBC does not verify the interp's nesting level itself; the nesting
+# level will only be verified when it invokes a non-bcc'd command.
+#
+test interp-29.3.7a {recursion limit error reporting} {
+ interp create slave
+ after 0 {interp recursionlimit slave 5}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.3.7b {recursion limit error reporting} {
+ interp create slave
+ after 0 {interp recursionlimit slave 5}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ update
+ eval { # 5
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.3.7c {recursion limit error reporting} {
+ interp create slave
+ after 0 {interp recursionlimit slave 5}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set set set
+ $set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {1 {too many nested evaluations (infinite loop?)}}
+test interp-29.3.8a {recursion limit error reporting} {
+ interp create slave
+ after 0 {interp recursionlimit slave 4}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.3.8b {recursion limit error reporting} {
+ interp create slave
+ after 0 {interp recursionlimit slave 4}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ update
+ eval { # 5
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {1 {too many nested evaluations (infinite loop?)}}
+test interp-29.3.9a {recursion limit error reporting} {
+ interp create slave
+ after 0 {interp recursionlimit slave 6}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.3.9b {recursion limit error reporting} {
+ interp create slave
+ after 0 {interp recursionlimit slave 6}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ set set set
+ $set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.3.10a {recursion limit error reporting} {
+ interp create slave
+ after 0 {slave recursionlimit 4}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.3.10b {recursion limit error reporting} {
+ interp create slave
+ after 0 {slave recursionlimit 4}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ update
+ eval { # 5
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {1 {too many nested evaluations (infinite loop?)}}
+test interp-29.3.11a {recursion limit error reporting} {
+ interp create slave
+ after 0 {slave recursionlimit 5}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.3.11b {recursion limit error reporting} {
+ interp create slave
+ after 0 {slave recursionlimit 5}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set set set
+ $set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {1 {too many nested evaluations (infinite loop?)}}
+test interp-29.3.12a {recursion limit error reporting} {
+ interp create slave
+ after 0 {slave recursionlimit 6}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.3.12b {recursion limit error reporting} {
+ interp create slave
+ after 0 {slave recursionlimit 6}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set set set
+ $set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.4.1 {recursion limit inheritance} {
+ set i [interp create]
+ set ii [interp eval $i {
+ interp recursionlimit {} 50
+ interp create
+ }]
+ set r [interp eval [list $i $ii] {
+ proc p {} {incr ::i; p}
+ set i 0
+ catch p
+ set i
+ }]
+ interp delete $i
+ set r
+} 50
+test interp-29.4.2 {recursion limit inheritance} {
+ set i [interp create]
+ $i recursionlimit 50
+ set ii [interp eval $i {interp create}]
+ set r [interp eval [list $i $ii] {
+ proc p {} {incr ::i; p}
+ set i 0
+ catch p
+ set i
+ }]
+ interp delete $i
+ set r
+} 50
+test interp-29.5.1 {does slave recursion limit affect master?} {
+ set before [interp recursionlimit {}]
+ set i [interp create]
+ interp recursionlimit $i 20000
+ set after [interp recursionlimit {}]
+ set slavelimit [interp recursionlimit $i]
+ interp delete $i
+ list [expr {$before == $after}] $slavelimit
+} {1 20000}
+test interp-29.5.2 {does slave recursion limit affect master?} {
+ set before [interp recursionlimit {}]
+ set i [interp create]
+ interp recursionlimit $i 20000
+ set after [interp recursionlimit {}]
+ set slavelimit [$i recursionlimit]
+ interp delete $i
+ list [expr {$before == $after}] $slavelimit
+} {1 20000}
+test interp-29.5.3 {does slave recursion limit affect master?} {
+ set before [interp recursionlimit {}]
+ set i [interp create]
+ $i recursionlimit 20000
+ set after [interp recursionlimit {}]
+ set slavelimit [interp recursionlimit $i]
+ interp delete $i
+ list [expr {$before == $after}] $slavelimit
+} {1 20000}
+test interp-29.5.4 {does slave recursion limit affect master?} {
+ set before [interp recursionlimit {}]
+ set i [interp create]
+ $i recursionlimit 20000
+ set after [interp recursionlimit {}]
+ set slavelimit [$i recursionlimit]
+ interp delete $i
+ list [expr {$before == $after}] $slavelimit
+} {1 20000}
+test interp-29.6.1 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set n [interp recursionlimit slave]
+ interp delete slave
+ set n
+} 1000
+test interp-29.6.2 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set n [slave recursionlimit]
+ interp delete slave
+ set n
+} 1000
+test interp-29.6.3 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set n1 [interp recursionlimit slave 42]
+ set n2 [interp recursionlimit slave]
+ interp delete slave
+ list $n1 $n2
+} {42 42}
+test interp-29.6.4 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set n1 [slave recursionlimit 42]
+ set n2 [interp recursionlimit slave]
+ interp delete slave
+ list $n1 $n2
+} {42 42}
+test interp-29.6.5 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set n1 [interp recursionlimit slave 42]
+ set n2 [slave recursionlimit]
+ interp delete slave
+ list $n1 $n2
+} {42 42}
+test interp-29.6.6 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set n1 [slave recursionlimit 42]
+ set n2 [slave recursionlimit]
+ interp delete slave
+ list $n1 $n2
+} {42 42}
+test interp-29.6.7 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set n1 [slave recursionlimit 42]
+ set n2 [slave recursionlimit]
+ interp delete slave
+ list $n1 $n2
+} {42 42}
+test interp-29.6.8 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set n [catch {slave eval {interp recursionlimit {} 42}} msg]
+ interp delete slave
+ list $n $msg
+} {1 {permission denied: safe interpreters cannot change recursion limit}}
+test interp-29.6.9 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set result [
+ slave eval {
+ interp create slave2 -safe
+ set n [catch {
+ interp recursionlimit slave2 42
+ } msg]
+ list $n $msg
+ }
+ ]
+ interp delete slave
+ set result
+} {1 {permission denied: safe interpreters cannot change recursion limit}}
+test interp-29.6.10 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set result [
+ slave eval {
+ interp create slave2 -safe
+ set n [catch {
+ slave2 recursionlimit 42
+ } msg]
+ list $n $msg
+ }
+ ]
+ interp delete slave
+ set result
+} {1 {permission denied: safe interpreters cannot change recursion limit}}
+
+
+# # Deep recursion (into interps when the regular one fails):
+# # still crashes...
+# proc p {} {
+# if {[catch p ret]} {
+# catch {
+# set i [interp create]
+# interp eval $i [list proc p {} [info body p]]
+# interp eval $i p
+# }
+# interp delete $i
+# return ok
+# }
+# return $ret
+# }
+# p
+
+# more tests needed...
+
+# Interp & stack
+#test interp-29.1 {interp and stack (info level)} {
+#} {}
+
+# End of stack-recursion tests
+
+# This test dumps core in Tcl 8.0.3!
+test interp-30.1 {deletion of aliases inside namespaces} {
+ set i [interp create]
+ $i alias ns::cmd list
+ $i alias ns::cmd {}
+} {}
+
+test interp-31.1 {alias invocation scope} {
+ proc mySet {varName value} {
+ upvar 1 $varName localVar
+ set localVar $value
+ }
+ interp alias {} myNewSet {} mySet
+ proc testMyNewSet {value} {
+ myNewSet a $value
+ return $a
+ }
+ unset -nocomplain a
+ set result [testMyNewSet "ok"]
+ rename testMyNewSet {}
+ rename mySet {}
+ rename myNewSet {}
+ set result
+} ok
+
+test interp-32.1 {parent's working directory should be inherited by a child interp} -setup {
+ cd [temporaryDirectory]
+} -body {
+ set parent [pwd]
+ set i [interp create]
+ set child [$i eval pwd]
+ interp delete $i
+ file mkdir cwd_test
+ cd cwd_test
+ lappend parent [pwd]
+ set i [interp create]
+ lappend child [$i eval pwd]
+ cd ..
+ file delete cwd_test
+ interp delete $i
+ expr {[string equal $parent $child] ? 1 :
+ "\{$parent\} != \{$child\}"}
+} -cleanup {
+ cd [workingDirectory]
+} -result 1
+
+test interp-33.1 {refCounting for target words of alias [Bug 730244]} {
+ # This test will panic if Bug 730244 is not fixed.
+ set i [interp create]
+ proc testHelper args {rename testHelper {}; return $args}
+ # Note: interp names are simple words by default
+ trace add execution testHelper enter "interp alias $i alias {} ;#"
+ interp alias $i alias {} testHelper this
+ $i eval alias
+} this
+
+test interp-34.1 {basic test of limits - calling commands} -body {
+ set i [interp create]
+ $i eval {
+ proc foobar {} {
+ for {set x 0} {$x<1000000} {incr x} {
+ # Calls to this are not bytecoded away
+ pid
+ }
+ }
+ }
+ $i limit command -value 1000
+ $i eval foobar
+} -returnCodes error -result {command count limit exceeded} -cleanup {
+ interp delete $i
+}
+test interp-34.2 {basic test of limits - bytecoded commands} -body {
+ set i [interp create]
+ $i eval {
+ proc foobar {} {
+ for {set x 0} {$x<1000000} {incr x} {
+ # Calls to this *are* bytecoded away
+ expr {1+2+3}
+ }
+ }
+ }
+ $i limit command -value 1000
+ $i eval foobar
+} -returnCodes error -result {command count limit exceeded} -cleanup {
+ interp delete $i
+}
+test interp-34.3 {basic test of limits - pure bytecode loop} -body {
+ set i [interp create]
+ $i eval {
+ proc foobar {} {
+ while {1} {
+ # No bytecode at all here...
+ }
+ }
+ }
+ # We use a time limit here; command limits don't trap this case
+ $i limit time -seconds [expr {[clock seconds]+2}]
+ $i eval foobar
+} -returnCodes error -result {time limit exceeded} -cleanup {
+ interp delete $i
+}
+test interp-34.3.1 {basic test of limits - pure inside-command loop} -body {
+ set i [interp create]
+ $i eval {
+ proc foobar {} {
+ set while while
+ $while {1} {
+ # No bytecode at all here...
+ }
+ }
+ }
+ # We use a time limit here; command limits don't trap this case
+ $i limit time -seconds [expr {[clock seconds]+2}]
+ $i eval foobar
+} -returnCodes error -result {time limit exceeded} -cleanup {
+ interp delete $i
+}
+test interp-34.4 {limits with callbacks: extending limits} -setup {
+ set i [interp create]
+ set a 0
+ set b 0
+ set c a
+ proc cb1 {} {
+ global c
+ incr ::$c
+ }
+ proc cb2 {newlimit args} {
+ global c i
+ set c b
+ $i limit command -value $newlimit
+ }
+} -body {
+ interp alias $i foo {} cb1
+ set curlim [$i eval info cmdcount]
+ $i limit command -command "cb2 [expr $curlim+100]" \
+ -value [expr {$curlim+10}]
+ $i eval {for {set i 0} {$i<10} {incr i} {foo}}
+ list $a $b $c
+} -result {6 4 b} -cleanup {
+ interp delete $i
+ rename cb1 {}
+ rename cb2 {}
+}
+# The next three tests exercise all the three ways that limit handlers
+# can be deleted. Fully verifying this requires additional source
+# code instrumentation.
+test interp-34.5 {limits with callbacks: removing limits} -setup {
+ set i [interp create]
+ set a 0
+ set b 0
+ set c a
+ proc cb1 {} {
+ global c
+ incr ::$c
+ }
+ proc cb2 {newlimit args} {
+ global c i
+ set c b
+ $i limit command -value $newlimit
+ }
+} -body {
+ interp alias $i foo {} cb1
+ set curlim [$i eval info cmdcount]
+ $i limit command -command "cb2 {}" -value [expr {$curlim+10}]
+ $i eval {for {set i 0} {$i<10} {incr i} {foo}}
+ list $a $b $c
+} -result {6 4 b} -cleanup {
+ interp delete $i
+ rename cb1 {}
+ rename cb2 {}
+}
+test interp-34.6 {limits with callbacks: removing limits and handlers} -setup {
+ set i [interp create]
+ set a 0
+ set b 0
+ set c a
+ proc cb1 {} {
+ global c
+ incr ::$c
+ }
+ proc cb2 {args} {
+ global c i
+ set c b
+ $i limit command -value {} -command {}
+ }
+} -body {
+ interp alias $i foo {} cb1
+ set curlim [$i eval info cmdcount]
+ $i limit command -command cb2 -value [expr {$curlim+10}]
+ $i eval {for {set i 0} {$i<10} {incr i} {foo}}
+ list $a $b $c
+} -result {6 4 b} -cleanup {
+ interp delete $i
+ rename cb1 {}
+ rename cb2 {}
+}
+test interp-34.7 {limits with callbacks: deleting the handler interp} -setup {
+ set i [interp create]
+ $i eval {
+ set i [interp create]
+ proc cb1 {} {
+ global c
+ incr ::$c
+ }
+ proc cb2 {args} {
+ global c i curlim
+ set c b
+ $i limit command -value [expr {$curlim+1000}]
+ trapToParent
+ }
+ }
+ proc cb3 {} {
+ global i subi
+ interp alias [list $i $subi] foo {} cb4
+ interp delete $i
+ }
+ proc cb4 {} {
+ global n
+ incr n
+ }
+} -body {
+ set subi [$i eval set i]
+ interp alias $i trapToParent {} cb3
+ set n 0
+ $i eval {
+ set a 0
+ set b 0
+ set c a
+ interp alias $i foo {} cb1
+ set curlim [$i eval info cmdcount]
+ $i limit command -command cb2 -value [expr {$curlim+10}]
+ }
+ $i eval {
+ $i eval {
+ for {set i 0} {$i<10} {incr i} {foo}
+ }
+ }
+ list $n [interp exists $i]
+} -result {4 0} -cleanup {
+ rename cb3 {}
+ rename cb4 {}
+}
+# Bug 1085023
+test interp-34.8 {time limits trigger in vwaits} -body {
+ set i [interp create]
+ interp limit $i time -seconds [expr {[clock seconds]+1}] -granularity 1
+ $i eval {
+ set x {}
+ vwait x
+ }
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {limit exceeded}
+test interp-34.9 {time limits trigger in blocking after} {
+ set i [interp create]
+ set t0 [clock seconds]
+ interp limit $i time -seconds [expr {$t0 + 1}] -granularity 1
+ set code [catch {
+ $i eval {after 10000}
+ } msg]
+ set t1 [clock seconds]
+ interp delete $i
+ list $code $msg [expr {($t1-$t0) < 3 ? "OK" : $t1-$t0}]
+} {1 {time limit exceeded} OK}
+test interp-34.10 {time limits trigger in vwaits: Bug 1221395} -body {
+ set i [interp create]
+ # Assume someone hasn't set the clock to early 1970!
+ $i limit time -seconds 1 -granularity 4
+ interp alias $i log {} lappend result
+ set result {}
+ catch {
+ $i eval {
+ log 1
+ after 100
+ log 2
+ }
+ } msg
+ interp delete $i
+ lappend result $msg
+} -result {1 {time limit exceeded}}
+test interp-34.11 {time limit extension in callbacks} -setup {
+ proc cb1 {i t} {
+ global result
+ lappend result cb1
+ $i limit time -seconds $t -command cb2
+ }
+ proc cb2 {} {
+ global result
+ lappend result cb2
+ }
+} -body {
+ set i [interp create]
+ set t0 [clock seconds]
+ $i limit time -seconds [expr {$t0+1}] -granularity 1 \
+ -command "cb1 $i [expr {$t0+2}]"
+ set ::result {}
+ lappend ::result [catch {
+ $i eval {
+ for {set i 0} {$i<30} {incr i} {
+ after 100
+ }
+ }
+ } msg] $msg
+ set t1 [clock seconds]
+ lappend ::result [expr {$t1-$t0>=2 ? "ok" : "$t0,$t1"}]
+ interp delete $i
+ return $::result
+} -result {cb1 cb2 1 {time limit exceeded} ok} -cleanup {
+ rename cb1 {}
+ rename cb2 {}
+}
+test interp-34.12 {time limit extension in callbacks} -setup {
+ proc cb1 {i} {
+ global result times
+ lappend result cb1
+ set times [lassign $times t]
+ $i limit time -seconds $t
+ }
+} -body {
+ set i [interp create]
+ set t0 [clock seconds]
+ set ::times "[expr {$t0+2}] [expr {$t0+100}]"
+ $i limit time -seconds [expr {$t0+1}] -granularity 1 -command "cb1 $i"
+ set ::result {}
+ lappend ::result [catch {
+ $i eval {
+ for {set i 0} {$i<30} {incr i} {
+ after 100
+ }
+ }
+ } msg] $msg
+ set t1 [clock seconds]
+ lappend ::result [expr {$t1-$t0>=2 ? "ok" : "$t0,$t1"}]
+ interp delete $i
+ return $::result
+} -result {cb1 cb1 0 {} ok} -cleanup {
+ rename cb1 {}
+}
+test interp-34.13 {time limit granularity and vwait: Bug 2891362} -setup {
+ set i [interp create -safe]
+} -body {
+ $i limit time -seconds [clock add [clock seconds] 1 second]
+ $i eval {
+ after 2000 set x timeout
+ vwait x
+ return $x
+ }
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {limit exceeded}
+
+test interp-35.1 {interp limit syntax} -body {
+ interp limit
+} -returnCodes error -result {wrong # args: should be "interp limit path limitType ?-option value ...?"}
+test interp-35.2 {interp limit syntax} -body {
+ interp limit {}
+} -returnCodes error -result {wrong # args: should be "interp limit path limitType ?-option value ...?"}
+test interp-35.3 {interp limit syntax} -body {
+ interp limit {} foo
+} -returnCodes error -result {bad limit type "foo": must be commands or time}
+test interp-35.4 {interp limit syntax} -body {
+ set i [interp create]
+ set dict [interp limit $i commands]
+ set result {}
+ foreach key [lsort [dict keys $dict]] {
+ lappend result $key [dict get $dict $key]
+ }
+ set result
+} -cleanup {
+ interp delete $i
+} -result {-command {} -granularity 1 -value {}}
+test interp-35.5 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i commands -granularity
+} -cleanup {
+ interp delete $i
+} -result 1
+test interp-35.6 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i commands -granularity 2
+} -cleanup {
+ interp delete $i
+} -result {}
+test interp-35.7 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i commands -foobar
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {bad option "-foobar": must be -command, -granularity, or -value}
+test interp-35.8 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i commands -granularity foobar
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {expected integer but got "foobar"}
+test interp-35.9 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i commands -granularity 0
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {granularity must be at least 1}
+test interp-35.10 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i commands -value foobar
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {expected integer but got "foobar"}
+test interp-35.11 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i commands -value -1
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {command limit value must be at least 0}
+test interp-35.12 {interp limit syntax} -body {
+ set i [interp create]
+ set dict [interp limit $i time]
+ set result {}
+ foreach key [lsort [dict keys $dict]] {
+ lappend result $key [dict get $dict $key]
+ }
+ set result
+} -cleanup {
+ interp delete $i
+} -result {-command {} -granularity 10 -milliseconds {} -seconds {}}
+test interp-35.13 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -granularity
+} -cleanup {
+ interp delete $i
+} -result 10
+test interp-35.14 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -granularity 2
+} -cleanup {
+ interp delete $i
+} -result {}
+test interp-35.15 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -foobar
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {bad option "-foobar": must be -command, -granularity, -milliseconds, or -seconds}
+test interp-35.16 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -granularity foobar
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {expected integer but got "foobar"}
+test interp-35.17 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -granularity 0
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {granularity must be at least 1}
+test interp-35.18 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -seconds foobar
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {expected integer but got "foobar"}
+test interp-35.19 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -seconds -1
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {seconds must be at least 0}
+test interp-35.20 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -millis foobar
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {expected integer but got "foobar"}
+test interp-35.21 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -millis -1
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {milliseconds must be at least 0}
+test interp-35.22 {interp time limits normalize milliseconds} -body {
+ set i [interp create]
+ interp limit $i time -seconds 1 -millis 1500
+ list [$i limit time -seconds] [$i limit time -millis]
+} -cleanup {
+ interp delete $i
+} -result {2 500}
+# Bug 3398794
+test interp-35.23 {interp command limits can't touch current interp} -body {
+ interp limit {} commands -value 10
+} -returnCodes error -result {limits on current interpreter inaccessible}
+test interp-35.24 {interp time limits can't touch current interp} -body {
+ interp limit {} time -seconds 2
+} -returnCodes error -result {limits on current interpreter inaccessible}
+
+test interp-36.1 {interp bgerror syntax} -body {
+ interp bgerror
+} -returnCodes error -result {wrong # args: should be "interp bgerror path ?cmdPrefix?"}
+test interp-36.2 {interp bgerror syntax} -body {
+ interp bgerror x y z
+} -returnCodes error -result {wrong # args: should be "interp bgerror path ?cmdPrefix?"}
+test interp-36.3 {interp bgerror syntax} -setup {
+ interp create slave
+} -body {
+ slave bgerror x y
+} -cleanup {
+ interp delete slave
+} -returnCodes error -result {wrong # args: should be "slave bgerror ?cmdPrefix?"}
+test interp-36.4 {SlaveBgerror syntax} -setup {
+ interp create slave
+} -body {
+ slave bgerror \{
+} -cleanup {
+ interp delete slave
+} -returnCodes error -result {cmdPrefix must be list of length >= 1}
+test interp-36.5 {SlaveBgerror syntax} -setup {
+ interp create slave
+} -body {
+ slave bgerror {}
+} -cleanup {
+ interp delete slave
+} -returnCodes error -result {cmdPrefix must be list of length >= 1}
+test interp-36.6 {SlaveBgerror returns handler} -setup {
+ interp create slave
+} -body {
+ slave bgerror {foo bar soom}
+} -cleanup {
+ interp delete slave
+} -result {foo bar soom}
+test interp-36.7 {SlaveBgerror sets error handler of slave [1999035]} -setup {
+ interp create slave
+ slave alias handler handler
+ slave bgerror handler
+ variable result {untouched}
+ proc handler {args} {
+ variable result
+ set result [lindex $args 0]
+ }
+} -body {
+ slave eval {
+ variable done {}
+ after 0 error foo
+ after 10 [list ::set [namespace which -variable done] {}]
+ vwait [namespace which -variable done]
+ }
+ set result
+} -cleanup {
+ variable result {}
+ unset -nocomplain result
+ interp delete slave
+} -result foo
+
+test interp-37.1 {safe interps and min() and max(): Bug 2895741} -setup {
+ catch {interp delete a}
+ interp create a
+ set result {}
+} -body {
+ interp create {a b} -safe
+ lappend result [interp eval a {expr min(5,2,3)*max(7,13,11)}]
+ lappend result [interp eval {a b} {expr min(5,2,3)*max(7,13,11)}]
+} -cleanup {
+ unset -nocomplain result
+ interp delete a
+} -result {26 26}
+
+test interp-38.1 {interp debug one-way switch} -setup {
+ catch {interp delete a}
+ interp create a
+ interp debug a -frame 1
+} -body {
+ # TIP #3xx interp debug frame is a one-way switch
+ interp debug a -frame 0
+} -cleanup {
+ interp delete a
+} -result {1}
+test interp-38.2 {interp debug env var} -setup {
+ catch {interp delete a}
+ set ::env(TCL_INTERP_DEBUG_FRAME) 1
+ interp create a
+} -body {
+ interp debug a
+} -cleanup {
+ unset -nocomplain ::env(TCL_INTERP_DEBUG_FRAME)
+ interp delete a
+} -result {-frame 1}
+test interp-38.3 {interp debug wrong args} -body {
+ interp debug
+} -returnCodes {
+ error
+} -result {wrong # args: should be "interp debug path ?-frame ?bool??"}
+test interp-38.4 {interp debug basic setup} -body {
+ interp debug {}
+} -result {-frame 0}
+test interp-38.5 {interp debug basic setup} -body {
+ interp debug {} -f
+} -result {0}
+test interp-38.6 {interp debug basic setup} -body {
+ interp debug -frames
+} -returnCodes error -result {could not find interpreter "-frames"}
+test interp-38.7 {interp debug basic setup} -body {
+ interp debug {} -frames
+} -returnCodes error -result {bad debug option "-frames": must be -frame}
+test interp-38.8 {interp debug basic setup} -body {
+ interp debug {} -frame 0 bogus
+} -returnCodes {
+ error
+} -result {wrong # args: should be "interp debug path ?-frame ?bool??"}
+
+# cleanup
+unset -nocomplain hidden_cmds
+foreach i [interp slaves] {
+ interp delete $i
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/io.test b/library/msgcat/tests/io.test
new file mode 100644
index 0000000..f3c39f4
--- /dev/null
+++ b/library/msgcat/tests/io.test
@@ -0,0 +1,7797 @@
+# -*- tcl -*-
+# Functionality covered: operation of all IO commands, and all procedures
+# defined in generic/tclIO.c.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# 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.
+
+if {[catch {package require tcltest 2}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2 required."
+ return
+}
+namespace eval ::tcl::test::io {
+ namespace import ::tcltest::*
+
+ variable umaskValue
+ variable path
+ variable f
+ variable i
+ variable n
+ variable v
+ variable msg
+ variable expected
+
+testConstraint testchannel [llength [info commands testchannel]]
+testConstraint exec [llength [info commands exec]]
+testConstraint openpipe 1
+testConstraint fileevent [llength [info commands fileevent]]
+testConstraint fcopy [llength [info commands fcopy]]
+testConstraint testfevent [llength [info commands testfevent]]
+testConstraint testchannelevent [llength [info commands testchannelevent]]
+testConstraint testmainthread [llength [info commands testmainthread]]
+testConstraint thread [expr {0 == [catch {package require Thread 2.6}]}]
+
+# You need a *very* special environment to do some tests. In
+# particular, many file systems do not support large-files...
+testConstraint largefileSupport 0
+
+# some tests can only be run is umask is 2
+# if "umask" cannot be run, the tests will be skipped.
+set umaskValue 0
+testConstraint umask [expr {![catch {set umaskValue [scan [exec /bin/sh -c umask] %o]}]}]
+
+testConstraint makeFileInHome [expr {![file exists ~/_test_] && [file writable ~]}]
+
+# set up a long data file for some of the following tests
+
+set path(longfile) [makeFile {} longfile]
+set f [open $path(longfile) w]
+fconfigure $f -eofchar {} -translation lf
+for { set i 0 } { $i < 100 } { incr i} {
+ puts $f "#123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
+\#123456789abcdef01
+\#"
+ }
+close $f
+
+set path(cat) [makeFile {
+ set f stdin
+ if {$argv != ""} {
+ set f [open [lindex $argv 0]]
+ }
+ fconfigure $f -encoding binary -translation lf -blocking 0 -eofchar \x1a
+ fconfigure stdout -encoding binary -translation lf -buffering none
+ fileevent $f readable "foo $f"
+ proc foo {f} {
+ set x [read $f]
+ catch {puts -nonewline $x}
+ if {[eof $f]} {
+ close $f
+ exit 0
+ }
+ }
+ vwait forever
+} cat]
+
+set thisScript [file join [pwd] [info script]]
+
+proc contents {file} {
+ set f [open $file]
+ fconfigure $f -translation binary
+ set a [read $f]
+ close $f
+ return $a
+}
+
+test io-1.5 {Tcl_WriteChars: CheckChannelErrors} {emptyTest} {
+ # no test, need to cause an async error.
+} {}
+set path(test1) [makeFile {} test1]
+test io-1.6 {Tcl_WriteChars: WriteBytes} {
+ set f [open $path(test1) w]
+ fconfigure $f -encoding binary
+ puts -nonewline $f "a\u4e4d\0"
+ close $f
+ contents $path(test1)
+} "a\x4d\x00"
+test io-1.7 {Tcl_WriteChars: WriteChars} {
+ set f [open $path(test1) w]
+ fconfigure $f -encoding shiftjis
+ puts -nonewline $f "a\u4e4d\0"
+ close $f
+ contents $path(test1)
+} "a\x93\xe1\x00"
+set path(test2) [makeFile {} test2]
+test io-1.8 {Tcl_WriteChars: WriteChars} {
+ # This test written for SF bug #506297.
+ #
+ # Executing this test without the fix for the referenced bug
+ # applied to tcl will cause tcl, more specifically WriteChars, to
+ # go into an infinite loop.
+
+ set f [open $path(test2) w]
+ fconfigure $f -encoding iso2022-jp
+ puts -nonewline $f [format %s%c [string repeat " " 4] 12399]
+ close $f
+ contents $path(test2)
+} " \x1b\$B\$O\x1b(B"
+
+test io-1.9 {Tcl_WriteChars: WriteChars} {
+ # When closing a channel with an encoding that appends
+ # escape bytes, check for the case where the escape
+ # bytes overflow the current IO buffer. The bytes
+ # should be moved into a new buffer.
+
+ set data "1234567890 [format %c 12399]"
+
+ set sizes [list]
+
+ # With default buffer size
+ set f [open $path(test2) w]
+ fconfigure $f -encoding iso2022-jp
+ puts -nonewline $f $data
+ close $f
+ lappend sizes [file size $path(test2)]
+
+ # With buffer size equal to the length
+ # of the data, the escape bytes would
+ # go into the next buffer.
+
+ set f [open $path(test2) w]
+ fconfigure $f -encoding iso2022-jp -buffersize 16
+ puts -nonewline $f $data
+ close $f
+ lappend sizes [file size $path(test2)]
+
+ # With buffer size that is large enough
+ # to hold 1 byte of escaped data, but
+ # not all 3. This should not write
+ # the escape bytes to the first buffer
+ # and then again to the second buffer.
+
+ set f [open $path(test2) w]
+ fconfigure $f -encoding iso2022-jp -buffersize 17
+ puts -nonewline $f $data
+ close $f
+ lappend sizes [file size $path(test2)]
+
+ # With buffer size that can hold 2 out of
+ # 3 bytes of escaped data.
+
+ set f [open $path(test2) w]
+ fconfigure $f -encoding iso2022-jp -buffersize 18
+ puts -nonewline $f $data
+ close $f
+ lappend sizes [file size $path(test2)]
+
+ # With buffer size that can hold all the
+ # data and escape bytes.
+
+ set f [open $path(test2) w]
+ fconfigure $f -encoding iso2022-jp -buffersize 19
+ puts -nonewline $f $data
+ close $f
+ lappend sizes [file size $path(test2)]
+
+ set sizes
+} {19 19 19 19 19}
+
+test io-2.1 {WriteBytes} {
+ # loop until all bytes are written
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding binary -buffersize 16 -translation crlf
+ puts $f "abcdefghijklmnopqrstuvwxyz"
+ close $f
+ contents $path(test1)
+} "abcdefghijklmnopqrstuvwxyz\r\n"
+test io-2.2 {WriteBytes: savedLF > 0} {
+ # After flushing buffer, there was a \n left over from the last
+ # \n -> \r\n expansion. It gets stuck at beginning of this buffer.
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding binary -buffersize 16 -translation crlf
+ puts -nonewline $f "123456789012345\n12"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "123456789012345\r" "123456789012345\r\n12"]
+test io-2.3 {WriteBytes: flush on line} {
+ # Tcl "line" buffering has weird behavior: if current buffer contains
+ # a \n, entire buffer gets flushed. Logical behavior would be to flush
+ # only up to the \n.
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding binary -buffering line -translation crlf
+ puts -nonewline $f "\n12"
+ set x [contents $path(test1)]
+ close $f
+ set x
+} "\r\n12"
+test io-2.4 {WriteBytes: reset sawLF after each buffer} {
+ set f [open $path(test1) w]
+ fconfigure $f -encoding binary -buffering line -translation lf \
+ -buffersize 16
+ puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]
+
+test io-3.1 {WriteChars: compatibility with WriteBytes} {
+ # loop until all bytes are written
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding ascii -buffersize 16 -translation crlf
+ puts $f "abcdefghijklmnopqrstuvwxyz"
+ close $f
+ contents $path(test1)
+} "abcdefghijklmnopqrstuvwxyz\r\n"
+test io-3.2 {WriteChars: compatibility with WriteBytes: savedLF > 0} {
+ # After flushing buffer, there was a \n left over from the last
+ # \n -> \r\n expansion. It gets stuck at beginning of this buffer.
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding ascii -buffersize 16 -translation crlf
+ puts -nonewline $f "123456789012345\n12"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "123456789012345\r" "123456789012345\r\n12"]
+test io-3.3 {WriteChars: compatibility with WriteBytes: flush on line} {
+ # Tcl "line" buffering has weird behavior: if current buffer contains
+ # a \n, entire buffer gets flushed. Logical behavior would be to flush
+ # only up to the \n.
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding ascii -buffering line -translation crlf
+ puts -nonewline $f "\n12"
+ set x [contents $path(test1)]
+ close $f
+ set x
+} "\r\n12"
+test io-3.4 {WriteChars: loop over stage buffer} {
+ # stage buffer maps to more than can be queued at once.
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding jis0208 -buffersize 16
+ puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test io-3.5 {WriteChars: saved != 0} {
+ # Bytes produced by UtfToExternal from end of last channel buffer
+ # had to be moved to beginning of next channel buffer to preserve
+ # requested buffersize.
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding jis0208 -buffersize 17
+ puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test io-3.6 {WriteChars: (stageRead + dstWrote == 0)} {
+ # One incomplete UTF-8 character at end of staging buffer. Backup
+ # in src to the beginning of that UTF-8 character and try again.
+ #
+ # Translate the first 16 bytes, produce 14 bytes of output, 2 left over
+ # (first two bytes of \uff21 in UTF-8). Given those two bytes try
+ # translating them again, find that no bytes are read produced, and break
+ # to outer loop where those two bytes will have the remaining 4 bytes
+ # (the last byte of \uff21 plus the all of \uff22) appended.
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding shiftjis -buffersize 16
+ puts -nonewline $f "12345678901234\uff21\uff22"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "12345678901234\x82\x60" "12345678901234\x82\x60\x82\x61"]
+test io-3.7 {WriteChars: (bufPtr->nextAdded > bufPtr->length)} {
+ # When translating UTF-8 to external, the produced bytes went past end
+ # of the channel buffer. This is done purpose -- we then truncate the
+ # bytes at the end of the partial character to preserve the requested
+ # blocksize on flush. The truncated bytes are moved to the beginning
+ # of the next channel buffer.
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding jis0208 -buffersize 17
+ puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test io-3.8 {WriteChars: reset sawLF after each buffer} {
+ set f [open $path(test1) w]
+ fconfigure $f -encoding ascii -buffering line -translation lf \
+ -buffersize 16
+ puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]
+
+test io-4.1 {TranslateOutputEOL: lf} {
+ # search for \n
+
+ set f [open $path(test1) w]
+ fconfigure $f -buffering line -translation lf
+ puts $f "abcde"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "abcde\n" "abcde\n"]
+test io-4.2 {TranslateOutputEOL: cr} {
+ # search for \n, replace with \r
+
+ set f [open $path(test1) w]
+ fconfigure $f -buffering line -translation cr
+ puts $f "abcde"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "abcde\r" "abcde\r"]
+test io-4.3 {TranslateOutputEOL: crlf} {
+ # simple case: search for \n, replace with \r
+
+ set f [open $path(test1) w]
+ fconfigure $f -buffering line -translation crlf
+ puts $f "abcde"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "abcde\r\n" "abcde\r\n"]
+test io-4.4 {TranslateOutputEOL: crlf} {
+ # keep storing more bytes in output buffer until output buffer is full.
+ # We have 13 bytes initially that would turn into 18 bytes. Fill
+ # dest buffer while (dstEnd < dstMax).
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -buffersize 16
+ puts -nonewline $f "1234567\n\n\n\n\nA"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "1234567\r\n\r\n\r\n\r\n\r" "1234567\r\n\r\n\r\n\r\n\r\nA"]
+test io-4.5 {TranslateOutputEOL: crlf} {
+ # Check for overflow of the destination buffer
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -buffersize 12
+ puts -nonewline $f "12345678901\n456789012345678901234"
+ close $f
+ set x [contents $path(test1)]
+} "12345678901\r\n456789012345678901234"
+
+test io-5.1 {CheckFlush: not full} {
+ set f [open $path(test1) w]
+ fconfigure $f
+ puts -nonewline $f "12345678901234567890"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "" "12345678901234567890"]
+test io-5.2 {CheckFlush: full} {
+ set f [open $path(test1) w]
+ fconfigure $f -buffersize 16
+ puts -nonewline $f "12345678901234567890"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "1234567890123456" "12345678901234567890"]
+test io-5.3 {CheckFlush: not line} {
+ set f [open $path(test1) w]
+ fconfigure $f -buffering line
+ puts -nonewline $f "12345678901234567890"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "" "12345678901234567890"]
+test io-5.4 {CheckFlush: line} {
+ set f [open $path(test1) w]
+ fconfigure $f -buffering line -translation lf -encoding ascii
+ puts -nonewline $f "1234567890\n1234567890"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "1234567890\n1234567890" "1234567890\n1234567890"]
+test io-5.5 {CheckFlush: none} {
+ set f [open $path(test1) w]
+ fconfigure $f -buffering none
+ puts -nonewline $f "1234567890"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "1234567890" "1234567890"]
+
+test io-6.1 {Tcl_GetsObj: working} {
+ set f [open $path(test1) w]
+ puts $f "foo\nboo"
+ close $f
+ set f [open $path(test1)]
+ set x [gets $f]
+ close $f
+ set x
+} {foo}
+test io-6.2 {Tcl_GetsObj: CheckChannelErrors() != 0} emptyTest {
+ # no test, need to cause an async error.
+} {}
+test io-6.3 {Tcl_GetsObj: how many have we used?} {
+ # if (bufPtr != NULL) {oldRemoved = bufPtr->nextRemoved}
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f "abc\ndefg"
+ close $f
+ set f [open $path(test1)]
+ set x [list [tell $f] [gets $f line] [tell $f] [gets $f line] $line]
+ close $f
+ set x
+} {0 3 5 4 defg}
+test io-6.4 {Tcl_GetsObj: encoding == NULL} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation binary
+ puts $f "\x81\u1234\0"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation binary
+ set x [list [gets $f line] $line]
+ close $f
+ set x
+} [list 3 "\x81\x34\x00"]
+test io-6.5 {Tcl_GetsObj: encoding != NULL} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation binary
+ puts $f "\x88\xea\x92\x9a"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding shiftjis
+ set x [list [gets $f line] $line]
+ close $f
+ set x
+} [list 2 "\u4e00\u4e01"]
+set a "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
+append a $a
+append a $a
+test io-6.6 {Tcl_GetsObj: loop test} {
+ # if (dst >= dstEnd)
+
+ set f [open $path(test1) w]
+ puts $f $a
+ puts $f hi
+ close $f
+ set f [open $path(test1)]
+ set x [list [gets $f line] $line]
+ close $f
+ set x
+} [list 256 $a]
+test io-6.7 {Tcl_GetsObj: error in input} {stdio openpipe} {
+ # if (FilterInputBytes(chanPtr, &gs) != 0)
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ puts -nonewline $f "hi\nwould"
+ flush $f
+ gets $f
+ fconfigure $f -blocking 0
+ set x [gets $f line]
+ close $f
+ set x
+} {-1}
+test io-6.8 {Tcl_GetsObj: remember if EOF is seen} {
+ set f [open $path(test1) w]
+ puts $f "abcdef\x1aghijk\nwombat"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -eofchar \x1a
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {6 abcdef -1 {}}
+test io-6.9 {Tcl_GetsObj: remember if EOF is seen} {
+ set f [open $path(test1) w]
+ puts $f "abcdefghijk\nwom\u001abat"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -eofchar \x1a
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {11 abcdefghijk 3 wom}
+# Comprehensive tests
+test io-6.10 {Tcl_GetsObj: lf mode: no chars} {
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation lf
+ set x [list [gets $f line] $line]
+ close $f
+ set x
+} {-1 {}}
+test io-6.11 {Tcl_GetsObj: lf mode: lone \n} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation lf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {0 {} -1 {}}
+test io-6.12 {Tcl_GetsObj: lf mode: lone \r} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation lf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 1 "\r" -1 ""]
+test io-6.13 {Tcl_GetsObj: lf mode: 1 char} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f a
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation lf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {1 a -1 {}}
+test io-6.14 {Tcl_GetsObj: lf mode: 1 char followed by EOL} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation lf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {1 a -1 {}}
+test io-6.15 {Tcl_GetsObj: lf mode: several chars} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation lf
+ set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 4 "abcd" 10 "efgh\rijkl\r" 4 "mnop" -1 ""]
+test io-6.16 {Tcl_GetsObj: cr mode: no chars} {
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation cr
+ set x [list [gets $f line] $line]
+ close $f
+ set x
+} {-1 {}}
+test io-6.17 {Tcl_GetsObj: cr mode: lone \n} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation cr
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 1 "\n" -1 ""]
+test io-6.18 {Tcl_GetsObj: cr mode: lone \r} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation cr
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {0 {} -1 {}}
+test io-6.19 {Tcl_GetsObj: cr mode: 1 char} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f a
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation cr
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {1 a -1 {}}
+test io-6.20 {Tcl_GetsObj: cr mode: 1 char followed by EOL} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation cr
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {1 a -1 {}}
+test io-6.21 {Tcl_GetsObj: cr mode: several chars} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation cr
+ set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 9 "abcd\nefgh" 4 "ijkl" 5 "\nmnop" -1 ""]
+test io-6.22 {Tcl_GetsObj: crlf mode: no chars} {
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [list [gets $f line] $line]
+ close $f
+ set x
+} {-1 {}}
+test io-6.23 {Tcl_GetsObj: crlf mode: lone \n} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 1 "\n" -1 ""]
+test io-6.24 {Tcl_GetsObj: crlf mode: lone \r} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 1 "\r" -1 ""]
+test io-6.25 {Tcl_GetsObj: crlf mode: \r\r} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 2 "\r\r" -1 ""]
+test io-6.26 {Tcl_GetsObj: crlf mode: \r\n} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 0 "" -1 ""]
+test io-6.27 {Tcl_GetsObj: crlf mode: 1 char} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f a
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {1 a -1 {}}
+test io-6.28 {Tcl_GetsObj: crlf mode: 1 char followed by EOL} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\r\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {1 a -1 {}}
+test io-6.29 {Tcl_GetsObj: crlf mode: several chars} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 14 "abcd\nefgh\rijkl" 4 "mnop" -1 ""]
+test io-6.30 {Tcl_GetsObj: crlf mode: buffer exhausted} {testchannel} {
+ # if (eol >= dstEnd)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456789012345\r\nabcdefghijklmnoprstuvwxyz"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf -buffersize 16
+ set x [list [gets $f line] $line [testchannel inputbuffered $f]]
+ close $f
+ set x
+} [list 15 "123456789012345" 15]
+test io-6.31 {Tcl_GetsObj: crlf mode: buffer exhausted, blocked} {stdio testchannel openpipe fileevent} {
+ # (FilterInputBytes() != 0)
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {crlf lf} -buffering none
+ puts -nonewline $f "bbbbbbbbbbbbbb\r\n123456789012345\r"
+ fconfigure $f -buffersize 16
+ set x [gets $f]
+ fconfigure $f -blocking 0
+ lappend x [gets $f line] $line [fblocked $f] [testchannel inputbuffered $f]
+ close $f
+ set x
+} [list "bbbbbbbbbbbbbb" -1 "" 1 16]
+test io-6.32 {Tcl_GetsObj: crlf mode: buffer exhausted, more data} {testchannel} {
+ # not (FilterInputBytes() != 0)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456789012345\r\n123"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf -buffersize 16
+ set x [list [gets $f line] $line [tell $f] [testchannel inputbuffered $f]]
+ close $f
+ set x
+} [list 15 "123456789012345" 17 3]
+test io-6.33 {Tcl_GetsObj: crlf mode: buffer exhausted, at eof} {
+ # eol still equals dstEnd
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456789012345\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf -buffersize 16
+ set x [list [gets $f line] $line [eof $f]]
+ close $f
+ set x
+} [list 16 "123456789012345\r" 1]
+test io-6.34 {Tcl_GetsObj: crlf mode: buffer exhausted, not followed by \n} {
+ # not (*eol == '\n')
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456789012345\rabcd\r\nefg"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf -buffersize 16
+ set x [list [gets $f line] $line [tell $f]]
+ close $f
+ set x
+} [list 20 "123456789012345\rabcd" 22]
+test io-6.35 {Tcl_GetsObj: auto mode: no chars} {
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [gets $f line] $line]
+ close $f
+ set x
+} {-1 {}}
+test io-6.36 {Tcl_GetsObj: auto mode: lone \n} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 0 "" -1 ""]
+test io-6.37 {Tcl_GetsObj: auto mode: lone \r} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 0 "" -1 ""]
+test io-6.38 {Tcl_GetsObj: auto mode: \r\r} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 0 "" 0 "" -1 ""]
+test io-6.39 {Tcl_GetsObj: auto mode: \r\n} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 0 "" -1 ""]
+test io-6.40 {Tcl_GetsObj: auto mode: 1 char} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f a
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {1 a -1 {}}
+test io-6.41 {Tcl_GetsObj: auto mode: 1 char followed by EOL} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\r\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {1 a -1 {}}
+test io-6.42 {Tcl_GetsObj: auto mode: several chars} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [gets $f line] $line [gets $f line] $line]
+ lappend x [gets $f line] $line [gets $f line] $line [gets $f line] $line
+ close $f
+ set x
+} [list 4 "abcd" 4 "efgh" 4 "ijkl" 4 "mnop" -1 ""]
+test io-6.43 {Tcl_GetsObj: input saw cr} {stdio testchannel openpipe fileevent} {
+ # if (chanPtr->flags & INPUT_SAW_CR)
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {auto lf} -buffering none
+ puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+ fconfigure $f -buffersize 16
+ set x [list [gets $f]]
+ fconfigure $f -blocking 0
+ lappend x [gets $f line] $line [testchannel queuedcr $f]
+ fconfigure $f -blocking 1
+ puts -nonewline $f "\nabcd\refg\x1a"
+ lappend x [gets $f line] $line [testchannel queuedcr $f]
+ lappend x [gets $f line] $line
+ close $f
+ set x
+} [list "bbbbbbbbbbbbbbb" 15 "123456789abcdef" 1 4 "abcd" 0 3 "efg"]
+test io-6.44 {Tcl_GetsObj: input saw cr, not followed by cr} {stdio testchannel openpipe fileevent} {
+ # not (*eol == '\n')
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {auto lf} -buffering none
+ puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+ fconfigure $f -buffersize 16
+ set x [list [gets $f]]
+ fconfigure $f -blocking 0
+ lappend x [gets $f line] $line [testchannel queuedcr $f]
+ fconfigure $f -blocking 1
+ puts -nonewline $f "abcd\refg\x1a"
+ lappend x [gets $f line] $line [testchannel queuedcr $f]
+ lappend x [gets $f line] $line
+ close $f
+ set x
+} [list "bbbbbbbbbbbbbbb" 15 "123456789abcdef" 1 4 "abcd" 0 3 "efg"]
+test io-6.45 {Tcl_GetsObj: input saw cr, skip right number of bytes} {stdio testchannel openpipe fileevent} {
+ # Tcl_ExternalToUtf()
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {auto lf} -buffering none
+ fconfigure $f -encoding unicode
+ puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+ fconfigure $f -buffersize 16
+ gets $f
+ fconfigure $f -blocking 0
+ set x [list [gets $f line] $line [testchannel queuedcr $f]]
+ fconfigure $f -blocking 1
+ puts -nonewline $f "\nabcd\refg"
+ lappend x [gets $f line] $line [testchannel queuedcr $f]
+ close $f
+ set x
+} [list 15 "123456789abcdef" 1 4 "abcd" 0]
+test io-6.46 {Tcl_GetsObj: input saw cr, followed by just \n should give eof} {stdio testchannel openpipe fileevent} {
+ # memmove()
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {auto lf} -buffering none
+ puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+ fconfigure $f -buffersize 16
+ gets $f
+ fconfigure $f -blocking 0
+ set x [list [gets $f line] $line [testchannel queuedcr $f]]
+ fconfigure $f -blocking 1
+ puts -nonewline $f "\n\x1a"
+ lappend x [gets $f line] $line [testchannel queuedcr $f]
+ close $f
+ set x
+} [list 15 "123456789abcdef" 1 -1 "" 0]
+test io-6.47 {Tcl_GetsObj: auto mode: \r at end of buffer, peek for \n} {testchannel} {
+ # (eol == dstEnd)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456789012345\r\nabcdefghijklmnopq"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto -buffersize 16
+ set x [list [gets $f] [testchannel inputbuffered $f]]
+ close $f
+ set x
+} [list "123456789012345" 15]
+test io-6.48 {Tcl_GetsObj: auto mode: \r at end of buffer, no more avail} {testchannel} {
+ # PeekAhead() did not get any, so (eol >= dstEnd)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456789012345\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto -buffersize 16
+ set x [list [gets $f] [testchannel queuedcr $f]]
+ close $f
+ set x
+} [list "123456789012345" 1]
+test io-6.49 {Tcl_GetsObj: auto mode: \r followed by \n} {testchannel} {
+ # if (*eol == '\n') {skip++}
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456\r\n78901"
+ close $f
+ set f [open $path(test1)]
+ set x [list [gets $f] [testchannel queuedcr $f] [tell $f] [gets $f]]
+ close $f
+ set x
+} [list "123456" 0 8 "78901"]
+test io-6.50 {Tcl_GetsObj: auto mode: \r not followed by \n} {testchannel} {
+ # not (*eol == '\n')
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456\r78901"
+ close $f
+ set f [open $path(test1)]
+ set x [list [gets $f] [testchannel queuedcr $f] [tell $f] [gets $f]]
+ close $f
+ set x
+} [list "123456" 0 7 "78901"]
+test io-6.51 {Tcl_GetsObj: auto mode: \n} {
+ # else if (*eol == '\n') {goto gotoeol;}
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456\n78901"
+ close $f
+ set f [open $path(test1)]
+ set x [list [gets $f] [tell $f] [gets $f]]
+ close $f
+ set x
+} [list "123456" 7 "78901"]
+test io-6.52 {Tcl_GetsObj: saw EOF character} {testchannel} {
+ # if (eof != NULL)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456\x1ak9012345\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -eofchar \x1a
+ set x [list [gets $f] [testchannel queuedcr $f] [tell $f] [gets $f]]
+ close $f
+ set x
+} [list "123456" 0 6 ""]
+test io-6.53 {Tcl_GetsObj: device EOF} {
+ # didn't produce any bytes
+
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1)]
+ set x [list [gets $f line] $line [eof $f]]
+ close $f
+ set x
+} {-1 {} 1}
+test io-6.54 {Tcl_GetsObj: device EOF} {
+ # got some bytes before EOF.
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abc
+ close $f
+ set f [open $path(test1)]
+ set x [list [gets $f line] $line [eof $f]]
+ close $f
+ set x
+} {3 abc 1}
+test io-6.55 {Tcl_GetsObj: overconverted} {
+ # Tcl_ExternalToUtf(), make sure state updated
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding iso2022-jp
+ puts $f "there\u4e00ok\n\u4e01more bytes\nhere"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding iso2022-jp
+ set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 8 "there\u4e00ok" 11 "\u4e01more bytes" 4 "here"]
+test io-6.56 {Tcl_GetsObj: incomplete lines should disable file events} {stdio openpipe fileevent} {
+ update
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -buffering none
+ puts -nonewline $f "foobar"
+ fconfigure $f -blocking 0
+ variable x {}
+ after 500 [namespace code { lappend x timeout }]
+ fileevent $f readable [namespace code { lappend x [gets $f] }]
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ fconfigure $f -blocking 1
+ puts -nonewline $f "baz\n"
+ after 500 [namespace code { lappend x timeout }]
+ fconfigure $f -blocking 0
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ close $f
+ set x
+} {{} timeout foobarbaz timeout}
+
+test io-7.1 {FilterInputBytes: split up character at end of buffer} {
+ # (result == TCL_CONVERT_MULTIBYTE)
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding shiftjis
+ puts $f "1234567890123\uff10\uff11\uff12\uff13\uff14\nend"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding shiftjis -buffersize 16
+ set x [gets $f]
+ close $f
+ set x
+} "1234567890123\uff10\uff11\uff12\uff13\uff14"
+test io-7.2 {FilterInputBytes: split up character in middle of buffer} {
+ # (bufPtr->nextAdded < bufPtr->bufLength)
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding binary
+ puts -nonewline $f "1234567890\n123\x82\x4f\x82\x50\x82"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding shiftjis
+ set x [list [gets $f line] $line [eof $f]]
+ close $f
+ set x
+} [list 10 "1234567890" 0]
+test io-7.3 {FilterInputBytes: split up character at EOF} {testchannel} {
+ set f [open $path(test1) w]
+ fconfigure $f -encoding binary
+ puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding shiftjis
+ set x [list [gets $f line] $line]
+ lappend x [tell $f] [testchannel inputbuffered $f] [eof $f]
+ lappend x [gets $f line] $line
+ close $f
+ set x
+} [list 15 "1234567890123\uff10\uff11" 18 0 1 -1 ""]
+test io-7.4 {FilterInputBytes: recover from split up character} {stdio openpipe fileevent} {
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -encoding binary -buffering none
+ puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
+ fconfigure $f -encoding shiftjis -blocking 0
+ fileevent $f read [namespace code "ready $f"]
+ variable x {}
+ proc ready {f} {
+ variable x
+ lappend x [gets $f line] $line [fblocked $f]
+ }
+ vwait [namespace which -variable x]
+ fconfigure $f -encoding binary -blocking 1
+ puts $f "\x51\x82\x52"
+ fconfigure $f -encoding shiftjis
+ vwait [namespace which -variable x]
+ close $f
+ set x
+} [list -1 "" 1 17 "1234567890123\uff10\uff11\uff12\uff13" 0]
+
+test io-8.1 {PeekAhead: only go to device if no more cached data} {testchannel} {
+ # (bufPtr->nextPtr == NULL)
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding ascii -translation lf
+ puts -nonewline $f "123456789012345\r\n2345678"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding ascii -translation auto -buffersize 16
+ # here
+ gets $f
+ set x [testchannel inputbuffered $f]
+ close $f
+ set x
+} "7"
+test io-8.2 {PeekAhead: only go to device if no more cached data} {stdio testchannel openpipe fileevent} {
+ # not (bufPtr->nextPtr == NULL)
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation lf -encoding ascii -buffering none
+ puts -nonewline $f "123456789012345\r\nbcdefghijklmnopqrstuvwxyz"
+ variable x {}
+ fileevent $f read [namespace code "ready $f"]
+ proc ready {f} {
+ variable x
+ lappend x [gets $f line] $line [testchannel inputbuffered $f]
+ }
+ fconfigure $f -encoding unicode -buffersize 16 -blocking 0
+ vwait [namespace which -variable x]
+ fconfigure $f -translation auto -encoding ascii -blocking 1
+ # here
+ vwait [namespace which -variable x]
+ close $f
+ set x
+} [list -1 "" 42 15 "123456789012345" 25]
+test io-8.3 {PeekAhead: no cached data available} {stdio testchannel openpipe fileevent} {
+ # (bytesLeft == 0)
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {auto binary}
+ puts -nonewline $f "abcdefghijklmno\r"
+ flush $f
+ set x [list [gets $f line] $line [testchannel queuedcr $f]]
+ close $f
+ set x
+} [list 15 "abcdefghijklmno" 1]
+set a "123456789012345678901234567890"
+append a "123456789012345678901234567890"
+append a "1234567890123456789012345678901"
+test io-8.4 {PeekAhead: cached data available in this buffer} {
+ # not (bytesLeft == 0)
+
+ set f [open $path(test1) w+]
+ fconfigure $f -translation binary
+ puts $f "${a}\r\nabcdef"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding binary -translation auto
+
+ # "${a}\r" was converted in one operation (because ENCODING_LINESIZE
+ # is 30). To check if "\n" follows, calls PeekAhead and determines
+ # that cached data is available in buffer w/o having to call driver.
+
+ set x [gets $f]
+ close $f
+ set x
+} $a
+unset a
+test io-8.5 {PeekAhead: don't peek if last read was short} {stdio testchannel openpipe fileevent} {
+ # (bufPtr->nextAdded < bufPtr->length)
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {auto binary}
+ puts -nonewline $f "abcdefghijklmno\r"
+ flush $f
+ # here
+ set x [list [gets $f line] $line [testchannel queuedcr $f]]
+ close $f
+ set x
+} {15 abcdefghijklmno 1}
+test io-8.6 {PeekAhead: change to non-blocking mode} {stdio testchannel openpipe fileevent} {
+ # ((chanPtr->flags & CHANNEL_NONBLOCKING) == 0)
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {auto binary} -buffersize 16
+ puts -nonewline $f "abcdefghijklmno\r"
+ flush $f
+ # here
+ set x [list [gets $f line] $line [testchannel queuedcr $f]]
+ close $f
+ set x
+} {15 abcdefghijklmno 1}
+test io-8.7 {PeekAhead: cleanup} {stdio testchannel openpipe fileevent} {
+ # Make sure bytes are removed from buffer.
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {auto binary} -buffering none
+ puts -nonewline $f "abcdefghijklmno\r"
+ # here
+ set x [list [gets $f line] $line [testchannel queuedcr $f]]
+ puts -nonewline $f "\x1a"
+ lappend x [gets $f line] $line
+ close $f
+ set x
+} {15 abcdefghijklmno 1 -1 {}}
+
+test io-9.1 {CommonGetsCleanup} emptyTest {
+} {}
+
+test io-10.1 {Tcl_ReadChars: CheckChannelErrors} emptyTest {
+ # no test, need to cause an async error.
+} {}
+test io-10.2 {Tcl_ReadChars: loop until enough copied} {
+ # one time
+ # for (copied = 0; (unsigned) toRead > 0; )
+
+ set f [open $path(test1) w]
+ puts $f abcdefghijklmnop
+ close $f
+
+ set f [open $path(test1)]
+ set x [read $f 5]
+ close $f
+ set x
+} {abcde}
+test io-10.3 {Tcl_ReadChars: loop until enough copied} {
+ # multiple times
+ # for (copied = 0; (unsigned) toRead > 0; )
+
+ set f [open $path(test1) w]
+ puts $f abcdefghijklmnopqrstuvwxyz
+ close $f
+
+ set f [open $path(test1)]
+ fconfigure $f -buffersize 16
+ # here
+ set x [read $f 19]
+ close $f
+ set x
+} {abcdefghijklmnopqrs}
+test io-10.4 {Tcl_ReadChars: no more in channel buffer} {
+ # (copiedNow < 0)
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abcdefghijkl
+ close $f
+
+ set f [open $path(test1)]
+ # here
+ set x [read $f 1000]
+ close $f
+ set x
+} {abcdefghijkl}
+test io-10.5 {Tcl_ReadChars: stop on EOF} {
+ # (chanPtr->flags & CHANNEL_EOF)
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abcdefghijkl
+ close $f
+
+ set f [open $path(test1)]
+ # here
+ set x [read $f 1000]
+ close $f
+ set x
+} {abcdefghijkl}
+
+test io-11.1 {ReadBytes: want to read a lot} {
+ # ((unsigned) toRead > (unsigned) srcLen)
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abcdefghijkl
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding binary
+ # here
+ set x [read $f 1000]
+ close $f
+ set x
+} {abcdefghijkl}
+test io-11.2 {ReadBytes: want to read all} {
+ # ((unsigned) toRead > (unsigned) srcLen)
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abcdefghijkl
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding binary
+ # here
+ set x [read $f]
+ close $f
+ set x
+} {abcdefghijkl}
+test io-11.3 {ReadBytes: allocate more space} {
+ # (toRead > length - offset - 1)
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abcdefghijklmnopqrstuvwxyz
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -buffersize 16 -encoding binary
+ # here
+ set x [read $f]
+ close $f
+ set x
+} {abcdefghijklmnopqrstuvwxyz}
+test io-11.4 {ReadBytes: EOF char found} {
+ # (TranslateInputEOL() != 0)
+
+ set f [open $path(test1) w]
+ puts $f abcdefghijklmnopqrstuvwxyz
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -eofchar m -encoding binary
+ # here
+ set x [list [read $f] [eof $f] [read $f] [eof $f]]
+ close $f
+ set x
+} [list "abcdefghijkl" 1 "" 1]
+
+test io-12.1 {ReadChars: want to read a lot} {
+ # ((unsigned) toRead > (unsigned) srcLen)
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abcdefghijkl
+ close $f
+ set f [open $path(test1)]
+ # here
+ set x [read $f 1000]
+ close $f
+ set x
+} {abcdefghijkl}
+test io-12.2 {ReadChars: want to read all} {
+ # ((unsigned) toRead > (unsigned) srcLen)
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abcdefghijkl
+ close $f
+ set f [open $path(test1)]
+ # here
+ set x [read $f]
+ close $f
+ set x
+} {abcdefghijkl}
+test io-12.3 {ReadChars: allocate more space} {
+ # (toRead > length - offset - 1)
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abcdefghijklmnopqrstuvwxyz
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -buffersize 16
+ # here
+ set x [read $f]
+ close $f
+ set x
+} {abcdefghijklmnopqrstuvwxyz}
+test io-12.4 {ReadChars: split-up char} {stdio testchannel openpipe fileevent} {
+ # (srcRead == 0)
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -encoding binary -buffering none -buffersize 16
+ puts -nonewline $f "123456789012345\x96"
+ fconfigure $f -encoding shiftjis -blocking 0
+
+ fileevent $f read [namespace code "ready $f"]
+ proc ready {f} {
+ variable x
+ lappend x [read $f] [testchannel inputbuffered $f]
+ }
+ variable x {}
+
+ fconfigure $f -encoding shiftjis
+ vwait [namespace which -variable x]
+ fconfigure $f -encoding binary -blocking 1
+ puts -nonewline $f "\x7b"
+ after 500 ;# Give the cat process time to catch up
+ fconfigure $f -encoding shiftjis -blocking 0
+ vwait [namespace which -variable x]
+ close $f
+ set x
+} [list "123456789012345" 1 "\u672c" 0]
+test io-12.5 {ReadChars: fileevents on partial characters} {stdio openpipe fileevent} {
+ set path(test1) [makeFile {
+ fconfigure stdout -encoding binary -buffering none
+ gets stdin; puts -nonewline "\xe7"
+ gets stdin; puts -nonewline "\x89"
+ gets stdin; puts -nonewline "\xa6"
+ } test1]
+ set f [open "|[list [interpreter] $path(test1)]" r+]
+ fileevent $f readable [namespace code {
+ lappend x [read $f]
+ if {[eof $f]} {
+ lappend x eof
+ }
+ }]
+ puts $f "go1"
+ flush $f
+ fconfigure $f -blocking 0 -encoding utf-8
+ variable x {}
+ vwait [namespace which -variable x]
+ after 500 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ puts $f "go2"
+ flush $f
+ vwait [namespace which -variable x]
+ after 500 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ puts $f "go3"
+ flush $f
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ lappend x [catch {close $f} msg] $msg
+ set x
+} "{} timeout {} timeout \u7266 {} eof 0 {}"
+
+test io-13.1 {TranslateInputEOL: cr mode} {} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\rdef\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation cr
+ set x [read $f]
+ close $f
+ set x
+} "abcd\ndef\n"
+test io-13.2 {TranslateInputEOL: crlf mode} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\r\ndef\r\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [read $f]
+ close $f
+ set x
+} "abcd\ndef\n"
+test io-13.3 {TranslateInputEOL: crlf mode: naked cr} {
+ # (src >= srcMax)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\r\ndef\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [read $f]
+ close $f
+ set x
+} "abcd\ndef\r"
+test io-13.4 {TranslateInputEOL: crlf mode: cr followed by not \n} {
+ # (src >= srcMax)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\r\ndef\rfgh"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [read $f]
+ close $f
+ set x
+} "abcd\ndef\rfgh"
+test io-13.5 {TranslateInputEOL: crlf mode: naked lf} {
+ # (src >= srcMax)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\r\ndef\nfgh"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [read $f]
+ close $f
+ set x
+} "abcd\ndef\nfgh"
+test io-13.6 {TranslateInputEOL: auto mode: saw cr in last segment} {stdio testchannel openpipe fileevent} {
+ # (chanPtr->flags & INPUT_SAW_CR)
+ # This test may fail on slower machines.
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -blocking 0 -buffering none -translation {auto lf}
+
+ fileevent $f read [namespace code "ready $f"]
+ proc ready {f} {
+ variable x
+ lappend x [read $f] [testchannel queuedcr $f]
+ }
+ variable x {}
+ variable y {}
+
+ puts -nonewline $f "abcdefghj\r"
+ after 500 [namespace code {set y ok}]
+ vwait [namespace which -variable y]
+
+ puts -nonewline $f "\n01234"
+ after 500 [namespace code {set y ok}]
+ vwait [namespace which -variable y]
+
+ close $f
+ set x
+} [list "abcdefghj\n" 1 "01234" 0]
+test io-13.7 {TranslateInputEOL: auto mode: naked \r} {testchannel openpipe} {
+ # (src >= srcMax)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [read $f] [testchannel queuedcr $f]]
+ close $f
+ set x
+} [list "abcd\n" 1]
+test io-13.8 {TranslateInputEOL: auto mode: \r\n} {
+ # (*src == '\n')
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\r\ndef"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [read $f]
+ close $f
+ set x
+} "abcd\ndef"
+test io-13.9 {TranslateInputEOL: auto mode: \r followed by not \n} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\rdef"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [read $f]
+ close $f
+ set x
+} "abcd\ndef"
+test io-13.10 {TranslateInputEOL: auto mode: \n} {
+ # not (*src == '\r')
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\ndef"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [read $f]
+ close $f
+ set x
+} "abcd\ndef"
+test io-13.11 {TranslateInputEOL: EOF char} {
+ # (*chanPtr->inEofChar != '\0')
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\ndefgh"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto -eofchar e
+ set x [read $f]
+ close $f
+ set x
+} "abcd\nd"
+test io-13.12 {TranslateInputEOL: find EOF char in src} {
+ # (*chanPtr->inEofChar != '\0')
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r\n\r\n\r\nab\r\n\r\ndef\r\n\r\n\r\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto -eofchar e
+ set x [read $f]
+ close $f
+ set x
+} "\n\n\nab\n\nd"
+
+# Test standard handle management. The functions tested are
+# Tcl_SetStdChannel and Tcl_GetStdChannel. Incidentally we are
+# also testing channel table management.
+
+if {[info commands testchannel] != ""} {
+ set consoleFileNames [lsort [testchannel open]]
+} else {
+ # just to avoid an error
+ set consoleFileNames [list]
+}
+
+test io-14.1 {Tcl_SetStdChannel and Tcl_GetStdChannel} {testchannel} {
+ set l ""
+ lappend l [fconfigure stdin -buffering]
+ lappend l [fconfigure stdout -buffering]
+ lappend l [fconfigure stderr -buffering]
+ lappend l [lsort [testchannel open]]
+ set l
+} [list line line none $consoleFileNames]
+test io-14.2 {Tcl_SetStdChannel and Tcl_GetStdChannel} {
+ interp create x
+ set l ""
+ lappend l [x eval {fconfigure stdin -buffering}]
+ lappend l [x eval {fconfigure stdout -buffering}]
+ lappend l [x eval {fconfigure stderr -buffering}]
+ interp delete x
+ set l
+} {line line none}
+set path(test3) [makeFile {} test3]
+test io-14.3 {Tcl_SetStdChannel & Tcl_GetStdChannel} {exec openpipe} {
+ set f [open $path(test1) w]
+ puts -nonewline $f {
+ close stdin
+ close stdout
+ close stderr
+ set f [}
+ puts $f [list open $path(test1) r]]
+ puts $f "set f2 \[[list open $path(test2) w]]"
+ puts $f "set f3 \[[list open $path(test3) w]]"
+ puts $f { puts stdout [gets stdin]
+ puts stdout out
+ puts stderr err
+ close $f
+ close $f2
+ close $f3
+ }
+ close $f
+ set result [exec [interpreter] $path(test1)]
+ set f [open $path(test2) r]
+ set f2 [open $path(test3) r]
+ lappend result [read $f] [read $f2]
+ close $f
+ close $f2
+ set result
+} {{
+out
+} {err
+}}
+# This test relies on the fact that stdout is used before stderr
+test io-14.4 {Tcl_SetStdChannel & Tcl_GetStdChannel} {exec} {
+ set f [open $path(test1) w]
+ puts -nonewline $f { close stdin
+ close stdout
+ close stderr
+ set f [}
+ puts $f [list open $path(test1) r]]
+ puts $f "set f2 \[[list open $path(test2) w]]"
+ puts $f "set f3 \[[list open $path(test3) w]]"
+ puts $f { puts stdout [gets stdin]
+ puts stdout $f2
+ puts stderr $f3
+ close $f
+ close $f2
+ close $f3
+ }
+ close $f
+ set result [exec [interpreter] $path(test1)]
+ set f [open $path(test2) r]
+ set f2 [open $path(test3) r]
+ lappend result [read $f] [read $f2]
+ close $f
+ close $f2
+ set result
+} {{ close stdin
+stdout
+} {stderr
+}}
+catch {interp delete z}
+test io-14.5 {Tcl_GetChannel: stdio name translation} {
+ interp create z
+ eof stdin
+ catch {z eval flush stdin} msg1
+ catch {z eval close stdin} msg2
+ catch {z eval flush stdin} msg3
+ set result [list $msg1 $msg2 $msg3]
+ interp delete z
+ set result
+} {{channel "stdin" wasn't opened for writing} {} {can not find channel named "stdin"}}
+test io-14.6 {Tcl_GetChannel: stdio name translation} {
+ interp create z
+ eof stdout
+ catch {z eval flush stdout} msg1
+ catch {z eval close stdout} msg2
+ catch {z eval flush stdout} msg3
+ set result [list $msg1 $msg2 $msg3]
+ interp delete z
+ set result
+} {{} {} {can not find channel named "stdout"}}
+test io-14.7 {Tcl_GetChannel: stdio name translation} {
+ interp create z
+ eof stderr
+ catch {z eval flush stderr} msg1
+ catch {z eval close stderr} msg2
+ catch {z eval flush stderr} msg3
+ set result [list $msg1 $msg2 $msg3]
+ interp delete z
+ set result
+} {{} {} {can not find channel named "stderr"}}
+set path(script) [makeFile {} script]
+test io-14.8 {reuse of stdio special channels} {stdio openpipe} {
+ file delete $path(script)
+ file delete $path(test1)
+ set f [open $path(script) w]
+ puts -nonewline $f {
+ close stderr
+ set f [}
+ puts $f [list open $path(test1) w]]
+ puts -nonewline $f {
+ puts stderr hello
+ close $f
+ set f [}
+ puts $f [list open $path(test1) r]]
+ puts $f {
+ puts [gets $f]
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ set c [gets $f]
+ close $f
+ set c
+} hello
+test io-14.9 {reuse of stdio special channels} {stdio openpipe fileevent} {
+ file delete $path(script)
+ file delete $path(test1)
+ set f [open $path(script) w]
+ puts $f {
+ array set path [lindex $argv 0]
+ set f [open $path(test1) w]
+ puts $f hello
+ close $f
+ close stderr
+ set f [open "|[list [info nameofexecutable] $path(cat) $path(test1)]" r]
+ puts [gets $f]
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script) [array get path]]" r]
+ set c [gets $f]
+ close $f
+ # Added delay to give Windows time to stop the spawned process and clean
+ # up its grip on the file test1. Added delete as proper test cleanup.
+ # The failing tests were 18.1 and 18.2 as first re-users of file "test1".
+ after 10000
+ file delete $path(script)
+ file delete $path(test1)
+ set c
+} hello
+
+test io-15.1 {Tcl_CreateCloseHandler} emptyTest {
+} {}
+
+test io-16.1 {Tcl_DeleteCloseHandler} emptyTest {
+} {}
+
+# Test channel table management. The functions tested are
+# GetChannelTable, DeleteChannelTable, Tcl_RegisterChannel,
+# Tcl_UnregisterChannel, Tcl_GetChannel and Tcl_CreateChannel.
+#
+# These functions use "eof stdin" to ensure that the standard
+# channels are added to the channel table of the interpreter.
+
+test io-17.1 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} {
+ set l1 [testchannel refcount stdin]
+ eof stdin
+ interp create x
+ set l ""
+ lappend l [expr [testchannel refcount stdin] - $l1]
+ x eval {eof stdin}
+ lappend l [expr [testchannel refcount stdin] - $l1]
+ interp delete x
+ lappend l [expr [testchannel refcount stdin] - $l1]
+ set l
+} {0 1 0}
+test io-17.2 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} {
+ set l1 [testchannel refcount stdout]
+ eof stdin
+ interp create x
+ set l ""
+ lappend l [expr [testchannel refcount stdout] - $l1]
+ x eval {eof stdout}
+ lappend l [expr [testchannel refcount stdout] - $l1]
+ interp delete x
+ lappend l [expr [testchannel refcount stdout] - $l1]
+ set l
+} {0 1 0}
+test io-17.3 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} {
+ set l1 [testchannel refcount stderr]
+ eof stdin
+ interp create x
+ set l ""
+ lappend l [expr [testchannel refcount stderr] - $l1]
+ x eval {eof stderr}
+ lappend l [expr [testchannel refcount stderr] - $l1]
+ interp delete x
+ lappend l [expr [testchannel refcount stderr] - $l1]
+ set l
+} {0 1 0}
+
+test io-18.1 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {testchannel} {
+ file delete -force $path(test1)
+ set l ""
+ set f [open $path(test1) w]
+ lappend l [lindex [testchannel info $f] 15]
+ close $f
+ if {[catch {lindex [testchannel info $f] 15} msg]} {
+ lappend l $msg
+ } else {
+ lappend l "very broken: $f found after being closed"
+ }
+ string compare [string tolower $l] \
+ [list 1 [format "can not find channel named \"%s\"" $f]]
+} 0
+test io-18.2 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {testchannel} {
+ file delete -force $path(test1)
+ set l ""
+ set f [open $path(test1) w]
+ lappend l [lindex [testchannel info $f] 15]
+ interp create x
+ interp share "" $f x
+ lappend l [lindex [testchannel info $f] 15]
+ x eval close $f
+ lappend l [lindex [testchannel info $f] 15]
+ interp delete x
+ lappend l [lindex [testchannel info $f] 15]
+ close $f
+ if {[catch {lindex [testchannel info $f] 15} msg]} {
+ lappend l $msg
+ } else {
+ lappend l "very broken: $f found after being closed"
+ }
+ string compare [string tolower $l] \
+ [list 1 2 1 1 [format "can not find channel named \"%s\"" $f]]
+} 0
+test io-18.3 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {testchannel} {
+ file delete $path(test1)
+ set l ""
+ set f [open $path(test1) w]
+ lappend l [lindex [testchannel info $f] 15]
+ interp create x
+ interp share "" $f x
+ lappend l [lindex [testchannel info $f] 15]
+ interp delete x
+ lappend l [lindex [testchannel info $f] 15]
+ close $f
+ if {[catch {lindex [testchannel info $f] 15} msg]} {
+ lappend l $msg
+ } else {
+ lappend l "very broken: $f found after being closed"
+ }
+ string compare [string tolower $l] \
+ [list 1 2 1 [format "can not find channel named \"%s\"" $f]]
+} 0
+
+test io-19.1 {Tcl_GetChannel->Tcl_GetStdChannel, standard handles} {
+ eof stdin
+} 0
+test io-19.2 {testing Tcl_GetChannel, user opened handle} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ set x [eof $f]
+ close $f
+ set x
+} 0
+test io-19.3 {Tcl_GetChannel, channel not found} {
+ list [catch {eof file34} msg] $msg
+} {1 {can not find channel named "file34"}}
+test io-19.4 {Tcl_CreateChannel, insertion into channel table} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ set l ""
+ lappend l [eof $f]
+ close $f
+ if {[catch {lindex [testchannel info $f] 15} msg]} {
+ lappend l $msg
+ } else {
+ lappend l "very broken: $f found after being closed"
+ }
+ string compare [string tolower $l] \
+ [list 0 [format "can not find channel named \"%s\"" $f]]
+} 0
+
+test io-20.1 {Tcl_CreateChannel: initial settings} {
+ set a [open $path(test2) w]
+ set old [encoding system]
+ encoding system ascii
+ set f [open $path(test1) w]
+ set x [fconfigure $f -encoding]
+ close $f
+ encoding system $old
+ close $a
+ set x
+} {ascii}
+test io-20.2 {Tcl_CreateChannel: initial settings} {win} {
+ set f [open $path(test1) w+]
+ set x [list [fconfigure $f -eofchar] [fconfigure $f -translation]]
+ close $f
+ set x
+} [list [list \x1a ""] {auto crlf}]
+test io-20.3 {Tcl_CreateChannel: initial settings} {unix} {
+ set f [open $path(test1) w+]
+ set x [list [fconfigure $f -eofchar] [fconfigure $f -translation]]
+ close $f
+ set x
+} {{{} {}} {auto lf}}
+set path(stdout) [makeFile {} stdout]
+test io-20.5 {Tcl_CreateChannel: install channel in empty slot} {stdio openpipe} {
+ set f [open $path(script) w]
+ puts -nonewline $f {
+ close stdout
+ set f1 [}
+ puts $f [list open $path(stdout) w]]
+ puts $f {
+ fconfigure $f1 -buffersize 777
+ puts stderr [fconfigure stdout -buffersize]
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]"]
+ catch {close $f} msg
+ set msg
+} {777}
+
+test io-21.1 {CloseChannelsOnExit} emptyTest {
+} {}
+
+# Test management of attributes associated with a channel, such as
+# its default translation, its name and type, etc. The functions
+# tested in this group are Tcl_GetChannelName,
+# Tcl_GetChannelType and Tcl_GetChannelFile. Tcl_GetChannelInstanceData
+# not tested because files do not use the instance data.
+
+test io-22.1 {Tcl_GetChannelMode} emptyTest {
+ # Not used anywhere in Tcl.
+} {}
+
+test io-23.1 {Tcl_GetChannelName} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ set n [testchannel name $f]
+ close $f
+ string compare $n $f
+} 0
+
+test io-24.1 {Tcl_GetChannelType} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ set t [testchannel type $f]
+ close $f
+ string compare $t file
+} 0
+
+test io-25.1 {Tcl_GetChannelHandle, input} {testchannel} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f "1234567890\n098765432"
+ close $f
+ set f [open $path(test1) r]
+ gets $f
+ set l ""
+ lappend l [testchannel inputbuffered $f]
+ lappend l [tell $f]
+ close $f
+ set l
+} {10 11}
+test io-25.2 {Tcl_GetChannelHandle, output} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello
+ set l ""
+ lappend l [testchannel outputbuffered $f]
+ lappend l [tell $f]
+ flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [tell $f]
+ close $f
+ file delete $path(test1)
+ set l
+} {6 6 0 6}
+
+test io-26.1 {Tcl_GetChannelInstanceData} {stdio openpipe} {
+ # "pid" command uses Tcl_GetChannelInstanceData
+ # Don't care what pid is (but must be a number), just want to exercise it.
+
+ set f [open "|[list [interpreter] << exit]"]
+ expr [pid $f]
+ close $f
+} {}
+
+# Test flushing. The functions tested here are FlushChannel.
+
+test io-27.1 {FlushChannel, no output buffered} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ flush $f
+ set s [file size $path(test1)]
+ close $f
+ set s
+} 0
+test io-27.2 {FlushChannel, some output buffered} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ set l ""
+ puts $f hello
+ lappend l [file size $path(test1)]
+ flush $f
+ lappend l [file size $path(test1)]
+ close $f
+ lappend l [file size $path(test1)]
+ set l
+} {0 6 6}
+test io-27.3 {FlushChannel, implicit flush on close} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ set l ""
+ puts $f hello
+ lappend l [file size $path(test1)]
+ close $f
+ lappend l [file size $path(test1)]
+ set l
+} {0 6}
+test io-27.4 {FlushChannel, implicit flush when buffer fills} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ fconfigure $f -buffersize 60
+ set l ""
+ lappend l [file size $path(test1)]
+ for {set i 0} {$i < 12} {incr i} {
+ puts $f hello
+ }
+ lappend l [file size $path(test1)]
+ flush $f
+ lappend l [file size $path(test1)]
+ close $f
+ set l
+} {0 60 72}
+test io-27.5 {FlushChannel, implicit flush when buffer fills and on close} \
+ {unixOrPc} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -buffersize 60 -eofchar {}
+ set l ""
+ lappend l [file size $path(test1)]
+ for {set i 0} {$i < 12} {incr i} {
+ puts $f hello
+ }
+ lappend l [file size $path(test1)]
+ close $f
+ lappend l [file size $path(test1)]
+ set l
+} {0 60 72}
+set path(pipe) [makeFile {} pipe]
+set path(output) [makeFile {} output]
+test io-27.6 {FlushChannel, async flushing, async close} \
+ {stdio asyncPipeClose openpipe} {
+ # This test may fail on old Unix systems (seen on IRIX64 6.5) with
+ # obsolete gettimeofday() calls. See Tcl Bugs 3530533, 1942197.
+ file delete $path(pipe)
+ file delete $path(output)
+ set f [open $path(pipe) w]
+ puts $f "set f \[[list open $path(output) w]]"
+ puts $f {
+ fconfigure $f -translation lf -buffering none -eofchar {}
+ while {![eof stdin]} {
+ after 20
+ puts -nonewline $f [read stdin 1024]
+ }
+ close $f
+ }
+ close $f
+ set x 01234567890123456789012345678901
+ for {set i 0} {$i < 11} {incr i} {
+ set x "$x$x"
+ }
+ set f [open $path(output) w]
+ close $f
+ set f [open "|[list [interpreter] $path(pipe)]" w]
+ fconfigure $f -blocking off
+ puts -nonewline $f $x
+ close $f
+ set counter 0
+ while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+ after 20 [list incr [namespace which -variable counter]]
+ vwait [namespace which -variable counter]
+ }
+ if {$counter == 1000} {
+ set result "file size only [file size $path(output)]"
+ } else {
+ set result ok
+ }
+} ok
+
+# Tests closing a channel. The functions tested are CloseChannel and Tcl_Close.
+
+test io-28.1 {CloseChannel called when all references are dropped} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ interp create x
+ interp share "" $f x
+ set l ""
+ lappend l [testchannel refcount $f]
+ x eval close $f
+ interp delete x
+ lappend l [testchannel refcount $f]
+ close $f
+ set l
+} {2 1}
+test io-28.2 {CloseChannel called when all references are dropped} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ interp create x
+ interp share "" $f x
+ puts -nonewline $f abc
+ close $f
+ x eval puts $f def
+ x eval close $f
+ interp delete x
+ set f [open $path(test1) r]
+ set l [gets $f]
+ close $f
+ set l
+} abcdef
+test io-28.3 {CloseChannel, not called before output queue is empty} \
+ {stdio asyncPipeClose nonPortable openpipe} {
+ file delete $path(pipe)
+ file delete $path(output)
+ set f [open $path(pipe) w]
+ puts $f {
+
+ # Need to not have eof char appended on close, because the other
+ # side of the pipe already closed, so that writing would cause an
+ # error "invalid file".
+
+ fconfigure stdout -eofchar {}
+ fconfigure stderr -eofchar {}
+
+ set f [open $path(output) w]
+ fconfigure $f -translation lf -buffering none
+ for {set x 0} {$x < 20} {incr x} {
+ after 20
+ puts -nonewline $f [read stdin 1024]
+ }
+ close $f
+ }
+ close $f
+ set x 01234567890123456789012345678901
+ for {set i 0} {$i < 11} {incr i} {
+ set x "$x$x"
+ }
+ set f [open $path(output) w]
+ close $f
+ set f [open "|[list [interpreter] pipe]" r+]
+ fconfigure $f -blocking off -eofchar {}
+
+ puts -nonewline $f $x
+ close $f
+ set counter 0
+ while {([file size $path(output)] < 20480) && ($counter < 1000)} {
+ after 20 [list incr [namespace which -variable counter]]
+ vwait [namespace which -variable counter]
+ }
+ if {$counter == 1000} {
+ set result probably_broken
+ } else {
+ set result ok
+ }
+} ok
+test io-28.4 {Tcl_Close} {testchannel} {
+ file delete $path(test1)
+ set l ""
+ lappend l [lsort [testchannel open]]
+ set f [open $path(test1) w]
+ lappend l [lsort [testchannel open]]
+ close $f
+ lappend l [lsort [testchannel open]]
+ set x [list $consoleFileNames \
+ [lsort [list {*}$consoleFileNames $f]] \
+ $consoleFileNames]
+ string compare $l $x
+} 0
+test io-28.5 {Tcl_Close vs standard handles} {stdio unix testchannel openpipe} {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f {
+ close stdin
+ puts [testchannel open]
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ set l [gets $f]
+ close $f
+ lsort $l
+} {file1 file2}
+
+test io-29.1 {Tcl_WriteChars, channel not writable} {
+ list [catch {puts stdin hello} msg] $msg
+} {1 {channel "stdin" wasn't opened for writing}}
+test io-29.2 {Tcl_WriteChars, empty string} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -eofchar {}
+ puts -nonewline $f ""
+ close $f
+ file size $path(test1)
+} 0
+test io-29.3 {Tcl_WriteChars, nonempty string} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -eofchar {}
+ puts -nonewline $f hello
+ close $f
+ file size $path(test1)
+} 5
+test io-29.4 {Tcl_WriteChars, buffering in full buffering mode} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -buffering full -eofchar {}
+ puts $f hello
+ set l ""
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ close $f
+ set l
+} {6 0 0 6}
+test io-29.5 {Tcl_WriteChars, buffering in line buffering mode} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -buffering line -eofchar {}
+ puts -nonewline $f hello
+ set l ""
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ close $f
+ set l
+} {5 0 0 11}
+test io-29.6 {Tcl_WriteChars, buffering in no buffering mode} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -buffering none -eofchar {}
+ puts -nonewline $f hello
+ set l ""
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ close $f
+ set l
+} {0 5 0 11}
+test io-29.7 {Tcl_Flush, full buffering} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -buffering full -eofchar {}
+ puts -nonewline $f hello
+ set l ""
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ close $f
+ set l
+} {5 0 11 0 0 11}
+test io-29.8 {Tcl_Flush, full buffering} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -buffering line
+ puts -nonewline $f hello
+ set l ""
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ close $f
+ set l
+} {5 0 0 5 0 11 0 11}
+test io-29.9 {Tcl_Flush, channel not writable} {
+ list [catch {flush stdin} msg] $msg
+} {1 {channel "stdin" wasn't opened for writing}}
+test io-29.10 {Tcl_WriteChars, looping and buffering} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ set f2 [open $path(longfile) r]
+ for {set x 0} {$x < 10} {incr x} {
+ puts $f1 [gets $f2]
+ }
+ close $f2
+ close $f1
+ file size $path(test1)
+} 387
+test io-29.11 {Tcl_WriteChars, no newline, implicit flush} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -eofchar {}
+ set f2 [open $path(longfile) r]
+ for {set x 0} {$x < 10} {incr x} {
+ puts -nonewline $f1 [gets $f2]
+ }
+ close $f1
+ close $f2
+ file size $path(test1)
+} 377
+test io-29.12 {Tcl_WriteChars on a pipe} {stdio openpipe} {
+ file delete $path(test1)
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 "set f1 \[[list open $path(longfile) r]]"
+ puts $f1 {
+ for {set x 0} {$x < 10} {incr x} {
+ puts [gets $f1]
+ }
+ }
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r]
+ set f2 [open $path(longfile) r]
+ set y ok
+ for {set x 0} {$x < 10} {incr x} {
+ set l1 [gets $f1]
+ set l2 [gets $f2]
+ if {"$l1" != "$l2"} {
+ set y broken
+ }
+ }
+ close $f1
+ close $f2
+ set y
+} ok
+test io-29.13 {Tcl_WriteChars to a pipe, line buffered} {stdio openpipe} {
+ file delete $path(test1)
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {
+ puts [gets stdin]
+ puts [gets stdin]
+ }
+ close $f1
+ set y ok
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ fconfigure $f1 -buffering line
+ set f2 [open $path(longfile) r]
+ set line [gets $f2]
+ puts $f1 $line
+ set backline [gets $f1]
+ if {"$line" != "$backline"} {
+ set y broken
+ }
+ set line [gets $f2]
+ puts $f1 $line
+ set backline [gets $f1]
+ if {"$line" != "$backline"} {
+ set y broken
+ }
+ close $f1
+ close $f2
+ set y
+} ok
+test io-29.14 {Tcl_WriteChars, buffering and implicit flush at close} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ puts -nonewline $f "Text1"
+ puts -nonewline $f " Text 2"
+ puts $f " Text 3"
+ close $f
+ set f [open $path(test3) r]
+ set x [gets $f]
+ close $f
+ set x
+} {Text1 Text 2 Text 3}
+test io-29.15 {Tcl_Flush, channel not open for writing} {
+ file delete $path(test1)
+ set fd [open $path(test1) w]
+ close $fd
+ set fd [open $path(test1) r]
+ set x [list [catch {flush $fd} msg] $msg]
+ close $fd
+ string compare $x \
+ [list 1 "channel \"$fd\" wasn't opened for writing"]
+} 0
+test io-29.16 {Tcl_Flush on pipe opened only for reading} {stdio openpipe} {
+ set fd [open "|[list [interpreter] cat longfile]" r]
+ set x [list [catch {flush $fd} msg] $msg]
+ catch {close $fd}
+ string compare $x \
+ [list 1 "channel \"$fd\" wasn't opened for writing"]
+} 0
+test io-29.17 {Tcl_WriteChars buffers, then Tcl_Flush flushes} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf
+ puts $f1 hello
+ puts $f1 hello
+ puts $f1 hello
+ flush $f1
+ set x [file size $path(test1)]
+ close $f1
+ set x
+} 18
+test io-29.18 {Tcl_WriteChars and Tcl_Flush intermixed} {
+ file delete $path(test1)
+ set x ""
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf
+ puts $f1 hello
+ puts $f1 hello
+ puts $f1 hello
+ flush $f1
+ lappend x [file size $path(test1)]
+ puts $f1 hello
+ flush $f1
+ lappend x [file size $path(test1)]
+ puts $f1 hello
+ flush $f1
+ lappend x [file size $path(test1)]
+ close $f1
+ set x
+} {18 24 30}
+test io-29.19 {Explicit and implicit flushes} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ set x ""
+ puts $f1 hello
+ puts $f1 hello
+ puts $f1 hello
+ flush $f1
+ lappend x [file size $path(test1)]
+ puts $f1 hello
+ flush $f1
+ lappend x [file size $path(test1)]
+ puts $f1 hello
+ close $f1
+ lappend x [file size $path(test1)]
+ set x
+} {18 24 30}
+test io-29.20 {Implicit flush when buffer is full} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ set line "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+ for {set x 0} {$x < 100} {incr x} {
+ puts $f1 $line
+ }
+ set z ""
+ lappend z [file size $path(test1)]
+ for {set x 0} {$x < 100} {incr x} {
+ puts $f1 $line
+ }
+ lappend z [file size $path(test1)]
+ close $f1
+ lappend z [file size $path(test1)]
+ set z
+} {4096 12288 12600}
+test io-29.21 {Tcl_Flush to pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {set x [read stdin 6]}
+ puts $f1 {set cnt [string length $x]}
+ puts $f1 {puts "read $cnt characters"}
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ puts $f1 hello
+ flush $f1
+ set x [gets $f1]
+ catch {close $f1}
+ set x
+} "read 6 characters"
+test io-29.22 {Tcl_Flush called at other end of pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {
+ fconfigure stdout -buffering full
+ puts hello
+ puts hello
+ flush stdout
+ gets stdin
+ puts bye
+ flush stdout
+ }
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ set x ""
+ lappend x [gets $f1]
+ lappend x [gets $f1]
+ puts $f1 hello
+ flush $f1
+ lappend x [gets $f1]
+ close $f1
+ set x
+} {hello hello bye}
+test io-29.23 {Tcl_Flush and line buffering at end of pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {
+ puts hello
+ puts hello
+ gets stdin
+ puts bye
+ }
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ set x ""
+ lappend x [gets $f1]
+ lappend x [gets $f1]
+ puts $f1 hello
+ flush $f1
+ lappend x [gets $f1]
+ close $f1
+ set x
+} {hello hello bye}
+test io-29.24 {Tcl_WriteChars and Tcl_Flush move end of file} {
+ set f [open $path(test3) w]
+ puts $f "Line 1"
+ puts $f "Line 2"
+ set f2 [open $path(test3)]
+ set x {}
+ lappend x [read -nonewline $f2]
+ close $f2
+ flush $f
+ set f2 [open $path(test3)]
+ lappend x [read -nonewline $f2]
+ close $f2
+ close $f
+ set x
+} "{} {Line 1\nLine 2}"
+test io-29.25 {Implicit flush with Tcl_Flush to command pipelines} {stdio openpipe fileevent} {
+ file delete $path(test3)
+ set f [open "|[list [interpreter] $path(cat) | [interpreter] $path(cat) > $path(test3)]" w]
+ puts $f "Line 1"
+ puts $f "Line 2"
+ close $f
+ after 100
+ set f [open $path(test3) r]
+ set x [read $f]
+ close $f
+ set x
+} "Line 1\nLine 2\n"
+test io-29.26 {Tcl_Flush, Tcl_Write on bidirectional pipelines} {stdio unixExecs openpipe} {
+ set f [open "|[list cat -u]" r+]
+ puts $f "Line1"
+ flush $f
+ set x [gets $f]
+ close $f
+ set x
+} {Line1}
+test io-29.27 {Tcl_Flush on closed pipeline} {stdio openpipe} {
+ file delete $path(pipe)
+ set f [open $path(pipe) w]
+ puts $f {exit}
+ close $f
+ set f [open "|[list [interpreter] $path(pipe)]" r+]
+ gets $f
+ puts $f output
+ after 50
+ #
+ # The flush below will get a SIGPIPE. This is an expected part of
+ # test and indicates that the test operates correctly. If you run
+ # this test under a debugger, the signal will by intercepted unless
+ # you disable the debugger's signal interception.
+ #
+ if {[catch {flush $f} msg]} {
+ set x [list 1 $msg $::errorCode]
+ catch {close $f}
+ } else {
+ if {[catch {close $f} msg]} {
+ set x [list 1 $msg $::errorCode]
+ } else {
+ set x {this was supposed to fail and did not}
+ }
+ }
+ regsub {".*":} $x {"":} x
+ string tolower $x
+} {1 {error flushing "": broken pipe} {posix epipe {broken pipe}}}
+test io-29.28 {Tcl_WriteChars, lf mode} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f hello\nthere\nand\nhere
+ flush $f
+ set s [file size $path(test1)]
+ close $f
+ set s
+} 21
+test io-29.29 {Tcl_WriteChars, cr mode} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar {}
+ puts $f hello\nthere\nand\nhere
+ close $f
+ file size $path(test1)
+} 21
+test io-29.30 {Tcl_WriteChars, crlf mode} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -eofchar {}
+ puts $f hello\nthere\nand\nhere
+ close $f
+ file size $path(test1)
+} 25
+test io-29.31 {Tcl_WriteChars, background flush} {stdio openpipe} {
+ # This test may fail on old Unix systems (seen on IRIX64 6.5) with
+ # obsolete gettimeofday() calls. See Tcl Bugs 3530533, 1942197.
+ file delete $path(pipe)
+ file delete $path(output)
+ set f [open $path(pipe) w]
+ puts $f "set f \[[list open $path(output) w]]"
+ puts $f {fconfigure $f -translation lf}
+ set x [list while {![eof stdin]}]
+ set x "$x {"
+ puts $f $x
+ puts $f { puts -nonewline $f [read stdin 4096]}
+ puts $f { flush $f}
+ puts $f "}"
+ puts $f {close $f}
+ close $f
+ set x 01234567890123456789012345678901
+ for {set i 0} {$i < 11} {incr i} {
+ set x "$x$x"
+ }
+ set f [open $path(output) w]
+ close $f
+ set f [open "|[list [interpreter] $path(pipe)]" r+]
+ fconfigure $f -blocking off
+ puts -nonewline $f $x
+ close $f
+ set counter 0
+ while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+ after 10 [list incr [namespace which -variable counter]]
+ vwait [namespace which -variable counter]
+ }
+ if {$counter == 1000} {
+ set result "file size only [file size $path(output)]"
+ } else {
+ set result ok
+ }
+ # allow a little time for the background process to close.
+ # otherwise, the following test fails on the [file delete $path(output)
+ # on Windows because a process still has the file open.
+ after 100 set v 1; vwait v
+ set result
+} ok
+test io-29.32 {Tcl_WriteChars, background flush to slow reader} \
+ {stdio asyncPipeClose openpipe} {
+ # This test may fail on old Unix systems (seen on IRIX64 6.5) with
+ # obsolete gettimeofday() calls. See Tcl Bugs 3530533, 1942197.
+ file delete $path(pipe)
+ file delete $path(output)
+ set f [open $path(pipe) w]
+ puts $f "set f \[[list open $path(output) w]]"
+ puts $f {fconfigure $f -translation lf}
+ set x [list while {![eof stdin]}]
+ set x "$x \{"
+ puts $f $x
+ puts $f { after 20}
+ puts $f { puts -nonewline $f [read stdin 1024]}
+ puts $f { flush $f}
+ puts $f "\}"
+ puts $f {close $f}
+ close $f
+ set x 01234567890123456789012345678901
+ for {set i 0} {$i < 11} {incr i} {
+ set x "$x$x"
+ }
+ set f [open $path(output) w]
+ close $f
+ set f [open "|[list [interpreter] $path(pipe)]" r+]
+ fconfigure $f -blocking off
+ puts -nonewline $f $x
+ close $f
+ set counter 0
+ while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+ after 20 [list incr [namespace which -variable counter]]
+ vwait [namespace which -variable counter]
+ }
+ if {$counter == 1000} {
+ set result "file size only [file size $path(output)]"
+ } else {
+ set result ok
+ }
+} ok
+test io-29.33 {Tcl_Flush, implicit flush on exit} {exec} {
+ set f [open $path(script) w]
+ puts $f "set f \[[list open $path(test1) w]]"
+ puts $f {fconfigure $f -translation lf
+ puts $f hello
+ puts $f bye
+ puts $f strange
+ }
+ close $f
+ exec [interpreter] $path(script)
+ set f [open $path(test1) r]
+ set r [read $f]
+ close $f
+ set r
+} "hello\nbye\nstrange\n"
+set path(script2) [makeFile {} script2]
+test io-29.33b {TIP#398, no implicit flush of nonblocking on exit} {exec} {
+ set f [open $path(script) w]
+ puts $f {
+ fconfigure stdout -blocking 0
+ puts -nonewline stdout [string repeat A 655360]
+ flush stdout
+ }
+ close $f
+ set f [open $path(script2) w]
+ puts $f {after 2000}
+ close $f
+ set t1 [clock milliseconds]
+ set ff [open "|[list [interpreter] $path(script2)]" w]
+ catch {unset ::env(TCL_FLUSH_NONBLOCKING_ON_EXIT)}
+ exec [interpreter] $path(script) >@ $ff
+ set t2 [clock milliseconds]
+ close $ff
+ expr {($t2-$t1)/2000 ? $t2-$t1 : 0}
+} 0
+test io-29.34 {Tcl_Close, async flush on close, using sockets} {socket tempNotMac fileevent} {
+ variable c 0
+ variable x running
+ set l abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
+ proc writelots {s l} {
+ for {set i 0} {$i < 2000} {incr i} {
+ puts $s $l
+ }
+ }
+ proc accept {s a p} {
+ variable x
+ fileevent $s readable [namespace code [list readit $s]]
+ fconfigure $s -blocking off
+ set x accepted
+ }
+ proc readit {s} {
+ variable c
+ variable x
+ set l [gets $s]
+
+ if {[eof $s]} {
+ close $s
+ set x done
+ } elseif {([string length $l] > 0) || ![fblocked $s]} {
+ incr c
+ }
+ }
+ set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set cs [socket 127.0.0.1 [lindex [fconfigure $ss -sockname] 2]]
+ vwait [namespace which -variable x]
+ fconfigure $cs -blocking off
+ writelots $cs $l
+ close $cs
+ close $ss
+ vwait [namespace which -variable x]
+ set c
+} 2000
+test io-29.35 {Tcl_Close vs fileevent vs multiple interpreters} {socket tempNotMac fileevent} {
+ # On Mac, this test screws up sockets such that subsequent tests using port 2828
+ # either cause errors or panic().
+
+ catch {interp delete x}
+ catch {interp delete y}
+ interp create x
+ interp create y
+ set s [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ proc accept {s a p} {
+ puts $s hello
+ close $s
+ }
+ set c [socket 127.0.0.1 [lindex [fconfigure $s -sockname] 2]]
+ interp share {} $c x
+ interp share {} $c y
+ close $c
+ x eval {
+ proc readit {s} {
+ gets $s
+ if {[eof $s]} {
+ close $s
+ }
+ }
+ }
+ y eval {
+ proc readit {s} {
+ gets $s
+ if {[eof $s]} {
+ close $s
+ }
+ }
+ }
+ x eval "fileevent $c readable \{readit $c\}"
+ y eval "fileevent $c readable \{readit $c\}"
+ y eval [list close $c]
+ update
+ close $s
+ interp delete x
+ interp delete y
+} ""
+
+# Test end of line translations. Procedures tested are Tcl_Write, Tcl_Read.
+
+test io-30.1 {Tcl_Write lf, Tcl_Read lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf
+ set x [read $f]
+ close $f
+ set x
+} "hello\nthere\nand\nhere\n"
+test io-30.2 {Tcl_Write lf, Tcl_Read cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr
+ set x [read $f]
+ close $f
+ set x
+} "hello\nthere\nand\nhere\n"
+test io-30.3 {Tcl_Write lf, Tcl_Read crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set x [read $f]
+ close $f
+ set x
+} "hello\nthere\nand\nhere\n"
+test io-30.4 {Tcl_Write cr, Tcl_Read cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr
+ set x [read $f]
+ close $f
+ set x
+} "hello\nthere\nand\nhere\n"
+test io-30.5 {Tcl_Write cr, Tcl_Read lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf
+ set x [read $f]
+ close $f
+ set x
+} "hello\rthere\rand\rhere\r"
+test io-30.6 {Tcl_Write cr, Tcl_Read crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set x [read $f]
+ close $f
+ set x
+} "hello\rthere\rand\rhere\r"
+test io-30.7 {Tcl_Write crlf, Tcl_Read crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set x [read $f]
+ close $f
+ set x
+} "hello\nthere\nand\nhere\n"
+test io-30.8 {Tcl_Write crlf, Tcl_Read lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf
+ set x [read $f]
+ close $f
+ set x
+} "hello\r\nthere\r\nand\r\nhere\r\n"
+test io-30.9 {Tcl_Write crlf, Tcl_Read cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr
+ set x [read $f]
+ close $f
+ set x
+} "hello\n\nthere\n\nand\n\nhere\n\n"
+test io-30.10 {Tcl_Write lf, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ set c [read $f]
+ set x [fconfigure $f -translation]
+ close $f
+ list $c $x
+} {{hello
+there
+and
+here
+} auto}
+test io-30.11 {Tcl_Write cr, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ set c [read $f]
+ set x [fconfigure $f -translation]
+ close $f
+ list $c $x
+} {{hello
+there
+and
+here
+} auto}
+test io-30.12 {Tcl_Write crlf, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ set c [read $f]
+ set x [fconfigure $f -translation]
+ close $f
+ list $c $x
+} {{hello
+there
+and
+here
+} auto}
+test io-30.13 {Tcl_Write crlf on block boundary, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set line "123456789ABCDE" ;# 14 char plus crlf
+ puts -nonewline $f x ;# shift crlf across block boundary
+ for {set i 0} {$i < 700} {incr i} {
+ puts $f $line
+ }
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto
+ set c [read $f]
+ close $f
+ string length $c
+} [expr 700*15+1]
+test io-30.14 {Tcl_Write crlf on block boundary, Tcl_Read crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set line "123456789ABCDE" ;# 14 char plus crlf
+ puts -nonewline $f x ;# shift crlf across block boundary
+ for {set i 0} {$i < 700} {incr i} {
+ puts $f $line
+ }
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set c [read $f]
+ close $f
+ string length $c
+} [expr 700*15+1]
+test io-30.15 {Tcl_Write mixed, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\rhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto
+ set c [read $f]
+ close $f
+ set c
+} {hello
+there
+and
+here
+}
+test io-30.16 {Tcl_Write ^Z at end, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f hello\nthere\nand\rhere\n\x1a
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ set c [read $f]
+ close $f
+ set c
+} {hello
+there
+and
+here
+}
+test io-30.17 {Tcl_Write, implicit ^Z at end, Tcl_Read auto} {win} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -eofchar \x1a -translation lf
+ puts $f hello\nthere\nand\rhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ set c [read $f]
+ close $f
+ set c
+} {hello
+there
+and
+here
+}
+test io-30.18 {Tcl_Write, ^Z in middle, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1 {} 1}
+test io-30.19 {Tcl_Write, ^Z no newline in middle, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1 {} 1}
+test io-30.20 {Tcl_Write, ^Z in middle ignored, Tcl_Read lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf -eofchar {}
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} "abc def 0 \x1aghi 0 qrs 0 {} 1"
+test io-30.21 {Tcl_Write, ^Z in middle ignored, Tcl_Read cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr -eofchar {}
+ set l ""
+ set x [gets $f]
+ lappend l [string compare $x "abc\ndef\n\x1aghi\nqrs\n"]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {0 1 {} 1}
+test io-30.22 {Tcl_Write, ^Z in middle ignored, Tcl_Read crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf -eofchar {}
+ set l ""
+ set x [gets $f]
+ lappend l [string compare $x "abc\ndef\n\x1aghi\nqrs\n"]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {0 1 {} 1}
+test io-30.23 {Tcl_Write lf, ^Z in middle, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set c [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $e
+} {8 1}
+test io-30.24 {Tcl_Write lf, ^Z in middle, Tcl_Read lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf -eofchar \x1a
+ set c [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $e
+} {8 1}
+test io-30.25 {Tcl_Write cr, ^Z in middle, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set c [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $e
+} {8 1}
+test io-30.26 {Tcl_Write cr, ^Z in middle, Tcl_Read cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr -eofchar \x1a
+ set c [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $e
+} {8 1}
+test io-30.27 {Tcl_Write crlf, ^Z in middle, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set c [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $e
+} {8 1}
+test io-30.28 {Tcl_Write crlf, ^Z in middle, Tcl_Read crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf -eofchar \x1a
+ set c [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $e
+} {8 1}
+
+# Test end of line translations. Functions tested are Tcl_Write and Tcl_Gets.
+
+test io-31.1 {Tcl_Write lf, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ close $f
+ set l
+} {hello 6 auto there 12 auto}
+test io-31.2 {Tcl_Write cr, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ close $f
+ set l
+} {hello 6 auto there 12 auto}
+test io-31.3 {Tcl_Write crlf, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ close $f
+ set l
+} {hello 7 auto there 14 auto}
+test io-31.4 {Tcl_Write lf, Tcl_Gets lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf
+ set l ""
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ close $f
+ set l
+} {hello 6 lf there 12 lf}
+test io-31.5 {Tcl_Write lf, Tcl_Gets cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr
+ set l ""
+ lappend l [string length [gets $f]]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ close $f
+ set l
+} {21 21 cr 1 {} 21 cr 1}
+test io-31.6 {Tcl_Write lf, Tcl_Gets crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set l ""
+ lappend l [string length [gets $f]]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ close $f
+ set l
+} {21 21 crlf 1 {} 21 crlf 1}
+test io-31.7 {Tcl_Write cr, Tcl_Gets cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr
+ set l ""
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello 6 cr 0 there 12 cr 0}
+test io-31.8 {Tcl_Write cr, Tcl_Gets lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf
+ set l ""
+ lappend l [string length [gets $f]]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ close $f
+ set l
+} {21 21 lf 1 {} 21 lf 1}
+test io-31.9 {Tcl_Write cr, Tcl_Gets crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set l ""
+ lappend l [string length [gets $f]]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ close $f
+ set l
+} {21 21 crlf 1 {} 21 crlf 1}
+test io-31.10 {Tcl_Write crlf, Tcl_Gets crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set l ""
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello 7 crlf 0 there 14 crlf 0}
+test io-31.11 {Tcl_Write crlf, Tcl_Gets cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr
+ set l ""
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ lappend l [string length [gets $f]]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello 6 cr 0 6 13 cr 0}
+test io-31.12 {Tcl_Write crlf, Tcl_Gets lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf
+ set l ""
+ lappend l [string length [gets $f]]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ lappend l [string length [gets $f]]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ close $f
+ set l
+} {6 7 lf 0 6 14 lf 0}
+test io-31.13 {binary mode is synonym of lf mode} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation binary
+ set x [fconfigure $f -translation]
+ close $f
+ set x
+} lf
+#
+# Test io-9.14 has been removed because "auto" output translation mode is
+# not supoprted.
+#
+test io-31.14 {Tcl_Write mixed, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\rand\r\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello there and here 0 {} 1}
+test io-31.15 {Tcl_Write mixed, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f hello\nthere\rand\r\nhere\r
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello there and here 0 {} 1}
+test io-31.16 {Tcl_Write mixed, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f hello\nthere\rand\r\nhere\n
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello there and here 0 {} 1}
+test io-31.17 {Tcl_Write mixed, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f hello\nthere\rand\r\nhere\r\n
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello there and here 0 {} 1}
+test io-31.18 {Tcl_Write ^Z at end, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set s [format "hello\nthere\nand\rhere\n\%c" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello there and here 0 {} 1}
+test io-31.19 {Tcl_Write, implicit ^Z at end, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -eofchar \x1a -translation lf
+ puts $f hello\nthere\nand\rhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello there and here 0 {} 1}
+test io-31.20 {Tcl_Write, ^Z in middle, Tcl_Gets auto, eofChar} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a
+ fconfigure $f -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1}
+test io-31.21 {Tcl_Write, no newline ^Z in middle, Tcl_Gets auto, eofChar} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1}
+test io-31.22 {Tcl_Write, ^Z in middle ignored, Tcl_Gets lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf -eofchar {}
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test io-31.23 {Tcl_Write, ^Z in middle ignored, Tcl_Gets cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr -eofchar {}
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test io-31.24 {Tcl_Write, ^Z in middle ignored, Tcl_Gets crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf -eofchar {}
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test io-31.25 {Tcl_Write lf, ^Z in middle, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1}
+test io-31.26 {Tcl_Write lf, ^Z in middle, Tcl_Gets lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf -eofchar \x1a
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1}
+test io-31.27 {Tcl_Write cr, ^Z in middle, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1}
+test io-31.28 {Tcl_Write cr, ^Z in middle, Tcl_Gets cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr -eofchar \x1a
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1}
+test io-31.29 {Tcl_Write crlf, ^Z in middle, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1}
+test io-31.30 {Tcl_Write crlf, ^Z in middle, Tcl_Gets crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf -eofchar \x1a
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1}
+test io-31.31 {Tcl_Write crlf on block boundary, Tcl_Gets crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set line "123456789ABCDE" ;# 14 char plus crlf
+ puts -nonewline $f x ;# shift crlf across block boundary
+ for {set i 0} {$i < 700} {incr i} {
+ puts $f $line
+ }
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set c ""
+ while {[gets $f line] >= 0} {
+ append c $line\n
+ }
+ close $f
+ string length $c
+} [expr 700*15+1]
+test io-31.32 {Tcl_Write crlf on block boundary, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set line "123456789ABCDE" ;# 14 char plus crlf
+ puts -nonewline $f x ;# shift crlf across block boundary
+ for {set i 0} {$i < 700} {incr i} {
+ puts $f $line
+ }
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto
+ set c ""
+ while {[gets $f line] >= 0} {
+ append c $line\n
+ }
+ close $f
+ string length $c
+} [expr 700*15+1]
+
+# Test Tcl_Read and buffering.
+
+test io-32.1 {Tcl_Read, channel not readable} {
+ list [catch {read stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test io-32.2 {Tcl_Read, zero byte count} {
+ read stdin 0
+} ""
+test io-32.3 {Tcl_Read, negative byte count} {
+ set f [open $path(longfile) r]
+ set l [list [catch {read $f -1} msg] $msg]
+ close $f
+ set l
+} {1 {expected non-negative integer but got "-1"}}
+test io-32.4 {Tcl_Read, positive byte count} {
+ set f [open $path(longfile) r]
+ set x [read $f 1024]
+ set s [string length $x]
+ unset x
+ close $f
+ set s
+} 1024
+test io-32.5 {Tcl_Read, multiple buffers} {
+ set f [open $path(longfile) r]
+ fconfigure $f -buffersize 100
+ set x [read $f 1024]
+ set s [string length $x]
+ unset x
+ close $f
+ set s
+} 1024
+test io-32.6 {Tcl_Read, very large read} {
+ set f1 [open $path(longfile) r]
+ set z [read $f1 1000000]
+ close $f1
+ set l [string length $z]
+ set x ok
+ set z [file size $path(longfile)]
+ if {$z != $l} {
+ set x broken
+ }
+ set x
+} ok
+test io-32.7 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
+ set f1 [open $path(longfile) r]
+ fconfigure $f1 -blocking off
+ set z [read $f1 20]
+ close $f1
+ set l [string length $z]
+ set x ok
+ if {$l != 20} {
+ set x broken
+ }
+ set x
+} ok
+test io-32.8 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
+ set f1 [open $path(longfile) r]
+ fconfigure $f1 -blocking off
+ set z [read $f1 1000000]
+ close $f1
+ set x ok
+ set l [string length $z]
+ set z [file size $path(longfile)]
+ if {$z != $l} {
+ set x broken
+ }
+ set x
+} ok
+test io-32.9 {Tcl_Read, read to end of file} {
+ set f1 [open $path(longfile) r]
+ set z [read $f1]
+ close $f1
+ set l [string length $z]
+ set x ok
+ set z [file size $path(longfile)]
+ if {$z != $l} {
+ set x broken
+ }
+ set x
+} ok
+test io-32.10 {Tcl_Read from a pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {puts [gets stdin]}
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ puts $f1 hello
+ flush $f1
+ set x [read $f1]
+ close $f1
+ set x
+} "hello\n"
+test io-32.11 {Tcl_Read from a pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {puts [gets stdin]}
+ puts $f1 {puts [gets stdin]}
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ puts $f1 hello
+ flush $f1
+ set x ""
+ lappend x [read $f1 6]
+ puts $f1 hello
+ flush $f1
+ lappend x [read $f1]
+ close $f1
+ set x
+} {{hello
+} {hello
+}}
+test io-32.12 {Tcl_Read, -nonewline} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ puts $f1 hello
+ puts $f1 bye
+ close $f1
+ set f1 [open $path(test1) r]
+ set c [read -nonewline $f1]
+ close $f1
+ set c
+} {hello
+bye}
+test io-32.13 {Tcl_Read, -nonewline} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ puts $f1 hello
+ puts $f1 bye
+ close $f1
+ set f1 [open $path(test1) r]
+ set c [read -nonewline $f1]
+ close $f1
+ list [string length $c] $c
+} {9 {hello
+bye}}
+test io-32.14 {Tcl_Read, reading in small chunks} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f "Two lines: this one"
+ puts $f "and this one"
+ close $f
+ set f [open $path(test1)]
+ set x [list [read $f 1] [read $f 2] [read $f]]
+ close $f
+ set x
+} {T wo { lines: this one
+and this one
+}}
+test io-32.15 {Tcl_Read, asking for more input than available} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f "Two lines: this one"
+ puts $f "and this one"
+ close $f
+ set f [open $path(test1)]
+ set x [read $f 100]
+ close $f
+ set x
+} {Two lines: this one
+and this one
+}
+test io-32.16 {Tcl_Read, read to end of file with -nonewline} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f "Two lines: this one"
+ puts $f "and this one"
+ close $f
+ set f [open $path(test1)]
+ set x [read -nonewline $f]
+ close $f
+ set x
+} {Two lines: this one
+and this one}
+
+# Test Tcl_Gets.
+
+test io-33.1 {Tcl_Gets, reading what was written} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ set y "first line"
+ puts $f1 $y
+ close $f1
+ set f1 [open $path(test1) r]
+ set x [gets $f1]
+ set z ok
+ if {"$x" != "$y"} {
+ set z broken
+ }
+ close $f1
+ set z
+} ok
+test io-33.2 {Tcl_Gets into variable} {
+ set f1 [open $path(longfile) r]
+ set c [gets $f1 x]
+ set l [string length x]
+ set z ok
+ if {$l != $l} {
+ set z broken
+ }
+ close $f1
+ set z
+} ok
+test io-33.3 {Tcl_Gets from pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {puts [gets stdin]}
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ puts $f1 hello
+ flush $f1
+ set x [gets $f1]
+ close $f1
+ set z ok
+ if {"$x" != "hello"} {
+ set z broken
+ }
+ set z
+} ok
+test io-33.4 {Tcl_Gets with long line} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ puts $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ close $f
+ set f [open $path(test3)]
+ set x [gets $f]
+ close $f
+ set x
+} {abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
+test io-33.5 {Tcl_Gets with long line} {
+ set f [open $path(test3)]
+ set x [gets $f y]
+ close $f
+ list $x $y
+} {260 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
+test io-33.6 {Tcl_Gets and end of file} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ puts -nonewline $f "Test1\nTest2"
+ close $f
+ set f [open $path(test3)]
+ set x {}
+ set y {}
+ lappend x [gets $f y] $y
+ set y {}
+ lappend x [gets $f y] $y
+ set y {}
+ lappend x [gets $f y] $y
+ close $f
+ set x
+} {5 Test1 5 Test2 -1 {}}
+test io-33.7 {Tcl_Gets and bad variable} {
+ set f [open $path(test3) w]
+ puts $f "Line 1"
+ puts $f "Line 2"
+ close $f
+ catch {unset x}
+ set x 24
+ set f [open $path(test3) r]
+ set result [list [catch {gets $f x(0)} msg] $msg]
+ close $f
+ set result
+} {1 {can't set "x(0)": variable isn't array}}
+test io-33.8 {Tcl_Gets, exercising double buffering} {
+ set f [open $path(test3) w]
+ fconfigure $f -translation lf -eofchar {}
+ set x ""
+ for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+ for {set y 0} {$y < 100} {incr y} {puts $f $x}
+ close $f
+ set f [open $path(test3) r]
+ fconfigure $f -translation lf
+ for {set y 0} {$y < 100} {incr y} {gets $f}
+ close $f
+ set y
+} 100
+test io-33.9 {Tcl_Gets, exercising double buffering} {
+ set f [open $path(test3) w]
+ fconfigure $f -translation lf -eofchar {}
+ set x ""
+ for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+ for {set y 0} {$y < 200} {incr y} {puts $f $x}
+ close $f
+ set f [open $path(test3) r]
+ fconfigure $f -translation lf
+ for {set y 0} {$y < 200} {incr y} {gets $f}
+ close $f
+ set y
+} 200
+test io-33.10 {Tcl_Gets, exercising double buffering} {
+ set f [open $path(test3) w]
+ fconfigure $f -translation lf -eofchar {}
+ set x ""
+ for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+ for {set y 0} {$y < 300} {incr y} {puts $f $x}
+ close $f
+ set f [open $path(test3) r]
+ fconfigure $f -translation lf
+ for {set y 0} {$y < 300} {incr y} {gets $f}
+ close $f
+ set y
+} 300
+
+# Test Tcl_Seek and Tcl_Tell.
+
+test io-34.1 {Tcl_Seek to current position at start of file} {
+ set f1 [open $path(longfile) r]
+ seek $f1 0 current
+ set c [tell $f1]
+ close $f1
+ set c
+} 0
+test io-34.2 {Tcl_Seek to offset from start} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open $path(test1) r]
+ seek $f1 10 start
+ set c [tell $f1]
+ close $f1
+ set c
+} 10
+test io-34.3 {Tcl_Seek to end of file} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open $path(test1) r]
+ seek $f1 0 end
+ set c [tell $f1]
+ close $f1
+ set c
+} 54
+test io-34.4 {Tcl_Seek to offset from end of file} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open $path(test1) r]
+ seek $f1 -10 end
+ set c [tell $f1]
+ close $f1
+ set c
+} 44
+test io-34.5 {Tcl_Seek to offset from current position} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open $path(test1) r]
+ seek $f1 10 current
+ seek $f1 10 current
+ set c [tell $f1]
+ close $f1
+ set c
+} 20
+test io-34.6 {Tcl_Seek to offset from end of file} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open $path(test1) r]
+ seek $f1 -10 end
+ set c [tell $f1]
+ set r [read $f1]
+ close $f1
+ list $c $r
+} {44 {rstuvwxyz
+}}
+test io-34.7 {Tcl_Seek to offset from end of file, then to current position} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open $path(test1) r]
+ seek $f1 -10 end
+ set c1 [tell $f1]
+ set r1 [read $f1 5]
+ seek $f1 0 current
+ set c2 [tell $f1]
+ close $f1
+ list $c1 $r1 $c2
+} {44 rstuv 49}
+test io-34.8 {Tcl_Seek on pipes: not supported} {stdio openpipe} {
+ set f1 [open "|[list [interpreter]]" r+]
+ set x [list [catch {seek $f1 0 current} msg] $msg]
+ close $f1
+ regsub {".*":} $x {"":} x
+ string tolower $x
+} {1 {error during seek on "": invalid argument}}
+test io-34.9 {Tcl_Seek, testing buffered input flushing} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ fconfigure $f -eofchar {}
+ puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ close $f
+ set f [open $path(test3) RDWR]
+ set x [read $f 1]
+ seek $f 3
+ lappend x [read $f 1]
+ seek $f 0 start
+ lappend x [read $f 1]
+ seek $f 10 current
+ lappend x [read $f 1]
+ seek $f -2 end
+ lappend x [read $f 1]
+ seek $f 50 end
+ lappend x [read $f 1]
+ seek $f 1
+ lappend x [read $f 1]
+ close $f
+ set x
+} {a d a l Y {} b}
+set path(test3) [makeFile {} test3]
+test io-34.10 {Tcl_Seek testing flushing of buffered input} {
+ set f [open $path(test3) w]
+ fconfigure $f -translation lf
+ puts $f xyz\n123
+ close $f
+ set f [open $path(test3) r+]
+ fconfigure $f -translation lf
+ set x [gets $f]
+ seek $f 0 current
+ puts $f 456
+ close $f
+ list $x [viewFile test3]
+} "xyz {xyz
+456}"
+test io-34.11 {Tcl_Seek testing flushing of buffered output} {
+ set f [open $path(test3) w]
+ puts $f xyz\n123
+ close $f
+ set f [open $path(test3) w+]
+ puts $f xyzzy
+ seek $f 2
+ set x [gets $f]
+ close $f
+ list $x [viewFile test3]
+} "zzy xyzzy"
+test io-34.12 {Tcl_Seek testing combination of write, seek back and read} {
+ set f [open $path(test3) w]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f xyz\n123
+ close $f
+ set f [open $path(test3) a+]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f xyzzy
+ flush $f
+ set x [tell $f]
+ seek $f -4 cur
+ set y [gets $f]
+ close $f
+ list $x [viewFile test3] $y
+} {14 {xyz
+123
+xyzzy} zzy}
+test io-34.13 {Tcl_Tell at start of file} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ set p [tell $f1]
+ close $f1
+ set p
+} 0
+test io-34.14 {Tcl_Tell after seek to end of file} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open $path(test1) r]
+ seek $f1 0 end
+ set c1 [tell $f1]
+ close $f1
+ set c1
+} 54
+test io-34.15 {Tcl_Tell combined with seeking} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open $path(test1) r]
+ seek $f1 10 start
+ set c1 [tell $f1]
+ seek $f1 10 current
+ set c2 [tell $f1]
+ close $f1
+ list $c1 $c2
+} {10 20}
+test io-34.16 {Tcl_Tell on pipe: always -1} {stdio openpipe} {
+ set f1 [open "|[list [interpreter]]" r+]
+ set c [tell $f1]
+ close $f1
+ set c
+} -1
+test io-34.17 {Tcl_Tell on pipe: always -1} {stdio openpipe} {
+ set f1 [open "|[list [interpreter]]" r+]
+ puts $f1 {puts hello}
+ flush $f1
+ set c [tell $f1]
+ gets $f1
+ close $f1
+ set c
+} -1
+test io-34.18 {Tcl_Tell combined with seeking and reading} {
+ file delete $path(test2)
+ set f [open $path(test2) w]
+ fconfigure $f -translation lf -eofchar {}
+ puts -nonewline $f "line1\nline2\nline3\nline4\nline5\n"
+ close $f
+ set f [open $path(test2)]
+ fconfigure $f -translation lf
+ set x [tell $f]
+ read $f 3
+ lappend x [tell $f]
+ seek $f 2
+ lappend x [tell $f]
+ seek $f 10 current
+ lappend x [tell $f]
+ seek $f 0 end
+ lappend x [tell $f]
+ close $f
+ set x
+} {0 3 2 12 30}
+test io-34.19 {Tcl_Tell combined with opening in append mode} {
+ set f [open $path(test3) w]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f "abcdefghijklmnopqrstuvwxyz"
+ puts $f "abcdefghijklmnopqrstuvwxyz"
+ close $f
+ set f [open $path(test3) a]
+ set c [tell $f]
+ close $f
+ set c
+} 54
+test io-34.20 {Tcl_Tell combined with writing} {
+ set f [open $path(test3) w]
+ set l ""
+ seek $f 29 start
+ lappend l [tell $f]
+ puts -nonewline $f a
+ seek $f 39 start
+ lappend l [tell $f]
+ puts -nonewline $f a
+ lappend l [tell $f]
+ seek $f 407 end
+ lappend l [tell $f]
+ close $f
+ set l
+} {29 39 40 447}
+test io-34.21 {Tcl_Seek and Tcl_Tell on large files} {largefileSupport} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ fconfigure $f -encoding binary
+ set l ""
+ lappend l [tell $f]
+ puts -nonewline $f abcdef
+ lappend l [tell $f]
+ flush $f
+ lappend l [tell $f]
+ # 4GB offset!
+ seek $f 0x100000000
+ lappend l [tell $f]
+ puts -nonewline $f abcdef
+ lappend l [tell $f]
+ close $f
+ lappend l [file size $f]
+ # truncate...
+ close [open $path(test3) w]
+ lappend l [file size $f]
+ set l
+} {0 6 6 4294967296 4294967302 4294967302 0}
+
+# Test Tcl_Eof
+
+test io-35.1 {Tcl_Eof} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f hello
+ puts $f hello
+ close $f
+ set f [open $path(test1)]
+ set x [eof $f]
+ lappend x [eof $f]
+ gets $f
+ lappend x [eof $f]
+ gets $f
+ lappend x [eof $f]
+ gets $f
+ lappend x [eof $f]
+ lappend x [eof $f]
+ close $f
+ set x
+} {0 0 0 0 1 1}
+test io-35.2 {Tcl_Eof with pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {gets stdin}
+ puts $f1 {puts hello}
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ puts $f1 hello
+ set x [eof $f1]
+ flush $f1
+ lappend x [eof $f1]
+ gets $f1
+ lappend x [eof $f1]
+ gets $f1
+ lappend x [eof $f1]
+ close $f1
+ set x
+} {0 0 0 1}
+test io-35.3 {Tcl_Eof with pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {gets stdin}
+ puts $f1 {puts hello}
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ puts $f1 hello
+ set x [eof $f1]
+ flush $f1
+ lappend x [eof $f1]
+ gets $f1
+ lappend x [eof $f1]
+ gets $f1
+ lappend x [eof $f1]
+ gets $f1
+ lappend x [eof $f1]
+ gets $f1
+ lappend x [eof $f1]
+ close $f1
+ set x
+} {0 0 0 1 1 1}
+test io-35.4 {Tcl_Eof, eof detection on nonblocking file} {nonBlockFiles} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -blocking off
+ set l ""
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {{} 1}
+test io-35.5 {Tcl_Eof, eof detection on nonblocking pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f [open $path(pipe) w]
+ puts $f {
+ exit
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(pipe)]" r]
+ set l ""
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {{} 1}
+test io-35.6 {Tcl_Eof, eof char, lf write, auto read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $s $l $e
+} {9 8 1}
+test io-35.7 {Tcl_Eof, eof char, lf write, lf read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $s $l $e
+} {9 8 1}
+test io-35.8 {Tcl_Eof, eof char, cr write, auto read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $s $l $e
+} {9 8 1}
+test io-35.9 {Tcl_Eof, eof char, cr write, cr read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $s $l $e
+} {9 8 1}
+test io-35.10 {Tcl_Eof, eof char, crlf write, auto read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $s $l $e
+} {11 8 1}
+test io-35.11 {Tcl_Eof, eof char, crlf write, crlf read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $s $l $e
+} {11 8 1}
+test io-35.12 {Tcl_Eof, eof char in middle, lf write, auto read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ set i [format abc\ndef\n%cqrs\nuvw 26]
+ puts $f $i
+ close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $l $e
+} {17 8 1}
+test io-35.13 {Tcl_Eof, eof char in middle, lf write, lf read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ set i [format abc\ndef\n%cqrs\nuvw 26]
+ puts $f $i
+ close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $l $e
+} {17 8 1}
+test io-35.14 {Tcl_Eof, eof char in middle, cr write, auto read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar {}
+ set i [format abc\ndef\n%cqrs\nuvw 26]
+ puts $f $i
+ close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $l $e
+} {17 8 1}
+test io-35.15 {Tcl_Eof, eof char in middle, cr write, cr read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar {}
+ set i [format abc\ndef\n%cqrs\nuvw 26]
+ puts $f $i
+ close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $l $e
+} {17 8 1}
+test io-35.16 {Tcl_Eof, eof char in middle, crlf write, auto read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -eofchar {}
+ set i [format abc\ndef\n%cqrs\nuvw 26]
+ puts $f $i
+ close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $l $e
+} {21 8 1}
+test io-35.17 {Tcl_Eof, eof char in middle, crlf write, crlf read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -eofchar {}
+ set i [format abc\ndef\n%cqrs\nuvw 26]
+ puts $f $i
+ close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $l $e
+} {21 8 1}
+
+# Test Tcl_InputBlocked
+
+test io-36.1 {Tcl_InputBlocked on nonblocking pipe} {stdio openpipe} {
+ set f1 [open "|[list [interpreter]]" r+]
+ puts $f1 {puts hello_from_pipe}
+ flush $f1
+ gets $f1
+ fconfigure $f1 -blocking off -buffering full
+ puts $f1 {puts hello}
+ set x ""
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ flush $f1
+ after 200
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ close $f1
+ set x
+} {{} 1 hello 0 {} 1}
+test io-36.2 {Tcl_InputBlocked on blocking pipe} {stdio openpipe} {
+ set f1 [open "|[list [interpreter]]" r+]
+ fconfigure $f1 -buffering line
+ puts $f1 {puts hello_from_pipe}
+ set x ""
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ puts $f1 {exit}
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ lappend x [eof $f1]
+ close $f1
+ set x
+} {hello_from_pipe 0 {} 0 1}
+test io-36.3 {Tcl_InputBlocked vs files, short read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f abcdefghijklmnop
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [fblocked $f]
+ lappend l [read $f 3]
+ lappend l [fblocked $f]
+ lappend l [read -nonewline $f]
+ lappend l [fblocked $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {0 abc 0 defghijklmnop 0 1}
+test io-36.4 {Tcl_InputBlocked vs files, event driven read} {fileevent} {
+ proc in {f} {
+ variable l
+ variable x
+ lappend l [read $f 3]
+ if {[eof $f]} {lappend l eof; close $f; set x done}
+ }
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f abcdefghijklmnop
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ fileevent $f readable [namespace code [list in $f]]
+ variable x
+ vwait [namespace which -variable x]
+ set l
+} {abc def ghi jkl mno {p
+} eof}
+test io-36.5 {Tcl_InputBlocked vs files, short read, nonblocking} {nonBlockFiles} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f abcdefghijklmnop
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -blocking off
+ set l ""
+ lappend l [fblocked $f]
+ lappend l [read $f 3]
+ lappend l [fblocked $f]
+ lappend l [read -nonewline $f]
+ lappend l [fblocked $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {0 abc 0 defghijklmnop 0 1}
+test io-36.6 {Tcl_InputBlocked vs files, event driven read} {nonBlockFiles fileevent} {
+ proc in {f} {
+ variable l
+ variable x
+ lappend l [read $f 3]
+ if {[eof $f]} {lappend l eof; close $f; set x done}
+ }
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f abcdefghijklmnop
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -blocking off
+ set l ""
+ fileevent $f readable [namespace code [list in $f]]
+ variable x
+ vwait [namespace which -variable x]
+ set l
+} {abc def ghi jkl mno {p
+} eof}
+
+# Test Tcl_InputBuffered
+
+test io-37.1 {Tcl_InputBuffered} {testchannel} {
+ set f [open $path(longfile) r]
+ fconfigure $f -buffersize 4096
+ read $f 3
+ set l ""
+ lappend l [testchannel inputbuffered $f]
+ lappend l [tell $f]
+ close $f
+ set l
+} {4093 3}
+test io-37.2 {Tcl_InputBuffered, test input flushing on seek} {testchannel} {
+ set f [open $path(longfile) r]
+ fconfigure $f -buffersize 4096
+ read $f 3
+ set l ""
+ lappend l [testchannel inputbuffered $f]
+ lappend l [tell $f]
+ seek $f 0 current
+ lappend l [testchannel inputbuffered $f]
+ lappend l [tell $f]
+ close $f
+ set l
+} {4093 3 0 3}
+
+# Test Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize
+
+test io-38.1 {Tcl_GetChannelBufferSize, default buffer size} {
+ set f [open $path(longfile) r]
+ set s [fconfigure $f -buffersize]
+ close $f
+ set s
+} 4096
+test io-38.2 {Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize} {
+ set f [open $path(longfile) r]
+ set l ""
+ lappend l [fconfigure $f -buffersize]
+ fconfigure $f -buffersize 10000
+ lappend l [fconfigure $f -buffersize]
+ fconfigure $f -buffersize 1
+ lappend l [fconfigure $f -buffersize]
+ fconfigure $f -buffersize -1
+ lappend l [fconfigure $f -buffersize]
+ fconfigure $f -buffersize 0
+ lappend l [fconfigure $f -buffersize]
+ fconfigure $f -buffersize 100000
+ lappend l [fconfigure $f -buffersize]
+ fconfigure $f -buffersize 10000000
+ lappend l [fconfigure $f -buffersize]
+ close $f
+ set l
+} {4096 10000 1 1 1 100000 1048576}
+test io-38.3 {Tcl_SetChannelBufferSize, changing buffersize between reads} {
+ # This test crashes the interp if Bug #427196 is not fixed
+
+ set chan [open [info script] r]
+ fconfigure $chan -buffersize 10
+ set var [read $chan 2]
+ fconfigure $chan -buffersize 32
+ append var [read $chan]
+ close $chan
+} {}
+
+# Test Tcl_SetChannelOption, Tcl_GetChannelOption
+
+test io-39.1 {Tcl_GetChannelOption} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ set x [fconfigure $f1 -blocking]
+ close $f1
+ set x
+} 1
+#
+# Test 17.2 was removed.
+#
+test io-39.2 {Tcl_GetChannelOption} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ set x [fconfigure $f1 -buffering]
+ close $f1
+ set x
+} full
+test io-39.3 {Tcl_GetChannelOption} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -buffering line
+ set x [fconfigure $f1 -buffering]
+ close $f1
+ set x
+} line
+test io-39.4 {Tcl_GetChannelOption, Tcl_SetChannelOption} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ set l ""
+ lappend l [fconfigure $f1 -buffering]
+ fconfigure $f1 -buffering line
+ lappend l [fconfigure $f1 -buffering]
+ fconfigure $f1 -buffering none
+ lappend l [fconfigure $f1 -buffering]
+ fconfigure $f1 -buffering line
+ lappend l [fconfigure $f1 -buffering]
+ fconfigure $f1 -buffering full
+ lappend l [fconfigure $f1 -buffering]
+ close $f1
+ set l
+} {full line none line full}
+test io-39.5 {Tcl_GetChannelOption, invariance} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ set l ""
+ lappend l [fconfigure $f1 -buffering]
+ lappend l [list [catch {fconfigure $f1 -buffering green} msg] $msg]
+ lappend l [fconfigure $f1 -buffering]
+ close $f1
+ set l
+} {full {1 {bad value for -buffering: must be one of full, line, or none}} full}
+test io-39.6 {Tcl_SetChannelOption, multiple options} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -buffering line
+ puts $f1 hello
+ puts $f1 bye
+ set x [file size $path(test1)]
+ close $f1
+ set x
+} 10
+test io-39.7 {Tcl_SetChannelOption, buffering, translation} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf
+ puts $f1 hello
+ puts $f1 bye
+ set x ""
+ fconfigure $f1 -buffering line
+ lappend x [file size $path(test1)]
+ puts $f1 really_bye
+ lappend x [file size $path(test1)]
+ close $f1
+ set x
+} {0 21}
+test io-39.8 {Tcl_SetChannelOption, different buffering options} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ set l ""
+ fconfigure $f1 -translation lf -buffering none -eofchar {}
+ puts -nonewline $f1 hello
+ lappend l [file size $path(test1)]
+ puts -nonewline $f1 hello
+ lappend l [file size $path(test1)]
+ fconfigure $f1 -buffering full
+ puts -nonewline $f1 hello
+ lappend l [file size $path(test1)]
+ fconfigure $f1 -buffering none
+ lappend l [file size $path(test1)]
+ puts -nonewline $f1 hello
+ lappend l [file size $path(test1)]
+ close $f1
+ lappend l [file size $path(test1)]
+ set l
+} {5 10 10 10 20 20}
+test io-39.9 {Tcl_SetChannelOption, blocking mode} {nonBlockFiles} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ close $f1
+ set f1 [open $path(test1) r]
+ set x ""
+ lappend x [fconfigure $f1 -blocking]
+ fconfigure $f1 -blocking off
+ lappend x [fconfigure $f1 -blocking]
+ lappend x [gets $f1]
+ lappend x [read $f1 1000]
+ lappend x [fblocked $f1]
+ lappend x [eof $f1]
+ close $f1
+ set x
+} {1 0 {} {} 0 1}
+test io-39.10 {Tcl_SetChannelOption, blocking mode} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {
+ gets stdin
+ after 100
+ puts hi
+ gets stdin
+ }
+ close $f1
+ set x ""
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ fconfigure $f1 -blocking off -buffering line
+ lappend x [fconfigure $f1 -blocking]
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ fconfigure $f1 -blocking on
+ puts $f1 hello
+ fconfigure $f1 -blocking off
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ fconfigure $f1 -blocking on
+ puts $f1 bye
+ fconfigure $f1 -blocking off
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ fconfigure $f1 -blocking on
+ lappend x [fconfigure $f1 -blocking]
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ lappend x [eof $f1]
+ lappend x [gets $f1]
+ lappend x [eof $f1]
+ close $f1
+ set x
+} {0 {} 1 {} 1 {} 1 1 hi 0 0 {} 1}
+test io-39.11 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size clipped to lower bound} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -buffersize -10
+ set x [fconfigure $f -buffersize]
+ close $f
+ set x
+} 1
+test io-39.12 {Tcl_SetChannelOption, Tcl_GetChannelOption buffer size clipped to upper bound} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -buffersize 10000000
+ set x [fconfigure $f -buffersize]
+ close $f
+ set x
+} 1048576
+test io-39.13 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -buffersize 40000
+ set x [fconfigure $f -buffersize]
+ close $f
+ set x
+} 40000
+test io-39.14 {Tcl_SetChannelOption: -encoding, binary & utf-8} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -encoding {}
+ puts -nonewline $f \xe7\x89\xa6
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -encoding utf-8
+ set x [read $f]
+ close $f
+ set x
+} \u7266
+test io-39.15 {Tcl_SetChannelOption: -encoding, binary & utf-8} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -encoding binary
+ puts -nonewline $f \xe7\x89\xa6
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -encoding utf-8
+ set x [read $f]
+ close $f
+ set x
+} \u7266
+test io-39.16 {Tcl_SetChannelOption: -encoding, errors} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ set result [list [catch {fconfigure $f -encoding foobar} msg] $msg]
+ close $f
+ set result
+} {1 {unknown encoding "foobar"}}
+test io-39.17 {Tcl_SetChannelOption: -encoding, clearing CHANNEL_NEED_MORE_DATA} {stdio openpipe fileevent} {
+ set f [open "|[list [interpreter] $path(cat)]" r+]
+ fconfigure $f -encoding binary
+ puts -nonewline $f "\xe7"
+ flush $f
+ fconfigure $f -encoding utf-8 -blocking 0
+ variable x {}
+ fileevent $f readable [namespace code { lappend x [read $f] }]
+ vwait [namespace which -variable x]
+ after 300 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ fconfigure $f -encoding utf-8
+ vwait [namespace which -variable x]
+ after 300 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ fconfigure $f -encoding binary
+ vwait [namespace which -variable x]
+ after 300 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ close $f
+ set x
+} "{} timeout {} timeout \xe7 timeout"
+test io-39.18 {Tcl_SetChannelOption, setting read mode independently} \
+ {socket} {
+ proc accept {s a p} {close $s}
+ set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $s1 -sockname] 2]
+ set s2 [socket 127.0.0.1 $port]
+ update
+ fconfigure $s2 -translation {auto lf}
+ set modes [fconfigure $s2 -translation]
+ close $s1
+ close $s2
+ set modes
+} {auto lf}
+test io-39.19 {Tcl_SetChannelOption, setting read mode independently} \
+ {socket} {
+ proc accept {s a p} {close $s}
+ set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $s1 -sockname] 2]
+ set s2 [socket 127.0.0.1 $port]
+ update
+ fconfigure $s2 -translation {auto crlf}
+ set modes [fconfigure $s2 -translation]
+ close $s1
+ close $s2
+ set modes
+} {auto crlf}
+test io-39.20 {Tcl_SetChannelOption, setting read mode independently} \
+ {socket} {
+ proc accept {s a p} {close $s}
+ set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $s1 -sockname] 2]
+ set s2 [socket 127.0.0.1 $port]
+ update
+ fconfigure $s2 -translation {auto cr}
+ set modes [fconfigure $s2 -translation]
+ close $s1
+ close $s2
+ set modes
+} {auto cr}
+test io-39.21 {Tcl_SetChannelOption, setting read mode independently} \
+ {socket} {
+ proc accept {s a p} {close $s}
+ set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $s1 -sockname] 2]
+ set s2 [socket 127.0.0.1 $port]
+ update
+ fconfigure $s2 -translation {auto auto}
+ set modes [fconfigure $s2 -translation]
+ close $s1
+ close $s2
+ set modes
+} {auto crlf}
+test io-39.22 {Tcl_SetChannelOption, invariance} {unix} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w+]
+ set l ""
+ lappend l [fconfigure $f1 -eofchar]
+ fconfigure $f1 -eofchar {ON GO}
+ lappend l [fconfigure $f1 -eofchar]
+ fconfigure $f1 -eofchar D
+ lappend l [fconfigure $f1 -eofchar]
+ close $f1
+ set l
+} {{{} {}} {O G} {D D}}
+test io-39.22a {Tcl_SetChannelOption, invariance} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w+]
+ set l [list]
+ fconfigure $f1 -eofchar {ON GO}
+ lappend l [fconfigure $f1 -eofchar]
+ fconfigure $f1 -eofchar D
+ lappend l [fconfigure $f1 -eofchar]
+ lappend l [list [catch {fconfigure $f1 -eofchar {1 2 3}} msg] $msg]
+ close $f1
+ set l
+} {{O G} {D D} {1 {bad value for -eofchar: should be a list of zero, one, or two elements}}}
+test io-39.23 {Tcl_GetChannelOption, server socket is not readable or
+ writeable, it should still have valid -eofchar and -translation options } {
+ set l [list]
+ set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ lappend l [fconfigure $sock -eofchar] [fconfigure $sock -translation]
+ close $sock
+ set l
+} {{{}} auto}
+test io-39.24 {Tcl_SetChannelOption, server socket is not readable or
+ writable so we can't change -eofchar or -translation } {
+ set l [list]
+ set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ fconfigure $sock -eofchar D -translation lf
+ lappend l [fconfigure $sock -eofchar] [fconfigure $sock -translation]
+ close $sock
+ set l
+} {{{}} auto}
+
+test io-40.1 {POSIX open access modes: RDWR} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ puts $f xyzzy
+ close $f
+ set f [open $path(test3) RDWR]
+ puts -nonewline $f "ab"
+ seek $f 0 current
+ set x [gets $f]
+ close $f
+ set f [open $path(test3) r]
+ lappend x [gets $f]
+ close $f
+ set x
+} {zzy abzzy}
+test io-40.2 {POSIX open access modes: CREAT} {unix} {
+ file delete $path(test3)
+ set f [open $path(test3) {WRONLY CREAT} 0o600]
+ file stat $path(test3) stats
+ set x [format "0o%o" [expr $stats(mode)&0o777]]
+ puts $f "line 1"
+ close $f
+ set f [open $path(test3) r]
+ lappend x [gets $f]
+ close $f
+ set x
+} {0o600 {line 1}}
+test io-40.3 {POSIX open access modes: CREAT} {unix umask} {
+ # This test only works if your umask is 2, like ouster's.
+ file delete $path(test3)
+ set f [open $path(test3) {WRONLY CREAT}]
+ close $f
+ file stat $path(test3) stats
+ format "0%o" [expr $stats(mode)&0o777]
+} [format %04o [expr {0o666 & ~ $umaskValue}]]
+test io-40.4 {POSIX open access modes: CREAT} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ fconfigure $f -eofchar {}
+ puts $f xyzzy
+ close $f
+ set f [open $path(test3) {WRONLY CREAT}]
+ fconfigure $f -eofchar {}
+ puts -nonewline $f "ab"
+ close $f
+ set f [open $path(test3) r]
+ set x [gets $f]
+ close $f
+ set x
+} abzzy
+test io-40.5 {POSIX open access modes: APPEND} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f xyzzy
+ close $f
+ set f [open $path(test3) {WRONLY APPEND}]
+ fconfigure $f -translation lf
+ puts $f "new line"
+ seek $f 0
+ puts $f "abc"
+ close $f
+ set f [open $path(test3) r]
+ fconfigure $f -translation lf
+ set x ""
+ seek $f 6 current
+ lappend x [gets $f]
+ lappend x [gets $f]
+ close $f
+ set x
+} {{new line} abc}
+test io-40.6 {POSIX open access modes: EXCL} -match regexp -body {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ puts $f xyzzy
+ close $f
+ open $path(test3) {WRONLY CREAT EXCL}
+} -returnCodes error -result {(?i)couldn't open ".*test3": file (already )?exists}
+test io-40.7 {POSIX open access modes: EXCL} {
+ file delete $path(test3)
+ set f [open $path(test3) {WRONLY CREAT EXCL}]
+ fconfigure $f -eofchar {}
+ puts $f "A test line"
+ close $f
+ viewFile test3
+} {A test line}
+test io-40.8 {POSIX open access modes: TRUNC} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ puts $f xyzzy
+ close $f
+ set f [open $path(test3) {WRONLY TRUNC}]
+ puts $f abc
+ close $f
+ set f [open $path(test3) r]
+ set x [gets $f]
+ close $f
+ set x
+} abc
+test io-40.9 {POSIX open access modes: NONBLOCK} {nonPortable unix} {
+ file delete $path(test3)
+ set f [open $path(test3) {WRONLY NONBLOCK CREAT}]
+ puts $f "NONBLOCK test"
+ close $f
+ set f [open $path(test3) r]
+ set x [gets $f]
+ close $f
+ set x
+} {NONBLOCK test}
+test io-40.10 {POSIX open access modes: RDONLY} {
+ set f [open $path(test1) w]
+ puts $f "two lines: this one"
+ puts $f "and this"
+ close $f
+ set f [open $path(test1) RDONLY]
+ set x [list [gets $f] [catch {puts $f Test} msg] $msg]
+ close $f
+ string compare [string tolower $x] \
+ [list {two lines: this one} 1 \
+ [format "channel \"%s\" wasn't opened for writing" $f]]
+} 0
+test io-40.11 {POSIX open access modes: RDONLY} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) RDONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test io-40.12 {POSIX open access modes: WRONLY} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) WRONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test io-40.13 {POSIX open access modes: WRONLY} {
+ makeFile xyzzy test3
+ set f [open $path(test3) WRONLY]
+ fconfigure $f -eofchar {}
+ puts -nonewline $f "ab"
+ seek $f 0 current
+ set x [list [catch {gets $f} msg] $msg]
+ close $f
+ lappend x [viewFile test3]
+ string compare [string tolower $x] \
+ [list 1 "channel \"$f\" wasn't opened for reading" abzzy]
+} 0
+test io-40.14 {POSIX open access modes: RDWR} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) RDWR
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test io-40.15 {POSIX open access modes: RDWR} {
+ makeFile xyzzy test3
+ set f [open $path(test3) RDWR]
+ puts -nonewline $f "ab"
+ seek $f 0 current
+ set x [gets $f]
+ close $f
+ lappend x [viewFile test3]
+} {zzy abzzy}
+test io-40.16 {tilde substitution in open} -constraints makeFileInHome -setup {
+ makeFile {Some text} _test_ ~
+} -body {
+ file exists [file join $::env(HOME) _test_]
+} -cleanup {
+ removeFile _test_ ~
+} -result 1
+test io-40.17 {tilde substitution in open} {
+ set home $::env(HOME)
+ unset ::env(HOME)
+ set x [list [catch {open ~/foo} msg] $msg]
+ set ::env(HOME) $home
+ set x
+} {1 {couldn't find HOME environment variable to expand path}}
+
+test io-41.1 {Tcl_FileeventCmd: errors} {fileevent} {
+ list [catch {fileevent foo} msg] $msg
+} {1 {wrong # args: should be "fileevent channelId event ?script?"}}
+test io-41.2 {Tcl_FileeventCmd: errors} {fileevent} {
+ list [catch {fileevent foo bar baz q} msg] $msg
+} {1 {wrong # args: should be "fileevent channelId event ?script?"}}
+test io-41.3 {Tcl_FileeventCmd: errors} {fileevent} {
+ list [catch {fileevent gorp readable} msg] $msg
+} {1 {can not find channel named "gorp"}}
+test io-41.4 {Tcl_FileeventCmd: errors} {fileevent} {
+ list [catch {fileevent gorp writable} msg] $msg
+} {1 {can not find channel named "gorp"}}
+test io-41.5 {Tcl_FileeventCmd: errors} {fileevent} {
+ list [catch {fileevent gorp who-knows} msg] $msg
+} {1 {bad event name "who-knows": must be readable or writable}}
+
+#
+# Test fileevent on a file
+#
+
+set path(foo) [makeFile {} foo]
+set f [open $path(foo) w+]
+
+test io-42.1 {Tcl_FileeventCmd: creating, deleting, querying} {fileevent} {
+ list [fileevent $f readable] [fileevent $f writable]
+} {{} {}}
+test io-42.2 {Tcl_FileeventCmd: replacing} {fileevent} {
+ set result {}
+ fileevent $f r "first script"
+ lappend result [fileevent $f readable]
+ fileevent $f r "new script"
+ lappend result [fileevent $f readable]
+ fileevent $f r "yet another"
+ lappend result [fileevent $f readable]
+ fileevent $f r ""
+ lappend result [fileevent $f readable]
+} {{first script} {new script} {yet another} {}}
+test io-42.3 {Tcl_FileeventCmd: replacing, with NULL chars in script} {fileevent} {
+ set result {}
+ fileevent $f r "first scr\0ipt"
+ lappend result [string length [fileevent $f readable]]
+ fileevent $f r "new scr\0ipt"
+ lappend result [string length [fileevent $f readable]]
+ fileevent $f r "yet ano\0ther"
+ lappend result [string length [fileevent $f readable]]
+ fileevent $f r ""
+ lappend result [fileevent $f readable]
+} {13 11 12 {}}
+
+
+test io-43.1 {Tcl_FileeventCmd: creating, deleting, querying} {stdio unixExecs fileevent} {
+ set result {}
+ fileevent $f readable "script 1"
+ lappend result [fileevent $f readable] [fileevent $f writable]
+ fileevent $f writable "write script"
+ lappend result [fileevent $f readable] [fileevent $f writable]
+ fileevent $f readable {}
+ lappend result [fileevent $f readable] [fileevent $f writable]
+ fileevent $f writable {}
+ lappend result [fileevent $f readable] [fileevent $f writable]
+} {{script 1} {} {script 1} {write script} {} {write script} {} {}}
+test io-43.2 {Tcl_FileeventCmd: deleting when many present} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+ set result {}
+ lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
+ fileevent $f r "read f"
+ fileevent $f2 r "read f2"
+ fileevent $f3 r "read f3"
+ lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
+ fileevent $f2 r {}
+ lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
+ fileevent $f3 r {}
+ lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
+ fileevent $f r {}
+ lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
+} -cleanup {
+ catch {close $f2}
+ catch {close $f3}
+} -result {{} {} {} {read f} {read f2} {read f3} {read f} {} {read f3} {read f} {} {} {} {} {}}
+
+test io-44.1 {FileEventProc procedure: normal read event} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+ fileevent $f2 readable [namespace code {
+ set x [gets $f2]; fileevent $f2 readable {}
+ }]
+ puts $f2 text; flush $f2
+ variable x initial
+ vwait [namespace which -variable x]
+ set x
+} -cleanup {
+ catch {close $f2}
+ catch {close $f3}
+} -result {text}
+test io-44.2 {FileEventProc procedure: error in read event} -constraints {
+ stdio unixExecs fileevent openpipe
+} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+ proc myHandler {msg options} {
+ variable x $msg
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+} -body {
+ fileevent $f2 readable {error bogus}
+ puts $f2 text; flush $f2
+ variable x initial
+ vwait [namespace which -variable x]
+ list $x [fileevent $f2 readable]
+} -cleanup {
+ interp bgerror {} $handler
+ catch {close $f2}
+ catch {close $f3}
+} -result {bogus {}}
+test io-44.3 {FileEventProc procedure: normal write event} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+ fileevent $f2 writable [namespace code {
+ lappend x "triggered"
+ incr count -1
+ if {$count <= 0} {
+ fileevent $f2 writable {}
+ }
+ }]
+ variable x initial
+ set count 3
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ set x
+} -cleanup {
+ catch {close $f2}
+ catch {close $f3}
+} -result {initial triggered triggered triggered}
+test io-44.4 {FileEventProc procedure: eror in write event} -constraints {
+ stdio unixExecs fileevent openpipe
+} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+ proc myHandler {msg options} {
+ variable x $msg
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+} -body {
+ fileevent $f2 writable {error bad-write}
+ variable x initial
+ vwait [namespace which -variable x]
+ list $x [fileevent $f2 writable]
+} -cleanup {
+ interp bgerror {} $handler
+ catch {close $f2}
+ catch {close $f3}
+} -result {bad-write {}}
+test io-44.5 {FileEventProc procedure: end of file} {stdio unixExecs openpipe fileevent} {
+ set f4 [open "|[list [interpreter] $path(cat) << foo]" r]
+ fileevent $f4 readable [namespace code {
+ if {[gets $f4 line] < 0} {
+ lappend x eof
+ fileevent $f4 readable {}
+ } else {
+ lappend x $line
+ }
+ }]
+ variable x initial
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ close $f4
+ set x
+} {initial foo eof}
+
+close $f
+makeFile "foo bar" foo
+
+test io-45.1 {DeleteFileEvent, cleanup on close} {fileevent} {
+ set f [open $path(foo) r]
+ fileevent $f readable [namespace code {
+ lappend x "binding triggered: \"[gets $f]\""
+ fileevent $f readable {}
+ }]
+ close $f
+ set x initial
+ after 100 [namespace code { set y done }]
+ variable y
+ vwait [namespace which -variable y]
+ set x
+} {initial}
+test io-45.2 {DeleteFileEvent, cleanup on close} {fileevent} {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ fileevent $f readable [namespace code {
+ lappend x "f triggered: \"[gets $f]\""
+ fileevent $f readable {}
+ }]
+ fileevent $f2 readable [namespace code {
+ lappend x "f2 triggered: \"[gets $f2]\""
+ fileevent $f2 readable {}
+ }]
+ close $f
+ variable x initial
+ vwait [namespace which -variable x]
+ close $f2
+ set x
+} {initial {f2 triggered: "foo bar"}}
+test io-45.3 {DeleteFileEvent, cleanup on close} {fileevent} {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ set f3 [open $path(foo) r]
+ fileevent $f readable {f script}
+ fileevent $f2 readable {f2 script}
+ fileevent $f3 readable {f3 script}
+ set x {}
+ close $f2
+ lappend x [catch {fileevent $f readable} msg] $msg \
+ [catch {fileevent $f2 readable}] \
+ [catch {fileevent $f3 readable} msg] $msg
+ close $f3
+ lappend x [catch {fileevent $f readable} msg] $msg \
+ [catch {fileevent $f2 readable}] \
+ [catch {fileevent $f3 readable}]
+ close $f
+ lappend x [catch {fileevent $f readable}] \
+ [catch {fileevent $f2 readable}] \
+ [catch {fileevent $f3 readable}]
+} {0 {f script} 1 0 {f3 script} 0 {f script} 1 1 1 1 1}
+
+# Execute these tests only if the "testfevent" command is present.
+
+test io-46.1 {Tcl event loop vs multiple interpreters} {testfevent fileevent} {
+ testfevent create
+ set script "set f \[[list open $path(foo) r]]\n"
+ append script {
+ set x "no event"
+ fileevent $f readable [namespace code {
+ set x "f triggered: [gets $f]"
+ fileevent $f readable {}
+ }]
+ }
+ testfevent cmd $script
+ after 1 ;# We must delay because Windows takes a little time to notice
+ update
+ testfevent cmd {close $f}
+ list [testfevent cmd {set x}] [testfevent cmd {info commands after}]
+} {{f triggered: foo bar} after}
+test io-46.2 {Tcl event loop vs multiple interpreters} testfevent {
+ testfevent create
+ testfevent cmd {
+ variable x 0
+ after 100 {set x triggered}
+ vwait [namespace which -variable x]
+ set x
+ }
+} {triggered}
+test io-46.3 {Tcl event loop vs multiple interpreters} testfevent {
+ testfevent create
+ testfevent cmd {
+ set x 0
+ after 10 {lappend x timer}
+ after 30
+ set result $x
+ update idletasks
+ lappend result $x
+ update
+ lappend result $x
+ }
+} {0 0 {0 timer}}
+
+test io-47.1 {fileevent vs multiple interpreters} {testfevent fileevent} {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ set f3 [open $path(foo) r]
+ fileevent $f readable {script 1}
+ testfevent create
+ testfevent share $f2
+ testfevent cmd "fileevent $f2 readable {script 2}"
+ fileevent $f3 readable {sript 3}
+ set x {}
+ lappend x [fileevent $f2 readable]
+ testfevent delete
+ lappend x [fileevent $f readable] [fileevent $f2 readable] \
+ [fileevent $f3 readable]
+ close $f
+ close $f2
+ close $f3
+ set x
+} {{} {script 1} {} {sript 3}}
+test io-47.2 {deleting fileevent on interpreter delete} {testfevent fileevent} {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ set f3 [open $path(foo) r]
+ set f4 [open $path(foo) r]
+ fileevent $f readable {script 1}
+ testfevent create
+ testfevent share $f2
+ testfevent share $f3
+ testfevent cmd "fileevent $f2 readable {script 2}
+ fileevent $f3 readable {script 3}"
+ fileevent $f4 readable {script 4}
+ testfevent delete
+ set x [list [fileevent $f readable] [fileevent $f2 readable] \
+ [fileevent $f3 readable] [fileevent $f4 readable]]
+ close $f
+ close $f2
+ close $f3
+ close $f4
+ set x
+} {{script 1} {} {} {script 4}}
+test io-47.3 {deleting fileevent on interpreter delete} {testfevent fileevent} {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ set f3 [open $path(foo) r]
+ set f4 [open $path(foo) r]
+ testfevent create
+ testfevent share $f3
+ testfevent share $f4
+ fileevent $f readable {script 1}
+ fileevent $f2 readable {script 2}
+ testfevent cmd "fileevent $f3 readable {script 3}
+ fileevent $f4 readable {script 4}"
+ testfevent delete
+ set x [list [fileevent $f readable] [fileevent $f2 readable] \
+ [fileevent $f3 readable] [fileevent $f4 readable]]
+ close $f
+ close $f2
+ close $f3
+ close $f4
+ set x
+} {{script 1} {script 2} {} {}}
+test io-47.4 {file events on shared files and multiple interpreters} {testfevent fileevent} {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ testfevent create
+ testfevent share $f
+ testfevent cmd "fileevent $f readable {script 1}"
+ fileevent $f readable {script 2}
+ fileevent $f2 readable {script 3}
+ set x [list [fileevent $f2 readable] \
+ [testfevent cmd "fileevent $f readable"] \
+ [fileevent $f readable]]
+ testfevent delete
+ close $f
+ close $f2
+ set x
+} {{script 3} {script 1} {script 2}}
+test io-47.5 {file events on shared files, deleting file events} {testfevent fileevent} {
+ set f [open $path(foo) r]
+ testfevent create
+ testfevent share $f
+ testfevent cmd "fileevent $f readable {script 1}"
+ fileevent $f readable {script 2}
+ testfevent cmd "fileevent $f readable {}"
+ set x [list [testfevent cmd "fileevent $f readable"] \
+ [fileevent $f readable]]
+ testfevent delete
+ close $f
+ set x
+} {{} {script 2}}
+test io-47.6 {file events on shared files, deleting file events} {testfevent fileevent} {
+ set f [open $path(foo) r]
+ testfevent create
+ testfevent share $f
+ testfevent cmd "fileevent $f readable {script 1}"
+ fileevent $f readable {script 2}
+ fileevent $f readable {}
+ set x [list [testfevent cmd "fileevent $f readable"] \
+ [fileevent $f readable]]
+ testfevent delete
+ close $f
+ set x
+} {{script 1} {}}
+
+set path(bar) [makeFile {} bar]
+
+test io-48.1 {testing readability conditions} {fileevent} {
+ set f [open $path(bar) w]
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ close $f
+ set f [open $path(bar) r]
+ fileevent $f readable [namespace code [list consume $f]]
+ proc consume {f} {
+ variable l
+ variable x
+ lappend l called
+ if {[eof $f]} {
+ close $f
+ set x done
+ } else {
+ gets $f
+ }
+ }
+ set l ""
+ variable x not_done
+ vwait [namespace which -variable x]
+ list $x $l
+} {done {called called called called called called called}}
+test io-48.2 {testing readability conditions} {nonBlockFiles fileevent} {
+ set f [open $path(bar) w]
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ close $f
+ set f [open $path(bar) r]
+ fileevent $f readable [namespace code [list consume $f]]
+ fconfigure $f -blocking off
+ proc consume {f} {
+ variable x
+ variable l
+ lappend l called
+ if {[eof $f]} {
+ close $f
+ set x done
+ } else {
+ gets $f
+ }
+ }
+ set l ""
+ variable x not_done
+ vwait [namespace which -variable x]
+ list $x $l
+} {done {called called called called called called called}}
+set path(my_script) [makeFile {} my_script]
+test io-48.3 {testing readability conditions} {stdio unix nonBlockFiles openpipe fileevent} {
+ set f [open $path(bar) w]
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ close $f
+ set f [open $path(my_script) w]
+ puts $f {
+ proc copy_slowly {f} {
+ while {![eof $f]} {
+ puts [gets $f]
+ after 200
+ }
+ close $f
+ }
+ }
+ close $f
+ set f [open "|[list [interpreter]]" r+]
+ fileevent $f readable [namespace code [list consume $f]]
+ fconfigure $f -buffering line
+ fconfigure $f -blocking off
+ proc consume {f} {
+ variable l
+ variable x
+ if {[eof $f]} {
+ set x done
+ } else {
+ gets $f
+ lappend l [fblocked $f]
+ gets $f
+ lappend l [fblocked $f]
+ }
+ }
+ set l ""
+ variable x not_done
+ puts $f [list source $path(my_script)]
+ puts $f "set f \[[list open $path(bar) r]]"
+ puts $f {copy_slowly $f}
+ puts $f {exit}
+ vwait [namespace which -variable x]
+ close $f
+ list $x $l
+} {done {0 1 0 1 0 1 0 1 0 1 0 1 0 0}}
+test io-48.4 {lf write, testing readability, ^Z termination, auto read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ variable c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable c
+ variable x
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.5 {lf write, testing readability, ^Z in middle, auto read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable x
+ variable c
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.6 {cr write, testing readability, ^Z termination, auto read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ set c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable x
+ variable c
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.7 {cr write, testing readability, ^Z in middle, auto read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable c
+ variable x
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.8 {crlf write, testing readability, ^Z termination, auto read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable x
+ variable c
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.9 {crlf write, testing readability, ^Z in middle, auto read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable c
+ variable x
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.10 {lf write, testing readability, ^Z in middle, lf read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable c
+ variable x
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation lf
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.11 {lf write, testing readability, ^Z termination, lf read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable x
+ variable c
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf -eofchar \x1a
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.12 {cr write, testing readability, ^Z in middle, cr read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable x
+ variable c
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation cr
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.13 {cr write, testing readability, ^Z termination, cr read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ set c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable c
+ variable x
+ variable l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr -eofchar \x1a
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.14 {crlf write, testing readability, ^Z in middle, crlf read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable c
+ variable x
+ variable l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation crlf
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.15 {crlf write, testing readability, ^Z termi, crlf read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable c
+ variable x
+ variable l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf -eofchar \x1a
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+
+test io-49.1 {testing crlf reading, leftover cr disgorgment} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\rb\rc\r\n"
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [file size $path(test1)]
+ fconfigure $f -translation crlf
+ lappend l [read $f 1]
+ lappend l [tell $f]
+ lappend l [read $f 1]
+ lappend l [tell $f]
+ lappend l [read $f 1]
+ lappend l [tell $f]
+ lappend l [read $f 1]
+ lappend l [tell $f]
+ lappend l [read $f 1]
+ lappend l [tell $f]
+ lappend l [read $f 1]
+ lappend l [tell $f]
+ lappend l [eof $f]
+ lappend l [read $f 1]
+ lappend l [eof $f]
+ close $f
+ set l
+} "7 a 1 [list \r] 2 b 3 [list \r] 4 c 5 {
+} 7 0 {} 1"
+test io-49.2 {testing crlf reading, leftover cr disgorgment} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\rb\rc\r\n"
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [file size $path(test1)]
+ fconfigure $f -translation crlf
+ lappend l [read $f 2]
+ lappend l [tell $f]
+ lappend l [read $f 2]
+ lappend l [tell $f]
+ lappend l [read $f 2]
+ lappend l [tell $f]
+ lappend l [eof $f]
+ lappend l [read $f 2]
+ lappend l [tell $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} "7 [list a\r] 2 [list b\r] 4 [list c\n] 7 0 {} 7 1"
+test io-49.3 {testing crlf reading, leftover cr disgorgment} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\rb\rc\r\n"
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [file size $path(test1)]
+ fconfigure $f -translation crlf
+ lappend l [read $f 3]
+ lappend l [tell $f]
+ lappend l [read $f 3]
+ lappend l [tell $f]
+ lappend l [eof $f]
+ lappend l [read $f 3]
+ lappend l [tell $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} "7 [list a\rb] 3 [list \rc\n] 7 0 {} 7 1"
+test io-49.4 {testing crlf reading, leftover cr disgorgment} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\rb\rc\r\n"
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [file size $path(test1)]
+ fconfigure $f -translation crlf
+ lappend l [read $f 3]
+ lappend l [tell $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} "7 [list a\rb] 3 [list \rc] 7 0 {} 7 1"
+test io-49.5 {testing crlf reading, leftover cr disgorgment} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\rb\rc\r\n"
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [file size $path(test1)]
+ fconfigure $f -translation crlf
+ lappend l [set x [gets $f]]
+ lappend l [tell $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} [list 7 a\rb\rc 7 {} 7 1]
+
+test io-50.1 {testing handler deletion} {testchannelevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list delhandler $f]]
+ proc delhandler {f} {
+ variable z
+ set z called
+ testchannelevent $f delete 0
+ }
+ set z not_called
+ update
+ close $f
+ set z
+} called
+test io-50.2 {testing handler deletion with multiple handlers} {testchannelevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list delhandler $f 1]]
+ testchannelevent $f add readable [namespace code [list delhandler $f 0]]
+ proc delhandler {f i} {
+ variable z
+ lappend z "called delhandler $f $i"
+ testchannelevent $f delete 0
+ }
+ set z ""
+ update
+ close $f
+ string compare [string tolower $z] \
+ [list [list called delhandler $f 0] [list called delhandler $f 1]]
+} 0
+test io-50.3 {testing handler deletion with multiple handlers} {testchannelevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list notcalled $f 1]]
+ testchannelevent $f add readable [namespace code [list delhandler $f 0]]
+ set z ""
+ proc notcalled {f i} {
+ variable z
+ lappend z "notcalled was called!! $f $i"
+ }
+ proc delhandler {f i} {
+ variable z
+ testchannelevent $f delete 1
+ lappend z "delhandler $f $i called"
+ testchannelevent $f delete 0
+ lappend z "delhandler $f $i deleted myself"
+ }
+ set z ""
+ update
+ close $f
+ string compare [string tolower $z] \
+ [list [list delhandler $f 0 called] \
+ [list delhandler $f 0 deleted myself]]
+} 0
+test io-50.4 {testing handler deletion vs reentrant calls} {testchannelevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list delrecursive $f]]
+ proc delrecursive {f} {
+ variable z
+ variable u
+ if {"$u" == "recursive"} {
+ testchannelevent $f delete 0
+ lappend z "delrecursive deleting recursive"
+ } else {
+ lappend z "delrecursive calling recursive"
+ set u recursive
+ update
+ }
+ }
+ variable u toplevel
+ variable z ""
+ update
+ close $f
+ string compare [string tolower $z] \
+ {{delrecursive calling recursive} {delrecursive deleting recursive}}
+} 0
+test io-50.5 {testing handler deletion vs reentrant calls} {testchannelevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list notcalled $f]]
+ testchannelevent $f add readable [namespace code [list del $f]]
+ proc notcalled {f} {
+ variable z
+ lappend z "notcalled was called!! $f"
+ }
+ proc del {f} {
+ variable u
+ variable z
+ if {"$u" == "recursive"} {
+ testchannelevent $f delete 1
+ testchannelevent $f delete 0
+ lappend z "del deleted notcalled"
+ lappend z "del deleted myself"
+ } else {
+ set u recursive
+ lappend z "del calling recursive"
+ update
+ lappend z "del after update"
+ }
+ }
+ set z ""
+ set u toplevel
+ update
+ close $f
+ string compare [string tolower $z] \
+ [list {del calling recursive} {del deleted notcalled} \
+ {del deleted myself} {del after update}]
+} 0
+test io-50.6 {testing handler deletion vs reentrant calls} {testchannelevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list second $f]]
+ testchannelevent $f add readable [namespace code [list first $f]]
+ proc first {f} {
+ variable u
+ variable z
+ if {"$u" == "toplevel"} {
+ lappend z "first called"
+ set u first
+ update
+ lappend z "first after update"
+ } else {
+ lappend z "first called not toplevel"
+ }
+ }
+ proc second {f} {
+ variable u
+ variable z
+ if {"$u" == "first"} {
+ lappend z "second called, first time"
+ set u second
+ testchannelevent $f delete 0
+ } elseif {"$u" == "second"} {
+ lappend z "second called, second time"
+ testchannelevent $f delete 0
+ } else {
+ lappend z "second called, cannot happen!"
+ testchannelevent $f removeall
+ }
+ }
+ set z ""
+ set u toplevel
+ update
+ close $f
+ string compare [string tolower $z] \
+ [list {first called} {first called not toplevel} \
+ {second called, first time} {second called, second time} \
+ {first after update}]
+} 0
+
+test io-51.1 {Test old socket deletion on Macintosh} {socket} {
+ set x 0
+ set result ""
+ proc accept {s a p} {
+ variable x
+ variable wait
+ fconfigure $s -blocking off
+ puts $s "sock[incr x]"
+ close $s
+ set wait done
+ }
+ set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $ss -sockname] 2]
+
+ variable wait ""
+ set cs [socket 127.0.0.1 $port]
+ vwait [namespace which -variable wait]
+ lappend result [gets $cs]
+ close $cs
+
+ set wait ""
+ set cs [socket 127.0.0.1 $port]
+ vwait [namespace which -variable wait]
+ lappend result [gets $cs]
+ close $cs
+
+ set wait ""
+ set cs [socket 127.0.0.1 $port]
+ vwait [namespace which -variable wait]
+ lappend result [gets $cs]
+ close $cs
+
+ set wait ""
+ set cs [socket 127.0.0.1 $port]
+ vwait [namespace which -variable wait]
+ lappend result [gets $cs]
+ close $cs
+ close $ss
+ set result
+} {sock1 sock2 sock3 sock4}
+
+test io-52.1 {TclCopyChannel} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fcopy $f1 $f2 -command { # }
+ catch { fcopy $f1 $f2 } msg
+ close $f1
+ close $f2
+ string compare $msg "channel \"$f1\" is busy"
+} {0}
+test io-52.2 {TclCopyChannel} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ set f3 [open $thisScript]
+ fcopy $f1 $f2 -command { # }
+ catch { fcopy $f3 $f2 } msg
+ close $f1
+ close $f2
+ close $f3
+ string compare $msg "channel \"$f2\" is busy"
+} {0}
+test io-52.3 {TclCopyChannel} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation cr -blocking 0
+ set s0 [fcopy $f1 $f2]
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ close $f1
+ close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {("$s1" == "$s2") && ($s0 == $s1)} {
+ lappend result ok
+ }
+ set result
+} {0 0 ok}
+test io-52.4 {TclCopyChannel} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation cr -blocking 0
+ fcopy $f1 $f2 -size 40
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ close $f1
+ close $f2
+ lappend result [file size $path(test1)]
+} {0 0 40}
+test io-52.5 {TclCopyChannel, all} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation lf -blocking 0
+ fcopy $f1 $f2 -size -1 ;# -1 means 'copy all', same as if no -size specified.
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ close $f1
+ close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {"$s1" == "$s2"} {
+ lappend result ok
+ }
+ set result
+} {0 0 ok}
+test io-52.5a {TclCopyChannel, all, other negative value} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation lf -blocking 0
+ fcopy $f1 $f2 -size -2 ;# < 0 behaves like -1, copy all
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ close $f1
+ close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {"$s1" == "$s2"} {
+ lappend result ok
+ }
+ set result
+} {0 0 ok}
+test io-52.5b {TclCopyChannel, all, wrap to negative value} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation lf -blocking 0
+ fcopy $f1 $f2 -size 3221176172 ;# Wrapped to < 0, behaves like -1, copy all
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ close $f1
+ close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {"$s1" == "$s2"} {
+ lappend result ok
+ }
+ set result
+} {0 0 ok}
+test io-52.6 {TclCopyChannel} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation lf -blocking 0
+ set s0 [fcopy $f1 $f2 -size [expr [file size $thisScript] + 5]]
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ close $f1
+ close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {("$s1" == "$s2") && ($s0 == $s1)} {
+ lappend result ok
+ }
+ set result
+} {0 0 ok}
+test io-52.7 {TclCopyChannel} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation lf -blocking 0
+ fcopy $f1 $f2
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ close $f1
+ close $f2
+ if {"$s1" == "$s2"} {
+ lappend result ok
+ }
+ set result
+} {0 0 ok}
+test io-52.8 {TclCopyChannel} {stdio openpipe fcopy} {
+ file delete $path(test1)
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ fconfigure $f1 -translation lf
+ puts $f1 "
+ puts ready
+ gets stdin
+ set f1 \[open [list $thisScript] r\]
+ fconfigure \$f1 -translation lf
+ puts \[read \$f1 100\]
+ close \$f1
+ "
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ fconfigure $f1 -translation lf
+ gets $f1
+ puts $f1 ready
+ flush $f1
+ set f2 [open $path(test1) w]
+ fconfigure $f2 -translation lf
+ set s0 [fcopy $f1 $f2 -size 40]
+ catch {close $f1}
+ close $f2
+ list $s0 [file size $path(test1)]
+} {40 40}
+# Empty files, to register them with the test facility
+set path(kyrillic.txt) [makeFile {} kyrillic.txt]
+set path(utf8-fcopy.txt) [makeFile {} utf8-fcopy.txt]
+set path(utf8-rp.txt) [makeFile {} utf8-rp.txt]
+# Create kyrillic file, use lf translation to avoid os eol issues
+set out [open $path(kyrillic.txt) w]
+fconfigure $out -encoding koi8-r -translation lf
+puts $out "\u0410\u0410"
+close $out
+test io-52.9 {TclCopyChannel & encodings} {fcopy} {
+ # Copy kyrillic to UTF-8, using fcopy.
+
+ set in [open $path(kyrillic.txt) r]
+ set out [open $path(utf8-fcopy.txt) w]
+
+ fconfigure $in -encoding koi8-r -translation lf
+ fconfigure $out -encoding utf-8 -translation lf
+
+ fcopy $in $out
+ close $in
+ close $out
+
+ # Do the same again, but differently (read/puts).
+
+ set in [open $path(kyrillic.txt) r]
+ set out [open $path(utf8-rp.txt) w]
+
+ fconfigure $in -encoding koi8-r -translation lf
+ fconfigure $out -encoding utf-8 -translation lf
+
+ puts -nonewline $out [read $in]
+
+ close $in
+ close $out
+
+ list [file size $path(kyrillic.txt)] \
+ [file size $path(utf8-fcopy.txt)] \
+ [file size $path(utf8-rp.txt)]
+} {3 5 5}
+test io-52.10 {TclCopyChannel & encodings} {fcopy} {
+ # encoding to binary (=> implies that the
+ # internal utf-8 is written)
+
+ set in [open $path(kyrillic.txt) r]
+ set out [open $path(utf8-fcopy.txt) w]
+
+ fconfigure $in -encoding koi8-r -translation lf
+ # -translation binary is also -encoding binary
+ fconfigure $out -translation binary
+
+ fcopy $in $out
+ close $in
+ close $out
+
+ file size $path(utf8-fcopy.txt)
+} 5
+test io-52.11 {TclCopyChannel & encodings} {fcopy} {
+ # binary to encoding => the input has to be
+ # in utf-8 to make sense to the encoder
+
+ set in [open $path(utf8-fcopy.txt) r]
+ set out [open $path(kyrillic.txt) w]
+
+ # -translation binary is also -encoding binary
+ fconfigure $in -translation binary
+ fconfigure $out -encoding koi8-r -translation lf
+
+ fcopy $in $out
+ close $in
+ close $out
+
+ file size $path(kyrillic.txt)
+} 3
+
+test io-53.1 {CopyData} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation cr -blocking 0
+ fcopy $f1 $f2 -size 0
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ close $f1
+ close $f2
+ lappend result [file size $path(test1)]
+} {0 0 0}
+test io-53.2 {CopyData} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation cr -blocking 0
+ fcopy $f1 $f2 -command [namespace code {set s0}]
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ variable s0
+ vwait [namespace which -variable s0]
+ close $f1
+ close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {("$s1" == "$s2") && ($s0 == $s1)} {
+ lappend result ok
+ }
+ set result
+} {0 0 ok}
+test io-53.3 {CopyData: background read underflow} {stdio unix openpipe fcopy} {
+ file delete $path(test1)
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts -nonewline $f1 {
+ puts ready
+ flush stdout ;# Don't assume line buffered!
+ fcopy stdin stdout -command { set x }
+ vwait x
+ set f [}
+ puts $f1 [list open $path(test1) w]]
+ puts $f1 {
+ fconfigure $f -translation lf
+ puts $f "done"
+ close $f
+ }
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ set result [gets $f1]
+ puts $f1 line1
+ flush $f1
+ lappend result [gets $f1]
+ puts $f1 line2
+ flush $f1
+ lappend result [gets $f1]
+ close $f1
+ after 500
+ set f [open $path(test1)]
+ lappend result [read $f]
+ close $f
+ set result
+} "ready line1 line2 {done\n}"
+test io-53.4 {CopyData: background write overflow} {stdio unix openpipe fileevent fcopy} {
+ set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n
+ variable x
+ for {set x 0} {$x < 12} {incr x} {
+ append big $big
+ }
+ file delete $path(test1)
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {
+ puts ready
+ fcopy stdin stdout -command { set x }
+ vwait x
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f "done"
+ close $f
+ }
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ set result [gets $f1]
+ fconfigure $f1 -blocking 0
+ puts $f1 $big
+ flush $f1
+ after 500
+ set result ""
+ fileevent $f1 read [namespace code {
+ append result [read $f1 1024]
+ if {[string length $result] >= [string length $big]} {
+ set x done
+ }
+ }]
+ vwait [namespace which -variable x]
+ close $f1
+ set big {}
+ set x
+} done
+set result {}
+proc FcopyTestAccept {sock args} {
+ after 1000 "close $sock"
+}
+proc FcopyTestDone {bytes {error {}}} {
+ variable fcopyTestDone
+ if {[string length $error]} {
+ set fcopyTestDone 1
+ } else {
+ set fcopyTestDone 0
+ }
+}
+test io-53.5 {CopyData: error during fcopy} {socket fcopy} {
+ variable fcopyTestDone
+ set listen [socket -server [namespace code FcopyTestAccept] -myaddr 127.0.0.1 0]
+ set in [open $thisScript] ;# 126 K
+ set out [socket 127.0.0.1 [lindex [fconfigure $listen -sockname] 2]]
+ catch {unset fcopyTestDone}
+ close $listen ;# This means the socket open never really succeeds
+ fcopy $in $out -command [namespace code FcopyTestDone]
+ variable fcopyTestDone
+ if ![info exists fcopyTestDone] {
+ vwait [namespace which -variable fcopyTestDone] ;# The error occurs here in the b.g.
+ }
+ close $in
+ close $out
+ set fcopyTestDone ;# 1 for error condition
+} 1
+test io-53.6 {CopyData: error during fcopy} {stdio openpipe fcopy} {
+ variable fcopyTestDone
+ file delete $path(pipe)
+ file delete $path(test1)
+ catch {unset fcopyTestDone}
+ set f1 [open $path(pipe) w]
+ puts $f1 "exit 1"
+ close $f1
+ set in [open "|[list [interpreter] $path(pipe)]" r+]
+ set out [open $path(test1) w]
+ fcopy $in $out -command [namespace code FcopyTestDone]
+ variable fcopyTestDone
+ if ![info exists fcopyTestDone] {
+ vwait [namespace which -variable fcopyTestDone]
+ }
+ catch {close $in}
+ close $out
+ set fcopyTestDone ;# 0 for plain end of file
+} {0}
+proc doFcopy {in out {bytes 0} {error {}}} {
+ variable fcopyTestDone
+ variable fcopyTestCount
+ incr fcopyTestCount $bytes
+ if {[string length $error]} {
+ set fcopyTestDone 1
+ } elseif {[eof $in]} {
+ set fcopyTestDone 0
+ } else {
+ # Delay next fcopy to wait for size>0 input bytes
+ after 100 [list fcopy $in $out -size 1000 \
+ -command [namespace code [list doFcopy $in $out]]]
+ }
+}
+test io-53.7 {CopyData: Flooding fcopy from pipe} {stdio openpipe fcopy} {
+ variable fcopyTestDone
+ file delete $path(pipe)
+ catch {unset fcopyTestDone}
+ set fcopyTestCount 0
+ set f1 [open $path(pipe) w]
+ puts $f1 {
+ # Write 10 bytes / 10 msec
+ proc Write {count} {
+ puts -nonewline "1234567890"
+ if {[incr count -1]} {
+ after 10 [list Write $count]
+ } else {
+ set ::ready 1
+ }
+ }
+ fconfigure stdout -buffering none
+ Write 345 ;# 3450 bytes ~3.45 sec
+ vwait ready
+ exit 0
+ }
+ close $f1
+ set in [open "|[list [interpreter] $path(pipe) &]" r+]
+ set out [open $path(test1) w]
+ doFcopy $in $out
+ variable fcopyTestDone
+ if ![info exists fcopyTestDone] {
+ vwait [namespace which -variable fcopyTestDone]
+ }
+ catch {close $in}
+ close $out
+ # -1=error 0=script error N=number of bytes
+ expr ($fcopyTestDone == 0) ? $fcopyTestCount : -1
+} {3450}
+test io-53.8 {CopyData: async callback and error handling, Bug 1932639} -setup {
+ # copy progress callback. errors out intentionally
+ proc ::cmd args {
+ lappend ::RES "CMD $args"
+ error !STOP
+ }
+ # capture callback error here
+ proc ::bgerror args {
+ lappend ::RES "bgerror/OK $args"
+ set ::forever has-been-reached
+ return
+ }
+ # Files we use for our channels
+ set foo [makeFile ashgdfashdgfasdhgfasdhgf foo]
+ set bar [makeFile {} bar]
+ # Channels to copy between
+ set f [open $foo r] ; fconfigure $f -translation binary
+ set g [open $bar w] ; fconfigure $g -translation binary -buffering none
+} -constraints {stdio openpipe fcopy} -body {
+ # Record input size, so that result is always defined
+ lappend ::RES [file size $bar]
+ # Run the copy. Should not invoke -command now.
+ fcopy $f $g -size 2 -command ::cmd
+ # Check that -command was not called synchronously
+ set sbs [file size $bar]
+ lappend ::RES [expr {($sbs > 0) ? "sync/FAIL" : "sync/OK"}] $sbs
+ # Now let the async part happen. Should capture the error in cmd
+ # via bgerror. If not break the event loop via timer.
+ set token [after 1000 {
+ lappend ::RES {bgerror/FAIL timeout}
+ set ::forever has-been-reached
+ }]
+ vwait ::forever
+ catch {after cancel $token}
+ # Report
+ set ::RES
+} -cleanup {
+ close $f
+ close $g
+ catch {unset ::RES}
+ catch {unset ::forever}
+ rename ::cmd {}
+ rename ::bgerror {}
+ removeFile foo
+ removeFile bar
+} -result {0 sync/OK 0 {CMD 2} {bgerror/OK !STOP}}
+test io-53.8a {CopyData: async callback and error handling, Bug 1932639, at eof} -setup {
+ # copy progress callback. errors out intentionally
+ proc ::cmd args {
+ lappend ::RES "CMD $args"
+ set ::forever has-been-reached
+ return
+ }
+ # Files we use for our channels
+ set foo [makeFile ashgdfashdgfasdhgfasdhgf foo]
+ set bar [makeFile {} bar]
+ # Channels to copy between
+ set f [open $foo r] ; fconfigure $f -translation binary
+ set g [open $bar w] ; fconfigure $g -translation binary -buffering none
+} -constraints {stdio openpipe fcopy} -body {
+ # Initialize and force eof on the input.
+ seek $f 0 end ; read $f 1
+ set ::RES [eof $f]
+ # Run the copy. Should not invoke -command now.
+ fcopy $f $g -size 2 -command ::cmd
+ # Check that -command was not called synchronously
+ lappend ::RES [expr {([llength $::RES] > 1) ? "sync/FAIL" : "sync/OK"}]
+ # Now let the async part happen. Should capture the eof in cmd
+ # If not break the event loop via timer.
+ set token [after 1000 {
+ lappend ::RES {cmd/FAIL timeout}
+ set ::forever has-been-reached
+ }]
+ vwait ::forever
+ catch {after cancel $token}
+ # Report
+ set ::RES
+} -cleanup {
+ close $f
+ close $g
+ catch {unset ::RES}
+ catch {unset ::forever}
+ rename ::cmd {}
+ removeFile foo
+ removeFile bar
+} -result {1 sync/OK {CMD 0}}
+test io-53.8b {CopyData: async callback and -size 0} -setup {
+ # copy progress callback. errors out intentionally
+ proc ::cmd args {
+ lappend ::RES "CMD $args"
+ set ::forever has-been-reached
+ return
+ }
+ # Files we use for our channels
+ set foo [makeFile ashgdfashdgfasdhgfasdhgf foo]
+ set bar [makeFile {} bar]
+ # Channels to copy between
+ set f [open $foo r] ; fconfigure $f -translation binary
+ set g [open $bar w] ; fconfigure $g -translation binary -buffering none
+} -constraints {stdio openpipe fcopy} -body {
+ set ::RES {}
+ # Run the copy. Should not invoke -command now.
+ fcopy $f $g -size 0 -command ::cmd
+ # Check that -command was not called synchronously
+ lappend ::RES [expr {([llength $::RES] > 1) ? "sync/FAIL" : "sync/OK"}]
+ # Now let the async part happen. Should capture the eof in cmd
+ # If not break the event loop via timer.
+ set token [after 1000 {
+ lappend ::RES {cmd/FAIL timeout}
+ set ::forever has-been-reached
+ }]
+ vwait ::forever
+ catch {after cancel $token}
+ # Report
+ set ::RES
+} -cleanup {
+ close $f
+ close $g
+ catch {unset ::RES}
+ catch {unset ::forever}
+ rename ::cmd {}
+ removeFile foo
+ removeFile bar
+} -result {sync/OK {CMD 0}}
+test io-53.9 {CopyData: -size and event interaction, Bug 780533} -setup {
+ set out [makeFile {} out]
+ set err [makeFile {} err]
+ set pipe [open "|[list [info nameofexecutable] 2> $err]" r+]
+ fconfigure $pipe -translation binary -buffering line
+ puts $pipe {
+ fconfigure stdout -translation binary -buffering line
+ puts stderr Waiting...
+ after 1000
+ foreach x {a b c} {
+ puts stderr Looping...
+ puts $x
+ after 500
+ }
+ proc bye args {
+ if {[gets stdin line]<0} {
+ puts stderr "CHILD: EOF detected, exiting"
+ exit
+ } else {
+ puts stderr "CHILD: ignoring line: $line"
+ }
+ }
+ puts stderr Now-sleeping-forever
+ fileevent stdin readable bye
+ vwait forever
+ }
+ proc ::done args {
+ set ::forever OK
+ return
+ }
+ set ::forever {}
+ set out [open $out w]
+} -constraints {stdio openpipe fcopy} -body {
+ fcopy $pipe $out -size 6 -command ::done
+ set token [after 5000 {
+ set ::forever {fcopy hangs}
+ }]
+ vwait ::forever
+ catch {after cancel $token}
+ set ::forever
+} -cleanup {
+ close $pipe
+ rename ::done {}
+ after 1000; # Give Windows time to kill the process
+ catch {close $out}
+ catch {removeFile out}
+ catch {removeFile err}
+ catch {unset ::forever}
+} -result OK
+test io-53.10 {Bug 1350564, multi-directional fcopy} -setup {
+ set err [makeFile {} err]
+ set pipe [open "|[list [info nameofexecutable] 2> $err]" r+]
+ fconfigure $pipe -translation binary -buffering line
+ puts $pipe {
+ fconfigure stderr -buffering line
+ # Kill server when pipe closed by invoker.
+ proc bye args {
+ if {![eof stdin]} { gets stdin ; return }
+ puts stderr BYE
+ exit
+ }
+ # Server code. Bi-directional copy between 2 sockets.
+ proc geof {sok} {
+ puts stderr DONE/$sok
+ close $sok
+ }
+ proc new {sok args} {
+ puts stderr NEW/$sok
+ global l srv
+ fconfigure $sok -translation binary -buffering none
+ lappend l $sok
+ if {[llength $l]==2} {
+ close $srv
+ foreach {a b} $l break
+ fcopy $a $b -command [list geof $a]
+ fcopy $b $a -command [list geof $b]
+ puts stderr 2COPY
+ }
+ puts stderr ...
+ }
+ puts stderr SRV
+ set l {}
+ set srv [socket -server new 9999]
+ puts stderr WAITING
+ fileevent stdin readable bye
+ puts OK
+ vwait forever
+ }
+ # wait for OK from server.
+ gets $pipe
+ # Now the two clients.
+ proc ::done {sock} {
+ if {[eof $sock]} { close $sock ; return }
+ lappend ::forever [gets $sock]
+ return
+ }
+ set a [socket 127.0.0.1 9999]
+ set b [socket 127.0.0.1 9999]
+ fconfigure $a -translation binary -buffering none
+ fconfigure $b -translation binary -buffering none
+ fileevent $a readable [list ::done $a]
+ fileevent $b readable [list ::done $b]
+} -constraints {stdio openpipe fcopy} -body {
+ # Now pass data through the server in both directions.
+ set ::forever {}
+ puts $a AB
+ vwait ::forever
+ puts $b BA
+ vwait ::forever
+ set ::forever
+} -cleanup {
+ catch {close $a}
+ catch {close $b}
+ close $pipe
+ rename ::done {}
+ after 1000 ;# Give Windows time to kill the process
+ removeFile err
+ catch {unset ::forever}
+} -result {AB BA}
+test io-53.11 {Bug 2895565} -setup {
+ set in [makeFile {} in]
+ set f [open $in w]
+ fconfigure $f -encoding utf-8 -translation binary
+ puts -nonewline $f [string repeat "Ho hum\n" 11]
+ close $f
+ set inChan [open $in r]
+ fconfigure $inChan -translation binary
+ set out [makeFile {} out]
+ set outChan [open $out w]
+ fconfigure $outChan -encoding cp1252 -translation crlf
+ proc CopyDone {bytes args} {
+ variable done
+ if {[llength $args]} {
+ set done "Error: '[lindex $args 0]' after $bytes bytes copied"
+ } else {
+ set done "$bytes bytes copied"
+ }
+ }
+} -body {
+ variable done
+ after 2000 [list set [namespace which -variable done] timeout]
+ fcopy $inChan $outChan -size 40 -command [namespace which CopyDone]
+ vwait [namespace which -variable done]
+ set done
+} -cleanup {
+ close $outChan
+ close $inChan
+ removeFile out
+ removeFile in
+} -result {40 bytes copied}
+
+test io-54.1 {Recursive channel events} {socket fileevent} {
+ # This test checks to see if file events are delivered during recursive
+ # event loops when there is buffered data on the channel.
+
+ proc accept {s a p} {
+ variable as
+ fconfigure $s -translation lf
+ puts $s "line 1\nline2\nline3"
+ flush $s
+ set as $s
+ }
+ proc readit {s next} {
+ variable x
+ variable result
+ lappend result $next
+ if {$next == 1} {
+ fileevent $s readable [namespace code [list readit $s 2]]
+ vwait [namespace which -variable x]
+ }
+ incr x
+ }
+ set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+
+ # We need to delay on some systems until the creation of the
+ # server socket completes.
+
+ set done 0
+ for {set i 0} {$i < 10} {incr i} {
+ if {![catch {set cs [socket 127.0.0.1 [lindex [fconfigure $ss -sockname] 2]]}]} {
+ set done 1
+ break
+ }
+ after 100
+ }
+ if {$done == 0} {
+ close $ss
+ error "failed to connect to server"
+ }
+ variable result {}
+ variable x 0
+ variable as
+ vwait [namespace which -variable as]
+ fconfigure $cs -translation lf
+ lappend result [gets $cs]
+ fconfigure $cs -blocking off
+ fileevent $cs readable [namespace code [list readit $cs 1]]
+ set a [after 2000 [namespace code { set x failure }]]
+ vwait [namespace which -variable x]
+ after cancel $a
+ close $as
+ close $ss
+ close $cs
+ list $result $x
+} {{{line 1} 1 2} 2}
+test io-54.2 {Testing for busy-wait in recursive channel events} {socket fileevent} {
+ set accept {}
+ set after {}
+ variable s [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ proc accept {s a p} {
+ variable counter
+ variable accept
+
+ set accept $s
+ set counter 0
+ fconfigure $s -blocking off -buffering line -translation lf
+ fileevent $s readable [namespace code "doit $s"]
+ }
+ proc doit {s} {
+ variable counter
+ variable after
+
+ incr counter
+ set l [gets $s]
+ if {"$l" == ""} {
+ fileevent $s readable [namespace code "doit1 $s"]
+ set after [after 1000 [namespace code newline]]
+ }
+ }
+ proc doit1 {s} {
+ variable counter
+ variable accept
+
+ incr counter
+ set l [gets $s]
+ close $s
+ set accept {}
+ }
+ proc producer {} {
+ variable s
+ variable writer
+
+ set writer [socket 127.0.0.1 [lindex [fconfigure $s -sockname] 2]]
+ fconfigure $writer -buffering line
+ puts -nonewline $writer hello
+ flush $writer
+ }
+ proc newline {} {
+ variable done
+ variable writer
+
+ puts $writer hello
+ flush $writer
+ set done 1
+ }
+ producer
+ variable done
+ vwait [namespace which -variable done]
+ close $writer
+ close $s
+ after cancel $after
+ if {$accept != {}} {close $accept}
+ set counter
+} 1
+
+set path(fooBar) [makeFile {} fooBar]
+
+test io-55.1 {ChannelEventScriptInvoker: deletion} -constraints {
+ fileevent
+} -setup {
+ variable x
+ proc eventScript {fd} {
+ variable x
+ close $fd
+ error "planned error"
+ set x whoops
+ }
+ proc myHandler args {
+ variable x got_error
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+} -body {
+ set f [open $path(fooBar) w]
+ fileevent $f writable [namespace code [list eventScript $f]]
+ variable x not_done
+ vwait [namespace which -variable x]
+ set x
+} -cleanup {
+ interp bgerror {} $handler
+} -result {got_error}
+
+test io-56.1 {ChannelTimerProc} {testchannelevent} {
+ set f [open $path(fooBar) w]
+ puts $f "this is a test"
+ close $f
+ set f [open $path(fooBar) r]
+ testchannelevent $f add readable [namespace code {
+ read $f 1
+ incr x
+ }]
+ variable x 0
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ set result $x
+ testchannelevent $f set 0 none
+ after idle [namespace code {set y done}]
+ variable y
+ vwait [namespace which -variable y]
+ close $f
+ lappend result $y
+} {2 done}
+
+test io-57.1 {buffered data and file events, gets} {fileevent} {
+ proc accept {sock args} {
+ variable s2
+ set s2 $sock
+ }
+ set server [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set s [socket 127.0.0.1 [lindex [fconfigure $server -sockname] 2]]
+ variable s2
+ vwait [namespace which -variable s2]
+ update
+ fileevent $s2 readable [namespace code {lappend result readable}]
+ puts $s "12\n34567890"
+ flush $s
+ variable result [gets $s2]
+ after 1000 [namespace code {lappend result timer}]
+ vwait [namespace which -variable result]
+ lappend result [gets $s2]
+ vwait [namespace which -variable result]
+ close $s
+ close $s2
+ close $server
+ set result
+} {12 readable 34567890 timer}
+test io-57.2 {buffered data and file events, read} {fileevent} {
+ proc accept {sock args} {
+ variable s2
+ set s2 $sock
+ }
+ set server [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set s [socket 127.0.0.1 [lindex [fconfigure $server -sockname] 2]]
+ variable s2
+ vwait [namespace which -variable s2]
+ update
+ fileevent $s2 readable [namespace code {lappend result readable}]
+ puts -nonewline $s "1234567890"
+ flush $s
+ variable result [read $s2 1]
+ after 1000 [namespace code {lappend result timer}]
+ vwait [namespace which -variable result]
+ lappend result [read $s2 9]
+ vwait [namespace which -variable result]
+ close $s
+ close $s2
+ close $server
+ set result
+} {1 readable 234567890 timer}
+
+test io-58.1 {Tcl_NotifyChannel and error when closing} {stdio unixOrPc openpipe fileevent} {
+ set out [open $path(script) w]
+ puts $out {
+ puts "normal message from pipe"
+ puts stderr "error message from pipe"
+ exit 1
+ }
+ proc readit {pipe} {
+ variable x
+ variable result
+ if {[eof $pipe]} {
+ set x [catch {close $pipe} line]
+ lappend result catch $line
+ } else {
+ gets $pipe line
+ lappend result gets $line
+ }
+ }
+ close $out
+ set pipe [open "|[list [interpreter] $path(script)]" r]
+ fileevent $pipe readable [namespace code [list readit $pipe]]
+ variable x ""
+ set result ""
+ vwait [namespace which -variable x]
+ list $x $result
+} {1 {gets {normal message from pipe} gets {} catch {error message from pipe}}}
+
+test io-59.1 {Thread reference of channels} {testmainthread testchannel} {
+ # TIP #10
+ # More complicated tests (like that the reference changes as a
+ # channel is moved from thread to thread) can be done only in the
+ # extension which fully implements the moving of channels between
+ # threads, i.e. 'Threads'.
+
+ set f [open $path(longfile) r]
+ set result [testchannel mthread $f]
+ close $f
+ string equal $result [testmainthread]
+} {1}
+
+test io-60.1 {writing illegal utf sequences} {openpipe fileevent} {
+ # This test will hang in older revisions of the core.
+
+ set out [open $path(script) w]
+ puts $out {
+ puts [encoding convertfrom identity \xe2]
+ exit 1
+ }
+ proc readit {pipe} {
+ variable x
+ variable result
+ if {[eof $pipe]} {
+ set x [catch {close $pipe} line]
+ lappend result catch $line
+ } else {
+ gets $pipe line
+ lappend result gets $line
+ }
+ }
+ close $out
+ set pipe [open "|[list [interpreter] $path(script)]" r]
+ fileevent $pipe readable [namespace code [list readit $pipe]]
+ variable x ""
+ set result ""
+ vwait [namespace which -variable x]
+
+ # cut of the remainder of the error stack, especially the filename
+ set result [lreplace $result 3 3 [lindex [split [lindex $result 3] \n] 0]]
+ list $x $result
+} {1 {gets {} catch {error writing "stdout": invalid argument}}}
+
+test io-61.1 {Reset eof state after changing the eof char} -setup {
+ set datafile [makeFile {} eofchar]
+ set f [open $datafile w]
+ fconfigure $f -translation binary
+ puts -nonewline $f [string repeat "Ho hum\n" 11]
+ puts $f =
+ set line [string repeat "Ge gla " 4]
+ puts -nonewline $f [string repeat [string trimright $line]\n 834]
+ close $f
+} -body {
+ set f [open $datafile r]
+ fconfigure $f -eofchar =
+ set res {}
+ lappend res [read $f; tell $f]
+ fconfigure $f -eofchar {}
+ lappend res [read $f 1]
+ lappend res [read $f; tell $f]
+ # Any seek zaps the internals into a good state.
+ #seek $f 0 start
+ #seek $f 0 current
+ #lappend res [read $f; tell $f]
+ close $f
+ set res
+} -cleanup {
+ removeFile eofchar
+} -result {77 = 23431}
+
+
+# Test the cutting and splicing of channels, this is incidentially the
+# attach/detach facility of package Thread, but __without any
+# safeguards__. It can also be used to emulate transfer of channels
+# between threads, and is used for that here.
+
+test io-70.0 {Cutting & Splicing channels} {testchannel} {
+ set f [makeFile {... dummy ...} cutsplice]
+ set c [open $f r]
+
+ set res {}
+ lappend res [catch {seek $c 0 start}]
+ testchannel cut $c
+
+ lappend res [catch {seek $c 0 start}]
+ testchannel splice $c
+
+ lappend res [catch {seek $c 0 start}]
+ close $c
+
+ removeFile cutsplice
+
+ set res
+} {0 1 0}
+
+
+test io-70.1 {Transfer channel} {testchannel thread} {
+ set f [makeFile {... dummy ...} cutsplice]
+ set c [open $f r]
+
+ set res {}
+ lappend res [catch {seek $c 0 start}]
+ testchannel cut $c
+ lappend res [catch {seek $c 0 start}]
+
+ set tid [thread::create -preserved]
+ thread::send $tid [list set c $c]
+ thread::send $tid {load {} Tcltest}
+ lappend res [thread::send $tid {
+ testchannel splice $c
+ set res [catch {seek $c 0 start}]
+ close $c
+ set res
+ }]
+
+ thread::release $tid
+ removeFile cutsplice
+
+ set res
+} {0 1 0}
+
+# ### ### ### ######### ######### #########
+
+foreach {n msg expected} {
+ 0 {} {}
+ 1 {{message only}} {{message only}}
+ 2 {-options x} {-options x}
+ 3 {-options {x y} {the message}} {-options {x y} {the message}}
+
+ 4 {-code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 5 {-code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 6 {-code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 7 {-code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 8 {-code error -level 0 -f ba snarf} {-code error -level 0 -f ba snarf}
+ 9 {-code ok -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 10 {-code error -level 5 -f ba snarf} {-code error -level 0 -f ba snarf}
+ 11 {-code ok -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 12 {-code boss -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 13 {-code boss -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 14 {-code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 15 {-code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 16 {-code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 17 {-code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 18 {-code error -level 0 -f ba} {-code error -level 0 -f ba}
+ 19 {-code ok -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 20 {-code error -level 5 -f ba} {-code error -level 0 -f ba}
+ 21 {-code ok -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 22 {-code boss -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 23 {-code boss -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 24 {-code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 25 {-code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 26 {-code error -level X -f ba snarf} {-code error -level 0 -f ba snarf}
+ 27 {-code ok -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 28 {-code boss -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 29 {-code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+ 30 {-code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ 31 {-code error -level X -f ba} {-code error -level 0 -f ba}
+ 32 {-code ok -level X -f ba} {-code 1 -level 0 -f ba}
+ 33 {-code boss -level X -f ba} {-code 1 -level 0 -f ba}
+
+ 34 {-code 1 -code 1 -level 0 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 35 {-code 1 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 36 {-code 1 -code 1 -level 5 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 37 {-code 1 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 38 {-code 1 -code error -level 0 -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+ 39 {-code 1 -code ok -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 40 {-code 1 -code error -level 5 -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+ 41 {-code 1 -code ok -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 42 {-code 1 -code boss -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 43 {-code 1 -code boss -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 44 {-code 1 -code 1 -level 0 -f ba} {-code 1 -code 1 -level 0 -f ba}
+ 45 {-code 1 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 46 {-code 1 -code 1 -level 5 -f ba} {-code 1 -code 1 -level 0 -f ba}
+ 47 {-code 1 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 48 {-code 1 -code error -level 0 -f ba} {-code 1 -code error -level 0 -f ba}
+ 49 {-code 1 -code ok -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 50 {-code 1 -code error -level 5 -f ba} {-code 1 -code error -level 0 -f ba}
+ 51 {-code 1 -code ok -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 52 {-code 1 -code boss -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 53 {-code 1 -code boss -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 54 {-code 1 -code 1 -level X -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 55 {-code 1 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 56 {-code 1 -code error -level X -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+ 57 {-code 1 -code ok -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 58 {-code 1 -code boss -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 59 {-code 1 -code 1 -level X -f ba} {-code 1 -code 1 -level 0 -f ba}
+ 60 {-code 1 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ 61 {-code 1 -code error -level X -f ba} {-code 1 -code error -level 0 -f ba}
+ 62 {-code 1 -code ok -level X -f ba} {-code 1 -level 0 -f ba}
+ 63 {-code 1 -code boss -level X -f ba} {-code 1 -level 0 -f ba}
+
+ 64 {-code 0 -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 65 {-code 0 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 66 {-code 0 -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 67 {-code 0 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 68 {-code 0 -code error -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 69 {-code 0 -code ok -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 70 {-code 0 -code error -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 71 {-code 0 -code ok -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 72 {-code 0 -code boss -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 73 {-code 0 -code boss -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 74 {-code 0 -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 75 {-code 0 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 76 {-code 0 -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 77 {-code 0 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 78 {-code 0 -code error -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 79 {-code 0 -code ok -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 80 {-code 0 -code error -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 81 {-code 0 -code ok -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 82 {-code 0 -code boss -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 83 {-code 0 -code boss -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 84 {-code 0 -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 85 {-code 0 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 86 {-code 0 -code error -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 87 {-code 0 -code ok -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 88 {-code 0 -code boss -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 89 {-code 0 -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+ 90 {-code 0 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ 91 {-code 0 -code error -level X -f ba} {-code 1 -level 0 -f ba}
+ 92 {-code 0 -code ok -level X -f ba} {-code 1 -level 0 -f ba}
+ 93 {-code 0 -code boss -level X -f ba} {-code 1 -level 0 -f ba}
+
+ 94 {-code 1 -code 1 -level 0 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 95 {-code 0 -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 96 {-code 1 -code 1 -level 5 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 97 {-code 0 -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 98 {-code error -code 1 -level 0 -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+ 99 {-code ok -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ a0 {-code error -code 1 -level 5 -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+ a1 {-code ok -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ a2 {-code boss -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ a3 {-code boss -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ a4 {-code 1 -code 1 -level 0 -f ba} {-code 1 -code 1 -level 0 -f ba}
+ a5 {-code 0 -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ a6 {-code 1 -code 1 -level 5 -f ba} {-code 1 -code 1 -level 0 -f ba}
+ a7 {-code 0 -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ a8 {-code error -code 1 -level 0 -f ba} {-code error -code 1 -level 0 -f ba}
+ a9 {-code ok -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ b0 {-code error -code 1 -level 5 -f ba} {-code error -code 1 -level 0 -f ba}
+ b1 {-code ok -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ b2 {-code boss -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ b3 {-code boss -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ b4 {-code 1 -code 1 -level X -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ b5 {-code 0 -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ b6 {-code error -code 1 -level X -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+ b7 {-code ok -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ b8 {-code boss -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ b9 {-code 1 -code 1 -level X -f ba} {-code 1 -code 1 -level 0 -f ba}
+ c0 {-code 0 -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+ c1 {-code error -code 1 -level X -f ba} {-code error -code 1 -level 0 -f ba}
+ c2 {-code ok -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+ c3 {-code boss -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+
+ c4 {-code 1 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c5 {-code 0 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c6 {-code 1 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c7 {-code 0 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c8 {-code error -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c9 {-code ok -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d0 {-code error -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d1 {-code ok -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d2 {-code boss -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d3 {-code boss -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d4 {-code 1 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ d5 {-code 0 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ d6 {-code 1 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ d7 {-code 0 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ d8 {-code error -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ d9 {-code ok -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ e0 {-code error -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ e1 {-code ok -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ e2 {-code boss -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ e3 {-code boss -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ e4 {-code 1 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e5 {-code 0 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e6 {-code error -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e7 {-code ok -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e8 {-code boss -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e9 {-code 1 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ f0 {-code 0 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ f1 {-code error -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ f2 {-code ok -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ f3 {-code boss -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+} {
+ test io-71.$n {Tcl_SetChannelError} {testchannel} {
+
+ set f [makeFile {... dummy ...} cutsplice]
+ set c [open $f r]
+
+ set res [testchannel setchannelerror $c [lrange $msg 0 end]]
+ close $c
+ removeFile cutsplice
+
+ set res
+ } [lrange $expected 0 end]
+
+ test io-72.$n {Tcl_SetChannelErrorInterp} {testchannel} {
+
+ set f [makeFile {... dummy ...} cutsplice]
+ set c [open $f r]
+
+ set res [testchannel setchannelerrorinterp $c [lrange $msg 0 end]]
+ close $c
+ removeFile cutsplice
+
+ set res
+ } [lrange $expected 0 end]
+}
+
+test io-73.1 {channel Tcl_Obj SetChannelFromAny} {} {
+ # Test for Bug 1847044 - don't spoil type unless we have a valid channel
+ catch {close [lreplace [list a] 0 end]}
+} {1}
+
+test io-73.2 {channel Tcl_Obj SetChannelFromAny, bug 2407783} -setup {
+ # Invalidate intrep of 'channel' Tcl_Obj when transiting between interpreters.
+ set f [open [info script] r]
+} -body {
+ interp create foo
+ seek $f 0
+ set code [catch {interp eval foo [list seek $f 0]} msg]
+ # The string map converts the changing channel handle to a fixed string
+ list $code [string map [list $f @@] $msg]
+} -cleanup {
+ close $f
+} -result {1 {can not find channel named "@@"}}
+
+# ### ### ### ######### ######### #########
+
+# cleanup
+foreach file [list fooBar longfile script script2 output test1 pipe my_script \
+ test2 test3 cat stdout kyrillic.txt utf8-fcopy.txt utf8-rp.txt] {
+ removeFile $file
+}
+cleanupTests
+}
+namespace delete ::tcl::test::io
+return
diff --git a/library/msgcat/tests/ioCmd.test b/library/msgcat/tests/ioCmd.test
new file mode 100644
index 0000000..cf913ff
--- /dev/null
+++ b/library/msgcat/tests/ioCmd.test
@@ -0,0 +1,3741 @@
+# -*- tcl -*-
+# Commands covered: open, close, gets, read, puts, seek, tell, eof, flush,
+# fblocked, fconfigure, open, channel, fcopy
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Custom constraints used in this file
+testConstraint fcopy [llength [info commands fcopy]]
+testConstraint testchannel [llength [info commands testchannel]]
+testConstraint thread [expr {0 == [catch {package require Thread 2.6}]}]
+
+#----------------------------------------------------------------------
+
+test iocmd-1.1 {puts command} {
+ list [catch {puts} msg] $msg
+} {1 {wrong # args: should be "puts ?-nonewline? ?channelId? string"}}
+test iocmd-1.2 {puts command} {
+ list [catch {puts a b c d e f g} msg] $msg
+} {1 {wrong # args: should be "puts ?-nonewline? ?channelId? string"}}
+test iocmd-1.3 {puts command} {
+ list [catch {puts froboz -nonewline kablooie} msg] $msg
+} {1 {wrong # args: should be "puts ?-nonewline? ?channelId? string"}}
+test iocmd-1.4 {puts command} {
+ list [catch {puts froboz hello} msg] $msg
+} {1 {can not find channel named "froboz"}}
+test iocmd-1.5 {puts command} {
+ list [catch {puts stdin hello} msg] $msg
+} {1 {channel "stdin" wasn't opened for writing}}
+
+set path(test1) [makeFile {} test1]
+
+test iocmd-1.6 {puts command} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ puts -nonewline $f foobar
+ close $f
+ file size $path(test1)
+} 6
+test iocmd-1.7 {puts command} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f foobar
+ close $f
+ file size $path(test1)
+} 7
+test iocmd-1.8 {puts command} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {} -encoding iso8859-1
+ puts -nonewline $f [binary format a4a5 foo bar]
+ close $f
+ file size $path(test1)
+} 9
+
+test iocmd-2.1 {flush command} {
+ list [catch {flush} msg] $msg
+} {1 {wrong # args: should be "flush channelId"}}
+test iocmd-2.2 {flush command} {
+ list [catch {flush a b c d e} msg] $msg
+} {1 {wrong # args: should be "flush channelId"}}
+test iocmd-2.3 {flush command} {
+ list [catch {flush foo} msg] $msg
+} {1 {can not find channel named "foo"}}
+test iocmd-2.4 {flush command} {
+ list [catch {flush stdin} msg] $msg
+} {1 {channel "stdin" wasn't opened for writing}}
+
+test iocmd-3.1 {gets command} {
+ list [catch {gets} msg] $msg
+} {1 {wrong # args: should be "gets channelId ?varName?"}}
+test iocmd-3.2 {gets command} {
+ list [catch {gets a b c d e f g} msg] $msg
+} {1 {wrong # args: should be "gets channelId ?varName?"}}
+test iocmd-3.3 {gets command} {
+ list [catch {gets aaa} msg] $msg
+} {1 {can not find channel named "aaa"}}
+test iocmd-3.4 {gets command} {
+ list [catch {gets stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test iocmd-3.5 {gets command} {
+ set f [open $path(test1) w]
+ puts $f [binary format a4a5 foo bar]
+ close $f
+ set f [open $path(test1) r]
+ set result [gets $f]
+ close $f
+ set x foo\x00
+ set x "${x}bar\x00\x00"
+ string compare $x $result
+} 0
+
+test iocmd-4.1 {read command} {
+ list [catch {read} msg] $msg
+} {1 {wrong # args: should be "read channelId ?numChars?" or "read ?-nonewline? channelId"}}
+test iocmd-4.2 {read command} {
+ list [catch {read a b c d e f g h} msg] $msg
+} {1 {wrong # args: should be "read channelId ?numChars?" or "read ?-nonewline? channelId"}}
+test iocmd-4.3 {read command} {
+ list [catch {read aaa} msg] $msg
+} {1 {can not find channel named "aaa"}}
+test iocmd-4.4 {read command} {
+ list [catch {read -nonewline} msg] $msg
+} {1 {wrong # args: should be "read channelId ?numChars?" or "read ?-nonewline? channelId"}}
+test iocmd-4.5 {read command} {
+ list [catch {read -nonew file4} msg] $msg $::errorCode
+} {1 {can not find channel named "-nonew"} {TCL LOOKUP CHANNEL -nonew}}
+test iocmd-4.6 {read command} {
+ list [catch {read stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test iocmd-4.7 {read command} {
+ list [catch {read -nonewline stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test iocmd-4.8 {read command with incorrect combination of arguments} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f "Two lines: this one"
+ puts $f "and this one"
+ close $f
+ set f [open $path(test1)]
+ set x [list [catch {read -nonewline $f 20 z} msg] $msg $::errorCode]
+ close $f
+ set x
+} {1 {wrong # args: should be "read channelId ?numChars?" or "read ?-nonewline? channelId"} {TCL WRONGARGS}}
+test iocmd-4.9 {read command} {
+ list [catch {read stdin foo} msg] $msg $::errorCode
+} {1 {expected non-negative integer but got "foo"} {TCL VALUE NUMBER}}
+test iocmd-4.10 {read command} {
+ list [catch {read file107} msg] $msg $::errorCode
+} {1 {can not find channel named "file107"} {TCL LOOKUP CHANNEL file107}}
+set path(test3) [makeFile {} test3]
+test iocmd-4.11 {read command} {
+ set f [open $path(test3) w]
+ set x [list [catch {read $f} msg] $msg $::errorCode]
+ close $f
+ string compare [string tolower $x] \
+ [list 1 [format "channel \"%s\" wasn't opened for reading" $f] none]
+} 0
+test iocmd-4.12 {read command} -setup {
+ set f [open $path(test1)]
+} -body {
+ list [catch {read $f 12z} msg] $msg $::errorCode
+} -cleanup {
+ close $f
+} -result {1 {expected non-negative integer but got "12z"} {TCL VALUE NUMBER}}
+
+test iocmd-5.1 {seek command} -returnCodes error -body {
+ seek
+} -result {wrong # args: should be "seek channelId offset ?origin?"}
+test iocmd-5.2 {seek command} -returnCodes error -body {
+ seek a b c d e f g
+} -result {wrong # args: should be "seek channelId offset ?origin?"}
+test iocmd-5.3 {seek command} -returnCodes error -body {
+ seek stdin gugu
+} -result {expected integer but got "gugu"}
+test iocmd-5.4 {seek command} -returnCodes error -body {
+ seek stdin 100 gugu
+} -result {bad origin "gugu": must be start, current, or end}
+
+test iocmd-6.1 {tell command} {
+ list [catch {tell} msg] $msg
+} {1 {wrong # args: should be "tell channelId"}}
+test iocmd-6.2 {tell command} {
+ list [catch {tell a b c d e} msg] $msg
+} {1 {wrong # args: should be "tell channelId"}}
+test iocmd-6.3 {tell command} {
+ list [catch {tell aaa} msg] $msg
+} {1 {can not find channel named "aaa"}}
+
+test iocmd-7.1 {close command} {
+ list [catch {close} msg] $msg
+} {1 {wrong # args: should be "close channelId ?direction?"}}
+test iocmd-7.2 {close command} {
+ list [catch {close a b c d e} msg] $msg
+} {1 {wrong # args: should be "close channelId ?direction?"}}
+test iocmd-7.3 {close command} {
+ list [catch {close aaa} msg] $msg
+} {1 {can not find channel named "aaa"}}
+test iocmd-7.4 {close command} -setup {
+ set chan [open [info script] r]
+} -body {
+ chan close $chan bar
+} -cleanup {
+ close $chan
+} -returnCodes error -result "bad direction \"bar\": must be read or write"
+test iocmd-7.5 {close command} -setup {
+ set chan [open [info script] r]
+} -body {
+ chan close $chan write
+} -cleanup {
+ close $chan
+} -returnCodes error -result "Half-close of write-side not possible, side not opened or already closed"
+
+test iocmd-8.1 {fconfigure command} {
+ list [catch {fconfigure} msg] $msg
+} {1 {wrong # args: should be "fconfigure channelId ?-option value ...?"}}
+test iocmd-8.2 {fconfigure command} {
+ list [catch {fconfigure a b c d e f} msg] $msg
+} {1 {wrong # args: should be "fconfigure channelId ?-option value ...?"}}
+test iocmd-8.3 {fconfigure command} {
+ list [catch {fconfigure a b} msg] $msg
+} {1 {can not find channel named "a"}}
+test iocmd-8.4 {fconfigure command} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ set x [list [catch {fconfigure $f1 froboz} msg] $msg]
+ close $f1
+ set x
+} {1 {bad option "froboz": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, or -translation}}
+test iocmd-8.5 {fconfigure command} {
+ list [catch {fconfigure stdin -buffering froboz} msg] $msg
+} {1 {bad value for -buffering: must be one of full, line, or none}}
+test iocmd-8.6 {fconfigure command} {
+ list [catch {fconfigure stdin -translation froboz} msg] $msg
+} {1 {bad value for -translation: must be one of auto, binary, cr, lf, crlf, or platform}}
+test iocmd-8.7 {fconfigure command} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {} -encoding unicode
+ set x [fconfigure $f1]
+ close $f1
+ set x
+} {-blocking 1 -buffering full -buffersize 4096 -encoding unicode -eofchar {} -translation lf}
+test iocmd-8.8 {fconfigure command} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -buffering line -buffersize 3030 \
+ -eofchar {} -encoding unicode
+ set x ""
+ lappend x [fconfigure $f1 -buffering]
+ lappend x [fconfigure $f1]
+ close $f1
+ set x
+} {line {-blocking 1 -buffering line -buffersize 3030 -encoding unicode -eofchar {} -translation lf}}
+test iocmd-8.9 {fconfigure command} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation binary -buffering none -buffersize 4040 \
+ -eofchar {} -encoding binary
+ set x [fconfigure $f1]
+ close $f1
+ set x
+} {-blocking 1 -buffering none -buffersize 4040 -encoding binary -eofchar {} -translation lf}
+test iocmd-8.10 {fconfigure command} {
+ list [catch {fconfigure a b} msg] $msg
+} {1 {can not find channel named "a"}}
+set path(fconfigure.dummy) [makeFile {} fconfigure.dummy]
+test iocmd-8.11 {fconfigure command} {
+ set chan [open $path(fconfigure.dummy) r]
+ set res [list [catch {fconfigure $chan -froboz blarfo} msg] $msg]
+ close $chan
+ set res
+} {1 {bad option "-froboz": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, or -translation}}
+test iocmd-8.12 {fconfigure command} {
+ set chan [open $path(fconfigure.dummy) r]
+ set res [list [catch {fconfigure $chan -b blarfo} msg] $msg]
+ close $chan
+ set res
+} {1 {bad option "-b": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, or -translation}}
+test iocmd-8.13 {fconfigure command} {
+ set chan [open $path(fconfigure.dummy) r]
+ set res [list [catch {fconfigure $chan -buffer blarfo} msg] $msg]
+ close $chan
+ set res
+} {1 {bad option "-buffer": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, or -translation}}
+removeFile fconfigure.dummy
+test iocmd-8.14 {fconfigure command} {
+ fconfigure stdin -buffers
+} 4096
+test iocmd-8.15.1 {fconfigure command / tcp channel} -constraints {socket unixOrPc} -setup {
+ set srv [socket -server iocmdSRV -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $srv -sockname] 2]
+ proc iocmdSRV {sock ip port} {close $sock}
+ set cli [socket 127.0.0.1 $port]
+} -body {
+ fconfigure $cli -blah
+} -cleanup {
+ close $cli
+ close $srv
+ unset cli srv port
+ rename iocmdSRV {}
+} -returnCodes error -result {bad option "-blah": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -translation, -peername, or -sockname}
+test iocmd-8.16 {fconfigure command / tcp channel} -constraints socket -setup {
+ set srv [socket -server iocmdSRV -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $srv -sockname] 2]
+ proc iocmdSRV {sock ip port} {close $sock}
+ set cli [socket 127.0.0.1 $port]
+} -body {
+ expr {[lindex [fconfigure $cli -peername] 2] == $port}
+} -cleanup {
+ close $cli
+ close $srv
+ unset cli srv port
+ rename iocmdSRV {}
+} -result 1
+test iocmd-8.17 {fconfigure command / tcp channel} -constraints nonPortable -setup {
+ set srv [socket -server iocmdSRV -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $srv -sockname] 2]
+ proc iocmdSRV {sock ip port} {close $sock}
+ set cli [socket 127.0.0.1 $port]
+} -body {
+ # It is possible that you don't get the connection reset by peer
+ # error but rather a valid answer. Depends on the tcp implementation
+ update
+ puts $cli "blah"
+ flush $cli; # that flush could/should fail too
+ update
+ regsub -all {can([^:])+: } [catch {fconfigure $cli -peername} msg] {}
+} -cleanup {
+ close $cli
+ close $srv
+ unset cli srv port
+ rename iocmdSRV {}
+} -result 1
+test iocmd-8.18 {fconfigure command / unix tty channel} -constraints {nonPortable unix} -setup {
+ set tty ""
+} -body {
+ # might fail if /dev/ttya is unavailable
+ set tty [open /dev/ttya]
+ fconfigure $tty -blah blih
+} -cleanup {
+ if {$tty ne ""} {
+ close $tty
+ }
+} -returnCodes error -result {bad option "-blah": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -translation, or -mode}
+test iocmd-8.19 {fconfigure command / win tty channel} -constraints {nonPortable win} -setup {
+ set tty ""
+} -body {
+ # might fail early if com1 is unavailable
+ set tty [open com1]
+ fconfigure $tty -blah blih
+} -cleanup {
+ if {$tty ne ""} {
+ close $tty
+ }
+} -returnCodes error -result {bad option "-blah": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -translation, -mode, -handshake, -pollinterval, -sysbuffer, -timeout, -ttycontrol, or -xchar}
+# TODO: Test parsing of serial channel options (nonportable, since requires an
+# open channel to work with).
+
+test iocmd-9.1 {eof command} {
+ list [catch {eof} msg] $msg $::errorCode
+} {1 {wrong # args: should be "eof channelId"} {TCL WRONGARGS}}
+test iocmd-9.2 {eof command} {
+ list [catch {eof a b} msg] $msg $::errorCode
+} {1 {wrong # args: should be "eof channelId"} {TCL WRONGARGS}}
+test iocmd-9.3 {eof command} {
+ catch {close file100}
+ list [catch {eof file100} msg] $msg $::errorCode
+} {1 {can not find channel named "file100"} {TCL LOOKUP CHANNEL file100}}
+
+# The tests for Tcl_ExecObjCmd are in exec.test
+
+test iocmd-10.1 {fblocked command} {
+ list [catch {fblocked} msg] $msg
+} {1 {wrong # args: should be "fblocked channelId"}}
+test iocmd-10.2 {fblocked command} {
+ list [catch {fblocked a b c d e f g} msg] $msg
+} {1 {wrong # args: should be "fblocked channelId"}}
+test iocmd-10.3 {fblocked command} {
+ list [catch {fblocked file1000} msg] $msg
+} {1 {can not find channel named "file1000"}}
+test iocmd-10.4 {fblocked command} {
+ list [catch {fblocked stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test iocmd-10.5 {fblocked command} {
+ fblocked stdin
+} 0
+
+set path(test4) [makeFile {} test4]
+set path(test5) [makeFile {} test5]
+
+file delete $path(test5)
+test iocmd-11.1 {I/O to command pipelines} {unixOrPc unixExecs} {
+ set f [open $path(test4) w]
+ close $f
+ list [catch {open "| cat < \"$path(test4)\" > \"$path(test5)\"" w} msg] $msg $::errorCode
+} {1 {can't write input to command: standard input was redirected} {TCL OPERATION EXEC BADREDIRECT}}
+test iocmd-11.2 {I/O to command pipelines} {unixOrPc unixExecs} {
+ list [catch {open "| echo > \"$path(test5)\"" r} msg] $msg $::errorCode
+} {1 {can't read output from command: standard output was redirected} {TCL OPERATION EXEC BADREDIRECT}}
+test iocmd-11.3 {I/O to command pipelines} {unixOrPc unixExecs} {
+ list [catch {open "| echo > \"$path(test5)\"" r+} msg] $msg $::errorCode
+} {1 {can't read output from command: standard output was redirected} {TCL OPERATION EXEC BADREDIRECT}}
+test iocmd-11.4 {I/O to command pipelines} unixOrPc {
+ list [catch {open "| no_such_command_exists" rb} msg] $msg $::errorCode
+} {1 {couldn't execute "no_such_command_exists": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+
+test iocmd-12.1 {POSIX open access modes: RDONLY} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f "Two lines: this one"
+ puts $f "and this one"
+ close $f
+ set f [open $path(test1) RDONLY]
+ set x [list [gets $f] [catch {puts $f Test} msg] $msg]
+ close $f
+ string compare $x \
+ "{Two lines: this one} 1 [list [format "channel \"%s\" wasn't opened for writing" $f]]"
+} 0
+test iocmd-12.2 {POSIX open access modes: RDONLY} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) RDONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test iocmd-12.3 {POSIX open access modes: WRONLY} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) WRONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+#
+# Test 13.4 relies on assigning the same channel name twice.
+#
+test iocmd-12.4 {POSIX open access modes: WRONLY} {unix} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ fconfigure $f -eofchar {}
+ puts $f xyzzy
+ close $f
+ set f [open $path(test3) WRONLY]
+ fconfigure $f -eofchar {}
+ puts -nonewline $f "ab"
+ seek $f 0 current
+ set x [list [catch {gets $f} msg] $msg]
+ close $f
+ set f [open $path(test3) r]
+ fconfigure $f -eofchar {}
+ lappend x [gets $f]
+ close $f
+ set y [list 1 [format "channel \"%s\" wasn't opened for reading" $f] abzzy]
+ string compare $x $y
+} 0
+test iocmd-12.5 {POSIX open access modes: RDWR} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) RDWR
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test iocmd-12.6 {POSIX open access modes: errors} {
+ concat [catch {open $path(test3) "FOO \{BAR BAZ"} msg] $msg\n$::errorInfo
+} "1 unmatched open brace in list
+unmatched open brace in list
+ while processing open access modes \"FOO {BAR BAZ\"
+ invoked from within
+\"open \$path(test3) \"FOO \\{BAR BAZ\"\""
+test iocmd-12.7 {POSIX open access modes: errors} {
+ list [catch {open $path(test3) {FOO BAR BAZ}} msg] $msg
+} {1 {invalid access mode "FOO": must be RDONLY, WRONLY, RDWR, APPEND, BINARY, CREAT, EXCL, NOCTTY, NONBLOCK, or TRUNC}}
+test iocmd-12.8 {POSIX open access modes: errors} {
+ list [catch {open $path(test3) {TRUNC CREAT}} msg] $msg
+} {1 {access mode must include either RDONLY, WRONLY, or RDWR}}
+close [open $path(test3) w]
+test iocmd-12.9 {POSIX open access modes: BINARY} {
+ list [catch {open $path(test1) BINARY} msg] $msg
+} {1 {access mode must include either RDONLY, WRONLY, or RDWR}}
+test iocmd-12.10 {POSIX open access modes: BINARY} {
+ set f [open $path(test1) {WRONLY BINARY TRUNC}]
+ puts $f a
+ puts $f b
+ puts -nonewline $f c ;# contents are now 5 bytes: a\nb\nc
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation binary
+ set result [string length [read $f]]
+ close $f
+ set result
+} 5
+test iocmd-12.11 {POSIX open access modes: BINARY} {
+ set f [open $path(test1) {WRONLY BINARY TRUNC}]
+ puts $f \u0248 ;# gets truncated to \u0048
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation binary
+ set result [read -nonewline $f]
+ close $f
+ set result
+} \u0048
+
+test iocmd-13.1 {errors in open command} {
+ list [catch {open} msg] $msg
+} {1 {wrong # args: should be "open fileName ?access? ?permissions?"}}
+test iocmd-13.2 {errors in open command} {
+ list [catch {open a b c d} msg] $msg
+} {1 {wrong # args: should be "open fileName ?access? ?permissions?"}}
+test iocmd-13.3 {errors in open command} {
+ list [catch {open $path(test1) x} msg] $msg
+} {1 {illegal access mode "x"}}
+test iocmd-13.4 {errors in open command} {
+ list [catch {open $path(test1) rw} msg] $msg
+} {1 {illegal access mode "rw"}}
+test iocmd-13.5 {errors in open command} {
+ list [catch {open $path(test1) r+1} msg] $msg
+} {1 {illegal access mode "r+1"}}
+test iocmd-13.6 {errors in open command} {
+ set msg [list [catch {open _non_existent_} msg] $msg $::errorCode]
+ regsub [file join {} _non_existent_] $msg "_non_existent_" msg
+ string tolower $msg
+} {1 {couldn't open "_non_existent_": no such file or directory} {posix enoent {no such file or directory}}}
+test iocmd-13.7 {errors in open command} {
+ list [catch {open $path(test1) b} msg] $msg
+} {1 {illegal access mode "b"}}
+test iocmd-13.8 {errors in open command} {
+ list [catch {open $path(test1) rbb} msg] $msg
+} {1 {illegal access mode "rbb"}}
+test iocmd-13.9 {errors in open command} {
+ list [catch {open $path(test1) r++} msg] $msg
+} {1 {illegal access mode "r++"}}
+test iocmd-13.10.1 {open for append, a mode} -setup {
+ set log [makeFile {} out]
+ set chans {}
+} -body {
+ foreach i { 0 1 2 3 4 5 6 7 8 9 } {
+ puts [set ch [open $log a]] $i
+ lappend chans $ch
+ }
+ foreach ch $chans {catch {close $ch}}
+ lsort [split [string trim [viewFile out]] \n]
+} -cleanup {
+ removeFile out
+ # Ensure that channels are gone, even if body failed to do so
+ foreach ch $chans {catch {close $ch}}
+} -result {0 1 2 3 4 5 6 7 8 9}
+test iocmd-13.10.2 {open for append, O_APPEND} -setup {
+ set log [makeFile {} out]
+ set chans {}
+} -body {
+ foreach i { 0 1 2 3 4 5 6 7 8 9 } {
+ puts [set ch [open $log {WRONLY CREAT APPEND}]] $i
+ lappend chans $ch
+ }
+ foreach ch $chans {catch {close $ch}}
+ lsort [split [string trim [viewFile out]] \n]
+} -cleanup {
+ removeFile out
+ # Ensure that channels are gone, even if body failed to do so
+ foreach ch $chans {catch {close $ch}}
+} -result {0 1 2 3 4 5 6 7 8 9}
+test ioCmd-13.11 {open ... a+ must not use O_APPEND: Bug 1773127} -setup {
+ set f [makeFile {} ioutil41.tmp]
+ set fid [open $f wb]
+ puts -nonewline $fid 123
+ close $fid
+} -body {
+ set fid [open $f ab+]
+ puts -nonewline $fid 456
+ seek $fid 2
+ set d [read $fid 2]
+ seek $fid 4
+ puts -nonewline $fid x
+ close $fid
+ set fid [open $f rb]
+ append d [read $fid]
+ close $fid
+ return $d
+} -cleanup {
+ removeFile $f
+} -result 341234x6
+
+
+test iocmd-14.1 {file id parsing errors} {
+ list [catch {eof gorp} msg] $msg $::errorCode
+} {1 {can not find channel named "gorp"} {TCL LOOKUP CHANNEL gorp}}
+test iocmd-14.2 {file id parsing errors} {
+ list [catch {eof filex} msg] $msg
+} {1 {can not find channel named "filex"}}
+test iocmd-14.3 {file id parsing errors} {
+ list [catch {eof file12a} msg] $msg
+} {1 {can not find channel named "file12a"}}
+test iocmd-14.4 {file id parsing errors} {
+ list [catch {eof file123} msg] $msg
+} {1 {can not find channel named "file123"}}
+test iocmd-14.5 {file id parsing errors} {
+ list [catch {eof stdout} msg] $msg
+} {0 0}
+test iocmd-14.6 {file id parsing errors} {
+ list [catch {eof stdin} msg] $msg
+} {0 0}
+test iocmd-14.7 {file id parsing errors} {
+ list [catch {eof stdout} msg] $msg
+} {0 0}
+test iocmd-14.8 {file id parsing errors} {
+ list [catch {eof stderr} msg] $msg
+} {0 0}
+test iocmd-14.9 {file id parsing errors} {
+ list [catch {eof stderr1} msg] $msg
+} {1 {can not find channel named "stderr1"}}
+
+set f [open $path(test1) w]
+close $f
+
+set expect "1 {can not find channel named \"$f\"}"
+test iocmd-14.10 {file id parsing errors} {
+ list [catch {eof $f} msg] $msg
+} $expect
+
+test iocmd-15.1 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy} msg] $msg
+} {1 {wrong # args: should be "fcopy input output ?-size size? ?-command callback?"}}
+test iocmd-15.2 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy 1} msg] $msg
+} {1 {wrong # args: should be "fcopy input output ?-size size? ?-command callback?"}}
+test iocmd-15.3 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy 1 2 3 4 5 6 7} msg] $msg
+} {1 {wrong # args: should be "fcopy input output ?-size size? ?-command callback?"}}
+test iocmd-15.4 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy 1 2 3} msg] $msg
+} {1 {wrong # args: should be "fcopy input output ?-size size? ?-command callback?"}}
+test iocmd-15.5 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy 1 2 3 4 5} msg] $msg
+} {1 {wrong # args: should be "fcopy input output ?-size size? ?-command callback?"}}
+
+set path(test2) [makeFile {} test2]
+set f [open $path(test1) w]
+close $f
+set rfile [open $path(test1) r]
+set wfile [open $path(test2) w]
+
+test iocmd-15.6 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy foo $wfile} msg] $msg
+} {1 {can not find channel named "foo"}}
+test iocmd-15.7 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy $rfile foo} msg] $msg
+} {1 {can not find channel named "foo"}}
+test iocmd-15.8 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy $wfile $wfile} msg] $msg
+} "1 {channel \"$wfile\" wasn't opened for reading}"
+test iocmd-15.9 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy $rfile $rfile} msg] $msg
+} "1 {channel \"$rfile\" wasn't opened for writing}"
+test iocmd-15.10 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy $rfile $wfile foo bar} msg] $msg
+} {1 {bad switch "foo": must be -size or -command}}
+test iocmd-15.11 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy $rfile $wfile -size foo} msg] $msg
+} {1 {expected integer but got "foo"}}
+test iocmd-15.12 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy $rfile $wfile -command bar -size foo} msg] $msg
+} {1 {expected integer but got "foo"}}
+
+close $rfile
+close $wfile
+
+# ### ### ### ######### ######### #########
+## Testing the reflected channel.
+
+test iocmd-20.0 {chan, wrong#args} {
+ catch {chan} msg
+ set msg
+} {wrong # args: should be "chan subcommand ?arg ...?"}
+test iocmd-20.1 {chan, unknown method} -body {
+ chan foo
+} -returnCodes error -match glob -result {unknown or ambiguous subcommand "foo": must be *}
+
+# --- --- --- --------- --------- ---------
+# chan create, and method "initalize"
+
+test iocmd-21.0 {chan create, wrong#args, not enough} {
+ catch {chan create} msg
+ set msg
+} {wrong # args: should be "chan create mode cmdprefix"}
+test iocmd-21.1 {chan create, wrong#args, too many} {
+ catch {chan create a b c} msg
+ set msg
+} {wrong # args: should be "chan create mode cmdprefix"}
+test iocmd-21.2 {chan create, invalid r/w mode, empty} {
+ proc foo {} {}
+ catch {chan create {} foo} msg
+ rename foo {}
+ set msg
+} {bad mode list: is empty}
+test iocmd-21.3 {chan create, invalid r/w mode, bad string} {
+ proc foo {} {}
+ catch {chan create {c} foo} msg
+ rename foo {}
+ set msg
+} {bad mode "c": must be read or write}
+test iocmd-21.4 {chan create, bad handler, not a list} {
+ catch {chan create {r w} "foo \{"} msg
+ set msg
+} {unmatched open brace in list}
+test iocmd-21.5 {chan create, bad handler, not a command} {
+ catch {chan create {r w} foo} msg
+ set msg
+} {invalid command name "foo"}
+test iocmd-21.6 {chan create, initialize failed, bad signature} {
+ proc foo {} {}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} {wrong # args: should be "foo"}
+test iocmd-21.7 {chan create, initialize failed, bad signature} {
+ proc foo {} {}
+ catch {chan create {r w} ::foo} msg
+ rename foo {}
+ set msg
+} {wrong # args: should be "::foo"}
+test iocmd-21.8 {chan create, initialize failed, bad result, not a list} -body {
+ proc foo {args} {return "\{"}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set ::errorInfo
+} -match glob -result {chan handler "foo initialize" returned non-list: *}
+test iocmd-21.9 {chan create, initialize failed, bad result, not a list} -body {
+ proc foo {args} {return \{\{\}}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {chan handler "foo initialize" returned non-list: *}
+test iocmd-21.10 {chan create, initialize failed, bad result, empty list} -body {
+ proc foo {args} {}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {*all required methods*}
+test iocmd-21.11 {chan create, initialize failed, bad result, bogus method name} -body {
+ proc foo {args} {return 1}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {*bad method "1": must be *}
+test iocmd-21.12 {chan create, initialize failed, bad result, bogus method name} -body {
+ proc foo {args} {return {a b c}}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {*bad method "c": must be *}
+test iocmd-21.13 {chan create, initialize failed, bad result, required methods missing} -body {
+ proc foo {args} {return {initialize finalize}}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {*all required methods*}
+test iocmd-21.14 {chan create, initialize failed, bad result, mode/handler mismatch} -body {
+ proc foo {args} {return {initialize finalize watch read}}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {*lacks a "write" method}
+test iocmd-21.15 {chan create, initialize failed, bad result, mode/handler mismatch} -body {
+ proc foo {args} {return {initialize finalize watch write}}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {*lacks a "read" method}
+test iocmd-21.16 {chan create, initialize failed, bad result, cget(all) mismatch} -body {
+ proc foo {args} {return {initialize finalize watch cget write read}}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {*supports "cget" but not "cgetall"}
+test iocmd-21.17 {chan create, initialize failed, bad result, cget(all) mismatch} -body {
+ proc foo {args} {return {initialize finalize watch cgetall read write}}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {*supports "cgetall" but not "cget"}
+test iocmd-21.18 {chan create, initialize ok, creates channel} -match glob -body {
+ proc foo {args} {
+ global res
+ lappend res $args
+ if {[lindex $args 0] ne "initialize"} {return}
+ return {initialize finalize watch read write}
+ }
+ set res {}
+ lappend res [file channel rc*]
+ lappend res [chan create {r w} foo]
+ lappend res [close [lindex $res end]]
+ lappend res [file channel rc*]
+ rename foo {}
+ set res
+} -result {{} {initialize rc* {read write}} rc* {finalize rc*} {} {}}
+test iocmd-21.19 {chan create, init failure -> no channel, no finalize} -match glob -body {
+ proc foo {args} {
+ global res
+ lappend res $args
+ return {}
+ }
+ set res {}
+ lappend res [file channel rc*]
+ lappend res [catch {chan create {r w} foo} msg]
+ lappend res $msg
+ lappend res [file channel rc*]
+ rename foo {}
+ set res
+} -result {{} {initialize rc* {read write}} 1 {*all required methods*} {}}
+
+# --- --- --- --------- --------- ---------
+# Helper commands to record the arguments to handler methods.
+
+# Stored in a script so that the threads and interpreters needing this
+# code do not need their own copy but can access this variable.
+
+set helperscript {
+
+proc note {item} {global res; lappend res $item; return}
+proc track {} {upvar args item; note $item; return}
+proc notes {items} {foreach i $items {note $i}}
+# This forces the return options to be in the order that the test expects!
+proc noteOpts opts {global res; lappend res [dict merge {
+ -code !?! -level !?! -errorcode !?! -errorline !?! -errorinfo !?!
+} $opts]; return}
+
+# Helper command, canned result for 'initialize' method.
+# Gets the optional methods as arguments. Use return features
+# to post the result higher up.
+
+proc init {args} {
+ lappend args initialize finalize watch read write
+ return -code return $args
+}
+proc oninit {args} {
+ upvar args hargs
+ if {[lindex $hargs 0] ne "initialize"} {return}
+ lappend args initialize finalize watch read write
+ return -code return $args
+}
+proc onfinal {} {
+ upvar args hargs
+ if {[lindex $hargs 0] ne "finalize"} {return}
+ return -code return ""
+}
+}
+
+# Set everything up in the main thread.
+eval $helperscript
+
+# --- --- --- --------- --------- ---------
+# method finalize
+
+test iocmd-22.1 {chan finalize, handler destruction has no effect on channel} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return}
+ note [set c [chan create {r w} foo]]
+ rename foo {}
+ note [file channels rc*]
+ note [catch {close $c} msg]; note $msg
+ note [file channels rc*]
+ set res
+} -result {{initialize rc* {read write}} rc* rc* 1 {invalid command name "foo"} {}}
+test iocmd-22.2 {chan finalize, for close} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return {}}
+ note [set c [chan create {r w} foo]]
+ close $c
+ # Close deleted the channel.
+ note [file channels rc*]
+ # Channel destruction does not kill handler command!
+ note [info command foo]
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} {} foo}
+test iocmd-22.3 {chan finalize, for close, error, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -code error 5}
+ note [set c [chan create {r w} foo]]
+ note [catch {close $c} msg]; note $msg
+ # Channel is gone despite error.
+ note [file channels rc*]
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 5 {}}
+test iocmd-22.4 {chan finalize, for close, error, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; error FOO}
+ note [set c [chan create {r w} foo]]
+ note [catch {close $c} msg]; note $msg; note $::errorInfo
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 FOO {FOO
+*"close $c"}}
+test iocmd-22.5 {chan finalize, for close, arbitrary result, ignored} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return SOMETHING}
+ note [set c [chan create {r w} foo]]
+ note [catch {close $c} msg]; note $msg
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 0 {}}
+test iocmd-22.6 {chan finalize, for close, break, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -code 3}
+ note [set c [chan create {r w} foo]]
+ note [catch {close $c} msg]; note $msg
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*}
+test iocmd-22.7 {chan finalize, for close, continue, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -code 4}
+ note [set c [chan create {r w} foo]]
+ note [catch {close $c} msg]; note $msg
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*}
+test iocmd-22.8 {chan finalize, for close, custom code, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -code 777 BANG}
+ note [set c [chan create {r w} foo]]
+ note [catch {close $c} msg]; note $msg
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*}
+test iocmd-22.9 {chan finalize, for close, ignore level, close error} -match glob -setup {
+ set res {}
+} -body {
+ proc foo {args} {track; oninit; return -level 5 -code 777 BANG}
+ note [set c [chan create {r w} foo]]
+ note [catch {close $c} msg opt]; note $msg; noteOpts $opt
+ return $res
+} -cleanup {
+ rename foo {}
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "finalize"*}}
+
+# --- === *** ###########################
+# method read
+
+test iocmd-23.1 {chan read, regular data return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return snarf
+ }
+ set c [chan create {r w} foo]
+ note [read $c 10]
+ close $c
+ rename foo {}
+ set res
+} -result {{read rc* 4096} {read rc* 4096} snarfsnarf}
+test iocmd-23.2 {chan read, bad data return, to much} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return [string repeat snarf 1000]
+ }
+ set c [chan create {r w} foo]
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 {read delivered more than requested}}
+test iocmd-23.3 {chan read, for non-readable channel} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track; note MUST_NOT_HAPPEN
+ }
+ set c [chan create {w} foo]
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {1 {channel "rc*" wasn't opened for reading}}
+test iocmd-23.4 {chan read, error return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 BOOM!}
+test iocmd-23.5 {chan read, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -code break BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 *bad code*}
+test iocmd-23.6 {chan read, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -code continue BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 *bad code*}
+test iocmd-23.7 {chan read, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -code 777 BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 *bad code*}
+test iocmd-23.8 {chan read, level is squashed} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -level 55 -code 777 BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {read $c 2} msg opt]; note $msg; noteOpts $opt
+ close $c
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}}
+test iocmd-23.9 {chan read, no data means eof} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return ""
+ }
+ set c [chan create {r w} foo]
+} -body {
+ note [read $c 2]
+ note [eof $c]
+ set res
+} -cleanup {
+ close $c
+ rename foo {}
+ unset res
+} -result {{read rc* 4096} {} 1}
+test iocmd-23.10 {chan read, EAGAIN means no data, yet no eof either} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ error EAGAIN
+ }
+ set c [chan create {r w} foo]
+} -body {
+ note [read $c 2]
+ note [eof $c]
+ set res
+} -cleanup {
+ close $c
+ rename foo {}
+ unset res
+} -result {{read rc* 4096} {} 0}
+
+# --- === *** ###########################
+# method write
+
+test iocmd-24.1 {chan write, regular write} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ set written [string length [lindex $args 2]]
+ note $written
+ return $written
+ }
+ set c [chan create {r w} foo]
+ puts -nonewline $c snarf; flush $c
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarf} 5}
+test iocmd-24.2 {chan write, partial write is ok} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ set written [string length [lindex $args 2]]
+ if {$written > 10} {set written [expr {$written / 2}]}
+ note $written
+ return $written
+ }
+ set c [chan create {r w} foo]
+ puts -nonewline $c snarfsnarfsnarf; flush $c
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 7 {write rc* arfsnarf} 8}
+test iocmd-24.3 {chan write, failed write} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note -1; return -1}
+ set c [chan create {r w} foo]
+ puts -nonewline $c snarfsnarfsnarf; flush $c
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} -1}
+test iocmd-24.4 {chan write, non-writable channel} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r} foo]
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {1 {channel "rc*" wasn't opened for writing}}
+test iocmd-24.5 {chan write, bad result, more written than data} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return 10000}
+ set c [chan create {r w} foo]
+ note [catch {puts -nonewline $c snarf; flush $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarf} 1 {write wrote more than requested}}
+test iocmd-24.6 {chan write, bad result, zero-length write} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return 0}
+ set c [chan create {r w} foo]
+ note [catch {puts -nonewline $c snarf; flush $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarf} 1 {write wrote nothing}}
+test iocmd-24.7 {chan write, failed write, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code error BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 BOOM!}
+test iocmd-24.8 {chan write, failed write, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; error BOOM!}
+ set c [chan create {r w} foo]
+ notes [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 BOOM!}
+test iocmd-24.9 {chan write, failed write, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code break BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*}
+test iocmd-24.10 {chan write, failed write, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code continue BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*}
+test iocmd-24.11 {chan write, failed write, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code 777 BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*}
+test iocmd-24.12 {chan write, failed write, non-numeric return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return BANG}
+ set c [chan create {r w} foo]
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 {expected integer but got "BANG"}}
+test iocmd-24.13 {chan write, failed write, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -level 55 -code 777 BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg opt]
+ note $msg
+ noteOpts $opt
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "write"*}}
+test iocmd-24.14 {chan write, no EAGAIN means that writing is allowed at this time, bug 2936225} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return 3
+ }
+ set c [chan create {r w} foo]
+} -body {
+ note [puts -nonewline $c ABC ; flush $c]
+ set res
+} -cleanup {
+ close $c
+ rename foo {}
+ unset res
+} -result {{write rc* ABC} {}}
+test iocmd-24.15 {chan write, EAGAIN means that writing is not allowed at this time, bug 2936225} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ # Note: The EAGAIN signals that the channel cannot accept
+ # write requests right now, this in turn causes the IO core to
+ # request the generation of writable events (see expected
+ # result below, and compare to case 24.14 above).
+ error EAGAIN
+ }
+ set c [chan create {r w} foo]
+} -body {
+ note [puts -nonewline $c ABC ; flush $c]
+ set res
+} -cleanup {
+ close $c
+ rename foo {}
+ unset res
+} -result {{write rc* ABC} {watch rc* write} {}}
+
+# --- === *** ###########################
+# method cgetall
+
+test iocmd-25.1 {chan configure, cgetall, standard options} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ note [fconfigure $c]
+ close $c
+ rename foo {}
+ set res
+} -result {{-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *}}}
+test iocmd-25.2 {chan configure, cgetall, no options} -match glob -body {
+ set res {}
+ proc foo {args} {oninit cget cgetall; onfinal; track; return ""}
+ set c [chan create {r w} foo]
+ note [fconfigure $c]
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *}}}
+test iocmd-25.3 {chan configure, cgetall, regular result} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return "-bar foo -snarf x"
+ }
+ set c [chan create {r w} foo]
+ note [fconfigure $c]
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *} -bar foo -snarf x}}
+test iocmd-25.4 {chan configure, cgetall, bad result, list of uneven length} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return "-bar"
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 {Expected list with even number of elements, got 1 element instead}}
+test iocmd-25.5 {chan configure, cgetall, bad result, not a list} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return "\{"
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 {unmatched open brace in list}}
+test iocmd-25.6 {chan configure, cgetall, error return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 BOOM!}
+test iocmd-25.7 {chan configure, cgetall, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code break BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 *bad code*}
+test iocmd-25.8 {chan configure, cgetall, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code continue BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 *bad code*}
+test iocmd-25.9 {chan configure, cgetall, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code 777 BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 *bad code*}
+test iocmd-25.10 {chan configure, cgetall, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -level 55 -code 777 BANG
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c} msg opt]; note $msg; noteOpts $opt
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cgetall"*}}
+
+# --- === *** ###########################
+# method configure
+
+test iocmd-26.1 {chan configure, set standard option} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track; note MUST_NOT_HAPPEN; return
+ }
+ set c [chan create {r w} foo]
+ note [fconfigure $c -translation lf]
+ close $c
+ rename foo {}
+ set res
+} -result {{}}
+test iocmd-26.2 {chan configure, set option, error return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo bar} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 BOOM!}
+test iocmd-26.3 {chan configure, set option, ok return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit configure; onfinal; track; return}
+ set c [chan create {r w} foo]
+ note [fconfigure $c -rc-foo bar]
+ close $c
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} {}}
+test iocmd-26.4 {chan configure, set option, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -code break BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo bar} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*}
+test iocmd-26.5 {chan configure, set option, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -code continue BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo bar} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*}
+test iocmd-26.6 {chan configure, set option, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -code 444 BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo bar} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*}
+test iocmd-26.7 {chan configure, set option, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -level 55 -code 444 BANG
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo bar} msg opt]; note $msg; noteOpts $opt
+ close $c
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "configure"*}}
+
+# --- === *** ###########################
+# method cget
+
+test iocmd-27.1 {chan configure, get option, ok return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit cget cgetall; onfinal; track; return foo}
+ set c [chan create {r w} foo]
+ note [fconfigure $c -rc-foo]
+ close $c
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} foo}
+test iocmd-27.2 {chan configure, get option, error return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 BOOM!}
+test iocmd-27.3 {chan configure, get option, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 BOOM!}
+test iocmd-27.4 {chan configure, get option, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code continue BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 *bad code*}
+test iocmd-27.5 {chan configure, get option, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code 333 BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 *bad code*}
+test iocmd-27.6 {chan configure, get option, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -level 77 -code 333 BANG
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo} msg opt]; note $msg; noteOpts $opt
+ close $c
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cget"*}}
+
+# --- === *** ###########################
+# method seek
+
+test iocmd-28.1 {chan tell, not supported by handler} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ note [tell $c]
+ close $c
+ rename foo {}
+ set res
+} -result {-1}
+test iocmd-28.2 {chan tell, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code error BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {tell $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 BOOM!}
+test iocmd-28.3 {chan tell, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code break BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {tell $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 *bad code*}
+test iocmd-28.4 {chan tell, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code continue BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {tell $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 *bad code*}
+test iocmd-28.5 {chan tell, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code 222 BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {tell $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 *bad code*}
+test iocmd-28.6 {chan tell, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -level 11 -code 222 BANG}
+ set c [chan create {r w} foo]
+ note [catch {tell $c} msg opt]; note $msg; noteOpts $opt
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}}
+test iocmd-28.7 {chan tell, regular return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return 88}
+ set c [chan create {r w} foo]
+ note [tell $c]
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 88}
+test iocmd-28.8 {chan tell, negative return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -1}
+ set c [chan create {r w} foo]
+ note [catch {tell $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 {Tried to seek before origin}}
+test iocmd-28.9 {chan tell, string return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return BOGUS}
+ set c [chan create {r w} foo]
+ note [catch {tell $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 {expected integer but got "BOGUS"}}
+test iocmd-28.10 {chan seek, not supported by handler} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ note [catch {seek $c 0 start} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {1 {error during seek on "rc*": invalid argument}}
+test iocmd-28.11 {chan seek, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code error BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {seek $c 0 start} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 BOOM!}
+test iocmd-28.12 {chan seek, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code break BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {seek $c 0 start} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 *bad code*}
+test iocmd-28.13 {chan seek, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code continue BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {seek $c 0 start} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 *bad code*}
+test iocmd-28.14 {chan seek, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code 99 BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {seek $c 0 start} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 *bad code*}
+test iocmd-28.15 {chan seek, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -level 33 -code 99 BANG}
+ set c [chan create {r w} foo]
+ note [catch {seek $c 0 start} msg opt]; note $msg; noteOpts $opt
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}}
+test iocmd-28.16 {chan seek, bogus return, negative location} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -45}
+ set c [chan create {r w} foo]
+ note [catch {seek $c 0 start} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 {Tried to seek before origin}}
+test iocmd-28.17 {chan seek, bogus return, string return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return BOGUS}
+ set c [chan create {r w} foo]
+ note [catch {seek $c 0 start} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 {expected integer but got "BOGUS"}}
+test iocmd-28.18 {chan seek, ok result} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return 23}
+ set c [chan create {r w} foo]
+ note [seek $c 0 current]
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} {}}
+foreach {testname code} {
+ iocmd-28.19.0 start
+ iocmd-28.19.1 current
+ iocmd-28.19.2 end
+} {
+ test $testname "chan seek, base conversion, $code" -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return 0}
+ set c [chan create {r w} foo]
+ note [seek $c 0 $code]
+ close $c
+ rename foo {}
+ set res
+ } -result [list [list seek rc* 0 $code] {}]
+}
+
+# --- === *** ###########################
+# method blocking
+
+test iocmd-29.1 {chan blocking, no handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ note [fconfigure $c -blocking]
+ close $c
+ rename foo {}
+ set res
+} -result {1}
+test iocmd-29.2 {chan blocking, no handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ note [fconfigure $c -blocking 0]
+ note [fconfigure $c -blocking]
+ close $c
+ rename foo {}
+ set res
+} -result {{} 0}
+test iocmd-29.3 {chan blocking, retrieval, handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ note [fconfigure $c -blocking]
+ close $c
+ rename foo {}
+ set res
+} -result {1}
+test iocmd-29.4 {chan blocking, resetting, handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return}
+ set c [chan create {r w} foo]
+ note [fconfigure $c -blocking 0]
+ note [fconfigure $c -blocking]
+ close $c
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} {} 0}
+test iocmd-29.5 {chan blocking, setting, handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return}
+ set c [chan create {r w} foo]
+ note [fconfigure $c -blocking 1]
+ note [fconfigure $c -blocking]
+ close $c
+ rename foo {}
+ set res
+} -result {{blocking rc* 1} {} 1}
+test iocmd-29.6 {chan blocking, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; error BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -blocking 0} msg]; note $msg
+ # Catch the close. It changes blocking mode internally, and runs into the error result.
+ catch {close $c}
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 BOOM!}
+test iocmd-29.7 {chan blocking, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return -code break BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -blocking 0} msg]; note $msg
+ catch {close $c}
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 *bad code*}
+test iocmd-29.8 {chan blocking, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return -code continue BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -blocking 0} msg]; note $msg
+ catch {close $c}
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 *bad code*}
+test iocmd-29.9 {chan blocking, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return -code 44 BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -blocking 0} msg]; note $msg
+ catch {close $c}
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 *bad code*}
+test iocmd-29.10 {chan blocking, level is ignored} -match glob -setup {
+ set res {}
+} -body {
+ proc foo {args} {oninit blocking; onfinal; track; return -level 99 -code 44 BANG}
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -blocking 0} msg opt]; note $msg; noteOpts $opt
+ catch {close $c}
+ return $res
+} -cleanup {
+ rename foo {}
+} -result {{blocking rc* 0} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "blocking"*}}
+test iocmd-29.11 {chan blocking, regular return ok, value ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return BOGUS}
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -blocking 0} msg]; note $msg
+ catch {close $c}
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 0 {}}
+
+# --- === *** ###########################
+# method watch
+
+test iocmd-30.1 {chan watch, read interest, some return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return IGNORED}
+ set c [chan create {r w} foo]
+ note [fileevent $c readable {set tick $tick}]
+ close $c ;# 2nd watch, interest zero.
+ rename foo {}
+ set res
+} -result {{watch rc* read} {} {watch rc* {}}}
+test iocmd-30.2 {chan watch, write interest, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code error BOOM!_IGNORED}
+ set c [chan create {r w} foo]
+ note [fileevent $c writable {set tick $tick}]
+ note [fileevent $c writable {}]
+ close $c
+ rename foo {}
+ set res
+} -result {{watch rc* write} {} {watch rc* {}} {}}
+test iocmd-30.3 {chan watch, accumulated interests} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ note [fileevent $c writable {set tick $tick}]
+ note [fileevent $c readable {set tick $tick}]
+ note [fileevent $c writable {}]
+ note [fileevent $c readable {}]
+ close $c
+ rename foo {}
+ set res
+} -result {{watch rc* write} {} {watch rc* {read write}} {} {watch rc* read} {} {watch rc* {}} {}}
+test iocmd-30.4 {chan watch, unchanged interest not forwarded} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ note [fileevent $c writable {set tick $tick}]
+ note [fileevent $c readable {set tick $tick}] ;# Script is changing,
+ note [fileevent $c readable {set tock $tock}] ;# interest does not.
+ close $c ;# 3rd and 4th watch, removing the event handlers.
+ rename foo {}
+ set res
+} -result {{watch rc* write} {} {watch rc* {read write}} {} {} {watch rc* write} {watch rc* {}}}
+
+# --- === *** ###########################
+# chan postevent
+
+test iocmd-31.1 {chan postevent, restricted to reflected channels} -match glob -body {
+ set c [open [makeFile {} goo] r]
+ catch {chan postevent $c {r w}} msg
+ close $c
+ removeFile goo
+ set msg
+} -result {can not find reflected channel named "file*"}
+test iocmd-31.2 {chan postevent, unwanted events} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ catch {chan postevent $c {r w}} msg; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{tried to post events channel "rc*" is not interested in}}
+test iocmd-31.3 {chan postevent, bad input, empty list} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ catch {chan postevent $c {}} msg; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{bad event list: is empty}}
+test iocmd-31.4 {chan postevent, bad input, illlegal keyword} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ catch {chan postevent $c goo} msg; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{bad event "goo": must be read or write}}
+test iocmd-31.5 {chan postevent, bad input, not a list} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ catch {chan postevent $c "\{"} msg; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{unmatched open brace in list}}
+test iocmd-31.6 {chan postevent, posted events do happen} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ note [fileevent $c readable {note TOCK}]
+ set stop [after 10000 {note TIMEOUT}]
+ after 1000 {note [chan postevent $c r]}
+ vwait ::res
+ catch {after cancel $stop}
+ close $c
+ rename foo {}
+ set res
+} -result {{watch rc* read} {} TOCK {} {watch rc* {}}}
+test iocmd-31.7 {chan postevent, posted events do happen} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ note [fileevent $c writable {note TOCK}]
+ set stop [after 10000 {note TIMEOUT}]
+ after 1000 {note [chan postevent $c w]}
+ vwait ::res
+ catch {after cancel $stop}
+ close $c
+ rename foo {}
+ set res
+} -result {{watch rc* write} {} TOCK {} {watch rc* {}}}
+test iocmd-31.8 {chan postevent after close throws error} -match glob -setup {
+ proc foo {args} {oninit; onfinal; track; return}
+ proc dummy args { return }
+ set c [chan create {r w} foo]
+ fileevent $c readable dummy
+} -body {
+ close $c
+ chan postevent $c read
+} -cleanup {
+ rename foo {}
+ rename dummy {}
+} -returnCodes error -result {can not find reflected channel named "rc*"}
+
+# --- === *** ###########################
+# 'Pull the rug' tests. Create channel in a interpreter A, move to
+# other interpreter B, destroy the origin interpreter (A) before or
+# during access from B. Must not crash, must return proper errors.
+
+test iocmd-32.0 {origin interpreter of moved channel gone} -match glob -body {
+
+ set ida [interp create];#puts <<$ida>>
+ set idb [interp create];#puts <<$idb>>
+
+ # Magic to get the test* commands in the slaves
+ load {} Tcltest $ida
+ load {} Tcltest $idb
+
+ # Set up channel in interpreter
+ interp eval $ida $helperscript
+ set chan [interp eval $ida {
+ proc foo {args} {oninit seek; onfinal; track; return}
+ set chan [chan create {r w} foo]
+ fconfigure $chan -buffering none
+ set chan
+ }]
+
+ # Move channel to 2nd interpreter.
+ interp eval $ida [list testchannel cut $chan]
+ interp eval $idb [list testchannel splice $chan]
+
+ # Kill origin interpreter, then access channel from 2nd interpreter.
+ interp delete $ida
+
+ set res {}
+ lappend res [catch {interp eval $idb [list puts $chan shoo]} msg] $msg
+ lappend res [catch {interp eval $idb [list tell $chan]} msg] $msg
+ lappend res [catch {interp eval $idb [list seek $chan 1]} msg] $msg
+ lappend res [catch {interp eval $idb [list gets $chan]} msg] $msg
+ lappend res [catch {interp eval $idb [list close $chan]} msg] $msg
+ set res
+
+} -constraints {testchannel} \
+ -result {1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}}
+
+test iocmd-32.1 {origin interpreter of moved channel destroyed during access} -match glob -body {
+
+ set ida [interp create];#puts <<$ida>>
+ set idb [interp create];#puts <<$idb>>
+
+ # Magic to get the test* commands in the slaves
+ load {} Tcltest $ida
+ load {} Tcltest $idb
+
+ # Set up channel in thread
+ set chan [interp eval $ida $helperscript]
+ set chan [interp eval $ida {
+ proc foo {args} {
+ oninit; onfinal; track;
+ # destroy interpreter during channel access
+ # Actually not possible for an interp to destroy itself.
+ interp delete {}
+ return}
+ set chan [chan create {r w} foo]
+ fconfigure $chan -buffering none
+ set chan
+ }]
+
+ # Move channel to 2nd thread.
+ interp eval $ida [list testchannel cut $chan]
+ interp eval $idb [list testchannel splice $chan]
+
+ # Run access from interpreter B, this will give us a synchronous
+ # response.
+
+ interp eval $idb [list set chan $chan]
+ set res [interp eval $idb {
+ # wait a bit, give the main thread the time to start its event
+ # loop to wait for the response from B
+ after 2000
+ catch { puts $chan shoo } res
+ set res
+ }]
+ set res
+} -constraints {testchannel impossible} \
+ -result {Owner lost}
+
+test iocmd-32.2 {delete interp of reflected chan} {
+ # Bug 3034840
+ # Run this test in an interp with memory debugging to panic
+ # on the double free
+ interp create slave
+ slave eval {
+ proc no-op args {}
+ proc driver {sub args} {return {initialize finalize watch read}}
+ chan event [chan create read driver] readable no-op
+ }
+ interp delete slave
+} {}
+
+# ### ### ### ######### ######### #########
+## Same tests as above, but exercising the code forwarding and
+## receiving driver operations to the originator thread.
+
+# -*- tcl -*-
+# ### ### ### ######### ######### #########
+## Testing the reflected channel (Thread forwarding).
+#
+## The id numbers refer to the original test without thread
+## forwarding, and gaps due to tests not applicable to forwarding are
+## left to keep this asociation.
+
+# ### ### ### ######### ######### #########
+## Helper command. Runs a script in a separate thread and returns the
+## result. A channel is transfered into the thread as well, and list of
+## configuation variables
+
+proc inthread {chan script args} {
+ # Test thread.
+
+ set tid [thread::create -preserved]
+ thread::send $tid {load {} Tcltest}
+
+ # Init thread configuration.
+ # - Listed variables
+ # - Id of main thread
+ # - A number of helper commands
+
+ foreach v $args {
+ upvar 1 $v x
+ thread::send $tid [list set $v $x]
+
+ }
+ thread::send $tid [list set mid [thread::id]]
+ thread::send $tid {
+ proc note {item} {global notes; lappend notes $item}
+ proc notes {} {global notes; return $notes}
+ proc noteOpts opts {global notes; lappend notes [dict merge {
+ -code !?! -level !?! -errorcode !?! -errorline !?! -errorinfo !?!
+ } $opts]}
+ }
+ thread::send $tid [list proc s {} [list uplevel 1 $script]]; # (*)
+
+ # Transfer channel (cut/splice aka detach/attach)
+
+ testchannel cut $chan
+ thread::send $tid [list testchannel splice $chan]
+
+ # Run test script, also run local event loop!
+ # The local event loop waits for the result to come back.
+ # It is also necessary for the execution of forwarded channel
+ # operations.
+
+ set ::tres ""
+ thread::send -async $tid {
+ after 500
+ catch {s} res; # This runs the script, 's' was defined at (*)
+ thread::send -async $mid [list set ::tres $res]
+ }
+ vwait ::tres
+ # Remove test thread, and return the captured result.
+
+ thread::release $tid
+ return $::tres
+}
+
+# ### ### ### ######### ######### #########
+
+# ### ### ### ######### ######### #########
+
+test iocmd.tf-22.2 {chan finalize, for close} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return {}}
+ note [set c [chan create {r w} foo]]
+ note [inthread $c {
+ close $c
+ # Close the deleted the channel.
+ file channels rc*
+ } c]
+ # Channel destruction does not kill handler command!
+ note [info command foo]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{initialize rc* {read write}} rc* {finalize rc*} {} foo}
+test iocmd.tf-22.3 {chan finalize, for close, error, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -code error 5}
+ note [set c [chan create {r w} foo]]
+ notes [inthread $c {
+ note [catch {close $c} msg]; note $msg
+ # Channel is gone despite error.
+ note [file channels rc*]
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 5 {}}
+test iocmd.tf-22.4 {chan finalize, for close, error, close errror} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; error FOO}
+ note [set c [chan create {r w} foo]]
+ notes [inthread $c {
+ note [catch {close $c} msg]; note $msg
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 FOO}
+test iocmd.tf-22.5 {chan finalize, for close, arbitrary result} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return SOMETHING}
+ note [set c [chan create {r w} foo]]
+ notes [inthread $c {
+ note [catch {close $c} msg]; note $msg
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{initialize rc* {read write}} rc* {finalize rc*} 0 {}}
+test iocmd.tf-22.6 {chan finalize, for close, break, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -code 3}
+ note [set c [chan create {r w} foo]]
+ notes [inthread $c {
+ note [catch {close $c} msg]; note $msg
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-22.7 {chan finalize, for close, continue, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -code 4}
+ note [set c [chan create {r w} foo]]
+ notes [inthread $c {
+ note [catch {close $c} msg]; note $msg
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-22.8 {chan finalize, for close, custom code, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -code 777 BANG}
+ note [set c [chan create {r w} foo]]
+ notes [inthread $c {
+ note [catch {close $c} msg]; note $msg
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-22.9 {chan finalize, for close, ignore level, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -level 5 -code 777 BANG}
+ note [set c [chan create {r w} foo]]
+ notes [inthread $c {
+ note [catch {close $c} msg opt]; note $msg; noteOpts $opt
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "finalize"*}} \
+ -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method read
+
+test iocmd.tf-23.1 {chan read, regular data return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return snarf
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [read $c 10]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{read rc* 4096} {read rc* 4096} snarfsnarf}
+test iocmd.tf-23.2 {chan read, bad data return, to much} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return [string repeat snarf 1000]
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {[read $c 2]} msg]; note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{read rc* 4096} 1 {read delivered more than requested}}
+test iocmd.tf-23.3 {chan read, for non-readable channel} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track; note MUST_NOT_HAPPEN
+ }
+ set c [chan create {w} foo]
+ notes [inthread $c {
+ note [catch {[read $c 2]} msg]; note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {1 {channel "rc*" wasn't opened for reading}}
+test iocmd.tf-23.4 {chan read, error return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 BOOM!} \
+ -constraints {testchannel thread}
+test iocmd.tf-23.5 {chan read, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -code break BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-23.6 {chan read, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -code continue BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-23.7 {chan read, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -code 777 BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-23.8 {chan read, level is squashed} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -level 55 -code 777 BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {read $c 2} msg opt]; note $msg; noteOpts $opt
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}} \
+ -constraints {testchannel thread}
+test iocmd.tf-23.9 {chan read, no data means eof} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return ""
+ }
+ set c [chan create {r w} foo]
+} -body {
+ notes [inthread $c {
+ note [read $c 2]
+ note [eof $c]
+ close $c
+ notes
+ } c]
+ set res
+} -cleanup {
+ rename foo {}
+ unset res
+} -result {{read rc* 4096} {} 1} \
+ -constraints {testchannel thread}
+test iocmd.tf-23.10 {chan read, EAGAIN means no data, yet no eof either} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ error EAGAIN
+ }
+ set c [chan create {r w} foo]
+} -body {
+ notes [inthread $c {
+ note [read $c 2]
+ note [eof $c]
+ close $c
+ notes
+ } c]
+ set res
+} -cleanup {
+ rename foo {}
+ unset res
+} -result {{read rc* 4096} {} 0} \
+ -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method write
+
+test iocmd.tf-24.1 {chan write, regular write} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ set written [string length [lindex $args 2]]
+ note $written
+ return $written
+ }
+ set c [chan create {r w} foo]
+ inthread $c {
+ puts -nonewline $c snarf; flush $c
+ close $c
+ } c
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{write rc* snarf} 5}
+test iocmd.tf-24.2 {chan write, ack partial writes} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ set written [string length [lindex $args 2]]
+ if {$written > 10} {set written [expr {$written / 2}]}
+ note $written
+ return $written
+ }
+ set c [chan create {r w} foo]
+ inthread $c {
+ puts -nonewline $c snarfsnarfsnarf; flush $c
+ close $c
+ } c
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{write rc* snarfsnarfsnarf} 7 {write rc* arfsnarf} 8}
+test iocmd.tf-24.3 {chan write, failed write} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note -1; return -1}
+ set c [chan create {r w} foo]
+ inthread $c {
+ puts -nonewline $c snarfsnarfsnarf; flush $c
+ close $c
+ } c
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{write rc* snarfsnarfsnarf} -1}
+test iocmd.tf-24.4 {chan write, non-writable channel} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {1 {channel "rc*" wasn't opened for writing}}
+test iocmd.tf-24.5 {chan write, bad result, more written than data} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return 10000}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{write rc* snarf} 1 {write wrote more than requested}}
+test iocmd.tf-24.6 {chan write, zero writes} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return 0}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{write rc* snarf} 1 {write wrote more than requested}}
+test iocmd.tf-24.7 {chan write, failed write, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code error BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 BOOM!} \
+ -constraints {testchannel thread}
+test iocmd.tf-24.8 {chan write, failed write, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; error BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 BOOM!} \
+ -constraints {testchannel thread}
+test iocmd.tf-24.9 {chan write, failed write, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code break BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-24.10 {chan write, failed write, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code continue BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-24.11 {chan write, failed write, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code 777 BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-24.12 {chan write, failed write, non-numeric return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return BANG}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 {expected integer but got "BANG"}} \
+ -constraints {testchannel thread}
+test iocmd.tf-24.13 {chan write, failed write, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -level 55 -code 777 BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg opt]
+ note $msg
+ noteOpts $opt
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "write"*}} \
+ -constraints {testchannel thread}
+test iocmd.tf-24.14 {chan write, no EAGAIN means that writing is allowed at this time, bug 2936225} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return 3
+ }
+ set c [chan create {r w} foo]
+} -body {
+ notes [inthread $c {
+ note [puts -nonewline $c ABC ; flush $c]
+ close $c
+ notes
+ } c]
+ set res
+} -cleanup {
+ rename foo {}
+ unset res
+} -result {{write rc* ABC} {}} \
+ -constraints {testchannel thread}
+test iocmd.tf-24.15 {chan write, EAGAIN means that writing is not allowed at this time, bug 2936225} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ # Note: The EAGAIN signals that the channel cannot accept
+ # write requests right now, this in turn causes the IO core to
+ # request the generation of writable events (see expected
+ # result below, and compare to case 24.14 above).
+ error EAGAIN
+ }
+ set c [chan create {r w} foo]
+} -body {
+ notes [inthread $c {
+ note [puts -nonewline $c ABC ; flush $c]
+ close $c
+ notes
+ } c]
+ set res
+} -cleanup {
+ proc foo {args} {onfinal; set ::done-24.15 1; return 3}
+ after 1000 {set ::done-24.15 2}
+ vwait done-24.15
+ rename foo {}
+ unset res
+} -result {{write rc* ABC} {watch rc* write} {}} \
+ -constraints {testchannel thread}
+
+test iocmd.tf-24.16 {chan write, note the background flush setup by close due to the EAGAIN leaving data in buffers.} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ # Note: The EAGAIN signals that the channel cannot accept
+ # write requests right now, this in turn causes the IO core to
+ # request the generation of writable events (see expected
+ # result below, and compare to case 24.14 above).
+ error EAGAIN
+ }
+ set c [chan create {r w} foo]
+} -body {
+ notes [inthread $c {
+ note [puts -nonewline $c ABC ; flush $c]
+ close $c
+ notes
+ } c]
+ # Replace handler with all-tracking one which doesn't error.
+ # This will tell us if a write-due-flush is there.
+ proc foo {args} { onfinal; note BG ; track ; set ::endbody-24.16 1}
+ # Flush (sic!) the event-queue to capture the write from a
+ # BG-flush.
+ after 1000 {set ::endbody-24.16 2}
+ vwait endbody-24.16
+ set res
+} -cleanup {
+ proc foo {args} {onfinal; set ::done-24.16 1; return 3}
+ after 1000 {set ::done-24.16 2}
+ vwait done-24.16
+ rename foo {}
+ unset res
+} -result {{write rc* ABC} {watch rc* write} {} BG {write rc* ABC}} \
+ -constraints {testchannel thread}
+
+test iocmd.tf-24.17.bug3522560 {postevent for transfered channel} \
+ -constraints {testchannel thread} -setup {
+ # This test exposes how the execution of postevent in the handler thread causes
+ # a crash if we are not properly injecting the events into the owning thread instead.
+ # With the injection the test will simply complete without crash.
+
+ set beat 10000
+ set drive 999
+ set data ...---...
+
+ proc LOG {text} {
+ #puts stderr "[thread::id]: $text"
+ return
+ }
+
+ proc POST {hi} {
+ LOG "-> [info level 0]"
+ chan postevent $hi read
+ LOG "<- [info level 0]"
+
+ set ::timer [after $::drive [info level 0]]
+ return
+ }
+
+ proc HANDLER {op ch args} {
+ lappend ::res [lrange [info level 0] 1 end]
+ LOG "-> [info level 0]"
+ set ret {}
+ switch -glob -- $op {
+ init* {set ret {initialize finalize watch read}}
+ watch {
+ set l [lindex $args 0]
+ if {[llength $l]} {
+ set ::timer [after $::drive [list POST $ch]]
+ } else {
+ after cancel $::timer
+ }
+ }
+ finalize {
+ catch { after cancel $::timer }
+ after 500 {set ::forever now}
+ }
+ read {
+ set ret $::data
+ set ::data {} ; # Next is EOF.
+ }
+ }
+ LOG "<- [info level 0] : $ret"
+ return $ret
+ }
+} -body {
+ LOG BEGIN
+ set ch [chan create {read} HANDLER]
+
+ set tid [thread::create {
+ proc LOG {text} {
+ #puts stderr "\t\t\t\t\t\t[thread::id]: $text"
+ return
+ }
+ LOG THREAD-STARTED
+ load {} Tcltest
+ proc bgerror s {
+ LOG BGERROR:$s
+ }
+ vwait forever
+ LOG THREAD-DONE
+ }]
+
+ testchannel cut $ch
+ thread::send $tid [list set thech $ch]
+ thread::send $tid [list set beat $beat]
+ thread::send -async $tid {
+ LOG SPLICE-BEG
+ testchannel splice $thech
+ LOG SPLICE-END
+ proc PROCESS {ch} {
+ LOG "-> [info level 0]"
+ if {[eof $ch]} {
+ close $ch
+ set ::done 1
+ set c <<EOF>>
+ } else {
+ set c [read $ch 1]
+ }
+ LOG "GOTCHAR: $c"
+ LOG "<- [info level 0]"
+ }
+ LOG THREAD-FILEEVENT
+ fconfigure $thech -translation binary -blocking 0
+ fileevent $thech readable [list PROCESS $thech]
+ LOG THREAD-NOEVENT-LOOP
+ set done 0
+ while {!$done} {
+ after $beat
+ LOG THREAD-HEARTBEAT
+ update
+ }
+ LOG THREAD-LOOP-DONE
+ thread::exit
+ }
+
+ LOG MAIN_WAITING
+ vwait forever
+ LOG MAIN_DONE
+
+ set res
+} -cleanup {
+ rename LOG {}
+ rename POST {}
+ rename HANDLER {}
+ unset beat drive data forever res tid ch
+} -match glob \
+ -result {{initialize rc* read} {watch rc* read} {read rc* 4096} {watch rc* {}} {watch rc* read} {read rc* 4096} {watch rc* {}} {finalize rc*}}
+
+# --- === *** ###########################
+# method cgetall
+
+test iocmd.tf-25.1 {chan configure, cgetall, standard options} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} \
+ -result {{-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *}}}
+test iocmd.tf-25.2 {chan configure, cgetall, no options} -match glob -body {
+ set res {}
+ proc foo {args} {oninit cget cgetall; onfinal; track; return ""}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} \
+ -result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *}}}
+test iocmd.tf-25.3 {chan configure, cgetall, regular result} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return "-bar foo -snarf x"
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} \
+ -result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *} -bar foo -snarf x}}
+test iocmd.tf-25.4 {chan configure, cgetall, bad result, list of uneven length} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return "-bar"
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{cgetall rc*} 1 {Expected list with even number of elements, got 1 element instead}}
+test iocmd.tf-25.5 {chan configure, cgetall, bad result, not a list} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return "\{"
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{cgetall rc*} 1 {unmatched open brace in list}}
+test iocmd.tf-25.6 {chan configure, cgetall, error return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{cgetall rc*} 1 BOOM!}
+test iocmd.tf-25.7 {chan configure, cgetall, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code break BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-25.8 {chan configure, cgetall, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code continue BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-25.9 {chan configure, cgetall, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code 777 BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-25.10 {chan configure, cgetall, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -level 55 -code 777 BANG
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c} msg opt]
+ note $msg
+ noteOpts $opt
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cgetall"*}} \
+ -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method configure
+
+test iocmd.tf-26.1 {chan configure, set standard option} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track; note MUST_NOT_HAPPEN; return
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c -translation lf]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{}}
+test iocmd.tf-26.2 {chan configure, set option, error return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo bar} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{configure rc* -rc-foo bar} 1 BOOM!}
+test iocmd.tf-26.3 {chan configure, set option, ok return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit configure; onfinal; track; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c -rc-foo bar]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{configure rc* -rc-foo bar} {}}
+test iocmd.tf-26.4 {chan configure, set option, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -code break BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo bar} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-26.5 {chan configure, set option, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -code continue BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo bar} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-26.6 {chan configure, set option, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -code 444 BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo bar} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-26.7 {chan configure, set option, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -level 55 -code 444 BANG
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo bar} msg opt]
+ note $msg
+ noteOpts $opt
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "configure"*}} \
+ -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method cget
+
+test iocmd.tf-27.1 {chan configure, get option, ok return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit cget cgetall; onfinal; track; return foo}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c -rc-foo]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{cget rc* -rc-foo} foo}
+test iocmd.tf-27.2 {chan configure, get option, error return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{cget rc* -rc-foo} 1 BOOM!}
+test iocmd.tf-27.3 {chan configure, get option, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 BOOM!} \
+ -constraints {testchannel thread}
+test iocmd.tf-27.4 {chan configure, get option, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code continue BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-27.5 {chan configure, get option, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code 333 BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-27.6 {chan configure, get option, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -level 77 -code 333 BANG
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo} msg opt]
+ note $msg
+ noteOpts $opt
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cget"*}} \
+ -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method seek
+
+test iocmd.tf-28.1 {chan tell, not supported by handler} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [tell $c]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {-1} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.2 {chan tell, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code error BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {tell $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 BOOM!} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.3 {chan tell, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code break BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {tell $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.4 {chan tell, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code continue BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {tell $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.5 {chan tell, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code 222 BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {tell $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.6 {chan tell, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -level 11 -code 222 BANG}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {tell $c} msg opt]
+ note $msg
+ noteOpts $opt
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.7 {chan tell, regular return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return 88}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [tell $c]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 88} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.8 {chan tell, negative return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -1}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {tell $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 {Tried to seek before origin}} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.9 {chan tell, string return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return BOGUS}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {tell $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 {expected integer but got "BOGUS"}} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.10 {chan seek, not supported by handler} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {seek $c 0 start} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {1 {error during seek on "rc*": invalid argument}} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.11 {chan seek, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code error BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {seek $c 0 start} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 BOOM!} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.12 {chan seek, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code break BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {seek $c 0 start} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.13 {chan seek, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code continue BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {seek $c 0 start} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.14 {chan seek, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code 99 BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {seek $c 0 start} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.15 {chan seek, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -level 33 -code 99 BANG}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {seek $c 0 start} msg opt]
+ note $msg
+ noteOpts $opt
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.16 {chan seek, bogus return, negative location} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -45}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {seek $c 0 start} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 {Tried to seek before origin}} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.17 {chan seek, bogus return, string return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return BOGUS}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {seek $c 0 start} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 {expected integer but got "BOGUS"}} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.18 {chan seek, ok result} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return 23}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [seek $c 0 current]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} {}} \
+ -constraints {testchannel thread}
+foreach {testname code} {
+ iocmd.tf-28.19.0 start
+ iocmd.tf-28.19.1 current
+ iocmd.tf-28.19.2 end
+} {
+ test $testname "chan seek, base conversion, $code" -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return 0}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [seek $c 0 $code]
+ close $c
+ notes
+ } c code]
+ rename foo {}
+ set res
+ } -result [list [list seek rc* 0 $code] {}] \
+ -constraints {testchannel thread}
+}
+
+# --- === *** ###########################
+# method blocking
+
+test iocmd.tf-29.1 {chan blocking, no handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c -blocking]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {1} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.2 {chan blocking, no handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c -blocking 0]
+ note [fconfigure $c -blocking]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{} 0} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.3 {chan blocking, retrieval, handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c -blocking]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {1} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.4 {chan blocking, resetting, handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c -blocking 0]
+ note [fconfigure $c -blocking]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} {} 0} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.5 {chan blocking, setting, handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c -blocking 1]
+ note [fconfigure $c -blocking]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{blocking rc* 1} {} 1} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.6 {chan blocking, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; error BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -blocking 0} msg]
+ note $msg
+ # Catch the close. It changes blocking mode internally, and runs into the error result.
+ catch {close $c}
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 BOOM!} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.7 {chan blocking, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return -code break BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -blocking 0} msg]
+ note $msg
+ catch {close $c}
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.8 {chan blocking, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return -code continue BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -blocking 0} msg]
+ note $msg
+ catch {close $c}
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.9 {chan blocking, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return -code 44 BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -blocking 0} msg]
+ note $msg
+ catch {close $c}
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.10 {chan blocking, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return -level 99 -code 44 BANG}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -blocking 0} msg opt]
+ note $msg
+ noteOpts $opt
+ catch {close $c}
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "blocking"*}} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.11 {chan blocking, regular return ok, value ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return BOGUS}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -blocking 0} msg]
+ note $msg
+ catch {close $c}
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 0 {}} \
+ -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method watch
+
+test iocmd.tf-30.1 {chan watch, read interest, some return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return IGNORED}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fileevent $c readable {set tick $tick}]
+ close $c ;# 2nd watch, interest zero.
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{watch rc* read} {watch rc* {}} {}}
+test iocmd.tf-30.2 {chan watch, write interest, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code error BOOM!_IGNORED}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fileevent $c writable {set tick $tick}]
+ note [fileevent $c writable {}]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{watch rc* write} {watch rc* {}} {} {}}
+test iocmd.tf-30.3 {chan watch, accumulated interests} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fileevent $c writable {set tick $tick}]
+ note [fileevent $c readable {set tick $tick}]
+ note [fileevent $c writable {}]
+ note [fileevent $c readable {}]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} \
+ -result {{watch rc* write} {watch rc* {read write}} {watch rc* read} {watch rc* {}} {} {} {} {}}
+test iocmd.tf-30.4 {chan watch, unchanged interest not forwarded} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fileevent $c writable {set tick $tick}]
+ note [fileevent $c readable {set tick $tick}] ;# Script is changing,
+ note [fileevent $c readable {set tock $tock}] ;# interest does not.
+ close $c ;# 3rd and 4th watch, removing the event handlers.
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} \
+ -result {{watch rc* write} {watch rc* {read write}} {watch rc* write} {watch rc* {}} {} {} {}}
+
+# --- === *** ###########################
+# postevent
+# Not possible from a thread not containing the command handler.
+# Check that this is rejected.
+
+test iocmd.tf-31.8 {chan postevent, bad input} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ catch {chan postevent $c r} msg
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} \
+ -result {{can not find reflected channel named "rc*"}}
+
+# --- === *** ###########################
+# 'Pull the rug' tests. Create channel in a thread A, move to other
+# thread B, destroy the origin thread (A) before or during access from
+# B. Must not crash, must return proper errors.
+
+test iocmd.tf-32.0 {origin thread of moved channel gone} -match glob -body {
+
+ #puts <<$tcltest::mainThread>>main
+ set tida [thread::create -preserved];#puts <<$tida>>
+ thread::send $tida {load {} Tcltest}
+
+ set tidb [thread::create -preserved];#puts <<$tidb>>
+ thread::send $tidb {load {} Tcltest}
+
+ # Set up channel in thread
+ thread::send $tida $helperscript
+ set chan [thread::send $tida {
+ proc foo {args} {oninit seek; onfinal; track; return}
+ set chan [chan create {r w} foo]
+ fconfigure $chan -buffering none
+ set chan
+ }]
+
+ # Move channel to 2nd thread.
+ thread::send $tida [list testchannel cut $chan]
+ thread::send $tidb [list testchannel splice $chan]
+
+ # Kill origin thread, then access channel from 2nd thread.
+ thread::release $tida
+
+ set res {}
+ lappend res [catch {thread::send $tidb [list puts $chan shoo]} msg] $msg
+
+ lappend res [catch {thread::send $tidb [list tell $chan]} msg] $msg
+ lappend res [catch {thread::send $tidb [list seek $chan 1]} msg] $msg
+ lappend res [catch {thread::send $tidb [list gets $chan]} msg] $msg
+ lappend res [catch {thread::send $tidb [list close $chan]} msg] $msg
+ thread::release $tidb
+ set res
+
+} -constraints {testchannel thread} \
+ -result {1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}}
+
+
+# The test iocmd.tf-32.1 unavoidably exhibits a memory leak. We are testing
+# the ability of the reflected channel system to react to the situation where
+# the thread in which the driver routines runs exits during driver operations.
+# In this case, thread exit handlers signal back to the owner thread so that the
+# channel operation does not hang. There's no way to test this without actually
+# exiting a thread in mid-operation, and that action is unavoidably leaky (which
+# is why [thread::exit] is advised against).
+#
+# Use constraints to skip this test while valgrinding so this expected leak
+# doesn't prevent a finding of "leak-free".
+#
+testConstraint notValgrind [expr {![testConstraint valgrind]}]
+test iocmd.tf-32.1 {origin thread of moved channel destroyed during access} -match glob -body {
+
+ #puts <<$tcltest::mainThread>>main
+ set tida [thread::create -preserved];#puts <<$tida>>
+ thread::send $tida {load {} Tcltest}
+ set tidb [thread::create -preserved];#puts <<$tidb>>
+ thread::send $tidb {load {} Tcltest}
+
+ # Set up channel in thread
+ thread::send $tida $helperscript
+ set chan [thread::send $tida {
+ proc foo {args} {
+ oninit; onfinal; track;
+ # destroy thread during channel access
+ thread::exit
+ }
+ set chan [chan create {r w} foo]
+ fconfigure $chan -buffering none
+ set chan
+ }]
+
+ # Move channel to 2nd thread.
+ thread::send $tida [list testchannel cut $chan]
+ thread::send $tidb [list testchannel splice $chan]
+
+ # Run access from thread B, wait for response from A (A is not
+ # using event loop at this point, so the event pile up in the
+ # queue.
+
+ thread::send $tidb [list set chan $chan]
+ thread::send $tidb [list set mid [thread::id]]
+ thread::send -async $tidb {
+ # wait a bit, give the main thread the time to start its event
+ # loop to wait for the response from B
+ after 2000
+ catch { puts $chan shoo } res
+ thread::send -async $mid [list set ::res $res]
+ }
+ vwait ::res
+
+ catch {thread::release $tida}
+ thread::release $tidb
+ set res
+} -constraints {testchannel thread notValgrind} \
+ -result {Owner lost}
+
+# ### ### ### ######### ######### #########
+
+# ### ### ### ######### ######### #########
+
+rename track {}
+# cleanup
+foreach file [list test1 test2 test3 test4] {
+ removeFile $file
+}
+# delay long enough for background processes to finish
+after 500
+foreach file [list test5] {
+ removeFile $file
+}
+cleanupTests
+return
diff --git a/library/msgcat/tests/ioTrans.test b/library/msgcat/tests/ioTrans.test
new file mode 100644
index 0000000..7da4329
--- /dev/null
+++ b/library/msgcat/tests/ioTrans.test
@@ -0,0 +1,1864 @@
+# -*- tcl -*-
+# Functionality covered: operation of the reflected transformation
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 2007 Andreas Kupries <andreask@activestate.com>
+# <akupries@shaw.ca>
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Custom constraints used in this file
+testConstraint testchannel [llength [info commands testchannel]]
+testConstraint thread [expr {0 == [catch {package require Thread 2.6}]}]
+
+# testchannel cut|splice Both needed to test the reflection in threads.
+# thread::send
+
+#----------------------------------------------------------------------
+
+# ### ### ### ######### ######### #########
+## Testing the reflected transformation.
+
+# Helper commands to record the arguments to handler methods. Stored in a
+# script so that the tests needing this code do not need their own copy but
+# can access this variable.
+
+set helperscript {
+ if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+ }
+
+ # This forces the return options to be in the order that the test expects!
+ variable optorder {
+ -code !?! -level !?! -errorcode !?! -errorline !?! -errorinfo !?!
+ -errorstack !?!
+ }
+ proc noteOpts opts {
+ variable optorder
+ lappend ::res [dict merge $optorder $opts]
+ }
+
+ # Helper command, canned result for 'initialize' method. Gets the
+ # optional methods as arguments. Use return features to post the result
+ # higher up.
+
+ proc handle.initialize {args} {
+ upvar args hargs
+ if {[lindex $hargs 0] eq "initialize"} {
+ return -code return [list {*}$args initialize finalize read write]
+ }
+ }
+ proc handle.finalize {} {
+ upvar args hargs
+ if {[lindex $hargs 0] eq "finalize"} {
+ return -code return ""
+ }
+ }
+ proc handle.read {} {
+ upvar args hargs
+ if {[lindex $hargs 0] eq "read"} {
+ return -code return "@"
+ }
+ }
+ proc handle.drain {} {
+ upvar args hargs
+ if {[lindex $hargs 0] eq "drain"} {
+ return -code return "<>"
+ }
+ }
+ proc handle.clear {} {
+ upvar args hargs
+ if {[lindex $hargs 0] eq "clear"} {
+ return -code return ""
+ }
+ }
+
+ proc tempchan {{mode r+}} {
+ global tempchan
+ return [set tempchan [open [makeFile {test data} tempchanfile] $mode]]
+ }
+ proc tempdone {} {
+ global tempchan
+ catch {close $tempchan}
+ removeFile tempchanfile
+ return
+ }
+ proc tempview {} { viewFile tempchanfile }
+}
+
+# Set everything up in the main thread.
+eval $helperscript
+
+#puts <<[file channels]>>
+
+# ### ### ### ######### ######### #########
+
+test iortrans-1.0 {chan, wrong#args} -returnCodes error -body {
+ chan
+} -result {wrong # args: should be "chan subcommand ?arg ...?"}
+test iortrans-1.1 {chan, unknown method} -returnCodes error -body {
+ chan foo
+} -match glob -result {unknown or ambiguous subcommand "foo": must be*}
+
+# --- --- --- --------- --------- ---------
+# chan push, and method "initalize"
+
+test iortrans-2.0 {chan push, wrong#args, not enough} -returnCodes error -body {
+ chan push
+} -result {wrong # args: should be "chan push channel cmdprefix"}
+test iortrans-2.1 {chan push, wrong#args, too many} -returnCodes error -body {
+ chan push a b c
+} -result {wrong # args: should be "chan push channel cmdprefix"}
+test iortrans-2.2 {chan push, invalid channel} -setup {
+ proc foo {} {}
+} -returnCodes error -body {
+ chan push {} foo
+} -cleanup {
+ rename foo {}
+} -result {can not find channel named ""}
+test iortrans-2.3 {chan push, bad handler, not a list} -body {
+ chan push [tempchan] "foo \{"
+} -returnCodes error -cleanup {
+ tempdone
+} -result {unmatched open brace in list}
+test iortrans-2.4 {chan push, bad handler, not a command} -body {
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+} -result {invalid command name "foo"}
+test iortrans-2.5 {chan push, initialize failed, bad signature} -body {
+ proc foo {} {}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -result {wrong # args: should be "foo"}
+test iortrans-2.6 {chan push, initialize failed, bad signature} -body {
+ proc foo {} {}
+ chan push [tempchan] ::foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -result {wrong # args: should be "::foo"}
+test iortrans-2.7 {chan push, initialize failed, bad result, not a list} -body {
+ proc foo {args} {return "\{"}
+ catch {chan push [tempchan] foo}
+ return $::errorInfo
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {chan handler "foo initialize" returned non-list: *}
+test iortrans-2.8 {chan push, initialize failed, bad result, not a list} -body {
+ proc foo {args} {return \{\{\}}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {chan handler "foo initialize" returned non-list: *}
+test iortrans-2.9 {chan push, initialize failed, bad result, empty list} -body {
+ proc foo {args} {}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {*all required methods*}
+test iortrans-2.10 {chan push, initialize failed, bad result, bogus method name} -body {
+ proc foo {args} {return 1}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {*bad method "1": must be *}
+test iortrans-2.11 {chan push, initialize failed, bad result, bogus method name} -body {
+ proc foo {args} {return {a b c}}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {*bad method "c": must be *}
+test iortrans-2.12 {chan push, initialize failed, bad result, required methods missing} -body {
+ # Required: initialize, and finalize.
+ proc foo {args} {return {initialize}}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {*all required methods*}
+test iortrans-2.13 {chan push, initialize failed, bad result, illegal method name} -body {
+ proc foo {args} {return {initialize finalize BOGUS}}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {*returned bad method "BOGUS": must be clear, drain, finalize, flush, initialize, limit?, read, or write}
+test iortrans-2.14 {chan push, initialize failed, bad result, mode/handler mismatch} -body {
+ proc foo {args} {return {initialize finalize}}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {*makes the channel inaccessible}
+# iortrans-2.15 event/watch methods elimimated, removed these tests.
+# iortrans-2.16
+test iortrans-2.17 {chan push, initialize failed, bad result, drain/read mismatch} -body {
+ proc foo {args} {return {initialize finalize drain write}}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {*supports "drain" but not "read"}
+test iortrans-2.18 {chan push, initialize failed, bad result, flush/write mismatch} -body {
+ proc foo {args} {return {initialize finalize flush read}}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {*supports "flush" but not "write"}
+test iortrans-2.19 {chan push, initialize ok, creates channel} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ global res
+ lappend res $args
+ if {[lindex $args 0] ne "initialize"} {return}
+ return {initialize finalize drain flush read write}
+ }
+ lappend res [file channel rt*]
+ lappend res [chan push [tempchan] foo]
+ lappend res [close [lindex $res end]]
+ lappend res [file channel rt*]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{} {initialize rt* {read write}} file* {drain rt*} {flush rt*} {finalize rt*} {} {}}
+test iortrans-2.20 {chan push, init failure -> no channel, no finalize} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ global res
+ lappend res $args
+ return
+ }
+ lappend res [file channel rt*]
+ lappend res [catch {chan push [tempchan] foo} msg] $msg
+ lappend res [file channel rt*]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{} {initialize rt* {read write}} 1 {*all required methods*} {}}
+
+# --- --- --- --------- --------- ---------
+# method finalize (via close)
+
+# General note: file channels rt* finds the transform channel, however the
+# name reported will be that of the underlying base driver, fileXX here. This
+# actually allows us to see if the whole channel is gone, or only the
+# transformation, but not the base.
+
+test iortrans-3.1 {chan finalize, handler destruction has no effect on channel} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ rename foo {}
+ lappend res [file channels file*]
+ lappend res [file channels rt*]
+ lappend res [catch {close $c} msg] $msg
+ lappend res [file channels file*]
+ lappend res [file channels rt*]
+} -result {{initialize rt* {read write}} file* file* {} 1 {invalid command name "foo"} {} {}}
+test iortrans-3.2 {chan finalize, for close} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ close $c
+ # Close deleted the channel.
+ lappend res [file channels rt*]
+ # Channel destruction does not kill handler command!
+ lappend res [info command foo]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} {} foo}
+test iortrans-3.3 {chan finalize, for close, error, close error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -code error 5
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res [catch {close $c} msg] $msg
+ # Channel is gone despite error.
+ lappend res [file channels rt*]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 5 {}}
+test iortrans-3.4 {chan finalize, for close, error, close error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ error FOO
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res [catch {close $c} msg] $msg $::errorInfo
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 FOO {FOO
+*"close $c"}}
+test iortrans-3.5 {chan finalize, for close, arbitrary result, ignored} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return SOMETHING
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res [catch {close $c} msg] $msg
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 0 {}}
+test iortrans-3.6 {chan finalize, for close, break, close error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -code 3
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res [catch {close $c} msg] $msg
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans-3.7 {chan finalize, for close, continue, close error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -code 4
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res [catch {close $c} msg] $msg
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans-3.8 {chan finalize, for close, custom code, close error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -code 777 BANG
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res [catch {close $c} msg] $msg
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans-3.9 {chan finalize, for close, ignore level, close error} -setup {
+ set res {}
+} -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -level 5 -code 777 BANG
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res [catch {close $c} msg opt] $msg
+ noteOpts $opt
+} -match glob -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "finalize"*}}
+
+# --- === *** ###########################
+# method read (via read)
+
+test iortrans-4.1 {chan read, transform call and return} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return snarf
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [read $c 10]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} snarf}
+test iortrans-4.2 {chan read, for non-readable channel} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args MUST_NOT_HAPPEN
+ }
+ set c [chan push [tempchan w] foo]
+ lappend res [catch {read $c 2} msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {1 {channel "file*" wasn't opened for reading}}
+test iortrans-4.3 {chan read, error return} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code error BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {read $c 2} msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} 1 BOOM!}
+test iortrans-4.4 {chan read, break return is error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code break BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {read $c 2} msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans-4.5 {chan read, continue return is error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code continue BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {read $c 2} msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans-4.6 {chan read, custom return is error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code 777 BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {read $c 2} msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans-4.7 {chan read, level is squashed} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -level 55 -code 777 BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {read $c 2} msg opt] $msg
+ noteOpts $opt
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}}
+test iortrans-4.8 {chan read, read, bug 2921116} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {fd args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ # Kill and recreate transform while it is operating
+ chan pop $fd
+ chan push $fd [list foo $fd]
+ }
+ set c [chan push [set c [tempchan]] [list foo $c]]
+ lappend res [read $c]
+ #lappend res [gets $c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} file*}
+test iortrans-4.9 {chan read, gets, bug 2921116} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {fd args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ # Kill and recreate transform while it is operating
+ chan pop $fd
+ chan push $fd [list foo $fd]
+ }
+ set c [chan push [set c [tempchan]] [list foo $c]]
+ lappend res [gets $c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} file*}
+
+# --- === *** ###########################
+# method write (via puts)
+
+test iortrans-5.1 {chan write, regular write} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return transformresult
+ }
+ set c [chan push [tempchan] foo]
+ puts -nonewline $c snarf
+ flush $c
+ close $c
+ lappend res [tempview]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarf} transformresult}
+test iortrans-5.2 {chan write, no write is ok, no change to file} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return
+ }
+ set c [chan push [tempchan] foo]
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ close $c
+ lappend res [tempview]; # This has to show the original data, as nothing was written
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} {test data}}
+test iortrans-5.3 {chan write, failed write} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code error FAIL!
+ }
+ set c [chan push [tempchan] foo]
+ puts -nonewline $c snarfsnarfsnarf
+ lappend res [catch {flush $c} msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 FAIL!}
+test iortrans-5.4 {chan write, non-writable channel} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args MUST_NOT_HAPPEN
+ return
+ }
+ set c [chan push [tempchan r] foo]
+ lappend res [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+} -cleanup {
+ close $c
+ tempdone
+ rename foo {}
+} -result {1 {channel "file*" wasn't opened for writing}}
+test iortrans-5.5 {chan write, failed write, error return} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code error BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 BOOM!}
+test iortrans-5.6 {chan write, failed write, error return} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ error BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 BOOM!}
+test iortrans-5.7 {chan write, failed write, break return is error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code break BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans-5.8 {chan write, failed write, continue return is error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code continue BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans-5.9 {chan write, failed write, custom return is error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code 777 BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans-5.10 {chan write, failed write, level is ignored} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -level 55 -code 777 BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg opt] $msg
+ noteOpts $opt
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline * -errorinfo *bad code*subcommand "write"*}}
+test iortrans-5.11 {chan write, bug 2921116} -match glob -setup {
+ set res {}
+ set level 0
+} -body {
+ proc foo {fd args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ # pop - invokes flush - invokes 'foo write' - infinite recursion - stop it
+ global level
+ if {$level} {
+ return
+ }
+ incr level
+ # Kill and recreate transform while it is operating
+ chan pop $fd
+ chan push $fd [list foo $fd]
+ }
+ set c [chan push [set c [tempchan]] [list foo $c]]
+ lappend res [puts -nonewline $c abcdef]
+ lappend res [flush $c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{} {write rt* abcdef} {write rt* abcdef} {}}
+
+# --- === *** ###########################
+# method limit?, drain (via read)
+
+test iortrans-6.1 {chan read, read limits} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize limit?
+ handle.finalize
+ lappend ::res $args
+ handle.read
+ return 6
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [read $c 10]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{limit? rt*} {read rt* {test d}} {limit? rt*} {read rt* {ata
+}} {limit? rt*} @@}
+test iortrans-6.2 {chan read, read transform drain on eof} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize drain
+ handle.finalize
+ lappend ::res $args
+ handle.read
+ handle.drain
+ return
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [read $c]
+ lappend res [close $c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} {drain rt*} @<> {}}
+
+# --- === *** ###########################
+# method clear (via puts, seek)
+
+test iortrans-7.1 {chan write, write clears read buffers} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize clear
+ handle.finalize
+ lappend ::res $args
+ handle.clear
+ return transformresult
+ }
+ set c [chan push [tempchan] foo]
+ puts -nonewline $c snarf
+ flush $c
+ return $res
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{clear rt*} {write rt* snarf}}
+test iortrans-7.2 {seek clears read buffers} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize clear
+ handle.finalize
+ lappend ::res $args
+ return
+ }
+ set c [chan push [tempchan] foo]
+ seek $c 2
+ return $res
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{clear rt*}}
+test iortrans-7.3 {clear, any result is ignored} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize clear
+ handle.finalize
+ lappend ::res $args
+ return -code error "X"
+ }
+ set c [chan push [tempchan] foo]
+ seek $c 2
+ return $res
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{clear rt*}}
+test iortrans-7.4 {chan clear, bug 2921116} -match glob -setup {
+ set res {}
+} -body {
+ proc foo {fd args} {
+ handle.initialize clear
+ handle.finalize
+ lappend ::res $args
+ # Kill and recreate transform while it is operating
+ chan pop $fd
+ chan push $fd [list foo $fd]
+ }
+ set c [chan push [set c [tempchan]] [list foo $c]]
+ seek $c 2
+ return $res
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{clear rt*}}
+
+# --- === *** ###########################
+# method flush (via seek, close)
+
+test iortrans-8.1 {seek flushes write buffers, ignores data} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize flush
+ handle.finalize
+ lappend ::res $args
+ return X
+ }
+ set c [chan push [tempchan] foo]
+ # Flush, no writing
+ seek $c 2
+ # The close flushes again, this modifies the file!
+ lappend res |
+ lappend res [close $c] | [tempview]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{flush rt*} | {flush rt*} {} | {teXt data}}
+test iortrans-8.2 {close flushes write buffers, writes data} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize flush
+ lappend ::res $args
+ handle.finalize
+ return .flushed.
+ }
+ set c [chan push [tempchan] foo]
+ close $c
+ lappend res [tempview]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{flush rt*} {finalize rt*} .flushed.}
+test iortrans-8.3 {chan flush, bug 2921116} -match glob -setup {
+ set res {}
+} -body {
+ proc foo {fd args} {
+ handle.initialize flush
+ handle.finalize
+ lappend ::res $args
+ # Kill and recreate transform while it is operating
+ chan pop $fd
+ chan push $fd [list foo $fd]
+ }
+ set c [chan push [set c [tempchan]] [list foo $c]]
+ seek $c 2
+ set res
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{flush rt*}}
+
+# --- === *** ###########################
+# method watch - removed from TIP (rev 1.12+)
+
+# --- === *** ###########################
+# method event - removed from TIP (rev 1.12+)
+
+# --- === *** ###########################
+# 'Pull the rug' tests. Create channel in a interpreter A, move to other
+# interpreter B, destroy the origin interpreter (A) before or during access
+# from B. Must not crash, must return proper errors.
+test iortrans-11.0 {origin interpreter of moved transform gone} -setup {
+ set ida [interp create]; #puts <<$ida>>
+ set idb [interp create]; #puts <<$idb>>
+ # Magic to get the test* commands in the slaves
+ load {} Tcltest $ida
+ load {} Tcltest $idb
+} -constraints {testchannel} -match glob -body {
+ # Set up channel and transform in interpreter
+ interp eval $ida $helperscript
+ interp eval $ida [list ::variable tempchan [tempchan]]
+ interp transfer {} $::tempchan $ida
+ set chan [interp eval $ida {
+ variable tempchan
+ proc foo {args} {
+ handle.initialize clear drain flush limit? read write
+ handle.finalize
+ lappend ::res $args
+ return
+ }
+ set chan [chan push $tempchan foo]
+ fconfigure $chan -buffering none
+ set chan
+ }]
+ # Move channel to 2nd interpreter, transform goes with it.
+ interp eval $ida [list testchannel cut $chan]
+ interp eval $idb [list testchannel splice $chan]
+ # Kill origin interpreter, then access channel from 2nd interpreter.
+ interp delete $ida
+ set res {}
+ lappend res \
+ [catch {interp eval $idb [list puts $chan shoo]} msg] $msg \
+ [catch {interp eval $idb [list tell $chan]} msg] $msg \
+ [catch {interp eval $idb [list seek $chan 1]} msg] $msg \
+ [catch {interp eval $idb [list gets $chan]} msg] $msg \
+ [catch {interp eval $idb [list close $chan]} msg] $msg
+ #lappend res [interp eval $ida {set res}]
+ # actions: clear|write|clear|write|clear|flush|limit?|drain|flush
+ # The 'tell' is ok, as it passed through the transform to the base channel
+ # without invoking the transform handler.
+} -cleanup {
+ tempdone
+} -result {1 {Owner lost} 0 0 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}}
+test iortrans-11.1 {origin interpreter of moved transform destroyed during access} -setup {
+ set ida [interp create]; #puts <<$ida>>
+ set idb [interp create]; #puts <<$idb>>
+ # Magic to get the test* commands in the slaves
+ load {} Tcltest $ida
+ load {} Tcltest $idb
+} -constraints {testchannel impossible} -match glob -body {
+ # Set up channel in thread
+ set chan [interp eval $ida $helperscript]
+ set chan [interp eval $ida {
+ proc foo {args} {
+ handle.initialize clear drain flush limit? read write
+ handle.finalize
+ lappend ::res $args
+ # Destroy interpreter during channel access. Actually not
+ # possible for an interp to destroy itself.
+ interp delete {}
+ return}
+ set chan [chan push [tempchan] foo]
+ fconfigure $chan -buffering none
+ set chan
+ }]
+ # Move channel to 2nd thread, transform goes with it.
+ interp eval $ida [list testchannel cut $chan]
+ interp eval $idb [list testchannel splice $chan]
+ # Run access from interpreter B, this will give us a synchronous response.
+ interp eval $idb [list set chan $chan]
+ interp eval $idb [list set mid $tcltest::mainThread]
+ set res [interp eval $idb {
+ # Wait a bit, give the main thread the time to start its event loop to
+ # wait for the response from B
+ after 50
+ catch { puts $chan shoo } res
+ set res
+ }]
+} -cleanup {
+ tempdone
+} -result {Owner lost}
+test iortrans-11.2 {delete interp of reflected transform} -setup {
+ interp create slave
+ # Magic to get the test* commands into the slave
+ load {} Tcltest slave
+} -constraints {testchannel} -body {
+ # Get base channel into the slave
+ set c [tempchan]
+ testchannel cut $c
+ interp eval slave [list testchannel splice $c]
+ interp eval slave [list set c $c]
+ slave eval {
+ proc no-op args {}
+ proc driver {c sub args} {
+ return {initialize finalize read write}
+ }
+ set t [chan push $c [list driver $c]]
+ chan event $c readable no-op
+ }
+ interp delete slave
+} -result {}
+
+# ### ### ### ######### ######### #########
+## Same tests as above, but exercising the code forwarding and receiving
+## driver operations to the originator thread.
+
+# ### ### ### ######### ######### #########
+## Testing the reflected channel (Thread forwarding).
+#
+## The id numbers refer to the original test without thread forwarding, and
+## gaps due to tests not applicable to forwarding are left to keep this
+## association.
+
+# ### ### ### ######### ######### #########
+## Helper command. Runs a script in a separate thread and returns the result.
+## A channel is transfered into the thread as well, and a list of configuation
+## variables
+
+proc inthread {chan script args} {
+ # Test thread.
+ set tid [thread::create -preserved]
+ thread::send $tid {load {} Tcltest}
+
+ # Init thread configuration.
+ # - Listed variables
+ # - Id of main thread
+ # - A number of helper commands
+
+ foreach v $args {
+ upvar 1 $v x
+ thread::send $tid [list set $v $x]
+ }
+ thread::send $tid [list set mid [thread::id]]
+ thread::send $tid {
+ proc notes {} {
+ return $::notes
+ }
+ proc noteOpts opts {
+ lappend ::notes [dict merge {
+ -code !?! -level !?! -errorcode !?! -errorline !?!
+ -errorinfo !?! -errorstack !?!
+ } $opts]
+ }
+ }
+ thread::send $tid [list proc s {} [list uplevel 1 $script]]; # (*)
+
+ # Transfer channel (cut/splice aka detach/attach)
+
+ testchannel cut $chan
+ thread::send $tid [list testchannel splice $chan]
+
+ # Run test script, also run local event loop! The local event loop waits
+ # for the result to come back. It is also necessary for the execution of
+ # forwarded channel operations.
+
+ set ::tres ""
+ thread::send -async $tid {
+ after 50
+ catch {s} res; # This runs the script, 's' was defined at (*)
+ thread::send -async $mid [list set ::tres $res]
+ }
+ vwait ::tres
+ # Remove test thread, and return the captured result.
+
+ thread::release $tid
+ return $::tres
+}
+
+# ### ### ### ######### ######### #########
+
+test iortrans.tf-3.2 {chan finalize, for close} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return {}
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res [inthread $c {
+ close $c
+ # Close the deleted the channel.
+ file channels rt*
+ } c]
+ # Channel destruction does not kill handler command!
+ lappend res [info command foo]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} {} foo}
+test iortrans.tf-3.3 {chan finalize, for close, error, close error} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -code error 5
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {close $c} msg] $msg
+ # Channel is gone despite error.
+ lappend notes [file channels rt*]
+ notes
+ } c]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 5 {}}
+test iortrans.tf-3.4 {chan finalize, for close, error, close errror} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ error FOO
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {close $c} msg] $msg
+ notes
+ } c]
+} -match glob -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 FOO}
+test iortrans.tf-3.5 {chan finalize, for close, arbitrary result} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return SOMETHING
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {close $c} msg] $msg
+ notes
+ } c]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 0 {}}
+test iortrans.tf-3.6 {chan finalize, for close, break, close error} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -code 3
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {close $c} msg] $msg
+ notes
+ } c]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans.tf-3.7 {chan finalize, for close, continue, close error} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -code 4
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {close $c} msg] $msg
+ notes
+ } c]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans.tf-3.8 {chan finalize, for close, custom code, close error} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -code 777 BANG
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {close $c} msg] $msg
+ notes
+ } c]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans.tf-3.9 {chan finalize, for close, ignore level, close error} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -level 5 -code 777 BANG
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {close $c} msg opt] $msg
+ noteOpts $opt
+ notes
+ } c]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "finalize"*}}
+
+# --- === *** ###########################
+# method read
+
+test iortrans.tf-4.1 {chan read, transform call and return} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return snarf
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [read $c 10]
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {{read rt* {test data
+}} snarf}
+test iortrans.tf-4.2 {chan read, for non-readable channel} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args MUST_NOT_HAPPEN
+ }
+ set c [chan push [tempchan w] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {[read $c 2]} msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {1 {channel "file*" wasn't opened for reading}}
+test iortrans.tf-4.3 {chan read, error return} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code error BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {read $c 2} msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {{read rt* {test data
+}} 1 BOOM!}
+test iortrans.tf-4.4 {chan read, break return is error} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code break BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {read $c 2} msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans.tf-4.5 {chan read, continue return is error} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code continue BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {read $c 2} msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans.tf-4.6 {chan read, custom return is error} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code 777 BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {read $c 2} msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans.tf-4.7 {chan read, level is squashed} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -level 55 -code 777 BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {read $c 2} msg opt] $msg
+ noteOpts $opt
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {{read rt* {test data
+}} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}}
+
+# --- === *** ###########################
+# method write
+
+test iortrans.tf-5.1 {chan write, regular write} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return transformresult
+ }
+ set c [chan push [tempchan] foo]
+ inthread $c {
+ puts -nonewline $c snarf
+ flush $c
+ close $c
+ } c
+ lappend res [tempview]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarf} transformresult}
+test iortrans.tf-5.2 {chan write, no write is ok, no change to file} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return
+ }
+ set c [chan push [tempchan] foo]
+ inthread $c {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ close $c
+ } c
+ lappend res [tempview]; # This has to show the original data, as nothing was written
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} {test data}}
+test iortrans.tf-5.3 {chan write, failed write} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code error FAIL!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ puts -nonewline $c snarfsnarfsnarf
+ lappend notes [catch {flush $c} msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 FAIL!}
+test iortrans.tf-5.4 {chan write, non-writable channel} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args MUST_NOT_HAPPEN
+ return
+ }
+ set c [chan push [tempchan r] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {1 {channel "file*" wasn't opened for writing}}
+test iortrans.tf-5.5 {chan write, failed write, error return} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code error BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 BOOM!}
+test iortrans.tf-5.6 {chan write, failed write, error return} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ error BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 BOOM!}
+test iortrans.tf-5.7 {chan write, failed write, break return is error} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code break BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans.tf-5.8 {chan write, failed write, continue return is error} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code continue BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans.tf-5.9 {chan write, failed write, custom return is error} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code 777 BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans.tf-5.10 {chan write, failed write, level is ignored} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -level 55 -code 777 BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg opt] $msg
+ noteOpts $opt
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline * -errorinfo *bad code*subcommand "write"*}}
+
+# --- === *** ###########################
+# method limit?, drain (via read)
+
+test iortrans.tf-6.1 {chan read, read limits} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize limit?
+ handle.finalize
+ lappend ::res $args
+ handle.read
+ return 6
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [read $c 10]
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{limit? rt*} {read rt* {test d}} {limit? rt*} {read rt* {ata
+}} {limit? rt*} @@}
+test iortrans.tf-6.2 {chan read, read transform drain on eof} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize drain
+ handle.finalize
+ lappend ::res $args
+ handle.read
+ handle.drain
+ return
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [read $c]
+ lappend notes [close $c]
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} {drain rt*} @<> {}}
+
+# --- === *** ###########################
+# method clear (via puts, seek)
+
+test iortrans.tf-7.1 {chan write, write clears read buffers} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize clear
+ handle.finalize
+ lappend ::res $args
+ handle.clear
+ return transformresult
+ }
+ set c [chan push [tempchan] foo]
+ inthread $c {
+ puts -nonewline $c snarf
+ flush $c
+ close $c
+ } c
+ return $res
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{clear rt*} {write rt* snarf}}
+test iortrans.tf-7.2 {seek clears read buffers} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize clear
+ handle.finalize
+ lappend ::res $args
+ return
+ }
+ set c [chan push [tempchan] foo]
+ inthread $c {
+ seek $c 2
+ close $c
+ } c
+ return $res
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{clear rt*}}
+test iortrans.tf-7.3 {clear, any result is ignored} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize clear
+ handle.finalize
+ lappend ::res $args
+ return -code error "X"
+ }
+ set c [chan push [tempchan] foo]
+ inthread $c {
+ seek $c 2
+ close $c
+ } c
+ return $res
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{clear rt*}}
+
+# --- === *** ###########################
+# method flush (via seek, close)
+
+test iortrans.tf-8.1 {seek flushes write buffers, ignores data} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize flush
+ handle.finalize
+ lappend ::res $args
+ return X
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ # Flush, no writing
+ seek $c 2
+ # The close flushes again, this modifies the file!
+ lappend notes | [close $c] |
+ # NOTE: The flush generated by the close is recorded immediately, the
+ # other note's here are defered until after the thread is done. This
+ # changes the order of the result a bit from the non-threaded case
+ # (The first | moves one to the right). This is an artifact of the
+ # 'inthread' framework, not of the transformation itself.
+ notes
+ } c]
+ lappend res [tempview]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{flush rt*} {flush rt*} | {} | {teXt data}}
+test iortrans.tf-8.2 {close flushes write buffers, writes data} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize flush
+ lappend ::res $args
+ handle.finalize
+ return .flushed.
+ }
+ set c [chan push [tempchan] foo]
+ inthread $c {
+ close $c
+ } c
+ lappend res [tempview]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{flush rt*} {finalize rt*} .flushed.}
+
+# --- === *** ###########################
+# method watch - removed from TIP (rev 1.12+)
+
+# --- === *** ###########################
+# method event - removed from TIP (rev 1.12+)
+
+# --- === *** ###########################
+# 'Pull the rug' tests. Create channel in a thread A, move to other thread B,
+# destroy the origin thread (A) before or during access from B. Must not
+# crash, must return proper errors.
+
+test iortrans.tf-11.0 {origin thread of moved transform gone} -setup {
+ #puts <<$tcltest::mainThread>>main
+ set tida [thread::create -preserved]; #puts <<$tida>>
+ thread::send $tida {load {} Tcltest}
+ set tidb [thread::create -preserved]; #puts <<$tida>>
+ thread::send $tidb {load {} Tcltest}
+} -constraints {testchannel thread} -match glob -body {
+ # Set up channel in thread
+ thread::send $tida $helperscript
+ thread::send $tidb $helperscript
+ set chan [thread::send $tida {
+ proc foo {args} {
+ handle.initialize clear drain flush limit? read write
+ handle.finalize
+ lappend ::res $args
+ return
+ }
+ set chan [chan push [tempchan] foo]
+ fconfigure $chan -buffering none
+ set chan
+ }]
+
+ # Move channel to 2nd thread, transform goes with it.
+ thread::send $tida [list testchannel cut $chan]
+ thread::send $tidb [list testchannel splice $chan]
+
+ # Kill origin thread, then access channel from 2nd thread.
+ thread::release -wait $tida
+
+ set res {}
+ lappend res [catch {thread::send $tidb [list puts $chan shoo]} msg] $msg
+ lappend res [catch {thread::send $tidb [list tell $chan]} msg] $msg
+ lappend res [catch {thread::send $tidb [list seek $chan 1]} msg] $msg
+ lappend res [catch {thread::send $tidb [list gets $chan]} msg] $msg
+ lappend res [catch {thread::send $tidb [list close $chan]} msg] $msg
+ # The 'tell' is ok, as it passed through the transform to the base
+ # channel without invoking the transform handler.
+} -cleanup {
+ thread::send $tidb tempdone
+ thread::release $tidb
+} -result {1 {Owner lost} 0 0 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}}
+
+testConstraint notValgrind [expr {![testConstraint valgrind]}]
+
+test iortrans.tf-11.1 {origin thread of moved transform destroyed during access} -setup {
+ #puts <<$tcltest::mainThread>>main
+ set tida [thread::create -preserved]; #puts <<$tida>>
+ thread::send $tida {load {} Tcltest}
+ set tidb [thread::create -preserved]; #puts <<$tidb>>
+ thread::send $tidb {load {} Tcltest}
+} -constraints {testchannel thread notValgrind} -match glob -body {
+ # Set up channel in thread
+ thread::send $tida $helperscript
+ thread::send $tidb $helperscript
+ set chan [thread::send $tida {
+ proc foo {args} {
+ handle.initialize clear drain flush limit? read write
+ handle.finalize
+ lappend ::res $args
+ # destroy thread during channel access
+ thread::exit
+ }
+ set chan [chan push [tempchan] foo]
+ fconfigure $chan -buffering none
+ set chan
+ }]
+
+ # Move channel to 2nd thread, transform goes with it.
+ thread::send $tida [list testchannel cut $chan]
+ thread::send $tidb [list testchannel splice $chan]
+
+ # Run access from thread B, wait for response from A (A is not using event
+ # loop at this point, so the event pile up in the queue.
+ thread::send $tidb [list set chan $chan]
+ thread::send $tidb [list set mid [thread::id]]
+ thread::send -async $tidb {
+ # Wait a bit, give the main thread the time to start its event loop to
+ # wait for the response from B
+ after 50
+ catch { puts $chan shoo } res
+ catch { close $chan }
+ thread::send -async $mid [list set ::res $res]
+ }
+ vwait ::res
+ set res
+} -cleanup {
+ thread::send $tidb tempdone
+ thread::release $tidb
+} -result {Owner lost}
+
+# ### ### ### ######### ######### #########
+
+cleanupTests
+return
diff --git a/library/msgcat/tests/iogt.test b/library/msgcat/tests/iogt.test
new file mode 100644
index 0000000..60d7ab8
--- /dev/null
+++ b/library/msgcat/tests/iogt.test
@@ -0,0 +1,802 @@
+# -*- tcl -*-
+# Commands covered: transform, and stacking in general
+#
+# This file contains a collection of tests for Giot
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# Copyright (c) 2000 Ajuba Solutions.
+# Copyright (c) 2000 Andreas Kupries.
+# All rights reserved.
+
+if {[catch {package require tcltest 2.1}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2.1 required."
+ return
+}
+namespace eval ::tcl::test::iogt {
+ namespace import ::tcltest::*
+
+testConstraint testchannel [llength [info commands testchannel]]
+
+set path(dummy) [makeFile {abcdefghijklmnopqrstuvwxyz0123456789,./?><;'\|":[]\}\{`~!@#$%^&*()_+-=
+} dummy]
+
+# " capture coloring of quotes
+
+set path(dummyout) [makeFile {} dummyout]
+
+set path(__echo_srv__.tcl) [makeFile {
+#!/usr/local/bin/tclsh
+# -*- tcl -*-
+# echo server
+#
+# arguments, options: port to listen on for connections.
+# delay till echo of first block
+# delay between blocks
+# blocksize ...
+
+set port [lindex $argv 0]
+set fdelay [lindex $argv 1]
+set idelay [lindex $argv 2]
+set bsizes [lrange $argv 3 end]
+set c 0
+
+proc newconn {sock rhost rport} {
+ variable fdelay
+ variable c
+ incr c
+ namespace upvar [namespace current] c$c conn
+
+ #puts stdout "C $sock $rhost $rport / $fdelay" ; flush stdout
+
+ set conn(after) {}
+ set conn(state) 0
+ set conn(size) 0
+ set conn(data) ""
+ set conn(delay) $fdelay
+
+ fileevent $sock readable [list echoGet $c $sock]
+ fconfigure $sock -translation binary -buffering none -blocking 0
+}
+
+proc echoGet {c sock} {
+ variable fdelay
+ namespace upvar [namespace current] c$c conn
+
+ if {[eof $sock]} {
+ # one-shot echo
+ exit
+ }
+ append conn(data) [read $sock]
+
+ #puts stdout "G $c $sock $conn(data) <<$conn(data)>>" ; flush stdout
+
+ if {$conn(after) == {}} {
+ set conn(after) [after $conn(delay) [list echoPut $c $sock]]
+ }
+}
+
+proc echoPut {c sock} {
+ variable idelay
+ variable fdelay
+ variable bsizes
+ namespace upvar [namespace current] c$c conn
+
+ if {[string length $conn(data)] == 0} {
+ #puts stdout "C $c $sock" ; flush stdout
+ # auto terminate
+ close $sock
+ exit
+ #set conn(delay) $fdelay
+ return
+ }
+
+ set conn(delay) $idelay
+ set n [lindex $bsizes $conn(size)]
+
+ #puts stdout "P $c $sock $n >>" ; flush stdout
+
+ #puts __________________________________________
+ #parray conn
+ #puts n=<$n>
+
+ if {[string length $conn(data)] >= $n} {
+ puts -nonewline $sock [string range $conn(data) 0 $n]
+ set conn(data) [string range $conn(data) [incr n] end]
+ }
+
+ incr conn(size)
+ if {$conn(size) >= [llength $bsizes]} {
+ set conn(size) [expr {[llength $bsizes]-1}]
+ }
+
+ set conn(after) [after $conn(delay) [list echoPut $c $sock]]
+}
+
+#fileevent stdin readable {exit ;#cut}
+
+# main
+socket -server newconn -myaddr 127.0.0.1 $port
+vwait forever
+} __echo_srv__.tcl]
+
+########################################################################
+
+proc fevent {fdelay idelay blocks script data} {
+ # Start and initialize an echo server, prepare data transmission, then
+ # hand over to the test script. This has to start real transmission via
+ # 'flush'. The server is stopped after completion of the test.
+
+ upvar 1 sock sk
+
+ # Fixed port, not so good. Lets hope for the best, for now.
+ set port 4000
+
+ exec tclsh __echo_srv__.tcl $port $fdelay $idelay {*}$blocks >@stdout &
+ after 500
+
+ #puts stdout "> $port"; flush stdout
+
+ set sk [socket localhost $port]
+ fconfigure $sk -blocking 0 -buffering full \
+ -buffersize [expr {10+[llength $data]}]
+ puts -nonewline $sk $data
+
+ # The channel is prepared to go off.
+
+ #puts stdout ">>>>>"; flush stdout
+
+ set res [uplevel 1 $script]
+ catch {close $sk}
+ return $res
+}
+
+# --------------------------------------------------------------
+# utility transformations ...
+
+proc id {op data} {
+ switch -- $op {
+ create/write - create/read - delete/write - delete/read - clear_read {
+ #ignore
+ }
+ flush/write - flush/read - write - read {
+ return $data
+ }
+ query/maxRead {
+ return -1
+ }
+ }
+}
+
+proc id_optrail {var op data} {
+ variable $var
+ upvar 0 $var trail
+
+ lappend trail $op
+ switch -- $op {
+ create/write - create/read - delete/write - delete/read -
+ flush/read - clear/read {
+ #ignore
+ }
+ flush/write - write - read {
+ return $data
+ }
+ query/maxRead {
+ return -1
+ }
+ default {
+ lappend trail "error $op"
+ error $op
+ }
+ }
+}
+
+proc id_fulltrail {var op data} {
+ namespace upvar [namespace current] $var trail
+
+ #puts stdout ">> $var $op $data" ; flush stdout
+
+ switch -- $op {
+ create/write - create/read - delete/write - delete/read - clear_read {
+ set res *ignored*
+ }
+ flush/write - flush/read - write - read {
+ set res $data
+ }
+ query/maxRead {
+ set res -1
+ }
+ }
+
+ #catch {puts stdout "\t>* $res" ; flush stdout}
+ #catch {puts stdout "x$res"} msg
+
+ lappend trail [list $op $data $res]
+ return $res
+}
+
+proc counter {var op data} {
+ namespace upvar [namespace current] $var n
+
+ switch -- $op {
+ create/write - create/read - delete/write - delete/read - clear_read {
+ #ignore
+ }
+ flush/write - flush/read {
+ return {}
+ }
+ write {
+ return $data
+ }
+ read {
+ if {$n > 0} {
+ incr n -[string length $data]
+ if {$n < 0} {
+ set n 0
+ }
+ }
+ return $data
+ }
+ query/maxRead {
+ return $n
+ }
+ }
+}
+
+proc counter_audit {var vtrail op data} {
+ namespace upvar [namespace current] $var n $vtrail trail
+
+ switch -- $op {
+ create/write - create/read - delete/write - delete/read - clear_read {
+ set res {}
+ }
+ flush/write - flush/read {
+ set res {}
+ }
+ write {
+ set res $data
+ }
+ read {
+ if {$n > 0} {
+ incr n -[string length $data]
+ if {$n < 0} {
+ set n 0
+ }
+ }
+ set res $data
+ }
+ query/maxRead {
+ set res $n
+ }
+ }
+
+ lappend trail [list counter:$op $data $res]
+ return $res
+}
+
+proc rblocks {var vtrail n op data} {
+ namespace upvar [namespace current] $var n $vtrail trail
+
+ set res {}
+
+ switch -- $op {
+ create/write - create/read - delete/write - delete/read - clear_read {
+ set buf {}
+ }
+ flush/write {
+ }
+ flush/read {
+ set res $buf
+ set buf {}
+ }
+ write {
+ set data
+ }
+ read {
+ append buf $data
+ set b [expr {$n * ([string length $buf] / $n)}]
+ append op " $n [string length $buf] :- $b"
+ set res [string range $buf 0 [incr b -1]]
+ set buf [string range $buf [incr b] end]
+ #return $res
+ }
+ query/maxRead {
+ set res -1
+ }
+ }
+
+ lappend trail [list rblock | $op $data $res | $buf]
+ return $res
+}
+
+# --------------------------------------------------------------
+# ... and convenience procedures to stack them
+
+proc identity {-attach channel} {
+ testchannel transform $channel -command [namespace code id]
+}
+proc audit_ops {var -attach channel} {
+ testchannel transform $channel -command [namespace code [list id_optrail $var]]
+}
+proc audit_flow {var -attach channel} {
+ testchannel transform $channel -command [namespace code [list id_fulltrail $var]]
+}
+proc stopafter {var n -attach channel} {
+ namespace upvar [namespace current] $var vn
+ set vn $n
+ testchannel transform $channel -command [namespace code [list counter $var]]
+}
+proc stopafter_audit {var trail n -attach channel} {
+ namespace upvar [namespace current] $var vn
+ set vn $n
+ testchannel transform $channel -command [namespace code [list counter_audit $var $trail]]
+}
+proc rblocks_t {var trail n -attach channel} {
+ testchannel transform $channel -command [namespace code [list rblocks $var $trail $n]]
+}
+
+# --------------------------------------------------------------
+# serialize an array, with keys in sorted order.
+
+proc array_sget {v} {
+ upvar $v a
+ set res [list]
+ foreach n [lsort [array names a]] {
+ lappend res $n $a($n)
+ }
+ set res
+}
+proc asort {alist} {
+ # sort a list of key/value pairs by key, removes duplicates too.
+ array set a $alist
+ array_sget a
+}
+
+########################################################################
+
+test iogt-1.1 {stack/unstack} testchannel {
+ set fh [open $path(dummy) r]
+ identity -attach $fh
+ testchannel unstack $fh
+ close $fh
+} {}
+test iogt-1.2 {stack/close} testchannel {
+ set fh [open $path(dummy) r]
+ identity -attach $fh
+ close $fh
+} {}
+test iogt-1.3 {stack/unstack, configuration, options} testchannel {
+ set fh [open $path(dummy) r]
+ set ca [asort [fconfigure $fh]]
+ identity -attach $fh
+ set cb [asort [fconfigure $fh]]
+ testchannel unstack $fh
+ set cc [asort [fconfigure $fh]]
+ close $fh
+ # With this system none of the buffering, translation and encoding option
+ # may change their values with channels stacked upon each other or not.
+ # cb == ca == cc
+ list [string equal $ca $cb] [string equal $cb $cc] [string equal $ca $cc]
+} {1 1 1}
+test iogt-1.4 {stack/unstack, configuration} -setup {
+ set fh [open $path(dummy) r]
+} -constraints testchannel -body {
+ set ca [asort [fconfigure $fh]]
+ identity -attach $fh
+ fconfigure $fh -buffering line -translation cr -encoding shiftjis
+ testchannel unstack $fh
+ set cc [asort [fconfigure $fh]]
+ list [string equal $ca $cc] [fconfigure $fh -buffering] \
+ [fconfigure $fh -translation] [fconfigure $fh -encoding]
+} -cleanup {
+ close $fh
+} -result {0 line cr shiftjis}
+
+test iogt-2.0 {basic I/O going through transform} -setup {
+ set fin [open $path(dummy) r]
+ set fout [open $path(dummyout) w]
+} -constraints testchannel -body {
+ identity -attach $fin
+ identity -attach $fout
+ fcopy $fin $fout
+ close $fin
+ close $fout
+ set fin [open $path(dummy) r]
+ set fout [open $path(dummyout) r]
+ list [string equal [set in [read $fin]] [set out [read $fout]]] \
+ [string length $in] [string length $out]
+} -cleanup {
+ close $fin
+ close $fout
+} -result {1 71 71}
+test iogt-2.1 {basic I/O, operation trail} {testchannel unix} {
+ set fin [open $path(dummy) r]
+ set fout [open $path(dummyout) w]
+ set ain [list]; set aout [list]
+ audit_ops ain -attach $fin
+ audit_ops aout -attach $fout
+ fconfigure $fin -buffersize 10
+ fconfigure $fout -buffersize 10
+ fcopy $fin $fout
+ close $fin
+ close $fout
+ set res "[join $ain \n]\n--------\n[join $aout \n]"
+} {create/read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+flush/read
+delete/read
+--------
+create/write
+write
+write
+write
+write
+write
+write
+write
+write
+flush/write
+delete/write}
+test iogt-2.2 {basic I/O, data trail} {testchannel unix} {
+ set fin [open $path(dummy) r]
+ set fout [open $path(dummyout) w]
+ set ain [list]; set aout [list]
+ audit_flow ain -attach $fin
+ audit_flow aout -attach $fout
+ fconfigure $fin -buffersize 10
+ fconfigure $fout -buffersize 10
+ fcopy $fin $fout
+ close $fin
+ close $fout
+ set res "[join $ain \n]\n--------\n[join $aout \n]"
+} {create/read {} *ignored*
+query/maxRead {} -1
+read abcdefghij abcdefghij
+query/maxRead {} -1
+read klmnopqrst klmnopqrst
+query/maxRead {} -1
+read uvwxyz0123 uvwxyz0123
+query/maxRead {} -1
+read 456789,./? 456789,./?
+query/maxRead {} -1
+read {><;'\|":[]} {><;'\|":[]}
+query/maxRead {} -1
+read {\}\{`~!@#$} {\}\{`~!@#$}
+query/maxRead {} -1
+read %^&*()_+-= %^&*()_+-=
+query/maxRead {} -1
+read {
+} {
+}
+query/maxRead {} -1
+flush/read {} {}
+delete/read {} *ignored*
+--------
+create/write {} *ignored*
+write abcdefghij abcdefghij
+write klmnopqrst klmnopqrst
+write uvwxyz0123 uvwxyz0123
+write 456789,./? 456789,./?
+write {><;'\|":[]} {><;'\|":[]}
+write {\}\{`~!@#$} {\}\{`~!@#$}
+write %^&*()_+-= %^&*()_+-=
+write {
+} {
+}
+flush/write {} {}
+delete/write {} *ignored*}
+test iogt-2.3 {basic I/O, mixed trail} {testchannel unix} {
+ set fin [open $path(dummy) r]
+ set fout [open $path(dummyout) w]
+ set trail [list]
+ audit_flow trail -attach $fin
+ audit_flow trail -attach $fout
+ fconfigure $fin -buffersize 20
+ fconfigure $fout -buffersize 10
+ fcopy $fin $fout
+ close $fin
+ close $fout
+ join $trail \n
+} {create/read {} *ignored*
+create/write {} *ignored*
+query/maxRead {} -1
+read abcdefghijklmnopqrst abcdefghijklmnopqrst
+write abcdefghij abcdefghij
+write klmnopqrst klmnopqrst
+query/maxRead {} -1
+read uvwxyz0123456789,./? uvwxyz0123456789,./?
+write uvwxyz0123 uvwxyz0123
+write 456789,./? 456789,./?
+query/maxRead {} -1
+read {><;'\|":[]\}\{`~!@#$} {><;'\|":[]\}\{`~!@#$}
+write {><;'\|":[]} {><;'\|":[]}
+write {\}\{`~!@#$} {\}\{`~!@#$}
+query/maxRead {} -1
+read {%^&*()_+-=
+} {%^&*()_+-=
+}
+query/maxRead {} -1
+flush/read {} {}
+write %^&*()_+-= %^&*()_+-=
+write {
+} {
+}
+delete/read {} *ignored*
+flush/write {} {}
+delete/write {} *ignored*}
+
+test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} -setup {
+ proc DoneCopy {n {err {}}} {
+ variable copy 1
+ }
+} -constraints {testchannel hangs} -body {
+ # This test to check the validity of aquired Tcl_Channel references is not
+ # possible because even a backgrounded fcopy will immediately start to
+ # copy data, without waiting for the event loop. This is done only in case
+ # of an underflow on the read size!. So stacking transforms after the
+ # fcopy will miss information, or are not used at all.
+ #
+ # I was able to circumvent this by using the echo.tcl server with a big
+ # delay, causing the fcopy to underflow immediately.
+ set fin [open $path(dummy) r]
+ fevent 1000 500 {20 20 20 10 1 1} {
+ close $fin
+ set fout [open dummyout w]
+ flush $sock; # now, or fcopy will error us out
+ # But the 1 second delay should be enough to initialize everything
+ # else here.
+ fcopy $sock $fout -command [namespace code DoneCopy]
+ # Transform after fcopy got its handles! They should be still valid
+ # for fcopy.
+ set trail [list]
+ audit_ops trail -attach $fout
+ vwait [namespace which -variable copy]
+ } [read $fin]; # {}
+ close $fout
+ # Check result of copy.
+ set fin [open $path(dummy) r]
+ set fout [open $path(dummyout) r]
+ set res [string equal [read $fin] [read $fout]]
+ close $fin
+ close $fout
+ list $res $trail
+} -cleanup {
+ rename DoneCopy {}
+} -result {1 {create/write create/read write flush/write flush/read delete/write delete/read}}
+
+test iogt-4.0 {fileevent readable, after transform} -setup {
+ set fin [open $path(dummy) r]
+ set data [read $fin]
+ close $fin
+ set trail [list]
+ set got [list]
+ proc Done {args} {
+ variable stop 1
+ }
+} -constraints {testchannel hangs} -body {
+ fevent 1000 500 {20 20 20 10 1} {
+ audit_flow trail -attach $sock
+ rblocks_t rbuf trail 23 -attach $sock
+ fileevent $sock readable [namespace code {
+ if {[eof $sock]} {
+ Done
+ lappend trail "xxxxxxxxxxxxx"
+ close $sock
+ } else {
+ lappend trail "vvvvvvvvvvvvv"
+ lappend trail "\tgot: [lappend got "\[\[[read $sock]\]\]"]"
+ lappend trail "============="
+ #puts stdout $__; flush stdout
+ #read $sock
+ }
+ }]
+ flush $sock; # Now, or fcopy will error us out
+ # But the 1 second delay should be enough to initialize everything
+ # else here.
+ vwait [namespace which -variable stop]
+ } $data
+ join [list [join $got \n] ~~~~~~~~ [join $trail \n]] \n
+} -cleanup {
+ rename Done {}
+} -result {[[]]
+[[abcdefghijklmnopqrstuvw]]
+[[xyz0123456789,./?><;'\|]]
+[[]]
+[[]]
+[[":[]\}\{`~!@#$%^&*()]]
+[[]]
+~~~~~~~~
+create/write {} *ignored*
+create/read {} *ignored*
+rblock | create/write {} {} | {}
+rblock | create/read {} {} | {}
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | {}
+query/maxRead {} -1
+read abcdefghijklmnopqrstu abcdefghijklmnopqrstu
+query/maxRead {} -1
+rblock | {read 23 21 :- 0} abcdefghijklmnopqrstu {} | abcdefghijklmnopqrstu
+rblock | query/maxRead {} -1 | abcdefghijklmnopqrstu
+query/maxRead {} -1
+ got: {[[]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | abcdefghijklmnopqrstu
+query/maxRead {} -1
+read vwxyz0123456789,./?>< vwxyz0123456789,./?><
+query/maxRead {} -1
+rblock | {read 23 42 :- 23} vwxyz0123456789,./?>< abcdefghijklmnopqrstuvw | xyz0123456789,./?><
+rblock | query/maxRead {} -1 | xyz0123456789,./?><
+query/maxRead {} -1
+ got: {[[]]} {[[abcdefghijklmnopqrstuvw]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | xyz0123456789,./?><
+query/maxRead {} -1
+read {;'\|":[]\}\{`~!@#$%^&} {;'\|":[]\}\{`~!@#$%^&}
+query/maxRead {} -1
+rblock | {read 23 40 :- 23} {;'\|":[]\}\{`~!@#$%^&} {xyz0123456789,./?><;'\|} | {":[]\}\{`~!@#$%^&}
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&}
+query/maxRead {} -1
+ got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&}
+query/maxRead {} -1
+read *( *(
+query/maxRead {} -1
+rblock | {read 23 19 :- 0} *( {} | {":[]\}\{`~!@#$%^&*(}
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*(}
+query/maxRead {} -1
+ got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*(}
+query/maxRead {} -1
+read ) )
+query/maxRead {} -1
+rblock | {read 23 20 :- 0} ) {} | {":[]\}\{`~!@#$%^&*()}
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*()}
+query/maxRead {} -1
+ got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]} {[[]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*()}
+query/maxRead {} -1
+flush/read {} {}
+rblock | flush/read {} {":[]\}\{`~!@#$%^&*()} | {}
+rblock | query/maxRead {} -1 | {}
+query/maxRead {} -1
+ got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]} {[[]]} {[[":[]\}\{`~!@#$%^&*()]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | {}
+query/maxRead {} -1
+ got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]} {[[]]} {[[":[]\}\{`~!@#$%^&*()]]} {[[]]}
+xxxxxxxxxxxxx
+rblock | flush/write {} {} | {}
+rblock | delete/write {} {} | {}
+rblock | delete/read {} {} | {}
+flush/write {} {}
+delete/write {} *ignored*
+delete/read {} *ignored*}; # catch unescaped quote "
+
+test iogt-5.0 {EOF simulation} -setup {
+ set fin [open $path(dummy) r]
+ set fout [open $path(dummyout) w]
+ set trail [list]
+} -constraints {testchannel unknownFailure} -result {
+ audit_flow trail -attach $fin
+ stopafter_audit d trail 20 -attach $fin
+ audit_flow trail -attach $fout
+ fconfigure $fin -buffersize 20
+ fconfigure $fout -buffersize 10
+ fcopy $fin $fout
+ testchannel unstack $fin
+ # now copy the rest in the channel
+ lappend trail {**after unstack**}
+ fcopy $fin $fout
+ close $fin
+ close $fout
+ join $trail \n
+} -result {create/read {} *ignored*
+counter:create/read {} {}
+create/write {} *ignored*
+counter:query/maxRead {} 20
+query/maxRead {} -1
+read {abcdefghijklmnopqrstuvwxyz0123456789,./?><;'\|":[]\}\{`~!@#$%^&*()_+-=
+} {abcdefghijklmnopqrstuvwxyz0123456789,./?><;'\|":[]\}\{`~!@#$%^&*()_+-=
+}
+query/maxRead {} -1
+flush/read {} {}
+counter:read abcdefghijklmnopqrst abcdefghijklmnopqrst
+write abcdefghij abcdefghij
+write klmnopqrst klmnopqrst
+counter:query/maxRead {} 0
+counter:flush/read {} {}
+counter:delete/read {} {}
+**after unstack**
+query/maxRead {} -1
+write uvwxyz0123 uvwxyz0123
+write 456789,./? 456789,./?
+write {><;'\|":[]} {><;'\|":[]}
+write {\}\{`~!@#$} {\}\{`~!@#$}
+write %^&*()_+-= %^&*()_+-=
+write {
+} {
+}
+query/maxRead {} -1
+delete/read {} *ignored*
+flush/write {} {}
+delete/write {} *ignored*}
+
+proc constX {op data} {
+ # replace anything coming in with a same-length string of x'es.
+ switch -- $op {
+ create/write - create/read - delete/write - delete/read - clear_read {
+ #ignore
+ }
+ flush/write - flush/read - write - read {
+ return [string repeat x [string length $data]]
+ }
+ query/maxRead {
+ return -1
+ }
+ }
+}
+proc constx {-attach channel} {
+ testchannel transform $channel -command [namespace code constX]
+}
+
+test iogt-6.0 {Push back} -constraints testchannel -body {
+ set f [open $path(dummy) r]
+ # contents of dummy = "abcdefghi..."
+ read $f 3; # skip behind "abc"
+ constx -attach $f
+ # expect to get "xxx" from the transform because of unread "def" input to
+ # transform which returns "xxx".
+ #
+ # Actually the IO layer pre-read the whole file and will read "def"
+ # directly from the buffer without bothering to consult the newly stacked
+ # transformation. This is wrong.
+ read $f 3
+} -cleanup {
+ close $f
+} -result {xxx}
+test iogt-6.1 {Push back and up} -constraints {testchannel knownBug} -body {
+ set f [open $path(dummy) r]
+ # contents of dummy = "abcdefghi..."
+ read $f 3; # skip behind "abc"
+ constx -attach $f
+ set res [read $f 3]
+ testchannel unstack $f
+ append res [read $f 3]
+} -cleanup {
+ close $f
+} -result {xxxghi}
+
+# cleanup
+foreach file [list dummy dummyout __echo_srv__.tcl] {
+ removeFile $file
+}
+cleanupTests
+}
+namespace delete ::tcl::test::iogt
+return
diff --git a/library/msgcat/tests/join.test b/library/msgcat/tests/join.test
new file mode 100644
index 0000000..4abe233
--- /dev/null
+++ b/library/msgcat/tests/join.test
@@ -0,0 +1,55 @@
+# Commands covered: join
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test join-1.1 {basic join commands} {
+ join {a b c} xyz
+} axyzbxyzc
+test join-1.2 {basic join commands} {
+ join {a b c} {}
+} abc
+test join-1.3 {basic join commands} {
+ join {} xyz
+} {}
+test join-1.4 {basic join commands} {
+ join {12 34 56}
+} {12 34 56}
+
+test join-2.1 {join errors} {
+ list [catch join msg] $msg $errorCode
+} {1 {wrong # args: should be "join list ?joinString?"} {TCL WRONGARGS}}
+test join-2.2 {join errors} {
+ list [catch {join a b c} msg] $msg $errorCode
+} {1 {wrong # args: should be "join list ?joinString?"} {TCL WRONGARGS}}
+test join-2.3 {join errors} {
+ list [catch {join "a \{ c" 111} msg] $msg $errorCode
+} {1 {unmatched open brace in list} {TCL VALUE LIST BRACE}}
+
+test join-3.1 {joinString is binary ok} {
+ string length [join {a b c} a\0b]
+} 9
+test join-3.2 {join is binary ok} {
+ string length [join "a\0b a\0b a\0b"]
+} 11
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/lindex.test b/library/msgcat/tests/lindex.test
new file mode 100644
index 0000000..07abff8
--- /dev/null
+++ b/library/msgcat/tests/lindex.test
@@ -0,0 +1,455 @@
+# Commands covered: lindex
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2001 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2.2
+ namespace import -force ::tcltest::*
+}
+
+set minus -
+testConstraint testevalex [llength [info commands testevalex]]
+
+# Tests of Tcl_LindexObjCmd, NOT COMPILED
+
+test lindex-1.1 {wrong # args} testevalex {
+ list [catch {testevalex lindex} result] $result
+} "1 {wrong # args: should be \"lindex list ?index ...?\"}"
+
+# Indices that are lists or convertible to lists
+
+test lindex-2.1 {empty index list} testevalex {
+ set x {}
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {{a b c} {a b c}}
+test lindex-2.2 {singleton index list} testevalex {
+ set x { 1 }
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {b b}
+test lindex-2.3 {multiple indices in list} testevalex {
+ set x {1 2}
+ list [testevalex {lindex {{a b c} {d e f}} $x}] \
+ [testevalex {lindex {{a b c} {d e f}} $x}]
+} {f f}
+test lindex-2.4 {malformed index list} testevalex {
+ set x \{
+ list [catch { testevalex {lindex {a b c} $x} } result] $result
+} {1 bad\ index\ \"\{\":\ must\ be\ integer?\[+-\]integer?\ or\ end?\[+-\]integer?}
+
+# Indices that are integers or convertible to integers
+
+test lindex-3.1 {integer -1} testevalex {
+ set x ${minus}1
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {{} {}}
+test lindex-3.2 {integer 0} testevalex {
+ set x [string range 00 0 0]
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {a a}
+test lindex-3.3 {integer 2} testevalex {
+ set x [string range 22 0 0]
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {c c}
+test lindex-3.4 {integer 3} testevalex {
+ set x [string range 33 0 0]
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {{} {}}
+test lindex-3.5 {bad octal} -constraints testevalex -body {
+ set x 0o8
+ list [catch { testevalex {lindex {a b c} $x} } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-3.6 {bad octal} -constraints testevalex -body {
+ set x -0o9
+ list [catch { testevalex {lindex {a b c} $x} } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-3.7 {indexes don't shimmer wide ints} {
+ set x [expr {(wide(1)<<31) - 2}]
+ list $x [lindex {1 2 3} $x] [incr x] [incr x]
+} {2147483646 {} 2147483647 2147483648}
+
+# Indices relative to end
+
+test lindex-4.1 {index = end} testevalex {
+ set x end
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {c c}
+test lindex-4.2 {index = end--1} testevalex {
+ set x end--1
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {{} {}}
+test lindex-4.3 {index = end-0} testevalex {
+ set x end-0
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {c c}
+test lindex-4.4 {index = end-2} testevalex {
+ set x end-2
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {a a}
+test lindex-4.5 {index = end-3} testevalex {
+ set x end-3
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {{} {}}
+test lindex-4.6 {bad octal} -constraints testevalex -body {
+ set x end-0o8
+ list [catch { testevalex {lindex {a b c} $x} } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-4.7 {bad octal} -constraints testevalex -body {
+ set x end--0o9
+ list [catch { testevalex {lindex {a b c} $x} } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-4.8 {bad integer, not octal} testevalex {
+ set x end-0a2
+ list [catch { testevalex {lindex {a b c} $x} } result] $result
+} {1 {bad index "end-0a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lindex-4.9 {obsolete test} testevalex {
+ set x end
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {c c}
+test lindex-4.10 {incomplete end-} testevalex {
+ set x end-
+ list [catch { testevalex {lindex {a b c} $x} } result] $result
+} {1 {bad index "end-": must be integer?[+-]integer? or end?[+-]integer?}}
+
+test lindex-5.1 {bad second index} testevalex {
+ list [catch { testevalex {lindex {a b c} 0 0a2} } result] $result
+} {1 {bad index "0a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lindex-5.2 {good second index} testevalex {
+ testevalex {lindex {{a b c} {d e f} {g h i}} 1 2}
+} f
+test lindex-5.3 {three indices} testevalex {
+ testevalex {lindex {{{a b} {c d}} {{e f} {g h}}} 1 0 1}
+} f
+
+test lindex-6.1 {error conditions in parsing list} testevalex {
+ list [catch {testevalex {lindex "a \{" 2}} msg] $msg
+} {1 {unmatched open brace in list}}
+test lindex-6.2 {error conditions in parsing list} testevalex {
+ list [catch {testevalex {lindex {a {b c}d e} 2}} msg] $msg
+} {1 {list element in braces followed by "d" instead of space}}
+test lindex-6.3 {error conditions in parsing list} testevalex {
+ list [catch {testevalex {lindex {a "b c"def ghi} 2}} msg] $msg
+} {1 {list element in quotes followed by "def" instead of space}}
+
+test lindex-7.1 {quoted elements} testevalex {
+ testevalex {lindex {a "b c" d} 1}
+} {b c}
+test lindex-7.2 {quoted elements} testevalex {
+ testevalex {lindex {"{}" b c} 0}
+} {{}}
+test lindex-7.3 {quoted elements} testevalex {
+ testevalex {lindex {ab "c d \" x" y} 1}
+} {c d " x}
+test lindex-7.4 {quoted elements} {
+ lindex {a b {c d "e} {f g"}} 2
+} {c d "e}
+
+test lindex-8.1 {data reuse} testevalex {
+ set x 0
+ testevalex {lindex $x $x}
+} {0}
+test lindex-8.2 {data reuse} testevalex {
+ set a 0
+ testevalex {lindex $a $a $a}
+} 0
+test lindex-8.3 {data reuse} testevalex {
+ set a 1
+ testevalex {lindex $a $a $a}
+} {}
+test lindex-8.4 {data reuse} testevalex {
+ set x [list 0 0]
+ testevalex {lindex $x $x}
+} {0}
+test lindex-8.5 {data reuse} testevalex {
+ set x 0
+ testevalex {lindex $x [list $x $x]}
+} {0}
+test lindex-8.6 {data reuse} testevalex {
+ set x [list 1 1]
+ testevalex {lindex $x $x}
+} {}
+test lindex-8.7 {data reuse} testevalex {
+ set x 1
+ testevalex {lindex $x [list $x $x]}
+} {}
+
+#----------------------------------------------------------------------
+
+# Compilation tests for lindex
+
+test lindex-9.1 {wrong # args} {
+ list [catch {lindex} result] $result
+} "1 {wrong # args: should be \"lindex list ?index ...?\"}"
+test lindex-9.2 {ensure that compilation works in the right order} {
+ proc foo {} {
+ rename foo {}
+ lindex 1 0
+ }
+ foo
+} 1
+
+# Indices that are lists or convertible to lists
+
+test lindex-10.1 {empty index list} {
+ set x {}
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {{a b c} {a b c}}
+test lindex-10.2 {singleton index list} {
+ set x { 1 }
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {b b}
+test lindex-10.3 {multiple indices in list} {
+ set x {1 2}
+ catch {
+ list [lindex {{a b c} {d e f}} $x] [lindex {{a b c} {d e f}} $x]
+ } result
+ set result
+} {f f}
+test lindex-10.4 {malformed index list} {
+ set x \{
+ list [catch { lindex {a b c} $x } result] $result
+} {1 bad\ index\ \"\{\":\ must\ be\ integer?\[+-\]integer?\ or\ end?\[+-\]integer?}
+
+# Indices that are integers or convertible to integers
+
+test lindex-11.1 {integer -1} {
+ set x ${minus}1
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {{} {}}
+test lindex-11.2 {integer 0} {
+ set x [string range 00 0 0]
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {a a}
+test lindex-11.3 {integer 2} {
+ set x [string range 22 0 0]
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {c c}
+test lindex-11.4 {integer 3} {
+ set x [string range 33 0 0]
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {{} {}}
+test lindex-11.5 {bad octal} -body {
+ set x 0o8
+ list [catch { lindex {a b c} $x } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-11.6 {bad octal} -body {
+ set x -0o9
+ list [catch { lindex {a b c} $x } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+
+# Indices relative to end
+
+test lindex-12.1 {index = end} {
+ set x end
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {c c}
+test lindex-12.2 {index = end--1} {
+ set x end--1
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {{} {}}
+test lindex-12.3 {index = end-0} {
+ set x end-0
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {c c}
+test lindex-12.4 {index = end-2} {
+ set x end-2
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {a a}
+test lindex-12.5 {index = end-3} {
+ set x end-3
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {{} {}}
+test lindex-12.6 {bad octal} -body {
+ set x end-0o8
+ list [catch { lindex {a b c} $x } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-12.7 {bad octal} -body {
+ set x end--0o9
+ list [catch { lindex {a b c} $x } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-12.8 {bad integer, not octal} {
+ set x end-0a2
+ list [catch { lindex {a b c} $x } result] $result
+} {1 {bad index "end-0a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lindex-12.9 {obsolete test} {
+ set x end
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {c c}
+test lindex-12.10 {incomplete end-} {
+ set x end-
+ list [catch { lindex {a b c} $x } result] $result
+} {1 {bad index "end-": must be integer?[+-]integer? or end?[+-]integer?}}
+
+test lindex-13.1 {bad second index} {
+ list [catch { lindex {a b c} 0 0a2 } result] $result
+} {1 {bad index "0a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lindex-13.2 {good second index} {
+ catch {
+ lindex {{a b c} {d e f} {g h i}} 1 2
+ } result
+ set result
+} f
+test lindex-13.3 {three indices} {
+ catch {
+ lindex {{{a b} {c d}} {{e f} {g h}}} 1 0 1
+ } result
+ set result
+} f
+
+test lindex-14.1 {error conditions in parsing list} {
+ list [catch { lindex "a \{" 2 } msg] $msg
+} {1 {unmatched open brace in list}}
+test lindex-14.2 {error conditions in parsing list} {
+ list [catch { lindex {a {b c}d e} 2 } msg] $msg
+} {1 {list element in braces followed by "d" instead of space}}
+test lindex-14.3 {error conditions in parsing list} {
+ list [catch { lindex {a "b c"def ghi} 2 } msg] $msg
+} {1 {list element in quotes followed by "def" instead of space}}
+
+test lindex-15.1 {quoted elements} {
+ catch {
+ lindex {a "b c" d} 1
+ } result
+ set result
+} {b c}
+test lindex-15.2 {quoted elements} {
+ catch {
+ lindex {"{}" b c} 0
+ } result
+ set result
+} {{}}
+test lindex-15.3 {quoted elements} {
+ catch {
+ lindex {ab "c d \" x" y} 1
+ } result
+ set result
+} {c d " x}
+test lindex-15.4 {quoted elements} {
+ catch {
+ lindex {a b {c d "e} {f g"}} 2
+ } result
+ set result
+} {c d "e}
+
+test lindex-16.1 {data reuse} {
+ set x 0
+ catch {
+ lindex $x $x
+ } result
+ set result
+} {0}
+test lindex-16.2 {data reuse} {
+ set a 0
+ catch {
+ lindex $a $a $a
+ } result
+ set result
+} 0
+test lindex-16.3 {data reuse} {
+ set a 1
+ catch {
+ lindex $a $a $a
+ } result
+ set result
+} {}
+test lindex-16.4 {data reuse} {
+ set x [list 0 0]
+ catch {
+ lindex $x $x
+ } result
+ set result
+} {0}
+test lindex-16.5 {data reuse} {
+ set x 0
+ catch {
+ lindex $x [list $x $x]
+ } result
+ set result
+} {0}
+test lindex-16.6 {data reuse} {
+ set x [list 1 1]
+ catch {
+ lindex $x $x
+ } result
+ set result
+} {}
+test lindex-16.7 {data reuse} {
+ set x 1
+ catch {
+ lindex $x [list $x $x]
+ } result
+ set result
+} {}
+
+test lindex-17.0 {Bug 1718580} {*}{
+ -body {
+ lindex {} end foo
+ }
+ -match glob
+ -result {bad index "foo"*}
+ -returnCodes 1
+}
+
+test lindex-17.1 {Bug 1718580} {*}{
+ -body {
+ lindex a end foo
+ }
+ -match glob
+ -result {bad index "foo"*}
+ -returnCodes 1
+}
+
+catch { unset minus }
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/link.test b/library/msgcat/tests/link.test
new file mode 100644
index 0000000..60d0799
--- /dev/null
+++ b/library/msgcat/tests/link.test
@@ -0,0 +1,307 @@
+# Commands covered: none
+#
+# This file contains a collection of tests for Tcl_LinkVar and related library
+# procedures. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testlink [llength [info commands testlink]]
+
+foreach i {int real bool string} {
+ unset -nocomplain $i
+}
+
+test link-1.1 {reading C variables from Tcl} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink set 43 1.23 4 - 12341234 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ list $int $real $bool $string $wide
+} -result {43 1.23 1 NULL 12341234}
+test link-1.2 {reading C variables from Tcl} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ testlink set -3 2 0 "A long string with spaces" 43214321 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ list $int $real $bool $string $wide $int $real $bool $string $wide
+} -result {-3 2.0 0 {A long string with spaces} 43214321 -3 2.0 0 {A long string with spaces} 43214321}
+
+test link-2.1 {writing C variables from Tcl} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink set 43 1.21 4 - 56785678 64 250 30000 60000 0xbaadbeef 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ set int "0o0721"
+ set real -10.5
+ set bool true
+ set string abcdef
+ set wide 135135
+ set char 79
+ set uchar 161
+ set short 8000
+ set ushort 40000
+ set uint 0xc001babe
+ set long 34543
+ set ulong 567890
+ set float 1.0987654321
+ set uwide 357357357357
+ concat [testlink get] | $int $real $bool $string $wide $char $uchar $short $ushort $uint $long $ulong $float $uwide
+} -result {465 -10.5 1 abcdef 135135 79 161 8000 40000 -1073628482 34543 567890 1.0987653732299805 357357357357 | 0o0721 -10.5 true abcdef 135135 79 161 8000 40000 0xc001babe 34543 567890 1.0987654321 357357357357}
+test link-2.2 {writing bad values into variables} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ list [catch {set int 09a} msg] $msg $int
+} -result {1 {can't set "int": variable must have integer value} 43}
+test link-2.3 {writing bad values into variables} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ list [catch {set real 1.x3} msg] $msg $real
+} -result {1 {can't set "real": variable must have real value} 1.23}
+test link-2.4 {writing bad values into variables} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ list [catch {set bool gorp} msg] $msg $bool
+} -result {1 {can't set "bool": variable must have boolean value} 1}
+test link-2.5 {writing bad values into variables} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ list [catch {set wide gorp} msg] $msg $bool
+} -result {1 {can't set "wide": variable must have integer value} 1}
+
+test link-3.1 {read-only variables} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 0 1 1 0 0 0 0 0 0 0 0 0 0 0
+ list [catch {set int 4} msg] $msg $int \
+ [catch {set real 10.6} msg] $msg $real \
+ [catch {set bool no} msg] $msg $bool \
+ [catch {set string "new value"} msg] $msg $string \
+ [catch {set wide 12341234} msg] $msg $wide
+} -result {1 {can't set "int": linked variable is read-only} 43 0 10.6 10.6 0 no no 1 {can't set "string": linked variable is read-only} NULL 1 {can't set "wide": linked variable is read-only} 56785678}
+test link-3.2 {read-only variables} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 0 0 1 1 0 0 0 0 0 0 0 0 0
+ list [catch {set int 4} msg] $msg $int \
+ [catch {set real 10.6} msg] $msg $real \
+ [catch {set bool no} msg] $msg $bool \
+ [catch {set string "new value"} msg] $msg $string\
+ [catch {set wide 12341234} msg] $msg $wide
+} -result {0 4 4 1 {can't set "real": linked variable is read-only} 1.23 1 {can't set "bool": linked variable is read-only} 1 0 {new value} {new value} 0 12341234 12341234}
+
+test link-4.1 {unsetting linked variables} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink set -6 -2.5 0 stringValue 13579 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ unset int real bool string wide
+ list [catch {set int} msg] $msg [catch {set real} msg] $msg \
+ [catch {set bool} msg] $msg [catch {set string} msg] $msg \
+ [catch {set wide} msg] $msg
+} -result {0 -6 0 -2.5 0 0 0 stringValue 0 13579}
+test link-4.2 {unsetting linked variables} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink set -6 -2.1 0 stringValue 97531 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ unset int real bool string wide
+ set int 102
+ set real 16
+ set bool true
+ set string newValue
+ set wide 333555
+ lrange [testlink get] 0 4
+} -result {102 16.0 1 newValue 333555}
+
+test link-5.1 {unlinking variables} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink set -6 -2.25 0 stringValue 13579 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink delete
+ set int xx1
+ set real qrst
+ set bool bogus
+ set string 12345
+ set wide 875421
+ set char skjdf
+ set uchar dslfjk
+ set short slkf
+ set ushort skrh
+ set uint sfdkfkh
+ set long srkjh
+ set ulong sjkg
+ set float dskjfbjfd
+ set uwide isdfsngs
+ testlink get
+} -result {-6 -2.25 0 stringValue 13579 64 250 30000 60000 -1091585346 12321 32123 3.25 1231231234}
+test link-5.2 {unlinking variables} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink set -6 -2.25 0 stringValue 97531 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ testlink delete
+ testlink set 25 14.7 7 - 999999 65 251 30001 60001 0xbabebeef 12322 32124 3.125 12312312340
+ list $int $real $bool $string $wide $char $uchar $short $ushort $uint $long $ulong $float $uwide
+} -result {-6 -2.25 0 stringValue 97531 64 250 30000 60000 3203381950 12321 32123 3.25 1231231234}
+
+test link-6.1 {errors in setting up link} -setup {
+ testlink delete
+ unset -nocomplain int
+} -constraints {testlink} -body {
+ set int(44) 1
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+} -cleanup {
+ unset -nocomplain int
+} -returnCodes error -result {can't set "int": variable is array}
+
+test link-7.1 {access to linked variables via upvar} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ proc x {} {
+ upvar int y
+ unset y
+ }
+ testlink create 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ testlink set 14 {} {} {} {} {} {} {} {} {} {} {} {} {}
+ x
+ list [catch {set int} msg] $msg
+} -result {0 14}
+test link-7.2 {access to linked variables via upvar} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ proc x {} {
+ upvar int y
+ return [set y]
+ }
+ testlink create 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ testlink set 0 {} {} {} {} {} {} {} {} {} {} {} {} {}
+ set int
+ testlink set 23 {} {} {} {} {} {} {} {} {} {} {} {} {}
+ x
+ list [x] $int
+} -result {23 23}
+test link-7.3 {access to linked variables via upvar} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ proc x {} {
+ upvar int y
+ set y 44
+ }
+ testlink create 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ testlink set 11 {} {} {} {} {} {} {} {} {} {} {} {} {}
+ list [catch x msg] $msg $int
+} -result {1 {can't set "y": linked variable is read-only} 11}
+test link-7.4 {access to linked variables via upvar} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ proc x {} {
+ upvar int y
+ set y abc
+ }
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ testlink set -4 {} {} {} {} {} {} {} {} {} {} {} {} {}
+ list [catch x msg] $msg $int
+} -result {1 {can't set "y": variable must have integer value} -4}
+test link-7.5 {access to linked variables via upvar} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ proc x {} {
+ upvar real y
+ set y abc
+ }
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ testlink set -4 16.75 {} {} {} {} {} {} {} {} {} {} {} {}
+ list [catch x msg] $msg $real
+} -result {1 {can't set "y": variable must have real value} 16.75}
+test link-7.6 {access to linked variables via upvar} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ proc x {} {
+ upvar bool y
+ set y abc
+ }
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ testlink set -4 16.3 1 {} {} {} {} {} {} {} {} {} {} {}
+ list [catch x msg] $msg $bool
+} -result {1 {can't set "y": variable must have boolean value} 1}
+test link-7.7 {access to linked variables via upvar} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ proc x {} {
+ upvar wide y
+ set y abc
+ }
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ testlink set -4 16.3 1 {} 778899 {} {} {} {} {} {} {} {} {}
+ list [catch x msg] $msg $wide
+} -result {1 {can't set "y": variable must have integer value} 778899}
+
+test link-8.1 {Tcl_UpdateLinkedVar procedure} {testlink} {
+ proc x args {
+ global x int real bool string wide
+ lappend x $args $int $real $bool $string $wide
+ }
+ set x {}
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ testlink set 14 -2.0 0 xyzzy 995511 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ trace var int w x
+ testlink update 32 4.0 3 abcd 113355 65 251 30001 60001 0xbabebeef 12322 32124 3.125 12312312340
+ trace vdelete int w x
+ return $x
+} {{int {} w} 32 -2.0 0 xyzzy 995511}
+test link-8.2 {Tcl_UpdateLinkedVar procedure} {testlink} {
+ proc x args {
+ global x int real bool string wide
+ lappend x $args $int $real $bool $string $wide
+ }
+ set x {}
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ testlink set 14 -2.0 0 xyzzy 995511 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink delete
+ trace var int w x
+ testlink update 32 4.0 6 abcd 113355 65 251 30001 60001 0xbabebeef 12322 32124 3.125 12312312340
+ trace vdelete int w x
+ return $x
+} {}
+test link-8.3 {Tcl_UpdateLinkedVar procedure, read-only variable} {testlink} {
+ testlink create 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ list [catch {
+ testlink update 47 {} {} {} {} {} {} {} {} {} {} {} {} {}
+ } msg] $msg $int
+} {0 {} 47}
+
+catch {testlink set 0 0 0 - 0 0 0 0 0 0 0 0 0 0}
+catch {testlink delete}
+foreach i {int real bool string wide} {
+ unset -nocomplain $i
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/linsert.test b/library/msgcat/tests/linsert.test
new file mode 100644
index 0000000..4939e5c
--- /dev/null
+++ b/library/msgcat/tests/linsert.test
@@ -0,0 +1,119 @@
+# Commands covered: linsert
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+catch {unset lis}
+catch {rename p ""}
+
+test linsert-1.1 {linsert command} {
+ linsert {1 2 3 4 5} 0 a
+} {a 1 2 3 4 5}
+test linsert-1.2 {linsert command} {
+ linsert {1 2 3 4 5} 1 a
+} {1 a 2 3 4 5}
+test linsert-1.3 {linsert command} {
+ linsert {1 2 3 4 5} 2 a
+} {1 2 a 3 4 5}
+test linsert-1.4 {linsert command} {
+ linsert {1 2 3 4 5} 3 a
+} {1 2 3 a 4 5}
+test linsert-1.5 {linsert command} {
+ linsert {1 2 3 4 5} 4 a
+} {1 2 3 4 a 5}
+test linsert-1.6 {linsert command} {
+ linsert {1 2 3 4 5} 5 a
+} {1 2 3 4 5 a}
+test linsert-1.7 {linsert command} {
+ linsert {1 2 3 4 5} 2 one two \{three \$four
+} {1 2 one two \{three {$four} 3 4 5}
+test linsert-1.8 {linsert command} {
+ linsert {\{one \$two \{three \ four \ five} 2 a b c
+} {\{one {$two} a b c \{three { four} { five}}
+test linsert-1.9 {linsert command} {
+ linsert {{1 2} {3 4} {5 6} {7 8}} 2 {x y} {a b}
+} {{1 2} {3 4} {x y} {a b} {5 6} {7 8}}
+test linsert-1.10 {linsert command} {
+ linsert {} 2 a b c
+} {a b c}
+test linsert-1.11 {linsert command} {
+ linsert {} 2 {}
+} {{}}
+test linsert-1.12 {linsert command} {
+ linsert {a b "c c" d e} 3 1
+} {a b {c c} 1 d e}
+test linsert-1.13 {linsert command} {
+ linsert { a b c d} 0 1 2
+} {1 2 a b c d}
+test linsert-1.14 {linsert command} {
+ linsert {a b c {d e f}} 4 1 2
+} {a b c {d e f} 1 2}
+test linsert-1.15 {linsert command} {
+ linsert {a b c \{\ abc} 4 q r
+} {a b c \{\ q r abc}
+test linsert-1.16 {linsert command} {
+ linsert {a b c \{ abc} 4 q r
+} {a b c \{ q r abc}
+test linsert-1.17 {linsert command} {
+ linsert {a b c} end q r
+} {a b c q r}
+test linsert-1.18 {linsert command} {
+ linsert {a} end q r
+} {a q r}
+test linsert-1.19 {linsert command} {
+ linsert {} end q r
+} {q r}
+test linsert-1.20 {linsert command, use of end-int index} {
+ linsert {a b c d} end-2 e f
+} {a b e f c d}
+
+test linsert-2.1 {linsert errors} {
+ list [catch linsert msg] $msg
+} {1 {wrong # args: should be "linsert list index ?element ...?"}}
+test linsert-2.2 {linsert errors} {
+ list [catch {linsert a b} msg] $msg
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
+test linsert-2.3 {linsert errors} {
+ list [catch {linsert a 12x 2} msg] $msg
+} {1 {bad index "12x": must be integer?[+-]integer? or end?[+-]integer?}}
+test linsert-2.4 {linsert errors} {
+ list [catch {linsert \{ 12 2} msg] $msg
+} {1 {unmatched open brace in list}}
+test linsert-2.5 {syntax (TIP 323)} {
+ linsert {a b c} 0
+} [list a b c]
+test linsert-2.6 {syntax (TIP 323)} {
+ linsert "a\nb\nc" 0
+} [list a b c]
+
+test linsert-3.1 {linsert won't modify shared argument objects} {
+ proc p {} {
+ linsert "a b c" 1 "x y"
+ return "a b c"
+ }
+ p
+} "a b c"
+test linsert-3.2 {linsert won't modify shared argument objects} {
+ catch {unset lis}
+ set lis [format "a \"%s\" c" "b"]
+ linsert $lis 0 [string length $lis]
+} "7 a b c"
+
+# cleanup
+catch {unset lis}
+catch {rename p ""}
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/list.test b/library/msgcat/tests/list.test
new file mode 100644
index 0000000..dff5d50
--- /dev/null
+++ b/library/msgcat/tests/list.test
@@ -0,0 +1,134 @@
+# Commands covered: list
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# First, a bunch of individual tests
+
+test list-1.1 {basic tests} {list a b c} {a b c}
+test list-1.2 {basic tests} {list {a b} c} {{a b} c}
+test list-1.3 {basic tests} {list \{a b c} {\{a b c}
+test list-1.4 {basic tests} "list a{}} b{} c}" "a\\{\\}\\} b{} c\\}"
+test list-1.5 {basic tests} {list a\[ b\] } "{a\[} b\\]"
+test list-1.6 {basic tests} {list c\ d\t } "{c } {d\t}"
+test list-1.7 {basic tests} {list e\n f\$ } "{e\n} {f\$}"
+test list-1.8 {basic tests} {list g\; h\\} {{g;} h\\}
+test list-1.9 {basic tests} "list a\\\[} b\\\]} " "a\\\[\\\} b\\\]\\\}"
+test list-1.10 {basic tests} "list c\\\} d\\t} " "c\\} d\\t\\}"
+test list-1.11 {basic tests} "list e\\n} f\\$} " "e\\n\\} f\\$\\}"
+test list-1.12 {basic tests} "list g\\;} h\\\\} " "g\\;\\} {h\\}}"
+test list-1.13 {basic tests} {list a {{}} b} {a {{}} b}
+test list-1.14 {basic tests} {list a b xy\\} "a b xy\\\\"
+test list-1.15 {basic tests} "list a b\} e\\" "a b\\} e\\\\"
+test list-1.16 {basic tests} "list a b\}\\\$ e\\\$\\" "a b\\}\\\$ e\\\$\\\\"
+test list-1.17 {basic tests} {list a\f \{\f} "{a\f} \\\{\\f"
+test list-1.18 {basic tests} {list a\r \{\r} "{a\r} \\\{\\r"
+test list-1.19 {basic tests} {list a\v \{\v} "{a\v} \\\{\\v"
+test list-1.20 {basic tests} {list \"\}\{} "\\\"\\}\\{"
+test list-1.21 {basic tests} {list a b c\\\nd} "a b c\\\\\\nd"
+test list-1.22 {basic tests} {list "{ab}\\"} \\{ab\\}\\\\
+test list-1.23 {basic tests} {list \{} "\\{"
+test list-1.24 {basic tests} {list} {}
+test list-1.25 {basic tests} {list # #} {{#} #}
+test list-1.26 {basic tests} {list #\{ #\{} {\#\{ #\{}
+test list-1.27 {basic null treatment} {
+ set l [list "" "\0" "\0\0"]
+ set e "{} \0 \0\0"
+ string equal $l $e
+} 1
+test list-1.28 {basic null treatment} {
+ set result "\0a\0b"
+ list $result [string length $result]
+} "\0a\0b 4"
+test list-1.29 {basic null treatment} {
+ set result "\0a\0b"
+ set srep "$result 4"
+ set lrep [list $result [string length $result]]
+ string equal $srep $lrep
+} 1
+test list-1.30 {basic null treatment} {
+ set l [list "\0abc" "xyz"]
+ set e "\0abc xyz"
+ string equal $l $e
+} 1
+
+# For the next round of tests create a list and then pick it apart
+# with "index" to make sure that we get back exactly what went in.
+
+set num 0
+proc lcheck {testid a b c} {
+ global num d
+ set d [list $a $b $c]
+ test ${testid}-0 {what goes in must come out} {lindex $d 0} $a
+ test ${testid}-1 {what goes in must come out} {lindex $d 1} $b
+ test ${testid}-2 {what goes in must come out} {lindex $d 2} $c
+}
+lcheck list-2.1 a b c
+lcheck list-2.2 "a b" c\td e\nf
+lcheck list-2.3 {{a b}} {} { }
+lcheck list-2.4 \$ \$ab ab\$
+lcheck list-2.5 \; \;ab ab\;
+lcheck list-2.6 \[ \[ab ab\[
+lcheck list-2.7 \\ \\ab ab\\
+lcheck list-2.8 {"} {"ab} {ab"} ;#" Stupid emacs highlighting!
+lcheck list-2.9 {a b} { ab} {ab }
+lcheck list-2.10 a{ a{b \{ab
+lcheck list-2.11 a} a}b }ab
+lcheck list-2.12 a\\} {a \}b} {a \{c}
+lcheck list-2.13 xyz \\ 1\\\n2
+lcheck list-2.14 "{ab}\\" "{ab}xy" abc
+
+concat {}
+
+# Check that tclListObj.c's SetListFromAny handles possible overlarge
+# string rep lengths in the source object.
+
+proc slowsort list {
+ set result {}
+ set last [expr [llength $list] - 1]
+ while {$last > 0} {
+ set minIndex [expr [llength $list] - 1]
+ set min [lindex $list $last]
+ set i [expr $minIndex-1]
+ while {$i >= 0} {
+ if {[string compare [lindex $list $i] $min] < 0} {
+ set minIndex $i
+ set min [lindex $list $i]
+ }
+ set i [expr $i-1]
+ }
+ set result [concat $result [list $min]]
+ if {$minIndex == 0} {
+ set list [lrange $list 1 end]
+ } else {
+ set list [concat [lrange $list 0 [expr $minIndex-1]] \
+ [lrange $list [expr $minIndex+1] end]]
+ }
+ set last [expr $last-1]
+ }
+ return [concat $result $list]
+}
+test list-3.1 {SetListFromAny and lrange/concat results} {
+ slowsort {fred julie alex carol bill annie}
+} {alex annie bill carol fred julie}
+
+test list-4.1 {Bug 3173086} {
+ string is list "{[list \\\\\}]}"
+} 1
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/listObj.test b/library/msgcat/tests/listObj.test
new file mode 100644
index 0000000..53017b1
--- /dev/null
+++ b/library/msgcat/tests/listObj.test
@@ -0,0 +1,202 @@
+# Functionality covered: operation of the procedures in tclListObj.c that
+# implement the Tcl type manager for the list object type.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1995-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testobj [llength [info commands testobj]]
+
+catch {unset x}
+test listobj-1.1 {Tcl_GetListObjType} emptyTest {
+ # Test removed; tested an internal detail
+ # that's no longer correct, and duplicated test obj-1.1
+} {}
+
+test listobj-2.1 {Tcl_SetListObj, use in lappend} {
+ catch {unset x}
+ list [lappend x 1 abc def] [lappend x 1 ghi jkl] $x
+} {{1 abc def} {1 abc def 1 ghi jkl} {1 abc def 1 ghi jkl}}
+test listobj-2.2 {Tcl_SetListObj, use in ObjInterpProc} {
+ proc return_args {args} {
+ return $args
+ }
+ list [return_args] [return_args x] [return_args x y]
+} {{} x {x y}}
+test listobj-2.3 {Tcl_SetListObj, zero element count} {
+ list
+} {}
+
+test listobj-3.1 {Tcl_ListObjAppend, list conversion} {
+ catch {unset x}
+ list [lappend x 1 2 abc "long string"] $x
+} {{1 2 abc {long string}} {1 2 abc {long string}}}
+test listobj-3.2 {Tcl_ListObjAppend, list conversion} {
+ set x ""
+ list [lappend x first second] [lappend x third fourth] $x
+} {{first second} {first second third fourth} {first second third fourth}}
+test listobj-3.3 {Tcl_ListObjAppend, list conversion} {
+ set x "abc def"
+ list [lappend x first second] $x
+} {{abc def first second} {abc def first second}}
+test listobj-3.4 {Tcl_ListObjAppend, error in conversion} {
+ set x " \{"
+ list [catch {lappend x abc def} msg] $msg
+} {1 {unmatched open brace in list}}
+test listobj-3.5 {Tcl_ListObjAppend, force internal rep array to grow} {
+ set x ""
+ list [lappend x 1 1] [lappend x 2 2] [lappend x 3 3] [lappend x 4 4] \
+ [lappend x 5 5] [lappend x 6 6] [lappend x 7 7] [lappend x 8 8] $x
+} {{1 1} {1 1 2 2} {1 1 2 2 3 3} {1 1 2 2 3 3 4 4} {1 1 2 2 3 3 4 4 5 5} {1 1 2 2 3 3 4 4 5 5 6 6} {1 1 2 2 3 3 4 4 5 5 6 6 7 7} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8}}
+
+test listobj-4.1 {Tcl_ListObjAppendElement, list conversion} {
+ catch {unset x}
+ list [lappend x 1] $x
+} {1 1}
+test listobj-4.2 {Tcl_ListObjAppendElement, list conversion} {
+ set x ""
+ list [lappend x first] [lappend x second] $x
+} {first {first second} {first second}}
+test listobj-4.3 {Tcl_ListObjAppendElement, list conversion} {
+ set x "abc def"
+ list [lappend x first] $x
+} {{abc def first} {abc def first}}
+test listobj-4.4 {Tcl_ListObjAppendElement, error in conversion} {
+ set x " \{"
+ list [catch {lappend x abc} msg] $msg
+} {1 {unmatched open brace in list}}
+test listobj-4.5 {Tcl_ListObjAppendElement, force internal rep array to grow} {
+ set x ""
+ list [lappend x 1] [lappend x 2] [lappend x 3] [lappend x 4] \
+ [lappend x 5] [lappend x 6] [lappend x 7] [lappend x 8] $x
+} {1 {1 2} {1 2 3} {1 2 3 4} {1 2 3 4 5} {1 2 3 4 5 6} {1 2 3 4 5 6 7} {1 2 3 4 5 6 7 8} {1 2 3 4 5 6 7 8}}
+
+test listobj-5.1 {Tcl_ListObjIndex, basic tests} {
+ lindex {a b c} 0
+} a
+test listobj-5.2 {Tcl_ListObjIndex, basic tests} {
+ lindex a 0
+} a
+test listobj-5.3 {Tcl_ListObjIndex, basic tests} {
+ lindex {a {b c d} x} 1
+} {b c d}
+test listobj-5.4 {Tcl_ListObjIndex, basic tests} {
+ lindex {a b c} 3
+} {}
+test listobj-5.5 {Tcl_ListObjIndex, basic tests} {
+ lindex {a b c} 100
+} {}
+test listobj-5.6 {Tcl_ListObjIndex, basic tests} {
+ lindex a 100
+} {}
+test listobj-5.7 {Tcl_ListObjIndex, basic tests} {
+ lindex {} -1
+} {}
+test listobj-5.8 {Tcl_ListObjIndex, error in conversion} {
+ set x " \{"
+ list [catch {lindex $x 0} msg] $msg
+} {1 {unmatched open brace in list}}
+
+test listobj-6.1 {Tcl_ListObjLength} {
+ llength {a b c d}
+} 4
+test listobj-6.2 {Tcl_ListObjLength} {
+ llength {a b c {a b {c d}} d}
+} 5
+test listobj-6.3 {Tcl_ListObjLength} {
+ llength {}
+} 0
+test listobj-6.4 {Tcl_ListObjLength, convert from non-list} {
+ llength 123
+} 1
+test listobj-6.5 {Tcl_ListObjLength, error converting from non-list} {
+ list [catch {llength "a b c \{"} msg] $msg
+} {1 {unmatched open brace in list}}
+test listobj-6.6 {Tcl_ListObjLength, error converting from non-list} {
+ list [catch {llength "a {b}c"} msg] $msg
+} {1 {list element in braces followed by "c" instead of space}}
+
+test listobj-7.1 {Tcl_ListObjReplace, conversion from non-list} {
+ lreplace 123 0 0 x
+} {x}
+test listobj-7.2 {Tcl_ListObjReplace, error converting from non-list} {
+ list [catch {lreplace "a b c \{" 1 1 x} msg] $msg
+} {1 {unmatched open brace in list}}
+test listobj-7.3 {Tcl_ListObjReplace, error converting from non-list} {
+ list [catch {lreplace "a {b}c" 1 2 x} msg] $msg
+} {1 {list element in braces followed by "c" instead of space}}
+test listobj-7.4 {Tcl_ListObjReplace, negative first element index} {
+ lreplace {1 2 3 4 5} -1 1 a
+} {a 3 4 5}
+test listobj-7.5 {Tcl_ListObjReplace, last element index >= num elems} {
+ lreplace {1 2 3 4 5} 3 7 a b c
+} {1 2 3 a b c}
+test listobj-7.6 {Tcl_ListObjReplace, first element index > last index} {
+ lreplace {1 2 3 4 5} 3 1 a b c
+} {1 2 3 a b c 4 5}
+test listobj-7.7 {Tcl_ListObjReplace, no new elements} {
+ lreplace {1 2 3 4 5} 1 1
+} {1 3 4 5}
+test listobj-7.8 {Tcl_ListObjReplace, shrink array in place} {
+ lreplace {1 2 3 4 5 6 7} 4 5
+} {1 2 3 4 7}
+test listobj-7.9 {Tcl_ListObjReplace, grow array in place} {
+ lreplace {1 2 3 4 5 6 7} 1 3 a b c d e
+} {1 a b c d e 5 6 7}
+test listobj-7.10 {Tcl_ListObjReplace, replace tail of array} {
+ lreplace {1 2 3 4 5 6 7} 3 6 a
+} {1 2 3 a}
+test listobj-7.11 {Tcl_ListObjReplace, must grow internal array} {
+ lreplace {1 2 3 4 5} 2 3 a b c d e f g h i j k l
+} {1 2 a b c d e f g h i j k l 5}
+test listobj-7.12 {Tcl_ListObjReplace, grow array, insert at start} {
+ lreplace {1 2 3 4 5} -1 -1 a b c d e f g h i j k l
+} {a b c d e f g h i j k l 1 2 3 4 5}
+test listobj-7.13 {Tcl_ListObjReplace, grow array, insert at end} {
+ lreplace {1 2 3 4 5} 4 1 a b c d e f g h i j k l
+} {1 2 3 4 a b c d e f g h i j k l 5}
+
+test listobj-8.1 {SetListFromAny} {
+ lindex {0 foo\x00help 2} 1
+} "foo\x00help"
+
+test listobj-9.1 {UpdateStringOfList} {
+ string length [list foo\x00help]
+} 8
+
+test listobj-10.1 {Bug [2971669]} {*}{
+ -constraints testobj
+ -setup {
+ testobj freeallvars
+ }
+ -body {
+ set result {}
+ lappend result \
+ [testlistobj set 1 a b c d e] \
+ [testlistobj replace 1 0x7fffffff 0x7fffffff f] \
+ [testlistobj get 1]
+ }
+ -cleanup {
+ testobj freeallvars
+ }
+ -result {{a b c d e} {} {a b c d e f}}
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/llength.test b/library/msgcat/tests/llength.test
new file mode 100644
index 0000000..169c7ca
--- /dev/null
+++ b/library/msgcat/tests/llength.test
@@ -0,0 +1,41 @@
+# Commands covered: llength
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test llength-1.1 {length of list} {
+ llength {a b c d}
+} 4
+test llength-1.2 {length of list} {
+ llength {a b c {a b {c d}} d}
+} 5
+test llength-1.3 {length of list} {
+ llength {}
+} 0
+
+test llength-2.1 {error conditions} {
+ list [catch {llength} msg] $msg
+} {1 {wrong # args: should be "llength list"}}
+test llength-2.2 {error conditions} {
+ list [catch {llength 123 2} msg] $msg
+} {1 {wrong # args: should be "llength list"}}
+test llength-2.3 {error conditions} {
+ list [catch {llength "a b c \{"} msg] $msg
+} {1 {unmatched open brace in list}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/load.test b/library/msgcat/tests/load.test
new file mode 100644
index 0000000..b7c1a59
--- /dev/null
+++ b/library/msgcat/tests/load.test
@@ -0,0 +1,217 @@
+# Commands covered: load
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1995 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Figure out what extension is used for shared libraries on this
+# platform.
+if {![info exists ext]} {
+ set ext [info sharedlibextension]
+}
+# Tests require the existence of one of the DLLs in the dltest directory.
+set testDir [file join [file dirname [info nameofexecutable]] dltest]
+set x [file join $testDir pkga$ext]
+set dll "[file tail $x]Required"
+testConstraint $dll [file readable $x]
+
+# Tests also require that this DLL has not already been loaded.
+set loaded "[file tail $x]Loaded"
+set alreadyLoaded [info loaded]
+testConstraint $loaded [expr {![string match *pkga* $alreadyLoaded]}]
+
+set alreadyTotalLoaded [info loaded]
+
+# Certain tests require the 'teststaticpkg' command from tcltest
+
+testConstraint teststaticpkg [llength [info commands teststaticpkg]]
+
+# Test load-10.1 requires the 'testsimplefilesystem' command from tcltest
+
+testConstraint testsimplefilesystem \
+ [llength [info commands testsimplefilesystem]]
+
+test load-1.1 {basic errors} {} {
+ list [catch {load} msg] $msg
+} "1 {wrong \# args: should be \"load fileName ?packageName? ?interp?\"}"
+test load-1.2 {basic errors} {} {
+ list [catch {load a b c d} msg] $msg
+} "1 {wrong \# args: should be \"load fileName ?packageName? ?interp?\"}"
+test load-1.3 {basic errors} {} {
+ list [catch {load a b foobar} msg] $msg
+} {1 {could not find interpreter "foobar"}}
+test load-1.4 {basic errors} {} {
+ list [catch {load {}} msg] $msg
+} {1 {must specify either file name or package name}}
+test load-1.5 {basic errors} {} {
+ list [catch {load {} {}} msg] $msg
+} {1 {must specify either file name or package name}}
+test load-1.6 {basic errors} {} {
+ list [catch {load {} Unknown} msg] $msg
+} {1 {package "Unknown" isn't loaded statically}}
+
+test load-2.1 {basic loading, with guess for package name} \
+ [list $dll $loaded] {
+ load [file join $testDir pkga$ext]
+ list [pkga_eq abc def] [lsort [info commands pkga_*]]
+} {0 {pkga_eq pkga_quote}}
+interp create -safe child
+test load-2.2 {loading into a safe interpreter, with package name conversion} \
+ [list $dll $loaded] {
+ load [file join $testDir pkgb$ext] pKgB child
+ list [child eval pkgb_sub 44 13] [catch {child eval pkgb_unsafe} msg] $msg \
+ [catch {pkgb_sub 12 10} msg2] $msg2
+} {31 1 {invalid command name "pkgb_unsafe"} 1 {invalid command name "pkgb_sub"}}
+test load-2.3 {loading with no _Init procedure} -constraints [list $dll $loaded] \
+-body {
+ list [catch {load [file join $testDir pkgc$ext] foo} msg] $msg $errorCode
+} -match glob \
+ -result [list 1 {cannot find symbol "Foo_Init"*} \
+ {TCL LOOKUP LOAD_SYMBOL *Foo_Init}]
+test load-2.4 {loading with no _SafeInit procedure} [list $dll $loaded] {
+ list [catch {load [file join $testDir pkga$ext] {} child} msg] $msg
+} {1 {can't use package in a safe interpreter: no Pkga_SafeInit procedure}}
+
+test load-3.1 {error in _Init procedure, same interpreter} \
+ [list $dll $loaded] {
+ list [catch {load [file join $testDir pkge$ext] pkge} msg] \
+ $msg $::errorInfo $::errorCode
+} {1 {couldn't open "non_existent": no such file or directory} {couldn't open "non_existent": no such file or directory
+ while executing
+"open non_existent"
+ invoked from within
+"if 44 {open non_existent}"
+ invoked from within
+"load [file join $testDir pkge$ext] pkge"} {POSIX ENOENT {no such file or directory}}}
+test load-3.2 {error in _Init procedure, slave interpreter} \
+ [list $dll $loaded] {
+ catch {interp delete x}
+ interp create x
+ set ::errorCode foo
+ set ::errorInfo bar
+ set result [list [catch {load [file join $testDir pkge$ext] pkge x} msg] \
+ $msg $::errorInfo $::errorCode]
+ interp delete x
+ set result
+} {1 {couldn't open "non_existent": no such file or directory} {couldn't open "non_existent": no such file or directory
+ while executing
+"open non_existent"
+ invoked from within
+"if 44 {open non_existent}"
+ invoked from within
+"load [file join $testDir pkge$ext] pkge x"} {POSIX ENOENT {no such file or directory}}}
+
+test load-4.1 {reloading package into same interpreter} [list $dll $loaded] {
+ list [catch {load [file join $testDir pkga$ext] pkga} msg] $msg
+} {0 {}}
+test load-4.2 {reloading package into same interpreter} [list $dll $loaded] {
+ list [catch {load [file join $testDir pkga$ext] pkgb} msg] $msg
+} [list 1 "file \"[file join $testDir pkga$ext]\" is already loaded for package \"Pkga\""]
+
+test load-5.1 {file name not specified and no static package: pick default} \
+ [list $dll $loaded] {
+ catch {interp delete x}
+ interp create x
+ load [file join $testDir pkga$ext] pkga
+ load {} pkga x
+ set result [info loaded x]
+ interp delete x
+ set result
+} [list [list [file join $testDir pkga$ext] Pkga]]
+
+# On some platforms, like SunOS 4.1.3, these tests can't be run because
+# they cause the process to exit.
+#
+# As of 2005, such ancient broken systems no longer matter.
+
+test load-6.1 {errors loading file} [list $dll $loaded] {
+ catch {load foo foo}
+} {1}
+
+test load-7.1 {Tcl_StaticPackage procedure} [list teststaticpkg] {
+ set x "not loaded"
+ teststaticpkg Test 1 0
+ load {} Test
+ load {} Test child
+ list [set x] [child eval set x]
+} {loaded loaded}
+test load-7.2 {Tcl_StaticPackage procedure} [list teststaticpkg] {
+ set x "not loaded"
+ teststaticpkg Another 0 0
+ load {} Another
+ child eval {set x "not loaded"}
+ list [catch {load {} Another child} msg] $msg \
+ [child eval set x] [set x]
+} {1 {can't use package in a safe interpreter: no Another_SafeInit procedure} {not loaded} loaded}
+test load-7.3 {Tcl_StaticPackage procedure} [list teststaticpkg] {
+ set x "not loaded"
+ teststaticpkg More 0 1
+ load {} More
+ set x
+} {not loaded}
+test load-7.4 {Tcl_StaticPackage procedure, redundant calls} \
+ [list teststaticpkg $dll $loaded] {
+ teststaticpkg Double 0 1
+ teststaticpkg Double 0 1
+ info loaded
+ } [concat [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkge$ext] Pkge] [list [file join $testDir pkgb$ext] Pkgb] [list [file join $testDir pkga$ext] Pkga]] $alreadyTotalLoaded]
+
+test load-8.1 {TclGetLoadedPackages procedure} [list teststaticpkg $dll $loaded] {
+ info loaded
+} [concat [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkge$ext] Pkge] [list [file join $testDir pkgb$ext] Pkgb] [list [file join $testDir pkga$ext] Pkga]] $alreadyTotalLoaded]
+test load-8.2 {TclGetLoadedPackages procedure} [list teststaticpkg] {
+ list [catch {info loaded gorp} msg] $msg
+} {1 {could not find interpreter "gorp"}}
+test load-8.3 {TclGetLoadedPackages procedure} [list teststaticpkg $dll $loaded] {
+ list [info loaded {}] [info loaded child]
+} [list [concat [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga]] $alreadyLoaded] [list {{} Test} [list [file join $testDir pkgb$ext] Pkgb]]]
+test load-8.4 {TclGetLoadedPackages procedure} [list $dll $loaded teststaticpkg] {
+ load [file join $testDir pkgb$ext] pkgb
+ list [info loaded {}] [lsort [info commands pkgb_*]]
+} [list [concat [list [list [file join $testDir pkgb$ext] Pkgb] {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga]] $alreadyLoaded] {pkgb_sub pkgb_unsafe}]
+interp delete child
+
+test load-9.1 {Tcl_StaticPackage, load already-loaded package into another interp} \
+ -constraints {teststaticpkg} \
+ -setup {
+ interp create child1
+ interp create child2
+ load {} Tcltest child1
+ load {} Tcltest child2
+ } \
+ -body {
+ child1 eval { teststaticpkg Loadninepointone 0 1 }
+ child2 eval { teststaticpkg Loadninepointone 0 1 }
+ list \
+ [child1 eval { info loaded {} }] \
+ [child2 eval { info loaded {} }]
+ } \
+ -result {{{{} Loadninepointone} {{} Tcltest}} {{{} Loadninepointone} {{} Tcltest}}} \
+ -cleanup { interp delete child1 ; interp delete child2 }
+
+test load-10.1 {load from vfs} \
+ -constraints [list $dll $loaded testsimplefilesystem] \
+ -setup {set dir [pwd]; cd $testDir; testsimplefilesystem 1} \
+ -body {list [catch {load simplefs:/pkgd$ext pkgd} msg] $msg} \
+ -result {0 {}} \
+ -cleanup {testsimplefilesystem 0; cd $dir; unset dir}
+
+# cleanup
+unset ext
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/lrange.test b/library/msgcat/tests/lrange.test
new file mode 100644
index 0000000..6c81872
--- /dev/null
+++ b/library/msgcat/tests/lrange.test
@@ -0,0 +1,88 @@
+# Commands covered: lrange
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test lrange-1.1 {range of list elements} {
+ lrange {a b c d} 1 2
+} {b c}
+test lrange-1.2 {range of list elements} {
+ lrange {a {bcd e {f g {}}} l14 l15 d} 1 1
+} {{bcd e {f g {}}}}
+test lrange-1.3 {range of list elements} {
+ lrange {a {bcd e {f g {}}} l14 l15 d} 3 end
+} {l15 d}
+test lrange-1.4 {range of list elements} {
+ lrange {a {bcd e {f g {}}} l14 l15 d} 4 10000
+} {d}
+test lrange-1.5 {range of list elements} {
+ lrange {a {bcd e {f g {}}} l14 l15 d} 4 3
+} {}
+test lrange-1.6 {range of list elements} {
+ lrange {a {bcd e {f g {}}} l14 l15 d} 10 11
+} {}
+test lrange-1.7 {range of list elements} {
+ lrange {a b c d e} -1 2
+} {a b c}
+test lrange-1.8 {range of list elements} {
+ lrange {a b c d e} -2 -1
+} {}
+test lrange-1.9 {range of list elements} {
+ lrange {a b c d e} -2 end
+} {a b c d e}
+test lrange-1.10 {range of list elements} {
+ lrange "a b\{c d" 1 2
+} "b\\{c d"
+test lrange-1.11 {range of list elements} {
+ lrange "a b c d" end end
+} d
+test lrange-1.12 {range of list elements} {
+ lrange "a b c d" end 100000
+} d
+test lrange-1.13 {range of list elements} {
+ lrange "a b c d" end 3
+} d
+test lrange-1.14 {range of list elements} {
+ lrange "a b c d" end 2
+} {}
+test lrange-1.15 {range of list elements} {
+ concat \"[lrange {a b \{\ } 0 2]"
+} {"a b \{\ "}
+test lrange-1.16 {list element quoting} {
+ lrange {[append a .b]} 0 end
+} {{[append} a .b\]}
+test lrange-2.1 {error conditions} {
+ list [catch {lrange a b} msg] $msg
+} {1 {wrong # args: should be "lrange list first last"}}
+test lrange-2.2 {error conditions} {
+ list [catch {lrange a b 6 7} msg] $msg
+} {1 {wrong # args: should be "lrange list first last"}}
+test lrange-2.3 {error conditions} {
+ list [catch {lrange a b 6} msg] $msg
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
+test lrange-2.4 {error conditions} {
+ list [catch {lrange a 0 enigma} msg] $msg
+} {1 {bad index "enigma": must be integer?[+-]integer? or end?[+-]integer?}}
+test lrange-2.5 {error conditions} {
+ list [catch {lrange "a \{b c" 3 4} msg] $msg
+} {1 {unmatched open brace in list}}
+test lrange-2.6 {error conditions} {
+ list [catch {lrange "a b c \{ d e" 1 4} msg] $msg
+} {1 {unmatched open brace in list}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/lrepeat.test b/library/msgcat/tests/lrepeat.test
new file mode 100644
index 0000000..788bb9b
--- /dev/null
+++ b/library/msgcat/tests/lrepeat.test
@@ -0,0 +1,84 @@
+# Commands covered: lrepeat
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 2003 by Simon Geard.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+## Arg errors
+test lrepeat-1.1 {error cases} {
+ -body {
+ lrepeat
+ }
+ -returnCodes 1
+ -result {wrong # args: should be "lrepeat count ?value ...?"}
+}
+test lrepeat-1.2 {Accept zero elements(TIP 323)} {
+ -body {
+ lrepeat 1
+ }
+ -result {}
+}
+test lrepeat-1.3 {error cases} {
+ -body {
+ lrepeat a 1
+ }
+ -returnCodes 1
+ -result {expected integer but got "a"}
+}
+test lrepeat-1.4 {error cases} {
+ -body {
+ lrepeat -3 1
+ }
+ -returnCodes 1
+ -result {bad count "-3": must be integer >= 0}
+}
+test lrepeat-1.5 {Accept zero repetitions (TIP 323)} {
+ -body {
+ lrepeat 0
+ }
+ -result {}
+}
+test lrepeat-1.6 {error cases} {
+ -body {
+ lrepeat 3.5 1
+ }
+ -returnCodes 1
+ -result {expected integer but got "3.5"}
+}
+test lrepeat-1.7 {Accept zero repetitions (TIP 323)} {
+ -body {
+ lrepeat 0 a b c
+ }
+ -result {}
+}
+test lrepeat-1.8 {Do not build enormous lists - Bug 2130992} -body {
+ lrepeat 0x10000000 a b c d e f g h
+} -returnCodes error -match glob -result *
+
+## Okay
+test lrepeat-2.1 {normal cases} {
+ lrepeat 10 a
+} {a a a a a a a a a a}
+test lrepeat-2.2 {normal cases} {
+ lrepeat 3 [lrepeat 3 0]
+} {{0 0 0} {0 0 0} {0 0 0}}
+test lrepeat-2.3 {normal cases} {
+ lrepeat 3 a b c
+} {a b c a b c a b c}
+test lrepeat-2.4 {normal cases} {
+ lrepeat 3 [lrepeat 2 a] b c
+} {{a a} b c {a a} b c {a a} b c}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/lreplace.test b/library/msgcat/tests/lreplace.test
new file mode 100644
index 0000000..5f675bc
--- /dev/null
+++ b/library/msgcat/tests/lreplace.test
@@ -0,0 +1,136 @@
+# Commands covered: lreplace
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test lreplace-1.1 {lreplace command} {
+ lreplace {1 2 3 4 5} 0 0 a
+} {a 2 3 4 5}
+test lreplace-1.2 {lreplace command} {
+ lreplace {1 2 3 4 5} 1 1 a
+} {1 a 3 4 5}
+test lreplace-1.3 {lreplace command} {
+ lreplace {1 2 3 4 5} 2 2 a
+} {1 2 a 4 5}
+test lreplace-1.4 {lreplace command} {
+ lreplace {1 2 3 4 5} 3 3 a
+} {1 2 3 a 5}
+test lreplace-1.5 {lreplace command} {
+ lreplace {1 2 3 4 5} 4 4 a
+} {1 2 3 4 a}
+test lreplace-1.6 {lreplace command} {
+ lreplace {1 2 3 4 5} 4 5 a
+} {1 2 3 4 a}
+test lreplace-1.7 {lreplace command} {
+ lreplace {1 2 3 4 5} -1 -1 a
+} {a 1 2 3 4 5}
+test lreplace-1.8 {lreplace command} {
+ lreplace {1 2 3 4 5} 2 end a b c d
+} {1 2 a b c d}
+test lreplace-1.9 {lreplace command} {
+ lreplace {1 2 3 4 5} 0 3
+} {5}
+test lreplace-1.10 {lreplace command} {
+ lreplace {1 2 3 4 5} 0 4
+} {}
+test lreplace-1.11 {lreplace command} {
+ lreplace {1 2 3 4 5} 0 1
+} {3 4 5}
+test lreplace-1.12 {lreplace command} {
+ lreplace {1 2 3 4 5} 2 3
+} {1 2 5}
+test lreplace-1.13 {lreplace command} {
+ lreplace {1 2 3 4 5} 3 end
+} {1 2 3}
+test lreplace-1.14 {lreplace command} {
+ lreplace {1 2 3 4 5} -1 4 a b c
+} {a b c}
+test lreplace-1.15 {lreplace command} {
+ lreplace {a b "c c" d e f} 3 3
+} {a b {c c} e f}
+test lreplace-1.16 {lreplace command} {
+ lreplace { 1 2 3 4 5} 0 0 a
+} {a 2 3 4 5}
+test lreplace-1.17 {lreplace command} {
+ lreplace {1 2 3 4 "5 6"} 4 4 a
+} {1 2 3 4 a}
+test lreplace-1.18 {lreplace command} {
+ lreplace {1 2 3 4 {5 6}} 4 4 a
+} {1 2 3 4 a}
+test lreplace-1.19 {lreplace command} {
+ lreplace {1 2 3 4} 2 end x y z
+} {1 2 x y z}
+test lreplace-1.20 {lreplace command} {
+ lreplace {1 2 3 4} end end a
+} {1 2 3 a}
+test lreplace-1.21 {lreplace command} {
+ lreplace {1 2 3 4} end 3 a
+} {1 2 3 a}
+test lreplace-1.22 {lreplace command} {
+ lreplace {1 2 3 4} end end
+} {1 2 3}
+test lreplace-1.23 {lreplace command} {
+ lreplace {1 2 3 4} 2 -1 xy
+} {1 2 xy 3 4}
+test lreplace-1.24 {lreplace command} {
+ lreplace {1 2 3 4} end -1 z
+} {1 2 3 z 4}
+test lreplace-1.25 {lreplace command} {
+ concat \"[lreplace {\}\ hello} end end]\"
+} {"\}\ "}
+test lreplace-1.26 {lreplace command} {
+ catch {unset foo}
+ set foo {a b}
+ list [set foo [lreplace $foo end end]] \
+ [set foo [lreplace $foo end end]] \
+ [set foo [lreplace $foo end end]]
+} {a {} {}}
+
+
+test lreplace-2.1 {lreplace errors} {
+ list [catch lreplace msg] $msg
+} {1 {wrong # args: should be "lreplace list first last ?element ...?"}}
+test lreplace-2.2 {lreplace errors} {
+ list [catch {lreplace a b} msg] $msg
+} {1 {wrong # args: should be "lreplace list first last ?element ...?"}}
+test lreplace-2.3 {lreplace errors} {
+ list [catch {lreplace x a 10} msg] $msg
+} {1 {bad index "a": must be integer?[+-]integer? or end?[+-]integer?}}
+test lreplace-2.4 {lreplace errors} {
+ list [catch {lreplace x 10 x} msg] $msg
+} {1 {bad index "x": must be integer?[+-]integer? or end?[+-]integer?}}
+test lreplace-2.5 {lreplace errors} {
+ list [catch {lreplace x 10 1x} msg] $msg
+} {1 {bad index "1x": must be integer?[+-]integer? or end?[+-]integer?}}
+test lreplace-2.6 {lreplace errors} {
+ list [catch {lreplace x 3 2} msg] $msg
+} {1 {list doesn't contain element 3}}
+test lreplace-2.7 {lreplace errors} {
+ list [catch {lreplace x 1 1} msg] $msg
+} {1 {list doesn't contain element 1}}
+
+test lreplace-3.1 {lreplace won't modify shared argument objects} {
+ proc p {} {
+ lreplace "a b c" 1 1 "x y"
+ return "a b c"
+ }
+ p
+} "a b c"
+
+# cleanup
+catch {unset foo}
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/lsearch.test b/library/msgcat/tests/lsearch.test
new file mode 100644
index 0000000..f36e987
--- /dev/null
+++ b/library/msgcat/tests/lsearch.test
@@ -0,0 +1,528 @@
+# Commands covered: lsearch
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+set x {abcd bbcd 123 234 345}
+test lsearch-1.1 {lsearch command} {
+ lsearch $x 123
+} 2
+test lsearch-1.2 {lsearch command} {
+ lsearch $x 3456
+} -1
+test lsearch-1.3 {lsearch command} {
+ lsearch $x *5
+} 4
+test lsearch-1.4 {lsearch command} {
+ lsearch $x *bc*
+} 0
+
+test lsearch-2.1 {search modes} {
+ lsearch -exact {xyz bbcc *bc*} *bc*
+} 2
+test lsearch-2.2 {search modes} {
+ lsearch -exact {b.x ^bc xy bcx} ^bc
+} 1
+test lsearch-2.3 {search modes} {
+ lsearch -exact {foo bar cat} ba
+} -1
+test lsearch-2.4 {search modes} {
+ lsearch -exact {foo bar cat} bart
+} -1
+test lsearch-2.5 {search modes} {
+ lsearch -exact {foo bar cat} bar
+} 1
+test lsearch-2.6 {search modes} -returnCodes error -body {
+ lsearch -regexp {xyz bbcc *bc*} *bc*
+} -result {couldn't compile regular expression pattern: quantifier operand invalid}
+test lsearch-2.7 {search modes} {
+ lsearch -regexp {b.x ^bc xy bcx} ^bc
+} 3
+test lsearch-2.8 {search modes} {
+ lsearch -glob {xyz bbcc *bc*} *bc*
+} 1
+test lsearch-2.9 {search modes} {
+ lsearch -glob {b.x ^bc xy bcx} ^bc
+} 1
+test lsearch-2.10 {search modes} -returnCodes error -body {
+ lsearch -glib {b.x bx xy bcx} b.x
+} -result {bad option "-glib": must be -all, -ascii, -bisect, -decreasing, -dictionary, -exact, -glob, -increasing, -index, -inline, -integer, -nocase, -not, -real, -regexp, -sorted, -start, or -subindices}
+test lsearch-2.11 {search modes with -nocase} {
+ lsearch -exact -nocase {a b c A B C} A
+} 0
+test lsearch-2.12 {search modes with -nocase} {
+ lsearch -glob -nocase {a b c A B C} A*
+} 0
+test lsearch-2.13 {search modes with -nocase} {
+ lsearch -regexp -nocase {a b c A B C} ^A\$
+} 0
+test lsearch-2.14 {search modes without -nocase} {
+ lsearch -exact {a b c A B C} A
+} 3
+test lsearch-2.15 {search modes without -nocase} {
+ lsearch -glob {a b c A B C} A*
+} 3
+test lsearch-2.16 {search modes without -nocase} {
+ lsearch -regexp {a b c A B C} ^A\$
+} 3
+
+test lsearch-3.1 {lsearch errors} -returnCodes error -body {
+ lsearch
+} -result {wrong # args: should be "lsearch ?-option value ...? list pattern"}
+test lsearch-3.2 {lsearch errors} -returnCodes error -body {
+ lsearch a
+} -result {wrong # args: should be "lsearch ?-option value ...? list pattern"}
+test lsearch-3.3 {lsearch errors} -returnCodes error -body {
+ lsearch a b c
+} -result {bad option "a": must be -all, -ascii, -bisect, -decreasing, -dictionary, -exact, -glob, -increasing, -index, -inline, -integer, -nocase, -not, -real, -regexp, -sorted, -start, or -subindices}
+test lsearch-3.4 {lsearch errors} -returnCodes error -body {
+ lsearch a b c d
+} -result {bad option "a": must be -all, -ascii, -bisect, -decreasing, -dictionary, -exact, -glob, -increasing, -index, -inline, -integer, -nocase, -not, -real, -regexp, -sorted, -start, or -subindices}
+test lsearch-3.5 {lsearch errors} -returnCodes error -body {
+ lsearch "\{" b
+} -result {unmatched open brace in list}
+test lsearch-3.6 {lsearch errors} -returnCodes error -body {
+ lsearch -index a b
+} -result {"-index" option must be followed by list index}
+test lsearch-3.7 {lsearch errors} -returnCodes error -body {
+ lsearch -subindices -exact a b
+} -result {-subindices cannot be used without -index option}
+
+test lsearch-4.1 {binary data} {
+ lsearch -exact [list foo one\000two bar] bar
+} 2
+test lsearch-4.2 {binary data} {
+ set x one
+ append x \x00
+ append x two
+ lsearch -exact [list foo one\000two bar] $x
+} 1
+
+# Make a sorted list
+set l {}
+set l2 {}
+for {set i 0} {$i < 100} {incr i} {
+ lappend l $i
+ lappend l2 [expr {double($i)/2}]
+}
+set increasingIntegers [lsort -integer $l]
+set decreasingIntegers [lsort -decreasing -integer $l]
+set increasingDoubles [lsort -real $l2]
+set decreasingDoubles [lsort -decreasing -real $l2]
+set increasingStrings [lsort {48 6a 18b 22a 21aa 35 36}]
+set decreasingStrings [lsort -decreasing {48 6a 18b 22a 21aa 35 36}]
+set increasingDictionary [lsort -dictionary {48 6a 18b 22a 21aa 35 36}]
+set decreasingDictionary [lsort -dictionary -decreasing $increasingDictionary]
+
+set l {}
+for {set i 0} {$i < 10} {incr i} {
+ lappend l $i $i $i $i $i
+}
+set repeatingIncreasingIntegers [lsort -integer $l]
+set repeatingDecreasingIntegers [lsort -integer -decreasing $l]
+
+test lsearch-5.1 {binary search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -integer -sorted $increasingIntegers $i]
+ }
+ set res
+} $increasingIntegers
+test lsearch-5.2 {binary search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -integer -decreasing -sorted \
+ $decreasingIntegers $i]
+ }
+ set res
+} $decreasingIntegers
+test lsearch-5.3 {binary search finds leftmost occurances} {
+ set res {}
+ for {set i 0} {$i < 10} {incr i} {
+ lappend res [lsearch -integer -sorted $repeatingIncreasingIntegers $i]
+ }
+ set res
+} [list 0 5 10 15 20 25 30 35 40 45]
+test lsearch-5.4 {binary search -decreasing finds leftmost occurances} {
+ set res {}
+ for {set i 9} {$i >= 0} {incr i -1} {
+ lappend res [lsearch -sorted -integer -decreasing \
+ $repeatingDecreasingIntegers $i]
+ }
+ set res
+} [list 0 5 10 15 20 25 30 35 40 45]
+
+test lsearch-6.1 {integer search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -exact -integer $increasingIntegers $i]
+ }
+ set res
+} [lrange $increasingIntegers 0 99]
+test lsearch-6.2 {decreasing integer search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -exact -integer -decreasing \
+ $decreasingIntegers $i]
+ }
+ set res
+} [lrange $decreasingIntegers 0 99]
+test lsearch-6.3 {sorted integer search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -sorted -integer $increasingIntegers $i]
+ }
+ set res
+} [lrange $increasingIntegers 0 99]
+test lsearch-6.4 {sorted decreasing integer search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -integer -sorted -decreasing \
+ $decreasingIntegers $i]
+ }
+ set res
+} [lrange $decreasingIntegers 0 99]
+
+test lsearch-7.1 {double search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -exact -real $increasingDoubles \
+ [expr {double($i)/2}]]
+ }
+ set res
+} [lrange $increasingIntegers 0 99]
+test lsearch-7.2 {decreasing double search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -exact -real -decreasing \
+ $decreasingDoubles [expr {double($i)/2}]]
+ }
+ set res
+} [lrange $decreasingIntegers 0 99]
+test lsearch-7.3 {sorted double search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -sorted -real \
+ $increasingDoubles [expr {double($i)/2}]]
+ }
+ set res
+} [lrange $increasingIntegers 0 99]
+test lsearch-7.4 {sorted decreasing double search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -sorted -real -decreasing \
+ $decreasingDoubles [expr {double($i)/2}]]
+ }
+ set res
+} [lrange $decreasingIntegers 0 99]
+
+test lsearch-8.1 {dictionary search} {
+ set res {}
+ foreach val {6a 18b 21aa 22a 35 36 48} {
+ lappend res [lsearch -exact -dictionary $increasingDictionary $val]
+ }
+ set res
+} [list 0 1 2 3 4 5 6]
+test lsearch-8.2 {decreasing dictionary search} {
+ set res {}
+ foreach val {6a 18b 21aa 22a 35 36 48} {
+ lappend res [lsearch -exact -dictionary $decreasingDictionary $val]
+ }
+ set res
+} [list 6 5 4 3 2 1 0]
+test lsearch-8.3 {sorted dictionary search} {
+ set res {}
+ foreach val {6a 18b 21aa 22a 35 36 48} {
+ lappend res [lsearch -sorted -dictionary $increasingDictionary $val]
+ }
+ set res
+} [list 0 1 2 3 4 5 6]
+test lsearch-8.4 {decreasing sorted dictionary search} {
+ set res {}
+ foreach val {6a 18b 21aa 22a 35 36 48} {
+ lappend res [lsearch -decreasing -sorted -dictionary \
+ $decreasingDictionary $val]
+ }
+ set res
+} [list 6 5 4 3 2 1 0]
+
+test lsearch-9.1 {ascii search} {
+ set res {}
+ foreach val {18b 21aa 22a 35 36 48 6a} {
+ lappend res [lsearch -exact -ascii $increasingStrings $val]
+ }
+ set res
+} [list 0 1 2 3 4 5 6]
+test lsearch-9.2 {decreasing ascii search} {
+ set res {}
+ foreach val {18b 21aa 22a 35 36 48 6a} {
+ lappend res [lsearch -exact -ascii $decreasingStrings $val]
+ }
+ set res
+} [list 6 5 4 3 2 1 0]
+test lsearch-9.3 {sorted ascii search} {
+ set res {}
+ foreach val {18b 21aa 22a 35 36 48 6a} {
+ lappend res [lsearch -sorted -ascii $increasingStrings $val]
+ }
+ set res
+} [list 0 1 2 3 4 5 6]
+test lsearch-9.4 {decreasing sorted ascii search} {
+ set res {}
+ foreach val {18b 21aa 22a 35 36 48 6a} {
+ lappend res [lsearch -decreasing -sorted -ascii \
+ $decreasingStrings $val]
+ }
+ set res
+} [list 6 5 4 3 2 1 0]
+
+test lsearch-10.1 {offset searching} {
+ lsearch -start 2 {a b c a b c} a
+} 3
+test lsearch-10.2 {offset searching} {
+ lsearch -start 2 {a b c d e f} a
+} -1
+test lsearch-10.3 {offset searching} {
+ lsearch -start end-4 {a b c a b c} a
+} 3
+test lsearch-10.4 {offset searching} -returnCodes error -body {
+ lsearch -start foobar {a b c a b c} a
+} -result {bad index "foobar": must be integer?[+-]integer? or end?[+-]integer?}
+test lsearch-10.5 {offset searching} -returnCodes error -body {
+ lsearch -start 1 2
+} -result {missing starting index}
+test lsearch-10.6 {binary search with offset} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -integer -start 2 -sorted $increasingIntegers $i]
+ }
+ set res
+} [concat -1 -1 [lrange $increasingIntegers 2 end]]
+test lsearch-10.7 {offset searching with an empty list} {
+ # Stop bug #694232 from reocurring
+ lsearch -start 0 {} x
+} -1
+test lsearch-10.8 {offset searching past the end of the list} {
+ # Stop [Bug 1374778] from reoccurring
+ lsearch -start 10 {a b c} c
+} -1
+test lsearch-10.9 {offset searching past the end of the list} {
+ # Stop [Bug 1374778] from reoccurring
+ lsearch -start 10 -all {a b c} c
+} {}
+test lsearch-10.10 {offset searching past the end of the list} {
+ # Stop [Bug 1374778] from reoccurring
+ lsearch -start 10 -inline {a b c} c
+} {}
+
+test lsearch-11.1 {negated searches} {
+ lsearch -not {a a a b a a a} a
+} 3
+test lsearch-11.2 {negated searches} {
+ lsearch -not {a a a a a a a} a
+} -1
+
+test lsearch-12.1 {return values instead of indices} {
+ lsearch -glob -inline {a1 b2 c3 d4} c*
+} c3
+test lsearch-12.2 {return values instead of indices} {
+ lsearch -glob -inline {a1 b2 c3 d4} e*
+} {}
+
+test lsearch-13.1 {search for all matches} {
+ lsearch -all {a b a c a d} 1
+} {}
+test lsearch-13.2 {search for all matches} {
+ lsearch -all {a b a c a d} a
+} {0 2 4}
+test lsearch-13.3 {search for all matches with -nocase} {
+ lsearch -all -exact -nocase {a b c A B C} A
+} {0 3}
+test lsearch-13.4 {search for all matches with -nocase} {
+ lsearch -all -glob -nocase {a b c A B C} A*
+} {0 3}
+test lsearch-13.5 {search for all matches with -nocase} {
+ lsearch -all -regexp -nocase {a b c A B C} ^A\$
+} {0 3}
+
+test lsearch-14.1 {combinations: -all and -inline} {
+ lsearch -all -inline -glob {a1 b2 a3 c4 a5 d6} a*
+} {a1 a3 a5}
+test lsearch-14.2 {combinations: -all, -inline and -not} {
+ lsearch -all -inline -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {b2 c4 d6}
+test lsearch-14.3 {combinations: -all and -not} {
+ lsearch -all -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {1 3 5}
+test lsearch-14.4 {combinations: -inline and -not} {
+ lsearch -inline -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {b2}
+test lsearch-14.5 {combinations: -start, -all and -inline} {
+ lsearch -start 2 -all -inline -glob {a1 b2 a3 c4 a5 d6} a*
+} {a3 a5}
+test lsearch-14.6 {combinations: -start, -all, -inline and -not} {
+ lsearch -start 2 -all -inline -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {c4 d6}
+test lsearch-14.7 {combinations: -start, -all and -not} {
+ lsearch -start 2 -all -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {3 5}
+test lsearch-14.8 {combinations: -start, -inline and -not} {
+ lsearch -start 2 -inline -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {c4}
+
+test lsearch-15.1 {make sure no shimmering occurs} {
+ set x [expr int(sin(0))]
+ lsearch -start $x $x $x
+} 0
+
+test lsearch-16.1 {lsearch -regexp shared object} {
+ set str a
+ lsearch -regexp $str $str
+} 0
+# Bug 1366683
+test lsearch-16.2 {lsearch -regexp allows internal backrefs} {
+ lsearch -regexp {a aa b} {(.)\1}
+} 1
+
+test lsearch-17.1 {lsearch -index option, basic functionality} {
+ lsearch -index 1 {{a c} {a b} {a a}} a
+} 2
+test lsearch-17.2 {lsearch -index option, basic functionality} {
+ lsearch -index 1 -exact {{a c} {a b} {a a}} a
+} 2
+test lsearch-17.3 {lsearch -index option, basic functionality} {
+ lsearch -index 1 -glob {{ab cb} {ab bb} {ab ab}} b*
+} 1
+test lsearch-17.4 {lsearch -index option, basic functionality} {
+ lsearch -index 1 -regexp {{ab cb} {ab bb} {ab ab}} {[cb]b}
+} 0
+test lsearch-17.5 {lsearch -index option, basic functionality} {
+ lsearch -all -index 0 -exact {{a c} {a b} {d a}} a
+} {0 1}
+test lsearch-17.6 {lsearch -index option, basic functionality} {
+ lsearch -all -index 1 -glob {{ab cb} {ab bb} {db bx}} b*
+} {1 2}
+test lsearch-17.7 {lsearch -index option, basic functionality} {
+ lsearch -all -index 1 -regexp {{ab cb} {ab bb} {ab ab}} {[cb]b}
+} {0 1}
+
+test lsearch-18.1 {lsearch -index option, list as index basic functionality} {
+ lsearch -index {0 0} {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a
+} 1
+test lsearch-18.2 {lsearch -index option, list as index basic functionality} {
+ lsearch -index {2 0} -exact {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a
+} 0
+test lsearch-18.3 {lsearch -index option, list as index basic functionality} {
+ lsearch -index {1 1} -glob {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} b*
+} 0
+test lsearch-18.4 {lsearch -index option, list as index basic functionality} {
+ lsearch -index {0 1} -regexp {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} {[cb]b}
+} 0
+test lsearch-18.5 {lsearch -index option, list as index basic functionality} {
+ lsearch -all -index {0 0} -exact {{{a c} {a b} {d a}} {{a c} {a b} {d a}}} a
+} {0 1}
+
+test lsearch-19.1 {lsearch -sunindices option} {
+ lsearch -subindices -index {0 0} {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a
+} {1 0 0}
+test lsearch-19.2 {lsearch -sunindices option} {
+ lsearch -subindices -index {2 0} -exact {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a
+} {0 2 0}
+test lsearch-19.3 {lsearch -sunindices option} {
+ lsearch -subindices -index {1 1} -glob {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} b*
+} {0 1 1}
+test lsearch-19.4 {lsearch -sunindices option} {
+ lsearch -subindices -index {0 1} -regexp {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} {[cb]b}
+} {0 0 1}
+test lsearch-19.5 {lsearch -sunindices option} {
+ lsearch -subindices -all -index {0 0} -exact {{{a c} {a b} {d a}} {{a c} {a b} {d a}}} a
+} {{0 0 0} {1 0 0}}
+
+test lsearch-20.1 {lsearch -index option, index larger than sublists} -body {
+ lsearch -index 2 {{a c} {a b} {a a}} a
+} -returnCodes error -result {element 2 missing from sublist "a c"}
+test lsearch-20.2 {lsearch -index option, malformed index} -body {
+ lsearch -index foo {{a c} {a b} {a a}} a
+} -returnCodes error -result {bad index "foo": must be integer?[+-]integer? or end?[+-]integer?}
+test lsearch-20.3 {lsearch -index option, malformed index} -body {
+ lsearch -index \{ {{a c} {a b} {a a}} a
+} -returnCodes error -result {unmatched open brace in list}
+
+test lsearch-21.1 {lsearch shimmering crash} {
+ set x 0
+ lsearch -exact -integer $x $x
+} 0
+test lsearch-21.2 {lsearch shimmering crash} {
+ set x 0.5
+ lsearch -exact -real $x $x
+} 0
+
+test lsearch-22.1 {lsearch -bisect} -setup {
+ set res {}
+} -body {
+ foreach i {0 1 5 6 7 8 15 16} {
+ lappend res [lsearch -bisect -integer {1 4 5 7 9 15} $i]
+ }
+ return $res
+} -result {-1 0 2 2 3 3 5 5}
+test lsearch-22.2 {lsearch -bisect, last of equals} -setup {
+ set res {}
+} -body {
+ foreach i {0 1 2 3} {
+ lappend res [lsearch -bisect -integer {0 0 1 1 1 2 2 2 3 3 3} $i]
+ }
+ return $res
+} -result {1 4 7 10}
+test lsearch-22.3 {lsearch -bisect decreasing order} -setup {
+ set res {}
+} -body {
+ foreach i {0 1 5 6 7 8 15 16} {
+ lappend res [lsearch -bisect -integer -decreasing {15 9 7 5 4 1} $i]
+ }
+ return $res
+} -result {5 5 3 2 2 1 0 -1}
+test lsearch-22.4 {lsearch -bisect, last of equals, decreasing} -setup {
+ set res {}
+} -body {
+ foreach i {0 1 2 3} {
+ lappend res [lsearch -bisect -integer -decreasing \
+ {3 3 3 2 2 2 1 1 1 0 0} $i]
+ }
+ return $res
+} -result {10 8 5 2}
+test lsearch-22.5 {lsearch -bisect, all equal} {
+ lsearch -bisect -integer {5 5 5 5} 5
+} {3}
+test lsearch-22.6 {lsearch -sorted, all equal} {
+ lsearch -sorted -integer {5 5 5 5} 5
+} {0}
+
+# cleanup
+catch {unset res}
+catch {unset increasingIntegers}
+catch {unset decreasingIntegers}
+catch {unset increasingDoubles}
+catch {unset decreasingDoubles}
+catch {unset increasingStrings}
+catch {unset decreasingStrings}
+catch {unset increasingDictionary}
+catch {unset decreasingDictionary}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/lset.test b/library/msgcat/tests/lset.test
new file mode 100644
index 0000000..3f4914d
--- /dev/null
+++ b/library/msgcat/tests/lset.test
@@ -0,0 +1,478 @@
+# This file is a -*- tcl -*- test script
+
+# Commands covered: lset
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 2001 by 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+proc failTrace {name1 name2 op} {
+ error "trace failed"
+}
+
+testConstraint testevalex [llength [info commands testevalex]]
+
+set noRead {}
+trace add variable noRead read failTrace
+set noWrite {a b c}
+trace add variable noWrite write failTrace
+
+test lset-1.1 {lset, not compiled, arg count} testevalex {
+ list [catch {testevalex lset} msg] $msg
+} "1 {wrong \# args: should be \"lset listVar ?index? ?index ...? value\"}"
+test lset-1.2 {lset, not compiled, no such var} testevalex {
+ list [catch {testevalex {lset noSuchVar 0 {}}} msg] $msg
+} "1 {can't read \"noSuchVar\": no such variable}"
+test lset-1.3 {lset, not compiled, var not readable} testevalex {
+ list [catch {testevalex {lset noRead 0 {}}} msg] $msg
+} "1 {can't read \"noRead\": trace failed}"
+
+test lset-2.1 {lset, not compiled, 3 args, second arg a plain index} testevalex {
+ set x {0 1 2}
+ list [testevalex {lset x 0 3}] $x
+} {{3 1 2} {3 1 2}}
+test lset-2.2 {lset, not compiled, 3 args, second arg neither index nor list} testevalex {
+ set x {0 1 2}
+ list [catch {
+ testevalex {lset x {{bad}1} 3}
+ } msg] $msg
+} {1 {bad index "{bad}1": must be integer?[+-]integer? or end?[+-]integer?}}
+
+test lset-3.1 {lset, not compiled, 3 args, data duplicated} testevalex {
+ set x {0 1 2}
+ list [testevalex {lset x 0 $x}] $x
+} {{{0 1 2} 1 2} {{0 1 2} 1 2}}
+test lset-3.2 {lset, not compiled, 3 args, data duplicated} testevalex {
+ set x {0 1}
+ set y $x
+ list [testevalex {lset x 0 2}] $x $y
+} {{2 1} {2 1} {0 1}}
+test lset-3.3 {lset, not compiled, 3 args, data duplicated} testevalex {
+ set x {0 1}
+ set y $x
+ list [testevalex {lset x 0 $x}] $x $y
+} {{{0 1} 1} {{0 1} 1} {0 1}}
+test lset-3.4 {lset, not compiled, 3 args, data duplicated} testevalex {
+ set x {0 1 2}
+ list [testevalex {lset x [list 0] $x}] $x
+} {{{0 1 2} 1 2} {{0 1 2} 1 2}}
+test lset-3.5 {lset, not compiled, 3 args, data duplicated} testevalex {
+ set x {0 1}
+ set y $x
+ list [testevalex {lset x [list 0] 2}] $x $y
+} {{2 1} {2 1} {0 1}}
+test lset-3.6 {lset, not compiled, 3 args, data duplicated} testevalex {
+ set x {0 1}
+ set y $x
+ list [testevalex {lset x [list 0] $x}] $x $y
+} {{{0 1} 1} {{0 1} 1} {0 1}}
+
+test lset-4.1 {lset, not compiled, 3 args, not a list} testevalex {
+ set a "x \{"
+ list [catch {
+ testevalex {lset a [list 0] y}
+ } msg] $msg
+} {1 {unmatched open brace in list}}
+test lset-4.2 {lset, not compiled, 3 args, bad index} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a [list 2a2] w}
+ } msg] $msg
+} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lset-4.3 {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a [list -1] w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.4 {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a [list 4] w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.5a {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a [list end--2] w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.5b {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a [list end+2] w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.6 {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a [list end-3] w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.7 {lset, not compiled, 3 args, not a list} testevalex {
+ set a "x \{"
+ list [catch {
+ testevalex {lset a 0 y}
+ } msg] $msg
+} {1 {unmatched open brace in list}}
+test lset-4.8 {lset, not compiled, 3 args, bad index} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a 2a2 w}
+ } msg] $msg
+} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lset-4.9 {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a -1 w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.10 {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a 4 w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.11a {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a end--2 w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.11 {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a end+2 w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.12 {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a end-3 w}
+ } msg] $msg
+} {1 {list index out of range}}
+
+test lset-5.1 {lset, not compiled, 3 args, can't set variable} testevalex {
+ list [catch {
+ testevalex {lset noWrite 0 d}
+ } msg] $msg $noWrite
+} {1 {can't set "noWrite": trace failed} {d b c}}
+test lset-5.2 {lset, not compiled, 3 args, can't set variable} testevalex {
+ list [catch {
+ testevalex {lset noWrite [list 0] d}
+ } msg] $msg $noWrite
+} {1 {can't set "noWrite": trace failed} {d b c}}
+
+test lset-6.1 {lset, not compiled, 3 args, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a 0 a}] $a
+} {{a y z} {a y z}}
+test lset-6.2 {lset, not compiled, 3 args, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a [list 0] a}] $a
+} {{a y z} {a y z}}
+test lset-6.3 {lset, not compiled, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a 2 a}] $a
+} {{x y a} {x y a}}
+test lset-6.4 {lset, not compiled, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a [list 2] a}] $a
+} {{x y a} {x y a}}
+test lset-6.5 {lset, not compiled, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a end a}] $a
+} {{x y a} {x y a}}
+test lset-6.6 {lset, not compiled, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a [list end] a}] $a
+} {{x y a} {x y a}}
+test lset-6.7 {lset, not compiled, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a end-0 a}] $a
+} {{x y a} {x y a}}
+test lset-6.8 {lset, not compiled, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a [list end-0] a}] $a
+} {{x y a} {x y a}}
+test lset-6.9 {lset, not compiled, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a end-2 a}] $a
+} {{a y z} {a y z}}
+test lset-6.10 {lset, not compiled, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a [list end-2] a}] $a
+} {{a y z} {a y z}}
+
+test lset-7.1 {lset, not compiled, data sharing} testevalex {
+ set a 0
+ list [testevalex {lset a $a {gag me}}] $a
+} {{{gag me}} {{gag me}}}
+test lset-7.2 {lset, not compiled, data sharing} testevalex {
+ set a [list 0]
+ list [testevalex {lset a $a {gag me}}] $a
+} {{{gag me}} {{gag me}}}
+test lset-7.3 {lset, not compiled, data sharing} testevalex {
+ set a {x y}
+ list [testevalex {lset a 0 $a}] $a
+} {{{x y} y} {{x y} y}}
+test lset-7.4 {lset, not compiled, data sharing} testevalex {
+ set a {x y}
+ list [testevalex {lset a [list 0] $a}] $a
+} {{{x y} y} {{x y} y}}
+test lset-7.5 {lset, not compiled, data sharing} testevalex {
+ set n 0
+ set a {x y}
+ list [testevalex {lset a $n $n}] $a $n
+} {{0 y} {0 y} 0}
+test lset-7.6 {lset, not compiled, data sharing} testevalex {
+ set n [list 0]
+ set a {x y}
+ list [testevalex {lset a $n $n}] $a $n
+} {{0 y} {0 y} 0}
+test lset-7.7 {lset, not compiled, data sharing} testevalex {
+ set n 0
+ set a [list $n $n]
+ list [testevalex {lset a $n 1}] $a $n
+} {{1 0} {1 0} 0}
+test lset-7.8 {lset, not compiled, data sharing} testevalex {
+ set n [list 0]
+ set a [list $n $n]
+ list [testevalex {lset a $n 1}] $a $n
+} {{1 0} {1 0} 0}
+test lset-7.9 {lset, not compiled, data sharing} testevalex {
+ set a 0
+ list [testevalex {lset a $a $a}] $a
+} {0 0}
+test lset-7.10 {lset, not compiled, data sharing} testevalex {
+ set a [list 0]
+ list [testevalex {lset a $a $a}] $a
+} {0 0}
+
+test lset-8.1 {lset, not compiled, malformed sublist} testevalex {
+ set a [list "a \{" b]
+ list [catch {testevalex {lset a 0 1 c}} msg] $msg
+} {1 {unmatched open brace in list}}
+test lset-8.2 {lset, not compiled, malformed sublist} testevalex {
+ set a [list "a \{" b]
+ list [catch {testevalex {lset a {0 1} c}} msg] $msg
+} {1 {unmatched open brace in list}}
+test lset-8.3 {lset, not compiled, bad second index} testevalex {
+ set a {{b c} {d e}}
+ list [catch {testevalex {lset a 0 2a2 f}} msg] $msg
+} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lset-8.4 {lset, not compiled, bad second index} testevalex {
+ set a {{b c} {d e}}
+ list [catch {testevalex {lset a {0 2a2} f}} msg] $msg
+} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lset-8.5 {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a 2 -1 h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.6 {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a {2 -1} h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.7 {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a 2 3 h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.8 {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a {2 3} h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.9a {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a 2 end--2 h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.9b {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a 2 end+2 h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.10a {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a {2 end--2} h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.10b {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a {2 end+2} h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.11 {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a 2 end-2 h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.12 {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a {2 end-2} h}} msg] $msg
+} {1 {list index out of range}}
+
+test lset-9.1 {lset, not compiled, entire variable} testevalex {
+ set a x
+ list [testevalex {lset a y}] $a
+} {y y}
+test lset-9.2 {lset, not compiled, entire variable} testevalex {
+ set a x
+ list [testevalex {lset a {} y}] $a
+} {y y}
+
+test lset-10.1 {lset, not compiled, shared data} testevalex {
+ set row {p q}
+ set a [list $row $row]
+ list [testevalex {lset a 0 0 x}] $a
+} {{{x q} {p q}} {{x q} {p q}}}
+test lset-10.2 {lset, not compiled, shared data} testevalex {
+ set row {p q}
+ set a [list $row $row]
+ list [testevalex {lset a {0 0} x}] $a
+} {{{x q} {p q}} {{x q} {p q}}}
+test lset-10.3 {lset, not compiled, shared data, [Bug 1333036]} testevalex {
+ set a [list [list p q] [list r s]]
+ set b $a
+ list [testevalex {lset b {0 0} x}] $a
+} {{{x q} {r s}} {{p q} {r s}}}
+
+test lset-11.1 {lset, not compiled, 2-d basics} testevalex {
+ set a {{b c} {d e}}
+ list [testevalex {lset a 0 0 f}] $a
+} {{{f c} {d e}} {{f c} {d e}}}
+test lset-11.2 {lset, not compiled, 2-d basics} testevalex {
+ set a {{b c} {d e}}
+ list [testevalex {lset a {0 0} f}] $a
+} {{{f c} {d e}} {{f c} {d e}}}
+test lset-11.3 {lset, not compiled, 2-d basics} testevalex {
+ set a {{b c} {d e}}
+ list [testevalex {lset a 0 1 f}] $a
+} {{{b f} {d e}} {{b f} {d e}}}
+test lset-11.4 {lset, not compiled, 2-d basics} testevalex {
+ set a {{b c} {d e}}
+ list [testevalex {lset a {0 1} f}] $a
+} {{{b f} {d e}} {{b f} {d e}}}
+test lset-11.5 {lset, not compiled, 2-d basics} testevalex {
+ set a {{b c} {d e}}
+ list [testevalex {lset a 1 0 f}] $a
+} {{{b c} {f e}} {{b c} {f e}}}
+test lset-11.6 {lset, not compiled, 2-d basics} testevalex {
+ set a {{b c} {d e}}
+ list [testevalex {lset a {1 0} f}] $a
+} {{{b c} {f e}} {{b c} {f e}}}
+test lset-11.7 {lset, not compiled, 2-d basics} testevalex {
+ set a {{b c} {d e}}
+ list [testevalex {lset a 1 1 f}] $a
+} {{{b c} {d f}} {{b c} {d f}}}
+test lset-11.8 {lset, not compiled, 2-d basics} testevalex {
+ set a {{b c} {d e}}
+ list [testevalex {lset a {1 1} f}] $a
+} {{{b c} {d f}} {{b c} {d f}}}
+
+test lset-12.0 {lset, not compiled, typical sharing pattern} testevalex {
+ set zero 0
+ set row [list $zero $zero $zero $zero]
+ set ident [list $row $row $row $row]
+ for { set i 0 } { $i < 4 } { incr i } {
+ testevalex {lset ident $i $i 1}
+ }
+ set ident
+} {{1 0 0 0} {0 1 0 0} {0 0 1 0} {0 0 0 1}}
+
+test lset-13.0 {lset, not compiled, shimmering hell} testevalex {
+ set a 0
+ list [testevalex {lset a $a $a $a $a {gag me}}] $a
+} {{{{{{gag me}}}}} {{{{{gag me}}}}}}
+test lset-13.1 {lset, not compiled, shimmering hell} testevalex {
+ set a [list 0]
+ list [testevalex {lset a $a $a $a $a {gag me}}] $a
+} {{{{{{gag me}}}}} {{{{{gag me}}}}}}
+test lset-13.2 {lset, not compiled, shimmering hell} testevalex {
+ set a [list 0 0 0 0]
+ list [testevalex {lset a $a {gag me}}] $a
+} {{{{{{gag me}}}} 0 0 0} {{{{{gag me}}}} 0 0 0}}
+
+test lset-14.1 {lset, not compiled, list args, is string rep preserved?} testevalex {
+ set a { { 1 2 } { 3 4 } }
+ catch { testevalex {lset a {1 5} 5} }
+ list $a [lindex $a 1]
+} "{ { 1 2 } { 3 4 } } { 3 4 }"
+test lset-14.2 {lset, not compiled, flat args, is string rep preserved?} testevalex {
+ set a { { 1 2 } { 3 4 } }
+ catch { testevalex {lset a 1 5 5} }
+ list $a [lindex $a 1]
+} "{ { 1 2 } { 3 4 } } { 3 4 }"
+
+testConstraint testobj [llength [info commands testobj]]
+test lset-15.1 {lset: shared intrep [Bug 1677512]} -setup {
+ teststringobj set 1 {{1 2} 3}
+ testobj convert 1 list
+ testobj duplicate 1 2
+ variable x [teststringobj get 1]
+ variable y [teststringobj get 2]
+ testobj freeallvars
+ set l [list $y z]
+ unset y
+} -constraints testobj -body {
+ lset l 0 0 0 5
+ lindex $x 0 0
+} -cleanup {
+ unset -nocomplain x l
+} -result 1
+
+test lset-16.1 {lset - grow a variable} testevalex {
+ set x {}
+ testevalex {lset x 0 {test 1}}
+ testevalex {lset x 1 {test 2}}
+ set x
+} {{test 1} {test 2}}
+test lset-16.2 {lset - multiple created sublists} testevalex {
+ set x {}
+ testevalex {lset x 0 0 {test 1}}
+} {{{test 1}}}
+test lset-16.3 {lset - sublists 3 deep} testevalex {
+ set x {}
+ testevalex {lset x 0 0 0 {test 1}}
+} {{{{test 1}}}}
+test lset-16.4 {lset - append to inner list} testevalex {
+ set x {test 1}
+ testevalex {lset x 1 1 2}
+ testevalex {lset x 1 2 3}
+ testevalex {lset x 1 2 1 4}
+} {test {1 2 {3 4}}}
+
+test lset-16.5 {lset - grow a variable} testevalex {
+ set x {}
+ testevalex {lset x end+1 {test 1}}
+ testevalex {lset x end+1 {test 2}}
+ set x
+} {{test 1} {test 2}}
+test lset-16.6 {lset - multiple created sublists} testevalex {
+ set x {}
+ testevalex {lset x end+1 end+1 {test 1}}
+} {{{test 1}}}
+test lset-16.7 {lset - sublists 3 deep} testevalex {
+ set x {}
+ testevalex {lset x end+1 end+1 end+1 {test 1}}
+} {{{{test 1}}}}
+test lset-16.8 {lset - append to inner list} testevalex {
+ set x {test 1}
+ testevalex {lset x end end+1 2}
+ testevalex {lset x end end+1 3}
+ testevalex {lset x end end end+1 4}
+} {test {1 2 {3 4}}}
+
+catch {unset noRead}
+catch {unset noWrite}
+catch {rename failTrace {}}
+catch {unset ::x}
+catch {unset ::y}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/lsetComp.test b/library/msgcat/tests/lsetComp.test
new file mode 100755
index 0000000..6846cbf
--- /dev/null
+++ b/library/msgcat/tests/lsetComp.test
@@ -0,0 +1,431 @@
+# This file is a -*- tcl -*- test script
+
+# Commands covered: lset
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 2001 by 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# Procedure to evaluate a script within a proc, to test compilation
+# functionality
+
+proc evalInProc { script } {
+ proc testProc {} $script
+ set status [catch {
+ testProc
+ } result]
+ rename testProc {}
+ return [list $status $result]
+}
+
+# Tests for the bytecode compilation of the 'lset' command
+
+test lsetComp-1.1 {lset, compiled, wrong \# args} {
+ evalInProc {
+ lset
+ }
+} "1 {wrong \# args: should be \"lset listVar ?index? ?index ...? value\"}"
+
+test lsetComp-2.1 {lset, compiled, list of args, not a simple var name} {
+ evalInProc {
+ set y x
+ set x {{1 2} {3 4}}
+ lset $y {1 1} 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.2 {lset, compiled, list of args, scalar on stack} {
+ evalInProc {
+ set ::x {{1 2} {3 4}}
+ lset ::x {1 1} 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.3 {lset, compiled, list of args, scalar, one-byte offset} {
+ evalInProc {
+ set x {{1 2} {3 4}}
+ lset x {1 1} 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.4 {lset, compiled, list of args, scalar, four-byte offset} {
+ evalInProc {
+ set x0 0; set x1 0; set x2 0; set x3 0;
+ set x4 0; set x5 0; set x6 0; set x7 0;
+ set x8 0; set x9 0; set x10 0; set x11 0;
+ set x12 0; set x13 0; set x14 0; set x15 0;
+ set x16 0; set x17 0; set x18 0; set x19 0;
+ set x20 0; set x21 0; set x22 0; set x23 0;
+ set x24 0; set x25 0; set x26 0; set x27 0;
+ set x28 0; set x29 0; set x30 0; set x31 0;
+ set x32 0; set x33 0; set x34 0; set x35 0;
+ set x36 0; set x37 0; set x38 0; set x39 0;
+ set x40 0; set x41 0; set x42 0; set x43 0;
+ set x44 0; set x45 0; set x46 0; set x47 0;
+ set x48 0; set x49 0; set x50 0; set x51 0;
+ set x52 0; set x53 0; set x54 0; set x55 0;
+ set x56 0; set x57 0; set x58 0; set x59 0;
+ set x60 0; set x61 0; set x62 0; set x63 0;
+ set x64 0; set x65 0; set x66 0; set x67 0;
+ set x68 0; set x69 0; set x70 0; set x71 0;
+ set x72 0; set x73 0; set x74 0; set x75 0;
+ set x76 0; set x77 0; set x78 0; set x79 0;
+ set x80 0; set x81 0; set x82 0; set x83 0;
+ set x84 0; set x85 0; set x86 0; set x87 0;
+ set x88 0; set x89 0; set x90 0; set x91 0;
+ set x92 0; set x93 0; set x94 0; set x95 0;
+ set x96 0; set x97 0; set x98 0; set x99 0;
+ set x100 0; set x101 0; set x102 0; set x103 0;
+ set x104 0; set x105 0; set x106 0; set x107 0;
+ set x108 0; set x109 0; set x110 0; set x111 0;
+ set x112 0; set x113 0; set x114 0; set x115 0;
+ set x116 0; set x117 0; set x118 0; set x119 0;
+ set x120 0; set x121 0; set x122 0; set x123 0;
+ set x124 0; set x125 0; set x126 0; set x127 0;
+ set x128 0; set x129 0; set x130 0; set x131 0;
+ set x132 0; set x133 0; set x134 0; set x135 0;
+ set x136 0; set x137 0; set x138 0; set x139 0;
+ set x140 0; set x141 0; set x142 0; set x143 0;
+ set x144 0; set x145 0; set x146 0; set x147 0;
+ set x148 0; set x149 0; set x150 0; set x151 0;
+ set x152 0; set x153 0; set x154 0; set x155 0;
+ set x156 0; set x157 0; set x158 0; set x159 0;
+ set x160 0; set x161 0; set x162 0; set x163 0;
+ set x164 0; set x165 0; set x166 0; set x167 0;
+ set x168 0; set x169 0; set x170 0; set x171 0;
+ set x172 0; set x173 0; set x174 0; set x175 0;
+ set x176 0; set x177 0; set x178 0; set x179 0;
+ set x180 0; set x181 0; set x182 0; set x183 0;
+ set x184 0; set x185 0; set x186 0; set x187 0;
+ set x188 0; set x189 0; set x190 0; set x191 0;
+ set x192 0; set x193 0; set x194 0; set x195 0;
+ set x196 0; set x197 0; set x198 0; set x199 0;
+ set x200 0; set x201 0; set x202 0; set x203 0;
+ set x204 0; set x205 0; set x206 0; set x207 0;
+ set x208 0; set x209 0; set x210 0; set x211 0;
+ set x212 0; set x213 0; set x214 0; set x215 0;
+ set x216 0; set x217 0; set x218 0; set x219 0;
+ set x220 0; set x221 0; set x222 0; set x223 0;
+ set x224 0; set x225 0; set x226 0; set x227 0;
+ set x228 0; set x229 0; set x230 0; set x231 0;
+ set x232 0; set x233 0; set x234 0; set x235 0;
+ set x236 0; set x237 0; set x238 0; set x239 0;
+ set x240 0; set x241 0; set x242 0; set x243 0;
+ set x244 0; set x245 0; set x246 0; set x247 0;
+ set x248 0; set x249 0; set x250 0; set x251 0;
+ set x252 0; set x253 0; set x254 0; set x255 0;
+ set x {{1 2} {3 4}}
+ lset x {1 1} 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.5 {lset, compiled, list of args, array on stack} {
+ evalInProc {
+ set ::y(0) {{1 2} {3 4}}
+ lset ::y(0) {1 1} 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.6 {lset, compiled, list of args, array, one-byte offset} {
+ evalInProc {
+ set y(0) {{1 2} {3 4}}
+ lset y(0) {1 1} 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.7 {lset, compiled, list of args, array, four-byte offset} {
+ evalInProc {
+ set x0 0; set x1 0; set x2 0; set x3 0;
+ set x4 0; set x5 0; set x6 0; set x7 0;
+ set x8 0; set x9 0; set x10 0; set x11 0;
+ set x12 0; set x13 0; set x14 0; set x15 0;
+ set x16 0; set x17 0; set x18 0; set x19 0;
+ set x20 0; set x21 0; set x22 0; set x23 0;
+ set x24 0; set x25 0; set x26 0; set x27 0;
+ set x28 0; set x29 0; set x30 0; set x31 0;
+ set x32 0; set x33 0; set x34 0; set x35 0;
+ set x36 0; set x37 0; set x38 0; set x39 0;
+ set x40 0; set x41 0; set x42 0; set x43 0;
+ set x44 0; set x45 0; set x46 0; set x47 0;
+ set x48 0; set x49 0; set x50 0; set x51 0;
+ set x52 0; set x53 0; set x54 0; set x55 0;
+ set x56 0; set x57 0; set x58 0; set x59 0;
+ set x60 0; set x61 0; set x62 0; set x63 0;
+ set x64 0; set x65 0; set x66 0; set x67 0;
+ set x68 0; set x69 0; set x70 0; set x71 0;
+ set x72 0; set x73 0; set x74 0; set x75 0;
+ set x76 0; set x77 0; set x78 0; set x79 0;
+ set x80 0; set x81 0; set x82 0; set x83 0;
+ set x84 0; set x85 0; set x86 0; set x87 0;
+ set x88 0; set x89 0; set x90 0; set x91 0;
+ set x92 0; set x93 0; set x94 0; set x95 0;
+ set x96 0; set x97 0; set x98 0; set x99 0;
+ set x100 0; set x101 0; set x102 0; set x103 0;
+ set x104 0; set x105 0; set x106 0; set x107 0;
+ set x108 0; set x109 0; set x110 0; set x111 0;
+ set x112 0; set x113 0; set x114 0; set x115 0;
+ set x116 0; set x117 0; set x118 0; set x119 0;
+ set x120 0; set x121 0; set x122 0; set x123 0;
+ set x124 0; set x125 0; set x126 0; set x127 0;
+ set x128 0; set x129 0; set x130 0; set x131 0;
+ set x132 0; set x133 0; set x134 0; set x135 0;
+ set x136 0; set x137 0; set x138 0; set x139 0;
+ set x140 0; set x141 0; set x142 0; set x143 0;
+ set x144 0; set x145 0; set x146 0; set x147 0;
+ set x148 0; set x149 0; set x150 0; set x151 0;
+ set x152 0; set x153 0; set x154 0; set x155 0;
+ set x156 0; set x157 0; set x158 0; set x159 0;
+ set x160 0; set x161 0; set x162 0; set x163 0;
+ set x164 0; set x165 0; set x166 0; set x167 0;
+ set x168 0; set x169 0; set x170 0; set x171 0;
+ set x172 0; set x173 0; set x174 0; set x175 0;
+ set x176 0; set x177 0; set x178 0; set x179 0;
+ set x180 0; set x181 0; set x182 0; set x183 0;
+ set x184 0; set x185 0; set x186 0; set x187 0;
+ set x188 0; set x189 0; set x190 0; set x191 0;
+ set x192 0; set x193 0; set x194 0; set x195 0;
+ set x196 0; set x197 0; set x198 0; set x199 0;
+ set x200 0; set x201 0; set x202 0; set x203 0;
+ set x204 0; set x205 0; set x206 0; set x207 0;
+ set x208 0; set x209 0; set x210 0; set x211 0;
+ set x212 0; set x213 0; set x214 0; set x215 0;
+ set x216 0; set x217 0; set x218 0; set x219 0;
+ set x220 0; set x221 0; set x222 0; set x223 0;
+ set x224 0; set x225 0; set x226 0; set x227 0;
+ set x228 0; set x229 0; set x230 0; set x231 0;
+ set x232 0; set x233 0; set x234 0; set x235 0;
+ set x236 0; set x237 0; set x238 0; set x239 0;
+ set x240 0; set x241 0; set x242 0; set x243 0;
+ set x244 0; set x245 0; set x246 0; set x247 0;
+ set x248 0; set x249 0; set x250 0; set x251 0;
+ set x252 0; set x253 0; set x254 0; set x255 0;
+ set y(0) {{1 2} {3 4}}
+ lset y(0) {1 1} 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.8 {lset, compiled, list of args, error } {
+ evalInProc {
+ set x { {1 2} {3 4} }
+ lset x {1 5} 5
+ }
+} "1 {list index out of range}"
+
+test lsetComp-2.9 {lset, compiled, list of args, error - is string preserved} {
+ set ::x { { 1 2 } { 3 4 } }
+ evalInProc {
+ lset ::x { 1 5 } 5
+ }
+ list $::x [lindex $::x 1]
+} "{ { 1 2 } { 3 4 } } { 3 4 }"
+
+test lsetComp-3.1 {lset, compiled, flat args, not a simple var name} {
+ evalInProc {
+ set y x
+ set x {{1 2} {3 4}}
+ lset $y 1 1 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.2 {lset, compiled, flat args, scalar on stack} {
+ evalInProc {
+ set ::x {{1 2} {3 4}}
+ lset ::x 1 1 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.3 {lset, compiled, flat args, scalar, one-byte offset} {
+ evalInProc {
+ set x {{1 2} {3 4}}
+ lset x 1 1 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.4 {lset, compiled, scalar, four-byte offset} {
+ evalInProc {
+ set x0 0; set x1 0; set x2 0; set x3 0;
+ set x4 0; set x5 0; set x6 0; set x7 0;
+ set x8 0; set x9 0; set x10 0; set x11 0;
+ set x12 0; set x13 0; set x14 0; set x15 0;
+ set x16 0; set x17 0; set x18 0; set x19 0;
+ set x20 0; set x21 0; set x22 0; set x23 0;
+ set x24 0; set x25 0; set x26 0; set x27 0;
+ set x28 0; set x29 0; set x30 0; set x31 0;
+ set x32 0; set x33 0; set x34 0; set x35 0;
+ set x36 0; set x37 0; set x38 0; set x39 0;
+ set x40 0; set x41 0; set x42 0; set x43 0;
+ set x44 0; set x45 0; set x46 0; set x47 0;
+ set x48 0; set x49 0; set x50 0; set x51 0;
+ set x52 0; set x53 0; set x54 0; set x55 0;
+ set x56 0; set x57 0; set x58 0; set x59 0;
+ set x60 0; set x61 0; set x62 0; set x63 0;
+ set x64 0; set x65 0; set x66 0; set x67 0;
+ set x68 0; set x69 0; set x70 0; set x71 0;
+ set x72 0; set x73 0; set x74 0; set x75 0;
+ set x76 0; set x77 0; set x78 0; set x79 0;
+ set x80 0; set x81 0; set x82 0; set x83 0;
+ set x84 0; set x85 0; set x86 0; set x87 0;
+ set x88 0; set x89 0; set x90 0; set x91 0;
+ set x92 0; set x93 0; set x94 0; set x95 0;
+ set x96 0; set x97 0; set x98 0; set x99 0;
+ set x100 0; set x101 0; set x102 0; set x103 0;
+ set x104 0; set x105 0; set x106 0; set x107 0;
+ set x108 0; set x109 0; set x110 0; set x111 0;
+ set x112 0; set x113 0; set x114 0; set x115 0;
+ set x116 0; set x117 0; set x118 0; set x119 0;
+ set x120 0; set x121 0; set x122 0; set x123 0;
+ set x124 0; set x125 0; set x126 0; set x127 0;
+ set x128 0; set x129 0; set x130 0; set x131 0;
+ set x132 0; set x133 0; set x134 0; set x135 0;
+ set x136 0; set x137 0; set x138 0; set x139 0;
+ set x140 0; set x141 0; set x142 0; set x143 0;
+ set x144 0; set x145 0; set x146 0; set x147 0;
+ set x148 0; set x149 0; set x150 0; set x151 0;
+ set x152 0; set x153 0; set x154 0; set x155 0;
+ set x156 0; set x157 0; set x158 0; set x159 0;
+ set x160 0; set x161 0; set x162 0; set x163 0;
+ set x164 0; set x165 0; set x166 0; set x167 0;
+ set x168 0; set x169 0; set x170 0; set x171 0;
+ set x172 0; set x173 0; set x174 0; set x175 0;
+ set x176 0; set x177 0; set x178 0; set x179 0;
+ set x180 0; set x181 0; set x182 0; set x183 0;
+ set x184 0; set x185 0; set x186 0; set x187 0;
+ set x188 0; set x189 0; set x190 0; set x191 0;
+ set x192 0; set x193 0; set x194 0; set x195 0;
+ set x196 0; set x197 0; set x198 0; set x199 0;
+ set x200 0; set x201 0; set x202 0; set x203 0;
+ set x204 0; set x205 0; set x206 0; set x207 0;
+ set x208 0; set x209 0; set x210 0; set x211 0;
+ set x212 0; set x213 0; set x214 0; set x215 0;
+ set x216 0; set x217 0; set x218 0; set x219 0;
+ set x220 0; set x221 0; set x222 0; set x223 0;
+ set x224 0; set x225 0; set x226 0; set x227 0;
+ set x228 0; set x229 0; set x230 0; set x231 0;
+ set x232 0; set x233 0; set x234 0; set x235 0;
+ set x236 0; set x237 0; set x238 0; set x239 0;
+ set x240 0; set x241 0; set x242 0; set x243 0;
+ set x244 0; set x245 0; set x246 0; set x247 0;
+ set x248 0; set x249 0; set x250 0; set x251 0;
+ set x252 0; set x253 0; set x254 0; set x255 0;
+ set x {{1 2} {3 4}}
+ lset x 1 1 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.5 {lset, compiled, flat args, array on stack} {
+ evalInProc {
+ set ::y(0) {{1 2} {3 4}}
+ lset ::y(0) 1 1 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.6 {lset, compiled, flat args, array, one-byte offset} {
+ evalInProc {
+ set y(0) {{1 2} {3 4}}
+ lset y(0) 1 1 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.7 {lset, compiled, flat args, array, four-byte offset} {
+ evalInProc {
+ set x0 0; set x1 0; set x2 0; set x3 0;
+ set x4 0; set x5 0; set x6 0; set x7 0;
+ set x8 0; set x9 0; set x10 0; set x11 0;
+ set x12 0; set x13 0; set x14 0; set x15 0;
+ set x16 0; set x17 0; set x18 0; set x19 0;
+ set x20 0; set x21 0; set x22 0; set x23 0;
+ set x24 0; set x25 0; set x26 0; set x27 0;
+ set x28 0; set x29 0; set x30 0; set x31 0;
+ set x32 0; set x33 0; set x34 0; set x35 0;
+ set x36 0; set x37 0; set x38 0; set x39 0;
+ set x40 0; set x41 0; set x42 0; set x43 0;
+ set x44 0; set x45 0; set x46 0; set x47 0;
+ set x48 0; set x49 0; set x50 0; set x51 0;
+ set x52 0; set x53 0; set x54 0; set x55 0;
+ set x56 0; set x57 0; set x58 0; set x59 0;
+ set x60 0; set x61 0; set x62 0; set x63 0;
+ set x64 0; set x65 0; set x66 0; set x67 0;
+ set x68 0; set x69 0; set x70 0; set x71 0;
+ set x72 0; set x73 0; set x74 0; set x75 0;
+ set x76 0; set x77 0; set x78 0; set x79 0;
+ set x80 0; set x81 0; set x82 0; set x83 0;
+ set x84 0; set x85 0; set x86 0; set x87 0;
+ set x88 0; set x89 0; set x90 0; set x91 0;
+ set x92 0; set x93 0; set x94 0; set x95 0;
+ set x96 0; set x97 0; set x98 0; set x99 0;
+ set x100 0; set x101 0; set x102 0; set x103 0;
+ set x104 0; set x105 0; set x106 0; set x107 0;
+ set x108 0; set x109 0; set x110 0; set x111 0;
+ set x112 0; set x113 0; set x114 0; set x115 0;
+ set x116 0; set x117 0; set x118 0; set x119 0;
+ set x120 0; set x121 0; set x122 0; set x123 0;
+ set x124 0; set x125 0; set x126 0; set x127 0;
+ set x128 0; set x129 0; set x130 0; set x131 0;
+ set x132 0; set x133 0; set x134 0; set x135 0;
+ set x136 0; set x137 0; set x138 0; set x139 0;
+ set x140 0; set x141 0; set x142 0; set x143 0;
+ set x144 0; set x145 0; set x146 0; set x147 0;
+ set x148 0; set x149 0; set x150 0; set x151 0;
+ set x152 0; set x153 0; set x154 0; set x155 0;
+ set x156 0; set x157 0; set x158 0; set x159 0;
+ set x160 0; set x161 0; set x162 0; set x163 0;
+ set x164 0; set x165 0; set x166 0; set x167 0;
+ set x168 0; set x169 0; set x170 0; set x171 0;
+ set x172 0; set x173 0; set x174 0; set x175 0;
+ set x176 0; set x177 0; set x178 0; set x179 0;
+ set x180 0; set x181 0; set x182 0; set x183 0;
+ set x184 0; set x185 0; set x186 0; set x187 0;
+ set x188 0; set x189 0; set x190 0; set x191 0;
+ set x192 0; set x193 0; set x194 0; set x195 0;
+ set x196 0; set x197 0; set x198 0; set x199 0;
+ set x200 0; set x201 0; set x202 0; set x203 0;
+ set x204 0; set x205 0; set x206 0; set x207 0;
+ set x208 0; set x209 0; set x210 0; set x211 0;
+ set x212 0; set x213 0; set x214 0; set x215 0;
+ set x216 0; set x217 0; set x218 0; set x219 0;
+ set x220 0; set x221 0; set x222 0; set x223 0;
+ set x224 0; set x225 0; set x226 0; set x227 0;
+ set x228 0; set x229 0; set x230 0; set x231 0;
+ set x232 0; set x233 0; set x234 0; set x235 0;
+ set x236 0; set x237 0; set x238 0; set x239 0;
+ set x240 0; set x241 0; set x242 0; set x243 0;
+ set x244 0; set x245 0; set x246 0; set x247 0;
+ set x248 0; set x249 0; set x250 0; set x251 0;
+ set x252 0; set x253 0; set x254 0; set x255 0;
+ set y(0) {{1 2} {3 4}}
+ lset y(0) 1 1 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.8 {lset, compiled, flat args, error } {
+ evalInProc {
+ set x { {1 2} {3 4} }
+ lset x 1 5 5
+ }
+} "1 {list index out of range}"
+
+test lsetComp-3.9 {lset, compiled, flat args, error - is string preserved} {
+ set ::x { { 1 2 } { 3 4 } }
+ evalInProc {
+ lset ::x 1 5 5
+ }
+ list $::x [lindex $::x 1]
+} "{ { 1 2 } { 3 4 } } { 3 4 }"
+
+catch { rename evalInProc {} }
+catch { unset ::x }
+catch { unset ::y }
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/macOSXFCmd.test b/library/msgcat/tests/macOSXFCmd.test
new file mode 100644
index 0000000..071f11b
--- /dev/null
+++ b/library/msgcat/tests/macOSXFCmd.test
@@ -0,0 +1,181 @@
+# This file tests the tclMacOSXFCmd.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 2003 Tcl Core Team.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# These tests really need to be run from a writable directory, which
+# it is assumed [temporaryDirectory] is.
+set oldcwd [pwd]
+cd [temporaryDirectory]
+
+# check whether macosx file attributes are supported
+testConstraint macosxFileAttr 0
+if {[testConstraint unix] && $tcl_platform(os) eq "Darwin"} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ catch {
+ file attributes foo.test -creator
+ testConstraint macosxFileAttr 1
+ }
+ file delete -force -- foo.test
+}
+
+test macOSXFCmd-1.1 {MacOSXGetFileAttribute - file not found} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ list [catch {file attributes foo.test -creator} msg] $msg
+} {1 {could not read "foo.test": no such file or directory}}
+test macOSXFCmd-1.2 {MacOSXGetFileAttribute - creator} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -creator} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 {} {}}
+test macOSXFCmd-1.3 {MacOSXGetFileAttribute - type} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -type} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 {} {}}
+test macOSXFCmd-1.4 {MacOSXGetFileAttribute - hidden} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -hidden} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 0 {}}
+test macOSXFCmd-1.5 {MacOSXGetFileAttribute - rsrclength} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -rsrclength} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 0 {}}
+
+test macOSXFCmd-2.1 {MacOSXSetFileAttribute - file not found} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ list [catch {file attributes foo.test -creator FOOC} msg] $msg
+} {1 {could not read "foo.test": no such file or directory}}
+test macOSXFCmd-2.2 {MacOSXSetFileAttribute - creator} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -creator FOOC} msg] $msg \
+ [catch {file attributes foo.test -creator} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 {} 0 FOOC {}}
+test macOSXFCmd-2.3 {MacOSXSetFileAttribute - empty creator} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -creator {}} msg] $msg \
+ [catch {file attributes foo.test -creator} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 {} 0 {} {}}
+test macOSXFCmd-2.4 {MacOSXSetFileAttribute - type} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -type FOOT} msg] $msg \
+ [catch {file attributes foo.test -type} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 {} 0 FOOT {}}
+test macOSXFCmd-2.5 {MacOSXSetFileAttribute - empty type} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -type {}} msg] $msg \
+ [catch {file attributes foo.test -type} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 {} 0 {} {}}
+test macOSXFCmd-2.6 {MacOSXSetFileAttribute - hidden} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -hidden 1} msg] $msg \
+ [catch {file attributes foo.test -hidden} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 {} 0 1 {}}
+test macOSXFCmd-2.7 {MacOSXSetFileAttribute - rsrclength} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ catch {
+ set f [open foo.test/..namedfork/rsrc w]
+ fconfigure $f -translation lf -eofchar {}
+ puts -nonewline $f "foo"
+ close $f
+ }
+ list [catch {file attributes foo.test -rsrclength} msg] $msg \
+ [catch {file attributes foo.test -rsrclength 0} msg] $msg \
+ [catch {file attributes foo.test -rsrclength} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 3 0 {} 0 0 {}}
+
+test macOSXFCmd-3.1 {MacOSXCopyFileAttributes} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ catch {file delete -force -- bar.test}
+ close [open foo.test w]
+ catch {
+ file attributes foo.test -creator FOOC -type FOOT -hidden 1
+ set f [open foo.test/..namedfork/rsrc w]
+ fconfigure $f -translation lf -eofchar {}
+ puts -nonewline $f "foo"
+ close $f
+ file copy foo.test bar.test
+ }
+ list [catch {file attributes bar.test -creator} msg] $msg \
+ [catch {file attributes bar.test -type} msg] $msg \
+ [catch {file attributes bar.test -hidden} msg] $msg \
+ [catch {file attributes bar.test -rsrclength} msg] $msg \
+ [file delete -force -- foo.test bar.test]
+} {0 FOOC 0 FOOT 0 1 0 3 {}}
+
+test macOSXFCmd-4.1 {TclMacOSXMatchType} {macosxFileAttr notRoot} {
+ file mkdir globtest
+ cd globtest
+ foreach f {bar baz foo inv inw .nv reg} {
+ catch {file delete -force -- $f.test}
+ close [open $f.test w]
+ }
+ catch {file delete -force -- dir.test}
+ file mkdir dir.test
+ catch {
+ file attributes bar.test -type FOOT
+ file attributes baz.test -creator FOOC -type FOOT
+ file attributes foo.test -creator FOOC
+ file attributes inv.test -hidden 1
+ file attributes inw.test -hidden 1 -type FOOT
+ file attributes dir.test -hidden 1
+ }
+ set res [list \
+ [catch {glob *.test} msg] $msg \
+ [catch {glob -types FOOT *.test} msg] $msg \
+ [catch {glob -types {{macintosh type FOOT}} *.test} msg] $msg \
+ [catch {glob -types FOOTT *.test} msg] $msg \
+ [catch {glob -types {{macintosh type FOOTT}} *.test} msg] $msg \
+ [catch {glob -types {{macintosh type {}}} *.test} msg] $msg \
+ [catch {glob -types {{macintosh creator FOOC}} *.test} msg] $msg \
+ [catch {glob -types {{macintosh creator FOOC} {macintosh type FOOT}} *.test} msg] $msg \
+ [catch {glob -types hidden *.test} msg] $msg \
+ [catch {glob -types {hidden FOOT} *.test} msg] $msg \
+ ]
+ cd ..
+ file delete -force globtest
+ set res
+} [list \
+ 0 {bar.test baz.test dir.test foo.test inv.test inw.test reg.test} \
+ 0 {bar.test baz.test inw.test} 0 {bar.test baz.test inw.test} \
+ 1 {bad argument to "-types": FOOTT} \
+ 1 {expected Macintosh OS type but got "FOOTT": } \
+ 0 {foo.test inv.test reg.test} 0 {baz.test foo.test} \
+ 0 baz.test 0 {.nv.test dir.test inv.test inw.test} \
+ 0 inw.test
+]
+
+# cleanup
+cd $oldcwd
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/macOSXLoad.test b/library/msgcat/tests/macOSXLoad.test
new file mode 100644
index 0000000..12c77e0
--- /dev/null
+++ b/library/msgcat/tests/macOSXLoad.test
@@ -0,0 +1,33 @@
+# Commands covered: load unload
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1995 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+set oldTSF $::tcltest::testSingleFile
+set ::tcltest::testSingleFile false
+
+if {[testConstraint unix] && $tcl_platform(os) eq "Darwin" &&
+ ![string match *pkga* [info loaded]]} {
+ # On Darwin, test .bundle (un)loading in addition to .dylib
+ set ext .bundle
+ source [file join [file dirname [info script]] load.test]
+ set ext .bundle
+ source [file join [file dirname [info script]] unload.test]
+ unset -nocomplain ext
+}
+
+set ::tcltest::testSingleFile $oldTSF
+unset oldTSF
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/main.test b/library/msgcat/tests/main.test
new file mode 100644
index 0000000..f1dc7fd
--- /dev/null
+++ b/library/msgcat/tests/main.test
@@ -0,0 +1,1297 @@
+# This file contains a collection of tests for generic/tclMain.c.
+
+if {[catch {package require tcltest 2.0.2}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2.0.2 required."
+ return
+}
+
+namespace eval ::tcl::test::main {
+ namespace import ::tcltest::*
+
+ # Is [exec] defined?
+ testConstraint exec [llength [info commands exec]]
+
+ # Is the Tcltest package loaded?
+ # - that is, the special C-coded testing commands in tclTest.c
+ # - tests use testing commands introduced in Tcltest 8.4
+ testConstraint Tcltest [expr {
+ [llength [package provide Tcltest]]
+ && [package vsatisfies [package provide Tcltest] 8.4]}]
+
+ # Procedure to simulate interactive typing of commands, line by line
+ proc type {chan script} {
+ foreach line [split $script \n] {
+ if {[catch {
+ puts $chan $line
+ flush $chan
+ }]} {
+ return
+ }
+ # Grrr... Behavior depends on this value.
+ after 1000
+ }
+ }
+
+ cd [temporaryDirectory]
+ # Tests Tcl_Main-1.*: variable initializations
+
+ test Tcl_Main-1.1 {
+ Tcl_Main: startup script - normal
+ } -constraints {
+ stdio
+ } -setup {
+ makeFile {puts [list $argv0 $argv $tcl_interactive]} script
+ catch {set f [open "|[list [interpreter] script]" r]}
+ } -body {
+ read $f
+ } -cleanup {
+ close $f
+ removeFile script
+ } -result [list script {} 0]\n
+
+ test Tcl_Main-1.2 {
+ Tcl_Main: startup script - can't begin with '-'
+ } -constraints {
+ stdio
+ } -setup {
+ makeFile {puts [list $argv0 $argv $tcl_interactive]} -script
+ catch {set f [open "|[list [interpreter] -script]" w+]}
+ } -body {
+ puts $f {puts [list $argv0 $argv $tcl_interactive]; exit}
+ flush $f
+ read $f
+ } -cleanup {
+ close $f
+ removeFile -script
+ } -result [list [interpreter] -script 0]\n
+
+ test Tcl_Main-1.3 {
+ } -constraints {
+ stdio
+ } -setup {
+ makeFile {puts [list $argv0 $argv $tcl_interactive]} script
+ catch {set f [open "|[list [interpreter] script \u00c0]" r]}
+ } -body {
+ read $f
+ } -cleanup {
+ close $f
+ removeFile script
+ } -result [list script [list [encoding convertfrom [encoding system] \
+ [encoding convertto [encoding system] \u00c0]]] 0]\n
+
+ test Tcl_Main-1.4 {
+ } -constraints {
+ stdio
+ } -setup {
+ makeFile {puts [list $argv0 $argv $tcl_interactive]} script
+ catch {set f [open "|[list [interpreter] script \u20ac]" r]}
+ } -body {
+ read $f
+ } -cleanup {
+ close $f
+ removeFile script
+ } -result [list script [list [encoding convertfrom [encoding system] \
+ [encoding convertto [encoding system] \u20ac]]] 0]\n
+
+ test Tcl_Main-1.5 {
+ } -constraints {
+ stdio
+ } -setup {
+ makeFile {puts [list $argv0 $argv $tcl_interactive]} \u00c0
+ catch {set f [open "|[list [interpreter] \u00c0]" r]}
+ } -body {
+ read $f
+ } -cleanup {
+ close $f
+ removeFile \u00c0
+ } -result [list [list [encoding convertfrom [encoding system] \
+ [encoding convertto [encoding system] \u00c0]]] {} 0]\n
+
+ test Tcl_Main-1.6 {
+ } -constraints {
+ stdio
+ } -setup {
+ makeFile {puts [list $argv0 $argv $tcl_interactive]} \u20ac
+ catch {set f [open "|[list [interpreter] \u20ac]" r]}
+ } -body {
+ read $f
+ } -cleanup {
+ close $f
+ removeFile \u20ac
+ } -result [list [list [encoding convertfrom [encoding system] \
+ [encoding convertto [encoding system] \u20ac]]] {} 0]\n
+
+ test Tcl_Main-1.7 {
+ Tcl_Main: startup script - -encoding option
+ } -constraints {
+ stdio
+ } -setup {
+ set script [makeFile {} script]
+ file delete $script
+ set f [open $script w]
+ fconfigure $f -encoding utf-8
+ puts $f {puts [list $argv0 $argv $tcl_interactive]}
+ puts -nonewline $f {puts [string equal \u20ac }
+ puts $f "\u20ac]"
+ close $f
+ catch {set f [open "|[list [interpreter] -encoding utf-8 script]" r]}
+ } -body {
+ read $f
+ } -cleanup {
+ close $f
+ removeFile script
+ } -result [list script {} 0]\n1\n
+
+ test Tcl_Main-1.8 {
+ Tcl_Main: startup script - -encoding option - mismatched encodings
+ } -constraints {
+ stdio
+ } -setup {
+ set script [makeFile {} script]
+ file delete $script
+ set f [open $script w]
+ fconfigure $f -encoding utf-8
+ puts $f {puts [list $argv0 $argv $tcl_interactive]}
+ puts -nonewline $f {puts [string equal \u20ac }
+ puts $f "\u20ac]"
+ close $f
+ catch {set f [open "|[list [interpreter] -encoding ascii script]" r]}
+ } -body {
+ read $f
+ } -cleanup {
+ close $f
+ removeFile script
+ } -result [list script {} 0]\n0\n
+
+ test Tcl_Main-1.9 {
+ Tcl_Main: startup script - -encoding option - no abbrevation
+ } -constraints {
+ stdio
+ } -setup {
+ set script [makeFile {} script]
+ file delete $script
+ set f [open $script w]
+ fconfigure $f -encoding utf-8
+ puts $f {puts [list $argv0 $argv $tcl_interactive]}
+ puts -nonewline $f {puts [string equal \u20ac }
+ puts $f "\u20ac]"
+ close $f
+ catch {set f [open "|[list [interpreter] -enc utf-8 script]" r+]}
+ } -body {
+ type $f {
+ puts $argv
+ }
+ list [catch {gets $f} line] $line
+ } -cleanup {
+ close $f
+ removeFile script
+ } -result {0 {-enc utf-8 script}}
+
+ # Tests Tcl_Main-2.*: application-initialization procedure
+
+ test Tcl_Main-2.1 {
+ Tcl_Main: appInitProc returns error
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ makeFile {puts "In script"} script
+ } -body {
+ exec [interpreter] script -appinitprocerror >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -result "application-specific initialization failed: \nIn script\n"
+
+ test Tcl_Main-2.2 {
+ Tcl_Main: appInitProc returns error
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {puts "In script"} -appinitprocerror >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "application-specific initialization failed: \nIn script\n"
+
+ test Tcl_Main-2.3 {
+ Tcl_Main: appInitProc deletes interp
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ makeFile {puts "In script"} script
+ } -body {
+ exec [interpreter] script -appinitprocdeleteinterp >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -result "application-specific initialization failed: \n"
+
+ test Tcl_Main-2.4 {
+ Tcl_Main: appInitProc deletes interp
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {puts "In script"} \
+ -appinitprocdeleteinterp >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "application-specific initialization failed: \n"
+
+ test Tcl_Main-2.5 {
+ Tcl_Main: appInitProc closes stderr
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {puts "In script"} \
+ -appinitprocclosestderr >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "In script\n"
+
+ # Tests Tcl_Main-3.*: startup script evaluation
+
+ test Tcl_Main-3.1 {
+ Tcl_Main: startup script does not exist
+ } -constraints {
+ exec
+ } -setup {
+ if {[file exists no-such-file]} {
+ error "Can't run test Tcl_Main-3.1\
+ where a file named \"no-such-file\" exists"
+ }
+ } -body {
+ set code [catch {exec [interpreter] no-such-file >& result} result]
+ set f [open result]
+ list $code $result [read $f]
+ } -cleanup {
+ close $f
+ file delete result
+ } -match glob -result [list 1 {child process exited abnormally} \
+ {couldn't read file "no-such-file":*}]
+
+ test Tcl_Main-3.2 {
+ Tcl_Main: startup script raises error
+ } -constraints {
+ exec
+ } -setup {
+ makeFile {error ERROR} script
+ } -body {
+ set code [catch {exec [interpreter] script >& result} result]
+ set f [open result]
+ list $code $result [read $f]
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -match glob -result [list 1 {child process exited abnormally} \
+ "ERROR\n while executing*"]
+
+ test Tcl_Main-3.3 {
+ Tcl_Main: startup script closes stderr
+ } -constraints {
+ exec
+ } -setup {
+ makeFile {close stderr; error ERROR} script
+ } -body {
+ set code [catch {exec [interpreter] script >& result} result]
+ set f [open result]
+ list $code $result [read $f]
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -result [list 1 {child process exited abnormally} {}]
+
+ test Tcl_Main-3.4 {
+ Tcl_Main: startup script holds incomplete script
+ } -constraints {
+ exec
+ } -setup {
+ makeFile "if 1 \{" script
+ } -body {
+ set code [catch {exec [interpreter] script >& result} result]
+ set f [open result]
+ join [list $code $result [read $f]] \n
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -match glob -result [join [list 1 {child process exited abnormally}\
+ "missing close-brace\n while executing*"] \n]
+
+ test Tcl_Main-3.5 {
+ Tcl_Main: startup script sets main loop
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ makeFile {
+ rename exit _exit
+ proc exit {code} {
+ puts "In exit"
+ _exit $code
+ }
+ after 0 {
+ puts event
+ testexitmainloop
+ }
+ testexithandler create 0
+ testsetmainloop
+ } script
+ } -body {
+ exec [interpreter] script >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -result "event\nExit MainLoop\nIn exit\neven 0\n"
+
+ test Tcl_Main-3.6 {
+ Tcl_Main: startup script sets main loop and closes stdin
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ makeFile {
+ close stdin
+ testsetmainloop
+ rename exit _exit
+ proc exit {code} {
+ puts "In exit"
+ _exit $code
+ }
+ after 0 {
+ puts event
+ testexitmainloop
+ }
+ testexithandler create 0
+ } script
+ } -body {
+ exec [interpreter] script >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -result "event\nExit MainLoop\nIn exit\neven 0\n"
+
+ test Tcl_Main-3.7 {
+ Tcl_Main: startup script deletes interp
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ makeFile {
+ rename exit _exit
+ proc exit {code} {
+ puts "In exit"
+ _exit $code
+ }
+ testexithandler create 0
+ testinterpdelete {}
+ } script
+ } -body {
+ exec [interpreter] script >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -result "even 0\n"
+
+ test Tcl_Main-3.8 {
+ Tcl_Main: startup script deletes interp and sets mainloop
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ makeFile {
+ testsetmainloop
+ rename exit _exit
+ proc exit {code} {
+ puts "In exit"
+ _exit $code
+ }
+ testexitmainloop
+ testexithandler create 0
+ testinterpdelete {}
+ } script
+ } -body {
+ exec [interpreter] script >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -result "Exit MainLoop\neven 0\n"
+
+ test Tcl_Main-3.9 {
+ Tcl_Main: startup script can set tcl_interactive without limit
+ } -constraints {
+ exec
+ } -setup {
+ makeFile {set tcl_interactive foo} script
+ } -body {
+ exec [interpreter] script >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -result {}
+
+ # Tests Tcl_Main-4.*: rc file evaluation
+
+ test Tcl_Main-4.1 {
+ Tcl_Main: rcFile evaluation deletes interp
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ set rc [makeFile {testinterpdelete {}} rc]
+ } -body {
+ exec [interpreter] << {puts "In script"} \
+ -appinitprocsetrcfile $rc >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile rc
+ } -result "application-specific initialization failed: \n"
+
+ test Tcl_Main-4.2 {
+ Tcl_Main: rcFile evaluation closes stdin
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ set rc [makeFile {close stdin} rc]
+ } -body {
+ exec [interpreter] << {puts "In script"} \
+ -appinitprocsetrcfile $rc >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile rc
+ } -result "application-specific initialization failed: \n"
+
+ test Tcl_Main-4.3 {
+ Tcl_Main: rcFile evaluation closes stdin and sets main loop
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ set rc [makeFile {
+ close stdin
+ testsetmainloop
+ after 0 testexitmainloop
+ testexithandler create 0
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ } rc]
+ } -body {
+ exec [interpreter] << {puts "In script"} \
+ -appinitprocsetrcfile $rc >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile rc
+ } -result "application-specific initialization failed:\
+ \nExit MainLoop\nIn exit\neven 0\n"
+
+ test Tcl_Main-4.4 {
+ Tcl_Main: rcFile evaluation sets main loop
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ set rc [makeFile {
+ testsetmainloop
+ after 0 testexitmainloop
+ testexithandler create 0
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ } rc]
+ } -body {
+ exec [interpreter] << {} \
+ -appinitprocsetrcfile $rc >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile rc
+ } -result "application-specific initialization failed:\
+ \nExit MainLoop\nIn exit\neven 0\n"
+
+ test Tcl_Main-4.5 {
+ Tcl_Main: Bug 1481986
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ set rc [makeFile {
+ testsetmainloop
+ after 0 {puts "Event callback"}
+ } rc]
+ } -body {
+ set f [open "|[list [interpreter] -appinitprocsetrcfile $rc]" w+]
+ after 1000
+ type $f {puts {Interactive output}
+ exit
+ }
+ read $f
+ } -cleanup {
+ catch {close $f}
+ removeFile rc
+ } -result "Event callback\nInteractive output\n"
+
+ # Tests Tcl_Main-5.*: interactive operations
+
+ test Tcl_Main-5.1 {
+ Tcl_Main: tcl_interactive must be boolean
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {set tcl_interactive foo} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "can't set \"tcl_interactive\":\
+ variable must have boolean value\n"
+
+ test Tcl_Main-5.2 {
+ Tcl_Main able to handle non-blocking stdin
+ } -constraints {
+ exec
+ } -setup {
+ catch {set f [open "|[list [interpreter]]" w+]}
+ } -body {
+ type $f {
+ fconfigure stdin -blocking 0
+ puts SUCCESS
+ }
+ list [catch {gets $f} line] $line
+ } -cleanup {
+ close $f
+ } -result [list 0 SUCCESS]
+
+ test Tcl_Main-5.3 {
+ Tcl_Main handles stdin EOF in mid-command
+ } -constraints {
+ exec
+ } -setup {
+ catch {set f [open "|[list [interpreter]]" w+]}
+ catch {fconfigure $f -blocking 0}
+ } -body {
+ type $f "fconfigure stdin -eofchar \\032
+ if 1 \{\n\032"
+ variable wait
+ fileevent $f readable \
+ [list set [namespace which -variable wait] "child exit"]
+ set id [after 2000 [list set [namespace which -variable wait] timeout]]
+ vwait [namespace which -variable wait]
+ after cancel $id
+ set wait
+ } -cleanup {
+ if {[string equal timeout $wait] && [testConstraint unix]} {
+ exec kill [pid $f]
+ }
+ close $f
+ } -result {child exit}
+
+ test Tcl_Main-5.4 {
+ Tcl_Main handles stdin EOF in mid-command
+ } -constraints {
+ exec
+ } -setup {
+ set cmd {makeFile "if 1 \{" script}
+ catch {set f [open "|[list [interpreter]] < [list [eval $cmd]]" r]}
+ catch {fconfigure $f -blocking 0}
+ } -body {
+ variable wait
+ fileevent $f readable \
+ [list set [namespace which -variable wait] "child exit"]
+ set id [after 2000 [list set [namespace which -variable wait] timeout]]
+ vwait [namespace which -variable wait]
+ after cancel $id
+ set wait
+ } -cleanup {
+ if {[string equal timeout $wait] && [testConstraint unix]} {
+ exec kill [pid $f]
+ }
+ close $f
+ removeFile script
+ } -result {child exit}
+
+ test Tcl_Main-5.5 {
+ Tcl_Main: error raised in interactive mode
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {error foo} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "foo\n"
+
+ test Tcl_Main-5.6 {
+ Tcl_Main: interactive mode: errors don't stop command loop
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ error foo
+ puts bar
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "foo\nbar\n"
+
+ test Tcl_Main-5.7 {
+ Tcl_Main: interactive mode: closed stderr
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ close stderr
+ error foo
+ puts bar
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "bar\n"
+
+ test Tcl_Main-5.8 {
+ Tcl_Main: interactive mode: close stdin
+ -> main loop & [exit] & exit handlers
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ testsetmainloop
+ testexitmainloop
+ testexithandler create 0
+ close stdin
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "Exit MainLoop\nIn exit\neven 0\n"
+
+ test Tcl_Main-5.9 {
+ Tcl_Main: interactive mode: delete interp
+ -> main loop & exit handlers, but no [exit]
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ testsetmainloop
+ testexitmainloop
+ testexithandler create 0
+ testinterpdelete {}
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "Exit MainLoop\neven 0\n"
+
+ test Tcl_Main-5.10 {
+ Tcl_Main: exit main loop in mid-interactive command
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ catch {set f [open "|[list [interpreter]]" w+]}
+ catch {fconfigure $f -blocking 0}
+ } -body {
+ type $f "testsetmainloop
+ after 2000 testexitmainloop
+ puts \{1 2"
+ after 4000
+ type $f "3 4\}"
+ set code1 [catch {gets $f} line1]
+ set code2 [catch {gets $f} line2]
+ set code3 [catch {gets $f} line3]
+ list $code1 $line1 $code2 $line2 $code3 $line3
+ } -cleanup {
+ close $f
+ } -result [list 0 {Exit MainLoop} 0 {1 2} 0 {3 4}]
+
+ test Tcl_Main-5.11 {
+ Tcl_Main: EOF in interactive main loop
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ testexithandler create 0
+ after 0 testexitmainloop
+ testsetmainloop
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "Exit MainLoop\nIn exit\neven 0\n"
+
+ test Tcl_Main-5.12 {
+ Tcl_Main: close stdin in interactive main loop
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ testexithandler create 0
+ after 100 testexitmainloop
+ testsetmainloop
+ close stdin
+ puts "don't reach this"
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "Exit MainLoop\nIn exit\neven 0\n"
+
+ test Tcl_Main-5.13 {
+ Bug 1775878
+ } -constraints {
+ exec
+ } -setup {
+ catch {set f [open "|[list [interpreter]]" w+]}
+ } -body {
+ type $f "puts \\"
+ type $f return
+ list [catch {gets $f} line] $line
+ } -cleanup {
+ close $f
+ } -result [list 0 return]
+
+ # Tests Tcl_Main-6.*: interactive operations with prompts
+
+ test Tcl_Main-6.1 {
+ Tcl_Main: enable prompts with tcl_interactive
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {set tcl_interactive 1} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% "
+
+ test Tcl_Main-6.2 {
+ Tcl_Main: prompt deletes interp
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ set tcl_prompt1 {testinterpdelete {}}
+ set tcl_interactive 1
+ puts "not reached"
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n"
+
+ test Tcl_Main-6.3 {
+ Tcl_Main: prompt closes stdin
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ set tcl_prompt1 {close stdin}
+ set tcl_interactive 1
+ puts "not reached"
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n"
+
+ test Tcl_Main-6.4 {
+ Tcl_Main: interactive output, closed stdout
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ set tcl_interactive 1
+ close stdout
+ set a NO
+ puts stderr YES
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% YES\n"
+
+ test Tcl_Main-6.5 {
+ Tcl_Main: interactive entry to main loop
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ set tcl_interactive 1
+ testsetmainloop
+ testexitmainloop} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% % % Exit MainLoop\n"
+
+ test Tcl_Main-6.6 {
+ Tcl_Main: number of prompts during stdin close exit
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ set tcl_interactive 1
+ close stdin} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% "
+
+ test Tcl_Main-6.7 {
+ [unknown]: interactive auto-completion.
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ proc foo\{ x {}
+ set ::auto_noexec xxx
+ set tcl_interactive 1
+ foo y} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% % "
+
+ # Tests Tcl_Main-7.*: exiting
+
+ test Tcl_Main-7.1 {
+ Tcl_Main: [exit] defined as no-op -> still have exithandlers
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ proc exit args {}
+ testexithandler create 0
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "even 0\n"
+
+ test Tcl_Main-7.2 {
+ Tcl_Main: [exit] defined as no-op -> still have exithandlers
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ proc exit args {}
+ testexithandler create 0
+ after 0 testexitmainloop
+ testsetmainloop
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "Exit MainLoop\neven 0\n"
+
+ # Tests Tcl_Main-8.*: StdinProc operations
+
+ test Tcl_Main-8.1 {
+ StdinProc: handles non-blocking stdin
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ fconfigure stdin -blocking 0
+ testexitmainloop
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "Exit MainLoop\n"
+
+ test Tcl_Main-8.2 {
+ StdinProc: handles stdin EOF
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ testexithandler create 0
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ after 100 testexitmainloop
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "Exit MainLoop\nIn exit\neven 0\n"
+
+ test Tcl_Main-8.3 {
+ StdinProc: handles interactive stdin EOF
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ testexithandler create 0
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ set tcl_interactive 1} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% even 0\n"
+
+ test Tcl_Main-8.4 {
+ StdinProc: handles stdin close
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ after 100 testexitmainloop
+ after 0 puts 1
+ close stdin
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\nExit MainLoop\nIn exit\n"
+
+ test Tcl_Main-8.5 {
+ StdinProc: handles interactive stdin close
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ set tcl_interactive 1
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ after 100 testexitmainloop
+ after 0 puts 1
+ close stdin
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% % % after#0\n% after#1\n% 1\nExit MainLoop\nIn exit\n"
+
+ test Tcl_Main-8.6 {
+ StdinProc: handles event loop re-entry
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ after 100 {puts 1; set delay 1}
+ vwait delay
+ puts 2
+ testexitmainloop
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n2\nExit MainLoop\n"
+
+ test Tcl_Main-8.7 {
+ StdinProc: handling of errors
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ error foo
+ testexitmainloop
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "foo\nExit MainLoop\n"
+
+ test Tcl_Main-8.8 {
+ StdinProc: handling of errors, closed stderr
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ close stderr
+ error foo
+ testexitmainloop
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "Exit MainLoop\n"
+
+ test Tcl_Main-8.9 {
+ StdinProc: interactive output
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ set tcl_interactive 1
+ testexitmainloop} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% % Exit MainLoop\n"
+
+ test Tcl_Main-8.10 {
+ StdinProc: interactive output, closed stdout
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ close stdout
+ set tcl_interactive 1
+ testexitmainloop
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result {}
+
+ test Tcl_Main-8.11 {
+ StdinProc: prompt deletes interp
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ set tcl_prompt1 {testinterpdelete {}}
+ set tcl_interactive 1} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n"
+
+ test Tcl_Main-8.12 {
+ StdinProc: prompt closes stdin
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ set tcl_prompt1 {close stdin}
+ after 100 testexitmainloop
+ set tcl_interactive 1
+ puts "not reached"
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\nExit MainLoop\n"
+
+ test Tcl_Main-8.13 {
+ Bug 1775878
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ catch {set f [open "|[list [interpreter]]" w+]}
+ } -body {
+ exec [interpreter] << "testsetmainloop\nputs \\\npwd\ntestexitmainloop" >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "pwd\nExit MainLoop\n"
+
+ # Tests Tcl_Main-9.*: Prompt operations
+
+ test Tcl_Main-9.1 {
+ Prompt: custom prompt variables
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ set tcl_prompt1 {puts -nonewline stdout "one "}
+ set tcl_prompt2 {puts -nonewline stdout "two "}
+ set tcl_interactive 1
+ puts {This is
+ a test}} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\none two This is\n\t\ta test\none "
+
+ test Tcl_Main-9.2 {
+ Prompt: error in custom prompt variables
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ set tcl_prompt1 {error foo}
+ set tcl_interactive 1
+ set errorInfo} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\nfoo\n% foo\n while executing\n\"error foo\"\n (script\
+ that generates prompt)\nfoo\n% "
+
+ test Tcl_Main-9.3 {
+ Prompt: error in custom prompt variables, closed stderr
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ set tcl_prompt1 {close stderr; error foo}
+ set tcl_interactive 1} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% "
+
+ test Tcl_Main-9.4 {
+ Prompt: error in custom prompt variables, closed stdout
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ set tcl_prompt1 {close stdout; error foo}
+ set tcl_interactive 1} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\nfoo\n"
+
+ cd [workingDirectory]
+
+ cleanupTests
+}
+
+namespace delete ::tcl::test::main
+return
diff --git a/library/msgcat/tests/mathop.test b/library/msgcat/tests/mathop.test
new file mode 100644
index 0000000..f122b7b
--- /dev/null
+++ b/library/msgcat/tests/mathop.test
@@ -0,0 +1,1340 @@
+# Commands covered: ::tcl::mathop::...
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 2006 Donal K. Fellows
+# Copyright (c) 2006 Peter Spjuth
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2.1
+ namespace import -force ::tcltest::*
+}
+
+# A namespace to test that operators are exported and that they
+# work when imported
+namespace eval ::testmathop2 {
+ namespace import ::tcl::mathop::*
+}
+
+# Helper to test math ops.
+# Test different invokation variants and see that they do the same thing.
+# Byte compiled / non byte compiled version
+# Shared / unshared arguments
+# Original / imported
+proc TestOp {op args} {
+ set results {}
+
+ # Non byte compiled version, shared args
+ if {[catch {::tcl::mathop::$op {*}$args} res]} {
+ append res " $::errorCode"
+ }
+ lappend results $res
+
+ # Non byte compiled version, unshared args
+ set cmd ::tcl::mathop::\$op
+ foreach arg $args {
+ append cmd " \[format %s [list $arg]\]"
+ }
+ if {[catch $cmd res]} {
+ append res " $::errorCode"
+ }
+ lappend results $res
+
+ # Non byte compiled imported
+ if {[catch {::testmathop2::$op {*}$args} res]} {
+ append res " $::errorCode"
+ }
+ lappend results [string map {testmathop2 tcl::mathop} $res]
+
+ # BC version
+ set argList1 {}
+ set argList2 {}
+ set argList3 {}
+ for {set t 0} {$t < [llength $args]} {incr t} {
+ lappend argList1 a$t
+ lappend argList2 \$a$t
+ lappend argList3 "\[format %s \$a$t\]"
+ }
+ # Shared args
+ proc _TestOp $argList1 "::tcl::mathop::$op [join $argList2]"
+ # Unshared args
+ proc _TestOp2 $argList1 "::tcl::mathop::$op [join $argList3]"
+ # Imported
+ proc _TestOp3 $argList1 "::testmathop2::$op [join $argList2]"
+
+ set ::tcl_traceCompile 0 ;# Set to 2 to help with debug
+ if {[catch {_TestOp {*}$args} res]} {
+ append res " $::errorCode"
+ }
+ set ::tcl_traceCompile 0
+ lappend results $res
+
+ if {[catch {_TestOp2 {*}$args} res]} {
+ append res " $::errorCode"
+ }
+ lappend results $res
+
+ if {[catch {_TestOp3 {*}$args} res]} {
+ append res " $::errorCode"
+ }
+ lappend results [string map {testmathop2 tcl::mathop} $res]
+
+ # Check that they do the same
+ set len [llength $results]
+ for {set i 0} {$i < ($len - 1)} {incr i} {
+ set res1 [lindex $results $i]
+ set res2 [lindex $results $i+1]
+ if {$res1 ne $res2} {
+ return "$i:($res1 != $res2)"
+ }
+ }
+ return [lindex $results 0]
+}
+
+# start of tests
+
+namespace eval ::testmathop {
+ namespace path ::tcl::mathop
+ variable op ;# stop surprises!
+
+ test mathop-1.1 {compiled +} { + } 0
+ test mathop-1.2 {compiled +} { + 1 } 1
+ test mathop-1.3 {compiled +} { + 1 2 } 3
+ test mathop-1.4 {compiled +} { + 1 2 3 } 6
+ test mathop-1.5 {compiled +} { + 1.0 2 3 } 6.0
+ test mathop-1.6 {compiled +} { + 1 2 3.0 } 6.0
+ test mathop-1.7 {compiled +} { + 100000000000 2 3 } 100000000005
+ test mathop-1.8 {compiled +} { + 1 2 300000000000 } 300000000003
+ test mathop-1.9 {compiled +} { + 1000000000000000000000 2 3 } 1000000000000000000005
+ test mathop-1.10 {compiled +} { + 1 2 3000000000000000000000 } 3000000000000000000003
+ test mathop-1.11 {compiled +: errors} -returnCodes error -body {
+ + x 0
+ } -result {can't use non-numeric string as operand of "+"}
+ test mathop-1.12 {compiled +: errors} -returnCodes error -body {
+ + nan 0
+ } -result {can't use non-numeric floating-point value as operand of "+"}
+ test mathop-1.13 {compiled +: errors} -returnCodes error -body {
+ + 0 x
+ } -result {can't use non-numeric string as operand of "+"}
+ test mathop-1.14 {compiled +: errors} -returnCodes error -body {
+ + 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "+"}
+ test mathop-1.15 {compiled +: errors} -returnCodes error -body {
+ + 0o8 0
+ } -result {can't use invalid octal number as operand of "+"}
+ test mathop-1.16 {compiled +: errors} -returnCodes error -body {
+ + 0 0o8
+ } -result {can't use invalid octal number as operand of "+"}
+ test mathop-1.17 {compiled +: errors} -returnCodes error -body {
+ + 0 [error expectedError]
+ } -result expectedError
+ test mathop-1.18 {compiled +: argument processing order} -body {
+ # Bytecode compilation known hard for 3+ arguments
+ list [catch {
+ + [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+ set op +
+ test mathop-1.19 {interpreted +} { $op } 0
+ test mathop-1.20 {interpreted +} { $op 1 } 1
+ test mathop-1.21 {interpreted +} { $op 1 2 } 3
+ test mathop-1.22 {interpreted +} { $op 1 2 3 } 6
+ test mathop-1.23 {interpreted +} { $op 1.0 2 3 } 6.0
+ test mathop-1.24 {interpreted +} { $op 1 2 3.0 } 6.0
+ test mathop-1.25 {interpreted +} { $op 100000000000 2 3 } 100000000005
+ test mathop-1.26 {interpreted +} { $op 1 2 300000000000 } 300000000003
+ test mathop-1.27 {interpreted +} { $op 1000000000000000000000 2 3 } 1000000000000000000005
+ test mathop-1.28 {interpreted +} { $op 1 2 3000000000000000000000 } 3000000000000000000003
+ test mathop-1.29 {interpreted +: errors} -returnCodes error -body {
+ $op x 0
+ } -result {can't use non-numeric string as operand of "+"}
+ test mathop-1.30 {interpreted +: errors} -returnCodes error -body {
+ $op nan 0
+ } -result {can't use non-numeric floating-point value as operand of "+"}
+ test mathop-1.31 {interpreted +: errors} -returnCodes error -body {
+ $op 0 x
+ } -result {can't use non-numeric string as operand of "+"}
+ test mathop-1.32 {interpreted +: errors} -returnCodes error -body {
+ $op 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "+"}
+ test mathop-1.33 {interpreted +: errors} -returnCodes error -body {
+ $op 0o8 0
+ } -result {can't use invalid octal number as operand of "+"}
+ test mathop-1.34 {interpreted +: errors} -returnCodes error -body {
+ $op 0 0o8
+ } -result {can't use invalid octal number as operand of "+"}
+ test mathop-1.35 {interpreted +: errors} -returnCodes error -body {
+ $op 0 [error expectedError]
+ } -result expectedError
+ test mathop-1.36 {interpreted +: argument processing order} -body {
+ list [catch {
+ $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+
+ test mathop-2.1 {compiled *} { * } 1
+ test mathop-2.2 {compiled *} { * 2 } 2
+ test mathop-2.3 {compiled *} { * 2 3 } 6
+ test mathop-2.4 {compiled *} { * 2 3 4 } 24
+ test mathop-2.5 {compiled *} { * 1.0 2 3 } 6.0
+ test mathop-2.6 {compiled *} { * 1 2 3.0 } 6.0
+ test mathop-2.7 {compiled *} { * 100000000000 2 3 } 600000000000
+ test mathop-2.8 {compiled *} { * 1 2 300000000000 } 600000000000
+ test mathop-2.9 {compiled *} { * 1000000000000000000000 2 3 } 6000000000000000000000
+ test mathop-2.10 {compiled *} { * 1 2 3000000000000000000000 } 6000000000000000000000
+ test mathop-2.11 {compiled *: errors} -returnCodes error -body {
+ * x 0
+ } -result {can't use non-numeric string as operand of "*"}
+ test mathop-2.12 {compiled *: errors} -returnCodes error -body {
+ * nan 0
+ } -result {can't use non-numeric floating-point value as operand of "*"}
+ test mathop-2.13 {compiled *: errors} -returnCodes error -body {
+ * 0 x
+ } -result {can't use non-numeric string as operand of "*"}
+ test mathop-2.14 {compiled *: errors} -returnCodes error -body {
+ * 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "*"}
+ test mathop-2.15 {compiled *: errors} -returnCodes error -body {
+ * 0o8 0
+ } -result {can't use invalid octal number as operand of "*"}
+ test mathop-2.16 {compiled *: errors} -returnCodes error -body {
+ * 0 0o8
+ } -result {can't use invalid octal number as operand of "*"}
+ test mathop-2.17 {compiled *: errors} -returnCodes error -body {
+ * 0 [error expectedError]
+ } -result expectedError
+ test mathop-2.18 {compiled *: argument processing order} -body {
+ # Bytecode compilation known hard for 3+ arguments
+ list [catch {
+ * [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+ set op *
+ test mathop-2.19 {interpreted *} { $op } 1
+ test mathop-2.20 {interpreted *} { $op 2 } 2
+ test mathop-2.21 {interpreted *} { $op 2 3 } 6
+ test mathop-2.22 {interpreted *} { $op 2 3 4 } 24
+ test mathop-2.23 {interpreted *} { $op 1.0 2 3 } 6.0
+ test mathop-2.24 {interpreted *} { $op 1 2 3.0 } 6.0
+ test mathop-2.25 {interpreted *} { $op 100000000000 2 3 } 600000000000
+ test mathop-2.26 {interpreted *} { $op 1 2 300000000000 } 600000000000
+ test mathop-2.27 {interpreted *} { $op 1000000000000000000000 2 3 } 6000000000000000000000
+ test mathop-2.28 {interpreted *} { $op 1 2 3000000000000000000000 } 6000000000000000000000
+ test mathop-2.29 {interpreted *: errors} -returnCodes error -body {
+ $op x 0
+ } -result {can't use non-numeric string as operand of "*"}
+ test mathop-2.30 {interpreted *: errors} -returnCodes error -body {
+ $op nan 0
+ } -result {can't use non-numeric floating-point value as operand of "*"}
+ test mathop-2.31 {interpreted *: errors} -returnCodes error -body {
+ $op 0 x
+ } -result {can't use non-numeric string as operand of "*"}
+ test mathop-2.32 {interpreted *: errors} -returnCodes error -body {
+ $op 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "*"}
+ test mathop-2.33 {interpreted *: errors} -returnCodes error -body {
+ $op 0o8 0
+ } -result {can't use invalid octal number as operand of "*"}
+ test mathop-2.34 {interpreted *: errors} -returnCodes error -body {
+ $op 0 0o8
+ } -result {can't use invalid octal number as operand of "*"}
+ test mathop-2.35 {interpreted *: errors} -returnCodes error -body {
+ $op 0 [error expectedError]
+ } -result expectedError
+ test mathop-2.36 {interpreted *: argument processing order} -body {
+ list [catch {
+ $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+
+ test mathop-3.1 {compiled !} {! 0} 1
+ test mathop-3.2 {compiled !} {! 1} 0
+ test mathop-3.3 {compiled !} {! false} 1
+ test mathop-3.4 {compiled !} {! true} 0
+ test mathop-3.5 {compiled !} {! 0.0} 1
+ test mathop-3.6 {compiled !} {! 10000000000} 0
+ test mathop-3.7 {compiled !} {! 10000000000000000000000000} 0
+ test mathop-3.8 {compiled !: errors} -body {
+ ! foobar
+ } -returnCodes error -result {can't use non-numeric string as operand of "!"}
+ test mathop-3.9 {compiled !: errors} -body {
+ ! 0 0
+ } -returnCodes error -result "wrong # args: should be \"! boolean\""
+ test mathop-3.10 {compiled !: errors} -body {
+ !
+ } -returnCodes error -result "wrong # args: should be \"! boolean\""
+ set op !
+ test mathop-3.11 {interpreted !} {$op 0} 1
+ test mathop-3.12 {interpreted !} {$op 1} 0
+ test mathop-3.13 {interpreted !} {$op false} 1
+ test mathop-3.14 {interpreted !} {$op true} 0
+ test mathop-3.15 {interpreted !} {$op 0.0} 1
+ test mathop-3.16 {interpreted !} {$op 10000000000} 0
+ test mathop-3.17 {interpreted !} {$op 10000000000000000000000000} 0
+ test mathop-3.18 {interpreted !: errors} -body {
+ $op foobar
+ } -returnCodes error -result {can't use non-numeric string as operand of "!"}
+ test mathop-3.19 {interpreted !: errors} -body {
+ $op 0 0
+ } -returnCodes error -result "wrong # args: should be \"! boolean\""
+ test mathop-3.20 {interpreted !: errors} -body {
+ $op
+ } -returnCodes error -result "wrong # args: should be \"! boolean\""
+ test mathop-3.21 {compiled !: error} -returnCodes error -body {
+ ! NaN
+ } -result {can't use non-numeric floating-point value as operand of "!"}
+ test mathop-3.22 {interpreted !: error} -returnCodes error -body {
+ $op NaN
+ } -result {can't use non-numeric floating-point value as operand of "!"}
+
+ test mathop-4.1 {compiled ~} {~ 0} -1
+ test mathop-4.2 {compiled ~} {~ 1} -2
+ test mathop-4.3 {compiled ~} {~ 31} -32
+ test mathop-4.4 {compiled ~} {~ -127} 126
+ test mathop-4.5 {compiled ~} {~ -0} -1
+ test mathop-4.6 {compiled ~} {~ 10000000000} -10000000001
+ test mathop-4.7 {compiled ~} {~ 10000000000000000000000000} -10000000000000000000000001
+ test mathop-4.8 {compiled ~: errors} -body {
+ ~ foobar
+ } -returnCodes error -result {can't use non-numeric string as operand of "~"}
+ test mathop-4.9 {compiled ~: errors} -body {
+ ~ 0 0
+ } -returnCodes error -result "wrong # args: should be \"~ integer\""
+ test mathop-4.10 {compiled ~: errors} -body {
+ ~
+ } -returnCodes error -result "wrong # args: should be \"~ integer\""
+ test mathop-4.11 {compiled ~: errors} -returnCodes error -body {
+ ~ 0.0
+ } -result {can't use floating-point value as operand of "~"}
+ test mathop-4.12 {compiled ~: errors} -returnCodes error -body {
+ ~ NaN
+ } -result {can't use non-numeric floating-point value as operand of "~"}
+ set op ~
+ test mathop-4.13 {interpreted ~} {$op 0} -1
+ test mathop-4.14 {interpreted ~} {$op 1} -2
+ test mathop-4.15 {interpreted ~} {$op 31} -32
+ test mathop-4.16 {interpreted ~} {$op -127} 126
+ test mathop-4.17 {interpreted ~} {$op -0} -1
+ test mathop-4.18 {interpreted ~} {$op 10000000000} -10000000001
+ test mathop-4.19 {interpreted ~} {$op 10000000000000000000000000} -10000000000000000000000001
+ test mathop-4.20 {interpreted ~: errors} -body {
+ $op foobar
+ } -returnCodes error -result {can't use non-numeric string as operand of "~"}
+ test mathop-4.21 {interpreted ~: errors} -body {
+ $op 0 0
+ } -returnCodes error -result "wrong # args: should be \"~ integer\""
+ test mathop-4.22 {interpreted ~: errors} -body {
+ $op
+ } -returnCodes error -result "wrong # args: should be \"~ integer\""
+ test mathop-4.23 {interpreted ~: errors} -returnCodes error -body {
+ $op 0.0
+ } -result {can't use floating-point value as operand of "~"}
+ test mathop-4.24 {interpreted ~: errors} -returnCodes error -body {
+ $op NaN
+ } -result {can't use non-numeric floating-point value as operand of "~"}
+
+ test mathop-5.1 {compiled eq} {eq {} a} 0
+ test mathop-5.2 {compiled eq} {eq a a} 1
+ test mathop-5.3 {compiled eq} {eq a {}} 0
+ test mathop-5.4 {compiled eq} {eq a b} 0
+ test mathop-5.5 {compiled eq} { eq } 1
+ test mathop-5.6 {compiled eq} {eq a} 1
+ test mathop-5.7 {compiled eq} {eq a a a} 1
+ test mathop-5.8 {compiled eq} {eq a a b} 0
+ test mathop-5.9 {compiled eq} -body {
+ eq a b [error foobar]
+ } -returnCodes error -result foobar
+ test mathop-5.10 {compiled eq} {eq NaN Na NaN} 0
+ set op eq
+ test mathop-5.11 {interpreted eq} {$op {} a} 0
+ test mathop-5.12 {interpreted eq} {$op a a} 1
+ test mathop-5.13 {interpreted eq} {$op a {}} 0
+ test mathop-5.14 {interpreted eq} {$op a b} 0
+ test mathop-5.15 {interpreted eq} { $op } 1
+ test mathop-5.16 {interpreted eq} {$op a} 1
+ test mathop-5.17 {interpreted eq} {$op a a a} 1
+ test mathop-5.18 {interpreted eq} {$op a a b} 0
+ test mathop-5.19 {interpreted eq} -body {
+ $op a b [error foobar]
+ } -returnCodes error -result foobar
+ test mathop-5.20 {interpreted eq} {$op NaN Na NaN} 0
+
+ variable big1 12135435435354435435342423948763867876
+ variable big2 2746237174783836746262564892918327847
+ variable wide1 12345678912345
+ variable wide2 87321847232215
+ variable small1 87345
+ variable small2 16753
+
+ test mathop-6.1 {compiled &} { & } -1
+ test mathop-6.2 {compiled &} { & 1 } 1
+ test mathop-6.3 {compiled &} { & 1 2 } 0
+ test mathop-6.4 {compiled &} { & 3 7 6 } 2
+ test mathop-6.5 {compiled &} -returnCodes error -body {
+ & 1.0 2 3
+ } -result {can't use floating-point value as operand of "&"}
+ test mathop-6.6 {compiled &} -returnCodes error -body {
+ & 1 2 3.0
+ } -result {can't use floating-point value as operand of "&"}
+ test mathop-6.7 {compiled &} { & 100000000002 18 -126 } 2
+ test mathop-6.8 {compiled &} { & 0xff 0o377 333333333333 } 85
+ test mathop-6.9 {compiled &} { & 1000000000000000000002 18 -126 } 2
+ test mathop-6.10 {compiled &} { & 0xff 0o377 3333333333333333333333 } 85
+ test mathop-6.11 {compiled &: errors} -returnCodes error -body {
+ & x 0
+ } -result {can't use non-numeric string as operand of "&"}
+ test mathop-6.12 {compiled &: errors} -returnCodes error -body {
+ & nan 0
+ } -result {can't use non-numeric floating-point value as operand of "&"}
+ test mathop-6.13 {compiled &: errors} -returnCodes error -body {
+ & 0 x
+ } -result {can't use non-numeric string as operand of "&"}
+ test mathop-6.14 {compiled &: errors} -returnCodes error -body {
+ & 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "&"}
+ test mathop-6.15 {compiled &: errors} -returnCodes error -body {
+ & 0o8 0
+ } -result {can't use invalid octal number as operand of "&"}
+ test mathop-6.16 {compiled &: errors} -returnCodes error -body {
+ & 0 0o8
+ } -result {can't use invalid octal number as operand of "&"}
+ test mathop-6.17 {compiled &: errors} -returnCodes error -body {
+ & 0 [error expectedError]
+ } -result expectedError
+ test mathop-6.18 {compiled &: argument processing order} -body {
+ # Bytecode compilation known hard for 3+ arguments
+ list [catch {
+ & [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+ set op &
+ test mathop-6.19 {interpreted &} { $op } -1
+ test mathop-6.20 {interpreted &} { $op 1 } 1
+ test mathop-6.21 {interpreted &} { $op 1 2 } 0
+ test mathop-6.22 {interpreted &} { $op 3 7 6 } 2
+ test mathop-6.23 {interpreted &} -returnCodes error -body {
+ $op 1.0 2 3
+ } -result {can't use floating-point value as operand of "&"}
+ test mathop-6.24 {interpreted &} -returnCodes error -body {
+ $op 1 2 3.0
+ } -result {can't use floating-point value as operand of "&"}
+ test mathop-6.25 {interpreted &} { $op 100000000002 18 -126 } 2
+ test mathop-6.26 {interpreted &} { $op 0xff 0o377 333333333333 } 85
+ test mathop-6.27 {interpreted &} { $op 1000000000000000000002 18 -126 } 2
+ test mathop-6.28 {interpreted &} { $op 0xff 0o377 3333333333333333333333 } 85
+ test mathop-6.29 {interpreted &: errors} -returnCodes error -body {
+ $op x 0
+ } -result {can't use non-numeric string as operand of "&"}
+ test mathop-6.30 {interpreted &: errors} -returnCodes error -body {
+ $op nan 0
+ } -result {can't use non-numeric floating-point value as operand of "&"}
+ test mathop-6.31 {interpreted &: errors} -returnCodes error -body {
+ $op 0 x
+ } -result {can't use non-numeric string as operand of "&"}
+ test mathop-6.32 {interpreted &: errors} -returnCodes error -body {
+ $op 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "&"}
+ test mathop-6.33 {interpreted &: errors} -returnCodes error -body {
+ $op 0o8 0
+ } -result {can't use invalid octal number as operand of "&"}
+ test mathop-6.34 {interpreted &: errors} -returnCodes error -body {
+ $op 0 0o8
+ } -result {can't use invalid octal number as operand of "&"}
+ test mathop-6.35 {interpreted &: errors} -returnCodes error -body {
+ $op 0 [error expectedError]
+ } -result expectedError
+ test mathop-6.36 {interpreted &: argument processing order} -body {
+ list [catch {
+ $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+ test mathop-6.37 {& and bignums} {
+ list [& $big1 $big2] [$op $big1 $big2]
+ } {712439449294653815890598856501796 712439449294653815890598856501796}
+ test mathop-6.38 {& and bignums} {
+ list [& $big1 $wide2] [$op $big1 $wide2]
+ } {78521450111684 78521450111684}
+ test mathop-6.39 {& and bignums} {
+ list [& $big1 $small2] [$op $big1 $small2]
+ } {96 96}
+ test mathop-6.40 {& and bignums} {
+ list [& $wide1 $big2] [$op $wide1 $big2]
+ } {2371422390785 2371422390785}
+ test mathop-6.41 {& and bignums} {
+ list [& $wide1 $wide2] [$op $wide1 $wide2]
+ } {12275881497169 12275881497169}
+ test mathop-6.42 {& and bignums} {
+ list [& $wide1 $small2] [$op $wide1 $small2]
+ } {16721 16721}
+ test mathop-6.43 {& and bignums} {
+ list [& $small1 $big2] [$op $small1 $big2]
+ } {33 33}
+ test mathop-6.44 {& and bignums} {
+ list [& $small1 $wide2] [$op $small1 $wide2]
+ } {87057 87057}
+ test mathop-6.45 {& and bignums} {
+ list [& $small1 $small2] [$op $small1 $small2]
+ } {16689 16689}
+
+ test mathop-7.1 {compiled |} { | } 0
+ test mathop-7.2 {compiled |} { | 1 } 1
+ test mathop-7.3 {compiled |} { | 1 2 } 3
+ test mathop-7.4 {compiled |} { | 3 7 6 } 7
+ test mathop-7.5 {compiled |} -returnCodes error -body {
+ | 1.0 2 3
+ } -result {can't use floating-point value as operand of "|"}
+ test mathop-7.6 {compiled |} -returnCodes error -body {
+ | 1 2 3.0
+ } -result {can't use floating-point value as operand of "|"}
+ test mathop-7.7 {compiled |} { | 100000000002 18 -126 } -110
+ test mathop-7.8 {compiled |} { | 0xff 0o377 333333333333 } 333333333503
+ test mathop-7.9 {compiled |} { | 1000000000000000000002 18 -126 } -110
+ test mathop-7.10 {compiled |} { | 0xff 0o377 3333333333333333333333 } 3333333333333333333503
+ test mathop-7.11 {compiled |: errors} -returnCodes error -body {
+ | x 0
+ } -result {can't use non-numeric string as operand of "|"}
+ test mathop-7.12 {compiled |: errors} -returnCodes error -body {
+ | nan 0
+ } -result {can't use non-numeric floating-point value as operand of "|"}
+ test mathop-7.13 {compiled |: errors} -returnCodes error -body {
+ | 0 x
+ } -result {can't use non-numeric string as operand of "|"}
+ test mathop-7.14 {compiled |: errors} -returnCodes error -body {
+ | 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "|"}
+ test mathop-7.15 {compiled |: errors} -returnCodes error -body {
+ | 0o8 0
+ } -result {can't use invalid octal number as operand of "|"}
+ test mathop-7.16 {compiled |: errors} -returnCodes error -body {
+ | 0 0o8
+ } -result {can't use invalid octal number as operand of "|"}
+ test mathop-7.17 {compiled |: errors} -returnCodes error -body {
+ | 0 [error expectedError]
+ } -result expectedError
+ test mathop-7.18 {compiled |: argument processing order} -body {
+ # Bytecode compilation known hard for 3+ arguments
+ list [catch {
+ | [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+ set op |
+ test mathop-7.19 {interpreted |} { $op } 0
+ test mathop-7.20 {interpreted |} { $op 1 } 1
+ test mathop-7.21 {interpreted |} { $op 1 2 } 3
+ test mathop-7.22 {interpreted |} { $op 3 7 6 } 7
+ test mathop-7.23 {interpreted |} -returnCodes error -body {
+ $op 1.0 2 3
+ } -result {can't use floating-point value as operand of "|"}
+ test mathop-7.24 {interpreted |} -returnCodes error -body {
+ $op 1 2 3.0
+ } -result {can't use floating-point value as operand of "|"}
+ test mathop-7.25 {interpreted |} { $op 100000000002 18 -126 } -110
+ test mathop-7.26 {interpreted |} { $op 0xff 0o377 333333333333 } 333333333503
+ test mathop-7.27 {interpreted |} { $op 1000000000000000000002 18 -126 } -110
+ test mathop-7.28 {interpreted |} { $op 0xff 0o377 3333333333333333333333 } 3333333333333333333503
+ test mathop-7.29 {interpreted |: errors} -returnCodes error -body {
+ $op x 0
+ } -result {can't use non-numeric string as operand of "|"}
+ test mathop-7.30 {interpreted |: errors} -returnCodes error -body {
+ $op nan 0
+ } -result {can't use non-numeric floating-point value as operand of "|"}
+ test mathop-7.31 {interpreted |: errors} -returnCodes error -body {
+ $op 0 x
+ } -result {can't use non-numeric string as operand of "|"}
+ test mathop-7.32 {interpreted |: errors} -returnCodes error -body {
+ $op 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "|"}
+ test mathop-7.33 {interpreted |: errors} -returnCodes error -body {
+ $op 0o8 0
+ } -result {can't use invalid octal number as operand of "|"}
+ test mathop-7.34 {interpreted |: errors} -returnCodes error -body {
+ $op 0 0o8
+ } -result {can't use invalid octal number as operand of "|"}
+ test mathop-7.35 {interpreted |: errors} -returnCodes error -body {
+ $op 0 [error expectedError]
+ } -result expectedError
+ test mathop-7.36 {interpreted |: argument processing order} -body {
+ list [catch {
+ $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+ test mathop-7.37 {| and bignums} {
+ list [| $big1 $big2] [$op $big1 $big2]
+ } {14880960170688977527789098242825693927 14880960170688977527789098242825693927}
+ test mathop-7.38 {| and bignums} {
+ list [| $big1 $wide2] [$op $big1 $wide2]
+ } {12135435435354435435342432749160988407 12135435435354435435342432749160988407}
+ test mathop-7.39 {| and bignums} {
+ list [| $big1 $small2] [$op $big1 $small2]
+ } {12135435435354435435342423948763884533 12135435435354435435342423948763884533}
+ test mathop-7.40 {| and bignums} {
+ list [| $wide1 $big2] [$op $wide1 $big2]
+ } {2746237174783836746262574867174849407 2746237174783836746262574867174849407}
+ test mathop-7.41 {| and bignums} {
+ list [| $wide1 $wide2] [$op $wide1 $wide2]
+ } {87391644647391 87391644647391}
+ test mathop-7.42 {| and bignums} {
+ list [| $wide1 $small2] [$op $wide1 $small2]
+ } {12345678912377 12345678912377}
+ test mathop-7.43 {| and bignums} {
+ list [| $small1 $big2] [$op $small1 $big2]
+ } {2746237174783836746262564892918415159 2746237174783836746262564892918415159}
+ test mathop-7.44 {| and bignums} {
+ list [| $small1 $wide2] [$op $small1 $wide2]
+ } {87321847232503 87321847232503}
+ test mathop-7.45 {| and bignums} {
+ list [| $small1 $small2] [$op $small1 $small2]
+ } {87409 87409}
+
+ test mathop-8.1 {compiled ^} { ^ } 0
+ test mathop-8.2 {compiled ^} { ^ 1 } 1
+ test mathop-8.3 {compiled ^} { ^ 1 2 } 3
+ test mathop-8.4 {compiled ^} { ^ 3 7 6 } 2
+ test mathop-8.5 {compiled ^} -returnCodes error -body {
+ ^ 1.0 2 3
+ } -result {can't use floating-point value as operand of "^"}
+ test mathop-8.6 {compiled ^} -returnCodes error -body {
+ ^ 1 2 3.0
+ } -result {can't use floating-point value as operand of "^"}
+ test mathop-8.7 {compiled ^} { ^ 100000000002 18 -126 } -100000000110
+ test mathop-8.8 {compiled ^} { ^ 0xff 0o377 333333333333 } 333333333333
+ test mathop-8.9 {compiled ^} { ^ 1000000000000000000002 18 -126 } -1000000000000000000110
+ test mathop-8.10 {compiled ^} { ^ 0xff 0o377 3333333333333333333333 } 3333333333333333333333
+ test mathop-8.11 {compiled ^: errors} -returnCodes error -body {
+ ^ x 0
+ } -result {can't use non-numeric string as operand of "^"}
+ test mathop-8.12 {compiled ^: errors} -returnCodes error -body {
+ ^ nan 0
+ } -result {can't use non-numeric floating-point value as operand of "^"}
+ test mathop-8.13 {compiled ^: errors} -returnCodes error -body {
+ ^ 0 x
+ } -result {can't use non-numeric string as operand of "^"}
+ test mathop-8.14 {compiled ^: errors} -returnCodes error -body {
+ ^ 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "^"}
+ test mathop-8.15 {compiled ^: errors} -returnCodes error -body {
+ ^ 0o8 0
+ } -result {can't use invalid octal number as operand of "^"}
+ test mathop-8.16 {compiled ^: errors} -returnCodes error -body {
+ ^ 0 0o8
+ } -result {can't use invalid octal number as operand of "^"}
+ test mathop-8.17 {compiled ^: errors} -returnCodes error -body {
+ ^ 0 [error expectedError]
+ } -result expectedError
+ test mathop-8.18 {compiled ^: argument processing order} -body {
+ # Bytecode compilation known hard for 3+ arguments
+ list [catch {
+ ^ [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+ set op ^
+ test mathop-8.19 {interpreted ^} { $op } 0
+ test mathop-8.20 {interpreted ^} { $op 1 } 1
+ test mathop-8.21 {interpreted ^} { $op 1 2 } 3
+ test mathop-8.22 {interpreted ^} { $op 3 7 6 } 2
+ test mathop-8.23 {interpreted ^} -returnCodes error -body {
+ $op 1.0 2 3
+ } -result {can't use floating-point value as operand of "^"}
+ test mathop-8.24 {interpreted ^} -returnCodes error -body {
+ $op 1 2 3.0
+ } -result {can't use floating-point value as operand of "^"}
+ test mathop-8.25 {interpreted ^} { $op 100000000002 18 -126 } -100000000110
+ test mathop-8.26 {interpreted ^} { $op 0xff 0o377 333333333333 } 333333333333
+ test mathop-8.27 {interpreted ^} { $op 1000000000000000000002 18 -126 } -1000000000000000000110
+ test mathop-8.28 {interpreted ^} { $op 0xff 0o377 3333333333333333333333 } 3333333333333333333333
+ test mathop-8.29 {interpreted ^: errors} -returnCodes error -body {
+ $op x 0
+ } -result {can't use non-numeric string as operand of "^"}
+ test mathop-8.30 {interpreted ^: errors} -returnCodes error -body {
+ $op nan 0
+ } -result {can't use non-numeric floating-point value as operand of "^"}
+ test mathop-8.31 {interpreted ^: errors} -returnCodes error -body {
+ $op 0 x
+ } -result {can't use non-numeric string as operand of "^"}
+ test mathop-8.32 {interpreted ^: errors} -returnCodes error -body {
+ $op 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "^"}
+ test mathop-8.33 {interpreted ^: errors} -returnCodes error -body {
+ $op 0o8 0
+ } -result {can't use invalid octal number as operand of "^"}
+ test mathop-8.34 {interpreted ^: errors} -returnCodes error -body {
+ $op 0 0o8
+ } -result {can't use invalid octal number as operand of "^"}
+ test mathop-8.35 {interpreted ^: errors} -returnCodes error -body {
+ $op 0 [error expectedError]
+ } -result expectedError
+ test mathop-8.36 {interpreted ^: argument processing order} -body {
+ list [catch {
+ $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+ test mathop-8.37 {^ and bignums} {
+ list [^ $big1 $big2] [$op $big1 $big2]
+ } {14880247731239682873973207643969192131 14880247731239682873973207643969192131}
+ test mathop-8.38 {^ and bignums} {
+ list [^ $big1 $wide2] [$op $big1 $wide2]
+ } {12135435435354435435342354227710876723 12135435435354435435342354227710876723}
+ test mathop-8.39 {^ and bignums} {
+ list [^ $big1 $small2] [$op $big1 $small2]
+ } {12135435435354435435342423948763884437 12135435435354435435342423948763884437}
+ test mathop-8.40 {^ and bignums} {
+ list [^ $wide1 $big2] [$op $wide1 $big2]
+ } {2746237174783836746262572495752458622 2746237174783836746262572495752458622}
+ test mathop-8.41 {^ and bignums} {
+ list [^ $wide1 $wide2] [$op $wide1 $wide2]
+ } {75115763150222 75115763150222}
+ test mathop-8.42 {^ and bignums} {
+ list [^ $wide1 $small2] [$op $wide1 $small2]
+ } {12345678895656 12345678895656}
+ test mathop-8.43 {^ and bignums} {
+ list [^ $small1 $big2] [$op $small1 $big2]
+ } {2746237174783836746262564892918415126 2746237174783836746262564892918415126}
+ test mathop-8.44 {^ and bignums} {
+ list [^ $small1 $wide2] [$op $small1 $wide2]
+ } {87321847145446 87321847145446}
+ test mathop-8.45 {^ and bignums} {
+ list [^ $small1 $small2] [$op $small1 $small2]
+ } {70720 70720}
+
+ # TODO: % ** << >> - / == != < <= > >= ne in ni
+
+ test mathop-13.100 {compiled -: argument processing order} -body {
+ # Bytecode compilation known hard for 3+ arguments
+ list [catch {
+ - [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+
+ test mathop-14.100 {compiled /: argument processing order} -body {
+ # Bytecode compilation known hard for 3+ arguments
+ list [catch {
+ / [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+}
+
+test mathop-20.1 { zero args, return unit } {
+ set res {}
+ foreach op {+ * & ^ | ** < <= > >= == eq} {
+ lappend res [TestOp $op]
+ }
+ set res
+} {0 1 -1 0 0 1 1 1 1 1 1 1}
+test mathop-20.2 { zero args, not allowed } {
+ set exp {}
+ foreach op {~ ! << >> % != ne in ni - /} {
+ set res [TestOp $op]
+ if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
+ lappend exp 0
+ } else {
+ lappend exp $res
+ }
+ }
+ set exp
+} {0 0 0 0 0 0 0 0 0 0 0}
+test mathop-20.3 { one arg } {
+ set res {}
+ foreach val {7 8.3} {
+ foreach op {+ ** - * / < <= > >= == eq !} {
+ lappend res [TestOp $op $val]
+ }
+ }
+ set res
+} [list 7 7 -7 7 [expr {1.0/7.0}] 1 1 1 1 1 1 0 \
+ 8.3 8.3 -8.3 8.3 [expr {1.0/8.3}] 1 1 1 1 1 1 0]
+test mathop-20.4 { one arg, integer only ops } {
+ set res {}
+ foreach val {23} {
+ foreach op {& | ^ ~} {
+ lappend res [TestOp $op $val]
+ }
+ }
+ set res
+} [list 23 23 23 -24]
+test mathop-20.5 { one arg, not allowed } {
+ set exp {}
+ foreach op {% != ne in ni << >>} {
+ set res [TestOp $op 1]
+ if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
+ lappend exp 0
+ } else {
+ lappend exp $res
+ }
+ }
+ set exp
+} {0 0 0 0 0 0 0}
+test mathop-20.6 { one arg, error } {
+ set res {}
+ set exp {}
+ foreach vals {x {1 x} {1 1 x} {1 x 1}} {
+ # skipping - for now, knownbug...
+ foreach op {+ * / & | ^ **} {
+ lappend res [TestOp $op {*}$vals]
+ lappend exp "can't use non-numeric string as operand of \"$op\"\
+ ARITH DOMAIN {non-numeric string}"
+ }
+ }
+ foreach op {+ * / & | ^ **} {
+ lappend res [TestOp $op NaN 1]
+ lappend exp "can't use non-numeric floating-point value as operand of \"$op\"\
+ ARITH DOMAIN {non-numeric floating-point value}"
+ }
+ expr {$res eq $exp ? 0 : $res}
+} 0
+test mathop-20.7 { multi arg } {
+ set res {}
+ foreach vals {{1 2} {3 4 5} {4 3 2 1}} {
+ foreach op {+ - * /} {
+ lappend res [TestOp $op {*}$vals]
+ }
+ }
+ set res
+} [list 3 -1 2 0 12 -6 60 0 10 -2 24 0]
+test mathop-20.8 { multi arg, double } {
+ set res {}
+ foreach vals {{1.0 2} {3.0 4 5} {4 3.0 2 1}
+ {1.0 -1.0 1e-18} {1.0 1.0 1e-18}} {
+ foreach op {+ - * /} {
+ lappend res [TestOp $op {*}$vals]
+ }
+ }
+ set res
+} [list 3.0 -1.0 2.0 0.5 12.0 -6.0 60.0 0.15 10.0 -2.0 24.0 [expr {2.0/3}] 1e-18 2.0 -1e-18 [expr {-1.0/1e-18}] 2.0 -1e-18 1e-18 [expr {1.0/1e-18}]]
+
+test mathop-21.1 { unary ops, bitnot } {
+ set res {}
+ lappend res [TestOp ~ 7]
+ lappend res [TestOp ~ -5]
+ lappend res [TestOp ~ 354657483923456]
+ lappend res [TestOp ~ 123456789123456789123456789]
+ set res
+} [list -8 4 -354657483923457 -123456789123456789123456790]
+test mathop-21.2 { unary ops, logical not } {
+ set res {}
+ lappend res [TestOp ! 0]
+ lappend res [TestOp ! 1]
+ lappend res [TestOp ! true]
+ lappend res [TestOp ! false]
+ lappend res [TestOp ! 37]
+ lappend res [TestOp ! 8.5]
+ set res
+} [list 1 0 0 1 0 0]
+test mathop-21.3 { unary ops, negation } {
+ set res {}
+ lappend res [TestOp - 7.2]
+ lappend res [TestOp - -5]
+ lappend res [TestOp - -2147483648] ;# -2**31
+ lappend res [TestOp - -9223372036854775808] ;# -2**63
+ lappend res [TestOp - 354657483923456] ;# wide
+ lappend res [TestOp - 123456789123456789123456789] ;# big
+ set res
+} [list -7.2 5 2147483648 9223372036854775808 -354657483923456 \
+ -123456789123456789123456789]
+test mathop-21.4 { unary ops, inversion } {
+ set res {}
+ lappend res [TestOp / 1]
+ lappend res [TestOp / 5]
+ lappend res [TestOp / 5.6]
+ lappend res [TestOp / -8]
+ lappend res [TestOp / 354657483923456] ;# wide
+ lappend res [TestOp / 123456789123456789123456789] ;# big
+ set res
+} [list 1.0 0.2 0.17857142857142858 -0.125 \
+ 2.8196218755553604e-15 8.10000006561e-27]
+test mathop-21.5 { unary ops, bad values } {
+ set res {}
+ set exp {}
+ lappend res [TestOp / x]
+ lappend exp "can't use non-numeric string as operand of \"/\" ARITH DOMAIN {non-numeric string}"
+ lappend res [TestOp - x]
+ lappend exp "can't use non-numeric string as operand of \"-\" ARITH DOMAIN {non-numeric string}"
+ lappend res [TestOp ~ x]
+ lappend exp "can't use non-numeric string as operand of \"~\" ARITH DOMAIN {non-numeric string}"
+ lappend res [TestOp ! x]
+ lappend exp "can't use non-numeric string as operand of \"!\" ARITH DOMAIN {non-numeric string}"
+ lappend res [TestOp ~ 5.0]
+ lappend exp "can't use floating-point value as operand of \"~\" ARITH DOMAIN {floating-point value}"
+ expr {$res eq $exp ? 0 : $res}
+} 0
+test mathop-21.6 { unary ops, too many } {
+ set exp {}
+ foreach op {~ !} {
+ set res [TestOp $op 7 8]
+ if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
+ lappend exp 0
+ } else {
+ lappend exp $res
+ }
+ }
+ set exp
+} {0 0}
+
+test mathop-22.1 { bitwise ops } {
+ set res {}
+ foreach vals {5 {1 6} {1 2 3} {1 2 3 4}} {
+ foreach op {& | ^} {
+ lappend res [TestOp $op {*}$vals]
+ }
+ }
+ set res
+} [list 5 5 5 0 7 7 0 3 0 0 7 4]
+test mathop-22.2 { bitwise ops on bignums } {
+ set dig 50
+ set a 0x[string repeat 5 $dig]
+ set b 0x[string repeat 7 $dig]
+ set c 0x[string repeat 9 $dig]
+ set bn [expr {~$b}]
+ set cn [expr {~$c}]
+
+ set res {}
+ foreach vals [list [list $a $b] [list $a $c] [list $b $c] \
+ [list $a $bn] [list $bn $c] [list $bn $cn]] {
+ foreach op {& | ^} {
+ lappend res [TestOp $op {*}$vals]
+ }
+ }
+ set exp {}
+ foreach d {5 7 2 1 D C 1 F E 0 -D -D 8 -9 -1 -0 -E E} {
+ if {[string match "-*" $d]} {
+ set d [format %X [expr 15-0x[string range $d 1 end]]]
+ set val [expr -0x[string repeat $d $dig]-1]
+ } else {
+ set val [expr 0x[string repeat $d $dig]]
+ }
+ lappend exp $val
+ }
+ expr {$exp eq $res ? 1 : "($res != $exp"}
+} 1
+test mathop-22.3 { bitwise ops } {
+ set big1 12135435435354435435342423948763867876
+ set big2 2746237174783836746262564892918327847
+ set wide1 12345678912345
+ set wide2 87321847232215
+ set small1 87345
+ set small2 16753
+
+ set res {}
+ foreach op {& | ^} {
+ lappend res [TestOp $op $big1 $big2]
+ lappend res [TestOp $op $big1 $wide2]
+ lappend res [TestOp $op $big1 $small2]
+ lappend res [TestOp $op $wide1 $big2]
+ lappend res [TestOp $op $wide1 $wide2]
+ lappend res [TestOp $op $wide1 $small2]
+ lappend res [TestOp $op $small1 $big2]
+ lappend res [TestOp $op $small1 $wide2]
+ lappend res [TestOp $op $small1 $small2]
+ }
+ set res
+} [list \
+ 712439449294653815890598856501796 \
+ 78521450111684 \
+ 96 \
+ 2371422390785 \
+ 12275881497169 \
+ 16721 \
+ 33 \
+ 87057 \
+ 16689 \
+ 14880960170688977527789098242825693927 \
+ 12135435435354435435342432749160988407 \
+ 12135435435354435435342423948763884533 \
+ 2746237174783836746262574867174849407 \
+ 87391644647391 \
+ 12345678912377 \
+ 2746237174783836746262564892918415159 \
+ 87321847232503 \
+ 87409 \
+ 14880247731239682873973207643969192131 \
+ 12135435435354435435342354227710876723 \
+ 12135435435354435435342423948763884437 \
+ 2746237174783836746262572495752458622 \
+ 75115763150222 \
+ 12345678895656 \
+ 2746237174783836746262564892918415126 \
+ 87321847145446 \
+ 70720 \
+ ]
+test mathop-22.4 { unary ops, bad values } {
+ set res {}
+ set exp {}
+ foreach op {& | ^} {
+ lappend res [TestOp $op x 5]
+ lappend exp "can't use non-numeric string as operand of \"$op\" ARITH DOMAIN {non-numeric string}"
+ lappend res [TestOp $op 5 x]
+ lappend exp "can't use non-numeric string as operand of \"$op\" ARITH DOMAIN {non-numeric string}"
+ }
+ expr {$res eq $exp ? 0 : $res}
+} 0
+
+test mathop-23.1 { comparison ops, numerical } {
+ set res {}
+ set todo {5 {1 6} {1 2 2 3} {4 3 2 1} {5.0 5.0} {6 3 3 1} {5.0 5}}
+ lappend todo [list 2342476234762482734623842342 234827463876473 3434]
+ lappend todo [list 2653 453735910264536 453735910264537 2384762472634982746239847637]
+ lappend todo [list 2653 2384762472634982746239847637]
+ lappend todo [list 2653 -2384762472634982746239847637]
+ lappend todo [list 3789253678212653 -2384762472634982746239847637]
+ lappend todo [list 5.0 6 7.0 8 1e13 1945628567352654 1.1e20 \
+ 6734253647589123456784564378 2.3e50]
+ set a 7
+ lappend todo [list $a $a] ;# Same object
+ foreach vals $todo {
+ foreach op {< <= > >= == eq} {
+ lappend res [TestOp $op {*}$vals]
+ }
+ }
+ set res
+} [list 1 1 1 1 1 1 \
+ 1 1 0 0 0 0 \
+ 0 1 0 0 0 0 \
+ 0 0 1 1 0 0 \
+ 0 1 0 1 1 1 \
+ 0 0 0 1 0 0 \
+ 0 1 0 1 1 0 \
+ 0 0 1 1 0 0 \
+ 1 1 0 0 0 0 \
+ 1 1 0 0 0 0 \
+ 0 0 1 1 0 0 \
+ 0 0 1 1 0 0 \
+ 1 1 0 0 0 0 \
+ 0 1 0 1 1 1 \
+ ]
+test mathop-23.2 { comparison ops, string } {
+ set res {}
+ set todo {a {a b} {5 b b c} {d c b a} {xy xy} {gy ef ef ab}}
+ set a x
+ lappend todo [list $a $a]
+ foreach vals $todo {
+ foreach op {< <= > >= == eq} {
+ lappend res [TestOp $op {*}$vals]
+ }
+ }
+ set res
+} [list 1 1 1 1 1 1 \
+ 1 1 0 0 0 0 \
+ 0 1 0 0 0 0 \
+ 0 0 1 1 0 0 \
+ 0 1 0 1 1 1 \
+ 0 0 0 1 0 0 \
+ 0 1 0 1 1 1 \
+ ]
+test mathop-23.3 { comparison ops, nonequal} {
+ set res {}
+ foreach vals {{a b} {17.0 0x11} {foo foo} {10 10}} {
+ foreach op {!= ne} {
+ lappend res [TestOp $op {*}$vals]
+ }
+ }
+ set res
+} [list 1 1 0 1 0 0 0 0 ]
+
+test mathop-24.1 { binary ops } {
+ set res {}
+ foreach vals {{3 5} {17 7} {199 5} {293234675763434238476239486 17} \
+ {5 1} {0 7}} {
+ foreach op {% << >> in ni} {
+ lappend res [TestOp $op {*}$vals]
+ }
+ }
+ set res
+} [list 3 96 0 0 1 3 2176 0 0 1 4 6368 6 0 1 \
+ 14 38434855421664852505557661908992 2237203031642412097749 0 1 \
+ 0 10 2 0 1 0 0 0 0 1]
+test mathop-24.2 { binary ops, modulo } {
+ # Test different combinations to get all code paths
+ set res {}
+
+ set bigbig 14372423674564535234543545248972634923869
+ set big 12135435435354435435342423948763867876
+ set wide 12345678912345
+ set negwide -12345678912345
+ set small 5
+ set neg -5
+
+ lappend res [TestOp % $bigbig $big]
+ lappend res [TestOp % $wide $big]
+ lappend res [TestOp % $negwide $big]
+ lappend res [TestOp % $small $big]
+ lappend res [TestOp % $neg $big]
+ lappend res [TestOp % $small $wide]
+ lappend res [TestOp % $neg $wide]
+ lappend res [TestOp % $wide $small]
+ set res
+} [list 4068119104883679098115293636215358685 \
+ 12345678912345 \
+ 12135435435354435435342411603084955531 \
+ 5 \
+ 12135435435354435435342423948763867871 \
+ 5 \
+ 12345678912340 \
+ 0 \
+ ]
+test mathop-24.3 { binary ops, bad values } {
+ set res {}
+ set exp {}
+ foreach op {% << >>} {
+ lappend res [TestOp $op x 1]
+ lappend exp "can't use non-numeric string as operand of \"$op\" ARITH DOMAIN {non-numeric string}"
+ lappend res [TestOp $op 1 x]
+ lappend exp "can't use non-numeric string as operand of \"$op\" ARITH DOMAIN {non-numeric string}"
+ }
+ foreach op {% << >>} {
+ lappend res [TestOp $op 5.0 1]
+ lappend exp "can't use floating-point value as operand of \"$op\" ARITH DOMAIN {floating-point value}"
+ lappend res [TestOp $op 1 5.0]
+ lappend exp "can't use floating-point value as operand of \"$op\" ARITH DOMAIN {floating-point value}"
+ }
+ foreach op {in ni} {
+ lappend res [TestOp $op 5 "a b \{ c"]
+ lappend exp "unmatched open brace in list TCL VALUE LIST BRACE"
+ }
+ lappend res [TestOp % 5 0]
+ lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
+ lappend res [TestOp % 9838923468297346238478737647637375 0]
+ lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
+ lappend res [TestOp / 5 0]
+ lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
+ lappend res [TestOp / 9838923468297346238478737647637375 0]
+ lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
+ expr {$res eq $exp ? 0 : $res}
+} 0
+test mathop-24.4 { binary ops, negative shift } {
+ set res {}
+
+ set big -12135435435354435435342423948763867876
+ set wide -12345678912345
+ set small -1
+
+ lappend res [TestOp << 10 $big]
+ lappend res [TestOp << 10 $wide]
+ lappend res [TestOp << 10 $small]
+ lappend res [TestOp >> 10 $big]
+ lappend res [TestOp >> 10 $wide]
+ lappend res [TestOp >> 10 $small]
+
+ set exp [lrepeat 6 "negative shift argument NONE"]
+ expr {$res eq $exp ? 0 : $res}
+} 0
+test mathop-24.5 { binary ops, large shift } {
+ set res {}
+ set exp {}
+
+ set big 12135435435354435435342423948763867876
+ set wide 12345678912345
+ set small 1
+
+ lappend res [TestOp << 1 2147483648]
+ lappend exp "integer value too large to represent NONE"
+ lappend res [TestOp << 1 4294967296]
+ lappend exp "integer value too large to represent NONE"
+ lappend res [TestOp << $small $wide]
+ lappend exp "integer value too large to represent NONE"
+ lappend res [TestOp << $small $big]
+ lappend exp "integer value too large to represent NONE"
+ lappend res [TestOp >> $big $wide]
+ lappend exp 0
+ lappend res [TestOp >> $big $big]
+ lappend exp 0
+ lappend res [TestOp >> $small 70]
+ lappend exp 0
+ lappend res [TestOp >> $wide 70]
+ lappend exp 0
+ lappend res [TestOp >> -$big $wide]
+ lappend exp -1
+ lappend res [TestOp >> -$wide $wide]
+ lappend exp -1
+ lappend res [TestOp >> -$small $wide]
+ lappend exp -1
+ lappend res [TestOp >> -$small 70]
+ lappend exp -1
+ lappend res [TestOp >> -$wide 70]
+ lappend exp -1
+
+ expr {$res eq $exp ? 0 : $res}
+} 0
+test mathop-24.6 { binary ops, shift } {
+ # Test different combinations to get all code paths
+ set res {}
+
+ set bigbig 14372423674564535234543545248972634923869
+ set big 12135435435354435435342423948763867876
+ set wide 12345678912345
+ set negwide -12345678912345
+ set small 5
+ set neg -5
+
+ lappend res [TestOp << $wide $small]
+ lappend res [TestOp >> $wide $small]
+ set res
+} [list 395061725195040 \
+ 385802466010 \
+ ]
+test mathop-24.7 { binary ops, list search } {
+ set res {}
+
+ foreach op {in ni} {
+ lappend res [TestOp $op 5 {7 5 8}]
+ lappend res [TestOp $op hej {foo bar hej}]
+ lappend res [TestOp $op 5 {7 0x5 8}]
+ }
+ set res
+} [list 1 1 0 0 0 1]
+test mathop-24.8 { binary ops, too many } {
+ set exp {}
+ foreach op {<< >> % != ne in ni ~ !} {
+ set res [TestOp $op 7 8 9]
+ if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
+ lappend exp 0
+ } else {
+ lappend exp $res
+ }
+ }
+ set exp
+} {0 0 0 0 0 0 0 0 0}
+
+test mathop-25.1 { exp operator } {TestOp ** } 1
+test mathop-25.2 { exp operator } {TestOp ** 0 } 0
+test mathop-25.3 { exp operator } {TestOp ** 0 5} 0
+test mathop-25.4 { exp operator } {TestOp ** 7.5 } 7.5
+test mathop-25.5 { exp operator } {TestOp ** 1 5} 1
+test mathop-25.6 { exp operator } {TestOp ** 5 1} 5
+test mathop-25.7 { exp operator } {TestOp ** 4 3 2 1} 262144
+test mathop-25.8 { exp operator } {TestOp ** 5.5 4} 915.0625
+test mathop-25.9 { exp operator } {TestOp ** 16 3.5} 16384.0
+test mathop-25.10 { exp operator } {TestOp ** 3.5 0} 1.0
+test mathop-25.11 { exp operator } {TestOp ** 378 0} 1
+test mathop-25.12 { exp operator } {TestOp ** 7.8 1} 7.8
+test mathop-25.13 { exp operator } {TestOp ** 748 1} 748
+test mathop-25.14 { exp operator } {TestOp ** 1.6 -1} 0.625
+test mathop-25.15 { exp operator } {TestOp ** 683 -1} 0
+test mathop-25.16 { exp operator } {TestOp ** 1 -1} 1
+test mathop-25.17 { exp operator } {TestOp ** -1 -1} -1
+test mathop-25.18 { exp operator } {TestOp ** -1 -2} 1
+test mathop-25.19 { exp operator } {TestOp ** -1 3} -1
+test mathop-25.20 { exp operator } {TestOp ** -1 4} 1
+test mathop-25.21 { exp operator } {TestOp ** 2 63} 9223372036854775808
+test mathop-25.22 { exp operator } {TestOp ** 83756485763458746358734658473567847567473 2} 7015148907444467657897585474493757781161998914521537835809623408157343003287605729
+test mathop-25.23 { exp operator errors } {
+ set res {}
+ set exp {}
+
+ set huge [string repeat 145782 1000]
+ set big 12135435435354435435342423948763867876
+ set wide 12345678912345
+ set small 2
+
+ lappend res [TestOp ** 0 -5]
+ lappend exp "exponentiation of zero by negative power ARITH DOMAIN {exponentiation of zero by negative power}"
+ lappend res [TestOp ** 0.0 -5.0]
+ lappend exp "exponentiation of zero by negative power ARITH DOMAIN {exponentiation of zero by negative power}"
+ lappend res [TestOp ** $small $wide]
+ lappend exp "exponent too large NONE"
+ lappend res [TestOp ** 2 $big]
+ lappend exp "exponent too large NONE"
+ lappend res [TestOp ** $huge 2.1]
+ lappend exp "Inf"
+ lappend res [TestOp ** 2 foo]
+ lappend exp "can't use non-numeric string as operand of \"**\" ARITH DOMAIN {non-numeric string}"
+ lappend res [TestOp ** foo 2]
+ lappend exp "can't use non-numeric string as operand of \"**\" ARITH DOMAIN {non-numeric string}"
+
+ expr {$res eq $exp ? 0 : $res}
+} 0
+
+test mathop-26.1 { misc ops, size combinations } {
+ set big1 12135435435354435435342423948763867876
+ set big2 2746237174783836746262564892918327847
+ set wide1 87321847232215
+ set wide2 12345678912345
+ set small1 87345
+ set small2 16753
+
+ set res {}
+ foreach op {+ * - /} {
+ lappend res [TestOp $op $big1 $big2]
+ lappend res [TestOp $op $big1 $wide2]
+ lappend res [TestOp $op $big1 $small2]
+ lappend res [TestOp $op $wide1 $big2]
+ lappend res [TestOp $op $wide1 $wide2]
+ lappend res [TestOp $op $wide1 $small2]
+ lappend res [TestOp $op $small1 $big2]
+ lappend res [TestOp $op $small1 $wide2]
+ lappend res [TestOp $op $small1 $small2]
+ }
+ set res
+} [list \
+ 14881672610138272181604988841682195723 \
+ 12135435435354435435342436294442780221 \
+ 12135435435354435435342423948763884629 \
+ 2746237174783836746262652214765560062 \
+ 99667526144560 \
+ 87321847248968 \
+ 2746237174783836746262564892918415192 \
+ 12345678999690 \
+ 104098 \
+ 33326783924759424684447891401270222910405366244661685890993770489959542972 \
+ 149820189346379518024969783068410988366610965329220 \
+ 203304949848492856848291628413641078526628 \
+ 239806503039903915972546163440347114360602909991105 \
+ 1078047487961768329845194175 \
+ 1462902906681297895 \
+ 239870086031494220602303730571951345796215 \
+ 1078333324598774025 \
+ 1463290785 \
+ 9389198260570598689079859055845540029 \
+ 12135435435354435435342411603084955531 \
+ 12135435435354435435342423948763851123 \
+ -2746237174783836746262477571071095632 \
+ 74976168319870 \
+ 87321847215462 \
+ -2746237174783836746262564892918240502 \
+ -12345678825000 \
+ 70592 \
+ 4 \
+ 982970278225822587257201 \
+ 724373869477373332259441529801460 \
+ 0 \
+ 7 \
+ 5212311062 \
+ 0 \
+ 0 \
+ 5 \
+ ]
+test mathop-26.2 { misc ops, corner cases } {
+ set res {}
+ lappend res [TestOp - 0 -2147483648] ;# -2**31
+ lappend res [TestOp - 0 -9223372036854775808] ;# -2**63
+ lappend res [TestOp / -9223372036854775808 -1]
+ lappend res [TestOp * 2147483648 2]
+ lappend res [TestOp * 9223372036854775808 2]
+ set res
+} [list 2147483648 9223372036854775808 9223372036854775808 4294967296 18446744073709551616]
+
+if 0 {
+ # Compare ops to expr bytecodes
+ namespace import ::tcl::mathop::*
+ proc _X {a b c} {
+ set x [+ $a [- $b $c]]
+ set y [expr {$a + ($b - $c)}]
+ set z [< $a $b $c]
+ }
+ set ::tcl_traceCompile 2
+ _X 3 4 5
+ set ::tcl_traceCompile 0
+}
+
+# cleanup
+namespace delete ::testmathop
+namespace delete ::testmathop2
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/misc.test b/library/msgcat/tests/misc.test
new file mode 100644
index 0000000..fe19ebe
--- /dev/null
+++ b/library/msgcat/tests/misc.test
@@ -0,0 +1,76 @@
+# Commands covered: various
+#
+# This file contains a collection of miscellaneous Tcl tests that
+# don't fit naturally in any of the other test files. Many of these
+# tests are pathological cases that caused bugs in earlier Tcl
+# releases.
+#
+# Copyright (c) 1992-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testhashsystemhash [llength [info commands testhashsystemhash]]
+
+test misc-1.1 {error in variable ref. in command in array reference} {
+ proc tstProc {} {
+ global a
+
+ set tst $a([winfo name $zz])
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ }
+ set msg {}
+ list [catch tstProc msg] $msg
+} {1 {can't read "zz": no such variable}}
+test misc-1.2 {error in variable ref. in command in array reference} {
+ proc tstProc {} "
+ global a
+
+ set tst \$a(\[winfo name \$\{zz)
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ "
+ set msg {}
+ join [list [catch tstProc msg] $msg $::errorInfo] \n
+} [subst -novariables -nocommands {1
+missing close-brace for variable name
+missing close-brace for variable name
+ while executing
+"set tst $a([winfo name $\{zz)
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a ..."
+ (procedure "tstProc" line 4)
+ invoked from within
+"tstProc"}]
+
+for {set i 1} {$i<300} {incr i} {
+ test misc-2.$i {hash table with sys-alloc} testhashsystemhash \
+ "testhashsystemhash $i" OK
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/msgcat.test b/library/msgcat/tests/msgcat.test
new file mode 100644
index 0000000..0669810
--- /dev/null
+++ b/library/msgcat/tests/msgcat.test
@@ -0,0 +1,618 @@
+# This file contains a collection of tests for the msgcat package.
+# Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1998 Mark Harrison.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Contributions from Don Porter, NIST, 2002. (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.
+#
+# Note that after running these tests, entries will be left behind in the
+# message catalogs for locales foo, foo_BAR, and foo_BAR_baz.
+
+package require Tcl 8.2
+if {[catch {package require tcltest 2}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2 required."
+ return
+}
+if {[catch {package require msgcat 1.4.2}]} {
+ puts stderr "Skipping tests in [info script]. No msgcat 1.4.2 found to test."
+ return
+}
+
+namespace eval ::msgcat::test {
+ namespace import ::msgcat::*
+ namespace import ::tcltest::test
+ namespace import ::tcltest::cleanupTests
+ namespace import ::tcltest::temporaryDirectory
+ namespace import ::tcltest::make*
+ namespace import ::tcltest::remove*
+
+ # Tests msgcat-0.*: locale initialization
+
+ proc PowerSet {l} {
+ if {[llength $l] == 0} {return [list [list]]}
+ set element [lindex $l 0]
+ set rest [lrange $l 1 end]
+ set result [list]
+ foreach x [PowerSet $rest] {
+ lappend result [linsert $x 0 $element]
+ lappend result $x
+ }
+ return $result
+ }
+
+ variable envVars {LC_ALL LC_MESSAGES LANG}
+ variable count 0
+ variable body
+ variable result
+ variable setVars
+ foreach setVars [PowerSet $envVars] {
+ set result [string tolower [lindex $setVars 0]]
+ if {[string length $result] == 0} {
+ if {[info exists ::tcl::mac::locale]} {
+ set result [string tolower \
+ [msgcat::ConvertLocale $::tcl::mac::locale]]
+ } else {
+ set result c
+ }
+ }
+ test msgcat-0.$count [list \
+ locale initialization from environment variables $setVars \
+ ] -setup {
+ variable var
+ foreach var $envVars {
+ catch {variable $var $::env($var)}
+ catch {unset ::env($var)}
+ }
+ foreach var $setVars {
+ set ::env($var) $var
+ }
+ interp create [namespace current]::i
+ i eval [list package ifneeded msgcat [package provide msgcat] \
+ [package ifneeded msgcat [package provide msgcat]]]
+ i eval package require msgcat
+ } -cleanup {
+ interp delete [namespace current]::i
+ foreach var $envVars {
+ catch {unset ::env($var)}
+ catch {set ::env($var) [set [namespace current]::$var]}
+ }
+ } -body {i eval msgcat::mclocale} -result $result
+ incr count
+ }
+ catch {unset result}
+
+ # Could add tests of initialization from Windows registry here.
+ # Use a fake registry package.
+
+ # Tests msgcat-1.*: [mclocale], [mcpreferences]
+
+ test msgcat-1.3 {mclocale set, single element} -setup {
+ variable locale [mclocale]
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mclocale en
+ } -result en
+
+ test msgcat-1.4 {mclocale get, single element} -setup {
+ variable locale [mclocale]
+ mclocale en
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mclocale
+ } -result en
+
+ test msgcat-1.5 {mcpreferences, single element} -setup {
+ variable locale [mclocale]
+ mclocale en
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mcpreferences
+ } -result {en {}}
+
+ test msgcat-1.6 {mclocale set, two elements} -setup {
+ variable locale [mclocale]
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mclocale en_US
+ } -result en_us
+
+ test msgcat-1.7 {mclocale get, two elements} -setup {
+ variable locale [mclocale]
+ mclocale en_US
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mclocale
+ } -result en_us
+
+ test msgcat-1.8 {mcpreferences, two elements} -setup {
+ variable locale [mclocale]
+ mclocale en_US
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mcpreferences
+ } -result {en_us en {}}
+
+ test msgcat-1.9 {mclocale set, three elements} -setup {
+ variable locale [mclocale]
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mclocale en_US_funky
+ } -result en_us_funky
+
+ test msgcat-1.10 {mclocale get, three elements} -setup {
+ variable locale [mclocale]
+ mclocale en_US_funky
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mclocale
+ } -result en_us_funky
+
+ test msgcat-1.11 {mcpreferences, three elements} -setup {
+ variable locale [mclocale]
+ mclocale en_US_funky
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mcpreferences
+ } -result {en_us_funky en_us en {}}
+
+ test msgcat-1.12 {mclocale set, reject evil input} -setup {
+ variable locale [mclocale]
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mclocale /path/to/evil/code
+ } -returnCodes error -match glob -result {invalid newLocale value *}
+
+ test msgcat-1.13 {mclocale set, reject evil input} -setup {
+ variable locale [mclocale]
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mclocale looks/ok/../../../../but/is/path/to/evil/code
+ } -returnCodes error -match glob -result {invalid newLocale value *}
+
+ # Tests msgcat-2.*: [mcset], [mcmset], namespace partitioning
+
+ test msgcat-2.1 {mcset, global scope} {
+ namespace eval :: ::msgcat::mcset foo_BAR text1 text2
+ } {text2}
+
+ test msgcat-2.2 {mcset, global scope, default} {
+ namespace eval :: ::msgcat::mcset foo_BAR text3
+ } {text3}
+
+ test msgcat-2.2.1 {mcset, namespace overlap} {
+ namespace eval baz {::msgcat::mcset foo_BAR con1 con1baz}
+ } {con1baz}
+
+ test msgcat-2.3 {mcset, namespace overlap} -setup {
+ namespace eval bar {::msgcat::mcset foo_BAR con1 con1bar}
+ namespace eval baz {::msgcat::mcset foo_BAR con1 con1baz}
+ variable locale [mclocale]
+ mclocale foo_BAR
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ namespace eval bar {::msgcat::mc con1}
+ } -result con1bar
+
+ test msgcat-2.4 {mcset, namespace overlap} -setup {
+ namespace eval bar {::msgcat::mcset foo_BAR con1 con1bar}
+ namespace eval baz {::msgcat::mcset foo_BAR con1 con1baz}
+ variable locale [mclocale]
+ mclocale foo_BAR
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ namespace eval baz {::msgcat::mc con1}
+ } -result con1baz
+
+ test msgcat-2.5 {mcmset, global scope} -setup {
+ namespace eval :: {
+ ::msgcat::mcmset foo_BAR {
+ src1 trans1
+ src2 trans2
+ }
+ }
+ variable locale [mclocale]
+ mclocale foo_BAR
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ namespace eval :: {
+ ::msgcat::mc src1
+ }
+ } -result trans1
+
+ test msgcat-2.6 {mcmset, namespace overlap} -setup {
+ namespace eval bar {::msgcat::mcmset foo_BAR {con2 con2bar}}
+ namespace eval baz {::msgcat::mcmset foo_BAR {con2 con2baz}}
+ variable locale [mclocale]
+ mclocale foo_BAR
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ namespace eval bar {::msgcat::mc con2}
+ } -result con2bar
+
+ test msgcat-2.7 {mcmset, namespace overlap} -setup {
+ namespace eval bar {::msgcat::mcmset foo_BAR {con2 con2bar}}
+ namespace eval baz {::msgcat::mcmset foo_BAR {con2 con2baz}}
+ variable locale [mclocale]
+ mclocale foo_BAR
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ namespace eval baz {::msgcat::mc con2}
+ } -result con2baz
+
+ # Tests msgcat-3.*: [mcset], [mc], catalog "inheritance"
+ #
+ # Test mcset and mc, ensuring that more specific locales
+ # (e.g. en_UK) will search less specific locales
+ # (e.g. en) for translation strings.
+ #
+ # Do this for the 15 permutations of
+ # locales: {foo foo_BAR foo_BAR_baz}
+ # strings: {ov0 ov1 ov2 ov3 ov4}
+ # locale ROOT defines ov0, ov1, ov2, ov3
+ # locale foo defines ov1, ov2, ov3
+ # locale foo_BAR defines ov2, ov3
+ # locale foo_BAR_BAZ defines ov3
+ # (ov4 is defined in none)
+ # So,
+ # ov3 should be resolved in foo, foo_BAR, foo_BAR_baz
+ # ov2 should be resolved in foo, foo_BAR
+ # ov2 should resolve to foo_BAR in foo_BAR_baz
+ # ov1 should be resolved in foo
+ # ov1 should resolve to foo in foo_BAR, foo_BAR_baz
+ # ov4 should be resolved in none, and call mcunknown
+ #
+ variable count 2
+ variable result
+ array set result {
+ foo,ov0 ov0_ROOT foo,ov1 ov1_foo foo,ov2 ov2_foo
+ foo,ov3 ov3_foo foo,ov4 ov4
+ foo_BAR,ov0 ov0_ROOT foo_BAR,ov1 ov1_foo foo_BAR,ov2 ov2_foo_BAR
+ foo_BAR,ov3 ov3_foo_BAR foo_BAR,ov4 ov4
+ foo_BAR_baz,ov0 ov0_ROOT foo_BAR_baz,ov1 ov1_foo
+ foo_BAR_baz,ov2 ov2_foo_BAR
+ foo_BAR_baz,ov3 ov3_foo_BAR_baz foo_BAR_baz,ov4 ov4
+ }
+ variable loc
+ variable string
+ foreach loc {foo foo_BAR foo_BAR_baz} {
+ foreach string {ov0 ov1 ov2 ov3 ov4} {
+ test msgcat-3.$count {mcset, overlap} -setup {
+ mcset {} ov0 ov0_ROOT
+ mcset {} ov1 ov1_ROOT
+ mcset {} ov2 ov2_ROOT
+ mcset {} ov3 ov3_ROOT
+ mcset foo ov1 ov1_foo
+ mcset foo ov2 ov2_foo
+ mcset foo ov3 ov3_foo
+ mcset foo_BAR ov2 ov2_foo_BAR
+ mcset foo_BAR ov3 ov3_foo_BAR
+ mcset foo_BAR_baz ov3 ov3_foo_BAR_baz
+ variable locale [mclocale]
+ mclocale $loc
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc $string
+ } -result $result($loc,$string)
+ incr count
+ }
+ }
+ catch {unset result}
+
+ # Tests msgcat-4.*: [mcunknown]
+
+ test msgcat-4.2 {mcunknown, default} -setup {
+ mcset foo unk1 "unknown 1"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc unk1
+ } -result {unknown 1}
+
+ test msgcat-4.3 {mcunknown, default} -setup {
+ mcset foo unk1 "unknown 1"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc unk2
+ } -result unk2
+
+ test msgcat-4.4 {mcunknown, overridden} -setup {
+ rename ::msgcat::mcunknown SavedMcunknown
+ proc ::msgcat::mcunknown {dom s} {
+ return unknown:$dom:$s
+ }
+ mcset foo unk1 "unknown 1"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ rename ::msgcat::mcunknown {}
+ rename SavedMcunknown ::msgcat::mcunknown
+ } -body {
+ mc unk1
+ } -result {unknown 1}
+
+ test msgcat-4.5 {mcunknown, overridden} -setup {
+ rename ::msgcat::mcunknown SavedMcunknown
+ proc ::msgcat::mcunknown {dom s} {
+ return unknown:$dom:$s
+ }
+ mcset foo unk1 "unknown 1"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ rename ::msgcat::mcunknown {}
+ rename SavedMcunknown ::msgcat::mcunknown
+ } -body {
+ mc unk2
+ } -result {unknown:foo:unk2}
+
+ test msgcat-4.6 {mcunknown, uplevel context} -setup {
+ rename ::msgcat::mcunknown SavedMcunknown
+ proc ::msgcat::mcunknown {dom s} {
+ return "unknown:$dom:$s:[expr {[info level] - 1}]"
+ }
+ mcset foo unk1 "unknown 1"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ rename ::msgcat::mcunknown {}
+ rename SavedMcunknown ::msgcat::mcunknown
+ } -body {
+ mc unk2
+ } -result unknown:foo:unk2:[info level]
+
+ # Tests msgcat-5.*: [mcload]
+
+ variable locales {{} foo foo_BAR foo_BAR_baz}
+ set msgdir [makeDirectory msgdir]
+ foreach loc $locales {
+ if { $loc eq {} } {
+ set msg ROOT
+ } else {
+ set msg [string tolower $loc]
+ }
+ makeFile [list ::msgcat::mcset $loc abc abc-$loc] $msg.msg $msgdir
+ }
+ variable count 1
+ foreach loc {foo foo_BAR foo_BAR_baz} {
+ test msgcat-5.$count {mcload} -setup {
+ variable locale [mclocale]
+ mclocale $loc
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mcload $msgdir
+ } -result [expr { $count+1 }]
+ incr count
+ }
+
+ # Even though foo_BAR_notexist does not exist,
+ # foo_BAR, foo and the root should be loaded.
+ test msgcat-5.4 {mcload} -setup {
+ variable locale [mclocale]
+ mclocale foo_BAR_notexist
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mcload $msgdir
+ } -result 3
+
+ test msgcat-5.5 {mcload} -setup {
+ variable locale [mclocale]
+ mclocale no_FI_notexist
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mcload $msgdir
+ } -result 1
+
+ test msgcat-5.6 {mcload} -setup {
+ variable locale [mclocale]
+ mclocale foo
+ mcload $msgdir
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc abc
+ } -result abc-foo
+
+ test msgcat-5.7 {mcload} -setup {
+ variable locale [mclocale]
+ mclocale foo_BAR
+ mcload $msgdir
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc abc
+ } -result abc-foo_BAR
+
+ test msgcat-5.8 {mcload} -setup {
+ variable locale [mclocale]
+ mclocale foo_BAR_baz
+ mcload $msgdir
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc abc
+ } -result abc-foo_BAR_baz
+
+ test msgcat-5.9 {mcload} -setup {
+ variable locale [mclocale]
+ mclocale no_FI_notexist
+ mcload $msgdir
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc abc
+ } -result abc-
+
+ test msgcat-5.10 {mcload} -setup {
+ rename ::msgcat::mcunknown SavedMcunknown
+ proc ::msgcat::mcunknown {dom s} {
+ return unknown:$dom:$s
+ }
+ variable locale [mclocale]
+ mclocale no_FI_notexist
+ mcload $msgdir
+ } -cleanup {
+ mclocale $locale
+ rename ::msgcat::mcunknown {}
+ rename SavedMcunknown ::msgcat::mcunknown
+ } -body {
+ mc def
+ } -result unknown:no_fi_notexist:def
+
+ foreach loc $locales {
+ if { $loc eq {} } {
+ set msg ROOT
+ } else {
+ set msg [string tolower $loc]
+ }
+ removeFile $msg.msg $msgdir
+ }
+ removeDirectory msgdir
+
+ # Tests msgcat-6.*: [mcset], [mc] namespace inheritance
+#
+# Test mcset and mc, ensuring that resolution for messages
+# proceeds from the current ns to its parent and so on to the
+# global ns.
+#
+# Do this for the 12 permutations of
+# locales: foo
+# namespaces: foo foo::bar foo::bar::baz
+# strings: {ov1 ov2 ov3 ov4}
+# namespace ::foo defines ov1, ov2, ov3
+# namespace ::foo::bar defines ov2, ov3
+# namespace ::foo::bar::baz defines ov3
+#
+# ov4 is not defined in any namespace.
+#
+# So,
+# ov3 should be resolved in ::foo::bar::baz, ::foo::bar, ::foo;
+# ov2 should be resolved in ::foo, ::foo::bar
+# ov1 should be resolved in ::foo
+# ov4 should be resolved in none, and call mcunknown
+#
+
+ variable result
+ array set result {
+ foo,ov1 ov1_foo foo,ov2 ov2_foo foo,ov3 ov3_foo foo,ov4 ov4
+ foo::bar,ov1 ov1_foo foo::bar,ov2 ov2_foo_bar
+ foo::bar,ov3 ov3_foo_bar foo::bar,ov4 ov4 foo::bar::baz,ov1 ov1_foo
+ foo::bar::baz,ov2 ov2_foo_bar foo::bar::baz,ov3 ov3_foo_bar_baz
+ foo::bar::baz,ov4 ov4
+ }
+ variable count 1
+ variable ns
+ foreach ns {foo foo::bar foo::bar::baz} {
+ foreach string {ov1 ov2 ov3 ov4} {
+ test msgcat-6.$count {mcset, overlap} -setup {
+ namespace eval foo {
+ ::msgcat::mcset foo ov1 ov1_foo
+ ::msgcat::mcset foo ov2 ov2_foo
+ ::msgcat::mcset foo ov3 ov3_foo
+ namespace eval bar {
+ ::msgcat::mcset foo ov2 ov2_foo_bar
+ ::msgcat::mcset foo ov3 ov3_foo_bar
+ namespace eval baz {
+ ::msgcat::mcset foo ov3 "ov3_foo_bar_baz"
+ }
+ }
+
+ }
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ namespace delete foo
+ } -body {
+ namespace eval $ns [list ::msgcat::mc $string]
+ } -result $result($ns,$string)
+ incr count
+ }
+ }
+
+ # Tests msgcat-7.*: [mc] extra args processed by [format]
+
+ test msgcat-7.1 {mc extra args go through to format} -setup {
+ mcset foo format1 "this is a test"
+ mcset foo format2 "this is a %s"
+ mcset foo format3 "this is a %s %s"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc format1 "good test"
+ } -result "this is a test"
+
+ test msgcat-7.2 {mc extra args go through to format} -setup {
+ mcset foo format1 "this is a test"
+ mcset foo format2 "this is a %s"
+ mcset foo format3 "this is a %s %s"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc format2 "good test"
+ } -result "this is a good test"
+
+ test msgcat-7.3 {mc errors from format are propagated} -setup {
+ mcset foo format1 "this is a test"
+ mcset foo format2 "this is a %s"
+ mcset foo format3 "this is a %s %s"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ catch {mc format3 "good test"}
+ } -result 1
+
+ test msgcat-7.4 {mc, extra args are given to unknown} -setup {
+ mcset foo format1 "this is a test"
+ mcset foo format2 "this is a %s"
+ mcset foo format3 "this is a %s %s"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc "this is a %s" "good test"
+ } -result "this is a good test"
+
+ cleanupTests
+}
+namespace delete ::msgcat::test
+return
+
diff --git a/library/msgcat/tests/namespace-old.test b/library/msgcat/tests/namespace-old.test
new file mode 100644
index 0000000..1d8ba31
--- /dev/null
+++ b/library/msgcat/tests/namespace-old.test
@@ -0,0 +1,750 @@
+# Functionality covered: this file contains slightly modified versions of
+# the original tests written by Mike McLennan of Lucent Technologies for
+# the procedures in tclNamesp.c that implement Tcl's basic support for
+# namespaces. Other namespace-related tests appear in namespace.test
+# and variable.test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1997 Lucent Technologies
+# 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2.2
+ namespace import -force ::tcltest::*
+}
+
+# Clear out any namespaces called test_ns_*
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+
+test namespace-old-1.1 {usage for "namespace" command} {
+ list [catch {namespace} msg] $msg
+} {1 {wrong # args: should be "namespace subcommand ?arg ...?"}}
+test namespace-old-1.2 {global namespace's name is "::" or {}} {
+ list [namespace current] [namespace eval {} {namespace current}]
+} {:: ::}
+test namespace-old-1.3 {usage for "namespace eval"} {
+ list [catch {namespace eval} msg] $msg
+} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
+test namespace-old-1.4 {create new namespaces} {
+ list [lsort [namespace children :: test_ns_simple*]] \
+ [namespace eval test_ns_simple {}] \
+ [namespace eval test_ns_simple2 {}] \
+ [lsort [namespace children :: test_ns_simple*]]
+} {{} {} {} {::test_ns_simple ::test_ns_simple2}}
+test namespace-old-1.5 {access a new namespace} {
+ namespace eval test_ns_simple { namespace current }
+} {::test_ns_simple}
+test namespace-old-1.6 {usage for "namespace eval"} {
+ list [catch {namespace eval} msg] $msg
+} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
+test namespace-old-1.7 {usage for "namespace eval"} {
+ list [catch {namespace eval test_ns_xyzzy} msg] $msg
+} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
+test namespace-old-1.8 {command "namespace eval" concatenates args} {
+ namespace eval test_ns_simple namespace current
+} {::test_ns_simple}
+test namespace-old-1.9 {add elements to a namespace} {
+ namespace eval test_ns_simple {
+ variable test_ns_x 0
+ proc test {test_ns_x} {
+ return "test: $test_ns_x"
+ }
+ }
+} {}
+test namespace-old-1.10 {commands in a namespace} {
+ namespace eval test_ns_simple { info commands [namespace current]::*}
+} {::test_ns_simple::test}
+test namespace-old-1.11 {variables in a namespace} {
+ namespace eval test_ns_simple { info vars [namespace current]::* }
+} {::test_ns_simple::test_ns_x}
+test namespace-old-1.12 {global vars are separate from locals vars} {
+ list [test_ns_simple::test 123] [set test_ns_simple::test_ns_x]
+} {{test: 123} 0}
+test namespace-old-1.13 {add to an existing namespace} {
+ namespace eval test_ns_simple {
+ variable test_ns_y 123
+ proc _backdoor {cmd} {
+ eval $cmd
+ }
+ }
+} ""
+test namespace-old-1.14 {commands in a namespace} {
+ lsort [namespace eval test_ns_simple {info commands [namespace current]::*}]
+} {::test_ns_simple::_backdoor ::test_ns_simple::test}
+test namespace-old-1.15 {variables in a namespace} {
+ lsort [namespace eval test_ns_simple {info vars [namespace current]::*}]
+} {::test_ns_simple::test_ns_x ::test_ns_simple::test_ns_y}
+test namespace-old-1.16 {variables in a namespace} {
+ lsort [info vars test_ns_simple::*]
+} {::test_ns_simple::test_ns_x ::test_ns_simple::test_ns_y}
+test namespace-old-1.17 {commands in a namespace are hidden} {
+ list [catch "_backdoor {return yes!}" msg] $msg
+} {1 {invalid command name "_backdoor"}}
+test namespace-old-1.18 {using namespace qualifiers} {
+ list [catch "test_ns_simple::_backdoor {return yes!}" msg] $msg
+} {0 yes!}
+test namespace-old-1.19 {using absolute namespace qualifiers} {
+ list [catch "::test_ns_simple::_backdoor {return yes!}" msg] $msg
+} {0 yes!}
+test namespace-old-1.20 {variables in a namespace are hidden} {
+ list [catch "set test_ns_x" msg] $msg [catch "set test_ns_y" msg] $msg
+} {1 {can't read "test_ns_x": no such variable} 1 {can't read "test_ns_y": no such variable}}
+test namespace-old-1.21 {using namespace qualifiers} {
+ list [catch "set test_ns_simple::test_ns_x" msg] $msg \
+ [catch "set test_ns_simple::test_ns_y" msg] $msg
+} {0 0 0 123}
+test namespace-old-1.22 {using absolute namespace qualifiers} {
+ list [catch "set ::test_ns_simple::test_ns_x" msg] $msg \
+ [catch "set ::test_ns_simple::test_ns_y" msg] $msg
+} {0 0 0 123}
+test namespace-old-1.23 {variables can be accessed within a namespace} {
+ test_ns_simple::_backdoor {
+ variable test_ns_x
+ variable test_ns_y
+ return "$test_ns_x $test_ns_y"
+ }
+} {0 123}
+test namespace-old-1.24 {setting global variables} {
+ test_ns_simple::_backdoor {variable test_ns_x; set test_ns_x "new val"}
+ namespace eval test_ns_simple {set test_ns_x}
+} {new val}
+test namespace-old-1.25 {qualified variables don't need a global declaration} {
+ namespace eval test_ns_another { variable test_ns_x 456 }
+ set cmd {set ::test_ns_another::test_ns_x}
+ list [catch {test_ns_simple::_backdoor "$cmd some-value"} msg] $msg \
+ [eval $cmd]
+} {0 some-value some-value}
+test namespace-old-1.26 {namespace qualifiers are okay after $'s} {
+ namespace eval test_ns_simple { set test_ns_x 12; set test_ns_y 34 }
+ set cmd {list $::test_ns_simple::test_ns_x $::test_ns_simple::test_ns_y}
+ list [test_ns_simple::_backdoor $cmd] [eval $cmd]
+} {{12 34} {12 34}}
+test namespace-old-1.27 {can create commands with null names} {
+ proc test_ns_simple:: {args} {return $args}
+} {}
+
+# -----------------------------------------------------------------------
+# TEST: using "info" in namespace contexts
+# -----------------------------------------------------------------------
+test namespace-old-2.1 {querying: info commands} {
+ lsort [test_ns_simple::_backdoor {info commands [namespace current]::*}]
+} {::test_ns_simple:: ::test_ns_simple::_backdoor ::test_ns_simple::test}
+test namespace-old-2.2 {querying: info procs} {
+ lsort [test_ns_simple::_backdoor {info procs}]
+} {{} _backdoor test}
+test namespace-old-2.3 {querying: info vars} {
+ lsort [info vars test_ns_simple::*]
+} {::test_ns_simple::test_ns_x ::test_ns_simple::test_ns_y}
+test namespace-old-2.4 {querying: info vars} {
+ lsort [test_ns_simple::_backdoor {info vars [namespace current]::*}]
+} {::test_ns_simple::test_ns_x ::test_ns_simple::test_ns_y}
+test namespace-old-2.5 {querying: info locals} {
+ lsort [test_ns_simple::_backdoor {info locals}]
+} {cmd}
+test namespace-old-2.6 {querying: info exists} {
+ test_ns_simple::_backdoor {info exists test_ns_x}
+} {0}
+test namespace-old-2.7 {querying: info exists} {
+ test_ns_simple::_backdoor {info exists cmd}
+} {1}
+test namespace-old-2.8 {querying: info args} {
+ info args test_ns_simple::_backdoor
+} {cmd}
+test namespace-old-2.9 {querying: info body} {
+ string trim [info body test_ns_simple::test]
+} {return "test: $test_ns_x"}
+
+# -----------------------------------------------------------------------
+# TEST: namespace qualifiers, namespace tail
+# -----------------------------------------------------------------------
+test namespace-old-3.1 {usage for "namespace qualifiers"} {
+ list [catch "namespace qualifiers" msg] $msg
+} {1 {wrong # args: should be "namespace qualifiers string"}}
+test namespace-old-3.2 {querying: namespace qualifiers} {
+ list [namespace qualifiers ""] \
+ [namespace qualifiers ::] \
+ [namespace qualifiers x] \
+ [namespace qualifiers ::x] \
+ [namespace qualifiers foo::x] \
+ [namespace qualifiers ::foo::bar::xyz]
+} {{} {} {} {} foo ::foo::bar}
+test namespace-old-3.3 {usage for "namespace tail"} {
+ list [catch "namespace tail" msg] $msg
+} {1 {wrong # args: should be "namespace tail string"}}
+test namespace-old-3.4 {querying: namespace tail} {
+ list [namespace tail ""] \
+ [namespace tail ::] \
+ [namespace tail x] \
+ [namespace tail ::x] \
+ [namespace tail foo::x] \
+ [namespace tail ::foo::bar::xyz]
+} {{} {} x x x xyz}
+
+# -----------------------------------------------------------------------
+# TEST: delete commands and namespaces
+# -----------------------------------------------------------------------
+test namespace-old-4.1 {define test namespaces} {
+ namespace eval test_ns_delete {
+ namespace eval ns1 {
+ variable var1 1
+ proc cmd1 {} {return "cmd1"}
+ }
+ namespace eval ns2 {
+ variable var2 2
+ proc cmd2 {} {return "cmd2"}
+ }
+ namespace eval another {}
+ lsort [namespace children]
+ }
+} {::test_ns_delete::another ::test_ns_delete::ns1 ::test_ns_delete::ns2}
+test namespace-old-4.2 {it's okay to invoke "namespace delete" with no args} {
+ list [catch {namespace delete} msg] $msg
+} {0 {}}
+test namespace-old-4.3 {command "namespace delete" doesn't support patterns} {
+ set cmd {
+ namespace eval test_ns_delete {namespace delete ns*}
+ }
+ list [catch $cmd msg] $msg
+} {1 {unknown namespace "ns*" in namespace delete command}}
+test namespace-old-4.4 {command "namespace delete" handles multiple args} {
+ set cmd {
+ namespace eval test_ns_delete {
+ namespace delete \
+ {*}[namespace children [namespace current] ns?]
+ }
+ }
+ list [catch $cmd msg] $msg [namespace children test_ns_delete]
+} {0 {} ::test_ns_delete::another}
+
+# -----------------------------------------------------------------------
+# TEST: namespace hierarchy
+# -----------------------------------------------------------------------
+test namespace-old-5.1 {define nested namespaces} {
+ set test_ns_var_global "var in ::"
+ proc test_ns_cmd_global {} {return "cmd in ::"}
+ namespace eval test_ns_hier1 {
+ set test_ns_var_hier1 "particular to hier1"
+ proc test_ns_cmd_hier1 {} {return "particular to hier1"}
+ set test_ns_level 1
+ proc test_ns_show {} {return "[namespace current]: 1"}
+ namespace eval test_ns_hier2 {
+ set test_ns_var_hier2 "particular to hier2"
+ proc test_ns_cmd_hier2 {} {return "particular to hier2"}
+ set test_ns_level 2
+ proc test_ns_show {} {return "[namespace current]: 2"}
+ namespace eval test_ns_hier3a {}
+ namespace eval test_ns_hier3b {}
+ }
+ namespace eval test_ns_hier2a {}
+ namespace eval test_ns_hier2b {}
+ }
+} {}
+test namespace-old-5.2 {namespaces can be nested} {
+ list [namespace eval test_ns_hier1 {namespace current}] \
+ [namespace eval test_ns_hier1 {
+ namespace eval test_ns_hier2 {namespace current}
+ }]
+} {::test_ns_hier1 ::test_ns_hier1::test_ns_hier2}
+test namespace-old-5.3 {namespace qualifiers work in namespace command} {
+ list [namespace eval ::test_ns_hier1 {namespace current}] \
+ [namespace eval test_ns_hier1::test_ns_hier2 {namespace current}] \
+ [namespace eval ::test_ns_hier1::test_ns_hier2 {namespace current}]
+} {::test_ns_hier1 ::test_ns_hier1::test_ns_hier2 ::test_ns_hier1::test_ns_hier2}
+test namespace-old-5.4 {nested namespaces can access global namespace} {
+ list [namespace eval test_ns_hier1 {set test_ns_var_global}] \
+ [namespace eval test_ns_hier1 {test_ns_cmd_global}] \
+ [namespace eval test_ns_hier1::test_ns_hier2 {set test_ns_var_global}] \
+ [namespace eval test_ns_hier1::test_ns_hier2 {test_ns_cmd_global}]
+} {{var in ::} {cmd in ::} {var in ::} {cmd in ::}}
+test namespace-old-5.5 {variables in different namespaces don't conflict} {
+ list [set test_ns_hier1::test_ns_level] \
+ [set test_ns_hier1::test_ns_hier2::test_ns_level]
+} {1 2}
+test namespace-old-5.6 {commands in different namespaces don't conflict} {
+ list [test_ns_hier1::test_ns_show] \
+ [test_ns_hier1::test_ns_hier2::test_ns_show]
+} {{::test_ns_hier1: 1} {::test_ns_hier1::test_ns_hier2: 2}}
+test namespace-old-5.7 {nested namespaces don't see variables in parent} {
+ set cmd {
+ namespace eval test_ns_hier1::test_ns_hier2 {set test_ns_var_hier1}
+ }
+ list [catch $cmd msg] $msg
+} {1 {can't read "test_ns_var_hier1": no such variable}}
+test namespace-old-5.8 {nested namespaces don't see commands in parent} {
+ set cmd {
+ namespace eval test_ns_hier1::test_ns_hier2 {test_ns_cmd_hier1}
+ }
+ list [catch $cmd msg] $msg
+} {1 {invalid command name "test_ns_cmd_hier1"}}
+test namespace-old-5.9 {usage for "namespace children"} {
+ list [catch {namespace children test_ns_hier1 y z} msg] $msg
+} {1 {wrong # args: should be "namespace children ?name? ?pattern?"}}
+test namespace-old-5.10 {command "namespace children" must get valid namespace} -body {
+ namespace children xyzzy
+} -returnCodes error -result {namespace "xyzzy" not found in "::"}
+test namespace-old-5.11 {querying namespace children} {
+ lsort [namespace children :: test_ns_hier*]
+} {::test_ns_hier1}
+test namespace-old-5.12 {querying namespace children} {
+ lsort [namespace children test_ns_hier1]
+} {::test_ns_hier1::test_ns_hier2 ::test_ns_hier1::test_ns_hier2a ::test_ns_hier1::test_ns_hier2b}
+test namespace-old-5.13 {querying namespace children} {
+ lsort [namespace eval test_ns_hier1 {namespace children}]
+} {::test_ns_hier1::test_ns_hier2 ::test_ns_hier1::test_ns_hier2a ::test_ns_hier1::test_ns_hier2b}
+test namespace-old-5.14 {querying namespace children} {
+ lsort [namespace children test_ns_hier1::test_ns_hier2]
+} {::test_ns_hier1::test_ns_hier2::test_ns_hier3a ::test_ns_hier1::test_ns_hier2::test_ns_hier3b}
+test namespace-old-5.15 {querying namespace children} {
+ lsort [namespace eval test_ns_hier1::test_ns_hier2 {namespace children}]
+} {::test_ns_hier1::test_ns_hier2::test_ns_hier3a ::test_ns_hier1::test_ns_hier2::test_ns_hier3b}
+test namespace-old-5.16 {querying namespace children with patterns} {
+ lsort [namespace children test_ns_hier1::test_ns_hier2 test_ns_*]
+} {::test_ns_hier1::test_ns_hier2::test_ns_hier3a ::test_ns_hier1::test_ns_hier2::test_ns_hier3b}
+test namespace-old-5.17 {querying namespace children with patterns} {
+ lsort [namespace children test_ns_hier1::test_ns_hier2 *b]
+} {::test_ns_hier1::test_ns_hier2::test_ns_hier3b}
+test namespace-old-5.18 {usage for "namespace parent"} {
+ list [catch {namespace parent x y} msg] $msg
+} {1 {wrong # args: should be "namespace parent ?name?"}}
+test namespace-old-5.19 {command "namespace parent" must get valid namespace} -body {
+ namespace parent xyzzy
+} -returnCodes error -result {namespace "xyzzy" not found in "::"}
+test namespace-old-5.20 {querying namespace parent} {
+ list [namespace eval :: {namespace parent}] \
+ [namespace eval test_ns_hier1 {namespace parent}] \
+ [namespace eval test_ns_hier1::test_ns_hier2 {namespace parent}] \
+ [namespace eval test_ns_hier1::test_ns_hier2::test_ns_hier3a {namespace parent}] \
+} {{} :: ::test_ns_hier1 ::test_ns_hier1::test_ns_hier2}
+test namespace-old-5.21 {querying namespace parent for explicit namespace} {
+ list [namespace parent ::] \
+ [namespace parent test_ns_hier1] \
+ [namespace parent test_ns_hier1::test_ns_hier2] \
+ [namespace parent test_ns_hier1::test_ns_hier2::test_ns_hier3a]
+} {{} :: ::test_ns_hier1 ::test_ns_hier1::test_ns_hier2}
+
+# -----------------------------------------------------------------------
+# TEST: name resolution and caching
+# -----------------------------------------------------------------------
+test namespace-old-6.1 {relative ns names only looked up in current ns} {
+ namespace eval test_ns_cache1 {}
+ namespace eval test_ns_cache2 {}
+ namespace eval test_ns_cache2::test_ns_cache3 {}
+ set trigger {
+ namespace eval test_ns_cache2 {namespace current}
+ }
+ set trigger2 {
+ namespace eval test_ns_cache2::test_ns_cache3 {namespace current}
+ }
+ list [namespace eval test_ns_cache1 $trigger] \
+ [namespace eval test_ns_cache1 $trigger2]
+} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
+test namespace-old-6.2 {relative ns names only looked up in current ns} {
+ namespace eval test_ns_cache1::test_ns_cache2 {}
+ list [namespace eval test_ns_cache1 $trigger] \
+ [namespace eval test_ns_cache1 $trigger2]
+} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
+test namespace-old-6.3 {relative ns names only looked up in current ns} {
+ namespace eval test_ns_cache1::test_ns_cache2::test_ns_cache3 {}
+ list [namespace eval test_ns_cache1 $trigger] \
+ [namespace eval test_ns_cache1 $trigger2]
+} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
+test namespace-old-6.4 {relative ns names only looked up in current ns} {
+ namespace delete test_ns_cache1::test_ns_cache2
+ list [namespace eval test_ns_cache1 $trigger] \
+ [namespace eval test_ns_cache1 $trigger2]
+} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
+test namespace-old-6.5 {define test commands} {
+ proc test_ns_cache_cmd {} {
+ return "global version"
+ }
+ namespace eval test_ns_cache1 {
+ proc trigger {} {
+ test_ns_cache_cmd
+ }
+ }
+ test_ns_cache1::trigger
+} {global version}
+test namespace-old-6.6 {one-level check for command shadowing} {
+ proc test_ns_cache1::test_ns_cache_cmd {} {
+ return "cache1 version"
+ }
+ test_ns_cache1::trigger
+} {cache1 version}
+test namespace-old-6.7 {renaming commands changes command epoch} {
+ namespace eval test_ns_cache1 {
+ rename test_ns_cache_cmd test_ns_new
+ }
+ test_ns_cache1::trigger
+} {global version}
+test namespace-old-6.8 {renaming back handles shadowing} {
+ namespace eval test_ns_cache1 {
+ rename test_ns_new test_ns_cache_cmd
+ }
+ test_ns_cache1::trigger
+} {cache1 version}
+test namespace-old-6.9 {deleting commands changes command epoch} {
+ namespace eval test_ns_cache1 {
+ rename test_ns_cache_cmd ""
+ }
+ test_ns_cache1::trigger
+} {global version}
+test namespace-old-6.10 {define test namespaces} {
+ namespace eval test_ns_cache2 {
+ proc test_ns_cache_cmd {} {
+ return "global cache2 version"
+ }
+ }
+ namespace eval test_ns_cache1 {
+ proc trigger {} {
+ test_ns_cache2::test_ns_cache_cmd
+ }
+ }
+ namespace eval test_ns_cache1::test_ns_cache2 {
+ proc trigger {} {
+ test_ns_cache_cmd
+ }
+ }
+ list [test_ns_cache1::trigger] [test_ns_cache1::test_ns_cache2::trigger]
+} {{global cache2 version} {global version}}
+test namespace-old-6.11 {commands affect all parent namespaces} {
+ proc test_ns_cache1::test_ns_cache2::test_ns_cache_cmd {} {
+ return "cache2 version"
+ }
+ list [test_ns_cache1::trigger] [test_ns_cache1::test_ns_cache2::trigger]
+} {{cache2 version} {cache2 version}}
+test namespace-old-6.12 {define test variables} {
+ variable test_ns_cache_var "global version"
+ set trigger {set test_ns_cache_var}
+ namespace eval test_ns_cache1 $trigger
+} {global version}
+test namespace-old-6.13 {one-level check for variable shadowing} {
+ namespace eval test_ns_cache1 {
+ variable test_ns_cache_var "cache1 version"
+ }
+ namespace eval test_ns_cache1 $trigger
+} {cache1 version}
+test namespace-old-6.14 {deleting variables changes variable epoch} {
+ namespace eval test_ns_cache1 {
+ unset test_ns_cache_var
+ }
+ namespace eval test_ns_cache1 $trigger
+} {global version}
+test namespace-old-6.15 {define test namespaces} {
+ namespace eval test_ns_cache2 {
+ variable test_ns_cache_var "global cache2 version"
+ }
+ set trigger2 {set test_ns_cache2::test_ns_cache_var}
+ list [namespace eval test_ns_cache1 $trigger2] \
+ [namespace eval test_ns_cache1::test_ns_cache2 $trigger]
+} {{global cache2 version} {global version}}
+test namespace-old-6.16 {public variables affect all parent namespaces} {
+ variable test_ns_cache1::test_ns_cache2::test_ns_cache_var "cache2 version"
+ list [namespace eval test_ns_cache1 $trigger2] \
+ [namespace eval test_ns_cache1::test_ns_cache2 $trigger]
+} {{cache2 version} {cache2 version}}
+test namespace-old-6.17 {usage for "namespace which"} {
+ list [catch "namespace which -baz x" msg] $msg
+} {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
+test namespace-old-6.18 {usage for "namespace which"} {
+ # Presume no imported command called -command ;^)
+ namespace which -command
+} {}
+test namespace-old-6.19 {querying: namespace which -command} {
+ proc test_ns_cache1::test_ns_cache_cmd {} {
+ return "cache1 version"
+ }
+ list [namespace eval :: {namespace which test_ns_cache_cmd}] \
+ [namespace eval test_ns_cache1 {namespace which test_ns_cache_cmd}] \
+ [namespace eval :: {namespace which -command test_ns_cache_cmd}] \
+ [namespace eval test_ns_cache1 {namespace which -command test_ns_cache_cmd}]
+} {::test_ns_cache_cmd ::test_ns_cache1::test_ns_cache_cmd ::test_ns_cache_cmd ::test_ns_cache1::test_ns_cache_cmd}
+test namespace-old-6.20 {command "namespace which" may not find commands} {
+ namespace eval test_ns_cache1 {namespace which -command xyzzy}
+} {}
+test namespace-old-6.21 {querying: namespace which -variable} {
+ namespace eval test_ns_cache1::test_ns_cache2 {
+ namespace which -variable test_ns_cache_var
+ }
+} {::test_ns_cache1::test_ns_cache2::test_ns_cache_var}
+test namespace-old-6.22 {command "namespace which" may not find variables} {
+ namespace eval test_ns_cache1 {namespace which -variable xyzzy}
+} {}
+
+# -----------------------------------------------------------------------
+# TEST: uplevel/upvar across namespace boundaries
+# -----------------------------------------------------------------------
+test namespace-old-7.1 {define test namespace} {
+ namespace eval test_ns_uplevel {
+ variable x 0
+ variable y 1
+ proc show_vars {num} {
+ return [uplevel $num {info vars}]
+ }
+ proc test_uplevel {num} {
+ set a 0
+ set b 1
+ namespace eval ::test_ns_uplevel " return \[show_vars $num\] "
+ }
+ }
+} {}
+test namespace-old-7.2 {uplevel can access namespace call frame} {
+ list [expr {"x" in [test_ns_uplevel::test_uplevel 1]}] \
+ [expr {"y" in [test_ns_uplevel::test_uplevel 1]}]
+} {1 1}
+test namespace-old-7.3 {uplevel can go beyond namespace call frame} {
+ lsort [test_ns_uplevel::test_uplevel 2]
+} {a b num}
+test namespace-old-7.4 {uplevel can go up to global context} {
+ expr {[test_ns_uplevel::test_uplevel 3] == [info globals]}
+} {1}
+test namespace-old-7.5 {absolute call frame references work too} {
+ list [expr {"x" in [test_ns_uplevel::test_uplevel #2]}] \
+ [expr {"y" in [test_ns_uplevel::test_uplevel #2]}]
+} {1 1}
+test namespace-old-7.6 {absolute call frame references work too} {
+ lsort [test_ns_uplevel::test_uplevel #1]
+} {a b num}
+test namespace-old-7.7 {absolute call frame references work too} {
+ expr {[test_ns_uplevel::test_uplevel #0] == [info globals]}
+} {1}
+test namespace-old-7.8 {namespaces are included in the call stack} {
+ namespace eval test_ns_upvar {
+ variable scope "test_ns_upvar"
+ proc show_val {var num} {
+ upvar $num $var x
+ return $x
+ }
+ proc test_upvar {num} {
+ set scope "test_ns_upvar::test_upvar"
+ namespace eval ::test_ns_upvar " return \[show_val scope $num\] "
+ }
+ }
+} {}
+test namespace-old-7.9 {upvar can access namespace call frame} {
+ test_ns_upvar::test_upvar 1
+} {test_ns_upvar}
+test namespace-old-7.10 {upvar can go beyond namespace call frame} {
+ test_ns_upvar::test_upvar 2
+} {test_ns_upvar::test_upvar}
+test namespace-old-7.11 {absolute call frame references work too} {
+ test_ns_upvar::test_upvar #2
+} {test_ns_upvar}
+test namespace-old-7.12 {absolute call frame references work too} {
+ test_ns_upvar::test_upvar #1
+} {test_ns_upvar::test_upvar}
+
+# -----------------------------------------------------------------------
+# TEST: variable traces across namespace boundaries
+# -----------------------------------------------------------------------
+test namespace-old-8.1 {traces work across namespace boundaries} {
+ namespace eval test_ns_trace {
+ namespace eval foo {
+ variable x ""
+ }
+ variable status ""
+ proc monitor {name1 name2 op} {
+ variable status
+ lappend status "$op: $name1"
+ }
+ trace variable foo::x rwu [namespace code monitor]
+ }
+ set test_ns_trace::foo::x "yes!"
+ set test_ns_trace::foo::x
+ unset test_ns_trace::foo::x
+ namespace eval test_ns_trace { set status }
+} {{w: test_ns_trace::foo::x} {r: test_ns_trace::foo::x} {u: test_ns_trace::foo::x}}
+
+# -----------------------------------------------------------------------
+# TEST: imported commands
+# -----------------------------------------------------------------------
+test namespace-old-9.1 {empty "namespace export" list} {
+ list [catch "namespace export" msg] $msg
+} {0 {}}
+test namespace-old-9.2 {usage for "namespace export" command} {
+ list [catch "namespace export test_ns_trace::zzz" msg] $msg
+} {1 {invalid export pattern "test_ns_trace::zzz": pattern can't specify a namespace}}
+test namespace-old-9.3 {define test namespaces for import} {
+ namespace eval test_ns_export {
+ namespace export cmd1 cmd2 cmd3
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ proc cmd3 {args} {return "cmd3: $args"}
+ proc cmd4 {args} {return "cmd4: $args"}
+ proc cmd5 {args} {return "cmd5: $args"}
+ proc cmd6 {args} {return "cmd6: $args"}
+ }
+ lsort [info commands test_ns_export::*]
+} {::test_ns_export::cmd1 ::test_ns_export::cmd2 ::test_ns_export::cmd3 ::test_ns_export::cmd4 ::test_ns_export::cmd5 ::test_ns_export::cmd6}
+test namespace-old-9.4 {check export status} {
+ set x ""
+ namespace eval test_ns_import {
+ namespace export cmd1 cmd2
+ namespace import ::test_ns_export::*
+ }
+ foreach cmd [lsort [info commands test_ns_import::*]] {
+ lappend x $cmd
+ }
+ set x
+} {::test_ns_import::cmd1 ::test_ns_import::cmd2 ::test_ns_import::cmd3}
+test namespace-old-9.5 {empty import list in "namespace import" command} {
+ namespace eval test_ns_import_empty {
+ namespace import ::test_ns_export::*
+ try {
+ lsort [namespace import]
+ } finally {
+ namespace delete [namespace current]
+ }
+ }
+} {cmd1 cmd2 cmd3}
+# there is no namespace-old-9.6
+test namespace-old-9.7 {empty forget list for "namespace forget" command} {
+ namespace forget
+} {}
+catch {rename cmd1 {}}
+catch {rename cmd2 {}}
+catch {rename ncmd {}}
+catch {rename ncmd1 {}}
+catch {rename ncmd2 {}}
+test namespace-old-9.8 {only exported commands are imported} {
+ namespace import test_ns_import::cmd*
+ set x [lsort [info commands cmd*]]
+} {cmd1 cmd2}
+test namespace-old-9.9 {imported commands work just the same as original} {
+ list [cmd1 test 1 2 3] [test_ns_import::cmd1 test 4 5 6]
+} {{cmd1: test 1 2 3} {cmd1: test 4 5 6}}
+test namespace-old-9.10 {commands can be imported from many namespaces} {
+ namespace eval test_ns_import2 {
+ namespace export ncmd ncmd1 ncmd2
+ proc ncmd {args} {return "ncmd: $args"}
+ proc ncmd1 {args} {return "ncmd1: $args"}
+ proc ncmd2 {args} {return "ncmd2: $args"}
+ proc ncmd3 {args} {return "ncmd3: $args"}
+ }
+ namespace import test_ns_import2::*
+ lsort [concat [info commands cmd*] [info commands ncmd*]]
+} {cmd1 cmd2 ncmd ncmd1 ncmd2}
+test namespace-old-9.11 {imported commands can be removed by deleting them} {
+ rename cmd1 ""
+ lsort [concat [info commands cmd*] [info commands ncmd*]]
+} {cmd2 ncmd ncmd1 ncmd2}
+test namespace-old-9.12 {command "namespace forget" checks for valid namespaces} {
+ list [catch {namespace forget xyzzy::*} msg] $msg
+} {1 {unknown namespace in namespace forget pattern "xyzzy::*"}}
+test namespace-old-9.13 {command "namespace forget" ignores patterns that don't match} {
+ list [catch {namespace forget test_ns_import::xy*zzy} msg] $msg \
+ [lsort [info commands cmd?]]
+} {0 {} cmd2}
+test namespace-old-9.14 {imported commands can be removed} {
+ namespace forget test_ns_import::cmd?
+ list [lsort [info commands cmd?]] \
+ [catch {cmd1 another test} msg] $msg
+} {{} 1 {invalid command name "cmd1"}}
+test namespace-old-9.15 {existing commands can't be overwritten} {
+ proc cmd1 {x y} {
+ return [expr $x+$y]
+ }
+ list [catch {namespace import test_ns_import::cmd?} msg] $msg \
+ [cmd1 3 5]
+} {1 {can't import command "cmd1": already exists} 8}
+test namespace-old-9.16 {use "-force" option to override existing commands} {
+ list [cmd1 3 5] \
+ [namespace import -force test_ns_import::cmd?] \
+ [cmd1 3 5]
+} {8 {} {cmd1: 3 5}}
+test namespace-old-9.17 {commands can be imported into many namespaces} {
+ namespace eval test_ns_import_use {
+ namespace import ::test_ns_import::* ::test_ns_import2::ncmd?
+ lsort [concat [info commands ::test_ns_import_use::cmd*] \
+ [info commands ::test_ns_import_use::ncmd*]]
+ }
+} {::test_ns_import_use::cmd1 ::test_ns_import_use::cmd2 ::test_ns_import_use::ncmd1 ::test_ns_import_use::ncmd2}
+test namespace-old-9.18 {when command is deleted, imported commands go away} {
+ namespace eval test_ns_import { rename cmd1 "" }
+ list [info commands cmd1] \
+ [namespace eval test_ns_import_use {info commands cmd1}]
+} {{} {}}
+test namespace-old-9.19 {when namesp is deleted, all imported commands go away} {
+ namespace delete test_ns_import test_ns_import2
+ list [info commands cmd*] \
+ [info commands ncmd*] \
+ [namespace eval test_ns_import_use {info commands cmd*}] \
+ [namespace eval test_ns_import_use {info commands ncmd*}] \
+} {{} {} {} {}}
+
+# -----------------------------------------------------------------------
+# TEST: scoped values
+# -----------------------------------------------------------------------
+test namespace-old-10.1 {define namespace for scope test} {
+ namespace eval test_ns_inscope {
+ variable x "x-value"
+ proc show {args} {
+ return "show: $args"
+ }
+ proc do {args} {
+ return [eval $args]
+ }
+ list [set x] [show test]
+ }
+} {x-value {show: test}}
+test namespace-old-10.2 {command "namespace code" requires one argument} {
+ list [catch {namespace code} msg] $msg
+} {1 {wrong # args: should be "namespace code arg"}}
+test namespace-old-10.3 {command "namespace code" requires one argument} {
+ list [catch {namespace code first "second arg" third} msg] $msg
+} {1 {wrong # args: should be "namespace code arg"}}
+test namespace-old-10.4 {command "namespace code" gets current namesp context} {
+ namespace eval test_ns_inscope {
+ namespace code {"1 2 3" "4 5" 6}
+ }
+} {::namespace inscope ::test_ns_inscope {"1 2 3" "4 5" 6}}
+test namespace-old-10.5 {with one arg, first "scope" sticks} {
+ set sval [namespace eval test_ns_inscope {namespace code {one two}}]
+ namespace code $sval
+} {::namespace inscope ::test_ns_inscope {one two}}
+test namespace-old-10.6 {with many args, each "scope" adds new args} {
+ set sval [namespace eval test_ns_inscope {namespace code {one two}}]
+ namespace code "$sval three"
+} {::namespace inscope ::test_ns_inscope {one two} three}
+test namespace-old-10.7 {scoped commands work with eval} {
+ set cref [namespace eval test_ns_inscope {namespace code show}]
+ list [eval $cref "a" "b c" "d e f"]
+} {{show: a b c d e f}}
+test namespace-old-10.8 {scoped commands execute in namespace context} {
+ set cref [namespace eval test_ns_inscope {
+ namespace code {set x "some new value"}
+ }]
+ list [set test_ns_inscope::x] [eval $cref] [set test_ns_inscope::x]
+} {x-value {some new value} {some new value}}
+
+foreach cmd [info commands test_ns_*] {
+ rename $cmd ""
+}
+catch {rename cmd {}}
+catch {rename cmd1 {}}
+catch {rename cmd2 {}}
+catch {rename ncmd {}}
+catch {rename ncmd1 {}}
+catch {rename ncmd2 {}}
+catch {unset cref}
+catch {unset trigger}
+catch {unset trigger2}
+catch {unset sval}
+catch {unset msg}
+catch {unset x}
+catch {unset test_ns_var_global}
+catch {unset cmd}
+eval namespace delete [namespace children :: test_ns_*]
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/namespace.test b/library/msgcat/tests/namespace.test
new file mode 100644
index 0000000..f07d8cf
--- /dev/null
+++ b/library/msgcat/tests/namespace.test
@@ -0,0 +1,2944 @@
+# Functionality covered: this file contains a collection of tests for the
+# procedures in tclNamesp.c and tclEnsemble.c that implement Tcl's basic
+# support for namespaces. Other namespace-related tests appear in
+# variable.test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+testConstraint memory [llength [info commands memory]]
+
+#
+# REMARK: the tests for 'namespace upvar' are not done here. They are to be
+# found in the file 'upvar.test'.
+#
+
+# Clear out any namespaces called test_ns_*
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+
+proc fq {ns} {
+ if {[string match ::* $ns]} {return $ns}
+ set current [uplevel 1 {namespace current}]
+ return [string trimright $current :]::[string trimleft $ns :]
+}
+
+test namespace-1.1 {TclInitNamespaces, GetNamespaceFromObj, NamespaceChildrenCmd} {
+ namespace children :: test_ns_*
+} {}
+
+catch {unset l}
+test namespace-2.1 {Tcl_GetCurrentNamespace} {
+ list [namespace current] [namespace eval {} {namespace current}] \
+ [namespace eval {} {namespace current}]
+} {:: :: ::}
+test namespace-2.2 {Tcl_GetCurrentNamespace} {
+ set l {}
+ lappend l [namespace current]
+ namespace eval test_ns_1 {
+ lappend l [namespace current]
+ namespace eval foo {
+ lappend l [namespace current]
+ }
+ }
+ lappend l [namespace current]
+} {:: ::test_ns_1 ::test_ns_1::foo ::}
+
+test namespace-3.1 {Tcl_GetGlobalNamespace} {
+ namespace eval test_ns_1 {namespace eval foo {namespace eval bar {} } }
+ # namespace children uses Tcl_GetGlobalNamespace
+ namespace eval test_ns_1 {namespace children foo b*}
+} {::test_ns_1::foo::bar}
+
+test namespace-4.1 {Tcl_PushCallFrame with isProcCallFrame=1} {
+ namespace eval test_ns_1 {
+ variable v 123
+ proc p {} {
+ variable v
+ return $v
+ }
+ }
+ test_ns_1::p ;# does Tcl_PushCallFrame to push p's namespace
+} {123}
+test namespace-4.2 {Tcl_PushCallFrame with isProcCallFrame=0} {
+ namespace eval test_ns_1::baz {} ;# does Tcl_PushCallFrame to create baz
+ proc test_ns_1::baz::p {} {
+ variable v
+ set v 789
+ set v}
+ test_ns_1::baz::p
+} {789}
+
+test namespace-5.1 {Tcl_PopCallFrame, no vars} {
+ namespace eval test_ns_1::blodge {} ;# pushes then pops frame
+} {}
+test namespace-5.2 {Tcl_PopCallFrame, local vars must be deleted} {
+ proc test_ns_1::r {} {
+ set a 123
+ }
+ test_ns_1::r ;# pushes then pop's r's frame
+} {123}
+
+test namespace-6.1 {Tcl_CreateNamespace} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [lsort [namespace children :: test_ns_*]] \
+ [namespace eval test_ns_1 {namespace current}] \
+ [namespace eval test_ns_2 {namespace current}] \
+ [namespace eval ::test_ns_3 {namespace current}] \
+ [namespace eval ::test_ns_4 \
+ {namespace eval foo {namespace current}}] \
+ [namespace eval ::test_ns_5 \
+ {namespace eval ::test_ns_6 {namespace current}}] \
+ [lsort [namespace children :: test_ns_*]]
+} {{} ::test_ns_1 ::test_ns_2 ::test_ns_3 ::test_ns_4::foo ::test_ns_6 {::test_ns_1 ::test_ns_2 ::test_ns_3 ::test_ns_4 ::test_ns_5 ::test_ns_6}}
+test namespace-6.2 {Tcl_CreateNamespace, odd number of :'s in name is okay} {
+ list [namespace eval :::test_ns_1::::foo {namespace current}] \
+ [namespace eval test_ns_2:::::foo {namespace current}]
+} {::test_ns_1::foo ::test_ns_2::foo}
+test namespace-6.3 {Tcl_CreateNamespace, trailing ::s in ns name are ignored} {
+ list [catch {namespace eval test_ns_7::: {namespace current}} msg] $msg
+} {0 ::test_ns_7}
+test namespace-6.4 {Tcl_CreateNamespace, trailing ::s in ns name are ignored} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1:: {
+ namespace eval test_ns_2:: {}
+ namespace eval test_ns_3:: {}
+ }
+ lsort [namespace children ::test_ns_1]
+} [lsort {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_3}]
+test namespace-6.5 {Tcl_CreateNamespace, relative ns names now only looked up in current ns} {
+ set trigger {
+ namespace eval test_ns_2 {namespace current}
+ }
+ set l {}
+ lappend l [namespace eval test_ns_1 $trigger]
+ namespace eval test_ns_1::test_ns_2 {}
+ lappend l [namespace eval test_ns_1 $trigger]
+} {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_2}
+
+test namespace-7.1 {Tcl_DeleteNamespace, active call frames in ns} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1 {
+ proc p {} {
+ namespace delete [namespace current]
+ return [namespace current]
+ }
+ }
+ list [test_ns_1::p] [catch {test_ns_1::p} msg] $msg
+} {::test_ns_1 1 {invalid command name "test_ns_1::p"}}
+test namespace-7.2 {Tcl_DeleteNamespace, no active call frames in ns} {
+ namespace eval test_ns_2 {
+ proc p {} {
+ return [namespace current]
+ }
+ }
+ list [test_ns_2::p] [namespace delete test_ns_2]
+} {::test_ns_2 {}}
+test namespace-7.3 {recursive Tcl_DeleteNamespace, active call frames in ns} {
+ # [Bug 1355942]
+ namespace eval test_ns_2 {
+ set x 1
+ trace add variable x unset "namespace delete [namespace current];#"
+ namespace delete [namespace current]
+ }
+} {}
+test namespace-7.4 {recursive Tcl_DeleteNamespace, active call frames in ns} {
+ # [Bug 1355942]
+ namespace eval test_ns_2 {
+ proc x {} {}
+ trace add command x delete "namespace delete [namespace current];#"
+ namespace delete [namespace current]
+ }
+} {}
+test namespace-7.5 {recursive Tcl_DeleteNamespace, no active call frames in ns} {
+ # [Bug 1355942]
+ namespace eval test_ns_2 {
+ set x 1
+ trace add variable x unset "namespace delete [namespace current];#"
+ }
+ namespace delete test_ns_2
+} {}
+test namespace-7.6 {recursive Tcl_DeleteNamespace, no active call frames in ns} {
+ # [Bug 1355942]
+ namespace eval test_ns_2 {
+ proc x {} {}
+ trace add command x delete "namespace delete [namespace current];#"
+ }
+ namespace delete test_ns_2
+} {}
+test namespace-7.7 {Bug 1655305} -setup {
+ interp create slave
+ # Can't invoke through the ensemble, since deleting the global namespace
+ # (indirectly, via deleting ::tcl) deletes the ensemble.
+ slave eval {rename ::tcl::info::commands ::infocommands}
+ slave hide infocommands
+ slave eval {
+ proc foo {} {
+ namespace delete ::
+ }
+ }
+} -body {
+ slave eval foo
+ slave invokehidden infocommands
+} -cleanup {
+ interp delete slave
+} -result {}
+
+
+test namespace-8.1 {TclTeardownNamespace, delete global namespace} {
+ catch {interp delete test_interp}
+ interp create test_interp
+ interp eval test_interp {
+ namespace eval test_ns_1 {
+ namespace export p
+ proc p {} {
+ return [namespace current]
+ }
+ }
+ namespace eval test_ns_2 {
+ namespace import ::test_ns_1::p
+ variable v 27
+ proc q {} {
+ variable v
+ return "[p] $v"
+ }
+ }
+ set x [test_ns_2::q]
+ catch {set xxxx}
+ }
+ list [interp eval test_interp {test_ns_2::q}] \
+ [interp eval test_interp {namespace delete ::}] \
+ [catch {interp eval test_interp {set a 123}} msg] $msg \
+ [interp delete test_interp]
+} {{::test_ns_1 27} {} 1 {invalid command name "set"} {}}
+test namespace-8.2 {TclTeardownNamespace, remove deleted ns from parent} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1::test_ns_2::test_ns_3a {proc p {} {}}
+ namespace eval test_ns_1::test_ns_2::test_ns_3b {proc q {} {}}
+ list [namespace children test_ns_1] \
+ [namespace delete test_ns_1::test_ns_2] \
+ [namespace children test_ns_1]
+} {::test_ns_1::test_ns_2 {} {}}
+test namespace-8.3 {TclTeardownNamespace, delete child namespaces} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1::test_ns_2::test_ns_3a {proc p {} {}}
+ namespace eval test_ns_1::test_ns_2::test_ns_3b {proc q {} {}}
+ list [namespace children test_ns_1] \
+ [namespace delete test_ns_1::test_ns_2] \
+ [namespace children test_ns_1] \
+ [catch {namespace children test_ns_1::test_ns_2} msg] $msg \
+ [info commands test_ns_1::test_ns_2::test_ns_3a::*]
+} {::test_ns_1::test_ns_2 {} {} 1 {namespace "test_ns_1::test_ns_2" not found in "::"} {}}
+test namespace-8.4 {TclTeardownNamespace, cmds imported from deleted ns go away} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_export {
+ namespace export cmd1 cmd2
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ }
+ namespace eval test_ns_import {
+ namespace import ::test_ns_export::*
+ proc p {} {return foo}
+ }
+ list [lsort [info commands test_ns_import::*]] \
+ [namespace delete test_ns_export] \
+ [info commands test_ns_import::*]
+} [list [lsort {::test_ns_import::p ::test_ns_import::cmd1 ::test_ns_import::cmd2}] {} ::test_ns_import::p]
+test namespace-8.5 {TclTeardownNamespace: preserve errorInfo; errorCode values} {
+ interp create slave
+ slave eval {trace add execution error leave {namespace delete :: ;#}}
+ catch {slave eval error foo bar baz}
+ interp delete slave
+ set ::errorInfo
+} {bar
+ invoked from within
+"slave eval error foo bar baz"}
+test namespace-8.6 {TclTeardownNamespace: preserve errorInfo; errorCode values} {
+ interp create slave
+ slave eval {trace add variable errorCode write {namespace delete :: ;#}}
+ catch {slave eval error foo bar baz}
+ interp delete slave
+ set ::errorInfo
+} {bar
+ invoked from within
+"slave eval error foo bar baz"}
+test namespace-8.7 {TclTeardownNamespace: preserve errorInfo; errorCode values} {
+ interp create slave
+ slave eval {trace add execution error leave {namespace delete :: ;#}}
+ catch {slave eval error foo bar baz}
+ interp delete slave
+ set ::errorCode
+} baz
+
+test namespace-9.1 {Tcl_Import, empty import pattern} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace eval test_ns_import {namespace import {}}} msg] $msg
+} {1 {empty import pattern}}
+test namespace-9.2 {Tcl_Import, unknown namespace in import pattern} {
+ list [catch {namespace eval test_ns_import {namespace import fred::x}} msg] $msg
+} {1 {unknown namespace in import pattern "fred::x"}}
+test namespace-9.3 {Tcl_Import, import ns == export ns} {
+ list [catch {namespace eval test_ns_import {namespace import ::test_ns_import::puts}} msg] $msg
+} {1 {import pattern "::test_ns_import::puts" tries to import from namespace "test_ns_import" into itself}}
+test namespace-9.4 {Tcl_Import, simple import} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_export {
+ namespace export cmd1
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ }
+ namespace eval test_ns_import {
+ namespace import ::test_ns_export::*
+ proc p {} {return [cmd1 123]}
+ }
+ test_ns_import::p
+} {cmd1: 123}
+test namespace-9.5 {Tcl_Import, can't redefine cmd unless allowOverwrite!=0} {
+ list [catch {namespace eval test_ns_import {namespace import ::test_ns_export::*}} msg] $msg
+} {0 {}}
+test namespace-9.6 {Tcl_Import, cmd redefinition ok if allowOverwrite!=0} {
+ namespace eval test_ns_import {
+ namespace import -force ::test_ns_export::*
+ cmd1 555
+ }
+} {cmd1: 555}
+test namespace-9.7 {Tcl_Import, links are preserved if cmd is redefined} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_export {
+ namespace export cmd1
+ proc cmd1 {args} {return "cmd1: $args"}
+ }
+ namespace eval test_ns_import {
+ namespace import -force ::test_ns_export::*
+ }
+ list [test_ns_import::cmd1 a b c] \
+ [test_ns_export::cmd1 d e f] \
+ [proc test_ns_export::cmd1 {args} {return "new1: $args"}] \
+ [namespace origin test_ns_import::cmd1] \
+ [namespace origin test_ns_export::cmd1] \
+ [test_ns_import::cmd1 g h i] \
+ [test_ns_export::cmd1 j k l]
+} {{cmd1: a b c} {cmd1: d e f} {} ::test_ns_export::cmd1 ::test_ns_export::cmd1 {new1: g h i} {new1: j k l}}
+
+test namespace-9.8 {Tcl_Import: Bug 1017299} -setup {
+ namespace eval one {
+ namespace export cmd
+ proc cmd {} {}
+ }
+ namespace eval two {
+ namespace export cmd
+ proc other args {}
+ }
+ namespace eval two \
+ [list namespace import [namespace current]::one::cmd]
+ namespace eval three \
+ [list namespace import [namespace current]::two::cmd]
+ namespace eval three {
+ rename cmd other
+ namespace export other
+ }
+} -body {
+ namespace eval two [list namespace import -force \
+ [namespace current]::three::other]
+ namespace origin two::other
+} -cleanup {
+ namespace delete one two three
+} -match glob -result *::one::cmd
+
+test namespace-9.9 {Tcl_Import: Bug 1017299} -setup {
+ namespace eval one {
+ namespace export cmd
+ proc cmd {} {}
+ }
+ namespace eval two namespace export cmd
+ namespace eval two \
+ [list namespace import [namespace current]::one::cmd]
+ namespace eval three namespace export cmd
+ namespace eval three \
+ [list namespace import [namespace current]::two::cmd]
+} -body {
+ namespace eval two [list namespace import -force \
+ [namespace current]::three::cmd]
+ namespace origin two::cmd
+} -cleanup {
+ namespace delete one two three
+} -returnCodes error -match glob -result {import pattern * would create a loop*}
+
+test namespace-10.1 {Tcl_ForgetImport, check for valid namespaces} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace forget xyzzy::*} msg] $msg
+} {1 {unknown namespace in namespace forget pattern "xyzzy::*"}}
+test namespace-10.2 {Tcl_ForgetImport, ignores patterns that don't match} {
+ namespace eval test_ns_export {
+ namespace export cmd1
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ }
+ namespace eval test_ns_import {
+ namespace forget ::test_ns_export::wombat
+ }
+} {}
+test namespace-10.3 {Tcl_ForgetImport, deletes matching imported cmds} {
+ namespace eval test_ns_import {
+ namespace import ::test_ns_export::*
+ proc p {} {return [cmd1 123]}
+ set l {}
+ lappend l [lsort [info commands ::test_ns_import::*]]
+ namespace forget ::test_ns_export::cmd1
+ lappend l [info commands ::test_ns_import::*]
+ lappend l [catch {cmd1 777} msg] $msg
+ }
+} [list [lsort {::test_ns_import::p ::test_ns_import::cmd1}] ::test_ns_import::p 1 {invalid command name "cmd1"}]
+
+test namespace-10.4 {Tcl_ForgetImport: Bug 560297} -setup {
+ namespace eval origin {
+ namespace export cmd
+ proc cmd {} {}
+ }
+ namespace eval unrelated {
+ proc cmd {} {}
+ }
+ namespace eval my \
+ [list namespace import [namespace current]::origin::cmd]
+} -body {
+ namespace eval my \
+ [list namespace forget [namespace current]::unrelated::cmd]
+ my::cmd
+} -cleanup {
+ namespace delete origin unrelated my
+}
+
+test namespace-10.5 {Tcl_ForgetImport: Bug 560297} -setup {
+ namespace eval origin {
+ namespace export cmd
+ proc cmd {} {}
+ }
+ namespace eval my \
+ [list namespace import [namespace current]::origin::cmd]
+ namespace eval my rename cmd newname
+} -body {
+ namespace eval my \
+ [list namespace forget [namespace current]::origin::cmd]
+ my::newname
+} -cleanup {
+ namespace delete origin my
+} -returnCodes error -match glob -result *
+
+test namespace-10.6 {Tcl_ForgetImport: Bug 560297} -setup {
+ namespace eval origin {
+ namespace export cmd
+ proc cmd {} {}
+ }
+ namespace eval my \
+ [list namespace import [namespace current]::origin::cmd]
+ namespace eval your {}
+ namespace eval my \
+ [list rename cmd [namespace current]::your::newname]
+} -body {
+ namespace eval your namespace forget newname
+ your::newname
+} -cleanup {
+ namespace delete origin my your
+} -returnCodes error -match glob -result *
+
+test namespace-10.7 {Tcl_ForgetImport: Bug 560297} -setup {
+ namespace eval origin {
+ namespace export cmd
+ proc cmd {} {}
+ }
+ namespace eval link namespace export cmd
+ namespace eval link \
+ [list namespace import [namespace current]::origin::cmd]
+ namespace eval link2 namespace export cmd
+ namespace eval link2 \
+ [list namespace import [namespace current]::link::cmd]
+ namespace eval my \
+ [list namespace import [namespace current]::link2::cmd]
+} -body {
+ namespace eval my \
+ [list namespace forget [namespace current]::origin::cmd]
+ my::cmd
+} -cleanup {
+ namespace delete origin link link2 my
+} -returnCodes error -match glob -result *
+
+test namespace-10.8 {Tcl_ForgetImport: Bug 560297} -setup {
+ namespace eval origin {
+ namespace export cmd
+ proc cmd {} {}
+ }
+ namespace eval link namespace export cmd
+ namespace eval link \
+ [list namespace import [namespace current]::origin::cmd]
+ namespace eval link2 namespace export cmd
+ namespace eval link2 \
+ [list namespace import [namespace current]::link::cmd]
+ namespace eval my \
+ [list namespace import [namespace current]::link2::cmd]
+} -body {
+ namespace eval my \
+ [list namespace forget [namespace current]::link::cmd]
+ my::cmd
+} -cleanup {
+ namespace delete origin link link2 my
+}
+
+test namespace-10.9 {Tcl_ForgetImport: Bug 560297} -setup {
+ namespace eval origin {
+ namespace export cmd
+ proc cmd {} {}
+ }
+ namespace eval link namespace export cmd
+ namespace eval link \
+ [list namespace import [namespace current]::origin::cmd]
+ namespace eval link2 namespace export cmd
+ namespace eval link2 \
+ [list namespace import [namespace current]::link::cmd]
+ namespace eval my \
+ [list namespace import [namespace current]::link2::cmd]
+} -body {
+ namespace eval my \
+ [list namespace forget [namespace current]::link2::cmd]
+ my::cmd
+} -cleanup {
+ namespace delete origin link link2 my
+} -returnCodes error -match glob -result *
+
+test namespace-11.1 {TclGetOriginalCommand, check if not imported cmd} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_export {
+ namespace export cmd1
+ proc cmd1 {args} {return "cmd1: $args"}
+ }
+ list [namespace origin set] [namespace origin test_ns_export::cmd1]
+} {::set ::test_ns_export::cmd1}
+test namespace-11.2 {TclGetOriginalCommand, directly imported cmd} {
+ namespace eval test_ns_import1 {
+ namespace import ::test_ns_export::*
+ namespace export *
+ proc p {} {namespace origin cmd1}
+ }
+ list [test_ns_import1::p] [namespace origin test_ns_import1::cmd1]
+} {::test_ns_export::cmd1 ::test_ns_export::cmd1}
+test namespace-11.3 {TclGetOriginalCommand, indirectly imported cmd} {
+ namespace eval test_ns_import2 {
+ namespace import ::test_ns_import1::*
+ proc q {} {return [cmd1 123]}
+ }
+ list [test_ns_import2::q] [namespace origin test_ns_import2::cmd1]
+} {{cmd1: 123} ::test_ns_export::cmd1}
+
+test namespace-12.1 {InvokeImportedCmd} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_export {
+ namespace export cmd1
+ proc cmd1 {args} {namespace current}
+ }
+ namespace eval test_ns_import {
+ namespace import ::test_ns_export::*
+ }
+ list [test_ns_import::cmd1]
+} {::test_ns_export}
+
+test namespace-13.1 {DeleteImportedCmd, deletes imported cmds} {
+ namespace eval test_ns_import {
+ set l {}
+ lappend l [info commands ::test_ns_import::*]
+ namespace forget ::test_ns_export::cmd1
+ lappend l [info commands ::test_ns_import::*]
+ }
+} {::test_ns_import::cmd1 {}}
+
+test namespace-14.1 {TclGetNamespaceForQualName, absolute names} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ variable v 10
+ namespace eval test_ns_1::test_ns_2 {
+ variable v 20
+ }
+ namespace eval test_ns_2 {
+ variable v 30
+ }
+ namespace eval test_ns_1 {
+ list $::v $::test_ns_2::v $::test_ns_1::test_ns_2::v \
+ [lsort [namespace children :: test_ns_*]]
+ }
+} [list 10 30 20 [lsort {::test_ns_1 ::test_ns_2}]]
+test namespace-14.2 {TclGetNamespaceForQualName, invalid absolute names} {
+ namespace eval test_ns_1 {
+ list [catch {set ::test_ns_777::v} msg] $msg \
+ [catch {namespace children test_ns_777} msg] $msg
+ }
+} {1 {can't read "::test_ns_777::v": no such variable} 1 {namespace "test_ns_777" not found in "::test_ns_1"}}
+test namespace-14.3 {TclGetNamespaceForQualName, relative names} {
+ namespace eval test_ns_1 {
+ list $v $test_ns_2::v
+ }
+} {10 20}
+test namespace-14.4 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
+ namespace eval test_ns_1::test_ns_2 {
+ namespace eval foo {}
+ }
+ namespace eval test_ns_1 {
+ list [namespace children test_ns_2] \
+ [catch {namespace children test_ns_1} msg] $msg
+ }
+} {::test_ns_1::test_ns_2::foo 1 {namespace "test_ns_1" not found in "::test_ns_1"}}
+test namespace-14.5 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
+ namespace eval ::test_ns_2 {
+ namespace eval bar {}
+ }
+ namespace eval test_ns_1 {
+ list [catch {namespace delete test_ns_2::bar} msg] $msg
+ }
+} {1 {unknown namespace "test_ns_2::bar" in namespace delete command}}
+test namespace-14.6 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
+ namespace eval test_ns_1::test_ns_2 {
+ namespace eval foo {}
+ }
+ namespace eval test_ns_1 {
+ list [namespace children test_ns_2] \
+ [catch {namespace children test_ns_1} msg] $msg
+ }
+} {::test_ns_1::test_ns_2::foo 1 {namespace "test_ns_1" not found in "::test_ns_1"}}
+test namespace-14.7 {TclGetNamespaceForQualName, ignore extra :s if ns} {
+ namespace children test_ns_1:::
+} {::test_ns_1::test_ns_2}
+test namespace-14.8 {TclGetNamespaceForQualName, ignore extra :s if ns} {
+ namespace children :::test_ns_1:::::test_ns_2:::
+} {::test_ns_1::test_ns_2::foo}
+test namespace-14.9 {TclGetNamespaceForQualName, extra ::s are significant for vars} {
+ set l {}
+ lappend l [catch {set test_ns_1::test_ns_2::} msg] $msg
+ namespace eval test_ns_1::test_ns_2 {variable {} 2525}
+ lappend l [set test_ns_1::test_ns_2::]
+} {1 {can't read "test_ns_1::test_ns_2::": no such variable} 2525}
+test namespace-14.10 {TclGetNamespaceForQualName, extra ::s are significant for vars} {
+ catch {unset test_ns_1::test_ns_2::}
+ set l {}
+ lappend l [catch {set test_ns_1::test_ns_2::} msg] $msg
+ set test_ns_1::test_ns_2:: 314159
+ lappend l [set test_ns_1::test_ns_2::]
+} {1 {can't read "test_ns_1::test_ns_2::": no such variable} 314159}
+test namespace-14.11 {TclGetNamespaceForQualName, extra ::s are significant for commands} {
+ catch {rename test_ns_1::test_ns_2:: {}}
+ set l {}
+ lappend l [catch {test_ns_1::test_ns_2:: hello} msg] $msg
+ proc test_ns_1::test_ns_2:: {args} {return "\{\}: $args"}
+ lappend l [test_ns_1::test_ns_2:: hello]
+} {1 {invalid command name "test_ns_1::test_ns_2::"} {{}: hello}}
+test namespace-14.12 {TclGetNamespaceForQualName, extra ::s are significant for vars} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1 {
+ variable {}
+ set test_ns_1::(x) y
+ }
+ set test_ns_1::(x)
+} y
+test namespace-14.13 {TclGetNamespaceForQualName, namespace other than global ns can't have empty name} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace eval test_ns_1 {proc {} {} {}; namespace eval {} {}; {}}} msg] $msg
+} {1 {can't create namespace "": only global namespace can have empty name}}
+
+test namespace-15.1 {Tcl_FindNamespace, absolute name found} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_delete {
+ namespace eval test_ns_delete2 {}
+ proc cmd {args} {namespace current}
+ }
+ list [namespace delete ::test_ns_delete::test_ns_delete2] \
+ [namespace children ::test_ns_delete]
+} {{} {}}
+test namespace-15.2 {Tcl_FindNamespace, absolute name not found} {
+ list [catch {namespace delete ::test_ns_delete::test_ns_delete2} msg] $msg
+} {1 {unknown namespace "::test_ns_delete::test_ns_delete2" in namespace delete command}}
+test namespace-15.3 {Tcl_FindNamespace, relative name found} {
+ namespace eval test_ns_delete {
+ namespace eval test_ns_delete2 {}
+ namespace eval test_ns_delete3 {}
+ list [namespace delete test_ns_delete2] \
+ [namespace children [namespace current]]
+ }
+} {{} ::test_ns_delete::test_ns_delete3}
+test namespace-15.4 {Tcl_FindNamespace, relative name not found} {
+ namespace eval test_ns_delete2 {}
+ namespace eval test_ns_delete {
+ list [catch {namespace delete test_ns_delete2} msg] $msg
+ }
+} {1 {unknown namespace "test_ns_delete2" in namespace delete command}}
+
+test namespace-16.1 {Tcl_FindCommand, absolute name found} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1 {
+ proc cmd {args} {return "[namespace current]::cmd: $args"}
+ variable v "::test_ns_1::cmd"
+ eval $v one
+ }
+} {::test_ns_1::cmd: one}
+test namespace-16.2 {Tcl_FindCommand, absolute name found} {
+ eval $test_ns_1::v two
+} {::test_ns_1::cmd: two}
+test namespace-16.3 {Tcl_FindCommand, absolute name not found} {
+ namespace eval test_ns_1 {
+ variable v2 "::test_ns_1::ladidah"
+ list [catch {eval $v2} msg] $msg
+ }
+} {1 {invalid command name "::test_ns_1::ladidah"}}
+
+# save the "unknown" proc, which is redefined by the following two tests
+catch {rename unknown unknown.old}
+proc unknown {args} {
+ return "unknown: $args"
+}
+test namespace-16.4 {Tcl_FindCommand, absolute name and TCL_GLOBAL_ONLY} {
+ ::test_ns_1::foobar x y z
+} {unknown: ::test_ns_1::foobar x y z}
+test namespace-16.5 {Tcl_FindCommand, absolute name and TCL_GLOBAL_ONLY} {
+ ::foobar 1 2 3 4 5
+} {unknown: ::foobar 1 2 3 4 5}
+test namespace-16.6 {Tcl_FindCommand, relative name and TCL_GLOBAL_ONLY} {
+ test_ns_1::foobar x y z
+} {unknown: test_ns_1::foobar x y z}
+test namespace-16.7 {Tcl_FindCommand, relative name and TCL_GLOBAL_ONLY} {
+ foobar 1 2 3 4 5
+} {unknown: foobar 1 2 3 4 5}
+# restore the "unknown" proc saved previously
+catch {rename unknown {}}
+catch {rename unknown.old unknown}
+
+test namespace-16.8 {Tcl_FindCommand, relative name found} {
+ namespace eval test_ns_1 {
+ cmd a b c
+ }
+} {::test_ns_1::cmd: a b c}
+test namespace-16.9 {Tcl_FindCommand, relative name found} -body {
+ proc cmd2 {args} {return "[namespace current]::cmd2: $args"}
+ namespace eval test_ns_1 {
+ cmd2 a b c
+ }
+} -cleanup {
+ catch {rename cmd2 {}}
+} -result {::::cmd2: a b c}
+test namespace-16.10 {Tcl_FindCommand, relative name found, only look in current then global ns} -body {
+ proc cmd2 {args} {return "[namespace current]::cmd2: $args"}
+ namespace eval test_ns_1 {
+ proc cmd2 {args} {
+ return "[namespace current]::cmd2 in test_ns_1: $args"
+ }
+ namespace eval test_ns_12 {
+ cmd2 a b c
+ }
+ }
+} -cleanup {
+ catch {rename cmd2 {}}
+} -result {::::cmd2: a b c}
+test namespace-16.11 {Tcl_FindCommand, relative name not found} {
+ namespace eval test_ns_1 {
+ list [catch {cmd3 a b c} msg] $msg
+ }
+} {1 {invalid command name "cmd3"}}
+
+catch {unset x}
+test namespace-17.1 {Tcl_FindNamespaceVar, absolute name found} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ set x 314159
+ namespace eval test_ns_1 {
+ set ::x
+ }
+} {314159}
+test namespace-17.2 {Tcl_FindNamespaceVar, absolute name found} {
+ namespace eval test_ns_1 {
+ variable x 777
+ set ::test_ns_1::x
+ }
+} {777}
+test namespace-17.3 {Tcl_FindNamespaceVar, absolute name found} {
+ namespace eval test_ns_1 {
+ namespace eval test_ns_2 {
+ variable x 1111
+ }
+ set ::test_ns_1::test_ns_2::x
+ }
+} {1111}
+test namespace-17.4 {Tcl_FindNamespaceVar, absolute name not found} {
+ namespace eval test_ns_1 {
+ namespace eval test_ns_2 {
+ variable x 1111
+ }
+ list [catch {set ::test_ns_1::test_ns_2::y} msg] $msg
+ }
+} {1 {can't read "::test_ns_1::test_ns_2::y": no such variable}}
+test namespace-17.5 {Tcl_FindNamespaceVar, absolute name and TCL_GLOBAL_ONLY} {
+ namespace eval test_ns_1 {
+ namespace eval test_ns_3 {
+ variable ::test_ns_1::test_ns_2::x 2222
+ }
+ }
+ set ::test_ns_1::test_ns_2::x
+} {2222}
+test namespace-17.6 {Tcl_FindNamespaceVar, relative name found} {
+ namespace eval test_ns_1 {
+ set x
+ }
+} {777}
+test namespace-17.7 {Tcl_FindNamespaceVar, relative name found} {
+ namespace eval test_ns_1 {
+ unset x
+ set x ;# must be global x now
+ }
+} {314159}
+test namespace-17.8 {Tcl_FindNamespaceVar, relative name not found} {
+ namespace eval test_ns_1 {
+ list [catch {set wuzzat} msg] $msg
+ }
+} {1 {can't read "wuzzat": no such variable}}
+test namespace-17.9 {Tcl_FindNamespaceVar, relative name and TCL_GLOBAL_ONLY} {
+ namespace eval test_ns_1 {
+ variable a hello
+ }
+ set test_ns_1::a
+} {hello}
+test namespace-17.10 {Tcl_FindNamespaceVar, interference with cached varNames} {
+ namespace eval test_ns_1 {}
+ proc test_ns {} {
+ set ::test_ns_1::a 0
+ }
+ test_ns
+ rename test_ns {}
+ namespace eval test_ns_1 unset a
+ set a 0
+ namespace eval test_ns_1 set a 1
+ namespace delete test_ns_1
+ return $a
+} 1
+catch {unset a}
+catch {unset x}
+
+catch {unset l}
+catch {rename foo {}}
+test namespace-18.1 {TclResetShadowedCmdRefs, one-level check for command shadowing} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ proc foo {} {return "global foo"}
+ namespace eval test_ns_1 {
+ proc trigger {} {
+ return [foo]
+ }
+ }
+ set l ""
+ lappend l [test_ns_1::trigger]
+ namespace eval test_ns_1 {
+ # force invalidation of cached ref to "foo" in proc trigger
+ proc foo {} {return "foo in test_ns_1"}
+ }
+ lappend l [test_ns_1::trigger]
+} {{global foo} {foo in test_ns_1}}
+test namespace-18.2 {TclResetShadowedCmdRefs, multilevel check for command shadowing} {
+ namespace eval test_ns_2 {
+ proc foo {} {return "foo in ::test_ns_2"}
+ }
+ namespace eval test_ns_1 {
+ namespace eval test_ns_2 {}
+ proc trigger {} {
+ return [test_ns_2::foo]
+ }
+ }
+ set l ""
+ lappend l [test_ns_1::trigger]
+ namespace eval test_ns_1 {
+ namespace eval test_ns_2 {
+ # force invalidation of cached ref to "foo" in proc trigger
+ proc foo {} {return "foo in ::test_ns_1::test_ns_2"}
+ }
+ }
+ lappend l [test_ns_1::trigger]
+} {{foo in ::test_ns_2} {foo in ::test_ns_1::test_ns_2}}
+catch {unset l}
+catch {rename foo {}}
+
+test namespace-19.1 {GetNamespaceFromObj, global name found} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1::test_ns_2 {}
+ namespace children ::test_ns_1
+} {::test_ns_1::test_ns_2}
+test namespace-19.2 {GetNamespaceFromObj, relative name found} {
+ namespace eval test_ns_1 {
+ namespace children test_ns_2
+ }
+} {}
+test namespace-19.3 {GetNamespaceFromObj, name not found} -body {
+ namespace eval test_ns_1 {
+ namespace children test_ns_99
+ }
+} -returnCodes error -result {namespace "test_ns_99" not found in "::test_ns_1"}
+test namespace-19.4 {GetNamespaceFromObj, invalidation of cached ns refs} {
+ namespace eval test_ns_1 {
+ proc foo {} {
+ return [namespace children test_ns_2]
+ }
+ list [catch {namespace children test_ns_99} msg] $msg
+ }
+ set l {}
+ lappend l [test_ns_1::foo]
+ namespace delete test_ns_1::test_ns_2
+ namespace eval test_ns_1::test_ns_2::test_ns_3 {}
+ lappend l [test_ns_1::foo]
+} {{} ::test_ns_1::test_ns_2::test_ns_3}
+
+test namespace-20.1 {Tcl_NamespaceObjCmd, bad subcommand} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace} msg] $msg
+} {1 {wrong # args: should be "namespace subcommand ?arg ...?"}}
+test namespace-20.2 {Tcl_NamespaceObjCmd, bad subcommand} -body {
+ namespace wombat {}
+} -returnCodes error -match glob -result {unknown or ambiguous subcommand "wombat": must be *}
+test namespace-20.3 {Tcl_NamespaceObjCmd, abbreviations are okay} {
+ namespace ch :: test_ns_*
+} {}
+
+test namespace-21.1 {NamespaceChildrenCmd, no args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1::test_ns_2 {}
+ expr {[string first ::test_ns_1 [namespace children]] != -1}
+} {1}
+test namespace-21.2 {NamespaceChildrenCmd, no args} {
+ namespace eval test_ns_1 {
+ namespace children
+ }
+} {::test_ns_1::test_ns_2}
+test namespace-21.3 {NamespaceChildrenCmd, ns name given} {
+ namespace children ::test_ns_1
+} {::test_ns_1::test_ns_2}
+test namespace-21.4 {NamespaceChildrenCmd, ns name given} {
+ namespace eval test_ns_1 {
+ namespace children test_ns_2
+ }
+} {}
+test namespace-21.5 {NamespaceChildrenCmd, too many args} {
+ namespace eval test_ns_1 {
+ list [catch {namespace children test_ns_2 xxx yyy} msg] $msg
+ }
+} {1 {wrong # args: should be "namespace children ?name? ?pattern?"}}
+test namespace-21.6 {NamespaceChildrenCmd, glob-style pattern given} {
+ namespace eval test_ns_1::test_ns_foo {}
+ namespace children test_ns_1 *f*
+} {::test_ns_1::test_ns_foo}
+test namespace-21.7 {NamespaceChildrenCmd, glob-style pattern given} {
+ namespace eval test_ns_1::test_ns_foo {}
+ lsort [namespace children test_ns_1 test*]
+} [lsort {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_foo}]
+test namespace-21.8 {NamespaceChildrenCmd, trivial pattern starting with ::} {
+ namespace eval test_ns_1 {}
+ namespace children [namespace current] [fq test_ns_1]
+} [fq test_ns_1]
+
+test namespace-22.1 {NamespaceCodeCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace code} msg] $msg \
+ [catch {namespace code xxx yyy} msg] $msg
+} {1 {wrong # args: should be "namespace code arg"} 1 {wrong # args: should be "namespace code arg"}}
+test namespace-22.2 {NamespaceCodeCmd, arg is already scoped value} {
+ namespace eval test_ns_1 {
+ proc cmd {} {return "test_ns_1::cmd"}
+ }
+ namespace code {::namespace inscope ::test_ns_1 cmd}
+} {::namespace inscope ::test_ns_1 cmd}
+test namespace-22.3 {NamespaceCodeCmd, arg is already scoped value} {
+ namespace code {namespace inscope ::test_ns_1 cmd}
+} {::namespace inscope :: {namespace inscope ::test_ns_1 cmd}}
+test namespace-22.4 {NamespaceCodeCmd, in :: namespace} {
+ namespace code unknown
+} {::namespace inscope :: unknown}
+test namespace-22.5 {NamespaceCodeCmd, in other namespace} {
+ namespace eval test_ns_1 {
+ namespace code cmd
+ }
+} {::namespace inscope ::test_ns_1 cmd}
+test namespace-22.6 {NamespaceCodeCmd, in other namespace} {
+ namespace eval test_ns_1 {
+ variable v 42
+ }
+ namespace eval test_ns_2 {
+ proc namespace args {}
+ }
+ namespace eval test_ns_2 [namespace eval test_ns_1 {
+ namespace code {set v}
+ }]
+} {42}
+test namespace-22.7 {NamespaceCodeCmd, Bug 3202171} {
+ namespace eval demo {
+ proc namespace args {puts $args}
+ ::namespace code {namespace inscope foo}
+ }
+} [list ::namespace inscope [fq demo] {namespace inscope foo}]
+
+test namespace-23.1 {NamespaceCurrentCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace current xxx} msg] $msg \
+ [catch {namespace current xxx yyy} msg] $msg
+} {1 {wrong # args: should be "namespace current"} 1 {wrong # args: should be "namespace current"}}
+test namespace-23.2 {NamespaceCurrentCmd, at global level} {
+ namespace current
+} {::}
+test namespace-23.3 {NamespaceCurrentCmd, in nested ns} {
+ namespace eval test_ns_1::test_ns_2 {
+ namespace current
+ }
+} {::test_ns_1::test_ns_2}
+
+test namespace-24.1 {NamespaceDeleteCmd, no args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace delete
+} {}
+test namespace-24.2 {NamespaceDeleteCmd, one arg} {
+ namespace eval test_ns_1::test_ns_2 {}
+ namespace delete ::test_ns_1
+} {}
+test namespace-24.3 {NamespaceDeleteCmd, two args} {
+ namespace eval test_ns_1::test_ns_2 {}
+ list [namespace delete ::test_ns_1::test_ns_2] [namespace delete ::test_ns_1]
+} {{} {}}
+test namespace-24.4 {NamespaceDeleteCmd, unknown ns} {
+ list [catch {namespace delete ::test_ns_foo} msg] $msg
+} {1 {unknown namespace "::test_ns_foo" in namespace delete command}}
+
+test namespace-25.1 {NamespaceEvalCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace eval} msg] $msg
+} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
+test namespace-25.2 {NamespaceEvalCmd, bad args} -body {
+ namespace test_ns_1
+} -returnCodes error -match glob -result {unknown or ambiguous subcommand "test_ns_1": must be *}
+catch {unset v}
+test namespace-25.3 {NamespaceEvalCmd, new namespace} {
+ set v 123
+ namespace eval test_ns_1 {
+ variable v 314159
+ proc p {} {
+ variable v
+ return $v
+ }
+ }
+ test_ns_1::p
+} {314159}
+test namespace-25.4 {NamespaceEvalCmd, existing namespace} {
+ namespace eval test_ns_1 {
+ proc q {} {return [expr {[p]+1}]}
+ }
+ test_ns_1::q
+} {314160}
+test namespace-25.5 {NamespaceEvalCmd, multiple args} {
+ namespace eval test_ns_1 "set" "v"
+} {314159}
+test namespace-25.6 {NamespaceEvalCmd, error in eval'd script} {
+ list [catch {namespace eval test_ns_1 {xxxx}} msg] $msg $::errorInfo
+} {1 {invalid command name "xxxx"} {invalid command name "xxxx"
+ while executing
+"xxxx"
+ (in namespace eval "::test_ns_1" script line 1)
+ invoked from within
+"namespace eval test_ns_1 {xxxx}"}}
+test namespace-25.7 {NamespaceEvalCmd, error in eval'd script} {
+ list [catch {namespace eval test_ns_1 {error foo bar baz}} msg] $msg $::errorInfo
+} {1 foo {bar
+ (in namespace eval "::test_ns_1" script line 1)
+ invoked from within
+"namespace eval test_ns_1 {error foo bar baz}"}}
+test namespace-25.8 {NamespaceEvalCmd, error in eval'd script} {
+ list [catch {namespace eval test_ns_1 error foo bar baz} msg] $msg $::errorInfo
+} {1 foo {bar
+ (in namespace eval "::test_ns_1" script line 1)
+ invoked from within
+"namespace eval test_ns_1 error foo bar baz"}}
+catch {unset v}
+test namespace-25.9 {NamespaceEvalCmd, 545325} {
+ namespace eval test_ns_1 info level 0
+} {namespace eval test_ns_1 info level 0}
+
+test namespace-26.1 {NamespaceExportCmd, no args and new ns} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace export
+} {}
+test namespace-26.2 {NamespaceExportCmd, just -clear arg} {
+ namespace export -clear
+} {}
+test namespace-26.3 {NamespaceExportCmd, pattern can't specify a namespace} {
+ namespace eval test_ns_1 {
+ list [catch {namespace export ::zzz} msg] $msg
+ }
+} {1 {invalid export pattern "::zzz": pattern can't specify a namespace}}
+test namespace-26.4 {NamespaceExportCmd, one pattern} {
+ namespace eval test_ns_1 {
+ namespace export cmd1
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ proc cmd3 {args} {return "cmd3: $args"}
+ proc cmd4 {args} {return "cmd4: $args"}
+ }
+ namespace eval test_ns_2 {
+ namespace import ::test_ns_1::*
+ }
+ list [info commands test_ns_2::*] [test_ns_2::cmd1 hello]
+} {::test_ns_2::cmd1 {cmd1: hello}}
+test namespace-26.5 {NamespaceExportCmd, sequence of patterns, patterns accumulate} {
+ namespace eval test_ns_1 {
+ namespace export cmd1 cmd3
+ }
+ namespace eval test_ns_2 {
+ namespace import -force ::test_ns_1::*
+ }
+ list [lsort [info commands test_ns_2::*]] [test_ns_2::cmd3 hello]
+} [list [lsort {::test_ns_2::cmd1 ::test_ns_2::cmd3}] {cmd3: hello}]
+test namespace-26.6 {NamespaceExportCmd, no patterns means return uniq'ed export list} {
+ namespace eval test_ns_1 {
+ namespace export
+ }
+} {cmd1 cmd3}
+test namespace-26.7 {NamespaceExportCmd, -clear resets export list} {
+ namespace eval test_ns_1 {
+ namespace export -clear cmd4
+ }
+ namespace eval test_ns_2 {
+ namespace import ::test_ns_1::*
+ }
+ list [lsort [info commands test_ns_2::*]] [test_ns_2::cmd4 hello]
+} [list [lsort {::test_ns_2::cmd4 ::test_ns_2::cmd1 ::test_ns_2::cmd3}] {cmd4: hello}]
+
+test namespace-27.1 {NamespaceForgetCmd, no args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace forget
+} {}
+test namespace-27.2 {NamespaceForgetCmd, args must be valid namespaces} {
+ list [catch {namespace forget ::test_ns_1::xxx} msg] $msg
+} {1 {unknown namespace in namespace forget pattern "::test_ns_1::xxx"}}
+test namespace-27.3 {NamespaceForgetCmd, arg is forgotten} {
+ namespace eval test_ns_1 {
+ namespace export cmd*
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ }
+ namespace eval test_ns_2 {
+ namespace import ::test_ns_1::*
+ namespace forget ::test_ns_1::cmd1
+ }
+ info commands ::test_ns_2::*
+} {::test_ns_2::cmd2}
+
+test namespace-28.1 {NamespaceImportCmd, no args} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ namespace eval ::test_ns_1 {
+ proc foo {} {}
+ proc bar {} {}
+ proc boo {} {}
+ proc glorp {} {}
+ namespace export foo b*
+ }
+ namespace eval ::test_ns_2 {
+ namespace import ::test_ns_1::*
+ lsort [namespace import]
+ }
+} -cleanup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -result {bar boo foo}
+test namespace-28.2 {NamespaceImportCmd, no args and just "-force"} {
+ namespace import -force
+} {}
+test namespace-28.3 {NamespaceImportCmd, arg is imported} {
+ namespace eval test_ns_1 {
+ namespace export cmd2
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ }
+ namespace eval test_ns_2 {
+ namespace import ::test_ns_1::*
+ namespace forget ::test_ns_1::cmd1
+ }
+ info commands test_ns_2::*
+} {::test_ns_2::cmd2}
+
+test namespace-29.1 {NamespaceInscopeCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace inscope} msg] $msg
+} {1 {wrong # args: should be "namespace inscope name arg ?arg...?"}}
+test namespace-29.2 {NamespaceInscopeCmd, bad args} {
+ list [catch {namespace inscope ::} msg] $msg
+} {1 {wrong # args: should be "namespace inscope name arg ?arg...?"}}
+test namespace-29.3 {NamespaceInscopeCmd, specified ns must exist} -body {
+ namespace inscope test_ns_1 {set v}
+} -returnCodes error -result {namespace "test_ns_1" not found in "::"}
+test namespace-29.4 {NamespaceInscopeCmd, simple case} {
+ namespace eval test_ns_1 {
+ variable v 747
+ proc cmd {args} {
+ variable v
+ return "[namespace current]::cmd: v=$v, args=$args"
+ }
+ }
+ namespace inscope test_ns_1 cmd
+} {::test_ns_1::cmd: v=747, args=}
+test namespace-29.5 {NamespaceInscopeCmd, has lappend semantics} {
+ list [namespace inscope test_ns_1 cmd x y z] \
+ [namespace eval test_ns_1 [concat cmd [list x y z]]]
+} {{::test_ns_1::cmd: v=747, args=x y z} {::test_ns_1::cmd: v=747, args=x y z}}
+test namespace-29.6 {NamespaceInscopeCmd, 1400572} {
+ namespace inscope test_ns_1 {info level 0}
+} {namespace inscope test_ns_1 {info level 0}}
+
+
+test namespace-30.1 {NamespaceOriginCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace origin} msg] $msg
+} {1 {wrong # args: should be "namespace origin name"}}
+test namespace-30.2 {NamespaceOriginCmd, bad args} {
+ list [catch {namespace origin x y} msg] $msg
+} {1 {wrong # args: should be "namespace origin name"}}
+test namespace-30.3 {NamespaceOriginCmd, command not found} {
+ list [catch {namespace origin fred} msg] $msg
+} {1 {invalid command name "fred"}}
+test namespace-30.4 {NamespaceOriginCmd, command isn't imported} {
+ namespace origin set
+} {::set}
+test namespace-30.5 {NamespaceOriginCmd, imported command} {
+ namespace eval test_ns_1 {
+ namespace export cmd*
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ }
+ namespace eval test_ns_2 {
+ namespace export *
+ namespace import ::test_ns_1::*
+ proc p {} {}
+ }
+ namespace eval test_ns_3 {
+ namespace import ::test_ns_2::*
+ list [namespace origin foreach] \
+ [namespace origin p] \
+ [namespace origin cmd1] \
+ [namespace origin ::test_ns_2::cmd2]
+ }
+} {::foreach ::test_ns_2::p ::test_ns_1::cmd1 ::test_ns_1::cmd2}
+
+test namespace-31.1 {NamespaceParentCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace parent a b} msg] $msg
+} {1 {wrong # args: should be "namespace parent ?name?"}}
+test namespace-31.2 {NamespaceParentCmd, no args} {
+ namespace parent
+} {}
+test namespace-31.3 {NamespaceParentCmd, namespace specified} {
+ namespace eval test_ns_1 {
+ namespace eval test_ns_2 {
+ namespace eval test_ns_3 {}
+ }
+ }
+ list [namespace parent ::] \
+ [namespace parent test_ns_1::test_ns_2] \
+ [namespace eval test_ns_1::test_ns_2::test_ns_3 {namespace parent ::test_ns_1::test_ns_2}]
+} {{} ::test_ns_1 ::test_ns_1}
+test namespace-31.4 {NamespaceParentCmd, bad namespace specified} -body {
+ namespace parent test_ns_1::test_ns_foo
+} -returnCodes error -result {namespace "test_ns_1::test_ns_foo" not found in "::"}
+
+test namespace-32.1 {NamespaceQualifiersCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace qualifiers} msg] $msg
+} {1 {wrong # args: should be "namespace qualifiers string"}}
+test namespace-32.2 {NamespaceQualifiersCmd, bad args} {
+ list [catch {namespace qualifiers x y} msg] $msg
+} {1 {wrong # args: should be "namespace qualifiers string"}}
+test namespace-32.3 {NamespaceQualifiersCmd, simple name} {
+ namespace qualifiers foo
+} {}
+test namespace-32.4 {NamespaceQualifiersCmd, leading ::} {
+ namespace qualifiers ::x::y::z
+} {::x::y}
+test namespace-32.5 {NamespaceQualifiersCmd, no leading ::} {
+ namespace qualifiers a::b
+} {a}
+test namespace-32.6 {NamespaceQualifiersCmd, :: argument} {
+ namespace qualifiers ::
+} {}
+test namespace-32.7 {NamespaceQualifiersCmd, odd number of :s} {
+ namespace qualifiers :::::
+} {}
+test namespace-32.8 {NamespaceQualifiersCmd, odd number of :s} {
+ namespace qualifiers foo:::
+} {foo}
+
+test namespace-33.1 {NamespaceTailCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace tail} msg] $msg
+} {1 {wrong # args: should be "namespace tail string"}}
+test namespace-33.2 {NamespaceTailCmd, bad args} {
+ list [catch {namespace tail x y} msg] $msg
+} {1 {wrong # args: should be "namespace tail string"}}
+test namespace-33.3 {NamespaceTailCmd, simple name} {
+ namespace tail foo
+} {foo}
+test namespace-33.4 {NamespaceTailCmd, leading ::} {
+ namespace tail ::x::y::z
+} {z}
+test namespace-33.5 {NamespaceTailCmd, no leading ::} {
+ namespace tail a::b
+} {b}
+test namespace-33.6 {NamespaceTailCmd, :: argument} {
+ namespace tail ::
+} {}
+test namespace-33.7 {NamespaceTailCmd, odd number of :s} {
+ namespace tail :::::
+} {}
+test namespace-33.8 {NamespaceTailCmd, odd number of :s} {
+ namespace tail foo:::
+} {}
+
+test namespace-34.1 {NamespaceWhichCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace which} msg] $msg
+} {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
+test namespace-34.2 {NamespaceWhichCmd, bad args} {
+ list [catch {namespace which -fred x} msg] $msg
+} {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
+test namespace-34.3 {NamespaceWhichCmd, single arg is always command name} {
+ namespace which -command
+} {}
+test namespace-34.4 {NamespaceWhichCmd, bad args} {
+ list [catch {namespace which a b} msg] $msg
+} {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
+test namespace-34.5 {NamespaceWhichCmd, command lookup} {
+ namespace eval test_ns_1 {
+ namespace export cmd*
+ variable v1 111
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ }
+ namespace eval test_ns_2 {
+ namespace export *
+ namespace import ::test_ns_1::*
+ variable v2 222
+ proc p {} {}
+ }
+ namespace eval test_ns_3 {
+ namespace import ::test_ns_2::*
+ variable v3 333
+ list [namespace which -command foreach] \
+ [namespace which -command p] \
+ [namespace which -command cmd1] \
+ [namespace which -command ::test_ns_2::cmd2] \
+ [catch {namespace which -command ::test_ns_2::noSuchCmd} msg] $msg
+ }
+} {::foreach ::test_ns_3::p ::test_ns_3::cmd1 ::test_ns_2::cmd2 0 {}}
+test namespace-34.6 {NamespaceWhichCmd, -command is default} {
+ namespace eval test_ns_3 {
+ list [namespace which foreach] \
+ [namespace which p] \
+ [namespace which cmd1] \
+ [namespace which ::test_ns_2::cmd2]
+ }
+} {::foreach ::test_ns_3::p ::test_ns_3::cmd1 ::test_ns_2::cmd2}
+test namespace-34.7 {NamespaceWhichCmd, variable lookup} {
+ namespace eval test_ns_3 {
+ list [namespace which -variable env] \
+ [namespace which -variable v3] \
+ [namespace which -variable ::test_ns_2::v2] \
+ [catch {namespace which -variable ::test_ns_2::noSuchVar} msg] $msg
+ }
+} {::env ::test_ns_3::v3 ::test_ns_2::v2 0 {}}
+
+test namespace-35.1 {FreeNsNameInternalRep, resulting ref count > 0} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1 {
+ proc p {} {
+ namespace delete [namespace current]
+ return [namespace current]
+ }
+ }
+ test_ns_1::p
+} {::test_ns_1}
+test namespace-35.2 {FreeNsNameInternalRep, resulting ref count == 0} {
+ namespace eval test_ns_1 {
+ proc q {} {
+ return [namespace current]
+ }
+ }
+ list [test_ns_1::q] \
+ [namespace delete test_ns_1] \
+ [catch {test_ns_1::q} msg] $msg
+} {::test_ns_1 {} 1 {invalid command name "test_ns_1::q"}}
+
+catch {unset x}
+catch {unset y}
+test namespace-36.1 {DupNsNameInternalRep} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1 {}
+ set x "::test_ns_1"
+ list [namespace parent $x] [set y $x] [namespace parent $y]
+} {:: ::test_ns_1 ::}
+catch {unset x}
+catch {unset y}
+
+test namespace-37.1 {SetNsNameFromAny, ns name found} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1::test_ns_2 {}
+ namespace eval test_ns_1 {
+ namespace children ::test_ns_1
+ }
+} {::test_ns_1::test_ns_2}
+test namespace-37.2 {SetNsNameFromAny, ns name not found} -body {
+ namespace eval test_ns_1 {
+ namespace children ::test_ns_1::test_ns_foo
+ }
+} -returnCodes error -result {namespace "::test_ns_1::test_ns_foo" not found}
+
+test namespace-38.1 {UpdateStringOfNsName} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ ;# Tcl_NamespaceObjCmd calls UpdateStringOfNsName to get subcmd name
+ list [namespace eval {} {namespace current}] \
+ [namespace eval {} {namespace current}]
+} {:: ::}
+
+test namespace-39.1 {NamespaceExistsCmd} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval ::test_ns_z::test_me { variable foo }
+ list [namespace exists ::] \
+ [namespace exists ::bogus_namespace] \
+ [namespace exists ::test_ns_z] \
+ [namespace exists test_ns_z] \
+ [namespace exists ::test_ns_z::foo] \
+ [namespace exists ::test_ns_z::test_me] \
+ [namespace eval ::test_ns_z { namespace exists ::test_me }] \
+ [namespace eval ::test_ns_z { namespace exists test_me }] \
+ [namespace exists :::::test_ns_z]
+} {1 0 1 1 0 1 0 1 1}
+test namespace-39.2 {NamespaceExistsCmd error} {
+ list [catch {namespace exists} msg] $msg
+} {1 {wrong # args: should be "namespace exists name"}}
+test namespace-39.3 {NamespaceExistsCmd error} {
+ list [catch {namespace exists a b} msg] $msg
+} {1 {wrong # args: should be "namespace exists name"}}
+
+test namespace-40.1 {Ignoring namespace proc "unknown"} -setup {
+ rename unknown _unknown
+} -body {
+ proc unknown args {return global}
+ namespace eval ns {proc unknown args {return local}}
+ list [namespace eval ns aaa bbb] [namespace eval ns aaa]
+} -cleanup {
+ rename unknown {}
+ rename _unknown unknown
+ namespace delete ns
+} -result {global global}
+
+test namespace-41.1 {Shadowing byte-compiled commands, Bug: 231259} {
+ set res {}
+ namespace eval ns {
+ set res {}
+ proc test {} {
+ set ::g 0
+ }
+ lappend ::res [test]
+ proc set {a b} {
+ ::set a [incr b]
+ }
+ lappend ::res [test]
+ }
+ namespace delete ns
+ set res
+} {0 1}
+test namespace-41.2 {Shadowing byte-compiled commands, Bug: 231259} {
+ set res {}
+ namespace eval ns {}
+ proc ns::a {i} {
+ variable b
+ proc set args {return "New proc is called"}
+ return [set b $i]
+ }
+ ns::a 1
+ set res [ns::a 2]
+ namespace delete ns
+ set res
+} {New proc is called}
+test namespace-41.3 {Shadowing byte-compiled commands, Bugs: 231259, 729692} {
+ set res {}
+ namespace eval ns {
+ variable b 0
+ }
+ proc ns::a {i} {
+ variable b
+ proc set args {return "New proc is called"}
+ return [set b $i]
+ }
+ set res [list [ns::a 1] $ns::b]
+ namespace delete ns
+ set res
+} {{New proc is called} 0}
+
+# Ensembles (TIP#112)
+
+test namespace-42.1 {ensembles: basic} {
+ namespace eval ns {
+ namespace export x
+ proc x {} {format 1}
+ namespace ensemble create
+ }
+ list [info command ns] [ns x] [namespace delete ns] [info command ns]
+} {ns 1 {} {}}
+test namespace-42.2 {ensembles: basic} {
+ namespace eval ns {
+ namespace export x
+ proc x {} {format 1}
+ namespace ensemble create
+ }
+ rename ns foo
+ list [info command foo] [foo x] [namespace delete ns] [info command foo]
+} {foo 1 {} {}}
+test namespace-42.3 {ensembles: basic} {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {} {format 1}
+ proc x2 {} {format 2}
+ namespace ensemble create
+ }
+ set result [list [ns x1] [ns x2]]
+ lappend result [catch {ns x} msg] $msg
+ rename ns {}
+ lappend result [info command ns::x1]
+ namespace delete ns
+ lappend result [info command ns::x1]
+} {1 2 1 {unknown or ambiguous subcommand "x": must be x1, or x2} ::ns::x1 {}}
+test namespace-42.4 {ensembles: basic} -body {
+ namespace eval ns {
+ namespace export y*
+ proc x1 {} {format 1}
+ proc x2 {} {format 2}
+ namespace ensemble create
+ }
+ list [catch {ns x} msg] $msg
+} -cleanup {
+ namespace delete ns
+} -result {1 {unknown subcommand "x": namespace ::ns does not export any commands}}
+test namespace-42.5 {ensembles: basic} -body {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {} {format 1}
+ proc x2 {} {format 2}
+ proc x3 {} {format 3}
+ namespace ensemble create
+ }
+ list [catch {ns x} msg] $msg
+} -cleanup {
+ namespace delete ns
+} -result {1 {unknown or ambiguous subcommand "x": must be x1, x2, or x3}}
+test namespace-42.6 {ensembles: nested} -body {
+ namespace eval ns {
+ namespace export x*
+ namespace eval x0 {
+ proc z {} {format 0}
+ namespace export z
+ namespace ensemble create
+ }
+ proc x1 {} {format 1}
+ proc x2 {} {format 2}
+ proc x3 {} {format 3}
+ namespace ensemble create
+ }
+ list [ns x0 z] [ns x1] [ns x2] [ns x3]
+} -cleanup {
+ namespace delete ns
+} -result {0 1 2 3}
+test namespace-42.7 {ensembles: nested} -body {
+ namespace eval ns {
+ namespace export x*
+ namespace eval x0 {
+ proc z {} {list [info level] [info level 1]}
+ namespace export z
+ namespace ensemble create
+ }
+ proc x1 {} {format 1}
+ proc x2 {} {format 2}
+ proc x3 {} {format 3}
+ namespace ensemble create
+ }
+ list [ns x0 z] [ns x1] [ns x2] [ns x3]
+} -cleanup {
+ namespace delete ns
+} -result {{1 ::ns::x0::z} 1 2 3}
+test namespace-42.8 {ensembles: [Bug 1670091]} -setup {
+ proc demo args {}
+ variable target [list [namespace which demo] x]
+ proc trial args {variable target; string length $target}
+ trace add execution demo enter [namespace code trial]
+ namespace ensemble create -command foo -map [list bar $target]
+} -body {
+ foo bar
+} -cleanup {
+ unset target
+ rename demo {}
+ rename trial {}
+ rename foo {}
+} -result {}
+
+test namespace-43.1 {ensembles: dict-driven} {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {} {format 1}
+ proc x2 {} {format 2}
+ namespace ensemble create -map {a x1 b x2}
+ }
+ set result [list [catch {ns c} msg] $msg [namespace ensemble exists ns]]
+ rename ns {}
+ lappend result [namespace ensemble exists ns]
+} {1 {unknown or ambiguous subcommand "c": must be a, or b} 1 0}
+test namespace-43.2 {ensembles: dict-driven} -body {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {args} {list 1 $args}
+ proc x2 {args} {list 2 [llength $args]}
+ namespace ensemble create -map {
+ a ::ns::x1 b ::ns::x2 c {::ns::x1 .} d {::ns::x2 .}
+ }
+ }
+ list [ns a] [ns b] [ns c] [ns c foo] [ns d] [ns d foo]
+} -cleanup {
+ namespace delete ns
+} -result {{1 {}} {2 0} {1 .} {1 {. foo}} {2 1} {2 2}}
+set SETUP {
+ namespace eval ns {
+ namespace export a b
+ proc a args {format 1,[llength $args]}
+ proc b args {format 2,[llength $args]}
+ proc c args {format 3,[llength $args]}
+ proc d args {format 4,[llength $args]}
+ namespace ensemble create -subcommands {b c}
+ }
+}
+test namespace-43.3 {ensembles: list-driven} -setup $SETUP -body {
+ namespace delete ns
+} -result {}
+test namespace-43.4 {ensembles: list-driven} -setup $SETUP -body {
+ ns a foo bar boo spong wibble
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown or ambiguous subcommand "a": must be b, or c}
+test namespace-43.5 {ensembles: list-driven} -setup $SETUP -body {
+ ns b foo bar boo spong wibble
+} -cleanup {namespace delete ns} -result 2,5
+test namespace-43.6 {ensembles: list-driven} -setup $SETUP -body {
+ ns c foo bar boo spong wibble
+} -cleanup {namespace delete ns} -result 3,5
+test namespace-43.7 {ensembles: list-driven} -setup $SETUP -body {
+ ns d foo bar boo spong wibble
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown or ambiguous subcommand "d": must be b, or c}
+set SETUP {
+ namespace eval ns {
+ namespace export a b
+ proc a args {format 1,[llength $args]}
+ proc b args {format 2,[llength $args]}
+ proc c args {format 3,[llength $args]}
+ proc d args {format 4,[llength $args]}
+ namespace ensemble create -subcommands {b c} -map {c ::ns::d}
+ }
+}
+test namespace-43.8 {ensembles: list-and-map-driven} -setup $SETUP -body {
+ namespace delete ns
+} -result {}
+test namespace-43.9 {ensembles: list-and-map-driven} -setup $SETUP -body {
+ ns a foo bar boo spong wibble
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown or ambiguous subcommand "a": must be b, or c}
+test namespace-43.10 {ensembles: list-and-map-driven} -setup $SETUP -body {
+ ns b foo bar boo spong wibble
+} -cleanup {namespace delete ns} -result 2,5
+test namespace-43.11 {ensembles: list-and-map-driven} -setup $SETUP -body {
+ ns c foo bar boo spong wibble
+} -cleanup {namespace delete ns} -result 4,5
+test namespace-43.12 {ensembles: list-and-map-driven} -setup $SETUP -body {
+ ns d foo bar boo spong wibble
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown or ambiguous subcommand "d": must be b, or c}
+set SETUP {
+ namespace eval ns {
+ namespace export *
+ proc foo args {format bar}
+ proc spong args {format wibble}
+ namespace ensemble create -prefixes off
+ }
+}
+test namespace-43.13 {ensembles: turn off prefixes} -setup $SETUP -body {
+ namespace delete ns
+} -result {}
+test namespace-43.14 {ensembles: turn off prefixes} -setup $SETUP -body {
+ ns fo
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown subcommand "fo": must be foo, or spong}
+test namespace-43.15 {ensembles: turn off prefixes} -setup $SETUP -body {
+ ns foo
+} -cleanup {namespace delete ns} -result bar
+test namespace-43.16 {ensembles: turn off prefixes} -setup $SETUP -body {
+ ns s
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown subcommand "s": must be foo, or spong}
+test namespace-43.17 {ensembles: turn off prefixes} -setup $SETUP -body {
+ ns spong
+} -cleanup {namespace delete ns} -result wibble
+
+test namespace-44.1 {ensemble: errors} {
+ list [catch {namespace ensemble} msg] $msg
+} {1 {wrong # args: should be "namespace ensemble subcommand ?arg ...?"}}
+test namespace-44.2 {ensemble: errors} {
+ list [catch {namespace ensemble ?} msg] $msg
+} {1 {bad subcommand "?": must be configure, create, or exists}}
+test namespace-44.3 {ensemble: errors} {
+ namespace eval ns {
+ list [catch {namespace ensemble create -map x} msg] $msg
+ }
+} {1 {missing value to go with key}}
+test namespace-44.4 {ensemble: errors} {
+ namespace eval ns {
+ list [catch {namespace ensemble create -map {x {}}} msg] $msg
+ }
+} {1 {ensemble subcommand implementations must be non-empty lists}}
+test namespace-44.5 {ensemble: errors} -setup {
+ namespace ensemble create -command foobar -subcommands {foobarcget foobarconfigure}
+} -body {
+ foobar foobarcon
+} -cleanup {
+ rename foobar {}
+} -returnCodes error -result {invalid command name "::foobarconfigure"}
+test namespace-44.6 {ensemble: errors} -returnCodes error -body {
+ namespace ensemble create gorp
+} -result {wrong # args: should be "namespace ensemble create ?option value ...?"}
+
+test namespace-45.1 {ensemble: introspection} {
+ namespace eval ns {
+ namespace export x
+ proc x {} {}
+ namespace ensemble create
+ set ::result [namespace ensemble configure ::ns]
+ }
+ namespace delete ns
+ set result
+} {-map {} -namespace ::ns -parameters {} -prefixes 1 -subcommands {} -unknown {}}
+test namespace-45.2 {ensemble: introspection} {
+ namespace eval ns {
+ namespace export x
+ proc x {} {}
+ namespace ensemble create -map {A x}
+ set ::result [namespace ensemble configure ::ns -map]
+ }
+ namespace delete ns
+ set result
+} {A ::ns::x}
+
+test namespace-46.1 {ensemble: modification} {
+ namespace eval ns {
+ namespace export x
+ proc x {} {format 123}
+ # Ensemble maps A->x
+ namespace ensemble create -command ns -map {A ::ns::x}
+ set ::result [list [namespace ensemble configure ns -map] [ns A]]
+ # Ensemble maps B->x
+ namespace ensemble configure ns -map {B ::ns::x}
+ lappend ::result [namespace ensemble configure ns -map] [ns B]
+ # Ensemble maps x->x
+ namespace ensemble configure ns -map {}
+ lappend ::result [namespace ensemble configure ns -map] [ns x]
+ }
+ namespace delete ns
+ set result
+} {{A ::ns::x} 123 {B ::ns::x} 123 {} 123}
+test namespace-46.2 {ensemble: ensembles really use current export list} {
+ namespace eval ns {
+ namespace export x1
+ proc x1 {} {format 1}
+ proc x2 {} {format 1}
+ namespace ensemble create
+ }
+ catch {ns ?} msg; set result [list $msg]
+ namespace eval ns {namespace export x*}
+ catch {ns ?} msg; lappend result $msg
+ rename ns::x1 {}
+ catch {ns ?} msg; lappend result $msg
+ namespace delete ns
+ set result
+} {{unknown or ambiguous subcommand "?": must be x1} {unknown or ambiguous subcommand "?": must be x1, or x2} {unknown or ambiguous subcommand "?": must be x2}}
+test namespace-46.3 {ensemble: implementation errors} {
+ namespace eval ns {
+ variable count 0
+ namespace ensemble create -map {
+ a {::lappend ::result}
+ b {::incr ::ns::count}
+ }
+ }
+ set result {}
+ lappend result [catch { ns } msg] $msg
+ ns a [ns b 10]
+ catch {rename p {}}
+ rename ns p
+ p a [p b 3000]
+ lappend result $ns::count
+ namespace delete ns
+ lappend result [info command p]
+} {1 {wrong # args: should be "ns subcommand ?arg ...?"} 10 3010 3010 {}}
+test namespace-46.4 {ensemble: implementation errors} {
+ namespace eval ns {
+ namespace ensemble create
+ }
+ set result [info command ns]
+ lappend result [catch {ns ?} msg] $msg
+ namespace delete ns
+ set result
+} {ns 1 {unknown subcommand "?": namespace ::ns does not export any commands}}
+test namespace-46.5 {ensemble: implementation errors} {
+ namespace eval ns {
+ namespace ensemble create -map {makeError ::error}
+ }
+ list [catch {ns makeError "an error happened"} msg] $msg $::errorInfo [namespace delete ns]
+} {1 {an error happened} {an error happened
+ while executing
+"ns makeError "an error happened""} {}}
+test namespace-46.6 {ensemble: implementation renames/deletes itself} {
+ namespace eval ns {
+ namespace ensemble create -map {to ::rename}
+ }
+ ns to ns foo
+ foo to foo bar
+ bar to bar spong
+ spong to spong {}
+ namespace delete ns
+} {}
+test namespace-46.7 {ensemble: implementation deletes its namespace} {
+ namespace eval ns {
+ namespace ensemble create -map {kill {::namespace delete}}
+ }
+ ns kill ns
+} {}
+test namespace-46.8 {ensemble: implementation deletes its namespace} {
+ namespace eval ns {
+ namespace export *
+ proc foo {} {
+ variable x 1
+ bar
+ # Tricky; what is the correct return value anyway?
+ info exist x
+ }
+ proc bar {} {
+ namespace delete [namespace current]
+ }
+ namespace ensemble create
+ }
+ list [ns foo] [info exist ns::x]
+} {1 0}
+test namespace-46.9 {ensemble: configuring really configures things} {
+ namespace eval ns {
+ namespace ensemble create -map {a a} -prefixes 0
+ }
+ set result [list [catch {ns x} msg] $msg]
+ namespace ensemble configure ns -map {b b}
+ lappend result [catch {ns x} msg] $msg
+ namespace delete ns
+ set result
+} {1 {unknown subcommand "x": must be a} 1 {unknown subcommand "x": must be b}}
+
+test namespace-47.1 {ensemble: unknown handler} {
+ set log {}
+ namespace eval ns {
+ namespace export {[a-z]*}
+ proc Magic {ensemble subcmd args} {
+ global log
+ if {[string match {[a-z]*} $subcmd]} {
+ lappend log "making $subcmd"
+ proc $subcmd args {
+ global log
+ lappend log "running [info level 0]"
+ llength $args
+ }
+ } else {
+ lappend log "unknown $subcmd - args = $args"
+ return -code error \
+ "unknown or protected subcommand \"$subcmd\""
+ }
+ }
+ namespace ensemble create -unknown ::ns::Magic
+ }
+ set result {}
+ lappend result [catch {ns a b c} msg] $msg
+ lappend result [catch {ns a b c} msg] $msg
+ lappend result [catch {ns b c d} msg] $msg
+ lappend result [catch {ns c d e} msg] $msg
+ lappend result [catch {ns Magic foo bar spong wibble} msg] $msg
+ list $result [lsort [info commands ::ns::*]] $log [namespace delete ns]
+} {{0 2 0 2 0 2 0 2 1 {unknown or protected subcommand "Magic"}} {::ns::Magic ::ns::a ::ns::b ::ns::c} {{making a} {running ::ns::a b c} {running ::ns::a b c} {making b} {running ::ns::b c d} {making c} {running ::ns::c d e} {unknown Magic - args = foo bar spong wibble}} {}}
+test namespace-47.2 {ensemble: unknown handler} {
+ namespace eval ns {
+ namespace export {[a-z]*}
+ proc Magic {ensemble subcmd args} {
+ error foobar
+ }
+ namespace ensemble create -unknown ::ns::Magic
+ }
+ list [catch {ns spong} msg] $msg $::errorInfo [namespace delete ns]
+} {1 foobar {foobar
+ while executing
+"error foobar"
+ (procedure "::ns::Magic" line 2)
+ invoked from within
+"::ns::Magic ::ns spong"
+ (ensemble unknown subcommand handler)
+ invoked from within
+"ns spong"} {}}
+test namespace-47.3 {ensemble: unknown handler} {
+ namespace eval ns {
+ variable count 0
+ namespace export {[a-z]*}
+ proc a {} {}
+ proc c {} {}
+ proc Magic {ensemble subcmd args} {
+ variable count
+ incr count
+ proc b {} {}
+ }
+ namespace ensemble create -unknown ::ns::Magic
+ }
+ list [catch {ns spong} msg] $msg $ns::count [namespace delete ns]
+} {1 {unknown or ambiguous subcommand "spong": must be a, b, or c} 1 {}}
+test namespace-47.4 {ensemble: unknown handler} {
+ namespace eval ns {
+ namespace export {[a-z]*}
+ proc Magic {ensemble subcmd args} {
+ return -code break
+ }
+ namespace ensemble create -unknown ::ns::Magic
+ }
+ list [catch {ns spong} msg] $msg $::errorInfo [namespace delete ns]
+} {1 {unknown subcommand handler returned bad code: break} {unknown subcommand handler returned bad code: break
+ result of ensemble unknown subcommand handler: ::ns::Magic ::ns spong
+ invoked from within
+"ns spong"} {}}
+test namespace-47.5 {ensemble: unknown handler} {
+ namespace ensemble create -command foo -unknown bar
+ proc bar {args} {
+ global result target
+ lappend result "LOG $args"
+ return $target
+ }
+ set result {}
+ set target {}
+ lappend result [catch {foo bar} msg] $msg
+ set target {lappend result boo hoo}
+ lappend result [catch {foo bar} msg] $msg [namespace ensemble config foo]
+ rename foo {}
+ set result
+} {{LOG ::foo bar} 1 {unknown subcommand "bar": namespace :: does not export any commands} {LOG ::foo bar} boo hoo 0 {{LOG ::foo bar} 1 {unknown subcommand "bar": namespace :: does not export any commands} {LOG ::foo bar} boo hoo} {-map {} -namespace :: -parameters {} -prefixes 1 -subcommands {} -unknown bar}}
+test namespace-47.6 {ensemble: unknown handler} {
+ namespace ensemble create -command foo -unknown bar
+ proc bar {args} {
+ return "\{"
+ }
+ set result [list [catch {foo bar} msg] $msg $::errorInfo]
+ rename foo {}
+ set result
+} {1 {unmatched open brace in list} {unmatched open brace in list
+ while parsing result of ensemble unknown subcommand handler
+ invoked from within
+"foo bar"}}
+test namespace-47.7 {ensemble: unknown handler, commands with spaces} {
+ namespace ensemble create -command foo -unknown bar
+ proc bar {args} {
+ list ::set ::x [join $args |]
+ }
+ set result [foo {one two three}]
+ rename foo {}
+ set result
+} {::foo|one two three}
+test namespace-47.8 {ensemble: unknown handler, commands with spaces} {
+ namespace ensemble create -command foo -unknown {bar boo}
+ proc bar {args} {
+ list ::set ::x [join $args |]
+ }
+ set result [foo {one two three}]
+ rename foo {}
+ set result
+} {boo|::foo|one two three}
+
+test namespace-48.1 {ensembles and namespace import: unknown handler} {
+ namespace eval foo {
+ namespace export bar
+ namespace ensemble create -command bar -unknown ::foo::u -subcomm x
+ proc u {ens args} {
+ global result
+ lappend result $ens $args
+ namespace ensemble config $ens -subcommand {x y}
+ }
+ proc u2 {ens args} {
+ global result
+ lappend result $ens $args
+ namespace ensemble config ::bar -subcommand {x y z}
+ }
+ proc x args {
+ global result
+ lappend result XXX $args
+ }
+ proc y args {
+ global result
+ lappend result YYY $args
+ }
+ proc z args {
+ global result
+ lappend result ZZZ $args
+ }
+ }
+ namespace import -force foo::bar
+ set result [list [namespace ensemble config bar]]
+ bar x 123
+ bar y 456
+ namespace ensemble config bar -unknown ::foo::u2
+ bar z 789
+ namespace delete foo
+ set result
+} {{-map {} -namespace ::foo -parameters {} -prefixes 1 -subcommands x -unknown ::foo::u} XXX 123 ::foo::bar {y 456} YYY 456 ::foo::bar {z 789} ZZZ 789}
+test namespace-48.2 {ensembles and namespace import: exists} {
+ namespace eval foo {
+ namespace ensemble create -command ::foo::bar
+ namespace export bar
+ }
+ set result [namespace ensemble exist foo::bar]
+ lappend result [namespace ensemble exist bar]
+ namespace import foo::bar
+ lappend result [namespace ensemble exist bar]
+ rename foo::bar foo::bar2
+ lappend result [namespace ensemble exist bar] \
+ [namespace ensemble exist spong]
+ rename bar spong
+ lappend result [namespace ensemble exist bar] \
+ [namespace ensemble exist spong]
+ rename foo::bar2 {}
+ lappend result [namespace ensemble exist spong]
+ namespace delete foo
+ set result
+} {1 0 1 1 0 0 1 0}
+test namespace-48.3 {ensembles and namespace import: config} {
+ catch {rename spong {}}
+ namespace eval foo {
+ namespace ensemble create -command ::foo::bar
+ namespace export bar boo
+ proc boo {} {}
+ }
+ namespace import foo::bar foo::boo
+ set result [namespace ensemble config bar -namespace]
+ lappend result [catch {namespace ensemble config boo} msg] $msg
+ lappend result [catch {namespace ensemble config spong} msg] $msg
+ namespace delete foo
+ set result
+} {::foo 1 {"boo" is not an ensemble command} 1 {unknown command "spong"}}
+
+test namespace-49.1 {ensemble subcommand caching} -body {
+ namespace ens cre -command a -map {b {lappend result 1}}
+ namespace ens cre -command c -map {b {lappend result 2}}
+ proc x {} {a b; c b; a b; c b}
+ x
+} -result {1 2 1 2} -cleanup {
+ rename a {}
+ rename c {}
+ rename x {}
+}
+test namespace-49.2 {strange delete crash} -body {
+ namespace eval foo {namespace ensemble create -command ::bar}
+ trace add command ::bar delete DeleteTrace
+ proc DeleteTrace {old new op} {
+ trace remove command ::bar delete DeleteTrace
+ rename $old ""
+ # This next line caused a bus error in [Bug 1220058]
+ namespace delete foo
+ }
+ rename ::bar ""
+} -result "" -cleanup {
+ rename DeleteTrace ""
+}
+
+test namespace-50.1 {ensembles affect proc arguments error messages} -body {
+ namespace ens cre -command a -map {b {bb foo}}
+ proc bb {c d {e f} args} {list $c $args}
+ a b
+} -returnCodes error -result "wrong # args: should be \"a b d ?e? ?arg ...?\"" -cleanup {
+ rename a {}
+ rename bb {}
+}
+test namespace-50.2 {ensembles affect WrongNumArgs error messages} -body {
+ namespace ens cre -command a -map {b {string is}}
+ a b boolean
+} -returnCodes error -result "wrong # args: should be \"a b class ?-strict? ?-failindex var? str\"" -cleanup {
+ rename a {}
+}
+test namespace-50.3 {chained ensembles affect error messages} -body {
+ namespace ens cre -command a -map {b c}
+ namespace ens cre -command c -map {d e}
+ proc e f {}
+ a b d
+} -returnCodes error -result "wrong # args: should be \"a b d f\"" -cleanup {
+ rename a {}
+ rename c {}
+}
+test namespace-50.4 {chained ensembles affect error messages} -body {
+ namespace ens cre -command a -map {b {c d}}
+ namespace ens cre -command c -map {d {e f}}
+ proc e f {}
+ a b d
+} -returnCodes error -result "wrong # args: should be \"a b\"" -cleanup {
+ rename a {}
+ rename c {}
+}
+
+test namespace-51.1 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ namespace eval test_ns_2 {
+ proc pathtestA {} {
+ ::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+ }
+ proc pathtestC {} {
+ ::return 2
+ }
+ }
+ proc pathtestB {} {
+ return 1
+ }
+ proc pathtestC {} {
+ return 1
+ }
+ namespace path ::test_ns_1
+ }
+ proc ::pathtestB {} {
+ return global
+ }
+ proc ::pathtestD {} {
+ return global
+ }
+ test_ns_1::test_ns_2::pathtestA
+} -result "global,2,global," -cleanup {
+ namespace delete ::test_ns_1
+ catch {rename ::pathtestB {}}
+ catch {rename ::pathtestD {}}
+}
+test namespace-51.2 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ namespace eval test_ns_2 {
+ namespace path ::test_ns_1
+ proc pathtestA {} {
+ ::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+ }
+ proc pathtestC {} {
+ ::return 2
+ }
+ }
+ proc pathtestB {} {
+ return 1
+ }
+ proc pathtestC {} {
+ return 1
+ }
+ }
+ proc ::pathtestB {} {
+ return global
+ }
+ proc ::pathtestD {} {
+ return global
+ }
+ ::test_ns_1::test_ns_2::pathtestA
+} -result "1,2,global,::test_ns_1" -cleanup {
+ namespace delete ::test_ns_1
+ catch {rename ::pathtestB {}}
+ catch {rename ::pathtestD {}}
+}
+test namespace-51.3 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ namespace eval test_ns_2 {
+ proc pathtestA {} {
+ ::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+ }
+ proc pathtestC {} {
+ ::return 2
+ }
+ }
+ proc pathtestB {} {
+ return 1
+ }
+ proc pathtestC {} {
+ return 1
+ }
+ }
+ proc ::pathtestB {} {
+ return global
+ }
+ proc ::pathtestD {} {
+ return global
+ }
+ set result [::test_ns_1::test_ns_2::pathtestA]
+ namespace eval ::test_ns_1::test_ns_2 {
+ namespace path ::test_ns_1
+ }
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+ rename ::test_ns_1::pathtestB {}
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+} -result "global,2,global, 1,2,global,::test_ns_1 global,2,global,::test_ns_1" -cleanup {
+ namespace delete ::test_ns_1
+ catch {rename ::pathtestB {}}
+ catch {rename ::pathtestD {}}
+}
+test namespace-51.4 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ namespace eval test_ns_2 {
+ proc pathtestA {} {
+ ::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+ }
+ proc pathtestC {} {
+ ::return 2
+ }
+ }
+ proc pathtestB {} {
+ return 1
+ }
+ proc pathtestC {} {
+ return 1
+ }
+ }
+ proc ::pathtestB {} {
+ return global
+ }
+ proc ::pathtestD {} {
+ return global
+ }
+ set result [::test_ns_1::test_ns_2::pathtestA]
+ namespace eval ::test_ns_1::test_ns_2 {
+ namespace path ::test_ns_1
+ }
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+ namespace eval ::test_ns_1::test_ns_2 {
+ namespace path {}
+ }
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+} -result "global,2,global, 1,2,global,::test_ns_1 global,2,global," -cleanup {
+ namespace delete ::test_ns_1
+ catch {rename ::pathtestB {}}
+ catch {rename ::pathtestD {}}
+}
+test namespace-51.5 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ namespace eval test_ns_2 {
+ proc pathtestA {} {
+ ::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+ }
+ proc pathtestC {} {
+ ::return 2
+ }
+ namespace path ::test_ns_1
+ }
+ proc pathtestB {} {
+ return 1
+ }
+ proc pathtestC {} {
+ return 1
+ }
+ proc pathtestD {} {
+ return 1
+ }
+ }
+ proc ::pathtestB {} {
+ return global
+ }
+ proc ::pathtestD {} {
+ return global
+ }
+ set result [::test_ns_1::test_ns_2::pathtestA]
+ namespace eval ::test_ns_1::test_ns_2 {
+ namespace path {:: ::test_ns_1}
+ }
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+ rename ::test_ns_1::test_ns_2::pathtestC {}
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+} -result "1,2,1,::test_ns_1 {global,2,global,:: ::test_ns_1} {global,1,global,:: ::test_ns_1}" -cleanup {
+ namespace delete ::test_ns_1
+ catch {rename ::pathtestB {}}
+ catch {rename ::pathtestD {}}
+}
+test namespace-51.6 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ namespace eval test_ns_2 {
+ proc pathtestA {} {
+ ::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+ }
+ proc pathtestC {} {
+ ::return 2
+ }
+ namespace path ::test_ns_1
+ }
+ proc pathtestB {} {
+ return 1
+ }
+ proc pathtestC {} {
+ return 1
+ }
+ proc pathtestD {} {
+ return 1
+ }
+ }
+ proc ::pathtestB {} {
+ return global
+ }
+ proc ::pathtestD {} {
+ return global
+ }
+ set result [::test_ns_1::test_ns_2::pathtestA]
+ namespace eval ::test_ns_1::test_ns_2 {
+ namespace path {:: ::test_ns_1}
+ }
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+ rename ::test_ns_1::test_ns_2::pathtestC {}
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+ proc ::pathtestC {} {
+ return global
+ }
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+} -result "1,2,1,::test_ns_1 {global,2,global,:: ::test_ns_1} {global,1,global,:: ::test_ns_1} {global,global,global,:: ::test_ns_1}" -cleanup {
+ namespace delete ::test_ns_1
+ catch {rename ::pathtestB {}}
+ catch {rename ::pathtestD {}}
+}
+test namespace-51.7 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ }
+ namespace eval ::test_ns_2 {
+ namespace path ::test_ns_1
+ proc getpath {} {namespace path}
+ }
+ list [::test_ns_2::getpath] [namespace delete ::test_ns_1] [::test_ns_2::getpath]
+} -result {::test_ns_1 {} {}} -cleanup {
+ catch {namespace delete ::test_ns_1}
+ namespace delete ::test_ns_2
+}
+test namespace-51.8 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ }
+ namespace eval ::test_ns_2 {
+ }
+ namespace eval ::test_ns_3 {
+ }
+ namespace eval ::test_ns_4 {
+ namespace path {::test_ns_1 ::test_ns_2 ::test_ns_3}
+ proc getpath {} {namespace path}
+ }
+ list [::test_ns_4::getpath] [namespace delete ::test_ns_2] [::test_ns_4::getpath]
+} -result {{::test_ns_1 ::test_ns_2 ::test_ns_3} {} {::test_ns_1 ::test_ns_3}} -cleanup {
+ catch {namespace delete ::test_ns_1}
+ catch {namespace delete ::test_ns_2}
+ catch {namespace delete ::test_ns_3}
+ catch {namespace delete ::test_ns_4}
+}
+test namespace-51.9 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ }
+ namespace eval ::test_ns_2 {
+ }
+ namespace eval ::test_ns_3 {
+ }
+ namespace eval ::test_ns_4 {
+ namespace path {::test_ns_1 ::test_ns_2 ::test_ns_3}
+ proc getpath {} {namespace path}
+ }
+ list [::test_ns_4::getpath] [namespace delete ::test_ns_2] [namespace eval ::test_ns_2 {}] [::test_ns_4::getpath]
+} -result {{::test_ns_1 ::test_ns_2 ::test_ns_3} {} {} {::test_ns_1 ::test_ns_3}} -cleanup {
+ catch {namespace delete ::test_ns_1}
+ catch {namespace delete ::test_ns_2}
+ catch {namespace delete ::test_ns_3}
+ catch {namespace delete ::test_ns_4}
+}
+test namespace-51.10 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ namespace path does::not::exist
+ }
+} -returnCodes error -result {namespace "does::not::exist" not found in "::test_ns_1"} -cleanup {
+ catch {namespace delete ::test_ns_1}
+}
+test namespace-51.11 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ proc foo {} {return 1}
+ }
+ namespace eval ::test_ns_2 {
+ proc foo {} {return 2}
+ }
+ namespace eval ::test_ns_3 {
+ namespace path ::test_ns_1
+ }
+ namespace eval ::test_ns_4 {
+ namespace path {::test_ns_3 ::test_ns_2}
+ foo
+ }
+} -result 2 -cleanup {
+ catch {namespace delete ::test_ns_1}
+ catch {namespace delete ::test_ns_2}
+ catch {namespace delete ::test_ns_3}
+ catch {namespace delete ::test_ns_4}
+}
+test namespace-51.12 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ proc foo {} {return 1}
+ }
+ namespace eval ::test_ns_2 {
+ proc foo {} {return 2}
+ }
+ namespace eval ::test_ns_3 {
+ namespace path ::test_ns_1
+ }
+ namespace eval ::test_ns_4 {
+ namespace path {::test_ns_3 ::test_ns_2}
+ list [foo] [namespace delete ::test_ns_3] [foo]
+ }
+} -result {2 {} 2} -cleanup {
+ catch {namespace delete ::test_ns_1}
+ catch {namespace delete ::test_ns_2}
+ catch {namespace delete ::test_ns_3}
+ catch {namespace delete ::test_ns_4}
+}
+test namespace-51.13 {name resolution path control} -body {
+ set ::result {}
+ namespace eval ::test_ns_1 {
+ proc foo {} {lappend ::result 1}
+ }
+ namespace eval ::test_ns_2 {
+ proc foo {} {lappend ::result 2}
+ trace add command foo delete "namespace eval ::test_ns_3 foo;#"
+ }
+ namespace eval ::test_ns_3 {
+ proc foo {} {
+ lappend ::result 3
+ namespace delete [namespace current]
+ ::test_ns_4::bar
+ }
+ }
+ namespace eval ::test_ns_4 {
+ namespace path {::test_ns_2 ::test_ns_3 ::test_ns_1}
+ proc bar {} {
+ list [foo] [namespace delete ::test_ns_2] [foo]
+ }
+ bar
+ }
+ # Should the result be "2 {} {2 3 2 1}" instead?
+} -result {2 {} {2 3 1 1}} -cleanup {
+ catch {namespace delete ::test_ns_1}
+ catch {namespace delete ::test_ns_2}
+ catch {namespace delete ::test_ns_3}
+ catch {namespace delete ::test_ns_4}
+}
+test namespace-51.14 {name resolution path control} -setup {
+ foreach cmd [info commands foo*] {
+ rename $cmd {}
+ }
+ namespace eval ::test_ns_1 {}
+ namespace eval ::test_ns_2 {}
+ namespace eval ::test_ns_3 {}
+} -body {
+ proc foo0 {} {}
+ proc ::test_ns_1::foo1 {} {}
+ proc ::test_ns_2::foo2 {} {}
+ namespace eval ::test_ns_3 {
+ variable result {}
+ lappend result [info commands foo*]
+ namespace path {::test_ns_1 ::test_ns_2}
+ lappend result [info commands foo*]
+ proc foo2 {} {}
+ lappend result [info commands foo*]
+ rename foo2 {}
+ lappend result [info commands foo*]
+ namespace delete ::test_ns_1
+ lappend result [info commands foo*]
+ }
+} -cleanup {
+ catch {namespace delete ::test_ns_1}
+ catch {namespace delete ::test_ns_2}
+ catch {namespace delete ::test_ns_3}
+} -result {foo0 {foo1 foo2 foo0} {foo2 foo1 foo0} {foo1 foo2 foo0} {foo2 foo0}}
+test namespace-51.15 {namespace resolution path control} -body {
+ namespace eval ::test_ns_2 {
+ proc foo {} {return 2}
+ }
+ namespace eval ::test_ns_1 {
+ namespace eval test_ns_2 {
+ proc foo {} {return 1_2}
+ }
+ namespace eval test_ns_3 {
+ namespace path ::test_ns_1
+ test_ns_2::foo
+ }
+ }
+} -result 1_2 -cleanup {
+ namespace delete ::test_ns_1
+ namespace delete ::test_ns_2
+}
+test namespace-51.16 {Bug 1566526} {
+ interp create slave
+ slave eval namespace eval demo namespace path ::
+ interp delete slave
+} {}
+test namespace-51.17 {resolution epoch handling: Bug 2898722} -setup {
+ set result {}
+ catch {namespace delete ::a}
+} -body {
+ namespace eval ::a {
+ proc c {} {lappend ::result A}
+ c
+ namespace eval b {
+ variable d c
+ lappend ::result [catch { $d }]
+ }
+ lappend ::result .
+ namespace eval b {
+ namespace path [namespace parent]
+ $d;[format %c 99]
+ }
+ lappend ::result .
+ namespace eval b {
+ proc c {} {lappend ::result B}
+ $d;[format %c 99]
+ }
+ lappend ::result .
+ }
+ namespace eval ::a::b {
+ $d;[format %c 99]
+ lappend ::result .
+ proc ::c {} {lappend ::result G}
+ $d;[format %c 99]
+ lappend ::result .
+ rename ::a::c {}
+ $d;[format %c 99]
+ lappend ::result .
+ rename ::a::b::c {}
+ $d;[format %c 99]
+ }
+} -cleanup {
+ namespace delete ::a
+ catch {rename ::c {}}
+ unset result
+} -result {A 1 . A A . B B . B B . B B . B B . G G}
+test namespace-51.18 {Bug 3185407} -setup {
+ namespace eval ::test_ns_1 {}
+} -body {
+ namespace eval ::test_ns_1 {
+ variable result {}
+ namespace eval ns {proc foo {} {}}
+ namespace eval ns2 {proc foo {} {}}
+ namespace path {ns ns2}
+ variable x foo
+ lappend result [namespace which $x]
+ proc foo {} {}
+ lappend result [namespace which $x]
+ }
+} -cleanup {
+ namespace delete ::test_ns_1
+} -result {::test_ns_1::ns::foo ::test_ns_1::foo}
+
+# TIP 181 - namespace unknown tests
+test namespace-52.1 {unknown: default handler ::unknown} {
+ set result [list [namespace eval foobar { namespace unknown }]]
+ lappend result [namespace eval :: { namespace unknown }]
+ namespace delete foobar
+ set result
+} {{} ::unknown}
+test namespace-52.2 {unknown: default resolution global} {
+ proc ::foo {} { return "GLOBAL" }
+ namespace eval ::bar { proc foo {} { return "NAMESPACE" } }
+ namespace eval ::bar::jim { proc test {} { foo } }
+ set result [::bar::jim::test]
+ namespace delete ::bar
+ rename ::foo {}
+ set result
+} {GLOBAL}
+test namespace-52.3 {unknown: default resolution local} {
+ proc ::foo {} { return "GLOBAL" }
+ namespace eval ::bar {
+ proc foo {} { return "NAMESPACE" }
+ proc test {} { foo }
+ }
+ set result [::bar::test]
+ namespace delete ::bar
+ rename ::foo {}
+ set result
+} {NAMESPACE}
+test namespace-52.4 {unknown: set handler} {
+ namespace eval foo {
+ namespace unknown [list dispatch]
+ proc dispatch {args} { return $args }
+ proc test {} {
+ UnknownCmd a b c
+ }
+ }
+ set result [foo::test]
+ namespace delete foo
+ set result
+} {UnknownCmd a b c}
+test namespace-52.5 {unknown: search path before unknown is unaltered} {
+ proc ::test2 {args} { return "TEST2: $args" }
+ namespace eval foo {
+ namespace unknown [list dispatch]
+ proc dispatch {args} { return "UNKNOWN: $args" }
+ proc test1 {args} { return "TEST1: $args" }
+ proc test {} {
+ set result [list [test1 a b c]]
+ lappend result [test2 a b c]
+ lappend result [test3 a b c]
+ return $result
+ }
+ }
+ set result [foo::test]
+ namespace delete foo
+ rename ::test2 {}
+ set result
+} {{TEST1: a b c} {TEST2: a b c} {UNKNOWN: test3 a b c}}
+test namespace-52.6 {unknown: deleting handler restores default} {
+ rename ::unknown ::_unknown_orig
+ proc ::unknown {args} { return "DEFAULT: $args" }
+ namespace eval foo {
+ namespace unknown dummy
+ namespace unknown {}
+ }
+ set result [namespace eval foo { dummy a b c }]
+ rename ::unknown {}
+ rename ::_unknown_orig ::unknown
+ namespace delete foo
+ set result
+} {DEFAULT: dummy a b c}
+test namespace-52.7 {unknown: setting global unknown handler} {
+ proc ::myunknown {args} { return "MYUNKNOWN: $args" }
+ namespace eval :: { namespace unknown ::myunknown }
+ set result [namespace eval foo { dummy a b c }]
+ namespace eval :: { namespace unknown {} }
+ rename ::myunknown {}
+ namespace delete foo
+ set result
+} {MYUNKNOWN: dummy a b c}
+test namespace-52.8 {unknown: destroying and redefining global namespace} {
+ set i [interp create]
+ $i hide proc
+ $i hide namespace
+ $i hide return
+ $i invokehidden namespace delete ::
+ $i expose return
+ $i invokehidden proc unknown args { return "FINE" }
+ $i eval { foo bar bob }
+} {FINE}
+test namespace-52.9 {unknown: refcounting} -setup {
+ proc this args {
+ unset args ;# stop sharing
+ set copy [namespace unknown]
+ string length $copy ;# shimmer away list rep
+ info level 0
+ }
+ set handler [namespace unknown]
+ namespace unknown {this is a test}
+ catch {rename noSuchCommand {}}
+} -body {
+ noSuchCommand
+} -cleanup {
+ namespace unknown $handler
+ rename this {}
+} -result {this is a test noSuchCommand}
+testConstraint testevalobjv [llength [info commands testevalobjv]]
+test namespace-52.10 {unknown: with TCL_EVAL_GLOBAL} -constraints {
+ testevalobjv
+} -setup {
+ rename ::unknown unknown.save
+ proc ::unknown args {
+ set caller [uplevel 1 {namespace current}]
+ namespace eval $caller {
+ variable foo
+ return $foo
+ }
+ }
+ catch {rename ::noSuchCommand {}}
+} -body {
+ namespace eval :: {
+ variable foo SUCCESS
+ }
+ namespace eval test_ns_1 {
+ variable foo FAIL
+ testevalobjv 1 noSuchCommand
+ }
+} -cleanup {
+ unset -nocomplain ::foo
+ namespace delete test_ns_1
+ rename ::unknown {}
+ rename unknown.save ::unknown
+} -result SUCCESS
+test namespace-52.11 {unknown: with TCL_EVAL_INVOKE} -setup {
+ set handler [namespace eval :: {namespace unknown}]
+ namespace eval :: {namespace unknown unknown}
+ rename ::unknown unknown.save
+ namespace eval :: {
+ proc unknown args {
+ return SUCCESS
+ }
+ }
+ catch {rename ::noSuchCommand {}}
+ set ::slave [interp create]
+} -body {
+ $::slave alias bar noSuchCommand
+ namespace eval test_ns_1 {
+ namespace unknown unknown
+ proc unknown args {
+ return FAIL
+ }
+ $::slave eval bar
+ }
+} -cleanup {
+ interp delete $::slave
+ unset ::slave
+ namespace delete test_ns_1
+ rename ::unknown {}
+ rename unknown.save ::unknown
+ namespace eval :: [list namespace unknown $handler]
+} -result SUCCESS
+test namespace-52.12 {unknown: error case must not reset handler} -body {
+ namespace eval foo {
+ namespace unknown ok
+ catch {namespace unknown {{}{}{}}}
+ namespace unknown
+ }
+} -cleanup {
+ namespace delete foo
+} -result ok
+
+# TIP 314 - ensembles with parameters
+test namespace-53.1 {ensembles: parameters} {
+ namespace eval ns {
+ namespace export x
+ proc x {para} {list 1 $para}
+ namespace ensemble create -parameters {para1}
+ }
+ list [info command ns] [ns bar x] [namespace delete ns] [info command ns]
+} {ns {1 bar} {} {}}
+test namespace-53.2 {ensembles: parameters} -setup {
+ namespace eval ns {
+ namespace export x
+ proc x {para} {list 1 $para}
+ namespace ensemble create
+ }
+} -body {
+ namespace ensemble configure ns -parameters {para1}
+ rename ns foo
+ list [info command foo] [foo bar x] [namespace delete ns] [info command foo]
+} -result {foo {1 bar} {} {}}
+test namespace-53.3 {ensembles: parameters} -setup {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {para} {list 1 $para}
+ proc x2 {para} {list 2 $para}
+ namespace ensemble create -parameters param1
+ }
+} -body {
+ set result [list [ns x2 x1] [ns x1 x2]]
+ lappend result [catch {ns x} msg] $msg
+ lappend result [catch {ns x x} msg] $msg
+ rename ns {}
+ lappend result [info command ns::x1]
+ namespace delete ns
+ lappend result [info command ns::x1]
+} -result\
+ {{1 x2} {2 x1}\
+ 1 {wrong # args: should be "ns param1 subcommand ?arg ...?"}\
+ 1 {unknown or ambiguous subcommand "x": must be x1, or x2}\
+ ::ns::x1 {}}
+test namespace-53.4 {ensembles: parameters} -setup {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {a1 a2} {list 1 $a1 $a2}
+ proc x2 {a1 a2} {list 2 $a1 $a2}
+ proc x3 {a1 a2} {list 3 $a1 $a2}
+ namespace ensemble create
+ }
+} -body {
+ set result {}
+ lappend result [ns x1 x2 x3]
+ namespace ensemble configure ns -parameters p1
+ lappend result [ns x1 x2 x3]
+ namespace ensemble configure ns -parameters {p1 p2}
+ lappend result [ns x1 x2 x3]
+} -cleanup {
+ namespace delete ns
+} -result {{1 x2 x3} {2 x1 x3} {3 x1 x2}}
+test namespace-53.5 {ensembles: parameters} -setup {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {para} {list 1 $para}
+ proc x2 {para} {list 2 $para}
+ proc x3 {para} {list 3 $para}
+ namespace ensemble create
+ }
+} -body {
+ set result [list [catch {ns x x1} msg] $msg]
+ lappend result [catch {ns x1 x} msg] $msg
+ namespace ensemble configure ns -parameters p1
+ lappend result [catch {ns x1 x} msg] $msg
+ lappend result [catch {ns x x1} msg] $msg
+} -cleanup {
+ namespace delete ns
+} -result\
+ {1 {unknown or ambiguous subcommand "x": must be x1, x2, or x3}\
+ 0 {1 x}\
+ 1 {unknown or ambiguous subcommand "x": must be x1, x2, or x3}\
+ 0 {1 x}}
+test namespace-53.6 {ensembles: nested} -setup {
+ namespace eval ns {
+ namespace export x*
+ namespace eval x0 {
+ proc z {args} {list 0 $args}
+ namespace export z
+ namespace ensemble create
+ }
+ proc x1 {args} {list 1 $args}
+ proc x2 {args} {list 2 $args}
+ proc x3 {args} {list 3 $args}
+ namespace ensemble create -parameters p
+ }
+} -body {
+ list [ns z x0] [ns z x1] [ns z x2] [ns z x3]
+} -cleanup {
+ namespace delete ns
+} -result {{0 {}} {1 z} {2 z} {3 z}}
+test namespace-53.7 {ensembles: parameters & wrong # args} -setup {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {a1 a2 a3 a4} {list x1 $a1 $a2 $a3 $a4}
+ namespace ensemble create -parameters p1
+ }
+} -body {
+ set result {}
+ lappend result [catch {ns} msg] $msg
+ lappend result [catch {ns x1} msg] $msg
+ lappend result [catch {ns x1 x1} msg] $msg
+ lappend result [catch {ns x1 x1 x1} msg] $msg
+ lappend result [catch {ns x1 x1 x1 x1} msg] $msg
+ lappend result [catch {ns x1 x1 x1 x1 x1} msg] $msg
+} -cleanup {
+ namespace delete ns
+} -result\
+ {1 {wrong # args: should be "ns p1 subcommand ?arg ...?"}\
+ 1 {wrong # args: should be "ns p1 subcommand ?arg ...?"}\
+ 1 {wrong # args: should be "ns x1 x1 a2 a3 a4"}\
+ 1 {wrong # args: should be "ns x1 x1 a2 a3 a4"}\
+ 1 {wrong # args: should be "ns x1 x1 a2 a3 a4"}\
+ 0 {x1 x1 x1 x1 x1}}
+test namespace-53.8 {ensemble: unknown handler changing -parameters} -setup {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {a1} {list 1 $a1}
+ proc Magic {ensemble subcmd args} {
+ namespace ensemble configure $ensemble\
+ -parameters [lrange p1 [llength [
+ namespace ensemble configure $ensemble -parameters
+ ]] 0]
+ list
+ }
+ namespace ensemble create -unknown ::ns::Magic
+ }
+} -body {
+ set result {}
+ lappend result [catch {ns x1 x2} msg] $msg [namespace ensemble configure ns -parameters]
+ lappend result [catch {ns x2 x1} msg] $msg [namespace ensemble configure ns -parameters]
+ lappend result [catch {ns x2 x3} msg] $msg [namespace ensemble configure ns -parameters]
+} -cleanup {
+ namespace delete ns
+} -result\
+ {0 {1 x2} {}\
+ 0 {1 x2} p1\
+ 1 {unknown or ambiguous subcommand "x2": must be x1} {}}
+test namespace-53.9 {ensemble: unknown handler changing -parameters,\
+ thereby eating all args} -setup {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {args} {list 1 $args}
+ proc Magic {ensemble subcmd args} {
+ namespace ensemble configure $ensemble\
+ -parameters {p1 p2 p3 p4 p5}
+ list
+ }
+ namespace ensemble create -unknown ::ns::Magic
+ }
+} -body {
+ set result {}
+ lappend result [catch {ns x1 x2} msg] $msg [namespace ensemble configure ns -parameters]
+ lappend result [catch {ns x2 x1} msg] $msg [namespace ensemble configure ns -parameters]
+ lappend result [catch {ns a1 a2 a3 a4 a5 x1} msg] $msg [namespace ensemble configure ns -parameters]
+} -cleanup {
+ namespace delete ns
+} -result\
+ {0 {1 x2} {}\
+ 1 {wrong # args: should be "ns p1 p2 p3 p4 p5 subcommand ?arg ...?"} {p1 p2 p3 p4 p5}\
+ 0 {1 {a1 a2 a3 a4 a5}} {p1 p2 p3 p4 p5}}
+test namespace-53.10 {ensembles: nested rewrite} -setup {
+ namespace eval ns {
+ namespace export x
+ namespace eval x {
+ proc z0 {} {list 0}
+ proc z1 {a1} {list 1 $a1}
+ proc z2 {a1 a2} {list 2 $a1 $a2}
+ proc z3 {a1 a2 a3} {list 3 $a1 $a2 $a3}
+ namespace export z*
+ namespace ensemble create
+ }
+ namespace ensemble create -parameters p
+ }
+} -body {
+ set result {}
+ # In these cases, parsing the subensemble does not grab a new word.
+ lappend result [catch {ns z0 x} msg] $msg
+ lappend result [catch {ns z1 x} msg] $msg
+ lappend result [catch {ns z2 x} msg] $msg
+ lappend result [catch {ns z2 x v} msg] $msg
+ namespace ensemble configure ns::x -parameters q1
+ # In these cases, parsing the subensemble grabs a new word.
+ lappend result [catch {ns v x z0} msg] $msg
+ lappend result [catch {ns v x z1} msg] $msg
+ lappend result [catch {ns v x z2} msg] $msg
+ lappend result [catch {ns v x z2 v2} msg] $msg
+} -cleanup {
+ namespace delete ns
+} -result\
+ {0 0\
+ 1 {wrong # args: should be "ns z1 x a1"}\
+ 1 {wrong # args: should be "ns z2 x a1 a2"}\
+ 1 {wrong # args: should be "ns z2 x a1 a2"}\
+ 1 {wrong # args: should be "::ns::x::z0"}\
+ 0 {1 v}\
+ 1 {wrong # args: should be "ns v x z2 a2"}\
+ 0 {2 v v2}}
+
+test namespace-54.1 {leak on namespace deletion} -constraints {memory} \
+-setup {
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex $lines 3 3
+ }
+} -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ set ns ::y$i
+ namespace eval $ns {}
+ namespace delete $ns
+ set start $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $start}]
+} -cleanup {
+ rename getbytes {}
+ unset i ns start end
+} -result 0
+
+# cleanup
+catch {rename cmd1 {}}
+catch {unset l}
+catch {unset msg}
+catch {unset trigger}
+namespace delete {*}[namespace children :: test_ns_*]
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/notify.test b/library/msgcat/tests/notify.test
new file mode 100755
index 0000000..ba52c50
--- /dev/null
+++ b/library/msgcat/tests/notify.test
@@ -0,0 +1,324 @@
+# -*- tcl -*-
+#
+# notify.test --
+#
+# This file tests several functions in the file, 'generic/tclNotify.c'.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 2003 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testevent [llength [info commands testevent]]
+
+test notify-1.1 {Tcl_QueueEvent and delivery of a single event} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result {one}
+
+test notify-1.2 {Tcl_QueueEvent and delivery of events in order} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent queue two tail {lappend delivered two; expr 1}
+ testevent queue three tail {lappend delivered three; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result {one two three}
+
+test notify-1.3 {Tcl_QueueEvent at head} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one head {lappend delivered one; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result one
+
+test notify-1.4 {Tcl_QueueEvent multiple events at head} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one head {lappend delivered one; expr 1}
+ testevent queue two head {lappend delivered two; expr 1}
+ testevent queue three head {lappend delivered three; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result {three two one}
+
+test notify-1.5 {Tcl_QueueEvent marker event into an empty queue} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result one
+
+test notify-1.6 {Tcl_QueueEvent first marker event in a nonempty queue} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent queue two mark {lappend delivered two; expr 1}
+ testevent queue three head {lappend delivered three; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result {three two one}
+
+test notify-1.7 {Tcl_QueueEvent second marker event} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent queue two mark {lappend delivered two; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result {one two}
+
+test notify-1.8 {Tcl_QueueEvent preexisting event following second marker} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent queue two tail {lappend delivered two; expr 1}
+ testevent queue three mark {lappend delivered three; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result {one three two}
+
+test notify-2.1 {remove sole element, don't replace } \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent delete one
+ vwait done
+ set delivered
+ } \
+ -result {}
+
+test notify-2.2 {remove and replace sole element} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent delete one
+ testevent queue two tail {lappend delivered two; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result two
+
+test notify-2.3 {remove first element} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent queue two tail {lappend delivered two; expr 1}
+ testevent delete one
+ vwait done
+ set delivered
+ } \
+ -result {two}
+
+test notify-2.4 {remove and replace first element} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent queue two tail {lappend delivered two; expr 1}
+ testevent delete one
+ testevent queue three head {lappend delivered three; expr 1};
+ vwait done
+ set delivered
+ } \
+ -result {three two}
+
+test notify-2.5 {remove last element} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent queue two tail {lappend delivered two; expr 1}
+ testevent delete two
+ vwait done
+ set delivered
+ } \
+ -result {one}
+
+
+test notify-2.6 {remove and replace last element} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent queue two tail {lappend delivered two; expr 1}
+ testevent delete two
+ testevent queue three tail {lappend delivered three; expr 1};
+ vwait done
+ set delivered
+ } \
+ -result {one three}
+
+test notify-2.7 {remove a middle element} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent queue two tail {lappend delivered two; expr 1}
+ testevent queue three tail {lappend delivered three; expr 1}
+ testevent delete two
+ vwait done
+ set delivered
+ } \
+ -result {one three}
+
+test notify-2.8 {remove a marker event that's the sole event in the queue} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent delete one
+ vwait done
+ set delivered
+ } \
+ -result {}
+
+test notify-2.9 {remove and replace a marker event that's the sole event} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent delete one
+ testevent queue two mark {lappend delivered two; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result two
+
+test notify-2.10 {remove marker event from head} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent queue two mark {lappend delivered two; expr 1}
+ testevent delete one
+ vwait done
+ set delivered
+ } \
+ -result two
+
+test notify-2.11 {remove and replace marker event at head} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent queue two tail {lappend delivered two; expr 1}
+ testevent delete one
+ testevent queue three mark {lappend delivered three; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result {three two}
+
+test notify-2.12 {remove marker event at tail} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent queue two mark {lappend delivered two; expr 1}
+ testevent delete two
+ vwait done
+ set delivered
+ } \
+ -result {one}
+
+test notify-2.13 {remove and replace marker event at tail} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent queue two mark {lappend delivered two; expr 1}
+ testevent delete two
+ testevent queue three mark {lappend delivered three; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result {one three}
+
+test notify-2.14 {remove marker event from middle} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent queue two mark {lappend delivered two; expr 1}
+ testevent queue three mark {lappend delivered three; expr 1}
+ testevent delete two
+ vwait done
+ set delivered
+ } \
+ -result {one three}
+
+test notify-2.15 {remove and replace marker event at middle} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent queue two mark {lappend delivered two; expr 1}
+ testevent queue three tail {lappend delivered three; expr 1}
+ testevent delete two
+ testevent queue four mark {lappend delivered four; expr 1};
+ vwait done
+ set delivered
+ } \
+ -result {one four three}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/nre.test b/library/msgcat/tests/nre.test
new file mode 100644
index 0000000..295f02e
--- /dev/null
+++ b/library/msgcat/tests/nre.test
@@ -0,0 +1,445 @@
+# Commands covered: proc, apply, [interp alias], [namespce import]
+#
+# This file contains a collection of tests for the non-recursive executor that
+# avoids recursive calls to TEBC. Only the NRE behaviour is tested here, the
+# actual command functionality is tested in the specific test file.
+#
+# Copyright (c) 2008 by Miguel Sofer.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testnrelevels [llength [info commands testnrelevels]]
+
+#
+# The tests that risked blowing the C stack on failure have been removed: we
+# can now actually measure using testnrelevels.
+#
+
+if {[testConstraint testnrelevels]} {
+ namespace eval testnre {
+ namespace path ::tcl::mathop
+ #
+ # [testnrelevels] returns a 6-list with: C-stack depth, iPtr->numlevels,
+ # cmdFrame level, callFrame level, tosPtr and callback depth
+ #
+ variable last [testnrelevels]
+ proc depthDiff {} {
+ variable last
+ set depth [testnrelevels]
+ set res {}
+ foreach t $depth l $last {
+ lappend res [expr {$t-$l}]
+ }
+ set last $depth
+ return $res
+ }
+ proc setabs {} {
+ variable abs [- [lindex [testnrelevels] 0]]
+ }
+
+ variable body0 {
+ set x [depthDiff]
+ if {[incr i] > 10} {
+ namespace upvar [namespace qualifiers \
+ [namespace origin depthDiff]] abs abs
+ incr abs [lindex [testnrelevels] 0]
+ return [list [lrange $x 0 3] $abs]
+ }
+ }
+ proc makebody txt {
+ variable body0
+ return "$body0; $txt"
+ }
+ namespace export *
+ }
+ namespace import testnre::*
+}
+
+test nre-1.1 {self-recursive procs} -setup {
+ proc a i [makebody {a $i}]
+} -body {
+ setabs
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 1 1 1} 0}
+
+test nre-1.2 {self-recursive lambdas} -setup {
+ set a [list i [makebody {apply $::a $i}]]
+} -body {
+ setabs
+ apply $a 0
+} -cleanup {
+ unset a
+} -constraints {
+ testnrelevels
+} -result {{0 1 1 1} 0}
+
+test nre-1.3 {mutually recursive procs and lambdas} -setup {
+ proc a i {
+ apply $::b [incr i]
+ }
+ set b [list i [makebody {a $i}]]
+} -body {
+ setabs
+ a 0
+} -cleanup {
+ rename a {}
+ unset b
+} -constraints {
+ testnrelevels
+} -result {{0 2 2 2} 0}
+
+#
+# Test that aliases are non-recursive
+#
+
+test nre-2.1 {alias is not recursive} -setup {
+ proc a i [makebody {b $i}]
+ interp alias {} b {} a
+} -body {
+ setabs
+ a 0
+} -cleanup {
+ rename a {}
+ rename b {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 1 1} 0}
+
+#
+# Test that imports are non-recursive
+#
+
+test nre-3.1 {imports are not recursive} -setup {
+ namespace eval foo {
+ setabs
+ namespace export a
+ }
+ proc foo::a i [makebody {::a $i}]
+ namespace import foo::a
+} -body {
+ a 0
+} -cleanup {
+ rename a {}
+ namespace delete ::foo
+} -constraints {
+ testnrelevels
+} -result {{0 2 1 1} 0}
+
+test nre-4.1 {ensembles are not recursive} -setup {
+ proc a i [makebody {b foo $i}]
+ namespace ensemble create \
+ -command b \
+ -map [list foo a]
+} -body {
+ setabs
+ a 0
+} -cleanup {
+ rename a {}
+ rename b {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 1 1} 0}
+
+test nre-5.1 {[namespace eval] is not recursive} -setup {
+ namespace eval ::foo {
+ setabs
+ }
+ proc foo::a i [makebody {namespace eval ::foo [list a $i]}]
+} -body {
+ ::foo::a 0
+} -cleanup {
+ namespace delete ::foo
+} -constraints {
+ testnrelevels
+} -result {{0 3 2 2} 0}
+
+test nre-5.2 {[namespace eval] is not recursive} -setup {
+ namespace eval ::foo {
+ setabs
+ }
+ proc foo::a i [makebody {namespace eval ::foo "set x $i; a $i"}]
+} -body {
+ foo::a 0
+} -cleanup {
+ namespace delete ::foo
+} -constraints {
+ testnrelevels
+} -result {{0 3 2 2} 0}
+
+test nre-6.1 {[uplevel] is not recursive} -setup {
+ proc a i [makebody {uplevel 1 [list a $i]}]
+} -body {
+ setabs
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 2 0} 0}
+
+test nre-6.2 {[uplevel] is not recursive} -setup {
+ setabs
+ proc a i [makebody {uplevel 1 "set x $i; a $i"}]
+} -body {
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 2 0} 0}
+
+test nre-7.1 {[catch] is not recursive} -setup {
+ setabs
+ proc a i [makebody {uplevel 1 "catch {a $i} msg; set msg"}]
+} -body {
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 3 3 0} 0}
+
+test nre-7.2 {[if] is not recursive} -setup {
+ setabs
+ proc a i [makebody {uplevel 1 "if 1 {a $i}"}]
+} -body {
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 2 0} 0}
+
+test nre-7.3 {[while] is not recursive} -setup {
+ setabs
+ proc a i [makebody {uplevel 1 "while 1 {set res \[a $i\]; break}; set res"}]
+} -body {
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 2 0} 0}
+
+test nre-7.4 {[for] is not recursive} -setup {
+ setabs
+ proc a i [makebody {uplevel 1 "for {set j 0} {\$j < 10} {incr j} {set res \[a $i\]; break}; set res"}]
+} -body {
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 2 0} 0}
+
+test nre-7.5 {[foreach] is not recursive} -setup {
+ #
+ # Enable once [foreach] is NR-enabled
+ #
+ setabs
+ proc a i [makebody {uplevel 1 "foreach j {1 2 3 4 5 6} {set res \[a $i\]; break}; set res"}]
+} -body {
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 3 3 0} 0}
+
+test nre-7.6 {[eval] is not recursive} -setup {
+ proc a i [makebody {eval [list a $i]}]
+} -body {
+ setabs
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 2 1} 0}
+
+test nre-7.7 {[eval] is not recursive} -setup {
+ proc a i [makebody {eval "a $i"}]
+} -body {
+ setabs
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 2 1} 0}
+
+test nre-7.8 {bug #2910748: switch out of stale BC is not nre-aware} -setup {
+ proc foo args {}
+ foo
+ coroutine bar apply {{} {
+ yield
+ proc foo args {return ok}
+ while 1 {
+ yield [incr i]
+ foo
+ }
+ }}
+} -body {
+ # if switching to plain eval is not nre aware, this will cause a "cannot
+ # yield" error
+
+ list [bar] [bar] [bar]
+} -cleanup {
+ rename bar {}
+ rename foo {}
+} -result {1 2 3}
+
+
+test nre-8.1 {nre and {*}} -body {
+ # force an expansion that grows the evaluation stack, check that nre
+ # adapts the TEBCdataPtr. This crashes on failure.
+
+ proc inner {} {
+ set long [lrepeat 1000000 1]
+ list {*}$long
+ }
+ proc outer {} inner
+ lrange [outer] 0 2
+} -cleanup {
+ rename inner {}
+ rename outer {}
+} -result {1 1 1}
+test nre-8.2 {nre and {*}, [Bug 2415422]} -body {
+ # force an expansion that grows the evaluation stack, check that nre
+ # adapts the bcFramePtr. This causes an NRE assertion to fail if it is not
+ # done properly.
+
+ proc nop {} {}
+ proc crash {} {
+ foreach val [list {*}[lrepeat 100000 x]] {
+ nop
+ }
+ }
+
+ crash
+} -cleanup {
+ rename nop {}
+ rename crash {}
+}
+
+
+#
+# Basic TclOO tests
+#
+
+test nre-oo.1 {really deep calls in oo - direct} -setup {
+ oo::object create foo
+ oo::objdefine foo method bar i [makebody {foo bar $i}]
+} -body {
+ setabs
+ foo bar 0
+} -cleanup {
+ foo destroy
+} -constraints {
+ testnrelevels
+} -result {{0 1 1 1} 0}
+
+test nre-oo.2 {really deep calls in oo - call via [self]} -setup {
+ oo::object create foo
+ oo::objdefine foo method bar i [makebody {[self] bar $i}]
+} -body {
+ setabs
+ foo bar 0
+} -cleanup {
+ foo destroy
+} -constraints {
+ testnrelevels
+} -result {{0 1 1 1} 0}
+
+test nre-oo.3 {really deep calls in oo - private calls} -setup {
+ oo::object create foo
+ oo::objdefine foo method bar i [makebody {my bar $i}]
+} -body {
+ setabs
+ foo bar 0
+} -cleanup {
+ foo destroy
+} -constraints {
+ testnrelevels
+} -result {{0 1 1 1} 0}
+
+test nre-oo.4 {really deep calls in oo - overriding} -setup {
+ oo::class create foo {
+ method bar i [makebody {my bar $i}]
+ }
+ oo::class create boo {
+ superclass foo
+ method bar i [makebody {next $i}]
+ }
+} -body {
+ setabs
+ [boo new] bar 0
+} -cleanup {
+ foo destroy
+} -constraints {
+ testnrelevels
+} -result {{0 1 1 1} 0}
+
+test nre-oo.5 {really deep calls in oo - forwards} -setup {
+ oo::object create foo
+ set body [makebody {my boo $i}]
+ oo::objdefine foo "
+ method bar i {$body}
+ forward boo ::foo bar
+ "
+} -body {
+ setabs
+ foo bar 0
+} -cleanup {
+ foo destroy
+} -constraints {
+ testnrelevels
+} -result {{0 2 1 1} 0}
+
+
+#
+# NASTY BUG found by tcllib's interp package
+#
+
+test nre-X.1 {eval in wrong interp} -setup {
+ set i [interp create]
+ $i eval {proc filter lst {lsearch -all -inline -not $lst "::tcl"}}
+} -body {
+ $i eval {
+ set x {namespace children ::}
+ set y [list namespace children ::]
+ namespace delete {*}[filter [{*}$y]]
+ set j [interp create]
+ $j alias filter filter
+ $j eval {namespace delete {*}[filter [namespace children ::]]}
+ namespace eval foo {}
+ list [filter [eval $x]] [filter [eval $y]] [filter [$j eval $x]] [filter [$j eval $y]]
+ }
+} -cleanup {
+ interp delete $i
+} -result {::foo ::foo {} {}}
+
+# cleanup
+::tcltest::cleanupTests
+
+if {[testConstraint testnrelevels]} {
+ namespace forget testnre::*
+ namespace delete testnre
+}
+
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/obj.test b/library/msgcat/tests/obj.test
new file mode 100644
index 0000000..126d5ca
--- /dev/null
+++ b/library/msgcat/tests/obj.test
@@ -0,0 +1,632 @@
+# Functionality covered: this file contains a collection of tests for the
+# procedures in tclObj.c that implement Tcl's basic type support and the
+# type managers for the types boolean, double, and integer.
+#
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 1995-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testobj [llength [info commands testobj]]
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}]
+
+test obj-1.1 {Tcl_AppendAllObjTypes, and InitTypeTable, Tcl_RegisterObjType} testobj {
+ set r 1
+ foreach {t} {
+ {array search}
+ bytearray
+ bytecode
+ cmdName
+ dict
+ end-offset
+ regexp
+ string
+ } {
+ set first [string first $t [testobj types]]
+ set r [expr {$r && ($first != -1)}]
+ }
+ set result $r
+} {1}
+
+test obj-2.1 {Tcl_GetObjType error} testobj {
+ list [testintobj set 1 0] [catch {testobj convert 1 foo} msg] $msg
+} {0 1 {no type foo found}}
+test obj-2.2 {Tcl_GetObjType and Tcl_ConvertToType} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testintobj set 1 12]
+ lappend result [testobj convert 1 bytearray]
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 12 12 bytearray 3}
+
+test obj-3.1 {Tcl_ConvertToType error} testobj {
+ list [testdoubleobj set 1 12.34] \
+ [catch {testobj convert 1 end-offset} msg] \
+ $msg
+} {12.34 1 {bad index "12.34": must be end?[+-]integer?}}
+test obj-3.2 {Tcl_ConvertToType error, "empty string" object} testobj {
+ list [testobj newobj 1] [catch {testobj convert 1 end-offset} msg] $msg
+} {{} 1 {bad index "": must be end?[+-]integer?}}
+
+test obj-4.1 {Tcl_NewObj and AllocateFreeObjects} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testobj newobj 1]
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} {} string 2}
+
+test obj-5.1 {Tcl_FreeObj} testobj {
+ set result ""
+ lappend result [testintobj set 1 12345]
+ lappend result [testobj freeallvars]
+ lappend result [catch {testintobj get 1} msg]
+ lappend result $msg
+} {12345 {} 1 {variable 1 is unset (NULL)}}
+
+test obj-6.1 {Tcl_DuplicateObj, object has internal rep} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testintobj set 1 47]
+ lappend result [testobj duplicate 1 2]
+ lappend result [testintobj get 2]
+ lappend result [testobj refcount 1]
+ lappend result [testobj refcount 2]
+} {{} 47 47 47 2 3}
+test obj-6.2 {Tcl_DuplicateObj, "empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testobj newobj 1]
+ lappend result [testobj duplicate 1 2]
+ lappend result [testintobj get 2]
+ lappend result [testobj refcount 1]
+ lappend result [testobj refcount 2]
+} {{} {} {} {} 2 3}
+
+# We assume that testobj is an indicator for test*obj as well
+
+test obj-7.1 {Tcl_GetString, return existing string rep} testobj {
+ set result ""
+ lappend result [testintobj set 1 47]
+ lappend result [testintobj get2 1]
+} {47 47}
+test obj-7.2 {Tcl_GetString, "empty string" object} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [teststringobj append 1 abc -1]
+ lappend result [teststringobj get2 1]
+} {{} abc abc}
+test obj-7.3 {Tcl_GetString, returns string internal rep (DString)} testobj {
+ set result ""
+ lappend result [teststringobj set 1 xyz]
+ lappend result [teststringobj append 1 abc -1]
+ lappend result [teststringobj get2 1]
+} {xyz xyzabc xyzabc}
+test obj-7.4 {Tcl_GetString, recompute string rep from internal rep} testobj {
+ set result ""
+ lappend result [testintobj set 1 77]
+ lappend result [testintobj mult10 1]
+ lappend result [teststringobj get2 1]
+} {77 770 770}
+
+test obj-8.1 {Tcl_GetStringFromObj, return existing string rep} testobj {
+ set result ""
+ lappend result [testintobj set 1 47]
+ lappend result [testintobj get 1]
+} {47 47}
+test obj-8.2 {Tcl_GetStringFromObj, "empty string" object} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [teststringobj append 1 abc -1]
+ lappend result [teststringobj get 1]
+} {{} abc abc}
+test obj-8.3 {Tcl_GetStringFromObj, returns string internal rep (DString)} testobj {
+ set result ""
+ lappend result [teststringobj set 1 xyz]
+ lappend result [teststringobj append 1 abc -1]
+ lappend result [teststringobj get 1]
+} {xyz xyzabc xyzabc}
+test obj-8.4 {Tcl_GetStringFromObj, recompute string rep from internal rep} testobj {
+ set result ""
+ lappend result [testintobj set 1 77]
+ lappend result [testintobj mult10 1]
+ lappend result [teststringobj get 1]
+} {77 770 770}
+
+test obj-9.1 {Tcl_NewBooleanObj} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testbooleanobj set 1 0]
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 0 int 2}
+
+test obj-10.1 {Tcl_SetBooleanObj, existing "empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testobj newobj 1]
+ lappend result [testbooleanobj set 1 0] ;# makes existing obj boolean
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} {} 0 int 2}
+test obj-10.2 {Tcl_SetBooleanObj, existing non-"empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testintobj set 1 98765]
+ lappend result [testbooleanobj set 1 1] ;# makes existing obj boolean
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 98765 1 int 2}
+
+test obj-11.1 {Tcl_GetBooleanFromObj, existing boolean object} testobj {
+ set result ""
+ lappend result [testbooleanobj set 1 1]
+ lappend result [testbooleanobj not 1] ;# gets existing boolean rep
+} {1 0}
+test obj-11.2 {Tcl_GetBooleanFromObj, convert to boolean} testobj {
+ set result ""
+ lappend result [testintobj set 1 47]
+ lappend result [testbooleanobj not 1] ;# must convert to bool
+ lappend result [testobj type 1]
+} {47 0 int}
+test obj-11.3 {Tcl_GetBooleanFromObj, error converting to boolean} testobj {
+ set result ""
+ lappend result [teststringobj set 1 abc]
+ lappend result [catch {testbooleanobj not 1} msg]
+ lappend result $msg
+} {abc 1 {expected boolean value but got "abc"}}
+test obj-11.4 {Tcl_GetBooleanFromObj, error converting from "empty string"} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [catch {testbooleanobj not 1} msg]
+ lappend result $msg
+} {{} 1 {expected boolean value but got ""}}
+test obj-11.5 {Tcl_GetBooleanFromObj, convert hex to boolean} testobj {
+ set result ""
+ lappend result [teststringobj set 1 0xac]
+ lappend result [testbooleanobj not 1]
+ lappend result [testobj type 1]
+} {0xac 0 int}
+test obj-11.6 {Tcl_GetBooleanFromObj, convert float to boolean} testobj {
+ set result ""
+ lappend result [teststringobj set 1 5.42]
+ lappend result [testbooleanobj not 1]
+ lappend result [testobj type 1]
+} {5.42 0 int}
+
+test obj-12.1 {DupBooleanInternalRep} testobj {
+ set result ""
+ lappend result [testbooleanobj set 1 1]
+ lappend result [testobj duplicate 1 2] ;# uses DupBooleanInternalRep
+ lappend result [testbooleanobj get 2]
+} {1 1 1}
+
+test obj-13.1 {SetBooleanFromAny, int to boolean special case} testobj {
+ set result ""
+ lappend result [testintobj set 1 1234]
+ lappend result [testbooleanobj not 1] ;# converts with SetBooleanFromAny
+ lappend result [testobj type 1]
+} {1234 0 int}
+test obj-13.2 {SetBooleanFromAny, double to boolean special case} testobj {
+ set result ""
+ lappend result [testdoubleobj set 1 3.14159]
+ lappend result [testbooleanobj not 1] ;# converts with SetBooleanFromAny
+ lappend result [testobj type 1]
+} {3.14159 0 int}
+test obj-13.3 {SetBooleanFromAny, special case strings representing booleans} testobj {
+ set result ""
+ foreach s {yes no true false on off} {
+ teststringobj set 1 $s
+ lappend result [testbooleanobj not 1]
+ }
+ lappend result [testobj type 1]
+} {0 1 0 1 0 1 int}
+test obj-13.4 {SetBooleanFromAny, recompute string rep then parse it} testobj {
+ set result ""
+ lappend result [testintobj set 1 456]
+ lappend result [testintobj div10 1]
+ lappend result [testbooleanobj not 1] ;# converts with SetBooleanFromAny
+ lappend result [testobj type 1]
+} {456 45 0 int}
+test obj-13.5 {SetBooleanFromAny, error parsing string} testobj {
+ set result ""
+ lappend result [teststringobj set 1 abc]
+ lappend result [catch {testbooleanobj not 1} msg]
+ lappend result $msg
+} {abc 1 {expected boolean value but got "abc"}}
+test obj-13.6 {SetBooleanFromAny, error parsing string} testobj {
+ set result ""
+ lappend result [teststringobj set 1 x1.0]
+ lappend result [catch {testbooleanobj not 1} msg]
+ lappend result $msg
+} {x1.0 1 {expected boolean value but got "x1.0"}}
+test obj-13.7 {SetBooleanFromAny, error converting from "empty string"} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [catch {testbooleanobj not 1} msg]
+ lappend result $msg
+} {{} 1 {expected boolean value but got ""}}
+test obj-13.8 {SetBooleanFromAny, unicode strings} testobj {
+ set result ""
+ lappend result [teststringobj set 1 1\u7777]
+ lappend result [catch {testbooleanobj not 1} msg]
+ lappend result $msg
+} "1\u7777 1 {expected boolean value but got \"1\u7777\"}"
+
+test obj-14.1 {UpdateStringOfBoolean} testobj {
+ set result ""
+ lappend result [testbooleanobj set 1 0]
+ lappend result [testbooleanobj not 1]
+ lappend result [testbooleanobj get 1] ;# must update string rep
+} {0 1 1}
+
+test obj-15.1 {Tcl_NewDoubleObj} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testdoubleobj set 1 3.1459]
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 3.1459 double 2}
+
+test obj-16.1 {Tcl_SetDoubleObj, existing "empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testobj newobj 1]
+ lappend result [testdoubleobj set 1 0.123] ;# makes existing obj boolean
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} {} 0.123 double 2}
+test obj-16.2 {Tcl_SetDoubleObj, existing non-"empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testintobj set 1 98765]
+ lappend result [testdoubleobj set 1 27.56] ;# makes existing obj double
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 98765 27.56 double 2}
+
+test obj-17.1 {Tcl_GetDoubleFromObj, existing double object} testobj {
+ set result ""
+ lappend result [testdoubleobj set 1 16.1]
+ lappend result [testdoubleobj mult10 1] ;# gets existing double rep
+} {16.1 161.0}
+test obj-17.2 {Tcl_GetDoubleFromObj, convert to double} testobj {
+ set result ""
+ lappend result [testintobj set 1 477]
+ lappend result [testdoubleobj div10 1] ;# must convert to bool
+ lappend result [testobj type 1]
+} {477 47.7 double}
+test obj-17.3 {Tcl_GetDoubleFromObj, error converting to double} testobj {
+ set result ""
+ lappend result [teststringobj set 1 abc]
+ lappend result [catch {testdoubleobj mult10 1} msg]
+ lappend result $msg
+} {abc 1 {expected floating-point number but got "abc"}}
+test obj-17.4 {Tcl_GetDoubleFromObj, error converting from "empty string"} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [catch {testdoubleobj div10 1} msg]
+ lappend result $msg
+} {{} 1 {expected floating-point number but got ""}}
+
+test obj-18.1 {DupDoubleInternalRep} testobj {
+ set result ""
+ lappend result [testdoubleobj set 1 17.1]
+ lappend result [testobj duplicate 1 2] ;# uses DupDoubleInternalRep
+ lappend result [testdoubleobj get 2]
+} {17.1 17.1 17.1}
+
+test obj-19.1 {SetDoubleFromAny, int to double special case} testobj {
+ set result ""
+ lappend result [testintobj set 1 1234]
+ lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
+ lappend result [testobj type 1]
+} {1234 12340.0 double}
+test obj-19.2 {SetDoubleFromAny, boolean to double special case} testobj {
+ set result ""
+ lappend result [testbooleanobj set 1 1]
+ lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
+ lappend result [testobj type 1]
+} {1 10.0 double}
+test obj-19.3 {SetDoubleFromAny, recompute string rep then parse it} testobj {
+ set result ""
+ lappend result [testintobj set 1 456]
+ lappend result [testintobj div10 1]
+ lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
+ lappend result [testobj type 1]
+} {456 45 450.0 double}
+test obj-19.4 {SetDoubleFromAny, error parsing string} testobj {
+ set result ""
+ lappend result [teststringobj set 1 abc]
+ lappend result [catch {testdoubleobj mult10 1} msg]
+ lappend result $msg
+} {abc 1 {expected floating-point number but got "abc"}}
+test obj-19.5 {SetDoubleFromAny, error parsing string} testobj {
+ set result ""
+ lappend result [teststringobj set 1 x1.0]
+ lappend result [catch {testdoubleobj mult10 1} msg]
+ lappend result $msg
+} {x1.0 1 {expected floating-point number but got "x1.0"}}
+test obj-19.6 {SetDoubleFromAny, error converting from "empty string"} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [catch {testdoubleobj div10 1} msg]
+ lappend result $msg
+} {{} 1 {expected floating-point number but got ""}}
+
+test obj-20.1 {UpdateStringOfDouble} testobj {
+ set result ""
+ lappend result [testdoubleobj set 1 3.14159]
+ lappend result [testdoubleobj mult10 1]
+ lappend result [testdoubleobj get 1] ;# must update string rep
+} {3.14159 31.4159 31.4159}
+
+test obj-21.1 {Tcl_NewIntObj} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testintobj set 1 55]
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 55 int 2}
+
+test obj-22.1 {Tcl_SetIntObj, existing "empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testobj newobj 1]
+ lappend result [testintobj set 1 77] ;# makes existing obj int
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} {} 77 int 2}
+test obj-22.2 {Tcl_SetIntObj, existing non-"empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testdoubleobj set 1 12.34]
+ lappend result [testintobj set 1 77] ;# makes existing obj int
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 12.34 77 int 2}
+
+test obj-23.1 {Tcl_GetIntFromObj, existing int object} testobj {
+ set result ""
+ lappend result [testintobj set 1 22]
+ lappend result [testintobj mult10 1] ;# gets existing int rep
+} {22 220}
+test obj-23.2 {Tcl_GetIntFromObj, convert to int} testobj {
+ set result ""
+ lappend result [testintobj set 1 477]
+ lappend result [testintobj div10 1] ;# must convert to bool
+ lappend result [testobj type 1]
+} {477 47 int}
+test obj-23.3 {Tcl_GetIntFromObj, error converting to int} testobj {
+ set result ""
+ lappend result [teststringobj set 1 abc]
+ lappend result [catch {testintobj mult10 1} msg]
+ lappend result $msg
+} {abc 1 {expected integer but got "abc"}}
+test obj-23.4 {Tcl_GetIntFromObj, error converting from "empty string"} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [catch {testintobj div10 1} msg]
+ lappend result $msg
+} {{} 1 {expected integer but got ""}}
+test obj-23.5 {Tcl_GetIntFromObj, integer too large to represent as non-long error} {testobj} {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [testintobj inttoobigtest 1]
+} {{} 1}
+
+test obj-24.1 {DupIntInternalRep} testobj {
+ set result ""
+ lappend result [testintobj set 1 23]
+ lappend result [testobj duplicate 1 2] ;# uses DupIntInternalRep
+ lappend result [testintobj get 2]
+} {23 23 23}
+
+test obj-25.1 {SetIntFromAny, int to int special case} testobj {
+ set result ""
+ lappend result [testintobj set 1 1234]
+ lappend result [testintobj mult10 1] ;# converts with SetIntFromAny
+ lappend result [testobj type 1]
+} {1234 12340 int}
+test obj-25.2 {SetIntFromAny, boolean to int special case} testobj {
+ set result ""
+ lappend result [testbooleanobj set 1 1]
+ lappend result [testintobj mult10 1] ;# converts with SetIntFromAny
+ lappend result [testobj type 1]
+} {1 10 int}
+test obj-25.3 {SetIntFromAny, recompute string rep then parse it} testobj {
+ set result ""
+ lappend result [testintobj set 1 456]
+ lappend result [testintobj div10 1]
+ lappend result [testintobj mult10 1] ;# converts with SetIntFromAny
+ lappend result [testobj type 1]
+} {456 45 450 int}
+test obj-25.4 {SetIntFromAny, error parsing string} testobj {
+ set result ""
+ lappend result [teststringobj set 1 abc]
+ lappend result [catch {testintobj mult10 1} msg]
+ lappend result $msg
+} {abc 1 {expected integer but got "abc"}}
+test obj-25.5 {SetIntFromAny, error parsing string} testobj {
+ set result ""
+ lappend result [teststringobj set 1 x17]
+ lappend result [catch {testintobj mult10 1} msg]
+ lappend result $msg
+} {x17 1 {expected integer but got "x17"}}
+test obj-25.6 {SetIntFromAny, integer too large} {testobj} {
+ set result ""
+ lappend result [teststringobj set 1 123456789012345678901]
+ lappend result [catch {testintobj mult10 1} msg]
+ lappend result $msg
+} {123456789012345678901 1 {integer value too large to represent}}
+test obj-25.7 {SetIntFromAny, error converting from "empty string"} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [catch {testintobj div10 1} msg]
+ lappend result $msg
+} {{} 1 {expected integer but got ""}}
+
+test obj-26.1 {UpdateStringOfInt} testobj {
+ set result ""
+ lappend result [testintobj set 1 512]
+ lappend result [testintobj mult10 1]
+ lappend result [testintobj get 1] ;# must update string rep
+} {512 5120 5120}
+
+test obj-27.1 {Tcl_NewLongObj} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ testintobj setmaxlong 1
+ lappend result [testintobj ismaxlong 1]
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 1 int 1}
+
+test obj-28.1 {Tcl_SetLongObj, existing "empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testobj newobj 1]
+ lappend result [testintobj setlong 1 77] ;# makes existing obj long int
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} {} 77 int 2}
+test obj-28.2 {Tcl_SetLongObj, existing non-"empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testdoubleobj set 1 12.34]
+ lappend result [testintobj setlong 1 77] ;# makes existing obj long int
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 12.34 77 int 2}
+
+test obj-29.1 {Tcl_GetLongFromObj, existing long integer object} testobj {
+ set result ""
+ lappend result [testintobj setlong 1 22]
+ lappend result [testintobj mult10 1] ;# gets existing long int rep
+} {22 220}
+test obj-29.2 {Tcl_GetLongFromObj, convert to long} testobj {
+ set result ""
+ lappend result [testintobj setlong 1 477]
+ lappend result [testintobj div10 1] ;# must convert to bool
+ lappend result [testobj type 1]
+} {477 47 int}
+test obj-29.3 {Tcl_GetLongFromObj, error converting to long integer} testobj {
+ set result ""
+ lappend result [teststringobj set 1 abc]
+ lappend result [catch {testintobj ismaxlong 1} msg] ;# cvts to long int
+ lappend result $msg
+} {abc 1 {expected integer but got "abc"}}
+test obj-29.4 {Tcl_GetLongFromObj, error converting from "empty string"} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [catch {testintobj ismaxlong 1} msg] ;# cvts to long int
+ lappend result $msg
+} {{} 1 {expected integer but got ""}}
+
+test obj-30.1 {Ref counting and object deletion, simple types} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testintobj set 1 1024]
+ lappend result [testobj assign 1 2] ;# vars 1 and 2 share the int obj
+ lappend result [testobj type 2]
+ lappend result [testobj refcount 1]
+ lappend result [testobj refcount 2]
+ lappend result [testbooleanobj set 2 0] ;# must copy on write, now 2 objs
+ lappend result [testobj type 2]
+ lappend result [testobj refcount 1]
+ lappend result [testobj refcount 2]
+} {{} 1024 1024 int 4 4 0 int 3 2}
+
+
+test obj-31.1 {regenerate string rep of "end"} testobj {
+ testobj freeallvars
+ teststringobj set 1 end
+ testobj convert 1 end-offset
+ testobj invalidateStringRep 1
+} end
+test obj-31.2 {regenerate string rep of "end-1"} testobj {
+ testobj freeallvars
+ teststringobj set 1 end-0x1
+ testobj convert 1 end-offset
+ testobj invalidateStringRep 1
+} end-1
+test obj-31.3 {regenerate string rep of "end--1"} testobj {
+ testobj freeallvars
+ teststringobj set 1 end--0x1
+ testobj convert 1 end-offset
+ testobj invalidateStringRep 1
+} end--1
+test obj-31.4 {regenerate string rep of "end-bigInteger"} testobj {
+ testobj freeallvars
+ teststringobj set 1 end-0x7fffffff
+ testobj convert 1 end-offset
+ testobj invalidateStringRep 1
+} end-2147483647
+test obj-31.5 {regenerate string rep of "end--bigInteger"} testobj {
+ testobj freeallvars
+ teststringobj set 1 end--0x7fffffff
+ testobj convert 1 end-offset
+ testobj invalidateStringRep 1
+} end--2147483647
+test obj-31.6 {regenerate string rep of "end--bigInteger"} {testobj longIs32bit} {
+ testobj freeallvars
+ teststringobj set 1 end--0x80000000
+ testobj convert 1 end-offset
+ testobj invalidateStringRep 1
+} end--2147483648
+
+test obj-32.1 {freeing very large object trees} {
+ set x {}
+ for {set i 0} {$i<100000} {incr i} {
+ set x [list $x {}]
+ }
+ unset x
+} {}
+
+test obj-33.1 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+ set x 0x8000; append x 0000
+ list [string is integer $x] [expr { wide($x) }]
+} {1 2147483648}
+test obj-33.2 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+ set x 0xffff; append x ffff
+ list [string is integer $x] [expr { wide($x) }]
+} {1 4294967295}
+test obj-33.3 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+ set x 0x10000; append x 0000
+ list [string is integer $x] [expr { wide($x) }]
+} {0 4294967296}
+test obj-33.4 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+ set x -0x8000; append x 0000
+ list [string is integer $x] [expr { wide($x) }]
+} {1 -2147483648}
+test obj-33.5 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+ set x -0x8000; append x 0001
+ list [string is integer $x] [expr { wide($x) }]
+} {1 -2147483649}
+test obj-33.6 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+ set x -0xffff; append x ffff
+ list [string is integer $x] [expr { wide($x) }]
+} {1 -4294967295}
+test obj-33.7 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+ set x -0x10000; append x 0000
+ list [string is integer $x] [expr { wide($x) }]
+} {0 -4294967296}
+
+if {[testConstraint testobj]} {
+ testobj freeallvars
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/oo.test b/library/msgcat/tests/oo.test
new file mode 100644
index 0000000..00663e9
--- /dev/null
+++ b/library/msgcat/tests/oo.test
@@ -0,0 +1,3364 @@
+# This file contains a collection of tests for Tcl's built-in object system.
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 2006-2011 Donal K. Fellows
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require -exact TclOO 0.6.3 ;# Must match value in generic/tclOO.h
+package require tcltest 2
+if {"::tcltest" in [namespace children]} {
+ namespace import -force ::tcltest::*
+}
+
+testConstraint memory [llength [info commands memory]]
+if {[testConstraint memory]} {
+ proc getbytes {} {
+ set lines [split [memory info] \n]
+ return [lindex $lines 3 3]
+ }
+ proc leaktest {script {iterations 3}} {
+ set end [getbytes]
+ for {set i 0} {$i < $iterations} {incr i} {
+ uplevel 1 $script
+ set tmp $end
+ set end [getbytes]
+ }
+ return [expr {$end - $tmp}]
+ }
+}
+
+test oo-0.1 {basic test of OO's ability to clean up its initial state} {
+ interp create t
+ t eval {
+ package require TclOO
+ }
+ interp delete t
+} {}
+test oo-0.2 {basic test of OO's ability to clean up its initial state} {
+ set i [interp create]
+ interp eval $i {
+ package require TclOO
+ namespace delete ::
+ }
+ interp delete $i
+} {}
+test oo-0.3 {basic test of OO's ability to clean up its initial state} -body {
+ leaktest {
+ [oo::object new] destroy
+ }
+} -constraints memory -result 0
+test oo-0.4 {basic test of OO's ability to clean up its initial state} -body {
+ leaktest {
+ oo::class create foo
+ foo new
+ foo destroy
+ }
+} -constraints memory -result 0
+test oo-0.5 {testing literal leak on interp delete} memory {
+ leaktest {
+ interp create foo
+ foo eval {oo::object new}
+ interp delete foo
+ }
+} 0
+test oo-0.6 {cleaning the core class pair; way #1} -setup {
+ interp create t
+} -body {
+ t eval {
+ package require TclOO
+ namespace path oo
+ list [catch {class destroy} m] $m [catch {object destroy} m] $m
+ }
+} -cleanup {
+ interp delete t
+} -result {0 {} 1 {invalid command name "object"}}
+test oo-0.7 {cleaning the core class pair; way #2} -setup {
+ interp create t
+} -body {
+ t eval {
+ package require TclOO
+ namespace path oo
+ list [catch {object destroy} m] $m [catch {class destroy} m] $m
+ }
+} -cleanup {
+ interp delete t
+} -result {0 {} 1 {invalid command name "class"}}
+test oo-0.8 {leak in variable management} -setup {
+ oo::class create foo
+} -constraints memory -body {
+ oo::define foo {
+ constructor {} {
+ variable v 0
+ }
+ }
+ leaktest {[foo new] destroy}
+} -cleanup {
+ foo destroy
+} -result 0
+test oo-0.9 {various types of presence of the TclOO package} {
+ list [lsearch -nocase -all -inline [package names] tcloo] \
+ [package present TclOO] [package versions TclOO]
+} [list TclOO $::oo::version $::oo::version]
+
+test oo-1.1 {basic test of OO functionality: no classes} {
+ set result {}
+ lappend result [oo::object create foo]
+ lappend result [oo::objdefine foo {
+ method bar args {
+ global result
+ lappend result {*}$args
+ return [llength $args]
+ }
+ }]
+ lappend result [foo bar a b c]
+ lappend result [foo destroy] [info commands foo]
+} {::foo {} a b c 3 {} {}}
+test oo-1.2 {basic test of OO functionality: no classes} -body {
+ oo::define oo::object method missingArgs
+} -returnCodes 1 -result "wrong # args: should be \"oo::define oo::object method name args body\""
+test oo-1.3 {basic test of OO functionality: no classes} {
+ catch {oo::define oo::object method missingArgs}
+ set errorInfo
+} "wrong # args: should be \"oo::define oo::object method name args body\"
+ while executing
+\"oo::define oo::object method missingArgs\""
+test oo-1.4 {basic test of OO functionality} -body {
+ oo::object create {}
+} -returnCodes 1 -result {object name must not be empty}
+test oo-1.5 {basic test of OO functionality} -body {
+ oo::object doesnotexist
+} -returnCodes 1 -result {unknown method "doesnotexist": must be create, destroy or new}
+test oo-1.5.1 {basic test of OO functionality} -setup {
+ oo::object create aninstance
+} -returnCodes error -body {
+ aninstance
+} -cleanup {
+ rename aninstance {}
+} -result {wrong # args: should be "aninstance method ?arg ...?"}
+test oo-1.6 {basic test of OO functionality} -setup {
+ oo::object create aninstance
+} -body {
+ oo::objdefine aninstance unexport destroy
+ aninstance doesnotexist
+} -cleanup {
+ rename aninstance {}
+} -returnCodes 1 -result {object "::aninstance" has no visible methods}
+test oo-1.7 {basic test of OO functionality} -setup {
+ oo::object create aninstance
+} -body {
+ oo::objdefine aninstance {
+ # Do not do this in real code! Ever! This is *not* supported!
+ ::oo::define::method ha ha ha
+ }
+} -returnCodes error -cleanup {
+ aninstance destroy
+} -result {attempt to misuse API}
+test oo-1.8 {basic test of OO functionality} -setup {
+ oo::object create obj
+ set result {}
+} -cleanup {
+ obj destroy
+} -body {
+ oo::objdefine obj method foo {} {return bar}
+ lappend result [obj foo]
+ oo::objdefine obj method foo {} {}
+ lappend result [obj foo]
+} -result {bar {}}
+test oo-1.9 {basic test of OO functionality} -setup {
+ oo::object create a
+ oo::object create b
+} -cleanup {
+ catch {a destroy}
+ b destroy
+} -body {
+ oo::objdefine a method foo {} { return A }
+ oo::objdefine b method foo {} { return B }
+ apply {{} {
+ set m foo
+ return [a $m],[a destroy],[b $m]
+ }}
+} -result A,,B
+test oo-1.10 {basic test of OO functionality} -body {
+ namespace eval foo {
+ namespace eval bar {
+ oo::object create o
+ namespace export o
+ }
+ namespace import bar::o
+ }
+ list [info object isa object foo::bar::o] [info object isa object foo::o]
+} -cleanup {
+ namespace delete foo
+} -result {1 1}
+test oo-1.11 {basic test of OO functionality: abbreviating} -setup {
+ oo::class create c
+} -cleanup {
+ c destroy
+} -body {
+ oo::define c super oo::class
+ info class super c
+} -result ::oo::class
+test oo-1.12 {basic test of OO functionality: abbreviating} -setup {
+ oo::class create c
+} -cleanup {
+ c destroy
+} -body {
+ oo::define c {super oo::class}
+ info class super c
+} -result ::oo::class
+test oo-1.13 {basic test of OO functionality: abbreviating} -setup {
+ oo::class create c
+} -cleanup {
+ c destroy
+} -body {
+ oo::define c self {forw a b}
+ info object forw c a
+} -result b
+test oo-1.14 {basic test of OO functionality: abbreviating} -setup {
+ oo::class create c
+} -cleanup {
+ c destroy
+} -body {
+ oo::define c self forw a b
+ info object forw c a
+} -result b
+test oo-1.15 {basic test of OO functionality: abbreviating} -setup {
+ oo::object create o
+} -cleanup {
+ o destroy
+} -body {
+ oo::objdefine o {forw a b}
+ info object forw o a
+} -result b
+test oo-1.16 {basic test of OO functionality: abbreviating} -setup {
+ oo::object create o
+} -cleanup {
+ o destroy
+} -body {
+ oo::objdefine o forw a b
+ info object forw o a
+} -result b
+test oo-1.17 {basic test of OO functionality: Bug 2481109} -body {
+ namespace eval ::foo {oo::object create lreplace}
+} -cleanup {
+ namespace delete ::foo
+} -result ::foo::lreplace
+# Check for Bug 2519474; problem in tclNamesp.c, but tested here...
+test oo-1.18 {OO: create object in NS with same name as global cmd} -setup {
+ proc test-oo-1.18 {} return
+ oo::class create A
+ oo::class create B {superclass A}
+} -body {
+ oo::define B constructor {} {A create test-oo-1.18}
+ B create C
+} -cleanup {
+ rename test-oo-1.18 {}
+ A destroy
+} -result ::C
+test oo-1.19 {basic test of OO functionality: teardown order} -body {
+ oo::object create o
+ namespace delete [info object namespace o]
+ o destroy
+ # Crashes on error
+} -returnCodes error -result {invalid command name "o"}
+test oo-1.20 {basic test of OO functionality: my teardown post rename} -body {
+ oo::object create obj
+ rename [info object namespace obj]::my ::AGlobalName
+ obj destroy
+ info commands ::AGlobalName
+} -result {}
+
+test oo-2.1 {basic test of OO functionality: constructor} -setup {
+ # This is a bit complex because it needs to run in a sub-interp as
+ # we're modifying the root object class's constructor
+ interp create subinterp
+ subinterp eval {
+ package require TclOO
+ }
+} -body {
+ subinterp eval {
+ oo::define oo::object constructor {} {
+ lappend ::result [info level 0]
+ }
+ lappend result 1
+ lappend result 2 [oo::object create foo]
+ }
+} -cleanup {
+ interp delete subinterp
+} -result {1 {oo::object create foo} 2 ::foo}
+test oo-2.2 {basic test of OO functionality: constructor} {
+ oo::class create testClass {
+ constructor {} {
+ global result
+ lappend result "[self]->construct"
+ }
+ method bar {} {
+ global result
+ lappend result "[self]->bar"
+ }
+ }
+ set result {}
+ [testClass create foo] bar
+ testClass destroy
+ return $result
+} {::foo->construct ::foo->bar}
+test oo-2.4 {OO constructor - Bug 2531577} -setup {
+ oo::class create foo
+} -body {
+ oo::define foo constructor {} return
+ [foo new] destroy
+ oo::define foo constructor {} {}
+ llength [info command [foo new]]
+} -cleanup {
+ foo destroy
+} -result 1
+test oo-2.5 {OO constructor - Bug 2531577} -setup {
+ oo::class create foo
+ set result {}
+} -body {
+ oo::define foo constructor {} {error x}
+ lappend result [catch {foo new}]
+ oo::define foo constructor {} {}
+ lappend result [llength [info command [foo new]]]
+} -cleanup {
+ foo destroy
+} -result {1 1}
+test oo-2.6 {OO constructor and tailcall - Bug 2414858} -setup {
+ oo::class create foo
+} -body {
+ oo::define foo {
+ constructor {} { tailcall my bar }
+ method bar {} { return bad }
+ }
+ namespace tail [foo create good]
+} -cleanup {
+ foo destroy
+} -result good
+test oo-2.7 {construction, method calls and ensembles - Bug 3514761} -setup {
+ namespace eval k {}
+} -body {
+ namespace eval k {
+ oo::class create s {
+ constructor {j} {
+ # nothing
+ }
+ }
+ namespace export s
+ namespace ensemble create
+ }
+ k s create X
+} -returnCodes error -cleanup {
+ namespace delete k
+} -result {wrong # args: should be "k s create X j"}
+test oo-2.8 {construction, method calls and ensembles - Bug 3514761} -setup {
+ namespace eval k {}
+} -body {
+ namespace eval k {
+ oo::class create s {
+ constructor {j} {
+ # nothing
+ }
+ }
+ oo::class create t {
+ superclass s
+ constructor args {
+ k next {*}$args
+ }
+ }
+ interp alias {} ::k::next {} ::oo::Helpers::next
+ namespace export t next
+ namespace ensemble create
+ }
+ k t create X
+} -returnCodes error -cleanup {
+ namespace delete k
+} -result {wrong # args: should be "k next j"}
+
+test oo-3.1 {basic test of OO functionality: destructor} -setup {
+ # This is a bit complex because it needs to run in a sub-interp as we're
+ # modifying the root object class's constructor
+ interp create subinterp
+ subinterp eval {
+ package require TclOO
+ }
+} -body {
+ subinterp eval {
+ oo::define oo::object destructor {
+ lappend ::result died
+ }
+ lappend result 1 [oo::object create foo]
+ lappend result 2 [rename foo {}]
+ oo::define oo::object destructor {}
+ return $result
+ }
+} -cleanup {
+ interp delete subinterp
+} -result {1 ::foo died 2 {}}
+test oo-3.2 {basic test of OO functionality: destructor} -setup {
+ # This is a bit complex because it needs to run in a sub-interp as
+ # we're modifying the root object class's constructor
+ interp create subinterp
+ subinterp eval {
+ package require TclOO
+ }
+} -body {
+ subinterp eval {
+ oo::define oo::object destructor {
+ lappend ::result died
+ }
+ lappend result 1 [oo::object create foo]
+ lappend result 2 [rename foo {}]
+ }
+} -cleanup {
+ interp delete subinterp
+} -result {1 ::foo died 2 {}}
+test oo-3.3 {basic test of OO functionality: destructor} -setup {
+ oo::class create foo
+ set result {}
+} -cleanup {
+ foo destroy
+} -body {
+ oo::define foo {
+ constructor {} {lappend ::result made}
+ destructor {lappend ::result died}
+ }
+ namespace delete [info object namespace [foo new]]
+ return $result
+} -result {made died}
+test oo-3.4 {basic test of OO functionality: my exists in destructor} -setup {
+ oo::class create cls
+ set result {}
+} -cleanup {
+ cls destroy
+} -body {
+ oo::define cls {
+ variable state
+ constructor {} {
+ proc localcmdexists {} {}
+ set state ok
+ }
+ forward Report lappend ::result
+ destructor {
+ objmy Report [catch {set state} msg] $msg
+ objmy Report [namespace which -var state]
+ objmy Report [info commands localcmdexists]
+ }
+ }
+ cls create obj
+ rename [info object namespace obj]::my ::objmy
+ obj destroy
+ lappend result [info commands ::objmy]
+} -match glob -result {0 ok *::state localcmdexists {}}
+test oo-3.4a {basic test of OO functionality: my exists in destructor} -setup {
+ oo::class create cls
+ set result {}
+} -cleanup {
+ cls destroy
+} -body {
+ oo::define cls {
+ variable state
+ constructor {} {
+ proc localcmdexists {} {}
+ set state ok
+ }
+ forward Report lappend ::result
+ destructor {
+ objmy Report [catch {set state} msg] $msg
+ objmy Report [namespace which -var state]
+ objmy Report [info commands localcmdexists]
+ }
+ }
+ cls create obj
+ rename [info object namespace obj]::my ::objmy
+ rename obj {}
+ lappend result [info commands ::objmy]
+} -match glob -result {0 ok *::state localcmdexists {}}
+test oo-3.5 {basic test of OO functionality: destructor: evil case for Itcl} -setup {
+ oo::class create cls
+ set result {}
+} -cleanup {
+ cls destroy
+} -body {
+ oo::define cls {
+ variable state
+ constructor {} {
+ proc localcmdexists {} {}
+ set state ok
+ }
+ forward Report lappend ::result
+ destructor {
+ objmy Report [catch {set state} msg] $msg
+ objmy Report [namespace which -var state]
+ objmy Report [info commands localcmdexists]
+ }
+ }
+ cls create obj
+ rename [info object namespace obj]::my ::objmy
+ namespace delete [info object namespace obj]
+ lappend result [info commands ::objmy]
+} -match glob -result {0 ok *::state localcmdexists {}}
+test oo-3.5a {basic test of OO functionality: destructor: evil case for Itcl} -setup {
+ oo::class create cls
+ set result {}
+} -cleanup {
+ cls destroy
+} -body {
+ oo::define cls {
+ variable state result
+ constructor {} {
+ proc localcmdexists {} {}
+ set state ok
+ my eval {upvar 0 ::result result}
+ }
+ method nuke {} {
+ namespace delete [namespace current]
+ return $result
+ }
+ destructor {
+ lappend result [self] $state [info commands localcmdexists]
+ }
+ }
+ cls create obj
+ namespace delete [info object namespace obj]
+ [cls create obj2] nuke
+} -match glob -result {::obj ok localcmdexists ::obj2 ok localcmdexists}
+test oo-3.6 {basic test of OO functionality: errors in destructor} -setup {
+ oo::class create cls
+} -cleanup {
+ cls destroy
+} -body {
+ oo::define cls destructor {error foo}
+ list [catch {[cls create obj] destroy} msg] $msg [info commands obj]
+} -result {1 foo {}}
+test oo-3.7 {basic test of OO functionality: errors in destructor} -setup {
+ oo::class create cls
+ set result {}
+ proc bgerror msg {lappend ::result $msg}
+} -cleanup {
+ cls destroy
+ rename bgerror {}
+} -body {
+ oo::define cls destructor {error foo}
+ list [rename [cls create obj] {}] \
+ [update idletasks] $result [info commands obj]
+} -result {{} {} foo {}}
+test oo-3.8 {basic test of OO functionality: errors in destructor} -setup {
+ oo::class create cls
+ set result {}
+ proc bgerror msg {lappend ::result $msg}
+} -cleanup {
+ cls destroy
+ rename bgerror {}
+} -body {
+ oo::define cls destructor {error foo}
+ list [namespace delete [info object namespace [cls create obj]]] \
+ [update idletasks] $result [info commands obj]
+} -result {{} {} foo {}}
+test oo-3.9 {Bug 2944404: deleting the object in the destructor} -setup {
+ oo::class create cls
+ set result {}
+} -body {
+ oo::define cls {
+ destructor {
+ lappend ::result in destructor
+ [self] destroy
+ }
+ }
+ # This used to crash
+ [cls new] destroy
+ return $result
+} -cleanup {
+ cls destroy
+} -result {in destructor}
+
+test oo-4.1 {basic test of OO functionality: export} {
+ set o [oo::object new]
+ set result {}
+ oo::objdefine $o method Foo {} {lappend ::result Foo; return}
+ lappend result [catch {$o Foo} msg] $msg
+ oo::objdefine $o export Foo
+ lappend result [$o Foo] [$o destroy]
+} {1 {unknown method "Foo": must be destroy} Foo {} {}}
+test oo-4.2 {basic test of OO functionality: unexport} {
+ set o [oo::object new]
+ set result {}
+ oo::objdefine $o method foo {} {lappend ::result foo; return}
+ lappend result [$o foo]
+ oo::objdefine $o unexport foo
+ lappend result [catch {$o foo} msg] $msg [$o destroy]
+} {foo {} 1 {unknown method "foo": must be destroy} {}}
+test oo-4.3 {exporting and error messages, Bug 1824958} -setup {
+ oo::class create testClass
+} -cleanup {
+ testClass destroy
+} -body {
+ oo::define testClass self export Bad
+ testClass Bad
+} -returnCodes 1 -result {unknown method "Bad": must be create, destroy or new}
+test oo-4.4 {exporting a class method from an object} -setup {
+ oo::class create testClass
+ testClass create testObject
+} -cleanup {
+ testClass destroy
+} -body {
+ oo::define testClass method Good {} { return ok }
+ oo::objdefine testObject export Good
+ testObject Good
+} -result ok
+test oo-4.5 {export creates proper method entries} -setup {
+ oo::class create testClass
+} -body {
+ oo::define testClass {
+ export foo
+ method foo {} {return ok}
+ }
+ [testClass new] foo
+} -cleanup {
+ testClass destroy
+} -result ok
+test oo-4.6 {export creates proper method entries} -setup {
+ oo::class create testClass
+} -body {
+ oo::define testClass {
+ unexport foo
+ method foo {} {return ok}
+ }
+ [testClass new] foo
+} -cleanup {
+ testClass destroy
+} -result ok
+
+test oo-5.1 {OO: manipulation of classes as objects} -setup {
+ set obj [oo::object new]
+} -body {
+ oo::objdefine oo::object method foo {} { return "in object" }
+ catch {$obj foo} result
+ list [catch {$obj foo} result] $result [oo::object foo]
+} -cleanup {
+ oo::objdefine oo::object deletemethod foo
+ $obj destroy
+} -result {1 {unknown method "foo": must be destroy} {in object}}
+test oo-5.2 {OO: manipulation of classes as objects} -setup {
+ set obj [oo::object new]
+} -body {
+ oo::define oo::object self method foo {} { return "in object" }
+ catch {$obj foo} result
+ list [catch {$obj foo} result] $result [oo::object foo]
+} -cleanup {
+ oo::objdefine oo::object deletemethod foo
+ $obj destroy
+} -result {1 {unknown method "foo": must be destroy} {in object}}
+test oo-5.3 {OO: manipulation of classes as objects} -setup {
+ set obj [oo::object new]
+} -body {
+ oo::objdefine oo::object {
+ method foo {} { return "in object" }
+ }
+ catch {$obj foo} result
+ list [catch {$obj foo} result] $result [oo::object foo]
+} -cleanup {
+ oo::objdefine oo::object deletemethod foo
+ $obj destroy
+} -result {1 {unknown method "foo": must be destroy} {in object}}
+test oo-5.4 {OO: manipulation of classes as objects} -setup {
+ set obj [oo::object new]
+} -body {
+ oo::define oo::object {
+ self method foo {} { return "in object" }
+ }
+ catch {$obj foo} result
+ list [catch {$obj foo} result] $result [oo::object foo]
+} -cleanup {
+ oo::objdefine oo::object deletemethod foo
+ $obj destroy
+} -result {1 {unknown method "foo": must be destroy} {in object}}
+test oo-5.5 {OO: manipulation of classes as objects} -setup {
+ set obj [oo::object new]
+} -body {
+ oo::define oo::object {
+ self {
+ method foo {} { return "in object" }
+ }
+ }
+ catch {$obj foo} result
+ list [catch {$obj foo} result] $result [oo::object foo]
+} -cleanup {
+ oo::objdefine oo::object deletemethod foo
+ $obj destroy
+} -result {1 {unknown method "foo": must be destroy} {in object}}
+
+test oo-6.1 {OO: forward} {
+ oo::object create foo
+ oo::objdefine foo {
+ forward a lappend
+ forward b lappend result
+ }
+ set result {}
+ foo a result 1
+ foo b 2
+ foo destroy
+ return $result
+} {1 2}
+test oo-6.2 {OO: forward resolution scope} -setup {
+ oo::class create fooClass
+} -body {
+ proc foo {} {return bad}
+ oo::define fooClass {
+ constructor {} {
+ proc foo {} {return good}
+ }
+ forward bar foo
+ }
+ [fooClass new] bar
+} -cleanup {
+ fooClass destroy
+ rename foo {}
+} -result good
+test oo-6.3 {OO: forward resolution scope} -setup {
+ oo::class create fooClass
+} -body {
+ proc foo {} {return bad}
+ oo::define fooClass {
+ constructor {} {
+ proc foo {} {return good}
+ }
+ }
+ oo::define fooClass forward bar foo
+ [fooClass new] bar
+} -cleanup {
+ fooClass destroy
+ rename foo {}
+} -result good
+test oo-6.4 {OO: forward resolution scope} -setup {
+ oo::class create fooClass
+} -body {
+ proc foo {} {return good}
+ oo::define fooClass {
+ constructor {} {
+ proc foo {} {return bad}
+ }
+ forward bar ::foo
+ }
+ [fooClass new] bar
+} -cleanup {
+ fooClass destroy
+ rename foo {}
+} -result good
+test oo-6.5 {OO: forward resolution scope} -setup {
+ oo::class create fooClass
+ namespace eval foo {}
+} -body {
+ proc foo::foo {} {return good}
+ oo::define fooClass {
+ constructor {} {
+ proc foo {} {return bad}
+ }
+ forward bar foo::foo
+ }
+ [fooClass new] bar
+} -cleanup {
+ fooClass destroy
+ namespace delete foo
+} -result good
+test oo-6.6 {OO: forward resolution scope} -setup {
+ oo::class create fooClass
+ namespace eval foo {}
+} -body {
+ proc foo::foo {} {return bad}
+ oo::define fooClass {
+ constructor {} {
+ namespace eval foo {
+ proc foo {} {return good}
+ }
+ }
+ forward bar foo::foo
+ }
+ [fooClass new] bar
+} -cleanup {
+ fooClass destroy
+ namespace delete foo
+} -result good
+test oo-6.7 {OO: forward resolution scope is per-object} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ constructor {} {
+ proc curns {} {namespace current}
+ }
+ forward ns curns
+ }
+ expr {[[fooClass new] ns] ne [[fooClass new] ns]}
+} -cleanup {
+ fooClass destroy
+} -result 1
+test oo-6.8 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test my handler
+ method handler {a b c} {}
+ }
+ fooClass create ::foo
+ foo test
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "foo test a b c"}
+test oo-6.9 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test my handler
+ method handler {a b c} {list $a,$b,$c}
+ }
+ fooClass create ::foo
+ foo test 1 2 3
+} -cleanup {
+ fooClass destroy
+} -result 1,2,3
+test oo-6.10 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test my handler
+ method handler {a b c} {list $a,$b,$c}
+ }
+ fooClass create ::foo
+ foo test 1 2
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "foo test a b c"}
+test oo-6.11 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo {
+ forward test my handler
+ method handler {a b c} {}
+ }
+ foo test
+} -returnCodes error -cleanup {
+ foo destroy
+} -result {wrong # args: should be "foo test a b c"}
+test oo-6.12 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo {
+ forward test my handler
+ method handler {a b c} {list $a,$b,$c}
+ }
+ foo test 1 2 3
+} -cleanup {
+ foo destroy
+} -result 1,2,3
+test oo-6.13 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo {
+ forward test my handler
+ method handler {a b c} {list $a,$b,$c}
+ }
+ foo test 1 2
+} -returnCodes error -cleanup {
+ foo destroy
+} -result {wrong # args: should be "foo test a b c"}
+test oo-6.14 {Bug 3400658: forwarding and wrongargs rewriting - multistep} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test my handler1 p
+ forward handler1 my handler q
+ method handler {a b c} {}
+ }
+ fooClass create ::foo
+ foo test
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "foo test c"}
+test oo-6.15 {Bug 3400658: forwarding and wrongargs rewriting - multistep} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test my handler1 p
+ forward handler1 my handler q
+ method handler {a b c} {list $a,$b,$c}
+ }
+ fooClass create ::foo
+ foo test 1
+} -cleanup {
+ fooClass destroy
+} -result q,p,1
+test oo-6.16 {Bug 3400658: forwarding and wrongargs rewriting - via alias} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test handler1 foo bar
+ forward handler2 my handler x
+ method handler {a b c d} {list $a,$b,$c,$d}
+ export eval
+ }
+ fooClass create ::foo
+ foo eval {
+ interp alias {} [namespace current]::handler1 \
+ {} [namespace current]::my handler2
+ }
+ foo test 1 2 3
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "foo test d"}
+test oo-6.17 {Bug 3400658: forwarding and wrongargs rewriting - via ensemble} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test handler1 foo bar boo
+ forward handler2 my handler
+ method handler {a b c d} {list $a,$b,$c,$d}
+ export eval
+ }
+ fooClass create ::foo
+ foo eval {
+ namespace ensemble create \
+ -command [namespace current]::handler1 -parameters {p q} \
+ -map [list boo [list [namespace current]::my handler2]]
+ }
+ foo test 1 2 3
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "foo test c d"}
+test oo-6.18 {Bug 3408830: more forwarding cases} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward len string length
+ }
+ [fooClass create foo] len a b
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "::foo len string"}
+
+test oo-7.1 {OO: inheritance 101} -setup {
+ oo::class create superClass
+ oo::class create subClass
+ subClass create instance
+} -body {
+ oo::define superClass method doit x {lappend ::result $x}
+ oo::define subClass superclass superClass
+ set result [list [catch {subClass doit bad} msg] $msg]
+ instance doit ok
+ return $result
+} -cleanup {
+ subClass destroy
+ superClass destroy
+} -result {1 {unknown method "doit": must be create, destroy or new} ok}
+test oo-7.2 {OO: inheritance 101} -setup {
+ oo::class create superClass
+ oo::class create subClass
+ subClass create instance
+} -body {
+ oo::define superClass method doit x {
+ lappend ::result |$x|
+ }
+ oo::define subClass superclass superClass
+ oo::objdefine instance method doit x {
+ lappend ::result =$x=
+ next [incr x]
+ }
+ set result {}
+ instance doit 1
+ return $result
+} -cleanup {
+ subClass destroy
+ superClass destroy
+} -result {=1= |2|}
+test oo-7.3 {OO: inheritance 101} -setup {
+ oo::class create superClass
+ oo::class create subClass
+ subClass create instance
+} -body {
+ oo::define superClass method doit x {
+ lappend ::result |$x|
+ }
+ oo::define subClass {
+ superclass superClass
+ method doit x {lappend ::result -$x-; next [incr x]}
+ }
+ oo::objdefine instance method doit x {
+ lappend ::result =$x=;
+ next [incr x]
+ }
+ set result {}
+ instance doit 1
+ return $result
+} -cleanup {
+ subClass destroy
+ superClass destroy
+} -result {=1= -2- |3|}
+test oo-7.4 {OO: inheritance from oo::class} -body {
+ oo::class create meta {
+ superclass oo::class
+ self {
+ unexport create new
+ method make {x {definitions {}}} {
+ if {![string match ::* $x]} {
+ set ns [uplevel 1 {::namespace current}]
+ set x ${ns}::$x
+ }
+ set o [my create $x]
+ lappend ::result "made $o"
+ oo::define $o $definitions
+ return $o
+ }
+ }
+ }
+ set result [list [catch {meta create foo} msg] $msg]
+ lappend result [meta make classinstance {
+ lappend ::result "in definition script in [namespace current]"
+ }]
+ lappend result [classinstance create instance]
+} -cleanup {
+ catch {classinstance destroy}
+ catch {meta destroy}
+} -result {1 {unknown method "create": must be destroy or make} {made ::classinstance} {in definition script in ::oo::define} ::classinstance ::instance}
+test oo-7.5 {OO: inheritance from oo::class in the secondary chain} -body {
+ oo::class create other
+ oo::class create meta {
+ superclass other oo::class
+ self {
+ unexport create new
+ method make {x {definitions {}}} {
+ if {![string match ::* $x]} {
+ set ns [uplevel 1 {::namespace current}]
+ set x ${ns}::$x
+ }
+ set o [my create $x]
+ lappend ::result "made $o"
+ oo::define $o $definitions
+ return $o
+ }
+ }
+ }
+ set result [list [catch {meta create foo} msg] $msg]
+ lappend result [meta make classinstance {
+ lappend ::result "in definition script in [namespace current]"
+ }]
+ lappend result [classinstance create instance]
+} -cleanup {
+ catch {classinstance destroy}
+ catch {meta destroy}
+ catch {other destroy}
+} -result {1 {unknown method "create": must be destroy or make} {made ::classinstance} {in definition script in ::oo::define} ::classinstance ::instance}
+test oo-7.6 {OO: inheritance 101 - overridden methods should be oblivious} -setup {
+ oo::class create Aclass
+ oo::class create Bclass
+ Bclass create Binstance
+} -body {
+ oo::define Aclass {
+ method incr {var step} {
+ upvar 1 $var v
+ ::incr v $step
+ }
+ }
+ oo::define Bclass {
+ superclass Aclass
+ method incr {var {step 1}} {
+ global result
+ lappend result $var $step
+ set r [next $var $step]
+ lappend result returning:$r
+ return $r
+ }
+ }
+ set result {}
+ set x 10
+ lappend result x=$x
+ lappend result [Binstance incr x]
+ lappend result x=$x
+} -result {x=10 x 1 returning:11 11 x=11} -cleanup {
+ unset -nocomplain x
+ Aclass destroy
+}
+test oo-7.7 {OO: inheritance and errorInfo} -setup {
+ oo::class create A
+ oo::class create B
+ B create c
+} -body {
+ oo::define A method foo {} {error foo!}
+ oo::define B {
+ superclass A
+ method foo {} { next }
+ }
+ oo::objdefine c method foo {} { next }
+ catch {c ?} msg
+ set result [list $msg]
+ catch {c foo} msg
+ lappend result $msg $errorInfo
+} -cleanup {
+ A destroy
+} -result {{unknown method "?": must be destroy or foo} foo! {foo!
+ while executing
+"error foo!"
+ (class "::A" method "foo" line 1)
+ invoked from within
+"next "
+ (class "::B" method "foo" line 1)
+ invoked from within
+"next "
+ (object "::c" method "foo" line 1)
+ invoked from within
+"c foo"}}
+test oo-7.8 {OO: next at the end of the method chain} -setup {
+ set ::result ""
+} -cleanup {
+ foo destroy
+} -body {
+ oo::class create foo {
+ method bar {} {lappend ::result foo; lappend ::result [next] foo}
+ }
+ oo::class create foo2 {
+ superclass foo
+ method bar {} {lappend ::result foo2; lappend ::result [next] foo2}
+ }
+ lappend result [catch {[foo2 new] bar} msg] $msg
+} -result {foo2 foo 1 {no next method implementation}}
+test oo-7.9 {OO: defining inheritance in namespaces} -setup {
+ set ::result {}
+ oo::class create ::master
+ namespace eval ::foo {
+ oo::class create mixin {superclass ::master}
+ }
+} -cleanup {
+ ::master destroy
+ namespace delete ::foo
+} -body {
+ namespace eval ::foo {
+ oo::class create bar {superclass master}
+ oo::class create boo
+ oo::define boo {superclass bar}
+ oo::define boo {mixin mixin}
+ oo::class create spong {superclass boo}
+ return
+ }
+} -result {}
+
+test oo-8.1 {OO: global must work in methods} {
+ oo::object create foo
+ oo::objdefine foo method bar x {global result; lappend result $x}
+ set result {}
+ foo bar this
+ foo bar is
+ lappend result a
+ foo bar test
+ foo destroy
+ return $result
+} {this is a test}
+
+test oo-9.1 {OO: multiple inheritance} -setup {
+ oo::class create A
+ oo::class create B
+ oo::class create C
+ oo::class create D
+ D create foo
+} -body {
+ oo::define A method test {} {lappend ::result A; return ok}
+ oo::define B {
+ superclass A
+ method test {} {lappend ::result B; next}
+ }
+ oo::define C {
+ superclass A
+ method test {} {lappend ::result C; next}
+ }
+ oo::define D {
+ superclass B C
+ method test {} {lappend ::result D; next}
+ }
+ set result {}
+ lappend result [foo test]
+} -cleanup {
+ D destroy
+ C destroy
+ B destroy
+ A destroy
+} -result {D B C A ok}
+test oo-9.2 {OO: multiple inheritance} -setup {
+ oo::class create A
+ oo::class create B
+ oo::class create C
+ oo::class create D
+ D create foo
+} -body {
+ oo::define A method test {} {lappend ::result A; return ok}
+ oo::define B {
+ superclass A
+ method test {} {lappend ::result B; next}
+ }
+ oo::define C {
+ superclass A
+ method test {} {lappend ::result C; next}
+ }
+ oo::define D {
+ superclass B C
+ method test {} {lappend ::result D; next}
+ }
+ set result {}
+ lappend result [foo test]
+} -cleanup {
+ A destroy
+} -result {D B C A ok}
+
+test oo-10.1 {OO: recursive invoke and modify} -setup {
+ [oo::class create C] create O
+} -cleanup {
+ C destroy
+} -body {
+ oo::define C method foo x {
+ lappend ::result $x
+ if {$x} {
+ [self object] foo [incr x -1]
+ }
+ }
+ oo::objdefine O method foo x {
+ lappend ::result -$x-
+ if {$x == 1} {
+ oo::objdefine O deletemethod foo
+ }
+ next $x
+ }
+ set result {}
+ O foo 2
+ return $result
+} -result {-2- 2 -1- 1 0}
+test oo-10.2 {OO: recursive invoke and modify} -setup {
+ oo::object create O
+} -cleanup {
+ O destroy
+} -body {
+ oo::objdefine O method foo {} {
+ oo::objdefine [self] method foo {} {
+ error "not called"
+ }
+ return [format %s%s call ed]
+ }
+ O foo
+} -result called
+test oo-10.3 {OO: invoke and modify} -setup {
+ oo::class create A {
+ method a {} {return A.a}
+ method b {} {return A.b}
+ method c {} {return A.c}
+ }
+ oo::class create B {
+ superclass A
+ method a {} {return [next],B.a}
+ method b {} {return [next],B.b}
+ method c {} {return [next],B.c}
+ }
+ B create C
+ set result {}
+} -cleanup {
+ A destroy
+} -body {
+ lappend result [C a] [C b] [C c] -
+ oo::define B deletemethod b
+ lappend result [C a] [C b] [C c] -
+ oo::define B renamemethod a b
+ lappend result [C a] [C b] [C c] -
+ oo::define B deletemethod b c
+ lappend result [C a] [C b] [C c]
+} -result {A.a,B.a A.b,B.b A.c,B.c - A.a,B.a A.b A.c,B.c - A.a A.b,B.a A.c,B.c - A.a A.b A.c}
+
+test oo-11.1 {OO: cleanup} {
+ oo::object create foo
+ set result [list [catch {oo::object create foo} msg] $msg]
+ lappend result [foo destroy] [oo::object create foo] [foo destroy]
+} {1 {can't create object "foo": command already exists with that name} {} ::foo {}}
+test oo-11.2 {OO: cleanup} {
+ oo::class create bar
+ bar create foo
+ set result [list [catch {bar create foo} msg] $msg]
+ lappend result [bar destroy] [oo::object create foo] [foo destroy]
+} {1 {can't create object "foo": command already exists with that name} {} ::foo {}}
+test oo-11.3 {OO: cleanup} {
+ oo::class create bar0
+ oo::class create bar
+ oo::define bar superclass bar0
+ bar create foo
+ set result [list [catch {bar create foo} msg] $msg]
+ lappend result [bar0 destroy] [oo::object create foo] [foo destroy]
+} {1 {can't create object "foo": command already exists with that name} {} ::foo {}}
+test oo-11.4 {OO: cleanup} {
+ oo::class create bar0
+ oo::class create bar1
+ oo::define bar1 superclass bar0
+ oo::class create bar2
+ oo::define bar2 {
+ superclass bar0
+ destructor {lappend ::result destroyed}
+ }
+ oo::class create bar
+ oo::define bar superclass bar1 bar2
+ bar create foo
+ set result [list [catch {bar create foo} msg] $msg]
+ lappend result [bar0 destroy] [oo::object create foo] [foo destroy] \
+ [oo::object create bar2] [bar2 destroy]
+} {1 {can't create object "foo": command already exists with that name} destroyed {} ::foo {} ::bar2 {}}
+
+test oo-12.1 {OO: filters} {
+ oo::class create Aclass
+ Aclass create Aobject
+ oo::define Aclass {
+ method concatenate args {
+ global result
+ lappend result {*}$args
+ join $args {}
+ }
+ method logFilter args {
+ global result
+ lappend result "calling [self object]->[self method] $args"
+ set r [next {*}$args]
+ lappend result "result=$r"
+ return $r
+ }
+ }
+ oo::objdefine Aobject filter logFilter
+ set result {}
+ lappend result [Aobject concatenate 1 2 3 4 5]
+ Aclass destroy
+ return $result
+} {{calling ::Aobject->logFilter 1 2 3 4 5} 1 2 3 4 5 result=12345 12345}
+test oo-12.2 {OO: filters} -setup {
+ oo::class create Aclass
+ Aclass create Aobject
+} -body {
+ oo::define Aclass {
+ method concatenate args {
+ global result
+ lappend result {*}$args
+ join $args {}
+ }
+ method logFilter args {
+ global result
+ lappend result "calling [self object]->[self method] $args"
+ set r [next {*}$args]
+ lappend result "result=$r"
+ return $r
+ }
+ }
+ oo::objdefine Aobject filter logFilter
+ set result {}
+ lappend result [Aobject concatenate 1 2 3 4 5] [Aobject destroy]
+} -cleanup {
+ Aclass destroy
+} -result {{calling ::Aobject->logFilter 1 2 3 4 5} 1 2 3 4 5 result=12345 {calling ::Aobject->logFilter } result= 12345 {}}
+test oo-12.3 {OO: filters} -setup {
+ oo::class create Aclass
+ Aclass create Aobject
+} -body {
+ oo::define Aclass {
+ method concatenate args {
+ global result
+ lappend result {*}$args
+ join $args {}
+ }
+ method logFilter args {
+ global result
+ lappend result "calling [self object]->[self method] $args"
+ set r [next {*}$args]
+ lappend result "result=$r"
+ return $r
+ }
+ filter logFilter
+ }
+ set result {}
+ lappend result [Aobject concatenate 1 2 3 4 5] [Aobject destroy]
+} -cleanup {
+ Aclass destroy
+} -result {{calling ::Aobject->logFilter 1 2 3 4 5} 1 2 3 4 5 result=12345 {calling ::Aobject->logFilter } result= 12345 {}}
+test oo-12.4 {OO: filters} -setup {
+ oo::class create Aclass
+ Aclass create Aobject
+} -body {
+ oo::define Aclass {
+ method foo {} { return foo }
+ method Bar {} { return 1 }
+ method boo {} { if {[my Bar]} { next } { error forbidden } }
+ filter boo
+ }
+ Aobject foo
+} -cleanup {
+ Aclass destroy
+} -result foo
+test oo-12.5 {OO: filters} -setup {
+ oo::class create Aclass
+ Aclass create Aobject
+} -body {
+ oo::define Aclass {
+ method foo {} { return foo }
+ method Bar {} { return [my Bar2] }
+ method Bar2 {} { return 1 }
+ method boo {} { if {[my Bar]} { next } { error forbidden } }
+ filter boo
+ }
+ Aobject foo
+} -cleanup {
+ Aclass destroy
+} -result foo
+test oo-12.6 {OO: filters} -setup {
+ oo::class create Aclass
+ Aclass create Aobject
+} -body {
+ oo::define Aclass {
+ method foo {} { return foo }
+ method Bar {} { return [my Bar2] }
+ method Bar2 {} { return [my Bar3] }
+ method Bar3 {} { return 1 }
+ method boo {} { if {[my Bar]} { next } { error forbidden } }
+ filter boo
+ }
+ Aobject foo
+} -cleanup {
+ Aclass destroy
+} -result foo
+test oo-12.7 {OO: filters} -setup {
+ oo::class create Aclass
+ Aclass create Aobject
+} -body {
+ oo::define Aclass {
+ method outerfoo {} { return [my InnerFoo] }
+ method InnerFoo {} { return foo }
+ method Bar {} { return [my Bar2] }
+ method Bar2 {} { return [my Bar3] }
+ method Bar3 {} { return 1 }
+ method boo {} {
+ lappend ::log [self target]
+ if {[my Bar]} { next } else { error forbidden }
+ }
+ filter boo
+ }
+ set log {}
+ list [Aobject outerfoo] $log
+} -cleanup {
+ Aclass destroy
+} -result {foo {{::Aclass outerfoo} {::Aclass InnerFoo}}}
+
+test oo-13.1 {OO: changing an object's class} {
+ oo::class create Aclass
+ oo::define Aclass {method bar {} {lappend ::result "in A [self object]"}}
+ oo::class create Bclass
+ oo::define Bclass {method bar {} {lappend ::result "in B [self object]"}}
+ set result [Aclass create foo]
+ foo bar
+ oo::objdefine foo class Bclass
+ foo bar
+ Aclass destroy
+ lappend result [info command foo]
+ Bclass destroy
+ return $result
+} {::foo {in A ::foo} {in B ::foo} foo}
+test oo-13.2 {OO: changing an object's class} -body {
+ oo::object create foo
+ oo::objdefine foo class oo::class
+} -cleanup {
+ foo destroy
+} -returnCodes 1 -result {may not change a non-class object into a class object}
+test oo-13.3 {OO: changing an object's class} -body {
+ oo::class create foo
+ oo::objdefine foo class oo::object
+} -cleanup {
+ foo destroy
+} -returnCodes 1 -result {may not change a class object into a non-class object}
+test oo-13.4 {OO: changing an object's class} -body {
+ oo::class create foo {
+ method m {} {
+ set result [list [self class] [info object class [self]]]
+ oo::objdefine [self] class ::bar
+ lappend result [self class] [info object class [self]]
+ }
+ }
+ oo::class create bar
+ [foo new] m
+} -cleanup {
+ foo destroy
+ bar destroy
+} -result {::foo ::foo ::foo ::bar}
+# todo: changing a class subtype (metaclass) to another class subtype
+
+test oo-14.1 {OO: mixins} {
+ oo::class create Aclass
+ oo::define Aclass method bar {} {lappend ::result "[self object] in bar"}
+ oo::class create Bclass
+ oo::define Bclass method boo {} {lappend ::result "[self object] in boo"}
+ oo::objdefine [Aclass create fooTest] mixin Bclass
+ oo::objdefine [Aclass create fooTest2] mixin Bclass
+ set result [list [catch {fooTest ?} msg] $msg]
+ fooTest bar
+ fooTest boo
+ fooTest2 bar
+ fooTest2 boo
+ oo::objdefine fooTest2 mixin
+ lappend result [Bclass destroy] [info command fooTest*] [Aclass destroy]
+} {1 {unknown method "?": must be bar, boo or destroy} {::fooTest in bar} {::fooTest in boo} {::fooTest2 in bar} {::fooTest2 in boo} {} fooTest2 {}}
+test oo-14.2 {OO: mixins} {
+ oo::class create Aclass {
+ method bar {} {return "[self object] in bar"}
+ }
+ oo::class create Bclass {
+ method boo {} {return "[self object] in boo"}
+ }
+ oo::define Aclass mixin Bclass
+ Aclass create fooTest
+ set result [list [catch {fooTest ?} msg] $msg]
+ lappend result [catch {fooTest bar} msg] $msg
+ lappend result [catch {fooTest boo} msg] $msg
+ lappend result [Bclass destroy] [info commands Aclass]
+} {1 {unknown method "?": must be bar, boo or destroy} 0 {::fooTest in bar} 0 {::fooTest in boo} {} {}}
+test oo-14.3 {OO and mixins and filters - advanced case} -setup {
+ oo::class create mix
+ oo::class create c {
+ mixin mix
+ }
+ c create i
+} -body {
+ oo::define mix {
+ method foo {} {return >>[next]<<}
+ filter foo
+ }
+ oo::objdefine i method bar {} {return foobar}
+ i bar
+} -cleanup {
+ mix destroy
+ if {[info object isa object i]} {
+ error "mixin deletion failed to destroy dependent instance"
+ }
+} -result >>foobar<<
+test oo-14.4 {OO: mixin error case} -setup {
+ oo::class create c
+} -body {
+ oo::define c mixin c
+} -returnCodes error -cleanup {
+ c destroy
+} -result {may not mix a class into itself}
+test oo-14.5 {OO and mixins and filters - advanced case} -setup {
+ oo::class create mix
+ oo::class create c {
+ mixin mix
+ }
+ c create i
+} -body {
+ oo::define mix {
+ method foo {} {return >>[next]<<}
+ filter foo
+ }
+ oo::objdefine i method bar {} {return foobar}
+ i bar
+} -cleanup {
+ c destroy
+ mix destroy
+} -result >>foobar<<
+test oo-14.6 {OO and mixins of mixins - Bug 1960703} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create A {
+ superclass master
+ method egg {} {
+ return chicken
+ }
+ }
+ oo::class create B {
+ superclass master
+ mixin A
+ method bar {} {
+ # mixin from A
+ my egg
+ }
+ }
+ oo::class create C {
+ superclass master
+ mixin B
+ method foo {} {
+ # mixin from B
+ my bar
+ }
+ }
+ [C new] foo
+} -result chicken
+test oo-14.7 {OO and filters from mixins of mixins} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create A {
+ superclass master
+ method egg {} {
+ return chicken
+ }
+ filter f
+ method f args {
+ set m [lindex [self target] 1]
+ return "($m) [next {*}$args] ($m)"
+ }
+ }
+ oo::class create B {
+ superclass master
+ mixin A
+ filter f
+ method bar {} {
+ # mixin from A
+ my egg
+ }
+ }
+ oo::class create C {
+ superclass master
+ mixin B
+ filter f
+ method foo {} {
+ # mixin from B
+ my bar
+ }
+ }
+ [C new] foo
+} -result {(foo) (bar) (egg) chicken (egg) (bar) (foo)}
+test oo-14.8 {OO: class mixin order - Bug 1998221} -setup {
+ set ::result {}
+ oo::class create master {
+ method test {} {}
+ }
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create mix {
+ superclass master
+ method test {} {lappend ::result mix; next; return $::result}
+ }
+ oo::class create cls {
+ superclass master
+ mixin mix
+ method test {} {lappend ::result cls; next; return $::result}
+ }
+ [cls new] test
+} -result {mix cls}
+
+test oo-15.1 {OO: object cloning} {
+ oo::class create Aclass
+ oo::define Aclass method test {} {lappend ::result [self object]->test}
+ Aclass create Ainstance
+ set result {}
+ Ainstance test
+ oo::copy Ainstance Binstance
+ Binstance test
+ Ainstance test
+ Ainstance destroy
+ namespace eval foo {
+ oo::copy Binstance Cinstance
+ Cinstance test
+ }
+ Aclass destroy
+ namespace delete foo
+ lappend result [info commands Binstance]
+} {::Ainstance->test ::Binstance->test ::Ainstance->test ::foo::Cinstance->test {}}
+test oo-15.2 {OO: object cloning} {
+ oo::object create foo
+ oo::objdefine foo {
+ method m x {lappend ::result [self object] >$x<}
+ forward f ::lappend ::result fwd
+ }
+ set result {}
+ foo m 1
+ foo f 2
+ lappend result [oo::copy foo bar]
+ foo m 3
+ foo f 4
+ bar m 5
+ bar f 6
+ lappend result [foo destroy]
+ bar m 7
+ bar f 8
+ lappend result [bar destroy]
+} {::foo >1< fwd 2 ::bar ::foo >3< fwd 4 ::bar >5< fwd 6 {} ::bar >7< fwd 8 {}}
+catch {foo destroy}
+catch {bar destroy}
+test oo-15.3 {OO: class cloning} {
+ oo::class create foo {
+ method testme {} {lappend ::result [self class]->[self object]}
+ }
+ set result {}
+ foo create baseline
+ baseline testme
+ oo::copy foo bar
+ baseline testme
+ bar create tester
+ tester testme
+ foo destroy
+ tester testme
+ bar destroy
+ return $result
+} {::foo->::baseline ::foo->::baseline ::bar->::tester ::bar->::tester}
+test oo-15.4 {OO: object cloning - Bug 3474460} -setup {
+ oo::class create ArbitraryClass
+} -body {
+ ArbitraryClass create foo
+ oo::objdefine foo variable a b c
+ oo::copy foo bar
+ info object variable bar
+} -cleanup {
+ ArbitraryClass destroy
+} -result {a b c}
+test oo-15.5 {OO: class cloning - Bug 3474460} -setup {
+ oo::class create ArbitraryClass
+} -body {
+ oo::class create Foo {
+ superclass ArbitraryClass
+ variable a b c
+ }
+ oo::copy Foo Bar
+ info class variable Bar
+} -cleanup {
+ ArbitraryClass destroy
+} -result {a b c}
+test oo-15.6 {OO: object cloning copies namespace contents} -setup {
+ oo::class create ArbitraryClass {export eval}
+} -body {
+ ArbitraryClass create a
+ a eval {proc foo x {
+ variable y
+ return [string repeat $x [incr y]]
+ }}
+ set result [list [a eval {foo 2}] [a eval {foo 3}]]
+ oo::copy a b
+ a eval {rename foo bar}
+ lappend result [b eval {foo 2}] [b eval {foo 3}] [a eval {bar 4}]
+} -cleanup {
+ ArbitraryClass destroy
+} -result {2 33 222 3333 444}
+test oo-15.7 {OO: classes can be cloned anonymously} -setup {
+ oo::class create ArbitraryClassA
+ oo::class create ArbitraryClassB {superclass ArbitraryClassA}
+} -body {
+ info object isa class [oo::copy ArbitraryClassB]
+} -cleanup {
+ ArbitraryClassA destroy
+} -result 1
+test oo-15.8 {OO: intercept object cloning} -setup {
+ oo::class create Foo
+ set result {}
+} -body {
+ oo::define Foo {
+ constructor {msg} {
+ variable v $msg
+ }
+ method <cloned> {from} {
+ next $from
+ lappend ::result cloned $from [self]
+ }
+ method check {} {
+ variable v
+ lappend ::result check [self] $v
+ }
+ }
+ Foo create foo ok
+ oo::copy foo bar
+ foo check
+ bar check
+} -cleanup {
+ Foo destroy
+} -result {cloned ::foo ::bar check ::foo ok check ::bar ok}
+test oo-15.9 {ensemble rewriting must not bleed through oo::copy} -setup {
+ oo::class create Foo
+} -body {
+ oo::define Foo {
+ method <cloned> {a b} {}
+ }
+ interp alias {} Bar {} oo::copy [Foo create foo]
+ Bar bar
+} -returnCodes error -cleanup {
+ Foo destroy
+} -result {wrong # args: should be "::bar <cloned> a b"}
+
+test oo-16.1 {OO: object introspection} -body {
+ info object
+} -returnCodes 1 -result "wrong \# args: should be \"info object subcommand ?arg ...?\""
+test oo-16.2 {OO: object introspection} -body {
+ info object class NOTANOBJECT
+} -returnCodes 1 -result {NOTANOBJECT does not refer to an object}
+test oo-16.3 {OO: object introspection} -body {
+ info object gorp oo::object
+} -returnCodes 1 -result {unknown or ambiguous subcommand "gorp": must be call, class, definition, filters, forward, isa, methods, methodtype, mixins, namespace, variables, or vars}
+test oo-16.4 {OO: object introspection} -setup {
+ oo::class create meta { superclass oo::class }
+ [meta create instance1] create instance2
+} -body {
+ list [list [info object class oo::object] \
+ [info object class oo::class] \
+ [info object class meta] \
+ [info object class instance1] \
+ [info object class instance2]] \
+ [list [info object isa class oo::object] \
+ [info object isa class meta] \
+ [info object isa class instance1] \
+ [info object isa class instance2]] \
+ [list [info object isa metaclass oo::object] \
+ [info object isa metaclass oo::class] \
+ [info object isa metaclass meta] \
+ [info object isa metaclass instance1] \
+ [info object isa metaclass instance2]] \
+ [list [info object isa object oo::object] \
+ [info object isa object oo::class] \
+ [info object isa object meta] \
+ [info object isa object instance1] \
+ [info object isa object instance2] \
+ [info object isa object oo::define] \
+ [info object isa object NOTANOBJECT]]
+} -cleanup {
+ meta destroy
+} -result {{::oo::class ::oo::class ::oo::class ::meta ::instance1} {1 1 1 0} {0 1 1 0 0} {1 1 1 1 1 0 0}}
+test oo-16.5 {OO: object introspection} {info object methods oo::object} {}
+test oo-16.6 {OO: object introspection} {
+ oo::object create foo
+ set result [list [info object methods foo]]
+ oo::objdefine foo method bar {} {...}
+ lappend result [info object methods foo] [foo destroy]
+} {{} bar {}}
+test oo-16.7 {OO: object introspection} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo method bar {a {b c} args} {the body}
+ set result [info object methods foo]
+ lappend result [info object methodtype foo bar] \
+ [info object definition foo bar]
+} -cleanup {
+ foo destroy
+} -result {bar method {{a {b c} args} {the body}}}
+test oo-16.8 {OO: object introspection} {
+ oo::object create foo
+ oo::class create bar
+ oo::objdefine foo mixin bar
+ set result [list [info object mixins foo] \
+ [info object isa mixin foo bar] \
+ [info object isa mixin foo oo::class]]
+ foo destroy
+ bar destroy
+ return $result
+} {::bar 1 0}
+test oo-16.9 {OO: object introspection} -body {
+ oo::class create Ac
+ oo::class create Bc; oo::define Bc superclass Ac
+ oo::class create Cc; oo::define Cc superclass Bc
+ oo::class create Dc; oo::define Dc mixin Cc
+ Cc create E
+ Dc create F
+ list [info object isa typeof E oo::class] \
+ [info object isa typeof E Ac] \
+ [info object isa typeof F Bc] \
+ [info object isa typeof F Cc]
+} -cleanup {
+ catch {Ac destroy}
+} -result {0 1 1 1}
+test oo-16.10 {OO: object introspection} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo export eval
+ foo eval {variable c 3 a 1 b 2 ddd 4 e}
+ lsort [info object vars foo ?]
+} -cleanup {
+ foo destroy
+} -result {a b c}
+test oo-16.11 {OO: object introspection} -setup {
+ oo::class create foo
+ foo create bar
+} -body {
+ oo::define foo method spong {} {...}
+ oo::objdefine bar method boo {a {b c} args} {the body}
+ list [lsort [info object methods bar -all]] [lsort [info object methods bar -all -private]]
+} -cleanup {
+ foo destroy
+} -result {{boo destroy spong} {<cloned> boo destroy eval spong unknown variable varname}}
+test oo-16.12 {OO: object introspection} -setup {
+ oo::object create foo
+} -cleanup {
+ rename foo {}
+} -body {
+ oo::objdefine foo unexport {*}[info object methods foo -all]
+ info object methods foo -all
+} -result {}
+test oo-16.13 {OO: object introspection} -setup {
+ oo::object create foo
+} -cleanup {
+ rename foo {}
+} -body {
+ oo::objdefine foo method Bar {} {return "ok in foo"}
+ [info object namespace foo]::my Bar
+} -result "ok in foo"
+
+test oo-17.1 {OO: class introspection} -body {
+ info class
+} -returnCodes 1 -result "wrong \# args: should be \"info class subcommand ?arg ...?\""
+test oo-17.2 {OO: class introspection} -body {
+ info class superclass NOTANOBJECT
+} -returnCodes 1 -result {NOTANOBJECT does not refer to an object}
+test oo-17.3 {OO: class introspection} -setup {
+ oo::object create foo
+} -body {
+ info class superclass foo
+} -returnCodes 1 -cleanup {
+ foo destroy
+} -result {"foo" is not a class}
+test oo-17.4 {OO: class introspection} -body {
+ info class gorp oo::object
+} -returnCodes 1 -result {unknown or ambiguous subcommand "gorp": must be call, constructor, definition, destructor, filters, forward, instances, methods, methodtype, mixins, subclasses, superclasses, or variables}
+test oo-17.5 {OO: class introspection} -setup {
+ oo::class create testClass
+} -body {
+ testClass create foo
+ testClass create bar
+ testClass create spong
+ lsort [info class instances testClass]
+} -cleanup {
+ testClass destroy
+} -result {::bar ::foo ::spong}
+test oo-17.6 {OO: class introspection} -setup {
+ oo::class create foo
+} -body {
+ oo::define foo method bar {a {b c} args} {the body}
+ set result [info class methods foo]
+ lappend result [info class methodtype foo bar] \
+ [info class definition foo bar]
+} -cleanup {
+ foo destroy
+} -result {bar method {{a {b c} args} {the body}}}
+test oo-17.7 {OO: class introspection} {
+ info class superclasses oo::class
+} ::oo::object
+test oo-17.8 {OO: class introspection} -setup {
+ oo::class create testClass
+ oo::class create superClass1
+ oo::class create superClass2
+} -body {
+ oo::define testClass superclass superClass1 superClass2
+ list [info class superclasses testClass] \
+ [lsort [info class subclass oo::object ::superClass?]]
+} -cleanup {
+ testClass destroy
+ superClass1 destroy
+ superClass2 destroy
+} -result {{::superClass1 ::superClass2} {::superClass1 ::superClass2}}
+test oo-17.9 {OO: class introspection} -setup {
+ oo::class create foo
+ oo::class create subfoo {superclass foo}
+} -body {
+ oo::define foo {
+ method bar {a {b c} args} {the body}
+ self {
+ method bad {} {...}
+ }
+ }
+ oo::define subfoo method boo {a {b c} args} {the body}
+ list [lsort [info class methods subfoo -all]] \
+ [lsort [info class methods subfoo -all -private]]
+} -cleanup {
+ foo destroy
+} -result {{bar boo destroy} {<cloned> bar boo destroy eval unknown variable varname}}
+test oo-17.10 {OO: class introspection} -setup {
+ oo::class create foo
+} -cleanup {
+ rename foo {}
+} -body {
+ oo::define foo unexport {*}[info class methods foo -all]
+ info class methods foo -all
+} -result {}
+
+test oo-18.1 {OO: define command support} {
+ list [catch {oo::define oo::object {error foo}} msg] $msg $errorInfo
+} {1 foo {foo
+ while executing
+"error foo"
+ (in definition script for class "::oo::object" line 1)
+ invoked from within
+"oo::define oo::object {error foo}"}}
+test oo-18.2 {OO: define command support} {
+ list [catch {oo::define oo::object error foo} msg] $msg $errorInfo
+} {1 foo {foo
+ while executing
+"oo::define oo::object error foo"}}
+test oo-18.3 {OO: define command support} {
+ list [catch {oo::class create foo {error bar}} msg] $msg $errorInfo
+} {1 bar {bar
+ while executing
+"error bar"
+ (in definition script for class "::foo" line 1)
+ invoked from within
+"oo::class create foo {error bar}"}}
+test oo-18.3a {OO: define command support} {
+ list [catch {oo::class create foo {
+ error bar
+}} msg] $msg $errorInfo
+} {1 bar {bar
+ while executing
+"error bar"
+ (in definition script for class "::foo" line 2)
+ invoked from within
+"oo::class create foo {
+ error bar
+}"}}
+test oo-18.3b {OO: define command support} {
+ list [catch {oo::class create foo {
+ eval eval error bar
+}} msg] $msg $errorInfo
+} {1 bar {bar
+ while executing
+"error bar"
+ ("eval" body line 1)
+ invoked from within
+"eval error bar"
+ ("eval" body line 1)
+ invoked from within
+"eval eval error bar"
+ (in definition script for class "::foo" line 2)
+ invoked from within
+"oo::class create foo {
+ eval eval error bar
+}"}}
+test oo-18.4 {OO: more error traces from the guts} -setup {
+ oo::object create obj
+} -body {
+ oo::objdefine obj method bar {} {my eval {error foo}}
+ list [catch {obj bar} msg] $msg $errorInfo
+} -cleanup {
+ obj destroy
+} -result {1 foo {foo
+ while executing
+"error foo"
+ (in "my eval" script line 1)
+ invoked from within
+"my eval {error foo}"
+ (object "::obj" method "bar" line 1)
+ invoked from within
+"obj bar"}}
+test oo-18.5 {OO: more error traces from the guts} -setup {
+ [oo::class create cls] create obj
+ set errorInfo {}
+} -body {
+ oo::define cls {
+ method eval script {next $script}
+ export eval
+ }
+ oo::objdefine obj method bar {} {my eval {error foo}}
+ set result {}
+ lappend result [catch {obj bar} msg] $msg $errorInfo
+ lappend result [catch {obj eval {error bar}} msg] $msg $errorInfo
+} -cleanup {
+ cls destroy
+} -result {1 foo {foo
+ while executing
+"error foo"
+ (in "my eval" script line 1)
+ invoked from within
+"next $script"
+ (class "::cls" method "eval" line 1)
+ invoked from within
+"my eval {error foo}"
+ (object "::obj" method "bar" line 1)
+ invoked from within
+"obj bar"} 1 bar {bar
+ while executing
+"error bar"
+ (in "::obj eval" script line 1)
+ invoked from within
+"next $script"
+ (class "::cls" method "eval" line 1)
+ invoked from within
+"obj eval {error bar}"}}
+test oo-18.6 {class construction reference management and errors} -setup {
+ oo::class create super_abc
+} -body {
+ catch {
+oo::class create abc {
+ superclass super_abc
+ ::rename abc ::def
+ ::error foo
+}
+ } msg opt
+ dict get $opt -errorinfo
+} -cleanup {
+ super_abc destroy
+} -result {foo
+ while executing
+"::error foo"
+ (in definition script for class "::def" line 4)
+ invoked from within
+"oo::class create abc {
+ superclass super_abc
+ ::rename abc ::def
+ ::error foo
+}"}
+test oo-18.7 {OO: objdefine command support} -setup {
+ oo::object create ::inst
+} -body {
+ list [catch {oo::objdefine inst {rename ::inst ::INST;error foo}} msg] $msg $errorInfo
+} -cleanup {
+ catch {::inst destroy}
+ catch {::INST destroy}
+} -result {1 foo {foo
+ while executing
+"error foo"
+ (in definition script for object "::INST" line 1)
+ invoked from within
+"oo::objdefine inst {rename ::inst ::INST;error foo}"}}
+test oo-18.8 {OO: define/self command support} -setup {
+ oo::class create master
+ oo::class create ::foo {superclass master}
+} -body {
+ catch {oo::define foo {rename ::foo ::bar; self {error foobar}}} msg opt
+ dict get $opt -errorinfo
+} -cleanup {
+ master destroy
+} -result {foobar
+ while executing
+"error foobar"
+ (in definition script for class object "::bar" line 1)
+ invoked from within
+"self {error foobar}"
+ (in definition script for class "::bar" line 1)
+ invoked from within
+"oo::define foo {rename ::foo ::bar; self {error foobar}}"}
+test oo-18.9 {OO: define/self command support} -setup {
+ oo::class create master
+ set c [oo::class create now_this_is_a_very_very_long_class_name_indeed {
+ superclass master
+ }]
+} -body {
+ catch {oo::define $c {error err}} msg opt
+ dict get $opt -errorinfo
+} -cleanup {
+ master destroy
+} -result {err
+ while executing
+"error err"
+ (in definition script for class "::now_this_is_a_very_very_long..." line 1)
+ invoked from within
+"oo::define $c {error err}"}
+test oo-18.10 {OO: define/self command support} -setup {
+ oo::class create master
+ oo::class create ::foo {superclass master}
+} -body {
+ catch {oo::define foo {self {rename ::foo {}; error foobar}}} msg opt
+ dict get $opt -errorinfo
+} -cleanup {
+ master destroy
+} -result {foobar
+ while executing
+"error foobar"
+ (in definition script for class object "::foo" line 1)
+ invoked from within
+"self {rename ::foo {}; error foobar}"
+ (in definition script for class "::foo" line 1)
+ invoked from within
+"oo::define foo {self {rename ::foo {}; error foobar}}"}
+test oo-18.11 {OO: define/self command support} -setup {
+ oo::class create master
+ oo::class create ::foo {superclass master}
+} -body {
+ catch {oo::define foo {rename ::foo {}; self {error foobar}}} msg opt
+ dict get $opt -errorinfo
+} -cleanup {
+ master destroy
+} -result {this command cannot be called when the object has been deleted
+ while executing
+"self {error foobar}"
+ (in definition script for class "::foo" line 1)
+ invoked from within
+"oo::define foo {rename ::foo {}; self {error foobar}}"}
+
+test oo-19.1 {OO: varname method} -setup {
+ oo::object create inst
+ oo::objdefine inst export eval
+ set result {}
+ inst eval { variable x }
+} -body {
+ inst eval {trace add variable x write foo}
+ set ns [inst eval namespace current]
+ proc foo args {
+ global ns result
+ set context [uplevel 1 namespace current]
+ lappend result $args [expr {
+ $ns eq $context ? "ok" : [list $ns ne $context]
+ }] [expr {
+ "${ns}::x" eq [uplevel 1 my varname x] ? "ok" : [list ${ns}::x ne [uplevel 1 my varname x]]
+ }]
+ }
+ lappend result [inst eval set x 0]
+} -cleanup {
+ inst destroy
+ rename foo {}
+} -result {{x {} write} ok ok 0}
+test oo-19.2 {OO: varname method: Bug 2883857} -setup {
+ oo::class create SpecialClass
+ oo::objdefine SpecialClass export createWithNamespace
+ SpecialClass createWithNamespace inst ::oo_test
+ oo::objdefine inst export varname eval
+} -body {
+ inst eval { variable x; array set x {y z} }
+ inst varname x(y)
+} -cleanup {
+ SpecialClass destroy
+} -result ::oo_test::x(y)
+
+test oo-20.1 {OO: variable method} -body {
+ oo::class create testClass {
+ constructor {} {
+ my variable ok
+ set ok {}
+ }
+ }
+ lsort [info object vars [testClass new]]
+} -cleanup {
+ catch {testClass destroy}
+} -result ok
+test oo-20.2 {OO: variable method} -body {
+ oo::class create testClass {
+ constructor {} {
+ my variable a b c
+ set a [set b [set c {}]]
+ }
+ }
+ lsort [info object vars [testClass new]]
+} -cleanup {
+ catch {testClass destroy}
+} -result {a b c}
+test oo-20.3 {OO: variable method} -body {
+ oo::class create testClass {
+ export varname
+ method bar {} {
+ my variable a(b)
+ }
+ }
+ testClass create foo
+ array set [foo varname a] {b c}
+ foo bar
+} -returnCodes 1 -cleanup {
+ catch {testClass destroy}
+} -result {can't define "a(b)": name refers to an element in an array}
+test oo-20.4 {OO: variable method} -body {
+ oo::class create testClass {
+ export varname
+ method bar {} {
+ my variable a(b)
+ }
+ }
+ testClass create foo
+ set [foo varname a] b
+ foo bar
+} -returnCodes 1 -cleanup {
+ catch {testClass destroy}
+} -result {can't define "a(b)": name refers to an element in an array}
+test oo-20.5 {OO: variable method} -body {
+ oo::class create testClass {
+ method bar {} {
+ my variable a::b
+ }
+ }
+ testClass create foo
+ foo bar
+} -returnCodes 1 -cleanup {
+ catch {testClass destroy}
+} -result {variable name "a::b" illegal: must not contain namespace separator}
+test oo-20.6 {OO: variable method} -setup {
+ oo::class create testClass {
+ export varname
+ self export eval
+ }
+} -body {
+ testClass eval variable a 0
+ oo::objdefine [testClass create foo] method bar {other} {
+ $other variable a
+ set a 3
+ }
+ oo::objdefine [testClass create boo] export variable
+ set [foo varname a] 1
+ set [boo varname a] 2
+ foo bar boo
+ list [testClass eval set a] [set [foo varname a]] [set [boo varname a]]
+} -cleanup {
+ testClass destroy
+} -result {0 1 3}
+test oo-20.7 {OO: variable method} -setup {
+ oo::class create cls
+} -body {
+ oo::define cls {
+ method a {} {
+ my variable d b
+ lappend b $d
+ }
+ method e {} {
+ my variable b d
+ return [list $b $d]
+ }
+ method f {x y} {
+ my variable b d
+ set b $x
+ set d $y
+ }
+ }
+ cls create obj
+ obj f p q
+ obj a
+ obj a
+ obj e
+} -cleanup {
+ cls destroy
+} -result {{p q q} q}
+# oo-20.8 tested explicitly for functionality removed due to [Bug 1959457]
+test oo-20.9 {OO: variable method} -setup {
+ oo::object create obj
+} -body {
+ oo::objdefine obj {
+ method a {} {
+ my variable ::b
+ }
+ }
+ obj a
+} -returnCodes 1 -cleanup {
+ obj destroy
+} -result {variable name "::b" illegal: must not contain namespace separator}
+test oo-20.10 {OO: variable and varname methods refer to same things} -setup {
+ oo::object create obj
+} -body {
+ oo::objdefine obj {
+ method a {} {
+ my variable b
+ set b [self]
+ return [my varname b]
+ }
+ }
+ list [set [obj a]] [namespace tail [obj a]]
+} -cleanup {
+ obj destroy
+} -result {::obj b}
+test oo-20.11 {OO: variable mustn't crash when recursing} -body {
+ oo::class create A {
+ constructor {name} {
+ my variable np_name
+ set np_name $name
+ }
+ method copy {nm} {
+ set cpy [[info object class [self]] new $nm]
+ foreach var [info object vars [self]] {
+ my variable $var
+ set val [set $var]
+ if {[string match o_* $var]} {
+ set objs {}
+ foreach ref $val {
+ # call to "copy" crashes
+ lappend objs [$ref copy {}]
+ }
+ $cpy prop $var $objs
+ } else {
+ $cpy prop $var $val
+ }
+ }
+ return $cpy
+ }
+ method prop {name val} {
+ my variable $name
+ set $name $val
+ }
+ }
+ set o1 [A new {}]
+ set o2 [A new {}]
+ $o1 prop o_object $o2
+ $o1 copy aa
+} -cleanup {
+ catch {A destroy}
+} -match glob -result *
+test oo-20.12 {OO: variable method accept zero args (TIP 323)} -setup {
+ oo::object create foo
+} -cleanup {
+ foo destroy
+} -body {
+ oo::objdefine foo method demo {} {
+ my variable
+ }
+ foo demo
+} -result {}
+test oo-20.13 {OO: variable method use in non-methods [Bug 2903811]} -setup {
+ oo::object create fooObj
+ oo::objdefine fooObj export variable
+} -cleanup {
+ fooObj destroy
+} -body {
+ apply {{} {fooObj variable x; set x ok; return}}
+ apply {{} {fooObj variable x; return $x}}
+} -result ok
+test oo-20.14 {OO: variable method use in non-methods [Bug 2903811]} -setup {
+ oo::object create fooObj
+ oo::objdefine fooObj export variable
+ namespace eval ns1 {}
+ namespace eval ns2 {}
+ set x bad
+} -cleanup {
+ fooObj destroy
+ namespace delete ns1 ns2
+ unset x
+} -body {
+ namespace eval ns1 {fooObj variable x; set x ok; subst ""}
+ set x bad
+ namespace eval ns2 {fooObj variable x; return $x}
+} -result ok
+test oo-20.15 {OO: variable method use in non-methods [Bug 2903811]} -setup {
+ oo::object create fooObj
+ oo::objdefine fooObj export variable varname
+} -cleanup {
+ fooObj destroy
+} -body {
+ apply {{} {fooObj variable x; set x ok; return}}
+ return [set [fooObj varname x]]
+} -result ok
+test oo-20.16 {variable method: leak per instance} -setup {
+ oo::class create foo
+} -constraints memory -body {
+ oo::define foo {
+ constructor {} {
+ set [my variable v] 0
+ }
+ }
+ leaktest {[foo new] destroy}
+} -cleanup {
+ foo destroy
+} -result 0
+
+test oo-21.1 {OO: inheritance ordering} -setup {
+ oo::class create A
+} -body {
+ oo::define A method m {} {lappend ::result A}
+ oo::class create B {
+ superclass A
+ method m {} {lappend ::result B;next}
+ }
+ oo::class create C {
+ superclass A
+ method m {} {lappend ::result C;next}
+ }
+ oo::class create D {
+ superclass B C
+ method m {} {lappend ::result D;next}
+ }
+ D create o
+ oo::objdefine o method m {} {lappend ::result o;next}
+ set result {}
+ o m
+ return $result
+} -cleanup {
+ A destroy
+} -result {o D B C A}
+test oo-21.2 {OO: inheritance ordering} -setup {
+ oo::class create A
+} -body {
+ oo::define A method m {} {lappend ::result A}
+ oo::class create B {
+ superclass A
+ method m {} {lappend ::result B;next}
+ }
+ oo::class create C {
+ superclass A
+ method m {} {lappend ::result C;next}
+ }
+ oo::class create D {
+ superclass B C
+ method m {} {lappend ::result D;next}
+ }
+ oo::class create Emix {
+ superclass C
+ method m {} {lappend ::result Emix;next}
+ }
+ oo::class create Fmix {
+ superclass Emix
+ method m {} {lappend ::result Fmix;next}
+ }
+ D create o
+ oo::objdefine o {
+ method m {} {lappend ::result o;next}
+ mixin Fmix
+ }
+ set result {}
+ o m
+ return $result
+} -cleanup {
+ A destroy
+} -result {Fmix Emix o D B C A}
+test oo-21.3 {OO: inheritance ordering} -setup {
+ oo::class create A
+} -body {
+ oo::define A method m {} {lappend ::result A}
+ oo::class create B {
+ superclass A
+ method m {} {lappend ::result B;next}
+ method f {} {lappend ::result B-filt;next}
+ }
+ oo::class create C {
+ superclass A
+ method m {} {lappend ::result C;next}
+ }
+ oo::class create D {
+ superclass B C
+ method m {} {lappend ::result D;next}
+ }
+ oo::class create Emix {
+ superclass C
+ method m {} {lappend ::result Emix;next}
+ method f {} {lappend ::result Emix-filt;next}
+ }
+ oo::class create Fmix {
+ superclass Emix
+ method m {} {lappend ::result Fmix;next}
+ }
+ D create o
+ oo::objdefine o {
+ method m {} {lappend ::result o;next}
+ mixin Fmix
+ filter f
+ }
+ set result {}
+ o m
+ return $result
+} -cleanup {
+ A destroy
+} -result {Emix-filt B-filt Fmix Emix o D B C A}
+test oo-21.4 {OO: inheritance ordering} -setup {
+ oo::class create A
+} -body {
+ oo::define A method m {} {lappend ::result A}
+ oo::class create B {
+ superclass A
+ method m {} {lappend ::result B;next}
+ method f {} {lappend ::result B-filt;next}
+ method g {} {lappend ::result B-cfilt;next}
+ }
+ oo::class create C {
+ superclass A
+ method m {} {lappend ::result C;next}
+ }
+ oo::class create D {
+ superclass B C
+ method m {} {lappend ::result D;next}
+ method g {} {lappend ::result D-cfilt;next}
+ filter g
+ }
+ oo::class create Emix {
+ superclass C
+ method m {} {lappend ::result Emix;next}
+ method f {} {lappend ::result Emix-filt;next}
+ }
+ oo::class create Fmix {
+ superclass Emix
+ method m {} {lappend ::result Fmix;next}
+ }
+ D create o
+ oo::objdefine o {
+ method m {} {lappend ::result o;next}
+ mixin Fmix
+ filter f
+ }
+ set result {}
+ o m
+ return $result
+} -cleanup {
+ A destroy
+} -result {Emix-filt B-filt D-cfilt B-cfilt Fmix Emix o D B C A}
+
+test oo-22.1 {OO and info frame} -setup {
+ oo::class create c
+ c create i
+} -match glob -body {
+ oo::define c self method frame {} {
+ info frame 0
+ }
+ oo::define c {
+ method frames {} {
+ info frame 0
+ }
+ method level {} {
+ info frame
+ }
+ }
+ oo::objdefine i {
+ method frames {} {
+ list [next] [info frame 0]
+ }
+ method level {} {
+ expr {[next] - [info frame]}
+ }
+ }
+ list [i level] [i frames] [dict get [c frame] object]
+} -cleanup {
+ c destroy
+} -result {1 {{* cmd {info frame 0} method frames class ::c level 0} {* cmd {info frame 0} method frames object ::i level 0}} ::c}
+test oo-22.2 {OO and info frame: Bug 3001438} -setup {
+ oo::class create c
+} -body {
+ oo::define c method test {{x 1}} {
+ if {$x} {my test 0}
+ lsort {q w e r t y u i o p}; # Overwrite the Tcl stack
+ info frame 0
+ }
+ [c new] test
+} -match glob -cleanup {
+ c destroy
+} -result {* cmd {info frame 0} method test class ::c level 0}
+
+# Prove that the issue in [Bug 1865054] isn't an issue any more
+test oo-23.1 {Self-like derivation; complex case!} -setup {
+ oo::class create SELF {
+ superclass oo::class
+ unexport create new
+ # Next is just a convenience
+ method method args {oo::define [self] method {*}$args}
+ method derive {name} {
+ set o [my new [list superclass [self]]]
+ oo::objdefine $o mixin $o
+ uplevel 1 [list rename $o $name]\;[list namespace which $name]
+ }
+ self mixin SELF
+ }
+ set result {}
+} -body {
+ [SELF derive foo1] method bar1 {} {return 1}
+ lappend result [foo1 bar1]
+ [foo1 derive foo2] method bar2 {} {return [my bar1],2}
+ lappend result [foo2 bar2]
+ [foo2 derive foo3] method bar3 {} {return [my bar2],3}
+ lappend result [foo3 bar3]
+ [foo3 derive foo4] method bar4 {} {return [my bar3],4}
+ lappend result [foo4 bar4]
+ foo2 method bar2 {} {return [my bar1],x}
+ lappend result [foo4 bar4]
+} -cleanup {
+ SELF destroy
+} -result {1 1,2 1,2,3 1,2,3,4 1,x,3,4}
+
+test oo-24.1 {unknown method method - Bug 1965063} -setup {
+ oo::class create cls
+} -cleanup {
+ cls destroy
+} -returnCodes error -body {
+ oo::define cls {
+ method dummy {} {}
+ method unknown args {next {*}$args}
+ }
+ [cls new] foo bar
+} -result {unknown method "foo": must be destroy, dummy or unknown}
+test oo-24.2 {unknown method method - Bug 1965063} -setup {
+ oo::class create cls
+} -cleanup {
+ cls destroy
+} -returnCodes error -body {
+ oo::define cls {
+ method dummy {} {}
+ method unknown args {next {*}$args}
+ }
+ cls create obj
+ oo::objdefine obj {
+ method dummy2 {} {}
+ method unknown args {next {*}$args}
+ }
+ obj foo bar
+} -result {unknown method "foo": must be destroy, dummy, dummy2 or unknown}
+test oo-24.3 {unknown method method - absent method name} -setup {
+ set o [oo::object new]
+} -cleanup {
+ $o destroy
+} -body {
+ oo::objdefine $o method unknown args {
+ return "unknown: >>$args<<"
+ }
+ list [$o] [$o foobar] [$o foo bar]
+} -result {{unknown: >><<} {unknown: >>foobar<<} {unknown: >>foo bar<<}}
+
+# Probably need a better set of tests, but this is quite difficult to devise
+test oo-25.1 {call chain caching} -setup {
+ oo::class create cls {
+ method ab {} {return ok}
+ }
+ set result {}
+} -cleanup {
+ cls destroy
+} -body {
+ cls create foo
+ cls create bar
+ set m1 ab
+ set m2 a; append m2 b ;# different object!
+ lappend result [foo $m1] [foo $m1] [bar $m1] [foo $m1]
+ lappend result [foo $m2] [bar $m2]
+ oo::objdefine foo method ab {} {return good}
+ lappend result [foo $m1] [bar $m2]
+} -result {ok ok ok ok ok ok good ok}
+test oo-25.2 {call chain caching - Bug #2120903} -setup {
+ set c [oo::class create MyClass]
+ set o [$c new]
+} -body {
+ oo::define MyClass {
+ method name {} {return ok}
+ method isa o {MyClass name $o}
+ self method name o {$o name}
+ }
+ list [$o name] [$c name $o] [$o isa $o]
+} -cleanup {
+ $c destroy
+} -result {ok ok ok}
+
+test oo-26.1 {Bug 2037727} -setup {
+ proc succeed args {}
+ oo::object create example
+} -body {
+ oo::objdefine example method foo {} {succeed}
+ example foo
+ proc succeed {} {return succeed}
+ example foo
+} -cleanup {
+ example destroy
+ rename succeed {}
+} -result succeed
+test oo-26.2 {Bug 2037727} -setup {
+ oo::class create example {
+ method localProc {args body} {proc called $args $body}
+ method run {} { called }
+ }
+ example create i1
+ example create i2
+} -body {
+ i1 localProc args {}
+ i2 localProc args {return nonempty}
+ list [i1 run] [i2 run]
+} -cleanup {
+ example destroy
+} -result {{} nonempty}
+test oo-26.3 {Bug 2037727} -setup {
+ oo::class create example {
+ method subProc {args body} {
+ namespace eval subns [list proc called $args $body]
+ }
+ method run {} { subns::called }
+ }
+ example create i1
+ example create i2
+} -body {
+ i1 subProc args {}
+ i2 subProc args {return nonempty}
+ list [i1 run] [i2 run]
+} -cleanup {
+ example destroy
+} -result {{} nonempty}
+
+test oo-27.1 {variables declaration - class introspection} -setup {
+ oo::class create foo
+} -cleanup {
+ foo destroy
+} -body {
+ oo::define foo variable a b c
+ info class variables foo
+} -result {a b c}
+test oo-27.2 {variables declaration - object introspection} -setup {
+ oo::object create foo
+} -cleanup {
+ foo destroy
+} -body {
+ oo::objdefine foo variable a b c
+ info object variables foo
+} -result {a b c}
+test oo-27.3 {variables declaration - basic behaviour} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x!
+ constructor {} {set x! 1}
+ method y {} {incr x!}
+ }
+ foo create bar
+ bar y
+ bar y
+} -result 3
+test oo-27.4 {variables declaration - destructors too} -setup {
+ oo::class create master
+ set result bad!
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x!
+ constructor {} {set x! 1}
+ method y {} {incr x!}
+ destructor {set ::result ${x!}}
+ }
+ foo create bar
+ bar y
+ bar y
+ bar destroy
+ return $result
+} -result 3
+test oo-27.5 {variables declaration - object-bound variables} -setup {
+ oo::object create foo
+} -cleanup {
+ foo destroy
+} -body {
+ oo::objdefine foo {
+ variable x!
+ method y {} {incr x!}
+ }
+ foo y
+ foo y
+} -result 2
+test oo-27.6 {variables declaration - non-interference of levels} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x!
+ constructor {} {set x! 1}
+ method y {} {incr x!}
+ }
+ foo create bar
+ oo::objdefine bar {
+ variable y!
+ method y {} {list [next] [incr y!] [info var] [info local]}
+ export eval
+ }
+ bar y
+ list [bar y] [lsort [info object vars bar]] [bar eval {info vars *!}]
+} -result {{3 2 y! {}} {x! y!} {x! y!}}
+test oo-27.7 {variables declaration - one underlying variable space} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x!
+ constructor {} {set x! 1}
+ method y {} {incr x!}
+ }
+ oo::class create foo2 {
+ superclass foo
+ variable y!
+ constructor {} {set y! 42; next}
+ method x {} {incr y! -1}
+ }
+ foo2 create bar
+ oo::objdefine bar {
+ variable x! y!
+ method z {} {list ${x!} ${y!}}
+ }
+ bar y
+ bar x
+ list [bar y] [bar x] [bar z]
+} -result {3 40 {3 40}}
+test oo-27.8 {variables declaration - error cases - ns separators} -body {
+ oo::define oo::object variable bad::var
+} -returnCodes error -result {invalid declared variable name "bad::var": must not contain namespace separators}
+test oo-27.9 {variables declaration - error cases - arrays} -body {
+ oo::define oo::object variable bad(var)
+} -returnCodes error -result {invalid declared variable name "bad(var)": must not refer to an array element}
+test oo-27.10 {variables declaration - no instance var leaks with class resolvers} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable clsvar
+ constructor {} {
+ set clsvar 0
+ }
+ method step {} {
+ incr clsvar
+ return
+ }
+ method value {} {
+ return $clsvar
+ }
+ }
+ foo create inst1
+ inst1 step
+ foo create inst2
+ inst2 step
+ inst1 step
+ inst2 step
+ inst1 step
+ list [inst1 value] [inst2 value]
+} -result {3 2}
+test oo-27.11 {variables declaration - no instance var leaks with class resolvers} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable clsvar
+ constructor {} {
+ set clsvar 0
+ }
+ method step {} {
+ incr clsvar
+ return
+ }
+ method value {} {
+ return $clsvar
+ }
+ }
+ foo create inst1
+ oo::objdefine inst1 {
+ variable clsvar
+ method reinit {} {
+ set clsvar 0
+ }
+ }
+ foo create inst2
+ oo::objdefine inst2 {
+ variable clsvar
+ method reinit {} {
+ set clsvar 0
+ }
+ }
+ inst1 step
+ inst2 step
+ inst1 reinit
+ inst2 reinit
+ inst1 step
+ inst2 step
+ inst1 step
+ inst2 step
+ inst1 step
+ list [inst1 value] [inst2 value]
+} -result {3 2}
+test oo-27.12 {variables declaration: leak per instance} -setup {
+ oo::class create foo
+} -constraints memory -body {
+ oo::define foo {
+ variable v
+ constructor {} {
+ set v 0
+ }
+ }
+ leaktest {[foo new] destroy}
+} -cleanup {
+ foo destroy
+} -result 0
+# This test will actually (normally) crash if it fails!
+test oo-27.13 {variables declaration: Bug 3185009: require refcount management} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo {
+ variable x
+ method set v {set x $v}
+ method unset {} {unset x}
+ method exists {} {info exists x}
+ method get {} {return $x}
+ }
+ list [foo exists] [foo set 7] [foo exists] [foo get] [foo unset] \
+ [foo exists] [catch {foo get} msg] $msg
+} -cleanup {
+ foo destroy
+} -result {0 7 1 7 {} 0 1 {can't read "x": no such variable}}
+test oo-27.14 {variables declaration - multiple use} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x
+ variable y
+ method boo {} {
+ return [incr x],[incr y]
+ }
+ }
+ foo create bar
+ list [bar boo] [bar boo]
+} -result {1,1 2,2}
+test oo-27.15 {variables declaration - multiple use} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable
+ variable x y
+ method boo {} {
+ return [incr x],[incr y]
+ }
+ }
+ foo create bar
+ list [bar boo] [bar boo]
+} -result {1,1 2,2}
+test oo-27.16 {variables declaration - multiple use} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x
+ variable -clear
+ variable y
+ method boo {} {
+ return [incr x],[incr y]
+ }
+ }
+ foo create bar
+ list [bar boo] [bar boo]
+} -result {1,1 1,2}
+test oo-27.17 {variables declaration - multiple use} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x
+ variable -set y
+ method boo {} {
+ return [incr x],[incr y]
+ }
+ }
+ foo create bar
+ list [bar boo] [bar boo]
+} -result {1,1 1,2}
+test oo-27.18 {variables declaration - multiple use} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x
+ variable -? y
+ method boo {} {
+ return [incr x],[incr y]
+ }
+ }
+ foo create bar
+ list [bar boo] [bar boo]
+} -returnCodes error -match glob -result {unknown method "-?": must be *}
+test oo-27.19 {variables declaration and [info vars]: Bug 2712377} -setup {
+ oo::class create Foo
+ set result {}
+} -body {
+ # This is really a test of problems to do with Tcl's introspection when a
+ # variable resolver is present...
+ oo::define Foo {
+ variable foo bar
+ method setvars {f b} {
+ set foo $f
+ set bar $b
+ }
+ method dump1 {} {
+ lappend ::result <1>
+ foreach v [lsort [info vars *]] {
+ lappend ::result $v=[set $v]
+ }
+ lappend ::result [info locals] [info locals *]
+ }
+ method dump2 {} {
+ lappend ::result <2>
+ foreach v [lsort [info vars *]] {
+ lappend ::result $v=[set $v]
+ }
+ lappend ::result | foo=$foo [info locals] [info locals *]
+ }
+ }
+ Foo create stuff
+ stuff setvars what ever
+ stuff dump1
+ stuff dump2
+ return $result
+} -cleanup {
+ Foo destroy
+} -result {<1> bar=ever foo=what v v <2> bar=ever foo=what | foo=what v v}
+test oo-27.20 {variables declaration and [info vars]: Bug 2712377} -setup {
+ oo::class create Foo
+ set result {}
+} -body {
+ # This is really a test of problems to do with Tcl's introspection when a
+ # variable resolver is present...
+ oo::define Foo {
+ variable foo bar
+ method setvars {f b} {
+ set foo $f
+ set bar $b
+ }
+ method dump1 {} {
+ lappend ::result <1>
+ foreach v [lsort [info vars *o]] {
+ lappend ::result $v=[set $v]
+ }
+ lappend ::result [info locals] [info locals *]
+ }
+ method dump2 {} {
+ lappend ::result <2>
+ foreach v [lsort [info vars *o]] {
+ lappend ::result $v=[set $v]
+ }
+ lappend ::result | foo=$foo [info locals] [info locals *]
+ }
+ }
+ Foo create stuff
+ stuff setvars what ever
+ stuff dump1
+ stuff dump2
+ return $result
+} -cleanup {
+ Foo destroy
+} -result {<1> foo=what v v <2> foo=what | foo=what v v}
+test oo-27.21 {variables declaration uniqueifies: Bug 3396896} -setup {
+ oo::class create Foo
+} -body {
+ oo::define Foo variable v v v t t v t
+ info class variable Foo
+} -cleanup {
+ Foo destroy
+} -result {v t}
+test oo-27.22 {variables declaration uniqueifies: Bug 3396896} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo variable v v v t t v t
+ info object variable foo
+} -cleanup {
+ foo destroy
+} -result {v t}
+
+# A feature that's not supported because the mechanism may change without
+# warning, but is supposed to work...
+test oo-28.1 {scripted extensions to oo::define} -setup {
+ interp create foo
+ foo eval {oo::class create cls {export eval}}
+} -cleanup {
+ interp delete foo
+} -body {
+ foo eval {
+ proc oo::define::privateMethod {name arguments body} {
+ uplevel 1 [list method $name $arguments $body]
+ uplevel 1 [list unexport $name]
+ }
+ oo::define cls privateMethod m {x y} {return $x,$y}
+ cls create obj
+ list [catch {obj m 1 2}] [obj eval my m 3 4]
+ }
+} -result {1 3,4}
+
+test oo-29.1 {self class with object-defined methods} -setup {
+ oo::object create obj
+} -body {
+ oo::objdefine obj method demo {} {
+ self class
+ }
+ obj demo
+} -returnCodes error -cleanup {
+ obj destroy
+} -result {method not defined by a class}
+
+test oo-30.1 {Bug 2903011: deleting an object in a constructor} -setup {
+ oo::class create cls
+} -body {
+ oo::define cls {constructor {} {[self] destroy}}
+ cls new
+} -returnCodes error -cleanup {
+ cls destroy
+} -result {object deleted in constructor}
+test oo-30.2 {Bug 2903011: deleting an object in a constructor} -setup {
+ oo::class create cls
+} -body {
+ oo::define cls {constructor {} {my destroy}}
+ cls new
+} -returnCodes error -cleanup {
+ cls destroy
+} -result {object deleted in constructor}
+
+test oo-31.1 {Bug 3111059: when objects and coroutines entangle} -setup {
+ oo::class create cls
+} -constraints memory -body {
+ oo::define cls {
+ method justyield {} {
+ yield
+ }
+ constructor {} {
+ coroutine coro my justyield
+ }
+ }
+ list [leaktest {[cls new] destroy}] [info class instances cls]
+} -cleanup {
+ cls destroy
+} -result {0 {}}
+test oo-31.2 {Bug 3111059: when objects and coroutines entangle} -setup {
+ oo::class create cls
+} -constraints memory -body {
+ oo::define cls {
+ method justyield {} {
+ yield
+ }
+ constructor {} {
+ coroutine coro my justyield
+ }
+ destructor {
+ rename coro {}
+ }
+ }
+ list [leaktest {[cls new] destroy}] [info class instances cls]
+} -cleanup {
+ cls destroy
+} -result {0 {}}
+
+oo::class create SampleSlot {
+ superclass oo::Slot
+ constructor {} {
+ variable contents {a b c} ops {}
+ }
+ method contents {} {variable contents; return $contents}
+ method ops {} {variable ops; return $ops}
+ method Get {} {
+ variable contents
+ variable ops
+ lappend ops [info level] Get
+ return $contents
+ }
+ method Set {lst} {
+ variable contents $lst
+ variable ops
+ lappend ops [info level] Set $lst
+ return
+ }
+}
+
+test oo-32.1 {TIP 380: slots - class test} -setup {
+ SampleSlot create sampleSlot
+} -body {
+ list [info level] [sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+ rename sampleSlot {}
+} -result {0 {a b c} {}}
+test oo-32.2 {TIP 380: slots - class test} -setup {
+ SampleSlot create sampleSlot
+} -body {
+ list [info level] [sampleSlot -clear] \
+ [sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+ rename sampleSlot {}
+} -result {0 {} {} {1 Set {}}}
+test oo-32.3 {TIP 380: slots - class test} -setup {
+ SampleSlot create sampleSlot
+} -body {
+ list [info level] [sampleSlot -append g h i] \
+ [sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+ rename sampleSlot {}
+} -result {0 {} {a b c g h i} {1 Get 1 Set {a b c g h i}}}
+test oo-32.4 {TIP 380: slots - class test} -setup {
+ SampleSlot create sampleSlot
+} -body {
+ list [info level] [sampleSlot -set d e f] \
+ [sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+ rename sampleSlot {}
+} -result {0 {} {d e f} {1 Set {d e f}}}
+test oo-32.5 {TIP 380: slots - class test} -setup {
+ SampleSlot create sampleSlot
+} -body {
+ list [info level] [sampleSlot -set d e f] [sampleSlot -append g h i] \
+ [sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+ rename sampleSlot {}
+} -result {0 {} {} {d e f g h i} {1 Set {d e f} 1 Get 1 Set {d e f g h i}}}
+
+test oo-33.1 {TIP 380: slots - defaulting} -setup {
+ set s [SampleSlot new]
+} -body {
+ list [$s x y] [$s contents]
+} -cleanup {
+ rename $s {}
+} -result {{} {a b c x y}}
+test oo-33.2 {TIP 380: slots - defaulting} -setup {
+ set s [SampleSlot new]
+} -body {
+ list [$s destroy; $s unknown] [$s contents]
+} -cleanup {
+ rename $s {}
+} -result {{} {a b c destroy unknown}}
+test oo-33.3 {TIP 380: slots - defaulting} -setup {
+ set s [SampleSlot new]
+} -body {
+ oo::objdefine $s forward --default-operation my -set
+ list [$s destroy; $s unknown] [$s contents] [$s ops]
+} -cleanup {
+ rename $s {}
+} -result {{} unknown {1 Set destroy 1 Set unknown}}
+test oo-33.4 {TIP 380: slots - errors} -setup {
+ set s [SampleSlot new]
+} -body {
+ # Method names beginning with "-" are special to slots
+ $s -grill q
+} -returnCodes error -cleanup {
+ rename $s {}
+} -result {unknown method "-grill": must be -append, -clear, -set, contents or ops}
+
+SampleSlot destroy
+
+test oo-34.1 {TIP 380: slots - presence} -setup {
+ set obj [oo::object new]
+ set result {}
+} -body {
+ oo::define oo::object {
+ ::lappend ::result [::info object class filter]
+ ::lappend ::result [::info object class mixin]
+ ::lappend ::result [::info object class superclass]
+ ::lappend ::result [::info object class variable]
+ }
+ oo::objdefine $obj {
+ ::lappend ::result [::info object class filter]
+ ::lappend ::result [::info object class mixin]
+ ::lappend ::result [::info object class variable]
+ }
+ return $result
+} -cleanup {
+ $obj destroy
+} -result {::oo::Slot ::oo::Slot ::oo::Slot ::oo::Slot ::oo::Slot ::oo::Slot ::oo::Slot}
+test oo-34.2 {TIP 380: slots - presence} {
+ lsort [info class instances oo::Slot]
+} {::oo::define::filter ::oo::define::mixin ::oo::define::superclass ::oo::define::variable ::oo::objdefine::filter ::oo::objdefine::mixin ::oo::objdefine::variable}
+proc getMethods obj {
+ list [lsort [info object methods $obj -all]] \
+ [lsort [info object methods $obj -private]]
+}
+test oo-34.3 {TIP 380: slots - presence} {
+ getMethods oo::define::filter
+} {{-append -clear -set} {Get Set}}
+test oo-34.4 {TIP 380: slots - presence} {
+ getMethods oo::define::mixin
+} {{-append -clear -set} {--default-operation Get Set}}
+test oo-34.5 {TIP 380: slots - presence} {
+ getMethods oo::define::superclass
+} {{-append -clear -set} {--default-operation Get Set}}
+test oo-34.6 {TIP 380: slots - presence} {
+ getMethods oo::define::variable
+} {{-append -clear -set} {Get Set}}
+test oo-34.7 {TIP 380: slots - presence} {
+ getMethods oo::objdefine::filter
+} {{-append -clear -set} {Get Set}}
+test oo-34.8 {TIP 380: slots - presence} {
+ getMethods oo::objdefine::mixin
+} {{-append -clear -set} {--default-operation Get Set}}
+test oo-34.9 {TIP 380: slots - presence} {
+ getMethods oo::objdefine::variable
+} {{-append -clear -set} {Get Set}}
+
+cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/ooNext2.test b/library/msgcat/tests/ooNext2.test
new file mode 100644
index 0000000..eeade11
--- /dev/null
+++ b/library/msgcat/tests/ooNext2.test
@@ -0,0 +1,790 @@
+# This file contains a collection of tests for Tcl's built-in object system.
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 2006-2008 Donal K. Fellows
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: oo.test,v 1.59 2011/01/18 16:10:48 dkf Exp $
+
+package require -exact TclOO 0.6.3 ;# Must match value in configure.in
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint memory [llength [info commands memory]]
+if {[testConstraint memory]} {
+ proc getbytes {} {
+ set lines [split [memory info] \n]
+ return [lindex $lines 3 3]
+ }
+ proc leaktest {script {iterations 3}} {
+ set end [getbytes]
+ for {set i 0} {$i < $iterations} {incr i} {
+ uplevel 1 $script
+ set tmp $end
+ set end [getbytes]
+ }
+ return [expr {$end - $tmp}]
+ }
+}
+
+test oo-nextto-1.1 {basic nextto functionality} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x args {
+ lappend ::result ==A== $args
+ }
+ }
+ oo::class create B {
+ superclass A
+ method x args {
+ lappend ::result ==B== $args
+ nextto A B -> A {*}$args
+ }
+ }
+ oo::class create C {
+ superclass A
+ method x args {
+ lappend ::result ==C== $args
+ nextto A C -> A {*}$args
+ }
+ }
+ oo::class create D {
+ superclass B C
+ method x args {
+ lappend ::result ==D== $args
+ next foo
+ nextto C bar
+ }
+ }
+ set ::result {}
+ [D new] x
+ return $::result
+} -cleanup {
+ root destroy
+} -result {==D== {} ==B== foo ==A== {B -> A foo} ==C== bar ==A== {C -> A bar}}
+test oo-nextto-1.2 {basic nextto functionality} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x args {
+ lappend ::result ==A== $args
+ }
+ }
+ oo::class create B {
+ superclass A
+ method x args {
+ lappend ::result ==B== $args
+ nextto A B -> A {*}$args
+ }
+ }
+ oo::class create C {
+ superclass A
+ method x args {
+ lappend ::result ==C== $args
+ nextto A C -> A {*}$args
+ }
+ }
+ oo::class create D {
+ superclass B C
+ method x args {
+ lappend ::result ==D== $args
+ nextto B foo {*}$args
+ nextto C bar {*}$args
+ }
+ }
+ set ::result {}
+ [D new] x 123
+ return $::result
+} -cleanup {
+ root destroy
+} -result {==D== 123 ==B== {foo 123} ==A== {B -> A foo 123} ==C== {bar 123} ==A== {C -> A bar 123}}
+test oo-nextto-1.3 {basic nextto functionality: constructors} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ variable result
+ constructor {a c} {
+ lappend result ==A== a=$a,c=$c
+ }
+ }
+ oo::class create B {
+ superclass root
+ variable result
+ constructor {b} {
+ lappend result ==B== b=$b
+ }
+ }
+ oo::class create C {
+ superclass A B
+ variable result
+ constructor {p q r} {
+ lappend result ==C== p=$p,q=$q,r=$r
+ # Route arguments to superclasses, in non-trival pattern
+ nextto B $q
+ nextto A $p $r
+ }
+ method result {} {return $result}
+ }
+ [C new x y z] result
+} -cleanup {
+ root destroy
+} -result {==C== p=x,q=y,r=z ==B== b=y ==A== a=x,c=z}
+test oo-nextto-1.4 {basic nextto functionality: destructors} -setup {
+ oo::class create root {destructor return}
+} -body {
+ oo::class create A {
+ superclass root
+ destructor {
+ lappend ::result ==A==
+ next
+ }
+ }
+ oo::class create B {
+ superclass root
+ destructor {
+ lappend ::result ==B==
+ next
+ }
+ }
+ oo::class create C {
+ superclass A B
+ destructor {
+ lappend ::result ==C==
+ lappend ::result |
+ nextto B
+ lappend ::result |
+ nextto A
+ lappend ::result |
+ next
+ }
+ }
+ set ::result ""
+ [C new] destroy
+ return $::result
+} -cleanup {
+ root destroy
+} -result {==C== | ==B== | ==A== ==B== | ==A== ==B==}
+
+test oo-nextto-2.1 {errors in nextto} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x y {error $y}
+ }
+ oo::class create B {
+ superclass A
+ method x y {nextto A $y}
+ }
+ [B new] x boom
+} -cleanup {
+ root destroy
+} -result boom -returnCodes error
+test oo-nextto-2.2 {errors in nextto} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x y {error $y}
+ }
+ oo::class create B {
+ superclass root
+ method x y {nextto A $y}
+ }
+ [B new] x boom
+} -returnCodes error -cleanup {
+ root destroy
+} -result {method has no non-filter implementation by "A"}
+test oo-nextto-2.3 {errors in nextto} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x y {nextto $y}
+ }
+ oo::class create B {
+ superclass A
+ method x y {nextto A $y}
+ }
+ [B new] x B
+} -returnCodes error -cleanup {
+ root destroy
+} -result {method implementation by "B" not reachable from here}
+test oo-nextto-2.4 {errors in nextto} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x y {nextto $y}
+ }
+ oo::class create B {
+ superclass A
+ method x y {nextto}
+ }
+ [B new] x B
+} -returnCodes error -cleanup {
+ root destroy
+} -result {wrong # args: should be "nextto class ?arg...?"}
+test oo-nextto-2.5 {errors in nextto} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x y {nextto $y}
+ }
+ oo::class create B {
+ superclass A
+ method x y {nextto $y $y $y}
+ }
+ [B new] x A
+} -cleanup {
+ root destroy
+} -result {wrong # args: should be "nextto A y"} -returnCodes error
+test oo-nextto-2.6 {errors in nextto} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x y {nextto $y}
+ }
+ oo::class create B {
+ superclass A
+ method x y {nextto $y $y $y}
+ }
+ [B new] x [root create notAClass]
+} -cleanup {
+ root destroy
+} -result {"::notAClass" is not a class} -returnCodes error
+test oo-nextto-2.7 {errors in nextto} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x y {nextto $y}
+ }
+ oo::class create B {
+ superclass A
+ filter Y
+ method Y args {next {*}$args}
+ }
+ oo::class create C {
+ superclass B
+ method x y {nextto $y $y $y}
+ }
+ [C new] x B
+} -returnCodes error -cleanup {
+ root destroy
+} -result {method has no non-filter implementation by "B"}
+
+test oo-call-1.1 {object call introspection} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ A create y
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{method x ::A method}}
+test oo-call-1.2 {object call introspection} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ }
+ B create y
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{method x ::B method} {method x ::A method}}
+test oo-call-1.3 {object call introspection} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ A create y
+ oo::objdefine y method x {} {}
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{method x object method} {method x ::A method}}
+test oo-call-1.4 {object object call introspection - unknown} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ A create y
+ info object call y z
+} -cleanup {
+ root destroy
+} -result {{unknown unknown ::oo::object {core method: "unknown"}}}
+test oo-call-1.5 {object call introspection - filters} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ method y {} {}
+ filter y
+ }
+ A create y
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{filter y ::A method} {method x ::A method}}
+test oo-call-1.6 {object call introspection - filters} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ method y {} {}
+ filter y
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ }
+ B create y
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{filter y ::A method} {method x ::B method} {method x ::A method}}
+test oo-call-1.7 {object call introspection - filters} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ method y {} {}
+ filter y
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ method y {} {}
+ }
+ B create y
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{filter y ::B method} {filter y ::A method} {method x ::B method} {method x ::A method}}
+test oo-call-1.8 {object call introspection - filters} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ method y {} {}
+ filter y
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ method y {} {}
+ method z {} {}
+ filter z
+ }
+ B create y
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{filter z ::B method} {filter y ::B method} {filter y ::A method} {method x ::B method} {method x ::A method}}
+test oo-call-1.9 {object call introspection - filters} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ method y {} {}
+ filter y
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ method y {} {}
+ method z {} {}
+ filter z
+ }
+ B create y
+ info object call y y
+} -cleanup {
+ root destroy
+} -result {{filter z ::B method} {filter y ::B method} {filter y ::A method} {method y ::B method} {method y ::A method}}
+test oo-call-1.10 {object call introspection - filters + unknown} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method y {} {}
+ filter y
+ }
+ oo::class create ::B {
+ superclass A
+ method y {} {}
+ method unknown {} {}
+ }
+ B create y
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{filter y ::B method} {filter y ::A method} {unknown unknown ::B method} {unknown unknown ::oo::object {core method: "unknown"}}}
+test oo-call-1.11 {object call introspection - filters + unknown} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method y {} {}
+ filter y
+ }
+ A create y
+ oo::objdefine y method unknown {} {}
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{filter y ::A method} {unknown unknown object method} {unknown unknown ::oo::object {core method: "unknown"}}}
+test oo-call-1.12 {object call introspection - filters + unknown} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method y {} {}
+ }
+ A create y
+ oo::objdefine y {
+ method unknown {} {}
+ filter y
+ }
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{filter y ::A method} {unknown unknown object method} {unknown unknown ::oo::object {core method: "unknown"}}}
+test oo-call-1.13 {object call introspection - filters + unknown} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method y {} {}
+ }
+ A create y
+ oo::objdefine y {
+ method unknown {} {}
+ method x {} {}
+ filter y
+ }
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{filter y ::A method} {method x object method}}
+test oo-call-1.14 {object call introspection - errors} -body {
+ info object call
+} -returnCodes error -result {wrong # args: should be "info object call objName methodName"}
+test oo-call-1.15 {object call introspection - errors} -body {
+ info object call a
+} -returnCodes error -result {wrong # args: should be "info object call objName methodName"}
+test oo-call-1.16 {object call introspection - errors} -body {
+ info object call a b c
+} -returnCodes error -result {wrong # args: should be "info object call objName methodName"}
+test oo-call-1.17 {object call introspection - errors} -body {
+ info object call notanobject x
+} -returnCodes error -result {notanobject does not refer to an object}
+test oo-call-1.18 {object call introspection - memory leaks} -body {
+ leaktest {
+ info object call oo::object destroy
+ }
+} -constraints memory -result 0
+test oo-call-1.19 {object call introspection - memory leaks} -setup {
+ oo::class create leaktester { method foo {} {dummy} }
+} -body {
+ leaktest {
+ set lt [leaktester new]
+ oo::objdefine $lt method foobar {} {dummy}
+ list [info object call $lt destroy] \
+ [info object call $lt foo] \
+ [info object call $lt bar] \
+ [info object call $lt foobar] \
+ [$lt destroy]
+ }
+} -cleanup {
+ leaktester destroy
+} -constraints memory -result 0
+
+test oo-call-2.1 {class call introspection} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ info class call A x
+} -cleanup {
+ root destroy
+} -result {{method x ::A method}}
+test oo-call-2.2 {class call introspection} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ }
+ list [info class call A x] [info class call B x]
+} -cleanup {
+ root destroy
+} -result {{{method x ::A method}} {{method x ::B method} {method x ::A method}}}
+test oo-call-2.3 {class call introspection} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ }
+ oo::class create ::C {
+ superclass A
+ method x {} {}
+ }
+ oo::class create ::D {
+ superclass C B
+ method x {} {}
+ }
+ info class call D x
+} -cleanup {
+ root destroy
+} -result {{method x ::D method} {method x ::C method} {method x ::B method} {method x ::A method}}
+test oo-call-2.4 {class call introspection - mixin} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ }
+ oo::class create ::C {
+ superclass A
+ method x {} {}
+ }
+ oo::class create ::D {
+ superclass C
+ mixin B
+ method x {} {}
+ }
+ info class call D x
+} -cleanup {
+ root destroy
+} -result {{method x ::B method} {method x ::D method} {method x ::C method} {method x ::A method}}
+test oo-call-2.5 {class call introspection - mixin + filter} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ method y {} {}
+ filter y
+ }
+ oo::class create ::C {
+ superclass A
+ method x {} {}
+ method y {} {}
+ }
+ oo::class create ::D {
+ superclass C
+ mixin B
+ method x {} {}
+ }
+ info class call D x
+} -cleanup {
+ root destroy
+} -result {{filter y ::B method} {filter y ::C method} {method x ::B method} {method x ::D method} {method x ::C method} {method x ::A method}}
+test oo-call-2.6 {class call introspection - mixin + filter + unknown} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ method unknown {} {}
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ method y {} {}
+ filter y
+ }
+ oo::class create ::C {
+ superclass A
+ method x {} {}
+ method y {} {}
+ }
+ oo::class create ::D {
+ superclass C
+ mixin B
+ method x {} {}
+ method unknown {} {}
+ }
+ info class call D z
+} -cleanup {
+ root destroy
+} -result {{filter y ::B method} {filter y ::C method} {unknown unknown ::D method} {unknown unknown ::A method} {unknown unknown ::oo::object {core method: "unknown"}}}
+test oo-call-2.7 {class call introspection - mixin + filter + unknown} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ filter x
+ }
+ info class call B x
+} -cleanup {
+ root destroy
+} -result {{filter x ::B method} {filter x ::A method} {method x ::B method} {method x ::A method}}
+test oo-call-2.8 {class call introspection - errors} -body {
+ info class call
+} -returnCodes error -result {wrong # args: should be "info class call className methodName"}
+test oo-call-2.9 {class call introspection - errors} -body {
+ info class call a
+} -returnCodes error -result {wrong # args: should be "info class call className methodName"}
+test oo-call-2.10 {class call introspection - errors} -body {
+ info class call a b c
+} -returnCodes error -result {wrong # args: should be "info class call className methodName"}
+test oo-call-2.11 {class call introspection - errors} -body {
+ info class call notaclass x
+} -returnCodes error -result {notaclass does not refer to an object}
+test oo-call-2.12 {class call introspection - errors} -setup {
+ oo::class create root
+} -body {
+ root create notaclass
+ info class call notaclass x
+} -returnCodes error -cleanup {
+ root destroy
+} -result {"notaclass" is not a class}
+test oo-call-2.13 {class call introspection - memory leaks} -body {
+ leaktest {
+ info class call oo::class destroy
+ }
+} -constraints memory -result 0
+test oo-call-2.14 {class call introspection - memory leaks} -body {
+ leaktest {
+ oo::class create leaktester { method foo {} {dummy} }
+ [leaktester new] destroy
+ list [info class call leaktester destroy] \
+ [info class call leaktester foo] \
+ [info class call leaktester bar] \
+ [leaktester destroy]
+ }
+} -constraints memory -result 0
+
+test oo-call-3.1 {current call introspection} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x {} {lappend ::result [self call]}
+ }
+ oo::class create B {
+ superclass A
+ method x {} {lappend ::result [self call];next}
+ }
+ B create y
+ oo::objdefine y method x {} {lappend ::result [self call];next}
+ set ::result {}
+ y x
+} -cleanup {
+ root destroy
+} -result {{{{method x object method} {method x ::B method} {method x ::A method}} 0} {{{method x object method} {method x ::B method} {method x ::A method}} 1} {{{method x object method} {method x ::B method} {method x ::A method}} 2}}
+test oo-call-3.2 {current call introspection} -setup {
+ oo::class create root
+} -constraints memory -body {
+ oo::class create A {
+ superclass root
+ method x {} {self call}
+ }
+ oo::class create B {
+ superclass A
+ method x {} {self call;next}
+ }
+ B create y
+ oo::objdefine y method x {} {self call;next}
+ leaktest {
+ y x
+ }
+} -cleanup {
+ root destroy
+} -result 0
+test oo-call-3.3 {current call introspection: in constructors} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ constructor {} {lappend ::result [self call]}
+ }
+ oo::class create B {
+ superclass A
+ constructor {} {lappend ::result [self call]; next}
+ }
+ set ::result {}
+ [B new] destroy
+ return $::result
+} -cleanup {
+ root destroy
+} -result {{{{method <constructor> ::B method} {method <constructor> ::A method}} 0} {{{method <constructor> ::B method} {method <constructor> ::A method}} 1}}
+test oo-call-3.4 {current call introspection: in destructors} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ destructor {lappend ::result [self call]}
+ }
+ oo::class create B {
+ superclass A
+ destructor {lappend ::result [self call]; next}
+ }
+ set ::result {}
+ [B new] destroy
+ return $::result
+} -cleanup {
+ root destroy
+} -result {{{{method <destructor> ::B method} {method <destructor> ::A method}} 0} {{{method <destructor> ::B method} {method <destructor> ::A method}} 1}}
+
+cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/opt.test b/library/msgcat/tests/opt.test
new file mode 100644
index 0000000..2732d40
--- /dev/null
+++ b/library/msgcat/tests/opt.test
@@ -0,0 +1,245 @@
+# Package covered: opt1.0/optparse.tcl
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# the package we are going to test
+package require opt 0.4.6
+
+# we are using implementation specifics to test the package
+
+
+#### functions tests #####
+
+set n $::tcl::OptDescN
+
+test opt-1.1 {OptKeyRegister / check that auto allocation is skipping existing keys} {
+ list [::tcl::OptKeyRegister {} $n] [::tcl::OptKeyRegister {} [expr $n+1]] [::tcl::OptKeyRegister {}]
+} "$n [expr $n+1] [expr $n+2]"
+
+test opt-2.1 {OptKeyDelete} {
+ list [::tcl::OptKeyRegister {} testkey] \
+ [info exists ::tcl::OptDesc(testkey)] \
+ [::tcl::OptKeyDelete testkey] \
+ [info exists ::tcl::OptDesc(testkey)]
+} {testkey 1 {} 0}
+
+test opt-3.1 {OptParse / temp key is removed} {
+ set n $::tcl::OptDescN
+ set prev [array names ::tcl::OptDesc]
+ ::tcl::OptKeyRegister {} $n
+ list [info exists ::tcl::OptDesc($n)]\
+ [::tcl::OptKeyDelete $n]\
+ [::tcl::OptParse {{-foo}} {}]\
+ [info exists ::tcl::OptDesc($n)]\
+ [expr {"[lsort $prev]"=="[lsort [array names ::tcl::OptDesc]]"}]
+} {1 {} {} 0 1}
+test opt-3.2 {OptParse / temp key is removed even on errors} {
+ set n $::tcl::OptDescN
+ catch {::tcl::OptKeyDelete $n}
+ list [catch {::tcl::OptParse {{-foo}} {-blah}}] \
+ [info exists ::tcl::OptDesc($n)]
+} {1 0}
+
+test opt-4.1 {OptProc} {
+ ::tcl::OptProc optTest {} {}
+ optTest
+ ::tcl::OptKeyDelete optTest
+} {}
+
+test opt-5.1 {OptProcArgGiven} {
+ ::tcl::OptProc optTest {{-foo}} {
+ if {[::tcl::OptProcArgGiven "-foo"]} {
+ return 1
+ } else {
+ return 0
+ }
+ }
+ list [optTest] [optTest -f] [optTest -F] [optTest -fOO]
+} {0 1 1 1}
+
+test opt-6.1 {OptKeyParse} {
+ ::tcl::OptKeyRegister {} test
+ list [catch {::tcl::OptKeyParse test {-help}} msg] $msg
+} {1 {Usage information:
+ Var/FlagName Type Value Help
+ ------------ ---- ----- ----
+ (-help gives this help)}}
+
+test opt-7.1 {OptCheckType} {
+ list \
+ [::tcl::OptCheckType 23 int] \
+ [::tcl::OptCheckType 23 float] \
+ [::tcl::OptCheckType true boolean] \
+ [::tcl::OptCheckType "-blah" any] \
+ [::tcl::OptCheckType {a b c} list] \
+ [::tcl::OptCheckType maYbe choice {yes maYbe no}] \
+ [catch {::tcl::OptCheckType "-blah" string}] \
+ [catch {::tcl::OptCheckType 6 boolean}] \
+ [catch {::tcl::OptCheckType x float}] \
+ [catch {::tcl::OptCheckType "a \{ c" list}] \
+ [catch {::tcl::OptCheckType 2.3 int}] \
+ [catch {::tcl::OptCheckType foo choice {x y Foo z}}]
+} {23 23.0 1 -blah {a b c} maYbe 1 1 1 1 1 1}
+
+test opt-8.1 {List utilities} {
+ ::tcl::Lempty {}
+} 1
+test opt-8.2 {List utilities} {
+ ::tcl::Lempty {a b c}
+} 0
+test opt-8.3 {List utilities} {
+ ::tcl::Lget {a {b c d} e} {1 2}
+} d
+test opt-8.4 {List utilities} {
+ set l {a {b c d e} f}
+ ::tcl::Lvarset l {1 2} D
+ set l
+} {a {b c D e} f}
+test opt-8.5 {List utilities} {
+ set l {a b c}
+ ::tcl::Lvarset1 l 6 X
+ set l
+} {a b c {} {} {} X}
+test opt-8.6 {List utilities} {
+ set l {a {b c 7 e} f}
+ ::tcl::Lvarincr l {1 2}
+ set l
+} {a {b c 8 e} f}
+test opt-8.7 {List utilities} {
+ set l {a {b c 7 e} f}
+ ::tcl::Lvarincr l {1 2} -9
+ set l
+} {a {b c -2 e} f}
+# 8.8 and 8.9 missing?
+test opt-8.10 {List utilities} {
+ set l {a {b c 7 e} f}
+ ::tcl::Lvarpop l
+ set l
+} {{b c 7 e} f}
+test opt-8.11 {List utilities} {
+ catch {unset x}
+ set l {a {b c 7 e} f}
+ list [::tcl::Lassign $l u v w x] \
+ $u $v $w [info exists x]
+} {3 a {b c 7 e} f 0}
+
+test opt-9.1 {Misc utilities} {
+ catch {unset v}
+ ::tcl::SetMax v 3
+ ::tcl::SetMax v 7
+ ::tcl::SetMax v 6
+ set v
+} 7
+test opt-9.2 {Misc utilities} {
+ catch {unset v}
+ ::tcl::SetMin v 3
+ ::tcl::SetMin v -7
+ ::tcl::SetMin v 1
+ set v
+} -7
+
+#### behaviour tests #####
+
+test opt-10.1 {ambigous flags} {
+ ::tcl::OptProc optTest {{-fla} {-other} {-flag2xyz} {-flag3xyz}} {}
+ catch {optTest -fL} msg
+ set msg
+} {ambigous option "-fL", choose from:
+ -fla boolflag (false)
+ -flag2xyz boolflag (false)
+ -flag3xyz boolflag (false)}
+test opt-10.2 {non ambigous flags} {
+ ::tcl::OptProc optTest {{-flag1xyz} {-other} {-flag2xyz} {-flag3xyz}} {
+ return $flag2xyz
+ }
+ optTest -fLaG2
+} 1
+test opt-10.3 {non ambigous flags because of exact match} {
+ ::tcl::OptProc optTest {{-flag1x} {-other} {-flag1} {-flag1xy}} {
+ return $flag1
+ }
+ optTest -flAg1
+} 1
+test opt-10.4 {ambigous flags, not exact match} {
+ ::tcl::OptProc optTest {{-flag1xy} {-other} {-flag1} {-flag1xyz}} {
+ return $flag1
+ }
+ catch {optTest -fLag1X} msg
+ set msg
+} {ambigous option "-fLag1X", choose from:
+ -flag1xy boolflag (false)
+ -flag1xyz boolflag (false)}
+
+# medium size overall test example: (defined once)
+::tcl::OptProc optTest {
+ {cmd -choice {print save delete} "sub command to choose"}
+ {-allowBoing -boolean true}
+ {arg2 -string "this is help"}
+ {?arg3? 7 "optional number"}
+ {-moreflags}
+} {
+ list $cmd $allowBoing $arg2 $arg3 $moreflags
+}
+
+test opt-10.5 {medium size overall test} {
+ list [catch {optTest} msg] $msg
+} {1 {no value given for parameter "cmd" (use -help for full usage) :
+ cmd choice (print save delete) sub command to choose}}
+test opt-10.6 {medium size overall test} {
+ list [catch {optTest -help} msg] $msg
+} {1 {Usage information:
+ Var/FlagName Type Value Help
+ ------------ ---- ----- ----
+ (-help gives this help)
+ cmd choice (print save delete) sub command to choose
+ -allowBoing boolean (true)
+ arg2 string () this is help
+ ?arg3? int (7) optional number
+ -moreflags boolflag (false)}}
+test opt-10.7 {medium size overall test} {
+ optTest save tst
+} {save 1 tst 7 0}
+test opt-10.8 {medium size overall test} {
+ optTest save -allowBoing false -- 8
+} {save 0 8 7 0}
+test opt-10.9 {medium size overall test} {
+ optTest save tst -m --
+} {save 1 tst 7 1}
+test opt-10.10 {medium size overall test} {
+ list [catch {optTest save tst foo} msg] [lindex [split $msg "\n"] 0]
+} {1 {too many arguments (unexpected argument(s): foo), usage:}}
+
+test opt-11.1 {too many args test 2} {
+ set key [::tcl::OptKeyRegister {-foo}]
+ list [catch {::tcl::OptKeyParse $key {-foo blah}} msg] $msg\
+ [::tcl::OptKeyDelete $key]
+} {1 {too many arguments (unexpected argument(s): blah), usage:
+ Var/FlagName Type Value Help
+ ------------ ---- ----- ----
+ (-help gives this help)
+ -foo boolflag (false)} {}}
+test opt-11.2 {default value for args} {
+ set args {}
+ set key [::tcl::OptKeyRegister {{args -list {a b c} "args..."}}]
+ ::tcl::OptKeyParse $key {}
+ ::tcl::OptKeyDelete $key
+ set args
+} {a b c}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/package.test b/library/msgcat/tests/package.test
new file mode 100644
index 0000000..da778f1
--- /dev/null
+++ b/library/msgcat/tests/package.test
@@ -0,0 +1,1279 @@
+# This file contains tests for the package and ::pkg::* commands.
+# Note that the tests are limited to Tcl scripts only, there are no shared
+# libraries against which to test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2011 Donal K. Fellows
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2.3.3
+ namespace import -force ::tcltest::*
+}
+
+# Do all this in a slave interp to avoid garbaging the package list
+set i [interp create]
+tcltest::loadIntoSlaveInterpreter $i {*}$argv
+interp eval $i {
+namespace import -force ::tcltest::*
+package forget {*}[package names]
+set oldPkgUnknown [package unknown]
+package unknown {}
+set oldPath $auto_path
+set auto_path ""
+
+test package-1.1 {pkg::create gives error on insufficient args} -body {
+ ::pkg::create
+} -returnCodes error -match glob -result {wrong # args: should be "*"}
+test package-1.2 {pkg::create gives error on bad args} -body {
+ ::pkg::create -foo bar -bar baz -baz boo
+} -returnCodes error -match glob -result {unknown option "bar": *}
+test package-1.3 {pkg::create gives error on no value given} -body {
+ ::pkg::create -name foo -version 1.0 -source test.tcl -load
+} -returnCodes error -match glob -result {value for "-load" missing: *}
+test package-1.4 {pkg::create gives error on no name given} -body {
+ ::pkg::create -version 1.0 -source test.tcl -load foo.so
+} -returnCodes error -match glob -result {value for "-name" missing: *}
+test package-1.5 {pkg::create gives error on no version given} -body {
+ ::pkg::create -name foo -source test.tcl -load foo.so
+} -returnCodes error -match glob -result {value for "-version" missing: *}
+test package-1.6 {pkg::create gives error on no source or load options} -body {
+ ::pkg::create -name foo -version 1.0 -version 2.0
+} -returnCodes error -result {at least one of -load and -source must be given}
+test package-1.7 {pkg::create gives correct output for 1 direct source} {
+ ::pkg::create -name foo -version 1.0 -source test.tcl
+} {package ifneeded foo 1.0 [list source [file join $dir test.tcl]]}
+test package-1.8 {pkg::create gives correct output for 2 direct sources} {
+ ::pkg::create -name foo -version 1.0 -source test.tcl -source test2.tcl
+} {package ifneeded foo 1.0 [list source [file join $dir test.tcl]]\n[list source [file join $dir test2.tcl]]}
+test package-1.9 {pkg::create gives correct output for 1 direct load} {
+ ::pkg::create -name foo -version 1.0 -load test.so
+} {package ifneeded foo 1.0 [list load [file join $dir test.so]]}
+test package-1.10 {pkg::create gives correct output for 2 direct loads} {
+ ::pkg::create -name foo -version 1.0 -load test.so -load test2.so
+} {package ifneeded foo 1.0 [list load [file join $dir test.so]]\n[list load [file join $dir test2.so]]}
+test package-1.11 {pkg::create gives correct output for 1 lazy source} {
+ ::pkg::create -name foo -version 1.0 -source {test.tcl {foo bar}}
+} {package ifneeded foo 1.0 [list tclPkgSetup $dir foo 1.0 {{test.tcl source {foo bar}}}]}
+test package-1.12 {pkg::create gives correct output for 2 lazy sources} {
+ ::pkg::create -name foo -version 1.0 -source {test.tcl {foo bar}} \
+ -source {test2.tcl {baz boo}}
+} {package ifneeded foo 1.0 [list tclPkgSetup $dir foo 1.0 {{test.tcl source {foo bar}} {test2.tcl source {baz boo}}}]}
+test package-1.13 {pkg::create gives correct output for 1 lazy load} {
+ ::pkg::create -name foo -version 1.0 -load {test.so {foo bar}}
+} {package ifneeded foo 1.0 [list tclPkgSetup $dir foo 1.0 {{test.so load {foo bar}}}]}
+test package-1.14 {pkg::create gives correct output for 2 lazy loads} {
+ ::pkg::create -name foo -version 1.0 -load {test.so {foo bar}} \
+ -load {test2.so {baz boo}}
+} {package ifneeded foo 1.0 [list tclPkgSetup $dir foo 1.0 {{test.so load {foo bar}} {test2.so load {baz boo}}}]}
+test package-1.15 {pkg::create gives correct output for 1 each, direct} {
+ ::pkg::create -name foo -version 1.0 -source test.tcl -load test2.so
+} {package ifneeded foo 1.0 [list load [file join $dir test2.so]]\n[list source [file join $dir test.tcl]]}
+test package-1.16 {pkg::create gives correct output for 1 direct, 1 lazy} {
+ ::pkg::create -name foo -version 1.0 -source test.tcl \
+ -source {test2.tcl {foo bar}}
+} {package ifneeded foo 1.0 [list source [file join $dir test.tcl]]\n[list tclPkgSetup $dir foo 1.0 {{test2.tcl source {foo bar}}}]}
+
+test package-2.1 {Tcl_PkgProvide procedure} {
+ package forget t
+ package provide t 2.3
+} {}
+test package-2.2 {Tcl_PkgProvide procedure} -returnCodes error -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package provide t 2.2
+} -result {conflicting versions provided for package "t": 2.3, then 2.2}
+test package-2.3 {Tcl_PkgProvide procedure} -returnCodes error -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package provide t 2.4
+} -result {conflicting versions provided for package "t": 2.3, then 2.4}
+test package-2.4 {Tcl_PkgProvide procedure} -returnCodes error -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package provide t 3.3
+} -result {conflicting versions provided for package "t": 2.3, then 3.3}
+test package-2.5 {Tcl_PkgProvide procedure} -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package provide t 2.3
+} -result {}
+test package-2.6 {Tcl_PkgProvide procedure} {
+ package forget t
+ package provide t 2.3a1
+} {}
+
+set n 0
+foreach v {
+ 2.3k1 2a3a2 2ab3 2.a4 2.b4 2b.4 2a.4 2ba4 2a4b1
+ 2b4a1 2b3b2
+} {
+ test package-2.7.$n {Tcl_PkgProvide procedure} -setup {
+ package forget t
+ } -returnCodes error -body "
+ package provide t $v
+ " -result "expected version number but got \"$v\""
+ incr n
+}
+
+test package-3.1 {Tcl_PkgRequire procedure, picking best version} -setup {
+ package forget t
+ set x xxx
+} -body {
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ package require t
+ return $x
+} -result {3.4}
+test package-3.2 {Tcl_PkgRequire procedure, picking best version} -setup {
+ package forget t
+ set x xxx
+} -body {
+ foreach i {1.4 3.4 2.3 2.4 2.2 3.5 3.2} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ package require t
+ return $x
+} -result {3.5}
+test package-3.3 {Tcl_PkgRequire procedure, picking best version} -setup {
+ package forget t
+ set x xxx
+} -body {
+ foreach i {3.5 2.1 2.3} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ package require t 2.2
+ return $x
+} -result {2.3}
+test package-3.4 {Tcl_PkgRequire procedure, picking best version} -setup {
+ package forget t
+ set x xxx
+} -body {
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ package require -exact t 2.3
+ return $x
+} -result {2.3}
+test package-3.5 {Tcl_PkgRequire procedure, picking best version} -setup {
+ package forget t
+ set x xxx
+} -body {
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ package require t 2.1
+ return $x
+} -result {2.4}
+test package-3.6 {Tcl_PkgRequire procedure, can't find suitable version} -setup {
+ package forget t
+} -returnCodes error -body {
+ package unknown {}
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i"
+ }
+ package require t 2.5
+} -result {can't find package t 2.5}
+test package-3.7 {Tcl_PkgRequire procedure, can't find suitable version} -setup {
+ package forget t
+} -returnCodes error -body {
+ package unknown {}
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i"
+ }
+ package require t 4.1
+} -result {can't find package t 4.1}
+test package-3.8 {Tcl_PkgRequire procedure, can't find suitable version} -setup {
+ package forget t
+} -returnCodes error -body {
+ package unknown {}
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i"
+ }
+ package require -exact t 1.3
+} -result {can't find package t exactly 1.3}
+test package-3.9 {Tcl_PkgRequire procedure, can't find suitable version} -setup {
+ package forget t
+} -returnCodes error -body {
+ package unknown {}
+ package require t
+} -result {can't find package t}
+test package-3.10 {Tcl_PkgRequire procedure, error in ifneeded script} -setup {
+ package forget t
+} -body {
+ package ifneeded t 2.1 {package provide t 2.1; error "ifneeded test"}
+ list [catch {package require t 2.1} msg] $msg $::errorInfo
+} -match glob -result {1 {ifneeded test} {ifneeded test
+ while executing
+"error "ifneeded test""
+ ("package ifneeded*" script)
+ invoked from within
+"package require t 2.1"}}
+test package-3.11 {Tcl_PkgRequire procedure, ifneeded script doesn't provide package} -setup {
+ package forget t
+ set x xxx
+} -body {
+ package ifneeded t 2.1 "set x invoked"
+ list [catch {package require t 2.1} msg] $msg $x
+} -match glob -result {1 * invoked}
+test package-3.12 {Tcl_PkgRequire procedure, self-deleting script} -setup {
+ package forget t
+ set x xxx
+} -body {
+ package ifneeded t 1.2 "package forget t; set x 1.2; package provide t 1.2"
+ package require t 1.2
+ return $x
+} -result {1.2}
+test package-3.13 {Tcl_PkgRequire procedure, "package unknown" support} -setup {
+ package forget t
+ set x xxx
+} -body {
+ proc pkgUnknown args {
+ # args = name requirement
+ # requirement = v-v (for exact version)
+ global x
+ set x $args
+ package provide [lindex $args 0] [lindex [split [lindex $args 1] -] 0]
+ }
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i"
+ }
+ package unknown pkgUnknown
+ package require -exact t 1.5
+ return $x
+} -cleanup {
+ package unknown {}
+} -result {t 1.5-1.5}
+test package-3.14 {Tcl_PkgRequire procedure, "package unknown" support} -setup {
+ package forget t
+ set x xxx
+} -body {
+ proc pkgUnknown args {
+ package ifneeded t 1.2 "set x loaded; package provide t 1.2"
+ }
+ package unknown pkgUnknown
+ list [package require t] $x
+} -cleanup {
+ package unknown {}
+} -result {1.2 loaded}
+test package-3.15 {Tcl_PkgRequire procedure, "package unknown" support} -setup {
+ package forget {a b}
+ package unknown pkgUnknown
+ set x xxx
+} -body {
+ proc pkgUnknown args {
+ global x
+ set x $args
+ package provide [lindex $args 0] 2.0
+ }
+ package require {a b}
+ return $x
+} -cleanup {
+ package unknown {}
+} -result {{a b} 0-}
+test package-3.16 {Tcl_PkgRequire procedure, "package unknown" error} -setup {
+ package forget t
+} -body {
+ proc pkgUnknown args {
+ error "testing package unknown"
+ }
+ package unknown pkgUnknown
+ list [catch {package require t} msg] $msg $::errorInfo
+} -cleanup {
+ package unknown {}
+} -result {1 {testing package unknown} {testing package unknown
+ while executing
+"error "testing package unknown""
+ (procedure "pkgUnknown" line 2)
+ invoked from within
+"pkgUnknown t 0-"
+ ("package unknown" script)
+ invoked from within
+"package require t"}}
+test package-3.17 {Tcl_PkgRequire procedure, "package unknown" doesn't load package} -setup {
+ package forget t
+ set x xxx
+} -body {
+ proc pkgUnknown args {
+ global x
+ set x $args
+ }
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i"
+ }
+ package unknown pkgUnknown
+ list [catch {package require -exact t 1.5} msg] $msg $x
+} -cleanup {
+ package unknown {}
+} -result {1 {can't find package t exactly 1.5} {t 1.5-1.5}}
+test package-3.18 {Tcl_PkgRequire procedure, version checks} -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package require t
+} -result {2.3}
+test package-3.19 {Tcl_PkgRequire procedure, version checks} -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package require t 2.1
+} -result {2.3}
+test package-3.20 {Tcl_PkgRequire procedure, version checks} -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package require t 2.3
+} -result {2.3}
+test package-3.21 {Tcl_PkgRequire procedure, version checks} -setup {
+ package forget t
+} -returnCodes error -body {
+ package provide t 2.3
+ package require t 2.4
+} -result {version conflict for package "t": have 2.3, need 2.4}
+test package-3.22 {Tcl_PkgRequire procedure, version checks} -setup {
+ package forget t
+} -returnCodes error -body {
+ package provide t 2.3
+ package require t 1.2
+} -result {version conflict for package "t": have 2.3, need 1.2}
+test package-3.23 {Tcl_PkgRequire procedure, version checks} -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package require -exact t 2.3
+} -result {2.3}
+test package-3.24 {Tcl_PkgRequire procedure, version checks} -setup {
+ package forget t
+} -returnCodes error -body {
+ package provide t 2.3
+ package require -exact t 2.2
+} -result {version conflict for package "t": have 2.3, need exactly 2.2}
+test package-3.25 {Tcl_PkgRequire procedure, error in ifneeded script} -setup {
+ package forget t
+} -body {
+ package ifneeded t 2.1 {package provide t 2.1; error "ifneeded test" EI}
+ list [catch {package require t 2.1} msg] $msg $::errorInfo
+} -match glob -result {1 {ifneeded test} {EI
+ ("package ifneeded*" script)
+ invoked from within
+"package require t 2.1"}}
+test package-3.26 {Tcl_PkgRequire procedure, error in ifneeded script} -setup {
+ package forget t
+} -body {
+ package ifneeded t 2.1 {package provide t 2.1; foreach x 1 {error "ifneeded test" EI}}
+ list [catch {package require t 2.1} msg] $msg $::errorInfo
+} -match glob -result {1 {ifneeded test} {EI
+ ("foreach" body line 1)
+ invoked from within
+"foreach x 1 {error "ifneeded test" EI}"
+ ("package ifneeded*" script)
+ invoked from within
+"package require t 2.1"}}
+test package-3.27 {Tcl_PkgRequire: circular dependency} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {package require foo 1}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob -result {circular package dependency:*}
+test package-3.28 {Tcl_PkgRequire: circular dependency} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {package require foo 2}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob -result {circular package dependency:*}
+test package-3.29 {Tcl_PkgRequire: circular dependency} -setup {
+ package forget foo
+ package forget bar
+} -body {
+ package ifneeded foo 1 {package require bar 1; package provide foo 1}
+ package ifneeded bar 1 {package require foo 1; package provide bar 1}
+ package require foo 1
+} -cleanup {
+ package forget foo
+ package forget bar
+} -returnCodes error -match glob -result {circular package dependency:*}
+test package-3.30 {Tcl_PkgRequire: circular dependency} -setup {
+ package forget foo
+ package forget bar
+} -body {
+ package ifneeded foo 1 {package require bar 1; package provide foo 1}
+ package ifneeded foo 2 {package provide foo 2}
+ package ifneeded bar 1 {package require foo 2; package provide bar 1}
+ package require foo 1
+} -cleanup {
+ package forget foo
+ package forget bar
+} -returnCodes error -match glob -result {circular package dependency:*}
+test package-3.31 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {package provide foo 1; error foo}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob -result foo
+test package-3.32 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {package provide foo 1; error foo}
+ catch {package require foo 1}
+ package provide foo
+} -cleanup {
+ package forget foo
+} -result {}
+test package-3.33 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {package provide foo 2}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob -result {attempt to provide package * failed:*}
+test package-3.34 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {package provide foo 1.1}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob -result {attempt to provide package * failed:*}
+test package-3.34.1 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1.1 {package provide foo 1}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob -result {attempt to provide package * failed:*}
+test package-3.34.2 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1.1 {package provide foo 1}
+ package require foo 1.1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob -result {attempt to provide package * failed:*}
+test package-3.35 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob -result {attempt to provide package * failed:*}
+test package-3.35.1 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {break}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob \
+-result {attempt to provide package * failed: bad return code:*}
+test package-3.36 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {continue}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob \
+-result {attempt to provide package * failed: bad return code:*}
+test package-3.37 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {return}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob \
+-result {attempt to provide package * failed: bad return code:*}
+test package-3.38 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {return -level 0 -code 10}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob \
+-result {attempt to provide package * failed: bad return code:*}
+test package-3.39 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+ set saveUnknown [package unknown]
+ package unknown {package provide foo 2 ;#}
+} -body {
+ package require foo 1
+} -cleanup {
+ package forget foo
+ package unknown $saveUnknown
+} -returnCodes error -match glob -result *
+test package-3.40 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+ set saveUnknown [package unknown]
+ package unknown {break ;#}
+} -body {
+ package require foo 1
+} -cleanup {
+ package forget foo
+ package unknown $saveUnknown
+} -returnCodes error -match glob -result {bad return code:*}
+test package-3.41 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+ set saveUnknown [package unknown]
+ package unknown {continue ;#}
+} -body {
+ package require foo 1
+} -cleanup {
+ package forget foo
+ package unknown $saveUnknown
+} -returnCodes error -match glob -result {bad return code:*}
+test package-3.42 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+ set saveUnknown [package unknown]
+ package unknown {return ;#}
+} -body {
+ package require foo 1
+} -cleanup {
+ package forget foo
+ package unknown $saveUnknown
+} -returnCodes error -match glob -result {bad return code:*}
+test package-3.43 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+ set saveUnknown [package unknown]
+ package unknown {return -level 0 -code 10 ;#}
+} -body {
+ package require foo 1
+} -cleanup {
+ package forget foo
+ package unknown $saveUnknown
+} -returnCodes error -match glob -result {bad return code:*}
+test package-3.44 {Tcl_PkgRequire: exact version matching (1578344)} -setup {
+ package provide demo 1.2.3
+} -body {
+ package require -exact demo 1.2
+} -returnCodes error -cleanup {
+ package forget demo
+} -result {version conflict for package "demo": have 1.2.3, need exactly 1.2}
+test package-3.50 {Tcl_PkgRequire procedure, picking best stable version} -setup {
+ package forget t
+ set x xxx
+} -body {
+ foreach i {1.4 3.4 4.0a1 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ package require t
+ return $x
+} -result {3.4}
+test package-3.51 {Tcl_PkgRequire procedure, picking best stable version} -setup {
+ package forget t
+ set x xxx
+} -body {
+ foreach i {1.2b1 1.2 1.3a2 1.3} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ package require t
+ return $x
+} -result {1.3}
+test package-3.52 {Tcl_PkgRequire procedure, picking best stable version} -setup {
+ package forget t
+ set x xxx
+} -body {
+ foreach i {1.2b1 1.2 1.3 1.3a2} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ package require t
+ return $x
+} -result {1.3}
+
+test package-4.1 {Tcl_PackageCmd procedure} -returnCodes error -body {
+ package
+} -result {wrong # args: should be "package option ?arg ...?"}
+test package-4.2 {Tcl_PackageCmd procedure, "forget" option} {
+ package forget {*}[package names]
+ package names
+} {}
+test package-4.3 {Tcl_PackageCmd procedure, "forget" option} {
+ package forget {*}[package names]
+ package forget foo
+} {}
+test package-4.4 {Tcl_PackageCmd procedure, "forget" option} -setup {
+ package forget {*}[package names]
+ set result {}
+} -body {
+ package ifneeded t 1.1 {first script}
+ package ifneeded t 2.3 {second script}
+ package ifneeded x 1.4 {x's script}
+ lappend result [lsort [package names]] [package versions t]
+ package forget t
+ lappend result [lsort [package names]] [package versions t]
+} -result {{t x} {1.1 2.3} x {}}
+test package-4.5 {Tcl_PackageCmd procedure, "forget" option} -setup {
+ package forget {*}[package names]
+} -body {
+ package ifneeded a 1.1 {first script}
+ package ifneeded b 2.3 {second script}
+ package ifneeded c 1.4 {third script}
+ package forget
+ set result [list [lsort [package names]]]
+ package forget a c
+ lappend result [lsort [package names]]
+} -result {{a b c} b}
+test package-4.5.1 {Tcl_PackageCmd procedure, "forget" option} -body {
+ # Test for Bug 415273
+ package ifneeded a 1 "I should have been forgotten"
+ package forget no-such-package a
+ package ifneeded a 1
+} -cleanup {
+ package forget a
+} -result {}
+test package-4.6 {Tcl_PackageCmd procedure, "ifneeded" option} -body {
+ package ifneeded a
+} -returnCodes error -result {wrong # args: should be "package ifneeded package version ?script?"}
+test package-4.7 {Tcl_PackageCmd procedure, "ifneeded" option} -body {
+ package ifneeded a b c d
+} -returnCodes error -result {wrong # args: should be "package ifneeded package version ?script?"}
+test package-4.8 {Tcl_PackageCmd procedure, "ifneeded" option} -body {
+ package ifneeded t xyz
+} -returnCodes error -result {expected version number but got "xyz"}
+test package-4.9 {Tcl_PackageCmd procedure, "ifneeded" option} {
+ package forget {*}[package names]
+ list [package ifneeded foo 1.1] [package names]
+} {{} {}}
+test package-4.10 {Tcl_PackageCmd procedure, "ifneeded" option} -setup {
+ package forget t
+} -body {
+ package ifneeded t 1.4 "script for t 1.4"
+ list [package names] [package ifneeded t 1.4] [package versions t]
+} -result {t {script for t 1.4} 1.4}
+test package-4.11 {Tcl_PackageCmd procedure, "ifneeded" option} -setup {
+ package forget t
+} -body {
+ package ifneeded t 1.4 "script for t 1.4"
+ list [package ifneeded t 1.5] [package names] [package versions t]
+} -result {{} t 1.4}
+test package-4.12 {Tcl_PackageCmd procedure, "ifneeded" option} -setup {
+ package forget t
+} -body {
+ package ifneeded t 1.4 "script for t 1.4"
+ package ifneeded t 1.4 "second script for t 1.4"
+ list [package ifneeded t 1.4] [package names] [package versions t]
+} -result {{second script for t 1.4} t 1.4}
+test package-4.13 {Tcl_PackageCmd procedure, "ifneeded" option} -setup {
+ package forget t
+} -body {
+ package ifneeded t 1.4 "script for t 1.4"
+ package ifneeded t 1.2 "second script"
+ package ifneeded t 3.1 "last script"
+ list [package ifneeded t 1.2] [package versions t]
+} -result {{second script} {1.4 1.2 3.1}}
+test package-4.14 {Tcl_PackageCmd procedure, "names" option} -body {
+ package names a
+} -returnCodes error -result {wrong # args: should be "package names"}
+test package-4.15 {Tcl_PackageCmd procedure, "names" option} {
+ package forget {*}[package names]
+ package names
+} {}
+test package-4.16 {Tcl_PackageCmd procedure, "names" option} -setup {
+ package forget {*}[package names]
+} -body {
+ package ifneeded x 1.2 {dummy}
+ package provide x 1.3
+ package provide y 2.4
+ catch {package require z 47.16}
+ lsort [package names]
+} -result {x y}
+test package-4.17 {Tcl_PackageCmd procedure, "provide" option} -body {
+ package provide
+} -returnCodes error -result {wrong # args: should be "package provide package ?version?"}
+test package-4.18 {Tcl_PackageCmd procedure, "provide" option} -body {
+ package provide a b c
+} -returnCodes error -result {wrong # args: should be "package provide package ?version?"}
+test package-4.19 {Tcl_PackageCmd procedure, "provide" option} -setup {
+ package forget t
+} -body {
+ package provide t
+} -result {}
+test package-4.20 {Tcl_PackageCmd procedure, "provide" option} -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package provide t
+} -result {2.3}
+test package-4.21 {Tcl_PackageCmd procedure, "provide" option} -setup {
+ package forget t
+} -returnCodes error -body {
+ package provide t a.b
+} -result {expected version number but got "a.b"}
+test package-4.22 {Tcl_PackageCmd procedure, "require" option} -returnCodes error -body {
+ package require
+} -result {wrong # args: should be "package require ?-exact? package ?requirement ...?"}
+test package-4.24 {Tcl_PackageCmd procedure, "require" option} -body {
+ package require -exact a b c
+ # Exact syntax: -exact name version
+ # name ?requirement ...?
+} -returnCodes error -result {wrong # args: should be "package require ?-exact? package ?requirement ...?"}
+test package-4.26 {Tcl_PackageCmd procedure, "require" option} -body {
+ package require x a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-4.27 {Tcl_PackageCmd procedure, "require" option} -body {
+ package require -exact x a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-4.28 {Tcl_PackageCmd procedure, "require" option} -body {
+ package require -exact x
+} -returnCodes error -result {wrong # args: should be "package require ?-exact? package ?requirement ...?"}
+test package-4.29 {Tcl_PackageCmd procedure, "require" option} -body {
+ package require -exact
+} -returnCodes error -result {wrong # args: should be "package require ?-exact? package ?requirement ...?"}
+test package-4.30 {Tcl_PackageCmd procedure, "require" option} -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package require t 2.1
+} -result {2.3}
+test package-4.31 {Tcl_PackageCmd procedure, "require" option} -setup {
+ package forget t
+} -body {
+ package require t
+} -returnCodes error -result {can't find package t}
+test package-4.32 {Tcl_PackageCmd procedure, "require" option} -setup {
+ package forget t
+} -body {
+ package ifneeded t 2.3 "error {synthetic error}"
+ package require t 2.3
+} -returnCodes error -result {synthetic error}
+test package-4.33 {Tcl_PackageCmd procedure, "unknown" option} -body {
+ package unknown a b
+} -returnCodes error -result {wrong # args: should be "package unknown ?command?"}
+test package-4.34 {Tcl_PackageCmd procedure, "unknown" option} {
+ package unknown "test script"
+ package unknown
+} {test script}
+test package-4.35 {Tcl_PackageCmd procedure, "unknown" option} {
+ package unknown "test script"
+ package unknown {}
+ package unknown
+} {}
+test package-4.36 {Tcl_PackageCmd procedure, "vcompare" option} -body {
+ package vcompare a
+} -returnCodes error -result {wrong # args: should be "package vcompare version1 version2"}
+test package-4.37 {Tcl_PackageCmd procedure, "vcompare" option} -body {
+ package vcompare a b c
+} -returnCodes error -result {wrong # args: should be "package vcompare version1 version2"}
+test package-4.38 {Tcl_PackageCmd procedure, "vcompare" option} -body {
+ package vcompare x.y 3.4
+} -returnCodes error -result {expected version number but got "x.y"}
+test package-4.39 {Tcl_PackageCmd procedure, "vcompare" option} -body {
+ package vcompare 2.1 a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-4.40 {Tcl_PackageCmd procedure, "vcompare" option} {
+ package vc 2.1 2.3
+} {-1}
+test package-4.41 {Tcl_PackageCmd procedure, "vcompare" option} {
+ package vc 2.2.4 2.2.4
+} {0}
+test package-4.42 {Tcl_PackageCmd procedure, "versions" option} -body {
+ package versions
+} -returnCodes error -result {wrong # args: should be "package versions package"}
+test package-4.43 {Tcl_PackageCmd procedure, "versions" option} -body {
+ package versions a b
+} -returnCodes error -result {wrong # args: should be "package versions package"}
+test package-4.44 {Tcl_PackageCmd procedure, "versions" option} -body {
+ package forget t
+ package versions t
+} -result {}
+test package-4.45 {Tcl_PackageCmd procedure, "versions" option} -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package versions t
+} -result {}
+test package-4.46 {Tcl_PackageCmd procedure, "versions" option} -setup {
+ package forget t
+} -body {
+ package ifneeded t 2.3 x
+ package ifneeded t 2.4 y
+ package versions t
+} -result {2.3 2.4}
+test package-4.47 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+ package vsatisfies a
+} -returnCodes error -result {wrong # args: should be "package vsatisfies version ?requirement ...?"}
+test package-4.49 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+ package vsatisfies x.y 3.4
+} -returnCodes error -result {expected version number but got "x.y"}
+test package-4.50 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+ package vcompare 2.1 a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-4.51 {Tcl_PackageCmd procedure, "vsatisfies" option} {
+ package vs 2.3 2.1
+} {1}
+test package-4.52 {Tcl_PackageCmd procedure, "vsatisfies" option} {
+ package vs 2.3 1.2
+} {0}
+test package-4.53 {Tcl_PackageCmd procedure, "versions" option} -body {
+ package foo
+} -returnCodes error -result {bad option "foo": must be forget, ifneeded, names, prefer, present, provide, require, unknown, vcompare, versions, or vsatisfies}
+test package-4.54 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+ package vsatisfies 2.1 2.1-3.2-4.5
+} -returnCodes error -result {expected versionMin-versionMax but got "2.1-3.2-4.5"}
+test package-4.55 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+ package vsatisfies 2.1 3.2-x.y
+} -returnCodes error -result {expected version number but got "x.y"}
+test package-4.56 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+ package vsatisfies 2.1 x.y-3.2
+} -returnCodes error -result {expected version number but got "x.y"}
+
+# No tests for FindPackage; can't think up anything detectable errors.
+
+test package-5.1 {TclFreePackageInfo procedure} {
+ interp create slave
+ slave eval {
+ package ifneeded t 2.3 x
+ package ifneeded t 2.4 y
+ package ifneeded x 3.1 z
+ package provide q 4.3
+ package unknown "will this get freed?"
+ }
+ interp delete slave
+} {}
+test package-5.2 {TclFreePackageInfo procedure} -body {
+ interp create foo
+ foo eval {
+ package ifneeded t 2.3 x
+ package ifneeded t 2.4 y
+ package ifneeded x 3.1 z
+ package provide q 4.3
+ }
+ foo alias z kill
+ proc kill {} {
+ interp delete foo
+ }
+ foo eval package require x 3.1
+} -returnCodes error -match glob -result *
+
+test package-6.1 {CheckVersion procedure} {
+ package vcompare 1 2.1
+} -1
+test package-6.2 {CheckVersion procedure} -body {
+ package vcompare .1 2.1
+} -returnCodes error -result {expected version number but got ".1"}
+test package-6.3 {CheckVersion procedure} -body {
+ package vcompare 111.2a.3 2.1
+} -returnCodes error -result {expected version number but got "111.2a.3"}
+test package-6.4 {CheckVersion procedure} -body {
+ package vcompare 1.2.3. 2.1
+} -returnCodes error -result {expected version number but got "1.2.3."}
+test package-6.5 {CheckVersion procedure} -body {
+ package vcompare 1.2..3 2.1
+} -returnCodes error -result {expected version number but got "1.2..3"}
+
+test package-7.1 {ComparePkgVersions procedure} {
+ package vcompare 1.23 1.22
+} {1}
+test package-7.2 {ComparePkgVersions procedure} {
+ package vcompare 1.22.1.2.3 1.22.1.2.3
+} {0}
+test package-7.3 {ComparePkgVersions procedure} {
+ package vcompare 1.21 1.22
+} {-1}
+test package-7.4 {ComparePkgVersions procedure} {
+ package vcompare 1.21 1.21.2
+} {-1}
+test package-7.5 {ComparePkgVersions procedure} {
+ package vcompare 1.21.1 1.21
+} {1}
+test package-7.6 {ComparePkgVersions procedure} {
+ package vsatisfies 1.21.1 1.21
+} {1}
+test package-7.7 {ComparePkgVersions procedure} {
+ package vsatisfies 2.22.3 1.21
+} {0}
+test package-7.8 {ComparePkgVersions procedure} {
+ package vsatisfies 1 1
+} {1}
+test package-7.9 {ComparePkgVersions procedure} {
+ package vsatisfies 2 1
+} {0}
+
+test package-8.1 {Tcl_PkgPresent procedure, any version} -setup {
+ package forget t
+} -body {
+ package provide t 2.4
+ package present t
+} -result {2.4}
+test package-8.2 {Tcl_PkgPresent procedure, correct version} -setup {
+ package forget t
+} -body {
+ package provide t 2.4
+ package present t 2.4
+} -result {2.4}
+test package-8.3 {Tcl_PkgPresent procedure, satisfying version} -setup {
+ package forget t
+} -body {
+ package provide t 2.4
+ package present t 2.0
+} -result {2.4}
+test package-8.4 {Tcl_PkgPresent procedure, not satisfying version} -setup {
+ package forget t
+} -returnCodes error -body {
+ package provide t 2.4
+ package present t 2.6
+} -result {version conflict for package "t": have 2.4, need 2.6}
+test package-8.5 {Tcl_PkgPresent procedure, not satisfying version} -setup {
+ package forget t
+} -returnCodes error -body {
+ package provide t 2.4
+ package present t 1.0
+} -result {version conflict for package "t": have 2.4, need 1.0}
+test package-8.6 {Tcl_PkgPresent procedure, exact version} -setup {
+ package forget t
+} -body {
+ package provide t 2.4
+ package present -exact t 2.4
+} -result {2.4}
+test package-8.7 {Tcl_PkgPresent procedure, not exact version} -setup {
+ package forget t
+} -returnCodes error -body {
+ package provide t 2.4
+ package present -exact t 2.3
+} -result {version conflict for package "t": have 2.4, need exactly 2.3}
+test package-8.8 {Tcl_PkgPresent procedure, unknown package} -body {
+ package forget t
+ package present t
+} -returnCodes error -result {package t is not present}
+test package-8.9 {Tcl_PkgPresent procedure, unknown package} -body {
+ package forget t
+ package present t 2.4
+} -returnCodes error -result {package t 2.4 is not present}
+test package-8.10 {Tcl_PkgPresent procedure, unknown package} -body {
+ package forget t
+ package present -exact t 2.4
+} -returnCodes error -result {package t 2.4 is not present}
+test package-8.11 {Tcl_PackageCmd procedure, "present" option} -body {
+ package present
+} -returnCodes error -result {wrong # args: should be "package present ?-exact? package ?requirement ...?"}
+test package-8.12 {Tcl_PackageCmd procedure, "present" option} -body {
+ package present a b c
+} -returnCodes error -result {expected version number but got "b"}
+test package-8.13 {Tcl_PackageCmd procedure, "present" option} -body {
+ package present -exact a b c
+} -returnCodes error -result {wrong # args: should be "package present ?-exact? package ?requirement ...?"}
+test package-8.14 {Tcl_PackageCmd procedure, "present" option} -body {
+ package present -bs a b
+} -returnCodes error -result {expected version number but got "a"}
+test package-8.15 {Tcl_PackageCmd procedure, "present" option} -body {
+ package present x a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-8.16 {Tcl_PackageCmd procedure, "present" option} -body {
+ package present -exact x a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-8.17 {Tcl_PackageCmd procedure, "present" option} -body {
+ package present -exact x
+} -returnCodes error -result {wrong # args: should be "package present ?-exact? package ?requirement ...?"}
+test package-8.18 {Tcl_PackageCmd procedure, "present" option} -body {
+ package present -exact
+} -returnCodes error -result {wrong # args: should be "package present ?-exact? package ?requirement ...?"}
+
+set n 0
+foreach {r p vs vc} {
+ 8.5a0 8.5a5 1 -1
+ 8.5a0 8.5b1 1 -1
+ 8.5a0 8.5.1 1 -1
+ 8.5a0 8.6a0 1 -1
+ 8.5a0 8.6b0 1 -1
+ 8.5a0 8.6.0 1 -1
+ 8.5a6 8.5a5 0 1
+ 8.5a6 8.5b1 1 -1
+ 8.5a6 8.5.1 1 -1
+ 8.5a6 8.6a0 1 -1
+ 8.5a6 8.6b0 1 -1
+ 8.5a6 8.6.0 1 -1
+ 8.5b0 8.5a5 0 1
+ 8.5b0 8.5b1 1 -1
+ 8.5b0 8.5.1 1 -1
+ 8.5b0 8.6a0 1 -1
+ 8.5b0 8.6b0 1 -1
+ 8.5b0 8.6.0 1 -1
+ 8.5b2 8.5a5 0 1
+ 8.5b2 8.5b1 0 1
+ 8.5b2 8.5.1 1 -1
+ 8.5b2 8.6a0 1 -1
+ 8.5b2 8.6b0 1 -1
+ 8.5b2 8.6.0 1 -1
+ 8.5 8.5a5 1 1
+ 8.5 8.5b1 1 1
+ 8.5 8.5.1 1 -1
+ 8.5 8.6a0 1 -1
+ 8.5 8.6b0 1 -1
+ 8.5 8.6.0 1 -1
+ 8.5.0 8.5a5 0 1
+ 8.5.0 8.5b1 0 1
+ 8.5.0 8.5.1 1 -1
+ 8.5.0 8.6a0 1 -1
+ 8.5.0 8.6b0 1 -1
+ 8.5.0 8.6.0 1 -1
+ 10 8 0 1
+ 8 10 0 -1
+ 0.0.1.2 0.1.2 1 -1
+} {
+ test package-9.$n {package vsatisfies} {
+ package vsatisfies $p $r
+ } $vs
+ test package-10.$n {package vcompare} {
+ package vcompare $r $p
+ } $vc
+ incr n
+}
+
+test package-11.0.0 {package vcompare at 32bit boundary} {
+ package vcompare [expr {1<<31}] [expr {(1<<31)-1}]
+} 1
+
+# Note: It is correct that the result of the very first test, i.e. "5.0 5.0a0"
+# is 1, i.e. that version 5.0a0 satisfies a 5.0 requirement.
+
+# The requirement "5.0" internally translates first to "5.0-6", and then to
+# its final form of "5.0a0-6a0". These translations are explicitly specified
+# by the TIP (Search for "padded/extended internally with 'a0'"). This was
+# done intentionally for exactly the tested case, that an alpha package can
+# satisfy a requirement for the regular package. An example would be a package
+# FOO requiring Tcl 8.X for its operation. It can be used with Tcl 8.Xa0.
+# Without our translation that would not be possible.
+
+set n 0
+foreach {required provided satisfied} {
+ 5.0 5.0a0 1
+ 5.0a0 5.0 1
+
+ 8.5a0- 8.5a5 1
+ 8.5a0- 8.5b1 1
+ 8.5a0- 8.5.1 1
+ 8.5a0- 8.6a0 1
+ 8.5a0- 8.6b0 1
+ 8.5a0- 8.6.0 1
+ 8.5a6- 8.5a5 0
+ 8.5a6- 8.5b1 1
+ 8.5a6- 8.5.1 1
+ 8.5a6- 8.6a0 1
+ 8.5a6- 8.6b0 1
+ 8.5a6- 8.6.0 1
+ 8.5b0- 8.5a5 0
+ 8.5b0- 8.5b1 1
+ 8.5b0- 8.5.1 1
+ 8.5b0- 8.6a0 1
+ 8.5b0- 8.6b0 1
+ 8.5b0- 8.6.0 1
+ 8.5b2- 8.5a5 0
+ 8.5b2- 8.5b1 0
+ 8.5b2- 8.5.1 1
+ 8.5b2- 8.6a0 1
+ 8.5b2- 8.6b0 1
+ 8.5b2- 8.6.0 1
+ 8.5- 8.5a5 1
+ 8.5- 8.5b1 1
+ 8.5- 8.5.1 1
+ 8.5- 8.6a0 1
+ 8.5- 8.6b0 1
+ 8.5- 8.6.0 1
+ 8.5.0- 8.5a5 0
+ 8.5.0- 8.5b1 0
+ 8.5.0- 8.5.1 1
+ 8.5.0- 8.6a0 1
+ 8.5.0- 8.6b0 1
+ 8.5.0- 8.6.0 1
+ 8.5a0-7 8.5a5 0
+ 8.5a0-7 8.5b1 0
+ 8.5a0-7 8.5.1 0
+ 8.5a0-7 8.6a0 0
+ 8.5a0-7 8.6b0 0
+ 8.5a0-7 8.6.0 0
+ 8.5a6-7 8.5a5 0
+ 8.5a6-7 8.5b1 0
+ 8.5a6-7 8.5.1 0
+ 8.5a6-7 8.6a0 0
+ 8.5a6-7 8.6b0 0
+ 8.5a6-7 8.6.0 0
+ 8.5b0-7 8.5a5 0
+ 8.5b0-7 8.5b1 0
+ 8.5b0-7 8.5.1 0
+ 8.5b0-7 8.6a0 0
+ 8.5b0-7 8.6b0 0
+ 8.5b0-7 8.6.0 0
+ 8.5b2-7 8.5a5 0
+ 8.5b2-7 8.5b1 0
+ 8.5b2-7 8.5.1 0
+ 8.5b2-7 8.6a0 0
+ 8.5b2-7 8.6b0 0
+ 8.5b2-7 8.6.0 0
+ 8.5-7 8.5a5 0
+ 8.5-7 8.5b1 0
+ 8.5-7 8.5.1 0
+ 8.5-7 8.6a0 0
+ 8.5-7 8.6b0 0
+ 8.5-7 8.6.0 0
+ 8.5.0-7 8.5a5 0
+ 8.5.0-7 8.5b1 0
+ 8.5.0-7 8.5.1 0
+ 8.5.0-7 8.6a0 0
+ 8.5.0-7 8.6b0 0
+ 8.5.0-7 8.6.0 0
+ 8.5a0-8.6.1 8.5a5 1
+ 8.5a0-8.6.1 8.5b1 1
+ 8.5a0-8.6.1 8.5.1 1
+ 8.5a0-8.6.1 8.6a0 1
+ 8.5a0-8.6.1 8.6b0 1
+ 8.5a0-8.6.1 8.6.0 1
+ 8.5a6-8.6.1 8.5a5 0
+ 8.5a6-8.6.1 8.5b1 1
+ 8.5a6-8.6.1 8.5.1 1
+ 8.5a6-8.6.1 8.6a0 1
+ 8.5a6-8.6.1 8.6b0 1
+ 8.5a6-8.6.1 8.6.0 1
+ 8.5b0-8.6.1 8.5a5 0
+ 8.5b0-8.6.1 8.5b1 1
+ 8.5b0-8.6.1 8.5.1 1
+ 8.5b0-8.6.1 8.6a0 1
+ 8.5b0-8.6.1 8.6b0 1
+ 8.5b0-8.6.1 8.6.0 1
+ 8.5b2-8.6.1 8.5a5 0
+ 8.5b2-8.6.1 8.5b1 0
+ 8.5b2-8.6.1 8.5.1 1
+ 8.5b2-8.6.1 8.6a0 1
+ 8.5b2-8.6.1 8.6b0 1
+ 8.5b2-8.6.1 8.6.0 1
+ 8.5-8.6.1 8.5a5 1
+ 8.5-8.6.1 8.5b1 1
+ 8.5-8.6.1 8.5.1 1
+ 8.5-8.6.1 8.6a0 1
+ 8.5-8.6.1 8.6b0 1
+ 8.5-8.6.1 8.6.0 1
+ 8.5.0-8.6.1 8.5a5 0
+ 8.5.0-8.6.1 8.5b1 0
+ 8.5.0-8.6.1 8.5.1 1
+ 8.5.0-8.6.1 8.6a0 1
+ 8.5.0-8.6.1 8.6b0 1
+ 8.5.0-8.6.1 8.6.0 1
+ 8.5a0-8.5a0 8.5a0 1
+ 8.5a0-8.5a0 8.5b1 0
+ 8.5a0-8.5a0 8.4 0
+ 8.5b0-8.5b0 8.5a5 0
+ 8.5b0-8.5b0 8.5b0 1
+ 8.5b0-8.5b0 8.5.1 0
+ 8.5-8.5 8.5a5 0
+ 8.5-8.5 8.5b1 0
+ 8.5-8.5 8.5 1
+ 8.5-8.5 8.5.1 0
+ 8.5.0-8.5.0 8.5a5 0
+ 8.5.0-8.5.0 8.5b1 0
+ 8.5.0-8.5.0 8.5.0 1
+ 8.5.0-8.5.0 8.5.1 0
+ 8.5.0-8.5.0 8.6a0 0
+ 8.5.0-8.5.0 8.6b0 0
+ 8.5.0-8.5.0 8.6.0 0
+ 8.2 9 0
+ 8.2- 9 1
+ 8.2-8.5 9 0
+ 8.2-9.1 9 1
+
+ 8.5-8.5 8.5b1 0
+ 8.5a0-8.5 8.5b1 0
+ 8.5a0-8.5.1 8.5b1 1
+
+ 8.5-8.5 8.5 1
+ 8.5.0-8.5.0 8.5 1
+ 8.5a0-8.5.0 8.5 0
+} {
+ test package-11.$n "package vsatisfies $provided $required" {
+ package vsatisfies $provided $required
+ } $satisfied
+ incr n
+}
+
+test package-12.0 "package vsatisfies multiple" {
+ # yes no
+ package vsatisfies 8.4 8.4 7.3
+} 1
+test package-12.1 "package vsatisfies multiple" {
+ # no yes
+ package vsatisfies 8.4 7.3 8.4
+} 1
+test package-12.2 "package vsatisfies multiple" {
+ # yes yes
+ package vsatisfies 8.4.2 8.4 8.4.1
+} 1
+test package-12.3 "package vsatisfies multiple" {
+ # no no
+ package vsatisfies 8.4 7.3 6.1
+} 0
+
+proc prefer {args} {
+ set ip [interp create]
+ try {
+ lappend res [$ip eval {package prefer}]
+ foreach mode $args {
+ lappend res [$ip eval [list package prefer $mode]]
+ }
+ return $res
+ } finally {
+ interp delete $ip
+ }
+}
+
+test package-13.0 {package prefer defaults} {
+ prefer
+} stable
+test package-13.1 {package prefer defaults} -body {
+ set ::env(TCL_PKG_PREFER_LATEST) stable ;# value not relevant!
+ prefer
+} -cleanup {
+ unset -nocomplain ::env(TCL_PKG_PREFER_LATEST)
+} -result latest
+
+test package-14.0 {wrong\#args} -returnCodes error -body {
+ package prefer foo bar
+} -result {wrong # args: should be "package prefer ?latest|stable?"}
+test package-14.1 {bogus argument} -returnCodes error -body {
+ package prefer foo
+} -result {bad preference "foo": must be latest or stable}
+
+test package-15.0 {set, keep} {package prefer stable} stable
+test package-15.1 {set stable, keep} {prefer stable} {stable stable}
+test package-15.2 {set latest, change} {prefer latest} {stable latest}
+test package-15.3 {set latest, keep} {
+ prefer latest latest
+} {stable latest latest}
+test package-15.4 {set stable, rejected} {
+ prefer latest stable
+} {stable latest latest}
+
+rename prefer {}
+
+set auto_path $oldPath
+package unknown $oldPkgUnknown
+
+cleanupTests
+}
+
+# cleanup
+interp delete $i
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/parse.test b/library/msgcat/tests/parse.test
new file mode 100644
index 0000000..3523975
--- /dev/null
+++ b/library/msgcat/tests/parse.test
@@ -0,0 +1,1094 @@
+# This file contains a collection of tests for the procedures in the
+# file tclParse.c. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[catch {package require tcltest 2.0.2}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2.0.2 required."
+ return
+}
+
+namespace eval ::tcl::test::parse {
+ namespace import ::tcltest::*
+
+testConstraint testparser [llength [info commands testparser]]
+testConstraint testevalobjv [llength [info commands testevalobjv]]
+testConstraint testevalex [llength [info commands testevalex]]
+testConstraint testparsevarname [llength [info commands testparsevarname]]
+testConstraint testparsevar [llength [info commands testparsevar]]
+testConstraint testasync [llength [info commands testasync]]
+testConstraint testcmdtrace [llength [info commands testcmdtrace]]
+
+test parse-1.1 {Tcl_ParseCommand procedure, computing string length} testparser {
+ testparser [bytestring "foo\0 bar"] -1
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-1.2 {Tcl_ParseCommand procedure, computing string length} testparser {
+ testparser "foo bar" -1
+} {- {foo bar} 2 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
+test parse-1.3 {Tcl_ParseCommand procedure, leading space} testparser {
+ testparser " \n\t foo" 0
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-1.4 {Tcl_ParseCommand procedure, leading space} testparser {
+ testparser "\f\r\vfoo" 0
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-1.5 {Tcl_ParseCommand procedure, backslash-newline in leading space} testparser {
+ testparser " \\\n foo" 0
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-1.6 {Tcl_ParseCommand procedure, backslash-newline in leading space} testparser {
+ testparser { \a foo} 0
+} {- {\a foo} 2 word {\a} 1 backslash {\a} 0 simple foo 1 text foo 0 {}}
+test parse-1.7 {Tcl_ParseCommand procedure, missing continuation line in leading space} testparser {
+ testparser " \\\n" 0
+} {- {} 0 {}}
+test parse-1.8 {Tcl_ParseCommand procedure, eof in leading space} testparser {
+ testparser " foo" 3
+} {- {} 0 { foo}}
+test parse-1.9 {Tcl_ParseCommand procedure, backslash newline + newline} testparser {
+ testparser "cmd1\\\n\ncmd2" 0
+} {- cmd1\\\n\n 1 simple cmd1 1 text cmd1 0 cmd2}
+test parse-1.10 {Tcl_ParseCommand procedure, backslash newline + newline} testparser {
+ testparser "list \\\nA B\\\n\nlist C D" 0
+} {- list\ \\\nA\ B\\\n\n 3 simple list 1 text list 0 simple A 1 text A 0 simple B 1 text B 0 {list C D}}
+
+test parse-2.1 {Tcl_ParseCommand procedure, comments} testparser {
+ testparser "# foo bar\n foo" 0
+} {{# foo bar
+} foo 1 simple foo 1 text foo 0 {}}
+test parse-2.2 {Tcl_ParseCommand procedure, several comments} testparser {
+ testparser " # foo bar\n # another comment\n\n foo" 0
+} {{# foo bar
+ # another comment
+} foo 1 simple foo 1 text foo 0 {}}
+test parse-2.3 {Tcl_ParseCommand procedure, backslash-newline in comments} testparser {
+ testparser " # foo bar\\\ncomment on continuation line\nfoo" 0
+} {\#\ foo\ bar\\\ncomment\ on\ continuation\ line\n foo 1 simple foo 1 text foo 0 {}}
+test parse-2.4 {Tcl_ParseCommand procedure, missing continuation line in comment} testparser {
+ testparser "# \\\n" 0
+} {\#\ \ \ \\\n {} 0 {}}
+test parse-2.5 {Tcl_ParseCommand procedure, eof in comment} testparser {
+ testparser " # foo bar\nfoo" 8
+} {{# foo b} {} 0 {ar
+foo}}
+
+test parse-3.1 {Tcl_ParseCommand procedure, parsing words, skipping space} testparser {
+ testparser "foo bar\t\tx" 0
+} {- {foo bar x} 3 simple foo 1 text foo 0 simple bar 1 text bar 0 simple x 1 text x 0 {}}
+test parse-3.2 {Tcl_ParseCommand procedure, missing continuation line in leading space} testparser {
+ testparser "abc \\\n" 0
+} {- abc\ \ \\\n 1 simple abc 1 text abc 0 {}}
+test parse-3.3 {Tcl_ParseCommand procedure, parsing words, command ends in space} testparser {
+ testparser "foo ; bar x" 0
+} {- {foo ;} 1 simple foo 1 text foo 0 { bar x}}
+test parse-3.4 {Tcl_ParseCommand procedure, parsing words, command ends in space} testparser {
+ testparser "foo " 5
+} {- {foo } 1 simple foo 1 text foo 0 { }}
+test parse-3.5 {Tcl_ParseCommand procedure, quoted words} testparser {
+ testparser {foo "a b c" d "efg";} 0
+} {- {foo "a b c" d "efg";} 4 simple foo 1 text foo 0 simple {"a b c"} 1 text {a b c} 0 simple d 1 text d 0 simple {"efg"} 1 text efg 0 {}}
+test parse-3.6 {Tcl_ParseCommand procedure, words in braces} testparser {
+ testparser {foo {a $b [concat foo]} {c d}} 0
+} {- {foo {a $b [concat foo]} {c d}} 3 simple foo 1 text foo 0 simple {{a $b [concat foo]}} 1 text {a $b [concat foo]} 0 simple {{c d}} 1 text {c d} 0 {}}
+test parse-3.7 {Tcl_ParseCommand procedure, error in unquoted word} testparser {
+ list [catch {testparser "foo \$\{abc" 0} msg] $msg $::errorInfo
+} {1 {missing close-brace for variable name} missing\ close-brace\ for\ variable\ name\n\ \ \ \ (remainder\ of\ script:\ \"\{abc\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"foo\ \\\$\\\{abc\"\ 0\"}
+
+test parse-4.1 {Tcl_ParseCommand procedure, simple words} testparser {
+ testparser {foo} 0
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-4.2 {Tcl_ParseCommand procedure, simple words} testparser {
+ testparser {{abc}} 0
+} {- {{abc}} 1 simple {{abc}} 1 text abc 0 {}}
+test parse-4.3 {Tcl_ParseCommand procedure, simple words} testparser {
+ testparser {"c d"} 0
+} {- {"c d"} 1 simple {"c d"} 1 text {c d} 0 {}}
+test parse-4.4 {Tcl_ParseCommand procedure, simple words} testparser {
+ testparser {x$d} 0
+} {- {x$d} 1 word {x$d} 3 text x 0 variable {$d} 1 text d 0 {}}
+test parse-4.5 {Tcl_ParseCommand procedure, simple words} testparser {
+ testparser {"a [foo] b"} 0
+} {- {"a [foo] b"} 1 word {"a [foo] b"} 3 text {a } 0 command {[foo]} 0 text { b} 0 {}}
+test parse-4.6 {Tcl_ParseCommand procedure, simple words} testparser {
+ testparser {$x} 0
+} {- {$x} 1 word {$x} 2 variable {$x} 1 text x 0 {}}
+
+test parse-5.1 {Tcl_ParseCommand procedure, backslash-newline terminates word} testparser {
+ testparser "{abc}\\\n" 0
+} {- \{abc\}\\\n 1 simple {{abc}} 1 text abc 0 {}}
+test parse-5.2 {Tcl_ParseCommand procedure, backslash-newline terminates word} testparser {
+ testparser "foo\\\nbar" 0
+} {- foo\\\nbar 2 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
+test parse-5.3 {Tcl_ParseCommand procedure, word terminator is command terminator} testparser {
+ testparser "foo\n bar" 0
+} {- {foo
+} 1 simple foo 1 text foo 0 { bar}}
+test parse-5.4 {Tcl_ParseCommand procedure, word terminator is command terminator} testparser {
+ testparser "foo; bar" 0
+} {- {foo;} 1 simple foo 1 text foo 0 { bar}}
+test parse-5.5 {Tcl_ParseCommand procedure, word terminator is end of string} testparser {
+ testparser "\"foo\" bar" 5
+} {- {"foo"} 1 simple {"foo"} 1 text foo 0 { bar}}
+test parse-5.6 {Tcl_ParseCommand procedure, junk after close quote} testparser {
+ list [catch {testparser {foo "bar"x} 0} msg] $msg $::errorInfo
+} {1 {extra characters after close-quote} {extra characters after close-quote
+ (remainder of script: "x")
+ invoked from within
+"testparser {foo "bar"x} 0"}}
+test parse-5.7 {Tcl_ParseCommand procedure, backslash-newline after close quote} testparser {
+ testparser "foo \"bar\"\\\nx" 0
+} {- foo\ \"bar\"\\\nx 3 simple foo 1 text foo 0 simple {"bar"} 1 text bar 0 simple x 1 text x 0 {}}
+test parse-5.8 {Tcl_ParseCommand procedure, junk after close brace} testparser {
+ list [catch {testparser {foo {bar}x} 0} msg] $msg $::errorInfo
+} {1 {extra characters after close-brace} {extra characters after close-brace
+ (remainder of script: "x")
+ invoked from within
+"testparser {foo {bar}x} 0"}}
+test parse-5.9 {Tcl_ParseCommand procedure, backslash-newline after close brace} testparser {
+ testparser "foo {bar}\\\nx" 0
+} {- foo\ \{bar\}\\\nx 3 simple foo 1 text foo 0 simple {{bar}} 1 text bar 0 simple x 1 text x 0 {}}
+test parse-5.10 {Tcl_ParseCommand procedure, multiple deletion of non-static buffer} testparser {
+ # This test is designed to catch bug 1681.
+ list [catch {testparser "a \"\\1\\2\\3\\4\\5\\6\\7\\8\\9\\1\\2\\3\\4\\5\\6\\7\\8" 0} msg] $msg $::errorInfo
+} "1 {missing \"} {missing \"
+ (remainder of script: \"\"\\1\\2\\3\\4\\5\\6\\7\\8\\9\\1\\2\\3\\4\\5\\6\\7\\8\")
+ invoked from within
+\"testparser \"a \\\"\\\\1\\\\2\\\\3\\\\4\\\\5\\\\6\\\\7\\\\8\\\\9\\\\1\\\\2\\\\3\\\\4\\\\5\\\\6\\\\7\\\\8\" 0\"}"
+
+test parse-5.11 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{expan}} 0
+} {- {{expan}} 1 simple {{expan}} 1 text expan 0 {}}
+test parse-5.12 {Tcl_ParseCommand: {*} parsing} -constraints {
+ testparser
+} -body {
+ testparser {{expan}x} 0
+} -returnCodes error -result {extra characters after close-brace}
+test parse-5.13 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{**}} 0
+} {- {{**}} 1 simple {{**}} 1 text ** 0 {}}
+test parse-5.14 {Tcl_ParseCommand: {*} parsing} -constraints {
+ testparser
+} -body {
+ testparser {{**}x} 0
+} -returnCodes error -result {extra characters after close-brace}
+test parse-5.15 {Tcl_ParseCommand: {*} parsing} -constraints {
+ testparser
+} -body {
+ testparser {{*}{123456}x} 0
+} -returnCodes error -result {extra characters after close-brace}
+test parse-5.16 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{123456\
+ }} 0
+} {- {{123456 }} 1 simple {{123456 }} 1 text {123456 } 0 {}}
+test parse-5.17 {Tcl_ParseCommand: {*} parsing} -constraints {
+ testparser
+} -body {
+ testparser {{123456\
+ }x} 0
+} -returnCodes error -result {extra characters after close-brace}
+test parse-5.18 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{*\
+ }} 0
+} {- {{* }} 1 simple {{* }} 1 text {* } 0 {}}
+test parse-5.19 {Tcl_ParseCommand: {*} parsing} -constraints {
+ testparser
+} -body {
+ testparser {{*\
+ }x} 0
+} -returnCodes error -result {extra characters after close-brace}
+test parse-5.20 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{123456}} 0
+} {- {{123456}} 1 simple {{123456}} 1 text 123456 0 {}}
+test parse-5.21 {Tcl_ParseCommand: {*} parsing} -constraints {
+ testparser
+} -body {
+ testparser {{123456}x} 0
+} -returnCodes error -result {extra characters after close-brace}
+test parse-5.22 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{*}} 0
+} {- {{*}} 1 simple {{*}} 1 text * 0 {}}
+test parse-5.23 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{*} } 0
+} {- {{*} } 1 simple {{*}} 1 text * 0 {}}
+test parse-5.24 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{*}x} 0
+} {- {{*}x} 1 simple x 1 text x 0 {}}
+test parse-5.25 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{*}
+} 0
+} {- {{*}
+} 1 simple {{*}} 1 text * 0 {}}
+test parse-5.26 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{*};} 0
+} {- {{*};} 1 simple {{*}} 1 text * 0 {}}
+test parse-5.27 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser "{*}\\\n foo bar" 0
+} {- \{*\}\\\n\ foo\ bar 3 simple {{*}} 1 text * 0 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
+test parse-5.28 {Tcl_ParseCommand: {*} parsing, expanded literals} testparser {
+ testparser {{*}{a b}} 0
+} {- {{*}{a b}} 2 simple a 1 text a 0 simple b 1 text b 0 {}}
+test parse-5.29 {Tcl_ParseCommand: {*} parsing, expanded literals, naked backslashes} testparser {
+ testparser {{*}{a \n b}} 0
+} {- {{*}{a \n b}} 1 expand {{*}{a \n b}} 1 text {a \n b} 0 {}}
+test parse-5.30 {Tcl_ParseCommand: {*} parsing, expanded literals} testparser {
+ testparser {{*}"a b"} 0
+} {- {{*}"a b"} 2 simple a 1 text a 0 simple b 1 text b 0 {}}
+test parse-5.31 {Tcl_ParseCommand: {*} parsing, expanded literals, naked backslashes} testparser {
+ testparser {{*}"a \n b"} 0
+} {- {{*}"a \n b"} 1 expand {{*}"a \n b"} 3 text {a } 0 backslash {\n} 0 text { b} 0 {}}
+
+test parse-6.1 {ParseTokens procedure, empty word} testparser {
+ testparser {""} 0
+} {- {""} 1 simple {""} 1 text {} 0 {}}
+test parse-6.2 {ParseTokens procedure, simple range} testparser {
+ testparser {"abc$x.e"} 0
+} {- {"abc$x.e"} 1 word {"abc$x.e"} 4 text abc 0 variable {$x} 1 text x 0 text .e 0 {}}
+test parse-6.3 {ParseTokens procedure, variable reference} testparser {
+ testparser {abc$x.e $y(z)} 0
+} {- {abc$x.e $y(z)} 2 word {abc$x.e} 4 text abc 0 variable {$x} 1 text x 0 text .e 0 word {$y(z)} 3 variable {$y(z)} 2 text y 0 text z 0 {}}
+test parse-6.4 {ParseTokens procedure, variable reference} testparser {
+ list [catch {testparser {$x([a )} 0} msg] $msg
+} {1 {missing close-bracket}}
+test parse-6.5 {ParseTokens procedure, command substitution} testparser {
+ testparser {[foo $x bar]z} 0
+} {- {[foo $x bar]z} 1 word {[foo $x bar]z} 2 command {[foo $x bar]} 0 text z 0 {}}
+test parse-6.6 {ParseTokens procedure, command substitution} testparser {
+ testparser {[foo \] [a b]]} 0
+} {- {[foo \] [a b]]} 1 word {[foo \] [a b]]} 1 command {[foo \] [a b]]} 0 {}}
+test parse-6.7 {ParseTokens procedure, error in command substitution} testparser {
+ list [catch {testparser {a [b {}c d] e} 0} msg] $msg $::errorInfo
+} {1 {extra characters after close-brace} {extra characters after close-brace
+ (remainder of script: "c d] e")
+ invoked from within
+"testparser {a [b {}c d] e} 0"}}
+test parse-6.8 {ParseTokens procedure, error in command substitution} {
+ info complete {a [b {}c d]}
+} {1}
+test parse-6.9 {ParseTokens procedure, error in command substitution} {
+ info complete {a [b "c d}
+} {0}
+test parse-6.10 {ParseTokens procedure, incomplete sub-command} {
+ info complete {puts [
+ expr 1+1
+ #this is a comment ]}
+} {0}
+test parse-6.11 {ParseTokens procedure, memory allocation for big nested command} testparser {
+ testparser {[$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b)]} 0
+} {- {[$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b)]} 1 word {[$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b)]} 1 command {[$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b)]} 0 {}}
+test parse-6.12 {ParseTokens procedure, missing close bracket} testparser {
+ list [catch {testparser {[foo $x bar} 0} msg] $msg $::errorInfo
+} {1 {missing close-bracket} {missing close-bracket
+ (remainder of script: "[foo $x bar")
+ invoked from within
+"testparser {[foo $x bar} 0"}}
+test parse-6.13 {ParseTokens procedure, backslash-newline without continuation line} testparser {
+ list [catch {testparser "\"a b\\\n" 0} msg] $msg $::errorInfo
+} {1 {missing "} missing\ \"\n\ \ \ \ (remainder\ of\ script:\ \"\"a\ b\\\n\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"\\\"a\ b\\\\\\n\"\ 0\"}
+test parse-6.14 {ParseTokens procedure, backslash-newline} testparser {
+ testparser "b\\\nc" 0
+} {- b\\\nc 2 simple b 1 text b 0 simple c 1 text c 0 {}}
+test parse-6.15 {ParseTokens procedure, backslash-newline} testparser {
+ testparser "\"b\\\nc\"" 0
+} {- \"b\\\nc\" 1 word \"b\\\nc\" 3 text b 0 backslash \\\n 0 text c 0 {}}
+test parse-6.16 {ParseTokens procedure, backslash substitution} testparser {
+ testparser {\n\a\x7f} 0
+} {- {\n\a\x7f} 1 word {\n\a\x7f} 3 backslash {\n} 0 backslash {\a} 0 backslash {\x7f} 0 {}}
+test parse-6.17 {ParseTokens procedure, null characters} testparser {
+ testparser [bytestring "foo\0zz"] 0
+} "- [bytestring foo\0zz] 1 word [bytestring foo\0zz] 3 text foo 0 text [bytestring \0] 0 text zz 0 {}"
+test parse-6.18 {ParseTokens procedure, seek past numBytes for close-bracket} testparser {
+ # Test for Bug 681841
+ list [catch {testparser {[a]} 2} msg] $msg
+} {1 {missing close-bracket}}
+
+test parse-7.1 {Tcl_FreeParse and ExpandTokenArray procedures} testparser {
+ testparser {$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) } 0
+} {- {$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) } 16 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 {}}
+
+test parse-8.1 {Tcl_EvalObjv procedure} testevalobjv {
+ testevalobjv 0 concat this is a test
+} {this is a test}
+test parse-8.2 {Tcl_EvalObjv procedure, unknown commands} testevalobjv {
+ rename ::unknown unknown.old
+ set x [catch {testevalobjv 10 asdf poiu} msg]
+ rename unknown.old ::unknown
+ list $x $msg
+} {1 {invalid command name "asdf"}}
+test parse-8.3 {Tcl_EvalObjv procedure, unknown commands} testevalobjv {
+ rename ::unknown unknown.old
+ proc ::unknown args {
+ return "unknown $args"
+ }
+ set x [catch {testevalobjv 0 asdf poiu} msg]
+ rename ::unknown {}
+ rename unknown.old ::unknown
+ list $x $msg
+} {0 {unknown asdf poiu}}
+test parse-8.4 {Tcl_EvalObjv procedure, unknown commands} testevalobjv {
+ rename ::unknown unknown.old
+ proc ::unknown args {
+ error "I don't like that command"
+ }
+ set x [catch {testevalobjv 0 asdf poiu} msg]
+ rename ::unknown {}
+ rename unknown.old ::unknown
+ list $x $msg
+} {1 {I don't like that command}}
+test parse-8.5 {Tcl_EvalObjv procedure, command traces} {testevalobjv testcmdtrace} {
+ testevalobjv 0 set x 123
+ testcmdtrace tracetest {testevalobjv 0 set x $x}
+} {{testevalobjv 0 set x $x} {testevalobjv 0 set x 123} {set x 123} {set x 123}}
+test parse-8.7 {Tcl_EvalObjv procedure, TCL_EVAL_GLOBAL flag} -constraints {
+ testevalobjv
+} -setup {
+ proc x {} {
+ set y 23
+ set z [testevalobjv 1 set y]
+ return [list $z $y]
+ }
+ set ::y 16
+} -cleanup {
+ unset ::y
+} -body {
+ x
+} -result {16 23}
+test parse-8.8 {Tcl_EvalObjv procedure, async handlers} -constraints {
+ testevalobjv testasync
+} -setup {
+ variable ::aresult
+ variable ::acode
+ proc async1 {result code} {
+ variable ::aresult
+ variable ::acode
+ set aresult $result
+ set acode $code
+ return "new result"
+ }
+ set handler1 [testasync create async1]
+ set aresult xxx
+ set acode yyy
+} -cleanup {
+ testasync delete
+} -body {
+ list [testevalobjv 0 testasync mark $handler1 original 0] $acode $aresult
+} -result {{new result} 0 original}
+test parse-8.9 {Tcl_EvalObjv procedure, exceptional return} testevalobjv {
+ list [catch {testevalobjv 0 error message} msg] $msg
+} {1 message}
+test parse-8.10 {Tcl_EvalObjv procedure, TCL_EVAL_GLOBAL} testevalobjv {
+ rename ::unknown unknown.save
+ proc ::unknown args {lappend ::info [info level]}
+ catch {rename ::noSuchCommand {}}
+ set ::info {}
+ namespace eval test_ns_1 {
+ testevalobjv 1 noSuchCommand
+ uplevel #0 noSuchCommand
+ }
+ namespace delete test_ns_1
+ rename ::unknown {}
+ rename unknown.save ::unknown
+ set ::info
+} {1 1}
+test parse-8.11 {Tcl_EvalObjv procedure, TCL_EVAL_INVOKE} testevalobjv {
+ rename ::unknown unknown.save
+ proc ::unknown args {lappend ::info [info level]; uplevel 1 foo}
+ proc ::foo args {lappend ::info global}
+ catch {rename ::noSuchCommand {}}
+ set ::slave [interp create]
+ $::slave alias bar noSuchCommand
+ set ::info {}
+ namespace eval test_ns_1 {
+ proc foo args {lappend ::info namespace}
+ $::slave eval bar
+ testevalobjv 1 [list $::slave eval bar]
+ uplevel #0 [list $::slave eval bar]
+ }
+ namespace delete test_ns_1
+ rename ::foo {}
+ rename ::unknown {}
+ rename unknown.save ::unknown
+ set ::info
+} [subst {[set level 2; incr level [info level]] global 1 global 1 global}]
+test parse-8.12 {Tcl_EvalObjv procedure, TCL_EVAL_INVOKE} {
+ set ::auto_index(noSuchCommand) {
+ proc noSuchCommand {} {lappend ::info global}
+ }
+ set ::auto_index(::[string trimleft [namespace current]::test_ns_1::noSuchCommand :]) [list \
+ proc [namespace current]::test_ns_1::noSuchCommand {} {
+ lappend ::info ns
+ }]
+ catch {rename ::noSuchCommand {}}
+ set ::slave [interp create]
+ $::slave alias bar noSuchCommand
+ set ::info {}
+ namespace eval test_ns_1 {
+ $::slave eval bar
+ }
+ namespace delete test_ns_1
+ interp delete $::slave
+ catch {rename ::noSuchCommand {}}
+ set ::info
+} global
+
+
+test parse-9.1 {Tcl_LogCommandInfo, line numbers} testevalex {
+ catch {unset x}
+ list [catch {testevalex {for {} 1 {} {
+
+
+ # asdf
+ set x
+ }}}] $::errorInfo
+} {1 {can't read "x": no such variable
+ while executing
+"set x"
+ ("for" body line 5)
+ invoked from within
+"for {} 1 {} {
+
+
+ # asdf
+ set x
+ }"
+ invoked from within
+"testevalex {for {} 1 {} {
+
+
+ # asdf
+ set x
+ }}"}}
+test parse-9.2 {Tcl_LogCommandInfo, truncating long commands} {
+ list [catch {set a b 111111111 222222222 333333333 444444444 555555555 666666666 777777777 888888888 999999999 000000000 aaaaaaaaa bbbbbbbbb ccccccccc ddddddddd eeeeeeeee fffffffff ggggggggg}] $::errorInfo
+} {1 {wrong # args: should be "set varName ?newValue?"
+ while executing
+"set a b 111111111 222222222 333333333 444444444 555555555 666666666 777777777 888888888 999999999 000000000 aaaaaaaaa bbbbbbbbb ccccccccc ddddddddd ee..."}}
+
+test parse-10.1 {Tcl_EvalTokens, simple text} testevalex {
+ testevalex {concat test}
+} {test}
+test parse-10.2 {Tcl_EvalTokens, backslash sequences} testevalex {
+ testevalex {concat test\063\062test}
+} {test32test}
+test parse-10.3 {Tcl_EvalTokens, nested commands} testevalex {
+ testevalex {concat [expr 2 + 6]}
+} {8}
+test parse-10.4 {Tcl_EvalTokens, nested commands} testevalex {
+ catch {unset a}
+ list [catch {testevalex {concat xxx[expr $a]}} msg] $msg
+} {1 {can't read "a": no such variable}}
+test parse-10.5 {Tcl_EvalTokens, simple variables} testevalex {
+ set a hello
+ testevalex {concat $a}
+} {hello}
+test parse-10.6 {Tcl_EvalTokens, array variables} testevalex {
+ catch {unset a}
+ set a(12) 46
+ testevalex {concat $a(12)}
+} {46}
+test parse-10.7 {Tcl_EvalTokens, array variables} testevalex {
+ catch {unset a}
+ set a(12) 46
+ testevalex {concat $a(1[expr 3 - 1])}
+} {46}
+test parse-10.8 {Tcl_EvalTokens, array variables} testevalex {
+ catch {unset a}
+ list [catch {testevalex {concat $x($a)}} msg] $msg
+} {1 {can't read "a": no such variable}}
+test parse-10.9 {Tcl_EvalTokens, array variables} testevalex {
+ catch {unset a}
+ list [catch {testevalex {concat xyz$a(1)}} msg] $msg
+} {1 {can't read "a(1)": no such variable}}
+test parse-10.10 {Tcl_EvalTokens, object values} testevalex {
+ set a 123
+ testevalex {concat $a}
+} {123}
+test parse-10.11 {Tcl_EvalTokens, object values} testevalex {
+ set a 123
+ testevalex {concat $a$a$a}
+} {123123123}
+test parse-10.12 {Tcl_EvalTokens, object values} testevalex {
+ testevalex {concat [expr 2][expr 4][expr 6]}
+} {246}
+test parse-10.13 {Tcl_EvalTokens, string values} testevalex {
+ testevalex {concat {a" b"}}
+} {a" b"}
+test parse-10.14 {Tcl_EvalTokens, string values} testevalex {
+ set a 111
+ testevalex {concat x$a.$a.$a}
+} {x111.111.111}
+
+test parse-11.1 {Tcl_EvalEx, TCL_EVAL_GLOBAL flag} -constraints {
+ testevalex
+} -setup {
+ proc x {} {
+ set y 777
+ set z [testevalex "set y" global]
+ return [list $z $y]
+ }
+ set ::y 321
+} -cleanup {
+ unset ::y
+} -body {
+ x
+} -result {321 777}
+test parse-11.2 {Tcl_EvalEx, error while parsing} testevalex {
+ list [catch {testevalex {concat "abc}} msg] $msg
+} {1 {missing "}}
+test parse-11.3 {Tcl_EvalEx, error while collecting words} testevalex {
+ catch {unset a}
+ list [catch {testevalex {concat xyz $a}} msg] $msg
+} {1 {can't read "a": no such variable}}
+test parse-11.4 {Tcl_EvalEx, error in Tcl_EvalObjv call} testevalex {
+ catch {unset a}
+ list [catch {testevalex {_bogus_ a b c d}} msg] $msg
+} {1 {invalid command name "_bogus_"}}
+test parse-11.5 {Tcl_EvalEx, exceptional return} testevalex {
+ list [catch {testevalex {break}} msg] $msg
+} {3 {}}
+test parse-11.6 {Tcl_EvalEx, freeing memory} testevalex {
+ testevalex {concat a b c d e f g h i j k l m n o p q r s t u v w x y z}
+} {a b c d e f g h i j k l m n o p q r s t u v w x y z}
+test parse-11.7 {Tcl_EvalEx, multiple commands in script} testevalex {
+ list [testevalex {set a b; set c d}] $a $c
+} {d b d}
+test parse-11.8 {Tcl_EvalEx, multiple commands in script} testevalex {
+ list [testevalex {
+ set a b
+ set c d
+ }] $a $c
+} {d b d}
+test parse-11.9 {Tcl_EvalEx, freeing memory after error} testevalex {
+ catch {unset a}
+ list [catch {testevalex {concat a b c d e f g h i j k l m n o p q r s t u v w x y z $a}} msg] $msg
+} {1 {can't read "a": no such variable}}
+test parse-11.10 {Tcl_EvalTokens, empty commands} testevalex {
+ testevalex {concat xyz; }
+} {xyz}
+test parse-11.11 {Tcl_EvalTokens, empty commands} testevalex {
+ testevalex "concat abc; ; # this is a comment\n"
+} {abc}
+test parse-11.12 {Tcl_EvalTokens, empty commands} testevalex {
+ testevalex {}
+} {}
+
+test parse-12.1 {Tcl_ParseVarName procedure, initialization} testparsevarname {
+ list [catch {testparsevarname {$a([first second])} 8 0} msg] $msg
+} {1 {missing close-bracket}}
+test parse-12.2 {Tcl_ParseVarName procedure, initialization} testparsevarname {
+ testparsevarname {$a([first second])} 0 0
+} {- {} 0 variable {$a([first second])} 2 text a 0 command {[first second]} 0 {}}
+test parse-12.3 {Tcl_ParseVarName procedure, initialization} testparsevarname {
+ list [catch {testparsevarname {$abcd} 3 0} msg] $msg
+} {0 {- {} 0 variable {$ab} 1 text ab 0 cd}}
+test parse-12.4 {Tcl_ParseVarName procedure, initialization} testparsevarname {
+ testparsevarname {$abcd} 0 0
+} {- {} 0 variable {$abcd} 1 text abcd 0 {}}
+test parse-12.5 {Tcl_ParseVarName procedure, just a dollar sign} testparsevarname {
+ testparsevarname {$abcd} 1 0
+} {- {} 0 text {$} 0 abcd}
+test parse-12.6 {Tcl_ParseVarName procedure, braced variable name} testparser {
+ testparser {${..[]b}cd} 0
+} {- {${..[]b}cd} 1 word {${..[]b}cd} 3 variable {${..[]b}} 1 text {..[]b} 0 text cd 0 {}}
+test parse-12.7 {Tcl_ParseVarName procedure, braced variable name} testparser {
+ testparser "\$\{\{\} " 0
+} {- \$\{\{\}\ 1 word \$\{\{\} 2 variable \$\{\{\} 1 text \{ 0 {}}
+test parse-12.8 {Tcl_ParseVarName procedure, missing close brace} testparser {
+ list [catch {testparser "$\{abc" 0} msg] $msg $::errorInfo
+} {1 {missing close-brace for variable name} missing\ close-brace\ for\ variable\ name\n\ \ \ \ (remainder\ of\ script:\ \"\{abc\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"\$\\\{abc\"\ 0\"}
+test parse-12.9 {Tcl_ParseVarName procedure, missing close brace} testparsevarname {
+ list [catch {testparsevarname {${bcd}} 4 0} msg] $msg
+} {1 {missing close-brace for variable name}}
+test parse-12.10 {Tcl_ParseVarName procedure, missing close brace} testparsevarname {
+ list [catch {testparsevarname {${bc}} 4 0} msg] $msg
+} {1 {missing close-brace for variable name}}
+test parse-12.11 {Tcl_ParseVarName procedure, simple variable name} testparser {
+ testparser {$az_AZ.} 0
+} {- {$az_AZ.} 1 word {$az_AZ.} 3 variable {$az_AZ} 1 text az_AZ 0 text . 0 {}}
+test parse-12.12 {Tcl_ParseVarName procedure, simple variable name} testparser {
+ testparser {$abcdefg} 4
+} {- {$abc} 1 word {$abc} 2 variable {$abc} 1 text abc 0 defg}
+test parse-12.13 {Tcl_ParseVarName procedure, simple variable name with ::} testparser {
+ testparser {$xyz::ab:c} 0
+} {- {$xyz::ab:c} 1 word {$xyz::ab:c} 3 variable {$xyz::ab} 1 text xyz::ab 0 text :c 0 {}}
+test parse-12.14 {Tcl_ParseVarName procedure, variable names with many colons} testparser {
+ testparser {$xyz:::::c} 0
+} {- {$xyz:::::c} 1 word {$xyz:::::c} 2 variable {$xyz:::::c} 1 text xyz:::::c 0 {}}
+test parse-12.15 {Tcl_ParseVarName procedure, : vs. ::} testparsevarname {
+ testparsevarname {$ab:cd} 0 0
+} {- {} 0 variable {$ab} 1 text ab 0 :cd}
+test parse-12.16 {Tcl_ParseVarName procedure, eof in ::} testparsevarname {
+ testparsevarname {$ab::cd} 4 0
+} {- {} 0 variable {$ab} 1 text ab 0 ::cd}
+test parse-12.17 {Tcl_ParseVarName procedure, eof in ::} testparsevarname {
+ testparsevarname {$ab:::cd} 5 0
+} {- {} 0 variable {$ab::} 1 text ab:: 0 :cd}
+test parse-12.18 {Tcl_ParseVarName procedure, no variable name} testparser {
+ testparser {$$ $.} 0
+} {- {$$ $.} 2 word {$$} 2 text {$} 0 text {$} 0 word {$.} 2 text {$} 0 text . 0 {}}
+test parse-12.19 {Tcl_ParseVarName procedure, EOF before (} testparsevarname {
+ testparsevarname {$ab(cd)} 3 0
+} {- {} 0 variable {$ab} 1 text ab 0 (cd)}
+test parse-12.20 {Tcl_ParseVarName procedure, array reference} testparser {
+ testparser {$x(abc)} 0
+} {- {$x(abc)} 1 word {$x(abc)} 3 variable {$x(abc)} 2 text x 0 text abc 0 {}}
+test parse-12.21 {Tcl_ParseVarName procedure, array reference} testparser {
+ testparser {$x(ab$cde[foo bar])} 0
+} {- {$x(ab$cde[foo bar])} 1 word {$x(ab$cde[foo bar])} 6 variable {$x(ab$cde[foo bar])} 5 text x 0 text ab 0 variable {$cde} 1 text cde 0 command {[foo bar]} 0 {}}
+test parse-12.22 {Tcl_ParseVarName procedure, array reference} testparser {
+ testparser {$x([cmd arg]zz)} 0
+} {- {$x([cmd arg]zz)} 1 word {$x([cmd arg]zz)} 4 variable {$x([cmd arg]zz)} 3 text x 0 command {[cmd arg]} 0 text zz 0 {}}
+test parse-12.23 {Tcl_ParseVarName procedure, missing close paren in array reference} testparser {
+ list [catch {testparser {$x(poiu} 0} msg] $msg $::errorInfo
+} {1 {missing )} {missing )
+ (remainder of script: "(poiu")
+ invoked from within
+"testparser {$x(poiu} 0"}}
+test parse-12.24 {Tcl_ParseVarName procedure, missing close paren in array reference} testparsevarname {
+ list [catch {testparsevarname {$ab(cd)} 6 0} msg] $msg $::errorInfo
+} {1 {missing )} {missing )
+ (remainder of script: "(cd)")
+ invoked from within
+"testparsevarname {$ab(cd)} 6 0"}}
+test parse-12.25 {Tcl_ParseVarName procedure, nested array reference} testparser {
+ testparser {$x(a$y(b$z))} 0
+} {- {$x(a$y(b$z))} 1 word {$x(a$y(b$z))} 8 variable {$x(a$y(b$z))} 7 text x 0 text a 0 variable {$y(b$z)} 4 text y 0 text b 0 variable {$z} 1 text z 0 {}}
+
+test parse-13.1 {Tcl_ParseVar procedure} testparsevar {
+ set abc 24
+ testparsevar {$abc.fg}
+} {24 .fg}
+test parse-13.2 {Tcl_ParseVar procedure, no variable name} testparsevar {
+ testparsevar {$}
+} {{$} {}}
+test parse-13.3 {Tcl_ParseVar procedure, no variable name} testparsevar {
+ testparsevar {$.123}
+} {{$} .123}
+test parse-13.4 {Tcl_ParseVar procedure, error looking up variable} testparsevar {
+ catch {unset abc}
+ list [catch {testparsevar {$abc}} msg] $msg
+} {1 {can't read "abc": no such variable}}
+test parse-13.5 {Tcl_ParseVar procedure, error looking up variable} testparsevar {
+ catch {unset abc}
+ list [catch {testparsevar {$abc([bogus x y z])}} msg] $msg
+} {1 {invalid command name "bogus"}}
+
+test parse-14.1 {Tcl_ParseBraces procedure, computing string length} testparser {
+ testparser [bytestring "foo\0 bar"] -1
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-14.2 {Tcl_ParseBraces procedure, computing string length} testparser {
+ testparser "foo bar" -1
+} {- {foo bar} 2 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
+test parse-14.3 {Tcl_ParseBraces procedure, words in braces} testparser {
+ testparser {foo {a $b [concat foo]} {c d}} 0
+} {- {foo {a $b [concat foo]} {c d}} 3 simple foo 1 text foo 0 simple {{a $b [concat foo]}} 1 text {a $b [concat foo]} 0 simple {{c d}} 1 text {c d} 0 {}}
+test parse-14.4 {Tcl_ParseBraces procedure, empty nested braces} testparser {
+ testparser {foo {{}}} 0
+} {- {foo {{}}} 2 simple foo 1 text foo 0 simple {{{}}} 1 text {{}} 0 {}}
+test parse-14.5 {Tcl_ParseBraces procedure, nested braces} testparser {
+ testparser {foo {{a {b} c} {} {d e}}} 0
+} {- {foo {{a {b} c} {} {d e}}} 2 simple foo 1 text foo 0 simple {{{a {b} c} {} {d e}}} 1 text {{a {b} c} {} {d e}} 0 {}}
+test parse-14.6 {Tcl_ParseBraces procedure, backslashes in words in braces} testparser {
+ testparser "foo {a \\n\\\{}" 0
+} {- {foo {a \n\{}} 2 simple foo 1 text foo 0 simple {{a \n\{}} 1 text {a \n\{} 0 {}}
+test parse-14.7 {Tcl_ParseBraces procedure, missing continuation line in braces} testparser {
+ list [catch {testparser "\{abc\\\n" 0} msg] $msg $::errorInfo
+} {1 {missing close-brace} missing\ close-brace\n\ \ \ \ (remainder\ of\ script:\ \"\{abc\\\n\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"\\\{abc\\\\\\n\"\ 0\"}
+test parse-14.8 {Tcl_ParseBraces procedure, backslash-newline in braces} testparser {
+ testparser "foo {\\\nx}" 0
+} {- foo\ \{\\\nx\} 2 simple foo 1 text foo 0 word \{\\\nx\} 2 backslash \\\n 0 text x 0 {}}
+test parse-14.9 {Tcl_ParseBraces procedure, backslash-newline in braces} testparser {
+ testparser "foo {a \\\n b}" 0
+} {- foo\ \{a\ \\\n\ \ \ b\} 2 simple foo 1 text foo 0 word \{a\ \\\n\ \ \ b\} 3 text {a } 0 backslash \\\n\ \ \ 0 text b 0 {}}
+test parse-14.10 {Tcl_ParseBraces procedure, backslash-newline in braces} testparser {
+ testparser "foo {xyz\\\n }" 0
+} {- foo\ \{xyz\\\n\ \} 2 simple foo 1 text foo 0 word \{xyz\\\n\ \} 2 text xyz 0 backslash \\\n\ 0 {}}
+test parse-14.11 {Tcl_ParseBraces procedure, empty braced string} testparser {
+ testparser {foo {}} 0
+} {- {foo {}} 2 simple foo 1 text foo 0 simple {{}} 1 text {} 0 {}}
+test parse-14.12 {Tcl_ParseBraces procedure, missing close brace} testparser {
+ list [catch {testparser "foo \{xy\\\nz" 0} msg] $msg $::errorInfo
+} {1 {missing close-brace} missing\ close-brace\n\ \ \ \ (remainder\ of\ script:\ \"\{xy\\\nz\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"foo\ \\\{xy\\\\\\nz\"\ 0\"}
+
+test parse-15.1 {Tcl_ParseQuotedString procedure, computing string length} testparser {
+ testparser [bytestring "foo\0 bar"] -1
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-15.2 {Tcl_ParseQuotedString procedure, computing string length} testparser {
+ testparser "foo bar" -1
+} {- {foo bar} 2 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
+test parse-15.3 {Tcl_ParseQuotedString procedure, word is quoted string} testparser {
+ testparser {foo "a b c" d "efg";} 0
+} {- {foo "a b c" d "efg";} 4 simple foo 1 text foo 0 simple {"a b c"} 1 text {a b c} 0 simple d 1 text d 0 simple {"efg"} 1 text efg 0 {}}
+test parse-15.4 {Tcl_ParseQuotedString procedure, garbage after quoted string} testparser {
+ list [catch {testparser {foo "a b c"d} 0} msg] $msg $::errorInfo
+} {1 {extra characters after close-quote} {extra characters after close-quote
+ (remainder of script: "d")
+ invoked from within
+"testparser {foo "a b c"d} 0"}}
+
+test parse-15.5 {CommandComplete procedure} {
+ info complete ""
+} 1
+test parse-15.6 {CommandComplete procedure} {
+ info complete " \n"
+} 1
+test parse-15.7 {CommandComplete procedure} {
+ info complete "abc def"
+} 1
+test parse-15.8 {CommandComplete procedure} {
+ info complete "a b c d e f \t\n"
+} 1
+test parse-15.9 {CommandComplete procedure} {
+ info complete {a b c"d}
+} 1
+test parse-15.10 {CommandComplete procedure} {
+ info complete {a b "c d" e}
+} 1
+test parse-15.11 {CommandComplete procedure} {
+ info complete {a b "c d"}
+} 1
+test parse-15.12 {CommandComplete procedure} {
+ info complete {a b "c d"}
+} 1
+test parse-15.13 {CommandComplete procedure} {
+ info complete {a b "c d}
+} 0
+test parse-15.14 {CommandComplete procedure} {
+ info complete {a b "}
+} 0
+test parse-15.15 {CommandComplete procedure} {
+ info complete {a b "cd"xyz}
+} 1
+test parse-15.16 {CommandComplete procedure} {
+ info complete {a b "c $d() d"}
+} 1
+test parse-15.17 {CommandComplete procedure} {
+ info complete {a b "c $dd("}
+} 0
+test parse-15.18 {CommandComplete procedure} {
+ info complete {a b "c \"}
+} 0
+test parse-15.19 {CommandComplete procedure} {
+ info complete {a b "c [d e f]"}
+} 1
+test parse-15.20 {CommandComplete procedure} {
+ info complete {a b "c [d e f] g"}
+} 1
+test parse-15.21 {CommandComplete procedure} {
+ info complete {a b "c [d e f"}
+} 0
+test parse-15.22 {CommandComplete procedure} {
+ info complete {a {b c d} e}
+} 1
+test parse-15.23 {CommandComplete procedure} {
+ info complete {a {b c d}}
+} 1
+test parse-15.24 {CommandComplete procedure} {
+ info complete "a b\{c d"
+} 1
+test parse-15.25 {CommandComplete procedure} {
+ info complete "a b \{c"
+} 0
+test parse-15.26 {CommandComplete procedure} {
+ info complete "a b \{c{ }"
+} 0
+test parse-15.27 {CommandComplete procedure} {
+ info complete "a b {c d e}xxx"
+} 1
+test parse-15.28 {CommandComplete procedure} {
+ info complete "a b {c \\\{d e}xxx"
+} 1
+test parse-15.29 {CommandComplete procedure} {
+ info complete {a b [ab cd ef]}
+} 1
+test parse-15.30 {CommandComplete procedure} {
+ info complete {a b x[ab][cd][ef] gh}
+} 1
+test parse-15.31 {CommandComplete procedure} {
+ info complete {a b x[ab][cd[ef] gh}
+} 0
+test parse-15.32 {CommandComplete procedure} {
+ info complete {a b x[ gh}
+} 0
+test parse-15.33 {CommandComplete procedure} {
+ info complete {[]]]}
+} 1
+test parse-15.34 {CommandComplete procedure} {
+ info complete {abc x$yyy}
+} 1
+test parse-15.35 {CommandComplete procedure} {
+ info complete "abc x\${abc\[\\d} xyz"
+} 1
+test parse-15.36 {CommandComplete procedure} {
+ info complete "abc x\$\{ xyz"
+} 0
+test parse-15.37 {CommandComplete procedure} {
+ info complete {word $a(xyz)}
+} 1
+test parse-15.38 {CommandComplete procedure} {
+ info complete {word $a(}
+} 0
+test parse-15.39 {CommandComplete procedure} {
+ info complete "set a \\\n"
+} 0
+test parse-15.40 {CommandComplete procedure} {
+ info complete "set a \\\\\n"
+} 1
+test parse-15.41 {CommandComplete procedure} {
+ info complete "set a \\n "
+} 1
+test parse-15.42 {CommandComplete procedure} {
+ info complete "set a \\"
+} 1
+test parse-15.43 {CommandComplete procedure} {
+ info complete "foo \\\n\{"
+} 0
+test parse-15.44 {CommandComplete procedure} {
+ info complete "a\nb\n# \{\n# \{\nc\n"
+} 1
+test parse-15.45 {CommandComplete procedure} {
+ info complete "#Incomplete comment\\\n"
+} 0
+test parse-15.46 {CommandComplete procedure} {
+ info complete "#Incomplete comment\\\nBut now it's complete.\n"
+} 1
+test parse-15.47 {CommandComplete procedure} {
+ info complete "# Complete comment\\\\\n"
+} 1
+test parse-15.48 {CommandComplete procedure} {
+ info complete "abc\\\n def"
+} 1
+test parse-15.49 {CommandComplete procedure} {
+ info complete "abc\\\n "
+} 1
+test parse-15.50 {CommandComplete procedure} {
+ info complete "abc\\\n"
+} 0
+test parse-15.51 {CommandComplete procedure} "
+ info complete \"\\\{abc\\\}\\\{\"
+" 1
+test parse-15.52 {CommandComplete procedure} {
+ info complete "\"abc\"("
+} 1
+test parse-15.53 {CommandComplete procedure} "
+ info complete \" # \{\"
+" 1
+test parse-15.54 {CommandComplete procedure} "
+ info complete \"foo bar;# \{\"
+" 1
+test parse-15.55 {CommandComplete procedure} {
+ info complete "set x [bytestring \0]; puts hi"
+} 1
+test parse-15.56 {CommandComplete procedure} {
+ info complete "set x [bytestring \0]; \{"
+} 0
+test parse-15.57 {CommandComplete procedure} {
+ info complete "# Comment should be complete command"
+} 1
+test parse-15.58 {CommandComplete procedure, memory leaks} {
+ info complete "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22"
+} 1
+test parse-15.59 {CommandComplete procedure} {
+ # Test for Tcl Bug 684744
+ info complete [encoding convertfrom identity "\x00;if 1 \{"]
+} 0
+test parse-15.60 {CommandComplete procedure} {
+ # Test for Tcl Bug 1968882
+ info complete \\\n
+} 0
+
+test parse-16.1 {Bug 218885 (Scriptics bug 2535)} {
+ subst {[eval {return foo}]bar}
+} foobar
+
+test parse-17.1 {Correct return codes from errors during substitution} {
+ catch {eval {w[continue]}}
+} 4
+
+test parse-18.1 {Tcl_SubstObj, ParseTokens flags} {
+ subst {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo $::tcl_library $::tcl_library"
+test parse-18.2 {Tcl_SubstObj, ParseTokens flags} {
+ subst -nocommands {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo $::tcl_library \[set ::tcl_library]"
+test parse-18.3 {Tcl_SubstObj, ParseTokens flags} {
+ subst -novariables {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo \$::tcl_library $::tcl_library"
+test parse-18.4 {Tcl_SubstObj, ParseTokens flags} {
+ subst -nobackslashes {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo\\t$::tcl_library\\t$::tcl_library"
+test parse-18.5 {Tcl_SubstObj, ParseTokens flags} {
+ subst -novariables -nobackslashes {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo\\t\$::tcl_library\\t$::tcl_library"
+test parse-18.6 {Tcl_SubstObj, ParseTokens flags} {
+ subst -nocommands -nobackslashes {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo\\t$::tcl_library\\t\[set ::tcl_library]"
+test parse-18.7 {Tcl_SubstObj, ParseTokens flags} {
+ subst -nocommands -novariables {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo \$::tcl_library \[set ::tcl_library]"
+test parse-18.8 {Tcl_SubstObj, ParseTokens flags} {
+ subst -nocommands -novariables -nobackslashes \
+ {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo\\t\$::tcl_library\\t\[set ::tcl_library]"
+
+test parse-18.9 {Tcl_SubstObj, parse errors} {
+ list [catch "subst foo\$\{foo" msg] $msg
+} [list 1 "missing close-brace for variable name"]
+test parse-18.10 {Tcl_SubstObj, parse errors} {
+ list [catch "subst foo\[set \$\{foo]" msg] $msg
+} [list 1 "missing close-brace for variable name"]
+test parse-18.11 {Tcl_SubstObj, parse errors} {
+ list [catch "subst foo\$array(\$\{foo)" msg] $msg
+} [list 1 "missing close-brace for variable name"]
+test parse-18.12 {Tcl_SubstObj, parse errors} {
+ list [catch "subst foo\$(\$\{foo)" msg] $msg
+} [list 1 "missing close-brace for variable name"]
+test parse-18.13 {Tcl_SubstObj, parse errors} {
+ list [catch "subst \[" msg] $msg
+} [list 1 "missing close-bracket"]
+
+test parse-18.14 {Tcl_SubstObj, exception handling} {
+ subst {abc,[break],def}
+} {abc,}
+test parse-18.15 {Tcl_SubstObj, exception handling} {
+ subst {abc,[continue; expr 1+2],def}
+} {abc,,def}
+test parse-18.16 {Tcl_SubstObj, exception handling} {
+ subst {abc,[return foo; expr 1+2],def}
+} {abc,foo,def}
+test parse-18.17 {Tcl_SubstObj, exception handling} {
+ subst {abc,[return -code 10 foo; expr 1+2],def}
+} {abc,foo,def}
+test parse-18.18 {Tcl_SubstObj, exception handling} {
+ subst {abc,[break; set {} {}{}],def}
+} {abc,}
+test parse-18.19 {Tcl_SubstObj, exception handling} {
+ list [catch {subst {abc,[continue; expr 1+2; set {} {}{}],def}} msg] $msg
+} [list 1 "extra characters after close-brace"]
+test parse-18.20 {Tcl_SubstObj, exception handling} {
+ list [catch {subst {abc,[return foo; expr 1+2; set {} {}{}],def}} msg] $msg
+} [list 1 "extra characters after close-brace"]
+test parse-18.21 {Tcl_SubstObj, exception handling} {
+ list [catch {
+ subst {abc,[return -code 10 foo; expr 1+2; set {} {}{}],def}
+ } msg] $msg
+} [list 1 "extra characters after close-brace"]
+
+test parse-18.22 {Tcl_SubstObj, side effects} {
+ set a 0
+ list [subst {foo[incr a]bar}] $a
+} [list foo1bar 1]
+test parse-18.23 {Tcl_SubstObj, side effects} {
+ set a 0
+ list [subst {foo[incr a; incr a]bar}] $a
+} [list foo2bar 2]
+test parse-18.24 {Tcl_SubstObj, side effects} {
+ set a 0
+ list [subst {foo[incr a; break; incr a]bar}] $a
+} [list foo 1]
+test parse-18.25 {Tcl_SubstObj, side effects} {
+ set a 0
+ list [subst {foo[incr a; continue; incr a]bar}] $a
+} [list foobar 1]
+test parse-18.26 {Tcl_SubstObj, side effects} {
+ set a 0
+ list [subst {foo[incr a; return; incr a]bar}] $a
+} [list foobar 1]
+test parse-18.27 {Tcl_SubstObj, side effects} {
+ set a 0
+ list [subst {foo[incr a; return -code 10; incr a]bar}] $a
+} [list foobar 1]
+test parse-18.28 {Tcl_SubstObj, side effects} {
+ set a 0
+ catch {subst {foo[incr a; parse error {}{}; incr a]bar}}
+ set a
+} 1
+test parse-18.29 {Tcl_SubstObj, side effects} {
+ set a 0
+ catch {subst {foo[incr a; incr a; parse error {}{}]bar}}
+ set a
+} 2
+test parse-18.30 {Tcl_SubstObj, side effects} {
+ set a 0
+ catch {subst {foo[incr a; incr a parse error {}{}]bar}}
+ set a
+} 1
+
+test parse-19.1 {Bug 1115904: recursion limit in Tcl_EvalEx} -constraints {
+ testevalex
+} -setup {
+ interp create i
+ load {} Tcltest i
+ i eval {proc {} args {}}
+ interp recursionlimit i 3
+} -body {
+ i eval {testevalex {[]}}
+} -cleanup {
+ interp delete i
+}
+
+test parse-19.2 {Bug 1115904: recursion limit in Tcl_EvalEx} -constraints {
+ testevalex
+} -setup {
+ interp create i
+ load {} Tcltest i
+ i eval {proc {} args {}}
+ interp recursionlimit i 2
+} -body {
+ i eval {testevalex {[[]]}}
+} -cleanup {
+ interp delete i
+} -returnCodes error -match glob -result {too many nested*}
+
+test parse-19.3 {Bug 1115904: recursion limit in Tcl_EvalEx} emptyTest {
+ # Test no longer valid in Tcl 8.6
+} {}
+test parse-19.4 {Bug 1115904: recursion limit in Tcl_EvalEx} emptyTest {
+ # Test no longer valid in Tcl 8.6
+} {}
+
+test parse-20.1 {TclParseBackslash: truncated escape} testparser {
+ testparser {\u12345} 1
+} {- \\ 1 simple \\ 1 text \\ 0 u12345}
+test parse-20.2 {TclParseBackslash: truncated escape} testparser {
+ testparser {\u12345} 2
+} {- {\u} 1 word {\u} 1 backslash {\u} 0 12345}
+test parse-20.3 {TclParseBackslash: truncated escape} testparser {
+ testparser {\u12345} 3
+} {- {\u1} 1 word {\u1} 1 backslash {\u1} 0 2345}
+test parse-20.4 {TclParseBackslash: truncated escape} testparser {
+ testparser {\u12345} 4
+} {- {\u12} 1 word {\u12} 1 backslash {\u12} 0 345}
+test parse-20.5 {TclParseBackslash: truncated escape} testparser {
+ testparser {\u12345} 5
+} {- {\u123} 1 word {\u123} 1 backslash {\u123} 0 45}
+test parse-20.6 {TclParseBackslash: truncated escape} testparser {
+ testparser {\u12345} 6
+} {- {\u1234} 1 word {\u1234} 1 backslash {\u1234} 0 5}
+test parse-20.7 {TclParseBackslash: truncated escape} testparser {
+ testparser {\u12345} 7
+} {- {\u12345} 1 word {\u12345} 2 backslash {\u1234} 0 text 5 0 {}}
+
+test parse-20.8 {TclParseBackslash: truncated escape} testparser {
+ testparser {\x12X} 1
+} {- \\ 1 simple \\ 1 text \\ 0 x12X}
+test parse-20.9 {TclParseBackslash: truncated escape} testparser {
+ testparser {\x12X} 2
+} {- {\x} 1 word {\x} 1 backslash {\x} 0 12X}
+test parse-20.10 {TclParseBackslash: truncated escape} testparser {
+ testparser {\x12X} 3
+} {- {\x1} 1 word {\x1} 1 backslash {\x1} 0 2X}
+test parse-20.11 {TclParseBackslash: truncated escape} testparser {
+ testparser {\x12X} 4
+} {- {\x12} 1 word {\x12} 1 backslash {\x12} 0 X}
+test parse-20.12 {TclParseBackslash: truncated escape} testparser {
+ testparser {\x12X} 5
+} {- {\x12X} 1 word {\x12X} 2 backslash {\x12} 0 text X 0 {}}
+
+cleanupTests
+}
+
+namespace delete ::tcl::test::parse
+return
diff --git a/library/msgcat/tests/parseExpr.test b/library/msgcat/tests/parseExpr.test
new file mode 100644
index 0000000..cd0342a
--- /dev/null
+++ b/library/msgcat/tests/parseExpr.test
@@ -0,0 +1,1068 @@
+# This file contains a collection of tests for the procedures in the
+# file tclCompExpr.c. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Note that the Tcl expression parser (tclCompExpr.c) does not check
+# the semantic validity of the expressions it parses. It does not check,
+# for example, that a math function actually exists, or that the operands
+# of "<<" are integers.
+
+testConstraint testexprparser [llength [info commands testexprparser]]
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+ variable ieeeValues
+ binary scan [binary format dd -1.0 1.0] c* c
+ switch -exact -- $c {
+ {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+ # little endian
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+ ieeeValues(-Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+ ieeeValues(-Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+ ieeeValues(-Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+ ieeeValues(+Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+ ieeeValues(+Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 1
+ return 1
+ }
+ {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+ binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Infinity)
+ binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Normal)
+ binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Subnormal)
+ binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Normal)
+ binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Infinity)
+ binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 0
+ return 1
+ }
+ default {
+ return 0
+ }
+ }
+}
+testConstraint ieeeFloatingPoint [testIEEE]
+
+######################################################################
+
+test parseExpr-1.1 {Tcl_ParseExpr procedure, computing string length} testexprparser {
+ testexprparser [bytestring "1+2\0 +3"] -1
+} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-1.2 {Tcl_ParseExpr procedure, computing string length} testexprparser {
+ testexprparser "1 + 2" -1
+} {- {} 0 subexpr {1 + 2} 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-1.3 {Tcl_ParseExpr procedure, error getting initial lexeme} testexprparser {
+ testexprparser 12345678901234567890 -1
+} {- {} 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-1.4 {Tcl_ParseExpr procedure, error in conditional expression} \
+ -constraints testexprparser -body {
+ testexprparser {foo+} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-1.5 {Tcl_ParseExpr procedure, lexemes after the expression} -constraints testexprparser -body {
+ testexprparser {1+2 345} -1
+} -returnCodes error -match glob -result *
+
+test parseExpr-2.1 {ParseCondExpr procedure, valid test subexpr} testexprparser {
+ testexprparser {2>3? 1 : 0} -1
+} {- {} 0 subexpr {2>3? 1 : 0} 11 operator ? 0 subexpr 2>3 5 operator > 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-2.2 {ParseCondExpr procedure, error in test subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {0 || foo} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-2.3 {ParseCondExpr procedure, next lexeme isn't "?"} testexprparser {
+ testexprparser {1+2} -1
+} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-2.4 {ParseCondExpr procedure, next lexeme is "?"} testexprparser {
+ testexprparser {1+2 ? 3 : 4} -1
+} {- {} 0 subexpr {1+2 ? 3 : 4} 11 operator ? 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-2.5 {ParseCondExpr procedure, bad lexeme after "?"} testexprparser {
+ testexprparser {1+2 ? 12345678901234567890 : 0} -1
+} {- {} 0 subexpr {1+2 ? 12345678901234567890 : 0} 11 operator ? 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-2.6 {ParseCondExpr procedure, valid "then" subexpression} testexprparser {
+ testexprparser {1? 3 : 4} -1
+} {- {} 0 subexpr {1? 3 : 4} 7 operator ? 0 subexpr 1 1 text 1 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-2.7 {ParseCondExpr procedure, error in "then" subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1? fred : martha} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-2.8 {ParseCondExpr procedure, lexeme after "then" subexpr isn't ":"} -constraints testexprparser -body {
+ testexprparser {1? 2 martha 3} -1
+} -returnCodes error -match glob -result *
+test parseExpr-2.9 {ParseCondExpr procedure, valid "else" subexpression} testexprparser {
+ testexprparser {27||3? 3 : 4&&9} -1
+} {- {} 0 subexpr {27||3? 3 : 4&&9} 15 operator ? 0 subexpr 27||3 5 operator || 0 subexpr 27 1 text 27 0 subexpr 3 1 text 3 0 subexpr 3 1 text 3 0 subexpr 4&&9 5 operator && 0 subexpr 4 1 text 4 0 subexpr 9 1 text 9 0 {}}
+test parseExpr-2.10 {ParseCondExpr procedure, error in "else" subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1? 2 : martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-3.1 {ParseLorExpr procedure, valid logical and subexpr} testexprparser {
+ testexprparser {1&&2 || 3} -1
+} {- {} 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-3.2 {ParseLorExpr procedure, error in logical and subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1&&foo || 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-3.3 {ParseLorExpr procedure, next lexeme isn't "||"} testexprparser {
+ testexprparser {1&&2? 1 : 0} -1
+} {- {} 0 subexpr {1&&2? 1 : 0} 11 operator ? 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-3.4 {ParseLorExpr procedure, next lexeme is "||"} testexprparser {
+ testexprparser {1&&2 || 3} -1
+} {- {} 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-3.5 {ParseLorExpr procedure, bad lexeme after "||"} testexprparser {
+ testexprparser {1&&2 || 12345678901234567890} -1
+} {- {} 0 subexpr {1&&2 || 12345678901234567890} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-3.6 {ParseLorExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1&&2 || 3 || 4} -1
+} {- {} 0 subexpr {1&&2 || 3 || 4} 13 operator || 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-3.7 {ParseLorExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1&&2 || 3 || martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-4.1 {ParseLandExpr procedure, valid LHS "|" subexpr} testexprparser {
+ testexprparser {1|2 && 3} -1
+} {- {} 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-4.2 {ParseLandExpr procedure, error in LHS "|" subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1&&foo && 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-4.3 {ParseLandExpr procedure, next lexeme isn't "&&"} testexprparser {
+ testexprparser {1|2? 1 : 0} -1
+} {- {} 0 subexpr {1|2? 1 : 0} 11 operator ? 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-4.4 {ParseLandExpr procedure, next lexeme is "&&"} testexprparser {
+ testexprparser {1|2 && 3} -1
+} {- {} 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-4.5 {ParseLandExpr procedure, bad lexeme after "&&"} testexprparser {
+ testexprparser {1|2 && 12345678901234567890} -1
+} {- {} 0 subexpr {1|2 && 12345678901234567890} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-4.6 {ParseLandExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1|2 && 3 && 4} -1
+} {- {} 0 subexpr {1|2 && 3 && 4} 13 operator && 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-4.7 {ParseLandExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1|2 && 3 && martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-5.1 {ParseBitOrExpr procedure, valid LHS "^" subexpr} testexprparser {
+ testexprparser {1^2 | 3} -1
+} {- {} 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-5.2 {ParseBitOrExpr procedure, error in LHS "^" subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1|foo | 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-5.3 {ParseBitOrExpr procedure, next lexeme isn't "|"} testexprparser {
+ testexprparser {1^2? 1 : 0} -1
+} {- {} 0 subexpr {1^2? 1 : 0} 11 operator ? 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-5.4 {ParseBitOrExpr procedure, next lexeme is "|"} testexprparser {
+ testexprparser {1^2 | 3} -1
+} {- {} 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-5.5 {ParseBitOrExpr procedure, bad lexeme after "|"} testexprparser {
+ testexprparser {1^2 | 12345678901234567890} -1
+} {- {} 0 subexpr {1^2 | 12345678901234567890} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-5.6 {ParseBitOrExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1^2 | 3 | 4} -1
+} {- {} 0 subexpr {1^2 | 3 | 4} 13 operator | 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-5.7 {ParseBitOrExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1^2 | 3 | martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-6.1 {ParseBitXorExpr procedure, valid LHS "&" subexpr} testexprparser {
+ testexprparser {1&2 ^ 3} -1
+} {- {} 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-6.2 {ParseBitXorExpr procedure, error in LHS "&" subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1^foo ^ 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-6.3 {ParseBitXorExpr procedure, next lexeme isn't "^"} testexprparser {
+ testexprparser {1&2? 1 : 0} -1
+} {- {} 0 subexpr {1&2? 1 : 0} 11 operator ? 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-6.4 {ParseBitXorExpr procedure, next lexeme is "^"} testexprparser {
+ testexprparser {1&2 ^ 3} -1
+} {- {} 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-6.5 {ParseBitXorExpr procedure, bad lexeme after "^"} testexprparser {
+ testexprparser {1&2 ^ 12345678901234567890} -1
+} {- {} 0 subexpr {1&2 ^ 12345678901234567890} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-6.6 {ParseBitXorExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1&2 ^ 3 ^ 4} -1
+} {- {} 0 subexpr {1&2 ^ 3 ^ 4} 13 operator ^ 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-6.7 {ParseBitXorExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1&2 ^ 3 ^ martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-7.1 {ParseBitAndExpr procedure, valid LHS equality subexpr} testexprparser {
+ testexprparser {1==2 & 3} -1
+} {- {} 0 subexpr {1==2 & 3} 9 operator & 0 subexpr 1==2 5 operator == 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-7.2 {ParseBitAndExpr procedure, error in LHS equality subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1!=foo & 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-7.3 {ParseBitAndExpr procedure, next lexeme isn't "&"} testexprparser {
+ testexprparser {1==2? 1 : 0} -1
+} {- {} 0 subexpr {1==2? 1 : 0} 11 operator ? 0 subexpr 1==2 5 operator == 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-7.4 {ParseBitAndExpr procedure, next lexeme is "&"} testexprparser {
+ testexprparser {1>2 & 3} -1
+} {- {} 0 subexpr {1>2 & 3} 9 operator & 0 subexpr 1>2 5 operator > 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-7.5 {ParseBitAndExpr procedure, bad lexeme after "&"} {testexprparser} {
+ testexprparser {1==2 & 12345678901234567890} -1
+} {- {} 0 subexpr {1==2 & 12345678901234567890} 9 operator & 0 subexpr 1==2 5 operator == 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-7.6 {ParseBitAndExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1<2 & 3 & 4} -1
+} {- {} 0 subexpr {1<2 & 3 & 4} 13 operator & 0 subexpr {1<2 & 3} 9 operator & 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-7.7 {ParseBitAndExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1==2 & 3>2 & martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-8.1 {ParseEqualityExpr procedure, valid LHS relational subexpr} testexprparser {
+ testexprparser {1<2 == 3} -1
+} {- {} 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-8.2 {ParseEqualityExpr procedure, error in LHS relational subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1>=foo == 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-8.3 {ParseEqualityExpr procedure, next lexeme isn't "==" or "!="} testexprparser {
+ testexprparser {1<2? 1 : 0} -1
+} {- {} 0 subexpr {1<2? 1 : 0} 11 operator ? 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-8.4 {ParseEqualityExpr procedure, next lexeme is "==" or "!="} testexprparser {
+ testexprparser {1<2 == 3} -1
+} {- {} 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-8.5 {ParseEqualityExpr procedure, next lexeme is "==" or "!="} testexprparser {
+ testexprparser {1<2 != 3} -1
+} {- {} 0 subexpr {1<2 != 3} 9 operator != 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-8.6 {ParseEqualityExpr procedure, bad lexeme after "==" or "!="} testexprparser {
+ testexprparser {1<2 == 12345678901234567890} -1
+} {- {} 0 subexpr {1<2 == 12345678901234567890} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-8.7 {ParseEqualityExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1<2 == 3 == 4} -1
+} {- {} 0 subexpr {1<2 == 3 == 4} 13 operator == 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-8.8 {ParseEqualityExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1<2 == 3 != martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-9.1 {ParseRelationalExpr procedure, valid LHS shift subexpr} testexprparser {
+ testexprparser {1<<2 < 3} -1
+} {- {} 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-9.2 {ParseRelationalExpr procedure, error in LHS shift subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1>=foo < 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-9.3 {ParseRelationalExpr procedure, next lexeme isn't relational op} testexprparser {
+ testexprparser {1<<2? 1 : 0} -1
+} {- {} 0 subexpr {1<<2? 1 : 0} 11 operator ? 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-9.4 {ParseRelationalExpr procedure, next lexeme is relational op} testexprparser {
+ testexprparser {1<<2 < 3} -1
+} {- {} 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-9.5 {ParseRelationalExpr procedure, next lexeme is relational op} testexprparser {
+ testexprparser {1>>2 > 3} -1
+} {- {} 0 subexpr {1>>2 > 3} 9 operator > 0 subexpr 1>>2 5 operator >> 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-9.6 {ParseRelationalExpr procedure, next lexeme is relational op} testexprparser {
+ testexprparser {1<<2 <= 3} -1
+} {- {} 0 subexpr {1<<2 <= 3} 9 operator <= 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-9.7 {ParseRelationalExpr procedure, next lexeme is relational op} testexprparser {
+ testexprparser {1<<2 >= 3} -1
+} {- {} 0 subexpr {1<<2 >= 3} 9 operator >= 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-9.8 {ParseRelationalExpr procedure, bad lexeme after relational op} testexprparser {
+ testexprparser {1<<2 < 12345678901234567890} -1
+} {- {} 0 subexpr {1<<2 < 12345678901234567890} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-9.9 {ParseRelationalExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1<<2 < 3 < 4} -1
+} {- {} 0 subexpr {1<<2 < 3 < 4} 13 operator < 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-9.10 {ParseRelationalExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1<<2 < 3 > martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-10.1 {ParseShiftExpr procedure, valid LHS add subexpr} testexprparser {
+ testexprparser {1+2 << 3} -1
+} {- {} 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-10.2 {ParseShiftExpr procedure, error in LHS add subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1-foo << 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-10.3 {ParseShiftExpr procedure, next lexeme isn't "<<" or ">>"} testexprparser {
+ testexprparser {1+2? 1 : 0} -1
+} {- {} 0 subexpr {1+2? 1 : 0} 11 operator ? 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-10.4 {ParseShiftExpr procedure, next lexeme is "<<" or ">>"} testexprparser {
+ testexprparser {1+2 << 3} -1
+} {- {} 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-10.5 {ParseShiftExpr procedure, next lexeme is "<<" or ">>"} testexprparser {
+ testexprparser {1+2 >> 3} -1
+} {- {} 0 subexpr {1+2 >> 3} 9 operator >> 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-10.6 {ParseShiftExpr procedure, bad lexeme after "<<" or ">>"} testexprparser {
+ testexprparser {1+2 << 12345678901234567890} -1
+} {- {} 0 subexpr {1+2 << 12345678901234567890} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-10.7 {ParseShiftExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1+2 << 3 << 4} -1
+} {- {} 0 subexpr {1+2 << 3 << 4} 13 operator << 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-10.8 {ParseShiftExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1+2 << 3 >> martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-11.1 {ParseAddExpr procedure, valid LHS multiply subexpr} testexprparser {
+ testexprparser {1*2 + 3} -1
+} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-11.2 {ParseAddExpr procedure, error in LHS multiply subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1/foo + 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-11.3 {ParseAddExpr procedure, next lexeme isn't "+" or "-"} testexprparser {
+ testexprparser {1*2? 1 : 0} -1
+} {- {} 0 subexpr {1*2? 1 : 0} 11 operator ? 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-11.4 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
+ testexprparser {1*2 + 3} -1
+} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-11.5 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
+ testexprparser {1*2 - 3} -1
+} {- {} 0 subexpr {1*2 - 3} 9 operator - 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-11.6 {ParseAddExpr procedure, bad lexeme after "+" or "-"} testexprparser {
+ testexprparser {1*2 + 12345678901234567890} -1
+} {- {} 0 subexpr {1*2 + 12345678901234567890} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-11.7 {ParseAddExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1*2 + 3 + 4} -1
+} {- {} 0 subexpr {1*2 + 3 + 4} 13 operator + 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-11.8 {ParseAddExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1*2 + 3 - martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-12.1 {ParseAddExpr procedure, valid LHS multiply subexpr} testexprparser {
+ testexprparser {1*2 + 3} -1
+} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-12.2 {ParseAddExpr procedure, error in LHS multiply subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1/foo + 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-12.3 {ParseAddExpr procedure, next lexeme isn't "+" or "-"} testexprparser {
+ testexprparser {1*2? 1 : 0} -1
+} {- {} 0 subexpr {1*2? 1 : 0} 11 operator ? 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-12.4 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
+ testexprparser {1*2 + 3} -1
+} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-12.5 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
+ testexprparser {1*2 - 3} -1
+} {- {} 0 subexpr {1*2 - 3} 9 operator - 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-12.6 {ParseAddExpr procedure, bad lexeme after "+" or "-"} testexprparser {
+ testexprparser {1*2 + 12345678901234567890} -1
+} {- {} 0 subexpr {1*2 + 12345678901234567890} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-12.7 {ParseAddExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1*2 + 3 + 4} -1
+} {- {} 0 subexpr {1*2 + 3 + 4} 13 operator + 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-12.8 {ParseAddExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1*2 + 3 - martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-13.1 {ParseMultiplyExpr procedure, valid LHS unary subexpr} testexprparser {
+ testexprparser {+2 * 3} -1
+} {- {} 0 subexpr {+2 * 3} 7 operator * 0 subexpr +2 3 operator + 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-13.2 {ParseMultiplyExpr procedure, error in LHS unary subexpr} testexprparser {
+ testexprparser {-12345678901234567890 * 3} -1
+} {- {} 0 subexpr {-12345678901234567890 * 3} 7 operator * 0 subexpr -12345678901234567890 3 operator - 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-13.3 {ParseMultiplyExpr procedure, next lexeme isn't "*", "/", or "%"} testexprparser {
+ testexprparser {+2? 1 : 0} -1
+} {- {} 0 subexpr {+2? 1 : 0} 9 operator ? 0 subexpr +2 3 operator + 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-13.4 {ParseMultiplyExpr procedure, next lexeme is "*", "/", or "%"} testexprparser {
+ testexprparser {-123 * 3} -1
+} {- {} 0 subexpr {-123 * 3} 7 operator * 0 subexpr -123 3 operator - 0 subexpr 123 1 text 123 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-13.5 {ParseMultiplyExpr procedure, next lexeme is "*", "/", or "%"} testexprparser {
+ testexprparser {+-456 / 3} -1
+} {- {} 0 subexpr {+-456 / 3} 9 operator / 0 subexpr +-456 5 operator + 0 subexpr -456 3 operator - 0 subexpr 456 1 text 456 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-13.6 {ParseMultiplyExpr procedure, next lexeme is "*", "/", or "%"} testexprparser {
+ testexprparser {+-456 % 3} -1
+} {- {} 0 subexpr {+-456 % 3} 9 operator % 0 subexpr +-456 5 operator + 0 subexpr -456 3 operator - 0 subexpr 456 1 text 456 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-13.7 {ParseMultiplyExpr procedure, bad lexeme after "*", "/", or "%"} testexprparser {
+ testexprparser {--++5 / 12345678901234567890} -1
+} {- {} 0 subexpr {--++5 / 12345678901234567890} 13 operator / 0 subexpr --++5 9 operator - 0 subexpr -++5 7 operator - 0 subexpr ++5 5 operator + 0 subexpr +5 3 operator + 0 subexpr 5 1 text 5 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-13.8 {ParseMultiplyExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {-2 / 3 % 4} -1
+} {- {} 0 subexpr {-2 / 3 % 4} 11 operator % 0 subexpr {-2 / 3} 7 operator / 0 subexpr -2 3 operator - 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-13.9 {ParseMultiplyExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {++2 / 3 * martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-14.1 {ParseUnaryExpr procedure, first token is unary operator} testexprparser {
+ testexprparser {+2} -1
+} {- {} 0 subexpr +2 3 operator + 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-14.2 {ParseUnaryExpr procedure, first token is unary operator} testexprparser {
+ testexprparser {-2} -1
+} {- {} 0 subexpr -2 3 operator - 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-14.3 {ParseUnaryExpr procedure, first token is unary operator} testexprparser {
+ testexprparser {~2} -1
+} {- {} 0 subexpr ~2 3 operator ~ 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-14.4 {ParseUnaryExpr procedure, first token is unary operator} testexprparser {
+ testexprparser {!2} -1
+} {- {} 0 subexpr !2 3 operator ! 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-14.5 {ParseUnaryExpr procedure, error in lexeme after unary op} testexprparser {
+ testexprparser {-12345678901234567890} -1
+} {- {} 0 subexpr -12345678901234567890 3 operator - 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-14.6 {ParseUnaryExpr procedure, simple unary expr after unary op} testexprparser {
+ testexprparser {+"1234"} -1
+} {- {} 0 subexpr +\"1234\" 3 operator + 0 subexpr {"1234"} 1 text 1234 0 {}}
+test parseExpr-14.7 {ParseUnaryExpr procedure, another unary expr after unary op} testexprparser {
+ testexprparser {~!{fred}} -1
+} {- {} 0 subexpr ~!{fred} 5 operator ~ 0 subexpr !{fred} 3 operator ! 0 subexpr {{fred}} 1 text fred 0 {}}
+test parseExpr-14.8 {ParseUnaryExpr procedure, error in unary expr after unary op} -constraints testexprparser -body {
+ testexprparser {+-||27} -1
+} -returnCodes error -match glob -result *
+test parseExpr-14.9 {ParseUnaryExpr procedure, error in unary expr after unary op} -constraints testexprparser -body {
+ testexprparser {+-||27} -1
+} -returnCodes error -match glob -result *
+test parseExpr-14.10 {ParseUnaryExpr procedure, first token is not unary op} testexprparser {
+ testexprparser {123} -1
+} {- {} 0 subexpr 123 1 text 123 0 {}}
+test parseExpr-14.11 {ParseUnaryExpr procedure, not unary expr, complex primary expr} testexprparser {
+ testexprparser {(1+2)} -1
+} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-14.12 {ParseUnaryExpr procedure, not unary expr, error in primary expr} testexprparser {
+ testexprparser {(12345678901234567890)} -1
+} {- {} 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+
+test parseExpr-15.1 {ParsePrimaryExpr procedure, just parenthesized subexpr} testexprparser {
+ testexprparser {({abc}/{def})} -1
+} {- {} 0 subexpr {{abc}/{def}} 5 operator / 0 subexpr {{abc}} 1 text abc 0 subexpr {{def}} 1 text def 0 {}}
+test parseExpr-15.2 {ParsePrimaryExpr procedure, bad lexeme after "("} {testexprparser} {
+ testexprparser {(12345678901234567890)} -1
+} {- {} 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-15.3 {ParsePrimaryExpr procedure, valid parenthesized subexpr} testexprparser {
+ testexprparser {({abc}? 2*4 : -6)} -1
+} {- {} 0 subexpr {{abc}? 2*4 : -6} 13 operator ? 0 subexpr {{abc}} 1 text abc 0 subexpr 2*4 5 operator * 0 subexpr 2 1 text 2 0 subexpr 4 1 text 4 0 subexpr -6 3 operator - 0 subexpr 6 1 text 6 0 {}}
+test parseExpr-15.4 {ParsePrimaryExpr procedure, error in parenthesized subexpr} -constraints testexprparser -body {
+ testexprparser {(? 123 : 456)} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.5 {ParsePrimaryExpr procedure, missing ")" after in parenthesized subexpr} -constraints testexprparser -body {
+ testexprparser {({abc}/{def}} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.6 {ParsePrimaryExpr procedure, primary is literal} testexprparser {
+ testexprparser {12345} -1
+} {- {} 0 subexpr 12345 1 text 12345 0 {}}
+test parseExpr-15.7 {ParsePrimaryExpr procedure, primary is literal} testexprparser {
+ testexprparser {12345.6789} -1
+} {- {} 0 subexpr 12345.6789 1 text 12345.6789 0 {}}
+test parseExpr-15.8 {ParsePrimaryExpr procedure, primary is var reference} testexprparser {
+ testexprparser {$a} -1
+} {- {} 0 subexpr {$a} 2 variable {$a} 1 text a 0 {}}
+test parseExpr-15.9 {ParsePrimaryExpr procedure, primary is var reference} testexprparser {
+ testexprparser {$a(hello$there)} -1
+} {- {} 0 subexpr {$a(hello$there)} 5 variable {$a(hello$there)} 4 text a 0 text hello 0 variable {$there} 1 text there 0 {}}
+test parseExpr-15.10 {ParsePrimaryExpr procedure, primary is var reference} testexprparser {
+ testexprparser {$a()} -1
+} {- {} 0 subexpr {$a()} 3 variable {$a()} 2 text a 0 text {} 0 {}}
+test parseExpr-15.11 {ParsePrimaryExpr procedure, error in var reference} -constraints testexprparser -body {
+ testexprparser {$a(} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.12 {ParsePrimaryExpr procedure, primary is quoted string} testexprparser {
+ testexprparser {"abc $xyz def"} -1
+} {- {} 0 subexpr {"abc $xyz def"} 5 word {"abc $xyz def"} 4 text {abc } 0 variable {$xyz} 1 text xyz 0 text { def} 0 {}}
+test parseExpr-15.13 {ParsePrimaryExpr procedure, error in quoted string} -constraints testexprparser -body {
+ testexprparser {"$a(12"} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.14 {ParsePrimaryExpr procedure, quoted string has multiple tokens} testexprparser {
+ testexprparser {"abc [xyz] $def"} -1
+} {- {} 0 subexpr {"abc [xyz] $def"} 6 word {"abc [xyz] $def"} 5 text {abc } 0 command {[xyz]} 0 text { } 0 variable {$def} 1 text def 0 {}}
+test parseExpr-15.15 {ParsePrimaryExpr procedure, primary is command} testexprparser {
+ testexprparser {[def]} -1
+} {- {} 0 subexpr {[def]} 1 command {[def]} 0 {}}
+test parseExpr-15.16 {ParsePrimaryExpr procedure, primary is multiple commands} testexprparser {
+ testexprparser {[one; two; three; four;]} -1
+} {- {} 0 subexpr {[one; two; three; four;]} 1 command {[one; two; three; four;]} 0 {}}
+test parseExpr-15.17 {ParsePrimaryExpr procedure, primary is multiple commands} testexprparser {
+ testexprparser {[one; two; three; four;]} -1
+} {- {} 0 subexpr {[one; two; three; four;]} 1 command {[one; two; three; four;]} 0 {}}
+test parseExpr-15.18 {ParsePrimaryExpr procedure, missing close bracket} -constraints testexprparser -body {
+ testexprparser {[one} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.19 {ParsePrimaryExpr procedure, primary is braced string} testexprparser {
+ testexprparser {{hello world}} -1
+} {- {} 0 subexpr {{hello world}} 1 text {hello world} 0 {}}
+test parseExpr-15.20 {ParsePrimaryExpr procedure, error in primary, which is braced string} -constraints testexprparser -body {
+ testexprparser "\{abc\\\n" -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.21 {ParsePrimaryExpr procedure, primary is braced string with multiple tokens} testexprparser {
+ testexprparser "\{ \\
+ +123 \}" -1
+} {- {} 0 subexpr \{\ \ \\\n\ +123\ \} 4 word \{\ \ \\\n\ +123\ \} 3 text { } 0 backslash \\\n\ 0 text {+123 } 0 {}}
+test parseExpr-15.22 {ParsePrimaryExpr procedure, primary is function call} testexprparser {
+ testexprparser {foo(123)} -1
+} {- {} 0 subexpr foo(123) 3 operator foo 0 subexpr 123 1 text 123 0 {}}
+test parseExpr-15.23 {ParsePrimaryExpr procedure, bad lexeme after function name} -constraints testexprparser -body {
+ testexprparser {foo 12345678901234567890 123)} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.24 {ParsePrimaryExpr procedure, lexeme after function name isn't "("} \
+ -constraints testexprparser -body {
+ testexprparser {foo 27.4 123)} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-15.25 {ParsePrimaryExpr procedure, bad lexeme after "("} testexprparser {
+ testexprparser {foo(12345678901234567890)} -1
+} {- {} 0 subexpr foo(12345678901234567890) 3 operator foo 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-15.26 {ParsePrimaryExpr procedure, function call, one arg} testexprparser {
+ testexprparser {foo(27*4)} -1
+} {- {} 0 subexpr foo(27*4) 7 operator foo 0 subexpr 27*4 5 operator * 0 subexpr 27 1 text 27 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-15.27 {ParsePrimaryExpr procedure, error in function arg} -constraints testexprparser -body {
+ testexprparser {foo(*1-2)} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.28 {ParsePrimaryExpr procedure, error in function arg} -constraints testexprparser -body {
+ testexprparser {foo(*1-2)} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.29 {ParsePrimaryExpr procedure, function call, comma after arg} testexprparser {
+ testexprparser {foo(27-2, (-2*[foo]))} -1
+} {- {} 0 subexpr {foo(27-2, (-2*[foo]))} 15 operator foo 0 subexpr 27-2 5 operator - 0 subexpr 27 1 text 27 0 subexpr 2 1 text 2 0 subexpr {-2*[foo]} 7 operator * 0 subexpr -2 3 operator - 0 subexpr 2 1 text 2 0 subexpr {[foo]} 1 command {[foo]} 0 {}}
+test parseExpr-15.30 {ParsePrimaryExpr procedure, bad lexeme after comma} testexprparser {
+ testexprparser {foo(123, 12345678901234567890)} -1
+} {- {} 0 subexpr {foo(123, 12345678901234567890)} 5 operator foo 0 subexpr 123 1 text 123 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-15.31 {ParsePrimaryExpr procedure, lexeme not "," or ")" after arg} -constraints testexprparser -body {
+ testexprparser {foo(123 [foo])} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.32 {ParsePrimaryExpr procedure, bad lexeme after primary} -constraints testexprparser -body {
+ testexprparser {123 12345678901234567890} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.33 {ParsePrimaryExpr procedure, comma-specific message} -constraints testexprparser -body {
+ testexprparser {123+,456} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.34 {ParsePrimaryExpr procedure, single equal-specific message} -constraints testexprparser -body {
+ testexprparser {123+=456} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.35 {ParsePrimaryExpr procedure, error in parenthesized subexpr} -constraints testexprparser -body {
+ testexprparser {(: 123 : 456)} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.36 {ParsePrimaryExpr procedure, missing close-bracket} -constraints testexprparser -body {
+ # Test for Bug 681841
+ testexprparser {[set a [format bc]} -1
+} -returnCodes error -match glob -result *
+
+test parseExpr-16.1 {GetLexeme procedure, whitespace before lexeme} testexprparser {
+ testexprparser { 123} -1
+} {- {} 0 subexpr 123 1 text 123 0 {}}
+test parseExpr-16.2 {GetLexeme procedure, whitespace before lexeme} testexprparser {
+ testexprparser { \
+456} -1
+} {- {} 0 subexpr 456 1 text 456 0 {}}
+test parseExpr-16.3 {GetLexeme procedure, no lexeme after whitespace} testexprparser {
+ testexprparser { 123 \
+ } -1
+} {- {} 0 subexpr 123 1 text 123 0 {}}
+test parseExpr-16.4 {GetLexeme procedure, integer lexeme} testexprparser {
+ testexprparser {000} -1
+} {- {} 0 subexpr 000 1 text 000 0 {}}
+test parseExpr-16.5 {GetLexeme procedure, integer lexeme too big} testexprparser {
+ testexprparser {12345678901234567890} -1
+} {- {} 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-16.6 {GetLexeme procedure, bad integer lexeme} -constraints testexprparser -body {
+ testexprparser {0o999} -1
+} -returnCodes error -match glob -result {*invalid octal number*}
+test parseExpr-16.7 {GetLexeme procedure, double lexeme} testexprparser {
+ testexprparser {0.999} -1
+} {- {} 0 subexpr 0.999 1 text 0.999 0 {}}
+test parseExpr-16.8 {GetLexeme procedure, double lexeme} testexprparser {
+ testexprparser {.123} -1
+} {- {} 0 subexpr .123 1 text .123 0 {}}
+test parseExpr-16.9 {GetLexeme procedure, double lexeme} {testexprparser unix} {
+ testexprparser {nan} -1
+} {- {} 0 subexpr nan 1 text nan 0 {}}
+test parseExpr-16.10 {GetLexeme procedure, double lexeme} {testexprparser unix} {
+ testexprparser {NaN} -1
+} {- {} 0 subexpr NaN 1 text NaN 0 {}}
+test parseExpr-16.11a {GetLexeme procedure, bad double lexeme too big} {testexprparser && !ieeeFloatingPoint} {
+ list [catch {testexprparser {123.e+99999999999999} -1} msg] $msg
+} {1 {floating-point value too large to represent}}
+test parseExpr-16.11b {GetLexeme procedure, bad double lexeme too big} {testexprparser && ieeeFloatingPoint} {
+ list [catch {testexprparser {123.e+99999999999999} -1} msg] $msg
+} {0 {- {} 0 subexpr 123.e+99999999999999 1 text 123.e+99999999999999 0 {}}}
+test parseExpr-16.12 {GetLexeme procedure, bad double lexeme} -constraints testexprparser -body {
+ testexprparser {123.4x56} -1
+} -returnCodes error -match glob -result *
+test parseExpr-16.13 {GetLexeme procedure, lexeme is "["} testexprparser {
+ testexprparser {[foo]} -1
+} {- {} 0 subexpr {[foo]} 1 command {[foo]} 0 {}}
+test parseExpr-16.14 {GetLexeme procedure, lexeme is open brace} testexprparser {
+ testexprparser {{bar}} -1
+} {- {} 0 subexpr {{bar}} 1 text bar 0 {}}
+test parseExpr-16.15 {GetLexeme procedure, lexeme is "("} testexprparser {
+ testexprparser {(123)} -1
+} {- {} 0 subexpr 123 1 text 123 0 {}}
+test parseExpr-16.16 {GetLexeme procedure, lexeme is ")"} testexprparser {
+ testexprparser {(2*3)} -1
+} {- {} 0 subexpr 2*3 5 operator * 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.17 {GetLexeme procedure, lexeme is "$"} testexprparser {
+ testexprparser {$wombat} -1
+} {- {} 0 subexpr {$wombat} 2 variable {$wombat} 1 text wombat 0 {}}
+test parseExpr-16.18 "GetLexeme procedure, lexeme is '\"'" testexprparser {
+ testexprparser {"fred"} -1
+} {- {} 0 subexpr {"fred"} 1 text fred 0 {}}
+test parseExpr-16.19 {GetLexeme procedure, lexeme is ","} testexprparser {
+ testexprparser {foo(1,2)} -1
+} {- {} 0 subexpr foo(1,2) 5 operator foo 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.20 {GetLexeme procedure, lexeme is "*"} testexprparser {
+ testexprparser {$a*$b} -1
+} {- {} 0 subexpr {$a*$b} 7 operator * 0 subexpr {$a} 2 variable {$a} 1 text a 0 subexpr {$b} 2 variable {$b} 1 text b 0 {}}
+test parseExpr-16.21 {GetLexeme procedure, lexeme is "/"} testexprparser {
+ testexprparser {5/6} -1
+} {- {} 0 subexpr 5/6 5 operator / 0 subexpr 5 1 text 5 0 subexpr 6 1 text 6 0 {}}
+test parseExpr-16.22 {GetLexeme procedure, lexeme is "%"} testexprparser {
+ testexprparser {5%[xxx]} -1
+} {- {} 0 subexpr {5%[xxx]} 5 operator % 0 subexpr 5 1 text 5 0 subexpr {[xxx]} 1 command {[xxx]} 0 {}}
+test parseExpr-16.23 {GetLexeme procedure, lexeme is "+"} testexprparser {
+ testexprparser {1+2} -1
+} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.24 {GetLexeme procedure, lexeme is "-"} testexprparser {
+ testexprparser {.12-0e27} -1
+} {- {} 0 subexpr .12-0e27 5 operator - 0 subexpr .12 1 text .12 0 subexpr 0e27 1 text 0e27 0 {}}
+test parseExpr-16.25 {GetLexeme procedure, lexeme is "?" or ":"} testexprparser {
+ testexprparser {$b? 1 : 0} -1
+} {- {} 0 subexpr {$b? 1 : 0} 8 operator ? 0 subexpr {$b} 2 variable {$b} 1 text b 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-16.26 {GetLexeme procedure, lexeme is "<"} testexprparser {
+ testexprparser {2<3} -1
+} {- {} 0 subexpr 2<3 5 operator < 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.27 {GetLexeme procedure, lexeme is "<<"} testexprparser {
+ testexprparser {2<<3} -1
+} {- {} 0 subexpr 2<<3 5 operator << 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.28 {GetLexeme procedure, lexeme is "<="} testexprparser {
+ testexprparser {2<=3} -1
+} {- {} 0 subexpr 2<=3 5 operator <= 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.29 {GetLexeme procedure, lexeme is ">"} testexprparser {
+ testexprparser {2>3} -1
+} {- {} 0 subexpr 2>3 5 operator > 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.30 {GetLexeme procedure, lexeme is ">>"} testexprparser {
+ testexprparser {2>>3} -1
+} {- {} 0 subexpr 2>>3 5 operator >> 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.31 {GetLexeme procedure, lexeme is ">="} testexprparser {
+ testexprparser {2>=3} -1
+} {- {} 0 subexpr 2>=3 5 operator >= 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.32 {GetLexeme procedure, lexeme is "=="} testexprparser {
+ testexprparser {2==3} -1
+} {- {} 0 subexpr 2==3 5 operator == 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.33 {GetLexeme procedure, bad lexeme starting with "="} -constraints testexprparser -body {
+ testexprparser {2=+3} -1
+} -returnCodes error -match glob -result *
+test parseExpr-16.34 {GetLexeme procedure, lexeme is "!="} testexprparser {
+ testexprparser {2!=3} -1
+} {- {} 0 subexpr 2!=3 5 operator != 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.35 {GetLexeme procedure, lexeme is "!"} testexprparser {
+ testexprparser {!2} -1
+} {- {} 0 subexpr !2 3 operator ! 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.36 {GetLexeme procedure, lexeme is "&&"} testexprparser {
+ testexprparser {2&&3} -1
+} {- {} 0 subexpr 2&&3 5 operator && 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.37 {GetLexeme procedure, lexeme is "&"} testexprparser {
+ testexprparser {1&2} -1
+} {- {} 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.38 {GetLexeme procedure, lexeme is "^"} testexprparser {
+ testexprparser {1^2} -1
+} {- {} 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.39 {GetLexeme procedure, lexeme is "||"} testexprparser {
+ testexprparser {2||3} -1
+} {- {} 0 subexpr 2||3 5 operator || 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.40 {GetLexeme procedure, lexeme is "|"} testexprparser {
+ testexprparser {1|2} -1
+} {- {} 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.41 {GetLexeme procedure, lexeme is "~"} testexprparser {
+ testexprparser {~2} -1
+} {- {} 0 subexpr ~2 3 operator ~ 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.42 {GetLexeme procedure, lexeme is func name} testexprparser {
+ testexprparser {george()} -1
+} {- {} 0 subexpr george() 1 operator george 0 {}}
+test parseExpr-16.43 {GetLexeme procedure, lexeme is func name} testexprparser {
+ testexprparser {harmonic_ratio(2,3)} -1
+} {- {} 0 subexpr harmonic_ratio(2,3) 5 operator harmonic_ratio 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.44 {GetLexeme procedure, unknown lexeme} -constraints testexprparser -body {
+ testexprparser {@27} -1
+} -returnCodes error -match glob -result *
+
+test parseExpr-17.1 {PrependSubExprTokens procedure, expand token array} testexprparser {
+ testexprparser {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]} -1
+} {- {} 0 subexpr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]} 13 operator && 0 subexpr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]} 9 operator && 0 subexpr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]} 5 operator && 0 subexpr {[string compare [format %c $i] [string index $a $i]]} 1 command {[string compare [format %c $i] [string index $a $i]]} 0 subexpr {[string compare [format %c $i] [string index $a $i]]} 1 command {[string compare [format %c $i] [string index $a $i]]} 0 subexpr {[string compare [format %c $i] [string index $a $i]]} 1 command {[string compare [format %c $i] [string index $a $i]]} 0 subexpr {[string compare [format %c $i] [string index $a $i]]} 1 command {[string compare [format %c $i] [string index $a $i]]} 0 {}}
+
+test parseExpr-18.1 {LogSyntaxError procedure, error in expr longer than 60 chars} -constraints testexprparser -body {
+ testexprparser {(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)/} -1
+} -returnCodes error -match glob -result *
+
+test parseExpr-19.1 {TclParseInteger: [Bug 648441]} -body {
+ # Should see this as integer "0" followed by incomplete function "x"
+ # Thus, syntax error.
+ # If Bug 648441 is not fixed, "0x" will be seen as floating point 0.0
+ expr 0x
+} -returnCodes error -match glob -result *
+
+test parseExpr-20.1 {Bug 1451233} {
+ expr 1000000000000000000042
+} 1000000000000000000042
+test parseExpr-20.2 {Bug 1451233} {
+ expr 10000000000000000000420000000042
+} 10000000000000000000420000000042
+test parseExpr-20.3 {Bug 1451233} {
+ expr 10000000000000000000020000000002
+} 10000000000000000000020000000002
+
+test parseExpr-21.1 {error messages} -body {
+ expr @
+} -returnCodes error -result {invalid character "@"
+in expression "@"}
+test parseExpr-21.2 {error messages} -body {
+ expr =
+} -returnCodes error -result {incomplete operator "="
+in expression "="}
+test parseExpr-21.3 {error messages} -body {
+ expr x
+} -returnCodes error -result {invalid bareword "x"
+in expression "x";
+should be "$x" or "{x}" or "x(...)" or ...}
+test parseExpr-21.4 {error messages} -body {
+ expr abcdefghijklmnopqrstuvwxyz
+} -returnCodes error -result {invalid bareword "abcdefghijklmnopqrstuv..."
+in expression "abcdefghijklmnopqrstuv...";
+should be "$abcdefghijklmnopqrstuv..." or "{abcdefghijklmnopqrstuv...}" or "abcdefghijklmnopqrstuv...(...)" or ...}
+test parseExpr-21.5 {error messages} -body {
+ expr {[][]}
+} -returnCodes error -result {missing operator at _@_
+in expression "[]_@_[]"}
+test parseExpr-21.6 {error messages} -body {
+ expr {0 0}
+} -returnCodes error -result {missing operator at _@_
+in expression "0 _@_0"}
+test parseExpr-21.7 {error messages} -body {
+ expr {0o8}
+} -returnCodes error -match glob -result {*invalid octal number*}
+test parseExpr-21.8 {error messages} -body {
+ expr {0o8x}
+} -returnCodes error -match glob -result {*invalid octal number*}
+test parseExpr-21.9 {error messages} -body {
+ expr {"}
+} -returnCodes error -result {missing "
+in expression """}
+test parseExpr-21.10 {error messages} -body {
+ expr \{
+} -returnCodes error -result "missing close-brace
+in expression \"\{\""
+test parseExpr-21.11 {error messages} -body {
+ expr $
+} -returnCodes error -result {invalid character "$"
+in expression "$"}
+test parseExpr-21.12 {error messages} -body {
+ expr {$(}
+} -returnCodes error -result {missing )
+in expression "$("}
+test parseExpr-21.13 {error messages} -body {
+ expr {[""x]}
+} -returnCodes error -result {extra characters after close-quote
+in expression "[""x]"}
+test parseExpr-21.14 {error messages} -body {
+ expr {[}
+} -returnCodes error -result {missing close-bracket
+in expression "["}
+test parseExpr-21.15 {error messages} -body {
+ expr 0~0
+} -returnCodes error -result {missing operator at _@_
+in expression "0_@_~0"}
+test parseExpr-21.16 {error messages} -body {
+ expr ()
+} -returnCodes error -result {empty subexpression at _@_
+in expression "(_@_)"}
+test parseExpr-21.17 {error messages} -body {
+ expr (
+} -returnCodes error -result {unbalanced open paren
+in expression "("}
+test parseExpr-21.18 {error messages} -body {
+ expr a(0,)
+} -returnCodes error -result {missing function argument at _@_
+in expression "a(0,_@_)"}
+test parseExpr-21.19 {error messages} -body {
+ expr {}
+} -returnCodes error -result {empty expression
+in expression ""}
+test parseExpr-21.20 {error messages} -body {
+ expr )
+} -returnCodes error -result {unbalanced close paren
+in expression ")"}
+test parseExpr-21.21 {error messages} -body {
+ expr a(,0)
+} -returnCodes error -result {missing function argument at _@_
+in expression "a(_@_,0)"}
+test parseExpr-21.22 {error messages} -body {
+ expr 0&|0
+} -returnCodes error -result {missing operand at _@_
+in expression "0&_@_|0"}
+test parseExpr-21.23 {error messages} -body {
+ expr 0^^0
+} -returnCodes error -result {missing operand at _@_
+in expression "0^_@_^0"}
+test parseExpr-21.24 {error messages} -body {
+ expr 0|&0
+} -returnCodes error -result {missing operand at _@_
+in expression "0|_@_&0"}
+test parseExpr-21.25 {error messages} -body {
+ expr a(1+,0)
+} -returnCodes error -result {missing operand at _@_
+in expression "a(1+_@_,0)"}
+test parseExpr-21.26 {error messages} -body {
+ expr (0
+} -returnCodes error -result {unbalanced open paren
+in expression "(0"}
+test parseExpr-21.27 {error messages} -body {
+ expr 0?0
+} -returnCodes error -result {missing operator ":" at _@_
+in expression "0?0_@_"}
+test parseExpr-21.28 {error messages} -body {
+ expr 0:0
+} -returnCodes error -result {unexpected operator ":" without preceding "?"
+in expression "0:0"}
+test parseExpr-21.29 {error messages} -body {
+ expr 0)
+} -returnCodes error -result {unbalanced close paren
+in expression "0)"}
+test parseExpr-21.30 {error messages} -body {
+ expr 0,
+} -returnCodes error -result {unexpected "," outside function argument list
+in expression "0,"}
+test parseExpr-21.31 {error messages} -body {
+ expr 0,0
+} -returnCodes error -result {unexpected "," outside function argument list
+in expression "0,0"}
+test parseExpr-21.32 {error messages} -body {
+ expr (0,0)
+} -returnCodes error -result {unexpected "," outside function argument list
+in expression "(0,0)"}
+test parseExpr-21.33 {error messages} -body {
+ expr a(0:0,0)
+} -returnCodes error -result {unexpected operator ":" without preceding "?"
+in expression "a(0:0,0)"}
+test parseExpr-21.34 {error messages} -body {
+ expr {"abcdefghijklmnopqrstuvwxyz"@0}
+} -returnCodes error -result {invalid character "@"
+in expression "...fghijklmnopqrstuvwxyz"@0"}
+test parseExpr-21.35 {error messages} -body {
+ expr {0@"abcdefghijklmnopqrstuvwxyz"}
+} -returnCodes error -result {invalid character "@"
+in expression "0@"abcdefghijklmnopqrstu..."}
+test parseExpr-21.36 {error messages} -body {
+ expr {"abcdefghijklmnopqrstuvwxyz"@"abcdefghijklmnopqrstuvwxyz"}
+} -returnCodes error -result {invalid character "@"
+in expression "...fghijklmnopqrstuvwxyz"@"abcdefghijklmnopqrstu..."}
+test parseExpr-21.37 {error messages} -body {
+ expr [format {"%s" @ 0} [string repeat \u00a7 25]]
+} -returnCodes error -result [format {invalid character "@"
+in expression "...%s" @ 0"} [string repeat \u00a7 10]]
+test parseExpr-21.38 {error messages} -body {
+ expr [format {0 @ "%s"} [string repeat \u00a7 25]]
+} -returnCodes error -result [format {invalid character "@"
+in expression "0 @ "%s..."} [string repeat \u00a7 10]]
+test parseExpr-21.39 {error messages} -body {
+ expr [format {"%s" @ "%s"} [string repeat \u00a7 25] [string repeat \u00a7 25]]
+} -returnCodes error -result [format {invalid character "@"
+in expression "...%s" @ "%s..."} [string repeat \u00a7 10] [string repeat \u00a7 10]]
+test parseExpr-21.40 {error messages} -body {
+ catch {expr {"abcdefghijklmnopqrstuvwxyz"@0}} m o
+ dict get $o -errorinfo
+} -result {invalid character "@"
+in expression "...fghijklmnopqrstuvwxyz"@0"
+ (parsing expression ""abcdefghijklmnopqrstu...")
+ invoked from within
+"expr {"abcdefghijklmnopqrstuvwxyz"@0}"}
+test parseExpr-21.41 {error messages} -body {
+ catch {expr [format {"%s" @ 0} [string repeat \u00a7 25]]} m o
+ dict get $o -errorinfo
+} -result [format {invalid character "@"
+in expression "...%s" @ 0"
+ (parsing expression ""%s...")
+ invoked from within
+"expr [format {"%%s" @ 0} [string repeat \u00a7 25]]"} [string repeat \u00a7 10] [string repeat \u00a7 10]]
+test parseExpr-21.42 {error message} -body {
+ expr {123456789012345678901234567890*"abcdefghijklmnopqrstuvwxyz}
+} -returnCodes error -result {missing "
+in expression "...012345678901234567890*"abcdefghijklmnopqrstuv..."}
+test parseExpr-21.43 {error message} -body {
+ expr "123456789012345678901234567890*\"foobar\$\{abcdefghijklmnopqrstuvwxyz\""
+} -returnCodes error -result "missing close-brace for variable name
+in expression \"...8901234567890*\"foobar\$\{abcdefghijklmnopqrstuv...\""
+test parseExpr-21.44 {error message} -body {
+ expr {123456789012345678901234567890*"foo$bar(abcdefghijklmnopqrstuvwxyz"}
+} -returnCodes error -result {missing )
+in expression "...8901234567890*"foo$bar(abcdefghijklmnopqrstuv..."}
+test parseExpr-21.45 {error message} -body {
+ expr {123456789012345678901234567890*"foo$bar([{}abcdefghijklmnopqrstuvwxyz])"}
+} -returnCodes error -result {extra characters after close-brace
+in expression "...234567890*"foo$bar([{}abcdefghijklmnopqrstuv..."}
+test parseExpr-21.46 {error message} -body {
+ expr {123456789012345678901234567890*"foo$bar([""abcdefghijklmnopqrstuvwxyz])"}
+} -returnCodes error -result {extra characters after close-quote
+in expression "...234567890*"foo$bar([""abcdefghijklmnopqrstuv..."}
+test parseExpr-21.47 {error message} -body {
+ expr {123456789012345678901234567890*"foo$bar([abcdefghijklmnopqrstuvwxyz)"}
+} -returnCodes error -result {missing close-bracket
+in expression "...901234567890*"foo$bar([abcdefghijklmnopqrstuv..."}
+test parseExpr-21.48 {error message} -body {
+ expr "123456789012345678901234567890*\"foo\$bar(\[\{abcdefghijklmnopqrstuvwxyz])\""
+} -returnCodes error -result "missing close-brace
+in expression \"...01234567890*\"foo\$bar(\[\{abcdefghijklmnopqrstuv...\""
+
+test parseExpr-21.49 {error message} -body {
+ expr "123456789012345678901234567890*\{abcdefghijklmnopqrstuvwxyz"
+} -returnCodes error -result "missing close-brace
+in expression \"...012345678901234567890*\{abcdefghijklmnopqrstuv...\""
+
+test parseExpr-21.50 {error message} -body {
+ expr {123456789012345678901234567890*$foo(["abcdefghijklmnopqrstuvwxyz])}
+} -returnCodes error -result {missing "
+in expression "...678901234567890*$foo(["abcdefghijklmnopqrstuv..."}
+test parseExpr-21.51 {error message} -body {
+ expr "123456789012345678901234567890*\$\{abcdefghijklmnopqrstuvwxyz"
+} -returnCodes error -result "missing close-brace for variable name
+in expression \"...12345678901234567890*\$\{abcdefghijklmnopqrstuv...\""
+test parseExpr-21.52 {error message} -body {
+ expr {123456789012345678901234567890*$bar(abcdefghijklmnopqrstuvwxyz}
+} -returnCodes error -result {missing )
+in expression "...45678901234567890*$bar(abcdefghijklmnopqrstuv..."}
+test parseExpr-21.53 {error message} -body {
+ expr {123456789012345678901234567890*$bar([{}abcdefghijklmnopqrstuvwxyz])"}
+} -returnCodes error -result {extra characters after close-brace
+in expression "...8901234567890*$bar([{}abcdefghijklmnopqrstuv..."}
+test parseExpr-21.54 {error message} -body {
+ expr {123456789012345678901234567890*$bar([""abcdefghijklmnopqrstuvwxyz])"}
+} -returnCodes error -result {extra characters after close-quote
+in expression "...8901234567890*$bar([""abcdefghijklmnopqrstuv..."}
+test parseExpr-21.55 {error message} -body {
+ expr {123456789012345678901234567890*$bar([abcdefghijklmnopqrstuvwxyz)"}
+} -returnCodes error -result {missing close-bracket
+in expression "...5678901234567890*$bar([abcdefghijklmnopqrstuv..."}
+test parseExpr-21.56 {error message} -body {
+ expr "123456789012345678901234567890*\$bar(\[\{abcdefghijklmnopqrstuvwxyz])"
+} -returnCodes error -result "missing close-brace
+in expression \"...678901234567890*\$bar(\[\{abcdefghijklmnopqrstuv...\""
+
+test parseExpr-21.57 {error message} -body {
+ expr {123456789012345678901234567890*["abcdefghijklmnopqrstuvwxyz]}
+} -returnCodes error -result {missing "
+in expression "...12345678901234567890*["abcdefghijklmnopqrstuv..."}
+test parseExpr-21.58 {error message} -body {
+ expr "123456789012345678901234567890*\[\$\{abcdefghijklmnopqrstuvwxyz]"
+} -returnCodes error -result "missing close-brace for variable name
+in expression \"...2345678901234567890*\[\$\{abcdefghijklmnopqrstuv...\""
+test parseExpr-21.59 {error message} -body {
+ expr {123456789012345678901234567890*[$bar(abcdefghijklmnopqrstuvwxyz]}
+} -returnCodes error -result {missing )
+in expression "...5678901234567890*[$bar(abcdefghijklmnopqrstuv..."}
+test parseExpr-21.60 {error message} -body {
+ expr {123456789012345678901234567890*[{}abcdefghijklmnopqrstuvwxyz]"}
+} -returnCodes error -result {extra characters after close-brace
+in expression "...345678901234567890*[{}abcdefghijklmnopqrstuv..."}
+test parseExpr-21.61 {error message} -body {
+ expr {123456789012345678901234567890*[""abcdefghijklmnopqrstuvwxyz]"}
+} -returnCodes error -result {extra characters after close-quote
+in expression "...345678901234567890*[""abcdefghijklmnopqrstuv..."}
+test parseExpr-21.62 {error message} -body {
+ expr {123456789012345678901234567890*[abcdefghijklmnopqrstuvwxyz"}
+} -returnCodes error -result {missing close-bracket
+in expression "...012345678901234567890*[abcdefghijklmnopqrstuv..."}
+test parseExpr-21.63 {error message} -body {
+ expr "123456789012345678901234567890*\[\{abcdefghijklmnopqrstuvwxyz]"
+} -returnCodes error -result "missing close-brace
+in expression \"...12345678901234567890*\[\{abcdefghijklmnopqrstuv...\""
+
+test parseExpr-22.1 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser 2a() 1
+} -result {- {} 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-22.2 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser nana() 3
+} -result {- {} 0 subexpr nan 1 text nan 0 {}}
+test parseExpr-22.3 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser 2a() -1
+} -result {- {} 0 subexpr 2a() 1 operator 2a 0 {}}
+test parseExpr-22.4 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser nana() -1
+} -result {- {} 0 subexpr nana() 1 operator nana 0 {}}
+test parseExpr-22.5 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser nan9() -1
+} -result {- {} 0 subexpr nan9() 1 operator nan9 0 {}}
+test parseExpr-22.6 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser 2_() -1
+} -result {- {} 0 subexpr 2_() 1 operator 2_ 0 {}}
+test parseExpr-22.7 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser nan_() -1
+} -result {- {} 0 subexpr nan_() 1 operator nan_ 0 {}}
+test parseExpr-22.8 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser nan!() -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR MISSING}
+test parseExpr-22.9 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser 1e3_() -1
+} -result {- {} 0 subexpr 1e3_() 1 operator 1e3_ 0 {}}
+test parseExpr-22.10 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 1.3_() -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADCHAR}
+test parseExpr-22.11 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 1e-3_() -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADCHAR}
+test parseExpr-22.12 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser naneq() -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR EMPTY}
+test parseExpr-22.13 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser naner() -1
+} -result {- {} 0 subexpr naner() 1 operator naner 0 {}}
+
+test parseExpr-22.14 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 08 -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER OCTAL}
+test parseExpr-22.15 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 0o8 -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER OCTAL}
+test parseExpr-22.16 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 0o08 -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER OCTAL}
+test parseExpr-22.17 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 0b2 -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER BINARY}
+test parseExpr-22.18 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 0b02 -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER BINARY}
+
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/parseOld.test b/library/msgcat/tests/parseOld.test
new file mode 100644
index 0000000..132481c
--- /dev/null
+++ b/library/msgcat/tests/parseOld.test
@@ -0,0 +1,543 @@
+# Commands covered: set (plus basic command syntax). Also tests the
+# procedures in the file tclOldParse.c. This set of tests is an old
+# one that predates the new parser in Tcl 8.1.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testwordend [llength [info commands testwordend]]
+
+# Save the argv value for restoration later
+set savedArgv $argv
+
+proc fourArgs {a b c d} {
+ global arg1 arg2 arg3 arg4
+ set arg1 $a
+ set arg2 $b
+ set arg3 $c
+ set arg4 $d
+}
+
+proc getArgs args {
+ global argv
+ set argv $args
+}
+
+# Basic argument parsing.
+
+test parseOld-1.1 {basic argument parsing} {
+ set arg1 {}
+ fourArgs a b c d
+ list $arg1 $arg2 $arg3 $arg4
+} {a b c d}
+test parseOld-1.2 {basic argument parsing} {
+ set arg1 {}
+ eval "fourArgs 123\v4\f56\r7890"
+ list $arg1 $arg2 $arg3 $arg4
+} {123 4 56 7890}
+
+# Quotes.
+
+test parseOld-2.1 {quotes and variable-substitution} {
+ getArgs "a b c" d
+ set argv
+} {{a b c} d}
+test parseOld-2.2 {quotes and variable-substitution} {
+ set a 101
+ getArgs "a$a b c"
+ set argv
+} {{a101 b c}}
+test parseOld-2.3 {quotes and variable-substitution} {
+ set argv "xy[format xabc]"
+ set argv
+} {xyxabc}
+test parseOld-2.4 {quotes and variable-substitution} {
+ set argv "xy\t"
+ set argv
+} xy\t
+test parseOld-2.5 {quotes and variable-substitution} {
+ set argv "a b c
+d e f"
+ set argv
+} a\ b\tc\nd\ e\ f
+test parseOld-2.6 {quotes and variable-substitution} {
+ set argv a"bcd"e
+ set argv
+} {a"bcd"e}
+
+# Braces.
+
+test parseOld-3.1 {braces} {
+ getArgs {a b c} d
+ set argv
+} "{a b c} d"
+test parseOld-3.2 {braces} {
+ set a 101
+ set argv {a$a b c}
+ set b [string index $argv 1]
+ set b
+} {$}
+test parseOld-3.3 {braces} {
+ set argv {a[format xyz] b}
+ string length $argv
+} 15
+test parseOld-3.4 {braces} {
+ set argv {a\nb\}}
+ string length $argv
+} 6
+test parseOld-3.5 {braces} {
+ set argv {{{{}}}}
+ set argv
+} "{{{}}}"
+test parseOld-3.6 {braces} {
+ set argv a{{}}b
+ set argv
+} "a{{}}b"
+test parseOld-3.7 {braces} {
+ set a [format "last]"]
+ set a
+} {last]}
+
+# Command substitution.
+
+test parseOld-4.1 {command substitution} {
+ set a [format xyz]
+ set a
+} xyz
+test parseOld-4.2 {command substitution} {
+ set a a[format xyz]b[format q]
+ set a
+} axyzbq
+test parseOld-4.3 {command substitution} {
+ set a a[
+set b 22;
+format %s $b
+
+]b
+ set a
+} a22b
+test parseOld-4.4 {command substitution} {
+ set a 7.7
+ if [catch {expr int($a)}] {set a foo}
+ set a
+} 7.7
+
+# Variable substitution.
+
+test parseOld-5.1 {variable substitution} {
+ set a 123
+ set b $a
+ set b
+} 123
+test parseOld-5.2 {variable substitution} {
+ set a 345
+ set b x$a.b
+ set b
+} x345.b
+test parseOld-5.3 {variable substitution} {
+ set _123z xx
+ set b $_123z^
+ set b
+} xx^
+test parseOld-5.4 {variable substitution} {
+ set a 78
+ set b a${a}b
+ set b
+} a78b
+test parseOld-5.5 {variable substitution} {catch {$_non_existent_} msg} 1
+test parseOld-5.6 {variable substitution} {
+ catch {$_non_existent_} msg
+ set msg
+} {can't read "_non_existent_": no such variable}
+test parseOld-5.7 {array variable substitution} {
+ catch {unset a}
+ set a(xyz) 123
+ set b $a(xyz)foo
+ set b
+} 123foo
+test parseOld-5.8 {array variable substitution} {
+ catch {unset a}
+ set "a(x y z)" 123
+ set b $a(x y z)foo
+ set b
+} 123foo
+test parseOld-5.9 {array variable substitution} {
+ catch {unset a}; catch {unset qqq}
+ set "a(x y z)" qqq
+ set $a([format x]\ y [format z]) foo
+ set qqq
+} foo
+test parseOld-5.10 {array variable substitution} {
+ catch {unset a}
+ list [catch {set b $a(22)} msg] $msg
+} {1 {can't read "a(22)": no such variable}}
+test parseOld-5.11 {array variable substitution} {
+ set b a$!
+ set b
+} {a$!}
+test parseOld-5.12 {empty array name support} {
+ list [catch {set b a$()} msg] $msg
+} {1 {can't read "()": no such variable}}
+catch {unset a}
+test parseOld-5.13 {array variable substitution} {
+ catch {unset a}
+ set long {This is a very long variable, long enough to cause storage \
+ allocation to occur in Tcl_ParseVar. If that storage isn't getting \
+ freed up correctly, then a core leak will occur when this test is \
+ run. This text is probably beginning to sound like drivel, but I've \
+ run out of things to say and I need more characters still.}
+ set a($long) 777
+ set b $a($long)
+ list $b [array names a]
+} {777 {{This is a very long variable, long enough to cause storage \
+ allocation to occur in Tcl_ParseVar. If that storage isn't getting \
+ freed up correctly, then a core leak will occur when this test is \
+ run. This text is probably beginning to sound like drivel, but I've \
+ run out of things to say and I need more characters still.}}}
+test parseOld-5.14 {array variable substitution} {
+ catch {unset a}; catch {unset b}; catch {unset a1}
+ set a1(22) foo
+ set a(foo) bar
+ set b $a($a1(22))
+ set b
+} bar
+catch {unset a}; catch {unset a1}
+
+test parseOld-7.1 {backslash substitution} {
+ set a "\a\c\n\]\}"
+ string length $a
+} 5
+test parseOld-7.2 {backslash substitution} {
+ set a {\a\c\n\]\}}
+ string length $a
+} 10
+test parseOld-7.3 {backslash substitution} {
+ set a "abc\
+def"
+ set a
+} {abc def}
+test parseOld-7.4 {backslash substitution} {
+ set a {abc\
+def}
+ set a
+} {abc def}
+test parseOld-7.5 {backslash substitution} {
+ set msg {}
+ set a xxx
+ set error [catch {if {24 < \
+ 35} {set a 22} {set \
+ a 33}} msg]
+ list $error $msg $a
+} {0 22 22}
+test parseOld-7.6 {backslash substitution} {
+ eval "concat abc\\"
+} "abc\\"
+test parseOld-7.7 {backslash substitution} {
+ eval "concat \\\na"
+} "a"
+test parseOld-7.8 {backslash substitution} {
+ eval "concat x\\\n a"
+} "x a"
+test parseOld-7.9 {backslash substitution} {
+ eval "concat \\x"
+} "x"
+test parseOld-7.10 {backslash substitution} {
+ eval "list a b\\\nc d"
+} {a b c d}
+test parseOld-7.11 {backslash substitution} {
+ eval "list a \"b c\"\\\nd e"
+} {a {b c} d e}
+test parseOld-7.12 {backslash substitution} {
+ list \ua2
+} [bytestring "\xc2\xa2"]
+test parseOld-7.13 {backslash substitution} {
+ list \u4e21
+} [bytestring "\xe4\xb8\xa1"]
+test parseOld-7.14 {backslash substitution} {
+ list \u4e2k
+} [bytestring "\xd3\xa2k"]
+
+# Semi-colon.
+
+test parseOld-8.1 {semi-colons} {
+ set b 0
+ getArgs a;set b 2
+ set argv
+} a
+test parseOld-8.2 {semi-colons} {
+ set b 0
+ getArgs a;set b 2
+ set b
+} 2
+test parseOld-8.3 {semi-colons} {
+ getArgs a b ; set b 1
+ set argv
+} {a b}
+test parseOld-8.4 {semi-colons} {
+ getArgs a b ; set b 1
+ set b
+} 1
+
+# The following checks are to ensure that the interpreter's result
+# gets re-initialized by Tcl_Eval in all the right places.
+
+test parseOld-9.1 {result initialization} {concat abc} abc
+test parseOld-9.2 {result initialization} {concat abc; proc foo {} {}} {}
+test parseOld-9.3 {result initialization} {concat abc; proc foo {} $a} {}
+test parseOld-9.4 {result initialization} {proc foo {} [concat abc]} {}
+test parseOld-9.5 {result initialization} {concat abc; } abc
+test parseOld-9.6 {result initialization} {
+ eval {
+ concat abc
+}} abc
+test parseOld-9.7 {result initialization} {} {}
+test parseOld-9.8 {result initialization} {concat abc; ; ;} abc
+
+# Syntax errors.
+
+test parseOld-10.1 {syntax errors} {catch "set a \{bcd" msg} 1
+test parseOld-10.2 {syntax errors} {
+ catch "set a \{bcd" msg
+ set msg
+} {missing close-brace}
+test parseOld-10.3 {syntax errors} {catch {set a "bcd} msg} 1
+test parseOld-10.4 {syntax errors} {
+ catch {set a "bcd} msg
+ set msg
+} {missing "}
+#" Emacs formatting >:^(
+test parseOld-10.5 {syntax errors} {catch {set a "bcd"xy} msg} 1
+test parseOld-10.6 {syntax errors} {
+ catch {set a "bcd"xy} msg
+ set msg
+} {extra characters after close-quote}
+test parseOld-10.7 {syntax errors} {catch "set a {bcd}xy" msg} 1
+test parseOld-10.8 {syntax errors} {
+ catch "set a {bcd}xy" msg
+ set msg
+} {extra characters after close-brace}
+test parseOld-10.9 {syntax errors} {catch {set a [format abc} msg} 1
+test parseOld-10.10 {syntax errors} {
+ catch {set a [format abc} msg
+ set msg
+} {missing close-bracket}
+test parseOld-10.11 {syntax errors} {catch gorp-a-lot msg} 1
+test parseOld-10.12 {syntax errors} {
+ catch gorp-a-lot msg
+ set msg
+} {invalid command name "gorp-a-lot"}
+test parseOld-10.13 {syntax errors} {
+ set a [concat {a}\
+ {b}]
+ set a
+} {a b}
+
+# The next test will fail on the Mac, 'cause the MSL uses a fixed sized
+# buffer for %d conversions (LAME!). I won't leave the test out, however,
+# since MetroWerks may some day fix this.
+
+test parseOld-10.14 {syntax errors} {
+ list [catch {eval \$x[format "%01000d" 0](} msg] $msg $::errorInfo
+} {1 {missing )} {missing )
+ while executing
+"$x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000..."
+ ("eval" body line 1)
+ invoked from within
+"eval \$x[format "%01000d" 0]("}}
+test parseOld-10.15 {syntax errors, missplaced braces} {
+ catch {
+ proc misplaced_end_brace {} {
+ set what foo
+ set when [expr ${what}size - [set off$what]}]
+ } msg
+ set msg
+} {extra characters after close-brace}
+test parseOld-10.16 {syntax errors, missplaced braces} {
+ catch {
+ set a {
+ set what foo
+ set when [expr ${what}size - [set off$what]}]
+ } msg
+ set msg
+} {extra characters after close-brace}
+test parseOld-10.17 {syntax errors, unusual spacing} {
+ list [catch {return [ [1]]} msg] $msg
+} {1 {invalid command name "1"}}
+# Long values (stressing storage management)
+
+set a {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH}
+
+test parseOld-11.1 {long values} {
+ string length $a
+} 214
+test parseOld-11.2 {long values} {
+ llength $a
+} 43
+test parseOld-11.3 {long values} {
+ set b "1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH"
+ set b
+} $a
+test parseOld-11.4 {long values} {
+ set b "$a"
+ set b
+} $a
+test parseOld-11.5 {long values} {
+ set b [set a]
+ set b
+} $a
+test parseOld-11.6 {long values} {
+ set b [concat 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH]
+ string length $b
+} 214
+test parseOld-11.7 {long values} {
+ set b [concat 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH]
+ llength $b
+} 43
+test parseOld-11.8 {long values} {
+ set b
+} $a
+test parseOld-11.9 {long values} {
+ set a [concat 0000 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH IIII JJJJ KKKK LLLL MMMM NNNN OOOO PPPP QQQQ RRRR SSSS TTTT UUUU VVVV WWWW XXXX YYYY ZZZZ]
+ llength $a
+} 62
+set i 0
+foreach j [concat 0000 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH IIII JJJJ KKKK LLLL MMMM NNNN OOOO PPPP QQQQ RRRR SSSS TTTT UUUU VVVV WWWW XXXX YYYY ZZZZ] {
+ set test [string index 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ $i]
+ set test $test$test$test$test
+ test parseOld-11.10-[incr i] {long values} {
+ set j
+ } $test
+}
+test parseOld-11.11 {test buffer overflow in backslashes in braces} {
+ expr {"a" == {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101}}
+} 0
+
+test parseOld-12.1 {comments} {
+ set a old
+ eval { # set a new}
+ set a
+} {old}
+test parseOld-12.2 {comments} {
+ set a old
+ eval " # set a new\nset a new"
+ set a
+} {new}
+test parseOld-12.3 {comments} {
+ set a old
+ eval " # set a new\\\nset a new"
+ set a
+} {old}
+test parseOld-12.4 {comments} {
+ set a old
+ eval " # set a new\\\\\nset a new"
+ set a
+} {new}
+
+test parseOld-13.1 {comments at the end of a bracketed script} {
+ set x "[
+expr 1+1
+# skip this!
+]"
+} {2}
+
+test parseOld-14.1 {TclWordEnd procedure} {testwordend} {
+ testwordend " \n abc"
+} {c}
+test parseOld-14.2 {TclWordEnd procedure} {testwordend} {
+ testwordend " \\\n"
+} {}
+test parseOld-14.3 {TclWordEnd procedure} {testwordend} {
+ testwordend " \\\n "
+} { }
+test parseOld-14.4 {TclWordEnd procedure} {testwordend} {
+ testwordend {"abc"}
+} {"}
+#" Emacs formatting :^(
+test parseOld-14.5 {TclWordEnd procedure} {testwordend} {
+ testwordend {{xyz}}
+} \}
+test parseOld-14.6 {TclWordEnd procedure} {testwordend} {
+ testwordend {{a{}b{}\}} xyz}
+} "\} xyz"
+test parseOld-14.7 {TclWordEnd procedure} {testwordend} {
+ testwordend {abc[this is a]def ghi}
+} {f ghi}
+test parseOld-14.8 {TclWordEnd procedure} {testwordend} {
+ testwordend "puts\\\n\n "
+} "s\\\n\n "
+test parseOld-14.9 {TclWordEnd procedure} {testwordend} {
+ testwordend "puts\\\n "
+} "s\\\n "
+test parseOld-14.10 {TclWordEnd procedure} {testwordend} {
+ testwordend "puts\\\n xyz"
+} "s\\\n xyz"
+test parseOld-14.11 {TclWordEnd procedure} {testwordend} {
+ testwordend {a$x.$y(a long index) foo}
+} ") foo"
+test parseOld-14.12 {TclWordEnd procedure} {testwordend} {
+ testwordend {abc; def}
+} {; def}
+test parseOld-14.13 {TclWordEnd procedure} {testwordend} {
+ testwordend {abc def}
+} {c def}
+test parseOld-14.14 {TclWordEnd procedure} {testwordend} {
+ testwordend {abc def}
+} {c def}
+test parseOld-14.15 {TclWordEnd procedure} {testwordend} {
+ testwordend "abc\ndef"
+} "c\ndef"
+test parseOld-14.16 {TclWordEnd procedure} {testwordend} {
+ testwordend "abc"
+} {c}
+test parseOld-14.17 {TclWordEnd procedure} {testwordend} {
+ testwordend "a\000bc"
+} {c}
+test parseOld-14.18 {TclWordEnd procedure} {testwordend} {
+ testwordend \[a\000\]
+} {]}
+test parseOld-14.19 {TclWordEnd procedure} {testwordend} {
+ testwordend \"a\000\"
+} {"}
+#" Emacs formatting :^(
+test parseOld-14.20 {TclWordEnd procedure} {testwordend} {
+ testwordend a{\000}b
+} {b}
+test parseOld-14.21 {TclWordEnd procedure} {testwordend} {
+ testwordend " \000b"
+} {b}
+
+test parseOld-15.1 {TclScriptEnd procedure} {
+ info complete {puts [
+ expr 1+1
+ #this is a comment ]}
+} {0}
+test parseOld-15.2 {TclScriptEnd procedure} {
+ info complete "abc\\\n"
+} {0}
+test parseOld-15.3 {TclScriptEnd procedure} {
+ info complete "abc\\\\\n"
+} {1}
+test parseOld-15.4 {TclScriptEnd procedure} {
+ info complete "xyz \[abc \{abc\]"
+} {0}
+test parseOld-15.5 {TclScriptEnd procedure} {
+ info complete "xyz \[abc"
+} {0}
+
+# cleanup
+set argv $savedArgv
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/pid.test b/library/msgcat/tests/pid.test
new file mode 100644
index 0000000..d21dbaa
--- /dev/null
+++ b/library/msgcat/tests/pid.test
@@ -0,0 +1,57 @@
+# Commands covered: pid
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1995 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint pidDefined [llength [info commands pid]]
+
+test pid-1.1 {pid command} pidDefined {
+ regexp {(^[0-9]+$)|(^0x[0-9a-fA-F]+$)} [pid]
+} 1
+test pid-1.2 {pid command} -constraints {unixOrPc unixExecs pidDefined} -setup {
+ set path(test1) [makeFile {} test1]
+ file delete $path(test1)
+} -body {
+ set f [open |[list echo foo | cat >$path(test1)] w]
+ set pids [pid $f]
+ close $f
+ list [llength $pids] [regexp {^[0-9]+$} [lindex $pids 0]] \
+ [regexp {^[0-9]+$} [lindex $pids 1]] \
+ [expr {[lindex $pids 0] == [lindex $pids 1]}]
+} -cleanup {
+ removeFile test1
+} -result {2 1 1 0}
+test pid-1.3 {pid command} -constraints pidDefined -setup {
+ set path(test1) [makeFile {} test1]
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ set pids [pid $f]
+ close $f
+ set pids
+} -cleanup {
+ removeFile test1
+} -result {}
+test pid-1.4 {pid command} pidDefined {
+ list [catch {pid a b} msg] $msg
+} {1 {wrong # args: should be "pid ?channelId?"}}
+test pid-1.5 {pid command} pidDefined {
+ list [catch {pid gorp} msg] $msg
+} {1 {can not find channel named "gorp"}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/pkgMkIndex.test b/library/msgcat/tests/pkgMkIndex.test
new file mode 100644
index 0000000..0fe394e
--- /dev/null
+++ b/library/msgcat/tests/pkgMkIndex.test
@@ -0,0 +1,700 @@
+# This file contains tests for the pkg_mkIndex command.
+# Note that the tests are limited to Tcl scripts only, there are no shared
+# libraries against which to test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# All rights reserved.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+set fullPkgPath [makeDirectory pkg]
+
+namespace eval pkgtest {
+ # Namespace for procs we can discard
+}
+
+# pkgtest::parseArgs --
+#
+# Parse an argument list.
+#
+# Arguments:
+# <flags> (optional) arguments starting with a dash are collected as
+# options to pkg_mkIndex and passed to pkg_mkIndex.
+# dirPath the directory to index
+# pattern0 pattern to index
+# ... pattern to index
+# patternN pattern to index
+#
+# Results:
+# Returns a three element list:
+# 0: the options
+# 1: the directory to index
+# 2: the patterns list
+
+proc pkgtest::parseArgs { args } {
+ set options ""
+
+ set argc [llength $args]
+ for {set iarg 0} {$iarg < $argc} {incr iarg} {
+ set a [lindex $args $iarg]
+ if {[regexp {^-} $a]} {
+ lappend options $a
+ if {[string compare -load $a] == 0} {
+ incr iarg
+ lappend options [lindex $args $iarg]
+ }
+ } else {
+ break
+ }
+ }
+
+ set dirPath [lindex $args $iarg]
+ incr iarg
+ set patternList [lrange $args $iarg end]
+
+ return [list $options $dirPath $patternList]
+}
+
+# pkgtest::parseIndex --
+#
+# Loads a pkgIndex.tcl file, records all the calls to "package ifneeded".
+#
+# Arguments:
+# filePath path to the pkgIndex.tcl file.
+#
+# Results:
+# Returns a list, in "array set/get" format, where the keys are the package
+# name and version (in the form "$name:$version"), and the values the rest
+# of the command line.
+
+proc pkgtest::parseIndex { filePath } {
+ # create a slave interpreter, where we override "package ifneeded"
+
+ set slave [interp create]
+ if {[catch {
+ $slave eval {
+ rename package package_original
+ proc package { args } {
+ if {[string compare [lindex $args 0] ifneeded] == 0} {
+ set pkg [lindex $args 1]
+ set ver [lindex $args 2]
+ set ::PKGS($pkg:$ver) [lindex $args 3]
+ } else {
+ return [package_original {*}$args]
+ }
+ }
+ array set ::PKGS {}
+ }
+
+ set dir [file dirname $filePath]
+ $slave eval {set curdir [pwd]}
+ $slave eval [list cd $dir]
+ $slave eval [list set dir $dir]
+ $slave eval [list source [file tail $filePath]]
+ $slave eval {cd $curdir}
+
+ # Create the list in sorted order, so that we don't get spurious
+ # errors because the order has changed.
+
+ array set P {}
+ foreach {k v} [$slave eval {array get ::PKGS}] {
+ set P($k) $v
+ }
+
+ set PKGS ""
+ foreach k [lsort [array names P]] {
+ lappend PKGS $k $P($k)
+ }
+ } err]} {
+ set ei $::errorInfo
+ set ec $::errorCode
+
+ catch {interp delete $slave}
+
+ error $ei $ec
+ }
+
+ interp delete $slave
+
+ return $PKGS
+}
+
+# pkgtest::createIndex --
+#
+# Runs pkg_mkIndex for the given directory and set of patterns. This
+# procedure deletes any pkgIndex.tcl file in the target directory, then runs
+# pkg_mkIndex.
+#
+# Arguments:
+# <flags> (optional) arguments starting with a dash are collected as
+# options to pkg_mkIndex and passed to pkg_mkIndex.
+# dirPath the directory to index
+# pattern0 pattern to index
+# ... pattern to index
+# patternN pattern to index
+#
+# Results:
+# Returns a two element list:
+# 0: 1 if the procedure encountered an error, 0 otherwise.
+# 1: the error result if element 0 was 1
+
+proc pkgtest::createIndex { args } {
+ set parsed [parseArgs {*}$args]
+ set options [lindex $parsed 0]
+ set dirPath [lindex $parsed 1]
+ set patternList [lindex $parsed 2]
+
+ file mkdir $dirPath
+
+ if {[catch {
+ file delete [file join $dirPath pkgIndex.tcl]
+ pkg_mkIndex {*}$options $dirPath {*}$patternList
+ } err]} {
+ return [list 1 $err]
+ }
+
+ return [list 0 {}]
+}
+
+# makePkgList --
+#
+# Takes the output of a pkgtest::parseIndex call, filters it and returns a
+# cleaned up list of packages and their actions.
+#
+# Arguments:
+# inList output from a pkgtest::parseIndex.
+#
+# Results:
+# Returns a list of two element lists:
+# 0: the name:version
+# 1: a list describing the package.
+# For tclPkgSetup packages it consists of:
+# 0: the keyword tclPkgSetup
+# 1: the first file to source, with its exported procedures
+# 2: the second file ...
+# N: the N-1st file ...
+
+proc makePkgList { inList } {
+ set pkgList ""
+
+ foreach {k v} $inList {
+ switch [lindex $v 0] {
+ tclPkgSetup {
+ set l tclPkgSetup
+ foreach s [lindex $v 4] {
+ lappend l $s
+ }
+ }
+ source {
+ set l $v
+ }
+ default {
+ error "can't handle $k $v"
+ }
+ }
+
+ lappend pkgList [list $k $l]
+ }
+
+ return $pkgList
+}
+
+# pkgtest::runIndex --
+#
+# Runs pkg_mkIndex, parses the generated index file.
+#
+# Arguments:
+# <flags> (optional) arguments starting with a dash are collected as
+# options to pkg_mkIndex and passed to pkg_mkIndex.
+# dirPath the directory to index
+# pattern0 pattern to index
+# ... pattern to index
+# patternN pattern to index
+#
+# Results:
+# Returns a two element list:
+# 0: 1 if the procedure encountered an error, 0 otherwise.
+# 1: if no error, this is the parsed generated index file, in the format
+# returned by pkgtest::parseIndex. If error, this is the error result.
+
+proc pkgtest::runCreatedIndex {rv args} {
+ if {[lindex $rv 0] == 0} {
+ set parsed [parseArgs {*}$args]
+ set dirPath [lindex $parsed 1]
+ set idxFile [file join $dirPath pkgIndex.tcl]
+
+ if {[catch {
+ set result [list 0 [makePkgList [parseIndex $idxFile]]]
+ } err]} {
+ set result [list 1 $err]
+ }
+ file delete $idxFile
+ } else {
+ set result $rv
+ }
+
+ return $result
+}
+proc pkgtest::runIndex { args } {
+ set rv [createIndex {*}$args]
+ return [runCreatedIndex $rv {*}$args]
+}
+
+# If there is no match to the patterns, make sure the directory hasn't changed
+# on us
+
+test pkgMkIndex-1.1 {nothing matches pattern - current dir is the same} {
+ list [pkgtest::runIndex -lazy $fullPkgPath nomatch.tcl] [pwd]
+} [list {1 {no files matched glob pattern "nomatch.tcl"}} [pwd]]
+
+makeFile {
+# This is a simple package, just to check basic functionality.
+package provide simple 1.0
+namespace eval simple {
+ namespace export lower upper
+}
+proc simple::lower { stg } {
+ return [string tolower $stg]
+}
+proc simple::upper { stg } {
+ return [string toupper $stg]
+}
+} [file join pkg simple.tcl]
+
+test pkgMkIndex-2.1 {simple package} {
+ pkgtest::runIndex -lazy $fullPkgPath simple.tcl
+} {0 {{simple:1.0 {tclPkgSetup {simple.tcl source {::simple::lower ::simple::upper}}}}}}
+
+test pkgMkIndex-2.2 {simple package - use -direct} {
+ pkgtest::runIndex -direct $fullPkgPath simple.tcl
+} "0 {{simple:1.0 {[list source [file join $fullPkgPath simple.tcl]]}}}"
+
+test pkgMkIndex-2.3 {simple package - direct loading is default} {
+ pkgtest::runIndex $fullPkgPath simple.tcl
+} "0 {{simple:1.0 {[list source [file join $fullPkgPath simple.tcl]]}}}"
+
+test pkgMkIndex-2.4 {simple package - use -verbose} -body {
+ pkgtest::runIndex -verbose $fullPkgPath simple.tcl
+} -result "0 {{simple:1.0 {[list source [file join $fullPkgPath simple.tcl]]}}}" \
+ -errorOutput {successful sourcing of simple.tcl
+packages provided were {simple 1.0}
+processed simple.tcl
+}
+
+removeFile [file join pkg simple.tcl]
+
+makeFile {
+# Contains global symbols, used to check that they don't have a leading ::
+package provide global 1.0
+proc global_lower { stg } {
+ return [string tolower $stg]
+}
+proc global_upper { stg } {
+ return [string toupper $stg]
+}
+} [file join pkg global.tcl]
+
+test pkgMkIndex-3.1 {simple package with global symbols} {
+ pkgtest::runIndex -lazy $fullPkgPath global.tcl
+} {0 {{global:1.0 {tclPkgSetup {global.tcl source {global_lower global_upper}}}}}}
+
+removeFile [file join pkg global.tcl]
+
+makeFile {
+# This package is required by pkg1.
+# This package is split into two files, to test packages that are split over
+# multiple files.
+package provide pkg2 1.0
+namespace eval pkg2 {
+ namespace export p2-1
+}
+proc pkg2::p2-1 { num } {
+ return [expr $num * 2]
+}
+} [file join pkg pkg2_a.tcl]
+
+makeFile {
+# This package is required by pkg1.
+# This package is split into two files, to test packages that are split over
+# multiple files.
+package provide pkg2 1.0
+namespace eval pkg2 {
+ namespace export p2-2
+}
+proc pkg2::p2-2 { num } {
+ return [expr $num * 3]
+}
+} [file join pkg pkg2_b.tcl]
+
+test pkgMkIndex-4.1 {split package} {
+ pkgtest::runIndex -lazy $fullPkgPath pkg2_a.tcl pkg2_b.tcl
+} {0 {{pkg2:1.0 {tclPkgSetup {pkg2_a.tcl source ::pkg2::p2-1} {pkg2_b.tcl source ::pkg2::p2-2}}}}}
+
+test pkgMkIndex-4.2 {split package - direct loading} {
+ pkgtest::runIndex -direct $fullPkgPath pkg2_a.tcl pkg2_b.tcl
+} "0 {{pkg2:1.0 {[list source [file join $fullPkgPath pkg2_a.tcl]]
+[list source [file join $fullPkgPath pkg2_b.tcl]]}}}"
+
+# Add the direct1 directory to auto_path, so that the direct1 package can be
+# found.
+set direct1 [makeDirectory direct1]
+lappend auto_path $direct1
+makeFile {
+# This is referenced by pkgIndex.tcl as a -direct script.
+package provide direct1 1.0
+namespace eval direct1 {
+ namespace export pd1 pd2
+}
+proc direct1::pd1 { stg } {
+ return [string tolower $stg]
+}
+proc direct1::pd2 { stg } {
+ return [string toupper $stg]
+}
+} [file join direct1 direct1.tcl]
+pkg_mkIndex -direct $direct1 direct1.tcl
+
+makeFile {
+# Does a package require of direct1, whose pkgIndex.tcl entry is created
+# above with option -direct. This tests that pkg_mkIndex can handle code
+# that is sourced in pkgIndex.tcl files.
+package require direct1
+package provide std 1.0
+namespace eval std {
+ namespace export p1 p2
+}
+proc std::p1 { stg } {
+ return [string tolower $stg]
+}
+proc std::p2 { stg } {
+ return [string toupper $stg]
+}
+} [file join pkg std.tcl]
+
+test pkgMkIndex-5.1 {requires -direct package} {
+ pkgtest::runIndex -lazy $fullPkgPath std.tcl
+} {0 {{std:1.0 {tclPkgSetup {std.tcl source {::std::p1 ::std::p2}}}}}}
+
+removeFile [file join direct1 direct1.tcl]
+file delete [file join $direct1 pkgIndex.tcl]
+removeDirectory direct1
+removeFile [file join pkg std.tcl]
+
+makeFile {
+# This package requires pkg3, but it does not use any of pkg3's procs in the
+# code that is executed by the file (i.e. references to pkg3's procs are in
+# the proc bodies only).
+package require pkg3 1.0
+package provide pkg1 1.0
+namespace eval pkg1 {
+ namespace export p1-1 p1-2
+}
+proc pkg1::p1-1 { num } {
+ return [pkg3::p3-1 $num]
+}
+proc pkg1::p1-2 { num } {
+ return [pkg3::p3-2 $num]
+}
+} [file join pkg pkg1.tcl]
+
+makeFile {
+package provide pkg3 1.0
+namespace eval pkg3 {
+ namespace export p3-1 p3-2
+}
+proc pkg3::p3-1 { num } {
+ return {[expr $num * 2]}
+}
+proc pkg3::p3-2 { num } {
+ return {[expr $num * 3]}
+}
+} [file join pkg pkg3.tcl]
+
+test pkgMkIndex-6.1 {pkg1 requires pkg3} {
+ pkgtest::runIndex -lazy $fullPkgPath pkg1.tcl pkg3.tcl
+} {0 {{pkg1:1.0 {tclPkgSetup {pkg1.tcl source {::pkg1::p1-1 ::pkg1::p1-2}}}} {pkg3:1.0 {tclPkgSetup {pkg3.tcl source {::pkg3::p3-1 ::pkg3::p3-2}}}}}}
+
+test pkgMkIndex-6.2 {pkg1 requires pkg3 - use -direct} {
+ pkgtest::runIndex -direct $fullPkgPath pkg1.tcl pkg3.tcl
+} "0 {{pkg1:1.0 {[list source [file join $fullPkgPath pkg1.tcl]]}} {pkg3:1.0 {[list source [file join $fullPkgPath pkg3.tcl]]}}}"
+
+removeFile [file join pkg pkg1.tcl]
+
+makeFile {
+# This package requires pkg3, and it calls a pkg3 proc in the code that is
+# executed by the file
+package require pkg3 1.0
+package provide pkg4 1.0
+namespace eval pkg4 {
+ namespace export p4-1 p4-2
+ variable m2 [pkg3::p3-1 10]
+}
+proc pkg4::p4-1 { num } {
+ variable m2
+ return [expr {$m2 * $num}]
+}
+proc pkg4::p4-2 { num } {
+ return [pkg3::p3-2 $num]
+}
+} [file join pkg pkg4.tcl]
+
+test pkgMkIndex-7.1 {pkg4 uses pkg3} {
+ pkgtest::runIndex -lazy $fullPkgPath pkg4.tcl pkg3.tcl
+} {0 {{pkg3:1.0 {tclPkgSetup {pkg3.tcl source {::pkg3::p3-1 ::pkg3::p3-2}}}} {pkg4:1.0 {tclPkgSetup {pkg4.tcl source {::pkg4::p4-1 ::pkg4::p4-2}}}}}}
+
+test pkgMkIndex-7.2 {pkg4 uses pkg3 - use -direct} {
+ pkgtest::runIndex -direct $fullPkgPath pkg4.tcl pkg3.tcl
+} "0 {{pkg3:1.0 {[list source [file join $fullPkgPath pkg3.tcl]]}} {pkg4:1.0 {[list source [file join $fullPkgPath pkg4.tcl]]}}}"
+
+removeFile [file join pkg pkg4.tcl]
+removeFile [file join pkg pkg3.tcl]
+
+makeFile {
+# This package requires pkg2, and it calls a pkg2 proc in the code that is
+# executed by the file. Pkg2 is a split package.
+package require pkg2 1.0
+package provide pkg5 1.0
+namespace eval pkg5 {
+ namespace export p5-1 p5-2
+ variable m2 [pkg2::p2-1 10]
+ variable m3 [pkg2::p2-2 10]
+}
+proc pkg5::p5-1 { num } {
+ variable m2
+ return [expr {$m2 * $num}]
+}
+proc pkg5::p5-2 { num } {
+ variable m2
+ return [expr {$m2 * $num}]
+}
+} [file join pkg pkg5.tcl]
+
+test pkgMkIndex-8.1 {pkg5 uses pkg2} {
+ pkgtest::runIndex -lazy $fullPkgPath pkg5.tcl pkg2_a.tcl pkg2_b.tcl
+} {0 {{pkg2:1.0 {tclPkgSetup {pkg2_a.tcl source ::pkg2::p2-1} {pkg2_b.tcl source ::pkg2::p2-2}}} {pkg5:1.0 {tclPkgSetup {pkg5.tcl source {::pkg5::p5-1 ::pkg5::p5-2}}}}}}
+
+test pkgMkIndex-8.2 {pkg5 uses pkg2 - use -direct} {
+ pkgtest::runIndex -direct $fullPkgPath pkg5.tcl pkg2_a.tcl pkg2_b.tcl
+} "0 {{pkg2:1.0 {[list source [file join $fullPkgPath pkg2_a.tcl]]
+[list source [file join $fullPkgPath pkg2_b.tcl]]}} {pkg5:1.0 {[list source [file join $fullPkgPath pkg5.tcl]]}}}"
+
+removeFile [file join pkg pkg5.tcl]
+removeFile [file join pkg pkg2_a.tcl]
+removeFile [file join pkg pkg2_b.tcl]
+
+makeFile {
+# This package requires circ2, and circ2 requires circ3, which in turn
+# requires circ1. In case of cirularities, pkg_mkIndex should give up when
+# it gets stuck.
+package require circ2 1.0
+package provide circ1 1.0
+namespace eval circ1 {
+ namespace export c1-1 c1-2 c1-3 c1-4
+}
+proc circ1::c1-1 { num } {
+ return [circ2::c2-1 $num]
+}
+proc circ1::c1-2 { num } {
+ return [circ2::c2-2 $num]
+}
+proc circ1::c1-3 {} {
+ return 10
+}
+proc circ1::c1-4 {} {
+ return 20
+}
+} [file join pkg circ1.tcl]
+
+makeFile {
+# This package is required by circ1, and requires circ3. Circ3, in turn,
+# requires circ1 to give us a circularity.
+package require circ3 1.0
+package provide circ2 1.0
+namespace eval circ2 {
+ namespace export c2-1 c2-2
+}
+proc circ2::c2-1 { num } {
+ return [expr $num * [circ3::c3-1]]
+}
+proc circ2::c2-2 { num } {
+ return [expr $num * [circ3::c3-2]]
+}
+} [file join pkg circ2.tcl]
+
+makeFile {
+# This package is required by circ2, and in turn requires circ1. This closes
+# the circularity.
+package require circ1 1.0
+package provide circ3 1.0
+namespace eval circ3 {
+ namespace export c3-1 c3-4
+}
+proc circ3::c3-1 {} {
+ return [circ1::c1-3]
+}
+proc circ3::c3-2 {} {
+ return [circ1::c1-4]
+}
+} [file join pkg circ3.tcl]
+
+test pkgMkIndex-9.1 {circular packages} {
+ pkgtest::runIndex -lazy $fullPkgPath circ1.tcl circ2.tcl circ3.tcl
+} {0 {{circ1:1.0 {tclPkgSetup {circ1.tcl source {::circ1::c1-1 ::circ1::c1-2 ::circ1::c1-3 ::circ1::c1-4}}}} {circ2:1.0 {tclPkgSetup {circ2.tcl source {::circ2::c2-1 ::circ2::c2-2}}}} {circ3:1.0 {tclPkgSetup {circ3.tcl source ::circ3::c3-1}}}}}
+
+removeFile [file join pkg circ1.tcl]
+removeFile [file join pkg circ2.tcl]
+removeFile [file join pkg circ3.tcl]
+
+# Some tests require the existence of one of the DLLs in the dltest directory
+set x [file join [file dirname [info nameofexecutable]] dltest \
+ pkga[info sharedlibextension]]
+set dll "[file tail $x]Required"
+testConstraint $dll [file exists $x]
+
+if {[testConstraint $dll]} {
+ makeFile {
+# This package provides Pkga, which is also provided by a DLL.
+package provide Pkga 1.0
+proc pkga_neq { x } {
+ return [expr {! [pkgq_eq $x]}]
+}
+} [file join pkg pkga.tcl]
+ file copy -force $x $fullPkgPath
+}
+testConstraint exec [llength [info commands ::exec]]
+
+test pkgMkIndex-10.1 {package in DLL and script} [list exec $dll] {
+ # Do all [load]ing of shared libraries in another process, so we can
+ # delete the file and not get stuck because we're holding a reference to
+ # it.
+ set cmd [list pkg_mkIndex -lazy $fullPkgPath [file tail $x] pkga.tcl]
+ exec [interpreter] << $cmd
+ pkgtest::runCreatedIndex {0 {}} -lazy $fullPkgPath pkga[info sharedlibextension] pkga.tcl
+} "0 {{Pkga:1.0 {tclPkgSetup {pkga[info sharedlibextension] load {pkga_eq pkga_quote}} {pkga.tcl source pkga_neq}}}}"
+test pkgMkIndex-10.2 {package in DLL hidden by -load} [list exec $dll] {
+ # Do all [load]ing of shared libraries in another process, so we can
+ # delete the file and not get stuck because we're holding a reference to
+ # it.
+ #
+ # This test depends on context from prior test, so repeat it.
+ set script \
+ "[list pkg_mkIndex -lazy $fullPkgPath [file tail $x] pkga.tcl]"
+ append script \n \
+ "[list pkg_mkIndex -lazy -load Pkg* $fullPkgPath [file tail $x]]"
+ exec [interpreter] << $script
+ pkgtest::runCreatedIndex {0 {}} -lazy -load Pkg* -- $fullPkgPath pkga[info sharedlibextension]
+} {0 {}}
+
+if {[testConstraint $dll]} {
+ file delete -force [file join $fullPkgPath [file tail $x]]
+ removeFile [file join pkg pkga.tcl]
+}
+
+# Tolerate "namespace import" at the global scope
+
+makeFile {
+package provide fubar 1.0
+namespace eval ::fubar:: {
+ #
+ # export only public functions.
+ #
+ namespace export {[a-z]*}
+}
+proc ::fubar::foo {bar} {
+ puts "$bar"
+ return true
+}
+namespace import ::fubar::foo
+} [file join pkg import.tcl]
+
+test pkgMkIndex-11.1 {conflicting namespace imports} {
+ pkgtest::runIndex -lazy $fullPkgPath import.tcl
+} {0 {{fubar:1.0 {tclPkgSetup {import.tcl source ::fubar::foo}}}}}
+
+removeFile [file join pkg import.tcl]
+
+# Verify that the auto load list generated is correct even when there is a
+# proc name conflict between two namespaces (ie, ::foo::baz and ::bar::baz)
+
+makeFile {
+package provide football 1.0
+namespace eval ::pro:: {
+ #
+ # export only public functions.
+ #
+ namespace export {[a-z]*}
+}
+namespace eval ::college:: {
+ #
+ # export only public functions.
+ #
+ namespace export {[a-z]*}
+}
+proc ::pro::team {} {
+ puts "go packers!"
+ return true
+}
+proc ::college::team {} {
+ puts "go badgers!"
+ return true
+}
+} [file join pkg samename.tcl]
+
+test pkgMkIndex-12.1 {same name procs in different namespace} {
+ pkgtest::runIndex -lazy $fullPkgPath samename.tcl
+} {0 {{football:1.0 {tclPkgSetup {samename.tcl source {::college::team ::pro::team}}}}}}
+
+removeFile [file join pkg samename.tcl]
+
+# Proc names with embedded spaces are properly listed (ie, correct number of
+# braces) in result
+makeFile {
+package provide spacename 1.0
+proc {a b} {} {}
+proc {c d} {} {}
+} [file join pkg spacename.tcl]
+
+test pkgMkIndex-13.1 {proc names with embedded spaces} {
+ pkgtest::runIndex -lazy $fullPkgPath spacename.tcl
+} {0 {{spacename:1.0 {tclPkgSetup {spacename.tcl source {{a b} {c d}}}}}}}
+
+removeFile [file join pkg spacename.tcl]
+
+# Test the tcl::Pkg::CompareExtension helper function
+test pkgMkIndex-14.1 {tcl::Pkg::CompareExtension} {unix} {
+ tcl::Pkg::CompareExtension foo.so .so
+} 1
+test pkgMkIndex-14.2 {tcl::Pkg::CompareExtension} {unix} {
+ tcl::Pkg::CompareExtension foo.so.bar .so
+} 0
+test pkgMkIndex-14.3 {tcl::Pkg::CompareExtension} {unix} {
+ tcl::Pkg::CompareExtension foo.so.1 .so
+} 1
+test pkgMkIndex-14.4 {tcl::Pkg::CompareExtension} {unix} {
+ tcl::Pkg::CompareExtension foo.so.1.2 .so
+} 1
+test pkgMkIndex-14.5 {tcl::Pkg::CompareExtension} {unix} {
+ tcl::Pkg::CompareExtension foo .so
+} 0
+test pkgMkIndex-14.6 {tcl::Pkg::CompareExtension} {unix} {
+ tcl::Pkg::CompareExtension foo.so.1.2.bar .so
+} 0
+
+# cleanup
+
+removeDirectory pkg
+
+namespace delete pkgtest
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/platform.test b/library/msgcat/tests/platform.test
new file mode 100644
index 0000000..92ca7ab
--- /dev/null
+++ b/library/msgcat/tests/platform.test
@@ -0,0 +1,59 @@
+# The file tests the tcl_platform variable
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testCPUID [llength [info commands testcpuid]]
+
+test platform-1.1 {TclpSetVariables: tcl_platform} {
+ interp create i
+ i eval {catch {unset tcl_platform(debug)}}
+ i eval {catch {unset tcl_platform(threaded)}}
+ set result [i eval {lsort [array names tcl_platform]}]
+ interp delete i
+ set result
+} {byteOrder machine os osVersion pathSeparator platform pointerSize user wordSize}
+
+# Test assumes twos-complement arithmetic, which is true of virtually
+# everything these days. Note that this does *not* use wide(), and
+# this is intentional since that could make Tcl's numbers wider than
+# the machine-integer on some platforms...
+test platform-2.1 {tcl_platform(wordSize) indicates size of native word} {
+ set result [expr {int(1 << (8 * $tcl_platform(wordSize) - 1))}]
+ # Result must be the largest bit in a machine word, which this checks
+ # without assuming how wide the word really is
+ list [expr {$result < 0}] [expr {$result ^ int($result - 1)}]
+} {1 -1}
+
+# On Windows/UNIX, test that the CPU ID works
+
+test platform-3.1 {CPU ID on Windows/UNIX} \
+ -constraints testCPUID \
+ -body {
+ set cpudata [testcpuid 0]
+ binary format iii \
+ [lindex $cpudata 1] \
+ [lindex $cpudata 3] \
+ [lindex $cpudata 2]
+ } \
+ -match regexp \
+ -result {^(?:AuthenticAMD|CentaurHauls|CyrixInstead|GenuineIntel)$}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/proc-old.test b/library/msgcat/tests/proc-old.test
new file mode 100644
index 0000000..e45cf5c
--- /dev/null
+++ b/library/msgcat/tests/proc-old.test
@@ -0,0 +1,517 @@
+# Commands covered: proc, return, global
+#
+# This file, proc-old.test, includes the original set of tests for Tcl's
+# proc, return, and global commands. There is now a new file proc.test
+# that contains tests for the tclProc.c source file.
+#
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+catch {rename t1 ""}
+catch {rename foo ""}
+
+proc tproc {} {return a; return b}
+test proc-old-1.1 {simple procedure call and return} {tproc} a
+proc tproc x {
+ set x [expr $x+1]
+ return $x
+}
+test proc-old-1.2 {simple procedure call and return} {tproc 2} 3
+test proc-old-1.3 {simple procedure call and return} {
+ proc tproc {} {return foo}
+} {}
+test proc-old-1.4 {simple procedure call and return} {
+ proc tproc {} {return}
+ tproc
+} {}
+proc tproc1 {a} {incr a; return $a}
+proc tproc2 {a b} {incr a; return $a}
+test proc-old-1.5 {simple procedure call and return (2 procs with same body but different parameters)} {
+ list [tproc1 123] [tproc2 456 789]
+} {124 457}
+test proc-old-1.6 {simple procedure call and return (shared proc body string)} {
+ set x {}
+ proc tproc {} {} ;# body is shared with x
+ list [tproc] [append x foo]
+} {{} foo}
+
+test proc-old-2.1 {local and global variables} {
+ proc tproc x {
+ set x [expr $x+1]
+ return $x
+ }
+ set x 42
+ list [tproc 6] $x
+} {7 42}
+test proc-old-2.2 {local and global variables} {
+ proc tproc x {
+ set y [expr $x+1]
+ return $y
+ }
+ set y 18
+ list [tproc 6] $y
+} {7 18}
+test proc-old-2.3 {local and global variables} {
+ proc tproc x {
+ global y
+ set y [expr $x+1]
+ return $y
+ }
+ set y 189
+ list [tproc 6] $y
+} {7 7}
+test proc-old-2.4 {local and global variables} {
+ proc tproc x {
+ global y
+ return [expr $x+$y]
+ }
+ set y 189
+ list [tproc 6] $y
+} {195 189}
+catch {unset _undefined_}
+test proc-old-2.5 {local and global variables} {
+ proc tproc x {
+ global _undefined_
+ return $_undefined_
+ }
+ list [catch {tproc xxx} msg] $msg
+} {1 {can't read "_undefined_": no such variable}}
+test proc-old-2.6 {local and global variables} {
+ set a 114
+ set b 115
+ global a b
+ list $a $b
+} {114 115}
+
+proc do {cmd} {eval $cmd}
+test proc-old-3.1 {local and global arrays} {
+ catch {unset a}
+ set a(0) 22
+ list [catch {do {global a; set a(0)}} msg] $msg
+} {0 22}
+test proc-old-3.2 {local and global arrays} {
+ catch {unset a}
+ set a(x) 22
+ list [catch {do {global a; set a(x) newValue}} msg] $msg $a(x)
+} {0 newValue newValue}
+test proc-old-3.3 {local and global arrays} {
+ catch {unset a}
+ set a(x) 22
+ set a(y) 33
+ list [catch {do {global a; unset a(y)}; array names a} msg] $msg
+} {0 x}
+test proc-old-3.4 {local and global arrays} {
+ catch {unset a}
+ set a(x) 22
+ set a(y) 33
+ list [catch {do {global a; unset a; info exists a}} msg] $msg \
+ [info exists a]
+} {0 0 0}
+test proc-old-3.5 {local and global arrays} {
+ catch {unset a}
+ set a(x) 22
+ set a(y) 33
+ list [catch {do {global a; unset a(y); array names a}} msg] $msg
+} {0 x}
+catch {unset a}
+test proc-old-3.6 {local and global arrays} {
+ catch {unset a}
+ set a(x) 22
+ set a(y) 33
+ do {global a; do {global a; unset a}; set a(z) 22}
+ list [catch {array names a} msg] $msg
+} {0 z}
+test proc-old-3.7 {local and global arrays} {
+ proc t1 {args} {global info; set info 1}
+ catch {unset a}
+ set info {}
+ do {global a; trace var a(1) w t1}
+ set a(1) 44
+ set info
+} 1
+test proc-old-3.8 {local and global arrays} {
+ proc t1 {args} {global info; set info 1}
+ catch {unset a}
+ trace var a(1) w t1
+ set info {}
+ do {global a; trace vdelete a(1) w t1}
+ set a(1) 44
+ set info
+} {}
+test proc-old-3.9 {local and global arrays} {
+ proc t1 {args} {global info; set info 1}
+ catch {unset a}
+ trace var a(1) w t1
+ do {global a; trace vinfo a(1)}
+} {{w t1}}
+catch {unset a}
+
+test proc-old-30.1 {arguments and defaults} {
+ proc tproc {x y z} {
+ return [list $x $y $z]
+ }
+ tproc 11 12 13
+} {11 12 13}
+test proc-old-30.2 {arguments and defaults} {
+ proc tproc {x y z} {
+ return [list $x $y $z]
+ }
+ list [catch {tproc 11 12} msg] $msg
+} {1 {wrong # args: should be "tproc x y z"}}
+test proc-old-30.3 {arguments and defaults} {
+ proc tproc {x y z} {
+ return [list $x $y $z]
+ }
+ list [catch {tproc 11 12 13 14} msg] $msg
+} {1 {wrong # args: should be "tproc x y z"}}
+test proc-old-30.4 {arguments and defaults} {
+ proc tproc {x {y y-default} {z z-default}} {
+ return [list $x $y $z]
+ }
+ tproc 11 12 13
+} {11 12 13}
+test proc-old-30.5 {arguments and defaults} {
+ proc tproc {x {y y-default} {z z-default}} {
+ return [list $x $y $z]
+ }
+ tproc 11 12
+} {11 12 z-default}
+test proc-old-30.6 {arguments and defaults} {
+ proc tproc {x {y y-default} {z z-default}} {
+ return [list $x $y $z]
+ }
+ tproc 11
+} {11 y-default z-default}
+test proc-old-30.7 {arguments and defaults} {
+ proc tproc {x {y y-default} {z z-default}} {
+ return [list $x $y $z]
+ }
+ list [catch {tproc} msg] $msg
+} {1 {wrong # args: should be "tproc x ?y? ?z?"}}
+test proc-old-30.8 {arguments and defaults} {
+ list [catch {
+ proc tproc {x {y y-default} z} {
+ return [list $x $y $z]
+ }
+ tproc 2 3
+ } msg] $msg
+} {1 {wrong # args: should be "tproc x ?y? z"}}
+test proc-old-30.9 {arguments and defaults} {
+ proc tproc {x {y y-default} args} {
+ return [list $x $y $args]
+ }
+ tproc 2 3 4 5
+} {2 3 {4 5}}
+test proc-old-30.10 {arguments and defaults} {
+ proc tproc {x {y y-default} args} {
+ return [list $x $y $args]
+ }
+ tproc 2 3
+} {2 3 {}}
+test proc-old-30.11 {arguments and defaults} {
+ proc tproc {x {y y-default} args} {
+ return [list $x $y $args]
+ }
+ tproc 2
+} {2 y-default {}}
+test proc-old-30.12 {arguments and defaults} {
+ proc tproc {x {y y-default} args} {
+ return [list $x $y $args]
+ }
+ list [catch {tproc} msg] $msg
+} {1 {wrong # args: should be "tproc x ?y? ?arg ...?"}}
+
+test proc-old-4.1 {variable numbers of arguments} {
+ proc tproc args {return $args}
+ tproc
+} {}
+test proc-old-4.2 {variable numbers of arguments} {
+ proc tproc args {return $args}
+ tproc 1 2 3 4 5 6 7 8
+} {1 2 3 4 5 6 7 8}
+test proc-old-4.3 {variable numbers of arguments} {
+ proc tproc args {return $args}
+ tproc 1 {2 3} {4 {5 6} {{{7}}}} 8
+} {1 {2 3} {4 {5 6} {{{7}}}} 8}
+test proc-old-4.4 {variable numbers of arguments} {
+ proc tproc {x y args} {return $args}
+ tproc 1 2 3 4 5 6 7
+} {3 4 5 6 7}
+test proc-old-4.5 {variable numbers of arguments} {
+ proc tproc {x y args} {return $args}
+ tproc 1 2
+} {}
+test proc-old-4.6 {variable numbers of arguments} {
+ proc tproc {x missing args} {return $args}
+ list [catch {tproc 1} msg] $msg
+} {1 {wrong # args: should be "tproc x missing ?arg ...?"}}
+
+test proc-old-5.1 {error conditions} {
+ list [catch {proc} msg] $msg
+} {1 {wrong # args: should be "proc name args body"}}
+test proc-old-5.2 {error conditions} {
+ list [catch {proc tproc b} msg] $msg
+} {1 {wrong # args: should be "proc name args body"}}
+test proc-old-5.3 {error conditions} {
+ list [catch {proc tproc b c d e} msg] $msg
+} {1 {wrong # args: should be "proc name args body"}}
+test proc-old-5.4 {error conditions} {
+ list [catch {proc tproc \{xyz {return foo}} msg] $msg
+} {1 {unmatched open brace in list}}
+test proc-old-5.5 {error conditions} {
+ list [catch {proc tproc {{} y} {return foo}} msg] $msg
+} {1 {argument with no name}}
+test proc-old-5.6 {error conditions} {
+ list [catch {proc tproc {{} y} {return foo}} msg] $msg
+} {1 {argument with no name}}
+test proc-old-5.7 {error conditions} {
+ list [catch {proc tproc {{x 1 2} y} {return foo}} msg] $msg
+} {1 {too many fields in argument specifier "x 1 2"}}
+test proc-old-5.8 {error conditions} {
+ catch {return}
+} 2
+proc tproc {} {
+ set a 22
+ global a
+}
+test proc-old-5.10 {error conditions} {
+ list [catch {tproc} msg] $msg
+} {1 {variable "a" already exists}}
+test proc-old-5.11 {error conditions} {
+ catch {rename tproc {}}
+ catch {
+ proc tproc {x {} z} {return foo}
+ }
+ list [catch {tproc 1} msg] $msg
+} {1 {invalid command name "tproc"}}
+test proc-old-5.12 {error conditions} {
+ proc tproc {} {
+ set a 22
+ error "error in procedure"
+ return
+ }
+ list [catch tproc msg] $msg
+} {1 {error in procedure}}
+test proc-old-5.13 {error conditions} {
+ proc tproc {} {
+ set a 22
+ error "error in procedure"
+ return
+ }
+ catch tproc msg
+ set ::errorInfo
+} {error in procedure
+ while executing
+"error "error in procedure""
+ (procedure "tproc" line 3)
+ invoked from within
+"tproc"}
+test proc-old-5.14 {error conditions} {
+ proc tproc {} {
+ set a 22
+ break
+ return
+ }
+ catch tproc msg
+ set ::errorInfo
+} {invoked "break" outside of a loop
+ (procedure "tproc" line 1)
+ invoked from within
+"tproc"}
+test proc-old-5.15 {error conditions} {
+ proc tproc {} {
+ set a 22
+ continue
+ return
+ }
+ catch tproc msg
+ set ::errorInfo
+} {invoked "continue" outside of a loop
+ (procedure "tproc" line 1)
+ invoked from within
+"tproc"}
+test proc-old-5.16 {error conditions} {
+ proc foo args {
+ global fooMsg
+ set fooMsg "foo was called: $args"
+ }
+ proc tproc {} {
+ set x 44
+ trace var x u foo
+ while {$x < 100} {
+ error "Nested error"
+ }
+ }
+ set fooMsg "foo not called"
+ list [catch tproc msg] $msg $::errorInfo $fooMsg
+} {1 {Nested error} {Nested error
+ while executing
+"error "Nested error""
+ (procedure "tproc" line 5)
+ invoked from within
+"tproc"} {foo was called: x {} u}}
+
+# The tests below will really only be useful when run under Purify or
+# some other system that can detect accesses to freed memory...
+
+test proc-old-6.1 {procedure that redefines itself} {
+ proc tproc {} {
+ proc tproc {} {
+ return 44
+ }
+ return 45
+ }
+ tproc
+} 45
+test proc-old-6.2 {procedure that deletes itself} {
+ proc tproc {} {
+ rename tproc {}
+ return 45
+ }
+ tproc
+} 45
+
+proc tproc code {
+ return -code $code abc
+}
+test proc-old-7.1 {return with special completion code} {
+ list [catch {tproc ok} msg] $msg
+} {0 abc}
+test proc-old-7.2 {return with special completion code} {
+ list [catch {tproc error} msg] $msg $::errorInfo $::errorCode
+} {1 abc {abc
+ while executing
+"tproc error"} NONE}
+test proc-old-7.3 {return with special completion code} {
+ list [catch {tproc return} msg] $msg
+} {2 abc}
+test proc-old-7.4 {return with special completion code} {
+ list [catch {tproc break} msg] $msg
+} {3 abc}
+test proc-old-7.5 {return with special completion code} {
+ list [catch {tproc continue} msg] $msg
+} {4 abc}
+test proc-old-7.6 {return with special completion code} {
+ list [catch {tproc -14} msg] $msg
+} {-14 abc}
+test proc-old-7.7 {return with special completion code} -body {
+ tproc err
+} -returnCodes error -match glob -result {bad completion code "err": must be ok, error, return, break, continue*, or an integer}
+test proc-old-7.8 {return with special completion code} -body {
+ tproc 10b
+} -returnCodes error -match glob -result {bad completion code "10b": must be ok, error, return, break, continue*, or an integer}
+test proc-old-7.9 {return with special completion code} {
+ proc tproc2 {} {
+ tproc return
+ }
+ list [catch tproc2 msg] $msg
+} {0 abc}
+test proc-old-7.10 {return with special completion code} {
+ proc tproc2 {} {
+ return -code error
+ }
+ list [catch tproc2 msg] $msg
+} {1 {}}
+test proc-old-7.11 {return with special completion code} {
+ proc tproc2 {} {
+ global errorCode errorInfo
+ catch {open _bad_file_name r} msg
+ return -code error -errorinfo $errorInfo -errorcode $errorCode $msg
+ }
+ set msg [list [catch tproc2 msg] $msg $::errorInfo $::errorCode]
+ regsub -all [file join {} _bad_file_name] $msg "_bad_file_name" msg
+ normalizeMsg $msg
+} {1 {couldn't open "_bad_file_name": no such file or directory} {couldn't open "_bad_file_name": no such file or directory
+ while executing
+"open _bad_file_name r"
+ invoked from within
+"tproc2"} {posix enoent {no such file or directory}}}
+test proc-old-7.12 {return with special completion code} {
+ proc tproc2 {} {
+ global errorCode errorInfo
+ catch {open _bad_file_name r} msg
+ return -code error -errorcode $errorCode $msg
+ }
+ set msg [list [catch tproc2 msg] $msg $::errorInfo $::errorCode]
+ regsub -all [file join {} _bad_file_name] $msg "_bad_file_name" msg
+ normalizeMsg $msg
+} {1 {couldn't open "_bad_file_name": no such file or directory} {couldn't open "_bad_file_name": no such file or directory
+ while executing
+"tproc2"} {posix enoent {no such file or directory}}}
+test proc-old-7.13 {return with special completion code} {
+ proc tproc2 {} {
+ global errorCode errorInfo
+ catch {open _bad_file_name r} msg
+ return -code error -errorinfo $errorInfo $msg
+ }
+ set msg [list [catch tproc2 msg] $msg $::errorInfo $::errorCode]
+ regsub -all [file join {} _bad_file_name] $msg "_bad_file_name" msg
+ normalizeMsg $msg
+} {1 {couldn't open "_bad_file_name": no such file or directory} {couldn't open "_bad_file_name": no such file or directory
+ while executing
+"open _bad_file_name r"
+ invoked from within
+"tproc2"} none}
+test proc-old-7.14 {return with special completion code} {
+ proc tproc2 {} {
+ global errorCode errorInfo
+ catch {open _bad_file_name r} msg
+ return -code error $msg
+ }
+ set msg [list [catch tproc2 msg] $msg $::errorInfo $::errorCode]
+ regsub -all [file join {} _bad_file_name] $msg "_bad_file_name" msg
+ normalizeMsg $msg
+} {1 {couldn't open "_bad_file_name": no such file or directory} {couldn't open "_bad_file_name": no such file or directory
+ while executing
+"tproc2"} none}
+test proc-old-7.15 {return with special completion code} {
+ list [catch {return -badOption foo message} msg] $msg
+} {2 message}
+
+test proc-old-8.1 {unset and undefined local arrays} {
+ proc t1 {} {
+ foreach v {xxx, yyy} {
+ catch {unset $v}
+ }
+ set yyy(foo) bar
+ }
+ t1
+} bar
+
+test proc-old-9.1 {empty command name} {
+ catch {rename {} ""}
+ proc t1 {args} {
+ return
+ }
+ set v [t1]
+ catch {$v}
+} 1
+
+test proc-old-10.1 {ByteCode epoch change during recursive proc execution} {
+ proc t1 x {
+ set y 20
+ rename expr expr.old
+ rename expr.old expr
+ if $x then {t1 0} ;# recursive call after foo's code is invalidated
+ return 20
+ }
+ t1 1
+} 20
+
+# cleanup
+catch {rename t1 ""}
+catch {rename foo ""}
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/proc.test b/library/msgcat/tests/proc.test
new file mode 100644
index 0000000..e06720e
--- /dev/null
+++ b/library/msgcat/tests/proc.test
@@ -0,0 +1,396 @@
+# This file contains tests for the tclProc.c source file. Tests appear in the
+# same order as the C code that they test. The set of tests is currently
+# incomplete since it includes only new tests, in particular tests for code
+# changed for the addition of Tcl namespaces. Other procedure-related tests
+# appear in other test files such as proc-old.test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint procbodytest [expr {![catch {package require procbodytest}]}]
+testConstraint memory [llength [info commands memory]]
+
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+catch {rename p ""}
+catch {rename {} ""}
+catch {unset msg}
+
+test proc-1.1 {Tcl_ProcObjCmd, put proc in namespace specified in name, if any} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ namespace eval test_ns_1 {
+ namespace eval baz {}
+ }
+ proc test_ns_1::baz::p {} {
+ return "p in [namespace current]"
+ }
+ list [test_ns_1::baz::p] \
+ [namespace eval test_ns_1 {baz::p}] \
+ [info commands test_ns_1::baz::*]
+} -result {{p in ::test_ns_1::baz} {p in ::test_ns_1::baz} ::test_ns_1::baz::p}
+test proc-1.2 {Tcl_ProcObjCmd, namespace specified in proc name must exist} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -returnCodes error -body {
+ proc test_ns_1::baz::p {} {}
+} -result {can't create procedure "test_ns_1::baz::p": unknown namespace}
+test proc-1.3 {Tcl_ProcObjCmd, empty proc name} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ proc :: {} {
+ return "empty called"
+ }
+ list [::] \
+ [info body {}]
+} -result {{empty called} {
+ return "empty called"
+ }}
+test proc-1.4 {Tcl_ProcObjCmd, simple proc name and proc defined in namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ namespace eval test_ns_1 {
+ namespace eval baz {
+ proc p {} {
+ return "p in [namespace current]"
+ }
+ }
+ }
+ list [test_ns_1::baz::p] \
+ [info commands test_ns_1::baz::*]
+} -result {{p in ::test_ns_1::baz} ::test_ns_1::baz::p}
+test proc-1.5 {Tcl_ProcObjCmd, qualified proc name and proc defined in namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ namespace eval test_ns_1::baz {}
+ namespace eval test_ns_1 {
+ proc baz::p {} {
+ return "p in [namespace current]"
+ }
+ }
+ list [test_ns_1::baz::p] \
+ [info commands test_ns_1::baz::*] \
+ [namespace eval test_ns_1::baz {namespace which p}]
+} -result {{p in ::test_ns_1::baz} ::test_ns_1::baz::p ::test_ns_1::baz::p}
+test proc-1.6 {Tcl_ProcObjCmd, namespace code ignores single ":"s in middle or end of command names} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ namespace eval test_ns_1 {
+ proc q: {} {return "q:"}
+ proc value:at: {} {return "value:at:"}
+ }
+ list [namespace eval test_ns_1 {q:}] \
+ [namespace eval test_ns_1 {value:at:}] \
+ [test_ns_1::q:] \
+ [test_ns_1::value:at:] \
+ [lsort [info commands test_ns_1::*]] \
+ [namespace eval test_ns_1 {namespace which q:}] \
+ [namespace eval test_ns_1 {namespace which value:at:}]
+} -result {q: value:at: q: value:at: {::test_ns_1::q: ::test_ns_1::value:at:} ::test_ns_1::q: ::test_ns_1::value:at:}
+test proc-1.7 {Tcl_ProcObjCmd, check that formal parameter names are not array elements} -setup {
+ catch {rename p ""}
+} -returnCodes error -body {
+ proc p {a(1) a(2)} {
+ set z [expr $a(1)+$a(2)]
+ puts "$z=z, $a(1)=$a(1)"
+ }
+} -result {formal parameter "a(1)" is an array element}
+test proc-1.8 {Tcl_ProcObjCmd, check that formal parameter names are simple names} -setup {
+ catch {rename p ""}
+} -body {
+ proc p {b:a b::a} {
+ }
+} -returnCodes error -result {formal parameter "b::a" is not a simple name}
+
+test proc-2.1 {TclFindProc, simple proc name and proc not in namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename p ""}
+} -body {
+ proc p {} {return "p in [namespace current]"}
+ info body p
+} -result {return "p in [namespace current]"}
+test proc-2.2 {TclFindProc, simple proc name and proc defined in namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ namespace eval test_ns_1 {
+ namespace eval baz {
+ proc p {} {return "p in [namespace current]"}
+ }
+ }
+ namespace eval test_ns_1::baz {info body p}
+} -result {return "p in [namespace current]"}
+test proc-2.3 {TclFindProc, qualified proc name and proc defined in namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ namespace eval test_ns_1::baz {}
+ namespace eval test_ns_1 {
+ proc baz::p {} {return "p in [namespace current]"}
+ }
+ namespace eval test_ns_1 {info body baz::p}
+} -result {return "p in [namespace current]"}
+test proc-2.4 {TclFindProc, global proc and executing in namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename p ""}
+} -body {
+ proc p {} {return "global p"}
+ namespace eval test_ns_1::baz {info body p}
+} -result {return "global p"}
+
+test proc-3.1 {TclObjInterpProc, proc defined and executing in same namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ proc p {} {return "p in [namespace current]"}
+ p
+} -result {p in ::}
+test proc-3.2 {TclObjInterpProc, proc defined and executing in same namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ namespace eval test_ns_1::baz {
+ proc p {} {return "p in [namespace current]"}
+ p
+ }
+} -result {p in ::test_ns_1::baz}
+test proc-3.3 {TclObjInterpProc, proc defined and executing in different namespaces} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename p ""}
+} -body {
+ proc p {} {return "p in [namespace current]"}
+ namespace eval test_ns_1::baz {
+ p
+ }
+} -result {p in ::}
+test proc-3.4 {TclObjInterpProc, procs execute in the namespace in which they were defined unless renamed into new namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename p ""}
+} -body {
+ namespace eval test_ns_1::baz {
+ proc p {} {return "p in [namespace current]"}
+ rename ::test_ns_1::baz::p ::p
+ list [p] [namespace which p]
+ }
+} -result {{p in ::} ::p}
+test proc-3.5 {TclObjInterpProc, any old result is reset before appending error msg about missing arguments} -body {
+ proc p {x} {info commands 3m}
+ p
+} -returnCodes error -result {wrong # args: should be "p x"}
+test proc-3.6 {TclObjInterpProc, proper quoting of proc name, Bug 942757} -body {
+ proc {a b c} {x} {info commands 3m}
+ {a b c}
+} -returnCodes error -result {wrong # args: should be "{a b c} x"}
+
+test proc-3.7 {TclObjInterpProc, wrong num args, Bug 3366265} {
+ proc {} {x} {}
+ list [catch {{}} msg] $msg
+} {1 {wrong # args: should be "{} x"}}
+
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+catch {rename p ""}
+catch {rename {} ""}
+catch {rename {a b c} {}}
+catch {unset msg}
+
+catch {rename p ""}
+catch {rename t ""}
+
+# Note that the test require that procedures whose body is used to create
+# procbody objects must be executed before the procbodytest::proc command is
+# executed, so that the Proc struct is populated correctly (CompiledLocals are
+# added at compile time).
+
+test proc-4.1 {TclCreateProc, procbody obj} -constraints procbodytest -body {
+ proc p x {return "$x:$x"}
+ set rv [p P]
+ procbodytest::proc t x p
+ lappend rv [t T]
+} -cleanup {
+ catch {rename p ""}
+ catch {rename t ""}
+} -result {P:P T:T}
+test proc-4.2 {TclCreateProc, procbody obj, use compiled locals} -body {
+ proc p x {
+ set y [string tolower $x]
+ return "$x:$y"
+ }
+ set rv [p P]
+ procbodytest::proc t x p
+ lappend rv [t T]
+} -constraints procbodytest -cleanup {
+ catch {rename p ""}
+ catch {rename t ""}
+} -result {P:p T:t}
+test proc-4.3 {TclCreateProc, procbody obj, too many args} -body {
+ proc p x {
+ set y [string tolower $x]
+ return "$x:$y"
+ }
+ set rv [p P]
+ procbodytest::proc t {x x1 x2} p
+ lappend rv [t T]
+} -constraints procbodytest -returnCodes error -cleanup {
+ catch {rename p ""}
+ catch {rename t ""}
+} -result {procedure "t": arg list contains 3 entries, precompiled header expects 1}
+test proc-4.4 {TclCreateProc, procbody obj, inconsistent arg name} -body {
+ proc p {x y z} {
+ set v [join [list $x $y $z]]
+ set w [string tolower $v]
+ return "$v:$w"
+ }
+ set rv [p P Q R]
+ procbodytest::proc t {x x1 z} p
+ lappend rv [t S T U]
+} -constraints procbodytest -returnCodes error -cleanup {
+ catch {rename p ""}
+ catch {rename t ""}
+} -result {procedure "t": formal parameter 1 is inconsistent with precompiled body}
+test proc-4.5 {TclCreateProc, procbody obj, inconsistent arg default type} -body {
+ proc p {x y {z Z}} {
+ set v [join [list $x $y $z]]
+ set w [string tolower $v]
+ return "$v:$w"
+ }
+ set rv [p P Q R]
+ procbodytest::proc t {x y z} p
+ lappend rv [t S T U]
+} -constraints procbodytest -returnCodes error -cleanup {
+ catch {rename p ""}
+ catch {rename t ""}
+} -result {procedure "t": formal parameter 2 is inconsistent with precompiled body}
+test proc-4.6 {TclCreateProc, procbody obj, inconsistent arg default type} -body {
+ proc p {x y z} {
+ set v [join [list $x $y $z]]
+ set w [string tolower $v]
+ return "$v:$w"
+ }
+ set rv [p P Q R]
+ procbodytest::proc t {x y {z Z}} p
+ lappend rv [t S T U]
+} -returnCodes error -constraints procbodytest -cleanup {
+ catch {rename p ""}
+ catch {rename t ""}
+} -result {procedure "t": formal parameter 2 is inconsistent with precompiled body}
+test proc-4.7 {TclCreateProc, procbody obj, inconsistent arg default value} -body {
+ proc p {x y {z Z}} {
+ set v [join [list $x $y $z]]
+ set w [string tolower $v]
+ return "$v:$w"
+ }
+ set rv [p P Q R]
+ procbodytest::proc t {x y {z ZZ}} p
+ lappend rv [t S T U]
+} -constraints procbodytest -returnCodes error -cleanup {
+ catch {rename p ""}
+ catch {rename t ""}
+} -result {procedure "t": formal parameter "z" has default value inconsistent with precompiled body}
+test proc-4.8 {TclCreateProc, procbody obj, no leak on multiple iterations} -setup {
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex $lines 3 3
+ }
+ proc px x {
+ set y [string tolower $x]
+ return "$x:$y"
+ }
+ px x
+} -constraints {procbodytest memory} -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ procbodytest::proc tx x px
+ set tmp $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+ rename getbytes {}
+ unset -nocomplain end i tmp leakedBytes
+} -result 0
+
+test proc-5.1 {Bytecompiling noop; test for correct argument substitution} -body {
+ proc p args {} ; # this will be bytecompiled into t
+ proc t {} {
+ set res {}
+ set a 0
+ set b 0
+ trace add variable a read {append res a ;#}
+ trace add variable b write {append res b ;#}
+ p $a ccccccw {bfe} {$a} [incr b] [incr a] {[incr b]} {$a} hello
+ set res
+ }
+ t
+} -cleanup {
+ catch {rename p ""}
+ catch {rename t ""}
+} -result {aba}
+
+test proc-6.1 {ProcessProcResultCode: Bug 647307 (negative return code)} -body {
+ proc a {} {return -code -5}
+ proc b {} a
+ catch b
+} -cleanup {
+ rename a {}
+ rename b {}
+} -result -5
+
+test proc-7.1 {Redefining a compiled cmd: Bug 729692} {
+ proc bar args {}
+ proc foo {} {
+ proc bar args {return bar}
+ bar
+ }
+ foo
+} bar
+test proc-7.2 {Shadowing a compiled cmd: Bug 729692} -body {
+ namespace eval ugly {}
+ proc ugly::foo {} {
+ proc set args {return bar}
+ set x 1
+ }
+ ugly::foo
+} -cleanup {
+ namespace delete ugly
+} -result bar
+test proc-7.3 {Returning loop exception from redefined cmd: Bug 729692} -body {
+ namespace eval ugly {}
+ proc ugly::foo {} {
+ set i 0
+ while { 1 } {
+ if { [incr i] > 3 } {
+ proc continue {} {return -code break}
+ }
+ continue
+ }
+ return $i
+ }
+ ugly::foo
+} -cleanup {
+ namespace delete ugly
+} -result 4
+
+test proc-7.4 {Proc struct outlives its interp: Bug 3532959} {
+ set lambda x
+ lappend lambda {set a 1}
+ interp create slave
+ slave eval [list apply $lambda foo]
+ interp delete slave
+ unset lambda
+} {}
+
+# cleanup
+catch {rename p ""}
+catch {rename t ""}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/pwd.test b/library/msgcat/tests/pwd.test
new file mode 100644
index 0000000..175c852
--- /dev/null
+++ b/library/msgcat/tests/pwd.test
@@ -0,0 +1,31 @@
+# Commands covered: pwd
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+test pwd-1.1 {simple pwd} {
+ catch pwd
+} 0
+test pwd-1.2 {simple pwd} {
+ expr [string length pwd]>0
+} 1
+test pwd-1.3 {pwd takes no args} -body {
+ pwd foobar
+} -returnCodes error -result "wrong \# args: should be \"pwd\""
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/reg.test b/library/msgcat/tests/reg.test
new file mode 100644
index 0000000..abfc9ca
--- /dev/null
+++ b/library/msgcat/tests/reg.test
@@ -0,0 +1,1087 @@
+# reg.test --
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+# (Don't panic if you are seeing this as part of the reg distribution
+# and aren't using Tcl -- reg's own regression tester also knows how
+# to read this file, ignoring the Tcl-isms.)
+#
+# Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+}
+
+# All tests require the testregexp command, return if this
+# command doesn't exist
+
+::tcltest::testConstraint testregexp [llength [info commands testregexp]]
+::tcltest::testConstraint localeRegexp 0
+
+# This file uses some custom procedures, defined below, for regexp regression
+# testing. The name of the procedure indicates the general nature of the
+# test:
+# expectError compile error expected
+# expectNomatch match failure expected
+# expectMatch successful match
+# expectIndices successful match with -indices (used in checking things
+# like nonparticipating subexpressions)
+# expectPartial unsuccessful match with -indices (!!) (used in checking
+# partial-match reporting)
+# There is also "doing" which sets up title and major test number for each
+# block of tests.
+
+# The first 3 arguments are constant: a minor number (which often gets
+# a letter or two suffixed to it internally), some flags, and the RE
+# itself. For expectError, the remaining argument is the name of the
+# compile error expected, less the leading "REG_". For the rest, the
+# next argument is the string to try the match against. Remaining
+# arguments are the substring expected to be matched, and any
+# substrings expected to be matched by subexpressions. (For
+# expectNomatch, these arguments are optional, and if present are
+# ignored except that they indicate how many subexpressions should be
+# present in the RE.) It is an error for the number of subexpression
+# arguments to be wrong. Cases involving nonparticipating
+# subexpressions, checking where empty substrings are located,
+# etc. should be done using expectIndices and expectPartial.
+
+# The flag characters are complex and a bit eclectic. Generally speaking,
+# lowercase letters are compile options, uppercase are expected re_info
+# bits, and nonalphabetics are match options, controls for how the test is
+# run, or testing options. The one small surprise is that AREs are the
+# default, and you must explicitly request lesser flavors of RE. The flags
+# are as follows. It is admitted that some are not very mnemonic.
+# There are some others which are purely debugging tools and are not
+# useful in this file.
+#
+# - no-op (placeholder)
+# + provide fake xy equivalence class and ch collating element
+# % force small state-set cache in matcher (to test cache replace)
+# ^ beginning of string is not beginning of line
+# $ end of string is not end of line
+# * test is Unicode-specific, needs big character set
+#
+# & test as both ARE and BRE
+# b BRE
+# e ERE
+# a turn advanced-features bit on (error unless ERE already)
+# q literal string, no metacharacters at all
+#
+# i case-independent matching
+# o ("opaque") no subexpression capture
+# p newlines are half-magic, excluded from . and [^ only
+# w newlines are half-magic, significant to ^ and $ only
+# n newlines are fully magic, both effects
+# x expanded RE syntax
+# t incomplete-match reporting
+#
+# A backslash-_a_lphanumeric seen
+# B ERE/ARE literal-_b_race heuristic used
+# E backslash (_e_scape) seen within []
+# H looka_h_ead constraint seen
+# I _i_mpossible to match
+# L _l_ocale-specific construct seen
+# M unportable (_m_achine-specific) construct seen
+# N RE can match empty (_n_ull) string
+# P non-_P_OSIX construct seen
+# Q {} _q_uantifier seen
+# R back _r_eference seen
+# S POSIX-un_s_pecified syntax seen
+# T prefers shortest (_t_iny)
+# U saw original-POSIX botch: unmatched right paren in ERE (_u_gh)
+
+# The one area we can't easily test is memory-allocation failures (which
+# are hard to provoke on command). Embedded NULs also are not tested at
+# the moment, but this is a historical accident which should be fixed.
+
+
+# test procedures and related
+namespace eval RETest {
+ namespace export doing expect* knownBug
+
+ variable regBug 0
+
+ # re_info abbreviation mapping table
+ variable infonames
+ array set infonames {
+ A REG_UBSALNUM
+ B REG_UBRACES
+ E REG_UBBS
+ H REG_ULOOKAHEAD
+ I REG_UIMPOSSIBLE
+ L REG_ULOCALE
+ M REG_UUNPORT
+ N REG_UEMPTYMATCH
+ P REG_UNONPOSIX
+ Q REG_UBOUNDS
+ R REG_UBACKREF
+ S REG_UUNSPEC
+ T REG_USHORTEST
+ U REG_UPBOTCH
+ }
+ variable infonameorder "RHQBAUEPSMLNIT" ;# must match bit order, lsb first
+
+ # build test number (internal)
+ proc TestNum {args} {
+ return reg-[join [concat $args] .]
+ }
+
+ # build description, with possible modifiers (internal)
+ proc TestDesc {args} {
+ variable description
+
+ set testid [concat $args]
+ set d $description
+ if {[llength $testid] > 1} {
+ set d "$d ([lrange $testid 1 end])"
+ }
+ return $d
+ }
+
+ # build trailing options and flags argument from a flags string (internal)
+ proc TestFlags {fl} {
+ set args [list]
+ set flags ""
+ foreach f [split $fl ""] {
+ switch -exact -- $f {
+ "i" { lappend args "-nocase" }
+ "x" { lappend args "-expanded" }
+ "n" { lappend args "-line" }
+ "p" { lappend args "-linestop" }
+ "w" { lappend args "-lineanchor" }
+ "-" { }
+ default { append flags $f }
+ }
+ }
+ if {$flags ne ""} {
+ lappend args -xflags $flags
+ }
+ return $args
+ }
+
+ # build info-flags list from a flags string (internal)
+ proc TestInfoFlags {fl} {
+ variable infonames
+ variable infonameorder
+
+ set ret [list]
+ foreach f [split $infonameorder ""] {
+ if {[string match *$f* $fl]} {
+ lappend ret $infonames($f)
+ }
+ }
+ return $ret
+ }
+
+ # Share the generation of the list of test constraints so it is
+ # done the same on all routes.
+ proc TestConstraints {flags} {
+ set constraints [list testregexp]
+
+ variable regBug
+ if {$regBug} {
+ # This will trigger registration as a skipped test
+ lappend constraints knownBug
+ }
+
+ # Tcl locale stuff doesn't do the ch/xy test fakery yet
+ if {[string match *+* $flags]} {
+ # This will trigger registration as a skipped test
+ lappend constraints localeRegexp
+ }
+
+ return $constraints
+ }
+
+ # match expected, internal routine that does the work
+ # parameters like the "real" routines except they don't have "opts",
+ # which is a possibly-empty list of switches for the regexp match attempt
+ # The ! flag is used to indicate expected match failure (for REG_EXPECT,
+ # which wants argument testing even in the event of failure).
+ proc MatchExpected {opts testid flags re target args} {
+ # if &, test as both BRE and ARE
+ if {[string match *&* $flags]} {
+ set f [string map {& {}} $flags]
+ MatchExpected $opts "$testid ARE" ${f} $re $target {*}$args
+ MatchExpected $opts "$testid BRE" ${f}b $re $target {*}$args
+ return
+ }
+
+ set constraints [TestConstraints $flags]
+
+ set f [TestFlags $flags]
+ set infoflags [TestInfoFlags $flags]
+ set ccmd [list testregexp -about {*}$f $re]
+ set ecmd [list testregexp {*}$opts {*}$f $re $target]
+
+ set nsub [expr {[llength $args] - 1}]
+ set names [list]
+ set refs ""
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ if {$i == 0} {
+ set name match
+ } else {
+ set name sub$i
+ }
+ lappend names $name
+ append refs " \$$name"
+ set $name ""
+ }
+ if {[string match *o* $flags]} { ;# REG_NOSUB kludge
+ set nsub 0 ;# unsigned value cannot be -1
+ }
+ if {[string match *t* $flags]} { ;# REG_EXPECT
+ incr nsub -1 ;# the extra does not count
+ }
+ set erun "list \[[concat $ecmd $names]\] $refs"
+ set result [list [expr {![string match *!* $flags]}] {*}$args]
+ set info [list $nsub $infoflags]
+
+ ::tcltest::test [TestNum $testid compile] [TestDesc $testid compile] \
+ -constraints $constraints -body $ccmd -result $info
+ ::tcltest::test [TestNum $testid execute] [TestDesc $testid execute] \
+ -constraints $constraints -body $erun -result $result
+ }
+
+ # set major test number and description
+ proc doing {major desc} {
+ variable description "RE engine $desc"
+ }
+
+ # compilation error expected
+ proc expectError {testid flags re err} {
+ # if &, test as both ARE and BRE
+ if {[string match *&* $flags]} {
+ set f [string map {& {}} $flags]
+ expectError "$testid ARE" ${f} $re $err
+ expectError "$testid BRE" ${f}b $re $err
+ return
+ }
+
+ set constraints [TestConstraints $flags]
+
+ set cmd [list testregexp -about {*}[TestFlags $flags] $re]
+ ::tcltest::test [TestNum $testid error] [TestDesc $testid error] \
+ -constraints $constraints -result [list 1 REG_$err] -body \
+ "list \[catch \{$cmd\}\] \[lindex \$::errorCode 1\]"
+ }
+
+ # match failure expected
+ proc expectNomatch {testid flags re target args} {
+ variable regBug
+ # if &, test as both ARE and BRE
+ if {[string match *&* $flags]} {
+ set f [string map {& {}} $flags]
+ expectNomatch "$testid ARE" ${f} $re $target {*}$args
+ expectNomatch "$testid BRE" ${f}b $re $target {*}$args
+ return
+ }
+
+ set constraints [TestConstraints $flags]
+
+ set f [TestFlags $flags]
+ set infoflags [TestInfoFlags $flags]
+ set ccmd [list testregexp -about {*}$f $re]
+ set nsub [expr {[llength $args] - 1}]
+ if {$nsub == -1} {
+ # didn't tell us number of subexps
+ set ccmd "lreplace \[$ccmd\] 0 0"
+ set info [list $infoflags]
+ } else {
+ set info [list $nsub $infoflags]
+ }
+ set ecmd [list testregexp {*}$f $re $target]
+
+ ::tcltest::test [TestNum $testid compile] [TestDesc $testid compile] \
+ -constraints $constraints -body $ccmd -result $info
+ ::tcltest::test [TestNum $testid execute] [TestDesc $testid execute] \
+ -constraints $constraints -body $ecmd -result 0
+ }
+
+ # match expected (no missing, empty, or ambiguous submatches)
+ # expectMatch testno flags re target mat submat ...
+ proc expectMatch {args} {
+ MatchExpected {} {*}$args
+ }
+
+ # match expected (full fanciness)
+ # expectIndices testno flags re target mat submat ...
+ proc expectIndices {args} {
+ MatchExpected -indices {*}$args
+ }
+
+ # partial match expected
+ # expectPartial testno flags re target mat "" ...
+ # Quirk: number of ""s must be one more than number of subREs.
+ proc expectPartial {args} {
+ lset args 1 ![lindex $args 1] ;# add ! flag
+ MatchExpected -indices {*}$args
+ }
+
+ # test is a knownBug
+ proc knownBug {args} {
+ variable regBug 1
+ uplevel \#0 $args
+ set regBug 0
+ }
+}
+namespace import RETest::*
+
+######## the tests themselves ########
+
+# support functions and preliminary misc.
+# This is sensitive to changes in message wording, but we really have to
+# test the code->message expansion at least once.
+::tcltest::test reg-0.1 "regexp error reporting" {
+ list [catch {regexp (*) ign} msg] $msg
+} {1 {couldn't compile regular expression pattern: quantifier operand invalid}}
+
+
+doing 1 "basic sanity checks"
+expectMatch 1.1 & abc abc abc
+expectNomatch 1.2 & abc def
+expectMatch 1.3 & abc xyabxabce abc
+
+
+doing 2 "invalid option combinations"
+expectError 2.1 qe a INVARG
+expectError 2.2 qa a INVARG
+expectError 2.3 qx a INVARG
+expectError 2.4 qn a INVARG
+expectError 2.5 ba a INVARG
+
+
+doing 3 "basic syntax"
+expectIndices 3.1 &NS "" a {0 -1}
+expectMatch 3.2 NS a| a a
+expectMatch 3.3 - a|b a a
+expectMatch 3.4 - a|b b b
+expectMatch 3.5 NS a||b b b
+expectMatch 3.6 & ab ab ab
+
+
+doing 4 "parentheses"
+expectMatch 4.1 - (a)e ae ae a
+expectMatch 4.2 o (a)e ae
+expectMatch 4.3 b {\(a\)b} ab ab a
+expectMatch 4.4 - a((b)c) abc abc bc b
+expectMatch 4.5 - a(b)(c) abc abc b c
+expectError 4.6 - a(b EPAREN
+expectError 4.7 b {a\(b} EPAREN
+# sigh, we blew it on the specs here... someday this will be fixed in POSIX,
+# but meanwhile, it's fixed in AREs
+expectMatch 4.8 eU a)b a)b a)b
+expectError 4.9 - a)b EPAREN
+expectError 4.10 b {a\)b} EPAREN
+expectMatch 4.11 P a(?:b)c abc abc
+expectError 4.12 e a(?:b)c BADRPT
+expectIndices 4.13 S a()b ab {0 1} {1 0}
+expectMatch 4.14 SP a(?:)b ab ab
+expectIndices 4.15 S a(|b)c ac {0 1} {1 0}
+expectMatch 4.16 S a(b|)c abc abc b
+
+
+doing 5 "simple one-char matching"
+# general case of brackets done later
+expectMatch 5.1 & a.b axb axb
+expectNomatch 5.2 &n "a.b" "a\nb"
+expectMatch 5.3 & {a[bc]d} abd abd
+expectMatch 5.4 & {a[bc]d} acd acd
+expectNomatch 5.5 & {a[bc]d} aed
+expectNomatch 5.6 & {a[^bc]d} abd
+expectMatch 5.7 & {a[^bc]d} aed aed
+expectNomatch 5.8 &p "a\[^bc]d" "a\nd"
+
+
+doing 6 "context-dependent syntax"
+# plus odds and ends
+expectError 6.1 - * BADRPT
+expectMatch 6.2 b * * *
+expectMatch 6.3 b {\(*\)} * * *
+expectError 6.4 - (*) BADRPT
+expectMatch 6.5 b ^* * *
+expectError 6.6 - ^* BADRPT
+expectNomatch 6.7 & ^b ^b
+expectMatch 6.8 b x^ x^ x^
+expectNomatch 6.9 I x^ x
+expectMatch 6.10 n "\n^" "x\nb" "\n"
+expectNomatch 6.11 bS {\(^b\)} ^b
+expectMatch 6.12 - (^b) b b b
+expectMatch 6.13 & {x$} x x
+expectMatch 6.14 bS {\(x$\)} x x x
+expectMatch 6.15 - {(x$)} x x x
+expectMatch 6.16 b {x$y} "x\$y" "x\$y"
+expectNomatch 6.17 I {x$y} xy
+expectMatch 6.18 n "x\$\n" "x\n" "x\n"
+expectError 6.19 - + BADRPT
+expectError 6.20 - ? BADRPT
+
+
+doing 7 "simple quantifiers"
+expectMatch 7.1 &N a* aa aa
+expectIndices 7.2 &N a* b {0 -1}
+expectMatch 7.3 - a+ aa aa
+expectMatch 7.4 - a?b ab ab
+expectMatch 7.5 - a?b b b
+expectError 7.6 - ** BADRPT
+expectMatch 7.7 bN ** *** ***
+expectError 7.8 & a** BADRPT
+expectError 7.9 & a**b BADRPT
+expectError 7.10 & *** BADRPT
+expectError 7.11 - a++ BADRPT
+expectError 7.12 - a?+ BADRPT
+expectError 7.13 - a?* BADRPT
+expectError 7.14 - a+* BADRPT
+expectError 7.15 - a*+ BADRPT
+
+
+doing 8 "braces"
+expectMatch 8.1 NQ "a{0,1}" "" ""
+expectMatch 8.2 NQ "a{0,1}" ac a
+expectError 8.3 - "a{1,0}" BADBR
+expectError 8.4 - "a{1,2,3}" BADBR
+expectError 8.5 - "a{257}" BADBR
+expectError 8.6 - "a{1000}" BADBR
+expectError 8.7 - "a{1" EBRACE
+expectError 8.8 - "a{1n}" BADBR
+expectMatch 8.9 BS "a{b" "a\{b" "a\{b"
+expectMatch 8.10 BS "a{" "a\{" "a\{"
+expectMatch 8.11 bQ "a\\{0,1\\}b" cb b
+expectError 8.12 b "a\\{0,1" EBRACE
+expectError 8.13 - "a{0,1\\" BADBR
+expectMatch 8.14 Q "a{0}b" ab b
+expectMatch 8.15 Q "a{0,0}b" ab b
+expectMatch 8.16 Q "a{0,1}b" ab ab
+expectMatch 8.17 Q "a{0,2}b" b b
+expectMatch 8.18 Q "a{0,2}b" aab aab
+expectMatch 8.19 Q "a{0,}b" aab aab
+expectMatch 8.20 Q "a{1,1}b" aab ab
+expectMatch 8.21 Q "a{1,3}b" aaaab aaab
+expectNomatch 8.22 Q "a{1,3}b" b
+expectMatch 8.23 Q "a{1,}b" aab aab
+expectNomatch 8.24 Q "a{2,3}b" ab
+expectMatch 8.25 Q "a{2,3}b" aaaab aaab
+expectNomatch 8.26 Q "a{2,}b" ab
+expectMatch 8.27 Q "a{2,}b" aaaab aaaab
+
+
+doing 9 "brackets"
+expectMatch 9.1 & {a[bc]} ac ac
+expectMatch 9.2 & {a[-]} a- a-
+expectMatch 9.3 & {a[[.-.]]} a- a-
+expectMatch 9.4 &L {a[[.zero.]]} a0 a0
+expectMatch 9.5 &LM {a[[.zero.]-9]} a2 a2
+expectMatch 9.6 &M {a[0-[.9.]]} a2 a2
+expectMatch 9.7 &+L {a[[=x=]]} ax ax
+expectMatch 9.8 &+L {a[[=x=]]} ay ay
+expectNomatch 9.9 &+L {a[[=x=]]} az
+expectError 9.10 & {a[0-[=x=]]} ERANGE
+expectMatch 9.11 &L {a[[:digit:]]} a0 a0
+expectError 9.12 & {a[[:woopsie:]]} ECTYPE
+expectNomatch 9.13 &L {a[[:digit:]]} ab
+expectError 9.14 & {a[0-[:digit:]]} ERANGE
+expectMatch 9.15 &LP {[[:<:]]a} a a
+expectMatch 9.16 &LP {a[[:>:]]} a a
+expectError 9.17 & {a[[..]]b} ECOLLATE
+expectError 9.18 & {a[[==]]b} ECOLLATE
+expectError 9.19 & {a[[::]]b} ECTYPE
+expectError 9.20 & {a[[.a} EBRACK
+expectError 9.21 & {a[[=a} EBRACK
+expectError 9.22 & {a[[:a} EBRACK
+expectError 9.23 & {a[} EBRACK
+expectError 9.24 & {a[b} EBRACK
+expectError 9.25 & {a[b-} EBRACK
+expectError 9.26 & {a[b-c} EBRACK
+expectMatch 9.27 &M {a[b-c]} ab ab
+expectMatch 9.28 & {a[b-b]} ab ab
+expectMatch 9.29 &M {a[1-2]} a2 a2
+expectError 9.30 & {a[c-b]} ERANGE
+expectError 9.31 & {a[a-b-c]} ERANGE
+expectMatch 9.32 &M {a[--?]b} a?b a?b
+expectMatch 9.33 & {a[---]b} a-b a-b
+expectMatch 9.34 & {a[]b]c} a]c a]c
+expectMatch 9.35 EP {a[\]]b} a]b a]b
+expectNomatch 9.36 bE {a[\]]b} a]b
+expectMatch 9.37 bE {a[\]]b} "a\\]b" "a\\]b"
+expectMatch 9.38 eE {a[\]]b} "a\\]b" "a\\]b"
+expectMatch 9.39 EP {a[\\]b} "a\\b" "a\\b"
+expectMatch 9.40 eE {a[\\]b} "a\\b" "a\\b"
+expectMatch 9.41 bE {a[\\]b} "a\\b" "a\\b"
+expectError 9.42 - {a[\Z]b} EESCAPE
+expectMatch 9.43 & {a[[b]c} "a\[c" "a\[c"
+expectMatch 9.44 EMP* {a[\u00fe-\u0507][\u00ff-\u0300]b} \
+ "a\u0102\u02ffb" "a\u0102\u02ffb"
+
+
+doing 10 "anchors and newlines"
+expectMatch 10.1 & ^a a a
+expectNomatch 10.2 &^ ^a a
+expectIndices 10.3 &N ^ a {0 -1}
+expectIndices 10.4 & {a$} aba {2 2}
+expectNomatch 10.5 {&$} {a$} a
+expectIndices 10.6 &N {$} ab {2 1}
+expectMatch 10.7 &n ^a a a
+expectMatch 10.8 &n "^a" "b\na" "a"
+expectIndices 10.9 &w "^a" "a\na" {0 0}
+expectIndices 10.10 &n^ "^a" "a\na" {2 2}
+expectMatch 10.11 &n {a$} a a
+expectMatch 10.12 &n "a\$" "a\nb" "a"
+expectIndices 10.13 &n "a\$" "a\na" {0 0}
+expectIndices 10.14 N ^^ a {0 -1}
+expectMatch 10.15 b ^^ ^ ^
+expectIndices 10.16 N {$$} a {1 0}
+expectMatch 10.17 b {$$} "\$" "\$"
+expectMatch 10.18 &N {^$} "" ""
+expectNomatch 10.19 &N {^$} a
+expectIndices 10.20 &nN "^\$" a\n\nb {2 1}
+expectMatch 10.21 N {$^} "" ""
+expectMatch 10.22 b {$^} "\$^" "\$^"
+expectMatch 10.23 P {\Aa} a a
+expectMatch 10.24 ^P {\Aa} a a
+expectNomatch 10.25 ^nP {\Aa} "b\na"
+expectMatch 10.26 P {a\Z} a a
+expectMatch 10.27 \$P {a\Z} a a
+expectNomatch 10.28 \$nP {a\Z} "a\nb"
+expectError 10.29 - ^* BADRPT
+expectError 10.30 - {$*} BADRPT
+expectError 10.31 - {\A*} BADRPT
+expectError 10.32 - {\Z*} BADRPT
+
+
+doing 11 "boundary constraints"
+expectMatch 11.1 &LP {[[:<:]]a} a a
+expectMatch 11.2 &LP {[[:<:]]a} -a a
+expectNomatch 11.3 &LP {[[:<:]]a} ba
+expectMatch 11.4 &LP {a[[:>:]]} a a
+expectMatch 11.5 &LP {a[[:>:]]} a- a
+expectNomatch 11.6 &LP {a[[:>:]]} ab
+expectMatch 11.7 bLP {\<a} a a
+expectNomatch 11.8 bLP {\<a} ba
+expectMatch 11.9 bLP {a\>} a a
+expectNomatch 11.10 bLP {a\>} ab
+expectMatch 11.11 LP {\ya} a a
+expectNomatch 11.12 LP {\ya} ba
+expectMatch 11.13 LP {a\y} a a
+expectNomatch 11.14 LP {a\y} ab
+expectMatch 11.15 LP {a\Y} ab a
+expectNomatch 11.16 LP {a\Y} a-
+expectNomatch 11.17 LP {a\Y} a
+expectNomatch 11.18 LP {-\Y} -a
+expectMatch 11.19 LP {-\Y} -% -
+expectNomatch 11.20 LP {\Y-} a-
+expectError 11.21 - {[[:<:]]*} BADRPT
+expectError 11.22 - {[[:>:]]*} BADRPT
+expectError 11.23 b {\<*} BADRPT
+expectError 11.24 b {\>*} BADRPT
+expectError 11.25 - {\y*} BADRPT
+expectError 11.26 - {\Y*} BADRPT
+expectMatch 11.27 LP {\ma} a a
+expectNomatch 11.28 LP {\ma} ba
+expectMatch 11.29 LP {a\M} a a
+expectNomatch 11.30 LP {a\M} ab
+expectNomatch 11.31 ILP {\Ma} a
+expectNomatch 11.32 ILP {a\m} a
+
+
+doing 12 "character classes"
+expectMatch 12.1 LP {a\db} a0b a0b
+expectNomatch 12.2 LP {a\db} axb
+expectNomatch 12.3 LP {a\Db} a0b
+expectMatch 12.4 LP {a\Db} axb axb
+expectMatch 12.5 LP "a\\sb" "a b" "a b"
+expectMatch 12.6 LP "a\\sb" "a\tb" "a\tb"
+expectMatch 12.7 LP "a\\sb" "a\nb" "a\nb"
+expectNomatch 12.8 LP {a\sb} axb
+expectMatch 12.9 LP {a\Sb} axb axb
+expectNomatch 12.10 LP "a\\Sb" "a b"
+expectMatch 12.11 LP {a\wb} axb axb
+expectNomatch 12.12 LP {a\wb} a-b
+expectNomatch 12.13 LP {a\Wb} axb
+expectMatch 12.14 LP {a\Wb} a-b a-b
+expectMatch 12.15 LP {\y\w+z\y} adze-guz guz
+expectMatch 12.16 LPE {a[\d]b} a1b a1b
+expectMatch 12.17 LPE "a\[\\s]b" "a b" "a b"
+expectMatch 12.18 LPE {a[\w]b} axb axb
+
+
+doing 13 "escapes"
+expectError 13.1 & "a\\" EESCAPE
+expectMatch 13.2 - {a\<b} a<b a<b
+expectMatch 13.3 e {a\<b} a<b a<b
+expectMatch 13.4 bAS {a\wb} awb awb
+expectMatch 13.5 eAS {a\wb} awb awb
+expectMatch 13.6 PL "a\\ab" "a\007b" "a\007b"
+expectMatch 13.7 P "a\\bb" "a\bb" "a\bb"
+expectMatch 13.8 P {a\Bb} "a\\b" "a\\b"
+expectMatch 13.9 MP "a\\chb" "a\bb" "a\bb"
+expectMatch 13.10 MP "a\\cHb" "a\bb" "a\bb"
+expectMatch 13.11 LMP "a\\e" "a\033" "a\033"
+expectMatch 13.12 P "a\\fb" "a\fb" "a\fb"
+expectMatch 13.13 P "a\\nb" "a\nb" "a\nb"
+expectMatch 13.14 P "a\\rb" "a\rb" "a\rb"
+expectMatch 13.15 P "a\\tb" "a\tb" "a\tb"
+expectMatch 13.16 P "a\\u0008x" "a\bx" "a\bx"
+expectMatch 13.17 P {a\u008x} "a\bx" "a\bx"
+expectMatch 13.18 P "a\\u00088x" "a\b8x" "a\b8x"
+expectMatch 13.19 P "a\\U00000008x" "a\bx" "a\bx"
+expectMatch 13.20 P {a\U0000008x} "a\bx" "a\bx"
+expectMatch 13.21 P "a\\vb" "a\vb" "a\vb"
+expectMatch 13.22 MP "a\\x08x" "a\bx" "a\bx"
+expectError 13.23 - {a\xq} EESCAPE
+expectMatch 13.24 MP "a\\x08x" "a\bx" "a\bx"
+expectError 13.25 - {a\z} EESCAPE
+expectMatch 13.26 MP "a\\010b" "a\bb" "a\bb"
+expectMatch 13.27 P "a\\U00001234x" "a\u1234x" "a\u1234x"
+expectMatch 13.28 P {a\U00001234x} "a\u1234x" "a\u1234x"
+expectMatch 13.29 P "a\\U0001234x" "a\u1234x" "a\u1234x"
+expectMatch 13.30 P {a\U0001234x} "a\u1234x" "a\u1234x"
+expectMatch 13.31 P "a\\U000012345x" "a\u12345x" "a\u12345x"
+expectMatch 13.32 P {a\U000012345x} "a\u12345x" "a\u12345x"
+expectMatch 13.33 P "a\\U1000000x" "a\ufffd0x" "a\ufffd0x"
+expectMatch 13.34 P {a\U1000000x} "a\ufffd0x" "a\ufffd0x"
+
+
+doing 14 "back references"
+# ugh
+expectMatch 14.1 RP {a(b*)c\1} abbcbb abbcbb bb
+expectMatch 14.2 RP {a(b*)c\1} ac ac ""
+expectNomatch 14.3 RP {a(b*)c\1} abbcb
+expectMatch 14.4 RP {a(b*)\1} abbcbb abb b
+expectMatch 14.5 RP {a(b|bb)\1} abbcbb abb b
+expectMatch 14.6 RP {a([bc])\1} abb abb b
+expectNomatch 14.7 RP {a([bc])\1} abc
+expectMatch 14.8 RP {a([bc])\1} abcabb abb b
+expectNomatch 14.9 RP {a([bc])*\1} abc
+expectNomatch 14.10 RP {a([bc])\1} abB
+expectMatch 14.11 iRP {a([bc])\1} abB abB b
+expectMatch 14.12 RP {a([bc])\1+} abbb abbb b
+expectMatch 14.13 QRP "a(\[bc])\\1{3,4}" abbbb abbbb b
+expectNomatch 14.14 QRP "a(\[bc])\\1{3,4}" abbb
+expectMatch 14.15 RP {a([bc])\1*} abbb abbb b
+expectMatch 14.16 RP {a([bc])\1*} ab ab b
+expectMatch 14.17 RP {a([bc])(\1*)} ab ab b ""
+expectError 14.18 - {a((b)\1)} ESUBREG
+expectError 14.19 - {a(b)c\2} ESUBREG
+expectMatch 14.20 bR {a\(b*\)c\1} abbcbb abbcbb bb
+expectMatch 14.21 RP {^([bc])\1*$} bbb bbb b
+expectMatch 14.22 RP {^([bc])\1*$} ccc ccc c
+knownBug expectNomatch 14.23 R {^([bc])\1*$} bcb
+
+
+doing 15 "octal escapes vs back references"
+# initial zero is always octal
+expectMatch 15.1 MP "a\\010b" "a\bb" "a\bb"
+expectMatch 15.2 MP "a\\0070b" "a\0070b" "a\0070b"
+expectMatch 15.3 MP "a\\07b" "a\007b" "a\007b"
+expectMatch 15.4 MP "a(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)\\07c" \
+ "abbbbbbbbbb\007c" abbbbbbbbbb\007c b b b b b b b b b b
+# a single digit is always a backref
+expectError 15.5 - {a\7b} ESUBREG
+# otherwise it's a backref only if within range (barf!)
+expectMatch 15.6 MP "a\\10b" "a\bb" "a\bb"
+expectMatch 15.7 MP {a\101b} aAb aAb
+expectMatch 15.8 RP {a(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)\10c} \
+ "abbbbbbbbbbbc" abbbbbbbbbbbc b b b b b b b b b b
+# but we're fussy about border cases -- guys who want octal should use the zero
+expectError 15.9 - {a((((((((((b\10))))))))))c} ESUBREG
+# BREs don't have octal, EREs don't have backrefs
+expectMatch 15.10 MP "a\\12b" "a\nb" "a\nb"
+expectError 15.11 b {a\12b} ESUBREG
+expectMatch 15.12 eAS {a\12b} a12b a12b
+expectMatch 15.13 MP {a\701b} a\u00381b a\u00381b
+
+
+doing 16 "expanded syntax"
+expectMatch 16.1 xP "a b c" "abc" "abc"
+expectMatch 16.2 xP "a b #oops\nc\td" "abcd" "abcd"
+expectMatch 16.3 x "a\\ b\\\tc" "a b\tc" "a b\tc"
+expectMatch 16.4 xP "a b\\#c" "ab#c" "ab#c"
+expectMatch 16.5 xP "a b\[c d]e" "ab e" "ab e"
+expectMatch 16.6 xP "a b\[c#d]e" "ab#e" "ab#e"
+expectMatch 16.7 xP "a b\[c#d]e" "abde" "abde"
+expectMatch 16.8 xSPB "ab{ d" "ab\{d" "ab\{d"
+expectMatch 16.9 xPQ "ab{ 1 , 2 }c" "abc" "abc"
+
+
+doing 17 "misc syntax"
+expectMatch 17.1 P a(?#comment)b ab ab
+
+
+doing 18 "unmatchable REs"
+expectNomatch 18.1 I a^b ab
+
+
+doing 19 "case independence"
+expectMatch 19.1 &i ab Ab Ab
+expectMatch 19.2 &i {a[bc]} aC aC
+expectNomatch 19.3 &i {a[^bc]} aB
+expectMatch 19.4 &iM {a[b-d]} aC aC
+expectNomatch 19.5 &iM {a[^b-d]} aC
+
+
+doing 20 "directors and embedded options"
+expectError 20.1 & ***? BADPAT
+expectMatch 20.2 q ***? ***? ***?
+expectMatch 20.3 &P ***=a*b a*b a*b
+expectMatch 20.4 q ***=a*b ***=a*b ***=a*b
+expectMatch 20.5 bLP {***:\w+} ab ab
+expectMatch 20.6 eLP {***:\w+} ab ab
+expectError 20.7 & ***:***=a*b BADRPT
+expectMatch 20.8 &P ***:(?b)a+b a+b a+b
+expectMatch 20.9 P (?b)a+b a+b a+b
+expectError 20.10 e {(?b)\w+} BADRPT
+expectMatch 20.11 bAS {(?b)\w+} (?b)w+ (?b)w+
+expectMatch 20.12 iP (?c)a a a
+expectNomatch 20.13 iP (?c)a A
+expectMatch 20.14 APS {(?e)\W+} WW WW
+expectMatch 20.15 P (?i)a+ Aa Aa
+expectNomatch 20.16 P "(?m)a.b" "a\nb"
+expectMatch 20.17 P "(?m)^b" "a\nb" "b"
+expectNomatch 20.18 P "(?n)a.b" "a\nb"
+expectMatch 20.19 P "(?n)^b" "a\nb" "b"
+expectNomatch 20.20 P "(?p)a.b" "a\nb"
+expectNomatch 20.21 P "(?p)^b" "a\nb"
+expectMatch 20.22 P (?q)a+b a+b a+b
+expectMatch 20.23 nP "(?s)a.b" "a\nb" "a\nb"
+expectMatch 20.24 xP "(?t)a b" "a b" "a b"
+expectMatch 20.25 P "(?w)a.b" "a\nb" "a\nb"
+expectMatch 20.26 P "(?w)^b" "a\nb" "b"
+expectMatch 20.27 P "(?x)a b" "ab" "ab"
+expectError 20.28 - (?z)ab BADOPT
+expectMatch 20.29 P (?ici)a+ Aa Aa
+expectError 20.30 P (?i)(?q)a+ BADRPT
+expectMatch 20.31 P (?q)(?i)a+ (?i)a+ (?i)a+
+expectMatch 20.32 P (?qe)a+ a a
+expectMatch 20.33 xP "(?q)a b" "a b" "a b"
+expectMatch 20.34 P "(?qx)a b" "a b" "a b"
+expectMatch 20.35 P (?qi)ab Ab Ab
+
+
+doing 21 "capturing"
+expectMatch 21.1 - a(b)c abc abc b
+expectMatch 21.2 P a(?:b)c xabc abc
+expectMatch 21.3 - a((b))c xabcy abc b b
+expectMatch 21.4 P a(?:(b))c abcy abc b
+expectMatch 21.5 P a((?:b))c abc abc b
+expectMatch 21.6 P a(?:(?:b))c abc abc
+expectIndices 21.7 Q "a(b){0}c" ac {0 1} {-1 -1}
+expectMatch 21.8 - a(b)c(d)e abcde abcde b d
+expectMatch 21.9 - (b)c(d)e bcde bcde b d
+expectMatch 21.10 - a(b)(d)e abde abde b d
+expectMatch 21.11 - a(b)c(d) abcd abcd b d
+expectMatch 21.12 - (ab)(cd) xabcdy abcd ab cd
+expectMatch 21.13 - a(b)?c xabcy abc b
+expectIndices 21.14 - a(b)?c xacy {1 2} {-1 -1}
+expectMatch 21.15 - a(b)?c(d)?e xabcdey abcde b d
+expectIndices 21.16 - a(b)?c(d)?e xacdey {1 4} {-1 -1} {3 3}
+expectIndices 21.17 - a(b)?c(d)?e xabcey {1 4} {2 2} {-1 -1}
+expectIndices 21.18 - a(b)?c(d)?e xacey {1 3} {-1 -1} {-1 -1}
+expectMatch 21.19 - a(b)*c xabcy abc b
+expectIndices 21.20 - a(b)*c xabbbcy {1 5} {4 4}
+expectIndices 21.21 - a(b)*c xacy {1 2} {-1 -1}
+expectMatch 21.22 - a(b*)c xabbbcy abbbc bbb
+expectMatch 21.23 - a(b*)c xacy ac ""
+expectNomatch 21.24 - a(b)+c xacy
+expectMatch 21.25 - a(b)+c xabcy abc b
+expectIndices 21.26 - a(b)+c xabbbcy {1 5} {4 4}
+expectMatch 21.27 - a(b+)c xabbbcy abbbc bbb
+expectIndices 21.28 Q "a(b){2,3}c" xabbbcy {1 5} {4 4}
+expectIndices 21.29 Q "a(b){2,3}c" xabbcy {1 4} {3 3}
+expectNomatch 21.30 Q "a(b){2,3}c" xabcy
+expectMatch 21.31 LP "\\y(\\w+)\\y" "-- abc-" "abc" "abc"
+expectMatch 21.32 - a((b|c)d+)+ abacdbd acdbd bd b
+expectMatch 21.33 N (.*).* abc abc abc
+expectMatch 21.34 N (a*)* bc "" ""
+
+
+doing 22 "multicharacter collating elements"
+# again ugh
+expectMatch 22.1 &+L {a[c]e} ace ace
+expectNomatch 22.2 &+IL {a[c]h} ach
+expectMatch 22.3 &+L {a[[.ch.]]} ach ach
+expectNomatch 22.4 &+L {a[[.ch.]]} ace
+expectMatch 22.5 &+L {a[c[.ch.]]} ac ac
+expectMatch 22.6 &+L {a[c[.ch.]]} ace ac
+expectMatch 22.7 &+L {a[c[.ch.]]} ache ach
+expectNomatch 22.8 &+L {a[^c]e} ace
+expectMatch 22.9 &+L {a[^c]e} abe abe
+expectMatch 22.10 &+L {a[^c]e} ache ache
+expectNomatch 22.11 &+L {a[^[.ch.]]} ach
+expectMatch 22.12 &+L {a[^[.ch.]]} ace ac
+expectMatch 22.13 &+L {a[^[.ch.]]} ac ac
+expectMatch 22.14 &+L {a[^[.ch.]]} abe ab
+expectNomatch 22.15 &+L {a[^c[.ch.]]} ach
+expectNomatch 22.16 &+L {a[^c[.ch.]]} ace
+expectNomatch 22.17 &+L {a[^c[.ch.]]} ac
+expectMatch 22.18 &+L {a[^c[.ch.]]} abe ab
+expectMatch 22.19 &+L {a[^b]} ac ac
+expectMatch 22.20 &+L {a[^b]} ace ac
+expectMatch 22.21 &+L {a[^b]} ach ach
+expectNomatch 22.22 &+L {a[^b]} abe
+
+
+doing 23 "lookahead constraints"
+expectMatch 23.1 HP a(?=b)b* ab ab
+expectNomatch 23.2 HP a(?=b)b* a
+expectMatch 23.3 HP a(?=b)b*(?=c)c* abc abc
+expectNomatch 23.4 HP a(?=b)b*(?=c)c* ab
+expectNomatch 23.5 HP a(?!b)b* ab
+expectMatch 23.6 HP a(?!b)b* a a
+expectMatch 23.7 HP (?=b)b b b
+expectNomatch 23.8 HP (?=b)b a
+
+
+doing 24 "non-greedy quantifiers"
+expectMatch 24.1 PT ab+? abb ab
+expectMatch 24.2 PT ab+?c abbc abbc
+expectMatch 24.3 PT ab*? abb a
+expectMatch 24.4 PT ab*?c abbc abbc
+expectMatch 24.5 PT ab?? ab a
+expectMatch 24.6 PT ab??c abc abc
+expectMatch 24.7 PQT "ab{2,4}?" abbbb abb
+expectMatch 24.8 PQT "ab{2,4}?c" abbbbc abbbbc
+expectMatch 24.9 - 3z* 123zzzz456 3zzzz
+expectMatch 24.10 PT 3z*? 123zzzz456 3
+expectMatch 24.11 - z*4 123zzzz456 zzzz4
+expectMatch 24.12 PT z*?4 123zzzz456 zzzz4
+
+
+doing 25 "mixed quantifiers"
+# this is very incomplete as yet
+# should include |
+expectMatch 25.1 PNT {^(.*?)(a*)$} "xyza" xyza xyz a
+expectMatch 25.2 PNT {^(.*?)(a*)$} "xyzaa" xyzaa xyz aa
+expectMatch 25.3 PNT {^(.*?)(a*)$} "xyz" xyz xyz ""
+
+
+doing 26 "tricky cases"
+# attempts to trick the matcher into accepting a short match
+expectMatch 26.1 - (week|wee)(night|knights) \
+ "weeknights" weeknights wee knights
+expectMatch 26.2 RP {a(bc*).*\1} abccbccb abccbccb b
+expectMatch 26.3 - {a(b.[bc]*)+} abcbd abcbd bd
+
+
+doing 27 "implementation misc."
+# duplicate arcs are suppressed
+expectMatch 27.1 P a(?:b|b)c abc abc
+# make color/subcolor relationship go back and forth
+expectMatch 27.2 & {[ab][ab][ab]} aba aba
+expectMatch 27.3 & {[ab][ab][ab][ab][ab][ab][ab]} \
+ "abababa" abababa
+
+
+doing 28 "boundary busters etc."
+# color-descriptor allocation changes at 10
+expectMatch 28.1 & abcdefghijkl "abcdefghijkl" abcdefghijkl
+# so does arc allocation
+expectMatch 28.2 P a(?:b|c|d|e|f|g|h|i|j|k|l|m)n "agn" agn
+# subexpression tracking also at 10
+expectMatch 28.3 - a(((((((((((((b)))))))))))))c \
+ "abc" abc b b b b b b b b b b b b b
+# state-set handling changes slightly at unsigned size (might be 64...)
+# (also stresses arc allocation)
+expectMatch 28.4 Q "ab{1,100}c" abbc abbc
+expectMatch 28.5 Q "ab{1,100}c" \
+ "abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc" \
+ abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc
+expectMatch 28.6 Q "ab{1,100}c" \
+ "abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc"\
+ abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc
+# force small cache and bust it, several ways
+expectMatch 28.7 LP {\w+abcdefgh} xyzabcdefgh xyzabcdefgh
+expectMatch 28.8 %LP {\w+abcdefgh} xyzabcdefgh xyzabcdefgh
+expectMatch 28.9 %LP {\w+abcdefghijklmnopqrst} \
+ "xyzabcdefghijklmnopqrst" xyzabcdefghijklmnopqrst
+expectIndices 28.10 %LP {\w+(abcdefgh)?} xyz {0 2} {-1 -1}
+expectIndices 28.11 %LP {\w+(abcdefgh)?} xyzabcdefg {0 9} {-1 -1}
+expectIndices 28.12 %LP {\w+(abcdefghijklmnopqrst)?} \
+ "xyzabcdefghijklmnopqrs" {0 21} {-1 -1}
+
+
+doing 29 "incomplete matches"
+expectPartial 29.1 t def abc {3 2} ""
+expectPartial 29.2 t bcd abc {1 2} ""
+expectPartial 29.3 t abc abab {0 3} ""
+expectPartial 29.4 t abc abdab {3 4} ""
+expectIndices 29.5 t abc abc {0 2} {0 2}
+expectIndices 29.6 t abc xyabc {2 4} {2 4}
+expectPartial 29.7 t abc+ xyab {2 3} ""
+expectIndices 29.8 t abc+ xyabc {2 4} {2 4}
+knownBug expectIndices 29.9 t abc+ xyabcd {2 4} {6 5}
+expectIndices 29.10 t abc+ xyabcdd {2 4} {7 6}
+expectPartial 29.11 tPT abc+? xyab {2 3} ""
+# the retain numbers in these two may look wrong, but they aren't
+expectIndices 29.12 tPT abc+? xyabc {2 4} {5 4}
+expectIndices 29.13 tPT abc+? xyabcc {2 4} {6 5}
+expectIndices 29.14 tPT abc+? xyabcd {2 4} {6 5}
+expectIndices 29.15 tPT abc+? xyabcdd {2 4} {7 6}
+expectIndices 29.16 t abcd|bc xyabc {3 4} {2 4}
+expectPartial 29.17 tn .*k "xx\nyyy" {3 5} ""
+
+
+doing 30 "misc. oddities and old bugs"
+expectError 30.1 & *** BADRPT
+expectMatch 30.2 N a?b* abb abb
+expectMatch 30.3 N a?b* bb bb
+expectMatch 30.4 & a*b aab aab
+expectMatch 30.5 & ^a*b aaaab aaaab
+expectMatch 30.6 &M {[0-6][1-2][0-3][0-6][1-6][0-6]} \
+ "010010" 010010
+# temporary REG_BOSONLY kludge
+expectMatch 30.7 s abc abcd abc
+expectNomatch 30.8 s abc xabcd
+# back to normal stuff
+expectMatch 30.9 HLP {(?n)^(?![t#])\S+} \
+ "tk\n\n#\n#\nit0" it0
+
+
+# Now for tests *not* written by Henry Spencer
+
+namespace import -force ::tcltest::test
+
+# Tests resulting from bugs reported by users
+test reg-31.1 {[[:xdigit:]] behaves correctly when followed by [[:space:]]} {
+ set str {2:::DebugWin32}
+ set re {([[:xdigit:]])([[:space:]]*)}
+ list [regexp $re $str match xdigit spaces] $match $xdigit $spaces
+ # Code used to produce {1 2:::DebugWin32 2 :::DebugWin32} !!!
+} {1 2 2 {}}
+
+test reg-32.1 {canmatch functionality -- at end} testregexp {
+ set pat {blah}
+ set line "asd asd"
+ # can match at the final d, if '%' follows
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 7}
+test reg-32.2 {canmatch functionality -- at end} testregexp {
+ set pat {s%$}
+ set line "asd asd"
+ # can only match after the end of the string
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 7}
+test reg-32.3 {canmatch functionality -- not last char} testregexp {
+ set pat {[^d]%$}
+ set line "asd asd"
+ # can only match after the end of the string
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 7}
+test reg-32.3.1 {canmatch functionality -- no match} testregexp {
+ set pat {\Zx}
+ set line "asd asd"
+ # can match the last char, if followed by x
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 -1}
+test reg-32.4 {canmatch functionality -- last char} {knownBug testregexp} {
+ set pat {.x}
+ set line "asd asd"
+ # can match the last char, if followed by x
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+test reg-32.4.1 {canmatch functionality -- last char} {knownBug testregexp} {
+ set pat {.x$}
+ set line "asd asd"
+ # can match the last char, if followed by x
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+test reg-32.5 {canmatch functionality -- last char} {knownBug testregexp} {
+ set pat {.[^d]x$}
+ set line "asd asd"
+ # can match the last char, if followed by not-d and x.
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+test reg-32.6 {canmatch functionality -- last char} {knownBug testregexp} {
+ set pat {[^a]%[^\r\n]*$}
+ set line "asd asd"
+ # can match at the final d, if '%' follows
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+test reg-32.7 {canmatch functionality -- last char} {knownBug testregexp} {
+ set pat {[^a]%$}
+ set line "asd asd"
+ # can match at the final d, if '%' follows
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+test reg-32.8 {canmatch functionality -- last char} {knownBug testregexp} {
+ set pat {[^x]%$}
+ set line "asd asd"
+ # can match at the final d, if '%' follows
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+test reg-32.9 {canmatch functionality -- more complex case} {knownBug testregexp} {
+ set pat {((\B\B|\Bh+line)[ \t]*|[^\B]%[^\r\n]*)$}
+ set line "asd asd"
+ # can match at the final d, if '%' follows
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+
+# Tests reg-33.*: Checks for bug fixes
+
+test reg-33.1 {Bug 230589} {
+ regexp {[ ]*(^|[^%])%V} "*%V2" m s
+} 1
+test reg-33.2 {Bug 504785} {
+ regexp -inline {([^_.]*)([^.]*)\.(..)(.).*} bbcos_001_c01.q1la
+} {bbcos_001_c01.q1la bbcos _001_c01 q1 l}
+test reg-33.3 {Bug 505048} {
+ regexp {\A\s*[^<]*\s*<([^>]+)>} a<a>
+} 1
+test reg-33.4 {Bug 505048} {
+ regexp {\A\s*([^b]*)b} ab
+} 1
+test reg-33.5 {Bug 505048} {
+ regexp {\A\s*[^b]*(b)} ab
+} 1
+test reg-33.6 {Bug 505048} {
+ regexp {\A(\s*)[^b]*(b)} ab
+} 1
+test reg-33.7 {Bug 505048} {
+ regexp {\A\s*[^b]*b} ab
+} 1
+test reg-33.8 {Bug 505048} {
+ regexp -inline {\A\s*[^b]*b} ab
+} ab
+test reg-33.9 {Bug 505048} {
+ regexp -indices -inline {\A\s*[^b]*b} ab
+} {{0 1}}
+test reg-33.10 {Bug 840258} -body {
+ regsub {(^|\n)+\.*b} \n.b {} tmp
+} -cleanup {
+ unset tmp
+} -result 1
+test reg-33.11 {Bug 840258} -body {
+ regsub {(^|[\n\r]+)\.*\?<.*?(\n|\r)+} \
+ "TQ\r\n.?<5000267>Test already stopped\r\n" {} tmp
+} -cleanup {
+ unset tmp
+} -result 1
+test reg-33.12 {Bug 1810264 - bad read} {
+ regexp {\3161573148} {\3161573148}
+} 0
+test reg-33.13 {Bug 1810264 - infinite loop} {
+ regexp {($|^)*} {x}
+} 1
+# Some environments have small default stack sizes. [Bug 1905562]
+test reg-33.14 {Bug 1810264 - super-expensive expression} nonPortable {
+ regexp {(x{200}){200}$y} {x}
+} 0
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/regexp.test b/library/msgcat/tests/regexp.test
new file mode 100644
index 0000000..7cafd1b
--- /dev/null
+++ b/library/msgcat/tests/regexp.test
@@ -0,0 +1,1072 @@
+# Commands covered: regexp, regsub
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1998 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+unset -nocomplain foo
+
+testConstraint exec [llength [info commands exec]]
+
+test regexp-1.1 {basic regexp operation} {
+ regexp ab*c abbbc
+} 1
+test regexp-1.2 {basic regexp operation} {
+ regexp ab*c ac
+} 1
+test regexp-1.3 {basic regexp operation} {
+ regexp ab*c ab
+} 0
+test regexp-1.4 {basic regexp operation} {
+ regexp -- -gorp abc-gorpxxx
+} 1
+test regexp-1.5 {basic regexp operation} {
+ regexp {^([^ ]*)[ ]*([^ ]*)} "" a
+} 1
+test regexp-1.6 {basic regexp operation} {
+ list [catch {regexp {} abc} msg] $msg
+} {0 1}
+test regexp-1.7 {regexp utf compliance} {
+ # if not UTF-8 aware, result is "0 1"
+ set foo "\u4e4eb q"
+ regexp "\u4e4eb q" "a\u4e4eb qw\u5e4e\x4e wq" bar
+ list [string compare $foo $bar] [regexp 4 $bar]
+} {0 0}
+test regexp-1.8 {regexp ***= metasyntax} {
+ regexp -- "***=o" "aeiou"
+} 1
+test regexp-1.9 {regexp ***= metasyntax} {
+ set string "aeiou"
+ regexp -- "***=o" $string
+} 1
+test regexp-1.10 {regexp ***= metasyntax} {
+ set string "aeiou"
+ set re "***=o"
+ regexp -- $re $string
+} 1
+test regexp-1.11 {regexp ***= metasyntax} {
+ regexp -- "***=y" "aeiou"
+} 0
+test regexp-1.12 {regexp ***= metasyntax} {
+ set string "aeiou"
+ regexp -- "***=y" $string
+} 0
+test regexp-1.13 {regexp ***= metasyntax} {
+ set string "aeiou"
+ set re "***=y"
+ regexp -- $re $string
+} 0
+
+test regexp-2.1 {getting substrings back from regexp} {
+ set foo {}
+ list [regexp ab*c abbbbc foo] $foo
+} {1 abbbbc}
+test regexp-2.2 {getting substrings back from regexp} {
+ set foo {}
+ set f2 {}
+ list [regexp a(b*)c abbbbc foo f2] $foo $f2
+} {1 abbbbc bbbb}
+test regexp-2.3 {getting substrings back from regexp} {
+ set foo {}
+ set f2 {}
+ list [regexp a(b*)(c) abbbbc foo f2] $foo $f2
+} {1 abbbbc bbbb}
+test regexp-2.4 {getting substrings back from regexp} {
+ set foo {}
+ set f2 {}
+ set f3 {}
+ list [regexp a(b*)(c) abbbbc foo f2 f3] $foo $f2 $f3
+} {1 abbbbc bbbb c}
+test regexp-2.5 {getting substrings back from regexp} {
+ set foo {}; set f1 {}; set f2 {}; set f3 {}; set f4 {}; set f5 {};
+ set f6 {}; set f7 {}; set f8 {}; set f9 {}; set fa {}; set fb {};
+ list [regexp (1*)(2*)(3*)(4*)(5*)(6*)(7*)(8*)(9*)(a*)(b*) \
+ 12223345556789999aabbb \
+ foo f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb] $foo $f1 $f2 $f3 $f4 $f5 \
+ $f6 $f7 $f8 $f9 $fa $fb
+} {1 12223345556789999aabbb 1 222 33 4 555 6 7 8 9999 aa bbb}
+test regexp-2.6 {getting substrings back from regexp} {
+ set foo 2; set f2 2; set f3 2; set f4 2
+ list [regexp (a)(b)? xay foo f2 f3 f4] $foo $f2 $f3 $f4
+} {1 a a {} {}}
+test regexp-2.7 {getting substrings back from regexp} {
+ set foo 1; set f2 1; set f3 1; set f4 1
+ list [regexp (a)(b)?(c) xacy foo f2 f3 f4] $foo $f2 $f3 $f4
+} {1 ac a {} c}
+test regexp-2.8 {getting substrings back from regexp} {
+ set match {}
+ list [regexp {^a*b} aaaab match] $match
+} {1 aaaab}
+test regexp-2.9 {getting substrings back from regexp} {
+ set foo {}
+ set f2 {}
+ list [regexp f\352te(b*)c f\352tebbbbc foo f2] $foo $f2
+} [list 1 f\352tebbbbc bbbb]
+test regexp-2.10 {getting substrings back from regexp} {
+ set foo {}
+ set f2 {}
+ list [regexp f\352te(b*)c eff\352tebbbbc foo f2] $foo $f2
+} [list 1 f\352tebbbbc bbbb]
+test regexp-2.11 {non-capturing subgroup} {
+ set foo {}
+ set f2 {}
+ list [regexp {str(?:a+)} straa foo f2] $foo $f2
+} [list 1 straa {}]
+test regexp-2.12 {non-capturing subgroup with -inline} {
+ regexp -inline {str(?:a+)} straa
+} {straa}
+test regexp-2.13 {non-capturing and capturing subgroups} {
+ set foo {}
+ set f2 {}
+ set f3 {}
+ list [regexp {str(?:a+)(c+)} straacc foo f2 f3] $foo $f2 $f3
+} [list 1 straacc cc {}]
+test regexp-2.14 {non-capturing and capturing subgroups} {
+ regexp -inline {str(?:a+)(c+)} straacc
+} {straacc cc}
+test regexp-2.15 {getting substrings back from regexp} {
+ set foo NA
+ set f2 NA
+ list [regexp {str(?:a+)} straa foo f2] $foo $f2
+} [list 1 straa {}]
+
+test regexp-3.1 {-indices option to regexp} {
+ set foo {}
+ list [regexp -indices ab*c abbbbc foo] $foo
+} {1 {0 5}}
+test regexp-3.2 {-indices option to regexp} {
+ set foo {}
+ set f2 {}
+ list [regexp -indices a(b*)c abbbbc foo f2] $foo $f2
+} {1 {0 5} {1 4}}
+test regexp-3.3 {-indices option to regexp} {
+ set foo {}
+ set f2 {}
+ list [regexp -indices a(b*)(c) abbbbc foo f2] $foo $f2
+} {1 {0 5} {1 4}}
+test regexp-3.4 {-indices option to regexp} {
+ set foo {}
+ set f2 {}
+ set f3 {}
+ list [regexp -indices a(b*)(c) abbbbc foo f2 f3] $foo $f2 $f3
+} {1 {0 5} {1 4} {5 5}}
+test regexp-3.5 {-indices option to regexp} {
+ set foo {}; set f1 {}; set f2 {}; set f3 {}; set f4 {}; set f5 {};
+ set f6 {}; set f7 {}; set f8 {}; set f9 {}
+ list [regexp -indices (1*)(2*)(3*)(4*)(5*)(6*)(7*)(8*)(9*) \
+ 12223345556789999 \
+ foo f1 f2 f3 f4 f5 f6 f7 f8 f9] $foo $f1 $f2 $f3 $f4 $f5 \
+ $f6 $f7 $f8 $f9
+} {1 {0 16} {0 0} {1 3} {4 5} {6 6} {7 9} {10 10} {11 11} {12 12} {13 16}}
+test regexp-3.6 {getting substrings back from regexp} {
+ set foo 2; set f2 2; set f3 2; set f4 2
+ list [regexp -indices (a)(b)? xay foo f2 f3 f4] $foo $f2 $f3 $f4
+} {1 {1 1} {1 1} {-1 -1} {-1 -1}}
+test regexp-3.7 {getting substrings back from regexp} {
+ set foo 1; set f2 1; set f3 1; set f4 1
+ list [regexp -indices (a)(b)?(c) xacy foo f2 f3 f4] $foo $f2 $f3 $f4
+} {1 {1 2} {1 1} {-1 -1} {2 2}}
+
+test regexp-4.1 {-nocase option to regexp} {
+ regexp -nocase foo abcFOo
+} 1
+test regexp-4.2 {-nocase option to regexp} {
+ set f1 22
+ set f2 33
+ set f3 44
+ list [regexp -nocase {a(b*)([xy]*)z} aBbbxYXxxZ22 f1 f2 f3] $f1 $f2 $f3
+} {1 aBbbxYXxxZ Bbb xYXxx}
+test regexp-4.3 {-nocase option to regexp} {
+ regexp -nocase FOo abcFOo
+} 1
+set x abcdefghijklmnopqrstuvwxyz1234567890
+set x $x$x$x$x$x$x$x$x$x$x$x$x
+test regexp-4.4 {case conversion in regexp} {
+ list [regexp -nocase $x $x foo] $foo
+} "1 $x"
+unset -nocomplain x
+
+test regexp-5.1 {exercise cache of compiled expressions} {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*a bbba
+} 1
+test regexp-5.2 {exercise cache of compiled expressions} {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*b xxxb
+} 1
+test regexp-5.3 {exercise cache of compiled expressions} {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*c yyyc
+} 1
+test regexp-5.4 {exercise cache of compiled expressions} {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*d 1d
+} 1
+test regexp-5.5 {exercise cache of compiled expressions} {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*e xe
+} 1
+
+test regexp-6.1 {regexp errors} {
+ list [catch {regexp a} msg] $msg
+} {1 {wrong # args: should be "regexp ?-switch ...? exp string ?matchVar? ?subMatchVar ...?"}}
+test regexp-6.2 {regexp errors} {
+ list [catch {regexp -nocase a} msg] $msg
+} {1 {wrong # args: should be "regexp ?-switch ...? exp string ?matchVar? ?subMatchVar ...?"}}
+test regexp-6.3 {regexp errors} {
+ list [catch {regexp -gorp a} msg] $msg
+} {1 {bad switch "-gorp": must be -all, -about, -indices, -inline, -expanded, -line, -linestop, -lineanchor, -nocase, -start, or --}}
+test regexp-6.4 {regexp errors} {
+ list [catch {regexp a( b} msg] $msg
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexp-6.5 {regexp errors} {
+ list [catch {regexp a( b} msg] $msg
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexp-6.6 {regexp errors} {
+ list [catch {regexp a a f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1} msg] $msg
+} {0 1}
+test regexp-6.7 {regexp errors} {
+ list [catch {regexp (x)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.) xyzzy} msg] $msg
+} {0 0}
+test regexp-6.8 {regexp errors} -setup {
+ unset -nocomplain f1
+} -body {
+ set f1 44
+ regexp abc abc f1(f2)
+} -returnCodes error -result {can't set "f1(f2)": variable isn't array}
+test regexp-6.9 {regexp errors, -start bad int check} {
+ list [catch {regexp -start bogus {^$} {}} msg] $msg
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
+test regexp-6.10 {regexp errors} {
+ list [catch {regexp {a[} b} msg] $msg
+} {1 {couldn't compile regular expression pattern: brackets [] not balanced}}
+
+test regexp-7.1 {basic regsub operation} {
+ list [regsub aa+ xaxaaaxaa 111&222 foo] $foo
+} {1 xax111aaa222xaa}
+test regexp-7.2 {basic regsub operation} {
+ list [regsub aa+ aaaxaa &111 foo] $foo
+} {1 aaa111xaa}
+test regexp-7.3 {basic regsub operation} {
+ list [regsub aa+ xaxaaa 111& foo] $foo
+} {1 xax111aaa}
+test regexp-7.4 {basic regsub operation} {
+ list [regsub aa+ aaa 11&2&333 foo] $foo
+} {1 11aaa2aaa333}
+test regexp-7.5 {basic regsub operation} {
+ list [regsub aa+ xaxaaaxaa &2&333 foo] $foo
+} {1 xaxaaa2aaa333xaa}
+test regexp-7.6 {basic regsub operation} {
+ list [regsub aa+ xaxaaaxaa 1&22& foo] $foo
+} {1 xax1aaa22aaaxaa}
+test regexp-7.7 {basic regsub operation} {
+ list [regsub a(a+) xaxaaaxaa {1\122\1} foo] $foo
+} {1 xax1aa22aaxaa}
+test regexp-7.8 {basic regsub operation} {
+ list [regsub a(a+) xaxaaaxaa {1\\\122\1} foo] $foo
+} "1 {xax1\\aa22aaxaa}"
+test regexp-7.9 {basic regsub operation} {
+ list [regsub a(a+) xaxaaaxaa {1\\122\1} foo] $foo
+} "1 {xax1\\122aaxaa}"
+test regexp-7.10 {basic regsub operation} {
+ list [regsub a(a+) xaxaaaxaa {1\\&\1} foo] $foo
+} "1 {xax1\\aaaaaxaa}"
+test regexp-7.11 {basic regsub operation} {
+ list [regsub a(a+) xaxaaaxaa {1\&\1} foo] $foo
+} {1 xax1&aaxaa}
+test regexp-7.12 {basic regsub operation} {
+ list [regsub a(a+) xaxaaaxaa {\1\1\1\1&&} foo] $foo
+} {1 xaxaaaaaaaaaaaaaaxaa}
+test regexp-7.13 {basic regsub operation} {
+ set foo xxx
+ list [regsub abc xyz 111 foo] $foo
+} {0 xyz}
+test regexp-7.14 {basic regsub operation} {
+ set foo xxx
+ list [regsub ^ xyz "111 " foo] $foo
+} {1 {111 xyz}}
+test regexp-7.15 {basic regsub operation} {
+ set foo xxx
+ list [regsub -- -foo abc-foodef "111 " foo] $foo
+} {1 {abc111 def}}
+test regexp-7.16 {basic regsub operation} {
+ set foo xxx
+ list [regsub x "" y foo] $foo
+} {0 {}}
+test regexp-7.17 {regsub utf compliance} {
+ # if not UTF-8 aware, result is "0 1"
+ set foo "xyz555ijka\u4e4ebpqr"
+ regsub a\u4e4eb xyza\u4e4ebijka\u4e4ebpqr 555 bar
+ list [string compare $foo $bar] [regexp 4 $bar]
+} {0 0}
+test regexp-7.18 {basic regsub replacement} {
+ list [regsub a+ aaa {&} foo] $foo
+} {1 aaa}
+test regexp-7.19 {basic regsub replacement} {
+ list [regsub a+ aaa {\&} foo] $foo
+} {1 &}
+test regexp-7.20 {basic regsub replacement} {
+ list [regsub a+ aaa {\\&} foo] $foo
+} {1 {\aaa}}
+test regexp-7.21 {basic regsub replacement} {
+ list [regsub a+ aaa {\\\&} foo] $foo
+} {1 {\&}}
+test regexp-7.22 {basic regsub replacement} {
+ list [regsub a+ aaa {\0} foo] $foo
+} {1 aaa}
+test regexp-7.23 {basic regsub replacement} {
+ list [regsub a+ aaa {\\0} foo] $foo
+} {1 {\0}}
+test regexp-7.24 {basic regsub replacement} {
+ list [regsub a+ aaa {\\\0} foo] $foo
+} {1 {\aaa}}
+test regexp-7.25 {basic regsub replacement} {
+ list [regsub a+ aaa {\\\\0} foo] $foo
+} {1 {\\0}}
+test regexp-7.26 {dollar zero is not a backslash replacement} {
+ list [regsub a+ aaa {$0} foo] $foo
+} {1 {$0}}
+test regexp-7.27 {dollar zero is not a backslash replacement} {
+ list [regsub a+ aaa {\0$0} foo] $foo
+} {1 {aaa$0}}
+test regexp-7.28 {dollar zero is not a backslash replacement} {
+ list [regsub a+ aaa {\$0} foo] $foo
+} {1 {\$0}}
+test regexp-7.29 {dollar zero is not a backslash replacement} {
+ list [regsub a+ aaa {\\} foo] $foo
+} {1 \\}
+
+test regexp-8.1 {case conversion in regsub} {
+ list [regsub -nocase a(a+) xaAAaAAay & foo] $foo
+} {1 xaAAaAAay}
+test regexp-8.2 {case conversion in regsub} {
+ list [regsub -nocase a(a+) xaAAaAAay & foo] $foo
+} {1 xaAAaAAay}
+test regexp-8.3 {case conversion in regsub} {
+ set foo 123
+ list [regsub a(a+) xaAAaAAay & foo] $foo
+} {0 xaAAaAAay}
+test regexp-8.4 {case conversion in regsub} {
+ set foo 123
+ list [regsub -nocase a CaDE b foo] $foo
+} {1 CbDE}
+test regexp-8.5 {case conversion in regsub} {
+ set foo 123
+ list [regsub -nocase XYZ CxYzD b foo] $foo
+} {1 CbD}
+test regexp-8.6 {case conversion in regsub} {
+ set x abcdefghijklmnopqrstuvwxyz1234567890
+ set x $x$x$x$x$x$x$x$x$x$x$x$x
+ set foo 123
+ list [regsub -nocase $x $x b foo] $foo
+} {1 b}
+
+test regexp-9.1 {-all option to regsub} {
+ set foo 86
+ list [regsub -all x+ axxxbxxcxdx |&| foo] $foo
+} {4 a|xxx|b|xx|c|x|d|x|}
+test regexp-9.2 {-all option to regsub} {
+ set foo 86
+ list [regsub -nocase -all x+ aXxXbxxcXdx |&| foo] $foo
+} {4 a|XxX|b|xx|c|X|d|x|}
+test regexp-9.3 {-all option to regsub} {
+ set foo 86
+ list [regsub x+ axxxbxxcxdx |&| foo] $foo
+} {1 a|xxx|bxxcxdx}
+test regexp-9.4 {-all option to regsub} {
+ set foo 86
+ list [regsub -all bc axxxbxxcxdx |&| foo] $foo
+} {0 axxxbxxcxdx}
+test regexp-9.5 {-all option to regsub} {
+ set foo xxx
+ list [regsub -all node "node node more" yy foo] $foo
+} {2 {yy yy more}}
+test regexp-9.6 {-all option to regsub} {
+ set foo xxx
+ list [regsub -all ^ xxx 123 foo] $foo
+} {1 123xxx}
+
+test regexp-10.1 {expanded syntax in regsub} {
+ set foo xxx
+ list [regsub -expanded ". \#comment\n . \#comment2" abc def foo] $foo
+} {1 defc}
+test regexp-10.2 {newline sensitivity in regsub} {
+ set foo xxx
+ list [regsub -line {^a.*b$} "dabc\naxyb\n" 123 foo] $foo
+} "1 {dabc\n123\n}"
+test regexp-10.3 {newline sensitivity in regsub} {
+ set foo xxx
+ list [regsub -line {^a.*b$} "dabc\naxyb\nxb" 123 foo] $foo
+} "1 {dabc\n123\nxb}"
+test regexp-10.4 {partial newline sensitivity in regsub} {
+ set foo xxx
+ list [regsub -lineanchor {^a.*b$} "da\naxyb\nxb" 123 foo] $foo
+} "1 {da\n123}"
+test regexp-10.5 {inverse partial newline sensitivity in regsub} {
+ set foo xxx
+ list [regsub -linestop {a.*b} "da\nbaxyb\nxb" 123 foo] $foo
+} "1 {da\nb123\nxb}"
+
+test regexp-11.1 {regsub errors} {
+ list [catch {regsub a b} msg] $msg
+} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}}
+test regexp-11.2 {regsub errors} {
+ list [catch {regsub -nocase a b} msg] $msg
+} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}}
+test regexp-11.3 {regsub errors} {
+ list [catch {regsub -nocase -all a b} msg] $msg
+} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}}
+test regexp-11.4 {regsub errors} {
+ list [catch {regsub a b c d e f} msg] $msg
+} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}}
+test regexp-11.5 {regsub errors} {
+ list [catch {regsub -gorp a b c} msg] $msg
+} {1 {bad switch "-gorp": must be -all, -nocase, -expanded, -line, -linestop, -lineanchor, -start, or --}}
+test regexp-11.6 {regsub errors} {
+ list [catch {regsub -nocase a( b c d} msg] $msg
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexp-11.7 {regsub errors} -setup {
+ unset -nocomplain f1
+} -body {
+ set f1 44
+ regsub -nocase aaa aaa xxx f1(f2)
+} -returnCodes error -result {can't set "f1(f2)": variable isn't array}
+test regexp-11.8 {regsub errors, -start bad int check} {
+ list [catch {regsub -start bogus pattern string rep var} msg] $msg
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
+test regexp-11.9 {regsub without final variable name returns value} {
+ regsub b abaca X
+} {aXaca}
+test regexp-11.10 {regsub without final variable name returns value} {
+ regsub -all a abaca X
+} {XbXcX}
+test regexp-11.11 {regsub without final variable name returns value} {
+ regsub b(.*?)d abcdeabcfde {,&,\1,}
+} {a,bcd,c,eabcfde}
+test regexp-11.12 {regsub without final variable name returns value} {
+ regsub -all b(.*?)d abcdeabcfde {,&,\1,}
+} {a,bcd,c,ea,bcfd,cf,e}
+
+# This test crashes on the Mac unless you increase the Stack Space to about 1
+# Meg. This is probably bigger than most users want...
+# 8.2.3 regexp reduced stack space requirements, but this should be
+# tested again
+test regexp-12.1 {Tcl_RegExpExec: large number of subexpressions} {macCrash} {
+ list [regexp (.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.) abcdefghijklmnopqrstuvwxyz all a b c d e f g h i j k l m n o p q r s t u v w x y z] $all $a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z
+} {1 abcdefghijklmnopqrstuvwxyz a b c d e f g h i j k l m n o p q r s t u v w x y z}
+
+test regexp-13.1 {regsub of a very large string} {
+ # This test is designed to stress the memory subsystem in order to catch
+ # Bug #933. It only fails if the Tcl memory allocator is in use.
+ set line {BEGIN_TABLE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; END_TABLE}
+ set filedata [string repeat $line 200]
+ for {set i 1} {$i<10} {incr i} {
+ regsub -all "BEGIN_TABLE " $filedata "" newfiledata
+ }
+ set x done
+} {done}
+
+test regexp-14.1 {CompileRegexp: regexp cache} {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ set x .
+ append x *a
+ regexp $x bbba
+} 1
+test regexp-14.2 {CompileRegexp: regexp cache, different flags} {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ set x .
+ append x *a
+ regexp -nocase $x bbba
+} 1
+test regexp-14.3 {CompileRegexp: regexp cache, empty regexp and empty cache} -constraints {
+ exec
+} -setup {
+ set junk [makeFile {puts [regexp {} foo]} junk.tcl]
+} -body {
+ exec [interpreter] $junk
+} -cleanup {
+ removeFile junk.tcl
+} -result 1
+
+test regexp-15.1 {regexp -start} {
+ unset -nocomplain x
+ list [regexp -start -10 {\d} 1abc2de3 x] $x
+} {1 1}
+test regexp-15.2 {regexp -start} {
+ unset -nocomplain x
+ list [regexp -start 2 {\d} 1abc2de3 x] $x
+} {1 2}
+test regexp-15.3 {regexp -start} {
+ unset -nocomplain x
+ list [regexp -start 4 {\d} 1abc2de3 x] $x
+} {1 2}
+test regexp-15.4 {regexp -start} {
+ unset -nocomplain x
+ list [regexp -start 5 {\d} 1abc2de3 x] $x
+} {1 3}
+test regexp-15.5 {regexp -start, over end of string} {
+ unset -nocomplain x
+ list [regexp -start [string length 1abc2de3] {\d} 1abc2de3 x] [info exists x]
+} {0 0}
+test regexp-15.6 {regexp -start, loss of ^$ behavior} {
+ list [regexp -start 2 {^$} {}]
+} {0}
+test regexp-15.7 {regexp -start, double option} {
+ regexp -start 2 -start 0 a abc
+} 1
+test regexp-15.8 {regexp -start, double option} {
+ regexp -start 0 -start 2 a abc
+} 0
+test regexp-15.9 {regexp -start, end relative index} {
+ unset -nocomplain x
+ list [regexp -start end {\d} 1abc2de3 x] [info exists x]
+} {0 0}
+test regexp-15.10 {regexp -start, end relative index} {
+ unset -nocomplain x
+ list [regexp -start end-1 {\d} 1abc2de3 x] [info exists x] $x
+} {1 1 3}
+test regexp-15.11 {regexp -start, over end of string} {
+ set x NA
+ list [regexp -start 2 {.*} ab x] $x
+} {1 {}}
+
+test regexp-16.1 {regsub -start} {
+ unset -nocomplain x
+ list [regsub -all -start 2 {\d} a1b2c3d4e5 {/&} x] $x
+} {4 a1b/2c/3d/4e/5}
+test regexp-16.2 {regsub -start} {
+ unset -nocomplain x
+ list [regsub -all -start -25 {z} hello {/&} x] $x
+} {0 hello}
+test regexp-16.3 {regsub -start} {
+ unset -nocomplain x
+ list [regsub -all -start 3 {z} hello {/&} x] $x
+} {0 hello}
+test regexp-16.4 {regsub -start, \A behavior} {
+ set out {}
+ lappend out [regsub -start 0 -all {\A(\w)} {abcde} {/\1} x] $x
+ lappend out [regsub -start 2 -all {\A(\w)} {abcde} {/\1} x] $x
+} {5 /a/b/c/d/e 3 ab/c/d/e}
+test regexp-16.5 {regsub -start, double option} {
+ list [regsub -start 2 -start 0 a abc c x] $x
+} {1 cbc}
+test regexp-16.6 {regsub -start, double option} {
+ list [regsub -start 0 -start 2 a abc c x] $x
+} {0 abc}
+test regexp-16.7 {regexp -start, end relative index} {
+ list [regsub -start end a aaa b x] $x
+} {0 aaa}
+test regexp-16.8 {regexp -start, end relative index} {
+ list [regsub -start end-1 a aaa b x] $x
+} {1 aab}
+test regexp-16.9 {regsub -start and -all} {
+ set foo {}
+ list [regsub -start 0 -all x+ axxxbxx |&| foo] $foo
+} {2 a|xxx|b|xx|}
+test regexp-16.10 {regsub -start and -all} {
+ set foo {}
+ list [regsub -start 1 -all x+ axxxbxx |&| foo] $foo
+} {2 a|xxx|b|xx|}
+test regexp-16.11 {regsub -start and -all} {
+ set foo {}
+ list [regsub -start 4 -all x+ axxxbxx |&| foo] $foo
+} {1 axxxb|xx|}
+test regexp-16.12 {regsub -start} {
+ set foo {}
+ list [regsub -start 4 x+ axxxbxx |&| foo] $foo
+} {1 axxxb|xx|}
+test regexp-16.13 {regsub -start and -all} {
+ set foo {}
+ list [regsub -start 1 -all a+ "" & foo] $foo
+} {0 {}}
+test regexp-16.14 {regsub -start} {
+ set foo {}
+ list [regsub -start 1 a+ "" & foo] $foo
+} {0 {}}
+test regexp-16.15 {regsub -start and -all} {
+ set foo {}
+ list [regsub -start 2 -all a+ "xy" & foo] $foo
+} {0 xy}
+test regexp-16.16 {regsub -start} {
+ set foo {}
+ list [regsub -start 2 a+ "xy" & foo] $foo
+} {0 xy}
+test regexp-16.17 {regsub -start and -all} {
+ set foo {}
+ list [regsub -start 1 -all y+ "xy" & foo] $foo
+} {1 xy}
+test regexp-16.18 {regsub -start} {
+ set foo {}
+ list [regsub -start 1 y+ "xy" & foo] $foo
+} {1 xy}
+test regexp-16.19 {regsub -start} {
+ set foo {}
+ list [regsub -start -1 a+ "" & foo] $foo
+} {0 {}}
+test regexp-16.20 {regsub -start, loss of ^$ behavior} {
+ set foo NA
+ list [regsub -start 1 {^$} {} & foo] $foo
+} {0 {}}
+test regexp-16.21 {regsub -start, loss of ^$ behavior} {
+ set foo NA
+ list [regsub -start 1 {^.*$} abc & foo] $foo
+} {0 abc}
+test regexp-16.22 {regsub -start, loss of ^$ behavior} {
+ set foo NA
+ list [regsub -all -start 1 {^.*$} abc & foo] $foo
+} {0 abc}
+
+test regexp-17.1 {regexp -inline} {
+ regexp -inline b ababa
+} {b}
+test regexp-17.2 {regexp -inline} {
+ regexp -inline (b) ababa
+} {b b}
+test regexp-17.3 {regexp -inline -indices} {
+ regexp -inline -indices (b) ababa
+} {{1 1} {1 1}}
+test regexp-17.4 {regexp -inline} {
+ regexp -inline {\w(\d+)\w} " hello 23 there456def "
+} {e456d 456}
+test regexp-17.5 {regexp -inline no matches} {
+ regexp -inline {\w(\d+)\w} ""
+} {}
+test regexp-17.6 {regexp -inline no matches} {
+ regexp -inline hello goodbye
+} {}
+test regexp-17.7 {regexp -inline, no matchvars allowed} {
+ list [catch {regexp -inline b abc match} msg] $msg
+} {1 {regexp match variables not allowed when using -inline}}
+
+test regexp-18.1 {regexp -all} {
+ regexp -all b bbbbb
+} {5}
+test regexp-18.2 {regexp -all} {
+ regexp -all b abababbabaaaaaaaaaab
+} {6}
+test regexp-18.3 {regexp -all -inline} {
+ regexp -all -inline b abababbabaaaaaaaaaab
+} {b b b b b b}
+test regexp-18.4 {regexp -all -inline} {
+ regexp -all -inline {\w(\w)} abcdefg
+} {ab b cd d ef f}
+test regexp-18.5 {regexp -all -inline} {
+ regexp -all -inline {\w(\w)$} abcdefg
+} {fg g}
+test regexp-18.6 {regexp -all -inline} {
+ regexp -all -inline {\d+} 10:20:30:40
+} {10 20 30 40}
+test regexp-18.7 {regexp -all -inline} {
+ list [catch {regexp -all -inline b abc match} msg] $msg
+} {1 {regexp match variables not allowed when using -inline}}
+test regexp-18.8 {regexp -all} {
+ # This should not cause an infinite loop
+ regexp -all -inline {a*} a
+} {a}
+test regexp-18.9 {regexp -all} {
+ # Yes, the expected result is {a {}}. Here's why:
+ # Start at index 0; a* matches the "a" there then stops.
+ # Go to index 1; a* matches the lambda (or {}) there then stops. Recall
+ # that a* matches zero or more "a"'s; thus it matches the string "b", as
+ # there are zero or more "a"'s there.
+ # Go to index 2; this is past the end of the string, so stop.
+ regexp -all -inline {a*} ab
+} {a {}}
+test regexp-18.10 {regexp -all} {
+ # Yes, the expected result is {a {} a}. Here's why:
+ # Start at index 0; a* matches the "a" there then stops.
+ # Go to index 1; a* matches the lambda (or {}) there then stops. Recall
+ # that a* matches zero or more "a"'s; thus it matches the string "b", as
+ # there are zero or more "a"'s there.
+ # Go to index 2; a* matches the "a" there then stops.
+ # Go to index 3; this is past the end of the string, so stop.
+ regexp -all -inline {a*} aba
+} {a {} a}
+test regexp-18.11 {regexp -all} {
+ regexp -all -inline {^a} aaaa
+} {a}
+test regexp-18.12 {regexp -all -inline -indices} {
+ regexp -all -inline -indices a(b(c)d|e(f)g)h abcdhaefgh
+} {{0 4} {1 3} {2 2} {-1 -1} {5 9} {6 8} {-1 -1} {7 7}}
+
+test regexp-19.1 {regsub null replacement} {
+ regsub -all {@} {@hel@lo@} "\0a\0" result
+ list $result [string length $result]
+} "\0a\0hel\0a\0lo\0a\0 14"
+
+test regexp-19.2 {regsub null replacement} {
+ regsub -all {@} {@hel@lo@} "\0a\0" result
+ set expected "\0a\0hel\0a\0lo\0a\0"
+ string equal $result $expected
+} 1
+
+test regexp-20.1 {regsub shared object shimmering} {
+ # Bug #461322
+ set a abcdefghijklmnopqurstuvwxyz
+ set b $a
+ set c abcdefghijklmnopqurstuvwxyz0123456789
+ regsub $a $c $b d
+ list $d [string length $d] [string bytelength $d]
+} [list abcdefghijklmnopqurstuvwxyz0123456789 37 37]
+test regexp-20.2 {regsub shared object shimmering with -about} {
+ eval regexp -about abc
+} {0 {}}
+
+test regexp-21.1 {regsub works with empty string} {
+ regsub -- ^ {} foo
+} {foo}
+test regexp-21.2 {regsub works with empty string} {
+ regsub -- \$ {} foo
+} {foo}
+test regexp-21.3 {regsub works with empty string offset} {
+ regsub -start 0 -- ^ {} foo
+} {foo}
+test regexp-21.4 {regsub works with empty string offset} {
+ regsub -start 0 -- \$ {} foo
+} {foo}
+test regexp-21.5 {regsub works with empty string offset} {
+ regsub -start 3 -- \$ {123} foo
+} {123foo}
+test regexp-21.6 {regexp works with empty string} {
+ regexp -- ^ {}
+} {1}
+test regexp-21.7 {regexp works with empty string} {
+ regexp -start 0 -- ^ {}
+} {1}
+test regexp-21.8 {regexp works with empty string offset} {
+ regexp -start 3 -- ^ {123}
+} {0}
+test regexp-21.9 {regexp works with empty string offset} {
+ regexp -start 3 -- \$ {123}
+} {1}
+test regexp-21.10 {multiple matches handle newlines} {
+ regsub -all -lineanchor -- {^#[^\n]*\n} "#one\n#two\n#three\n" foo\n
+} "foo\nfoo\nfoo\n"
+test regexp-21.11 {multiple matches handle newlines} {
+ regsub -all -line -- ^ "a\nb\nc" \#
+} "\#a\n\#b\n\#c"
+test regexp-21.12 {multiple matches handle newlines} {
+ regsub -all -line -- ^ "\n\n" \#
+} "\#\n\#\n\#"
+test regexp-21.13 {multiple matches handle newlines} {
+ regexp -all -inline -indices -line -- ^ "a\nb\nc"
+} {{0 -1} {2 1} {4 3}}
+test regexp-21.14 {regsub works with empty string} {
+ regsub -- ^ {} &
+} {}
+test regexp-21.15 {regsub works with empty string} {
+ regsub -- ^ {} foo&
+} {foo}
+test regexp-21.16 {regsub works with empty string} {
+ regsub -all -- ^ {} foo&
+} {foo}
+test regexp-21.17 {regsub works with empty string} {
+ regsub -- ^ {} {foo\0}
+} {foo}
+test regexp-21.18 {regsub works with empty string} {
+ regsub -- ^.* {} {foo$0}
+} {foo$0}
+test regexp-21.19 {regsub works with empty string} {
+ regsub -- ^ {input} {}
+} {input}
+test regexp-21.20 {regsub works with empty string} {
+ regsub -- x {} {foo}
+} {}
+
+test regexp-22.1 {Bug 1810038} {
+ regexp ($|^X)* {}
+} 1
+test regexp-22.2 {regexp compile and backrefs, Bug 1857126} {
+ regexp -- {([bc])\1} bb
+} 1
+
+test regexp-23.1 {regexp -all and -line} {
+ set string ""
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1}} {{0 -1}} {{0 -1}}}
+test regexp-23.2 {regexp -all and -line} {
+ set string "\n"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1}} {{0 -1}} {{0 -1}}}
+test regexp-23.3 {regexp -all and -line} {
+ set string "\n\n"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {1 0}} {{0 -1} {1 0}} {{0 -1} {1 0}}}
+test regexp-23.4 {regexp -all and -line} {
+ set string "a"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^.*$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1}} {{0 0}} {{1 0}}}
+test regexp-23.5 {regexp -all and -line} {knownBug} {
+ set string "a\n"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^.*$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {2 1}} {{0 0} {2 1}} {{1 0} {2 1}}}
+test regexp-23.6 {regexp -all and -line} {
+ set string "\na"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^.*$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {1 0}} {{0 -1} {1 1}} {{0 -1} {2 1}}}
+test regexp-23.7 {regexp -all and -line} {knownBug} {
+ set string "ab\n"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^.*$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {3 2}} {{0 1} {3 2}} {{2 1} {3 2}}}
+test regexp-23.8 {regexp -all and -line} {
+ set string "a\nb"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^.*$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {2 1}} {{0 0} {2 2}} {{1 0} {3 2}}}
+test regexp-23.9 {regexp -all and -line} {knownBug} {
+ set string "a\nb\n"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^.*$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {2 1} {4 3}} {{0 0} {2 2} {4 3}} {{1 0} {3 2} {4 3}}}
+test regexp-23.10 {regexp -all and -line} {
+ set string "a\nb\nc"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^.*$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {2 1} {4 3}} {{0 0} {2 2} {4 4}} {{1 0} {3 2} {5 4}}}
+test regexp-23.11 {regexp -all and -line} {
+ regexp -all -inline -indices -line -- {b} "abb\nb"
+} {{1 1} {2 2} {4 4}}
+
+test regexp-24.1 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string ""
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} {1 <> 1 <> 1 <>}
+test regexp-24.2 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "\n"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 2 "<>\n<>" 2 "<>\n<>" 2 "<>\n<>"]
+test regexp-24.3 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "\n\n"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 3 "<>\n<>\n<>" 3 "<>\n<>\n<>" 3 "<>\n<>\n<>"]
+test regexp-24.4 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "a"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 1 "<>a" 1 "<a>" 1 "a<>"]
+test regexp-24.5 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "a\n"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 2 "<>a\n<>" 2 "<a>\n<>" 2 "a<>\n<>"]
+test regexp-24.6 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "\na"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 2 "<>\n<>a" 2 "<>\n<a>" 2 "<>\na<>"]
+test regexp-24.7 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "ab\n"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 2 "<>ab\n<>" 2 "<ab>\n<>" 2 "ab<>\n<>"]
+test regexp-24.8 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "a\nb"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 2 "<>a\n<>b" 2 "<a>\n<b>" 2 "a<>\nb<>"]
+test regexp-24.9 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "a\nb\n"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 3 "<>a\n<>b\n<>" 3 "<a>\n<b>\n<>" 3 "a<>\nb<>\n<>"]
+test regexp-24.10 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "a\nb\nc"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 3 "<>a\n<>b\n<>c" 3 "<a>\n<b>\n<c>" 3 "a<>\nb<>\nc<>"]
+test regexp-24.11 {regsub -all and -line} {
+ regsub -line -all {b} "abb\nb" {<&>}
+} "a<b><b>\n<b>"
+
+test regexp-25.1 {regexp without -line option} {
+ set foo ""
+ list [regexp {a.*b} "dabc\naxyb\n" foo] $foo
+} [list 1 abc\naxyb]
+test regexp-25.2 {regexp without -line option} {
+ set foo ""
+ list [regexp {^a.*b$} "dabc\naxyb\n" foo] $foo
+} {0 {}}
+test regexp-25.3 {regexp with -line option} {
+ set foo ""
+ list [regexp -line {^a.*b$} "dabc\naxyb\n" foo] $foo
+} {1 axyb}
+test regexp-25.4 {regexp with -line option} {
+ set foo ""
+ list [regexp -line {^a.*b$} "dabc\naxyb\nxb" foo] $foo
+} {1 axyb}
+test regexp-25.5 {regexp without -line option} {
+ set foo ""
+ list [regexp {^a.*b$} "dabc\naxyb\nxb" foo] $foo
+} {0 {}}
+test regexp-25.6 {regexp without -line option} {
+ set foo ""
+ list [regexp {a.*b$} "dabc\naxyb\nxb" foo] $foo
+} "1 {abc\naxyb\nxb}"
+test regexp-25.7 {regexp with -lineanchor option} {
+ set foo ""
+ list [regexp -lineanchor {^a.*b$} "dabc\naxyb\nxb" foo] $foo
+} "1 {axyb\nxb}"
+test regexp-25.8 {regexp with -lineanchor and -linestop option} {
+ set foo ""
+ list [regexp -lineanchor -linestop {^a.*b$} "dabc\naxyb\nxb" foo] $foo
+} {1 axyb}
+test regexp-25.9 {regexp with -linestop option} {
+ set foo ""
+ list [regexp -linestop {a.*b} "ab\naxyb\nxb" foo] $foo
+} {1 ab}
+
+test regexp-26.1 {matches start of line 1 time} {
+ regexp -all -inline -- {^a+} "aab\naaa"
+} {aa}
+test regexp-26.2 {matches start of line(s) 2 times} {
+ regexp -all -inline -line -- {^a+} "aab\naaa"
+} {aa aaa}
+test regexp-26.3 {effect of -line -all and -start} {
+ list \
+ [regexp -all -inline -line -start 0 -- {^a+} "aab\naaa"] \
+ [regexp -all -inline -line -start 1 -- {^a+} "aab\naaa"] \
+ [regexp -all -inline -line -start 3 -- {^a+} "aab\naaa"] \
+ [regexp -all -inline -line -start 4 -- {^a+} "aab\naaa"] \
+} {{aa aaa} aaa aaa aaa}
+# No regexp-26.4
+test regexp-26.5 {match length 0, match length 1} {
+ regexp -all -inline -line -- {^b*} "a\nb"
+} {{} b}
+test regexp-26.6 {non reporting capture group} {
+ regexp -all -inline -line -- {^(?:a+|b)} "aab\naaa"
+} {aa aaa}
+test regexp-26.7 {Tcl bug 2826551: -line sensitive regexp and -start} {
+ set match1 {}
+ set match2 {}
+ list \
+ [regexp -start 0 -indices -line {^a} "\nab" match1] $match1 \
+ [regexp -start 1 -indices -line {^a} "\nab" match2] $match2
+} {1 {1 1} 1 {1 1}}
+test regexp-26.8 {Tcl bug 2826551: diff regexp with -line option} {
+ set data "@1\n2\n+3\n@4\n-5\n+6\n7\n@8\n9\n"
+ regexp -all -inline -line {^@.*\n(?:[^@].*\n?)*} $data
+} [list "@1\n2\n+3\n" "@4\n-5\n+6\n7\n" "@8\n9\n"]
+test regexp-26.9 {Tcl bug 2826551: diff regexp with embedded -line option} {
+ set data "@1\n2\n+3\n@4\n-5\n+6\n7\n@8\n9\n"
+ regexp -all -inline {(?n)^@.*\n(?:[^@].*\n?)*} $data
+} [list "@1\n2\n+3\n" "@4\n-5\n+6\n7\n" "@8\n9\n"]
+test regexp-26.10 {regexp with -line option} {
+ regexp -all -inline -line -- {a*} "a\n"
+} {a {}}
+test regexp-26.11 {regexp without -line option} {
+ regexp -all -inline -- {a*} "a\n"
+} {a {}}
+test regexp-26.12 {regexp with -line option} {
+ regexp -all -inline -line -- {a*} "b\n"
+} {{} {}}
+test regexp-26.13 {regexp without -line option} {
+ regexp -all -inline -- {a*} "b\n"
+} {{} {}}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/regexpComp.test b/library/msgcat/tests/regexpComp.test
new file mode 100644
index 0000000..94fb90e
--- /dev/null
+++ b/library/msgcat/tests/regexpComp.test
@@ -0,0 +1,992 @@
+# Commands covered: regexp, regsub
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1998 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Procedure to evaluate a script within a proc, to test compilation
+# functionality
+
+proc evalInProc { script } {
+ proc testProc {} $script
+ set status [catch {
+ testProc
+ } result]
+ rename testProc {}
+ return $result
+ #return [list $status $result]
+}
+
+unset -nocomplain foo
+
+test regexpComp-1.1 {basic regexp operation} {
+ evalInProc {
+ regexp ab*c abbbc
+ }
+} 1
+test regexpComp-1.2 {basic regexp operation} {
+ evalInProc {
+ regexp ab*c ac
+ }
+} 1
+test regexpComp-1.3 {basic regexp operation} {
+ evalInProc {
+ regexp ab*c ab
+ }
+} 0
+test regexpComp-1.4 {basic regexp operation} {
+ evalInProc {
+ regexp -- -gorp abc-gorpxxx
+ }
+} 1
+test regexpComp-1.5 {basic regexp operation} {
+ evalInProc {
+ regexp {^([^ ]*)[ ]*([^ ]*)} "" a
+ }
+} 1
+test regexpComp-1.6 {basic regexp operation} {
+ list [catch {regexp {} abc} msg] $msg
+} {0 1}
+test regexpComp-1.7 {regexp utf compliance} {
+ # if not UTF-8 aware, result is "0 1"
+ evalInProc {
+ set foo "\u4e4eb q"
+ regexp "\u4e4eb q" "a\u4e4eb qw\u5e4e\x4e wq" bar
+ list [string compare $foo $bar] [regexp 4 $bar]
+ }
+} {0 0}
+
+test regexpComp-1.8 {regexp ***= metasyntax} {
+ evalInProc {
+ regexp -- "***=o" "aeiou"
+ }
+} 1
+test regexpComp-1.9 {regexp ***= metasyntax} {
+ evalInProc {
+ set string "aeiou"
+ regexp -- "***=o" $string
+ }
+} 1
+test regexpComp-1.10 {regexp ***= metasyntax} {
+ evalInProc {
+ set string "aeiou"
+ set re "***=o"
+ regexp -- $re $string
+ }
+} 1
+test regexpComp-1.11 {regexp ***= metasyntax} {
+ evalInProc {
+ regexp -- "***=y" "aeiou"
+ }
+} 0
+test regexpComp-1.12 {regexp ***= metasyntax} {
+ evalInProc {
+ set string "aeiou"
+ regexp -- "***=y" $string
+ }
+} 0
+test regexpComp-1.13 {regexp ***= metasyntax} {
+ evalInProc {
+ set string "aeiou"
+ set re "***=y"
+ regexp -- $re $string
+ }
+} 0
+test regexpComp-1.14 {regexp ***= metasyntax} {
+ evalInProc {
+ set string "aeiou"
+ set re "***=e*o"
+ regexp -- $re $string
+ }
+} 0
+test regexpComp-1.15 {regexp ***= metasyntax} {
+ evalInProc {
+ set string "ae*ou"
+ set re "***=e*o"
+ regexp -- $re $string
+ }
+} 1
+test regexpComp-1.16 {regexp ***= metasyntax} {
+ evalInProc {
+ set string {ae*[o]?ua}
+ set re {***=e*[o]?u}
+ regexp -- $re $string
+ }
+} 1
+
+test regexpComp-2.1 {getting substrings back from regexp} {
+ evalInProc {
+ set foo {}
+ list [regexp ab*c abbbbc foo] $foo
+ }
+} {1 abbbbc}
+test regexpComp-2.2 {getting substrings back from regexp} {
+ evalInProc {
+ set foo {}
+ set f2 {}
+ list [regexp a(b*)c abbbbc foo f2] $foo $f2
+ }
+} {1 abbbbc bbbb}
+test regexpComp-2.3 {getting substrings back from regexp} {
+ evalInProc {
+ set foo {}
+ set f2 {}
+ list [regexp a(b*)(c) abbbbc foo f2] $foo $f2
+ }
+} {1 abbbbc bbbb}
+test regexpComp-2.4 {getting substrings back from regexp} {
+ evalInProc {
+ set foo {}
+ set f2 {}
+ set f3 {}
+ list [regexp a(b*)(c) abbbbc foo f2 f3] $foo $f2 $f3
+ }
+} {1 abbbbc bbbb c}
+test regexpComp-2.5 {getting substrings back from regexp} {
+ evalInProc {
+ set foo {}; set f1 {}; set f2 {}; set f3 {}; set f4 {}; set f5 {};
+ set f6 {}; set f7 {}; set f8 {}; set f9 {}; set fa {}; set fb {};
+ list [regexp (1*)(2*)(3*)(4*)(5*)(6*)(7*)(8*)(9*)(a*)(b*) \
+ 12223345556789999aabbb \
+ foo f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb] $foo $f1 $f2 $f3 $f4 $f5 \
+ $f6 $f7 $f8 $f9 $fa $fb
+ }
+} {1 12223345556789999aabbb 1 222 33 4 555 6 7 8 9999 aa bbb}
+test regexpComp-2.6 {getting substrings back from regexp} {
+ evalInProc {
+ set foo 2; set f2 2; set f3 2; set f4 2
+ list [regexp (a)(b)? xay foo f2 f3 f4] $foo $f2 $f3 $f4
+ }
+} {1 a a {} {}}
+test regexpComp-2.7 {getting substrings back from regexp} {
+ evalInProc {
+ set foo 1; set f2 1; set f3 1; set f4 1
+ list [regexp (a)(b)?(c) xacy foo f2 f3 f4] $foo $f2 $f3 $f4
+ }
+} {1 ac a {} c}
+test regexpComp-2.8 {getting substrings back from regexp} {
+ evalInProc {
+ set match {}
+ list [regexp {^a*b} aaaab match] $match
+ }
+} {1 aaaab}
+
+test regexpComp-3.1 {-indices option to regexp} {
+ evalInProc {
+ set foo {}
+ list [regexp -indices ab*c abbbbc foo] $foo
+ }
+} {1 {0 5}}
+test regexpComp-3.2 {-indices option to regexp} {
+ evalInProc {
+ set foo {}
+ set f2 {}
+ list [regexp -indices a(b*)c abbbbc foo f2] $foo $f2
+ }
+} {1 {0 5} {1 4}}
+test regexpComp-3.3 {-indices option to regexp} {
+ evalInProc {
+ set foo {}
+ set f2 {}
+ list [regexp -indices a(b*)(c) abbbbc foo f2] $foo $f2
+ }
+} {1 {0 5} {1 4}}
+test regexpComp-3.4 {-indices option to regexp} {
+ evalInProc {
+ set foo {}
+ set f2 {}
+ set f3 {}
+ list [regexp -indices a(b*)(c) abbbbc foo f2 f3] $foo $f2 $f3
+ }
+} {1 {0 5} {1 4} {5 5}}
+test regexpComp-3.5 {-indices option to regexp} {
+ evalInProc {
+ set foo {}; set f1 {}; set f2 {}; set f3 {}; set f4 {}; set f5 {};
+ set f6 {}; set f7 {}; set f8 {}; set f9 {}
+ list [regexp -indices (1*)(2*)(3*)(4*)(5*)(6*)(7*)(8*)(9*) \
+ 12223345556789999 \
+ foo f1 f2 f3 f4 f5 f6 f7 f8 f9] $foo $f1 $f2 $f3 $f4 $f5 \
+ $f6 $f7 $f8 $f9
+ }
+} {1 {0 16} {0 0} {1 3} {4 5} {6 6} {7 9} {10 10} {11 11} {12 12} {13 16}}
+test regexpComp-3.6 {getting substrings back from regexp} {
+ evalInProc {
+ set foo 2; set f2 2; set f3 2; set f4 2
+ list [regexp -indices (a)(b)? xay foo f2 f3 f4] $foo $f2 $f3 $f4
+ }
+} {1 {1 1} {1 1} {-1 -1} {-1 -1}}
+test regexpComp-3.7 {getting substrings back from regexp} {
+ evalInProc {
+ set foo 1; set f2 1; set f3 1; set f4 1
+ list [regexp -indices (a)(b)?(c) xacy foo f2 f3 f4] $foo $f2 $f3 $f4
+ }
+} {1 {1 2} {1 1} {-1 -1} {2 2}}
+
+test regexpComp-4.1 {-nocase option to regexp} {
+ evalInProc {
+ regexp -nocase foo abcFOo
+ }
+} 1
+test regexpComp-4.2 {-nocase option to regexp} {
+ evalInProc {
+ set f1 22
+ set f2 33
+ set f3 44
+ list [regexp -nocase {a(b*)([xy]*)z} aBbbxYXxxZ22 f1 f2 f3] $f1 $f2 $f3
+ }
+} {1 aBbbxYXxxZ Bbb xYXxx}
+test regexpComp-4.3 {-nocase option to regexp} {
+ evalInProc {
+ regexp -nocase FOo abcFOo
+ }
+} 1
+set ::x abcdefghijklmnopqrstuvwxyz1234567890
+set ::x $x$x$x$x$x$x$x$x$x$x$x$x
+test regexpComp-4.4 {case conversion in regexp} {
+ evalInProc {
+ list [regexp -nocase $::x $::x foo] $foo
+ }
+} "1 $x"
+unset -nocomplain ::x
+
+test regexpComp-5.1 {exercise cache of compiled expressions} {
+ evalInProc {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*a bbba
+ }
+} 1
+test regexpComp-5.2 {exercise cache of compiled expressions} {
+ evalInProc {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*b xxxb
+ }
+} 1
+test regexpComp-5.3 {exercise cache of compiled expressions} {
+ evalInProc {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*c yyyc
+ }
+} 1
+test regexpComp-5.4 {exercise cache of compiled expressions} {
+ evalInProc {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*d 1d
+ }
+} 1
+test regexpComp-5.5 {exercise cache of compiled expressions} {
+ evalInProc {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*e xe
+ }
+} 1
+
+test regexpComp-6.1 {regexp errors} {
+ evalInProc {
+ list [catch {regexp a} msg] $msg
+ }
+} {1 {wrong # args: should be "regexp ?-switch ...? exp string ?matchVar? ?subMatchVar ...?"}}
+test regexpComp-6.2 {regexp errors} {
+ evalInProc {
+ list [catch {regexp -nocase a} msg] $msg
+ }
+} {1 {wrong # args: should be "regexp ?-switch ...? exp string ?matchVar? ?subMatchVar ...?"}}
+test regexpComp-6.3 {regexp errors} {
+ evalInProc {
+ list [catch {regexp -gorp a} msg] $msg
+ }
+} {1 {bad switch "-gorp": must be -all, -about, -indices, -inline, -expanded, -line, -linestop, -lineanchor, -nocase, -start, or --}}
+test regexpComp-6.4 {regexp errors} {
+ evalInProc {
+ list [catch {regexp a( b} msg] $msg
+ }
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexpComp-6.5 {regexp errors} {
+ evalInProc {
+ list [catch {regexp a( b} msg] $msg
+ }
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexpComp-6.6 {regexp errors} {
+ evalInProc {
+ list [catch {regexp a a f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1} msg] $msg
+ }
+} {0 1}
+test regexpComp-6.7 {regexp errors} {
+ evalInProc {
+ list [catch {regexp (x)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.) xyzzy} msg] $msg
+ }
+} {0 0}
+test regexpComp-6.8 {regexp errors} {
+ evalInProc {
+ unset -nocomplain f1
+ set f1 44
+ list [catch {regexp abc abc f1(f2)} msg] $msg
+ }
+} {1 {can't set "f1(f2)": variable isn't array}}
+test regexpComp-6.9 {regexp errors, -start bad int check} {
+ evalInProc {
+ list [catch {regexp -start bogus {^$} {}} msg] $msg
+ }
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
+
+test regexpComp-7.1 {basic regsub operation} {
+ evalInProc {
+ list [regsub aa+ xaxaaaxaa 111&222 foo] $foo
+ }
+} {1 xax111aaa222xaa}
+test regexpComp-7.2 {basic regsub operation} {
+ evalInProc {
+ list [regsub aa+ aaaxaa &111 foo] $foo
+ }
+} {1 aaa111xaa}
+test regexpComp-7.3 {basic regsub operation} {
+ evalInProc {
+ list [regsub aa+ xaxaaa 111& foo] $foo
+ }
+} {1 xax111aaa}
+test regexpComp-7.4 {basic regsub operation} {
+ evalInProc {
+ list [regsub aa+ aaa 11&2&333 foo] $foo
+ }
+} {1 11aaa2aaa333}
+test regexpComp-7.5 {basic regsub operation} {
+ evalInProc {
+ list [regsub aa+ xaxaaaxaa &2&333 foo] $foo
+ }
+} {1 xaxaaa2aaa333xaa}
+test regexpComp-7.6 {basic regsub operation} {
+ evalInProc {
+ list [regsub aa+ xaxaaaxaa 1&22& foo] $foo
+ }
+} {1 xax1aaa22aaaxaa}
+test regexpComp-7.7 {basic regsub operation} {
+ evalInProc {
+ list [regsub a(a+) xaxaaaxaa {1\122\1} foo] $foo
+ }
+} {1 xax1aa22aaxaa}
+test regexpComp-7.8 {basic regsub operation} {
+ evalInProc {
+ list [regsub a(a+) xaxaaaxaa {1\\\122\1} foo] $foo
+ }
+} "1 {xax1\\aa22aaxaa}"
+test regexpComp-7.9 {basic regsub operation} {
+ evalInProc {
+ list [regsub a(a+) xaxaaaxaa {1\\122\1} foo] $foo
+ }
+} "1 {xax1\\122aaxaa}"
+test regexpComp-7.10 {basic regsub operation} {
+ evalInProc {
+ list [regsub a(a+) xaxaaaxaa {1\\&\1} foo] $foo
+ }
+} "1 {xax1\\aaaaaxaa}"
+test regexpComp-7.11 {basic regsub operation} {
+ evalInProc {
+ list [regsub a(a+) xaxaaaxaa {1\&\1} foo] $foo
+ }
+} {1 xax1&aaxaa}
+test regexpComp-7.12 {basic regsub operation} {
+ evalInProc {
+ list [regsub a(a+) xaxaaaxaa {\1\1\1\1&&} foo] $foo
+ }
+} {1 xaxaaaaaaaaaaaaaaxaa}
+test regexpComp-7.13 {basic regsub operation} {
+ evalInProc {
+ set foo xxx
+ list [regsub abc xyz 111 foo] $foo
+ }
+} {0 xyz}
+test regexpComp-7.14 {basic regsub operation} {
+ evalInProc {
+ set foo xxx
+ list [regsub ^ xyz "111 " foo] $foo
+ }
+} {1 {111 xyz}}
+test regexpComp-7.15 {basic regsub operation} {
+ evalInProc {
+ set foo xxx
+ list [regsub -- -foo abc-foodef "111 " foo] $foo
+ }
+} {1 {abc111 def}}
+test regexpComp-7.16 {basic regsub operation} {
+ evalInProc {
+ set foo xxx
+ list [regsub x "" y foo] $foo
+ }
+} {0 {}}
+test regexpComp-7.17 {regsub utf compliance} {
+ evalInProc {
+ # if not UTF-8 aware, result is "0 1"
+ set foo "xyz555ijka\u4e4ebpqr"
+ regsub a\u4e4eb xyza\u4e4ebijka\u4e4ebpqr 555 bar
+ list [string compare $foo $bar] [regexp 4 $bar]
+ }
+} {0 0}
+
+test regexpComp-8.1 {case conversion in regsub} {
+ evalInProc {
+ list [regsub -nocase a(a+) xaAAaAAay & foo] $foo
+ }
+} {1 xaAAaAAay}
+test regexpComp-8.2 {case conversion in regsub} {
+ evalInProc {
+ list [regsub -nocase a(a+) xaAAaAAay & foo] $foo
+ }
+} {1 xaAAaAAay}
+test regexpComp-8.3 {case conversion in regsub} {
+ evalInProc {
+ set foo 123
+ list [regsub a(a+) xaAAaAAay & foo] $foo
+ }
+} {0 xaAAaAAay}
+test regexpComp-8.4 {case conversion in regsub} {
+ evalInProc {
+ set foo 123
+ list [regsub -nocase a CaDE b foo] $foo
+ }
+} {1 CbDE}
+test regexpComp-8.5 {case conversion in regsub} {
+ evalInProc {
+ set foo 123
+ list [regsub -nocase XYZ CxYzD b foo] $foo
+ }
+} {1 CbD}
+test regexpComp-8.6 {case conversion in regsub} {
+ evalInProc {
+ set x abcdefghijklmnopqrstuvwxyz1234567890
+ set x $x$x$x$x$x$x$x$x$x$x$x$x
+ set foo 123
+ list [regsub -nocase $x $x b foo] $foo
+ }
+} {1 b}
+
+test regexpComp-9.1 {-all option to regsub} {
+ evalInProc {
+ set foo 86
+ list [regsub -all x+ axxxbxxcxdx |&| foo] $foo
+ }
+} {4 a|xxx|b|xx|c|x|d|x|}
+test regexpComp-9.2 {-all option to regsub} {
+ evalInProc {
+ set foo 86
+ list [regsub -nocase -all x+ aXxXbxxcXdx |&| foo] $foo
+ }
+} {4 a|XxX|b|xx|c|X|d|x|}
+test regexpComp-9.3 {-all option to regsub} {
+ evalInProc {
+ set foo 86
+ list [regsub x+ axxxbxxcxdx |&| foo] $foo
+ }
+} {1 a|xxx|bxxcxdx}
+test regexpComp-9.4 {-all option to regsub} {
+ evalInProc {
+ set foo 86
+ list [regsub -all bc axxxbxxcxdx |&| foo] $foo
+ }
+} {0 axxxbxxcxdx}
+test regexpComp-9.5 {-all option to regsub} {
+ evalInProc {
+ set foo xxx
+ list [regsub -all node "node node more" yy foo] $foo
+ }
+} {2 {yy yy more}}
+test regexpComp-9.6 {-all option to regsub} {
+ evalInProc {
+ set foo xxx
+ list [regsub -all ^ xxx 123 foo] $foo
+ }
+} {1 123xxx}
+
+test regexpComp-10.1 {expanded syntax in regsub} {
+ evalInProc {
+ set foo xxx
+ list [regsub -expanded ". \#comment\n . \#comment2" abc def foo] $foo
+ }
+} {1 defc}
+test regexpComp-10.2 {newline sensitivity in regsub} {
+ evalInProc {
+ set foo xxx
+ list [regsub -line {^a.*b$} "dabc\naxyb\n" 123 foo] $foo
+ }
+} "1 {dabc\n123\n}"
+test regexpComp-10.3 {newline sensitivity in regsub} {
+ evalInProc {
+ set foo xxx
+ list [regsub -line {^a.*b$} "dabc\naxyb\nxb" 123 foo] $foo
+ }
+} "1 {dabc\n123\nxb}"
+test regexpComp-10.4 {partial newline sensitivity in regsub} {
+ evalInProc {
+ set foo xxx
+ list [regsub -lineanchor {^a.*b$} "da\naxyb\nxb" 123 foo] $foo
+ }
+} "1 {da\n123}"
+test regexpComp-10.5 {inverse partial newline sensitivity in regsub} {
+ evalInProc {
+ set foo xxx
+ list [regsub -linestop {a.*b} "da\nbaxyb\nxb" 123 foo] $foo
+ }
+} "1 {da\nb123\nxb}"
+
+test regexpComp-11.1 {regsub errors} {
+ evalInProc {
+ list [catch {regsub a b} msg] $msg
+ }
+} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}}
+test regexpComp-11.2 {regsub errors} {
+ evalInProc {
+ list [catch {regsub -nocase a b} msg] $msg
+ }
+} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}}
+test regexpComp-11.3 {regsub errors} {
+ evalInProc {
+ list [catch {regsub -nocase -all a b} msg] $msg
+ }
+} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}}
+test regexpComp-11.4 {regsub errors} {
+ evalInProc {
+ list [catch {regsub a b c d e f} msg] $msg
+ }
+} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}}
+test regexpComp-11.5 {regsub errors} {
+ evalInProc {
+ list [catch {regsub -gorp a b c} msg] $msg
+ }
+} {1 {bad switch "-gorp": must be -all, -nocase, -expanded, -line, -linestop, -lineanchor, -start, or --}}
+test regexpComp-11.6 {regsub errors} {
+ evalInProc {
+ list [catch {regsub -nocase a( b c d} msg] $msg
+ }
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexpComp-11.7 {regsub errors} {
+ evalInProc {
+ unset -nocomplain f1
+ set f1 44
+ list [catch {regsub -nocase aaa aaa xxx f1(f2)} msg] $msg
+ }
+} {1 {can't set "f1(f2)": variable isn't array}}
+test regexpComp-11.8 {regsub errors, -start bad int check} {
+ evalInProc {
+ list [catch {regsub -start bogus pattern string rep var} msg] $msg
+ }
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
+
+# This test crashes on the Mac unless you increase the Stack Space to about 1
+# Meg. This is probably bigger than most users want...
+# 8.2.3 regexp reduced stack space requirements, but this should be
+# tested again
+test regexpComp-12.1 {Tcl_RegExpExec: large number of subexpressions} {macCrash} {
+ evalInProc {
+ list [regexp (.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.) abcdefghijklmnopqrstuvwxyz all a b c d e f g h i j k l m n o p q r s t u v w x y z] $all $a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z
+ }
+} {1 abcdefghijklmnopqrstuvwxyz a b c d e f g h i j k l m n o p q r s t u v w x y z}
+
+test regexpComp-13.1 {regsub of a very large string} {
+ # This test is designed to stress the memory subsystem in order
+ # to catch Bug #933. It only fails if the Tcl memory allocator
+ # is in use.
+
+ set line {BEGIN_TABLE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; END_TABLE}
+ set filedata [string repeat $line 200]
+ for {set i 1} {$i<10} {incr i} {
+ regsub -all "BEGIN_TABLE " $filedata "" newfiledata
+ }
+ set x done
+} {done}
+
+test regexpComp-14.1 {CompileRegexp: regexp cache} {
+ evalInProc {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ set x .
+ append x *a
+ regexp $x bbba
+ }
+} 1
+test regexpComp-14.2 {CompileRegexp: regexp cache, different flags} {
+ evalInProc {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ set x .
+ append x *a
+ regexp -nocase $x bbba
+ }
+} 1
+
+testConstraint exec [llength [info commands exec]]
+test regexpComp-14.3 {CompileRegexp: regexp cache, empty regexp and empty cache} -constraints {
+ exec
+} -setup {
+ set junk [makeFile {puts [regexp {} foo]} junk.tcl]
+} -body {
+ exec [interpreter] $junk
+} -cleanup {
+ removeFile junk.tcl
+} -result 1
+
+test regexpComp-15.1 {regexp -start} {
+ unset -nocomplain x
+ list [regexp -start -10 {\d} 1abc2de3 x] $x
+} {1 1}
+test regexpComp-15.2 {regexp -start} {
+ unset -nocomplain x
+ list [regexp -start 2 {\d} 1abc2de3 x] $x
+} {1 2}
+test regexpComp-15.3 {regexp -start} {
+ unset -nocomplain x
+ list [regexp -start 4 {\d} 1abc2de3 x] $x
+} {1 2}
+test regexpComp-15.4 {regexp -start} {
+ unset -nocomplain x
+ list [regexp -start 5 {\d} 1abc2de3 x] $x
+} {1 3}
+test regexpComp-15.5 {regexp -start, over end of string} {
+ unset -nocomplain x
+ list [regexp -start [string length 1abc2de3] {\d} 1abc2de3 x] [info exists x]
+} {0 0}
+test regexpComp-15.6 {regexp -start, loss of ^$ behavior} {
+ list [regexp -start 2 {^$} {}]
+} {0}
+
+test regexpComp-16.1 {regsub -start} {
+ unset -nocomplain x
+ list [regsub -all -start 2 {\d} a1b2c3d4e5 {/&} x] $x
+} {4 a1b/2c/3d/4e/5}
+test regexpComp-16.2 {regsub -start} {
+ unset -nocomplain x
+ list [regsub -all -start -25 {z} hello {/&} x] $x
+} {0 hello}
+test regexpComp-16.3 {regsub -start} {
+ unset -nocomplain x
+ list [regsub -all -start 3 {z} hello {/&} x] $x
+} {0 hello}
+test regexpComp-16.4 {regsub -start, \A behavior} {
+ set out {}
+ lappend out [regsub -start 0 -all {\A(\w)} {abcde} {/\1} x] $x
+ lappend out [regsub -start 2 -all {\A(\w)} {abcde} {/\1} x] $x
+} {5 /a/b/c/d/e 3 ab/c/d/e}
+
+test regexpComp-17.1 {regexp -inline} {
+ regexp -inline b ababa
+} {b}
+test regexpComp-17.2 {regexp -inline} {
+ regexp -inline (b) ababa
+} {b b}
+test regexpComp-17.3 {regexp -inline -indices} {
+ regexp -inline -indices (b) ababa
+} {{1 1} {1 1}}
+test regexpComp-17.4 {regexp -inline} {
+ regexp -inline {\w(\d+)\w} " hello 23 there456def "
+} {e456d 456}
+test regexpComp-17.5 {regexp -inline no matches} {
+ regexp -inline {\w(\d+)\w} ""
+} {}
+test regexpComp-17.6 {regexp -inline no matches} {
+ regexp -inline hello goodbye
+} {}
+test regexpComp-17.7 {regexp -inline, no matchvars allowed} {
+ list [catch {regexp -inline b abc match} msg] $msg
+} {1 {regexp match variables not allowed when using -inline}}
+
+test regexpComp-18.1 {regexp -all} {
+ regexp -all b bbbbb
+} {5}
+test regexpComp-18.2 {regexp -all} {
+ regexp -all b abababbabaaaaaaaaaab
+} {6}
+test regexpComp-18.3 {regexp -all -inline} {
+ regexp -all -inline b abababbabaaaaaaaaaab
+} {b b b b b b}
+test regexpComp-18.4 {regexp -all -inline} {
+ regexp -all -inline {\w(\w)} abcdefg
+} {ab b cd d ef f}
+test regexpComp-18.5 {regexp -all -inline} {
+ regexp -all -inline {\w(\w)$} abcdefg
+} {fg g}
+test regexpComp-18.6 {regexp -all -inline} {
+ regexp -all -inline {\d+} 10:20:30:40
+} {10 20 30 40}
+test regexpComp-18.7 {regexp -all -inline} {
+ list [catch {regexp -all -inline b abc match} msg] $msg
+} {1 {regexp match variables not allowed when using -inline}}
+test regexpComp-18.8 {regexp -all} {
+ # This should not cause an infinite loop
+ regexp -all -inline {a*} a
+} {a}
+test regexpComp-18.9 {regexp -all} {
+ # Yes, the expected result is {a {}}. Here's why:
+ # Start at index 0; a* matches the "a" there then stops.
+ # Go to index 1; a* matches the lambda (or {}) there then stops. Recall
+ # that a* matches zero or more "a"'s; thus it matches the string "b", as
+ # there are zero or more "a"'s there.
+ # Go to index 2; this is past the end of the string, so stop.
+ regexp -all -inline {a*} ab
+} {a {}}
+test regexpComp-18.10 {regexp -all} {
+ # Yes, the expected result is {a {} a}. Here's why:
+ # Start at index 0; a* matches the "a" there then stops.
+ # Go to index 1; a* matches the lambda (or {}) there then stops. Recall
+ # that a* matches zero or more "a"'s; thus it matches the string "b", as
+ # there are zero or more "a"'s there.
+ # Go to index 2; a* matches the "a" there then stops.
+ # Go to index 3; this is past the end of the string, so stop.
+ regexp -all -inline {a*} aba
+} {a {} a}
+test regexpComp-18.11 {regexp -all} {
+ evalInProc {
+ regexp -all -inline {^a} aaaa
+ }
+} {a}
+test regexpComp-18.12 {regexp -all -inline -indices} {
+ evalInProc {
+ regexp -all -inline -indices a(b(c)d|e(f)g)h abcdhaefgh
+ }
+} {{0 4} {1 3} {2 2} {-1 -1} {5 9} {6 8} {-1 -1} {7 7}}
+
+test regexpComp-19.1 {regsub null replacement} {
+ evalInProc {
+ regsub -all {@} {@hel@lo@} "\0a\0" result
+ list $result [string length $result]
+ }
+} "\0a\0hel\0a\0lo\0a\0 14"
+
+test regexpComp-20.1 {regsub shared object shimmering} {
+ evalInProc {
+ # Bug #461322
+ set a abcdefghijklmnopqurstuvwxyz
+ set b $a
+ set c abcdefghijklmnopqurstuvwxyz0123456789
+ regsub $a $c $b d
+ list $d [string length $d] [string bytelength $d]
+ }
+} [list abcdefghijklmnopqurstuvwxyz0123456789 37 37]
+test regexpComp-20.2 {regsub shared object shimmering with -about} {
+ evalInProc {
+ eval regexp -about abc
+ }
+} {0 {}}
+
+test regexpComp-21.1 {regexp command compiling tests} {
+ evalInProc {
+ regexp foo bar
+ }
+} 0
+test regexpComp-21.2 {regexp command compiling tests} {
+ evalInProc {
+ regexp {^foo$} dogfood
+ }
+} 0
+test regexpComp-21.3 {regexp command compiling tests} {
+ evalInProc {
+ set a foo
+ regexp {^foo$} $a
+ }
+} 1
+test regexpComp-21.4 {regexp command compiling tests} {
+ evalInProc {
+ regexp foo dogfood
+ }
+} 1
+test regexpComp-21.5 {regexp command compiling tests} {
+ evalInProc {
+ regexp -nocase FOO dogfod
+ }
+} 0
+test regexpComp-21.6 {regexp command compiling tests} {
+ evalInProc {
+ regexp -n foo dogfoOd
+ }
+} 1
+test regexpComp-21.7 {regexp command compiling tests} {
+ evalInProc {
+ regexp -no -- FoO dogfood
+ }
+} 1
+test regexpComp-21.8 {regexp command compiling tests} {
+ evalInProc {
+ regexp -- foo dogfod
+ }
+} 0
+test regexpComp-21.9 {regexp command compiling tests} {
+ evalInProc {
+ list [catch {regexp -- -nocase foo dogfod} msg] $msg
+ }
+} {0 0}
+test regexpComp-21.10 {regexp command compiling tests} {
+ evalInProc {
+ list [regsub -all "" foo bar str] $str
+ }
+} {3 barfbarobaro}
+test regexpComp-21.11 {regexp command compiling tests} {
+ evalInProc {
+ list [regsub -all "" "" bar str] $str
+ }
+} {0 {}}
+
+test regexpComp-22.0.1 {Bug 1810038} {
+ evalInProc {
+ regexp ($|^X)* {}
+ }
+} 1
+
+test regexpComp-22.0.2 {regexp compile and backrefs, Bug 1857126} {
+ evalInProc {
+ regexp -- {([bc])\1} bb
+ }
+} 1
+
+set i 0
+foreach {str exp result} {
+ foo ^foo 1
+ foobar ^foobar$ 1
+ foobar bar$ 1
+ foobar ^$ 0
+ "" ^$ 1
+ anything $ 1
+ anything ^.*$ 1
+ anything ^.*a$ 0
+ anything ^.*a.*$ 1
+ anything ^.*.*$ 1
+ anything ^.*..*$ 1
+ anything ^.*b$ 0
+ anything ^a.*$ 1
+} {
+ test regexpComp-22.[incr i] {regexp command compiling tests} \
+ [subst {evalInProc {set a "$str"; regexp {$exp} \$a}}] $result
+}
+
+set i 0
+foreach {str exp result} {
+ foo ^foo 1
+ foobar ^foobar$ 1
+ foobar bar$ 1
+ foobar ^$ 0
+ "" ^$ 1
+ anything $ 1
+ anything ^.*$ 1
+ anything ^.*a$ 0
+ anything ^.*a.*$ 1
+ anything ^.*.*$ 1
+ anything ^.*..*$ 1
+ anything ^.*b$ 0
+ anything ^a.*$ 1
+} {
+ test regexpComp-23.[incr i] {regexp command compiling tests INST_REGEXP} \
+ [subst {evalInProc {set a "$str"; set re "$exp"; regexp \$re \$a}}] $result
+}
+
+test regexpComp-24.1 {regexp command compiling tests} {
+ evalInProc {
+ set re foo
+ regexp -nocase $re bar
+ }
+} 0
+test regexpComp-24.2 {regexp command compiling tests} {
+ evalInProc {
+ set re {^foo$}
+ regexp $re dogfood
+ }
+} 0
+test regexpComp-24.3 {regexp command compiling tests} {
+ evalInProc {
+ set a foo
+ set re {^foo$}
+ regexp $re $a
+ }
+} 1
+test regexpComp-24.4 {regexp command compiling tests} {
+ evalInProc {
+ set re foo
+ regexp $re dogfood
+ }
+} 1
+test regexpComp-24.5 {regexp command compiling tests} {
+ evalInProc {
+ set re FOO
+ regexp -nocase $re dogfod
+ }
+} 0
+test regexpComp-24.6 {regexp command compiling tests} {
+ evalInProc {
+ set re foo
+ regexp -n $re dogfoOd
+ }
+} 1
+test regexpComp-24.7 {regexp command compiling tests} {
+ evalInProc {
+ set re FoO
+ regexp -no -- $re dogfood
+ }
+} 1
+test regexpComp-24.8 {regexp command compiling tests} {
+ evalInProc {
+ set re foo
+ regexp -- $re dogfod
+ }
+} 0
+test regexpComp-24.9 {regexp command compiling tests} {
+ evalInProc {
+ set re "("
+ list [catch {regexp -- $re dogfod} msg] $msg
+ }
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexpComp-24.10 {regexp command compiling tests} {
+ # Bug 1902436 - last * escaped
+ evalInProc {
+ set text {this is *bold* !}
+ set re {\*bold\*}
+ regexp -- $re $text
+ }
+} 1
+test regexpComp-24.11 {regexp command compiling tests} {
+ # Bug 1902436 - last * escaped
+ evalInProc {
+ set text {this is *bold* !}
+ set re {\*bold\*.*!}
+ regexp -- $re $text
+ }
+} 1
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/registry.test b/library/msgcat/tests/registry.test
new file mode 100644
index 0000000..400277f
--- /dev/null
+++ b/library/msgcat/tests/registry.test
@@ -0,0 +1,691 @@
+# registry.test --
+#
+# This file contains a collection of tests for the registry command.
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# In order for these tests to run, the registry package must be on the
+# auto_path or the registry package must have been loaded already.
+#
+# Copyright (c) 1997 by Sun Microsystems, Inc. All rights reserved.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint reg 0
+if {[testConstraint win]} {
+ catch {
+ # Is the registry extension already static to this shell?
+ if [catch {load {} Registry; set ::reglib {}}] {
+ # try the location given to use on the commandline to tcltest
+ ::tcltest::loadTestedCommands
+ load $::reglib Registry
+ }
+ testConstraint reg 1
+ }
+}
+
+# determine the current locale
+testConstraint english [expr {
+ [llength [info commands testlocale]]
+ && [string match "English*" [testlocale all ""]]
+}]
+
+test registry-1.1 {argument parsing for registry command} {win reg} {
+ list [catch {registry} msg] $msg
+} {1 {wrong # args: should be "registry ?-32bit|-64bit? option ?arg ...?"}}
+test registry-1.1a {argument parsing for registry command} {win reg} {
+ list [catch {registry -32bit} msg] $msg
+} {1 {wrong # args: should be "registry ?-32bit|-64bit? option ?arg ...?"}}
+test registry-1.1b {argument parsing for registry command} {win reg} {
+ list [catch {registry -64bit} msg] $msg
+} {1 {wrong # args: should be "registry ?-32bit|-64bit? option ?arg ...?"}}
+test registry-1.2 {argument parsing for registry command} {win reg} {
+ list [catch {registry foo} msg] $msg
+} {1 {bad option "foo": must be broadcast, delete, get, keys, set, type, or values}}
+test registry-1.2a {argument parsing for registry command} {win reg} {
+ list [catch {registry -33bit foo} msg] $msg
+} {1 {bad mode "-33bit": must be -32bit or -64bit}}
+
+test registry-1.3 {argument parsing for registry command} {win reg} {
+ list [catch {registry d} msg] $msg
+} {1 {wrong # args: should be "registry delete keyName ?valueName?"}}
+test registry-1.3a {argument parsing for registry command} {win reg} {
+ list [catch {registry -32bit d} msg] $msg
+} {1 {wrong # args: should be "registry -32bit delete keyName ?valueName?"}}
+test registry-1.3b {argument parsing for registry command} {win reg} {
+ list [catch {registry -64bit d} msg] $msg
+} {1 {wrong # args: should be "registry -64bit delete keyName ?valueName?"}}
+test registry-1.4 {argument parsing for registry command} {win reg} {
+ list [catch {registry delete} msg] $msg
+} {1 {wrong # args: should be "registry delete keyName ?valueName?"}}
+test registry-1.5 {argument parsing for registry command} {win reg} {
+ list [catch {registry delete foo bar baz} msg] $msg
+} {1 {wrong # args: should be "registry delete keyName ?valueName?"}}
+
+test registry-1.6 {argument parsing for registry command} {win reg} {
+ list [catch {registry g} msg] $msg
+} {1 {wrong # args: should be "registry get keyName valueName"}}
+test registry-1.6a {argument parsing for registry command} {win reg} {
+ list [catch {registry -32bit g} msg] $msg
+} {1 {wrong # args: should be "registry -32bit get keyName valueName"}}
+test registry-1.6b {argument parsing for registry command} {win reg} {
+ list [catch {registry -64bit g} msg] $msg
+} {1 {wrong # args: should be "registry -64bit get keyName valueName"}}
+test registry-1.7 {argument parsing for registry command} {win reg} {
+ list [catch {registry get} msg] $msg
+} {1 {wrong # args: should be "registry get keyName valueName"}}
+test registry-1.8 {argument parsing for registry command} {win reg} {
+ list [catch {registry get foo} msg] $msg
+} {1 {wrong # args: should be "registry get keyName valueName"}}
+test registry-1.9 {argument parsing for registry command} {win reg} {
+ list [catch {registry get foo bar baz} msg] $msg
+} {1 {wrong # args: should be "registry get keyName valueName"}}
+
+test registry-1.10 {argument parsing for registry command} {win reg} {
+ list [catch {registry k} msg] $msg
+} {1 {wrong # args: should be "registry keys keyName ?pattern?"}}
+test registry-1.10a {argument parsing for registry command} {win reg} {
+ list [catch {registry -32bit k} msg] $msg
+} {1 {wrong # args: should be "registry -32bit keys keyName ?pattern?"}}
+test registry-1.10b {argument parsing for registry command} {win reg} {
+ list [catch {registry -64bit k} msg] $msg
+} {1 {wrong # args: should be "registry -64bit keys keyName ?pattern?"}}
+test registry-1.11 {argument parsing for registry command} {win reg} {
+ list [catch {registry keys} msg] $msg
+} {1 {wrong # args: should be "registry keys keyName ?pattern?"}}
+test registry-1.12 {argument parsing for registry command} {win reg} {
+ list [catch {registry keys foo bar baz} msg] $msg
+} {1 {wrong # args: should be "registry keys keyName ?pattern?"}}
+
+test registry-1.13 {argument parsing for registry command} {win reg} {
+ list [catch {registry s} msg] $msg
+} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
+test registry-1.13a {argument parsing for registry command} {win reg} {
+ list [catch {registry -32bit s} msg] $msg
+} {1 {wrong # args: should be "registry -32bit set keyName ?valueName data ?type??"}}
+test registry-1.13b {argument parsing for registry command} {win reg} {
+ list [catch {registry -64bit s} msg] $msg
+} {1 {wrong # args: should be "registry -64bit set keyName ?valueName data ?type??"}}
+test registry-1.14 {argument parsing for registry command} {win reg} {
+ list [catch {registry set} msg] $msg
+} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
+test registry-1.15 {argument parsing for registry command} {win reg} {
+ list [catch {registry set foo bar} msg] $msg
+} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
+test registry-1.16 {argument parsing for registry command} {win reg} {
+ list [catch {registry set foo bar baz blat gorp} msg] $msg
+} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
+
+test registry-1.17 {argument parsing for registry command} {win reg} {
+ list [catch {registry t} msg] $msg
+} {1 {wrong # args: should be "registry type keyName valueName"}}
+test registry-1.17a {argument parsing for registry command} {win reg} {
+ list [catch {registry -32bit t} msg] $msg
+} {1 {wrong # args: should be "registry -32bit type keyName valueName"}}
+test registry-1.17b {argument parsing for registry command} {win reg} {
+ list [catch {registry -64bit t} msg] $msg
+} {1 {wrong # args: should be "registry -64bit type keyName valueName"}}
+test registry-1.18 {argument parsing for registry command} {win reg} {
+ list [catch {registry type} msg] $msg
+} {1 {wrong # args: should be "registry type keyName valueName"}}
+test registry-1.19 {argument parsing for registry command} {win reg} {
+ list [catch {registry type foo} msg] $msg
+} {1 {wrong # args: should be "registry type keyName valueName"}}
+test registry-1.20 {argument parsing for registry command} {win reg} {
+ list [catch {registry type foo bar baz} msg] $msg
+} {1 {wrong # args: should be "registry type keyName valueName"}}
+
+test registry-1.21 {argument parsing for registry command} {win reg} {
+ list [catch {registry v} msg] $msg
+} {1 {wrong # args: should be "registry values keyName ?pattern?"}}
+test registry-1.21a {argument parsing for registry command} {win reg} {
+ list [catch {registry -32bit v} msg] $msg
+} {1 {wrong # args: should be "registry -32bit values keyName ?pattern?"}}
+test registry-1.21b {argument parsing for registry command} {win reg} {
+ list [catch {registry -64bit v} msg] $msg
+} {1 {wrong # args: should be "registry -64bit values keyName ?pattern?"}}
+test registry-1.22 {argument parsing for registry command} {win reg} {
+ list [catch {registry values} msg] $msg
+} {1 {wrong # args: should be "registry values keyName ?pattern?"}}
+test registry-1.23 {argument parsing for registry command} {win reg} {
+ list [catch {registry values foo bar baz} msg] $msg
+} {1 {wrong # args: should be "registry values keyName ?pattern?"}}
+
+test registry-2.1 {DeleteKey: bad key} {win reg} {
+ list [catch {registry delete foo} msg] $msg
+} {1 {bad root name "foo": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}}
+test registry-2.2 {DeleteKey: bad key} {win reg} {
+ list [catch {registry delete HKEY_CLASSES_ROOT} msg] $msg
+} {1 {bad key: cannot delete root keys}}
+test registry-2.3 {DeleteKey: bad key} {win reg} {
+ list [catch {registry delete HKEY_CLASSES_ROOT\\} msg] $msg
+} {1 {bad key: cannot delete root keys}}
+test registry-2.4 {DeleteKey: subkey at root level} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry keys HKEY_CURRENT_USER TclFoobar
+} {}
+test registry-2.5 {DeleteKey: subkey below root level} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test
+ registry delete HKEY_CURRENT_USER\\TclFoobar\\test
+ set result [registry keys HKEY_CURRENT_USER TclFoobar\\test]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {}
+test registry-2.6 {DeleteKey: recursive delete} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test1
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test2\\test3
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result [registry keys HKEY_CURRENT_USER TclFoobar]
+ set result
+} {}
+test registry-2.7 {DeleteKey: trailing backslashes} {win reg english} {
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz
+ list [catch {registry delete HKEY_CURRENT_USER\\TclFoobar\\} msg] $msg
+} {1 {unable to delete key: The configuration registry key is invalid.}}
+test registry-2.8 {DeleteKey: failure} {win reg} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} {}
+test registry-2.9 {DeleteKey: unicode} {win reg} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test\u00c7bar\\a
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test\u00c7bar\\b
+ registry delete HKEY_CURRENT_USER\\TclFoobar\\test\u00c7bar
+ set result [registry keys HKEY_CURRENT_USER\\TclFoobar]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {}
+
+test registry-3.1 {DeleteValue} {win reg} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz test1 blort
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz test2 blat
+ registry delete HKEY_CURRENT_USER\\TclFoobar\\baz test1
+ set result [registry values HKEY_CURRENT_USER\\TclFoobar\\baz]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} test2
+test registry-3.2 {DeleteValue: bad key} {win reg english} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ list [catch {registry delete HKEY_CURRENT_USER\\TclFoobar test} msg] $msg
+} {1 {unable to open key: The system cannot find the file specified.}}
+test registry-3.3 {DeleteValue: bad value} {win reg english} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz test2 blort
+ set result [list [catch {registry delete HKEY_CURRENT_USER\\TclFoobar test1} msg] $msg]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {1 {unable to delete value "test1" from key "HKEY_CURRENT_USER\TclFoobar": The system cannot find the file specified.}}
+test registry-3.4 {DeleteValue: Unicode} {win reg} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\\u00c7baz \u00c7test1 blort
+ registry set HKEY_CURRENT_USER\\TclFoobar\\\u00c7baz test2 blat
+ registry delete HKEY_CURRENT_USER\\TclFoobar\\\u00c7baz \u00c7test1
+ set result [registry values HKEY_CURRENT_USER\\TclFoobar\\\u00c7baz]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} test2
+
+test registry-4.1 {GetKeyNames: bad key} {win reg english} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ list [catch {registry keys HKEY_CURRENT_USER\\TclFoobar} msg] $msg
+} {1 {unable to open key: The system cannot find the file specified.}}
+test registry-4.2 {GetKeyNames} {win reg} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz
+ set result [registry keys HKEY_CURRENT_USER\\TclFoobar]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {baz}
+test registry-4.3 {GetKeyNames: remote key} {win reg nonPortable english} {
+ set hostname [info hostname]
+ registry set \\\\$hostname\\HKEY_CURRENT_USER\\TclFoobar\\baz
+ set result [registry keys \\\\gaspode\\HKEY_CURRENT_USER\\TclFoobar]
+ registry delete \\\\$hostname\\HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {baz}
+test registry-4.4 {GetKeyNames: empty key} {win reg} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar
+ set result [registry keys HKEY_CURRENT_USER\\TclFoobar]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {}
+test registry-4.5 {GetKeyNames: patterns} {win reg} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz
+ registry set HKEY_CURRENT_USER\\TclFoobar\\blat
+ registry set HKEY_CURRENT_USER\\TclFoobar\\foo
+ set result [lsort [registry keys HKEY_CURRENT_USER\\TclFoobar b*]]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {baz blat}
+test registry-4.6 {GetKeyNames: names with spaces} {win reg} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz\ bar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\blat
+ registry set HKEY_CURRENT_USER\\TclFoobar\\foo
+ set result [lsort [registry keys HKEY_CURRENT_USER\\TclFoobar b*]]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {{baz bar} blat}
+test registry-4.7 {GetKeyNames: Unicode} {win reg english} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz\u00c7bar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\blat
+ registry set HKEY_CURRENT_USER\\TclFoobar\\foo
+ set result [lsort [registry keys HKEY_CURRENT_USER\\TclFoobar b*]]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} "baz\u00c7bar blat"
+test registry-4.8 {GetKeyNames: Unicode} {win reg nt} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz\u30b7bar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\blat
+ registry set HKEY_CURRENT_USER\\TclFoobar\\foo
+ set result [lsort [registry keys HKEY_CURRENT_USER\\TclFoobar b*]]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} "baz\u30b7bar blat"
+test registry-4.9 {GetKeyNames: very long key [Bug 1682211]} {*}{
+ -constraints {win reg}
+ -setup {
+ registry set HKEY_CURRENT_USER\\TclFoobar\\a
+ registry set HKEY_CURRENT_USER\\TclFoobar\\b[string repeat x 254]
+ registry set HKEY_CURRENT_USER\\TclFoobar\\c
+ }
+ -body {
+ lsort [registry keys HKEY_CURRENT_USER\\TclFoobar]
+ }
+ -cleanup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ }} \
+ -result [list a b[string repeat x 254] c]
+
+test registry-5.1 {GetType} {win reg english} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ list [catch {registry type HKEY_CURRENT_USER\\TclFoobar val1} msg] $msg
+} {1 {unable to open key: The system cannot find the file specified.}}
+test registry-5.2 {GetType} {win reg english} {
+ registry set HKEY_CURRENT_USER\\TclFoobar
+ list [catch {registry type HKEY_CURRENT_USER\\TclFoobar val1} msg] $msg
+} {1 {unable to get type of value "val1" from key "HKEY_CURRENT_USER\TclFoobar": The system cannot find the file specified.}}
+test registry-5.3 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar none
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} none
+test registry-5.4 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} sz
+test registry-5.5 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar sz
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} sz
+test registry-5.6 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar expand_sz
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} expand_sz
+test registry-5.7 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 binary
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} binary
+test registry-5.8 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 dword
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} dword
+test registry-5.9 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 dword_big_endian
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} dword_big_endian
+test registry-5.10 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 link
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} link
+test registry-5.11 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar multi_sz
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} multi_sz
+test registry-5.12 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 resource_list
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} resource_list
+test registry-5.13 {GetType: unknown types} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 24
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} 24
+test registry-5.14 {GetType: Unicode} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar va\u00c7l1 1 24
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar va\u00c7l1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} 24
+
+test registry-6.1 {GetValue} {win reg english} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ list [catch {registry get HKEY_CURRENT_USER\\TclFoobar val1} msg] $msg
+} {1 {unable to open key: The system cannot find the file specified.}}
+test registry-6.2 {GetValue} {win reg english} {
+ registry set HKEY_CURRENT_USER\\TclFoobar
+ list [catch {registry get HKEY_CURRENT_USER\\TclFoobar val1} msg] $msg
+} {1 {unable to get value "val1" from key "HKEY_CURRENT_USER\TclFoobar": The system cannot find the file specified.}}
+test registry-6.3 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar none
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} foobar
+test registry-6.4 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} foobar
+test registry-6.5 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} foobar
+test registry-6.6 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar expand_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} foobar
+test registry-6.7 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 binary
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} 1
+test registry-6.8 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 0x20 dword
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} 32
+test registry-6.9 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 0x20 dword_big_endian
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} 32
+test registry-6.10 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 link
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} 1
+test registry-6.11 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} foobar
+test registry-6.12 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 {foo\ bar baz} multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {{foo bar} baz}
+test registry-6.13 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 {} multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {}
+test registry-6.14 {GetValue: truncation of multivalues with null elements} \
+ {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 {a {} b} multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} a
+test registry-6.15 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 resource_list
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} 1
+test registry-6.16 {GetValue: unknown types} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 24
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} 1
+test registry-6.17 {GetValue: Unicode value names} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val\u00c71 foobar multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val\u00c71]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} foobar
+test registry-6.18 {GetValue: values with Unicode strings} {win reg nt} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 {foo ba\u30b7r baz} multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} "foo ba\u30b7r baz"
+test registry-6.19 {GetValue: values with Unicode strings} {win reg english} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 {foo ba\u00c7r baz} multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} "foo ba\u00c7r baz"
+test registry-6.20 {GetValue: values with Unicode strings with embedded nulls} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 {foo ba\u0000r baz} multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} "foo ba r baz"
+test registry-6.21 {GetValue: very long value names and values} {pcOnly} {
+ registry set HKEY_CURRENT_USER\\TclFoobar [string repeat k 16383] [string repeat x 16383] multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar [string repeat k 16383]]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} [string repeat x 16383]
+
+test registry-7.1 {GetValueNames: bad key} -constraints {win reg english} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -body {
+ registry values HKEY_CURRENT_USER\\TclFoobar
+} -returnCodes error -result {unable to open key: The system cannot find the file specified.}
+test registry-7.2 {GetValueNames} -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar baz foobar
+} -body {
+ registry values HKEY_CURRENT_USER\\TclFoobar
+} -cleanup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result baz
+test registry-7.3 {GetValueNames} -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar baz foobar1
+ registry set HKEY_CURRENT_USER\\TclFoobar blat foobar2
+ registry set HKEY_CURRENT_USER\\TclFoobar {} foobar3
+} -body {
+ lsort [registry values HKEY_CURRENT_USER\\TclFoobar]
+} -cleanup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {{} baz blat}
+test registry-7.4 {GetValueNames: remote key} -constraints {win reg nonPortable english} -body {
+ set hostname [info hostname]
+ registry set \\\\$hostname\\HKEY_CURRENT_USER\\TclFoobar baz blat
+ set result [registry values \\\\$hostname\\HKEY_CURRENT_USER\\TclFoobar]
+ registry delete \\\\$hostname\\HKEY_CURRENT_USER\\TclFoobar
+ set result
+} -result baz
+test registry-7.5 {GetValueNames: empty key} -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar
+} -body {
+ registry values HKEY_CURRENT_USER\\TclFoobar
+} -cleanup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {}
+test registry-7.6 {GetValueNames: patterns} -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar baz foobar1
+ registry set HKEY_CURRENT_USER\\TclFoobar blat foobar2
+ registry set HKEY_CURRENT_USER\\TclFoobar foo foobar3
+} -body {
+ lsort [registry values HKEY_CURRENT_USER\\TclFoobar b*]
+} -cleanup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {baz blat}
+test registry-7.7 {GetValueNames: names with spaces} -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar baz\ bar foobar1
+ registry set HKEY_CURRENT_USER\\TclFoobar blat foobar2
+ registry set HKEY_CURRENT_USER\\TclFoobar foo foobar3
+} -body {
+ lsort [registry values HKEY_CURRENT_USER\\TclFoobar b*]
+} -cleanup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {{baz bar} blat}
+
+test registry-8.1 {OpenSubKey} -constraints {win reg nonPortable english} \
+ -body {
+ # This test will only succeed if the current user does not have
+ # registry access on the specified machine.
+ registry keys {\\mom\HKEY_LOCAL_MACHINE}
+ } -returnCodes error -result "unable to open key: Access is denied."
+test registry-8.2 {OpenSubKey} -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar
+} -body {
+ registry keys HKEY_CURRENT_USER TclFoobar
+} -cleanup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {TclFoobar}
+test registry-8.3 {OpenSubKey} -constraints {win reg english} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -body {
+ registry keys HKEY_CURRENT_USER\\TclFoobar
+} -returnCodes error \
+ -result "unable to open key: The system cannot find the file specified."
+
+test registry-9.1 {ParseKeyName: bad keys} -constraints {win reg} -body {
+ registry values \\
+} -returnCodes error -result "bad key \"\\\": must start with a valid root"
+test registry-9.2 {ParseKeyName: bad keys} -constraints {win reg} -body {
+ registry values \\foobar
+} -returnCodes error -result {bad key "\foobar": must start with a valid root}
+test registry-9.3 {ParseKeyName: bad keys} -constraints {win reg} -body {
+ registry values \\\\
+} -returnCodes error -result {bad root name "": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}
+test registry-9.4 {ParseKeyName: bad keys} -constraints {win reg} -body {
+ registry values \\\\\\
+} -returnCodes error -result {bad root name "": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}
+test registry-9.5 {ParseKeyName: bad keys} -constraints {win reg english nt} -body {
+ registry values \\\\\\HKEY_CLASSES_ROOT
+} -returnCodes error -result {unable to open key: The network address is invalid.}
+test registry-9.6 {ParseKeyName: bad keys} -constraints {win reg} -body {
+ registry values \\\\gaspode
+} -returnCodes error -result {bad root name "": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}
+test registry-9.7 {ParseKeyName: bad keys} -constraints {win reg} -body {
+ registry values foobar
+} -returnCodes error -result {bad root name "foobar": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}
+test registry-9.8 {ParseKeyName: null keys} -constraints {win reg} -body {
+ registry delete HKEY_CLASSES_ROOT\\
+} -returnCodes error -result {bad key: cannot delete root keys}
+test registry-9.9 {ParseKeyName: null keys} \
+ -constraints {win reg english} \
+ -body {registry keys HKEY_CLASSES_ROOT\\TclFoobar\\baz} \
+ -returnCodes error \
+ -result {unable to open key: The system cannot find the file specified.}
+
+test registry-10.1 {RecursiveDeleteKey} -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -body {
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test1
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test2\\test3
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result [registry keys HKEY_CURRENT_USER TclFoobar]
+ set result
+} -result {}
+test registry-10.2 {RecursiveDeleteKey} -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test1
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test2\\test3
+} -body {
+ registry delete HKEY_CURRENT_USER\\TclFoobar\\test2\\test4
+} -cleanup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {}
+
+test registry-11.1 {SetValue: recursive creation} \
+ -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ } -body {
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz blat foobar
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar\\baz blat]
+ } -result {foobar}
+test registry-11.2 {SetValue: modification} -constraints {win reg} \
+ -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ } -body {
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz blat foobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz blat frob
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar\\baz blat]
+ } -result {frob}
+test registry-11.3 {SetValue: failure} \
+ -constraints {win reg nonPortable english} \
+ -body {
+ # This test will only succeed if the current user does not have
+ # registry access on the specified machine.
+ registry set {\\mom\HKEY_CURRENT_USER\TclFoobar} bar foobar
+ } -returnCodes error -result {unable to open key: Access is denied.}
+
+test registry-12.1 {BroadcastValue} -constraints {win reg} -body {
+ registry broadcast
+} -returnCodes error -result "wrong # args: should be \"registry broadcast keyName ?-timeout milliseconds?\""
+test registry-12.2 {BroadcastValue} -constraints {win reg} -body {
+ registry broadcast "" -time
+} -returnCodes error -result "wrong # args: should be \"registry broadcast keyName ?-timeout milliseconds?\""
+test registry-12.3 {BroadcastValue} -constraints {win reg} -body {
+ registry broadcast "" - 500
+} -returnCodes error -result "wrong # args: should be \"registry broadcast keyName ?-timeout milliseconds?\""
+test registry-12.4 {BroadcastValue} -constraints {win reg} -body {
+ registry broadcast {Environment}
+} -result {1 0}
+test registry-12.5 {BroadcastValue} -constraints {win reg} -body {
+ registry b {}
+} -result {1 0}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# tcl-indent-level: 4
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/remote.tcl b/library/msgcat/tests/remote.tcl
new file mode 100644
index 0000000..097e41f
--- /dev/null
+++ b/library/msgcat/tests/remote.tcl
@@ -0,0 +1,159 @@
+# This file contains Tcl code to implement a remote server that can be
+# used during testing of Tcl socket code. This server is used by some
+# of the tests in socket.test.
+#
+# Source this file in the remote server you are using to test Tcl against.
+#
+# 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.
+
+# Initialize message delimitor
+
+# Initialize command array
+catch {unset command}
+set command(0) ""
+set callerSocket ""
+
+# Detect whether we should print out connection messages etc.
+if {![info exists VERBOSE]} {
+ set VERBOSE 0
+}
+
+proc __doCommands__ {l s} {
+ global callerSocket VERBOSE
+
+ if {$VERBOSE} {
+ puts "--- Server executing the following for socket $s:"
+ puts $l
+ puts "---"
+ }
+ set callerSocket $s
+ set ::errorInfo ""
+ set code [catch {uplevel "#0" $l} msg]
+ return [list $code $::errorInfo $msg]
+}
+
+proc __readAndExecute__ {s} {
+ global command VERBOSE
+
+ set l [gets $s]
+ if {[string compare $l "--Marker--Marker--Marker--"] == 0} {
+ puts $s [__doCommands__ $command($s) $s]
+ puts $s "--Marker--Marker--Marker--"
+ set command($s) ""
+ return
+ }
+ if {[string compare $l ""] == 0} {
+ if {[eof $s]} {
+ if {$VERBOSE} {
+ puts "Server closing $s, eof from client"
+ }
+ close $s
+ }
+ return
+ }
+ if {[eof $s]} {
+ if {$VERBOSE} {
+ puts "Server closing $s, eof from client"
+ }
+ close $s
+ unset command($s)
+ return
+ }
+ append command($s) $l "\n"
+}
+
+proc __accept__ {s a p} {
+ global command VERBOSE
+
+ if {$VERBOSE} {
+ puts "Server accepts new connection from $a:$p on $s"
+ }
+ set command($s) ""
+ fconfigure $s -buffering line -translation crlf
+ fileevent $s readable [list __readAndExecute__ $s]
+}
+
+set serverIsSilent 0
+for {set i 0} {$i < $argc} {incr i} {
+ if {[string compare -serverIsSilent [lindex $argv $i]] == 0} {
+ set serverIsSilent 1
+ break
+ }
+}
+if {![info exists serverPort]} {
+ if {[info exists env(serverPort)]} {
+ set serverPort $env(serverPort)
+ }
+}
+if {![info exists serverPort]} {
+ for {set i 0} {$i < $argc} {incr i} {
+ if {[string compare -port [lindex $argv $i]] == 0} {
+ if {$i < [expr $argc - 1]} {
+ set serverPort [lindex $argv [expr $i + 1]]
+ }
+ break
+ }
+ }
+}
+if {![info exists serverPort]} {
+ set serverPort 2048
+}
+
+if {![info exists serverAddress]} {
+ if {[info exists env(serverAddress)]} {
+ set serverAddress $env(serverAddress)
+ }
+}
+if {![info exists serverAddress]} {
+ for {set i 0} {$i < $argc} {incr i} {
+ if {[string compare -address [lindex $argv $i]] == 0} {
+ if {$i < [expr $argc - 1]} {
+ set serverAddress [lindex $argv [expr $i + 1]]
+ }
+ break
+ }
+ }
+}
+if {![info exists serverAddress]} {
+ set serverAddress 0.0.0.0
+}
+
+if {$serverIsSilent == 0} {
+ set l "Remote server listening on port $serverPort, IP $serverAddress."
+ puts ""
+ puts $l
+ for {set c [string length $l]} {$c > 0} {incr c -1} {puts -nonewline "-"}
+ puts ""
+ puts ""
+ puts "You have set the Tcl variables serverAddress to $serverAddress and"
+ puts "serverPort to $serverPort. You can set these with the -address and"
+ puts "-port command line options, or as environment variables in your"
+ puts "shell."
+ puts ""
+ puts "NOTE: The tests will not work properly if serverAddress is set to"
+ puts "\"localhost\" or 127.0.0.1."
+ puts ""
+ puts "When you invoke tcltest to run the tests, set the variables"
+ puts "remoteServerPort to $serverPort and remoteServerIP to"
+ puts "[info hostname]. You can set these as environment variables"
+ puts "from the shell. The tests will not work properly if you set"
+ puts "remoteServerIP to \"localhost\" or 127.0.0.1."
+ puts ""
+ puts -nonewline "Type Ctrl-C to terminate--> "
+ flush stdout
+}
+
+proc getPort sock {
+ lindex [fconfigure $sock -sockname] 2
+}
+
+if {[catch {set serverSocket \
+ [socket -myaddr $serverAddress -server __accept__ $serverPort]} msg]} {
+ puts "Server on $serverAddress:$serverPort cannot start: $msg"
+} else {
+ puts ready
+ vwait __server_wait_variable__
+}
diff --git a/library/msgcat/tests/rename.test b/library/msgcat/tests/rename.test
new file mode 100644
index 0000000..9ac49b4
--- /dev/null
+++ b/library/msgcat/tests/rename.test
@@ -0,0 +1,182 @@
+# Commands covered: rename
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testdel [llength [info commands testdel]]
+
+# Must eliminate the "unknown" command while the test is running, especially
+# if the test is being run in a program with its own special-purpose unknown
+# command.
+catch {rename unknown unknown.old}
+
+catch {rename r2 {}}
+proc r1 {} {return "procedure r1"}
+rename r1 r2
+
+test rename-1.1 {simple renaming} {
+ r2
+} {procedure r1}
+test rename-1.2 {simple renaming} {
+ list [catch r1 msg] $msg
+} {1 {invalid command name "r1"}}
+rename r2 {}
+test rename-1.3 {simple renaming} {
+ list [catch r2 msg] $msg
+} {1 {invalid command name "r2"}}
+
+# The test below is tricky because it renames a built-in command. It's
+# possible that the test procedure uses this command, so must restore the
+# command before calling test again.
+rename list l.new
+set a [catch list msg1]
+set b [l.new a b c]
+rename l.new list
+set c [catch l.new msg2]
+set d [list 111 222]
+test rename-2.1 {renaming built-in command} {
+ list $a $msg1 $b $c $msg2 $d
+} {1 {invalid command name "list"} {a b c} 1 {invalid command name "l.new"} {111 222}}
+
+test rename-3.1 {error conditions} {
+ list [catch {rename r1} msg] $msg $errorCode
+} {1 {wrong # args: should be "rename oldName newName"} {TCL WRONGARGS}}
+test rename-3.2 {error conditions} {
+ list [catch {rename r1 r2 r3} msg] $msg $errorCode
+} {1 {wrong # args: should be "rename oldName newName"} {TCL WRONGARGS}}
+test rename-3.3 {error conditions} -setup {
+ proc r1 {} {}
+ proc r2 {} {}
+} -returnCodes error -body {
+ rename r1 r2
+} -result {can't rename to "r2": command already exists}
+test rename-3.4 {error conditions} -setup {
+ catch {rename r1 {}}
+ catch {rename r2 {}}
+} -returnCodes error -body {
+ rename r1 r2
+} -result {can't rename "r1": command doesn't exist}
+test rename-3.5 {error conditions} -setup {
+ catch {rename _non_existent_command {}}
+} -returnCodes error -body {
+ rename _non_existent_command {}
+} -result {can't delete "_non_existent_command": command doesn't exist}
+
+catch {rename unknown {}}
+catch {rename unknown.old unknown}
+catch {rename bar {}}
+
+test rename-4.1 {reentrancy issues with command deletion and renaming} testdel {
+ set x {}
+ testdel {} foo {lappend x deleted; rename bar {}; lappend x [info command bar]}
+ rename foo bar
+ lappend x |
+ rename bar {}
+ set x
+} {| deleted {}}
+test rename-4.2 {reentrancy issues with command deletion and renaming} testdel {
+ set x {}
+ testdel {} foo {lappend x deleted; rename foo bar}
+ rename foo {}
+ set x
+} {deleted}
+test rename-4.3 {reentrancy issues with command deletion and renaming} testdel {
+ set x {}
+ testdel {} foo {lappend x deleted; testdel {} foo {lappend x deleted2}}
+ rename foo {}
+ lappend x |
+ rename foo {}
+ set x
+} {deleted | deleted2}
+test rename-4.4 {reentrancy issues with command deletion and renaming} testdel {
+ set x {}
+ testdel {} foo {lappend x deleted; rename foo bar}
+ rename foo {}
+ lappend x | [info command bar]
+} {deleted | {}}
+test rename-4.5 {reentrancy issues with command deletion and renaming} testdel {
+ set env(value) before
+ interp create foo
+ testdel foo cmd {set env(value) deleted}
+ interp delete foo
+ set env(value)
+} {deleted}
+test rename-4.6 {reentrancy issues with command deletion and renaming} testdel {
+ proc kill args {
+ interp delete foo
+ }
+ set env(value) before
+ interp create foo
+ foo alias kill kill
+ testdel foo cmd {set env(value) deleted; kill}
+ list [catch {foo eval {rename cmd {}}} msg] $msg $env(value)
+} {0 {} deleted}
+test rename-4.7 {reentrancy issues with command deletion and renaming} testdel {
+ proc kill args {
+ interp delete foo
+ }
+ set env(value) before
+ interp create foo
+ foo alias kill kill
+ testdel foo cmd {set env(value) deleted; kill}
+ list [catch {interp delete foo} msg] $msg $env(value)
+} {0 {} deleted}
+if {[info exists env(value)]} {
+ unset env(value)
+}
+
+# Save the unknown procedure which is modified by the following test.
+
+catch {rename unknown unknown.old}
+
+set SAVED_UNKNOWN "proc unknown "
+append SAVED_UNKNOWN [list [info args unknown.old] [info body unknown.old]]
+test rename-5.1 {repeated rename deletion and redefinition of same command} {
+ for {set i 0} {$i < 10} {incr i} {
+ eval $SAVED_UNKNOWN
+ tcl_wordBreakBefore "" 0
+ rename tcl_wordBreakBefore {}
+ rename unknown {}
+ }
+} {}
+
+catch {rename unknown {}}
+catch {rename unknown.old unknown}
+
+test rename-6.1 {old code invalidated (epoch incremented) when cmd with compile proc is renamed} -body {
+ proc x {} {
+ set a 123
+ set b [incr a]
+ }
+ x
+ rename incr incr.old
+ proc incr {} {puts "new incr called!"}
+ x
+} -cleanup {
+ rename incr {}
+ rename incr.old incr
+} -returnCodes error -result {wrong # args: should be "incr"}
+
+if {[info commands incr.old] != {}} {
+ catch {rename incr {}}
+ catch {rename incr.old incr}
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/resolver.test b/library/msgcat/tests/resolver.test
new file mode 100644
index 0000000..bb9f59d
--- /dev/null
+++ b/library/msgcat/tests/resolver.test
@@ -0,0 +1,200 @@
+# This test collection covers some unwanted interactions between command
+# literal sharing and the use of command resolvers (per-interp) which cause
+# command literals to be re-used with their command references being invalid
+# in the reusing context. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 2011 Gustaf Neumann <gustaf.neumann@wu.ac.at>
+# Copyright (c) 2011 Stefan Sobernig <stefan.sobernig@wu.ac.at>
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+if {"::tcltest" in [namespace children]} {
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testinterpresolver [llength [info commands testinterpresolver]]
+
+test resolver-1.1 {cmdNameObj sharing vs. cmd resolver: namespace import} -setup {
+ testinterpresolver up
+ namespace eval ::ns1 {
+ proc z {} { return Z }
+ namespace export z
+ }
+ proc ::y {} { return Y }
+ proc ::x {} {
+ z
+ }
+} -constraints testinterpresolver -body {
+ # 1) Have the proc body compiled: During compilation or, alternatively,
+ # the first evaluation of the compiled body, the InterpCmdResolver (see
+ # tclTest.c) maps the cmd token "z" to "::y"; this mapping is saved in the
+ # resulting CmdName Tcl_Obj with the print string "z". The CmdName Tcl_Obj
+ # is turned into a command literal shared for a given (here: the global)
+ # namespace.
+ set r0 [x]; # --> The result of [x] is "Y"
+ # 2) After having requested cmd resolution above, we can now use the
+ # globally shared CmdName Tcl_Obj "z", now bound to cmd ::y. This is
+ # certainly questionable, but defensible
+ set r1 [z]; # --> The result of [z] is "Y"
+ # 3) We import from the namespace ns1 another z. [namespace import] takes
+ # care "shadowed" cmd references, however, till now cmd literals have not
+ # been touched. This is, however, necessary since the BC compiler (used in
+ # the [namespace eval]) seems to be eager to reuse CmdName Tcl_Objs as cmd
+ # literals for a given NS scope. We expect, that r2 is "Z", the result of
+ # the namespace imported cmd.
+ namespace eval :: {
+ namespace import ::ns1::z
+ set r2 [z]
+ }
+ list $r0 $r1 $::r2
+} -cleanup {
+ testinterpresolver down
+ rename ::x ""
+ rename ::y ""
+ namespace delete ::ns1
+} -result {Y Y Z}
+test resolver-1.2 {cmdNameObj sharing vs. cmd resolver: proc creation} -setup {
+ testinterpresolver up
+ proc ::y {} { return Y }
+ proc ::x {} {
+ z
+ }
+} -constraints testinterpresolver -body {
+ set r0 [x]
+ set r1 [z]
+ proc ::foo {} {
+ proc ::z {} { return Z }
+ return [z]
+ }
+ list $r0 $r1 [::foo]
+} -cleanup {
+ testinterpresolver down
+ rename ::x ""
+ rename ::y ""
+ rename ::foo ""
+ rename ::z ""
+} -result {Y Y Z}
+test resolver-1.3 {cmdNameObj sharing vs. cmd resolver: rename} -setup {
+ testinterpresolver up
+ proc ::Z {} { return Z }
+ proc ::y {} { return Y }
+ proc ::x {} {
+ z
+ }
+} -constraints testinterpresolver -body {
+ set r0 [x]
+ set r1 [z]
+ namespace eval :: {
+ rename ::Z ::z
+ set r2 [z]
+ }
+ list $r0 $r1 $r2
+} -cleanup {
+ testinterpresolver down
+ rename ::x ""
+ rename ::y ""
+ rename ::z ""
+} -result {Y Y Z}
+test resolver-1.4 {cmdNameObj sharing vs. cmd resolver: interp expose} -setup {
+ testinterpresolver up
+ proc ::Z {} { return Z }
+ interp hide {} Z
+ proc ::y {} { return Y }
+ proc ::x {} {
+ z
+ }
+} -constraints testinterpresolver -body {
+ set r0 [x]
+ set r1 [z]
+ interp expose {} Z z
+ namespace eval :: {
+ set r2 [z]
+ }
+ list $r0 $r1 $r2
+} -cleanup {
+ testinterpresolver down
+ rename ::x ""
+ rename ::y ""
+ rename ::z ""
+} -result {Y Y Z}
+test resolver-1.5 {cmdNameObj sharing vs. cmd resolver: other than global NS} -setup {
+ testinterpresolver up
+ namespace eval ::ns1 {
+ proc z {} { return Z }
+ namespace export z
+ }
+ proc ::y {} { return Y }
+ namespace eval ::ns2 {
+ proc x {} {
+ z
+ }
+ }
+} -constraints testinterpresolver -body {
+ set r0 [namespace eval ::ns2 {x}]
+ set r1 [namespace eval ::ns2 {z}]
+ namespace eval ::ns2 {
+ namespace import ::ns1::z
+ set r2 [z]
+ }
+ list $r0 $r1 $r2
+} -cleanup {
+ testinterpresolver down
+ namespace delete ::ns2
+ namespace delete ::ns1
+} -result {Y Y Z}
+test resolver-1.6 {cmdNameObj sharing vs. cmd resolver: interp alias} -setup {
+ testinterpresolver up
+ proc ::Z {} { return Z }
+ proc ::y {} { return Y }
+ proc ::x {} {
+ z
+ }
+} -constraints testinterpresolver -body {
+ set r0 [x]
+ set r1 [z]
+ namespace eval :: {
+ interp alias {} ::z {} ::Z
+ set r2 [z]
+ }
+ list $r0 $r1 $r2
+} -cleanup {
+ testinterpresolver down
+ rename ::x ""
+ rename ::y ""
+ rename ::Z ""
+} -result {Y Y Z}
+
+test resolver-2.1 {compiled var resolver: Bug #3383616} -setup {
+ testinterpresolver up
+ # The compiled var resolver fetches just variables starting with a capital
+ # "T" and stores some test information in the resolver-specific resolver
+ # var info.
+ proc ::x {} {
+ set T1 100
+ return $T1
+ }
+} -constraints testinterpresolver -body {
+ # Call "x" the first time, causing a byte code compilation of the body.
+ # During the compilation the compiled var resolver, the resolve-specific
+ # var info is allocated, during the execution of the body, the variable is
+ # fetched and cached.
+ x;
+ # During later calls, the cached variable is reused.
+ x
+ # When the proc is freed, the resolver-specific resolver var info is
+ # freed. This did not happen before fix #3383616.
+ rename ::x ""
+} -cleanup {
+ testinterpresolver down
+} -result {}
+
+cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/result.test b/library/msgcat/tests/result.test
new file mode 100644
index 0000000..f080654
--- /dev/null
+++ b/library/msgcat/tests/result.test
@@ -0,0 +1,146 @@
+# This file tests the routines in tclResult.c.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Some tests require the testsaveresult command
+
+testConstraint testsaveresult [llength [info commands testsaveresult]]
+testConstraint testsetobjerrorcode [llength [info commands testsetobjerrorcode]]
+testConstraint testseterrorcode [llength [info commands testseterrorcode]]
+testConstraint testreturn [llength [info commands testreturn]]
+
+test result-1.1 {Tcl_SaveInterpResult} {testsaveresult} {
+ testsaveresult small {set x 42} 0
+} {small result}
+test result-1.2 {Tcl_SaveInterpResult} {testsaveresult} {
+ testsaveresult append {set x 42} 0
+} {append result}
+test result-1.3 {Tcl_SaveInterpResult} {testsaveresult} {
+ testsaveresult dynamic {set x 42} 0
+} {dynamic result notCalled present}
+test result-1.4 {Tcl_SaveInterpResult} {testsaveresult} {
+ testsaveresult object {set x 42} 0
+} {object result same}
+test result-1.5 {Tcl_SaveInterpResult} {testsaveresult} {
+ testsaveresult small {set x 42} 1
+} {42}
+test result-1.6 {Tcl_SaveInterpResult} {testsaveresult} {
+ testsaveresult append {set x 42} 1
+} {42}
+test result-1.7 {Tcl_SaveInterpResult} {testsaveresult} {
+ testsaveresult dynamic {set x 42} 1
+} {42 called missing}
+test result-1.8 {Tcl_SaveInterpResult} {testsaveresult} {
+ testsaveresult object {set x 42} 1
+} {42 different}
+
+# Tcl_RestoreInterpResult is mostly tested by the previous tests except
+# for the following case
+
+test result-2.1 {Tcl_RestoreInterpResult} {testsaveresult} {
+ testsaveresult append {cd _foobar} 0
+} {append result}
+
+# Tcl_DiscardInterpResult is mostly tested by the previous tests except
+# for the following cases
+
+test result-3.1 {Tcl_DiscardInterpResult} -constraints testsaveresult -body {
+ testsaveresult append {cd _foobar} 1
+} -returnCodes error -result {couldn't change working directory to "_foobar": no such file or directory}
+test result-3.2 {Tcl_DiscardInterpResult} {testsaveresult} {
+ testsaveresult free {set x 42} 1
+} {42}
+
+test result-4.1 {Tcl_SetObjErrorCode - one arg} {testsetobjerrorcode} {
+ catch {testsetobjerrorcode 1}
+ list [set errorCode]
+} {1}
+test result-4.2 {Tcl_SetObjErrorCode - two args} {testsetobjerrorcode} {
+ catch {testsetobjerrorcode 1 2}
+ list [set errorCode]
+} {{1 2}}
+test result-4.3 {Tcl_SetObjErrorCode - three args} {testsetobjerrorcode} {
+ catch {testsetobjerrorcode 1 2 3}
+ list [set errorCode]
+} {{1 2 3}}
+test result-4.4 {Tcl_SetObjErrorCode - four args} {testsetobjerrorcode} {
+ catch {testsetobjerrorcode 1 2 3 4}
+ list [set errorCode]
+} {{1 2 3 4}}
+test result-4.5 {Tcl_SetObjErrorCode - five args} {testsetobjerrorcode} {
+ catch {testsetobjerrorcode 1 2 3 4 5}
+ list [set errorCode]
+} {{1 2 3 4 5}}
+
+test result-5.1 {Tcl_SetErrorCode - one arg} testseterrorcode {
+ catch {testseterrorcode 1}
+ set errorCode
+} 1
+test result-5.2 {Tcl_SetErrorCode - one arg, list quoting} testseterrorcode {
+ catch {testseterrorcode {a b}}
+ set errorCode
+} {{a b}}
+test result-5.3 {Tcl_SetErrorCode - one arg, list quoting} testseterrorcode {
+ catch {testseterrorcode \{}
+ llength $errorCode
+} 1
+test result-5.4 {Tcl_SetErrorCode - two args, list quoting} testseterrorcode {
+ catch {testseterrorcode {a b} c}
+ set errorCode
+} {{a b} c}
+
+test result-6.0 {Bug 1209759} -constraints testreturn -body {
+ # Might panic if bug is not fixed.
+ proc foo {} {testreturn}
+ foo
+} -returnCodes ok -result {}
+test result-6.1 {Bug 1209759} -constraints testreturn -body {
+ # Might panic if bug is not fixed.
+ proc foo {} {catch {return -level 2}; testreturn}
+ foo
+} -cleanup {
+ rename foo {}
+} -returnCodes ok -result {}
+test result-6.2 {Bug 1649062} -setup {
+ proc foo {} {
+ if {[catch {
+ return -code error -errorinfo custom -errorcode CUSTOM foo
+ } err]} {
+ return [list $err $::errorCode $::errorInfo]
+ }
+ }
+ set ::errorInfo {}
+ set ::errorCode {}
+} -body {
+ foo
+} -cleanup {
+ rename foo {}
+} -result {foo {} {}}
+test result-6.3 {Bug 2383005} {
+ catch {return -code error -errorcode {{}a} eek} m
+ set m
+} {bad -errorcode value: expected a list but got "{}a"}
+test result-6.4 {non-list -errorstack} -body {
+ catch {return -code error -errorstack {{}a} eek} m o
+ list $m [dict get $o -errorcode] [dict get $o -errorstack]
+} -match glob -result {{bad -errorstack value: expected a list but got "{}a"} {TCL RESULT NONLIST_ERRORSTACK} {INNER * UP 1}}
+test result-6.5 {odd-sized-list -errorstack} -body {
+ catch {return -code error -errorstack a eek} m o
+ list $m [dict get $o -errorcode] [dict get $o -errorstack]
+} -match glob -result {{forbidden odd-sized list for -errorstack: "a"} {TCL RESULT ODDSIZEDLIST_ERRORSTACK} {INNER * UP 1}}
+# cleanup
+cleanupTests
+return
diff --git a/library/msgcat/tests/safe.test b/library/msgcat/tests/safe.test
new file mode 100644
index 0000000..4a2792e
--- /dev/null
+++ b/library/msgcat/tests/safe.test
@@ -0,0 +1,774 @@
+# safe.test --
+#
+# This file contains a collection of tests for safe Tcl, packages loading, and
+# using safe interpreters. Sourcing this file into tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require Tcl 8.5
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+foreach i [interp slaves] {
+ interp delete $i
+}
+
+set saveAutoPath $::auto_path
+set ::auto_path [info library]
+
+# Force actual loading of the safe package because we use un exported (and
+# thus un-autoindexed) APIs in this test result arguments:
+catch {safe::interpConfigure}
+
+# testing that nested and statics do what is advertised (we use a static
+# package - Tcltest - but it might be absent if we're in standard tclsh)
+
+testConstraint TcltestPackage [expr {![catch {package require Tcltest}]}]
+
+test safe-1.1 {safe::interpConfigure syntax} -returnCodes error -body {
+ safe::interpConfigure
+} -result {no value given for parameter "slave" (use -help for full usage) :
+ slave name () name of the slave}
+test safe-1.2 {safe::interpCreate syntax} -returnCodes error -body {
+ safe::interpCreate -help
+} -result {Usage information:
+ Var/FlagName Type Value Help
+ ------------ ---- ----- ----
+ (-help gives this help)
+ ?slave? name () name of the slave (optional)
+ -accessPath list () access path for the slave
+ -noStatics boolflag (false) prevent loading of statically linked pkgs
+ -statics boolean (true) loading of statically linked pkgs
+ -nestedLoadOk boolflag (false) allow nested loading
+ -nested boolean (false) nested loading
+ -deleteHook script () delete hook}
+test safe-1.3 {safe::interpInit syntax} -returnCodes error -body {
+ safe::interpInit -noStatics
+} -result {bad value "-noStatics" for parameter
+ slave name () name of the slave}
+
+test safe-2.1 {creating interpreters, should have no aliases} emptyTest {
+ # Disabled this test. It tests nothing sensible. [Bug 999612]
+ # interp aliases
+} ""
+test safe-2.2 {creating interpreters, should have no aliases} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ interp create a
+ a aliases
+} -cleanup {
+ safe::interpDelete a
+} -result ""
+test safe-2.3 {creating safe interpreters, should have no unexpected aliases} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ interp create a -safe
+ lsort [a aliases]
+} -cleanup {
+ interp delete a
+} -result {::tcl::mathfunc::max ::tcl::mathfunc::min clock}
+
+test safe-3.1 {calling safe::interpInit is safe} -setup {
+ catch {safe::interpDelete a}
+ interp create a -safe
+} -body {
+ safe::interpInit a
+ interp eval a exec ls
+} -returnCodes error -cleanup {
+ safe::interpDelete a
+} -result {invalid command name "exec"}
+test safe-3.2 {calling safe::interpCreate on trusted interp} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ safe::interpCreate a
+ lsort [a aliases]
+} -cleanup {
+ safe::interpDelete a
+} -result {::tcl::file::atime ::tcl::file::attributes ::tcl::file::copy ::tcl::file::delete ::tcl::file::dirname ::tcl::file::executable ::tcl::file::exists ::tcl::file::extension ::tcl::file::isdirectory ::tcl::file::isfile ::tcl::file::link ::tcl::file::lstat ::tcl::file::mkdir ::tcl::file::mtime ::tcl::file::nativename ::tcl::file::normalize ::tcl::file::owned ::tcl::file::readable ::tcl::file::readlink ::tcl::file::rename ::tcl::file::rootname ::tcl::file::size ::tcl::file::stat ::tcl::file::tail ::tcl::file::tempfile ::tcl::file::type ::tcl::file::volumes ::tcl::file::writable ::tcl::info::nameofexecutable clock encoding exit glob load source}
+test safe-3.3 {calling safe::interpCreate on trusted interp} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ safe::interpCreate a
+ interp eval a {source [file join $tcl_library init.tcl]}
+} -cleanup {
+ safe::interpDelete a
+} -result ""
+test safe-3.4 {calling safe::interpCreate on trusted interp} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ safe::interpCreate a
+ interp eval a {source [file join $tcl_library init.tcl]}
+} -cleanup {
+ safe::interpDelete a
+} -result {}
+
+test safe-4.1 {safe::interpDelete} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ interp create a
+ safe::interpDelete a
+} -result ""
+test safe-4.2 {safe::interpDelete, indirectly} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ interp create a
+ a alias exit safe::interpDelete a
+ a eval exit
+} -result ""
+test safe-4.5 {safe::interpDelete} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ safe::interpCreate a
+ safe::interpCreate a
+} -returnCodes error -cleanup {
+ safe::interpDelete a
+} -result {interpreter named "a" already exists, cannot create}
+test safe-4.6 {safe::interpDelete, indirectly} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ safe::interpCreate a
+ a eval exit
+} -result ""
+
+# The following test checks whether the definition of tcl_endOfWord can be
+# obtained from auto_loading.
+
+test safe-5.1 {test auto-loading in safe interpreters} -setup {
+ catch {safe::interpDelete a}
+ safe::interpCreate a
+} -body {
+ interp eval a {tcl_endOfWord "" 0}
+} -cleanup {
+ safe::interpDelete a
+} -result -1
+
+# test safe interps 'information leak'
+proc SafeEval {script} {
+ # Helper procedure that ensures the safe interp is cleaned up even if
+ # there is a failure in the script.
+ set SafeInterp [interp create -safe]
+ catch {$SafeInterp eval $script} msg opts
+ interp delete $SafeInterp
+ return -options $opts $msg
+}
+
+test safe-6.1 {test safe interpreters knowledge of the world} {
+ lsort [SafeEval {info globals}]
+} {tcl_interactive tcl_patchLevel tcl_platform tcl_version}
+test safe-6.2 {test safe interpreters knowledge of the world} {
+ SafeEval {info script}
+} {}
+test safe-6.3 {test safe interpreters knowledge of the world} {
+ set r [SafeEval {array names tcl_platform}]
+ # If running a windows-debug shell, remove the "debug" element from r.
+ if {[testConstraint win]} {
+ set r [lsearch -all -inline -not -exact $r "debug"]
+ }
+ set r [lsearch -all -inline -not -exact $r "threaded"]
+ lsort $r
+} {byteOrder pathSeparator platform pointerSize wordSize}
+
+# More test should be added to check that hostname, nameofexecutable, aren't
+# leaking infos, but they still do...
+
+# high level general test
+test safe-7.1 {tests that everything works at high level} {
+ set i [safe::interpCreate]
+ # no error shall occur:
+ # (because the default access_path shall include 1st level sub dirs so
+ # package require in a slave works like in the master)
+ set v [interp eval $i {package require http 1}]
+ # no error shall occur:
+ interp eval $i {http_config}
+ safe::interpDelete $i
+ set v
+} 1.0
+test safe-7.2 {tests specific path and interpFind/AddToAccessPath} -body {
+ set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
+ # should not add anything (p0)
+ set token1 [safe::interpAddToAccessPath $i [info library]]
+ # should add as p1
+ set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
+ # an error shall occur (http is not anymore in the secure 0-level
+ # provided deep path)
+ list $token1 $token2 \
+ [catch {interp eval $i {package require http 1}} msg] $msg \
+ [safe::interpConfigure $i]\
+ [safe::interpDelete $i]
+} -match glob -result "{\$p(:0:)} {\$p(:*:)} 1 {can't find package http 1} {-accessPath {[list $tcl_library */dummy/unixlike/test/path]} -statics 0 -nested 1 -deleteHook {}} {}"
+test safe-7.3 {check that safe subinterpreters work} {
+ set i [safe::interpCreate]
+ set j [safe::interpCreate [list $i x]]
+ list [interp eval $j {join {o k} ""}] [safe::interpDelete $i] [interp exists $j]
+} {ok {} 0}
+
+# test source control on file name
+test safe-8.1 {safe source control on file} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+} -body {
+ safe::interpCreate $i
+ $i eval {source}
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {wrong # args: should be "source ?-encoding E? fileName"}
+test safe-8.2 {safe source control on file} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+} -body {
+ safe::interpCreate $i
+ $i eval {source a b c d e}
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {wrong # args: should be "source ?-encoding E? fileName"}
+test safe-8.3 {safe source control on file} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+ set log {}
+ proc safe-test-log {str} {lappend ::log $str}
+ set prevlog [safe::setLogCmd]
+} -body {
+ safe::interpCreate $i
+ safe::setLogCmd safe-test-log
+ list [catch {$i eval {source .}} msg] $msg $log
+} -cleanup {
+ safe::setLogCmd $prevlog
+ unset log
+ safe::interpDelete $i
+} -result {1 {permission denied} {{ERROR for slave a : ".": is a directory}}}
+test safe-8.4 {safe source control on file} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+ set log {}
+ proc safe-test-log {str} {global log; lappend log $str}
+ set prevlog [safe::setLogCmd]
+} -body {
+ safe::interpCreate $i
+ safe::setLogCmd safe-test-log
+ list [catch {$i eval {source /abc/def}} msg] $msg $log
+} -cleanup {
+ safe::setLogCmd $prevlog
+ unset log
+ safe::interpDelete $i
+} -result {1 {permission denied} {{ERROR for slave a : "/abc/def": not in access_path}}}
+test safe-8.5 {safe source control on file} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+ set log {}
+ proc safe-test-log {str} {global log; lappend log $str}
+ set prevlog [safe::setLogCmd]
+} -body {
+ # This tested filename == *.tcl or tclIndex, but that restriction was
+ # removed in 8.4a4 - hobbs
+ safe::interpCreate $i
+ safe::setLogCmd safe-test-log
+ list [catch {
+ $i eval {source [file join [info lib] blah]}
+ } msg] $msg $log
+} -cleanup {
+ safe::setLogCmd $prevlog
+ unset log
+ safe::interpDelete $i
+} -result [list 1 {no such file or directory} [list "ERROR for slave a : [file join [info library] blah]:no such file or directory"]]
+test safe-8.6 {safe source control on file} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+ set log {}
+ proc safe-test-log {str} {global log; lappend log $str}
+ set prevlog [safe::setLogCmd]
+} -body {
+ safe::interpCreate $i
+ safe::setLogCmd safe-test-log
+ list [catch {
+ $i eval {source [file join [info lib] blah.tcl]}
+ } msg] $msg $log
+} -cleanup {
+ safe::setLogCmd $prevlog
+ unset log
+ safe::interpDelete $i
+} -result [list 1 {no such file or directory} [list "ERROR for slave a : [file join [info library] blah.tcl]:no such file or directory"]]
+test safe-8.7 {safe source control on file} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+ set log {}
+ proc safe-test-log {str} {global log; lappend log $str}
+ set prevlog [safe::setLogCmd]
+} -body {
+ safe::interpCreate $i
+ # This tested length of filename, but that restriction was removed in
+ # 8.4a4 - hobbs
+ safe::setLogCmd safe-test-log
+ list [catch {
+ $i eval {source [file join [info lib] xxxxxxxxxxx.tcl]}
+ } msg] $msg $log
+} -cleanup {
+ safe::setLogCmd $prevlog
+ unset log
+ safe::interpDelete $i
+} -result [list 1 {no such file or directory} [list "ERROR for slave a : [file join [info library] xxxxxxxxxxx.tcl]:no such file or directory"]]
+test safe-8.8 {safe source forbids -rsrc} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+ safe::interpCreate $i
+} -body {
+ $i eval {source -rsrc Init}
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {wrong # args: should be "source ?-encoding E? fileName"}
+test safe-8.9 {safe source and return} -setup {
+ set returnScript [makeFile {return "ok"} return.tcl]
+ catch {safe::interpDelete $i}
+} -body {
+ safe::interpCreate $i
+ set token [safe::interpAddToAccessPath $i [file dirname $returnScript]]
+ $i eval [list source $token/[file tail $returnScript]]
+} -cleanup {
+ catch {safe::interpDelete $i}
+ removeFile $returnScript
+} -result ok
+test safe-8.10 {safe source and return} -setup {
+ set returnScript [makeFile {return -level 2 "ok"} return.tcl]
+ catch {safe::interpDelete $i}
+} -body {
+ safe::interpCreate $i
+ set token [safe::interpAddToAccessPath $i [file dirname $returnScript]]
+ $i eval [list apply {filename {
+ source $filename
+ error boom
+ }} $token/[file tail $returnScript]]
+} -cleanup {
+ catch {safe::interpDelete $i}
+ removeFile $returnScript
+} -result ok
+
+test safe-9.1 {safe interps' deleteHook} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+ set res {}
+} -body {
+ proc testDelHook {args} {
+ global res
+ # the interp still exists at that point
+ interp eval a {set delete 1}
+ # mark that we've been here (successfully)
+ set res $args
+ }
+ safe::interpCreate $i -deleteHook "testDelHook arg1 arg2"
+ list [interp eval $i exit] $res
+} -result {{} {arg1 arg2 a}}
+test safe-9.2 {safe interps' error in deleteHook} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+ set res {}
+ set log {}
+ proc safe-test-log {str} {lappend ::log $str}
+ set prevlog [safe::setLogCmd]
+} -body {
+ proc testDelHook {args} {
+ global res
+ # the interp still exists at that point
+ interp eval a {set delete 1}
+ # mark that we've been here (successfully)
+ set res $args
+ # create an exception
+ error "being catched"
+ }
+ safe::interpCreate $i -deleteHook "testDelHook arg1 arg2"
+ safe::setLogCmd safe-test-log
+ list [safe::interpDelete $i] $res $log
+} -cleanup {
+ safe::setLogCmd $prevlog
+ unset log
+} -result {{} {arg1 arg2 a} {{NOTICE for slave a : About to delete} {ERROR for slave a : Delete hook error (being catched)} {NOTICE for slave a : Deleted}}}
+test safe-9.3 {dual specification of statics} -returnCodes error -body {
+ safe::interpCreate -stat true -nostat
+} -result {conflicting values given for -statics and -noStatics}
+test safe-9.4 {dual specification of statics} {
+ # no error shall occur
+ safe::interpDelete [safe::interpCreate -stat false -nostat]
+} {}
+test safe-9.5 {dual specification of nested} -returnCodes error -body {
+ safe::interpCreate -nested 0 -nestedload
+} -result {conflicting values given for -nested and -nestedLoadOk}
+test safe-9.6 {interpConfigure widget like behaviour} -body {
+ # this test shall work, don't try to "fix it" unless you *really* know what
+ # you are doing (ie you are me :p) -- dl
+ list [set i [safe::interpCreate \
+ -noStatics \
+ -nestedLoadOk \
+ -deleteHook {foo bar}]
+ safe::interpConfigure $i -accessPath /foo/bar
+ safe::interpConfigure $i]\
+ [safe::interpConfigure $i -aCCess]\
+ [safe::interpConfigure $i -nested]\
+ [safe::interpConfigure $i -statics]\
+ [safe::interpConfigure $i -DEL]\
+ [safe::interpConfigure $i -accessPath /blah -statics 1
+ safe::interpConfigure $i]\
+ [safe::interpConfigure $i -deleteHook toto -nosta -nested 0
+ safe::interpConfigure $i]
+} -match glob -result {{-accessPath * -statics 0 -nested 1 -deleteHook {foo bar}} {-accessPath *} {-nested 1} {-statics 0} {-deleteHook {foo bar}} {-accessPath * -statics 1 -nested 1 -deleteHook {foo bar}} {-accessPath * -statics 0 -nested 0 -deleteHook toto}}
+
+catch {teststaticpkg Safepkg1 0 0}
+test safe-10.1 {testing statics loading} -constraints TcltestPackage -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i {load {} Safepkg1}
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {can't use package in a safe interpreter: no Safepkg1_SafeInit procedure}
+test safe-10.2 {testing statics loading / -nostatics} -constraints TcltestPackage -body {
+ set i [safe::interpCreate -nostatics]
+ interp eval $i {load {} Safepkg1}
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {permission denied (static package)}
+test safe-10.3 {testing nested statics loading / no nested by default} -setup {
+ set i [safe::interpCreate]
+} -constraints TcltestPackage -body {
+ interp eval $i {interp create x; load {} Safepkg1 x}
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {permission denied (nested load)}
+test safe-10.4 {testing nested statics loading / -nestedloadok} -constraints TcltestPackage -body {
+ set i [safe::interpCreate -nestedloadok]
+ interp eval $i {interp create x; load {} Safepkg1 x}
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {can't use package in a safe interpreter: no Safepkg1_SafeInit procedure}
+
+test safe-11.1 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {wrong # args: should be "encoding option ?arg ...?"}
+test safe-11.1a {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding foobar
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -match glob -result {bad option "foobar": must be *}
+test safe-11.2 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding system cp775
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {wrong # args: should be "encoding system"}
+test safe-11.3 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding system
+} -cleanup {
+ safe::interpDelete $i
+} -result [encoding system]
+test safe-11.4 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding names
+} -cleanup {
+ safe::interpDelete $i
+} -result [encoding names]
+test safe-11.5 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding convertfrom cp1258 foobar
+} -cleanup {
+ safe::interpDelete $i
+} -result foobar
+test safe-11.6 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding convertto cp1258 foobar
+} -cleanup {
+ safe::interpDelete $i
+} -result foobar
+test safe-11.7 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding convertfrom
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {wrong # args: should be "encoding convertfrom ?encoding? data"}
+test safe-11.8 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding convertto
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {wrong # args: should be "encoding convertto ?encoding? data"}
+
+test safe-12.1 {glob is restricted [Bug 2906841]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ $i eval glob ../*
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result "permission denied"
+test safe-12.2 {glob is restricted [Bug 2906841]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ $i eval glob -directory .. *
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result "permission denied"
+test safe-12.3 {glob is restricted [Bug 2906841]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ $i eval glob -join .. *
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result "permission denied"
+test safe-12.4 {glob is restricted [Bug 2906841]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ $i eval glob -nocomplain ../*
+} -cleanup {
+ safe::interpDelete $i
+} -result {}
+test safe-12.5 {glob is restricted [Bug 2906841]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ $i eval glob -directory .. -nocomplain *
+} -cleanup {
+ safe::interpDelete $i
+} -result {}
+test safe-12.6 {glob is restricted [Bug 2906841]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ $i eval glob -nocomplain -join .. *
+} -cleanup {
+ safe::interpDelete $i
+} -result {}
+test safe-12.7 {glob is restricted} -setup {
+ set i [safe::interpCreate]
+} -body {
+ $i eval glob *
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {permission denied}
+
+proc buildEnvironment {filename} {
+ upvar 1 testdir testdir testdir2 testdir2 testfile testfile
+ set testdir [makeDirectory deletethisdir]
+ set testdir2 [makeDirectory deletemetoo $testdir]
+ set testfile [makeFile {} $filename $testdir2]
+}
+#### New tests for Safe base glob, with patches @ Bug 2964715
+test safe-13.1 {glob is restricted [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ $i eval glob *
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {permission denied}
+test safe-13.2 {mimic the valid glob call by ::tcl::tm::UnknownHandler [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment deleteme.tm
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir2
+ set result [$i eval glob -nocomplain -directory $testdir2 *.tm]
+ if {$result eq [list $testfile]} {
+ return "glob match"
+ } else {
+ return "no match: $result"
+ }
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {glob match}
+test safe-13.3 {cf 13.2 but test glob failure when -directory is outside access path [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment deleteme.tm
+} -body {
+ $i eval glob -directory $testdir2 *.tm
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {permission denied}
+test safe-13.4 {another valid glob call [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment deleteme.tm
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir
+ ::safe::interpAddToAccessPath $i $testdir2
+ set result [$i eval \
+ glob -nocomplain -directory $testdir [file join deletemetoo *.tm]]
+ if {$result eq [list $testfile]} {
+ return "glob match"
+ } else {
+ return "no match: $result"
+ }
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {glob match}
+test safe-13.5 {as 13.4 but test glob failure when -directory is outside access path [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment deleteme.tm
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir2
+ $i eval \
+ glob -directory $testdir [file join deletemetoo *.tm]
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {permission denied}
+test safe-13.6 {as 13.4 but test silent failure when result is outside access_path [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment deleteme.tm
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir
+ $i eval \
+ glob -nocomplain -directory $testdir [file join deletemetoo *.tm]
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {}
+test safe-13.7 {mimic the glob call by tclPkgUnknown which gives a deliberate error in a safe interpreter [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment pkgIndex.tcl
+} -body {
+ set safeTD [::safe::interpAddToAccessPath $i $testdir]
+ ::safe::interpAddToAccessPath $i $testdir2
+ string map [list $safeTD EXPECTED] [$i eval [list \
+ glob -directory $safeTD -join * pkgIndex.tcl]]
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {{EXPECTED/deletemetoo/pkgIndex.tcl}}
+# Note the extra {} around the result above; that's *expected* because of the
+# format of virtual path roots.
+test safe-13.8 {mimic the glob call by tclPkgUnknown without the deliberate error that is specific to pkgIndex.tcl [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment notIndex.tcl
+} -body {
+ set safeTD [::safe::interpAddToAccessPath $i $testdir]
+ ::safe::interpAddToAccessPath $i $testdir2
+ $i eval [list glob -directory $safeTD -join -nocomplain * notIndex.tcl]
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {}
+test safe-13.9 {as 13.8 but test glob failure when -directory is outside access path [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment notIndex.tcl
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir2
+ set result [$i eval \
+ glob -directory $testdir -join -nocomplain * notIndex.tcl]
+ if {$result eq [list $testfile]} {
+ return {glob match}
+ } else {
+ return "no match: $result"
+ }
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {no match: }
+test safe-13.10 {as 13.8 but test silent failure when result is outside access_path [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment notIndex.tcl
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir
+ $i eval glob -directory $testdir -join -nocomplain * notIndex.tcl
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {}
+rename buildEnvironment {}
+
+#### Test for the module path
+test safe-14.1 {Check that module path is the same as in the master interpreter [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ set tm {}
+ foreach token [$i eval ::tcl::tm::path list] {
+ lappend tm [dict get [set ::safe::S${i}(access_path,map)] $token]
+ }
+ return $tm
+} -cleanup {
+ safe::interpDelete $i
+} -result [::tcl::tm::path list]
+
+test safe-15.1 {safe file ensemble does not surprise code} -setup {
+ set i [interp create -safe]
+} -body {
+ set result [expr {"file" in [interp hidden $i]}]
+ lappend result [interp eval $i {tcl::file::split a/b/c}]
+ lappend result [catch {interp eval $i {tcl::file::isdirectory .}}]
+ lappend result [interp invokehidden $i file split a/b/c]
+ lappend result [catch {interp eval $i {file split a/b/c}} msg] $msg
+ lappend result [catch {interp invokehidden $i file isdirectory .}]
+ interp expose $i file
+ lappend result [catch {interp eval $i {file split a/b/c}} msg] $msg
+ lappend result [catch {interp eval $i {file isdirectory .}} msg] $msg
+} -cleanup {
+ interp delete $i
+} -result {1 {a b c} 1 {a b c} 1 {invalid command name "file"} 1 0 {a b c} 1 {not allowed to invoke subcommand isdirectory of file}}
+
+### ~ should have no special meaning in paths in safe interpreters
+test safe-16.1 {Bug 3529949: defang ~ in paths} -setup {
+ set savedHOME $env(HOME)
+ set env(HOME) /foo/bar
+ set i [safe::interpCreate]
+} -body {
+ $i eval {
+ set d [format %c 126]
+ list [file join [file dirname $d] [file tail $d]]
+ }
+} -cleanup {
+ safe::interpDelete $i
+ set env(HOME) $savedHOME
+} -result {./~}
+test safe-16.2 {Bug 3529949: defang ~user in paths} -setup {
+ set i [safe::interpCreate]
+ set user $tcl_platform(user)
+} -body {
+ string map [list $user USER] [$i eval \
+ "file join \[file dirname ~$user\] \[file tail ~$user\]"]
+} -cleanup {
+ safe::interpDelete $i
+} -result {./~USER}
+test safe-16.3 {Bug 3529949: defang ~ in globs} -setup {
+ set syntheticHOME [makeDirectory foo]
+ makeFile {} bar $syntheticHOME
+ set savedHOME $env(HOME)
+ set env(HOME) $syntheticHOME
+ set i [safe::interpCreate]
+} -body {
+ ::safe::interpAddToAccessPath $i $syntheticHOME
+ $i eval {glob -nocomplain ~/*}
+} -cleanup {
+ safe::interpDelete $i
+ set env(HOME) $savedHOME
+ removeDirectory $syntheticHOME
+} -result {}
+test safe-16.4 {Bug 3529949: defang ~user in globs} -setup {
+ set i [safe::interpCreate]
+} -body {
+ ::safe::interpAddToAccessPath $i $~$tcl_platform(user)
+ $i eval [list glob -nocomplain ~$tcl_platform(user)/*]
+} -cleanup {
+ safe::interpDelete $i
+} -result {}
+
+set ::auto_path $saveAutoPath
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/scan.test b/library/msgcat/tests/scan.test
new file mode 100644
index 0000000..97ad5eb
--- /dev/null
+++ b/library/msgcat/tests/scan.test
@@ -0,0 +1,773 @@
+# Commands covered: scan
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint wideIs64bit \
+ [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}]
+
+test scan-1.1 {BuildCharSet, CharInSet} {
+ list [scan foo {%[^o]} x] $x
+} {1 f}
+test scan-1.2 {BuildCharSet, CharInSet} {
+ list [scan \]foo {%[]f]} x] $x
+} {1 \]f}
+test scan-1.3 {BuildCharSet, CharInSet} {
+ list [scan abc-def {%[a-c]} x] $x
+} {1 abc}
+test scan-1.4 {BuildCharSet, CharInSet} {
+ list [scan abc-def {%[a-c]} x] $x
+} {1 abc}
+test scan-1.5 {BuildCharSet, CharInSet} {
+ list [scan -abc-def {%[-ac]} x] $x
+} {1 -a}
+test scan-1.6 {BuildCharSet, CharInSet} {
+ list [scan -abc-def {%[ac-]} x] $x
+} {1 -a}
+test scan-1.7 {BuildCharSet, CharInSet} {
+ list [scan abc-def {%[c-a]} x] $x
+} {1 abc}
+test scan-1.8 {BuildCharSet, CharInSet} {
+ list [scan def-abc {%[^c-a]} x] $x
+} {1 def-}
+test scan-1.9 {BuildCharSet, CharInSet no match} {
+ catch {unset x}
+ list [scan {= f} {= %[TF]} x] [info exists x]
+} {0 0}
+
+test scan-2.1 {ReleaseCharSet} {
+ list [scan abcde {%[abc]} x] $x
+} {1 abc}
+test scan-2.2 {ReleaseCharSet} {
+ list [scan abcde {%[a-c]} x] $x
+} {1 abc}
+
+test scan-3.1 {ValidateFormat} {
+ list [catch {scan {} {%d%1$d} x} msg] $msg
+} {1 {cannot mix "%" and "%n$" conversion specifiers}}
+test scan-3.2 {ValidateFormat} {
+ list [catch {scan {} {%d%1$d} x} msg] $msg
+} {1 {cannot mix "%" and "%n$" conversion specifiers}}
+test scan-3.3 {ValidateFormat} {
+ list [catch {scan {} {%2$d%d} x} msg] $msg
+} {1 {"%n$" argument index out of range}}
+test scan-3.4 {ValidateFormat} {
+ # degenerate case, before changed from 8.2 to 8.3
+ list [catch {scan {} %d} msg] $msg
+} {0 {}}
+test scan-3.5 {ValidateFormat} {
+ list [catch {scan {} {%10c} a} msg] $msg
+} {1 {field width may not be specified in %c conversion}}
+test scan-3.6 {ValidateFormat} {
+ list [catch {scan {} {%*1$d} a} msg] $msg
+} {1 {bad scan conversion character "$"}}
+test scan-3.7 {ValidateFormat} {
+ list [catch {scan {} {%1$d%1$d} a} msg] $msg
+} {1 {variable is assigned by multiple "%n$" conversion specifiers}}
+test scan-3.8 {ValidateFormat} {
+ list [catch {scan {} a x} msg] $msg
+} {1 {variable is not assigned by any conversion specifiers}}
+test scan-3.9 {ValidateFormat} {
+ list [catch {scan {} {%2$s} x y} msg] $msg
+} {1 {variable is not assigned by any conversion specifiers}}
+test scan-3.10 {ValidateFormat} {
+ list [catch {scan {} {%[a} x} msg] $msg
+} {1 {unmatched [ in format string}}
+test scan-3.11 {ValidateFormat} {
+ list [catch {scan {} {%[^a} x} msg] $msg
+} {1 {unmatched [ in format string}}
+test scan-3.12 {ValidateFormat} {
+ list [catch {scan {} {%[]a} x} msg] $msg
+} {1 {unmatched [ in format string}}
+test scan-3.13 {ValidateFormat} {
+ list [catch {scan {} {%[^]a} x} msg] $msg
+} {1 {unmatched [ in format string}}
+
+test scan-4.1 {Tcl_ScanObjCmd, argument checks} {
+ list [catch {scan} msg] $msg
+} {1 {wrong # args: should be "scan string format ?varName ...?"}}
+test scan-4.2 {Tcl_ScanObjCmd, argument checks} {
+ list [catch {scan string} msg] $msg
+} {1 {wrong # args: should be "scan string format ?varName ...?"}}
+test scan-4.3 {Tcl_ScanObjCmd, argument checks} {
+ # degenerate case, before changed from 8.2 to 8.3
+ list [catch {scan string format} msg] $msg
+} {0 {}}
+test scan-4.4 {Tcl_ScanObjCmd, whitespace} {
+ list [scan { abc def } {%s%s} x y] $x $y
+} {2 abc def}
+test scan-4.5 {Tcl_ScanObjCmd, whitespace} {
+ list [scan { abc def } { %s %s } x y] $x $y
+} {2 abc def}
+test scan-4.6 {Tcl_ScanObjCmd, whitespace} {
+ list [scan { abc def } { %s %s } x y] $x $y
+} {2 abc def}
+test scan-4.7 {Tcl_ScanObjCmd, literals} {
+ # degenerate case, before changed from 8.2 to 8.3
+ scan { abc def } { abc def }
+} {}
+test scan-4.8 {Tcl_ScanObjCmd, literals} {
+ set x {}
+ list [scan { abcg} { abc def %1s} x] $x
+} {0 {}}
+test scan-4.9 {Tcl_ScanObjCmd, literals} {
+ list [scan { abc%defghi} { abc %% def%n } x] $x
+} {1 10}
+test scan-4.10 {Tcl_ScanObjCmd, assignment suppression} {
+ list [scan { abc def } { %*c%s def } x] $x
+} {1 bc}
+test scan-4.11 {Tcl_ScanObjCmd, XPG3-style} {
+ list [scan { abc def } {%2$s %1$s} x y] $x $y
+} {2 def abc}
+test scan-4.12 {Tcl_ScanObjCmd, width specifiers} {
+ list [scan {abc123456789012} {%3s%3d%3f%3[0-9]%s} a b c d e] $a $b $c $d $e
+} {5 abc 123 456.0 789 012}
+test scan-4.13 {Tcl_ScanObjCmd, width specifiers} {
+ list [scan {abc123456789012} {%3s%3d%3f%3[0-9]%s} a b c d e] $a $b $c $d $e
+} {5 abc 123 456.0 789 012}
+test scan-4.14 {Tcl_ScanObjCmd, underflow} {
+ set x {}
+ list [scan {a} {a%d} x] $x
+} {-1 {}}
+test scan-4.15 {Tcl_ScanObjCmd, underflow} {
+ set x {}
+ list [scan {} {a%d} x] $x
+} {-1 {}}
+test scan-4.16 {Tcl_ScanObjCmd, underflow} {
+ set x {}
+ list [scan {ab} {a%d} x] $x
+} {0 {}}
+test scan-4.17 {Tcl_ScanObjCmd, underflow} {
+ set x {}
+ list [scan {a } {a%d} x] $x
+} {-1 {}}
+test scan-4.18 {Tcl_ScanObjCmd, skipping whitespace} {
+ list [scan { b} {%c%s} x y] $x $y
+} {2 32 b}
+test scan-4.19 {Tcl_ScanObjCmd, skipping whitespace} {
+ list [scan { b} {%[^b]%s} x y] $x $y
+} {2 { } b}
+test scan-4.20 {Tcl_ScanObjCmd, string scanning} {
+ list [scan {abc def} {%s} x] $x
+} {1 abc}
+test scan-4.21 {Tcl_ScanObjCmd, string scanning} {
+ list [scan {abc def} {%0s} x] $x
+} {1 abc}
+test scan-4.22 {Tcl_ScanObjCmd, string scanning} {
+ list [scan {abc def} {%2s} x] $x
+} {1 ab}
+test scan-4.23 {Tcl_ScanObjCmd, string scanning} {
+ list [scan {abc def} {%*s%n} x] $x
+} {1 3}
+test scan-4.24 {Tcl_ScanObjCmd, charset scanning} {
+ list [scan {abcdef} {%[a-c]} x] $x
+} {1 abc}
+test scan-4.25 {Tcl_ScanObjCmd, charset scanning} {
+ list [scan {abcdef} {%0[a-c]} x] $x
+} {1 abc}
+test scan-4.26 {Tcl_ScanObjCmd, charset scanning} {
+ list [scan {abcdef} {%2[a-c]} x] $x
+} {1 ab}
+test scan-4.27 {Tcl_ScanObjCmd, charset scanning} {
+ list [scan {abcdef} {%*[a-c]%n} x] $x
+} {1 3}
+test scan-4.28 {Tcl_ScanObjCmd, character scanning} {
+ list [scan {abcdef} {%c} x] $x
+} {1 97}
+test scan-4.29 {Tcl_ScanObjCmd, character scanning} {
+ list [scan {abcdef} {%*c%n} x] $x
+} {1 1}
+
+test scan-4.30 {Tcl_ScanObjCmd, base-10 integer scanning} {
+ set x {}
+ list [scan {1234567890a} {%3d} x] $x
+} {1 123}
+test scan-4.31 {Tcl_ScanObjCmd, base-10 integer scanning} {
+ set x {}
+ list [scan {1234567890a} {%d} x] $x
+} {1 1234567890}
+test scan-4.32 {Tcl_ScanObjCmd, base-10 integer scanning} {
+ set x {}
+ list [scan {01234567890a} {%d} x] $x
+} {1 1234567890}
+test scan-4.33 {Tcl_ScanObjCmd, base-10 integer scanning} {
+ set x {}
+ list [scan {+01234} {%d} x] $x
+} {1 1234}
+test scan-4.34 {Tcl_ScanObjCmd, base-10 integer scanning} {
+ set x {}
+ list [scan {-01234} {%d} x] $x
+} {1 -1234}
+test scan-4.35 {Tcl_ScanObjCmd, base-10 integer scanning} {
+ set x {}
+ list [scan {a01234} {%d} x] $x
+} {0 {}}
+test scan-4.36 {Tcl_ScanObjCmd, base-10 integer scanning} {
+ set x {}
+ list [scan {0x10} {%d} x] $x
+} {1 0}
+test scan-4.37 {Tcl_ScanObjCmd, base-8 integer scanning} {
+ set x {}
+ list [scan {012345678} {%o} x] $x
+} {1 342391}
+test scan-4.38 {Tcl_ScanObjCmd, base-8 integer scanning} {
+ set x {}
+ list [scan {+1238 -1239 123a} {%o%*s%o%*s%o} x y z] $x $y $z
+} {3 83 -83 83}
+test scan-4.39 {Tcl_ScanObjCmd, base-16 integer scanning} {
+ set x {}
+ list [scan {+1238 -123a 0123} {%x%x%x} x y z] $x $y $z
+} {3 4664 -4666 291}
+test scan-4.40 {Tcl_ScanObjCmd, base-16 integer scanning} {
+ # The behavior changed in 8.4a4/8.3.4cvs (6 Feb) to correctly
+ # return '1' for 0x1 scanned via %x, to comply with 8.0 and C scanf.
+ # Bug #495213
+ set x {}
+ list [scan {aBcDeF AbCdEf 0x1} {%x%x%x} x y z] $x $y $z
+} {3 11259375 11259375 1}
+test scan-4.40.1 {Tcl_ScanObjCmd, base-16 integer scanning} {
+ set x {}
+ list [scan {0xF 0x00A0B 0X0XF} {%x %x %x} x y z] $x $y $z
+} {3 15 2571 0}
+test scan-4.40.2 {Tcl_ScanObjCmd, base-16 integer scanning} {
+ catch {unset x}
+ list [scan {xF} {%x} x] [info exists x]
+} {0 0}
+test scan-4.40.3 {Tcl_ScanObjCmd, base-2 integer scanning} {
+ set x {}
+ list [scan {1001 0b101 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000} {%b %b %llb} x y z] $x $y $z
+} {3 9 5 340282366920938463463374607431768211456}
+test scan-4.41 {Tcl_ScanObjCmd, base-unknown integer scanning} {
+ set x {}
+ list [scan {10 010 0x10 0b10} {%i%i%i%i} x y z t] $x $y $z $t
+} {4 10 8 16 0}
+test scan-4.42 {Tcl_ScanObjCmd, base-unknown integer scanning} {
+ set x {}
+ list [scan {10 010 0X10} {%i%i%i} x y z] $x $y $z
+} {3 10 8 16}
+test scan-4.43 {Tcl_ScanObjCmd, integer scanning, odd cases} {
+ set x {}
+ list [scan {+ } {%i} x] $x
+} {0 {}}
+test scan-4.44 {Tcl_ScanObjCmd, integer scanning, odd cases} {
+ set x {}
+ list [scan {+} {%i} x] $x
+} {-1 {}}
+test scan-4.45 {Tcl_ScanObjCmd, integer scanning, odd cases} {
+ set x {}
+ list [scan {0x} {%i%s} x y] $x $y
+} {2 0 x}
+test scan-4.46 {Tcl_ScanObjCmd, integer scanning, odd cases} {
+ set x {}
+ list [scan {0X} {%i%s} x y] $x $y
+} {2 0 X}
+test scan-4.47 {Tcl_ScanObjCmd, integer scanning, suppressed} {
+ set x {}
+ list [scan {123def} {%*i%s} x] $x
+} {1 def}
+test scan-4.48 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {1 2 3} {%e %f %g} x y z] $x $y $z
+} {3 1.0 2.0 3.0}
+test scan-4.49 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {.1 0.2 3.} {%e %f %g} x y z] $x $y $z
+} {3 0.1 0.2 3.0}
+test scan-4.50 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {1234567890a} %f x] $x
+} {1 1234567890.0}
+test scan-4.51 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {+123+45} %f x] $x
+} {1 123.0}
+test scan-4.52 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {-123+45} %f x] $x
+} {1 -123.0}
+test scan-4.53 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {1.0e1} %f x] $x
+} {1 10.0}
+test scan-4.54 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {1.0e-1} %f x] $x
+} {1 0.1}
+test scan-4.55 {Tcl_ScanObjCmd, odd cases} {
+ set x {}
+ list [scan {+} %f x] $x
+} {-1 {}}
+test scan-4.56 {Tcl_ScanObjCmd, odd cases} {
+ set x {}
+ list [scan {1.0e} %f%s x y] $x $y
+} {2 1.0 e}
+test scan-4.57 {Tcl_ScanObjCmd, odd cases} {
+ set x {}
+ list [scan {1.0e+} %f%s x y] $x $y
+} {2 1.0 e+}
+test scan-4.58 {Tcl_ScanObjCmd, odd cases} {
+ set x {}
+ set y {}
+ list [scan {e1} %f%s x y] $x $y
+} {0 {} {}}
+test scan-4.59 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {1.0e-1x} %*f%n x] $x
+} {1 6}
+
+test scan-4.60 {Tcl_ScanObjCmd, set errors} {
+ set x {}
+ set y {}
+ catch {unset z}; array set z {}
+ set result [list [catch {scan {abc def ghi} {%s%s%s} x z y} msg] \
+ $msg $x $y]
+ unset z
+ set result
+} {1 {can't set "z": variable is array} abc ghi}
+test scan-4.61 {Tcl_ScanObjCmd, set errors} {
+ set x {}
+ catch {unset y}; array set y {}
+ catch {unset z}; array set z {}
+ set result [list [catch {scan {abc def ghi} {%s%s%s} x z y} msg] \
+ $msg $x]
+ unset y
+ unset z
+ set result
+} {1 {can't set "z": variable is array} abc}
+
+# procedure that returns the range of integers
+
+proc int_range {} {
+ for { set MIN_INT 1 } { int($MIN_INT) > 0 } {} {
+ set MIN_INT [expr { $MIN_INT << 1 }]
+ }
+ set MIN_INT [expr {int($MIN_INT)}]
+ set MAX_INT [expr { ~ $MIN_INT }]
+ return [list $MIN_INT $MAX_INT]
+}
+
+test scan-4.62 {scanning of large and negative octal integers} {
+ foreach { MIN_INT MAX_INT } [int_range] {}
+ set scanstring [format {%o %o %o} -1 $MIN_INT $MAX_INT]
+ list [scan $scanstring {%o %o %o} a b c] \
+ [expr { $a == -1 }] [expr { $b == $MIN_INT }] [expr { $c == $MAX_INT }]
+} {3 1 1 1}
+test scan-4.63 {scanning of large and negative hex integers} {
+ foreach { MIN_INT MAX_INT } [int_range] {}
+ set scanstring [format {%x %x %x} -1 $MIN_INT $MAX_INT]
+ list [scan $scanstring {%x %x %x} a b c] \
+ [expr { $a == -1 }] [expr { $b == $MIN_INT }] [expr { $c == $MAX_INT }]
+} {3 1 1 1}
+
+# clean up from last two tests
+
+catch {
+ rename int_range {}
+}
+
+test scan-5.1 {integer scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "-20 1476 \n33 0" "%d %d %d %d" a b c d] $a $b $c $d
+} {4 -20 1476 33 0}
+test scan-5.2 {integer scanning} {
+ set a {}; set b {}; set c {}
+ list [scan "-45 16 7890 +10" "%2d %*d %10d %d" a b c] $a $b $c
+} {3 -4 16 7890}
+test scan-5.3 {integer scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "-45 16 +10 987" "%ld %d %ld %d" a b c d] $a $b $c $d
+} {4 -45 16 10 987}
+test scan-5.4 {integer scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "14 1ab 62 10" "%d %x %lo %x" a b c d] $a $b $c $d
+} {4 14 427 50 16}
+test scan-5.5 {integer scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "12345670 1234567890ab cdefg" "%o %o %x %lx" a b c d] \
+ $a $b $c $d
+} {4 2739128 342391 561323 52719}
+test scan-5.6 {integer scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "ab123-24642" "%2x %3x %3o %2o" a b c d] $a $b $c $d
+} {4 171 291 -20 52}
+test scan-5.7 {integer scanning} {
+ set a {}; set b {}
+ list [scan "1234567 234 567 " "%*3x %x %*o %4o" a b] $a $b
+} {2 17767 375}
+test scan-5.8 {integer scanning} {
+ set a {}; set b {}
+ list [scan "a 1234" "%d %d" a b] $a $b
+} {0 {} {}}
+test scan-5.9 {integer scanning} {
+ set a {}; set b {}; set c {}; set d {};
+ list [scan "12345678" "%2d %2d %2ld %2d" a b c d] $a $b $c $d
+} {4 12 34 56 78}
+test scan-5.10 {integer scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "1 2 " "%hd %d %d %d" a b c d] $a $b $c $d
+} {2 1 2 {} {}}
+#
+# The behavior for scaning intergers larger than MAX_INT is
+# not defined by the ANSI spec. Some implementations wrap the
+# input (-16) some return MAX_INT.
+#
+test scan-5.11 {integer scanning} {nonPortable} {
+ set a {}; set b {};
+ list [scan "4294967280 4294967280" "%u %d" a b] $a \
+ [expr {$b == -16 || $b == 0x7fffffff}]
+} {2 4294967280 1}
+test scan-5.12 {integer scanning} {wideIs64bit} {
+ set a {}; set b {}; set c {}
+ list [scan "7810179016327718216,6c63546f6c6c6548,661432506755433062510" \
+ %ld,%lx,%lo a b c] $a $b $c
+} {3 7810179016327718216 7810179016327718216 7810179016327718216}
+test scan-5.13 {integer scanning and overflow} {
+ # This test used to fail on some 64-bit systems. [Bug 1011860]
+ scan {300000000 3000000000 30000000000} {%ld %ld %ld}
+} {300000000 3000000000 30000000000}
+
+test scan-5.14 {integer scanning} {
+ scan 0xff %u
+} 0
+
+test scan-6.1 {floating-point scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "2.1 -3.0e8 .99962 a" "%f%g%e%f" a b c d] $a $b $c $d
+} {3 2.1 -300000000.0 0.99962 {}}
+test scan-6.2 {floating-point scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "-1.2345 +8.2 9" "%3e %3lf %f %f" a b c d] $a $b $c $d
+} {4 -1.0 234.0 5.0 8.2}
+test scan-6.3 {floating-point scanning} {
+ set a {}; set b {}; set c {}
+ list [scan "1e00004 332E-4 3e+4" "%Lf %*2e %f %f" a b c] $a $c
+} {3 10000.0 30000.0}
+#
+# Some libc implementations consider 3.e- bad input. The ANSI
+# spec states that digits must follow the - sign.
+#
+test scan-6.4 {floating-point scanning} {
+ set a {}; set b {}; set c {}
+ list [scan "1. 47.6 2.e2 3.e-" "%f %*f %f %f" a b c] $a $b $c
+} {3 1.0 200.0 3.0}
+test scan-6.5 {floating-point scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "4.6 99999.7 876.43e-1 118" "%f %f %f %e" a b c d] $a $b $c $d
+} {4 4.6 99999.7 87.643 118.0}
+test scan-6.6 {floating-point scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "1.2345 697.0e-3 124 .00005" "%f %e %f %e" a b c d] $a $b $c $d
+} {4 1.2345 0.697 124.0 5e-5}
+test scan-6.7 {floating-point scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "4.6abc" "%f %f %f %f" a b c d] $a $b $c $d
+} {1 4.6 {} {} {}}
+test scan-6.8 {floating-point scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "4.6 5.2" "%f %f %f %f" a b c d] $a $b $c $d
+} {2 4.6 5.2 {} {}}
+
+test scan-7.1 {string and character scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "abc defghijk dum " "%s %3s %20s %s" a b c d] $a $b $c $d
+} {4 abc def ghijk dum}
+test scan-7.2 {string and character scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "a bcdef" "%c%c%1s %s" a b c d] $a $b $c $d
+} {4 97 32 b cdef}
+test scan-7.3 {string and character scanning} {
+ set a {}; set b {}; set c {}
+ list [scan "123456 test " "%*c%*s %s %s %s" a b c] $a $b $c
+} {1 test {} {}}
+test scan-7.4 {string and character scanning} {
+ set a {}; set b {}; set c {}; set d
+ list [scan "ababcd01234 f 123450" {%4[abcd] %4[abcd] %[^abcdef] %[^0]} a b c d] $a $b $c $d
+} {4 abab cd {01234 } {f 12345}}
+test scan-7.5 {string and character scanning} {
+ set a {}; set b {}; set c {}
+ list [scan "aaaaaabc aaabcdefg + + XYZQR" {%*4[a] %s %*4[a]%s%*4[ +]%c} a b c] $a $b $c
+} {3 aabc bcdefg 43}
+test scan-7.6 {string and character scanning, unicode} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "abc d\u00c7fghijk dum " "%s %3s %20s %s" a b c d] $a $b $c $d
+} "4 abc d\u00c7f ghijk dum"
+test scan-7.7 {string and character scanning, unicode} {
+ set a {}; set b {}
+ list [scan "ab\u00c7cdef" "ab%c%c" a b] $a $b
+} "2 199 99"
+test scan-7.8 {string and character scanning, unicode} {
+ set a {}; set b {}
+ list [scan "ab\ufeffdef" "%\[ab\ufeff\]" a] $a
+} "1 ab\ufeff"
+
+test scan-8.1 {error conditions} {
+ catch {scan a}
+} 1
+test scan-8.2 {error conditions} {
+ catch {scan a} msg
+ set msg
+} {wrong # args: should be "scan string format ?varName ...?"}
+test scan-8.3 {error conditions} {
+ list [catch {scan a %D x} msg] $msg
+} {1 {bad scan conversion character "D"}}
+test scan-8.4 {error conditions} {
+ list [catch {scan a %O x} msg] $msg
+} {1 {bad scan conversion character "O"}}
+test scan-8.5 {error conditions} {
+ list [catch {scan a %X x} msg] $msg
+} {1 {bad scan conversion character "X"}}
+test scan-8.6 {error conditions} {
+ list [catch {scan a %F x} msg] $msg
+} {1 {bad scan conversion character "F"}}
+test scan-8.7 {error conditions} {
+ list [catch {scan a %E x} msg] $msg
+} {1 {bad scan conversion character "E"}}
+test scan-8.8 {error conditions} {
+ list [catch {scan a "%d %d" a} msg] $msg
+} {1 {different numbers of variable names and field specifiers}}
+test scan-8.9 {error conditions} {
+ list [catch {scan a "%d %d" a b c} msg] $msg
+} {1 {variable is not assigned by any conversion specifiers}}
+test scan-8.10 {error conditions} {
+ set a {}; set b {}; set c {}; set d {}
+ list [expr {[scan " a" " a %d %d %d %d" a b c d] <= 0}] $a $b $c $d
+} {1 {} {} {} {}}
+test scan-8.11 {error conditions} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "1 2" "%d %d %d %d" a b c d] $a $b $c $d
+} {2 1 2 {} {}}
+test scan-8.12 {error conditions} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {scan 44 %d a} msg] $msg
+} {1 {can't set "a": variable is array}}
+test scan-8.13 {error conditions} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {scan 44 %c a} msg] $msg
+} {1 {can't set "a": variable is array}}
+test scan-8.14 {error conditions} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {scan 44 %s a} msg] $msg
+} {1 {can't set "a": variable is array}}
+test scan-8.15 {error conditions} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {scan 44 %f a} msg] $msg
+} {1 {can't set "a": variable is array}}
+test scan-8.16 {error conditions} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {scan 44 %f a} msg] $msg
+} {1 {can't set "a": variable is array}}
+catch {unset a}
+test scan-8.17 {error conditions} {
+ list [catch {scan 44 %2c a} msg] $msg
+} {1 {field width may not be specified in %c conversion}}
+test scan-8.18 {error conditions} {
+ list [catch {scan abc {%[} x} msg] $msg
+} {1 {unmatched [ in format string}}
+test scan-8.19 {error conditions} {
+ list [catch {scan abc {%[^a} x} msg] $msg
+} {1 {unmatched [ in format string}}
+test scan-8.20 {error conditions} {
+ list [catch {scan abc {%[^]a} x} msg] $msg
+} {1 {unmatched [ in format string}}
+test scan-8.21 {error conditions} {
+ list [catch {scan abc {%[]a} x} msg] $msg
+} {1 {unmatched [ in format string}}
+
+test scan-9.1 {lots of arguments} {
+ scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200" "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20
+} 20
+test scan-9.2 {lots of arguments} {
+ scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200" "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20
+ set a20
+} 200
+
+test scan-10.1 {miscellaneous tests} {
+ set a {}
+ list [scan ab16c ab%dc a] $a
+} {1 16}
+test scan-10.2 {miscellaneous tests} {
+ set a {}
+ list [scan ax16c ab%dc a] $a
+} {0 {}}
+test scan-10.3 {miscellaneous tests} {
+ set a {}
+ list [catch {scan ab%c114 ab%%c%d a} msg] $msg $a
+} {0 1 114}
+test scan-10.4 {miscellaneous tests} {
+ set a {}
+ list [catch {scan ab%c14 ab%%c%d a} msg] $msg $a
+} {0 1 14}
+test scan-10.5 {miscellaneous tests} {
+ catch {unset arr}
+ set arr(2) {}
+ list [catch {scan ab%c14 ab%%c%d arr(2)} msg] $msg $arr(2)
+} {0 1 14}
+test scan-10.6 {miscellaneous tests} {
+ scan 5a {%i%[a]}
+} {5 a}
+test scan-10.7 {miscellaneous tests} {
+ scan {5 a} {%i%[a]}
+} {5 {}}
+
+test scan-11.1 {alignment in results array (TCL_ALIGN)} {
+ scan "123 13.6" "%s %f" a b
+ set b
+} 13.6
+test scan-11.2 {alignment in results array (TCL_ALIGN)} {
+ scan "1234567 13.6" "%s %f" a b
+ set b
+} 13.6
+test scan-11.3 {alignment in results array (TCL_ALIGN)} {
+ scan "12345678901 13.6" "%s %f" a b
+ set b
+} 13.6
+test scan-11.4 {alignment in results array (TCL_ALIGN)} {
+ scan "123456789012345 13.6" "%s %f" a b
+ set b
+} 13.6
+test scan-11.5 {alignment in results array (TCL_ALIGN)} {
+ scan "1234567890123456789 13.6" "%s %f" a b
+ set b
+} 13.6
+
+test scan-12.1 {Tcl_ScanObjCmd, inline case} {
+ scan a %c
+} 97
+test scan-12.2 {Tcl_ScanObjCmd, inline case} {
+ scan abc %c%c%c%c
+} {97 98 99 {}}
+test scan-12.3 {Tcl_ScanObjCmd, inline case} {
+ scan abc %s%c
+} {abc {}}
+test scan-12.4 {Tcl_ScanObjCmd, inline case, underflow} {
+ scan abc abc%c
+} {}
+test scan-12.5 {Tcl_ScanObjCmd, inline case} {
+ scan abc bogus%c%c%c
+} {{} {} {}}
+test scan-12.6 {Tcl_ScanObjCmd, inline case} {
+ # degenerate case, behavior changed from 8.2 to 8.3
+ list [catch {scan foo foobar} msg] $msg
+} {0 {}}
+test scan-12.7 {Tcl_ScanObjCmd, inline case lots of arguments} {
+ scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140\
+ 150 160 170 180 190 200" \
+ "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"
+} {10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200 {}}
+
+test scan-13.1 {Tcl_ScanObjCmd, inline XPG case} {
+ scan a {%1$c}
+} 97
+test scan-13.2 {Tcl_ScanObjCmd, inline XPG case} {
+ scan abc {%1$c%2$c%3$c%4$c}
+} {97 98 99 {}}
+test scan-13.3 {Tcl_ScanObjCmd, inline XPG case} {
+ list [catch {scan abc {%1$c%1$c}} msg] $msg
+} {1 {variable is assigned by multiple "%n$" conversion specifiers}}
+test scan-13.4 {Tcl_ScanObjCmd, inline XPG case} {
+ scan abc {%2$s%1$c}
+} {{} abc}
+test scan-13.5 {Tcl_ScanObjCmd, inline XPG case, underflow} {
+ scan abc {abc%5$c}
+} {}
+test scan-13.6 {Tcl_ScanObjCmd, inline XPG case} {
+ catch {scan abc {bogus%1$c%5$c%10$c}} msg
+ list [llength $msg] $msg
+} {10 {{} {} {} {} {} {} {} {} {} {}}}
+test scan-13.7 {Tcl_ScanObjCmd, inline XPG case lots of arguments} {
+ scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200" {%20$d %18$d %17$d %16$d %15$d %14$d %13$d %12$d %11$d %10$d %9$d %8$d %7$d %6$d %5$d %4$d %3$d %2$d %1$d}
+} {190 180 170 160 150 140 130 120 110 100 90 80 70 60 50 40 30 20 {} 10}
+test scan-13.8 {Tcl_ScanObjCmd, inline XPG case lots of arguments} {
+ set msg [scan "10 20 30" {%100$d %5$d %200$d}]
+ list [llength $msg] [lindex $msg 99] [lindex $msg 4] [lindex $msg 199]
+} {200 10 20 30}
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+ variable ieeeValues
+ binary scan [binary format dd -1.0 1.0] c* c
+ switch -exact -- $c {
+ {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+ # little endian
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+ ieeeValues(-Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+ ieeeValues(-Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+ ieeeValues(-Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+ ieeeValues(+Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+ ieeeValues(+Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 1
+ return 1
+ }
+ {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+ binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Infinity)
+ binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Normal)
+ binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Subnormal)
+ binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Normal)
+ binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Infinity)
+ binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 0
+ return 1
+ }
+ default {
+ return 0
+ }
+ }
+}
+
+testConstraint ieeeFloatingPoint [testIEEE]
+
+# scan infinities - not working
+
+test scan-14.1 {infinity} {
+ scan Inf %g d
+ set d
+} Inf
+test scan-14.2 {infinity} {
+ scan -Inf %g d
+ set d
+} -Inf
+
+# TODO - also need to scan NaN's
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/security.test b/library/msgcat/tests/security.test
new file mode 100644
index 0000000..eeabc9c
--- /dev/null
+++ b/library/msgcat/tests/security.test
@@ -0,0 +1,45 @@
+# security.test --
+#
+# Functionality covered: this file contains a collection of tests for the auto
+# loading and namespaces.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# All rights reserved.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# If this proc becomes invoked, then there is a bug
+
+proc BUG {args} {
+ set ::BUG 1
+}
+
+# Check and Clear the bug flag (to do before each test)
+set ::BUG 0
+
+proc CB {} {
+ set ret $::BUG
+ set ::BUG 0
+ return $ret
+}
+
+
+test security-1.1 {tcl_endOfPreviousWord} {
+ catch {tcl_startOfPreviousWord x {[BUG]}}
+ CB
+} 0
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/set-old.test b/library/msgcat/tests/set-old.test
new file mode 100644
index 0000000..52dc0ff
--- /dev/null
+++ b/library/msgcat/tests/set-old.test
@@ -0,0 +1,928 @@
+# Commands covered: set, unset, array
+#
+# This file includes the original set of tests for Tcl's set command.
+# Since the set command is now compiled, a new set of tests covering
+# the new implementation is in the file "set.test". Sourcing this file
+# into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+proc ignore args {}
+
+# Simple variable operations.
+
+catch {unset a}
+test set-old-1.1 {basic variable setting and unsetting} {
+ set a 22
+} 22
+test set-old-1.2 {basic variable setting and unsetting} {
+ set a 123
+ set a
+} 123
+test set-old-1.3 {basic variable setting and unsetting} {
+ set a xxx
+ format %s $a
+} xxx
+test set-old-1.4 {basic variable setting and unsetting} {
+ set a 44
+ unset a
+ list [catch {set a} msg] $msg
+} {1 {can't read "a": no such variable}}
+
+# Basic array operations.
+
+catch {unset a}
+set a(xyz) 2
+set a(44) 3
+set {a(a long name)} test
+test set-old-2.1 {basic array operations} {
+ lsort [array names a]
+} {44 {a long name} xyz}
+test set-old-2.2 {basic array operations} {
+ set a(44)
+} 3
+test set-old-2.3 {basic array operations} {
+ set a(xyz)
+} 2
+test set-old-2.4 {basic array operations} {
+ set "a(a long name)"
+} test
+test set-old-2.5 {basic array operations} {
+ list [catch {set a(other)} msg] $msg
+} {1 {can't read "a(other)": no such element in array}}
+test set-old-2.6 {basic array operations} {
+ list [catch {set a} msg] $msg
+} {1 {can't read "a": variable is array}}
+test set-old-2.7 {basic array operations} {
+ format %s $a(44)
+} 3
+test set-old-2.8 {basic array operations} {
+ format %s $a(a long name)
+} test
+unset a(44)
+test set-old-2.9 {basic array operations} {
+ lsort [array names a]
+} {{a long name} xyz}
+test set-old-2.10 {basic array operations} {
+ catch {unset b}
+ list [catch {set b(123)} msg] $msg
+} {1 {can't read "b(123)": no such variable}}
+test set-old-2.11 {basic array operations} {
+ catch {unset b}
+ set b 44
+ list [catch {set b(123)} msg] $msg
+} {1 {can't read "b(123)": variable isn't array}}
+test set-old-2.12 {basic array operations} {
+ list [catch {set a 14} msg] $msg
+} {1 {can't set "a": variable is array}}
+unset a
+test set-old-2.13 {basic array operations} {
+ list [catch {set a(xyz)} msg] $msg
+} {1 {can't read "a(xyz)": no such variable}}
+
+# Test the set commands, and exercise the corner cases of the code
+# that parses array references into two parts.
+
+test set-old-3.1 {set command} {
+ list [catch {set} msg] $msg
+} {1 {wrong # args: should be "set varName ?newValue?"}}
+test set-old-3.2 {set command} {
+ list [catch {set x y z} msg] $msg
+} {1 {wrong # args: should be "set varName ?newValue?"}}
+test set-old-3.3 {set command} {
+ catch {unset a}
+ list [catch {set a} msg] $msg
+} {1 {can't read "a": no such variable}}
+test set-old-3.4 {set command} {
+ catch {unset a}
+ set a(14) 83
+ list [catch {set a 22} msg] $msg
+} {1 {can't set "a": variable is array}}
+
+# Test the corner-cases of parsing array names, using set and unset.
+
+test set-old-4.1 {parsing array names} {
+ catch {unset a}
+ set a(()) 44
+ list [catch {array names a} msg] $msg
+} {0 ()}
+test set-old-4.2 {parsing array names} {
+ catch {unset a a(abcd}
+ set a(abcd 33
+ info exists a(abcd
+} 1
+test set-old-4.3 {parsing array names} {
+ catch {unset a a(abcd}
+ set a(abcd 33
+ list [catch {array names a} msg] $msg
+} {0 {}}
+test set-old-4.4 {parsing array names} {
+ catch {unset a abcd)}
+ set abcd) 33
+ info exists abcd)
+} 1
+test set-old-4.5 {parsing array names} {
+ set a(bcd yyy
+ catch {unset a}
+ list [catch {set a(bcd} msg] $msg
+} {0 yyy}
+test set-old-4.6 {parsing array names} {
+ catch {unset a}
+ set a 44
+ list [catch {set a(bcd test} msg] $msg
+} {0 test}
+
+# Errors in reading variables
+
+test set-old-5.1 {errors in reading variables} {
+ catch {unset a}
+ list [catch {set a} msg] $msg
+} {1 {can't read "a": no such variable}}
+test set-old-5.2 {errors in reading variables} {
+ catch {unset a}
+ set a 44
+ list [catch {set a(18)} msg] $msg
+} {1 {can't read "a(18)": variable isn't array}}
+test set-old-5.3 {errors in reading variables} {
+ catch {unset a}
+ set a(6) 44
+ list [catch {set a(18)} msg] $msg
+} {1 {can't read "a(18)": no such element in array}}
+test set-old-5.4 {errors in reading variables} {
+ catch {unset a}
+ set a(6) 44
+ list [catch {set a} msg] $msg
+} {1 {can't read "a": variable is array}}
+
+# Errors and other special cases in writing variables
+
+test set-old-6.1 {creating array during write} {
+ catch {unset a}
+ trace var a rwu ignore
+ list [catch {set a(14) 186} msg] $msg [array names a]
+} {0 186 14}
+test set-old-6.2 {errors in writing variables} {
+ catch {unset a}
+ set a xxx
+ list [catch {set a(14) 186} msg] $msg
+} {1 {can't set "a(14)": variable isn't array}}
+test set-old-6.3 {errors in writing variables} {
+ catch {unset a}
+ set a(100) yyy
+ list [catch {set a 2} msg] $msg
+} {1 {can't set "a": variable is array}}
+test set-old-6.4 {expanding variable size} {
+ catch {unset a}
+ list [set a short] [set a "longer name"] [set a "even longer name"] \
+ [set a "a much much truly longer name"]
+} {short {longer name} {even longer name} {a much much truly longer name}}
+
+# Unset command, Tcl_UnsetVar procedures
+
+test set-old-7.1 {unset command} {
+ catch {unset a}; catch {unset b}; catch {unset c}; catch {unset d}
+ set a 44
+ set b 55
+ set c 66
+ set d 77
+ unset a b c
+ list [catch {set a(0) 0}] [catch {set b(0) 0}] [catch {set c(0) 0}] \
+ [catch {set d(0) 0}]
+} {0 0 0 1}
+test set-old-7.2 {unset command} {
+ list [catch {unset} msg] $msg
+} {0 {}}
+# Used to return:
+#{1 {wrong # args: should be "unset ?-nocomplain? ?--? ?varName ...?"}}
+test set-old-7.3 {unset command} {
+ catch {unset a}
+ list [catch {unset a} msg] $msg
+} {1 {can't unset "a": no such variable}}
+test set-old-7.4 {unset command} {
+ catch {unset a}
+ set a 44
+ list [catch {unset a(14)} msg] $msg
+} {1 {can't unset "a(14)": variable isn't array}}
+test set-old-7.5 {unset command} {
+ catch {unset a}
+ set a(0) xx
+ list [catch {unset a(14)} msg] $msg
+} {1 {can't unset "a(14)": no such element in array}}
+test set-old-7.6 {unset command} {
+ catch {unset a}; catch {unset b}; catch {unset c}
+ set a foo
+ set c gorp
+ list [catch {unset a a a(14)} msg] $msg [info exists c]
+} {1 {can't unset "a": no such variable} 1}
+test set-old-7.7 {unsetting globals from within procedures} {
+ set y 0
+ proc p1 {} {
+ global y
+ set z [p2]
+ return [list $z [catch {set y} msg] $msg]
+ }
+ proc p2 {} {global y; unset y; list [catch {set y} msg] $msg}
+ p1
+} {{1 {can't read "y": no such variable}} 1 {can't read "y": no such variable}}
+test set-old-7.8 {unsetting globals from within procedures} {
+ set y 0
+ proc p1 {} {
+ global y
+ p2
+ return [list [catch {set y 44} msg] $msg]
+ }
+ proc p2 {} {global y; unset y}
+ concat [p1] [list [catch {set y} msg] $msg]
+} {0 44 0 44}
+test set-old-7.9 {unsetting globals from within procedures} {
+ set y 0
+ proc p1 {} {
+ global y
+ unset y
+ return [list [catch {set y 55} msg] $msg]
+ }
+ concat [p1] [list [catch {set y} msg] $msg]
+} {0 55 0 55}
+test set-old-7.10 {unset command} {
+ catch {unset a}
+ set a(14) 22
+ unset a(14)
+ list [catch {set a(14)} msg] $msg [catch {array names a} msg2] $msg2
+} {1 {can't read "a(14)": no such element in array} 0 {}}
+test set-old-7.11 {unset command} {
+ catch {unset a}
+ set a(14) 22
+ unset a
+ list [catch {set a(14)} msg] $msg [catch {array names a} msg2] $msg2
+} {1 {can't read "a(14)": no such variable} 0 {}}
+test set-old-7.12 {unset command, -nocomplain} {
+ catch {unset a}
+ list [info exists a] [catch {unset -nocomplain a}] [info exists a]
+} {0 0 0}
+test set-old-7.13 {unset command, -nocomplain} {
+ set -nocomplain abc
+ list [info exists -nocomplain] [catch {unset -nocomplain}] \
+ [info exists -nocomplain] [catch {unset -- -nocomplain}] \
+ [info exists -nocomplain]
+} {1 0 1 0 0}
+test set-old-7.14 {unset command, --} {
+ set -- abc
+ list [info exists --] [catch {unset --}] \
+ [info exists --] [catch {unset -- --}] \
+ [info exists --]
+} {1 0 1 0 0}
+test set-old-7.15 {unset command, -nocomplain} {
+ set -nocomplain abc
+ set -- abc
+ list [info exists -nocomplain] [catch {unset -- -nocomplain}] \
+ [info exists -nocomplain] [info exists --] \
+ [catch {unset -- -nocomplain}] [info exists --] \
+ [catch {unset -- --}] [info exists --]
+} {1 0 0 1 1 1 0 0}
+test set-old-7.16 {unset command, -nocomplain} {
+ set -nocomplain abc
+ set var abc
+ list [info exists bogus] [catch {unset -nocomplain bogus var bogus}] \
+ [info exists -nocomplain] [info exists var] \
+ [catch {unset -nocomplain -nocomplain}] [info exists -nocomplain]
+} {0 0 1 0 0 0}
+test set-old-7.17 {unset command, -nocomplain (no abbreviation)} {
+ set -nocomp abc
+ list [info exists -nocomp] [catch {unset -nocomp}] [info exists -nocomp]
+} {1 0 0}
+test set-old-7.18 {unset command, -nocomplain (no abbreviation)} {
+ catch {unset -nocomp}
+ list [info exists -nocomp] [catch {unset -nocomp}]
+} {0 1}
+
+# Array command.
+
+test set-old-8.1 {array command} {
+ list [catch {array} msg] $msg
+} {1 {wrong # args: should be "array subcommand ?arg ...?"}}
+test set-old-8.2 {array command} {
+ list [catch {array a} msg] $msg
+} {1 {wrong # args: should be "array anymore arrayName searchId"}}
+test set-old-8.3 {array command} {
+ catch {unset a}
+ list [catch {array anymore a b} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.4 {array command} {
+ catch {unset a}
+ set a 44
+ list [catch {array anymore a b} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.5 {array command} {
+ proc foo {} {
+ set a 44
+ upvar 0 a x
+ list [catch {array anymore x b} msg] $msg
+ }
+ foo
+} {1 {"x" isn't an array}}
+test set-old-8.6 {array command} {
+ catch {unset a}
+ set a(22) 3
+ list [catch {array gorp a} msg] $msg
+} {1 {unknown or ambiguous subcommand "gorp": must be anymore, donesearch, exists, get, names, nextelement, set, size, startsearch, statistics, or unset}}
+test set-old-8.7 {array command, anymore option} {
+ catch {unset a}
+ list [catch {array anymore a x} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.8 {array command, anymore option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ proc foo {x} {
+ if {$x==1} {
+ return [array anymore a x]
+ }
+ set a(x) 123
+ }
+ list [catch {foo 1} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.9 {array command, donesearch option} {
+ catch {unset a}
+ list [catch {array donesearch a x} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.10 {array command, donesearch option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ proc foo {x} {
+ if {$x==1} {
+ return [array donesearch a x]
+ }
+ set a(x) 123
+ }
+ list [catch {foo 1} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.11 {array command, exists option} {
+ list [catch {array exists a b} msg] $msg
+} {1 {wrong # args: should be "array exists arrayName"}}
+test set-old-8.12 {array command, exists option} {
+ catch {unset a}
+ array exists a
+} {0}
+test set-old-8.13 {array command, exists option} {
+ catch {unset a}
+ set a(0) 1
+ array exists a
+} {1}
+test set-old-8.14 {array command, exists option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ proc foo {x} {
+ if {$x==1} {
+ return [array exists a]
+ }
+ set a(x) 123
+ }
+ list [catch {foo 1} msg] $msg
+} {0 0}
+test set-old-8.15 {array command, get option} {
+ list [catch {array get} msg] $msg
+} {1 {wrong # args: should be "array get arrayName ?pattern?"}}
+test set-old-8.16 {array command, get option} {
+ list [catch {array get a b c} msg] $msg
+} {1 {wrong # args: should be "array get arrayName ?pattern?"}}
+test set-old-8.17 {array command, get option} {
+ catch {unset a}
+ array get a
+} {}
+test set-old-8.18 {array command, get option} {
+ catch {unset a}
+ set a(22) 3
+ set {a(long name)} {}
+ lsort [array get a]
+} {{} 22 3 {long name}}
+test set-old-8.19 {array command, get option (unset variable)} {
+ catch {unset a}
+ set a(x) 3
+ trace var a(y) w ignore
+ array get a
+} {x 3}
+test set-old-8.20 {array command, get option, with pattern} {
+ catch {unset a}
+ set a(x1) 3
+ set a(x2) 4
+ set a(x3) 5
+ set a(b1) 24
+ set a(b2) 25
+ lsort [array get a x*]
+} {3 4 5 x1 x2 x3}
+test set-old-8.21 {array command, get option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ proc foo {x} {
+ if {$x==1} {
+ return [array get a]
+ }
+ set a(x) 123
+ }
+ list [catch {foo 1} msg] $msg
+} {0 {}}
+test set-old-8.22 {array command, names option} {
+ catch {unset a}
+ set a(22) 3
+ list [catch {array names a 4 5} msg] $msg
+} {1 {bad option "4": must be -exact, -glob, or -regexp}}
+test set-old-8.23 {array command, names option} {
+ catch {unset a}
+ array names a
+} {}
+test set-old-8.24 {array command, names option} {
+ catch {unset a}
+ set a(22) 3; set a(Textual_name) 44; set "a(name with spaces)" xxx
+ list [catch {lsort [array names a]} msg] $msg
+} {0 {22 Textual_name {name with spaces}}}
+test set-old-8.25 {array command, names option} {
+ catch {unset a}
+ set a(22) 3; set a(33) 44;
+ trace var a(xxx) w ignore
+ list [catch {lsort [array names a]} msg] $msg
+} {0 {22 33}}
+test set-old-8.26 {array command, names option} {
+ catch {unset a}
+ set a(22) 3; set a(33) 44;
+ trace var a(xxx) w ignore
+ set a(xxx) value
+ list [catch {lsort [array names a]} msg] $msg
+} {0 {22 33 xxx}}
+test set-old-8.27 {array command, names option} {
+ catch {unset a}
+ set a(axy) 3
+ set a(bxy) 44
+ set a(no) yes
+ set a(xxx) value
+ list [lsort [array names a *xy]] [lsort [array names a]]
+} {{axy bxy} {axy bxy no xxx}}
+test set-old-8.28 {array command, names option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ proc foo {x} {
+ if {$x==1} {
+ return [array names a]
+ }
+ set a(x) 123
+ }
+ list [catch {foo 1} msg] $msg
+} {0 {}}
+test set-old-8.29 {array command, nextelement option} {
+ list [catch {array nextelement a} msg] $msg
+} {1 {wrong # args: should be "array nextelement arrayName searchId"}}
+test set-old-8.30 {array command, nextelement option} {
+ catch {unset a}
+ list [catch {array nextelement a b} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.31 {array command, nextelement option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ proc foo {x} {
+ if {$x==1} {
+ return [array nextelement a b]
+ }
+ set a(x) 123
+ }
+ list [catch {foo 1} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.32 {array command, set option} {
+ list [catch {array set a} msg] $msg
+} {1 {wrong # args: should be "array set arrayName list"}}
+test set-old-8.33 {array command, set option} {
+ list [catch {array set a 1 2} msg] $msg
+} {1 {wrong # args: should be "array set arrayName list"}}
+test set-old-8.34 {array command, set option} {
+ list [catch {array set a "a \{ c"} msg] $msg
+} {1 {unmatched open brace in list}}
+test set-old-8.35 {array command, set option} {
+ catch {unset a}
+ set a 44
+ list [catch {array set a {a b c d}} msg] $msg
+} {1 {can't set "a(a)": variable isn't array}}
+test set-old-8.36 {array command, set option} {
+ catch {unset a}
+ set a(xx) yy
+ array set a {b c d e}
+ lsort [array get a]
+} {b c d e xx yy}
+test set-old-8.37 {array command, set option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ proc foo {x} {
+ if {$x==1} {
+ return [array set a {x 0}]
+ }
+ set a(x)
+ }
+ list [catch {foo 1} msg] $msg
+} {0 {}}
+test set-old-8.38 {array command, set option} {
+ catch {unset aVaRnAmE}
+ array set aVaRnAmE {}
+ list [info exists aVaRnAmE] [catch {set aVaRnAmE} msg] $msg
+} {1 1 {can't read "aVaRnAmE": variable is array}}
+test set-old-8.38.1 {array command, set scalar} {
+ catch {unset aVaRnAmE}
+ set aVaRnAmE 1
+ list [catch {array set aVaRnAmE {}} msg] $msg
+} {1 {can't array set "aVaRnAmE": variable isn't array}}
+test set-old-8.38.2 {array command, set alias} {
+ catch {unset aVaRnAmE}
+ upvar 0 aVaRnAmE anAliAs
+ array set anAliAs {}
+ list [array exists aVaRnAmE] [catch {set anAliAs} msg] $msg
+} {1 1 {can't read "anAliAs": variable is array}}
+test set-old-8.38.3 {array command, set element alias} {
+ catch {unset aVaRnAmE}
+ list [catch {upvar 0 aVaRnAmE(elem) elemAliAs}] \
+ [catch {array set elemAliAs {}} msg] $msg
+} {0 1 {can't array set "elemAliAs": variable isn't array}}
+test set-old-8.38.4 {array command, empty set with populated array} {
+ catch {unset aVaRnAmE}
+ array set aVaRnAmE [list e1 v1 e2 v2]
+ array set aVaRnAmE {}
+ array set aVaRnAmE [list e3 v3]
+ list [lsort [array names aVaRnAmE]] [catch {set aVaRnAmE(e2)} msg] $msg
+} {{e1 e2 e3} 0 v2}
+test set-old-8.38.5 {array command, set with non-existent namespace} {
+ list [catch {array set bogusnamespace::var {}} msg] $msg
+} {1 {can't set "bogusnamespace::var": parent namespace doesn't exist}}
+test set-old-8.38.6 {array command, set with non-existent namespace} {
+ list [catch {array set bogusnamespace::var {a b}} msg] $msg
+} {1 {can't set "bogusnamespace::var": parent namespace doesn't exist}}
+test set-old-8.38.7 {array command, set with non-existent namespace} {
+ list [catch {array set bogusnamespace::var(0) {a b}} msg] $msg
+} {1 {can't set "bogusnamespace::var(0)": parent namespace doesn't exist}}
+test set-old-8.39 {array command, size option} {
+ catch {unset a}
+ array size a
+} {0}
+test set-old-8.40 {array command, size option} {
+ list [catch {array size a 4} msg] $msg
+} {1 {wrong # args: should be "array size arrayName"}}
+test set-old-8.41 {array command, size option} {
+ catch {unset a}
+ array size a
+} {0}
+test set-old-8.42 {array command, size option} {
+ catch {unset a}
+ set a(22) 3; set a(Textual_name) 44; set "a(name with spaces)" xxx
+ list [catch {array size a} msg] $msg
+} {0 3}
+test set-old-8.43 {array command, size option} {
+ catch {unset a}
+ set a(22) 3; set a(xx) 44; set a(y) xxx
+ unset a(22) a(y) a(xx)
+ list [catch {array size a} msg] $msg
+} {0 0}
+test set-old-8.44 {array command, size option} {
+ catch {unset a}
+ set a(22) 3;
+ trace var a(33) rwu ignore
+ list [catch {array size a} msg] $msg
+} {0 1}
+test set-old-8.45 {array command, size option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ proc foo {x} {
+ if {$x==1} {
+ return [array size a]
+ }
+ set a(x) 123
+ }
+ list [catch {foo 1} msg] $msg
+} {0 0}
+test set-old-8.46 {array command, startsearch option} {
+ list [catch {array startsearch a b} msg] $msg
+} {1 {wrong # args: should be "array startsearch arrayName"}}
+test set-old-8.47 {array command, startsearch option} {
+ catch {unset a}
+ list [catch {array startsearch a} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.48 {array command, startsearch option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ catch {rename p ""}
+ proc p {x} {
+ if {$x==1} {
+ return [array startsearch a]
+ }
+ set a(x) 123
+ }
+ list [catch {p 1} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.49 {array command, statistics option} {
+ catch {unset a}
+ set a(abc) 1
+ set a(def) 2
+ set a(ghi) 3
+ set a(jkl) 4
+ set a(mno) 5
+ set a(pqr) 6
+ set a(stu) 7
+ set a(vwx) 8
+ set a(yz) 9
+ array statistics a
+} "9 entries in table, 4 buckets
+number of buckets with 0 entries: 0
+number of buckets with 1 entries: 0
+number of buckets with 2 entries: 3
+number of buckets with 3 entries: 1
+number of buckets with 4 entries: 0
+number of buckets with 5 entries: 0
+number of buckets with 6 entries: 0
+number of buckets with 7 entries: 0
+number of buckets with 8 entries: 0
+number of buckets with 9 entries: 0
+number of buckets with 10 or more entries: 0
+average search distance for entry: 1.7"
+test set-old-8.50 {array command, array names -exact on glob pattern} {
+ catch {unset a}
+ set a(1*2) 1
+ list [catch {array names a -exact 1*2} msg] $msg
+} {0 1*2}
+test set-old-8.51 {array command, array names -glob on glob pattern} {
+ catch {unset a}
+ set a(1*2) 1
+ set a(12) 1
+ set a(11) 1
+ list [catch {lsort [array names a -glob 1*2]} msg] $msg
+} {0 {1*2 12}}
+test set-old-8.52 {array command, array names -regexp on regexp pattern} {
+ catch {unset a}
+ set a(1*2) 1
+ set a(12) 1
+ set a(11) 1
+ list [catch {lsort [array names a -regexp ^1]} msg] $msg
+} {0 {1*2 11 12}}
+test set-old-8.53 {array command, array names -regexp} {
+ catch {unset a}
+ set a(-glob) 1
+ set a(-regexp) 1
+ set a(-exact) 1
+ list [catch {array names a -regexp} msg] $msg
+} {0 -regexp}
+test set-old-8.54 {array command, array names -exact} {
+ catch {unset a}
+ set a(-glob) 1
+ set a(-regexp) 1
+ set a(-exact) 1
+ list [catch {array names a -exact} msg] $msg
+} {0 -exact}
+test set-old-8.55 {array command, array names -glob} {
+ catch {unset a}
+ set a(-glob) 1
+ set a(-regexp) 1
+ set a(-exact) 1
+ list [catch {array names a -glob} msg] $msg
+} {0 -glob}
+test set-old-8.56 {array command, array statistics on a non-array} {
+ catch {unset a}
+ list [catch {array statistics a} msg] $msg
+} [list 1 "\"a\" isn't an array"]
+test set-old-8.57 {array command, array get with trivial pattern} {
+ catch {unset a}
+ set a(x) 1
+ set a(y) 2
+ array get a x
+} {x 1}
+
+test set-old-9.1 {ids for array enumeration} {
+ catch {unset a}
+ set a(a) 1
+ list [array star a] [array star a] [array done a s-1-a; array star a] \
+ [array done a s-2-a; array d a s-3-a; array start a]
+} {s-1-a s-2-a s-3-a s-1-a}
+test set-old-9.2 {array enumeration} {
+ catch {unset a}
+ set a(a) 1
+ set a(b) 1
+ set a(c) 1
+ set x [array startsearch a]
+ lsort [list [array nextelement a $x] [array ne a $x] [array next a $x] \
+ [array next a $x] [array next a $x]]
+} {{} {} a b c}
+test set-old-9.3 {array enumeration} {
+ catch {unset a}
+ set a(a) 1
+ set a(b) 1
+ set a(c) 1
+ set x [array startsearch a]
+ set y [array startsearch a]
+ set z [array startsearch a]
+ lsort [list [array nextelement a $x] [array ne a $x] \
+ [array next a $y] [array next a $z] [array next a $y] \
+ [array next a $z] [array next a $y] [array next a $z] \
+ [array next a $y] [array next a $z] [array next a $x] \
+ [array next a $x]]
+} {{} {} {} a a a b b b c c c}
+test set-old-9.4 {array enumeration: stopping searches} {
+ catch {unset a}
+ set a(a) 1
+ set a(b) 1
+ set a(c) 1
+ set x [array startsearch a]
+ set y [array startsearch a]
+ set z [array startsearch a]
+ lsort [list [array next a $x] [array next a $x] [array next a $y] \
+ [array done a $z; array next a $x] \
+ [array done a $x; array next a $y] [array next a $y]]
+} {a a b b c c}
+test set-old-9.5 {array enumeration: stopping searches} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ array done a $x
+ list [catch {array next a $x} msg] $msg
+} {1 {couldn't find search "s-1-a"}}
+test set-old-9.6 {array enumeration: searches automatically stopped} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ set y [array startsearch a]
+ set a(b) 1
+ list [catch {array next a $x} msg] $msg \
+ [catch {array next a $y} msg2] $msg2
+} {1 {couldn't find search "s-1-a"} 1 {couldn't find search "s-2-a"}}
+test set-old-9.7 {array enumeration: searches automatically stopped} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ set y [array startsearch a]
+ set a(a) 2
+ list [catch {array next a $x} msg] $msg \
+ [catch {array next a $y} msg2] $msg2
+} {0 a 0 a}
+test set-old-9.8 {array enumeration: searches automatically stopped} {
+ catch {unset a}
+ set a(a) 1
+ set a(c) 2
+ set x [array startsearch a]
+ set y [array startsearch a]
+ catch {unset a(c)}
+ list [catch {array next a $x} msg] $msg \
+ [catch {array next a $y} msg2] $msg2
+} {1 {couldn't find search "s-1-a"} 1 {couldn't find search "s-2-a"}}
+test set-old-9.9 {array enumeration: searches automatically stopped} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ set y [array startsearch a]
+ catch {unset a(c)}
+ list [catch {array next a $x} msg] $msg \
+ [catch {array next a $y} msg2] $msg2
+} {0 a 0 a}
+test set-old-9.10 {array enumeration: searches automatically stopped} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ set y [array startsearch a]
+ trace var a(b) r {}
+ list [catch {array next a $x} msg] $msg \
+ [catch {array next a $y} msg2] $msg2
+} {1 {couldn't find search "s-1-a"} 1 {couldn't find search "s-2-a"}}
+test set-old-9.11 {array enumeration: searches automatically stopped} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ set y [array startsearch a]
+ trace var a(a) r {}
+ list [catch {array next a $x} msg] $msg \
+ [catch {array next a $y} msg2] $msg2
+} {0 a 0 a}
+test set-old-9.12 {array enumeration with traced undefined elements} {
+ catch {unset a}
+ set a(a) 1
+ trace var a(b) r {}
+ set x [array startsearch a]
+ lsort [list [array next a $x] [array next a $x]]
+} {{} a}
+
+test set-old-10.1 {array enumeration errors} {
+ list [catch {array start} msg] $msg
+} {1 {wrong # args: should be "array startsearch arrayName"}}
+test set-old-10.2 {array enumeration errors} {
+ list [catch {array start a b} msg] $msg
+} {1 {wrong # args: should be "array startsearch arrayName"}}
+test set-old-10.3 {array enumeration errors} {
+ catch {unset a}
+ list [catch {array start a} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-10.4 {array enumeration errors} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ list [catch {array next a} msg] $msg
+} {1 {wrong # args: should be "array nextelement arrayName searchId"}}
+test set-old-10.5 {array enumeration errors} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ list [catch {array next a b c} msg] $msg
+} {1 {wrong # args: should be "array nextelement arrayName searchId"}}
+test set-old-10.6 {array enumeration errors} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ list [catch {array next a a-1-a} msg] $msg
+} {1 {illegal search identifier "a-1-a"}}
+test set-old-10.7 {array enumeration errors} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ list [catch {array next a sx1-a} msg] $msg
+} {1 {illegal search identifier "sx1-a"}}
+test set-old-10.8 {array enumeration errors} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ list [catch {array next a s--a} msg] $msg
+} {1 {illegal search identifier "s--a"}}
+test set-old-10.9 {array enumeration errors} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ list [catch {array next a s-1-b} msg] $msg
+} {1 {search identifier "s-1-b" isn't for variable "a"}}
+test set-old-10.10 {array enumeration errors} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ list [catch {array next a s-1ba} msg] $msg
+} {1 {illegal search identifier "s-1ba"}}
+test set-old-10.11 {array enumeration errors} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ list [catch {array next a s-2-a} msg] $msg
+} {1 {couldn't find search "s-2-a"}}
+test set-old-10.12 {array enumeration errors} {
+ list [catch {array done a} msg] $msg
+} {1 {wrong # args: should be "array donesearch arrayName searchId"}}
+test set-old-10.13 {array enumeration errors} {
+ list [catch {array done a b c} msg] $msg
+} {1 {wrong # args: should be "array donesearch arrayName searchId"}}
+test set-old-10.14 {array enumeration errors} {
+ list [catch {array done a b} msg] $msg
+} {1 {illegal search identifier "b"}}
+test set-old-10.15 {array enumeration errors} {
+ list [catch {array anymore a} msg] $msg
+} {1 {wrong # args: should be "array anymore arrayName searchId"}}
+test set-old-10.16 {array enumeration errors} {
+ list [catch {array any a b c} msg] $msg
+} {1 {wrong # args: should be "array anymore arrayName searchId"}}
+test set-old-10.17 {array enumeration errors} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {array any a bogus} msg] $msg
+} {1 {illegal search identifier "bogus"}}
+
+# Array enumeration with "anymore" option
+
+test set-old-11.1 {array anymore option} {
+ catch {unset a}
+ set a(a) 1
+ set a(b) 2
+ set a(c) 3
+ array startsearch a
+ lsort [list [array anymore a s-1-a] [array next a s-1-a] \
+ [array anymore a s-1-a] [array next a s-1-a] \
+ [array anymore a s-1-a] [array next a s-1-a] \
+ [array anymore a s-1-a] [array next a s-1-a]]
+} {{} 0 1 1 1 a b c}
+test set-old-11.2 {array anymore option} {
+ catch {unset a}
+ set a(a) 1
+ set a(b) 2
+ set a(c) 3
+ array startsearch a
+ lsort [list [array next a s-1-a] [array next a s-1-a] \
+ [array anymore a s-1-a] [array next a s-1-a] \
+ [array next a s-1-a] [array anymore a s-1-a]]
+} {{} 0 1 a b c}
+
+# Special check to see that the value of a variable is handled correctly
+# if it is returned as the result of a procedure (must not free the variable
+# string while deleting the call frame). Errors will only be detected if
+# a memory consistency checker such as Purify is being used.
+
+test set-old-12.1 {cleanup on procedure return} {
+ proc foo {} {
+ set x 12345
+ }
+ foo
+} 12345
+test set-old-12.2 {cleanup on procedure return} {
+ proc foo {} {
+ set x(1) 23456
+ }
+ foo
+} 23456
+
+# Must delete variables when done, since these arrays get used as
+# scalars by other tests.
+catch {unset a}
+catch {unset b}
+catch {unset c}
+catch {unset aVaRnAmE}
+catch {rename foo {}}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/set.test b/library/msgcat/tests/set.test
new file mode 100644
index 0000000..9e0ddc0
--- /dev/null
+++ b/library/msgcat/tests/set.test
@@ -0,0 +1,531 @@
+# Commands covered: set
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testset2 [llength [info commands testset2]]
+
+catch {unset x}
+catch {unset i}
+
+test set-1.1 {TclCompileSetCmd: missing variable name} {
+ list [catch {set} msg] $msg
+} {1 {wrong # args: should be "set varName ?newValue?"}}
+test set-1.2 {TclCompileSetCmd: simple variable name} {
+ set i 10
+ list [set i] $i
+} {10 10}
+test set-1.3 {TclCompileSetCmd: error compiling variable name} {
+ set i 10
+ catch {set "i"xxx} msg
+ set msg
+} {extra characters after close-quote}
+test set-1.4 {TclCompileSetCmd: simple variable name in quotes} {
+ set i 17
+ list [set "i"] $i
+} {17 17}
+test set-1.5 {TclCompileSetCmd: simple variable name in braces} {
+ catch {unset {a simple var}}
+ set {a simple var} 27
+ list [set {a simple var}] ${a simple var}
+} {27 27}
+test set-1.6 {TclCompileSetCmd: simple array variable name} {
+ catch {unset a}
+ set a(foo) 37
+ list [set a(foo)] $a(foo)
+} {37 37}
+test set-1.7 {TclCompileSetCmd: non-simple (computed) variable name} {
+ set x "i"
+ set i 77
+ list [set $x] $i
+} {77 77}
+test set-1.8 {TclCompileSetCmd: non-simple (computed) variable name} {
+ set x "i"
+ set i 77
+ list [set [set x] 2] $i
+} {2 2}
+
+test set-1.9 {TclCompileSetCmd: 3rd arg => assignment} {
+ set i "abcdef"
+ list [set i] $i
+} {abcdef abcdef}
+test set-1.10 {TclCompileSetCmd: only two args => just getting value} {
+ set i {one two}
+ set i
+} {one two}
+
+test set-1.11 {TclCompileSetCmd: simple global name} {
+ proc p {} {
+ global i
+ set i 54
+ set i
+ }
+ p
+} {54}
+test set-1.12 {TclCompileSetCmd: simple local name} {
+ proc p {bar} {
+ set foo $bar
+ set foo
+ }
+ p 999
+} {999}
+test set-1.13 {TclCompileSetCmd: simple but new (unknown) local name} {
+ proc p {} {
+ set bar
+ }
+ catch {p} msg
+ set msg
+} {can't read "bar": no such variable}
+test set-1.14 {TclCompileSetCmd: simple local name, >255 locals} {
+ proc 260locals {} {
+ # create 260 locals (the last ones with index > 255)
+ set a0 0; set a1 0; set a2 0; set a3 0; set a4 0
+ set a5 0; set a6 0; set a7 0; set a8 0; set a9 0
+ set b0 0; set b1 0; set b2 0; set b3 0; set b4 0
+ set b5 0; set b6 0; set b7 0; set b8 0; set b9 0
+ set c0 0; set c1 0; set c2 0; set c3 0; set c4 0
+ set c5 0; set c6 0; set c7 0; set c8 0; set c9 0
+ set d0 0; set d1 0; set d2 0; set d3 0; set d4 0
+ set d5 0; set d6 0; set d7 0; set d8 0; set d9 0
+ set e0 0; set e1 0; set e2 0; set e3 0; set e4 0
+ set e5 0; set e6 0; set e7 0; set e8 0; set e9 0
+ set f0 0; set f1 0; set f2 0; set f3 0; set f4 0
+ set f5 0; set f6 0; set f7 0; set f8 0; set f9 0
+ set g0 0; set g1 0; set g2 0; set g3 0; set g4 0
+ set g5 0; set g6 0; set g7 0; set g8 0; set g9 0
+ set h0 0; set h1 0; set h2 0; set h3 0; set h4 0
+ set h5 0; set h6 0; set h7 0; set h8 0; set h9 0
+ set i0 0; set i1 0; set i2 0; set i3 0; set i4 0
+ set i5 0; set i6 0; set i7 0; set i8 0; set i9 0
+ set j0 0; set j1 0; set j2 0; set j3 0; set j4 0
+ set j5 0; set j6 0; set j7 0; set j8 0; set j9 0
+ set k0 0; set k1 0; set k2 0; set k3 0; set k4 0
+ set k5 0; set k6 0; set k7 0; set k8 0; set k9 0
+ set l0 0; set l1 0; set l2 0; set l3 0; set l4 0
+ set l5 0; set l6 0; set l7 0; set l8 0; set l9 0
+ set m0 0; set m1 0; set m2 0; set m3 0; set m4 0
+ set m5 0; set m6 0; set m7 0; set m8 0; set m9 0
+ set n0 0; set n1 0; set n2 0; set n3 0; set n4 0
+ set n5 0; set n6 0; set n7 0; set n8 0; set n9 0
+ set o0 0; set o1 0; set o2 0; set o3 0; set o4 0
+ set o5 0; set o6 0; set o7 0; set o8 0; set o9 0
+ set p0 0; set p1 0; set p2 0; set p3 0; set p4 0
+ set p5 0; set p6 0; set p7 0; set p8 0; set p9 0
+ set q0 0; set q1 0; set q2 0; set q3 0; set q4 0
+ set q5 0; set q6 0; set q7 0; set q8 0; set q9 0
+ set r0 0; set r1 0; set r2 0; set r3 0; set r4 0
+ set r5 0; set r6 0; set r7 0; set r8 0; set r9 0
+ set s0 0; set s1 0; set s2 0; set s3 0; set s4 0
+ set s5 0; set s6 0; set s7 0; set s8 0; set s9 0
+ set t0 0; set t1 0; set t2 0; set t3 0; set t4 0
+ set t5 0; set t6 0; set t7 0; set t8 0; set t9 0
+ set u0 0; set u1 0; set u2 0; set u3 0; set u4 0
+ set u5 0; set u6 0; set u7 0; set u8 0; set u9 0
+ set v0 0; set v1 0; set v2 0; set v3 0; set v4 0
+ set v5 0; set v6 0; set v7 0; set v8 0; set v9 0
+ set w0 0; set w1 0; set w2 0; set w3 0; set w4 0
+ set w5 0; set w6 0; set w7 0; set w8 0; set w9 0
+ set x0 0; set x1 0; set x2 0; set x3 0; set x4 0
+ set x5 0; set x6 0; set x7 0; set x8 0; set x9 0
+ set y0 0; set y1 0; set y2 0; set y3 0; set y4 0
+ set y5 0; set y6 0; set y7 0; set y8 0; set y9 0
+ set z0 0; set z1 0; set z2 0; set z3 0; set z4 0
+ set z5 0; set z6 0; set z7 0; set z8 0; set z9 1234
+ }
+ 260locals
+} {1234}
+test set-1.15 {TclCompileSetCmd: variable is array} {
+ catch {unset a}
+ set x 27
+ set x [set a(foo) 11]
+ catch {unset a}
+ set x
+} 11
+test set-1.16 {TclCompileSetCmd: variable is array, elem substitutions} {
+ catch {unset a}
+ set i 5
+ set x 789
+ set a(foo5) 27
+ set x [set a(foo$i)]
+ catch {unset a}
+ set x
+} 27
+
+test set-1.17 {TclCompileSetCmd: doing assignment, simple int} {
+ set i 5
+ set i 123
+} 123
+test set-1.18 {TclCompileSetCmd: doing assignment, simple int} {
+ set i 5
+ set i -100
+} -100
+test set-1.19 {TclCompileSetCmd: doing assignment, simple but not int} {
+ set i 5
+ set i 0x12MNOP
+ set i
+} {0x12MNOP}
+test set-1.20 {TclCompileSetCmd: doing assignment, in quotes} {
+ set i 25
+ set i "-100"
+} -100
+test set-1.21 {TclCompileSetCmd: doing assignment, in braces} {
+ set i 24
+ set i {126}
+} 126
+test set-1.22 {TclCompileSetCmd: doing assignment, large int} {
+ set i 5
+ set i 200000
+} 200000
+test set-1.23 {TclCompileSetCmd: doing assignment, formatted int != int} {
+ set i 25
+ set i 0o00012345 ;# an octal literal == 5349 decimal
+ list $i [incr i]
+} {0o00012345 5350}
+
+test set-1.24 {TclCompileSetCmd: too many arguments} {
+ set i 10
+ catch {set i 20 30} msg
+ set msg
+} {wrong # args: should be "set varName ?newValue?"}
+
+test set-1.25 {TclCompileSetCmd: var is array, braced (no subs)} {
+ # This was a known error in 8.1a* - 8.2.1
+ catch {unset array}
+ set {array($foo)} 5
+} 5
+test set-1.26 {TclCompileSetCmd: various array constructs} {
+ # Test all kinds of array constructs that TclCompileSetCmd
+ # may feel inclined to tamper with.
+ proc p {} {
+ set a x
+ set be(hej) 1 ; # hej
+ set be($a) 1 ; # x
+ set {be($a)} 1 ; # $a
+ set be($a,hej) 1 ; # x,hej
+ set be($a,$a) 5 ; # x,x
+ set be(c($a) 1 ; # c(x
+ set be(\w\w) 1 ; # ww
+ set be(a:$a) [set be(x,$a)] ; # a:x
+ set be(hej,$be($a,hej),hej) 1 ; # hej,1,hej
+ set be([string range hugge 0 2]) 1 ; # hug
+ set be(a\ a) 1 ; # a a
+ set be($a\ ,[string range hugge 1 3],hej) 1 ; # x ,ugg,hej
+ set be($a,h"ej) 1 ; # x,h"ej
+ set be([string range "a b c" 2 end]) 1 ; # b c
+ set [string range bet 0 1](foo) 1 ; # foo
+ set be([set be(a:$a)][set b\e($a)]) 1 ; # 51
+ return [lsort [array names be]]
+ }
+ p
+} [lsort {hej x $a x,hej x,x c(x ww a:x hej,1,hej hug {a a} {x ,ugg,hej} x,h"ej
+{b c} foo 51}]; # " just a matching end quote
+
+test set-2.1 {set command: runtime error, bad variable name} {
+ unset -nocomplain {"foo}
+ list [catch {set {"foo}} msg] $msg $::errorInfo
+} {1 {can't read ""foo": no such variable} {can't read ""foo": no such variable
+ while executing
+"set {"foo}"}}
+test set-2.2 {set command: runtime error, not array variable} {
+ catch {unset b}
+ set b 44
+ list [catch {set b(123)} msg] $msg
+} {1 {can't read "b(123)": variable isn't array}}
+test set-2.3 {set command: runtime error, errors in reading variables} {
+ catch {unset a}
+ set a(6) 44
+ list [catch {set a(18)} msg] $msg
+} {1 {can't read "a(18)": no such element in array}}
+test set-2.4 {set command: runtime error, readonly variable} -body {
+ proc readonly args {error "variable is read-only"}
+ set x 123
+ trace var x w readonly
+ list [catch {set x 1} msg] $msg $::errorInfo
+} -match glob -result {1 {can't set "x": variable is read-only} {*variable is read-only
+ while executing
+*
+"set x 1"}}
+test set-2.5 {set command: runtime error, basic array operations} {
+ list [catch {set a(other)} msg] $msg
+} {1 {can't read "a(other)": no such element in array}}
+test set-2.6 {set command: runtime error, basic array operations} {
+ list [catch {set a} msg] $msg
+} {1 {can't read "a": variable is array}}
+
+# Test the uncompiled version of set
+
+catch {unset a}
+catch {unset b}
+catch {unset i}
+catch {unset x}
+
+test set-3.1 {uncompiled set command: missing variable name} {
+ set z set
+ list [catch {$z} msg] $msg
+} {1 {wrong # args: should be "set varName ?newValue?"}}
+test set-3.2 {uncompiled set command: simple variable name} {
+ set z set
+ $z i 10
+ list [$z i] $i
+} {10 10}
+test set-3.3 {uncompiled set command: error compiling variable name} {
+ set z set
+ $z i 10
+ catch {$z "i"xxx} msg
+ $z msg
+} {extra characters after close-quote}
+test set-3.4 {uncompiled set command: simple variable name in quotes} {
+ set z set
+ $z i 17
+ list [$z "i"] $i
+} {17 17}
+test set-3.5 {uncompiled set command: simple variable name in braces} {
+ set z set
+ catch {unset {a simple var}}
+ $z {a simple var} 27
+ list [$z {a simple var}] ${a simple var}
+} {27 27}
+test set-3.6 {uncompiled set command: simple array variable name} {
+ set z set
+ catch {unset a}
+ $z a(foo) 37
+ list [$z a(foo)] $a(foo)
+} {37 37}
+test set-3.7 {uncompiled set command: non-simple (computed) variable name} {
+ set z set
+ $z x "i"
+ $z i 77
+ list [$z $x] $i
+} {77 77}
+test set-3.8 {uncompiled set command: non-simple (computed) variable name} {
+ set z set
+ $z x "i"
+ $z i 77
+ list [$z [$z x] 2] $i
+} {2 2}
+
+test set-3.9 {uncompiled set command: 3rd arg => assignment} {
+ set z set
+ $z i "abcdef"
+ list [$z i] $i
+} {abcdef abcdef}
+test set-3.10 {uncompiled set command: only two args => just getting value} {
+ set z set
+ $z i {one two}
+ $z i
+} {one two}
+
+test set-3.11 {uncompiled set command: simple global name} {
+ proc p {} {
+ set z set
+ global i
+ $z i 54
+ $z i
+ }
+ p
+} {54}
+test set-3.12 {uncompiled set command: simple local name} {
+ proc p {bar} {
+ set z set
+ $z foo $bar
+ $z foo
+ }
+ p 999
+} {999}
+test set-3.13 {uncompiled set command: simple but new (unknown) local name} {
+ set z set
+ proc p {} {
+ set z set
+ $z bar
+ }
+ catch {p} msg
+ $z msg
+} {can't read "bar": no such variable}
+test set-3.14 {uncompiled set command: simple local name, >255 locals} {
+ proc 260locals {} {
+ set z set
+ # create 260 locals (the last ones with index > 255)
+ $z a0 0; $z a1 0; $z a2 0; $z a3 0; $z a4 0
+ $z a5 0; $z a6 0; $z a7 0; $z a8 0; $z a9 0
+ $z b0 0; $z b1 0; $z b2 0; $z b3 0; $z b4 0
+ $z b5 0; $z b6 0; $z b7 0; $z b8 0; $z b9 0
+ $z c0 0; $z c1 0; $z c2 0; $z c3 0; $z c4 0
+ $z c5 0; $z c6 0; $z c7 0; $z c8 0; $z c9 0
+ $z d0 0; $z d1 0; $z d2 0; $z d3 0; $z d4 0
+ $z d5 0; $z d6 0; $z d7 0; $z d8 0; $z d9 0
+ $z e0 0; $z e1 0; $z e2 0; $z e3 0; $z e4 0
+ $z e5 0; $z e6 0; $z e7 0; $z e8 0; $z e9 0
+ $z f0 0; $z f1 0; $z f2 0; $z f3 0; $z f4 0
+ $z f5 0; $z f6 0; $z f7 0; $z f8 0; $z f9 0
+ $z g0 0; $z g1 0; $z g2 0; $z g3 0; $z g4 0
+ $z g5 0; $z g6 0; $z g7 0; $z g8 0; $z g9 0
+ $z h0 0; $z h1 0; $z h2 0; $z h3 0; $z h4 0
+ $z h5 0; $z h6 0; $z h7 0; $z h8 0; $z h9 0
+ $z i0 0; $z i1 0; $z i2 0; $z i3 0; $z i4 0
+ $z i5 0; $z i6 0; $z i7 0; $z i8 0; $z i9 0
+ $z j0 0; $z j1 0; $z j2 0; $z j3 0; $z j4 0
+ $z j5 0; $z j6 0; $z j7 0; $z j8 0; $z j9 0
+ $z k0 0; $z k1 0; $z k2 0; $z k3 0; $z k4 0
+ $z k5 0; $z k6 0; $z k7 0; $z k8 0; $z k9 0
+ $z l0 0; $z l1 0; $z l2 0; $z l3 0; $z l4 0
+ $z l5 0; $z l6 0; $z l7 0; $z l8 0; $z l9 0
+ $z m0 0; $z m1 0; $z m2 0; $z m3 0; $z m4 0
+ $z m5 0; $z m6 0; $z m7 0; $z m8 0; $z m9 0
+ $z n0 0; $z n1 0; $z n2 0; $z n3 0; $z n4 0
+ $z n5 0; $z n6 0; $z n7 0; $z n8 0; $z n9 0
+ $z o0 0; $z o1 0; $z o2 0; $z o3 0; $z o4 0
+ $z o5 0; $z o6 0; $z o7 0; $z o8 0; $z o9 0
+ $z p0 0; $z p1 0; $z p2 0; $z p3 0; $z p4 0
+ $z p5 0; $z p6 0; $z p7 0; $z p8 0; $z p9 0
+ $z q0 0; $z q1 0; $z q2 0; $z q3 0; $z q4 0
+ $z q5 0; $z q6 0; $z q7 0; $z q8 0; $z q9 0
+ $z r0 0; $z r1 0; $z r2 0; $z r3 0; $z r4 0
+ $z r5 0; $z r6 0; $z r7 0; $z r8 0; $z r9 0
+ $z s0 0; $z s1 0; $z s2 0; $z s3 0; $z s4 0
+ $z s5 0; $z s6 0; $z s7 0; $z s8 0; $z s9 0
+ $z t0 0; $z t1 0; $z t2 0; $z t3 0; $z t4 0
+ $z t5 0; $z t6 0; $z t7 0; $z t8 0; $z t9 0
+ $z u0 0; $z u1 0; $z u2 0; $z u3 0; $z u4 0
+ $z u5 0; $z u6 0; $z u7 0; $z u8 0; $z u9 0
+ $z v0 0; $z v1 0; $z v2 0; $z v3 0; $z v4 0
+ $z v5 0; $z v6 0; $z v7 0; $z v8 0; $z v9 0
+ $z w0 0; $z w1 0; $z w2 0; $z w3 0; $z w4 0
+ $z w5 0; $z w6 0; $z w7 0; $z w8 0; $z w9 0
+ $z x0 0; $z x1 0; $z x2 0; $z x3 0; $z x4 0
+ $z x5 0; $z x6 0; $z x7 0; $z x8 0; $z x9 0
+ $z y0 0; $z y1 0; $z y2 0; $z y3 0; $z y4 0
+ $z y5 0; $z y6 0; $z y7 0; $z y8 0; $z y9 0
+ $z z0 0; $z z1 0; $z z2 0; $z z3 0; $z z4 0
+ $z z5 0; $z z6 0; $z z7 0; $z z8 0; $z z9 1234
+ }
+ 260locals
+} {1234}
+test set-3.15 {uncompiled set command: variable is array} {
+ set z set
+ catch {unset a}
+ $z x 27
+ $z x [$z a(foo) 11]
+ catch {unset a}
+ $z x
+} 11
+test set-3.16 {uncompiled set command: variable is array, elem substitutions} {
+ set z set
+ catch {unset a}
+ $z i 5
+ $z x 789
+ $z a(foo5) 27
+ $z x [$z a(foo$i)]
+ catch {unset a}
+ $z x
+} 27
+
+test set-3.17 {uncompiled set command: doing assignment, simple int} {
+ set z set
+ $z i 5
+ $z i 123
+} 123
+test set-3.18 {uncompiled set command: doing assignment, simple int} {
+ set z set
+ $z i 5
+ $z i -100
+} -100
+test set-3.19 {uncompiled set command: doing assignment, simple but not int} {
+ set z set
+ $z i 5
+ $z i 0x12MNOP
+ $z i
+} {0x12MNOP}
+test set-3.20 {uncompiled set command: doing assignment, in quotes} {
+ set z set
+ $z i 25
+ $z i "-100"
+} -100
+test set-3.21 {uncompiled set command: doing assignment, in braces} {
+ set z set
+ $z i 24
+ $z i {126}
+} 126
+test set-3.22 {uncompiled set command: doing assignment, large int} {
+ set z set
+ $z i 5
+ $z i 200000
+} 200000
+test set-3.23 {uncompiled set command: doing assignment, formatted int != int} {
+ set z set
+ $z i 25
+ $z i 0o00012345 ;# an octal literal == 5349 decimal
+ list $i [incr i]
+} {0o00012345 5350}
+
+test set-3.24 {uncompiled set command: too many arguments} {
+ set z set
+ $z i 10
+ catch {$z i 20 30} msg
+ $z msg
+} {wrong # args: should be "set varName ?newValue?"}
+
+test set-4.1 {uncompiled set command: runtime error, bad variable name} {
+ unset -nocomplain {"foo}
+ set z set
+ list [catch {$z {"foo}} msg] $msg $::errorInfo
+} {1 {can't read ""foo": no such variable} {can't read ""foo": no such variable
+ while executing
+"$z {"foo}"}}
+test set-4.2 {uncompiled set command: runtime error, not array variable} {
+ set z set
+ catch {unset b}
+ $z b 44
+ list [catch {$z b(123)} msg] $msg
+} {1 {can't read "b(123)": variable isn't array}}
+test set-4.3 {uncompiled set command: runtime error, errors in reading variables} {
+ set z set
+ catch {unset a}
+ $z a(6) 44
+ list [catch {$z a(18)} msg] $msg
+} {1 {can't read "a(18)": no such element in array}}
+test set-4.4 {uncompiled set command: runtime error, readonly variable} -body {
+ set z set
+ proc readonly args {error "variable is read-only"}
+ $z x 123
+ trace var x w readonly
+ list [catch {$z x 1} msg] $msg $::errorInfo
+} -match glob -result {1 {can't set "x": variable is read-only} {*variable is read-only
+ while executing
+*
+"$z x 1"}}
+test set-4.5 {uncompiled set command: runtime error, basic array operations} {
+ set z set
+ list [catch {$z a(other)} msg] $msg
+} {1 {can't read "a(other)": no such element in array}}
+test set-4.6 {set command: runtime error, basic array operations} {
+ set z set
+ list [catch {$z a} msg] $msg
+} {1 {can't read "a": variable is array}}
+
+test set-5.1 {error on malformed array name} testset2 {
+ unset -nocomplain z
+ catch {testset2 z(a) b} msg
+ catch {testset2 z(b) a} msg1
+ list $msg $msg1
+} {{can't read "z(a)(b)": variable isn't array} {can't read "z(b)(a)": variable isn't array}}
+
+# cleanup
+catch {unset a}
+catch {unset b}
+catch {unset i}
+catch {unset x}
+catch {unset z}
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/socket.test b/library/msgcat/tests/socket.test
new file mode 100644
index 0000000..9f1cc78
--- /dev/null
+++ b/library/msgcat/tests/socket.test
@@ -0,0 +1,1860 @@
+# Commands tested in this file: socket.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 Ajuba Solutions.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+# Running socket tests with a remote server:
+# ------------------------------------------
+#
+# Some tests in socket.test depend on the existence of a remote server to
+# which they connect. The remote server must be an instance of tcltest and it
+# must run the script found in the file "remote.tcl" in this directory. You
+# can start the remote server on any machine reachable from the machine on
+# which you want to run the socket tests, by issuing:
+#
+# tcltest remote.tcl -port 2048 # Or choose another port number.
+#
+# If the machine you are running the remote server on has several IP
+# interfaces, you can choose which interface the server listens on for
+# connections by specifying the -address command line flag, so:
+#
+# tcltest remote.tcl -address your.machine.com
+#
+# These options can also be set by environment variables. On Unix, you can
+# type these commands to the shell from which the remote server is started:
+#
+# shell% setenv serverPort 2048
+# shell% setenv serverAddress your.machine.com
+#
+# and subsequently you can start the remote server with:
+#
+# tcltest remote.tcl
+#
+# to have it listen on port 2048 on the interface your.machine.com.
+#
+# When the server starts, it prints out a detailed message containing its
+# configuration information, and it will block until killed with a Ctrl-C.
+# Once the remote server exists, you can run the tests in socket.test with the
+# server by setting two Tcl variables:
+#
+# % set remoteServerIP <name or address of machine on which server runs>
+# % set remoteServerPort 2048
+#
+# These variables are also settable from the environment. On Unix, you can:
+#
+# shell% setenv remoteServerIP machine.where.server.runs
+# shell% senetv remoteServerPort 2048
+#
+# The preamble of the socket.test file checks to see if the variables are set
+# either in Tcl or in the environment; if they are, it attempts to connect to
+# the server. If the connection is successful, the tests using the remote
+# server will be performed; otherwise, it will attempt to start the remote
+# server (via exec) on platforms that support this, on the local host,
+# listening at port 2048. If all fails, a message is printed and the tests
+# using the remote server are not performed.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+# Some tests require the Thread package or exec command
+testConstraint thread [expr {0 == [catch {package require Thread 2.6.6}]}]
+testConstraint exec [llength [info commands exec]]
+
+# Produce a random port number in the Dynamic/Private range
+# from 49152 through 65535.
+proc randport {} { expr {int(rand()*16383+49152)} }
+
+# Test the latency of tcp connections over the loopback interface. Some OSes
+# (e.g. NetBSD) seem to use the Nagle algorithm and delayed ACKs, so it takes
+# up to 200ms for a packet sent to localhost to arrive. We're measuring this
+# here, so that OSes that don't have this problem can run the tests at full
+# speed.
+set server [socket -server {apply {{s a p} {set ::s1 $s}}} 0]
+set s2 [socket localhost [lindex [fconfigure $server -sockname] 2]]
+vwait s1; close $server
+fconfigure $s1 -buffering line
+fconfigure $s2 -buffering line
+set t1 [clock milliseconds]
+puts $s2 test1; gets $s1
+puts $s2 test2; gets $s1
+close $s1; close $s2
+set t2 [clock milliseconds]
+set latency [expr {($t2-$t1)*2}]; # doubled as a safety margin
+unset t1 t2 s1 s2 server
+
+# If remoteServerIP or remoteServerPort are not set, check in the environment
+# variables for externally set values.
+#
+
+if {![info exists remoteServerIP]} {
+ if {[info exists env(remoteServerIP)]} {
+ set remoteServerIP $env(remoteServerIP)
+ }
+}
+if {![info exists remoteServerPort]} {
+ if {[info exists env(remoteServerPort)]} {
+ set remoteServerPort $env(remoteServerPort)
+ } else {
+ if {[info exists remoteServerIP]} {
+ set remoteServerPort 2048
+ }
+ }
+}
+
+if 0 {
+ # activate this to time the tests
+ proc test {args} {
+ set name [lindex $args 0]
+ puts "[lindex [time {uplevel [linsert $args 0 tcltest::test]}] 0] @@@ $name"
+ }
+}
+
+foreach {af localhost} {
+ inet 127.0.0.1
+ inet6 ::1
+} {
+ # Check if the family is supported and set the constraint accordingly
+ testConstraint supported_$af [expr {![catch {socket -server foo -myaddr $localhost 0} sock]}]
+ catch {close $sock}
+}
+testConstraint supported_any [expr {[testConstraint supported_inet] || [testConstraint supported_inet6]}]
+
+set sock [socket -server foo -myaddr localhost 0]
+set sockname [fconfigure $sock -sockname]
+close $sock
+testConstraint localhost_v4 [expr {"127.0.0.1" in $sockname}]
+testConstraint localhost_v6 [expr {"::1" in $sockname}]
+
+
+foreach {af localhost} {
+ any 127.0.0.1
+ inet 127.0.0.1
+ inet6 ::1
+} {
+ set ::tcl::unsupported::socketAF $af
+#
+# Check if we're supposed to do tests against the remote server
+#
+
+set doTestsWithRemoteServer 1
+if {![info exists remoteServerIP]} {
+ set remoteServerIP $localhost
+}
+if {($doTestsWithRemoteServer == 1) && (![info exists remoteServerPort])} {
+ set remoteServerPort [randport]
+}
+
+# Attempt to connect to a remote server if one is already running. If it is
+# not running or for some other reason the connect fails, attempt to start the
+# remote server on the local host listening on port 2048. This is only done on
+# platforms that support exec (i.e. not on the Mac). On platforms that do not
+# support exec, the remote server must be started by the user before running
+# the tests.
+
+set remoteProcChan ""
+set commandSocket ""
+if {$doTestsWithRemoteServer} {
+ catch {close $commandSocket}
+ if {![catch {
+ set commandSocket [socket $remoteServerIP $remoteServerPort]
+ }]} then {
+ fconfigure $commandSocket -translation crlf -buffering line
+ } elseif {![testConstraint exec]} {
+ set noRemoteTestReason "can't exec"
+ set doTestsWithRemoteServer 0
+ } else {
+ set remoteServerIP $localhost
+ # Be *extra* careful in case this file is sourced from
+ # a directory other than the current one...
+ set remoteFile [file join [pwd] [file dirname [info script]] \
+ remote.tcl]
+ if {![catch {
+ set remoteProcChan [open "|[list \
+ [interpreter] $remoteFile -serverIsSilent \
+ -port $remoteServerPort -address $remoteServerIP]" w+]
+ } msg]} then {
+ gets $remoteProcChan
+ if {[catch {
+ set commandSocket [socket $remoteServerIP $remoteServerPort]
+ } msg] == 0} then {
+ fconfigure $commandSocket -translation crlf -buffering line
+ } else {
+ set noRemoteTestReason $msg
+ set doTestsWithRemoteServer 0
+ }
+ } else {
+ set noRemoteTestReason "$msg [interpreter]"
+ set doTestsWithRemoteServer 0
+ }
+ }
+}
+
+# Some tests are run only if we are doing testing against a remote server.
+testConstraint doTestsWithRemoteServer $doTestsWithRemoteServer
+if {!$doTestsWithRemoteServer} {
+ if {[string first s $::tcltest::verbose] != -1} {
+ puts "Skipping tests with remote server. See tests/socket.test for"
+ puts "information on how to run remote server."
+ puts "Reason for not doing remote tests: $noRemoteTestReason"
+ }
+}
+
+#
+# If we do the tests, define a command to send a command to the remote server.
+#
+
+if {[testConstraint doTestsWithRemoteServer]} {
+ proc sendCommand {c} {
+ global commandSocket
+
+ if {[eof $commandSocket]} {
+ error "remote server disappeared"
+ }
+ if {[catch {puts $commandSocket $c} msg]} {
+ error "remote server disappaered: $msg"
+ }
+ if {[catch {puts $commandSocket "--Marker--Marker--Marker--"} msg]} {
+ error "remote server disappeared: $msg"
+ }
+
+ while {1} {
+ set line [gets $commandSocket]
+ if {[eof $commandSocket]} {
+ error "remote server disappaered"
+ }
+ if {$line eq "--Marker--Marker--Marker--"} {
+ lassign $result code info value
+ return -code $code -errorinfo $info $value
+ }
+ append result $line "\n"
+ }
+ }
+}
+
+proc getPort sock {
+ lindex [fconfigure $sock -sockname] 2
+}
+
+
+# ----------------------------------------------------------------------
+
+test socket_$af-1.1 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -server
+} -returnCodes error -result {no argument given for -server option}
+test socket_$af-1.2 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -server foo
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
+test socket_$af-1.3 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -myaddr
+} -returnCodes error -result {no argument given for -myaddr option}
+test socket_$af-1.4 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -myaddr $localhost
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
+test socket_$af-1.5 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -myport
+} -returnCodes error -result {no argument given for -myport option}
+test socket_$af-1.6 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -myport xxxx
+} -returnCodes error -result {expected integer but got "xxxx"}
+test socket_$af-1.7 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -myport 2522
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
+test socket_$af-1.8 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -froboz
+} -returnCodes error -result {bad option "-froboz": must be -async, -myaddr, -myport, or -server}
+test socket_$af-1.9 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -server foo -myport 2521 3333
+} -returnCodes error -result {option -myport is not valid for servers}
+test socket_$af-1.10 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket host 2528 -junk
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
+test socket_$af-1.11 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -server callback 2520 --
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
+test socket_$af-1.12 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket foo badport
+} -returnCodes error -result {expected integer but got "badport"}
+test socket_$af-1.13 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -async -server
+} -returnCodes error -result {cannot set -async option for server sockets}
+test socket_$af-1.14 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -server foo -async
+} -returnCodes error -result {cannot set -async option for server sockets}
+
+set path(script) [makeFile {} script]
+
+test socket_$af-2.1 {tcp connection} -constraints [list socket supported_$af stdio] -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f {
+ set timer [after 10000 "set x timed_out"]
+ set f [socket -server accept 0]
+ proc accept {file addr port} {
+ global x
+ set x done
+ close $file
+ }
+ puts ready
+ puts [lindex [fconfigure $f -sockname] 2]
+ vwait x
+ after cancel $timer
+ close $f
+ puts $x
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f x
+ gets $f listen
+} -body {
+ # $x == "ready" at this point
+ set sock [socket $localhost $listen]
+ lappend x [gets $f]
+ close $sock
+ lappend x [gets $f]
+} -cleanup {
+ close $f
+} -result {ready done {}}
+test socket_$af-2.2 {tcp connection with client port specified} -setup {
+ set port [randport]
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f {
+ set timer [after 10000 "set x timeout"]
+ set f [socket -server accept 0]
+ proc accept {file addr port} {
+ global x
+ puts "[gets $file] $port"
+ close $file
+ set x done
+ }
+ puts ready
+ puts [lindex [fconfigure $f -sockname] 2]
+ vwait x
+ after cancel $timer
+ close $f
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f x
+ gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+ # $x == "ready" at this point
+ set sock [socket -myport $port $localhost $listen]
+ puts $sock hello
+ flush $sock
+ lappend x [expr {[gets $f] eq "hello $port"}]
+ close $sock
+ return $x
+} -cleanup {
+ catch {close [socket $localhost $listen]}
+ close $f
+} -result {ready 1}
+test socket_$af-2.3 {tcp connection with client interface specified} -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f {
+ set timer [after 2000 "set x done"]
+ set f [socket -server accept 0]
+ proc accept {file addr port} {
+ global x
+ puts "[gets $file] $addr"
+ close $file
+ set x done
+ }
+ puts [lindex [fconfigure $f -sockname] 2]
+ puts ready
+ vwait x
+ after cancel $timer
+ close $f
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f listen
+ gets $f x
+} -constraints [list socket supported_$af stdio] -body {
+ # $x == "ready" at this point
+ set sock [socket -myaddr $localhost $localhost $listen]
+ puts $sock hello
+ flush $sock
+ lappend x [gets $f]
+ close $sock
+ return $x
+} -cleanup {
+ close $f
+} -result [list ready [list hello $localhost]]
+test socket_$af-2.4 {tcp connection with server interface specified} -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f [list set localhost $localhost]
+ puts $f {
+ set timer [after 2000 "set x done"]
+ set f [socket -server accept -myaddr $localhost 0]
+ proc accept {file addr port} {
+ global x
+ puts "[gets $file]"
+ close $file
+ set x done
+ }
+ puts ready
+ puts [lindex [fconfigure $f -sockname] 2]
+ vwait x
+ after cancel $timer
+ close $f
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f x
+ gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+ # $x == "ready" at this point
+ set sock [socket $localhost $listen]
+ puts $sock hello
+ flush $sock
+ lappend x [gets $f]
+ close $sock
+ return $x
+} -cleanup {
+ close $f
+} -result {ready hello}
+test socket_$af-2.5 {tcp connection with redundant server port} -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f {
+ set timer [after 10000 "set x timeout"]
+ set f [socket -server accept 0]
+ proc accept {file addr port} {
+ global x
+ puts "[gets $file]"
+ close $file
+ set x done
+ }
+ puts ready
+ puts [lindex [fconfigure $f -sockname] 2]
+ vwait x
+ after cancel $timer
+ close $f
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f x
+ gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+ # $x == "ready" at this point
+ set sock [socket $localhost $listen]
+ puts $sock hello
+ flush $sock
+ lappend x [gets $f]
+ close $sock
+ return $x
+} -cleanup {
+ close $f
+} -result {ready hello}
+test socket_$af-2.6 {tcp connection} -constraints [list socket supported_$af] -body {
+ set status ok
+ if {![catch {set sock [socket $localhost [randport]]}]} {
+ if {![catch {gets $sock}]} {
+ set status broken
+ }
+ close $sock
+ }
+ set status
+} -result ok
+test socket_$af-2.7 {echo server, one line} -constraints [list socket supported_$af stdio] -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f {
+ set timer [after 10000 "set x timeout"]
+ set f [socket -server accept 0]
+ proc accept {s a p} {
+ fileevent $s readable [list echo $s]
+ fconfigure $s -translation lf -buffering line
+ }
+ proc echo {s} {
+ set l [gets $s]
+ if {[eof $s]} {
+ global x
+ close $s
+ set x done
+ } else {
+ puts $s $l
+ }
+ }
+ puts ready
+ puts [lindex [fconfigure $f -sockname] 2]
+ vwait x
+ after cancel $timer
+ close $f
+ puts $x
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f
+ gets $f listen
+} -body {
+ set s [socket $localhost $listen]
+ fconfigure $s -buffering line -translation lf
+ puts $s "hello abcdefghijklmnop"
+ set x [gets $s]
+ close $s
+ list $x [gets $f]
+} -cleanup {
+ close $f
+} -result {{hello abcdefghijklmnop} done}
+removeFile script
+test socket_$af-2.8 {echo server, loop 50 times, single connection} -setup {
+ set path(script) [makeFile {
+ set f [socket -server accept 0]
+ proc accept {s a p} {
+ fileevent $s readable [list echo $s]
+ fconfigure $s -buffering line
+ }
+ proc echo {s} {
+ global i
+ set l [gets $s]
+ if {[eof $s]} {
+ global x
+ close $s
+ set x done
+ } else {
+ incr i
+ puts $s $l
+ }
+ }
+ set i 0
+ puts ready
+ puts [lindex [fconfigure $f -sockname] 2]
+ set timer [after 20000 "set x done"]
+ vwait x
+ after cancel $timer
+ close $f
+ puts "done $i"
+ } script]
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f
+ gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+ set s [socket $localhost $listen]
+ fconfigure $s -buffering line
+ catch {
+ for {set x 0} {$x < 50} {incr x} {
+ puts $s "hello abcdefghijklmnop"
+ gets $s
+ }
+ }
+ close $s
+ catch {set x [gets $f]}
+ return $x
+} -cleanup {
+ close $f
+ removeFile script
+} -result {done 50}
+set path(script) [makeFile {} script]
+test socket_$af-2.9 {socket conflict} -constraints [list socket supported_$af stdio] -body {
+ set s [socket -server accept 0]
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f [list set ::tcl::unsupported::socketAF $::tcl::unsupported::socketAF]
+ puts $f "socket -server accept [lindex [fconfigure $s -sockname] 2]"
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f
+ after 100
+ close $f
+} -returnCodes error -cleanup {
+ close $s
+} -match glob -result {couldn't open socket: address already in use*}
+test socket_$af-2.10 {close on accept, accepted socket lives} -setup {
+ set done 0
+ set timer [after 20000 "set done timed_out"]
+} -constraints [list socket supported_$af] -body {
+ set ss [socket -server accept 0]
+ proc accept {s a p} {
+ global ss
+ close $ss
+ fileevent $s readable "readit $s"
+ fconfigure $s -trans lf
+ }
+ proc readit {s} {
+ global done
+ gets $s
+ close $s
+ set done 1
+ }
+ set cs [socket $localhost [lindex [fconfigure $ss -sockname] 2]]
+ puts $cs hello
+ close $cs
+ vwait done
+ return $done
+} -cleanup {
+ after cancel $timer
+} -result 1
+test socket_$af-2.11 {detecting new data} -constraints [list socket supported_$af] -setup {
+ proc accept {s a p} {
+ global sock
+ set sock $s
+ }
+ set s [socket -server accept 0]
+ set sock ""
+} -body {
+ set s2 [socket $localhost [lindex [fconfigure $s -sockname] 2]]
+ vwait sock
+ puts $s2 one
+ flush $s2
+ after idle {set x 1}
+ vwait x
+ fconfigure $sock -blocking 0
+ set result a:[gets $sock]
+ lappend result b:[gets $sock]
+ fconfigure $sock -blocking 1
+ puts $s2 two
+ flush $s2
+ after $latency {set x 1}; # NetBSD fails here if we do [after idle]
+ vwait x
+ fconfigure $sock -blocking 0
+ lappend result c:[gets $sock]
+} -cleanup {
+ fconfigure $sock -blocking 1
+ close $s2
+ close $s
+ close $sock
+} -result {a:one b: c:two}
+
+test socket_$af-3.1 {socket conflict} -constraints [list socket supported_$af stdio] -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f [list set localhost $localhost]
+ puts $f {
+ set f [socket -server accept -myaddr $localhost 0]
+ puts ready
+ puts [lindex [fconfigure $f -sockname] 2]
+ gets stdin
+ close $f
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r+]
+ gets $f
+ gets $f listen
+} -body {
+ socket -server accept -myaddr $localhost $listen
+} -cleanup {
+ puts $f bye
+ close $f
+} -returnCodes error -result {couldn't open socket: address already in use}
+test socket_$af-3.2 {server with several clients} -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f [list set localhost $localhost]
+ puts $f {
+ set t1 [after 30000 "set x timed_out"]
+ set t2 [after 31000 "set x timed_out"]
+ set t3 [after 32000 "set x timed_out"]
+ set counter 0
+ set s [socket -server accept -myaddr $localhost 0]
+ proc accept {s a p} {
+ fileevent $s readable [list echo $s]
+ fconfigure $s -buffering line
+ }
+ proc echo {s} {
+ global x
+ set l [gets $s]
+ if {[eof $s]} {
+ close $s
+ set x done
+ } else {
+ puts $s $l
+ }
+ }
+ puts ready
+ puts [lindex [fconfigure $s -sockname] 2]
+ vwait x
+ after cancel $t1
+ vwait x
+ after cancel $t2
+ vwait x
+ after cancel $t3
+ close $s
+ puts $x
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r+]
+ set x [gets $f]
+ gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+ # $x == "ready" here
+ set s1 [socket $localhost $listen]
+ fconfigure $s1 -buffering line
+ set s2 [socket $localhost $listen]
+ fconfigure $s2 -buffering line
+ set s3 [socket $localhost $listen]
+ fconfigure $s3 -buffering line
+ for {set i 0} {$i < 100} {incr i} {
+ puts $s1 hello,s1
+ gets $s1
+ puts $s2 hello,s2
+ gets $s2
+ puts $s3 hello,s3
+ gets $s3
+ }
+ close $s1
+ close $s2
+ close $s3
+ lappend x [gets $f]
+} -cleanup {
+ close $f
+} -result {ready done}
+
+test socket_$af-4.1 {server with several clients} -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f [list set localhost $localhost]
+ puts $f {
+ set port [gets stdin]
+ set s [socket $localhost $port]
+ fconfigure $s -buffering line
+ for {set i 0} {$i < 100} {incr i} {
+ puts $s hello
+ gets $s
+ }
+ close $s
+ puts bye
+ gets stdin
+ }
+ close $f
+ set p1 [open "|[list [interpreter] $path(script)]" r+]
+ fconfigure $p1 -buffering line
+ set p2 [open "|[list [interpreter] $path(script)]" r+]
+ fconfigure $p2 -buffering line
+ set p3 [open "|[list [interpreter] $path(script)]" r+]
+ fconfigure $p3 -buffering line
+} -constraints [list socket supported_$af stdio] -body {
+ proc accept {s a p} {
+ fconfigure $s -buffering line
+ fileevent $s readable [list echo $s]
+ }
+ proc echo {s} {
+ global x
+ set l [gets $s]
+ if {[eof $s]} {
+ close $s
+ set x done
+ } else {
+ puts $s $l
+ }
+ }
+ set t1 [after 30000 "set x timed_out"]
+ set t2 [after 31000 "set x timed_out"]
+ set t3 [after 32000 "set x timed_out"]
+ set s [socket -server accept -myaddr $localhost 0]
+ set listen [lindex [fconfigure $s -sockname] 2]
+ puts $p1 $listen
+ puts $p2 $listen
+ puts $p3 $listen
+ vwait x
+ vwait x
+ vwait x
+ after cancel $t1
+ after cancel $t2
+ after cancel $t3
+ close $s
+ set l ""
+ lappend l [list p1 [gets $p1] $x]
+ lappend l [list p2 [gets $p2] $x]
+ lappend l [list p3 [gets $p3] $x]
+} -cleanup {
+ puts $p1 bye
+ puts $p2 bye
+ puts $p3 bye
+ close $p1
+ close $p2
+ close $p3
+} -result {{p1 bye done} {p2 bye done} {p3 bye done}}
+test socket_$af-4.2 {byte order problems, socket numbers, htons} -body {
+ close [socket -server dodo -myaddr $localhost 0x3000]
+ return ok
+} -constraints [list socket supported_$af] -result ok
+
+test socket_$af-5.1 {byte order problems, socket numbers, htons} -body {
+ if {![catch {socket -server dodo 0x1} msg]} {
+ close $msg
+ return {htons problem, should be disallowed, are you running as SU?}
+ }
+ return {couldn't open socket: not owner}
+} -constraints [list socket supported_$af unix notRoot] -result {couldn't open socket: not owner}
+test socket_$af-5.2 {byte order problems, socket numbers, htons} -body {
+ if {![catch {socket -server dodo 0x10000} msg]} {
+ close $msg
+ return {port resolution problem, should be disallowed}
+ }
+ return {couldn't open socket: port number too high}
+} -constraints [list socket supported_$af] -result {couldn't open socket: port number too high}
+test socket_$af-5.3 {byte order problems, socket numbers, htons} -body {
+ if {![catch {socket -server dodo 21} msg]} {
+ close $msg
+ return {htons problem, should be disallowed, are you running as SU?}
+ }
+ return {couldn't open socket: not owner}
+} -constraints [list socket supported_$af unix notRoot] -result {couldn't open socket: not owner}
+
+test socket_$af-6.1 {accept callback error} -constraints [list socket supported_$af stdio] -setup {
+ proc myHandler {msg options} {
+ variable x $msg
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+ file delete $path(script)
+} -body {
+ set f [open $path(script) w]
+ puts $f [list set localhost $localhost]
+ puts $f {
+ gets stdin port
+ socket $localhost $port
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r+]
+ proc accept {s a p} {expr 10 / 0}
+ set s [socket -server accept -myaddr $localhost 0]
+ puts $f [lindex [fconfigure $s -sockname] 2]
+ close $f
+ set timer [after 10000 "set x timed_out"]
+ vwait x
+ after cancel $timer
+ close $s
+ return $x
+} -cleanup {
+ interp bgerror {} $handler
+} -result {divide by zero}
+
+test socket_$af-6.2 {
+ readable fileevent on server socket
+} -setup {
+ set sock [socket -server dummy 0]
+} -constraints [list socket supported_$af] -body {
+ fileevent $sock readable dummy
+} -cleanup {
+ close $sock
+} -returnCodes 1 -result "channel is not readable"
+
+test socket_$af-6.3 {writable fileevent on server socket} -setup {
+ set sock [socket -server dummy 0]
+} -constraints [list socket supported_$af] -body {
+ fileevent $sock writable dummy
+} -cleanup {
+ close $sock
+} -returnCodes 1 -result "channel is not writable"
+
+test socket_$af-7.1 {testing socket specific options} -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f {
+ set ss [socket -server accept 0]
+ proc accept args {
+ global x
+ set x done
+ }
+ puts ready
+ puts [lindex [fconfigure $ss -sockname] 2]
+ set timer [after 10000 "set x timed_out"]
+ vwait x
+ after cancel $timer
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f
+ gets $f listen
+ set l ""
+} -constraints [list socket supported_$af stdio] -body {
+ set s [socket $localhost $listen]
+ set p [fconfigure $s -peername]
+ close $s
+ lappend l [string compare [lindex $p 0] $localhost]
+ lappend l [string compare [lindex $p 2] $listen]
+ lappend l [llength $p]
+} -cleanup {
+ close $f
+} -result {0 0 3}
+test socket_$af-7.2 {testing socket specific options} -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f [list set ::tcl::unsupported::socketAF $::tcl::unsupported::socketAF]
+ puts $f {
+ set ss [socket -server accept 0]
+ proc accept args {
+ global x
+ set x done
+ }
+ puts ready
+ puts [lindex [fconfigure $ss -sockname] 2]
+ set timer [after 10000 "set x timed_out"]
+ vwait x
+ after cancel $timer
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f
+ gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+ set s [socket $localhost $listen]
+ set p [fconfigure $s -sockname]
+ close $s
+ list [llength $p] \
+ [regexp {^(127\.0\.0\.1|0\.0\.0\.0|::1)$} [lindex $p 0]] \
+ [expr {[lindex $p 2] == $listen}]
+} -cleanup {
+ close $f
+} -result {3 1 0}
+test socket_$af-7.3 {testing socket specific options} -constraints [list socket supported_$af] -body {
+ set s [socket -server accept -myaddr $localhost 0]
+ set l [fconfigure $s]
+ close $s
+ update
+ llength $l
+} -result 14
+test socket_$af-7.4 {testing socket specific options} -constraints [list socket supported_$af] -setup {
+ set timer [after 10000 "set x timed_out"]
+ set l ""
+} -body {
+ set s [socket -server accept -myaddr $localhost 0]
+ proc accept {s a p} {
+ global x
+ set x [fconfigure $s -sockname]
+ close $s
+ }
+ set listen [lindex [fconfigure $s -sockname] 2]
+ set s1 [socket $localhost $listen]
+ vwait x
+ lappend l [expr {[lindex $x 2] == $listen}] [llength $x]
+} -cleanup {
+ after cancel $timer
+ close $s
+ close $s1
+} -result {1 3}
+test socket_$af-7.5 {testing socket specific options} -setup {
+ set timer [after 10000 "set x timed_out"]
+ set l ""
+} -constraints [list socket supported_$af unixOrPc] -body {
+ set s [socket -server accept 0]
+ proc accept {s a p} {
+ global x
+ set x [fconfigure $s -sockname]
+ close $s
+ }
+ set listen [lindex [fconfigure $s -sockname] 2]
+ set s1 [socket $localhost $listen]
+ vwait x
+ lappend l [lindex $x 0] [expr {[lindex $x 2] == $listen}] [llength $x]
+} -cleanup {
+ after cancel $timer
+ close $s
+ close $s1
+} -result [list $localhost 1 3]
+
+test socket_$af-8.1 {testing -async flag on sockets} -constraints [list socket supported_$af] -body {
+ # NOTE: This test may fail on some Solaris 2.4 systems. If it does, check
+ # that you have these patches installed (using showrev -p):
+ #
+ # 101907-05, 101925-02, 101945-14, 101959-03, 101969-05, 101973-03,
+ # 101977-03, 101981-02, 101985-01, 102001-03, 102003-01, 102007-01,
+ # 102011-02, 102024-01, 102039-01, 102044-01, 102048-01, 102062-03,
+ # 102066-04, 102070-01, 102105-01, 102153-03, 102216-01, 102232-01,
+ # 101878-03, 101879-01, 101880-03, 101933-01, 101950-01, 102030-01,
+ # 102057-08, 102140-01, 101920-02, 101921-09, 101922-07, 101923-03
+ #
+ # If after installing these patches you are still experiencing a problem,
+ # please email jyl@eng.sun.com. We have not observed this failure on
+ # Solaris 2.5, so another option (instead of installing these patches) is
+ # to upgrade to Solaris 2.5.
+ set s [socket -server accept -myaddr $localhost 0]
+ proc accept {s a p} {
+ global x
+ puts $s bye
+ close $s
+ set x done
+ }
+ set s1 [socket -async $localhost [lindex [fconfigure $s -sockname] 2]]
+ vwait x
+ gets $s1
+} -cleanup {
+ close $s
+ close $s1
+} -result bye
+
+test socket_$af-9.1 {testing spurious events} -constraints [list socket supported_$af] -setup {
+ set len 0
+ set spurious 0
+ set done 0
+ set timer [after 10000 "set done timed_out"]
+} -body {
+ proc readlittle {s} {
+ global spurious done len
+ set l [read $s 1]
+ if {[string length $l] == 0} {
+ if {![eof $s]} {
+ incr spurious
+ } else {
+ close $s
+ set done 1
+ }
+ } else {
+ incr len [string length $l]
+ }
+ }
+ proc accept {s a p} {
+ fconfigure $s -buffering none -blocking off
+ fileevent $s readable [list readlittle $s]
+ }
+ set s [socket -server accept -myaddr $localhost 0]
+ set c [socket $localhost [lindex [fconfigure $s -sockname] 2]]
+ puts -nonewline $c 01234567890123456789012345678901234567890123456789
+ close $c
+ vwait done
+ close $s
+ list $spurious $len
+} -cleanup {
+ after cancel $timer
+} -result {0 50}
+test socket_$af-9.2 {testing async write, fileevents, flush on close} -constraints [list socket supported_$af] -setup {
+ set firstblock ""
+ for {set i 0} {$i < 5} {incr i} {set firstblock "a$firstblock$firstblock"}
+ set secondblock ""
+ for {set i 0} {$i < 16} {incr i} {
+ set secondblock "b$secondblock$secondblock"
+ }
+ set timer [after 10000 "set done timed_out"]
+ set l [socket -server accept -myaddr $localhost 0]
+ proc accept {s a p} {
+ fconfigure $s -blocking 0 -translation lf -buffersize 16384 \
+ -buffering line
+ fileevent $s readable "readable $s"
+ }
+ proc readable {s} {
+ set l [gets $s]
+ fileevent $s readable {}
+ after idle respond $s
+ }
+ proc respond {s} {
+ global firstblock
+ puts -nonewline $s $firstblock
+ after idle writedata $s
+ }
+ proc writedata {s} {
+ global secondblock
+ puts -nonewline $s $secondblock
+ close $s
+ }
+} -body {
+ set s [socket $localhost [lindex [fconfigure $l -sockname] 2]]
+ fconfigure $s -blocking 0 -trans lf -buffering line
+ set count 0
+ puts $s hello
+ proc readit {s} {
+ global count done
+ set l [read $s]
+ incr count [string length $l]
+ if {[eof $s]} {
+ close $s
+ set done 1
+ }
+ }
+ fileevent $s readable "readit $s"
+ vwait done
+ return $count
+} -cleanup {
+ close $l
+ after cancel $timer
+} -result 65566
+test socket_$af-9.3 {testing EOF stickyness} -constraints [list socket supported_$af] -setup {
+ set count 0
+ set done false
+ proc write_then_close {s} {
+ puts $s bye
+ close $s
+ }
+ proc accept {s a p} {
+ fconfigure $s -buffering line -translation lf
+ fileevent $s writable "write_then_close $s"
+ }
+ set s [socket -server accept -myaddr $localhost 0]
+} -body {
+ proc count_to_eof {s} {
+ global count done
+ set l [gets $s]
+ if {[eof $s]} {
+ incr count
+ if {$count > 9} {
+ close $s
+ set done true
+ set count {eof is sticky}
+ }
+ }
+ }
+ proc timerproc {s} {
+ global done count
+ set done true
+ set count {timer went off, eof is not sticky}
+ close $s
+ }
+ set c [socket $localhost [lindex [fconfigure $s -sockname] 2]]
+ fconfigure $c -blocking off -buffering line -translation lf
+ fileevent $c readable "count_to_eof $c"
+ set timer [after 1000 timerproc $c]
+ vwait done
+ return $count
+} -cleanup {
+ close $s
+ after cancel $timer
+} -result {eof is sticky}
+
+removeFile script
+
+test socket_$af-10.1 {testing socket accept callback error handling} \
+ -constraints [list socket supported_$af] -setup {
+ variable goterror 0
+ proc myHandler {msg options} {
+ variable goterror 1
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+} -body {
+ set s [socket -server accept -myaddr $localhost 0]
+ proc accept {s a p} {close $s; error}
+ set c [socket $localhost [lindex [fconfigure $s -sockname] 2]]
+ vwait goterror
+ close $s
+ close $c
+ return $goterror
+} -cleanup {
+ interp bgerror {} $handler
+} -result 1
+
+test socket_$af-11.1 {tcp connection} -setup {
+ set port [sendCommand {
+ set server [socket -server accept 0]
+ proc accept {s a p} {
+ puts $s done
+ close $s
+ }
+ getPort $server
+ }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ set s [socket $remoteServerIP $port]
+ gets $s
+} -cleanup {
+ close $s
+ sendCommand {close $server}
+} -result done
+test socket_$af-11.2 {client specifies its port} -setup {
+ set lport [randport]
+ set rport [sendCommand {
+ set server [socket -server accept 0]
+ proc accept {s a p} {
+ puts $s $p
+ close $s
+ }
+ getPort $server
+ }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ set s [socket -myport $lport $remoteServerIP $rport]
+ set r [gets $s]
+ expr {$r==$lport ? "ok" : "broken: $r != $port"}
+} -cleanup {
+ close $s
+ sendCommand {close $server}
+} -result ok
+test socket_$af-11.3 {trying to connect, no server} -body {
+ set status ok
+ if {![catch {set s [socket $remoteServerIp [randport]]}]} {
+ if {![catch {gets $s}]} {
+ set status broken
+ }
+ close $s
+ }
+ return $status
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -result ok
+test socket_$af-11.4 {remote echo, one line} -setup {
+ set port [sendCommand {
+ set server [socket -server accept 0]
+ proc accept {s a p} {
+ fileevent $s readable [list echo $s]
+ fconfigure $s -buffering line -translation crlf
+ }
+ proc echo {s} {
+ set l [gets $s]
+ if {[eof $s]} {
+ close $s
+ } else {
+ puts $s $l
+ }
+ }
+ getPort $server
+ }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ set f [socket $remoteServerIP $port]
+ fconfigure $f -translation crlf -buffering line
+ puts $f hello
+ gets $f
+} -cleanup {
+ catch {close $f}
+ sendCommand {close $server}
+} -result hello
+test socket_$af-11.5 {remote echo, 50 lines} -setup {
+ set port [sendCommand {
+ set server [socket -server accept 0]
+ proc accept {s a p} {
+ fileevent $s readable [list echo $s]
+ fconfigure $s -buffering line -translation crlf
+ }
+ proc echo {s} {
+ set l [gets $s]
+ if {[eof $s]} {
+ close $s
+ } else {
+ puts $s $l
+ }
+ }
+ getPort $server
+ }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ set f [socket $remoteServerIP $port]
+ fconfigure $f -translation crlf -buffering line
+ for {set cnt 0} {$cnt < 50} {incr cnt} {
+ puts $f "hello, $cnt"
+ if {[gets $f] != "hello, $cnt"} {
+ break
+ }
+ }
+ return $cnt
+} -cleanup {
+ close $f
+ sendCommand {close $server}
+} -result 50
+test socket_$af-11.6 {socket conflict} -setup {
+ set s1 [socket -server accept -myaddr $localhost 0]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ set s2 [socket -server accept -myaddr $localhost [getPort $s1]]
+ list [getPort $s2] [close $s2]
+} -cleanup {
+ close $s1
+} -returnCodes error -result {couldn't open socket: address already in use}
+test socket_$af-11.7 {server with several clients} -setup {
+ set port [sendCommand {
+ set server [socket -server accept 0]
+ proc accept {s a p} {
+ fconfigure $s -buffering line
+ fileevent $s readable [list echo $s]
+ }
+ proc echo {s} {
+ set l [gets $s]
+ if {[eof $s]} {
+ close $s
+ } else {
+ puts $s $l
+ }
+ }
+ getPort $server
+ }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ set s1 [socket $remoteServerIP $port]
+ fconfigure $s1 -buffering line
+ set s2 [socket $remoteServerIP $port]
+ fconfigure $s2 -buffering line
+ set s3 [socket $remoteServerIP $port]
+ fconfigure $s3 -buffering line
+ for {set i 0} {$i < 100} {incr i} {
+ puts $s1 hello,s1
+ gets $s1
+ puts $s2 hello,s2
+ gets $s2
+ puts $s3 hello,s3
+ gets $s3
+ }
+ return $i
+} -cleanup {
+ close $s1
+ close $s2
+ close $s3
+ sendCommand {close $server}
+} -result 100
+test socket_$af-11.8 {client with several servers} -setup {
+ lassign [sendCommand {
+ set s1 [socket -server "accept server1" 0]
+ set s2 [socket -server "accept server2" 0]
+ set s3 [socket -server "accept server3" 0]
+ proc accept {mp s a p} {
+ puts $s $mp
+ close $s
+ }
+ list [getPort $s1] [getPort $s2] [getPort $s3]
+ }] p1 p2 p3
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ set s1 [socket $remoteServerIP $p1]
+ set s2 [socket $remoteServerIP $p2]
+ set s3 [socket $remoteServerIP $p3]
+ list [gets $s1] [gets $s1] [eof $s1] [gets $s2] [gets $s2] [eof $s2] \
+ [gets $s3] [gets $s3] [eof $s3]
+} -cleanup {
+ close $s1
+ close $s2
+ close $s3
+ sendCommand {
+ close $s1
+ close $s2
+ close $s3
+ }
+} -result {server1 {} 1 server2 {} 1 server3 {} 1}
+test socket_$af-11.9 {accept callback error} -constraints [list socket supported_$af doTestsWithRemoteServer] -setup {
+ proc myHandler {msg options} {
+ variable x $msg
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+ set timer [after 10000 "set x timed_out"]
+} -body {
+ set s [socket -server accept 0]
+ proc accept {s a p} {expr {10 / 0}}
+ sendCommand "set port [getPort $s]"
+ if {[catch {
+ sendCommand {
+ set peername [fconfigure $callerSocket -peername]
+ set s [socket [lindex $peername 0] $port]
+ close $s
+ }
+ } msg]} then {
+ close $s
+ error $msg
+ }
+ vwait x
+ return $x
+} -cleanup {
+ close $s
+ after cancel $timer
+ interp bgerror {} $handler
+} -result {divide by zero}
+test socket_$af-11.10 {testing socket specific options} -setup {
+ set port [sendCommand {
+ set server [socket -server accept 0]
+ proc accept {s a p} {close $s}
+ getPort $server
+ }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ set s [socket $remoteServerIP $port]
+ set p [fconfigure $s -peername]
+ set n [fconfigure $s -sockname]
+ list [expr {[lindex $p 2] == $port}] [llength $p] [llength $n]
+} -cleanup {
+ close $s
+ sendCommand {close $server}
+} -result {1 3 3}
+test socket_$af-11.11 {testing spurious events} -setup {
+ set port [sendCommand {
+ set server [socket -server accept 0]
+ proc accept {s a p} {
+ fconfigure $s -translation "auto lf"
+ after idle writesome $s
+ }
+ proc writesome {s} {
+ for {set i 0} {$i < 100} {incr i} {
+ puts $s "line $i from remote server"
+ }
+ close $s
+ }
+ getPort $server
+ }]
+ set len 0
+ set spurious 0
+ set done 0
+ set timer [after 40000 "set done timed_out"]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ proc readlittle {s} {
+ global spurious done len
+ set l [read $s 1]
+ if {[string length $l] == 0} {
+ if {![eof $s]} {
+ incr spurious
+ } else {
+ close $s
+ set done 1
+ }
+ } else {
+ incr len [string length $l]
+ }
+ }
+ set c [socket $remoteServerIP $port]
+ fileevent $c readable "readlittle $c"
+ vwait done
+ list $spurious $len $done
+} -cleanup {
+ after cancel $timer
+ sendCommand {close $server}
+} -result {0 2690 1}
+test socket_$af-11.12 {testing EOF stickyness} -constraints [list socket supported_$af doTestsWithRemoteServer] -setup {
+ set counter 0
+ set done 0
+ set port [sendCommand {
+ set server [socket -server accept 0]
+ proc accept {s a p} {
+ after idle close $s
+ }
+ getPort $server
+ }]
+ proc timed_out {} {
+ global c done
+ set done {timed_out, EOF is not sticky}
+ close $c
+ }
+ set after_id [after 1000 timed_out]
+} -body {
+ proc count_up {s} {
+ global counter done
+ set l [gets $s]
+ if {[eof $s]} {
+ incr counter
+ if {$counter > 9} {
+ set done {EOF is sticky}
+ close $s
+ }
+ }
+ }
+ set c [socket $remoteServerIP $port]
+ fileevent $c readable [list count_up $c]
+ vwait done
+ return $done
+} -cleanup {
+ after cancel $after_id
+ sendCommand {close $server}
+} -result {EOF is sticky}
+test socket_$af-11.13 {testing async write, async flush, async close} -setup {
+ set port [sendCommand {
+ set firstblock ""
+ for {set i 0} {$i < 5} {incr i} {
+ set firstblock "a$firstblock$firstblock"
+ }
+ set secondblock ""
+ for {set i 0} {$i < 16} {incr i} {
+ set secondblock "b$secondblock$secondblock"
+ }
+ set l [socket -server accept 0]
+ proc accept {s a p} {
+ fconfigure $s -blocking 0 -translation lf -buffersize 16384 \
+ -buffering line
+ fileevent $s readable "readable $s"
+ }
+ proc readable {s} {
+ set l [gets $s]
+ fileevent $s readable {}
+ after idle respond $s
+ }
+ proc respond {s} {
+ global firstblock
+ puts -nonewline $s $firstblock
+ after idle writedata $s
+ }
+ proc writedata {s} {
+ global secondblock
+ puts -nonewline $s $secondblock
+ close $s
+ }
+ getPort $l
+ }]
+ set timer [after 10000 "set done timed_out"]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ proc readit {s} {
+ global count done
+ set l [read $s]
+ incr count [string length $l]
+ if {[eof $s]} {
+ close $s
+ set done 1
+ }
+ }
+ set s [socket $remoteServerIP $port]
+ fconfigure $s -blocking 0 -trans lf -buffering line
+ set count 0
+ puts $s hello
+ fileevent $s readable "readit $s"
+ vwait done
+ return $count
+} -cleanup {
+ after cancel $timer
+ sendCommand {close $l}
+} -result 65566
+
+set path(script1) [makeFile {} script1]
+set path(script2) [makeFile {} script2]
+
+test socket_$af-12.1 {testing inheritance of server sockets} -setup {
+ file delete $path(script1)
+ file delete $path(script2)
+ # Script1 is just a 10 second delay. If the server socket is inherited, it
+ # will be held open for 10 seconds
+ set f [open $path(script1) w]
+ puts $f {
+ fileevent stdin readable exit
+ after 10000 exit
+ vwait forever
+ }
+ close $f
+ # Script2 creates the server socket, launches script1, and exits.
+ # The server socket will now be closed unless script1 inherited it.
+ set f [open $path(script2) w]
+ puts $f [list set tcltest [interpreter]]
+ puts $f [list set delay $path(script1)]
+ puts $f [list set localhost $localhost]
+ puts $f {
+ set f [socket -server accept -myaddr $localhost 0]
+ proc accept { file addr port } {
+ close $file
+ }
+ exec $tcltest $delay &
+ puts [lindex [fconfigure $f -sockname] 2]
+ close $f
+ exit
+ }
+ close $f
+} -constraints [list socket supported_$af stdio exec] -body {
+ # Launch script2 and wait 5 seconds
+ ### exec [interpreter] script2 &
+ set p [open "|[list [interpreter] $path(script2)]" r]
+ # If we can still connect to the server, the socket got inherited.
+ if {[catch {close [socket $localhost $listen]}]} {
+ return {server socket was not inherited}
+ } else {
+ return {server socket was inherited}
+ }
+} -cleanup {
+ catch {close $p}
+} -result {server socket was not inherited}
+test socket_$af-12.2 {testing inheritance of client sockets} -setup {
+ file delete $path(script1)
+ file delete $path(script2)
+ # Script1 is just a 20 second delay. If the server socket is inherited, it
+ # will be held open for 20 seconds
+ set f [open $path(script1) w]
+ puts $f {
+ fileevent stdin readable exit
+ after 20000 exit
+ vwait forever
+ }
+ close $f
+ # Script2 opens the client socket and writes to it. It then launches
+ # script1 and exits. If the child process inherited the client socket, the
+ # socket will still be open.
+ set f [open $path(script2) w]
+ puts $f [list set tcltest [interpreter]]
+ puts $f [list set delay $path(script1)]
+ puts $f [list set localhost $localhost]
+ puts $f {
+ gets stdin port
+ set f [socket $localhost $port]
+ exec $tcltest $delay &
+ puts $f testing
+ flush $f
+ exit
+ }
+ close $f
+ # If the socket doesn't hit end-of-file in 10 seconds, the script1 process
+ # must have inherited the client.
+ set failed 0
+ set after [after 10000 [list set failed 1]]
+} -constraints [list socket supported_$af stdio exec] -body {
+ # Create the server socket
+ set server [socket -server accept -myaddr $localhost 0]
+ proc accept { file host port } {
+ # When the client connects, establish the read handler
+ global server
+ close $server
+ fileevent $file readable [list getdata $file]
+ fconfigure $file -buffering line -blocking 0
+ }
+ proc getdata { file } {
+ # Read handler on the accepted socket.
+ global x failed
+ set status [catch {read $file} data]
+ if {$status != 0} {
+ set x {read failed, error was $data}
+ catch { close $file }
+ } elseif {$data ne ""} {
+ } elseif {[fblocked $file]} {
+ } elseif {[eof $file]} {
+ if {$failed} {
+ set x {client socket was inherited}
+ } else {
+ set x {client socket was not inherited}
+ }
+ catch { close $file }
+ } else {
+ set x {impossible case}
+ catch { close $file }
+ }
+ }
+ # Launch the script2 process
+ ### exec [interpreter] script2 &
+ set p [open "|[list [interpreter] $path(script2)]" w]
+ puts $p [lindex [fconfigure $server -sockname] 2] ; flush $p
+ vwait x
+ return $x
+} -cleanup {
+ after cancel $after
+ close $p
+} -result {client socket was not inherited}
+test socket_$af-12.3 {testing inheritance of accepted sockets} -setup {
+ file delete $path(script1)
+ file delete $path(script2)
+ set f [open $path(script1) w]
+ puts $f {
+ fileevent stdin readable exit
+ after 10000 exit
+ vwait forever
+ }
+ close $f
+ set f [open $path(script2) w]
+ puts $f [list set tcltest [interpreter]]
+ puts $f [list set delay $path(script1)]
+ puts $f [list set localhost $localhost]
+ puts $f {
+ set server [socket -server accept -myaddr $localhost 0]
+ proc accept { file host port } {
+ global tcltest delay
+ puts $file {test data on socket}
+ exec $tcltest $delay &
+ after idle exit
+ }
+ puts stdout [lindex [fconfigure $server -sockname] 2]
+ vwait forever
+ }
+ close $f
+} -constraints [list socket supported_$af stdio exec] -body {
+ # Launch the script2 process and connect to it. See how long the socket
+ # stays open
+ ## exec [interpreter] script2 &
+ set p [open "|[list [interpreter] $path(script2)]" r]
+ gets $p listen
+ set f [socket $localhost $listen]
+ fconfigure $f -buffering full -blocking 0
+ fileevent $f readable [list getdata $f]
+ # If the socket is still open after 5 seconds, the script1 process must
+ # have inherited the accepted socket.
+ set failed 0
+ set after [after 5000 [list set failed 1]]
+ proc getdata { file } {
+ # Read handler on the client socket.
+ global x
+ global failed
+ set status [catch {read $file} data]
+ if {$status != 0} {
+ set x {read failed, error was $data}
+ catch { close $file }
+ } elseif {[string compare {} $data]} {
+ } elseif {[fblocked $file]} {
+ } elseif {[eof $file]} {
+ if {$failed} {
+ set x {accepted socket was inherited}
+ } else {
+ set x {accepted socket was not inherited}
+ }
+ catch { close $file }
+ } else {
+ set x {impossible case}
+ catch { close $file }
+ }
+ return
+ }
+ vwait x
+ return $x
+} -cleanup {
+ after cancel $after
+ catch {close $p}
+} -result {accepted socket was not inherited}
+
+test socket_$af-13.1 {Testing use of shared socket between two threads} -body {
+ # create a thread
+ set serverthread [thread::create -preserved [string map [list @localhost@ $localhost] {
+ set f [socket -server accept -myaddr @localhost@ 0]
+ set listen [lindex [fconfigure $f -sockname] 2]
+ proc accept {s a p} {
+ fileevent $s readable [list echo $s]
+ fconfigure $s -buffering line
+ }
+ proc echo {s} {
+ global i
+ set l [gets $s]
+ if {[eof $s]} {
+ global x
+ close $s
+ set x done
+ } else {
+ incr i
+ puts $s $l
+ }
+ }
+ set i 0
+ vwait x
+ close $f
+ thread::wait
+ }]]
+ set port [thread::send $serverthread {set listen}]
+ set s [socket $localhost $port]
+ fconfigure $s -buffering line
+ catch {
+ puts $s "hello"
+ gets $s result
+ }
+ close $s
+ thread::release $serverthread
+ append result " " [llength [thread::names]]
+} -result {hello 1} -constraints [list socket supported_$af thread]
+
+# ----------------------------------------------------------------------
+
+removeFile script1
+removeFile script2
+
+# cleanup
+if {$remoteProcChan ne ""} {
+ catch {sendCommand exit}
+}
+catch {close $commandSocket}
+catch {close $remoteProcChan}
+}
+unset ::tcl::unsupported::socketAF
+test socket-14.0 {[socket -async] when server only listens on IPv4} \
+ -constraints [list socket supported_any localhost_v4] \
+ -setup {
+ proc accept {s a p} {
+ global x
+ puts $s bye
+ close $s
+ set x ok
+ }
+ set server [socket -server accept -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $server -sockname] 2]
+ } -body {
+ set client [socket -async localhost $port]
+ set after [after 1000 {set x [fconfigure $client -error]}]
+ vwait x
+ set x
+ } -cleanup {
+ after cancel $after
+ close $server
+ close $client
+ unset x
+ } -result ok
+test socket-14.1 {[socket -async] fileevent while still connecting} \
+ -constraints [list socket supported_any] \
+ -setup {
+ proc accept {s a p} {
+ global x
+ puts $s bye
+ close $s
+ lappend x ok
+ }
+ set server [socket -server accept -myaddr localhost 0]
+ set port [lindex [fconfigure $server -sockname] 2]
+ set x ""
+ } -body {
+ set client [socket -async localhost $port]
+ fileevent $client writable {
+ lappend x [fconfigure $client -error]
+ fileevent $client writable {}
+ }
+ set after [after 1000 {lappend x timeout}]
+ while {[llength $x] < 2 && "timeout" ni $x} {
+ vwait x
+ }
+ lsort $x; # we only want to see both events, the order doesn't matter
+ } -cleanup {
+ after cancel $after
+ close $server
+ close $client
+ unset x
+ } -result {{} ok}
+test socket-14.2 {[socket -async] fileevent connection refused} \
+ -constraints [list socket supported_any] \
+ -body {
+ if {[catch {socket -async localhost [randport]} client]} {
+ regexp {[^:]*: (.*)} $client -> x
+ } else {
+ fileevent $client writable {set x [fconfigure $client -error]}
+ set after [after 1000 {set x timeout}]
+ vwait x
+ after cancel $after
+ if {$x eq "timeout"} {
+ append x ": [fconfigure $client -error]"
+ }
+ close $client
+ }
+ set x
+ } -cleanup {
+ unset x
+ } -result "connection refused"
+test socket-14.3 {[socket -async] when server only listens on IPv6} \
+ -constraints [list socket supported_any localhost_v6] \
+ -setup {
+ proc accept {s a p} {
+ global x
+ puts $s bye
+ close $s
+ set x ok
+ }
+ set server [socket -server accept -myaddr ::1 0]
+ set port [lindex [fconfigure $server -sockname] 2]
+ } -body {
+ set client [socket -async localhost $port]
+ set after [after 1000 {set x [fconfigure $client -error]}]
+ vwait x
+ set x
+ } -cleanup {
+ after cancel $after
+ close $server
+ close $client
+ unset x
+ } -result ok
+test socket-14.4 {[socket -async] and both, readdable and writable fileevents} \
+ -constraints [list socket supported_any] \
+ -setup {
+ proc accept {s a p} {
+ puts $s bye
+ close $s
+ }
+ set server [socket -server accept -myaddr localhost 0]
+ set port [lindex [fconfigure $server -sockname] 2]
+ set x ""
+ } -body {
+ set client [socket -async localhost $port]
+ fileevent $client writable {
+ lappend x [fconfigure $client -error]
+ fileevent $client writable {}
+ }
+ fileevent $client readable {lappend x [gets $client]}
+ set after [after 1000 {lappend x timeout}]
+ while {[llength $x] < 2 && "timeout" ni $x} {
+ vwait x
+ }
+ lsort $x
+ } -cleanup {
+ after cancel $after
+ close $client
+ close $server
+ } -result {{} bye}
+test socket-14.5 {[socket -async] which fails before any connect() can be made} \
+ -constraints [list socket supported_any] \
+ -body {
+ # address from rfc5737
+ socket -async -myaddr 192.0.2.42 127.0.0.1 [randport]
+ } \
+ -returnCodes 1 \
+ -result {couldn't open socket: cannot assign requested address}
+::tcltest::cleanupTests
+flush stdout
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/source.test b/library/msgcat/tests/source.test
new file mode 100644
index 0000000..d71212d
--- /dev/null
+++ b/library/msgcat/tests/source.test
@@ -0,0 +1,302 @@
+# Commands covered: source
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 by Scriptics Corporation.
+# 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.
+
+if {[catch {package require tcltest 2.1}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2.1 required."
+ return
+}
+
+namespace eval ::tcl::test::source {
+ namespace import ::tcltest::*
+
+test source-1.1 {source command} -setup {
+ set x "old x value"
+ set y "old y value"
+ set z "old z value"
+ set sourcefile [makeFile {
+ set x 22
+ set y 33
+ set z 44
+ } source.file]
+} -body {
+ source $sourcefile
+ list $x $y $z
+} -cleanup {
+ removeFile source.file
+} -result {22 33 44}
+test source-1.2 {source command} -setup {
+ set sourcefile [makeFile {list result} source.file]
+} -body {
+ source $sourcefile
+} -cleanup {
+ removeFile source.file
+} -result result
+test source-1.3 {source command} -setup {
+ set sourcefile [makeFile {} source.file]
+ set fd [open $sourcefile w]
+ fconfigure $fd -translation lf
+ puts $fd "list a b c \\"
+ puts $fd "d e f"
+ close $fd
+} -body {
+ source $sourcefile
+} -cleanup {
+ removeFile source.file
+} -result {a b c d e f}
+
+proc ListGlobMatch {expected actual} {
+ if {[llength $expected] != [llength $actual]} {
+ return 0
+ }
+ foreach e $expected a $actual {
+ if {![string match $e $a]} {
+ return 0
+ }
+ }
+ return 1
+}
+customMatch listGlob [namespace which ListGlobMatch]
+
+test source-2.3 {source error conditions} -setup {
+ set sourcefile [makeFile {
+ set x 146
+ error "error in sourced file"
+ set y $x
+ } source.file]
+} -body {
+ list [catch {source $sourcefile} msg] $msg $::errorInfo
+} -cleanup {
+ removeFile source.file
+} -match listGlob -result [list 1 {error in sourced file} \
+ {error in sourced file
+ while executing
+"error "error in sourced file""
+ (file "*source.file" line 3)
+ invoked from within
+"source $sourcefile"}]
+test source-2.4 {source error conditions} -setup {
+ set sourcefile [makeFile {break} source.file]
+} -body {
+ source $sourcefile
+} -cleanup {
+ removeFile source.file
+} -returnCodes break
+test source-2.5 {source error conditions} -setup {
+ set sourcefile [makeFile {continue} source.file]
+} -body {
+ source $sourcefile
+} -cleanup {
+ removeFile source.file
+} -returnCodes continue
+test source-2.6 {source error conditions} -setup {
+ set sourcefile [makeFile {} _non_existent_]
+ removeFile _non_existent_
+} -body {
+ list [catch {source $sourcefile} msg] $msg $::errorCode
+} -match listGlob -result [list 1 \
+ {couldn't read file "*_non_existent_": no such file or directory} \
+ {POSIX ENOENT {no such file or directory}}]
+test source-2.7 {utf-8 with BOM} -setup {
+ set sourcefile [makeFile {} source.file]
+} -body {
+ set out [open $sourcefile w]
+ fconfigure $out -encoding utf-8
+ puts $out "\ufeffset y new-y"
+ close $out
+ set y old-y
+ source -encoding utf-8 $sourcefile
+ return $y
+} -cleanup {
+ removeFile $sourcefile
+} -result {new-y}
+
+test source-3.1 {return in middle of source file} -setup {
+ set sourcefile [makeFile {
+ set x new-x
+ return allDone
+ set y new-y
+ } source.file]
+} -body {
+ set x old-x
+ set y old-y
+ set z [source $sourcefile]
+ list $x $y $z
+} -cleanup {
+ removeFile source.file
+} -result {new-x old-y allDone}
+test source-3.2 {return with special code etc.} -setup {
+ set sourcefile [makeFile {
+ set x new-x
+ return -code break "Silly result"
+ set y new-y
+ } source.file]
+} -body {
+ source $sourcefile
+} -cleanup {
+ removeFile source.file
+} -returnCodes break -result {Silly result}
+test source-3.3 {return with special code etc.} -setup {
+ set sourcefile [makeFile {
+ set x new-x
+ return -code error "Simulated error"
+ set y new-y
+ } source.file]
+} -body {
+ list [catch {source $sourcefile} msg] $msg $::errorInfo $::errorCode
+} -cleanup {
+ removeFile source.file
+} -result {1 {Simulated error} {Simulated error
+ while executing
+"source $sourcefile"} NONE}
+test source-3.4 {return with special code etc.} -setup {
+ set sourcefile [makeFile {
+ set x new-x
+ return -code error -errorinfo "Simulated errorInfo stuff"
+ set y new-y
+ } source.file]
+} -body {
+ list [catch {source $sourcefile} msg] $msg $::errorInfo $::errorCode
+} -cleanup {
+ removeFile source.file
+} -result {1 {} {Simulated errorInfo stuff
+ invoked from within
+"source $sourcefile"} NONE}
+test source-3.5 {return with special code etc.} -setup {
+ set sourcefile [makeFile {
+ set x new-x
+ return -code error -errorinfo "Simulated errorInfo stuff" \
+ -errorcode {a b c}
+ set y new-y
+ } source.file]
+} -body {
+ list [catch {source $sourcefile} msg] $msg $::errorInfo $::errorCode
+} -cleanup {
+ removeFile source.file
+} -result {1 {} {Simulated errorInfo stuff
+ invoked from within
+"source $sourcefile"} {a b c}}
+
+test source-6.1 {source is binary ok} -setup {
+ # Note [makeFile] writes in the system encoding.
+ # [source] defaults to reading in the system encoding.
+ set sourcefile [makeFile [list set x "a b\0c"] source.file]
+} -body {
+ set x {}
+ source $sourcefile
+ string length $x
+} -cleanup {
+ removeFile source.file
+} -result 5
+test source-6.2 {source skips everything after Ctrl-Z: Bug 2040} -setup {
+ set sourcefile [makeFile "set x ab\32c" source.file]
+} -body {
+ set x {}
+ source $sourcefile
+ string length $x
+} -cleanup {
+ removeFile source.file
+} -result 2
+
+test source-7.1 {source -encoding test} -setup {
+ set sourcefile [makeFile {} source.file]
+ file delete $sourcefile
+ set f [open $sourcefile w]
+ fconfigure $f -encoding utf-8
+ puts $f "set symbol(square-root) \u221A; set x correct"
+ close $f
+} -body {
+ set x unset
+ source -encoding utf-8 $sourcefile
+ set x
+} -cleanup {
+ removeFile source.file
+} -result correct
+test source-7.2 {source -encoding test} -setup {
+ # This tests for bad interactions between [source -encoding]
+ # and use of the Control-Z character (\u001A) as a cross-platform
+ # EOF character by [source]. Here we write out and the [source] a
+ # file that contains the byte \x1A, although not the character \u001A in
+ # the indicated encoding.
+ set sourcefile [makeFile {} source.file]
+ file delete $sourcefile
+ set f [open $sourcefile w]
+ fconfigure $f -encoding unicode
+ puts $f "set symbol(square-root) \u221A; set x correct"
+ close $f
+} -body {
+ set x unset
+ source -encoding unicode $sourcefile
+ set x
+} -cleanup {
+ removeFile source.file
+} -result correct
+test source-7.3 {source -encoding: syntax} -body {
+ # Have to spell out the -encoding option
+ source -e utf-8 no_file
+} -returnCodes 1 -match glob -result {bad option*}
+test source-7.4 {source -encoding: syntax} -setup {
+ set sourcefile [makeFile {} source.file]
+} -body {
+ source -encoding no-such-encoding $sourcefile
+} -cleanup {
+ removeFile source.file
+} -returnCodes 1 -match glob -result {unknown encoding*}
+test source-7.5 {source -encoding: correct operation} -setup {
+ set sourcefile [makeFile {} source.file]
+ file delete $sourcefile
+ set f [open $sourcefile w]
+ fconfigure $f -encoding utf-8
+ puts $f "proc \u20ac {} {return foo}"
+ close $f
+} -body {
+ source -encoding utf-8 $sourcefile
+ \u20ac
+} -cleanup {
+ removeFile source.file
+ rename \u20ac {}
+} -result foo
+test source-7.6 {source -encoding: mismatch encoding error} -setup {
+ set sourcefile [makeFile {} source.file]
+ file delete $sourcefile
+ set f [open $sourcefile w]
+ fconfigure $f -encoding utf-8
+ puts $f "proc \u20ac {} {return foo}"
+ close $f
+} -body {
+ source -encoding ascii $sourcefile
+ \u20ac
+} -cleanup {
+ removeFile source.file
+} -returnCodes error -match glob -result {invalid command name*}
+
+test source-8.1 {source and coroutine/yield} -setup {
+ set sourcefile [makeFile {} source.file]
+ file delete $sourcefile
+} -body {
+ makeFile {yield 1; yield 2; return 3;} $sourcefile
+ coroutine coro apply {f {yield;source $f}} $sourcefile
+ list [coro] [coro] [coro] [info exist coro]
+} -cleanup {
+ catch {rename coro {}}
+ removeFile source.file
+} -result {1 2 3 0}
+
+cleanupTests
+}
+namespace delete ::tcl::test::source
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/split.test b/library/msgcat/tests/split.test
new file mode 100644
index 0000000..778131f
--- /dev/null
+++ b/library/msgcat/tests/split.test
@@ -0,0 +1,88 @@
+# Commands covered: split
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test split-1.1 {basic split commands} {
+ split "a\n b\t\r c\n "
+} {a {} b {} {} c {} {}}
+test split-1.2 {basic split commands} {
+ split "word 1xyzword 2zword 3" xyz
+} {{word 1} {} {} {word 2} {word 3}}
+test split-1.3 {basic split commands} {
+ split "12345" {}
+} {1 2 3 4 5}
+test split-1.4 {basic split commands} {
+ split "a\}b\[c\{\]\$"
+} "a\\}b\\\[c\\{\\\]\\\$"
+test split-1.5 {basic split commands} {
+ split {} {}
+} {}
+test split-1.6 {basic split commands} {
+ split {}
+} {}
+test split-1.7 {basic split commands} {
+ split { }
+} {{} {} {} {}}
+test split-1.8 {basic split commands} {
+ proc foo {} {
+ set x {}
+ foreach f [split {]\n} {}] {
+ append x $f
+ }
+ return $x
+ }
+ foo
+} {]\n}
+test split-1.9 {basic split commands} {
+ proc foo {} {
+ set x ab\000c
+ set y [split $x {}]
+ return $y
+ }
+ foo
+} "a b \000 c"
+test split-1.10 {basic split commands} {
+ split "a0ab1b2bbb3\000c4" ab\000c
+} {{} 0 {} 1 2 {} {} 3 {} 4}
+test split-1.11 {basic split commands} {
+ split "12,3,45" {,}
+} {12 3 45}
+test split-1.12 {basic split commands} {
+ split "\u0001ab\u0001cd\u0001\u0001ef\u0001" \1
+} {{} ab cd {} ef {}}
+test split-1.13 {basic split commands} {
+ split "12,34,56," {,}
+} {12 34 56 {}}
+test split-1.14 {basic split commands} {
+ split ",12,,,34,56," {,}
+} {{} 12 {} {} 34 56 {}}
+
+test split-2.1 {split errors} {
+ list [catch split msg] $msg $errorCode
+} {1 {wrong # args: should be "split string ?splitChars?"} {TCL WRONGARGS}}
+test split-2.2 {split errors} {
+ list [catch {split a b c} msg] $msg $errorCode
+} {1 {wrong # args: should be "split string ?splitChars?"} {TCL WRONGARGS}}
+
+# cleanup
+catch {rename foo {}}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/stack.test b/library/msgcat/tests/stack.test
new file mode 100644
index 0000000..873cb08
--- /dev/null
+++ b/library/msgcat/tests/stack.test
@@ -0,0 +1,64 @@
+# Tests that the stack size is big enough for the application.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1998-2000 Ajuba Solutions.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Note that a failure in this test may result in a crash of the executable.
+
+test stack-1.1 {maxNestingDepth reached on infinite recursion} -body {
+ # do this in a sub process in case it segfaults
+ exec [interpreter] << {
+ proc recurse {} { recurse }
+ catch { recurse } rv
+ puts $rv
+ }
+} -result {too many nested evaluations (infinite loop?)}
+
+test stack-2.1 {maxNestingDepth reached on infinite recursion} -body {
+ # do this in a sub process in case it segfaults
+ exec [interpreter] << {
+ interp alias {} unknown {} notaknownproc
+ catch { unknown } msg
+ puts $msg
+ }
+} -result {too many nested evaluations (infinite loop?)}
+
+# Make sure that there is enough stack to run regexp even if we're
+# close to the recursion limit. [Bug 947070] [Patch 746378]
+test stack-3.1 {enough room for regexp near recursion limit} -body {
+ # do this in a sub process in case it segfaults
+ exec [interpreter] << {
+ interp recursionlimit {} 10000
+ set depth 0
+ proc a { max } {
+ if { [info level] < $max } {
+ set ::depth [info level]
+ a $max
+ } else {
+ regexp {^ ?} x
+ }
+ }
+ catch { a 10001 }
+ set depth2 $depth
+ puts [list [a $depth] [expr { $depth2 - $depth }]]
+ }
+} -result {1 1}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/string.test b/library/msgcat/tests/string.test
new file mode 100644
index 0000000..b3326ae
--- /dev/null
+++ b/library/msgcat/tests/string.test
@@ -0,0 +1,1966 @@
+# Commands covered: string
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2001 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# Some tests require the testobj command
+
+testConstraint testobj [expr {[info commands testobj] != {}}]
+testConstraint testindexobj [expr {[info commands testindexobj] != {}}]
+
+# Used for constraining memory leak tests
+testConstraint memory [llength [info commands memory]]
+
+test string-1.1 {error conditions} {
+ list [catch {string gorp a b} msg] $msg
+} {1 {unknown or ambiguous subcommand "gorp": must be bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}}
+test string-1.2 {error conditions} {
+ list [catch {string} msg] $msg
+} {1 {wrong # args: should be "string subcommand ?arg ...?"}}
+
+test string-2.1 {string compare, too few args} {
+ list [catch {string compare a} msg] $msg
+} {1 {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"}}
+test string-2.2 {string compare, bad args} {
+ list [catch {string compare a b c} msg] $msg
+} {1 {bad option "a": must be -nocase or -length}}
+test string-2.3 {string compare, bad args} {
+ list [catch {string compare -length -nocase str1 str2} msg] $msg
+} {1 {expected integer but got "-nocase"}}
+test string-2.4 {string compare, too many args} {
+ list [catch {string compare -length 10 -nocase str1 str2 str3} msg] $msg
+} {1 {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"}}
+test string-2.5 {string compare with length unspecified} {
+ list [catch {string compare -length 10 10} msg] $msg
+} {1 {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"}}
+test string-2.6 {string compare} {
+ string compare abcde abdef
+} -1
+test string-2.7 {string compare, shortest method name} {
+ string c abcde ABCDE
+} 1
+test string-2.8 {string compare} {
+ string compare abcde abcde
+} 0
+test string-2.9 {string compare with length} {
+ string compare -length 2 abcde abxyz
+} 0
+test string-2.10 {string compare with special index} {
+ list [catch {string compare -length end-3 abcde abxyz} msg] $msg
+} {1 {expected integer but got "end-3"}}
+test string-2.11 {string compare, unicode} {
+ string compare ab\u7266 ab\u7267
+} -1
+test string-2.12 {string compare, high bit} {
+ # This test will fail if the underlying comparaison
+ # is using signed chars instead of unsigned chars.
+ # (like SunOS's default memcmp thus the compat/memcmp.c)
+ string compare "\x80" "@"
+ # Nb this tests works also in utf8 space because \x80 is
+ # translated into a 2 or more bytelength but whose first byte has
+ # the high bit set.
+} 1
+test string-2.13 {string compare -nocase} {
+ string compare -nocase abcde abdef
+} -1
+test string-2.14 {string compare -nocase} {
+ string c -nocase abcde ABCDE
+} 0
+test string-2.15 {string compare -nocase} {
+ string compare -nocase abcde abcde
+} 0
+test string-2.16 {string compare -nocase with length} {
+ string compare -length 2 -nocase abcde Abxyz
+} 0
+test string-2.17 {string compare -nocase with length} {
+ string compare -nocase -length 3 abcde Abxyz
+} -1
+test string-2.18 {string compare -nocase with length <= 0} {
+ string compare -nocase -length -1 abcde AbCdEf
+} -1
+test string-2.19 {string compare -nocase with excessive length} {
+ string compare -nocase -length 50 AbCdEf abcde
+} 1
+test string-2.20 {string compare -len unicode} {
+ # These are strings that are 6 BYTELENGTH long, but the length
+ # shouldn't make a different because there are actually 3 CHARS long
+ string compare -len 5 \334\334\334 \334\334\374
+} -1
+test string-2.21 {string compare -nocase with special index} {
+ list [catch {string compare -nocase -length end-3 Abcde abxyz} msg] $msg
+} {1 {expected integer but got "end-3"}}
+test string-2.22 {string compare, null strings} {
+ string compare "" ""
+} 0
+test string-2.23 {string compare, null strings} {
+ string compare "" foo
+} -1
+test string-2.24 {string compare, null strings} {
+ string compare foo ""
+} 1
+test string-2.25 {string compare -nocase, null strings} {
+ string compare -nocase "" ""
+} 0
+test string-2.26 {string compare -nocase, null strings} {
+ string compare -nocase "" foo
+} -1
+test string-2.27 {string compare -nocase, null strings} {
+ string compare -nocase foo ""
+} 1
+test string-2.28 {string compare with length, unequal strings} {
+ string compare -length 2 abc abde
+} 0
+test string-2.29 {string compare with length, unequal strings} {
+ string compare -length 2 ab abde
+} 0
+test string-2.30 {string compare with NUL character vs. other ASCII} {
+ # Be careful here, since UTF-8 rep comparison with memcmp() of
+ # these puts chars in the wrong order
+ string compare \x00 \x01
+} -1
+test string-2.31 {string compare, high bit} {
+ proc foo {} {string compare "a\x80" "a@"}
+ foo
+} 1
+test string-2.32 {string compare, high bit} {
+ proc foo {} {string compare "a\x00" "a\x01"}
+ foo
+} -1
+test string-2.33 {string compare, high bit} {
+ proc foo {} {string compare "\x00\x00" "\x00\x01"}
+ foo
+} -1
+
+# only need a few tests on equal, since it uses the same code as
+# string compare, but just modifies the return output
+test string-3.1 {string equal} {
+ string equal abcde abdef
+} 0
+test string-3.2 {string equal} {
+ string eq abcde ABCDE
+} 0
+test string-3.3 {string equal} {
+ string equal abcde abcde
+} 1
+test string-3.4 {string equal -nocase} {
+ string equal -nocase \334\334\334\334\374\374\374\374 \334\334\334\334\334\334\334\334
+} 1
+test string-3.5 {string equal -nocase} {
+ string equal -nocase abcde abdef
+} 0
+test string-3.6 {string equal -nocase} {
+ string eq -nocase abcde ABCDE
+} 1
+test string-3.7 {string equal -nocase} {
+ string equal -nocase abcde abcde
+} 1
+test string-3.8 {string equal with length, unequal strings} {
+ string equal -length 2 abc abde
+} 1
+
+test string-4.1 {string first, too few args} {
+ list [catch {string first a} msg] $msg
+} {1 {wrong # args: should be "string first needleString haystackString ?startIndex?"}}
+test string-4.2 {string first, bad args} {
+ list [catch {string first a b c} msg] $msg
+} {1 {bad index "c": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-4.3 {string first, too many args} {
+ list [catch {string first a b 5 d} msg] $msg
+} {1 {wrong # args: should be "string first needleString haystackString ?startIndex?"}}
+test string-4.4 {string first} {
+ string first bq abcdefgbcefgbqrs
+} 12
+test string-4.5 {string first} {
+ string fir bcd abcdefgbcefgbqrs
+} 1
+test string-4.6 {string first} {
+ string f b abcdefgbcefgbqrs
+} 1
+test string-4.7 {string first} {
+ string first xxx x123xx345xxx789xxx012
+} 9
+test string-4.8 {string first} {
+ string first "" x123xx345xxx789xxx012
+} -1
+test string-4.9 {string first, unicode} {
+ string first x abc\u7266x
+} 4
+test string-4.10 {string first, unicode} {
+ string first \u7266 abc\u7266x
+} 3
+test string-4.11 {string first, start index} {
+ string first \u7266 abc\u7266x 3
+} 3
+test string-4.12 {string first, start index} {
+ string first \u7266 abc\u7266x 4
+} -1
+test string-4.13 {string first, start index} {
+ string first \u7266 abc\u7266x end-2
+} 3
+test string-4.14 {string first, negative start index} {
+ string first b abc -1
+} 1
+test string-4.15 {string first, ability to two-byte encoded utf-8 chars} {
+ # Test for a bug in Tcl 8.3 where test for all-single-byte-encoded
+ # strings was incorrect, leading to an index returned by [string first]
+ # which pointed past the end of the string.
+ set uchar \u057e ;# character with two-byte encoding in utf-8
+ string first % %#$uchar$uchar#$uchar$uchar#% 3
+} 8
+
+test string-5.1 {string index} {
+ list [catch {string index} msg] $msg
+} {1 {wrong # args: should be "string index string charIndex"}}
+test string-5.2 {string index} {
+ list [catch {string index a b c} msg] $msg
+} {1 {wrong # args: should be "string index string charIndex"}}
+test string-5.3 {string index} {
+ string index abcde 0
+} a
+test string-5.4 {string index} {
+ string in abcde 4
+} e
+test string-5.5 {string index} {
+ string index abcde 5
+} {}
+test string-5.6 {string index} {
+ list [catch {string index abcde -10} msg] $msg
+} {0 {}}
+test string-5.7 {string index} {
+ list [catch {string index a xyz} msg] $msg
+} {1 {bad index "xyz": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-5.8 {string index} {
+ string index abc end
+} c
+test string-5.9 {string index} {
+ string index abc end-1
+} b
+test string-5.10 {string index, unicode} {
+ string index abc\u7266d 4
+} d
+test string-5.11 {string index, unicode} {
+ string index abc\u7266d 3
+} \u7266
+test string-5.12 {string index, unicode over char length, under byte length} {
+ string index \334\374\334\374 6
+} {}
+test string-5.13 {string index, bytearray object} {
+ string index [binary format a5 fuz] 0
+} f
+test string-5.14 {string index, bytearray object} {
+ string index [binary format I* {0x50515253 0x52}] 3
+} S
+test string-5.15 {string index, bytearray object} {
+ set b [binary format I* {0x50515253 0x52}]
+ set i1 [string index $b end-6]
+ set i2 [string index $b 1]
+ string compare $i1 $i2
+} 0
+test string-5.16 {string index, bytearray object with string obj shimmering} {
+ set str "0123456789\x00 abcdedfghi"
+ binary scan $str H* dump
+ string compare [string index $str 10] \x00
+} 0
+test string-5.17 {string index, bad integer} -body {
+ list [catch {string index "abc" 0o8} msg] $msg
+} -match glob -result {1 {*invalid octal number*}}
+test string-5.18 {string index, bad integer} -body {
+ list [catch {string index "abc" end-0o0289} msg] $msg
+} -match glob -result {1 {*invalid octal number*}}
+test string-5.19 {string index, bytearray object out of bounds} {
+ string index [binary format I* {0x50515253 0x52}] -1
+} {}
+test string-5.20 {string index, bytearray object out of bounds} {
+ string index [binary format I* {0x50515253 0x52}] 20
+} {}
+
+
+proc largest_int {} {
+ # This will give us what the largest valid int on this machine is,
+ # so we can test for overflow properly below on >32 bit systems
+ set int 1
+ set exp 7; # assume we get at least 8 bits
+ while {wide($int) > 0} { set int [expr {wide(1) << [incr exp]}] }
+ return [expr {$int-1}]
+}
+
+test string-6.1 {string is, too few args} {
+ list [catch {string is} msg] $msg
+} {1 {wrong # args: should be "string is class ?-strict? ?-failindex var? str"}}
+test string-6.2 {string is, too few args} {
+ list [catch {string is alpha} msg] $msg
+} {1 {wrong # args: should be "string is class ?-strict? ?-failindex var? str"}}
+test string-6.3 {string is, bad args} {
+ list [catch {string is alpha -failin str} msg] $msg
+} {1 {wrong # args: should be "string is alpha ?-strict? ?-failindex var? str"}}
+test string-6.4 {string is, too many args} {
+ list [catch {string is alpha -failin var -strict str more} msg] $msg
+} {1 {wrong # args: should be "string is class ?-strict? ?-failindex var? str"}}
+test string-6.5 {string is, class check} {
+ list [catch {string is bogus str} msg] $msg
+} {1 {bad class "bogus": must be alnum, alpha, ascii, control, boolean, digit, double, entier, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, or xdigit}}
+test string-6.6 {string is, ambiguous class} {
+ list [catch {string is al str} msg] $msg
+} {1 {ambiguous class "al": must be alnum, alpha, ascii, control, boolean, digit, double, entier, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, or xdigit}}
+test string-6.7 {string is alpha, all ok} {
+ string is alpha -strict -failindex var abc
+} 1
+test string-6.8 {string is, error in var} {
+ list [string is alpha -failindex var abc5def] $var
+} {0 3}
+test string-6.9 {string is, var shouldn't get set} {
+ catch {unset var}
+ list [catch {string is alpha -failindex var abc; set var} msg] $msg
+} {1 {can't read "var": no such variable}}
+test string-6.10 {string is, ok on empty} {
+ string is alpha {}
+} 1
+test string-6.11 {string is, -strict check against empty} {
+ string is alpha -strict {}
+} 0
+test string-6.12 {string is alnum, true} {
+ string is alnum abc123
+} 1
+test string-6.13 {string is alnum, false} {
+ list [string is alnum -failindex var abc1.23] $var
+} {0 4}
+test string-6.14 {string is alnum, unicode} "string is alnum abc\xfc" 1
+test string-6.15 {string is alpha, true} {
+ string is alpha abc
+} 1
+test string-6.16 {string is alpha, false} {
+ list [string is alpha -fail var a1bcde] $var
+} {0 1}
+test string-6.17 {string is alpha, unicode} {
+ string is alpha abc\374
+} 1
+test string-6.18 {string is ascii, true} {
+ string is ascii abc\u007Fend\u0000
+} 1
+test string-6.19 {string is ascii, false} {
+ list [string is ascii -fail var abc\u0000def\u0080more] $var
+} {0 7}
+test string-6.20 {string is boolean, true} {
+ string is boolean true
+} 1
+test string-6.21 {string is boolean, true} {
+ string is boolean f
+} 1
+test string-6.22 {string is boolean, true based on type} {
+ string is bool [string compare a a]
+} 1
+test string-6.23 {string is boolean, false} {
+ list [string is bool -fail var yada] $var
+} {0 0}
+test string-6.24 {string is digit, true} {
+ string is digit 0123456789
+} 1
+test string-6.25 {string is digit, false} {
+ list [string is digit -fail var 0123\u00dc567] $var
+} {0 4}
+test string-6.26 {string is digit, false} {
+ list [string is digit -fail var +123567] $var
+} {0 0}
+test string-6.27 {string is double, true} {
+ string is double 1
+} 1
+test string-6.28 {string is double, true} {
+ string is double [expr double(1)]
+} 1
+test string-6.29 {string is double, true} {
+ string is double 1.0
+} 1
+test string-6.30 {string is double, true} {
+ string is double [string compare a a]
+} 1
+test string-6.31 {string is double, true} {
+ string is double " +1.0e-1 "
+} 1
+test string-6.32 {string is double, true} {
+ string is double "\n1.0\v"
+} 1
+test string-6.33 {string is double, false} {
+ list [string is double -fail var 1abc] $var
+} {0 1}
+test string-6.34 {string is double, false} {
+ list [string is double -fail var abc] $var
+} {0 0}
+test string-6.35 {string is double, false} {
+ list [string is double -fail var " 1.0e4e4 "] $var
+} {0 8}
+test string-6.36 {string is double, false} {
+ list [string is double -fail var "\n"] $var
+} {0 0}
+test string-6.37 {string is double, false on int overflow} {
+ # Make it the largest int recognizable, with one more digit for overflow
+ # Since bignums arrived in Tcl 8.5, the sense of this test changed.
+ # Now integer values that exceed native limits become bignums, and
+ # bignums can convert to doubles without error.
+ list [string is double -fail var [largest_int]0] $var
+} {1 0}
+# string-6.38 removed, underflow on input is no longer an error.
+test string-6.39 {string is double, false} {
+ # This test is non-portable because IRIX thinks
+ # that .e1 is a valid double - this is really a bug
+ # on IRIX as .e1 should NOT be a valid double
+ #
+ # Portable now. Tcl 8.5 does its own double parsing.
+
+ list [string is double -fail var .e1] $var
+} {0 0}
+test string-6.40 {string is false, true} {
+ string is false false
+} 1
+test string-6.41 {string is false, true} {
+ string is false FaLsE
+} 1
+test string-6.42 {string is false, true} {
+ string is false N
+} 1
+test string-6.43 {string is false, true} {
+ string is false 0
+} 1
+test string-6.44 {string is false, true} {
+ string is false off
+} 1
+test string-6.45 {string is false, false} {
+ list [string is false -fail var abc] $var
+} {0 0}
+test string-6.46 {string is false, false} {
+ catch {unset var}
+ list [string is false -fail var Y] $var
+} {0 0}
+test string-6.47 {string is false, false} {
+ catch {unset var}
+ list [string is false -fail var offensive] $var
+} {0 0}
+test string-6.48 {string is integer, true} {
+ string is integer +1234567890
+} 1
+test string-6.49 {string is integer, true on type} {
+ string is integer [expr int(50.0)]
+} 1
+test string-6.50 {string is integer, true} {
+ string is integer [list -10]
+} 1
+test string-6.51 {string is integer, true as hex} {
+ string is integer 0xabcdef
+} 1
+test string-6.52 {string is integer, true as octal} {
+ string is integer 012345
+} 1
+test string-6.53 {string is integer, true with whitespace} {
+ string is integer " \n1234\v"
+} 1
+test string-6.54 {string is integer, false} {
+ list [string is integer -fail var 123abc] $var
+} {0 3}
+test string-6.55 {string is integer, false on overflow} {
+ list [string is integer -fail var +[largest_int]0] $var
+} {0 -1}
+test string-6.56 {string is integer, false} {
+ list [string is integer -fail var [expr double(1)]] $var
+} {0 1}
+test string-6.57 {string is integer, false} {
+ list [string is integer -fail var " "] $var
+} {0 0}
+test string-6.58 {string is integer, false on bad octal} {
+ list [string is integer -fail var 0o36963] $var
+} {0 4}
+test string-6.58.1 {string is integer, false on bad octal} {
+ list [string is integer -fail var 0o36963] $var
+} {0 4}
+test string-6.59 {string is integer, false on bad hex} {
+ list [string is integer -fail var 0X345XYZ] $var
+} {0 5}
+test string-6.60 {string is lower, true} {
+ string is lower abc
+} 1
+test string-6.61 {string is lower, unicode true} {
+ string is lower abc\u00fcue
+} 1
+test string-6.62 {string is lower, false} {
+ list [string is lower -fail var aBc] $var
+} {0 1}
+test string-6.63 {string is lower, false} {
+ list [string is lower -fail var abc1] $var
+} {0 3}
+test string-6.64 {string is lower, unicode false} {
+ list [string is lower -fail var ab\u00dcUE] $var
+} {0 2}
+test string-6.65 {string is space, true} {
+ string is space " \t\n\v\f"
+} 1
+test string-6.66 {string is space, false} {
+ list [string is space -fail var " \t\n\v1\f"] $var
+} {0 4}
+test string-6.67 {string is true, true} {
+ string is true true
+} 1
+test string-6.68 {string is true, true} {
+ string is true TrU
+} 1
+test string-6.69 {string is true, true} {
+ string is true ye
+} 1
+test string-6.70 {string is true, true} {
+ string is true 1
+} 1
+test string-6.71 {string is true, true} {
+ string is true on
+} 1
+test string-6.72 {string is true, false} {
+ list [string is true -fail var onto] $var
+} {0 0}
+test string-6.73 {string is true, false} {
+ catch {unset var}
+ list [string is true -fail var 25] $var
+} {0 0}
+test string-6.74 {string is true, false} {
+ catch {unset var}
+ list [string is true -fail var no] $var
+} {0 0}
+test string-6.75 {string is upper, true} {
+ string is upper ABC
+} 1
+test string-6.76 {string is upper, unicode true} {
+ string is upper ABC\u00dcUE
+} 1
+test string-6.77 {string is upper, false} {
+ list [string is upper -fail var AbC] $var
+} {0 1}
+test string-6.78 {string is upper, false} {
+ list [string is upper -fail var AB2C] $var
+} {0 2}
+test string-6.79 {string is upper, unicode false} {
+ list [string is upper -fail var ABC\u00fcue] $var
+} {0 3}
+test string-6.80 {string is wordchar, true} {
+ string is wordchar abc_123
+} 1
+test string-6.81 {string is wordchar, unicode true} {
+ string is wordchar abc\u00fcab\u00dcAB\u5001
+} 1
+test string-6.82 {string is wordchar, false} {
+ list [string is wordchar -fail var abcd.ef] $var
+} {0 4}
+test string-6.83 {string is wordchar, unicode false} {
+ list [string is wordchar -fail var abc\u0080def] $var
+} {0 3}
+test string-6.84 {string is control} {
+ ## Control chars are in the ranges
+ ## 00..1F && 7F..9F
+ list [string is control -fail var \x00\x01\x10\x1F\x7F\x80\x9F\x60] $var
+} {0 7}
+test string-6.85 {string is control} {
+ string is control \u0100
+} 0
+test string-6.86 {string is graph} {
+ ## graph is any print char, except space
+ list [string is gra -fail var "0123abc!@#\$\u0100 "] $var
+} {0 12}
+test string-6.87 {string is print} {
+ ## basically any printable char
+ list [string is print -fail var "0123abc!@#\$\u0100 \u0010"] $var
+} {0 13}
+test string-6.88 {string is punct} {
+ ## any graph char that isn't alnum
+ list [string is punct -fail var "_!@#\u00beq0"] $var
+} {0 4}
+test string-6.89 {string is xdigit} {
+ list [string is xdigit -fail var 0123456789\u0061bcdefABCDEFg] $var
+} {0 22}
+
+test string-6.90 {string is integer, bad integers} {
+ # SF bug #634856
+ set result ""
+ set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1"]
+ foreach num $numbers {
+ lappend result [string is int -strict $num]
+ }
+ return $result
+} {1 1 0 0 0 1 0 0}
+test string-6.91 {string is double, bad doubles} {
+ set result ""
+ set numbers [list 1.0 +1.0 ++1.0 +-1.0 -+1.0 -1.0 --1.0 "- +1.0"]
+ foreach num $numbers {
+ lappend result [string is double -strict $num]
+ }
+ return $result
+} {1 1 0 0 0 1 0 0}
+test string-6.92 {string is integer, 32-bit overflow} {
+ # Bug 718878
+ set x 0x100000000
+ list [string is integer -failindex var $x] $var
+} {0 -1}
+test string-6.93 {string is integer, 32-bit overflow} {
+ # Bug 718878
+ set x 0x100000000
+ append x ""
+ list [string is integer -failindex var $x] $var
+} {0 -1}
+test string-6.94 {string is integer, 32-bit overflow} {
+ # Bug 718878
+ set x 0x100000000
+ list [string is integer -failindex var [expr {$x}]] $var
+} {0 -1}
+test string-6.95 {string is wideinteger, true} {
+ string is wideinteger +1234567890
+} 1
+test string-6.96 {string is wideinteger, true on type} {
+ string is wideinteger [expr wide(50.0)]
+} 1
+test string-6.97 {string is wideinteger, true} {
+ string is wideinteger [list -10]
+} 1
+test string-6.98 {string is wideinteger, true as hex} {
+ string is wideinteger 0xabcdef
+} 1
+test string-6.99 {string is wideinteger, true as octal} {
+ string is wideinteger 0123456
+} 1
+test string-6.100 {string is wideinteger, true with whitespace} {
+ string is wideinteger " \n1234\v"
+} 1
+test string-6.101 {string is wideinteger, false} {
+ list [string is wideinteger -fail var 123abc] $var
+} {0 3}
+test string-6.102 {string is wideinteger, false on overflow} {
+ list [string is wideinteger -fail var +[largest_int]0] $var
+} {0 -1}
+test string-6.103 {string is wideinteger, false} {
+ list [string is wideinteger -fail var [expr double(1)]] $var
+} {0 1}
+test string-6.104 {string is wideinteger, false} {
+ list [string is wideinteger -fail var " "] $var
+} {0 0}
+test string-6.105 {string is wideinteger, false on bad octal} {
+ list [string is wideinteger -fail var 0o36963] $var
+} {0 4}
+test string-6.105.1 {string is wideinteger, false on bad octal} {
+ list [string is wideinteger -fail var 0o36963] $var
+} {0 4}
+test string-6.106 {string is wideinteger, false on bad hex} {
+ list [string is wideinteger -fail var 0X345XYZ] $var
+} {0 5}
+test string-6.107 {string is integer, bad integers} {
+ # SF bug #634856
+ set result ""
+ set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1"]
+ foreach num $numbers {
+ lappend result [string is wideinteger -strict $num]
+ }
+ return $result
+} {1 1 0 0 0 1 0 0}
+test string-6.108 {string is double, Bug 1382287} {
+ set x 2turtledoves
+ string is double $x
+ string is double $x
+} 0
+test string-6.109 {string is double, Bug 1360532} {
+ string is double 1\u00a0
+} 0
+test string-6.110 {string is entier, true} {
+ string is entier +1234567890
+} 1
+test string-6.111 {string is entier, true on type} {
+ string is entier [expr wide(50.0)]
+} 1
+test string-6.112 {string is entier, true} {
+ string is entier [list -10]
+} 1
+test string-6.113 {string is entier, true as hex} {
+ string is entier 0xabcdef
+} 1
+test string-6.114 {string is entier, true as octal} {
+ string is entier 0123456
+} 1
+test string-6.115 {string is entier, true with whitespace} {
+ string is entier " \n1234\v"
+} 1
+test string-6.116 {string is entier, false} {
+ list [string is entier -fail var 123abc] $var
+} {0 3}
+test string-6.117 {string is entier, false} {
+ list [string is entier -fail var 123123123123123123123123123123123123123123123123123123123123123123123123123123123123abc] $var
+} {0 84}
+test string-6.118 {string is entier, false} {
+ list [string is entier -fail var [expr double(1)]] $var
+} {0 1}
+test string-6.119 {string is entier, false} {
+ list [string is entier -fail var " "] $var
+} {0 0}
+test string-6.120 {string is entier, false on bad octal} {
+ list [string is entier -fail var 0o36963] $var
+} {0 4}
+test string-6.121.1 {string is entier, false on bad octal} {
+ list [string is entier -fail var 0o36963] $var
+} {0 4}
+test string-6.122 {string is entier, false on bad hex} {
+ list [string is entier -fail var 0X345XYZ] $var
+} {0 5}
+test string-6.123 {string is entier, bad integers} {
+ # SF bug #634856
+ set result ""
+ set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1"]
+ foreach num $numbers {
+ lappend result [string is entier -strict $num]
+ }
+ return $result
+} {1 1 0 0 0 1 0 0}
+test string-6.124 {string is entier, true} {
+ string is entier +1234567890123456789012345678901234567890
+} 1
+test string-6.125 {string is entier, true} {
+ string is entier [list -10000000000000000000000000000000000000000000000000000000000000000000000000000000000000]
+} 1
+test string-6.126 {string is entier, true as hex} {
+ string is entier 0xabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef
+} 1
+test string-6.127 {string is entier, true as octal} {
+ string is entier 0123456112341234561234565623456123456123456123456123456123456123456123456123456123456
+} 1
+test string-6.128 {string is entier, true with whitespace} {
+ string is entier " \n12340000000000000000000000000000000000000000000000000000000000000000000000000000000000000\v"
+} 1
+test string-6.129 {string is entier, false on bad octal} {
+ list [string is entier -fail var 0o1234561123412345612345656234561234561234561234561234561234561234561234561234561234536963] $var
+} {0 87}
+test string-6.130.1 {string is entier, false on bad octal} {
+ list [string is entier -fail var 0o1234561123412345612345656234561234561234561234561234561234561234561234561234561234536963] $var
+} {0 87}
+test string-6.131 {string is entier, false on bad hex} {
+ list [string is entier -fail var 0X12345611234123456123456562345612345612345612345612345612345612345612345612345612345345XYZ] $var
+} {0 88}
+
+catch {rename largest_int {}}
+
+test string-7.1 {string last, too few args} {
+ list [catch {string last a} msg] $msg
+} {1 {wrong # args: should be "string last needleString haystackString ?startIndex?"}}
+test string-7.2 {string last, bad args} {
+ list [catch {string last a b c} msg] $msg
+} {1 {bad index "c": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-7.3 {string last, too many args} {
+ list [catch {string last a b c d} msg] $msg
+} {1 {wrong # args: should be "string last needleString haystackString ?startIndex?"}}
+test string-7.4 {string last} {
+ string la xxx xxxx123xx345x678
+} 1
+test string-7.5 {string last} {
+ string last xx xxxx123xx345x678
+} 7
+test string-7.6 {string last} {
+ string las x xxxx123xx345x678
+} 12
+test string-7.7 {string last, unicode} {
+ string las x xxxx12\u7266xx345x678
+} 12
+test string-7.8 {string last, unicode} {
+ string las \u7266 xxxx12\u7266xx345x678
+} 6
+test string-7.9 {string last, stop index} {
+ string las \u7266 xxxx12\u7266xx345x678
+} 6
+test string-7.10 {string last, unicode} {
+ string las \u7266 xxxx12\u7266xx345x678
+} 6
+test string-7.11 {string last, start index} {
+ string last \u7266 abc\u7266x 3
+} 3
+test string-7.12 {string last, start index} {
+ string last \u7266 abc\u7266x 2
+} -1
+test string-7.13 {string last, start index} {
+ ## Constrain to last 'a' should work
+ string last ba badbad end-1
+} 3
+test string-7.14 {string last, start index} {
+ ## Constrain to last 'b' should skip last 'ba'
+ string last ba badbad end-2
+} 0
+test string-7.15 {string last, start index} {
+ string last \334a \334ad\334ad 0
+} -1
+test string-7.16 {string last, start index} {
+ string last \334a \334ad\334ad end-1
+} 3
+
+test string-8.1 {string bytelength} {
+ list [catch {string bytelength} msg] $msg
+} {1 {wrong # args: should be "string bytelength string"}}
+test string-8.2 {string bytelength} {
+ list [catch {string bytelength a b} msg] $msg
+} {1 {wrong # args: should be "string bytelength string"}}
+test string-8.3 {string bytelength} {
+ string bytelength "\u00c7"
+} 2
+test string-8.4 {string bytelength} {
+ string b ""
+} 0
+
+test string-9.1 {string length} {
+ list [catch {string length} msg] $msg
+} {1 {wrong # args: should be "string length string"}}
+test string-9.2 {string length} {
+ list [catch {string length a b} msg] $msg
+} {1 {wrong # args: should be "string length string"}}
+test string-9.3 {string length} {
+ string length "a little string"
+} 15
+test string-9.4 {string length} {
+ string le ""
+} 0
+test string-9.5 {string length, unicode} {
+ string le "abcd\u7266"
+} 5
+test string-9.6 {string length, bytearray object} {
+ string length [binary format a5 foo]
+} 5
+test string-9.7 {string length, bytearray object} {
+ string length [binary format I* {0x50515253 0x52}]
+} 8
+
+test string-10.1 {string map, too few args} {
+ list [catch {string map} msg] $msg
+} {1 {wrong # args: should be "string map ?-nocase? charMap string"}}
+test string-10.2 {string map, bad args} {
+ list [catch {string map {a b} abba oops} msg] $msg
+} {1 {bad option "a b": must be -nocase}}
+test string-10.3 {string map, too many args} {
+ list [catch {string map -nocase {a b} str1 str2} msg] $msg
+} {1 {wrong # args: should be "string map ?-nocase? charMap string"}}
+test string-10.4 {string map} {
+ string map {a b} abba
+} {bbbb}
+test string-10.5 {string map} {
+ string map {a b} a
+} {b}
+test string-10.6 {string map -nocase} {
+ string map -nocase {a b} Abba
+} {bbbb}
+test string-10.7 {string map} {
+ string map {abc 321 ab * a A} aabcabaababcab
+} {A321*A*321*}
+test string-10.8 {string map -nocase} {
+ string map -nocase {aBc 321 Ab * a A} aabcabaababcab
+} {A321*A*321*}
+test string-10.9 {string map -nocase} {
+ string map -no {abc 321 Ab * a A} aAbCaBaAbAbcAb
+} {A321*A*321*}
+test string-10.10 {string map} {
+ list [catch {string map {a b c} abba} msg] $msg
+} {1 {char map list unbalanced}}
+test string-10.11 {string map, nulls} {
+ string map {\x00 NULL blah \x00nix} {qwerty}
+} {qwerty}
+test string-10.12 {string map, unicode} {
+ string map [list \374 ue UE \334] "a\374ueUE\000EU"
+} aueue\334\0EU
+test string-10.13 {string map, -nocase unicode} {
+ string map -nocase [list \374 ue UE \334] "a\374ueUE\000EU"
+} aue\334\334\0EU
+test string-10.14 {string map, -nocase null arguments} {
+ string map -nocase {{} abc} foo
+} foo
+test string-10.15 {string map, one pair case} {
+ string map -nocase {abc 32} aAbCaBaAbAbcAb
+} {a32aBaAb32Ab}
+test string-10.16 {string map, one pair case} {
+ string map -nocase {ab 4321} aAbCaBaAbAbcAb
+} {a4321C4321a43214321c4321}
+test string-10.17 {string map, one pair case} {
+ string map {Ab 4321} aAbCaBaAbAbcAb
+} {a4321CaBa43214321c4321}
+test string-10.18 {string map, empty argument} {
+ string map -nocase {{} abc} foo
+} foo
+test string-10.19 {string map, empty arguments} {
+ string map -nocase {{} abc f bar {} def} foo
+} baroo
+test string-10.20 {string map, dictionaries don't alter map ordering} {
+ set map {aa X a Y}
+ list [string map [dict create aa X a Y] aaa] [string map $map aaa] [dict size $map] [string map $map aaa]
+} {XY XY 2 XY}
+test string-10.21 {string map, ABR checks} {
+ string map {longstring foob} long
+} long
+test string-10.22 {string map, ABR checks} {
+ string map {long foob} long
+} foob
+test string-10.23 {string map, ABR checks} {
+ string map {lon foob} long
+} foobg
+test string-10.24 {string map, ABR checks} {
+ string map {lon foob} longlo
+} foobglo
+test string-10.25 {string map, ABR checks} {
+ string map {lon foob} longlon
+} foobgfoob
+test string-10.26 {string map, ABR checks} {
+ string map {longstring foob longstring bar} long
+} long
+test string-10.27 {string map, ABR checks} {
+ string map {long foob longstring bar} long
+} foob
+test string-10.28 {string map, ABR checks} {
+ string map {lon foob longstring bar} long
+} foobg
+test string-10.29 {string map, ABR checks} {
+ string map {lon foob longstring bar} longlo
+} foobglo
+test string-10.30 {string map, ABR checks} {
+ string map {lon foob longstring bar} longlon
+} foobgfoob
+test string-10.31 {string map, nasty sharing crash from [Bug 1018562]} {
+ set a {a b}
+ string map $a $a
+} {b b}
+
+test string-11.1 {string match, too few args} {
+ list [catch {string match a} msg] $msg
+} {1 {wrong # args: should be "string match ?-nocase? pattern string"}}
+test string-11.2 {string match, too many args} {
+ list [catch {string match a b c d} msg] $msg
+} {1 {wrong # args: should be "string match ?-nocase? pattern string"}}
+test string-11.3 {string match} {
+ string match abc abc
+} 1
+test string-11.4 {string match} {
+ string mat abc abd
+} 0
+test string-11.5 {string match} {
+ string match ab*c abc
+} 1
+test string-11.6 {string match} {
+ string match ab**c abc
+} 1
+test string-11.7 {string match} {
+ string match ab* abcdef
+} 1
+test string-11.8 {string match} {
+ string match *c abc
+} 1
+test string-11.9 {string match} {
+ string match *3*6*9 0123456789
+} 1
+test string-11.9.1 {string match} {
+ string match *3*6*89 0123456789
+} 1
+test string-11.9.2 {string match} {
+ string match *3*456*89 0123456789
+} 1
+test string-11.9.3 {string match} {
+ string match *3*6* 0123456789
+} 1
+test string-11.9.4 {string match} {
+ string match *3*56* 0123456789
+} 1
+test string-11.9.5 {string match} {
+ string match *3*456*** 0123456789
+} 1
+test string-11.9.6 {string match} {
+ string match **3*456** 0123456789
+} 1
+test string-11.9.7 {string match} {
+ string match *3***456* 0123456789
+} 1
+test string-11.9.8 {string match} {
+ string match *3***\[456]* 0123456789
+} 1
+test string-11.9.9 {string match} {
+ string match *3***\[4-6]* 0123456789
+} 1
+test string-11.9.10 {string match} {
+ string match *3***\[4-6] 0123456789
+} 0
+test string-11.9.11 {string match} {
+ string match *3***\[4-6] 0123456
+} 1
+test string-11.10 {string match} {
+ string match *3*6*9 01234567890
+} 0
+test string-11.10.1 {string match} {
+ string match *3*6*89 01234567890
+} 0
+test string-11.10.2 {string match} {
+ string match *3*456*89 01234567890
+} 0
+test string-11.10.3 {string match} {
+ string match **3*456*89 01234567890
+} 0
+test string-11.10.4 {string match} {
+ string match *3*456***89 01234567890
+} 0
+test string-11.11 {string match} {
+ string match a?c abc
+} 1
+test string-11.12 {string match} {
+ string match a??c abc
+} 0
+test string-11.13 {string match} {
+ string match ?1??4???8? 0123456789
+} 1
+test string-11.14 {string match} {
+ string match {[abc]bc} abc
+} 1
+test string-11.15 {string match} {
+ string match {a[abc]c} abc
+} 1
+test string-11.16 {string match} {
+ string match {a[xyz]c} abc
+} 0
+test string-11.17 {string match} {
+ string match {12[2-7]45} 12345
+} 1
+test string-11.18 {string match} {
+ string match {12[ab2-4cd]45} 12345
+} 1
+test string-11.19 {string match} {
+ string match {12[ab2-4cd]45} 12b45
+} 1
+test string-11.20 {string match} {
+ string match {12[ab2-4cd]45} 12d45
+} 1
+test string-11.21 {string match} {
+ string match {12[ab2-4cd]45} 12145
+} 0
+test string-11.22 {string match} {
+ string match {12[ab2-4cd]45} 12545
+} 0
+test string-11.23 {string match} {
+ string match {a\*b} a*b
+} 1
+test string-11.24 {string match} {
+ string match {a\*b} ab
+} 0
+test string-11.25 {string match} {
+ string match {a\*\?\[\]\\\x} "a*?\[\]\\x"
+} 1
+test string-11.26 {string match} {
+ string match ** ""
+} 1
+test string-11.27 {string match} {
+ string match *. ""
+} 0
+test string-11.28 {string match} {
+ string match "" ""
+} 1
+test string-11.29 {string match} {
+ string match \[a a
+} 1
+test string-11.30 {string match, bad args} {
+ list [catch {string match - b c} msg] $msg
+} {1 {bad option "-": must be -nocase}}
+test string-11.31 {string match case} {
+ string match a A
+} 0
+test string-11.32 {string match nocase} {
+ string match -n a A
+} 1
+test string-11.33 {string match nocase} {
+ string match -nocase a\334 A\374
+} 1
+test string-11.34 {string match nocase} {
+ string match -nocase a*f ABCDEf
+} 1
+test string-11.35 {string match case, false hope} {
+ # This is true because '_' lies between the A-Z and a-z ranges
+ string match {[A-z]} _
+} 1
+test string-11.36 {string match nocase range} {
+ # This is false because although '_' lies between the A-Z and a-z ranges,
+ # we lower case the end points before checking the ranges.
+ string match -nocase {[A-z]} _
+} 0
+test string-11.37 {string match nocase} {
+ string match -nocase {[A-fh-Z]} g
+} 0
+test string-11.38 {string match case, reverse range} {
+ string match {[A-fh-Z]} g
+} 1
+test string-11.39 {string match, *\ case} {
+ string match {*\abc} abc
+} 1
+test string-11.39.1 {string match, *\ case} {
+ string match {*ab\c} abc
+} 1
+test string-11.39.2 {string match, *\ case} {
+ string match {*ab\*} ab*
+} 1
+test string-11.39.3 {string match, *\ case} {
+ string match {*ab\*} abc
+} 0
+test string-11.39.4 {string match, *\ case} {
+ string match {*ab\\*} {ab\c}
+} 1
+test string-11.39.5 {string match, *\ case} {
+ string match {*ab\\*} {ab\*}
+} 1
+test string-11.40 {string match, *special case} {
+ string match {*[ab]} abc
+} 0
+test string-11.41 {string match, *special case} {
+ string match {*[ab]*} abc
+} 1
+test string-11.42 {string match, *special case} {
+ string match "*\\" "\\"
+} 0
+test string-11.43 {string match, *special case} {
+ string match "*\\\\" "\\"
+} 1
+test string-11.44 {string match, *special case} {
+ string match "*???" "12345"
+} 1
+test string-11.45 {string match, *special case} {
+ string match "*???" "12"
+} 0
+test string-11.46 {string match, *special case} {
+ string match "*\\*" "abc*"
+} 1
+test string-11.47 {string match, *special case} {
+ string match "*\\*" "*"
+} 1
+test string-11.48 {string match, *special case} {
+ string match "*\\*" "*abc"
+} 0
+test string-11.49 {string match, *special case} {
+ string match "?\\*" "a*"
+} 1
+test string-11.50 {string match, *special case} {
+ string match "\\" "\\"
+} 0
+test string-11.51 {string match; *, -nocase and UTF-8} {
+ string match -nocase [binary format I 717316707] \
+ [binary format I 2028036707]
+} 1
+test string-11.52 {string match, null char in string} {
+ set out ""
+ set ptn "*abc*"
+ foreach elem [list "\u0000@abc" "@abc" "\u0000@abc\u0000" "blahabcblah"] {
+ lappend out [string match $ptn $elem]
+ }
+ set out
+} {1 1 1 1}
+test string-11.53 {string match, null char in pattern} {
+ set out ""
+ foreach {ptn elem} [list \
+ "*\u0000abc\u0000" "\u0000abc\u0000" \
+ "*\u0000abc\u0000" "\u0000abc\u0000ef" \
+ "*\u0000abc\u0000*" "\u0000abc\u0000ef" \
+ "*\u0000abc\u0000" "@\u0000abc\u0000ef" \
+ "*\u0000abc\u0000*" "@\u0000abc\u0000ef" \
+ ] {
+ lappend out [string match $ptn $elem]
+ }
+ set out
+} {1 0 1 0 1}
+test string-11.54 {string match, failure} {
+ set longString ""
+ for {set i 0} {$i < 10} {incr i} {
+ append longString "abcdefghijklmnopqrstuvwxy\u0000z01234567890123"
+ }
+ string first $longString 123
+ list [string match *cba* $longString] \
+ [string match *a*l*\u0000* $longString] \
+ [string match *a*l*\u0000*123 $longString] \
+ [string match *a*l*\u0000*123* $longString] \
+ [string match *a*l*\u0000*cba* $longString] \
+ [string match *===* $longString]
+} {0 1 1 1 0 0}
+
+test string-12.1 {string range} {
+ list [catch {string range} msg] $msg
+} {1 {wrong # args: should be "string range string first last"}}
+test string-12.2 {string range} {
+ list [catch {string range a 1} msg] $msg
+} {1 {wrong # args: should be "string range string first last"}}
+test string-12.3 {string range} {
+ list [catch {string range a 1 2 3} msg] $msg
+} {1 {wrong # args: should be "string range string first last"}}
+test string-12.4 {string range} {
+ string range abcdefghijklmnop 2 14
+} {cdefghijklmno}
+test string-12.5 {string range, last > length} {
+ string range abcdefghijklmnop 7 1000
+} {hijklmnop}
+test string-12.6 {string range} {
+ string range abcdefghijklmnop 10 end
+} {klmnop}
+test string-12.7 {string range, last < first} {
+ string range abcdefghijklmnop 10 9
+} {}
+test string-12.8 {string range, first < 0} {
+ string range abcdefghijklmnop -3 2
+} {abc}
+test string-12.9 {string range} {
+ string range abcdefghijklmnop -3 -2
+} {}
+test string-12.10 {string range} {
+ string range abcdefghijklmnop 1000 1010
+} {}
+test string-12.11 {string range} {
+ string range abcdefghijklmnop -100 end
+} {abcdefghijklmnop}
+test string-12.12 {string range} {
+ list [catch {string range abc abc 1} msg] $msg
+} {1 {bad index "abc": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-12.13 {string range} {
+ list [catch {string range abc 1 eof} msg] $msg
+} {1 {bad index "eof": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-12.14 {string range} {
+ string range abcdefghijklmnop end-1 end
+} {op}
+test string-12.15 {string range} {
+ string range abcdefghijklmnop end 1000
+} {p}
+test string-12.16 {string range} {
+ string range abcdefghijklmnop end end-1
+} {}
+test string-12.17 {string range, unicode} {
+ string range ab\u7266cdefghijklmnop 5 5
+} e
+test string-12.18 {string range, unicode} {
+ string range ab\u7266cdefghijklmnop 2 3
+} \u7266c
+test string-12.19 {string range, bytearray object} {
+ set b [binary format I* {0x50515253 0x52}]
+ set r1 [string range $b 1 end-1]
+ set r2 [string range $b 1 6]
+ string equal $r1 $r2
+} 1
+test string-12.20 {string range, out of bounds indices} {
+ string range \u00ff 0 1
+} \u00ff
+# Bug 1410553
+test string-12.21 {string range, regenerates correct reps, bug 1410553} {
+ set bytes "\x00 \x03 \x41"
+ set rxBuffer {}
+ foreach ch $bytes {
+ append rxBuffer $ch
+ if {$ch eq "\x03"} {
+ string length $rxBuffer
+ }
+ }
+ set rxCRC [string range $rxBuffer end-1 end]
+ binary scan [join $bytes {}] "H*" input_hex
+ binary scan $rxBuffer "H*" rxBuffer_hex
+ binary scan $rxCRC "H*" rxCRC_hex
+ list $input_hex $rxBuffer_hex $rxCRC_hex
+} {000341 000341 0341}
+test string-12.22 {string range, shimmering binary/index} {
+ set s 0000000001
+ binary scan $s a* x
+ string range $s $s end
+} 000000001
+
+test string-13.1 {string repeat} {
+ list [catch {string repeat} msg] $msg
+} {1 {wrong # args: should be "string repeat string count"}}
+test string-13.2 {string repeat} {
+ list [catch {string repeat abc 10 oops} msg] $msg
+} {1 {wrong # args: should be "string repeat string count"}}
+test string-13.3 {string repeat} {
+ string repeat {} 100
+} {}
+test string-13.4 {string repeat} {
+ string repeat { } 5
+} { }
+test string-13.5 {string repeat} {
+ string repeat abc 3
+} {abcabcabc}
+test string-13.6 {string repeat} {
+ string repeat abc -1
+} {}
+test string-13.7 {string repeat} {
+ list [catch {string repeat abc end} msg] $msg
+} {1 {expected integer but got "end"}}
+test string-13.8 {string repeat} {
+ string repeat {} -1000
+} {}
+test string-13.9 {string repeat} {
+ string repeat {} 0
+} {}
+test string-13.10 {string repeat} {
+ string repeat def 0
+} {}
+test string-13.11 {string repeat} {
+ string repeat def 1
+} def
+test string-13.12 {string repeat} {
+ string repeat ab\u7266cd 3
+} ab\u7266cdab\u7266cdab\u7266cd
+test string-13.13 {string repeat} {
+ string repeat \x00 3
+} \x00\x00\x00
+test string-13.14 {string repeat} {
+ # The string range will ensure us that string repeat gets a unicode string
+ string repeat [string range ab\u7266cd 2 3] 3
+} \u7266c\u7266c\u7266c
+
+test string-14.1 {string replace} {
+ list [catch {string replace} msg] $msg
+} {1 {wrong # args: should be "string replace string first last ?string?"}}
+test string-14.2 {string replace} {
+ list [catch {string replace a 1} msg] $msg
+} {1 {wrong # args: should be "string replace string first last ?string?"}}
+test string-14.3 {string replace} {
+ list [catch {string replace a 1 2 3 4} msg] $msg
+} {1 {wrong # args: should be "string replace string first last ?string?"}}
+test string-14.4 {string replace} {
+} {}
+test string-14.5 {string replace} {
+ string replace abcdefghijklmnop 2 14
+} {abp}
+test string-14.6 {string replace} {
+ string replace abcdefghijklmnop 7 1000
+} {abcdefg}
+test string-14.7 {string replace} {
+ string replace abcdefghijklmnop 10 end
+} {abcdefghij}
+test string-14.8 {string replace} {
+ string replace abcdefghijklmnop 10 9
+} {abcdefghijklmnop}
+test string-14.9 {string replace} {
+ string replace abcdefghijklmnop -3 2
+} {defghijklmnop}
+test string-14.10 {string replace} {
+ string replace abcdefghijklmnop -3 -2
+} {abcdefghijklmnop}
+test string-14.11 {string replace} {
+ string replace abcdefghijklmnop 1000 1010
+} {abcdefghijklmnop}
+test string-14.12 {string replace} {
+ string replace abcdefghijklmnop -100 end
+} {}
+test string-14.13 {string replace} {
+ list [catch {string replace abc abc 1} msg] $msg
+} {1 {bad index "abc": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-14.14 {string replace} {
+ list [catch {string replace abc 1 eof} msg] $msg
+} {1 {bad index "eof": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-14.15 {string replace} {
+ string replace abcdefghijklmnop end-10 end-2 NEW
+} {abcdeNEWop}
+test string-14.16 {string replace} {
+ string replace abcdefghijklmnop 0 end foo
+} {foo}
+test string-14.17 {string replace} {
+ string replace abcdefghijklmnop end end-1
+} {abcdefghijklmnop}
+
+test string-15.1 {string tolower too few args} {
+ list [catch {string tolower} msg] $msg
+} {1 {wrong # args: should be "string tolower string ?first? ?last?"}}
+test string-15.2 {string tolower bad args} {
+ list [catch {string tolower a b} msg] $msg
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-15.3 {string tolower too many args} {
+ list [catch {string tolower ABC 1 end oops} msg] $msg
+} {1 {wrong # args: should be "string tolower string ?first? ?last?"}}
+test string-15.4 {string tolower} {
+ string tolower ABCDeF
+} {abcdef}
+test string-15.5 {string tolower} {
+ string tolower "ABC XyZ"
+} {abc xyz}
+test string-15.6 {string tolower} {
+ string tolower {123#$&*()}
+} {123#$&*()}
+test string-15.7 {string tolower} {
+ string tolower ABC 1
+} AbC
+test string-15.8 {string tolower} {
+ string tolower ABC 1 end
+} Abc
+test string-15.9 {string tolower} {
+ string tolower ABC 0 end-1
+} abC
+test string-15.10 {string tolower, unicode} {
+ string tolower ABCabc\xc7\xe7
+} "abcabc\xe7\xe7"
+
+test string-16.1 {string toupper} {
+ list [catch {string toupper} msg] $msg
+} {1 {wrong # args: should be "string toupper string ?first? ?last?"}}
+test string-16.2 {string toupper} {
+ list [catch {string toupper a b} msg] $msg
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-16.3 {string toupper} {
+ list [catch {string toupper a 1 end oops} msg] $msg
+} {1 {wrong # args: should be "string toupper string ?first? ?last?"}}
+test string-16.4 {string toupper} {
+ string toupper abCDEf
+} {ABCDEF}
+test string-16.5 {string toupper} {
+ string toupper "abc xYz"
+} {ABC XYZ}
+test string-16.6 {string toupper} {
+ string toupper {123#$&*()}
+} {123#$&*()}
+test string-16.7 {string toupper} {
+ string toupper abc 1
+} aBc
+test string-16.8 {string toupper} {
+ string toupper abc 1 end
+} aBC
+test string-16.9 {string toupper} {
+ string toupper abc 0 end-1
+} ABc
+test string-16.10 {string toupper, unicode} {
+ string toupper ABCabc\xc7\xe7
+} "ABCABC\xc7\xc7"
+
+test string-17.1 {string totitle} {
+ list [catch {string totitle} msg] $msg
+} {1 {wrong # args: should be "string totitle string ?first? ?last?"}}
+test string-17.2 {string totitle} {
+ list [catch {string totitle a b} msg] $msg
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-17.3 {string totitle} {
+ string totitle abCDEf
+} {Abcdef}
+test string-17.4 {string totitle} {
+ string totitle "abc xYz"
+} {Abc xyz}
+test string-17.5 {string totitle} {
+ string totitle {123#$&*()}
+} {123#$&*()}
+test string-17.6 {string totitle, unicode} {
+ string totitle ABCabc\xc7\xe7
+} "Abcabc\xe7\xe7"
+test string-17.7 {string totitle, unicode} {
+ string totitle \u01f3BCabc\xc7\xe7
+} "\u01f2bcabc\xe7\xe7"
+
+test string-18.1 {string trim} {
+ list [catch {string trim} msg] $msg
+} {1 {wrong # args: should be "string trim string ?chars?"}}
+test string-18.2 {string trim} {
+ list [catch {string trim a b c} msg] $msg
+} {1 {wrong # args: should be "string trim string ?chars?"}}
+test string-18.3 {string trim} {
+ string trim " XYZ "
+} {XYZ}
+test string-18.4 {string trim} {
+ string trim "\t\nXYZ\t\n\r\n"
+} {XYZ}
+test string-18.5 {string trim} {
+ string trim " A XYZ A "
+} {A XYZ A}
+test string-18.6 {string trim} {
+ string trim "XXYYZZABC XXYYZZ" ZYX
+} {ABC }
+test string-18.7 {string trim} {
+ string trim " \t\r "
+} {}
+test string-18.8 {string trim} {
+ string trim {abcdefg} {}
+} {abcdefg}
+test string-18.9 {string trim} {
+ string trim {}
+} {}
+test string-18.10 {string trim} {
+ string trim ABC DEF
+} {ABC}
+test string-18.11 {string trim, unicode} {
+ string trim "\xe7\xe8 AB\xe7C \xe8\xe7" \xe7\xe8
+} " AB\xe7C "
+test string-18.12 {string trim, unicode default} {
+ string trim ABC\u1361\u1680\u3000
+} ABC
+
+test string-19.1 {string trimleft} {
+ list [catch {string trimleft} msg] $msg
+} {1 {wrong # args: should be "string trimleft string ?chars?"}}
+test string-19.2 {string trimleft} {
+ string trimleft " XYZ "
+} {XYZ }
+test string-19.3 {string trimleft, unicode default} {
+ string trimleft \u1361\u1680\u3000ABC
+} ABC
+
+test string-20.1 {string trimright errors} {
+ list [catch {string trimright} msg] $msg
+} {1 {wrong # args: should be "string trimright string ?chars?"}}
+test string-20.2 {string trimright errors} {
+ list [catch {string trimg a} msg] $msg
+} {1 {unknown or ambiguous subcommand "trimg": must be bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}}
+test string-20.3 {string trimright} {
+ string trimright " XYZ "
+} { XYZ}
+test string-20.4 {string trimright} {
+ string trimright " "
+} {}
+test string-20.5 {string trimright} {
+ string trimright ""
+} {}
+test string-20.6 {string trimright, unicode default} {
+ string trimright ABC\u1361\u1680\u3000
+} ABC
+
+test string-21.1 {string wordend} {
+ list [catch {string wordend a} msg] $msg
+} {1 {wrong # args: should be "string wordend string index"}}
+test string-21.2 {string wordend} {
+ list [catch {string wordend a b c} msg] $msg
+} {1 {wrong # args: should be "string wordend string index"}}
+test string-21.3 {string wordend} {
+ list [catch {string wordend a gorp} msg] $msg
+} {1 {bad index "gorp": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-21.4 {string wordend} {
+ string wordend abc. -1
+} 3
+test string-21.5 {string wordend} {
+ string wordend abc. 100
+} 4
+test string-21.6 {string wordend} {
+ string wordend "word_one two three" 2
+} 8
+test string-21.7 {string wordend} {
+ string wordend "one .&# three" 5
+} 6
+test string-21.8 {string wordend} {
+ string worde "x.y" 0
+} 1
+test string-21.9 {string wordend} {
+ string worde "x.y" end-1
+} 2
+test string-21.10 {string wordend, unicode} {
+ string wordend "xyz\u00c7de fg" 0
+} 6
+test string-21.11 {string wordend, unicode} {
+ string wordend "xyz\uc700de fg" 0
+} 6
+test string-21.12 {string wordend, unicode} {
+ string wordend "xyz\u203fde fg" 0
+} 6
+test string-21.13 {string wordend, unicode} {
+ string wordend "xyz\u2045de fg" 0
+} 3
+test string-21.14 {string wordend, unicode} {
+ string wordend "\uc700\uc700 abc" 8
+} 6
+
+test string-22.1 {string wordstart} {
+ list [catch {string word a} msg] $msg
+} {1 {unknown or ambiguous subcommand "word": must be bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}}
+test string-22.2 {string wordstart} {
+ list [catch {string wordstart a} msg] $msg
+} {1 {wrong # args: should be "string wordstart string index"}}
+test string-22.3 {string wordstart} {
+ list [catch {string wordstart a b c} msg] $msg
+} {1 {wrong # args: should be "string wordstart string index"}}
+test string-22.4 {string wordstart} {
+ list [catch {string wordstart a gorp} msg] $msg
+} {1 {bad index "gorp": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-22.5 {string wordstart} {
+ string wordstart "one two three_words" 400
+} 8
+test string-22.6 {string wordstart} {
+ string wordstart "one two three_words" 2
+} 0
+test string-22.7 {string wordstart} {
+ string wordstart "one two three_words" -2
+} 0
+test string-22.8 {string wordstart} {
+ string wordstart "one .*&^ three" 6
+} 6
+test string-22.9 {string wordstart} {
+ string wordstart "one two three" 4
+} 4
+test string-22.10 {string wordstart} {
+ string wordstart "one two three" end-5
+} 7
+test string-22.11 {string wordstart, unicode} {
+ string wordstart "one tw\u00c7o three" 7
+} 4
+test string-22.12 {string wordstart, unicode} {
+ string wordstart "ab\uc700\uc700 cdef ghi" 12
+} 10
+test string-22.13 {string wordstart, unicode} {
+ string wordstart "\uc700\uc700 abc" 8
+} 3
+
+test string-23.0 {string is boolean, Bug 1187123} testindexobj {
+ set x 5
+ catch {testindexobj $x foo bar soom}
+ string is boolean $x
+} 0
+test string-23.1 {string is command with empty string} {
+ set s ""
+ list \
+ [string is alnum $s] \
+ [string is alpha $s] \
+ [string is ascii $s] \
+ [string is control $s] \
+ [string is boolean $s] \
+ [string is digit $s] \
+ [string is double $s] \
+ [string is false $s] \
+ [string is graph $s] \
+ [string is integer $s] \
+ [string is lower $s] \
+ [string is print $s] \
+ [string is punct $s] \
+ [string is space $s] \
+ [string is true $s] \
+ [string is upper $s] \
+ [string is wordchar $s] \
+ [string is xdigit $s] \
+
+} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1}
+test string-23.2 {string is command with empty string} {
+ set s ""
+ list \
+ [string is alnum -strict $s] \
+ [string is alpha -strict $s] \
+ [string is ascii -strict $s] \
+ [string is control -strict $s] \
+ [string is boolean -strict $s] \
+ [string is digit -strict $s] \
+ [string is double -strict $s] \
+ [string is false -strict $s] \
+ [string is graph -strict $s] \
+ [string is integer -strict $s] \
+ [string is lower -strict $s] \
+ [string is print -strict $s] \
+ [string is punct -strict $s] \
+ [string is space -strict $s] \
+ [string is true -strict $s] \
+ [string is upper -strict $s] \
+ [string is wordchar -strict $s] \
+ [string is xdigit -strict $s] \
+
+} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}
+
+test string-24.1 {string reverse command} -body {
+ string reverse
+} -returnCodes error -result "wrong # args: should be \"string reverse string\""
+test string-24.2 {string reverse command} -body {
+ string reverse a b
+} -returnCodes error -result "wrong # args: should be \"string reverse string\""
+test string-24.3 {string reverse command - shared string} {
+ set x abcde
+ string reverse $x
+} edcba
+test string-24.4 {string reverse command - unshared string} {
+ set x abc
+ set y de
+ string reverse $x$y
+} edcba
+test string-24.5 {string reverse command - shared unicode string} {
+ set x abcde\udead
+ string reverse $x
+} \udeadedcba
+test string-24.6 {string reverse command - unshared string} {
+ set x abc
+ set y de\udead
+ string reverse $x$y
+} \udeadedcba
+test string-24.7 {string reverse command - simple case} {
+ string reverse a
+} a
+test string-24.8 {string reverse command - simple case} {
+ string reverse \udead
+} \udead
+test string-24.9 {string reverse command - simple case} {
+ string reverse {}
+} {}
+test string-24.10 {string reverse command - corner case} {
+ set x \ubeef\udead
+ string reverse $x
+} \udead\ubeef
+test string-24.11 {string reverse command - corner case} {
+ set x \ubeef
+ set y \udead
+ string reverse $x$y
+} \udead\ubeef
+test string-24.12 {string reverse command - corner case} {
+ set x \ubeef
+ set y \udead
+ string is ascii [string reverse $x$y]
+} 0
+test string-24.13 {string reverse command - pure Unicode string} {
+ string reverse [string range \ubeef\udead\ubeef\udead\ubeef\udead 1 5]
+} \udead\ubeef\udead\ubeef\udead
+test string-24.14 {string reverse command - pure bytearray} {
+ binary scan [string reverse [binary format H* 010203]] H* x
+ set x
+} 030201
+test string-24.15 {string reverse command - pure bytearray} {
+ binary scan [tcl::string::reverse [binary format H* 010203]] H* x
+ set x
+} 030201
+
+test string-25.1 {string is list} {
+ string is list {a b c}
+} 1
+test string-25.2 {string is list} {
+ string is list "a \{b c"
+} 0
+test string-25.3 {string is list} {
+ string is list {a {b c}d e}
+} 0
+test string-25.4 {string is list} {
+ string is list {}
+} 1
+test string-25.5 {string is list} {
+ string is list -strict {a b c}
+} 1
+test string-25.6 {string is list} {
+ string is list -strict "a \{b c"
+} 0
+test string-25.7 {string is list} {
+ string is list -strict {a {b c}d e}
+} 0
+test string-25.8 {string is list} {
+ string is list -strict {}
+} 1
+test string-25.9 {string is list} {
+ set x {}
+ list [string is list -failindex x {a b c}] $x
+} {1 {}}
+test string-25.10 {string is list} {
+ set x {}
+ list [string is list -failindex x "a \{b c"] $x
+} {0 2}
+test string-25.11 {string is list} {
+ set x {}
+ list [string is list -failindex x {a b {b c}d e}] $x
+} {0 4}
+test string-25.12 {string is list} {
+ set x {}
+ list [string is list -failindex x {}] $x
+} {1 {}}
+test string-25.13 {string is list} {
+ set x {}
+ list [string is list -failindex x { {b c}d e}] $x
+} {0 2}
+test string-25.14 {string is list} {
+ set x {}
+ list [string is list -failindex x "\uabcd {b c}d e"] $x
+} {0 2}
+
+test string-26.1 {tcl::prefix, too few args} -body {
+ tcl::prefix match a
+} -returnCodes 1 -result {wrong # args: should be "tcl::prefix match ?options? table string"}
+test string-26.2 {tcl::prefix, bad args} -body {
+ tcl::prefix match a b c
+} -returnCodes 1 -result {bad option "a": must be -error, -exact, or -message}
+test string-26.2.1 {tcl::prefix, empty table} -body {
+ tcl::prefix match {} foo
+} -returnCodes 1 -result {bad option "foo": no valid options}
+test string-26.3 {tcl::prefix, bad args} -body {
+ tcl::prefix match -error "{}x" -exact str1 str2
+} -returnCodes 1 -result {list element in braces followed by "x" instead of space}
+test string-26.3.1 {tcl::prefix, bad args} -body {
+ tcl::prefix match -error "x" -exact str1 str2
+} -returnCodes 1 -result {error options must have an even number of elements}
+test string-26.3.2 {tcl::prefix, bad args} -body {
+ tcl::prefix match -error str1 str2
+} -returnCodes 1 -result {missing error options}
+test string-26.4 {tcl::prefix, bad args} -body {
+ tcl::prefix match -message str1 str2
+} -returnCodes 1 -result {missing message}
+test string-26.5 {tcl::prefix} {
+ tcl::prefix match {apa bepa cepa depa} cepa
+} cepa
+test string-26.6 {tcl::prefix} {
+ tcl::prefix match {apa bepa cepa depa} be
+} bepa
+test string-26.7 {tcl::prefix} -body {
+ tcl::prefix match -exact {apa bepa cepa depa} be
+} -returnCodes 1 -result {bad option "be": must be apa, bepa, cepa, or depa}
+test string-26.8 {tcl::prefix} -body {
+ tcl::prefix match -message switch {apa bepa bear depa} be
+} -returnCodes 1 -result {ambiguous switch "be": must be apa, bepa, bear, or depa}
+test string-26.9 {tcl::prefix} -body {
+ tcl::prefix match -error {} {apa bepa bear depa} be
+} -returnCodes 0 -result {}
+test string-26.10 {tcl::prefix} -body {
+ tcl::prefix match -error {-level 1} {apa bepa bear depa} be
+} -returnCodes 2 -result {ambiguous option "be": must be apa, bepa, bear, or depa}
+test string-26.10.1 {tcl::prefix} -setup {
+ proc _testprefix {args} {
+ array set opts {-a x -b y -c y}
+ foreach {opt val} $args {
+ set opt [tcl::prefix match -error {-level 1} {-a -b -c} $opt]
+ set opts($opt) $val
+ }
+ array get opts
+ }
+} -body {
+ set a [catch {_testprefix -x u} result options]
+ dict get $options -errorinfo
+} -cleanup {
+ rename _testprefix {}
+} -result {bad option "-x": must be -a, -b, or -c
+ while executing
+"_testprefix -x u"}
+
+# Helper for memory stress tests
+# Repeat each body in a local space checking that memory does not increase
+proc MemStress {args} {
+ set res {}
+ foreach body $args {
+ set end 0
+ for {set i 0} {$i < 5} {incr i} {
+ proc MemStress_Body {} $body
+ uplevel 1 MemStress_Body
+ rename MemStress_Body {}
+ set tmp $end
+ set end [lindex [lindex [split [memory info] "\n"] 3] 3]
+ }
+ lappend res [expr {$end - $tmp}]
+ }
+ return $res
+}
+
+test string-26.11 {tcl::prefix: testing for leaks} -body {
+ # This test is made to stress object reference management
+ MemStress {
+ set table {hejj miff gurk}
+ set item [lindex $table 1]
+ # If not careful, this can cause a circular reference
+ # that will cause a leak.
+ tcl::prefix match $table $item
+ } {
+ # A similar case with nested lists
+ set table2 {hejj {miff maff} gurk}
+ set item [lindex [lindex $table2 1] 0]
+ tcl::prefix match $table2 $item
+ } {
+ # A similar case with dict
+ set table3 {hejj {miff maff} gurk2}
+ set item [lindex [dict keys [lindex $table3 1]] 0]
+ tcl::prefix match $table3 $item
+ }
+} -constraints memory -result {0 0 0}
+
+test string-26.12 {tcl::prefix: testing for leaks} -body {
+ # This is a memory leak test in a form that might actually happen
+ # in real code. The shared literal "miff" causes a connection
+ # between the item and the table.
+ MemStress {
+ proc stress1 {item} {
+ set table [list hejj miff gurk]
+ tcl::prefix match $table $item
+ }
+ proc stress2 {} {
+ stress1 miff
+ }
+ stress2
+ rename stress1 {}
+ rename stress2 {}
+ }
+} -constraints memory -result 0
+
+test string-26.13 {tcl::prefix: testing for leaks} -body {
+ # This test is made to stress object reference management
+ MemStress {
+ set table [list hejj miff]
+ set item $table
+ set error $table
+ # Use the same objects in all places
+ catch {
+ tcl::prefix match -error $error $table $item
+ }
+ }
+} -constraints memory -result {0}
+
+test string-27.1 {tcl::prefix all, too few args} -body {
+ tcl::prefix all a
+} -returnCodes 1 -result {wrong # args: should be "tcl::prefix all table string"}
+test string-27.2 {tcl::prefix all, bad args} -body {
+ tcl::prefix all a b c
+} -returnCodes 1 -result {wrong # args: should be "tcl::prefix all table string"}
+test string-27.3 {tcl::prefix all, bad args} -body {
+ tcl::prefix all "{}x" str2
+} -returnCodes 1 -result {list element in braces followed by "x" instead of space}
+test string-27.4 {tcl::prefix all} {
+ tcl::prefix all {apa bepa cepa depa} c
+} cepa
+test string-27.5 {tcl::prefix all} {
+ tcl::prefix all {apa bepa cepa depa} cepa
+} cepa
+test string-27.6 {tcl::prefix all} {
+ tcl::prefix all {apa bepa cepa depa} cepax
+} {}
+test string-27.7 {tcl::prefix all} {
+ tcl::prefix all {apa aska appa} a
+} {apa aska appa}
+test string-27.8 {tcl::prefix all} {
+ tcl::prefix all {apa aska appa} ap
+} {apa appa}
+test string-27.9 {tcl::prefix all} {
+ tcl::prefix all {apa aska appa} p
+} {}
+test string-27.10 {tcl::prefix all} {
+ tcl::prefix all {apa aska appa} {}
+} {apa aska appa}
+
+test string-28.1 {tcl::prefix longest, too few args} -body {
+ tcl::prefix longest a
+} -returnCodes 1 -result {wrong # args: should be "tcl::prefix longest table string"}
+test string-28.2 {tcl::prefix longest, bad args} -body {
+ tcl::prefix longest a b c
+} -returnCodes 1 -result {wrong # args: should be "tcl::prefix longest table string"}
+test string-28.3 {tcl::prefix longest, bad args} -body {
+ tcl::prefix longest "{}x" str2
+} -returnCodes 1 -result {list element in braces followed by "x" instead of space}
+test string-28.4 {tcl::prefix longest} {
+ tcl::prefix longest {apa bepa cepa depa} c
+} cepa
+test string-28.5 {tcl::prefix longest} {
+ tcl::prefix longest {apa bepa cepa depa} cepa
+} cepa
+test string-28.6 {tcl::prefix longest} {
+ tcl::prefix longest {apa bepa cepa depa} cepax
+} {}
+test string-28.7 {tcl::prefix longest} {
+ tcl::prefix longest {apa aska appa} a
+} a
+test string-28.8 {tcl::prefix longest} {
+ tcl::prefix longest {apa aska appa} ap
+} ap
+test string-28.9 {tcl::prefix longest} {
+ tcl::prefix longest {apa bska appa} a
+} ap
+test string-28.10 {tcl::prefix longest} {
+ tcl::prefix longest {apa bska appa} {}
+} {}
+test string-28.11 {tcl::prefix longest} {
+ tcl::prefix longest {{} bska appa} {}
+} {}
+test string-28.12 {tcl::prefix longest} {
+ tcl::prefix longest {apa {} appa} {}
+} {}
+test string-28.13 {tcl::prefix longest} {
+ # Test UTF8 handling
+ tcl::prefix longest {ax\x90 bep ax\x91} a
+} ax
+
+# cleanup
+rename MemStress {}
+catch {rename foo {}}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/stringComp.test b/library/msgcat/tests/stringComp.test
new file mode 100644
index 0000000..ff18819
--- /dev/null
+++ b/library/msgcat/tests/stringComp.test
@@ -0,0 +1,703 @@
+# Commands covered: string
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# This differs from the original string tests in that the tests call
+# things in procs, which uses the compiled string code instead of
+# the runtime parse string code. The tests of import should match
+# their equivalent number in string.test.
+#
+# Copyright (c) 2001 by ActiveState Corporation.
+# Copyright (c) 2001 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# Some tests require the testobj command
+
+testConstraint testobj [expr {[info commands testobj] != {}}]
+
+test stringComp-1.1 {error conditions} {
+ proc foo {} {string gorp a b}
+ list [catch {foo} msg] $msg
+} {1 {unknown or ambiguous subcommand "gorp": must be bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}}
+test stringComp-1.2 {error conditions} {
+ proc foo {} {string}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string subcommand ?arg ...?"}}
+test stringComp-1.3 {error condition - undefined method during compile} {
+ # We don't want this to complain about 'never' because it may never
+ # be called, or string may get redefined. This must compile OK.
+ proc foo {str i} {
+ if {"yes" == "no"} { string never called but complains here }
+ string index $str $i
+ }
+ foo abc 0
+} a
+
+## Test string compare|equal over equal constraints
+## Use result for string compare, and negate it for string equal
+## The body will be tested both in and outside a proc
+set i 0
+foreach {tname tbody tresult tcode} {
+ {too few args} {
+ string compare a
+ } {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"} {error}
+ {bad args} {
+ string compare a b c
+ } {bad option "a": must be -nocase or -length} {error}
+ {bad args} {
+ string compare -length -nocase str1 str2
+ } {expected integer but got "-nocase"} {error}
+ {too many args} {
+ string compare -length 10 -nocase str1 str2 str3
+ } {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"} {error}
+ {compare with length unspecified} {
+ string compare -length 10 10
+ } {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"} {error}
+ {basic operation fail} {
+ string compare abcde abdef
+ } {-1} {}
+ {basic operation success} {
+ string compare abcde abcde
+ } {0} {}
+ {with length} {
+ string compare -length 2 abcde abxyz
+ } {0} {}
+ {with special index} {
+ string compare -length end-3 abcde abxyz
+ } {expected integer but got "end-3"} {error}
+ {unicode} {
+ string compare ab\u7266 ab\u7267
+ } {-1} {}
+ {unicode} {string compare \334 \u00dc} 0 {}
+ {unicode} {string compare \334 \u00fc} -1 {}
+ {unicode} {string compare \334\334\334\374\374 \334\334\334\334\334} 1 {}
+ {high bit} {
+ # This test will fail if the underlying comparaison
+ # is using signed chars instead of unsigned chars.
+ # (like SunOS's default memcmp thus the compat/memcmp.c)
+ string compare "\x80" "@"
+ # Nb this tests works also in utf8 space because \x80 is
+ # translated into a 2 or more bytelength but whose first byte has
+ # the high bit set.
+ } {1} {}
+ {-nocase 1} {string compare -nocase abcde abdef} {-1} {}
+ {-nocase 2} {string compare -nocase abcde Abdef} {-1} {}
+ {-nocase 3} {string compare -nocase abcde ABCDE} {0} {}
+ {-nocase 4} {string compare -nocase abcde abcde} {0} {}
+ {-nocase unicode} {
+ string compare -nocase \334 \u00dc
+ } 0 {}
+ {-nocase unicode} {
+ string compare -nocase \334\334\334\374\u00fc \334\334\334\334\334
+ } 0 {}
+ {-nocase with length} {
+ string compare -length 2 -nocase abcde Abxyz
+ } {0} {}
+ {-nocase with length} {
+ string compare -nocase -length 3 abcde Abxyz
+ } {-1} {}
+ {-nocase with length <= 0} {
+ string compare -nocase -length -1 abcde AbCdEf
+ } {-1} {}
+ {-nocase with excessive length} {
+ string compare -nocase -length 50 AbCdEf abcde
+ } {1} {}
+ {-len unicode} {
+ # These are strings that are 6 BYTELENGTH long, but the length
+ # shouldn't make a different because there are actually 3 CHARS long
+ string compare -len 5 \334\334\334 \334\334\374
+ } -1 {}
+ {-nocase with special index} {
+ string compare -nocase -length end-3 Abcde abxyz
+ } {expected integer but got "end-3"} error
+ {null strings} {
+ string compare "" ""
+ } 0 {}
+ {null strings} {
+ string compare "" foo
+ } -1 {}
+ {null strings} {
+ string compare foo ""
+ } 1 {}
+ {-nocase null strings} {
+ string compare -nocase "" ""
+ } 0 {}
+ {-nocase null strings} {
+ string compare -nocase "" foo
+ } -1 {}
+ {-nocase null strings} {
+ string compare -nocase foo ""
+ } 1 {}
+ {with length, unequal strings} {
+ string compare -length 2 abc abde
+ } 0 {}
+ {with length, unequal strings} {
+ string compare -length 2 ab abde
+ } 0 {}
+ {with NUL character vs. other ASCII} {
+ # Be careful here, since UTF-8 rep comparison with memcmp() of
+ # these puts chars in the wrong order
+ string compare \x00 \x01
+ } -1 {}
+ {high bit} {
+ string compare "a\x80" "a@"
+ } 1 {}
+ {high bit} {
+ string compare "a\x00" "a\x01"
+ } -1 {}
+ {high bit} {
+ string compare "\x00\x00" "\x00\x01"
+ } -1 {}
+ {binary equal} {
+ string compare [binary format a100 0] [binary format a100 0]
+ } 0 {}
+ {binary neq} {
+ string compare [binary format a100a 0 1] [binary format a100a 0 0]
+ } 1 {}
+ {binary neq inequal length} {
+ string compare [binary format a20a 0 1] [binary format a100a 0 0]
+ } 1 {}
+} {
+ if {$tname eq ""} { continue }
+ if {$tcode eq ""} { set tcode ok }
+ test stringComp-2.[incr i] "string compare, $tname" \
+ -body [list eval $tbody] \
+ -returnCodes $tcode -result $tresult
+ test stringComp-2.[incr i] "string compare bc, $tname" \
+ -body "[list proc foo {} $tbody];foo" \
+ -returnCodes $tcode -result $tresult
+ if {"error" ni $tcode} {
+ set tresult [expr {!$tresult}]
+ } else {
+ set tresult [string map {compare equal} $tresult]
+ }
+ set tbody [string map {compare equal} $tbody]
+ test stringComp-2.[incr i] "string equal, $tname" \
+ -body [list eval $tbody] \
+ -returnCodes $tcode -result $tresult
+ test stringComp-2.[incr i] "string equal bc, $tname" \
+ -body "[list proc foo {} $tbody];foo" \
+ -returnCodes $tcode -result $tresult
+}
+
+# need a few extra tests short abbr cmd
+test stringComp-3.1 {string compare, shortest method name} {
+ proc foo {} {string c abcde ABCDE}
+ foo
+} 1
+test stringComp-3.2 {string equal, shortest method name} {
+ proc foo {} {string e abcde ABCDE}
+ foo
+} 0
+test stringComp-3.3 {string equal -nocase} {
+ proc foo {} {string eq -nocase abcde ABCDE}
+ foo
+} 1
+
+test stringComp-4.1 {string first, too few args} {
+ proc foo {} {string first a}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string first needleString haystackString ?startIndex?"}}
+test stringComp-4.2 {string first, bad args} {
+ proc foo {} {string first a b c}
+ list [catch {foo} msg] $msg
+} {1 {bad index "c": must be integer?[+-]integer? or end?[+-]integer?}}
+test stringComp-4.3 {string first, too many args} {
+ proc foo {} {string first a b 5 d}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string first needleString haystackString ?startIndex?"}}
+test stringComp-4.4 {string first} {
+ proc foo {} {string first bq abcdefgbcefgbqrs}
+ foo
+} 12
+test stringComp-4.5 {string first} {
+ proc foo {} {string fir bcd abcdefgbcefgbqrs}
+ foo
+} 1
+test stringComp-4.6 {string first} {
+ proc foo {} {string f b abcdefgbcefgbqrs}
+ foo
+} 1
+test stringComp-4.7 {string first} {
+ proc foo {} {string first xxx x123xx345xxx789xxx012}
+ foo
+} 9
+test stringComp-4.8 {string first} {
+ proc foo {} {string first "" x123xx345xxx789xxx012}
+ foo
+} -1
+test stringComp-4.9 {string first, unicode} {
+ proc foo {} {string first x abc\u7266x}
+ foo
+} 4
+test stringComp-4.10 {string first, unicode} {
+ proc foo {} {string first \u7266 abc\u7266x}
+ foo
+} 3
+test stringComp-4.11 {string first, start index} {
+ proc foo {} {string first \u7266 abc\u7266x 3}
+ foo
+} 3
+test stringComp-4.12 {string first, start index} {
+ proc foo {} {string first \u7266 abc\u7266x 4}
+ foo
+} -1
+test stringComp-4.13 {string first, start index} {
+ proc foo {} {string first \u7266 abc\u7266x end-2}
+ foo
+} 3
+test stringComp-4.14 {string first, negative start index} {
+ proc foo {} {string first b abc -1}
+ foo
+} 1
+
+test stringComp-5.1 {string index} {
+ proc foo {} {string index}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string index string charIndex"}}
+test stringComp-5.2 {string index} {
+ proc foo {} {string index a b c}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string index string charIndex"}}
+test stringComp-5.3 {string index} {
+ proc foo {} {string index abcde 0}
+ foo
+} a
+test stringComp-5.4 {string index} {
+ proc foo {} {string in abcde 4}
+ foo
+} e
+test stringComp-5.5 {string index} {
+ proc foo {} {string index abcde 5}
+ foo
+} {}
+test stringComp-5.6 {string index} {
+ proc foo {} {string index abcde -10}
+ list [catch {foo} msg] $msg
+} {0 {}}
+test stringComp-5.7 {string index} {
+ proc foo {} {string index a xyz}
+ list [catch {foo} msg] $msg
+} {1 {bad index "xyz": must be integer?[+-]integer? or end?[+-]integer?}}
+test stringComp-5.8 {string index} {
+ proc foo {} {string index abc end}
+ foo
+} c
+test stringComp-5.9 {string index} {
+ proc foo {} {string index abc end-1}
+ foo
+} b
+test stringComp-5.10 {string index, unicode} {
+ proc foo {} {string index abc\u7266d 4}
+ foo
+} d
+test stringComp-5.11 {string index, unicode} {
+ proc foo {} {string index abc\u7266d 3}
+ foo
+} \u7266
+test stringComp-5.12 {string index, unicode over char length, under byte length} {
+ proc foo {} {string index \334\374\334\374 6}
+ foo
+} {}
+test stringComp-5.13 {string index, bytearray object} {
+ proc foo {} {string index [binary format a5 fuz] 0}
+ foo
+} f
+test stringComp-5.14 {string index, bytearray object} {
+ proc foo {} {string index [binary format I* {0x50515253 0x52}] 3}
+ foo
+} S
+test stringComp-5.15 {string index, bytearray object} {
+ proc foo {} {
+ set b [binary format I* {0x50515253 0x52}]
+ set i1 [string index $b end-6]
+ set i2 [string index $b 1]
+ string compare $i1 $i2
+ }
+ foo
+} 0
+test stringComp-5.16 {string index, bytearray object with string obj shimmering} {
+ proc foo {} {
+ set str "0123456789\x00 abcdedfghi"
+ binary scan $str H* dump
+ string compare [string index $str 10] \x00
+ }
+ foo
+} 0
+test stringComp-5.17 {string index, bad integer} -body {
+ proc foo {} {string index "abc" 0o8}
+ list [catch {foo} msg] $msg
+} -match glob -result {1 {*invalid octal number*}}
+test stringComp-5.18 {string index, bad integer} -body {
+ proc foo {} {string index "abc" end-0o0289}
+ list [catch {foo} msg] $msg
+} -match glob -result {1 {*invalid octal number*}}
+test stringComp-5.19 {string index, bytearray object out of bounds} {
+ proc foo {} {string index [binary format I* {0x50515253 0x52}] -1}
+ foo
+} {}
+test stringComp-5.20 {string index, bytearray object out of bounds} {
+ proc foo {} {string index [binary format I* {0x50515253 0x52}] 20}
+ foo
+} {}
+
+
+proc largest_int {} {
+ # This will give us what the largest valid int on this machine is,
+ # so we can test for overflow properly below on >32 bit systems
+ set int 1
+ set exp 7; # assume we get at least 8 bits
+ while {$int > 0} { set int [expr {1 << [incr exp]}] }
+ return [expr {$int-1}]
+}
+
+## string is
+## not yet bc
+
+catch {rename largest_int {}}
+
+## string last
+## not yet bc
+
+## string length
+## not yet bc
+test stringComp-8.1 {string bytelength} {
+ proc foo {} {string bytelength}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string bytelength string"}}
+test stringComp-8.2 {string bytelength} {
+ proc foo {} {string bytelength a b}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string bytelength string"}}
+test stringComp-8.3 {string bytelength} {
+ proc foo {} {string bytelength "\u00c7"}
+ foo
+} 2
+test stringComp-8.4 {string bytelength} {
+ proc foo {} {string b ""}
+ foo
+} 0
+
+## string length
+##
+test stringComp-9.1 {string length} {
+ proc foo {} {string length}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string length string"}}
+test stringComp-9.2 {string length} {
+ proc foo {} {string length a b}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string length string"}}
+test stringComp-9.3 {string length} {
+ proc foo {} {string length "a little string"}
+ foo
+} 15
+test stringComp-9.4 {string length} {
+ proc foo {} {string le ""}
+ foo
+} 0
+test stringComp-9.5 {string length, unicode} {
+ proc foo {} {string le "abcd\u7266"}
+ foo
+} 5
+test stringComp-9.6 {string length, bytearray object} {
+ proc foo {} {string length [binary format a5 foo]}
+ foo
+} 5
+test stringComp-9.7 {string length, bytearray object} {
+ proc foo {} {string length [binary format I* {0x50515253 0x52}]}
+ foo
+} 8
+
+## string map
+## not yet bc
+
+## string match
+##
+test stringComp-11.1 {string match, too few args} {
+ proc foo {} {string match a}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string match ?-nocase? pattern string"}}
+test stringComp-11.2 {string match, too many args} {
+ proc foo {} {string match a b c d}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string match ?-nocase? pattern string"}}
+test stringComp-11.3 {string match} {
+ proc foo {} {string match abc abc}
+ foo
+} 1
+test stringComp-11.4 {string match} {
+ proc foo {} {string mat abc abd}
+ foo
+} 0
+test stringComp-11.5 {string match} {
+ proc foo {} {string match ab*c abc}
+ foo
+} 1
+test stringComp-11.6 {string match} {
+ proc foo {} {string match ab**c abc}
+ foo
+} 1
+test stringComp-11.7 {string match} {
+ proc foo {} {string match ab* abcdef}
+ foo
+} 1
+test stringComp-11.8 {string match} {
+ proc foo {} {string match *c abc}
+ foo
+} 1
+test stringComp-11.9 {string match} {
+ proc foo {} {string match *3*6*9 0123456789}
+ foo
+} 1
+test stringComp-11.10 {string match} {
+ proc foo {} {string match *3*6*9 01234567890}
+ foo
+} 0
+test stringComp-11.11 {string match} {
+ proc foo {} {string match a?c abc}
+ foo
+} 1
+test stringComp-11.12 {string match} {
+ proc foo {} {string match a??c abc}
+ foo
+} 0
+test stringComp-11.13 {string match} {
+ proc foo {} {string match ?1??4???8? 0123456789}
+ foo
+} 1
+test stringComp-11.14 {string match} {
+ proc foo {} {string match {[abc]bc} abc}
+ foo
+} 1
+test stringComp-11.15 {string match} {
+ proc foo {} {string match {a[abc]c} abc}
+ foo
+} 1
+test stringComp-11.16 {string match} {
+ proc foo {} {string match {a[xyz]c} abc}
+ foo
+} 0
+test stringComp-11.17 {string match} {
+ proc foo {} {string match {12[2-7]45} 12345}
+ foo
+} 1
+test stringComp-11.18 {string match} {
+ proc foo {} {string match {12[ab2-4cd]45} 12345}
+ foo
+} 1
+test stringComp-11.19 {string match} {
+ proc foo {} {string match {12[ab2-4cd]45} 12b45}
+ foo
+} 1
+test stringComp-11.20 {string match} {
+ proc foo {} {string match {12[ab2-4cd]45} 12d45}
+ foo
+} 1
+test stringComp-11.21 {string match} {
+ proc foo {} {string match {12[ab2-4cd]45} 12145}
+ foo
+} 0
+test stringComp-11.22 {string match} {
+ proc foo {} {string match {12[ab2-4cd]45} 12545}
+ foo
+} 0
+test stringComp-11.23 {string match} {
+ proc foo {} {string match {a\*b} a*b}
+ foo
+} 1
+test stringComp-11.24 {string match} {
+ proc foo {} {string match {a\*b} ab}
+ foo
+} 0
+test stringComp-11.25 {string match} {
+ proc foo {} {string match {a\*\?\[\]\\\x} "a*?\[\]\\x"}
+ foo
+} 1
+test stringComp-11.26 {string match} {
+ proc foo {} {string match ** ""}
+ foo
+} 1
+test stringComp-11.27 {string match} {
+ proc foo {} {string match *. ""}
+ foo
+} 0
+test stringComp-11.28 {string match} {
+ proc foo {} {string match "" ""}
+ foo
+} 1
+test stringComp-11.29 {string match} {
+ proc foo {} {string match \[a a}
+ foo
+} 1
+test stringComp-11.30 {string match, bad args} {
+ proc foo {} {string match - b c}
+ list [catch {foo} msg] $msg
+} {1 {bad option "-": must be -nocase}}
+test stringComp-11.31 {string match case} {
+ proc foo {} {string match a A}
+ foo
+} 0
+test stringComp-11.32 {string match nocase} {
+ proc foo {} {string match -n a A}
+ foo
+} 1
+test stringComp-11.33 {string match nocase} {
+ proc foo {} {string match -nocase a\334 A\374}
+ foo
+} 1
+test stringComp-11.34 {string match nocase} {
+ proc foo {} {string match -nocase a*f ABCDEf}
+ foo
+} 1
+test stringComp-11.35 {string match case, false hope} {
+ # This is true because '_' lies between the A-Z and a-z ranges
+ proc foo {} {string match {[A-z]} _}
+ foo
+} 1
+test stringComp-11.36 {string match nocase range} {
+ # This is false because although '_' lies between the A-Z and a-z ranges,
+ # we lower case the end points before checking the ranges.
+ proc foo {} {string match -nocase {[A-z]} _}
+ foo
+} 0
+test stringComp-11.37 {string match nocase} {
+ proc foo {} {string match -nocase {[A-fh-Z]} g}
+ foo
+} 0
+test stringComp-11.38 {string match case, reverse range} {
+ proc foo {} {string match {[A-fh-Z]} g}
+ foo
+} 1
+test stringComp-11.39 {string match, *\ case} {
+ proc foo {} {string match {*\abc} abc}
+ foo
+} 1
+test stringComp-11.40 {string match, *special case} {
+ proc foo {} {string match {*[ab]} abc}
+ foo
+} 0
+test stringComp-11.41 {string match, *special case} {
+ proc foo {} {string match {*[ab]*} abc}
+ foo
+} 1
+test stringComp-11.42 {string match, *special case} {
+ proc foo {} {string match "*\\" "\\"}
+ foo
+} 0
+test stringComp-11.43 {string match, *special case} {
+ proc foo {} {string match "*\\\\" "\\"}
+ foo
+} 1
+test stringComp-11.44 {string match, *special case} {
+ proc foo {} {string match "*???" "12345"}
+ foo
+} 1
+test stringComp-11.45 {string match, *special case} {
+ proc foo {} {string match "*???" "12"}
+ foo
+} 0
+test stringComp-11.46 {string match, *special case} {
+ proc foo {} {string match "*\\*" "abc*"}
+ foo
+} 1
+test stringComp-11.47 {string match, *special case} {
+ proc foo {} {string match "*\\*" "*"}
+ foo
+} 1
+test stringComp-11.48 {string match, *special case} {
+ proc foo {} {string match "*\\*" "*abc"}
+ foo
+} 0
+test stringComp-11.49 {string match, *special case} {
+ proc foo {} {string match "?\\*" "a*"}
+ foo
+} 1
+test stringComp-11.50 {string match, *special case} {
+ proc foo {} {string match "\\" "\\"}
+ foo
+} 0
+test stringComp-11.51 {string match; *, -nocase and UTF-8} {
+ proc foo {} {string match -nocase [binary format I 717316707] \
+ [binary format I 2028036707]}
+ foo
+} 1
+test stringComp-11.52 {string match, null char in string} {
+ proc foo {} {
+ set ptn "*abc*"
+ foreach elem [list "\u0000@abc" "@abc" "\u0000@abc\u0000" "blahabcblah"] {
+ lappend out [string match $ptn $elem]
+ }
+ set out
+ }
+ foo
+} {1 1 1 1}
+test stringComp-11.53 {string match, null char in pattern} {
+ proc foo {} {
+ set out ""
+ foreach {ptn elem} [list \
+ "*\u0000abc\u0000" "\u0000abc\u0000" \
+ "*\u0000abc\u0000" "\u0000abc\u0000ef" \
+ "*\u0000abc\u0000*" "\u0000abc\u0000ef" \
+ "*\u0000abc\u0000" "@\u0000abc\u0000ef" \
+ "*\u0000abc\u0000*" "@\u0000abc\u0000ef" \
+ ] {
+ lappend out [string match $ptn $elem]
+ }
+ set out
+ }
+ foo
+} {1 0 1 0 1}
+test stringComp-11.54 {string match, failure} {
+ proc foo {} {
+ set longString ""
+ for {set i 0} {$i < 10} {incr i} {
+ append longString "abcdefghijklmnopqrstuvwxy\u0000z01234567890123"
+ }
+ list [string match *cba* $longString] \
+ [string match *a*l*\u0000* $longString] \
+ [string match *a*l*\u0000*123 $longString] \
+ [string match *a*l*\u0000*123* $longString] \
+ [string match *a*l*\u0000*cba* $longString] \
+ [string match *===* $longString]
+ }
+ foo
+} {0 1 1 1 0 0}
+
+## string range
+## not yet bc
+
+## string repeat
+## not yet bc
+
+## string replace
+## not yet bc
+
+## string tolower
+## not yet bc
+
+## string toupper
+## not yet bc
+
+## string totitle
+## not yet bc
+
+## string trim*
+## not yet bc
+
+## string word*
+## not yet bc
+
+# cleanup
+catch {rename foo {}}
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/stringObj.test b/library/msgcat/tests/stringObj.test
new file mode 100644
index 0000000..d93bb82
--- /dev/null
+++ b/library/msgcat/tests/stringObj.test
@@ -0,0 +1,487 @@
+# Commands covered: none
+#
+# This file contains tests for the procedures in tclStringObj.c that implement
+# the Tcl type manager for the string type.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1995-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testobj [llength [info commands testobj]]
+testConstraint testdstring [llength [info commands testdstring]]
+
+test stringObj-1.1 {string type registration} testobj {
+ set t [testobj types]
+ set first [string first "string" $t]
+ set result [expr {$first != -1}]
+} {1}
+
+test stringObj-2.1 {Tcl_NewStringObj} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [teststringobj set 1 abcd]
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} abcd string 2}
+
+test stringObj-3.1 {Tcl_SetStringObj, existing "empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testobj newobj 1]
+ lappend result [teststringobj set 1 xyz] ;# makes existing obj a string
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} {} xyz string 2}
+test stringObj-3.2 {Tcl_SetStringObj, existing non-"empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testintobj set 1 512]
+ lappend result [teststringobj set 1 foo] ;# makes existing obj a string
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 512 foo string 2}
+
+test stringObj-4.1 {Tcl_SetObjLength procedure, string gets shorter} testobj {
+ testobj freeallvars
+ teststringobj set 1 test
+ teststringobj setlength 1 3
+ list [teststringobj length 1] [teststringobj length2 1] \
+ [teststringobj get 1]
+} {3 4 tes}
+test stringObj-4.2 {Tcl_SetObjLength procedure, string gets longer} testobj {
+ testobj freeallvars
+ teststringobj set 1 abcdef
+ teststringobj setlength 1 10
+ list [teststringobj length 1] [teststringobj length2 1]
+} {10 10}
+test stringObj-4.3 {Tcl_SetObjLength procedure, string gets longer} testobj {
+ testobj freeallvars
+ teststringobj set 1 abcdef
+ teststringobj append 1 xyzq -1
+ list [teststringobj length 1] [teststringobj length2 1] \
+ [teststringobj get 1]
+} {10 20 abcdefxyzq}
+test stringObj-4.4 {Tcl_SetObjLength procedure, "expty string", length 0} testobj {
+ testobj freeallvars
+ testobj newobj 1
+ teststringobj setlength 1 0
+ list [teststringobj length2 1] [teststringobj get 1]
+} {0 {}}
+
+test stringObj-5.1 {Tcl_AppendToObj procedure, type conversion} testobj {
+ testobj freeallvars
+ testintobj set2 1 43
+ teststringobj append 1 xyz -1
+ teststringobj get 1
+} {43xyz}
+test stringObj-5.2 {Tcl_AppendToObj procedure, length calculation} testobj {
+ testobj freeallvars
+ teststringobj set 1 {x y }
+ teststringobj append 1 bbCCddEE 4
+ teststringobj append 1 123 -1
+ teststringobj get 1
+} {x y bbCC123}
+test stringObj-5.3 {Tcl_AppendToObj procedure, reallocating space} testobj {
+ testobj freeallvars
+ teststringobj set 1 xyz
+ teststringobj setlength 1 15
+ teststringobj setlength 1 2
+ set result {}
+ teststringobj append 1 1234567890123 -1
+ lappend result [teststringobj length 1] [teststringobj length2 1]
+ teststringobj setlength 1 10
+ teststringobj append 1 abcdef -1
+ lappend result [teststringobj length 1] [teststringobj length2 1] \
+ [teststringobj get 1]
+} {15 15 16 32 xy12345678abcdef}
+
+test stringObj-6.1 {Tcl_AppendStringsToObj procedure, type conversion} testobj {
+ testobj freeallvars
+ teststringobj set2 1 [list a b]
+ teststringobj appendstrings 1 xyz { 1234 } foo
+ teststringobj get 1
+} {a bxyz 1234 foo}
+test stringObj-6.2 {Tcl_AppendStringsToObj procedure, counting space} testobj {
+ testobj freeallvars
+ teststringobj set 1 abc
+ teststringobj appendstrings 1
+ list [teststringobj length 1] [teststringobj get 1]
+} {3 abc}
+test stringObj-6.3 {Tcl_AppendStringsToObj procedure, counting space} testobj {
+ testobj freeallvars
+ teststringobj set 1 abc
+ teststringobj appendstrings 1 {} {} {} {}
+ list [teststringobj length 1] [teststringobj get 1]
+} {3 abc}
+test stringObj-6.4 {Tcl_AppendStringsToObj procedure, counting space} testobj {
+ testobj freeallvars
+ teststringobj set 1 abc
+ teststringobj appendstrings 1 { 123 } abcdefg
+ list [teststringobj length 1] [teststringobj get 1]
+} {15 {abc 123 abcdefg}}
+test stringObj-6.5 {Tcl_AppendStringsToObj procedure, don't double space if initial string empty} testobj {
+ testobj freeallvars
+ testobj newobj 1
+ teststringobj appendstrings 1 123 abcdefg
+ list [teststringobj length 1] [teststringobj length2 1] [teststringobj get 1]
+} {10 20 123abcdefg}
+test stringObj-6.6 {Tcl_AppendStringsToObj procedure, space reallocation} testobj {
+ testobj freeallvars
+ teststringobj set 1 abc
+ teststringobj setlength 1 10
+ teststringobj setlength 1 2
+ teststringobj appendstrings 1 34567890
+ list [teststringobj length 1] [teststringobj length2 1] \
+ [teststringobj get 1]
+} {10 10 ab34567890}
+test stringObj-6.7 {Tcl_AppendStringsToObj procedure, space reallocation} testobj {
+ testobj freeallvars
+ teststringobj set 1 abc
+ teststringobj setlength 1 10
+ teststringobj setlength 1 2
+ teststringobj appendstrings 1 34567890x
+ list [teststringobj length 1] [teststringobj length2 1] \
+ [teststringobj get 1]
+} {11 22 ab34567890x}
+test stringObj-6.8 {Tcl_AppendStringsToObj procedure, object totally empty} testobj {
+ testobj freeallvars
+ testobj newobj 1
+ teststringobj appendstrings 1 {}
+ list [teststringobj length2 1] [teststringobj get 1]
+} {0 {}}
+test stringObj-6.9 {Tcl_AppendStringToObj, pure unicode} testobj {
+ testobj freeallvars
+ teststringobj set2 1 [string replace abc 1 1 d]
+ teststringobj appendstrings 1 foo bar soom
+ teststringobj get 1
+} adcfoobarsoom
+
+test stringObj-7.1 {SetStringFromAny procedure} testobj {
+ testobj freeallvars
+ teststringobj set2 1 [list a b]
+ teststringobj append 1 x -1
+ list [teststringobj length 1] [teststringobj length2 1] \
+ [teststringobj get 1]
+} {4 8 {a bx}}
+test stringObj-7.2 {SetStringFromAny procedure, null object} testobj {
+ testobj freeallvars
+ testobj newobj 1
+ teststringobj appendstrings 1 {}
+ list [teststringobj length 1] [teststringobj length2 1] \
+ [teststringobj get 1]
+} {0 0 {}}
+test stringObj-7.3 {SetStringFromAny called with non-string obj} testobj {
+ set x 2345
+ list [incr x] [testobj objtype $x] [string index $x end] \
+ [testobj objtype $x]
+} {2346 int 6 string}
+test stringObj-7.4 {SetStringFromAny called with string obj} testobj {
+ set x "abcdef"
+ list [string length $x] [testobj objtype $x] \
+ [string length $x] [testobj objtype $x]
+} {6 string 6 string}
+
+test stringObj-8.1 {DupStringInternalRep procedure} testobj {
+ testobj freeallvars
+ teststringobj set 1 {}
+ teststringobj append 1 abcde -1
+ testobj duplicate 1 2
+ list [teststringobj length 1] [teststringobj length2 1] \
+ [teststringobj maxchars 1] [teststringobj get 1] \
+ [teststringobj length 2] [teststringobj length2 2] \
+ [teststringobj maxchars 2] [teststringobj get 2]
+} {5 10 0 abcde 5 5 0 abcde}
+test stringObj-8.2 {DupUnicodeInternalRep, mixed width chars} testobj {
+ set x abc\u00ef\u00bf\u00aeghi
+ string length $x
+ set y $x
+ list [testobj objtype $x] [testobj objtype $y] [append x "\u00ae\u00bf\u00ef"] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} "string string abc\u00ef\u00bf\u00aeghi\u00ae\u00bf\u00ef abc\u00ef\u00bf\u00aeghi string string"
+test stringObj-8.3 {DupUnicodeInternalRep, mixed width chars} testobj {
+ set x abc\u00ef\u00bf\u00aeghi
+ set y $x
+ string length $x
+ list [testobj objtype $x] [testobj objtype $y] [append x "\u00ae\u00bf\u00ef"] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} "string string abc\u00ef\u00bf\u00aeghi\u00ae\u00bf\u00ef abc\u00ef\u00bf\u00aeghi string string"
+test stringObj-8.4 {DupUnicodeInternalRep, all byte-size chars} testobj {
+ set x abcdefghi
+ string length $x
+ set y $x
+ list [testobj objtype $x] [testobj objtype $y] [append x jkl] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} {string string abcdefghijkl abcdefghi string string}
+test stringObj-8.5 {DupUnicodeInternalRep, all byte-size chars} testobj {
+ set x abcdefghi
+ set y $x
+ string length $x
+ list [testobj objtype $x] [testobj objtype $y] [append x jkl] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} {string string abcdefghijkl abcdefghi string string}
+
+test stringObj-9.1 {TclAppendObjToObj, mixed src & dest} {testobj testdstring} {
+ set x abc\u00ef\u00bf\u00aeghi
+ testdstring free
+ testdstring append \u00ae\u00bf\u00ef -1
+ set y [testdstring get]
+ string length $x
+ list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} "string none abc\u00ef\u00bf\u00aeghi\u00ae\u00bf\u00ef \u00ae\u00bf\u00ef string none"
+test stringObj-9.2 {TclAppendObjToObj, mixed src & dest} testobj {
+ set x abc\u00ef\u00bf\u00aeghi
+ string length $x
+ list [testobj objtype $x] [append x $x] [testobj objtype $x] \
+ [append x $x] [testobj objtype $x]
+} "string abc\u00ef\u00bf\u00aeghiabc\u00ef\u00bf\u00aeghi string\
+abc\u00ef\u00bf\u00aeghiabc\u00ef\u00bf\u00aeghiabc\u00ef\u00bf\u00aeghiabc\u00ef\u00bf\u00aeghi\
+string"
+test stringObj-9.3 {TclAppendObjToObj, mixed src & 1-byte dest} {testobj testdstring} {
+ set x abcdefghi
+ testdstring free
+ testdstring append \u00ae\u00bf\u00ef -1
+ set y [testdstring get]
+ string length $x
+ list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} "string none abcdefghi\u00ae\u00bf\u00ef \u00ae\u00bf\u00ef string none"
+test stringObj-9.4 {TclAppendObjToObj, 1-byte src & dest} {testobj testdstring} {
+ set x abcdefghi
+ testdstring free
+ testdstring append jkl -1
+ set y [testdstring get]
+ string length $x
+ list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} {string none abcdefghijkl jkl string none}
+test stringObj-9.5 {TclAppendObjToObj, 1-byte src & dest} testobj {
+ set x abcdefghi
+ string length $x
+ list [testobj objtype $x] [append x $x] [testobj objtype $x] \
+ [append x $x] [testobj objtype $x]
+} {string abcdefghiabcdefghi string abcdefghiabcdefghiabcdefghiabcdefghi\
+string}
+test stringObj-9.6 {TclAppendObjToObj, 1-byte src & mixed dest} {testobj testdstring} {
+ set x abc\u00ef\u00bf\u00aeghi
+ testdstring free
+ testdstring append jkl -1
+ set y [testdstring get]
+ string length $x
+ list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} "string none abc\u00ef\u00bf\u00aeghijkl jkl string none"
+test stringObj-9.7 {TclAppendObjToObj, integer src & dest} testobj {
+ set x [expr {4 * 5}]
+ set y [expr {4 + 5}]
+ list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+ [testobj objtype $x] [append x $y] [testobj objtype $x] \
+ [testobj objtype $y]
+} {int int 209 string 2099 string int}
+test stringObj-9.8 {TclAppendObjToObj, integer src & dest} testobj {
+ set x [expr {4 * 5}]
+ list [testobj objtype $x] [append x $x] [testobj objtype $x] \
+ [append x $x] [testobj objtype $x]
+} {int 2020 string 20202020 string}
+test stringObj-9.9 {TclAppendObjToObj, integer src & 1-byte dest} testobj {
+ set x abcdefghi
+ set y [expr {4 + 5}]
+ string length $x
+ list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} {string int abcdefghi9 9 string int}
+test stringObj-9.10 {TclAppendObjToObj, integer src & mixed dest} testobj {
+ set x abc\u00ef\u00bf\u00aeghi
+ set y [expr {4 + 5}]
+ string length $x
+ list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} "string int abc\u00ef\u00bf\u00aeghi9 9 string int"
+test stringObj-9.11 {TclAppendObjToObj, mixed src & 1-byte dest index check} testobj {
+ # bug 2678, in <=8.2.0, the second obj (the one to append) in
+ # Tcl_AppendObjToObj was not correctly checked to see if it was all one
+ # byte chars, so a unicode string would be added as one byte chars.
+ set x abcdef
+ set len [string length $x]
+ set y a\u00fcb\u00e5c\u00ef
+ set len [string length $y]
+ append x $y
+ string length $x
+ set q {}
+ for {set i 0} {$i < 12} {incr i} {
+ lappend q [string index $x $i]
+ }
+ set q
+} "a b c d e f a \u00fc b \u00e5 c \u00ef"
+
+test stringObj-10.1 {Tcl_GetRange with all byte-size chars} {testobj testdstring} {
+ testdstring free
+ testdstring append abcdef -1
+ set x [testdstring get]
+ list [testobj objtype $x] [set y [string range $x 1 end-1]] \
+ [testobj objtype $x] [testobj objtype $y]
+} [list none bcde string string]
+test stringObj-10.2 {Tcl_GetRange with some mixed width chars} {testobj testdstring} {
+ # Because this test does not use \uXXXX notation below instead of
+ # hardcoding the values, it may fail in multibyte locales. However, we
+ # need to test that the parser produces untyped objects even when there
+ # are high-ASCII characters in the input (like "ï"). I don't know what
+ # else to do but inline those characters here.
+ testdstring free
+ testdstring append "abc\u00ef\u00efdef" -1
+ set x [testdstring get]
+ list [testobj objtype $x] [set y [string range $x 1 end-1]] \
+ [testobj objtype $x] [testobj objtype $y]
+} [list none "bc\u00EF\u00EFde" string string]
+test stringObj-10.3 {Tcl_GetRange with some mixed width chars} testobj {
+ # set x "abcïïdef"
+ # Use \uXXXX notation below instead of hardcoding the values, otherwise
+ # the test will fail in multibyte locales.
+ set x "abc\u00EF\u00EFdef"
+ string length $x
+ list [testobj objtype $x] [set y [string range $x 1 end-1]] \
+ [testobj objtype $x] [testobj objtype $y]
+} [list string "bc\u00EF\u00EFde" string string]
+test stringObj-10.4 {Tcl_GetRange with some mixed width chars} testobj {
+ # set a "ïa¿b®cï¿d®"
+ # Use \uXXXX notation below instead of hardcoding the values, otherwise
+ # the test will fail in multibyte locales.
+ set a "\u00EFa\u00BFb\u00AEc\u00EF\u00BFd\u00AE"
+ set result [list]
+ while {[string length $a] > 0} {
+ set a [string range $a 1 end-1]
+ lappend result $a
+ }
+ set result
+} [list a\u00BFb\u00AEc\u00EF\u00BFd \
+ \u00BFb\u00AEc\u00EF\u00BF \
+ b\u00AEc\u00EF \
+ \u00AEc \
+ {}]
+
+test stringObj-11.1 {UpdateStringOfString} testobj {
+ set x 2345
+ list [string index $x end] [testobj objtype $x] [incr x] \
+ [testobj objtype $x]
+} {5 string 2346 int}
+
+test stringObj-12.1 {Tcl_GetUniChar with byte-size chars} testobj {
+ set x "abcdefghi"
+ list [string index $x 0] [string index $x 1]
+} {a b}
+test stringObj-12.2 {Tcl_GetUniChar with byte-size chars} testobj {
+ set x "abcdefghi"
+ list [string index $x 3] [string index $x end]
+} {d i}
+test stringObj-12.3 {Tcl_GetUniChar with byte-size chars} testobj {
+ set x "abcdefghi"
+ list [string index $x end] [string index $x end-1]
+} {i h}
+test stringObj-12.4 {Tcl_GetUniChar with mixed width chars} testobj {
+ string index "\u00efa\u00bfb\u00aec\u00ae\u00bfd\u00ef" 0
+} "\u00ef"
+test stringObj-12.5 {Tcl_GetUniChar} testobj {
+ set x "\u00efa\u00bfb\u00aec\u00ae\u00bfd\u00ef"
+ list [string index $x 4] [string index $x 0]
+} "\u00ae \u00ef"
+test stringObj-12.6 {Tcl_GetUniChar} testobj {
+ string index "\u00efa\u00bfb\u00aec\u00ef\u00bfd\u00ae" end
+} "\u00ae"
+
+test stringObj-13.1 {Tcl_GetCharLength with byte-size chars} testobj {
+ set a ""
+ list [string length $a] [string length $a]
+} {0 0}
+test stringObj-13.2 {Tcl_GetCharLength with byte-size chars} testobj {
+ string length "a"
+} 1
+test stringObj-13.3 {Tcl_GetCharLength with byte-size chars} testobj {
+ set a "abcdef"
+ list [string length $a] [string length $a]
+} {6 6}
+test stringObj-13.4 {Tcl_GetCharLength with mixed width chars} testobj {
+ string length "\u00ae"
+} 1
+test stringObj-13.5 {Tcl_GetCharLength with mixed width chars} testobj {
+ # string length "○○"
+ # Use \uXXXX notation below instead of hardcoding the values, otherwise
+ # the test will fail in multibyte locales.
+ string length "\u00EF\u00BF\u00AE\u00EF\u00BF\u00AE"
+} 6
+test stringObj-13.6 {Tcl_GetCharLength with mixed width chars} testobj {
+ # set a "ïa¿b®cï¿d®"
+ # Use \uXXXX notation below instead of hardcoding the values, otherwise
+ # the test will fail in multibyte locales.
+ set a "\u00EFa\u00BFb\u00AEc\u00EF\u00BFd\u00AE"
+ list [string length $a] [string length $a]
+} {10 10}
+test stringObj-13.7 {Tcl_GetCharLength with identity nulls} testobj {
+ # SF bug #684699
+ string length [encoding convertfrom identity \x00]
+} 1
+test stringObj-13.8 {Tcl_GetCharLength with identity nulls} testobj {
+ string length [encoding convertfrom identity \x01\x00\x02]
+} 3
+
+test stringObj-14.1 {Tcl_SetObjLength on pure unicode object} testobj {
+ teststringobj set 1 foo
+ teststringobj getunicode 1
+ teststringobj append 1 bar -1
+ teststringobj getunicode 1
+ teststringobj append 1 bar -1
+ teststringobj setlength 1 0
+ teststringobj append 1 bar -1
+ teststringobj get 1
+} {bar}
+
+test stringObj-15.1 {Tcl_Append*ToObj: self appends} testobj {
+ teststringobj set 1 foo
+ teststringobj appendself 1 0
+} foofoo
+test stringObj-15.2 {Tcl_Append*ToObj: self appends} testobj {
+ teststringobj set 1 foo
+ teststringobj appendself 1 1
+} foooo
+test stringObj-15.3 {Tcl_Append*ToObj: self appends} testobj {
+ teststringobj set 1 foo
+ teststringobj appendself 1 2
+} fooo
+test stringObj-15.4 {Tcl_Append*ToObj: self appends} testobj {
+ teststringobj set 1 foo
+ teststringobj appendself 1 3
+} foo
+test stringObj-15.5 {Tcl_Append*ToObj: self appends} testobj {
+ teststringobj set 1 foo
+ teststringobj appendself2 1 0
+} foofoo
+test stringObj-15.6 {Tcl_Append*ToObj: self appends} testobj {
+ teststringobj set 1 foo
+ teststringobj appendself2 1 1
+} foooo
+test stringObj-15.7 {Tcl_Append*ToObj: self appends} testobj {
+ teststringobj set 1 foo
+ teststringobj appendself2 1 2
+} fooo
+test stringObj-15.8 {Tcl_Append*ToObj: self appends} testobj {
+ teststringobj set 1 foo
+ teststringobj appendself2 1 3
+} foo
+
+
+if {[testConstraint testobj]} {
+ testobj freeallvars
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/subst.test b/library/msgcat/tests/subst.test
new file mode 100644
index 0000000..4be4798
--- /dev/null
+++ b/library/msgcat/tests/subst.test
@@ -0,0 +1,303 @@
+# Commands covered: subst
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1994 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 Ajuba Solutions.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2.1
+ namespace import -force ::tcltest::*
+}
+
+test subst-1.1 {basics} -returnCodes error -body {
+ subst
+} -result {wrong # args: should be "subst ?-nobackslashes? ?-nocommands? ?-novariables? string"}
+test subst-1.2 {basics} -returnCodes error -body {
+ subst a b c
+} -result {bad switch "a": must be -nobackslashes, -nocommands, or -novariables}
+
+test subst-2.1 {simple strings} {
+ subst {}
+} {}
+test subst-2.2 {simple strings} {
+ subst a
+} a
+test subst-2.3 {simple strings} {
+ subst abcdefg
+} abcdefg
+test subst-2.4 {simple strings} {
+ # Tcl Bug 685106
+ subst [bytestring bar\x00soom]
+} [bytestring bar\x00soom]
+
+test subst-3.1 {backslash substitutions} {
+ subst {\x\$x\[foo bar]\\}
+} "x\$x\[foo bar]\\"
+test subst-3.2 {backslash substitutions with utf chars} {
+ # 'j' is just a char that doesn't mean anything, and \344 is 'ä'
+ # that also doesn't mean anything, but is multi-byte in UTF-8.
+ list [subst \j] [subst \\j] [subst \\344] [subst \\\344]
+} "j j \344 \344"
+
+test subst-4.1 {variable substitutions} {
+ set a 44
+ subst {$a}
+} {44}
+test subst-4.2 {variable substitutions} {
+ set a 44
+ subst {x$a.y{$a}.z}
+} {x44.y{44}.z}
+test subst-4.3 {variable substitutions} -setup {
+ catch {unset a}
+} -body {
+ set a(13) 82
+ set i 13
+ subst {x.$a($i)}
+} -result {x.82}
+catch {unset a}
+set long {This is a very long string, intentionally made so long that it
+ will overflow the static character size for dstrings, so that
+ additional memory will have to be allocated by subst. That way,
+ if the subst procedure forgets to free up memory while returning
+ an error, there will be memory that isn't freed (this will be
+ detected when the tests are run under a checking memory allocator
+ such as Purify).}
+test subst-4.4 {variable substitutions} -returnCodes error -body {
+ subst {$long $a}
+} -result {can't read "a": no such variable}
+
+test subst-5.1 {command substitutions} {
+ subst {[concat {}]}
+} {}
+test subst-5.2 {command substitutions} {
+ subst {[concat A test string]}
+} {A test string}
+test subst-5.3 {command substitutions} {
+ subst {x.[concat foo].y.[concat bar].z}
+} {x.foo.y.bar.z}
+test subst-5.4 {command substitutions} {
+ list [catch {subst {$long [set long] [bogus_command]}} msg] $msg
+} {1 {invalid command name "bogus_command"}}
+test subst-5.5 {command substitutions} {
+ set a 0
+ list [catch {subst {[set a 1}} msg] $a $msg
+} {1 0 {missing close-bracket}}
+test subst-5.6 {command substitutions} {
+ set a 0
+ list [catch {subst {0[set a 1}} msg] $a $msg
+} {1 0 {missing close-bracket}}
+test subst-5.7 {command substitutions} {
+ set a 0
+ list [catch {subst {0[set a 1; set a 2}} msg] $a $msg
+} {1 1 {missing close-bracket}}
+
+# repeat the tests above simulating cmd line input
+test subst-5.8 {command substitutions} {
+ set script {[subst {[set a 1}]}
+ list [catch {exec [info nameofexecutable] << $script} msg] $msg
+} {1 {missing close-bracket}}
+test subst-5.9 {command substitutions} {
+ set script {[subst {0[set a 1}]}
+ list [catch {exec [info nameofexecutable] << $script} msg] $msg
+} {1 {missing close-bracket}}
+test subst-5.10 {command substitutions} {
+ set script {[subst {0[set a 1; set a 2}]}
+ list [catch {exec [info nameofexecutable] << $script} msg] $msg
+} {1 {missing close-bracket}}
+
+test subst-6.1 {clear the result after command substitution} -body {
+ catch {unset a}
+ subst {[concat foo] $a}
+} -returnCodes error -result {can't read "a": no such variable}
+
+test subst-7.1 {switches} -returnCodes error -body {
+ subst foo bar
+} -result {bad switch "foo": must be -nobackslashes, -nocommands, or -novariables}
+test subst-7.2 {switches} -returnCodes error -body {
+ subst -no bar
+} -result {ambiguous switch "-no": must be -nobackslashes, -nocommands, or -novariables}
+test subst-7.3 {switches} -returnCodes error -body {
+ subst -bogus bar
+} -result {bad switch "-bogus": must be -nobackslashes, -nocommands, or -novariables}
+test subst-7.4 {switches} {
+ set x 123
+ subst -nobackslashes {abc $x [expr 1+2] \\\x41}
+} {abc 123 3 \\\x41}
+test subst-7.5 {switches} {
+ set x 123
+ subst -nocommands {abc $x [expr 1+2] \\\x41}
+} {abc 123 [expr 1+2] \A}
+test subst-7.6 {switches} {
+ set x 123
+ subst -novariables {abc $x [expr 1+2] \\\x41}
+} {abc $x 3 \A}
+test subst-7.7 {switches} {
+ set x 123
+ subst -nov -nob -noc {abc $x [expr 1+2] \\\x41}
+} {abc $x [expr 1+2] \\\x41}
+
+test subst-8.1 {return in a subst} {
+ subst {foo [return {x}; bogus code] bar}
+} {foo x bar}
+test subst-8.2 {return in a subst} {
+ subst {foo [return x ; bogus code] bar}
+} {foo x bar}
+test subst-8.3 {return in a subst} {
+ subst {foo [if 1 { return {x}; bogus code }] bar}
+} {foo x bar}
+test subst-8.4 {return in a subst} {
+ subst {[eval {return hi}] there}
+} {hi there}
+test subst-8.5 {return in a subst} {
+ subst {foo [return {]}; bogus code] bar}
+} {foo ] bar}
+test subst-8.6 {return in a subst} -returnCodes error -body {
+ subst "foo \[return {x}; bogus code bar"
+} -result {missing close-bracket}
+test subst-8.7 {return in a subst, parse error} -body {
+ subst {foo [return {x} ; set a {}"" ; stuff] bar}
+} -returnCodes error -result {extra characters after close-brace}
+test subst-8.8 {return in a subst, parse error} -body {
+ subst {foo [return {x} ; set bar baz ; set a {}"" ; stuff] bar}
+} -returnCodes error -result {extra characters after close-brace}
+test subst-8.9 {return in a variable subst} {
+ subst {foo $var([return {x}]) bar}
+} {foo x bar}
+
+test subst-9.1 {error in a subst} -body {
+ subst {[error foo; bogus code]bar}
+} -returnCodes error -result foo
+test subst-9.2 {error in a subst} -body {
+ subst {[if 1 { error foo; bogus code}]bar}
+} -returnCodes error -result foo
+test subst-9.3 {error in a variable subst} -setup {
+ catch {unset var}
+} -body {
+ subst {foo $var([error foo]) bar}
+} -returnCodes error -result foo
+
+test subst-10.1 {break in a subst} {
+ subst {foo [break; bogus code] bar}
+} {foo }
+test subst-10.2 {break in a subst} {
+ subst {foo [break; return x; bogus code] bar}
+} {foo }
+test subst-10.3 {break in a subst} {
+ subst {foo [if 1 { break; bogus code}] bar}
+} {foo }
+test subst-10.4 {break in a subst, parse error} {
+ subst {foo [break ; set a {}{} ; stuff] bar}
+} {foo }
+test subst-10.5 {break in a subst, parse error} {
+ subst {foo [break ;set bar baz ;set a {}{} ; stuff] bar}
+} {foo }
+test subst-10.6 {break in a variable subst} {
+ subst {foo $var([break]) bar}
+} {foo }
+
+test subst-11.1 {continue in a subst} {
+ subst {foo [continue; bogus code] bar}
+} {foo bar}
+test subst-11.2 {continue in a subst} {
+ subst {foo [continue; return x; bogus code] bar}
+} {foo bar}
+test subst-11.3 {continue in a subst} {
+ subst {foo [if 1 { continue; bogus code}] bar}
+} {foo bar}
+test subst-11.4 {continue in a subst, parse error} -body {
+ subst {foo [continue ; set a {}{} ; stuff] bar}
+} -returnCodes error -result {extra characters after close-brace}
+test subst-11.5 {continue in a subst, parse error} -body {
+ subst {foo [continue ;set bar baz ;set a {}{} ; stuff] bar}
+} -returnCodes error -result {extra characters after close-brace}
+test subst-11.6 {continue in a variable subst} {
+ subst {foo $var([continue]) bar}
+} {foo bar}
+
+test subst-12.1 {nasty case, Bug 1036649} {
+ for {set i 0} {$i < 10} {incr i} {
+ set res [list [catch {subst "\[subst {};"} msg] $msg]
+ if {$msg ne "missing close-bracket"} break
+ }
+ return $res
+} {1 {missing close-bracket}}
+test subst-12.2 {nasty case, Bug 1036649} {
+ for {set i 0} {$i < 10} {incr i} {
+ set res [list [catch {subst "\[subst {}; "} msg] $msg]
+ if {$msg ne "missing close-bracket"} break
+ }
+ return $res
+} {1 {missing close-bracket}}
+test subst-12.3 {nasty case, Bug 1036649} {
+ set x 0
+ for {set i 0} {$i < 10} {incr i} {
+ set res [list [catch {subst "\[incr x;"} msg] $msg]
+ if {$msg ne "missing close-bracket"} break
+ }
+ lappend res $x
+} {1 {missing close-bracket} 10}
+test subst-12.4 {nasty case, Bug 1036649} {
+ set x 0
+ for {set i 0} {$i < 10} {incr i} {
+ set res [list [catch {subst "\[incr x; "} msg] $msg]
+ if {$msg ne "missing close-bracket"} break
+ }
+ lappend res $x
+} {1 {missing close-bracket} 10}
+test subst-12.5 {nasty case, Bug 1036649} {
+ set x 0
+ for {set i 0} {$i < 10} {incr i} {
+ set res [list [catch {subst "\[incr x"} msg] $msg]
+ if {$msg ne "missing close-bracket"} break
+ }
+ lappend res $x
+} {1 {missing close-bracket} 0}
+test subst-12.6 {nasty case with compilation} {
+ set x unset
+ set y unset
+ list [eval [list subst {[set x 1;break;incr x][set y $x]}]] $x $y
+} {{} 1 unset}
+test subst-12.7 {nasty case with compilation} {
+ set x unset
+ set y unset
+ list [eval [list subst {[set x 1;continue;incr x][set y $x]}]] $x $y
+} {1 1 1}
+
+test subst-13.1 {Bug 3081065} -setup {
+ set script [makeFile {
+ proc demo {string} {
+ subst $string
+ }
+ demo name2
+ } subst13.tcl]
+} -body {
+ interp create slave
+ slave eval [list source $script]
+ interp delete slave
+ interp create slave
+ slave eval {
+ set count 400
+ while {[incr count -1]} {
+ lappend bloat [expr {rand()}]
+ }
+ }
+ slave eval [list source $script]
+ interp delete slave
+} -cleanup {
+ removeFile subst13.tcl
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/switch.test b/library/msgcat/tests/switch.test
new file mode 100644
index 0000000..a03948b
--- /dev/null
+++ b/library/msgcat/tests/switch.test
@@ -0,0 +1,772 @@
+# Commands covered: switch
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+test switch-1.1 {simple patterns} {
+ switch a a {subst 1} b {subst 2} c {subst 3} default {subst 4}
+} 1
+test switch-1.2 {simple patterns} {
+ switch b a {subst 1} b {subst 2} c {subst 3} default {subst 4}
+} 2
+test switch-1.3 {simple patterns} {
+ switch x a {subst 1} b {subst 2} c {subst 3} default {subst 4}
+} 4
+test switch-1.4 {simple patterns} {
+ switch x a {subst 1} b {subst 2} c {subst 3}
+} {}
+test switch-1.5 {simple pattern matches many times} {
+ switch b a {subst 1} b {subst 2} b {subst 3} b {subst 4}
+} 2
+test switch-1.6 {simple patterns} {
+ switch default a {subst 1} default {subst 2} c {subst 3} default {subst 4}
+} 2
+test switch-1.7 {simple patterns} {
+ switch x a {subst 1} default {subst 2} c {subst 3} default {subst 4}
+} 4
+test switch-1.8 {simple patterns with -nocase} {
+ switch -nocase b a {subst 1} b {subst 2} c {subst 3} default {subst 4}
+} 2
+test switch-1.9 {simple patterns with -nocase} {
+ switch -nocase B a {subst 1} b {subst 2} c {subst 3} default {subst 4}
+} 2
+test switch-1.10 {simple patterns with -nocase} {
+ switch -nocase b a {subst 1} B {subst 2} c {subst 3} default {subst 4}
+} 2
+test switch-1.11 {simple patterns with -nocase} {
+ switch -nocase x a {subst 1} default {subst 2} c {subst 3} default {subst 4}
+} 4
+
+test switch-2.1 {single-argument form for pattern/command pairs} {
+ switch b {
+ a {subst 1}
+ b {subst 2}
+ default {subst 6}
+ }
+} {2}
+test switch-2.2 {single-argument form for pattern/command pairs} -body {
+ switch z {a 2 b}
+} -returnCodes error -result {extra switch pattern with no body}
+
+test switch-3.1 {-exact vs. -glob vs. -regexp} {
+ switch -exact aaaab {
+ ^a*b$ {subst regexp}
+ *b {subst glob}
+ aaaab {subst exact}
+ default {subst none}
+ }
+} exact
+test switch-3.2 {-exact vs. -glob vs. -regexp} {
+ switch -regexp aaaab {
+ ^a*b$ {subst regexp}
+ *b {subst glob}
+ aaaab {subst exact}
+ default {subst none}
+ }
+} regexp
+test switch-3.3 {-exact vs. -glob vs. -regexp} {
+ switch -glob aaaab {
+ ^a*b$ {subst regexp}
+ *b {subst glob}
+ aaaab {subst exact}
+ default {subst none}
+ }
+} glob
+test switch-3.4 {-exact vs. -glob vs. -regexp} {
+ switch aaaab {^a*b$} {subst regexp} *b {subst glob} \
+ aaaab {subst exact} default {subst none}
+} exact
+test switch-3.5 {-exact vs. -glob vs. -regexp} {
+ switch -- -glob {
+ ^g.*b$ {subst regexp}
+ -* {subst glob}
+ -glob {subst exact}
+ default {subst none}
+ }
+} exact
+test switch-3.6 {-exact vs. -glob vs. -regexp} -body {
+ switch -foo a b c
+} -returnCodes error -result {bad option "-foo": must be -exact, -glob, -indexvar, -matchvar, -nocase, -regexp, or --}
+test switch-3.7 {-exact vs. -glob vs. -regexp with -nocase} {
+ switch -exact -nocase aaaab {
+ ^a*b$ {subst regexp}
+ *b {subst glob}
+ aaaab {subst exact}
+ default {subst none}
+ }
+} exact
+test switch-3.8 {-exact vs. -glob vs. -regexp with -nocase} {
+ switch -regexp -nocase aaaab {
+ ^a*b$ {subst regexp}
+ *b {subst glob}
+ aaaab {subst exact}
+ default {subst none}
+ }
+} regexp
+test switch-3.9 {-exact vs. -glob vs. -regexp with -nocase} {
+ switch -glob -nocase aaaab {
+ ^a*b$ {subst regexp}
+ *b {subst glob}
+ aaaab {subst exact}
+ default {subst none}
+ }
+} glob
+test switch-3.10 {-exact vs. -glob vs. -regexp with -nocase} {
+ switch -nocase aaaab {^a*b$} {subst regexp} *b {subst glob} \
+ aaaab {subst exact} default {subst none}
+} exact
+test switch-3.11 {-exact vs. -glob vs. -regexp with -nocase} {
+ switch -nocase -- -glob {
+ ^g.*b$ {subst regexp}
+ -* {subst glob}
+ -glob {subst exact}
+ default {subst none}
+ }
+} exact
+test switch-3.12 {-exact vs. -glob vs. -regexp} {
+ switch -exa Foo Foo {set result OK}
+} OK
+test switch-3.13 {-exact vs. -glob vs. -regexp} {
+ switch -gl Foo Fo? {set result OK}
+} OK
+test switch-3.14 {-exact vs. -glob vs. -regexp} {
+ switch -re Foo Fo. {set result OK}
+} OK
+test switch-3.15 {-exact vs. -glob vs. -regexp} -body {
+ switch -exact -exact Foo Foo {set result OK}
+} -returnCodes error -result {bad option "-exact": -exact option already found}
+test switch-3.16 {-exact vs. -glob vs. -regexp} -body {
+ switch -exact -glob Foo Foo {set result OK}
+} -returnCodes error -result {bad option "-glob": -exact option already found}
+test switch-3.17 {-exact vs. -glob vs. -regexp} -body {
+ switch -glob -regexp Foo Foo {set result OK}
+} -returnCodes error -result {bad option "-regexp": -glob option already found}
+test switch-3.18 {-exact vs. -glob vs. -regexp} -body {
+ switch -regexp -glob Foo Foo {set result OK}
+} -returnCodes error -result {bad option "-glob": -regexp option already found}
+
+test switch-4.1 {error in executed command} {
+ list [catch {switch a a {error "Just a test"} default {subst 1}} msg] \
+ $msg $::errorInfo
+} {1 {Just a test} {Just a test
+ while executing
+"error "Just a test""
+ ("a" arm line 1)
+ invoked from within
+"switch a a {error "Just a test"} default {subst 1}"}}
+test switch-4.2 {error: not enough args} -returnCodes error -body {
+ switch
+} -result {wrong # args: should be "switch ?-switch ...? string ?pattern body ...? ?default body?"}
+test switch-4.3 {error: pattern with no body} -body {
+ switch a b
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-4.4 {error: pattern with no body} -body {
+ switch a b {subst 1} c
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-4.5 {error in default command} {
+ list [catch {switch foo a {error switch1} b {error switch 3} \
+ default {error switch2}} msg] $msg $::errorInfo
+} {1 switch2 {switch2
+ while executing
+"error switch2"
+ ("default" arm line 1)
+ invoked from within
+"switch foo a {error switch1} b {error switch 3} default {error switch2}"}}
+
+test switch-5.1 {errors in -regexp matching} -returnCodes error -body {
+ switch -regexp aaaab {
+ *b {subst glob}
+ aaaab {subst exact}
+ default {subst none}
+ }
+} -result {couldn't compile regular expression pattern: quantifier operand invalid}
+
+test switch-6.1 {backslashes in patterns} {
+ switch -exact {\a\$\.\[} {
+ \a\$\.\[ {subst first}
+ \a\\$\.\\[ {subst second}
+ \\a\\$\\.\\[ {subst third}
+ {\a\\$\.\\[} {subst fourth}
+ {\\a\\$\\.\\[} {subst fifth}
+ default {subst none}
+ }
+} third
+test switch-6.2 {backslashes in patterns} {
+ switch -exact {\a\$\.\[} {
+ \a\$\.\[ {subst first}
+ {\a\$\.\[} {subst second}
+ {{\a\$\.\[}} {subst third}
+ default {subst none}
+ }
+} second
+
+test switch-7.1 {"-" bodies} {
+ switch a {
+ a -
+ b -
+ c {subst 1}
+ default {subst 2}
+ }
+} 1
+test switch-7.2 {"-" bodies} -body {
+ switch a {
+ a -
+ b -
+ c -
+ }
+} -returnCodes error -result {no body specified for pattern "c"}
+test switch-7.3 {"-" bodies} -body {
+ switch a {
+ a -
+ b -foo
+ c -
+ }
+} -returnCodes error -result {no body specified for pattern "c"}
+test switch-7.4 {"-" bodies} -body {
+ switch a {
+ a -
+ b -foo
+ c {}
+ }
+} -returnCodes error -result {invalid command name "-foo"}
+
+test switch-8.1 {empty body} {
+ set msg {}
+ switch {2} {
+ 1 {set msg 1}
+ 2 {}
+ default {set msg 2}
+ }
+} {}
+proc test_switch_body {} {
+ return "INVOKED"
+}
+test switch-8.2 {weird body text, variable} {
+ set cmd {test_switch_body}
+ switch Foo {
+ Foo $cmd
+ }
+} {INVOKED}
+test switch-8.3 {weird body text, variable} {
+ set cmd {test_switch_body}
+ switch Foo {
+ Foo {$cmd}
+ }
+} {INVOKED}
+
+test switch-9.1 {empty pattern/body list} -returnCodes error -body {
+ switch x
+} -result {wrong # args: should be "switch ?-switch ...? string ?pattern body ...? ?default body?"}
+test switch-9.2 {unpaired pattern} -returnCodes error -body {
+ switch -- x
+} -result {extra switch pattern with no body}
+test switch-9.3 {empty pattern/body list} -body {
+ switch x {}
+} -returnCodes error -result {wrong # args: should be "switch ?-switch ...? string {?pattern body ...? ?default body?}"}
+test switch-9.4 {empty pattern/body list} -body {
+ switch -- x {}
+} -returnCodes error -result {wrong # args: should be "switch ?-switch ...? string {?pattern body ...? ?default body?}"}
+test switch-9.5 {unpaired pattern} -body {
+ switch x a {} b
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-9.6 {unpaired pattern} -body {
+ switch x {a {} b}
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-9.7 {unpaired pattern} -body {
+ switch x a {} # comment b
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-9.8 {unpaired pattern} -returnCodes error -body {
+ switch x {a {} # comment b}
+} -result {extra switch pattern with no body, this may be due to a comment incorrectly placed outside of a switch body - see the "switch" documentation}
+test switch-9.9 {unpaired pattern} -body {
+ switch x a {} x {} # comment b
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-9.10 {unpaired pattern} -returnCodes error -body {
+ switch x {a {} x {} # comment b}
+} -result {extra switch pattern with no body, this may be due to a comment incorrectly placed outside of a switch body - see the "switch" documentation}
+
+test switch-10.1 {compiled -exact switch} {
+ if 1 {switch -exact -- a {a {subst 1} b {subst 2}}}
+} 1
+test switch-10.1a {compiled -exact switch} {
+ if 1 {switch -exact a {a {subst 1} b {subst 2}}}
+} 1
+test switch-10.2 {compiled -exact switch} {
+ if 1 {switch -exact -- b {a {subst 1} b {subst 2}}}
+} 2
+test switch-10.2a {compiled -exact switch} {
+ if 1 {switch -exact b {a {subst 1} b {subst 2}}}
+} 2
+test switch-10.3 {compiled -exact switch} {
+ if 1 {switch -exact -- c {a {subst 1} b {subst 2}}}
+} {}
+test switch-10.3a {compiled -exact switch} {
+ if 1 {switch -exact c {a {subst 1} b {subst 2}}}
+} {}
+test switch-10.4 {compiled -exact switch} {
+ if 1 {
+ set x 0
+ switch -exact -- c {a {subst 1} b {subst 2}}
+ }
+} {}
+test switch-10.5 {compiled -exact switch} {
+ if 1 {switch -exact -- a {a - aa {subst 1} b {subst 2}}}
+} 1
+test switch-10.6 {compiled -exact switch} {
+ if 1 {switch -exact -- b {a {
+ set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+ set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+ set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+ set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+ set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+ set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+ set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+ set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+ } b {subst 2}}}
+} 2
+
+# Command variants are:
+# c* are compiled switches, i* are interpreted
+# *-glob use glob matching, *-exact use exact matching
+# *2* include a default clause (different results too.)
+proc cswtest-glob s {
+ set x 0; set y 0
+ foreach c [split $s {}] {
+ switch -glob $c {
+ a {incr x}
+ b {incr y}
+ }
+ }
+ set x [expr {$x*100}]; set y [expr {$y*100}]
+ foreach c [split $s {}] {
+ switch -glob -- $c a {incr x} b {incr y}
+ }
+ return $x,$y
+}
+proc iswtest-glob s {
+ set x 0; set y 0; set switch switch
+ foreach c [split $s {}] {
+ $switch -glob $c {
+ a {incr x}
+ b {incr y}
+ }
+ }
+ set x [expr {$x*100}]; set y [expr {$y*100}]
+ foreach c [split $s {}] {
+ $switch -glob -- $c a {incr x} b {incr y}
+ }
+ return $x,$y
+}
+proc cswtest-exact s {
+ set x 0; set y 0
+ foreach c [split $s {}] {
+ switch -exact $c {
+ a {incr x}
+ b {incr y}
+ }
+ }
+ set x [expr {$x*100}]; set y [expr {$y*100}]
+ foreach c [split $s {}] {
+ switch -exact -- $c a {incr x} b {incr y}
+ }
+ return $x,$y
+}
+proc iswtest-exact s {
+ set x 0; set y 0; set switch switch
+ foreach c [split $s {}] {
+ $switch -exact $c {
+ a {incr x}
+ b {incr y}
+ }
+ }
+ set x [expr {$x*100}]; set y [expr {$y*100}]
+ foreach c [split $s {}] {
+ $switch -exact -- $c a {incr x} b {incr y}
+ }
+ return $x,$y
+}
+proc cswtest2-glob s {
+ set x 0; set y 0; set z 0
+ foreach c [split $s {}] {
+ switch -glob $c {
+ a {incr x}
+ b {incr y}
+ default {incr z}
+ }
+ }
+ set x [expr {$x*100}]; set y [expr {$y*100}]; set z [expr {$z*100}]
+ foreach c [split $s {}] {
+ switch -glob -- $c a {incr x} b {incr y} default {incr z}
+ }
+ return $x,$y,$z
+}
+proc iswtest2-glob s {
+ set x 0; set y 0; set z 0; set switch switch
+ foreach c [split $s {}] {
+ $switch -glob $c {
+ a {incr x}
+ b {incr y}
+ default {incr z}
+ }
+ }
+ set x [expr {$x*100}]; set y [expr {$y*100}]; set z [expr {$z*100}]
+ foreach c [split $s {}] {
+ $switch -glob -- $c a {incr x} b {incr y} default {incr z}
+ }
+ return $x,$y,$z
+}
+proc cswtest2-exact s {
+ set x 0; set y 0; set z 0
+ foreach c [split $s {}] {
+ switch -exact $c {
+ a {incr x}
+ b {incr y}
+ default {incr z}
+ }
+ }
+ set x [expr {$x*100}]; set y [expr {$y*100}]; set z [expr {$z*100}]
+ foreach c [split $s {}] {
+ switch -exact -- $c a {incr x} b {incr y} default {incr z}
+ }
+ return $x,$y,$z
+}
+proc iswtest2-exact s {
+ set x 0; set y 0; set z 0; set switch switch
+ foreach c [split $s {}] {
+ $switch -exact $c {
+ a {incr x}
+ b {incr y}
+ default {incr z}
+ }
+ }
+ set x [expr {$x*100}]; set y [expr {$y*100}]; set z [expr {$z*100}]
+ foreach c [split $s {}] {
+ $switch -exact -- $c a {incr x} b {incr y} default {incr z}
+ }
+ return $x,$y,$z
+}
+
+test switch-10.7 {comparison of compiled and interpreted behaviour of switch, exact matching} {
+ cswtest-exact abcb
+} [iswtest-exact abcb]
+test switch-10.8 {comparison of compiled and interpreted behaviour of switch, glob matching} {
+ cswtest-glob abcb
+} [iswtest-glob abcb]
+test switch-10.9 {comparison of compiled and interpreted behaviour of switch, exact matching with default} {
+ cswtest2-exact abcb
+} [iswtest2-exact abcb]
+test switch-10.10 {comparison of compiled and interpreted behaviour of switch, glob matching with default} {
+ cswtest2-glob abcb
+} [iswtest2-glob abcb]
+proc cswtest-default-exact {x} {
+ switch -- $x {
+ a* {return b}
+ aa {return c}
+ default {return d}
+ }
+}
+test switch-10.11 {default to exact matching when compiled} {
+ cswtest-default-exact a
+} d
+test switch-10.12 {default to exact matching when compiled} {
+ cswtest-default-exact aa
+} c
+test switch-10.13 {default to exact matching when compiled} {
+ cswtest-default-exact a*
+} b
+test switch-10.14 {default to exact matching when compiled} {
+ cswtest-default-exact a**
+} d
+rename cswtest-default-exact {}
+rename cswtest-glob {}
+rename iswtest-glob {}
+rename cswtest2-glob {}
+rename iswtest2-glob {}
+rename cswtest-exact {}
+rename iswtest-exact {}
+rename cswtest2-exact {}
+rename iswtest2-exact {}
+# Bug 1891827
+test switch-10.15 {(not) compiled exact nocase regression} {
+ apply {{} {
+ switch -nocase -- A { a {return yes} default {return no} }
+ }}
+} yes
+
+# Added due to TIP#75
+test switch-11.1 {regexp matching with -matchvar} {
+ switch -regexp -matchvar x -- abc {.(.). {set x}}
+} {abc b}
+test switch-11.2 {regexp matching with -matchvar} {
+ set x GOOD
+ switch -regexp -matchvar x -- abc {.(.).. {list $x z}}
+ set x
+} GOOD
+test switch-11.3 {regexp matching with -matchvar} {
+ switch -regexp -matchvar x -- "a b c" {.(.). {set x}}
+} {{a b} { }}
+test switch-11.4 {regexp matching with -matchvar} {
+ set x BAD
+ switch -regexp -matchvar x -- "a b c" {
+ bc {list $x YES}
+ default {list $x NO}
+ }
+} {{} NO}
+test switch-11.5 {-matchvar without -regexp} {
+ set x {}
+ list [catch {switch -glob -matchvar x -- abc . {set x}} msg] $x $msg
+} {1 {} {-matchvar option requires -regexp option}}
+test switch-11.6 {-matchvar unwritable} {
+ set x {}
+ list [catch {switch -regexp -matchvar x(x) -- abc . {set x}} msg] $x $msg
+} {1 {} {can't set "x(x)": variable isn't array}}
+
+test switch-12.1 {regexp matching with -indexvar} {
+ switch -regexp -indexvar x -- abc {.(.). {set x}}
+} {{0 2} {1 1}}
+test switch-12.2 {regexp matching with -indexvar} {
+ set x GOOD
+ switch -regexp -indexvar x -- abc {.(.).. {list $x z}}
+ set x
+} GOOD
+test switch-12.3 {regexp matching with -indexvar} {
+ switch -regexp -indexvar x -- "a b c" {.(.). {set x}}
+} {{0 2} {1 1}}
+test switch-12.4 {regexp matching with -indexvar} {
+ set x BAD
+ switch -regexp -indexvar x -- "a b c" {
+ bc {list $x YES}
+ default {list $x NO}
+ }
+} {{} NO}
+test switch-12.5 {-indexvar without -regexp} {
+ set x {}
+ list [catch {switch -glob -indexvar x -- abc . {set x}} msg] $x $msg
+} {1 {} {-indexvar option requires -regexp option}}
+test switch-12.6 {-indexvar unwritable} {
+ set x {}
+ list [catch {switch -regexp -indexvar x(x) -- abc . {set x}} msg] $x $msg
+} {1 {} {can't set "x(x)": variable isn't array}}
+test switch-12.7 {[Bug 3106532] -indexvar should be directly usable with [string range]} {
+ set str abcdef
+ switch -regexp -indexvar x -- $str ^... {string range $str {*}[lindex $x 0]}
+} abc
+test switch-12.8 {-indexvar and matched empty strings} {
+ switch -regexp -indexvar x -- abcdef ^...(x?) {return $x}
+} {{0 2} {3 2}}
+test switch-12.9 {-indexvar and unmatched strings} {
+ switch -regexp -indexvar x -- abcdef ^...(x)? {return $x}
+} {{0 2} {-1 -1}}
+
+test switch-13.1 {-indexvar -matchvar combinations} {
+ switch -regexp -indexvar x -matchvar y abc {
+ . {list $x $y}
+ }
+} {{{0 0}} a}
+test switch-13.2 {-indexvar -matchvar combinations} {
+ switch -regexp -indexvar x -matchvar y abc {
+ .$ {list $x $y}
+ }
+} {{{2 2}} c}
+test switch-13.3 {-indexvar -matchvar combinations} {
+ switch -regexp -indexvar x -matchvar y abc {
+ (.)(.)(.) {list $x $y}
+ }
+} {{{0 2} {0 0} {1 1} {2 2}} {abc a b c}}
+test switch-13.4 {-indexvar -matchvar combinations} {
+ set x -
+ set y -
+ switch -regexp -indexvar x -matchvar y abc {
+ (.)(.)(.). -
+ default {list $x $y}
+ }
+} {{} {}}
+test switch-13.5 {-indexvar -matchvar combinations} {
+ set x -
+ set y -
+ list [catch {
+ switch -regexp -indexvar x(x) -matchvar y abc {. {list $x $y}}
+ } msg] $x $y $msg
+} {1 - - {can't set "x(x)": variable isn't array}}
+test switch-13.6 {-indexvar -matchvar combinations} {
+ set x -
+ set y -
+ list [catch {
+ switch -regexp -indexvar x -matchvar y(y) abc {. {list $x $y}}
+ } msg] $x $y $msg
+} {1 {{0 0}} - {can't set "y(y)": variable isn't array}}
+
+test switch-14.1 {-regexp -- compilation [Bug 1854399]} {
+ switch -regexp -- 0 {
+ {[0-9]+} {return yes}
+ default {return no}
+ }
+ foo
+} yes
+test switch-14.2 {-regexp -- compilation [Bug 1854399]} {
+ proc foo {} {
+ switch -regexp -- 0 {
+ {[0-9]+} {return yes}
+ default {return no}
+ }
+ }
+ foo
+} yes
+test switch-14.3 {-regexp -- compilation [Bug 1854399]} {
+ proc foo {} {
+ switch -regexp -- 0 {
+ {\d+} {return yes}
+ default {return no}
+ }
+ }
+ foo
+} yes
+test switch-14.4 {-regexp -- compilation [Bug 1854399]} {
+ proc foo {} {
+ switch -regexp -- 0 {
+ {0} {return yes}
+ default {return no}
+ }
+ }
+ foo
+} yes
+test switch-14.5 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- 0 {
+ {0|1|2} {return yes}
+ default {return no}
+ }
+ }}
+} yes
+test switch-14.6 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- 0 {
+ {0|11|222} {return yes}
+ default {return no}
+ }
+ }}
+} yes
+test switch-14.7 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- 0 {
+ {[012]} {return yes}
+ default {return no}
+ }
+ }}
+} yes
+test switch-14.8 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- x {
+ {0|1|2} {return yes}
+ default {return no}
+ }
+ }}
+} no
+test switch-14.9 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- x {
+ {0|11|222} {return yes}
+ default {return no}
+ }
+ }}
+} no
+test switch-14.10 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- x {
+ {[012]} {return yes}
+ default {return no}
+ }
+ }}
+} no
+test switch-14.11 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- x {
+ {0|1|2} {return yes}
+ .+ {return yes2}
+ default {return no}
+ }
+ }}
+} yes2
+test switch-14.12 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- x {
+ {0|11|222} {return yes}
+ .+ {return yes2}
+ default {return no}
+ }
+ }}
+} yes2
+test switch-14.13 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- x {
+ {[012]} {return yes}
+ .+ {return yes2}
+ default {return no}
+ }
+ }}
+} yes2
+test switch-14.14 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- {} {
+ {0|1|2} {return yes}
+ .+ {return yes2}
+ default {return no}
+ }
+ }}
+} no
+test switch-14.15 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- {} {
+ {0|11|222} {return yes}
+ .+ {return yes2}
+ default {return no}
+ }
+ }}
+} no
+test switch-14.16 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- {} {
+ {[012]} {return yes}
+ .+ {return yes2}
+ default {return no}
+ }
+ }}
+} no
+
+test switch-15.1 {coroutine safety of non-bytecoded switch} {*}{
+ -body {
+ proc coro {} {
+ switch -glob a {
+ a {yield ok1}
+ }
+ return ok2
+ }
+ list [coroutine c coro] [c]
+ }
+ -result {ok1 ok2}
+ -cleanup {
+ rename coro {}
+ }
+}
+
+# cleanup
+catch {rename foo {}}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/tailcall.test b/library/msgcat/tests/tailcall.test
new file mode 100644
index 0000000..e9ec188
--- /dev/null
+++ b/library/msgcat/tests/tailcall.test
@@ -0,0 +1,663 @@
+# Commands covered: tailcall
+#
+# This file contains a collection of tests for experimental commands that are
+# found in ::tcl::unsupported. The tests will migrate to normal test files
+# if/when the commands find their way into the core.
+#
+# Copyright (c) 2008 by Miguel Sofer.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testnrelevels [llength [info commands testnrelevels]]
+
+#
+# The tests that risked blowing the C stack on failure have been removed: we
+# can now actually measure using testnrelevels.
+#
+
+if {[testConstraint testnrelevels]} {
+ namespace eval testnre {
+ #
+ # [testnrelevels] returns a 6-list with: C-stack depth, iPtr->numlevels,
+ # cmdFrame level, callFrame level, tosPtr and callback depth
+ #
+ variable last [testnrelevels]
+ proc depthDiff {} {
+ variable last
+ set depth [testnrelevels]
+ set res {}
+ foreach t $depth l $last {
+ lappend res [expr {$t-$l}]
+ }
+ set last $depth
+ return $res
+ }
+ namespace export *
+ }
+ namespace import testnre::*
+}
+
+proc errorcode options {
+ dict get [dict merge {-errorcode NONE} $options] -errorcode
+}
+
+test tailcall-0.1 {tailcall is constant space} -constraints testnrelevels -setup {
+ proc a i {
+ #
+ # NOTE: there may be a diff in callback depth with the first call
+ # ($i==0) due to the fact that the first is from an eval. Successive
+ # calls should add nothing to any stack depths.
+ #
+ if {$i == 1} {
+ depthDiff
+ }
+ if {[incr i] > 10} {
+ return [depthDiff]
+ }
+ tailcall a $i
+ }
+} -body {
+ a 0
+} -cleanup {
+ rename a {}
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.2 {tailcall is constant space} -constraints testnrelevels -setup {
+ set a { i {
+ if {$i == 1} {
+ depthDiff
+ }
+ if {[incr i] > 10} {
+ return [depthDiff]
+ }
+ upvar 1 a a
+ tailcall apply $a $i
+ }}
+} -body {
+ apply $a 0
+} -cleanup {
+ unset a
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.3 {tailcall is constant space} -constraints testnrelevels -setup {
+ proc a i {
+ if {$i == 1} {
+ depthDiff
+ }
+ if {[incr i] > 10} {
+ return [depthDiff]
+ }
+ tailcall b $i
+ }
+ interp alias {} b {} a
+} -body {
+ b 0
+} -cleanup {
+ rename a {}
+ rename b {}
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.4 {tailcall is constant space} -constraints testnrelevels -setup {
+ namespace eval ::ns {
+ namespace export *
+ }
+ proc ::ns::a i {
+ if {$i == 1} {
+ depthDiff
+ }
+ if {[incr i] > 10} {
+ return [depthDiff]
+ }
+ set b [uplevel 1 [list namespace which b]]
+ tailcall $b $i
+ }
+ namespace import ::ns::a
+ rename a b
+} -body {
+ b 0
+} -cleanup {
+ rename b {}
+ namespace delete ::ns
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.5 {tailcall is constant space} -constraints testnrelevels -setup {
+ proc b i {
+ if {$i == 1} {
+ depthDiff
+ }
+ if {[incr i] > 10} {
+ return [depthDiff]
+ }
+ tailcall a b $i
+ }
+ namespace ensemble create -command a -map {b b}
+} -body {
+ a b 0
+} -cleanup {
+ rename a {}
+ rename b {}
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.6 {tailcall is constant space} -constraints {testnrelevels knownBug} -setup {
+ #
+ # This test fails because ns-unknown is not NR-enabled
+ #
+ proc c i {
+ if {$i == 1} {
+ depthDiff
+ }
+ if {[incr i] > 10} {
+ return [depthDiff]
+ }
+ tailcall a b $i
+ }
+ proc d {ens sub args} {
+ return [list $ens c]
+ }
+ namespace ensemble create -command a -unknown d
+} -body {
+ a b 0
+} -cleanup {
+ rename a {}
+ rename c {}
+ rename d {}
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.7 {tailcall is constant space} -constraints testnrelevels -setup {
+ catch {rename foo {}}
+ oo::class create foo {
+ method b i {
+ if {$i == 1} {
+ depthDiff
+ }
+ if {[incr i] > 10} {
+ return [depthDiff]
+ }
+ tailcall [self] b $i
+ }
+ }
+} -body {
+ foo create a
+ a b 0
+} -cleanup {
+ rename a {}
+ rename foo {}
+} -result {0 0 0 0 0 0}
+
+test tailcall-1 {tailcall} -body {
+ namespace eval a {
+ variable x *::a
+ proc xset {} {
+ set tmp {}
+ set ns {[namespace current]}
+ set level [info level]
+ for {set i 0} {$i <= [info level]} {incr i} {
+ uplevel #$i "set x $i$ns"
+ lappend tmp "$i [info level $i]"
+ }
+ lrange $tmp 1 end
+ }
+ proc foo {} {tailcall xset; set x noreach}
+ }
+ namespace eval b {
+ variable x *::b
+ proc xset args {error b::xset}
+ proc moo {} {set x 0; variable y [::a::foo]; set x}
+ }
+ variable x *::
+ proc xset args {error ::xset}
+ list [::b::moo] | $x $a::x $b::x | $::b::y
+} -cleanup {
+ unset x
+ rename xset {}
+ namespace delete a b
+} -result {1::b | 0:: *::a *::b | {{1 ::b::moo} {2 xset}}}
+
+
+test tailcall-2 {tailcall in non-proc} -body {
+ namespace eval a [list tailcall set x 1]
+} -match glob -result *tailcall* -returnCodes error
+
+test tailcall-3 {tailcall falls off tebc} -body {
+ unset -nocomplain x
+ proc foo {} {tailcall set x 1}
+ list [catch foo msg] $msg [set x]
+} -cleanup {
+ rename foo {}
+ unset x
+} -result {0 1 1}
+
+test tailcall-4 {tailcall falls off tebc} -body {
+ set x 2
+ proc foo {} {tailcall set x 1}
+ foo
+ set x
+} -cleanup {
+ rename foo {}
+ unset x
+} -result 1
+
+test tailcall-5 {tailcall falls off tebc} -body {
+ set x 2
+ namespace eval bar {
+ variable x 3
+ proc foo {} {tailcall set x 1}
+ }
+ bar::foo
+ list $x $bar::x
+} -cleanup {
+ unset x
+ namespace delete bar
+} -result {1 3}
+
+test tailcall-6 {tailcall does remove callframes} -body {
+ proc foo {} {info level}
+ proc moo {} {tailcall foo}
+ proc boo {} {expr {[moo] - [info level]}}
+ boo
+} -cleanup {
+ rename foo {}
+ rename moo {}
+ rename boo {}
+} -result 1
+
+test tailcall-7 {tailcall does return} -setup {
+ namespace eval ::foo {
+ variable res {}
+ proc a {} {
+ variable res
+ append res a
+ tailcall set x 1
+ append res a
+ }
+ proc b {} {
+ variable res
+ append res b
+ a
+ append res b
+ }
+ proc c {} {
+ variable res
+ append res c
+ b
+ append res c
+ }
+ }
+} -body {
+ namespace eval ::foo c
+} -cleanup {
+ namespace delete ::foo
+} -result cbabc
+
+test tailcall-8 {tailcall tailcall} -setup {
+ namespace eval ::foo {
+ variable res {}
+ proc a {} {
+ variable res
+ append res a
+ tailcall tailcall set x 1
+ append res a
+ }
+ proc b {} {
+ variable res
+ append res b
+ a
+ append res b
+ }
+ proc c {} {
+ variable res
+ append res c
+ b
+ append res c
+ }
+ }
+} -body {
+ namespace eval ::foo c
+} -cleanup {
+ namespace delete ::foo
+} -result cbac
+
+test tailcall-9 {tailcall factorial} -setup {
+ proc fact {n {b 1}} {
+ if {$n == 1} {
+ return $b
+ }
+ tailcall fact [expr {$n-1}] [expr {$n*$b}]
+ }
+} -body {
+ list [fact 1] [fact 5] [fact 10] [fact 15]
+} -cleanup {
+ rename fact {}
+} -result {1 120 3628800 1307674368000}
+
+test tailcall-10a {tailcall and eval} -setup {
+ set ::x 0
+ proc a {} {
+ eval [list tailcall lappend ::x 2]
+ set ::x 1
+ }
+} -body {
+ list [a] $::x
+} -cleanup {
+ unset -nocomplain ::x
+} -result {{0 2} {0 2}}
+
+test tailcall-10b {tailcall and eval} -setup {
+ set ::x 0
+ proc a {} {
+ eval {tailcall lappend ::x 2}
+ set ::x 1
+ }
+} -body {
+ list [a] $::x
+} -cleanup {
+ unset -nocomplain ::x
+} -result {{0 2} {0 2}}
+
+test tailcall-11a {tailcall and uplevel} -setup {
+ proc a {} {
+ uplevel 1 [list tailcall set ::x 2]
+ set ::x 1
+ }
+} -body {
+ list [a] $::x
+} -cleanup {
+ unset -nocomplain ::x
+} -match glob -result *tailcall* -returnCodes error
+
+test tailcall-11b {tailcall and uplevel} -setup {
+ proc a {} {
+ uplevel 1 {tailcall set ::x 2}
+ set ::x 1
+ }
+} -body {
+ list [a] $::x
+} -cleanup {
+ unset -nocomplain ::x
+} -match glob -result *tailcall* -returnCodes error
+
+test tailcall-11c {tailcall and uplevel} -setup {
+ proc a {} {
+ uplevel 1 {tailcall lappend ::x 2}
+ set ::x 1
+ }
+ proc b {} {set ::x 0; a; lappend ::x 3}
+} -body {
+ list [b] $::x
+} -cleanup {
+ rename a {}
+ rename b {}
+ unset -nocomplain ::x
+} -result {{0 3 2} {0 3 2}}
+
+test tailcall-12.1 {[Bug 2649975]} -setup {
+ proc dump {{text {}}} {
+ set text [uplevel 1 [list subst $text]]
+ set l [expr {[info level] -1}]
+ if {$text eq {}} {
+ set text [info level $l]
+ }
+ puts "$l: $text"
+ }
+ # proc dump args {}
+ proc bravo {} {
+ upvar 1 v w
+ dump {inside bravo, v -> $w}
+ set v "procedure bravo"
+ #uplevel 1 [list delta ::betty]
+ uplevel 1 {delta ::betty}
+ return $::resolution
+ }
+ proc delta name {
+ upvar 1 v w
+ dump {inside delta, v -> $w}
+ set v "procedure delta"
+ tailcall foxtrot
+ }
+ proc foxtrot {} {
+ upvar 1 v w
+ dump {inside foxtrot, v -> $w}
+ global resolution
+ set ::resolution $w
+ }
+ set v "global level"
+} -body {
+ set result [bravo]
+ if {$result ne $v} {
+ puts "v should have been found at $v but was found in $result"
+ }
+} -cleanup {
+ unset v
+ rename dump {}
+ rename bravo {}
+ rename delta {}
+ rename foxtrot {}
+} -output {1: inside bravo, v -> global level
+1: inside delta, v -> global level
+1: inside foxtrot, v -> global level
+}
+
+test tailcall-12.2 {[Bug 2649975]} -setup {
+ proc dump {{text {}}} {
+ set text [uplevel 1 [list subst $text]]
+ set l [expr {[info level] -1}]
+ if {$text eq {}} {
+ set text [info level $l]
+ }
+ puts "$l: $text"
+ }
+ # proc dump args {}
+ set v "global level"
+ oo::class create foo { # like connection
+ method alpha {} { # like connections 'tables' method
+ dump
+ upvar 1 v w
+ dump {inside foo's alpha, v resolves to $w}
+ set v "foo's method alpha"
+ dump {foo's alpha is calling [self] bravo - v should resolve at global level}
+ set result [uplevel 1 [list [self] bravo]]
+ dump {exiting from foo's alpha}
+ return $result
+ }
+ method bravo {} { # like connections 'foreach' method
+ dump
+ upvar 1 v w
+ dump {inside foo's bravo, v resolves to $w}
+ set v "foo's method bravo"
+ dump {foo's bravo is calling charlie to create barney}
+ set barney [my charlie ::barney]
+ dump {foo's bravo is calling bravo on $barney}
+ dump {v should resolve at global scope there}
+ set result [uplevel 1 [list $barney bravo]]
+ dump {exiting from foo's bravo}
+ return $result
+ }
+ method charlie {name} { # like tdbc prepare
+ dump
+ set v "foo's method charlie"
+ dump {tailcalling bar's constructor}
+ tailcall ::bar create $name
+ }
+ }
+ oo::class create bar { # like statement
+ method bravo {} { # like statement foreach method
+ dump
+ upvar 1 v w
+ dump {inside bar's bravo, v is resolving to $w}
+ set v "bar's method bravo"
+ dump {calling delta to construct betty - v should resolve global there}
+ uplevel 1 [list [self] delta ::betty]
+ dump {exiting from bar's bravo}
+ return [::betty whathappened]
+ }
+ method delta {name} { # like statement execute method
+ dump
+ upvar 1 v w
+ dump {inside bar's delta, v is resolving to $w}
+ set v "bar's method delta"
+ dump {tailcalling to construct $name as instance of grill}
+ dump {v should resolve at global level in grill's constructor}
+ dump {grill's constructor should run at level [info level]}
+ tailcall grill create $name
+ }
+ }
+ oo::class create grill {
+ variable resolution
+ constructor {} {
+ dump
+ upvar 1 v w
+ dump "in grill's constructor, v resolves to $w"
+ set resolution $w
+ }
+ method whathappened {} {
+ return $resolution
+ }
+ }
+ foo create fred
+} -body {
+ set result [fred alpha]
+ if {$result ne "global level"} {
+ puts "v should have been found at global level but was found in $result"
+ }
+} -cleanup {
+ unset result
+ rename fred {}
+ rename dump {}
+ rename foo {}
+ rename bar {}
+ rename grill {}
+} -output {1: fred alpha
+1: inside foo's alpha, v resolves to global level
+1: foo's alpha is calling ::fred bravo - v should resolve at global level
+1: ::fred bravo
+1: inside foo's bravo, v resolves to global level
+1: foo's bravo is calling charlie to create barney
+2: my charlie ::barney
+2: tailcalling bar's constructor
+1: foo's bravo is calling bravo on ::barney
+1: v should resolve at global scope there
+1: ::barney bravo
+1: inside bar's bravo, v is resolving to global level
+1: calling delta to construct betty - v should resolve global there
+1: ::barney delta ::betty
+1: inside bar's delta, v is resolving to global level
+1: tailcalling to construct ::betty as instance of grill
+1: v should resolve at global level in grill's constructor
+1: grill's constructor should run at level 1
+1: grill create ::betty
+1: in grill's constructor, v resolves to global level
+1: exiting from bar's bravo
+1: exiting from foo's bravo
+1: exiting from foo's alpha
+}
+
+test tailcall-12.3a0 {[Bug 2695587]} -body {
+ apply {{} {
+ catch [list tailcall foo]
+ }}
+} -returnCodes 1 -result {invalid command name "foo"}
+
+test tailcall-12.3a1 {[Bug 2695587]} -body {
+ apply {{} {
+ catch [list tailcall foo]
+ tailcall
+ }}
+} -result {}
+
+test tailcall-12.3a2 {[Bug 2695587]} -body {
+ apply {{} {
+ catch [list tailcall foo]
+ tailcall moo
+ }}
+} -returnCodes 1 -result {invalid command name "moo"}
+
+test tailcall-12.3a3 {[Bug 2695587]} -body {
+ set x 0
+ apply {{} {
+ catch [list tailcall foo]
+ tailcall lappend x 1
+ }}
+ set x
+} -cleanup {
+ unset x
+} -result {0 1}
+
+test tailcall-12.3b0 {[Bug 2695587]} -body {
+ apply {{} {
+ set catch catch
+ $catch [list tailcall foo]
+ }}
+} -returnCodes 1 -result {invalid command name "foo"}
+
+test tailcall-12.3b1 {[Bug 2695587]} -body {
+ apply {{} {
+ set catch catch
+ $catch [list tailcall foo]
+ tailcall
+ }}
+} -result {}
+
+test tailcall-12.3b2 {[Bug 2695587]} -body {
+ apply {{} {
+ set catch catch
+ $catch [list tailcall foo]
+ tailcall moo
+ }}
+} -returnCodes 1 -result {invalid command name "moo"}
+
+test tailcall-12.3b3 {[Bug 2695587]} -body {
+ set x 0
+ apply {{} {
+ set catch catch
+ $catch [list tailcall foo]
+ tailcall lappend x 1
+ }}
+ set x
+} -cleanup {
+ unset x
+} -result {0 1}
+
+# MORE VARIANTS MISSING: bc'ed caught script vs (bc'ed, not-bc'ed)
+# catch. Actually superfluous now, as tailcall just returns TCL_RETURN so that
+# standard catch behaviour is required.
+
+test tailcall-13.1 {directly tailcalling the tailcall command is ok} {
+ list [catch {
+ apply {{} {
+ apply {{} {
+ tailcall tailcall subst ok
+ subst b
+ }}
+ subst c
+ }}
+ } msg opt] $msg [errorcode $opt]
+} {0 ok NONE}
+test tailcall-13.2 {indirectly tailcalling the tailcall command is ok} {
+ list [catch {
+ apply {{} {
+ apply {{} {
+ tailcall eval tailcall subst ok
+ subst b
+ }}
+ subst c
+ }}
+ } msg opt] $msg [errorcode $opt]
+} {0 ok NONE}
+
+if {[testConstraint testnrelevels]} {
+ namespace forget testnre::*
+ namespace delete testnre
+}
+
+# cleanup
+::tcltest::cleanupTests
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/tcltest.test b/library/msgcat/tests/tcltest.test
new file mode 100755
index 0000000..86aca6f
--- /dev/null
+++ b/library/msgcat/tests/tcltest.test
@@ -0,0 +1,1837 @@
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2000 by Ajuba Solutions
+# All rights reserved.
+
+# Note that there are several places where the value of
+# tcltest::currentFailure is stored/reset in the -setup/-cleanup
+# of a test that has a body that runs [test] that will fail.
+# This is a workaround of using the same tcltest code that we are
+# testing to run the test itself. Ditto on things like [verbose].
+#
+# It would be better to have the -body of the tests run the tcltest
+# commands in a slave interp so the [test] being tested would not
+# interfere with the [test] doing the testing.
+#
+
+if {[catch {package require tcltest 2.1}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2.1 required."
+ return
+}
+
+namespace eval ::tcltest::test {
+
+namespace import ::tcltest::*
+
+makeFile {
+ package require tcltest
+ namespace import ::tcltest::test
+ test a-1.0 {test a} {
+ list 0
+ } {0}
+ test b-1.0 {test b} {
+ list 1
+ } {0}
+ test c-1.0 {test c} {knownBug} {
+ } {}
+ test d-1.0 {test d} {
+ error "foo" foo 9
+ } {}
+ tcltest::cleanupTests
+ exit
+} test.tcl
+
+cd [temporaryDirectory]
+testConstraint exec [llength [info commands exec]]
+# test -help
+# Child processes because -help [exit]s.
+test tcltest-1.1 {tcltest -help} {exec} {
+ set result [catch {exec [interpreter] test.tcl -help} msg]
+ list $result [regexp Usage $msg]
+} {1 1}
+test tcltest-1.2 {tcltest -help -something} {exec} {
+ set result [catch {exec [interpreter] test.tcl -help -something} msg]
+ list $result [regexp Usage $msg]
+} {1 1}
+test tcltest-1.3 {tcltest -h} {exec} {
+ set result [catch {exec [interpreter] test.tcl -h} msg]
+ list $result [regexp Usage $msg]
+} {1 0}
+
+# -verbose, implicit & explicit testing of [verbose]
+proc slave {msgVar args} {
+ upvar 1 $msgVar msg
+
+ interp create [namespace current]::i
+ # Fake the slave interp into dumping output to a file
+ i eval {namespace eval ::tcltest {}}
+ i eval "set tcltest::outputChannel\
+ \[[list open [set of [makeFile {} output]] w]]"
+ i eval "set tcltest::errorChannel\
+ \[[list open [set ef [makeFile {} error]] w]]"
+ i eval [list set argv0 [lindex $args 0]]
+ i eval [list set argv [lrange $args 1 end]]
+ i eval [list package ifneeded tcltest [package provide tcltest] \
+ [package ifneeded tcltest [package provide tcltest]]]
+ i eval {proc exit args {}}
+
+ # Need to capture output in msg
+
+ set code [catch {i eval {source $argv0}} foo]
+if $code {
+#puts "$code: $foo\n$::errorInfo"
+}
+ i eval {close $tcltest::outputChannel}
+ interp delete [namespace current]::i
+ set f [open $of]
+ set msg [read -nonewline $f]
+ close $f
+ set f [open $ef]
+ set err [read -nonewline $f]
+ close $f
+ removeFile output
+ removeFile error
+ if {[string length $err]} {
+ set code 1
+ append msg \n$err
+ }
+ return $code
+
+# return [catch {uplevel 1 [linsert $args 0 exec [interpreter]]} msg]
+}
+test tcltest-2.0 {tcltest (verbose default - 'b')} {unixOrPc} {
+ set result [slave msg test.tcl]
+ list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+ [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 1 0 0 1}
+test tcltest-2.1 {tcltest -verbose 'b'} {unixOrPc} {
+ set result [slave msg test.tcl -verbose 'b']
+ list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+ [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 1 0 0 1}
+test tcltest-2.2 {tcltest -verbose 'p'} {unixOrPc} {
+ set result [slave msg test.tcl -verbose 'p']
+ list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+ [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 0 1 0 1}
+test tcltest-2.3 {tcltest -verbose 's'} {unixOrPc} {
+ set result [slave msg test.tcl -verbose 's']
+ list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+ [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 0 0 1 1}
+test tcltest-2.4 {tcltest -verbose 'ps'} {unixOrPc} {
+ set result [slave msg test.tcl -verbose 'ps']
+ list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+ [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 0 1 1 1}
+test tcltest-2.5 {tcltest -verbose 'psb'} {unixOrPc} {
+ set result [slave msg test.tcl -verbose 'psb']
+ list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+ [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 1 1 1 1}
+
+test tcltest-2.5a {tcltest -verbose 'pass skip body'} {unixOrPc} {
+ set result [slave msg test.tcl -verbose "pass skip body"]
+ list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+ [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 1 1 1 1}
+
+test tcltest-2.6 {tcltest -verbose 't'} {
+ -constraints {unixOrPc}
+ -body {
+ set result [slave msg test.tcl -verbose 't']
+ list $result $msg
+ }
+ -result {^0 .*a-1.0 start.*b-1.0 start}
+ -match regexp
+}
+
+test tcltest-2.6a {tcltest -verbose 'start'} {
+ -constraints {unixOrPc}
+ -body {
+ set result [slave msg test.tcl -verbose start]
+ list $result $msg
+ }
+ -result {^0 .*a-1.0 start.*b-1.0 start}
+ -match regexp
+}
+
+test tcltest-2.7 {tcltest::verbose} {
+ -body {
+ set oldVerbosity [verbose]
+ verbose bar
+ set currentVerbosity [verbose]
+ verbose foo
+ set newVerbosity [verbose]
+ verbose $oldVerbosity
+ list $currentVerbosity $newVerbosity
+ }
+ -result {body {}}
+}
+
+test tcltest-2.8 {tcltest -verbose 'error'} {
+ -constraints {unixOrPc}
+ -body {
+ set result [slave msg test.tcl -verbose error]
+ list $result $msg
+ }
+ -result {errorInfo: foo.*errorCode: 9}
+ -match regexp
+}
+# -match, [match]
+test tcltest-3.1 {tcltest -match 'a*'} {unixOrPc} {
+ set result [slave msg test.tcl -match a* -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+3.+Failed.+0" $msg]
+} {0 1 0 0 1}
+test tcltest-3.2 {tcltest -match 'b*'} {unixOrPc} {
+ set result [slave msg test.tcl -match b* -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+0.+Skipped.+3.+Failed.+1" $msg]
+} {0 0 1 0 1}
+test tcltest-3.3 {tcltest -match 'c*'} {unixOrPc} {
+ set result [slave msg test.tcl -match c* -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+0.+Skipped.+4.+Failed.+0" $msg]
+} {0 0 0 1 1}
+test tcltest-3.4 {tcltest -match 'a* b*'} {unixOrPc} {
+ set result [slave msg test.tcl -match {a* b*} -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+2.+Failed.+1" $msg]
+} {0 1 1 0 1}
+
+test tcltest-3.5 {tcltest::match} {
+ -body {
+ set oldMatch [match]
+ match foo
+ set currentMatch [match]
+ match bar
+ set newMatch [match]
+ match $oldMatch
+ list $currentMatch $newMatch
+ }
+ -result {foo bar}
+}
+
+# -skip, [skip]
+test tcltest-4.1 {tcltest -skip 'a*'} {unixOrPc} {
+ set result [slave msg test.tcl -skip a* -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+0.+Skipped.+2.+Failed.+1" $msg]
+} {0 0 1 1 1}
+test tcltest-4.2 {tcltest -skip 'b*'} {unixOrPc} {
+ set result [slave msg test.tcl -skip b* -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+2.+Failed.+1" $msg]
+} {0 1 0 1 1}
+test tcltest-4.3 {tcltest -skip 'c*'} {unixOrPc} {
+ set result [slave msg test.tcl -skip c* -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 1 1 0 1}
+test tcltest-4.4 {tcltest -skip 'a* b*'} {unixOrPc} {
+ set result [slave msg test.tcl -skip {a* b*} -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+0.+Skipped.+3.+Failed.+1" $msg]
+} {0 0 0 1 1}
+test tcltest-4.5 {tcltest -match 'a* b*' -skip 'b*'} {unixOrPc} {
+ set result [slave msg test.tcl -match {a* b*} -skip b* -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+3.+Failed.+0" $msg]
+} {0 1 0 0 1}
+
+test tcltest-4.6 {tcltest::skip} {
+ -body {
+ set oldSkip [skip]
+ skip foo
+ set currentSkip [skip]
+ skip bar
+ set newSkip [skip]
+ skip $oldSkip
+ list $currentSkip $newSkip
+ }
+ -result {foo bar}
+}
+
+# -constraints, -limitconstraints, [testConstraint],
+# $constraintsSpecified, [limitConstraints]
+test tcltest-5.1 {tcltest -constraints 'knownBug'} {unixOrPc} {
+ set result [slave msg test.tcl -constraints knownBug -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+2.+Skipped.+0.+Failed.+2" $msg]
+} {0 1 1 1 1}
+test tcltest-5.2 {tcltest -constraints 'knownBug' -limitconstraints 1} {unixOrPc} {
+ set result [slave msg test.tcl -constraints knownBug -verbose 'p' -limitconstraints 1]
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+3.+Failed.+0" $msg]
+} {0 0 0 1 1}
+
+test tcltest-5.3 {testConstraint - constraint empty (tcltest::safeFetch)} {
+ -body {
+ set r1 [testConstraint tcltestFakeConstraint]
+ set r2 [testConstraint tcltestFakeConstraint 4]
+ set r3 [testConstraint tcltestFakeConstraint]
+ list $r1 $r2 $r3
+ }
+ -result {0 4 4}
+ -cleanup {unset ::tcltest::testConstraints(tcltestFakeConstraint)}
+}
+
+# Removed this test of internals of tcltest. Those internals have changed.
+#test tcltest-5.4 {tcltest::constraintsSpecified} {
+# -setup {
+# set constraintlist $::tcltest::constraintsSpecified
+# set ::tcltest::constraintsSpecified {}
+# }
+# -body {
+# set r1 $::tcltest::constraintsSpecified
+# testConstraint tcltestFakeConstraint1 1
+# set r2 $::tcltest::constraintsSpecified
+# testConstraint tcltestFakeConstraint2 1
+# set r3 $::tcltest::constraintsSpecified
+# list $r1 $r2 $r3
+# }
+# -result {{} tcltestFakeConstraint1 {tcltestFakeConstraint1 tcltestFakeConstraint2}}
+# -cleanup {
+# set ::tcltest::constraintsSpecified $constraintlist
+# unset ::tcltest::testConstraints(tcltestFakeConstraint1)
+# unset ::tcltest::testConstraints(tcltestFakeConstraint2)
+# }
+#}
+
+test tcltest-5.5 {InitConstraints: list of built-in constraints} \
+ -constraints {!singleTestInterp} \
+ -setup {tcltest::InitConstraints} \
+ -body { lsort [array names ::tcltest::testConstraints] } \
+ -result [lsort {
+ 95 98 asyncPipeClose eformat emptyTest exec hasIsoLocale interactive
+ knownBug mac macCrash macOnly macOrPc macOrUnix macOrWin nonBlockFiles
+ nonPortable notRoot nt pc pcCrash pcOnly root singleTestInterp socket
+ stdio tempNotMac tempNotPc tempNotUnix tempNotWin unix unixCrash unixExecs
+ unixOnly unixOrPc unixOrWin userInteraction win winCrash winOnly
+}]
+
+# Removed this broken test. Its usage of [limitConstraints] was not
+# in agreement with the documentation. [limitConstraints] is supposed
+# to take an optional boolean argument, and "knownBug" ain't no boolean!
+#test tcltest-5.6 {tcltest::limitConstraints} {
+# -setup {
+# set keeplc $::tcltest::limitConstraints
+# set keepkb [testConstraint knownBug]
+# }
+# -body {
+# set r1 [limitConstraints]
+# set r2 [limitConstraints knownBug]
+# set r3 [limitConstraints]
+# list $r1 $r2 $r3
+# }
+# -cleanup {
+# limitConstraints $keeplc
+# testConstraint knownBug $keepkb
+# }
+# -result {false knownBug knownBug}
+#}
+
+# -outfile, -errfile, [outputChannel], [outputFile], [errorChannel], [errorFile]
+set printerror [makeFile {
+ package require tcltest
+ namespace import ::tcltest::*
+ puts [outputChannel] "a test"
+ ::tcltest::PrintError "a really short string"
+ ::tcltest::PrintError "a really really really really really really long \
+ string containing \"quotes\" and other bad bad stuff"
+ ::tcltest::PrintError "a really really long string containing a \
+ \"Path/that/is/really/long/and/contains/no/spaces\""
+ ::tcltest::PrintError "a really really long string containing a \
+ \"Really/Long/Path/that/contains/no/spaces/and/is/longer/than/eighty/characters/to/see/what/happens\""
+ ::tcltest::PrintError "Problem renaming file: error renaming \"Z:/ws/tcl8.2/win32-ix86/tests/core\" to \"Z:/ws/tcl8.2/win32-ix86/tests/movecore-core\""
+ exit
+} printerror.tcl]
+
+test tcltest-6.1 {tcltest -outfile, -errfile defaults} {
+ -constraints unixOrPc
+ -body {
+ slave msg $printerror
+ return $msg
+ }
+ -result {a test.*a really}
+ -match regexp
+}
+test tcltest-6.2 {tcltest -outfile a.tmp} {unixOrPc unixExecs} {
+ slave msg $printerror -outfile a.tmp
+ set result1 [catch {exec grep "a test" a.tmp}]
+ set result2 [catch {exec grep "a really" a.tmp}]
+ list [regexp "a test" $msg] [regexp "a really" $msg] \
+ $result1 $result2 [file exists a.tmp] [file delete a.tmp]
+} {0 1 0 1 1 {}}
+test tcltest-6.3 {tcltest -errfile a.tmp} {unixOrPc unixExecs} {
+ slave msg $printerror -errfile a.tmp
+ set result1 [catch {exec grep "a test" a.tmp}]
+ set result2 [catch {exec grep "a really" a.tmp}]
+ list [regexp "a test" $msg] [regexp "a really" $msg] \
+ $result1 $result2 [file exists a.tmp] [file delete a.tmp]
+} {1 0 1 0 1 {}}
+test tcltest-6.4 {tcltest -outfile a.tmp -errfile b.tmp} {unixOrPc unixExecs} {
+ slave msg $printerror -outfile a.tmp -errfile b.tmp
+ set result1 [catch {exec grep "a test" a.tmp}]
+ set result2 [catch {exec grep "a really" b.tmp}]
+ list [regexp "a test" $msg] [regexp "a really" $msg] \
+ $result1 $result2 \
+ [file exists a.tmp] [file delete a.tmp] \
+ [file exists b.tmp] [file delete b.tmp]
+} {0 0 0 0 1 {} 1 {}}
+
+test tcltest-6.5 {tcltest::errorChannel - retrieval} {
+ -setup {
+ set of [errorChannel]
+ set ::tcltest::errorChannel stderr
+ }
+ -body {
+ errorChannel
+ }
+ -result {stderr}
+ -cleanup {
+ set ::tcltest::errorChannel $of
+ }
+}
+
+test tcltest-6.6 {tcltest::errorFile (implicit errorChannel)} {
+ -setup {
+ set ef [makeFile {} efile]
+ set of [errorFile]
+ set ::tcltest::errorChannel stderr
+ set ::tcltest::errorFile stderr
+ }
+ -body {
+ set f0 [errorChannel]
+ set f1 [errorFile]
+ set f2 [errorFile $ef]
+ set f3 [errorChannel]
+ set f4 [errorFile]
+ subst {$f0;$f1;$f2;$f3;$f4}
+ }
+ -result {stderr;stderr;.*efile;file[0-9a-f]+;.*efile}
+ -match regexp
+ -cleanup {
+ errorFile $of
+ removeFile efile
+ }
+}
+test tcltest-6.7 {tcltest::outputChannel - retrieval} {
+ -setup {
+ set of [outputChannel]
+ set ::tcltest::outputChannel stdout
+ }
+ -body {
+ outputChannel
+ }
+ -result {stdout}
+ -cleanup {
+ set ::tcltest::outputChannel $of
+ }
+}
+
+test tcltest-6.8 {tcltest::outputFile (implicit outputFile)} {
+ -setup {
+ set ef [makeFile {} efile]
+ set of [outputFile]
+ set ::tcltest::outputChannel stdout
+ set ::tcltest::outputFile stdout
+ }
+ -body {
+ set f0 [outputChannel]
+ set f1 [outputFile]
+ set f2 [outputFile $ef]
+ set f3 [outputChannel]
+ set f4 [outputFile]
+ subst {$f0;$f1;$f2;$f3;$f4}
+ }
+ -result {stdout;stdout;.*efile;file[0-9a-f]+;.*efile}
+ -match regexp
+ -cleanup {
+ outputFile $of
+ removeFile efile
+ }
+}
+
+# -debug, [debug]
+# Must use child processes to test -debug because it always writes
+# messages to stdout, and we have no way to capture stdout of a
+# slave interp
+test tcltest-7.1 {tcltest test.tcl -debug 0} {unixOrPc} {
+ catch {exec [interpreter] test.tcl -debug 0} msg
+ regexp "Flags passed into tcltest" $msg
+} {0}
+test tcltest-7.2 {tcltest test.tcl -debug 1} {unixOrPc} {
+ catch {exec [interpreter] test.tcl -debug 1 -skip b*} msg
+ list [regexp userSpecifiedSkip $msg] \
+ [regexp "Flags passed into tcltest" $msg]
+} {1 0}
+test tcltest-7.3 {tcltest test.tcl -debug 1} {unixOrPc} {
+ catch {exec [interpreter] test.tcl -debug 1 -match b*} msg
+ list [regexp userSpecifiedNonMatch $msg] \
+ [regexp "Flags passed into tcltest" $msg]
+} {1 0}
+test tcltest-7.4 {tcltest test.tcl -debug 2} {unixOrPc} {
+ catch {exec [interpreter] test.tcl -debug 2} msg
+ list [regexp "Flags passed into tcltest" $msg] [regexp "Running" $msg]
+} {1 0}
+test tcltest-7.5 {tcltest test.tcl -debug 3} {unixOrPc} {
+ catch {exec [interpreter] test.tcl -debug 3} msg
+ list [regexp "Flags passed into tcltest" $msg] [regexp "Running" $msg]
+} {1 1}
+
+test tcltest-7.6 {tcltest::debug} {
+ -setup {
+ set old $::tcltest::debug
+ set ::tcltest::debug 0
+ }
+ -body {
+ set f1 [debug]
+ set f2 [debug 1]
+ set f3 [debug]
+ set f4 [debug 2]
+ set f5 [debug]
+ list $f1 $f2 $f3 $f4 $f5
+ }
+ -result {0 1 1 2 2}
+ -cleanup {
+ set ::tcltest::debug $old
+ }
+}
+removeFile test.tcl
+
+# directory tests
+
+set a [makeFile {
+ package require tcltest
+ tcltest::makeFile {} a.tmp
+ puts [tcltest::outputChannel] "testdir: [tcltest::testsDirectory]"
+ exit
+} a.tcl]
+
+set tdiaf [makeFile {} thisdirectoryisafile]
+
+set normaldirectory [makeDirectory normaldirectory]
+normalizePath normaldirectory
+
+# -tmpdir, [temporaryDirectory]
+test tcltest-8.1 {tcltest a.tcl -tmpdir a} -constraints unixOrPc -setup {
+ file delete -force thisdirectorydoesnotexist
+} -body {
+ slave msg $a -tmpdir thisdirectorydoesnotexist
+ file exists [file join thisdirectorydoesnotexist a.tmp]
+} -cleanup {
+ file delete -force thisdirectorydoesnotexist
+} -result 1
+test tcltest-8.2 {tcltest a.tcl -tmpdir thisdirectoryisafile} {
+ -constraints unixOrPc
+ -body {
+ slave msg $a -tmpdir $tdiaf
+ return $msg
+ }
+ -result {*not a directory*}
+ -match glob
+}
+# Test non-writeable directories, non-readable directories with directory flags
+set notReadableDir [file join [temporaryDirectory] notreadable]
+set notWriteableDir [file join [temporaryDirectory] notwriteable]
+makeDirectory notreadable
+makeDirectory notwriteable
+switch -- $::tcl_platform(platform) {
+ "unix" {
+ file attributes $notReadableDir -permissions 00333
+ file attributes $notWriteableDir -permissions 00555
+ }
+ default {
+ catch {file attributes $notWriteableDir -readonly 1}
+ catch {testchmod 000 $notWriteableDir}
+ }
+}
+test tcltest-8.3 {tcltest a.tcl -tmpdir notReadableDir} {
+ -constraints {unix notRoot}
+ -body {
+ slave msg $a -tmpdir $notReadableDir
+ return $msg
+ }
+ -result {*not readable*}
+ -match glob
+}
+# This constraint doesn't go at the top of the file so that it doesn't
+# interfere with tcltest-5.5
+testConstraint notFAT [expr {
+ ![string match "FAT*" [lindex [file system $notWriteableDir] 1]]
+}]
+# FAT permissions are fairly hopeless; ignore this test if that FS is used
+test tcltest-8.4 {tcltest a.tcl -tmpdir notWriteableDir} {
+ -constraints {unixOrPc notRoot notFAT}
+ -body {
+ slave msg $a -tmpdir $notWriteableDir
+ return $msg
+ }
+ -result {*not writeable*}
+ -match glob
+}
+test tcltest-8.5 {tcltest a.tcl -tmpdir normaldirectory} {
+ -constraints unixOrPc
+ -body {
+ slave msg $a -tmpdir $normaldirectory
+ # The join is necessary because the message can be split on multiple
+ # lines
+ file exists [file join $normaldirectory a.tmp]
+ }
+ -cleanup {
+ catch {file delete [file join $normaldirectory a.tmp]}
+ }
+ -result 1
+}
+cd [workingDirectory]
+test tcltest-8.6 {temporaryDirectory} {
+ -setup {
+ set old $::tcltest::temporaryDirectory
+ set ::tcltest::temporaryDirectory $normaldirectory
+ }
+ -body {
+ set f1 [temporaryDirectory]
+ set f2 [temporaryDirectory [workingDirectory]]
+ set f3 [temporaryDirectory]
+ list $f1 $f2 $f3
+ }
+ -result "[list $normaldirectory [workingDirectory] [workingDirectory]]"
+ -cleanup {
+ set ::tcltest::temporaryDirectory $old
+ }
+}
+test tcltest-8.6a {temporaryDirectory - test format 2} -setup {
+ set old $::tcltest::temporaryDirectory
+ set ::tcltest::temporaryDirectory $normaldirectory
+} -body {
+ set f1 [temporaryDirectory]
+ set f2 [temporaryDirectory [workingDirectory]]
+ set f3 [temporaryDirectory]
+ list $f1 $f2 $f3
+} -cleanup {
+ set ::tcltest::temporaryDirectory $old
+} -result [list $normaldirectory [workingDirectory] [workingDirectory]]
+cd [temporaryDirectory]
+# -testdir, [testsDirectory]
+test tcltest-8.10 {tcltest a.tcl -testdir thisdirectorydoesnotexist} {
+ -constraints unixOrPc
+ -setup {
+ file delete -force thisdirectorydoesnotexist
+ }
+ -body {
+ slave msg $a -testdir thisdirectorydoesnotexist
+ return $msg
+ }
+ -match glob
+ -result {*does not exist*}
+}
+test tcltest-8.11 {tcltest a.tcl -testdir thisdirectoryisafile} {
+ -constraints unixOrPc
+ -body {
+ slave msg $a -testdir $tdiaf
+ return $msg
+ }
+ -match glob
+ -result {*not a directory*}
+}
+test tcltest-8.12 {tcltest a.tcl -testdir notReadableDir} {
+ -constraints {unix notRoot}
+ -body {
+ slave msg $a -testdir $notReadableDir
+ return $msg
+ }
+ -match glob
+ -result {*not readable*}
+}
+test tcltest-8.13 {tcltest a.tcl -testdir normaldirectory} {
+ -constraints unixOrPc
+ -body {
+ slave msg $a -testdir $normaldirectory
+ # The join is necessary because the message can be split on multiple
+ # lines
+ list [string first "testdir: $normaldirectory" [join $msg]] \
+ [file exists [file join [temporaryDirectory] a.tmp]]
+ }
+ -cleanup {
+ file delete [file join [temporaryDirectory] a.tmp]
+ }
+ -result {0 1}
+}
+cd [workingDirectory]
+set current [pwd]
+test tcltest-8.14 {testsDirectory} {
+ -setup {
+ set old $::tcltest::testsDirectory
+ set ::tcltest::testsDirectory $normaldirectory
+ }
+ -body {
+ set f1 [testsDirectory]
+ set f2 [testsDirectory $current]
+ set f3 [testsDirectory]
+ list $f1 $f2 $f3
+ }
+ -result "[list $normaldirectory $current $current]"
+ -cleanup {
+ set ::tcltest::testsDirectory $old
+ }
+}
+# [workingDirectory]
+test tcltest-8.60 {::workingDirectory} {
+ -setup {
+ set old $::tcltest::workingDirectory
+ set current [pwd]
+ set ::tcltest::workingDirectory $normaldirectory
+ cd $normaldirectory
+ }
+ -body {
+ set f1 [workingDirectory]
+ set f2 [pwd]
+ set f3 [workingDirectory $current]
+ set f4 [pwd]
+ set f5 [workingDirectory]
+ list $f1 $f2 $f3 $f4 $f5
+ }
+ -result "[list $normaldirectory \
+ $normaldirectory \
+ $current \
+ $current \
+ $current]"
+ -cleanup {
+ set ::tcltest::workingDirectory $old
+ cd $current
+ }
+}
+
+# clean up from directory testing
+
+switch $::tcl_platform(platform) {
+ "unix" {
+ file attributes $notReadableDir -permissions 777
+ file attributes $notWriteableDir -permissions 777
+ }
+ default {
+ catch {testchmod 777 $notWriteableDir}
+ catch {file attributes $notWriteableDir -readonly 0}
+ }
+}
+
+file delete -force $notReadableDir $notWriteableDir
+removeFile a.tcl
+removeFile thisdirectoryisafile
+removeDirectory normaldirectory
+
+# -file, -notfile, [matchFiles], [skipFiles]
+test tcltest-9.1 {-file d*.tcl} -constraints {unixOrPc} -setup {
+ set old [testsDirectory]
+ testsDirectory [file dirname [info script]]
+} -body {
+ slave msg [file join [testsDirectory] all.tcl] -file d*.test
+ return $msg
+} -cleanup {
+ testsDirectory $old
+} -match regexp -result {dstring\.test}
+
+test tcltest-9.2 {-file d*.tcl} -constraints {unixOrPc} -setup {
+ set old [testsDirectory]
+ testsDirectory [file dirname [info script]]
+} -body {
+ slave msg [file join [testsDirectory] all.tcl] \
+ -file d*.test -notfile dstring*
+ regexp {dstring\.test} $msg
+} -cleanup {
+ testsDirectory $old
+} -result 0
+
+test tcltest-9.3 {matchFiles} {
+ -body {
+ set old [matchFiles]
+ matchFiles foo
+ set current [matchFiles]
+ matchFiles bar
+ set new [matchFiles]
+ matchFiles $old
+ list $current $new
+ }
+ -result {foo bar}
+}
+
+test tcltest-9.4 {skipFiles} {
+ -body {
+ set old [skipFiles]
+ skipFiles foo
+ set current [skipFiles]
+ skipFiles bar
+ set new [skipFiles]
+ skipFiles $old
+ list $current $new
+ }
+ -result {foo bar}
+}
+
+test tcltest-9.5 {GetMatchingFiles: Bug 1119798} -setup {
+ set d [makeDirectory tmp]
+ makeDirectory foo $d
+ makeFile {} fee $d
+ file copy [file join [file dirname [info script]] all.tcl] $d
+} -body {
+ slave msg [file join [temporaryDirectory] all.tcl] -file f*
+ regexp {exiting with errors:} $msg
+} -cleanup {
+ file delete [file join $d all.tcl]
+ removeFile fee $d
+ removeDirectory foo $d
+ removeDirectory tmp
+} -result 0
+
+# -preservecore, [preserveCore]
+set mc [makeFile {
+ package require tcltest
+ namespace import ::tcltest::test
+ test makecore {make a core file} {
+ set f [open core w]
+ close $f
+ } {}
+ ::tcltest::cleanupTests
+ return
+} makecore.tcl]
+
+cd [temporaryDirectory]
+test tcltest-10.1 {-preservecore 0} {unixOrPc} {
+ slave msg $mc -preservecore 0
+ file delete core
+ regexp "Core file produced" $msg
+} {0}
+test tcltest-10.2 {-preservecore 1} {unixOrPc} {
+ slave msg $mc -preservecore 1
+ file delete core
+ regexp "Core file produced" $msg
+} {1}
+test tcltest-10.3 {-preservecore 2} {unixOrPc} {
+ slave msg $mc -preservecore 2
+ file delete core
+ list [regexp "Core file produced" $msg] [regexp "Moving file to" $msg] \
+ [regexp "core-" $msg] [file delete core-makecore]
+} {1 1 1 {}}
+test tcltest-10.4 {-preservecore 3} {unixOrPc} {
+ slave msg $mc -preservecore 3
+ file delete core
+ list [regexp "Core file produced" $msg] [regexp "Moving file to" $msg] \
+ [regexp "core-" $msg] [file delete core-makecore]
+} {1 1 1 {}}
+
+# Removing this test. It makes no sense to test the ability of
+# [preserveCore] to accept an invalid value that will cause errors
+# in other parts of tcltest's operation.
+#test tcltest-10.5 {preserveCore} {
+# -body {
+# set old [preserveCore]
+# set result [preserveCore foo]
+# set result2 [preserveCore]
+# preserveCore $old
+# list $result $result2
+# }
+# -result {foo foo}
+#}
+removeFile makecore.tcl
+
+# -load, -loadfile, [loadScript], [loadFile]
+set contents {
+ package require tcltest
+ namespace import tcltest::*
+ puts [outputChannel] $::tcltest::loadScript
+ exit
+}
+set loadfile [makeFile $contents load.tcl]
+
+test tcltest-12.1 {-load xxx} {unixOrPc} {
+ slave msg $loadfile -load xxx
+ return $msg
+} {xxx}
+
+# Using child process because of -debug usage.
+test tcltest-12.2 {-loadfile load.tcl} {unixOrPc} {
+ catch {exec [interpreter] $loadfile -debug 2 -loadfile $loadfile} msg
+ list \
+ [regexp {tcltest} [join [list $msg] [split $msg \n]]] \
+ [regexp {loadScript} [join [list $msg] [split $msg \n]]]
+} {1 1}
+
+test tcltest-12.3 {loadScript} {
+ -setup {
+ set old $::tcltest::loadScript
+ set ::tcltest::loadScript {}
+ }
+ -body {
+ set f1 [loadScript]
+ set f2 [loadScript xxx]
+ set f3 [loadScript]
+ list $f1 $f2 $f3
+ }
+ -result {{} xxx xxx}
+ -cleanup {
+ set ::tcltest::loadScript $old
+ }
+}
+
+test tcltest-12.4 {loadFile} {
+ -setup {
+ set olds $::tcltest::loadScript
+ set ::tcltest::loadScript {}
+ set oldf $::tcltest::loadFile
+ set ::tcltest::loadFile {}
+ }
+ -body {
+ set f1 [loadScript]
+ set f2 [loadFile]
+ set f3 [loadFile $loadfile]
+ set f4 [loadScript]
+ set f5 [loadFile]
+ list $f1 $f2 $f3 $f4 $f5
+ }
+ -result "[list {} {} $loadfile $contents $loadfile]\n"
+ -cleanup {
+ set ::tcltest::loadScript $olds
+ set ::tcltest::loadFile $oldf
+ }
+}
+removeFile load.tcl
+
+# [interpreter]
+test tcltest-13.1 {interpreter} {
+ -setup {
+ set old $::tcltest::tcltest
+ set ::tcltest::tcltest tcltest
+ }
+ -body {
+ set f1 [interpreter]
+ set f2 [interpreter tclsh]
+ set f3 [interpreter]
+ list $f1 $f2 $f3
+ }
+ -result {tcltest tclsh tclsh}
+ -cleanup {
+ set ::tcltest::tcltest $old
+ }
+}
+
+# -singleproc, [singleProcess]
+set spd [makeDirectory singleprocdir]
+makeFile {
+ set foo 1
+} single1.test $spd
+
+makeFile {
+ unset foo
+} single2.test $spd
+
+set allfile [makeFile {
+ package require tcltest
+ namespace import tcltest::*
+ testsDirectory [file join [temporaryDirectory] singleprocdir]
+ runAllTests
+} all-single.tcl $spd]
+cd [workingDirectory]
+
+test tcltest-14.1 {-singleproc - single process} {
+ -constraints {unixOrPc}
+ -body {
+ slave msg $allfile -singleproc 0 -tmpdir [temporaryDirectory]
+ return $msg
+ }
+ -result {Test file error: can't unset .foo.: no such variable}
+ -match regexp
+}
+
+test tcltest-14.2 {-singleproc - multiple process} {
+ -constraints {unixOrPc}
+ -body {
+ slave msg $allfile -singleproc 1 -tmpdir [temporaryDirectory]
+ return $msg
+ }
+ -result {single1.test.*single2.test.*all\-single.tcl:.*Total.*0.*Passed.*0.*Skipped.*0.*Failed.*0}
+ -match regexp
+}
+
+test tcltest-14.3 {singleProcess} {
+ -setup {
+ set old $::tcltest::singleProcess
+ set ::tcltest::singleProcess 0
+ }
+ -body {
+ set f1 [singleProcess]
+ set f2 [singleProcess 1]
+ set f3 [singleProcess]
+ list $f1 $f2 $f3
+ }
+ -result {0 1 1}
+ -cleanup {
+ set ::tcltest::singleProcess $old
+ }
+}
+removeFile single1.test $spd
+removeFile single2.test $spd
+removeDirectory singleprocdir
+
+# -asidefromdir, -relateddir, [matchDirectories], [skipDirectories]
+
+# Before running these tests, need to set up test subdirectories with their own
+# all.tcl files.
+
+set dtd [makeDirectory dirtestdir]
+set dtd1 [makeDirectory dirtestdir2.1 $dtd]
+set dtd2 [makeDirectory dirtestdir2.2 $dtd]
+set dtd3 [makeDirectory dirtestdir2.3 $dtd]
+makeFile {
+ package require tcltest
+ namespace import -force tcltest::*
+ testsDirectory [file join [temporaryDirectory] dirtestdir]
+ runAllTests
+} all.tcl $dtd
+makeFile {
+ package require tcltest
+ namespace import -force tcltest::*
+ testsDirectory [file join [temporaryDirectory] dirtestdir dirtestdir2.1]
+ runAllTests
+} all.tcl $dtd1
+makeFile {
+ package require tcltest
+ namespace import -force tcltest::*
+ testsDirectory [file join [temporaryDirectory] dirtestdir dirtestdir2.2]
+ runAllTests
+} all.tcl $dtd2
+makeFile {
+ package require tcltest
+ namespace import -force tcltest::*
+ testsDirectory [file join [temporaryDirectory] dirtestdir dirtestdir2.3]
+ runAllTests
+} all.tcl $dtd3
+
+test tcltest-15.1 {basic directory walking} {
+ -constraints {unixOrPc}
+ -body {
+ if {[slave msg \
+ [file join $dtd all.tcl] \
+ -tmpdir [temporaryDirectory]] == 1} {
+ error $msg
+ }
+ }
+ -match regexp
+ -returnCodes 1
+ -result {Tests located in:.*dirtestdir.*Tests located in:.*dirtestdir2.[123].*Tests located in:.*dirtestdir2.[123].*Tests located in:.*dirtestdir2.[123]}
+}
+
+test tcltest-15.2 {-asidefromdir} {
+ -constraints {unixOrPc}
+ -body {
+ if {[slave msg \
+ [file join $dtd all.tcl] \
+ -asidefromdir dirtestdir2.3 \
+ -tmpdir [temporaryDirectory]] == 1} {
+ error $msg
+ }
+ }
+ -match regexp
+ -returnCodes 1
+ -result {Tests located in:.*dirtestdir.*Tests located in:.*dirtestdir2.[12].*Tests located in:.*dirtestdir2.[12].*dirtestdir2.[12] test ended at .*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Error: No test files remain after applying your match and skip patterns!
+Error: No test files remain after applying your match and skip patterns!
+Error: No test files remain after applying your match and skip patterns!$}
+}
+
+test tcltest-15.3 {-relateddir, non-existent dir} {
+ -constraints {unixOrPc}
+ -body {
+ if {[slave msg \
+ [file join $dtd all.tcl] \
+ -relateddir [file join [temporaryDirectory] dirtestdir0] \
+ -tmpdir [temporaryDirectory]] == 1} {
+ error $msg
+ }
+ }
+ -returnCodes 1
+ -match regexp
+ -result {[^~]|dirtestdir[^2]}
+}
+
+test tcltest-15.4 {-relateddir, subdir} {
+ -constraints {unixOrPc}
+ -body {
+ if {[slave msg \
+ [file join $dtd all.tcl] \
+ -relateddir dirtestdir2.1 -tmpdir [temporaryDirectory]] == 1} {
+ error $msg
+ }
+ }
+ -returnCodes 1
+ -match regexp
+ -result {Tests located in:.*dirtestdir2.[^23]}
+}
+test tcltest-15.5 {-relateddir, -asidefromdir} {
+ -constraints {unixOrPc}
+ -body {
+ if {[slave msg \
+ [file join $dtd all.tcl] \
+ -relateddir "dirtestdir2.1 dirtestdir2.2" \
+ -asidefromdir dirtestdir2.2 \
+ -tmpdir [temporaryDirectory]] == 1} {
+ error $msg
+ }
+ }
+ -match regexp
+ -returnCodes 1
+ -result {Tests located in:.*dirtestdir2.[^23]}
+}
+
+test tcltest-15.6 {matchDirectories} {
+ -setup {
+ set old [matchDirectories]
+ set ::tcltest::matchDirectories {}
+ }
+ -body {
+ set r1 [matchDirectories]
+ set r2 [matchDirectories foo]
+ set r3 [matchDirectories]
+ list $r1 $r2 $r3
+ }
+ -cleanup {
+ set ::tcltest::matchDirectories $old
+ }
+ -result {{} foo foo}
+}
+
+test tcltest-15.7 {skipDirectories} {
+ -setup {
+ set old [skipDirectories]
+ set ::tcltest::skipDirectories {}
+ }
+ -body {
+ set r1 [skipDirectories]
+ set r2 [skipDirectories foo]
+ set r3 [skipDirectories]
+ list $r1 $r2 $r3
+ }
+ -cleanup {
+ set ::tcltest::skipDirectories $old
+ }
+ -result {{} foo foo}
+}
+removeDirectory dirtestdir2.3 $dtd
+removeDirectory dirtestdir2.2 $dtd
+removeDirectory dirtestdir2.1 $dtd
+removeDirectory dirtestdir
+
+# TCLTEST_OPTIONS
+test tcltest-19.1 {TCLTEST_OPTIONS default} -setup {
+ if {[info exists ::env(TCLTEST_OPTIONS)]} {
+ set oldoptions $::env(TCLTEST_OPTIONS)
+ } else {
+ set oldoptions none
+ }
+ # set this to { } instead of just {} to get around quirk in
+ # Windows env handling that removes empty elements from env array.
+ set ::env(TCLTEST_OPTIONS) { }
+ interp create slave1
+ slave1 eval [list set argv {-debug 2}]
+ slave1 alias puts puts
+ interp create slave2
+ slave2 alias puts puts
+ } -cleanup {
+ interp delete slave2
+ interp delete slave1
+ if {$oldoptions == "none"} {
+ unset ::env(TCLTEST_OPTIONS)
+ } else {
+ set ::env(TCLTEST_OPTIONS) $oldoptions
+ }
+ } -body {
+ slave1 eval [package ifneeded tcltest [package provide tcltest]]
+ slave1 eval tcltest::debug
+ set ::env(TCLTEST_OPTIONS) "-debug 3"
+ slave2 eval [package ifneeded tcltest [package provide tcltest]]
+ slave2 eval tcltest::debug
+ } -result {^3$} -match regexp -output\
+{tcltest::debug\s+= 2.*tcltest::debug\s+= 3}
+
+# Begin testing of tcltest procs ...
+
+cd [temporaryDirectory]
+# PrintError
+test tcltest-20.1 {PrintError} {unixOrPc} {
+ set result [slave msg $printerror]
+ list $result [regexp "Error: a really short string" $msg] \
+ [regexp " \"quotes\"" $msg] [regexp " \"Path" $msg] \
+ [regexp " \"Really" $msg] [regexp Problem $msg]
+} {1 1 1 1 1 1}
+cd [workingDirectory]
+removeFile printerror.tcl
+
+# test::test
+test tcltest-21.0 {name and desc but no args specified} -setup {
+ set v [verbose]
+} -cleanup {
+ verbose $v
+} -body {
+ verbose {}
+ test tcltest-21.0.0 bar
+} -result {}
+
+test tcltest-21.1 {expect with glob} {
+ -body {
+ list a b c d e
+ }
+ -match glob
+ -result {[ab] b c d e}
+}
+
+test tcltest-21.2 {force a test command failure} {
+ -body {
+ test tcltest-21.2.0 {
+ return 2
+ } {1}
+ }
+ -returnCodes 1
+ -result {bad option "1": must be -body, -cleanup, -constraints, -errorOutput, -match, -output, -result, -returnCodes, or -setup}
+}
+
+test tcltest-21.3 {test command with setup} {
+ -setup {
+ set foo 1
+ }
+ -body {
+ set foo
+ }
+ -cleanup {unset foo}
+ -result {1}
+}
+
+test tcltest-21.4 {test command with cleanup failure} {
+ -setup {
+ if {[info exists foo]} {
+ unset foo
+ }
+ set fail $::tcltest::currentFailure
+ set v [verbose]
+ }
+ -body {
+ verbose {}
+ test tcltest-21.4.0 {foo-1} {
+ -cleanup {unset foo}
+ }
+ }
+ -result {^$}
+ -match regexp
+ -cleanup {verbose $v; set ::tcltest::currentFailure $fail}
+ -output "Test cleanup failed:.*can't unset \"foo\": no such variable"
+}
+
+test tcltest-21.5 {test command with setup failure} {
+ -setup {
+ if {[info exists foo]} {
+ unset foo
+ }
+ set fail $::tcltest::currentFailure
+ }
+ -body {
+ test tcltest-21.5.0 {foo-2} {
+ -setup {unset foo}
+ }
+ }
+ -result {^$}
+ -match regexp
+ -cleanup {set ::tcltest::currentFailure $fail}
+ -output "Test setup failed:.*can't unset \"foo\": no such variable"
+}
+
+test tcltest-21.6 {test command - setup occurs before cleanup & before script} {
+ -setup {set v [verbose]; set fail $::tcltest::currentFailure}
+ -body {
+ verbose {}
+ test tcltest-21.6.0 {foo-3} {
+ -setup {
+ if {[info exists foo]} {
+ unset foo
+ }
+ set foo 1
+ set expected 2
+ }
+ -body {
+ incr foo
+ set foo
+ }
+ -cleanup {
+ if {$foo != 2} {
+ puts [outputChannel] "foo is wrong"
+ } else {
+ puts [outputChannel] "foo is 2"
+ }
+ }
+ -result {$expected}
+ }
+ }
+ -cleanup {verbose $v; set ::tcltest::currentFailure $fail}
+ -result {^$}
+ -match regexp
+ -output "foo is 2"
+}
+
+test tcltest-21.7 {test command - bad flag} {
+ -setup {set fail $::tcltest::currentFailure}
+ -cleanup {set ::tcltest::currentFailure $fail}
+ -body {
+ test tcltest-21.7.0 {foo-4} {
+ -foobar {}
+ }
+ }
+ -returnCodes 1
+ -result {bad option "-foobar": must be -body, -cleanup, -constraints, -errorOutput, -match, -output, -result, -returnCodes, or -setup}
+}
+
+# alternate test command format (these are the same as 21.1-21.6, with the
+# exception of being in the all-inline format)
+
+test tcltest-21.7a {expect with glob} \
+ -body {list a b c d e} \
+ -result {[ab] b c d e} \
+ -match glob
+
+test tcltest-21.8 {force a test command failure} \
+ -setup {set fail $::tcltest::currentFailure} \
+ -body {
+ test tcltest-21.8.0 {
+ return 2
+ } {1}
+ } \
+ -returnCodes 1 \
+ -cleanup {set ::tcltest::currentFailure $fail} \
+ -result {bad option "1": must be -body, -cleanup, -constraints, -errorOutput, -match, -output, -result, -returnCodes, or -setup}
+
+test tcltest-21.9 {test command with setup} \
+ -setup {set foo 1} \
+ -body {set foo} \
+ -cleanup {unset foo} \
+ -result {1}
+
+test tcltest-21.10 {test command with cleanup failure} -setup {
+ if {[info exists foo]} {
+ unset foo
+ }
+ set fail $::tcltest::currentFailure
+ set v [verbose]
+} -cleanup {
+ verbose $v
+ set ::tcltest::currentFailure $fail
+} -body {
+ verbose {}
+ test tcltest-21.10.0 {foo-1} -cleanup {unset foo}
+} -result {^$} -match regexp \
+ -output {Test cleanup failed:.*can't unset \"foo\": no such variable}
+
+test tcltest-21.11 {test command with setup failure} -setup {
+ if {[info exists foo]} {
+ unset foo
+ }
+ set fail $::tcltest::currentFailure
+} -cleanup {set ::tcltest::currentFailure $fail} -body {
+ test tcltest-21.11.0 {foo-2} -setup {unset foo}
+} -result {^$} -output {Test setup failed:.*can't unset \"foo\": no such variable} -match regexp
+
+test tcltest-21.12 {
+ test command - setup occurs before cleanup & before script
+} -setup {
+ set fail $::tcltest::currentFailure
+ set v [verbose]
+} -cleanup {
+ verbose $v
+ set ::tcltest::currentFailure $fail
+} -body {
+ verbose {}
+ test tcltest-21.12.0 {foo-3} -setup {
+ if {[info exists foo]} {
+ unset foo
+ }
+ set foo 1
+ set expected 2
+ } -body {
+ incr foo
+ set foo
+ } -cleanup {
+ if {$foo != 2} {
+ puts [outputChannel] "foo is wrong"
+ } else {
+ puts [outputChannel] "foo is 2"
+ }
+ } -result {$expected}
+} -result {^$} -output {foo is 2} -match regexp
+
+# test all.tcl usage (runAllTests); simulate .test file failure, as well as
+# crashes to determine whether or not these errors are logged.
+
+set atd [makeDirectory alltestdir]
+makeFile {
+ package require tcltest
+ namespace import -force tcltest::*
+ testsDirectory [file join [temporaryDirectory] alltestdir]
+ runAllTests
+} all.tcl $atd
+makeFile {
+ exit 1
+} exit.test $atd
+makeFile {
+ error "throw an error"
+} error.test $atd
+makeFile {
+ package require tcltest
+ namespace import -force tcltest::*
+ test foo-1.1 {foo} {
+ -body { return 1 }
+ -result {1}
+ }
+ cleanupTests
+} test.test $atd
+
+# Must use a child process because stdout/stderr parsing can't be
+# duplicated in slave interp.
+test tcltest-22.1 {runAllTests} {
+ -constraints {unixOrPc}
+ -body {
+ exec [interpreter] \
+ [file join $atd all.tcl] \
+ -verbose t -tmpdir [temporaryDirectory]
+ }
+ -match regexp
+ -result "Test files exiting with errors:.*error.test.*exit.test"
+}
+removeDirectory alltestdir
+
+# makeFile, removeFile, makeDirectory, removeDirectory, viewFile
+test tcltest-23.1 {makeFile} {
+ -setup {
+ set mfdir [file join [temporaryDirectory] mfdir]
+ file mkdir $mfdir
+ }
+ -body {
+ makeFile {} t1.tmp
+ makeFile {} et1.tmp $mfdir
+ list [file exists [file join [temporaryDirectory] t1.tmp]] \
+ [file exists [file join $mfdir et1.tmp]]
+ }
+ -cleanup {
+ file delete -force $mfdir \
+ [file join [temporaryDirectory] t1.tmp]
+ }
+ -result {1 1}
+}
+test tcltest-23.2 {removeFile} {
+ -setup {
+ set mfdir [file join [temporaryDirectory] mfdir]
+ file mkdir $mfdir
+ makeFile {} t1.tmp
+ makeFile {} et1.tmp $mfdir
+ if {![file exists [file join [temporaryDirectory] t1.tmp]] || \
+ ![file exists [file join $mfdir et1.tmp]]} {
+ error "file creation didn't work"
+ }
+ }
+ -body {
+ removeFile t1.tmp
+ removeFile et1.tmp $mfdir
+ list [file exists [file join [temporaryDirectory] t1.tmp]] \
+ [file exists [file join $mfdir et1.tmp]]
+ }
+ -cleanup {
+ file delete -force $mfdir \
+ [file join [temporaryDirectory] t1.tmp]
+ }
+ -result {0 0}
+}
+test tcltest-23.3 {makeDirectory} {
+ -body {
+ set mfdir [file join [temporaryDirectory] mfdir]
+ file mkdir $mfdir
+ makeDirectory d1
+ makeDirectory d2 $mfdir
+ list [file exists [file join [temporaryDirectory] d1]] \
+ [file exists [file join $mfdir d2]]
+ }
+ -cleanup {
+ file delete -force [file join [temporaryDirectory] d1] $mfdir
+ }
+ -result {1 1}
+}
+test tcltest-23.4 {removeDirectory} {
+ -setup {
+ set mfdir [makeDirectory mfdir]
+ makeDirectory t1
+ makeDirectory t2 $mfdir
+ if {![file exists $mfdir] || \
+ ![file exists [file join [temporaryDirectory] $mfdir t2]]} {
+ error "setup failed - directory not created"
+ }
+ }
+ -body {
+ removeDirectory t1
+ removeDirectory t2 $mfdir
+ list [file exists [file join [temporaryDirectory] t1]] \
+ [file exists [file join $mfdir t2]]
+ }
+ -result {0 0}
+}
+test tcltest-23.5 {viewFile} {
+ -body {
+ set mfdir [file join [temporaryDirectory] mfdir]
+ file mkdir $mfdir
+ makeFile {foobar} t1.tmp
+ makeFile {foobarbaz} t2.tmp $mfdir
+ list [viewFile t1.tmp] [viewFile t2.tmp $mfdir]
+ }
+ -result {foobar foobarbaz}
+ -cleanup {
+ file delete -force $mfdir
+ removeFile t1.tmp
+ }
+}
+
+# customMatch
+proc matchNegative { expected actual } {
+ set match 0
+ foreach a $actual e $expected {
+ if { $a != $e } {
+ set match 1
+ break
+ }
+ }
+ return $match
+}
+
+test tcltest-24.0 {
+ customMatch: syntax
+} -body {
+ list [catch {customMatch} result] $result
+} -result [list 1 "wrong # args: should be \"customMatch mode script\""]
+
+test tcltest-24.1 {
+ customMatch: syntax
+} -body {
+ list [catch {customMatch foo} result] $result
+} -result [list 1 "wrong # args: should be \"customMatch mode script\""]
+
+test tcltest-24.2 {
+ customMatch: syntax
+} -body {
+ list [catch {customMatch foo bar baz} result] $result
+} -result [list 1 "wrong # args: should be \"customMatch mode script\""]
+
+test tcltest-24.3 {
+ customMatch: argument checking
+} -body {
+ list [catch {customMatch bad "a \{ b"} result] $result
+} -result [list 1 "invalid customMatch script; can't evaluate after completion"]
+
+test tcltest-24.4 {
+ test: valid -match values
+} -body {
+ list [catch {
+ test tcltest-24.4.0 {} \
+ -match [namespace current]::noSuchMode
+ } result] $result
+} -match glob -result {1 *bad -match value*}
+
+test tcltest-24.5 {
+ test: valid -match values
+} -setup {
+ customMatch [namespace current]::alwaysMatch "format 1 ;#"
+} -body {
+ list [catch {
+ test tcltest-24.5.0 {} \
+ -match [namespace current]::noSuchMode
+ } result] $result
+} -match glob -result {1 *bad -match value*: must be *alwaysMatch,*}
+
+test tcltest-24.6 {
+ customMatch: -match script that always matches
+} -setup {
+ customMatch [namespace current]::alwaysMatch "format 1 ;#"
+ set v [verbose]
+} -body {
+ verbose {}
+ test tcltest-24.6.0 {} -match [namespace current]::alwaysMatch \
+ -body {format 1} -result 0
+} -cleanup {
+ verbose $v
+} -result {} -output {} -errorOutput {}
+
+test tcltest-24.7 {
+ customMatch: replace default -exact matching
+} -setup {
+ set saveExactMatchScript $::tcltest::CustomMatch(exact)
+ customMatch exact "format 1 ;#"
+ set v [verbose]
+} -body {
+ verbose {}
+ test tcltest-24.7.0 {} -body {format 1} -result 0
+} -cleanup {
+ verbose $v
+ customMatch exact $saveExactMatchScript
+ unset saveExactMatchScript
+} -result {} -output {}
+
+test tcltest-24.9 {
+ customMatch: error during match
+} -setup {
+ proc errorDuringMatch args {return -code error "match returned error"}
+ customMatch [namespace current]::errorDuringMatch \
+ [namespace code errorDuringMatch]
+ set v [verbose]
+ set fail $::tcltest::currentFailure
+} -body {
+ verbose {}
+ test tcltest-24.9.0 {} -match [namespace current]::errorDuringMatch
+} -cleanup {
+ verbose $v
+ set ::tcltest::currentFailure $fail
+} -match glob -result {} -output {*FAILED*match returned error*}
+
+test tcltest-24.10 {
+ customMatch: bad return from match command
+} -setup {
+ proc nonBooleanReturn args {return foo}
+ customMatch nonBooleanReturn [namespace code nonBooleanReturn]
+ set v [verbose]
+ set fail $::tcltest::currentFailure
+} -body {
+ verbose {}
+ test tcltest-24.10.0 {} -match nonBooleanReturn
+} -cleanup {
+ verbose $v
+ set ::tcltest::currentFailure $fail
+} -match glob -result {} -output {*FAILED*expected boolean value*}
+
+test tcltest-24.11 {
+ test: -match exact
+} -body {
+ set result {A B C}
+} -match exact -result {A B C}
+
+test tcltest-24.12 {
+ test: -match exact match command eval in ::, not caller namespace
+} -setup {
+ set saveExactMatchScript $::tcltest::CustomMatch(exact)
+ customMatch exact [list string equal]
+ set v [verbose]
+ proc string args {error {called [string] in caller namespace}}
+} -body {
+ verbose {}
+ test tcltest-24.12.0 {} -body {format 1} -result 1
+} -cleanup {
+ rename string {}
+ verbose $v
+ customMatch exact $saveExactMatchScript
+ unset saveExactMatchScript
+} -match exact -result {} -output {}
+
+test tcltest-24.13 {
+ test: -match exact failure
+} -setup {
+ set saveExactMatchScript $::tcltest::CustomMatch(exact)
+ customMatch exact [list string equal]
+ set v [verbose]
+ set fail $::tcltest::currentFailure
+} -body {
+ verbose {}
+ test tcltest-24.13.0 {} -body {format 1} -result 0
+} -cleanup {
+ set ::tcltest::currentFailure $fail
+ verbose $v
+ customMatch exact $saveExactMatchScript
+ unset saveExactMatchScript
+} -match glob -result {} -output {*FAILED*Result was:
+1*(exact matching):
+0*}
+
+test tcltest-24.14 {
+ test: -match glob
+} -body {
+ set result {A B C}
+} -match glob -result {A B*}
+
+test tcltest-24.15 {
+ test: -match glob failure
+} -setup {
+ set v [verbose]
+ set fail $::tcltest::currentFailure
+} -body {
+ verbose {}
+ test tcltest-24.15.0 {} -match glob -body {format {A B C}} \
+ -result {A B* }
+} -cleanup {
+ set ::tcltest::currentFailure $fail
+ verbose $v
+} -match glob -result {} -output {*FAILED*Result was:
+*(glob matching):
+*}
+
+test tcltest-24.16 {
+ test: -match regexp
+} -body {
+ set result {A B C}
+} -match regexp -result {A B.*}
+
+test tcltest-24.17 {
+ test: -match regexp failure
+} -setup {
+ set fail $::tcltest::currentFailure
+ set v [verbose]
+} -body {
+ verbose {}
+ test tcltest-24.17.0 {} -match regexp -body {format {A B C}} \
+ -result {A B.* X}
+} -cleanup {
+ set ::tcltest::currentFailure $fail
+ verbose $v
+} -match glob -result {} -output {*FAILED*Result was:
+*(regexp matching):
+*}
+
+test tcltest-24.18 {
+ test: -match custom forget namespace qualification
+} -setup {
+ set fail $::tcltest::currentFailure
+ set v [verbose]
+ customMatch negative matchNegative
+} -body {
+ verbose {}
+ test tcltest-24.18.0 {} -match negative -body {format {A B C}} \
+ -result {A B X}
+} -cleanup {
+ set ::tcltest::currentFailure $fail
+ verbose $v
+} -match glob -result {} -output {*FAILED*Error testing result:*}
+
+test tcltest-24.19 {
+ test: -match custom
+} -setup {
+ set v [verbose]
+ customMatch negative [namespace code matchNegative]
+} -body {
+ verbose {}
+ test tcltest-24.19.0 {} -match negative -body {format {A B C}} \
+ -result {A B X}
+} -cleanup {
+ verbose $v
+} -match exact -result {} -output {}
+
+test tcltest-24.20 {
+ test: -match custom failure
+} -setup {
+ set fail $::tcltest::currentFailure
+ set v [verbose]
+ customMatch negative [namespace code matchNegative]
+} -body {
+ verbose {}
+ test tcltest-24.20.0 {} -match negative -body {format {A B C}} \
+ -result {A B C}
+} -cleanup {
+ set ::tcltest::currentFailure $fail
+ verbose $v
+} -match glob -result {} -output {*FAILED*Result was:
+*(negative matching):
+*}
+
+test tcltest-25.1 {
+ constraint of setup/cleanup (Bug 589859)
+} -setup {
+ set foo 0
+} -body {
+ # Buggy tcltest will generate result of 2
+ test tcltest-25.1.0 {} -constraints knownBug -setup {
+ incr foo
+ } -body {
+ incr foo
+ } -cleanup {
+ incr foo
+ } -match glob -result *
+ set foo
+} -cleanup {
+ unset foo
+} -result 0
+
+test tcltest-25.2 {
+ puts -nonewline (Bug 612786)
+} -body {
+ puts -nonewline stdout bla
+ puts -nonewline stdout bla
+} -output {blabla}
+
+test tcltest-25.3 {
+ reported return code (Bug 611922)
+} -setup {
+ set fail $::tcltest::currentFailure
+ set v [verbose]
+} -body {
+ verbose {}
+ test tcltest-25.3.0 {} -body {
+ error foo
+ }
+} -cleanup {
+ set ::tcltest::currentFailure $fail
+ verbose $v
+} -match glob -output {*generated error; Return code was: 1*}
+
+test tcltest-26.1 {Bug/RFE 1017151} -setup {
+ makeFile {
+ package require tcltest
+ set ::errorInfo "Should never see this"
+ tcltest::test tcltest-26.1.0 {
+ no errorInfo when only return code mismatch
+ } -body {
+ set x 1
+ } -returnCodes error -result 1
+ tcltest::cleanupTests
+ } test.tcl
+} -body {
+ slave msg [file join [temporaryDirectory] test.tcl]
+ return $msg
+} -cleanup {
+ removeFile test.tcl
+} -match glob -result {*
+---- Return code should have been one of: 1
+==== tcltest-26.1.0 FAILED*}
+
+test tcltest-26.2 {Bug/RFE 1017151} -setup {
+ makeFile {
+ package require tcltest
+ set ::errorInfo "Should never see this"
+ tcltest::test tcltest-26.2.0 {do not mask body errorInfo} -body {
+ error "body error"
+ } -cleanup {
+ error "cleanup error"
+ } -result 1
+ tcltest::cleanupTests
+ } test.tcl
+} -body {
+ slave msg [file join [temporaryDirectory] test.tcl]
+ return $msg
+} -cleanup {
+ removeFile test.tcl
+} -match glob -result {*
+---- errorInfo: body error
+*
+---- errorInfo(cleanup): cleanup error*}
+
+cleanupTests
+}
+
+namespace delete ::tcltest::test
+return
diff --git a/library/msgcat/tests/thread.test b/library/msgcat/tests/thread.test
new file mode 100644
index 0000000..44789fa
--- /dev/null
+++ b/library/msgcat/tests/thread.test
@@ -0,0 +1,1436 @@
+# Commands covered: (test)thread
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2006-2008 by Joe Mistachkin. All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2.2
+ namespace import -force ::tcltest::*
+}
+
+# Some tests require the testthread command
+
+testConstraint testthread [expr {[info commands testthread] != {}}]
+
+# Some tests require the Thread package
+
+testConstraint thread [expr {0 == [catch {package require Thread 2.7}]}]
+
+# Some tests may not work under valgrind
+
+testConstraint notValgrind [expr {![testConstraint valgrind]}]
+
+set threadSuperKillScript {
+ rename catch ""
+ rename while ""
+ rename unknown ""
+ rename update ""
+ thread::release
+}
+
+proc getThreadErrorFromInfo { info } {
+ set list [split $info \n]
+ set idx [lsearch -glob $list "*eval*unwound*"]
+ if {$idx != -1} then {
+ return [lindex $list $idx]
+ }
+ set idx [lsearch -glob $list "*eval*canceled*"]
+ if {$idx != -1} then {
+ return [lindex $list $idx]
+ }
+ return ""; # some other error we do not care about.
+}
+
+proc findThreadError { info } {
+ foreach error [lreverse $info] {
+ set error [getThreadErrorFromInfo $error]
+ if {[string length $error] > 0} then {
+ return $error
+ }
+ }
+ return ""; # some other error we do not care about.
+}
+
+proc ThreadError {id info} {
+ global threadSawError
+ if {[string length [getThreadErrorFromInfo $info]] > 0} then {
+ global threadId threadError
+ set threadId $id
+ lappend threadError($id) $info
+ }
+ set threadSawError($id) true; # signal main thread to exit [vwait].
+}
+
+if {[testConstraint thread]} {
+ thread::errorproc ThreadError
+}
+
+if {[testConstraint testthread]} {
+ proc drainEventQueue {} {
+ while {[set x [testthread event]]} {
+ puts "WARNING: drained $x event(s) on main thread"
+ }
+ }
+
+ testthread errorproc ThreadError
+
+ set mainThread [testthread id]
+
+ proc ThreadNullError {id info} {
+ # ignore
+ }
+
+ proc threadReap {} {
+ testthread errorproc ThreadNullError
+ while {[llength [testthread names]] > 1} {
+ foreach tid [testthread names] {
+ if {$tid != [testthread id]} {
+ catch {
+ testthread send -async $tid {testthread exit}
+ }
+ }
+ }
+ after 1
+ }
+ testthread errorproc ThreadError
+ return [llength [testthread names]]
+ }
+}
+
+# Some tests require manual draining of the event queue
+
+testConstraint drainEventQueue [expr {[info commands drainEventQueue] != {}}]
+
+test thread-1.3 {Tcl_ThreadObjCmd: initial thread list} {thread} {
+ llength [thread::names]
+} 1
+test thread-1.4 {Tcl_ThreadObjCmd: thread create } {thread} {
+ set serverthread [thread::create -preserved]
+ set numthreads [llength [thread::names]]
+ thread::release $serverthread
+ set numthreads
+} {2}
+test thread-1.5 {Tcl_ThreadObjCmd: thread create one shot} {thread} {
+ thread::create {set x 5}
+ foreach try {0 1 2 4 5 6} {
+ # Try various ways to yield
+ update
+ after 10
+ set l [llength [thread::names]]
+ if {$l == 1} {
+ break
+ }
+ }
+ set l
+} {1}
+test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {thread} {
+ thread::create {{*}{}}
+ update
+ after 10
+ llength [thread::names]
+} {1}
+test thread-1.13 {Tcl_ThreadObjCmd: send args} {thread} {
+ set serverthread [thread::create -preserved]
+ set five [thread::send $serverthread {set x 5}]
+ thread::release $serverthread
+ set five
+} 5
+test thread-1.15 {Tcl_ThreadObjCmd: wait} {thread} {
+ set serverthread [thread::create -preserved {set z 5 ; thread::wait}]
+ set five [thread::send $serverthread {set z}]
+ thread::release $serverthread
+ set five
+} 5
+
+# The tests above also cover:
+# TclCreateThread, except when pthread_create fails
+# NewThread, safe and regular
+# ThreadErrorProc, except for printing to standard error
+
+test thread-2.1 {ListUpdateInner and ListRemove} {thread} {
+ catch {unset tid}
+ foreach t {0 1 2} {
+ upvar #0 t$t tid
+ set tid [thread::create -preserved]
+ }
+ foreach t {0 1 2} {
+ upvar #0 t$t tid
+ thread::release $tid
+ }
+ llength [thread::names]
+} 1
+
+test thread-3.1 {TclThreadList} {thread} {
+ catch {unset tid}
+ set len [llength [thread::names]]
+ set l1 {}
+ foreach t {0 1 2} {
+ lappend l1 [thread::create -preserved]
+ }
+ set l2 [thread::names]
+ set c [string compare [lsort [concat [thread::id] $l1]] [lsort $l2]]
+ foreach t $l1 {
+ thread::release $t
+ }
+ list $len $c
+} {1 0}
+
+test thread-4.1 {TclThreadSend to self} {thread} {
+ catch {unset x}
+ thread::send [thread::id] {
+ set x 4
+ }
+ set x
+} {4}
+test thread-4.2 {TclThreadSend -async} {thread} {
+ set len [llength [thread::names]]
+ set serverthread [thread::create -preserved]
+ thread::send -async $serverthread {
+ after 1 {thread::release}
+ }
+ set two [llength [thread::names]]
+ after 100 {set done 1}
+ vwait done
+ list $len [llength [thread::names]] $two
+} {1 1 2}
+test thread-4.3 {TclThreadSend preserve errorInfo} {thread} {
+ set len [llength [thread::names]]
+ set serverthread [thread::create -preserved]
+ set x [catch {thread::send $serverthread {set undef}} msg]
+ set savedErrorInfo $::errorInfo
+ thread::release $serverthread
+ list $len $x $msg $savedErrorInfo
+} {1 1 {can't read "undef": no such variable} {can't read "undef": no such variable
+ while executing
+"set undef"
+ invoked from within
+"thread::send $serverthread {set undef}"}}
+test thread-4.4 {TclThreadSend preserve code} {thread} {
+ set len [llength [thread::names]]
+ set serverthread [thread::create -preserved]
+ set ::errorInfo {}
+ set x [catch {thread::send $serverthread {set ::errorInfo {}; break}} msg]
+ set savedErrorInfo $::errorInfo
+ thread::release $serverthread
+ list $len $x $msg $savedErrorInfo
+} {1 3 {} {}}
+test thread-4.5 {TclThreadSend preserve errorCode} {thread} {
+ set serverthread [thread::create]
+ set x [catch {thread::send $serverthread {error ERR INFO CODE}} msg]
+ set savedErrorCode $::errorCode
+ thread::release $serverthread
+ list $x $msg $savedErrorCode
+} {1 ERR CODE}
+
+
+test thread-5.0 {Joining threads} {thread} {
+ set serverthread [thread::create -joinable -preserved]
+ thread::send -async $serverthread {after 1000 ; thread::release}
+ thread::join $serverthread
+} {0}
+test thread-5.1 {Joining threads after the fact} {thread} {
+ set serverthread [thread::create -joinable -preserved]
+ thread::send -async $serverthread {thread::release}
+ after 2000
+ thread::join $serverthread
+} {0}
+test thread-5.2 {Try to join a detached thread} {thread} {
+ set serverthread [thread::create -preserved]
+ thread::send -async $serverthread {after 1000 ; thread::release}
+ catch {set res [thread::join $serverthread]} msg
+ while {[llength [thread::names]] > 1} {
+ after 20
+ }
+ lrange $msg 0 2
+} {cannot join thread}
+
+test thread-6.1 {freeing very large object trees in a thread} thread {
+ # conceptual duplicate of obj-32.1
+ set serverthread [thread::create -preserved]
+ thread::send -async $serverthread {
+ set x {}
+ for {set i 0} {$i<100000} {incr i} {
+ set x [list $x {}]
+ }
+ unset x
+ }
+ thread::release -wait $serverthread
+} 0
+
+# TIP #285: Script cancellation support
+test thread-7.4 {cancel: pure bytecode loop} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ while {1} {
+ # No bytecode at all here...
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.5 {cancel: pure inside-command loop} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ set while while
+ $while {1} {
+ # No bytecode at all here...
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.6 {cancel: pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ while {1} {
+ # No bytecode at all here...
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.7 {cancel: pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ set while while
+ $while {1} {
+ # No bytecode at all here...
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.8 {cancel: pure bytecode loop custom result} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ while {1} {
+ # No bytecode at all here...
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread "the eval was canceled"]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {the eval was canceled}}
+test thread-7.9 {cancel: pure inside-command loop custom result} -constraints {
+ thread
+ drainEventQueue
+} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ set while while
+ $while {1} {
+ # No bytecode at all here...
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread "the eval was canceled"]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {the eval was canceled}}
+test thread-7.10 {cancel: pure bytecode loop custom result -unwind} -constraints {
+ thread
+ drainEventQueue
+} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ while {1} {
+ # No bytecode at all here...
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread "the eval was unwound"]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {the eval was unwound}}
+test thread-7.11 {cancel: pure inside-command loop custom result -unwind} -constraints {
+ thread
+ drainEventQueue
+} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ set while while
+ $while {1} {
+ # No bytecode at all here...
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread "the eval was unwound"]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {the eval was unwound}}
+test thread-7.12 {cancel: after} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ after 30000
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.13 {cancel: after -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ after 30000
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.14 {cancel: vwait} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID [thread::id]] {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ vwait forever
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.15 {cancel: vwait -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ vwait forever
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.16 {cancel: expr} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ expr {[while {1} {incr x}]}
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.17 {cancel: expr -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ expr {[while {1} {incr x}]}
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.18 {cancel: expr bignum} {thread drainEventQueue knownBug} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ #
+ # BUGBUG: This will not cancel because libtommath
+ # does not check Tcl_Canceled.
+ #
+ expr {2**99999}
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted; after 1000
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread); # WARNING: Never returns (see above).
+ thread::join $serverthread; drainEventQueue; # WARNING: Never returns (see above).
+ list $res [expr {[info exists ::threadIdStarted] ? \
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 0 {}}
+test thread-7.19 {cancel: expr bignum -unwind} {thread drainEventQueue knownBug} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ #
+ # BUGBUG: This will not cancel because libtommath
+ # does not check Tcl_Canceled.
+ #
+ expr {2**99999}
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted; after 1000
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread); # WARNING: Never returns (see above).
+ thread::join $serverthread; drainEventQueue; # WARNING: Never returns (see above).
+ list $res [expr {[info exists ::threadIdStarted] ? \
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 0 {}}
+test thread-7.20 {cancel: subst} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ subst {[while {1} {incr x}]}
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.21 {cancel: subst -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ subst {[while {1} {incr x}]}
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.22 {cancel: slave interp} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ while {1} {}
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.23 {cancel: slave interp -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ set while while; $while {1} {}
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.24 {cancel: nested catch inside pure bytecode loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ catch {
+ while {1} {
+ catch {
+ while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted; after 1000
+ set res [thread::cancel $serverthread]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {[info exists ::threadIdStarted] ? \
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 0 {}}
+test thread-7.25 {cancel: nested catch inside pure inside-command loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ set catch catch
+ set while while
+ $while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ $catch {
+ $while {1} {
+ $catch {
+ $while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted; after 1000
+ set res [thread::cancel $serverthread]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {[info exists ::threadIdStarted] ? \
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 0 {}}
+test thread-7.26 {cancel: send async cancel bad interp path} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ update
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ catch {thread::send $serverthread {interp cancel -- bad}} msg
+ thread::send -async $serverthread {interp cancel -unwind}
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list [expr {$::threadIdStarted == $serverthread}] $msg
+} {1 {could not find interpreter "bad"}}
+test thread-7.27 {cancel: send async cancel -- switch} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create -- -unwind]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ proc foobar {} {
+ while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ update
+ }
+ }
+ foobar
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::send -async $serverthread {interp cancel -- -unwind}]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.28 {cancel: send async cancel nested catch inside pure bytecode loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ catch {
+ while {1} {
+ catch {
+ while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted; after 1000
+ set res [thread::send -async $serverthread {interp cancel}]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {[info exists ::threadIdStarted] ? \
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 1 {eval canceled}}
+test thread-7.29 {cancel: send async cancel nested catch pure inside-command loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ set catch catch
+ set while while
+ $while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ $catch {
+ $while {1} {
+ $catch {
+ $while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted; after 1000
+ set res [thread::send -async $serverthread {interp cancel}]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {[info exists ::threadIdStarted] ? \
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 1 {eval canceled}}
+test thread-7.30 {cancel: send async thread cancel nested catch inside pure bytecode loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ catch {
+ while {1} {
+ catch {
+ while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted; after 1000
+ set res [thread::send -async $serverthread {thread::cancel [thread::id]}]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {[info exists ::threadIdStarted] ? \
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 1 {eval canceled}}
+test thread-7.31 {cancel: send async thread cancel nested catch pure inside-command loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ set catch catch
+ set while while
+ $while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ $catch {
+ $while {1} {
+ $catch {
+ $while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted; after 1000
+ set res [thread::send -async $serverthread {thread::cancel [thread::id]}]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {[info exists ::threadIdStarted] ? \
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 1 {eval canceled}}
+test thread-7.32 {cancel: nested catch inside pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ catch {
+ while {1} {
+ catch {
+ while {1} {
+ # No bytecode at all here...
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.33 {cancel: nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ set catch catch
+ set while while
+ $while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ $catch {
+ $while {1} {
+ $catch {
+ $while {1} {
+ # No bytecode at all here...
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.34 {cancel: send async cancel nested catch inside pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ catch {
+ while {1} {
+ catch {
+ while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::send -async $serverthread {interp cancel -unwind}]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.35 {cancel: send async cancel nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ set catch catch
+ set while while
+ $while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ $catch {
+ $while {1} {
+ $catch {
+ $while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::send -async $serverthread {interp cancel -unwind}]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.36 {cancel: send async thread cancel nested catch inside pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ catch {
+ while {1} {
+ catch {
+ while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::send -async $serverthread {thread::cancel -unwind [thread::id]}]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.37 {cancel: send async thread cancel nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID [thread::id]] {
+ proc foobar {} {
+ set catch catch
+ set while while
+ $while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ $catch {
+ $while {1} {
+ $catch {
+ $while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::send -async $serverthread {thread::cancel -unwind [thread::id]}]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/timer.test b/library/msgcat/tests/timer.test
new file mode 100644
index 0000000..ab6efc9
--- /dev/null
+++ b/library/msgcat/tests/timer.test
@@ -0,0 +1,605 @@
+# This file contains a collection of tests for the procedures in the
+# file tclTimer.c, which includes the "after" Tcl command. Sourcing
+# this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+test timer-1.1 {Tcl_CreateTimerHandler procedure} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x ""
+ foreach i {100 200 1000 50 150} {
+ after $i lappend x $i
+ }
+ after 200 set done 1
+ vwait done
+ return $x
+} -cleanup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {50 100 150 200}
+
+test timer-2.1 {Tcl_DeleteTimerHandler procedure} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x ""
+ foreach i {100 200 1000 50 150} {
+ after $i lappend x $i
+ }
+ after cancel lappend x 150
+ after cancel lappend x 50
+ after 200 set done 1
+ vwait done
+ return $x
+} -result {100 200}
+
+# No tests for Tcl_ServiceTimer or ResetTimer, since it is already tested
+# above.
+
+test timer-3.1 {TimerHandlerEventProc procedure: event masks} {
+ set x start
+ after 100 { set x fired }
+ update idletasks
+ set result $x
+ after 200
+ update
+ lappend result $x
+} {start fired}
+test timer-3.2 {TimerHandlerEventProc procedure: multiple timers} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ foreach i {200 600 1000} {
+ after $i lappend x $i
+ }
+ after 200
+ set result ""
+ set x ""
+ update
+ lappend result $x
+ after 400
+ update
+ lappend result $x
+ after 400
+ update
+ lappend result $x
+} -result {200 {200 600} {200 600 1000}}
+test timer-3.3 {TimerHandlerEventProc procedure: reentrant timer deletion} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x {}
+ after 100 lappend x 100
+ set i [after 300 lappend x 300]
+ after 200 after cancel $i
+ after 400
+ update
+ return $x
+} -result 100
+test timer-3.4 {TimerHandlerEventProc procedure: all expired timers fire} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x {}
+ after 100 lappend x a
+ after 200 lappend x b
+ after 300 lappend x c
+ after 300
+ vwait x
+ return $x
+} -result {a b c}
+test timer-3.5 {TimerHandlerEventProc procedure: reentrantly added timers don't fire} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x {}
+ after 100 {lappend x a; after 0 lappend x b}
+ after 100
+ vwait x
+ return $x
+} -result a
+test timer-3.6 {TimerHandlerEventProc procedure: reentrantly added timers don't fire} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x {}
+ after 100 {lappend x a; after 100 lappend x b; after 100}
+ after 100
+ vwait x
+ set result $x
+ vwait x
+ lappend result $x
+} -result {a {a b}}
+
+# No tests for Tcl_DoWhenIdle: it's already tested by other tests
+# below.
+
+test timer-4.1 {Tcl_CancelIdleCall procedure} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x before
+ set y before
+ set z before
+ after idle set x after1
+ after idle set y after2
+ after idle set z after3
+ after cancel set y after2
+ update idletasks
+ list $x $y $z
+} -result {after1 before after3}
+test timer-4.2 {Tcl_CancelIdleCall procedure} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x before
+ set y before
+ set z before
+ after idle set x after1
+ after idle set y after2
+ after idle set z after3
+ after cancel set x after1
+ update idletasks
+ list $x $y $z
+} -result {before after2 after3}
+
+test timer-5.1 {Tcl_ServiceIdle, self-rescheduling handlers} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x 1
+ set y 23
+ after idle {incr x; after idle {incr x; after idle {incr x}}}
+ after idle {incr y}
+ vwait x
+ set result "$x $y"
+ update idletasks
+ lappend result $x
+} -result {2 24 4}
+
+test timer-6.1 {Tcl_AfterCmd procedure, basics} -returnCodes error -body {
+ after
+} -result {wrong # args: should be "after option ?arg ...?"}
+test timer-6.2 {Tcl_AfterCmd procedure, basics} -returnCodes error -body {
+ after 2x
+} -result {bad argument "2x": must be cancel, idle, info, or an integer}
+test timer-6.3 {Tcl_AfterCmd procedure, basics} -returnCodes error -body {
+ after gorp
+} -result {bad argument "gorp": must be cancel, idle, info, or an integer}
+test timer-6.4 {Tcl_AfterCmd procedure, ms argument} {
+ set x before
+ after 400 {set x after}
+ after 200
+ update
+ set y $x
+ after 400
+ update
+ list $y $x
+} {before after}
+test timer-6.5 {Tcl_AfterCmd procedure, ms argument} {
+ set x before
+ after 300 set x after
+ after 200
+ update
+ set y $x
+ after 200
+ update
+ list $y $x
+} {before after}
+test timer-6.6 {Tcl_AfterCmd procedure, cancel option} -body {
+ after cancel
+} -returnCodes error -result {wrong # args: should be "after cancel id|command"}
+test timer-6.7 {Tcl_AfterCmd procedure, cancel option} {
+ after cancel after#1
+} {}
+test timer-6.8 {Tcl_AfterCmd procedure, cancel option} {
+ after cancel {foo bar}
+} {}
+test timer-6.9 {Tcl_AfterCmd procedure, cancel option} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x before
+ set y [after 100 set x after]
+ after cancel $y
+ after 200
+ update
+ return $x
+} -result {before}
+test timer-6.10 {Tcl_AfterCmd procedure, cancel option} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x before
+ after 100 set x after
+ after cancel {set x after}
+ after 200
+ update
+ return $x
+} -result {before}
+test timer-6.11 {Tcl_AfterCmd procedure, cancel option} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x before
+ after 100 set x after
+ set id [after 300 set x after]
+ after cancel $id
+ after 200
+ update
+ set y $x
+ set x cleared
+ after 200
+ update
+ list $y $x
+} -result {after cleared}
+test timer-6.12 {Tcl_AfterCmd procedure, cancel option} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x first
+ after idle lappend x second
+ after idle lappend x third
+ set i [after idle lappend x fourth]
+ after cancel {lappend x second}
+ after cancel $i
+ update idletasks
+ return $x
+} -result {first third}
+test timer-6.13 {Tcl_AfterCmd procedure, cancel option, multiple arguments for command} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x first
+ after idle lappend x second
+ after idle lappend x third
+ set i [after idle lappend x fourth]
+ after cancel lappend x second
+ after cancel $i
+ update idletasks
+ return $x
+} -result {first third}
+test timer-6.14 {Tcl_AfterCmd procedure, cancel option, cancel during handler, used to dump core} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set id [
+ after 100 {
+ set x done
+ after cancel $id
+ }
+ ]
+ vwait x
+} -result {}
+test timer-6.15 {Tcl_AfterCmd procedure, cancel option, multiple interps} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ interp create x
+ x eval {set a before; set b before; after idle {set a a-after};
+ after idle {set b b-after}}
+ set result [llength [x eval after info]]
+ lappend result [llength [after info]]
+ after cancel {set b b-after}
+ set a aaa
+ set b bbb
+ x eval {after cancel set a a-after}
+ update idletasks
+ lappend result $a $b [x eval {list $a $b}]
+} -cleanup {
+ interp delete x
+} -result {2 0 aaa bbb {before b-after}}
+test timer-6.16 {Tcl_AfterCmd procedure, idle option} -body {
+ after idle
+} -returnCodes error -result {wrong # args: should be "after idle script ?script ...?"}
+test timer-6.17 {Tcl_AfterCmd procedure, idle option} {
+ set x before
+ after idle {set x after}
+ set y $x
+ update idletasks
+ list $y $x
+} {before after}
+test timer-6.18 {Tcl_AfterCmd procedure, idle option} {
+ set x before
+ after idle set x after
+ set y $x
+ update idletasks
+ list $y $x
+} {before after}
+
+set event1 [after idle event 1]
+set event2 [after 1000 event 2]
+interp create x
+set childEvent [x eval {after idle event in child}]
+test timer-6.19 {Tcl_AfterCmd, info option} {
+ lsort [after info]
+} [lsort "$event1 $event2"]
+test timer-6.20 {Tcl_AfterCmd, info option} -returnCodes error -body {
+ after info a b
+} -result {wrong # args: should be "after info ?id?"}
+test timer-6.21 {Tcl_AfterCmd, info option} -returnCodes error -body {
+ after info $childEvent
+} -result "event \"$childEvent\" doesn't exist"
+test timer-6.22 {Tcl_AfterCmd, info option} {
+ list [after info $event1] [after info $event2]
+} {{{event 1} idle} {{event 2} timer}}
+after cancel $event1
+after cancel $event2
+interp delete x
+
+test timer-6.23 {Tcl_AfterCmd procedure, no option, script with NUL} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x "hello world"
+ after 1 "set x ab\0cd"
+ after 10
+ update
+ string length $x
+} -result {5}
+test timer-6.24 {Tcl_AfterCmd procedure, no option, script with NUL} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x "hello world"
+ after 1 set x ab\0cd
+ after 10
+ update
+ string length $x
+} -result {5}
+test timer-6.25 {Tcl_AfterCmd procedure, cancel option, script with NUL} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x "hello world"
+ after 1 set x ab\0cd
+ after cancel "set x ab\0ef"
+ llength [after info]
+} -cleanup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {1}
+test timer-6.26 {Tcl_AfterCmd procedure, cancel option, script with NUL} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x "hello world"
+ after 1 set x ab\0cd
+ after cancel set x ab\0ef
+ llength [after info]
+} -cleanup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {1}
+test timer-6.27 {Tcl_AfterCmd procedure, idle option, script with NUL} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x "hello world"
+ after idle "set x ab\0cd"
+ update
+ string length $x
+} -result {5}
+test timer-6.28 {Tcl_AfterCmd procedure, idle option, script with NUL} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x "hello world"
+ after idle set x ab\0cd
+ update
+ string length $x
+} -result {5}
+test timer-6.29 {Tcl_AfterCmd procedure, info option, script with NUL} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x "hello world"
+ set id junk
+ set id [after 10 set x ab\0cd]
+ update
+ string length [lindex [lindex [after info $id] 0] 2]
+} -cleanup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result 5
+
+set event [after idle foo bar]
+scan $event after#%d lastId
+test timer-7.1 {GetAfterEvent procedure} -returnCodes error -body {
+ after info xfter#$lastId
+} -result "event \"xfter#$lastId\" doesn't exist"
+test timer-7.2 {GetAfterEvent procedure} -returnCodes error -body {
+ after info afterx$lastId
+} -result "event \"afterx$lastId\" doesn't exist"
+test timer-7.3 {GetAfterEvent procedure} -returnCodes error -body {
+ after info after#ab
+} -result {event "after#ab" doesn't exist}
+test timer-7.4 {GetAfterEvent procedure} -returnCodes error -body {
+ after info after#
+} -result {event "after#" doesn't exist}
+test timer-7.5 {GetAfterEvent procedure} -returnCodes error -body {
+ after info after#${lastId}x
+} -result "event \"after#${lastId}x\" doesn't exist"
+test timer-7.6 {GetAfterEvent procedure} -returnCodes error -body {
+ after info afterx[expr {$lastId+1}]
+} -result "event \"afterx[expr {$lastId+1}]\" doesn't exist"
+after cancel $event
+
+test timer-8.1 {AfterProc procedure} {
+ set x before
+ proc foo {} {
+ set x untouched
+ after 100 {set x after}
+ after 200
+ update
+ return $x
+ }
+ list [foo] $x
+} {untouched after}
+test timer-8.2 {AfterProc procedure} -setup {
+ variable x empty
+ proc myHandler {msg options} {
+ variable x [list $msg [dict get $options -errorinfo]]
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+} -body {
+ after 100 {error "After error"}
+ after 200
+ set y $x
+ update
+ list $y $x
+} -cleanup {
+ interp bgerror {} $handler
+} -result {empty {{After error} {After error
+ while executing
+"error "After error""
+ ("after" script)}}}
+test timer-8.3 {AfterProc procedure, deleting handler from itself} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ proc foo {} {
+ global x
+ set x {}
+ foreach i [after info] {
+ lappend x [after info $i]
+ }
+ after cancel foo
+ }
+ after idle foo
+ after 1000 {error "I shouldn't ever have executed"}
+ update idletasks
+ return $x
+} -result {{{error "I shouldn't ever have executed"} timer}}
+test timer-8.4 {AfterProc procedure, deleting handler from itself} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ proc foo {} {
+ global x
+ set x {}
+ foreach i [after info] {
+ lappend x [after info $i]
+ }
+ after cancel foo
+ }
+ after 1000 {error "I shouldn't ever have executed"}
+ after idle foo
+ update idletasks
+ return $x
+} -result {{{error "I shouldn't ever have executed"} timer}}
+
+foreach i [after info] {
+ after cancel $i
+}
+
+# No test for FreeAfterPtr, since it is already tested above.
+
+test timer-9.1 {AfterCleanupProc procedure} -setup {
+ catch {interp delete x}
+} -body {
+ interp create x
+ x eval {after 200 {
+ lappend x after
+ puts "part 1: this message should not appear"
+ }}
+ after 200 {lappend x after2}
+ x eval {after 200 {
+ lappend x after3
+ puts "part 2: this message should not appear"
+ }}
+ after 200 {lappend x after4}
+ x eval {after 200 {
+ lappend x after5
+ puts "part 3: this message should not appear"
+ }}
+ interp delete x
+ set x before
+ after 300
+ update
+ return $x
+} -result {before after2 after4}
+
+test timer-10.1 {Bug 1016167: [after] overwrites imports} -setup {
+ interp create slave
+ slave eval namespace export after
+ slave eval namespace eval foo namespace import ::after
+} -body {
+ slave eval foo::after 1
+ slave eval namespace origin foo::after
+} -cleanup {
+ # Bug will cause crash here; would cause failure otherwise
+ interp delete slave
+} -result ::after
+
+test timer-11.1 {Bug 1350291: [after] overflowing 32-bit field} -body {
+ set b ok
+ set a [after 0x100000001 {set b "after fired early"}]
+ after 100 set done 1
+ vwait done
+ return $b
+} -cleanup {
+ catch {after cancel $a}
+} -result ok
+test timer-11.2 {Bug 1350293: [after] negative argument} -body {
+ set l {}
+ after 100 {lappend l 100; set done 1}
+ after -1 {lappend l -1}
+ vwait done
+ return $l
+} -result {-1 100}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/tm.test b/library/msgcat/tests/tm.test
new file mode 100644
index 0000000..149a65d
--- /dev/null
+++ b/library/msgcat/tests/tm.test
@@ -0,0 +1,245 @@
+# This file contains tests for the ::tcl::tm::* commands.
+#
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 2004 by Donal K. Fellows.
+# All rights reserved.
+
+package require Tcl 8.5
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+test tm-1.1 {tm: path command exists} {
+ catch { ::tcl::tm::path }
+ info commands ::tcl::tm::path
+} ::tcl::tm::path
+test tm-1.2 {tm: path command syntax} -returnCodes error -body {
+ ::tcl::tm::path foo
+} -result {unknown or ambiguous subcommand "foo": must be add, list, or remove}
+test tm-1.3 {tm: path command syntax} {
+ ::tcl::tm::path add
+} {}
+test tm-1.4 {tm: path command syntax} {
+ ::tcl::tm::path remove
+} {}
+test tm-1.5 {tm: path command syntax} -returnCodes error -body {
+ ::tcl::tm::path list foobar
+} -result "wrong # args: should be \"::tcl::tm::path list\""
+
+test tm-2.1 {tm: roots command exists} {
+ catch { ::tcl::tm::roots }
+ info commands ::tcl::tm::roots
+} ::tcl::tm::roots
+test tm-2.2 {tm: roots command syntax} -returnCodes error -body {
+ ::tcl::tm::roots
+} -result "wrong # args: should be \"::tcl::tm::roots paths\""
+test tm-2.3 {tm: roots command syntax} -returnCodes error -body {
+ ::tcl::tm::roots foo bar
+} -result "wrong # args: should be \"::tcl::tm::roots paths\""
+
+
+test tm-3.1 {tm: module path management, input validation} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -returnCodes error -body {
+ ::tcl::tm::path add foo/bar
+ ::tcl::tm::path add foo
+} -result {foo is ancestor of existing module path foo/bar.}
+
+test tm-3.2 {tm: module path management, input validation} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -returnCodes error -body {
+ ::tcl::tm::path add foo
+ ::tcl::tm::path add foo/bar
+} -result {foo/bar is subdirectory of existing module path foo.}
+
+test tm-3.3 {tm: module path management, add/list interaction} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ ::tcl::tm::path add foo
+ ::tcl::tm::path add bar
+ ::tcl::tm::path list
+} -result {bar foo}
+
+test tm-3.4 {tm: module path management, add/list interaction} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ ::tcl::tm::path add foo bar baz
+ ::tcl::tm::path list
+} -result {baz bar foo}
+
+test tm-3.5 {tm: module path management, input validation/list interaction} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ catch {::tcl::tm::path add snarf foo geode foo/bar}
+ # Nothing is added if a problem was found.
+ ::tcl::tm::path list
+} -result {}
+
+test tm-3.6 {tm: module path management, input validation/list interaction} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ catch {::tcl::tm::path add snarf foo/bar geode foo}
+ # Nothing is added if a problem was found.
+ ::tcl::tm::path list
+} -result {}
+
+test tm-3.7 {tm: module path management, input validation/list interaction} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ catch {
+ ::tcl::tm::path add foo/bar
+ ::tcl::tm::path add snarf geode foo
+ }
+ # Nothing is added if a problem was found.
+ ::tcl::tm::path list
+} -result {foo/bar}
+
+test tm-3.8 {tm: module path management, input validation, ignore duplicates} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ # Ignore path if present
+ ::tcl::tm::path add foo
+ ::tcl::tm::path add snarf geode foo
+ ::tcl::tm::path list
+} -result {geode snarf foo}
+
+test tm-3.9 {tm: module path management, input validation, ignore duplicates} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ # Ignore path if present
+ ::tcl::tm::path add foo snarf geode foo
+ ::tcl::tm::path list
+} -result {geode snarf foo}
+
+test tm-3.10 {tm: module path management, remove} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ ::tcl::tm::path add snarf geode foo
+ ::tcl::tm::path remove foo
+ ::tcl::tm::path list
+} -result {geode snarf}
+
+test tm-3.11 {tm: module path management, remove ignores unknown path} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ ::tcl::tm::path add foo snarf geode
+ ::tcl::tm::path remove fox
+ ::tcl::tm::path list
+} -result {geode snarf foo}
+
+
+proc genpaths {base} {
+ # Normalizing picks up drive letters on windows [Bug 1053568]
+ set base [file normalize $base]
+ foreach {major minor} [split [info tclversion] .] break
+ set results {}
+ set base [file join $base tcl$major]
+ lappend results [file join $base site-tcl]
+ for {set i 0} {$i <= $minor} {incr i} {
+ lappend results [file join $base ${major}.$i]
+ }
+ return $results
+}
+
+test tm-3.12 {tm: module path management, roots} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ ::tcl::tm::roots /FOO
+ ::tcl::tm::path list
+} -result [genpaths /FOO]
+
+test tm-3.13 {tm: module path management, roots} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ ::tcl::tm::roots [list /FOO /BAR]
+ ::tcl::tm::path list
+} -result [concat [genpaths /BAR] [genpaths /FOO]]
+
+rename genpaths {}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/trace.test b/library/msgcat/tests/trace.test
new file mode 100644
index 0000000..693dbad
--- /dev/null
+++ b/library/msgcat/tests/trace.test
@@ -0,0 +1,2639 @@
+# Commands covered: trace
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testcmdtrace [llength [info commands testcmdtrace]]
+testConstraint testevalobjv [llength [info commands testevalobjv]]
+
+# Used for constraining memory leak tests
+testConstraint memory [llength [info commands memory]]
+
+proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex [lindex $lines 3] 3
+}
+
+proc traceScalar {name1 name2 op} {
+ global info
+ set info [list $name1 $name2 $op [catch {uplevel set $name1} msg] $msg]
+}
+proc traceScalarAppend {name1 name2 op} {
+ global info
+ lappend info $name1 $name2 $op [catch {uplevel set $name1} msg] $msg
+}
+proc traceArray {name1 name2 op} {
+ global info
+ set info [list $name1 $name2 $op [catch {uplevel set [set name1]($name2)} msg] $msg]
+}
+proc traceArray2 {name1 name2 op} {
+ global info
+ set info [list $name1 $name2 $op]
+}
+proc traceProc {name1 name2 op} {
+ global info
+ set info [concat $info [list $name1 $name2 $op]]
+}
+proc traceTag {tag args} {
+ global info
+ set info [concat $info $tag]
+}
+proc traceError {args} {
+ error "trace returned error"
+}
+proc traceCheck {cmd args} {
+ global info
+ set info [list [catch $cmd msg] $msg]
+}
+proc traceCrtElement {value name1 name2 op} {
+ uplevel set ${name1}($name2) $value
+}
+proc traceCommand {oldName newName op} {
+ global info
+ set info [list $oldName $newName $op]
+}
+
+test trace-0.0 {memory corruption in trace (Tcl Bug 484339)} {
+ # You may need Purify or Electric Fence to reliably
+ # see this one fail.
+ catch {unset z}
+ trace add variable z array {set z(foo) 1 ;#}
+ set res "names: [array names z]"
+ catch {unset ::z}
+ trace variable ::z w {unset ::z; error "memory corruption";#}
+ list [catch {set ::z 1} msg] $msg
+} {1 {can't set "::z": memory corruption}}
+
+# Read-tracing on variables
+
+test trace-1.1 {trace variable reads} {
+ catch {unset x}
+ set info {}
+ trace add variable x read traceScalar
+ list [catch {set x} msg] $msg $info
+} {1 {can't read "x": no such variable} {x {} read 1 {can't read "x": no such variable}}}
+test trace-1.2 {trace variable reads} {
+ catch {unset x}
+ set x 123
+ set info {}
+ trace add variable x read traceScalar
+ list [catch {set x} msg] $msg $info
+} {0 123 {x {} read 0 123}}
+test trace-1.3 {trace variable reads} {
+ catch {unset x}
+ set info {}
+ trace add variable x read traceScalar
+ set x 123
+ set info
+} {}
+test trace-1.4 {trace array element reads} {
+ catch {unset x}
+ set info {}
+ trace add variable x(2) read traceArray
+ list [catch {set x(2)} msg] $msg $info
+} {1 {can't read "x(2)": no such element in array} {x 2 read 1 {can't read "x(2)": no such element in array}}}
+test trace-1.5 {trace array element reads} {
+ catch {unset x}
+ set x(2) zzz
+ set info {}
+ trace add variable x(2) read traceArray
+ list [catch {set x(2)} msg] $msg $info
+} {0 zzz {x 2 read 0 zzz}}
+test trace-1.6 {trace array element reads} {
+ catch {unset x}
+ set info {}
+ trace add variable x read traceArray2
+ proc p {} {
+ global x
+ set x(2) willi
+ return $x(2)
+ }
+ list [catch {p} msg] $msg $info
+} {0 willi {x 2 read}}
+test trace-1.7 {trace array element reads, create element undefined if nonexistant} {
+ catch {unset x}
+ set info {}
+ trace add variable x read q
+ proc q {name1 name2 op} {
+ global info
+ set info [list $name1 $name2 $op]
+ global $name1
+ set ${name1}($name2) wolf
+ }
+ proc p {} {
+ global x
+ set x(X) willi
+ return $x(Y)
+ }
+ list [catch {p} msg] $msg $info
+} {0 wolf {x Y read}}
+test trace-1.8 {trace reads on whole arrays} {
+ catch {unset x}
+ set info {}
+ trace add variable x read traceArray
+ list [catch {set x(2)} msg] $msg $info
+} {1 {can't read "x(2)": no such variable} {}}
+test trace-1.9 {trace reads on whole arrays} {
+ catch {unset x}
+ set x(2) zzz
+ set info {}
+ trace add variable x read traceArray
+ list [catch {set x(2)} msg] $msg $info
+} {0 zzz {x 2 read 0 zzz}}
+test trace-1.10 {trace variable reads} {
+ catch {unset x}
+ set x 444
+ set info {}
+ trace add variable x read traceScalar
+ unset x
+ set info
+} {}
+test trace-1.11 {read traces that modify the array structure} {
+ catch {unset x}
+ set x(bar) 0
+ trace variable x r {set x(foo) 1 ;#}
+ trace variable x r {unset -nocomplain x(bar) ;#}
+ array get x
+} {}
+test trace-1.12 {read traces that modify the array structure} {
+ catch {unset x}
+ set x(bar) 0
+ trace variable x r {unset -nocomplain x(bar) ;#}
+ trace variable x r {set x(foo) 1 ;#}
+ array get x
+} {}
+test trace-1.13 {read traces that modify the array structure} {
+ catch {unset x}
+ set x(bar) 0
+ trace variable x r {set x(foo) 1 ;#}
+ trace variable x r {unset -nocomplain x;#}
+ list [catch {array get x} res] $res
+} {1 {can't read "x(bar)": no such variable}}
+test trace-1.14 {read traces that modify the array structure} {
+ catch {unset x}
+ set x(bar) 0
+ trace variable x r {unset -nocomplain x;#}
+ trace variable x r {set x(foo) 1 ;#}
+ list [catch {array get x} res] $res
+} {1 {can't read "x(bar)": no such variable}}
+
+# Basic write-tracing on variables
+
+test trace-2.1 {trace variable writes} {
+ catch {unset x}
+ set info {}
+ trace add variable x write traceScalar
+ set x 123
+ set info
+} {x {} write 0 123}
+test trace-2.2 {trace writes to array elements} {
+ catch {unset x}
+ set info {}
+ trace add variable x(33) write traceArray
+ set x(33) 444
+ set info
+} {x 33 write 0 444}
+test trace-2.3 {trace writes on whole arrays} {
+ catch {unset x}
+ set info {}
+ trace add variable x write traceArray
+ set x(abc) qq
+ set info
+} {x abc write 0 qq}
+test trace-2.4 {trace variable writes} {
+ catch {unset x}
+ set x 1234
+ set info {}
+ trace add variable x write traceScalar
+ set x
+ set info
+} {}
+test trace-2.5 {trace variable writes} {
+ catch {unset x}
+ set x 1234
+ set info {}
+ trace add variable x write traceScalar
+ unset x
+ set info
+} {}
+test trace-2.6 {trace variable writes on compiled local} {
+ #
+ # Check correct function of whole array traces on compiled local
+ # arrays [Bug 1770591]. The corresponding function for read traces is
+ # already indirectly tested in trace-1.7
+ #
+ catch {unset x}
+ set info {}
+ proc p {} {
+ trace add variable x write traceArray
+ set x(X) willy
+ }
+ p
+ set info
+} {x X write 0 willy}
+test trace-2.7 {trace variable writes on errorInfo} -body {
+ #
+ # Check correct behaviour of write traces on errorInfo.
+ # [Bug 1773040]
+ trace add variable ::errorInfo write traceScalar
+ catch {set dne}
+ lrange [set info] 0 2
+} -cleanup {
+ # always remove trace on errorInfo otherwise further tests will fail
+ unset ::errorInfo
+} -result {::errorInfo {} write}
+
+
+
+# append no longer triggers read traces when fetching the old values of
+# variables before doing the append operation. However, lappend _does_
+# still trigger these read traces. Also lappend triggers only one write
+# trace: after appending all arguments to the list.
+
+test trace-3.1 {trace variable read-modify-writes} {
+ catch {unset x}
+ set info {}
+ trace add variable x read traceScalarAppend
+ append x 123
+ append x 456
+ lappend x 789
+ set info
+} {x {} read 0 123456}
+test trace-3.2 {trace variable read-modify-writes} {
+ catch {unset x}
+ set info {}
+ trace add variable x {read write} traceScalarAppend
+ append x 123
+ lappend x 456
+ set info
+} {x {} write 0 123 x {} read 0 123 x {} write 0 {123 456}}
+
+# Basic unset-tracing on variables
+
+test trace-4.1 {trace variable unsets} {
+ catch {unset x}
+ set info {}
+ trace add variable x unset traceScalar
+ catch {unset x}
+ set info
+} {x {} unset 1 {can't read "x": no such variable}}
+test trace-4.2 {variable mustn't exist during unset trace} {
+ catch {unset x}
+ set x 1234
+ set info {}
+ trace add variable x unset traceScalar
+ unset x
+ set info
+} {x {} unset 1 {can't read "x": no such variable}}
+test trace-4.3 {unset traces mustn't be called during reads and writes} {
+ catch {unset x}
+ set info {}
+ trace add variable x unset traceScalar
+ set x 44
+ set x
+ set info
+} {}
+test trace-4.4 {trace unsets on array elements} {
+ catch {unset x}
+ set x(0) 18
+ set info {}
+ trace add variable x(1) unset traceArray
+ catch {unset x(1)}
+ set info
+} {x 1 unset 1 {can't read "x(1)": no such element in array}}
+test trace-4.5 {trace unsets on array elements} {
+ catch {unset x}
+ set x(1) 18
+ set info {}
+ trace add variable x(1) unset traceArray
+ unset x(1)
+ set info
+} {x 1 unset 1 {can't read "x(1)": no such element in array}}
+test trace-4.6 {trace unsets on array elements} {
+ catch {unset x}
+ set x(1) 18
+ set info {}
+ trace add variable x(1) unset traceArray
+ unset x
+ set info
+} {x 1 unset 1 {can't read "x(1)": no such variable}}
+test trace-4.7 {trace unsets on whole arrays} {
+ catch {unset x}
+ set x(1) 18
+ set info {}
+ trace add variable x unset traceProc
+ catch {unset x(0)}
+ set info
+} {}
+test trace-4.8 {trace unsets on whole arrays} {
+ catch {unset x}
+ set x(1) 18
+ set x(2) 144
+ set x(3) 14
+ set info {}
+ trace add variable x unset traceProc
+ unset x(1)
+ set info
+} {x 1 unset}
+test trace-4.9 {trace unsets on whole arrays} {
+ catch {unset x}
+ set x(1) 18
+ set x(2) 144
+ set x(3) 14
+ set info {}
+ trace add variable x unset traceProc
+ unset x
+ set info
+} {x {} unset}
+
+# Array tracing on variables
+test trace-5.1 {array traces fire on accesses via [array]} {
+ catch {unset x}
+ set x(b) 2
+ trace add variable x array traceArray2
+ set ::info {}
+ array set x {a 1}
+ set ::info
+} {x {} array}
+test trace-5.2 {array traces do not fire on normal accesses} {
+ catch {unset x}
+ set x(b) 2
+ trace add variable x array traceArray2
+ set ::info {}
+ set x(a) 1
+ set x(b) $x(a)
+ set ::info
+} {}
+test trace-5.3 {array traces do not outlive variable} {
+ catch {unset x}
+ trace add variable x array traceArray2
+ set ::info {}
+ set x(a) 1
+ unset x
+ array set x {a 1}
+ set ::info
+} {}
+test trace-5.4 {array traces properly listed in trace information} {
+ catch {unset x}
+ trace add variable x array traceArray2
+ set result [trace info variable x]
+ set result
+} [list [list array traceArray2]]
+test trace-5.5 {array traces properly listed in trace information} {
+ catch {unset x}
+ trace variable x a traceArray2
+ set result [trace vinfo x]
+ set result
+} [list [list a traceArray2]]
+test trace-5.6 {array traces don't fire on scalar variables} {
+ catch {unset x}
+ set x foo
+ trace add variable x array traceArray2
+ set ::info {}
+ catch {array set x {a 1}}
+ set ::info
+} {}
+test trace-5.7 {array traces fire for undefined variables} {
+ catch {unset x}
+ trace add variable x array traceArray2
+ set ::info {}
+ array set x {a 1}
+ set ::info
+} {x {} array}
+test trace-5.8 {array traces fire for undefined variables} {
+ catch {unset x}
+ trace add variable x array {set x(foo) 1 ;#}
+ set res "names: [array names x]"
+} {names: foo}
+
+# Trace multiple trace types at once.
+
+test trace-6.1 {multiple ops traced at once} {
+ catch {unset x}
+ set info {}
+ trace add variable x {read write unset} traceProc
+ catch {set x}
+ set x 22
+ set x
+ set x 33
+ unset x
+ set info
+} {x {} read x {} write x {} read x {} write x {} unset}
+test trace-6.2 {multiple ops traced on array element} {
+ catch {unset x}
+ set info {}
+ trace add variable x(0) {read write unset} traceProc
+ catch {set x(0)}
+ set x(0) 22
+ set x(0)
+ set x(0) 33
+ unset x(0)
+ unset x
+ set info
+} {x 0 read x 0 write x 0 read x 0 write x 0 unset}
+test trace-6.3 {multiple ops traced on whole array} {
+ catch {unset x}
+ set info {}
+ trace add variable x {read write unset} traceProc
+ catch {set x(0)}
+ set x(0) 22
+ set x(0)
+ set x(0) 33
+ unset x(0)
+ unset x
+ set info
+} {x 0 write x 0 read x 0 write x 0 unset x {} unset}
+
+# Check order of invocation of traces
+
+test trace-7.1 {order of invocation of traces} {
+ catch {unset x}
+ set info {}
+ trace add variable x read "traceTag 1"
+ trace add variable x read "traceTag 2"
+ trace add variable x read "traceTag 3"
+ catch {set x}
+ set x 22
+ set x
+ set info
+} {3 2 1 3 2 1}
+test trace-7.2 {order of invocation of traces} {
+ catch {unset x}
+ set x(0) 44
+ set info {}
+ trace add variable x(0) read "traceTag 1"
+ trace add variable x(0) read "traceTag 2"
+ trace add variable x(0) read "traceTag 3"
+ set x(0)
+ set info
+} {3 2 1}
+test trace-7.3 {order of invocation of traces} {
+ catch {unset x}
+ set x(0) 44
+ set info {}
+ trace add variable x(0) read "traceTag 1"
+ trace add variable x read "traceTag A1"
+ trace add variable x(0) read "traceTag 2"
+ trace add variable x read "traceTag A2"
+ trace add variable x(0) read "traceTag 3"
+ trace add variable x read "traceTag A3"
+ set x(0)
+ set info
+} {A3 A2 A1 3 2 1}
+
+# Check effects of errors in trace procedures
+
+test trace-8.1 {error returns from traces} {
+ catch {unset x}
+ set x 123
+ set info {}
+ trace add variable x read "traceTag 1"
+ trace add variable x read traceError
+ list [catch {set x} msg] $msg $info
+} {1 {can't read "x": trace returned error} {}}
+test trace-8.2 {error returns from traces} {
+ catch {unset x}
+ set x 123
+ set info {}
+ trace add variable x write "traceTag 1"
+ trace add variable x write traceError
+ list [catch {set x 44} msg] $msg $info
+} {1 {can't set "x": trace returned error} {}}
+test trace-8.3 {error returns from traces} {
+ catch {unset x}
+ set x 123
+ set info {}
+ trace add variable x write traceError
+ list [catch {append x 44} msg] $msg $info
+} {1 {can't set "x": trace returned error} {}}
+test trace-8.4 {error returns from traces} {
+ catch {unset x}
+ set x 123
+ set info {}
+ trace add variable x unset "traceTag 1"
+ trace add variable x unset traceError
+ list [catch {unset x} msg] $msg $info
+} {0 {} 1}
+test trace-8.5 {error returns from traces} {
+ catch {unset x}
+ set x(0) 123
+ set info {}
+ trace add variable x(0) read "traceTag 1"
+ trace add variable x read "traceTag 2"
+ trace add variable x read traceError
+ trace add variable x read "traceTag 3"
+ list [catch {set x(0)} msg] $msg $info
+} {1 {can't read "x(0)": trace returned error} 3}
+test trace-8.6 {error returns from traces} {
+ catch {unset x}
+ set x 123
+ trace add variable x unset traceError
+ list [catch {unset x} msg] $msg
+} {0 {}}
+test trace-8.7 {error returns from traces} {
+ # This test just makes sure that the memory for the error message
+ # gets deallocated correctly when the trace is invoked again or
+ # when the trace is deleted.
+ catch {unset x}
+ set x 123
+ trace add variable x read traceError
+ catch {set x}
+ catch {set x}
+ trace remove variable x read traceError
+} {}
+test trace-8.8 {error returns from traces} {
+ # Yet more elaborate memory corruption testing that checks nothing
+ # bad happens when the trace deletes itself and installs something
+ # new. Alas, there is no neat way to guarantee that this test will
+ # fail if there is a problem, but that's life and with the new code
+ # it should *never* fail.
+ #
+ # Adapted from Bug #219393 reported by Don Porter.
+ catch {rename ::foo {}}
+ proc foo {old args} {
+ trace remove variable ::x write [list foo $old]
+ trace add variable ::x write [list foo $::x]
+ error "foo"
+ }
+ catch {unset ::x ::y}
+ set x junk
+ trace add variable ::x write [list foo $x]
+ for {set y 0} {$y<100} {incr y} {
+ catch {set x junk}
+ }
+ unset x
+} {}
+
+# Check to see that variables are expunged before trace
+# procedures are invoked, so trace procedure can even manipulate
+# a new copy of the variables.
+
+test trace-9.1 {be sure variable is unset before trace is called} {
+ catch {unset x}
+ set x 33
+ set info {}
+ trace add variable x unset {traceCheck {uplevel set x}}
+ unset x
+ set info
+} {1 {can't read "x": no such variable}}
+test trace-9.2 {be sure variable is unset before trace is called} {
+ catch {unset x}
+ set x 33
+ set info {}
+ trace add variable x unset {traceCheck {uplevel set x 22}}
+ unset x
+ concat $info [list [catch {set x} msg] $msg]
+} {0 22 0 22}
+test trace-9.3 {be sure traces are cleared before unset trace called} {
+ catch {unset x}
+ set x 33
+ set info {}
+ trace add variable x unset {traceCheck {uplevel trace info variable x}}
+ unset x
+ set info
+} {0 {}}
+test trace-9.4 {set new trace during unset trace} {
+ catch {unset x}
+ set x 33
+ set info {}
+ trace add variable x unset {traceCheck {global x; trace add variable x unset traceProc}}
+ unset x
+ concat $info [trace info variable x]
+} {0 {} {unset traceProc}}
+
+test trace-10.1 {make sure array elements are unset before traces are called} {
+ catch {unset x}
+ set x(0) 33
+ set info {}
+ trace add variable x(0) unset {traceCheck {uplevel set x(0)}}
+ unset x(0)
+ set info
+} {1 {can't read "x(0)": no such element in array}}
+test trace-10.2 {make sure array elements are unset before traces are called} {
+ catch {unset x}
+ set x(0) 33
+ set info {}
+ trace add variable x(0) unset {traceCheck {uplevel set x(0) zzz}}
+ unset x(0)
+ concat $info [list [catch {set x(0)} msg] $msg]
+} {0 zzz 0 zzz}
+test trace-10.3 {array elements are unset before traces are called} {
+ catch {unset x}
+ set x(0) 33
+ set info {}
+ trace add variable x(0) unset {traceCheck {global x; trace info variable x(0)}}
+ unset x(0)
+ set info
+} {0 {}}
+test trace-10.4 {set new array element trace during unset trace} {
+ catch {unset x}
+ set x(0) 33
+ set info {}
+ trace add variable x(0) unset {traceCheck {uplevel {trace add variable x(0) read {}}}}
+ catch {unset x(0)}
+ concat $info [trace info variable x(0)]
+} {0 {} {read {}}}
+
+test trace-11.1 {make sure arrays are unset before traces are called} {
+ catch {unset x}
+ set x(0) 33
+ set info {}
+ trace add variable x unset {traceCheck {uplevel set x(0)}}
+ unset x
+ set info
+} {1 {can't read "x(0)": no such variable}}
+test trace-11.2 {make sure arrays are unset before traces are called} {
+ catch {unset x}
+ set x(y) 33
+ set info {}
+ trace add variable x unset {traceCheck {uplevel set x(y) 22}}
+ unset x
+ concat $info [list [catch {set x(y)} msg] $msg]
+} {0 22 0 22}
+test trace-11.3 {make sure arrays are unset before traces are called} {
+ catch {unset x}
+ set x(y) 33
+ set info {}
+ trace add variable x unset {traceCheck {uplevel array exists x}}
+ unset x
+ set info
+} {0 0}
+test trace-11.4 {make sure arrays are unset before traces are called} {
+ catch {unset x}
+ set x(y) 33
+ set info {}
+ set cmd {traceCheck {uplevel {trace info variable x}}}
+ trace add variable x unset $cmd
+ unset x
+ set info
+} {0 {}}
+test trace-11.5 {set new array trace during unset trace} {
+ catch {unset x}
+ set x(y) 33
+ set info {}
+ trace add variable x unset {traceCheck {global x; trace add variable x read {}}}
+ unset x
+ concat $info [trace info variable x]
+} {0 {} {read {}}}
+test trace-11.6 {create scalar during array unset trace} {
+ catch {unset x}
+ set x(y) 33
+ set info {}
+ trace add variable x unset {traceCheck {global x; set x 44}}
+ unset x
+ concat $info [list [catch {set x} msg] $msg]
+} {0 44 0 44}
+
+# Check special conditions (e.g. errors) in Tcl_TraceVar2.
+
+test trace-12.1 {creating array when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace add variable x(0) write traceProc
+ list [catch {set x 22} msg] $msg
+} {1 {can't set "x": variable is array}}
+test trace-12.2 {creating array when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace add variable x(0) write traceProc
+ list [catch {set x(0)} msg] $msg
+} {1 {can't read "x(0)": no such element in array}}
+test trace-12.3 {creating array when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace add variable x(0) write traceProc
+ set x(0) 22
+ set info
+} {x 0 write}
+test trace-12.4 {creating variable when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace add variable x write traceProc
+ list [catch {set x} msg] $msg
+} {1 {can't read "x": no such variable}}
+test trace-12.5 {creating variable when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace add variable x write traceProc
+ set x 22
+ set info
+} {x {} write}
+test trace-12.6 {creating variable when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace add variable x write traceProc
+ set x(0) 22
+ set info
+} {x 0 write}
+test trace-12.7 {create array element during read trace} {
+ catch {unset x}
+ set x(2) zzz
+ trace add variable x read {traceCrtElement xyzzy}
+ list [catch {set x(3)} msg] $msg
+} {0 xyzzy}
+test trace-12.8 {errors when setting variable traces} {
+ catch {unset x}
+ set x 44
+ list [catch {trace add variable x(0) write traceProc} msg] $msg
+} {1 {can't trace "x(0)": variable isn't array}}
+
+# Check trace deletion
+
+test trace-13.1 {delete one trace from another} {
+ proc delTraces {args} {
+ global x
+ trace remove variable x read {traceTag 2}
+ trace remove variable x read {traceTag 3}
+ trace remove variable x read {traceTag 4}
+ }
+ catch {unset x}
+ set x 44
+ set info {}
+ trace add variable x read {traceTag 1}
+ trace add variable x read {traceTag 2}
+ trace add variable x read {traceTag 3}
+ trace add variable x read {traceTag 4}
+ trace add variable x read delTraces
+ trace add variable x read {traceTag 5}
+ set x
+ set info
+} {5 1}
+
+test trace-13.2 {leak when unsetting traced variable} \
+ -constraints memory -body {
+ set end [getbytes]
+ proc f args {}
+ for {set i 0} {$i < 5} {incr i} {
+ trace add variable bepa write f
+ set bepa a
+ unset bepa
+ set tmp $end
+ set end [getbytes]
+ }
+ expr {$end - $tmp}
+ } -cleanup {
+ unset -nocomplain end i tmp
+ } -result 0
+test trace-13.3 {leak when removing traces} \
+ -constraints memory -body {
+ set end [getbytes]
+ proc f args {}
+ for {set i 0} {$i < 5} {incr i} {
+ trace add variable bepa write f
+ set bepa a
+ trace remove variable bepa write f
+ set tmp $end
+ set end [getbytes]
+ }
+ expr {$end - $tmp}
+ } -cleanup {
+ unset -nocomplain end i tmp
+ } -result 0
+test trace-13.4 {leaks in error returns from traces} \
+ -constraints memory -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ set apa {a 1 b 2}
+ set bepa [lrange $apa 0 end]
+ trace add variable bepa write {error hej}
+ catch {set bepa a}
+ unset bepa
+ set tmp $end
+ set end [getbytes]
+ }
+ expr {$end - $tmp}
+ } -cleanup {
+ unset -nocomplain end i tmp
+ } -result 0
+
+# Check operation and syntax of "trace" command.
+
+# Syntax for adding/removing variable and command traces is basically the
+# same:
+# trace add variable name opList command
+# trace remove variable name opList command
+#
+# The following loops just get all the common "wrong # args" tests done.
+
+set i 0
+set start "wrong # args:"
+foreach type {variable command} {
+ foreach op {add remove} {
+ test trace-14.0.[incr i] "trace command, wrong # args errors" {
+ list [catch {trace $op $type} msg] $msg
+ } [list 1 "$start should be \"trace $op $type name opList command\""]
+ test trace-14.0.[incr i] "trace command wrong # args errors" {
+ list [catch {trace $op $type foo} msg] $msg
+ } [list 1 "$start should be \"trace $op $type name opList command\""]
+ test trace-14.0.[incr i] "trace command, wrong # args errors" {
+ list [catch {trace $op $type foo bar} msg] $msg
+ } [list 1 "$start should be \"trace $op $type name opList command\""]
+ test trace-14.0.[incr i] "trace command, wrong # args errors" {
+ list [catch {trace $op $type foo bar baz boo} msg] $msg
+ } [list 1 "$start should be \"trace $op $type name opList command\""]
+ }
+ test trace-14.0.[incr i] "trace command, wrong # args errors" {
+ list [catch {trace info $type foo bar} msg] $msg
+ } [list 1 "$start should be \"trace info $type name\""]
+ test trace-14.0.[incr i] "trace command, wrong # args errors" {
+ list [catch {trace info $type} msg] $msg
+ } [list 1 "$start should be \"trace info $type name\""]
+}
+
+test trace-14.1 "trace command, wrong # args errors" {
+ list [catch {trace} msg] $msg
+} [list 1 "wrong # args: should be \"trace option ?arg ...?\""]
+test trace-14.2 "trace command, wrong # args errors" {
+ list [catch {trace add} msg] $msg
+} [list 1 "wrong # args: should be \"trace add type ?arg ...?\""]
+test trace-14.3 "trace command, wrong # args errors" {
+ list [catch {trace remove} msg] $msg
+} [list 1 "wrong # args: should be \"trace remove type ?arg ...?\""]
+test trace-14.4 "trace command, wrong # args errors" {
+ list [catch {trace info} msg] $msg
+} [list 1 "wrong # args: should be \"trace info type name\""]
+
+test trace-14.5 {trace command, invalid option} {
+ list [catch {trace gorp} msg] $msg
+} [list 1 "bad option \"gorp\": must be add, info, remove, variable, vdelete, or vinfo"]
+
+# Again, [trace ... command] and [trace ... variable] share syntax and
+# error message styles for their opList options; these loops test those
+# error messages.
+
+set i 0
+set errs [list "array, read, unset, or write" "delete or rename" "enter, leave, enterstep, or leavestep"]
+set abbvs [list {a r u w} {d r} {}]
+proc x {} {}
+foreach type {variable command execution} err $errs abbvlist $abbvs {
+ foreach op {add remove} {
+ test trace-14.6.[incr i] "trace $op $type errors" {
+ list [catch {trace $op $type x {y z w} a} msg] $msg
+ } [list 1 "bad operation \"y\": must be $err"]
+ foreach abbv $abbvlist {
+ test trace-14.6.[incr i] "trace $op $type rejects abbreviations" {
+ list [catch {trace $op $type x $abbv a} msg] $msg
+ } [list 1 "bad operation \"$abbv\": must be $err"]
+ }
+ test trace-14.6.[incr i] "trace $op $type rejects null opList" {
+ list [catch {trace $op $type x {} a} msg] $msg
+ } [list 1 "bad operation list \"\": must be one or more of $err"]
+ }
+}
+rename x {}
+
+test trace-14.7 {trace command, "trace variable" errors} {
+ list [catch {trace variable} msg] $msg
+} [list 1 "wrong # args: should be \"trace variable name ops command\""]
+test trace-14.8 {trace command, "trace variable" errors} {
+ list [catch {trace variable x} msg] $msg
+} [list 1 "wrong # args: should be \"trace variable name ops command\""]
+test trace-14.9 {trace command, "trace variable" errors} {
+ list [catch {trace variable x y} msg] $msg
+} [list 1 "wrong # args: should be \"trace variable name ops command\""]
+test trace-14.10 {trace command, "trace variable" errors} {
+ list [catch {trace variable x y z w} msg] $msg
+} [list 1 "wrong # args: should be \"trace variable name ops command\""]
+test trace-14.11 {trace command, "trace variable" errors} {
+ list [catch {trace variable x y z} msg] $msg
+} [list 1 "bad operations \"y\": should be one or more of rwua"]
+
+
+test trace-14.12 {trace command ("remove variable" option)} {
+ catch {unset x}
+ set info {}
+ trace add variable x write traceProc
+ trace remove variable x write traceProc
+} {}
+test trace-14.13 {trace command ("remove variable" option)} {
+ catch {unset x}
+ set info {}
+ trace add variable x write traceProc
+ trace remove variable x write traceProc
+ set x 12345
+ set info
+} {}
+test trace-14.14 {trace command ("remove variable" option)} {
+ catch {unset x}
+ set info {}
+ trace add variable x write {traceTag 1}
+ trace add variable x write traceProc
+ trace add variable x write {traceTag 2}
+ set x yy
+ trace remove variable x write traceProc
+ set x 12345
+ trace remove variable x write {traceTag 1}
+ set x foo
+ trace remove variable x write {traceTag 2}
+ set x gorp
+ set info
+} {2 x {} write 1 2 1 2}
+test trace-14.15 {trace command ("remove variable" option)} {
+ catch {unset x}
+ set info {}
+ trace add variable x write {traceTag 1}
+ trace remove variable x write non_existent
+ set x 12345
+ set info
+} {1}
+test trace-14.16 {trace command ("info variable" option)} {
+ catch {unset x}
+ trace add variable x write {traceTag 1}
+ trace add variable x write traceProc
+ trace add variable x write {traceTag 2}
+ trace info variable x
+} {{write {traceTag 2}} {write traceProc} {write {traceTag 1}}}
+test trace-14.17 {trace command ("info variable" option)} {
+ catch {unset x}
+ trace info variable x
+} {}
+test trace-14.18 {trace command ("info variable" option)} {
+ catch {unset x}
+ trace info variable x(0)
+} {}
+test trace-14.19 {trace command ("info variable" option)} {
+ catch {unset x}
+ set x 44
+ trace info variable x(0)
+} {}
+test trace-14.20 {trace command ("info variable" option)} {
+ catch {unset x}
+ set x 44
+ trace add variable x write {traceTag 1}
+ proc check {} {global x; trace info variable x}
+ check
+} {{write {traceTag 1}}}
+
+# Check fancy trace commands (long ones, weird arguments, etc.)
+
+test trace-15.1 {long trace command} {
+ catch {unset x}
+ set info {}
+ trace add variable x write {traceTag {This is a very very long argument. It's \
+ designed to test out the facilities of TraceVarProc for dealing \
+ with such long arguments by malloc-ing space. One possibility \
+ is that space doesn't get freed properly. If this happens, then \
+ invoking this test over and over again will eventually leak memory.}}
+ set x 44
+ set info
+} {This is a very very long argument. It's \
+ designed to test out the facilities of TraceVarProc for dealing \
+ with such long arguments by malloc-ing space. One possibility \
+ is that space doesn't get freed properly. If this happens, then \
+ invoking this test over and over again will eventually leak memory.}
+test trace-15.2 {long trace command result to ignore} {
+ proc longResult {args} {return "quite a bit of text, designed to
+ generate a core leak if this command file is invoked over and over again
+ and memory isn't being recycled correctly"}
+ catch {unset x}
+ trace add variable x write longResult
+ set x 44
+ set x 5
+ set x abcde
+} abcde
+test trace-15.3 {special list-handling in trace commands} {
+ catch {unset "x y z"}
+ set "x y z(a\n\{)" 44
+ set info {}
+ trace add variable "x y z(a\n\{)" write traceProc
+ set "x y z(a\n\{)" 33
+ set info
+} "{x y z} a\\n\\\{ write"
+
+# Check for proper handling of unsets during traces.
+
+proc traceUnset {unsetName args} {
+ global info
+ upvar $unsetName x
+ lappend info [catch {unset x} msg] $msg [catch {set x} msg] $msg
+}
+proc traceReset {unsetName resetName args} {
+ global info
+ upvar $unsetName x $resetName y
+ lappend info [catch {unset x} msg] $msg [catch {set y xyzzy} msg] $msg
+}
+proc traceReset2 {unsetName resetName args} {
+ global info
+ lappend info [catch {uplevel unset $unsetName} msg] $msg \
+ [catch {uplevel set $resetName xyzzy} msg] $msg
+}
+proc traceAppend {string name1 name2 op} {
+ global info
+ lappend info $string
+}
+
+test trace-16.1 {unsets during read traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace add variable y read {traceUnset y}
+ trace add variable y unset {traceAppend unset}
+ lappend info [catch {set y} msg] $msg
+} {unset 0 {} 1 {can't read "x": no such variable} 1 {can't read "y": no such variable}}
+test trace-16.2 {unsets during read traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) read {traceUnset y(0)}
+ lappend info [catch {set y(0)} msg] $msg
+} {0 {} 1 {can't read "x": no such variable} 1 {can't read "y(0)": no such element in array}}
+test trace-16.3 {unsets during read traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) read {traceUnset y}
+ lappend info [catch {set y(0)} msg] $msg
+} {0 {} 1 {can't read "x": no such variable} 1 {can't read "y(0)": no such variable}}
+test trace-16.4 {unsets during read traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace add variable y read {traceReset y y}
+ lappend info [catch {set y} msg] $msg
+} {0 {} 0 xyzzy 0 xyzzy}
+test trace-16.5 {unsets during read traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) read {traceReset y(0) y(0)}
+ lappend info [catch {set y(0)} msg] $msg
+} {0 {} 0 xyzzy 0 xyzzy}
+test trace-16.6 {unsets during read traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) read {traceReset y y(0)}
+ lappend info [catch {set y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 1 {can't set "y": upvar refers to element in deleted array} 1 {can't read "y(0)": no such variable} 1 {can't read "y(0)": no such variable}}
+test trace-16.7 {unsets during read traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) read {traceReset2 y y(0)}
+ lappend info [catch {set y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 0 xyzzy 1 {can't read "y(0)": no such element in array} 0 xyzzy}
+test trace-16.8 {unsets during write traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace add variable y write {traceUnset y}
+ trace add variable y unset {traceAppend unset}
+ lappend info [catch {set y xxx} msg] $msg
+} {unset 0 {} 1 {can't read "x": no such variable} 0 {}}
+test trace-16.9 {unsets during write traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) write {traceUnset y(0)}
+ lappend info [catch {set y(0) xxx} msg] $msg
+} {0 {} 1 {can't read "x": no such variable} 0 {}}
+test trace-16.10 {unsets during write traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) write {traceUnset y}
+ lappend info [catch {set y(0) xxx} msg] $msg
+} {0 {} 1 {can't read "x": no such variable} 0 {}}
+test trace-16.11 {unsets during write traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace add variable y write {traceReset y y}
+ lappend info [catch {set y xxx} msg] $msg
+} {0 {} 0 xyzzy 0 xyzzy}
+test trace-16.12 {unsets during write traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) write {traceReset y(0) y(0)}
+ lappend info [catch {set y(0) xxx} msg] $msg
+} {0 {} 0 xyzzy 0 xyzzy}
+test trace-16.13 {unsets during write traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) write {traceReset y y(0)}
+ lappend info [catch {set y(0) xxx} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 1 {can't set "y": upvar refers to element in deleted array} 0 {} 1 {can't read "y(0)": no such variable}}
+test trace-16.14 {unsets during write traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) write {traceReset2 y y(0)}
+ lappend info [catch {set y(0) xxx} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 0 xyzzy 0 {} 0 xyzzy}
+test trace-16.15 {unsets during unset traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace add variable y unset {traceUnset y}
+ lappend info [catch {unset y} msg] $msg [catch {set y} msg] $msg
+} {1 {can't unset "x": no such variable} 1 {can't read "x": no such variable} 0 {} 1 {can't read "y": no such variable}}
+test trace-16.16 {unsets during unset traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) unset {traceUnset y(0)}
+ lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {1 {can't unset "x": no such variable} 1 {can't read "x": no such variable} 0 {} 1 {can't read "y(0)": no such element in array}}
+test trace-16.17 {unsets during unset traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) unset {traceUnset y}
+ lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 1 {can't read "x": no such variable} 0 {} 1 {can't read "y(0)": no such variable}}
+test trace-16.18 {unsets during unset traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace add variable y unset {traceReset2 y y}
+ lappend info [catch {unset y} msg] $msg [catch {set y} msg] $msg
+} {1 {can't unset "y": no such variable} 0 xyzzy 0 {} 0 xyzzy}
+test trace-16.19 {unsets during unset traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) unset {traceReset2 y(0) y(0)}
+ lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {1 {can't unset "y(0)": no such element in array} 0 xyzzy 0 {} 0 xyzzy}
+test trace-16.20 {unsets during unset traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) unset {traceReset2 y y(0)}
+ lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 0 xyzzy 0 {} 0 xyzzy}
+test trace-16.21 {unsets cancelling traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace add variable y read {traceAppend first}
+ trace add variable y read {traceUnset y}
+ trace add variable y read {traceAppend third}
+ trace add variable y unset {traceAppend unset}
+ lappend info [catch {set y} msg] $msg
+} {third unset 0 {} 1 {can't read "x": no such variable} 1 {can't read "y": no such variable}}
+test trace-16.22 {unsets cancelling traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) read {traceAppend first}
+ trace add variable y(0) read {traceUnset y}
+ trace add variable y(0) read {traceAppend third}
+ trace add variable y(0) unset {traceAppend unset}
+ lappend info [catch {set y(0)} msg] $msg
+} {third unset 0 {} 1 {can't read "x": no such variable} 1 {can't read "y(0)": no such variable}}
+
+# Check various non-interference between traces and other things.
+
+test trace-17.1 {trace doesn't prevent unset errors} {
+ catch {unset x}
+ set info {}
+ trace add variable x unset {traceProc}
+ list [catch {unset x} msg] $msg $info
+} {1 {can't unset "x": no such variable} {x {} unset}}
+test trace-17.2 {traced variables must survive procedure exits} {
+ catch {unset x}
+ proc p1 {} {global x; trace add variable x write traceProc}
+ p1
+ trace info variable x
+} {{write traceProc}}
+test trace-17.3 {traced variables must survive procedure exits} {
+ catch {unset x}
+ set info {}
+ proc p1 {} {global x; trace add variable x write traceProc}
+ p1
+ set x 44
+ set info
+} {x {} write}
+
+# Be sure that procedure frames are released before unset traces
+# are invoked.
+
+test trace-18.1 {unset traces on procedure returns} {
+ proc p1 {x y} {set a 44; p2 14}
+ proc p2 {z} {trace add variable z unset {traceCheck {lsort [uplevel {info vars}]}}}
+ set info {}
+ p1 foo bar
+ set info
+} {0 {a x y}}
+test trace-18.2 {namespace delete / trace vdelete combo} {
+ namespace eval ::foo {
+ variable x 123
+ }
+ proc p1 args {
+ trace vdelete ::foo::x u p1
+ }
+ trace variable ::foo::x u p1
+ namespace delete ::foo
+ info exists ::foo::x
+} 0
+test trace-18.3 {namespace delete / trace vdelete combo, Bug \#1337229} {
+ namespace eval ::ns {}
+ trace add variable ::ns::var unset {unset ::ns::var ;#}
+ namespace delete ::ns
+} {}
+test trace-18.4 {namespace delete / trace vdelete combo, Bug \#1338280} {
+ namespace eval ::ref {}
+ set ::ref::var1 AAA
+ trace add variable ::ref::var1 unset doTrace
+ set ::ref::var2 BBB
+ trace add variable ::ref::var2 {unset} doTrace
+ proc doTrace {vtraced vidx op} {
+ global info
+ append info [catch {set ::$vtraced}][llength [info vars ::ref::*]]
+ }
+ set info {}
+ namespace delete ::ref
+ rename doTrace {}
+ set info
+} 1110
+
+# Delete arrays when done, so they can be re-used as scalars
+# elsewhere.
+
+catch {unset x}
+catch {unset y}
+
+test trace-19.0.1 {trace add command (command existence)} {
+ # Just in case!
+ catch {rename nosuchname ""}
+ list [catch {trace add command nosuchname rename traceCommand} msg] $msg
+} {1 {unknown command "nosuchname"}}
+test trace-19.0.2 {trace add command (command existence in ns)} {
+ list [catch {trace add command nosuchns::nosuchname rename traceCommand} msg] $msg
+} {1 {unknown command "nosuchns::nosuchname"}}
+
+
+test trace-19.1 {trace add command (rename option)} {
+ proc foo {} {}
+ catch {rename bar {}}
+ trace add command foo rename traceCommand
+ rename foo bar
+ set info
+} {::foo ::bar rename}
+test trace-19.2 {traces stick with renamed commands} {
+ proc foo {} {}
+ catch {rename bar {}}
+ trace add command foo rename traceCommand
+ rename foo bar
+ rename bar foo
+ set info
+} {::bar ::foo rename}
+test trace-19.2.1 {trace add command rename trace exists} {
+ proc foo {} {}
+ trace add command foo rename traceCommand
+ trace info command foo
+} {{rename traceCommand}}
+test trace-19.3 {command rename traces don't fire on command deletion} {
+ proc foo {} {}
+ set info {}
+ trace add command foo rename traceCommand
+ rename foo {}
+ set info
+} {}
+test trace-19.4 {trace add command rename doesn't trace recreated commands} {
+ proc foo {} {}
+ catch {rename bar {}}
+ trace add command foo rename traceCommand
+ proc foo {} {}
+ rename foo bar
+ set info
+} {}
+test trace-19.5 {trace add command deleted removes traces} {
+ proc foo {} {}
+ trace add command foo rename traceCommand
+ proc foo {} {}
+ trace info command foo
+} {}
+
+namespace eval tc {}
+proc tc::tcfoo {} {}
+test trace-19.6 {trace add command rename in namespace} {
+ trace add command tc::tcfoo rename traceCommand
+ rename tc::tcfoo tc::tcbar
+ set info
+} {::tc::tcfoo ::tc::tcbar rename}
+test trace-19.7 {trace add command rename in namespace back again} {
+ rename tc::tcbar tc::tcfoo
+ set info
+} {::tc::tcbar ::tc::tcfoo rename}
+test trace-19.8 {trace add command rename in namespace to out of namespace} {
+ rename tc::tcfoo tcbar
+ set info
+} {::tc::tcfoo ::tcbar rename}
+test trace-19.9 {trace add command rename back into namespace} {
+ rename tcbar tc::tcfoo
+ set info
+} {::tcbar ::tc::tcfoo rename}
+test trace-19.10 {trace add command failed rename doesn't trigger trace} {
+ set info {}
+ proc foo {} {}
+ proc bar {} {}
+ trace add command foo {rename delete} traceCommand
+ catch {rename foo bar}
+ set info
+} {}
+catch {rename foo {}}
+catch {rename bar {}}
+test trace-19.11 {trace add command qualifies when renamed in namespace} {
+ set info {}
+ namespace eval tc {rename tcfoo tcbar}
+ set info
+} {::tc::tcfoo ::tc::tcbar rename}
+
+# Make sure it exists again
+proc foo {} {}
+
+test trace-20.1 {trace add command (delete option)} {
+ trace add command foo delete traceCommand
+ rename foo ""
+ set info
+} {::foo {} delete}
+test trace-20.2 {trace add command delete doesn't trace recreated commands} {
+ set info {}
+ proc foo {} {}
+ rename foo ""
+ set info
+} {}
+test trace-20.2.1 {trace add command delete trace info} {
+ proc foo {} {}
+ trace add command foo delete traceCommand
+ trace info command foo
+} {{delete traceCommand}}
+test trace-20.3 {trace add command implicit delete} {
+ proc foo {} {}
+ trace add command foo delete traceCommand
+ proc foo {} {}
+ set info
+} {::foo {} delete}
+test trace-20.3.1 {trace add command delete trace info} {
+ proc foo {} {}
+ trace info command foo
+} {}
+test trace-20.4 {trace add command rename followed by delete} {
+ set infotemp {}
+ proc foo {} {}
+ trace add command foo {rename delete} traceCommand
+ rename foo bar
+ lappend infotemp $info
+ rename bar {}
+ lappend infotemp $info
+ set info $infotemp
+ unset infotemp
+ set info
+} {{::foo ::bar rename} {::bar {} delete}}
+catch {rename foo {}}
+catch {rename bar {}}
+
+test trace-20.5 {trace add command rename and delete} {
+ set infotemp {}
+ set info {}
+ proc foo {} {}
+ trace add command foo {rename delete} traceCommand
+ rename foo bar
+ lappend infotemp $info
+ rename bar {}
+ lappend infotemp $info
+ set info $infotemp
+ unset infotemp
+ set info
+} {{::foo ::bar rename} {::bar {} delete}}
+
+test trace-20.6 {trace add command rename and delete in subinterp} {
+ set tc [interp create]
+ foreach p {traceCommand} {
+ $tc eval [list proc $p [info args $p] [info body $p]]
+ }
+ $tc eval [list set infotemp {}]
+ $tc eval [list set info {}]
+ $tc eval [list proc foo {} {}]
+ $tc eval [list trace add command foo {rename delete} traceCommand]
+ $tc eval [list rename foo bar]
+ $tc eval {lappend infotemp $info}
+ $tc eval [list rename bar {}]
+ $tc eval {lappend infotemp $info}
+ $tc eval {set info $infotemp}
+ $tc eval [list unset infotemp]
+ set info [$tc eval [list set info]]
+ interp delete $tc
+ set info
+} {{::foo ::bar rename} {::bar {} delete}}
+
+# I'd like it if this test could give 'foo {} d' as a result,
+# but interp deletion means there is no interp to evaluate
+# the trace in.
+test trace-20.7 {trace add command delete in subinterp while being deleted} {
+ set info {}
+ set tc [interp create]
+ interp alias $tc traceCommand {} traceCommand
+ $tc eval [list proc foo {} {}]
+ $tc eval [list trace add command foo {rename delete} traceCommand]
+ interp delete $tc
+ set info
+} {}
+
+proc traceDelete {cmd old new op} {
+ trace remove command $cmd {*}[lindex [trace info command $cmd] 0]
+ global info
+ set info [list $old $new $op]
+}
+proc traceCmdrename {cmd old new op} {
+ rename $old someothername
+}
+proc traceCmddelete {cmd old new op} {
+ rename $old ""
+}
+test trace-20.8 {trace delete while trace is active} {
+ set info {}
+ proc foo {} {}
+ catch {rename bar {}}
+ trace add command foo {rename delete} [list traceDelete foo]
+ rename foo bar
+ list [set info] [trace info command bar]
+} {{::foo ::bar rename} {}}
+
+test trace-20.9 {rename trace deletes command} {
+ set info {}
+ proc foo {} {}
+ catch {rename bar {}}
+ catch {rename someothername {}}
+ trace add command foo rename [list traceCmddelete foo]
+ rename foo bar
+ list [info commands foo] [info commands bar] [info commands someothername]
+} {{} {} {}}
+
+test trace-20.10 {rename trace renames command} {
+ set info {}
+ proc foo {} {}
+ catch {rename bar {}}
+ catch {rename someothername {}}
+ trace add command foo rename [list traceCmdrename foo]
+ rename foo bar
+ set info [list [info commands foo] [info commands bar] [info commands someothername]]
+ rename someothername {}
+ set info
+} {{} {} someothername}
+
+test trace-20.11 {delete trace deletes command} {
+ set info {}
+ proc foo {} {}
+ catch {rename bar {}}
+ catch {rename someothername {}}
+ trace add command foo delete [list traceCmddelete foo]
+ rename foo {}
+ list [info commands foo] [info commands bar] [info commands someothername]
+} {{} {} {}}
+
+test trace-20.12 {delete trace renames command} {
+ set info {}
+ proc foo {} {}
+ catch {rename bar {}}
+ catch {rename someothername {}}
+ trace add command foo delete [list traceCmdrename foo]
+ rename foo bar
+ rename bar {}
+ # None of these should exist.
+ list [info commands foo] [info commands bar] [info commands someothername]
+} {{} {} {}}
+
+test trace-20.13 {rename trace discards result [Bug 1355342]} {
+ proc foo {} {}
+ trace add command foo rename {set w Aha!;#}
+ list [rename foo bar] [rename bar {}]
+} {{} {}}
+test trace-20.14 {rename trace discards error result [Bug 1355342]} {
+ proc foo {} {}
+ trace add command foo rename {error}
+ list [rename foo bar] [rename bar {}]
+} {{} {}}
+test trace-20.15 {delete trace discards result [Bug 1355342]} {
+ proc foo {} {}
+ trace add command foo delete {set w Aha!;#}
+ rename foo {}
+} {}
+test trace-20.16 {delete trace discards error result [Bug 1355342]} {
+ proc foo {} {}
+ trace add command foo delete {error}
+ rename foo {}
+} {}
+
+
+proc foo {b} { set a $b }
+
+
+# Delete arrays when done, so they can be re-used as scalars
+# elsewhere.
+
+catch {unset x}
+catch {unset y}
+
+# Delete procedures when done, so we don't clash with other tests
+# (e.g. foobar will clash with 'unknown' tests).
+catch {rename foobar {}}
+catch {rename foo {}}
+catch {rename bar {}}
+
+proc foo {a} {
+ set b $a
+}
+
+proc traceExecute {args} {
+ global info
+ lappend info $args
+}
+
+test trace-21.1 {trace execution: enter} {
+ set info {}
+ trace add execution foo enter [list traceExecute foo]
+ foo 1
+ trace remove execution foo enter [list traceExecute foo]
+ set info
+} {{foo {foo 1} enter}}
+
+test trace-21.2 {trace exeuction: leave} {
+ set info {}
+ trace add execution foo leave [list traceExecute foo]
+ foo 2
+ trace remove execution foo leave [list traceExecute foo]
+ set info
+} {{foo {foo 2} 0 2 leave}}
+
+test trace-21.3 {trace exeuction: enter, leave} {
+ set info {}
+ trace add execution foo {enter leave} [list traceExecute foo]
+ foo 3
+ trace remove execution foo {enter leave} [list traceExecute foo]
+ set info
+} {{foo {foo 3} enter} {foo {foo 3} 0 3 leave}}
+
+test trace-21.4 {trace execution: enter, leave, enterstep} {
+ set info {}
+ trace add execution foo {enter leave enterstep} [list traceExecute foo]
+ foo 3
+ trace remove execution foo {enter leave enterstep} [list traceExecute foo]
+ set info
+} {{foo {foo 3} enter} {foo {set b 3} enterstep} {foo {foo 3} 0 3 leave}}
+
+test trace-21.5 {trace execution: enter, leave, enterstep, leavestep} {
+ set info {}
+ trace add execution foo {enter leave enterstep leavestep} [list traceExecute foo]
+ foo 3
+ trace remove execution foo {enter leave enterstep leavestep} [list traceExecute foo]
+ set info
+} {{foo {foo 3} enter} {foo {set b 3} enterstep} {foo {set b 3} 0 3 leavestep} {foo {foo 3} 0 3 leave}}
+
+test trace-21.6 {trace execution: enterstep, leavestep} {
+ set info {}
+ trace add execution foo {enterstep leavestep} [list traceExecute foo]
+ foo 3
+ trace remove execution foo {enterstep leavestep} [list traceExecute foo]
+ set info
+} {{foo {set b 3} enterstep} {foo {set b 3} 0 3 leavestep}}
+
+test trace-21.7 {trace execution: enterstep} {
+ set info {}
+ trace add execution foo {enterstep} [list traceExecute foo]
+ foo 3
+ trace remove execution foo {enterstep} [list traceExecute foo]
+ set info
+} {{foo {set b 3} enterstep}}
+
+test trace-21.8 {trace execution: leavestep} {
+ set info {}
+ trace add execution foo {leavestep} [list traceExecute foo]
+ foo 3
+ trace remove execution foo {leavestep} [list traceExecute foo]
+ set info
+} {{foo {set b 3} 0 3 leavestep}}
+
+test trace-21.9 {trace execution: TCL_EVAL_GLOBAL} testevalobjv {
+ trace add execution foo enter soom
+ proc ::soom args {lappend ::info SUCCESS [info level]}
+ set ::info {}
+ namespace eval test_ns_1 {
+ proc soom args {lappend ::info FAIL [info level]}
+ # [testevalobjv 1 ...] ought to produce the same
+ # results as [uplevel #0 ...].
+ testevalobjv 1 foo x
+ uplevel #0 foo x
+ }
+ namespace delete test_ns_1
+ trace remove execution foo enter soom
+ set ::info
+} {SUCCESS 1 SUCCESS 1}
+
+test trace-21.10 {trace execution: TCL_EVAL_GLOBAL} testevalobjv {
+ trace add execution foo leave soom
+ proc ::soom args {lappend ::info SUCCESS [info level]}
+ set ::info {}
+ namespace eval test_ns_1 {
+ proc soom args {lappend ::info FAIL [info level]}
+ # [testevalobjv 1 ...] ought to produce the same
+ # results as [uplevel #0 ...].
+ testevalobjv 1 foo x
+ uplevel #0 foo x
+ }
+ namespace delete test_ns_1
+ trace remove execution foo leave soom
+ set ::info
+} {SUCCESS 1 SUCCESS 1}
+
+test trace-21.11 {trace execution and alias} -setup {
+ set res {}
+ proc ::x {} {return ::}
+ namespace eval a {}
+ proc ::a::x {} {return ::a}
+ interp alias {} y {} x
+} -body {
+ lappend res [namespace eval ::a y]
+ trace add execution ::x enter {
+ rename ::x {}
+ proc ::x {} {return ::}
+ #}
+ lappend res [namespace eval ::a y]
+} -cleanup {
+ namespace delete a
+ rename ::x {}
+} -result {:: ::}
+
+proc factorial {n} {
+ if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }
+ return 1
+}
+
+test trace-22.1 {recursive(1) trace execution: enter} {
+ set info {}
+ trace add execution factorial {enter} [list traceExecute factorial]
+ factorial 1
+ trace remove execution factorial {enter} [list traceExecute factorial]
+ set info
+} {{factorial {factorial 1} enter}}
+
+test trace-22.2 {recursive(2) trace execution: enter} {
+ set info {}
+ trace add execution factorial {enter} [list traceExecute factorial]
+ factorial 2
+ trace remove execution factorial {enter} [list traceExecute factorial]
+ set info
+} {{factorial {factorial 2} enter} {factorial {factorial 1} enter}}
+
+test trace-22.3 {recursive(3) trace execution: enter} {
+ set info {}
+ trace add execution factorial {enter} [list traceExecute factorial]
+ factorial 3
+ trace remove execution factorial {enter} [list traceExecute factorial]
+ set info
+} {{factorial {factorial 3} enter} {factorial {factorial 2} enter} {factorial {factorial 1} enter}}
+
+test trace-23.1 {recursive(1) trace execution: enter, leave, enterstep, leavestep} {
+ set info {}
+ trace add execution factorial {enter leave enterstep leavestep} [list traceExecute]
+ factorial 1
+ trace remove execution factorial {enter leave enterstep leavestep} [list traceExecute]
+ join $info "\n"
+} {{factorial 1} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 0 {} leavestep
+{return 1} enterstep
+{return 1} 2 1 leavestep
+{factorial 1} 0 1 leave}
+
+test trace-23.2 {recursive(2) trace execution: enter, leave, enterstep, leavestep} {
+ set info {}
+ trace add execution factorial {enter leave enterstep leavestep} [list traceExecute]
+ factorial 2
+ trace remove execution factorial {enter leave enterstep leavestep} [list traceExecute]
+ join $info "\n"
+} {{factorial 2} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{expr {$n * [factorial [expr {$n -1 }]]}} enterstep
+{expr {$n -1 }} enterstep
+{expr {$n -1 }} 0 1 leavestep
+{factorial 1} enterstep
+{factorial 1} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 0 {} leavestep
+{return 1} enterstep
+{return 1} 2 1 leavestep
+{factorial 1} 0 1 leave
+{factorial 1} 0 1 leavestep
+{expr {$n * [factorial [expr {$n -1 }]]}} 0 2 leavestep
+{return 2} enterstep
+{return 2} 2 2 leavestep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 2 2 leavestep
+{factorial 2} 0 2 leave}
+
+test trace-23.3 {recursive(3) trace execution: enter, leave, enterstep, leavestep} {
+ set info {}
+ trace add execution factorial {enter leave enterstep leavestep} [list traceExecute]
+ factorial 3
+ trace remove execution factorial {enter leave enterstep leavestep} [list traceExecute]
+ join $info "\n"
+} {{factorial 3} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{expr {$n * [factorial [expr {$n -1 }]]}} enterstep
+{expr {$n -1 }} enterstep
+{expr {$n -1 }} 0 2 leavestep
+{factorial 2} enterstep
+{factorial 2} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{expr {$n * [factorial [expr {$n -1 }]]}} enterstep
+{expr {$n -1 }} enterstep
+{expr {$n -1 }} 0 1 leavestep
+{factorial 1} enterstep
+{factorial 1} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 0 {} leavestep
+{return 1} enterstep
+{return 1} 2 1 leavestep
+{factorial 1} 0 1 leave
+{factorial 1} 0 1 leavestep
+{expr {$n * [factorial [expr {$n -1 }]]}} 0 2 leavestep
+{return 2} enterstep
+{return 2} 2 2 leavestep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 2 2 leavestep
+{factorial 2} 0 2 leave
+{factorial 2} 0 2 leavestep
+{expr {$n * [factorial [expr {$n -1 }]]}} 0 6 leavestep
+{return 6} enterstep
+{return 6} 2 6 leavestep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 2 6 leavestep
+{factorial 3} 0 6 leave}
+
+proc traceDelete {cmd args} {
+ trace remove execution $cmd {*}[lindex [trace info execution $cmd] 0]
+ global info
+ set info $args
+}
+
+test trace-24.1 {delete trace during enter trace} {
+ set info {}
+ trace add execution foo enter [list traceDelete foo]
+ foo 1
+ list $info [catch {trace info execution foo} res] $res
+} {{{foo 1} enter} 0 {}}
+
+test trace-24.2 {delete trace during leave trace} {
+ set info {}
+ trace add execution foo leave [list traceDelete foo]
+ foo 1
+ list $info [catch {trace info execution foo} res] $res
+} {{{foo 1} 0 1 leave} 0 {}}
+
+test trace-24.3 {delete trace during enter-leave trace} {
+ set info {}
+ trace add execution foo {enter leave} [list traceDelete foo]
+ foo 1
+ list $info [catch {trace info execution foo} res] $res
+} {{{foo 1} enter} 0 {}}
+
+test trace-24.4 {delete trace during all exec traces} {
+ set info {}
+ trace add execution foo {enter leave enterstep leavestep} [list traceDelete foo]
+ foo 1
+ list $info [catch {trace info execution foo} res] $res
+} {{{foo 1} enter} 0 {}}
+
+test trace-24.5 {delete trace during all exec traces except enter} {
+ set info {}
+ trace add execution foo {leave enterstep leavestep} [list traceDelete foo]
+ foo 1
+ list $info [catch {trace info execution foo} res] $res
+} {{{set b 1} enterstep} 0 {}}
+
+proc traceDelete {cmd args} {
+ rename $cmd {}
+ global info
+ set info $args
+}
+
+proc foo {a} {
+ set b $a
+}
+
+test trace-25.1 {delete command during enter trace} {
+ set info {}
+ trace add execution foo enter [list traceDelete foo]
+ catch {foo 1} err
+ list $err $info [catch {trace info execution foo} res] $res
+} {{invalid command name "foo"} {{foo 1} enter} 1 {unknown command "foo"}}
+
+proc foo {a} {
+ set b $a
+}
+
+test trace-25.2 {delete command during leave trace} {
+ set info {}
+ trace add execution foo leave [list traceDelete foo]
+ foo 1
+ list $info [catch {trace info execution foo} res] $res
+} {{{foo 1} 0 1 leave} 1 {unknown command "foo"}}
+
+proc foo {a} {
+ set b $a
+}
+
+test trace-25.3 {delete command during enter then leave trace} {
+ set info {}
+ trace add execution foo enter [list traceDelete foo]
+ trace add execution foo leave [list traceDelete foo]
+ catch {foo 1} err
+ list $err $info [catch {trace info execution foo} res] $res
+} {{invalid command name "foo"} {{foo 1} enter} 1 {unknown command "foo"}}
+
+proc foo {a} {
+ set b $a
+}
+proc traceExecute2 {args} {
+ global info
+ lappend info $args
+}
+
+# This shows the peculiar consequences of having two traces
+# at the same time: as well as tracing the procedure you want
+test trace-25.4 {order dependencies of two enter traces} {
+ set info {}
+ trace add execution foo enter [list traceExecute traceExecute]
+ trace add execution foo enter [list traceExecute2 traceExecute2]
+ catch {foo 1} err
+ trace remove execution foo enter [list traceExecute traceExecute]
+ trace remove execution foo enter [list traceExecute2 traceExecute2]
+ join [list $err [join $info \n] [trace info execution foo]] "\n"
+} {1
+traceExecute2 {foo 1} enter
+traceExecute {foo 1} enter
+}
+
+test trace-25.5 {order dependencies of two step traces} {
+ set info {}
+ trace add execution foo enterstep [list traceExecute traceExecute]
+ trace add execution foo enterstep [list traceExecute2 traceExecute2]
+ catch {foo 1} err
+ trace remove execution foo enterstep [list traceExecute traceExecute]
+ trace remove execution foo enterstep [list traceExecute2 traceExecute2]
+ join [list $err [join $info \n] [trace info execution foo]] "\n"
+} {1
+traceExecute2 {set b 1} enterstep
+traceExecute {set b 1} enterstep
+}
+
+# We don't want the result string (5th argument), or the results
+# will get unmanageable.
+proc tracePostExecute {args} {
+ global info
+ lappend info [concat [lrange $args 0 2] [lindex $args 4]]
+}
+proc tracePostExecute2 {args} {
+ global info
+ lappend info [concat [lrange $args 0 2] [lindex $args 4]]
+}
+
+test trace-25.6 {order dependencies of two leave traces} {
+ set info {}
+ trace add execution foo leave [list tracePostExecute tracePostExecute]
+ trace add execution foo leave [list tracePostExecute2 tracePostExecute2]
+ catch {foo 1} err
+ trace remove execution foo leave [list tracePostExecute tracePostExecute]
+ trace remove execution foo leave [list tracePostExecute2 tracePostExecute2]
+ join [list $err [join $info \n] [trace info execution foo]] "\n"
+} {1
+tracePostExecute {foo 1} 0 leave
+tracePostExecute2 {foo 1} 0 leave
+}
+
+test trace-25.7 {order dependencies of two leavestep traces} {
+ set info {}
+ trace add execution foo leavestep [list tracePostExecute tracePostExecute]
+ trace add execution foo leavestep [list tracePostExecute2 tracePostExecute2]
+ catch {foo 1} err
+ trace remove execution foo leavestep [list tracePostExecute tracePostExecute]
+ trace remove execution foo leavestep [list tracePostExecute2 tracePostExecute2]
+ join [list $err [join $info \n] [trace info execution foo]] "\n"
+} {1
+tracePostExecute {set b 1} 0 leavestep
+tracePostExecute2 {set b 1} 0 leavestep
+}
+
+proc foo {a} {
+ set b $a
+}
+
+proc traceDelete {cmd args} {
+ rename $cmd {}
+ global info
+ set info $args
+}
+
+test trace-25.8 {delete command during enter leave and enter/leave-step traces} {
+ set info {}
+ trace add execution foo enter [list traceDelete foo]
+ trace add execution foo leave [list traceDelete foo]
+ trace add execution foo enterstep [list traceDelete foo]
+ trace add execution foo leavestep [list traceDelete foo]
+ catch {foo 1} err
+ list $err $info [catch {trace info execution foo} res] $res
+} {{invalid command name "foo"} {{foo 1} enter} 1 {unknown command "foo"}}
+
+proc foo {a} {
+ set b $a
+}
+
+test trace-25.9 {delete command during enter leave and leavestep traces} {
+ set info {}
+ trace add execution foo enter [list traceDelete foo]
+ trace add execution foo leave [list traceDelete foo]
+ trace add execution foo leavestep [list traceDelete foo]
+ catch {foo 1} err
+ list $err $info [catch {trace info execution foo} res] $res
+} {{invalid command name "foo"} {{foo 1} enter} 1 {unknown command "foo"}}
+
+proc foo {a} {
+ set b $a
+}
+
+test trace-25.10 {delete command during leave and leavestep traces} {
+ set info {}
+ trace add execution foo leave [list traceDelete foo]
+ trace add execution foo leavestep [list traceDelete foo]
+ catch {foo 1} err
+ list $err $info [catch {trace info execution foo} res] $res
+} {1 {{set b 1} 0 1 leavestep} 1 {unknown command "foo"}}
+
+proc foo {a} {
+ set b $a
+}
+
+test trace-25.11 {delete command during enter and enterstep traces} {
+ set info {}
+ trace add execution foo enter [list traceDelete foo]
+ trace add execution foo enterstep [list traceDelete foo]
+ catch {foo 1} err
+ list $err $info [catch {trace info execution foo} res] $res
+} {{invalid command name "foo"} {{foo 1} enter} 1 {unknown command "foo"}}
+
+test trace-26.1 {trace targetCmd when invoked through an alias} {
+ proc foo {args} {
+ set b $args
+ }
+ set info {}
+ trace add execution foo enter [list traceExecute foo]
+ interp alias {} bar {} foo 1
+ bar 2
+ trace remove execution foo enter [list traceExecute foo]
+ set info
+} {{foo {foo 1 2} enter}}
+test trace-26.2 {trace targetCmd when invoked through an alias} {
+ proc foo {args} {
+ set b $args
+ }
+ set info {}
+ trace add execution foo enter [list traceExecute foo]
+ interp create child
+ interp alias child bar {} foo 1
+ child eval bar 2
+ interp delete child
+ trace remove execution foo enter [list traceExecute foo]
+ set info
+} {{foo {foo 1 2} enter}}
+
+test trace-27.1 {memory leak in rename trace (604609)} {
+ catch {rename bar {}}
+ proc foo {} {error foo}
+ trace add command foo rename {rename foo "" ;#}
+ rename foo bar
+ info commands foo
+} {}
+
+test trace-27.2 {command trace remove nonsense} {
+ list [catch {trace remove command thisdoesntexist \
+ {delete rename} bar} res] $res
+} {1 {unknown command "thisdoesntexist"}}
+
+test trace-27.3 {command trace info nonsense} {
+ list [catch {trace info command thisdoesntexist} res] $res
+} {1 {unknown command "thisdoesntexist"}}
+
+
+test trace-28.1 {enterstep and leavestep traces with update idletasks (615043)} {
+ catch {rename foo {}}
+ proc foo {} {
+ set a 1
+ update idletasks
+ set b 1
+ }
+
+ set info {}
+ trace add execution foo {enter enterstep leavestep leave} \
+ [list traceExecute foo]
+ update
+ after idle {set a "idle"}
+ foo
+
+ trace remove execution foo {enter enterstep leavestep leave} \
+ [list traceExecute foo]
+ rename foo {}
+ catch {unset a}
+ join $info "\n"
+} {foo foo enter
+foo {set a 1} enterstep
+foo {set a 1} 0 1 leavestep
+foo {update idletasks} enterstep
+foo {set a idle} enterstep
+foo {set a idle} 0 idle leavestep
+foo {update idletasks} 0 {} leavestep
+foo {set b 1} enterstep
+foo {set b 1} 0 1 leavestep
+foo foo 0 1 leave}
+
+test trace-28.2 {exec traces with 'error'} {
+ set info {}
+ set res {}
+
+ proc foo {} {
+ if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }
+ }
+
+ proc bar {} { error "msg" }
+
+ lappend res [foo]
+
+ trace add execution foo {enter enterstep leave leavestep} \
+ [list traceExecute foo]
+
+ # With the trace active
+
+ lappend res [foo]
+
+ trace remove execution foo {enter enterstep leave leavestep} \
+ [list traceExecute foo]
+
+ list $res [join $info \n]
+} {{error error} {foo foo enter
+foo {if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }} enterstep
+foo {catch bar} enterstep
+foo bar enterstep
+foo {error msg} enterstep
+foo {error msg} 1 msg leavestep
+foo bar 1 msg leavestep
+foo {catch bar} 0 1 leavestep
+foo {return error} enterstep
+foo {return error} 2 error leavestep
+foo {if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }} 2 error leavestep
+foo foo 0 error leave}}
+
+test trace-28.3 {exec traces with 'return -code error'} {
+ set info {}
+ set res {}
+
+ proc foo {} {
+ if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }
+ }
+
+ proc bar {} { return -code error "msg" }
+
+ lappend res [foo]
+
+ trace add execution foo {enter enterstep leave leavestep} \
+ [list traceExecute foo]
+
+ # With the trace active
+
+ lappend res [foo]
+
+ trace remove execution foo {enter enterstep leave leavestep} \
+ [list traceExecute foo]
+
+ list $res [join $info \n]
+} {{error error} {foo foo enter
+foo {if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }} enterstep
+foo {catch bar} enterstep
+foo bar enterstep
+foo {return -code error msg} enterstep
+foo {return -code error msg} 2 msg leavestep
+foo bar 1 msg leavestep
+foo {catch bar} 0 1 leavestep
+foo {return error} enterstep
+foo {return error} 2 error leavestep
+foo {if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }} 2 error leavestep
+foo foo 0 error leave}}
+
+test trace-28.4 {exec traces in slave with 'return -code error'} {
+ interp create slave
+ interp alias slave traceExecute {} traceExecute
+ set info {}
+ set res [interp eval slave {
+ set info {}
+ set res {}
+
+ proc foo {} {
+ if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }
+ }
+
+ proc bar {} { return -code error "msg" }
+
+ lappend res [foo]
+
+ trace add execution foo {enter enterstep leave leavestep} \
+ [list traceExecute foo]
+
+ # With the trace active
+
+ lappend res [foo]
+
+ trace remove execution foo {enter enterstep leave leavestep} \
+ [list traceExecute foo]
+
+ list $res
+ }]
+ interp delete slave
+ lappend res [join $info \n]
+} {{error error} {foo foo enter
+foo {if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }} enterstep
+foo {catch bar} enterstep
+foo bar enterstep
+foo {return -code error msg} enterstep
+foo {return -code error msg} 2 msg leavestep
+foo bar 1 msg leavestep
+foo {catch bar} 0 1 leavestep
+foo {return error} enterstep
+foo {return error} 2 error leavestep
+foo {if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }} 2 error leavestep
+foo foo 0 error leave}}
+
+test trace-28.5 {exec traces} {
+ set info {}
+ proc foo {args} { set a 1 }
+ trace add execution foo {enter enterstep leave leavestep} \
+ [list traceExecute foo]
+ after idle [list foo test-28.4]
+ update
+ # Complicated way of removing traces
+ set ti [lindex [eval [list trace info execution ::foo]] 0]
+ if {[llength $ti]} {
+ eval [concat [list trace remove execution foo] $ti]
+ }
+ join $info \n
+} {foo {foo test-28.4} enter
+foo {set a 1} enterstep
+foo {set a 1} 0 1 leavestep
+foo {foo test-28.4} 0 1 leave}
+
+test trace-28.6 {exec traces firing order} {
+ set info {}
+ proc enterStep {cmd op} {lappend ::info "enter $cmd/$op"}
+ proc leaveStep {cmd code result op} {lappend ::info "leave $cmd/$code/$result/$op"}
+
+ proc foo x {
+ set b x=$x
+ incr x
+ }
+ trace add execution foo enterstep enterStep
+ trace add execution foo leavestep leaveStep
+ foo 42
+ rename foo {}
+ join $info \n
+} {enter set b x=42/enterstep
+leave set b x=42/0/x=42/leavestep
+enter incr x/enterstep
+leave incr x/0/43/leavestep}
+
+test trace-28.7 {exec trace information} {
+ set info {}
+ proc foo x { incr x }
+ proc bar {args} {}
+ trace add execution foo {enter leave enterstep leavestep} bar
+ set info [trace info execution foo]
+ trace remove execution foo {enter leave enterstep leavestep} bar
+} {}
+
+test trace-28.8 {exec trace remove nonsense} {
+ list [catch {trace remove execution thisdoesntexist \
+ {enter leave enterstep leavestep} bar} res] $res
+} {1 {unknown command "thisdoesntexist"}}
+
+test trace-28.9 {exec trace info nonsense} {
+ list [catch {trace info execution thisdoesntexist} res] $res
+} {1 {unknown command "thisdoesntexist"}}
+
+test trace-28.10 {exec trace info nonsense} {
+ list [catch {trace remove execution} res] $res
+} {1 {wrong # args: should be "trace remove execution name opList command"}}
+
+test trace-29.1 {Tcl_CreateTrace, correct command and argc/argv arguments of trace proc} {testcmdtrace} {
+ testcmdtrace tracetest {set stuff [expr 14 + 16]}
+} {{expr 14 + 16} {expr 14 + 16} {set stuff [expr 14 + 16]} {set stuff 30}}
+test trace-29.2 {Tcl_CreateTrace, correct command and argc/argv arguments of trace proc} {testcmdtrace} {
+ testcmdtrace tracetest {set stuff [info tclversion]}
+} [concat {{info tclversion} {info tclversion} ::tcl::info::tclversion {::tcl::info::tclversion} {set stuff [info tclversion]}} [list "set stuff [info tclversion]"]]
+test trace-29.3 {Tcl_CreateTrace, correct command and argc/argv arguments of trace proc} {testcmdtrace} {
+ testcmdtrace deletetest {set stuff [info tclversion]}
+} [info tclversion]
+test trace-29.4 {Tcl_CreateTrace, check that tracing doesn't cause memory faults} {testcmdtrace} {
+ # Note that the proc call is the same as the variable name, and that
+ # the call can be direct or indirect by way of another procedure
+ proc tracer {args} {}
+ proc tracedLoop {level} {
+ incr level
+ tracer
+ foreach tracer [expr {$level==1 ? {1 2} : {}}] {tracedLoop $level}
+ }
+ testcmdtrace tracetest {tracedLoop 0}
+} {{tracedLoop 0} {tracedLoop 0} {incr level} {incr level} tracer {tracer} {expr {$level==1 ? {1 2} : {}}} {expr {$level==1 ? {1 2} : {}}} {foreach tracer [expr {$level==1 ? {1 2} : {}}] {tracedLoop $level}} {foreach tracer {1 2} {tracedLoop $level}} {tracedLoop $level} {tracedLoop 1} {incr level} {incr level} tracer {tracer} {expr {$level==1 ? {1 2} : {}}} {expr {$level==1 ? {1 2} : {}}} {foreach tracer [expr {$level==1 ? {1 2} : {}}] {tracedLoop $level}} {foreach tracer {} {tracedLoop $level}} {tracedLoop $level} {tracedLoop 1} {incr level} {incr level} tracer {tracer} {expr {$level==1 ? {1 2} : {}}} {expr {$level==1 ? {1 2} : {}}} {foreach tracer [expr {$level==1 ? {1 2} : {}}] {tracedLoop $level}} {foreach tracer {} {tracedLoop $level}}}
+catch {rename tracer {}}
+catch {rename tracedLoop {}}
+
+test trace-29.5 {Tcl_CreateObjTrace, status return TCL_ERROR} {testcmdtrace} {
+ proc Error { args } { error "Shouldn't get here" }
+ set x 1;
+ list [catch {testcmdtrace resulttest {Error $x}} result] [set result]
+} {1 {Error $x}}
+
+test trace-29.6 {Tcl_CreateObjTrace, status return TCL_RETURN} {testcmdtrace} {
+ proc Return { args } { error "Shouldn't get here" }
+ set x 1;
+ list [catch {testcmdtrace resulttest {Return $x}} result] [set result]
+} {2 {}}
+
+test trace-29.7 {Tcl_CreateObjTrace, status return TCL_BREAK} {testcmdtrace} {
+ proc Break { args } { error "Shouldn't get here" }
+ set x 1;
+ list [catch {testcmdtrace resulttest {Break $x}} result] [set result]
+} {3 {}}
+
+test trace-29.8 {Tcl_CreateObjTrace, status return TCL_CONTINUE} {testcmdtrace} {
+ proc Continue { args } { error "Shouldn't get here" }
+ set x 1;
+ list [catch {testcmdtrace resulttest {Continue $x}} result] [set result]
+} {4 {}}
+
+test trace-29.9 {Tcl_CreateObjTrace, status return unknown} {testcmdtrace} {
+ proc OtherStatus { args } { error "Shouldn't get here" }
+ set x 1;
+ list [catch {testcmdtrace resulttest {OtherStatus $x}} result] [set result]
+} {6 {}}
+
+test trace-29.10 {Tcl_CreateTrace, correct level interpretation} {testcmdtrace} {
+ proc foo {} {uplevel 1 bar}
+ proc bar {} {uplevel 1 grok}
+ proc grok {} {uplevel 1 spock}
+ proc spock {} {uplevel 1 fascinating}
+ proc fascinating {} {}
+ testcmdtrace leveltest {foo}
+} {foo {foo} {uplevel 1 bar} {uplevel 1 bar} bar {bar} {uplevel 1 grok} {uplevel 1 grok}}
+
+test trace-29.11 {Tcl_CreateTrace, multiple traces} {testcmdtrace} {
+ testcmdtrace doubletest {format xx}
+} {{format xx} {format xx}}
+
+test trace-30.1 {Tcl_DeleteTrace} {emptyTest} {
+ # the above tests have tested Tcl_DeleteTrace
+} {}
+
+test trace-31.1 {command and execution traces shared struct} {
+ # Tcl Bug 807243
+ proc foo {} {}
+ trace add command foo delete foo
+ trace add execution foo enter foo
+ set result [trace info command foo]
+ trace remove command foo delete foo
+ trace remove execution foo enter foo
+ rename foo {}
+ set result
+} [list [list delete foo]]
+test trace-31.2 {command and execution traces shared struct} {
+ # Tcl Bug 807243
+ proc foo {} {}
+ trace add command foo delete foo
+ trace add execution foo enter foo
+ set result [trace info execution foo]
+ trace remove command foo delete foo
+ trace remove execution foo enter foo
+ rename foo {}
+ set result
+} [list [list enter foo]]
+
+test trace-32.1 {
+ TraceCommandInfo refcount decr in TraceCommandProc w/o loss of reference
+} {
+ # Tcl Bug 811483
+ proc foo {} {}
+ trace add command foo delete foo
+ trace add execution foo enter foo
+ set result [trace info command foo]
+ rename foo {}
+ set result
+} [list [list delete foo]]
+
+test trace-33.1 {variable match with remove variable} {
+ unset -nocomplain x
+ trace variable x w foo
+ trace remove variable x write foo
+ llength [trace info variable x]
+} 0
+
+test trace-34.1 {Bug 1201035} {
+ set ::x [list]
+ proc foo {} {lappend ::x foo}
+ proc bar args {
+ lappend ::x $args
+ trace remove execution foo leavestep bar
+ trace remove execution foo enterstep bar
+ trace add execution foo leavestep bar
+ trace add execution foo enterstep bar
+ lappend ::x done
+ }
+ trace add execution foo leavestep bar
+ trace add execution foo enterstep bar
+ foo
+ set ::x
+} {{{lappend ::x foo} enterstep} done foo}
+
+test trace-34.2 {Bug 1224585} {
+ proc foo {} {}
+ proc bar args {trace remove execution foo leave soom}
+ trace add execution foo leave bar
+ trace add execution foo leave soom
+ foo
+} {}
+
+test trace-34.3 {Bug 1224585} {
+ proc foo {} {set x {}}
+ proc bar args {trace remove execution foo enterstep soom}
+ trace add execution foo enterstep soom
+ trace add execution foo enterstep bar
+ foo
+} {}
+
+# We test here for the half-documented and currently valid interplay between
+# delete traces and namespace deletion.
+test trace-34.4 {Bug 1047286} {
+ variable x notrace
+ proc callback {old - -} {
+ variable x "$old exists: [namespace which -command $old]"
+ }
+ namespace eval ::foo {proc bar {} {}}
+ trace add command ::foo::bar delete [namespace code callback]
+ namespace delete ::foo
+ set x
+} {::foo::bar exists: ::foo::bar}
+
+test trace-34.5 {Bug 1047286} {
+ variable x notrace
+ proc callback {old - -} {
+ variable x "$old exists: [namespace which -command $old]"
+ }
+ namespace eval ::foo {proc bar {} {}}
+ trace add command ::foo::bar delete [namespace code callback]
+ namespace eval ::foo namespace delete ::foo
+ set x
+} {::foo::bar exists: }
+
+test trace-34.6 {Bug 1458266} -setup {
+ proc dummy {} {}
+ proc stepTraceHandler {cmdString args} {
+ variable log
+ append log "[expr {[info level] - 1}]: [lindex [split $cmdString] 0]\n"
+ dummy
+ isTracedInside_2
+ }
+ proc cmdTraceHandler {cmdString args} {
+ # silent
+ }
+ proc isTracedInside_1 {} {
+ isTracedInside_2
+ }
+ proc isTracedInside_2 {} {
+ set x 2
+ }
+} -body {
+ variable log {}
+ trace add execution isTracedInside_1 enterstep stepTraceHandler
+ trace add execution isTracedInside_2 enterstep stepTraceHandler
+ isTracedInside_1
+ variable first $log
+ set log {}
+ trace add execution dummy enter cmdTraceHandler
+ isTracedInside_1
+ variable second $log
+ expr {($first eq $second) ? "ok" : "\n$first\nand\n\n$second\ndiffer"}
+} -cleanup {
+ unset -nocomplain log first second
+ rename dummy {}
+ rename stepTraceHandler {}
+ rename cmdTraceHandler {}
+ rename isTracedInside_1 {}
+ rename isTracedInside_2 {}
+} -result ok
+
+test trace-35.1 {527164: Keep -errorinfo of traces} -setup {
+ unset -nocomplain x y
+} -body {
+ trace add variable x write {error foo;#}
+ trace add variable y write {set x 2;#}
+ list [catch {set y 1} msg opts] $msg [dict get $opts -errorinfo]
+} -cleanup {
+ unset -nocomplain x y
+} -result {1 {can't set "y": can't set "x": foo} {foo
+ while executing
+"error foo"
+ (write trace on "x")
+ invoked from within
+"set x 2"
+ (write trace on "y")
+ invoked from within
+"set y 1"}}
+
+
+#
+# Test for the correct(?) dynamics of execution traces. This test insures that
+# the dynamics of the original implementation remain valid; note that
+# these aspects are neither documented nor do they appear in TIP 62
+
+proc traceproc {tracevar args} {
+ append ::$tracevar *
+}
+proc untraced {type} {
+ trace add execution untraced $type {traceproc tracevar}
+ append ::tracevar -
+}
+proc runbase {results base} {
+ set tt {enter leave enterstep leavestep}
+ foreach n {1 2 3 4} t $tt r $results {
+ eval [subst $base]
+ }
+}
+set base {
+ test trace-36.$n {dynamic trace creation: $t} -setup {
+ set ::tracevar {}
+ } -cleanup {
+ unset ::tracevar
+ trace remove execution untraced $t {traceproc tracevar}
+ } -body {
+ untraced $t
+ set ::tracevar
+ } -result {$r}
+}
+runbase {- - - -} $base
+
+set base {
+ test trace-37.$n {dynamic trace addition: $t} -setup {
+ set ::tracevar {}
+ set ::tracevar2 {}
+ trace add execution untraced enter {traceproc tracevar2}
+ } -cleanup {
+ trace remove execution untraced $t {traceproc tracevar}
+ trace remove execution untraced enter {traceproc tracevar2}
+ unset ::tracevar ::tracevar2
+ } -body {
+ untraced $t
+ list \$::tracevar \$::tracevar2
+ } -result {$r}
+}
+runbase {{- *} {-* *} {- *} {- *}} $base
+
+set base {
+ test trace-38.$n {dynamic trace addition: $t} -setup {
+ set ::tracevar {}
+ set ::tracevar2 {}
+ trace add execution untraced leave {traceproc tracevar2}
+ } -cleanup {
+ trace remove execution untraced $t {traceproc tracevar}
+ trace remove execution untraced leave {traceproc tracevar2}
+ unset ::tracevar ::tracevar2
+ } -body {
+ untraced $t
+ list \$::tracevar \$::tracevar2
+ } -result {$r}
+}
+runbase {{- *} {-* *} {- *} {- *}} $base
+
+test trace-39 {bug #3484621: tracing Bc'ed commands} -setup {
+ set ::traceLog 0
+ set ::traceCalls 0
+ set ::bar [list 0 1 2 3]
+ set res {}
+ proc dotrace args {
+ incr ::traceLog
+ }
+ proc foo {} {
+ incr ::traceCalls
+ # choose a BC'ed command that is 'unlikely' to interfere with tcltest's
+ # internals
+ lset ::bar 1 2
+ }
+} -body {
+ foo
+ lappend res $::traceLog
+
+ trace add execution lset enter dotrace
+ foo
+ lappend res $::traceLog
+
+ trace remove execution lset enter dotrace
+ foo
+ lappend res $::traceLog
+
+ list $::traceCalls | {*}$res
+} -cleanup {
+ unset ::traceLog ::traceCalls ::bar res
+ rename dotrace {}
+ rename foo {}
+} -result {3 | 0 1 1}
+
+test trace-39.1 {bug #3485022: tracing Bc'ed commands} -setup {
+ set ::traceLog 0
+ set ::traceCalls 0
+ set res {}
+ proc dotrace args {
+ incr ::traceLog
+ }
+ proc foo {} {
+ incr ::traceCalls
+ string equal zip zap
+ }
+} -body {
+ foo
+ lappend res $::traceLog
+
+ trace add execution ::tcl::string::equal enter dotrace
+ foo
+ lappend res $::traceLog
+
+ trace remove execution tcl::string::equal enter dotrace
+ foo
+ lappend res $::traceLog
+
+ list $::traceCalls | {*}$res
+} -cleanup {
+ unset ::traceLog ::traceCalls res
+ rename dotrace {}
+ rename foo {}
+} -result {3 | 0 1 1}
+
+# Delete procedures when done, so we don't clash with other tests
+# (e.g. foobar will clash with 'unknown' tests).
+catch {rename foobar {}}
+catch {rename foo {}}
+catch {rename bar {}}
+catch {rename untraced {}}
+catch {rename traceproc {}}
+catch {rename runbase {}}
+
+# Unset the variable when done
+catch {unset info}
+catch {unset base}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/unixFCmd.test b/library/msgcat/tests/unixFCmd.test
new file mode 100644
index 0000000..e8148e9
--- /dev/null
+++ b/library/msgcat/tests/unixFCmd.test
@@ -0,0 +1,437 @@
+# This file tests the tclUnixFCmd.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testchmod [llength [info commands testchmod]]
+
+# These tests really need to be run from a writable directory, which
+# it is assumed [temporaryDirectory] is.
+set oldcwd [pwd]
+cd [temporaryDirectory]
+
+# Several tests require need to match results against the unix username
+set user {}
+if {[testConstraint unix]} {
+ catch {set user [exec whoami]}
+ if {$user == ""} {
+ catch {regexp {^[^(]*\(([^)]*)\)} [exec id] dummy user}
+ }
+ if {$user == ""} {
+ set user "root"
+ }
+}
+
+# Find a group that exists on this system, or else skip tests that require
+# groups
+testConstraint foundGroup 0
+if {[testConstraint unix]} {
+ catch {
+ set groupList [exec groups]
+ set group [lindex $groupList 0]
+ testConstraint foundGroup 1
+ }
+}
+
+# check whether -readonly attribute is supported
+testConstraint readonlyAttr 0
+if {[testConstraint unix]} {
+ set f [makeFile "whatever" probe]
+ catch {
+ file attributes $f -readonly
+ testConstraint readonlyAttr 1
+ }
+ removeFile probe
+}
+
+proc openup {path} {
+ testchmod 777 $path
+ if {[file isdirectory $path]} {
+ catch {
+ foreach p [glob -directory $path *] {
+ openup $p
+ }
+ }
+ }
+}
+
+proc cleanup {args} {
+ foreach p ". $args" {
+ set x ""
+ catch {
+ set x [glob -directory $p tf* td*]
+ }
+ foreach file $x {
+ if {
+ [catch {file delete -force -- $file}]
+ && [testConstraint testchmod]
+ } then {
+ openup $file
+ file delete -force -- $file
+ }
+ }
+ }
+}
+
+if {[testConstraint unix] && [testConstraint notRoot]} {
+ testConstraint execMknod [expr {![catch {exec mknod tf1 p}]}]
+ cleanup
+}
+
+test unixFCmd-1.1 {TclpRenameFile: EACCES} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir td1/td2/td3
+ file attributes td1/td2 -permissions 0000
+ file rename td1/td2/td3 td2
+} -returnCodes error -cleanup {
+ file attributes td1/td2 -permissions 0755
+ cleanup
+} -result {error renaming "td1/td2/td3": permission denied}
+test unixFCmd-1.2 {TclpRenameFile: EEXIST} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir td1/td2
+ file mkdir td2
+ file rename td2 td1
+} -returnCodes error -cleanup {
+ cleanup
+} -result {error renaming "td2" to "td1/td2": file already exists}
+test unixFCmd-1.3 {TclpRenameFile: EINVAL} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir td1
+ file rename td1 td1
+} -returnCodes error -cleanup {
+ cleanup
+} -result {error renaming "td1" to "td1/td1": trying to rename a volume or move a directory into itself}
+test unixFCmd-1.4 {TclpRenameFile: EISDIR} {emptyTest unix notRoot} {
+ # can't make it happen
+} {}
+test unixFCmd-1.5 {TclpRenameFile: ENOENT} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir td1
+ file rename td2 td1
+} -returnCodes error -cleanup {
+ cleanup
+} -result {error renaming "td2": no such file or directory}
+test unixFCmd-1.6 {TclpRenameFile: ENOTDIR} {emptyTest unix notRoot} {
+ # can't make it happen
+} {}
+test unixFCmd-1.7 {TclpRenameFile: EXDEV} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir foo/bar
+ file attr foo -perm 040555
+ file rename foo/bar /tmp
+} -returnCodes error -cleanup {
+ catch {file delete /tmp/bar}
+ catch {file attr foo -perm 040777}
+ catch {file delete -force foo}
+} -match glob -result {*: permission denied}
+test unixFCmd-1.8 {Checking EINTR Bug} {unix notRoot nonPortable} {
+ testalarm
+ after 2000
+ list [testgotsig] [testgotsig]
+} {1 0}
+test unixFCmd-1.9 {Checking EINTR Bug} -constraints {unix notRoot nonPortable} -setup {
+ cleanup
+ set f [open tfalarm w]
+ puts $f {
+ after 2000
+ puts "hello world"
+ exit 0
+ }
+ close $f
+} -body {
+ testalarm
+ set pipe [open "|[info nameofexecutable] tfalarm" r+]
+ set line [read $pipe 1]
+ catch {close $pipe}
+ list $line [testgotsig]
+} -cleanup {
+ cleanup
+} -result {h 1}
+
+test unixFCmd-2.1 {TclpCopyFile: target exists: lstat(dst) == 0} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ close [open tf1 a]
+ close [open tf2 a]
+ file copy -force tf1 tf2
+} -cleanup {
+ cleanup
+} -result {}
+test unixFCmd-2.2.1 {TclpCopyFile: src is symlink} -setup {
+ cleanup
+} -constraints {unix notRoot dontCopyLinks} -body {
+ # copying links should end up with real files
+ close [open tf1 a]
+ file link -symbolic tf2 tf1
+ file copy tf2 tf3
+ file type tf3
+} -cleanup {
+ cleanup
+} -result file
+test unixFCmd-2.2.2 {TclpCopyFile: src is symlink} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ # copying links should end up with the links copied
+ close [open tf1 a]
+ file link -symbolic tf2 tf1
+ file copy tf2 tf3
+ file type tf3
+} -cleanup {
+ cleanup
+} -result link
+test unixFCmd-2.3 {TclpCopyFile: src is block} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ set null "/dev/null"
+ while {[file type $null] != "characterSpecial"} {
+ set null [file join [file dirname $null] [file readlink $null]]
+ }
+ # file copy $null tf1
+} -result {}
+test unixFCmd-2.4 {TclpCopyFile: src is fifo} -setup {
+ cleanup
+} -constraints {unix notRoot execMknod} -body {
+ exec mknod tf1 p
+ file copy tf1 tf2
+ list [file type tf1] [file type tf2]
+} -cleanup {
+ cleanup
+} -result {fifo fifo}
+test unixFCmd-2.5 {TclpCopyFile: copy attributes} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ close [open tf1 a]
+ file attributes tf1 -permissions 0472
+ file copy tf1 tf2
+ file attributes tf2 -permissions
+} -cleanup {
+ cleanup
+} -result 00472 ;# i.e. perms field of [exec ls -l tf2] is -r--rwx-w-
+
+test unixFCmd-3.1 {CopyFile not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-4.1 {TclpDeleteFile not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-5.1 {TclpCreateDirectory not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-6.1 {TclpCopyDirectory not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-7.1 {TclpRemoveDirectory not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-8.1 {TraverseUnixTree not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-9.1 {TraversalCopy not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-10.1 {TraversalDelete not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-11.1 {CopyFileAttrs not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-12.1 {GetGroupAttribute - file not found} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+ file attributes foo.test -group
+} -result {could not read "foo.test": no such file or directory}
+test unixFCmd-12.2 {GetGroupAttribute - file found} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+ close [open foo.test w]
+ file attributes foo.test -group
+} -cleanup {
+ file delete -force -- foo.test
+} -match glob -result *
+
+test unixFCmd-13.1 {GetOwnerAttribute - file not found} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+ file attributes foo.test -group
+} -result {could not read "foo.test": no such file or directory}
+test unixFCmd-13.2 {GetOwnerAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+ close [open foo.test w]
+ file attributes foo.test -owner
+} -cleanup {
+ file delete -force -- foo.test
+} -result $user
+
+test unixFCmd-14.1 {GetPermissionsAttribute - file not found} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+ file attributes foo.test -permissions
+} -result {could not read "foo.test": no such file or directory}
+test unixFCmd-14.2 {GetPermissionsAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+ close [open foo.test w]
+ file attribute foo.test -permissions
+} -cleanup {
+ file delete -force -- foo.test
+} -match glob -result *
+
+#groups hard to test
+test unixFCmd-15.1 {SetGroupAttribute - invalid group} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+ file attributes foo.test -group foozzz
+} -returnCodes error -cleanup {
+ file delete -force -- foo.test
+} -result {could not set group for file "foo.test": group "foozzz" does not exist}
+test unixFCmd-15.2 {SetGroupAttribute - invalid file} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot foundGroup} -returnCodes error -body {
+ file attributes foo.test -group $group
+} -result {could not set group for file "foo.test": no such file or directory}
+
+#changing owners hard to do
+test unixFCmd-16.1 {SetOwnerAttribute - current owner} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+ close [open foo.test w]
+ list [file attributes foo.test -owner $user] \
+ [file attributes foo.test -owner]
+} -cleanup {
+ file delete -force -- foo.test
+} -result [list {} $user]
+test unixFCmd-16.2 {SetOwnerAttribute - invalid file} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+ file attributes foo.test -owner $user
+} -result {could not set owner for file "foo.test": no such file or directory}
+test unixFCmd-16.3 {SetOwnerAttribute - invalid owner} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+ file attributes foo.test -owner foozzz
+} -result {could not set owner for file "foo.test": user "foozzz" does not exist}
+
+test unixFCmd-17.1 {SetPermissionsAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+ close [open foo.test w]
+ list [file attributes foo.test -permissions 0000] \
+ [file attributes foo.test -permissions]
+} -cleanup {
+ file delete -force -- foo.test
+} -result {{} 00000}
+test unixFCmd-17.2 {SetPermissionsAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+ file attributes foo.test -permissions 0000
+} -result {could not set permissions for file "foo.test": no such file or directory}
+test unixFCmd-17.3 {SetPermissionsAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+ close [open foo.test w]
+ file attributes foo.test -permissions foo
+} -cleanup {
+ file delete -force -- foo.test
+} -returnCodes error -result {unknown permission string format "foo"}
+test unixFCmd-17.4 {SetPermissionsAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+ close [open foo.test w]
+ file attributes foo.test -permissions ---rwx
+} -cleanup {
+ file delete -force -- foo.test
+} -returnCodes error -result {unknown permission string format "---rwx"}
+
+close [open foo.test w]
+set ::i 4
+proc permcheck {testnum permstr expected} {
+ test $testnum {SetPermissionsAttribute} {unix notRoot} {
+ file attributes foo.test -permissions $permstr
+ file attributes foo.test -permissions
+ } $expected
+}
+permcheck unixFCmd-17.5 rwxrwxrwx 00777
+permcheck unixFCmd-17.6 r--r---w- 00442
+permcheck unixFCmd-17.7 0 00000
+permcheck unixFCmd-17.8 u+rwx,g+r 00740
+permcheck unixFCmd-17.9 u-w 00540
+permcheck unixFCmd-17.10 o+rwx 00547
+permcheck unixFCmd-17.11 --x--x--x 00111
+permcheck unixFCmd-17.12 a+rwx 00777
+file delete -force -- foo.test
+
+test unixFCmd-18.1 {Unix pwd} -constraints {unix notRoot nonPortable} -setup {
+ set cd [pwd]
+} -body {
+ # This test is nonportable because SunOS generates a weird error
+ # message when the current directory isn't readable.
+ set nd $cd/tstdir
+ file mkdir $nd
+ cd $nd
+ file attributes $nd -permissions 0000
+ pwd
+} -returnCodes error -cleanup {
+ cd $cd
+ file attributes $nd -permissions 0755
+ file delete $nd
+} -match glob -result {error getting working directory name:*}
+
+test unixFCmd-19.1 {GetReadOnlyAttribute - file not found} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot readonlyAttr} -returnCodes error -body {
+ file attributes foo.test -readonly
+} -result {could not read "foo.test": no such file or directory}
+test unixFCmd-19.2 {GetReadOnlyAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot readonlyAttr} -body {
+ close [open foo.test w]
+ file attribute foo.test -readonly
+} -cleanup {
+ file delete -force -- foo.test
+} -result 0
+
+test unixFCmd-20.1 {SetReadOnlyAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot readonlyAttr} -body {
+ close [open foo.test w]
+ list [catch {file attributes foo.test -readonly 1} msg] $msg \
+ [catch {file attribute foo.test -readonly} msg] $msg \
+ [catch {file delete -force -- foo.test}] \
+ [catch {file attributes foo.test -readonly 0} msg] $msg \
+ [catch {file attribute foo.test -readonly} msg] $msg
+} -cleanup {
+ file delete -force -- foo.test
+} -result {0 {} 0 1 1 0 {} 0 0}
+test unixFCmd-20.2 {SetReadOnlyAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot readonlyAttr} -returnCodes error -body {
+ file attributes foo.test -readonly 1
+} -result {could not read "foo.test": no such file or directory}
+
+# cleanup
+cleanup
+cd $oldcwd
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/unixFile.test b/library/msgcat/tests/unixFile.test
new file mode 100644
index 0000000..0ea0ec1
--- /dev/null
+++ b/library/msgcat/tests/unixFile.test
@@ -0,0 +1,62 @@
+# This file contains tests for the routines in the file tclUnixFile.c
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testfindexecutable [llength [info commands testfindexecutable]]
+
+set oldpwd [pwd]
+cd [temporaryDirectory]
+
+catch {
+ set oldPath $env(PATH)
+ file attributes [makeFile "" junk] -perm 0777
+}
+set absPath [file join [temporaryDirectory] junk]
+
+test unixFile-1.1 {Tcl_FindExecutable} {testfindexecutable unix} {
+ set env(PATH) ""
+ testfindexecutable junk
+} $absPath
+test unixFile-1.2 {Tcl_FindExecutable} {testfindexecutable unix} {
+ set env(PATH) "/dummy"
+ testfindexecutable junk
+} {}
+test unixFile-1.3 {Tcl_FindExecutable} {testfindexecutable unix} {
+ set env(PATH) "/dummy:[pwd]"
+ testfindexecutable junk
+} $absPath
+test unixFile-1.4 {Tcl_FindExecutable} {testfindexecutable unix} {
+ set env(PATH) "/dummy:"
+ testfindexecutable junk
+} $absPath
+test unixFile-1.5 {Tcl_FindExecutable} {testfindexecutable unix} {
+ set env(PATH) "/dummy:/dummy"
+ testfindexecutable junk
+} {}
+test unixFile-1.6 {Tcl_FindExecutable} {testfindexecutable unix} {
+ set env(PATH) "/dummy::/dummy"
+ testfindexecutable junk
+} $absPath
+test unixFile-1.7 {Tcl_FindExecutable} {testfindexecutable unix} {
+ set env(PATH) ":/dummy"
+ testfindexecutable junk
+} $absPath
+
+# cleanup
+catch {set env(PATH) $oldPath}
+removeFile junk
+cd $oldpwd
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/unixInit.test b/library/msgcat/tests/unixInit.test
new file mode 100644
index 0000000..9ba9c11
--- /dev/null
+++ b/library/msgcat/tests/unixInit.test
@@ -0,0 +1,402 @@
+# The file tests the functions in the tclUnixInit.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+package require tcltest 2.2
+namespace import -force ::tcltest::*
+unset -nocomplain path
+catch {set oldlang $env(LANG)}
+set env(LANG) C
+
+test unixInit-1.1 {TclpInitPlatform: ignore SIGPIPE} {unix stdio} {
+ set x {}
+ # Watch out for a race condition here. If tcltest is too slow to start
+ # then we'll kill it before it has a chance to set up its signal handler.
+ set f [open "|[list [interpreter]]" w+]
+ puts $f "puts hi"
+ flush $f
+ gets $f
+ exec kill -PIPE [pid $f]
+ lappend x [catch {close $f}]
+ set f [open "|[list [interpreter]]" w+]
+ puts $f "puts hi"
+ flush $f
+ gets $f
+ exec kill [pid $f]
+ lappend x [catch {close $f}]
+ set x
+} {0 1}
+# This test is really a test of code in tclUnixChan.c, but the channels are
+# set up as part of initialisation of the interpreter so the test seems to me
+# to fit here as well as anywhere else.
+test unixInit-1.2 {initialisation: standard channel type deduction} {unix stdio} {
+ # pipe1 is a connection to a server that reports what port it starts on,
+ # and delivers a constant string to the first client to connect to that
+ # port before exiting.
+ set pipe1 [open "|[list [interpreter]]" r+]
+ puts $pipe1 {
+ proc accept {channel host port} {
+ puts $channel {puts [fconfigure stdin -peername]; exit}
+ close $channel
+ exit
+ }
+ puts [fconfigure [socket -server accept -myaddr 127.0.0.1 0] -sockname]
+ vwait forever \
+ }
+ # Note the backslash above; this is important to make sure that the whole
+ # string is read before an [exit] can happen...
+ flush $pipe1
+ set port [lindex [gets $pipe1] 2]
+ set sock [socket localhost $port]
+ # pipe2 is a connection to a Tcl interpreter that takes its orders from
+ # the socket we hand it (i.e. the server we create above.) These orders
+ # will tell it to print out the details about the socket it is taking
+ # instructions from, hopefully identifying it as a socket. Which is what
+ # this test is all about.
+ set pipe2 [open "|[list [interpreter] <@$sock]" r]
+ set result [gets $pipe2]
+ # Clear any pending data; stops certain kinds of (non-important) errors
+ fconfigure $pipe1 -blocking 0; gets $pipe1
+ fconfigure $pipe2 -blocking 0; gets $pipe2
+ # Close the pipes and the socket.
+ close $pipe2
+ close $pipe1
+ catch {close $sock}
+ # Can't use normal comparison, as hostname varies due to some
+ # installations having a messed up /etc/hosts file.
+ if {
+ "127.0.0.1" eq [lindex $result 0] && $port == [lindex $result 2]
+ } then {
+ subst "OK"
+ } else {
+ subst "Expected: `[list 127.0.0.1 localhost $port]', Got `$result'"
+ }
+} {OK}
+
+# The unixInit-2.* tests were written to test the internal routine,
+# TclpInitLibraryPath. That routine no longer does the things it used to do
+# so those tests are obsolete. Skip them.
+
+skip [concat [skip] unixInit-2.*]
+
+test unixInit-2.0 {TclpInitLibraryPath: setting tclDefaultEncodingDir} {
+ set origDir [testgetdefenc]
+ testsetdefenc slappy
+ set path [testgetdefenc]
+ testsetdefenc $origDir
+ set path
+} {slappy}
+test unixInit-2.1 {TclpInitLibraryPath: value of installLib, developLib} -setup {
+ unset -nocomplain oldlibrary
+ if {[info exists env(TCL_LIBRARY)]} {
+ set oldlibrary $env(TCL_LIBRARY)
+ unset env(TCL_LIBRARY)
+ }
+} -body {
+ set path [getlibpath]
+ set installLib lib/tcl[info tclversion]
+ set developLib tcl[info patchlevel]/library
+ set prefix [file dirname [file dirname [interpreter]]]
+ list [string equal [lindex $path 0] $prefix/$installLib] \
+ [string equal [lindex $path 4] [file dirname $prefix]/$developLib]
+} -cleanup {
+ if {[info exists oldlibrary]} {
+ set env(TCL_LIBRARY) $oldlibrary
+ unset oldlibrary
+ }
+} -result {1 1}
+test unixInit-2.2 {TclpInitLibraryPath: TCL_LIBRARY} -setup {
+ unset -nocomplain oldlibrary
+ if {[info exists env(TCL_LIBRARY)]} {
+ set oldlibrary $env(TCL_LIBRARY)
+ }
+} -body {
+ # ((str != NULL) && (str[0] != '\0'))
+ set env(TCL_LIBRARY) sparkly
+ lindex [getlibpath] 0
+} -cleanup {
+ unset -nocomplain env(TCL_LIBRARY)
+ if {[info exists oldlibrary]} {
+ set env(TCL_LIBRARY) $oldlibrary
+ unset oldlibrary
+ }
+} -result "sparkly"
+test unixInit-2.3 {TclpInitLibraryPath: TCL_LIBRARY wrong version} -setup {
+ unset -nocomplain oldlibrary
+ if {[info exists env(TCL_LIBRARY)]} {
+ set oldlibrary $env(TCL_LIBRARY)
+ }
+} -body {
+ # ((pathc > 0) && (strcasecmp(installLib + 4, pathv[pathc - 1]) != 0))
+ set env(TCL_LIBRARY) /a/b/tcl1.7
+ lrange [getlibpath] 0 1
+} -cleanup {
+ unset -nocomplain env(TCL_LIBRARY)
+ if {[info exists oldlibrary]} {
+ set env(TCL_LIBRARY) $oldlibrary
+ unset oldlibrary
+ }
+} -result [list /a/b/tcl1.7 /a/b/tcl[info tclversion]]
+test unixInit-2.4 {TclpInitLibraryPath: TCL_LIBRARY: INTL} -setup {
+ if {[info exists env(TCL_LIBRARY)]} {
+ set oldlibrary $env(TCL_LIBRARY)
+ }
+} -body {
+ # Child process translates env variable from native encoding.
+ set env(TCL_LIBRARY) "\xa7"
+ lindex [getlibpath] 0
+} -cleanup {
+ unset -nocomplain env(TCL_LIBRARY) env(LANG)
+ if {[info exists oldlibrary]} {
+ set env(TCL_LIBRARY) $oldlibrary
+ unset oldlibrary
+ }
+} -result "\xa7"
+test unixInit-2.5 {TclpInitLibraryPath: compiled-in library path} {
+ # cannot test
+} {}
+test unixInit-2.6 {TclpInitLibraryPath: executable relative} -setup {
+ unset -nocomplain oldlibrary
+ if {[info exists env(TCL_LIBRARY)]} {
+ set oldlibrary $env(TCL_LIBRARY)
+ }
+ set env(TCL_LIBRARY) [info library]
+ makeDirectory tmp
+ makeDirectory [file join tmp sparkly]
+ makeDirectory [file join tmp sparkly bin]
+ file copy [interpreter] [file join [temporaryDirectory] tmp sparkly \
+ bin tcltest]
+ makeDirectory [file join tmp sparkly lib]
+ makeDirectory [file join tmp sparkly lib tcl[info tclversion]]
+ makeFile {} [file join tmp sparkly lib tcl[info tclversion] init.tcl]
+} -body {
+ lrange [getlibpath [file join [temporaryDirectory] tmp sparkly \
+ bin tcltest]] 1 2
+} -cleanup {
+ removeFile [file join tmp sparkly lib tcl[info tclversion] init.tcl]
+ removeDirectory [file join tmp sparkly lib tcl[info tclversion]]
+ removeDirectory [file join tmp sparkly lib]
+ removeDirectory [file join tmp sparkly bin]
+ removeDirectory [file join tmp sparkly]
+ removeDirectory tmp
+ unset env(TCL_LIBRARY)
+ if {[info exists oldlibrary]} {
+ set env(TCL_LIBRARY) $oldlibrary
+ unset oldlibrary
+ }
+} -result [list [temporaryDirectory]/tmp/sparkly/lib/tcl[info tclversion] [temporaryDirectory]/tmp/lib/tcl[info tclversion]]
+test unixInit-2.7 {TclpInitLibraryPath: compiled-in library path} {
+ # would need test command to get defaultLibDir and compare it to
+ # [lindex $auto_path end]
+} {}
+#
+# The following two tests write to the directory /tmp/sparkly instead of to
+# [temporaryDirectory]. This is because the failures tested by these tests
+# need paths near the "root" of the file system to present themselves.
+#
+test unixInit-2.8 {TclpInitLibraryPath: all absolute pathtype} -setup {
+ unset -nocomplain oldlibrary
+ if {[info exists env(TCL_LIBRARY)]} {
+ set oldlibrary $env(TCL_LIBRARY)
+ }
+ set env(TCL_LIBRARY) [info library]
+ # Checking for Bug 219416
+ # When a program that embeds the Tcl library, like tcltest, is installed
+ # near the "root" of the file system, there was a problem constructing
+ # directories relative to the executable. When a relative ".." went past
+ # the root, relative path names were created rather than absolute
+ # pathnames. In some cases, accessing past the root caused memory access
+ # violations too.
+ #
+ # The bug is now fixed, but here we check for it by making sure that the
+ # directories constructed relative to the executable are all absolute
+ # pathnames, even when the executable is installed near the root of the
+ # filesystem.
+ #
+ # The only directory near the root we are likely to have write access to
+ # is /tmp.
+ file delete -force /tmp/sparkly
+ file delete -force /tmp/lib/tcl[info tclversion]
+ file mkdir /tmp/sparkly
+ file copy [interpreter] /tmp/sparkly/tcltest
+ # Keep any existing /tmp/lib directory
+ set deletelib 1
+ if {[file exists /tmp/lib]} {
+ if {[file isdirectory /tmp/lib]} {
+ set deletelib 0
+ } else {
+ file delete -force /tmp/lib
+ }
+ }
+ # For a successful Tcl_Init, we need a [source]-able init.tcl in
+ # ../lib/tcl$version relative to the executable.
+ file mkdir /tmp/lib/tcl[info tclversion]
+ close [open /tmp/lib/tcl[info tclversion]/init.tcl w]
+} -body {
+ # Check that all directories in the library path are absolute pathnames
+ set allAbsolute 1
+ foreach dir [getlibpath /tmp/sparkly/tcltest] {
+ set allAbsolute [expr {$allAbsolute \
+ && [string equal absolute [file pathtype $dir]]}]
+ }
+ set allAbsolute
+} -cleanup {
+ # Clean up temporary installation
+ file delete -force /tmp/sparkly
+ file delete -force /tmp/lib/tcl[info tclversion]
+ if {$deletelib} {file delete -force /tmp/lib}
+ unset env(TCL_LIBRARY)
+ if {[info exists oldlibrary]} {
+ set env(TCL_LIBRARY) $oldlibrary
+ unset oldlibrary
+ }
+} -result 1
+test unixInit-2.9 {TclpInitLibraryPath: paths relative to executable} -setup {
+ # Checking for Bug 438014
+ unset -nocomplain oldlibrary
+ if {[info exists env(TCL_LIBRARY)]} {
+ set oldlibrary $env(TCL_LIBRARY)
+ }
+ set env(TCL_LIBRARY) [info library]
+ file delete -force /tmp/sparkly
+ file delete -force /tmp/library
+ file mkdir /tmp/sparkly
+ file copy [interpreter] /tmp/sparkly/tcltest
+ file mkdir /tmp/library/
+ close [open /tmp/library/init.tcl w]
+} -body {
+ lrange [getlibpath /tmp/sparkly/tcltest] 1 5
+} -cleanup {
+ file delete -force /tmp/sparkly
+ file delete -force /tmp/library
+ unset env(TCL_LIBRARY)
+ if {[info exists oldlibrary]} {
+ set env(TCL_LIBRARY) $oldlibrary
+ unset oldlibrary
+ }
+} -result [list /tmp/lib/tcl[info tclversion] /lib/tcl[info tclversion] \
+ /tmp/library /library /tcl[info patchlevel]/library]
+test unixInit-2.10 {TclpInitLibraryPath: executable relative} -setup {
+ unset -nocomplain oldlibrary
+ if {[info exists env(TCL_LIBRARY)]} {
+ set oldlibrary $env(TCL_LIBRARY)
+ }
+ set env(TCL_LIBRARY) [info library]
+ set tmpDir [makeDirectory tmp]
+ set sparklyDir [makeDirectory sparkly $tmpDir]
+ set execPath [file join [makeDirectory bin $sparklyDir] tcltest]
+ file copy [interpreter] $execPath
+ set libDir [makeDirectory lib $sparklyDir]
+ set scriptDir [makeDirectory tcl[info tclversion] $libDir]
+ makeFile {} init.tcl $scriptDir
+ set saveDir [pwd]
+ cd $libDir
+} -body {
+ # Checking for Bug 832657
+ set x [lrange [getlibpath [file join .. bin tcltest]] 3 4]
+ foreach p $x {
+ lappend y [file normalize $p]
+ }
+ set y
+} -cleanup {
+ cd $saveDir
+ removeFile init.tcl $scriptDir
+ removeDirectory tcl[info tclversion] $libDir
+ file delete $execPath
+ removeDirectory bin $sparklyDir
+ removeDirectory lib $sparklyDir
+ removeDirectory sparkly $tmpDir
+ removeDirectory tmp
+ unset -nocomplain saveDir scriptDir libDir execPath sparklyDir tmpDir
+ unset -nocomplain x p y env(TCL_LIBRARY)
+ if {[info exists oldlibrary]} {
+ set env(TCL_LIBRARY) $oldlibrary
+ unset oldlibrary
+ }
+} -result [list [file join [temporaryDirectory] tmp sparkly library] \
+ [file join [temporaryDirectory] tmp library] ]
+
+test unixInit-3.1 {TclpSetInitialEncodings} -constraints {
+ unix stdio
+} -body {
+ set env(LANG) C
+ set f [open "|[list [interpreter]]" w+]
+ fconfigure $f -buffering none
+ puts $f {puts [encoding system]; exit}
+ set enc [gets $f]
+ close $f
+ return $enc
+} -cleanup {
+ unset -nocomplain env(LANG)
+} -match regexp -result [expr {
+ ($tcl_platform(os) eq "Darwin") ? "^utf-8$" : "^iso8859-15?$"}]
+test unixInit-3.2 {TclpSetInitialEncodings} -setup {
+ catch {set oldlc_all $env(LC_ALL)}
+} -constraints {unix stdio} -body {
+ set env(LANG) japanese
+ set env(LC_ALL) japanese
+ set f [open "|[list [interpreter]]" w+]
+ fconfigure $f -buffering none
+ puts $f {puts [encoding system]; exit}
+ set enc [gets $f]
+ close $f
+ set validEncodings [list euc-jp]
+ if {[string match HP-UX $tcl_platform(os)]} {
+ # Some older HP-UX systems need us to accept this as valid Bug 453883
+ # reports that newer HP-UX systems report euc-jp like everybody else.
+ lappend validEncodings shiftjis
+ }
+ expr {$enc ni $validEncodings}
+} -cleanup {
+ unset -nocomplain env(LANG) env(LC_ALL)
+ catch {set env(LC_ALL) $oldlc_all}
+} -result 0
+
+test unixInit-4.1 {TclpSetVariables} {unix} {
+ # just make sure they exist
+ set a [list $tcl_library $tcl_pkgPath $tcl_platform(os)]
+ set a [list $tcl_platform(osVersion) $tcl_platform(machine)]
+ set tcl_platform(platform)
+} "unix"
+
+test unixInit-5.1 {Tcl_Init} {emptyTest unix} {
+ # test initScript
+} {}
+
+test unixInit-6.1 {Tcl_SourceRCFile} {emptyTest unix} {
+} {}
+
+test unixInit-7.1 {closed standard channel: Bug 772288} -constraints {
+ unix stdio
+} -body {
+ set tclsh [interpreter]
+ set crash [makeFile {puts [open /dev/null]} crash.tcl]
+ set crashtest [makeFile "
+ close stdin
+ [list exec $tclsh $crash]
+ " crashtest.tcl]
+ exec $tclsh $crashtest
+} -cleanup {
+ removeFile crash.tcl
+ removeFile crashtest.tcl
+} -returnCodes 0
+
+# cleanup
+catch {unset env(LANG)}
+catch {set env(LANG) $oldlang}
+unset -nocomplain path
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/unixNotfy.test b/library/msgcat/tests/unixNotfy.test
new file mode 100644
index 0000000..0646a3d
--- /dev/null
+++ b/library/msgcat/tests/unixNotfy.test
@@ -0,0 +1,102 @@
+# This file contains tests for tclUnixNotfy.c.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# When run in a Tk shell, these tests hang.
+testConstraint noTk [expr {0 != [catch {package present Tk}]}]
+testConstraint thread [expr {0 == [catch {package require Thread 2.6}]}]
+# Darwin always uses a threaded notifier
+testConstraint unthreaded [expr {
+ ![::tcl::pkgconfig get threaded]
+ && $tcl_platform(os) ne "Darwin"
+}]
+
+# The next two tests will hang if threads are enabled because the notifier
+# will not necessarily wait for ever in this case, so it does not generate
+# an error.
+test unixNotfy-1.1 {Tcl_DeleteFileHandler} -constraints {noTk unix unthreaded} -body {
+ catch {vwait x}
+ set f [open [makeFile "" foo] w]
+ fileevent $f writable {set x 1}
+ vwait x
+ close $f
+ list [catch {vwait x} msg] $msg
+} -result {1 {can't wait for variable "x": would wait forever}} -cleanup {
+ catch { close $f }
+ catch { removeFile foo }
+}
+test unixNotfy-1.2 {Tcl_DeleteFileHandler} -constraints {noTk unix unthreaded} -body {
+ catch {vwait x}
+ set f1 [open [makeFile "" foo] w]
+ set f2 [open [makeFile "" foo2] w]
+ fileevent $f1 writable {set x 1}
+ fileevent $f2 writable {set y 1}
+ vwait x
+ close $f1
+ vwait y
+ close $f2
+ list [catch {vwait x} msg] $msg
+} -result {1 {can't wait for variable "x": would wait forever}} -cleanup {
+ catch { close $f1 }
+ catch { close $f2 }
+ catch { removeFile foo }
+ catch { removeFile foo2 }
+}
+
+test unixNotfy-2.1 {Tcl_DeleteFileHandler} \
+ -constraints {noTk unix thread} \
+ -body {
+ update
+ set f [open [makeFile "" foo] w]
+ fileevent $f writable {set x 1}
+ vwait x
+ close $f
+ thread::create "thread::send [thread::id] {set x ok}"
+ vwait x
+ set x
+ } \
+ -result {ok} \
+ -cleanup {
+ catch { close $f }
+ catch { removeFile foo }
+ }
+test unixNotfy-2.2 {Tcl_DeleteFileHandler} \
+ -constraints {noTk unix thread} \
+ -body {
+ update
+ set f1 [open [makeFile "" foo] w]
+ set f2 [open [makeFile "" foo2] w]
+ fileevent $f1 writable {set x 1}
+ fileevent $f2 writable {set y 1}
+ vwait x
+ close $f1
+ vwait y
+ close $f2
+ thread::create "thread::send [thread::id] {set x ok}"
+ vwait x
+ set x
+ } \
+ -result {ok} \
+ -cleanup {
+ catch { close $f1 }
+ catch { close $f2 }
+ catch { removeFile foo }
+ catch { removeFile foo2 }
+ }
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/unknown.test b/library/msgcat/tests/unknown.test
new file mode 100644
index 0000000..40be6602
--- /dev/null
+++ b/library/msgcat/tests/unknown.test
@@ -0,0 +1,67 @@
+# Commands covered: unknown
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+catch {unset x}
+catch {rename unknown unknown.old}
+
+test unknown-1.1 {non-existent "unknown" command} {
+ list [catch {_non-existent_ foo bar} msg] $msg
+} {1 {invalid command name "_non-existent_"}}
+
+proc unknown {args} {
+ global x
+ set x $args
+}
+test unknown-2.1 {calling "unknown" command} {
+ foobar x y z
+ set x
+} {foobar x y z}
+test unknown-2.2 {calling "unknown" command with lots of args} {
+ foobar 1 2 3 4 5 6 7
+ set x
+} {foobar 1 2 3 4 5 6 7}
+test unknown-2.3 {calling "unknown" command with lots of args} {
+ foobar 1 2 3 4 5 6 7 8
+ set x
+} {foobar 1 2 3 4 5 6 7 8}
+test unknown-2.4 {calling "unknown" command with lots of args} {
+ foobar 1 2 3 4 5 6 7 8 9
+ set x
+} {foobar 1 2 3 4 5 6 7 8 9}
+
+test unknown-3.1 {argument quoting in calls to "unknown"} {
+ foobar \{ \} a\{b \; "\\" \$a a\[b \]
+ set x
+} "foobar \\{ \\} a\\{b {;} \\\\ {\$a} {a\[b} \\]"
+
+proc unknown args {
+ error "unknown failed"
+}
+test unknown-4.1 {errors in "unknown" procedure} {
+ list [catch {non-existent a b} msg] $msg $errorCode
+} {1 {unknown failed} NONE}
+
+# cleanup
+catch {rename unknown {}}
+catch {rename unknown.old unknown}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/unload.test b/library/msgcat/tests/unload.test
new file mode 100644
index 0000000..a103cc5
--- /dev/null
+++ b/library/msgcat/tests/unload.test
@@ -0,0 +1,242 @@
+# Commands covered: unload
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1995 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2003-2004 by Georgios Petasis
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Figure out what extension is used for shared libraries on this
+# platform.
+if {![info exists ext]} {
+ set ext [info sharedlibextension]
+}
+
+# Tests require the existence of one of the DLLs in the dltest directory.
+set testDir [file join [file dirname [info nameofexecutable]] dltest]
+set x [file join $testDir pkgua$ext]
+set dll "[file tail $x]Required"
+testConstraint $dll [file readable $x]
+
+# Tests also require that this DLL has not already been loaded.
+set loaded "[file tail $x]Loaded"
+set alreadyLoaded [info loaded]
+testConstraint $loaded [expr {![string match *pkgua* $alreadyLoaded]}]
+
+set alreadyTotalLoaded [info loaded]
+
+# Certain tests require the 'teststaticpkg' command from tcltest
+testConstraint teststaticpkg [llength [info commands teststaticpkg]]
+
+# Certain tests need the 'testsimplefilsystem' in tcltest
+testConstraint testsimplefilesystem \
+ [llength [info commands testsimplefilesystem]]
+
+# Basic tests: parameter testing...
+test unload-1.1 {basic errors} -returnCodes error -body {
+ unload
+} -result {wrong # args: should be "unload ?-switch ...? fileName ?packageName? ?interp?"}
+test unload-1.2 {basic errors} -returnCodes error -body {
+ unload a b c d
+} -result {wrong # args: should be "unload ?-switch ...? fileName ?packageName? ?interp?"}
+test unload-1.3 {basic errors} -returnCodes error -body {
+ unload a b foobar
+} -result {could not find interpreter "foobar"}
+test unload-1.4 {basic errors} -returnCodes error -body {
+ unload {}
+} -result {must specify either file name or package name}
+test unload-1.5 {basic errors} -returnCodes error -body {
+ unload {} {}
+} -result {must specify either file name or package name}
+test unload-1.6 {basic errors} -returnCodes error -body {
+ unload {} Unknown
+} -result {package "Unknown" is loaded statically and cannot be unloaded}
+test unload-1.7 {-nocomplain switch} {
+ unload -nocomplain {} Unknown
+} {}
+
+set pkgua_loaded {}
+set pkgua_detached {}
+set pkgua_unloaded {}
+# Tests for loading/unloading in trusted (non-safe) interpreters...
+test unload-2.1 {basic loading of non-unloadable package, with guess for package name} [list $dll $loaded] {
+ load [file join $testDir pkga$ext]
+ list [pkga_eq abc def] [lsort [info commands pkga_*]]
+} {0 {pkga_eq pkga_quote}}
+test unload-2.2 {basic loading of unloadable package, with guess for package name} [list $dll $loaded] {
+ list $pkgua_loaded $pkgua_detached $pkgua_unloaded \
+ [load [file join $testDir pkgua$ext]] \
+ [pkgua_eq abc def] [lsort [info commands pkgua_*]] \
+ $pkgua_loaded $pkgua_detached $pkgua_unloaded
+} {{} {} {} {} 0 {pkgua_eq pkgua_quote} . {} {}}
+test unload-2.3 {basic unloading of non-unloadable package, with guess for package name} [list $dll $loaded] {
+ list [catch {unload [file join $testDir pkga$ext]} msg] \
+ [string map [list [file join $testDir pkga$ext] file] $msg]
+} {1 {file "file" cannot be unloaded under a trusted interpreter}}
+test unload-2.4 {basic unloading of unloadable package, with guess for package name} [list $dll $loaded] {
+ list $pkgua_loaded $pkgua_detached $pkgua_unloaded \
+ [unload [file join $testDir pkgua$ext]] \
+ [info commands pkgua_*] \
+ $pkgua_loaded $pkgua_detached $pkgua_unloaded
+} {. {} {} {} {} . . .}
+test unload-2.5 {reloading of unloaded package, with guess for package name} [list $dll $loaded] {
+ list $pkgua_loaded $pkgua_detached $pkgua_unloaded \
+ [load [file join $testDir pkgua$ext]] \
+ [pkgua_eq abc def] [lsort [info commands pkgua_*]] \
+ $pkgua_loaded $pkgua_detached $pkgua_unloaded
+} {. . . {} 0 {pkgua_eq pkgua_quote} .. . .}
+test unload-2.6 {basic unloading of re-loaded package, with guess for package name} [list $dll $loaded] {
+ list $pkgua_loaded $pkgua_detached $pkgua_unloaded \
+ [unload [file join $testDir pkgua$ext]] \
+ [info commands pkgua_*] \
+ $pkgua_loaded $pkgua_detached $pkgua_unloaded
+} {.. . . {} {} .. .. ..}
+
+# Tests for loading/unloading in safe interpreters...
+interp create -safe child
+child eval {
+ set pkgua_loaded {}
+ set pkgua_detached {}
+ set pkgua_unloaded {}
+}
+test unload-3.1 {basic loading of non-unloadable package in a safe interpreter, with package name conversion} \
+ [list $dll $loaded] {
+ catch {rename pkgb_sub {}}
+ load [file join $testDir pkgb$ext] pKgB child
+ list [child eval pkgb_sub 44 13] [catch {child eval pkgb_unsafe} msg] $msg \
+ [catch {pkgb_sub 12 10} msg2] $msg2
+} {31 1 {invalid command name "pkgb_unsafe"} 1 {invalid command name "pkgb_sub"}}
+test unload-3.2 {basic loading of unloadable package in a safe interpreter, with package name conversion} \
+ [list $dll $loaded] {
+ list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+ [load [file join $testDir pkgua$ext] pKgUA child] \
+ [child eval pkgua_eq abc def] \
+ [lsort [child eval info commands pkgua_*]] \
+ [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} {{{} {} {}} {} 0 {pkgua_eq pkgua_quote} {. {} {}}}
+test unload-3.3 {unloading of a package that has never been loaded from a safe interpreter} \
+ [list $dll $loaded] {
+ list [catch {unload [file join $testDir pkga$ext] {} child} msg] \
+ [string map [list [file join $testDir pkga$ext] file] $msg]
+} {1 {file "file" has never been loaded in this interpreter}}
+test unload-3.4 {basic unloading of a non-unloadable package from a safe interpreter, with guess for package name} \
+ [list $dll $loaded] {
+ list [catch {unload [file join $testDir pkgb$ext] {} child} msg] \
+ [string map [list [file join $testDir pkgb$ext] file] $msg]
+} {1 {file "file" cannot be unloaded under a safe interpreter}}
+test unload-3.5 {basic unloading of an unloadable package from a safe interpreter, with guess for package name} \
+ [list $dll $loaded] {
+ list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+ [unload [file join $testDir pkgua$ext] {} child] \
+ [child eval info commands pkgua_*] \
+ [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} {{. {} {}} {} {} {. . .}}
+test unload-3.6 {reloading of unloaded package in a safe interpreter, with guess for package name} \
+ [list $dll $loaded] {
+ list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+ [load [file join $testDir pkgua$ext] {} child] \
+ [child eval pkgua_eq abc def] \
+ [lsort [child eval info commands pkgua_*]] \
+ [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} {{. . .} {} 0 {pkgua_eq pkgua_quote} {.. . .}}
+test unload-3.7 {basic unloading of re-loaded package from a safe interpreter, with package name conversion} \
+ [list $dll $loaded] {
+ list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+ [unload [file join $testDir pkgua$ext] pKgUa child] \
+ [child eval info commands pkgua_*] \
+ [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} {{.. . .} {} {} {.. .. ..}}
+
+# Tests for loading/unloading of a package among multiple interpreters...
+interp create child-trusted
+child-trusted eval {
+ set pkgua_loaded {}
+ set pkgua_detached {}
+ set pkgua_unloaded {}
+}
+## Load package in main trusted interpreter...
+test unload-4.1 {loading of unloadable package in trusted interpreter, with guess for package name} \
+ [list $dll $loaded] {
+ list [list $pkgua_loaded $pkgua_detached $pkgua_unloaded] \
+ [load [file join $testDir pkgua$ext]] \
+ [pkgua_eq abc def] [lsort [info commands pkgua_*]] \
+ [list $pkgua_loaded $pkgua_detached $pkgua_unloaded]
+} {{.. .. ..} {} 0 {pkgua_eq pkgua_quote} {... .. ..}}
+## Load package in child-safe interpreter...
+test unload-4.2 {basic loading of unloadable package in a safe interpreter, with package name conversion} \
+ [list $dll $loaded] {
+ list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+ [load [file join $testDir pkgua$ext] pKgUA child] \
+ [child eval pkgua_eq abc def] \
+ [lsort [child eval info commands pkgua_*]] \
+ [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} {{.. .. ..} {} 0 {pkgua_eq pkgua_quote} {... .. ..}}
+## Load package in child-trusted interpreter...
+test unload-4.3 {basic loading of unloadable package in a second trusted interpreter, with package name conversion} \
+ [list $dll $loaded] {
+ list [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+ [load [file join $testDir pkgua$ext] pkguA child-trusted] \
+ [child-trusted eval pkgua_eq abc def] \
+ [lsort [child-trusted eval info commands pkgua_*]] \
+ [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} {{{} {} {}} {} 0 {pkgua_eq pkgua_quote} {. {} {}}}
+## Unload the package from the main trusted interpreter...
+test unload-4.4 {basic unloading of unloadable package from trusted interpreter, with guess for package name} \
+ [list $dll $loaded] {
+ list [list $pkgua_loaded $pkgua_detached $pkgua_unloaded] \
+ [unload [file join $testDir pkgua$ext]] \
+ [info commands pkgua_*] \
+ [list $pkgua_loaded $pkgua_detached $pkgua_unloaded]
+} {{... .. ..} {} {} {... ... ..}}
+## Unload the package from the child safe interpreter...
+test unload-4.5 {basic unloading of unloadable package from a safe interpreter, with guess for package name} \
+ [list $dll $loaded] {
+ list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+ [unload [file join $testDir pkgua$ext] {} child] \
+ [child eval info commands pkgua_*] \
+ [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} {{... .. ..} {} {} {... ... ..}}
+## Unload the package from the child trusted interpreter...
+test unload-4.6 {basic unloading of unloadable package from a safe interpreter, with guess for package name} \
+ [list $dll $loaded] {
+ list [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+ [unload [file join $testDir pkgua$ext] {} child-trusted] \
+ [child-trusted eval info commands pkgua_*] \
+ [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} {{. {} {}} {} {} {. . .}}
+
+test unload-5.1 {unload a module loaded from vfs} \
+ -constraints [list $dll $loaded testsimplefilesystem] \
+ -setup {
+ set dir [pwd]
+ cd $testDir
+ testsimplefilesystem 1
+ load simplefs:/pkgua$ext pkgua
+ } \
+ -body {
+ list [catch {unload simplefs:/pkgua$ext} msg] $msg
+ } \
+ -result {0 {}}
+
+
+
+# cleanup
+interp delete child
+interp delete child-trusted
+unset ext
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/uplevel.test b/library/msgcat/tests/uplevel.test
new file mode 100644
index 0000000..0410469
--- /dev/null
+++ b/library/msgcat/tests/uplevel.test
@@ -0,0 +1,206 @@
+# Commands covered: uplevel
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+proc a {x y} {
+ newset z [expr $x+$y]
+ return $z
+}
+proc newset {name value} {
+ uplevel set $name $value
+ uplevel 1 {uplevel 1 {set xyz 22}}
+}
+
+test uplevel-1.1 {simple operation} {
+ set xyz 0
+ a 22 33
+} 55
+test uplevel-1.2 {command is another uplevel command} {
+ set xyz 0
+ a 22 33
+ set xyz
+} 22
+
+proc a1 {} {
+ b1
+ global a a1
+ set a $x
+ set a1 $y
+}
+proc b1 {} {
+ c1
+ global b b1
+ set b $x
+ set b1 $y
+}
+proc c1 {} {
+ uplevel 1 set x 111
+ uplevel #2 set y 222
+ uplevel 2 set x 333
+ uplevel #1 set y 444
+ uplevel 3 set x 555
+ uplevel #0 set y 666
+}
+a1
+test uplevel-2.1 {relative and absolute uplevel} {set a} 333
+test uplevel-2.2 {relative and absolute uplevel} {set a1} 444
+test uplevel-2.3 {relative and absolute uplevel} {set b} 111
+test uplevel-2.4 {relative and absolute uplevel} {set b1} 222
+test uplevel-2.5 {relative and absolute uplevel} {set x} 555
+test uplevel-2.6 {relative and absolute uplevel} {set y} 666
+
+test uplevel-3.1 {uplevel to same level} {
+ set x 33
+ uplevel #0 set x 44
+ set x
+} 44
+test uplevel-3.2 {uplevel to same level} {
+ set x 33
+ uplevel 0 set x
+} 33
+test uplevel-3.3 {uplevel to same level} {
+ set y xxx
+ proc a1 {} {set y 55; uplevel 0 set y 66; return $y}
+ a1
+} 66
+test uplevel-3.4 {uplevel to same level} {
+ set y zzz
+ proc a1 {} {set y 55; uplevel #1 set y}
+ a1
+} 55
+
+test uplevel-4.1 {error: non-existent level} -returnCodes error -body {
+ apply {{} {
+ uplevel #2 {set y 222}
+ }}
+} -result {bad level "#2"}
+test uplevel-4.2 {error: non-existent level} -returnCodes error -body {
+ apply {{} {
+ uplevel 3 {set a b}
+ }}
+} -result {bad level "3"}
+test uplevel-4.3 {error: not enough args} -returnCodes error -body {
+ uplevel
+} -result {wrong # args: should be "uplevel ?level? command ?arg ...?"}
+test uplevel-4.4 {error: not enough args} -returnCodes error -body {
+ apply {{} {
+ uplevel 1
+ }}
+} -result {wrong # args: should be "uplevel ?level? command ?arg ...?"}
+
+proc a2 {} {
+ uplevel a3
+}
+proc a3 {} {
+ global x y
+ set x [info level]
+ set y [info level 1]
+}
+a2
+test uplevel-5.1 {info level} {set x} 1
+test uplevel-5.2 {info level} {set y} a3
+
+namespace eval ns1 {
+ proc set args {return ::ns1}
+}
+proc a2 {} {
+ uplevel {set x ::}
+}
+test uplevel-6.1 {uplevel and shadowed cmds} {
+ set res [namespace eval ns1 a2]
+ lappend res [namespace eval ns2 a2]
+ lappend res [namespace eval ns1 a2]
+ namespace eval ns1 {rename set {}}
+ lappend res [namespace eval ns1 a2]
+} {::ns1 :: ::ns1 ::}
+
+#
+# These tests verify that upleveled scripts run in the correct level and access
+# the proper variables.
+#
+
+test uplevel-7.1 {var access, no LVT in either level} -setup {
+ set x 1
+ unset -nocomplain y z
+} -body {
+ namespace eval foo {
+ set x 2
+ set y 2
+ uplevel 1 {
+ set x 3
+ set y 3
+ set z 3
+ }
+ }
+ list $x $y $z
+} -cleanup {
+ namespace delete foo
+ unset -nocomplain x y z
+} -result {3 3 3}
+
+test uplevel-7.2 {var access, no LVT in upper level} -setup {
+ set x 1
+ unset -nocomplain y z
+} -body {
+ proc foo {} {
+ set x 2
+ set y 2
+ uplevel 1 {
+ set x 3
+ set y 3
+ set z 3
+ }
+ }
+ foo
+ list $x $y $z
+} -cleanup {
+ rename foo {}
+ unset -nocomplain x y z
+} -result {3 3 3}
+
+test uplevel-7.3 {var access, LVT in upper level} -setup {
+ proc moo {} {
+ set x 1; #var in LVT
+ unset -nocomplain y z
+ foo
+ list $x $y $z
+ }
+} -body {
+ proc foo {} {
+ set x 2
+ set y 2
+ uplevel 1 {
+ set x 3
+ set y 3
+ set z 3
+ }
+ }
+ foo
+ moo
+} -cleanup {
+ rename foo {}
+ rename moo {}
+} -result {3 3 3}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/upvar.test b/library/msgcat/tests/upvar.test
new file mode 100644
index 0000000..cd78c31
--- /dev/null
+++ b/library/msgcat/tests/upvar.test
@@ -0,0 +1,543 @@
+# Commands covered: 'upvar', 'namespace upvar'
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testupvar [llength [info commands testupvar]]
+
+test upvar-1.1 {reading variables with upvar} {
+ proc p1 {a b} {set c 22; set d 33; p2}
+ proc p2 {} {upvar a x1 b x2 c x3 d x4; set a abc; list $x1 $x2 $x3 $x4 $a}
+ p1 foo bar
+} {foo bar 22 33 abc}
+test upvar-1.2 {reading variables with upvar} {
+ proc p1 {a b} {set c 22; set d 33; p2}
+ proc p2 {} {p3}
+ proc p3 {} {upvar 2 a x1 b x2 c x3 d x4; set a abc; list $x1 $x2 $x3 $x4 $a}
+ p1 foo bar
+} {foo bar 22 33 abc}
+test upvar-1.3 {reading variables with upvar} {
+ proc p1 {a b} {set c 22; set d 33; p2}
+ proc p2 {} {p3}
+ proc p3 {} {
+ upvar #1 a x1 b x2 c x3 d x4
+ set a abc
+ list $x1 $x2 $x3 $x4 $a
+ }
+ p1 foo bar
+} {foo bar 22 33 abc}
+test upvar-1.4 {reading variables with upvar} {
+ set x1 44
+ set x2 55
+ proc p1 {} {p2}
+ proc p2 {} {
+ upvar 2 x1 x1 x2 a
+ upvar #0 x1 b
+ set c $b
+ incr b 3
+ list $x1 $a $b
+ }
+ p1
+} {47 55 47}
+test upvar-1.5 {reading array elements with upvar} {
+ proc p1 {} {set a(0) zeroth; set a(1) first; p2}
+ proc p2 {} {upvar a(0) x; set x}
+ p1
+} {zeroth}
+
+test upvar-2.1 {writing variables with upvar} {
+ proc p1 {a b} {set c 22; set d 33; p2; list $a $b $c $d}
+ proc p2 {} {
+ upvar a x1 b x2 c x3 d x4
+ set x1 14
+ set x4 88
+ }
+ p1 foo bar
+} {14 bar 22 88}
+test upvar-2.2 {writing variables with upvar} {
+ set x1 44
+ set x2 55
+ proc p1 {x1 x2} {
+ upvar #0 x1 a
+ upvar x2 b
+ set a $x1
+ set b $x2
+ }
+ p1 newbits morebits
+ list $x1 $x2
+} {newbits morebits}
+test upvar-2.3 {writing variables with upvar} {
+ catch {unset x1}
+ catch {unset x2}
+ proc p1 {x1 x2} {
+ upvar #0 x1 a
+ upvar x2 b
+ set a $x1
+ set b $x2
+ }
+ p1 newbits morebits
+ list [catch {set x1} msg] $msg [catch {set x2} msg] $msg
+} {0 newbits 0 morebits}
+test upvar-2.4 {writing array elements with upvar} {
+ proc p1 {} {set a(0) zeroth; set a(1) first; list [p2] $a(0)}
+ proc p2 {} {upvar a(0) x; set x xyzzy}
+ p1
+} {xyzzy xyzzy}
+
+test upvar-3.1 {unsetting variables with upvar} {
+ proc p1 {a b} {set c 22; set d 33; p2; lsort [info vars]}
+ proc p2 {} {
+ upvar 1 a x1 d x2
+ unset x1 x2
+ }
+ p1 foo bar
+} {b c}
+test upvar-3.2 {unsetting variables with upvar} {
+ proc p1 {a b} {set c 22; set d 33; p2; lsort [info vars]}
+ proc p2 {} {
+ upvar 1 a x1 d x2
+ unset x1 x2
+ set x2 28
+ }
+ p1 foo bar
+} {b c d}
+test upvar-3.3 {unsetting variables with upvar} {
+ set x1 44
+ set x2 55
+ proc p1 {} {p2}
+ proc p2 {} {
+ upvar 2 x1 a
+ upvar #0 x2 b
+ unset a b
+ }
+ p1
+ list [info exists x1] [info exists x2]
+} {0 0}
+test upvar-3.4 {unsetting variables with upvar} {
+ set x1 44
+ set x2 55
+ proc p1 {} {
+ upvar x1 a x2 b
+ unset a b
+ set b 118
+ }
+ p1
+ list [info exists x1] [catch {set x2} msg] $msg
+} {0 0 118}
+test upvar-3.5 {unsetting array elements with upvar} {
+ proc p1 {} {
+ set a(0) zeroth
+ set a(1) first
+ set a(2) second
+ p2
+ array names a
+ }
+ proc p2 {} {upvar a(0) x; unset x}
+ lsort [p1]
+} {1 2}
+test upvar-3.6 {unsetting then resetting array elements with upvar} {
+ proc p1 {} {
+ set a(0) zeroth
+ set a(1) first
+ set a(2) second
+ p2
+ list [lsort [array names a]] [catch {set a(0)} msg] $msg
+ }
+ proc p2 {} {upvar a(0) x; unset x; set x 12345}
+ p1
+} {{0 1 2} 0 12345}
+
+test upvar-4.1 {nested upvars} {
+ set x1 88
+ proc p1 {a b} {set c 22; set d 33; p2}
+ proc p2 {} {global x1; upvar c x2; p3}
+ proc p3 {} {
+ upvar x1 a x2 b
+ list $a $b
+ }
+ p1 14 15
+} {88 22}
+test upvar-4.2 {nested upvars} {
+ set x1 88
+ proc p1 {a b} {set c 22; set d 33; p2; list $a $b $c $d}
+ proc p2 {} {global x1; upvar c x2; p3}
+ proc p3 {} {
+ upvar x1 a x2 b
+ set a foo
+ set b bar
+ }
+ list [p1 14 15] $x1
+} {{14 15 bar 33} foo}
+
+proc tproc {args} {global x; set x [list $args [uplevel info vars]]}
+test upvar-5.1 {traces involving upvars} {
+ proc p1 {a b} {set c 22; set d 33; trace var c rw tproc; p2}
+ proc p2 {} {upvar c x1; set x1 22}
+ set x ---
+ p1 foo bar
+ set x
+} {{x1 {} w} x1}
+test upvar-5.2 {traces involving upvars} {
+ proc p1 {a b} {set c 22; set d 33; trace var c rw tproc; p2}
+ proc p2 {} {upvar c x1; set x1}
+ set x ---
+ p1 foo bar
+ set x
+} {{x1 {} r} x1}
+test upvar-5.3 {traces involving upvars} {
+ proc p1 {a b} {set c 22; set d 33; trace var c rwu tproc; p2}
+ proc p2 {} {upvar c x1; unset x1}
+ set x ---
+ p1 foo bar
+ set x
+} {{x1 {} u} x1}
+
+test upvar-6.1 {retargeting an upvar} {
+ proc p1 {} {
+ set a(0) zeroth
+ set a(1) first
+ set a(2) second
+ p2
+ }
+ proc p2 {} {
+ upvar a x
+ set result {}
+ foreach i [array names x] {
+ upvar a($i) x
+ lappend result $x
+ }
+ lsort $result
+ }
+ p1
+} {first second zeroth}
+test upvar-6.2 {retargeting an upvar} {
+ set x 44
+ set y abcde
+ proc p1 {} {
+ global x
+ set result $x
+ upvar y x
+ lappend result $x
+ }
+ p1
+} {44 abcde}
+test upvar-6.3 {retargeting an upvar} {
+ set x 44
+ set y abcde
+ proc p1 {} {
+ upvar y x
+ lappend result $x
+ global x
+ lappend result $x
+ }
+ p1
+} {abcde 44}
+
+test upvar-7.1 {upvar to same level} {
+ set x 44
+ set y 55
+ catch {unset uv}
+ upvar #0 x uv
+ set uv abc
+ upvar 0 y uv
+ set uv xyzzy
+ list $x $y
+} {abc xyzzy}
+test upvar-7.2 {upvar to same level} {
+ set x 1234
+ set y 4567
+ proc p1 {x y} {
+ upvar 0 x uv
+ set uv $y
+ return "$x $y"
+ }
+ p1 44 89
+} {89 89}
+test upvar-7.3 {upvar to same level} {
+ set x 1234
+ set y 4567
+ proc p1 {x y} {
+ upvar #1 x uv
+ set uv $y
+ return "$x $y"
+ }
+ p1 xyz abc
+} {abc abc}
+test upvar-7.4 {upvar to same level: tricky problems when deleting variable table} {
+ proc tt {} {upvar #1 toto loc; return $loc}
+ list [catch tt msg] $msg
+} {1 {can't read "loc": no such variable}}
+test upvar-7.5 {potential memory leak when deleting variable table} {
+ proc leak {} {
+ array set foo {1 2 3 4}
+ upvar 0 foo(1) bar
+ }
+ leak
+} {}
+
+test upvar-8.1 {errors in upvar command} -returnCodes error -body {
+ upvar
+} -result {wrong # args: should be "upvar ?level? otherVar localVar ?otherVar localVar ...?"}
+test upvar-8.2 {errors in upvar command} -returnCodes error -body {
+ upvar 1
+} -result {wrong # args: should be "upvar ?level? otherVar localVar ?otherVar localVar ...?"}
+test upvar-8.2.1 {upvar with numeric first argument} {
+ apply {{} {set 0 ok; apply {{} {upvar 0 x; return $x}}}}
+} ok
+test upvar-8.3 {errors in upvar command} -returnCodes error -body {
+ proc p1 {} {upvar a b c}
+ p1
+} -result {bad level "a"}
+test upvar-8.4 {errors in upvar command} -returnCodes error -body {
+ proc p1 {} {upvar 0 b b}
+ p1
+} -result {can't upvar from variable to itself}
+test upvar-8.5 {errors in upvar command} -returnCodes error -body {
+ proc p1 {} {upvar 0 a b; upvar 0 b a}
+ p1
+} -result {can't upvar from variable to itself}
+test upvar-8.6 {errors in upvar command} -returnCodes error -body {
+ proc p1 {} {set a 33; upvar b a}
+ p1
+} -result {variable "a" already exists}
+test upvar-8.7 {errors in upvar command} -returnCodes error -body {
+ proc p1 {} {trace variable a w foo; upvar b a}
+ p1
+} -result {variable "a" has traces: can't use for upvar}
+test upvar-8.8 {create nested array with upvar} -body {
+ proc p1 {} {upvar x(a) b; set b(2) 44}
+ catch {unset x}
+ p1
+} -returnCodes error -cleanup {
+ unset x
+} -result {can't set "b(2)": variable isn't array}
+test upvar-8.9 {upvar won't create namespace variable that refers to procedure variable} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename MakeLink ""}
+ namespace eval ::test_ns_1 {}
+} -returnCodes error -body {
+ proc MakeLink {a} {
+ namespace eval ::test_ns_1 {
+ upvar a a
+ }
+ unset ::test_ns_1::a
+ }
+ MakeLink 1
+} -result {bad variable name "a": upvar won't create namespace variable that refers to procedure variable}
+test upvar-8.10 {upvar will create element alias for new array element} -setup {
+ catch {unset upvarArray}
+} -body {
+ array set upvarArray {}
+ catch {upvar 0 upvarArray(elem) upvarArrayElemAlias}
+} -result {0}
+test upvar-8.11 {upvar will not create a variable that looks like an array} -setup {
+ catch {unset upvarArray}
+} -body {
+ array set upvarArray {}
+ upvar 0 upvarArray(elem) upvarArrayElemAlias(elem)
+} -returnCodes 1 -match glob -result *
+
+test upvar-9.1 {Tcl_UpVar2 procedure} testupvar {
+ list [catch {testupvar xyz a {} x global} msg] $msg
+} {1 {bad level "xyz"}}
+test upvar-9.2 {Tcl_UpVar2 procedure} testupvar {
+ catch {unset a}
+ catch {unset x}
+ set a 44
+ list [catch "testupvar #0 a 1 x global" msg] $msg
+} {1 {can't access "a(1)": variable isn't array}}
+test upvar-9.3 {Tcl_UpVar2 procedure} testupvar {
+ proc foo {} {
+ testupvar 1 a {} x local
+ set x
+ }
+ catch {unset a}
+ catch {unset x}
+ set a 44
+ foo
+} {44}
+test upvar-9.4 {Tcl_UpVar2 procedure} testupvar {
+ proc foo {} {
+ testupvar 1 a {} _up_ global
+ list [catch {set x} msg] $msg
+ }
+ catch {unset a}
+ catch {unset _up_}
+ set a 44
+ concat [foo] $_up_
+} {1 {can't read "x": no such variable} 44}
+test upvar-9.5 {Tcl_UpVar2 procedure} testupvar {
+ proc foo {} {
+ testupvar 1 a b x local
+ set x
+ }
+ catch {unset a}
+ catch {unset x}
+ set a(b) 1234
+ foo
+} {1234}
+test upvar-9.6 {Tcl_UpVar procedure} testupvar {
+ proc foo {} {
+ testupvar 1 a x local
+ set x
+ }
+ catch {unset a}
+ catch {unset x}
+ set a xyzzy
+ foo
+} {xyzzy}
+test upvar-9.7 {Tcl_UpVar procedure} testupvar {
+ proc foo {} {
+ testupvar #0 a(b) x local
+ set x
+ }
+ catch {unset a}
+ catch {unset x}
+ set a(b) 1234
+ foo
+} {1234}
+catch {unset a}
+
+#
+# Tests for 'namespace upvar'. As the implementation is essentially the same as
+# for 'upvar', we only test that the variables are linked correctly, i.e., we
+# assume that the behaviour of variables once the link is established has
+# already been tested above.
+#
+
+# Clear out any namespaces called test_ns_*
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+namespace eval test_ns_0 {
+ variable x test_ns_0
+}
+set ::x test_global
+
+test upvar-NS-1.1 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ namespace upvar ::test_ns_0 x w
+ set w
+ }
+} -result {test_ns_0} -cleanup {
+ namespace delete test_ns_1
+}
+test upvar-NS-1.2 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ proc a {} {
+ namespace upvar ::test_ns_0 x w
+ set w
+ }
+ return [a]
+ }
+} -result {test_ns_0} -cleanup {
+ namespace delete test_ns_1
+}
+test upvar-NS-1.3 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ namespace upvar test_ns_0 x w
+ set w
+ }
+} -returnCodes error -cleanup {
+ namespace delete test_ns_1
+} -result {namespace "test_ns_0" not found in "::test_ns_1"}
+test upvar-NS-1.4 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ proc a {} {
+ namespace upvar test_ns_0 x w
+ set w
+ }
+ return [a]
+ }
+} -returnCodes error -cleanup {
+ namespace delete test_ns_1
+} -result {namespace "test_ns_0" not found in "::test_ns_1"}
+
+test upvar-NS-1.5 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ namespace eval test_ns_0 {}
+ namespace upvar test_ns_0 x w
+ set w
+ }
+} -cleanup {
+ namespace delete test_ns_1
+} -result {can't read "w": no such variable} -returnCodes error
+test upvar-NS-1.6 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ namespace eval test_ns_0 {}
+ proc a {} {
+ namespace upvar test_ns_0 x w
+ set w
+ }
+ return [a]
+ }
+} -cleanup {
+ namespace delete test_ns_1
+} -result {can't read "w": no such variable} -returnCodes error
+test upvar-NS-1.7 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ namespace eval test_ns_0 {
+ variable x test_ns_1::test_ns_0
+ }
+ namespace upvar test_ns_0 x w
+ set w
+ }
+} -cleanup {
+ namespace delete test_ns_1
+} -result {test_ns_1::test_ns_0}
+test upvar-NS-1.8 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ namespace eval test_ns_0 {
+ variable x test_ns_1::test_ns_0
+ }
+ proc a {} {
+ namespace upvar test_ns_0 x w
+ set w
+ }
+ return [a]
+ }
+} -cleanup {
+ namespace delete test_ns_1
+} -result {test_ns_1::test_ns_0}
+test upvar-NS-1.9 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ variable x test_ns_1
+ proc a {} {
+ namespace upvar test_ns_0 x w
+ set w
+ }
+ return [a]
+ }
+} -returnCodes error -cleanup {
+ namespace delete test_ns_1
+} -result {namespace "test_ns_0" not found in "::test_ns_1"}
+
+test upvar-NS-2.1 {TIP 323} -returnCodes error -body {
+ namespace upvar
+} -result {wrong # args: should be "namespace upvar ns ?otherVar myVar ...?"}
+test upvar-NS-2.2 {TIP 323} -setup {
+ namespace eval test_ns_1 {}
+} -body {
+ namespace upvar test_ns_1
+} -cleanup {
+ namespace delete test_ns_1
+} -result {}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/utf.test b/library/msgcat/tests/utf.test
new file mode 100644
index 0000000..fcd2a73
--- /dev/null
+++ b/library/msgcat/tests/utf.test
@@ -0,0 +1,445 @@
+# This file contains a collection of tests for tclUtf.c
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+catch {unset x}
+
+test utf-1.1 {Tcl_UniCharToUtf: 1 byte sequences} {
+ set x \x01
+} [bytestring "\x01"]
+test utf-1.2 {Tcl_UniCharToUtf: 2 byte sequences} {
+ set x "\x00"
+} [bytestring "\xc0\x80"]
+test utf-1.3 {Tcl_UniCharToUtf: 2 byte sequences} {
+ set x "\xe0"
+} [bytestring "\xc3\xa0"]
+test utf-1.4 {Tcl_UniCharToUtf: 3 byte sequences} {
+ set x "\u4e4e"
+} [bytestring "\xe4\xb9\x8e"]
+test utf-1.5 {Tcl_UniCharToUtf: overflowed Tcl_UniChar} {
+ format %c 0x110000
+} [bytestring "\xef\xbf\xbd"]
+test utf-1.6 {Tcl_UniCharToUtf: negative Tcl_UniChar} {
+ format %c -1
+} [bytestring "\xef\xbf\xbd"]
+
+test utf-2.1 {Tcl_UtfToUniChar: low ascii} {
+ string length "abc"
+} {3}
+test utf-2.2 {Tcl_UtfToUniChar: naked trail bytes} {
+ string length [bytestring "\x82\x83\x84"]
+} {3}
+test utf-2.3 {Tcl_UtfToUniChar: lead (2-byte) followed by non-trail} {
+ string length [bytestring "\xC2"]
+} {1}
+test utf-2.4 {Tcl_UtfToUniChar: lead (2-byte) followed by trail} {
+ string length [bytestring "\xC2\xa2"]
+} {1}
+test utf-2.5 {Tcl_UtfToUniChar: lead (3-byte) followed by non-trail} {
+ string length [bytestring "\xE2"]
+} {1}
+test utf-2.6 {Tcl_UtfToUniChar: lead (3-byte) followed by 1 trail} {
+ string length [bytestring "\xE2\xA2"]
+} {2}
+test utf-2.7 {Tcl_UtfToUniChar: lead (3-byte) followed by 2 trail} {
+ string length [bytestring "\xE4\xb9\x8e"]
+} {1}
+test utf-2.8 {Tcl_UtfToUniChar: longer UTF sequences not supported} {
+ string length [bytestring "\xF4\xA2\xA2\xA2"]
+} {4}
+
+test utf-3.1 {Tcl_UtfCharComplete} {
+} {}
+
+testConstraint testnumutfchars [llength [info commands testnumutfchars]]
+test utf-4.1 {Tcl_NumUtfChars: zero length} testnumutfchars {
+ testnumutfchars ""
+} {0}
+test utf-4.2 {Tcl_NumUtfChars: length 1} testnumutfchars {
+ testnumutfchars [bytestring "\xC2\xA2"]
+} {1}
+test utf-4.3 {Tcl_NumUtfChars: long string} testnumutfchars {
+ testnumutfchars [bytestring "abc\xC2\xA2\xe4\xb9\x8e\uA2\u4e4e"]
+} {7}
+test utf-4.4 {Tcl_NumUtfChars: #u0000} testnumutfchars {
+ testnumutfchars [bytestring "\xC0\x80"]
+} {1}
+test utf-4.5 {Tcl_NumUtfChars: zero length, calc len} testnumutfchars {
+ testnumutfchars "" 1
+} {0}
+test utf-4.6 {Tcl_NumUtfChars: length 1, calc len} testnumutfchars {
+ testnumutfchars [bytestring "\xC2\xA2"] 1
+} {1}
+test utf-4.7 {Tcl_NumUtfChars: long string, calc len} testnumutfchars {
+ testnumutfchars [bytestring "abc\xC2\xA2\xe4\xb9\x8e\uA2\u4e4e"] 1
+} {7}
+test utf-4.8 {Tcl_NumUtfChars: #u0000, calc len} testnumutfchars {
+ testnumutfchars [bytestring "\xC0\x80"] 1
+} {1}
+
+test utf-5.1 {Tcl_UtfFindFirsts} {
+} {}
+
+test utf-6.1 {Tcl_UtfNext} {
+} {}
+
+test utf-7.1 {Tcl_UtfPrev} {
+} {}
+
+test utf-8.1 {Tcl_UniCharAtIndex: index = 0} {
+ string index abcd 0
+} {a}
+test utf-8.2 {Tcl_UniCharAtIndex: index = 0} {
+ string index \u4e4e\u25a 0
+} "\u4e4e"
+test utf-8.3 {Tcl_UniCharAtIndex: index > 0} {
+ string index abcd 2
+} {c}
+test utf-8.4 {Tcl_UniCharAtIndex: index > 0} {
+ string index \u4e4e\u25a\xff\u543 2
+} "\uff"
+
+test utf-9.1 {Tcl_UtfAtIndex: index = 0} {
+ string range abcd 0 2
+} {abc}
+test utf-9.2 {Tcl_UtfAtIndex: index > 0} {
+ string range \u4e4e\u25a\xff\u543klmnop 1 5
+} "\u25a\xff\u543kl"
+
+
+test utf-10.1 {Tcl_UtfBackslash: dst == NULL} {
+ set x \n
+} {
+}
+test utf-10.2 {Tcl_UtfBackslash: \u subst} {
+ set x \ua2
+} [bytestring "\xc2\xa2"]
+test utf-10.3 {Tcl_UtfBackslash: longer \u subst} {
+ set x \u4e21
+} [bytestring "\xe4\xb8\xa1"]
+test utf-10.4 {Tcl_UtfBackslash: stops at first non-hex} {
+ set x \u4e2k
+} "[bytestring \xd3\xa2]k"
+test utf-10.5 {Tcl_UtfBackslash: stops after 4 hex chars} {
+ set x \u4e216
+} "[bytestring \xe4\xb8\xa1]6"
+proc bsCheck {char num} {
+ global errNum
+ test utf-10.$errNum {backslash substitution} {
+ scan $char %c value
+ set value
+ } $num
+ incr errNum
+}
+set errNum 6
+bsCheck \b 8
+bsCheck \e 101
+bsCheck \f 12
+bsCheck \n 10
+bsCheck \r 13
+bsCheck \t 9
+bsCheck \v 11
+bsCheck \{ 123
+bsCheck \} 125
+bsCheck \[ 91
+bsCheck \] 93
+bsCheck \$ 36
+bsCheck \ 32
+bsCheck \; 59
+bsCheck \\ 92
+bsCheck \Ca 67
+bsCheck \Ma 77
+bsCheck \CMa 67
+# prior to 8.3, this returned 8, as \8 as accepted as an
+# octal value - but it isn't! [Bug: 3975]
+bsCheck \8a 56
+bsCheck \14 12
+bsCheck \141 97
+bsCheck b\0 98
+bsCheck \x 120
+bsCheck \xa 10
+bsCheck \xA 10
+bsCheck \x41 65
+bsCheck \x541 84
+bsCheck \u 117
+bsCheck \uk 117
+bsCheck \u41 65
+bsCheck \ua 10
+bsCheck \uA 10
+bsCheck \340 224
+bsCheck \ua1 161
+bsCheck \u4e21 20001
+bsCheck \741 60
+bsCheck \U 85
+bsCheck \Uk 85
+bsCheck \U41 65
+bsCheck \Ua 10
+bsCheck \UA 10
+bsCheck \Ua1 161
+bsCheck \U4e21 20001
+bsCheck \U004e21 20001
+bsCheck \U00004e21 20001
+bsCheck \U00110000 65533
+bsCheck \Uffffffff 65533
+
+test utf-11.1 {Tcl_UtfToUpper} {
+ string toupper {}
+} {}
+test utf-11.2 {Tcl_UtfToUpper} {
+ string toupper abc
+} ABC
+test utf-11.3 {Tcl_UtfToUpper} {
+ string toupper \u00e3ab
+} \u00c3AB
+test utf-11.4 {Tcl_UtfToUpper} {
+ string toupper \u01e3ab
+} \u01e2AB
+
+test utf-12.1 {Tcl_UtfToLower} {
+ string tolower {}
+} {}
+test utf-12.2 {Tcl_UtfToLower} {
+ string tolower ABC
+} abc
+test utf-12.3 {Tcl_UtfToLower} {
+ string tolower \u00c3AB
+} \u00e3ab
+test utf-12.4 {Tcl_UtfToLower} {
+ string tolower \u01e2AB
+} \u01e3ab
+
+test utf-13.1 {Tcl_UtfToTitle} {
+ string totitle {}
+} {}
+test utf-13.2 {Tcl_UtfToTitle} {
+ string totitle abc
+} Abc
+test utf-13.3 {Tcl_UtfToTitle} {
+ string totitle \u00e3ab
+} \u00c3ab
+test utf-13.4 {Tcl_UtfToTitle} {
+ string totitle \u01f3ab
+} \u01f2ab
+
+test utf-14.1 {Tcl_UtfNcasecmp} {
+ string compare -nocase a b
+} -1
+test utf-14.2 {Tcl_UtfNcasecmp} {
+ string compare -nocase b a
+} 1
+test utf-14.3 {Tcl_UtfNcasecmp} {
+ string compare -nocase B a
+} 1
+test utf-14.4 {Tcl_UtfNcasecmp} {
+ string compare -nocase aBcB abca
+} 1
+
+test utf-15.1 {Tcl_UniCharToUpper, negative delta} {
+ string toupper aA
+} AA
+test utf-15.2 {Tcl_UniCharToUpper, positive delta} {
+ string toupper \u0178\u00ff
+} \u0178\u0178
+test utf-15.3 {Tcl_UniCharToUpper, no delta} {
+ string toupper !
+} !
+
+test utf-16.1 {Tcl_UniCharToLower, negative delta} {
+ string tolower aA
+} aa
+test utf-16.2 {Tcl_UniCharToLower, positive delta} {
+ string tolower \u0178\u00ff\uA78D\u01c5
+} \u00ff\u00ff\u0265\u01c6
+
+test utf-17.1 {Tcl_UniCharToLower, no delta} {
+ string tolower !
+} !
+
+test utf-18.1 {Tcl_UniCharToTitle, add one for title} {
+ string totitle \u01c4
+} \u01c5
+test utf-18.2 {Tcl_UniCharToTitle, subtract one for title} {
+ string totitle \u01c6
+} \u01c5
+test utf-18.3 {Tcl_UniCharToTitle, subtract delta for title (positive)} {
+ string totitle \u017f
+} \u0053
+test utf-18.4 {Tcl_UniCharToTitle, subtract delta for title (negative)} {
+ string totitle \u00ff
+} \u0178
+test utf-18.5 {Tcl_UniCharToTitle, no delta} {
+ string totitle !
+} !
+
+test utf-19.1 {TclUniCharLen} {
+ list [regexp \\d abc456def foo] $foo
+} {1 4}
+
+test utf-20.1 {TclUniCharNcmp} {
+} {}
+
+test utf-21.1 {TclUniCharIsAlnum} {
+ # this returns 1 with Unicode 6 compliance
+ string is alnum \u1040\u021f\u0220
+} {1}
+test utf-21.2 {unicode alnum char in regc_locale.c} {
+ # this returns 1 with Unicode 6 compliance
+ list [regexp {^[[:alnum:]]+$} \u1040\u021f\u0220] [regexp {^\w+$} \u1040\u021f\u0220]
+} {1 1}
+test utf-21.3 {unicode print char in regc_locale.c} {
+ # this returns 1 with Unicode 6 compliance
+ regexp {^[[:print:]]+$} \ufbc1
+} 1
+test utf-21.4 {TclUniCharIsGraph} {
+ # [Bug 3464428]
+ string is graph \u0120
+} {1}
+test utf-21.5 {unicode graph char in regc_locale.c} {
+ # [Bug 3464428]
+ regexp {^[[:graph:]]+$} \u0120
+} {1}
+test utf-21.6 {TclUniCharIsGraph} {
+ # [Bug 3464428]
+ string is graph \u00a0
+} {0}
+test utf-21.7 {unicode graph char in regc_locale.c} {
+ # [Bug 3464428]
+ regexp {[[:graph:]]} \u0020\u00a0\u2028\u2029
+} {0}
+test utf-21.8 {TclUniCharIsPrint} {
+ # [Bug 3464428]
+ string is print \u0009
+} {0}
+test utf-21.9 {unicode print char in regc_locale.c} {
+ # [Bug 3464428]
+ regexp {[[:print:]]} \u0009
+} {0}
+test utf-21.10 {unicode print char in regc_locale.c} {
+ # [Bug 3464428]
+ regexp {[[:print:]]} \u0009
+} {0}
+test utf-21.11 {TclUniCharIsControl} {
+ # [Bug 3464428]
+ string is control \u00ad
+} {1}
+test utf-21.12 {unicode control char in regc_locale.c} {
+ # [Bug 3464428]
+ regexp {^[[:cntrl:]]$} \u00ad
+} {1}
+
+test utf-22.1 {TclUniCharIsWordChar} {
+ string wordend "xyz123_bar fg" 0
+} 10
+test utf-22.2 {TclUniCharIsWordChar} {
+ string wordend "x\u5080z123_bar\u203c fg" 0
+} 10
+
+test utf-23.1 {TclUniCharIsAlpha} {
+ # this returns 1 with Unicode 6 compliance
+ string is alpha \u021f\u0220
+} {1}
+test utf-23.2 {unicode alpha char in regc_locale.c} {
+ # this returns 1 with Unicode 6 compliance
+ regexp {^[[:alpha:]]+$} \u021f\u0220
+} {1}
+
+test utf-24.1 {TclUniCharIsDigit} {
+ # this returns 1 with Unicode 6 compliance
+ string is digit \u1040\uabf0
+} {1}
+test utf-24.2 {unicode digit char in regc_locale.c} {
+ # this returns 1 with Unicode 6 compliance
+ list [regexp {^[[:digit:]]+$} \u1040\uabf0] [regexp {^\d+$} \u1040\uabf0]
+} {1 1}
+
+test utf-24.3 {TclUniCharIsSpace} {
+ # this returns 1 with Unicode 6 compliance
+ string is space \u1680\u180e
+} {1}
+test utf-24.4 {unicode space char in regc_locale.c} {
+ # this returns 1 with Unicode 6 compliance
+ list [regexp {^[[:space:]]+$} \u1680\u180e] [regexp {^\s+$} \u1680\u180e]
+} {1 1}
+
+testConstraint teststringobj [llength [info commands teststringobj]]
+
+test utf-25.1 {Tcl_UniCharNcasecmp} -constraints teststringobj \
+ -setup {
+ testobj freeallvars
+ } \
+ -body {
+ teststringobj set 1 a
+ teststringobj set 2 b
+ teststringobj getunicode 1
+ teststringobj getunicode 2
+ string compare -nocase [teststringobj get 1] [teststringobj get 2]
+ } \
+ -cleanup {
+ testobj freeallvars
+ } \
+ -result -1
+test utf-25.2 {Tcl_UniCharNcasecmp} -constraints teststringobj \
+ -setup {
+ testobj freeallvars
+ } \
+ -body {
+ teststringobj set 1 b
+ teststringobj set 2 a
+ teststringobj getunicode 1
+ teststringobj getunicode 2
+ string compare -nocase [teststringobj get 1] [teststringobj get 2]
+ } \
+ -cleanup {
+ testobj freeallvars
+ } \
+ -result 1
+test utf-25.3 {Tcl_UniCharNcasecmp} -constraints teststringobj \
+ -setup {
+ testobj freeallvars
+ } \
+ -body {
+ teststringobj set 1 B
+ teststringobj set 2 a
+ teststringobj getunicode 1
+ teststringobj getunicode 2
+ string compare -nocase [teststringobj get 1] [teststringobj get 2]
+ } \
+ -cleanup {
+ testobj freeallvars
+ } \
+ -result 1
+
+test utf-25.4 {Tcl_UniCharNcasecmp} -constraints teststringobj \
+ -setup {
+ testobj freeallvars
+ } \
+ -body {
+ teststringobj set 1 aBcB
+ teststringobj set 2 abca
+ teststringobj getunicode 1
+ teststringobj getunicode 2
+ string compare -nocase [teststringobj get 1] [teststringobj get 2]
+ } \
+ -cleanup {
+ testobj freeallvars
+ } \
+ -result 1
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/util.test b/library/msgcat/tests/util.test
new file mode 100644
index 0000000..1da533c
--- /dev/null
+++ b/library/msgcat/tests/util.test
@@ -0,0 +1,4024 @@
+# This file is a Tcl script to test the code in the file tclUtil.c.
+# This file is organized in the standard fashion for Tcl tests.
+#
+# Copyright (c) 1995-1998 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint controversialNaN 1
+testConstraint testdstring [llength [info commands testdstring]]
+testConstraint testconcatobj [llength [info commands testconcatobj]]
+testConstraint testdoubledigits [llength [info commands testdoubledigits]]
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+ variable ieeeValues
+ binary scan [binary format dd -1.0 1.0] c* c
+ switch -exact -- $c {
+ {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+ # little endian
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+ ieeeValues(-Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+ ieeeValues(-Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+ ieeeValues(-Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+ ieeeValues(+Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+ ieeeValues(+Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+ ieeeValues(NaN)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\xff d \
+ ieeeValues(-NaN)
+ binary scan \xef\xcd\xab\x89\x67\x45\xfb\xff d \
+ ieeeValues(-NaN(3456789abcdef))
+ set ieeeValues(littleEndian) 1
+ return 1
+ }
+ {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+ binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Infinity)
+ binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Normal)
+ binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Subnormal)
+ binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Normal)
+ binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Infinity)
+ binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(NaN)
+ binary scan \xff\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-NaN)
+ binary scan \xff\xfb\x45\x67\x89\xab\xcd\xef d \
+ ieeeValues(-NaN(3456789abcdef))
+ set ieeeValues(littleEndian) 0
+ return 1
+ }
+ default {
+ return 0
+ }
+ }
+}
+testConstraint ieeeFloatingPoint [testIEEE]
+
+proc convertDouble { x } {
+ variable ieeeValues
+ if { $ieeeValues(littleEndian) } {
+ binary scan [binary format w $x] d result
+ } else {
+ binary scan [binary format W $x] d result
+ }
+ return $result
+}
+
+proc verdonk_test {sig binexp shouldbe exp} {
+ regexp {([-+]?)([0-9a-f]+)} $sig -> signum sig
+ scan $sig %llx sig
+ if {$signum eq {-}} {
+ set signum [expr 1<<63]
+ } else {
+ set signum 0
+ }
+ regexp {E([-+]?[0-9]+)} $binexp -> binexp
+ set word [expr {$signum | (($binexp + 0x3ff)<<52)|($sig & ~(1<<52))}]
+ binary scan [binary format w $word] q double
+ regexp {([-+])(\d+)_(\d+)\&} $shouldbe -> signum digits1 digits2
+ regexp {E([-+]\d+)} $exp -> decexp
+ incr decexp [expr {[string length $digits1] - 1}]
+ lassign [testdoubledigits $double [string length $digits1] e] \
+ outdigits decpt outsign
+ if {[string index $digits2 0] >= 5} {
+ incr digits1
+ }
+ if {$outsign != $signum || $outdigits != $digits1 || $decpt != $decexp} {
+ return -code error "result is ${outsign}0.${outdigits}E$decpt\
+ should be ${signum}0.${digits1}E$decexp"
+ }
+}
+
+test util-1.1 {TclFindElement procedure - binary element in middle of list} {
+ lindex {0 foo\x00help 1} 1
+} "foo\x00help"
+test util-1.2 {TclFindElement procedure - binary element at end of list} {
+ lindex {0 foo\x00help} 1
+} "foo\x00help"
+
+test util-2.1 {TclCopyAndCollapse procedure - normal string} {
+ lindex {0 foo} 1
+} {foo}
+test util-2.2 {TclCopyAndCollapse procedure - string with backslashes} {
+ lindex {0 foo\n\x00help 1} 1
+} "foo\n\x00help"
+
+test util-3.1 {Tcl_ScanCountedElement procedure - don't leave unmatched braces} {
+ # This test checks for a very tricky feature. Any list element
+ # generated with Tcl_ScanCountedElement and Tcl_ConvertElement must
+ # have the property that it can be enclosing in curly braces to make
+ # an embedded sub-list. If this property doesn't hold, then
+ # Tcl_DStringStartSublist doesn't work.
+ set x {}
+ lappend x "# \\\{ \\"
+ concat $x [llength "{$x}"]
+} {\#\ \\\{\ \\ 1}
+test util-3.2 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+ list # # a
+} {{#} # a}
+test util-3.3 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+ list #\{ # a
+} {\#\{ # a}
+test util-3.4 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+ proc # {} {return #}
+ set result [eval [list #]]
+ rename # {}
+ set result
+} {#}
+test util-3.4.1 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+ proc # {} {return #}
+ set cmd [list #]
+ append cmd "" ;# force string rep generation
+ set result [eval $cmd]
+ rename # {}
+ set result
+} {#}
+test util-3.5 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+ proc #\{ {} {return #}
+ set result [eval [list #\{]]
+ rename #\{ {}
+ set result
+} {#}
+test util-3.5.1 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+ proc #\{ {} {return #}
+ set cmd [list #\{]
+ append cmd "" ;# force string rep generation
+ set result [eval $cmd]
+ rename #\{ {}
+ set result
+} {#}
+test util-3.6 {Tcl_ConvertElement, Bug 3371644} {
+ interp create #\\
+ interp alias {} x #\\ concat
+ interp target {} x ;# Crash if bug not fixed
+ interp delete #\\
+} {}
+
+test util-4.1 {Tcl_ConcatObj - backslash-space at end of argument} {
+ concat a {b\ } c
+} {a b\ c}
+test util-4.2 {Tcl_ConcatObj - backslash-space at end of argument} {
+ concat a {b\ } c
+} {a b\ c}
+test util-4.3 {Tcl_ConcatObj - backslash-space at end of argument} {
+ concat a {b\\ } c
+} {a b\\ c}
+test util-4.4 {Tcl_ConcatObj - backslash-space at end of argument} {
+ concat a {b } c
+} {a b c}
+test util-4.5 {Tcl_ConcatObj - backslash-space at end of argument} {
+ concat a { } c
+} {a c}
+test util-4.6 {Tcl_ConcatObj - utf-8 sequence with "whitespace" char} {
+ # Check for Bug #227512. If this violates C isspace, then it returns \xc3.
+ concat \xe0
+} \xe0
+test util-4.7 {Tcl_ConcatObj - refCount safety} testconcatobj {
+ # Check for Bug #1447328 (actually, bugs in its original "fix"). One of the
+ # symptoms was Bug #2055782.
+ testconcatobj
+} {}
+
+proc Wrapper_Tcl_StringMatch {pattern string} {
+ # Forces use of Tcl_StringMatch, not Tcl_UniCharCaseMatch
+ switch -glob -- $string $pattern {return 1} default {return 0}
+}
+test util-5.1 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch ab*c abc
+} 1
+test util-5.2 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch ab**c abc
+} 1
+test util-5.3 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch ab* abcdef
+} 1
+test util-5.4 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch *c abc
+} 1
+test util-5.5 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch *3*6*9 0123456789
+} 1
+test util-5.6 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch *3*6*9 01234567890
+} 0
+test util-5.7 {Tcl_StringMatch: UTF-8} {
+ Wrapper_Tcl_StringMatch *u \u4e4fu
+} 1
+test util-5.8 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch a?c abc
+} 1
+test util-5.9 {Tcl_StringMatch: UTF-8} {
+ # skip one character in string
+ Wrapper_Tcl_StringMatch a?c a\u4e4fc
+} 1
+test util-5.10 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch a??c abc
+} 0
+test util-5.11 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch ?1??4???8? 0123456789
+} 1
+test util-5.12 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {[abc]bc} abc
+} 1
+test util-5.13 {Tcl_StringMatch: UTF-8} {
+ # string += Tcl_UtfToUniChar(string, &ch);
+ Wrapper_Tcl_StringMatch "\[\u4e4fxy\]bc" "\u4e4fbc"
+} 1
+test util-5.14 {Tcl_StringMatch} {
+ # if ((*pattern == ']') || (*pattern == '\0'))
+ # badly formed pattern
+ Wrapper_Tcl_StringMatch {[]} {[]}
+} 0
+test util-5.15 {Tcl_StringMatch} {
+ # if ((*pattern == ']') || (*pattern == '\0'))
+ # badly formed pattern
+ Wrapper_Tcl_StringMatch {[} {[}
+} 0
+test util-5.16 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {a[abc]c} abc
+} 1
+test util-5.17 {Tcl_StringMatch: UTF-8} {
+ # pattern += Tcl_UtfToUniChar(pattern, &endChar);
+ # get 1 UTF-8 character
+ Wrapper_Tcl_StringMatch "a\[a\u4e4fc]c" "a\u4e4fc"
+} 1
+test util-5.18 {Tcl_StringMatch: UTF-8} {
+ # pattern += Tcl_UtfToUniChar(pattern, &endChar);
+ # proper advance: wrong answer would match on UTF trail byte of \u4e4f
+ Wrapper_Tcl_StringMatch {a[a\u4e4fc]c} [bytestring a\u008fc]
+} 0
+test util-5.19 {Tcl_StringMatch: UTF-8} {
+ # pattern += Tcl_UtfToUniChar(pattern, &endChar);
+ # proper advance.
+ Wrapper_Tcl_StringMatch {a[a\u4e4fc]c} "acc"
+} 1
+test util-5.20 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {a[xyz]c} abc
+} 0
+test util-5.21 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {12[2-7]45} 12345
+} 1
+test util-5.22 {Tcl_StringMatch: UTF-8 range} {
+ Wrapper_Tcl_StringMatch "\[\u4e00-\u4e4f]" "0"
+} 0
+test util-5.23 {Tcl_StringMatch: UTF-8 range} {
+ Wrapper_Tcl_StringMatch "\[\u4e00-\u4e4f]" "\u4e33"
+} 1
+test util-5.24 {Tcl_StringMatch: UTF-8 range} {
+ Wrapper_Tcl_StringMatch "\[\u4e00-\u4e4f]" "\uff08"
+} 0
+test util-5.25 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {12[ab2-4cd]45} 12345
+} 1
+test util-5.26 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {12[ab2-4cd]45} 12b45
+} 1
+test util-5.27 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {12[ab2-4cd]45} 12d45
+} 1
+test util-5.28 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {12[ab2-4cd]45} 12145
+} 0
+test util-5.29 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {12[ab2-4cd]45} 12545
+} 0
+test util-5.30 {Tcl_StringMatch: forwards range} {
+ Wrapper_Tcl_StringMatch {[k-w]} "z"
+} 0
+test util-5.31 {Tcl_StringMatch: forwards range} {
+ Wrapper_Tcl_StringMatch {[k-w]} "w"
+} 1
+test util-5.32 {Tcl_StringMatch: forwards range} {
+ Wrapper_Tcl_StringMatch {[k-w]} "r"
+} 1
+test util-5.33 {Tcl_StringMatch: forwards range} {
+ Wrapper_Tcl_StringMatch {[k-w]} "k"
+} 1
+test util-5.34 {Tcl_StringMatch: forwards range} {
+ Wrapper_Tcl_StringMatch {[k-w]} "a"
+} 0
+test util-5.35 {Tcl_StringMatch: reverse range} {
+ Wrapper_Tcl_StringMatch {[w-k]} "z"
+} 0
+test util-5.36 {Tcl_StringMatch: reverse range} {
+ Wrapper_Tcl_StringMatch {[w-k]} "w"
+} 1
+test util-5.37 {Tcl_StringMatch: reverse range} {
+ Wrapper_Tcl_StringMatch {[w-k]} "r"
+} 1
+test util-5.38 {Tcl_StringMatch: reverse range} {
+ Wrapper_Tcl_StringMatch {[w-k]} "k"
+} 1
+test util-5.39 {Tcl_StringMatch: reverse range} {
+ Wrapper_Tcl_StringMatch {[w-k]} "a"
+} 0
+test util-5.40 {Tcl_StringMatch: skip correct number of ']'} {
+ Wrapper_Tcl_StringMatch {[A-]x} Ax
+} 0
+test util-5.41 {Tcl_StringMatch: skip correct number of ']'} {
+ Wrapper_Tcl_StringMatch {[A-]]x} Ax
+} 1
+test util-5.42 {Tcl_StringMatch: skip correct number of ']'} {
+ Wrapper_Tcl_StringMatch {[A-]]x} \ue1x
+} 0
+test util-5.43 {Tcl_StringMatch: skip correct number of ']'} {
+ Wrapper_Tcl_StringMatch \[A-]\ue1]x \ue1x
+} 1
+test util-5.44 {Tcl_StringMatch: skip correct number of ']'} {
+ Wrapper_Tcl_StringMatch {[A-]h]x} hx
+} 1
+test util-5.45 {Tcl_StringMatch} {
+ # if (*pattern == '\0')
+ # badly formed pattern, still treats as a set
+ Wrapper_Tcl_StringMatch {[a} a
+} 1
+test util-5.46 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {a\*b} a*b
+} 1
+test util-5.47 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {a\*b} ab
+} 0
+test util-5.48 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {a\*\?\[\]\\\x} "a*?\[\]\\x"
+} 1
+test util-5.49 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch ** ""
+} 1
+test util-5.50 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch *. ""
+} 0
+test util-5.51 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch "" ""
+} 1
+
+test util-6.1 {Tcl_PrintDouble - using tcl_precision} -setup {
+ set old_precision $::tcl_precision
+ set ::tcl_precision 12
+} -body {
+ concat x[expr 1.4]
+} -cleanup {
+ set ::tcl_precision $old_precision
+} -result {x1.4}
+test util-6.2 {Tcl_PrintDouble - using tcl_precision} -setup {
+ set old_precision $::tcl_precision
+ set ::tcl_precision 12
+} -body {
+ concat x[expr 1.39999999999]
+} -cleanup {
+ set ::tcl_precision $old_precision
+} -result {x1.39999999999}
+test util-6.3 {Tcl_PrintDouble - using tcl_precision} -setup {
+ set old_precision $::tcl_precision
+ set ::tcl_precision 12
+} -body {
+ concat x[expr 1.399999999999]
+} -cleanup {
+ set ::tcl_precision $old_precision
+} -result {x1.4}
+test util-6.4 {Tcl_PrintDouble - using tcl_precision} -setup {
+ set old_precision $::tcl_precision
+ set ::tcl_precision 5
+} -body {
+ concat x[expr 1.123412341234]
+} -cleanup {
+ set tcl_precision $old_precision
+} -result {x1.1234}
+test util-6.5 {Tcl_PrintDouble - make sure there's a decimal point} {
+ concat x[expr 2.0]
+} {x2.0}
+test util-6.6 {Tcl_PrintDouble - make sure there's a decimal point} {
+ concat x[expr 3.0e98]
+} {x3e+98}
+
+test util-7.1 {TclPrecTraceProc - unset callbacks} -setup {
+ set old_precision $::tcl_precision
+} -body {
+ set tcl_precision 7
+ set x $tcl_precision
+ unset tcl_precision
+ list $x $tcl_precision
+} -cleanup {
+ set ::tcl_precision $old_precision
+} -result {7 7}
+test util-7.2 {TclPrecTraceProc - read traces, sharing among interpreters} -setup {
+ set old_precision $::tcl_precision
+} -body {
+ set tcl_precision 12
+ interp create child
+ set x [child eval set tcl_precision]
+ child eval {set tcl_precision 6}
+ interp delete child
+ list $x $tcl_precision
+} -cleanup {
+ set ::tcl_precision $old_precision
+} -result {12 6}
+test util-7.3 {TclPrecTraceProc - write traces, safe interpreters} -setup {
+ set old_precision $::tcl_precision
+} -body {
+ set tcl_precision 12
+ interp create -safe child
+ set x [child eval {
+ list [catch {set tcl_precision 8} msg] $msg
+ }]
+ interp delete child
+ list $x $tcl_precision
+} -cleanup {
+ set ::tcl_precision $old_precision
+} -result {{1 {can't set "tcl_precision": can't modify precision from a safe interpreter}} 12}
+test util-7.4 {TclPrecTraceProc - write traces, bogus values} -setup {
+ set old_precision $::tcl_precision
+} -body {
+ set tcl_precision 12
+ list [catch {set tcl_precision abc} msg] $msg $tcl_precision
+} -cleanup {
+ set ::tcl_precision $old_precision
+} -result {1 {can't set "tcl_precision": improper value for precision} 12}
+
+# This test always succeeded in the C locale anyway...
+test util-8.1 {TclNeedSpace - correct UTF8 handling} {
+ # Bug 411825
+ # Note that this test relies on the fact that
+ # [interp target] calls on Tcl_AppendElement()
+ # which calls on TclNeedSpace(). If [interp target]
+ # is ever updated, this test will no longer test
+ # TclNeedSpace.
+ interp create \u5420
+ interp create [list \u5420 foo]
+ interp alias {} fooset [list \u5420 foo] set
+ set result [interp target {} fooset]
+ interp delete \u5420
+ set result
+} "\u5420 foo"
+test util-8.2 {TclNeedSpace - correct UTF8 handling} testdstring {
+ # Bug 411825
+ # This tests the same bug as the previous test, but
+ # should be more future-proof, as the DString
+ # operations will likely continue to call TclNeedSpace
+ testdstring free
+ testdstring append \u5420 -1
+ testdstring element foo
+ llength [testdstring get]
+} 2
+test util-8.3 {TclNeedSpace - correct UTF8 handling} testdstring {
+ # Bug 411825 - new variant reported by Dossy Shiobara
+ testdstring free
+ testdstring append \u00A0 -1
+ testdstring element foo
+ llength [testdstring get]
+} 2
+test util-8.4 {TclNeedSpace - correct UTF8 handling} testdstring {
+ # Another bug uncovered while fixing 411825
+ testdstring free
+ testdstring append {\ } -1
+ testdstring append \{ -1
+ testdstring element foo
+ llength [testdstring get]
+} 2
+test util-8.5 {TclNeedSpace - correct UTF8 handling} testdstring {
+ # Note that in this test TclNeedSpace actually gets it wrong,
+ # claiming we need a space when we really do not. Extra space
+ # between list elements is harmless though, and better to have
+ # extra space in really weird string reps of lists, than to
+ # invest the effort required to make TclNeedSpace foolproof.
+ testdstring free
+ testdstring append {\\ } -1
+ testdstring element foo
+ list [llength [testdstring get]] [string length [testdstring get]]
+} {2 7}
+test util-8.6 {TclNeedSpace - correct UTF8 handling} testdstring {
+ # Another example of TclNeedSpace harmlessly getting it wrong.
+ testdstring free
+ testdstring append {\\ } -1
+ testdstring append \{ -1
+ testdstring element foo
+ testdstring append \} -1
+ list [llength [testdstring get]] [string length [testdstring get]]
+} {2 9}
+
+test util-9.0.0 {TclGetIntForIndex} {
+ string index abcd 0
+} a
+test util-9.0.1 {TclGetIntForIndex} {
+ string index abcd 0x0
+} a
+test util-9.0.2 {TclGetIntForIndex} {
+ string index abcd -0x0
+} a
+test util-9.0.3 {TclGetIntForIndex} {
+ string index abcd { 0 }
+} a
+test util-9.0.4 {TclGetIntForIndex} {
+ string index abcd { 0x0 }
+} a
+test util-9.0.5 {TclGetIntForIndex} {
+ string index abcd { -0x0 }
+} a
+test util-9.0.6 {TclGetIntForIndex} {
+ string index abcd 01
+} b
+test util-9.0.7 {TclGetIntForIndex} {
+ string index abcd { 01 }
+} b
+test util-9.1.0 {TclGetIntForIndex} {
+ string index abcd 3
+} d
+test util-9.1.1 {TclGetIntForIndex} {
+ string index abcd { 3 }
+} d
+test util-9.1.2 {TclGetIntForIndex} {
+ string index abcdefghijk 0xa
+} k
+test util-9.1.3 {TclGetIntForIndex} {
+ string index abcdefghijk { 0xa }
+} k
+test util-9.2.0 {TclGetIntForIndex} {
+ string index abcd end
+} d
+test util-9.2.1 {TclGetIntForIndex} -body {
+ string index abcd { end}
+} -returnCodes error -match glob -result *
+test util-9.2.2 {TclGetIntForIndex} -body {
+ string index abcd {end }
+} -returnCodes error -match glob -result *
+test util-9.3 {TclGetIntForIndex} {
+ # Deprecated
+ string index abcd en
+} d
+test util-9.4 {TclGetIntForIndex} {
+ # Deprecated
+ string index abcd e
+} d
+test util-9.5.0 {TclGetIntForIndex} {
+ string index abcd end-1
+} c
+test util-9.5.1 {TclGetIntForIndex} {
+ string index abcd {end-1 }
+} c
+test util-9.5.2 {TclGetIntForIndex} -body {
+ string index abcd { end-1}
+} -returnCodes error -match glob -result *
+test util-9.6 {TclGetIntForIndex} {
+ string index abcd end+-1
+} c
+test util-9.7 {TclGetIntForIndex} {
+ string index abcd end+1
+} {}
+test util-9.8 {TclGetIntForIndex} {
+ string index abcd end--1
+} {}
+test util-9.9.0 {TclGetIntForIndex} {
+ string index abcd 0+0
+} a
+test util-9.9.1 {TclGetIntForIndex} {
+ string index abcd { 0+0 }
+} a
+test util-9.10 {TclGetIntForIndex} {
+ string index abcd 0-0
+} a
+test util-9.11 {TclGetIntForIndex} {
+ string index abcd 1+0
+} b
+test util-9.12 {TclGetIntForIndex} {
+ string index abcd 1-0
+} b
+test util-9.13 {TclGetIntForIndex} {
+ string index abcd 1+1
+} c
+test util-9.14 {TclGetIntForIndex} {
+ string index abcd 1-1
+} a
+test util-9.15 {TclGetIntForIndex} {
+ string index abcd -1+2
+} b
+test util-9.16 {TclGetIntForIndex} {
+ string index abcd -1--2
+} b
+test util-9.17 {TclGetIntForIndex} {
+ string index abcd { -1+2 }
+} b
+test util-9.18 {TclGetIntForIndex} {
+ string index abcd { -1--2 }
+} b
+test util-9.19 {TclGetIntForIndex} -body {
+ string index a {}
+} -returnCodes error -match glob -result *
+test util-9.20 {TclGetIntForIndex} -body {
+ string index a { }
+} -returnCodes error -match glob -result *
+test util-9.21 {TclGetIntForIndex} -body {
+ string index a " \r\t\n"
+} -returnCodes error -match glob -result *
+test util-9.22 {TclGetIntForIndex} -body {
+ string index a +
+} -returnCodes error -match glob -result *
+test util-9.23 {TclGetIntForIndex} -body {
+ string index a -
+} -returnCodes error -match glob -result *
+test util-9.24 {TclGetIntForIndex} -body {
+ string index a x
+} -returnCodes error -match glob -result *
+test util-9.25 {TclGetIntForIndex} -body {
+ string index a +x
+} -returnCodes error -match glob -result *
+test util-9.26 {TclGetIntForIndex} -body {
+ string index a -x
+} -returnCodes error -match glob -result *
+test util-9.27 {TclGetIntForIndex} -body {
+ string index a 0y
+} -returnCodes error -match glob -result *
+test util-9.28 {TclGetIntForIndex} -body {
+ string index a 1*
+} -returnCodes error -match glob -result *
+test util-9.29 {TclGetIntForIndex} -body {
+ string index a 0+
+} -returnCodes error -match glob -result *
+test util-9.30 {TclGetIntForIndex} -body {
+ string index a {0+ }
+} -returnCodes error -match glob -result *
+test util-9.31 {TclGetIntForIndex} -body {
+ string index a 0x
+} -returnCodes error -match glob -result *
+test util-9.32 {TclGetIntForIndex} -body {
+ string index a 0x1FFFFFFFF+0
+} -returnCodes error -match glob -result *
+test util-9.33 {TclGetIntForIndex} -body {
+ string index a 100000000000+0
+} -returnCodes error -match glob -result *
+test util-9.34 {TclGetIntForIndex} -body {
+ string index a 1.0
+} -returnCodes error -match glob -result *
+test util-9.35 {TclGetIntForIndex} -body {
+ string index a 1e23
+} -returnCodes error -match glob -result *
+test util-9.36 {TclGetIntForIndex} -body {
+ string index a 1.5e2
+} -returnCodes error -match glob -result *
+test util-9.37 {TclGetIntForIndex} -body {
+ string index a 0+x
+} -returnCodes error -match glob -result *
+test util-9.38 {TclGetIntForIndex} -body {
+ string index a 0+0x
+} -returnCodes error -match glob -result *
+test util-9.39 {TclGetIntForIndex} -body {
+ string index a 0+0xg
+} -returnCodes error -match glob -result *
+test util-9.40 {TclGetIntForIndex} -body {
+ string index a 0+0xg
+} -returnCodes error -match glob -result *
+test util-9.41 {TclGetIntForIndex} -body {
+ string index a 0+1.0
+} -returnCodes error -match glob -result *
+test util-9.42 {TclGetIntForIndex} -body {
+ string index a 0+1e2
+} -returnCodes error -match glob -result *
+test util-9.43 {TclGetIntForIndex} -body {
+ string index a 0+1.5e1
+} -returnCodes error -match glob -result *
+test util-9.44 {TclGetIntForIndex} -body {
+ string index a 0+1000000000000
+} -returnCodes error -match glob -result *
+
+test util-10.1 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x0000000000000000
+} {0.0}
+test util-10.2 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x8000000000000000
+} {-0.0}
+test util-10.3 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x7ef754e31cd072da
+} {4e+303}
+test util-10.4 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xd08afcef51f0fb5f
+} {-1e+80}
+test util-10.5 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x7ed754e31cd072da
+} {1e+303}
+test util-10.6 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xfee754e31cd072da
+} {-2e+303}
+test util-10.7 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x0afe07b27dd78b14
+} {1e-255}
+test util-10.8 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x93ae29e9c56687fe
+} {-7e-214}
+test util-10.9 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x376be03d0bf225c7
+} {1e-41}
+test util-10.10 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xa0ca2fe76a3f9475
+} {-1e-150}
+test util-10.11 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x7fa9a2028368022e
+} {9e+306}
+test util-10.12 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xdfc317e5ef3ab327
+} {-2e+153}
+test util-10.13 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x5fd317e5ef3ab327
+} {4e+153}
+test util-10.14 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xdfe317e5ef3ab327
+} {-8e+153}
+test util-10.15 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x00feb8e84fa0b278
+} {7e-304}
+test util-10.16 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x8133339131c46f8b
+} {-7e-303}
+test util-10.17 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x35dc0f92a6276c9d
+} {3e-49}
+test util-10.18 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xa445ce1f143d7ad2
+} {-6e-134}
+test util-10.19 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x2d2c0794d9d40e96
+} {4.3e-91}
+test util-10.20 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xad3c0794d9d40e96
+} {-8.6e-91}
+test util-10.21 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x30ecd5bee57763e6
+} {5.1e-73}
+test util-10.22 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x68ad1c26db7d0dae
+} {1.7e+196}
+test util-10.23 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbfa3f7ced916872b
+} {-0.039}
+test util-10.24 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x64b7d93193f78fc6
+} {1.51e+177}
+test util-10.25 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x98ea82a1631eeb30
+} {-1.19e-188}
+test util-10.26 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xd216c309024bab4b
+} {-2.83e+87}
+test util-10.27 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x0dfdbbac6f83a821
+} {2.7869147e-241}
+test util-10.28 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xdadc569e968e0944
+} {-4.91080654e+129}
+test util-10.29 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x5acc569e968e0944
+} {2.45540327e+129}
+test util-10.30 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xab5fc575867314ee
+} {-9.078555839e-100}
+test util-10.31 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xdabc569e968e0944
+} {-1.227701635e+129}
+test util-10.32 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x2b6fc575867314ee
+} {1.8157111678e-99}
+test util-10.33 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xb3b8bf7e7fa6f02a
+} {-1.5400733123779e-59}
+test util-10.34 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xcd83de005bd620df
+} {-2.6153245263757307e+65}
+test util-10.35 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x6cdf92bacb3cb40c
+} {2.7210404151224248e+216}
+test util-10.36 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xecef92bacb3cb40c
+} {-5.4420808302448496e+216}
+test util-10.37 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x49342dbf25096cf5
+} {4.5e+44}
+test util-10.38 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xd06afcef51f0fb5f
+} {-2.5e+79}
+test util-10.39 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x49002498ea6df0c4
+} {4.5e+43}
+test util-10.40 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xfeb754e31cd072da
+} {-2.5e+302}
+test util-10.41 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x1d22deac01e2b4f7
+} {2.5e-168}
+test util-10.42 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xaccb1df536c13eee
+} {-6.5e-93}
+test util-10.43 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3650711fed5b19a4
+} {4.5e-47}
+test util-10.44 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xb6848d67e8b1e00d
+} {-4.5e-46}
+test util-10.45 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x4bac8c574c0c6be7
+} {3.5e+56}
+test util-10.46 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xccd756183c147514
+} {-1.5e+62}
+test util-10.47 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x4ca2ab469676c410
+} {1.5e+61}
+test util-10.48 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xcf5539684e774b48
+} {-1.5e+74}
+test util-10.49 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x2e12e5f5dfa4fe9d
+} {9.5e-87}
+test util-10.50 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x8b9bdc2417bf7787
+} {-9.5e-253}
+test util-10.51 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x00eeb8e84fa0b278
+} {3.5e-304}
+test util-10.52 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xadde3cbc9907fdc8
+} {-9.5e-88}
+test util-10.53 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x2bb0ad836f269a17
+} {3.05e-98}
+test util-10.54 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x950b39ae1909c31b
+} {-2.65e-207}
+test util-10.55 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x1bfb2ab18615fcc6
+} {6.865e-174}
+test util-10.56 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x98f3e1f90a573064
+} {-1.785e-188}
+test util-10.57 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x5206c309024bab4b
+} {1.415e+87}
+test util-10.58 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xcc059bd3ad46e346
+} {-1.6955e+58}
+test util-10.59 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x47bdf4170f0fdecc
+} {3.9815e+37}
+test util-10.60 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x59e7e1e0f1c7a4ac
+} {1.263005e+125}
+test util-10.61 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xda1dda592e398dd7
+} {-1.263005e+126}
+test util-10.62 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xdc4e597c0b94b7ae
+} {-4.4118455e+136}
+test util-10.63 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x5aac569e968e0944
+} {6.138508175e+128}
+test util-10.64 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xdabc569e968e0944
+} {-1.227701635e+129}
+test util-10.65 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x6ce7ae0c186d8709
+} {4.081560622683637e+216}
+test util-10.66 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x44b52d02c7e14af7
+} {1.0000000000000001e+23}
+test util-10.67 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc589d971e4fe8402
+} {-1e+27}
+test util-10.68 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x4599d971e4fe8402
+} {2e+27}
+test util-10.69 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc5a9d971e4fe8402
+} {-4e+27}
+test util-10.70 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3e45798ee2308c3a
+} {1e-8}
+test util-10.71 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbe55798ee2308c3a
+} {-2e-8}
+test util-10.72 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3e65798ee2308c3a
+} {4e-8}
+test util-10.73 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbabef2d0f5da7dd9
+} {-1e-25}
+test util-10.74 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x44da784379d99db4
+} {5e+23}
+test util-10.75 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc4fa784379d99db4
+} {-2e+24}
+test util-10.76 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x4503da329b633647
+} {3e+24}
+test util-10.77 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc54cf389cd46047d
+} {-7e+25}
+test util-10.78 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3fc999999999999a
+} {0.2}
+test util-10.79 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbfd3333333333333
+} {-0.3}
+test util-10.80 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3cf6849b86a12b9b
+} {5e-15}
+test util-10.81 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbd16849b86a12b9b
+} {-2e-14}
+test util-10.82 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3b87ccfc73126788
+} {6.3e-22}
+test util-10.83 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbbbdc03b8fd7016a
+} {-6.3e-21}
+test util-10.84 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3fa3f7ced916872b
+} {0.039}
+test util-10.85 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x460b297cad9f70b6
+} {2.69e+29}
+test util-10.86 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc61b297cad9f70b6
+} {-5.38e+29}
+test util-10.87 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3adcdc06b20ef183
+} {3.73e-25}
+test util-10.88 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x45fb297cad9f70b6
+} {1.345e+29}
+test util-10.89 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc60b297cad9f70b6
+} {-2.69e+29}
+test util-10.90 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbc050a246ecd44f3
+} {-1.4257e-19}
+test util-10.91 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbec19b96f36ec68b
+} {-2.09901e-6}
+test util-10.92 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3dcc06d366394441
+} {5.0980203373e-11}
+test util-10.93 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc79f58ac4db68c90
+} {-1.04166211811e+37}
+test util-10.94 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x4569d971e4fe8402
+} {2.5e+26}
+test util-10.95 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc50dc74be914d16b
+} {-4.5e+24}
+test util-10.96 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x4534adf4b7320335
+} {2.5e+25}
+test util-10.97 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc54ae22487c1042b
+} {-6.5e+25}
+test util-10.98 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3c987fe49aab41e0
+} {8.5e-17}
+test util-10.99 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbc2f5c05e4b23fd7
+} {-8.5e-19}
+test util-10.100 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3d5faa7ab552a552
+} {4.5e-13}
+test util-10.101 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbdbb7cdfd9d7bdbb
+} {-2.5e-11}
+test util-10.102 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x44f3da329b633647
+} {1.5e+24}
+test util-10.103 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc53cf389cd46047d
+} {-3.5e+25}
+test util-10.104 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x454f04ef12cb04cf
+} {7.5e+25}
+test util-10.105 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc55f04ef12cb04cf
+} {-1.5e+26}
+test util-10.106 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3fc3333333333333
+} {0.15}
+test util-10.107 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbdb07e1fe91b0b70
+} {-1.5e-11}
+test util-10.108 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3de49da7e361ce4c
+} {1.5e-10}
+test util-10.109 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbe19c511dc3a41df
+} {-1.5e-9}
+test util-10.110 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc5caa83d74267822
+} {-1.65e+28}
+test util-10.111 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x4588f1d5969453de
+} {9.65e+26}
+test util-10.112 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3b91d9bd564dcda6
+} {9.45e-22}
+test util-10.113 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbcfa58973ecbede6
+} {-5.85e-15}
+test util-10.114 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x45eb297cad9f70b6
+} {6.725e+28}
+test util-10.115 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc5fb297cad9f70b6
+} {-1.345e+29}
+test util-10.116 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3accdc06b20ef183
+} {1.865e-25}
+test util-10.117 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbd036071dcae4565
+} {-8.605e-15}
+test util-10.118 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x462cb968d297dde8
+} {1.137885e+30}
+test util-10.119 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc661f3e1839eeab1
+} {-1.137885e+31}
+test util-10.120 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x474e9cec176c96f8
+} {3.179033335e+35}
+test util-10.121 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3dbc06d366394441
+} {2.54901016865e-11}
+test util-10.122 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x478f58ac4db68c90
+} {5.20831059055e+36}
+
+test util-11.1 {Tcl_PrintDouble - scaling} {
+ expr 1.1e-5
+} {1.1e-5}
+test util-11.2 {Tcl_PrintDouble - scaling} {
+ expr 1.1e-4
+} {0.00011}
+test util-11.3 {Tcl_PrintDouble - scaling} {
+ expr 1.1e-3
+} {0.0011}
+test util-11.4 {Tcl_PrintDouble - scaling} {
+ expr 1.1e-2
+} {0.011}
+test util-11.5 {Tcl_PrintDouble - scaling} {
+ expr 1.1e-1
+} {0.11}
+test util-11.6 {Tcl_PrintDouble - scaling} {
+ expr 1.1e0
+} {1.1}
+test util-11.7 {Tcl_PrintDouble - scaling} {
+ expr 1.1e1
+} {11.0}
+test util-11.8 {Tcl_PrintDouble - scaling} {
+ expr 1.1e2
+} {110.0}
+test util-11.9 {Tcl_PrintDouble - scaling} {
+ expr 1.1e3
+} {1100.0}
+test util-11.10 {Tcl_PrintDouble - scaling} {
+ expr 1.1e4
+} {11000.0}
+test util-11.11 {Tcl_PrintDouble - scaling} {
+ expr 1.1e5
+} {110000.0}
+test util-11.12 {Tcl_PrintDouble - scaling} {
+ expr 1.1e6
+} {1100000.0}
+test util-11.13 {Tcl_PrintDouble - scaling} {
+ expr 1.1e7
+} {11000000.0}
+test util-11.14 {Tcl_PrintDouble - scaling} {
+ expr 1.1e8
+} {110000000.0}
+test util-11.15 {Tcl_PrintDouble - scaling} {
+ expr 1.1e9
+} {1100000000.0}
+test util-11.16 {Tcl_PrintDouble - scaling} {
+ expr 1.1e10
+} {11000000000.0}
+test util-11.17 {Tcl_PrintDouble - scaling} {
+ expr 1.1e11
+} {110000000000.0}
+test util-11.18 {Tcl_PrintDouble - scaling} {
+ expr 1.1e12
+} {1100000000000.0}
+test util-11.19 {Tcl_PrintDouble - scaling} {
+ expr 1.1e13
+} {11000000000000.0}
+test util-11.20 {Tcl_PrintDouble - scaling} {
+ expr 1.1e14
+} {110000000000000.0}
+test util-11.21 {Tcl_PrintDouble - scaling} {
+ expr 1.1e15
+} {1100000000000000.0}
+test util-11.22 {Tcl_PrintDouble - scaling} {
+ expr 1.1e16
+} {11000000000000000.0}
+test util-11.23 {Tcl_PrintDouble - scaling} {
+ expr 1.1e17
+} {1.1e+17}
+
+test util-12.1 {TclDoubleDigits - Inf} {testdoubledigits ieeeFloatingPoint} {
+ testdoubledigits Inf -1 shortest
+} {Infinity 9999 +}
+test util-12.2 {TclDoubleDigits - -Inf} {testdoubledigits ieeeFloatingPoint} {
+ testdoubledigits -Inf -1 shortest
+} {Infinity 9999 -}
+test util-12.3 {TclDoubleDigits - NaN} {testdoubledigits ieeeFloatingPoint} {
+ testdoubledigits $ieeeValues(NaN) -1 shortest
+} {NaN 9999 +}
+test util-12.4 {TclDoubleDigits - NaN} {*}{
+ -constraints {testdoubledigits ieeeFloatingPoint controversialNaN}
+ -body {
+ testdoubledigits -NaN -1 shortest
+ }
+ -result {NaN 9999 -}
+}
+test util-12.5 {TclDoubleDigits - 0} testdoubledigits {
+ testdoubledigits 0.0 -1 shortest
+} {0 0 +}
+test util-12.6 {TclDoubleDigits - -0} testdoubledigits {
+ testdoubledigits -0.0 -1 shortest
+} {0 0 -}
+
+# Verdonk test vectors
+
+test util-13.1 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1754e31cd072da E+1008 +4_000000000000000000& E+303
+ }
+ -result {}
+}
+test util-13.2 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1afcef51f0fb5f E+265 -1_000000000000000000& E+80
+ }
+ -result {}
+}
+test util-13.3 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1754e31cd072da E+1006 +1_000000000000000000& E+303
+ }
+ -result {}
+}
+test util-13.4 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1754e31cd072da E+1007 -2_000000000000000000& E+303
+ }
+ -result {}
+}
+test util-13.5 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1e07b27dd78b14 E-848 +1_00000000000000000& E-255
+ }
+ -result {}
+}
+test util-13.6 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1e29e9c56687fe E-709 -7_00000000000000000& E-214
+ }
+ -result {}
+}
+test util-13.7 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1be03d0bf225c7 E-137 +1_00000000000000000& E-41
+ }
+ -result {}
+}
+test util-13.8 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1a2fe76a3f9475 E-499 -1_00000000000000000& E-150
+ }
+ -result {}
+}
+test util-13.9 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 19a2028368022e E+1019 +8_999999999999999999& E+306
+ }
+ -result {}
+}
+test util-13.10 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1317e5ef3ab327 E+509 -1_999999999999999999& E+153
+ }
+ -result {}
+}
+test util-13.11 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1317e5ef3ab327 E+510 +3_99999999999999999& E+153
+ }
+ -result {}
+}
+test util-13.12 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1317e5ef3ab327 E+511 -7_99999999999999999& E+153
+ }
+ -result {}
+}
+test util-13.13 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1eb8e84fa0b278 E-1008 +6_999999999999999999& E-304
+ }
+ -result {}
+}
+test util-13.14 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -13339131c46f8b E-1004 -6_999999999999999999& E-303
+ }
+ -result {}
+}
+test util-13.15 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1c0f92a6276c9d E-162 +2_999999999999999999& E-49
+ }
+ -result {}
+}
+test util-13.16 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -15ce1f143d7ad2 E-443 -5_99999999999999999& E-134
+ }
+ -result {}
+}
+test util-13.17 {just over exact - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1c0794d9d40e96 E-301 +43_000000000000000000& E-92
+ }
+ -result {}
+}
+test util-13.18 {just over exact - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1c0794d9d40e96 E-300 -86_000000000000000000& E-92
+ }
+ -result {}
+}
+test util-13.19 {just over exact - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1cd5bee57763e6 E-241 +51_000000000000000000& E-74
+ }
+ -result {}
+}
+test util-13.20 {just under exact - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1d1c26db7d0dae E+651 +16_999999999999999999& E+195
+ }
+ -result {}
+}
+test util-13.21 {just under exact - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -13f7ced916872b E-5 -38_999999999999999999& E-3
+ }
+ -result {}
+}
+test util-13.22 {just over exact - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 17d93193f78fc6 E+588 +151_0000000000000000000& E+175
+ }
+ -result {}
+}
+test util-13.23 {just over exact - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1a82a1631eeb30 E-625 -119_000000000000000000& E-190
+ }
+ -result {}
+}
+test util-13.24 {just under exact - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -16c309024bab4b E+290 -282_999999999999999999& E+85
+ }
+ -result {}
+}
+test util-13.25 {just over exact - 8 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1dbbac6f83a821 E-800 +27869147_0000000000000000000& E-248
+ }
+ -result {}
+}
+test util-13.26 {just under exact - 9 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1c569e968e0944 E+430 -491080653_9999999999999999999& E+121
+ }
+ -result {}
+}
+test util-13.27 {just under exact - 9 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1c569e968e0944 E+429 +245540326_9999999999999999999& E+121
+ }
+ -result {}
+}
+test util-13.28 {just over exact - 10 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1fc575867314ee E-330 -9078555839_0000000000000000000& E-109
+ }
+ -result {}
+}
+test util-13.29 {just under exact - 10 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1c569e968e0944 E+428 -1227701634_9999999999999999999& E+120
+ }
+ -result {}
+}
+test util-13.30 {just over exact - 11 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1fc575867314ee E-329 +18157111678_0000000000000000000& E-109
+ }
+ -result {}
+}
+test util-13.31 {just over exact - 14 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -18bf7e7fa6f02a E-196 -15400733123779_0000000000000000000& E-72
+ }
+ -result {}
+}
+test util-13.32 {just over exact - 17 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -13de005bd620df E+217 -26153245263757307_0000000000000000000& E+49
+ }
+ -result {}
+}
+test util-13.33 {just over exact - 18 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1f92bacb3cb40c E+718 +272104041512242479_0000000000000000000& E+199
+ }
+ -result {}
+}
+test util-13.34 {just over exact - 18 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1f92bacb3cb40c E+719 -544208083024484958_0000000000000000000& E+199
+ }
+ -result {}
+}
+test util-13.35 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 142dbf25096cf5 E+148 +4_500000000000000000& E+44
+ }
+ -result {}
+}
+test util-13.36 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1afcef51f0fb5f E+263 -2_500000000000000000& E+79
+ }
+ -result {}
+}
+test util-13.37 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 102498ea6df0c4 E+145 +4_500000000000000000& E+43
+ }
+ -result {}
+}
+test util-13.38 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1754e31cd072da E+1004 -2_500000000000000000& E+302
+ }
+ -result {}
+}
+test util-13.39 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 12deac01e2b4f7 E-557 +2_50000000000000000& E-168
+ }
+ -result {}
+}
+test util-13.40 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1b1df536c13eee E-307 -6_50000000000000000& E-93
+ }
+ -result {}
+}
+test util-13.41 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 10711fed5b19a4 E-154 +4_50000000000000000& E-47
+ }
+ -result {}
+}
+test util-13.42 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -148d67e8b1e00d E-151 -4_50000000000000000& E-46
+ }
+ -result {}
+}
+test util-13.43 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1c8c574c0c6be7 E+187 +3_49999999999999999& E+56
+ }
+ -result {}
+}
+test util-13.44 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1756183c147514 E+206 -1_49999999999999999& E+62
+ }
+ -result {}
+}
+test util-13.45 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 12ab469676c410 E+203 +1_49999999999999999& E+61
+ }
+ -result {}
+}
+test util-13.46 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1539684e774b48 E+246 -1_49999999999999999& E+74
+ }
+ -result {}
+}
+test util-13.47 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 12e5f5dfa4fe9d E-286 +9_499999999999999999& E-87
+ }
+ -result {}
+}
+test util-13.48 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1bdc2417bf7787 E-838 -9_499999999999999999& E-253
+ }
+ -result {}
+}
+test util-13.49 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1eb8e84fa0b278 E-1009 +3_499999999999999999& E-304
+ }
+ -result {}
+}
+test util-13.50 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1e3cbc9907fdc8 E-290 -9_499999999999999999& E-88
+ }
+ -result {}
+}
+test util-13.51 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 10ad836f269a17 E-324 +30_500000000000000000& E-99
+ }
+ -result {}
+}
+test util-13.52 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1b39ae1909c31b E-687 -26_500000000000000000& E-208
+ }
+ -result {}
+}
+test util-13.53 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1b2ab18615fcc6 E-576 +686_500000000000000000& E-176
+ }
+ -result {}
+}
+test util-13.54 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -13e1f90a573064 E-624 -178_500000000000000000& E-190
+ }
+ -result {}
+}
+test util-13.55 {just under half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 16c309024bab4b E+289 +141_499999999999999999& E+85
+ }
+ -result {}
+}
+test util-13.56 {just under half ulp - 4 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -159bd3ad46e346 E+193 -1695_499999999999999999& E+55
+ }
+ -result {}
+}
+test util-13.57 {just under half ulp - 4 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1df4170f0fdecc E+124 +3981_499999999999999999& E+34
+ }
+ -result {}
+}
+test util-13.58 {just over half ulp - 6 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 17e1e0f1c7a4ac E+415 +126300_5000000000000000000& E+120
+ }
+ -result {}
+}
+test util-13.59 {just over half ulp - 6 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1dda592e398dd7 E+418 -126300_5000000000000000000& E+121
+ }
+ -result {}
+}
+test util-13.60 {just under half ulp - 7 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1e597c0b94b7ae E+453 -4411845_499999999999999999& E+130
+ }
+ -result {}
+}
+test util-13.61 {just under half ulp - 9 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1c569e968e0944 E+427 +613850817_4999999999999999999& E+120
+ }
+ -result {}
+}
+test util-13.62 {just under half ulp - 9 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1c569e968e0944 E+428 -122770163_49999999999999999999& E+121
+ }
+ -result {}
+}
+test util-13.63 {just over half ulp - 18 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 17ae0c186d8709 E+719 +408156062268363718_5000000000000000000& E+199
+ }
+ -result {}
+}
+test util-13.64 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 152d02c7e14af7 E+76 +1_0000000000000000& E+23
+ }
+ -result {}
+}
+test util-13.65 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -19d971e4fe8402 E+89 -1_0000000000000000& E+27
+ }
+ -result {}
+}
+test util-13.66 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 19d971e4fe8402 E+90 +2_0000000000000000& E+27
+ }
+ -result {}
+}
+test util-13.67 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -19d971e4fe8402 E+91 -4_0000000000000000& E+27
+ }
+ -result {}
+}
+test util-13.68 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 15798ee2308c3a E-27 +1_0000000000000000& E-8
+ }
+ -result {}
+}
+test util-13.69 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -15798ee2308c3a E-26 -2_0000000000000000& E-8
+ }
+ -result {}
+}
+test util-13.70 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 15798ee2308c3a E-25 +4_0000000000000000& E-8
+ }
+ -result {}
+}
+test util-13.71 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1ef2d0f5da7dd9 E-84 -1_0000000000000000& E-25
+ }
+ -result {}
+}
+test util-13.72 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1a784379d99db4 E+78 +4_9999999999999999& E+23
+ }
+ -result {}
+}
+test util-13.73 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1a784379d99db4 E+80 -1_9999999999999999& E+24
+ }
+ -result {}
+}
+test util-13.74 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 13da329b633647 E+81 +2_9999999999999999& E+24
+ }
+ -result {}
+}
+test util-13.75 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1cf389cd46047d E+85 -6_9999999999999999& E+25
+ }
+ -result {}
+}
+test util-13.76 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 19999999999999 E-3 +1_99999999999999999& E-1
+ }
+ -result {}
+}
+test util-13.77 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -13333333333333 E-2 -2_99999999999999999& E-1
+ }
+ -result {}
+}
+test util-13.78 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 16849b86a12b9b E-48 +4_99999999999999999& E-15
+ }
+ -result {}
+}
+test util-13.79 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -16849b86a12b9b E-46 -1_99999999999999999& E-14
+ }
+ -result {}
+}
+test util-13.80 {just over exact - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 17ccfc73126788 E-71 +63_00000000000000000& E-23
+ }
+ -result {}
+}
+test util-13.81 {just over exact - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1dc03b8fd7016a E-68 -63_00000000000000000& E-22
+ }
+ -result {}
+}
+test util-13.82 {just under exact - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 13f7ced916872b E-5 +38_999999999999999999& E-3
+ }
+ -result {}
+}
+test util-13.83 {just over exact - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1b297cad9f70b6 E+97 +269_000000000000000000& E+27
+ }
+ -result {}
+}
+test util-13.84 {just over exact - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1b297cad9f70b6 E+98 -538_00000000000000000& E+27
+ }
+ -result {}
+}
+test util-13.85 {just over exact - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1cdc06b20ef183 E-82 +373_00000000000000000& E-27
+ }
+ -result {}
+}
+test util-13.86 {just over exact - 4 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1b297cad9f70b6 E+96 +1345_00000000000000000& E+26
+ }
+ -result {}
+}
+# this one is not 4 digits, it is 3, and it is covered above.
+test util-13.87 {just over exact - 4 digits} {*}{
+ -constraints {testdoubledigits knownBadTest}
+ -body {
+ verdonk_test -1b297cad9f70b6 E+97 -2690_00000000000000000& E+26
+ }
+ -result {}
+}
+test util-13.88 {just over exact - 5 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -150a246ecd44f3 E-63 -14257_00000000000000000& E-23
+ }
+ -result {}
+}
+test util-13.89 {just under exact - 6 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -119b96f36ec68b E-19 -209900_999999999999999999& E-11
+ }
+ -result {}
+}
+test util-13.90 {just over exact - 11 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1c06d366394441 E-35 +50980203373_000000000000000000& E-21
+ }
+ -result {}
+}
+test util-13.91 {just under exact - 12 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1f58ac4db68c90 E+122 -104166211810_99999999999999999& E+26
+ }
+ -result {}
+}
+test util-13.92 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 19d971e4fe8402 E+87 +2_5000000000000000& E+26
+ }
+ -result {}
+}
+test util-13.93 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1dc74be914d16b E+81 -4_500000000000000& E+24
+ }
+ -result {}
+}
+test util-13.94 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 14adf4b7320335 E+84 +2_500000000000000& E+25
+ }
+ -result {}
+}
+test util-13.95 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1ae22487c1042b E+85 -6_5000000000000000& E+25
+ }
+ -result {}
+}
+test util-13.96 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 187fe49aab41e0 E-54 +8_5000000000000000& E-17
+ }
+ -result {}
+}
+test util-13.97 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1f5c05e4b23fd7 E-61 -8_5000000000000000& E-19
+ }
+ -result {}
+}
+test util-13.98 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1faa7ab552a552 E-42 +4_5000000000000000& E-13
+ }
+ -result {}
+}
+test util-13.99 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1b7cdfd9d7bdbb E-36 -2_5000000000000000& E-11
+ }
+ -result {}
+}
+test util-13.100 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 13da329b633647 E+80 +1_4999999999999999& E+24
+ }
+ -result {}
+}
+test util-13.101 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1cf389cd46047d E+84 -3_49999999999999999& E+25
+ }
+ -result {}
+}
+test util-13.102 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1f04ef12cb04cf E+85 +7_4999999999999999& E+25
+ }
+ -result {}
+}
+test util-13.103 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1f04ef12cb04cf E+86 -1_4999999999999999& E+26
+ }
+ -result {}
+}
+test util-13.104 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 13333333333333 E-3 +1_49999999999999999& E-1
+ }
+ -result {}
+}
+test util-13.105 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -107e1fe91b0b70 E-36 -1_49999999999999999& E-11
+ }
+ -result {}
+}
+test util-13.106 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 149da7e361ce4c E-33 +1_49999999999999999& E-10
+ }
+ -result {}
+}
+test util-13.107 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -19c511dc3a41df E-30 -1_49999999999999999& E-9
+ }
+ -result {}
+}
+test util-13.108 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1aa83d74267822 E+93 -16_5000000000000000& E+27
+ }
+ -result {}
+}
+test util-13.109 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 18f1d5969453de E+89 +96_5000000000000000& E+25
+ }
+ -result {}
+}
+test util-13.110 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 11d9bd564dcda6 E-70 +94_50000000000000000& E-23
+ }
+ -result {}
+}
+test util-13.111 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1a58973ecbede6 E-48 -58_50000000000000000& E-16
+ }
+ -result {}
+}
+test util-13.112 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1b297cad9f70b6 E+95 +672_50000000000000000& E+26
+ }
+ -result {}
+}
+test util-13.113 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1b297cad9f70b6 E+96 -134_500000000000000000& E+27
+ }
+ -result {}
+}
+test util-13.114 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1cdc06b20ef183 E-83 +186_50000000000000000& E-27
+ }
+ -result {}
+}
+test util-13.115 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -136071dcae4565 E-47 -860_50000000000000000& E-17
+ }
+ -result {}
+}
+test util-13.116 {just over half ulp - 6 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1cb968d297dde8 E+99 +113788_50000000000000000& E+25
+ }
+ -result {}
+}
+test util-13.117 {just over half ulp - 6 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -11f3e1839eeab1 E+103 -113788_50000000000000000& E+26
+ }
+ -result {}
+}
+test util-13.118 {just under half ulp - 9 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1e9cec176c96f8 E+117 +317903333_49999999999999999& E+27
+ }
+ -result {}
+}
+test util-13.119 {just over half ulp - 11 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1c06d366394441 E-36 +25490101686_500000000000000000& E-21
+ }
+ -result {}
+}
+test util-13.120 {just under half ulp - 11 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1f58ac4db68c90 E+121 +52083105905_49999999999999999& E+26
+ }
+ -result {}
+}
+
+test util-14.1 {funky NaN} {*}{
+ -constraints {ieeeFloatingPoint controversialNaN}
+ -body {
+ set ieeeValues(-NaN)
+ }
+ -result -NaN
+}
+
+test util-14.2 {funky NaN} {*}{
+ -constraints {ieeeFloatingPoint controversialNaN}
+ -body {
+ set ieeeValues(-NaN(3456789abcdef))
+ }
+ -result -NaN(3456789abcdef)
+}
+
+test util-15.1 {largest subnormal} {*}{
+ -body {
+ binary scan [binary format w 0x000fffffffffffff] q x
+ set x
+ }
+ -result 2.225073858507201e-308
+ -cleanup {
+ unset x
+ }
+}
+
+test util-15.2 {largest subnormal} {*}{
+ -body {
+ binary scan [binary format w 0x800fffffffffffff] q x
+ set x
+ }
+ -result -2.225073858507201e-308
+ -cleanup {
+ unset x
+ }
+}
+
+test util-15.3 {largest subnormal} {*}{
+ -body {
+ binary scan [binary format q 2.225073858507201e-308] w x
+ format %#lx $x
+ }
+ -result 0xfffffffffffff
+ -cleanup {
+ unset x
+ }
+}
+
+test util-15.4 {largest subnormal} {*}{
+ -body {
+ binary scan [binary format q -2.225073858507201e-308] w x
+ format %#lx $x
+ }
+ -result 0x800fffffffffffff
+ -cleanup {
+ unset x
+ }
+}
+
+test util-15.5 {smallest normal} {*}{
+ -body {
+ binary scan [binary format w 0x0010000000000000] q x
+ set x
+ }
+ -result 2.2250738585072014e-308
+ -cleanup {
+ unset x
+ }
+}
+
+test util-15.6 {smallest normal} {*}{
+ -body {
+ binary scan [binary format w 0x8010000000000000] q x
+ set x
+ }
+ -result -2.2250738585072014e-308
+ -cleanup {
+ unset x
+ }
+}
+
+test util-15.7 {smallest normal} {*}{
+ -body {
+ binary scan [binary format q 2.2250738585072014e-308] w x
+ format %#lx $x
+ }
+ -result 0x10000000000000
+ -cleanup {
+ unset x
+ }
+}
+
+test util-15.8 {smallest normal} {*}{
+ -body {
+ binary scan [binary format q -2.2250738585072014e-308] w x
+ format %#lx $x
+ }
+ -result 0x8010000000000000
+ -cleanup {
+ unset x
+ }
+}
+
+set saved_precision $::tcl_precision
+foreach ::tcl_precision {0 12} {
+ for {set e -312} {$e < -9} {incr e} {
+ test util-16.1.$::tcl_precision.$e {shortening of numbers} \
+ "expr 1.1e$e" 1.1e$e
+ }
+}
+set tcl_precision 0
+for {set e -9} {$e < -4} {incr e} {
+ test util-16.1.$::tcl_precision.$e {shortening of numbers} \
+ "expr 1.1e$e" 1.1e$e
+}
+set tcl_precision 12
+for {set e -9} {$e < -4} {incr e} {
+ test util-16.1.$::tcl_precision.$e {8.4 compatible formatting of doubles} \
+ "expr 1.1e$e" 1.1e[format %+03d $e]
+}
+foreach ::tcl_precision {0 12} {
+ test util-16.1.$::tcl_precision.-4 {shortening of numbers} \
+ {expr 1.1e-4} \
+ 0.00011
+ test util-16.1.$::tcl_precision.-3 {shortening of numbers} \
+ {expr 1.1e-3} \
+ 0.0011
+ test util-16.1.$::tcl_precision.-2 {shortening of numbers} \
+ {expr 1.1e-2} \
+ 0.011
+ test util-16.1.$::tcl_precision.-1 {shortening of numbers} \
+ {expr 1.1e-1} \
+ 0.11
+ test util-16.1.$::tcl_precision.0 {shortening of numbers} \
+ {expr 1.1} \
+ 1.1
+ for {set e 1} {$e < 17} {incr e} {
+ test util-16.1.$::tcl_precision.$e {shortening of numbers} \
+ "expr 11[string repeat 0 [expr {$e-1}]].0" \
+ 11[string repeat 0 [expr {$e-1}]].0
+ }
+ for {set e 17} {$e < 309} {incr e} {
+ test util-16.1.$::tcl_precision.$e {shortening of numbers} \
+ "expr 1.1e$e" 1.1e+$e
+ }
+}
+set tcl_precision 17
+test util-16.1.17.-300 {8.4 compatible formatting of doubles} \
+ {expr 1e-300} \
+ 1e-300
+test util-16.1.17.-299 {8.4 compatible formatting of doubles} \
+ {expr 1e-299} \
+ 9.9999999999999999e-300
+test util-16.1.17.-298 {8.4 compatible formatting of doubles} \
+ {expr 1e-298} \
+ 9.9999999999999991e-299
+test util-16.1.17.-297 {8.4 compatible formatting of doubles} \
+ {expr 1e-297} \
+ 1e-297
+test util-16.1.17.-296 {8.4 compatible formatting of doubles} \
+ {expr 1e-296} \
+ 1e-296
+test util-16.1.17.-295 {8.4 compatible formatting of doubles} \
+ {expr 1e-295} \
+ 1.0000000000000001e-295
+test util-16.1.17.-294 {8.4 compatible formatting of doubles} \
+ {expr 1e-294} \
+ 1e-294
+test util-16.1.17.-293 {8.4 compatible formatting of doubles} \
+ {expr 1e-293} \
+ 1.0000000000000001e-293
+test util-16.1.17.-292 {8.4 compatible formatting of doubles} \
+ {expr 1e-292} \
+ 1.0000000000000001e-292
+test util-16.1.17.-291 {8.4 compatible formatting of doubles} \
+ {expr 1e-291} \
+ 9.9999999999999996e-292
+test util-16.1.17.-290 {8.4 compatible formatting of doubles} \
+ {expr 1e-290} \
+ 1.0000000000000001e-290
+test util-16.1.17.-289 {8.4 compatible formatting of doubles} \
+ {expr 1e-289} \
+ 1e-289
+test util-16.1.17.-288 {8.4 compatible formatting of doubles} \
+ {expr 1e-288} \
+ 1.0000000000000001e-288
+test util-16.1.17.-287 {8.4 compatible formatting of doubles} \
+ {expr 1e-287} \
+ 1e-287
+test util-16.1.17.-286 {8.4 compatible formatting of doubles} \
+ {expr 1e-286} \
+ 1.0000000000000001e-286
+test util-16.1.17.-285 {8.4 compatible formatting of doubles} \
+ {expr 1e-285} \
+ 1.0000000000000001e-285
+test util-16.1.17.-284 {8.4 compatible formatting of doubles} \
+ {expr 1e-284} \
+ 1e-284
+test util-16.1.17.-283 {8.4 compatible formatting of doubles} \
+ {expr 1e-283} \
+ 9.9999999999999995e-284
+test util-16.1.17.-282 {8.4 compatible formatting of doubles} \
+ {expr 1e-282} \
+ 1e-282
+test util-16.1.17.-281 {8.4 compatible formatting of doubles} \
+ {expr 1e-281} \
+ 1e-281
+test util-16.1.17.-280 {8.4 compatible formatting of doubles} \
+ {expr 1e-280} \
+ 9.9999999999999996e-281
+test util-16.1.17.-279 {8.4 compatible formatting of doubles} \
+ {expr 1e-279} \
+ 1.0000000000000001e-279
+test util-16.1.17.-278 {8.4 compatible formatting of doubles} \
+ {expr 1e-278} \
+ 9.9999999999999994e-279
+test util-16.1.17.-277 {8.4 compatible formatting of doubles} \
+ {expr 1e-277} \
+ 9.9999999999999997e-278
+test util-16.1.17.-276 {8.4 compatible formatting of doubles} \
+ {expr 1e-276} \
+ 1.0000000000000001e-276
+test util-16.1.17.-275 {8.4 compatible formatting of doubles} \
+ {expr 1e-275} \
+ 9.9999999999999993e-276
+test util-16.1.17.-274 {8.4 compatible formatting of doubles} \
+ {expr 1e-274} \
+ 9.9999999999999997e-275
+test util-16.1.17.-273 {8.4 compatible formatting of doubles} \
+ {expr 1e-273} \
+ 1.0000000000000001e-273
+test util-16.1.17.-272 {8.4 compatible formatting of doubles} \
+ {expr 1e-272} \
+ 9.9999999999999993e-273
+test util-16.1.17.-271 {8.4 compatible formatting of doubles} \
+ {expr 1e-271} \
+ 9.9999999999999996e-272
+test util-16.1.17.-270 {8.4 compatible formatting of doubles} \
+ {expr 1e-270} \
+ 1e-270
+test util-16.1.17.-269 {8.4 compatible formatting of doubles} \
+ {expr 1e-269} \
+ 9.9999999999999996e-270
+test util-16.1.17.-268 {8.4 compatible formatting of doubles} \
+ {expr 1e-268} \
+ 9.9999999999999996e-269
+test util-16.1.17.-267 {8.4 compatible formatting of doubles} \
+ {expr 1e-267} \
+ 9.9999999999999998e-268
+test util-16.1.17.-266 {8.4 compatible formatting of doubles} \
+ {expr 1e-266} \
+ 9.9999999999999998e-267
+test util-16.1.17.-265 {8.4 compatible formatting of doubles} \
+ {expr 1e-265} \
+ 9.9999999999999998e-266
+test util-16.1.17.-264 {8.4 compatible formatting of doubles} \
+ {expr 1e-264} \
+ 1e-264
+test util-16.1.17.-263 {8.4 compatible formatting of doubles} \
+ {expr 1e-263} \
+ 1e-263
+test util-16.1.17.-262 {8.4 compatible formatting of doubles} \
+ {expr 1e-262} \
+ 1e-262
+test util-16.1.17.-261 {8.4 compatible formatting of doubles} \
+ {expr 1e-261} \
+ 9.9999999999999998e-262
+test util-16.1.17.-260 {8.4 compatible formatting of doubles} \
+ {expr 1e-260} \
+ 9.9999999999999996e-261
+test util-16.1.17.-259 {8.4 compatible formatting of doubles} \
+ {expr 1e-259} \
+ 1.0000000000000001e-259
+test util-16.1.17.-258 {8.4 compatible formatting of doubles} \
+ {expr 1e-258} \
+ 9.9999999999999995e-259
+test util-16.1.17.-257 {8.4 compatible formatting of doubles} \
+ {expr 1e-257} \
+ 9.9999999999999998e-258
+test util-16.1.17.-256 {8.4 compatible formatting of doubles} \
+ {expr 1e-256} \
+ 9.9999999999999998e-257
+test util-16.1.17.-255 {8.4 compatible formatting of doubles} \
+ {expr 1e-255} \
+ 1e-255
+test util-16.1.17.-254 {8.4 compatible formatting of doubles} \
+ {expr 1e-254} \
+ 9.9999999999999991e-255
+test util-16.1.17.-253 {8.4 compatible formatting of doubles} \
+ {expr 1e-253} \
+ 1.0000000000000001e-253
+test util-16.1.17.-252 {8.4 compatible formatting of doubles} \
+ {expr 1e-252} \
+ 9.9999999999999994e-253
+test util-16.1.17.-251 {8.4 compatible formatting of doubles} \
+ {expr 1e-251} \
+ 1e-251
+test util-16.1.17.-250 {8.4 compatible formatting of doubles} \
+ {expr 1e-250} \
+ 1.0000000000000001e-250
+test util-16.1.17.-249 {8.4 compatible formatting of doubles} \
+ {expr 1e-249} \
+ 1.0000000000000001e-249
+test util-16.1.17.-248 {8.4 compatible formatting of doubles} \
+ {expr 1e-248} \
+ 9.9999999999999998e-249
+test util-16.1.17.-247 {8.4 compatible formatting of doubles} \
+ {expr 1e-247} \
+ 1e-247
+test util-16.1.17.-246 {8.4 compatible formatting of doubles} \
+ {expr 1e-246} \
+ 9.9999999999999996e-247
+test util-16.1.17.-245 {8.4 compatible formatting of doubles} \
+ {expr 1e-245} \
+ 9.9999999999999993e-246
+test util-16.1.17.-244 {8.4 compatible formatting of doubles} \
+ {expr 1e-244} \
+ 9.9999999999999993e-245
+test util-16.1.17.-243 {8.4 compatible formatting of doubles} \
+ {expr 1e-243} \
+ 1e-243
+test util-16.1.17.-242 {8.4 compatible formatting of doubles} \
+ {expr 1e-242} \
+ 9.9999999999999997e-243
+test util-16.1.17.-241 {8.4 compatible formatting of doubles} \
+ {expr 1e-241} \
+ 9.9999999999999997e-242
+test util-16.1.17.-240 {8.4 compatible formatting of doubles} \
+ {expr 1e-240} \
+ 9.9999999999999997e-241
+test util-16.1.17.-239 {8.4 compatible formatting of doubles} \
+ {expr 1e-239} \
+ 1.0000000000000001e-239
+test util-16.1.17.-238 {8.4 compatible formatting of doubles} \
+ {expr 1e-238} \
+ 9.9999999999999999e-239
+test util-16.1.17.-237 {8.4 compatible formatting of doubles} \
+ {expr 1e-237} \
+ 9.9999999999999999e-238
+test util-16.1.17.-236 {8.4 compatible formatting of doubles} \
+ {expr 1e-236} \
+ 1e-236
+test util-16.1.17.-235 {8.4 compatible formatting of doubles} \
+ {expr 1e-235} \
+ 9.9999999999999996e-236
+test util-16.1.17.-234 {8.4 compatible formatting of doubles} \
+ {expr 1e-234} \
+ 9.9999999999999996e-235
+test util-16.1.17.-233 {8.4 compatible formatting of doubles} \
+ {expr 1e-233} \
+ 9.9999999999999996e-234
+test util-16.1.17.-232 {8.4 compatible formatting of doubles} \
+ {expr 1e-232} \
+ 1e-232
+test util-16.1.17.-231 {8.4 compatible formatting of doubles} \
+ {expr 1e-231} \
+ 9.9999999999999999e-232
+test util-16.1.17.-230 {8.4 compatible formatting of doubles} \
+ {expr 1e-230} \
+ 1e-230
+test util-16.1.17.-229 {8.4 compatible formatting of doubles} \
+ {expr 1e-229} \
+ 1.0000000000000001e-229
+test util-16.1.17.-228 {8.4 compatible formatting of doubles} \
+ {expr 1e-228} \
+ 1e-228
+test util-16.1.17.-227 {8.4 compatible formatting of doubles} \
+ {expr 1e-227} \
+ 9.9999999999999994e-228
+test util-16.1.17.-226 {8.4 compatible formatting of doubles} \
+ {expr 1e-226} \
+ 9.9999999999999992e-227
+test util-16.1.17.-225 {8.4 compatible formatting of doubles} \
+ {expr 1e-225} \
+ 9.9999999999999996e-226
+test util-16.1.17.-224 {8.4 compatible formatting of doubles} \
+ {expr 1e-224} \
+ 1e-224
+test util-16.1.17.-223 {8.4 compatible formatting of doubles} \
+ {expr 1e-223} \
+ 9.9999999999999997e-224
+test util-16.1.17.-222 {8.4 compatible formatting of doubles} \
+ {expr 1e-222} \
+ 1e-222
+test util-16.1.17.-221 {8.4 compatible formatting of doubles} \
+ {expr 1e-221} \
+ 1e-221
+test util-16.1.17.-220 {8.4 compatible formatting of doubles} \
+ {expr 1e-220} \
+ 9.9999999999999999e-221
+test util-16.1.17.-219 {8.4 compatible formatting of doubles} \
+ {expr 1e-219} \
+ 1e-219
+test util-16.1.17.-218 {8.4 compatible formatting of doubles} \
+ {expr 1e-218} \
+ 1e-218
+test util-16.1.17.-217 {8.4 compatible formatting of doubles} \
+ {expr 1e-217} \
+ 1.0000000000000001e-217
+test util-16.1.17.-216 {8.4 compatible formatting of doubles} \
+ {expr 1e-216} \
+ 1e-216
+test util-16.1.17.-215 {8.4 compatible formatting of doubles} \
+ {expr 1e-215} \
+ 1e-215
+test util-16.1.17.-214 {8.4 compatible formatting of doubles} \
+ {expr 1e-214} \
+ 9.9999999999999991e-215
+test util-16.1.17.-213 {8.4 compatible formatting of doubles} \
+ {expr 1e-213} \
+ 9.9999999999999995e-214
+test util-16.1.17.-212 {8.4 compatible formatting of doubles} \
+ {expr 1e-212} \
+ 9.9999999999999995e-213
+test util-16.1.17.-211 {8.4 compatible formatting of doubles} \
+ {expr 1e-211} \
+ 1.0000000000000001e-211
+test util-16.1.17.-210 {8.4 compatible formatting of doubles} \
+ {expr 1e-210} \
+ 1e-210
+test util-16.1.17.-209 {8.4 compatible formatting of doubles} \
+ {expr 1e-209} \
+ 1e-209
+test util-16.1.17.-208 {8.4 compatible formatting of doubles} \
+ {expr 1e-208} \
+ 1.0000000000000001e-208
+test util-16.1.17.-207 {8.4 compatible formatting of doubles} \
+ {expr 1e-207} \
+ 9.9999999999999993e-208
+test util-16.1.17.-206 {8.4 compatible formatting of doubles} \
+ {expr 1e-206} \
+ 1e-206
+test util-16.1.17.-205 {8.4 compatible formatting of doubles} \
+ {expr 1e-205} \
+ 1e-205
+test util-16.1.17.-204 {8.4 compatible formatting of doubles} \
+ {expr 1e-204} \
+ 1e-204
+test util-16.1.17.-203 {8.4 compatible formatting of doubles} \
+ {expr 1e-203} \
+ 1e-203
+test util-16.1.17.-202 {8.4 compatible formatting of doubles} \
+ {expr 1e-202} \
+ 1e-202
+test util-16.1.17.-201 {8.4 compatible formatting of doubles} \
+ {expr 1e-201} \
+ 9.9999999999999995e-202
+test util-16.1.17.-200 {8.4 compatible formatting of doubles} \
+ {expr 1e-200} \
+ 9.9999999999999998e-201
+test util-16.1.17.-199 {8.4 compatible formatting of doubles} \
+ {expr 1e-199} \
+ 9.9999999999999998e-200
+test util-16.1.17.-198 {8.4 compatible formatting of doubles} \
+ {expr 1e-198} \
+ 9.9999999999999991e-199
+test util-16.1.17.-197 {8.4 compatible formatting of doubles} \
+ {expr 1e-197} \
+ 9.9999999999999999e-198
+test util-16.1.17.-196 {8.4 compatible formatting of doubles} \
+ {expr 1e-196} \
+ 1e-196
+test util-16.1.17.-195 {8.4 compatible formatting of doubles} \
+ {expr 1e-195} \
+ 1.0000000000000001e-195
+test util-16.1.17.-194 {8.4 compatible formatting of doubles} \
+ {expr 1e-194} \
+ 1e-194
+test util-16.1.17.-193 {8.4 compatible formatting of doubles} \
+ {expr 1e-193} \
+ 1e-193
+test util-16.1.17.-192 {8.4 compatible formatting of doubles} \
+ {expr 1e-192} \
+ 1.0000000000000001e-192
+test util-16.1.17.-191 {8.4 compatible formatting of doubles} \
+ {expr 1e-191} \
+ 1e-191
+test util-16.1.17.-190 {8.4 compatible formatting of doubles} \
+ {expr 1e-190} \
+ 1e-190
+test util-16.1.17.-189 {8.4 compatible formatting of doubles} \
+ {expr 1e-189} \
+ 1.0000000000000001e-189
+test util-16.1.17.-188 {8.4 compatible formatting of doubles} \
+ {expr 1e-188} \
+ 9.9999999999999995e-189
+test util-16.1.17.-187 {8.4 compatible formatting of doubles} \
+ {expr 1e-187} \
+ 1e-187
+test util-16.1.17.-186 {8.4 compatible formatting of doubles} \
+ {expr 1e-186} \
+ 9.9999999999999991e-187
+test util-16.1.17.-185 {8.4 compatible formatting of doubles} \
+ {expr 1e-185} \
+ 9.9999999999999999e-186
+test util-16.1.17.-184 {8.4 compatible formatting of doubles} \
+ {expr 1e-184} \
+ 1.0000000000000001e-184
+test util-16.1.17.-183 {8.4 compatible formatting of doubles} \
+ {expr 1e-183} \
+ 1e-183
+test util-16.1.17.-182 {8.4 compatible formatting of doubles} \
+ {expr 1e-182} \
+ 1e-182
+test util-16.1.17.-181 {8.4 compatible formatting of doubles} \
+ {expr 1e-181} \
+ 1e-181
+test util-16.1.17.-180 {8.4 compatible formatting of doubles} \
+ {expr 1e-180} \
+ 1e-180
+test util-16.1.17.-179 {8.4 compatible formatting of doubles} \
+ {expr 1e-179} \
+ 1e-179
+test util-16.1.17.-178 {8.4 compatible formatting of doubles} \
+ {expr 1e-178} \
+ 9.9999999999999995e-179
+test util-16.1.17.-177 {8.4 compatible formatting of doubles} \
+ {expr 1e-177} \
+ 9.9999999999999995e-178
+test util-16.1.17.-176 {8.4 compatible formatting of doubles} \
+ {expr 1e-176} \
+ 1e-176
+test util-16.1.17.-175 {8.4 compatible formatting of doubles} \
+ {expr 1e-175} \
+ 1e-175
+test util-16.1.17.-174 {8.4 compatible formatting of doubles} \
+ {expr 1e-174} \
+ 1e-174
+test util-16.1.17.-173 {8.4 compatible formatting of doubles} \
+ {expr 1e-173} \
+ 1e-173
+test util-16.1.17.-172 {8.4 compatible formatting of doubles} \
+ {expr 1e-172} \
+ 1e-172
+test util-16.1.17.-171 {8.4 compatible formatting of doubles} \
+ {expr 1e-171} \
+ 9.9999999999999998e-172
+test util-16.1.17.-170 {8.4 compatible formatting of doubles} \
+ {expr 1e-170} \
+ 9.9999999999999998e-171
+test util-16.1.17.-169 {8.4 compatible formatting of doubles} \
+ {expr 1e-169} \
+ 1e-169
+test util-16.1.17.-168 {8.4 compatible formatting of doubles} \
+ {expr 1e-168} \
+ 1e-168
+test util-16.1.17.-167 {8.4 compatible formatting of doubles} \
+ {expr 1e-167} \
+ 1e-167
+test util-16.1.17.-166 {8.4 compatible formatting of doubles} \
+ {expr 1e-166} \
+ 1e-166
+test util-16.1.17.-165 {8.4 compatible formatting of doubles} \
+ {expr 1e-165} \
+ 1e-165
+test util-16.1.17.-164 {8.4 compatible formatting of doubles} \
+ {expr 1e-164} \
+ 9.9999999999999996e-165
+test util-16.1.17.-163 {8.4 compatible formatting of doubles} \
+ {expr 1e-163} \
+ 9.9999999999999992e-164
+test util-16.1.17.-162 {8.4 compatible formatting of doubles} \
+ {expr 1e-162} \
+ 9.9999999999999995e-163
+test util-16.1.17.-161 {8.4 compatible formatting of doubles} \
+ {expr 1e-161} \
+ 1e-161
+test util-16.1.17.-160 {8.4 compatible formatting of doubles} \
+ {expr 1e-160} \
+ 9.9999999999999999e-161
+test util-16.1.17.-159 {8.4 compatible formatting of doubles} \
+ {expr 1e-159} \
+ 9.9999999999999999e-160
+test util-16.1.17.-158 {8.4 compatible formatting of doubles} \
+ {expr 1e-158} \
+ 1.0000000000000001e-158
+test util-16.1.17.-157 {8.4 compatible formatting of doubles} \
+ {expr 1e-157} \
+ 9.9999999999999994e-158
+test util-16.1.17.-156 {8.4 compatible formatting of doubles} \
+ {expr 1e-156} \
+ 1e-156
+test util-16.1.17.-155 {8.4 compatible formatting of doubles} \
+ {expr 1e-155} \
+ 1e-155
+test util-16.1.17.-154 {8.4 compatible formatting of doubles} \
+ {expr 1e-154} \
+ 9.9999999999999997e-155
+test util-16.1.17.-153 {8.4 compatible formatting of doubles} \
+ {expr 1e-153} \
+ 1e-153
+test util-16.1.17.-152 {8.4 compatible formatting of doubles} \
+ {expr 1e-152} \
+ 1.0000000000000001e-152
+test util-16.1.17.-151 {8.4 compatible formatting of doubles} \
+ {expr 1e-151} \
+ 9.9999999999999994e-152
+test util-16.1.17.-150 {8.4 compatible formatting of doubles} \
+ {expr 1e-150} \
+ 1e-150
+test util-16.1.17.-149 {8.4 compatible formatting of doubles} \
+ {expr 1e-149} \
+ 9.9999999999999998e-150
+test util-16.1.17.-148 {8.4 compatible formatting of doubles} \
+ {expr 1e-148} \
+ 9.9999999999999994e-149
+test util-16.1.17.-147 {8.4 compatible formatting of doubles} \
+ {expr 1e-147} \
+ 9.9999999999999997e-148
+test util-16.1.17.-146 {8.4 compatible formatting of doubles} \
+ {expr 1e-146} \
+ 1e-146
+test util-16.1.17.-145 {8.4 compatible formatting of doubles} \
+ {expr 1e-145} \
+ 9.9999999999999991e-146
+test util-16.1.17.-144 {8.4 compatible formatting of doubles} \
+ {expr 1e-144} \
+ 9.9999999999999995e-145
+test util-16.1.17.-143 {8.4 compatible formatting of doubles} \
+ {expr 1e-143} \
+ 9.9999999999999995e-144
+test util-16.1.17.-142 {8.4 compatible formatting of doubles} \
+ {expr 1e-142} \
+ 1e-142
+test util-16.1.17.-141 {8.4 compatible formatting of doubles} \
+ {expr 1e-141} \
+ 1e-141
+test util-16.1.17.-140 {8.4 compatible formatting of doubles} \
+ {expr 1e-140} \
+ 9.9999999999999998e-141
+test util-16.1.17.-139 {8.4 compatible formatting of doubles} \
+ {expr 1e-139} \
+ 1e-139
+test util-16.1.17.-138 {8.4 compatible formatting of doubles} \
+ {expr 1e-138} \
+ 1.0000000000000001e-138
+test util-16.1.17.-137 {8.4 compatible formatting of doubles} \
+ {expr 1e-137} \
+ 9.9999999999999998e-138
+test util-16.1.17.-136 {8.4 compatible formatting of doubles} \
+ {expr 1e-136} \
+ 1e-136
+test util-16.1.17.-135 {8.4 compatible formatting of doubles} \
+ {expr 1e-135} \
+ 1e-135
+test util-16.1.17.-134 {8.4 compatible formatting of doubles} \
+ {expr 1e-134} \
+ 1e-134
+test util-16.1.17.-133 {8.4 compatible formatting of doubles} \
+ {expr 1e-133} \
+ 1.0000000000000001e-133
+test util-16.1.17.-132 {8.4 compatible formatting of doubles} \
+ {expr 1e-132} \
+ 9.9999999999999999e-133
+test util-16.1.17.-131 {8.4 compatible formatting of doubles} \
+ {expr 1e-131} \
+ 9.9999999999999999e-132
+test util-16.1.17.-130 {8.4 compatible formatting of doubles} \
+ {expr 1e-130} \
+ 1.0000000000000001e-130
+test util-16.1.17.-129 {8.4 compatible formatting of doubles} \
+ {expr 1e-129} \
+ 9.9999999999999993e-130
+test util-16.1.17.-128 {8.4 compatible formatting of doubles} \
+ {expr 1e-128} \
+ 1.0000000000000001e-128
+test util-16.1.17.-127 {8.4 compatible formatting of doubles} \
+ {expr 1e-127} \
+ 1e-127
+test util-16.1.17.-126 {8.4 compatible formatting of doubles} \
+ {expr 1e-126} \
+ 9.9999999999999995e-127
+test util-16.1.17.-125 {8.4 compatible formatting of doubles} \
+ {expr 1e-125} \
+ 1e-125
+test util-16.1.17.-124 {8.4 compatible formatting of doubles} \
+ {expr 1e-124} \
+ 9.9999999999999993e-125
+test util-16.1.17.-123 {8.4 compatible formatting of doubles} \
+ {expr 1e-123} \
+ 1.0000000000000001e-123
+test util-16.1.17.-122 {8.4 compatible formatting of doubles} \
+ {expr 1e-122} \
+ 1.0000000000000001e-122
+test util-16.1.17.-121 {8.4 compatible formatting of doubles} \
+ {expr 1e-121} \
+ 9.9999999999999998e-122
+test util-16.1.17.-120 {8.4 compatible formatting of doubles} \
+ {expr 1e-120} \
+ 9.9999999999999998e-121
+test util-16.1.17.-119 {8.4 compatible formatting of doubles} \
+ {expr 1e-119} \
+ 1e-119
+test util-16.1.17.-118 {8.4 compatible formatting of doubles} \
+ {expr 1e-118} \
+ 9.9999999999999999e-119
+test util-16.1.17.-117 {8.4 compatible formatting of doubles} \
+ {expr 1e-117} \
+ 1e-117
+test util-16.1.17.-116 {8.4 compatible formatting of doubles} \
+ {expr 1e-116} \
+ 9.9999999999999999e-117
+test util-16.1.17.-115 {8.4 compatible formatting of doubles} \
+ {expr 1e-115} \
+ 1.0000000000000001e-115
+test util-16.1.17.-114 {8.4 compatible formatting of doubles} \
+ {expr 1e-114} \
+ 1.0000000000000001e-114
+test util-16.1.17.-113 {8.4 compatible formatting of doubles} \
+ {expr 1e-113} \
+ 9.9999999999999998e-114
+test util-16.1.17.-112 {8.4 compatible formatting of doubles} \
+ {expr 1e-112} \
+ 9.9999999999999995e-113
+test util-16.1.17.-111 {8.4 compatible formatting of doubles} \
+ {expr 1e-111} \
+ 1.0000000000000001e-111
+test util-16.1.17.-110 {8.4 compatible formatting of doubles} \
+ {expr 1e-110} \
+ 1.0000000000000001e-110
+test util-16.1.17.-109 {8.4 compatible formatting of doubles} \
+ {expr 1e-109} \
+ 9.9999999999999999e-110
+test util-16.1.17.-108 {8.4 compatible formatting of doubles} \
+ {expr 1e-108} \
+ 1e-108
+test util-16.1.17.-107 {8.4 compatible formatting of doubles} \
+ {expr 1e-107} \
+ 1e-107
+test util-16.1.17.-106 {8.4 compatible formatting of doubles} \
+ {expr 1e-106} \
+ 9.9999999999999994e-107
+test util-16.1.17.-105 {8.4 compatible formatting of doubles} \
+ {expr 1e-105} \
+ 9.9999999999999997e-106
+test util-16.1.17.-104 {8.4 compatible formatting of doubles} \
+ {expr 1e-104} \
+ 9.9999999999999993e-105
+test util-16.1.17.-103 {8.4 compatible formatting of doubles} \
+ {expr 1e-103} \
+ 9.9999999999999996e-104
+test util-16.1.17.-102 {8.4 compatible formatting of doubles} \
+ {expr 1e-102} \
+ 9.9999999999999993e-103
+test util-16.1.17.-101 {8.4 compatible formatting of doubles} \
+ {expr 1e-101} \
+ 1.0000000000000001e-101
+test util-16.1.17.-100 {8.4 compatible formatting of doubles} \
+ {expr 1e-100} \
+ 1e-100
+test util-16.1.17.-99 {8.4 compatible formatting of doubles} \
+ {expr 1e-99} \
+ 1e-99
+test util-16.1.17.-98 {8.4 compatible formatting of doubles} \
+ {expr 1e-98} \
+ 9.9999999999999994e-99
+test util-16.1.17.-97 {8.4 compatible formatting of doubles} \
+ {expr 1e-97} \
+ 1e-97
+test util-16.1.17.-96 {8.4 compatible formatting of doubles} \
+ {expr 1e-96} \
+ 9.9999999999999991e-97
+test util-16.1.17.-95 {8.4 compatible formatting of doubles} \
+ {expr 1e-95} \
+ 9.9999999999999999e-96
+test util-16.1.17.-94 {8.4 compatible formatting of doubles} \
+ {expr 1e-94} \
+ 9.9999999999999996e-95
+test util-16.1.17.-93 {8.4 compatible formatting of doubles} \
+ {expr 1e-93} \
+ 9.999999999999999e-94
+test util-16.1.17.-92 {8.4 compatible formatting of doubles} \
+ {expr 1e-92} \
+ 9.9999999999999999e-93
+test util-16.1.17.-91 {8.4 compatible formatting of doubles} \
+ {expr 1e-91} \
+ 1e-91
+test util-16.1.17.-90 {8.4 compatible formatting of doubles} \
+ {expr 1e-90} \
+ 9.9999999999999999e-91
+test util-16.1.17.-89 {8.4 compatible formatting of doubles} \
+ {expr 1e-89} \
+ 1e-89
+test util-16.1.17.-88 {8.4 compatible formatting of doubles} \
+ {expr 1e-88} \
+ 9.9999999999999993e-89
+test util-16.1.17.-87 {8.4 compatible formatting of doubles} \
+ {expr 1e-87} \
+ 1e-87
+test util-16.1.17.-86 {8.4 compatible formatting of doubles} \
+ {expr 1e-86} \
+ 1.0000000000000001e-86
+test util-16.1.17.-85 {8.4 compatible formatting of doubles} \
+ {expr 1e-85} \
+ 9.9999999999999998e-86
+test util-16.1.17.-84 {8.4 compatible formatting of doubles} \
+ {expr 1e-84} \
+ 1e-84
+test util-16.1.17.-83 {8.4 compatible formatting of doubles} \
+ {expr 1e-83} \
+ 1e-83
+test util-16.1.17.-82 {8.4 compatible formatting of doubles} \
+ {expr 1e-82} \
+ 9.9999999999999996e-83
+test util-16.1.17.-81 {8.4 compatible formatting of doubles} \
+ {expr 1e-81} \
+ 9.9999999999999996e-82
+test util-16.1.17.-80 {8.4 compatible formatting of doubles} \
+ {expr 1e-80} \
+ 9.9999999999999996e-81
+test util-16.1.17.-79 {8.4 compatible formatting of doubles} \
+ {expr 1e-79} \
+ 1e-79
+test util-16.1.17.-78 {8.4 compatible formatting of doubles} \
+ {expr 1e-78} \
+ 1e-78
+test util-16.1.17.-77 {8.4 compatible formatting of doubles} \
+ {expr 1e-77} \
+ 9.9999999999999993e-78
+test util-16.1.17.-76 {8.4 compatible formatting of doubles} \
+ {expr 1e-76} \
+ 9.9999999999999993e-77
+test util-16.1.17.-75 {8.4 compatible formatting of doubles} \
+ {expr 1e-75} \
+ 9.9999999999999996e-76
+test util-16.1.17.-74 {8.4 compatible formatting of doubles} \
+ {expr 1e-74} \
+ 9.9999999999999996e-75
+test util-16.1.17.-73 {8.4 compatible formatting of doubles} \
+ {expr 1e-73} \
+ 1e-73
+test util-16.1.17.-72 {8.4 compatible formatting of doubles} \
+ {expr 1e-72} \
+ 9.9999999999999997e-73
+test util-16.1.17.-71 {8.4 compatible formatting of doubles} \
+ {expr 1e-71} \
+ 9.9999999999999992e-72
+test util-16.1.17.-70 {8.4 compatible formatting of doubles} \
+ {expr 1e-70} \
+ 1e-70
+test util-16.1.17.-69 {8.4 compatible formatting of doubles} \
+ {expr 1e-69} \
+ 9.9999999999999996e-70
+test util-16.1.17.-68 {8.4 compatible formatting of doubles} \
+ {expr 1e-68} \
+ 1.0000000000000001e-68
+test util-16.1.17.-67 {8.4 compatible formatting of doubles} \
+ {expr 1e-67} \
+ 9.9999999999999994e-68
+test util-16.1.17.-66 {8.4 compatible formatting of doubles} \
+ {expr 1e-66} \
+ 9.9999999999999998e-67
+test util-16.1.17.-65 {8.4 compatible formatting of doubles} \
+ {expr 1e-65} \
+ 9.9999999999999992e-66
+test util-16.1.17.-64 {8.4 compatible formatting of doubles} \
+ {expr 1e-64} \
+ 9.9999999999999997e-65
+test util-16.1.17.-63 {8.4 compatible formatting of doubles} \
+ {expr 1e-63} \
+ 1.0000000000000001e-63
+test util-16.1.17.-62 {8.4 compatible formatting of doubles} \
+ {expr 1e-62} \
+ 1e-62
+test util-16.1.17.-61 {8.4 compatible formatting of doubles} \
+ {expr 1e-61} \
+ 1e-61
+test util-16.1.17.-60 {8.4 compatible formatting of doubles} \
+ {expr 1e-60} \
+ 9.9999999999999997e-61
+test util-16.1.17.-59 {8.4 compatible formatting of doubles} \
+ {expr 1e-59} \
+ 1e-59
+test util-16.1.17.-58 {8.4 compatible formatting of doubles} \
+ {expr 1e-58} \
+ 1e-58
+test util-16.1.17.-57 {8.4 compatible formatting of doubles} \
+ {expr 1e-57} \
+ 9.9999999999999995e-58
+test util-16.1.17.-56 {8.4 compatible formatting of doubles} \
+ {expr 1e-56} \
+ 1e-56
+test util-16.1.17.-55 {8.4 compatible formatting of doubles} \
+ {expr 1e-55} \
+ 9.9999999999999999e-56
+test util-16.1.17.-54 {8.4 compatible formatting of doubles} \
+ {expr 1e-54} \
+ 1e-54
+test util-16.1.17.-53 {8.4 compatible formatting of doubles} \
+ {expr 1e-53} \
+ 1e-53
+test util-16.1.17.-52 {8.4 compatible formatting of doubles} \
+ {expr 1e-52} \
+ 1e-52
+test util-16.1.17.-51 {8.4 compatible formatting of doubles} \
+ {expr 1e-51} \
+ 1e-51
+test util-16.1.17.-50 {8.4 compatible formatting of doubles} \
+ {expr 1e-50} \
+ 1e-50
+test util-16.1.17.-49 {8.4 compatible formatting of doubles} \
+ {expr 1e-49} \
+ 9.9999999999999994e-50
+test util-16.1.17.-48 {8.4 compatible formatting of doubles} \
+ {expr 1e-48} \
+ 9.9999999999999997e-49
+test util-16.1.17.-47 {8.4 compatible formatting of doubles} \
+ {expr 1e-47} \
+ 9.9999999999999997e-48
+test util-16.1.17.-46 {8.4 compatible formatting of doubles} \
+ {expr 1e-46} \
+ 1e-46
+test util-16.1.17.-45 {8.4 compatible formatting of doubles} \
+ {expr 1e-45} \
+ 9.9999999999999998e-46
+test util-16.1.17.-44 {8.4 compatible formatting of doubles} \
+ {expr 1e-44} \
+ 9.9999999999999995e-45
+test util-16.1.17.-43 {8.4 compatible formatting of doubles} \
+ {expr 1e-43} \
+ 1.0000000000000001e-43
+test util-16.1.17.-42 {8.4 compatible formatting of doubles} \
+ {expr 1e-42} \
+ 1e-42
+test util-16.1.17.-41 {8.4 compatible formatting of doubles} \
+ {expr 1e-41} \
+ 1e-41
+test util-16.1.17.-40 {8.4 compatible formatting of doubles} \
+ {expr 1e-40} \
+ 9.9999999999999993e-41
+test util-16.1.17.-39 {8.4 compatible formatting of doubles} \
+ {expr 1e-39} \
+ 9.9999999999999993e-40
+test util-16.1.17.-38 {8.4 compatible formatting of doubles} \
+ {expr 1e-38} \
+ 9.9999999999999996e-39
+test util-16.1.17.-37 {8.4 compatible formatting of doubles} \
+ {expr 1e-37} \
+ 1.0000000000000001e-37
+test util-16.1.17.-36 {8.4 compatible formatting of doubles} \
+ {expr 1e-36} \
+ 9.9999999999999994e-37
+test util-16.1.17.-35 {8.4 compatible formatting of doubles} \
+ {expr 1e-35} \
+ 1e-35
+test util-16.1.17.-34 {8.4 compatible formatting of doubles} \
+ {expr 1e-34} \
+ 9.9999999999999993e-35
+test util-16.1.17.-33 {8.4 compatible formatting of doubles} \
+ {expr 1e-33} \
+ 1.0000000000000001e-33
+test util-16.1.17.-32 {8.4 compatible formatting of doubles} \
+ {expr 1e-32} \
+ 1.0000000000000001e-32
+test util-16.1.17.-31 {8.4 compatible formatting of doubles} \
+ {expr 1e-31} \
+ 1.0000000000000001e-31
+test util-16.1.17.-30 {8.4 compatible formatting of doubles} \
+ {expr 1e-30} \
+ 1.0000000000000001e-30
+test util-16.1.17.-29 {8.4 compatible formatting of doubles} \
+ {expr 1e-29} \
+ 9.9999999999999994e-30
+test util-16.1.17.-28 {8.4 compatible formatting of doubles} \
+ {expr 1e-28} \
+ 9.9999999999999997e-29
+test util-16.1.17.-27 {8.4 compatible formatting of doubles} \
+ {expr 1e-27} \
+ 1e-27
+test util-16.1.17.-26 {8.4 compatible formatting of doubles} \
+ {expr 1e-26} \
+ 1e-26
+test util-16.1.17.-25 {8.4 compatible formatting of doubles} \
+ {expr 1e-25} \
+ 1e-25
+test util-16.1.17.-24 {8.4 compatible formatting of doubles} \
+ {expr 1e-24} \
+ 9.9999999999999992e-25
+test util-16.1.17.-23 {8.4 compatible formatting of doubles} \
+ {expr 1e-23} \
+ 9.9999999999999996e-24
+test util-16.1.17.-22 {8.4 compatible formatting of doubles} \
+ {expr 1e-22} \
+ 1e-22
+test util-16.1.17.-21 {8.4 compatible formatting of doubles} \
+ {expr 1e-21} \
+ 9.9999999999999991e-22
+test util-16.1.17.-20 {8.4 compatible formatting of doubles} \
+ {expr 1e-20} \
+ 9.9999999999999995e-21
+test util-16.1.17.-19 {8.4 compatible formatting of doubles} \
+ {expr 1e-19} \
+ 9.9999999999999998e-20
+test util-16.1.17.-18 {8.4 compatible formatting of doubles} \
+ {expr 1e-18} \
+ 1.0000000000000001e-18
+test util-16.1.17.-17 {8.4 compatible formatting of doubles} \
+ {expr 1e-17} \
+ 1.0000000000000001e-17
+test util-16.1.17.-16 {8.4 compatible formatting of doubles} \
+ {expr 1e-16} \
+ 9.9999999999999998e-17
+test util-16.1.17.-15 {8.4 compatible formatting of doubles} \
+ {expr 1e-15} \
+ 1.0000000000000001e-15
+test util-16.1.17.-14 {8.4 compatible formatting of doubles} \
+ {expr 1e-14} \
+ 1e-14
+test util-16.1.17.-13 {8.4 compatible formatting of doubles} \
+ {expr 1e-13} \
+ 1e-13
+test util-16.1.17.-12 {8.4 compatible formatting of doubles} \
+ {expr 1e-12} \
+ 9.9999999999999998e-13
+test util-16.1.17.-11 {8.4 compatible formatting of doubles} \
+ {expr 1e-11} \
+ 9.9999999999999994e-12
+test util-16.1.17.-10 {8.4 compatible formatting of doubles} \
+ {expr 1e-10} \
+ 1e-10
+test util-16.1.17.-9 {8.4 compatible formatting of doubles} \
+ {expr 1e-9} \
+ 1.0000000000000001e-09
+test util-16.1.17.-8 {8.4 compatible formatting of doubles} \
+ {expr 1e-8} \
+ 1e-08
+test util-16.1.17.-7 {8.4 compatible formatting of doubles} \
+ {expr 1e-7} \
+ 9.9999999999999995e-08
+test util-16.1.17.-6 {8.4 compatible formatting of doubles} \
+ {expr 1e-6} \
+ 9.9999999999999995e-07
+test util-16.1.17.-5 {8.4 compatible formatting of doubles} \
+ {expr 1e-5} \
+ 1.0000000000000001e-05
+test util-16.1.17.-4 {8.4 compatible formatting of doubles} \
+ {expr 1e-4} \
+ 0.0001
+test util-16.1.17.-3 {8.4 compatible formatting of doubles} \
+ {expr 1e-3} \
+ 0.001
+test util-16.1.17.-2 {8.4 compatible formatting of doubles} \
+ {expr 1e-2} \
+ 0.01
+test util-16.1.17.-1 {8.4 compatible formatting of doubles} \
+ {expr 1e-1} \
+ 0.10000000000000001
+test util-16.1.17.0 {8.4 compatible formatting of doubles} \
+ {expr 1e0} \
+ 1.0
+test util-16.1.17.1 {8.4 compatible formatting of doubles} \
+ {expr 1e1} \
+ 10.0
+test util-16.1.17.2 {8.4 compatible formatting of doubles} \
+ {expr 1e2} \
+ 100.0
+test util-16.1.17.3 {8.4 compatible formatting of doubles} \
+ {expr 1e3} \
+ 1000.0
+test util-16.1.17.4 {8.4 compatible formatting of doubles} \
+ {expr 1e4} \
+ 10000.0
+test util-16.1.17.5 {8.4 compatible formatting of doubles} \
+ {expr 1e5} \
+ 100000.0
+test util-16.1.17.6 {8.4 compatible formatting of doubles} \
+ {expr 1e6} \
+ 1000000.0
+test util-16.1.17.7 {8.4 compatible formatting of doubles} \
+ {expr 1e7} \
+ 10000000.0
+test util-16.1.17.8 {8.4 compatible formatting of doubles} \
+ {expr 1e8} \
+ 100000000.0
+test util-16.1.17.9 {8.4 compatible formatting of doubles} \
+ {expr 1e9} \
+ 1000000000.0
+test util-16.1.17.10 {8.4 compatible formatting of doubles} \
+ {expr 1e10} \
+ 10000000000.0
+test util-16.1.17.11 {8.4 compatible formatting of doubles} \
+ {expr 1e11} \
+ 100000000000.0
+test util-16.1.17.12 {8.4 compatible formatting of doubles} \
+ {expr 1e12} \
+ 1000000000000.0
+test util-16.1.17.13 {8.4 compatible formatting of doubles} \
+ {expr 1e13} \
+ 10000000000000.0
+test util-16.1.17.14 {8.4 compatible formatting of doubles} \
+ {expr 1e14} \
+ 100000000000000.0
+test util-16.1.17.15 {8.4 compatible formatting of doubles} \
+ {expr 1e15} \
+ 1000000000000000.0
+test util-16.1.17.16 {8.4 compatible formatting of doubles} \
+ {expr 1e16} \
+ 10000000000000000.0
+test util-16.1.17.17 {8.4 compatible formatting of doubles} \
+ {expr 1e17} \
+ 1e+17
+test util-16.1.17.18 {8.4 compatible formatting of doubles} \
+ {expr 1e18} \
+ 1e+18
+test util-16.1.17.19 {8.4 compatible formatting of doubles} \
+ {expr 1e19} \
+ 1e+19
+test util-16.1.17.20 {8.4 compatible formatting of doubles} \
+ {expr 1e20} \
+ 1e+20
+test util-16.1.17.21 {8.4 compatible formatting of doubles} \
+ {expr 1e21} \
+ 1e+21
+test util-16.1.17.22 {8.4 compatible formatting of doubles} \
+ {expr 1e22} \
+ 1e+22
+test util-16.1.17.23 {8.4 compatible formatting of doubles} \
+ {expr 1e23} \
+ 9.9999999999999992e+22
+test util-16.1.17.24 {8.4 compatible formatting of doubles} \
+ {expr 1e24} \
+ 9.9999999999999998e+23
+test util-16.1.17.25 {8.4 compatible formatting of doubles} \
+ {expr 1e25} \
+ 1.0000000000000001e+25
+test util-16.1.17.26 {8.4 compatible formatting of doubles} \
+ {expr 1e26} \
+ 1e+26
+test util-16.1.17.27 {8.4 compatible formatting of doubles} \
+ {expr 1e27} \
+ 1e+27
+test util-16.1.17.28 {8.4 compatible formatting of doubles} \
+ {expr 1e28} \
+ 9.9999999999999996e+27
+test util-16.1.17.29 {8.4 compatible formatting of doubles} \
+ {expr 1e29} \
+ 9.9999999999999991e+28
+test util-16.1.17.30 {8.4 compatible formatting of doubles} \
+ {expr 1e30} \
+ 1e+30
+test util-16.1.17.31 {8.4 compatible formatting of doubles} \
+ {expr 1e31} \
+ 9.9999999999999996e+30
+test util-16.1.17.32 {8.4 compatible formatting of doubles} \
+ {expr 1e32} \
+ 1.0000000000000001e+32
+test util-16.1.17.33 {8.4 compatible formatting of doubles} \
+ {expr 1e33} \
+ 9.9999999999999995e+32
+test util-16.1.17.34 {8.4 compatible formatting of doubles} \
+ {expr 1e34} \
+ 9.9999999999999995e+33
+test util-16.1.17.35 {8.4 compatible formatting of doubles} \
+ {expr 1e35} \
+ 9.9999999999999997e+34
+test util-16.1.17.36 {8.4 compatible formatting of doubles} \
+ {expr 1e36} \
+ 1e+36
+test util-16.1.17.37 {8.4 compatible formatting of doubles} \
+ {expr 1e37} \
+ 9.9999999999999995e+36
+test util-16.1.17.38 {8.4 compatible formatting of doubles} \
+ {expr 1e38} \
+ 9.9999999999999998e+37
+test util-16.1.17.39 {8.4 compatible formatting of doubles} \
+ {expr 1e39} \
+ 9.9999999999999994e+38
+test util-16.1.17.40 {8.4 compatible formatting of doubles} \
+ {expr 1e40} \
+ 1e+40
+test util-16.1.17.41 {8.4 compatible formatting of doubles} \
+ {expr 1e41} \
+ 1e+41
+test util-16.1.17.42 {8.4 compatible formatting of doubles} \
+ {expr 1e42} \
+ 1e+42
+test util-16.1.17.43 {8.4 compatible formatting of doubles} \
+ {expr 1e43} \
+ 1e+43
+test util-16.1.17.44 {8.4 compatible formatting of doubles} \
+ {expr 1e44} \
+ 1.0000000000000001e+44
+test util-16.1.17.45 {8.4 compatible formatting of doubles} \
+ {expr 1e45} \
+ 9.9999999999999993e+44
+test util-16.1.17.46 {8.4 compatible formatting of doubles} \
+ {expr 1e46} \
+ 9.9999999999999999e+45
+test util-16.1.17.47 {8.4 compatible formatting of doubles} \
+ {expr 1e47} \
+ 1e+47
+test util-16.1.17.48 {8.4 compatible formatting of doubles} \
+ {expr 1e48} \
+ 1e+48
+test util-16.1.17.49 {8.4 compatible formatting of doubles} \
+ {expr 1e49} \
+ 9.9999999999999995e+48
+test util-16.1.17.50 {8.4 compatible formatting of doubles} \
+ {expr 1e50} \
+ 1.0000000000000001e+50
+test util-16.1.17.51 {8.4 compatible formatting of doubles} \
+ {expr 1e51} \
+ 9.9999999999999999e+50
+test util-16.1.17.52 {8.4 compatible formatting of doubles} \
+ {expr 1e52} \
+ 9.9999999999999999e+51
+test util-16.1.17.53 {8.4 compatible formatting of doubles} \
+ {expr 1e53} \
+ 9.9999999999999999e+52
+test util-16.1.17.54 {8.4 compatible formatting of doubles} \
+ {expr 1e54} \
+ 1.0000000000000001e+54
+test util-16.1.17.55 {8.4 compatible formatting of doubles} \
+ {expr 1e55} \
+ 1e+55
+test util-16.1.17.56 {8.4 compatible formatting of doubles} \
+ {expr 1e56} \
+ 1.0000000000000001e+56
+test util-16.1.17.57 {8.4 compatible formatting of doubles} \
+ {expr 1e57} \
+ 1e+57
+test util-16.1.17.58 {8.4 compatible formatting of doubles} \
+ {expr 1e58} \
+ 9.9999999999999994e+57
+test util-16.1.17.59 {8.4 compatible formatting of doubles} \
+ {expr 1e59} \
+ 9.9999999999999997e+58
+test util-16.1.17.60 {8.4 compatible formatting of doubles} \
+ {expr 1e60} \
+ 9.9999999999999995e+59
+test util-16.1.17.61 {8.4 compatible formatting of doubles} \
+ {expr 1e61} \
+ 9.9999999999999995e+60
+test util-16.1.17.62 {8.4 compatible formatting of doubles} \
+ {expr 1e62} \
+ 1e+62
+test util-16.1.17.63 {8.4 compatible formatting of doubles} \
+ {expr 1e63} \
+ 1.0000000000000001e+63
+test util-16.1.17.64 {8.4 compatible formatting of doubles} \
+ {expr 1e64} \
+ 1e+64
+test util-16.1.17.65 {8.4 compatible formatting of doubles} \
+ {expr 1e65} \
+ 9.9999999999999999e+64
+test util-16.1.17.66 {8.4 compatible formatting of doubles} \
+ {expr 1e66} \
+ 9.9999999999999995e+65
+test util-16.1.17.67 {8.4 compatible formatting of doubles} \
+ {expr 1e67} \
+ 9.9999999999999998e+66
+test util-16.1.17.68 {8.4 compatible formatting of doubles} \
+ {expr 1e68} \
+ 9.9999999999999995e+67
+test util-16.1.17.69 {8.4 compatible formatting of doubles} \
+ {expr 1e69} \
+ 1.0000000000000001e+69
+test util-16.1.17.70 {8.4 compatible formatting of doubles} \
+ {expr 1e70} \
+ 1.0000000000000001e+70
+test util-16.1.17.71 {8.4 compatible formatting of doubles} \
+ {expr 1e71} \
+ 1e+71
+test util-16.1.17.72 {8.4 compatible formatting of doubles} \
+ {expr 1e72} \
+ 9.9999999999999994e+71
+test util-16.1.17.73 {8.4 compatible formatting of doubles} \
+ {expr 1e73} \
+ 9.9999999999999998e+72
+test util-16.1.17.74 {8.4 compatible formatting of doubles} \
+ {expr 1e74} \
+ 9.9999999999999995e+73
+test util-16.1.17.75 {8.4 compatible formatting of doubles} \
+ {expr 1e75} \
+ 9.9999999999999993e+74
+test util-16.1.17.76 {8.4 compatible formatting of doubles} \
+ {expr 1e76} \
+ 1e+76
+test util-16.1.17.77 {8.4 compatible formatting of doubles} \
+ {expr 1e77} \
+ 9.9999999999999998e+76
+test util-16.1.17.78 {8.4 compatible formatting of doubles} \
+ {expr 1e78} \
+ 1e+78
+test util-16.1.17.79 {8.4 compatible formatting of doubles} \
+ {expr 1e79} \
+ 9.9999999999999997e+78
+test util-16.1.17.80 {8.4 compatible formatting of doubles} \
+ {expr 1e80} \
+ 1e+80
+test util-16.1.17.81 {8.4 compatible formatting of doubles} \
+ {expr 1e81} \
+ 9.9999999999999992e+80
+test util-16.1.17.82 {8.4 compatible formatting of doubles} \
+ {expr 1e82} \
+ 9.9999999999999996e+81
+test util-16.1.17.83 {8.4 compatible formatting of doubles} \
+ {expr 1e83} \
+ 1e+83
+test util-16.1.17.84 {8.4 compatible formatting of doubles} \
+ {expr 1e84} \
+ 1.0000000000000001e+84
+test util-16.1.17.85 {8.4 compatible formatting of doubles} \
+ {expr 1e85} \
+ 1e+85
+test util-16.1.17.86 {8.4 compatible formatting of doubles} \
+ {expr 1e86} \
+ 1e+86
+test util-16.1.17.87 {8.4 compatible formatting of doubles} \
+ {expr 1e87} \
+ 9.9999999999999996e+86
+test util-16.1.17.88 {8.4 compatible formatting of doubles} \
+ {expr 1e88} \
+ 9.9999999999999996e+87
+test util-16.1.17.89 {8.4 compatible formatting of doubles} \
+ {expr 1e89} \
+ 9.9999999999999999e+88
+test util-16.1.17.90 {8.4 compatible formatting of doubles} \
+ {expr 1e90} \
+ 9.9999999999999997e+89
+test util-16.1.17.91 {8.4 compatible formatting of doubles} \
+ {expr 1e91} \
+ 1.0000000000000001e+91
+test util-16.1.17.92 {8.4 compatible formatting of doubles} \
+ {expr 1e92} \
+ 1e+92
+test util-16.1.17.93 {8.4 compatible formatting of doubles} \
+ {expr 1e93} \
+ 1e+93
+test util-16.1.17.94 {8.4 compatible formatting of doubles} \
+ {expr 1e94} \
+ 1e+94
+test util-16.1.17.95 {8.4 compatible formatting of doubles} \
+ {expr 1e95} \
+ 1e+95
+test util-16.1.17.96 {8.4 compatible formatting of doubles} \
+ {expr 1e96} \
+ 1e+96
+test util-16.1.17.97 {8.4 compatible formatting of doubles} \
+ {expr 1e97} \
+ 1.0000000000000001e+97
+test util-16.1.17.98 {8.4 compatible formatting of doubles} \
+ {expr 1e98} \
+ 1e+98
+test util-16.1.17.99 {8.4 compatible formatting of doubles} \
+ {expr 1e99} \
+ 9.9999999999999997e+98
+test util-16.1.17.100 {8.4 compatible formatting of doubles} \
+ {expr 1e100} \
+ 1e+100
+test util-16.1.17.101 {8.4 compatible formatting of doubles} \
+ {expr 1e101} \
+ 9.9999999999999998e+100
+test util-16.1.17.102 {8.4 compatible formatting of doubles} \
+ {expr 1e102} \
+ 9.9999999999999998e+101
+test util-16.1.17.103 {8.4 compatible formatting of doubles} \
+ {expr 1e103} \
+ 1e+103
+test util-16.1.17.104 {8.4 compatible formatting of doubles} \
+ {expr 1e104} \
+ 1e+104
+test util-16.1.17.105 {8.4 compatible formatting of doubles} \
+ {expr 1e105} \
+ 9.9999999999999994e+104
+test util-16.1.17.106 {8.4 compatible formatting of doubles} \
+ {expr 1e106} \
+ 1.0000000000000001e+106
+test util-16.1.17.107 {8.4 compatible formatting of doubles} \
+ {expr 1e107} \
+ 9.9999999999999997e+106
+test util-16.1.17.108 {8.4 compatible formatting of doubles} \
+ {expr 1e108} \
+ 1e+108
+test util-16.1.17.109 {8.4 compatible formatting of doubles} \
+ {expr 1e109} \
+ 9.9999999999999998e+108
+test util-16.1.17.110 {8.4 compatible formatting of doubles} \
+ {expr 1e110} \
+ 1e+110
+test util-16.1.17.111 {8.4 compatible formatting of doubles} \
+ {expr 1e111} \
+ 9.9999999999999996e+110
+test util-16.1.17.112 {8.4 compatible formatting of doubles} \
+ {expr 1e112} \
+ 9.9999999999999993e+111
+test util-16.1.17.113 {8.4 compatible formatting of doubles} \
+ {expr 1e113} \
+ 1e+113
+test util-16.1.17.114 {8.4 compatible formatting of doubles} \
+ {expr 1e114} \
+ 1e+114
+test util-16.1.17.115 {8.4 compatible formatting of doubles} \
+ {expr 1e115} \
+ 1e+115
+test util-16.1.17.116 {8.4 compatible formatting of doubles} \
+ {expr 1e116} \
+ 1e+116
+test util-16.1.17.117 {8.4 compatible formatting of doubles} \
+ {expr 1e117} \
+ 1.0000000000000001e+117
+test util-16.1.17.118 {8.4 compatible formatting of doubles} \
+ {expr 1e118} \
+ 9.9999999999999997e+117
+test util-16.1.17.119 {8.4 compatible formatting of doubles} \
+ {expr 1e119} \
+ 9.9999999999999994e+118
+test util-16.1.17.120 {8.4 compatible formatting of doubles} \
+ {expr 1e120} \
+ 9.9999999999999998e+119
+test util-16.1.17.121 {8.4 compatible formatting of doubles} \
+ {expr 1e121} \
+ 1e+121
+test util-16.1.17.122 {8.4 compatible formatting of doubles} \
+ {expr 1e122} \
+ 1e+122
+test util-16.1.17.123 {8.4 compatible formatting of doubles} \
+ {expr 1e123} \
+ 9.9999999999999998e+122
+test util-16.1.17.124 {8.4 compatible formatting of doubles} \
+ {expr 1e124} \
+ 9.9999999999999995e+123
+test util-16.1.17.125 {8.4 compatible formatting of doubles} \
+ {expr 1e125} \
+ 9.9999999999999992e+124
+test util-16.1.17.126 {8.4 compatible formatting of doubles} \
+ {expr 1e126} \
+ 9.9999999999999992e+125
+test util-16.1.17.127 {8.4 compatible formatting of doubles} \
+ {expr 1e127} \
+ 9.9999999999999995e+126
+test util-16.1.17.128 {8.4 compatible formatting of doubles} \
+ {expr 1e128} \
+ 1.0000000000000001e+128
+test util-16.1.17.129 {8.4 compatible formatting of doubles} \
+ {expr 1e129} \
+ 1e+129
+test util-16.1.17.130 {8.4 compatible formatting of doubles} \
+ {expr 1e130} \
+ 1.0000000000000001e+130
+test util-16.1.17.131 {8.4 compatible formatting of doubles} \
+ {expr 1e131} \
+ 9.9999999999999991e+130
+test util-16.1.17.132 {8.4 compatible formatting of doubles} \
+ {expr 1e132} \
+ 9.9999999999999999e+131
+test util-16.1.17.133 {8.4 compatible formatting of doubles} \
+ {expr 1e133} \
+ 1e+133
+test util-16.1.17.134 {8.4 compatible formatting of doubles} \
+ {expr 1e134} \
+ 9.9999999999999992e+133
+test util-16.1.17.135 {8.4 compatible formatting of doubles} \
+ {expr 1e135} \
+ 9.9999999999999996e+134
+test util-16.1.17.136 {8.4 compatible formatting of doubles} \
+ {expr 1e136} \
+ 1.0000000000000001e+136
+test util-16.1.17.137 {8.4 compatible formatting of doubles} \
+ {expr 1e137} \
+ 1e+137
+test util-16.1.17.138 {8.4 compatible formatting of doubles} \
+ {expr 1e138} \
+ 1e+138
+test util-16.1.17.139 {8.4 compatible formatting of doubles} \
+ {expr 1e139} \
+ 1e+139
+test util-16.1.17.140 {8.4 compatible formatting of doubles} \
+ {expr 1e140} \
+ 1.0000000000000001e+140
+test util-16.1.17.141 {8.4 compatible formatting of doubles} \
+ {expr 1e141} \
+ 1e+141
+test util-16.1.17.142 {8.4 compatible formatting of doubles} \
+ {expr 1e142} \
+ 1.0000000000000001e+142
+test util-16.1.17.143 {8.4 compatible formatting of doubles} \
+ {expr 1e143} \
+ 1e+143
+test util-16.1.17.144 {8.4 compatible formatting of doubles} \
+ {expr 1e144} \
+ 1e+144
+test util-16.1.17.145 {8.4 compatible formatting of doubles} \
+ {expr 1e145} \
+ 9.9999999999999999e+144
+test util-16.1.17.146 {8.4 compatible formatting of doubles} \
+ {expr 1e146} \
+ 9.9999999999999993e+145
+test util-16.1.17.147 {8.4 compatible formatting of doubles} \
+ {expr 1e147} \
+ 9.9999999999999998e+146
+test util-16.1.17.148 {8.4 compatible formatting of doubles} \
+ {expr 1e148} \
+ 1e+148
+test util-16.1.17.149 {8.4 compatible formatting of doubles} \
+ {expr 1e149} \
+ 1e+149
+test util-16.1.17.150 {8.4 compatible formatting of doubles} \
+ {expr 1e150} \
+ 9.9999999999999998e+149
+test util-16.1.17.151 {8.4 compatible formatting of doubles} \
+ {expr 1e151} \
+ 1e+151
+test util-16.1.17.152 {8.4 compatible formatting of doubles} \
+ {expr 1e152} \
+ 1e+152
+test util-16.1.17.153 {8.4 compatible formatting of doubles} \
+ {expr 1e153} \
+ 1e+153
+test util-16.1.17.154 {8.4 compatible formatting of doubles} \
+ {expr 1e154} \
+ 1e+154
+test util-16.1.17.155 {8.4 compatible formatting of doubles} \
+ {expr 1e155} \
+ 1e+155
+test util-16.1.17.156 {8.4 compatible formatting of doubles} \
+ {expr 1e156} \
+ 9.9999999999999998e+155
+test util-16.1.17.157 {8.4 compatible formatting of doubles} \
+ {expr 1e157} \
+ 9.9999999999999998e+156
+test util-16.1.17.158 {8.4 compatible formatting of doubles} \
+ {expr 1e158} \
+ 9.9999999999999995e+157
+test util-16.1.17.159 {8.4 compatible formatting of doubles} \
+ {expr 1e159} \
+ 9.9999999999999993e+158
+test util-16.1.17.160 {8.4 compatible formatting of doubles} \
+ {expr 1e160} \
+ 1e+160
+test util-16.1.17.161 {8.4 compatible formatting of doubles} \
+ {expr 1e161} \
+ 1e+161
+test util-16.1.17.162 {8.4 compatible formatting of doubles} \
+ {expr 1e162} \
+ 9.9999999999999994e+161
+test util-16.1.17.163 {8.4 compatible formatting of doubles} \
+ {expr 1e163} \
+ 9.9999999999999994e+162
+test util-16.1.17.164 {8.4 compatible formatting of doubles} \
+ {expr 1e164} \
+ 1e+164
+test util-16.1.17.165 {8.4 compatible formatting of doubles} \
+ {expr 1e165} \
+ 9.999999999999999e+164
+test util-16.1.17.166 {8.4 compatible formatting of doubles} \
+ {expr 1e166} \
+ 9.9999999999999994e+165
+test util-16.1.17.167 {8.4 compatible formatting of doubles} \
+ {expr 1e167} \
+ 1e+167
+test util-16.1.17.168 {8.4 compatible formatting of doubles} \
+ {expr 1e168} \
+ 9.9999999999999993e+167
+test util-16.1.17.169 {8.4 compatible formatting of doubles} \
+ {expr 1e169} \
+ 9.9999999999999993e+168
+test util-16.1.17.170 {8.4 compatible formatting of doubles} \
+ {expr 1e170} \
+ 1e+170
+test util-16.1.17.171 {8.4 compatible formatting of doubles} \
+ {expr 1e171} \
+ 9.9999999999999995e+170
+test util-16.1.17.172 {8.4 compatible formatting of doubles} \
+ {expr 1e172} \
+ 1.0000000000000001e+172
+test util-16.1.17.173 {8.4 compatible formatting of doubles} \
+ {expr 1e173} \
+ 1e+173
+test util-16.1.17.174 {8.4 compatible formatting of doubles} \
+ {expr 1e174} \
+ 1.0000000000000001e+174
+test util-16.1.17.175 {8.4 compatible formatting of doubles} \
+ {expr 1e175} \
+ 9.9999999999999994e+174
+test util-16.1.17.176 {8.4 compatible formatting of doubles} \
+ {expr 1e176} \
+ 1e+176
+test util-16.1.17.177 {8.4 compatible formatting of doubles} \
+ {expr 1e177} \
+ 1e+177
+test util-16.1.17.178 {8.4 compatible formatting of doubles} \
+ {expr 1e178} \
+ 1.0000000000000001e+178
+test util-16.1.17.179 {8.4 compatible formatting of doubles} \
+ {expr 1e179} \
+ 9.9999999999999998e+178
+test util-16.1.17.180 {8.4 compatible formatting of doubles} \
+ {expr 1e180} \
+ 1e+180
+test util-16.1.17.181 {8.4 compatible formatting of doubles} \
+ {expr 1e181} \
+ 9.9999999999999992e+180
+test util-16.1.17.182 {8.4 compatible formatting of doubles} \
+ {expr 1e182} \
+ 1.0000000000000001e+182
+test util-16.1.17.183 {8.4 compatible formatting of doubles} \
+ {expr 1e183} \
+ 9.9999999999999995e+182
+test util-16.1.17.184 {8.4 compatible formatting of doubles} \
+ {expr 1e184} \
+ 1e+184
+test util-16.1.17.185 {8.4 compatible formatting of doubles} \
+ {expr 1e185} \
+ 9.9999999999999998e+184
+test util-16.1.17.186 {8.4 compatible formatting of doubles} \
+ {expr 1e186} \
+ 9.9999999999999998e+185
+test util-16.1.17.187 {8.4 compatible formatting of doubles} \
+ {expr 1e187} \
+ 9.9999999999999991e+186
+test util-16.1.17.188 {8.4 compatible formatting of doubles} \
+ {expr 1e188} \
+ 1e+188
+test util-16.1.17.189 {8.4 compatible formatting of doubles} \
+ {expr 1e189} \
+ 1e+189
+test util-16.1.17.190 {8.4 compatible formatting of doubles} \
+ {expr 1e190} \
+ 1.0000000000000001e+190
+test util-16.1.17.191 {8.4 compatible formatting of doubles} \
+ {expr 1e191} \
+ 1.0000000000000001e+191
+test util-16.1.17.192 {8.4 compatible formatting of doubles} \
+ {expr 1e192} \
+ 1e+192
+test util-16.1.17.193 {8.4 compatible formatting of doubles} \
+ {expr 1e193} \
+ 1.0000000000000001e+193
+test util-16.1.17.194 {8.4 compatible formatting of doubles} \
+ {expr 1e194} \
+ 9.9999999999999994e+193
+test util-16.1.17.195 {8.4 compatible formatting of doubles} \
+ {expr 1e195} \
+ 9.9999999999999998e+194
+test util-16.1.17.196 {8.4 compatible formatting of doubles} \
+ {expr 1e196} \
+ 9.9999999999999995e+195
+test util-16.1.17.197 {8.4 compatible formatting of doubles} \
+ {expr 1e197} \
+ 9.9999999999999995e+196
+test util-16.1.17.198 {8.4 compatible formatting of doubles} \
+ {expr 1e198} \
+ 1e+198
+test util-16.1.17.199 {8.4 compatible formatting of doubles} \
+ {expr 1e199} \
+ 1.0000000000000001e+199
+test util-16.1.17.200 {8.4 compatible formatting of doubles} \
+ {expr 1e200} \
+ 9.9999999999999997e+199
+test util-16.1.17.201 {8.4 compatible formatting of doubles} \
+ {expr 1e201} \
+ 1e+201
+test util-16.1.17.202 {8.4 compatible formatting of doubles} \
+ {expr 1e202} \
+ 9.999999999999999e+201
+test util-16.1.17.203 {8.4 compatible formatting of doubles} \
+ {expr 1e203} \
+ 9.9999999999999999e+202
+test util-16.1.17.204 {8.4 compatible formatting of doubles} \
+ {expr 1e204} \
+ 9.9999999999999999e+203
+test util-16.1.17.205 {8.4 compatible formatting of doubles} \
+ {expr 1e205} \
+ 1e+205
+test util-16.1.17.206 {8.4 compatible formatting of doubles} \
+ {expr 1e206} \
+ 1e+206
+test util-16.1.17.207 {8.4 compatible formatting of doubles} \
+ {expr 1e207} \
+ 1e+207
+test util-16.1.17.208 {8.4 compatible formatting of doubles} \
+ {expr 1e208} \
+ 9.9999999999999998e+207
+test util-16.1.17.209 {8.4 compatible formatting of doubles} \
+ {expr 1e209} \
+ 1.0000000000000001e+209
+test util-16.1.17.210 {8.4 compatible formatting of doubles} \
+ {expr 1e210} \
+ 9.9999999999999993e+209
+test util-16.1.17.211 {8.4 compatible formatting of doubles} \
+ {expr 1e211} \
+ 9.9999999999999996e+210
+test util-16.1.17.212 {8.4 compatible formatting of doubles} \
+ {expr 1e212} \
+ 9.9999999999999991e+211
+test util-16.1.17.213 {8.4 compatible formatting of doubles} \
+ {expr 1e213} \
+ 9.9999999999999998e+212
+test util-16.1.17.214 {8.4 compatible formatting of doubles} \
+ {expr 1e214} \
+ 9.9999999999999995e+213
+test util-16.1.17.215 {8.4 compatible formatting of doubles} \
+ {expr 1e215} \
+ 9.9999999999999991e+214
+test util-16.1.17.216 {8.4 compatible formatting of doubles} \
+ {expr 1e216} \
+ 1e+216
+test util-16.1.17.217 {8.4 compatible formatting of doubles} \
+ {expr 1e217} \
+ 9.9999999999999996e+216
+test util-16.1.17.218 {8.4 compatible formatting of doubles} \
+ {expr 1e218} \
+ 1.0000000000000001e+218
+test util-16.1.17.219 {8.4 compatible formatting of doubles} \
+ {expr 1e219} \
+ 9.9999999999999997e+218
+test util-16.1.17.220 {8.4 compatible formatting of doubles} \
+ {expr 1e220} \
+ 1e+220
+test util-16.1.17.221 {8.4 compatible formatting of doubles} \
+ {expr 1e221} \
+ 1e+221
+test util-16.1.17.222 {8.4 compatible formatting of doubles} \
+ {expr 1e222} \
+ 1e+222
+test util-16.1.17.223 {8.4 compatible formatting of doubles} \
+ {expr 1e223} \
+ 1e+223
+test util-16.1.17.224 {8.4 compatible formatting of doubles} \
+ {expr 1e224} \
+ 9.9999999999999997e+223
+test util-16.1.17.225 {8.4 compatible formatting of doubles} \
+ {expr 1e225} \
+ 9.9999999999999993e+224
+test util-16.1.17.226 {8.4 compatible formatting of doubles} \
+ {expr 1e226} \
+ 9.9999999999999996e+225
+test util-16.1.17.227 {8.4 compatible formatting of doubles} \
+ {expr 1e227} \
+ 1.0000000000000001e+227
+test util-16.1.17.228 {8.4 compatible formatting of doubles} \
+ {expr 1e228} \
+ 9.9999999999999992e+227
+test util-16.1.17.229 {8.4 compatible formatting of doubles} \
+ {expr 1e229} \
+ 9.9999999999999999e+228
+test util-16.1.17.230 {8.4 compatible formatting of doubles} \
+ {expr 1e230} \
+ 1.0000000000000001e+230
+test util-16.1.17.231 {8.4 compatible formatting of doubles} \
+ {expr 1e231} \
+ 1.0000000000000001e+231
+test util-16.1.17.232 {8.4 compatible formatting of doubles} \
+ {expr 1e232} \
+ 1.0000000000000001e+232
+test util-16.1.17.233 {8.4 compatible formatting of doubles} \
+ {expr 1e233} \
+ 9.9999999999999997e+232
+test util-16.1.17.234 {8.4 compatible formatting of doubles} \
+ {expr 1e234} \
+ 1e+234
+test util-16.1.17.235 {8.4 compatible formatting of doubles} \
+ {expr 1e235} \
+ 1.0000000000000001e+235
+test util-16.1.17.236 {8.4 compatible formatting of doubles} \
+ {expr 1e236} \
+ 1.0000000000000001e+236
+test util-16.1.17.237 {8.4 compatible formatting of doubles} \
+ {expr 1e237} \
+ 9.9999999999999994e+236
+test util-16.1.17.238 {8.4 compatible formatting of doubles} \
+ {expr 1e238} \
+ 1e+238
+test util-16.1.17.239 {8.4 compatible formatting of doubles} \
+ {expr 1e239} \
+ 9.9999999999999999e+238
+test util-16.1.17.240 {8.4 compatible formatting of doubles} \
+ {expr 1e240} \
+ 1e+240
+test util-16.1.17.241 {8.4 compatible formatting of doubles} \
+ {expr 1e241} \
+ 1.0000000000000001e+241
+test util-16.1.17.242 {8.4 compatible formatting of doubles} \
+ {expr 1e242} \
+ 1.0000000000000001e+242
+test util-16.1.17.243 {8.4 compatible formatting of doubles} \
+ {expr 1e243} \
+ 1.0000000000000001e+243
+test util-16.1.17.244 {8.4 compatible formatting of doubles} \
+ {expr 1e244} \
+ 1.0000000000000001e+244
+test util-16.1.17.245 {8.4 compatible formatting of doubles} \
+ {expr 1e245} \
+ 1e+245
+test util-16.1.17.246 {8.4 compatible formatting of doubles} \
+ {expr 1e246} \
+ 1.0000000000000001e+246
+test util-16.1.17.247 {8.4 compatible formatting of doubles} \
+ {expr 1e247} \
+ 9.9999999999999995e+246
+test util-16.1.17.248 {8.4 compatible formatting of doubles} \
+ {expr 1e248} \
+ 1e+248
+test util-16.1.17.249 {8.4 compatible formatting of doubles} \
+ {expr 1e249} \
+ 9.9999999999999992e+248
+test util-16.1.17.250 {8.4 compatible formatting of doubles} \
+ {expr 1e250} \
+ 9.9999999999999992e+249
+test util-16.1.17.251 {8.4 compatible formatting of doubles} \
+ {expr 1e251} \
+ 1e+251
+test util-16.1.17.252 {8.4 compatible formatting of doubles} \
+ {expr 1e252} \
+ 1.0000000000000001e+252
+test util-16.1.17.253 {8.4 compatible formatting of doubles} \
+ {expr 1e253} \
+ 9.9999999999999994e+252
+test util-16.1.17.254 {8.4 compatible formatting of doubles} \
+ {expr 1e254} \
+ 9.9999999999999994e+253
+test util-16.1.17.255 {8.4 compatible formatting of doubles} \
+ {expr 1e255} \
+ 9.9999999999999999e+254
+test util-16.1.17.256 {8.4 compatible formatting of doubles} \
+ {expr 1e256} \
+ 1e+256
+test util-16.1.17.257 {8.4 compatible formatting of doubles} \
+ {expr 1e257} \
+ 1e+257
+test util-16.1.17.258 {8.4 compatible formatting of doubles} \
+ {expr 1e258} \
+ 1.0000000000000001e+258
+test util-16.1.17.259 {8.4 compatible formatting of doubles} \
+ {expr 1e259} \
+ 9.9999999999999993e+258
+test util-16.1.17.260 {8.4 compatible formatting of doubles} \
+ {expr 1e260} \
+ 1.0000000000000001e+260
+test util-16.1.17.261 {8.4 compatible formatting of doubles} \
+ {expr 1e261} \
+ 9.9999999999999993e+260
+test util-16.1.17.262 {8.4 compatible formatting of doubles} \
+ {expr 1e262} \
+ 1e+262
+test util-16.1.17.263 {8.4 compatible formatting of doubles} \
+ {expr 1e263} \
+ 1e+263
+test util-16.1.17.264 {8.4 compatible formatting of doubles} \
+ {expr 1e264} \
+ 1e+264
+test util-16.1.17.265 {8.4 compatible formatting of doubles} \
+ {expr 1e265} \
+ 1.0000000000000001e+265
+test util-16.1.17.266 {8.4 compatible formatting of doubles} \
+ {expr 1e266} \
+ 1e+266
+test util-16.1.17.267 {8.4 compatible formatting of doubles} \
+ {expr 1e267} \
+ 9.9999999999999997e+266
+test util-16.1.17.268 {8.4 compatible formatting of doubles} \
+ {expr 1e268} \
+ 9.9999999999999997e+267
+test util-16.1.17.269 {8.4 compatible formatting of doubles} \
+ {expr 1e269} \
+ 1e+269
+test util-16.1.17.270 {8.4 compatible formatting of doubles} \
+ {expr 1e270} \
+ 1e+270
+test util-16.1.17.271 {8.4 compatible formatting of doubles} \
+ {expr 1e271} \
+ 9.9999999999999995e+270
+test util-16.1.17.272 {8.4 compatible formatting of doubles} \
+ {expr 1e272} \
+ 1.0000000000000001e+272
+test util-16.1.17.273 {8.4 compatible formatting of doubles} \
+ {expr 1e273} \
+ 9.9999999999999995e+272
+test util-16.1.17.274 {8.4 compatible formatting of doubles} \
+ {expr 1e274} \
+ 9.9999999999999992e+273
+test util-16.1.17.275 {8.4 compatible formatting of doubles} \
+ {expr 1e275} \
+ 9.9999999999999996e+274
+test util-16.1.17.276 {8.4 compatible formatting of doubles} \
+ {expr 1e276} \
+ 1.0000000000000001e+276
+test util-16.1.17.277 {8.4 compatible formatting of doubles} \
+ {expr 1e277} \
+ 1e+277
+test util-16.1.17.278 {8.4 compatible formatting of doubles} \
+ {expr 1e278} \
+ 9.9999999999999996e+277
+test util-16.1.17.279 {8.4 compatible formatting of doubles} \
+ {expr 1e279} \
+ 1.0000000000000001e+279
+test util-16.1.17.280 {8.4 compatible formatting of doubles} \
+ {expr 1e280} \
+ 1e+280
+test util-16.1.17.281 {8.4 compatible formatting of doubles} \
+ {expr 1e281} \
+ 1e+281
+test util-16.1.17.282 {8.4 compatible formatting of doubles} \
+ {expr 1e282} \
+ 1e+282
+test util-16.1.17.283 {8.4 compatible formatting of doubles} \
+ {expr 1e283} \
+ 9.9999999999999996e+282
+test util-16.1.17.284 {8.4 compatible formatting of doubles} \
+ {expr 1e284} \
+ 1.0000000000000001e+284
+test util-16.1.17.285 {8.4 compatible formatting of doubles} \
+ {expr 1e285} \
+ 9.9999999999999998e+284
+test util-16.1.17.286 {8.4 compatible formatting of doubles} \
+ {expr 1e286} \
+ 1e+286
+test util-16.1.17.287 {8.4 compatible formatting of doubles} \
+ {expr 1e287} \
+ 1.0000000000000001e+287
+test util-16.1.17.288 {8.4 compatible formatting of doubles} \
+ {expr 1e288} \
+ 1e+288
+test util-16.1.17.289 {8.4 compatible formatting of doubles} \
+ {expr 1e289} \
+ 1.0000000000000001e+289
+test util-16.1.17.290 {8.4 compatible formatting of doubles} \
+ {expr 1e290} \
+ 1.0000000000000001e+290
+test util-16.1.17.291 {8.4 compatible formatting of doubles} \
+ {expr 1e291} \
+ 9.9999999999999996e+290
+test util-16.1.17.292 {8.4 compatible formatting of doubles} \
+ {expr 1e292} \
+ 1e+292
+test util-16.1.17.293 {8.4 compatible formatting of doubles} \
+ {expr 1e293} \
+ 9.9999999999999992e+292
+test util-16.1.17.294 {8.4 compatible formatting of doubles} \
+ {expr 1e294} \
+ 1.0000000000000001e+294
+test util-16.1.17.295 {8.4 compatible formatting of doubles} \
+ {expr 1e295} \
+ 9.9999999999999998e+294
+test util-16.1.17.296 {8.4 compatible formatting of doubles} \
+ {expr 1e296} \
+ 9.9999999999999998e+295
+test util-16.1.17.297 {8.4 compatible formatting of doubles} \
+ {expr 1e297} \
+ 1e+297
+test util-16.1.17.298 {8.4 compatible formatting of doubles} \
+ {expr 1e298} \
+ 9.9999999999999996e+297
+test util-16.1.17.299 {8.4 compatible formatting of doubles} \
+ {expr 1e299} \
+ 1.0000000000000001e+299
+test util-16.1.17.300 {8.4 compatible formatting of doubles} \
+ {expr 1e300} \
+ 1.0000000000000001e+300
+test util-16.1.17.301 {8.4 compatible formatting of doubles} \
+ {expr 1e301} \
+ 1.0000000000000001e+301
+test util-16.1.17.302 {8.4 compatible formatting of doubles} \
+ {expr 1e302} \
+ 1.0000000000000001e+302
+test util-16.1.17.303 {8.4 compatible formatting of doubles} \
+ {expr 1e303} \
+ 1e+303
+test util-16.1.17.304 {8.4 compatible formatting of doubles} \
+ {expr 1e304} \
+ 9.9999999999999994e+303
+test util-16.1.17.305 {8.4 compatible formatting of doubles} \
+ {expr 1e305} \
+ 9.9999999999999994e+304
+test util-16.1.17.306 {8.4 compatible formatting of doubles} \
+ {expr 1e306} \
+ 1e+306
+test util-16.1.17.307 {8.4 compatible formatting of doubles} \
+ {expr 1e307} \
+ 9.9999999999999999e+306
+
+test util-17.1 {bankers' rounding [Bug 3349507]} {ieeeFloatingPoint} {
+ set r {}
+ foreach {input} {
+ 0x1ffffffffffffc000
+ 0x1ffffffffffffc800
+ 0x1ffffffffffffd000
+ 0x1ffffffffffffd800
+ 0x1ffffffffffffe000
+ 0x1ffffffffffffe800
+ 0x1fffffffffffff000
+ 0x1fffffffffffff800
+ } {
+ binary scan [binary format q [expr double($input)]] wu x
+ lappend r [format %#llx $x]
+ binary scan [binary format q [expr double(-$input)]] wu x
+ lappend r [format %#llx $x]
+ }
+ set r
+} [list {*}{
+ 0x43fffffffffffffc 0xc3fffffffffffffc
+ 0x43fffffffffffffc 0xc3fffffffffffffc
+ 0x43fffffffffffffd 0xc3fffffffffffffd
+ 0x43fffffffffffffe 0xc3fffffffffffffe
+ 0x43fffffffffffffe 0xc3fffffffffffffe
+ 0x43fffffffffffffe 0xc3fffffffffffffe
+ 0x43ffffffffffffff 0xc3ffffffffffffff
+ 0x4400000000000000 0xc400000000000000
+}]
+
+set ::tcl_precision $saved_precision
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/var.test b/library/msgcat/tests/var.test
new file mode 100644
index 0000000..f2923de
--- /dev/null
+++ b/library/msgcat/tests/var.test
@@ -0,0 +1,815 @@
+# This file contains tests for the tclVar.c source file. Tests appear in the
+# same order as the C code that they test. The set of tests is currently
+# incomplete since it currently includes only new tests for code changed for
+# the addition of Tcl namespaces. Other variable-related tests appear in
+# several other test files including namespace.test, set.test, trace.test, and
+# upvar.test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2.2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testupvar [llength [info commands testupvar]]
+testConstraint testgetvarfullname [llength [info commands testgetvarfullname]]
+testConstraint testsetnoerr [llength [info commands testsetnoerr]]
+
+catch {rename p ""}
+catch {namespace delete test_ns_var}
+catch {unset xx}
+catch {unset x}
+catch {unset y}
+catch {unset i}
+catch {unset a}
+catch {unset arr}
+
+test var-1.1 {TclLookupVar, Array handling} -setup {
+ catch {unset a}
+} -body {
+ set x "incr" ;# force no compilation and runtime call to Tcl_IncrCmd
+ set i 10
+ set arr(foo) 37
+ list [$x i] $i [$x arr(foo)] $arr(foo)
+} -result {11 11 38 38}
+test var-1.2 {TclLookupVar, TCL_GLOBAL_ONLY implies global namespace var} {
+ set x "global value"
+ namespace eval test_ns_var {
+ variable x "namespace value"
+ proc p {} {
+ global x ;# specifies TCL_GLOBAL_ONLY to get global x
+ return $x
+ }
+ }
+ test_ns_var::p
+} {global value}
+test var-1.3 {TclLookupVar, TCL_NAMESPACE_ONLY implies namespace var} {
+ namespace eval test_ns_var {
+ proc q {} {
+ variable x ;# specifies TCL_NAMESPACE_ONLY to get namespace x
+ return $x
+ }
+ }
+ test_ns_var::q
+} {namespace value}
+test var-1.4 {TclLookupVar, no active call frame implies global namespace var} {
+ set x
+} {global value}
+test var-1.5 {TclLookupVar, active call frame pushed for namespace eval implies namespace var} {
+ namespace eval test_ns_var {set x}
+} {namespace value}
+test var-1.6 {TclLookupVar, name starts with :: implies some namespace var} {
+ namespace eval test_ns_var {set ::x}
+} {global value}
+test var-1.7 {TclLookupVar, error finding namespace var} -body {
+ set a:::b
+} -returnCodes error -result {can't read "a:::b": no such variable}
+test var-1.8 {TclLookupVar, error finding namespace var} -body {
+ set ::foobarfoo
+} -returnCodes error -result {can't read "::foobarfoo": no such variable}
+test var-1.9 {TclLookupVar, create new namespace var} {
+ namespace eval test_ns_var {
+ set v hello
+ }
+} {hello}
+test var-1.10 {TclLookupVar, create new namespace var} -setup {
+ catch {unset y}
+} -body {
+ namespace eval test_ns_var {
+ set ::y 789
+ }
+ set y
+} -result {789}
+test var-1.11 {TclLookupVar, error creating new namespace var} -body {
+ namespace eval test_ns_var {
+ set ::test_ns_var::foo::bar 314159
+ }
+} -returnCodes error -result {can't set "::test_ns_var::foo::bar": parent namespace doesn't exist}
+test var-1.12 {TclLookupVar, error creating new namespace var} -body {
+ namespace eval test_ns_var {
+ set ::test_ns_var::foo:: 1997
+ }
+} -returnCodes error -result {can't set "::test_ns_var::foo::": parent namespace doesn't exist}
+test var-1.13 {TclLookupVar, new namespace var is created in a particular namespace} {
+ catch {unset aNeWnAmEiNnS}
+ namespace eval test_ns_var {
+ namespace eval test_ns_var2::test_ns_var3 {
+ set aNeWnAmEiNnS 77777
+ }
+ # namespace which builds a name by traversing nsPtr chain to ::
+ namespace which -variable test_ns_var2::test_ns_var3::aNeWnAmEiNnS
+ }
+} {::test_ns_var::test_ns_var2::test_ns_var3::aNeWnAmEiNnS}
+test var-1.14 {TclLookupVar, namespace code ignores ":"s in middle and end of var names} {
+ namespace eval test_ns_var {
+ set : 123
+ set v: 456
+ set x:y: 789
+ list [set :] [set v:] [set x:y:] \
+ ${:} ${v:} ${x:y:} \
+ [expr {":" in [info vars]}] \
+ [expr {"v:" in [info vars]}] \
+ [expr {"x:y:" in [info vars]}]
+ }
+} {123 456 789 123 456 789 1 1 1}
+test var-1.15 {TclLookupVar, resurrect variable via upvar to deleted namespace: compiled code path} {
+ namespace eval test_ns_var {
+ variable foo 2
+ }
+ proc p {} {
+ variable ::test_ns_var::foo
+ lappend result [catch {set foo} msg] $msg
+ namespace delete ::test_ns_var
+ lappend result [catch {set foo 3} msg] $msg
+ lappend result [catch {set foo(3) 3} msg] $msg
+ }
+ p
+} {0 2 1 {can't set "foo": upvar refers to variable in deleted namespace} 1 {can't set "foo(3)": upvar refers to variable in deleted namespace}}
+test var-1.16 {TclLookupVar, resurrect variable via upvar to deleted namespace: uncompiled code path} {
+ namespace eval test_ns_var {
+ variable result
+ namespace eval subns {
+ variable foo 2
+ }
+ upvar 0 subns::foo foo
+ lappend result [catch {set foo} msg] $msg
+ namespace delete subns
+ lappend result [catch {set foo 3} msg] $msg
+ lappend result [catch {set foo(3) 3} msg] $msg
+ namespace delete [namespace current]
+ set result
+ }
+} {0 2 1 {can't set "foo": upvar refers to variable in deleted namespace} 1 {can't set "foo(3)": upvar refers to variable in deleted namespace}}
+test var-1.17 {TclLookupVar, resurrect array element via upvar to deleted array: compiled code path} {
+ namespace eval test_ns_var {
+ variable result
+ proc p {} {
+ array set x {1 2 3 4}
+ upvar 0 x(1) foo
+ lappend result [catch {set foo} msg] $msg
+ unset x
+ lappend result [catch {set foo 3} msg] $msg
+ }
+ set result [p]
+ namespace delete [namespace current]
+ set result
+ }
+} {0 2 1 {can't set "foo": upvar refers to element in deleted array}}
+test var-1.18 {TclLookupVar, resurrect array element via upvar to deleted array: uncompiled code path} {
+ namespace eval test_ns_var {
+ variable result {}
+ variable x
+ array set x {1 2 3 4}
+ upvar 0 x(1) foo
+ lappend result [catch {set foo} msg] $msg
+ unset x
+ lappend result [catch {set foo 3} msg] $msg
+ namespace delete [namespace current]
+ set result
+ }
+} {0 2 1 {can't set "foo": upvar refers to element in deleted array}}
+test var-1.19 {TclLookupVar, right error message when parsing variable name} -body {
+ [format set] thisvar(doesntexist)
+} -returnCodes error -result {can't read "thisvar(doesntexist)": no such variable}
+
+test var-2.1 {Tcl_LappendObjCmd, create var if new} {
+ catch {unset x}
+ lappend x 1 2
+} {1 2}
+
+test var-3.1 {MakeUpvar, TCL_NAMESPACE_ONLY not specified for other var} -setup {
+ catch {unset x}
+} -body {
+ set x 1997
+ proc p {} {
+ global x ;# calls MakeUpvar with TCL_NAMESPACE_ONLY for other var x
+ return $x
+ }
+ p
+} -result {1997}
+test var-3.2 {MakeUpvar, other var has TCL_NAMESPACE_ONLY specified} {
+ namespace eval test_ns_var {
+ catch {unset v}
+ variable v 1998
+ proc p {} {
+ variable v ;# TCL_NAMESPACE_ONLY specified for other var x
+ return $v
+ }
+ p
+ }
+} {1998}
+test var-3.3 {MakeUpvar, my var has TCL_GLOBAL_ONLY specified} -setup {
+ catch {unset a}
+} -constraints testupvar -body {
+ set a 123321
+ proc p {} {
+ # create global xx linked to global a
+ testupvar 1 a {} xx global
+ }
+ list [p] $xx [set xx 789] $a
+} -result {{} 123321 789 789}
+test var-3.4 {MakeUpvar, my var has TCL_NAMESPACE_ONLY specified} -setup {
+ catch {unset a}
+} -constraints testupvar -body {
+ set a 456
+ namespace eval test_ns_var {
+ catch {unset ::test_ns_var::vv}
+ proc p {} {
+ # create namespace var vv linked to global a
+ testupvar 1 a {} vv namespace
+ }
+ p
+ }
+ list $test_ns_var::vv [set test_ns_var::vv 123] $a
+} -result {456 123 123}
+test var-3.5 {MakeUpvar, no call frame so my var will be in global :: ns} -setup {
+ catch {unset aaaaa}
+ catch {unset xxxxx}
+} -body {
+ set aaaaa 77777
+ upvar #0 aaaaa xxxxx
+ list [set xxxxx] [set aaaaa]
+} -result {77777 77777}
+test var-3.6 {MakeUpvar, active call frame pushed for namespace eval} -setup {
+ catch {unset a}
+} -body {
+ set a 121212
+ namespace eval test_ns_var {
+ upvar ::a vvv
+ set vvv
+ }
+} -result {121212}
+test var-3.7 {MakeUpvar, my var has ::s} -setup {
+ catch {unset a}
+} -body {
+ set a 789789
+ upvar #0 a test_ns_var::lnk
+ namespace eval test_ns_var {
+ set lnk
+ }
+} -result {789789}
+test var-3.8 {MakeUpvar, my var already exists in global ns} -setup {
+ catch {unset aaaaa}
+ catch {unset xxxxx}
+} -body {
+ set aaaaa 456654
+ set xxxxx hello
+ upvar #0 aaaaa xxxxx
+ set xxxxx
+} -result {hello}
+test var-3.9 {MakeUpvar, my var has invalid ns name} -setup {
+ catch {unset aaaaa}
+} -returnCodes error -body {
+ set aaaaa 789789
+ upvar #0 aaaaa test_ns_fred::lnk
+} -result {can't create "test_ns_fred::lnk": parent namespace doesn't exist}
+test var-3.10 {MakeUpvar, between namespaces} -body {
+ namespace eval {} {
+ variable bar 0
+ namespace eval foo upvar bar bar
+ set foo::bar 1
+ list $bar $foo::bar
+ }
+} -cleanup {
+ unset ::aaaaa
+} -result {1 1}
+test var-3.11 {MakeUpvar, my var looks like array elem} -setup {
+ catch {unset aaaaa}
+} -returnCodes error -body {
+ set aaaaa 789789
+ upvar #0 aaaaa foo(bar)
+} -result {bad variable name "foo(bar)": upvar won't create a scalar variable that looks like an array element}
+
+test var-4.1 {Tcl_GetVariableName, global variable} testgetvarfullname {
+ catch {unset a}
+ set a 123
+ testgetvarfullname a global
+} ::a
+test var-4.2 {Tcl_GetVariableName, namespace variable} testgetvarfullname {
+ namespace eval test_ns_var {
+ variable george
+ testgetvarfullname george namespace
+ }
+} ::test_ns_var::george
+test var-4.3 {Tcl_GetVariableName, variable can't be array element} -setup {
+ catch {unset a}
+} -constraints testgetvarfullname -body {
+ set a(1) foo
+ testgetvarfullname a(1) global
+} -returnCodes error -result {unknown variable "a(1)"}
+
+test var-5.1 {Tcl_GetVariableFullName, global variable} -setup {
+ catch {unset a}
+} -body {
+ set a bar
+ namespace which -variable a
+} -result {::a}
+test var-5.2 {Tcl_GetVariableFullName, namespace variable} {
+ namespace eval test_ns_var {
+ variable martha
+ namespace which -variable martha
+ }
+} {::test_ns_var::martha}
+test var-5.3 {Tcl_GetVariableFullName, namespace variable} {
+ namespace which -variable test_ns_var::martha
+} {::test_ns_var::martha}
+
+test var-6.1 {Tcl_GlobalObjCmd, variable is qualified by a namespace name} {
+ namespace eval test_ns_var {
+ variable boeing 777
+ }
+ apply {{} {
+ global ::test_ns_var::boeing
+ set boeing
+ }}
+} {777}
+test var-6.2 {Tcl_GlobalObjCmd, variable is qualified by a namespace name} {
+ namespace eval test_ns_var {
+ namespace eval test_ns_nested {
+ variable java java
+ }
+ proc p {} {
+ global ::test_ns_var::test_ns_nested::java
+ set java
+ }
+ }
+ test_ns_var::p
+} {java}
+test var-6.3 {Tcl_GlobalObjCmd, variable named {} qualified by a namespace name} {
+ set ::test_ns_var::test_ns_nested:: 24
+ apply {{} {
+ global ::test_ns_var::test_ns_nested::
+ set {}
+ }}
+} {24}
+test var-6.4 {Tcl_GlobalObjCmd, variable name matching :*} {
+ # Test for Tcl Bug 480176
+ set :v broken
+ proc p {} {
+ global :v
+ set :v fixed
+ }
+ p
+ set :v
+} {fixed}
+test var-6.5 {Tcl_GlobalObjCmd, no-op case (TIP 323)} {
+ global
+} {}
+test var-6.6 {Tcl_GlobalObjCmd, no-op case (TIP 323)} {
+ proc p {} {
+ global
+ }
+ p
+} {}
+
+test var-7.1 {Tcl_VariableObjCmd, create and initialize one new ns variable} -setup {
+ catch {namespace delete test_ns_var}
+} -body {
+ namespace eval test_ns_var {
+ variable one 1
+ }
+ list [info vars test_ns_var::*] [set test_ns_var::one]
+} -result {::test_ns_var::one 1}
+test var-7.2 {Tcl_VariableObjCmd, if new and no value, leave undefined} {
+ set two 2222222
+ namespace eval test_ns_var {
+ variable two
+ }
+ list [info exists test_ns_var::two] [catch {set test_ns_var::two} msg] $msg
+} {0 1 {can't read "test_ns_var::two": no such variable}}
+test var-7.3 {Tcl_VariableObjCmd, "define" var already created above} {
+ namespace eval test_ns_var {
+ variable two 2
+ }
+ list [lsort [info vars test_ns_var::*]] \
+ [namespace eval test_ns_var {set two}]
+} [list [lsort {::test_ns_var::two ::test_ns_var::one}] 2]
+test var-7.4 {Tcl_VariableObjCmd, list of vars} {
+ namespace eval test_ns_var {
+ variable three 3 four 4
+ }
+ list [lsort [info vars test_ns_var::*]] \
+ [namespace eval test_ns_var {expr $three+$four}]
+} [list [lsort {::test_ns_var::four ::test_ns_var::three ::test_ns_var::two ::test_ns_var::one}] 7]
+test var-7.5 {Tcl_VariableObjCmd, value for last var is optional} -setup {
+ catch {unset a}
+ catch {unset five}
+ catch {unset six}
+} -body {
+ set a ""
+ set five 555
+ set six 666
+ namespace eval test_ns_var {
+ variable five 5 six
+ lappend a $five
+ }
+ lappend a $test_ns_var::five \
+ [set test_ns_var::six 6] [set test_ns_var::six] $six
+} -cleanup {
+ catch {unset five}
+ catch {unset six}
+} -result {5 5 6 6 666}
+test var-7.6 {Tcl_VariableObjCmd, variable name can be qualified} -setup {
+ catch {unset newvar}
+} -body {
+ namespace eval test_ns_var {
+ variable ::newvar cheers!
+ }
+ return $newvar
+} -cleanup {
+ catch {unset newvar}
+} -result {cheers!}
+test var-7.7 {Tcl_VariableObjCmd, bad var name} -returnCodes error -body {
+ namespace eval test_ns_var {
+ variable sev:::en 7
+ }
+} -result {can't define "sev:::en": parent namespace doesn't exist}
+test var-7.8 {Tcl_VariableObjCmd, if var already exists and no value is given, leave value unchanged} {
+ set a ""
+ namespace eval test_ns_var {
+ variable eight 8
+ lappend a $eight
+ variable eight
+ lappend a $eight
+ }
+ set a
+} {8 8}
+test var-7.9 {Tcl_VariableObjCmd, mark as namespace var so var persists until namespace is destroyed or var is unset} -setup {
+ catch {namespace delete test_ns_var2}
+} -body {
+ set a ""
+ namespace eval test_ns_var2 {
+ variable x 123
+ variable y
+ variable z
+ }
+ lappend a [lsort [info vars test_ns_var2::*]]
+ lappend a [info exists test_ns_var2::x] [info exists test_ns_var2::y] \
+ [info exists test_ns_var2::z]
+ lappend a [list [catch {set test_ns_var2::y} msg] $msg]
+ lappend a [lsort [info vars test_ns_var2::*]]
+ lappend a [info exists test_ns_var2::y] [info exists test_ns_var2::z]
+ lappend a [set test_ns_var2::y hello]
+ lappend a [info exists test_ns_var2::y] [info exists test_ns_var2::z]
+ lappend a [list [catch {unset test_ns_var2::y} msg] $msg]
+ lappend a [lsort [info vars test_ns_var2::*]]
+ lappend a [info exists test_ns_var2::y] [info exists test_ns_var2::z]
+ lappend a [list [catch {unset test_ns_var2::z} msg] $msg]
+ lappend a [namespace delete test_ns_var2]
+} -result [list [lsort {::test_ns_var2::x ::test_ns_var2::y ::test_ns_var2::z}] 1 0 0\
+ {1 {can't read "test_ns_var2::y": no such variable}}\
+ [lsort {::test_ns_var2::x ::test_ns_var2::y ::test_ns_var2::z}] 0 0\
+ hello 1 0\
+ {0 {}}\
+ [lsort {::test_ns_var2::x ::test_ns_var2::z}] 0 0\
+ {1 {can't unset "test_ns_var2::z": no such variable}}\
+ {}]
+test var-7.10 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} {
+ namespace eval test_ns_var {
+ proc p {} {
+ variable eight
+ list [set eight] [info vars]
+ }
+ p
+ }
+} {8 eight}
+test var-7.11 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} {
+ proc p {} { ;# note this proc is at global :: scope
+ variable test_ns_var::eight
+ list [set eight] [info vars]
+ }
+ p
+} {8 eight}
+test var-7.12 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} {
+ namespace eval test_ns_var {
+ variable {} {My name is empty}
+ }
+ proc p {} { ;# note this proc is at global :: scope
+ variable test_ns_var::
+ list [set {}] [info vars]
+ }
+ p
+} {{My name is empty} {{}}}
+test var-7.13 {Tcl_VariableObjCmd, variable named ":"} {
+ namespace eval test_ns_var {
+ variable : {My name is ":"}
+ proc p {} {
+ variable :
+ list [set :] [info vars]
+ }
+ p
+ }
+} {{My name is ":"} :}
+test var-7.14 {Tcl_VariableObjCmd, array element parameter} -body {
+ namespace eval test_ns_var { variable arrayvar(1) }
+} -returnCodes error -result "can't define \"arrayvar(1)\": name refers to an element in an array"
+test var-7.15 {Tcl_VariableObjCmd, array element parameter} -body {
+ namespace eval test_ns_var {
+ variable arrayvar
+ set arrayvar(1) x
+ variable arrayvar(1) y
+ }
+} -returnCodes error -result "can't define \"arrayvar(1)\": name refers to an element in an array"
+test var-7.16 {Tcl_VariableObjCmd, no args (TIP 323)} {
+ variable
+} {}
+test var-7.17 {Tcl_VariableObjCmd, no args (TIP 323)} {
+ namespace eval test_ns_var {
+ variable
+ }
+} {}
+
+test var-8.1 {TclDeleteVars, "unset" traces are called with fully-qualified var names} -setup {
+ catch {namespace delete test_ns_var}
+ catch {unset a}
+} -body {
+ namespace eval test_ns_var {
+ variable v 123
+ variable info ""
+ proc traceUnset {name1 name2 op} {
+ variable info
+ set info [concat $info [list $name1 $name2 $op]]
+ }
+ trace var v u [namespace code traceUnset]
+ }
+ list [unset test_ns_var::v] $test_ns_var::info
+} -result {{} {test_ns_var::v {} u}}
+test var-8.2 {TclDeleteNamespaceVars, "unset" traces on ns delete are called with fully-qualified var names} -setup {
+ catch {namespace delete test_ns_var}
+ catch {unset a}
+} -body {
+ set info ""
+ namespace eval test_ns_var {
+ variable v 123 1
+ trace var v u ::traceUnset
+ }
+ proc traceUnset {name1 name2 op} {
+ set ::info [concat $::info [list $name1 $name2 $op]]
+ }
+ list [namespace delete test_ns_var] $::info
+} -result {{} {::test_ns_var::v {} u}}
+
+test var-9.1 {behaviour of TclGet/SetVar simple get/set} -setup {
+ catch {unset u}
+ catch {unset v}
+} -constraints testsetnoerr -body {
+ list \
+ [set u a; testsetnoerr u] \
+ [testsetnoerr v b] \
+ [testseterr u] \
+ [unset v; testseterr v b]
+} -result [list {before get a} {before set b} {before get a} {before set b}]
+test var-9.2 {behaviour of TclGet/SetVar namespace get/set} -setup {
+ catch {namespace delete ns}
+} -constraints testsetnoerr -body {
+ namespace eval ns {variable u a; variable v}
+ list \
+ [testsetnoerr ns::u] \
+ [testsetnoerr ns::v b] \
+ [testseterr ns::u] \
+ [unset ns::v; testseterr ns::v b]
+} -result [list {before get a} {before set b} {before get a} {before set b}]
+test var-9.3 {behaviour of TclGetVar no variable} -setup {
+ catch {unset u}
+} -constraints testsetnoerr -body {
+ list \
+ [catch {testsetnoerr u} res] $res \
+ [catch {testseterr u} res] $res
+} -result {1 {before get} 1 {can't read "u": no such variable}}
+test var-9.4 {behaviour of TclGetVar no namespace variable} -setup {
+ catch {namespace delete ns}
+} -constraints testsetnoerr -body {
+ namespace eval ns {}
+ list \
+ [catch {testsetnoerr ns::w} res] $res \
+ [catch {testseterr ns::w} res] $res
+} -result {1 {before get} 1 {can't read "ns::w": no such variable}}
+test var-9.5 {behaviour of TclGetVar no namespace} -setup {
+ catch {namespace delete ns}
+} -constraints testsetnoerr -body {
+ list \
+ [catch {testsetnoerr ns::u} res] $res \
+ [catch {testseterr ns::v} res] $res
+} -result {1 {before get} 1 {can't read "ns::v": no such variable}}
+test var-9.6 {behaviour of TclSetVar no namespace} -setup {
+ catch {namespace delete ns}
+} -constraints testsetnoerr -body {
+ list \
+ [catch {testsetnoerr ns::v 1} res] $res \
+ [catch {testseterr ns::v 1} res] $res
+} -result {1 {before set} 1 {can't set "ns::v": parent namespace doesn't exist}}
+test var-9.7 {behaviour of TclGetVar array variable} -setup {
+ catch {unset arr}
+} -constraints testsetnoerr -body {
+ set arr(1) 1
+ list \
+ [catch {testsetnoerr arr} res] $res \
+ [catch {testseterr arr} res] $res
+} -result {1 {before get} 1 {can't read "arr": variable is array}}
+test var-9.8 {behaviour of TclSetVar array variable} -setup {
+ catch {unset arr}
+} -constraints testsetnoerr -body {
+ set arr(1) 1
+ list \
+ [catch {testsetnoerr arr 2} res] $res \
+ [catch {testseterr arr 2} res] $res
+} -result {1 {before set} 1 {can't set "arr": variable is array}}
+test var-9.9 {behaviour of TclGetVar read trace success} -setup {
+ catch {unset u}
+ catch {unset v}
+} -constraints testsetnoerr -body {
+ proc resetvar {val name elem op} {upvar 1 $name v; set v $val}
+ set u 10
+ trace var u r [list resetvar 1]
+ trace var v r [list resetvar 2]
+ list \
+ [testsetnoerr u] \
+ [testseterr v]
+} -result {{before get 1} {before get 2}}
+test var-9.10 {behaviour of TclGetVar read trace error} testsetnoerr {
+ proc writeonly args {error "write-only"}
+ set v 456
+ trace var v r writeonly
+ list \
+ [catch {testsetnoerr v} msg] $msg \
+ [catch {testseterr v} msg] $msg
+} {1 {before get} 1 {can't read "v": write-only}}
+test var-9.11 {behaviour of TclSetVar write trace success} -setup {
+ catch {unset u}
+ catch {unset v}
+} -constraints testsetnoerr -body {
+ proc doubleval {name elem op} {upvar 1 $name v; set v [expr {2 * $v}]}
+ set v 1
+ trace var v w doubleval
+ trace var u w doubleval
+ list \
+ [testsetnoerr u 2] \
+ [testseterr v 3]
+} -result {{before set 4} {before set 6}}
+test var-9.12 {behaviour of TclSetVar write trace error} testsetnoerr {
+ proc readonly args {error "read-only"}
+ set v 456
+ trace var v w readonly
+ list \
+ [catch {testsetnoerr v 2} msg] $msg $v \
+ [catch {testseterr v 3} msg] $msg $v
+} {1 {before set} 2 1 {can't set "v": read-only} 3}
+
+test var-10.1 {can't nest arrays with array set} -setup {
+ catch {unset arr}
+} -returnCodes error -body {
+ array set arr(x) {a 1 b 2}
+} -result {can't set "arr(x)": variable isn't array}
+test var-10.2 {can't nest arrays with array set} -setup {
+ catch {unset arr}
+} -returnCodes error -body {
+ array set arr(x) {}
+} -result {can't set "arr(x)": variable isn't array}
+
+test var-11.1 {array unset} -setup {
+ catch {unset a}
+} -body {
+ array set a { 1,1 a 1,2 b 2,1 c 2,3 d }
+ array unset a 1,*
+ lsort -dict [array names a]
+} -result {2,1 2,3}
+test var-11.2 {array unset} -setup {
+ catch {unset a}
+} -body {
+ array set a { 1,1 a 1,2 b }
+ array unset a
+ array exists a
+} -result 0
+test var-11.3 {array unset errors} -setup {
+ catch {unset a}
+} -returnCodes error -body {
+ array set a { 1,1 a 1,2 b }
+ array unset a pattern too
+} -result {wrong # args: should be "array unset arrayName ?pattern?"}
+
+test var-12.1 {TclFindCompiledLocals, {} array name} {
+ namespace eval n {
+ proc p {} {
+ variable {}
+ set (0) 0
+ set (1) 1
+ set n 2
+ set ($n) 2
+ set ($n,foo) 2
+ }
+ p
+ lsort -dictionary [array names {}]
+ }
+} {0 1 2 2,foo}
+
+test var-13.1 {Tcl_UnsetVar2, unset array with trace set on element} -setup {
+ catch {unset t}
+} -body {
+ proc foo {var ind op} {
+ global t
+ set foo bar
+ }
+ namespace eval :: {
+ set t(1) 1
+ trace variable t(1) u foo
+ unset t
+ }
+ set x "If you see this, it worked"
+} -result "If you see this, it worked"
+
+test var-14.1 {array names syntax} -body {
+ array names foo bar baz snafu
+} -returnCodes 1 -match glob -result *
+test var-14.2 {array names -glob} -body {
+ array names tcl_platform -glob os
+} -result os
+
+test var-15.1 {segfault in [unset], [Bug 735335]} {
+ proc A { name } {
+ upvar $name var
+ set var $name
+ }
+ #
+ # Note that the variable name has to be
+ # unused previously for the segfault to
+ # be triggered.
+ #
+ namespace eval test A useSomeUnlikelyNameHere
+ namespace eval test unset useSomeUnlikelyNameHere
+} {}
+
+test var-16.1 {CallVarTraces: save/restore interp error state} {
+ trace add variable ::errorCode write " ;#"
+ catch {error foo bar baz}
+ trace remove variable ::errorCode write " ;#"
+ set ::errorInfo
+} bar
+
+test var-17.1 {TclArraySet [Bug 1669489]} -setup {
+ unset -nocomplain ::a
+} -body {
+ namespace eval :: {
+ set elements {1 2 3 4}
+ trace add variable a write "string length \$elements ;#"
+ array set a $elements
+ }
+} -cleanup {
+ unset -nocomplain ::a ::elements
+} -result {}
+
+test var-18.1 {array unset and unset traces: Bug 2939073} -setup {
+ set already 0
+ unset x
+} -body {
+ array set x {e 1 i 1}
+ trace add variable x unset {apply {args {
+ global already x
+ if {!$already} {
+ set already 1
+ unset x(i)
+ }
+ }}}
+ # The next command would crash reliably with memory debugging prior to the
+ # bug fix.
+ array unset x *
+ array size x
+} -cleanup {
+ unset x already
+} -result 0
+
+test var-19.1 {crash when freeing locals hashtable: Bug 3037525} {
+ proc foo {} { catch {upvar 0 dummy \$index} }
+ foo ; # This crashes without the fix for the bug
+ rename foo {}
+} {}
+
+catch {namespace delete ns}
+catch {unset arr}
+catch {unset v}
+
+catch {rename p ""}
+catch {namespace delete test_ns_var}
+catch {namespace delete test_ns_var2}
+catch {unset xx}
+catch {unset x}
+catch {unset y}
+catch {unset i}
+catch {unset a}
+catch {unset xxxxx}
+catch {unset aaaaa}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/while-old.test b/library/msgcat/tests/while-old.test
new file mode 100644
index 0000000..ee17d0b
--- /dev/null
+++ b/library/msgcat/tests/while-old.test
@@ -0,0 +1,119 @@
+# Commands covered: while
+#
+# This file contains the original set of tests for Tcl's while command.
+# Since the while command is now compiled, a new set of tests covering
+# the new implementation is in the file "while.test". Sourcing this file
+# into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test while-old-1.1 {basic while loops} {
+ set count 0
+ while {$count < 10} {set count [expr $count+1]}
+ set count
+} 10
+test while-old-1.2 {basic while loops} {
+ set value xxx
+ while {2 > 3} {set value yyy}
+ set value
+} xxx
+test while-old-1.3 {basic while loops} {
+ set value 1
+ while {"true"} {
+ incr value;
+ if {$value > 5} {
+ break;
+ }
+ }
+ set value
+} 6
+test while-old-1.4 {basic while loops, multiline test expr} {
+ set value 1
+ while {($tcl_platform(platform) != "foobar1") && \
+ ($tcl_platform(platform) != "foobar2")} {
+ incr value
+ break
+ }
+ set value
+} {2}
+test while-old-1.5 {basic while loops, test expr in quotes} {
+ set value 1
+ while "0 < 3" {set value 2; break}
+ set value
+} {2}
+
+test while-old-2.1 {continue in while loop} {
+ set list {1 2 3 4 5}
+ set index 0
+ set result {}
+ while {$index < 5} {
+ if {$index == 2} {set index [expr $index+1]; continue}
+ set result [concat $result [lindex $list $index]]
+ set index [expr $index+1]
+ }
+ set result
+} {1 2 4 5}
+
+test while-old-3.1 {break in while loop} {
+ set list {1 2 3 4 5}
+ set index 0
+ set result {}
+ while {$index < 5} {
+ if {$index == 3} break
+ set result [concat $result [lindex $list $index]]
+ set index [expr $index+1]
+ }
+ set result
+} {1 2 3}
+
+test while-old-4.1 {errors in while loops} {
+ set err [catch {while} msg]
+ list $err $msg
+} {1 {wrong # args: should be "while test command"}}
+test while-old-4.2 {errors in while loops} {
+ set err [catch {while 1} msg]
+ list $err $msg
+} {1 {wrong # args: should be "while test command"}}
+test while-old-4.3 {errors in while loops} {
+ set err [catch {while 1 2 3} msg]
+ list $err $msg
+} {1 {wrong # args: should be "while test command"}}
+test while-old-4.4 {errors in while loops} {
+ set err [catch {while {"a"+"b"} {error "loop aborted"}} msg]
+ list $err $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test while-old-4.5 {errors in while loops} {
+ catch {unset x}
+ set x 1
+ set err [catch {while {$x} {set x foo}} msg]
+ list $err $msg
+} {1 {expected boolean value but got "foo"}}
+test while-old-4.6 {errors in while loops} {
+ set err [catch {while {1} {error "loop aborted"}} msg]
+ list $err $msg $::errorInfo
+} {1 {loop aborted} {loop aborted
+ while executing
+"error "loop aborted""}}
+
+test while-old-5.1 {while return result} {
+ while {0} {set a 400}
+} {}
+test while-old-5.2 {while return result} {
+ set x 1
+ while {$x} {set x 0}
+} {}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/while.test b/library/msgcat/tests/while.test
new file mode 100644
index 0000000..642ec93
--- /dev/null
+++ b/library/msgcat/tests/while.test
@@ -0,0 +1,702 @@
+# Commands covered: while
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Basic "while" operation.
+
+catch {unset i}
+catch {unset a}
+
+test while-1.1 {TclCompileWhileCmd: missing test expression} -body {
+ while
+} -returnCodes error -result {wrong # args: should be "while test command"}
+test while-1.2 {TclCompileWhileCmd: error in test expression} -body {
+ set i 0
+ catch {while {$i<} break}
+ return $::errorInfo
+} -cleanup {
+ unset i
+} -match glob -result {*"while {$i<} break"}
+test while-1.3 {TclCompileWhileCmd: error in test expression} -body {
+ while {"a"+"b"} {error "loop aborted"}
+} -returnCodes error -result {can't use non-numeric string as operand of "+"}
+test while-1.4 {TclCompileWhileCmd: multiline test expr} -body {
+ set value 1
+ while {($tcl_platform(platform) != "foobar1") && \
+ ($tcl_platform(platform) != "foobar2")} {
+ incr value
+ break
+ }
+ return $value
+} -cleanup {
+ unset value
+} -result {2}
+test while-1.5 {TclCompileWhileCmd: non-numeric boolean test expr} -body {
+ set value 1
+ while {"true"} {
+ incr value;
+ if {$value > 5} {
+ break;
+ }
+ }
+ return $value
+} -cleanup {
+ unset value
+} -result 6
+test while-1.6 {TclCompileWhileCmd: test expr is enclosed in quotes} {
+ set i 0
+ while "$i > 5" {}
+} {}
+test while-1.7 {TclCompileWhileCmd: missing command body} -body {
+ set i 0
+ while {$i < 5}
+} -returnCodes error -result {wrong # args: should be "while test command"}
+test while-1.8 {TclCompileWhileCmd: error compiling command body} -body {
+ set i 0
+ catch {while {$i < 5} {set}}
+ return $::errorInfo
+} -match glob -cleanup {
+ unset i
+} -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test while-1.9 {TclCompileWhileCmd: simple command body} -body {
+ set a {}
+ set i 1
+ while {$i<6} {
+ if $i==4 break
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i
+} -result {1 2 3}
+test while-1.10 {TclCompileWhileCmd: command body in quotes} -body {
+ set a {}
+ set i 1
+ while {$i<6} "append a x; incr i"
+ return $a
+} -cleanup {
+ unset a i
+} -result {xxxxx}
+test while-1.11 {TclCompileWhileCmd: computed command body} -setup {
+ catch {unset x1}
+ catch {unset bb}
+ catch {unset x2}
+} -body {
+ set x1 {append a x1; }
+ set bb {break}
+ set x2 {; append a x2; incr i}
+ set a {}
+ set i 1
+ while {$i<6} $x1$bb$x2
+ return $a
+} -cleanup {
+ unset x1 bb x2 a i
+} -result {x1}
+test while-1.12 {TclCompileWhileCmd: long command body} -body {
+ set a {}
+ set i 1
+ while {$i<6} {
+ if $i==4 break
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i
+} -result {1 2 3}
+test while-1.13 {TclCompileWhileCmd: while command result} -body {
+ set i 0
+ set a [while {$i < 5} {incr i}]
+ return $a
+} -cleanup {
+ unset a i
+} -result {}
+test while-1.14 {TclCompileWhileCmd: while command result} -body {
+ set i 0
+ set a [while {$i < 5} {if $i==3 break; incr i}]
+ return $a
+} -cleanup {
+ unset a i
+} -result {}
+
+# Check "while" and "continue".
+
+test while-2.1 {continue tests} -body {
+ set a {}
+ set i 1
+ while {$i <= 4} {
+ incr i
+ if {$i == 3} continue
+ set a [concat $a $i]
+ }
+ return $a
+} -cleanup {
+ unset a i
+} -result {2 4 5}
+test while-2.2 {continue tests} -body {
+ set a {}
+ set i 1
+ while {$i <= 4} {
+ incr i
+ if {$i != 2} continue
+ set a [concat $a $i]
+ }
+ return $a
+} -cleanup {
+ unset a i
+} -result {2}
+test while-2.3 {continue tests, nested loops} -body {
+ set msg {}
+ set i 1
+ while {$i <= 4} {
+ incr i
+ set a 1
+ while {$a <= 2} {
+ incr a
+ if {$i>=3 && $a>=3} continue
+ set msg [concat $msg "$i.$a"]
+ }
+ }
+ return $msg
+} -cleanup {
+ unset a i msg
+} -result {2.2 2.3 3.2 4.2 5.2}
+test while-2.4 {continue tests, long command body} -body {
+ set a {}
+ set i 1
+ while {$i<6} {
+ if $i==2 {incr i; continue}
+ if $i==4 break
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i
+} -result {1 3}
+
+# Check "while" and "break".
+
+test while-3.1 {break tests} -body {
+ set a {}
+ set i 1
+ while {$i <= 4} {
+ if {$i == 3} break
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i
+} -result {1 2}
+test while-3.2 {break tests, nested loops} -body {
+ set msg {}
+ set i 1
+ while {$i <= 4} {
+ set a 1
+ while {$a <= 2} {
+ if {$i>=2 && $a>=2} break
+ set msg [concat $msg "$i.$a"]
+ incr a
+ }
+ incr i
+ }
+ return $msg
+} -cleanup {
+ unset a i msg
+} -result {1.1 1.2 2.1 3.1 4.1}
+test while-3.3 {break tests, long command body} -body {
+ set a {}
+ set i 1
+ while {$i<6} {
+ if $i==2 {incr i; continue}
+ if $i==5 break
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if $i==4 break
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i
+} -result {1 3}
+
+# Check "while" with computed command names.
+
+test while-4.1 {while and computed command names} -body {
+ set i 0
+ set z while
+ $z {$i < 10} {
+ incr i
+ }
+ return $i
+} -cleanup {
+ unset i z
+} -result 10
+test while-4.2 {while (not compiled): missing test expression} -body {
+ set z while
+ $z
+} -returnCodes error -cleanup {
+ unset z
+} -result {wrong # args: should be "while test command"}
+test while-4.3 {while (not compiled): error in test expression} -body {
+ set i 0
+ set z while
+ catch {$z {$i<} {set x 1}}
+ return $::errorInfo
+} -match glob -cleanup {
+ unset i z
+} -result {*"$z {$i<} {set x 1}"}
+test while-4.4 {while (not compiled): error in test expression} -body {
+ set z while
+ $z {"a"+"b"} {error "loop aborted"}
+} -returnCodes error -result {can't use non-numeric string as operand of "+"}
+test while-4.5 {while (not compiled): multiline test expr} -body {
+ set value 1
+ set z while
+ $z {($tcl_platform(platform) != "foobar1") && \
+ ($tcl_platform(platform) != "foobar2")} {
+ incr value
+ break
+ }
+ return $value
+} -cleanup {
+ unset value z
+} -result {2}
+test while-4.6 {while (not compiled): non-numeric boolean test expr} -body {
+ set value 1
+ set z while
+ $z {"true"} {
+ incr value;
+ if {$value > 5} {
+ break;
+ }
+ }
+ return $value
+} -cleanup {
+ unset value z
+} -result 6
+test while-4.7 {while (not compiled): test expr is enclosed in quotes} -body {
+ set i 0
+ set z while
+ $z "$i > 5" {}
+} -cleanup {
+ unset i z
+} -result {}
+test while-4.8 {while (not compiled): missing command body} -body {
+ set i 0
+ set z while
+ $z {$i < 5}
+} -returnCodes error -cleanup {
+ unset i z
+} -result {wrong # args: should be "while test command"}
+test while-4.9 {while (not compiled): error compiling command body} -body {
+ set i 0
+ set z while
+ catch {$z {$i < 5} {set}}
+ set ::errorInfo
+} -match glob -cleanup {
+ unset i z
+} -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"
+ ("while" body line 1)
+ invoked from within
+"$z {$i < 5} {set}"}
+test while-4.10 {while (not compiled): simple command body} -body {
+ set a {}
+ set i 1
+ set z while
+ $z {$i<6} {
+ if $i==4 break
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i z
+} -result {1 2 3}
+test while-4.11 {while (not compiled): command body in quotes} -body {
+ set a {}
+ set i 1
+ set z while
+ $z {$i<6} "append a x; incr i"
+ return $a
+} -cleanup {
+ unset a i z
+} -result {xxxxx}
+test while-4.12 {while (not compiled): computed command body} -setup {
+ catch {unset x1}
+ catch {unset bb}
+ catch {unset x2}
+} -body {
+ set z while
+ set x1 {append a x1; }
+ set bb {break}
+ set x2 {; append a x2; incr i}
+ set a {}
+ set i 1
+ $z {$i<6} $x1$bb$x2
+ return $a
+} -cleanup {
+ unset z x1 bb x2 a i
+} -result {x1}
+test while-4.13 {while (not compiled): long command body} -body {
+ set a {}
+ set z while
+ set i 1
+ $z {$i<6} {
+ if $i==4 break
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i z
+} -result {1 2 3}
+test while-4.14 {while (not compiled): while command result} -body {
+ set i 0
+ set z while
+ set a [$z {$i < 5} {incr i}]
+ return $a
+} -cleanup {
+ unset a i z
+} -result {}
+test while-4.15 {while (not compiled): while command result} -body {
+ set i 0
+ set z while
+ set a [$z {$i < 5} {if $i==3 break; incr i}]
+ return $a
+} -cleanup {
+ unset a i z
+} -result {}
+
+# Check "break" with computed command names.
+
+test while-5.1 {break and computed command names} -body {
+ set i 0
+ set z break
+ while 1 {
+ if {$i > 10} $z
+ incr i
+ }
+ return $i
+} -cleanup {
+ unset i z
+} -result 11
+test while-5.2 {break tests with computed command names} -body {
+ set a {}
+ set i 1
+ set z break
+ while {$i <= 4} {
+ if {$i == 3} $z
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i z
+} -result {1 2}
+test while-5.3 {break tests, nested loops with computed command names} -body {
+ set msg {}
+ set i 1
+ set z break
+ while {$i <= 4} {
+ set a 1
+ while {$a <= 2} {
+ if {$i>=2 && $a>=2} $z
+ set msg [concat $msg "$i.$a"]
+ incr a
+ }
+ incr i
+ }
+ return $msg
+} -cleanup {
+ unset a i z msg
+} -result {1.1 1.2 2.1 3.1 4.1}
+test while-5.4 {break tests, long command body with computed command names} -body {
+ set a {}
+ set i 1
+ set z break
+ while {$i<6} {
+ if $i==2 {incr i; continue}
+ if $i==5 $z
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if $i==4 $z
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i z
+} -result {1 3}
+
+# Check "continue" with computed command names.
+
+test while-6.1 {continue and computed command names} -body {
+ set i 0
+ set z continue
+ while 1 {
+ incr i
+ if {$i < 10} $z
+ break
+ }
+ return $i
+} -cleanup {
+ unset i z
+} -result 10
+test while-6.2 {continue tests} -body {
+ set a {}
+ set i 1
+ set z continue
+ while {$i <= 4} {
+ incr i
+ if {$i == 3} $z
+ set a [concat $a $i]
+ }
+ return $a
+} -cleanup {
+ unset a i z
+} -result {2 4 5}
+test while-6.3 {continue tests with computed command names} -body {
+ set a {}
+ set i 1
+ set z continue
+ while {$i <= 4} {
+ incr i
+ if {$i != 2} $z
+ set a [concat $a $i]
+ }
+ return $a
+} -cleanup {
+ unset a i z
+} -result {2}
+test while-6.4 {continue tests, nested loops with computed command names} -body {
+ set msg {}
+ set i 1
+ set z continue
+ while {$i <= 4} {
+ incr i
+ set a 1
+ while {$a <= 2} {
+ incr a
+ if {$i>=3 && $a>=3} $z
+ set msg [concat $msg "$i.$a"]
+ }
+ }
+ return $msg
+} -cleanup {
+ unset a i z msg
+} -result {2.2 2.3 3.2 4.2 5.2}
+test while-6.5 {continue tests, long command body with computed command names} -body {
+ set a {}
+ set i 1
+ set z continue
+ while {$i<6} {
+ if $i==2 {incr i; continue}
+ if $i==4 break
+ if $i>5 $z
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i z
+} -result {1 3}
+
+# Test for incorrect "double evaluation" semantics
+
+test while-7.1 {delayed substitution of body} -body {
+ set i 0
+ while {[incr i] < 10} "
+ set result $i
+ "
+ proc p {} {
+ set i 0
+ while {[incr i] < 10} "
+ set result $i
+ "
+ return $result
+ }
+ append result [p]
+} -cleanup {
+ unset result i
+} -result {00}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/msgcat/tests/winConsole.test b/library/msgcat/tests/winConsole.test
new file mode 100644
index 0000000..fdde41c
--- /dev/null
+++ b/library/msgcat/tests/winConsole.test
@@ -0,0 +1,48 @@
+# This file tests the tclWinConsole.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+
+test winConsole-1.1 {Console file channel: non-blocking gets} {win interactive} {
+ set oldmode [fconfigure stdin]
+
+ puts stdout "Enter abcdef<return> now: " nonewline
+ flush stdout
+ fileevent stdin readable {
+ if {[gets stdin line] >= 0} {
+ set result $line
+ } else {
+ set result "gets failed"
+ }
+ }
+
+ fconfigure stdin -blocking 0 -buffering line
+
+ set result {}
+ vwait result
+
+ #cleanup the fileevent
+ fileevent stdin readable {}
+ fconfigure stdin {*}$oldmode
+
+ set result
+
+} "abcdef"
+
+#cleanup
+
+::tcltest::cleanupTests
+return
+
diff --git a/library/msgcat/tests/winDde.test b/library/msgcat/tests/winDde.test
new file mode 100644
index 0000000..83f3598
--- /dev/null
+++ b/library/msgcat/tests/winDde.test
@@ -0,0 +1,471 @@
+# This file tests the tclWinDde.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ #tcltest::configure -verbose {pass start}
+ namespace import -force ::tcltest::*
+}
+
+if [catch {
+ # Is the dde extension already static to this shell?
+ if [catch {load {} Dde; set ::ddelib {}}] {
+ # try the location given to use on the commandline to tcltest
+ ::tcltest::loadTestedCommands
+ load $::ddelib Dde
+ }
+ testConstraint dde 1
+}] {
+ testConstraint dde 0
+}
+
+
+# -------------------------------------------------------------------------
+# Setup a script for a test server
+#
+
+set scriptName [makeFile {} script1.tcl]
+
+proc createChildProcess {ddeServerName args} {
+ file delete -force $::scriptName
+
+ set f [open $::scriptName w+]
+ puts $f [list set ddeServerName $ddeServerName]
+ if {$::ddelib != ""} {
+ puts $f [list load $::ddelib Dde]
+ }
+ puts $f {
+ # DDE child server -
+ #
+ if {"::tcltest" ni [namespace children]} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+ }
+
+ # If an error occurs during the tests, this process may end up not
+ # being closed down. To deal with this we create a 30s timeout.
+ proc ::DoTimeout {} {
+ global done ddeServerName
+ set done 1
+ puts "winDde.test child process $ddeServerName timed out."
+ flush stdout
+ }
+ set timeout [after 30000 ::DoTimeout]
+
+ # Define a restricted handler.
+ proc Handler1 {cmd} {
+ if {$cmd eq "stop"} {set ::done 1}
+ if {$cmd == ""} {
+ set cmd "null data"
+ }
+ puts $cmd ; flush stdout
+ return
+ }
+ proc Handler2 {cmd} {
+ if {$cmd eq "stop"} {set ::done 1}
+ puts [uplevel \#0 $cmd] ; flush stdout
+ return
+ }
+ proc Handler3 {prefix cmd} {
+ if {$cmd eq "stop"} {set ::done 1}
+ puts [list $prefix $cmd] ; flush stdout
+ return
+ }
+ }
+ # set the dde server name to the supplied argument.
+ puts $f [list dde servername {*}$args -- $ddeServerName]
+ puts $f {
+ # run the server and handle final cleanup.
+ after 200;# give dde a chance to get going.
+ puts ready
+ flush stdout
+ vwait done
+ # allow enough time for the calling process to
+ # claim all results, to avoid spurious "server did
+ # not respond"
+ after 200 {set reallyDone 1}
+ vwait reallyDone
+ exit
+ }
+ close $f
+
+ # run the child server script.
+ set f [open |[list [interpreter] $::scriptName] r]
+ fconfigure $f -buffering line
+ gets $f line
+ return $f
+}
+
+# -------------------------------------------------------------------------
+
+test winDde-1.1 {Settings the server's topic name} -constraints dde -body {
+ list [dde servername foobar] [dde servername] [dde servername self]
+} -result {foobar foobar self}
+
+test winDde-2.1 {Checking for other services} -constraints dde -body {
+ expr [llength [dde services {} {}]] >= 0
+} -result 1
+test winDde-2.2 {Checking for existence, with service and topic specified} \
+ -constraints dde -body {
+ llength [dde services TclEval self]
+} -result 1
+test winDde-2.3 {Checking for existence, with only the service specified} \
+ -constraints dde -body {
+ expr [llength [dde services TclEval {}]] >= 1
+} -result 1
+test winDde-2.4 {Checking for existence, with only the topic specified} \
+ -constraints dde -body {
+ expr [llength [dde services {} self]] >= 1
+} -result 1
+
+# -------------------------------------------------------------------------
+
+test winDde-3.1 {DDE execute locally} -constraints dde -body {
+ set \xe1 ""
+ dde execute TclEval self [list set \xe1 foo]
+ set \xe1
+} -result foo
+test winDde-3.2 {DDE execute -async locally} -constraints dde -body {
+ set \xe1 ""
+ dde execute -async TclEval self [list set \xe1 foo]
+ update
+ set \xe1
+} -result foo
+test winDde-3.3 {DDE request locally} -constraints dde -body {
+ set a ""
+ dde execute TclEval self [list set a foo]
+ dde request TclEval self a
+} -result foo
+test winDde-3.4 {DDE eval locally} -constraints dde -body {
+ set \xe1 ""
+ dde eval self set \xe1 foo
+} -result foo
+test winDde-3.5 {DDE request locally} -constraints dde -body {
+ set a ""
+ dde execute TclEval self [list set a foo]
+ dde request -binary TclEval self a
+} -result "foo\x00"
+# Set variable a to A with diaeresis (unicode C4) by relying on the fact
+# that utf8 is sent (e.g. "c3 84" on the wire)
+test winDde-3.6 {DDE request utf8} -constraints dde -body {
+ set a "not set"
+ dde execute TclEval self "set a \xc4"
+ scan $a %c
+} -result 196
+# Set variable a to A with diaeresis (unicode C4) using binary execute
+# and compose utf-8 (e.g. "c3 84" ) manualy
+test winDde-3.7 {DDE request binary} -constraints dde -body {
+ set a "not set"
+ dde execute -binary TclEval self [list set a \xc3\x84\x00]
+ scan $a %c
+} -result 196
+
+# -------------------------------------------------------------------------
+
+test winDde-4.1 {DDE execute remotely} -constraints {dde stdio} -body {
+ set \xe1 ""
+ set name ch\xEDld-4.1
+ set child [createChildProcess $name]
+ dde execute TclEval $name [list set \xe1 foo]
+ dde execute TclEval $name {set done 1}
+ update
+ set \xe1
+} -result ""
+test winDde-4.2 {DDE execute async remotely} -constraints {dde stdio} -body {
+ set \xe1 ""
+ set name ch\xEDld-4.2
+ set child [createChildProcess $name]
+ dde execute -async TclEval $name [list set \xe1 foo]
+ update
+ dde execute TclEval $name {set done 1}
+ update
+ set \xe1
+} -result ""
+test winDde-4.3 {DDE request remotely} -constraints {dde stdio} -body {
+ set a ""
+ set name ch\xEDld-4.3
+ set child [createChildProcess $name]
+ dde execute TclEval $name [list set a foo]
+ set a [dde request TclEval $name a]
+ dde execute TclEval $name {set done 1}
+ update
+ set a
+} -result foo
+test winDde-4.4 {DDE eval remotely} -constraints {dde stdio} -body {
+ set a ""
+ set name ch\xEDld-4.4
+ set child [createChildProcess $name]
+ set a [dde eval $name set a foo]
+ dde execute TclEval $name {set done 1}
+ update
+ set a
+} -result foo
+
+# -------------------------------------------------------------------------
+
+test winDde-5.1 {check for bad arguments} -constraints dde -body {
+ dde execute "" "" "" ""
+} -returnCodes error -result {wrong # args: should be "dde execute ?-async? ?-binary? serviceName topicName value"}
+test winDde-5.2 {check for bad arguments} -constraints dde -body {
+ dde execute -binary "" "" ""
+} -returnCodes error -result {cannot execute null data}
+test winDde-5.3 {check for bad arguments} -constraints dde -body {
+ dde execute -foo "" "" ""
+} -returnCodes error -result {wrong # args: should be "dde execute ?-async? ?-binary? serviceName topicName value"}
+test winDde-5.4 {DDE eval bad arguments} -constraints dde -body {
+ dde eval "" "foo"
+} -returnCodes error -result {invalid service name ""}
+
+# -------------------------------------------------------------------------
+
+test winDde-6.1 {DDE servername bad arguments} -constraints dde -body {
+ dde servername -z -z -z
+} -returnCodes error -result {bad option "-z": must be -force, -handler, or --}
+test winDde-6.2 {DDE servername set name} -constraints dde -body {
+ dde servername -- winDde-6.2
+} -result {winDde-6.2}
+test winDde-6.3 {DDE servername set exact name} -constraints dde -body {
+ dde servername -force winDde-6.3
+} -result {winDde-6.3}
+test winDde-6.4 {DDE servername set exact name} -constraints dde -body {
+ dde servername -force -- winDde-6.4
+} -result {winDde-6.4}
+test winDde-6.5 {DDE remote servername collision} -constraints {dde stdio} -setup {
+ set name ch\xEDld-6.5
+ set child [createChildProcess $name]
+} -body {
+ dde servername -- $name
+} -cleanup {
+ dde execute TclEval $name {set done 1}
+ update
+} -result "ch\xEDld-6.5 #2"
+test winDde-6.6 {DDE remote servername collision force} -constraints {dde stdio} -setup {
+ set name ch\xEDld-6.6
+ set child [createChildProcess $name]
+} -body {
+ dde servername -force -- $name
+} -cleanup {
+ dde execute TclEval $name {set done 1}
+ update
+} -result "ch\xEDld-6.6"
+
+# -------------------------------------------------------------------------
+
+test winDde-7.1 {Load DDE in slave interpreter} -constraints dde -setup {
+ interp create slave
+} -body {
+ slave eval [list load $::ddelib Dde]
+ slave eval [list dde servername -- dde-interp-7.1]
+} -cleanup {
+ interp delete slave
+} -result {dde-interp-7.1}
+test winDde-7.2 {DDE slave cleanup} -constraints dde -setup {
+ interp create slave
+ slave eval [list load $::ddelib Dde]
+ slave eval [list dde servername -- dde-interp-7.5]
+ interp delete slave
+} -body {
+ dde services TclEval {}
+ set s [dde services TclEval {}]
+ set m [list [list TclEval dde-interp-7.5]]
+ if {$m in $s} {
+ set s
+ }
+} -result {}
+test winDde-7.3 {DDE present in slave interp} -constraints dde -setup {
+ interp create slave
+ slave eval [list load $::ddelib Dde]
+ slave eval [list dde servername -- dde-interp-7.3]
+} -body {
+ dde services TclEval dde-interp-7.3
+} -cleanup {
+ interp delete slave
+} -result {{TclEval dde-interp-7.3}}
+test winDde-7.4 {interp name collision with -force} -constraints dde -setup {
+ interp create slave
+ slave eval [list load $::ddelib Dde]
+ slave eval [list dde servername -- dde-interp-7.4]
+} -body {
+ dde servername -force -- dde-interp-7.4
+} -cleanup {
+ interp delete slave
+} -result {dde-interp-7.4}
+test winDde-7.5 {interp name collision without -force} -constraints dde -setup {
+ interp create slave
+ slave eval [list load $::ddelib Dde]
+ slave eval [list dde servername -- dde-interp-7.5]
+} -body {
+ dde servername -- dde-interp-7.5
+} -cleanup {
+ interp delete slave
+} -result "dde-interp-7.5 #2"
+
+# -------------------------------------------------------------------------
+
+test winDde-8.1 {Safe DDE load} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+} -body {
+ slave eval dde servername slave
+} -cleanup {
+ interp delete slave
+} -returnCodes error -result {invalid command name "dde"}
+test winDde-8.2 {Safe DDE set servername} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+} -body {
+ slave invokehidden dde servername slave
+} -cleanup {interp delete slave} -result {slave}
+test winDde-8.3 {Safe DDE check handler required for eval} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave invokehidden dde servername slave
+} -body {
+ catch {dde eval slave set a 1} msg
+} -cleanup {interp delete slave} -result {1}
+test winDde-8.4 {Safe DDE check that execute is denied} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave invokehidden dde servername slave
+} -body {
+ slave eval set a 1
+ dde execute TclEval slave {set a 2}
+ slave eval set a
+} -cleanup {interp delete slave} -result 1
+test winDde-8.5 {Safe DDE check that request is denied} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave invokehidden dde servername slave
+} -body {
+ slave eval set a 1
+ dde request TclEval slave a
+} -cleanup {
+ interp delete slave
+} -returnCodes error -result {remote server cannot handle this command}
+test winDde-8.6 {Safe DDE assign handler procedure} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave eval {proc DDEACCEPT {cmd} {set ::DDECMD $cmd}}
+} -body {
+ slave invokehidden dde servername -handler DDEACCEPT slave
+} -cleanup {interp delete slave} -result slave
+test winDde-8.7 {Safe DDE check simple command} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave eval {proc DDEACCEPT {cmd} {set ::DDECMD $cmd}}
+ slave invokehidden dde servername -handler DDEACCEPT slave
+} -body {
+ dde eval slave set x 1
+} -cleanup {interp delete slave} -result {set x 1}
+test winDde-8.8 {Safe DDE check non-list command} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave eval {proc DDEACCEPT {cmd} {set ::DDECMD $cmd}}
+ slave invokehidden dde servername -handler DDEACCEPT slave
+} -body {
+ set s "c:\\Program Files\\Microsoft Visual Studio\\"
+ dde eval slave $s
+ string equal [slave eval set DDECMD] $s
+} -cleanup {interp delete slave} -result 1
+test winDde-8.9 {Safe DDE check command evaluation} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave eval {proc DDEACCEPT {cmd} {set ::DDECMD [uplevel \#0 $cmd]}}
+ slave invokehidden dde servername -handler DDEACCEPT slave
+} -body {
+ dde eval slave set \xe1 1
+ slave eval set \xe1
+} -cleanup {interp delete slave} -result 1
+test winDde-8.10 {Safe DDE check command evaluation (2)} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave eval {proc DDEACCEPT {cmd} {set ::DDECMD [uplevel \#0 $cmd]}}
+ slave invokehidden dde servername -handler DDEACCEPT slave
+} -body {
+ dde eval slave [list set x 1]
+ slave eval set x
+} -cleanup {interp delete slave} -result 1
+test winDde-8.11 {Safe DDE check command evaluation (3)} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave eval {proc DDEACCEPT {cmd} {set ::DDECMD [uplevel \#0 $cmd]}}
+ slave invokehidden dde servername -handler DDEACCEPT slave
+} -body {
+ dde eval slave [list [list set x 1]]
+ slave eval set x
+} -cleanup {interp delete slave} -returnCodes error -result {invalid command name "set x 1"}
+
+# -------------------------------------------------------------------------
+
+test winDde-9.1 {External safe DDE check string passing} -constraints {dde stdio} -setup {
+ set name ch\xEDld-9.1
+ set child [createChildProcess $name -handler Handler1]
+ file copy -force script1.tcl dde-script.tcl
+} -body {
+ dde eval $name set x 1
+ gets $child line
+ set line
+} -cleanup {
+ dde execute TclEval $name stop
+ update
+ file delete -force -- dde-script.tcl
+} -result {set x 1}
+test winDde-9.2 {External safe DDE check command evaluation} -constraints {dde stdio} -setup {
+ set name ch\xEDld-9.2
+ set child [createChildProcess $name -handler Handler2]
+ file copy -force script1.tcl dde-script.tcl
+} -body {
+ dde eval $name set x 1
+ gets $child line
+ set line
+} -cleanup {
+ dde execute TclEval $name stop
+ update
+ file delete -force -- dde-script.tcl
+} -result 1
+test winDde-9.3 {External safe DDE check prefixed arguments} -constraints {dde stdio} -setup {
+ set name ch\xEDld-9.3
+ set child [createChildProcess $name -handler [list Handler3 ARG]]
+ file copy -force script1.tcl dde-script.tcl
+} -body {
+ dde eval $name set x 1
+ gets $child line
+ set line
+} -cleanup {
+ dde execute TclEval $name stop
+ update
+ file delete -force -- dde-script.tcl
+} -result {ARG {set x 1}}
+test winDde-9.4 {External safe DDE check null data passing} -constraints {dde stdio} -setup {
+ set name ch\xEDld-9.4
+ set child [createChildProcess $name -handler Handler1]
+ file copy -force script1.tcl dde-script.tcl
+} -body {
+ dde execute TclEval $name ""
+ gets $child line
+ set line
+} -cleanup {
+ dde execute TclEval $name stop
+ update
+ file delete -force -- dde-script.tcl
+} -result {null data}
+
+# -------------------------------------------------------------------------
+
+#cleanup
+#catch {interp delete $slave}; # ensure we clean up the slave.
+file delete -force $::scriptName
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/winFCmd.test b/library/msgcat/tests/winFCmd.test
new file mode 100644
index 0000000..b49356d
--- /dev/null
+++ b/library/msgcat/tests/winFCmd.test
@@ -0,0 +1,1549 @@
+# This file tests the tclWinFCmd.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1996-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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# Initialise the test constraints
+
+testConstraint winVista 0
+testConstraint win2000orXP 0
+testConstraint winOlderThan2000 0
+testConstraint testvolumetype [llength [info commands testvolumetype]]
+testConstraint testfile [llength [info commands testfile]]
+testConstraint testchmod [llength [info commands testchmod]]
+testConstraint cdrom 0
+testConstraint exdev 0
+testConstraint longFileNames 0
+
+proc createfile {file {string a}} {
+ set f [open $file w]
+ puts -nonewline $f $string
+ close $f
+ return $string
+}
+
+proc contents {file} {
+ set f [open $file r]
+ set r [read $f]
+ close $f
+ set r
+}
+
+proc cleanup {args} {
+ foreach p ". $args" {
+ set x ""
+ catch {
+ set x [glob -directory $p tf* td*]
+ }
+ if {$x != ""} {
+ catch {file delete -force -- {*}$x}
+ }
+ }
+}
+
+if {[testConstraint winOnly]} {
+ set major [string index $tcl_platform(osVersion) 0]
+ if {[testConstraint nt] && $major > 4} {
+ if {$major > 5} {
+ testConstraint winVista 1
+ } elseif {$major == 5} {
+ testConstraint win2000orXP 1
+ }
+ } else {
+ testConstraint winOlderThan2000 1
+ }
+}
+
+# find a CD-ROM so we can test read-only filesystems.
+
+proc findfile {dir} {
+ foreach p [glob -nocomplain -type f -directory $dir *] {
+ return $p
+ }
+ foreach p [glob -nocomplain -type d -directory $dir *] {
+ set f [findfile $p]
+ if {$f ne ""} {
+ return $f
+ }
+ }
+ return ""
+}
+
+if {[testConstraint testvolumetype]} {
+ foreach p {d e f g h i j k l m n o p q r s t u v w x y z} {
+ if {![catch {testvolumetype ${p}:} result] && $result in {CDFS UDF}} {
+ set cdrom ${p}:
+ set cdfile [findfile $cdrom]
+ testConstraint cdrom 1
+ break
+ }
+ }
+}
+
+# NB: filename is chosen to be short but unlikely to clash with other apps
+if {[file exists c:/] && [file exists d:/]} {
+ catch {file delete d:/TclTmpF.1}
+ if {[catch {createfile d:/TclTmpF.1 {}}] == 0} {
+ file delete d:/TclTmpF.1
+ testConstraint exdev 1
+ }
+}
+
+file delete -force -- td1
+if {![catch {open td1 w} testfile]} {
+ close $testfile
+ testConstraint longFileNames 1
+ file delete -force -- td1
+}
+
+# A really long file name
+# length of longname is 1216 chars, which should be greater than any static
+# buffer or allowable filename.
+
+set longname "abcdefghihjllmnopqrstuvwxyz01234567890"
+append longname $longname
+append longname $longname
+append longname $longname
+append longname $longname
+append longname $longname
+
+# Uses the "testfile" command instead of the "file" command. The "file"
+# command provides several layers of sanity checks on the arguments and
+# it can be difficult to actually forward "insane" arguments to the
+# low-level posix emulation layer.
+
+test winFCmd-1.1 {TclpRenameFile: errno: EACCES} -body {
+ testfile mv $cdfile $cdrom/dummy~~.fil
+} -constraints {win cdrom testfile} -returnCodes error -result EACCES
+test winFCmd-1.2 {TclpRenameFile: errno: EEXIST} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1/td2/td3
+ file mkdir td2
+ testfile mv td2 td1/td2
+} -returnCodes error -result EEXIST
+test winFCmd-1.3 {TclpRenameFile: errno: EINVAL} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mv / td1
+} -returnCodes error -result EINVAL
+test winFCmd-1.4 {TclpRenameFile: errno: EINVAL} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile mv td1 td1/td2
+} -returnCodes error -result EINVAL
+test winFCmd-1.5 {TclpRenameFile: errno: EISDIR} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile tf1
+ testfile mv tf1 td1
+} -returnCodes error -result EISDIR
+test winFCmd-1.6 {TclpRenameFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mv tf1 tf2
+} -returnCodes error -result ENOENT
+test winFCmd-1.7 {TclpRenameFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mv "" tf2
+} -returnCodes error -result ENOENT
+test winFCmd-1.8 {TclpRenameFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ testfile mv tf1 ""
+} -returnCodes error -result ENOENT
+test winFCmd-1.9 {TclpRenameFile: errno: ENOTDIR} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile tf1
+ testfile mv td1 tf1
+} -returnCodes error -result ENOTDIR
+test winFCmd-1.10 {TclpRenameFile: errno: EXDEV} -setup {
+ file delete -force d:/tf1
+} -constraints {win exdev testfile} -body {
+ file mkdir c:/tf1
+ testfile mv c:/tf1 d:/tf1
+} -cleanup {
+ file delete -force c:/tf1
+} -returnCodes error -result EXDEV
+test winFCmd-1.11 {TclpRenameFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ set fd [open tf1 w]
+ testfile mv tf1 tf2
+} -cleanup {
+ catch {close $fd}
+} -returnCodes error -result EACCES
+test winFCmd-1.12 {TclpRenameFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ set fd [open tf2 w]
+ testfile mv tf1 tf2
+} -cleanup {
+ catch {close $fd}
+} -returnCodes error -result EACCES
+test winFCmd-1.13 {TclpRenameFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win win2000orXP testfile} -body {
+ testfile mv nul tf1
+} -returnCodes error -result EINVAL
+test winFCmd-1.13.1 {TclpRenameFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win nt winOlderThan2000 testfile} -body {
+ testfile mv nul tf1
+} -returnCodes error -result EACCES
+test winFCmd-1.13.2 {TclpRenameFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ testfile mv nul tf1
+} -returnCodes error -result ENOENT
+test winFCmd-1.14 {TclpRenameFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ createfile tf1
+ testfile mv tf1 nul
+} -returnCodes error -result EACCES
+test winFCmd-1.15 {TclpRenameFile: errno: EEXIST} -setup {
+ cleanup
+} -constraints {win nt testfile} -body {
+ createfile tf1
+ testfile mv tf1 nul
+} -returnCodes error -result EEXIST
+test winFCmd-1.16 {TclpRenameFile: MoveFile() != FALSE} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1 tf1
+ testfile mv tf1 tf2
+ list [file exists tf1] [contents tf2]
+} -result {0 tf1}
+test winFCmd-1.17 {TclpRenameFile: MoveFile() == FALSE} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mv tf1 tf2
+} -returnCodes error -result ENOENT
+test winFCmd-1.18 {TclpRenameFile: srcAttr == -1} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mv tf1 tf2
+} -returnCodes error -result ENOENT
+test winFCmd-1.19 {TclpRenameFile: errno == EACCES} -setup {
+ cleanup
+} -constraints {win win2000orXP testfile} -body {
+ testfile mv nul tf1
+} -returnCodes error -result EINVAL
+test winFCmd-1.19.1 {TclpRenameFile: errno == EACCES} -setup {
+ cleanup
+} -constraints {win nt winOlderThan2000 testfile} -body {
+ testfile mv nul tf1
+} -returnCodes error -result EACCES
+test winFCmd-1.19.2 {TclpRenameFile: errno == ENOENT} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ testfile mv nul tf1
+} -returnCodes error -result ENOENT
+test winFCmd-1.20 {TclpRenameFile: src is dir} -setup {
+ cleanup
+} -constraints {win nt testfile} -body {
+ # under 95, this would actually succeed and move the current dir out from
+ # under the current process!
+ file delete /tf1
+ testfile mv [pwd] /tf1
+} -returnCodes error -result EACCES
+test winFCmd-1.21 {TclpRenameFile: long src} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mv $longname tf1
+} -returnCodes error -result ENAMETOOLONG
+test winFCmd-1.22 {TclpRenameFile: long dst} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ testfile mv tf1 $longname
+} -returnCodes error -result ENAMETOOLONG
+test winFCmd-1.23 {TclpRenameFile: move dir into self} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile mv [pwd]/td1 td1/td2
+} -returnCodes error -result EINVAL
+test winFCmd-1.24 {TclpRenameFile: move a root dir} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mv / c:/
+} -returnCodes error -result EINVAL
+test winFCmd-1.25 {TclpRenameFile: cross file systems} -setup {
+ cleanup
+} -constraints {win cdrom testfile} -body {
+ file mkdir td1
+ testfile mv td1 $cdrom/td1
+} -returnCodes error -result EXDEV
+test winFCmd-1.26 {TclpRenameFile: readonly fs} -setup {
+ cleanup
+} -constraints {win cdrom testfile} -body {
+ testfile mv $cdfile $cdrom/dummy~~.fil
+} -returnCodes error -result EACCES
+test winFCmd-1.27 {TclpRenameFile: open file} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ set fd [open tf1 w]
+ testfile mv tf1 tf2
+} -cleanup {
+ catch {close $fd}
+} -returnCodes error -result EACCES
+test winFCmd-1.28 {TclpRenameFile: errno == EEXIST} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ createfile tf2
+ testfile mv tf1 tf2
+ list [file exists tf1] [file exists tf2]
+} -result {0 1}
+test winFCmd-1.29 {TclpRenameFile: src is dir} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile tf1
+ testfile mv td1 tf1
+} -returnCodes error -result ENOTDIR
+test winFCmd-1.30 {TclpRenameFile: dst is dir} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ file mkdir td2/td2
+ testfile mv td1 td2
+} -returnCodes error -result EEXIST
+test winFCmd-1.31 {TclpRenameFile: TclpRemoveDirectory fails} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ file mkdir td2/td2
+ testfile mv td1 td2
+} -returnCodes error -result EEXIST
+test winFCmd-1.32 {TclpRenameFile: TclpRemoveDirectory succeeds} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1/td2
+ file mkdir td2
+ testfile mv td1 td2
+ list [file exists td1] [file exists td2] [file exists td2/td2]
+} -result {0 1 1}
+test winFCmd-1.33 {TclpRenameFile: After removing dst dir, MoveFile fails} \
+ -constraints {win exdev testfile testchmod} -body {
+ file mkdir d:/td1
+ testchmod 000 d:/td1
+ file mkdir c:/tf1
+ catch {testfile mv c:/tf1 d:/td1} msg
+ list $msg [file writable d:/td1]
+} -cleanup {
+ catch {testchmod 666 d:/td1}
+ file delete d:/td1
+ file delete -force c:/tf1
+} -result {EXDEV 0}
+test winFCmd-1.34 {TclpRenameFile: src is dir, dst is not} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile tf1
+ testfile mv td1 tf1
+} -cleanup {
+ cleanup
+} -returnCodes error -result ENOTDIR
+test winFCmd-1.35 {TclpRenameFile: src is not dir, dst is} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile tf1
+ testfile mv tf1 td1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-1.36 {TclpRenameFile: src and dst not dir} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1 tf1
+ createfile tf2 tf2
+ testfile mv tf1 tf2
+ contents tf2
+} -cleanup {
+ cleanup
+} -result {tf1}
+test winFCmd-1.37 {TclpRenameFile: need to restore temp file} {win emptyTest} {
+ # Can't figure out how to cause this.
+ # Need a file that can't be copied.
+} {}
+
+# If the native filesystem produces 0 for inodes numbers there is no point
+# doing the following test.
+testConstraint winNonZeroInodes [eval {
+ file stat [info nameofexecutable] statExe
+ expr {$statExe(ino) != 0}
+}]
+
+proc MakeFiles {dirname} {
+ set inodes {}
+ set ndx -1
+ while {1} {
+ # upped to 50K for 64bit Server 2008
+ if {$ndx > 50000} {
+ return -code error "limit reached without finding a collistion."
+ }
+ set filename [file join $dirname Test[incr ndx]]
+ set f [open $filename w]
+ close $f
+ file stat $filename stat
+ if {[set n [lsearch -exact -integer $inodes $stat(ino)]] != -1} {
+ return [list [file join $dirname Test$n] $filename]
+ }
+ lappend inodes $stat(ino)
+ unset stat
+ }
+}
+
+test winFCmd-1.38 {TclpRenameFile: check rename of conflicting inodes} -setup {
+ cleanup
+} -constraints {win winNonZeroInodes} -body {
+ file mkdir td1
+ foreach {a b} [MakeFiles td1] break
+ file rename -force $a $b
+ file exists $a
+} -cleanup {
+ cleanup
+} -result {0}
+
+
+test winFCmd-2.1 {TclpCopyFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win cdrom testfile} -body {
+ testfile cp $cdfile $cdrom/dummy~~.fil
+} -returnCodes error -result EACCES
+test winFCmd-2.2 {TclpCopyFile: errno: EISDIR} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile cp td1 tf1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.3 {TclpCopyFile: errno: EISDIR} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ file mkdir td1
+ testfile cp tf1 td1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.4 {TclpCopyFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile cp tf1 tf2
+} -returnCodes error -result ENOENT
+test winFCmd-2.5 {TclpCopyFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile cp "" tf2
+} -returnCodes error -result ENOENT
+test winFCmd-2.6 {TclpCopyFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ testfile cp tf1 ""
+} -cleanup {
+ cleanup
+} -returnCodes error -result ENOENT
+test winFCmd-2.7 {TclpCopyFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ createfile tf1
+ set fd [open tf2 w]
+ testfile cp tf1 tf2
+} -cleanup {
+ close $fd
+ cleanup
+} -returnCodes error -result EACCES
+test winFCmd-2.8 {TclpCopyFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win win2000orXP testfile} -body {
+ testfile cp nul tf1
+} -returnCodes error -result EINVAL
+test winFCmd-2.8.1 {TclpCopyFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win nt winOlderThan2000 testfile} -body {
+ testfile cp nul tf1
+} -returnCodes error -result EACCES
+test winFCmd-2.9 {TclpCopyFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ testfile cp nul tf1
+} -returnCodes error -result ENOENT
+test winFCmd-2.10 {TclpCopyFile: CopyFile succeeds} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1 tf1
+ testfile cp tf1 tf2
+ list [contents tf1] [contents tf2]
+} -cleanup {
+ cleanup
+} -result {tf1 tf1}
+test winFCmd-2.11 {TclpCopyFile: CopyFile succeeds} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1 tf1
+ createfile tf2 tf2
+ testfile cp tf1 tf2
+ list [contents tf1] [contents tf2]
+} -cleanup {
+ cleanup
+} -result {tf1 tf1}
+test winFCmd-2.12 {TclpCopyFile: CopyFile succeeds} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1 tf1
+ testchmod 000 tf1
+ testfile cp tf1 tf2
+ list [contents tf2] [file writable tf2]
+} -cleanup {
+ catch {testchmod 666 tf1}
+ cleanup
+} -result {tf1 0}
+test winFCmd-2.13 {TclpCopyFile: CopyFile fails} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ file mkdir td1
+ testfile cp tf1 td1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.14 {TclpCopyFile: errno == EACCES} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile cp td1 tf1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.15 {TclpCopyFile: src is directory} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile cp td1 tf1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.16 {TclpCopyFile: dst is directory} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ file mkdir td1
+ testfile cp tf1 td1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.17 {TclpCopyFile: dst is readonly} -setup {
+ cleanup
+} -constraints {win testfile testchmod} -body {
+ createfile tf1 tf1
+ createfile tf2 tf2
+ testchmod 000 tf2
+ testfile cp tf1 tf2
+ list [file writable tf2] [contents tf2]
+} -cleanup {
+ catch {testchmod 666 tf2}
+ cleanup
+} -result {1 tf1}
+test winFCmd-2.18 {TclpCopyFile: still can't copy onto dst} -setup {
+ cleanup
+} -constraints {win 95 testfile testchmod} -body {
+ createfile tf1
+ createfile tf2
+ testchmod 000 tf2
+ set fd [open tf2]
+ set msg [list [catch {testfile cp tf1 tf2} msg] $msg]
+ close $fd
+ lappend msg [file writable tf2]
+} -result {1 EACCES 0}
+
+test winFCmd-3.1 {TclpDeleteFile: errno: EACCES} -body {
+ testfile rm $cdfile $cdrom/dummy~~.fil
+} -constraints {win cdrom testfile} -returnCodes error -result EACCES
+test winFCmd-3.2 {TclpDeleteFile: errno: EISDIR} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile rm td1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-3.3 {TclpDeleteFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile rm tf1
+} -returnCodes error -result ENOENT
+test winFCmd-3.4 {TclpDeleteFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile rm ""
+} -returnCodes error -result ENOENT
+test winFCmd-3.5 {TclpDeleteFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ set fd [open tf1 w]
+ testfile rm tf1
+} -cleanup {
+ close $fd
+ cleanup
+} -returnCodes error -result EACCES
+test winFCmd-3.6 {TclpDeleteFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile rm nul
+} -returnCodes error -result EACCES
+test winFCmd-3.7 {TclpDeleteFile: DeleteFile succeeds} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ testfile rm tf1
+ file exists tf1
+} -result {0}
+test winFCmd-3.8 {TclpDeleteFile: DeleteFile fails} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile rm td1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-3.9 {TclpDeleteFile: errno == EACCES} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ set fd [open tf1 w]
+ testfile rm tf1
+} -cleanup {
+ close $fd
+} -returnCodes error -result EACCES
+test winFCmd-3.10 {TclpDeleteFile: path is readonly} -setup {
+ cleanup
+} -constraints {win testfile testchmod} -body {
+ createfile tf1
+ testchmod 000 tf1
+ testfile rm tf1
+ file exists tf1
+} -result {0}
+test winFCmd-3.11 {TclpDeleteFile: still can't remove path} -setup {
+ cleanup
+} -constraints {win testfile testchmod} -body {
+ set fd [open tf1 w]
+ testchmod 000 tf1
+ testfile rm tf1
+} -cleanup {
+ close $fd
+ catch {testchmod 666 tf1}
+ cleanup
+} -returnCodes error -result EACCES
+
+test winFCmd-4.1 {TclpCreateDirectory: errno: EACCES} -body {
+ testfile mkdir $cdrom/dummy~~.dir
+} -constraints {win nt cdrom testfile} -returnCodes error -result EACCES
+test winFCmd-4.2 {TclpCreateDirectory: errno: EACCES} -body {
+ testfile mkdir $cdrom/dummy~~.dir
+} -constraints {win 95 cdrom testfile} -returnCodes error -result ENOSPC
+test winFCmd-4.3 {TclpCreateDirectory: errno: EEXIST} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile mkdir td1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EEXIST
+test winFCmd-4.4 {TclpCreateDirectory: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mkdir td1/td2
+} -returnCodes error -result ENOENT
+test winFCmd-4.5 {TclpCreateDirectory: CreateDirectory succeeds} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mkdir td1
+ file type td1
+} -cleanup cleanup -result directory
+
+test winFCmd-5.1 {TclpCopyDirectory: calls TraverseWinTree} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile cpdir td1 td2
+ list [file type td1] [file type td2]
+} -cleanup {
+ cleanup
+} -result {directory directory}
+
+test winFCmd-6.1 {TclpRemoveDirectory: errno: EACCES} -setup {
+ cleanup
+} -constraints {winVista testfile testchmod} -body {
+ file mkdir td1
+ testchmod 000 td1
+ testfile rmdir td1
+ file exists td1
+} -returnCodes error -cleanup {
+ catch {testchmod 666 td1}
+ cleanup
+} -result {td1 EACCES}
+# This next test has a very hokey way of matching...
+test winFCmd-6.2 {TclpRemoveDirectory: errno: EEXIST} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1/td2
+ list [catch {testfile rmdir td1} msg] [file tail $msg]
+} -result {1 {td1 EEXIST}}
+test winFCmd-6.3 {TclpRemoveDirectory: errno: EACCES} {win emptyTest} {
+ # can't test this w/o removing everything on your hard disk first!
+ # testfile rmdir /
+} {}
+# This next test has a very hokey way of matching...
+test winFCmd-6.4 {TclpRemoveDirectory: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ list [catch {testfile rmdir td1} msg] [file tail $msg]
+} -result {1 {td1 ENOENT}}
+test winFCmd-6.5 {TclpRemoveDirectory: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile rmdir ""
+} -returnCodes error -result ENOENT
+# This next test has a very hokey way of matching...
+test winFCmd-6.6 {TclpRemoveDirectory: errno: ENOTDIR} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ list [catch {testfile rmdir tf1} msg] [file tail $msg]
+} -result {1 {tf1 ENOTDIR}}
+test winFCmd-6.7 {TclpRemoveDirectory: RemoveDirectory succeeds} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile rmdir td1
+ file exists td1
+} -result {0}
+# This next test has a very hokey way of matching...
+test winFCmd-6.8 {TclpRemoveDirectory: RemoveDirectory fails} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ list [catch {testfile rmdir tf1} msg] [file tail $msg]
+} -result {1 {tf1 ENOTDIR}}
+test winFCmd-6.9 {TclpRemoveDirectory: errno == EACCES} -setup {
+ cleanup
+} -constraints {winVista testfile testchmod} -body {
+ file mkdir td1
+ testchmod 000 td1
+ testfile rmdir td1
+ file exists td1
+} -returnCodes error -cleanup {
+ catch {testchmod 666 td1}
+ cleanup
+} -result {td1 EACCES}
+test winFCmd-6.10 {TclpRemoveDirectory: attr == -1} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ testfile rmdir nul
+} -returnCodes error -result {nul EACCES}
+test winFCmd-6.11 {TclpRemoveDirectory: attr == -1} -setup {
+ cleanup
+} -constraints {win nt testfile} -body {
+ testfile rmdir /
+ # WinXP returns EEXIST, WinNT seems to return EACCES. No policy
+ # decision has been made as to which is correct.
+} -returnCodes error -match regexp -result {^/ E(ACCES|EXIST)$}
+# This next test has a very hokey way of matching...
+test winFCmd-6.12 {TclpRemoveDirectory: errno == EACCES} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ createfile tf1
+ set res [catch {testfile rmdir tf1} msg]
+ # get rid of path
+ set msg [list [file tail [lindex $msg 0]] [lindex $msg 1]]
+ list $res $msg
+} -result {1 {tf1 ENOTDIR}}
+test winFCmd-6.13 {TclpRemoveDirectory: write-protected} -setup {
+ cleanup
+} -constraints {winVista testfile testchmod} -body {
+ file mkdir td1
+ testchmod 000 td1
+ testfile rmdir td1
+ file exists td1
+} -cleanup {
+ catch {testchmod 666 td1}
+ cleanup
+} -returnCodes error -result {td1 EACCES}
+# This next test has a very hokey way of matching...
+test winFCmd-6.14 {TclpRemoveDirectory: check if empty dir} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ file mkdir td1/td2
+ set res [catch {testfile rmdir td1} msg]
+ # get rid of path
+ set msg [list [file tail [lindex $msg 0]] [lindex $msg 1]]
+ list $res $msg
+} -result {1 {td1 EEXIST}}
+# This next test has a very hokey way of matching...
+test winFCmd-6.15 {TclpRemoveDirectory: !recursive} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1/td2
+ list [catch {testfile rmdir td1} msg] [file tail $msg]
+} -result {1 {td1 EEXIST}}
+test winFCmd-6.16 {TclpRemoveDirectory: recursive, but errno != EEXIST} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ testfile rmdir -force tf1
+} -returnCodes error -result {tf1 ENOTDIR}
+test winFCmd-6.17 {TclpRemoveDirectory: calls TraverseWinTree} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1/td2
+ testfile rmdir -force td1
+ file exists td1
+} -result {0}
+
+test winFCmd-7.1 {TraverseWinTree: targetPtr == NULL} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1/td2/td3
+ testfile rmdir -force td1
+ file exists td1
+} -result {0}
+test winFCmd-7.2 {TraverseWinTree: targetPtr != NULL} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1/td2/td3
+ testfile cpdir td1 td2
+ list [file exists td1] [file exists td2]
+} -cleanup {
+ cleanup
+} -result {1 1}
+test winFCmd-7.3 {TraverseWinTree: sourceAttr == -1} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile cpdir td1 td2
+} -returnCodes error -result {td1 ENOENT}
+test winFCmd-7.4 {TraverseWinTree: source isn't directory} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testfile cpdir td1 td2
+ contents td2/tf1
+} -cleanup {
+ cleanup
+} -result {tf1}
+test winFCmd-7.5 {TraverseWinTree: call TraversalCopy: DOTREE_F} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testfile cpdir td1 td2
+ contents td2/tf1
+} -cleanup {
+ cleanup
+} -result {tf1}
+test winFCmd-7.6 {TraverseWinTree: call TraversalDelete: DOTREE_F} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testfile rmdir -force td1
+ file exists td1
+} -result {0}
+test winFCmd-7.7 {TraverseWinTree: append \ to source if necessary} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testfile cpdir td1 td2
+ contents td2/tf1
+} -cleanup {
+ cleanup
+} -result {tf1}
+test winFCmd-7.8 {TraverseWinTree: append \ to source if necessary} -body {
+ # cdrom can return either d:\ or D:/, but we only care about the errcode
+ testfile rmdir $cdrom/
+} -constraints {win 95 cdrom testfile} -returnCodes error -match glob \
+ -result {* EACCES} ; # was EEXIST, but changed for win98.
+test winFCmd-7.9 {TraverseWinTree: append \ to source if necessary} -body {
+ testfile rmdir $cdrom/
+} -constraints {win nt cdrom testfile} -returnCodes error -match glob \
+ -result {* EACCES}
+test winFCmd-7.10 {TraverseWinTree: can't read directory: handle == INVALID} \
+ {win emptyTest} {
+ # can't make it happen
+} {}
+test winFCmd-7.11 {TraverseWinTree: call TraversalCopy: DOTREE_PRED} -setup {
+ cleanup
+} -constraints {win testfile testchmod} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testchmod 000 td1
+ testfile cpdir td1 td2
+ list [file exists td2] [file writable td2]
+} -cleanup {
+ catch {testchmod 666 td1}
+ cleanup
+} -result {1 1}
+test winFCmd-7.12 {TraverseWinTree: call TraversalDelete: DOTREE_PRED} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testfile rmdir -force td1
+ file exists td1
+} -result {0}
+test winFCmd-7.13 {TraverseWinTree: append \ to target if necessary} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testfile cpdir td1 td2
+ contents td2/tf1
+} -cleanup {
+ cleanup
+} -result {tf1}
+test winFCmd-7.14 {TraverseWinTree: append \ to target if necessary} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ file mkdir td1
+ testfile cpdir td1 /
+} -cleanup {
+ cleanup
+} -returnCodes error -result {/ EEXIST}
+test winFCmd-7.15 {TraverseWinTree: append \ to target if necessary} -setup {
+ cleanup
+} -constraints {win nt testfile} -body {
+ file mkdir td1
+ testfile cpdir td1 /
+} -cleanup {
+ cleanup
+ # Windows7 returns EEXIST, XP returns EACCES
+} -returnCodes error -match regexp -result {^/ E(ACCES|EXIST)$}
+test winFCmd-7.16 {TraverseWinTree: recurse on files: no files} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile cpdir td1 td2
+} -cleanup {
+ cleanup
+} -result {}
+test winFCmd-7.17 {TraverseWinTree: recurse on files: one file} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/td2
+ testfile cpdir td1 td2
+ glob td2/*
+} -cleanup {
+ cleanup
+} -result {td2/td2}
+test winFCmd-7.18 {TraverseWinTree: recurse on files: several files and dir} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1
+ createfile td1/tf2
+ file mkdir td1/td2/td3
+ createfile td1/tf3
+ createfile td1/tf4
+ testfile cpdir td1 td2
+ lsort [glob td2/*]
+} -cleanup {
+ cleanup
+} -result {td2/td2 td2/tf1 td2/tf2 td2/tf3 td2/tf4}
+test winFCmd-7.19 {TraverseWinTree: call TraversalCopy: DOTREE_POSTD} -setup {
+ cleanup
+} -constraints {win testfile testchmod} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testchmod 000 td1
+ testfile cpdir td1 td2
+ list [file exists td2] [file writable td2]
+} -cleanup {
+ catch {testchmod 666 td1}
+ cleanup
+} -result {1 1}
+test winFCmd-7.20 {TraverseWinTree: call TraversalDelete: DOTREE_POSTD} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testfile rmdir -force td1
+ file exists td1
+} -result {0}
+test winFCmd-7.21 {TraverseWinTree: fill errorPtr} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile cpdir td1 td2
+} -returnCodes error -result {td1 ENOENT}
+
+test winFCmd-8.1 {TraversalCopy: DOTREE_F} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile cpdir td1 td1
+} -returnCodes error -result {td1 EEXIST}
+test winFCmd-8.2 {TraversalCopy: DOTREE_PRED} -setup {
+ cleanup
+} -constraints {win testfile testchmod} -body {
+ file mkdir td1/td2
+ testchmod 000 td1
+ testfile cpdir td1 td2
+ list [file writable td1] [file writable td1/td2]
+} -cleanup {
+ catch {testchmod 666 td1}
+ cleanup
+} -result {0 1}
+test winFCmd-8.3 {TraversalCopy: DOTREE_POSTD} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile cpdir td1 td2
+} -cleanup {
+ cleanup
+} -result {}
+
+test winFCmd-9.1 {TraversalDelete: DOTREE_F} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1
+ testfile rmdir -force td1
+} -result {}
+test winFCmd-9.2 {TraversalDelete: DOTREE_F} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ file mkdir td1
+ set fd [open td1/tf1 w]
+ testfile rmdir -force td1
+} -cleanup {
+ close $fd
+} -returnCodes error -result {td1\tf1 EACCES}
+test winFCmd-9.3 {TraversalDelete: DOTREE_PRED} -setup {
+ cleanup
+} -constraints {winVista testfile testchmod} -body {
+ file mkdir td1/td2
+ testchmod 000 td1
+ testfile rmdir -force td1
+ file exists td1
+} -cleanup {
+ catch {testchmod 666 td1}
+ cleanup
+} -returnCodes error -result {td1 EACCES}
+test winFCmd-9.4 {TraversalDelete: DOTREE_POSTD} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1/td1/td3/td4/td5
+ testfile rmdir -force td1
+} -result {}
+
+test winFCmd-10.1 {AttributesPosixError - get} -constraints {win} -setup {
+ cleanup
+} -body {
+ file attributes td1 -archive
+} -returnCodes error -result {could not read "td1": no such file or directory}
+test winFCmd-10.2 {AttributesPosixError - set} -constraints {win} -setup {
+ cleanup
+} -body {
+ file attributes td1 -archive 0
+} -returnCodes error -result {could not read "td1": no such file or directory}
+
+test winFCmd-11.1 {GetWinFileAttributes} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ file attributes td1 -archive
+} -cleanup {
+ cleanup
+} -result 1
+test winFCmd-11.2 {GetWinFileAttributes} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ file attributes td1 -readonly
+} -cleanup {
+ cleanup
+} -result 0
+test winFCmd-11.3 {GetWinFileAttributes} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ file attributes td1 -hidden
+} -cleanup {
+ cleanup
+} -result 0
+test winFCmd-11.4 {GetWinFileAttributes} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ file attributes td1 -system
+} -cleanup {
+ cleanup
+} -result 0
+test winFCmd-11.5 {GetWinFileAttributes} -constraints {win} -setup {
+ set old [pwd]
+} -body {
+ # Attr of relative paths that resolve to root was failing don't care about
+ # answer, just that test runs.
+ cd c:/
+ file attr c:
+ file attr c:.
+ file attr .
+} -cleanup {
+ cd $old
+} -match glob -result *
+test winFCmd-11.6 {GetWinFileAttributes} -constraints {win} -body {
+ file attr c:/ -hidden
+} -result {0}
+
+test winFCmd-12.1 {ConvertFileNameFormat} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ string tolower [file attributes td1 -longname]
+} -cleanup {
+ cleanup
+} -result {td1}
+test winFCmd-12.2 {ConvertFileNameFormat} -constraints {win} -setup {
+ cleanup
+} -body {
+ file mkdir td1
+ createfile td1/td1 {}
+ string tolower [file attributes td1/td1 -longname]
+} -cleanup {
+ cleanup
+} -result {td1/td1}
+test winFCmd-12.3 {ConvertFileNameFormat} -constraints {win} -setup {
+ cleanup
+} -body {
+ file mkdir td1
+ file mkdir td1/td2
+ createfile td1/td3 {}
+ string tolower [file attributes td1/td2/../td3 -longname]
+} -cleanup {
+ cleanup
+} -result {td1/td2/../td3}
+test winFCmd-12.4 {ConvertFileNameFormat} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ string tolower [file attributes ./td1 -longname]
+} -cleanup {
+ cleanup
+} -result {./td1}
+test winFCmd-12.5 {ConvertFileNameFormat: absolute path} -body {
+ list [file attributes / -longname] [file attributes \\ -longname]
+} -constraints {win} -result {/ /}
+test winFCmd-12.6 {ConvertFileNameFormat: absolute path with drive} -setup {
+ catch {file delete -force -- c:/td1}
+} -constraints {win win2000orXP} -body {
+ createfile c:/td1 {}
+ string tolower [file attributes c:/td1 -longname]
+} -cleanup {
+ file delete -force -- c:/td1
+} -result {c:/td1}
+test winFCmd-12.7 {ConvertFileNameFormat} -body {
+ string tolower [file attributes //bisque/tcl/ws -longname]
+} -constraints {nonPortable win} -result {//bisque/tcl/ws}
+test winFCmd-12.8 {ConvertFileNameFormat} -setup {
+ cleanup
+} -constraints {win longFileNames} -body {
+ createfile td1 {}
+ string tolower [file attributes td1 -longname]
+} -cleanup {
+ cleanup
+} -result {td1}
+test winFCmd-12.10 {ConvertFileNameFormat} -setup {
+ cleanup
+} -constraints {longFileNames win} -body {
+ createfile td1td1td1 {}
+ file attributes td1td1td1 -shortname
+} -cleanup {
+ cleanup
+} -match glob -result *
+test winFCmd-12.11 {ConvertFileNameFormat} -setup {
+ cleanup
+} -constraints {longFileNames win} -body {
+ createfile td1 {}
+ string tolower [file attributes td1 -shortname]
+} -cleanup {
+ cleanup
+} -result {td1}
+
+test winFCmd-13.1 {GetWinFileLongName} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ string tolower [file attributes td1 -longname]
+} -cleanup {
+ cleanup
+} -result td1
+
+test winFCmd-14.1 {GetWinFileShortName} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ string tolower [file attributes td1 -shortname]
+} -cleanup {
+ cleanup
+} -result td1
+
+test winFCmd-15.1 {SetWinFileAttributes} -constraints {win} -setup {
+ cleanup
+} -body {
+ file attributes td1 -archive 0
+} -returnCodes error -result {could not read "td1": no such file or directory}
+test winFCmd-15.2 {SetWinFileAttributes - archive} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ list [file attributes td1 -archive 1] [file attributes td1 -archive]
+} -cleanup {
+ cleanup
+} -result {{} 1}
+test winFCmd-15.3 {SetWinFileAttributes - archive} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ list [file attributes td1 -archive 0] [file attributes td1 -archive]
+} -cleanup {
+ cleanup
+} -result {{} 0}
+test winFCmd-15.4 {SetWinFileAttributes - hidden} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ list [file attributes td1 -hidden 1] [file attributes td1 -hidden] \
+ [file attributes td1 -hidden 0]
+} -cleanup {
+ cleanup
+} -result {{} 1 {}}
+test winFCmd-15.5 {SetWinFileAttributes - hidden} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ list [file attributes td1 -hidden 0] [file attributes td1 -hidden]
+} -cleanup {
+ cleanup
+} -result {{} 0}
+test winFCmd-15.6 {SetWinFileAttributes - readonly} -setup {
+ cleanup
+} -constraints {win} -body {
+ createfile td1 {}
+ list [file attributes td1 -readonly 1] [file attributes td1 -readonly]
+} -cleanup {
+ cleanup
+} -result {{} 1}
+test winFCmd-15.7 {SetWinFileAttributes - readonly} -setup {
+ cleanup
+} -constraints {win} -body {
+ createfile td1 {}
+ list [file attributes td1 -readonly 0] [file attributes td1 -readonly]
+} -cleanup {
+ cleanup
+} -result {{} 0}
+test winFCmd-15.8 {SetWinFileAttributes - system} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ list [file attributes td1 -system 1] [file attributes td1 -system]
+} -cleanup {
+ cleanup
+} -result {{} 1}
+test winFCmd-15.9 {SetWinFileAttributes - system} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ list [file attributes td1 -system 0] [file attributes td1 -system]
+} -cleanup {
+ cleanup
+} -result {{} 0}
+test winFCmd-15.10 {SetWinFileAttributes - failing} -setup {
+ cleanup
+} -constraints {win cdrom} -body {
+ file attributes $cdfile -archive 1
+} -returnCodes error -match glob -result *
+
+test winFCmd-16.1 {Windows file normalization} -constraints {win} -body {
+ list [file normalize c:/] [file normalize C:/]
+} -result {C:/ C:/}
+test winFCmd-16.2 {Windows file normalization} -constraints {win} -body {
+ createfile td1... {}
+ file tail [file normalize td1]
+} -cleanup {
+ file delete td1...
+} -result {td1}
+set pwd [pwd]
+set d [string index $pwd 0]
+test winFCmd-16.3 {Windows file normalization} -constraints {win} -body {
+ file norm ${d}:foo
+} -result [file join $pwd foo]
+test winFCmd-16.4 {Windows file normalization} -constraints {win} -body {
+ file norm [string tolower ${d}]:foo
+} -result [file join $pwd foo]
+test winFCmd-16.5 {Windows file normalization} -constraints {win} -body {
+ file norm ${d}:foo/bar
+} -result [file join $pwd foo/bar]
+test winFCmd-16.6 {Windows file normalization} -constraints {win} -body {
+ file norm ${d}:foo\\bar
+} -result [file join $pwd foo/bar]
+test winFCmd-16.7 {Windows file normalization} -constraints {win} -body {
+ file norm /bar
+} -result "${d}:/bar"
+test winFCmd-16.8 {Windows file normalization} -constraints {win} -body {
+ file norm ///bar
+} -result "${d}:/bar"
+test winFCmd-16.9 {Windows file normalization} -constraints {win} -body {
+ file norm /bar/foo
+} -result "${d}:/bar/foo"
+if {$d eq "C"} { set dd "D" } else { set dd "C" }
+test winFCmd-16.10 {Windows file normalization} -constraints {win} -body {
+ file norm ${dd}:foo
+} -result "${dd}:/foo"
+test winFCmd-16.11 {Windows file normalization} -body {
+ cd ${d}:
+ cd $cdrom
+ cd ${d}:
+ cd $cdrom
+ # Must not crash
+ set result "no crash"
+} -constraints {win cdrom} -cleanup {
+ cd $pwd
+} -result {no crash}
+test winFCmd-16.12 {Windows file normalization - no crash} \
+ -constraints win -setup {
+ set oldhome ""
+ catch {set oldhome $::env(HOME)}
+} -body {
+ set expectedResult [file normalize ${d}:]
+ set ::env(HOME) ${d}:
+ cd
+ # At one point this led to an infinite recursion in Tcl
+ set result [pwd]; # <- Must not crash
+ set result "no crash"
+} -cleanup {
+ set ::env(HOME) $oldhome
+ cd $pwd
+} -result {no crash}
+test winFCmd-16.13 {Windows file normalization - absolute HOME} -setup {
+ set oldhome ""
+ catch {set oldhome $::env(HOME)}
+} -constraints win -body {
+ # Test 'cd' normalization when HOME is absolute
+ set ::env(HOME) ${d}:/
+ cd
+ pwd
+} -cleanup {
+ set ::env(HOME) $oldhome
+ cd $pwd
+} -result [file normalize ${d}:/]
+test winFCmd-16.14 {Windows file normalization - relative HOME} -setup {
+ set oldhome ""
+ catch {set oldhome $::env(HOME)}
+} -constraints win -body {
+ # Test 'cd' normalization when HOME is relative
+ set ::env(HOME) ${d}:
+ cd
+ pwd
+} -cleanup {
+ set ::env(HOME) $oldhome
+ cd $pwd
+} -result $pwd
+
+test winFCmd-17.1 {Windows bad permissions cd} -constraints win -body {
+ set d {}
+ foreach dd {c:/ d:/ e:/} {
+ eval lappend d [glob -nocomplain \
+ -types hidden -dir $dd "System Volume Information"]
+ }
+ # Old versions of Tcl gave a misleading error that the
+ # directory in question didn't exist.
+ if {[llength $d] && [catch {cd [lindex $d 0]} err]} {
+ regsub ".*: " $err "" err
+ set err
+ } else {
+ set err "permission denied"
+ }
+} -cleanup {
+ cd $pwd
+} -result "permission denied"
+
+cd $pwd
+unset d dd pwd
+
+test winFCmd-18.1 {Windows reserved path names} -constraints win -body {
+ file pathtype com1
+} -result "absolute"
+test winFCmd-18.1.2 {Windows reserved path names} -constraints win -body {
+ file pathtype com4
+} -result "absolute"
+test winFCmd-18.1.3 {Windows reserved path names} -constraints win -body {
+ file pathtype com5
+} -result "relative"
+test winFCmd-18.1.4 {Windows reserved path names} -constraints win -body {
+ file pathtype lpt3
+} -result "absolute"
+test winFCmd-18.1.5 {Windows reserved path names} -constraints win -body {
+ file pathtype lpt4
+} -result "relative"
+test winFCmd-18.1.6 {Windows reserved path names} -constraints win -body {
+ file pathtype nul
+} -result "absolute"
+test winFCmd-18.1.7 {Windows reserved path names} -constraints win -body {
+ file pathtype null
+} -result "relative"
+test winFCmd-18.2 {Windows reserved path names} -constraints win -body {
+ file pathtype com1:
+} -result "absolute"
+test winFCmd-18.3 {Windows reserved path names} -constraints win -body {
+ file pathtype COM1
+} -result "absolute"
+test winFCmd-18.4 {Windows reserved path names} -constraints win -body {
+ file pathtype CoM1:
+} -result "absolute"
+test winFCmd-18.5 {Windows reserved path names} -constraints win -body {
+ file normalize com1:
+} -result COM1
+test winFCmd-18.6 {Windows reserved path names} -constraints win -body {
+ file normalize COM1:
+} -result COM1
+test winFCmd-18.7 {Windows reserved path names} -constraints win -body {
+ file normalize cOm1
+} -result COM1
+test winFCmd-18.8 {Windows reserved path names} -constraints win -body {
+ file normalize cOm1:
+} -result COM1
+
+test winFCmd-19.1 {Windows extended path names} -constraints nt -body {
+ file normalize //?/c:/windows/win.ini
+} -result //?/c:/windows/win.ini
+test winFCmd-19.2 {Windows extended path names} -constraints nt -body {
+ file normalize //?/c:/windows/../windows/win.ini
+} -result //?/c:/windows/win.ini
+test winFCmd-19.3 {Windows extended path names} -constraints nt -setup {
+ set tmpfile [file join $::env(TEMP) tcl[string repeat x 20].tmp]
+ set tmpfile [file normalize $tmpfile]
+} -body {
+ list [catch {
+ set f [open $tmpfile [list WRONLY CREAT]]
+ close $f
+ } res] $res
+} -cleanup {
+ catch {file delete $tmpfile}
+} -result [list 0 {}]
+test winFCmd-19.4 {Windows extended path names} -constraints nt -setup {
+ set tmpfile [file join $::env(TEMP) tcl[string repeat x 20].tmp]
+ set tmpfile //?/[file normalize $tmpfile]
+} -body {
+ list [catch {
+ set f [open $tmpfile [list WRONLY CREAT]]
+ close $f
+ } res] $res
+} -cleanup {
+ catch {file delete $tmpfile}
+} -result [list 0 {}]
+test winFCmd-19.5 {Windows extended path names} -constraints nt -setup {
+ set tmpfile [file join $::env(TEMP) tcl[string repeat x 248].tmp]
+ set tmpfile [file normalize $tmpfile]
+} -body {
+ list [catch {
+ set f [open $tmpfile [list WRONLY CREAT]]
+ close $f
+ } res] errormsg ;#$res
+} -cleanup {
+ catch {file delete $tmpfile}
+} -result [list 1 errormsg]
+test winFCmd-19.6 {Windows extended path names} -constraints nt -setup {
+ set tmpfile [file join $::env(TEMP) tcl[string repeat x 248].tmp]
+ set tmpfile //?/[file normalize $tmpfile]
+} -body {
+ list [catch {
+ set f [open $tmpfile [list WRONLY CREAT]]
+ close $f
+ } res] $res
+} -cleanup {
+ catch {file delete $tmpfile}
+} -result [list 0 {}]
+test winFCmd-19.7 {Windows extended path names} -constraints nt -setup {
+ set tmpfile [file join $::env(TEMP) "tcl[pid].tmp "]
+ set tmpfile [file normalize $tmpfile]
+} -body {
+ list [catch {
+ set f [open $tmpfile [list WRONLY CREAT]]
+ close $f
+ } res] $res [glob -directory $::env(TEMP) -tails tcl[pid].*]
+} -cleanup {
+ catch {file delete $tmpfile}
+} -result [list 0 {} [list tcl[pid].tmp]]
+test winFCmd-19.8 {Windows extended path names} -constraints nt -setup {
+ set tmpfile [file join $::env(TEMP) "tcl[pid].tmp "]
+ set tmpfile //?/[file normalize $tmpfile]
+} -body {
+ list [catch {
+ set f [open $tmpfile [list WRONLY CREAT]]
+ close $f
+ } res] $res [glob -directory $::env(TEMP) -tails tcl[pid].*]
+} -cleanup {
+ catch {file delete $tmpfile}
+} -result [list 0 {} [list "tcl[pid].tmp "]]
+
+# This block of code used to occur after the "return" call, so I'm
+# commenting it out and assuming that this code is still under construction.
+#foreach source {tef ted tnf tnd "" nul com1} {
+# foreach chmodsrc {000 755} {
+# foreach dest "tfn tfe tdn tdempty tdfull td1/td2 $p $p/td1 {} nul" {
+# foreach chmoddst {000 755} {
+# puts hi
+# cleanup
+# file delete -force ted tef
+# file mkdir ted
+# createfile tef
+# createfile tfe
+# file mkdir tdempty
+# file mkdir tdfull/td1/td2
+#
+# catch {testchmod $chmodsrc $source}
+# catch {testchmod $chmoddst $dest}
+#
+# if [catch {file rename $source $dest} msg] {
+# puts "file rename $source ($chmodsrc) $dest ($chmoddst)"
+# puts $msg
+# }
+# }
+# }
+# }
+#}
+
+# cleanup
+cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/winFile.test b/library/msgcat/tests/winFile.test
new file mode 100644
index 0000000..ad34624
--- /dev/null
+++ b/library/msgcat/tests/winFile.test
@@ -0,0 +1,239 @@
+# This file tests the tclWinFile.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[catch {package require tcltest 2.0.2}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2.0.2 required."
+ return
+}
+namespace import -force ::tcltest::*
+
+testConstraint testvolumetype [llength [info commands testvolumetype]]
+testConstraint notNTFS 0
+testConstraint win2000 0
+
+if {[testConstraint testvolumetype]} {
+ testConstraint notNTFS [expr {[testvolumetype] eq "NTFS"}]
+}
+if {[testConstraint nt] && $::tcl_platform(osVersion) >= 5.0} {
+ testConstraint win2000 1
+}
+
+test winFile-1.1 {TclpGetUserHome} -constraints {win} -body {
+ glob ~nosuchuser
+} -returnCodes error -result {user "nosuchuser" doesn't exist}
+test winFile-1.2 {TclpGetUserHome} -constraints {win nt nonPortable} -body {
+ # The administrator account should always exist.
+ glob ~administrator
+} -match glob -result *
+test winFile-1.3 {TclpGetUserHome} -constraints {win 95} -body {
+ # Find some user in system.ini and then see if they have a home.
+
+ set f [open $::env(windir)/system.ini]
+ while {[gets $f line] >= 0} {
+ if {$line ne {[Password Lists]}} {
+ continue
+ }
+ gets $f
+ set name [lindex [split [gets $f] =] 0]
+ if {$name ne ""} {
+ return [catch {glob ~$name}]
+ }
+ }
+ return 0 ;# didn't find anything...
+} -cleanup {
+ catch {close $f}
+} -result {0}
+test winFile-1.4 {TclpGetUserHome} {win nt nonPortable} {
+ catch {glob ~stanton@workgroup}
+} {0}
+
+test winFile-2.1 {TclpMatchFiles: case sensitivity} -constraints {win} -body {
+ makeFile {} GlobCapS
+ list [glob -nocomplain GlobC*] [glob -nocomplain globc*]
+} -cleanup {
+ removeFile GlobCapS
+} -result {GlobCapS GlobCapS}
+test winFile-2.2 {TclpMatchFiles: case sensitivity} -constraints {win} -body {
+ makeFile {} globlower
+ list [glob -nocomplain globl*] [glob -nocomplain gLOBl*]
+} -cleanup {
+ removeFile globlower
+} -result {globlower globlower}
+
+test winFile-3.1 {file system} -constraints {win testvolumetype} -setup {
+ set res ""
+} -body {
+ foreach vol [file volumes] {
+ # Have to catch in case there is a removable drive (CDROM, floppy)
+ # with nothing in it.
+ catch {
+ if {[lindex [file system $vol] 1] ne [testvolumetype $vol]} {
+ append res "For $vol, we found [file system $vol]\
+ and [testvolumetype $vol] are different\n"
+ }
+ }
+ }
+ set res
+} -result {}
+
+proc cacls {fname args} {
+ string trim [eval [list exec cacls [file nativename $fname]] $args <<y]
+}
+
+# dir/q output:
+# 2003-11-03 20:36 598 OCTAVIAN\benny filename.txt
+# Note this output from a german win2k machine:
+# 14.12.2007 14:26 30 VORDEFINIERT\Administratest.dat
+#
+# Modified to cope with Msys environment and use ls -l.
+proc getuser {fname} {
+ global env
+ set tryname $fname
+ if {[file isdirectory $fname]} {
+ set tryname [file dirname $fname]
+ }
+ set owner ""
+ set tail [file tail $tryname]
+ if {[info exists env(OSTYPE)] && $env(OSTYPE) eq "msys"} {
+ set dirtext [exec ls -l $fname]
+ foreach line [split $dirtext "\n"] {
+ set owner [lindex $line 2]
+ }
+ } else {
+ set dirtext [exec cmd /c dir /q [file nativename $fname]]
+ foreach line [split $dirtext "\n"] {
+ if {[string match -nocase "*$tail" $line]} {
+ set attrs [string range $line 0 end-[string length $tail]]
+ regexp { [^ \\]+\\.*$} $attrs owner
+ set owner [string trim $owner]
+ }
+ }
+ }
+ if {$owner eq ""} {
+ error "getuser: Owner not found in output of dir/q"
+ }
+ return $owner
+}
+
+proc test_read {fname} {
+ if {[catch {open $fname r} ifs]} {
+ return 0
+ }
+ set readfailed [catch {read $ifs}]
+ return [expr {![catch {close $ifs}] && !$readfailed}]
+}
+
+proc test_writ {fname} {
+ if {[catch {open $fname w} ofs]} {
+ return 0
+ }
+ set writefailed [catch {puts $ofs "Hello"}]
+ return [expr {![catch {close $ofs}] && !$writefailed}]
+}
+
+proc test_access {fname read writ} {
+ set problem {}
+ foreach type {read writ} {
+ if {[set $type] != [file ${type}able $fname]} {
+ lappend problem "[set $type] != \[file ${type}able $fname\]"
+ }
+ if {[set $type] != [test_${type} $fname]} {
+ lappend problem "[set $type] != \[test_${type} $fname\]"
+ }
+ }
+ if {![llength $problem]} {
+ return
+ }
+ return "Problem [join $problem \n]\nActual rights are: [cacls $fname]"
+}
+
+if {[testConstraint win]} {
+ # Create the test file
+ # NOTE: [tcltest::makeFile] not used. Presumably to force file
+ # creation in a particular filesystem? If not, try [makeFile]
+ # in a -setup script.
+ set fname test.dat
+ file delete $fname
+ close [open $fname w]
+}
+
+test winFile-4.0 {
+ Enhanced NTFS user/group permissions: test no acccess
+} -constraints {
+ win nt notNTFS win2000
+} -setup {
+ set owner [getuser $fname]
+ set user $::env(USERDOMAIN)\\$::env(USERNAME)
+} -body {
+ # Clean out all well-known ACLs
+ catch {cacls $fname /E /R "Everyone"} result
+ catch {cacls $fname /E /R $user} result
+ catch {cacls $fname /E /R $owner} result
+ cacls $fname /E /P $user:N
+ test_access $fname 0 0
+} -result {}
+test winFile-4.1 {
+ Enhanced NTFS user/group permissions: test readable only
+} -constraints {
+ win nt notNTFS
+} -setup {
+ set user $::env(USERDOMAIN)\\$::env(USERNAME)
+} -body {
+ cacls $fname /E /P $user:N
+ cacls $fname /E /G $user:R
+ test_access $fname 1 0
+} -result {}
+test winFile-4.2 {
+ Enhanced NTFS user/group permissions: test writable only
+} -constraints {
+ win nt notNTFS
+} -setup {
+ set user $::env(USERDOMAIN)\\$::env(USERNAME)
+} -body {
+ catch {cacls $fname /E /R $user} result
+ cacls $fname /E /P $user:N
+ cacls $fname /E /G $user:W
+ test_access $fname 0 1
+} -result {}
+test winFile-4.3 {
+ Enhanced NTFS user/group permissions: test read+write
+} -constraints {
+ win nt notNTFS
+} -setup {
+ set user $::env(USERDOMAIN)\\$::env(USERNAME)
+} -body {
+ catch {cacls $fname /E /R $user} result
+ cacls $fname /E /P $user:N
+ cacls $fname /E /G $user:R
+ cacls $fname /E /G $user:W
+ test_access $fname 1 1
+} -result {}
+test winFile-4.4 {
+ Enhanced NTFS user/group permissions: test full access
+} -constraints {
+ win nt notNTFS
+} -setup {
+ set user $::env(USERDOMAIN)\\$::env(USERNAME)
+} -body {
+ catch {cacls $fname /E /R $user} result
+ cacls $fname /E /P $user:N
+ cacls $fname /E /G $user:F
+ test_access $fname 1 1
+} -result {}
+
+if {[testConstraint win]} {
+ file delete $fname
+}
+
+# cleanup
+cleanupTests
+return
diff --git a/library/msgcat/tests/winNotify.test b/library/msgcat/tests/winNotify.test
new file mode 100644
index 0000000..f9c75a3
--- /dev/null
+++ b/library/msgcat/tests/winNotify.test
@@ -0,0 +1,159 @@
+# This file tests the tclWinNotify.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testeventloop [expr {[info commands testeventloop] != {}}]
+
+# There is no explicit test for InitNotifier or NotifierExitHandler
+
+test winNotify-1.1 {Tcl_SetTimer: positive timeout} {win} {
+ set done 0
+ after 1000 { set done 1 }
+ vwait done
+ set done
+} 1
+test winNotify-1.2 {Tcl_SetTimer: positive timeout, message pending} {win} {
+ set x 0
+ set y 1
+ set a1 [after 0 { incr y }]
+ after cancel $a1
+ after 500 { incr x }
+ vwait x
+ list $x $y
+} {1 1}
+test winNotify-1.3 {Tcl_SetTimer: cancelling positive timeout} {win} {
+ set x 0
+ set y 1
+ set id [after 10000 { incr y }]
+ after 0 { incr x }
+ vwait x
+ after cancel $id
+ list $x $y
+} {1 1}
+test winNotify-1.4 {Tcl_SetTimer: null timeout, message pending} {win} {
+ set x 0
+ set y 1
+ after 0 { incr x }
+ after 0 { incr y }
+ vwait x
+ list $x $y
+} {1 2}
+
+test winNotify-2.1 {Tcl_ResetIdleTimer} {win} {
+ set x 0
+ update
+ after idle { incr x }
+ vwait x
+ set x
+} 1
+test winNotify-2.2 {Tcl_ResetIdleTimer: message pending} {win} {
+ set x 0
+ set y 1
+ update
+ after idle { incr x }
+ after idle { incr y }
+ update
+ list $x $y
+} {1 2}
+
+test winNotify-3.1 {NotifierProc: non-modal normal timer} {win testeventloop} {
+ update
+ set x 0
+ foreach i [after info] {
+ after cancel $i
+ }
+ after 500 { incr x; testeventloop done }
+ testeventloop wait
+ set x
+} 1
+test winNotify-3.2 {NotifierProc: non-modal normal timer, rescheduled} {win testeventloop} {
+ update
+ set x 0
+ foreach i [after info] {
+ after cancel $i
+ }
+ after 500 { incr x; after 100 {incr x; testeventloop done }}
+ testeventloop wait
+ set x
+} 2
+test winNotify-3.3 {NotifierProc: modal normal timer} {win} {
+ update
+ set x 0
+ foreach i [after info] {
+ after cancel $i
+ }
+ after 500 { incr x }
+ vwait x
+ set x
+} 1
+test winNotify-3.4 {NotifierProc: modal normal timer, rescheduled} {win} {
+ update
+ set x 0
+ foreach i [after info] {
+ after cancel $i
+ }
+ set y 0
+ after 500 { incr y; after 100 {incr x}}
+ vwait x
+ list $x $y
+} {1 1}
+test winNotify-3.5 {NotifierProc: non-modal idle timer} {win testeventloop} {
+ update
+ set x 0
+ foreach i [after info] {
+ after cancel $i
+ }
+ after idle { incr x; testeventloop done }
+ testeventloop wait
+ set x
+} 1
+test winNotify-3.6 {NotifierProc: non-modal idle timer, rescheduled} {win testeventloop} {
+ update
+ set x 0
+ foreach i [after info] {
+ after cancel $i
+ }
+ after idle { incr x; after idle {incr x; testeventloop done }}
+ testeventloop wait
+ set x
+} 2
+test winNotify-3.7 {NotifierProc: modal idle timer} {win} {
+ update
+ set x 0
+ foreach i [after info] {
+ after cancel $i
+ }
+ after idle { incr x }
+ vwait x
+ set x
+} 1
+test winNotify-3.8 {NotifierProc: modal idle timer, rescheduled} {win} {
+ update
+ set x 0
+ foreach i [after info] {
+ after cancel $i
+ }
+ set y 0
+ after idle { incr y; after idle {incr x}}
+ vwait x
+ list $x $y
+} {1 1}
+
+# Tcl_DoOneEvent is tested by the timer.test, io.test, and event.test files
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/winPipe.test b/library/msgcat/tests/winPipe.test
new file mode 100644
index 0000000..62d7d0d
--- /dev/null
+++ b/library/msgcat/tests/winPipe.test
@@ -0,0 +1,450 @@
+#
+# winPipe.test --
+#
+# This file contains a collection of tests for tclWinPipe.c
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output (except for one message) means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest
+namespace import -force ::tcltest::*
+unset -nocomplain path
+
+set bindir [file join [pwd] [file dirname [info nameofexecutable]]]
+set cat32 [file join $bindir cat32.exe]
+
+testConstraint exec [llength [info commands exec]]
+testConstraint cat32 [file exists $cat32]
+testConstraint AllocConsole [catch {puts console1 ""}]
+testConstraint RealConsole [expr {![testConstraint AllocConsole]}]
+
+set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n
+append big $big
+append big $big
+append big $big
+append big $big
+append big $big
+append big $big
+
+set path(little) [makeFile {} little]
+set f [open $path(little) w]
+puts -nonewline $f "little"
+close $f
+
+set path(big) [makeFile {} big]
+set f [open $path(big) w]
+puts -nonewline $f $big
+close $f
+
+proc contents {file} {
+ set f [open $file r]
+ set r [read $f]
+ close $f
+ set r
+}
+
+set path(more) [makeFile {
+ while {[eof stdin] == 0} {
+ puts -nonewline [read stdin]
+ }
+} more]
+
+set path(stdout) [makeFile {} stdout]
+set path(stderr) [makeFile {} stderr]
+
+test winpipe-1.1 {32 bit comprehensive tests: from little file} {win exec cat32} {
+ exec $cat32 < $path(little) > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.2 {32 bit comprehensive tests: from big file} {win exec cat32} {
+ exec $cat32 < $path(big) > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} "{$big} stderr32"
+test winpipe-1.3 {32 bit comprehensive tests: a little from pipe} {win nt exec cat32} {
+ exec [interpreter] $path(more) < $path(little) | $cat32 > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.4 {32 bit comprehensive tests: a lot from pipe} {win nt exec cat32} {
+ exec [interpreter] $path(more) < $path(big) | $cat32 > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} "{$big} stderr32"
+test winpipe-1.5 {32 bit comprehensive tests: a lot from pipe} {win 95 exec cat32} {
+ exec command /c type $path(big) |& $cat32 > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} "{$big} stderr32"
+test winpipe-1.6 {32 bit comprehensive tests: from console} \
+ {win cat32 AllocConsole} {
+ # would block waiting for human input
+} {}
+test winpipe-1.7 {32 bit comprehensive tests: from NUL} {win exec cat32} {
+ exec $cat32 < nul > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} {{} stderr32}
+test winpipe-1.8 {32 bit comprehensive tests: from socket} {win cat32} {
+ # doesn't work
+} {}
+test winpipe-1.9 {32 bit comprehensive tests: from nowhere} \
+ {win exec cat32 RealConsole} {
+ exec $cat32 > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} {{} stderr32}
+test winpipe-1.10 {32 bit comprehensive tests: from file handle} \
+ {win exec cat32} {
+ set f [open $path(little) r]
+ exec $cat32 <@$f > $path(stdout) 2> $path(stderr)
+ close $f
+ list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.11 {32 bit comprehensive tests: read from application} \
+ {win exec cat32} {
+ set f [open "|[list $cat32] < [list $path(little)]" r]
+ gets $f line
+ catch {close $f} msg
+ list $line $msg
+} {little stderr32}
+test winpipe-1.12 {32 bit comprehensive tests: a little to file} \
+ {win exec cat32} {
+ exec $cat32 < $path(little) > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.13 {32 bit comprehensive tests: a lot to file} \
+ {win exec cat32} {
+ exec $cat32 < $path(big) > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} "{$big} stderr32"
+test winpipe-1.14 {32 bit comprehensive tests: a little to pipe} \
+ {win exec stdio cat32} {
+ exec $cat32 < $path(little) | [interpreter] $path(more) > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.15 {32 bit comprehensive tests: a lot to pipe} \
+ {win exec stdio cat32} {
+ exec $cat32 < $path(big) | [interpreter] $path(more) > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} "{$big} stderr32"
+test winpipe-1.16 {32 bit comprehensive tests: to console} {win exec cat32} {
+ catch {exec $cat32 << "You should see this\n" >@stdout} msg
+ set msg
+} stderr32
+test winpipe-1.17 {32 bit comprehensive tests: to NUL} {win exec cat32} {
+ # some apps hang when sending a large amount to NUL. $cat32 isn't one.
+ catch {exec $cat32 < $path(big) > nul} msg
+ set msg
+} stderr32
+test winpipe-1.18 {32 bit comprehensive tests: to nowhere} \
+ {win exec cat32 RealConsole} {
+ exec $cat32 < $path(big) >&@stdout
+} {}
+test winpipe-1.19 {32 bit comprehensive tests: to file handle} {win exec cat32} {
+ set f1 [open $path(stdout) w]
+ set f2 [open $path(stderr) w]
+ exec $cat32 < $path(little) >@$f1 2>@$f2
+ close $f1
+ close $f2
+ list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.20 {32 bit comprehensive tests: write to application} \
+ {win exec cat32} {
+ set f [open |[list $cat32 >$path(stdout)] w]
+ puts -nonewline $f "foo"
+ catch {close $f} msg
+ list [contents $path(stdout)] $msg
+} {foo stderr32}
+test winpipe-1.21 {32 bit comprehensive tests: read/write application} \
+ {win exec cat32} {
+ set f [open "|[list $cat32]" r+]
+ puts $f $big
+ puts $f \032
+ flush $f
+ set r [read $f 64]
+ catch {close $f}
+ set r
+} "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
+test winpipe-1.22 {Checking command.com for Win95/98 hanging} {win 95 exec} {
+ exec command.com /c dir /b
+ set result 1
+} 1
+
+test winpipe-4.1 {Tcl_WaitPid} {win nt exec cat32} {
+ proc readResults {f} {
+ global x result
+ if { [eof $f] } {
+ close $f
+ set x 1
+ } else {
+ set line [read $f ]
+ set result "$result$line"
+ }
+ }
+ set f [open "|[list $cat32] < $path(big) 2> $path(stderr)" r]
+ fconfigure $f -buffering none -blocking 0
+ fileevent $f readable "readResults $f"
+ set x 0
+ set result ""
+ vwait x
+ list $result $x [contents $path(stderr)]
+} "{$big} 1 stderr32"
+test winpipe-4.2 {Tcl_WaitPid: return of exception codes, SIGFPE} {win exec} {
+ set f [open "|[list [interpreter]]" w+]
+ set pid [pid $f]
+ puts $f "testexcept float_underflow"
+ set status [catch {close $f}]
+ list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2]
+} {1 1 SIGFPE}
+test winpipe-4.3 {Tcl_WaitPid: return of exception codes, SIGSEGV} {win exec} {
+ set f [open "|[list [interpreter]]" w+]
+ set pid [pid $f]
+ puts $f "testexcept access_violation"
+ set status [catch {close $f}]
+ list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2]
+} {1 1 SIGSEGV}
+test winpipe-4.4 {Tcl_WaitPid: return of exception codes, SIGILL} {win exec} {
+ set f [open "|[list [interpreter]]" w+]
+ set pid [pid $f]
+ puts $f "testexcept illegal_instruction"
+ set status [catch {close $f}]
+ list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2]
+} {1 1 SIGILL}
+test winpipe-4.5 {Tcl_WaitPid: return of exception codes, SIGINT} {win exec} {
+ set f [open "|[list [interpreter]]" w+]
+ set pid [pid $f]
+ puts $f "testexcept ctrl+c"
+ set status [catch {close $f}]
+ list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2]
+} {1 1 SIGINT}
+
+set path(nothing) [makeFile {} nothing]
+close [open $path(nothing) w]
+
+catch {set env_tmp $env(TMP)}
+catch {set env_temp $env(TEMP)}
+
+set env(TMP) c:/
+set env(TEMP) c:/
+
+test winpipe-5.1 {TclpCreateTempFile: cleanup temp files} {win exec} {
+ set x {}
+ set existing [glob -nocomplain c:/tcl*.tmp]
+ exec [interpreter] < $path(nothing)
+ foreach p [glob -nocomplain c:/tcl*.tmp] {
+ if {$p ni $existing} {
+ lappend x $p
+ }
+ }
+ set x
+} {}
+test winpipe-5.2 {TclpCreateTempFile: TMP and TEMP not defined} {win exec} {
+ set tmp $env(TMP)
+ set temp $env(TEMP)
+ unset env(TMP)
+ unset env(TEMP)
+ exec [interpreter] < $path(nothing)
+ set env(TMP) $tmp
+ set env(TEMP) $temp
+ set x {}
+} {}
+test winpipe-5.3 {TclpCreateTempFile: TMP specifies non-existent directory} \
+ {win exec } {
+ set tmp $env(TMP)
+ set env(TMP) snarky
+ exec [interpreter] < $path(nothing)
+ set env(TMP) $tmp
+ set x {}
+} {}
+test winpipe-5.4 {TclpCreateTempFile: TEMP specifies non-existent directory} \
+ {win exec} {
+ set tmp $env(TMP)
+ set temp $env(TEMP)
+ unset env(TMP)
+ set env(TEMP) snarky
+ exec [interpreter] < $path(nothing)
+ set env(TMP) $tmp
+ set env(TEMP) $temp
+ set x {}
+} {}
+
+test winpipe-6.1 {PipeSetupProc & PipeCheckProc: read threads} \
+ {win exec cat32} {
+ set f [open "|[list $cat32]" r+]
+ fconfigure $f -blocking 0
+ fileevent $f writable { set x writable }
+ set x {}
+ vwait x
+ fileevent $f writable {}
+ fileevent $f readable { lappend x readable }
+ after 100 { lappend x timeout }
+ vwait x
+ puts $f foobar
+ flush $f
+ vwait x
+ lappend x [read $f]
+ after 100 { lappend x timeout }
+ vwait x
+ fconfigure $f -blocking 1
+ lappend x [catch {close $f} msg] $msg
+} {writable timeout readable {foobar
+} timeout 1 stderr32}
+test winpipe-6.2 {PipeSetupProc & PipeCheckProc: write threads} \
+ {win exec cat32} {
+ set f [open "|[list $cat32]" r+]
+ fconfigure $f -blocking 0
+ fileevent $f writable { set x writable }
+ set x {}
+ vwait x
+ puts -nonewline $f $big$big$big$big
+ flush $f
+ after 100 { lappend x timeout }
+ vwait x
+ lappend x [catch {close $f} msg] $msg
+} {writable timeout 0 {}}
+
+set path(echoArgs.tcl) [makeFile {
+ puts "[list $argv0 $argv]"
+} echoArgs.tcl]
+
+### validate the raw output of BuildCommandLine().
+###
+test winpipe-7.1 {BuildCommandLine: null arguments} {win exec} {
+ exec $env(COMSPEC) /c echo foo "" bar
+} {foo "" bar}
+test winpipe-7.2 {BuildCommandLine: null arguments} {win exec} {
+ exec $env(COMSPEC) /c echo foo {} bar
+} {foo "" bar}
+test winpipe-7.3 {BuildCommandLine: dbl quote quoting #1} {win exec} {
+ exec $env(COMSPEC) /c echo foo "\"" bar
+} {foo \" bar}
+test winpipe-7.4 {BuildCommandLine: dbl quote quoting #2} {win exec} {
+ exec $env(COMSPEC) /c echo foo {""} bar
+} {foo \"\" bar}
+test winpipe-7.5 {BuildCommandLine: dbl quote quoting #3} {win exec} {
+ exec $env(COMSPEC) /c echo foo "\" " bar
+} {foo "\" " bar}
+test winpipe-7.6 {BuildCommandLine: dbl quote quoting #4} {win exec} {
+ exec $env(COMSPEC) /c echo foo {a="b"} bar
+} {foo a=\"b\" bar}
+test winpipe-7.7 {BuildCommandLine: dbl quote quoting #5} {win exec} {
+ exec $env(COMSPEC) /c echo foo {a = "b"} bar
+} {foo "a = \"b\"" bar}
+test winpipe-7.8 {BuildCommandLine: dbl quote quoting #6} {win exec} {
+ exec $env(COMSPEC) /c echo {"hello"} {""hello""} {"""hello"""} {"\"hello\""} {he llo} "he \" llo"
+} {\"hello\" \"\"hello\"\" \"\"\"hello\"\"\" \"\\\"hello\\\"\" "he llo" "he \" llo"}
+test winpipe-7.9 {BuildCommandLine: N backslashes followed a quote rule #1} {win exec} {
+ exec $env(COMSPEC) /c echo foo \\ bar
+} {foo \ bar}
+test winpipe-7.10 {BuildCommandLine: N backslashes followed a quote rule #2} {win exec} {
+ exec $env(COMSPEC) /c echo foo \\\\ bar
+} {foo \\ bar}
+test winpipe-7.11 {BuildCommandLine: N backslashes followed a quote rule #3} {win exec} {
+ exec $env(COMSPEC) /c echo foo \\\ \\ bar
+} {foo "\ \\" bar}
+test winpipe-7.12 {BuildCommandLine: N backslashes followed a quote rule #4} {win exec} {
+ exec $env(COMSPEC) /c echo foo \\\ \\\\ bar
+} {foo "\ \\\\" bar}
+test winpipe-7.13 {BuildCommandLine: N backslashes followed a quote rule #5} {win exec} {
+ exec $env(COMSPEC) /c echo foo \\\ \\\\\\ bar
+} {foo "\ \\\\\\" bar}
+test winpipe-7.14 {BuildCommandLine: N backslashes followed a quote rule #6} {win exec} {
+ exec $env(COMSPEC) /c echo foo \\\ \\\" bar
+} {foo "\ \\\"" bar}
+test winpipe-7.15 {BuildCommandLine: N backslashes followed a quote rule #7} {win exec} {
+ exec $env(COMSPEC) /c echo foo \\\ \\\\\" bar
+} {foo "\ \\\\\"" bar}
+test winpipe-7.16 {BuildCommandLine: N backslashes followed a quote rule #8} {win exec} {
+ exec $env(COMSPEC) /c echo foo \\\ \\\\\\\" bar
+} {foo "\ \\\\\\\"" bar}
+test winpipe-7.17 {BuildCommandLine: special chars #4} {win exec} {
+ exec $env(COMSPEC) /c echo foo \{ bar
+} "foo \{ bar"
+test winpipe-7.18 {BuildCommandLine: special chars #5} {win exec} {
+ exec $env(COMSPEC) /c echo foo \} bar
+} "foo \} bar"
+
+### validate the pass-thru from BuildCommandLine() to the crt's parse_cmdline().
+###
+test winpipe-8.1 {BuildCommandLine/parse_cmdline pass-thru: null arguments} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo "" bar
+} [list $path(echoArgs.tcl) [list foo {} bar]]
+test winpipe-8.2 {BuildCommandLine/parse_cmdline pass-thru: null arguments} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo {} bar
+} [list $path(echoArgs.tcl) [list foo {} bar]]
+test winpipe-8.3 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #1} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo "\"" bar
+} [list $path(echoArgs.tcl) [list foo "\"" bar]]
+test winpipe-8.4 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #2} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo {""} bar
+} [list $path(echoArgs.tcl) [list foo {""} bar]]
+test winpipe-8.5 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #3} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo "\" " bar
+} [list $path(echoArgs.tcl) [list foo "\" " bar]]
+test winpipe-8.6 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #4} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo {a="b"} bar
+} [list $path(echoArgs.tcl) [list foo {a="b"} bar]]
+test winpipe-8.7 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #5} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo {a = "b"} bar
+} [list $path(echoArgs.tcl) [list foo {a = "b"} bar]]
+test winpipe-8.8 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #6} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) {"hello"} {""hello""} {"""hello"""} {"\"hello\""} {he llo} {he " llo}
+} [list $path(echoArgs.tcl) [list {"hello"} {""hello""} {"""hello"""} {"\"hello\""} {he llo} {he " llo}]]
+test winpipe-8.9 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #1} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \\ bar
+} [list $path(echoArgs.tcl) [list foo \\ bar]]
+test winpipe-8.10 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #2} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \\\\ bar
+} [list $path(echoArgs.tcl) [list foo \\\\ bar]]
+test winpipe-8.11 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #3} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \\\ \\ bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\ bar]]
+test winpipe-8.12 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #4} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\ bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\\\ bar]]
+test winpipe-8.13 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #5} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\\\ bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\\\\\ bar]]
+test winpipe-8.14 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #6} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\" bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\\" bar]]
+test winpipe-8.15 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #7} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\\" bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\\\\" bar]]
+test winpipe-8.16 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #8} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\\\\" bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\\\\\\" bar]]
+test winpipe-8.17 {BuildCommandLine/parse_cmdline pass-thru: special chars #1} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \{ bar
+} [list $path(echoArgs.tcl) [list foo \{ bar]]
+test winpipe-8.18 {BuildCommandLine/parse_cmdline pass-thru: special chars #2} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \} bar
+} [list $path(echoArgs.tcl) [list foo \} bar]]
+test winpipe-8.19 {ensure parse_cmdline isn't doing wildcard replacement} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo * makefile.?c bar
+} [list $path(echoArgs.tcl) [list foo * makefile.?c bar]]
+
+# restore old values for env(TMP) and env(TEMP)
+
+if {[catch {set env(TMP) $env_tmp}]} {
+ unset env(TMP)
+}
+if {[catch {set env(TEMP) $env_temp}]} {
+ unset env(TEMP)
+}
+
+# cleanup
+removeFile little
+removeFile big
+removeFile more
+removeFile stdout
+removeFile stderr
+removeFile nothing
+removeFile echoArgs.tcl
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/library/msgcat/tests/winTime.test b/library/msgcat/tests/winTime.test
new file mode 100644
index 0000000..278db32
--- /dev/null
+++ b/library/msgcat/tests/winTime.test
@@ -0,0 +1,63 @@
+# This file tests the tclWinTime.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testwinclock [llength [info commands testwinclock]]
+
+# The next two tests will crash on Windows if the check for negative
+# clock values is not done properly.
+
+test winTime-1.1 {TclpGetDate} {win} {
+ set ::env(TZ) JST-9
+ set result [clock format -1 -format %Y]
+ unset ::env(TZ)
+ set result
+} {1970}
+test winTime-1.2 {TclpGetDate} {win} {
+ set ::env(TZ) PST8
+ set result [clock format 1 -format %Y]
+ unset ::env(TZ)
+ set result
+} {1969}
+
+# Next test tries to make sure that the Tcl clock stays in step
+# with the Windows clock. 30 sec really isn't enough,
+# but how much time does a tester have patience for?
+
+test winTime-2.1 {Synchronization of Tcl and Windows clocks} {testwinclock} {
+ # May fail due to OS/hardware discrepancies. See:
+ # http://support.microsoft.com/default.aspx?scid=kb;en-us;274323
+ set failed {}
+ set ok 1
+ foreach start_sec [testwinclock] break
+ while { 1 } {
+ foreach { sys_sec sys_usec tcl_sec tcl_usec } [testwinclock] break
+ set diff [expr { $tcl_sec - $sys_sec
+ + 1.0e-6 * ( $tcl_usec - $sys_usec ) }]
+ if { abs($diff) > 0.06 } {
+ set failed "Tcl clock differs from system clock by $diff sec"
+ break
+ } else {
+ testwinsleep 1
+ }
+ if { $sys_sec - $start_sec >= 30 } break
+ }
+ set failed
+} {}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/library/msgcat/tests/zlib.test b/library/msgcat/tests/zlib.test
new file mode 100644
index 0000000..8212082
--- /dev/null
+++ b/library/msgcat/tests/zlib.test
@@ -0,0 +1,672 @@
+# The file tests the tclZlib.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1996-1998 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2.1
+ namespace import -force ::tcltest::*
+}
+
+testConstraint zlib [llength [info commands zlib]]
+
+test zlib-1.1 {zlib basics} -constraints zlib -returnCodes error -body {
+ zlib
+} -result {wrong # args: should be "zlib command arg ?...?"}
+test zlib-1.2 {zlib basics} -constraints zlib -returnCodes error -body {
+ zlib ? {}
+} -result {bad command "?": must be adler32, compress, crc32, decompress, deflate, gunzip, gzip, inflate, push, or stream}
+
+test zlib-2.1 {zlib compress/decompress} zlib {
+ zlib decompress [zlib compress abcdefghijklm]
+} abcdefghijklm
+
+test zlib-3.1 {zlib deflate/inflate} zlib {
+ zlib inflate [zlib deflate abcdefghijklm]
+} abcdefghijklm
+
+test zlib-4.1 {zlib gzip/gunzip} zlib {
+ zlib gunzip [zlib gzip abcdefghijklm]
+} abcdefghijklm
+test zlib-4.2 {zlib gzip/gunzip} zlib {
+ set s [string repeat abcdef 5]
+ list [zlib gunzip [zlib gzip $s -header {comment gorp}] -header head] \
+ [dict get $head comment] [dict get $head size]
+} {abcdefabcdefabcdefabcdefabcdef gorp 30}
+
+test zlib-5.1 {zlib adler32} zlib {
+ format %x [expr {[zlib adler32 abcdeabcdeabcdeabcdeabcdeabcde] & 0xffffffff}]
+} b3b50b9b
+test zlib-5.2 {zlib adler32} zlib {
+ format %x [expr {[zlib adler32 abcdeabcdeabcdeabcdeabcdeabcde 42] & 0xffffffff}]
+} b8830bc4
+test zlib-5.3 {zlib adler32} -constraints zlib -returnCodes error -body {
+ zlib adler32 abcdeabcdeabcdeabcdeabcdeabcde 42 x
+} -result {wrong # args: should be "zlib adler32 data ?startValue?"}
+
+test zlib-6.1 {zlib crc32} zlib {
+ format %x [expr {[zlib crc32 abcdeabcdeabcdeabcdeabcdeabcde] & 0xffffffff}]
+} 6f73e901
+test zlib-6.2 {zlib crc32} zlib {
+ format %x [expr {[zlib crc32 abcdeabcdeabcdeabcdeabcdeabcde 42] & 0xffffffff}]
+} ce1c4914
+test zlib-6.3 {zlib crc32} -constraints zlib -returnCodes error -body {
+ zlib crc32 abcdeabcdeabcdeabcdeabcdeabcde 42 x
+} -result {wrong # args: should be "zlib crc32 data ?startValue?"}
+test zlib-6.4 {zlib crc32: bug 2662434} -constraints zlib -body {
+ zlib crc32 "dabale arroz a la zorra el abad"
+} -result 3842832571
+
+test zlib-7.0 {zlib stream} -constraints zlib -returnCodes error -setup {
+ set s [zlib stream compress]
+} -body {
+ $s ?
+} -cleanup {
+ $s close
+} -result {bad option "?": must be add, checksum, close, eof, finalize, flush, fullflush, get, put, or reset}
+test zlib-7.1 {zlib stream} zlib {
+ set s [zlib stream compress]
+ $s put -finalize abcdeEDCBA
+ set data [$s get]
+ set result [list [$s get] [format %x [$s checksum]]]
+ $s close
+ lappend result [zlib decompress $data]
+} {{} 136f033f abcdeEDCBA}
+test zlib-7.2 {zlib stream} zlib {
+ set s [zlib stream decompress]
+ $s put -finalize [zlib compress abcdeEDCBA]
+ set data [$s get]
+ set result [list [$s get] [format %x [$s checksum]]]
+ $s close
+ lappend result $data
+} {{} 136f033f abcdeEDCBA}
+test zlib-7.3 {zlib stream} zlib {
+ set s [zlib stream deflate]
+ $s put -finalize abcdeEDCBA
+ set data [$s get]
+ set result [list [$s get] [format %x [$s checksum]]]
+ $s close
+ lappend result [zlib inflate $data]
+} {{} 1 abcdeEDCBA}
+test zlib-7.4 {zlib stream} zlib {
+ set s [zlib stream inflate]
+ $s put -finalize [zlib deflate abcdeEDCBA]
+ set data [$s get]
+ set result [list [$s get] [format %x [$s checksum]]]
+ $s close
+ lappend result $data
+} {{} 1 abcdeEDCBA}
+test zlib-7.5 {zlib stream} zlib {
+ set s [zlib stream gzip]
+ $s put -finalize abcdeEDCBA..
+ set data [$s get]
+ set result [list [$s get] [format %x [$s checksum]]]
+ $s close
+ lappend result [zlib gunzip $data]
+} {{} 69f34b6a abcdeEDCBA..}
+test zlib-7.6 {zlib stream} zlib {
+ set s [zlib stream gunzip]
+ $s put -finalize [zlib gzip abcdeEDCBA..]
+ set data [$s get]
+ set result [list [$s get] [format %x [$s checksum]]]
+ $s close
+ lappend result $data
+} {{} 69f34b6a abcdeEDCBA..}
+
+test zlib-8.1 {zlib transformation} -constraints zlib -setup {
+ set file [makeFile {} test.gz]
+} -body {
+ set f [zlib push gzip [open $file w] -header {comment gorp}]
+ puts $f "ok"
+ close $f
+ set f [zlib push gunzip [open $file]]
+ list [gets $f] [dict get [chan configure $f -header] comment]
+} -cleanup {
+ close $f
+ removeFile $file
+} -result {ok gorp}
+test zlib-8.2 {zlib transformation} -constraints zlib -setup {
+ set file [makeFile {} test.z]
+} -body {
+ set f [zlib push compress [open $file w]]
+ puts $f "ok"
+ close $f
+ set f [zlib push decompress [open $file]]
+ gets $f
+} -cleanup {
+ close $f
+ removeFile $file
+} -result ok
+test zlib-8.3 {zlib transformation and fileevent} -constraints zlib -setup {
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ fconfigure $c -translation binary -buffering none -blocking 0
+ puts -nonewline $c [zlib gzip [string repeat a 81920]]
+ close $c
+ }}} 0]
+ set port [lindex [fconfigure $srv -sockname] 2]
+ set file [makeFile {} test.gz]
+ set fout [open $file wb]
+} -body {
+ set sin [socket localhost $port]
+ try {
+ fconfigure $sin -translation binary
+ zlib push gunzip $sin
+ after 1000 {set total timeout}
+ fcopy $sin $fout -command {apply {{c {e {}}} {
+ set ::total [expr {$e eq {} ? $c : $e}]
+ }}}
+ vwait total
+ after cancel {set total timeout}
+ } finally {
+ close $sin
+ }
+ append total --> [file size $file]
+} -cleanup {
+ close $fout
+ close $srv
+ removeFile $file
+} -result 81920-->81920
+test zlib-8.4 {transformation and flushing: Bug 3517696} -setup {
+ set file [makeFile {} test.z]
+ set fd [open $file w]
+} -constraints zlib -body {
+ zlib push compress $fd
+ puts $fd "qwertyuiop"
+ fconfigure $fd -flush sync
+ puts $fd "qwertyuiop"
+} -cleanup {
+ catch {close $fd}
+ removeFile $file
+} -result {}
+test zlib-8.5 {transformation and flushing and fileevents: Bug 3525907} -setup {
+ foreach {r w} [chan pipe] break
+} -constraints zlib -body {
+ set ::res {}
+ fconfigure $w -buffering none
+ zlib push compress $w
+ puts -nonewline $w qwertyuiop
+ chan configure $w -flush sync
+ after 500 {puts -nonewline $w asdfghjkl;close $w}
+ fconfigure $r -blocking 0 -buffering none
+ zlib push decompress $r
+ fileevent $r readable {set msg [read $r];lappend ::res $msg;if {[eof $r]} {set ::done 1}}
+ after 250 {lappend ::res MIDDLE}
+ vwait ::done
+ set ::res
+} -cleanup {
+ catch {close $r}
+} -result {qwertyuiop MIDDLE asdfghjkl}
+
+test zlib-9.1 "check fcopy with push" -constraints zlib -setup {
+ set sfile [makeFile {} testsrc.gz]
+ set file [makeFile {} test.gz]
+ set f [open $sfile wb]
+ puts -nonewline $f [zlib gzip [string repeat a 81920]]
+ close $f
+} -body {
+ set fin [zlib push gunzip [open $sfile rb]]
+ set fout [open $file wb]
+ set total [fcopy $fin $fout]
+ close $fin ; close $fout
+ list copied $total size [file size $file]
+} -cleanup {
+ removeFile $file
+ removeFile $sfile
+} -result {copied 81920 size 81920}
+test zlib-9.2 "socket fcopy with push" -constraints zlib -setup {
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ puts -nonewline $c [zlib gzip [string repeat a 81920]]
+ close $c
+ }}} 0]
+ set file [makeFile {} test.gz]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ set sin [socket $addr $port]
+ chan configure $sin -translation binary
+ zlib push gunzip $sin
+ update
+ set total [fcopy $sin [set fout [open $file wb]]]
+ close $sin
+ close $fout
+ list read $total size [file size $file]
+} -cleanup {
+ close $srv
+ removeFile $file
+} -result {read 81920 size 81920}
+test zlib-9.3 "socket fcopy bg (identity)" -constraints {tempNotWin zlib} -setup {
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ #puts "connection from $a:$p on $c"
+ chan configure $c -translation binary -buffering none -blocking 0
+ puts -nonewline $c [string repeat a 81920]
+ close $c
+ }}} 0]
+ set file [makeFile {} test.gz]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ #puts "listening for connections on $addr $port"
+ set sin [socket localhost $port]
+ chan configure $sin -translation binary
+ update
+ set fout [open $file wb]
+ after 1000 {set ::total timeout}
+ fcopy $sin $fout -command {apply {{c {e {}}} {
+ set ::total [expr {$e eq {} ? $c : $e}]
+ }}}
+ vwait ::total
+ after cancel {set ::total timeout}
+ close $sin; close $fout
+ list read $::total size [file size $file]
+} -cleanup {
+ close $srv
+ removeFile $file
+} -returnCodes {ok error} -result {read 81920 size 81920}
+test zlib-9.4 "socket fcopy bg (gzip)" -constraints zlib -setup {
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ puts -nonewline $c [zlib gzip [string repeat a 81920]]
+ close $c
+ }}} 0]
+ set file [makeFile {} test.gz]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ set sin [socket $addr $port]
+ chan configure $sin -translation binary
+ zlib push gunzip $sin
+ update
+ set fout [open $file wb]
+ after 1000 {set ::total timeout}
+ fcopy $sin $fout -command {apply {{c {e {}}} {
+ set ::total [expr {$e eq {} ? $c : $e}]
+ }}}
+ vwait ::total
+ after cancel {set ::total timeout}
+ close $sin; close $fout
+ list read $::total size [file size $file]
+} -cleanup {
+ close $srv
+ removeFile $file
+} -result {read 81920 size 81920}
+test zlib-9.5 "socket fcopy incremental (gzip)" -constraints zlib -setup {
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ puts -nonewline $c [zlib gzip [string repeat a 81920]]
+ close $c
+ }}} 0]
+ proc zlib95copy {i o t c {e {}}} {
+ incr t $c
+ if {$e ne {}} {
+ set ::total [list error $e]
+ } elseif {[eof $i]} {
+ set ::total [list eof $t]
+ } else {
+ fcopy $i $o -size 8192 -command [list zlib95copy $i $o $t]
+ }
+ }
+ set file [makeFile {} test.gz]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ set sin [socket $addr $port]
+ chan configure $sin -translation binary
+ zlib push gunzip $sin
+ update
+ set fout [open $file wb]
+ after 1000 {set ::total timeout}
+ fcopy $sin $fout -size 8192 -command [list zlib95copy $sin $fout 0]
+ vwait ::total
+ after cancel {set ::total timeout}
+ close $sin; close $fout
+ list $::total size [file size $file]
+} -cleanup {
+ close $srv
+ rename zlib95copy {}
+ removeFile $file
+} -result {{eof 81920} size 81920}
+test zlib-9.6 "bug #2818131 (gzip)" -constraints zlib -setup {
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ zlib push gzip $c
+ puts -nonewline $c [string repeat hello 100]
+ close $c
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ chan configure $s -translation binary
+ zlib push gunzip $s
+ chan event $s readable [list apply {{s} {
+ set d [read $s]
+ if {[eof $s]} {
+ chan event $s readable {}
+ set ::total [list eof [string length $d]]
+ }
+ }} $s]
+ vwait ::total
+ after cancel {set ::total timeout}
+ close $s
+ set ::total
+} -cleanup {
+ close $srv
+ unset -nocomplain total
+} -result {eof 500}
+test zlib-9.7 "bug #2818131 (compress)" -constraints zlib -setup {
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ zlib push compress $c
+ puts -nonewline $c [string repeat hello 100]
+ close $c
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ chan configure $s -translation binary
+ zlib push decompress $s
+ chan event $s readable [list apply {{s} {
+ set d [read $s]
+ if {[eof $s]} {
+ chan event $s readable {}
+ set ::total [list eof [string length $d]]
+ }
+ }} $s]
+ vwait ::total
+ after cancel {set ::total timeout}
+ close $s
+ set ::total
+} -cleanup {
+ close $srv
+ unset -nocomplain total
+} -result {eof 500}
+test zlib-9.8 "bug #2818131 (deflate)" -constraints zlib -setup {
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ zlib push deflate $c
+ puts -nonewline $c [string repeat hello 100]
+ close $c
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ chan configure $s -translation binary
+ zlib push inflate $s
+ chan event $s readable [list apply {{s} {
+ set d [read $s]
+ if {[eof $s]} {
+ chan event $s readable {}
+ set ::total [list eof [string length $d]]
+ }
+ }} $s]
+ vwait ::total
+ after cancel {set ::total timeout}
+ close $s
+ set ::total
+} -cleanup {
+ unset -nocomplain total
+ close $srv
+} -result {eof 500}
+test zlib-9.9 "bug #2818131 (gzip mismatch)" -constraints zlib -setup {
+ proc bgerror {s} {set ::total [list error $s]}
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ zlib push gzip $c
+ puts -nonewline $c [string repeat hello 100]
+ close $c
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ try {
+ chan configure $s -translation binary
+ zlib push inflate $s
+ chan event $s readable [list apply {{s} {
+ set d [read $s]
+ if {[eof $s]} {
+ chan event $s readable {}
+ set ::total [list eof [string length $d]]
+ }
+ }} $s]
+ vwait ::total
+ } finally {
+ after cancel {set ::total timeout}
+ close $s
+ }
+ set ::total
+} -cleanup {
+ unset -nocomplain total
+ close $srv
+ rename bgerror {}
+} -result {error {invalid block type}}
+test zlib-9.10 "bug #2818131 (compress mismatch)" -constraints zlib -setup {
+ proc bgerror {s} {set ::total [list error $s]}
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ zlib push compress $c
+ puts -nonewline $c [string repeat hello 100]
+ close $c
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ try {
+ chan configure $s -translation binary
+ zlib push inflate $s
+ chan event $s readable [list apply {{s} {
+ set d [read $s]
+ if {[eof $s]} {
+ chan event $s readable {}
+ set ::total [list eof [string length $d]]
+ }
+ }} $s]
+ vwait ::total
+ } finally {
+ after cancel {set ::total timeout}
+ close $s
+ }
+ set ::total
+} -cleanup {
+ unset -nocomplain total
+ close $srv
+ rename bgerror {}
+} -result {error {invalid stored block lengths}}
+test zlib-9.11 "bug #2818131 (deflate mismatch)" -constraints zlib -setup {
+ proc bgerror {s} {set ::total [list error $s]}
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ zlib push deflate $c
+ puts -nonewline $c [string repeat hello 100]
+ close $c
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ try {
+ chan configure $s -translation binary
+ zlib push gunzip $s
+ chan event $s readable [list apply {{s} {
+ set d [read $s]
+ if {[eof $s]} {
+ chan event $s readable {}
+ set ::total [list eof [string length $d]]
+ }
+ }} $s]
+ vwait ::total
+ } finally {
+ after cancel {set ::total timeout}
+ close $s
+ }
+ set ::total
+} -cleanup {
+ unset -nocomplain total
+ close $srv
+ rename bgerror {}
+} -result {error {incorrect header check}}
+
+test zlib-10.0 "bug #2818131 (close with null interp)" -constraints {
+ zlib
+} -setup {
+ proc bgerror {s} {set ::total [list error $s]}
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary
+ zlib push inflate $c
+ chan event $c readable [list apply {{c} {
+ set d [read $c]
+ if {[eof $c]} {
+ chan event $c readable {}
+ close $c
+ set ::total [list eof [string length $d]]
+ }
+ }} $c]
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ chan configure $s -translation binary -buffering none -blocking 0
+ zlib push gzip $s
+ chan event $s xyzzy [list apply {{s} {
+ if {[gets $s line] < 0} {
+ chan close $s
+ }
+ }} $s]
+ after idle [list apply {{s} {
+ puts $s test
+ chan close $s
+ after 100 {set ::total done}
+ }} $s]
+ vwait ::total
+ after cancel {set ::total timeout}
+ after cancel {set ::total done}
+ set ::total
+} -cleanup {
+ close $srv
+ rename bgerror {}
+} -returnCodes error \
+ -result {bad event name "xyzzy": must be readable or writable}
+test zlib-10.1 "bug #2818131 (mismatch read)" -constraints {
+ zlib
+} -setup {
+ proc bgerror {s} {set ::total [list error $s]}
+ proc zlibRead {c} {
+ set d [read $c]
+ if {[eof $c]} {
+ chan event $c readable {}
+ close $c
+ set ::total [list eof [string length $d]]
+ }
+ }
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary
+ zlib push inflate $c
+ chan event $c readable [list zlibRead $c]
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ chan configure $s -translation binary -buffering none -blocking 0
+ zlib push gzip $s
+ chan event $s readable [list zlibRead $s]
+ after idle [list apply {{s} {
+ puts $s test
+ chan close $s
+ after 100 {set ::total done}
+ }} $s]
+ vwait ::total
+ after cancel {set ::total timeout}
+ after cancel {set ::total done}
+ set ::total
+} -cleanup {
+ close $srv
+ rename bgerror {}
+ rename zlibRead {}
+} -result {error {invalid block type}}
+test zlib-10.2 "bug #2818131 (mismatch gets)" -constraints {
+ zlib
+} -setup {
+ proc bgerror {s} {set ::total [list error $s]}
+ proc zlibRead {c} {
+ if {[gets $c line] < 0} {
+ close $c
+ set ::total [list error -1]
+ } elseif {[eof $c]} {
+ chan event $c readable {}
+ close $c
+ set ::total [list eof 0]
+ }
+ }
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary
+ zlib push inflate $c
+ chan event $c readable [list zlibRead $c]
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ chan configure $s -translation binary -buffering none -blocking 0
+ zlib push gzip $s
+ chan event $s readable [list zlibRead $s]
+ after idle [list apply {{s} {
+ puts $s test
+ chan close $s
+ after 100 {set ::total done}
+ }} $s]
+ vwait ::total
+ after cancel {set ::total timeout}
+ after cancel {set ::total done}
+ set ::total
+} -cleanup {
+ close $srv
+ rename bgerror {}
+ rename zlibRead {}
+} -result {error {invalid block type}}
+
+test zlib-11.1 "Bug #3390073: mis-appled gzip filtering" -setup {
+ set file [makeFile {} test.input]
+} -constraints zlib -body {
+ set f [open $file wb]
+ puts -nonewline [zlib push gzip $f] [string repeat "hello" 1000]
+ close $f
+ set f [open $file rb]
+ set d [read $f]
+ close $f
+ set d [zlib gunzip $d]
+ list [regexp -all "hello" $d] [string length [regsub -all "hello" $d {}]]
+} -cleanup {
+ removeFile $file
+} -result {1000 0}
+test zlib-11.2 "Bug #3390073: mis-appled gzip filtering" -setup {
+ set file [makeFile {} test.input]
+} -constraints zlib -body {
+ set f [open $file wb]
+ puts -nonewline [zlib push gzip $f -header {filename /foo/bar}] \
+ [string repeat "hello" 1000]
+ close $f
+ set f [open $file rb]
+ set d [read $f]
+ close $f
+ set d [zlib gunzip $d -header h]
+ list [regexp -all "hello" $d] [dict get $h filename] \
+ [string length [regsub -all "hello" $d {}]]
+} -cleanup {
+ removeFile $file
+} -result {1000 /foo/bar 0}
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/Makefile.in b/pkgs/msgcat/Makefile.in
new file mode 100644
index 0000000..cc60045
--- /dev/null
+++ b/pkgs/msgcat/Makefile.in
@@ -0,0 +1,86 @@
+# TODO: Get libdir and mandir from tclConfig.sh or tclsh?
+# TODO: Get default value of TCLSH_PROG
+
+MIN_TCL = 8.5
+PACKAGE = @PACKAGE_NAME@
+VERSION = @PACKAGE_VERSION@
+
+srcdir = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+mandir = @mandir@
+
+TCLSH_PROG = $(srcdir)/../../unix/tclsh
+DIST_ROOT = /tmp/dist
+
+# Install files under $(DESTDIR)
+INSTALL_ROOT = $(DESTDIR)
+LIB_INSTALL_DIR = $(INSTALL_ROOT)$(libdir)
+MAN_INSTALL_DIR = $(INSTALL_ROOT)$(mandir)
+MANN_INSTALL_DIR = $(MAN_INSTALL_DIR)/mann
+MODULE_INSTALL_DIR = $(LIB_INSTALL_DIR)/tcl8/$(MIN_TCL)
+
+MANTAIL = $(PACKAGE).n
+MANPAGE = $(srcdir)/doc/$(MANTAIL)
+TESTTAIL = $(PACKAGE).test
+TESTFILE = $(srcdir)/tests/$(TESTTAIL)
+SOURCE = $(srcdir)/$(PACKAGE).tcl
+MODULE_STEM = $(PACKAGE)-$(VERSION)
+MODULE = $(MODULE_STEM).tm
+DIST_DIR = $(DIST_ROOT)/$(MODULE_STEM)
+
+all: $(MODULE)
+
+$(MODULE): $(SOURCE)
+ cp -f $< $@
+
+# Test package in place using $(TCLSH_PROG)
+test: $(MODULE)
+ TCL$(subst .,_,$(MIN_TCL))_TM_PATH=. $(TCLSH_PROG) $(TESTFILE)
+
+install: install-module install-doc
+
+install-module: $(MODULE)
+ @echo "Installing package '$(PACKAGE) $(VERSION)' as Tcl Module"
+ @mkdir -p "$(MODULE_INSTALL_DIR)"
+ @cp -f "$(MODULE)" "$(MODULE_INSTALL_DIR)"
+ @chmod 644 "$(MODULE_INSTALL_DIR)/$(MODULE)"
+
+install-doc: $(MANPAGE)
+ @echo "Installing package '$(PACKAGE) $(VERSION)' documentation"
+ @mkdir -p "$(MANN_INSTALL_DIR)"
+ @cp -f "$(MANPAGE)" "$(MANN_INSTALL_DIR)"
+ @chmod 644 "$(MANN_INSTALL_DIR)/$(MANTAIL)"
+
+# Clean away files made by `make all`
+clean:
+ -rm -f $(MODULE)
+
+# Clean away files made by configure
+distclean: clean
+ -rm -f Makefile
+ -rm -f config.log config.status
+
+# TODO
+# Build distribution tarball under $(DIST_ROOT)
+dist: dist-clean
+ mkdir -p $(DIST_DIR)
+
+dist-clean:
+ -rm -rf $(DIST_DIR) $(DIST_ROOT)/$(MODULE_STEM).tar.*
+
+Makefile: $(srcdir)/Makefile.in config.status
+ -rm -f $(MODULE)
+ $(SHELL) config.status
+
+config.status: $(srcdir)/configure
+ $(SHELL) config.status --recheck
+
+$(srcdir)/configure: $(SOURCE)
+ -$(MAKE) -C $(srcdir) -f configure.make \
+ "PACKAGE=$(PACKAGE)" "TCLSH=$(TCLSH_PROG)"
+
+.PHONY: all test install install-module install-doc clean distclean dist
+
diff --git a/pkgs/msgcat/configure b/pkgs/msgcat/configure
new file mode 100755
index 0000000..daf4ab7
--- /dev/null
+++ b/pkgs/msgcat/configure
@@ -0,0 +1,2128 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for msgcat 1.4.3.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete. It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='msgcat'
+PACKAGE_TARNAME='msgcat'
+PACKAGE_VERSION='1.4.3'
+PACKAGE_STRING='msgcat 1.4.3'
+PACKAGE_BUGREPORT=''
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_option in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ eval "enable_$ac_feature=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_$ac_feature='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_$ac_package='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/-/_/g'`
+ eval "with_$ac_package=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+ eval "$ac_envvar='$ac_optarg'"
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+ localstatedir libdir includedir oldincludedir infodir mandir
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+ { (exit 1); exit 1; }; }
+ else
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+ fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+ { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures msgcat 1.4.3 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+ cat <<_ACEOF
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --infodir=DIR info documentation [PREFIX/info]
+ --mandir=DIR man documentation [PREFIX/man]
+_ACEOF
+
+ cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of msgcat 1.4.3:";;
+ esac
+ cat <<\_ACEOF
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ ac_popdir=`pwd`
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d $ac_dir || continue
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+ cd $ac_dir
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_srcdir/configure.gnu; then
+ echo
+ $SHELL $ac_srcdir/configure.gnu --help=recursive
+ elif test -f $ac_srcdir/configure; then
+ echo
+ $SHELL $ac_srcdir/configure --help=recursive
+ elif test -f $ac_srcdir/configure.ac ||
+ test -f $ac_srcdir/configure.in; then
+ echo
+ $ac_configure --help
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi
+ cd $ac_popdir
+ done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+ cat <<\_ACEOF
+msgcat configure 1.4.3
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by msgcat $as_me 1.4.3, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+ # Get rid of the leading space.
+ ac_sep=" "
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+{
+ (set) 2>&1 |
+ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ sed -n \
+ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+ ;;
+ *)
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+}
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ sed "/^$/d" confdefs.h | sort
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core &&
+ rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+ ' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . $cache_file;;
+ *) . ./$cache_file;;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+ eval ac_new_val="\$ac_env_${ac_var}_value"
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_files="$ac_config_files Makefile"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+ (set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+} |
+ sed '
+ t clear
+ : clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+ if test -w $cache_file; then
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[ ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[ ]*$//;
+}'
+fi
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section. Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g
+t quote
+s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[ `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output. A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_i=`echo "$ac_i" |
+ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+ # 2. Add them.
+ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling. Logging --version etc. is OK.
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by msgcat $as_me 1.4.3, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+msgcat config.status 1.4.3
+configured by $0, generated by GNU Autoconf 2.59,
+ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "x$1" : 'x\([^=]*\)='`
+ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ -*)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ *) # This is not an option, so the user has probably given explicit
+ # arguments.
+ ac_option=$1
+ ac_need_defaults=false;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --vers* | -V )
+ echo "$ac_cs_version"; exit 0 ;;
+ --he | --h)
+ # Conflict between --help and --header
+ { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ echo "$ac_cs_usage"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1" ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+ case "$ac_config_target" in
+ # Handling of arguments.
+ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./confstat$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+ # Protect against being on the right side of a sed subst in config.status.
+ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+ cat >>$CONFIG_STATUS <<\_ACEOF
+ # Split the substitutions into bite-sized pieces for seds with
+ # small command number limits, like on Digital OSF/1 and HP-UX.
+ ac_max_sed_lines=48
+ ac_sed_frag=1 # Number of current file.
+ ac_beg=1 # First line for current file.
+ ac_end=$ac_max_sed_lines # Line after last line for current file.
+ ac_more_lines=:
+ ac_sed_cmds=
+ while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ else
+ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ fi
+ if test ! -s $tmp/subs.frag; then
+ ac_more_lines=false
+ else
+ # The purpose of the label and of the branching condition is to
+ # speed up the sed processing (if there are no `@' at all, there
+ # is no need to browse any of the substitutions).
+ # These are the two extra sed commands mentioned above.
+ (echo ':t
+ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+ fi
+ ac_sed_frag=`expr $ac_sed_frag + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_lines`
+ fi
+ done
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+ fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ configure_input=
+ else
+ configure_input="$ac_file. "
+ fi
+ configure_input=$configure_input"Generated from `echo $ac_file_in |
+ sed 's,.*/,,'` by configure."
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+ rm -f $tmp/stdin
+ if test x"$ac_file" != x-; then
+ mv $tmp/out $ac_file
+ else
+ cat $tmp/out
+ rm -f $tmp/out
+ fi
+
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/pkgs/msgcat/configure.in b/pkgs/msgcat/configure.in
new file mode 100644
index 0000000..8bd2b85
--- /dev/null
+++ b/pkgs/msgcat/configure.in
@@ -0,0 +1,2 @@
+AC_INIT([msgcat], [1.4.3])
+AC_OUTPUT([Makefile])
diff --git a/pkgs/msgcat/configure.make b/pkgs/msgcat/configure.make
new file mode 100644
index 0000000..1d2e79e
--- /dev/null
+++ b/pkgs/msgcat/configure.make
@@ -0,0 +1,10 @@
+configure: configure.in
+ -autoconf
+
+configure.in: $(PACKAGE).tcl
+ version=`echo "source $(PACKAGE).tcl; \
+ puts [package provide $(PACKAGE)]" | $(TCLSH)`; \
+ (\
+ echo "AC_INIT([$(PACKAGE)], [$$version])"; \
+ echo "AC_OUTPUT([Makefile])"; \
+ ) > configure.in
diff --git a/pkgs/msgcat/doc/Access.3 b/pkgs/msgcat/doc/Access.3
new file mode 100644
index 0000000..1e82e07
--- /dev/null
+++ b/pkgs/msgcat/doc/Access.3
@@ -0,0 +1,71 @@
+'\"
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_Access 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Access, Tcl_Stat \- check file permissions and other attributes
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_Access\fR(\fIpath\fR, \fImode\fR)
+.sp
+int
+\fBTcl_Stat\fR(\fIpath\fR, \fIstatPtr\fR)
+.SH ARGUMENTS
+.AS "struct stat" *statPtr out
+.AP char *path in
+Native name of the file to check the attributes of.
+.AP int mode in
+Mask consisting of one or more of \fBR_OK\fR, \fBW_OK\fR, \fBX_OK\fR and
+\fBF_OK\fR. \fBR_OK\fR, \fBW_OK\fR and \fBX_OK\fR request checking whether the
+file exists and has read, write and execute permissions, respectively.
+\fBF_OK\fR just requests a check for the existence of the file.
+.AP "struct stat" *statPtr out
+The structure that contains the result.
+.BE
+.SH DESCRIPTION
+.PP
+As of Tcl 8.4, the object-based APIs \fBTcl_FSAccess\fR and \fBTcl_FSStat\fR
+should be used in preference to \fBTcl_Access\fR and \fBTcl_Stat\fR, wherever
+possible. Those functions also support Tcl's virtual filesystem layer, which
+these do not.
+.SS "OBSOLETE FUNCTIONS"
+.PP
+There are two reasons for calling \fBTcl_Access\fR and \fBTcl_Stat\fR rather
+than calling system level functions \fBaccess\fR and \fBstat\fR directly.
+First, the Windows implementation of both functions fixes some bugs in the
+system level calls. Second, both \fBTcl_Access\fR and \fBTcl_Stat\fR (as well
+as \fBTcl_OpenFileChannelProc\fR) hook into a linked list of functions. This
+allows the possibility to reroute file access to alternative media or access
+methods.
+.PP
+\fBTcl_Access\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
+\fIpath\fR. If \fIpath\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.
+.PP
+\fBTcl_Stat\fR fills the stat structure \fIstatPtr\fR with information about
+the specified file. You do not need any access rights to the file to get this
+information but you need search rights to all directories named in the path
+leading to the file. The stat structure includes info regarding device, inode
+(always 0 on Windows), privilege mode, nlink (always 1 on Windows), user id
+(always 0 on Windows), group id (always 0 on Windows), rdev (same as device on
+Windows), size, last access time, last modification time, and creation time.
+.PP
+If \fIpath\fR exists, \fBTcl_Stat\fR returns 0 and the stat structure is
+filled with data. Otherwise, -1 is returned, and no stat info is given.
+.SH KEYWORDS
+stat, access
+.SH "SEE ALSO"
+Tcl_FSAccess(3), Tcl_FSStat(3)
diff --git a/pkgs/msgcat/doc/AddErrInfo.3 b/pkgs/msgcat/doc/AddErrInfo.3
new file mode 100644
index 0000000..e450a3e
--- /dev/null
+++ b/pkgs/msgcat/doc/AddErrInfo.3
@@ -0,0 +1,312 @@
+'\"
+'\" Copyright (c) 1989-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.
+'\"
+.so man.macros
+.TH Tcl_AddErrorInfo 3 8.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_GetReturnOptions, Tcl_SetReturnOptions, Tcl_AddErrorInfo, Tcl_AppendObjToErrorInfo, Tcl_AddObjErrorInfo, Tcl_SetObjErrorCode, Tcl_SetErrorCode, Tcl_SetErrorCodeVA, Tcl_SetErrorLine, Tcl_GetErrorLine, Tcl_PosixError, Tcl_LogCommandInfo \- retrieve or record information about errors and other return options
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_GetReturnOptions\fR(\fIinterp, code\fR)
+.sp
+int
+\fBTcl_SetReturnOptions\fR(\fIinterp, options\fR)
+.sp
+\fBTcl_AddErrorInfo\fR(\fIinterp, message\fR)
+.sp
+\fBTcl_AppendObjToErrorInfo\fR(\fIinterp, objPtr\fR)
+.sp
+\fBTcl_AddObjErrorInfo\fR(\fIinterp, message, length\fR)
+.sp
+\fBTcl_SetObjErrorCode\fR(\fIinterp, errorObjPtr\fR)
+.sp
+\fBTcl_SetErrorCode\fR(\fIinterp, element, element, ... \fB(char *) NULL\fR)
+.sp
+\fBTcl_SetErrorCodeVA\fR(\fIinterp, argList\fR)
+.sp
+\fBTcl_GetErrorLine\fR(\fIinterp\fR)
+.sp
+\fBTcl_SetErrorLine\fR(\fIinterp, lineNum\fR)
+.sp
+const char *
+\fBTcl_PosixError\fR(\fIinterp\fR)
+.sp
+void
+\fBTcl_LogCommandInfo\fR(\fIinterp, script, command, commandLength\fR)
+.SH ARGUMENTS
+.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 \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.
+.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.
+.AP int length in
+The number of bytes to copy from \fImessage\fR when
+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
+The \fB\-errorcode\fR return option will be set to this value.
+.AP char *element in
+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
+\fBva_start\fR, and cleared using \fBva_end\fR.
+.AP int lineNum
+The line number of a script where an error occurred.
+.AP "const char" *script in
+Pointer to first character in script containing command (must be <= command)
+.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
+.BE
+.SH DESCRIPTION
+.PP
+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.
+As with any \fBTcl_Obj\fR with reference count of zero, it is up to
+the caller to arrange for its disposal with \fBTcl_DecrRefCount\fR or
+to a reference to it via \fBTcl_IncrRefCount\fR (or one of the many
+functions that call that, notably including \fBTcl_SetObjResult\fR and
+\fBTcl_SetVar2Ex\fR).
+.PP
+A typical usage for \fBTcl_GetReturnOptions\fR is to
+retrieve the stack trace when script evaluation returns
+\fBTCL_ERROR\fR, like so:
+.PP
+.CS
+int code = Tcl_Eval(interp, script);
+if (code == TCL_ERROR) {
+ Tcl_Obj *options = \fBTcl_GetReturnOptions\fR(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 */
+ Tcl_DecrRefCount(options);
+}
+.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:
+.PP
+.CS
+if ((objc % 2) == 0) { /* explicit result argument */
+ objc--;
+ Tcl_SetObjResult(interp, objv[objc]);
+}
+return \fBTcl_SetReturnOptions\fR(interp, Tcl_NewListObj(objc-1, objv+1));
+.CE
+.PP
+(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. The \fB\-errorline\fR
+return option is also read by commands that evaluate scripts
+and wish to supply detailed error location information in
+the stack trace text they append to the \fB\-errorinfo\fR option.
+Tcl provides several simpler interfaces to more directly set
+these return options.
+.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 \fB\-errorcode\fR option holds a list of items that
+are intended to be machine-readable.
+The first item in the \fB\-errorcode\fR value identifies the class of
+error that occurred
+(e.g. POSIX means an error occurred in a POSIX system call)
+and additional elements hold additional pieces
+of information that depend on the class.
+See the \fBtclvars\fR manual entry for details on the various
+formats for the \fB\-errorcode\fR option used by
+Tcl's built-in commands.
+.PP
+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_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
+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_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
+\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.
+.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
+\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
+the \fB\-errorcode\fR return option to \fBNONE\fR.
+.PP
+The procedure \fBTcl_SetErrorCode\fR is also used to set the
+\fB\-errorcode\fR return option. However, it takes one or more strings to
+record instead of an object. Otherwise, it is similar to
+\fBTcl_SetObjErrorCode\fR in behavior.
+.PP
+\fBTcl_SetErrorCodeVA\fR is the same as \fBTcl_SetErrorCode\fR except that
+instead of taking a variable number of arguments it takes an argument list.
+.PP
+The procedure \fBTcl_GetErrorLine\fR is used to read the integer value
+of the \fB\-errorline\fR return option without the overhead of a full
+call to \fBTcl_GetReturnOptions\fR. Likewise, \fBTcl_SetErrorLine\fR
+sets the \fB\-errorline\fR return option value.
+.PP
+\fBTcl_PosixError\fR
+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 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
+occurs in a dynamically loaded extension. See the manual entry for
+\fBTcl_SetErrno\fR for more information.
+.PP
+\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 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 \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 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.
+.PP
+If the procedure \fBTcl_ResetResult\fR is called,
+it clears all of the state of the interpreter associated with
+script evaluation, including the entire return options dictionary.
+In particular, the \fB\-errorinfo\fR and \fB\-errorcode\fR options
+are reset.
+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(3), Tcl_IncrRefCount(3), Tcl_Interp(3), Tcl_ResetResult(3),
+Tcl_SetErrno(3), tclvars(n)
+.SH KEYWORDS
+error, object, object result, stack, trace, variable
diff --git a/pkgs/msgcat/doc/Alloc.3 b/pkgs/msgcat/doc/Alloc.3
new file mode 100644
index 0000000..ca4f949
--- /dev/null
+++ b/pkgs/msgcat/doc/Alloc.3
@@ -0,0 +1,92 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_Alloc 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Alloc, Tcl_Free, Tcl_Realloc, Tcl_AttemptAlloc, Tcl_AttemptRealloc, ckalloc, ckfree, ckrealloc, attemptckalloc, attemptckrealloc \- allocate or free heap memory
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+char *
+\fBTcl_Alloc\fR(\fIsize\fR)
+.sp
+void
+\fBTcl_Free\fR(\fIptr\fR)
+.sp
+char *
+\fBTcl_Realloc\fR(\fIptr, size\fR)
+.sp
+char *
+\fBTcl_AttemptAlloc\fR(\fIsize\fR)
+.sp
+char *
+\fBTcl_AttemptRealloc\fR(\fIptr, size\fR)
+.sp
+char *
+\fBckalloc\fR(\fIsize\fR)
+.sp
+void
+\fBckfree\fR(\fIptr\fR)
+.sp
+char *
+\fBckrealloc\fR(\fIptr, size\fR)
+.sp
+char *
+\fBattemptckalloc\fR(\fIsize\fR)
+.sp
+char *
+\fBattemptckrealloc\fR(\fIptr, size\fR)
+.SH ARGUMENTS
+.AS char *size
+.AP "unsigned int" size in
+Size in bytes of the memory block to allocate.
+.AP char *ptr in
+Pointer to memory block to free or realloc.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures provide a platform and compiler independent interface
+for memory allocation. Programs that need to transfer ownership of
+memory blocks between Tcl and other modules should use these routines
+rather than the native \fBmalloc()\fR and \fBfree()\fR routines
+provided by the C run-time library.
+.PP
+\fBTcl_Alloc\fR returns a pointer to a block of at least \fIsize\fR
+bytes suitably aligned for any use.
+.PP
+\fBTcl_Free\fR makes the space referred to by \fIptr\fR available for
+further allocation.
+.PP
+\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. 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, 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 procedures. To support Tcl's memory debugging within a
+module, use the macros rather than direct calls to \fBTcl_Alloc\fR, etc.
+
+.SH KEYWORDS
+alloc, allocation, free, malloc, memory, realloc, TCL_MEM_DEBUG
diff --git a/pkgs/msgcat/doc/AllowExc.3 b/pkgs/msgcat/doc/AllowExc.3
new file mode 100644
index 0000000..ae595f1
--- /dev/null
+++ b/pkgs/msgcat/doc/AllowExc.3
@@ -0,0 +1,44 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_AllowExceptions 3 7.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_AllowExceptions \- allow all exceptions in next script evaluation
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_AllowExceptions\fR(\fIinterp\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Interpreter in which script will be evaluated.
+.BE
+
+.SH DESCRIPTION
+.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 \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,
+\fBTcl_GlobalEval\fR, \fBTcl_GlobalEvalObj\fR, \fBTcl_VarEval\fR and
+\fBTcl_VarEvalVA\fR.
+.PP
+However, if \fBTcl_AllowExceptions\fR is invoked immediately before
+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 \fBTCL_BREAK\fR or \fBTCL_CONTINUE\fR in a meaningful way.
+
+.SH KEYWORDS
+continue, break, exception, interpreter
diff --git a/pkgs/msgcat/doc/AppInit.3 b/pkgs/msgcat/doc/AppInit.3
new file mode 100644
index 0000000..e4ae971
--- /dev/null
+++ b/pkgs/msgcat/doc/AppInit.3
@@ -0,0 +1,83 @@
+'\"
+'\" 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 Tcl_AppInit 3 7.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_AppInit \- perform application-specific initialization
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_AppInit\fR(\fIinterp\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Interpreter for the application.
+.BE
+
+.SH DESCRIPTION
+.PP
+\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.
+To create a new application you write a new version of
+\fBTcl_AppInit\fR to replace the default version provided by Tcl,
+then link your new \fBTcl_AppInit\fR with the Tcl library.
+.PP
+\fBTcl_AppInit\fR is invoked by \fBTcl_Main\fR and \fBTk_Main\fR
+after their own initialization and before entering the main loop
+to process commands.
+Here are some examples of things that \fBTcl_AppInit\fR might do:
+.IP [1]
+Call initialization procedures for various packages used by
+the application.
+Each initialization procedure adds new commands to \fIinterp\fR
+for its package and performs other package-specific initialization.
+.IP [2]
+Process command-line arguments, which can be accessed from the
+Tcl variables \fBargv\fR and \fBargv0\fR in \fIinterp\fR.
+.IP [3]
+Invoke a startup script to initialize the application.
+.IP [4]
+Use the routines \fBTcl_SetStartupScript\fR and
+\fBTcl_GetStartupScript\fR to set or query the file and encoding
+that the active \fBTcl_Main\fR or \fBTk_Main\fR routine will
+use as a startup script.
+.LP
+\fBTcl_AppInit\fR returns \fBTCL_OK\fR or \fBTCL_ERROR\fR.
+If it returns \fBTCL_ERROR\fR then it must leave an error message in
+for the interpreter's result; otherwise the result is ignored.
+.PP
+In addition to \fBTcl_AppInit\fR, your application should also contain
+a procedure \fBmain\fR that calls \fBTcl_Main\fR as follows:
+.PP
+.CS
+Tcl_Main(argc, argv, Tcl_AppInit);
+.CE
+.PP
+The third argument to \fBTcl_Main\fR gives the address of the
+application-specific initialization procedure to invoke.
+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).
+The best way to get started is to make a copy of the file
+\fBtclAppInit.c\fR from the Tcl library or source directory.
+It already contains a \fBmain\fR procedure and a template for
+\fBTcl_AppInit\fR that you can modify for your application.
+
+.SH "SEE ALSO"
+Tcl_Main(3)
+
+.SH KEYWORDS
+application, argument, command, initialization, interpreter
diff --git a/pkgs/msgcat/doc/AssocData.3 b/pkgs/msgcat/doc/AssocData.3
new file mode 100644
index 0000000..59c26a4
--- /dev/null
+++ b/pkgs/msgcat/doc/AssocData.3
@@ -0,0 +1,87 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.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
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+ClientData
+\fBTcl_GetAssocData\fR(\fIinterp, key, delProcPtr\fR)
+.sp
+\fBTcl_SetAssocData\fR(\fIinterp, key, delProc, clientData\fR)
+.sp
+\fBTcl_DeleteAssocData\fR(\fIinterp, key\fR)
+.SH ARGUMENTS
+.AS Tcl_InterpDeleteProc **delProcPtr
+.AP Tcl_Interp *interp in
+Interpreter in which to execute the specified command.
+.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
+Procedure to call when \fIinterp\fR is deleted.
+.AP Tcl_InterpDeleteProc **delProcPtr in
+Pointer to location in which to store address of current deletion procedure
+for association. Ignored if NULL.
+.AP ClientData clientData in
+Arbitrary one-word value associated with the given key in this
+interpreter. This data is owned by the caller.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures allow extensions to associate their own data with
+a Tcl interpreter.
+An association consists of a string key, typically the name of
+the extension, and a one-word value, which is typically a pointer
+to a data structure holding data specific to the extension.
+Tcl makes no interpretation of either the key or the value for
+an association.
+.PP
+Storage management is facilitated by storing with each association a
+procedure to call when the interpreter is deleted. This
+procedure can dispose of the storage occupied by the client's data in any
+way it sees fit.
+.PP
+\fBTcl_SetAssocData\fR creates an association between a string
+key and a user specified datum in the given interpreter.
+If there is already an association with the given \fIkey\fR,
+\fBTcl_SetAssocData\fR overwrites it with the new information.
+It is up to callers to organize their use of names to avoid conflicts,
+for example, by using package names as the keys.
+If the \fIdeleteProc\fR argument is non-NULL it specifies the address of a
+procedure to invoke if the interpreter is deleted before the association
+is deleted. \fIDeleteProc\fR should have arguments and result that match
+the type \fBTcl_InterpDeleteProc\fR:
+.PP
+.CS
+typedef void \fBTcl_InterpDeleteProc\fR(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+When \fIdeleteProc\fR is invoked the \fIclientData\fR and \fIinterp\fR
+arguments will be the same as the corresponding arguments passed to
+\fBTcl_SetAssocData\fR.
+The deletion procedure will \fInot\fR be invoked if the association
+is deleted before the interpreter is deleted.
+.PP
+\fBTcl_GetAssocData\fR returns the datum stored in the association with the
+specified key in the given interpreter, and if the \fIdelProcPtr\fR field
+is non-\fBNULL\fR, the address indicated by it gets the address of the
+delete procedure stored with this association. If no association with the
+specified key exists in the given interpreter \fBTcl_GetAssocData\fR
+returns \fBNULL\fR.
+.PP
+\fBTcl_DeleteAssocData\fR deletes an association with a specified key in
+the given interpreter. Then it calls the deletion procedure.
+.SH KEYWORDS
+association, data, deletion procedure, interpreter, key
diff --git a/pkgs/msgcat/doc/Async.3 b/pkgs/msgcat/doc/Async.3
new file mode 100644
index 0000000..d02f76d
--- /dev/null
+++ b/pkgs/msgcat/doc/Async.3
@@ -0,0 +1,161 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_AsyncCreate 3 7.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_AsyncCreate, Tcl_AsyncMark, Tcl_AsyncInvoke, Tcl_AsyncDelete, Tcl_AsyncReady \- handle asynchronous events
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_AsyncHandler
+\fBTcl_AsyncCreate\fR(\fIproc, clientData\fR)
+.sp
+\fBTcl_AsyncMark\fR(\fIasync\fR)
+.sp
+int
+\fBTcl_AsyncInvoke\fR(\fIinterp, code\fR)
+.sp
+\fBTcl_AsyncDelete\fR(\fIasync\fR)
+.sp
+int
+\fBTcl_AsyncReady\fR()
+.SH ARGUMENTS
+.AS Tcl_AsyncHandler clientData
+.AP Tcl_AsyncProc *proc in
+Procedure to invoke to handle an asynchronous event.
+.AP ClientData clientData in
+One-word value to pass to \fIproc\fR.
+.AP Tcl_AsyncHandler async in
+Token for asynchronous event handler.
+.AP Tcl_Interp *interp in
+Tcl interpreter in which command was being evaluated when handler was
+invoked, or NULL if handler was invoked when there was no interpreter
+active.
+.AP int code in
+Completion code from command that just completed in \fIinterp\fR,
+or 0 if \fIinterp\fR is NULL.
+.BE
+
+.SH DESCRIPTION
+.PP
+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 is not safe to take any substantive action to
+process the event.
+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.
+The only safe approach is to set a flag indicating that the event
+occurred, then handle the event later when the world has returned
+to a clean state, such as after the current Tcl command completes.
+.PP
+\fBTcl_AsyncCreate\fR, \fBTcl_AsyncDelete\fR, and \fBTcl_AsyncReady\fR
+are thread sensitive. They access and/or set a thread-specific data
+structure in the event of a core built with \fI\-\-enable\-threads\fR. The token
+created by \fBTcl_AsyncCreate\fR contains the needed thread information it
+was called from so that calling \fBTcl_AsyncMark\fR(\fItoken\fR) will only yield
+the origin thread into the asynchronous handler.
+.PP
+\fBTcl_AsyncCreate\fR creates an asynchronous handler and returns
+a token for it.
+The asynchronous handler must be created before
+any occurrences of the asynchronous event that it is intended
+to handle (it is not safe to create a handler at the time of
+an event).
+When an asynchronous event occurs the code that detects the event
+(such as a signal handler) should call \fBTcl_AsyncMark\fR with the
+token for the handler.
+\fBTcl_AsyncMark\fR will mark the handler as ready to execute, but it
+will not invoke the handler immediately.
+Tcl will call the \fIproc\fR associated with the handler later, when
+the world is in a safe state, and \fIproc\fR can then carry out
+the actions associated with the asynchronous event.
+\fIProc\fR should have arguments and result that match the
+type \fBTcl_AsyncProc\fR:
+.PP
+.CS
+typedef int \fBTcl_AsyncProc\fR(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ int \fIcode\fR);
+.CE
+.PP
+The \fIclientData\fR will be the same as the \fIclientData\fR
+argument passed to \fBTcl_AsyncCreate\fR when the handler was
+created.
+If \fIproc\fR is invoked just after a command has completed
+execution in an interpreter, then \fIinterp\fR will identify
+the interpreter in which the command was evaluated and
+\fIcode\fR will be the completion code returned by that
+command.
+The command's result will be present in the interpreter's result.
+When \fIproc\fR returns, whatever it leaves in the interpreter's result
+will be returned as the result of the command and the integer
+value returned by \fIproc\fR will be used as the new completion
+code for the command.
+.PP
+It is also possible for \fIproc\fR to be invoked when no interpreter
+is active.
+This can happen, for example, if an asynchronous event occurs while
+the application is waiting for interactive input or an X event.
+In this case \fIinterp\fR will be NULL and \fIcode\fR will be
+0, and the return value from \fIproc\fR will be ignored.
+.PP
+The procedure \fBTcl_AsyncInvoke\fR is called to invoke all of the
+handlers that are ready.
+The procedure \fBTcl_AsyncReady\fR will return non-zero whenever any
+asynchronous handlers are ready; it can be checked to avoid calls
+to \fBTcl_AsyncInvoke\fR when there are no ready handlers.
+Tcl calls \fBTcl_AsyncReady\fR after each command is evaluated
+and calls \fBTcl_AsyncInvoke\fR if needed.
+Applications may also call \fBTcl_AsyncInvoke\fR at interesting
+times for that application.
+For example, Tcl's event handler calls \fBTcl_AsyncReady\fR
+after each event and calls \fBTcl_AsyncInvoke\fR if needed.
+The \fIinterp\fR and \fIcode\fR arguments to \fBTcl_AsyncInvoke\fR
+have the same meaning as for \fIproc\fR: they identify the active
+interpreter, if any, and the completion code from the command
+that just completed.
+.PP
+\fBTcl_AsyncDelete\fR removes an asynchronous handler so that
+its \fIproc\fR will never be invoked again.
+A handler can be deleted even when ready, and it will still
+not be invoked.
+.PP
+If multiple handlers become active at the same time, the
+handlers are invoked in the order they were created (oldest
+handler first).
+The \fIcode\fR and the interpreter's result for later handlers
+reflect the values returned by earlier handlers, so that
+the most recently created handler has last say about
+the interpreter's result and completion code.
+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
+handler to modify the interpreter's result or return a code different
+from its \fIcode\fR argument.
+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 state by calling
+\fBTcl_SaveInterpState\fR, passing in the \fIcode\fR argument.
+When the asynchronous handler is finished it should restore
+the interpreter's state by calling \fBTcl_RestoreInterpState\fR,
+and then returning the \fIcode\fR argument.
+
+.SH KEYWORDS
+asynchronous event, handler, signal, Tcl_SaveInterpState, thread
diff --git a/pkgs/msgcat/doc/BackgdErr.3 b/pkgs/msgcat/doc/BackgdErr.3
new file mode 100644
index 0000000..3116671
--- /dev/null
+++ b/pkgs/msgcat/doc/BackgdErr.3
@@ -0,0 +1,78 @@
+'\"
+'\" Copyright (c) 1992-1994 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 Tcl_BackgroundError 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_BackgroundException, Tcl_BackgroundError \- report Tcl exception that occurred in background processing
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_BackgroundException\fR(\fIinterp, code\fR)
+.sp
+\fBTcl_BackgroundError\fR(\fIinterp\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Interpreter in which the exception occurred.
+.AP int code in
+The exceptional return code to be reported.
+.BE
+
+.SH DESCRIPTION
+.PP
+This procedure is typically invoked when a Tcl exception (any
+return code other than TCL_OK) occurs during
+.QW "background processing"
+such as executing an event handler.
+When such an exception occurs, the 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 exception to the user.
+In these cases the code calls \fBTcl_BackgroundException\fR with an
+\fIinterp\fR argument identifying the interpreter in which the
+exception occurred, and a \fIcode\fR argument holding the return
+code value of the exception. The state of the interpreter, including
+any error message in the interpreter result, and the values of
+any entries in the return options dictionary, is captured and
+saved. \fBTcl_BackgroundException\fR then arranges for the event
+loop to invoke at some later time the command registered
+in that interpreter to handle background errors by the
+\fBinterp bgerror\fR command, passing the captured values as
+arguments.
+The registered handler command is meant to report the exception
+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_BackgroundException\fR reports the
+error itself by printing a message on the standard error file.
+.PP
+\fBTcl_BackgroundException\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 the handler command later as an idle callback.
+.PP
+It is possible for many background exceptions to accumulate before
+the handler command is invoked. When this happens, each of the exceptions
+is processed in order. However, if the handler command returns a
+break exception, then all remaining error reports for the
+interpreter are skipped.
+.PP
+The \fBTcl_BackgroundError\fR routine is an older and simpler interface
+useful when the exception code reported is \fBTCL_ERROR\fR. It is
+equivalent to:
+.PP
+.CS
+Tcl_BackgroundException(interp, TCL_ERROR);
+.CE
+
+.SH KEYWORDS
+background, bgerror, error, interp
diff --git a/pkgs/msgcat/doc/Backslash.3 b/pkgs/msgcat/doc/Backslash.3
new file mode 100644
index 0000000..8b399fc
--- /dev/null
+++ b/pkgs/msgcat/doc/Backslash.3
@@ -0,0 +1,47 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_Backslash 3 "8.1" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Backslash \- parse a backslash sequence
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+char
+\fBTcl_Backslash\fR(\fIsrc, countPtr\fR)
+.SH ARGUMENTS
+.AS char *countPtr out
+.AP char *src in
+Pointer to a string starting with a backslash.
+.AP int *countPtr out
+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
+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.
+\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.
+.SH "SEE ALSO"
+Tcl(n), Tcl_UtfBackslash(3)
+
+.SH KEYWORDS
+backslash, parse
diff --git a/pkgs/msgcat/doc/BoolObj.3 b/pkgs/msgcat/doc/BoolObj.3
new file mode 100644
index 0000000..395d159
--- /dev/null
+++ b/pkgs/msgcat/doc/BoolObj.3
@@ -0,0 +1,95 @@
+'\"
+'\" 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.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_NewBooleanObj, Tcl_SetBooleanObj, Tcl_GetBooleanFromObj \- store/retrieve boolean value in a Tcl_Obj
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewBooleanObj\fR(\fIboolValue\fR)
+.sp
+\fBTcl_SetBooleanObj\fR(\fIobjPtr, boolValue\fR)
+.sp
+int
+\fBTcl_GetBooleanFromObj\fR(\fIinterp, objPtr, boolPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp boolValue in/out
+.AP int boolValue in
+Integer value to be stored as a boolean value in a Tcl_Obj.
+.AP Tcl_Obj *objPtr in/out
+Points to the Tcl_Obj in which to store, or from which to
+retrieve a boolean value.
+.AP Tcl_Interp *interp in/out
+If a boolean value cannot be retrieved,
+an error message is left in the interpreter's result object
+unless \fIinterp\fR is NULL.
+.AP int *boolPtr out
+Points to place where \fBTcl_GetBooleanFromObj\fR
+stores the boolean value (0 or 1) obtained from \fIobjPtr\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+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_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_IsShared, Tcl_GetBoolean
+
+.SH KEYWORDS
+boolean, object
diff --git a/pkgs/msgcat/doc/ByteArrObj.3 b/pkgs/msgcat/doc/ByteArrObj.3
new file mode 100644
index 0000000..77c94ac
--- /dev/null
+++ b/pkgs/msgcat/doc/ByteArrObj.3
@@ -0,0 +1,91 @@
+'\"
+'\" 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 Tcl_ByteArrayObj 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_NewByteArrayObj, Tcl_SetByteArrayObj, Tcl_GetByteArrayFromObj, Tcl_SetByteArrayLength \- manipulate Tcl objects as a arrays of bytes
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewByteArrayObj\fR(\fIbytes, length\fR)
+.sp
+void
+\fBTcl_SetByteArrayObj\fR(\fIobjPtr, bytes, length\fR)
+.sp
+unsigned char *
+\fBTcl_GetByteArrayFromObj\fR(\fIobjPtr, lengthPtr\fR)
+.sp
+unsigned char *
+\fBTcl_SetByteArrayLength\fR(\fIobjPtr, length\fR)
+.SH ARGUMENTS
+.AS "const unsigned char" *lengthPtr in/out
+.AP "const unsigned char" *bytes in
+The array of bytes used to initialize or set a byte-array object. May be NULL
+even if \fIlength\fR is non-zero.
+.AP int length in
+The length of the array of bytes. It must be >= 0.
+.AP Tcl_Obj *objPtr in/out
+For \fBTcl_SetByteArrayObj\fR, this points to the object to be converted to
+byte-array type. For \fBTcl_GetByteArrayFromObj\fR and
+\fBTcl_SetByteArrayLength\fR, this points to the object from which to get
+the byte-array value; if \fIobjPtr\fR does not already point to a byte-array
+object, it will be converted to one.
+.AP int *lengthPtr out
+If non-NULL, filled with the length of the array of bytes in the object.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures are used to create, modify, and read Tcl byte-array objects
+from C code. Byte-array objects are typically used to hold the
+results of binary IO operations or data structures created with the
+\fBbinary\fR command. In Tcl, an array of bytes is not equivalent to a
+string. Conceptually, a string is an array of Unicode characters, while a
+byte-array is an array of 8-bit quantities with no implicit meaning.
+Accessor functions are provided to get the string representation of a
+byte-array or to convert an arbitrary object to a byte-array. Obtaining the
+string representation of a byte-array object (by calling
+\fBTcl_GetStringFromObj\fR) produces a properly formed UTF-8 sequence with a
+one-to-one mapping between the bytes in the internal representation and the
+UTF-8 characters in the string representation.
+.PP
+\fBTcl_NewByteArrayObj\fR and \fBTcl_SetByteArrayObj\fR will
+create a new object of byte-array type or modify an existing object to have a
+byte-array type. Both of these procedures set the object's type to be
+byte-array and set the object's internal representation to a copy of the
+array of bytes given by \fIbytes\fR. \fBTcl_NewByteArrayObj\fR returns a
+pointer to a newly allocated object with a reference count of zero.
+\fBTcl_SetByteArrayObj\fR invalidates any old string representation and, if
+the object is not already a byte-array object, frees any old internal
+representation. If \fIbytes\fR is NULL then the new byte array contains
+arbitrary values.
+.PP
+\fBTcl_GetByteArrayFromObj\fR converts a Tcl object to byte-array type and
+returns a pointer to the object's new internal representation as an array of
+bytes. The length of this array is stored in \fIlengthPtr\fR if
+\fIlengthPtr\fR is non-NULL. The storage for the array of bytes is owned by
+the object and should not be freed. The contents of the array may be
+modified by the caller only if the object is not shared and the caller
+invalidates the string representation.
+.PP
+\fBTcl_SetByteArrayLength\fR converts the Tcl object to byte-array type
+and changes the length of the object's internal representation as an
+array of bytes. If \fIlength\fR is greater than the space currently
+allocated for the array, the array is reallocated to the new length; the
+newly allocated bytes at the end of the array have arbitrary values. If
+\fIlength\fR is less than the space currently allocated for the array,
+the length of array is reduced to the new length. The return value is a
+pointer to the object's new array of bytes.
+
+.SH "SEE ALSO"
+Tcl_GetStringFromObj, Tcl_NewObj, Tcl_IncrRefCount, Tcl_DecrRefCount
+
+.SH KEYWORDS
+object, byte array, utf, unicode, internationalization
diff --git a/pkgs/msgcat/doc/CallDel.3 b/pkgs/msgcat/doc/CallDel.3
new file mode 100644
index 0000000..dec4392
--- /dev/null
+++ b/pkgs/msgcat/doc/CallDel.3
@@ -0,0 +1,67 @@
+'\"
+'\" 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 Tcl_CallWhenDeleted 3 7.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CallWhenDeleted, Tcl_DontCallWhenDeleted \- Arrange for callback when interpreter is deleted
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_CallWhenDeleted\fR(\fIinterp\fR, \fIproc\fR, \fIclientData\fR)
+.sp
+\fBTcl_DontCallWhenDeleted\fR(\fIinterp\fR, \fIproc\fR, \fIclientData\fR)
+.SH ARGUMENTS
+.AS Tcl_InterpDeleteProc clientData
+.AP Tcl_Interp *interp in
+Interpreter with which to associated callback.
+.AP Tcl_InterpDeleteProc *proc in
+Procedure to call when \fIinterp\fR is deleted.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CallWhenDeleted\fR arranges for \fIproc\fR to be called by
+\fBTcl_DeleteInterp\fR if/when \fIinterp\fR is deleted at some future
+time. \fIProc\fR will be invoked just before the interpreter
+is deleted, but the interpreter will still be valid at the
+time of the call.
+\fIProc\fR should have arguments and result that match the
+type \fBTcl_InterpDeleteProc\fR:
+.PP
+.CS
+typedef void \fBTcl_InterpDeleteProc\fR(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+The \fIclientData\fR and \fIinterp\fR parameters are
+copies of the \fIclientData\fR and \fIinterp\fR arguments given
+to \fBTcl_CallWhenDeleted\fR.
+Typically, \fIclientData\fR points to an application-specific
+data structure that \fIproc\fR uses to perform cleanup when an
+interpreter is about to go away.
+\fIProc\fR does not return a value.
+.PP
+\fBTcl_DontCallWhenDeleted\fR cancels a previous call to
+\fBTcl_CallWhenDeleted\fR with the same arguments, so that
+\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
+\fBTcl_DontCallWhenDeleted\fR has no effect.
+.PP
+Note that if the callback is being used to delete a resource that \fImust\fR
+be released on exit, \fBTcl_CreateExitHandler\fR should be used to ensure that
+a callback is received even if the application terminates without deleting the interpreter.
+.SH "SEE ALSO"
+Tcl_CreateExitHandler(3), Tcl_CreateThreadExitHandler(3)
+.SH KEYWORDS
+callback, cleanup, delete, interpreter
diff --git a/pkgs/msgcat/doc/Cancel.3 b/pkgs/msgcat/doc/Cancel.3
new file mode 100644
index 0000000..80db3a3
--- /dev/null
+++ b/pkgs/msgcat/doc/Cancel.3
@@ -0,0 +1,66 @@
+'\"
+'\" Copyright (c) 2006-2008 Joe Mistachkin.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_Cancel 3 8.6 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CancelEval, Tcl_Canceled \- cancel Tcl scripts
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+int
+\fBTcl_CancelEval\fR(\fIinterp, clientData, flags\fR)
+.sp
+int
+\fBTcl_Canceled\fR(\fIinterp, flags\fR)
+.SH ARGUMENTS
+.AP Tcl_Interp *interp in
+Interpreter in which to cancel the script.
+.AP int flags in
+ORed combination of flag bits that specify additional options.
+For \fBTcl_CancelEval\fR, only \fBTCL_CANCEL_UNWIND\fR is currently
+supported. For \fBTcl_Canceled\fR, only \fBTCL_LEAVE_ERR_MSG\fR and
+\fBTCL_CANCEL_UNWIND\fR are currently supported.
+.AP ClientData clientData in
+Currently, reserved for future use.
+It should be set to NULL.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CancelEval\fR cancels or unwinds the script in progress soon after
+the next invocation of asynchronous handlers, causing \fBTCL_ERROR\fR to be
+the return code for that script. This function is thread-safe and may be
+called from any thread in the process.
+.PP
+\fBTcl_Canceled\fR checks if the script in progress has been canceled and
+returns \fBTCL_ERROR\fR if it has. Otherwise, \fBTCL_OK\fR is returned.
+Extensions can use this function to check to see if they should abort a long
+running command. This function is thread sensitive and may only be called
+from the thread the interpreter was created in.
+.SH "FLAG BITS"
+Any ORed combination of the following values may be used for the
+\fIflags\fR argument to procedures such as \fBTcl_CancelEval\fR:
+.TP 23
+\fBTCL_CANCEL_UNWIND\fR
+This flag is used by \fBTcl_CancelEval\fR and \fBTcl_Canceled\fR.
+For \fBTcl_CancelEval\fR, if this flag is set, the script in progress
+is canceled and the evaluation stack for the interpreter is unwound.
+For \fBTcl_Canceled\fR, if this flag is set, the script in progress
+is considered to be canceled only if the evaluation stack for the
+interpreter is being unwound.
+.TP 23
+\fBTCL_LEAVE_ERR_MSG\fR
+This flag is only used by \fBTcl_Canceled\fR; it is ignored by
+other procedures. 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 is not set then no error
+message is left and the interpreter's result will not be modified.
+.SH "SEE ALSO"
+TIP 285
+.SH KEYWORDS
+cancel, unwind
diff --git a/pkgs/msgcat/doc/ChnlStack.3 b/pkgs/msgcat/doc/ChnlStack.3
new file mode 100644
index 0000000..9ec38b4
--- /dev/null
+++ b/pkgs/msgcat/doc/ChnlStack.3
@@ -0,0 +1,97 @@
+'\"
+'\" Copyright (c) 1999-2000 Ajuba Solutions.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+.so man.macros
+.TH Tcl_StackChannel 3 8.3 Tcl "Tcl Library Procedures"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_StackChannel, Tcl_UnstackChannel, Tcl_GetStackedChannel, Tcl_GetTopChannel \- manipulate stacked I/O channels
+.SH SYNOPSIS
+.nf
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Channel
+\fBTcl_StackChannel\fR(\fIinterp, typePtr, clientData, mask, channel\fR)
+.sp
+int
+\fBTcl_UnstackChannel\fR(\fIinterp, channel\fR)
+.sp
+Tcl_Channel
+\fBTcl_GetStackedChannel\fR(\fIchannel\fR)
+.sp
+Tcl_Channel
+\fBTcl_GetTopChannel\fR(\fIchannel\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_ChannelType clientData
+.AP Tcl_Interp *interp in
+Interpreter for error reporting.
+.AP "const Tcl_ChannelType" *typePtr in
+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\fR.
+.AP Tcl_Channel channel in
+An existing Tcl channel such as returned by \fBTcl_CreateChannel\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+These functions are for use by extensions that add processing layers to Tcl
+I/O channels. Examples include compression and encryption modules. These
+functions transparently stack and unstack a new channel on top of an
+existing one. Any number of channels can be stacked together.
+.PP
+The implementation of the Tcl channel code was rewritten in 8.3.2 to
+correct some problems with the previous implementation with regard to
+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\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
+buffering options are shared between all channels in the stack. The hidden
+channel does no buffering, newline translations, or character set encoding.
+Instead, the buffering, newline translations, and encoding functions all
+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\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.
+.PP
+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\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\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
+\fBTcl_GetTopChannel\fR returns the top channel in the stack of
+channels the supplied channel is part of.
+.PP
+\fBTcl_GetStackedChannel\fR returns the channel in the stack of
+channels which is just below the supplied channel.
+
+.SH "SEE ALSO"
+Notifier(3), Tcl_CreateChannel(3), Tcl_OpenFileChannel(3), vwait(n).
+
+.SH KEYWORDS
+channel, compression
diff --git a/pkgs/msgcat/doc/Class.3 b/pkgs/msgcat/doc/Class.3
new file mode 100644
index 0000000..28cea9b
--- /dev/null
+++ b/pkgs/msgcat/doc/Class.3
@@ -0,0 +1,236 @@
+'\"
+'\" Copyright (c) 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 Tcl_Class 3 0.1 TclOO "TclOO Library Functions"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_ClassGetMetadata, Tcl_ClassSetMetadata, Tcl_CopyObjectInstance, Tcl_GetClassAsObject, Tcl_GetObjectAsClass, Tcl_GetObjectCommand, Tcl_GetObjectFromObj, Tcl_GetObjectName, Tcl_GetObjectNamespace, Tcl_NewObjectInstance, Tcl_ObjectDeleted, Tcl_ObjectGetMetadata, Tcl_ObjectGetMethodNameMapper, Tcl_ObjectSetMetadata, Tcl_ObjectSetMethodNameMapper \- manipulate objects and classes
+.SH SYNOPSIS
+.nf
+\fB#include <tclOO.h>\fR
+.sp
+Tcl_Object
+\fBTcl_GetObjectFromObj\fR(\fIinterp, objPtr\fR)
+.sp
+Tcl_Object
+\fBTcl_GetClassAsObject\fR(\fIclass\fR)
+.sp
+Tcl_Class
+\fBTcl_GetObjectAsClass\fR(\fIobject\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetObjectName\fR(\fIinterp, object\fR)
+.sp
+Tcl_Command
+\fBTcl_GetObjectCommand\fR(\fIobject\fR)
+.sp
+Tcl_Namespace *
+\fBTcl_GetObjectNamespace\fR(\fIobject\fR)
+.sp
+Tcl_Object
+\fBTcl_NewObjectInstance\fR(\fIinterp, class, name, nsName, objc, objv, skip\fR)
+.sp
+Tcl_Object
+\fBTcl_CopyObjectInstance\fR(\fIinterp, object, name, nsName\fR)
+.sp
+int
+\fBTcl_ObjectDeleted\fR(\fIobject\fR)
+.sp
+ClientData
+\fBTcl_ObjectGetMetadata\fR(\fIobject, metaTypePtr\fR)
+.sp
+\fBTcl_ObjectSetMetadata\fR(\fIobject, metaTypePtr, metadata\fR)
+.sp
+ClientData
+\fBTcl_ClassGetMetadata\fR(\fIclass, metaTypePtr\fR)
+.sp
+\fBTcl_ClassSetMetadata\fR(\fIclass, metaTypePtr, metadata\fR)
+.sp
+Tcl_ObjectMapMethodNameProc
+\fBTcl_ObjectGetMethodNameMapper\fR(\fIobject\fR)
+.sp
+\fBTcl_ObjectSetMethodNameMapper\fR(\fIobject\fR, \fImethodNameMapper\fR)
+.SH ARGUMENTS
+.AS ClientData metadata in/out
+.AP Tcl_Interp *interp in/out
+Interpreter providing the context for looking up or creating an object, and
+into whose result error messages will be written on failure.
+.AP Tcl_Obj *objPtr in
+The name of the object to look up.
+.AP Tcl_Object object in
+Reference to the object to operate upon.
+.AP Tcl_Class class in
+Reference to the class to operate upon.
+.AP "const char" *name in
+The name of the object to create, or NULL if a new unused name is to be
+automatically selected.
+.AP "const char" *nsName in
+The name of the namespace to create for the object's private use, or NULL if a
+new unused name is to be automatically selected.
+.AP int objc in
+The number of elements in the \fIobjv\fR array.
+.AP "Tcl_Obj *const" *objv in
+The arguments to the command to create the instance of the class.
+.AP int skip in
+The number of arguments at the start of the argument array, \fIobjv\fR, that
+are not arguments to any constructors.
+.AP Tcl_ObjectMetadataType *metaTypePtr in
+The type of \fImetadata\fR being set with \fBTcl_ClassSetMetadata\fR or
+retrieved with \fBTcl_ClassGetMetadata\fR.
+.AP ClientData metadata in
+An item of metadata to attach to the class, or NULL to remove the metadata
+associated with a particular \fImetaTypePtr\fR.
+.AP "Tcl_ObjectMapMethodNameProc" "methodNameMapper" in
+A pointer to a function to call to adjust the mapping of objects and method
+names to implementations, or NULL when no such mapping is required.
+.BE
+.SH DESCRIPTION
+.PP
+Objects are typed entities that have a set of operations ("methods")
+associated with them. Classes are objects that can manufacture objects. Each
+class can be viewed as an object itself; the object view can be retrieved
+using \fBTcl_GetClassAsObject\fR which always returns the object when applied
+to a non-destroyed class, and an object can be viewed as a class with the aid
+of the \fBTcl_GetObjectAsClass\fR (which either returns the class, or NULL if
+the object is not a class). An object may be looked up using the
+\fBTcl_GetObjectFromObj\fR function, which either returns an object or NULL
+(with an error message in the interpreter result) if the object cannot be
+found. The correct way to look up a class by name is to look up the object
+with that name, and then to use \fBTcl_GetObjectAsClass\fR.
+.PP
+Every object has its own command and namespace associated with it. The command
+may be retrieved using the \fBTcl_GetObjectCommand\fR function, the name of
+the object (and hence the name of the command) with \fBTcl_GetObjectName\fR,
+and the namespace may be retrieved using the \fBTcl_GetObjectNamespace\fR
+function. Note that the Tcl_Obj reference returned by \fBTcl_GetObjectName\fR
+is a shared reference.
+.PP
+Instances of classes are created using \fBTcl_NewObjectInstance\fR, which
+takes creates an object from any class (and which is internally called by both
+the \fBcreate\fR and \fBnew\fR methods of the \fBoo::class\fR class). It takes
+parameters that optionally give the name of the object and namespace to
+create, and which describe the arguments to pass to the class's constructor
+(if any). The result of the function will be either a reference to the newly
+created object, or NULL if the creation failed (when an error message will be
+left in the interpreter result). In addition, objects may be copied by using
+\fBTcl_CopyObjectInstance\fR which creates a copy of an object without running
+any constructors.
+.SH "OBJECT AND CLASS METADATA"
+.PP
+Every object and every class may have arbitrary amounts of metadata attached
+to it, which the object or class attaches no meaning to beyond what is
+described in a Tcl_ObjectMetadataType structure instance. Metadata to be
+attached is described by the type of the metadata (given in the
+\fImetaTypePtr\fR argument) and an arbitrary pointer (the \fImetadata\fR
+argument) that are given to \fBTcl_ObjectSetMetadata\fR and
+\fBTcl_ClassSetMetadata\fR, and a particular piece of metadata can be
+retrieved given its type using \fBTcl_ObjectGetMetadata\fR and
+\fBTcl_ClassGetMetadata\fR. If the \fImetadata\fR parameter to either
+\fBTcl_ObjectSetMetadata\fR or \fBTcl_ClassSetMetadata\fR is NULL, the
+metadata is removed if it was attached, and the results of
+\fBTcl_ObjectGetMetadata\fR and \fBTcl_ClassGetMetadata\fR are NULL if the
+given type of metadata was not attached. It is not an error to request or
+remove a piece of metadata that was not attached.
+.SS "TCL_OBJECTMETADATATYPE STRUCTURE"
+.PP
+The contents of the Tcl_ObjectMetadataType structure are as follows:
+.PP
+.CS
+typedef const struct {
+ int \fIversion\fR;
+ const char *\fIname\fR;
+ Tcl_ObjectMetadataDeleteProc *\fIdeleteProc\fR;
+ Tcl_CloneProc *\fIcloneProc\fR;
+} \fBTcl_ObjectMetadataType\fR;
+.CE
+.PP
+The \fIversion\fR field allows for future expansion of the structure, and
+should always be declared equal to TCL_OO_METADATA_VERSION_CURRENT. The
+\fIname\fR field provides a human-readable name for the type, and is reserved
+for debugging.
+.PP
+The \fIdeleteProc\fR field gives a function of type
+Tcl_ObjectMetadataDeleteProc that is used to delete a particular piece of
+metadata, and is called when the attached metadata is replaced or removed; the
+field must not be NULL.
+.PP
+The \fIcloneProc\fR field gives a function that is used to copy a piece of
+metadata (used when a copy of an object is created using
+\fBTcl_CopyObjectInstance\fR); if NULL, the metadata will be just directly
+copied.
+.SS "TCL_OBJECTMETADATADELETEPROC FUNCTION SIGNATURE"
+.PP
+Functions matching this signature are used to delete metadata associated with
+a class or object.
+.PP
+.CS
+typedef void \fBTcl_ObjectMetadataDeleteProc\fR(
+ ClientData \fImetadata\fR);
+.CE
+.PP
+The \fImetadata\fR argument gives the address of the metadata to be
+deleted.
+.SS "TCL_CLONEPROC FUNCTION SIGNATURE"
+.PP
+Functions matching this signature are used to create copies of metadata
+associated with a class or object.
+.PP
+.CS
+typedef int \fBTcl_CloneProc\fR(
+ Tcl_Interp *\fIinterp\fR,
+ ClientData \fIsrcMetadata\fR,
+ ClientData *\fIdstMetadataPtr\fR);
+.CE
+.PP
+The \fIinterp\fR argument gives a place to write an error message when the
+attempt to clone the object is to fail, in which case the clone procedure must
+also return TCL_ERROR; it should return TCL_OK otherwise.
+The \fIsrcMetadata\fR argument gives the address of the metadata to be cloned,
+and the cloned metadata should be written into the variable pointed to by
+\fIdstMetadataPtr\fR; a NULL should be written if the metadata is to not be
+cloned but the overall object copy operation is still to succeed.
+.SH "OBJECT METHOD NAME MAPPING"
+It is possible to control, on a per-object basis, what methods are invoked
+when a particular method is invoked. Normally this is done by looking up the
+method name in the object and then in the class hierarchy, but fine control of
+exactly what the value used to perform the look up is afforded through the
+ability to set a method name mapper callback via
+\fBTcl_ObjectSetMethodNameMapper\fR (and its introspection counterpart,
+\fBTcl_ObjectGetMethodNameMapper\fR, which returns the current mapper). The
+current mapper (if any) is invoked immediately before looking up what chain of
+method implementations is to be used.
+.SS "TCL_OBJECTMAPMETHODNAMEPROC FUNCTION SIGNATURE"
+The \fITcl_ObjectMapMethodNameProc\fR callback is defined as follows:
+.PP
+.CS
+typedef int \fBTcl_ObjectMapMethodNameProc\fR(
+ Tcl_Interp *\fIinterp\fR,
+ Tcl_Object \fIobject\fR,
+ Tcl_Class *\fIstartClsPtr\fR,
+ Tcl_Obj *\fImethodNameObj\fR);
+.CE
+.PP
+If the result is TCL_OK, the remapping is assumed to have been done. If the
+result is TCL_ERROR, an error message will have been left in \fIinterp\fR and
+the method call will fail. If the result is TCL_BREAK, the standard method
+name lookup rules will be used; the behavior of other result codes is
+currently undefined. The \fIobject\fR parameter says which object is being
+processed. The \fIstartClsPtr\fR parameter points to a variable that contains
+the first class to provide a definition in the method chain to process, or
+NULL if the whole chain is to be processed (the argument itself is never
+NULL); this variable may be updated by the callback. The \fImethodNameObj\fR
+parameter gives an unshared object containing the name of the method being
+invoked, as provided by the user; this object may be updated by the callback.
+.SH "SEE ALSO"
+Method(3), oo::class(n), oo::copy(n), oo::define(n), oo::object(n)
+.SH KEYWORDS
+class, constructor, object
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/pkgs/msgcat/doc/CmdCmplt.3 b/pkgs/msgcat/doc/CmdCmplt.3
new file mode 100644
index 0000000..eeae039
--- /dev/null
+++ b/pkgs/msgcat/doc/CmdCmplt.3
@@ -0,0 +1,34 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_CommandComplete 3 "" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CommandComplete \- Check for unmatched braces in a Tcl command
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_CommandComplete\fR(\fIcmd\fR)
+.SH ARGUMENTS
+.AS "const char" *cmd
+.AP "const char" *cmd in
+Command string to test for completeness.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_CommandComplete\fR takes a Tcl command string
+as argument and determines whether it contains one or more
+complete commands (i.e. there are no unclosed quotes, braces,
+brackets, or variable references).
+If the command string is complete then it returns 1; otherwise it returns 0.
+
+.SH KEYWORDS
+complete command, partial command
diff --git a/pkgs/msgcat/doc/Concat.3 b/pkgs/msgcat/doc/Concat.3
new file mode 100644
index 0000000..c38bf82
--- /dev/null
+++ b/pkgs/msgcat/doc/Concat.3
@@ -0,0 +1,51 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_Concat 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Concat \- concatenate a collection of strings
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+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
+Array of strings to concatenate. Must have \fIargc\fR entries.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_Concat\fR is a utility procedure used by several of the
+Tcl commands. Given a collection of strings, it concatenates
+them together into a single string, with the original strings
+separated by spaces. This procedure behaves differently than
+\fBTcl_Merge\fR, in that the arguments are simply concatenated:
+no effort is made to ensure proper list structure.
+However, in most common usage the arguments will all be proper
+lists themselves; if this is true, then the result will also have
+proper list structure.
+.PP
+\fBTcl_Concat\fR eliminates leading and trailing white space as it
+copies strings from \fBargv\fR to the result. If an element of
+\fBargv\fR consists of nothing but white space, then that string
+is ignored entirely. This white-space removal was added to make
+the output of the \fBconcat\fR command cleaner-looking.
+.PP
+The result string is dynamically allocated
+using \fBTcl_Alloc\fR; the caller must eventually release the space
+by calling \fBTcl_Free\fR.
+.SH "SEE ALSO"
+Tcl_ConcatObj
+.SH KEYWORDS
+concatenate, strings
diff --git a/pkgs/msgcat/doc/CrtChannel.3 b/pkgs/msgcat/doc/CrtChannel.3
new file mode 100644
index 0000000..478ef0b
--- /dev/null
+++ b/pkgs/msgcat/doc/CrtChannel.3
@@ -0,0 +1,928 @@
+'\"
+'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
+'\" Copyright (c) 1997-2000 Ajuba Solutions.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+.so man.macros
+.TH Tcl_CreateChannel 3 8.4 Tcl "Tcl Library Procedures"
+.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_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
+.sp
+Tcl_Channel
+\fBTcl_CreateChannel\fR(\fItypePtr, channelName, instanceData, mask\fR)
+.sp
+ClientData
+\fBTcl_GetChannelInstanceData\fR(\fIchannel\fR)
+.sp
+const Tcl_ChannelType *
+\fBTcl_GetChannelType\fR(\fIchannel\fR)
+.sp
+const char *
+\fBTcl_GetChannelName\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_GetChannelHandle\fR(\fIchannel, direction, handlePtr\fR)
+.sp
+Tcl_ThreadId
+\fBTcl_GetChannelThread\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_GetChannelMode\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_GetChannelBufferSize\fR(\fIchannel\fR)
+.sp
+\fBTcl_SetChannelBufferSize\fR(\fIchannel, size\fR)
+.sp
+\fBTcl_NotifyChannel\fR(\fIchannel, mask\fR)
+.sp
+int
+\fBTcl_BadChannelOption\fR(\fIinterp, optionName, optionList\fR)
+.sp
+int
+\fBTcl_IsChannelShared\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_IsChannelRegistered\fR(\fIinterp, channel\fR)
+.sp
+int
+\fBTcl_IsChannelExisting\fR(\fIchannelName\fR)
+.sp
+void
+\fBTcl_CutChannel\fR(\fIchannel\fR)
+.sp
+void
+\fBTcl_SpliceChannel\fR(\fIchannel\fR)
+.sp
+void
+\fBTcl_ClearChannelHandlers\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_ChannelBuffered\fR(\fIchannel\fR)
+.sp
+const char *
+\fBTcl_ChannelName\fR(\fItypePtr\fR)
+.sp
+Tcl_ChannelTypeVersion
+\fBTcl_ChannelVersion\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverBlockModeProc *
+\fBTcl_ChannelBlockModeProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverCloseProc *
+\fBTcl_ChannelCloseProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverClose2Proc *
+\fBTcl_ChannelClose2Proc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverInputProc *
+\fBTcl_ChannelInputProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverOutputProc *
+\fBTcl_ChannelOutputProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverSeekProc *
+\fBTcl_ChannelSeekProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverWideSeekProc *
+\fBTcl_ChannelWideSeekProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverThreadActionProc *
+\fBTcl_ChannelThreadActionProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverTruncateProc *
+\fBTcl_ChannelTruncateProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverSetOptionProc *
+\fBTcl_ChannelSetOptionProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverGetOptionProc *
+\fBTcl_ChannelGetOptionProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverWatchProc *
+\fBTcl_ChannelWatchProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverGetHandleProc *
+\fBTcl_ChannelGetHandleProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverFlushProc *
+\fBTcl_ChannelFlushProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverHandlerProc *
+\fBTcl_ChannelHandlerProc\fR(\fItypePtr\fR)
+.sp
+.SH ARGUMENTS
+.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
+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. If the created channel is assigned to one
+of the standard channels (\fBstdin\fR, \fBstdout\fR or \fBstderr\fR),
+the assigned channel name will be the name of the standard channel.
+.AP ClientData instanceData in
+Arbitrary one-word value to be associated with this channel. This
+value is passed to procedures in \fItypePtr\fR when they are invoked.
+.AP int mask in
+OR-ed combination of \fBTCL_READABLE\fR and \fBTCL_WRITABLE\fR to indicate
+whether a channel is readable and writable.
+.AP Tcl_Channel channel in
+The channel to operate on.
+.AP int direction in
+\fBTCL_READABLE\fR means the input handle is wanted; \fBTCL_WRITABLE\fR
+means the output handle is wanted.
+.AP ClientData *handlePtr out
+Points to the location where the desired OS-specific handle should be
+stored.
+.AP int size in
+The size, in bytes, of buffers to allocate in this channel.
+.AP int mask in
+An OR-ed combination of \fBTCL_READABLE\fR, \fBTCL_WRITABLE\fR
+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
+Name of the invalid option.
+.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.
+.BE
+.SH DESCRIPTION
+.PP
+Tcl uses a two-layered channel architecture. It provides a generic upper
+layer to enable C and Tcl programs to perform input and output using the
+same APIs for a variety of files, devices, sockets etc. The generic C APIs
+are described in the manual entry for \fBTcl_OpenFileChannel\fR.
+.PP
+The lower layer provides type-specific channel drivers for each type
+of device supported on each platform. This manual entry describes the
+C APIs used to communicate between the generic layer and the
+type-specific channel drivers. It also explains how new types of
+channels can be added by providing new channel drivers.
+.PP
+Channel drivers consist of a number of components: First, each channel
+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
+\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
+command creates channels that use the file and command channel
+drivers, and the Tcl \fBsocket\fR command creates channels that use
+TCP sockets for network communication.
+.PP
+Third, a channel driver optionally provides a C function to open
+channel instances of that type. For example, \fBTcl_OpenFileChannel\fR
+opens a channel that uses the file channel driver, and
+\fBTcl_OpenTcpClient\fR opens a channel that uses the TCP network
+protocol. These creation functions typically use
+\fBTcl_CreateChannel\fR internally to open the channel.
+.PP
+To add a new type of channel you must implement a C API or a Tcl command
+that opens a channel by invoking \fBTcl_CreateChannel\fR.
+When your driver calls \fBTcl_CreateChannel\fR it passes in
+a \fBTcl_ChannelType\fR structure describing the driver's I/O
+procedures.
+The generic layer will then invoke the functions referenced in that
+structure to perform operations on the channel.
+.PP
+\fBTcl_CreateChannel\fR opens a new channel and associates the supplied
+\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 \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
+call to \fBTcl_GetStdChannel\fR or a call to \fBTcl_SetStdChannel\fR
+closing this standard channel will cause the next call to
+\fBTcl_CreateChannel\fR to make the new channel the new standard
+channel too. See \fBTcl_StandardChannels\fR for a general treatise
+about standard channels and the behavior of the Tcl library with
+regard to them.
+.PP
+\fBTcl_GetChannelInstanceData\fR returns the instance data associated with
+the channel in \fIchannel\fR. This is the same as the \fIinstanceData\fR
+argument in the call to \fBTcl_CreateChannel\fR that created this channel.
+.PP
+\fBTcl_GetChannelType\fR returns a pointer to the \fBTcl_ChannelType\fR
+structure used by the channel in the \fIchannel\fR argument. This is
+the same as the \fItypePtr\fR argument in the call to
+\fBTcl_CreateChannel\fR that created this channel.
+.PP
+\fBTcl_GetChannelName\fR returns a string containing the name associated
+with the channel, or NULL if the \fIchannelName\fR argument to
+\fBTcl_CreateChannel\fR was NULL.
+.PP
+\fBTcl_GetChannelHandle\fR places the OS-specific device handle
+associated with \fIchannel\fR for the given \fIdirection\fR in the
+location specified by \fIhandlePtr\fR and returns \fBTCL_OK\fR. If
+the channel does not have a device handle for the specified direction,
+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
+\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.
+.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
+and output.
+.PP
+\fBTcl_GetChannelBufferSize\fR returns the size, in bytes, of buffers
+allocated to store input or output in \fIchannel\fR. If the value was not set
+by a previous call to \fBTcl_SetChannelBufferSize\fR, described below, then
+the default value of 4096 is returned.
+.PP
+\fBTcl_SetChannelBufferSize\fR sets the size, in bytes, of buffers that
+will be allocated in subsequent operations on the channel to store input or
+output. The \fIsize\fR argument should be between ten and one million,
+allowing buffers of ten bytes to one million bytes. If \fIsize\fR is
+outside this range, \fBTcl_SetChannelBufferSize\fR sets the buffer size to
+4096.
+.PP
+\fBTcl_NotifyChannel\fR is called by a channel driver to indicate to
+the generic layer that the events specified by \fImask\fR have
+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
+\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
+\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).
+.PP
+\fBTcl_IsChannelRegistered\fR checks whether the specified \fIchannel\fR is
+registered in the given \fIinterp\fRreter (result == 1) or not
+(result == 0).
+.PP
+\fBTcl_IsChannelExisting\fR checks whether a channel with the specified
+name is registered in the (thread)-global list of all channels (result
+== 1) or not (result == 0).
+.PP
+\fBTcl_CutChannel\fR removes the specified \fIchannel\fR from the
+(thread)global list of all channels (of the current thread).
+Application to a channel still registered in some interpreter
+is not allowed.
+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.
+.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.
+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.
+.PP
+\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.
+.SH TCL_CHANNELTYPE
+.PP
+A channel driver provides a \fBTcl_ChannelType\fR structure that contains
+pointers to functions that implement the various operations on a channel;
+these operations are invoked as needed by the generic layer. The structure
+was versioned starting in Tcl 8.3.2/8.4 to correct a problem with stacked
+channel drivers. See the \fBOLD CHANNEL TYPES\fR section below for
+details about the old structure.
+.PP
+The \fBTcl_ChannelType\fR structure contains the following fields:
+.PP
+.CS
+typedef struct Tcl_ChannelType {
+ const 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;
+ Tcl_DriverTruncateProc *\fItruncateProc\fR;
+} \fBTcl_ChannelType\fR;
+.CE
+.PP
+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, \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
+structure, the following functions should be used to obtain the values:
+\fBTcl_ChannelName\fR, \fBTcl_ChannelVersion\fR,
+\fBTcl_ChannelBlockModeProc\fR, \fBTcl_ChannelCloseProc\fR,
+\fBTcl_ChannelClose2Proc\fR, \fBTcl_ChannelInputProc\fR,
+\fBTcl_ChannelOutputProc\fR, \fBTcl_ChannelSeekProc\fR,
+\fBTcl_ChannelWideSeekProc\fR, \fBTcl_ChannelThreadActionProc\fR,
+\fBTcl_ChannelTruncateProc\fR,
+\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 (i.e. TLS, Trf) have new versions to correspond to the above change
+since the previous code for stacked channels had problems.
+.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.
+\fBfile\fR or \fBsocket\fR.
+.PP
+This value can be retrieved with \fBTcl_ChannelName\fR, which returns
+a pointer to the string.
+.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.
+\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).
+\fBTCL_CHANNEL_VERSION_5\fR must be set to specify the
+\fItruncateProc\fR members (includes
+\fIwideSeekProc\fR and \fIthreadActionProc\fR).
+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
+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
+one of
+\fBTCL_CHANNEL_VERSION_5\fR,
+\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.
+\fIBlockModeProc\fR should match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverBlockModeProc\fR(
+ ClientData \fIinstanceData\fR,
+ int \fImode\fR);
+.CE
+.PP
+The \fIinstanceData\fR is the same as the value passed to
+\fBTcl_CreateChannel\fR when this channel was created. The \fImode\fR
+argument is either \fBTCL_MODE_BLOCKING\fR or \fBTCL_MODE_NONBLOCKING\fR to
+set the device into blocking or nonblocking mode. The function should
+return zero if the operation was successful, or a nonzero POSIX error code
+if the operation failed.
+.PP
+If the operation is successful, the function can modify the supplied
+\fIinstanceData\fR to record that the channel entered blocking or
+nonblocking mode and to implement the blocking or nonblocking behavior.
+For some device types, the blocking and nonblocking behavior can be
+implemented by the underlying operating system; for other device types, the
+behavior must be emulated in the channel driver.
+.PP
+This value can be retrieved with \fBTcl_ChannelBlockModeProc\fR, which returns
+a pointer to the function.
+.PP
+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
+unacceptable value. Any confusion here may lead the interpreter into a
+(spurious and difficult to find) deadlock.
+.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
+closed. \fICloseProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverCloseProc\fR(
+ ClientData \fIinstanceData\fR,
+ Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+The \fIinstanceData\fR argument is the same as the value provided to
+\fBTcl_CreateChannel\fR when the channel was created. The function should
+release any storage maintained by the channel driver for this channel, and
+close the input and output devices encapsulated by this channel. All queued
+output will have been flushed to the device before this function is called,
+and no further driver operations will be invoked on this instance after
+calling the \fIcloseProc\fR. If the close operation is successful, the
+procedure should return zero; otherwise it should 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
+Alternatively, channels that support closing the read and write sides
+independently may set \fIcloseProc\fR to \fBTCL_CLOSE2PROC\fR and set
+\fIclose2Proc\fR to the address of a function that matches the
+following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverClose2Proc\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
+combination of \fBTCL_CLOSE_READ\fR or \fBTCL_CLOSE_WRITE\fR to
+indicate that the driver should close the read and/or write side of
+the channel. The channel driver may be invoked to perform
+additional operations on the channel after \fIclose2Proc\fR is
+called to close one or both sides of the channel. If \fIflags\fR is
+\fB0\fR (zero), the driver should close the channel in the manner
+described above for \fIcloseProc\fR. No further operations will be
+invoked on this instance after \fIclose2Proc\fR is called with all
+flags cleared. In all cases, the \fIclose2Proc\fR function should
+return zero if the close operation was successful; otherwise it should
+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
+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
+internal buffer. \fIInputProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverInputProc\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
+\fBTcl_CreateChannel\fR when the channel was created. The \fIbuf\fR
+argument points to an array of bytes in which to store input from the
+device, and the \fIbufSize\fR argument indicates how many bytes are
+available at \fIbuf\fR.
+.PP
+The \fIerrorCodePtr\fR argument points to an integer variable provided by
+the generic layer. If an error occurs, the function should set the variable
+to a POSIX error code that identifies the error that occurred.
+.PP
+The function should read data from the input device encapsulated by the
+channel and store it at \fIbuf\fR. On success, the function should return
+a nonnegative integer indicating how many bytes were read from the input
+device and stored at \fIbuf\fR. On error, the function should return -1. If
+an error occurs after some data has been read from the device, that data is
+lost.
+.PP
+If \fIinputProc\fR can determine that the input device has some data
+available but less than requested by the \fIbufSize\fR argument, the
+function should only attempt to read as much data as is available and
+return without blocking. If the input device has no data available
+whatsoever and the channel is in nonblocking mode, the function should
+return an \fBEAGAIN\fR error. If the input device has no data available
+whatsoever and the channel is in blocking mode, the function should block
+for the shortest possible time until at least one byte of data can be read
+from the device; then, it should return as much data as it can read without
+blocking.
+.PP
+This value can be retrieved with \fBTcl_ChannelInputProc\fR, which returns
+a pointer to the function.
+.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.
+\fIOutputProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverOutputProc\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
+\fBTcl_CreateChannel\fR when the channel was created. The \fIbuf\fR
+argument contains an array of bytes to be written to the device, and the
+\fItoWrite\fR argument indicates how many bytes are to be written from the
+\fIbuf\fR argument.
+.PP
+The \fIerrorCodePtr\fR argument points to an integer variable provided by
+the generic layer. If an error occurs, the function should set this
+variable to a POSIX error code that identifies the error.
+.PP
+The function should write the data at \fIbuf\fR to the output device
+encapsulated by the channel. On success, the function should return a
+nonnegative integer indicating how many bytes were written to the output
+device. The return value is normally the same as \fItoWrite\fR, but may be
+less in some cases such as if the output operation is interrupted by a
+signal. If an error occurs the function should return -1. In case of
+error, some data may have been written to the device.
+.PP
+If the channel is nonblocking and the output device is unable to absorb any
+data whatsoever, the function should return -1 with an \fBEAGAIN\fR error
+without writing any data.
+.PP
+This value can be retrieved with \fBTcl_ChannelOutputProc\fR, which returns
+a pointer to the function.
+.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
+operations will be applied. \fISeekProc\fR must match the following
+prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverSeekProc\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
+\fBTcl_CreateChannel\fR when this channel was created. \fIOffset\fR and
+\fIseekMode\fR have the same meaning as for the \fBTcl_Seek\fR
+procedure (described in the manual entry for \fBTcl_OpenFileChannel\fR).
+.PP
+The \fIerrorCodePtr\fR argument points to an integer variable provided by
+the generic layer for returning \fBerrno\fR values from the function. The
+function should set this variable to a POSIX error code if an error occurs.
+The function should store an \fBEINVAL\fR error code if the channel type
+does not implement seeking.
+.PP
+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
+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
+within files larger than 2GB. The \fIwideSeekProc\fR will be called
+in preference to the \fIseekProc\fR, but both must be defined if the
+\fIwideSeekProc\fR is defined. \fIWideSeekProc\fR must match the
+following prototype:
+.PP
+.CS
+typedef Tcl_WideInt \fBTcl_DriverWideSeekProc\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
+\fIseekProc\fR above, except that the type of offsets and the return
+type are different.
+.PP
+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.
+.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.
+\fIsetOptionProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverSetOptionProc\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
+the new value for that option, as a string. The \fIinstanceData\fR is the
+same as the value given to \fBTcl_CreateChannel\fR when this channel was
+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
+each channel type and the \fIsetOptionProc\fR procedure of the channel
+driver will get called to implement them. The \fIsetOptionProc\fR field can
+be NULL, which indicates that this channel type supports no type specific
+options.
+.PP
+If the option value is successfully modified to the new value, the function
+returns \fBTCL_OK\fR.
+It should call \fBTcl_BadChannelOption\fR which itself returns
+\fBTCL_ERROR\fR if the \fIoptionName\fR is
+unrecognized.
+If \fInewValue\fR specifies a value for the option that
+is not supported or if a system call error occurs,
+the function should leave an error message in the
+\fIresult\fR field of \fIinterp\fR if \fIinterp\fR is not NULL. The
+function should also call \fBTcl_SetErrno\fR to store an appropriate POSIX
+error code.
+.PP
+This value can be retrieved with \fBTcl_ChannelSetOptionProc\fR, which returns
+a pointer to the function.
+.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
+channel. \fIgetOptionProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverGetOptionProc\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
+channel. If the option name is not NULL, the function stores its current
+value, as a string, in the Tcl dynamic string \fIoptionValue\fR.
+If \fIoptionName\fR is NULL, the function stores in \fIoptionValue\fR an
+alternating list of all supported options and their current values.
+On success, the function returns \fBTCL_OK\fR.
+It should call \fBTcl_BadChannelOption\fR which itself returns
+\fBTCL_ERROR\fR if the \fIoptionName\fR is
+unrecognized. If a system call error occurs,
+the function should leave an error message in the
+result of \fIinterp\fR if \fIinterp\fR is not NULL. The
+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
+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
+specific options.
+.PP
+This value can be retrieved with \fBTcl_ChannelGetOptionProc\fR, which returns
+a pointer to the function.
+.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
+notice events of interest on this channel.
+\fIWatchProc\fR should match the following prototype:
+.PP
+.CS
+typedef void \fBTcl_DriverWatchProc\fR(
+ ClientData \fIinstanceData\fR,
+ int \fImask\fR);
+.CE
+.PP
+The \fIinstanceData\fR is the same as the value passed to
+\fBTcl_CreateChannel\fR when this channel was created. The \fImask\fR
+argument is an OR-ed combination of \fBTCL_READABLE\fR, \fBTCL_WRITABLE\fR
+and \fBTCL_EXCEPTION\fR; it indicates events the caller is interested in
+noticing on this channel.
+.PP
+The function should initialize device type specific mechanisms to
+notice when an event of interest is present on the channel. When one
+or more of the designated events occurs on the channel, the channel
+driver is responsible for calling \fBTcl_NotifyChannel\fR to inform
+the generic channel module. The driver should take care not to starve
+other channel drivers or sources of callbacks by invoking
+Tcl_NotifyChannel too frequently. Fairness can be insured by using
+the Tcl event queue to allow the channel event to be scheduled in sequence
+with other events. See the description of \fBTcl_QueueEvent\fR for
+details on how to queue an event.
+.PP
+This value can be retrieved with \fBTcl_ChannelWatchProc\fR, which returns
+a pointer to the function.
+.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.
+\fIGetHandleProc\fR should match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverGetHandleProc\fR(
+ ClientData \fIinstanceData\fR,
+ int \fIdirection\fR,
+ ClientData *\fIhandlePtr\fR);
+.CE
+.PP
+\fIInstanceData\fR is the same as the value passed to
+\fBTcl_CreateChannel\fR when this channel was created. The \fIdirection\fR
+argument is either \fBTCL_READABLE\fR to retrieve the handle used
+for input, or \fBTCL_WRITABLE\fR to retrieve the handle used for
+output.
+.PP
+If the channel implementation has device-specific handles, the
+function should retrieve the appropriate handle associated with the
+channel, according the \fIdirection\fR argument. The handle should be
+stored in the location referred to by \fIhandlePtr\fR, and
+\fBTCL_OK\fR should be returned. If the channel is not open for the
+specified direction, or if the channel implementation does not use
+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.
+.SS FLUSHPROC
+.PP
+The \fIflushProc\fR field is currently reserved for future use.
+It should be set to NULL.
+\fIFlushProc\fR should match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverFlushProc\fR(
+ ClientData \fIinstanceData\fR);
+.CE
+.PP
+This value can be retrieved with \fBTcl_ChannelFlushProc\fR, which returns
+a pointer to the function.
+.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
+be defined for stacked channel drivers that wish to be notified of events
+that occur on the underlying (stacked) channel.
+\fIHandlerProc\fR should match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverHandlerProc\fR(
+ ClientData \fIinstanceData\fR,
+ int \fIinterestMask\fR);
+.CE
+.PP
+\fIInstanceData\fR is the same as the value passed to \fBTcl_CreateChannel\fR
+when this channel was created. The \fIinterestMask\fR is an OR-ed
+combination of \fBTCL_READABLE\fR or \fBTCL_WRITABLE\fR; it indicates what
+type of event occurred on this channel.
+.PP
+This value can be retrieved with \fBTcl_ChannelHandlerProc\fR, which returns
+a pointer to the function.
+
+.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
+going to move to a different thread, i.e. whenever thread-specific
+driver state might have to initialized or updated. It can be NULL.
+The action \fITCL_CHANNEL_THREAD_REMOVE\fR is used to notify the
+driver that it should update or remove any thread-specific data it
+might be maintaining for the channel.
+.PP
+The action \fITCL_CHANNEL_THREAD_INSERT\fR is used to notify the
+driver that it should update or initialize any thread-specific data it
+might be maintaining using the calling thread as the associate. See
+\fBTcl_CutChannel\fR and \fBTcl_SpliceChannel\fR for more detail.
+.PP
+.CS
+typedef void \fBTcl_DriverThreadActionProc\fR(
+ ClientData \fIinstanceData\fR,
+ int \fIaction\fR);
+.CE
+.PP
+\fIInstanceData\fR is the same as the value passed to
+\fBTcl_CreateChannel\fR when this channel was created.
+.PP
+These values can be retrieved with \fBTcl_ChannelThreadActionProc\fR,
+which returns a pointer to the function.
+.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 \fBTcl_DriverTruncateProc\fR(
+ 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
+.QW "bad option"
+error message in an
+(optional) interpreter. It is used by channel drivers when
+an invalid Set/Get option is requested. Its purpose is to concatenate
+the generic options list to the specific ones and factorize
+the generic options error message string.
+.PP
+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 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
+.CE
+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
+.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 {
+ const 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;
+} \fBTcl_ChannelType\fR;
+.CE
+.PP
+It is still possible to create channel with the above structure. The
+internal channel code will determine the version. It is imperative to use
+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
+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 {
+ const 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;
+} \fBTcl_ChannelType\fR;
+.CE
+.PP
+When the above structure is registered as a channel type, the
+\fIversion\fR field should always be \fBTCL_CHANNEL_VERSION_2\fR.
+.SH "SEE ALSO"
+Tcl_Close(3), Tcl_OpenFileChannel(3), Tcl_SetErrno(3), Tcl_QueueEvent(3), Tcl_StackChannel(3), Tcl_GetStdChannel(3)
+.SH KEYWORDS
+blocking, channel driver, channel registration, channel type, nonblocking
diff --git a/pkgs/msgcat/doc/CrtChnlHdlr.3 b/pkgs/msgcat/doc/CrtChnlHdlr.3
new file mode 100644
index 0000000..1451e30
--- /dev/null
+++ b/pkgs/msgcat/doc/CrtChnlHdlr.3
@@ -0,0 +1,89 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_CreateChannelHandler 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_CreateChannelHandler, Tcl_DeleteChannelHandler \- call a procedure when a channel becomes readable or writable
+.SH SYNOPSIS
+.nf
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_CreateChannelHandler\fR(\fIchannel, mask, proc, clientData\fR)
+.sp
+void
+\fBTcl_DeleteChannelHandler\fR(\fIchannel, proc, clientData\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_ChannelProc clientData
+.AP Tcl_Channel channel in
+Tcl channel such as returned by \fBTcl_CreateChannel\fR.
+.AP int mask in
+Conditions under which \fIproc\fR should be called: OR-ed combination of
+\fBTCL_READABLE\fR, \fBTCL_WRITABLE\fR and \fBTCL_EXCEPTION\fR. Specify
+a zero value to temporarily disable an existing handler.
+.AP Tcl_FileProc *proc in
+Procedure to invoke whenever the channel indicated by \fIchannel\fR meets
+the conditions specified by \fImask\fR.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateChannelHandler\fR arranges for \fIproc\fR to be called in the
+future whenever input or output becomes possible on the channel identified
+by \fIchannel\fR, or whenever an exceptional condition exists for
+\fIchannel\fR. The conditions of interest under which \fIproc\fR will be
+invoked are specified by the \fImask\fR argument.
+See the manual entry for \fBfileevent\fR for a precise description of
+what it means for a channel to be readable or writable.
+\fIProc\fR must conform to the following prototype:
+.PP
+.CS
+typedef void \fBTcl_ChannelProc\fR(
+ ClientData \fIclientData\fR,
+ int \fImask\fR);
+.CE
+.PP
+The \fIclientData\fR argument is the same as the value passed to
+\fBTcl_CreateChannelHandler\fR when the handler was created. Typically,
+\fIclientData\fR points to a data structure containing application-specific
+information about the channel. \fIMask\fR is an integer mask indicating
+which of the requested conditions actually exists for the channel; it will
+contain a subset of the bits from the \fImask\fR argument to
+\fBTcl_CreateChannelHandler\fR when the handler was created.
+.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 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
+handler is created; instead, the \fImask\fR is changed for the
+existing handler.
+.PP
+\fBTcl_DeleteChannelHandler\fR deletes a channel handler identified by
+\fIchannel\fR, \fIproc\fR and \fIclientData\fR; if no such handler exists,
+the call has no effect.
+.PP
+Channel handlers are invoked via the Tcl event mechanism, so they
+are only useful in applications that are event-driven.
+Note also that the conditions specified in the \fImask\fR argument
+to \fIproc\fR may no longer exist when \fIproc\fR is invoked: for
+example, if there are two handlers for \fBTCL_READABLE\fR on the same
+channel, the first handler could consume all of the available input
+so that the channel is no longer readable when the second handler
+is invoked.
+For this reason it may be useful to use nonblocking I/O on channels
+for which there are event handlers.
+.SH "SEE ALSO"
+Notifier(3), Tcl_CreateChannel(3), Tcl_OpenFileChannel(3), vwait(n).
+.SH KEYWORDS
+blocking, callback, channel, events, handler, nonblocking.
diff --git a/pkgs/msgcat/doc/CrtCloseHdlr.3 b/pkgs/msgcat/doc/CrtCloseHdlr.3
new file mode 100644
index 0000000..a114f9c
--- /dev/null
+++ b/pkgs/msgcat/doc/CrtCloseHdlr.3
@@ -0,0 +1,55 @@
+'\"
+'\" 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 Tcl_CreateCloseHandler 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_CreateCloseHandler, Tcl_DeleteCloseHandler \- arrange for callbacks when channels are closed
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_CreateCloseHandler\fR(\fIchannel, proc, clientData\fR)
+.sp
+void
+\fBTcl_DeleteCloseHandler\fR(\fIchannel, proc, clientData\fR)
+.sp
+.SH ARGUMENTS
+.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
+The procedure to call as the callback.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateCloseHandler\fR arranges for \fIproc\fR to be called when
+\fIchannel\fR is closed with \fBTcl_Close\fR or
+\fBTcl_UnregisterChannel\fR, or using the Tcl \fBclose\fR command.
+\fIProc\fR should match the following prototype:
+.PP
+.CS
+typedef void \fBTcl_CloseProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR is the same as the value provided in the call to
+\fBTcl_CreateCloseHandler\fR.
+.PP
+\fBTcl_DeleteCloseHandler\fR removes a close callback for \fIchannel\fR.
+The \fIproc\fR and \fIclientData\fR identify which close callback to
+remove; \fBTcl_DeleteCloseHandler\fR does nothing if its \fIproc\fR and
+\fIclientData\fR arguments do not match the \fIproc\fR and \fIclientData\fR
+for a close handler for \fIchannel\fR.
+.SH "SEE ALSO"
+close(n), Tcl_Close(3), Tcl_UnregisterChannel(3)
+.SH KEYWORDS
+callback, channel closing
diff --git a/pkgs/msgcat/doc/CrtCommand.3 b/pkgs/msgcat/doc/CrtCommand.3
new file mode 100644
index 0000000..f0a7b43
--- /dev/null
+++ b/pkgs/msgcat/doc/CrtCommand.3
@@ -0,0 +1,143 @@
+'\"
+'\" Copyright (c) 1989-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.
+'\"
+.so man.macros
+.TH Tcl_CreateCommand 3 "" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CreateCommand \- implement new commands in C
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Command
+\fBTcl_CreateCommand\fR(\fIinterp, cmdName, proc, clientData, deleteProc\fR)
+.SH ARGUMENTS
+.AS Tcl_CmdDeleteProc *deleteProc
+.AP Tcl_Interp *interp in
+Interpreter in which to create new command.
+.AP "const char" *cmdName in
+Name of command.
+.AP Tcl_CmdProc *proc in
+Implementation of new command: \fIproc\fR will be called whenever
+\fIcmdName\fR is invoked as a command.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR and \fIdeleteProc\fR.
+.AP Tcl_CmdDeleteProc *deleteProc in
+Procedure to call before \fIcmdName\fR is deleted from the interpreter;
+allows for command-specific cleanup. If NULL, then no procedure is
+called before the command is deleted.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateCommand\fR defines a new command in \fIinterp\fR and associates
+it with procedure \fIproc\fR such that whenever \fIcmdName\fR is
+invoked as a Tcl command (via a call to \fBTcl_Eval\fR) the Tcl interpreter
+will call \fIproc\fR to process the command.
+It differs from \fBTcl_CreateObjCommand\fR in that a new string-based
+command is defined;
+that is, a command procedure is defined that takes an array of
+argument strings instead of objects.
+The object-based command procedures registered by \fBTcl_CreateObjCommand\fR
+can execute significantly faster than the string-based command procedures
+defined by \fBTcl_CreateCommand\fR.
+This is because they take Tcl objects as arguments
+and those objects can retain an internal representation that
+can be manipulated more efficiently.
+Also, Tcl's interpreter now uses objects internally.
+In order to invoke a string-based command procedure
+registered by \fBTcl_CreateCommand\fR,
+it must generate and fetch a string representation
+from each argument object before the call.
+New commands should be defined using \fBTcl_CreateObjCommand\fR.
+We support \fBTcl_CreateCommand\fR for backwards compatibility.
+.PP
+The procedures \fBTcl_DeleteCommand\fR, \fBTcl_GetCommandInfo\fR,
+and \fBTcl_SetCommandInfo\fR are used in conjunction with
+\fBTcl_CreateCommand\fR.
+.PP
+\fBTcl_CreateCommand\fR will delete an existing command \fIcmdName\fR,
+if one is already associated with the interpreter.
+It returns a token that may be used to refer
+to the command in subsequent calls to \fBTcl_GetCommandName\fR.
+If \fIcmdName\fR contains any \fB::\fR namespace qualifiers,
+then the command is added to the specified namespace;
+otherwise the command is added to the global namespace.
+If \fBTcl_CreateCommand\fR is called for an interpreter that is in
+the process of being deleted, then it does not create a new command
+and it returns NULL.
+\fIProc\fR should have arguments and result that match the type
+\fBTcl_CmdProc\fR:
+.PP
+.CS
+typedef int \fBTcl_CmdProc\fR(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ int \fIargc\fR,
+ const char *\fIargv\fR[]);
+.CE
+.PP
+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 \fBTcl_CreateCommand\fR.
+Typically, \fIclientData\fR points to an application-specific
+data structure that describes what to do when the command procedure
+is invoked. \fIArgc\fR and \fIargv\fR describe the arguments to
+the command, \fIargc\fR giving the number of arguments (including
+the command name) and \fIargv\fR giving the values of the arguments
+as strings. The \fIargv\fR array will contain \fIargc\fR+1 values;
+the first \fIargc\fR values point to the argument strings, and the
+last value is NULL.
+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.
+.PP
+Note that the argument strings are encoded in normalized UTF-8 since
+version 8.1 of Tcl.
+.PP
+\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;
+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 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,
+so simple commands can return an empty result by doing nothing at all.
+.PP
+The contents of the \fIargv\fR array belong to Tcl and are not
+guaranteed to persist once \fIproc\fR returns: \fIproc\fR should
+not modify them, nor should it set the interpreter result to point
+anywhere within the \fIargv\fR values.
+Call \fBTcl_SetResult\fR with status \fBTCL_VOLATILE\fR if you want
+to return something from the \fIargv\fR array.
+.PP
+\fIDeleteProc\fR will be invoked when (if) \fIcmdName\fR is deleted. This can
+occur through a call to \fBTcl_DeleteCommand\fR or \fBTcl_DeleteInterp\fR,
+or by replacing \fIcmdName\fR in another call to \fBTcl_CreateCommand\fR.
+\fIDeleteProc\fR is invoked before the command is deleted, and gives the
+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:
+.PP
+.CS
+typedef void \fBTcl_CmdDeleteProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR argument will be the same as the \fIclientData\fR
+argument passed to \fBTcl_CreateCommand\fR.
+.SH "SEE ALSO"
+Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_GetCommandInfo,
+Tcl_SetCommandInfo, Tcl_GetCommandName, Tcl_SetObjResult
+.SH KEYWORDS
+bind, command, create, delete, interpreter, namespace
diff --git a/pkgs/msgcat/doc/CrtFileHdlr.3 b/pkgs/msgcat/doc/CrtFileHdlr.3
new file mode 100644
index 0000000..cbc5e9f
--- /dev/null
+++ b/pkgs/msgcat/doc/CrtFileHdlr.3
@@ -0,0 +1,91 @@
+'\"
+'\" Copyright (c) 1990-1994 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.
+'\"
+.so man.macros
+.TH Tcl_CreateFileHandler 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CreateFileHandler, Tcl_DeleteFileHandler \- associate procedure callbacks with files or devices (Unix only)
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_CreateFileHandler\fR(\fIfd, mask, proc, clientData\fR)
+.sp
+\fBTcl_DeleteFileHandler\fR(\fIfd\fR)
+.SH ARGUMENTS
+.AS Tcl_FileProc clientData
+.AP int fd in
+Unix file descriptor for an open file or device.
+.AP int mask in
+Conditions under which \fIproc\fR should be called:
+OR-ed combination of \fBTCL_READABLE\fR, \fBTCL_WRITABLE\fR,
+and \fBTCL_EXCEPTION\fR. May be set to 0 to temporarily disable
+a handler.
+.AP Tcl_FileProc *proc in
+Procedure to invoke whenever the file or device indicated
+by \fIfile\fR meets the conditions specified by \fImask\fR.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+\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
+are indicated by \fImask\fR. For example, if \fImask\fR
+is \fBTCL_READABLE\fR, \fIproc\fR will be called when
+the file is readable.
+The callback to \fIproc\fR is made by \fBTcl_DoOneEvent\fR, so
+\fBTcl_CreateFileHandler\fR is only useful in programs that dispatch
+events through \fBTcl_DoOneEvent\fR or through Tcl commands such
+as \fBvwait\fR.
+.PP
+\fIProc\fR should have arguments and result that match the
+type \fBTcl_FileProc\fR:
+.PP
+.CS
+typedef void \fBTcl_FileProc\fR(
+ ClientData \fIclientData\fR,
+ int \fImask\fR);
+.CE
+.PP
+The \fIclientData\fR parameter to \fIproc\fR is a copy
+of the \fIclientData\fR
+argument given to \fBTcl_CreateFileHandler\fR when the callback
+was created. Typically, \fIclientData\fR points to a data
+structure containing application-specific information about
+the file. \fIMask\fR is an integer mask indicating which
+of the requested conditions actually exists for the file; it
+will contain a subset of the bits in the \fImask\fR argument
+to \fBTcl_CreateFileHandler\fR.
+.PP
+There may exist only one handler for a given file at a given time.
+If \fBTcl_CreateFileHandler\fR is called when a handler already
+exists for \fIfd\fR, then the new callback replaces the information
+that was previously recorded.
+.PP
+\fBTcl_DeleteFileHandler\fR may be called to delete the
+file handler for \fIfd\fR; if no handler exists for the
+file given by \fIfd\fR then the procedure has no effect.
+.PP
+The purpose of file handlers is to enable an application to respond to
+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 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
+Note that these interfaces are only supported by the Unix
+implementation of the Tcl notifier.
+.SH "SEE ALSO"
+fileevent(n), Tcl_CreateTimerHandler(3), Tcl_DoWhenIdle(3)
+.SH KEYWORDS
+callback, file, handler
diff --git a/pkgs/msgcat/doc/CrtInterp.3 b/pkgs/msgcat/doc/CrtInterp.3
new file mode 100644
index 0000000..a248cf4
--- /dev/null
+++ b/pkgs/msgcat/doc/CrtInterp.3
@@ -0,0 +1,149 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_CreateInterp 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CreateInterp, Tcl_DeleteInterp, Tcl_InterpActive, Tcl_InterpDeleted \- create and delete Tcl command interpreters
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Interp *
+\fBTcl_CreateInterp\fR()
+.sp
+\fBTcl_DeleteInterp\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_InterpDeleted\fR(\fIinterp\fR)
+.sp
+.VS 8.6
+int
+\fBTcl_InterpActive\fR(\fIinterp\fR)
+.VE 8.6
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Token for interpreter to be destroyed or queried.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateInterp\fR creates a new interpreter structure and returns
+a token for it. The token is required in calls to most other Tcl
+procedures, such as \fBTcl_CreateCommand\fR, \fBTcl_Eval\fR, and
+\fBTcl_DeleteInterp\fR. The token returned by \fBTcl_CreateInterp\fR
+may only be passed to Tcl routines called from the same thread as
+the original \fBTcl_CreateInterp\fR call. It is not safe for multiple
+threads to pass the same token to Tcl's routines.
+The new interpreter is initialized with the built-in Tcl commands
+and with the variables documented in the \fBtclvars\fR manual page. To bind in
+additional commands, call \fBTcl_CreateCommand\fR.
+.PP
+\fBTcl_DeleteInterp\fR marks an interpreter as deleted; the interpreter
+will eventually be deleted when all calls to \fBTcl_Preserve\fR for it have
+been matched by calls to \fBTcl_Release\fR. At that time, all of the
+resources associated with it, including variables, procedures, and
+application-specific command bindings, will be deleted. After
+\fBTcl_DeleteInterp\fR returns any attempt to use \fBTcl_Eval\fR on the
+interpreter will fail and return \fBTCL_ERROR\fR. After the call to
+\fBTcl_DeleteInterp\fR it is safe to examine the interpreter's result,
+query or set the values of variables, define, undefine or retrieve
+procedures, and examine the runtime evaluation stack. See below, in the
+section \fBINTERPRETERS AND MEMORY MANAGEMENT\fR for details.
+.PP
+\fBTcl_InterpDeleted\fR returns nonzero if \fBTcl_DeleteInterp\fR was
+called with \fIinterp\fR as its argument; this indicates that the
+interpreter will eventually be deleted, when the last call to
+\fBTcl_Preserve\fR for it is matched by a call to \fBTcl_Release\fR. If
+nonzero is returned, further calls to \fBTcl_Eval\fR in this interpreter
+will return \fBTCL_ERROR\fR.
+.PP
+\fBTcl_InterpDeleted\fR is useful in deletion callbacks to distinguish
+between when only the memory the callback is responsible for is being
+deleted and when the whole interpreter is being deleted. In the former case
+the callback may recreate the data being deleted, but this would lead to an
+infinite loop if the interpreter were being deleted.
+.PP
+.VS 8.6
+\fBTcl_InterpActive\fR is useful for determining whether there is any
+execution of scripts ongoing in an interpreter, which is a useful piece of
+information when Tcl is embedded in a garbage-collected environment and it
+becomes necessary to determine whether the interpreter is a candidate for
+deletion. The function returns a true value if the interpreter has at least
+one active execution running inside it, and a false value otherwise.
+.VE 8.6
+.SH "INTERPRETERS AND MEMORY MANAGEMENT"
+.PP
+\fBTcl_DeleteInterp\fR can be called at any time on an interpreter that may
+be used by nested evaluations and C code in various extensions. Tcl
+implements a simple mechanism that allows callers to use interpreters
+without worrying about the interpreter being deleted in a nested call, and
+without requiring special code to protect the interpreter, in most cases.
+This mechanism ensures that nested uses of an interpreter can safely
+continue using it even after \fBTcl_DeleteInterp\fR is called.
+.PP
+The mechanism relies on matching up calls to \fBTcl_Preserve\fR with calls
+to \fBTcl_Release\fR. If \fBTcl_DeleteInterp\fR has been called, only when
+the last call to \fBTcl_Preserve\fR is matched by a call to
+\fBTcl_Release\fR, will the interpreter be freed. See the manual entry for
+\fBTcl_Preserve\fR for a description of these functions.
+.PP
+The rules for when the user of an interpreter must call \fBTcl_Preserve\fR
+and \fBTcl_Release\fR are simple:
+.TP
+\fBInterpreters Passed As Arguments\fR
+.
+Functions that are passed an interpreter as an argument can safely use the
+interpreter without any special protection. Thus, when you write an
+extension consisting of new Tcl commands, no special code is needed to
+protect interpreters received as arguments. This covers the majority of all
+uses.
+.TP
+\fBInterpreter Creation And Deletion\fR
+.
+When a new interpreter is created and used in a call to \fBTcl_Eval\fR,
+\fBTcl_VarEval\fR, \fBTcl_GlobalEval\fR, \fBTcl_SetVar\fR, or
+\fBTcl_GetVar\fR, a pair of calls to \fBTcl_Preserve\fR and
+\fBTcl_Release\fR should be wrapped around all uses of the interpreter.
+Remember that it is unsafe to use the interpreter once \fBTcl_Release\fR
+has been called. To ensure that the interpreter is properly deleted when
+it is no longer needed, call \fBTcl_InterpDeleted\fR to test if some other
+code already called \fBTcl_DeleteInterp\fR; if not, call
+\fBTcl_DeleteInterp\fR before calling \fBTcl_Release\fR in your own code.
+.TP
+\fBRetrieving An Interpreter From A Data Structure\fR
+.
+When an interpreter is retrieved from a data structure (e.g. the client
+data of a callback) for use in one of the evaluation functions
+(\fBTcl_Eval\fR, \fBTcl_VarEval\fR, \fBTcl_GlobalEval\fR, \fBTcl_EvalObjv\fR,
+etc.) or variable access functions (\fBTcl_SetVar\fR, \fBTcl_GetVar\fR,
+\fBTcl_SetVar2Ex\fR, etc.), a pair of
+calls to \fBTcl_Preserve\fR and \fBTcl_Release\fR should be wrapped around
+all uses of the interpreter; it is unsafe to reuse the interpreter once
+\fBTcl_Release\fR has been called. If an interpreter is stored inside a
+callback data structure, an appropriate deletion cleanup mechanism should
+be set up by the code that creates the data structure so that the
+interpreter is removed from the data structure (e.g. by setting the field
+to NULL) when the interpreter is deleted. Otherwise, you may be using an
+interpreter that has been freed and whose memory may already have been
+reused.
+.PP
+All uses of interpreters in Tcl and Tk have already been protected.
+Extension writers should ensure that their code also properly protects any
+additional interpreters used, as described above.
+.PP
+.VS 8.6
+Note that the protection mechanisms do not work well with conventional garbage
+collection systems. When in such a managed environment, \fBTcl_InterpActive\fR
+should be used to determine when an interpreter is a candidate for deletion
+due to inactivity.
+.VE 8.6
+.SH "SEE ALSO"
+Tcl_Preserve(3), Tcl_Release(3), tclvars(n)
+.SH KEYWORDS
+command, create, delete, interpreter
diff --git a/pkgs/msgcat/doc/CrtMathFnc.3 b/pkgs/msgcat/doc/CrtMathFnc.3
new file mode 100644
index 0000000..3f2c84e
--- /dev/null
+++ b/pkgs/msgcat/doc/CrtMathFnc.3
@@ -0,0 +1,155 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_CreateMathFunc 3 8.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CreateMathFunc, Tcl_GetMathFuncInfo, Tcl_ListMathFuncs \- Define, query and enumerate math functions for expressions
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_CreateMathFunc\fR(\fIinterp, name, numArgs, argTypes, proc, clientData\fR)
+.sp
+int
+\fBTcl_GetMathFuncInfo\fR(\fIinterp, name, numArgsPtr, argTypesPtr, procPtr,
+ clientDataPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ListMathFuncs\fR(\fIinterp, pattern\fR)
+.SH ARGUMENTS
+.AS Tcl_ValueType *clientDataPtr out
+.AP Tcl_Interp *interp in
+Interpreter in which new function will be defined.
+.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.
+.AP Tcl_ValueType *argTypes in
+Points to an array giving the permissible types for each argument to
+function.
+.AP Tcl_MathProc *proc in
+Procedure that implements the function.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR when it is invoked.
+.AP int *numArgsPtr out
+Points to a variable that will be set to contain the number of
+arguments to the function.
+.AP Tcl_ValueType **argTypesPtr out
+Points to a variable that will be set to contain a pointer to an array
+giving the permissible types for each argument to the function which
+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).
+.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
+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
+.SH DESCRIPTION
+.PP
+Tcl allows a number of mathematical functions to be used in
+expressions, such as \fBsin\fR, \fBcos\fR, and \fBhypot\fR.
+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 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
+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.
+.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:
+.PP
+.CS
+typedef int \fBTcl_MathProc\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:
+.PP
+.CS
+typedef struct Tcl_Value {
+ Tcl_ValueType \fItype\fR;
+ long \fIintValue\fR;
+ double \fIdoubleValue\fR;
+ Tcl_WideInt \fIwideValue\fR;
+} \fBTcl_Value\fR;
+.CE
+.PP
+The \fItype\fR field indicates the type of the argument and is
+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 \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,
+\fIdoubleValue\fR or \fIwideValue\fR
+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
+\fBTCL_INT\fR, \fBTCL_DOUBLE\fR or \fBTCL_WIDE_INT\fR
+to indicate which value was set.
+Under normal circumstances \fIproc\fR should return \fBTCL_OK\fR.
+If an error occurs while executing the function, \fIproc\fR should
+return \fBTCL_ERROR\fR and leave an error message in the interpreter's result.
+.PP
+\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
+\fBTCL_OK\fR but if the named function does not exist, \fBTCL_ERROR\fR
+is returned and an error message is placed in the interpreter's
+result.
+.PP
+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, 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. 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
diff --git a/pkgs/msgcat/doc/CrtObjCmd.3 b/pkgs/msgcat/doc/CrtObjCmd.3
new file mode 100644
index 0000000..343b3dd
--- /dev/null
+++ b/pkgs/msgcat/doc/CrtObjCmd.3
@@ -0,0 +1,302 @@
+'\"
+'\" Copyright (c) 1996-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 Tcl_CreateObjCommand 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_DeleteCommandFromToken, Tcl_GetCommandInfo, Tcl_GetCommandInfoFromToken, Tcl_SetCommandInfo, Tcl_SetCommandInfoFromToken, Tcl_GetCommandName, Tcl_GetCommandFullName, Tcl_GetCommandFromObj \- implement new commands in C
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Command
+\fBTcl_CreateObjCommand\fR(\fIinterp, cmdName, proc, clientData, deleteProc\fR)
+.sp
+int
+\fBTcl_DeleteCommand\fR(\fIinterp, cmdName\fR)
+.sp
+int
+\fBTcl_DeleteCommandFromToken\fR(\fIinterp, token\fR)
+.sp
+int
+\fBTcl_GetCommandInfo\fR(\fIinterp, cmdName, infoPtr\fR)
+.sp
+int
+\fBTcl_SetCommandInfo\fR(\fIinterp, cmdName, infoPtr\fR)
+.sp
+int
+\fBTcl_GetCommandInfoFromToken\fR(\fItoken, infoPtr\fR)
+.sp
+int
+\fBTcl_SetCommandInfoFromToken\fR(\fItoken, infoPtr\fR)
+.sp
+const char *
+\fBTcl_GetCommandName\fR(\fIinterp, token\fR)
+.sp
+void
+\fBTcl_GetCommandFullName\fR(\fIinterp, token, objPtr\fR)
+.sp
+Tcl_Command
+\fBTcl_GetCommandFromObj\fR(\fIinterp, objPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_CmdDeleteProc *deleteProc in/out
+.AP Tcl_Interp *interp in
+Interpreter in which to create a new command or that contains a command.
+.AP char *cmdName in
+Name of command.
+.AP Tcl_ObjCmdProc *proc in
+Implementation of the new command: \fIproc\fR will be called whenever
+\fIcmdName\fR is invoked as a command.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR and \fIdeleteProc\fR.
+.AP Tcl_CmdDeleteProc *deleteProc in
+Procedure to call before \fIcmdName\fR is deleted from the interpreter;
+allows for command-specific cleanup. If NULL, then no procedure is
+called before the command is deleted.
+.AP Tcl_Command token in
+Token for command, returned by previous call to \fBTcl_CreateObjCommand\fR.
+The command must not have been deleted.
+.AP Tcl_CmdInfo *infoPtr in/out
+Pointer to structure containing various information about a
+Tcl command.
+.AP Tcl_Obj *objPtr in
+Object containing the name of a Tcl command.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateObjCommand\fR defines a new command in \fIinterp\fR
+and associates it with procedure \fIproc\fR
+such that whenever \fIname\fR is
+invoked as a Tcl command (e.g., via a call to \fBTcl_EvalObjEx\fR)
+the Tcl interpreter will call \fIproc\fR to process the command.
+.PP
+\fBTcl_CreateObjCommand\fR deletes any existing command
+\fIname\fR already associated with the interpreter
+(however see below for an exception where the existing command
+is not deleted).
+It returns a token that may be used to refer
+to the command in subsequent calls to \fBTcl_GetCommandName\fR.
+If \fIname\fR contains any \fB::\fR namespace qualifiers,
+then the command is added to the specified namespace;
+otherwise the command is added to the global namespace.
+If \fBTcl_CreateObjCommand\fR is called for an interpreter that is in
+the process of being deleted, then it does not create a new command
+and it returns NULL.
+\fIproc\fR should have arguments and result that match the type
+\fBTcl_ObjCmdProc\fR:
+.PP
+.CS
+typedef int \fBTcl_ObjCmdProc\fR(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ int \fIobjc\fR,
+ Tcl_Obj *const \fIobjv\fR[]);
+.CE
+.PP
+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
+\fBTcl_CreateObjCommand\fR. Typically, \fIclientData\fR points to an
+application-specific data structure that describes what to do when the
+command procedure is invoked. \fIObjc\fR and \fIobjv\fR describe the
+arguments to the command, \fIobjc\fR giving the number of argument objects
+(including the command name) and \fIobjv\fR giving the values of the
+arguments. The \fIobjv\fR array will contain \fIobjc\fR values, pointing to
+the argument objects. Unlike \fIargv\fR[\fIargv\fR] used in a
+string-based command procedure, \fIobjv\fR[\fIobjc\fR] will not contain NULL.
+.PP
+Additionally, when \fIproc\fR is invoked, it must not modify the contents
+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
+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
+\fBTcl_GetIntFromObj\fR on \fIobjv\fR[\fB2\fR] to obtain the integer
+representation of that object; that call may change the type of the object
+that \fIobjv\fR[\fB2\fR] points at, but will not change where
+\fIobjv\fR[\fB2\fR] points.
+.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
+for details on what these codes mean. Most normal commands will only
+return \fBTCL_OK\fR or \fBTCL_ERROR\fR.
+In addition, if \fIproc\fR needs to return a non-empty result,
+it can call \fBTcl_SetObjResult\fR to set the interpreter's result.
+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 this gives an error message.
+Before invoking a command procedure,
+\fBTcl_EvalObjEx\fR sets interpreter's result to
+point to an object representing an empty string, so simple
+commands can return an empty result by doing nothing at all.
+.PP
+The contents of the \fIobjv\fR array belong to Tcl and are not
+guaranteed to persist once \fIproc\fR returns: \fIproc\fR should
+not modify them.
+Call \fBTcl_SetObjResult\fR if you want
+to return something from the \fIobjv\fR array.
+.PP
+Ordinarily, \fBTcl_CreateObjCommand\fR deletes any existing command
+\fIname\fR already associated with the interpreter.
+However, if the existing command was created by a previous call to
+\fBTcl_CreateCommand\fR,
+\fBTcl_CreateObjCommand\fR does not delete the command
+but instead arranges for the Tcl interpreter to call the
+\fBTcl_ObjCmdProc\fR \fIproc\fR in the future.
+The old string-based \fBTcl_CmdProc\fR associated with the command
+is retained and its address can be obtained by subsequent
+\fBTcl_GetCommandInfo\fR calls. This is done for backwards compatibility.
+.PP
+\fIDeleteProc\fR will be invoked when (if) \fIname\fR is deleted.
+This can occur through a call to \fBTcl_DeleteCommand\fR,
+\fBTcl_DeleteCommandFromToken\fR, or \fBTcl_DeleteInterp\fR,
+or by replacing \fIname\fR in another call to \fBTcl_CreateObjCommand\fR.
+\fIDeleteProc\fR is invoked before the command is deleted, and gives the
+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:
+.PP
+.CS
+typedef void \fBTcl_CmdDeleteProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR argument will be the same as the \fIclientData\fR
+argument passed to \fBTcl_CreateObjCommand\fR.
+.PP
+\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 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
+a built-in command, an application-specific command, or a Tcl procedure.
+If \fIname\fR contains any \fB::\fR namespace qualifiers,
+the command is deleted from the specified namespace.
+.PP
+Given a token returned by \fBTcl_CreateObjCommand\fR,
+\fBTcl_DeleteCommandFromToken\fR deletes the command
+from a command interpreter.
+It will delete a command even if that command has been renamed.
+Once the call completes, attempts to invoke the command in
+\fIinterp\fR will result in errors.
+If the command corresponding to \fItoken\fR
+has already been deleted from \fIinterp\fR then
+\fBTcl_DeleteCommand\fR does nothing and returns -1;
+otherwise it returns 0.
+.PP
+\fBTcl_GetCommandInfo\fR checks to see whether its \fIcmdName\fR argument
+exists as a command in \fIinterp\fR.
+\fIcmdName\fR may include \fB::\fR namespace qualifiers
+to identify a command in a particular namespace.
+If the command is not found, then it returns 0.
+Otherwise it places information about the command
+in the \fBTcl_CmdInfo\fR structure
+pointed to by \fIinfoPtr\fR and returns 1.
+A \fBTcl_CmdInfo\fR structure has the following fields:
+.PP
+.CS
+typedef struct Tcl_CmdInfo {
+ 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;
+} \fBTcl_CmdInfo\fR;
+.CE
+.PP
+The \fIisNativeObjectProc\fR field has the value 1
+if \fBTcl_CreateObjCommand\fR was called to register the command;
+it is 0 if only \fBTcl_CreateCommand\fR was called.
+It allows a program to determine whether it is faster to
+call \fIobjProc\fR or \fIproc\fR:
+\fIobjProc\fR is normally faster
+if \fIisNativeObjectProc\fR has the value 1.
+The fields \fIobjProc\fR and \fIobjClientData\fR
+have the same meaning as the \fIproc\fR and \fIclientData\fR
+arguments to \fBTcl_CreateObjCommand\fR;
+they hold information about the object-based command procedure
+that the Tcl interpreter calls to implement the command.
+The fields \fIproc\fR and \fIclientData\fR
+hold information about the string-based command procedure
+that implements the command.
+If \fBTcl_CreateCommand\fR was called for this command,
+this is the procedure passed to it;
+otherwise, this is a compatibility procedure
+registered by \fBTcl_CreateObjCommand\fR
+that simply calls the command's
+object-based procedure after converting its string arguments to Tcl objects.
+The field \fIdeleteData\fR is the ClientData value
+to pass to \fIdeleteProc\fR; it is normally the same as
+\fIclientData\fR but may be set independently using the
+\fBTcl_SetCommandInfo\fR procedure.
+The field \fInamespacePtr\fR holds a pointer to the
+Tcl_Namespace that contains the command.
+.PP
+\fBTcl_GetCommandInfoFromToken\fR is identical to
+\fBTcl_GetCommandInfo\fR except that it uses a command token returned
+from \fBTcl_CreateObjCommand\fR in place of the command name. If the
+\fItoken\fR parameter is NULL, it returns 0; otherwise, it returns 1
+and fills in the structure designated by \fIinfoPtr\fR.
+.PP
+\fBTcl_SetCommandInfo\fR is used to modify the procedures and
+ClientData values associated with a command.
+Its \fIcmdName\fR argument is the name of a command in \fIinterp\fR.
+\fIcmdName\fR may include \fB::\fR namespace qualifiers
+to identify a command in a particular namespace.
+If this command does not exist then \fBTcl_SetCommandInfo\fR returns 0.
+Otherwise, it copies the information from \fI*infoPtr\fR to
+Tcl's internal structure for the command and returns 1.
+.PP
+\fBTcl_SetCommandInfoFromToken\fR is identical to
+\fBTcl_SetCommandInfo\fR except that it takes a command token as
+returned by \fBTcl_CreateObjCommand\fR instead of the command name.
+If the \fItoken\fR parameter is NULL, it returns 0. Otherwise, it
+copies the information from \fI*infoPtr\fR to Tcl's internal structure
+for the command and returns 1.
+.PP
+Note that \fBTcl_SetCommandInfo\fR and
+\fBTcl_SetCommandInfoFromToken\fR both allow the ClientData for a
+command's deletion procedure to be given a different value than the
+ClientData for its command procedure.
+.PP
+Note that neither \fBTcl_SetCommandInfo\fR nor
+\fBTcl_SetCommandInfoFromToken\fR will change a command's namespace.
+Use \fBTcl_Eval\fR to call the \fBrename\fR command to do that.
+.PP
+\fBTcl_GetCommandName\fR provides a mechanism for tracking commands
+that have been renamed.
+Given a token returned by \fBTcl_CreateObjCommand\fR
+when the command was created, \fBTcl_GetCommandName\fR returns the
+string name of the command. If the command has been renamed since it
+was created, then \fBTcl_GetCommandName\fR returns the current name.
+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 is not deleted or renamed; callers should copy the string if
+they need to keep it for a long time.
+.PP
+\fBTcl_GetCommandFullName\fR produces the fully qualified name
+of a command from a command token.
+The name, including all namespace prefixes,
+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\fR.
+The command name is resolved relative to the current namespace.
+Returns NULL if the command is not found.
+.SH "SEE ALSO"
+Tcl_CreateCommand(3), Tcl_ResetResult(3), Tcl_SetObjResult(3)
+.SH KEYWORDS
+bind, command, create, delete, namespace, object
diff --git a/pkgs/msgcat/doc/CrtSlave.3 b/pkgs/msgcat/doc/CrtSlave.3
new file mode 100644
index 0000000..3863373
--- /dev/null
+++ b/pkgs/msgcat/doc/CrtSlave.3
@@ -0,0 +1,236 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.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
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_IsSafe\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_MakeSafe\fR(\fIinterp\fR)
+.sp
+Tcl_Interp *
+\fBTcl_CreateSlave\fR(\fIinterp, slaveName, isSafe\fR)
+.sp
+Tcl_Interp *
+\fBTcl_GetSlave\fR(\fIinterp, slaveName\fR)
+.sp
+Tcl_Interp *
+\fBTcl_GetMaster\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_GetInterpPath\fR(\fIaskingInterp, slaveInterp\fR)
+.sp
+int
+\fBTcl_CreateAlias\fR(\fIslaveInterp, slaveCmd, targetInterp, targetCmd,
+ argc, argv\fR)
+.sp
+int
+\fBTcl_CreateAliasObj\fR(\fIslaveInterp, slaveCmd, targetInterp, targetCmd,
+ objc, objv\fR)
+.sp
+int
+\fBTcl_GetAlias\fR(\fIinterp, slaveCmd, targetInterpPtr, targetCmdPtr,
+ argcPtr, argvPtr\fR)
+.sp
+int
+\fBTcl_GetAliasObj\fR(\fIinterp, slaveCmd, targetInterpPtr, targetCmdPtr,
+ objcPtr, objvPtr\fR)
+.sp
+int
+\fBTcl_ExposeCommand\fR(\fIinterp, hiddenCmdName, cmdName\fR)
+.sp
+int
+\fBTcl_HideCommand\fR(\fIinterp, cmdName, hiddenCmdName\fR)
+.SH ARGUMENTS
+.AS "const char *const" **targetInterpPtr out
+.AP Tcl_Interp *interp in
+Interpreter in which to execute the specified command.
+.AP "const char" *slaveName in
+Name of slave interpreter to create or manipulate.
+.AP int isSafe in
+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
+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
+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
+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_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
+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
+Pointer to location to store a vector of strings, the additional arguments
+to pass to an alias. The location is in storage owned by the caller, the
+vector of strings is owned by the called function.
+.AP int *objcPtr out
+Pointer to location to store count of additional object arguments to be
+passed to the alias. The location is in storage owned by the caller.
+.AP Tcl_Obj ***objvPtr out
+Pointer to location to store a vector of Tcl_Obj structures, the additional
+arguments to pass to an object alias command. The location is in storage
+owned by the caller, the vector of Tcl_Obj structures is owned by the
+called function.
+.AP "const char" *cmdName in
+Name of an exposed command to hide or create.
+.AP "const char" *hiddenCmdName in
+Name under which a hidden command is stored and with which it can be
+exposed or invoked.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures are intended for access to the multiple interpreter
+facility from inside C programs. They enable managing multiple interpreters
+in a hierarchical relationship, and the management of aliases, commands
+that when invoked in one interpreter execute a command in another
+interpreter. The return value for those procedures that return an \fBint\fR
+is either \fBTCL_OK\fR or \fBTCL_ERROR\fR. If \fBTCL_ERROR\fR is returned
+then the \fBresult\fR field of the interpreter contains an error message.
+.PP
+\fBTcl_CreateSlave\fR creates a new interpreter as a slave of \fIinterp\fR.
+It also creates a slave command named \fIslaveName\fR in \fIinterp\fR which
+allows \fIinterp\fR to manipulate the new slave.
+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
+.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
+.QW safe
+(was created with the \fBTCL_SAFE_INTERPRETER\fR flag specified),
+\fB0\fR otherwise.
+.PP
+\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
+or application are safe and does not make any attempt to remove those
+parts, so safety is not guaranteed after calling \fBTcl_MakeSafe\fR.
+Callers will want to take care with their use of \fBTcl_MakeSafe\fR
+to avoid false claims of safety. For many situations, \fBTcl_CreateSlave\fR
+may be a better choice, since it creates interpreters in a known-safe state.
+.PP
+\fBTcl_GetSlave\fR returns a pointer to a slave interpreter of
+\fIinterp\fR. The slave interpreter is identified by \fIslaveName\fR.
+If no such slave interpreter exists, \fBNULL\fR is returned.
+.PP
+\fBTcl_GetMaster\fR returns a pointer to the master interpreter of
+\fIinterp\fR. If \fIinterp\fR has no master (it is a
+top-level interpreter) then \fBNULL\fR is returned.
+.PP
+\fBTcl_GetInterpPath\fR sets the \fIresult\fR field in \fIaskingInterp\fR
+to the relative path between \fIaskingInterp\fR and \fIslaveInterp\fR;
+\fIslaveInterp\fR must be a slave of \fIaskingInterp\fR. If the computation
+of the relative path succeeds, \fBTCL_OK\fR is returned, else
+\fBTCL_ERROR\fR is returned and the \fIresult\fR field in
+\fIaskingInterp\fR contains the error message.
+.PP
+\fBTcl_CreateAlias\fR creates an object command named \fIslaveCmd\fR in
+\fIslaveInterp\fR that when invoked, will cause the command \fItargetCmd\fR
+to be invoked in \fItargetInterp\fR. The arguments specified by the strings
+contained in \fIargv\fR are always prepended to any arguments supplied in the
+invocation of \fIslaveCmd\fR and passed to \fItargetCmd\fR.
+This operation returns \fBTCL_OK\fR if it succeeds, or \fBTCL_ERROR\fR if
+it fails; in that case, an error message is left in the object result
+of \fIslaveInterp\fR.
+Note that there are no restrictions on the ancestry relationship (as
+created by \fBTcl_CreateSlave\fR) between \fIslaveInterp\fR and
+\fItargetInterp\fR. Any two interpreters can be used, without any
+restrictions on how they are related.
+.PP
+\fBTcl_CreateAliasObj\fR is similar to \fBTcl_CreateAlias\fR except
+that it takes a vector of objects to pass as additional arguments instead
+of a vector of strings.
+.PP
+\fBTcl_GetAlias\fR returns information about an alias \fIaliasName\fR
+in \fIinterp\fR. Any of the result fields can be \fBNULL\fR, in
+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.
+.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
+strings.
+.PP
+\fBTcl_ExposeCommand\fR moves the command named \fIhiddenCmdName\fR from
+the set of hidden commands to the set of exposed commands, putting
+it under the name
+\fIcmdName\fR.
+\fIHiddenCmdName\fR must be the name of an existing hidden
+command, or the operation will return \fBTCL_ERROR\fR and leave an error
+message in the \fIresult\fR field in \fIinterp\fR.
+If an exposed command named \fIcmdName\fR already exists,
+the operation returns \fBTCL_ERROR\fR and leaves an error message in the
+object result of \fIinterp\fR.
+If the operation succeeds, it returns \fBTCL_OK\fR.
+After executing this command, attempts to use \fIcmdName\fR in a call to
+\fBTcl_Eval\fR or with the Tcl \fBeval\fR command will again succeed.
+.PP
+\fBTcl_HideCommand\fR moves the command named \fIcmdName\fR from the set of
+exposed commands to the set of hidden commands, under the name
+\fIhiddenCmdName\fR.
+\fICmdName\fR must be the name of an existing exposed
+command, or the operation will return \fBTCL_ERROR\fR and leave an error
+message in the object result of \fIinterp\fR.
+Currently both \fIcmdName\fR and \fIhiddenCmdName\fR must not contain
+namespace qualifiers, or the operation will return \fBTCL_ERROR\fR and
+leave an error message in the object result of \fIinterp\fR.
+The \fICmdName\fR will be looked up in the global namespace, and not
+relative to the current namespace, even if the current namespace is not the
+global one.
+If a hidden command whose name is \fIhiddenCmdName\fR already
+exists, the operation also returns \fBTCL_ERROR\fR and the \fIresult\fR
+field in \fIinterp\fR contains an error message.
+If the operation succeeds, it returns \fBTCL_OK\fR.
+After executing this command, attempts to use \fIcmdName\fR in a call to
+\fBTcl_Eval\fR or with the Tcl \fBeval\fR command will fail.
+.PP
+For a description of the Tcl interface to multiple interpreters, see
+\fIinterp(n)\fR.
+.SH "SEE ALSO"
+interp
+
+.SH KEYWORDS
+alias, command, exposed commands, hidden commands, interpreter, invoke,
+master, slave
diff --git a/pkgs/msgcat/doc/CrtTimerHdlr.3 b/pkgs/msgcat/doc/CrtTimerHdlr.3
new file mode 100644
index 0000000..2c9f90a
--- /dev/null
+++ b/pkgs/msgcat/doc/CrtTimerHdlr.3
@@ -0,0 +1,76 @@
+'\"
+'\" Copyright (c) 1990 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 Tcl_CreateTimerHandler 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CreateTimerHandler, Tcl_DeleteTimerHandler \- call a procedure at a given time
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_TimerToken
+\fBTcl_CreateTimerHandler\fR(\fImilliseconds, proc, clientData\fR)
+.sp
+\fBTcl_DeleteTimerHandler\fR(\fItoken\fR)
+.SH ARGUMENTS
+.AS Tcl_TimerToken milliseconds
+.AP int milliseconds in
+How many milliseconds to wait before invoking \fIproc\fR.
+.AP Tcl_TimerProc *proc in
+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
+from some previous call to \fBTcl_CreateTimerHandler\fR).
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateTimerHandler\fR arranges for \fIproc\fR to be
+invoked at a time \fImilliseconds\fR milliseconds in the
+future.
+The callback to \fIproc\fR will be made by \fBTcl_DoOneEvent\fR,
+so \fBTcl_CreateTimerHandler\fR is only useful in programs that
+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 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.
+.PP
+\fIProc\fR should have arguments and return value that match
+the type \fBTcl_TimerProc\fR:
+.PP
+.CS
+typedef void \fBTcl_TimerProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR parameter to \fIproc\fR is a
+copy of the \fIclientData\fR argument given to
+\fBTcl_CreateTimerHandler\fR when the callback
+was created. Typically, \fIclientData\fR points to a data
+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
+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
+has been invoked then \fBTcl_DeleteTimerHandler\fR does nothing.
+The tokens returned by \fBTcl_CreateTimerHandler\fR never have
+a value of NULL, so if NULL is passed to \fBTcl_DeleteTimerHandler\fR
+then the procedure does nothing.
+.SH "SEE ALSO"
+after(n), Tcl_CreateFileHandler(3), Tcl_DoWhenIdle(3)
+.SH KEYWORDS
+callback, clock, handler, timer
diff --git a/pkgs/msgcat/doc/CrtTrace.3 b/pkgs/msgcat/doc/CrtTrace.3
new file mode 100644
index 0000000..3689add
--- /dev/null
+++ b/pkgs/msgcat/doc/CrtTrace.3
@@ -0,0 +1,191 @@
+'\"
+'\" 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 <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 Tcl_CreateTrace 3 "" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CreateTrace, Tcl_CreateObjTrace, Tcl_DeleteTrace \- arrange for command execution to be traced
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Trace
+\fBTcl_CreateTrace\fR(\fIinterp, level, proc, clientData\fR)
+.sp
+Tcl_Trace
+\fBTcl_CreateObjTrace\fR(\fIinterp, level, flags, objProc, clientData, deleteProc\fR)
+.sp
+\fBTcl_DeleteTrace\fR(\fIinterp, trace\fR)
+.SH ARGUMENTS
+.AS Tcl_CmdObjTraceDeleteProc *deleteProc
+.AP Tcl_Interp *interp in
+Interpreter containing command to be traced or untraced.
+.AP int level in
+Only commands at or below this nesting level will be traced unless
+0 is specified. 1 means
+top-level commands only, 2 means top-level commands or those that are
+invoked as immediate consequences of executing top-level commands
+(procedure bodies, bracketed commands, etc.) and so on.
+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 is executed. See below for
+details of the calling sequence.
+.AP Tcl_CmdTraceProc *proc in
+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 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.
+.AP Tcl_Trace trace in
+Token for trace to be removed (return value from previous call
+to \fBTcl_CreateTrace\fR).
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateObjTrace\fR arranges for command tracing. After it is
+called, \fIobjProc\fR will be invoked before the Tcl interpreter calls
+any command procedure when evaluating commands in \fIinterp\fR.
+The return value from \fBTcl_CreateObjTrace\fR is a token for the trace,
+which may be passed to \fBTcl_DeleteTrace\fR to remove the trace.
+There may be many traces in effect simultaneously for the same
+interpreter.
+.PP
+\fIobjProc\fR should have arguments and result that match the type,
+\fBTcl_CmdObjTraceProc\fR:
+.PP
+.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[]);
+.CE
+.PP
+The \fIclientData\fR and \fIinterp\fR parameters are copies of the
+corresponding arguments given to \fBTcl_CreateTrace\fR.
+\fIClientData\fR typically points to an application-specific data
+structure that describes what to do when \fIobjProc\fR is invoked. The
+\fIlevel\fR parameter gives the nesting level of the command (1 for
+top-level commands passed to \fBTcl_Eval\fR by the application, 2 for
+the next-level commands passed to \fBTcl_Eval\fR as part of parsing or
+interpreting level-1 commands, and so on). The \fIcommand\fR parameter
+points to a string containing the text of the command, before any
+argument substitution. The \fIcommandToken\fR parameter is a Tcl
+command token that identifies the command to be invoked. The token
+may be passed to \fBTcl_GetCommandName\fR,
+\fBTcl_GetCommandInfoFromToken\fR, or \fBTcl_SetCommandInfoFromToken\fR to
+manipulate the definition of the command. The \fIobjc\fR and \fIobjv\fR
+parameters designate the final parameter count and parameter vector
+that will be passed to the command, and have had all substitutions
+performed.
+.PP
+The \fIobjProc\fR callback is expected to return a standard Tcl status
+return code. If this code is \fBTCL_OK\fR (the normal case), then
+the Tcl interpreter will invoke the command. Any other return code
+is treated as if the command returned that status, and the command is
+\fInot\fR invoked.
+.PP
+The \fIobjProc\fR callback must not modify \fIobjv\fR in any way. It
+is, however, permissible to change the command by calling
+\fBTcl_SetCommandTokenInfo\fR prior to returning. Any such change
+takes effect immediately, and the command is invoked with the new
+information.
+.PP
+Tracing will only occur for commands at nesting level less than
+or equal to the \fIlevel\fR parameter (i.e. the \fIlevel\fR
+parameter to \fIobjProc\fR will always be less than or equal to the
+\fIlevel\fR parameter to \fBTcl_CreateTrace\fR).
+.PP
+Tracing has a significant effect on runtime performance because it
+causes the bytecode compiler to refrain from generating in-line code
+for Tcl commands such as \fBif\fR and \fBwhile\fR in order that they
+may be traced. If traces for the built-in commands are not required,
+the \fIflags\fR parameter may be set to the constant value
+\fBTCL_ALLOW_INLINE_COMPILATION\fR. In this case, traces on built-in
+commands may or may not result in trace callbacks, depending on the
+state of the interpreter, but run-time performance will be improved
+significantly. (This functionality is desirable, for example, when
+using \fBTcl_CreateObjTrace\fR to implement an execution time
+profiler.)
+.PP
+Calls to \fIobjProc\fR will be made by the Tcl parser immediately before
+it calls the command procedure for the command (\fIcmdProc\fR). This
+occurs after argument parsing and substitution, so tracing for
+substituted commands occurs before tracing of the commands
+containing the substitutions. If there is a syntax error in a
+command, or if there is no command procedure associated with a
+command name, then no tracing will occur for that command. If a
+string passed to Tcl_Eval contains multiple commands (bracketed, or
+on different lines) then multiple calls to \fIobjProc\fR will occur,
+one for each command.
+.PP
+\fBTcl_DeleteTrace\fR removes a trace, so that no future calls will be
+made to the procedure associated with the trace. After \fBTcl_DeleteTrace\fR
+returns, the caller should never again use the \fItrace\fR token.
+.PP
+When \fBTcl_DeleteTrace\fR is called, the interpreter invokes the
+\fIdeleteProc\fR that was passed as a parameter to
+\fBTcl_CreateObjTrace\fR. The \fIdeleteProc\fR must match the type,
+\fBTcl_CmdObjTraceDeleteProc\fR:
+.PP
+.CS
+typedef void \fBTcl_CmdObjTraceDeleteProc\fR(
+ \fBClientData\fR \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR parameter will be the same as the
+\fIclientData\fR parameter that was originally passed to
+\fBTcl_CreateObjTrace\fR.
+.PP
+\fBTcl_CreateTrace\fR is an alternative interface for command tracing,
+\fInot recommended for new applications\fR. It is provided for backward
+compatibility with code that was developed for older versions of the
+Tcl interpreter. It is similar to \fBTcl_CreateObjTrace\fR, except
+that its \fIproc\fR parameter should have arguments and result that
+match the type \fBTcl_CmdTraceProc\fR:
+.PP
+.CS
+typedef void \fBTcl_CmdTraceProc\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
+.PP
+The parameters to the \fIproc\fR callback are similar to those of the
+\fIobjProc\fR callback above. The \fIcommandToken\fR is
+replaced with \fIcmdProc\fR, a pointer to the (string-based) command
+procedure that will be invoked; and \fIcmdClientData\fR, the client
+data that will be passed to the procedure. The \fIobjc\fR parameter
+is replaced with an \fIargv\fR parameter, that gives the arguments to
+the command as character strings.
+\fIProc\fR must not modify the \fIcommand\fR or \fIargv\fR strings.
+.PP
+If a trace created with \fBTcl_CreateTrace\fR is in effect, inline
+compilation of Tcl commands such as \fBif\fR and \fBwhile\fR is always
+disabled. There is no notification when a trace created with
+\fBTcl_CreateTrace\fR is deleted.
+There is no way to be notified when the trace created by
+\fBTcl_CreateTrace\fR is deleted. There is no way for the \fIproc\fR
+associated with a call to \fBTcl_CreateTrace\fR to abort execution of
+\fIcommand\fR.
+.SH KEYWORDS
+command, create, delete, interpreter, trace
diff --git a/pkgs/msgcat/doc/DString.3 b/pkgs/msgcat/doc/DString.3
new file mode 100644
index 0000000..a85b1cf
--- /dev/null
+++ b/pkgs/msgcat/doc/DString.3
@@ -0,0 +1,153 @@
+'\"
+'\" 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 Tcl_DString 3 7.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_DStringInit, Tcl_DStringAppend, Tcl_DStringAppendElement, Tcl_DStringStartSublist, Tcl_DStringEndSublist, Tcl_DStringLength, Tcl_DStringValue, Tcl_DStringSetLength, Tcl_DStringTrunc, Tcl_DStringFree, Tcl_DStringResult, Tcl_DStringGetResult \- manipulate dynamic strings
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_DStringInit\fR(\fIdsPtr\fR)
+.sp
+char *
+\fBTcl_DStringAppend\fR(\fIdsPtr, bytes, length\fR)
+.sp
+char *
+\fBTcl_DStringAppendElement\fR(\fIdsPtr, element\fR)
+.sp
+\fBTcl_DStringStartSublist\fR(\fIdsPtr\fR)
+.sp
+\fBTcl_DStringEndSublist\fR(\fIdsPtr\fR)
+.sp
+int
+\fBTcl_DStringLength\fR(\fIdsPtr\fR)
+.sp
+char *
+\fBTcl_DStringValue\fR(\fIdsPtr\fR)
+.sp
+\fBTcl_DStringSetLength\fR(\fIdsPtr, newLength\fR)
+.sp
+\fBTcl_DStringTrunc\fR(\fIdsPtr, newLength\fR)
+.sp
+\fBTcl_DStringFree\fR(\fIdsPtr\fR)
+.sp
+\fBTcl_DStringResult\fR(\fIinterp, dsPtr\fR)
+.sp
+\fBTcl_DStringGetResult\fR(\fIinterp, dsPtr\fR)
+.SH ARGUMENTS
+.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" *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 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
+character.
+.AP Tcl_Interp *interp in/out
+Interpreter whose result is to be set from or moved to the
+dynamic string.
+.BE
+
+.SH DESCRIPTION
+.PP
+Dynamic strings provide a mechanism for building up arbitrarily long
+strings by gradually appending information. If the dynamic string is
+short then there will be no memory allocation overhead; as the string
+gets larger, additional space will be allocated as needed.
+.PP
+\fBTcl_DStringInit\fR initializes a dynamic string to zero length.
+The Tcl_DString structure must have been allocated by the caller.
+No assumptions are made about the current state of the structure;
+anything already in it is discarded.
+If the structure has been used previously, \fBTcl_DStringFree\fR should
+be called first to free up any memory allocated for the old
+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 \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
+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 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
+.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
+\fBTcl_DStringStartSublist\fR and \fBTcl_DStringEndSublist\fR can be
+used to create nested lists.
+To append a list element that is itself a sublist, first
+call \fBTcl_DStringStartSublist\fR, then call \fBTcl_DStringAppendElement\fR
+for each of the elements in the sublist, then call
+\fBTcl_DStringEndSublist\fR to end the sublist.
+\fBTcl_DStringStartSublist\fR appends a space character if needed,
+followed by an open brace; \fBTcl_DStringEndSublist\fR appends
+a close brace.
+Lists can be nested to any depth.
+.PP
+\fBTcl_DStringLength\fR is a macro that returns the current length
+of a dynamic string (not including the terminating null character).
+\fBTcl_DStringValue\fR is a macro that returns a pointer to the
+current contents of a dynamic string.
+.PP
+.PP
+\fBTcl_DStringSetLength\fR changes the length of a dynamic string.
+If \fInewLength\fR is less than the string's current length, then
+the string is truncated.
+If \fInewLength\fR is greater than the string's current length,
+then the string will become longer and new space will be allocated
+for the string if needed.
+However, \fBTcl_DStringSetLength\fR will not initialize the new
+space except to provide a terminating null character; it is up to the
+caller to fill in the new space.
+\fBTcl_DStringSetLength\fR does not free up the string's storage space
+even if the string is truncated to zero length, so \fBTcl_DStringFree\fR
+will still need to be called.
+.PP
+\fBTcl_DStringTrunc\fR changes the length of a dynamic string.
+This procedure is now deprecated. \fBTcl_DStringSetLength\fR should
+be used instead.
+.PP
+\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
+\fBTcl_DStringResult\fR sets the result of \fIinterp\fR to the value of
+the dynamic string given by \fIdsPtr\fR. It does this by moving
+a pointer from \fIdsPtr\fR to the interpreter's result.
+This saves the cost of allocating new memory and copying the string.
+\fBTcl_DStringResult\fR also reinitializes the dynamic string to
+an empty string.
+.PP
+\fBTcl_DStringGetResult\fR does the opposite of \fBTcl_DStringResult\fR.
+It sets the value of \fIdsPtr\fR to the result of \fIinterp\fR and
+it clears \fIinterp\fR's result.
+If possible it does this by moving a pointer rather than by copying
+the string.
+
+.SH KEYWORDS
+append, dynamic string, free, result
diff --git a/pkgs/msgcat/doc/DetachPids.3 b/pkgs/msgcat/doc/DetachPids.3
new file mode 100644
index 0000000..0535cd8
--- /dev/null
+++ b/pkgs/msgcat/doc/DetachPids.3
@@ -0,0 +1,75 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_DetachPids 3 "" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_DetachPids, Tcl_ReapDetachedProcs, Tcl_WaitPid \- manage child processes in background
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_DetachPids\fR(\fInumPids, pidPtr\fR)
+.sp
+\fBTcl_ReapDetachedProcs\fR()
+.sp
+Tcl_Pid
+\fBTcl_WaitPid\fR(\fIpid, statusPtr, options\fR)
+.SH ARGUMENTS
+.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 *statusPtr out
+The result of waiting on a process (pipe). Either 0 or ECHILD.
+.AP int options in
+The options controlling the wait. WNOHANG specifies not to wait when
+checking the process.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_DetachPids\fR and \fBTcl_ReapDetachedProcs\fR provide a
+mechanism for managing subprocesses that are running in background.
+These procedures are needed because the parent of a process must
+eventually invoke the \fBwaitpid\fR kernel call (or one of a few other
+similar kernel calls) to wait for the child to exit. Until the
+parent waits for the child, the child's state cannot be completely
+reclaimed by the system. If a parent continually creates children
+and doesn't wait on them, the system's process table will eventually
+overflow, even if all the children have exited.
+.PP
+\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 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 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 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
+\fBTcl_ReapDetachedProcs\fR from time to time so that background
+processes can be cleaned up.
+.PP
+\fBTcl_WaitPid\fR is a thin wrapper around the facilities provided by
+the operating system to wait on the end of a spawned process and to
+check a whether spawned process is still running. It is used by
+\fBTcl_ReapDetachedProcs\fR and the channel system to portably access
+the operating system.
+
+.SH KEYWORDS
+background, child, detach, process, wait
diff --git a/pkgs/msgcat/doc/DictObj.3 b/pkgs/msgcat/doc/DictObj.3
new file mode 100644
index 0000000..a5dc9e5
--- /dev/null
+++ b/pkgs/msgcat/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 manipulated 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/pkgs/msgcat/doc/DoOneEvent.3 b/pkgs/msgcat/doc/DoOneEvent.3
new file mode 100644
index 0000000..9bdf926
--- /dev/null
+++ b/pkgs/msgcat/doc/DoOneEvent.3
@@ -0,0 +1,106 @@
+'\"
+'\" Copyright (c) 1990-1992 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 Tcl_DoOneEvent 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_DoOneEvent \- wait for events and invoke event handlers
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_DoOneEvent\fR(\fIflags\fR)
+.SH ARGUMENTS
+.AS int flags
+.AP int flags in
+This parameter is normally zero. It may be an OR-ed combination
+of any of the following flag bits:
+\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
+.PP
+This procedure is the entry point to Tcl's event loop; it is responsible for
+waiting for events and dispatching event handlers created with
+procedures such as \fBTk_CreateEventHandler\fR, \fBTcl_CreateFileHandler\fR,
+\fBTcl_CreateTimerHandler\fR, and \fBTcl_DoWhenIdle\fR.
+\fBTcl_DoOneEvent\fR checks to see if
+events are already present on the Tcl event queue; if so,
+it calls the handler(s) for the first (oldest) event, removes it from
+the queue, and returns.
+If there are no events ready to be handled, then \fBTcl_DoOneEvent\fR
+checks for new events from all possible sources.
+If any are found, it puts all of them on Tcl's event queue, calls
+handlers for the first event on the queue, and returns.
+If no events are found, \fBTcl_DoOneEvent\fR checks for \fBTcl_DoWhenIdle\fR
+callbacks; if any are found, it invokes all of them and returns.
+Finally, if no events or idle callbacks have been found, then
+\fBTcl_DoOneEvent\fR sleeps until an event occurs; then it adds any
+new events to the Tcl event queue, calls handlers for the first event,
+and returns.
+The normal return value is 1 to signify that some event
+was processed (see below for other alternatives).
+.PP
+If the \fIflags\fR argument to \fBTcl_DoOneEvent\fR is non-zero,
+it restricts the kinds of events that will be processed by
+\fBTcl_DoOneEvent\fR.
+\fIFlags\fR may be an OR-ed combination of any of the following bits:
+.TP 27
+\fBTCL_WINDOW_EVENTS\fR \-
+Process window system events.
+.TP 27
+\fBTCL_FILE_EVENTS\fR \-
+Process file events.
+.TP 27
+\fBTCL_TIMER_EVENTS\fR \-
+Process timer events.
+.TP 27
+\fBTCL_IDLE_EVENTS\fR \-
+Process idle callbacks.
+.TP 27
+\fBTCL_ALL_EVENTS\fR \-
+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 \-
+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,
+\fBTCL_TIMER_EVENTS\fR, or \fBTCL_IDLE_EVENTS\fR is set, then the only
+events that will be considered are those for which flags are set.
+Setting none of these flags is equivalent to the value
+\fBTCL_ALL_EVENTS\fR, which causes all event types to be processed.
+If an application has defined additional event sources with
+\fBTcl_CreateEventSource\fR, then additional \fIflag\fR values
+may also be valid, depending on those event sources.
+.PP
+The \fBTCL_DONT_WAIT\fR flag causes \fBTcl_DoOneEvent\fR not to put
+the process to sleep: it will check for events but if none are found
+then it returns immediately with a return value of 0 to indicate
+that no work was done.
+\fBTcl_DoOneEvent\fR will also return 0 without doing anything if
+the only alternative is to block forever (this can happen, for example,
+if \fIflags\fR is \fBTCL_IDLE_EVENTS\fR and there are no
+\fBTcl_DoWhenIdle\fR callbacks pending, or if no event handlers or
+timer handlers exist).
+.PP
+\fBTcl_DoOneEvent\fR may be invoked recursively. For example,
+it is possible to invoke \fBTcl_DoOneEvent\fR recursively
+from a handler called by \fBTcl_DoOneEvent\fR. This sort
+of operation is useful in some modal situations, such
+as when a
+notification dialog has been popped up and an application wishes to
+wait for the user to click a button in the dialog before
+doing anything else.
+
+.SH KEYWORDS
+callback, event, handler, idle, timer
diff --git a/pkgs/msgcat/doc/DoWhenIdle.3 b/pkgs/msgcat/doc/DoWhenIdle.3
new file mode 100644
index 0000000..27a4b8c
--- /dev/null
+++ b/pkgs/msgcat/doc/DoWhenIdle.3
@@ -0,0 +1,87 @@
+'\"
+'\" Copyright (c) 1990 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 Tcl_DoWhenIdle 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_DoWhenIdle, Tcl_CancelIdleCall \- invoke a procedure when there are no pending events
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_DoWhenIdle\fR(\fIproc, clientData\fR)
+.sp
+\fBTcl_CancelIdleCall\fR(\fIproc, clientData\fR)
+.SH ARGUMENTS
+.AS Tcl_IdleProc clientData
+.AP Tcl_IdleProc *proc in
+Procedure to invoke.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+\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, 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
+be a single call to \fIproc\fR; after \fIproc\fR is
+invoked the handler is automatically removed.
+\fBTcl_DoWhenIdle\fR is only usable in programs that
+use \fBTcl_DoOneEvent\fR to dispatch events.
+.PP
+\fIProc\fR should have arguments and result that match the
+type \fBTcl_IdleProc\fR:
+.PP
+.CS
+typedef void \fBTcl_IdleProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR parameter to \fIproc\fR is a copy of the \fIclientData\fR
+argument given to \fBTcl_DoWhenIdle\fR. Typically, \fIclientData\fR
+points to a data structure containing application-specific information about
+what \fIproc\fR should do.
+.PP
+\fBTcl_CancelIdleCall\fR
+may be used to cancel one or more previous
+calls to \fBTcl_DoWhenIdle\fR: if there is a \fBTcl_DoWhenIdle\fR
+handler registered for \fIproc\fR and \fIclientData\fR, then it
+is removed without invoking it. If there is more than one
+handler on the idle list that refers to \fIproc\fR and \fIclientData\fR,
+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 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
+actual work to be deferred until all pending events have
+been processed. At this point the exact work to be done
+will presumably be known and it can be done exactly once.
+.PP
+For example, \fBTcl_DoWhenIdle\fR might be used by an editor
+to defer display updates until all pending commands have
+been processed. Without this feature, redundant redisplays
+might occur in some situations, such as the processing of
+a command file.
+.SH BUGS
+.PP
+At present it is not safe for an idle callback to reschedule itself
+continuously. This will interact badly with certain features of Tk
+that attempt to wait for all idle callbacks to complete. If you would
+like for an idle callback to reschedule itself continuously, it is
+better to use a timer handler with a zero timeout period.
+.SH "SEE ALSO"
+after(n), Tcl_CreateFileHandler(3), Tcl_CreateTimerHandler(3)
+.SH KEYWORDS
+callback, defer, idle callback
diff --git a/pkgs/msgcat/doc/DoubleObj.3 b/pkgs/msgcat/doc/DoubleObj.3
new file mode 100644
index 0000000..12818b0
--- /dev/null
+++ b/pkgs/msgcat/doc/DoubleObj.3
@@ -0,0 +1,64 @@
+'\"
+'\" Copyright (c) 1996-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 Tcl_DoubleObj 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_NewDoubleObj, Tcl_SetDoubleObj, Tcl_GetDoubleFromObj \- manipulate Tcl objects as floating-point values
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewDoubleObj\fR(\fIdoubleValue\fR)
+.sp
+\fBTcl_SetDoubleObj\fR(\fIobjPtr, doubleValue\fR)
+.sp
+int
+\fBTcl_GetDoubleFromObj\fR(\fIinterp, objPtr, doublePtr\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp doubleValue in/out
+.AP double doubleValue in
+A double-precision floating-point value used to initialize or set a Tcl object.
+.AP Tcl_Obj *objPtr in/out
+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 retrieve a double value.
+.AP Tcl_Interp *interp in/out
+When non-NULL, an error message is left here when double value retrieval fails.
+.AP double *doublePtr out
+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 Tcl objects that
+hold double-precision floating-point values.
+.PP
+\fBTcl_NewDoubleObj\fR creates and returns a new Tcl object initialized to
+the double value \fIdoubleValue\fR. The returned Tcl object is unshared.
+.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/pkgs/msgcat/doc/DumpActiveMemory.3 b/pkgs/msgcat/doc/DumpActiveMemory.3
new file mode 100644
index 0000000..1f6cb46
--- /dev/null
+++ b/pkgs/msgcat/doc/DumpActiveMemory.3
@@ -0,0 +1,68 @@
+'\"
+'\" Copyright (c) 1992-1999 Karl Lehenbauer and Mark Diekhans.
+'\" Copyright (c) 2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.so man.macros
+.TH "Tcl_DumpActiveMemory" 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_DumpActiveMemory, Tcl_InitMemory, Tcl_ValidateAllMemory \- Validated memory allocation interface
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_DumpActiveMemory\fR(\fIfileName\fR)
+.sp
+void
+\fBTcl_InitMemory\fR(\fIinterp\fR)
+.sp
+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
+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).
+.AP int line in
+Line number at which the call to \fBTcl_ValidateAllMemory\fR is made
+(normally \fB__LINE__\fR).
+.BE
+
+.SH DESCRIPTION
+These functions provide access to Tcl memory debugging information.
+They are only functional when Tcl has been compiled with
+\fBTCL_MEM_DEBUG\fR defined at compile-time. When \fBTCL_MEM_DEBUG\fR
+is not defined, these functions are all no-ops.
+.PP
+\fBTcl_DumpActiveMemory\fR will output a list of all currently
+allocated memory to the specified file. The information output for
+each allocated block of memory is: starting and ending addresses
+(excluding guard zone), size, source file where \fBckalloc\fR was
+called to allocate the block and line number in that file. It is
+especially useful to call \fBTcl_DumpActiveMemory\fR after the Tcl
+interpreter has been deleted.
+.PP
+\fBTcl_InitMemory\fR adds the Tcl \fBmemory\fR command to the
+interpreter given by \fIinterp\fR. \fBTcl_InitMemory\fR is called
+by \fBTcl_Main\fR.
+.PP
+\fBTcl_ValidateAllMemory\fR forces a validation of the guard zones of
+all currently allocated blocks of memory. Normally validation of a
+block occurs when its freed, unless full validation is enabled, in
+which case validation of all blocks occurs when \fBckalloc\fR and
+\fBckfree\fR are called. This function forces the validation to occur
+at any point.
+
+.SH "SEE ALSO"
+TCL_MEM_DEBUG, memory
+
+.SH KEYWORDS
+memory, debug
+
+
diff --git a/pkgs/msgcat/doc/Encoding.3 b/pkgs/msgcat/doc/Encoding.3
new file mode 100644
index 0000000..7bcb285
--- /dev/null
+++ b/pkgs/msgcat/doc/Encoding.3
@@ -0,0 +1,592 @@
+'\"
+'\" 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_GetEncoding 3 "8.1" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_GetEncoding, Tcl_FreeEncoding, Tcl_GetEncodingFromObj, Tcl_ExternalToUtfDString, Tcl_ExternalToUtf, Tcl_UtfToExternalDString, Tcl_UtfToExternal, Tcl_WinTCharToUtf, Tcl_WinUtfToTChar, Tcl_GetEncodingName, Tcl_SetSystemEncoding, Tcl_GetEncodingNameFromEnvironment, Tcl_GetEncodingNames, Tcl_CreateEncoding, Tcl_GetEncodingSearchPath, Tcl_SetEncodingSearchPath, Tcl_GetDefaultEncodingDir, Tcl_SetDefaultEncodingDir \- procedures for creating and using encodings
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Encoding
+\fBTcl_GetEncoding\fR(\fIinterp, name\fR)
+.sp
+void
+\fBTcl_FreeEncoding\fR(\fIencoding\fR)
+.sp
+int
+\fBTcl_GetEncodingFromObj\fR(\fIinterp, objPtr, encodingPtr\fR)
+.sp
+char *
+\fBTcl_ExternalToUtfDString\fR(\fIencoding, src, srcLen, dstPtr\fR)
+.sp
+char *
+\fBTcl_UtfToExternalDString\fR(\fIencoding, src, srcLen, dstPtr\fR)
+.sp
+int
+\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)
+.sp
+TCHAR *
+\fBTcl_WinUtfToTChar\fR(\fIsrc, srcLen, dstPtr\fR)
+.sp
+const char *
+\fBTcl_GetEncodingName\fR(\fIencoding\fR)
+.sp
+int
+\fBTcl_SetSystemEncoding\fR(\fIinterp, name\fR)
+.sp
+const char *
+\fBTcl_GetEncodingNameFromEnvironment\fR(\fIbufPtr\fR)
+.sp
+void
+\fBTcl_GetEncodingNames\fR(\fIinterp\fR)
+.sp
+Tcl_Encoding
+\fBTcl_CreateEncoding\fR(\fItypePtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetEncodingSearchPath\fR()
+.sp
+int
+\fBTcl_SetEncodingSearchPath\fR(\fIsearchPath\fR)
+.sp
+const char *
+\fBTcl_GetDefaultEncodingDir\fR(\fIvoid\fR)
+.sp
+void
+\fBTcl_SetDefaultEncodingDir\fR(\fIpath\fR)
+.SH ARGUMENTS
+.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
+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 Tcl_Obj *objPtr in
+Name of encoding to get token for.
+.AP Tcl_Encoding *encodingPtr out
+Points to storage where encoding token is to be written.
+.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
+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
+encoding-specific length of the string is used.
+.AP Tcl_DString *dstPtr out
+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.
+\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. \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.
+\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
+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
+routine knows what state it was in when it left off at the end of the
+last piece. May be NULL, in which case the value specified for \fIflags\fR
+is ignored and the source buffer is assumed to contain the complete string to
+convert.
+.AP char *dst out
+Buffer in which the converted result will be stored. No more than
+\fIdstLen\fR bytes will be stored in \fIdst\fR.
+.AP int dstLen in
+The maximum length of the output buffer \fIdst\fR in bytes.
+.AP int *srcReadPtr out
+Filled with the number of bytes from \fIsrc\fR that were actually
+converted. This may be less than the original source length if there was
+a problem converting some source characters. May be NULL.
+.AP int *dstWrotePtr out
+Filled with the number of bytes that were actually stored in the output
+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_DString *bufPtr out
+Storage for the prescribed system encoding name.
+.AP "const Tcl_EncodingType" *typePtr in
+Structure that defines a new type of encoding.
+.AP Tcl_Obj *searchPath in
+List of filesystem directories in which to search for encoding data files.
+.AP "const char" *path in
+A path to the location of the encoding file.
+.BE
+.SH INTRODUCTION
+.PP
+These routines convert between Tcl's internal character representation,
+UTF-8, and character representations used by various operating systems or
+file systems, such as Unicode, ASCII, or Shift-JIS. When operating on
+strings, such as such as obtaining the names of files or displaying
+characters using international fonts, the strings must be translated into
+one or possibly multiple formats that the various system calls can use. For
+instance, on a Japanese Unix workstation, a user might obtain a filename
+represented in the EUC-JP file encoding and then translate the characters to
+the jisx0208 font encoding in order to display the filename in a Tk widget.
+The purpose of the encoding package is to help bridge the translation gap.
+UTF-8 provides an intermediate staging ground for all the various
+encodings. In the example above, text would be translated into UTF-8 from
+whatever file encoding the operating system is using. Then it would be
+translated from UTF-8 into whatever font encoding the display routines
+require.
+.PP
+Some basic encodings are compiled into Tcl. Others can be defined by the
+user or dynamically loaded from encoding files in a
+platform-independent manner.
+.SH DESCRIPTION
+.PP
+\fBTcl_GetEncoding\fR finds an encoding given its \fIname\fR. The name may
+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,
+\fBTcl_FreeEncoding\fR, and \fBTcl_UtfToExternal\fR. If the name did not
+refer to any known or loadable encoding, NULL is returned and an error
+message is returned in \fIinterp\fR.
+.PP
+The encoding package maintains a database of all encodings currently in use.
+The first time \fIname\fR is seen, \fBTcl_GetEncoding\fR returns an
+encoding with a reference count of 1. If the same \fIname\fR is requested
+further times, then the reference count for that encoding is incremented
+without the overhead of allocating a new encoding and all its associated
+data structures.
+.PP
+When an \fIencoding\fR is no longer needed, \fBTcl_FreeEncoding\fR
+should be called to release it. When an \fIencoding\fR is no longer in use
+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
+\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.
+.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
+call \fBTcl_DStringFree\fR to free any information stored in \fIdstPtr\fR.
+When converting, if any of the characters in the source buffer cannot be
+represented in the target encoding, a default fallback character will be
+used. The return value is a pointer to the value stored in the DString.
+.PP
+\fBTcl_ExternalToUtf\fR converts a source buffer \fIsrc\fR from the specified
+\fIencoding\fR into UTF-8. Up to \fIsrcLen\fR bytes are converted from the
+source buffer and up to \fIdstLen\fR converted bytes are stored in \fIdst\fR.
+In all cases, \fI*srcReadPtr\fR is filled with the number of bytes that were
+successfully converted from \fIsrc\fR and \fI*dstWrotePtr\fR is filled with
+the corresponding number of bytes that were stored in \fIdst\fR. The return
+value is one of the following:
+.RS
+.IP \fBTCL_OK\fR 29
+All bytes of \fIsrc\fR were converted.
+.IP \fBTCL_CONVERT_NOSPACE\fR 29
+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 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
+from the source stream to properly convert the formerly split-up multibyte
+sequence.
+.IP \fBTCL_CONVERT_SYNTAX\fR 29
+The source buffer contained an invalid character sequence. This may occur
+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 \fBTCL_ENCODING_STOPONERROR\fR was specified.
+.RE
+.LP
+\fBTcl_UtfToExternalDString\fR converts a source buffer \fIsrc\fR from UTF-8
+into the specified \fIencoding\fR. The converted bytes are stored in
+\fIdstPtr\fR, which is then terminated with the appropriate encoding-specific
+null. The caller should eventually call \fBTcl_DStringFree\fR to free any
+information stored in \fIdstPtr\fR. When converting, if any of the
+characters in the source buffer cannot be represented in the target
+encoding, a default fallback character will be used. The return value is
+a pointer to the value stored in the DString.
+.PP
+\fBTcl_UtfToExternal\fR converts a source buffer \fIsrc\fR from UTF-8 into
+the specified \fIencoding\fR. Up to \fIsrcLen\fR bytes are converted from
+the source buffer and up to \fIdstLen\fR converted bytes are stored in
+\fIdst\fR. In all cases, \fI*srcReadPtr\fR is filled with the number of
+bytes that were successfully converted from \fIsrc\fR and \fI*dstWrotePtr\fR
+is filled with the corresponding number of bytes that were stored in
+\fIdst\fR. The return values are the same as the return values for
+\fBTcl_ExternalToUtf\fR.
+.PP
+\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 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
+.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
+.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
+.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):
+.PP
+.CS
+if (running NT) {
+ encoding <- Tcl_GetEncoding("unicode");
+ nativeBuffer <- Tcl_UtfToExternal(encoding, utfBuffer);
+ Tcl_FreeEncoding(encoding);
+} else {
+ nativeBuffer <- Tcl_UtfToExternal(NULL, utfBuffer);
+}
+.CE
+.PP
+\fBTcl_WinUtfToTChar\fR and \fBTcl_WinTCharToUtf\fR automatically
+handle this test and use the proper encoding based on the current
+operating system. \fBTcl_WinUtfToTChar\fR returns a pointer to
+a TCHAR string, and \fBTcl_WinTCharToUtf\fR expects a TCHAR string
+pointer as the \fIsrc\fR string. Otherwise, these functions
+behave identically to \fBTcl_UtfToExternalDString\fR and
+\fBTcl_ExternalToUtfDString\fR.
+.PP
+\fBTcl_GetEncodingName\fR is roughly the inverse of \fBTcl_GetEncoding\fR.
+Given an \fIencoding\fR, the return value is the \fIname\fR argument that
+was used to create the encoding. The string returned by
+\fBTcl_GetEncodingName\fR is only guaranteed to persist until the
+\fIencoding\fR is deleted. The caller must not modify this string.
+.PP
+\fBTcl_SetSystemEncoding\fR sets the default encoding that should be used
+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, \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
+\fBTCL_OK\fR.
+.PP
+\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.
+.PP
+\fBTcl_GetEncodingNames\fR sets the \fIinterp\fR result to a list
+consisting of the names of all the encodings that are currently defined
+or can be dynamically loaded, searching the encoding path specified by
+\fBTcl_SetDefaultEncodingDir\fR. This procedure does not ensure that the
+dynamically-loadable encoding files contain valid data, but merely that they
+exist.
+.PP
+\fBTcl_CreateEncoding\fR defines a new encoding and registers the C
+procedures that are called back to convert between the encoding and
+UTF-8. Encodings created by \fBTcl_CreateEncoding\fR are thereafter
+visible in the database used by \fBTcl_GetEncoding\fR. Just as with the
+\fBTcl_GetEncoding\fR procedure, the return value is a token that
+represents the encoding and can be used in subsequent calls to other
+encoding functions. \fBTcl_CreateEncoding\fR returns an encoding with a
+reference count of 1. If an encoding with the specified \fIname\fR
+already exists, then its entry in the database is replaced with the new
+encoding; the token for the old encoding will remain valid and continue
+to behave as before, but users of the new token will now call the new
+encoding procedures.
+.PP
+The \fItypePtr\fR argument to \fBTcl_CreateEncoding\fR contains information
+about the name of the encoding and the procedures that will be called to
+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;
+} \fBTcl_EncodingType\fR;
+.CE
+.PP
+The \fIencodingName\fR provides a string name for the encoding, by
+which it can be referred in other procedures such as
+\fBTcl_GetEncoding\fR. The \fItoUtfProc\fR refers to a callback
+procedure to invoke to convert text from this encoding into UTF-8.
+The \fIfromUtfProc\fR refers to a callback procedure to invoke to
+convert text from UTF-8 into this encoding. The \fIfreeProc\fR refers
+to a callback procedure to invoke when this encoding is deleted. The
+\fIfreeProc\fR field may be NULL. The \fIclientData\fR contains an
+arbitrary one-word value passed to \fItoUtfProc\fR, \fIfromUtfProc\fR,
+and \fIfreeProc\fR whenever they are called. Typically, this is a
+pointer to a data structure containing encoding-specific information
+that can be used by the callback procedures. For instance, two very
+similar encodings such as \fBascii\fR and \fBmacRoman\fR may use the
+same callback procedure, but use different values of \fIclientData\fR
+to control its behavior. The \fInullSize\fR specifies the number of
+zero bytes that signify end-of-string in this encoding. It must be
+\fB1\fR (for single-byte or multi-byte encodings like ASCII or
+Shift-JIS) or \fB2\fR (for double-byte encodings like Unicode).
+Constant-sized encodings with 3 or more bytes per character (such as
+CNS11643) are not accepted.
+.PP
+The callback procedures \fItoUtfProc\fR and \fIfromUtfProc\fR should match the
+type \fBTcl_EncodingConvertProc\fR:
+.PP
+.CS
+typedef int \fBTcl_EncodingConvertProc\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
+\fBTcl_ExternalToUtf\fR or \fBTcl_UtfToExternal\fR family of functions to
+perform the actual conversion. The \fIclientData\fR parameter to these
+procedures is the same as the \fIclientData\fR field specified to
+\fBTcl_CreateEncoding\fR when the encoding was created. The remaining
+arguments to the callback procedures are the same as the arguments,
+documented at the top, to \fBTcl_ExternalToUtf\fR or
+\fBTcl_UtfToExternal\fR, with the following exceptions. If the
+\fIsrcLen\fR argument to one of those high-level functions is negative,
+the value passed to the callback procedure will be the appropriate
+encoding-specific string length of \fIsrc\fR. If any of the \fIsrcReadPtr\fR,
+\fIdstWrotePtr\fR, or \fIdstCharsPtr\fR arguments to one of the high-level
+functions is NULL, the corresponding value passed to the callback
+procedure will be a non-NULL location.
+.PP
+The callback procedure \fIfreeProc\fR, if non-NULL, should match the type
+\fBTcl_EncodingFreeProc\fR:
+.PP
+.CS
+typedef void \fBTcl_EncodingFreeProc\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
+\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
+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.
+.SH "ENCODING FILES"
+Space would prohibit precompiling into Tcl every possible encoding
+algorithm, so many encodings are stored on disk as dynamically-loadable
+encoding files. This behavior also allows the user to create additional
+encoding files that can be loaded using the same mechanism. These
+encoding files contain information about the tables and/or escape
+sequences used to map between an external encoding and Unicode. The
+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
+.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"
+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"
+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"
+A multi-byte encoding, where one character may be either one or two bytes long.
+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"
+An escape-sequence encoding, specifying that certain sequences of bytes
+do not represent characters, but commands that describe how following bytes
+should be interpreted.
+.PP
+The rest of the lines in the file depend on the type.
+.PP
+Cases [1], [2], and [3] are collectively referred to as table-based encoding
+files. The lines in a table-based encoding file are in the same
+format as this example taken from the \fBshiftjis\fR encoding (this is not
+the complete file):
+.PP
+.CS
+# Encoding file: shiftjis, multi-byte
+M
+003F 0 40
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D203E007F
+0080000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
+FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
+FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
+FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+81
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+300030013002FF0CFF0E30FBFF1AFF1BFF1FFF01309B309C00B4FF4000A8FF3E
+FFE3FF3F30FD30FE309D309E30034EDD30053006300730FC20152010FF0F005C
+301C2016FF5C2026202520182019201C201DFF08FF0930143015FF3BFF3DFF5B
+FF5D30083009300A300B300C300D300E300F30103011FF0B221200B100D70000
+00F7FF1D2260FF1CFF1E22662267221E22342642264000B0203220332103FFE5
+FF0400A200A3FF05FF03FF06FF0AFF2000A72606260525CB25CF25CE25C725C6
+25A125A025B325B225BD25BC203B301221922190219121933013000000000000
+000000000000000000000000000000002208220B2286228722822283222A2229
+000000000000000000000000000000002227222800AC21D221D4220022030000
+0000000000000000000000000000000000000000222022A52312220222072261
+2252226A226B221A223D221D2235222B222C0000000000000000000000000000
+212B2030266F266D266A2020202100B6000000000000000025EF000000000000
+.CE
+.PP
+The third line of the file is three numbers. The first number is the
+fallback character (in base 16) to use when converting from UTF-8 to this
+encoding. The second number is a \fB1\fR if this file represents the
+encoding for a symbol font, or \fB0\fR otherwise. The last number (in base
+10) is how many pages of data follow.
+.PP
+Subsequent lines in the example above are pages that describe how to map
+from the encoding into 2-byte Unicode. The first line in a page identifies
+the page number. Following it are 256 double-byte numbers, arranged as 16
+rows of 16 numbers. Given a character in the encoding, the high byte of
+that character is used to select which page, and the low byte of that
+character is used as an index to select one of the double-byte numbers in
+that page \- the value obtained being the corresponding Unicode character.
+By examination of the example above, one can see that the characters 0x7E
+and 0x8163 in \fBshiftjis\fR map to 203E and 2026 in Unicode, respectively.
+.PP
+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 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
+file are in the same format as this example taken from the \fBiso2022-jp\fR
+encoding:
+.PP
+.CS
+.ta 1.5i
+# Encoding file: iso2022-jp, escape-driven
+E
+init {}
+final {}
+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
+is the associated value. \fBinit\fR is a string to emit or expect before
+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,
+.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 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/pkgs/msgcat/doc/Ensemble.3 b/pkgs/msgcat/doc/Ensemble.3
new file mode 100644
index 0000000..cd69bbd
--- /dev/null
+++ b/pkgs/msgcat/doc/Ensemble.3
@@ -0,0 +1,219 @@
+'\"
+'\" 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_GetEnsembleParameterList, Tcl_GetEnsembleUnknownHandler, Tcl_GetEnsembleSubcommandList, Tcl_IsEnsemble, Tcl_SetEnsembleFlags, Tcl_SetEnsembleMappingDict, Tcl_SetEnsembleParameterList, 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
+.VS 8.6
+int
+\fBTcl_GetEnsembleParameterList\fR(\fIinterp, token, listObjPtr\fR)
+.sp
+int
+\fBTcl_SetEnsembleParameterList\fR(\fIinterp, token, listObj\fR)
+.VE 8.6
+.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, \fBTCL_ENSEMBLE_PREFIX\fR,
+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 \fBTCL_LEAVE_ERR_MSG\fR 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 \fBTCL_ENSEMBLE_PREFIX\fR 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 list of formal pre-subcommand parameters, the
+defined list of subcommands in the dictionary or the unknown subcommand
+handler command prefix. May be NULL if the subcommand list or unknown handler
+are to be removed.
+.AP Tcl_Obj **listObjPtr out
+Pointer to a variable into which to write the current list of formal
+pre-subcommand parameters, the defined 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 \fBTCL_LEAVE_ERR_MSG\fR 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 \fBTCL_ENSEMBLE_PREFIX\fR
+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 (\fBTCL_OK\fR, or \fBTCL_ERROR\fR 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 (\fBTCL_OK\fR, or \fBTCL_ERROR\fR if the token does not refer to an
+ensemble) and the dictionary obtained from
+\fBTcl_GetEnsembleMappingDict\fR should always be treated as immutable
+even if it is unshared.
+All command names in prefixes set via \fBTcl_SetEnsembleMappingDict\fR
+must be fully qualified.
+.TP
+\fBformal pre-subcommand parameter list\fR (read-write)
+.VS 8.6
+A list of formal parameter names (the names only being used when generating
+error messages) that come at invocation of the ensemble between the name of
+the ensemble and the subcommand argument. NULL (the default) is equivalent to
+the empty list. May be read and written using
+\fBTcl_GetEnsembleParameterList\fR and \fBTcl_SetEnsembleParameterList\fR
+respectively. The result of both of those functions is a Tcl result code
+(\fBTCL_OK\fR, or \fBTCL_ERROR\fR if the token does not refer to an
+ensemble) and the
+dictionary obtained from \fBTcl_GetEnsembleParameterList\fR should always be
+treated as immutable even if it is unshared.
+.VE 8.6
+.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 (\fBTCL_OK\fR, or
+\fBTCL_ERROR\fR if the
+token does not refer to an ensemble) and the list obtained from
+\fBTcl_GetEnsembleSubcommandList\fR should always be treated as
+immutable even if it is unshared.
+.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 (\fBTCL_OK\fR, or \fBTCL_ERROR\fR 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
+(\fBTCL_OK\fR, or \fBTCL_ERROR\fR if the token does not refer to an ensemble).
+.SH "SEE ALSO"
+namespace(n), Tcl_DeleteCommandFromToken(3)
+.SH KEYWORDS
+command, ensemble
diff --git a/pkgs/msgcat/doc/Environment.3 b/pkgs/msgcat/doc/Environment.3
new file mode 100644
index 0000000..3753f43
--- /dev/null
+++ b/pkgs/msgcat/doc/Environment.3
@@ -0,0 +1,38 @@
+'\"
+'\" 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_PutEnv 3 "7.5" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_PutEnv \- procedures to manipulate the environment
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_PutEnv\fR(\fIassignment\fR)
+.SH ARGUMENTS
+.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
+.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
+\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/pkgs/msgcat/doc/Eval.3 b/pkgs/msgcat/doc/Eval.3
new file mode 100644
index 0000000..b776e93
--- /dev/null
+++ b/pkgs/msgcat/doc/Eval.3
@@ -0,0 +1,211 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Scriptics Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_Eval 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_EvalObjEx, Tcl_EvalFile, Tcl_EvalObjv, Tcl_Eval, Tcl_EvalEx, Tcl_GlobalEval, Tcl_GlobalEvalObj, Tcl_VarEval, Tcl_VarEvalVA \- execute Tcl scripts
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_EvalObjEx\fR(\fIinterp, objPtr, flags\fR)
+.sp
+int
+\fBTcl_EvalFile\fR(\fIinterp, fileName\fR)
+.sp
+int
+\fBTcl_EvalObjv\fR(\fIinterp, objc, objv, flags\fR)
+.sp
+int
+\fBTcl_Eval\fR(\fIinterp, script\fR)
+.sp
+int
+\fBTcl_EvalEx\fR(\fIinterp, script, numBytes, flags\fR)
+.sp
+int
+\fBTcl_GlobalEval\fR(\fIinterp, script\fR)
+.sp
+int
+\fBTcl_GlobalEvalObj\fR(\fIinterp, objPtr\fR)
+.sp
+int
+\fBTcl_VarEval\fR(\fIinterp, part, part, ... \fB(char *) NULL\fR)
+.sp
+int
+\fBTcl_VarEvalVA\fR(\fIinterp, argList\fR)
+.SH ARGUMENTS
+.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.
+.AP Tcl_Obj *objPtr in
+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
+Name of a file containing a Tcl script.
+.AP int objc in
+The number of objects in the array pointed to by \fIobjPtr\fR;
+this is also the number of words in the command.
+.AP Tcl_Obj **objv in
+Points to an array of pointers to objects; each object holds the
+value of a single word in the command to execute.
+.AP int numBytes in
+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
+Points to first byte of script to execute (null-terminated and UTF-8).
+.AP char *part in
+String forming part of a Tcl script.
+.AP va_list argList in
+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 invoked to execute Tcl scripts in
+various forms.
+\fBTcl_EvalObjEx\fR is the core procedure and is used by many of the others.
+It executes the commands in the script stored in \fIobjPtr\fR
+until either an error occurs or the end of the script is reached.
+If this is the first time \fIobjPtr\fR has been executed,
+its commands are compiled into bytecode instructions
+which are then executed. The
+bytecodes are saved in \fIobjPtr\fR so that the compilation step
+can be skipped if the object is evaluated again in the future.
+.PP
+The return value from \fBTcl_EvalObjEx\fR (and all the other procedures
+described here) is a Tcl completion code with
+one of the values \fBTCL_OK\fR, \fBTCL_ERROR\fR, \fBTCL_RETURN\fR,
+\fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR, or possibly some other
+integer value originating in an extension.
+In addition, a result value or error message is left in \fIinterp\fR's
+result; it can be retrieved using \fBTcl_GetObjResult\fR.
+.PP
+\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 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 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
+executed again, \fBTcl_Eval\fR may be faster than \fBTcl_EvalObjEx\fR.
+ \fBTcl_Eval\fR returns a completion code and result just like
+\fBTcl_EvalObjEx\fR. Note: for backward compatibility with versions before
+Tcl 8.0, \fBTcl_Eval\fR copies the object result in \fIinterp\fR to
+\fIinterp->result\fR (use is deprecated) where it can be accessed directly.
+ This makes \fBTcl_Eval\fR somewhat slower than \fBTcl_EvalEx\fR, which
+does not do the copy.
+.PP
+\fBTcl_EvalEx\fR is an extended version of \fBTcl_Eval\fR that takes
+additional arguments \fInumBytes\fR and \fIflags\fR. For the
+efficiency reason given above, \fBTcl_EvalEx\fR is generally preferred
+over \fBTcl_Eval\fR.
+.PP
+\fBTcl_GlobalEval\fR and \fBTcl_GlobalEvalObj\fR are older procedures
+that are now deprecated. They are similar to \fBTcl_EvalEx\fR and
+\fBTcl_EvalObjEx\fR except that the script is evaluated in the global
+namespace and its variable context consists of global variables only
+(it ignores any Tcl procedures that are active). These functions are
+equivalent to using the \fBTCL_EVAL_GLOBAL\fR flag (see below).
+.PP
+\fBTcl_VarEval\fR takes any number of string arguments
+of any length, concatenates them into a single string,
+then calls \fBTcl_Eval\fR to execute that string as a Tcl command.
+It returns the result of the command and also modifies
+\fIinterp->result\fR in the same way as \fBTcl_Eval\fR.
+The last argument to \fBTcl_VarEval\fR must be NULL to indicate the end
+of arguments. \fBTcl_VarEval\fR is now deprecated.
+.PP
+\fBTcl_VarEvalVA\fR is the same as \fBTcl_VarEval\fR except that
+instead of taking a variable number of arguments it takes an argument
+list. Like \fBTcl_VarEval\fR, \fBTcl_VarEvalVA\fR is deprecated.
+
+.SH "FLAG BITS"
+.PP
+Any ORed combination of the following values may be used for the
+\fIflags\fR argument to procedures such as \fBTcl_EvalObjEx\fR:
+.TP 23
+\fBTCL_EVAL_DIRECT\fR
+.
+This flag is only used by \fBTcl_EvalObjEx\fR; it is ignored by
+other procedures. If this flag bit is set, the script is not
+compiled to bytecodes; instead it is executed directly
+as is done by \fBTcl_EvalEx\fR. The
+\fBTCL_EVAL_DIRECT\fR flag is useful in situations where the
+contents of an object are going to change immediately, so the
+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
+means that it is evaluated in the global namespace and its variable
+context consists of global variables only (it ignores any Tcl
+procedures that are active).
+
+.SH "MISCELLANEOUS DETAILS"
+.PP
+During the processing of a Tcl command it is legal to make nested
+calls to evaluate other commands (this is how procedures and
+some control structures are implemented).
+If a code other than \fBTCL_OK\fR is returned
+from a nested \fBTcl_EvalObjEx\fR invocation,
+then the caller should normally return immediately,
+passing that same return code back to its caller,
+and so on until the top-level application is reached.
+A few commands, like \fBfor\fR, will check for certain
+return codes, like \fBTCL_BREAK\fR and \fBTCL_CONTINUE\fR, and process them
+specially without returning.
+.PP
+\fBTcl_EvalObjEx\fR keeps track of how many nested \fBTcl_EvalObjEx\fR
+invocations are in progress for \fIinterp\fR.
+If a code of \fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR is
+about to be returned from the topmost \fBTcl_EvalObjEx\fR
+invocation for \fIinterp\fR,
+it converts the return code to \fBTCL_ERROR\fR
+and sets \fIinterp\fR's result to an error message indicating that
+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.
+
+.SH KEYWORDS
+execute, file, global, object, result, script
diff --git a/pkgs/msgcat/doc/Exit.3 b/pkgs/msgcat/doc/Exit.3
new file mode 100644
index 0000000..fd251c7
--- /dev/null
+++ b/pkgs/msgcat/doc/Exit.3
@@ -0,0 +1,140 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.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, Tcl_SetExitProc \- end the application or thread (and invoke exit handlers)
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_Exit\fR(\fIstatus\fR)
+.sp
+\fBTcl_Finalize\fR()
+.sp
+\fBTcl_CreateExitHandler\fR(\fIproc, clientData\fR)
+.sp
+\fBTcl_DeleteExitHandler\fR(\fIproc, clientData\fR)
+.sp
+\fBTcl_ExitThread\fR(\fIstatus\fR)
+.sp
+\fBTcl_FinalizeThread\fR()
+.sp
+\fBTcl_CreateThreadExitHandler\fR(\fIproc, clientData\fR)
+.sp
+\fBTcl_DeleteThreadExitHandler\fR(\fIproc, clientData\fR)
+.sp
+Tcl_ExitProc *
+\fBTcl_SetExitProc\fR(\fIproc\fR)
+.SH ARGUMENTS
+.AS Tcl_ExitProc clientData
+.AP int status in
+Provides information about why the application or thread exited.
+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, 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
+
+.SH DESCRIPTION
+.PP
+The procedures described here provide a graceful mechanism to end the
+execution of a \fBTcl\fR application. Exit handlers are invoked to cleanup the
+application's state before ending the execution of \fBTcl\fR code.
+.PP
+Invoke \fBTcl_Exit\fR to end a \fBTcl\fR application and to exit from this
+process. This procedure is invoked by the \fBexit\fR command, and can be
+invoked anyplace else to terminate the application.
+No-one should ever invoke the \fBexit\fR system procedure directly; always
+invoke \fBTcl_Exit\fR instead, so that it can invoke exit handlers.
+Note that if other code invokes \fBexit\fR system procedure directly, or
+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.
+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.
+.PP
+\fBTcl_Finalize\fR is similar to \fBTcl_Exit\fR except that it does not
+exit from the current process.
+It is useful for cleaning up when a process is finished using \fBTcl\fR but
+wishes to continue executing, and when \fBTcl\fR is used in a dynamically
+loaded extension that is about to be unloaded.
+Your code should always invoke \fBTcl_Finalize\fR when \fBTcl\fR is being
+unloaded, to ensure proper cleanup. \fBTcl_Finalize\fR can be safely called
+more than once.
+.PP
+\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.
+.PP
+\fBTcl_CreateExitHandler\fR arranges for \fIproc\fR to be invoked
+by \fBTcl_Finalize\fR and \fBTcl_Exit\fR.
+\fBTcl_CreateThreadExitHandler\fR arranges for \fIproc\fR to be invoked
+by \fBTcl_FinalizeThread\fR and \fBTcl_ExitThread\fR.
+This provides a hook for cleanup operations such as flushing buffers
+and freeing global memory.
+\fIProc\fR should match the type \fBTcl_ExitProc\fR:
+.PP
+.CS
+typedef void \fBTcl_ExitProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR parameter to \fIproc\fR is a
+copy of the \fIclientData\fR argument given to
+\fBTcl_CreateExitHandler\fR or \fBTcl_CreateThreadExitHandler\fR when
+the callback
+was created. Typically, \fIclientData\fR points to a data
+structure containing application-specific information about
+what to do in \fIproc\fR.
+.PP
+\fBTcl_DeleteExitHandler\fR and \fBTcl_DeleteThreadExitHandler\fR may be
+called to delete a
+previously-created exit handler. It removes the handler
+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
+\fBTcl_Finalize\fR and \fBTcl_Exit\fR execute all registered exit handlers,
+in reverse order from the order in which they were registered.
+This matches the natural order in which extensions are loaded and unloaded;
+if extension \fBA\fR loads extension \fBB\fR, it usually
+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.
+.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.
+.PP
+\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.
+.SH "SEE ALSO"
+exit(n)
+.SH KEYWORDS
+abort, callback, cleanup, dynamic loading, end application, exit, unloading, thread
diff --git a/pkgs/msgcat/doc/ExprLong.3 b/pkgs/msgcat/doc/ExprLong.3
new file mode 100644
index 0000000..ef93284
--- /dev/null
+++ b/pkgs/msgcat/doc/ExprLong.3
@@ -0,0 +1,106 @@
+'\"
+'\" Copyright (c) 1989-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.
+'\"
+.so man.macros
+.TH Tcl_ExprLong 3 7.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean, Tcl_ExprString \- evaluate an expression
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_ExprLong\fR(\fIinterp, expr, longPtr\fR)
+.sp
+int
+\fBTcl_ExprDouble\fR(\fIinterp, expr, doublePtr\fR)
+.sp
+int
+\fBTcl_ExprBoolean\fR(\fIinterp, expr, booleanPtr\fR)
+.sp
+int
+\fBTcl_ExprString\fR(\fIinterp, expr\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *booleanPtr out
+.AP Tcl_Interp *interp in
+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
+expression.
+.AP int *doublePtr out
+Pointer to location in which to store the floating-point value of the
+expression.
+.AP int *booleanPtr out
+Pointer to location in which to store the 0/1 boolean value of the
+expression.
+.BE
+
+.SH DESCRIPTION
+.PP
+These four procedures all evaluate the expression
+given by the \fIexpr\fR argument
+and return the result in one of four different forms.
+The expression can have any of the forms accepted by the \fBexpr\fR command.
+Note that these procedures have been largely replaced by the
+object-based procedures \fBTcl_ExprLongObj\fR, \fBTcl_ExprDoubleObj\fR,
+\fBTcl_ExprBooleanObj\fR, and \fBTcl_ExprObj\fR.
+Those object-based procedures evaluate an expression held in a Tcl object
+instead of a string.
+The object argument can retain an internal representation
+that is more efficient to execute.
+.PP
+The \fIinterp\fR argument refers to an interpreter used to
+evaluate the expression (e.g. for variables and nested Tcl
+commands) and to return error information.
+.PP
+For all of these procedures the return value is a standard
+Tcl result: \fBTCL_OK\fR means the expression was successfully
+evaluated, and \fBTCL_ERROR\fR means that an error occurred while
+evaluating the expression.
+If \fBTCL_ERROR\fR is returned then
+the interpreter's result will hold a message describing the error.
+If an error occurs while executing a Tcl command embedded in
+the expression then that error will be returned.
+.PP
+If the expression is successfully evaluated, then its value is
+returned in one of four forms, depending on which procedure
+is invoked.
+\fBTcl_ExprLong\fR stores an integer value at \fI*longPtr\fR.
+If the expression's actual value is a floating-point number,
+then it is truncated to an integer.
+If the expression's actual value is a non-numeric string then
+an error is returned.
+.PP
+\fBTcl_ExprDouble\fR stores a floating-point value at \fI*doublePtr\fR.
+If the expression's actual value is an integer, it is converted to
+floating-point.
+If the expression's actual value is a non-numeric string then
+an error is returned.
+.PP
+\fBTcl_ExprBoolean\fR stores a 0/1 integer value at \fI*booleanPtr\fR.
+If the expression's actual value is an integer or floating-point
+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
+.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.
+
+.SH "SEE ALSO"
+Tcl_ExprLongObj, Tcl_ExprDoubleObj, Tcl_ExprBooleanObj, Tcl_ExprObj
+
+.SH KEYWORDS
+boolean, double, evaluate, expression, integer, object, string
diff --git a/pkgs/msgcat/doc/ExprLongObj.3 b/pkgs/msgcat/doc/ExprLongObj.3
new file mode 100644
index 0000000..c8a564d
--- /dev/null
+++ b/pkgs/msgcat/doc/ExprLongObj.3
@@ -0,0 +1,106 @@
+'\"
+'\" Copyright (c) 1996-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 Tcl_ExprLongObj 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_ExprLongObj, Tcl_ExprDoubleObj, Tcl_ExprBooleanObj, Tcl_ExprObj \- evaluate an expression
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_ExprLongObj\fR(\fIinterp, objPtr, longPtr\fR)
+.sp
+int
+\fBTcl_ExprDoubleObj\fR(\fIinterp, objPtr, doublePtr\fR)
+.sp
+int
+\fBTcl_ExprBooleanObj\fR(\fIinterp, objPtr, booleanPtr\fR)
+.sp
+int
+\fBTcl_ExprObj\fR(\fIinterp, objPtr, resultPtrPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp **resultPtrPtr out
+.AP Tcl_Interp *interp in
+Interpreter in whose context to evaluate \fIobjPtr\fR.
+.AP Tcl_Obj *objPtr in
+Pointer to an object containing the expression to evaluate.
+.AP long *longPtr out
+Pointer to location in which to store the integer value of the
+expression.
+.AP int *doublePtr out
+Pointer to location in which to store the floating-point value of the
+expression.
+.AP int *booleanPtr out
+Pointer to location in which to store the 0/1 boolean value of the
+expression.
+.AP Tcl_Obj **resultPtrPtr out
+Pointer to location in which to store a pointer to the object
+that is the result of the expression.
+.BE
+
+.SH DESCRIPTION
+.PP
+These four procedures all evaluate an expression, returning
+the result in one of four different forms.
+The expression is given by the \fIobjPtr\fR argument, and it
+can have any of the forms accepted by the \fBexpr\fR command.
+.PP
+The \fIinterp\fR argument refers to an interpreter used to
+evaluate the expression (e.g. for variables and nested Tcl
+commands) and to return error information.
+.PP
+For all of these procedures the return value is a standard
+Tcl result: \fBTCL_OK\fR means the expression was successfully
+evaluated, and \fBTCL_ERROR\fR means that an error occurred while
+evaluating the expression.
+If \fBTCL_ERROR\fR is returned,
+then a message describing the error
+can be retrieved using \fBTcl_GetObjResult\fR.
+If an error occurs while executing a Tcl command embedded in
+the expression then that error will be returned.
+.PP
+If the expression is successfully evaluated, then its value is
+returned in one of four forms, depending on which procedure
+is invoked.
+\fBTcl_ExprLongObj\fR stores an integer value at \fI*longPtr\fR.
+If the expression's actual value is a floating-point number,
+then it is truncated to an integer.
+If the expression's actual value is a non-numeric string then
+an error is returned.
+.PP
+\fBTcl_ExprDoubleObj\fR stores a floating-point value at \fI*doublePtr\fR.
+If the expression's actual value is an integer, it is converted to
+floating-point.
+If the expression's actual value is a non-numeric string then
+an error is returned.
+.PP
+\fBTcl_ExprBooleanObj\fR stores a 0/1 integer value at \fI*booleanPtr\fR.
+If the expression's actual value is an integer or floating-point
+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
+.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
+containing the expression's value at \fI*resultPtrPtr\fR.
+In this case, the caller is responsible for calling
+\fBTcl_DecrRefCount\fR to decrement the object's reference count
+when it is finished with the object.
+
+.SH "SEE ALSO"
+Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean, Tcl_ExprString, Tcl_GetObjResult
+
+.SH KEYWORDS
+boolean, double, evaluate, expression, integer, object, string
diff --git a/pkgs/msgcat/doc/FileSystem.3 b/pkgs/msgcat/doc/FileSystem.3
new file mode 100644
index 0000000..d7198b1
--- /dev/null
+++ b/pkgs/msgcat/doc/FileSystem.3
@@ -0,0 +1,1643 @@
+'\"
+'\" Copyright (c) 2001 Vincent Darley
+'\" Copyright (c) 2008-2010 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 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_FSEvalFileEx, Tcl_FSLoadFile, Tcl_FSUnloadFile, Tcl_FSMatchInDirectory, Tcl_FSLink, Tcl_FSLstat, Tcl_FSUtime, Tcl_FSFileAttrsGet, Tcl_FSFileAttrsSet, Tcl_FSFileAttrStrings, Tcl_FSStat, Tcl_FSAccess, Tcl_FSOpenFileChannel, Tcl_FSGetCwd, Tcl_FSChdir, Tcl_FSPathSeparator, Tcl_FSJoinPath, Tcl_FSSplitPath, Tcl_FSEqualPaths, Tcl_FSGetNormalizedPath, Tcl_FSJoinToPath, Tcl_FSConvertToPathType, Tcl_FSGetInternalRep, Tcl_FSGetTranslatedPath, Tcl_FSGetTranslatedStringPath, Tcl_FSNewNativePath, Tcl_FSGetNativePath, Tcl_FSFileSystemInfo, Tcl_GetAccessTimeFromStat, Tcl_GetBlockSizeFromStat, Tcl_GetBlocksFromStat, Tcl_GetChangeTimeFromStat, Tcl_GetDeviceTypeFromStat, Tcl_GetFSDeviceFromStat, Tcl_GetFSInodeFromStat, Tcl_GetGroupIdFromStat, Tcl_GetLinkCountFromStat, Tcl_GetModeFromStat, Tcl_GetModificationTimeFromStat, Tcl_GetSizeFromStat, Tcl_GetUserIdFromStat, Tcl_AllocStatBuf \- procedures to interact with any filesystem
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_FSRegister\fR(\fIclientData, fsPtr\fR)
+.sp
+int
+\fBTcl_FSUnregister\fR(\fIfsPtr\fR)
+.sp
+ClientData
+\fBTcl_FSData\fR(\fIfsPtr\fR)
+.sp
+void
+\fBTcl_FSMountsChanged\fR(\fIfsPtr\fR)
+.sp
+const Tcl_Filesystem *
+\fBTcl_FSGetFileSystemForPath\fR(\fIpathPtr\fR)
+.sp
+Tcl_PathType
+\fBTcl_FSGetPathType\fR(\fIpathPtr\fR)
+.sp
+int
+\fBTcl_FSCopyFile\fR(\fIsrcPathPtr, destPathPtr\fR)
+.sp
+int
+\fBTcl_FSCopyDirectory\fR(\fIsrcPathPtr, destPathPtr, errorPtr\fR)
+.sp
+int
+\fBTcl_FSCreateDirectory\fR(\fIpathPtr\fR)
+.sp
+int
+\fBTcl_FSDeleteFile\fR(\fIpathPtr\fR)
+.sp
+int
+\fBTcl_FSRemoveDirectory\fR(\fIpathPtr, int recursive, errorPtr\fR)
+.sp
+int
+\fBTcl_FSRenameFile\fR(\fIsrcPathPtr, destPathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSListVolumes\fR(\fIvoid\fR)
+.sp
+int
+\fBTcl_FSEvalFileEx\fR(\fIinterp, pathPtr, encodingName\fR)
+.sp
+int
+\fBTcl_FSEvalFile\fR(\fIinterp, pathPtr\fR)
+.sp
+int
+\fBTcl_FSLoadFile\fR(\fIinterp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
+ loadHandlePtr, unloadProcPtr\fR)
+.sp
+.VS 8.6
+int
+\fBTcl_FSUnloadFile\fR(\fIinterp, loadHandle\fR)
+.VE 8.6
+.sp
+int
+\fBTcl_FSMatchInDirectory\fR(\fIinterp, resultPtr, pathPtr, pattern, types\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSLink\fR(\fIlinkNamePtr, toPtr, linkAction\fR)
+.sp
+int
+\fBTcl_FSLstat\fR(\fIpathPtr, statPtr\fR)
+.sp
+int
+\fBTcl_FSUtime\fR(\fIpathPtr, tval\fR)
+.sp
+int
+\fBTcl_FSFileAttrsGet\fR(\fIinterp, int index, pathPtr, objPtrRef\fR)
+.sp
+int
+\fBTcl_FSFileAttrsSet\fR(\fIinterp, int index, pathPtr, Tcl_Obj *objPtr\fR)
+.sp
+const char **
+\fBTcl_FSFileAttrStrings\fR(\fIpathPtr, objPtrRef\fR)
+.sp
+int
+\fBTcl_FSStat\fR(\fIpathPtr, statPtr\fR)
+.sp
+int
+\fBTcl_FSAccess\fR(\fIpathPtr, mode\fR)
+.sp
+Tcl_Channel
+\fBTcl_FSOpenFileChannel\fR(\fIinterp, pathPtr, modeString, permissions\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSGetCwd\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_FSChdir\fR(\fIpathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSPathSeparator\fR(\fIpathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSJoinPath\fR(\fIlistObj, elements\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSSplitPath\fR(\fIpathPtr, lenPtr\fR)
+.sp
+int
+\fBTcl_FSEqualPaths\fR(\fIfirstPtr, secondPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSGetNormalizedPath\fR(\fIinterp, pathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSJoinToPath\fR(\fIbasePtr, objc, objv\fR)
+.sp
+int
+\fBTcl_FSConvertToPathType\fR(\fIinterp, pathPtr\fR)
+.sp
+ClientData
+\fBTcl_FSGetInternalRep\fR(\fIpathPtr, fsPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSGetTranslatedPath\fR(\fIinterp, pathPtr\fR)
+.sp
+const char *
+\fBTcl_FSGetTranslatedStringPath\fR(\fIinterp, pathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSNewNativePath\fR(\fIfsPtr, clientData\fR)
+.sp
+const void *
+\fBTcl_FSGetNativePath\fR(\fIpathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSFileSystemInfo\fR(\fIpathPtr\fR)
+.sp
+Tcl_StatBuf *
+\fBTcl_AllocStatBuf\fR()
+.sp
+.VS 8.6
+Tcl_WideInt
+\fBTcl_GetAccessTimeFromStat\fR(\fIstatPtr\fR)
+.sp
+unsigned
+\fBTcl_GetBlockSizeFromStat\fR(\fIstatPtr\fR)
+.sp
+Tcl_WideUInt
+\fBTcl_GetBlocksFromStat\fR(\fIstatPtr\fR)
+.sp
+Tcl_WideInt
+\fBTcl_GetChangeTimeFromStat\fR(\fIstatPtr\fR)
+.sp
+int
+\fBTcl_GetDeviceTypeFromStat\fR(\fIstatPtr\fR)
+.sp
+unsigned
+\fBTcl_GetFSDeviceFromStat\fR(\fIstatPtr\fR)
+.sp
+unsigned
+\fBTcl_GetFSInodeFromStat\fR(\fIstatPtr\fR)
+.sp
+int
+\fBTcl_GetGroupIdFromStat\fR(\fIstatPtr\fR)
+.sp
+int
+\fBTcl_GetLinkCountFromStat\fR(\fIstatPtr\fR)
+.sp
+unsigned
+\fBTcl_GetModeFromStat\fR(\fIstatPtr\fR)
+.sp
+Tcl_WideInt
+\fBTcl_GetModificationTimeFromStat\fR(\fIstatPtr\fR)
+.sp
+Tcl_WideUInt
+\fBTcl_GetSizeFromStat\fR(\fIstatPtr\fR)
+.sp
+int
+\fBTcl_GetUserIdFromStat\fR(\fIstatPtr\fR)
+.VE 8.6
+.SH ARGUMENTS
+.AS Tcl_GlobTypeData **srcPathPtr out
+.AP "const Tcl_Filesystem" *fsPtr in
+Points to a structure containing the addresses of procedures that
+can be called to perform the various filesystem operations.
+.AP Tcl_Obj *pathPtr in
+The path represented by this object is used for the operation in
+question. If the object does not already have an internal \fBpath\fR
+representation, it will be converted to have one.
+.AP Tcl_Obj *srcPathPtr in
+As for \fIpathPtr\fR, but used for the source file for a copy or
+rename operation.
+.AP Tcl_Obj *destPathPtr in
+As for \fIpathPtr\fR, but used for the destination filename for a copy or
+rename operation.
+.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. This parameter may be NULL.
+.AP Tcl_Interp *interp in
+Interpreter to use either for results, evaluation, or reporting error
+messages.
+.AP ClientData clientData in
+The native description of the path object to create.
+.AP Tcl_Obj *firstPtr in
+The first of two path objects to compare. The object may be converted
+to \fBpath\fR type.
+.AP Tcl_Obj *secondPtr in
+The second of two path objects to compare. The object may be converted
+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 \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 *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,
+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
+Name of a procedure to look up in the file's symbol table
+.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 ClientData *clientDataPtr out
+Filled with the clientData value to pass to this code's unload
+function when it is called.
+.AP Tcl_LoadHandle *loadHandlePtr 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 Tcl_LoadHandle loadHandle in
+Handle to the loaded library to be unloaded.
+.AP utimbuf *tval in
+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
+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
+POSIX-style permission flags such as 0644. If a new file is created, these
+permissions will be set on the created file.
+.AP int *lenPtr out
+If non-NULL, filled with the number of elements in the split path.
+.AP Tcl_Obj *basePtr in
+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
+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 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 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
+.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
+.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
+.QW files
+which are not
+native files in the native filesystem. This also means that any Tcl
+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.
+.PP
+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
+.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 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 reference count of zero to any of these functions. If such calls were
+handled, they might result
+in memory leaks (under some circumstances, the filesystem code may wish
+to retain a reference to the passed in object, and so one must not assume
+that after any of these calls return, the object still has a reference count of
+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
+.PP
+.CS
+Tcl_Obj *path = Tcl_NewStringObj(...);
+Tcl_FS\fIWhatever\fR(path);
+Tcl_DecrRefCount(path);
+.CE
+.PP
+is wrong, and may cause memory errors. The \fIpath\fR must have its
+reference count incremented before passing it in, or
+decrementing it. For this reason, objects with a reference count of zero are
+considered not to be valid filesystem paths and calling any Tcl_FS API
+function with such an object will result in no action being taken.
+.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
+.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
+.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
+\fIpathPtr\fR by calling the owning filesystem's
+.QW "create directory"
+function.
+.PP
+\fBTcl_FSDeleteFile\fR attempts to delete the file given by
+\fIpathPtr\fR by calling the owning filesystem's
+.QW "delete file"
+function.
+.PP
+\fBTcl_FSRemoveDirectory\fR attempts to remove the directory given by
+\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
+\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
+.QW "rename 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_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 reference count of 0).
+.PP
+\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 \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.
+.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 \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.
+.VS 8.6
+\fBTcl_FSUnloadFile\fR reverses the operation, asking for the library
+indicated by the \fIloadHandle\fR to be removed from the process. Note that,
+unlike with the \fBunload\fR command, this does not give the library any
+opportunity to clean up.
+.VE 8.6
+.PP
+Both the above functions return a standard Tcl completion code. If an error
+occurs, an error message is left in the \fIinterp\fR's result.
+.PP
+.VS 8.6
+The token provided via the variable indicated by \fIloadHandlePtr\fR may be
+used with \fBTcl_FindSymbol\fR.
+.VE 8.6
+.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 \fIpathPtr\fR belongs will be called.
+.PP
+The return value is a standard Tcl result indicating whether an error
+occurred in globbing. Error messages are placed in interp (unless
+interp is NULL, which is allowed), but good results are placed in the
+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 \fBstring match\fR. To handle recursion, Tcl
+will call this function frequently asking only for directories to be
+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 \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
+.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 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 is returned.
+.PP
+\fBTcl_FSLstat\fR fills the \fITcl_StatBuf\fR structure \fIstatPtr\fR with
+information about the specified file. You do not need any access rights to the
+file to get this information but you need search rights to all
+directories named in the path leading to the file. The \fITcl_StatBuf\fR
+structure includes info regarding device, inode (always 0 on Windows),
+privilege mode, nlink (always 1 on Windows), user id (always 0 on
+Windows), group id (always 0 on Windows), rdev (same as device on
+Windows), size, last access time, last modification time, and
+last metadata change time.
+See \fBPORTABLE STAT RESULT API\fR for a description of how to write
+portable code to allocate and access the \fITcl_StatBuf\fR structure.
+.PP
+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.
+.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
+\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
+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
+\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_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
+The called procedure may either return an array of strings, or may
+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
+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 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.
+.PP
+\fBTcl_FSStat\fR fills the \fITcl_StatBuf\fR structure \fIstatPtr\fR with
+information about the specified file. You do not need any access rights to the
+file to get this information but you need search rights to all
+directories named in the path leading to the file. The \fITcl_StatBuf\fR
+structure includes info regarding device, inode (always 0 on Windows),
+privilege mode, nlink (always 1 on Windows), user id (always 0 on
+Windows), group id (always 0 on Windows), rdev (same as device on
+Windows), size, last access time, last modification time, and
+last metadata change time.
+See \fBPORTABLE STAT RESULT API\fR for a description of how to write
+portable code to allocate and access the \fITcl_StatBuf\fR structure.
+.PP
+If \fIpath\fR exists, \fBTcl_FSStat\fR returns 0 and the stat structure
+is filled with data. Otherwise, -1 is returned, and no stat info is
+given.
+.PP
+\fBTcl_FSOpenFileChannel\fR opens a file specified by \fIpathPtr\fR and
+returns a channel handle that can be used to perform input and output on
+the file. This API is modeled after the \fBfopen\fR procedure of
+the Unix standard I/O library.
+The syntax and meaning of all arguments is similar to those
+given in the Tcl \fBopen\fR command when opening a file.
+If an error occurs while opening the channel, \fBTcl_FSOpenFileChannel\fR
+returns NULL and records a POSIX error code that can be
+retrieved with \fBTcl_GetErrno\fR.
+In addition, if \fIinterp\fR is non-NULL, \fBTcl_FSOpenFileChannel\fR
+leaves an error message in \fIinterp\fR's result after any error.
+.PP
+The newly created channel is not registered in the supplied interpreter; to
+register it, use \fBTcl_RegisterChannel\fR.
+If one of the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.PP
+\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, 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 \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 \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 \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 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
+an element.
+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.
+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, 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, 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
+.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
+path object, in the given filesystem. If the path object belongs to a
+different filesystem, we return NULL. If the internal representation is
+currently NULL, we attempt to generate it, by calling the filesystem's
+\fBTcl_FSCreateInternalRepProc\fR.
+.PP
+Returns NULL or a valid internal path representation. This internal
+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.
+.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
+.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
+\fBTcl_FSGetNormalizedPath\fR or \fBTcl_FSGetNativePath\fR are usually
+better functions to use for most purposes.
+.PP
+\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 \fBckfree\fR to ensure it is freed. Again,
+\fBTcl_FSGetNormalizedPath\fR or \fBTcl_FSGetNativePath\fR are usually
+better functions to use for most purposes.
+.PP
+\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.\ \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
+.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 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. 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. 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.
+.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.
+.PP
+A valid list object is returned, unless the path object is not
+recognized, when NULL will be returned.
+.PP
+\fBTcl_FSGetFileSystemForPath\fR returns a pointer to the
+\fBTcl_Filesystem\fR which accepts this path as valid.
+.PP
+If no filesystem will accept the path, NULL is returned.
+.PP
+\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 \fBTCL_PATH_ABSOLUTE\fR, \fBTCL_PATH_RELATIVE\fR, or
+\fBTCL_PATH_VOLUME_RELATIVE\fR
+.SS "PORTABLE STAT RESULT API"
+.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
+.VS 8.6
+The portable fields of a \fITcl_StatBuf\fR may be read using the following
+functions, each of which returns the value of the corresponding field listed
+in the table below. Note that on some platforms there may be other fields in
+the \fITcl_StatBuf\fR as it is an alias for a suitable system structure, but
+only the portable ones are made available here. See your system documentation
+for a full description of these fields.
+.DS
+.ta \w'\fBTcl_GetModificationTimeFromStat\fR\0\0\0\0'u
+\fIAccess Function\fR \fIField\fR
+ \fBTcl_GetFSDeviceFromStat\fR st_dev
+ \fBTcl_GetFSInodeFromStat\fR st_ino
+ \fBTcl_GetModeFromStat\fR st_mode
+ \fBTcl_GetLinkCountFromStat\fR st_nlink
+ \fBTcl_GetUserIdFromStat\fR st_uid
+ \fBTcl_GetGroupIdFromStat\fR st_gid
+ \fBTcl_GetDeviceTypeFromStat\fR st_rdev
+ \fBTcl_GetAccessTimeFromStat\fR st_atime
+ \fBTcl_GetModificationTimeFromStat\fR st_mtime
+ \fBTcl_GetChangeTimeFromStat\fR st_ctime
+ \fBTcl_GetSizeFromStat\fR st_size
+ \fBTcl_GetBlocksFromStat\fR st_blocks
+ \fBTcl_GetBlockSizeFromStat\fR st_blksize
+.DE
+.VE 8.6
+.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.
+.PP
+The \fBTcl_Filesystem\fR structures are manipulated using the following
+methods.
+.PP
+\fBTcl_FSRegister\fR takes a pointer to a filesystem structure and an
+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). \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 \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
+filesystem, if that filesystem is registered. Otherwise it will
+return NULL.
+.PP
+\fBTcl_FSMountsChanged\fR is used to inform the Tcl's core that
+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:
+.PP
+.CS
+typedef struct Tcl_Filesystem {
+ 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_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_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;
+} \fBTcl_Filesystem\fR;
+.CE
+.PP
+Except for the first three fields in this structure which contain
+simple data elements, all entries contain addresses of functions called
+by the generic filesystem layer to perform the complete range of
+filesystem related actions.
+.PP
+The many functions in this structure are broken down into three
+categories: infrastructure functions (almost all of which must be
+implemented), operational functions (which must be implemented if a
+complete filesystem is provided), and efficiency functions (which need
+only be implemented if they can be done so efficiently, or if they have
+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 \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_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 (\fBlstat\fR, \fBload\fR, \fBgetcwd\fR and \fBchdir\fR)
+for which fallbacks do in fact occur at the C level.
+.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.
+.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.
+.PP
+.CS
+static Tcl_Filesystem vfsFilesystem = {
+ "tclvfs",
+ sizeof(Tcl_Filesystem),
+ TCL_FILESYSTEM_VERSION_1,
+ &VfsPathInFilesystem,
+ &VfsDupInternalRep,
+ &VfsFreeInternalRep,
+ /* No internal to normalized, since we don't create
+ * any pure 'internal' Tcl_Obj path representations */
+ NULL,
+ /* No create native rep function, since we don't use
+ * it and don't choose to support uses of
+ * Tcl_FSNewNativePath */
+ NULL,
+ /* Normalize path isn't needed - we assume paths only
+ * have one representation */
+ NULL,
+ &VfsFilesystemPathType,
+ &VfsFilesystemSeparator,
+ &VfsStat,
+ &VfsAccess,
+ &VfsOpenFileChannel,
+ &VfsMatchInDirectory,
+ &VfsUtime,
+ /* We choose not to support symbolic links inside our
+ * VFS's */
+ NULL,
+ &VfsListVolumes,
+ &VfsFileAttrStrings,
+ &VfsFileAttrsGet,
+ &VfsFileAttrsSet,
+ &VfsCreateDirectory,
+ &VfsRemoveDirectory,
+ &VfsDeleteFile,
+ /* No copy file; use the core fallback mechanism */
+ NULL,
+ /* No rename file; use the core fallback mechanism */
+ NULL,
+ /* No copy directory; use the core fallback mechanism */
+ NULL,
+ /* Core will use stat for lstat */
+ NULL,
+ /* No load; use the core fallback mechanism */
+ NULL,
+ /* We don't need a getcwd or chdir; the core's own
+ * internal value is suitable */
+ NULL,
+ NULL
+};
+.CE
+.SH "FILESYSTEM INFRASTRUCTURE"
+.PP
+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.
+.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.
+.SS VERSION
+.PP
+The \fIversion\fR field should be set to \fBTCL_FILESYSTEM_VERSION_1\fR.
+.SS PATHINFILESYSTEMPROC
+.PP
+The \fIpathInFilesystemProc\fR field contains the address of a function
+which is called to determine whether a given path object belongs to this
+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 behavior of Tcl
+for any other return value is not defined). If \fBTCL_OK\fR is returned,
+then the optional \fIclientDataPtr\fR output parameter can be used to
+return an internal (filesystem specific) representation of the path,
+which will be cached inside the path object, and may be retrieved
+efficiently by the other filesystem functions. Tcl will simultaneously
+cache the fact that this path belongs to this filesystem. Such caches
+are invalidated when filesystem structures are added or removed from
+Tcl's internal list of known filesystems.
+.PP
+.CS
+typedef int \fBTcl_FSPathInFilesystemProc\fR(
+ Tcl_Obj *\fIpathPtr\fR,
+ ClientData *\fIclientDataPtr\fR);
+.CE
+.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
+simply not copy the internal representation, which may then need to be
+regenerated later.
+.PP
+.CS
+typedef ClientData \fBTcl_FSDupInternalRepProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.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 \fBTcl_FSFreeInternalRepProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.SS INTERNALTONORMALIZEDPROC
+.PP
+Function to convert internal representation to a normalized path. Only
+required if the filesystem creates pure path objects with no string/path
+representation. The return value is a Tcl object whose string
+representation is the normalized path.
+.PP
+.CS
+typedef Tcl_Obj *\fBTcl_FSInternalToNormalizedProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.SS CREATEINTERNALREPPROC
+.PP
+Function to take a path object, and calculate an internal
+representation for it, and store that native representation in the
+object. May be NULL if paths have no internal representation, or if
+the \fITcl_FSPathInFilesystemProc\fR for this filesystem always
+immediately creates an internal representation for paths it accepts.
+.PP
+.CS
+typedef ClientData \fBTcl_FSCreateInternalRepProc\fR(
+ Tcl_Obj *\fIpathPtr\fR);
+.CE
+.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
+.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
+.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 \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
+up to and including the file separator is known and normalized.
+.PP
+.CS
+typedef int \fBTcl_FSNormalizePathProc\fR(
+ Tcl_Interp *\fIinterp\fR,
+ Tcl_Obj *\fIpathPtr\fR,
+ int \fInextCheckpoint\fR);
+.CE
+.SH "FILESYSTEM OPERATIONS"
+.PP
+The fields in this section of the structure contain addresses of
+functions which are called to carry out the basic filesystem
+operations. A filesystem which expects to be used with the complete
+standard Tcl command set must implement all of these. If some of
+them are not implemented, then certain Tcl commands may fail when
+operating on paths within that filesystem. However, in some instances
+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).
+.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
+.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
+.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 *\fBTcl_FSFilesystemPathTypeProc\fR(
+ Tcl_Obj *\fIpathPtr\fR);
+.CE
+.SS FILESYSTEMSEPARATORPROC
+.PP
+Function to return the separator character(s) for this filesystem.
+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 *\fBTcl_FSFilesystemSeparatorProc\fR(
+ Tcl_Obj *\fIpathPtr\fR);
+.CE
+.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
+upon it (e.g.\ \fBfile atime\fR, \fBfile isdirectory\fR, \fBfile size\fR,
+\fBglob\fR).
+.PP
+.CS
+typedef int \fBTcl_FSStatProc\fR(
+ Tcl_Obj *\fIpathPtr\fR,
+ Tcl_StatBuf *\fIstatPtr\fR);
+.CE
+.PP
+The \fBTcl_FSStatProc\fR fills the stat structure \fIstatPtr\fR with
+information about the specified file. You do not need any access
+rights to the file to get this information but you need search rights
+to all directories named in the path leading to the file. The stat
+structure includes info regarding device, inode (always 0 on Windows),
+privilege mode, nlink (always 1 on Windows), user id (always 0 on
+Windows), group id (always 0 on Windows), rdev (same as device on
+Windows), size, last access time, last modification time, and
+last metadata change time.
+.PP
+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.
+.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
+upon it (e.g.\ \fBfile exists\fR, \fBfile readable\fR).
+.PP
+.CS
+typedef int \fBTcl_FSAccessProc\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 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
+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
+(e.g.\ \fBopen\fR, \fBencoding\fR, and many Tk commands).
+.PP
+.CS
+typedef Tcl_Channel \fBTcl_FSOpenFileChannelProc\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
+\fIpathPtr\fR and returns a channel handle that can be used to perform
+input and output on the file. This API is modeled after the \fBfopen\fR
+procedure of the Unix standard I/O library. The syntax and meaning of
+all arguments is similar to those given in the Tcl \fBopen\fR command
+when opening a file, where the \fImode\fR argument is a combination of
+the POSIX flags O_RDONLY, O_WRONLY, etc. If an error occurs while
+opening the channel, the \fBTcl_FSOpenFileChannelProc\fR returns NULL and
+records a POSIX error code that can be retrieved with \fBTcl_GetErrno\fR.
+In addition, if \fIinterp\fR is non-NULL, the
+\fBTcl_FSOpenFileChannelProc\fR leaves an error message in \fIinterp\fR's
+result after any error.
+.PP
+The newly created channel must not be registered in the supplied interpreter
+by a \fBTcl_FSOpenFileChannelProc\fR; that task is up to the caller of
+\fBTcl_FSOpenFileChannel\fR (if necessary). If one of
+the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it
+as a replacement for the standard channel.
+.SS MATCHINDIRECTORYPROC
+.PP
+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 \fBencoding names\fR
+which use glob functionality internally).
+.PP
+.CS
+typedef int \fBTcl_FSMatchInDirectoryProc\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
+objects) which match the given pattern and accord with the \fItypes\fR
+specification given. There are two ways in which this function may be
+called. If \fIpattern\fR is NULL, then \fIpathPtr\fR is a full path
+specification of a single file or directory which should be checked for
+existence and correct type. Otherwise, \fIpathPtr\fR is a directory, the
+contents of which the function should search for files or directories
+which have the correct type. In either case, \fIpathPtr\fR can be
+assumed to be both non-NULL and non-empty. It is not currently
+documented whether \fIpathPtr\fR will have a file separator at its end of
+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, 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
+The \fBTcl_GlobTypeData\fR structure passed in the \fItypes\fR
+parameter contains the following fields:
+.PP
+.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;
+} \fBTcl_GlobTypeData\fR;
+.CE
+.PP
+There are two specific cases which it is important to handle correctly,
+both when \fItypes\fR is non-NULL. The two cases are when \fItypes->types
+& TCL_GLOB_TYPE_DIR\fR or \fItypes->types & TCL_GLOB_TYPE_MOUNT\fR are
+true (and in particular when the other flags are false). In the first of
+these cases, the function must list the contained directories. Tcl uses
+this to implement recursive globbing, so it is critical that filesystems
+implement directory matching correctly. In the second of these cases,
+with \fBTCL_GLOB_TYPE_MOUNT\fR, the filesystem must list the mount points
+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.
+.SS UTIMEPROC
+.PP
+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 \fBTcl_FSUtimeProc\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 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
+only if the filesystem supports links, and may otherwise be NULL.
+.PP
+.CS
+typedef Tcl_Obj *\fBTcl_FSLinkProc\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 (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 reference count manipulations on either end are needed). See
+the documentation for \fBTcl_FSLink\fR for the correct interpretation
+of the \fIlinkAction\fR flags.
+.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 \fBfile volumes\fR.
+.PP
+.CS
+typedef Tcl_Obj *\fBTcl_FSListVolumesProc\fR(void);
+.CE
+.PP
+The result should be a list of volumes added by this filesystem, or
+NULL (or an empty list) if no volumes are provided. The result object
+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
+.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
+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.
+.SS FILEATTRSTRINGSPROC
+.PP
+Function to list all attribute strings which are valid for this
+filesystem. If not implemented the filesystem will not support
+the \fBfile attributes\fR command. This allows arbitrary additional
+information to be attached to files in the filesystem. If it is
+not implemented, there is no need to implement the \fBget\fR and \fBset\fR
+methods.
+.PP
+.CS
+typedef const char *const *\fBTcl_FSFileAttrStringsProc\fR(
+ 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 \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
+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 \fBfile
+attributes\fR.
+.PP
+.CS
+typedef int \fBTcl_FSFileAttrsGetProc\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 \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 reference count to ensure it is properly freed.
+.SS FILEATTRSSETPROC
+.PP
+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 \fBTcl_FSFileAttrsSetProc\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.
+.SS CREATEDIRECTORYPROC
+.PP
+Function to process a \fBTcl_FSCreateDirectory\fR call. Should be
+implemented unless the FS is read-only.
+.PP
+.CS
+typedef int \fBTcl_FSCreateDirectoryProc\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.
+.SS REMOVEDIRECTORYPROC
+.PP
+Function to process a \fBTcl_FSRemoveDirectory\fR call. Should be
+implemented unless the FS is read-only.
+.PP
+.CS
+typedef int \fBTcl_FSRemoveDirectoryProc\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 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 \fBTcl_FSDeleteFileProc\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, the file specified by
+\fIpathPtr\fR should have been removed from the filesystem. Note that,
+if the filesystem supports symbolic links, Tcl will always call this
+function and not Tcl_FSRemoveDirectoryProc when needed to delete them
+(even if they are symbolic links to directories).
+.SH "FILESYSTEM EFFICIENCY"
+.PP
+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
+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 \fBTcl_FSLstatProc\fR(
+ Tcl_Obj *\fIpathPtr\fR,
+ Tcl_StatBuf *\fIstatPtr\fR);
+.CE
+.PP
+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
+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 \fBTcl_FSCopyFileProc\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 \fBfile
+copy\fR subcommand). Note that,
+if the filesystem supports symbolic links, Tcl will always call this
+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 \fBTcl_FSRenameFileProc\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. 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 \fBTcl_FSCopyDirectoryProc\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
+occurred in the copying process. If an error does occur, the name of
+the file or directory which caused the error should be placed in
+\fIerrorPtr\fR. Note that, \fIdestPathPtr\fR is the name of the
+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 \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 \fBTCL_ERROR\fR to disable load functionality in this filesystem
+entirely.
+.PP
+.CS
+typedef int \fBTcl_FSLoadFileProc\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 \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
+cleanup action required.
+.PP
+.CS
+typedef void \fBTcl_FSUnloadFileProc\fR(
+ Tcl_LoadHandle \fIloadHandle\fR);
+.CE
+.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 \fBgetcwd\fR is
+called before \fBchdir\fR. May be NULL.
+.PP
+.CS
+typedef Tcl_Obj *\fBTcl_FSGetCwdProc\fR(
+ Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+If the filesystem supports a native notion of a current working
+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 \fIinterp\fR's result.
+.SS CHDIRPROC
+.PP
+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 \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
+\fBTcl_FSGetCwd\fR.
+Real filesystems should carry out the correct action (i.e.\ call the
+correct system \fBchdir\fR API).
+.PP
+.CS
+typedef int \fBTcl_FSChdirProc\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), filename(n), load(n), open(n), pwd(n), source(n), unload(n)
+.SH KEYWORDS
+stat, access, filesystem, vfs, virtual filesystem
diff --git a/pkgs/msgcat/doc/FindExec.3 b/pkgs/msgcat/doc/FindExec.3
new file mode 100644
index 0000000..e4b4ed0
--- /dev/null
+++ b/pkgs/msgcat/doc/FindExec.3
@@ -0,0 +1,63 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_FindExecutable 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_FindExecutable, Tcl_GetNameOfExecutable \- identify or return the name of the binary file containing the application
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_FindExecutable\fR(\fIargv0\fR)
+.sp
+const char *
+\fBTcl_GetNameOfExecutable\fR()
+.SH ARGUMENTS
+.AS char *argv0
+.AP char *argv0 in
+The first command-line argument to the program, which gives the
+application's name.
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBTcl_FindExecutable\fR procedure computes the full path name of
+the executable file from which the application was invoked and saves
+it for Tcl's internal use.
+The executable's path name is needed for several purposes in
+Tcl. For example, it is needed on some platforms in the
+implementation of the \fBload\fR command.
+It is also returned by the \fBinfo nameofexecutable\fR command.
+.PP
+On UNIX platforms this procedure is typically invoked as the very
+first thing in the application's main program; it must be passed
+\fIargv[0]\fR as its argument. It is important not to change the
+working directory before the invocation.
+\fBTcl_FindExecutable\fR uses \fIargv0\fR
+along with the \fBPATH\fR environment variable to find the
+application's executable, if possible. If it fails to find
+the binary, then future calls to \fBinfo nameofexecutable\fR
+will return an empty string.
+.PP
+On Windows platforms this procedure is typically invoked as the very
+first thing in the application's main program as well; Its \fIargv[0]\fR
+argument is only used to indicate whether the executable has a stderr
+channel (any non-null value) or not (the value null). If \fBTcl_SetPanicProc\fR
+is never called and no debugger is running, this determines whether
+the panic message is sent to stderr or to a standard system dialog.
+.PP
+\fBTcl_GetNameOfExecutable\fR simply returns a pointer to the
+internal full path name of the executable file as computed by
+\fBTcl_FindExecutable\fR. This procedure call is the C API
+equivalent to the \fBinfo nameofexecutable\fR command. NULL
+is returned if the internal full path name has not been
+computed or unknown.
+
+.SH KEYWORDS
+binary, executable file
diff --git a/pkgs/msgcat/doc/GetCwd.3 b/pkgs/msgcat/doc/GetCwd.3
new file mode 100755
index 0000000..964e237
--- /dev/null
+++ b/pkgs/msgcat/doc/GetCwd.3
@@ -0,0 +1,52 @@
+'\"
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_GetCwd 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_GetCwd, Tcl_Chdir \- manipulate the current working directory
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+char *
+\fBTcl_GetCwd\fR(\fIinterp\fR, \fIbufferPtr\fR)
+.sp
+int
+\fBTcl_Chdir\fR(\fIpath\fR)
+.SH ARGUMENTS
+.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
+This dynamic string is used to store the current working directory.
+At the time of the call it should be uninitialized or free. The
+caller must eventually call \fBTcl_DStringFree\fR to free up
+anything stored here.
+.AP char *path in
+File path in UTF\-8 format.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures may be used to manipulate the current working
+directory for the application. They provide C\-level access to
+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 \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.
+.PP
+\fBTcl_Chdir\fR changes the applications current working directory to
+the value specified in \fIpath\fR. The format of the passed in string
+must be UTF\-8. The function returns -1 on error or 0 on success.
+
+.SH KEYWORDS
+pwd
diff --git a/pkgs/msgcat/doc/GetHostName.3 b/pkgs/msgcat/doc/GetHostName.3
new file mode 100644
index 0000000..28f3a4f
--- /dev/null
+++ b/pkgs/msgcat/doc/GetHostName.3
@@ -0,0 +1,27 @@
+'\"
+'\" Copyright (c) 1998-2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.so man.macros
+.TH Tcl_GetHostName 3 8.3 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_GetHostName \- get the name of the local host
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+const char *
+\fBTcl_GetHostName\fR()
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_GetHostName\fR is a utility procedure used by some of the
+Tcl commands. It returns a pointer to a string containing the name
+for the current machine, or an empty string if the name cannot be
+determined. The string is statically allocated, and the caller must
+not modify of free it.
+.PP
+.SH KEYWORDS
+hostname
diff --git a/pkgs/msgcat/doc/GetIndex.3 b/pkgs/msgcat/doc/GetIndex.3
new file mode 100644
index 0000000..f60feb5
--- /dev/null
+++ b/pkgs/msgcat/doc/GetIndex.3
@@ -0,0 +1,98 @@
+'\"
+'\" 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 Tcl_GetIndexFromObj 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_GetIndexFromObj, Tcl_GetIndexFromObjStruct \- lookup string in table of keywords
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_GetIndexFromObj\fR(\fIinterp, objPtr, tablePtr, msg, flags,
+indexPtr\fR)
+.sp
+int
+\fBTcl_GetIndexFromObjStruct\fR(\fIinterp, objPtr, structTablePtr, offset,
+ msg, flags, indexPtr\fR)
+.SH ARGUMENTS
+.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.
+.AP Tcl_Obj *objPtr in/out
+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 *const" *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\fR type.
+The first member of the structure must be a null-terminated string.
+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.
+.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
+OR-ed combination of bits providing additional information for
+operation. The only bit that is currently defined is \fBTCL_EXACT\fR.
+.AP int *indexPtr out
+The index of the string in \fItablePtr\fR that matches the value of
+\fIobjPtr\fR is returned here.
+.BE
+.SH DESCRIPTION
+.PP
+This procedure provides an efficient way for looking up keywords,
+switch names, option names, and similar things where the value of
+an object must be one of a predefined set of values.
+\fIObjPtr\fR is compared against each of
+the strings in \fItablePtr\fR to find a match. A match occurs if
+\fIobjPtr\fR's string value is identical to one of the strings in
+\fItablePtr\fR, or if it is a non-empty unique abbreviation
+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 \fBTCL_OK\fR is returned.
+.PP
+If there is no matching entry,
+\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
+.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
+the table and the index of the matching entry. If \fBTcl_GetIndexFromObj\fR
+is invoked again with the same \fIobjPtr\fR and \fItablePtr\fR
+arguments (e.g. during a reinvocation of a Tcl command), it returns
+the matching index immediately without having to redo the lookup
+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 \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 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.
+.SH "SEE ALSO"
+prefix(n), Tcl_WrongNumArgs(3)
+.SH KEYWORDS
+index, object, table lookup
diff --git a/pkgs/msgcat/doc/GetInt.3 b/pkgs/msgcat/doc/GetInt.3
new file mode 100644
index 0000000..f77d337
--- /dev/null
+++ b/pkgs/msgcat/doc/GetInt.3
@@ -0,0 +1,86 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_GetInt 3 "" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_GetInt, Tcl_GetDouble, Tcl_GetBoolean \- convert from string to integer, double, or boolean
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_GetInt\fR(\fIinterp, src, intPtr\fR)
+.sp
+int
+\fBTcl_GetDouble\fR(\fIinterp, src, doublePtr\fR)
+.sp
+int
+\fBTcl_GetBoolean\fR(\fIinterp, src, boolPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *doublePtr out
+.AP Tcl_Interp *interp in
+Interpreter to use for error reporting.
+.AP "const char" *src in
+Textual value to be converted.
+.AP int *intPtr out
+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 \fIsrc\fR.
+.AP int *boolPtr out
+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 \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
+\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 \fIsrc\fR to consist of a collection
+of integer digits, optionally signed and optionally preceded by
+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 \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
+.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
+.QW e
+is present then it must be followed by the exponent number.
+.PP
+\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 \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.
+
+.SH KEYWORDS
+boolean, conversion, double, floating-point, integer
diff --git a/pkgs/msgcat/doc/GetOpnFl.3 b/pkgs/msgcat/doc/GetOpnFl.3
new file mode 100644
index 0000000..38aa976
--- /dev/null
+++ b/pkgs/msgcat/doc/GetOpnFl.3
@@ -0,0 +1,58 @@
+'\"
+'\" Copyright (c) 1996-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 Tcl_GetOpenFile 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+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, chanID, write, checkUsage, filePtr\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_Interp checkUsage out
+.AP Tcl_Interp *interp in
+Tcl interpreter from which file handle is to be obtained.
+.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 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 \fIchanID\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_GetOpenFile\fR takes as argument a file identifier of the form
+returned by the \fBopen\fR command and
+returns at \fI*filePtr\fR a pointer to the FILE structure for
+the file.
+The \fIwrite\fR argument indicates whether the FILE pointer will
+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 \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.
+.PP
+Note that this interface is only supported on the Unix platform.
+
+.SH KEYWORDS
+channel, file handle, permissions, pipeline, read, write
diff --git a/pkgs/msgcat/doc/GetStdChan.3 b/pkgs/msgcat/doc/GetStdChan.3
new file mode 100644
index 0000000..e76ad66
--- /dev/null
+++ b/pkgs/msgcat/doc/GetStdChan.3
@@ -0,0 +1,86 @@
+'\"
+'\" Copyright (c) 1996 by 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_GetStdChannel 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_GetStdChannel, Tcl_SetStdChannel \- procedures for retrieving and replacing the standard channels
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Channel
+\fBTcl_GetStdChannel\fR(\fItype\fR)
+.sp
+\fBTcl_SetStdChannel\fR(\fIchannel, type\fR)
+.sp
+.SH ARGUMENTS
+.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.
+.AP Tcl_Channel channel in
+The channel to use as the new value for the specified standard channel.
+.BE
+
+.SH DESCRIPTION
+.PP
+Tcl defines three special channels that are used by various I/O related
+commands if no other channels are specified. The standard input channel
+has a channel name of \fBstdin\fR and is used by \fBread\fR and \fBgets\fR.
+The standard output channel is named \fBstdout\fR and is used by
+\fBputs\fR. The standard error channel is named \fBstderr\fR and is used for
+reporting errors. In addition, the standard channels are inherited by any
+child processes created using \fBexec\fR or \fBopen\fR in the absence of any
+other redirections.
+.PP
+The standard channels are actually aliases for other normal channels. The
+current channel associated with a standard channel can be retrieved by calling
+\fBTcl_GetStdChannel\fR with one of
+\fBTCL_STDIN\fR, \fBTCL_STDOUT\fR, or \fBTCL_STDERR\fR as the \fItype\fR. The
+return value will be a valid channel, or NULL.
+.PP
+A new channel can be set for the standard channel specified by \fItype\fR
+by calling \fBTcl_SetStdChannel\fR with a new channel or NULL in the
+\fIchannel\fR argument. If the specified channel is closed by a later call to
+\fBTcl_Close\fR, then the corresponding standard channel will automatically be
+set to NULL.
+.PP
+If a non-NULL value for \fIchannel\fR is passed to \fBTcl_SetStdChannel\fR,
+then that same value should be passed to \fBTcl_RegisterChannel\fR, like so:
+.PP
+.CS
+Tcl_RegisterChannel(NULL, channel);
+.CE
+.PP
+This is a workaround for a misfeature in \fBTcl_SetStdChannel\fR that it
+fails to do some reference counting housekeeping. This misfeature cannot
+be corrected without contradicting the assumptions of some existing
+code that calls \fBTcl_SetStdChannel\fR.
+.PP
+If \fBTcl_GetStdChannel\fR is called before \fBTcl_SetStdChannel\fR, Tcl will
+construct a new channel to wrap the appropriate platform-specific standard
+file handle. If \fBTcl_SetStdChannel\fR is called before
+\fBTcl_GetStdChannel\fR, then the default channel will not be created.
+.PP
+If one of the standard channels is set to NULL, either by calling
+\fBTcl_SetStdChannel\fR with a NULL \fIchannel\fR argument, or by calling
+\fBTcl_Close\fR on the channel, then the next call to \fBTcl_CreateChannel\fR
+will automatically set the standard channel with the newly created channel. If
+more than one standard channel is NULL, then the standard channels will be
+assigned starting with standard input, followed by standard output, with
+standard error being last.
+.PP
+See \fBTcl_StandardChannels\fR for a general treatise about standard
+channels and the behavior of the Tcl library with regard to them.
+
+.SH "SEE ALSO"
+Tcl_Close(3), Tcl_CreateChannel(3), Tcl_Main(3), tclsh(1)
+
+.SH KEYWORDS
+standard channel, standard input, standard output, standard error
diff --git a/pkgs/msgcat/doc/GetTime.3 b/pkgs/msgcat/doc/GetTime.3
new file mode 100644
index 0000000..f4da364
--- /dev/null
+++ b/pkgs/msgcat/doc/GetTime.3
@@ -0,0 +1,109 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_GetTime 3 8.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_GetTime, Tcl_SetTimeProc, Tcl_QueryTimeProc \- get date and time
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\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_GetTimeProc *getProc in
+.AP Tcl_Time *timePtr out
+Points to memory in which to store the date and time information.
+.AP Tcl_GetTimeProc getProc in
+Pointer to handler function replacing \fBTcl_GetTime\fR's access to the OS.
+.AP Tcl_ScaleTimeProc scaleProc in
+Pointer to handler function for the conversion of time delays in the
+virtual domain to real-time.
+.AP ClientData clientData in
+Value passed through to the two handler functions.
+.AP Tcl_GetTimeProc *getProcPtr out
+Pointer to place the currently registered get handler function into.
+.AP Tcl_ScaleTimeProc *scaleProcPtr out
+Pointer to place the currently registered scale handler function into.
+.AP ClientData *clientDataPtr out
+Pointer to place the currently registered pass-through value into.
+.BE
+.SH DESCRIPTION
+.PP
+The \fBTcl_GetTime\fR function retrieves the current time as a
+\fITcl_Time\fR structure in memory the caller provides. This
+structure has the following definition:
+.PP
+.CS
+typedef struct Tcl_Time {
+ long \fIsec\fR;
+ long \fIusec\fR;
+} \fBTcl_Time\fR;
+.CE
+.PP
+On return, the \fIsec\fR member of the structure is filled in with the
+number of seconds that have elapsed since the \fIepoch:\fR the epoch
+is the point in time of 00:00 UTC, 1 January 1970. This number does
+\fInot\fR count leap seconds \- an interval of one day advances it by
+86400 seconds regardless of whether a leap second has been inserted.
+.PP
+The \fIusec\fR member of the structure is filled in with the number of
+microseconds that have elapsed since the start of the second
+designated by \fIsec\fR. The Tcl library makes every effort to keep
+this number as precise as possible, subject to the limitations of the
+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.)
+.SS "VIRTUALIZED TIME"
+.PP
+The \fBTcl_SetTimeProc\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_QueryTimeProc\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
+The signatures of the handler functions are as follows:
+.PP
+.CS
+typedef void \fBTcl_GetTimeProc\fR(
+ Tcl_Time *\fItimebuf\fR,
+ ClientData \fIclientData\fR);
+typedef void \fBTcl_ScaleTimeProc\fR(
+ Tcl_Time *\fItimebuf\fR,
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fItimebuf\fR fields contain the time to manipulate, and the
+\fIclientData\fR fields contain a pointer supplied at the time the handler
+functions were registered.
+.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 behavior of the Tcl core
+with regard to this situation, i.e. the existing behavior is retained.
+.SH "SEE ALSO"
+clock(n)
+.SH KEYWORDS
+date, time
diff --git a/pkgs/msgcat/doc/GetVersion.3 b/pkgs/msgcat/doc/GetVersion.3
new file mode 100755
index 0000000..47034d0
--- /dev/null
+++ b/pkgs/msgcat/doc/GetVersion.3
@@ -0,0 +1,48 @@
+'\"
+'\" Copyright (c) 1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_GetVersion 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_GetVersion \- get the version of the library at runtime
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.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
+Minor version number of the Tcl library.
+.AP int *patchLevel out
+The patch level of the Tcl library (or alpha or beta number).
+.AP Tcl_ReleaseType *type out
+The type of release, also indicates the type of patch level. Can be
+one of \fBTCL_ALPHA_RELEASE\fR, \fBTCL_BETA_RELEASE\fR, or
+\fBTCL_FINAL_RELEASE\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_GetVersion\fR should be used to query the version number
+of the Tcl library at runtime. This is useful when using a
+dynamically loaded Tcl library or when writing a stubs-aware
+extension. For instance, if you write an extension that is
+linked against the Tcl stubs library, it could be loaded into
+a program linked to an older version of Tcl than you expected.
+Use \fBTcl_GetVersion\fR to verify that fact, and possibly to
+change the behavior of your extension.
+.PP
+\fBTcl_GetVersion\fR accepts NULL for any of the arguments. For instance if
+you do not care about the \fIpatchLevel\fR of the library, pass
+a NULL for the \fIpatchLevel\fR argument.
+
+.SH KEYWORDS
+version, patchlevel, major, minor, alpha, beta, release
+
diff --git a/pkgs/msgcat/doc/Hash.3 b/pkgs/msgcat/doc/Hash.3
new file mode 100644
index 0000000..d8e3d2c
--- /dev/null
+++ b/pkgs/msgcat/doc/Hash.3
@@ -0,0 +1,334 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_Hash 3 "" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_InitHashTable, Tcl_InitCustomHashTable, Tcl_InitObjHashTable, Tcl_DeleteHashTable, Tcl_CreateHashEntry, Tcl_DeleteHashEntry, Tcl_FindHashEntry, Tcl_GetHashValue, Tcl_SetHashValue, Tcl_GetHashKey, Tcl_FirstHashEntry, Tcl_NextHashEntry, Tcl_HashStats \- procedures to manage hash tables
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_InitHashTable\fR(\fItablePtr, keyType\fR)
+.sp
+\fBTcl_InitCustomHashTable\fR(\fItablePtr, keyType, typePtr\fR)
+.sp
+\fBTcl_InitObjHashTable\fR(\fItablePtr\fR)
+.sp
+\fBTcl_DeleteHashTable\fR(\fItablePtr\fR)
+.sp
+Tcl_HashEntry *
+\fBTcl_CreateHashEntry\fR(\fItablePtr, key, newPtr\fR)
+.sp
+\fBTcl_DeleteHashEntry\fR(\fIentryPtr\fR)
+.sp
+Tcl_HashEntry *
+\fBTcl_FindHashEntry\fR(\fItablePtr, key\fR)
+.sp
+ClientData
+\fBTcl_GetHashValue\fR(\fIentryPtr\fR)
+.sp
+\fBTcl_SetHashValue\fR(\fIentryPtr, value\fR)
+.sp
+void *
+\fBTcl_GetHashKey\fR(\fItablePtr, entryPtr\fR)
+.sp
+Tcl_HashEntry *
+\fBTcl_FirstHashEntry\fR(\fItablePtr, searchPtr\fR)
+.sp
+Tcl_HashEntry *
+\fBTcl_NextHashEntry\fR(\fIsearchPtr\fR)
+.sp
+char *
+\fBTcl_HashStats\fR(\fItablePtr\fR)
+.SH ARGUMENTS
+.AS "const 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
+\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 behavior of the hash table.
+.AP "const void" *key in
+Key to use for probe into table. Exact form depends on
+\fIkeyType\fR used to create table.
+.AP int *newPtr out
+The word at \fI*newPtr\fR is set to 1 if a new entry was created
+and 0 if there was already an entry for \fIkey\fR.
+.AP Tcl_HashEntry *entryPtr in
+Pointer to hash table entry.
+.AP ClientData value in
+New value to assign to hash table entry. Need not have type
+ClientData, but must fit in same space as ClientData.
+.AP Tcl_HashSearch *searchPtr in
+Pointer to record to use to keep track of progress in enumerating
+all the entries in a hash table.
+.BE
+.SH DESCRIPTION
+.PP
+A hash table consists of zero or more entries, each consisting of a
+key and a value. Given the key for an entry, the hashing routines can
+very quickly locate the entry, and hence its value. There may be at
+most one entry in a hash table with a particular key, but many entries
+may have the same value. Keys can take one of four forms: strings,
+one-word values, integer arrays, or custom keys defined by a
+Tcl_HashKeyType structure (See section \fBTHE TCL_HASHKEYTYPE 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
+.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.
+.PP
+Hash tables grow gracefully as the number of entries increases, so
+that there are always less than three entries per hash bucket, on
+average. This allows for fast lookups regardless of the number of
+entries in a table.
+.PP
+The core provides three functions for the initialization of hash
+tables, Tcl_InitHashTable, Tcl_InitObjHashTable and
+Tcl_InitCustomHashTable.
+.PP
+\fBTcl_InitHashTable\fR initializes a structure that describes a new
+hash table. The space for the structure is provided by the caller,
+not by the hash module. The value of \fIkeyType\fR indicates what
+kinds of keys will be used for all entries in the table. All of the
+key types described later are allowed, with the exception of
+\fBTCL_CUSTOM_TYPE_KEYS\fR and \fBTCL_CUSTOM_PTR_KEYS\fR.
+.PP
+\fBTcl_InitObjHashTable\fR is a wrapper around
+\fBTcl_InitCustomHashTable\fR and initializes a hash table whose keys
+are Tcl_Obj *.
+.PP
+\fBTcl_InitCustomHashTable\fR initializes a structure that describes a
+new hash table. The space for the structure is provided by the
+caller, not by the hash module. The value of \fIkeyType\fR indicates
+what kinds of keys will be used for all entries in the table.
+\fIKeyType\fR must have one of the following values:
+.IP \fBTCL_STRING_KEYS\fR 25
+Keys are null-terminated strings.
+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
+.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
+and comparison is determined by \fItypePtr\fR. The Tcl_HashKeyType
+structure is described in the section
+\fBTHE TCL_HASHKEYTYPE STRUCTURE\fR below.
+.IP \fBTCL_CUSTOM_PTR_KEYS\fR 25
+Keys are pointers to an arbitrary type, and are stored in the entry. Hashing
+and comparison is determined by \fItypePtr\fR. The Tcl_HashKeyType
+structure is described in the section
+\fBTHE TCL_HASHKEYTYPE STRUCTURE\fR below.
+.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
+.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.
+Array keys are passed into hashing functions using the address
+of the first int in the array.
+.PP
+\fBTcl_DeleteHashTable\fR deletes all of the entries in a hash
+table and frees up the memory associated with the table's
+bucket array and entries.
+It does not free the actual table structure (pointed to
+by \fItablePtr\fR), since that memory is assumed to be managed
+by the client.
+\fBTcl_DeleteHashTable\fR also does not free or otherwise
+manipulate the values of the hash table entries.
+If the entry values point to dynamically-allocated memory, then
+it is the client's responsibility to free these structures
+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
+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
+value and the value of the new entry will be set to zero.
+The return value from \fBTcl_CreateHashEntry\fR is a pointer to
+the entry, which may be used to retrieve and modify the entry's
+value or to delete the entry from the table.
+.PP
+\fBTcl_DeleteHashEntry\fR will remove an existing entry from a
+table.
+The memory associated with the entry itself will be freed, but
+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 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
+.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
+.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
+.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
+.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
+empty).
+Each subsequent call to \fBTcl_NextHashEntry\fR returns the
+next entry in the table or
+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 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
+entries it contains, the number of buckets in its hash array,
+and the utilization of the buckets.
+It is the caller's responsibility to free the result string
+by passing it to \fBckfree\fR.
+.PP
+The header file \fBtcl.h\fR defines the actual data structures
+used to implement hash tables.
+This is necessary so that clients can allocate Tcl_HashTable
+structures and so that macros can be used to read and write
+the values of entries.
+However, users of the hashing routines should never refer directly
+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 \fBTcl_HashKeyType\fR structure to describe the type, and
+calling \fBTcl_InitCustomHashTable\fR. The \fBTcl_HashKeyType\fR structure is
+defined as follows:
+.PP
+.CS
+typedef struct Tcl_HashKeyType {
+ int \fIversion\fR;
+ int \fIflags\fR;
+ Tcl_HashKeyProc *\fIhashKeyProc\fR;
+ Tcl_CompareHashKeysProc *\fIcompareKeysProc\fR;
+ Tcl_AllocHashEntryProc *\fIallocEntryProc\fR;
+ Tcl_FreeHashEntryProc *\fIfreeEntryProc\fR;
+} \fBTcl_HashKeyType\fR;
+.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.
+.PP
+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 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
+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.
+.PP
+The \fIhashKeyProc\fR member contains the address of a function called to
+calculate a hash value for the key.
+.PP
+.CS
+typedef unsigned int \fBTcl_HashKeyProc\fR(
+ Tcl_HashTable *\fItablePtr\fR,
+ void *\fIkeyPtr\fR);
+.CE
+.PP
+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.
+.PP
+.CS
+typedef int \fBTcl_CompareHashKeysProc\fR(
+ void *\fIkeyPtr\fR,
+ Tcl_HashEntry *\fIhPtr\fR);
+.CE
+.PP
+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 initialize the key and clientData.
+.PP
+.CS
+typedef Tcl_HashEntry *\fBTcl_AllocHashEntryProc\fR(
+ Tcl_HashTable *\fItablePtr\fR,
+ void *\fIkeyPtr\fR);
+.CE
+.PP
+If this is NULL then Tcl_Alloc is used to allocate enough space for a
+Tcl_HashEntry, the key pointer is assigned to key.oneWordValue and the
+clientData is set to NULL. String keys and array keys use this function to
+allocate enough space for the entry and the key in one block, rather than
+doing it in two blocks. This saves space for a pointer to the key from the
+entry and another memory allocation. Tcl_Obj* keys use this function to
+allocate enough space for an entry and increment the reference count on the
+object.
+.PP
+The \fIfreeEntryProc\fR member contains the address of a function called to
+free space for an entry.
+.PP
+.CS
+typedef void \fBTcl_FreeHashEntryProc\fR(
+ Tcl_HashEntry *\fIhPtr\fR);
+.CE
+.PP
+If this is NULL then Tcl_Free is used to free the space for the entry.
+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/pkgs/msgcat/doc/Init.3 b/pkgs/msgcat/doc/Init.3
new file mode 100644
index 0000000..f421479
--- /dev/null
+++ b/pkgs/msgcat/doc/Init.3
@@ -0,0 +1,34 @@
+'\"
+'\" Copyright (c) 1998-2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.so man.macros
+.TH Tcl_Init 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Init \- find and source initialization script
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+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\fRs the
+\fBinit.tcl\fR script, which should exist somewhere on the Tcl library
+path.
+.PP
+\fBTcl_Init\fR is typically called from \fBTcl_AppInit\fR procedures.
+
+.SH "SEE ALSO"
+Tcl_AppInit, Tcl_Main
+
+.SH KEYWORDS
+application, initialization, interpreter
diff --git a/pkgs/msgcat/doc/InitStubs.3 b/pkgs/msgcat/doc/InitStubs.3
new file mode 100644
index 0000000..5f56278
--- /dev/null
+++ b/pkgs/msgcat/doc/InitStubs.3
@@ -0,0 +1,89 @@
+'\"
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_InitStubs 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_InitStubs \- initialize the Tcl stubs mechanism
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+const char *
+\fBTcl_InitStubs\fR(\fIinterp, version, exact\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Tcl interpreter handle.
+.AP "const char" *version in
+A version string consisting of one or more decimal numbers
+separated by dots.
+.AP int exact in
+Non-zero means that only the particular version specified by
+\fIversion\fR is acceptable.
+Zero means that versions newer than \fIversion\fR are also
+acceptable as long as they have the same major version number
+as \fIversion\fR.
+.BE
+.SH INTRODUCTION
+.PP
+The Tcl stubs mechanism defines a way to dynamically bind
+extensions to a particular Tcl implementation at run time.
+This provides two significant benefits to Tcl users:
+.IP 1) 5
+Extensions that use the stubs mechanism can be loaded into
+multiple versions of Tcl without being recompiled or
+relinked.
+.IP 2) 5
+Extensions that use the stubs mechanism can be dynamically
+loaded into statically-linked Tcl applications.
+.PP
+The stubs mechanism accomplishes this by exporting function tables
+that define an interface to the Tcl API. The extension then accesses
+the Tcl API through offsets into the function table, so there are no
+direct references to any of the Tcl library's symbols. This
+redirection is transparent to the extension, so an extension writer
+can continue to use all public Tcl functions as documented.
+.PP
+The stubs mechanism requires no changes to applications incorporating
+Tcl interpreters. Only developers creating C-based Tcl extensions
+need to take steps to use the stubs mechanism with their extensions.
+.PP
+Enabling the stubs mechanism for an extension requires the following
+steps:
+.IP 1) 5
+Call \fBTcl_InitStubs\fR in the extension before calling any other
+Tcl functions.
+.IP 2) 5
+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. For example, to use the Tcl 8.1 ABI on Unix platforms,
+the library name is \fIlibtclstub8.1.a\fR; on Windows platforms, the
+library name is \fItclstub81.lib\fR.
+.PP
+If the extension also requires the Tk API, it must also call
+\fBTk_InitStubs\fR to initialize the Tk stubs interface and link
+with the Tk stubs libraries. See the \fBTk_InitStubs\fR page for
+more information.
+.SH DESCRIPTION
+\fBTcl_InitStubs\fR attempts to initialize the stub table pointers
+and ensure that the correct version of Tcl is loaded. In addition
+to an interpreter handle, it accepts as arguments a version number
+and a Boolean flag indicating whether the extension requires
+an exact version match or not. If \fIexact\fR is 0, then the
+extension is indicating that newer versions of Tcl are acceptable
+as long as they have the same major version number as \fIversion\fR;
+non-zero means that only the specified \fIversion\fR is acceptable.
+\fBTcl_InitStubs\fR returns a string containing the actual version
+of Tcl satisfying the request, or NULL if the Tcl version is not
+acceptable, does not support stubs, or any other error condition occurred.
+.SH "SEE ALSO"
+Tk_InitStubs
+.SH KEYWORDS
+stubs
diff --git a/pkgs/msgcat/doc/IntObj.3 b/pkgs/msgcat/doc/IntObj.3
new file mode 100644
index 0000000..cde96f8
--- /dev/null
+++ b/pkgs/msgcat/doc/IntObj.3
@@ -0,0 +1,151 @@
+'\"
+'\" Copyright (c) 1996-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 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, Tcl_NewBignumObj, Tcl_SetBignumObj, Tcl_GetBignumFromObj, Tcl_TakeBignumFromObj \- manipulate Tcl objects as integer values
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewIntObj\fR(\fIintValue\fR)
+.sp
+Tcl_Obj *
+\fBTcl_NewLongObj\fR(\fIlongValue\fR)
+.sp
+Tcl_Obj *
+\fBTcl_NewWideIntObj\fR(\fIwideValue\fR)
+.sp
+\fBTcl_SetIntObj\fR(\fIobjPtr, intValue\fR)
+.sp
+\fBTcl_SetLongObj\fR(\fIobjPtr, longValue\fR)
+.sp
+\fBTcl_SetWideIntObj\fR(\fIobjPtr, wideValue\fR)
+.sp
+int
+\fBTcl_GetIntFromObj\fR(\fIinterp, objPtr, intPtr\fR)
+.sp
+int
+\fBTcl_GetLongFromObj\fR(\fIinterp, objPtr, longPtr\fR)
+.sp
+int
+\fBTcl_GetWideIntFromObj\fR(\fIinterp, objPtr, widePtr\fR)
+.sp
+.sp
+\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)
+.SH ARGUMENTS
+.AS Tcl_WideInt doubleValue in/out
+.AP int intValue in
+Integer value used to initialize or set a Tcl object.
+.AP long longValue in
+Long integer value used to initialize or set a Tcl object.
+.AP Tcl_WideInt wideValue in
+Wide integer value used to initialize or set a Tcl object.
+.AP Tcl_Obj *objPtr in/out
+For \fBTcl_SetIntObj\fR, \fBTcl_SetLongObj\fR, \fBTcl_SetWideIntObj\fR,
+and \fBTcl_SetBignumObj\fR, this points to the object in which to store an
+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
+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 retrieved from \fIobjPtr\fR.
+.AP long *longPtr out
+Points to place to store the long integer value retrieved from \fIobjPtr\fR.
+.AP Tcl_WideInt *widePtr out
+Points to place to store the wide integer value retrieved from \fIobjPtr\fR.
+.AP mp_int *bigValue in/out
+Points to a multi-precision integer structure declared by the LibTomMath
+library.
+.AP double doubleValue in
+Double value from which the integer part is determined and
+used to initialize a multi-precision integer value.
+.BE
+.SH DESCRIPTION
+.PP
+These procedures are used to create, modify, and read Tcl objects
+that hold integral values.
+.PP
+The different routines exist to accommodate different integral types in C
+with which values might be exchanged. The C integral types for which Tcl
+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.
+.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/pkgs/msgcat/doc/Interp.3 b/pkgs/msgcat/doc/Interp.3
new file mode 100644
index 0000000..d908057
--- /dev/null
+++ b/pkgs/msgcat/doc/Interp.3
@@ -0,0 +1,134 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_Interp 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Interp \- client-visible fields of interpreter structures
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+typedef struct {
+ char *\fIresult\fR;
+ Tcl_FreeProc *\fIfreeProc\fR;
+ int \fIerrorLine\fR;
+} \fBTcl_Interp\fR;
+
+typedef void \fBTcl_FreeProc\fR(
+ char *\fIblockPtr\fR);
+.BE
+.SH DESCRIPTION
+.PP
+The \fBTcl_CreateInterp\fR procedure returns a pointer to a Tcl_Interp
+structure. Callers of \fBTcl_CreateInterp\fR should use this pointer
+as an opaque token, suitable for nothing other than passing back to
+other routines in the Tcl interface. Accessing fields directly through
+the pointer as described below is no longer supported. The supported
+public routines \fBTcl_SetResult\fR, \fBTcl_GetResult\fR,
+\fBTcl_SetErrorLine\fR, \fBTcl_GetErrorLine\fR must be used instead.
+.PP
+For legacy programs and extensions no longer being maintained, compiles
+against the Tcl 8.6 header files are only possible with the compiler
+directives
+.CS
+#define USE_INTERP_RESULT
+.CE
+and/or
+.CS
+#define USE_INTERP_ERRORLINE
+.CE
+depending on which fields of the \fBTcl_Interp\fR struct are accessed.
+These directives may be embedded in code or supplied via compiler options.
+.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 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
+will hide all the details of managing the fields.
+The description below is for those procedures that manipulate the
+fields directly.
+.PP
+Whenever a command procedure returns, it must ensure
+that the \fIresult\fR field of its interpreter points to the string
+being returned by the command.
+The \fIresult\fR field must always point to a valid string.
+If a command wishes to return no result then \fIinterp->result\fR
+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.
+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)
+and store a pointer to it in \fIinterp->result\fR.
+In this case, the command procedure must also set \fIinterp->freeProc\fR
+to the address of a procedure that can free the value, or \fBTCL_DYNAMIC\fR
+if the storage was allocated directly by Tcl or by a call to
+\fBTcl_Alloc\fR.
+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.
+If a client procedure overwrites \fIinterp->result\fR when
+\fIinterp->freeProc\fR is non-zero, then it is responsible for calling
+\fIfreeProc\fR to free the old \fIinterp->result\fR (the \fBTcl_FreeResult\fR
+macro should be used for this purpose).
+.PP
+\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.
+In most applications \fBTCL_DYNAMIC\fR is the only non-zero value ever
+used for \fIfreeProc\fR.
+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.
+.PP
+As part of processing each command, \fBTcl_Eval\fR initializes
+\fIinterp->result\fR
+and \fIinterp->freeProc\fR just before calling the command procedure for
+the command. The \fIfreeProc\fR field will be initialized to zero,
+and \fIinterp->result\fR will point to an empty string. Commands that
+do not return any value can simply leave the fields alone.
+Furthermore, the empty string pointed to by \fIresult\fR is actually
+part of an array of \fBTCL_RESULT_SIZE\fR characters (approximately 200).
+If a command wishes to return a short string, it can simply copy
+it to the area pointed to by \fIinterp->result\fR. Or, it can use
+the sprintf procedure to generate a short result string at the location
+pointed to by \fIinterp->result\fR.
+.PP
+It is a general convention in Tcl-based applications that the result
+of an interpreter is normally in the initialized state described
+in the previous paragraph.
+Procedures that manipulate an interpreter's result (e.g. by
+returning an error) will generally assume that the result
+has been initialized when the procedure is called.
+If such a procedure is to be called after the result has been
+changed, then \fBTcl_ResetResult\fR should be called first to
+reset the result to its initialized state. The direct use of
+\fIinterp->result\fR is strongly deprecated (see \fBTcl_SetResult\fR).
+.PP
+The \fIerrorLine\fR
+field is valid only after \fBTcl_Eval\fR returns
+a \fBTCL_ERROR\fR return code. In this situation the \fIerrorLine\fR
+field identifies the line number of the command being executed when
+the error occurred. The line numbers are relative to the command
+being executed: 1 means the first line of the command passed to
+\fBTcl_Eval\fR, 2 means the second line, and so on.
+The \fIerrorLine\fR field is typically used in conjunction with
+\fBTcl_AddErrorInfo\fR to report information about where an error
+occurred.
+\fIErrorLine\fR should not normally be modified except by \fBTcl_Eval\fR.
+
+.SH KEYWORDS
+free, initialized, interpreter, malloc, result
diff --git a/pkgs/msgcat/doc/Limit.3 b/pkgs/msgcat/doc/Limit.3
new file mode 100644
index 0000000..2941ee8
--- /dev/null
+++ b/pkgs/msgcat/doc/Limit.3
@@ -0,0 +1,192 @@
+'\"
+'\" 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 \fBTcl_LimitHandlerProc\fR(
+ 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 \fBTcl_LimitHandlerDeleteProc\fR(
+ 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/pkgs/msgcat/doc/LinkVar.3 b/pkgs/msgcat/doc/LinkVar.3
new file mode 100644
index 0000000..dc71a45
--- /dev/null
+++ b/pkgs/msgcat/doc/LinkVar.3
@@ -0,0 +1,207 @@
+'\"
+'\" 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 Tcl_LinkVar 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_LinkVar, Tcl_UnlinkVar, Tcl_UpdateLinkedVar \- link Tcl variable to C variable
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_LinkVar\fR(\fIinterp, varName, addr, type\fR)
+.sp
+\fBTcl_UnlinkVar\fR(\fIinterp, varName\fR)
+.sp
+\fBTcl_UpdateLinkedVar\fR(\fIinterp, varName\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp writable
+.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 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 \fBTCL_LINK_INT\fR,
+\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, \fBTCL_LINK_WIDE_INT\fR,
+\fBTCL_LINK_WIDE_UINT\fR, \fBTCL_LINK_FLOAT\fR,
+\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
+.PP
+\fBTcl_LinkVar\fR uses variable traces to keep the Tcl variable
+named by \fIvarName\fR in sync with the C variable at the address
+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 \fBTCL_OK\fR; if an error occurs
+while setting up the link (e.g. because \fIvarName\fR is the
+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
+\fBTCL_LINK_READ_ONLY\fR:
+.TP
+\fBTCL_LINK_INT\fR
+The C variable is of type \fBint\fR.
+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.
+.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.
+.TP
+\fBTCL_LINK_DOUBLE\fR
+The C variable is of type \fBdouble\fR.
+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.
+.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.
+.TP
+\fBTCL_LINK_WIDE_INT\fR
+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.
+.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.
+.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
+.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
+form acceptable to \fBTcl_GetBooleanFromObj\fR; attempts to write
+non-boolean values into \fIvarName\fR will be rejected with
+Tcl errors.
+.TP
+\fBTCL_LINK_STRING\fR
+The C variable is of type \fBchar *\fR.
+If its value is not NULL then it must be a pointer to a string
+allocated with \fBTcl_Alloc\fR or \fBckalloc\fR.
+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
+.QW NULL .
+.PP
+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.
+.PP
+\fBTcl_UnlinkVar\fR removes the link previously set up for the
+variable given by \fIvarName\fR. If there does not exist a link
+for \fIvarName\fR then the procedure has no effect.
+.PP
+\fBTcl_UpdateLinkedVar\fR may be invoked after the C variable has
+changed to force the Tcl variable to be updated immediately.
+In many cases this procedure is not needed, since any attempt to
+read the Tcl variable will return the latest value of the C variable.
+However, if a trace has been set on the Tcl variable (such as a
+Tk widget that wishes to display the value of the variable), the
+trace will not trigger when the C variable has changed.
+\fBTcl_UpdateLinkedVar\fR ensures that any traces on the Tcl
+variable are invoked.
+.PP
+Note that, as with any call to a Tcl interpreter, \fBTcl_UpdateLinkedVar\fR
+must be called from the same thread that created the interpreter. The safest
+mechanism is to ensure that the C variable is only ever updated from the same
+thread that created the interpreter (possibly in response to an event posted
+with \fBTcl_ThreadQueueEvent\fR), but when it is necessary to update the
+variable in a separate thread, it is advised that \fBTcl_AsyncMark\fR be used
+to indicate to the thread hosting the interpreter that it is ready to run
+\fBTcl_UpdateLinkedVar\fR.
+.SH "SEE ALSO"
+Tcl_TraceVar(3)
+.SH KEYWORDS
+boolean, integer, link, read-only, real, string, trace, variable
diff --git a/pkgs/msgcat/doc/ListObj.3 b/pkgs/msgcat/doc/ListObj.3
new file mode 100644
index 0000000..b93e52b
--- /dev/null
+++ b/pkgs/msgcat/doc/ListObj.3
@@ -0,0 +1,250 @@
+'\"
+'\" Copyright (c) 1996-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 Tcl_ListObj 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_ListObjAppendList, Tcl_ListObjAppendElement, Tcl_NewListObj, Tcl_SetListObj, Tcl_ListObjGetElements, Tcl_ListObjLength, Tcl_ListObjIndex, Tcl_ListObjReplace \- manipulate Tcl objects as lists
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_ListObjAppendList\fR(\fIinterp, listPtr, elemListPtr\fR)
+.sp
+int
+\fBTcl_ListObjAppendElement\fR(\fIinterp, listPtr, objPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_NewListObj\fR(\fIobjc, objv\fR)
+.sp
+\fBTcl_SetListObj\fR(\fIobjPtr, objc, objv\fR)
+.sp
+int
+\fBTcl_ListObjGetElements\fR(\fIinterp, listPtr, objcPtr, objvPtr\fR)
+.sp
+int
+\fBTcl_ListObjLength\fR(\fIinterp, listPtr, intPtr\fR)
+.sp
+int
+\fBTcl_ListObjIndex\fR(\fIinterp, listPtr, index, objPtrPtr\fR)
+.sp
+int
+\fBTcl_ListObjReplace\fR(\fIinterp, listPtr, first, count, objc, objv\fR)
+.SH ARGUMENTS
+.AS "Tcl_Obj *const" *elemListPtr in/out
+.AP Tcl_Interp *interp in
+If an error occurs while converting an object to be a list object,
+an error message is left in the interpreter's result object
+unless \fIinterp\fR is NULL.
+.AP Tcl_Obj *listPtr in/out
+Points to the list object to be manipulated.
+If \fIlistPtr\fR does not already point to a list object,
+an attempt will be made to convert it to one.
+.AP Tcl_Obj *elemListPtr in/out
+For \fBTcl_ListObjAppendList\fR, this points to a list object
+containing elements to be appended onto \fIlistPtr\fR.
+Each element of *\fIelemListPtr\fR will
+become a new element of \fIlistPtr\fR.
+If *\fIelemListPtr\fR is not NULL and
+does not already point to a list object,
+an attempt will be made to convert it to one.
+.AP Tcl_Obj *objPtr in
+For \fBTcl_ListObjAppendElement\fR,
+points to the Tcl object that will be appended to \fIlistPtr\fR.
+For \fBTcl_SetListObj\fR,
+this points to the Tcl object that will be converted to a list object
+containing the \fIobjc\fR elements of the array referenced by \fIobjv\fR.
+.AP int *objcPtr in
+Points to location where \fBTcl_ListObjGetElements\fR
+stores the number of element objects in \fIlistPtr\fR.
+.AP Tcl_Obj ***objvPtr out
+A location where \fBTcl_ListObjGetElements\fR stores a pointer to an array
+of pointers to the element objects of \fIlistPtr\fR.
+.AP int objc in
+The number of Tcl objects that \fBTcl_NewListObj\fR
+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.
+.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.
+.AP int *intPtr out
+Points to location where \fBTcl_ListObjLength\fR
+stores the length of the list.
+.AP int index in
+Index of the list element that \fBTcl_ListObjIndex\fR
+is to return.
+The first element has index 0.
+.AP Tcl_Obj **objPtrPtr out
+Points to place where \fBTcl_ListObjIndex\fR is to store
+a pointer to the resulting list element object.
+.AP int first in
+Index of the starting list element that \fBTcl_ListObjReplace\fR
+is to replace.
+The list's first element has index 0.
+.AP int count in
+The number of elements that \fBTcl_ListObjReplace\fR
+is to replace.
+.BE
+
+.SH DESCRIPTION
+.PP
+Tcl list objects have an internal representation that supports
+the efficient indexing and appending.
+The procedures described in this man page are used to
+create, modify, index, and append to Tcl list objects from C code.
+.PP
+\fBTcl_ListObjAppendList\fR and \fBTcl_ListObjAppendElement\fR
+both add one or more objects
+to the end of the list object referenced by \fIlistPtr\fR.
+\fBTcl_ListObjAppendList\fR appends each element of the list object
+referenced by \fIelemListPtr\fR while
+\fBTcl_ListObjAppendElement\fR appends the single object
+referenced by \fIobjPtr\fR.
+Both procedures will convert the object referenced by \fIlistPtr\fR
+to a list object if necessary.
+If an error occurs during conversion,
+both procedures return \fBTCL_ERROR\fR and leave an error message
+in the interpreter's result object if \fIinterp\fR is not NULL.
+Similarly, if \fIelemListPtr\fR does not already refer to a list object,
+\fBTcl_ListObjAppendList\fR will attempt to convert it to one
+and if an error occurs during conversion,
+will return \fBTCL_ERROR\fR
+and leave an error message in the interpreter's result object
+if interp is not NULL.
+Both procedures invalidate any old string representation of \fIlistPtr\fR
+and, if it was converted to a list object,
+free any old internal representation.
+Similarly, \fBTcl_ListObjAppendList\fR frees any old internal representation
+of \fIelemListPtr\fR if it converts it to a list object.
+After appending each element in \fIelemListPtr\fR,
+\fBTcl_ListObjAppendList\fR increments the element's reference count
+since \fIlistPtr\fR now also refers to it.
+For the same reason, \fBTcl_ListObjAppendElement\fR
+increments \fIobjPtr\fR's reference count.
+If no error occurs,
+the two procedures return \fBTCL_OK\fR after appending the objects.
+.PP
+\fBTcl_NewListObj\fR and \fBTcl_SetListObj\fR
+create a new object or modify an existing object to hold
+the \fIobjc\fR elements of the array referenced by \fIobjv\fR
+where each element is a pointer to a Tcl object.
+If \fIobjc\fR is less than or equal to zero,
+they return an empty object.
+The new object's string representation is left invalid.
+The two procedures increment the reference counts
+of the elements in \fIobjc\fR since the list object now refers to them.
+The new list object returned by \fBTcl_NewListObj\fR
+has reference count zero.
+.PP
+\fBTcl_ListObjGetElements\fR returns a count and a pointer to an array of
+the elements in a list object. It returns the count by storing it in the
+address \fIobjcPtr\fR. Similarly, it returns the array pointer by storing
+it in the address \fIobjvPtr\fR.
+The memory pointed to is managed by Tcl and should not be freed or written
+to by the caller. If the list is empty, 0 is stored at \fIobjcPtr\fR
+and NULL at \fIobjvPtr\fR.
+If \fIlistPtr\fR is not already a list object, \fBTcl_ListObjGetElements\fR
+will attempt to convert it to one; if the conversion fails, it returns
+\fBTCL_ERROR\fR and leaves an error message in the interpreter's result
+object if \fIinterp\fR is not NULL.
+Otherwise it returns \fBTCL_OK\fR after storing the count and array pointer.
+.PP
+\fBTcl_ListObjLength\fR returns the number of elements in the list object
+referenced by \fIlistPtr\fR.
+It returns this count by storing an integer in the address \fIintPtr\fR.
+If the object is not already a list object,
+\fBTcl_ListObjLength\fR will attempt to convert it to one;
+if the conversion fails, it returns \fBTCL_ERROR\fR
+and leaves an error message in the interpreter's result object
+if \fIinterp\fR is not NULL.
+Otherwise it returns \fBTCL_OK\fR after storing the list's length.
+.PP
+The procedure \fBTcl_ListObjIndex\fR returns a pointer to the object
+at element \fIindex\fR in the list referenced by \fIlistPtr\fR.
+It returns this object by storing a pointer to it
+in the address \fIobjPtrPtr\fR.
+If \fIlistPtr\fR does not already refer to a list object,
+\fBTcl_ListObjIndex\fR will attempt to convert it to one;
+if the conversion fails, it returns \fBTCL_ERROR\fR
+and leaves an error message in the interpreter's result object
+if \fIinterp\fR is not NULL.
+If the index is out of range,
+that is, \fIindex\fR is negative or
+greater than or equal to the number of elements in the list,
+\fBTcl_ListObjIndex\fR stores a NULL in \fIobjPtrPtr\fR
+and returns \fBTCL_OK\fR.
+Otherwise it returns \fBTCL_OK\fR after storing the element's
+object pointer.
+The reference count for the list element is not incremented;
+the caller must do that if it needs to retain a pointer to the element.
+.PP
+\fBTcl_ListObjReplace\fR replaces zero or more elements
+of the list referenced by \fIlistPtr\fR
+with the \fIobjc\fR objects in the array referenced by \fIobjv\fR.
+If \fIlistPtr\fR does not point to a list object,
+\fBTcl_ListObjReplace\fR will attempt to convert it to one;
+if the conversion fails, it returns \fBTCL_ERROR\fR
+and leaves an error message in the interpreter's result object
+if \fIinterp\fR is not NULL.
+Otherwise, it returns \fBTCL_OK\fR after replacing the objects.
+If \fIobjv\fR is NULL, no new elements are added.
+If the argument \fIfirst\fR is zero or negative,
+it refers to the first element.
+If \fIfirst\fR is greater than or equal to the
+number of elements in the list, then no elements are deleted;
+the new elements are appended to the list.
+\fIcount\fR gives the number of elements to replace.
+If \fIcount\fR is zero or negative then no elements are deleted;
+the new elements are simply inserted before the one
+designated by \fIfirst\fR.
+\fBTcl_ListObjReplace\fR invalidates \fIlistPtr\fR's
+old string representation.
+The reference counts of any elements inserted from \fIobjv\fR
+are incremented since the resulting list now refers to them.
+Similarly, the reference counts for any replaced objects are decremented.
+.PP
+Because \fBTcl_ListObjReplace\fR combines
+both element insertion and deletion,
+it can be used to implement a number of list operations.
+For example, the following code inserts the \fIobjc\fR objects
+referenced by the array of object pointers \fIobjv\fR
+just before the element \fIindex\fR of the list referenced by \fIlistPtr\fR:
+.PP
+.CS
+result = \fBTcl_ListObjReplace\fR(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 = \fBTcl_ListObjLength\fR(interp, listPtr, &length);
+if (result == TCL_OK) {
+ result = \fBTcl_ListObjReplace\fR(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 = \fBTcl_ListObjReplace\fR(interp, listPtr, first, count,
+ 0, NULL);
+.CE
+.SH "SEE ALSO"
+Tcl_NewObj(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3), Tcl_GetObjResult(3)
+.SH KEYWORDS
+append, index, insert, internal representation, length, list, list object, list type, object, object type, replace, string representation
diff --git a/pkgs/msgcat/doc/Load.3 b/pkgs/msgcat/doc/Load.3
new file mode 100644
index 0000000..c088f32
--- /dev/null
+++ b/pkgs/msgcat/doc/Load.3
@@ -0,0 +1,69 @@
+'\"
+'\" Copyright (c) 2009-2010 Kevin B. Kenny
+'\" Copyright (c) 2010 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 Load 3 8.6 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_LoadFile, Tcl_FindSymbol \- platform-independent dynamic library loading
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_LoadFile\fR(\fIinterp, pathPtr, symbols, flags, procPtrs, loadHandlePtr\fR)
+.sp
+void *
+\fBTcl_FindSymbol\fR(\fIinterp, loadHandle, symbol\fR)
+.SH ARGUMENTS
+.AS Tcl_LoadHandle loadHandle in
+.AP Tcl_Interp *interp in
+Interpreter to use for reporting error messages.
+.AP Tcl_Obj *pathPtr in
+The name of the file to load. If it is a single name, the library search path
+of the current environment will be used to resolve it.
+.AP "const char *const" symbols[] in
+Array of names of symbols to be resolved during the load of the library, or
+NULL if no symbols are to be resolved. If an array is given, the last entry in
+the array must be NULL.
+.AP int flags in
+Reserved for future expansion. Must be 0.
+.AP void *procPtrs out
+Points to an array that will hold the addresses of the functions described in
+the \fIsymbols\fR argument. Should be NULL if no symbols are to be resolved.
+.AP Tcl_LoadHandle *loadHandlePtr out
+Points to a variable that will hold the handle to the abstract token
+describing the library that has been loaded.
+.AP Tcl_LoadHandle loadHandle in
+Abstract token describing the library to look up a symbol in.
+.AP "const char" *symbol in
+The name of the symbol to look up.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_LoadFile\fR loads a file from the filesystem (including potentially any
+virtual filesystem that has been installed) and provides a handle to it that
+may be used in further operations. The \fIsymbols\fR array, if non-NULL,
+supplies a set of names of symbols (typically functions) that must be resolved
+from the library and which will be stored in the array indicated by
+\fIprocPtrs\fR. If any of the symbols is not resolved, the loading of the file
+will fail with an error message left in the interpreter (if that is non-NULL).
+The result of \fBTcl_LoadFile\fR is a standard Tcl error code. The library may
+be unloaded with \fBTcl_FSUnloadFile\fR.
+.PP
+\fBTcl_FindSymbol\fR locates a symbol in a loaded library and returns it. If
+the symbol cannot be found, it returns NULL and sets an error message in the
+given \fIinterp\fR (if that is non-NULL). Note that it is unsafe to use this
+operation on a handle that has been passed to \fBTcl_FSUnloadFile\fR.
+.SH "SEE ALSO"
+Tcl_FSLoadFile(3), Tcl_FSUnloadFile(3), load(n), unload(n)
+.SH KEYWORDS
+binary code, loading, shared library
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/pkgs/msgcat/doc/Method.3 b/pkgs/msgcat/doc/Method.3
new file mode 100644
index 0000000..43b3609
--- /dev/null
+++ b/pkgs/msgcat/doc/Method.3
@@ -0,0 +1,248 @@
+'\"
+'\" Copyright (c) 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 Tcl_Method 3 0.1 TclOO "TclOO Library Functions"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_ClassSetConstructor, Tcl_ClassSetDestructor, Tcl_MethodDeclarerClass, Tcl_MethodDeclarerObject, Tcl_MethodIsPublic, Tcl_MethodIsType, Tcl_MethodName, Tcl_NewInstanceMethod, Tcl_NewMethod, Tcl_ObjectContextInvokeNext, Tcl_ObjectContextIsFiltering, Tcl_ObjectContextMethod, Tcl_ObjectContextObject, Tcl_ObjectContextSkippedArgs \- manipulate methods and method-call contexts
+.SH SYNOPSIS
+.nf
+\fB#include <tclOO.h>\fR
+.sp
+Tcl_Method
+\fBTcl_NewMethod\fR(\fIinterp, class, nameObj, isPublic,
+ methodTypePtr, clientData\fR)
+.sp
+Tcl_Method
+\fBTcl_NewInstanceMethod\fR(\fIinterp, object, nameObj, isPublic,
+ methodTypePtr, clientData\fR)
+.sp
+\fBTcl_ClassSetConstructor\fR(\fIinterp, class, method\fR)
+.sp
+\fBTcl_ClassSetDestructor\fR(\fIinterp, class, method\fR)
+.sp
+Tcl_Class
+\fBTcl_MethodDeclarerClass\fR(\fImethod\fR)
+.sp
+Tcl_Object
+\fBTcl_MethodDeclarerObject\fR(\fImethod\fR)
+.sp
+Tcl_Obj *
+\fBTcl_MethodName\fR(\fImethod\fR)
+.sp
+int
+\fBTcl_MethodIsPublic\fR(\fImethod\fR)
+.sp
+int
+\fBTcl_MethodIsType\fR(\fImethod, methodTypePtr, clientDataPtr\fR)
+.sp
+int
+\fBTcl_ObjectContextInvokeNext\fR(\fIinterp, context, objc, objv, skip\fR)
+.sp
+int
+\fBTcl_ObjectContextIsFiltering\fR(\fIcontext\fR)
+.sp
+Tcl_Method
+\fBTcl_ObjectContextMethod\fR(\fIcontext\fR)
+.sp
+Tcl_Object
+\fBTcl_ObjectContextObject\fR(\fIcontext\fR)
+.sp
+int
+\fBTcl_ObjectContextSkippedArgs\fR(\fIcontext\fR)
+.SH ARGUMENTS
+.AS ClientData clientData in
+.AP Tcl_Interp *interp in/out
+The interpreter holding the object or class to create or update a method in.
+.AP Tcl_Object object in
+The object to create the method in.
+.AP Tcl_Class class in
+The class to create the method in.
+.AP Tcl_Obj *nameObj in
+The name of the method to create. Should not be NULL unless creating
+constructors or destructors.
+.AP int isPublic in
+A boolean flag saying whether the method is to be exported.
+.AP Tcl_MethodType *methodTypePtr in
+A description of the type of the method to create, or the type of method to
+compare against.
+.AP ClientData clientData in
+A piece of data that is passed to the implementation of the method without
+interpretation.
+.AP ClientData *clientDataPtr out
+A pointer to a variable in which to write the \fIclientData\fR value supplied
+when the method was created. If NULL, the \fIclientData\fR value will not be
+retrieved.
+.AP Tcl_Method method in
+A reference to a method to query.
+.AP Tcl_ObjectContext context in
+A reference to a method-call context. Note that client code \fImust not\fR
+retain a reference to a context.
+.AP int objc in
+The number of arguments to pass to the method implementation.
+.AP "Tcl_Obj *const" *objv in
+An array of arguments to pass to the method implementation.
+.AP int skip in
+The number of arguments passed to the method implementation that do not
+represent "real" arguments.
+.BE
+.SH DESCRIPTION
+.PP
+A method is an operation carried out on an object that is associated with the
+object. Every method must be attached to either an object or a class; methods
+attached to a class are associated with all instances (direct and indirect) of
+that class.
+.PP
+Given a method, the entity that declared it can be found using
+\fBTcl_MethodDeclarerClass\fR which returns the class that the method is
+attached to (or NULL if the method is not attached to any class) and
+\fBTcl_MethodDeclarerObject\fR which returns the object that the method is
+attached to (or NULL if the method is not attached to an object). The name of
+the method can be retrieved with \fBTcl_MethodName\fR and whether the method
+is exported is retrieved with \fBTcl_MethodIsPublic\fR. The type of the method
+can also be introspected upon to a limited degree; the function
+\fBTcl_MethodIsType\fR returns whether a method is of a particular type,
+assigning the per-method \fIclientData\fR to the variable pointed to by
+\fIclientDataPtr\fR if (that is non-NULL) if the type is matched.
+.SS "METHOD CREATION"
+.PP
+Methods are created by \fBTcl_NewMethod\fR and \fBTcl_NewInstanceMethod\fR,
+which
+create a method attached to a class or an object respectively. In both cases,
+the \fInameObj\fR argument gives the name of the method to create, the
+\fIisPublic\fR argument states whether the method should be exported
+initially, the \fImethodTypePtr\fR argument describes the implementation of
+the method (see the \fBMETHOD TYPES\fR section below) and the \fIclientData\fR
+argument gives some implementation-specific data that is passed on to the
+implementation of the method when it is called.
+.PP
+When the \fInameObj\fR argument to \fBTcl_NewMethod\fR is NULL, an
+unnamed method is created, which is used for constructors and destructors.
+Constructors should be installed into their class using the
+\fBTcl_ClassSetConstructor\fR function, and destructors (which must not
+require any arguments) should be installed into their class using the
+\fBTcl_ClassSetDestructor\fR function. Unnamed methods should not be used for
+any other purpose, and named methods should not be used as either constructors
+or destructors. Also note that a NULL \fImethodTypePtr\fR is used to provide
+internal signaling, and should not be used in client code.
+.SS "METHOD CALL CONTEXTS"
+.PP
+When a method is called, a method-call context reference is passed in as one
+of the arguments to the implementation function. This context can be inspected
+to provide information about the caller, but should not be retained beyond the
+moment when the method call terminates.
+.PP
+The method that is being called can be retrieved from the context by using
+\fBTcl_ObjectContextMethod\fR, and the object that caused the method to be
+invoked can be retrieved with \fBTcl_ObjectContextObject\fR. The number of
+arguments that are to be skipped (e.g. the object name and method name in a
+normal method call) is read with \fBTcl_ObjectContextSkippedArgs\fR, and the
+context can also report whether it is working as a filter for another method
+through \fBTcl_ObjectContextIsFiltering\fR.
+.PP
+During the execution of a method, the method implementation may choose to
+invoke the stages of the method call chain that come after the current method
+implementation. This (the core of the \fBnext\fR command) is done using
+\fBTcl_ObjectContextInvokeNext\fR. Note that this function does not manipulate
+the call-frame stack, unlike the \fBnext\fR command; if the method
+implementation has pushed one or more extra frames on the stack as part of its
+implementation, it is also responsible for temporarily popping those frames
+from the stack while the \fBTcl_ObjectContextInvokeNext\fR function is
+executing. Note also that the method-call context is \fInever\fR deleted
+during the execution of this function.
+.SH "METHOD TYPES"
+.PP
+The types of methods are described by a pointer to a Tcl_MethodType structure,
+which is defined as:
+.PP
+.CS
+typedef struct {
+ int \fIversion\fR;
+ const char *\fIname\fR;
+ Tcl_MethodCallProc *\fIcallProc\fR;
+ Tcl_MethodDeleteProc *\fIdeleteProc\fR;
+ Tcl_CloneProc *\fIcloneProc\fR;
+} \fBTcl_MethodType\fR;
+.CE
+.PP
+The \fIversion\fR field allows for future expansion of the structure, and
+should always be declared equal to TCL_OO_METHOD_VERSION_CURRENT. The
+\fIname\fR field provides a human-readable name for the type, and is reserved
+for debugging.
+.PP
+The \fIcallProc\fR field gives a function that is called when the method is
+invoked; it must never be NULL.
+.PP
+The \fIdeleteProc\fR field gives a function that is used to delete a
+particular method, and is called when the method is replaced or removed; if
+the field is NULL, it is assumed that the method's \fIclientData\fR needs no
+special action to delete.
+.PP
+The \fIcloneProc\fR field is either a function that is used to copy a method's
+\fIclientData\fR (as part of \fBTcl_CopyObjectInstance\fR) or NULL to indicate
+that the \fIclientData\fR can just be copied directly.
+.SS "TCL_METHODCALLPROC FUNCTION SIGNATURE"
+.PP
+Functions matching this signature are called when the method is invoked.
+.PP
+.CS
+typedef int \fBTcl_MethodCallProc\fR(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ Tcl_ObjectContext \fIobjectContext\fR,
+ int \fIobjc\fR,
+ Tcl_Obj *const *\fIobjv\fR);
+.CE
+.PP
+The \fIclientData\fR argument to a Tcl_MethodCallProc is the value that was
+given when the method was created, the \fIinterp\fR is a place in which to
+execute scripts and access variables as well as being where to put the result
+of the method, and the \fIobjc\fR and \fIobjv\fR fields give the parameter
+objects to the method. The calling context of the method can be discovered
+through the \fIobjectContext\fR argument, and the return value from a
+Tcl_MethodCallProc is any Tcl return code (e.g. TCL_OK, TCL_ERROR).
+.SS "TCL_METHODDELETEPROC FUNCTION SIGNATURE"
+.PP
+Functions matching this signature are used when a method is deleted, whether
+through a new method being created or because the object or class is deleted.
+.PP
+.CS
+typedef void \fBTcl_MethodDeleteProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR argument to a Tcl_MethodDeleteProc will be the same as
+the value passed to the \fIclientData\fR argument to \fBTcl_NewMethod\fR or
+\fBTcl_NewInstanceMethod\fR when the method was created.
+.SS "TCL_CLONEPROC FUNCTION SIGNATURE"
+.PP
+Functions matching this signature are used to copy a method when the object or
+class is copied using \fBTcl_CopyObjectInstance\fR (or \fBoo::copy\fR).
+.PP
+.CS
+typedef int \fBTcl_CloneProc\fR(
+ Tcl_Interp *\fIinterp\fR,
+ ClientData \fIoldClientData\fR,
+ ClientData *\fInewClientDataPtr\fR);
+.CE
+.PP
+The \fIinterp\fR argument gives a place to write an error message when the
+attempt to clone the object is to fail, in which case the clone procedure must
+also return TCL_ERROR; it should return TCL_OK otherwise.
+The \fIoldClientData\fR field to a Tcl_CloneProc gives the value from the
+method being copied from, and the \fInewClientDataPtr\fR field will point to
+a variable in which to write the value for the method being copied to.
+.SH "SEE ALSO"
+Class(3), oo::class(n), oo::define(n), oo::object(n)
+.SH KEYWORDS
+constructor, method, object
+
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/pkgs/msgcat/doc/NRE.3 b/pkgs/msgcat/doc/NRE.3
new file mode 100644
index 0000000..5c27491
--- /dev/null
+++ b/pkgs/msgcat/doc/NRE.3
@@ -0,0 +1,328 @@
+.\"
+.\" Copyright (c) 2008 by Kevin B. Kenny.
+.\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH NRE 3 8.6 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_NRCreateCommand, Tcl_NRCallObjProc, Tcl_NREvalObj, Tcl_NREvalObjv, Tcl_NRCmdSwap, Tcl_NRAddCallback \- Non-Recursive (stackless) evaluation of Tcl scripts.
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Command
+\fBTcl_NRCreateCommand\fR(\fIinterp, cmdName, proc, nreProc, clientData,
+ deleteProc\fR)
+.sp
+int
+\fBTcl_NRCallObjProc\fR(\fIinterp, nreProc, clientData, objc, objv\fR)
+.sp
+int
+\fBTcl_NREvalObj\fR(\fIinterp, objPtr, flags\fR)
+.sp
+int
+\fBTcl_NREvalObjv\fR(\fIinterp, objc, objv, flags\fR)
+.sp
+int
+\fBTcl_NRCmdSwap\fR(\fIinterp, cmd, objc, objv, flags\fR)
+.sp
+int
+\fBTcl_NRExprObj\fR(\fIinterp, objPtr, resultPtr\fR)
+.sp
+void
+\fBTcl_NRAddCallback\fR(\fIinterp, postProcPtr, data0, data1, data2, data3\fR)
+.fi
+.SH ARGUMENTS
+.AS Tcl_CmdDeleteProc *interp in
+.AP Tcl_Interp *interp in
+Interpreter in which to create or evaluate a command.
+.AP char *cmdName in
+Name of a new command to create.
+.AP Tcl_ObjCmdProc *proc in
+Implementation of a command that will be called whenever \fIcmdName\fR
+is invoked as a command in the unoptimized way.
+.AP Tcl_ObjCmdProc *nreProc in
+Implementation of a command that will be called whenever \fIcmdName\fR
+is invoked and requested to conserve the C stack.
+.AP ClientData clientData in
+Arbitrary one-word value that will be passed to \fIproc\fR, \fInreProc\fR,
+\fIdeleteProc\fR and \fIobjProc\fR.
+.AP Tcl_CmdDeleteProc *deleteProc in/out
+Procedure to call before \fIcmdName\fR is deleted from the interpreter.
+This procedure allows for command-specific cleanup. If \fIdeleteProc\fR
+is \fBNULL\fR, then no procedure is called before the command is deleted.
+.AP int objc in
+Count of parameters provided to the implementation of a command.
+.AP Tcl_Obj **objv in
+Pointer to an array of Tcl objects. Each object holds the value of a
+single word in the command to execute.
+.AP Tcl_Obj *objPtr in
+Pointer to a Tcl_Obj whose value is a script or expression to execute.
+.AP int flags in
+ORed combination of flag bits that specify additional options.
+\fBTCL_EVAL_GLOBAL\fR is the only flag that is currently supported.
+.\" TODO: This is a lie. But kbk didn't grasp TCL_EVAL_INVOKE and
+.\" TCL_EVAL_NOERR well enough to document them.
+.AP Tcl_Command cmd in
+Token for a command that is to be used instead of the currently
+executing command.
+.AP Tcl_Obj *resultPtr out
+Pointer to an unshared Tcl_Obj where the result of expression
+evaluation is written.
+.AP Tcl_NRPostProc *postProcPtr in
+Pointer to a function that will be invoked when the command currently
+executing in the interpreter designated by \fIinterp\fR completes.
+.AP ClientData data0 in
+.AP ClientData data1 in
+.AP ClientData data2 in
+.AP ClientData data3 in
+\fIdata0\fR through \fIdata3\fR are four one-word values that will be passed
+to the function designated by \fIpostProcPtr\fR when it is invoked.
+.BE
+.SH DESCRIPTION
+.PP
+This series of C functions provides an interface whereby commands that
+are implemented in C can be evaluated, and invoke Tcl commands scripts
+and scripts, without consuming space on the C stack. The non-recursive
+evaluation is done by installing a \fItrampoline\fR, a small piece of
+code that invokes a command or script, and then executes a series of
+callbacks when the command or script returns.
+.PP
+The \fBTcl_NRCreateCommand\fR function creates a Tcl command in the
+interpreter designated by \fIinterp\fR that is prepared to handle
+nonrecursive evaluation with a trampoline. The \fIcmdName\fR argument
+gives the name of the new command. If \fIcmdName\fR contains any
+namespace qualifiers, then the new command is added to the specified
+namespace; otherwise, it is added to the global namespace. \fIproc\fR
+gives the procedure that will be called when the interpreter wishes to
+evaluate the command in an unoptimized manner, and \fInreProc\fR is
+the procedure that will be called when the interpreter wishes to
+evaluate the command using a trampoline. \fIdeleteProc\fR is a
+function that will be called before the command is deleted from the
+interpreter. When any of the three functions is invoked, it is passed
+the \fIclientData\fR parameter.
+.PP
+\fBTcl_NRCreateCommand\fR deletes any existing command
+\fIname\fR already associated with the interpreter
+(however see below for an exception where the existing command
+is not deleted).
+It returns a token that may be used to refer
+to the command in subsequent calls to \fBTcl_GetCommandName\fR.
+If \fBTcl_NRCreateCommand\fR is called for an interpreter that is in
+the process of being deleted, then it does not create a new command,
+does not delete any existing command of the same name, and returns NULL.
+.PP
+The \fIproc\fR and \fInreProc\fR function are expected to conform to
+all the rules set forth for the \fIproc\fR argument to
+\fBTcl_CreateObjCommand\fR(3) (\fIq.v.\fR).
+.PP
+When a command that is written to cope with evaluation via trampoline
+is invoked without a trampoline on the stack, it will usually respond
+to the invocation by creating a trampoline and calling the
+trampoline-enabled implementation of the same command. This call is done by
+means of \fBTcl_NRCallObjProc\fR. In the call to
+\fBTcl_NRCallObjProc\fR, the \fIinterp\fR, \fIclientData\fR,
+\fIobjc\fR and \fIobjv\fR parameters should be the same ones that were
+passed to \fIproc\fR. The \fInreProc\fR parameter should designate the
+trampoline-enabled implementation of the command.
+.PP
+\fBTcl_NREvalObj\fR arranges for the script contained in \fIobjPtr\fR
+to be evaluated in the interpreter designated by \fIinterp\fR after
+the current command (which must be trampoline-enabled) returns. It is
+the method by which a command may invoke a script without consuming
+space on the C stack. Similarly, \fBTcl_NREvalObjv\fR arranges to
+invoke a single Tcl command whose words have already been separated
+and substituted. The \fIobjc\fR and \fIobjv\fR parameters give the
+words of the command to be evaluated when execution reaches the
+trampoline.
+.PP
+\fBTcl_NRCmdSwap\fR allows for trampoline evaluation of a command whose
+resolution is already known. The \fIcmd\fR parameter gives a
+\fBTcl_Command\fR object (returned from \fBTcl_CreateObjCommand\fR or
+\fBTcl_GetCommandFromObj\fR) identifying the command to be invoked in
+the trampoline; this command must match the word in \fIobjv[0]\fR.
+The remaining arguments are as for \fBTcl_NREvalObj\fR.
+.PP
+\fBTcl_NREvalObj\fR, \fBTcl_NREvalObjv\fR and \fBTcl_NRCmdSwap\fR
+all accept a \fIflags\fR parameter, which is an OR-ed-together set of
+bits to control evaluation. At the present time, the only supported flag
+available to callers is \fBTCL_EVAL_GLOBAL\fR.
+.\" TODO: Again, this is a lie. Do we want to explain TCL_EVAL_INVOKE
+.\" and TCL_EVAL_NOERR?
+If the \fBTCL_EVAL_GLOBAL\fR flag is set, the script or command is
+evaluated in the global namespace. If it is not set, it is evaluated
+in the current namespace.
+.PP
+\fBTcl_NRExprObj\fR arranges for the expression contained in \fIobjPtr\fR
+to be evaluated in the interpreter designated by \fIinterp\fR after
+the current command (which must be trampoline-enabled) returns. It is
+the method by which a command may evaluate a Tcl expression without consuming
+space on the C stack. The argument \fIresultPtr\fR is a pointer to an
+unshared Tcl_Obj where the result of expression evaluation is to be written.
+If expression evaluation returns any code other than TCL_OK, the
+\fIresultPtr\fR value is left untouched.
+.PP
+All of the routines return \fBTCL_OK\fR if command or expression invocation
+has been scheduled successfully. If for any reason the scheduling cannot
+be completed (for example, if the interpreter is unable to find
+the requested command), they return \fBTCL_ERROR\fR with an
+appropriate message left in the interpreter's result.
+.PP
+\fBTcl_NRAddCallback\fR arranges to have a C function called when the
+current trampoline-enabled command in the Tcl interpreter designated
+by \fIinterp\fR returns. The \fIpostProcPtr\fR argument is a pointer
+to the callback function, which must have arguments and return value
+consistent with the \fBTcl_NRPostProc\fR data type:
+.PP
+.CS
+typedef int
+\fBTcl_NRPostProc\fR(
+ \fBClientData\fR \fIdata\fR[],
+ \fBTcl_Interp\fR *\fIinterp\fR,
+ int \fIresult\fR);
+.CE
+.PP
+When the trampoline invokes the callback function, the \fIdata\fR
+parameter will point to an array containing the four one-word
+quantities that were passed to \fBTcl_NRAddCallback\fR in the
+\fIdata0\fR through \fIdata3\fR parameters. The Tcl interpreter will
+be designated by the \fIinterp\fR parameter, and the \fIresult\fR
+parameter will contain the result (\fBTCL_OK\fR, \fBTCL_ERROR\fR,
+\fBTCL_RETURN\fR, \fBTCL_BREAK\fR or \fBTCL_CONTINUE\fR) that was
+returned by the command evaluation. The callback function is expected,
+in turn, either to return a \fIresult\fR to control further evaluation.
+.PP
+Multiple \fBTcl_NRAddCallback\fR invocations may request multiple
+callbacks, which may be to the same or different callback
+functions. If multiple callbacks are requested, they are executed in
+last-in, first-out order, that is, the most recently requested
+callback is executed first.
+.SH EXAMPLE
+.PP
+The usual pattern for Tcl commands that invoke other Tcl commands
+is something like:
+.PP
+.CS
+int
+\fITheCmdObjProc\fR(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ int result;
+ Tcl_Obj *objPtr;
+
+ \fI... preparation ...\fR
+
+ result = \fBTcl_EvalObjEx\fR(interp, objPtr, 0);
+
+ \fI... postprocessing ...\fR
+
+ return result;
+}
+\fBTcl_CreateObjCommand\fR(interp, "theCommand",
+ \fITheCmdObjProc\fR, clientData, TheCmdDeleteProc);
+.CE
+.PP
+To enable a command like this one for trampoline-based evaluation,
+it must be split into three pieces:
+.IP \(bu
+A non-trampoline implementation, \fITheCmdNewObjProc\fR,
+which will simply create a trampoline
+and invoke the trampoline-based implementation.
+.IP \(bu
+A trampoline-enabled implementation, \fITheCmdNRObjProc\fR. This
+function will perform the initialization, request that the trampoline
+call the postprocessing routine after command evaluation, and finally,
+request that the trampoline call the inner command.
+.IP \(bu
+A postprocessing routine, \fITheCmdPostProc\fR. This function will
+perform the postprocessing formerly done after the return from the
+inner command in \fITheCmdObjProc\fR.
+.PP
+The non-trampoline implementation is simple and stylized, containing
+a single statement:
+.PP
+.CS
+int
+\fITheCmdNewObjProc\fR(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ return \fBTcl_NRCallObjProc\fR(interp, name,
+ \fITheCmdNRObjProc\fR, clientData, objc, objv);
+}
+.CE
+.PP
+The trampoline-enabled implementation requests postprocessing,
+and returns to the trampoline requesting command evaluation.
+.PP
+.CS
+int
+\fITheCmdNRObjProc\fR
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ Tcl_Obj *objPtr;
+
+ \fI... preparation ...\fR
+
+ \fBTcl_NRAddCallback\fR(interp, \fITheCmdPostProc\fR,
+ data0, data1, data2, data3);
+ /* \fIdata0 .. data3\fR are up to four one-word items to
+ * pass to the postprocessing procedure */
+
+ return \fBTcl_NREvalObj\fR(interp, objPtr, 0);
+}
+.CE
+.PP
+The postprocessing procedure does whatever the original command did
+upon return from the inner evaluation.
+.PP
+.CS
+int
+\fITheCmdNRPostProc\fR(
+ ClientData data[],
+ Tcl_Interp *interp,
+ int result)
+{
+ /* \fIdata[0] .. data[3]\fR are the four words of data
+ * passed to \fBTcl_NREvalObj\fR */
+
+ \fI... postprocessing ...\fR
+
+ return result;
+}
+.CE
+.PP
+If \fItheCommand\fR is a command that results in multiple commands or
+scripts being evaluated, its postprocessing routine may schedule
+additional postprocessing and then request another command evaluation
+by means of \fBTcl_NREvalObj\fR or one of the other evaluation
+routines. Looping and sequencing constructs may be implemented in this way.
+.PP
+Finally, to install a trampoline-enabled command in the interpreter,
+\fBTcl_NRCreateCommand\fR is used in place of
+\fBTcl_CreateObjCommand\fR. It accepts two command procedures instead
+of one. The first is for use when no trampoline is yet on the stack,
+and the second is for use when there is already a trampoline in place.
+.PP
+.CS
+\fBTcl_NRCreateCommand\fR(interp, "theCommand",
+ \fITheCmdObjProc\fR, \fITheCmdNRObjProc\fR, clientData,
+ TheCmdDeleteProc);
+.CE
+.SH "SEE ALSO"
+Tcl_CreateCommand(3), Tcl_CreateObjCommand(3), Tcl_EvalObjEx(3), Tcl_GetCommandFromObj(3), Tcl_ExprObj(3)
+.SH KEYWORDS
+stackless, nonrecursive, execute, command, global, object, result, script
+.SH COPYRIGHT
+Copyright (c) 2008 by Kevin B. Kenny
diff --git a/pkgs/msgcat/doc/Namespace.3 b/pkgs/msgcat/doc/Namespace.3
new file mode 100644
index 0000000..50cc559
--- /dev/null
+++ b/pkgs/msgcat/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:
+.PP
+.CS
+typedef void \fBTcl_NamespaceDeleteProc\fR(
+ ClientData \fIclientData\fR);
+.CE
+.PP
+\fBTcl_DeleteNamespace\fR deletes a namespace, calling the
+\fIdeleteProc\fR defined for the namespace (if any).
+.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(3), Tcl_ListObjAppendList(3), Tcl_SetVar(3)
+.SH KEYWORDS
+namespace, command
diff --git a/pkgs/msgcat/doc/Notifier.3 b/pkgs/msgcat/doc/Notifier.3
new file mode 100644
index 0000000..f65d580
--- /dev/null
+++ b/pkgs/msgcat/doc/Notifier.3
@@ -0,0 +1,635 @@
+'\"
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\" Copyright (c) 1995-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 Notifier 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_SetMaxBlockTime, Tcl_QueueEvent, Tcl_ThreadQueueEvent, Tcl_ThreadAlert, Tcl_GetCurrentThread, Tcl_DeleteEvents, Tcl_InitNotifier, Tcl_FinalizeNotifier, Tcl_WaitForEvent, Tcl_AlertNotifier, Tcl_SetTimer, Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, Tcl_SetServiceMode, Tcl_ServiceModeHook, Tcl_SetNotifier \- the event queue and notifier interfaces
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_CreateEventSource\fR(\fIsetupProc, checkProc, clientData\fR)
+.sp
+void
+\fBTcl_DeleteEventSource\fR(\fIsetupProc, checkProc, clientData\fR)
+.sp
+void
+\fBTcl_SetMaxBlockTime\fR(\fItimePtr\fR)
+.sp
+void
+\fBTcl_QueueEvent\fR(\fIevPtr, position\fR)
+.sp
+void
+\fBTcl_ThreadQueueEvent\fR(\fIthreadId, evPtr, position\fR)
+.sp
+void
+\fBTcl_ThreadAlert\fR(\fIthreadId\fR)
+.sp
+Tcl_ThreadId
+\fBTcl_GetCurrentThread\fR()
+.sp
+void
+\fBTcl_DeleteEvents\fR(\fIdeleteProc, clientData\fR)
+.sp
+ClientData
+\fBTcl_InitNotifier\fR()
+.sp
+void
+\fBTcl_FinalizeNotifier\fR(\fIclientData\fR)
+.sp
+int
+\fBTcl_WaitForEvent\fR(\fItimePtr\fR)
+.sp
+void
+\fBTcl_AlertNotifier\fR(\fIclientData\fR)
+.sp
+void
+\fBTcl_SetTimer\fR(\fItimePtr\fR)
+.sp
+int
+\fBTcl_ServiceAll\fR()
+.sp
+int
+\fBTcl_ServiceEvent\fR(\fIflags\fR)
+.sp
+int
+\fBTcl_GetServiceMode\fR()
+.sp
+int
+\fBTcl_SetServiceMode\fR(\fImode\fR)
+.sp
+void
+\fBTcl_ServiceModeHook\fR(\fImode\fR)
+.sp
+void
+\fBTcl_SetNotifier\fR(\fInotifierProcPtr\fR)
+.SH ARGUMENTS
+.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
+Procedure for \fBTcl_DoOneEvent\fR to invoke after waiting for
+events. Checks to see if any events have occurred and, if so,
+queues them.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIsetupProc\fR, \fIcheckProc\fR, or
+\fIdeleteProc\fR.
+.AP "const Tcl_Time" *timePtr in
+Indicates the maximum amount of time to wait for an event. This
+is specified as an interval (how long to wait), not an absolute
+time (when to wakeup). If the pointer passed to \fBTcl_WaitForEvent\fR
+is NULL, it means there is no maximum wait time: wait forever if
+necessary.
+.AP Tcl_Event *evPtr in
+An event to add to the event queue. The storage for the event must
+have been allocated by the caller using \fBTcl_Alloc\fR or \fBckalloc\fR.
+.AP Tcl_QueuePosition position in
+Where to add the new event in the queue: \fBTCL_QUEUE_TAIL\fR,
+\fBTCL_QUEUE_HEAD\fR, or \fBTCL_QUEUE_MARK\fR.
+.AP Tcl_ThreadId threadId in
+A unique identifier for a thread.
+.AP Tcl_EventDeleteProc *deleteProc in
+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.
+.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.
+.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
+.PP
+The interfaces described here are used to customize the Tcl event
+loop. The two most common customizations are to add new sources of
+events and to merge Tcl's event loop with some other event loop, such
+as one provided by an application in which Tcl is embedded. Each of
+these tasks is described in a separate section below.
+.PP
+The procedures in this manual entry are the building blocks out of which
+the Tcl event notifier is constructed. The event notifier is the lowest
+layer in the Tcl event mechanism. It consists of three things:
+.IP [1]
+Event sources: these represent the ways in which events can be
+generated. For example, there is a timer event source that implements
+the \fBTcl_CreateTimerHandler\fR procedure and the \fBafter\fR
+command, and there is a file event source that implements the
+\fBTcl_CreateFileHandler\fR procedure on Unix systems. An event
+source must work with the notifier to detect events at the right
+times, record them on the event queue, and eventually notify
+higher-level software that they have occurred. The procedures
+\fBTcl_CreateEventSource\fR, \fBTcl_DeleteEventSource\fR,
+and \fBTcl_SetMaxBlockTime\fR, \fBTcl_QueueEvent\fR, and
+\fBTcl_DeleteEvents\fR are used primarily by event sources.
+.IP [2]
+The event queue: for non-threaded applications,
+there is a single queue for the whole application,
+containing events that have been detected but not yet serviced. Event
+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. Threaded applications work in a
+similar manner, except that there is a separate event queue for
+each thread containing a Tcl interpreter.
+\fBTcl_QueueEvent\fR is used (primarily
+by event sources) to add events to the event queue and
+\fBTcl_DeleteEvents\fR is used to remove events from the queue without
+processing them. In a threaded application, \fBTcl_QueueEvent\fR adds
+an event to the current thread's queue, and \fBTcl_ThreadQueueEvent\fR
+adds an event to a queue in a specific thread.
+.IP [3]
+The event loop: in order to detect and process events, the application
+enters a loop that waits for events to occur, places them on the event
+queue, and then processes them. Most applications will do this by
+calling the procedure \fBTcl_DoOneEvent\fR, which is described in a
+separate manual entry.
+.PP
+Most Tcl applications need not worry about any of the internals of
+the Tcl notifier. However, the notifier now has enough flexibility
+to be retargeted either for a new platform or to use an external event
+loop (such as the Motif event loop, when Tcl is embedded in a Motif
+application). The procedures \fBTcl_WaitForEvent\fR and
+\fBTcl_SetTimer\fR are normally implemented by Tcl, but may be
+replaced with new versions to retarget the notifier (the
+\fBTcl_InitNotifier\fR, \fBTcl_AlertNotifier\fR,
+\fBTcl_FinalizeNotifier\fR, \fBTcl_Sleep\fR,
+\fBTcl_CreateFileHandler\fR, and \fBTcl_DeleteFileHandler\fR must
+also be replaced; see CREATING A NEW NOTIFIER below for details).
+The procedures \fBTcl_ServiceAll\fR, \fBTcl_ServiceEvent\fR,
+\fBTcl_GetServiceMode\fR, and \fBTcl_SetServiceMode\fR are provided
+to help connect Tcl's event loop to an external event loop such as
+Motif's.
+.SH "NOTIFIER BASICS"
+.PP
+The easiest way to understand how the notifier works is to consider
+what happens when \fBTcl_DoOneEvent\fR is called.
+\fBTcl_DoOneEvent\fR is passed a \fIflags\fR argument that indicates
+what sort of events it is OK to process and also whether or not to
+block if no events are ready. \fBTcl_DoOneEvent\fR does the following
+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
+from the queue, and return. It does this by calling
+\fBTcl_ServiceEvent\fR and passing in the \fIflags\fR argument.
+.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
+possibly call \fBTcl_SetMaxBlockTime\fR to limit how long
+\fBTcl_WaitForEvent\fR will block if no new events occur.
+.IP [3]
+Call \fBTcl_WaitForEvent\fR. This procedure is implemented differently
+on different platforms; it waits for an event to occur, based on the
+information provided by the event sources.
+It may cause the application to block if \fItimePtr\fR specifies
+an interval other than 0.
+\fBTcl_WaitForEvent\fR returns when something has happened,
+such as a file becoming readable or the interval given by \fItimePtr\fR
+expiring. If there are no events for \fBTcl_WaitForEvent\fR to
+wait for, so that it would block forever, then it returns immediately
+and \fBTcl_DoOneEvent\fR returns 0.
+.IP [4]
+Call a \fIcheck procedure\fR in each event source. The check
+procedure determines whether any events of interest to this source
+occurred. If so, the events are added to the event queue.
+.IP [5]
+Check the event queue to see if it contains any events that can
+be serviced. If so, service the first possible event, remove it
+from the queue, and return.
+.IP [6]
+See if there are idle callbacks pending. If so, invoke all of them and
+return.
+.IP [7]
+Either return 0 to indicate that no events were ready, or go back to
+step [2] if blocking was requested by the caller.
+.SH "CREATING A NEW EVENT SOURCE"
+.PP
+An event source consists of three procedures invoked by the notifier,
+plus additional C procedures that are invoked by higher-level code
+to arrange for event-driven callbacks. The three procedures called
+by the notifier consist of the setup and check procedures described
+above, plus an additional procedure that is invoked when an event
+is removed from the event queue for servicing.
+.PP
+The procedure \fBTcl_CreateEventSource\fR creates a new event source.
+Its arguments specify the setup procedure and check procedure for
+the event source.
+\fISetupProc\fR should match the following prototype:
+.PP
+.CS
+typedef void \fBTcl_EventSetupProc\fR(
+ ClientData \fIclientData\fR,
+ int \fIflags\fR);
+.CE
+.PP
+The \fIclientData\fR argument will be the same as the \fIclientData\fR
+argument to \fBTcl_CreateEventSource\fR; it is typically used to
+point to private information managed by the event source.
+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 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.
+.PP
+\fISetupProc\fR's job is to make sure that the application wakes up
+when events of the desired type occur. This is typically done in a
+platform-dependent fashion. For example, under Unix an event source
+might call \fBTcl_CreateFileHandler\fR; under Windows it might
+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.
+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
+interval passed to \fBTcl_SetMaxBlockTime\fR by one of the event
+sources. If an event source knows that it already has events ready to
+report, it can request a zero maximum block time. For example, the
+setup procedure for the X event source looks to see if there are
+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.
+The \fItimePtr\fR argument to \fBTcl_WaitForEvent\fR points to
+a structure that describes a time interval in seconds and
+microseconds:
+.PP
+.CS
+typedef struct Tcl_Time {
+ long \fIsec\fR;
+ long \fIusec\fR;
+} \fBTcl_Time\fR;
+.CE
+.PP
+The \fIusec\fR field should be less than 1000000.
+.PP
+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.
+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
+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
+handler is registered that needs to poll for events, the event source
+may call \fBTcl_SetMaxBlockTime\fR to set the block time to zero to
+force the external event loop to call Tcl. In this case,
+\fBTcl_SetMaxBlockTime\fR invokes \fBTcl_SetTimer\fR with the shortest
+interval seen since the last call to \fBTcl_DoOneEvent\fR or
+\fBTcl_ServiceAll\fR.
+.PP
+In addition to the generic procedure \fBTcl_SetMaxBlockTime\fR, other
+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.
+.PP
+The second procedure provided by each event source is its check
+procedure, indicated by the \fIcheckProc\fR argument to
+\fBTcl_CreateEventSource\fR. \fICheckProc\fR must match the
+following prototype:
+.PP
+.CS
+typedef void \fBTcl_EventCheckProc\fR(
+ ClientData \fIclientData\fR,
+ int \fIflags\fR);
+.CE
+.PP
+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
+for events. Presumably at least one event source is now prepared to
+queue an event. \fBTcl_DoOneEvent\fR calls each of the event sources
+in turn, so they all have a chance to queue any events that are ready.
+The check procedure does two things. First, it must see if any events
+have triggered. Different event sources do this in different ways.
+.PP
+If an event source's check procedure detects an interesting event, it
+must add the event to Tcl's event queue. To do this, the event source
+calls \fBTcl_QueueEvent\fR. The \fIevPtr\fR argument is a pointer to
+a dynamically allocated structure containing the event (see below for
+more information on memory management issues). Each event source can
+define its own event structure with whatever information is relevant
+to that event source. However, the first element of the structure
+must be a structure of type \fBTcl_Event\fR, and the address of this
+structure is used when communicating between the event source and the
+rest of the notifier. A \fBTcl_Event\fR has the following definition:
+.PP
+.CS
+typedef struct {
+ Tcl_EventProc *\fIproc\fR;
+ struct Tcl_Event *\fInextPtr\fR;
+} \fBTcl_Event\fR;
+.CE
+.PP
+The event source must fill in the \fIproc\fR field of
+the event before calling \fBTcl_QueueEvent\fR.
+The \fInextPtr\fR is used to link together the events in the queue
+and should not be modified by the event source.
+.PP
+An event may be added to the queue at any of three positions, depending
+on the \fIposition\fR argument to \fBTcl_QueueEvent\fR:
+.IP \fBTCL_QUEUE_TAIL\fR 24
+Add the event at the back of the queue, so that all other pending
+events will be serviced first. This is almost always the right
+place for new events.
+.IP \fBTCL_QUEUE_HEAD\fR 24
+Add the event at the front of the queue, so that it will be serviced
+before all other queued events.
+.IP \fBTCL_QUEUE_MARK\fR 24
+Add the event at the front of the queue, unless there are other
+events at the front whose position is \fBTCL_QUEUE_MARK\fR; if so,
+add the new event just after all other \fBTCL_QUEUE_MARK\fR events.
+This value of \fIposition\fR is used to insert an ordered sequence of
+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
+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
+in the first queued \fBTcl_Event\fR structure.
+\fIProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_EventProc\fR(
+ Tcl_Event *\fIevPtr\fR,
+ int \fIflags\fR);
+.CE
+.PP
+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
+current call to \fBTcl_ServiceEvent\fR; this is used by the event source
+to return immediately if its events are not relevant.
+.PP
+It is up to \fIproc\fR to handle the event, typically by invoking
+one or more Tcl commands or C-level callbacks.
+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
+should be deferred for processing later; in this case \fBTcl_ServiceEvent\fR
+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 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
+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
+the event source (using \fBTcl_Alloc\fR or the Tcl macro \fBckalloc\fR)
+before calling \fBTcl_QueueEvent\fR, but it
+will be freed by \fBTcl_ServiceEvent\fR, not by the event source.
+.PP
+Threaded applications work in a
+similar manner, except that there is a separate event queue for
+each thread containing a Tcl interpreter.
+Calling \fBTcl_QueueEvent\fR in a multithreaded application adds
+an event to the current thread's queue.
+To add an event to another thread's queue, use \fBTcl_ThreadQueueEvent\fR.
+\fBTcl_ThreadQueueEvent\fR accepts as an argument a Tcl_ThreadId argument,
+which uniquely identifies a thread in a Tcl application. To obtain the
+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
+.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
+for each event in the queue, deleting those for with the procedure
+returns 1. Events for which the procedure returns 0 are left in the
+queue. \fIProc\fR should match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_EventDeleteProc\fR(
+ Tcl_Event *\fIevPtr\fR,
+ ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR argument will be the same as the \fIclientData\fR
+argument to \fBTcl_DeleteEvents\fR; it is typically used to point to
+private information managed by the event source. The \fIevPtr\fR will
+point to the next event in the queue.
+.PP
+\fBTcl_DeleteEventSource\fR deletes an event source. The \fIsetupProc\fR,
+\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.
+.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
+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, 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
+procedure when initializing a Tcl interpreter. Similarly,
+\fBTcl_FinalizeNotifier\fR shuts down the notifier, and is
+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
+.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
+\fBTcl_WaitForEvent\fR gives the maximum time to block for an event,
+based on calls to \fBTcl_SetMaxBlockTime\fR made by setup procedures
+and on other information (such as the \fBTCL_DONT_WAIT\fR bit in
+\fIflags\fR).
+.PP
+Ideally, \fBTcl_WaitForEvent\fR should only wait for an event
+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 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 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
+platform where \fBTcl_WaitForEvent\fR only waits without doing any event
+processing, or \fBTcl_WaitForEvent\fR knows for sure that there are no
+additional events to process (e.g. it returned because the time
+elapsed). Finally, a return value of \-1 means that the event loop is
+no longer operational and the application should probably unwind and
+terminate. Under Windows this happens when a WM_QUIT message is received;
+under Unix it happens when \fBTcl_WaitForEvent\fR would have waited
+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
+.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
+If the notifier will be used with an external event loop, then it must
+also support the \fBTcl_SetTimer\fR interface. \fBTcl_SetTimer\fR is
+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 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
+procedures, which are described in the \fBTcl_CreateFileHandler\fR
+manual page.
+.PP
+The \fBTcl_Sleep\fR and \fBTcl_DoOneEvent\fR interfaces are described
+in their respective manual pages.
+.PP
+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:
+.PP
+.CS
+typedef struct Tcl_NotifierProcs {
+ Tcl_SetTimerProc *\fIsetTimerProc\fR;
+ Tcl_WaitForEventProc *\fIwaitForEventProc\fR;
+ Tcl_CreateFileHandlerProc *\fIcreateFileHandlerProc\fR;
+ Tcl_DeleteFileHandlerProc *\fIdeleteFileHandlerProc\fR;
+ Tcl_InitNotifierProc *\fIinitNotifierProc\fR;
+ Tcl_FinalizeNotifierProc *\fIfinalizeNotifierProc\fR;
+ Tcl_AlertNotifierProc *\fIalertNotifierProc\fR;
+ Tcl_ServiceModeHookProc *\fIserviceModeHookProc\fR;
+} \fBTcl_NotifierProcs\fR;
+.CE
+.PP
+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
+applications that have their own private event loops. In this case,
+the application does not call \fBTcl_DoOneEvent\fR except in the case
+of recursive event loops such as calls to the Tcl commands \fBupdate\fR
+or \fBvwait\fR. Most of the time is spent in the external event loop
+of the application. In this case the notifier must arrange for the
+external event loop to call back into Tcl when something
+happens on the various Tcl event sources. These callbacks should
+arrange for appropriate Tcl events to be placed on the Tcl event queue.
+.PP
+Because the external event loop is not calling \fBTcl_DoOneEvent\fR on
+a regular basis, it is up to the notifier to arrange for
+\fBTcl_ServiceEvent\fR to be called whenever events are pending on the
+Tcl event queue. The easiest way to do this is to invoke
+\fBTcl_ServiceAll\fR at the end of each callback from the external
+event loop. This will ensure that all of the event sources are
+polled, any queued events are serviced, and any pending idle handlers
+are processed before returning control to the application. In
+addition, event sources that need to poll for events can call
+\fBTcl_SetMaxBlockTime\fR to force the external event loop to call
+Tcl even if no events are available on the system event queue.
+.PP
+As a side effect of processing events detected in the main external
+event loop, Tcl may invoke \fBTcl_DoOneEvent\fR to start a recursive event
+loop in commands like \fBvwait\fR. \fBTcl_DoOneEvent\fR will invoke
+the external event loop, which will result in callbacks as described
+in the preceding paragraph, which will result in calls to
+\fBTcl_ServiceAll\fR. However, in these cases it is undesirable to
+service events in \fBTcl_ServiceAll\fR. Servicing events there is
+unnecessary because control will immediately return to the
+external event loop and hence to \fBTcl_DoOneEvent\fR, which can
+service the events itself. Furthermore, \fBTcl_DoOneEvent\fR is
+supposed to service only a single event, whereas \fBTcl_ServiceAll\fR
+normally services all pending events. To handle this situation,
+\fBTcl_DoOneEvent\fR sets a flag for \fBTcl_ServiceAll\fR
+that causes it to return without servicing any events.
+This flag is called the \fIservice mode\fR;
+\fBTcl_DoOneEvent\fR restores it to its previous value before it returns.
+.PP
+In some cases, however, it may be necessary for \fBTcl_ServiceAll\fR
+to service events
+even when it has been invoked from \fBTcl_DoOneEvent\fR. This happens
+when there is yet another recursive event loop invoked via an
+event handler called by \fBTcl_DoOneEvent\fR (such as one that is
+part of a native widget). In this case, \fBTcl_DoOneEvent\fR may not
+have a chance to service events so \fBTcl_ServiceAll\fR must service
+them all. Any recursive event loop that calls an external event
+loop rather than \fBTcl_DoOneEvent\fR must reset the service mode so
+that all events get processed in \fBTcl_ServiceAll\fR. This is done
+by invoking the \fBTcl_SetServiceMode\fR procedure. If
+\fBTcl_SetServiceMode\fR is passed \fBTCL_SERVICE_NONE\fR, then calls
+to \fBTcl_ServiceAll\fR will return immediately without processing any
+events. If \fBTcl_SetServiceMode\fR is passed \fBTCL_SERVICE_ALL\fR,
+then calls to \fBTcl_ServiceAll\fR will behave normally.
+\fBTcl_SetServiceMode\fR returns the previous value of the service
+mode, which should be restored when the recursive loop exits.
+\fBTcl_GetServiceMode\fR returns the current value of the service
+mode.
+.SH "SEE ALSO"
+Tcl_CreateFileHandler(3), Tcl_DeleteFileHandler(3), Tcl_Sleep(3),
+Tcl_DoOneEvent(3), Thread(3)
+.SH KEYWORDS
+event, notifier, event queue, event sources, file events, timer, idle, service mode, threads
diff --git a/pkgs/msgcat/doc/Object.3 b/pkgs/msgcat/doc/Object.3
new file mode 100644
index 0000000..1c60449
--- /dev/null
+++ b/pkgs/msgcat/doc/Object.3
@@ -0,0 +1,350 @@
+'\"
+'\" Copyright (c) 1996-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 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
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewObj\fR()
+.sp
+Tcl_Obj *
+\fBTcl_DuplicateObj\fR(\fIobjPtr\fR)
+.sp
+\fBTcl_IncrRefCount\fR(\fIobjPtr\fR)
+.sp
+\fBTcl_DecrRefCount\fR(\fIobjPtr\fR)
+.sp
+int
+\fBTcl_IsShared\fR(\fIobjPtr\fR)
+.sp
+\fBTcl_InvalidateStringRep\fR(\fIobjPtr\fR)
+.SH ARGUMENTS
+.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.
+.BE
+.SH INTRODUCTION
+.PP
+This man page presents an overview of Tcl objects and how they are used.
+It also describes generic procedures for managing Tcl objects.
+These procedures are used to create and copy objects,
+and increment and decrement the count of references (pointers) to objects.
+The procedures are used in conjunction with ones
+that operate on specific types of objects such as
+\fBTcl_GetIntFromObj\fR and \fBTcl_ListObjAppendElement\fR.
+The individual procedures are described along with the data structures
+they manipulate.
+.PP
+Tcl's \fIdual-ported\fR objects provide a general-purpose mechanism
+for storing and exchanging Tcl values.
+They largely replace the use of strings in Tcl.
+For example, they are used to store variable values,
+command arguments, command results, and scripts.
+Tcl objects behave like strings but also hold an internal representation
+that can be manipulated more efficiently.
+For example, a Tcl list is now represented as an object
+that holds the list's string representation
+as well as an array of pointers to the objects for each list element.
+Dual-ported objects avoid most runtime type conversions.
+They also improve the speed of many operations
+since an appropriate representation is immediately available.
+The compiler itself uses Tcl objects to
+cache the instruction bytecodes resulting from compiling scripts.
+.PP
+The two representations are a cache of each other and are computed lazily.
+That is, each representation is only computed when necessary,
+it is computed from the other representation,
+and, once computed, it is saved.
+In addition, a change in one representation invalidates the other one.
+As an example, a Tcl program doing integer calculations can
+operate directly on a variable's internal machine integer
+representation without having to constantly convert
+between integers and strings.
+Only when it needs a string representing the variable's value,
+say to print it,
+will the program regenerate the string representation from the integer.
+Although objects contain an internal representation,
+their semantics are defined in terms of strings:
+an up-to-date string can always be obtained,
+and any change to the object will be reflected in that string
+when the object's string representation is fetched.
+Because of this representation invalidation and regeneration,
+it is dangerous for extension writers to access
+\fBTcl_Obj\fR fields directly.
+It is better to access Tcl_Obj information using
+procedures like \fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR.
+.PP
+Objects are allocated on the heap
+and are referenced using a pointer to their \fBTcl_Obj\fR structure.
+Objects are shared as much as possible.
+This significantly reduces storage requirements
+because some objects such as long lists are very large.
+Also, most Tcl values are only read and never modified.
+This is especially true for procedure arguments,
+which can be shared between the caller and the called procedure.
+Assignment and argument binding is done by
+simply assigning a pointer to the value.
+Reference counting is used to determine when it is safe to
+reclaim an object's storage.
+.PP
+Tcl objects are typed.
+An object's internal representation is controlled by its type.
+Several types are predefined in the Tcl core
+including integer, double, list, and bytecode.
+Extension writers can extend the set of types
+by defining their own \fBTcl_ObjType\fR structs.
+.SH "THE TCL_OBJ STRUCTURE"
+.PP
+Each Tcl object is represented by a \fBTcl_Obj\fR structure
+which is defined as follows.
+.PP
+.CS
+typedef struct Tcl_Obj {
+ int \fIrefCount\fR;
+ char *\fIbytes\fR;
+ int \fIlength\fR;
+ const 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;
+} \fBTcl_Obj\fR;
+.CE
+.PP
+The \fIbytes\fR and the \fIlength\fR members together hold
+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.)
+\fIbytes\fR points to the first byte of the string representation.
+The \fIlength\fR member gives the number of bytes.
+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.
+C programs use \fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR to get
+an object's string representation.
+If \fIbytes\fR is NULL,
+the string representation is invalid.
+.PP
+An object's type manages its internal representation.
+The member \fItypePtr\fR points to the Tcl_ObjType structure
+that describes the type.
+If \fItypePtr\fR is NULL,
+the internal representation is invalid.
+.PP
+The \fIinternalRep\fR union member holds
+an object's internal representation.
+This is either a (long) integer, a double-precision floating-point number,
+a pointer to a value containing additional information
+needed by the object's type to represent the object, a Tcl_WideInt
+integer, two arbitrary pointers, or a pair made up of an unsigned long
+integer and a pointer.
+.PP
+The \fIrefCount\fR member is used to tell when it is safe to free
+an object's storage.
+It holds the count of active references to the object.
+Maintaining the correct reference count is a key responsibility
+of extension writers.
+Reference counting is discussed below
+in the section \fBSTORAGE MANAGEMENT OF OBJECTS\fR.
+.PP
+Although extension writers can directly access
+the members of a Tcl_Obj structure,
+it is much better to use the appropriate procedures and macros.
+For example, extension writers should never
+read or update \fIrefCount\fR directly;
+they should use macros such as
+\fBTcl_IncrRefCount\fR and \fBTcl_IsShared\fR instead.
+.PP
+A key property of Tcl objects is that they hold two representations.
+An object typically starts out containing only a string representation:
+it is untyped and has a NULL \fItypePtr\fR.
+An object containing an empty string or a copy of a specified string
+is created using \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR respectively.
+An object's string value is gotten with
+\fBTcl_GetStringFromObj\fR or \fBTcl_GetString\fR
+and changed with \fBTcl_SetStringObj\fR.
+If the object is later passed to a procedure like \fBTcl_GetIntFromObj\fR
+that requires a specific internal representation,
+the procedure will create one and set the object's \fItypePtr\fR.
+The internal representation is computed from the string representation.
+An object's two representations are duals of each other:
+changes made to one are reflected in the other.
+For example, \fBTcl_ListObjReplace\fR will modify an object's
+internal representation and the next call to \fBTcl_GetStringFromObj\fR
+or \fBTcl_GetString\fR will reflect that change.
+.PP
+Representations are recomputed lazily for efficiency.
+A change to one representation made by a procedure
+such as \fBTcl_ListObjReplace\fR is not reflected immediately
+in the other representation.
+Instead, the other representation is marked invalid
+so that it is only regenerated if it is needed later.
+Most C programmers never have to be concerned with how this is done
+and simply use procedures such as \fBTcl_GetBooleanFromObj\fR or
+\fBTcl_ListObjIndex\fR.
+Programmers that implement their own object types
+must check for invalid representations
+and mark representations invalid when necessary.
+The procedure \fBTcl_InvalidateStringRep\fR is used
+to mark an object's string representation invalid and to
+free any storage associated with the old string representation.
+.PP
+Objects usually remain one type over their life,
+but occasionally an object must be converted from one type to another.
+For example, a C program might build up a string in an object
+with repeated calls to \fBTcl_AppendToObj\fR,
+and then call \fBTcl_ListObjIndex\fR to extract a list element from
+the object.
+The same object holding the same string value
+can have several different internal representations
+at different times.
+Extension writers can also force an object to be converted from one type
+to another using the \fBTcl_ConvertToType\fR procedure.
+Only programmers that create new object types need to be concerned
+about how this is done.
+A procedure defined as part of the object type's implementation
+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,
+consider the following sequence of commands:
+.PP
+.CS
+\fBset x 123\fR
+.CE
+.PP
+This assigns to \fIx\fR an untyped object whose
+\fIbytes\fR member points to \fB123\fR and \fIlength\fR member contains 3.
+The object's \fItypePtr\fR member is NULL.
+.PP
+.CS
+\fBputs "x is $x"\fR
+.CE
+.PP
+\fIx\fR's string representation is valid (since \fIbytes\fR is non-NULL)
+and is fetched for the command.
+.PP
+.CS
+\fBincr x\fR
+.CE
+.PP
+The \fBincr\fR command first gets an integer from \fIx\fR's object
+by calling \fBTcl_GetIntFromObj\fR.
+This procedure checks whether the object is already an integer object.
+Since it is not, it converts the object
+by setting the object's \fIinternalRep.longValue\fR member
+to the integer \fB123\fR
+and setting the object's \fItypePtr\fR
+to point to the integer Tcl_ObjType structure.
+Both representations are now valid.
+\fBincr\fR increments the object's integer internal representation
+then invalidates its string representation
+(by calling \fBTcl_InvalidateStringRep\fR)
+since the string representation
+no longer corresponds to the internal representation.
+.PP
+.CS
+\fBputs "x is now $x"\fR
+.CE
+.PP
+The string representation of \fIx\fR's object is needed
+and is recomputed.
+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
+to reduce storage requirements.
+Reference counting is used to determine when an object is
+no longer needed and can safely be freed.
+An object just created by \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR
+has \fIrefCount\fR 0.
+The macro \fBTcl_IncrRefCount\fR increments the reference count
+when a new reference to the object is created.
+The macro \fBTcl_DecrRefCount\fR decrements the count
+when a reference is no longer needed and,
+if the object's reference count drops to zero, frees its storage.
+An object shared by different code or data structures has
+\fIrefCount\fR greater than 1.
+Incrementing an object's reference count ensures that
+it will not be freed too early or have its value change accidentally.
+.PP
+As an example, the bytecode interpreter shares argument objects
+between calling and called Tcl procedures to avoid having to copy objects.
+It assigns the call's argument objects to the procedure's
+formal parameter variables.
+In doing so, it calls \fBTcl_IncrRefCount\fR to increment
+the reference count of each argument since there is now a new
+reference to it from the formal parameter.
+When the called procedure returns,
+the interpreter calls \fBTcl_DecrRefCount\fR to decrement
+each argument's reference count.
+When an object's reference count drops less than or equal to zero,
+\fBTcl_DecrRefCount\fR reclaims its storage.
+Most command procedures do not have to be concerned about
+reference counting since they use an object's value immediately
+and do not retain a pointer to the object after they return.
+However, if they do retain a pointer to an object in a data structure,
+they must be careful to increment its reference count
+since the retained pointer is a new reference.
+.PP
+Command procedures that directly modify objects
+such as those for \fBlappend\fR and \fBlinsert\fR must be careful to
+copy a shared object before changing it.
+They must first check whether the object is shared
+by calling \fBTcl_IsShared\fR.
+If the object is shared they must copy the object
+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
+.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 (\fBTcl_IsShared\fR(listPtr)) {
+ listPtr = \fBTcl_DuplicateObj\fR(listPtr);
+}
+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 accidentally changing values in other data structures.
+.SH "SEE ALSO"
+Tcl_ConvertToType(3), Tcl_GetIntFromObj(3), Tcl_ListObjAppendElement(3), Tcl_ListObjIndex(3), Tcl_ListObjReplace(3), Tcl_RegisterObjType(3)
+.SH KEYWORDS
+internal representation, object, object creation, object type, reference counting, string representation, type conversion
diff --git a/pkgs/msgcat/doc/ObjectType.3 b/pkgs/msgcat/doc/ObjectType.3
new file mode 100644
index 0000000..0c11187
--- /dev/null
+++ b/pkgs/msgcat/doc/ObjectType.3
@@ -0,0 +1,255 @@
+'\"
+'\" Copyright (c) 1996-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 Tcl_ObjType 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_RegisterObjType, Tcl_GetObjType, Tcl_AppendAllObjTypes, Tcl_ConvertToType \- manipulate Tcl object types
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_RegisterObjType\fR(\fItypePtr\fR)
+.sp
+const Tcl_ObjType *
+\fBTcl_GetObjType\fR(\fItypeName\fR)
+.sp
+int
+\fBTcl_AppendAllObjTypes\fR(\fIinterp, objPtr\fR)
+.sp
+int
+\fBTcl_ConvertToType\fR(\fIinterp, objPtr, typePtr\fR)
+.SH ARGUMENTS
+.AS "const char" *typeName
+.AP "const 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
+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.
+.AP Tcl_Obj *objPtr in
+For \fBTcl_AppendAllObjTypes\fR, this points to the object onto which
+it appends the name of each object type as a list element.
+For \fBTcl_ConvertToType\fR, this points to an object that
+must have been the result of a previous call to \fBTcl_NewObj\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+The procedures in this man page manage Tcl object types.
+They are used to register new object types, look up types,
+and force conversions from one type to another.
+.PP
+\fBTcl_RegisterObjType\fR registers a new Tcl object type
+in the table of all object types that \fBTcl_GetObjType\fR
+can look up by name. There are other object types supported by Tcl
+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
+that implement the type.
+If the type table already contains a type
+with the same name as in \fItypePtr\fR,
+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 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 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;
+in that case \fBTCL_ERROR\fR is returned.
+.PP
+\fBTcl_ConvertToType\fR converts an object from one type to another
+if possible.
+It creates a new internal representation for \fIobjPtr\fR
+appropriate for the target type \fItypePtr\fR
+and sets its \fItypePtr\fR member as determined by calling the
+\fItypePtr->setFromAnyProc\fR routine.
+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
+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 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 {
+ const char *\fIname\fR;
+ Tcl_FreeInternalRepProc *\fIfreeIntRepProc\fR;
+ Tcl_DupInternalRepProc *\fIdupIntRepProc\fR;
+ Tcl_UpdateStringProc *\fIupdateStringProc\fR;
+ Tcl_SetFromAnyProc *\fIsetFromAnyProc\fR;
+} \fBTcl_ObjType\fR;
+.CE
+.SS "THE NAME FIELD"
+.PP
+The \fIname\fR member describes the name of the type, e.g. \fBint\fR.
+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 \fBTcl_SetFromAnyProc\fR(
+ Tcl_Interp *\fIinterp\fR,
+ Tcl_Obj *\fIobjPtr\fR);
+.CE
+.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
+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.
+.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 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 \fBTcl_ConvertToType\fR 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 \fBTcl_UpdateStringProc\fR(
+ 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,
+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.
+.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 \fBTcl_DupInternalRepProc\fR(
+ 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 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 \fBTcl_FreeInternalRepProc\fR(
+ 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.
+.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(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3)
+.SH KEYWORDS
+internal representation, object, object type, string representation, type conversion
diff --git a/pkgs/msgcat/doc/OpenFileChnl.3 b/pkgs/msgcat/doc/OpenFileChnl.3
new file mode 100644
index 0000000..2368492
--- /dev/null
+++ b/pkgs/msgcat/doc/OpenFileChnl.3
@@ -0,0 +1,648 @@
+'\"
+'\" Copyright (c) 1996-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 Tcl_OpenFileChannel 3 8.3 Tcl "Tcl Library Procedures"
+.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_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
+.sp
+Tcl_Channel
+\fBTcl_OpenFileChannel\fR(\fIinterp, fileName, mode, permissions\fR)
+.sp
+Tcl_Channel
+\fBTcl_OpenCommandChannel\fR(\fIinterp, argc, argv, flags\fR)
+.sp
+Tcl_Channel
+\fBTcl_MakeFileChannel\fR(\fIhandle, readOrWrite\fR)
+.sp
+Tcl_Channel
+\fBTcl_GetChannel\fR(\fIinterp, channelName, modePtr\fR)
+.sp
+int
+\fBTcl_GetChannelNames\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_GetChannelNamesEx\fR(\fIinterp, pattern\fR)
+.sp
+void
+\fBTcl_RegisterChannel\fR(\fIinterp, channel\fR)
+.sp
+int
+\fBTcl_UnregisterChannel\fR(\fIinterp, channel\fR)
+.sp
+int
+\fBTcl_DetachChannel\fR(\fIinterp, channel\fR)
+.sp
+int
+\fBTcl_IsStandardChannel\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_Close\fR(\fIinterp, channel\fR)
+.sp
+int
+\fBTcl_ReadChars\fR(\fIchannel, readObjPtr, charsToRead, appendFlag\fR)
+.sp
+int
+\fBTcl_Read\fR(\fIchannel, readBuf, bytesToRead\fR)
+.sp
+int
+\fBTcl_GetsObj\fR(\fIchannel, lineObjPtr\fR)
+.sp
+int
+\fBTcl_Gets\fR(\fIchannel, lineRead\fR)
+.sp
+int
+\fBTcl_Ungets\fR(\fIchannel, input, inputLen, addAtEnd\fR)
+.sp
+int
+\fBTcl_WriteObj\fR(\fIchannel, writeObjPtr\fR)
+.sp
+int
+\fBTcl_WriteChars\fR(\fIchannel, charBuf, bytesToWrite\fR)
+.sp
+int
+\fBTcl_Write\fR(\fIchannel, byteBuf, bytesToWrite\fR)
+.sp
+int
+\fBTcl_ReadRaw\fR(\fIchannel, readBuf, bytesToRead\fR)
+.sp
+int
+\fBTcl_WriteRaw\fR(\fIchannel, byteBuf, bytesToWrite\fR)
+.sp
+int
+\fBTcl_Eof\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_Flush\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_InputBlocked\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_InputBuffered\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_OutputBuffered\fR(\fIchannel\fR)
+.sp
+Tcl_WideInt
+\fBTcl_Seek\fR(\fIchannel, offset, seekMode\fR)
+.sp
+Tcl_WideInt
+\fBTcl_Tell\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_TruncateChannel\fR(\fIchannel, length\fR)
+.sp
+int
+\fBTcl_GetChannelOption\fR(\fIinterp, channel, optionName, optionValue\fR)
+.sp
+int
+\fBTcl_SetChannelOption\fR(\fIinterp, channel, optionName, newValue\fR)
+.sp
+.SH ARGUMENTS
+.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
+The name of a local or network file.
+.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
+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
+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
+Specifies the disposition of the stdio handles in pipeline: OR-ed
+combination of \fBTCL_STDIN\fR, \fBTCL_STDOUT\fR, \fBTCL_STDERR\fR, and
+\fBTCL_ENFORCE_MODE\fR. If \fBTCL_STDIN\fR is set, stdin for the first child
+in the pipe is the pipe channel, otherwise it is the same as the standard
+input of the invoking process; likewise for \fBTCL_STDOUT\fR and
+\fBTCL_STDERR\fR. If \fBTCL_ENFORCE_MODE\fR is not set, then the pipe can
+redirect stdio handles to override the stdio handles for which
+\fBTCL_STDIN\fR, \fBTCL_STDOUT\fR and \fBTCL_STDERR\fR have been set. If it
+is set, then such redirections cause an error.
+.AP ClientData handle in
+Operating system specific handle for I/O to a file. For Unix this is a
+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
+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.
+.AP "const char" *pattern in
+The pattern to match on, passed to Tcl_StringMatch, or NULL.
+.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.
+.AP Tcl_Obj *readObjPtr in/out
+A pointer to a Tcl Object in which to store the characters read from the
+channel.
+.AP int charsToRead in
+The number of characters to read from the channel. If the channel's encoding
+is \fBbinary\fR, this is equivalent to the number of bytes to read from the
+channel.
+.AP int appendFlag in
+If non-zero, data read from the channel will be appended to the object.
+Otherwise, the data will replace the existing contents of the object.
+.AP char *readBuf out
+A buffer in which to store the bytes read from the channel.
+.AP int bytesToRead in
+The number of bytes to read from the channel. The buffer \fIreadBuf\fR must
+be large enough to hold this many bytes.
+.AP Tcl_Obj *lineObjPtr in/out
+A pointer to a Tcl object in which to store the line read from the
+channel. The line read will be appended to the current value of the
+object.
+.AP Tcl_DString *lineRead in/out
+A pointer to a Tcl dynamic string in which to store the line read from the
+channel. Must have been initialized by the caller. The line read will be
+appended to any data already in the dynamic string.
+.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.
+.AP Tcl_Obj *writeObjPtr in
+A pointer to a Tcl Object whose contents will be output to the channel.
+.AP "const char" *charBuf in
+A buffer containing the characters to output to the channel.
+.AP "const char" *byteBuf in
+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.
+.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
+given by \fIseekMode\fR. May be either positive or negative.
+.AP int seekMode in
+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 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
+New value for the option given by \fIoptionName\fR.
+.BE
+.SH DESCRIPTION
+.PP
+The Tcl channel mechanism provides a device-independent and
+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
+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
+channels.
+.PP
+The procedures described in this manual entry comprise the C APIs of the
+generic layer of the channel architecture. For a description of the channel
+driver architecture and how to implement channel drivers for new types of
+channels, see the manual entry for \fBTcl_CreateChannel\fR.
+.SH TCL_OPENFILECHANNEL
+.PP
+\fBTcl_OpenFileChannel\fR opens a file specified by \fIfileName\fR and
+returns a channel handle that can be used to perform input and output on
+the file. This API is modeled after the \fBfopen\fR procedure of
+the Unix standard I/O library.
+The syntax and meaning of all arguments is similar to those
+given in the Tcl \fBopen\fR command when opening a file.
+If an error occurs while opening the channel, \fBTcl_OpenFileChannel\fR
+returns NULL and records a POSIX error code that can be
+retrieved with \fBTcl_GetErrno\fR.
+In addition, if \fIinterp\fR is non-NULL, \fBTcl_OpenFileChannel\fR
+leaves an error message in \fIinterp\fR's result after any error.
+As of Tcl 8.4, the object-based API \fBTcl_FSOpenFileChannel\fR should
+be used in preference to \fBTcl_OpenFileChannel\fR wherever possible.
+.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\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.SH TCL_OPENCOMMANDCHANNEL
+.PP
+\fBTcl_OpenCommandChannel\fR provides a C-level interface to the
+functions of the \fBexec\fR and \fBopen\fR commands.
+It creates a sequence of subprocesses specified
+by the \fIargv\fR and \fIargc\fR arguments and returns a channel that can
+be used to communicate with these subprocesses.
+The \fIflags\fR argument indicates what sort of communication will
+exist with the command pipeline.
+.PP
+If the \fBTCL_STDIN\fR flag is set then the standard input for the
+first subprocess will be tied to the channel: writing to the channel
+will provide input to the subprocess. If \fBTCL_STDIN\fR is not set,
+then standard input for the first subprocess will be the same as this
+application's standard input. If \fBTCL_STDOUT\fR is set then
+standard output from the last subprocess can be read from the channel;
+otherwise it goes to this application's standard output. If
+\fBTCL_STDERR\fR is set, standard error output for all subprocesses is
+returned to the channel and results in an error when the channel is
+closed; otherwise it goes to this application's standard error. If
+\fBTCL_ENFORCE_MODE\fR is not set, then \fIargc\fR and \fIargv\fR can
+redirect the stdio handles to override \fBTCL_STDIN\fR,
+\fBTCL_STDOUT\fR, and \fBTCL_STDERR\fR; if it is set, then it is an
+error for argc and argv to override stdio channels for which
+\fBTCL_STDIN\fR, \fBTCL_STDOUT\fR, and \fBTCL_STDERR\fR have been set.
+.PP
+If an error occurs while opening the channel, \fBTcl_OpenCommandChannel\fR
+returns NULL and records a POSIX error code that can be retrieved with
+\fBTcl_GetErrno\fR.
+In addition, \fBTcl_OpenCommandChannel\fR leaves an error message in
+the interpreter's result if \fIinterp\fR is not NULL.
+.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\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.SH TCL_MAKEFILECHANNEL
+.PP
+\fBTcl_MakeFileChannel\fR makes a \fBTcl_Channel\fR from an existing,
+platform-specific, file handle.
+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\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.SH TCL_GETCHANNEL
+.PP
+\fBTcl_GetChannel\fR returns a channel given the \fIchannelName\fR used to
+create it with \fBTcl_CreateChannel\fR and a pointer to a Tcl interpreter in
+\fIinterp\fR. If a channel by that name is not registered in that interpreter,
+the procedure returns NULL. If the \fImodePtr\fR argument is not NULL, it
+points at an integer variable that will receive an OR-ed combination of
+\fBTCL_READABLE\fR and \fBTCL_WRITABLE\fR describing whether the channel is
+open for reading and writing.
+.PP
+\fBTcl_GetChannelNames\fR and \fBTcl_GetChannelNamesEx\fR write the
+names of the registered channels to the interpreter's result as a
+list object. \fBTcl_GetChannelNamesEx\fR will filter these names
+according to the \fIpattern\fR. If \fIpattern\fR is NULL, then it
+will not do any filtering. The return value is \fBTCL_OK\fR if no
+errors occurred writing to the result, otherwise it is \fBTCL_ERROR\fR,
+and the error message is left in the interpreter's result.
+.SH TCL_REGISTERCHANNEL
+.PP
+\fBTcl_RegisterChannel\fR adds a channel to the set of channels accessible
+in \fIinterp\fR. After this call, Tcl programs executing in that
+interpreter can refer to the channel in input or output operations using
+the name given in the call to \fBTcl_CreateChannel\fR. After this call,
+the channel becomes the property of the interpreter, and the caller should
+not call \fBTcl_Close\fR for the channel; the channel will be closed
+automatically when it is unregistered from the interpreter.
+.PP
+Code executing outside of any Tcl interpreter can call
+\fBTcl_RegisterChannel\fR with \fIinterp\fR as NULL, to indicate that it
+wishes to hold a reference to this channel. Subsequently, the channel can
+be registered in a Tcl interpreter and it will only be closed when the
+matching number of calls to \fBTcl_UnregisterChannel\fR have been made.
+This allows code executing outside of any interpreter to safely hold a
+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. See \fBTcl_StandardChannels\fR for a general treatise about
+standard channels and the behavior of the Tcl library with regard to
+them.
+.SH TCL_UNREGISTERCHANNEL
+.PP
+\fBTcl_UnregisterChannel\fR removes a channel from the set of channels
+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.
+If this operation removed the last registration of the channel in any
+interpreter, the channel is also closed and destroyed.
+.PP
+Code not associated with a Tcl interpreter can call
+\fBTcl_UnregisterChannel\fR with \fIinterp\fR as NULL, to indicate to Tcl
+that it no longer holds a reference to that channel. If this is the last
+reference to the channel, it will now be closed. \fBTcl_UnregisterChannel\fR
+is very similar to \fBTcl_DetachChannel\fR except that it will also
+close the channel if no further references to it exist.
+.SH TCL_DETACHCHANNEL
+.PP
+\fBTcl_DetachChannel\fR removes a channel from the set of channels
+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 (\fBstdout\fR, \fBstderr\fR, \fBstdin\fR), and will return
+\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
+that it no longer holds a reference to that channel. If this is the last
+reference to the channel, unlike \fBTcl_UnregisterChannel\fR,
+it will not be closed.
+.SH TCL_ISSTANDARDCHANNEL
+.PP
+\fBTcl_IsStandardChannel\fR tests whether a channel is one of the
+three standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR.
+If so, it returns 1, otherwise 0.
+.PP
+No attempt is made to check whether the given channel or the standard
+channels are initialized or otherwise valid.
+.SH TCL_CLOSE
+.PP
+\fBTcl_Close\fR destroys the channel \fIchannel\fR, which must denote a
+currently open channel. The channel should not be registered in any
+interpreter when \fBTcl_Close\fR is called. Buffered output is flushed to
+the channel's output device prior to destroying the channel, and any
+buffered input is discarded. If this is a blocking channel, the call does
+not return until all buffered data is successfully sent to the channel's
+output device. If this is a nonblocking channel and there is buffered
+output that cannot be written without blocking, the call returns
+immediately; output is flushed in the background and the channel will be
+closed once all of the buffered data has been output. In this case errors
+during flushing are not reported.
+.PP
+If the channel was closed successfully, \fBTcl_Close\fR returns \fBTCL_OK\fR.
+If an error occurs, \fBTcl_Close\fR returns \fBTCL_ERROR\fR and records a
+POSIX error code that can be retrieved with \fBTcl_GetErrno\fR.
+If the channel is being closed synchronously and an error occurs during
+closing of the channel and \fIinterp\fR is not NULL, an error message is
+left in the interpreter's result.
+.PP
+Note: it is not safe to call \fBTcl_Close\fR on a channel that has been
+registered using \fBTcl_RegisterChannel\fR; see the documentation for
+\fBTcl_RegisterChannel\fR, above, for details. If the channel has ever
+been given as the \fBchan\fR argument in a call to
+\fBTcl_RegisterChannel\fR, you should instead use
+\fBTcl_UnregisterChannel\fR, which will internally call \fBTcl_Close\fR
+when all calls to \fBTcl_RegisterChannel\fR have been matched by
+corresponding calls to \fBTcl_UnregisterChannel\fR.
+.SH "TCL_READCHARS AND TCL_READ"
+.PP
+\fBTcl_ReadChars\fR consumes bytes from \fIchannel\fR, converting the bytes
+to UTF-8 based on the channel's encoding and storing the produced data in
+\fIreadObjPtr\fR's string representation. The return value of
+\fBTcl_ReadChars\fR is the number of characters, up to \fIcharsToRead\fR,
+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
+all characters currently available (non-blocking) or everything until
+eof (blocking mode).
+.PP
+The return value may be smaller than the value to read, indicating that less
+data than requested was available. This is called a \fIshort read\fR. In
+blocking mode, this can only happen on an end-of-file. In nonblocking mode,
+a short read can also occur if there is not enough input currently
+available: \fBTcl_ReadChars\fR returns a short count rather than waiting
+for more data.
+.PP
+If the channel is in blocking mode, a return value of zero indicates an
+end-of-file condition. If the channel is in nonblocking mode, a return
+value of zero indicates either that no input is currently available or an
+end-of-file condition. Use \fBTcl_Eof\fR and \fBTcl_InputBlocked\fR to tell
+which of these conditions actually occurred.
+.PP
+\fBTcl_ReadChars\fR translates the various end-of-line representations into
+the canonical \fB\en\fR internal representation according to the current
+end-of-line recognition mode. End-of-line recognition and the various
+platform-specific modes are described in the manual entry for the Tcl
+\fBfconfigure\fR command.
+.PP
+As a performance optimization, when reading from a channel with the encoding
+\fBbinary\fR, the bytes are not converted to UTF-8 as they are read.
+Instead, they are stored in \fIreadObjPtr\fR's internal representation as a
+byte-array object. The string representation of this object will only be
+constructed if it is needed (e.g., because of a call to
+\fBTcl_GetStringFromObj\fR). In this way, byte-oriented data can be read
+from a channel, manipulated by calling \fBTcl_GetByteArrayFromObj\fR and
+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 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
+\fIreadBuf\fR, performing end-of-line translations on the way. The return value
+of \fBTcl_Read\fR is the number of bytes, up to \fIbytesToRead\fR, written in
+\fIreadBuf\fR. The buffer produced by \fBTcl_Read\fR is not null-terminated.
+Its contents are valid from the zeroth position up to and excluding the
+position indicated by the return value.
+.PP
+\fBTcl_ReadRaw\fR is the same as \fBTcl_Read\fR but does not
+compensate for stacking. While \fBTcl_Read\fR (and the other functions
+in the API) always get their data from the topmost channel in the
+stack the supplied channel is part of, \fBTcl_ReadRaw\fR does
+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 channel below into the transformation.
+.SH "TCL_GETSOBJ AND TCL_GETS"
+.PP
+\fBTcl_GetsObj\fR consumes bytes from \fIchannel\fR, converting the bytes to
+UTF-8 based on the channel's encoding, until a full line of input has been
+seen. If the channel's encoding is \fBbinary\fR, each byte read from the
+channel is treated as an individual Unicode character. All of the
+characters of the line except for the terminating end-of-line character(s)
+are appended to \fIlineObjPtr\fR's string representation. The end-of-line
+character(s) are read and discarded.
+.PP
+If a line was successfully read, the return value is greater than or equal
+to zero and indicates the number of bytes stored in \fIlineObjPtr\fR. If an
+error occurs, \fBTcl_GetsObj\fR returns \-1 and records a POSIX error code
+that can be retrieved with \fBTcl_GetErrno\fR. \fBTcl_GetsObj\fR also
+returns \-1 if the end of the file is reached; the \fBTcl_Eof\fR procedure
+can be used to distinguish an error from an end-of-file condition.
+.PP
+If the channel is in nonblocking mode, the return value can also be \-1 if
+no data was available or the data that was available did not contain an
+end-of-line character. When \-1 is returned, the \fBTcl_InputBlocked\fR
+procedure may be invoked to determine if the channel is blocked because
+of input unavailability.
+.PP
+\fBTcl_Gets\fR is the same as \fBTcl_GetsObj\fR except the resulting
+characters are appended to the dynamic string given by
+\fIlineRead\fR rather than a Tcl object.
+.SH "TCL_UNGETS"
+.PP
+\fBTcl_Ungets\fR is used to add data to the input queue of a channel,
+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
+.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.
+.SH "TCL_WRITECHARS, TCL_WRITEOBJ, AND TCL_WRITE"
+.PP
+\fBTcl_WriteChars\fR accepts \fIbytesToWrite\fR bytes of character data at
+\fIcharBuf\fR. The UTF-8 characters in the buffer are converted to the
+channel's encoding and queued for output to \fIchannel\fR. If
+\fIbytesToWrite\fR is negative, \fBTcl_WriteChars\fR expects \fIcharBuf\fR
+to be null-terminated and it outputs everything up to the null.
+.PP
+Data queued for output may not appear on the output device immediately, due
+to internal buffering. If the data should appear immediately, call
+\fBTcl_Flush\fR after the call to \fBTcl_WriteChars\fR, or set the
+\fB\-buffering\fR option on the channel to \fBnone\fR. If you wish the data
+to appear as soon as a complete line is accepted for output, set the
+\fB\-buffering\fR option on the channel to \fBline\fR mode.
+.PP
+The return value of \fBTcl_WriteChars\fR is a count of how many bytes were
+accepted for output to the channel. This is either greater than zero to
+indicate success or \-1 to indicate that an error occurred. If an error
+occurs, \fBTcl_WriteChars\fR records a POSIX error code that may be
+retrieved with \fBTcl_GetErrno\fR.
+.PP
+Newline characters in the output data are translated to platform-specific
+end-of-line sequences according to the \fB\-translation\fR option for the
+channel. This is done even if the channel has no encoding.
+.PP
+\fBTcl_WriteObj\fR is similar to \fBTcl_WriteChars\fR except it
+accepts a Tcl object whose contents will be output to the channel. The
+UTF-8 characters in \fIwriteObjPtr\fR's string representation are converted
+to the channel's encoding and queued for output to \fIchannel\fR.
+As a performance optimization, when writing to a channel with the encoding
+\fBbinary\fR, UTF-8 characters are not converted as they are written.
+Instead, the bytes in \fIwriteObjPtr\fR's internal representation as a
+byte-array object are written to the channel. The byte-array representation
+of the object will be constructed if it is needed. In this way,
+byte-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 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
+\fIbyteBuf\fR and queues them for output to \fIchannel\fR. If
+\fIbytesToWrite\fR is negative, \fBTcl_Write\fR expects \fIbyteBuf\fR to be
+null-terminated and it outputs everything up to the null.
+.PP
+\fBTcl_WriteRaw\fR is the same as \fBTcl_Write\fR but does not
+compensate for stacking. While \fBTcl_Write\fR (and the other
+functions in the API) always feed their input to the topmost channel
+in the stack the supplied channel is part of, \fBTcl_WriteRaw\fR does
+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.
+.SH TCL_FLUSH
+.PP
+\fBTcl_Flush\fR causes all of the buffered output data for \fIchannel\fR
+to be written to its underlying file or device as soon as possible.
+If the channel is in blocking mode, the call does not return until
+all the buffered data has been sent to the channel or some error occurred.
+The call returns immediately if the channel is nonblocking; it starts
+a background flush that will write the buffered data to the channel
+eventually, as fast as the channel is able to absorb it.
+.PP
+The return value is normally \fBTCL_OK\fR.
+If an error occurs, \fBTcl_Flush\fR returns \fBTCL_ERROR\fR and
+records a POSIX error code that can be retrieved with \fBTcl_GetErrno\fR.
+.SH TCL_SEEK
+.PP
+\fBTcl_Seek\fR moves the access point in \fIchannel\fR where subsequent
+data will be read or written. Buffered output is flushed to the channel and
+buffered input is discarded, prior to the seek operation.
+.PP
+\fBTcl_Seek\fR normally returns the new access point.
+If an error occurs, \fBTcl_Seek\fR returns \-1 and records a POSIX error
+code that can be retrieved with \fBTcl_GetErrno\fR.
+After an error, the access point may or may not have been moved.
+.SH TCL_TELL
+.PP
+\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
+\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.
+.SH TCL_GETCHANNELOPTION
+.PP
+\fBTcl_GetChannelOption\fR retrieves, in \fIoptionValue\fR, the value of one of
+the options currently in effect for a channel, or a list of all options and
+their values. The \fIchannel\fR argument identifies the channel for which
+to query an option or retrieve all options and their values.
+If \fIoptionName\fR is not NULL, it is the name of the
+option to query; the option's value is copied to the Tcl dynamic string
+denoted by \fIoptionValue\fR. If
+\fIoptionName\fR is NULL, the function stores an alternating list of option
+names and their values in \fIoptionValue\fR, using a series of calls to
+\fBTcl_DStringAppendElement\fR. The various preexisting options and
+their possible values are described in the manual entry for the Tcl
+\fBfconfigure\fR command. Other options can be added by each channel type.
+These channel type specific options are described in the manual entry for
+the Tcl command that creates a channel of that type; for example, the
+additional options for TCP based channels are described in the manual entry
+for the Tcl \fBsocket\fR command.
+The procedure normally returns \fBTCL_OK\fR. If an error occurs, it returns
+\fBTCL_ERROR\fR and calls \fBTcl_SetErrno\fR to store an appropriate POSIX
+error code.
+.SH TCL_SETCHANNELOPTION
+.PP
+\fBTcl_SetChannelOption\fR sets a new value \fInewValue\fR
+for an option \fIoptionName\fR on \fIchannel\fR.
+The procedure normally returns \fBTCL_OK\fR. If an error occurs,
+it returns \fBTCL_ERROR\fR; in addition, if \fIinterp\fR is non-NULL,
+\fBTcl_SetChannelOption\fR leaves an error message in the interpreter's result.
+.SH TCL_EOF
+.PP
+\fBTcl_Eof\fR returns a nonzero value if \fIchannel\fR encountered
+an end of file during the last input operation.
+.SH TCL_INPUTBLOCKED
+.PP
+\fBTcl_InputBlocked\fR returns a nonzero value if \fIchannel\fR is in
+nonblocking mode and the last input operation returned less data than
+requested because there was insufficient data available.
+The call always returns zero if the channel is in blocking mode.
+.SH TCL_INPUTBUFFERED
+.PP
+\fBTcl_InputBuffered\fR returns the number of bytes of input currently
+buffered in the internal buffers for a channel. If the channel is not open
+for reading, this function always returns zero.
+.SH TCL_OUTPUTBUFFERED
+.PP
+\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.
+.SH "PLATFORM ISSUES"
+.PP
+The handles returned from \fBTcl_GetChannelHandle\fR depend on the
+platform and the channel type. On Unix platforms, the handle is
+always a Unix file descriptor as returned from the \fBopen\fR system
+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.
+.SH "SEE ALSO"
+DString(3), fconfigure(n), filename(n), fopen(3), Tcl_CreateChannel(3)
+.SH KEYWORDS
+access point, blocking, buffered I/O, channel, channel driver, end of file,
+flush, input, nonblocking, output, read, seek, write
diff --git a/pkgs/msgcat/doc/OpenTcp.3 b/pkgs/msgcat/doc/OpenTcp.3
new file mode 100644
index 0000000..78ac70b
--- /dev/null
+++ b/pkgs/msgcat/doc/OpenTcp.3
@@ -0,0 +1,169 @@
+'\"
+'\" Copyright (c) 1996-7 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_OpenTcpClient 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_OpenTcpClient, Tcl_MakeTcpClientChannel, Tcl_OpenTcpServer \- procedures to open channels using TCP sockets
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h> \fR
+.sp
+Tcl_Channel
+\fBTcl_OpenTcpClient\fR(\fIinterp, port, host, myaddr, myport, async\fR)
+.sp
+Tcl_Channel
+\fBTcl_MakeTcpClientChannel\fR(\fIsock\fR)
+.sp
+Tcl_Channel
+\fBTcl_OpenTcpServer\fR(\fIinterp, port, myaddr, proc, clientData\fR)
+.sp
+.SH ARGUMENTS
+.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
+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
+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.
+.AP int async in
+If nonzero, the client socket is connected asynchronously to the server.
+.AP ClientData sock in
+Platform-specific handle for client TCP socket.
+.AP Tcl_TcpAcceptProc *proc in
+Pointer to a procedure to invoke each time a new connection is
+accepted via the socket.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+These functions are convenience procedures for creating
+channels that communicate over TCP sockets.
+The operations on a channel
+are described in the manual entry for \fBTcl_OpenFileChannel\fR.
+.SS TCL_OPENTCPCLIENT
+.PP
+\fBTcl_OpenTcpClient\fR opens a client TCP socket connected to a \fIport\fR
+on a specific \fIhost\fR, and returns a channel that can be used to
+communicate with the server. The host to connect to can be specified either
+as a domain name style name (e.g. \fBwww.sunlabs.com\fR), or as a string
+containing the alphanumeric representation of its four-byte address (e.g.
+\fB127.0.0.1\fR). Use the string \fBlocalhost\fR to connect to a TCP socket on
+the host on which the function is invoked.
+.PP
+The \fImyaddr\fR and \fImyport\fR arguments allow a client to specify an
+address for the local end of the connection. If \fImyaddr\fR is NULL, then
+an interface is chosen automatically by the operating system.
+If \fImyport\fR is 0, then a port number is chosen at random by
+the operating system.
+.PP
+If \fIasync\fR is zero, the call to \fBTcl_OpenTcpClient\fR returns only
+after the client socket has either successfully connected to the server, or
+the attempted connection has failed.
+If \fIasync\fR is nonzero the socket is connected asynchronously and the
+returned channel may not yet be connected to the server when the call to
+\fBTcl_OpenTcpClient\fR returns. If the channel is in blocking mode and an
+input or output operation is done on the channel before the connection is
+completed or fails, that operation will wait until the connection either
+completes successfully or fails. If the channel is in nonblocking mode, the
+input or output operation will return immediately and a subsequent call to
+\fBTcl_InputBlocked\fR on the channel will return nonzero.
+.PP
+The returned channel is opened for reading and writing.
+If an error occurs in opening the socket, \fBTcl_OpenTcpClient\fR returns
+NULL and records a POSIX error code that can be retrieved
+with \fBTcl_GetErrno\fR.
+In addition, if \fIinterp\fR is non-NULL, an error message
+is left in the interpreter's result.
+.PP
+The newly created channel is not registered in the supplied interpreter; to
+register it, use \fBTcl_RegisterChannel\fR.
+If one of the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.SS TCL_MAKETCPCLIENTCHANNEL
+.PP
+\fBTcl_MakeTcpClientChannel\fR creates a \fBTcl_Channel\fR around an
+existing, platform specific, handle for a client TCP socket.
+.PP
+The newly created channel is not registered in the supplied interpreter; to
+register it, use \fBTcl_RegisterChannel\fR.
+If one of the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.SS TCL_OPENTCPSERVER
+.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\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:
+.PP
+.CS
+typedef void \fBTcl_TcpAcceptProc\fR(
+ 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\fR
+will contain the client's port number.
+The new channel
+is opened for both input and output.
+If \fIproc\fR raises an error, the connection is closed automatically.
+\fIProc\fR has no return value, but if it wishes to reject the
+connection it can close \fIchannel\fR.
+.PP
+\fBTcl_OpenTcpServer\fR normally returns a pointer to a channel
+representing the server socket.
+If an error occurs, \fBTcl_OpenTcpServer\fR returns NULL and
+records a POSIX error code that can be retrieved with \fBTcl_GetErrno\fR.
+In addition, if the interpreter is non-NULL, an error message
+is left in the interpreter's result.
+.PP
+The channel returned by \fBTcl_OpenTcpServer\fR cannot be used for
+either input or output.
+It is simply a handle for the socket used to accept connections.
+The caller can close the channel to shut down the server and disallow
+further connections from new clients.
+.PP
+TCP server channels operate correctly only in applications that dispatch
+events through \fBTcl_DoOneEvent\fR or through Tcl commands such as
+\fBvwait\fR; otherwise Tcl will never notice that a connection request from
+a remote client is pending.
+.PP
+The newly created channel is not registered in the supplied interpreter; to
+register it, use \fBTcl_RegisterChannel\fR.
+If one of the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.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.
+.SH "SEE ALSO"
+Tcl_OpenFileChannel(3), Tcl_RegisterChannel(3), vwait(n)
+.SH KEYWORDS
+channel, client, server, socket, TCP
diff --git a/pkgs/msgcat/doc/Panic.3 b/pkgs/msgcat/doc/Panic.3
new file mode 100644
index 0000000..48aed2b
--- /dev/null
+++ b/pkgs/msgcat/doc/Panic.3
@@ -0,0 +1,89 @@
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_Panic 3 8.4 Tcl "Tcl Library Procedures"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_Panic, Tcl_PanicVA, Tcl_SetPanicProc \- report fatal error and abort
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_Panic\fR(\fIformat\fR, \fIarg\fR, \fIarg\fR, \fI...\fR)
+.sp
+void
+\fBTcl_PanicVA\fR(\fIformat\fR, \fIargList\fR)
+.sp
+void
+\fBTcl_SetPanicProc\fR(\fIpanicProc\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_PanicProc *panicProc
+.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 \fBva_start\fR,
+and cleared using \fBva_end\fR.
+.AP Tcl_PanicProc *panicProc in
+Procedure to report fatal error message and abort.
+.BE
+.SH DESCRIPTION
+.PP
+When the Tcl library detects that its internal data structures are in an
+inconsistent state, or that its C procedures have been called in a
+manner inconsistent with their documentation, it calls \fBTcl_Panic\fR
+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 built-in Tcl command
+\fBformat\fR.
+.PP
+In a freshly loaded Tcl library, \fBTcl_Panic\fR prints the formatted
+error message to the standard error file of the process, and then
+calls \fBabort\fR to terminate the process. \fBTcl_Panic\fR does not
+return. On Windows, when a debugger is running, the formatted error
+message is sent to the debugger in stead. If the windows executable
+does not have a stderr channel (e.g. \fBwish.exe\fR), then a
+system dialog box is used to display the panic message.
+.PP
+\fBTcl_SetPanicProc\fR may be used to modify the behavior of
+\fBTcl_Panic\fR. The \fIpanicProc\fR argument should match the
+type \fBTcl_PanicProc\fR:
+.PP
+.CS
+typedef void \fBTcl_PanicProc\fR(
+ const char *\fBformat\fR,
+ \fBarg\fR, \fBarg\fR,...);
+.CE
+.PP
+After \fBTcl_SetPanicProc\fR returns, any future calls to
+\fBTcl_Panic\fR will call \fIpanicProc\fR, passing along the
+\fIformat\fR and \fIarg\fR arguments. \fIpanicProc\fR should avoid
+making calls into the Tcl library, or into other libraries that may
+call the Tcl library, since the original call to \fBTcl_Panic\fR
+indicates the Tcl library is not in a state of reliable operation.
+.PP
+The typical use of \fBTcl_SetPanicProc\fR arranges for the error message
+to be displayed or reported in a manner more suitable for the
+application or the platform.
+.PP
+Although the primary callers of \fBTcl_Panic\fR are the procedures of
+the Tcl library, \fBTcl_Panic\fR is a public function and may be called
+by any extension or application that wishes to abort the process and
+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.
+.SH "SEE ALSO"
+abort(3), printf(3), exec(n), format(n)
+.SH KEYWORDS
+abort, fatal, error
diff --git a/pkgs/msgcat/doc/ParseArgs.3 b/pkgs/msgcat/doc/ParseArgs.3
new file mode 100644
index 0000000..dd33830
--- /dev/null
+++ b/pkgs/msgcat/doc/ParseArgs.3
@@ -0,0 +1,198 @@
+'\"
+'\" Copyright (c) 2008 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_ParseArgsObjv 3 8.6 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_ParseArgsObjv \- parse arguments according to a tabular description
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_ParseArgsObjv\fR(\fIinterp, argTable, objcPtr, objv, remObjv\fR)
+.SH ARGUMENTS
+.AS "const Tcl_ArgvInfo" ***remObjv in/out
+.AP Tcl_Interp *interp out
+Where to store error messages.
+.AP "const Tcl_ArgvInfo" *argTable in
+Pointer to array of option descriptors.
+.AP int *objcPtr in/out
+A pointer to variable holding number of arguments in \fIobjv\fR. Will be
+modified to hold number of arguments left in the unprocessed argument list
+stored in \fIremObjv\fR.
+.AP "Tcl_Obj *const" *objv in
+The array of arguments to be parsed.
+.AP Tcl_Obj ***remObjv out
+Pointer to a variable that will hold the array of unprocessed arguments.
+Should be NULL if no return of unprocessed arguments is required. If
+\fIobjcPtr\fR is updated to a non-zero value, the array returned through this
+must be deallocated using \fBckfree\fR.
+.BE
+.SH DESCRIPTION
+.PP
+The \fBTcl_ParseArgsObjv\fR function provides a system for parsing argument
+lists of the form
+.QW "\fB\-someName \fIsomeValue\fR ..." .
+Such argument lists are commonly found both in the arguments to a program and
+in the arguments to an individual Tcl command. This parser assumes that the
+order of the arguments does not matter, other than in so far as later copies
+of a duplicated option overriding earlier ones.
+.PP
+The argument array is described by the \fIobjcPtr\fR and \fIobjv\fR
+parameters, and an array of unprocessed arguments is returned through the
+\fIobjcPtr\fR and \fIremObjv\fR parameters; if no return of unprocessed
+arguments is desired, the \fIremObjv\fR parameter should be NULL. If any
+problems happen, including if the
+.QW "generate help"
+option is selected, an error message is left in the interpreter result and
+TCL_ERROR is returned. Otherwise, the interpreter result is left unchanged and
+TCL_OK is returned.
+.PP
+The collection of arguments to be parsed is described by the \fIargTable\fR
+parameter. This points to a table of descriptor structures that is terminated
+by an entry with the \fItype\fR field set to TCL_ARGV_END. As convenience, the
+following prototypical entries are provided:
+.TP
+\fBTCL_ARGV_AUTO_HELP\fR
+.
+Enables the argument processor to provide help when passed the argument
+.QW \fB\-help\fR .
+.TP
+\fBTCL_ARGV_AUTO_REST\fR
+.
+Instructs the argument processor that arguments after
+.QW \fB\-\-\fR
+are to be unprocessed.
+.TP
+\fBTCL_ARGV_TABLE_END\fR
+.
+Marks the end of the table of argument descriptors.
+.SS "ARGUMENT DESCRIPTOR ENTRIES"
+.PP
+Each entry of the argument descriptor table must be a structure of type
+\fBTcl_ArgvInfo\fR. The structure is defined as this:
+.PP
+.CS
+typedef struct {
+ int \fItype\fR;
+ const char *\fIkeyStr\fR;
+ void *\fIsrcPtr\fR;
+ void *\fIdstPtr\fR;
+ const char *\fIhelpStr\fR;
+ ClientData \fIclientData\fR;
+} \fBTcl_ArgvInfo\fR;
+.CE
+.PP
+The \fIkeyStr\fR field contains the name of the option; by convention, this
+will normally begin with a
+.QW \fB\-\fR
+character. The \fItype\fR, \fIsrcPtr\fR, \fIdstPtr\fR and \fIclientData\fR
+fields describe the interpretation of the value of the argument, as described
+below. The \fIhelpStr\fR field gives some text that is used to provide help to
+users when they request it.
+.PP
+As noted above, the \fItype\fR field is used to describe the interpretation of
+the argument's value. The following values are acceptable values for
+\fItype\fR:
+.TP
+\fBTCL_ARGV_CONSTANT\fR
+.
+The argument does not take any following value argument. If this argument is
+present, the int pointed to by the \fIsrcPtr\fR field is copied to the
+\fIdstPtr\fR field. The \fIclientData\fR field is ignored.
+.TP
+\fBTCL_ARGV_END\fR
+.
+This value marks the end of all option descriptors in the table. All other
+fields are ignored.
+.TP
+\fBTCL_ARGV_FLOAT\fR
+.
+This argument takes a following floating point value argument. The value (once
+parsed by \fBTcl_GetDoubleFromObj\fR) will be stored as a double-precision
+value in the variable pointed to by the \fIdstPtr\fR field. The \fIsrcPtr\fR
+and \fIclientData\fR fields are ignored.
+.TP
+\fBTCL_ARGV_FUNC\fR
+.
+This argument optionally takes a following value argument; it is up to the
+handler callback function passed in \fIsrcPtr\fR to decide. That function will
+have the following signature:
+.RS
+.PP
+.CS
+typedef int (\fBTcl_ArgvFuncProc\fR)(
+ ClientData \fIclientData\fR,
+ Tcl_Obj *\fIobjPtr\fR,
+ void *\fIdstPtr\fR);
+.CE
+.PP
+The result is a boolean value indicating whether to consume the following
+argument. The \fIclientData\fR is the value from the table entry, the
+\fIobjPtr\fR is the object that represents the following argument or NULL if
+there are no following arguments at all, and the \fIdstPtr\fR argument to the
+\fBTcl_ArgvFuncProc\fR is the location to write the parsed value to.
+.RE
+.TP
+\fBTCL_ARGV_GENFUNC\fR
+.
+This argument takes zero or more following arguments; the handler callback
+function passed in \fIsrcPtr\fR returns how many (or a negative number to
+signal an error, in which case it should also set the interpreter result). The
+function will have the following signature:
+.RS
+.PP
+.CS
+typedef int (\fBTcl_ArgvGenFuncProc\fR)(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ int \fIobjc\fR,
+ Tcl_Obj *const *\fIobjv\fR,
+ void *\fIdstPtr\fR);
+.CE
+.PP
+The \fIclientData\fR is the value from the table entry, the \fIinterp\fR is
+where to store any error messages, the \fIkeyStr\fR is the name of the
+argument, \fIobjc\fR and \fIobjv\fR describe an array of all the remaining
+arguments, and \fIdstPtr\fR argument to the \fBTcl_ArgvGenFuncProc\fR is the
+location to write the parsed value (or values) to.
+.RE
+.TP
+\fBTCL_ARGV_HELP\fR
+.
+This special argument does not take any following value argument, but instead
+causes \fBTcl_ParseArgsObjv\fR to generate an error message describing the
+arguments supported. All other fields except the \fIhelpStr\fR field are
+ignored.
+.TP
+\fBTCL_ARGV_INT\fR
+.
+This argument takes a following integer value argument. The value (once parsed
+by \fBTcl_GetIntFromObj\fR) will be stored as an int in the variable pointed
+to by the \fIdstPtr\fR field. The \fIsrcPtr\fR field is ignored.
+.TP
+\fBTCL_ARGV_REST\fR
+.
+This special argument does not take any following value argument, but instead
+marks all following arguments to be left unprocessed. The \fIsrcPtr\fR,
+\fIdstPtr\fR and \fIclientData\fR fields are ignored.
+.TP
+\fBTCL_ARGV_STRING\fR
+.
+This argument takes a following string value argument. A pointer to the string
+will be stored at \fIdstPtr\fR; the string inside will have a lifetime linked
+to the lifetime of the string representation of the argument object that it
+came from, and so should be copied if it needs to be retained. The
+\fIsrcPtr\fR and \fIclientData\fR fields are ignored.
+.SH "SEE ALSO"
+Tcl_GetIndexFromObj(3), Tcl_Main(3), Tcl_CreateObjCommand(3)
+.SH KEYWORDS
+argument, parse
+'\" Local Variables:
+'\" fill-column: 78
+'\" End:
diff --git a/pkgs/msgcat/doc/ParseCmd.3 b/pkgs/msgcat/doc/ParseCmd.3
new file mode 100644
index 0000000..f3b3aeb
--- /dev/null
+++ b/pkgs/msgcat/doc/ParseCmd.3
@@ -0,0 +1,467 @@
+'\"
+'\" 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 Tcl_ParseCommand 3 8.3 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_ParseCommand, Tcl_ParseExpr, Tcl_ParseBraces, Tcl_ParseQuotedString, Tcl_ParseVarName, Tcl_ParseVar, Tcl_FreeParse, Tcl_EvalTokens, Tcl_EvalTokensStandard \- parse Tcl scripts and expressions
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_ParseCommand\fR(\fIinterp, start, numBytes, nested, parsePtr\fR)
+.sp
+int
+\fBTcl_ParseExpr\fR(\fIinterp, start, numBytes, parsePtr\fR)
+.sp
+int
+\fBTcl_ParseBraces\fR(\fIinterp, start, numBytes, parsePtr, append, termPtr\fR)
+.sp
+int
+\fBTcl_ParseQuotedString\fR(\fIinterp, start, numBytes, parsePtr, append, termPtr\fR)
+.sp
+int
+\fBTcl_ParseVarName\fR(\fIinterp, start, numBytes, parsePtr, append\fR)
+.sp
+const char *
+\fBTcl_ParseVar\fR(\fIinterp, start, termPtr\fR)
+.sp
+\fBTcl_FreeParse\fR(\fIusedParsePtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_EvalTokens\fR(\fIinterp, tokenPtr, numTokens\fR)
+.sp
+int
+\fBTcl_EvalTokensStandard\fR(\fIinterp, tokenPtr, numTokens\fR)
+.SH ARGUMENTS
+.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;
+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" *start in
+Pointer to first character in string to parse.
+.AP int numBytes in
+Number of bytes in string to parse, not including any terminating null
+character. If less than 0 then the script consists of all characters
+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,
+close brackets have no special meaning.
+.AP int append in
+Non-zero means that \fI*parsePtr\fR already contains valid tokens; the new
+tokens should be appended to those already present. Zero means that
+\fI*parsePtr\fR is uninitialized; any information in it is ignored.
+This argument is normally 0.
+.AP Tcl_Parse *parsePtr out
+Points to structure to fill in with information about the parsed
+command, expression, variable name, etc.
+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
+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
+just after the terminating character (the close-brace, the last
+character of the variable name, or the close-quote (respectively))
+if the parse was successful.
+.AP Tcl_Parse *usedParsePtr in
+Points to structure that was filled in by a previous call to
+\fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseVarName\fR, etc.
+.BE
+.SH DESCRIPTION
+.PP
+These procedures parse Tcl commands or portions of Tcl commands such as
+expressions or references to variables.
+Each procedure takes a pointer to a script (or portion thereof)
+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\fR's result
+(if \fIinterp\fR is not NULL),
+and leave nothing in \fIparsePtr\fR.
+.PP
+\fBTcl_ParseCommand\fR is a procedure that parses Tcl
+scripts. Given a pointer to a script, it
+parses the first command from the script. If the command was parsed
+successfully, \fBTcl_ParseCommand\fR returns \fBTCL_OK\fR and fills in the
+structure pointed to by \fIparsePtr\fR with information about the
+structure of the command (see below for details).
+If an error occurred in parsing the command then
+\fBTCL_ERROR\fR is returned, an error message is left in \fIinterp\fR's
+result, and no information is left at \fI*parsePtr\fR.
+.PP
+\fBTcl_ParseExpr\fR parses Tcl expressions.
+Given a pointer to a script containing an expression,
+\fBTcl_ParseExpr\fR parses the expression.
+If the expression was parsed successfully,
+\fBTcl_ParseExpr\fR returns \fBTCL_OK\fR and fills in the
+structure pointed to by \fIparsePtr\fR with information about the
+structure of the expression (see below for details).
+If an error occurred in parsing the command then
+\fBTCL_ERROR\fR is returned, an error message is left in \fIinterp\fR's
+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 \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
+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
+in the location given by \fI*termPtr\fR.
+If an error occurs while parsing the string
+then \fBTCL_ERROR\fR is returned,
+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 \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\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,
+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
+\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 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 \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
+\fIinterp\fR's result.
+.PP
+The information left at \fI*parsePtr\fR
+by \fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseBraces\fR,
+\fBTcl_ParseQuotedString\fR, and \fBTcl_ParseVarName\fR
+may include dynamically allocated memory.
+If these five parsing procedures return \fBTCL_OK\fR
+then the caller must invoke \fBTcl_FreeParse\fR to release
+the storage at \fI*parsePtr\fR.
+These procedures ignore any existing information in
+\fI*parsePtr\fR (unless \fIappend\fR is non-zero),
+so if repeated calls are being made to any of them
+then \fBTcl_FreeParse\fR must be invoked once after each call.
+.PP
+\fBTcl_EvalTokensStandard\fR evaluates a sequence of parse tokens from
+a Tcl_Parse structure. The tokens typically consist
+of all the tokens in a word or all the tokens that make up the index for
+a reference to an array variable. \fBTcl_EvalTokensStandard\fR performs the
+substitutions requested by the tokens and concatenates the
+resulting values.
+The return value from \fBTcl_EvalTokensStandard\fR is a Tcl completion
+code with one of the values \fBTCL_OK\fR, \fBTCL_ERROR\fR,
+\fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR, or possibly
+some other integer value originating in an extension.
+In addition, a result value or error message is left in \fIinterp\fR's
+result; it can be retrieved using \fBTcl_GetObjResult\fR.
+.PP
+\fBTcl_EvalTokens\fR differs from \fBTcl_EvalTokensStandard\fR only in
+the return convention used: it returns the result in a new Tcl_Obj.
+The reference count of the object returned as result has been
+incremented, so the caller must
+invoke \fBTcl_DecrRefCount\fR when it is finished with the object.
+If an error or other exception occurs while evaluating the tokens
+(such as a reference to a non-existent variable) then the return value
+is NULL and an error message is left in \fIinterp\fR's result. The use
+of \fBTcl_EvalTokens\fR is deprecated.
+.SH "TCL_PARSE STRUCTURE"
+.PP
+\fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseBraces\fR,
+\fBTcl_ParseQuotedString\fR, and \fBTcl_ParseVarName\fR
+return parse information in two data structures, Tcl_Parse and Tcl_Token:
+.PP
+.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;
+ ...
+} \fBTcl_Parse\fR;
+
+typedef struct Tcl_Token {
+ int \fItype\fR;
+ const char *\fIstart\fR;
+ int \fIsize\fR;
+ int \fInumComponents\fR;
+} \fBTcl_Token\fR;
+.CE
+.PP
+The first five fields of a Tcl_Parse structure
+are filled in only by \fBTcl_ParseCommand\fR.
+These fields are not used by the other parsing procedures.
+.PP
+\fBTcl_ParseCommand\fR fills in a Tcl_Parse structure
+with information that describes one Tcl command and any comments that
+precede the command.
+If there are comments,
+the \fIcommentStart\fR field points to the \fB#\fR character that begins
+the first comment and \fIcommentSize\fR indicates the number of bytes
+in all of the comments preceding the command, including the newline
+character that terminates the last comment.
+If the command is not preceded by any comments, \fIcommentSize\fR is 0.
+\fBTcl_ParseCommand\fR also sets the \fIcommandStart\fR field
+to point to the first character of the first
+word in the command (skipping any comments and leading space) and
+\fIcommandSize\fR gives the total number of bytes in the command,
+including the character pointed to by \fIcommandStart\fR up to and
+including the newline, close bracket, or semicolon character that
+terminates the command. The \fInumWords\fR field gives the
+total number of words in the command.
+.PP
+All parsing procedures set the remaining fields,
+\fItokenPtr\fR and \fInumTokens\fR.
+The \fItokenPtr\fR field points to the first in an array of Tcl_Token
+structures that describe the components of the entity being parsed.
+The \fInumTokens\fR field gives the total number of tokens
+present in the array.
+Each token contains four fields.
+The \fItype\fR field selects one of several token types
+that are described below. The \fIstart\fR field
+points to the first character in the token and the \fIsize\fR field
+gives the total number of characters in the token. Some token types,
+such as \fBTCL_TOKEN_WORD\fR and \fBTCL_TOKEN_VARIABLE\fR, consist of
+several component tokens, which immediately follow the parent token;
+the \fInumComponents\fR field describes how many of these there are.
+The \fItype\fR field has one of the following values:
+.TP 20
+\fBTCL_TOKEN_WORD\fR
+.
+This token ordinarily describes one word of a command
+but it may also describe a quoted or braced string in an expression.
+The token describes a component of the script that is
+the result of concatenating together a sequence of subcomponents,
+each described by a separate subtoken.
+The token starts with the first non-blank
+character of the component (which may be a double-quote or open brace)
+and includes all characters in the component up to but not including the
+space, semicolon, close bracket, close quote, or close brace that
+terminates the component. The \fInumComponents\fR field counts the total
+number of sub-tokens that make up the word, including sub-tokens
+of \fBTCL_TOKEN_VARIABLE\fR and \fBTCL_TOKEN_BS\fR tokens.
+.TP
+\fBTCL_TOKEN_SIMPLE_WORD\fR
+.
+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
+.
+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.
+.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.
+.TP
+\fBTCL_TOKEN_BS\fR
+.
+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 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
+see its tokens).
+.TP
+\fBTCL_TOKEN_VARIABLE\fR
+.
+The token describes a variable substitution, including the
+\fB$\fR, variable name, and array index (if there is one) up through the
+close parenthesis that terminates the index. This token is followed
+by one or more additional tokens that describe the variable name and
+array index. If \fInumComponents\fR is 1 then the variable is a
+scalar and the next token is a \fBTCL_TOKEN_TEXT\fR token that gives the
+variable name. If \fInumComponents\fR is greater than 1 then the
+variable is an array: the first sub-token is a \fBTCL_TOKEN_TEXT\fR
+token giving the array name and the remaining sub-tokens are
+\fBTCL_TOKEN_TEXT\fR, \fBTCL_TOKEN_BS\fR, \fBTCL_TOKEN_COMMAND\fR, and
+\fBTCL_TOKEN_VARIABLE\fR tokens that must be concatenated to produce the
+array index. The \fInumComponents\fR field includes nested sub-tokens
+that are part of \fBTCL_TOKEN_VARIABLE\fR tokens in the array index.
+.TP
+\fBTCL_TOKEN_SUB_EXPR\fR
+.
+The token describes one subexpression of an expression
+(or an entire expression).
+A subexpression may consist of a value
+such as an integer literal, variable substitution,
+or parenthesized subexpression;
+it may also consist of an operator and its operands.
+The token starts with the first non-blank character of the subexpression
+up to but not including the space, brace, close-paren, or bracket
+that terminates the subexpression.
+This token is followed by one or more additional tokens
+that describe the subexpression.
+If the first sub-token after the \fBTCL_TOKEN_SUB_EXPR\fR token
+is a \fBTCL_TOKEN_OPERATOR\fR token,
+the subexpression consists of an operator and its token operands.
+If the operator has no operands, the subexpression consists of
+just the \fBTCL_TOKEN_OPERATOR\fR token.
+Each operand is described by a \fBTCL_TOKEN_SUB_EXPR\fR token.
+Otherwise, the subexpression is a value described by
+one of the token types \fBTCL_TOKEN_WORD\fR, \fBTCL_TOKEN_TEXT\fR,
+\fBTCL_TOKEN_BS\fR, \fBTCL_TOKEN_COMMAND\fR,
+\fBTCL_TOKEN_VARIABLE\fR, and \fBTCL_TOKEN_SUB_EXPR\fR.
+The \fInumComponents\fR field
+counts the total number of sub-tokens that make up the subexpression;
+this includes the sub-tokens for any nested \fBTCL_TOKEN_SUB_EXPR\fR tokens.
+.TP
+\fBTCL_TOKEN_OPERATOR\fR
+.
+The token describes one operator of an expression
+such as \fB&&\fR or \fBhypot\fR.
+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
+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
+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,
+the \fBTCL_TOKEN_OPERATOR\fR token will give its name and
+the following \fBTCL_TOKEN_SUB_EXPR\fR tokens will describe
+its operands;
+if there are no operands (as with \fBrand\fR),
+no \fBTCL_TOKEN_SUB_EXPR\fR tokens follow.
+There is one trinary operator, \fB?\fR,
+that appears in if-then-else subexpressions
+such as \fIx\fB?\fIy\fB:\fIz\fR;
+in this case, the \fB?\fR \fBTCL_TOKEN_OPERATOR\fR token
+is followed by three \fBTCL_TOKEN_SUB_EXPR\fR tokens for the operands
+\fIx\fR, \fIy\fR, and \fIz\fR.
+The \fInumComponents\fR field for a \fBTCL_TOKEN_OPERATOR\fR token
+is always 0.
+.PP
+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 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
+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.
+.PP
+After \fBTcl_ParseExpr\fR returns, the first token pointed to by
+the \fItokenPtr\fR field of the
+Tcl_Parse structure always has type \fBTCL_TOKEN_SUB_EXPR\fR.
+It is followed by the sub-tokens that must be evaluated
+to produce the value of the expression.
+Only the token information in the Tcl_Parse structure
+is modified: the \fIcommentStart\fR, \fIcommentSize\fR,
+\fIcommandStart\fR, and \fIcommandSize\fR fields are not modified
+by \fBTcl_ParseExpr\fR.
+.PP
+After \fBTcl_ParseBraces\fR returns,
+the array of tokens pointed to by the \fItokenPtr\fR field of the
+Tcl_Parse structure will contain a single \fBTCL_TOKEN_TEXT\fR token
+if the braced string does not contain any backslash-newlines.
+If the string does contain backslash-newlines,
+the array of tokens will contain one or more
+\fBTCL_TOKEN_TEXT\fR or \fBTCL_TOKEN_BS\fR sub-tokens
+that must be concatenated to produce the value of the string.
+If the braced string was just \fB{}\fR
+(that is, the string was empty),
+the single \fBTCL_TOKEN_TEXT\fR token will have a \fIsize\fR field
+containing zero;
+this ensures that at least one token appears
+to describe the braced string.
+Only the token information in the Tcl_Parse structure
+is modified: the \fIcommentStart\fR, \fIcommentSize\fR,
+\fIcommandStart\fR, and \fIcommandSize\fR fields are not modified
+by \fBTcl_ParseBraces\fR.
+.PP
+After \fBTcl_ParseQuotedString\fR returns,
+the array of tokens pointed to by the \fItokenPtr\fR field of the
+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 \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
+is modified: the \fIcommentStart\fR, \fIcommentSize\fR,
+\fIcommandStart\fR, and \fIcommandSize\fR fields are not modified.
+.PP
+After \fBTcl_ParseVarName\fR returns, the first token pointed to by
+the \fItokenPtr\fR field of the
+Tcl_Parse structure always has type \fBTCL_TOKEN_VARIABLE\fR. It
+is followed by the sub-tokens that make up the variable name as
+described above. The total length of the variable name is
+contained in the \fIsize\fR field of the first token.
+As in \fBTcl_ParseExpr\fR,
+only the token information in the Tcl_Parse structure
+is modified by \fBTcl_ParseVarName\fR:
+the \fIcommentStart\fR, \fIcommentSize\fR,
+\fIcommandStart\fR, and \fIcommandSize\fR fields are not modified.
+.PP
+All of the character pointers in the
+Tcl_Parse and Tcl_Token structures refer
+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
+There are additional fields in the Tcl_Parse structure after the
+\fInumTokens\fR field, but these are for the private use of
+\fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseBraces\fR,
+\fBTcl_ParseQuotedString\fR, and \fBTcl_ParseVarName\fR; they should not be
+referenced by code outside of these procedures.
+.SH KEYWORDS
+backslash substitution, braces, command, expression, parse, token, variable substitution
diff --git a/pkgs/msgcat/doc/PkgRequire.3 b/pkgs/msgcat/doc/PkgRequire.3
new file mode 100644
index 0000000..d54d7af
--- /dev/null
+++ b/pkgs/msgcat/doc/PkgRequire.3
@@ -0,0 +1,97 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_PkgRequire 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+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 *
+\fBTcl_PkgRequire\fR(\fIinterp, name, version, exact\fR)
+.sp
+const char *
+\fBTcl_PkgRequireEx\fR(\fIinterp, name, version, exact, clientDataPtr\fR)
+.sp
+int
+\fBTcl_PkgRequireProc\fR(\fIinterp, name, objc, objv, clientDataPtr\fR)
+.sp
+const char *
+\fBTcl_PkgPresent\fR(\fIinterp, name, version, exact\fR)
+.sp
+const char *
+\fBTcl_PkgPresentEx\fR(\fIinterp, name, version, exact, clientDataPtr\fR)
+.sp
+int
+\fBTcl_PkgProvide\fR(\fIinterp, name, version\fR)
+.sp
+int
+\fBTcl_PkgProvideEx\fR(\fIinterp, name, version, clientData\fR)
+.SH ARGUMENTS
+.AS void *clientDataPtr out
+.AP Tcl_Interp *interp in
+Interpreter where package is needed or available.
+.AP "const char" *name in
+Name of package.
+.AP "const char" *version in
+A version string consisting of one or more decimal numbers
+separated by dots.
+.AP int exact in
+Non-zero means that only the particular version specified by
+\fIversion\fR is acceptable.
+Zero means that newer versions than \fIversion\fR are also
+acceptable as long as they have the same major version number
+as \fIversion\fR.
+.AP "const void" *clientData in
+Arbitrary value to be associated with the package.
+.AP void *clientDataPtr out
+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. The storage can be any pointer
+type with the same size as a void pointer.
+.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
+version management facilities.
+.PP
+\fBTcl_PkgRequire\fR is equivalent to the \fBpackage require\fR
+command, \fBTcl_PkgPresent\fR is equivalent to the \fBpackage present\fR
+command, and \fBTcl_PkgProvide\fR is equivalent to the
+\fBpackage provide\fR command.
+.PP
+See the documentation for the Tcl commands for details on what these
+procedures do.
+.PP
+If \fBTcl_PkgPresent\fR or \fBTcl_PkgRequire\fR complete successfully
+they return a pointer to the version string for the version of the package
+that is provided in the interpreter (which may be different than
+\fIversion\fR); if an error occurs they return NULL and leave an error
+message in the interpreter's result.
+.PP
+\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
+.SH "SEE ALSO"
+package(n), Tcl_StaticPackage(3)
diff --git a/pkgs/msgcat/doc/Preserve.3 b/pkgs/msgcat/doc/Preserve.3
new file mode 100644
index 0000000..905a31d
--- /dev/null
+++ b/pkgs/msgcat/doc/Preserve.3
@@ -0,0 +1,110 @@
+'\"
+'\" Copyright (c) 1990 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 Tcl_Preserve 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Preserve, Tcl_Release, Tcl_EventuallyFree \- avoid freeing storage while it is being used
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_Preserve\fR(\fIclientData\fR)
+.sp
+\fBTcl_Release\fR(\fIclientData\fR)
+.sp
+\fBTcl_EventuallyFree\fR(\fIclientData, freeProc\fR)
+.SH ARGUMENTS
+.AS Tcl_FreeProc clientData
+.AP ClientData clientData in
+Token describing structure to be freed or reallocated. Usually a pointer
+to memory for structure.
+.AP Tcl_FreeProc *freeProc in
+Procedure to invoke to free \fIclientData\fR.
+.BE
+.SH DESCRIPTION
+.PP
+These three procedures help implement a simple reference count mechanism
+for managing storage. They are designed to solve a problem
+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 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
+event-handling C procedure in the button to be invoked, which in
+turn causes the button's associated Tcl command to be executed,
+which in turn causes the button to be deleted, which in turn causes
+the button's widget record to be de-allocated.
+Unfortunately, when the Tcl command returns, the button's
+event-handling procedure will need to reference the
+button's widget record.
+Because of this, the widget record must not be freed as part of the
+deletion, but must be retained until the event-handling procedure has
+finished with it.
+In other situations where the widget is deleted, it may be possible
+to free the widget record immediately.
+.PP
+\fBTcl_Preserve\fR and \fBTcl_Release\fR
+implement short-term reference counts for their \fIclientData\fR
+argument.
+The \fIclientData\fR argument identifies an object and usually
+consists of the address of a structure.
+The reference counts guarantee that an object will not be freed
+until each call to \fBTcl_Preserve\fR for the object has been
+matched by calls to \fBTcl_Release\fR.
+There may be any number of unmatched \fBTcl_Preserve\fR calls
+in effect at once.
+.PP
+\fBTcl_EventuallyFree\fR is invoked to free up its \fIclientData\fR
+argument.
+It checks to see if there are unmatched \fBTcl_Preserve\fR calls
+for the object.
+If not, then \fBTcl_EventuallyFree\fR calls \fIfreeProc\fR immediately.
+Otherwise \fBTcl_EventuallyFree\fR records the fact that \fIclientData\fR
+needs eventually to be freed.
+When all calls to \fBTcl_Preserve\fR have been matched with
+calls to \fBTcl_Release\fR then \fIfreeProc\fR will be called by
+\fBTcl_Release\fR to do the cleanup.
+.PP
+All the work of freeing the object is carried out by \fIfreeProc\fR.
+\fIFreeProc\fR must have arguments and result that match the
+type \fBTcl_FreeProc\fR:
+.PP
+.CS
+typedef void \fBTcl_FreeProc\fR(
+ char *\fIblockPtr\fR);
+.CE
+.PP
+The \fIblockPtr\fR argument to \fIfreeProc\fR will be the
+same as the \fIclientData\fR argument to \fBTcl_EventuallyFree\fR.
+The type of \fIblockPtr\fR (\fBchar *\fR) is different than the type of the
+\fIclientData\fR argument to \fBTcl_EventuallyFree\fR for historical
+reasons, but the value is the same.
+.PP
+When the \fIclientData\fR argument to \fBTcl_EventuallyFree\fR
+refers to storage allocated and returned by a prior call to
+\fBTcl_Alloc\fR, \fBckalloc\fR, or another function of the Tcl library,
+then the \fIfreeProc\fR argument should be given the special value of
+\fBTCL_DYNAMIC\fR.
+.PP
+This mechanism can be used to solve the problem described above
+by placing \fBTcl_Preserve\fR and \fBTcl_Release\fR calls around
+actions that may cause undesired storage re-allocation. The
+mechanism is intended only for short-term use (i.e. while procedures
+are pending on the stack); it will not work efficiently as a
+mechanism for long-term reference counts.
+The implementation does not depend in any way on the internal
+structure of the objects being freed; it keeps the reference
+counts in a separate structure.
+.SH "SEE ALSO"
+Tcl_Interp, Tcl_Alloc
+.SH KEYWORDS
+free, reference count, storage
diff --git a/pkgs/msgcat/doc/PrintDbl.3 b/pkgs/msgcat/doc/PrintDbl.3
new file mode 100644
index 0000000..99b0113
--- /dev/null
+++ b/pkgs/msgcat/doc/PrintDbl.3
@@ -0,0 +1,51 @@
+'\"
+'\" Copyright (c) 1989-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.
+'\"
+.so man.macros
+.TH Tcl_PrintDouble 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_PrintDouble \- Convert floating value to string
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_PrintDouble\fR(\fIinterp, value, dst\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp out
+.AP Tcl_Interp *interp in
+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.
+.AP double value in
+Floating-point value to be converted.
+.AP char *dst out
+Where to store the string representing \fIvalue\fR. Must have at
+least \fBTCL_DOUBLE_SPACE\fR characters of storage.
+.BE
+.SH DESCRIPTION
+.PP
+\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
+.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 .
+.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.
+.SH KEYWORDS
+conversion, double-precision, floating-point, string
diff --git a/pkgs/msgcat/doc/RecEvalObj.3 b/pkgs/msgcat/doc/RecEvalObj.3
new file mode 100644
index 0000000..2eed471
--- /dev/null
+++ b/pkgs/msgcat/doc/RecEvalObj.3
@@ -0,0 +1,53 @@
+'\"
+'\" 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 Tcl_RecordAndEvalObj 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_RecordAndEvalObj \- save command on history list before evaluating
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_RecordAndEvalObj\fR(\fIinterp, cmdPtr, flags\fR)
+.SH ARGUMENTS
+.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. \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
+
+.SH DESCRIPTION
+.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 \fBTCL_EVAL_GLOBAL\fR bit is set
+in \fIflags\fR).
+It returns a completion code such as \fBTCL_OK\fR just like \fBTcl_EvalObjEx\fR,
+as well as a result object containing additional information
+(a result value or error message)
+that can be retrieved using \fBTcl_GetObjResult\fR.
+If you do not want the command recorded on the history list then
+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 \fBTCL_NO_EVAL\fR bit then
+the command is recorded without being evaluated.
+
+.SH "SEE ALSO"
+Tcl_EvalObjEx, Tcl_GetObjResult
+
+.SH KEYWORDS
+command, event, execute, history, interpreter, object, record
diff --git a/pkgs/msgcat/doc/RecordEval.3 b/pkgs/msgcat/doc/RecordEval.3
new file mode 100644
index 0000000..a8f3087
--- /dev/null
+++ b/pkgs/msgcat/doc/RecordEval.3
@@ -0,0 +1,55 @@
+'\"
+'\" Copyright (c) 1989-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.
+'\"
+.so man.macros
+.TH Tcl_RecordAndEval 3 7.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_RecordAndEval \- save command on history list before evaluating
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_RecordAndEval\fR(\fIinterp, cmd, flags\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Tcl interpreter in which to evaluate command.
+.AP "const char" *cmd in
+Command (or sequence of commands) to execute.
+.AP int flags in
+An OR'ed combination of flag bits. \fBTCL_NO_EVAL\fR means record the
+command but do not evaluate it. \fBTCL_EVAL_GLOBAL\fR means evaluate
+the command at global level instead of the current stack level.
+.BE
+
+.SH DESCRIPTION
+.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 \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 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 \fBTCL_NO_EVAL\fR bit then
+the command is recorded without being evaluated.
+.PP
+Note that \fBTcl_RecordAndEval\fR has been largely replaced by the
+object-based procedure \fBTcl_RecordAndEvalObj\fR.
+That object-based procedure records and optionally executes
+a command held in a Tcl object instead of a string.
+
+.SH "SEE ALSO"
+Tcl_RecordAndEvalObj
+
+.SH KEYWORDS
+command, event, execute, history, interpreter, record
diff --git a/pkgs/msgcat/doc/RegConfig.3 b/pkgs/msgcat/doc/RegConfig.3
new file mode 100644
index 0000000..063cc85
--- /dev/null
+++ b/pkgs/msgcat/doc/RegConfig.3
@@ -0,0 +1,111 @@
+'\"
+'\" 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 "const 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 \fIconfiguration\fR 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 *\fIkey\fR;
+ const char *\fIvalue\fR;
+} \fBTcl_Config\fR;
+.CE
+.\" No cross references yet.
+.\" .SH "SEE ALSO"
+.SH KEYWORDS
+embedding, configuration, binary library
diff --git a/pkgs/msgcat/doc/RegExp.3 b/pkgs/msgcat/doc/RegExp.3
new file mode 100644
index 0000000..e10314a
--- /dev/null
+++ b/pkgs/msgcat/doc/RegExp.3
@@ -0,0 +1,383 @@
+'\"
+'\" Copyright (c) 1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_RegExpMatch 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_RegExpMatch, Tcl_RegExpCompile, Tcl_RegExpExec, Tcl_RegExpRange, Tcl_GetRegExpFromObj, Tcl_RegExpMatchObj, Tcl_RegExpExecObj, Tcl_RegExpGetInfo \- Pattern matching with regular expressions
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_RegExpMatchObj\fR(\fIinterp\fR, \fItextObj\fR, \fIpatObj\fR)
+.sp
+int
+\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, \fItext\fR, \fIstart\fR)
+.sp
+void
+\fBTcl_RegExpRange\fR(\fIregexp\fR, \fIindex\fR, \fIstartPtr\fR, \fIendPtr\fR)
+.sp
+Tcl_RegExp
+\fBTcl_GetRegExpFromObj\fR(\fIinterp\fR, \fIpatObj\fR, \fIcflags\fR)
+.sp
+int
+\fBTcl_RegExpExecObj\fR(\fIinterp\fR, \fIregexp\fR, \fItextObj\fR, \fIoffset\fR, \fInmatches\fR, \fIeflags\fR)
+.sp
+void
+\fBTcl_RegExpGetInfo\fR(\fIregexp\fR, \fIinfoPtr\fR)
+.fi
+.SH ARGUMENTS
+.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.
+.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.
+.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 \fItext\fR is just a portion of some other string, this argument
+identifies the beginning of the larger string.
+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.
+.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
+The address of the character just after the last one in the range
+is stored here, or NULL if there is no such range.
+.AP int cflags in
+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 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
+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 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.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_RegExpMatch\fR determines whether its \fIpattern\fR argument
+matches \fIregexp\fR, where \fIregexp\fR is interpreted
+as a regular expression using the rules in the \fBre_syntax\fR
+reference page.
+If there is a match then \fBTcl_RegExpMatch\fR returns 1.
+If there is no match then \fBTcl_RegExpMatch\fR returns 0.
+If an error occurs in the matching process (e.g. \fIpattern\fR
+is not a valid regular expression) then \fBTcl_RegExpMatch\fR
+returns \-1 and leaves an error message in the interpreter result.
+\fBTcl_RegExpMatchObj\fR is similar to \fBTcl_RegExpMatch\fR except it
+operates on the Tcl objects \fItextObj\fR and \fIpatObj\fR instead of
+UTF strings.
+\fBTcl_RegExpMatchObj\fR is generally more efficient than
+\fBTcl_RegExpMatch\fR, so it is the preferred interface.
+.PP
+\fBTcl_RegExpCompile\fR, \fBTcl_RegExpExec\fR, and \fBTcl_RegExpRange\fR
+provide lower-level access to the regular expression pattern matcher.
+\fBTcl_RegExpCompile\fR compiles a regular expression string into
+the internal form used for efficient pattern matching.
+The return value is a token for this compiled form, which can be
+used in subsequent calls to \fBTcl_RegExpExec\fR or \fBTcl_RegExpRange\fR.
+If an error occurs while compiling the regular expression then
+\fBTcl_RegExpCompile\fR returns NULL and leaves an error message
+in the interpreter result.
+Note: the return value from \fBTcl_RegExpCompile\fR is only valid
+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 \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
+message in the interpreter result.
+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 \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 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 \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
+the string matched what parts of the pattern.
+\fBTcl_RegExpRange\fR returns a pair of pointers in \fI*startPtr\fR
+and \fI*endPtr\fR that identify a range of characters in
+the source string for the most recent call to \fBTcl_RegExpExec\fR.
+\fIIndex\fR indicates which of several ranges is desired:
+if \fIindex\fR is 0, information is returned about the overall range
+of characters that matched the entire pattern; otherwise,
+information is returned about the range of characters that matched the
+\fIindex\fR'th parenthesized subexpression within the pattern.
+If there is no range corresponding to \fIindex\fR then NULL
+is stored in \fI*startPtr\fR and \fI*endPtr\fR.
+.PP
+\fBTcl_GetRegExpFromObj\fR, \fBTcl_RegExpExecObj\fR, and
+\fBTcl_RegExpGetInfo\fR are object interfaces that provide the most
+direct control of Henry Spencer's regular expression library. For
+users that need to modify compilation and execution options directly,
+it is recommended that you use these interfaces instead of calling the
+internal regexp functions. These interfaces handle the details of UTF
+to Unicode translations as well as providing improved performance
+through caching in the pattern and string objects.
+.PP
+\fBTcl_GetRegExpFromObj\fR attempts to return a compiled regular
+expression from the \fIpatObj\fR. If the object does not already
+contain a compiled regular expression it will attempt to create one
+from the string in the object and assign it to the internal
+representation of the \fIpatObj\fR. The return value of this function
+is of type \fBTcl_RegExp\fR. The return value is a token for this
+compiled form, which can be used in subsequent calls to
+\fBTcl_RegExpExecObj\fR or \fBTcl_RegExpGetInfo\fR. If an error
+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 \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
+.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
+.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
+.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.
+.TP
+\fBTCL_REG_EXPANDED\fR
+Compile the regular expression (basic, extended, or advanced) using an
+expanded syntax that allows comments and whitespace. This mode causes
+non-backslashed non-bracket-expression white
+space and #-to-end-of-line comments to be ignored.
+.TP
+\fBTCL_REG_QUOTE\fR
+Compile a literal string, with all characters treated as ordinary characters.
+.TP
+\fBTCL_REG_NOCASE\fR
+Compile for matching that ignores upper/lower case distinctions.
+.TP
+\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,
+.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 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
+.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
+.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
+Compile for matching that reports only success or failure,
+not what was matched. This reduces compile overhead and may improve
+performance. Subsequent calls to \fBTcl_RegExpGetInfo\fR or
+\fBTcl_RegExpRange\fR will not report any match information.
+.TP
+\fBTCL_REG_CANMATCH\fR
+Compile for matching that reports the potential to complete a partial
+match given more text (see below).
+.RE
+.PP
+Only one of
+\fBTCL_REG_EXTENDED\fR,
+\fBTCL_REG_ADVANCED\fR,
+\fBTCL_REG_BASIC\fR, and
+\fBTCL_REG_QUOTE\fR may be specified.
+.PP
+\fBTcl_RegExpExecObj\fR executes the regular expression pattern
+matcher. It returns 1 if \fIobjPtr\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_RegExpExecObj\fR leaves an
+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
+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 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
+.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
+.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
+performed with a given regular expression \fIregexp\fR. The
+\fIinfoPtr\fR argument contains a pointer to a structure that is
+defined as follows:
+.PP
+.CS
+typedef struct Tcl_RegExpInfo {
+ int \fInsubs\fR;
+ Tcl_RegExpIndices *\fImatches\fR;
+ long \fIextendStart\fR;
+} \fBTcl_RegExpInfo\fR;
+.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+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
+appear in the pattern. Each element is a structure that is defined as
+follows:
+.PP
+.CS
+typedef struct Tcl_RegExpIndices {
+ long \fIstart\fR;
+ long \fIend\fR;
+} \fBTcl_RegExpIndices\fR;
+.CE
+.PP
+The \fIstart\fR and \fIend\fR values are Unicode character indices
+relative to the offset location within \fIobjPtr\fR where matching began.
+The \fIstart\fR index identifies the first character of the matched
+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.
+.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
+character in the string where a match could occur. If a match was
+found, this will be the same as the beginning of the current match.
+If no match was found, then it indicates the earliest point at which a
+match might occur if additional text is appended to the string. If it
+is no match is possible even with further text, this field will be set
+to \-1.
+.SH "SEE ALSO"
+re_syntax(n)
+.SH KEYWORDS
+match, pattern, regular expression, string, subexpression, Tcl_RegExpIndices, Tcl_RegExpInfo
diff --git a/pkgs/msgcat/doc/SaveResult.3 b/pkgs/msgcat/doc/SaveResult.3
new file mode 100644
index 0000000..d6ea48d
--- /dev/null
+++ b/pkgs/msgcat/doc/SaveResult.3
@@ -0,0 +1,120 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_SaveResult 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+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
+Tcl_InterpState
+\fBTcl_SaveInterpState\fR(\fIinterp, status\fR)
+.sp
+int
+\fBTcl_RestoreInterpState\fR(\fIinterp, state\fR)
+.sp
+\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_InterpState savedPtr
+.AP Tcl_Interp *interp in
+Interpreter for which state should be saved.
+.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
+These routines allows a C procedure to take a snapshot of the current
+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
+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 \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.
+.PP
+\fBTcl_SaveResult\fR moves the string and object results
+of \fIinterp\fR into the location specified by \fIstatePtr\fR.
+\fBTcl_SaveResult\fR clears the result for \fIinterp\fR and
+leaves the result in its normal empty initialized state.
+.PP
+\fBTcl_RestoreResult\fR moves the string and object results from
+\fIstatePtr\fR back into \fIinterp\fR. Any result or error that was
+already in the interpreter will be cleared. The \fIstatePtr\fR is left
+in an uninitialized state and cannot be used until another call to
+\fBTcl_SaveResult\fR.
+.PP
+\fBTcl_DiscardResult\fR releases the saved interpreter state
+stored at \fBstatePtr\fR. The state structure is left in an
+uninitialized state and cannot be used until another call to
+\fBTcl_SaveResult\fR.
+.PP
+Once \fBTcl_SaveResult\fR is called to save the interpreter
+result, either \fBTcl_RestoreResult\fR or
+\fBTcl_DiscardResult\fR must be called to properly clean up the
+memory associated with the saved state.
+.SH KEYWORDS
+result, state, interp
diff --git a/pkgs/msgcat/doc/SetChanErr.3 b/pkgs/msgcat/doc/SetChanErr.3
new file mode 100644
index 0000000..0a62dac
--- /dev/null
+++ b/pkgs/msgcat/doc/SetChanErr.3
@@ -0,0 +1,140 @@
+'\"
+'\" 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\fR defined for channels
+and interpreters. And the generic I/O layer uses \fBTcl_GetChannelError\fR and
+\fBTcl_GetChannelErrorInterp\fR to look for messages in the bypass areas and
+arrange for their return as errors. The POSIX error codes set by a driver are
+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, that is, 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, that is, 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.
+.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 \fInot\fR use
+any of the new functions.
+.IP \fBTcl_DriverGetOptionProc\fR
+Has already the ability to pass arbitrary error messages. Must
+\fInot\fR use any of the new functions.
+.IP \fBTcl_DriverWatchProc\fR
+Must \fInot\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 \fInot\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 \fInot\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; when these functions are called, the channel
+may now contain a stored arbitrary error message requiring processing by the
+caller.
+.DS
+.ta 1.9i 4i
+\fBTcl_Flush\fR \fBTcl_GetsObj\fR \fBTcl_Gets\fR
+\fBTcl_ReadChars\fR \fBTcl_ReadRaw\fR \fBTcl_Read\fR
+\fBTcl_Seek\fR \fBTcl_StackChannel\fR \fBTcl_Tell\fR
+\fBTcl_WriteChars\fR \fBTcl_WriteObj\fR \fBTcl_WriteRaw\fR
+\fBTcl_Write\fR
+.DE
+.PP
+All other API functions are unchanged. In particular, the functions below
+leave all their error information in the interpreter result.
+.DS
+.ta 1.9i 4i
+\fBTcl_Close\fR \fBTcl_UnstackChannel\fR \fBTcl_UnregisterChannel\fR
+.DE
+.SH "SEE ALSO"
+Tcl_Close(3), Tcl_OpenFileChannel(3), Tcl_SetErrno(3)
+.SH KEYWORDS
+channel driver, error messages, channel type
diff --git a/pkgs/msgcat/doc/SetErrno.3 b/pkgs/msgcat/doc/SetErrno.3
new file mode 100644
index 0000000..1735952
--- /dev/null
+++ b/pkgs/msgcat/doc/SetErrno.3
@@ -0,0 +1,66 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_SetErrno 3 8.3 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SetErrno, Tcl_GetErrno, Tcl_ErrnoId, Tcl_ErrnoMsg \- manipulate errno to store and retrieve error codes
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_SetErrno\fR(\fIerrorCode\fR)
+.sp
+int
+\fBTcl_GetErrno\fR()
+.sp
+const char *
+\fBTcl_ErrnoId\fR()
+.sp
+const char *
+\fBTcl_ErrnoMsg\fR(\fIerrorCode\fR)
+.sp
+.SH ARGUMENTS
+.AS int errorCode
+.AP int errorCode in
+A POSIX error code such as \fBENOENT\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_SetErrno\fR and \fBTcl_GetErrno\fR provide portable access
+to the \fBerrno\fR variable, which is used to record a POSIX error
+code after system calls and other operations such as \fBTcl_Gets\fR.
+These procedures are necessary because global variable accesses cannot
+be made across module boundaries on some platforms.
+.PP
+\fBTcl_SetErrno\fR sets the \fBerrno\fR variable to the value of the
+\fIerrorCode\fR argument
+C procedures that wish to return error information to their callers
+via \fBerrno\fR should call \fBTcl_SetErrno\fR rather than setting
+\fBerrno\fR directly.
+.PP
+\fBTcl_GetErrno\fR returns the current value of \fBerrno\fR.
+Procedures wishing to access \fBerrno\fR should call this procedure
+instead of accessing \fBerrno\fR directly.
+.PP
+\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
+.QW EACCES
+that corresponds to the current value of \fBerrno\fR.
+\fBTcl_ErrnoMsg\fR returns a human-readable string such as
+.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
+statically allocated and the caller must not free or modify them.
+
+.SH KEYWORDS
+errno, error code, global variables
diff --git a/pkgs/msgcat/doc/SetRecLmt.3 b/pkgs/msgcat/doc/SetRecLmt.3
new file mode 100644
index 0000000..e38ba2f
--- /dev/null
+++ b/pkgs/msgcat/doc/SetRecLmt.3
@@ -0,0 +1,53 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_SetRecursionLimit 3 7.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SetRecursionLimit \- set maximum allowable nesting depth in interpreter
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_SetRecursionLimit\fR(\fIinterp, depth\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Interpreter whose recursion limit is to be set.
+Must be greater than zero.
+.AP int depth in
+New limit for nested calls to \fBTcl_Eval\fR for \fIinterp\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+At any given time Tcl enforces a limit on the number of recursive
+calls that may be active for \fBTcl_Eval\fR and related procedures
+such as \fBTcl_GlobalEval\fR.
+Any call to \fBTcl_Eval\fR that exceeds this depth is aborted with
+an error.
+By default the recursion limit is 1000.
+.PP
+\fBTcl_SetRecursionLimit\fR may be used to change the maximum
+allowable nesting depth for an interpreter.
+The \fIdepth\fR argument specifies a new limit for \fIinterp\fR,
+and \fBTcl_SetRecursionLimit\fR returns the old limit.
+To read out the old limit without modifying it, invoke
+\fBTcl_SetRecursionLimit\fR with \fIdepth\fR equal to 0.
+.PP
+The \fBTcl_SetRecursionLimit\fR only sets the size of the Tcl
+call stack: 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 \fBTcl_SetRecursionLimit\fR.
+If this happens, see if there is a mechanism in your system for
+increasing the maximum size of the C stack.
+
+.SH KEYWORDS
+nesting depth, recursion
diff --git a/pkgs/msgcat/doc/SetResult.3 b/pkgs/msgcat/doc/SetResult.3
new file mode 100644
index 0000000..c308193
--- /dev/null
+++ b/pkgs/msgcat/doc/SetResult.3
@@ -0,0 +1,255 @@
+'\"
+'\" Copyright (c) 1989-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.
+'\"
+.so man.macros
+.TH Tcl_SetResult 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SetObjResult, Tcl_GetObjResult, Tcl_SetResult, Tcl_GetStringResult, Tcl_AppendResult, Tcl_AppendResultVA, Tcl_AppendElement, Tcl_ResetResult, Tcl_TransferResult, Tcl_FreeResult \- manipulate Tcl result
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_SetObjResult\fR(\fIinterp, objPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetObjResult\fR(\fIinterp\fR)
+.sp
+\fBTcl_SetResult\fR(\fIinterp, result, freeProc\fR)
+.sp
+const char *
+\fBTcl_GetStringResult\fR(\fIinterp\fR)
+.sp
+\fBTcl_AppendResult\fR(\fIinterp, result, result, ... , \fB(char *) NULL\fR)
+.sp
+\fBTcl_AppendResultVA\fR(\fIinterp, argList\fR)
+.sp
+\fBTcl_ResetResult\fR(\fIinterp\fR)
+.sp
+.VS 8.6
+\fBTcl_TransferResult\fR(\fIsourceInterp, result, targetInterp\fR)
+.VE 8.6
+.sp
+\fBTcl_AppendElement\fR(\fIinterp, element\fR)
+.sp
+\fBTcl_FreeResult\fR(\fIinterp\fR)
+.SH ARGUMENTS
+.AS Tcl_FreeProc sourceInterp 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 *result in
+String value to become result for \fIinterp\fR or to be
+appended to the existing result.
+.AP "const 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
+\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 initialized using
+\fBva_start\fR, and cleared using \fBva_end\fR.
+.AP Tcl_Interp *sourceInterp in
+.VS 8.6
+Interpreter that the result and error information should be copied from.
+.VE 8.6
+.AP Tcl_Interp *targetInterp in
+.VS 8.6
+Interpreter that the result and error information should be copied to.
+.VE 8.6
+.AP int result in
+.VS 8.6
+If \fBTCL_OK\fR, only copy the result. If \fBTCL_ERROR\fR, copy the error
+information as well.
+.VE 8.6
+.BE
+.SH DESCRIPTION
+.PP
+The procedures described here are utilities for manipulating the
+result value in a Tcl interpreter.
+The interpreter result may be either a Tcl object or a string.
+For example, \fBTcl_SetObjResult\fR and \fBTcl_SetResult\fR
+set the interpreter result to, respectively, an object and a string.
+Similarly, \fBTcl_GetObjResult\fR and \fBTcl_GetStringResult\fR
+return the interpreter result as an object and as a string.
+The procedures always keep the string and object forms
+of the interpreter result consistent.
+For example, if \fBTcl_SetObjResult\fR is called to set
+the result to an object,
+then \fBTcl_GetStringResult\fR is called,
+it will return the object's string value.
+.PP
+\fBTcl_SetObjResult\fR
+arranges for \fIobjPtr\fR to be the result for \fIinterp\fR,
+replacing any existing result.
+The result is left pointing to the object
+referenced by \fIobjPtr\fR.
+\fIobjPtr\fR's reference count is incremented
+since there is now a new reference to it from \fIinterp\fR.
+The reference count for any old result object
+is decremented and the old result object is freed if no
+references to it remain.
+.PP
+\fBTcl_GetObjResult\fR returns the result for \fIinterp\fR as an object.
+The object's reference count is not incremented;
+if the caller needs to retain a long-term pointer to the object
+they should use \fBTcl_IncrRefCount\fR to increment its reference count
+in order to keep it from being freed too early or accidentally changed.
+.PP
+\fBTcl_SetResult\fR
+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 \fIresult\fR argument;
+it is discussed in the section
+\fBTHE TCL_FREEPROC ARGUMENT TO TCL_SETRESULT\fR below.
+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 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,
+this conversion will lose information.
+For this reason, programmers are encouraged to
+write their code to use the new object API procedures
+and to call \fBTcl_GetObjResult\fR instead.
+.PP
+\fBTcl_ResetResult\fR clears the result for \fIinterp\fR
+and leaves the result in its normal empty initialized state.
+If the result is an object,
+its reference count is decremented and the result is left
+pointing to an unshared object representing an empty string.
+If the result is a dynamically allocated string, its memory is free*d
+and the result is left as a empty string.
+\fBTcl_ResetResult\fR also clears the error state managed by
+\fBTcl_AddErrorInfo\fR, \fBTcl_AddObjErrorInfo\fR,
+and \fBTcl_SetErrorCode\fR.
+.PP
+\fBTcl_AppendResult\fR makes it easy to build up Tcl results in pieces.
+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 \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 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.
+.PP
+.VS 8.6
+\fBTcl_TransferResult\fR moves a result from one interpreter to another,
+optionally (dependent on the \fIresult\fR parameter) including the error
+information dictionary as well. The interpreters must be in the same thread.
+The source interpreter will have its result reset by this operation.
+.VE 8.6
+.SH "DEPRECATED INTERFACES"
+.SS "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 \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
+\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
+.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 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.
+.SS "DIRECT ACCESS TO INTERP->RESULT"
+.PP
+It used to be legal for programs to
+directly read and write \fIinterp->result\fR
+to manipulate the interpreter result. The Tcl headers no longer
+permit this access by default, and C code still doing this must
+be updated to use supported routines \fBTcl_GetObjResult\fR,
+\fBTcl_GetStringResult\fR, \fBTcl_SetObjResult\fR, and \fBTcl_SetResult\fR.
+As a migration aid, access can be restored with the compiler directive
+.CS
+#define USE_INTERP_RESULT
+.CE
+but this is meant only to offer life support to otherwise dead code.
+.SH "THE TCL_FREEPROC ARGUMENT TO TCL_SETRESULT"
+.PP
+\fBTcl_SetResult\fR's \fIfreeProc\fR argument specifies how
+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 \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 \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 \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 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.
+When Tcl no longer needs the storage for the string, it will
+call \fIfreeProc\fR. \fIFreeProc\fR should have arguments and
+result that match the type \fBTcl_FreeProc\fR:
+.PP
+.CS
+typedef void \fBTcl_FreeProc\fR(
+ char *\fIblockPtr\fR);
+.CE
+.PP
+When \fIfreeProc\fR is called, its \fIblockPtr\fR will be set to
+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/pkgs/msgcat/doc/SetVar.3 b/pkgs/msgcat/doc/SetVar.3
new file mode 100644
index 0000000..ce47a73
--- /dev/null
+++ b/pkgs/msgcat/doc/SetVar.3
@@ -0,0 +1,249 @@
+'\"
+'\" Copyright (c) 1989-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.
+'\"
+.so man.macros
+.TH Tcl_SetVar 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SetVar2Ex, Tcl_SetVar, Tcl_SetVar2, Tcl_ObjSetVar2, Tcl_GetVar2Ex, Tcl_GetVar, Tcl_GetVar2, Tcl_ObjGetVar2, Tcl_UnsetVar, Tcl_UnsetVar2 \- manipulate Tcl variables
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_SetVar2Ex\fR(\fIinterp, name1, name2, newValuePtr, flags\fR)
+.sp
+const char *
+\fBTcl_SetVar\fR(\fIinterp, varName, newValue, flags\fR)
+.sp
+const char *
+\fBTcl_SetVar2\fR(\fIinterp, name1, name2, newValue, flags\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ObjSetVar2\fR(\fIinterp, part1Ptr, part2Ptr, newValuePtr, flags\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetVar2Ex\fR(\fIinterp, name1, name2, flags\fR)
+.sp
+const char *
+\fBTcl_GetVar\fR(\fIinterp, varName, flags\fR)
+.sp
+const char *
+\fBTcl_GetVar2\fR(\fIinterp, name1, name2, flags\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ObjGetVar2\fR(\fIinterp, part1Ptr, part2Ptr, flags\fR)
+.sp
+int
+\fBTcl_UnsetVar\fR(\fIinterp, varName, flags\fR)
+.sp
+int
+\fBTcl_UnsetVar2\fR(\fIinterp, name1, name2, flags\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *newValuePtr
+.AP Tcl_Interp *interp in
+Interpreter containing variable.
+.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
+If non-NULL, gives name of element within array; in this
+case \fIname1\fR must refer to an array variable.
+.AP Tcl_Obj *newValuePtr in
+Points to a Tcl object containing the new value for the variable.
+.AP int flags in
+OR-ed combination of bits providing additional information. See below
+for valid values.
+.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
+New value for variable, specified as a null-terminated string.
+A copy of this value is stored in the variable.
+.AP Tcl_Obj *part1Ptr in
+Points to a Tcl object containing the variable's name.
+The name may include a series of \fB::\fR namespace qualifiers
+to specify a variable in a particular namespace.
+May refer to a scalar variable or an element of an array variable.
+.AP Tcl_Obj *part2Ptr in
+If non-NULL, points to an object containing the name of an element
+within an array and \fIpart1Ptr\fR must refer to an array variable.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures are used to create, modify, read, and delete
+Tcl variables from C code.
+.PP
+\fBTcl_SetVar2Ex\fR, \fBTcl_SetVar\fR, \fBTcl_SetVar2\fR, and
+\fBTcl_ObjSetVar2\fR
+will create a new variable or modify an existing one.
+These procedures set the given variable to the value
+given by \fInewValuePtr\fR or \fInewValue\fR and return a
+pointer to the variable's new value, which is stored in Tcl's
+variable structure.
+\fBTcl_SetVar2Ex\fR and \fBTcl_ObjSetVar2\fR take the new value as a
+Tcl_Obj and return
+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
+\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
+\fBTcl_GetVar2Ex\fR, \fBTcl_GetVar\fR, \fBTcl_GetVar2\fR, and
+\fBTcl_ObjGetVar2\fR
+return the current value of a variable.
+The arguments to these procedures are treated in the same way
+as the arguments to the procedures described above.
+Under normal circumstances, the return value is a pointer
+to the variable's value. For \fBTcl_GetVar2Ex\fR and
+\fBTcl_ObjGetVar2\fR the value is
+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.
+If an error occurs while reading the variable (e.g. the variable
+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.
+.PP
+\fBTcl_UnsetVar\fR and \fBTcl_UnsetVar2\fR may be used to remove
+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 \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
+but the array remains.
+If an array name is specified without an index, then the entire
+array is removed.
+.PP
+The name of a variable may be specified to these procedures in
+four ways:
+.IP [1]
+If \fBTcl_SetVar\fR, \fBTcl_GetVar\fR, or \fBTcl_UnsetVar\fR
+is invoked, the variable name is given as
+a single string, \fIvarName\fR.
+If \fIvarName\fR contains an open parenthesis and ends with a
+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 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. 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).
+.PP
+The \fIflags\fR argument may be used to specify any of several
+options to the procedures.
+It consists of an OR-ed combination of the following bits.
+.TP
+\fBTCL_GLOBAL_ONLY\fR
+Under normal circumstances the procedures look up variables as follows.
+If a procedure call is active in \fIinterp\fR,
+the variable is looked up at the current level of procedure call.
+Otherwise, the variable is looked up first in the current namespace,
+then in the global namespace.
+However, if this bit is set in \fIflags\fR then the variable
+is looked up only in the global namespace
+even if there is a procedure call active.
+If both \fBTCL_GLOBAL_ONLY\fR and \fBTCL_NAMESPACE_ONLY\fR are given,
+\fBTCL_GLOBAL_ONLY\fR is ignored.
+.TP
+\fBTCL_NAMESPACE_ONLY\fR
+If this bit is set in \fIflags\fR then the variable
+is looked up only in the current namespace; if a procedure is active
+its variables are ignored, and the global namespace is also ignored unless
+it is the current namespace.
+.TP
+\fBTCL_LEAVE_ERR_MSG\fR
+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 is not set then no error message is left
+and the interpreter's result will not be modified.
+.TP
+\fBTCL_APPEND_VALUE\fR
+If this bit is set then \fInewValuePtr\fR or \fInewValue\fR is
+appended to the current value instead of replacing it.
+If the variable is currently undefined, then the bit is ignored.
+This bit is only used by the \fBTcl_Set*\fR procedures.
+.TP
+\fBTCL_LIST_ELEMENT\fR
+If this bit is set, then \fInewValue\fR is converted to a valid
+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
+.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.
+.PP
+\fBTcl_GetVar\fR and \fBTcl_GetVar2\fR
+return the current value of a variable.
+The arguments to these procedures are treated in the same way
+as the arguments to \fBTcl_SetVar\fR and \fBTcl_SetVar2\fR.
+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 \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
+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
+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 \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
+array is removed.
+
+.SH "SEE ALSO"
+Tcl_GetObjResult, Tcl_GetStringResult, Tcl_TraceVar
+
+.SH KEYWORDS
+array, get variable, interpreter, object, scalar, set, unset, variable
diff --git a/pkgs/msgcat/doc/Signal.3 b/pkgs/msgcat/doc/Signal.3
new file mode 100644
index 0000000..5b12654
--- /dev/null
+++ b/pkgs/msgcat/doc/Signal.3
@@ -0,0 +1,41 @@
+'\"
+'\" Copyright (c) 2001 ActiveState Tool Corp.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_SignalId 3 8.3 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SignalId, Tcl_SignalMsg \- Convert signal codes
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+const char *
+\fBTcl_SignalId\fR(\fIsig\fR)
+.sp
+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
+
+.SH DESCRIPTION
+.PP
+\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
+.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
+signals, signal numbers
diff --git a/pkgs/msgcat/doc/Sleep.3 b/pkgs/msgcat/doc/Sleep.3
new file mode 100644
index 0000000..2423ba1
--- /dev/null
+++ b/pkgs/msgcat/doc/Sleep.3
@@ -0,0 +1,34 @@
+'\"
+'\" Copyright (c) 1990 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 Tcl_Sleep 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Sleep \- delay execution for a given number of milliseconds
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.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 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/pkgs/msgcat/doc/SourceRCFile.3 b/pkgs/msgcat/doc/SourceRCFile.3
new file mode 100644
index 0000000..eabc47c
--- /dev/null
+++ b/pkgs/msgcat/doc/SourceRCFile.3
@@ -0,0 +1,32 @@
+'\"
+'\" Copyright (c) 1998-2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.so man.macros
+.TH Tcl_SourceRCFile 3 8.3 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SourceRCFile \- source the Tcl rc file
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+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
+
+.SH DESCRIPTION
+.PP
+\fBTcl_SourceRCFile\fR is used to source the Tcl rc file at startup.
+It is typically invoked by Tcl_Main or Tk_Main. The name of the file
+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.
+
+.SH KEYWORDS
+application-specific initialization, main program, rc file
diff --git a/pkgs/msgcat/doc/SplitList.3 b/pkgs/msgcat/doc/SplitList.3
new file mode 100644
index 0000000..219dfc7
--- /dev/null
+++ b/pkgs/msgcat/doc/SplitList.3
@@ -0,0 +1,188 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_SplitList 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SplitList, Tcl_Merge, Tcl_ScanElement, Tcl_ConvertElement, Tcl_ScanCountedElement, Tcl_ConvertCountedElement \- manipulate Tcl lists
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_SplitList\fR(\fIinterp, list, argcPtr, argvPtr\fR)
+.sp
+char *
+\fBTcl_Merge\fR(\fIargc, argv\fR)
+.sp
+int
+\fBTcl_ScanElement\fR(\fIsrc, flagsPtr\fR)
+.sp
+int
+\fBTcl_ScanCountedElement\fR(\fIsrc, length, flagsPtr\fR)
+.sp
+int
+\fBTcl_ConvertElement\fR(\fIsrc, dst, flags\fR)
+.sp
+int
+\fBTcl_ConvertCountedElement\fR(\fIsrc, length, dst, flags\fR)
+.SH ARGUMENTS
+.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.
+.AP char *list in
+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
+\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
+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
+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.
+The value of *\fIflagsPtr\fR must be passed to \fBTcl_ConvertElement\fR.
+.AP int length in
+Number of bytes in string \fIsrc\fR.
+.AP char *dst in
+Place to copy converted list element. Must contain enough characters
+to hold converted string.
+.AP int flags in
+Information about \fIsrc\fR. Must be value returned by previous
+call to \fBTcl_ScanElement\fR, possibly OR-ed
+with \fBTCL_DONT_USE_BRACES\fR.
+.BE
+.SH DESCRIPTION
+.PP
+These procedures may be used to disassemble and reassemble Tcl lists.
+\fBTcl_SplitList\fR breaks a list up into its constituent elements,
+returning an array of pointers to the elements using
+\fIargcPtr\fR and \fIargvPtr\fR.
+While extracting the arguments, \fBTcl_SplitList\fR obeys the usual
+rules for backslash substitutions and braces. The area of
+memory pointed to by \fI*argvPtr\fR is dynamically allocated; in
+addition to the array of pointers, it
+also holds copies of all the list elements. It is the caller's
+responsibility to free up all of this storage.
+For example, suppose that you have called \fBTcl_SplitList\fR with
+the following code:
+.PP
+.CS
+int argc, code;
+char *string;
+char **argv;
+\&...
+code = \fBTcl_SplitList\fR(interp, string, &argc, &argv);
+.CE
+.PP
+Then you should eventually free the storage with a call like the
+following:
+.PP
+.CS
+Tcl_Free((char *) argv);
+.CE
+.PP
+\fBTcl_SplitList\fR normally returns \fBTCL_OK\fR, which means the list was
+successfully parsed.
+If there was a syntax error in \fIlist\fR, then \fBTCL_ERROR\fR is returned
+and the interpreter's result will point to an error message describing the
+problem (if \fIinterp\fR was not NULL).
+If \fBTCL_ERROR\fR is returned then no memory is allocated and \fI*argvPtr\fR
+is not modified.
+.PP
+\fBTcl_Merge\fR is the inverse of \fBTcl_SplitList\fR: it
+takes a collection of strings given by \fIargc\fR
+and \fIargv\fR and generates a result string
+that has proper list structure.
+This means that commands like \fBindex\fR may be used to
+extract the original elements again.
+In addition, if the result of \fBTcl_Merge\fR is passed to \fBTcl_Eval\fR,
+it will be parsed into \fIargc\fR words whose values will
+be the same as the \fIargv\fR strings passed to \fBTcl_Merge\fR.
+\fBTcl_Merge\fR will modify the list elements with braces and/or
+backslashes in order to produce proper Tcl list structure.
+The result string is dynamically allocated
+using \fBTcl_Alloc\fR; the caller must eventually release the space
+using \fBTcl_Free\fR.
+.PP
+If the result of \fBTcl_Merge\fR is passed to \fBTcl_SplitList\fR,
+the elements returned by \fBTcl_SplitList\fR will be identical to
+those passed into \fBTcl_Merge\fR.
+However, the converse is not true: if \fBTcl_SplitList\fR
+is passed a given string, and the resulting \fIargc\fR and
+\fIargv\fR are passed to \fBTcl_Merge\fR, the resulting string
+may not be the same as the original string passed to \fBTcl_SplitList\fR.
+This is because \fBTcl_Merge\fR may use backslashes and braces
+differently than the original string.
+.PP
+\fBTcl_ScanElement\fR and \fBTcl_ConvertElement\fR are the
+procedures that do all of the real work of \fBTcl_Merge\fR.
+\fBTcl_ScanElement\fR scans its \fIsrc\fR argument
+and determines how to use backslashes and braces
+when converting it to a list element.
+It returns an overestimate of the number of characters
+required to represent \fIsrc\fR as a list element, and
+it stores information in \fI*flagsPtr\fR that is needed
+by \fBTcl_ConvertElement\fR.
+.PP
+\fBTcl_ConvertElement\fR is a companion procedure to \fBTcl_ScanElement\fR.
+It does the actual work of converting a string to a list element.
+Its \fIflags\fR argument must be the same as the value returned
+by \fBTcl_ScanElement\fR.
+\fBTcl_ConvertElement\fR writes a proper list element to memory
+starting at *\fIdst\fR and returns a count of the total number
+of characters written, which will be no more than the result
+returned by \fBTcl_ScanElement\fR.
+\fBTcl_ConvertElement\fR writes out only the actual list element
+without any leading or trailing spaces: it is up to the caller to
+include spaces between adjacent list elements.
+.PP
+\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 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.
+The caller may insist on the second approach by OR-ing the
+flag value returned by \fBTcl_ScanElement\fR with
+\fBTCL_DONT_USE_BRACES\fR.
+Although this will produce an uglier result, it is useful in some
+special situations, such as when \fBTcl_ConvertElement\fR is being
+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
+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.
+.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
+argument, and the string may contain embedded nulls.
+.SH "SEE ALSO"
+Tcl_ListObjGetElements(3)
+.SH KEYWORDS
+backslash, convert, element, list, merge, split, strings
diff --git a/pkgs/msgcat/doc/SplitPath.3 b/pkgs/msgcat/doc/SplitPath.3
new file mode 100644
index 0000000..7fdfce6
--- /dev/null
+++ b/pkgs/msgcat/doc/SplitPath.3
@@ -0,0 +1,97 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_SplitPath 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SplitPath, Tcl_JoinPath, Tcl_GetPathType \- manipulate platform-dependent file paths
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_SplitPath\fR(\fIpath, argcPtr, argvPtr\fR)
+.sp
+char *
+\fBTcl_JoinPath\fR(\fIargc, argv, resultPtr\fR)
+.sp
+Tcl_PathType
+\fBTcl_GetPathType\fR(\fIpath\fR)
+.SH ARGUMENTS
+.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
+\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
+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
+\fBTcl_JoinPath\fR will be appended.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures have been superseded by the objectified procedures in
+the \fBFileSystem\fR man page, which are more efficient.
+.PP
+These procedures may be used to disassemble and reassemble file
+paths in a platform independent manner: they provide C-level access to
+the same functionality as the \fBfile split\fR, \fBfile join\fR, and
+\fBfile pathtype\fR commands.
+.PP
+\fBTcl_SplitPath\fR breaks a path into its constituent elements,
+returning an array of pointers to the elements using \fIargcPtr\fR and
+\fIargvPtr\fR. The area of memory pointed to by \fI*argvPtr\fR is
+dynamically allocated; in addition to the array of pointers, it also
+holds copies of all the path elements. It is the caller's
+responsibility to free all of this storage.
+For example, suppose that you have called \fBTcl_SplitPath\fR with the
+following code:
+.PP
+.CS
+int argc;
+char *path;
+char **argv;
+\&...
+Tcl_SplitPath(string, &argc, &argv);
+.CE
+.PP
+Then you should eventually free the storage with a call like the
+following:
+.PP
+.CS
+Tcl_Free((char *) argv);
+.CE
+.PP
+\fBTcl_JoinPath\fR is the inverse of \fBTcl_SplitPath\fR: it takes a
+collection of path elements given by \fIargc\fR and \fIargv\fR and
+generates a result string that is a properly constructed path. The
+result string is appended to \fIresultPtr\fR. \fIResultPtr\fR must
+refer to an initialized \fBTcl_DString\fR.
+.PP
+If the result of \fBTcl_SplitPath\fR is passed to \fBTcl_JoinPath\fR,
+the result will refer to the same location, but may not be in the same
+form. This is because \fBTcl_SplitPath\fR and \fBTcl_JoinPath\fR
+eliminate duplicate path separators and return a normalized form for
+each platform.
+.PP
+\fBTcl_GetPathType\fR returns the type of the specified \fIpath\fR,
+where \fBTcl_PathType\fR is one of \fBTCL_PATH_ABSOLUTE\fR,
+\fBTCL_PATH_RELATIVE\fR, or \fBTCL_PATH_VOLUME_RELATIVE\fR. See the
+\fBfilename\fR manual entry for a description of the path types for
+each platform.
+
+.SH KEYWORDS
+file, filename, join, path, split, type
diff --git a/pkgs/msgcat/doc/StaticPkg.3 b/pkgs/msgcat/doc/StaticPkg.3
new file mode 100644
index 0000000..fa6c32f
--- /dev/null
+++ b/pkgs/msgcat/doc/StaticPkg.3
@@ -0,0 +1,70 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_StaticPackage 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_StaticPackage \- make a statically linked package available via the 'load' command
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_StaticPackage\fR(\fIinterp, pkgName, initProc, safeInitProc\fR)
+.SH ARGUMENTS
+.AS Tcl_PackageInitProc *safeInitProc
+.AP Tcl_Interp *interp in
+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
+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
+Procedure to invoke to incorporate this package into a trusted
+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
+cannot be used in safe interpreters.
+.BE
+.SH DESCRIPTION
+.PP
+This procedure may be invoked to announce that a package has been
+linked statically with a Tcl application and, optionally, that it
+has already been loaded into an interpreter.
+Once \fBTcl_StaticPackage\fR has been invoked for a package, it
+may be loaded into interpreters using the \fBload\fR command.
+\fBTcl_StaticPackage\fR is normally invoked only by the \fBTcl_AppInit\fR
+procedure for the application, not by packages for themselves
+(\fBTcl_StaticPackage\fR should only be invoked for statically
+loaded packages, and code in the package itself should not need
+to know whether the package is dynamically or statically loaded).
+.PP
+When the \fBload\fR command is used later to load the package into
+an interpreter, one of \fIinitProc\fR and \fIsafeInitProc\fR will
+be invoked, depending on whether the target interpreter is safe
+or not.
+\fIinitProc\fR and \fIsafeInitProc\fR must both match the
+following prototype:
+.PP
+.CS
+typedef int \fBTcl_PackageInitProc\fR(
+ Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+The \fIinterp\fR argument identifies the interpreter in which the package
+is to be loaded. The initialization 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. The result or error from the initialization procedure will
+be returned as the result of the \fBload\fR command that caused the
+initialization procedure to be invoked.
+.SH KEYWORDS
+initialization procedure, package, static linking
+.SH "SEE ALSO"
+load(n), package(n), Tcl_PkgRequire(3)
diff --git a/pkgs/msgcat/doc/StdChannels.3 b/pkgs/msgcat/doc/StdChannels.3
new file mode 100644
index 0000000..b5b020e
--- /dev/null
+++ b/pkgs/msgcat/doc/StdChannels.3
@@ -0,0 +1,120 @@
+'\"
+'\" Copyright (c) 2001 by ActiveState Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH "Standard Channels" 3 7.5 Tcl "Tcl Library Procedures"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_StandardChannels \- How the Tcl library deals with the standard channels
+.BE
+
+.SH DESCRIPTION
+.PP
+This page explains the initialization and use of standard channels in
+the Tcl library.
+.PP
+The term \fIstandard channels\fR comes out of the Unix world and
+refers to the three channels automatically opened by the OS for
+each new application. They are \fBstdin\fR, \fBstdout\fR and
+\fBstderr\fR. The first is the standard input an application can read
+from, the other two refer to writable channels, one for regular
+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.
+.SS "APPLICATION PROGRAMMING INTERFACES"
+.PP
+The public API procedures dealing directly with standard channels are
+\fBTcl_GetStdChannel\fR and \fBTcl_SetStdChannel\fR. Additional public
+APIs to consider are \fBTcl_RegisterChannel\fR,
+\fBTcl_CreateChannel\fR and \fBTcl_GetChannel\fR.
+.SH "INITIALIZATION OF TCL STANDARD CHANNELS"
+.PP
+Standard channels are initialized by the Tcl library in three cases:
+when explicitly requested, when implicitly required before returning
+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
+.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 states of the
+other standard channels are unaffected.
+.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
+platform-specific default values:
+.RS
+.TP
+(a)
+when open channels are listed with \fBTcl_GetChannelNames\fR (or the
+\fBfile channels\fR script command), or
+.TP
+(b)
+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).
+.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
+the application are designated as the Tcl standard channels.
+.RE
+.TP
+3)
+All uninitialized standard channels are initialized to
+platform-specific default values when a user-requested channel is
+registered with \fBTcl_RegisterChannel\fR.
+.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.
+.SH "RE-INITIALIZATION OF TCL STANDARD CHANNELS"
+.PP
+Once a Tcl standard channel is initialized through one of the methods
+above, closing this Tcl standard channel will cause the next call to
+\fBTcl_CreateChannel\fR to make the new channel the new standard
+channel, too. If more than one Tcl standard channel was closed
+\fBTcl_CreateChannel\fR will fill the empty slots in the order
+\fBstdin\fR, \fBstdout\fR and \fBstderr\fR.
+.PP
+\fBTcl_CreateChannel\fR will not try to reinitialize an empty slot if
+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 "SHELL-SPECIFIC DETAILS"
+.SS tclsh
+.PP
+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.
+.SS wish
+.PP
+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/pkgs/msgcat/doc/StrMatch.3 b/pkgs/msgcat/doc/StrMatch.3
new file mode 100644
index 0000000..5adaf6e
--- /dev/null
+++ b/pkgs/msgcat/doc/StrMatch.3
@@ -0,0 +1,49 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_StringMatch 3 8.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_StringMatch, Tcl_StringCaseMatch \- test whether a string matches a pattern
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_StringMatch\fR(\fIstr\fR, \fIpattern\fR)
+.sp
+int
+\fBTcl_StringCaseMatch\fR(\fIstr\fR, \fIpattern\fR, \fIflags\fR)
+.SH ARGUMENTS
+.AS "const char" *pattern
+.AP "const char" *str in
+String to test.
+.AP "const char" *pattern in
+Pattern to match against string. May contain special
+characters from the set *?\e[].
+.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
+.PP
+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 \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.
+.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 \fBTCL_MATCH_NOCASE\fR), then the string and
+pattern are essentially matched in the lower case.
+
+.SH KEYWORDS
+match, pattern, string
diff --git a/pkgs/msgcat/doc/StringObj.3 b/pkgs/msgcat/doc/StringObj.3
new file mode 100644
index 0000000..412ab78
--- /dev/null
+++ b/pkgs/msgcat/doc/StringObj.3
@@ -0,0 +1,384 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.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_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
+.sp
+Tcl_Obj *
+\fBTcl_NewStringObj\fR(\fIbytes, length\fR)
+.sp
+Tcl_Obj *
+\fBTcl_NewUnicodeObj\fR(\fIunicode, numChars\fR)
+.sp
+void
+\fBTcl_SetStringObj\fR(\fIobjPtr, bytes, length\fR)
+.sp
+void
+\fBTcl_SetUnicodeObj\fR(\fIobjPtr, unicode, numChars\fR)
+.sp
+char *
+\fBTcl_GetStringFromObj\fR(\fIobjPtr, lengthPtr\fR)
+.sp
+char *
+\fBTcl_GetString\fR(\fIobjPtr\fR)
+.sp
+Tcl_UniChar *
+\fBTcl_GetUnicodeFromObj\fR(\fIobjPtr, lengthPtr\fR)
+.sp
+Tcl_UniChar *
+\fBTcl_GetUnicode\fR(\fIobjPtr\fR)
+.sp
+Tcl_UniChar
+\fBTcl_GetUniChar\fR(\fIobjPtr, index\fR)
+.sp
+int
+\fBTcl_GetCharLength\fR(\fIobjPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetRange\fR(\fIobjPtr, first, last\fR)
+.sp
+void
+\fBTcl_AppendToObj\fR(\fIobjPtr, bytes, length\fR)
+.sp
+void
+\fBTcl_AppendUnicodeToObj\fR(\fIobjPtr, unicode, numChars\fR)
+.sp
+void
+\fBTcl_AppendObjToObj\fR(\fIobjPtr, appendObjPtr\fR)
+.sp
+void
+\fBTcl_AppendStringsToObj\fR(\fIobjPtr, string, string, ... \fB(char *) NULL\fR)
+.sp
+void
+\fBTcl_AppendStringsToObjVA\fR(\fIobjPtr, argList\fR)
+.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
+void
+\fBTcl_AppendPrintfToObj\fR(\fIobjPtr, format, ...\fR)
+.sp
+void
+\fBTcl_SetObjLength\fR(\fIobjPtr, newLength\fR)
+.sp
+int
+\fBTcl_AttemptSetObjLength\fR(\fIobjPtr, newLength\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ConcatObj\fR(\fIobjc, objv\fR)
+.SH ARGUMENTS
+.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 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.)
+.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
+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
+unless \fInumChars\fR is negative.
+.AP int numChars in
+The number of Unicode characters to copy from \fIunicode\fR when
+initializing, setting, or appending to a string object.
+If negative, all characters up to the first null character are used.
+.AP int index in
+The index of the Unicode character to return.
+.AP int first in
+The index of the first Unicode character in the Unicode range to be
+returned as a new object.
+.AP int last in
+The index of the last Unicode character in the Unicode range to be
+returned as a new object.
+.AP Tcl_Obj *objPtr in/out
+Points to an object to manipulate.
+.AP Tcl_Obj *appendObjPtr in
+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 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 initialized using
+\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
+.QW "..."
+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.
+.BE
+.SH DESCRIPTION
+.PP
+The procedures described in this manual entry allow Tcl objects to
+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 does not have to be copied for each append.
+Also, indexing and length computations are optimized because the
+Unicode string representation is calculated and cached as needed.
+When using the \fBTcl_Append*\fR family of functions where the
+interpreter's result is the object being appended to, it is important
+to call Tcl_ResetResult first to ensure you are not unintentionally
+appending to existing data in the result object.
+.PP
+\fBTcl_NewStringObj\fR and \fBTcl_SetStringObj\fR create a new object
+or modify an existing object to hold a copy of the string given by
+\fIbytes\fR and \fIlength\fR. \fBTcl_NewUnicodeObj\fR and
+\fBTcl_SetUnicodeObj\fR create a new object or modify an existing
+object to hold a copy of the Unicode string given by \fIunicode\fR and
+\fInumChars\fR. \fBTcl_NewStringObj\fR and \fBTcl_NewUnicodeObj\fR
+return a pointer to a newly created object with reference count zero.
+All four procedures set the object to hold a copy of the specified
+string. \fBTcl_SetStringObj\fR and \fBTcl_SetUnicodeObj\fR free any
+old string representation as well as any old internal representation
+of the object.
+.PP
+\fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR return an object's
+string representation. This is given by the returned byte pointer and
+(for \fBTcl_GetStringFromObj\fR) length, which is stored in
+\fIlengthPtr\fR if it is non-NULL. If the object's UTF string
+representation is invalid (its byte pointer is NULL), the string
+representation is regenerated from the object's internal
+representation. The storage referenced by the returned byte pointer
+is owned by the object manager. It is passed back as a writable
+pointer so that extension author creating their own \fBTcl_ObjType\fR
+will be able to modify the string representation within the
+\fBTcl_UpdateStringProc\fR of their \fBTcl_ObjType\fR. Except for that
+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.
+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
+to \fBTcl_IsShared\fR and \fBTcl_DuplicateObj\fR prior to any
+in-place modification of the string representation.
+The procedure \fBTcl_GetString\fR is used in the common case
+where the caller does not need the length of the string
+representation.
+.PP
+\fBTcl_GetUnicodeFromObj\fR and \fBTcl_GetUnicode\fR return an object's
+value as a Unicode string. This is given by the returned pointer and
+(for \fBTcl_GetUnicodeFromObj\fR) length, which is stored in
+\fIlengthPtr\fR if it is non-NULL. The storage referenced by the returned
+byte pointer is owned by the object manager and should not be modified by
+the caller. The procedure \fBTcl_GetUnicode\fR is used in the common case
+where the caller does not need the length of the unicode string
+representation.
+.PP
+\fBTcl_GetUniChar\fR returns the \fIindex\fR'th character in the
+object's Unicode representation.
+.PP
+\fBTcl_GetRange\fR returns a newly created object comprised of the
+characters between \fIfirst\fR and \fIlast\fR (inclusive) in the
+object's Unicode representation. If the object's Unicode
+representation is invalid, the Unicode representation is regenerated
+from the object's string representation.
+.PP
+\fBTcl_GetCharLength\fR returns the number of characters (as opposed
+to bytes) in the string object.
+.PP
+\fBTcl_AppendToObj\fR appends the data given by \fIbytes\fR and
+\fIlength\fR to the string representation of the object specified by
+\fIobjPtr\fR. If the object has an invalid string representation,
+then an attempt is made to convert \fIbytes\fR is to the Unicode
+format. If the conversion is successful, then the converted form of
+\fIbytes\fR is appended to the object's Unicode representation.
+Otherwise, the object's Unicode representation is invalidated and
+converted to the UTF format, and \fIbytes\fR is appended to the
+object's new string representation.
+.PP
+\fBTcl_AppendUnicodeToObj\fR appends the Unicode string given by
+\fIunicode\fR and \fInumChars\fR to the object specified by
+\fIobjPtr\fR. If the object has an invalid Unicode representation,
+then \fIunicode\fR is converted to the UTF format and appended to the
+object's string representation. Appends are optimized to handle
+repeated appends relatively efficiently (it over-allocates the string
+or Unicode space to avoid repeated reallocations and copies of
+object's string value).
+.PP
+\fBTcl_AppendObjToObj\fR is similar to \fBTcl_AppendToObj\fR, but it
+appends the string or Unicode value (whichever exists and is best
+suited to be appended to \fIobjPtr\fR) of \fIappendObjPtr\fR to
+\fIobjPtr\fR.
+.PP
+\fBTcl_AppendStringsToObj\fR is similar to \fBTcl_AppendToObj\fR
+except that it can be passed more than one value to append and
+each value must be a null-terminated string (i.e. none of the
+values may contain internal null characters). Any number of
+\fIstring\fR arguments may be provided, but the last argument
+must be a NULL pointer to indicate the end of the list.
+.PP
+\fBTcl_AppendStringsToObjVA\fR is the same as \fBTcl_AppendStringsToObj\fR
+except that instead of taking a variable number of arguments it takes an
+argument list.
+.PP
+\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
+.PP
+.CS
+\fBTcl_Format\fR(interp, \fBTcl_GetString\fR(objv[1]), objc-2, objv+2);
+.CE
+.PP
+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:
+.PP
+.CS
+Tcl_Obj *newPtr = \fBTcl_Format\fR(interp, format, objc, objv);
+if (newPtr == NULL) return TCL_ERROR;
+\fBTcl_AppendObjToObj\fR(objPtr, newPtr);
+return TCL_OK;
+.CE
+.PP
+but with greater convenience and efficiency when the appending
+functionality is needed.
+.PP
+\fBTcl_ObjPrintf\fR serves as a replacement for the common sequence
+.PP
+.CS
+char buf[SOME_SUITABLE_LENGTH];
+sprintf(buf, format, ...);
+\fBTcl_NewStringObj\fR(buf, -1);
+.CE
+.PP
+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 \fBint\fR.
+.PP
+.CS
+int x = 5;
+Tcl_Obj *objPtr = \fBTcl_ObjPrintf\fR("Value is %d", x);
+.CE
+.PP
+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.
+It is impossible however to provide runtime protection against
+mismatches between the format and any subsequent arguments.
+Compile-time protection may be provided by some compilers.
+.PP
+\fBTcl_AppendPrintfToObj\fR is an appending alternative form
+of \fBTcl_ObjPrintf\fR with functionality equivalent to
+.PP
+.CS
+\fBTcl_AppendObjToObj\fR(objPtr, \fBTcl_ObjPrintf\fR(format, ...));
+.CE
+.PP
+but with greater convenience and efficiency when the appending
+functionality is needed.
+.PP
+The \fBTcl_SetObjLength\fR procedure changes the length of the
+string value of its \fIobjPtr\fR argument. If the \fInewLength\fR
+argument is greater than the space allocated for the object's
+string, then the string space is reallocated and the old value
+is copied to the new space; the bytes between the old length of
+the string and the new length may have arbitrary values.
+If the \fInewLength\fR argument is less than the current length
+of the object's string, with \fIobjPtr->length\fR is reduced without
+reallocating the string space; the original allocated size for the
+string is recorded in the object, so that the string length can be
+enlarged in a subsequent call to \fBTcl_SetObjLength\fR without
+reallocating storage. In all cases \fBTcl_SetObjLength\fR leaves
+a null character at \fIobjPtr->bytes[newLength]\fR.
+.PP
+\fBTcl_AttemptSetObjLength\fR is identical in function to
+\fBTcl_SetObjLength\fR except that if sufficient memory to satisfy the
+request cannot be allocated, it does not cause the Tcl interpreter to
+\fBpanic\fR. Thus, if \fInewLength\fR is greater than the space
+allocated for the object's string, and there is not enough memory
+available to satisfy the request, \fBTcl_AttemptSetObjLength\fR will take
+no action and return 0 to indicate failure. If there is enough memory
+to satisfy the request, \fBTcl_AttemptSetObjLength\fR behaves just like
+\fBTcl_SetObjLength\fR and returns 1 to indicate success.
+.PP
+The \fBTcl_ConcatObj\fR function returns a new string object whose
+value is the space-separated concatenation of the string
+representations of all of the objects in the \fIobjv\fR
+array. \fBTcl_ConcatObj\fR eliminates leading and trailing white space
+as it copies the string representations of the \fIobjv\fR array to the
+result. If an element of the \fIobjv\fR array consists of nothing but
+white space, then that object is ignored entirely. This white-space
+removal was added to make the output of the \fBconcat\fR command
+cleaner-looking. \fBTcl_ConcatObj\fR returns a pointer to a
+newly-created object whose ref count is zero.
+.SH "SEE ALSO"
+Tcl_NewObj(3), Tcl_IncrRefCount(3), Tcl_DecrRefCount(3), format(n), sprintf(3)
+.SH KEYWORDS
+append, internal representation, object, object type, string object,
+string type, string representation, concat, concatenate, unicode
diff --git a/pkgs/msgcat/doc/SubstObj.3 b/pkgs/msgcat/doc/SubstObj.3
new file mode 100644
index 0000000..786b595
--- /dev/null
+++ b/pkgs/msgcat/doc/SubstObj.3
@@ -0,0 +1,68 @@
+'\"
+'\" Copyright (c) 2001 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_SubstObj 3 8.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_SubstObj \- perform substitutions on Tcl objects
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_SubstObj\fR(\fIinterp, objPtr, flags\fR)
+.SH ARGUMENTS
+.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
+message.
+.AP Tcl_Obj *objPtr in
+A Tcl object containing the string to perform substitutions on.
+.AP int flags in
+ORed combination of flag bits that specify which substitutions to
+perform. The flags \fBTCL_SUBST_COMMANDS\fR,
+\fBTCL_SUBST_VARIABLES\fR and \fBTCL_SUBST_BACKSLASHES\fR are
+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
+strings in the fashion of the \fBsubst\fR command. It gets the value
+of the string contained in \fIobjPtr\fR and scans it, copying
+characters and performing the chosen substitutions as it goes to an
+output object which is returned as the result of the function. In the
+event of an error occurring during the execution of a command or
+variable substitution, the function returns NULL and an error message
+is left in \fIinterp\fR's result.
+.PP
+Three kinds of substitutions are supported. When the
+\fBTCL_SUBST_BACKSLASHES\fR bit is set in \fIflags\fR, sequences that
+look like backslash substitutions for Tcl commands are replaced by
+their corresponding character.
+.PP
+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 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
+.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/pkgs/msgcat/doc/TCL_MEM_DEBUG.3 b/pkgs/msgcat/doc/TCL_MEM_DEBUG.3
new file mode 100644
index 0000000..05d4564
--- /dev/null
+++ b/pkgs/msgcat/doc/TCL_MEM_DEBUG.3
@@ -0,0 +1,80 @@
+'\"
+'\" Copyright (c) 1992-1999 Karl Lehenbauer and Mark Diekhans.
+'\" Copyright (c) 2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.so man.macros
+.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
+.BE
+.SH DESCRIPTION
+When Tcl is compiled with \fBTCL_MEM_DEBUG\fR defined, a powerful set
+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 (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 \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
+.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 \(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
+.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
+to isolate a corruption problem. Turning on memory validation with
+the memory command can help isolate difficult problems. If you
+suspect (or know) that corruption is occurring before the Tcl
+interpreter comes up far enough for you to issue commands, you can set
+\fBMEM_VALIDATE\fR define, recompile tclCkalloc.c and rebuild Tcl.
+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 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/pkgs/msgcat/doc/Tcl.n b/pkgs/msgcat/doc/Tcl.n
new file mode 100644
index 0000000..68146ab
--- /dev/null
+++ b/pkgs/msgcat/doc/Tcl.n
@@ -0,0 +1,270 @@
+'\"
+'\" 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 Tcl n "8.6" Tcl "Tcl Built-In Commands"
+.BS
+.SH NAME
+Tcl \- Tool Command Language
+.SH SYNOPSIS
+Summary of Tcl language syntax.
+.BE
+.SH DESCRIPTION
+.PP
+The following rules define the syntax and semantics of the Tcl language:
+.IP "[1] \fBCommands.\fR"
+A Tcl script is a string containing one or more commands.
+Semi-colons and newlines are command separators unless quoted as
+described below.
+Close brackets are command terminators during command substitution
+(see below) unless quoted.
+.IP "[2] \fBEvaluation.\fR"
+A command is evaluated in two steps.
+First, the Tcl interpreter breaks the command into \fIwords\fR
+and performs substitutions as described below.
+These substitutions are performed in the same way for all
+commands.
+The first word is used to locate a command procedure to
+carry out the command, then all of the words of the command are
+passed to the command procedure.
+The command procedure is free to interpret each of its words
+in any way it likes, such as an integer, variable name, list,
+or Tcl script.
+Different commands interpret their words differently.
+.IP "[3] \fBWords.\fR"
+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
+.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] \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 {g h}}"
+is equivalent to
+.QW "cmd a b {[c]} d {$e} f {g h}" .
+.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
+quoted with a backslash then it is not counted in locating the
+matching close brace).
+No substitutions are performed on the characters between the
+braces except for backslash-newline substitutions described
+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 "[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
+.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 "[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.
+Variable substitution may take any of the following forms:
+.RS
+.TP 15
+\fB$\fIname\fR
+.
+\fIName\fR is the name of a scalar variable; the name is a sequence
+of one or more characters that are a letter, digit, underscore,
+or namespace separators (two or more colons).
+Letters and digits are \fIonly\fR the standard ASCII ones (\fB0\fR\-\fB9\fR,
+\fBA\fR\-\fBZ\fR and \fBa\fR\-\fBz\fR).
+.TP 15
+\fB$\fIname\fB(\fIindex\fB)\fR
+.
+\fIName\fR gives the name of an array variable and \fIindex\fR gives
+the name of an element within that array.
+\fIName\fR must contain only letters, digits, underscores, and
+namespace separators, and may be an empty string.
+Letters and digits are \fIonly\fR the standard ASCII ones (\fB0\fR\-\fB9\fR,
+\fBA\fR\-\fBZ\fR and \fBa\fR\-\fBz\fR).
+Command substitutions, variable substitutions, and backslash
+substitutions are performed on the characters of \fIindex\fR.
+.TP 15
+\fB${\fIname\fB}\fR
+.
+\fIName\fR is the name of a scalar variable or array element. It may contain
+any characters whatsoever except for close braces. It indicates an array
+element if \fIname\fR is in the form
+.QW \fIarrayName\fB(\fIindex\fB)\fR
+where \fIarrayName\fR does not contain any open parenthesis characters,
+.QW \fB(\fR ,
+or close brace characters,
+.QW \fB}\fR ,
+and \fIindex\fR can be any sequence of characters except for close brace
+characters. No further
+substitutions are performed during the parsing of \fIname\fR.
+.PP
+There may be any number of variable substitutions in a single word.
+Variable substitution is not performed on words enclosed in braces.
+.PP
+Note that variables may contain character sequences other than those listed
+above, but in that case other mechanisms must be used to access them (e.g.,
+via the \fBset\fR command's single-argument form).
+.RE
+.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.
+This allows characters such as double quotes, close brackets,
+and dollar signs to be included in words without triggering
+special processing.
+The following table lists the backslash sequences that are
+handled specially, along with the value that replaces each sequence.
+.RS
+.TP 7
+\e\fBa\fR
+Audible alert (bell) (0x7).
+.TP 7
+\e\fBb\fR
+Backspace (0x8).
+.TP 7
+\e\fBf\fR
+Form feed (0xc).
+.TP 7
+\e\fBn\fR
+Newline (0xa).
+.TP 7
+\e\fBr\fR
+Carriage-return (0xd).
+.TP 7
+\e\fBt\fR
+Tab (0x9).
+.TP 7
+\e\fBv\fR
+Vertical tab (0xb).
+.TP 7
+\e\fB<newline>\fIwhiteSpace\fR
+.
+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 is not
+in braces or quotes.
+.TP 7
+\e\e
+Backslash
+.PQ \e "" .
+.TP 7
+\e\fIooo\fR
+.
+The digits \fIooo\fR (one, two, or three of them) give a eight-bit octal
+value for the Unicode character that will be inserted, in the range \fI000\fR
+- \fI377\fR. The parser will stop just before this range overflows, or when
+the maximum of three digits is reached. The upper bits of the Unicode
+character will be 0.
+.TP 7
+\e\fBx\fIhh\fR
+.
+The hexadecimal digits \fIhh\fR (one or two of them) give an eight-bit
+hexadecimal value for the Unicode character that will be inserted. The upper
+bits of the Unicode character will be 0.
+.TP 7
+\e\fBu\fIhhhh\fR
+.
+The hexadecimal digits \fIhhhh\fR (one, two, three, or four of them) give a
+sixteen-bit hexadecimal value for the Unicode character that will be
+inserted. The upper bits of the Unicode character will be 0.
+.TP 7
+\e\fBU\fIhhhhhhhh\fR
+.
+The hexadecimal digits \fIhhhhhhhh\fR (one up to eight of them) give a
+twenty-one-bit hexadecimal value for the Unicode character that will be
+inserted, in the range U+0000..U+10FFFF. The parser will stop just
+before this range overflows, or when the maximum of eight digits
+is reached. The upper bits of the Unicode character will be 0.
+.PP
+The range U+010000..U+10FFFD is reserved for the future.
+.PP
+Backslash substitution is not performed on words enclosed in braces,
+except for backslash-newline as described above.
+.RE
+.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 "[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
+substitutions are performed on the value of the variable; the
+value is inserted into the word verbatim.
+If command substitution occurs then the nested command is
+processed entirely by the recursive call to the Tcl interpreter;
+no substitutions are performed before making the recursive
+call and no additional substitutions are performed on the result
+of the nested script.
+.RS
+.PP
+Substitutions take place from left to right, and each substitution is
+evaluated completely before attempting to evaluate the next. Thus, a
+sequence like
+.PP
+.CS
+set y [set x 0][incr x][incr x]
+.CE
+.PP
+will always set the variable \fIy\fR to the value, \fI012\fR.
+.RE
+.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.
+.SH KEYWORDS
+backslash, command, comment, script, substitution, variable
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/pkgs/msgcat/doc/TclZlib.3 b/pkgs/msgcat/doc/TclZlib.3
new file mode 100644
index 0000000..1b5e892
--- /dev/null
+++ b/pkgs/msgcat/doc/TclZlib.3
@@ -0,0 +1,248 @@
+'\"
+'\" Copyright (c) 2008 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 TclZlib 3 8.6 Tcl "Tcl Library Procedures"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_ZlibAdler32, Tcl_ZlibCRC32, Tcl_ZlibDeflate, Tcl_ZlibInflate, Tcl_ZlibStreamChecksum, Tcl_ZlibStreamClose, Tcl_ZlibStreamEof, Tcl_ZlibStreamGet, Tcl_ZlibStreamGetCommandName, Tcl_ZlibStreamInit, Tcl_ZlibStreamPut \- compression and decompression functions
+.SH SYNOPSIS
+.nf
+#include <tcl.h>
+.sp
+int
+\fBTcl_ZlibDeflate\fR(\fIinterp, format, dataObj, level, dictObj\fR)
+.sp
+int
+\fBTcl_ZlibInflate\fR(\fIinterp, format, dataObj, dictObj\fR)
+.sp
+unsigned int
+\fBTcl_ZlibCRC32\fR(\fIinitValue, bytes, length\fR)
+.sp
+unsigned int
+\fBTcl_ZlibAdler32\fR(\fIinitValue, bytes, length\fR)
+.sp
+int
+\fBTcl_ZlibStreamInit\fR(\fIinterp, mode, format, level, dictObj, zshandlePtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ZlibStreamGetCommandName\fR(\fIzshandle\fR)
+.sp
+int
+\fBTcl_ZlibStreamEof\fR(\fIzshandle\fR)
+.sp
+int
+\fBTcl_ZlibStreamClose\fR(\fIzshandle\fR)
+.sp
+int
+\fBTcl_ZlibStreamReset\fR(\fIzshandle\fR)
+.sp
+int
+\fBTcl_ZlibStreamChecksum\fR(\fIzshandle\fR)
+.sp
+int
+\fBTcl_ZlibStreamPut\fR(\fIzshandle, dataObj, flush\fR)
+.sp
+int
+\fBTcl_ZlibStreamGet\fR(\fIzshandle, dataObj, count\fR)
+.fi
+.SH ARGUMENTS
+.AS Tcl_ZlibStream *zshandlePtr out
+.AP Tcl_Interp *interp in
+The interpreter to store resulting compressed or uncompressed data in. Also
+where any error messages are written. For \fBTcl_ZlibStreamInit\fR, this can
+be NULL to create a stream that is not bound to a command.
+.AP int format in
+What format of compressed data to work with. Must be one of
+\fBTCL_ZLIB_FORMAT_ZLIB\fR for zlib-format data, \fBTCL_ZLIB_FORMAT_GZIP\fR
+for gzip-format data, or \fBTCL_ZLIB_FORMAT_RAW\fR for raw compressed data. In
+addition, for decompression only, \fBTCL_ZLIB_FORMAT_AUTO\fR may also be
+chosen which can automatically detect whether the compressed data was in zlib
+or gzip format.
+.AP Tcl_Obj *dataObj in/out
+A byte-array object containing the data to be compressed or decompressed, or
+to which the data extracted from the stream is appended when passed to
+\fBTcl_ZlibStreamGet\fR.
+.AP int level in
+What level of compression to use. Should be a number from 0 to 9 or one of the
+following: \fBTCL_ZLIB_COMPRESS_NONE\fR for no compression,
+\fBTCL_ZLIB_COMPRESS_FAST\fR for fast but inefficient compression,
+\fBTCL_ZLIB_COMPRESS_BEST\fR for slow but maximal compression, or
+\fBTCL_ZLIB_COMPRESS_DEFAULT\fR for the level recommended by the zlib library.
+.AP Tcl_Obj *dictObj in/out
+A dictionary that contains, or which will be updated to contain, a description
+of the gzip header associated with the compressed data. Only useful when the
+\fIformat\fR is \fBTCL_ZLIB_FORMAT_GZIP\fR or \fBTCL_ZLIB_FORMAT_AUTO\fR. If
+a NULL is passed, a default header will be used on compression and the header
+will be ignored (apart from integrity checks) on decompression. See the
+section \fBGZIP OPTIONS DICTIONARY\fR for details about the contents of this
+dictionary.
+.AP "unsigned int" initValue in
+The initial value for the checksum algorithm.
+.AP "unsigned char" *bytes in
+An array of bytes to run the checksum algorithm over, or NULL to get the
+recommended initial value for the checksum algorithm.
+.AP int length in
+The number of bytes in the array.
+.AP int mode in
+What mode to operate the stream in. Should be either
+\fBTCL_ZLIB_STREAM_DEFLATE\fR for a compressing stream or
+\fBTCL_ZLIB_STREAM_INFLATE\fR for a decompressing stream.
+.AP Tcl_ZlibStream *zshandlePtr out
+A pointer to a variable in which to write the abstract token for the stream
+upon successful creation.
+.AP Tcl_ZlibStream zshandle in
+The abstract token for the stream to operate on.
+.AP int flush in
+Whether and how to flush the stream after writing the data to it. Must be one
+of: \fBTCL_ZLIB_NO_FLUSH\fR if no flushing is to be done, \fBTCL_ZLIB_FLUSH\fR
+if the currently compressed data must be made available for access using
+\fBTcl_ZlibStreamGet\fR, \fBTCL_ZLIB_FULLFLUSH\fR if the stream must be put
+into a state where the decompressor can recover from on corruption, or
+\fBTCL_ZLIB_FINALIZE\fR to ensure that the stream is finished and that any
+trailer demanded by the format is written.
+.AP int count in
+The maximum number of bytes to get from the stream, or -1 to get all remaining
+bytes from the stream's buffers.
+.BE
+.SH DESCRIPTION
+These functions form the interface from the Tcl library to the Zlib
+library by Jean-loup Gailly and Mark Adler.
+.PP
+\fBTcl_ZlibDeflate\fR and \fBTcl_ZlibInflate\fR respectively compress and
+decompress the data contained in the \fIdataObj\fR argument, according to the
+\fIformat\fR and, for compression, \fIlevel\fR arguments. The dictionary in
+the \fIdictObj\fR parameter is used to convey additional header information
+about the compressed data when the compression format supports it; currently,
+the dictionary is only used when the \fIformat\fR parameter is
+\fBTCL_ZLIB_FORMAT_GZIP\fR or \fBTCL_ZLIB_FORMAT_AUTO\fR. For details of the
+contents of the dictionary, see the \fBGZIP OPTIONS DICTIONARY\fR section
+below. Upon success, both functions leave the resulting compressed or
+decompressed data in a byte-array object that is the Tcl interpreter's result;
+the returned value is a standard Tcl result code.
+.PP
+\fBTcl_ZlibAdler32\fR and \fBTcl_ZlibCRC32\fR compute checksums on arrays of
+bytes, returning the computed checksum. Checksums are computed incrementally,
+allowing data to be processed one block at a time, but this requires the
+caller to maintain the current checksum and pass it in as the \fIinitValue\fR
+parameter; the initial value to use for this can be obtained by using NULL for
+the \fIbytes\fR parameter instead of a pointer to the array of bytes to
+compute the checksum over. Thus, typical usage in the single data block case
+is like this:
+.PP
+.CS
+checksum = \fBTcl_ZlibCRC32\fR(\fBTcl_ZlibCRC32\fR(0,NULL,0), data, length);
+.CE
+.PP
+Note that the Adler-32 algorithm is not a real checksum, but instead is a
+related type of hash that works best on longer data.
+.SS "ZLIB STREAMS"
+.PP
+\fBTcl_ZlibStreamInit\fR creates a compressing or decompressing stream that is
+linked to a Tcl command, according to its arguments, and provides an abstract
+token for the stream and returns a normal Tcl result code;
+\fBTcl_ZlibStreamGetCommandName\fR returns the name of that command given the
+stream token, or NULL if the stream has no command. Streams are not designed
+to be thread-safe; each stream should only ever be used from the thread that
+created it. When working with gzip streams, a dictionary (fields as given in
+the \fBGZIP OPTIONS DICTIONARY\fR section below) can be given via the
+\fIdictObj\fR parameter that on compression allows control over the generated
+headers, and on decompression allows discovery of the existing headers. Note
+that the dictionary will be written to on decompression once sufficient data
+has been read to have a complete header. This means that the dictionary must
+be an unshared object in that case; a blank object created with
+\fBTcl_NewObj\fR is suggested.
+.PP
+Once a stream has been constructed, \fBTcl_ZlibStreamPut\fR is used to add
+data to the stream and \fBTcl_ZlibStreamGet\fR is used to retrieve data from
+the stream after processing. Both return normal Tcl result codes and leave an
+error message in the result of the interpreter that the stream is registered
+with in the error case (if such a registration has been performed). With
+\fBTcl_ZlibStreamPut\fR, the data buffer object passed to it should not be
+modified afterwards. With \fBTcl_ZlibStreamGet\fR, the data buffer object
+passed to it will have the data bytes appended to it. Internally to the
+stream, data is kept compressed so as to minimize the cost of buffer space.
+.PP
+\fBTcl_ZlibStreamChecksum\fR returns the checksum computed over the
+uncompressed data according to the format, and \fBTcl_ZlibStreamEof\fR returns
+a boolean value indicating whether the end of the uncompressed data has been
+reached.
+.PP
+If you wish to clear a stream and reuse it for a new compression or
+decompression action, \fBTcl_ZlibStreamReset\fR will do this and return a
+normal Tcl result code to indicate whether it was successful; if the stream is
+registered with an interpreter, an error message will be left in the
+interpreter result when this function returns TCL_ERROR.
+Finally, \fBTcl_ZlibStreamClose\fR will clean up the stream and delete the
+associated command: using \fBTcl_DeleteCommand\fR on the stream's command is
+equivalent (when such a command exists).
+.SH "GZIP OPTIONS DICTIONARY"
+.PP
+The \fIdictObj\fR parameter to \fBTcl_ZlibDeflate\fR, \fBTcl_ZlibInflate\fR
+and \fBTcl_ZlibStreamInit\fR is used to pass a dictionary of options about
+that is used to describe the gzip header in the compressed data. When creating
+compressed data, the dictionary is read and when unpacking compressed data the
+dictionary is written (in which case the \fIdictObj\fR parameter must refer to
+an unshared dictionary object).
+.PP
+The following fields in the dictionary object are understood. All other fields
+are ignored. No field is required when creating a gzip-format stream.
+.TP
+\fBcomment\fR
+.
+This holds the comment field of the header, if present. If absent, no comment
+was supplied (on decompression) or will be created (on compression).
+.TP
+\fBcrc\fR
+.
+A boolean value describing whether a CRC of the header is computed. Note that
+the \fBgzip\fR program does \fInot\fR use or allow a CRC on the header.
+.TP
+\fBfilename\fR
+.
+The name of the file that held the uncompressed data. This should not contain
+any directory separators, and should be sanitized before use on decompression
+with \fBfile tail\fR.
+.TP
+\fBos\fR
+.
+The operating system type code field from the header (if not the
+.QW unknown
+value). See RFC 1952 for the meaning of these codes. On compression, if this
+is absent then the field will be set to the
+.QW unknown
+value.
+.TP
+\fBsize\fR
+.
+The size of the uncompressed data. This is ignored on compression; the size
+of the data compressed depends on how much data is supplied to the
+compression engine.
+.TP
+\fBtime\fR
+.
+The time field from the header if non-zero, expected to be the time that the
+file named by the \fBfilename\fR field was modified. Suitable for use with
+\fBclock format\fR. On creation, the right value to use is that from
+\fBclock seconds\fR or \fBfile mtime\fR.
+.TP
+\fBtype\fR
+.
+The type of the uncompressed data (either \fBbinary\fR or \fBtext\fR) if
+known.
+.SH "PORTABILITY NOTES"
+These functions will fail gracefully if Tcl is not linked with the zlib
+library.
+.SH "SEE ALSO"
+Tcl_NewByteArrayObj(3), zlib(n)
+'\"Tcl_StackChannel(3)
+.SH "KEYWORDS"
+compress, decompress, deflate, gzip, inflate
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/pkgs/msgcat/doc/Tcl_Main.3 b/pkgs/msgcat/doc/Tcl_Main.3
new file mode 100644
index 0000000..0a69835
--- /dev/null
+++ b/pkgs/msgcat/doc/Tcl_Main.3
@@ -0,0 +1,196 @@
+'\"
+'\" Copyright (c) 1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Ajuba Solutions.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH Tcl_Main 3 8.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_Main, Tcl_SetStartupScript, Tcl_GetStartupScript, Tcl_SetMainLoop \- main program, startup script, and event loop definition for Tcl-based applications
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_Main\fR(\fIargc, argv, appInitProc\fR)
+.sp
+\fBTcl_SetStartupScript\fR(\fIpath, encoding\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetStartupScript\fR(\fIencodingPtr\fR)
+.sp
+\fBTcl_SetMainLoop\fR(\fImainLoopProc\fR)
+.SH ARGUMENTS
+.AS Tcl_MainLoopProc *mainLoopProc
+.AP int argc in
+Number of elements in \fIargv\fR.
+.AP char *argv[] in
+Array of strings containing command-line arguments. On Windows, when
+using -DUNICODE, the parameter type changes to wchar_t *.
+.AP Tcl_AppInitProc *appInitProc in
+Address of an application-specific initialization procedure.
+The value for this argument is usually \fBTcl_AppInit\fR.
+.AP Tcl_Obj *path in
+Name of file to use as startup script, or NULL.
+.AP "const char" *encoding in
+Encoding of file to use as startup script, or NULL.
+.AP "const char" **encodingPtr out
+If non-NULL, location to write a copy of the (const char *)
+pointing to the encoding name.
+.AP Tcl_MainLoopProc *mainLoopProc in
+Address of an application-specific event loop procedure.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_Main\fR can serve as the main program for Tcl-based shell
+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
+to developers of shell applications, so they do not have to
+reproduce all of the code for proper initialization of the Tcl
+library and interactive shell operation. Other styles of embedding
+Tcl in an application are not supported by \fBTcl_Main\fR. Those
+must be achieved by calling lower level functions in the Tcl library
+directly.
+.PP
+The \fBTcl_Main\fR function has been offered by the Tcl library
+since release Tcl 7.4. In older releases of Tcl, the Tcl library
+itself defined a function \fBmain\fR, but that lacks flexibility
+of embedding style and having a function \fBmain\fR in a library
+(particularly a shared library) causes problems on many systems.
+Having \fBmain\fR in the Tcl library would also make it hard to use
+Tcl in C++ programs, since C++ programs must have special C++
+\fBmain\fR functions.
+.PP
+Normally each shell application contains a small \fBmain\fR function
+that does nothing but invoke \fBTcl_Main\fR.
+\fBTcl_Main\fR then does all the work of creating and running a
+\fBtclsh\fR-like application.
+.PP
+\fBTcl_Main\fR is not provided by the public interface of Tcl's
+stub library. Programs that call \fBTcl_Main\fR must be linked
+against the standard Tcl library. Extensions (stub-enabled or
+not) are not intended to call \fBTcl_Main\fR.
+.PP
+\fBTcl_Main\fR is not thread-safe. It should only be called by
+a single master thread of a multi-threaded application. This
+restriction is not a problem with normal use described above.
+.PP
+\fBTcl_Main\fR and therefore all applications based upon it, like
+\fBtclsh\fR, use \fBTcl_GetStdChannel\fR to initialize the standard
+channels to their default values. See \fBTcl_StandardChannels\fR for
+more information.
+.PP
+\fBTcl_Main\fR supports two modes of operation, depending on
+whether the filename and encoding of a startup script has been
+established. The routines \fBTcl_SetStartupScript\fR and
+\fBTcl_GetStartupScript\fR are the tools for controlling this
+configuration of \fBTcl_Main\fR.
+.PP
+\fBTcl_SetStartupScript\fR registers the value \fIpath\fR
+as the name of the file for \fBTcl_Main\fR to evaluate as
+its startup script. The value \fIencoding\fR is Tcl's name
+for the encoding used to store the text in that file. A
+value of \fBNULL\fR for \fIencoding\fR is a signal to use
+the system encoding. A value of \fBNULL\fR for \fIpath\fR
+erases any existing registration so that \fBTcl_Main\fR
+will not evaluate any startup script.
+.PP
+\fBTcl_GetStartupScript\fR queries the registered file name
+and encoding set by the most recent \fBTcl_SetStartupScript\fR
+call in the same thread. The stored file name is returned,
+and the stored encoding name is written to space pointed to
+by \fIencodingPtr\fR, when that is not NULL.
+.PP
+The file name and encoding values managed by the routines
+\fBTcl_SetStartupScript\fR and \fBTcl_GetStartupScript\fR
+are stored per-thread. Although the storage and retrieval
+functions of these routines work in any thread, only those
+calls in the same master thread as \fBTcl_Main\fR can have
+any influence on it.
+.PP
+The caller of \fBTcl_Main\fR may call \fBTcl_SetStartupScript\fR
+first to establish its desired startup script. If \fBTcl_Main\fR
+finds that no such startup script has been established, it consults
+the first few arguments in \fIargv\fR. If they 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. \fBTcl_Main\fR
+then calls \fBTcl_SetStartupScript\fR with these values.
+.PP
+\fBTcl_Main\fR then defines in its master interpreter
+the Tcl variables \fIargc\fR, \fIargv\fR, \fIargv0\fR, and
+\fItcl_interactive\fR, as described in the documentation for \fBtclsh\fR.
+.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
+.QW hook
+for the application to perform its own initialization of the interpreter
+created by \fBTcl_Main\fR, such as defining application-specific
+commands. The application initialization routine might also
+call \fBTcl_SetStartupScript\fR to (re-)set the file and encoding
+to be used as a startup script. The procedure must have an interface
+that matches the type \fBTcl_AppInitProc\fR:
+.PP
+.CS
+typedef int \fBTcl_AppInitProc\fR(
+ Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+\fIAppInitProc\fR is almost always a pointer to \fBTcl_AppInit\fR; for more
+details on this procedure, see the documentation for \fBTcl_AppInit\fR.
+.PP
+When the \fIappInitProc\fR is finished, \fBTcl_Main\fR calls
+\fBTcl_GetStartupScript\fR to determine what startup script has
+been requested, if any. If a startup script has been provided,
+\fBTcl_Main\fR attempts to evaluate it. Otherwise, interactive
+mode begins with examination of the variable \fItcl_rcFileName\fR
+in the master interpreter. If that variable exists and holds the
+name of a readable file, the contents of that file are evaluated
+in the master interpreter. Then interactive operations begin,
+with prompts and command evaluation results written to the standard
+output channel, and commands read from the standard input channel
+and then evaluated. The prompts written to the standard output
+channel may be customized by defining the Tcl variables \fItcl_prompt1\fR
+and \fItcl_prompt2\fR as described in the documentation for \fBtclsh\fR.
+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
+\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
+are in interactive mode, setting the main loop procedure will cause the
+prompt to become fileevent based and then the loop procedure is called.
+When the loop procedure returns in interactive mode, interactive operation
+will continue.
+The main loop procedure must have an interface that matches the type
+\fBTcl_MainLoopProc\fR:
+.PP
+.CS
+typedef void \fBTcl_MainLoopProc\fR(void);
+.CE
+.PP
+\fBTcl_Main\fR does not return. Normally a program based on
+\fBTcl_Main\fR will terminate when the \fBexit\fR command is
+evaluated. In interactive mode, if an EOF or channel error
+is encountered on the standard input channel, then \fBTcl_Main\fR
+itself will evaluate the \fBexit\fR command after the main loop
+procedure (if any) returns. In non-interactive mode, after
+\fBTcl_Main\fR evaluates the startup script, and the main loop
+procedure (if any) returns, \fBTcl_Main\fR will also evaluate
+the \fBexit\fR command.
+.SH "SEE ALSO"
+tclsh(1), Tcl_GetStdChannel(3), Tcl_StandardChannels(3), Tcl_AppInit(3),
+exit(n), encoding(n)
+.SH KEYWORDS
+application-specific initialization, command-line arguments, main program
diff --git a/pkgs/msgcat/doc/Thread.3 b/pkgs/msgcat/doc/Thread.3
new file mode 100644
index 0000000..ca135ee
--- /dev/null
+++ b/pkgs/msgcat/doc/Thread.3
@@ -0,0 +1,241 @@
+'\"
+'\" Copyright (c) 1999 Scriptics Corporation
+'\" 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.
+'\"
+.so man.macros
+.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
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_ConditionNotify\fR(\fIcondPtr\fR)
+.sp
+void
+\fBTcl_ConditionWait\fR(\fIcondPtr, mutexPtr, timePtr\fR)
+.sp
+void
+\fBTcl_ConditionFinalize\fR(\fIcondPtr\fR)
+.sp
+Void *
+\fBTcl_GetThreadData\fR(\fIkeyPtr, size\fR)
+.sp
+void
+\fBTcl_MutexLock\fR(\fImutexPtr\fR)
+.sp
+void
+\fBTcl_MutexUnlock\fR(\fImutexPtr\fR)
+.sp
+void
+\fBTcl_MutexFinalize\fR(\fImutexPtr\fR)
+.sp
+int
+\fBTcl_CreateThread\fR(\fIidPtr, proc, clientData, stackSize, flags\fR)
+.sp
+int
+\fBTcl_JoinThread\fR(\fIid, result\fR)
+.SH ARGUMENTS
+.AS Tcl_CreateThreadProc proc 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 "const Tcl_Time" *timePtr in
+A time limit on the condition wait. NULL to wait forever.
+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
+a different block of storage with this key.
+.AP int *size in
+The size of the thread local storage block. This amount of data
+is allocated and initialized to zero the first time each thread
+calls \fBTcl_GetThreadData\fR.
+.AP Tcl_ThreadId *idPtr out
+The referred storage will contain the id of the newly created thread as
+returned by the operating system.
+.AP Tcl_ThreadId id in
+Id of the thread waited upon.
+.AP Tcl_ThreadCreateProc *proc in
+This procedure will act as the \fBmain()\fR of the newly created
+thread. The specified \fIclientData\fR will be its sole argument.
+.AP ClientData clientData in
+Arbitrary information. Passed as sole argument to the \fIproc\fR.
+.AP int stackSize in
+The size of the stack given to the new thread.
+.AP int flags in
+Bitmask containing flags allowing the caller to modify behavior of
+the new thread.
+.AP int *result out
+The referred storage is used to place the exit code of the thread
+waited upon into it.
+.BE
+.SH INTRODUCTION
+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
+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, 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 behavior through the supplied \fIflags\fR. The value
+\fBTCL_THREAD_STACK_DEFAULT\fR for the \fIstackSize\fR indicates that
+the default size as specified by the operating system is to be used
+for the new thread. As for the flags, currently only the values
+\fBTCL_THREAD_NOFLAGS\fR and \fBTCL_THREAD_JOINABLE\fR are defined. The
+first of them invokes the default behavior with no special settings.
+Using the second value marks the new thread as \fIjoinable\fR. This
+means that another thread can wait for the such marked thread to exit
+and join it.
+.PP
+Restrictions: On some UNIX systems the pthread-library does not
+contain the functionality to specify the stack size of a thread. The
+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 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
+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
+its creation via \fBTcl_CreateThread\fR.
+.PP
+Trying to wait for the exit of a non-joinable thread or a thread which
+is already waited upon will result in an error. Waiting for a joinable
+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.
+.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 queuing in multithreaded applications. See
+the \fBNotifier\fR manual page for more information on these procedures.
+.PP
+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.
+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.
+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.
+.PP
+A condition variable is used as a signaling mechanism:
+a thread can lock a mutex and then wait on a condition variable
+with \fBTcl_ConditionWait\fR. This atomically releases the mutex lock
+and blocks the waiting thread until another thread calls
+\fBTcl_ConditionNotify\fR. The caller of \fBTcl_ConditionNotify\fR should
+have the associated mutex held by previously calling \fBTcl_MutexLock\fR,
+but this is not enforced. Notifying the
+condition variable unblocks all threads waiting on the condition variable,
+but they do not proceed until the mutex is released with \fBTcl_MutexUnlock\fR.
+The implementation of \fBTcl_ConditionWait\fR automatically locks
+the mutex before returning.
+.PP
+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
+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.
+.SS INITIALIZATION
+.PP
+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
+either cleaned up by process exit handlers (if living that long) or
+explicitly by calls to \fBTcl_MutexFinalize\fR or
+\fBTcl_ConditionFinalize\fR.
+Thread local storage is reclaimed during \fBTcl_FinalizeThread\fR.
+.SH "SCRIPT-LEVEL ACCESS TO THREADS"
+.PP
+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.
+.SH EXAMPLE
+.PP
+To create a thread with portable code, its implementation function should be
+declared as follows:
+.PP
+.CS
+static \fBTcl_ThreadCreateProc\fR MyThreadImplFunc;
+.CE
+.PP
+It should then be defined like this example, which just counts up to a given
+value and then finishes.
+.PP
+.CS
+static \fBTcl_ThreadCreateType\fR
+MyThreadImplFunc(
+ ClientData clientData)
+{
+ int i, limit = (int) clientData;
+ for (i=0 ; i<limit ; i++) {
+ /* doing nothing at all here */
+ }
+ \fBTCL_THREAD_CREATE_RETURN\fR;
+}
+.CE
+.PP
+To create the above thread, make it execute, and wait for it to finish, we
+would do this:
+.PP
+.CS
+int limit = 1000000000;
+ClientData limitData = (void*)((intptr_t) limit);
+Tcl_ThreadId id; \fI/* holds identity of thread created */\fR
+int result;
+
+if (\fBTcl_CreateThread\fR(&id, MyThreadImplFunc, limitData,
+ \fBTCL_THREAD_STACK_DEFAULT\fR,
+ \fBTCL_THREAD_JOINABLE\fR) != TCL_OK) {
+ \fI/* Thread did not create correctly */\fR
+ return;
+}
+\fI/* Do something else for a while here */\fR
+if (\fBTcl_JoinThread\fR(id, &result) != TCL_OK) {
+ \fI/* Thread did not finish properly */\fR
+ return;
+}
+\fI/* All cleaned up nicely */\fR
+.CE
+.SH "SEE ALSO"
+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/pkgs/msgcat/doc/ToUpper.3 b/pkgs/msgcat/doc/ToUpper.3
new file mode 100644
index 0000000..d6b3006
--- /dev/null
+++ b/pkgs/msgcat/doc/ToUpper.3
@@ -0,0 +1,88 @@
+'\"
+'\" Copyright (c) 1997 by 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_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
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_UniChar
+\fBTcl_UniCharToUpper\fR(\fIch\fR)
+.sp
+Tcl_UniChar
+\fBTcl_UniCharToLower\fR(\fIch\fR)
+.sp
+Tcl_UniChar
+\fBTcl_UniCharToTitle\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UtfToUpper\fR(\fIstr\fR)
+.sp
+int
+\fBTcl_UtfToLower\fR(\fIstr\fR)
+.sp
+int
+\fBTcl_UtfToTitle\fR(\fIstr\fR)
+.SH ARGUMENTS
+.AS char *str in/out
+.AP int ch in
+The Tcl_UniChar to be converted.
+.AP char *str in/out
+Pointer to UTF-8 string to be converted in place.
+.BE
+
+.SH DESCRIPTION
+.PP
+The first three routines convert the case of individual Unicode characters:
+.PP
+If \fIch\fR represents a lower-case character,
+\fBTcl_UniCharToUpper\fR returns the corresponding upper-case
+character. If no upper-case character is defined, it returns the
+character unchanged.
+.PP
+If \fIch\fR represents an upper-case character,
+\fBTcl_UniCharToLower\fR returns the corresponding lower-case
+character. If no lower-case character is defined, it returns the
+character unchanged.
+.PP
+If \fIch\fR represents a lower-case character,
+\fBTcl_UniCharToTitle\fR returns the corresponding title-case
+character. If no title-case character is defined, it returns the
+corresponding upper-case character. If no upper-case character is
+defined, it returns the character unchanged. Title-case is defined
+for a small number of characters that have a different appearance when
+they are at the beginning of a capitalized word.
+.PP
+The next three routines convert the case of UTF-8 strings in place in
+memory:
+.PP
+\fBTcl_UtfToUpper\fR changes every UTF-8 character in \fIstr\fR to
+upper-case. Because changing the case of a character may change its
+size, the byte offset of each character in the resulting string may
+differ from its original location. \fBTcl_UtfToUpper\fR writes a null
+byte at the end of the converted string. \fBTcl_UtfToUpper\fR returns
+the new length of the string in bytes. This new length is guaranteed
+to be no longer than the original string length.
+.PP
+\fBTcl_UtfToLower\fR is the same as \fBTcl_UtfToUpper\fR except it
+turns each character in the string into its lower-case equivalent.
+.PP
+\fBTcl_UtfToTitle\fR is the same as \fBTcl_UtfToUpper\fR except it
+turns the first character in the string into its title-case equivalent
+and all following characters into their lower-case equivalents.
+
+.SH BUGS
+.PP
+At this time, the case conversions are only defined for the ISO8859-1
+characters. Unicode characters above 0x00ff are not modified by these
+routines.
+
+.SH KEYWORDS
+utf, unicode, toupper, tolower, totitle, case
diff --git a/pkgs/msgcat/doc/TraceCmd.3 b/pkgs/msgcat/doc/TraceCmd.3
new file mode 100644
index 0000000..5cc1337
--- /dev/null
+++ b/pkgs/msgcat/doc/TraceCmd.3
@@ -0,0 +1,163 @@
+'\"
+'\" Copyright (c) 2002 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_TraceCommand 3 7.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CommandTraceInfo, Tcl_TraceCommand, Tcl_UntraceCommand \- monitor renames and deletes of a command
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+ClientData
+\fBTcl_CommandTraceInfo(\fIinterp, cmdName, flags, proc, prevClientData\fB)\fR
+.sp
+int
+\fBTcl_TraceCommand(\fIinterp, cmdName, flags, proc, clientData\fB)\fR
+.sp
+void
+\fBTcl_UntraceCommand(\fIinterp, cmdName, flags, proc, clientData\fB)\fR
+.SH ARGUMENTS
+.AS Tcl_CommandTraceProc prevClientData
+.AP Tcl_Interp *interp in
+Interpreter containing the command.
+.AP "const char" *cmdName in
+Name of command.
+.AP int flags in
+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
+Arbitrary argument to pass to \fIproc\fR.
+.AP ClientData prevClientData in
+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 \fBTCL_OK\fR. If an error
+occurred (e.g. \fIcmdName\fR specifies a non-existent command) then
+\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
+of any of the following values:
+.TP
+\fBTCL_TRACE_RENAME\fR
+Invoke \fIproc\fR whenever the command is renamed.
+.TP
+\fBTCL_TRACE_DELETE\fR
+Invoke \fIproc\fR when the command is deleted.
+.PP
+Whenever one of the specified operations occurs to the command,
+\fIproc\fR will be invoked. It should have arguments and result that
+match the type \fBTcl_CommandTraceProc\fR:
+.PP
+.CS
+typedef void \fBTcl_CommandTraceProc\fR(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ const char *\fIoldName\fR,
+ const char *\fInewName\fR,
+ int \fIflags\fR);
+.CE
+.PP
+The \fIclientData\fR and \fIinterp\fR parameters will have the same
+values as those passed to \fBTcl_TraceCommand\fR when the trace was
+created. \fIClientData\fR typically points to an application-specific
+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 \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
+\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
+\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 \fBTCL_INTERP_DESTROYED\fR
+below).
+.PP
+\fBTcl_UntraceCommand\fR may be used to remove a trace. If the
+command specified by \fIinterp\fR, \fIcmdName\fR, and \fIflags\fR has
+a trace set with \fIflags\fR, \fIproc\fR, and \fIclientData\fR, then
+the corresponding trace is removed. If no such trace exists, then the
+call to \fBTcl_UntraceCommand\fR has no effect. The same bits are
+valid for \fIflags\fR as for calls to \fBTcl_TraceCommand\fR.
+.PP
+\fBTcl_CommandTraceInfo\fR may be used to retrieve information about
+traces set on a given command.
+The return value from \fBTcl_CommandTraceInfo\fR is the \fIclientData\fR
+associated with a particular trace.
+The trace must be on the command specified by the \fIinterp\fR,
+\fIcmdName\fR, and \fIflags\fR arguments (note that currently the
+flags are ignored; \fIflags\fR should be set to 0 for future
+compatibility) 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 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
+\fIprevClientData\fR, or NULL if no trace matches \fIprevClientData\fR
+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 \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.
+When this happens, all of the trace procedures will be invoked on each
+access, in order from most-recently-created to least-recently-created.
+Attempts to delete the command during a delete trace will fail
+silently, since the command is already scheduled for deletion anyway.
+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 \fBTCL_TRACE_DESTROYED\fR bit
+is set in \fIflags\fR.
+.\" 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 \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 \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 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/pkgs/msgcat/doc/TraceVar.3 b/pkgs/msgcat/doc/TraceVar.3
new file mode 100644
index 0000000..6201a4f
--- /dev/null
+++ b/pkgs/msgcat/doc/TraceVar.3
@@ -0,0 +1,380 @@
+'\"
+'\" Copyright (c) 1989-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 Tcl_TraceVar 3 7.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_TraceVar, Tcl_TraceVar2, Tcl_UntraceVar, Tcl_UntraceVar2, Tcl_VarTraceInfo, Tcl_VarTraceInfo2 \- monitor accesses to a variable
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_TraceVar(\fIinterp, varName, flags, proc, clientData\fB)\fR
+.sp
+int
+\fBTcl_TraceVar2(\fIinterp, name1, name2, flags, proc, clientData\fB)\fR
+.sp
+\fBTcl_UntraceVar(\fIinterp, varName, flags, proc, clientData\fB)\fR
+.sp
+\fBTcl_UntraceVar2(\fIinterp, name1, name2, flags, proc, clientData\fB)\fR
+.sp
+ClientData
+\fBTcl_VarTraceInfo(\fIinterp, varName, flags, proc, prevClientData\fB)\fR
+.sp
+ClientData
+\fBTcl_VarTraceInfo2(\fIinterp, name1, name2, flags, proc, prevClientData\fB)\fR
+.SH ARGUMENTS
+.AS Tcl_VarTraceProc prevClientData
+.AP Tcl_Interp *interp in
+Interpreter containing variable.
+.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 \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
+Name of scalar or array variable (without array index).
+.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.
+.AP ClientData prevClientData in
+If non-NULL, gives last value returned by \fBTcl_VarTraceInfo\fR or
+\fBTcl_VarTraceInfo2\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_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
+\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
+trace procedure is to be invoked and provides information
+for setting up the trace. It consists of an OR-ed combination
+of any of the following values:
+.TP
+\fBTCL_GLOBAL_ONLY\fR
+Normally, the variable will be looked up at the current level of
+procedure call; if this bit is set then the variable will be looked
+up at global level, ignoring any active procedures.
+.TP
+\fBTCL_NAMESPACE_ONLY\fR
+Normally, the variable will be looked up at the current level of
+procedure call; if this bit is set then the variable will be looked
+up in the current namespace, ignoring any active procedures.
+.TP
+\fBTCL_TRACE_READS\fR
+Invoke \fIproc\fR whenever an attempt is made to read the variable.
+.TP
+\fBTCL_TRACE_WRITES\fR
+Invoke \fIproc\fR whenever an attempt is made to modify the variable.
+.TP
+\fBTCL_TRACE_UNSETS\fR
+Invoke \fIproc\fR whenever the variable is unset.
+A variable may be unset either explicitly by an \fBunset\fR command,
+or implicitly when a procedure returns (its local variables are
+automatically unset) or when the interpreter is deleted (all
+variables are automatically unset).
+.TP
+\fBTCL_TRACE_ARRAY\fR
+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.
+.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
+\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 \fBTCL_TRACE_RESULT_DYNAMIC\fR.
+.PP
+Whenever one of the specified operations occurs on the variable,
+\fIproc\fR will be invoked.
+It should have arguments and result that match the type
+\fBTcl_VarTraceProc\fR:
+.PP
+.CS
+typedef char *\fBTcl_VarTraceProc\fR(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ char *\fIname1\fR,
+ char *\fIname2\fR,
+ int \fIflags\fR);
+.CE
+.PP
+The \fIclientData\fR and \fIinterp\fR parameters will
+have the same values as those passed to \fBTcl_TraceVar\fR when the
+trace was created.
+\fIClientData\fR typically points to an application-specific
+data structure that describes what to do when \fIproc\fR
+is invoked.
+\fIName1\fR and \fIname2\fR give the name of the traced variable
+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 \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 \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 \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 \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 \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 \fBTCL_INTERP_DESTROYED\fR below).
+The trace procedure's return value should normally be NULL; see
+\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
+has a trace set with \fIflags\fR, \fIproc\fR, and
+\fIclientData\fR, then the corresponding trace is removed.
+If no such trace exists, then the call to \fBTcl_UntraceVar\fR
+has no effect.
+The same bits are valid for \fIflags\fR as for calls to \fBTcl_TraceVar\fR.
+.PP
+\fBTcl_VarTraceInfo\fR may be used to retrieve information about
+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 \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 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
+\fIprevClientData\fR, or NULL if no trace matches \fIprevClientData\fR
+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
+\fBTcl_VarTraceInfo2\fR are identical to \fBTcl_TraceVar\fR,
+\fBTcl_UntraceVar\fR, and \fBTcl_VarTraceInfo\fR, respectively,
+except that the name of the variable consists of two parts.
+\fIName1\fR gives the name of a scalar variable or array,
+and \fIname2\fR gives the name of an element within an array.
+When \fIname2\fR is NULL,
+\fIname1\fR may contain both an array and an element name:
+if the name contains an open parenthesis and ends with a
+close parenthesis, then the value between the parentheses is
+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 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
+trace procedure can read, write, or unset the traced
+variable using \fBTcl_GetVar2\fR, \fBTcl_SetVar2\fR, and
+other procedures.
+While \fIproc\fR is executing, traces are temporarily disabled
+for the variable, so that calls to \fBTcl_GetVar2\fR and
+\fBTcl_SetVar2\fR will not cause \fIproc\fR or other trace procedures
+to be invoked again.
+Disabling only occurs for the variable whose trace procedure
+is active; accesses to other variables will still be traced.
+However, if a variable is unset during a read or write trace then unset
+traces will be invoked.
+.PP
+During unset traces the variable has already been completely
+expunged.
+It is possible for the trace procedure to read or write the
+variable, but this will be a new version of the variable.
+Traces are not disabled during unset traces as they are for
+read and write traces, but existing traces have been removed
+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
+procedure will be invoked whenever the variable's value is
+read. This includes \fBset\fR Tcl commands, \fB$\fR-notation
+in Tcl commands, and invocations of the \fBTcl_GetVar\fR
+and \fBTcl_GetVar2\fR procedures.
+\fIProc\fR is invoked just before the variable's value is
+returned.
+It may modify the value of the variable to affect what
+is returned by the traced access.
+If it unsets the variable then the access will return an error
+just as if the variable never existed.
+.PP
+When write tracing has been specified for a variable, the
+trace procedure will be invoked whenever the variable's value
+is modified. This includes \fBset\fR commands,
+commands that modify variables as side effects (such as
+\fBcatch\fR and \fBscan\fR), and calls to the \fBTcl_SetVar\fR
+and \fBTcl_SetVar2\fR procedures).
+\fIProc\fR will be invoked after the variable's value has been
+modified, but before the new value of the variable has been
+returned.
+It may modify the value of the variable to override the change
+and to determine the value actually returned by the traced
+access.
+If it deletes the variable then the traced access will return
+an empty string.
+.PP
+When array tracing has been specified, the trace procedure
+will be invoked at the beginning of the array command implementation,
+before any of the operations like get, set, or names have been invoked.
+The trace procedure can modify the array elements with \fBTcl_SetVar\fR
+and \fBTcl_SetVar2\fR.
+.PP
+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
+the name of an array variable without an index into the array,
+then the trace will be set on the array as a whole.
+This means that \fIproc\fR will be invoked whenever any
+element of the array is accessed in the ways specified by
+\fIflags\fR.
+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.
+When this happens, all of the trace procedures will be invoked on each
+access, in order from most-recently-created to least-recently-created.
+When there exist whole-array traces for an array as well as
+traces on individual elements, the whole-array traces are invoked
+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
+successful completion.
+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,
+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.
+If a trace procedure returns an error, no further traces are
+invoked for the access and the traced access aborts with the
+given message.
+Trace procedures can use this facility to make variables
+read-only, for example (but note that the value of the variable
+will already have been modified before the trace procedure is
+called, so the trace procedure will have to restore the correct
+value).
+.PP
+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
+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
+.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 \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 \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 \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 \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 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 \fBinfo exists\fR command,
+nor is there Tcl-level access to array traces.
+.SH "SEE ALSO"
+trace(n)
+.SH KEYWORDS
+clientData, trace, variable
diff --git a/pkgs/msgcat/doc/Translate.3 b/pkgs/msgcat/doc/Translate.3
new file mode 100644
index 0000000..55233c3
--- /dev/null
+++ b/pkgs/msgcat/doc/Translate.3
@@ -0,0 +1,71 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-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_TranslateFileName 3 8.1 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_TranslateFileName \- convert file name to native form and replace tilde with home directory
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+char *
+\fBTcl_TranslateFileName\fR(\fIinterp\fR, \fIname\fR, \fIbufferPtr\fR)
+.SH ARGUMENTS
+.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
+.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
+caller must eventually call \fBTcl_DStringFree\fR to free up
+anything stored here.
+.BE
+.SH DESCRIPTION
+.PP
+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_FSGetNativePath\fR, there is no longer any need to use this
+procedure. In particular, \fBTcl_FSGetNativePath\fR performs all the
+necessary translation and encoding conversion, is virtual-filesystem
+aware, and caches the native result for faster repeated calls.
+Finally \fBTcl_FSGetNativePath\fR does not require you to free anything
+afterwards.
+.PP
+If
+\fBTcl_TranslateFileName\fR has to do tilde substitution or translate
+the name then it uses
+the dynamic string at \fI*bufferPtr\fR to hold the new string it
+generates.
+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 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
+name) then NULL is returned and an error message will be left
+in the interpreter's result.
+When an error occurs, \fBTcl_TranslateFileName\fR
+frees the dynamic string itself so that the caller need not call
+\fBTcl_DStringFree\fR.
+.PP
+The caller is responsible for making sure that the interpreter's result
+has its default empty value when \fBTcl_TranslateFileName\fR is invoked.
+.SH "SEE ALSO"
+filename(n)
+.SH KEYWORDS
+file name, home directory, tilde, translate, user
diff --git a/pkgs/msgcat/doc/UniCharIsAlpha.3 b/pkgs/msgcat/doc/UniCharIsAlpha.3
new file mode 100644
index 0000000..6029b2d
--- /dev/null
+++ b/pkgs/msgcat/doc/UniCharIsAlpha.3
@@ -0,0 +1,91 @@
+'\"
+'\" 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 Tcl_UniCharIsAlpha 3 "8.1" Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_UniCharIsAlnum, Tcl_UniCharIsAlpha, Tcl_UniCharIsControl, Tcl_UniCharIsDigit, Tcl_UniCharIsGraph, Tcl_UniCharIsLower, Tcl_UniCharIsPrint, Tcl_UniCharIsPunct, Tcl_UniCharIsSpace, Tcl_UniCharIsUpper, Tcl_UniCharIsWordChar \- routines for classification of Tcl_UniChar characters
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_UniCharIsAlnum\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsAlpha\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsControl\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsDigit\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsGraph\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsLower\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsPrint\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsPunct\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsSpace\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsUpper\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsWordChar\fR(\fIch\fR)
+.SH ARGUMENTS
+.AS int ch
+.AP int ch in
+The Tcl_UniChar to be examined.
+.BE
+
+.SH DESCRIPTION
+.PP
+All of the routines described examine Tcl_UniChars and return a
+boolean value. A non-zero return value means that the character does
+belong to the character class associated with the called routine. The
+rest of this document just describes the character classes associated
+with the various routines.
+.PP
+Note: A Tcl_UniChar is a Unicode character represented as an unsigned,
+fixed-size quantity.
+
+.SH "CHARACTER CLASSES"
+.PP
+\fBTcl_UniCharIsAlnum\fR tests if the character is an alphanumeric Unicode character.
+.PP
+\fBTcl_UniCharIsAlpha\fR tests if the character is an alphabetic Unicode character.
+.PP
+\fBTcl_UniCharIsControl\fR tests if the character is a Unicode control character.
+.PP
+\fBTcl_UniCharIsDigit\fR tests if the character is a numeric Unicode character.
+.PP
+\fBTcl_UniCharIsGraph\fR tests if the character is any Unicode print character except space.
+.PP
+\fBTcl_UniCharIsLower\fR tests if the character is a lowercase Unicode character.
+.PP
+\fBTcl_UniCharIsPrint\fR tests if the character is a Unicode print character.
+.PP
+\fBTcl_UniCharIsPunct\fR tests if the character is a Unicode punctuation character.
+.PP
+\fBTcl_UniCharIsSpace\fR tests if the character is a whitespace Unicode character.
+.PP
+\fBTcl_UniCharIsUpper\fR tests if the character is an uppercase Unicode character.
+.PP
+\fBTcl_UniCharIsWordChar\fR tests if the character is alphanumeric or
+a connector punctuation mark.
+
+.SH KEYWORDS
+unicode, classification
diff --git a/pkgs/msgcat/doc/UpVar.3 b/pkgs/msgcat/doc/UpVar.3
new file mode 100644
index 0000000..f1e6fe4
--- /dev/null
+++ b/pkgs/msgcat/doc/UpVar.3
@@ -0,0 +1,74 @@
+'\"
+'\" Copyright (c) 1994 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 Tcl_UpVar 3 7.4 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_UpVar, Tcl_UpVar2 \- link one variable to another
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_UpVar(\fIinterp, frameName, sourceName, destName, flags\fB)\fR
+.sp
+int
+\fBTcl_UpVar2(\fIinterp, frameName, name1, name2, destName, flags\fB)\fR
+.SH ARGUMENTS
+.AS "const char" *sourceName
+.AP Tcl_Interp *interp in
+Interpreter containing variables; also used for error reporting.
+.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
+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
+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
+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
+If source variable is an element of an array, gives the index of the element.
+For scalar source variables, is NULL.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_UpVar\fR and \fBTcl_UpVar2\fR provide the same functionality
+as the \fBupvar\fR command: they make a link from a source variable
+to a destination variable, so that references to the destination are
+passed transparently through to the source.
+The name of the source variable may be specified either as a single
+string such as \fBxyx\fR or \fBa(24)\fR (by calling \fBTcl_UpVar\fR)
+or in two parts where the array name has been separated from the
+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 \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;
+if it does exist, unsetting it later does not destroy the link. The
+destination variable may exist at the time of the call, but if so
+it must exist as a linked variable.
+
+.SH KEYWORDS
+linked variable, upvar, variable
diff --git a/pkgs/msgcat/doc/Utf.3 b/pkgs/msgcat/doc/Utf.3
new file mode 100644
index 0000000..55906e7
--- /dev/null
+++ b/pkgs/msgcat/doc/Utf.3
@@ -0,0 +1,259 @@
+'\"
+'\" 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 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
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+typedef ... \fBTcl_UniChar\fR;
+.sp
+int
+\fBTcl_UniCharToUtf\fR(\fIch, buf\fR)
+.sp
+int
+\fBTcl_UtfToUniChar\fR(\fIsrc, chPtr\fR)
+.sp
+char *
+\fBTcl_UniCharToUtfDString\fR(\fIuniStr, uniLength, dsPtr\fR)
+.sp
+Tcl_UniChar *
+\fBTcl_UtfToUniCharDString\fR(\fIsrc, length, dsPtr\fR)
+.sp
+int
+\fBTcl_UniCharLen\fR(\fIuniStr\fR)
+.sp
+int
+\fBTcl_UniCharNcmp\fR(\fIucs, uct, numChars\fR)
+.sp
+int
+\fBTcl_UniCharNcasecmp\fR(\fIucs, uct, numChars\fR)
+.sp
+int
+\fBTcl_UniCharCaseMatch\fR(\fIuniStr, uniPattern, nocase\fR)
+.sp
+int
+\fBTcl_UtfNcmp\fR(\fIcs, ct, numChars\fR)
+.sp
+int
+\fBTcl_UtfNcasecmp\fR(\fIcs, ct, numChars\fR)
+.sp
+int
+\fBTcl_UtfCharComplete\fR(\fIsrc, length\fR)
+.sp
+int
+\fBTcl_NumUtfChars\fR(\fIsrc, length\fR)
+.sp
+const char *
+\fBTcl_UtfFindFirst\fR(\fIsrc, ch\fR)
+.sp
+const char *
+\fBTcl_UtfFindLast\fR(\fIsrc, ch\fR)
+.sp
+const char *
+\fBTcl_UtfNext\fR(\fIsrc\fR)
+.sp
+const char *
+\fBTcl_UtfPrev\fR(\fIsrc, start\fR)
+.sp
+Tcl_UniChar
+\fBTcl_UniCharAtIndex\fR(\fIsrc, index\fR)
+.sp
+const char *
+\fBTcl_UtfAtIndex\fR(\fIsrc, index\fR)
+.sp
+int
+\fBTcl_UtfBackslash\fR(\fIsrc, readPtr, dst\fR)
+.SH ARGUMENTS
+.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
+\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
+Pointer to a UTF-8 string.
+.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
+A null-terminated Unicode string.
+.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 uniLength in
+The length of the Unicode string in characters. Must be greater than or
+equal to 0.
+.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
+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.
+.AP int *readPtr out
+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 \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).
+.BE
+
+.SH DESCRIPTION
+.PP
+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 \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
+represent one Unicode character in the UTF-8 representation.
+.PP
+\fBTcl_UniCharToUtf\fR stores the Tcl_UniChar \fIch\fR as a UTF-8 string
+in starting at \fIbuf\fR. The return value is the number of bytes stored
+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
+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
+not in proper UTF-8 format, \fBTcl_UtfToUniChar\fR will store the first
+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 \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.
+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
+is appended to the end of the \fBTcl_DString\fR. The Unicode string
+is terminated with a Unicode null character.
+.PP
+\fBTcl_UniCharLen\fR corresponds to \fBstrlen\fR for Unicode
+characters. It accepts a null-terminated Unicode string and returns
+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 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
+\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.
+.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 \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
+first string is greater than, equal to, or less than the second string
+respectively.
+.PP
+\fBTcl_UtfNcasecmp\fR corresponds to \fBstrncasecmp\fR for UTF-8
+strings. It is similar to \fBTcl_UtfNcmp\fR except comparisons ignore
+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 \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
+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 \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
+returns a pointer to the first occurrence of the Tcl_UniChar \fIch\fR
+in the null-terminated UTF-8 string \fIsrc\fR. The null terminator is
+considered part of the UTF-8 string.
+.PP
+\fBTcl_UtfFindLast\fR corresponds to \fBstrrchr\fR for UTF-8 strings. It
+returns a pointer to the last occurrence of the Tcl_UniChar \fIch\fR
+in the null-terminated UTF-8 string \fIsrc\fR. The null terminator is
+considered part of the UTF-8 string.
+.PP
+Given \fIsrc\fR, a pointer to some location in a UTF-8 string,
+\fBTcl_UtfNext\fR returns a pointer to the next UTF-8 character in the
+string. The caller must not ask for the next character after the last
+character in the string if the string is not terminated by a null
+character.
+.PP
+Given \fIsrc\fR, a pointer to some location in a UTF-8 string (or to a
+null byte immediately following such a string), \fBTcl_UtfPrev\fR
+returns a pointer to the closest preceding byte that starts a UTF-8
+character.
+This function will not back up to a position before \fIstart\fR,
+the start of the UTF-8 string. If \fIsrc\fR was already at \fIstart\fR, the
+return value will be \fIstart\fR.
+.PP
+\fBTcl_UniCharAtIndex\fR corresponds to a C string array dereference or the
+Pascal Ord() function. It returns the Tcl_UniChar represented at the
+specified character (not byte) \fIindex\fR in the UTF-8 string
+\fIsrc\fR. The source string must contain at least \fIindex\fR
+characters. Behavior is undefined if a negative \fIindex\fR is given.
+.PP
+\fBTcl_UtfAtIndex\fR returns a pointer to the specified character (not
+byte) \fIindex\fR in the UTF-8 string \fIsrc\fR. The source string must
+contain at least \fIindex\fR characters. This is equivalent to calling
+\fBTcl_UtfNext\fR \fIindex\fR times. If a negative \fIindex\fR is given,
+the return pointer points to the first character in the source string.
+.PP
+\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 \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.
+.PP
+See the \fBTcl\fR manual entry for information on the valid backslash
+sequences. All of the sequences described in the Tcl manual entry are
+supported by \fBTcl_UtfBackslash\fR.
+
+.SH KEYWORDS
+utf, unicode, backslash
diff --git a/pkgs/msgcat/doc/WrongNumArgs.3 b/pkgs/msgcat/doc/WrongNumArgs.3
new file mode 100644
index 0000000..a2908e9
--- /dev/null
+++ b/pkgs/msgcat/doc/WrongNumArgs.3
@@ -0,0 +1,79 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH Tcl_WrongNumArgs 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_WrongNumArgs \- generate standard error message for wrong number of arguments
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_WrongNumArgs\fR(\fIinterp, objc, objv, message\fR)
+.SH ARGUMENTS
+.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
+Arguments to command that had the wrong number of arguments.
+.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.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_WrongNumArgs\fR is a utility procedure that is invoked by
+command procedures when they discover that they have received the
+wrong number of arguments. \fBTcl_WrongNumArgs\fR generates a
+standard error message and stores it in the result object of
+\fIinterp\fR. The message includes the \fIobjc\fR initial
+elements of \fIobjv\fR plus \fImessage\fR. For example, if
+\fIobjv\fR consists of the values \fBfoo\fR and \fBbar\fR,
+\fIobjc\fR is 1, and \fImessage\fR is
+.QW "\fBfileName count\fR"
+then \fIinterp\fR's result object will be set to the following
+string:
+.PP
+.CS
+wrong # args: should be "foo fileName count"
+.CE
+.PP
+If \fIobjc\fR is 2, the result will be set to the following string:
+.PP
+.CS
+wrong # args: should be "foo bar fileName count"
+.CE
+.PP
+\fIObjc\fR is usually 1, but may be 2 or more for commands like
+\fBstring\fR and the Tk widget commands, which use the first argument
+as a subcommand.
+.PP
+Some of the objects in the \fIobjv\fR array may be abbreviations for
+a subcommand. The command
+\fBTcl_GetIndexFromObj\fR will convert the abbreviated string object
+into an \fIindexObject\fR. If an error occurs in the parsing of the
+subcommand we would like to use the full subcommand name rather than
+the abbreviation. If the \fBTcl_WrongNumArgs\fR command finds any
+\fIindexObjects\fR in the \fIobjv\fR array it will use the full subcommand
+name in the error message instead of the abbreviated name that was
+originally passed in. Using the above example, let us assume that
+\fIbar\fR is actually an abbreviation for \fIbarfly\fR and the object
+is now an indexObject because it was passed to
+\fBTcl_GetIndexFromObj\fR. In this case the error message would be:
+.PP
+.CS
+wrong # args: should be "foo barfly fileName count"
+.CE
+.SH "SEE ALSO"
+Tcl_GetIndexFromObj(3)
+.SH KEYWORDS
+command, error message, wrong number of arguments
diff --git a/pkgs/msgcat/doc/after.n b/pkgs/msgcat/doc/after.n
new file mode 100644
index 0000000..d6181c6
--- /dev/null
+++ b/pkgs/msgcat/doc/after.n
@@ -0,0 +1,151 @@
+'\"
+'\" Copyright (c) 1990-1994 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 after n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+after \- Execute a command after a time delay
+.SH SYNOPSIS
+\fBafter \fIms\fR
+.sp
+\fBafter \fIms \fR?\fIscript script script ...\fR?
+.sp
+\fBafter cancel \fIid\fR
+.sp
+\fBafter cancel \fIscript script script ...\fR
+.sp
+\fBafter idle \fR?\fIscript script script ...\fR?
+.sp
+\fBafter info \fR?\fIid\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command is used to delay execution of the program or to execute
+a command in background sometime in the future. It has several forms,
+depending on the first argument to the command:
+.TP
+\fBafter \fIms\fR
+.
+\fIMs\fR must be an integer giving a time in milliseconds.
+The command sleeps for \fIms\fR milliseconds and then returns.
+While the command is sleeping the application does not respond to
+events.
+.TP
+\fBafter \fIms \fR?\fIscript script script ...\fR?
+.
+In this form the command returns immediately, but it arranges
+for a Tcl command to be executed \fIms\fR milliseconds later as an
+event handler.
+The command will be executed exactly once, at the given time.
+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 background error will be reported by the command
+registered with \fBinterp bgerror\fR.
+The \fBafter\fR command returns an identifier that can be used
+to cancel the delayed command using \fBafter cancel\fR.
+.TP
+\fBafter cancel \fIid\fR
+.
+Cancels the execution of a delayed command that
+was previously scheduled.
+\fIId\fR indicates which command should be canceled; it must have
+been the return value from a previous \fBafter\fR command.
+If the command given by \fIid\fR has already been executed then
+the \fBafter cancel\fR command has no effect.
+.TP
+\fBafter cancel \fIscript script ...\fR
+.
+This command also cancels the execution of a delayed command.
+The \fIscript\fR arguments are concatenated together with space
+separators (just as in the \fBconcat\fR command).
+If there is a pending command that matches the string, it is
+canceled and will never be executed; if no such command is
+currently pending then the \fBafter cancel\fR command has no effect.
+.TP
+\fBafter idle \fIscript \fR?\fIscript script ...\fR?
+.
+Concatenates the \fIscript\fR arguments together with space
+separators (just as in the \fBconcat\fR command), and arranges
+for the resulting script to be evaluated later as an idle callback.
+The script will be run exactly once, the next time the event
+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
+background error will be reported by the command
+registered with \fBinterp bgerror\fR.
+.TP
+\fBafter info \fR?\fIid\fR?
+.
+This command returns information about existing event handlers.
+If no \fIid\fR argument is supplied, the command returns
+a list of the identifiers for all existing
+event handlers created by the \fBafter\fR command for this
+interpreter.
+If \fIid\fR is supplied, it specifies an existing handler;
+\fIid\fR must have been the return value from some previous call
+to \fBafter\fR and it must not have triggered yet or been canceled.
+In this case the command returns a list with two elements.
+The first element of the list is the script associated
+with \fIid\fR, and the second element is either
+\fBidle\fR or \fBtimer\fR to indicate what kind of event
+handler it is.
+.LP
+The \fBafter \fIms\fR and \fBafter idle\fR forms of the command
+assume that the application is event driven: the delayed commands
+will not be executed unless the application enters the event loop.
+In applications that are not normally event-driven, such as
+\fBtclsh\fR, the event loop can be entered with the \fBvwait\fR
+and \fBupdate\fR commands.
+.SH "EXAMPLES"
+This defines a command to make Tcl do nothing at all for \fIN\fR
+seconds:
+.PP
+.CS
+proc sleep {N} {
+ \fBafter\fR [expr {int($N * 1000)}]
+}
+.CE
+.PP
+This arranges for the command \fIwake_up\fR to be run in eight hours
+(providing the event loop is active at that time):
+.PP
+.CS
+\fBafter\fR [expr {1000 * 60 * 60 * 8}] wake_up
+.CE
+.PP
+The following command can be used to do long-running calculations (as
+represented here by \fI::my_calc::one_step\fR, which is assumed to
+return a boolean indicating whether another step should be performed)
+in a step-by-step fashion, though the calculation itself needs to be
+arranged so it can work step-wise. This technique is extra careful to
+ensure that the event loop is not starved by the rescheduling of
+processing steps (arranging for the next step to be done using an
+already-triggered timer event only when the event queue has been
+drained) and is useful when you want to ensure that a Tk GUI remains
+responsive during a slow task.
+.PP
+.CS
+proc doOneStep {} {
+ if {[::my_calc::one_step]} {
+ \fBafter idle\fR [list \fBafter\fR 0 doOneStep]
+ }
+}
+doOneStep
+.CE
+.SH "SEE ALSO"
+concat(n), interp(n), update(n), vwait(n)
+.SH KEYWORDS
+cancel, delay, idle callback, sleep, time
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/append.n b/pkgs/msgcat/doc/append.n
new file mode 100644
index 0000000..034068d
--- /dev/null
+++ b/pkgs/msgcat/doc/append.n
@@ -0,0 +1,49 @@
+'\"
+'\" 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 append n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+append \- Append to variable
+.SH SYNOPSIS
+\fBappend \fIvarName \fR?\fIvalue value value ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Append all of the \fIvalue\fR arguments to the current value
+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,
+.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.
+.PP
+.CS
+set var 0
+for {set i 1} {$i<=10} {incr i} {
+ \fBappend\fR var "," $i
+}
+puts $var
+# Prints 0,1,2,3,4,5,6,7,8,9,10
+.CE
+.SH "SEE ALSO"
+concat(n), lappend(n)
+.SH KEYWORDS
+append, variable
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/apply.n b/pkgs/msgcat/doc/apply.n
new file mode 100644
index 0000000..9d373e1
--- /dev/null
+++ b/pkgs/msgcat/doc/apply.n
@@ -0,0 +1,102 @@
+'\"
+'\" 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
+.PP
+This shows how to make a simple general command that applies a transformation
+to each element of a list.
+.PP
+.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:
+.PP
+.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
+anonymous function, argument, lambda, procedure,
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/array.n b/pkgs/msgcat/doc/array.n
new file mode 100644
index 0000000..47f9624
--- /dev/null
+++ b/pkgs/msgcat/doc/array.n
@@ -0,0 +1,187 @@
+'\"
+'\" Copyright (c) 1993-1994 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 array n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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
+variable given by \fIarrayName\fR.
+Unless otherwise specified for individual commands below,
+\fIarrayName\fR must be the name of an existing array variable.
+The \fIoption\fR argument determines what action is carried
+out by the command.
+The legal \fIoptions\fR (which may be abbreviated) are:
+.TP
+\fBarray anymore \fIarrayName searchId\fR
+Returns 1 if there are any more elements left to be processed
+in an array search, 0 if all elements have already been
+returned.
+\fISearchId\fR indicates which search on \fIarrayName\fR to
+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 will not indicate whether the search
+has been completed.
+.TP
+\fBarray donesearch \fIarrayName searchId\fR
+This command terminates an array search and destroys all the
+state associated with that search. \fISearchId\fR indicates
+which search on \fIarrayName\fR to destroy, and must have
+been the return value from a previous invocation of
+\fBarray startsearch\fR. Returns an empty string.
+.TP
+\fBarray exists \fIarrayName\fR
+Returns 1 if \fIarrayName\fR is an array variable, 0 if there
+is no variable by that name or if it is a scalar variable.
+.TP
+\fBarray get \fIarrayName\fR ?\fIpattern\fR?
+Returns a list containing pairs of elements. The first
+element in each pair is the name of an element in \fIarrayName\fR
+and the second element of each pair is the value of the
+array element. The order of the pairs is undefined.
+If \fIpattern\fR is not specified, then all of the elements of the
+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 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
+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
+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 is not the name of an array
+variable, then an empty string is returned.
+.TP
+\fBarray nextelement \fIarrayName searchId\fR
+Returns the name of the next element in \fIarrayName\fR, or
+an empty string if all elements of \fIarrayName\fR have
+already been returned in this search. The \fIsearchId\fR
+argument identifies the search, and must have
+been the return value of an \fBarray startsearch\fR command.
+Warning: if elements are added to or deleted from the array,
+then all searches are automatically terminated just as if
+\fBarray donesearch\fR had been invoked; this will cause
+\fBarray nextelement\fR operations to fail for those searches.
+.TP
+\fBarray set \fIarrayName list\fR
+Sets the values of one or more elements in \fIarrayName\fR.
+\fIlist\fR must have a form like that returned by \fBarray get\fR,
+consisting of an even number of elements.
+Each odd-numbered element in \fIlist\fR is treated as an element
+name within \fIarrayName\fR, and the following element in \fIlist\fR
+is used as a new value for that array element.
+If the variable \fIarrayName\fR does not already exist
+and \fIlist\fR is empty,
+\fIarrayName\fR is created with an empty array value.
+.TP
+\fBarray size \fIarrayName\fR
+Returns a decimal string giving the number of elements in the
+array.
+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
+array given by \fIarrayName\fR, such that invocations of the
+\fBarray nextelement\fR command will return the names of the
+individual elements in the array.
+When the search has been completed, the \fBarray donesearch\fR
+command should be invoked.
+The return value is a
+search identifier that must be used in \fBarray nextelement\fR
+and \fBarray donesearch\fR commands; it allows multiple
+searches to be underway simultaneously for the same array.
+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.
+.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.
+.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 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.
+.SH EXAMPLES
+.CS
+\fBarray set\fR colorcount {
+ red 1
+ green 5
+ blue 4
+ white 9
+}
+
+foreach {color count} [\fBarray get\fR colorcount] {
+ puts "Color: $color Count: $count"
+}
+ \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)"
+}
+ \fB\(->\fR Color: blue Count: 4
+ Color: white Count: 9
+ Color: green Count: 5
+ Color: red Count: 1
+
+foreach color [lsort [\fBarray names\fR colorcount]] {
+ puts "Color: $color Count: $colorcount($color)"
+}
+ \fB\(->\fR Color: blue Count: 4
+ Color: green Count: 5
+ Color: red Count: 1
+ Color: white Count: 9
+
+\fBarray statistics\fR colorcount
+ \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
+ number of buckets with 3 entries: 0
+ number of buckets with 4 entries: 0
+ number of buckets with 5 entries: 0
+ number of buckets with 6 entries: 0
+ number of buckets with 7 entries: 0
+ number of buckets with 8 entries: 0
+ number of buckets with 9 entries: 0
+ 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/pkgs/msgcat/doc/bgerror.n b/pkgs/msgcat/doc/bgerror.n
new file mode 100644
index 0000000..ac53eca
--- /dev/null
+++ b/pkgs/msgcat/doc/bgerror.n
@@ -0,0 +1,90 @@
+'\"
+'\" Copyright (c) 1990-1994 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 bgerror n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+bgerror \- Command invoked to process background errors
+.SH SYNOPSIS
+\fBbgerror \fImessage\fR
+.BE
+.SH DESCRIPTION
+.PP
+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.
+.PP
+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 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
+through nested Tcl command evaluations until it reaches the top-level
+code in the application; then the application can report the error
+in whatever way it wishes. When a background error occurs, the
+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 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
+implemented the \fBbgerror\fR command, and that the command will
+report the error in a way that makes sense for the application. Tcl
+will ignore any result returned by the \fBbgerror\fR command as long
+as no error is generated.
+.PP
+If another Tcl error occurs within the \fBbgerror\fR command (for
+example, because no \fBbgerror\fR command has been defined) then Tcl
+reports the error itself by writing a message to stderr.
+.PP
+If several background errors accumulate before \fBbgerror\fR is
+invoked to process them, \fBbgerror\fR will be invoked once for each
+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
+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
+to define a \fBbgerror\fR, or use other code that does and thus will
+have trouble integrating your code.
+.SH "EXAMPLE"
+.PP
+This \fBbgerror\fR procedure appends errors to a file, with a timestamp.
+.PP
+.CS
+proc bgerror {message} {
+ set timestamp [clock format [clock seconds]]
+ set fl [open mylog.txt {WRONLY CREAT APPEND}]
+ puts $fl "$timestamp: bgerror in $::argv '$message'"
+ close $fl
+}
+.CE
+.SH "SEE ALSO"
+after(n), interp(n), tclvars(n)
+.SH KEYWORDS
+background error, reporting
diff --git a/pkgs/msgcat/doc/binary.n b/pkgs/msgcat/doc/binary.n
new file mode 100644
index 0000000..68bf9cc
--- /dev/null
+++ b/pkgs/msgcat/doc/binary.n
@@ -0,0 +1,892 @@
+'\"
+'\" Copyright (c) 1997 by Sun Microsystems, Inc.
+'\" Copyright (c) 2008 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.
+'\"
+.so man.macros
+.TH binary n 8.0 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+binary \- Insert and extract fields from binary strings
+.SH SYNOPSIS
+.VS 8.6
+\fBbinary decode \fIformat\fR ?\fI\-option value ...\fR? \fIdata\fR
+.br
+\fBbinary encode \fIformat\fR ?\fI\-option value ...\fR? \fIdata\fR
+.br
+.VE 8.6
+\fBbinary format \fIformatString \fR?\fIarg arg ...\fR?
+.br
+\fBbinary scan \fIstring formatString \fR?\fIvarName varName ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command provides facilities for manipulating binary data. The
+subcommand \fBbinary format\fR creates a binary string from normal
+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 subcommand
+\fBbinary scan\fR, does the opposite: it extracts data
+from a binary string and returns it as ordinary Tcl string values.
+.VS 8.6
+The \fBbinary encode\fR and \fBbinary decode\fR subcommands convert
+binary data to or from string encodings such as base64 (used in MIME
+messages for example).
+.VE 8.6
+.SH "BINARY ENCODE AND DECODE"
+.VS 8.6
+.PP
+When encoding binary data as a readable string, the starting binary data is
+passed to the \fBbinary encode\fR command, together with the name of the
+encoding to use and any encoding-specific options desired. Data which has been
+encoded can be converted back to binary form using \fBbinary decode\fR. The
+following formats and options are supported.
+.TP
+\fBbase64\fR
+.
+The \fBbase64\fR binary encoding is commonly used in mail messages and XML
+documents, and uses mostly upper and lower case letters and digits. It has the
+distinction of being able to be rewrapped arbitrarily without losing
+information.
+.RS
+.PP
+During encoding, the following options are supported:
+.TP
+\fB\-maxlen \fIlength\fR
+.
+Indicates that the output should be split into lines of no more than
+\fIlength\fR characters. By default, lines are not split.
+.TP
+\fB\-wrapchar \fIcharacter\fR
+.
+Indicates that, when lines are split because of the \fB\-maxlen\fR option,
+\fIcharacter\fR should be used to separate lines. By default, this is a
+newline character,
+.QW \en .
+.PP
+During decoding, the following options are supported:
+.TP
+\fB\-strict\fR
+.
+Instructs the decoder to throw an error if it encounters whitespace characters. Otherwise it ignores them.
+.RE
+.TP
+\fBhex\fR
+.
+The \fBhex\fR binary encoding converts each byte to a pair of hexadecimal
+digits in big-endian form.
+.RS
+.PP
+No options are supported during encoding. During decoding, the following
+options are supported:
+.TP
+\fB\-strict\fR
+.
+Instructs the decoder to throw an error if it encounters whitespace characters. Otherwise it ignores them.
+.RE
+.TP
+\fBuuencode\fR
+.
+The \fBuuencode\fR binary encoding used to be common for transfer of data
+between Unix systems and on USENET, but is less common these days, having been
+largely superseded by the \fBbase64\fR binary encoding.
+.RS
+.PP
+During encoding, the following options are supported:
+'\" This is wrong! The uuencode format had more complexity than this!
+.TP
+\fB\-maxlen \fIlength\fR
+.
+Indicates that the output should be split into lines of no more than
+\fIlength\fR characters. By default, lines are not split.
+.TP
+\fB\-wrapchar \fIcharacter\fR
+.
+Indicates that, when lines are split because of the \fB\-maxlen\fR option,
+\fIcharacter\fR should be used to separate lines. By default, this is a
+newline character,
+.QW \en .
+.PP
+During decoding, the following options are supported:
+.TP
+\fB\-strict\fR
+.
+Instructs the decoder to throw an error if it encounters whitespace characters. Otherwise it ignores them.
+.RE
+.VE 8.6
+.SH "BINARY FORMAT"
+.PP
+The \fBbinary format\fR command generates a binary string whose layout
+is specified by the \fIformatString\fR and whose contents come from
+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 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
+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. The flag character
+is ignored for \fBbinary format\fR.
+.PP
+Here is a small example to clarify the relation between the field
+specifiers and the arguments:
+.CS
+\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
+of 3 for the associated field specifier, only the first three will be
+used. The second argument is associated with the second field
+specifier. The resulting binary string contains the four numbers 1.0,
+2.0, 3.0 and 0.1.
+.PP
+Each type-count pair moves an imaginary cursor through the binary
+data, storing bytes at the current position and advancing the cursor
+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 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 \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
+\fIcount\fR is \fB*\fR, then all of the bytes in \fIarg\fR will be
+formatted. If \fIcount\fR is omitted, then one character will be
+formatted. For example,
+.RS
+.CS
+\fBbinary format\fR a7a*a alpha bravo charlie
+.CE
+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\fR A6A*A alpha bravo charlie
+.CE
+will return \fBalpha bravoc\fR.
+.RE
+.IP \fBb\fR 5
+Stores a string of \fIcount\fR binary digits in low-to-high order
+within each byte in the output string. \fIArg\fR must contain a
+sequence of \fB1\fR and \fB0\fR characters. The resulting bytes are
+emitted in first to last order with the bits being formatted in
+low-to-high order within each byte. If \fIarg\fR has fewer than
+\fIcount\fR digits, then zeros will be used for the remaining bits.
+If \fIarg\fR has more than the specified number of digits, the extra
+digits will be ignored. If \fIcount\fR is \fB*\fR, then all of the
+digits in \fIarg\fR will be formatted. If \fIcount\fR is omitted,
+then one digit will be formatted. If the number of bits formatted
+does not end at a byte boundary, the remaining bits of the last byte
+will be zeros. For example,
+.RS
+.CS
+\fBbinary format\fR b5b* 11100 111000011010
+.CE
+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\fR B5B* 11100 111000011010
+.CE
+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 high-to-low
+within each byte in the output string. \fIArg\fR must contain a
+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
+\fB*\fR, then all of the digits in \fIarg\fR will be formatted. If
+\fIcount\fR is omitted, then one digit will be formatted. If the
+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\fR H3H*H2 ab DEF 987
+.CE
+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
+low-to-high order within each byte. This is seldom required. For example,
+.RS
+.CS
+\fBbinary format\fR h3h*h2 AB def 987
+.CE
+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. 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 greater
+than \fIcount\fR, then the extra elements are ignored. For example,
+.RS
+.CS
+\fBbinary format\fR c3cc* {3 -3 128 1} 260 {2 5}
+.CE
+will return a string equivalent to
+\fB\ex03\exfd\ex80\ex04\ex02\ex05\fR, whereas
+.CS
+\fBbinary format\fR c {2 5}
+.CE
+will generate an error.
+.RE
+.IP \fBs\fR 5
+This form is the same as \fBc\fR except that it stores one or more
+16-bit integers in little-endian byte order in the output string. The
+low-order 16-bits of each integer are stored as a two-byte value at
+the cursor position with the least significant byte stored first. For
+example,
+.RS
+.CS
+\fBbinary format\fR s3 {3 -3 258 1}
+.CE
+will return a string equivalent to
+\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
+16-bit integers in big-endian byte order in the output string. For
+example,
+.RS
+.CS
+\fBbinary format\fR S3 {3 -3 258 1}
+.CE
+will return a string equivalent to
+\fB\ex00\ex03\exff\exfd\ex01\ex02\fR.
+.RE
+.IP \fBt\fR 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.
+.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
+low-order 32-bits of each integer are stored as a four-byte value at
+the cursor position with the least significant byte stored first. For
+example,
+.RS
+.CS
+\fBbinary format\fR i3 {3 -3 65536 1}
+.CE
+will return a string equivalent to
+\fB\ex03\ex00\ex00\ex00\exfd\exff\exff\exff\ex00\ex00\ex01\ex00\fR
+.RE
+.IP \fBI\fR 5
+This form is the same as \fBi\fR except that it stores one or more one
+or more 32-bit integers in big-endian byte order in the output string.
+For example,
+.RS
+.CS
+\fBbinary format\fR I3 {3 -3 65536 1}
+.CE
+will return a string equivalent to
+\fB\ex00\ex00\ex00\ex03\exff\exff\exff\exfd\ex00\ex01\ex00\ex00\fR
+.RE
+.IP \fBn\fR 5
+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.
+.IP \fBw\fR 5
+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
+the cursor position with the least significant byte stored first. For
+example,
+.RS
+.CS
+\fBbinary format\fR w 7810179016327718216
+.CE
+will return the string \fBHelloTcl\fR
+.RE
+.IP \fBW\fR 5
+This form is the same as \fBw\fR except that it stores one or more one
+or more 64-bit integers in big-endian byte order in the output string.
+For example,
+.RS
+.CS
+\fBbinary format\fR Wc 4785469626960341345 110
+.CE
+will return the string \fBBigEndian\fR
+.RE
+.IP \fBm\fR 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.
+.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 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
+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
+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\fR f2 {1.6 3.4}
+.CE
+will return a string equivalent to
+\fB\excd\excc\excc\ex3f\ex9a\ex99\ex59\ex40\fR.
+.RE
+.IP \fBr\fR 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.)
+.IP \fBR\fR 5
+This form is the same as \fBr\fR except that it stores the
+single-precision floating point numbers in big-endian order.
+.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 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\fR d1 {1.6}
+.CE
+will return a string equivalent to
+\fB\ex9a\ex99\ex99\ex99\ex99\ex99\exf9\ex3f\fR.
+.RE
+.IP \fBq\fR 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.)
+.IP \fBQ\fR 5
+This form is the same as \fBq\fR except that it stores the
+double-precision floating point numbers in big-endian order.
+.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,
+generates an error. This type does not consume an argument. For
+example,
+.RS
+.CS
+\fBbinary format\fR a3xa3x2a3 abc def ghi
+.CE
+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
+\fIcount\fR is \fB*\fR or is larger than the current cursor position,
+then the cursor is positioned at location 0 so that the next byte
+stored will be the first byte in the result string. If \fIcount\fR is
+omitted then the cursor is moved back one byte. This type does not
+consume an argument. For example,
+.RS
+.CS
+\fBbinary format\fR a3X*a3X2a3 abc def ghi
+.CE
+will return \fBdghi\fR.
+.RE
+.IP \fB@\fR 5
+Moves the cursor to the absolute location in the output string
+specified by \fIcount\fR. Position 0 refers to the first byte in the
+output string. If \fIcount\fR refers to a position beyond the last
+byte stored so far, then null bytes will be placed in the uninitialized
+locations and the cursor will be placed at the specified location. If
+\fIcount\fR is \fB*\fR, then the cursor is moved to the current end of
+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\fR a5@2a1@*a3@10a1 abcde f ghi j
+.CE
+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 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.
+.PP
+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 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
+the specified type are taken from the data. If present, the
+\fIcount\fR is a non-negative decimal integer or \fB*\fR, which
+normally indicates that all of the remaining items in the data are to
+be used. If there are not enough bytes left after the current cursor
+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. 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\fR $bytes s3s first second
+.CE
+.PP
+This command (provided the binary string in the variable \fIbytes\fR
+is long enough) assigns a list of three integers to the variable
+\fIfirst\fR and assigns a single value to the variable \fIsecond\fR.
+If \fIbytes\fR contains fewer than 8 bytes (i.e. four 2-byte
+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
+puts [\fBbinary scan\fR abcdefg s3s first second]
+puts $first
+puts $second
+.CE
+will print (assuming neither variable is set previously):
+.CS
+1
+25185 25699 26213
+can't read "second": no such variable
+.CE
+.PP
+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
+set signShort [\fBbinary format\fR s1 0x8000]
+\fBbinary scan\fR $signShort s1 val; \fI# val == 0xFFFF8000\fR
+.CE
+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
+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,
+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 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
+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\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 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\fR "abc efghi \e000" A* var1
+.CE
+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
+.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 \fIstring\fR will be scanned. If
+\fIcount\fR is omitted, then one bit will be scanned. For example,
+.RS
+.CS
+\fBbinary scan\fR \ex07\ex87\ex05 b5b* var1 var2
+.CE
+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\fR \ex70\ex87\ex05 B5B* var1 var2
+.CE
+will return \fB2\fR with \fB01110\fR stored in \fIvar1\fR and
+\fB1000011100000101\fR stored in \fIvar2\fR.
+.RE
+.IP \fBH\fR 5
+The data is turned into a string of \fIcount\fR hexadecimal digits in
+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\fR \ex07\exC6\ex05\ex1f\ex34 H3H* var1 var2
+.CE
+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
+reverse (low-to-high) order within each byte. For example,
+.RS
+.CS
+\fBbinary scan\fR \ex07\ex86\ex05\ex12\ex34 h3h* var1 var2
+.CE
+will return \fB2\fR with \fB706\fR stored in \fIvar1\fR and
+\fB502143\fR stored in \fIvar2\fR.
+.PP
+Note that most code that wishes to parse the hexadecimal digits from
+multiple bytes in order should use the \fBH\fR format.
+.RE
+.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 \fIstring\fR will be scanned. If
+\fIcount\fR is omitted, then one 8-bit integer will be scanned. For
+example,
+.RS
+.CS
+\fBbinary scan\fR \ex07\ex86\ex05 c2c* var1 var2
+.CE
+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
+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 \fIstring\fR will be scanned. If
+\fIcount\fR is omitted, then one 16-bit integer will be scanned. For
+example,
+.RS
+.CS
+\fBbinary scan\fR \ex05\ex00\ex07\ex00\exf0\exff s2s* var1 var2
+.CE
+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
+set num [expr { $num & 0xffff }]
+.CE
+.RE
+.IP \fBS\fR 5
+This form is the same as \fBs\fR except that the data is interpreted
+as \fIcount\fR 16-bit signed integers represented in big-endian byte
+order. For example,
+.RS
+.CS
+\fBbinary scan\fR \ex00\ex05\ex00\ex07\exff\exf0 S2S* var1 var2
+.CE
+will return \fB2\fR with \fB5 7\fR stored in \fIvar1\fR and \fB\-16\fR
+stored in \fIvar2\fR.
+.RE
+.IP \fBt\fR 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.
+.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 \fIstring\fR will be scanned. If
+\fIcount\fR is omitted, then one 32-bit integer will be scanned. For
+example,
+.RS
+.CS
+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 \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
+set num [expr { $num & 0xffffffff }]
+.CE
+.RE
+.IP \fBI\fR 5
+This form is the same as \fBI\fR except that the data is interpreted
+as \fIcount\fR 32-bit signed integers represented in big-endian byte
+order. For example,
+.RS
+.CS
+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 \fIvar1\fR and \fB\-16\fR
+stored in \fIvar2\fR.
+.RE
+.IP \fBn\fR 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.
+.IP \fBw\fR 5
+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 \fIstring\fR will be scanned. If
+\fIcount\fR is omitted, then one 64-bit integer will be scanned. For
+example,
+.RS
+.CS
+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 \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
+This form is the same as \fBw\fR except that the data is interpreted
+as \fIcount\fR 64-bit signed integers represented in big-endian byte
+order. For example,
+.RS
+.CS
+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 \fIvar1\fR and \fB\-16\fR
+stored in \fIvar2\fR.
+.RE
+.IP \fBm\fR 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.
+.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
+\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
+valid floating point number, the resulting value is undefined and
+compiler dependent. For example, on a Windows system running on an
+Intel Pentium processor,
+.RS
+.CS
+\fBbinary scan\fR \ex3f\excc\excc\excd f var1
+.CE
+will return \fB1\fR with \fB1.6000000238418579\fR stored in
+\fIvar1\fR.
+.RE
+.IP \fBr\fR 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.
+.IP \fBR\fR 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.
+.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
+machine's native representation. For example, on a Windows system
+running on an Intel Pentium processor,
+.RS
+.CS
+\fBbinary scan\fR \ex9a\ex99\ex99\ex99\ex99\ex99\exf9\ex3f d var1
+.CE
+will return \fB1\fR with \fB1.6000000000000001\fR
+stored in \fIvar1\fR.
+.RE
+.IP \fBq\fR 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.
+.IP \fBQ\fR 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.
+.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 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\fR \ex01\ex02\ex03\ex04 x2H* var1
+.CE
+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
+\fIcount\fR is \fB*\fR or is larger than the current cursor position,
+then the cursor is positioned at location 0 so that the next byte
+scanned will be the first byte in \fIstring\fR. If \fIcount\fR
+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\fR \ex01\ex02\ex03\ex04 c2XH* var1 var2
+.CE
+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
+by \fIcount\fR. Note that position 0 refers to the first byte in
+\fIstring\fR. If \fIcount\fR refers to a position beyond the end of
+\fIstring\fR, then the cursor is positioned after the last byte. If
+\fIcount\fR is omitted, then an error will be generated. For example,
+.RS
+.CS
+\fBbinary scan\fR \ex01\ex02\ex03\ex04 c2@1H* var1 var2
+.CE
+will return \fB2\fR with \fB1 2\fR stored in \fIvar1\fR and \fB020304\fR
+stored in \fIvar2\fR.
+.RE
+.SH "PORTABILITY ISSUES"
+.PP
+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
+.PP
+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 \fIwriteString\fR {channel string} {
+ set data [encoding convertto utf-8 $string]
+ puts -nonewline [\fBbinary format\fR Ia* \e
+ [string length $data] $data]
+}
+.CE
+.PP
+This procedure reads a string from a channel that was written by the
+previously presented \fIwriteString\fR procedure:
+.CS
+proc \fIreadString\fR {channel} {
+ if {![\fBbinary scan\fR [read $channel 4] I length]} {
+ error "missing length"
+ }
+ set data [read $channel $length]
+ return [encoding convertfrom utf-8 $data]
+}
+.CE
+.PP
+This converts the contents of a file (named in the variable \fIfilename\fR) to
+base64 and prints them:
+.CS
+set f [open $filename rb]
+set data [read $f]
+close $f
+puts [\fBbinary encode\fR base64 \-maxlen 64 $data]
+.CE
+.SH "SEE ALSO"
+format(n), scan(n), tclvars(n)
+.SH KEYWORDS
+binary, format, scan
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/break.n b/pkgs/msgcat/doc/break.n
new file mode 100644
index 0000000..cef37c6
--- /dev/null
+++ b/pkgs/msgcat/doc/break.n
@@ -0,0 +1,47 @@
+'\"
+'\" Copyright (c) 1993-1994 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 break n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+break \- Abort looping command
+.SH SYNOPSIS
+\fBbreak\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command is typically invoked inside the body of a looping command
+such as \fBfor\fR or \fBforeach\fR or \fBwhile\fR.
+It returns a 3 (\fBTCL_BREAK\fR) result code, which causes a break exception
+to occur.
+The exception causes the current script to be aborted
+out to the innermost containing loop command, which then
+aborts its execution and returns normally.
+Break exceptions are also handled in a few other situations, such
+as the \fBcatch\fR command, Tk event bindings, and the outermost
+scripts of procedure bodies.
+.SH EXAMPLE
+.PP
+Print a line for each of the integers from 0 to 5:
+.PP
+.CS
+for {set x 0} {$x<10} {incr x} {
+ if {$x > 5} {
+ \fBbreak\fR
+ }
+ puts "x is $x"
+}
+.CE
+.SH "SEE ALSO"
+catch(n), continue(n), for(n), foreach(n), return(n), while(n)
+.SH KEYWORDS
+abort, break, loop
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/case.n b/pkgs/msgcat/doc/case.n
new file mode 100644
index 0000000..0155a61
--- /dev/null
+++ b/pkgs/msgcat/doc/case.n
@@ -0,0 +1,60 @@
+'\"
+'\" 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 case n 7.0 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+case \- Evaluate one of several scripts, depending on a given value
+.SH SYNOPSIS
+\fBcase\fI string \fR?\fBin\fR? \fIpatList body \fR?\fIpatList body \fR...?
+.sp
+\fBcase\fI string \fR?\fBin\fR? {\fIpatList body \fR?\fIpatList body \fR...?}
+.BE
+
+.SH DESCRIPTION
+.PP
+\fINote: the \fBcase\fI command is obsolete and is supported only
+for backward compatibility. At some point in the future it may be
+removed entirely. You should use the \fBswitch\fI command instead.\fR
+.PP
+The \fBcase\fR command matches \fIstring\fR against each of
+the \fIpatList\fR arguments in order.
+Each \fIpatList\fR argument is a list of one or
+more patterns. If any of these patterns matches \fIstring\fR then
+\fBcase\fR evaluates the following \fIbody\fR argument
+by passing it recursively to the Tcl interpreter and returns the result
+of that evaluation.
+Each \fIpatList\fR argument consists of a single
+pattern or list of patterns. Each pattern may contain any of the wild-cards
+described under \fBstring match\fR. If a \fIpatList\fR
+argument is \fBdefault\fR, the corresponding body will be evaluated
+if no \fIpatList\fR matches \fIstring\fR. If no \fIpatList\fR argument
+matches \fIstring\fR and no default is given, then the \fBcase\fR
+command returns an empty string.
+.PP
+Two syntaxes are provided for the \fIpatList\fR and \fIbody\fR arguments.
+The first uses a separate argument for each of the patterns and commands;
+this form is convenient if substitutions are desired on some of the
+patterns or commands.
+The second form places all of the patterns and commands together into
+a single argument; the argument must have proper list structure, with
+the elements of the list being the patterns and commands.
+The second form makes it easy to construct multi-line case commands,
+since the braces around the whole list make it unnecessary to include a
+backslash at the end of each line.
+Since the \fIpatList\fR arguments are in braces in the second form,
+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.
+
+.SH "SEE ALSO"
+switch(n)
+
+.SH KEYWORDS
+case, match, regular expression
diff --git a/pkgs/msgcat/doc/catch.n b/pkgs/msgcat/doc/catch.n
new file mode 100644
index 0000000..a05ca71
--- /dev/null
+++ b/pkgs/msgcat/doc/catch.n
@@ -0,0 +1,124 @@
+'\"
+'\" 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.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?\fIresultVarName\fR? ?\fIoptionsVarName\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fBcatch\fR command may be used to prevent errors from aborting command
+interpretation. The \fBcatch\fR command calls the Tcl interpreter recursively
+to execute \fIscript\fR, and always returns without raising an error,
+regardless of any errors that might occur while executing \fIscript\fR.
+.PP
+If \fIscript\fR raises an error, \fBcatch\fR will return a non-zero integer
+value corresponding to the exceptional return code returned by evaluation
+of \fIscript\fR. Tcl defines the normal return code from script
+evaluation to be zero (0), or \fBTCL_OK\fR. Tcl also defines four exceptional
+return codes: 1 (\fBTCL_ERROR\fR), 2 (\fBTCL_RETURN\fR), 3 (\fBTCL_BREAK\fR),
+and 4 (\fBTCL_CONTINUE\fR). Errors during evaluation of a script are indicated
+by a return code of \fBTCL_ERROR\fR. The other exceptional return codes are
+returned by the \fBreturn\fR, \fBbreak\fR, and \fBcontinue\fR commands
+and in other special situations as documented. Tcl packages can define
+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 \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 \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 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
+When the return code from evaluation of \fIscript\fR is
+\fBTCL_ERROR\fR, four additional entries are defined in the dictionary
+of return options stored in \fIoptionsVarName\fR: \fB\-errorinfo\fR,
+\fB\-errorcode\fR, \fB\-errorline\fR, and
+.VS 8.6
+\fB\-errorstack\fR.
+.VE 8.6
+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.
+.VS 8.6
+The value of the \fB\-errorstack\fR entry is an
+even-sized list made of token-parameter pairs accumulated while
+unwinding the stack. The token may be
+.QW \fBCALL\fR ,
+in which case the parameter is a list made of the proc name and arguments at
+the corresponding level; or it may be
+.QW \fBUP\fR ,
+in which case the parameter is
+the relative level (as in \fBuplevel\fR) of the previous \fBCALL\fR. The
+salient differences with respect to \fB\-errorinfo\fR are that:
+.IP [1]
+it is a machine-readable form that is amenable to processing with
+[\fBforeach\fR {tok prm} ...],
+.IP [2]
+it contains the true (substituted) values passed to the functions, instead of
+the static text of the calling sites, and
+.IP [3]
+it is coarser-grained, with only one element per stack frame (like procs; no
+separate elements for \fBforeach\fR constructs for example).
+.VE 8.6
+.PP
+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.
+.VS 8.6
+The value of the \fB\-errorstack\fR entry surfaces as \fBinfo errorstack\fR.
+.VE 8.6
+.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.
+.SH EXAMPLES
+.PP
+The \fBcatch\fR command may be used in an \fBif\fR to branch based on
+the success of a script.
+.PP
+.CS
+if { [\fBcatch\fR {open $someFile w} fid] } {
+ puts stderr "Could not open $someFile for writing\en$fid"
+ exit 1
+}
+.CE
+.PP
+There are more complex examples of \fBcatch\fR usage in the
+documentation for the \fBreturn\fR command.
+.SH "SEE ALSO"
+break(n), continue(n), dict(n), error(n), info(n), return(n), tclvars(n)
+.SH KEYWORDS
+catch, error, exception
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/pkgs/msgcat/doc/cd.n b/pkgs/msgcat/doc/cd.n
new file mode 100644
index 0000000..eb3854c
--- /dev/null
+++ b/pkgs/msgcat/doc/cd.n
@@ -0,0 +1,43 @@
+'\"
+'\" 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 cd n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+cd \- Change working directory
+.SH SYNOPSIS
+\fBcd \fR?\fIdirName\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Change the current working directory to \fIdirName\fR, or to the
+home directory (as specified in the HOME environment variable) if
+\fIdirName\fR is not given.
+Returns an empty string.
+Note that the current working directory is a per-process resource; the
+\fBcd\fR command changes the working directory for all interpreters
+and (in a threaded environment) all threads.
+.SH EXAMPLES
+.PP
+Change to the home directory of the user \fBfred\fR:
+.PP
+.CS
+\fBcd\fR ~fred
+.CE
+.PP
+Change to the directory \fBlib\fR that is a sibling directory of the
+current one:
+.PP
+.CS
+\fBcd\fR ../lib
+.CE
+.SH "SEE ALSO"
+filename(n), glob(n), pwd(n)
+.SH KEYWORDS
+working directory
diff --git a/pkgs/msgcat/doc/chan.n b/pkgs/msgcat/doc/chan.n
new file mode 100644
index 0000000..c518455
--- /dev/null
+++ b/pkgs/msgcat/doc/chan.n
@@ -0,0 +1,836 @@
+'\"
+'\" 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 ?\fIdirection\fR?
+.
+Close and destroy the channel called \fIchannelId\fR. Note that this
+deletes all existing file-events registered on the channel.
+.VS 8.6
+If the \fIdirection\fR argument (which must be \fBread\fR or \fBwrite\fR or
+any unique abbreviation of them) is present, the channel will only be
+half-closed, so that it can go from being read-write to write-only or
+read-only respectively. If a read-only channel is closed for reading, it is
+the same as if the channel is fully closed, and respectively similar for
+write-only channels. Without the \fIdirection\fR argument, the channel is
+closed for both reading and writing (but only if those directions are
+currently open). It is an error to close a read-only channel for writing, or a
+write-only channel for reading.
+.VE 8.6
+.RS
+.PP
+As part of closing the channel, all buffered output is flushed to the
+channel's output device (only if the channel is ceasing to be writable), any
+buffered input is discarded (only if the channel is ceasing to be readable),
+the underlying operating system resource is closed and \fIchannelId\fR becomes
+unavailable for future use (both only if the channel is being completely
+closed).
+.PP
+If the channel is blocking and the channel is ceasing to be writable, the
+command does not return until all output is flushed. If the channel is
+non-blocking and there is unflushed output, the channel remains open and the
+command returns immediately; output will be flushed in the background and the
+channel will be closed when all the flushing is complete.
+.PP
+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. With half-closing, the half-close of the channel only
+applies to the current interpreter's view of the channel until all channels
+have closed it in that direction (or completely).
+See the \fBinterp\fR command for a description of channel sharing.
+.PP
+Channels are automatically fully 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.)
+.PP
+.VS 8.6
+Note that half-closes of sockets and command pipelines can have important side
+effects because they result in a shutdown() or close() of the underlying
+system resource, which can change how other processes or systems respond to
+the Tcl program.
+.VE 8.6
+.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 channel
+for the options supported by that specific type of channel. For
+example, see the manual entry for the \fBsocket\fR command for additional
+options for sockets, and the \fBopen\fR command for additional options for
+serial devices.
+.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 non-blocking mode it will
+affect the operation of the \fBchan gets\fR, \fBchan read\fR, \fBchan
+puts\fR, \fBchan flush\fR, and \fBchan close\fR commands; see the
+documentation for those commands for details. For non-blocking mode to
+work correctly, the application must be using the Tcl event loop
+(e.g. by calling \fBTcl_DoOneEvent\fR or invoking the \fBvwait\fR
+command).
+.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
+\fBrefchan\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
+\fBrefchan\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 transferred
+to. While this pulls the rug out under the other thread(s) and/or
+interpreter(s), this cannot be avoided. Trying to use such a channel
+will cause the generation of a regular error about unknown channel
+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 non-blocking mode using events. A channel is also considered to be
+readable if an end of file or error condition is present on the
+underlying file or device. It is important for \fIscript\fR to check
+for these conditions and handle them appropriately; for example, if
+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
+non-blocking mode with the \fBchan configure\fR command. In blocking
+mode, a \fBchan puts\fR command may block if you give it more data
+than the underlying file or device can accept, and a \fBchan gets\fR
+or \fBchan read\fR command will block if you attempt to read more data
+than is ready; no events will be processed while the commands block.
+In non-blocking mode \fBchan puts\fR, \fBchan read\fR, and \fBchan
+gets\fR never block.
+.PP
+The script for a file event is executed at global level (outside the
+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 non-blocking mode, the command may return before all
+buffered output has been flushed; the remainder will be flushed in the
+background as fast as the underlying file or device is able to absorb
+it.
+.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-non-blocking 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 pipe\fR
+.VS 8.6
+Creates a standalone pipe whose read- and write-side channels are
+returned as a 2-element list, the first element being the read side and
+the second the write side. Can be useful e.g. to redirect
+separately \fBstderr\fR and \fBstdout\fR from a subprocess. To do
+this, spawn with "2>@" or
+">@" redirection operators onto the write side of a pipe, and then
+immediately close it in the parent. This is necessary to get an EOF on
+the read side once the child has exited or otherwise closed its output.
+.VE 8.6
+.TP
+\fBchan pop \fIchannelId\fR
+.VS 8.6
+Removes the topmost transformation from the channel \fIchannelId\fR, if there
+is any. If there are no transformations added to \fIchannelId\fR, this is
+equivalent to \fBchan close\fR of that channel. The result is normally the
+empty string, but can be an error in some situations (i.e. where the
+underlying system stream is closed and that results in an error).
+.VE 8.6
+.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 \fBrefchan\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 push \fIchannelId cmdPrefix\fR
+.VS 8.6
+Adds a new transformation on top of the channel \fIchannelId\fR. The
+\fIcmdPrefix\fR argument describes a list of one or more words which represent
+a handler that will be used to implement the transformation. The command
+prefix must provide the API described in the \fBtranschan\fR manual page.
+The result of this subcommand is a handle to the transformation. Note that it
+is important to make sure that the transformation is capable of supporting the
+channel mode that it is used with or this can make the channel neither
+readable nor writable.
+.VE 8.6
+.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 non-blocking
+mode then the \fBchan puts\fR command will not block even if the
+operating system cannot accept the data. Instead, Tcl continues to
+buffer the data and writes it in the background as fast as the
+underlying file or device can accept it. The application must use the
+Tcl event loop for non-blocking output to work; otherwise Tcl never
+finds out that the file or device is ready for more output data. It
+is possible for an arbitrarily large amount of data to be buffered for
+a channel in non-blocking mode, which could consume a large amount of
+memory. To avoid wasting memory, non-blocking I/O should normally be
+used in an event-driven fashion with the \fBchan event\fR command
+(do not invoke \fBchan puts\fR unless you have recently been notified
+via a file event that the channel is ready for more output data).
+.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 non-blocking mode, \fBchan read\fR may not
+read as many characters as requested: once all available input has
+been read, the command will return the data that is available rather
+than blocking for more input. If the channel is configured to use a
+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 non-blocking, like this:
+.PP
+.CS
+\fBchan configure \fIchannelId \fB\-blocking \fI0\fR.
+.CE
+.PP
+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 non-blocking mode. It also
+discards any buffered and unread input. This command returns an empty
+string. An error occurs if this command is applied to channels whose
+underlying file or device does not support seeking.
+.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 EXAMPLES
+.PP
+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
+.PP
+A network server that does echoing of its input line-by-line without
+preventing servicing of other connections at the same time.
+.PP
+.CS
+# This is a very simple logger...
+proc log {message} {
+ \fBchan puts\fR stdout $message
+}
+
+# This is called whenever a new client connects to the server
+proc connect {chan host port} {
+ set clientName [format <%s:%d> $host $port]
+ log "connection from $clientName"
+ \fBchan configure\fR $chan -blocking 0 -buffering line
+ \fBchan event\fR $chan readable [list echoLine $chan $clientName]
+}
+
+# This is called whenever either at least one byte of input
+# data is available, or the channel was closed by the client.
+proc echoLine {chan clientName} {
+ \fBchan gets\fR $chan line
+ if {[\fBchan eof\fR $chan]} {
+ log "finishing connection from $clientName"
+ \fBchan close\fR $chan
+ } elseif {![\fBchan blocked\fR $chan]} {
+ # Didn't block waiting for end-of-line
+ log "$clientName - $line"
+ \fBchan puts\fR $chan $line
+ }
+}
+
+# Create the server socket and enter the event-loop to wait
+# for incoming connections...
+socket -server connect 12345
+vwait forever
+.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), transchan(n)
+.SH KEYWORDS
+channel, input, output, events, offset
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/class.n b/pkgs/msgcat/doc/class.n
new file mode 100644
index 0000000..88d1b44
--- /dev/null
+++ b/pkgs/msgcat/doc/class.n
@@ -0,0 +1,136 @@
+'\"
+'\" Copyright (c) 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 class n 0.1 TclOO "TclOO Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+oo::class \- class of all classes
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBoo::class\fI method \fR?\fIarg ...\fR?
+.fi
+.SH "CLASS HIERARCHY"
+.nf
+\fBoo::object\fR
+ \(-> \fBoo::class\fR
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+Classes are objects that can manufacture other objects according to a pattern
+stored in the factory object (the class). An instance of the class is created
+by calling one of the class's factory methods, typically either \fBcreate\fR
+if an explicit name is being given, or \fBnew\fR if an arbitrary unique name
+is to be automatically selected.
+.PP
+The \fBoo::class\fR class is the class of all classes; every class is an
+instance of this class, which is consequently an instance of itself. This
+class is a subclass of \fBoo::object\fR, so every class is also an object.
+Additional metaclasses (i.e., classes of classes) can be defined if necessary
+by subclassing \fBoo::class\fR. Note that the \fBoo::class\fR object hides the
+\fBnew\fR method on itself, so new classes should always be made using the
+\fBcreate\fR method.
+.SS CONSTRUCTOR
+.PP
+The constructor of the \fBoo::class\fR class takes an optional argument which,
+if present, is sent to the \fBoo::define\fR command (along with the name of
+the newly-created class) to allow the class to be conveniently configured at
+creation time.
+.SS DESTRUCTOR
+The \fBoo::class\fR class does not define an explicit destructor. However,
+when a class is destroyed, all its subclasses and instances are also
+destroyed, along with all objects that it has been mixed into.
+.SS "EXPORTED METHODS"
+.TP
+\fIcls \fBcreate \fIname \fR?\fIarg ...\fR?
+.
+This creates a new instance of the class \fIcls\fR called \fIname\fR (which is
+resolved within the calling context's namespace if not fully qualified),
+passing the arguments, \fIarg ...\fR, to the constructor, and (if that returns
+a successful result) returning the fully qualified name of the created object
+(the result of the constructor is ignored). If the constructor fails (i.e.
+returns a non-OK result) then the object is destroyed and the error message is
+the result of this method call.
+.TP
+\fIcls \fBnew \fR?\fIarg ...\fR?
+.
+This creates a new instance of the class \fIcls\fR with a new unique name,
+passing the arguments, \fIarg ...\fR, to the constructor, and (if that returns
+a successful result) returning the fully qualified name of the created object
+(the result of the constructor is ignored). If the constructor fails (i.e.,
+returns a non-OK result) then the object is destroyed and the error message is
+the result of this method call.
+.RS
+.PP
+Note that this method is not exported by the \fBoo::class\fR object itself, so
+classes should not be created using this method.
+.RE
+.SS "NON-EXPORTED METHODS"
+.PP
+The \fBoo::class\fR class supports the following non-exported methods:
+.TP
+\fIcls \fBcreateWithNamespace\fI name nsName\fR ?\fIarg ...\fR?
+.
+This creates a new instance of the class \fIcls\fR called \fIname\fR (which is
+resolved within the calling context's namespace if not fully qualified),
+passing the arguments, \fIarg ...\fR, to the constructor, and (if that returns
+a successful result) returning the fully qualified name of the created object
+(the result of the constructor is ignored). The name of the instance's
+internal namespace will be \fInsName\fR unless that namespace already exists
+(when an arbitrary name will be chosen instead). If the constructor fails
+(i.e., returns a non-OK result) then the object is destroyed and the error
+message is the result of this method call.
+.SH EXAMPLES
+.PP
+This example defines a simple class hierarchy and creates a new instance of
+it. It then invokes a method of the object before destroying the hierarchy and
+showing that the destruction is transitive.
+.PP
+.CS
+\fBoo::class create\fR fruit {
+ method eat {} {
+ puts "yummy!"
+ }
+}
+\fBoo::class create\fR banana {
+ superclass fruit
+ constructor {} {
+ my variable peeled
+ set peeled 0
+ }
+ method peel {} {
+ my variable peeled
+ set peeled 1
+ puts "skin now off"
+ }
+ method edible? {} {
+ my variable peeled
+ return $peeled
+ }
+ method eat {} {
+ if {![my edible?]} {
+ my peel
+ }
+ next
+ }
+}
+set b [banana \fBnew\fR]
+$b eat \fI\(-> prints "skin now off" and "yummy!"\fR
+fruit destroy
+$b eat \fI\(-> error "unknown command"\fR
+.CE
+.SH "SEE ALSO"
+oo::define(n), oo::object(n)
+.SH KEYWORDS
+class, metaclass, object
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/pkgs/msgcat/doc/clock.n b/pkgs/msgcat/doc/clock.n
new file mode 100644
index 0000000..8708029
--- /dev/null
+++ b/pkgs/msgcat/doc/clock.n
@@ -0,0 +1,937 @@
+'\"
+'\" Generated from file './doc/clock.dt' by tcllib/doctools with format 'nroff'
+'\" Copyright (c) 2004 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\"
+.so man.macros
+.TH "clock" n 8.5 Tcl "Tcl Built-In Commands"
+.BS
+.SH NAME
+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
+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
+.PP
+If the \fI\-option\fR argument is \fB\-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 \fB\-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
+.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
+.PP
+.CS
+%a %b %d %H:%M:%S %z %Y
+.CE
+.PP
+On \fBclock scan\fR, the lack of a \fB\-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
+.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
+.PP
+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"
+.PP
+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.
+.PP
+.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.
+.PP
+.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.
+.PP
+.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.
+.PP
+.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"
+.PP
+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"
+.PP
+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"
+.PP
+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"
+.PP
+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
+\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"
+.PP
+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:
+.PP
+.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
+.PP
+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
+If the Posix time zone string contains a DST (Daylight Savings Time)
+part, but doesn't contain a rule stating when DST starts or ends,
+then default rules are used. For Timezones with an offset between 0
+and +12, the current European/Russian rules are used, otherwise the
+current US rules are used. In Europe (offset +0 to +2) the switch
+to summertime is done each last Sunday in March at 1:00 GMT, and
+the switch back is each last Sunday in October at 2:00 GMT. In
+Russia (offset +3 to +12), the switch dates are the same, only
+the switch to summertime is at 2:00 local time, and the switch
+back is at 3:00 local time in all time zones. The US switch to
+summertime takes place each second Sunday in March at 2:00 local
+time, and the switch back is each first Sunday in November at
+3:00 local time. These default rules mean that in all European,
+Russian and US (or compatible) time zones, DST calculations will
+be correct for dates in 2007 and later, unless in the future the
+rules change again.
+.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"
+.PP
+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"
+.PP
+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.
+.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.
+.PP
+The \fIinputString\fR argument consists of zero or more specifications of the
+following form:
+.TP
+\fItime\fR
+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
+.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
+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.
+.TP
+\fIISO 8601 point-in-time\fR
+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
+giving an explicit \fB\-format\fR option to the \fBclock scan\fR command.
+.TP
+\fIrelative time\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.
+.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
+specified, and no absolute or relative time is given, midnight is
+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.
+.SH "SEE ALSO"
+msgcat(n)
+.SH KEYWORDS
+clock, date, time
+.SH "COPYRIGHT"
+Copyright (c) 2004 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/close.n b/pkgs/msgcat/doc/close.n
new file mode 100644
index 0000000..2826d82
--- /dev/null
+++ b/pkgs/msgcat/doc/close.n
@@ -0,0 +1,108 @@
+'\"
+'\" 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 close n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+close \- Close an open channel
+.SH SYNOPSIS
+\fBclose \fIchannelId\fR ?r(ead)|w(rite)?
+.BE
+.SH DESCRIPTION
+.PP
+Closes or half-closes the channel given by \fIchannelId\fR.
+.PP
+\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.
+.PP
+The single-argument form is a simple
+.QW "full-close" :
+all buffered output is flushed to the channel's output device,
+any buffered input is discarded, the underlying file or device is closed,
+and \fIchannelId\fR becomes unavailable for use.
+.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
+\fBclose\fR waits for the child processes to complete.
+.PP
+If the channel is shared between interpreters, then \fBclose\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
+\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.
+.VS 8.6
+From 8.6 on (TIP#398), nonblocking channels are no longer switched to blocking mode when exiting; this guarantees a timely exit even when the peer or a communication channel is stalled. To ensure proper flushing of stalled nonblocking channels on exit, one must now either (a) actively switch them back to blocking or (b) use the environment variable TCL_FLUSH_NONBLOCKING_ON_EXIT, which when set and not equal to "0" restores the previous behavior.
+.VE 8.6
+.PP
+The command returns an empty string, and may generate an error if
+an error occurs while flushing output. If a command in a command
+pipeline created with \fBopen\fR returns an error, \fBclose\fR
+generates an error (similar to the \fBexec\fR command.)
+.PP
+.VS 8.6
+The two-argument form is a
+.QW "half-close" :
+given a bidirectional channel like a
+socket or command pipeline and a (possibly abbreviated) direction, it closes
+only the sub-stream going in that direction. This means a shutdown() on a
+socket, and a close() of one end of a pipe for a command pipeline. Then, the
+Tcl-level channel data structure is either kept or freed depending on whether
+the other direction is still open.
+.PP
+A single-argument close on an already half-closed bidirectional channel is
+defined to just
+.QW "finish the job" .
+A half-close on an already closed half, or on a wrong-sided unidirectional
+channel, raises an error.
+.PP
+In the case of a command pipeline, the child-reaping duty falls upon the
+shoulders of the last close or half-close, which is thus allowed to report an
+abnormal exit error.
+.PP
+Currently only sockets and command pipelines support half-close. A future
+extension will allow reflected and stacked channels to do so.
+.VE 8.6
+.SH EXAMPLE
+.PP
+This illustrates how you can use Tcl to ensure that files get closed
+even when errors happen by combining \fBcatch\fR, \fBclose\fR and
+\fBreturn\fR:
+.PP
+.CS
+proc withOpenFile {filename channelVar script} {
+ upvar 1 $channelVar chan
+ set chan [open $filename]
+ catch {
+ uplevel 1 $script
+ } result options
+ \fBclose\fR $chan
+ return -options $options $result
+}
+.CE
+.SH "SEE ALSO"
+file(n), open(n), socket(n), eof(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+blocking, channel, close, nonblocking, half-close
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/pkgs/msgcat/doc/concat.n b/pkgs/msgcat/doc/concat.n
new file mode 100644
index 0000000..b079b30
--- /dev/null
+++ b/pkgs/msgcat/doc/concat.n
@@ -0,0 +1,58 @@
+'\"
+'\" 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 concat n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+concat \- Join lists together
+.SH SYNOPSIS
+\fBconcat\fI \fR?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command joins each of its arguments together with spaces after
+trimming leading and trailing white-space from each of them. If all of the
+arguments are lists, this has the same effect as concatenating them
+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, flattening them in the process
+(so giving the following interactive session):
+.PP
+.CS
+\fI%\fR \fBconcat\fR a b {c d e} {f {g h}}
+\fIa b c d e f {g h}\fR
+.CE
+.PP
+it will also concatenate things that are not lists, as can be seen from this
+session:
+.PP
+.CS
+\fI%\fR \fBconcat\fR " a b {c " d " e} f"
+\fIa b {c d e} f\fR
+.CE
+.PP
+Note also that the concatenation does not remove spaces from the middle of
+values, as can be seen here:
+.PP
+.CS
+\fI%\fR \fBconcat\fR "a b c" { d e f }
+\fIa b c d e f\fR
+.CE
+.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), join(n)
+.SH KEYWORDS
+concatenate, join, list
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/continue.n b/pkgs/msgcat/doc/continue.n
new file mode 100644
index 0000000..de2f07c
--- /dev/null
+++ b/pkgs/msgcat/doc/continue.n
@@ -0,0 +1,47 @@
+'\"
+'\" Copyright (c) 1993-1994 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 continue n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+continue \- Skip to the next iteration of a loop
+.SH SYNOPSIS
+\fBcontinue\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command is typically invoked inside the body of a looping command
+such as \fBfor\fR or \fBforeach\fR or \fBwhile\fR.
+It returns a 4 (\fBTCL_CONTINUE\fR) result code, which causes a continue
+exception to occur.
+The exception causes the current script to be aborted
+out to the innermost containing loop command, which then
+continues with the next iteration of the loop.
+Catch exceptions are also handled in a few other situations, such
+as the \fBcatch\fR command and the outermost scripts of procedure
+bodies.
+.SH EXAMPLE
+.PP
+Print a line for each of the integers from 0 to 10 \fIexcept\fR 5:
+.PP
+.CS
+for {set x 0} {$x<10} {incr x} {
+ if {$x == 5} {
+ \fBcontinue\fR
+ }
+ puts "x is $x"
+}
+.CE
+.SH "SEE ALSO"
+break(n), for(n), foreach(n), return(n), while(n)
+.SH KEYWORDS
+continue, iteration, loop
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/copy.n b/pkgs/msgcat/doc/copy.n
new file mode 100644
index 0000000..f5002f8
--- /dev/null
+++ b/pkgs/msgcat/doc/copy.n
@@ -0,0 +1,66 @@
+'\"
+'\" Copyright (c) 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 copy n 0.1 TclOO "TclOO Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+oo::copy \- create copies of objects and classes
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBoo::copy\fI sourceObject \fR?\fItargetObject\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBoo::copy\fR command creates a copy of an object or class. It takes the
+name of the object or class to be copied, \fIsourceObject\fR, and optionally
+the name of the object or class to create, \fItargetObject\fR, which will be
+resolved relative to the current namespace if not an absolute qualified name.
+If \fItargetObject\fR is omitted, a new name is chosen. The copied object will
+be of the same class as the source object, and will have all its per-object
+methods copied. If it is a class, it will also have all the class methods in
+the class copied, but it will not have any of its instances copied.
+.PP
+.VS
+After the \fItargetObject\fR has been created and all definitions of its
+configuration (e.g., methods, filters, mixins) copied, the \fB<cloned>\fR
+method of \fItargetObject\fR will be invoked, to allow for customization of
+the created object such as installing related variable traces. The only
+argument given will be \fIsourceObject\fR. The default implementation of this
+method (in \fBoo::object\fR) just copies the procedures and variables in the
+namespace of \fIsourceObject\fR to the namespace of \fItargetObject\fR. If
+this method call does not return a result that is successful (i.e., an error
+or other kind of exception) then the \fItargetObject\fR will be deleted and an
+error returned.
+.VE
+.PP
+The result of the \fBoo::copy\fR command will be the fully-qualified name of
+the new object or class.
+.SH EXAMPLES
+.PP
+This example creates an object, copies it, modifies the source object, and
+then demonstrates that the copied object is indeed a copy.
+.PP
+.CS
+oo::object create src
+oo::objdefine src method msg {} {puts foo}
+\fBoo::copy\fR src dst
+oo::objdefine src method msg {} {puts bar}
+src msg \fI\(-> prints "bar"\fR
+dst msg \fI\(-> prints "foo"\fR
+.CE
+.SH "SEE ALSO"
+oo::class(n), oo::define(n), oo::object(n)
+.SH KEYWORDS
+clone, copy, duplication, object
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/pkgs/msgcat/doc/coroutine.n b/pkgs/msgcat/doc/coroutine.n
new file mode 100644
index 0000000..035d58a
--- /dev/null
+++ b/pkgs/msgcat/doc/coroutine.n
@@ -0,0 +1,205 @@
+'\"
+'\" Copyright (c) 2009 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 coroutine n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+coroutine, yield, yieldto \- Create and produce values from coroutines
+.SH SYNOPSIS
+.nf
+\fBcoroutine \fIname command\fR ?\fIarg...\fR?
+\fByield\fR ?\fIvalue\fR?
+.VS TIP396
+\fByieldto\fR \fIcommand\fR ?\fIarg...\fR?
+\fIname\fR ?\fIvalue...\fR?
+.VE TIP396
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBcoroutine\fR command creates a new coroutine context (with associated
+command) named \fIname\fR and executes that context by calling \fIcommand\fR,
+passing in the other remaining arguments without further interpretation. Once
+\fIcommand\fR returns normally or with an exception (e.g., an error) the
+coroutine context \fIname\fR is deleted.
+.PP
+Within the context, values may be generated as results by using the
+\fByield\fR command; if no \fIvalue\fR is supplied, the empty string is used.
+When that is called, the context will suspend execution and the
+\fBcoroutine\fR command will return the argument to \fByield\fR. The execution
+of the context can then be resumed by calling the context command, optionally
+passing in the \fIsingle\fR value to use as the result of the \fByield\fR call
+that caused
+the context to be suspended. If the coroutine context never yields and instead
+returns conventionally, the result of the \fBcoroutine\fR command will be the
+result of the evaluation of the context.
+.PP
+.VS TIP396
+The coroutine may also suspend its execution by use of the \fByieldto\fR
+command, which instead of returning, cedes execution to some command called
+\fIcommand\fR (resolved in the context of the coroutine) and to which \fIany
+number\fR of arguments may be passed. Since every coroutine has a context
+command, \fByieldto\fR can be used to transfer control directly from one
+coroutine to another (this is only advisable if the two coroutines are
+expecting this to happen) but \fIany\fR command may be the target. If a
+coroutine is suspended by this mechanism, the coroutine processing can be
+resumed by calling the context command optionally passing in an arbitrary
+number of arguments. The return value of the \fByieldto\fR call will be the
+list of arguments passed to the context command; it is up to the caller to
+decide what to do with those values.
+.PP
+The recommended way of writing a version of \fByield\fR that allows resumption
+with multiple arguments is by using \fByieldto\fR and the \fBreturn\fR
+command, like this:
+.PP
+.CS
+proc yieldm {value} {
+ \fByieldto\fR return -level 0 $value
+}
+.CE
+.VE TIP396
+.PP
+The coroutine can also be deleted by destroying the command \fIname\fR, and
+the name of the current coroutine can be retrieved by using
+\fBinfo coroutine\fR.
+If there are deletion traces on variables in the coroutine's
+implementation, they will fire at the point when the coroutine is explicitly
+deleted (or, naturally, if the command returns conventionally).
+.PP
+At the point when \fIcommand\fR is called, the current namespace will be the
+global namespace and there will be no stack frames above it (in the sense of
+\fBupvar\fR and \fBuplevel\fR). However, which command to call will be
+determined in the namespace that the \fBcoroutine\fR command was called from.
+.SH EXAMPLES
+.PP
+This example shows a coroutine that will produce an infinite sequence of
+even values, and a loop that consumes the first ten of them.
+.PP
+.CS
+proc allNumbers {} {
+ \fByield\fR
+ set i 0
+ while 1 {
+ \fByield\fR $i
+ incr i 2
+ }
+}
+\fBcoroutine\fR nextNumber allNumbers
+for {set i 0} {$i < 10} {incr i} {
+ puts "received [\fInextNumber\fR]"
+}
+rename nextNumber {}
+.CE
+.PP
+In this example, the coroutine acts to add up the arguments passed to it.
+.PP
+.CS
+\fBcoroutine\fR accumulator apply {{} {
+ set x 0
+ while 1 {
+ incr x [\fByield\fR $x]
+ }
+}}
+for {set i 0} {$i < 10} {incr i} {
+ puts "$i -> [\fIaccumulator\fR $i]"
+}
+.CE
+.PP
+This example demonstrates the use of coroutines to implement the classic Sieve
+of Eratosthenes algorithm for finding prime numbers. Note the creation of
+coroutines inside a coroutine.
+.PP
+.CS
+proc filterByFactor {source n} {
+ \fByield\fR [info coroutine]
+ while 1 {
+ set x [\fI$source\fR]
+ if {$x % $n} {
+ \fByield\fR $x
+ }
+ }
+}
+\fBcoroutine\fR allNumbers apply {{} {while 1 {\fByield\fR [incr x]}}}
+\fBcoroutine\fR eratosthenes apply {c {
+ \fByield\fR
+ while 1 {
+ set n [\fI$c\fR]
+ \fByield\fR $n
+ set c [\fBcoroutine\fR prime$n filterByFactor $c $n]
+ }
+}} allNumbers
+for {set i 1} {$i <= 20} {incr i} {
+ puts "prime#$i = [\fIeratosthenes\fR]"
+}
+.CE
+.PP
+.VS TIP396
+This example shows how a value can be passed around a group of three
+coroutines that yield to each other:
+.PP
+.CS
+proc juggler {name target {value ""}} {
+ if {$value eq ""} {
+ set value [\fByield\fR [info coroutine]]
+ }
+ while {$value ne ""} {
+ puts "$name : $value"
+ set value [string range $value 0 end-1]
+ lassign [\fByieldto\fR $target $value] value
+ }
+}
+\fBcoroutine\fR j1 juggler Larry [
+ \fBcoroutine\fR j2 juggler Curly [
+ \fBcoroutine\fR j3 juggler Moe j1]] "Nyuck!Nyuck!Nyuck!"
+.CE
+.VE TIP396
+.SS "DETAILED SEMANTICS"
+.PP
+This example demonstrates that coroutines start from the global namespace, and
+that \fIcommand\fR resolution happens before the coroutine stack is created.
+.PP
+.CS
+proc report {where level} {
+ # Where was the caller called from?
+ set ns [uplevel 2 {namespace current}]
+ \fByield\fR "made $where $level context=$ns name=[info coroutine]"
+}
+proc example {} {
+ report outer [info level]
+}
+namespace eval demo {
+ proc example {} {
+ report inner [info level]
+ }
+ proc makeExample {} {
+ puts "making from [info level]"
+ puts [\fBcoroutine\fR coroEg example]
+ }
+ makeExample
+}
+.CE
+.PP
+Which produces the output below. In particular, we can see that stack
+manipulation has occurred (comparing the levels from the first and second
+line) and that the parent level in the coroutine is the global namespace. We
+can also see that coroutine names are local to the current namespace if not
+qualified, and that coroutines may yield at depth (e.g., in called
+procedures).
+.PP
+.CS
+making from 2
+made inner 1 context=:: name=::demo::coroEg
+.CE
+.SH "SEE ALSO"
+apply(n), info(n), proc(n), return(n)
+.SH KEYWORDS
+coroutine, generator
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/pkgs/msgcat/doc/dde.n b/pkgs/msgcat/doc/dde.n
new file mode 100644
index 0000000..e4b51b7
--- /dev/null
+++ b/pkgs/msgcat/doc/dde.n
@@ -0,0 +1,184 @@
+'\"
+'\" Copyright (c) 1997 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 ActiveState Corporation.
+'\"
+'\" 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 dde n 1.4 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.4\fR
+.sp
+\fBdde servername\fR ?\fB\-force\fR? ?\fB\-handler \fIproc\fR? ?\fB\-\|\-\fR? ?\fItopic\fR?
+.sp
+.VS 8.6
+\fBdde execute\fR ?\fB\-async\fR? ?\fB\-binary\fR? \fIservice topic data\fR
+.sp
+\fBdde poke\fR ?\fB\-binary\fR? \fIservice topic item data\fR
+.VE 8.6
+.sp
+\fBdde request\fR ?\fB\-binary\fR? \fIservice topic item\fR
+.sp
+\fBdde services \fIservice topic\fR
+.sp
+\fBdde eval\fR ?\fB\-async\fR? \fItopic cmd \fR?\fIarg arg ...\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+This command allows an application to send Dynamic Data Exchange (DDE)
+command when running under Microsoft Windows. Dynamic Data Exchange is
+a mechanism where applications can exchange raw data. Each DDE
+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 names\fR and \fItopics\fR. For instance, Microsoft Excel
+has the service name \fBExcel\fR.
+.PP
+.SH "DDE COMMANDS"
+.PP
+The following commands are a subset of the full Dynamic Data Exchange
+set of commands.
+.TP
+\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. 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? ?\fB\-binary\fR? \fIservice topic data\fR
+.
+\fBdde execute\fR takes the \fIdata\fR and sends it to the server indicated
+by \fIservice\fR with the topic indicated by \fItopic\fR. Typically,
+\fIservice\fR is the name of an application, and \fItopic\fR is a file to
+work on. The \fIdata\fR field is given to the remote application.
+Typically, the application treats the \fIdata\fR field as a script, and the
+script is run in the application. The \fB\-async\fR option requests
+asynchronous invocation. The command returns an error message if the
+script did not run, unless the \fB\-async\fR flag was used, in which case
+the command returns immediately with no error.
+.VS 8.6
+The \fB\-binary\fR option treats \fIdata\fR as binary data, otherwise an utf-8
+string is sent. Combining \fB-binary\fR with the result of
+\fBencoding convertto\fR may be used to send data in arbitrary encodings.
+.VE 8.6
+.TP
+\fBdde poke ?\fB\-binary\fR? \fIservice topic item data\fR
+.
+\fBdde poke\fR passes the \fIdata\fR to the server indicated by
+\fIservice\fR using the \fItopic\fR and \fIitem\fR specified. Typically,
+\fIservice\fR is the name of an application. \fItopic\fR is application
+specific but can be a command to the server or the name of a file to work
+on. The \fIitem\fR is also application specific and is often not used, but
+it must always be non-null. The \fIdata\fR field is given to the remote
+application.
+.VS 8.6
+The \fB\-binary\fR option treats \fIdata\fR as binary data, otherwise an utf-8
+string is sent.
+.VE 8.6
+.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,
+\fItopic\fR is typically the name of the file, and \fIitem\fR is
+application-specific. The command returns the value of \fIitem\fR as
+defined in the application. Normally this is interpreted to be a
+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 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 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 send on Windows.
+.SH "DDE AND TCL"
+.PP
+A Tcl interpreter always has a service name of \fBTclEval\fR. Each
+different interpreter of all running Tcl applications must be
+given a unique
+name specified by \fBdde servername\fR. Each interp is available as a
+DDE topic only if the \fBdde servername\fR command was used to set the
+name of the topic for each interp. So a \fBdde services TclEval {}\fR
+command will return a list of service-topic pairs, where each of the
+currently running interps will be a topic.
+.PP
+When Tcl processes a \fBdde execute\fR command, the data for the
+execute is run as a script in the interp named by the topic of the
+\fBdde execute\fR command.
+.PP
+When Tcl processes a \fBdde request\fR command, it returns the value of the
+variable given in the dde command in the context of the interp named by the
+dde topic. Tcl reserves the variable \fB$TCLEVAL$EXECUTE$RESULT\fR for
+internal use, and \fBdde request\fR commands for that variable will give
+unpredictable results.
+.PP
+An external application which wishes to run a script in Tcl should have
+that script store its result in a variable, run the \fBdde execute\fR
+command, and then run \fBdde request\fR to get the value of the
+variable.
+.PP
+When using DDE, be careful to ensure that the event queue is flushed
+using either \fBupdate\fR or \fBvwait\fR. This happens by default
+when using \fBwish\fR unless a blocking command is called (such as \fBexec\fR
+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
+.PP
+This asks Internet Explorer (which must already be running) to go to a
+particularly important website:
+.PP
+.CS
+package require dde
+\fBdde execute\fR -async iexplore WWW_OpenURL http://www.tcl.tk/
+.CE
+.SH "SEE ALSO"
+tk(n), winfo(n), send(n)
+.SH KEYWORDS
+application, dde, name, remote execution
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/pkgs/msgcat/doc/define.n b/pkgs/msgcat/doc/define.n
new file mode 100644
index 0000000..6bdd9c5
--- /dev/null
+++ b/pkgs/msgcat/doc/define.n
@@ -0,0 +1,404 @@
+'\"
+'\" Copyright (c) 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 define n 0.3 TclOO "TclOO Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+oo::define, oo::objdefine \- define and configure classes and objects
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBoo::define\fI class defScript\fR
+\fBoo::define\fI class subcommand arg\fR ?\fIarg ...\fR?
+\fBoo::objdefine\fI object defScript\fR
+\fBoo::objdefine\fI object subcommand arg\fR ?\fIarg ...\fR?
+.fi
+.BE
+
+.SH DESCRIPTION
+The \fBoo::define\fR command is used to control the configuration of classes,
+and the \fBoo::objdefine\fR command is used to control the configuration of
+objects (including classes as instance objects), with the configuration being
+applied to the entity named in the \fIclass\fR or the \fIobject\fR argument.
+Configuring a class also updates the
+configuration of all subclasses of the class and all objects that are
+instances of that class or which mix it in (as modified by any per-instance
+configuration). The way in which the configuration is done is controlled by
+either the \fIdefScript\fR argument or by the \fIsubcommand\fR and following
+\fIarg\fR arguments; when the second is present, it is exactly as if all the
+arguments from \fIsubcommand\fR onwards are made into a list and that list is
+used as the \fIdefScript\fR argument.
+.SS "CONFIGURING CLASSES"
+.PP
+The following commands are supported in the \fIdefScript\fR for
+\fBoo::define\fR, each of which may also be used in the \fIsubcommand\fR form:
+.TP
+\fBconstructor\fI argList bodyScript\fR
+.
+This creates or updates the constructor for a class. The formal arguments to
+the constructor (defined using the same format as for the Tcl \fBproc\fR
+command) will be \fIargList\fR, and the body of the constructor will be
+\fIbodyScript\fR. When the body of the constructor is evaluated, the current
+namespace of the constructor will be a namespace that is unique to the object
+being constructed. Within the constructor, the \fBnext\fR command should be
+used to call the superclasses' constructors. If \fIbodyScript\fR is the empty
+string, the constructor will be deleted.
+.TP
+\fBdeletemethod\fI name\fR ?\fIname ...\fR
+.
+This deletes each of the methods called \fIname\fR from a class. The methods
+must have previously existed in that class. Does not affect the superclasses
+of the class, nor does it affect the subclasses or instances of the class
+(except when they have a call chain through the class being modified).
+.TP
+\fBdestructor\fI bodyScript\fR
+.
+This creates or updates the destructor for a class. Destructors take no
+arguments, and the body of the destructor will be \fIbodyScript\fR. The
+destructor is called when objects of the class are deleted, and when called
+will have the object's unique namespace as the current namespace. Destructors
+should use the \fBnext\fR command to call the superclasses' destructors. Note
+that destructors are not called in all situations (e.g. if the interpreter is
+destroyed). If \fIbodyScript\fR is the empty string, the destructor will be
+deleted.
+.RS
+Note that errors during the evaluation of a destructor \fIare not returned\fR
+to the code that causes the destruction of an object. Instead, they are passed
+to the currently-defined \fBbgerror\fR handler.
+.RE
+.TP
+\fBexport\fI name \fR?\fIname ...\fR?
+.
+This arranges for each of the named methods, \fIname\fR, to be exported
+(i.e. usable outside an instance through the instance object's command) by the
+class being defined. Note that the methods themselves may be actually defined
+by a superclass; subclass exports override superclass visibility, and may in
+turn be overridden by instances.
+.TP
+\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+sets or updates the list of method names that are used to guard whether
+method call to instances of the class may be called and what the method's
+results are. Each \fImethodName\fR names a single filtering method (which may
+be exposed or not exposed); it is not an error for a non-existent method to be
+named since they may be defined by subclasses.
+.VS
+By default, this slot works by appending.
+.VE
+.TP
+\fBforward\fI name cmdName \fR?\fIarg ...\fR?
+.
+This creates or updates a forwarded method called \fIname\fR. The method is
+defined be forwarded to the command called \fIcmdName\fR, with additional
+arguments, \fIarg\fR etc., added before those arguments specified by the
+caller of the method. The \fIcmdName\fR will always be resolved using the
+rules of the invoking objects' namespaces, i.e., when \fIcmdName\fR is not
+fully-qualified, the command will be searched for in each object's namespace,
+using the instances' namespace's path, or by looking in the global namespace.
+The method will be exported if \fIname\fR starts with a lower-case letter, and
+non-exported otherwise.
+.TP
+\fBmethod\fI name argList bodyScript\fR
+.
+This creates or updates a method that is implemented as a procedure-like
+script. The name of the method is \fIname\fR, the formal arguments to the
+method (defined using the same format as for the Tcl \fBproc\fR command) will
+be \fIargList\fR, and the body of the method will be \fIbodyScript\fR. When
+the body of the method is evaluated, the current namespace of the method will
+be a namespace that is unique to the current object. The method will be
+exported if \fIname\fR starts with a lower-case letter, and non-exported
+otherwise; this behavior can be overridden via \fBexport\fR and
+\fBunexport\fR.
+.TP
+\fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+sets or updates the list of additional classes that are to be mixed into
+all the instances of the class being defined. Each \fIclassName\fR argument
+names a single class that is to be mixed in.
+.VS
+By default, this slot works by replacement.
+.VE
+.TP
+\fBrenamemethod\fI fromName toName\fR
+.
+This renames the method called \fIfromName\fR in a class to \fItoName\fR. The
+method must have previously existed in the class, and \fItoName\fR must not
+previously refer to a method in that class. Does not affect the superclasses
+of the class, nor does it affect the subclasses or instances of the class
+(except when they have a call chain through the class being modified). Does
+not change the export status of the method; if it was exported before, it will
+be afterwards.
+.TP
+\fBself\fI subcommand arg ...\fR
+.TP
+\fBself\fI script\fR
+.
+This command is equivalent to calling \fBoo::objdefine\fR on the class being
+defined (see \fBCONFIGURING OBJECTS\fR below for a description of the
+supported values of \fIsubcommand\fR). It follows the same general pattern of
+argument handling as the \fBoo::define\fR and \fBoo::objdefine\fR commands,
+and
+.QW "\fBoo::define \fIcls \fBself \fIsubcommand ...\fR"
+operates identically to
+.QW "\fBoo::objdefine \fIcls subcommand ...\fR" .
+.TP
+\fBsuperclass\fI ?\fI\-slotOperation\fR? \fR?\fIclassName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+allows the alteration of the superclasses of the class being defined.
+Each \fIclassName\fR argument names one class that is to be a superclass of
+the defined class. Note that objects must not be changed from being classes to
+being non-classes or vice-versa, that an empty parent class is equivalent to
+\fBoo::object\fR, and that the parent classes of \fBoo::object\fR and
+\fBoo::class\fR may not be modified.
+.VS
+By default, this slot works by replacement.
+.VE
+.TP
+\fBunexport\fI name \fR?\fIname ...\fR?
+.
+This arranges for each of the named methods, \fIname\fR, to be not exported
+(i.e. not usable outside the instance through the instance object's command,
+but instead just through the \fBmy\fR command visible in each object's
+context) by the class being defined. Note that the methods themselves may be
+actually defined by a superclass; subclass unexports override superclass
+visibility, and may be overridden by instance unexports.
+.TP
+\fBvariable\fR ?\fI\-slotOperation\fR? ?\fIname ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below) arranges for each of the named
+variables to be automatically made
+available in the methods, constructor and destructor declared by the class
+being defined. Each variable name must not have any namespace
+separators and must not look like an array access. All variables will be
+actually present in the instance object on which the method is executed. Note
+that the variable lists declared by a superclass or subclass are completely
+disjoint, as are variable lists declared by instances; the list of variable
+names is just for methods (and constructors and destructors) declared by this
+class. By default, this slot works by appending.
+.VE
+.SS "CONFIGURING OBJECTS"
+.PP
+The following commands are supported in the \fIdefScript\fR for
+\fBoo::objdefine\fR, each of which may also be used in the \fIsubcommand\fR
+form:
+.TP
+\fBclass\fI className\fR
+.
+This allows the class of an object to be changed after creation. Note that the
+class's constructors are not called when this is done, and so the object may
+well be in an inconsistent state unless additional configuration work is done.
+.TP
+\fBdeletemethod\fI name\fR ?\fIname ...\fR
+.
+This deletes each of the methods called \fIname\fR from an object. The methods
+must have previously existed in that object. Does not affect the classes that
+the object is an instance of.
+.TP
+\fBexport\fI name \fR?\fIname ...\fR?
+.
+This arranges for each of the named methods, \fIname\fR, to be exported
+(i.e. usable outside the object through the object's command) by the object
+being defined. Note that the methods themselves may be actually defined by a
+class or superclass; object exports override class visibility.
+.TP
+\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+sets or updates the list of method names that are used to guard whether a
+method call to the object may be called and what the method's results are.
+Each \fImethodName\fR names a single filtering method (which may be exposed or
+not exposed); it is not an error for a non-existent method to be named. Note
+that the actual list of filters also depends on the filters set upon any
+classes that the object is an instance of.
+.VS
+By default, this slot works by appending.
+.VE
+.TP
+\fBforward\fI name cmdName \fR?\fIarg ...\fR?
+.
+This creates or updates a forwarded object method called \fIname\fR. The
+method is defined be forwarded to the command called \fIcmdName\fR, with
+additional arguments, \fIarg\fR etc., added before those arguments specified
+by the caller of the method. Forwarded methods should be deleted using the
+\fBmethod\fR subcommand. The method will be exported if \fIname\fR starts with
+a lower-case letter, and non-exported otherwise.
+.TP
+\fBmethod\fI name argList bodyScript\fR
+.
+This creates, updates or deletes an object method. The name of the method is
+\fIname\fR, the formal arguments to the method (defined using the same format
+as for the Tcl \fBproc\fR command) will be \fIargList\fR, and the body of the
+method will be \fIbodyScript\fR. When the body of the method is evaluated, the
+current namespace of the method will be a namespace that is unique to the
+object. The method will be exported if \fIname\fR starts with a lower-case
+letter, and non-exported otherwise.
+.TP
+\fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+sets or updates a per-object list of additional classes that are to be
+mixed into the object. Each argument, \fIclassName\fR, names a single class
+that is to be mixed in.
+.VS
+By default, this slot works by replacement.
+.VE
+.TP
+\fBrenamemethod\fI fromName toName\fR
+.
+This renames the method called \fIfromName\fR in an object to \fItoName\fR.
+The method must have previously existed in the object, and \fItoName\fR must
+not previously refer to a method in that object. Does not affect the classes
+that the object is an instance of. Does not change the export status of the
+method; if it was exported before, it will be afterwards.
+.TP
+\fBunexport\fI name \fR?\fIname ...\fR?
+.
+This arranges for each of the named methods, \fIname\fR, to be not exported
+(i.e. not usable outside the object through the object's command, but instead
+just through the \fBmy\fR command visible in the object's context) by the
+object being defined. Note that the methods themselves may be actually defined
+by a class; instance unexports override class visibility.
+.TP
+\fBvariable\fR ?\fI\-slotOperation\fR? ?\fIname ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below) arranges for each of the named
+variables to be automatically made available in the methods declared by the
+object being defined. Each variable name must not have any namespace
+separators and must not look like an array access. All variables will be
+actually present in the object on which the method is executed. Note that the
+variable lists declared by the classes and mixins of which the object is an
+instance are completely disjoint; the list of variable names is just for
+methods declared by this object. By default, this slot works by appending.
+.SH "SLOTTED DEFINITIONS"
+Some of the configurable definitions of a class or object are \fIslotted
+definitions\fR. This means that the configuration is implemented by a slot
+object, that is an instance of the class \fBoo::Slot\fR, which manages a list
+of values (class names, variable names, etc.) that comprises the contents of
+the slot. The class defines three operations (as methods) that may be done on
+the slot:
+.VE
+.TP
+\fIslot\fR \fB\-append\fR ?\fImember ...\fR?
+.VS
+This appends the given \fImember\fR elements to the slot definition.
+.VE
+.TP
+\fIslot\fR \fB\-clear\fR
+.VS
+This sets the slot definition to the empty list.
+.VE
+.TP
+\fIslot\fR \fB\-set\fR ?\fImember ...\fR?
+.VS
+This replaces the slot definition with the given \fImember\fR elements.
+.PP
+A consequence of this is that any use of a slot's default operation where the
+first member argument begins with a hyphen will be an error. One of the above
+operations should be used explicitly in those circumstances.
+.SS "SLOT IMPLEMENTATION"
+Internally, slot objects also define a method \fB\-\-default\-operation\fR
+which is forwarded to the default operation of the slot (thus, for the class
+.QW \fBvariable\fR
+slot, this is forwarded to
+.QW "\fBmy \-append\fR" ),
+and these methods which provide the implementation interface:
+.VE
+.TP
+\fIslot\fR \fBGet\fR
+.VS
+Returns a list that is the current contents of the slot. This method must
+always be called from a stack frame created by a call to \fBoo::define\fR or
+\fBoo::objdefine\fR.
+.VE
+.TP
+\fIslot\fR \fBSet \fIelementList\fR
+.VS
+Sets the contents of the slot to the list \fIelementList\fR and returns the
+empty string. This method must always be called from a stack frame created by
+a call to \fBoo::define\fR or \fBoo::objdefine\fR.
+.PP
+The implementation of these methods is slot-dependent (and responsible for
+accessing the correct part of the class or object definition). Slots also have
+an unknown method handler to tie all these pieces together, and they hide
+their \fBdestroy\fR method so that it is not invoked inadvertently. It is
+\fIrecommended\fR that any user changes to the slot mechanism be restricted to
+defining new operations whose names start with a hyphen.
+.VE
+.SH EXAMPLES
+This example demonstrates how to use both forms of the \fBoo::define\fR and
+\fBoo::objdefine\fR commands (they work in the same way), as well as
+illustrating four of the subcommands of them.
+.PP
+.CS
+oo::class create c
+c create o
+\fBoo::define\fR c \fBmethod\fR foo {} {
+ puts "world"
+}
+\fBoo::objdefine\fR o {
+ \fBmethod\fR bar {} {
+ my Foo "hello "
+ my foo
+ }
+ \fBforward\fR Foo ::puts -nonewline
+ \fBunexport\fR foo
+}
+o bar \fI\(-> prints "hello world"\fR
+o foo \fI\(-> error "unknown method foo"\fR
+o Foo Bar \fI\(-> error "unknown method Foo"\fR
+\fBoo::objdefine\fR o \fBrenamemethod\fR bar lollipop
+o lollipop \fI\(-> prints "hello world"\fR
+.CE
+.PP
+This example shows how additional classes can be mixed into an object. It also
+shows how \fBmixin\fR is a slot that supports appending:
+.PP
+.CS
+oo::object create inst
+inst m1 \fI\(-> error "unknown method m1"\fR
+inst m2 \fI\(-> error "unknown method m2"\fR
+
+oo::class create A {
+ \fBmethod\fR m1 {} {
+ puts "red brick"
+ }
+}
+\fBoo::objdefine\fR inst {
+ \fBmixin\fR A
+}
+inst m1 \fI\(-> prints "red brick"\fR
+inst m2 \fI\(-> error "unknown method m2"\fR
+
+oo::class create B {
+ \fBmethod\fR m2 {} {
+ puts "blue brick"
+ }
+}
+\fBoo::objdefine\fR inst {
+ \fBmixin -append\fR B
+}
+inst m1 \fI\(-> prints "red brick"\fR
+inst m2 \fI\(-> prints "blue brick"\fR
+.CE
+.SH "SEE ALSO"
+next(n), oo::class(n), oo::object(n)
+.SH KEYWORDS
+class, definition, method, object, slot
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/pkgs/msgcat/doc/dict.n b/pkgs/msgcat/doc/dict.n
new file mode 100644
index 0000000..361a112
--- /dev/null
+++ b/pkgs/msgcat/doc/dict.n
@@ -0,0 +1,416 @@
+'\"
+'\" 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\fR ?\fIglobPattern ...\fR?
+.VS 8.6
+The key rule only matches those key/value pairs whose keys match any
+of the given patterns (in the style of \fBstring match\fR.)
+.VE 8.6
+.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 \fR?\fIglobPattern ...\fR?
+.VS 8.6
+The value rule only matches those key/value pairs whose values match any
+of the given patterns (in the style of \fBstring match\fR.)
+.VE 8.6
+.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, lambda term for \fBapply\fR, or method). 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, lambda term for \fBapply\fR, or method). 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
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/encoding.n b/pkgs/msgcat/doc/encoding.n
new file mode 100644
index 0000000..5269a18
--- /dev/null
+++ b/pkgs/msgcat/doc/encoding.n
@@ -0,0 +1,95 @@
+'\"
+'\" Copyright (c) 1998 by Scriptics Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH encoding n "8.1" Tcl "Tcl Built-In Commands"
+.BS
+.SH NAME
+encoding \- Manipulate encodings
+.SH SYNOPSIS
+\fBencoding \fIoption\fR ?\fIarg arg ...\fR?
+.BE
+.SH INTRODUCTION
+.PP
+Strings in Tcl are encoded using 16-bit Unicode characters. Different
+operating system interfaces or applications may generate strings in
+other encodings such as Shift-JIS. The \fBencoding\fR command helps
+to bridge the gap between Unicode and these other formats.
+.SH DESCRIPTION
+.PP
+Performs one of several encoding related operations, depending on
+\fIoption\fR. The legal \fIoption\fRs are:
+.TP
+\fBencoding convertfrom\fR ?\fIencoding\fR? \fIdata\fR
+.
+Convert \fIdata\fR to Unicode from the specified \fIencoding\fR. The
+characters in \fIdata\fR are treated as binary data where the lower
+8-bits of each character is taken as a single byte. The resulting
+sequence of bytes is treated as a string in the specified
+\fIencoding\fR. If \fIencoding\fR is not specified, the current
+system encoding is used.
+.TP
+\fBencoding convertto\fR ?\fIencoding\fR? \fIstring\fR
+.
+Convert \fIstring\fR from Unicode to the specified \fIencoding\fR.
+The result is a sequence of bytes that represents the converted
+string. Each byte is stored in the lower 8-bits of a Unicode
+character. If \fIencoding\fR is not specified, the current
+system encoding is used.
+.TP
+\fBencoding dirs\fR ?\fIdirectoryList\fR?
+.
+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.
+.TP
+\fBencoding names\fR
+.
+Returns a list containing the names of all of the encodings that are
+currently available.
+.TP
+\fBencoding system\fR ?\fIencoding\fR?
+.
+Set the system encoding to \fIencoding\fR. If \fIencoding\fR is
+omitted then the command returns the current system encoding. The
+system encoding is used whenever Tcl passes strings to system calls.
+.SH EXAMPLE
+.PP
+It is common practice to write script files using a text editor that
+produces output in the euc-jp encoding, which represents the ASCII
+characters as singe bytes and Japanese characters as two bytes. This
+makes it easy to embed literal strings that correspond to non-ASCII
+characters by simply typing the strings in place in the script.
+However, because the \fBsource\fR command always reads files using the
+current system encoding, Tcl will only source such files correctly
+when the encoding used to write the file is the same. This tends not
+to be true in an internationalized setting. For example, if such a
+file was sourced in North America (where the ISO8859-1 is normally
+used), each byte in the file would be treated as a separate character
+that maps to the 00 page in Unicode. The resulting Tcl strings will
+not contain the expected Japanese characters. Instead, they will
+contain a sequence of Latin-1 characters that correspond to the bytes
+of the original string. The \fBencoding\fR command can be used to
+convert this string to the expected Japanese Unicode characters. For
+example,
+.PP
+.CS
+set s [\fBencoding convertfrom\fR euc-jp "\exA4\exCF"]
+.CE
+.PP
+would return the Unicode string
+.QW "\eu306F" ,
+which is the Hiragana letter HA.
+.SH "SEE ALSO"
+Tcl_GetEncoding(3)
+.SH KEYWORDS
+encoding, unicode
diff --git a/pkgs/msgcat/doc/eof.n b/pkgs/msgcat/doc/eof.n
new file mode 100644
index 0000000..017b10e
--- /dev/null
+++ b/pkgs/msgcat/doc/eof.n
@@ -0,0 +1,61 @@
+'\"
+'\" 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 eof n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+eof \- Check for end of file condition on channel
+.SH SYNOPSIS
+\fBeof \fIchannelId\fR
+.BE
+.SH DESCRIPTION
+.PP
+Returns 1 if an end of file condition occurred during the most
+recent input operation on \fIchannelId\fR (such as \fBgets\fR),
+0 otherwise.
+.PP
+\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.
+.SH EXAMPLES
+.PP
+Read and print out the contents of a file line-by-line:
+.PP
+.CS
+set f [open somefile.txt]
+while {1} {
+ set line [gets $f]
+ if {[\fBeof\fR $f]} {
+ close $f
+ break
+ }
+ puts "Read line: $line"
+}
+.CE
+.PP
+Read and print out the contents of a file by fixed-size records:
+.PP
+.CS
+set f [open somefile.dat]
+fconfigure $f -translation binary
+set recordSize 40
+while {1} {
+ set record [read $f $recordSize]
+ if {[\fBeof\fR $f]} {
+ close $f
+ break
+ }
+ puts "Read record: $record"
+}
+.CE
+.SH "SEE ALSO"
+file(n), open(n), close(n), fblocked(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+channel, end of file
diff --git a/pkgs/msgcat/doc/error.n b/pkgs/msgcat/doc/error.n
new file mode 100644
index 0000000..d61bd7b
--- /dev/null
+++ b/pkgs/msgcat/doc/error.n
@@ -0,0 +1,78 @@
+'\"
+'\" 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 error n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+error \- Generate an error
+.SH SYNOPSIS
+\fBerror \fImessage\fR ?\fIinfo\fR? ?\fIcode\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+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
+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 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:
+.PP
+.CS
+catch {...} errMsg
+set savedInfo $::errorInfo
+\&...
+\fBerror\fR $errMsg $savedInfo
+.CE
+.PP
+When working with Tcl 8.5 or later, the following code
+should be used instead:
+.PP
+.CS
+catch {...} errMsg options
+\&...
+return -options $options $errMsg
+.CE
+.PP
+If the \fIcode\fR argument is present, then its value is stored
+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
+.PP
+Generate an error if a basic mathematical operation fails:
+.PP
+.CS
+if {1+2 != 3} {
+ \fBerror\fR "something is very wrong with addition"
+}
+.CE
+.SH "SEE ALSO"
+catch(n), return(n)
+.SH KEYWORDS
+error, exception
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/eval.n b/pkgs/msgcat/doc/eval.n
new file mode 100644
index 0000000..da88757
--- /dev/null
+++ b/pkgs/msgcat/doc/eval.n
@@ -0,0 +1,83 @@
+'\"
+'\" 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 eval n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+eval \- Evaluate a Tcl script
+.SH SYNOPSIS
+\fBeval \fIarg \fR?\fIarg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+\fBEval\fR takes one or more arguments, which together comprise a Tcl
+script containing one or more commands.
+\fBEval\fR concatenates all its arguments in the same
+fashion as the \fBconcat\fR command, passes the concatenated string to the
+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 EXAMPLES
+.PP
+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:
+.PP
+.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
+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.
+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:
+.PP
+.CS
+proc lprepend {varName args} {
+ upvar 1 $varName var
+ # Ensure that the variable exists and contains a list
+ lappend var
+ # Now we insert all the arguments in one go
+ set var [\fBeval\fR [list linsert $var 0] $args]
+}
+.CE
+.PP
+However, the last line would now normally be written without
+\fBeval\fR, like this:
+.PP
+.CS
+set var [linsert $var 0 {*}$args]
+.CE
+.SH "SEE ALSO"
+catch(n), concat(n), error(n), interp(n), list(n), namespace(n), subst(n), tclvars(n), uplevel(n)
+.SH KEYWORDS
+concatenate, evaluate, script
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/exec.n b/pkgs/msgcat/doc/exec.n
new file mode 100644
index 0000000..5072d61
--- /dev/null
+++ b/pkgs/msgcat/doc/exec.n
@@ -0,0 +1,516 @@
+'\"
+'\" 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 8.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+exec \- Invoke subprocesses
+.SH SYNOPSIS
+\fBexec \fR?\fIswitches\fR? \fIarg \fR?\fIarg ...\fR? ?\fB&\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command treats its arguments as the specification
+of one or more subprocesses to execute.
+The arguments take the form of a standard shell pipeline
+where each \fIarg\fR becomes one word of a command, and
+each distinct command becomes a subprocess.
+.PP
+If the initial arguments to \fBexec\fR start with \fB\-\fR then
+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
+.
+Stops the \fBexec\fR command from treating the output of messages to the
+pipeline's standard error channel as an error case.
+.TP 13
+\fB\-keepnewline\fR
+.
+Retains a trailing newline in the pipeline's output.
+Normally a trailing newline will be deleted.
+.TP 13
+\fB\-\|\-\fR
+.
+Marks the end of switches. The argument following this one will
+be treated as the first \fIarg\fR even if it starts with a \fB\-\fR.
+.PP
+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
+.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
+\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
+\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
+\fB<<\0\fIvalue\fR
+.
+\fIValue\fR is passed to the first command as its standard input.
+.TP 15
+\fB>\0\fIfileName\fR
+.
+Standard output from the last command is redirected to the file named
+\fIfileName\fR, overwriting its previous contents.
+.TP 15
+\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
+\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
+\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
+\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
+\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
+\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
+\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
+\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
+all commands are redirected to \fIfileId\fR's file.
+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, unless
+.QW 2>@1
+was specified, in which case standard error is included as well.
+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
+\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 is not redirected
+and \fB\-ignorestderr\fR is not specified,
+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
+output.
+.PP
+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 do not
+normally end with newlines.
+However, if \fB\-keepnewline\fR is specified then the trailing
+newline is retained.
+.PP
+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
+.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 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.
+.PP
+The first word in each command is taken as the command name;
+tilde-substitution is performed on it, and if the result contains
+no slashes then the directories
+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
+.QW glob
+expansion or other shell-like substitutions
+are performed on the arguments to commands.
+.SH "PORTABILITY ISSUES"
+.TP
+\fBWindows\fR (all versions)
+.
+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.
+.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.
+.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
+as path separators. Bear in mind, however, that most Windows applications
+accept arguments with forward slashes only as option delimiters and
+backslashes only in paths. Any arguments to an application that specify a
+path name with forward slashes will not automatically be converted to use
+the backslash character. If an argument contains forward slashes as the
+path separator, it may or may not be recognized as a path name, depending on
+the program.
+.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
+.QW applba~1.def
+instead of
+.QW applbakery.default ),
+which can be obtained with the
+.QW "\fBfile attributes\fI fileName \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
+\fBc://windows/system\fR (two slashes together), which refers to the mount
+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.
+.PP
+Note that there are two general types of Win32 console applications:
+.RS
+.IP [1]
+CLI \(em CommandLine Interface, simple stdio exchange. \fBnetstat.exe\fR for
+example.
+.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.
+.RE
+.TP
+\fBWindows NT\fR
+.
+When attempting to execute an application, \fBexec\fR first searches for
+the name as it was specified. Then, in order, \fB.com\fR, \fB.exe\fR, and
+\fB.bat\fR are appended to the end of the specified name and it searches
+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:
+.RS
+.IP \(bu 3
+The directory from which the Tcl executable was loaded.
+.IP \(bu 3
+The current directory.
+.IP \(bu 3
+The Windows NT 32-bit system directory.
+.IP \(bu 3
+The Windows NT 16-bit system directory.
+.IP \(bu 3
+The Windows NT home directory.
+.IP \(bu 3
+The directories listed in the path.
+.PP
+In order to execute shell built-in commands like \fBdir\fR and \fBcopy\fR,
+the caller must prepend the desired command with
+.QW "\fBcmd.exe /c\0\fR"
+because built-in commands are not implemented using executables.
+.RE
+.TP
+\fBWindows 9x\fR
+.
+When attempting to execute an application, \fBexec\fR first searches for
+the name as it was specified. Then, in order, \fB.com\fR, \fB.exe\fR, and
+\fB.bat\fR are appended to the end of the specified name and it searches
+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:
+.RS
+.IP \(bu 3
+The directory from which the Tcl executable was loaded.
+.IP \(bu 3
+The current directory.
+.IP \(bu 3
+The Windows 9x system directory.
+.IP \(bu 3
+The Windows 9x home directory.
+.IP \(bu 3
+The directories listed in the path.
+.RE
+.RS
+.PP
+In order to execute shell built-in commands like \fBdir\fR and \fBcopy\fR,
+the caller must prepend the desired command with
+.QW "\fBcommand.com /c\0\fR"
+because built-in commands are not implemented using executables.
+.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.
+.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
+.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.
+.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
+begins executing. All standard output or error from a 16-bit DOS
+application to a pipe is collected into temporary files; the application
+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.
+.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
+output may fail, hang Tcl, or even hang the system if their own private
+console window is not available to them.
+.RE
+.TP
+\fBUnix\fR (including Mac OS X)
+.
+The \fBexec\fR command is fully functional and works as described.
+.SH "UNIX EXAMPLES"
+.PP
+Here are some examples of the use of the \fBexec\fR command on Unix.
+To execute a simple program and get its result:
+.PP
+.CS
+\fBexec\fR uname -a
+.CE
+.SS "WORKING WITH NON-ZERO RESULTS"
+.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 the contents
+of the \fB\-errorcode\fR return option if you have an error:
+.PP
+.CS
+set status 0
+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 other error; regenerate it to let caller handle
+ return -options $options -level 0 $results
+ }
+}
+.CE
+.VS 8.6
+.PP
+This is more easily written using the \fBtry\fR command, as that makes
+it simpler to trap specific types of errors. This is
+done using code like this:
+.PP
+.CS
+try {
+ set results [\fBexec\fR grep foo bar.txt]
+ set status 0
+} trap CHILDSTATUS {results options} {
+ set status [lindex [dict get $options -errorcode] 2]
+}
+.CE
+.VE 8.6
+.SS "WORKING WITH QUOTED ARGUMENTS"
+.PP
+When translating a command from a Unix shell invocation, care should
+be taken over the fact that single quote characters have no special
+significance to Tcl. Thus:
+.PP
+.CS
+awk '{sum += $1} END {print sum}' numbers.list
+.CE
+.PP
+would be translated into something like:
+.PP
+.CS
+\fBexec\fR awk {{sum += $1} END {print sum}} numbers.list
+.CE
+.SS "WORKING WITH GLOBBING"
+.PP
+If you are converting invocations involving shell globbing, you should
+remember that Tcl does not handle globbing or expand things into
+multiple arguments by default. Instead you should write things like
+this:
+.PP
+.CS
+\fBexec\fR ls -l {*}[glob *.tcl]
+.CE
+.SS "WORKING WITH USER-SUPPLIED SHELL SCRIPT FRAGMENTS"
+.PP
+One useful technique can be to expose to users of a script the ability
+to specify a fragment of shell script to execute that will have some
+data passed in on standard input that was produced by the Tcl program.
+This is a common technique for using the \fIlpr\fR program for
+printing. By far the simplest way of doing this is to pass the user's
+script to the user's shell for processing, as this avoids a lot of
+complexity with parsing other languages.
+.PP
+.CS
+set lprScript [\fIget from user...\fR]
+set postscriptData [\fIgenerate somehow...\fR]
+
+\fBexec\fR $env(SHELL) -c $lprScript << $postscriptData
+.CE
+.SH "WINDOWS EXAMPLES"
+.PP
+Here are some examples of the use of the \fBexec\fR command on Windows.
+To start an instance of \fInotepad\fR editing a file without waiting
+for the user to finish editing the file:
+.PP
+.CS
+\fBexec\fR notepad myfile.txt &
+.CE
+.PP
+To print a text file using \fInotepad\fR:
+.PP
+.CS
+\fBexec\fR notepad /p myfile.txt
+.CE
+.SS "WORKING WITH CONSOLE PROGRAMS"
+.PP
+If a program calls other programs, such as is common with compilers,
+then you may need to resort to batch files to hide the console windows
+that sometimes pop up:
+.PP
+.CS
+\fBexec\fR cmp.bat somefile.c -o somefile
+.CE
+.PP
+With the file \fIcmp.bat\fR looking something like:
+.PP
+.CS
+@gcc %1 %2 %3 %4 %5 %6 %7 %8 %9
+.CE
+.SS "WORKING WITH COMMAND BUILT-INS"
+.PP
+Sometimes you need to be careful, as different programs may have the
+same name and be in the path. It can then happen that typing a command
+at the DOS prompt finds \fIa different program\fR than the same
+command run via \fBexec\fR. This is because of the (documented)
+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
+.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:
+.PP
+.CS
+\fBexec\fR {*}[auto_execok dir] *.tcl
+.CE
+.SS "WORKING WITH NATIVE FILENAMES"
+.PP
+Many programs on Windows require filename arguments to be passed in with
+backslashes as pathname separators. This is done with the help of the
+\fBfile nativename\fR command. For example, to make a directory (on NTFS)
+encrypted so that only the current user can access it requires use of
+the \fICIPHER\fR command, like this:
+.PP
+.CS
+set secureDir "~/Desktop/Secure Directory"
+file mkdir $secureDir
+\fBexec\fR CIPHER /e /s:[file nativename $secureDir]
+.CE
+.SH "SEE ALSO"
+error(n), file(n), open(n)
+.SH KEYWORDS
+execute, pipeline, redirection, subprocess
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/exit.n b/pkgs/msgcat/doc/exit.n
new file mode 100644
index 0000000..ceb0529
--- /dev/null
+++ b/pkgs/msgcat/doc/exit.n
@@ -0,0 +1,51 @@
+'\"
+'\" 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 exit n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+exit \- End the application
+.SH SYNOPSIS
+\fBexit \fR?\fIreturnCode\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+Terminate the process, returning \fIreturnCode\fR to the
+system as the exit status.
+If \fIreturnCode\fR is not specified then it defaults
+to 0.
+.SH EXAMPLE
+.PP
+Since non-zero exit codes are usually interpreted as error cases by
+the calling process, the \fBexit\fR command is an important part of
+signaling that something fatal has gone wrong. This code fragment is
+useful in scripts to act as a general problem trap:
+.PP
+.CS
+proc main {} {
+ # ... put the real main code in here ...
+}
+
+if {[catch {main} msg options]} {
+ puts stderr "unexpected script error: $msg"
+ if {[info exist env(DEBUG)]} {
+ puts stderr "---- BEGIN TRACE ----"
+ puts stderr [dict get $options -errorinfo]
+ puts stderr "---- END TRACE ----"
+ }
+
+ # Reserve code 1 for "expected" error exits...
+ \fBexit\fR 2
+}
+.CE
+.SH "SEE ALSO"
+exec(n)
+.SH KEYWORDS
+abort, exit, process
diff --git a/pkgs/msgcat/doc/expr.n b/pkgs/msgcat/doc/expr.n
new file mode 100644
index 0000000..6d965fb
--- /dev/null
+++ b/pkgs/msgcat/doc/expr.n
@@ -0,0 +1,463 @@
+'\"
+'\" 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.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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 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
+.PP
+.CS
+\fBexpr\fR 8.2 + 6
+.CE
+.PP
+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, 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 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 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.
+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
+Operands may be specified in any of the following ways:
+.IP [1]
+As a numeric value, either integer or floating-point.
+.IP [2]
+As a boolean value, using any form understood by \fBstring is\fR
+\fBboolean\fR.
+.IP [3]
+As a Tcl variable, using standard \fB$\fR notation.
+The variable's value will be used as the operand.
+.IP [4]
+As a string enclosed in double-quotes.
+The expression parser will perform backslash, variable, and
+command substitutions on the information between the quotes,
+and use the resulting value as the operand
+.IP [5]
+As a string enclosed in braces.
+The characters between the open brace and matching close brace
+will be used as the operand without any substitutions.
+.IP [6]
+As a Tcl command enclosed in brackets.
+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 \fBMATH FUNCTIONS\fR below for
+a discussion of how mathematical functions are handled.
+.PP
+Where the above substitutions occur (e.g. inside quoted strings), they
+are performed by the expression's instructions.
+However, the command parser may already have performed one round of
+substitution before the expression processor was called.
+As discussed below, it is usually best to enclose expressions
+in braces to prevent the command parser from performing substitutions
+on the contents.
+.PP
+For some examples of simple expressions, suppose the variable
+\fBa\fR has the value 3 and
+the variable \fBb\fR has the value 6.
+Then the command on the left side of each of the lines below
+will produce the value on the right side of the line:
+.PP
+.CS
+.ta 6c
+\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
+.SS OPERATORS
+.PP
+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
+.
+Exponentiation. Valid for any numeric operands.
+.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
+to integers.
+The remainder will always have the same sign as the divisor and
+an absolute value smaller than the absolute value of the divisor.
+.RS
+.PP
+When applied to integers, the division and remainder operators can be
+considered to partition the number line into a sequence of equal-sized
+adjacent non-overlapping pieces where each piece is the size of the divisor;
+the division result identifies which piece the divisor lay within, and the
+remainder result identifies where within that piece the divisor lay. A
+consequence of this is that the result of
+.QW "-57 \fB/\fR 10"
+is always -6, and the result of
+.QW "-57 \fB%\fR 10"
+is always 3.
+.RE
+.TP 20
+\fB+\0\0\-\fR
+.
+Add and subtract. Valid for any numeric operands.
+.TP 20
+\fB<<\0\0>>\fR
+.
+Left and right shift. Valid for integer operands only.
+A right shift always propagates the sign bit.
+.TP 20
+\fB<\0\0>\0\0<=\0\0>=\fR
+.
+Boolean less, greater, less than or equal, and greater than or equal.
+Each operator produces 1 if the condition is true, 0 otherwise.
+These operators may be applied to strings as well as numeric operands,
+in which case string comparison is used.
+.TP 20
+\fB==\0\0!=\fR
+.
+Boolean equal and not equal. Each operator produces a zero/one result.
+Valid for all operand types.
+.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.
+.TP 20
+\fBin\0\0ni\fR
+.
+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.
+.TP 20
+\fB&\fR
+.
+Bit-wise AND. Valid for integer operands only.
+.TP 20
+\fB^\fR
+.
+Bit-wise exclusive OR. Valid for integer operands only.
+.TP 20
+\fB|\fR
+.
+Bit-wise OR. Valid for integer operands only.
+.TP 20
+\fB&&\fR
+.
+Logical AND. Produces a 1 result if both operands are non-zero,
+0 otherwise.
+Valid for boolean and numeric (integers or floating-point) operands only.
+.TP 20
+\fB||\fR
+.
+Logical OR. Produces a 0 result if both operands are zero, 1 otherwise.
+Valid for boolean and numeric (integers or floating-point) operands only.
+.TP 20
+\fIx\fB?\fIy\fB:\fIz\fR
+.
+If-then-else, as in C. If \fIx\fR
+evaluates to non-zero, then the result is the value of \fIy\fR.
+Otherwise the result is the value of \fIz\fR.
+The \fIx\fR operand must have a boolean or numeric value.
+.PP
+See the C manual for more details on the results
+produced by each operator.
+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.)
+All of the binary operators but exponentiation group left-to-right
+within the same precedence level; exponentiation groups right-to-left. For example, the command
+.PP
+.CS
+\fBexpr\fR {4*2 < 7}
+.CE
+.PP
+returns 0, while
+.PP
+.CS
+\fBexpr\fR {2**3**2}
+.CE
+.PP
+returns 512.
+.PP
+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
+.PP
+.CS
+\fBexpr\fR {$v ? [a] : [b]}
+.CE
+.PP
+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
+.QW \fB[a]\fR
+and
+.QW \fB[b]\fR
+before invoking the \fBexpr\fR command.
+.SS "MATH FUNCTIONS"
+.PP
+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:
+.PP
+.CS
+\fBexpr\fR {sin($x+$y)}
+.CE
+.PP
+is the same in every way as the processing of:
+.PP
+.CS
+\fBexpr\fR {[tcl::mathfunc::sin [\fBexpr\fR {$x+$y}]]}
+.CE
+.PP
+which in turn is the same as the processing of:
+.PP
+.CS
+tcl::mathfunc::sin [\fBexpr\fR {$x+$y}]
+.CE
+.PP
+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
+See the \fBmathfunc\fR(n) manual page for the math functions that are
+available by default.
+.SS "TYPES, OVERFLOW, AND PRECISION"
+.PP
+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.
+.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 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
+Conversion among internal representations for integer, floating-point,
+and string operands is done automatically as needed.
+For arithmetic computations, integers are used until some
+floating-point number is introduced, after which floating-point is used.
+For example,
+.PP
+.CS
+\fBexpr\fR {5 / 4}
+.CE
+.PP
+returns 1, while
+.PP
+.CS
+\fBexpr\fR {5 / 4.0}
+\fBexpr\fR {5 / ( [string length "abcd"] + 0.0 )}
+.CE
+.PP
+both return 1.25.
+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,
+.PP
+.CS
+\fBexpr\fR {20.0/5.0}
+.CE
+.PP
+returns \fB4.0\fR, not \fB4\fR.
+.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,
+i.e., when all arguments to the operator allow numeric interpretations,
+except in the case of the \fBeq\fR and \fBne\fR operators.
+If one of the operands of a comparison is a string and the other
+has a numeric value, a canonical string representation of the numeric
+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
+.PP
+.CS
+\fBexpr\fR {"0x03" > "2"}
+\fBexpr\fR {"0y" > "0x12"}
+.CE
+.PP
+both return 1. The first comparison is done using integer
+comparison, and the second is done using string comparison.
+Because of Tcl's tendency to treat values as numbers whenever
+possible, it is not generally a good idea to use operators like \fB==\fR
+when you really want string comparison and the values of the
+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
+storage requirements.
+This allows the Tcl bytecode compiler to generate the best code.
+.PP
+As mentioned above, expressions are substituted twice:
+once by the Tcl parser and once by the \fBexpr\fR command.
+For example, the commands
+.PP
+.CS
+set a 3
+set b {$a + 2}
+\fBexpr\fR $b*4
+.CE
+.PP
+return 11, not a multiple of 4.
+This is because the Tcl parser will first substitute \fB$a + 2\fR for
+the variable \fBb\fR,
+then the \fBexpr\fR command will evaluate the expression \fB$a + 2*4\fR.
+.PP
+Most expressions do not require a second round of substitutions.
+Either they are enclosed in braces or, if not,
+their variable and command substitutions yield numbers or strings
+that do not themselves require substitutions.
+However, because a few unbraced expressions
+need two rounds of substitutions,
+the bytecode compiler must emit
+additional instructions to handle this situation.
+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.
+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.
+.SH EXAMPLES
+.PP
+Define a procedure that computes an
+.QW interesting
+mathematical function:
+.PP
+.CS
+proc tcl::mathfunc::calc {x y} {
+ \fBexpr\fR { ($x**2 - $y**2) / exp($x**2 + $y**2) }
+}
+.CE
+.PP
+Convert polar coordinates into cartesian coordinates:
+.PP
+.CS
+# convert from ($radius,$angle)
+set x [\fBexpr\fR { $radius * cos($angle) }]
+set y [\fBexpr\fR { $radius * sin($angle) }]
+.CE
+.PP
+Convert cartesian coordinates into polar coordinates:
+.PP
+.CS
+# convert from ($x,$y)
+set radius [\fBexpr\fR { hypot($y, $x) }]
+set angle [\fBexpr\fR { atan2($y, $x) }]
+.CE
+.PP
+Print a message describing the relationship of two string values to
+each other:
+.PP
+.CS
+puts "a and b are [\fBexpr\fR {$a eq $b ? {equal} : {different}}]"
+.CE
+.PP
+Set a variable to whether an environment variable is both defined at
+all and also set to a true boolean value:
+.PP
+.CS
+set isTrue [\fBexpr\fR {
+ [info exists ::env(SOME_ENV_VAR)] &&
+ [string is true -strict $::env(SOME_ENV_VAR)]
+}]
+.CE
+.PP
+Generate a random integer in the range 0..99 inclusive:
+.PP
+.CS
+set randNum [\fBexpr\fR { int(100 * rand()) }]
+.CE
+.SH "SEE ALSO"
+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
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/fblocked.n b/pkgs/msgcat/doc/fblocked.n
new file mode 100644
index 0000000..2841aee
--- /dev/null
+++ b/pkgs/msgcat/doc/fblocked.n
@@ -0,0 +1,67 @@
+'\"
+'\" 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.
+'\"
+.TH fblocked n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+fblocked \- Test whether the last input operation exhausted all available input
+.SH SYNOPSIS
+\fBfblocked \fIchannelId\fR
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBfblocked\fR command returns 1 if the most recent input operation
+on \fIchannelId\fR returned less information than requested because all
+available input was exhausted.
+For example, if \fBgets\fR is invoked when there are only three
+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
+\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.
+.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
+without preventing the servicing of other connections. This can be
+seen in this simple echo-service:
+.PP
+.CS
+# This is called whenever a new client connects to the server
+proc connect {chan host port} {
+ set clientName [format <%s:%d> $host $port]
+ puts "connection from $clientName"
+ fconfigure $chan -blocking 0 -buffering line
+ fileevent $chan readable [list echoLine $chan $clientName]
+}
+
+# This is called whenever either at least one byte of input
+# data is available, or the channel was closed by the client.
+proc echoLine {chan clientName} {
+ gets $chan line
+ if {[eof $chan]} {
+ puts "finishing connection from $clientName"
+ close $chan
+ } elseif {![\fBfblocked\fR $chan]} {
+ # Didn't block waiting for end-of-line
+ puts "$clientName - $line"
+ puts $chan $line
+ }
+}
+
+# Create the server socket and enter the event-loop to wait
+# for incoming connections...
+socket -server connect 12345
+vwait forever
+.CE
+.SH "SEE ALSO"
+gets(n), open(n), read(n), socket(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+blocking, nonblocking
diff --git a/pkgs/msgcat/doc/fconfigure.n b/pkgs/msgcat/doc/fconfigure.n
new file mode 100644
index 0000000..ac0366c
--- /dev/null
+++ b/pkgs/msgcat/doc/fconfigure.n
@@ -0,0 +1,289 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH fconfigure n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+fconfigure \- Set and get options on a channel
+.SH SYNOPSIS
+.nf
+\fBfconfigure \fIchannelId\fR
+\fBfconfigure \fIchannelId\fR \fIname\fR
+\fBfconfigure \fIchannelId\fR \fIname value \fR?\fIname value ...\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBfconfigure\fR command sets and retrieves options for channels.
+.PP
+\fIChannelId\fR identifies the channel for which to set or query an
+option and must refer 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.
+.PP
+If no \fIname\fR or \fIvalue\fR arguments are supplied, the command
+returns a list containing alternating option names and values for the channel.
+If \fIname\fR is supplied but no \fIvalue\fR then the command returns
+the current value of the given option.
+If one or more pairs of \fIname\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 additional options for sockets, and
+the \fBopen\fR command for additional options for serial devices.
+.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 \fBgets\fR,
+\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
+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 \fBflush\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 between ten and one million, allowing
+buffers of ten to one million bytes in size.
+.TP
+\fB\-encoding\fR \fIname\fR
+.
+This option is used to specify the encoding of the channel, 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 \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\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.
+.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
+the translation.
+.RE
+.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
+.PP
+.SH "STANDARD CHANNELS"
+.PP
+The Tcl standard channels (\fBstdin\fR, \fBstdout\fR, and \fBstderr\fR)
+can be configured through this command like every other channel opened
+by the Tcl library. Beyond the standard options described above they
+will also support any special option according to their current type.
+If, for example, a Tcl application is started by the \fBinet\fR
+super-server common on Unix system its Tcl standard channels will be
+sockets and thus support the socket options.
+.SH EXAMPLES
+.PP
+Instruct Tcl to always send output to \fBstdout\fR immediately,
+whether or not it is to a terminal:
+.PP
+.CS
+\fBfconfigure\fR stdout -buffering none
+.CE
+.PP
+Open a socket and read lines from it without ever blocking the
+processing of other events:
+.PP
+.CS
+set s [socket some.where.com 12345]
+\fBfconfigure\fR $s -blocking 0
+fileevent $s readable "readMe $s"
+proc readMe chan {
+ if {[gets $chan line] < 0} {
+ if {[eof $chan]} {
+ close $chan
+ return
+ }
+ # Could not read a complete line this time; Tcl's
+ # internal buffering will hold the partial line for us
+ # until some more data is available over the socket.
+ } else {
+ puts stdout $line
+ }
+}
+.CE
+.PP
+Read a PPM-format image from a file:
+.PP
+.CS
+# Open the file and put it into Unix ASCII mode
+set f [open teapot.ppm]
+\fBfconfigure\fR $f \-encoding ascii \-translation lf
+
+# Get the header
+if {[gets $f] ne "P6"} {
+ error "not a raw\-bits PPM"
+}
+
+# Read lines until we have got non-comment lines
+# that supply us with three decimal values.
+set words {}
+while {[llength $words] < 3} {
+ gets $f line
+ if {[string match "#*" $line]} continue
+ 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.
+lassign $words xSize ySize depth
+
+# Now switch to binary mode to pull in the data,
+# one byte per channel (red,green,blue) per pixel.
+\fBfconfigure\fR $f \-translation binary
+set numDataBytes [expr {3 * $xSize * $ySize}]
+set data [read $f $numDataBytes]
+
+close $f
+.CE
+.SH "SEE ALSO"
+close(n), flush(n), gets(n), open(n), puts(n), read(n), socket(n),
+Tcl_StandardChannels(3)
+.SH KEYWORDS
+blocking, buffering, carriage return, end of line, flushing, linemode,
+newline, nonblocking, platform, translation, encoding, filter, byte array,
+binary
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/fcopy.n b/pkgs/msgcat/doc/fcopy.n
new file mode 100644
index 0000000..6a4bf1a
--- /dev/null
+++ b/pkgs/msgcat/doc/fcopy.n
@@ -0,0 +1,155 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH fcopy n 8.0 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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\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\fR
+command transfers data from \fIinchan\fR until end of file
+or \fIsize\fR bytes have been
+transferred. If no \fB\-size\fR argument is given,
+then the copy goes until end of file.
+All the data read from \fIinchan\fR is copied to \fIoutchan\fR.
+Without the \fB\-command\fR option, \fBfcopy\fR blocks until the copy is complete
+and returns the number of bytes written to \fIoutchan\fR.
+.PP
+The \fB\-command\fR argument makes \fBfcopy\fR work in the background.
+In this case it returns immediately and the \fIcallback\fR is invoked
+later when the copy completes.
+The \fIcallback\fR is called with
+one or two additional
+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\fR command takes care of that automatically.
+However, it is necessary to enter the event loop by using
+the \fBvwait\fR command or by using Tk.
+.PP
+You are not allowed to do other I/O operations with
+\fIinchan\fR or \fIoutchan\fR during a background \fBfcopy\fR.
+If either \fIinchan\fR or \fIoutchan\fR get closed
+while the copy is in progress, the current copy is stopped
+and the command callback is \fInot\fR made.
+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\fR handlers during a background
+copy so those handlers do not interfere with the copy.
+Any I/O attempted by a \fBfileevent\fR handler will get a
+.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
+for these channels.
+See the manual entry for \fBfconfigure\fR for details on the
+\fB\-translation\fR option.
+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\fR or
+as the argument to the callback for an asynchronous \fBfcopy\fR.
+.PP
+\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 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 EXAMPLES
+.PP
+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.
+.PP
+.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.
+.PP
+.CS
+proc Cleanup {in out bytes {error {}}} {
+ global total
+ set total $bytes
+ close $in
+ close $out
+ if {[string length $error] != 0} {
+ # error occurred during the copy
+ }
+}
+set in [open $file1]
+set out [socket $server $port]
+\fBfcopy\fR $in $out -command [list Cleanup $in $out]
+vwait total
+.CE
+.PP
+The third example copies in chunks and tests for end of file
+in the command callback.
+.PP
+.CS
+proc CopyMore {in out chunk bytes {error {}}} {
+ global total done
+ incr total $bytes
+ if {([string length $error] != 0) || [eof $in]} {
+ set done $total
+ close $in
+ close $out
+ } else {
+ \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
+\fBfcopy\fR $in $out -size $chunk \e
+ -command [list CopyMore $in $out $chunk]
+vwait done
+.CE
+.SH "SEE ALSO"
+eof(n), fblocked(n), fconfigure(n), file(n)
+.SH KEYWORDS
+blocking, channel, end of line, end of file, nonblocking, read, translation
diff --git a/pkgs/msgcat/doc/file.n b/pkgs/msgcat/doc/file.n
new file mode 100644
index 0000000..eef4647
--- /dev/null
+++ b/pkgs/msgcat/doc/file.n
@@ -0,0 +1,543 @@
+'\"
+'\" 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 file n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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.
+\fIName\fR is the name of a file; if it starts with a tilde, then tilde
+substitution is done before executing the command (see the manual entry for
+\fBfilename\fR for details). \fIOption\fR indicates what to do with the
+file name. Any unique abbreviation for \fIoption\fR is acceptable. The
+valid options are:
+.TP
+\fBfile atime \fIname\fR ?\fBtime\fR?
+.
+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
+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
+.TP
+\fBfile attributes \fIname\fR ?\fBoption\fR?
+.TP
+\fBfile attributes \fIname\fR ?\fBoption value option value...\fR?
+.
+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
+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)
+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:
+\fBu+s,go\-rw\fR add sticky bit for user, remove read and write
+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
+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
+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
+clears the value of the system attribute of the file.
+.PP
+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
+.TP
+\fBfile channels ?\fIpattern\fR?
+.
+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.
+.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
+.
+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 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,
+or overwrite a file with a directory will all result in errors even if
+\fB\-force\fR was specified. 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.
+.TP
+\fBfile delete \fR?\fB\-force\fR? ?\fB\-\|\-\fR? ?\fIpathname\fR ... ?
+.
+Removes the file or directory specified by each \fIpathname\fR
+argument. Non-empty directories will be removed only if the
+\fB\-force\fR option is specified. When operating on symbolic links,
+the links themselves will be deleted, not the objects they point to.
+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
+.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.
+.TP
+\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
+.QW \fB.\fR .
+If \fIname\fR refers to a root directory, then the root directory is
+returned. For example,
+.RS
+.PP
+.CS
+\fBfile dirname\fR c:/
+.CE
+.PP
+returns \fBc:/\fR.
+.PP
+Note that tilde substitution will only be
+performed if it is necessary to complete the command. For example,
+.PP
+.CS
+\fBfile dirname\fR ~/src/foo.c
+.CE
+.PP
+returns \fB~/src\fR, whereas
+.PP
+.CS
+\fBfile dirname\fR ~
+.CE
+.PP
+returns \fB/home\fR (or something similar).
+.RE
+.TP
+\fBfile executable \fIname\fR
+.
+Returns \fB1\fR if file \fIname\fR is executable by the current user,
+\fB0\fR otherwise.
+.TP
+\fBfile exists \fIname\fR
+.
+Returns \fB1\fR if file \fIname\fR exists and the current user has
+search privileges for the directories leading to it, \fB0\fR otherwise.
+.TP
+\fBfile extension \fIname\fR
+.
+Returns all of the characters in \fIname\fR after and including the last
+dot in the last element of \fIname\fR. If there is no dot in the last
+element of \fIname\fR then returns the empty string.
+.TP
+\fBfile isdirectory \fIname\fR
+.
+Returns \fB1\fR if file \fIname\fR is a directory, \fB0\fR otherwise.
+.TP
+\fBfile isfile \fIname\fR
+.
+Returns \fB1\fR if file \fIname\fR is a regular file, \fB0\fR otherwise.
+.TP
+\fBfile join \fIname\fR ?\fIname ...\fR?
+.
+Takes one or more file names and combines them, using the correct path
+separator for the current platform. If a particular \fIname\fR is
+relative, then it will be joined to the previous file name argument.
+Otherwise, any earlier arguments will be discarded, and joining will
+proceed from the current argument. For example,
+.RS
+.PP
+.CS
+\fBfile join\fR a b /foo bar
+.CE
+.PP
+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.
+.RE
+.TP
+\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 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
+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
+.QW \fB\-symbolic\fR
+and
+.QW \fB\-hard\fR .
+.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
+.
+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
+do not support symbolic links this option behaves exactly the same
+as the \fBstat\fR option.
+.TP
+\fBfile mkdir ?\fIdir\fR ...?
+.
+Creates each directory specified. For each pathname \fIdir\fR specified,
+this command will create all non-existing parent directories as
+well as \fIdir\fR itself. If an existing directory is specified, then
+no action is taken and no error is returned. Trying to overwrite an existing
+file with a directory will result in an error. Arguments are processed in
+the order specified, halting at the first error, if any.
+.TP
+\fBfile mtime \fIname\fR ?\fItime\fR?
+.
+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 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 to a
+subprocess via \fBexec\fR under Windows (see \fBEXAMPLES\fR below).
+.TP
+\fBfile normalize \fIname\fR
+.
+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
+.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 \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
+.
+Returns \fB1\fR if file \fIname\fR is owned by the current user, \fB0\fR
+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.
+.TP
+\fBfile readable \fIname\fR
+.
+Returns \fB1\fR if file \fIname\fR is readable by the current user,
+\fB0\fR otherwise.
+.TP
+\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 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
+.
+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
+\fItarget\fR is an existing directory, then the second form is used.
+The second form moves each \fIsource\fR file or directory into the
+directory \fItargetDir\fR. Existing files will not be overwritten
+unless the \fB\-force\fR option is specified. When operating inside a
+single filesystem, Tcl will rename symbolic links rather than the
+things that they point to. Trying to overwrite a non-empty directory,
+overwrite a directory with a file, or a file with a directory will all
+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.
+.TP
+\fBfile rootname \fIname\fR
+.
+Returns all of the characters in \fIname\fR up to but not including the
+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?
+.
+If no argument is given, returns the character which is used to separate
+path segments for native files on this platform. If a path is given,
+the filesystem responsible for that path is asked to return its
+separator character. If no file system accepts \fIname\fR, an error
+is generated.
+.TP
+\fBfile size \fIname\fR
+.
+Returns a decimal string giving the size of file \fIname\fR in bytes. If
+the file does not exist or its size cannot be queried then an error is
+generated.
+.TP
+\fBfile split \fIname\fR
+.
+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 to ensure that an element is unambiguously relative.
+For example, under Unix
+.RS
+.PP
+.CS
+\fBfile split\fR /foo/~bar/baz
+.CE
+.PP
+returns
+.QW \fB/\0\0foo\0\0./~bar\0\0baz\fR
+to ensure that later commands
+that use the third component do not attempt to perform tilde
+substitution.
+.RE
+.TP
+\fBfile stat \fIname varName\fR
+.
+Invokes the \fBstat\fR kernel call on \fIname\fR, and uses the variable
+given by \fIvarName\fR to hold information returned from the kernel call.
+\fIVarName\fR is treated as an array variable, and the following elements
+of that variable are set: \fBatime\fR, \fBctime\fR, \fBdev\fR, \fBgid\fR,
+\fBino\fR, \fBmode\fR, \fBmtime\fR, \fBnlink\fR, \fBsize\fR, \fBtype\fR,
+\fBuid\fR. Each element except \fBtype\fR is a decimal string with the
+value of the corresponding field from the \fBstat\fR return structure;
+see the manual entry for \fBstat\fR for details on the meanings of the
+values. The \fBtype\fR element gives the type of the file in the same
+form returned by the command \fBfile type\fR. This command returns an
+empty string.
+.TP
+\fBfile system \fIname\fR
+.
+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 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 tempfile\fR ?\fInameVar\fR? ?\fItemplate\fR?
+'\" TIP #210
+.VS 8.6
+Creates a temporary file and returns a read-write channel opened on that file.
+If the \fInameVar\fR is given, it specifies a variable that the name of the
+temporary file will be written into; if absent, Tcl will attempt to arrange
+for the temporary file to be deleted once it is no longer required. If the
+\fItemplate\fR is present, it specifies parts of the template of the filename
+to use when creating it (such as the directory, base-name or extension) though
+some platforms may ignore some or all of these parts and use a built-in
+default instead.
+.RS
+.PP
+Note that temporary files are \fIonly\fR ever created on the native
+filesystem. As such, they can be relied upon to be used with operating-system
+native APIs and external programs that require a filename.
+.RE
+.VE 8.6
+.TP
+\fBfile type \fIname\fR
+.
+Returns a string giving the type of file \fIname\fR, which will be one of
+\fBfile\fR, \fBdirectory\fR, \fBcharacterSpecial\fR, \fBblockSpecial\fR,
+\fBfifo\fR, \fBlink\fR, or \fBsocket\fR.
+.TP
+\fBfile volumes\fR
+.
+Returns the absolute paths to the volumes mounted on the system, as a
+proper Tcl list. Without any virtual filesystems mounted as root
+volumes, on UNIX, the command will always return
+.QW / ,
+since all filesystems are locally mounted.
+On Windows, it will return a list of the available local drives
+(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
+.
+Returns \fB1\fR if file \fIname\fR is writable by the current user,
+\fB0\fR otherwise.
+.SH "PORTABILITY ISSUES"
+.TP
+\fBUnix\fR\0\0\0\0\0\0\0
+.
+These commands always operate using the real user and group identifiers,
+not the effective ones.
+.SH EXAMPLES
+.PP
+This procedure shows how to search for C files in a given directory
+that have a correspondingly-named object file in the current
+directory:
+.PP
+.CS
+proc findMatchingCFiles {dir} {
+ set files {}
+ switch $::tcl_platform(platform) {
+ windows {
+ set ext .obj
+ }
+ unix {
+ set ext .o
+ }
+ }
+ 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
+ }
+ }
+ return $files
+}
+.CE
+.PP
+Rename a file and leave a symbolic link pointing from the old location
+to the new place:
+.PP
+.CS
+set oldName foobar.txt
+set newName foo/bar.txt
+# Make sure that where we're going to move to exists...
+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
+.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:
+.PP
+.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, user
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/pkgs/msgcat/doc/fileevent.n b/pkgs/msgcat/doc/fileevent.n
new file mode 100644
index 0000000..df48d2a
--- /dev/null
+++ b/pkgs/msgcat/doc/fileevent.n
@@ -0,0 +1,153 @@
+'\"
+'\" Copyright (c) 1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2008 Pat Thoyts
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH fileevent n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+fileevent \- Execute a script when a channel becomes readable or writable
+.SH SYNOPSIS
+\fBfileevent \fIchannelId \fBreadable \fR?\fIscript\fR?
+.sp
+\fBfileevent \fIchannelId \fBwritable \fR?\fIscript\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+This command is used to create \fIfile event handlers\fR. 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 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
+.QW "freeze up" .
+With \fBfileevent\fR, the process can
+tell when data is present and only invoke \fBgets\fR or \fBread\fR when
+they will not block.
+.PP
+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.
+.PP
+If the \fIscript\fR argument is specified, then \fBfileevent\fR
+creates a new event handler: \fIscript\fR will be evaluated
+whenever the channel becomes readable or writable (depending on the
+second argument to \fBfileevent\fR).
+In this case \fBfileevent\fR returns an empty string.
+The \fBreadable\fR and \fBwritable\fR event handlers for a file
+are independent, and may be created and deleted separately.
+However, there may be at most one \fBreadable\fR and one \fBwritable\fR
+handler for a file at a given time in a given interpreter.
+If \fBfileevent\fR is called when the specified handler already
+exists in the invoking interpreter, the new script replaces the old one.
+.PP
+If the \fIscript\fR argument is not specified, \fBfileevent\fR
+returns the current script for \fIchannelId\fR, or an empty string
+if there is none.
+If the \fIscript\fR argument is specified as an empty string
+then the event handler is deleted, so that no script will be invoked.
+A file event handler is also deleted automatically whenever
+its channel is closed or its interpreter is deleted.
+.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 \fBgets\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.
+.PP
+Event-driven I/O works best for channels that have been
+placed into nonblocking mode with the \fBfconfigure\fR command.
+In blocking mode, a \fBputs\fR command may block if you give it
+more data than the underlying file or device can accept, and a
+\fBgets\fR or \fBread\fR command will block if you attempt to read
+more data than is ready; no events will be processed while the
+commands block.
+In nonblocking mode \fBputs\fR, \fBread\fR, and \fBgets\fR never block.
+See the documentation for the individual commands for information
+on how they handle blocking and nonblocking channels.
+.PP
+Testing for the end of file condition should be done after any attempts
+read the channel data. The eof flag is set once an attempt to read the
+end of data has occurred and testing before this read will require an
+additional event to be fired.
+.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
+\fBfileevent\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.
+.SH EXAMPLE
+.PP
+In this setup \fBGetData\fR will be called with the channel as an
+argument whenever $chan becomes readable. The \fBread\fR call will
+read whatever binary data is currently available without blocking.
+Here the channel has the fileevent removed when an end of file
+occurs to avoid being continually called (see above). Alternatively
+the channel may be closed on this condition.
+.PP
+.CS
+proc GetData {chan} {
+ set data [read $chan]
+ puts "[string length $data] $data"
+ if {[eof $chan]} {
+ fileevent $chan readable {}
+ }
+}
+
+fconfigure $chan -blocking 0 -encoding binary
+\fBfileevent\fR $chan readable [list GetData $chan]
+.CE
+.PP
+The next example demonstrates use of \fBgets\fR to read line-oriented
+data.
+.PP
+.CS
+proc GetData {chan} {
+ if {[gets $chan line] >= 0} {
+ puts $line
+ }
+ if {[eof $chan]} {
+ close $chan
+ }
+}
+
+fconfigure $chan -blocking 0 -buffering line -translation crlf
+\fBfileevent\fR $chan readable [list GetData $chan]
+.CE
+.SH CREDITS
+.PP
+\fBfileevent\fR is based on the \fBaddinput\fR command created
+by Mark Diekhans.
+.SH "SEE ALSO"
+fconfigure(n), gets(n), interp(n), puts(n), read(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+asynchronous I/O, blocking, channel, event handler, nonblocking, readable,
+script, writable.
diff --git a/pkgs/msgcat/doc/filename.n b/pkgs/msgcat/doc/filename.n
new file mode 100644
index 0000000..d481fc9
--- /dev/null
+++ b/pkgs/msgcat/doc/filename.n
@@ -0,0 +1,178 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH filename n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+filename \- File name conventions supported by Tcl commands
+.BE
+.SH INTRODUCTION
+.PP
+All Tcl commands and C procedures that take file names as arguments
+expect the file names to be in one of three forms, depending on the
+current platform. On each platform, Tcl supports file names in the
+standard forms(s) for that platform. In addition, on all platforms,
+Tcl supports a Unix-like syntax intended to provide a convenient way
+of constructing simple file names. However, scripts that are intended
+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
+for the path used to specify the file: absolute, relative, and
+volume-relative. Absolute names are completely qualified, giving a path to
+the file relative to a particular volume and the root directory on that
+volume. Relative names are unqualified, giving a path to the file relative
+to the current working directory. Volume-relative names are partially
+qualified, either giving the path relative to the root directory on the
+current volume, or relative to the current directory of the specified
+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
+\fBplatform\fR element of the \fBtcl_platform\fR array:
+.TP 10
+\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
+The following examples illustrate various forms of path
+names:
+.TP 15
+\fB/\fR
+Absolute path to the root directory.
+.TP 15
+\fB/etc/passwd\fR
+Absolute path to the file named \fBpasswd\fR in the directory
+\fBetc\fR in the root directory.
+.TP 15
+\fB\&.\fR
+Relative path to the current directory.
+.TP 15
+\fBfoo\fR
+Relative path to the file \fBfoo\fR in the current directory.
+.TP 15
+\fBfoo/bar\fR
+Relative path to the file \fBbar\fR in the directory \fBfoo\fR in the
+current directory.
+.TP 15
+\fB\&../foo\fR
+Relative path to the file \fBfoo\fR in the directory above the current
+directory.
+.RE
+.TP
+\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
+specifier followed by an absolute or relative path. UNC paths follow the
+general form \fB\e\eservername\esharename\epath\efile\fR, but must at
+the very least contain the server and share components, i.e.
+\fB\e\eservername\esharename\fR. In both forms,
+the file names \fB.\fR and \fB..\fR are special and refer to the current
+directory and the parent of the current directory respectively. The
+following examples illustrate various forms of path names:
+.RS
+.TP 15
+\fB\&\e\eHost\eshare/file\fR
+Absolute UNC path to a file called \fBfile\fR in the root directory of
+the export point \fBshare\fR on the host \fBHost\fR. Note that
+repeated use of \fBfile dirname\fR on this path will give
+\fB//Host/share\fR, and will never give just \fB//Host\fR.
+.TP 15
+\fBc:foo\fR
+Volume-relative path to a file \fBfoo\fR in the current directory on drive
+\fBc\fR.
+.TP 15
+\fBc:/foo\fR
+Absolute path to a file \fBfoo\fR in the root directory of drive
+\fBc\fR.
+.TP 15
+\fBfoo\ebar\fR
+Relative path to a file \fBbar\fR in the \fBfoo\fR directory in the current
+directory on the current volume.
+.TP 15
+\fB\&\efoo\fR
+Volume-relative path to a file \fBfoo\fR in the root directory of the current
+volume.
+.TP 15
+\fB\&\e\efoo\fR
+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. This works on
+Unix, MacOS X and Windows (except very old releases).
+.PP
+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.
+'\""\" 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
+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
+.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
diff --git a/pkgs/msgcat/doc/flush.n b/pkgs/msgcat/doc/flush.n
new file mode 100644
index 0000000..b8bf3e9
--- /dev/null
+++ b/pkgs/msgcat/doc/flush.n
@@ -0,0 +1,45 @@
+'\"
+'\" 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 flush n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+flush \- Flush buffered output for a channel
+.SH SYNOPSIS
+\fBflush \fIchannelId\fR
+.BE
+.SH DESCRIPTION
+.PP
+Flushes any output that has been buffered for \fIchannelId\fR.
+.PP
+\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.
+.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.
+.SH EXAMPLE
+.PP
+Prompt for the user to type some information in on the console:
+.PP
+.CS
+puts -nonewline "Please type your name: "
+\fBflush\fR stdout
+gets stdin name
+puts "Hello there, $name!"
+.CE
+.SH "SEE ALSO"
+file(n), open(n), socket(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+blocking, buffer, channel, flush, nonblocking, output
diff --git a/pkgs/msgcat/doc/for.n b/pkgs/msgcat/doc/for.n
new file mode 100644
index 0000000..4c65793
--- /dev/null
+++ b/pkgs/msgcat/doc/for.n
@@ -0,0 +1,87 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH for n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+for \- 'For' loop
+.SH SYNOPSIS
+\fBfor \fIstart test next body\fR
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBFor\fR is a looping command, similar in structure to the C
+\fBfor\fR statement. The \fIstart\fR, \fInext\fR, and
+\fIbody\fR arguments must be Tcl command strings, and \fItest\fR
+is an expression string.
+The \fBfor\fR command first invokes the Tcl interpreter to
+execute \fIstart\fR. Then it repeatedly evaluates \fItest\fR as
+an expression; if the result is non-zero it invokes the Tcl
+interpreter on \fIbody\fR, then invokes the Tcl interpreter on \fInext\fR,
+then repeats the loop. The command terminates when \fItest\fR evaluates
+to 0. If a \fBcontinue\fR command is invoked within \fIbody\fR then
+any remaining commands in the current execution of \fIbody\fR are skipped;
+processing continues by invoking the Tcl interpreter on \fInext\fR, then
+evaluating \fItest\fR, and so on. If a \fBbreak\fR command is invoked
+within \fIbody\fR
+or \fInext\fR,
+then the \fBfor\fR command will
+return immediately.
+The operation of \fBbreak\fR and \fBcontinue\fR are similar to the
+corresponding statements in C.
+\fBFor\fR returns an empty string.
+.PP
+Note: \fItest\fR should almost always be enclosed in braces. If not,
+variable substitutions will be made before the \fBfor\fR
+command starts executing, which means that variable changes
+made by the loop body will not be considered in the expression.
+This is likely to result in an infinite loop. If \fItest\fR is
+enclosed in braces, variable substitutions are delayed until the
+expression is evaluated (before
+each loop iteration), so changes in the variables will be visible.
+See below for an example:
+.SH EXAMPLES
+.PP
+Print a line for each of the integers from 0 to 10:
+.PP
+.CS
+\fBfor\fR {set x 0} {$x<10} {incr x} {
+ puts "x is $x"
+}
+.CE
+.PP
+Either loop infinitely or not at all because the expression being
+evaluated is actually the constant, or even generate an error! The
+actual behaviour will depend on whether the variable \fIx\fR exists
+before the \fBfor\fR command is run and whether its value is a value
+that is less than or greater than/equal to ten, and this is because
+the expression will be substituted before the \fBfor\fR command is
+executed.
+.PP
+.CS
+\fBfor\fR {set x 0} $x<10 {incr x} {
+ puts "x is $x"
+}
+.CE
+.PP
+Print out the powers of two from 1 to 1024:
+.PP
+.CS
+\fBfor\fR {set x 1} {$x<=1024} {set x [expr {$x * 2}]} {
+ puts "x is $x"
+}
+.CE
+.SH "SEE ALSO"
+break(n), continue(n), foreach(n), while(n)
+.SH KEYWORDS
+boolean, for, iteration, loop
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/foreach.n b/pkgs/msgcat/doc/foreach.n
new file mode 100644
index 0000000..fb075d3
--- /dev/null
+++ b/pkgs/msgcat/doc/foreach.n
@@ -0,0 +1,104 @@
+'\"
+'\" 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 foreach n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+foreach \- Iterate over all elements in one or more lists
+.SH SYNOPSIS
+\fBforeach \fIvarname list body\fR
+.br
+\fBforeach \fIvarlist1 list1\fR ?\fIvarlist2 list2 ...\fR? \fIbody\fR
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBforeach\fR command implements a loop where the loop
+variable(s) take on values from one or more lists.
+In the simplest case there is one loop variable, \fIvarname\fR,
+and one list, \fIlist\fR, that is a list of values to assign to \fIvarname\fR.
+The \fIbody\fR argument is a Tcl script.
+For each element of \fIlist\fR (in order
+from first to last), \fBforeach\fR assigns the contents of the
+element to \fIvarname\fR as if the \fBlindex\fR command had been used
+to extract the element, then calls the Tcl interpreter to execute
+\fIbody\fR.
+.PP
+In the general case there can be more than one value list
+(e.g., \fIlist1\fR and \fIlist2\fR),
+and each value list can be associated with a list of loop variables
+(e.g., \fIvarlist1\fR and \fIvarlist2\fR).
+During each iteration of the loop
+the variables of each \fIvarlist\fR are assigned
+consecutive values from the corresponding \fIlist\fR.
+Values in each \fIlist\fR are used in order from first to last,
+and each value is used exactly once.
+The total number of loop iterations is large enough to use
+up all the values from all the value lists.
+If a value list does not contain enough
+elements for each of its loop variables in each iteration,
+empty values are used for the missing elements.
+.PP
+The \fBbreak\fR and \fBcontinue\fR statements may be
+invoked inside \fIbody\fR, with the same effect as in the \fBfor\fR
+command. \fBForeach\fR returns an empty string.
+.SH EXAMPLES
+.PP
+This loop prints every value in a list together with the square and
+cube of the value:
+.PP
+.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.
+.PP
+.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.
+.CE
+.PP
+The next loop uses i and j to iterate over two lists in parallel.
+.PP
+.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.
+.CE
+.PP
+The two forms are combined in the following example.
+.PP
+.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.
+.CE
+
+.SH "SEE ALSO"
+for(n), while(n), break(n), continue(n)
+
+.SH KEYWORDS
+foreach, iteration, list, loop
diff --git a/pkgs/msgcat/doc/format.n b/pkgs/msgcat/doc/format.n
new file mode 100644
index 0000000..23dfe60
--- /dev/null
+++ b/pkgs/msgcat/doc/format.n
@@ -0,0 +1,285 @@
+'\"
+'\" 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 format n 8.1 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+format \- Format a string in the style of sprintf
+.SH SYNOPSIS
+\fBformat \fIformatString \fR?\fIarg arg ...\fR?
+.BE
+
+.SH INTRODUCTION
+.PP
+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.
+The return value from \fBformat\fR is the formatted string.
+.SH "DETAILS ON FORMATTING"
+.PP
+The command operates by scanning \fIformatString\fR from left to right.
+Each character from the format string is appended to the result
+string unless it is a percent sign.
+If the character is a \fB%\fR then it is not copied to the result string.
+Instead, the characters following the \fB%\fR character are treated as
+a conversion specifier.
+The conversion specifier controls the conversion of the next successive
+\fIarg\fR to a particular format and the result is appended to
+the result string in place of the conversion specifier.
+If there are multiple conversion specifiers in the format string,
+then each one controls the conversion of one additional \fIarg\fR.
+The \fBformat\fR command must be given enough \fIarg\fRs to meet the needs
+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 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.
+.SS "OPTIONAL POSITIONAL SPECIFIER"
+.PP
+If the \fB%\fR is followed by a decimal number and a \fB$\fR, as in
+.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
+of \fB*\fR characters in the specifier then
+successive arguments are used, starting with the argument
+given by the number.
+This follows the XPG3 conventions for positional specifiers.
+If there are any positional specifiers in \fIformatString\fR
+then all of the specifiers must be positional.
+.SS "OPTIONAL FLAGS"
+.PP
+The second portion of a conversion specifier may contain any of the
+following flag characters, in any order:
+.TP 10
+\fB\-\fR
+Specifies that the converted argument should be left-justified
+in its field (numbers are normally right-justified with leading
+spaces if needed).
+.TP 10
+\fB+\fR
+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 is not a sign.
+.TP 10
+\fB0\fR
+Specifies that the number should be padded on the left with
+zeroes instead of spaces.
+.TP 10
+\fB#\fR
+Requests an alternate output form. For \fBo\fR and \fBO\fR
+conversions it guarantees that the first digit is always \fB0\fR.
+For \fBx\fR or \fBX\fR conversions, \fB0x\fR or \fB0X\fR (respectively)
+will be added to the beginning of the result unless it is zero.
+For \fBb\fR conversions, \fB0b\fR
+will be added to the beginning of the result unless it is zero.
+For all floating-point conversions (\fBe\fR, \fBE\fR, \fBf\fR,
+\fBg\fR, and \fBG\fR) it guarantees that the result always
+has a decimal point.
+For \fBg\fR and \fBG\fR conversions it specifies that
+trailing zeroes should not be removed.
+.SS "OPTIONAL FIELD WIDTH"
+.PP
+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
+minimum field width then it will be padded so that it is as wide
+as the minimum field width.
+Padding normally occurs by adding extra spaces on the left of the
+converted argument, but the \fB0\fR and \fB\-\fR flags
+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 an integer value.
+.SS "OPTIONAL PRECISION/BOUND"
+.PP
+The fourth portion of a conversion specifier is a precision,
+which consists of a period followed by a number.
+The number is used in different ways for different conversions.
+For \fBe\fR, \fBE\fR, and \fBf\fR conversions it specifies the number
+of digits to appear to the right of the decimal point.
+For \fBg\fR and \fBG\fR conversions it specifies the total number
+of digits to appear, including those on both sides of the decimal
+point (however, trailing zeroes after the decimal point will still
+be omitted unless the \fB#\fR flag has been specified).
+For integer conversions, it specifies a minimum number of digits
+to print (leading zeroes will be added if necessary).
+For \fBs\fR conversions it specifies the maximum number of characters to be
+printed; if the string is longer than this then the trailing characters will be dropped.
+If the precision is specified with \fB*\fR rather than a number
+then the next argument to the \fBformat\fR command determines the precision;
+it must be a numeric string.
+.SS "OPTIONAL SIZE MODIFIER"
+.PP
+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 the \fBwordSize\fR element of the
+\fBtcl_platform\fR array).
+.SS "MANDATORY CONVERSION TYPE"
+.PP
+The last thing in a conversion specifier is an alphabetic character
+that determines what kind of conversion to perform.
+The following conversion characters are currently supported:
+.TP 10
+\fBd\fR
+Convert integer to signed decimal string.
+.TP 10
+\fBu\fR
+Convert integer to unsigned decimal string.
+.TP 10
+\fBi\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
+.QW 0123456789abcdef
+for \fBx\fR and
+.QW 0123456789ABCDEF
+for \fBX\fR).
+.TP 10
+\fBb\fR
+Convert integer to binary string, using digits 0 and 1.
+.TP 10
+\fBc\fR
+Convert integer to the Unicode character it represents.
+.TP 10
+\fBs\fR
+No conversion; just insert string.
+.TP 10
+\fBf\fR
+Convert number to signed decimal string of
+the form \fIxx.yyy\fR, where the number of \fIy\fR's is determined by
+the precision (default: 6).
+If the precision is 0 then no decimal point is output.
+.TP 10
+\fBe\fR or \fBE\fR
+Convert number to scientific notation in the
+form \fIx.yyy\fBe\(+-\fIzz\fR, where the number of \fIy\fR's is determined
+by the precision (default: 6).
+If the precision is 0 then no decimal point is output.
+If the \fBE\fR form is used then \fBE\fR is
+printed instead of \fBe\fR.
+.TP 10
+\fBg\fR or \fBG\fR
+If the exponent is less than \-4 or greater than or equal to the
+precision, then convert number as for \fB%e\fR or
+\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.
+.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]
+Tcl guarantees that it will be working with UNICODE characters.
+.IP [2]
+\fB%p\fR and \fB%n\fR specifiers are not supported.
+.IP [3]
+For \fB%c\fR conversions the argument must be an integer value,
+which will then be converted to the corresponding character value.
+.IP [4]
+The size modifiers are ignored when formatting floating-point values.
+The \fBll\fR modifier has no \fBsprintf\fR counterpart.
+The \fBb\fR specifier has no \fBsprintf\fR counterpart.
+.SH EXAMPLES
+.PP
+Convert the numeric value of a UNICODE character to the character
+itself:
+.PP
+.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:
+.PP
+.CS
+set us [lindex [time $someTclCode] 0]
+puts [\fBformat\fR "%.2f seconds to execute" [expr {$us / 1e6}]]
+.CE
+.PP
+Create a packed X11 literal color specification:
+.PP
+.CS
+# Each color-component should be in range (0..255)
+set color [\fBformat\fR "#%02x%02x%02x" $r $g $b]
+.CE
+.PP
+Use XPG3 format codes to allow reordering of fields (a technique that
+is often used in localized message catalogs; see \fBmsgcat\fR) without
+reordering the data values passed to \fBformat\fR:
+.PP
+.CS
+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\e$s equity ($%3$.2f x %1\e$d) today"
+puts [\fBformat\fR $fmt2 123 "Global BigCorp" 19.37]
+.CE
+.PP
+Print a small table of powers of three:
+.PP
+.CS
+# Set up the column widths
+set w1 5
+set w2 10
+
+# Make a nice header (with separator) for the table first
+set sep +-[string repeat - $w1]-+-[string repeat - $w2]-+
+puts $sep
+puts [\fBformat\fR "| %-*s | %-*s |" $w1 "Index" $w2 "Power"]
+puts $sep
+
+# Print the contents of the table
+set p 1
+for {set i 0} {$i<=20} {incr i} {
+ puts [\fBformat\fR "| %*d | %*ld |" $w1 $i $w2 $p]
+ set p [expr {wide($p) * 3}]
+}
+
+# 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
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/gets.n b/pkgs/msgcat/doc/gets.n
new file mode 100644
index 0000000..fe24058
--- /dev/null
+++ b/pkgs/msgcat/doc/gets.n
@@ -0,0 +1,71 @@
+'\"
+'\" 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 gets n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+gets \- Read a line from a channel
+.SH SYNOPSIS
+\fBgets \fIchannelId\fR ?\fIvarName\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+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
+\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.
+.PP
+If \fIvarName\fR is omitted the line is returned as the result of the
+command.
+If \fIvarName\fR is specified then the line is placed in the variable by
+that name and the return value is a count of the number of characters
+returned.
+.PP
+If end of file occurs while scanning for an end of
+line, the command returns whatever input is available up to the end of file.
+If \fIchannelId\fR is in non-blocking mode and there is not a full
+line of input available, the command returns an empty string and
+does not consume any input.
+If \fIvarName\fR is specified and an empty string is returned in
+\fIvarName\fR because of end-of-file or because of insufficient
+data in non-blocking mode, then the return count is -1.
+Note that if \fIvarName\fR is not specified then the end-of-file
+and no-full-line-available cases can
+produce the same results as if there were an input line consisting
+only of the end-of-line character(s).
+The \fBeof\fR and \fBfblocked\fR commands can be used to distinguish
+these three cases.
+.SH "EXAMPLE"
+This example reads a file one line at a time and prints it out with
+the current line number attached to the start of each line.
+.PP
+.CS
+set chan [open "some.file.txt"]
+set lineNumber 0
+while {[\fBgets\fR $chan line] >= 0} {
+ puts "[incr lineNumber]: $line"
+}
+close $chan
+.CE
+
+.SH "SEE ALSO"
+file(n), eof(n), fblocked(n), Tcl_StandardChannels(3)
+
+.SH KEYWORDS
+blocking, channel, end of file, end of line, line, non-blocking, read
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/pkgs/msgcat/doc/glob.n b/pkgs/msgcat/doc/glob.n
new file mode 100644
index 0000000..7b71189
--- /dev/null
+++ b/pkgs/msgcat/doc/glob.n
@@ -0,0 +1,273 @@
+'\"
+'\" 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 glob n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+glob \- Return names of files that match patterns
+.SH SYNOPSIS
+\fBglob \fR?\fIswitches\fR? ?\fIpattern ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command performs file name
+.QW globbing
+in a fashion similar to
+the csh shell or bash shell.
+It returns a list of the files whose names match any
+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.
+.SS OPTIONS
+.PP
+If the initial arguments to \fBglob\fR start with \fB\-\fR then
+they are treated as switches. The following switches are
+currently supported:
+.TP
+\fB\-directory\fR \fIdirectory\fR
+.
+Search for files which match the given patterns starting in the given
+\fIdirectory\fR. This allows searching of directories whose name
+contains glob-sensitive characters without the need to quote such
+characters explicitly. This option may not be used in conjunction with
+\fB\-path\fR, which is used to allow searching for complete file paths
+whose names may contain glob-sensitive characters.
+.TP
+\fB\-join\fR
+.
+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.
+.TP
+\fB\-path\fR \fIpathPrefix\fR
+.
+Search for files with the given \fIpathPrefix\fR where the rest of the name
+matches the given patterns. This allows searching for files with names
+similar to a given file (as opposed to a directory) even when the names
+contain glob-sensitive
+characters. This option may not be used in conjunction with
+\fB\-directory\fR. For example, to find all files with the same root name
+as $path, but differing extensions, you should use
+.QW "\fBglob \-path [file rootname $path] .*\fR"
+which will work even if \fB$path\fR contains
+numerous glob-sensitive characters.
+.TP
+\fB\-tails\fR
+.
+Only return the part of each file found which follows the last directory
+named in any \fB\-directory\fR or \fB\-path\fR path specification.
+Thus
+.QW "\fBglob \-tails \-directory $dir *\fR"
+is equivalent to
+.QW "\fBset pwd [pwd]; cd $dir; glob *; cd $pwd\fR" .
+For \fB\-path\fR specifications, the returned names will include the last
+path segment, so
+.QW "\fBglob \-tails \-path [file rootname ~/foo.tex] .*\fR"
+will return paths like \fBfoo.aux foo.bib foo.tex\fR etc.
+.TP
+\fB\-types\fR \fItypeList\fR
+.
+Only list files or directories which match \fItypeList\fR, where the items
+in the list have two forms. The first form is like the \-type option of
+the Unix find command:
+\fIb\fR (block special file),
+\fIc\fR (character special file),
+\fId\fR (directory),
+\fIf\fR (plain file),
+\fIl\fR (symbolic link),
+\fIp\fR (named pipe),
+or \fIs\fR (socket), where multiple types may be specified in the list.
+\fBGlob\fR will return all files which match at least one of the types given.
+Note that symbolic links will be returned both if \fB\-types l\fR is given,
+or if the target of a link matches the requested type. So, a link to
+a directory will be returned if \fB\-types d\fR was specified.
+.RS
+.PP
+The second form specifies types where all the types given must match.
+These are \fIr\fR, \fIw\fR, \fIx\fR as file permissions, and
+\fIreadonly\fR, \fIhidden\fR as special permission cases. On the
+Macintosh, MacOS types and creators are also supported, where any item
+which is four characters long is assumed to be a MacOS type
+(e.g. \fBTEXT\fR). Items which are of the form \fI{macintosh type XXXX}\fR
+or \fI{macintosh creator XXXX}\fR will match types or creators
+respectively. Unrecognized types, or specifications of multiple MacOS
+types/creators will signal an error.
+.PP
+The two forms may be mixed, so \fB\-types {d f r w}\fR will find all
+regular files OR directories that have both read AND write permissions.
+The following are equivalent:
+.PP
+.CS
+\fBglob \-type d *\fR
+\fBglob */\fR
+.CE
+.PP
+except that the first case doesn't return the trailing
+.QW /
+and is more platform independent.
+.RE
+.TP
+\fB\-\|\-\fR
+.
+Marks the end of switches. The argument following this one will
+be treated as a \fIpattern\fR even if it starts with a \fB\-\fR.
+.SS "GLOBBING PATTERNS"
+.PP
+The \fIpattern\fR arguments may contain any of the following
+special characters, which are a superset of those supported by
+\fBstring match\fR:
+.TP 10
+\fB?\fR
+.
+Matches any single character.
+.TP 10
+\fB*\fR
+.
+Matches any sequence of zero or more characters.
+.TP 10
+\fB[\fIchars\fB]\fR
+.
+Matches any single character in \fIchars\fR. If \fIchars\fR
+contains a sequence of the form \fIa\fB\-\fIb\fR then any
+character between \fIa\fR and \fIb\fR (inclusive) will match.
+.TP 10
+\fB\e\fIx\fR
+.
+Matches the character \fIx\fR.
+.TP 10
+\fB{\fIa\fB,\fIb\fB,\fI...\fR}
+.
+Matches any of the sub-patterns \fIa\fR, \fIb\fR, etc.
+.PP
+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
+.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.
+.PP
+The \fBglob\fR command differs from csh globbing in two ways.
+First, it does not sort its result list (use the \fBlsort\fR
+command if you want the list sorted).
+Second, \fBglob\fR only returns the names of files that actually
+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
+.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 "WINDOWS PORTABILITY ISSUES"
+.PP
+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
+.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 accepted patterns
+like
+.QW .../
+and
+.QW ..../
+for successively higher up parent directories, but later versions of
+Windows do not accept these forms.
+.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
+.QW \fIC:\e\efoo\e\e*\fR
+is interpreted as
+.QW \fIC:\efoo\e*\fR
+where
+.QW \fI\ef\fR
+will match the single character
+.QW \fIf\fR
+and
+.QW \fI\e*\fR
+will match the single character
+.QW \fI*\fR
+and will not be
+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
+.QW "\fBfile join\fR \fB$path\fR"
+or
+.QW "\fBfile normalize\fR \fB$path\fR" .
+.SH EXAMPLES
+.PP
+Find all the Tcl files in the current directory:
+.PP
+.CS
+\fBglob\fR *.tcl
+.CE
+.PP
+Find all the Tcl files in the user's home directory, irrespective of
+what the current directory is:
+.PP
+.CS
+\fBglob\fR \-directory ~ *.tcl
+.CE
+.PP
+Find all subdirectories of the current directory:
+.PP
+.CS
+\fBglob\fR \-type d *
+.CE
+.PP
+Find all files whose name contains an
+.QW a ,
+a
+.QW b
+or the sequence
+.QW cde :
+.PP
+.CS
+\fBglob\fR \-type f *{a,b,cde}*
+.CE
+.SH "SEE ALSO"
+file(n)
+.SH KEYWORDS
+exist, file, glob, pattern
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/global.n b/pkgs/msgcat/doc/global.n
new file mode 100644
index 0000000..c17c370
--- /dev/null
+++ b/pkgs/msgcat/doc/global.n
@@ -0,0 +1,58 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH global n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+global \- Access global variables
+.SH SYNOPSIS
+\fBglobal \fR?\fIvarname ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command has no effect unless executed in the context of a proc body.
+If the \fBglobal\fR command is executed in the context of a proc body, it
+creates local variables linked to the corresponding global variables (though
+these linked variables, like those created by \fBupvar\fR, are not included
+in the list returned by \fBinfo locals\fR).
+.PP
+If \fIvarname\fR contains namespace qualifiers, the local variable's name is
+the unqualified name of the global variable, as determined by the
+\fBnamespace tail\fR command.
+.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
+.PP
+This procedure sets the namespace variable \fI::a::x\fR
+.PP
+.CS
+proc reset {} {
+ \fBglobal\fR a::x
+ set x 0
+}
+.CE
+.PP
+This procedure accumulates the strings passed to it in a global
+buffer, separated by newlines. It is useful for situations when you
+want to build a message piece-by-piece (as if with \fBputs\fR) but
+send that full message in a single piece (e.g. over a connection
+opened with \fBsocket\fR or as part of a counted HTTP response).
+.PP
+.CS
+proc accum {string} {
+ \fBglobal\fR accumulator
+ append accumulator $string \en
+}
+.CE
+.SH "SEE ALSO"
+namespace(n), upvar(n), variable(n)
+.SH KEYWORDS
+global, namespace, procedure, variable
diff --git a/pkgs/msgcat/doc/history.n b/pkgs/msgcat/doc/history.n
new file mode 100644
index 0000000..ba507b4
--- /dev/null
+++ b/pkgs/msgcat/doc/history.n
@@ -0,0 +1,102 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH history n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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
+.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\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
+the same as the first characters of the event, or if the string
+matches the event in the sense of the \fBstring match\fR command.
+.PP
+The \fBhistory\fR command can take any of the following forms:
+.TP
+\fBhistory\fR
+Same
+as \fBhistory info\fR, described below.
+.TP
+\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 is not specified
+then an empty string is returned as result.
+.TP
+\fBhistory change\fI newValue\fR ?\fIevent\fR?
+Replaces the value recorded for an event with \fInewValue\fR. \fIEvent\fR
+specifies the event to replace, and
+defaults to the \fIcurrent\fR event (not event \fB\-1\fR). This command
+is intended for use in commands that implement new forms of history
+substitution and wish to replace the current event (which invokes the
+substitution) with the command created through substitution. The return
+value is an empty string.
+.TP
+\fBhistory clear\fR
+Erase the history list. The current keep limit is retained.
+The history event numbers are reset.
+.TP
+\fBhistory event\fR ?\fIevent\fR?
+Returns the value of the event given by \fIevent\fR. \fIEvent\fR
+defaults to \fB\-1\fR.
+.TP
+\fBhistory info \fR?\fIcount\fR?
+Returns a formatted string (intended for humans to read) giving
+the event number and contents for each of the events in the history
+list except the current event. If \fIcount\fR is specified
+then only the most recent \fIcount\fR events are returned.
+.TP
+\fBhistory keep \fR?\fIcount\fR?
+This command may be used to change the size of the history list to
+\fIcount\fR events. Initially, 20 events are retained in the history
+list. If \fIcount\fR is not specified, the current keep limit is returned.
+.TP
+\fBhistory nextid\fR
+Returns the number of the next event to be recorded
+in the history list. It is useful for things like printing the
+event number in command-line prompts.
+.TP
+\fBhistory redo \fR?\fIevent\fR?
+Re-executes the command indicated by \fIevent\fR and returns its result.
+\fIEvent\fR defaults to \fB\-1\fR. This command results in history
+revision: see below for details.
+.SH "HISTORY REVISION"
+.PP
+Pre-8.0 Tcl had a complex history revision mechanism.
+The current mechanism is more limited, and the old
+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
+.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\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/pkgs/msgcat/doc/http.n b/pkgs/msgcat/doc/http.n
new file mode 100644
index 0000000..631a141
--- /dev/null
+++ b/pkgs/msgcat/doc/http.n
@@ -0,0 +1,646 @@
+'\"
+'\" Copyright (c) 1995-1997 Sun Microsystems, Inc.
+'\" Copyright (c) 1998-2000 by Ajuba Solutions.
+'\" Copyright (c) 2004 ActiveState Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH "http" n 2.7 http "Tcl Bundled Packages"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+http \- Client-side implementation of the HTTP/1.1 protocol
+.SH SYNOPSIS
+\fBpackage require http ?2.7?\fR
+.\" See Also -useragent option documentation in body!
+.sp
+\fB::http::config ?\fI\-option value\fR ...?
+.sp
+\fB::http::geturl \fIurl\fR ?\fI\-option value\fR ...?
+.sp
+\fB::http::formatQuery\fR \fIkey value\fR ?\fIkey value\fR ...?
+.sp
+\fB::http::reset\fR \fItoken\fR ?\fIwhy\fR?
+.sp
+\fB::http::wait \fItoken\fR
+.sp
+\fB::http::status \fItoken\fR
+.sp
+\fB::http::size \fItoken\fR
+.sp
+\fB::http::code \fItoken\fR
+.sp
+\fB::http::ncode \fItoken\fR
+.sp
+\fB::http::meta \fItoken\fR
+.sp
+\fB::http::data \fItoken\fR
+.sp
+\fB::http::error \fItoken\fR
+.sp
+\fB::http::cleanup \fItoken\fR
+.sp
+\fB::http::register \fIproto port command\fR
+.sp
+\fB::http::unregister \fIproto\fR
+.BE
+.SH DESCRIPTION
+.PP
+The \fBhttp\fR package provides the client side of the HTTP/1.1
+protocol, 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
+additional HTTP transport protocols, such as HTTPS, by providing
+a custom \fBsocket\fR command, via \fB::http::register\fR.
+.PP
+The \fB::http::geturl\fR procedure does a HTTP transaction.
+Its \fIoptions \fR determine whether a GET, POST, or HEAD transaction
+is performed.
+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 \fBSTATE ARRAY\fR section.
+.PP
+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
+when the transaction completes. For this to work, the Tcl event loop
+must be active. In Tk applications this is always true. For pure-Tcl
+applications, the caller can use \fB::http::wait\fR after calling
+\fB::http::geturl\fR to start the event loop.
+.SH COMMANDS
+.TP
+\fB::http::config\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
+is returned. If a single argument is specified, then it should be one
+of the flags described below. In this case the current value of
+that setting is returned. Otherwise, the options should be a set of
+flags and values that define the configuration:
+.RS
+.TP
+\fB\-accept\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,
+.QW "image/gif, image/jpeg, text/*" .
+.TP
+\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\fR \fInumber\fR
+.
+The proxy port number.
+.TP
+\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
+host name, is added to \fIcommand\fR when it is invoked. If a proxy
+is required, the callback should return a two-element list containing
+the proxy server and proxy port. Otherwise the filter should return
+an empty list. The default filter returns the values of the
+\fB\-proxyhost\fR and \fB\-proxyport\fR settings if they are
+non-empty.
+.TP
+\fB\-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
+returned by specifying the empty string (\fB{}\fR), although
+\fIiso8859-1\fR is recommended to restore similar behavior but without the
+\fB::http::formatQuery\fR throwing an error processing non-latin-1
+characters.
+.TP
+\fB\-useragent\fR \fIstring\fR
+.
+The value of the User-Agent header in the HTTP request. The default is
+.QW "\fBTcl http client package 2.7\fR" .
+.RE
+.TP
+\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 \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\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\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\fR \fIname\fR
+.
+Copy the URL contents to channel \fIname\fR instead of saving it in
+\fBstate(body)\fR.
+.TP
+\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 \fBSTATE ARRAY\fR section. Here is a template for the
+callback:
+.RS
+.PP
+.CS
+proc httpCallback {token} {
+ upvar #0 $token state
+ # Access state as a Tcl array
+}
+.CE
+.RE
+.TP
+\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 \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
+.PP
+.CS
+proc httpHandlerCallback {socket token} {
+ upvar #0 $token state
+ # Access socket, and state as a Tcl array
+ # For example...
+ ...
+ set data [read $socket 1000]
+ set nbytes [string length $data]
+ ...
+ return $nbytes
+}
+.CE
+.RE
+.TP
+\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
+header field names. Newlines are stripped from the values so the
+header cannot be corrupted. For example, if \fIkeyvaluelist\fR is
+\fBPragma no-cache\fR then the following header is included in the
+HTTP request:
+.RS
+.PP
+.CS
+Pragma: no-cache
+.CE
+.RE
+.TP
+\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
+\fBContent-Length\fR meta-data, and the current number of bytes
+transferred so far. The expected total size may be unknown, in which
+case zero is passed to the callback. Here is a template for the
+progress callback:
+.RS
+.PP
+.CS
+proc httpProgress {token total current} {
+ upvar #0 $token state
+}
+.CE
+.RE
+.TP
+\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\fR \fIsize\fR
+.
+The block size used when posting query data to the URL.
+At most
+\fIsize\fR
+bytes are written at once. After each block, a call to the
+\fB\-queryprogress\fR
+callback is made (if that option is specified).
+.TP
+\fB\-querychannel\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\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\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\-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\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\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\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
+\fBSTATE ARRAY\fR section for details.
+.RE
+.TP
+\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\fR \fItoken\fR ?\fIwhy\fR?
+.
+This command resets the HTTP transaction identified by \fItoken\fR, if 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\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 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\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\fR \fItoken\fR
+.
+This is a convenience procedure that returns the \fBerror\fR element
+of the state array.
+.TP
+\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\fR \fItoken\fR
+.
+This is a convenience procedure that returns the \fBhttp\fR element of the
+state array.
+.TP
+\fB::http::ncode\fR \fItoken\fR
+.
+This is a convenience procedure that returns just the numeric return
+code (200, 404, etc.) from the \fBhttp\fR element of the state array.
+.TP
+\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\fR call.
+.TP
+\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\fR \fItoken\fR
+.
+This procedure cleans up the state associated with the connection
+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\fR enough times, the memory leak could cause a
+performance hit...or worse.
+.TP
+\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.:
+.RS
+.PP
+.CS
+package require http
+package require tls
+
+::http::register https 443 ::tls::socket
+
+set token [::http::geturl https://my.secure.site/]
+.CE
+.RE
+.TP
+\fB::http::unregister\fR \fIproto\fR
+.
+This procedure unregisters a protocol handler that was previously
+registered via \fB::http::register\fR.
+.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,
+or a URL at a bad port on an existing host.
+These errors mean that it
+cannot even start the network transaction.
+It will also raise an error if it gets an I/O error while
+writing out the HTTP request header.
+For synchronous \fB::http::geturl\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\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\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\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\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\fR and then check status and error, just as the
+callback does.
+.PP
+In any case, you must still call
+\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\fR.
+These are described below.
+.TP
+\fBok\fR
+.
+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
+\fBeof\fR
+.
+If the server closes the socket without replying, then no error
+is raised, but the status of the transaction will be \fBeof\fR.
+.TP
+\fBerror\fR
+.
+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\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\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\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.
+Use this construct to create an easy-to-use array variable:
+.PP
+.CS
+upvar #0 $token state
+.CE
+.PP
+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\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\fR command.
+.TP
+\fBcharset\fR
+.
+The value of the charset attribute from the \fBContent-Type\fR meta-data
+value. If none was specified, this defaults to the RFC standard
+\fBiso8859-1\fR, or the value of \fB$::http::defaultCharset\fR. Incoming
+text data will be automatically converted from this charset to utf-8.
+.TP
+\fBcoding\fR
+.
+A copy of the \fBContent-Encoding\fR meta-data value.
+.TP
+\fBcurrentsize\fR
+.
+The current number of bytes fetched from the URL.
+This value is returned by the \fB::http::size\fR command.
+.TP
+\fBerror\fR
+.
+If defined, this is the error string seen when the HTTP transaction
+was aborted.
+.TP
+\fBhttp\fR
+.
+The HTTP status reply from the server. This value
+is returned by the \fB::http::code\fR command. The format of this value is:
+.RS
+.PP
+.CS
+\fIHTTP/1.1 code string\fR
+.CE
+.PP
+The \fIcode\fR is a three-digit number defined in the HTTP standard.
+A code of 200 is OK. Codes beginning with 4 or 5 indicate errors.
+Codes beginning with 3 are redirection errors. In this case the
+\fBLocation\fR meta-data specifies a new URL that contains the
+requested information.
+.RE
+.TP
+\fBmeta\fR
+.
+The HTTP protocol returns meta-data that describes the URL contents.
+The \fBmeta\fR element of the state array is a list of the keys and
+values of the meta-data. This is in a format useful for initializing
+an array that just contains the meta-data:
+.RS
+.PP
+.CS
+array set meta $state(meta)
+.CE
+.PP
+Some of the meta-data keys are listed below, but the HTTP standard defines
+more, and servers are free to add their own.
+.TP
+\fBContent-Type\fR
+.
+The type of the URL contents. Examples include \fBtext/html\fR,
+\fBimage/gif,\fR \fBapplication/postscript\fR and
+\fBapplication/x-tcl\fR.
+.TP
+\fBContent-Length\fR
+.
+The advertised size of the contents. The actual size obtained by
+\fB::http::geturl\fR is available as \fBstate(currentsize)\fR.
+.TP
+\fBLocation\fR
+.
+An alternate URL that contains the requested data.
+.RE
+.TP
+\fBposterror\fR
+.
+The error, if any, that occurred while writing
+the post query data to the server.
+.TP
+\fBstatus\fR
+.
+Either \fBok\fR, for successful completion, \fBreset\fR for
+user-reset, \fBtimeout\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
+\fBtotalsize\fR
+.
+A copy of the \fBContent-Length\fR meta-data value.
+.TP
+\fBtype\fR
+.
+A copy of the \fBContent-Type\fR meta-data value.
+.TP
+\fBurl\fR
+.
+The requested URL.
+.RE
+.SH EXAMPLE
+.PP
+This example creates a procedure to copy a URL to a file while printing a
+progress meter, and prints the meta-data associated with the URL.
+.PP
+.CS
+proc httpcopy { url file {chunk 4096} } {
+ set out [open $file w]
+ set token [\fB::http::geturl\fR $url -channel $out \e
+ -progress httpCopyProgress -blocksize $chunk]
+ close $out
+
+ # This ends the line started by httpCopyProgress
+ puts stderr ""
+
+ upvar #0 $token state
+ set max 0
+ foreach {name value} $state(meta) {
+ if {[string length $name] > $max} {
+ set max [string length $name]
+ }
+ if {[regexp -nocase ^location$ $name]} {
+ # Handle URL redirects
+ puts stderr "Location:$value"
+ return [httpcopy [string trim $value] $file $chunk]
+ }
+ }
+ incr max
+ foreach {name value} $state(meta) {
+ puts [format "%-*s %s" $max $name: $value]
+ }
+
+ return $token
+}
+proc httpCopyProgress {args} {
+ puts -nonewline stderr .
+ flush stderr
+}
+.CE
+.SH "SEE ALSO"
+safe(n), socket(n), safesock(n)
+.SH KEYWORDS
+internet, security policy, socket, www
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/if.n b/pkgs/msgcat/doc/if.n
new file mode 100644
index 0000000..700f325
--- /dev/null
+++ b/pkgs/msgcat/doc/if.n
@@ -0,0 +1,88 @@
+'\"
+'\" 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 if n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+if \- Execute scripts conditionally
+.SH SYNOPSIS
+\fBif \fIexpr1 \fR?\fBthen\fR? \fIbody1 \fBelseif \fIexpr2 \fR?\fBthen\fR? \fIbody2\fR \fBelseif\fR ... ?\fBelse\fR? ?\fIbodyN\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fIif\fR command evaluates \fIexpr1\fR as an expression (in the
+same way that \fBexpr\fR evaluates its argument). The value of the
+expression must be a boolean
+(a numeric value, where 0 is false and
+anything is true, or a string value such as \fBtrue\fR or \fByes\fR
+for true and \fBfalse\fR or \fBno\fR for false);
+if it is true then \fIbody1\fR is executed by passing it to the
+Tcl interpreter.
+Otherwise \fIexpr2\fR is evaluated as an expression and if it is true
+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
+.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
+that was executed, or an empty string
+if none of the expressions was non-zero and there was no \fIbodyN\fR.
+.SH EXAMPLES
+.PP
+A simple conditional:
+.PP
+.CS
+\fBif\fR {$vbl == 1} { puts "vbl is one" }
+.CE
+.PP
+With an \fBelse\fR-clause:
+.PP
+.CS
+\fBif\fR {$vbl == 1} {
+ puts "vbl is one"
+} \fBelse\fR {
+ puts "vbl is not one"
+}
+.CE
+.PP
+With an \fBelseif\fR-clause too:
+.PP
+.CS
+\fBif\fR {$vbl == 1} {
+ puts "vbl is one"
+} \fBelseif\fR {$vbl == 2} {
+ puts "vbl is two"
+} \fBelse\fR {
+ puts "vbl is not one or two"
+}
+.CE
+.PP
+Remember, expressions can be multi-line, but in that case it can be a
+good idea to use the optional \fBthen\fR keyword for clarity:
+.PP
+.CS
+\fBif\fR {
+ $vbl == 1
+ || $vbl == 2
+ || $vbl == 3
+} \fBthen\fR {
+ puts "vbl is one, two or three"
+}
+.CE
+.SH "SEE ALSO"
+expr(n), for(n), foreach(n)
+.SH KEYWORDS
+boolean, conditional, else, false, if, true
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/incr.n b/pkgs/msgcat/doc/incr.n
new file mode 100644
index 0000000..595cc27
--- /dev/null
+++ b/pkgs/msgcat/doc/incr.n
@@ -0,0 +1,61 @@
+'\"
+'\" 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 incr n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+incr \- Increment the value of a variable
+.SH SYNOPSIS
+\fBincr \fIvarName \fR?\fIincrement\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Increments the value stored in the variable whose name is \fIvarName\fR.
+The value of the variable must be an integer.
+If \fIincrement\fR is supplied then its value (which must be an
+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
+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.
+.SH EXAMPLES
+.PP
+Add one to the contents of the variable \fIx\fR:
+.PP
+.CS
+\fBincr\fR x
+.CE
+.PP
+Add 42 to the contents of the variable \fIx\fR:
+.PP
+.CS
+\fBincr\fR x 42
+.CE
+.PP
+Add the contents of the variable \fIy\fR to the contents of the
+variable \fIx\fR:
+.PP
+.CS
+\fBincr\fR x $y
+.CE
+.PP
+Add nothing at all to the variable \fIx\fR (often useful for checking
+whether an argument to a procedure is actually integral and generating
+an error if it is not):
+.PP
+.CS
+\fBincr\fR x 0
+.CE
+.SH "SEE ALSO"
+expr(n), set(n)
+.SH KEYWORDS
+add, increment, variable, value
diff --git a/pkgs/msgcat/doc/info.n b/pkgs/msgcat/doc/info.n
new file mode 100644
index 0000000..e65a083
--- /dev/null
+++ b/pkgs/msgcat/doc/info.n
@@ -0,0 +1,777 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\" Copyright (c) 1993-1997 Bell Labs Innovations for Lucent Technologies
+'\" Copyright (c) 1998-2000 Ajuba Solutions
+'\" Copyright (c) 2007-2012 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH info n 8.4 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+info \- Return information about the state of the Tcl interpreter
+.SH SYNOPSIS
+\fBinfo \fIoption \fR?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command provides information about various internals of the Tcl
+interpreter.
+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
+\fIprocname\fR, in order. \fIProcname\fR must be the name of a
+Tcl command procedure.
+.TP
+\fBinfo body \fIprocname\fR
+.
+Returns the body of procedure \fIprocname\fR. \fIProcname\fR must be
+the name of a Tcl command procedure.
+.TP
+\fBinfo class\fI subcommand class\fR ?\fIarg ...\fR
+.VS 8.6
+Returns information about the class, \fIclass\fR. The \fIsubcommand\fRs are
+described in \fBCLASS INTROSPECTION\fR below.
+.VE 8.6
+.TP
+\fBinfo cmdcount\fR
+.
+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 is not specified,
+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,
+only those names matching \fIpattern\fR are returned.
+Matching is determined using the same rules as for \fBstring match\fR.
+\fIpattern\fR can be a qualified name like \fBFoo::print*\fR.
+That is, it may specify a particular namespace
+using a sequence of namespace names separated by double colons (\fB::\fR),
+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, 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.
+.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 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 is not complete, the script can delay evaluating it until additional
+lines have been typed to complete the command.
+.TP
+\fBinfo coroutine\fR
+.VS 8.6
+Returns the name of the currently executing \fBcoroutine\fR, or the empty
+string if either no coroutine is currently executing, or the current coroutine
+has been deleted (but has not yet returned or yielded since deletion).
+.VE 8.6
+.TP
+\fBinfo default \fIprocname arg varname\fR
+.
+\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
+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
+\fBinfo errorstack \fR?\fIinterp\fR?
+.VS 8.6
+Returns, in a form that is programmatically easy to parse, the function names
+and arguments at each level from the call stack of the last error in the given
+\fIinterp\fR, or in the current one if not specified.
+.RS
+.PP
+This form is an even-sized list alternating tokens and parameters. Tokens are
+currently either \fBCALL\fR, \fBUP\fR, or \fBINNER\fR, but other values may be
+introduced in the future. \fBCALL\fR indicates a procedure call, and its
+parameter is the corresponding \fBinfo level\fR \fB0\fR. \fBUP\fR indicates a
+shift in variable frames generated by \fBuplevel\fR or similar, and applies to
+the previous \fBCALL\fR item. Its parameter is the level offset. \fBINNER\fR
+identifies the
+.QW "inner context" ,
+which is the innermost atomic command or bytecode instruction that raised the
+error, along with its arguments when available. While \fBCALL\fR and \fBUP\fR
+allow to follow complex call paths, \fBINNER\fR homes in on the offending
+operation in the innermost procedure call, even going to sub-expression
+granularity.
+.PP
+This information is also present in the \fB\-errorstack\fR entry of the
+options dictionary returned by 3-argument \fBcatch\fR; \fBinfo errorstack\fR
+is a convenient way of retrieving it for uncaught errors at top-level in an
+interactive \fBtclsh\fR.
+.RE
+.VE 8.6
+.TP
+\fBinfo exists \fIvarName\fR
+.
+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.
+.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 outer-most active command, 2 to the command it
+called, and so on, up to the current frame level which refers to
+\fBinfo frame\fR itself); 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 pre-compiled 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
+canonically-constructed list (e.g., as produced by the \fBlist\fR command)
+executed by \fBeval\fR it is the substituted form as they have no other
+string representation. Care is taken that the canonicality property of
+the latter is not spoiled.
+.TP
+\fBproc\fR
+.
+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, procedure definitions and \fBeval\fR within a dynamically
+\fBeval\fRuated environment count line numbers relative to the start of
+their script, even if they would be able to count relative to the
+start of the outer dynamic script. That type of number usually makes
+more sense.
+.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 line number
+within the list words as well, and otherwise all line numbers are
+counted relative to the start of each word (smallest scope)
+.RE
+.TP
+\fBinfo functions \fR?\fIpattern\fR?
+.
+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.
+.TP
+\fBinfo globals \fR?\fIpattern\fR?
+.
+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
+are returned. Matching is determined using the same rules as for
+\fBstring match\fR.
+.TP
+\fBinfo hostname\fR
+.
+Returns the name of the computer on which this invocation is being
+executed.
+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.
+.TP
+\fBinfo level\fR ?\fInumber\fR?
+.
+If \fInumber\fR is not specified, this command returns a number
+giving the stack level of the invoking procedure, or 0 if the
+command is invoked at top-level. If \fInumber\fR is specified,
+then the result is a list consisting of the name and arguments for the
+procedure call at level \fInumber\fR on the stack. If \fInumber\fR
+is positive then it selects a particular stack level (1 refers
+to the top-most active procedure, 2 to the procedure it called, and
+so on); otherwise it gives a level relative to the current level
+(0 refers to the current procedure, -1 to its caller, and so on).
+See the \fBuplevel\fR command for more information on what stack
+levels mean.
+.TP
+\fBinfo library\fR
+.
+Returns the name of the library directory in which standard Tcl
+scripts are stored.
+This is actually the value of the \fBtcl_library\fR
+variable and may be changed by setting \fBtcl_library\fR.
+See the \fBtclvars\fR manual entry for more information.
+.TP
+\fBinfo loaded \fR?\fIinterp\fR?
+.
+Returns a list describing all of the packages that have been loaded into
+\fIinterp\fR with the \fBload\fR command.
+Each list element is a sub-list with two elements consisting of the
+name of the file from which the package was loaded and the name of
+the package.
+For statically-loaded packages the file name will be an empty string.
+If \fIinterp\fR is omitted then information is returned for all packages
+loaded in any interpreter in the process.
+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 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
+\fBvariable\fR commands will not be returned.
+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.
+.TP
+\fBinfo nameofexecutable\fR
+.
+Returns the full path name of the binary file from which the application
+was invoked. If Tcl was unable to identify the file, then an empty
+string is returned.
+.TP
+\fBinfo object\fI subcommand object\fR ?\fIarg ...\fR
+.VS 8.6
+Returns information about the object, \fIobject\fR. The \fIsubcommand\fRs are
+described in \fBOBJECT INTROSPECTION\fR below.
+.VE 8.6
+.TP
+\fBinfo patchlevel\fR
+.
+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 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
+matching \fIpattern\fR are returned.
+Matching is determined using the same rules as for
+\fBstring match\fR.
+If \fIpattern\fR contains any namespace separators, they are used to
+select a namespace relative to the current namespace (or relative to
+the global namespace if \fIpattern\fR starts with \fB::\fR) to match
+within; the matching pattern is taken to be the part after the last
+namespace separator.
+.TP
+\fBinfo script\fR ?\fIfilename\fR?
+.
+If a Tcl script file is currently being evaluated (i.e. there is a
+call to \fBTcl_EvalFile\fR active or there is an active invocation
+of the \fBsource\fR command), then this command returns the name
+of the innermost file being processed. If \fIfilename\fR is specified,
+then the return value of this command will be modified for the
+duration of the active invocation to return that name. This is
+useful in virtual file system applications.
+Otherwise the command returns an empty string.
+.TP
+\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 are not supported on this platform then an empty
+string is returned.
+.TP
+\fBinfo tclversion\fR
+.
+Returns the value of the global variable \fBtcl_version\fR; see
+the \fBtclvars\fR manual entry for more information.
+.TP
+\fBinfo vars\fR ?\fIpattern\fR?
+.
+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
+are returned. Matching is determined using the same rules as for
+\fBstring match\fR.
+\fIpattern\fR can be a qualified name like \fBFoo::option*\fR.
+That is, it may specify a particular namespace
+using a sequence of namespace names separated by double colons (\fB::\fR),
+and may have pattern matching special characters
+at the end to specify a set of variables in that namespace.
+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
+.QW exist
+if it has not
+been set (e.g. a variable declared but not set by \fBvariable\fR).
+.SS "CLASS INTROSPECTION"
+.VS 8.6
+.PP
+The following \fIsubcommand\fR values are supported by \fBinfo class\fR:
+.VE 8.6
+.TP
+\fBinfo class call\fI class method\fR
+.VS
+Returns a description of the method implementations that are used to provide a
+stereotypical instance of \fIclass\fR's implementation of \fImethod\fR
+(stereotypical instances being objects instantiated by a class without having
+any object-specific definitions added). This consists of a list of lists of
+four elements, where each sublist consists of a word that describes the
+general type of method implementation (being one of \fBmethod\fR for an
+ordinary method, \fBfilter\fR for an applied filter, and \fBunknown\fR for a
+method that is invoked as part of unknown method handling), a word giving the
+name of the particular method invoked (which is always the same as
+\fImethod\fR for the \fBmethod\fR type, and
+.QW \fBunknown\fR
+for the \fBunknown\fR type), a word giving the fully qualified name of the
+class that defined the method, and a word describing the type of method
+implementation (see \fBinfo class methodtype\fR).
+.RS
+.PP
+Note that there is no inspection of whether the method implementations
+actually use \fBnext\fR to transfer control along the call chain.
+.RE
+.VE 8.6
+.TP
+\fBinfo class constructor\fI class\fR
+.VS 8.6
+This subcommand returns a description of the definition of the constructor of
+class \fIclass\fR. The definition is described as a two element list; the first
+element is the list of arguments to the constructor in a form suitable for
+passing to another call to \fBproc\fR or a method definition, and the second
+element is the body of the constructor. If no constructor is present, this
+returns the empty list.
+.VE 8.6
+.TP
+\fBinfo class definition\fI class method\fR
+.VS 8.6
+This subcommand returns a description of the definition of the method named
+\fImethod\fR of class \fIclass\fR. The definition is described as a two element
+list; the first element is the list of arguments to the method in a form
+suitable for passing to another call to \fBproc\fR or a method definition, and
+the second element is the body of the method.
+.VE 8.6
+.TP
+\fBinfo class destructor\fI class\fR
+.VS 8.6
+This subcommand returns the body of the destructor of class \fIclass\fR. If no
+destructor is present, this returns the empty string.
+.VE 8.6
+.TP
+\fBinfo class filters\fI class\fR
+.VS 8.6
+This subcommand returns the list of filter methods set on the class.
+.VE 8.6
+.TP
+\fBinfo class forward\fI class method\fR
+.VS 8.6
+This subcommand returns the argument list for the method forwarding called
+\fImethod\fR that is set on the class called \fIclass\fR.
+.VE 8.6
+.TP
+\fBinfo class instances\fI class\fR ?\fIpattern\fR?
+.VS 8.6
+This subcommand returns a list of instances of class \fIclass\fR. If the
+optional \fIpattern\fR argument is present, it constrains the list of returned
+instances to those that match it according to the rules of \fBstring match\fR.
+.VE 8.6
+.TP
+\fBinfo class methods\fI class\fR ?\fIoptions...\fR?
+.VS 8.6
+This subcommand returns a list of all public (i.e. exported) methods of the
+class called \fIclass\fR. Any of the following \fIoption\fRs may be
+specified, controlling exactly which method names are returned:
+.RS
+.VE 8.6
+.TP
+\fB\-all\fR
+.VS 8.6
+If the \fB\-all\fR flag is given, the list of methods will include those
+methods defined not just by the class, but also by the class's superclasses
+and mixins.
+.VE 8.6
+.TP
+\fB\-private\fR
+.VS 8.6
+If the \fB\-private\fR flag is given, the list of methods will also include
+the private (i.e. non-exported) methods of the class (and superclasses and
+mixins, if \fB\-all\fR is also given).
+.RE
+.VE 8.6
+.TP
+\fBinfo class methodtype\fI class method\fR
+.VS 8.6
+This subcommand returns a description of the type of implementation used for
+the method named \fImethod\fR of class \fIclass\fR. When the result is
+\fBmethod\fR, further information can be discovered with \fBinfo class
+definition\fR, and when the result is \fBforward\fR, further information can
+be discovered with \fBinfo class forward\fR.
+.VE 8.6
+.TP
+\fBinfo class mixins\fI class\fR
+.VS 8.6
+This subcommand returns a list of all classes that have been mixed into the
+class named \fIclass\fR.
+.VE 8.6
+.TP
+\fBinfo class subclasses\fI class\fR ?\fIpattern\fR?
+.VS 8.6
+This subcommand returns a list of direct subclasses of class \fIclass\fR. If
+the optional \fIpattern\fR argument is present, it constrains the list of
+returned classes to those that match it according to the rules of
+\fBstring match\fR.
+.VE 8.6
+.TP
+\fBinfo class superclasses\fI class\fR
+.VS 8.6
+This subcommand returns a list of direct superclasses of class \fIclass\fR in
+inheritance precedence order.
+.VE 8.6
+.TP
+\fBinfo class variables\fI class\fR
+.VS 8.6
+This subcommand returns a list of all variables that have been declared for
+the class named \fIclass\fR (i.e. that are automatically present in the
+class's methods, constructor and destructor).
+.SS "OBJECT INTROSPECTION"
+.PP
+The following \fIsubcommand\fR values are supported by \fBinfo object\fR:
+.VE 8.6
+.TP
+\fBinfo object call\fI object method\fR
+.VS 8.6
+Returns a description of the method implementations that are used to provide
+\fIobject\fR's implementation of \fImethod\fR. This consists of a list of
+lists of four elements, where each sublist consists of a word that describes
+the general type of method implementation (being one of \fBmethod\fR for an
+ordinary method, \fBfilter\fR for an applied filter, and \fBunknown\fR for a
+method that is invoked as part of unknown method handling), a word giving the
+name of the particular method invoked (which is always the same as
+\fImethod\fR for the \fBmethod\fR type, and
+.QW \fBunknown\fR
+for the \fBunknown\fR type), a word giving what defined the method (the fully
+qualified name of the class, or the literal string \fBobject\fR if the method
+implementation is on an instance), and a word describing the type of method
+implementation (see \fBinfo object methodtype\fR).
+.RS
+.PP
+Note that there is no inspection of whether the method implementations
+actually use \fBnext\fR to transfer control along the call chain.
+.RE
+.VE 8.6
+.TP
+\fBinfo object class\fI object\fR ?\fIclassName\fR?
+.VS 8.6
+If \fIclassName\fR is unspecified, this subcommand returns class of the
+\fIobject\fR object. If \fIclassName\fR is present, this subcommand returns a
+boolean value indicating whether the \fIobject\fR is of that class.
+.VE 8.6
+.TP
+\fBinfo object definition\fI object method\fR
+.VS 8.6
+This subcommand returns a description of the definition of the method named
+\fImethod\fR of object \fIobject\fR. The definition is described as a two
+element list; the first element is the list of arguments to the method in a
+form suitable for passing to another call to \fBproc\fR or a method definition,
+and the second element is the body of the method.
+.VE 8.6
+.TP
+\fBinfo object filters\fI object\fR
+.VS 8.6
+This subcommand returns the list of filter methods set on the object.
+.VE 8.6
+.TP
+\fBinfo object forward\fI object method\fR
+.VS 8.6
+This subcommand returns the argument list for the method forwarding called
+\fImethod\fR that is set on the object called \fIobject\fR.
+.VE 8.6
+.TP
+\fBinfo object isa\fI category object\fR ?\fIarg\fR?
+.VS 8.6
+This subcommand tests whether an object belongs to a particular category,
+returning a boolean value that indicates whether the \fIobject\fR argument
+meets the criteria for the category. The supported categories are:
+.VE 8.6
+.RS
+.TP
+\fBinfo object isa class\fI object\fR
+.VS 8.6
+This returns whether \fIobject\fR is a class (i.e. an instance of
+\fBoo::class\fR or one of its subclasses).
+.VE 8.6
+.TP
+\fBinfo object isa metaclass\fI object\fR
+.VS 8.6
+This returns whether \fIobject\fR is a class that can manufacture classes
+(i.e. is \fBoo::class\fR or a subclass of it).
+.VE 8.6
+.TP
+\fBinfo object isa mixin\fI object class\fR
+.VS 8.6
+This returns whether \fIclass\fR is directly mixed into \fIobject\fR.
+.VE 8.6
+.TP
+\fBinfo object isa object\fI object\fR
+.VS 8.6
+This returns whether \fIobject\fR really is an object.
+.VE 8.6
+.TP
+\fBinfo object isa typeof\fI object class\fR
+.VS 8.6
+This returns whether \fIclass\fR is the type of \fIobject\fR (i.e. whether
+\fIobject\fR is an instance of \fIclass\fR or one of its subclasses, whether
+direct or indirect).
+.RE
+.VE 8.6
+.TP
+\fBinfo object methods\fI object\fR ?\fIoption...\fR?
+.VS 8.6
+This subcommand returns a list of all public (i.e. exported) methods of the
+object called \fIobject\fR. Any of the following \fIoption\fRs may be
+specified, controlling exactly which method names are returned:
+.RS
+.VE 8.6
+.TP
+\fB\-all\fR
+.VS 8.6
+If the \fB\-all\fR flag is given, the list of methods will include those
+methods defined not just by the object, but also by the object's class and
+mixins, plus the superclasses of those classes.
+.VE 8.6
+.TP
+\fB\-private\fR
+.VS 8.6
+If the \fB\-private\fR flag is given, the list of methods will also include
+the private (i.e. non-exported) methods of the object (and classes, if
+\fB\-all\fR is also given).
+.RE
+.VE 8.6
+.TP
+\fBinfo object methodtype\fI object method\fR
+.VS 8.6
+This subcommand returns a description of the type of implementation used for
+the method named \fImethod\fR of object \fIobject\fR. When the result is
+\fBmethod\fR, further information can be discovered with \fBinfo object
+definition\fR, and when the result is \fBforward\fR, further information can
+be discovered with \fBinfo object forward\fR.
+.VE 8.6
+.TP
+\fBinfo object mixins\fI object\fR
+.VS 8.6
+This subcommand returns a list of all classes that have been mixed into the
+object named \fIobject\fR.
+.VE 8.6
+.TP
+\fBinfo object namespace\fI object\fR
+.VS 8.6
+This subcommand returns the name of the internal namespace of the object named
+\fIobject\fR.
+.VE 8.6
+.TP
+\fBinfo object variables\fI object\fR
+.VS 8.6
+This subcommand returns a list of all variables that have been declared for
+the object named \fIobject\fR (i.e. that are automatically present in the
+object's methods).
+.VE 8.6
+.TP
+\fBinfo object vars\fI object\fR ?\fIpattern\fR?
+.VS 8.6
+This subcommand returns a list of all variables in the private namespace of
+the object named \fIobject\fR. If the optional \fIpattern\fR argument is
+given, it is a filter (in the syntax of a \fBstring match\fR glob pattern)
+that constrains the list of variables returned. Note that this is different
+from the list returned by \fBinfo object variables\fR; that can include
+variables that are currently unset, whereas this can include variables that
+are not automatically included by any of \fIobject\fR's methods (or those of
+its class, superclasses or mixins).
+.VE 8.6
+.SH EXAMPLES
+.PP
+This command prints out a procedure suitable for saving in a Tcl
+script:
+.PP
+.CS
+proc printProc {procName} {
+ set result [list proc $procName]
+ set formals {}
+ foreach var [\fBinfo args\fR $procName] {
+ if {[\fBinfo default\fR $procName $var def]} {
+ lappend formals [list $var $def]
+ } else {
+ # Still need the list-quoting because variable
+ # names may properly contain spaces.
+ lappend formals [list $var]
+ }
+ }
+ puts [lappend result $formals [\fBinfo body\fR $procName]]
+}
+.CE
+.SS "EXAMPLES WITH OBJECTS"
+.VS 8.6
+.PP
+Every object necessarily knows what its class is; this information is
+trivially extractable through introspection:
+.PP
+.CS
+oo::class create c
+c create o
+puts [\fBinfo object class\fR o]
+ \fI\(-> prints "::c"\fR
+puts [\fBinfo object class\fR c]
+ \fI\(-> prints "::oo::class"\fR
+.CE
+.PP
+The introspection capabilities can be used to discover what class implements a
+method and get how it is defined. This procedure illustrates how:
+.PP
+.CS
+proc getDef {obj method} {
+ foreach inf [\fBinfo object call\fR $obj $method] {
+ lassign $inf calltype name locus methodtype
+ # Assume no forwards or filters, and hence no $calltype
+ # or $methodtype checks...
+ if {$locus eq "object"} {
+ return [\fBinfo object definition\fR $obj $name]
+ } else {
+ return [\fBinfo class definition\fR $locus $name]
+ }
+ }
+ error "no definition for $method"
+}
+.CE
+.PP
+This is an alternate way of looking up the definition; it is implemented by
+manually scanning the list of methods up the inheritance tree. This code
+assumes that only single inheritance is in use, and that there is no complex
+use of mixed-in classes (in such cases, using \fBinfo object call\fR as above
+is the simplest way of doing this by far):
+.PP
+.CS
+proc getDef {obj method} {
+ if {$method in [\fBinfo object methods\fR $obj]} {
+ # Assume no forwards
+ return [\fBinfo object definition\fR $obj $method]
+ }
+ set cls [\fBinfo object class\fR $obj]
+ while {$method ni [\fBinfo class methods\fR $cls]} {
+ # Assume the simple case
+ set cls [lindex [\fBinfo class superclass\fR $cls] 0]
+ if {$cls eq ""} {
+ error "no definition for $method"
+ }
+ }
+ # Assume no forwards
+ return [\fBinfo class definition\fR $cls $method]
+}
+.CE
+.VE 8.6
+.SH "SEE ALSO"
+.VS 8.6
+global(n), oo::class(n), oo::define(n), oo::object(n), proc(n), self(n)
+.VE 8.6
+.SH KEYWORDS
+command, information, interpreter, introspection, level, namespace,
+.VS 8.6
+object,
+.VE 8.6
+procedure, variable
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/pkgs/msgcat/doc/interp.n b/pkgs/msgcat/doc/interp.n
new file mode 100644
index 0000000..6ce10ee
--- /dev/null
+++ b/pkgs/msgcat/doc/interp.n
@@ -0,0 +1,910 @@
+'\"
+'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2004 Donal K. Fellows
+'\" Copyright (c) 2006-2008 Joe Mistachkin.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH interp n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+interp \- Create and manipulate Tcl interpreters
+.SH SYNOPSIS
+\fBinterp \fIsubcommand \fR?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+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.
+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.
+.PP
+Each interpreter is independent from the others: it has its own name
+space for commands, procedures, and global variables.
+A master interpreter may create connections between its slaves and
+itself using a mechanism called an \fIalias\fR. An \fIalias\fR is
+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,
+and by resource limit exceeded callbacks. 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
+to another.
+.PP
+The \fBinterp\fR command also provides support for \fIsafe\fR
+interpreters. A safe interpreter is a slave whose functions have
+been greatly restricted, so that it is safe to execute untrusted
+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.
+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;
+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
+on how the alias mechanism works.
+.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
+interpreter in its immediate master. Interpreter names are relative to the
+interpreter in which they are used. For example, if
+.QW \fBa\fR
+is a slave of the current interpreter and it has a slave
+.QW \fBa1\fR ,
+which in turn has a slave
+.QW \fBa11\fR ,
+the qualified name of
+.QW \fBa11\fR
+in
+.QW \fBa\fR
+is the list
+.QW "\fBa1 a11\fR" .
+.PP
+The \fBinterp\fR command, described below, accepts qualified interpreter
+names as arguments; the interpreter in which the command is being evaluated
+can always be referred to as \fB{}\fR (the empty list or string). Note that
+it is impossible to refer to a master (ancestor) interpreter by name in a
+slave interpreter except through aliases. Also, there is no global name by
+which one can refer to the first interpreter created in an application.
+Both restrictions are motivated by safety concerns.
+.SH "THE INTERP COMMAND"
+.PP
+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 \fIsubcommand\fR argument:
+.TP
+\fBinterp\fR \fBalias\fR \fIsrcPath\fR \fIsrcToken\fR
+.
+Returns a Tcl list whose elements are the \fItargetCmd\fR and
+\fIarg\fRs associated with the alias represented by \fIsrcToken\fR
+(this is the value returned when the alias was
+created; it is possible that the name of the source command in the
+slave is different from \fIsrcToken\fR).
+.TP
+\fBinterp\fR \fBalias\fR \fIsrcPath\fR \fIsrcToken\fR \fB{}\fR
+.
+Deletes the alias for \fIsrcToken\fR in the slave interpreter identified by
+\fIsrcPath\fR.
+\fIsrcToken\fR refers to the value returned when the alias
+was created; if the source command has been renamed, the renamed
+command will be deleted.
+.TP
+\fBinterp\fR \fBalias\fR \fIsrcPath\fR \fIsrcCmd\fR \fItargetPath\fR \fItargetCmd \fR?\fIarg arg ...\fR?
+.
+This command creates an alias between one slave and another (see the
+\fBalias\fR slave command below for creating aliases between a slave
+and its master). In this command, either of the slave interpreters
+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,
+.QW "\fBa b\fR"
+identifies an interpreter
+.QW \fBb\fR ,
+which is a slave of interpreter
+.QW \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 command, which will be created in the source interpreter.
+\fITargetPath\fR and \fItargetCmd\fR specify a target interpreter
+and command, and the \fIarg\fR arguments, if any, specify additional
+arguments to \fItargetCmd\fR which are prepended to any arguments specified
+in the invocation of \fIsrcCmd\fR.
+\fITargetCmd\fR may be undefined at the time of this call, or it may
+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.
+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
+\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
+as the current names of the commands).
+.TP
+\fBinterp bgerror \fIpath\fR ?\fIcmdPrefix\fR?
+.
+This command either gets or sets the current background exception handler
+for the interpreter identified by \fIpath\fR. If \fIcmdPrefix\fR is
+absent, the current background exception 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 exception handler to. See the
+\fBBACKGROUND EXCEPTION HANDLING\fR section for more details.
+.TP
+\fBinterp\fR \fBcancel \fR?\fB\-unwind\fR? ?\fB\-\|\-\fR? ?\fIpath\fR? ?\fIresult\fR?
+.VS 8.6
+Cancels the script being evaluated in the interpreter identified by
+\fIpath\fR. Without the \fB\-unwind\fR switch the evaluation stack for
+the interpreter is unwound until an enclosing catch command is found or
+there are no further invocations of the interpreter left on the call
+stack. With the \fB\-unwind\fR switch the evaluation stack for the
+interpreter is unwound without regard to any intervening catch command
+until there are no further invocations of the interpreter left on the
+call stack. The \fB\-\|\-\fR switch can be used to mark the end of
+switches; it may be needed if \fIpath\fR is an unusual value such
+as \fB\-safe\fR. If \fIresult\fR is present, it will be used as the
+error message string; otherwise, a default error message string will be
+used.
+.VE 8.6
+.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\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
+described below. If \fIpath\fR is omitted, Tcl creates a unique name of the
+form \fBinterp\fIx\fR, where \fIx\fR is an integer, and uses it for the
+interpreter and the slave command. If the \fB\-safe\fR switch is specified
+(or if the master interpreter is a safe interpreter), the new slave
+interpreter will be created as a safe interpreter with limited
+functionality; otherwise the slave will include the full set of Tcl
+built-in commands and variables. The \fB\-\|\-\fR switch can be used to
+mark the end of switches; it may be needed if \fIpath\fR is an unusual
+value such as \fB\-safe\fR. The result of the command is the name of the
+new interpreter. The name of a slave interpreter must be unique among all
+the slaves for its master; an error occurs if a slave interpreter by the
+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 ?\fB\-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 \fB\-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.
+.RS
+.PP
+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.
+.PP
+Note that once it is on, this flag cannot be switched back off: such
+attempts are silently ignored. This is needed to maintain the
+consistency of the underlying interpreter's state.
+.RE
+.TP
+\fBinterp\fR \fBdelete \fR?\fIpath ...?\fR
+.
+Deletes zero or more interpreters given by the optional \fIpath\fR
+arguments, and for each interpreter, it also deletes its slaves. The
+command also deletes the slave command for each interpreter deleted.
+For each \fIpath\fR argument, if no interpreter by that name
+exists, the command raises an error.
+.TP
+\fBinterp\fR \fBeval\fR \fIpath arg \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 the slave interpreter identified by \fIpath\fR. 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 the
+\fIpath\fR interpreter; 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.
+.TP
+\fBinterp exists \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.
+.TP
+\fBinterp expose \fIpath\fR \fIhiddenName\fR ?\fIexposedCmdName\fR?
+.
+Makes the hidden command \fIhiddenName\fR exposed, eventually bringing
+it back under a new \fIexposedCmdName\fR name (this name is currently
+accepted only if it is a valid global name space name without any ::),
+in the interpreter
+denoted by \fIpath\fR.
+If an exposed command with the targeted name already exists, this command
+fails.
+Hidden commands are explained in more detail in \fBHIDDEN COMMANDS\fR, below.
+.TP
+\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
+by \fIpath\fR.
+If a hidden command with the targeted name already exists, this command
+fails.
+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
+prevents slaves from fooling a master interpreter into hiding the wrong
+command, by making the current namespace be different from the global one.
+Hidden commands are explained in more detail in \fBHIDDEN COMMANDS\fR, below.
+.TP
+\fBinterp\fR \fBhidden\fR \fIpath\fR
+.
+Returns a list of the names of all hidden commands in the interpreter
+identified by \fIpath\fR.
+.TP
+\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. 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.
+.TP
+\fBinterp issafe\fR ?\fIpath\fR?
+.
+Returns \fB1\fR if the interpreter identified by the specified \fIpath\fR
+is safe, \fB0\fR otherwise.
+.TP
+\fBinterp\fR \fBlimit\fR \fIpath\fR \fIlimitType\fR ?\fI\-option\fR? ?\fIvalue\fR \fI...\fR?
+.
+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.
+.TP
+\fBinterp marktrusted\fR \fIpath\fR
+.
+Marks the interpreter identified by \fIpath\fR as trusted. Does
+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.
+.TP
+\fBinterp\fR \fBrecursionlimit\fR \fIpath\fR ?\fInewlimit\fR?
+.
+Returns the maximum allowable nesting depth for the interpreter
+specified by \fIpath\fR. If \fInewlimit\fR is specified,
+the interpreter recursion limit will be set so that nesting
+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.
+.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.
+.RE
+.TP
+\fBinterp\fR \fBshare\fR \fIsrcPath channelId destPath\fR
+.
+Causes the IO channel identified by \fIchannelId\fR to become shared
+between the interpreter identified by \fIsrcPath\fR and the interpreter
+identified by \fIdestPath\fR. Both interpreters have the same permissions
+on the IO channel.
+Both interpreters must close it to close the underlying IO channel; IO
+channels accessible in an interpreter are automatically closed when an
+interpreter is destroyed.
+.TP
+\fBinterp\fR \fBslaves\fR ?\fIpath\fR?
+.
+Returns a Tcl list of the names of all the slave interpreters associated
+with the interpreter identified by \fIpath\fR. If \fIpath\fR is omitted,
+the invoking interpreter is used.
+.TP
+\fBinterp\fR \fBtarget\fR \fIpath alias\fR
+.
+Returns a Tcl list describing the target interpreter for an alias. The
+alias is specified with an interpreter path and source command name, just
+as in \fBinterp alias\fR above. The name of the target interpreter is
+returned as an interpreter path, relative to the invoking interpreter.
+If the target interpreter for the alias is the invoking interpreter then an
+empty list is returned. If the target interpreter for the alias is not the
+invoking interpreter or one of its descendants then an error is generated.
+The target command does not have to be defined at the time of this invocation.
+.TP
+\fBinterp\fR \fBtransfer\fR \fIsrcPath channelId destPath\fR
+.
+Causes the IO channel identified by \fIchannelId\fR to become available in
+the interpreter identified by \fIdestPath\fR and unavailable in the
+interpreter identified by \fIsrcPath\fR.
+.SH "SLAVE COMMAND"
+.PP
+For each slave interpreter created with the \fBinterp\fR command, a
+new Tcl command is created in the master interpreter with the same
+name as the new interpreter. This command may be used to invoke
+various operations on the interpreter. It has the following
+general form:
+.PP
+.CS
+\fIslave command \fR?\fIarg arg ...\fR?
+.CE
+.PP
+\fISlave\fR is the name of the interpreter, and \fIcommand\fR
+and the \fIarg\fRs determine the exact behavior of the command.
+The valid forms of this command are:
+.TP
+\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
+as the current names of the commands).
+.TP
+\fIslave \fBalias \fIsrcToken\fR
+.
+Returns a Tcl list whose elements are the \fItargetCmd\fR and
+\fIarg\fRs associated with the alias represented by \fIsrcToken\fR
+(this is the value returned when the alias was
+created; it is possible that the actual source command in the
+slave is different from \fIsrcToken\fR).
+.TP
+\fIslave \fBalias \fIsrcToken \fB{}\fR
+.
+Deletes the alias for \fIsrcToken\fR in the slave interpreter.
+\fIsrcToken\fR refers to the value returned when the alias
+was created; if the source command has been renamed, the renamed
+command will be deleted.
+.TP
+\fIslave \fBalias \fIsrcCmd targetCmd \fR?\fIarg ..\fR?
+.
+Creates an alias such that whenever \fIsrcCmd\fR is invoked
+in \fIslave\fR, \fItargetCmd\fR is invoked in the master.
+The \fIarg\fR arguments will be passed to \fItargetCmd\fR as additional
+arguments, prepended before any arguments passed in the invocation of
+\fIsrcCmd\fR.
+See \fBALIAS INVOCATION\fR below for 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.
+.TP
+\fIslave \fBbgerror\fR ?\fIcmdPrefix\fR?
+.
+This command either gets or sets the current background exception handler
+for the \fIslave\fR interpreter. If \fIcmdPrefix\fR is
+absent, the current background exception 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 exception handler to. See the
+\fBBACKGROUND EXCEPTION HANDLING\fR section for more details.
+.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 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.
+.TP
+\fIslave \fBexpose \fIhiddenName \fR?\fIexposedCmdName\fR?
+.
+This command exposes the hidden command \fIhiddenName\fR, eventually bringing
+it back under a new \fIexposedCmdName\fR name (this name is currently
+accepted only if it is a valid global name space name without any ::),
+in \fIslave\fR.
+If an exposed command with the targeted name already exists, this command
+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
+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
+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
+prevents slaves from fooling a master interpreter into hiding the wrong
+command, by making the current namespace be different from the global one.
+For more details on hidden commands, see \fBHIDDEN COMMANDS\fR, below.
+.TP
+\fIslave \fBhidden\fR
+.
+Returns a list of the names of all hidden commands in \fIslave\fR.
+.TP
+\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. 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.
+.TP
+\fIslave \fBissafe\fR
+.
+Returns \fB1\fR if the slave interpreter is safe, \fB0\fR otherwise.
+.TP
+\fIslave \fBlimit\fR \fIlimitType\fR ?\fI\-option\fR? ?\fIvalue\fR \fI...\fR?
+.
+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.
+.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.
+.TP
+\fIslave\fR \fBrecursionlimit\fR ?\fInewlimit\fR?
+.
+Returns the maximum allowable nesting depth for the \fIslave\fR interpreter.
+If \fInewlimit\fR is specified, the recursion limit in \fIslave\fR will be
+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.
+.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.
+.RE
+.SH "SAFE INTERPRETERS"
+.PP
+A safe interpreter is one with restricted functionality, so that
+is safe to execute an arbitrary script from your worst enemy without
+fear of that script damaging the enclosing application or the rest
+of your computing environment. In order to make an interpreter
+safe, certain commands and variables are removed from the interpreter.
+For example, commands to create files on disk are removed, and the
+\fBexec\fR command is removed, since it could be used to cause damage
+through subprocesses.
+Limited access to these facilities can be provided, by creating
+aliases to the master interpreter which check their arguments carefully
+and provide restricted access to a safe subset of facilities.
+For example, file creation might be allowed in a particular subdirectory
+and subprocess invocation might be allowed for a carefully selected and
+fixed set of programs.
+.PP
+A safe interpreter is created by specifying the \fB\-safe\fR switch
+to the \fBinterp create\fR command. Furthermore, any slave created
+by a safe interpreter will also be safe.
+.PP
+A safe interpreter is created with exactly the following set of
+built-in commands:
+.DS
+.ta 1.2i 2.4i 3.6i
+\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
+The following commands are hidden by \fBinterp create\fR when it
+creates a safe interpreter:
+.DS
+.ta 1.2i 2.4i 3.6i
+\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.
+.PP
+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\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.
+Autoload access to Tcl's commands that are normally autoloaded:
+.DS
+.ta 2.1i
+\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
+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.
+.PP
+In addition, the \fBenv\fR variable is not present in a safe interpreter,
+so it cannot share environment variables with other interpreters. The
+\fBenv\fR variable poses a security risk, because users can store
+sensitive information in an environment variable. For example, the PGP
+manual recommends storing the PGP private key protection password in
+the environment variable \fIPGPPASS\fR. Making this variable available
+to untrusted code executing in a safe interpreter would incur a
+security risk.
+.PP
+If extensions are loaded into a safe interpreter, they may also restrict
+their own functionality to eliminate unsafe commands. For a discussion of
+management of extensions for safety see the manual entries for
+\fBSafe\-Tcl\fR and the \fBload\fR Tcl command.
+.PP
+A safe interpreter may not alter the recursion limit of any interpreter,
+including itself.
+.SH "ALIAS INVOCATION"
+.PP
+The alias mechanism has been carefully designed so that it can
+be used safely when an untrusted script is executing
+in a safe slave and the target of the alias is a trusted
+master. The most important thing in guaranteeing safety is to
+ensure that information passed from the slave to the master is
+never evaluated or substituted in the master; if this were to
+occur, it would enable an evil script in the slave to invoke
+arbitrary functions in the master, which would compromise security.
+.PP
+When the source for an alias is invoked in the slave interpreter, the
+usual Tcl substitutions are performed when parsing that command.
+These substitutions are carried out in the source interpreter just
+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
+.QW "\fIsrcCmd arg1 arg2 ... argN\fR" ,
+the new set of words will be
+.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
+is invoked with the new set of arguments. An error occurs if
+there is no command named \fItargetCmd\fR in the target interpreter.
+No additional substitutions are performed on the words: the
+target command procedure is invoked directly, without
+going through the normal Tcl evaluation mechanism.
+Substitutions are thus performed on each word exactly once:
+\fItargetCmd\fR and \fIargs\fR were substituted when parsing the command
+that created the alias, and \fIarg1 - argN\fR are substituted when
+the alias's source command is parsed in the source interpreter.
+.PP
+When writing the \fItargetCmd\fRs for aliases in safe interpreters,
+it is very important that the arguments to that command never be
+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.
+.SH "HIDDEN COMMANDS"
+.PP
+Safe interpreters greatly restrict the functionality available to Tcl
+programs executing within them.
+Allowing the untrusted Tcl program to have direct access to this
+functionality is unsafe, because it can be used for a variety of
+attacks on the environment.
+However, there are times when there is a legitimate need to use the
+dangerous functionality in the context of the safe interpreter. For
+example, sometimes a program must be \fBsource\fRd into the interpreter.
+Another example is Tk, where windows are bound to the hierarchy of windows
+for a specific interpreter; some potentially dangerous functions, e.g.
+window management, must be performed on these windows within the
+interpreter context.
+.PP
+The \fBinterp\fR command provides a solution to this problem in the form of
+\fIhidden commands\fR. Instead of removing the dangerous commands entirely
+from a safe interpreter, these commands are hidden so they become
+unavailable to Tcl scripts executing in the interpreter. However, such
+hidden commands can be invoked by any trusted ancestor of the safe
+interpreter, in the context of the safe interpreter, using \fBinterp
+invoke\fR. Hidden commands and exposed commands reside in separate name
+spaces. It is possible to define a hidden command and an exposed command by
+the same name within one interpreter.
+.PP
+Hidden commands in a slave interpreter can be invoked in the body of
+procedures called in the master during alias invocation. For example, an
+alias for \fBsource\fR could be created in a slave interpreter. When it is
+invoked in the slave interpreter, a procedure is called in the master
+interpreter to check that the operation is allowable (e.g. it asks to
+source a file that the slave interpreter is allowed to access). The
+procedure then it invokes the hidden \fBsource\fR command in the slave
+interpreter to actually source in the contents of the file. Note that two
+commands named \fBsource\fR exist in the slave interpreter: the alias, and
+the hidden command.
+.PP
+Because a master interpreter may invoke a hidden command as part of
+handling an alias invocation, great care must be taken to avoid evaluating
+any arguments passed in through the alias invocation.
+Otherwise, malicious slave interpreters could cause a trusted master
+interpreter to execute dangerous commands on their behalf. See the section
+on \fBALIAS INVOCATION\fR for a more complete discussion of this topic.
+To help avoid this problem, no substitutions or evaluations are
+applied to arguments of \fBinterp invokehidden\fR.
+.PP
+Safe interpreters are not allowed to invoke hidden commands in themselves
+or in their descendants. This prevents safe slaves from gaining access to
+hidden functionality in themselves or their descendants.
+.PP
+The set of hidden commands in an interpreter can be manipulated by a trusted
+interpreter using \fBinterp expose\fR and \fBinterp hide\fR. The \fBinterp
+expose\fR command moves a hidden command to the
+set of exposed commands in the interpreter identified by \fIpath\fR,
+potentially renaming the command in the process. If an exposed command by
+the targeted name already exists, the operation fails. Similarly,
+\fBinterp hide\fR moves an exposed command to the set of hidden commands in
+that interpreter. Safe interpreters are not allowed to move commands
+between the set of hidden and exposed commands, in either themselves or
+their descendants.
+.PP
+Currently, the names of hidden commands cannot contain namespace
+qualifiers, and you must first rename a command in a namespace to the
+global namespace before you can hide it.
+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.
+.SH "RESOURCE LIMITS"
+.PP
+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.
+.TP
+\fB\-command\fR
+.
+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 exception, it
+is reported through the background exception mechanism (see
+\fBBACKGROUND EXCEPTION 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.
+.TP
+\fB\-granularity\fR
+.
+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.
+.TP
+\fB\-milliseconds\fR
+.
+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.)
+.TP
+\fB\-seconds\fR
+.
+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.
+.TP
+\fB\-value\fR
+.
+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 EXCEPTION HANDLING"
+.PP
+When an exception 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 exception is instead reported through the background exception handling mechanism.
+Every interpreter has a background exception handler registered; the default exception
+handler arranges for the \fBbgerror\fR command in the interpreter's global
+namespace to be called, but other exception handlers may be installed and process
+background exceptions in substantially different ways.
+.PP
+A background exception 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
+interpreter result at time of the exception, typically an error message,
+and the second will be the dictionary of return options at the time of
+the exception. These are the same values that \fBcatch\fR can capture
+when it controls script evaluation in a non-background situation.
+The resulting list will then be executed
+in the interpreter's global namespace without further substitutions being
+performed.
+.SH CREDITS
+The safe interpreter mechanism is based on the Safe-Tcl prototype implemented
+by Nathaniel Borenstein and Marshall Rose.
+.SH EXAMPLES
+.PP
+Creating and using an alias for a command in the current interpreter:
+.PP
+.CS
+\fBinterp alias\fR {} getIndex {} lsearch {alpha beta gamma delta}
+set idx [getIndex delta]
+.CE
+.PP
+Executing an arbitrary command in a safe interpreter where every
+invocation of \fBlappend\fR is logged:
+.PP
+.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 invocation of lappend $args"
+ \fBinterp invokehidden\fR $i lappend {*}$args
+}
+\fBinterp eval\fR $i $someUntrustedScript
+.CE
+.PP
+Setting a resource limit on an interpreter so that an infinite loop
+terminates.
+.PP
+.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
+.SH "SEE ALSO"
+bgerror(n), load(n), safe(n), Tcl_CreateSlave(3), Tcl_Eval(3), Tcl_BackgroundException(3)
+.SH KEYWORDS
+alias, master interpreter, safe interpreter, slave interpreter
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/pkgs/msgcat/doc/join.n b/pkgs/msgcat/doc/join.n
new file mode 100644
index 0000000..1b23667
--- /dev/null
+++ b/pkgs/msgcat/doc/join.n
@@ -0,0 +1,44 @@
+'\"
+'\" 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 join n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+join \- Create a string by joining together list elements
+.SH SYNOPSIS
+\fBjoin \fIlist \fR?\fIjoinString\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fIlist\fR argument must be a valid Tcl list.
+This command returns the string
+formed by joining all of the elements of \fIlist\fR together with
+\fIjoinString\fR separating each adjacent pair of elements.
+The \fIjoinString\fR argument defaults to a space character.
+.SH EXAMPLES
+.PP
+Making a comma-separated list:
+.PP
+.CS
+set data {1 2 3 4 5}
+\fBjoin\fR $data ", "
+ \fB\(-> 1, 2, 3, 4, 5\fR
+.CE
+.PP
+Using \fBjoin\fR to flatten a list by a single level:
+.PP
+.CS
+set data {1 {2 3} 4 {5 {6 7} 8}}
+\fBjoin\fR $data
+ \fB\(-> 1 2 3 4 5 {6 7} 8\fR
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), split(n)
+.SH KEYWORDS
+element, join, list, separator
diff --git a/pkgs/msgcat/doc/lappend.n b/pkgs/msgcat/doc/lappend.n
new file mode 100644
index 0000000..9bfab72
--- /dev/null
+++ b/pkgs/msgcat/doc/lappend.n
@@ -0,0 +1,49 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH lappend n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+lappend \- Append list elements onto a variable
+.SH SYNOPSIS
+\fBlappend \fIvarName \fR?\fIvalue value value ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+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 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,
+.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
+.PP
+Using \fBlappend\fR to build up a list of numbers.
+.PP
+.CS
+% set var 1
+1
+% \fBlappend\fR var 2
+1 2
+% \fBlappend\fR var 3 4 5
+1 2 3 4 5
+.CE
+.SH "SEE ALSO"
+list(n), lindex(n), linsert(n), llength(n), lset(n),
+lsort(n), lrange(n)
+.SH KEYWORDS
+append, element, list, variable
diff --git a/pkgs/msgcat/doc/lassign.n b/pkgs/msgcat/doc/lassign.n
new file mode 100644
index 0000000..6f5042b
--- /dev/null
+++ b/pkgs/msgcat/doc/lassign.n
@@ -0,0 +1,60 @@
+'\"
+'\" 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 \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
+.PP
+An illustration of how multiple assignment works, and what happens
+when there are either too few or too many elements.
+.PP
+.CS
+\fBlassign\fR {a b c} x y z ;# Empty return
+puts $x ;# Prints "a"
+puts $y ;# Prints "b"
+puts $z ;# Prints "c"
+
+\fBlassign\fR {d e} x y z ;# Empty return
+puts $x ;# Prints "d"
+puts $y ;# Prints "e"
+puts $z ;# Prints ""
+
+\fBlassign\fR {f g h i} x y ;# Returns "h i"
+puts $x ;# Prints "f"
+puts $y ;# Prints "g"
+.CE
+.PP
+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:
+.PP
+.CS
+set ::argv [\fBlassign\fR $::argv argumentToReadOff]
+.CE
+.SH "SEE ALSO"
+lindex(n), list(n), lrange(n), lset(n), set(n)
+.SH KEYWORDS
+assign, element, list, multiple, set, variable
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/pkgs/msgcat/doc/library.n b/pkgs/msgcat/doc/library.n
new file mode 100644
index 0000000..2413692
--- /dev/null
+++ b/pkgs/msgcat/doc/library.n
@@ -0,0 +1,314 @@
+'\"
+'\" Copyright (c) 1991-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 library n "8.0" Tcl "Tcl Built-In Commands"
+.BS
+.SH NAME
+auto_execok, auto_import, auto_load, auto_mkindex, auto_qualify, auto_reset, tcl_findLibrary, parray, tcl_endOfWord, tcl_startOfNextWord, tcl_startOfPreviousWord, tcl_wordBreakAfter, tcl_wordBreakBefore \- standard library of Tcl procedures
+.SH SYNOPSIS
+.nf
+\fBauto_execok \fIcmd\fR
+\fBauto_import \fIpattern\fR
+\fBauto_load \fIcmd\fR
+\fBauto_mkindex \fIdir pattern pattern ...\fR
+\fBauto_qualify \fIcommand namespace\fR
+\fBauto_reset\fR
+\fBtcl_findLibrary \fIbasename version patch initScript enVarName varName\fR
+\fBparray \fIarrayName\fR
+\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
+.BE
+.SH INTRODUCTION
+.PP
+Tcl includes a library of Tcl procedures for commonly-needed functions.
+The procedures defined in the Tcl library are generic ones suitable
+for use by many different applications.
+The location of the Tcl library is returned by the \fBinfo library\fR
+command.
+In addition to the Tcl library, each application will normally have
+its own library of support procedures as well; the location of this
+library is normally given by the value of the \fB$\fIapp\fB_library\fR
+global variable, where \fIapp\fR is the name of the application.
+For example, the location of the Tk library is kept in the variable
+\fBtk_library\fR.
+.PP
+To access the procedures in the Tcl library, an application should
+source the file \fBinit.tcl\fR in the library, for example with
+the Tcl command
+.PP
+.CS
+\fBsource [file join [info library] init.tcl]\fR
+.CE
+.PP
+If the library procedure \fBTcl_Init\fR is invoked from an application's
+\fBTcl_AppInit\fR procedure, this happens automatically.
+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:
+.TP
+\fBauto_execok \fIcmd\fR
+Determines whether there is an executable file or shell builtin
+by the name \fIcmd\fR. If so, it returns a list of arguments to be
+passed to \fBexec\fR to execute the executable file or shell builtin
+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_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
+\fBauto_execok\fR to forget its cached information.
+.TP
+\fBauto_import \fIpattern\fR
+\fBAuto_import\fR is invoked during \fBnamespace import\fR to see if
+the imported commands specified by \fIpattern\fR reside in an
+autoloaded library. If so, the commands are loaded so that they will
+be available to the interpreter for creating the import links. If the
+commands do not reside in an autoloaded library, \fBauto_import\fR
+does nothing. The pattern matching is performed according to the
+matching rules of \fBnamespace import\fR.
+.TP
+\fBauto_load \fIcmd\fR
+This command attempts to load the definition for a Tcl command named
+\fIcmd\fR. To do this, it searches an \fIauto-load path\fR, which is
+a list of one or more directories. The auto-load path is given by the
+global variable \fBauto_path\fR if it exists. If there is no
+\fBauto_path\fR variable, then the TCLLIBPATH environment variable is
+used, if it exists. Otherwise the auto-load path consists of just the
+Tcl library directory. Within each directory in the auto-load path
+there must be a file \fBtclIndex\fR that describes one or more
+commands defined in that directory and a script to evaluate to load
+each of the commands. The \fBtclIndex\fR file should be generated
+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 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
+the array \fBauto_index\fR; future calls to \fBauto_load\fR check for
+\fIcmd\fR in the array rather than re-reading the index files. The
+cached index information may be deleted with the command
+\fBauto_reset\fR. This will force the next \fBauto_load\fR command to
+reload the index database from disk.
+.TP
+\fBauto_mkindex \fIdir pattern pattern ...\fR
+.
+Generates an index suitable for use by \fBauto_load\fR. The command
+searches \fIdir\fR for all files whose names match any of the
+\fIpattern\fR arguments (matching is done with the \fBglob\fR
+command), generates an index of all the Tcl command procedures defined
+in all the matching files, and stores the index information in a file
+named \fBtclIndex\fR in \fIdir\fR. If no pattern is given a pattern of
+\fB*.tcl\fR will be assumed. For example, the command
+.RS
+.PP
+.CS
+\fBauto_mkindex foo *.tcl\fR
+.CE
+.PP
+will read all the \fB.tcl\fR files in subdirectory \fBfoo\fR and
+generate a new index file \fBfoo/tclIndex\fR.
+.PP
+\fBAuto_mkindex\fR parses the Tcl scripts by sourcing them into a
+slave interpreter and monitoring the proc and namespace commands that
+are executed. Extensions can use the (undocumented)
+auto_mkindex_parser package to register other commands that can
+contribute to the auto_load index. You will have to read through
+auto.tcl to see how this works.
+.PP
+\fBAuto_mkindex_old\fR
+(which has the same syntax as \fBauto_mkindex\fR)
+parses the Tcl scripts in a relatively
+unsophisticated way: if any line contains the word
+.QW \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 do not appear in this way (e.g.\ they
+have spaces before the \fBproc\fR) will not be indexed. If your
+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 \fBauto_mkindex_old\fR.
+.RE
+.TP
+\fBauto_reset\fR
+.
+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 are used.
+.TP
+\fBauto_qualify \fIcommand namespace\fR
+Computes a list of fully qualified names for \fIcommand\fR. This list
+mirrors the path a standard Tcl interpreter follows for command
+lookups: first it looks for the command in the current namespace, and
+then in the global namespace. Accordingly, if \fIcommand\fR is
+relative and \fInamespace\fR is not \fB::\fR, the list returned has
+two elements: \fIcommand\fR scoped by \fInamespace\fR, as if it were
+a command in the \fInamespace\fR namespace; and \fIcommand\fR as if it
+were a command in the global namespace. Otherwise, if either
+\fIcommand\fR is absolute (it begins with \fB::\fR), or
+\fInamespace\fR is \fB::\fR, the list contains only \fIcommand\fR as
+if it were a command in the global namespace.
+.RS
+.PP
+\fBAuto_qualify\fR is used by the auto-loading facilities in Tcl, both
+for producing auto-loading indexes such as \fIpkgIndex.tcl\fR, and for
+performing the actual auto-loading of functions at runtime.
+.RE
+.TP
+\fBtcl_findLibrary \fIbasename version patch initScript enVarName varName\fR
+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\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\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\fR;
+relative to the Tcl library directory;
+relative to the executable file in the standard installation
+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
+\fBparray \fIarrayName\fR
+Prints on standard output the names and values of all the elements
+in the array \fIarrayName\fR.
+\fIArrayName\fR must be an array accessible to the caller of \fBparray\fR.
+It may be either local or global.
+.TP
+\fBtcl_endOfWord \fIstr start\fR
+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
+first word character after the starting point. Returns -1 if there
+are no more end-of-word locations after the starting point. See the
+description of \fBtcl_wordchars\fR and \fBtcl_nonwordchars\fR below
+for more details on how Tcl determines which characters are word
+characters.
+.TP
+\fBtcl_startOfNextWord \fIstr start\fR
+Returns the index of the first start-of-word location that occurs
+after a starting index \fIstart\fR in the string \fIstr\fR. A
+start-of-word location is defined to be the first word character
+following a non-word character. Returns \-1 if there are no more
+start-of-word locations after the starting point.
+.TP
+\fBtcl_startOfPreviousWord \fIstr start\fR
+Returns the index of the first start-of-word location that occurs
+before a starting index \fIstart\fR in the string \fIstr\fR. Returns
+\-1 if there are no more start-of-word locations before the starting
+point.
+.TP
+\fBtcl_wordBreakAfter \fIstr start\fR
+Returns the index of the first word boundary after the starting index
+\fIstart\fR in the string \fIstr\fR. Returns \-1 if there are no more
+boundaries after the starting point in the given string. The index
+returned refers to the second character of the pair that comprises a
+boundary.
+.TP
+\fBtcl_wordBreakBefore \fIstr start\fR
+Returns the index of the first word boundary before the starting index
+\fIstart\fR in the string \fIstr\fR. Returns \-1 if there are no more
+boundaries before the starting point in the given string. The index
+returned refers to the second character of the pair that comprises a
+boundary.
+.SH "VARIABLES"
+.PP
+The following global variables are defined or used by the procedures in
+the Tcl library. They fall into two broad classes, handling unknown
+commands and packages, and determining what are words.
+.SS "AUTOLOADING AND PACKAGE MANAGEMENT VARIABLES"
+.TP
+\fBauto_execs\fR
+Used by \fBauto_execok\fR to record information about whether
+particular commands exist as executable files.
+.TP
+\fBauto_index\fR
+Used by \fBauto_load\fR to save the index information read from
+disk.
+.TP
+\fBauto_noexec\fR
+If set to any value, then \fBunknown\fR will not attempt to auto-exec
+any commands.
+.TP
+\fBauto_noload\fR
+If set to any value, then \fBunknown\fR will not attempt to auto-load
+any commands.
+.TP
+\fBauto_path\fR
+If set, then it must contain a valid Tcl list giving directories to
+search during auto-load operations.
+This variable is initialized during startup to contain, in order:
+the directories listed in the \fBTCLLIBPATH\fR environment variable,
+the directory named by the \fBtcl_library\fR variable,
+the parent directory of \fBtcl_library\fR,
+the directories listed in the \fBtcl_pkgPath\fR variable.
+.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.
+.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.
+.SS "WORD BOUNDARY DETERMINATION VARIABLES"
+These variables are only used in the \fBtcl_endOfWord\fR,
+\fBtcl_startOfNextWord\fR, \fBtcl_startOfPreviousWord\fR,
+\fBtcl_wordBreakAfter\fR, and \fBtcl_wordBreakBefore\fR commands.
+.TP
+\fBtcl_nonwordchars\fR
+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
+considered to be a non-word character. On Windows platforms, spaces,
+tabs, and newlines are considered non-word characters. Under Unix,
+everything but numbers, letters and underscores are considered
+non-word characters.
+.TP
+\fBtcl_wordchars\fR
+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
+considered to be a word character. On Windows platforms, words are
+comprised of any character that is not a space, tab, or newline. Under
+Unix, words are comprised of numbers, letters or underscores.
+.SH "SEE ALSO"
+info(n), re_syntax(n), tclvars(n)
+.SH KEYWORDS
+auto-exec, auto-load, library, unknown, word, whitespace
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/pkgs/msgcat/doc/lindex.n b/pkgs/msgcat/doc/lindex.n
new file mode 100644
index 0000000..bb272a6
--- /dev/null
+++ b/pkgs/msgcat/doc/lindex.n
@@ -0,0 +1,125 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" 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.
+'\"
+.so man.macros
+.TH lindex n 8.4 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+lindex \- Retrieve an element from a list
+.SH SYNOPSIS
+\fBlindex \fIlist ?index ...?\fR
+.BE
+.SH DESCRIPTION
+.PP
+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.
+.PP
+If no indices are presented, the command takes the form:
+.PP
+.CS
+\fBlindex \fIlist\fR
+.CE
+.PP
+or
+.PP
+.CS
+\fBlindex \fIlist\fR {}
+.CE
+.PP
+In this case, the return value of \fBlindex\fR is simply the value of the
+\fIlist\fR parameter.
+.PP
+When presented with a single index, the \fBlindex\fR command
+treats \fIlist\fR as a Tcl list and returns the
+\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
+interpreter; however, variable
+substitution and command substitution do not occur.
+If \fIindex\fR is negative or greater than or equal to the number
+of elements in \fIvalue\fR, then an empty
+string is returned.
+The interpretation of each simple \fIindex\fR value is the same as
+for the command \fBstring index\fR, supporting simple index
+arithmetic and indices relative to the end of the list.
+.PP
+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,
+.PP
+.CS
+\fBlindex\fR $a 1 2 3
+.CE
+.PP
+or
+.PP
+.CS
+\fBlindex\fR $a {1 2 3}
+.CE
+.PP
+is synonymous with
+.PP
+.CS
+\fBlindex\fR [\fBlindex\fR [\fBlindex\fR $a 1] 2] 3
+.CE
+.SH EXAMPLES
+.PP
+Lists can be indexed into from either end:
+.PP
+.CS
+\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
+.CE
+.PP
+Lists or sequences of indices allow selection into lists of lists:
+.PP
+.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} {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
+.PP
+List indices may also perform limited computation, adding or subtracting fixed
+amounts from other indices:
+.PP
+.CS
+set idx 1
+\fBlindex\fR {a b c d e f} $idx+2
+ \fI\(-> d\fR
+set idx 3
+\fBlindex\fR {a b c d e f} $idx+2
+ \fI\(-> f\fR
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), linsert(n), llength(n), lsearch(n),
+lset(n), lsort(n), lrange(n), lreplace(n),
+string(n)
+.SH KEYWORDS
+element, index, list
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/pkgs/msgcat/doc/linsert.n b/pkgs/msgcat/doc/linsert.n
new file mode 100644
index 0000000..c722e4f
--- /dev/null
+++ b/pkgs/msgcat/doc/linsert.n
@@ -0,0 +1,55 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH linsert n 8.2 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+linsert \- Insert elements into a list
+.SH SYNOPSIS
+\fBlinsert \fIlist index \fR?\fIelement element ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+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, and if \fIindex\fR is
+greater or equal to the length of \fIlist\fR, it is as if it was \fBend\fR.
+As with \fBstring index\fR, the \fIindex\fR value supports both simple index
+arithmetic and end-relative indexing.
+.PP
+Subject to the restrictions that indices must refer to locations inside the
+list and that the \fIelement\fRs will always be inserted in order, insertions
+are done so that when \fIindex\fR is start-relative, the first \fIelement\fR
+will be at that index in the resulting list, and when \fIindex\fR is
+end-relative, the last \fIelement\fR will be at that index in the resulting
+list.
+.SH EXAMPLE
+.PP
+Putting some values into a list, first indexing from the start and
+then indexing from the end, and then chaining them together:
+.PP
+.CS
+set oldList {the fox jumps over the dog}
+set midList [\fBlinsert\fR $oldList 1 quick]
+set newList [\fBlinsert\fR $midList end-1 lazy]
+# The old lists still exist though...
+set newerList [\fBlinsert\fR [\fBlinsert\fR $oldList end-1 quick] 1 lazy]
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), lindex(n), llength(n), lsearch(n),
+lset(n), lsort(n), lrange(n), lreplace(n),
+string(n)
+.SH KEYWORDS
+element, insert, list
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/list.n b/pkgs/msgcat/doc/list.n
new file mode 100644
index 0000000..5705254
--- /dev/null
+++ b/pkgs/msgcat/doc/list.n
@@ -0,0 +1,56 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH list n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+list \- Create a list
+.SH SYNOPSIS
+\fBlist \fR?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command returns a list comprised of all the \fIarg\fRs,
+or an empty string if no \fIarg\fRs are specified.
+Braces and backslashes get added as necessary, so that the \fBlindex\fR command
+may be used on the result to re-extract the original arguments, and also
+so that \fBeval\fR may be used to execute the resulting list, with
+\fIarg1\fR comprising the command's name and the other \fIarg\fRs comprising
+its arguments. \fBList\fR produces slightly different results than
+\fBconcat\fR: \fBconcat\fR removes one level of grouping before forming
+the list, while \fBlist\fR works directly from the original arguments.
+.SH EXAMPLE
+.PP
+The command
+.PP
+.CS
+\fBlist\fR a b "c d e " " f {g h}"
+.CE
+.PP
+will return
+.PP
+.CS
+\fBa b {c d e } { f {g h}}\fR
+.CE
+.PP
+while \fBconcat\fR with the same arguments will return
+.PP
+.CS
+\fBa b c d e f {g h}\fR
+.CE
+.SH "SEE ALSO"
+lappend(n), lindex(n), linsert(n), llength(n), lrange(n),
+lrepeat(n),
+lreplace(n), lsearch(n), lset(n), lsort(n)
+.SH KEYWORDS
+element, list, quoting
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/pkgs/msgcat/doc/llength.n b/pkgs/msgcat/doc/llength.n
new file mode 100644
index 0000000..b0ee4d9
--- /dev/null
+++ b/pkgs/msgcat/doc/llength.n
@@ -0,0 +1,55 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH llength n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+llength \- Count the number of elements in a list
+.SH SYNOPSIS
+\fBllength \fIlist\fR
+.BE
+.SH DESCRIPTION
+.PP
+Treats \fIlist\fR as a list and returns a decimal string giving
+the number of elements in it.
+.SH EXAMPLES
+.PP
+The result is the number of elements:
+.PP
+.CS
+% \fBllength\fR {a b c d e}
+5
+% \fBllength\fR {a b c}
+3
+% \fBllength\fR {}
+0
+.CE
+.PP
+Elements are not guaranteed to be exactly words in a dictionary sense
+of course, especially when quoting is used:
+.PP
+.CS
+% \fBllength\fR {a b {c d} e}
+4
+% \fBllength\fR {a b { } c d e}
+6
+.CE
+.PP
+An empty list is not necessarily an empty string:
+.PP
+.CS
+% set var { }; puts "[string length $var],[\fBllength\fR $var]"
+1,0
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), lindex(n), linsert(n), lsearch(n),
+lset(n), lsort(n), lrange(n), lreplace(n)
+.SH KEYWORDS
+element, list, length
diff --git a/pkgs/msgcat/doc/load.n b/pkgs/msgcat/doc/load.n
new file mode 100644
index 0000000..c32cb65
--- /dev/null
+++ b/pkgs/msgcat/doc/load.n
@@ -0,0 +1,180 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH load n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+load \- Load machine code and initialize new commands
+.SH SYNOPSIS
+\fBload \fIfileName\fR
+.br
+\fBload \fIfileName packageName\fR
+.br
+\fBload \fIfileName packageName interp\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command loads binary code from a file into the
+application's address space and calls an initialization procedure
+in the package to incorporate it into an interpreter. \fIfileName\fR
+is the name of the file containing the code; its exact form varies
+from system to system but on most systems it is a shared library,
+such as a \fB.so\fR file under Solaris or a DLL under Windows.
+\fIpackageName\fR is the name of the package, and is used to
+compute the name of an initialization procedure.
+\fIinterp\fR is the path name of the interpreter into which to load
+the package (see the \fBinterp\fR manual entry for details);
+if \fIinterp\fR is omitted, it defaults to the
+interpreter in which the \fBload\fR command was invoked.
+.PP
+Once the file has been loaded into the application's address space,
+one of two initialization procedures will be invoked in the new code.
+Typically the initialization procedure will add new commands to a
+Tcl interpreter.
+The name of the initialization 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_Init\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_Init\fR.
+.PP
+If the target interpreter is a safe interpreter, then the name
+of the initialization procedure will be \fIpkg\fB_SafeInit\fR
+instead of \fIpkg\fB_Init\fR.
+The \fIpkg\fB_SafeInit\fR function should be written carefully, so that it
+initializes the safe interpreter only with partial functionality provided
+by the package that is safe for use by untrusted code. For more information
+on Safe\-Tcl, see the \fBsafe\fR manual entry.
+.PP
+The initialization procedure must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_PackageInitProc\fR(
+ Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+The \fIinterp\fR argument identifies the interpreter in which the
+package is to be loaded. The initialization 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. The result of the \fBload\fR command
+will be the result returned by the initialization procedure.
+.PP
+The actual loading of a file will only be done once for each \fIfileName\fR
+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.
+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.
+.PP
+The \fBload\fR command also supports packages that are statically
+linked with the application, if those packages have been registered
+by calling the \fBTcl_StaticPackage\fR procedure.
+If \fIfileName\fR is an empty string, then \fIpackageName\fR 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 \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.
+.PP
+If \fIfileName\fR is an empty string, then \fIpackageName\fR must
+be specified.
+The \fBload\fR command first searches for a statically loaded package
+(one that has been registered by calling the \fBTcl_StaticPackage\fR
+procedure) by that name; if one is found, it is used.
+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.
+.SH "PORTABILITY ISSUES"
+.TP
+\fBWindows\fR\0\0\0\0\0
+.
+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
+.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:
+.RS
+.PP
+.CS
+\fBload\fR [file join [pwd] mylib.DLL]
+.CE
+.RE
+.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).
+.SH EXAMPLE
+.PP
+The following is a minimal extension:
+.PP
+.CS
+#include <tcl.h>
+#include <stdio.h>
+static int fooCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {
+ printf("called with %d arguments\en", objc);
+ return TCL_OK;
+}
+int Foo_Init(Tcl_Interp *interp) {
+ if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
+ return TCL_ERROR;
+ }
+ printf("creating foo command");
+ Tcl_CreateObjCommand(interp, "foo", fooCmd, NULL, NULL);
+ return TCL_OK;
+}
+.CE
+.PP
+When built into a shared/dynamic library with a suitable name
+(e.g. \fBfoo.dll\fR on Windows, \fBlibfoo.so\fR on Solaris and Linux)
+it can then be loaded into Tcl with the following:
+.PP
+.CS
+# Load the extension
+switch $tcl_platform(platform) {
+ windows {
+ \fBload\fR [file join [pwd] foo.dll]
+ }
+ unix {
+ \fBload\fR [file join [pwd] libfoo[info sharedlibextension]]
+ }
+}
+
+# Now execute the command defined by the extension
+foo
+.CE
+.SH "SEE ALSO"
+info sharedlibextension, package(n), Tcl_StaticPackage(3), safe(n)
+.SH KEYWORDS
+binary code, dynamic library, load, safe interpreter, shared library
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/pkgs/msgcat/doc/lrange.n b/pkgs/msgcat/doc/lrange.n
new file mode 100644
index 0000000..4f4816a
--- /dev/null
+++ b/pkgs/msgcat/doc/lrange.n
@@ -0,0 +1,78 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH lrange n 7.4 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+lrange \- Return one or more adjacent elements from a list
+.SH SYNOPSIS
+\fBlrange \fIlist first last\fR
+.BE
+.SH DESCRIPTION
+.PP
+\fIList\fR must be a valid Tcl list. This command will
+return a new list consisting of elements
+\fIfirst\fR through \fIlast\fR, inclusive.
+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.
+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:
+.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
+.PP
+Selecting the first two elements:
+.PP
+.CS
+% \fBlrange\fR {a b c d e} 0 1
+a b
+.CE
+.PP
+Selecting the last three elements:
+.PP
+.CS
+% \fBlrange\fR {a b c d e} end-2 end
+c d e
+.CE
+.PP
+Selecting everything except the first and last element:
+.PP
+.CS
+% \fBlrange\fR {a b c d e} 1 end-1
+b c d
+.CE
+.PP
+Selecting a single element with \fBlrange\fR is not the same as doing
+so with \fBlindex\fR:
+.PP
+.CS
+% set var {some {elements to} select}
+some {elements to} select
+% lindex $var 1
+elements to
+% \fBlrange\fR $var 1 1
+{elements to}
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
+lset(n), lreplace(n), lsort(n),
+string(n)
+.SH KEYWORDS
+element, list, range, sublist
diff --git a/pkgs/msgcat/doc/lrepeat.n b/pkgs/msgcat/doc/lrepeat.n
new file mode 100644
index 0000000..59a1edf
--- /dev/null
+++ b/pkgs/msgcat/doc/lrepeat.n
@@ -0,0 +1,38 @@
+'\"
+'\" 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 \fIcount \fR?\fIelement ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fBlrepeat\fR command creates a list of size \fIcount * number of
+elements\fR by repeating \fIcount\fR times the sequence of elements
+\fIelement ...\fR. \fIcount\fR must be a non-negative integer,
+\fIelement\fR can be any Tcl value. Note that \fBlrepeat 1 element ...\fR
+is identical to \fBlist element ...\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/pkgs/msgcat/doc/lreplace.n b/pkgs/msgcat/doc/lreplace.n
new file mode 100644
index 0000000..6e6c3ea
--- /dev/null
+++ b/pkgs/msgcat/doc/lreplace.n
@@ -0,0 +1,86 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH lreplace n 7.4 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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 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.
+.PP
+If \fIfirst\fR is less than zero, it is considered to refer to before the
+first element of the list. For non-empty lists, the element indicated
+by \fIfirst\fR must exist or \fIfirst\fR must indicate before the
+start of the list.
+.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
+the list. If no \fIelement\fR arguments are specified, then the elements
+between \fIfirst\fR and \fIlast\fR are simply deleted. If \fIlist\fR
+is empty, any \fIelement\fR arguments are added to the end of the list.
+.SH EXAMPLES
+.PP
+Replacing an element of a list with another:
+.PP
+.CS
+% \fBlreplace\fR {a b c d e} 1 1 foo
+a foo c d e
+.CE
+.PP
+Replacing two elements of a list with three:
+.PP
+.CS
+% \fBlreplace\fR {a b c d e} 1 2 three more elements
+a three more elements d e
+.CE
+.PP
+Deleting the last element from a list in a variable:
+.PP
+.CS
+% set var {a b c d e}
+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:
+.PP
+.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"
+list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
+lset(n), lrange(n), lsort(n),
+string(n)
+.SH KEYWORDS
+element, list, replace
diff --git a/pkgs/msgcat/doc/lreverse.n b/pkgs/msgcat/doc/lreverse.n
new file mode 100644
index 0000000..f52db9b
--- /dev/null
+++ b/pkgs/msgcat/doc/lreverse.n
@@ -0,0 +1,34 @@
+'\"
+'\" 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
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/lsearch.n b/pkgs/msgcat/doc/lsearch.n
new file mode 100644
index 0000000..7835352
--- /dev/null
+++ b/pkgs/msgcat/doc/lsearch.n
@@ -0,0 +1,220 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\" 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.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+lsearch \- See if a list contains a particular element
+.SH SYNOPSIS
+\fBlsearch \fR?\fIoptions\fR? \fIlist pattern\fR
+.BE
+.SH DESCRIPTION
+.PP
+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
+(unless the options \fB\-all\fR or \fB\-inline\fR are specified.)
+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 must have one of the values below:
+.SS "MATCHING STYLE OPTIONS"
+.PP
+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
+.
+\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\-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"
+.PP
+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
+.
+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.
+.TP
+\fB\-not\fR
+.
+This negates the sense of the match, returning the index of the first
+non-matching value in the list.
+.TP
+\fB\-start\fR\0\fIindex\fR
+.
+The list is searched starting at position \fIindex\fR.
+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.
+.SS "CONTENTS DESCRIPTION OPTIONS"
+.PP
+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.
+.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.
+.TP
+\fB\-real\fR
+.
+The list elements are to be compared as floating-point values.
+.SS "SORTED LIST OPTIONS"
+.PP
+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\-decreasing\fR
+.
+The list elements are sorted in decreasing order. This option is only
+meaningful when used with \fB\-sorted\fR.
+.TP
+\fB\-increasing\fR
+.
+The list elements are sorted in increasing order. This option is only
+meaningful when used with \fB\-sorted\fR.
+.TP
+\fB\-bisect\fR
+.VS 8.6
+Inexact search when the list elements are in sorted order. For an increasing
+list the last index where the element is less than or equal to the pattern
+is returned. For a decreasing list the last index where the element is greater
+than or equal to the pattern is returned. If the pattern is before the first
+element or the list is empty, -1 is returned.
+This option implies \fB\-sorted\fR and cannot be used with either \fB\-all\fR
+or \fB\-not\fR.
+.VE 8.6
+.SS "NESTED LIST OPTIONS"
+.PP
+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
+\fB\-index\fR is also specified, and is just a convenience short-cut.
+.SH EXAMPLES
+.PP
+Basic searching:
+.PP
+.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
+.CE
+.PP
+Using \fBlsearch\fR to filter lists:
+.PP
+.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:
+.PP
+.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:
+.PP
+.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:
+.PP
+.CS
+\fBlsearch\fR -index 1 -all -inline {{a abc} {b bcd} {c cde}} *bc*
+ \fI\(-> {a abc} {b bcd}\fR
+.CE
+.SH "SEE ALSO"
+foreach(n), list(n), lappend(n), lindex(n), linsert(n), llength(n),
+lset(n), lsort(n), lrange(n), lreplace(n),
+string(n)
+.SH KEYWORDS
+binary search, linear search,
+list, match, pattern, regular expression, search, string
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/lset.n b/pkgs/msgcat/doc/lset.n
new file mode 100755
index 0000000..805de16
--- /dev/null
+++ b/pkgs/msgcat/doc/lset.n
@@ -0,0 +1,146 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH lset n 8.4 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+lset \- Change an element in a list
+.SH SYNOPSIS
+\fBlset \fIvarName ?index ...? newValue\fR
+.BE
+.SH DESCRIPTION
+.PP
+The \fBlset\fR command accepts a parameter, \fIvarName\fR, which
+it interprets as the name of a variable containing a Tcl list.
+It 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.
+Finally, it accepts a new value for an element of \fIvarName\fR.
+.PP
+If no indices are presented, the command takes the form:
+.PP
+.CS
+\fBlset\fR varName newValue
+.CE
+.PP
+or
+.PP
+.CS
+\fBlset\fR varName {} newValue
+.CE
+.PP
+In this case, \fInewValue\fR replaces the old value of the variable
+\fIvarName\fR.
+.PP
+When presented with a single index, the \fBlset\fR command
+treats the content of the \fIvarName\fR variable as a Tcl list.
+It addresses the \fIindex\fR'th element in it
+(0 refers to the first element of the list).
+When interpreting the list, \fBlset\fR observes the same rules
+concerning braces and quotes and backslashes as the Tcl command
+interpreter; however, variable
+substitution and command substitution do not occur.
+The command constructs a new list in which the designated element is
+replaced with \fInewValue\fR. This new list is stored in the
+variable \fIvarName\fR, and is also the return value from the \fBlset\fR
+command.
+.PP
+If \fIindex\fR is negative or greater than the number
+of elements in \fI$varName\fR, then an error occurs.
+.PP
+If \fIindex\fR is equal to the number of elements in \fI$varName\fR,
+then the given element is appended to the list.
+.PP
+The interpretation of each simple \fIindex\fR value is the same as
+for the command \fBstring index\fR, supporting simple index
+arithmetic and indices relative to the end of the list.
+.PP
+If additional \fIindex\fR arguments are supplied, then each argument is
+used in turn to address an element within a sublist designated
+by the previous indexing operation,
+allowing the script to alter elements in sublists (or append elements
+to sublists). The command,
+.PP
+.CS
+\fBlset\fR a 1 2 newValue
+.CE
+.PP
+or
+.PP
+.CS
+\fBlset\fR a {1 2} newValue
+.CE
+.PP
+replaces element 2 of sublist 1 with \fInewValue\fR.
+.PP
+The integer appearing in each \fIindex\fR argument must be greater
+than or equal to zero. The integer appearing in each \fIindex\fR
+argument must be less than or equal to the length of the corresponding
+list. In other words, the \fBlset\fR command can change the size
+of a list only by appending an element (setting the one after the current
+end). If an index is outside the permitted range, an error is reported.
+.SH EXAMPLES
+.PP
+In each of these examples, the initial value of \fIx\fR is:
+.PP
+.CS
+set x [list [list a b c] [list d e f] [list g h i]]
+ \fI\(-> {a b c} {d e f} {g h i}\fR
+.CE
+.PP
+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.)
+.PP
+.CS
+\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
+.PP
+In the following examples, the initial value of \fIx\fR is:
+.PP
+.CS
+set x [list [list [list a b] [list c d]] \e
+ [list [list e f] [list g h]]]
+ \fI\(-> {{a b} {c d}} {{e f} {g h}}\fR
+.CE
+.PP
+The indicated return value also becomes the new value of \fIx\fR.
+.PP
+.CS
+\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),
+string(n)
+.SH KEYWORDS
+element, index, list, replace, set
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/pkgs/msgcat/doc/lsort.n b/pkgs/msgcat/doc/lsort.n
new file mode 100644
index 0000000..312048e
--- /dev/null
+++ b/pkgs/msgcat/doc/lsort.n
@@ -0,0 +1,274 @@
+'\"
+'\" 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 <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.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+lsort \- Sort the elements of a list
+.SH SYNOPSIS
+\fBlsort \fR?\fIoptions\fR? \fIlist\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command sorts the elements of \fIlist\fR, returning a new
+list in sorted order. The implementation of the \fBlsort\fR command
+uses the merge\-sort algorithm which is a stable sort that has O(n log
+n) performance characteristics.
+.PP
+By default ASCII sorting is used with the result returned in
+increasing order. However, any of the following options may be
+specified before \fIlist\fR to control the sorting process (unique
+abbreviations are accepted):
+.TP
+\fB\-ascii\fR
+.
+Use string comparison with Unicode code-point collation order (the
+name is for backward-compatibility reasons.) This is the default.
+.TP
+\fB\-dictionary\fR
+.
+Use dictionary-style comparison. This is the same as \fB\-ascii\fR
+except (a) case is ignored except as a tie-breaker and (b) if two
+strings contain embedded numbers, the numbers compare as integers,
+not characters. For example, in \fB\-dictionary\fR mode, \fBbigBoy\fR
+sorts between \fBbigbang\fR and \fBbigboy\fR, and \fBx10y\fR
+sorts between \fBx9y\fR and \fBx11y\fR.
+.TP
+\fB\-integer\fR
+.
+Convert list elements to integers and use integer comparison.
+.TP
+\fB\-real\fR
+.
+Convert list elements to floating-point values and use floating comparison.
+.TP
+\fB\-command\0\fIcommand\fR
+.
+Use \fIcommand\fR as a comparison command.
+To compare two elements, evaluate a Tcl script consisting of
+\fIcommand\fR with the two elements appended as additional
+arguments. The script should return an integer less than,
+equal to, or greater than zero if the first element is to
+be considered less than, equal to, or greater than the second,
+respectively.
+.TP
+\fB\-increasing\fR
+.
+Sort the list in increasing order
+.PQ smallest "items first" .
+This is the default.
+.TP
+\fB\-decreasing\fR
+.
+Sort the list in decreasing order
+.PQ largest "items first" .
+.TP
+\fB\-indices\fR
+.
+Return a list of indices into \fIlist\fR in sorted order instead of
+the values themselves.
+.TP
+\fB\-index\0\fIindexList\fR
+.
+If this option is specified, each of the elements of \fIlist\fR must
+itself be a proper Tcl sublist (unless \fB\-stride\fR is used).
+Instead of sorting based on whole sublists, \fBlsort\fR will extract
+the \fIindexList\fR'th element from each sublist (as if the overall
+element and the \fIindexList\fR were passed to \fBlindex\fR) and sort
+based on the given element.
+For example,
+.RS
+.PP
+.CS
+\fBlsort\fR -integer -index 1 \e
+ {{First 24} {Second 18} {Third 30}}
+.CE
+.PP
+returns \fB{Second 18} {First 24} {Third 30}\fR,
+.PP
+'\"
+'\" This example is from the test suite!
+'\"
+.CS
+\fBlsort\fR -index end-1 \e
+ {{a 1 e i} {b 2 3 f g} {c 4 5 6 d h}}
+.CE
+.PP
+returns \fB{c 4 5 6 d h} {a 1 e i} {b 2 3 f g}\fR,
+and
+.PP
+.CS
+\fBlsort\fR -index {0 1} {
+ {{b i g} 12345}
+ {{d e m o} 34512}
+ {{c o d e} 54321}
+}
+.CE
+.PP
+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.)
+This option is much more efficient than using \fB\-command\fR
+to achieve the same effect.
+.RE
+.TP
+\fB\-stride\0\fIstrideLength\fR
+.
+If this option is specified, the list is treated as consisting of
+groups of \fIstrideLength\fR elements and the groups are sorted by
+either their first element or, if the \fB\-index\fR option is used,
+by the element within each group given by the first index passed to
+\fB\-index\fR (which is then ignored by \fB\-index\fR). Elements
+always remain in the same position within their group.
+.RS
+.PP
+The list length must be an integer multiple of \fIstrideLength\fR, which
+in turn must be at least 2.
+.PP
+For example,
+.PP
+.CS
+\fBlsort\fR \-stride 2 {carrot 10 apple 50 banana 25}
+.CE
+.PP
+returns
+.QW "apple 50 banana 25 carrot 10" ,
+and
+.PP
+.CS
+\fBlsort\fR \-stride 2 \-index 1 \-integer {carrot 10 apple 50 banana 25}
+.CE
+.PP
+returns
+.QW "carrot 10 banana 25 apple 50" .
+.RE
+.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.
+.TP
+\fB\-unique\fR
+.
+If this option is specified, then only the last set of duplicate
+elements found in the list will be retained. Note that duplicates are
+determined relative to the comparison used in the sort. Thus if
+\fB\-index 0\fR is used, \fB{1 a}\fR and \fB{1 b}\fR would be
+considered duplicates and only the second element, \fB{1 b}\fR, would
+be retained.
+.SH "NOTES"
+.PP
+The options to \fBlsort\fR only control what sort of comparison is
+used, and do not necessarily constrain what the values themselves
+actually are. This distinction is only noticeable when the list to be
+sorted has fewer than two elements.
+.PP
+The \fBlsort\fR command is reentrant, meaning it is safe to use as
+part of the implementation of a command used in the \fB\-command\fR
+option.
+.SH "EXAMPLES"
+.PP
+Sorting a list using ASCII sorting:
+.PP
+.CS
+\fI%\fR \fBlsort\fR {a10 B2 b1 a1 a2}
+B2 a1 a10 a2 b1
+.CE
+.PP
+Sorting a list using Dictionary sorting:
+.PP
+.CS
+\fI%\fR \fBlsort\fR -dictionary {a10 B2 b1 a1 a2}
+a1 a2 a10 b1 B2
+.CE
+.PP
+Sorting lists of integers:
+.PP
+.CS
+\fI%\fR \fBlsort\fR -integer {5 3 1 2 11 4}
+1 2 3 4 5 11
+\fI%\fR \fBlsort\fR -integer {1 2 0x5 7 0 4 -1}
+-1 0 1 2 4 0x5 7
+.CE
+.PP
+Sorting lists of floating-point numbers:
+.PP
+.CS
+\fI%\fR \fBlsort\fR -real {5 3 1 2 11 4}
+1 2 3 4 5 11
+\fI%\fR \fBlsort\fR -real {.5 0.07e1 0.4 6e-1}
+0.4 .5 6e-1 0.07e1
+.CE
+.PP
+Sorting using indices:
+.PP
+.CS
+\fI%\fR # Note the space character before the c
+\fI%\fR \fBlsort\fR {{a 5} { c 3} {b 4} {e 1} {d 2}}
+{ c 3} {a 5} {b 4} {d 2} {e 1}
+\fI%\fR \fBlsort\fR -index 0 {{a 5} { c 3} {b 4} {e 1} {d 2}}
+{a 5} {b 4} { c 3} {d 2} {e 1}
+\fI%\fR \fBlsort\fR -index 1 {{a 5} { c 3} {b 4} {e 1} {d 2}}
+{e 1} {d 2} { c 3} {b 4} {a 5}
+.CE
+.PP
+.VS 8.6
+Sorting a dictionary:
+.PP
+.CS
+\fI%\fR set d [dict create c d a b h i f g c e]
+c e a b h i f g
+\fI%\fR \fBlsort\fR -stride 2 $d
+a b c e f g h i
+.CE
+.PP
+Sorting using striding and multiple indices:
+.PP
+.CS
+\fI%\fR # Note the first index value is relative to the group
+\fI%\fR \fBlsort\fR \-stride 3 \-index {0 1} \e
+ {{Bob Smith} 25 Audi {Jane Doe} 40 Ford}
+{{Jane Doe} 40 Ford {Bob Smith} 25 Audi}
+.CE
+.VE 8.6
+.PP
+Stripping duplicate values using sorting:
+.PP
+.CS
+\fI%\fR \fBlsort\fR -unique {a b c a b c a b c}
+a b c
+.CE
+.PP
+More complex sorting using a comparison function:
+.PP
+.CS
+\fI%\fR proc compare {a b} {
+ set a0 [lindex $a 0]
+ set b0 [lindex $b 0]
+ if {$a0 < $b0} {
+ return -1
+ } elseif {$a0 > $b0} {
+ return 1
+ }
+ return [string compare [lindex $a 1] [lindex $b 1]]
+}
+\fI%\fR \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"
+list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
+lset(n), lrange(n), lreplace(n)
+.SH KEYWORDS
+element, list, order, sort
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/man.macros b/pkgs/msgcat/doc/man.macros
new file mode 100644
index 0000000..ddd073d
--- /dev/null
+++ b/pkgs/msgcat/doc/man.macros
@@ -0,0 +1,267 @@
+.\" The -*- nroff -*- definitions below are for supplemental macros used
+.\" in Tcl/Tk manual entries.
+.\"
+.\" .AP type name in/out ?indent?
+.\" Start paragraph describing an argument to a library procedure.
+.\" type is type of argument (int, etc.), in/out is either "in", "out",
+.\" or "in/out" to describe whether procedure reads or modifies arg,
+.\" and indent is equivalent to second arg of .IP (shouldn't ever be
+.\" needed; use .AS below instead)
+.\"
+.\" .AS ?type? ?name?
+.\" Give maximum sizes of arguments for setting tab stops. Type and
+.\" name are examples of largest possible arguments that will be passed
+.\" to .AP later. If args are omitted, default tab stops are used.
+.\"
+.\" .BS
+.\" Start box enclosure. From here until next .BE, everything will be
+.\" enclosed in one large box.
+.\"
+.\" .BE
+.\" End of box enclosure.
+.\"
+.\" .CS
+.\" Begin code excerpt.
+.\"
+.\" .CE
+.\" End code excerpt.
+.\"
+.\" .VS ?version? ?br?
+.\" Begin vertical sidebar, for use in marking newly-changed parts
+.\" of man pages. The first argument is ignored and used for recording
+.\" the version when the .VS was added, so that the sidebars can be
+.\" found and removed when they reach a certain age. If another argument
+.\" is present, then a line break is forced before starting the sidebar.
+.\"
+.\" .VE
+.\" End of vertical sidebar.
+.\"
+.\" .DS
+.\" Begin an indented unfilled display.
+.\"
+.\" .DE
+.\" End of indented unfilled display.
+.\"
+.\" .SO ?manpage?
+.\" Start of list of standard options for a Tk widget. The manpage
+.\" argument defines where to look up the standard options; if
+.\" omitted, defaults to "options". The options follow on successive
+.\" lines, in three columns separated by tabs.
+.\"
+.\" .SE
+.\" End of list of standard options for a Tk widget.
+.\"
+.\" .OP cmdName dbName dbClass
+.\" Start of description of a specific option. cmdName gives the
+.\" option's name as specified in the class command, dbName gives
+.\" the option's name in the option database, and dbClass gives
+.\" the option's class in the option database.
+.\"
+.\" .UL arg1 arg2
+.\" Print arg1 underlined, then print arg2 normally.
+.\"
+.\" .QW arg1 ?arg2?
+.\" Print arg1 in quotes, then arg2 normally (for trailing punctuation).
+.\"
+.\" .PQ arg1 ?arg2?
+.\" Print an open parenthesis, arg1 in quotes, then arg2 normally
+.\" (for trailing punctuation) and then a closing parenthesis.
+.\"
+.\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
+.if t .wh -1.3i ^B
+.nr ^l \n(.l
+.ad b
+.\" # Start an argument description
+.de AP
+.ie !"\\$4"" .TP \\$4
+.el \{\
+. ie !"\\$2"" .TP \\n()Cu
+. el .TP 15
+.\}
+.ta \\n()Au \\n()Bu
+.ie !"\\$3"" \{\
+\&\\$1 \\fI\\$2\\fP (\\$3)
+.\".b
+.\}
+.el \{\
+.br
+.ie !"\\$2"" \{\
+\&\\$1 \\fI\\$2\\fP
+.\}
+.el \{\
+\&\\fI\\$1\\fP
+.\}
+.\}
+..
+.\" # define tabbing values for .AP
+.de AS
+.nr )A 10n
+.if !"\\$1"" .nr )A \\w'\\$1'u+3n
+.nr )B \\n()Au+15n
+.\"
+.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
+.nr )C \\n()Bu+\\w'(in/out)'u+2n
+..
+.AS Tcl_Interp Tcl_CreateInterp in/out
+.\" # BS - start boxed text
+.\" # ^y = starting y location
+.\" # ^b = 1
+.de BS
+.br
+.mk ^y
+.nr ^b 1u
+.if n .nf
+.if n .ti 0
+.if n \l'\\n(.lu\(ul'
+.if n .fi
+..
+.\" # BE - end boxed text (draw box now)
+.de BE
+.nf
+.ti 0
+.mk ^t
+.ie n \l'\\n(^lu\(ul'
+.el \{\
+.\" Draw four-sided box normally, but don't draw top of
+.\" box if the box started on an earlier page.
+.ie !\\n(^b-1 \{\
+\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.el \}\
+\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.\}
+.fi
+.br
+.nr ^b 0
+..
+.\" # VS - start vertical sidebar
+.\" # ^Y = starting y location
+.\" # ^v = 1 (for troff; for nroff this doesn't matter)
+.de VS
+.if !"\\$2"" .br
+.mk ^Y
+.ie n 'mc \s12\(br\s0
+.el .nr ^v 1u
+..
+.\" # VE - end of vertical sidebar
+.de VE
+.ie n 'mc
+.el \{\
+.ev 2
+.nf
+.ti 0
+.mk ^t
+\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
+.sp -1
+.fi
+.ev
+.\}
+.nr ^v 0
+..
+.\" # Special macro to handle page bottom: finish off current
+.\" # box/sidebar if in box/sidebar mode, then invoked standard
+.\" # page bottom macro.
+.de ^B
+.ev 2
+'ti 0
+'nf
+.mk ^t
+.if \\n(^b \{\
+.\" Draw three-sided box if this is the box's first page,
+.\" draw two sides but no top otherwise.
+.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.\}
+.if \\n(^v \{\
+.nr ^x \\n(^tu+1v-\\n(^Yu
+\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
+.\}
+.bp
+'fi
+.ev
+.if \\n(^b \{\
+.mk ^y
+.nr ^b 2
+.\}
+.if \\n(^v \{\
+.mk ^Y
+.\}
+..
+.\" # DS - begin display
+.de DS
+.RS
+.nf
+.sp
+..
+.\" # DE - end display
+.de DE
+.fi
+.RE
+.sp
+..
+.\" # SO - start of list of standard options
+.de SO
+'ie '\\$1'' .ds So \\fBoptions\\fR
+'el .ds So \\fB\\$1\\fR
+.SH "STANDARD OPTIONS"
+.LP
+.nf
+.ta 5.5c 11c
+.ft B
+..
+.\" # SE - end of list of standard options
+.de SE
+.fi
+.ft R
+.LP
+See the \\*(So manual entry for details on the standard options.
+..
+.\" # OP - start of full description for a single option
+.de OP
+.LP
+.nf
+.ta 4c
+Command-Line Name: \\fB\\$1\\fR
+Database Name: \\fB\\$2\\fR
+Database Class: \\fB\\$3\\fR
+.fi
+.IP
+..
+.\" # CS - begin code excerpt
+.de CS
+.RS
+.nf
+.ta .25i .5i .75i 1i
+..
+.\" # CE - end code excerpt
+.de CE
+.fi
+.RE
+..
+.\" # UL - underline word
+.de UL
+\\$1\l'|0\(ul'\\$2
+..
+.\" # QW - apply quotation marks to word
+.de QW
+.ie '\\*(lq'"' ``\\$1''\\$2
+.\"" fix emacs highlighting
+.el \\*(lq\\$1\\*(rq\\$2
+..
+.\" # PQ - apply parens and quotation marks to word
+.de PQ
+.ie '\\*(lq'"' (``\\$1''\\$2)\\$3
+.\"" fix emacs highlighting
+.el (\\*(lq\\$1\\*(rq\\$2)\\$3
+..
+.\" # QR - quoted range
+.de QR
+.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3
+.\"" fix emacs highlighting
+.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3
+..
+.\" # MT - "empty" string
+.de MT
+.QW ""
+..
diff --git a/pkgs/msgcat/doc/mathfunc.n b/pkgs/msgcat/doc/mathfunc.n
new file mode 100644
index 0000000..14b448e
--- /dev/null
+++ b/pkgs/msgcat/doc/mathfunc.n
@@ -0,0 +1,305 @@
+'\"
+'\" 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
+\fB::tcl::mathfunc::entier\fR \fIarg\fR
+.br
+\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
+.
+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.
+.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,
+approximately
+.QW "\fBsqrt\fR [\fBexpr\fR {\fIx\fB*\fIx\fB+\fIy\fB*\fIy\fR}]"
+except for being more numerically stable when the two arguments have
+substantially different magnitudes.
+.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 the \fBwordSize\fR
+element of the \fBtcl_platform\fR array.
+.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
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/pkgs/msgcat/doc/mathop.n b/pkgs/msgcat/doc/mathop.n
new file mode 100644
index 0000000..ac2ebc1
--- /dev/null
+++ b/pkgs/msgcat/doc/mathop.n
@@ -0,0 +1,310 @@
+.\"
+.\" 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 (i.e., remainder) of the first argument
+with respect to the second.
+Each \fInumber\fR must have an integral value.
+Also, the sign of the result will be the same as the sign of the second
+\fInumber\fR, which must not be zero.
+.RS
+.PP
+Note that Tcl defines this operation exactly even for negative numbers, so
+that the following command returns a true value (omitting the namespace for
+clarity):
+.PP
+.CS
+\fB==\fR [\fB*\fR [\fB/\fI x y\fR] \fIy\fR] [\fB\-\fI x\fR [\fB%\fI x y\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
+.PP
+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.
+.PP
+.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
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/memory.n b/pkgs/msgcat/doc/memory.n
new file mode 100644
index 0000000..f82c5b4
--- /dev/null
+++ b/pkgs/msgcat/doc/memory.n
@@ -0,0 +1,115 @@
+'\"
+'\" Copyright (c) 1992-1999 by Karl Lehenbauer and Mark Diekhans
+'\" Copyright (c) 2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.so man.macros
+.TH memory n 8.1 Tcl "Tcl Built-In Commands"
+.BS
+.SH NAME
+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
+debugging capabilities. The memory command has several suboptions, which are
+described below. It is only available when Tcl has been compiled with
+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.
+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
+\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.
+.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
+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 \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\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
+of memory activity before a problem occurs, judicious use of this option
+can reduce the slowdown caused by tracing (and the amount of trace information
+produced), if you can identify a number of allocations that occur before
+the problem sets in. The current number of memory allocations that have
+occurred since Tcl started is printed on a guard zone failure.
+.TP
+\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
+allocated by \fBckalloc\fR. This has a large performance impact and
+should only be used when overwrite problems are strongly suspected.
+The advantage of enabling memory validation is that a guard zone
+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
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/pkgs/msgcat/doc/msgcat.n b/pkgs/msgcat/doc/msgcat.n
new file mode 100644
index 0000000..d389757
--- /dev/null
+++ b/pkgs/msgcat/doc/msgcat.n
@@ -0,0 +1,355 @@
+'\"
+'\" Copyright (c) 1998 Mark Harrison.
+'\"
+'\" 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 "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.5\fR
+.sp
+\fBpackage require msgcat 1.4.2\fR
+.sp
+\fB::msgcat::mc \fIsrc-string\fR ?\fIarg arg ...\fR?
+.sp
+\fB::msgcat::mcmax ?\fIsrc-string src-string ...\fR?
+.sp
+\fB::msgcat::mclocale \fR?\fInewLocale\fR?
+.sp
+\fB::msgcat::mcpreferences\fR
+.sp
+\fB::msgcat::mcload \fIdirname\fR
+.sp
+\fB::msgcat::mcset \fIlocale src-string \fR?\fItranslate-string\fR?
+.sp
+\fB::msgcat::mcmset \fIlocale src-trans-list\fR
+.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
+.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
+the message catalog.
+.PP
+Use of the message catalog is optional by any application
+or package, but is encouraged if the application or package
+wishes to be enabled for multi-lingual applications.
+.SH COMMANDS
+.TP
+\fB::msgcat::mc \fIsrc-string\fR ?\fIarg arg ...\fR?
+.
+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
+none is found, it will search in the parent of the current namespace,
+and so on until it reaches the global namespace. If no translation
+string exists, \fB::msgcat::mcunknown\fR is called and the string
+returned from \fB::msgcat::mcunknown\fR is returned.
+.PP
+\fB::msgcat::mc\fR is the main function used to localize an
+application. Instead of using an English string directly, an
+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
+of the longest translated string. This is useful when designing
+localized GUIs, which may require that all buttons, for example, be a
+fixed width (which will be the width of the widest button).
+.TP
+\fB::msgcat::mclocale \fR?\fInewLocale\fR?
+.
+This function sets the locale to \fInewLocale\fR. If \fInewLocale\fR
+is omitted, the current locale is returned, otherwise the current locale
+is set to \fInewLocale\fR. msgcat stores and compares the locale in a
+case-insensitive manner, and returns locales in lowercase.
+The initial locale is determined by the locale specified in
+the user's environment. See \fBLOCALE SPECIFICATION\fR
+below for a description of the locale string format.
+.TP
+\fB::msgcat::mcpreferences\fR
+.
+Returns an ordered list of the locales preferred by
+the user, based on the user's language specification.
+The list is ordered from most specific to least
+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.
+.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
+.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
+encoded form, or by use of the backslash-u quoting recognized by Tcl
+evaluation. The number of message files which matched the specification
+and were loaded is returned.
+.TP
+\fB::msgcat::mcset \fIlocale src-string \fR?\fItranslate-string\fR?
+.
+Sets the translation for \fIsrc-string\fR to \fItranslate-string\fR
+in the specified \fIlocale\fR and the current namespace. If
+\fItranslate-string\fR is not specified, \fIsrc-string\fR is used
+for both. The function returns \fItranslate-string\fR.
+.TP
+\fB::msgcat::mcmset \fIlocale src-trans-list\fR
+.
+Sets the translation for multiple source strings in
+\fIsrc-trans-list\fR in the specified \fIlocale\fR and the current
+namespace.
+\fIsrc-trans-list\fR must have an even number of elements and is in
+the form {\fIsrc-string translate-string\fR ?\fIsrc-string
+translate-string ...\fR?} \fB::msgcat::mcmset\fR can be significantly
+faster than multiple invocations of \fB::msgcat::mcset\fR. The function
+returns the number of translations set.
+.TP
+\fB::msgcat::mcunknown \fIlocale src-string\fR
+.
+This routine is called by \fB::msgcat::mc\fR in the case when
+a translation for \fIsrc-string\fR is not defined in the
+current locale. The default action is to return
+\fIsrc-string\fR. This procedure can be redefined by the
+application, for example to log error messages for each unknown
+string. The \fB::msgcat::mcunknown\fR procedure is invoked at the
+same stack context as the call to \fB::msgcat::mc\fR. The return value
+of \fB::msgcat::mcunknown\fR is used as the return value for the call
+to \fB::msgcat::mc\fR.
+.SH "LOCALE SPECIFICATION"
+.PP
+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
+.QW _ .
+The country and language
+codes are specified in standards ISO-639 and ISO-3166.
+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,
+\fBenv(LC_MESSAGES)\fR, and \fBenv(LANG)\fR are examined in order.
+The first of them to have a non-empty value is used to determine the
+initial locale. The value is parsed according to the XPG4 pattern
+.PP
+.CS
+language[_country][.codeset][@modifier]
+.CE
+.PP
+to extract its parts. The initial locale is then set by calling
+\fB::msgcat::mclocale\fR with the argument
+.PP
+.CS
+language[_country][_modifier]
+.CE
+.PP
+On Windows, if none of those environment variables is set, msgcat will
+attempt to extract locale information from the
+registry. If all these attempts to discover an initial locale
+from the user's environment fail, msgcat defaults to an initial
+locale of
+.QW C .
+.PP
+When a locale is specified by the user, a
+.QW "best match"
+search is performed during string translation. For example, if a user
+specifies
+en_GB_Funky, the locales
+.QW en_GB_Funky ,
+.QW en_GB ,
+.QW en
+and
+.MT
+(the empty string)
+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
+to the namespace from which they were added. This allows
+multiple packages to use the same strings without fear
+of collisions with other packages. It also allows the
+source string to be shorter and less prone to typographical
+error.
+.PP
+For example, executing the code
+.PP
+.CS
+\fB::msgcat::mcset\fR en hello "hello from ::"
+namespace eval foo {
+ \fB::msgcat::mcset\fR en hello "hello from ::foo"
+}
+puts [\fB::msgcat::mc\fR hello]
+namespace eval foo {puts [\fB::msgcat::mc\fR hello]}
+.CE
+.PP
+will print
+.PP
+.CS
+hello from ::
+hello from ::foo
+.CE
+.PP
+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
+.QW inherit
+messages from their parent namespace.
+.PP
+For example, executing (in the
+.QW en
+locale) the code
+.PP
+.CS
+\fB::msgcat::mcset\fR en m1 ":: message1"
+\fB::msgcat::mcset\fR en m2 ":: message2"
+\fB::msgcat::mcset\fR en m3 ":: message3"
+namespace eval ::foo {
+ \fB::msgcat::mcset\fR en m2 "::foo message2"
+ \fB::msgcat::mcset\fR en m3 "::foo message3"
+}
+namespace eval ::foo::bar {
+ \fB::msgcat::mcset\fR en m3 "::foo::bar message3"
+}
+namespace import \fB::msgcat::mc\fR
+puts "[\fBmc\fR m1]; [\fBmc\fR m2]; [\fBmc\fR m3]"
+namespace eval ::foo {puts "[\fBmc\fR m1]; [\fBmc\fR m2]; [\fBmc\fR m3]"}
+namespace eval ::foo::bar {puts "[\fBmc\fR m1]; [\fBmc\fR m2]; [\fBmc\fR m3]"}
+.CE
+.PP
+will print
+.PP
+.CS
+:: message1; :: message2; :: message3
+:: message1; ::foo message2; ::foo message3
+:: message1; ::foo message2; ::foo::bar message3
+.CE
+.SH "LOCATION AND FORMAT OF MESSAGE FILES"
+.PP
+Message files can be located in any directory, subject
+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
+.QW .msg .
+For example:
+.PP
+.CS
+es.msg \(em spanish
+en_gb.msg \(em United Kingdom English
+.CE
+.PP
+\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.
+.IP [3]
+The file contains a series of calls to \fBmcset\fR and
+\fBmcmset\fR, setting the necessary translation strings
+for the language, likely enclosed in a \fBnamespace eval\fR
+so that all source strings are tied to the namespace of
+the package. For example, a short \fBes.msg\fR might contain:
+.PP
+.CS
+namespace eval ::mypackage {
+ \fB::msgcat::mcset\fR es "Free Beer!" "Cerveza Gracias!"
+}
+.CE
+.SH "RECOMMENDED MESSAGE SETUP FOR PACKAGES"
+.PP
+If a package is installed into a subdirectory of the
+\fBtcl_pkgPath\fR and loaded via \fBpackage require\fR, the
+following procedure is recommended.
+.IP [1]
+During package installation, create a subdirectory
+\fBmsgs\fR under your package directory.
+.IP [2]
+Copy your *.msg files into that directory.
+.IP [3]
+Add the following command to your package initialization script:
+.PP
+.CS
+# load language files, stored in msgs subdirectory
+\fB::msgcat::mcload\fR [file join [file dirname [info script]] msgs]
+.CE
+.SH "POSITIONAL CODES FOR FORMAT AND SCAN COMMANDS"
+.PP
+It is possible that a message string used as an argument
+to \fBformat\fR might have positionally dependent parameters that
+might need to be repositioned. For example, it might be
+syntactically desirable to rearrange the sentence structure
+while translating.
+.PP
+.CS
+format "We produced %d units in location %s" $num $city
+format "In location %s we produced %d units" $city $num
+.CE
+.PP
+This can be handled by using the positional
+parameters:
+.PP
+.CS
+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
+extract values from internationalized strings. Note that it is not
+necessary to pass the output of \fB::msgcat::mc\fR to \fBformat\fR
+directly; by passing the values to substitute in as arguments, the
+formatting substitution is done directly.
+.PP
+.CS
+\fBmsgcat::mc\fR {Produced %1$d at %2$s} $num $city
+# ... where that key is mapped to one of the
+# human-oriented versions by \fBmsgcat::mcset\fR
+.CE
+.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
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/pkgs/msgcat/doc/my.n b/pkgs/msgcat/doc/my.n
new file mode 100644
index 0000000..b5afc67
--- /dev/null
+++ b/pkgs/msgcat/doc/my.n
@@ -0,0 +1,56 @@
+'\"
+'\" Copyright (c) 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 my n 0.1 TclOO "TclOO Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+my \- invoke any method of current object
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBmy\fI methodName\fR ?\fIarg ...\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBmy\fR command is used to allow methods of objects to invoke any method
+of the object (or its class). In particular, the set of valid values for
+\fImethodName\fR is the set of all methods supported by an object and its
+superclasses, including those that are not exported. The object upon which the
+method is invoked is always the one that is the current context of the method
+(i.e. the object that is returned by \fBself object\fR) from which the
+\fBmy\fR command is invoked.
+.PP
+Each object has its own \fBmy\fR command, contained in its instance namespace.
+.SH EXAMPLES
+.PP
+This example shows basic use of \fBmy\fR to use the \fBvariables\fR method of
+the \fBoo::object\fR class, which is not publicly visible by default:
+.PP
+.CS
+oo::class create c {
+ method count {} {
+ \fBmy\fR variable counter
+ print [incr counter]
+ }
+}
+c create o
+o count \fI\(-> prints "1"\fR
+o count \fI\(-> prints "2"\fR
+o count \fI\(-> prints "3"\fR
+.CE
+.SH "SEE ALSO"
+next(n), oo::object(n), self(n)
+.SH KEYWORDS
+method, method visibility, object, private method, public method
+
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/pkgs/msgcat/doc/namespace.n b/pkgs/msgcat/doc/namespace.n
new file mode 100644
index 0000000..b06d27a
--- /dev/null
+++ b/pkgs/msgcat/doc/namespace.n
@@ -0,0 +1,969 @@
+'\"
+'\" 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.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?\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 \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
+namespace \fInamespace\fR.
+If \fInamespace\fR is not specified,
+then the children are returned for the current namespace.
+This command returns fully-qualified names,
+which start with a double colon (\fB::\fR).
+If the optional \fIpattern\fR is given,
+then this command returns only the names that match the glob-style pattern.
+The actual pattern used is determined as follows:
+a pattern that starts with double colon (\fB::\fR) is used directly,
+otherwise the namespace \fInamespace\fR
+(or the fully-qualified name of the current namespace)
+is prepended onto the pattern.
+.TP
+\fBnamespace code \fIscript\fR
+.
+Captures the current namespace context for later execution
+of the script \fIscript\fR.
+It returns a new script in which \fIscript\fR has been wrapped
+in a \fBnamespace inscope\fR command.
+The new script has two important properties.
+First, it can be evaluated in any namespace and will cause
+\fIscript\fR to be evaluated in the current namespace
+(the one where the \fBnamespace code\fR command was invoked).
+Second, additional arguments can be appended to the resulting script
+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 [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
+\fB::namespace eval ::a::b {foo bar x y}\fR.
+This command is needed because
+extensions like Tk normally execute callback scripts
+in the global namespace.
+A scoped command captures a command together with its namespace context
+in a way that allows it to be executed properly later.
+See the section \fBSCOPED SCRIPTS\fR for some examples
+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
+.MT
+(i.e., an empty string),
+but this command returns \fB::\fR for the global namespace
+as a convenience to programmers.
+.TP
+\fBnamespace delete \fR?\fInamespace namespace ...\fR?
+.
+Each namespace \fInamespace\fR is deleted
+and all variables, procedures, and child namespaces
+contained in the namespace are deleted.
+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 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?
+.
+Creates and manipulates a command that is formed out of an ensemble of
+subcommands. See the section \fBENSEMBLES\fR below for further
+details.
+.TP
+\fBnamespace eval\fR \fInamespace arg\fR ?\fIarg ...\fR?
+.
+Activates a namespace called \fInamespace\fR and evaluates some code
+in that context.
+If the namespace does not already exist, it is created.
+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.
+.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
+context, returns \fB0\fR otherwise.
+.TP
+\fBnamespace export \fR?\fB\-clear\fR? ?\fIpattern pattern ...\fR?
+.
+Specifies which commands are exported from a namespace.
+The exported commands are those that can be later imported
+into another namespace using a \fBnamespace import\fR command.
+Both commands defined in a namespace and
+commands the namespace has previously imported
+can be exported by a namespace.
+The commands do not have to be defined
+at the time the \fBnamespace export\fR command is executed.
+Each \fIpattern\fR may contain glob-style special characters,
+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 \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 \fB\-clear\fR flag is not given,
+this command returns the namespace's current export list.
+.TP
+\fBnamespace forget \fR?\fIpattern pattern ...\fR?
+.
+Removes previously imported commands from a namespace.
+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
+.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
+.QW "simple pattern"
+this command deletes the matching commands of the
+current namespace that were imported from a different namespace.
+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.
+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, 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).
+.RS
+.PP
+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
+at the end of the qualified name.
+Glob characters may not appear in a namespace name.
+When the namespace name is not fully qualified (i.e., does not start
+with a namespace separator) it is resolved as a namespace name in the
+way described in the \fBNAME RESOLUTION\fR section; it is an error if
+no namespace with that name can be found.
+.PP
+All the commands that match a \fIpattern\fR string
+and which are currently exported from their namespace
+are added to the current namespace.
+This is done by creating a new command in the current namespace
+that points to the exported command in its original namespace;
+when the new imported command is called, it invokes the exported command.
+This command normally returns an error
+if an imported command conflicts with an existing command.
+However, if the \fB\-force\fR option is given,
+imported commands will silently replace existing commands.
+The \fBnamespace import\fR command has snapshot semantics:
+that is, only requested commands that are currently defined
+in the exporting namespace are imported.
+In other words, you can import only the commands that are in a namespace
+at the time when the \fBnamespace import\fR command is executed.
+If another command is defined and exported in this namespace later on,
+it will not be imported.
+.RE
+.TP
+\fBnamespace inscope\fR \fInamespace\fR \fIscript\fR ?\fIarg ...\fR?
+.
+Executes a script in the context of the specified \fInamespace\fR.
+This command is not expected to be used directly by programmers;
+calls to it are generated implicitly when applications
+use \fBnamespace code\fR commands to create callback scripts
+that the applications then register with, e.g., Tk widgets.
+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.
+.RS
+.PP
+.CS
+\fBnamespace inscope ::foo $script $x $y $z\fR
+.CE
+.PP
+is equivalent to
+.PP
+.CS
+\fBnamespace eval ::foo [concat $script [list $x $y $z]]\fR
+.CE
+.PP
+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
+to which the imported command \fIcommand\fR refers.
+When a command is imported into a namespace,
+a new command is created in that namespace
+that points to the actual command in the exporting namespace.
+If a command is imported into a sequence of namespaces
+\fIa, b,...,n\fR where each successive namespace
+just imports the command from the previous namespace,
+this command returns the fully-qualified name of the original command
+in the first namespace, \fIa\fR.
+If \fIcommand\fR does not refer to an imported command,
+the command's own fully-qualified name is returned.
+.TP
+\fBnamespace parent\fR ?\fInamespace\fR?
+.
+Returns the fully-qualified name of the parent namespace
+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?
+.
+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.
+.TP
+\fBnamespace qualifiers\fR \fIstring\fR
+.
+Returns any leading namespace qualifiers for \fIstring\fR.
+Qualifiers are namespace names separated by double colons (\fB::\fR).
+For the \fIstring\fR \fB::foo::bar::x\fR,
+this command returns \fB::foo::bar\fR,
+and for \fB::\fR it returns an empty string.
+This command is the complement of the \fBnamespace tail\fR command.
+Note that it does not check whether the
+namespace names are, in fact,
+the names of currently defined namespaces.
+.TP
+\fBnamespace tail\fR \fIstring\fR
+.
+Returns the simple name at the end of a qualified string.
+Qualifiers are namespace names separated by double colons (\fB::\fR).
+For the \fIstring\fR \fB::foo::bar::x\fR,
+this command returns \fBx\fR,
+and for \fB::\fR it returns an empty string.
+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...
+.
+This command arranges for zero 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 the current namespace, the namespace's path nor in
+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 ?\fB\-command\fR? ?\fB\-variable\fR? \fIname\fR
+.
+Looks up \fIname\fR as either a command or variable
+and returns its fully-qualified name.
+For example, if \fIname\fR does not exist in the current namespace
+but does exist in the global namespace,
+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
+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
+the rules regarding name resolution.
+.SH "WHAT IS A NAMESPACE?"
+.PP
+A namespace is a collection of commands and variables.
+It encapsulates the commands and variables to ensure that they
+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.
+The \fBnamespace eval\fR command lets you create new namespaces.
+For example,
+.PP
+.CS
+\fBnamespace eval\fR Counter {
+ \fBnamespace export\fR bump
+ variable num 0
+
+ proc bump {} {
+ variable num
+ incr num
+ }
+}
+.CE
+.PP
+creates a new namespace containing the variable \fBnum\fR and
+the procedure \fBbump\fR.
+The commands and variables in this namespace are separate from
+other commands and variables in the same program.
+If there is a command named \fBbump\fR in the global namespace,
+for example, it will be different from the command \fBbump\fR
+in the \fBCounter\fR namespace.
+.PP
+Namespace variables resemble global variables in Tcl.
+They exist outside of the procedures in a namespace
+but can be accessed in a procedure via the \fBvariable\fR command,
+as shown in the example above.
+.PP
+Namespaces are dynamic.
+You can add and delete commands and variables at any time,
+so you can build up the contents of a
+namespace over time using a series of \fBnamespace eval\fR commands.
+For example, the following series of commands has the same effect
+as the namespace definition shown above:
+.PP
+.CS
+\fBnamespace eval\fR Counter {
+ variable num 0
+ proc bump {} {
+ variable num
+ return [incr num]
+ }
+}
+\fBnamespace eval\fR Counter {
+ proc test {args} {
+ return $args
+ }
+}
+\fBnamespace eval\fR Counter {
+ rename test ""
+}
+.CE
+.PP
+Note that the \fBtest\fR procedure is added to the \fBCounter\fR namespace,
+and later removed via the \fBrename\fR command.
+.PP
+Namespaces can have other namespaces within them,
+so they nest hierarchically.
+A nested namespace is encapsulated inside its parent namespace
+and can not interfere with other namespaces.
+.SH "QUALIFIED NAMES"
+.PP
+Each namespace has a textual name such as
+\fBhistory\fR or \fB::safe::interp\fR.
+Since namespaces may nest,
+qualified names are used to refer to
+commands, variables, and child namespaces contained inside namespaces.
+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
+.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,
+which in turn is a child of the global namespace, \fB::\fR.
+.PP
+If you want to access commands and variables from another namespace,
+you must use some extra syntax.
+Names must be qualified by the namespace that contains them.
+From the global namespace,
+we might access the \fBCounter\fR procedures like this:
+.PP
+.CS
+Counter::bump 5
+Counter::Reset
+.CE
+.PP
+We could access the current count like this:
+.PP
+.CS
+puts "count = $Counter::num"
+.CE
+.PP
+When one namespace contains another, you may need more than one
+qualifier to reach its elements.
+If we had a namespace \fBFoo\fR that contained the namespace \fBCounter\fR,
+you could invoke its \fBbump\fR procedure
+from the global namespace like this:
+.PP
+.CS
+Foo::Counter::bump 3
+.CE
+.PP
+You can also use qualified names when you create and rename commands.
+For example, you could add a procedure to the \fBFoo\fR
+namespace like this:
+.PP
+.CS
+proc Foo::Test {args} {return $args}
+.CE
+.PP
+And you could move the same procedure to another namespace like this:
+.PP
+.CS
+rename Foo::Test Bar::Test
+.CE
+.PP
+There are a few remaining points about qualified names
+that we should cover.
+Namespaces have nonempty names except for the global namespace.
+\fB::\fR is disallowed in simple command, variable, and namespace names
+except as a namespace separator.
+Extra colons in any separator part of a qualified name are ignored;
+i.e. two or more colons are treated as a namespace separator.
+A trailing \fB::\fR in a qualified variable or command name
+refers to the variable or command named {}.
+However, a trailing \fB::\fR in a qualified namespace name is ignored.
+.SH "NAME RESOLUTION"
+.PP
+In general, all Tcl commands that take variable and command names
+support qualified names.
+This means you can give qualified names to such commands as
+\fBset\fR, \fBproc\fR, \fBrename\fR, and \fBinterp alias\fR.
+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 basic rules for looking it up:
+.IP \(bu
+\fBVariable names\fR are always resolved by looking first in the current
+namespace, and then in the global namespace.
+.IP \(bu
+\fBCommand names\fR are 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 appropriate \fBnamespace unknown\fR handler.)
+.IP \(bu
+\fBNamespace names\fR are always resolved by looking in only the current
+namespace.
+.PP
+In the following example,
+.PP
+.CS
+set traceLevel 0
+\fBnamespace eval\fR Debug {
+ printTrace $traceLevel
+}
+.CE
+.PP
+Tcl looks for \fBtraceLevel\fR in the namespace \fBDebug\fR
+and then in the global namespace.
+It looks up the command \fBprintTrace\fR in the same way.
+If a variable or command name is not found in either context,
+the name is undefined.
+To make this point absolutely clear, consider the following example:
+.PP
+.CS
+set traceLevel 0
+\fBnamespace eval\fR Foo {
+ variable traceLevel 3
+
+ \fBnamespace eval\fR Debug {
+ printTrace $traceLevel
+ }
+}
+.CE
+.PP
+Here Tcl looks for \fBtraceLevel\fR first in the namespace \fBFoo::Debug\fR.
+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.
+.PP
+You can use the \fBnamespace which\fR command to clear up any question
+about name resolution.
+For example, the command:
+.PP
+.CS
+\fBnamespace eval\fR Foo::Debug {\fBnamespace which\fR \-variable traceLevel}
+.CE
+.PP
+returns \fB::traceLevel\fR.
+On the other hand, the command,
+.PP
+.CS
+\fBnamespace eval\fR Foo {\fBnamespace which\fR \-variable traceLevel}
+.CE
+.PP
+returns \fB::Foo::traceLevel\fR.
+.PP
+As mentioned above,
+namespace names are looked up differently
+than the names of variables and commands.
+Namespace names are always resolved in the current namespace.
+This means, for example,
+that a \fBnamespace eval\fR command that creates a new namespace
+always creates a child of the current namespace
+unless the new namespace name begins with \fB::\fR.
+.PP
+Tcl has no access control to limit what variables, commands,
+or namespaces you can reference.
+If you provide a qualified name that resolves to an element
+by the name resolution rule above,
+you can access the element.
+.PP
+You can access a namespace variable
+from a procedure in the same namespace
+by using the \fBvariable\fR command.
+Much like the \fBglobal\fR command,
+this creates a local link to the namespace variable.
+If necessary, it also creates the variable in the current namespace
+and initializes it.
+Note that the \fBglobal\fR command only creates links
+to variables in the global namespace.
+It is not necessary to use a \fBvariable\fR command
+if you always refer to the namespace variable using an
+appropriate qualified name.
+.SH "IMPORTING COMMANDS"
+.PP
+Namespaces are often used to represent libraries.
+Some library commands are used so frequently
+that it is a nuisance to type their qualified names.
+For example, suppose that all of the commands in a package
+like BLT are contained in a namespace called \fBBlt\fR.
+Then you might access these commands like this:
+.PP
+.CS
+Blt::graph .g \-background red
+Blt::table . .g 0,0
+.CE
+.PP
+If you use the \fBgraph\fR and \fBtable\fR commands frequently,
+you may want to access them without the \fBBlt::\fR prefix.
+You can do this by importing the commands into the current namespace,
+like this:
+.PP
+.CS
+\fBnamespace import\fR Blt::*
+.CE
+.PP
+This adds all exported commands from the \fBBlt\fR namespace
+into the current namespace context, so you can write code like this:
+.PP
+.CS
+graph .g \-background red
+table . .g 0,0
+.CE
+.PP
+The \fBnamespace import\fR command only imports commands
+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 do not know what you will get.
+It is better to import just the specific commands you need.
+For example, the command
+.PP
+.CS
+\fBnamespace import\fR Blt::graph Blt::table
+.CE
+.PP
+imports only the \fBgraph\fR and \fBtable\fR commands into the
+current context.
+.PP
+If you try to import a command that already exists, you will get an
+error. This prevents you from importing the same command from two
+different packages. But from time to time (perhaps when debugging),
+you may want to get around this restriction. You may want to
+reissue the \fBnamespace import\fR command to pick up new commands
+that have appeared in a namespace. In that case, you can use the
+\fB\-force\fR option, and existing commands will be silently overwritten:
+.PP
+.CS
+\fBnamespace import\fR \-force Blt::graph Blt::table
+.CE
+.PP
+If for some reason, you want to stop using the imported commands,
+you can remove them with a \fBnamespace forget\fR command, like this:
+.PP
+.CS
+\fBnamespace forget\fR Blt::*
+.CE
+.PP
+This searches the current namespace for any commands imported from \fBBlt\fR.
+If it finds any, it removes them. Otherwise, it does nothing.
+After this, the \fBBlt\fR commands must be accessed with the \fBBlt::\fR
+prefix.
+.PP
+When you delete a command from the exporting namespace like this:
+.PP
+.CS
+rename Blt::graph ""
+.CE
+.PP
+the command is automatically removed from all namespaces that import it.
+.SH "EXPORTING COMMANDS"
+You can export commands from a namespace like this:
+.PP
+.CS
+\fBnamespace eval\fR Counter {
+ \fBnamespace export\fR bump reset
+ variable Num 0
+ variable Max 100
+
+ proc bump {{by 1}} {
+ variable Num
+ incr Num $by
+ Check
+ return $Num
+ }
+ proc reset {} {
+ variable Num
+ set Num 0
+ }
+ proc Check {} {
+ variable Num
+ variable Max
+ if {$Num > $Max} {
+ error "too high!"
+ }
+ }
+}
+.CE
+.PP
+The procedures \fBbump\fR and \fBreset\fR are exported,
+so they are included when you import from the \fBCounter\fR namespace,
+like this:
+.PP
+.CS
+\fBnamespace import\fR Counter::*
+.CE
+.PP
+However, the \fBCheck\fR procedure is not exported,
+so it is ignored by the import operation.
+.PP
+The \fBnamespace import\fR command only imports commands
+that were declared as exported by their namespace.
+The \fBnamespace export\fR command specifies what commands
+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 \fBtrace\fR callback into the current
+namespace:
+.PP
+.CS
+\fBnamespace eval\fR a {
+ variable b
+ proc theTraceCallback { n1 n2 op } {
+ upvar 1 $n1 var
+ puts "the value of $n1 has changed to $var"
+ return
+ }
+ 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
+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); if the first word of any target is not
+fully qualified when set, it is assumed to be relative to the
+\fIcurrent\fR namespace and changed to be exactly that (that is, it is
+always fully qualified when read). When this option is empty, the mapping
+will be from the local name of the subcommand to its fully-qualified
+name. Note that when this option is non-empty and the
+\fB\-subcommands\fR option is empty, the ensemble subcommand names
+will be exactly those words that have mappings in the dictionary.
+.TP
+\fB\-parameters\fR
+.VS 8.6
+This option gives a list of named arguments (the names being used during
+generation of error messages) that are passed by the caller of the ensemble
+between the name of the ensemble and the subcommand argument. By default, it
+is the empty list.
+.VE 8.6
+.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.
+.SH EXAMPLES
+Create a namespace containing a variable and an exported command:
+.PP
+.CS
+\fBnamespace eval\fR foo {
+ variable bar 0
+ proc grill {} {
+ variable bar
+ puts "called [incr bar] times"
+ }
+ \fBnamespace export\fR grill
+}
+.CE
+.PP
+Call the command defined in the previous example in various ways.
+.PP
+.CS
+# Direct call
+::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
+\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:
+.PP
+.CS
+puts "grill came from [\fBnamespace origin\fR grill]"
+.CE
+.PP
+Remove all imported commands from the current namespace:
+.PP
+.CS
+namespace forget {*}[namespace import]
+.CE
+.PP
+.VS 8.6
+Create an ensemble for simple working with numbers, using the
+\fB\-parameters\fR option to allow the operator to be put between the first
+and second arguments.
+.PP
+.CS
+\fBnamespace eval\fR do {
+ \fBnamespace export\fR *
+ \fBnamespace ensemble\fR create -parameters x
+ proc plus {x y} {expr { $x + $y }}
+ proc minus {x y} {expr { $x - $y }}
+}
+
+# In use, the ensemble works like this:
+puts [do 1 plus [do 9 minus 7]]
+.CE
+.VE 8.6
+.SH "SEE ALSO"
+interp(n), upvar(n), variable(n)
+.SH KEYWORDS
+command, ensemble, exported, internal, variable
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/next.n b/pkgs/msgcat/doc/next.n
new file mode 100644
index 0000000..d3f7937
--- /dev/null
+++ b/pkgs/msgcat/doc/next.n
@@ -0,0 +1,203 @@
+'\"
+'\" Copyright (c) 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 next n 0.1 TclOO "TclOO Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+next \- invoke superclass method implementations
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBnext\fR ?\fIarg ...\fR?
+\fBnextto\fI class\fR ?\fIarg ...\fR?
+.fi
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBnext\fR command is used to call implementations of a method by a class,
+superclass or mixin that are overridden by the current method. It can only be
+used from within a method. It is also used within filters to indicate the
+point where a filter calls the actual implementation (the filter may decide to
+not go along the chain, and may process the results of going along the chain
+of methods as it chooses). The result of the \fBnext\fR command is the result
+of the next method in the method chain; if there are no further methods in the
+method chain, the result of \fBnext\fR will be an error. The arguments,
+\fIarg\fR, to \fBnext\fR are the arguments to pass to the next method in the
+chain.
+.PP
+The \fBnextto\fR command is the same as the \fBnext\fR command, except that it
+takes an additional \fIclass\fR argument that identifies a class whose
+implementation of the current method chain (see \fBinfo object\fR \fBcall\fR) should
+be used; the method implementation selected will be the one provided by the
+given class, and it must refer to an existing non-filter invocation that lies
+further along the chain than the current implementation.
+.SH "THE METHOD CHAIN"
+.PP
+When a method of an object is invoked, things happen in several stages:
+.IP [1]
+The structure of the object, its class, superclasses, filters, and mixins, are
+examined to build a \fImethod chain\fR, which contains a list of method
+implementations to invoke.
+.IP [2]
+The first method implementation on the chain is invoked.
+.IP [3]
+If that method implementation invokes the \fBnext\fR command, the next method
+implementation is invoked (with its arguments being those that were passed to
+\fBnext\fR).
+.IP [4]
+The result from the overall method call is the result from the outermost
+method implementation; inner method implementations return their results
+through \fBnext\fR.
+.IP [5]
+The method chain is cached for future use.
+.SS "METHOD SEARCH ORDER"
+.PP
+When constructing the method chain, method implementations are searched for in
+the following order:
+.IP [1]
+In the object.
+.IP [2]
+In the classes mixed into the object, in class traversal order. The list of
+mixins is checked in natural order.
+.IP [3]
+In the classes mixed into the classes of the object, with sources of mixing in
+being searched in class traversal order. Within each class, the list of mixins
+is processed in natural order.
+.IP [4]
+In the object's class.
+.IP [5]
+In the superclasses of the class, following each superclass in a depth-first
+fashion in the natural order of the superclass list.
+.PP
+Any particular method implementation always comes as \fIlate\fR in the
+resulting list of implementations as possible.
+.SS FILTERS
+.PP
+When an object has a list of filter names set upon it, or is an instance of a
+class (or has mixed in a class) that has a list of filter names set upon it,
+before every invocation of any method the filters are processed. Filter
+implementations are found in class traversal order, as are the lists of filter
+names (each of which is traversed in natural list order). Explicitly invoking
+a method used as a filter will cause that method to be invoked twice, once as
+a filter and once as a normal method.
+.PP
+Each filter should decide for itself whether to permit the execution to go
+forward to the proper implementation of the method (which it does by invoking
+the \fBnext\fR command as filters are inserted into the front of the method
+call chain) and is responsible for returning the result of \fBnext\fR.
+.PP
+Filters are not invoked when processing an invocation of the \fBunknown\fR
+method because of a failure to locate a method implementation, or when
+invoking either constructors or destructors.
+.SH EXAMPLES
+.PP
+This example demonstrates how to use the \fBnext\fR command to call the
+(super)class's implementation of a method. The script:
+.PP
+.CS
+oo::class create theSuperclass {
+ method example {args} {
+ puts "in the superclass, args = $args"
+ }
+}
+oo::class create theSubclass {
+ superclass theSuperclass
+ method example {args} {
+ puts "before chaining from subclass, args = $args"
+ \fBnext\fR a {*}$args b
+ \fBnext\fR pureSynthesis
+ puts "after chaining from subclass"
+ }
+}
+theSubclass create obj
+oo::define obj method example args {
+ puts "per-object method, args = $args"
+ \fBnext\fR x {*}$args y
+ \fBnext\fR
+}
+obj example 1 2 3
+.CE
+.PP
+prints the following:
+.PP
+.CS
+per-object method, args = 1 2 3
+before chaining from subclass, args = x 1 2 3 y
+in the superclass, args = a x 1 2 3 y b
+in the superclass, args = pureSynthesis
+after chaining from subclass
+before chaining from subclass, args =
+in the superclass, args = a b
+in the superclass, args = pureSynthesis
+after chaining from subclass
+.CE
+.PP
+This example demonstrates how to build a simple cache class that applies
+memoization to all the method calls of the objects it is mixed into, and shows
+how it can make a difference to computation times:
+.PP
+.CS
+oo::class create cache {
+ filter Memoize
+ method Memoize args {
+ \fI# Do not filter the core method implementations\fR
+ if {[lindex [self target] 0] eq "::oo::object"} {
+ return [\fBnext\fR {*}$args]
+ }
+
+ \fI# Check if the value is already in the cache\fR
+ my variable ValueCache
+ set key [self target],$args
+ if {[info exist ValueCache($key)]} {
+ return $ValueCache($key)
+ }
+
+ \fI# Compute value, insert into cache, and return it\fR
+ return [set ValueCache($key) [\fBnext\fR {*}$args]]
+ }
+ method flushCache {} {
+ my variable ValueCache
+ unset ValueCache
+ \fI# Skip the caching\fR
+ return -level 2 ""
+ }
+}
+
+oo::object create demo
+oo::define demo {
+ mixin cache
+ method compute {a b c} {
+ after 3000 \fI;# Simulate deep thought\fR
+ return [expr {$a + $b * $c}]
+ }
+ method compute2 {a b c} {
+ after 3000 \fI;# Simulate deep thought\fR
+ return [expr {$a * $b + $c}]
+ }
+}
+
+puts [demo compute 1 2 3] \fI\(-> prints "7" after delay\fR
+puts [demo compute2 4 5 6] \fI\(-> prints "26" after delay\fR
+puts [demo compute 1 2 3] \fI\(-> prints "7" instantly\fR
+puts [demo compute2 4 5 6] \fI\(-> prints "26" instantly\fR
+puts [demo compute 4 5 6] \fI\(-> prints "34" after delay\fR
+puts [demo compute 4 5 6] \fI\(-> prints "34" instantly\fR
+puts [demo compute 1 2 3] \fI\(-> prints "7" instantly\fR
+demo flushCache
+puts [demo compute 1 2 3] \fI\(-> prints "7" after delay\fR
+.CE
+.SH "SEE ALSO"
+oo::class(n), oo::define(n), oo::object(n), self(n)
+.SH KEYWORDS
+call, method, method chain
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/pkgs/msgcat/doc/object.n b/pkgs/msgcat/doc/object.n
new file mode 100644
index 0000000..6737e7e
--- /dev/null
+++ b/pkgs/msgcat/doc/object.n
@@ -0,0 +1,128 @@
+'\"
+'\" Copyright (c) 2007-2008 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 object n 0.1 TclOO "TclOO Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+oo::object \- root class of the class hierarchy
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBoo::object\fI method \fR?\fIarg ...\fR?
+.fi
+.SH "CLASS HIERARCHY"
+.nf
+\fBoo::object\fR
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBoo::object\fR class is the root class of the object hierarchy; every
+object is an instance of this class. Since classes are themselves objects,
+they are instances of this class too. Objects are always referred to by their
+name, and may be \fBrename\fRd while maintaining their identity.
+.PP
+Instances of objects may be made with either the \fBcreate\fR or \fBnew\fR
+methods of the \fBoo::object\fR object itself, or by invoking those methods on
+any of the subclass objects; see \fBoo::class\fR for more details. The
+configuration of individual objects (i.e., instance-specific methods, mixed-in
+classes, etc.) may be controlled with the \fBoo::objdefine\fR command.
+.PP
+Each object has a unique namespace associated with it, the instance namespace.
+This namespace holds all the instance variables of the object, and will be the
+current namespace whenever a method of the object is invoked (including a
+method of the class of the object). When the object is destroyed, its instance
+namespace is deleted. The instance namespace contains the object's \fBmy\fR
+command, which may be used to invoke non-exported methods of the object or to
+create a reference to the object for the purpose of invocation which persists
+across renamings of the object.
+.SS CONSTRUCTOR
+The \fBoo::object\fR class does not define an explicit constructor.
+.SS DESTRUCTOR
+The \fBoo::object\fR class does not define an explicit destructor.
+.SS "EXPORTED METHODS"
+The \fBoo::object\fR class supports the following exported methods:
+.TP
+\fIobj \fBdestroy\fR
+.
+This method destroys the object, \fIobj\fR, that it is invoked upon, invoking
+any destructors on the object's class in the process. It is equivalent to
+using \fBrename\fR to delete the object command. The result of this method is
+always the empty string.
+.SS "NON-EXPORTED METHODS"
+.PP
+The \fBoo::object\fR class supports the following non-exported methods:
+.TP
+\fIobj \fBeval\fR ?\fIarg ...\fR?
+.
+This method concatenates the arguments, \fIarg\fR, as if with \fBconcat\fR,
+and then evaluates the resulting script in the namespace that is uniquely
+associated with \fIobj\fR, returning the result of the evaluation.
+.TP
+\fIobj \fBunknown ?\fImethodName\fR? ?\fIarg ...\fR?
+.
+This method is called when an attempt to invoke the method \fImethodName\fR on
+object \fIobj\fR fails. The arguments that the user supplied to the method are
+given as \fIarg\fR arguments.
+.VS
+If \fImethodName\fR is absent, the object was invoked with no method name at
+all (or any other arguments).
+.VE
+The default implementation (i.e., the one defined by the \fBoo::object\fR
+class) generates a suitable error, detailing what methods the object supports
+given whether the object was invoked by its public name or through the
+\fBmy\fR command.
+.TP
+\fIobj \fBvariable \fR?\fIvarName ...\fR?
+.
+This method arranges for each variable called \fIvarName\fR to be linked from
+the object \fIobj\fR's unique namespace into the caller's context. Thus, if it
+is invoked from inside a procedure then the namespace variable in the object
+is linked to the local variable in the procedure. Each \fIvarName\fR argument
+must not have any namespace separators in it. The result is the empty string.
+.TP
+\fIobj \fBvarname \fIvarName\fR
+.
+This method returns the globally qualified name of the variable \fIvarName\fR
+in the unique namespace for the object \fIobj\fR.
+.TP
+\fIobj \fB<cloned> \fIsourceObjectName\fR
+.VS
+This method is used by the \fBoo::object\fR command to copy the state of one
+object to another. It is responsible for copying the procedures and variables
+of the namespace of the source object (\fIsourceObjectName\fR) to the current
+object. It does not copy any other types of commands or any traces on the
+variables; that can be added if desired by overriding this method in a
+subclass.
+.VE
+.SH EXAMPLES
+.PP
+This example demonstrates basic use of an object.
+.PP
+.CS
+set obj [\fBoo::object\fR new]
+$obj foo \fI\(-> error "unknown method foo"\fR
+oo::objdefine $obj method foo {} {
+ my \fBvariable\fR count
+ puts "bar[incr count]"
+}
+$obj foo \fI\(-> prints "bar1"\fR
+$obj foo \fI\(-> prints "bar2"\fR
+$obj variable count \fI\(-> error "unknown method variable"\fR
+$obj \fBdestroy\fR
+$obj foo \fI\(-> error "unknown command obj"\fR
+.CE
+.SH "SEE ALSO"
+my(n), oo::class(n)
+.SH KEYWORDS
+base class, class, object, root class
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/pkgs/msgcat/doc/open.n b/pkgs/msgcat/doc/open.n
new file mode 100644
index 0000000..d4842f2
--- /dev/null
+++ b/pkgs/msgcat/doc/open.n
@@ -0,0 +1,465 @@
+'\"
+'\" 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 open n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+open \- Open a file-based or command pipeline channel
+.SH SYNOPSIS
+.sp
+\fBopen \fIfileName\fR
+.br
+\fBopen \fIfileName access\fR
+.br
+\fBopen \fIfileName access permissions\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command opens a file, serial port, or command pipeline and returns a
+channel identifier that may be used in future invocations of commands like
+\fBread\fR, \fBputs\fR, and \fBclose\fR.
+If the first character of \fIfileName\fR is not \fB|\fR then
+the command opens a file:
+\fIfileName\fR gives the name of the file to open, and it must conform to the
+conventions described in the \fBfilename\fR manual entry.
+.PP
+The \fIaccess\fR argument, if present, indicates the way in which the file
+(or command pipeline) is to be accessed.
+In the first form \fIaccess\fR may have any of the following values:
+.TP 15
+\fBr\fR
+.
+Open the file for reading only; the file must already exist. This is the
+default value if \fIaccess\fR is not specified.
+.TP 15
+\fBr+\fR
+.
+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 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 does not exist, create a new file.
+.TP 15
+\fBa\fR
+.
+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 does not exist,
+create a new empty file.
+Set the initial access position to the end of the file.
+.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 as if with the
+\fBfconfigure\fR \fB\-translation binary\fR option, making the channel suitable for
+reading or writing of binary data.
+.PP
+In the second form, \fIaccess\fR consists of a list of any of the
+following flags, all of which have the standard POSIX meanings.
+One of the flags must be either \fBRDONLY\fR, \fBWRONLY\fR or \fBRDWR\fR.
+.TP 15
+\fBRDONLY\fR
+.
+Open the file for reading only.
+.TP 15
+\fBWRONLY\fR
+.
+Open the file for writing only.
+.TP 15
+\fBRDWR\fR
+.
+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.
+.TP 15
+\fBBINARY\fR
+.
+Configure the opened channel with the \fB\-translation binary\fR option.
+.TP 15
+\fBCREAT\fR
+.
+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
+.
+If \fBCREAT\fR is also specified, an error is returned if the
+file already exists.
+.TP 15
+\fBNOCTTY\fR
+.
+If the file is a terminal device, this flag prevents the file from
+becoming the controlling terminal of the process.
+.TP 15
+\fBNONBLOCK\fR
+.
+Prevents the process from blocking while opening the file, and
+possibly in subsequent I/O operations. The exact behavior of
+this flag is system- and device-dependent; its use is discouraged
+(it is better to use the \fBfconfigure\fR command to put a file
+in nonblocking mode).
+For details refer to your system documentation on the \fBopen\fR system
+call's \fBO_NONBLOCK\fR flag.
+.TP 15
+\fBTRUNC\fR
+.
+If the file exists it is truncated to zero length.
+.PP
+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.
+.SH "COMMAND PIPELINES"
+.PP
+If the first character of \fIfileName\fR is
+.QW \fB|\fR
+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.
+In this case, the channel identifier returned by \fBopen\fR may be used
+to write to the command's input pipe or read from its output pipe,
+depending on the value of \fIaccess\fR.
+If write-only access is used (e.g. \fIaccess\fR is
+.QW \fBw\fR ),
+then standard output for the pipeline is directed to the current standard
+output unless overridden by the command.
+If read-only access is used (e.g. \fIaccess\fR is
+.QW \fBr\fR ),
+standard input for the pipeline is taken from the current standard
+input unless overridden by the command.
+The id of the spawned process is accessible through the \fBpid\fR
+command, using the channel id returned by \fBopen\fR as argument.
+.PP
+If the command (or one of the commands) executed in the command
+pipeline returns an error (according to the definition in \fBexec\fR),
+a Tcl error is generated when \fBclose\fR is called on the channel
+unless the pipeline is in non-blocking mode then no exit status is
+returned (a silent \fBclose\fR with -blocking 0).
+.PP
+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.
+.SH "SERIAL COMMUNICATIONS"
+.PP
+If \fIfileName\fR refers to a serial port, then the specified serial port
+is opened and initialized in a platform-dependent manner. Acceptable
+values for the \fIfileName\fR to use to open a serial port are described in
+the PORTABILITY ISSUES section.
+.PP
+The \fBfconfigure\fR command can be used to query and set additional
+configuration options specific to serial ports (where supported):
+.TP
+\fB\-mode\fR \fIbaud\fB,\fIparity\fB,\fIdata\fB,\fIstop\fR
+.
+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
+.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
+\fB\-handshake\fR \fItype\fR
+.
+(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.
+.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.
+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.
+.RE
+.TP
+\fB\-queue\fR
+.
+(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
+\fB\-timeout\fR \fImsec\fR
+.
+(Windows and Unix). This option is used to set the timeout for blocking
+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
+nonblocking reads.
+This option cannot be queried.
+.TP
+\fB\-ttycontrol\fR \fI{signal boolean signal boolean ...}\fR
+.
+(Windows and Unix). This option is used to setup the handshake
+output lines (see below) permanently or to send a BREAK over the serial line.
+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 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.
+.TP
+\fB\-ttystatus\fR
+.
+(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,
+e.g. \fB{CTS 1 DSR 0 RING 1 DCD 0}\fR.
+The \fIsignal\fR names are returned upper case.
+.TP
+\fB\-xchar\fR \fI{xonChar xoffChar}\fR
+.
+(Windows and Unix). This option is used to query or change the software
+handshake characters. Normally the operating system default should be
+DC1 (0x11) and DC3 (0x13) representing the ASCII standard
+XON and XOFF characters.
+.TP
+\fB\-pollinterval\fR \fImsec\fR
+.
+(Windows only). This option is used to set the maximum time between
+polling for fileevents.
+This affects the time interval between checking for events throughout the Tcl
+interpreter (the smallest value always wins). Use this option only if
+you want to poll the serial port more or less often than 10 msec
+(the default).
+.TP
+\fB\-sysbuffer\fR \fIinSize\fR
+.TP
+\fB\-sysbuffer\fR \fI{inSize outSize}\fR
+.
+(Windows only). This option is used to change the size of Windows
+system buffers for a serial channel. Especially at higher communication
+rates the default input buffer size of 4096 bytes can overrun
+for latent systems. The first form specifies the input buffer size,
+in the second form both input and output buffers are defined.
+.TP
+\fB\-lasterror\fR
+.
+(Windows only). This option is query only.
+In case of a serial communication error, \fBread\fR or \fBputs\fR
+returns a general Tcl file I/O error.
+\fBfconfigure\fR \fB\-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
+communications. A negative voltage (-3V..-12V) define a mark (on=1) bit and
+a positive voltage (+3..+12V) define a space (off=0) bit (RS-232C). The
+following signals are specified for incoming and outgoing data, status
+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\fR(output)
+\fBTransmitted Data:\fR Outgoing serial data.
+.IP \fBRXD\fR(input)
+\fBReceived Data:\fRIncoming serial data.
+.IP \fBRTS\fR(output)
+\fBRequest To Send:\fR This hardware handshake line informs the modem that
+your workstation is ready to receive data. Your workstation may
+automatically reset this signal to indicate that the input buffer is full.
+.IP \fBCTS\fR(input)
+\fBClear To Send:\fR The complement to RTS. Indicates that the modem is
+ready to receive data.
+.IP \fBDTR\fR(output)
+\fBData Terminal Ready:\fR This signal tells the modem that the workstation
+is ready to establish a link. DTR is often enabled automatically whenever a
+serial port is opened.
+.IP \fBDSR\fR(input)
+\fBData Set Ready:\fR The complement to DTR. Tells the workstation that the
+modem is ready to establish a link.
+.IP \fBDCD\fR(input)
+\fBData Carrier Detect:\fR This line becomes active when a modem detects a
+.QW Carrier
+signal.
+.IP \fBRI\fR(input)
+\fBRing Indicator:\fR Goes active when the modem detects an incoming call.
+.IP \fBBREAK\fR
+A BREAK condition is not a hardware signal line, but a logical zero on the
+TXD or RXD lines for a long period of time, usually 250 to 500
+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 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\fR \fB\-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
+it or your system is overloaded. Use \fBfconfigure\fR \fB\-sysbuffer\fR to avoid a
+temporary bottleneck and/or make your script faster.
+.TP 10
+\fBTXFULL\fR
+.
+Windows output buffer overrun. Complement to RXOVER. This error should
+practically not happen, because Tcl cares about the output buffer status.
+.TP 10
+\fBOVERRUN\fR
+.
+UART buffer overrun (hardware) with data lost.
+The data comes faster than the system driver receives it.
+Check your advanced serial port settings to enable the FIFO (16550) buffer
+and/or setup a lower(1) interrupt threshold value.
+.TP 10
+\fBRXPARITY\fR
+.
+A parity error has been detected by your UART.
+Wrong parity settings with \fBfconfigure\fR \fB\-mode\fR or a noisy data line (RXD)
+may cause this error.
+.TP 10
+\fBFRAME\fR
+.
+A stop-bit error has been detected by your UART.
+Wrong mode settings with \fBfconfigure\fR \fB\-mode\fR or a noisy data line (RXD)
+may cause this error.
+.TP 10
+\fBBREAK\fR
+.
+A BREAK condition has been detected by your UART (see above).
+.SH "PORTABILITY ISSUES"
+.TP
+\fBWindows \fR(all versions)
+.
+Valid values for \fIfileName\fR to open a serial port are of the form
+\fBcom\fIX\fB:\fR, where \fIX\fR is a number, generally from 1 to 4.
+This notation only works for serial ports from 1 to 9, if the system
+happens to have more than four. An attempt to open a serial port that
+does not exist or has a number greater than 9 will fail. An alternate
+form of opening serial ports is to use the filename \fB\e\e.\ecomX\fR,
+where X is any number that corresponds to a serial port; please note
+that this method is considerably slower on Windows 95 and Windows 98.
+.TP
+\fBWindows NT\fR
+.
+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, some
+of the lines entered at the console will be sent to the command pipeline and
+some will be sent to the Tcl evaluator. If a command pipeline is opened for
+writing, keystrokes entered into the console are not visible until the
+pipe is closed. This behavior occurs whether the command pipeline is
+executing 16-bit or 32-bit applications. These problems only occur because
+both Tcl and the child application are competing for the console at
+the same time. If the command pipeline is started from a script, so that Tcl
+is not accessing the console, or if the command pipeline does not use
+standard input or output, but is redirected from or to a file, then the
+above problems do not occur.
+.TP
+\fBWindows 95\fR
+.
+A command pipeline that executes a 16-bit DOS application cannot be opened
+for both reading and writing, since 16-bit DOS applications that receive
+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.
+.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
+a 32-bit application, some of the keystrokes entered at the console will be
+sent to the command pipeline and some will be sent to the Tcl evaluator. If
+a command pipeline is opened for writing to a 32-bit application, no output
+is visible on the console until the pipe is closed. These problems only
+occur because both Tcl and the child application are competing for the
+console at the same time. If the command pipeline is started from a script,
+so that Tcl is not accessing the console, or if the command pipeline does
+not use standard input or output, but is redirected from or to a file, then
+the above problems do not occur.
+.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
+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.
+.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.
+Advanced configuration options are only supported for serial ports
+when Tcl is built to use the POSIX serial interface.
+.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
+of the lines entered at the console will be sent to the command pipeline and
+some will be sent to the Tcl evaluator. This problem only occurs because
+both Tcl and the child application are competing for the console at the
+same time. If the command pipeline is started from a script, so that Tcl is
+not accessing the console, or if the command pipeline does not use standard
+input, but is redirected from a file, then the above problem does not occur.
+.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"
+.PP
+Open a command pipeline and catch any errors:
+.PP
+.CS
+set fl [\fBopen\fR "| ls this_file_does_not_exist"]
+set data [read $fl]
+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
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/pkgs/msgcat/doc/package.n b/pkgs/msgcat/doc/package.n
new file mode 100644
index 0000000..6cf8991
--- /dev/null
+++ b/pkgs/msgcat/doc/package.n
@@ -0,0 +1,370 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH package n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+package \- Facilities for package loading and version control
+.SH SYNOPSIS
+.nf
+\fBpackage forget\fR ?\fIpackage package ...\fR?
+\fBpackage ifneeded \fIpackage version\fR ?\fIscript\fR?
+\fBpackage names\fR
+\fBpackage present \fIpackage \fR?\fIrequirement...\fR?
+\fBpackage present \-exact \fIpackage version\fR
+\fBpackage provide \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 \fIversion requirement...\fR
+\fBpackage prefer \fR?\fBlatest\fR|\fBstable\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+This command keeps a simple database of the packages available for
+use by the current interpreter and how to load them into the
+interpreter.
+It supports multiple versions of each package and arranges
+for the correct version of a package to be loaded based on what
+is needed by the application.
+This command also detects and reports version clashes.
+Typically, only the \fBpackage require\fR and \fBpackage provide\fR
+commands are invoked in normal Tcl scripts; the other commands are used
+primarily by system scripts that maintain the package database.
+.PP
+The behavior of the \fBpackage\fR command is determined by its first argument.
+The following forms are permitted:
+.TP
+\fBpackage forget\fR ?\fIpackage package ...\fR?
+.
+Removes all information about each specified package from this interpreter,
+including information provided by both \fBpackage ifneeded\fR and
+\fBpackage provide\fR.
+.TP
+\fBpackage ifneeded \fIpackage version\fR ?\fIscript\fR?
+.
+This command typically appears only in system configuration
+scripts to set up the package database.
+It indicates that a particular version of
+a particular package is available if needed, and that the package
+can be added to the interpreter by executing \fIscript\fR.
+The script is saved in a database for use by subsequent
+\fBpackage require\fR commands; typically, \fIscript\fR
+sets up auto-loading for the commands in the package (or calls
+\fBload\fR and/or \fBsource\fR directly), then invokes
+\fBpackage provide\fR to indicate that the package is present.
+There may be information in the database for several different
+versions of a single package.
+If the database already contains information for \fIpackage\fR
+and \fIversion\fR, the new \fIscript\fR replaces the existing
+one.
+If the \fIscript\fR argument is omitted, the current script for
+version \fIversion\fR of package \fIpackage\fR is returned,
+or an empty string if no \fBpackage ifneeded\fR command has
+been invoked for this \fIpackage\fR and \fIversion\fR.
+.TP
+\fBpackage names\fR
+.
+Returns a list of the names of all packages in the
+interpreter for which a version has been provided (via
+\fBpackage provide\fR) or for which a \fBpackage ifneeded\fR
+script is available.
+The order of elements in the list is arbitrary.
+.TP
+\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
+\fBpackage provide \fIpackage \fR?\fIversion\fR?
+.
+This command is invoked to indicate that version \fIversion\fR
+of package \fIpackage\fR is now present in the interpreter.
+It is typically invoked once as part of an \fBifneeded\fR script,
+and again by the package itself when it is finally loaded.
+An error occurs if a different version of \fIpackage\fR has been
+provided by a previous \fBpackage provide\fR command.
+If the \fIversion\fR argument is omitted, then the command
+returns the version number that is currently provided, or an
+empty string if no \fBpackage provide\fR command has been
+invoked for \fIpackage\fR in this interpreter.
+.TP
+\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.
+.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 \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.
+If so, the script for the highest acceptable version number is evaluated
+in the global namespace;
+it must do whatever is necessary to load the package,
+including calling \fBpackage provide\fR for the package.
+If the \fBpackage ifneeded\fR database does not contain an acceptable
+version of the package and a \fBpackage unknown\fR command has been
+specified for the interpreter then that command is evaluated in the
+global namespace; when
+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
+.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 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 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.
+If \fIcommand\fR is specified as an empty string, then the current
+\fBpackage unknown\fR script is removed, if there is one.
+.TP
+\fBpackage vcompare \fIversion1 version2\fR
+.
+Compares the two version numbers given by \fIversion1\fR and \fIversion2\fR.
+Returns -1 if \fIversion1\fR is an earlier version than \fIversion2\fR,
+0 if they are equal, and 1 if \fIversion1\fR is later than \fIversion2\fR.
+.TP
+\fBpackage versions \fIpackage\fR
+.
+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 \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
+by dots, such as 2 or 1.162 or 3.1.13.1.
+The first number is called the major version number.
+Larger numbers correspond to later versions of a package, with
+leftmost numbers having greater significance.
+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.
+For example, Tcl scripts written for version 2.3 of a package should
+work unchanged under versions 2.3.2, 2.4, and 2.5.1.
+Changes in the major version number signify incompatible changes:
+if code is written to use version 2.1 of a package, it is not guaranteed
+to work unmodified with either version 1.7.3 or version 3.1.
+.SH "PACKAGE INDICES"
+.PP
+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 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
+.PP
+To state that a Tcl script requires the Tk and http packages, put this
+at the top of the script:
+.PP
+.CS
+\fBpackage require\fR Tk
+\fBpackage require\fR http
+.CE
+.PP
+To test to see if the Snack package is available and load if it is
+(often useful for optional enhancements to programs where the loss of
+the functionality is not critical) do this:
+.PP
+.CS
+if {[catch {\fBpackage require\fR Snack}]} {
+ # Error thrown - package not found.
+ # Set up a dummy interface to work around the absence
+} else {
+ # We have the package, configure the app to use it
+}
+.CE
+.SH "SEE ALSO"
+msgcat(n), packagens(n), pkgMkIndex(n)
+.SH KEYWORDS
+package, version
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/packagens.n b/pkgs/msgcat/doc/packagens.n
new file mode 100644
index 0000000..30617a3
--- /dev/null
+++ b/pkgs/msgcat/doc/packagens.n
@@ -0,0 +1,50 @@
+'\"
+'\" Copyright (c) 1998-2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.so man.macros
+.TH pkg::create n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+pkg::create \- Construct an appropriate 'package ifneeded' command for a given package specification
+.SH SYNOPSIS
+\fB::pkg::create\fR \fB\-name \fIpackageName \fB\-version \fIpackageVersion\fR ?\fB\-load \fIfilespec\fR? ... ?\fB\-source \fIfilespec\fR? ...
+.BE
+
+.SH DESCRIPTION
+.PP
+\fB::pkg::create\fR is a utility procedure that is part of the standard Tcl
+library. It is used to create an appropriate \fBpackage ifneeded\fR
+command for a given package specification. It can be used to construct a
+\fBpkgIndex.tcl\fR file for use with the \fBpackage\fR mechanism.
+
+.SH OPTIONS
+The parameters supported are:
+.TP
+\fB\-name \fIpackageName\fR
+This parameter specifies the name of the package. It is required.
+.TP
+\fB\-version \fIpackageVersion\fR
+This parameter specifies the version of the package. It is required.
+.TP
+\fB\-load \fIfilespec\fR
+This parameter specifies a binary library that must be loaded with the
+\fBload\fR command. \fIfilespec\fR is a list with two elements. The
+first element is the name of the file to load. The second, optional
+element is a list of commands supplied by loading that file. If the
+list of procedures is empty or omitted, \fB::pkg::create\fR will
+set up the library for direct loading (see \fBpkg_mkIndex\fR). Any
+number of \fB\-load\fR parameters may be specified.
+.TP
+\fB\-source \fIfilespec\fR
+This parameter is similar to the \fB\-load\fR parameter, except that it
+specifies a Tcl library that must be loaded with the
+\fBsource\fR command. Any number of \fB\-source\fR parameters may be
+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/pkgs/msgcat/doc/pid.n b/pkgs/msgcat/doc/pid.n
new file mode 100644
index 0000000..97a42a7
--- /dev/null
+++ b/pkgs/msgcat/doc/pid.n
@@ -0,0 +1,48 @@
+'\"
+'\" 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 pid n 7.0 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+pid \- Retrieve process identifiers
+.SH SYNOPSIS
+\fBpid \fR?\fIfileId\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+If the \fIfileId\fR argument is given then it should normally
+refer to a process pipeline created with the \fBopen\fR command.
+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 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.
+.SH EXAMPLE
+Print process information about the processes in a pipeline using the
+SysV \fBps\fR program before reading the output of that pipeline:
+.PP
+.CS
+set pipeline [open "| zcat somefile.gz | grep foobar | sort -u"]
+# Print process information
+exec ps -fp [\fBpid\fR $pipeline] >@stdout
+# Print a separator and then the output of the pipeline
+puts [string repeat - 70]
+puts [read $pipeline]
+close $pipeline
+.CE
+
+.SH "SEE ALSO"
+exec(n), open(n)
+
+.SH KEYWORDS
+file, pipeline, process identifier
diff --git a/pkgs/msgcat/doc/pkgMkIndex.n b/pkgs/msgcat/doc/pkgMkIndex.n
new file mode 100644
index 0000000..2753208
--- /dev/null
+++ b/pkgs/msgcat/doc/pkgMkIndex.n
@@ -0,0 +1,233 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH pkg_mkIndex n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+pkg_mkIndex \- Build an index for automatic loading of packages
+.SH SYNOPSIS
+.nf
+\fBpkg_mkIndex\fR ?\fIoptions...\fR? \fIdir\fR ?\fIpattern pattern ...\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+\fBPkg_mkIndex\fR is a utility procedure that is part of the standard
+Tcl library.
+It is used to create index files that allow packages to be loaded
+automatically when \fBpackage require\fR commands are executed.
+To use \fBpkg_mkIndex\fR, follow these steps:
+.IP [1]
+Create the package(s).
+Each package may consist of one or more Tcl script files or binary files.
+Binary files must be suitable for loading with the \fBload\fR command
+with a single argument; for example, if the file is \fBtest.so\fR it must
+be possible to load this file with the command \fBload test.so\fR.
+Each script file must contain a \fBpackage provide\fR command to declare
+the package and version number, and each binary file must contain
+a call to \fBTcl_PkgProvide\fR.
+.IP [2]
+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.
+The default pattern is \fB*.tcl\fR and \fB*.[info sharedlibextension]\fR.
+.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.
+It does this by loading each file into a slave
+interpreter and seeing what packages
+and new commands appear (this is why it is essential to have
+\fBpackage provide\fR commands or \fBTcl_PkgProvide\fR calls
+in the files, as described above).
+If you have a package split among scripts and binary files,
+or if you have dependencies among files,
+you may have to use the \fB\-load\fR option
+or adjust the order in which \fBpkg_mkIndex\fR processes
+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
+than one directory, machine-dependent packages (e.g., those that
+contain binary shared libraries) should normally be installed
+under the first directory and machine-independent packages (e.g.,
+those that contain only Tcl scripts) should be installed under the
+second directory.
+The subdirectory should include
+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.
+.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.
+\fBAuto_path\fR contains a list of directories that are searched
+by both the auto-loader and the package loader; by default it
+includes \fB$tcl_pkgPath\fR.
+The package loader also checks all of the subdirectories of the
+directories in \fBauto_path\fR.
+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.
+For example, if versions 2.1, 2.3, and 3.1 of package \fBTest\fR
+have been indexed by \fBpkg_mkIndex\fR, the command
+\fBpackage require Test\fR will make version 3.1 available
+and the command \fBpackage require \-exact Test 2.1\fR will
+make version 2.1 available.
+There may be many versions of a package in the various index files
+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
+\fB\-direct\fR
+The generated index will implement direct loading of the package
+upon \fBpackage require\fR. This is the default.
+.TP 15
+\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. 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\fR into the slave interpreter used to
+generate the index. The pattern match uses string match rules, but without
+making case distinctions.
+See \fBCOMPLEX CASES\fR below.
+.TP 15
+\fB\-verbose\fR
+Generate output during the indexing process. Output is via
+the \fBtclLog\fR procedure, which by default prints to stderr.
+.TP 15
+\fB\-\-\fR
+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,
+in that both arrange for files to be loaded on-demand.
+However, package management is a higher-level mechanism that uses
+the auto-loader for the last step in the loading process.
+It is generally better to index a package with \fBpkg_mkIndex\fR
+rather than \fBauto_mkindex\fR because the package mechanism provides
+version control: several versions of a package can be made available
+in the index files, with different applications using different
+versions based on \fBpackage require\fR commands.
+In contrast, \fBauto_mkindex\fR does not understand versions so
+it can only handle a single version of each package.
+It is probably not a good idea to index a given package with both
+\fBpkg_mkIndex\fR and \fBauto_mkindex\fR.
+If you use \fBpkg_mkIndex\fR to index a package, its commands cannot
+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,
+the \fBpackage ifneeded\fR command, and the auto-loader.
+The first time a \fBpackage require\fR command is invoked,
+the \fBpackage unknown\fR script is invoked.
+This is set by Tcl initialization to a script that
+evaluates all of the \fBpkgIndex.tcl\fR files in the
+\fBauto_path\fR.
+The \fBpkgIndex.tcl\fR files contain \fBpackage ifneeded\fR
+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.
+If the \fB\-lazy\fR flag was provided when the \fBpkgIndex.tcl\fR
+was generated,
+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.
+.SH "DIRECT LOADING"
+.PP
+Some packages, for instance packages which use namespaces and export
+commands or those which require special initialization, might select
+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 \fB\-lazy\fR argument.
+.SH "COMPLEX CASES"
+Most complex cases of dependencies among scripts
+and binary files, and packages being split among scripts and
+binary files are handled OK. However, you may have to adjust
+the order in which files are processed by \fBpkg_mkIndex\fR.
+These issues are described in detail below.
+.PP
+If each script or file contains one package, and packages
+are only contained in one file, then things are easy.
+You simply specify all files to be indexed in any order
+with some glob patterns.
+.PP
+In general, it is OK for scripts to have dependencies on other
+packages.
+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\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\fR API
+when loading a binary file.
+For example, suppose the BLT package requires Tk, and expresses
+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\fR and that match \fIpkgPat\fR
+into the interpreter used to process files.
+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,
+you should specify the one that has dependencies last.
+This way the one without dependencies will get loaded and indexed,
+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\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\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\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
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/pkgs/msgcat/doc/platform.n b/pkgs/msgcat/doc/platform.n
new file mode 100644
index 0000000..1553698
--- /dev/null
+++ b/pkgs/msgcat/doc/platform.n
@@ -0,0 +1,86 @@
+'\"
+'\" 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.10?\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 EXAMPLE
+.PP
+This can be used to allow an application to be shipped with multiple builds of
+a shared library, so that the same package works on many versions of an
+operating system. For example:
+.PP
+.CS
+\fBpackage require platform\fR
+# Assume that app script is .../theapp/bin/theapp.tcl
+set binDir [file dirname [file normalize [info script]]]
+set libDir [file join $binDir .. lib]
+set platLibDir [file join $libDir [\fBplatform::identify\fR]]
+load [file join $platLibDir support[info sharedlibextension]]
+.CE
+.SH KEYWORDS
+operating system, cpu architecture, platform, architecture
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/platform_shell.n b/pkgs/msgcat/doc/platform_shell.n
new file mode 100644
index 0000000..eef4d4e
--- /dev/null
+++ b/pkgs/msgcat/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/pkgs/msgcat/doc/prefix.n b/pkgs/msgcat/doc/prefix.n
new file mode 100644
index 0000000..eb79996
--- /dev/null
+++ b/pkgs/msgcat/doc/prefix.n
@@ -0,0 +1,116 @@
+'\"
+'\" Copyright (c) 2008 Peter Spjuth <pspjuth@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 prefix n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+tcl::prefix \- facilities for prefix matching
+.SH SYNOPSIS
+.nf
+\fB::tcl::prefix all\fR \fItable\fR \fIstring\fR
+\fB::tcl::prefix longest\fR \fItable\fR \fIstring\fR
+\fB::tcl::prefix match\fR \fI?option ...?\fR \fItable\fR \fIstring\fR
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+This document describes commands looking up a prefix in a list of strings.
+The following commands are supported:
+.TP
+\fB::tcl::prefix all\fR \fItable\fR \fIstring\fR
+.
+Returns a list of all elements in \fItable\fR that begin with the prefix
+\fIstring\fR.
+.TP
+\fB::tcl::prefix longest\fR \fItable\fR \fIstring\fR
+.
+Returns the longest common prefix of all elements in \fItable\fR that
+begin with the prefix \fIstring\fR.
+.TP
+\fB::tcl::prefix match\fR ?\fIoptions\fR? \fItable\fR \fIstring\fR
+.
+If \fIstring\fR equals one element in \fItable\fR or is a prefix to exactly
+one element, the matched element is returned. If not, the result depends
+on the \fB\-error\fR option. (It is recommended that the \fItable\fR be sorted
+before use with this subcommand, so that the list of matches presented in the
+error message also becomes sorted, though this is not strictly necessary for
+the operation of this subcommand itself.)
+.RS
+.TP
+\fB\-exact\fR\0
+.
+Accept only exact matches.
+.TP
+\fB\-message\0\fIstring\fR
+.
+Use \fIstring\fR in the error message at a mismatch. Default is
+.QW option .
+.TP
+\fB\-error\0\fIoptions\fR
+.
+The \fIoptions\fR are used when no match is found. If \fIoptions\fR is empty,
+no error is generated and an empty string is returned. Otherwise the
+\fIoptions\fR are used as \fBreturn\fR options when generating the error
+message. The default corresponds to setting
+.QW "\-level 0" .
+Example: If
+.QW "\fB\-error\fR {\-errorcode MyError \-level 1}"
+is used, an error would be generated as:
+.RS
+.PP
+.CS
+return \-errorcode MyError \-level 1 \-code error \e
+ "ambiguous option ..."
+.CE
+.RE
+.RE
+.SH "EXAMPLES"
+.PP
+Basic use:
+.PP
+.CS
+namespace import ::tcl::prefix
+\fBprefix match\fR {apa bepa cepa} apa
+ \fI\(-> apa\fR
+\fBprefix match\fR {apa bepa cepa} a
+ \fI\(-> apa\fR
+\fBprefix match\fR \-exact {apa bepa cepa} a
+ \fI\(-> bad option "a": must be apa, bepa, or cepa\fR
+\fBprefix match\fR \-message "switch" {apa ada bepa cepa} a
+ \fI\(-> ambiguous switch "a": must be apa, ada, bepa, or cepa\fR
+\fBprefix longest\fR {fblocked fconfigure fcopy file fileevent flush} fc
+ \fI\(-> fco\fR
+\fBprefix all\fR {fblocked fconfigure fcopy file fileevent flush} fc
+ \fI\(-> fconfigure fcopy\fR
+.CE
+.PP
+Simplifying option matching:
+.PP
+.CS
+array set opts {\-apa 1 \-bepa "" \-cepa 0}
+foreach {arg val} $args {
+ set opts([\fBprefix match\fR {\-apa \-bepa \-cepa} $arg]) $val
+}
+.CE
+.PP
+Creating a \fBswitch\fR that supports prefixes:
+.PP
+.CS
+switch [\fBprefix match\fR {apa bepa cepa} $arg] {
+ apa { }
+ bepa { }
+ cepa { }
+}
+.CE
+.SH "SEE ALSO"
+lsearch(n), namespace(n), string(n), Tcl_GetIndexFromObj(3)
+.SH "KEYWORDS"
+prefix, table lookup
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/proc.n b/pkgs/msgcat/doc/proc.n
new file mode 100644
index 0000000..570a37d
--- /dev/null
+++ b/pkgs/msgcat/doc/proc.n
@@ -0,0 +1,110 @@
+'\"
+'\" 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 proc n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+proc \- Create a Tcl procedure
+.SH SYNOPSIS
+\fBproc \fIname args body\fR
+.BE
+.SH DESCRIPTION
+.PP
+The \fBproc\fR command creates a new Tcl procedure named
+\fIname\fR, replacing
+any existing command or procedure there may have been by that name.
+Whenever the new command is invoked, the contents of \fIbody\fR will
+be executed by the Tcl interpreter.
+Normally, \fIname\fR is unqualified
+(does not include the names of any containing namespaces),
+and the new procedure is created in the current namespace.
+If \fIname\fR includes any namespace qualifiers,
+the procedure is created in the specified namespace.
+\fIArgs\fR specifies the formal arguments to the
+procedure. It consists of a list, possibly empty, each of whose
+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.
+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 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 formal arguments. In this case, all of the actual arguments
+starting at the one that would be assigned to \fBargs\fR are combined into
+a list (as if the \fBlist\fR command had been used); this combined value
+is assigned to the local variable \fBargs\fR.
+.PP
+When \fIbody\fR is being executed, variable names normally refer to
+local variables, which are created automatically when referenced and
+deleted when the procedure returns. One local variable is automatically
+created for each of the procedure's arguments.
+Other variables can only be accessed by invoking one of the \fBglobal\fR,
+\fBvariable\fR, \fBupvar\fR or \fBnamespace upvar\fR commands.
+The current namespace when \fIbody\fR is executed will be the
+namespace that the procedure's name exists in, which will be the
+namespace that it was created in unless it has been changed with
+\fBrename\fR.
+'\" We may change this! It makes [variable] unstable when renamed and is
+'\" frankly pretty crazy, but doing it right is harder than it looks.
+.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 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
+body, then the procedure-as-a-whole will return that same error.
+.SH EXAMPLES
+.PP
+This is a procedure that accepts arbitrarily many arguments and prints
+them out, one by one.
+.PP
+.CS
+\fBproc\fR printArguments args {
+ foreach arg $args {
+ puts $arg
+ }
+}
+.CE
+.PP
+This procedure is a bit like the \fBincr\fR command, except it
+multiplies the contents of the named variable by the value, which
+defaults to \fB2\fR:
+.PP
+.CS
+\fBproc\fR mult {varName {multiplier 2}} {
+ upvar 1 $varName var
+ set var [expr {$var * $multiplier}]
+}
+.CE
+.SH "SEE ALSO"
+info(n), unknown(n)
+.SH KEYWORDS
+argument, procedure
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/puts.n b/pkgs/msgcat/doc/puts.n
new file mode 100644
index 0000000..4a53d44
--- /dev/null
+++ b/pkgs/msgcat/doc/puts.n
@@ -0,0 +1,98 @@
+'\"
+'\" 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 puts n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+puts \- Write to a channel
+.SH SYNOPSIS
+\fBputs \fR?\fB\-nonewline\fR? ?\fIchannelId\fR? \fIstring\fR
+.BE
+.SH DESCRIPTION
+.PP
+Writes the characters given by \fIstring\fR to the channel given
+by \fIchannelId\fR.
+.PP
+\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.
+.PP
+If no \fIchannelId\fR is specified then it defaults to
+\fBstdout\fR. \fBPuts\fR normally outputs a newline character after
+\fIstring\fR, but this feature may be suppressed by specifying the
+\fB\-nonewline\fR switch.
+.PP
+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.
+See the \fBfconfigure\fR manual entry for a discussion on ways in
+which \fBfconfigure\fR will alter output.
+.PP
+Tcl buffers output internally, so characters written with \fBputs\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 \fBflush\fR
+command.
+.PP
+When the output buffer fills up, the \fBputs\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 \fBputs\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 \fBfileevent\fR command
+(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
+.PP
+Write a short message to the console (or wherever \fBstdout\fR is
+directed):
+.PP
+.CS
+\fBputs\fR "Hello, World!"
+.CE
+.PP
+Print a message in several parts:
+.PP
+.CS
+\fBputs\fR -nonewline "Hello, "
+\fBputs\fR "World!"
+.CE
+.PP
+Print a message to the standard error channel:
+.PP
+.CS
+\fBputs\fR stderr "Hello, World!"
+.CE
+.PP
+Append a log message to a file:
+.PP
+.CS
+set chan [open my.log a]
+set timestamp [clock format [clock seconds]]
+\fBputs\fR $chan "$timestamp - Hello, World!"
+close $chan
+.CE
+.SH "SEE ALSO"
+file(n), fileevent(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+channel, newline, output, write
diff --git a/pkgs/msgcat/doc/pwd.n b/pkgs/msgcat/doc/pwd.n
new file mode 100644
index 0000000..65fed84
--- /dev/null
+++ b/pkgs/msgcat/doc/pwd.n
@@ -0,0 +1,39 @@
+'\"
+'\" 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 pwd n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+pwd \- Return the absolute path of the current working directory
+.SH SYNOPSIS
+\fBpwd\fR
+.BE
+.SH DESCRIPTION
+.PP
+Returns the absolute path name of the current working directory.
+.SH EXAMPLE
+.PP
+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 minimizes user
+confusion. The way to do this is to save the current directory while
+the external command is being run:
+.PP
+.CS
+set tarFile [file normalize somefile.tar]
+set savedDir [\fBpwd\fR]
+cd /tmp
+exec tar -xf $tarFile
+cd $savedDir
+.CE
+.SH "SEE ALSO"
+file(n), cd(n), glob(n), filename(n)
+.SH KEYWORDS
+working directory
diff --git a/pkgs/msgcat/doc/re_syntax.n b/pkgs/msgcat/doc/re_syntax.n
new file mode 100644
index 0000000..46a180d
--- /dev/null
+++ b/pkgs/msgcat/doc/re_syntax.n
@@ -0,0 +1,834 @@
+'\"
+'\" Copyright (c) 1998 Sun Microsystems, Inc.
+'\" Copyright (c) 1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.ie '\w'o''\w'\C'^o''' .ds qo \C'^o'
+.el .ds qo u
+.TH re_syntax n "8.1" Tcl "Tcl Built-In Commands"
+.BS
+.SH NAME
+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 does not match others.
+.SH "DIFFERENT FLAVORS OF REs"
+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
+.PQ ARE s ,
+basically EREs with some significant extensions.
+.PP
+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
+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
+regular expressions below is copied verbatim from his manual entry.
+.PP
+An ARE is one or more \fIbranches\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.
+.SS QUANTIFIERS
+A quantified atom is an \fIatom\fR possibly followed
+by a single \fIquantifier\fR.
+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,
+but prefer the smallest number rather than the largest number
+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.
+.SS ATOMS
+An atom is one of:
+.RS 2
+.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
+.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
+.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 \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
+.TP
+\fB(?!\fIre\fB)\fR
+.
+\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
+.QW \fB\e\fR .
+.SH "BRACKET EXPRESSIONS"
+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.
+.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 incompatibility between programs.
+.PP
+To include a literal \fB]\fR or \fB\-\fR in the list, the simplest
+method is to enclose it in \fB[.\fR and \fB.]\fR to make it a
+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:
+.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 \fBalnum\fR
+and \fBpunct\fR).
+.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
+.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
+(\fINote:\fR Tcl has no multi-character collating elements. This information
+is only for illustration.)
+.RE
+.PP
+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
+.QW \fB.]\fR .)
+For example, if \fBo\fR and \fB\*(qo\fR are the members of an
+equivalence class, then
+.QW \fB[[=o=]]\fR ,
+.QW \fB[[=\*(qo=]]\fR ,
+and
+.QW \fB[o\*(qo]\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
+applications where there are multiple levels of backslash processing
+.TP
+\fB\ec\fIX\fR
+.
+(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
+.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 one up to four hexadecimal digits) the Unicode
+character \fBU+\fIwxyz\fR in the local byte ordering
+.TP
+\fB\eU\fIstuvwxyz\fR
+.
+(where \fIstuvwxyz\fR is one up to eight hexadecimal digits) reserved
+for a Unicode extension up to 21 bits. The digits are parsed until the
+first non-hexadecimal character is encountered, the maximun of eight
+hexadecimal digits are reached, or an overflow would occur in the maximum
+value of \fBU+\fI10ffff\fR.
+.TP
+\fB\ev\fR
+.
+vertical tab, as in C are all available.
+.TP
+\fB\ex\fIhh\fR
+.
+(where \fIhh\fR is one or two hexadecimal digits) the character
+whose hexadecimal value is \fB0x\fIhh\fR.
+.TP
+\fB\e0\fR
+.
+the character whose value is \fB0\fR
+.TP
+\fB\e\fIxyz\fR
+.
+(where \fIxyz\fR is exactly three octal digits, and is not a \fIback
+reference\fR (see below)) the character whose octal value is
+\fB0\fIxyz\fR. The first digit must be in the range 0-3, otherwise
+the two-digit form is assumed.
+.TP
+\fB\e\fIxy\fR
+.
+(where \fIxy\fR is exactly two octal digits, and is not a \fIback
+reference\fR (see below)) the character whose octal value is
+\fB0\fIxy\fR
+.RE
+.PP
+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 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)
+.TP
+\fB\eD\fR
+.
+\fB[^[:digit:]]\fR
+.TP
+\fB\eS\fR
+.
+\fB[^[:space:]]\fR
+.TP
+\fB\eW\fR
+.
+\fB[^[:alnum:]_]\fR (note underscore)
+.RE
+.PP
+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 \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 \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
+.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
+.RE
+.PP
+A word is defined as in the specification of
+.QW \fB[[:<:]]\fR
+and
+.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
+.QW \fBbb\fR
+or
+.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.
+.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
+.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 \fBMATCHING\fR, below)
+.TP 3
+\fBm\fR
+.
+historical synonym for \fBn\fR
+.TP 3
+\fBn\fR
+.
+newline-sensitive matching (see \fBMATCHING\fR, below)
+.TP 3
+\fBp\fR
+.
+partial newline-sensitive matching (see \fBMATCHING\fR, below)
+.TP 3
+\fBq\fR
+.
+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
+.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:
+.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
+.QW \fB(?:\fR
+or the BRE
+.QW \fB\e(\fR
+.PP
+Expanded-syntax white-space characters are blank, tab, newline, and
+any character that belongs to the \fIspace\fR character class.
+.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
+.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,
+.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
+.QW \fB(.*).*\fR
+is matched against
+.QW \fBabc\fR
+the parenthesized subexpression matches all three characters, and when
+.QW \fB(a*)*\fR
+is matched against
+.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
+.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
+.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.
+.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 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
+.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.
+.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.
+.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
+.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/pkgs/msgcat/doc/read.n b/pkgs/msgcat/doc/read.n
new file mode 100644
index 0000000..007c0ac
--- /dev/null
+++ b/pkgs/msgcat/doc/read.n
@@ -0,0 +1,89 @@
+'\"
+'\" 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 read n 8.1 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+read \- Read from a channel
+.SH SYNOPSIS
+\fBread \fR?\fB\-nonewline\fR? \fIchannelId\fR
+.sp
+\fBread \fIchannelId numChars\fR
+.BE
+.SH DESCRIPTION
+.PP
+In the first form, the \fBread\fR command reads all of the data from
+\fIchannelId\fR up to the end of the file. If the \fB\-nonewline\fR
+switch is specified then the last character of the file is discarded
+if it is a newline. In the second form, the extra argument specifies
+how many characters to read. Exactly that many characters will be
+read and returned, unless there are fewer than \fInumChars\fR left in
+the file; in this case all the remaining characters are returned. If
+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
+\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.
+.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,
+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
+\fBRead\fR translates end-of-line sequences in the input into
+newline characters according to the \fB\-translation\fR option
+for the channel.
+See the \fBfconfigure\fR manual entry for a discussion on ways in
+which \fBfconfigure\fR will alter input.
+.SH "USE WITH SERIAL PORTS"
+'\" Note: this advice actually applies to many versions of Tcl
+.PP
+For most applications a channel connected to a serial port should be
+configured to be nonblocking: \fBfconfigure\fI channelId \fB\-blocking
+\fI0\fR. Then \fBread\fR behaves much like described above. Care
+must be taken when using \fBread\fR on blocking serial ports:
+.TP
+\fBread \fIchannelId numChars\fR
+.
+In this form \fBread\fR blocks until \fInumChars\fR have been received
+from the serial port.
+.TP
+\fBread \fIchannelId\fR
+.
+In this form \fBread\fR blocks until the reception of the end-of-file
+character, see \fBfconfigure\fR \fB\-eofchar\fR. If there no end-of-file
+character has been configured for the channel, then \fBread\fR will
+block forever.
+.SH "EXAMPLE"
+.PP
+This example code reads a file all at once, and splits it into a list,
+with each line in the file corresponding to an element in the list:
+.PP
+.CS
+set fl [open /proc/meminfo]
+set data [\fBread\fR $fl]
+close $fl
+set lines [split $data \en]
+.CE
+.SH "SEE ALSO"
+file(n), eof(n), fblocked(n), fconfigure(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+blocking, channel, end of line, end of file, nonblocking, read, translation, encoding
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/pkgs/msgcat/doc/refchan.n b/pkgs/msgcat/doc/refchan.n
new file mode 100644
index 0000000..a51c3d7
--- /dev/null
+++ b/pkgs/msgcat/doc/refchan.n
@@ -0,0 +1,411 @@
+'\"
+'\" 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
+.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\fR \fBcreate\fR, though the implementation
+of handlers for reflected channel \fIis not\fR tied to \fBnamespace
+ensemble\fRs in any way; see \fBEXAMPLE\fR below for how to build an
+\fBoo::class\fR that supports the API). 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 \fBchan close\fR) will appear to have thrown this
+error. Any exception beyond \fBerror\fR (e.g.,\ \fBbreak\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, \fBbreak\fR, \fBcontinue\fR, 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 \fIbytes\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.
+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 \fBgets\fR, or \fBread\fR) will appear to have
+thrown this error. Any exception beyond \fBerror\fR, (e.g.,\ \fBbreak\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 \fBerror\fR (e.g.,\ \fBbreak\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
+\fBchan seek\fR and \fBchan tell\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 the same as the equivalent argument of the
+builtin \fBchan seek\fR, namely:
+.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 \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.
+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.
+If the subcommand throws an error the command which caused its
+invocation (usually \fBchan seek\fR, or \fBchan tell\fR) will appear to have
+thrown this error. Any exception beyond \fBerror\fR (e.g.,\ \fBbreak\fR,
+etc.) is treated as and converted to an error.
+.PP
+The offset/base combination of 0/\fBcurrent\fR signals a \fBchan tell\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 \fBerror\fR (e.g.,\ \fBbreak\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 or \fBchan configure\fR)
+will appear to have thrown this error. Any exception beyond \fIerror\fR
+(e.g.,\ \fBbreak\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 or \fBchan configure\fR)
+will appear to have thrown this error. Any exception beyond \fBerror\fR
+(e.g.,\ \fBbreak\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 or \fBchan configure\fR) will appear to
+have thrown this error. Any exception beyond \fBerror\fR (e.g.,\ \fBbreak\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 EXAMPLE
+.PP
+This demonstrates how to make a channel that reads from a string.
+.PP
+.CS
+oo::class create stringchan {
+ variable data pos
+ constructor {string {encoding {}}} {
+ if {$encoding eq ""} {set encoding [encoding system]}
+ set data [encoding convertto $encoding $string]
+ set pos 0
+ }
+
+ method \fBinitialize\fR {ch mode} {
+ return "initialize finalize watch read seek"
+ }
+ method \fBfinalize\fR {ch} {
+ my destroy
+ }
+ method \fBwatch\fR {ch events} {
+ # Must be present but we ignore it because we do not
+ # post any events
+ }
+
+ # Must be present on a readable channel
+ method \fBread\fR {ch count} {
+ set d [string range $data $pos [expr {$pos+$count-1}]]
+ incr pos [string length $d]
+ return $d
+ }
+
+ # This method is optional, but useful for the example below
+ method \fBseek\fR {ch offset base} {
+ switch $base {
+ start {
+ set pos $offset
+ }
+ current {
+ incr pos $offset
+ }
+ end {
+ set pos [string length $data]
+ incr pos $offset
+ }
+ }
+ if {$pos < 0} {
+ set pos 0
+ } elseif {$pos > [string length $data]} {
+ set pos [string length $data]
+ }
+ return $pos
+ }
+}
+
+# Now we create an instance...
+set string "The quick brown fox jumps over the lazy dog.\\n"
+set ch [\fBchan create\fR read [stringchan new $string]]
+
+puts [gets $ch]; # Prints the whole string
+
+seek $ch -5 end;
+puts [read $ch]; # Prints just the last word
+.CE
+.SH "SEE ALSO"
+chan(n), transchan(n)
+.SH KEYWORDS
+API, channel, ensemble, prefix, reflection
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/regexp.n b/pkgs/msgcat/doc/regexp.n
new file mode 100644
index 0000000..5e857f8
--- /dev/null
+++ b/pkgs/msgcat/doc/regexp.n
@@ -0,0 +1,208 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH regexp n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+regexp \- Match a regular expression against a string
+.SH SYNOPSIS
+\fBregexp \fR?\fIswitches\fR? \fIexp string \fR?\fImatchVar\fR? ?\fIsubMatchVar subMatchVar ...\fR?
+.BE
+.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 does not, unless
+\fB\-inline\fR is specified (see below).
+(Regular expression matching is described in the \fBre_syntax\fR
+reference page.)
+.PP
+If additional arguments are specified after \fIstring\fR then they
+are treated as the names of variables in which to return
+information about which part(s) of \fIstring\fR matched \fIexp\fR.
+\fIMatchVar\fR will be set to the range of \fIstring\fR that
+matched all of \fIexp\fR. The first \fIsubMatchVar\fR will contain
+the characters in \fIstring\fR that matched the leftmost parenthesized
+subexpression within \fIexp\fR, the next \fIsubMatchVar\fR will
+contain the characters that matched the next parenthesized
+subexpression to the right in \fIexp\fR, and so on.
+.PP
+If the initial arguments to \fBregexp\fR start with \fB\-\fR then
+they are treated as switches. The following switches are
+currently supported:
+.TP 15
+\fB\-about\fR
+.
+Instead of attempting to match the regular expression, returns a list
+containing information about the regular expression. The first
+element of the list is a subexpression count. The second element is a
+list of property names that describe various attributes of the regular
+expression. This switch is primarily intended for debugging purposes.
+.TP 15
+\fB\-expanded\fR
+.
+Enables use of the expanded regular expression syntax where
+whitespace and comments are ignored. This is the same as specifying
+the \fB(?x)\fR embedded option (see the \fBre_syntax\fR manual page).
+.TP 15
+\fB\-indices\fR
+.
+Changes what is stored in the \fIsubMatchVar\fRs.
+Instead of storing the matching characters from \fIstring\fR,
+each variable
+will contain a list of two decimal strings giving the indices
+in \fIstring\fR of the first and last characters in the matching
+range of characters.
+.TP 15
+\fB\-line\fR
+.
+Enables newline-sensitive matching. By default, newline is a
+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
+.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
+.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
+.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).
+.TP 15
+\fB\-nocase\fR
+.
+Causes upper-case characters in \fIstring\fR to be treated as
+lower case during the matching process.
+.TP 15
+\fB\-all\fR
+.
+Causes the regular expression to be matched as many times as possible
+in the string, returning the total number of matches found. If this
+is specified with match variables, they will contain information for
+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
+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:
+.RS
+.PP
+.CS
+\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
+.RE
+.TP 15
+\fB\-start\fR \fIindex\fR
+.
+Specifies a character index offset into the string to start
+matching the regular expression at.
+The \fIindex\fR value is interpreted in the same manner
+as the \fIindex\fR argument to \fBstring index\fR.
+When using this switch,
+.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.
+.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\fRs than parenthesized
+subexpressions within \fIexp\fR, or if a particular subexpression
+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:
+.PP
+.CS
+\fBregexp\fR {\emfoo(?!bar\eM)(\ew*)} $string \-> restOfWord
+.CE
+.PP
+Note that the whole matched substring has been placed in the variable
+.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:
+.PP
+.CS
+\fBregexp\fR \-indices {(?i)\embadger\eM} $string location
+.CE
+.PP
+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:
+.PP
+.CS
+\fBregexp\fR \-indices {(?ib)\e<badger\e>} $string location
+.CE
+.PP
+This counts the number of octal digits in a string:
+.PP
+.CS
+\fBregexp\fR \-all {[0\-7]} $string
+.CE
+.PP
+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:
+.PP
+.CS
+\fBregexp\fR \-all \-inline {\eS+} $string
+.CE
+.SH "SEE ALSO"
+re_syntax(n), regsub(n), string(n)
+.SH KEYWORDS
+match, parsing, pattern, regular expression, splitting, string
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/registry.n b/pkgs/msgcat/doc/registry.n
new file mode 100644
index 0000000..2e69b1e
--- /dev/null
+++ b/pkgs/msgcat/doc/registry.n
@@ -0,0 +1,218 @@
+'\"
+'\" Copyright (c) 1997 Sun Microsystems, Inc.
+'\" Copyright (c) 2002 ActiveState Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH registry n 1.1 registry "Tcl Bundled Packages"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+registry \- Manipulate the Windows registry
+.SH SYNOPSIS
+.sp
+\fBpackage require registry 1.3\fR
+.sp
+\fBregistry \fR?\fI\-mode\fR? \fIoption\fR \fIkeyName\fR ?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fBregistry\fR package provides a general set of operations for
+manipulating the Windows registry. The package implements the
+\fBregistry\fR Tcl command. This command is only supported on the
+Windows platform. Warning: this command should be used with caution
+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:
+.RS
+.PP
+\fB\e\e\fIhostname\fB\e\fIrootname\fB\e\fIkeypath\fR
+.PP
+\fIrootname\fB\e\fIkeypath\fR
+.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,
+\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
+registry key names separated by backslash (\fB\e\fR) characters.
+.PP
+.VS 8.6
+The optional \fI\-mode\fR argument indicates which registry to work
+with; when it is \fB\-32bit\fR the 32-bit registry will be used, and
+when it is \fB\-64bit\fR the 64-bit registry will be used. If this
+argument is omitted, the system's default registry will be the subject
+of the requested operation.
+.VE 8.6
+.PP
+\fIOption\fR indicates what to do with the registry key name. Any
+unique abbreviation for \fIoption\fR is acceptable. The valid options
+are:
+.TP
+\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
+keys like Environment. The timeout specifies the amount of time, in
+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 [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
+.RE
+.TP
+\fBregistry delete \fIkeyName\fR ?\fIvalueName\fR?
+.
+If the optional \fIvalueName\fR argument is present, the specified
+value under \fIkeyName\fR will be deleted from the registry. If the
+optional \fIvalueName\fR is omitted, the specified key and any subkeys
+or values beneath it in the registry hierarchy will be deleted. If
+the key could not be deleted then an error is generated. If the key
+did not exist, the command has no effect.
+.TP
+\fBregistry get \fIkeyName valueName\fR
+.
+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 \fBSUPPORTED TYPES\fR, below.
+.TP
+\fBregistry keys \fIkeyName\fR ?\fIpattern\fR?
+.
+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 match\fR. If the
+specified \fIkeyName\fR does not exist, then an error is generated.
+.TP
+\fBregistry set \fIkeyName\fR ?\fIvalueName data \fR?\fItype\fR??
+.
+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 is not specified, the type
+\fBsz\fR is assumed. For more details on the data and type arguments,
+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
+\fBSUPPORTED TYPES\fR, below.
+.TP
+\fBregistry values \fIkeyName\fR ?\fIpattern\fR?
+.
+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 match\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
+command converts between this internal representation and one that can
+be manipulated by Tcl scripts. In most cases, the data is simply
+returned as a Tcl string. The type indicates the intended use for the
+data, but does not actually change the representation. For some
+types, the \fBregistry\fR command returns the data in a different form to
+make it easier to manipulate. The following types are recognized by the
+registry command:
+.TP 17
+\fBbinary\fR
+.
+The registry value contains arbitrary binary data. The data is represented
+exactly in Tcl, including any embedded nulls.
+.TP
+\fBnone\fR
+.
+The registry value contains arbitrary binary data with no defined
+type. The data is represented exactly in Tcl, including any embedded
+nulls.
+.TP
+\fBsz\fR
+.
+The registry value contains a null-terminated string. The data is
+represented in Tcl as a string.
+.TP
+\fBexpand_sz\fR
+.
+The registry value contains a null-terminated string that contains
+unexpanded references to environment variables in the normal Windows
+style (for example,
+.QW %PATH% ).
+The data is represented in Tcl as a string.
+.TP
+\fBdword\fR
+.
+The registry value contains a little-endian 32-bit number. The data is
+represented in Tcl as a decimal string.
+.TP
+\fBdword_big_endian\fR
+.
+The registry value contains a big-endian 32-bit number. The data is
+represented in Tcl as a decimal string.
+.TP
+\fBlink\fR
+.
+The registry value contains a symbolic link. The data is represented
+exactly in Tcl, including any embedded nulls.
+.TP
+\fBmulti_sz\fR
+.
+The registry value contains an array of null-terminated strings. The
+data is represented in Tcl as a list of strings.
+.TP
+\fBresource_list\fR
+.
+The registry value contains a device-driver resource list. The data
+is represented exactly in Tcl, including any embedded nulls.
+.PP
+In addition to the symbolically named types listed above, unknown
+types are identified using a 32-bit integer that corresponds to the
+type code returned by the system interfaces. In this case, the data
+is represented exactly in Tcl, including any embedded nulls.
+.SH "PORTABILITY ISSUES"
+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
+
+# Read the type name
+set type [\fBregistry get\fR HKEY_CLASSES_ROOT\e\e$ext {}]
+# Work out where to look for the command
+set path HKEY_CLASSES_ROOT\e\e$type\e\eShell\e\eOpen\e\ecommand
+# Read the command!
+set command [\fBregistry get\fR $path {}]
+
+puts "$ext opens with $command"
+.CE
+.SH KEYWORDS
+registry
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/regsub.n b/pkgs/msgcat/doc/regsub.n
new file mode 100644
index 0000000..fe473d9
--- /dev/null
+++ b/pkgs/msgcat/doc/regsub.n
@@ -0,0 +1,192 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Scriptics Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH regsub n 8.3 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+regsub \- Perform substitutions based on regular expression pattern matching
+.SH SYNOPSIS
+\fBregsub \fR?\fIswitches\fR? \fIexp string subSpec \fR?\fIvarName\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command matches the regular expression \fIexp\fR against
+\fIstring\fR,
+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.
+(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
+(or to the result of this command if \fIvarName\fR is not present)
+the portion of \fIstring\fR that
+matched \fIexp\fR is replaced with \fIsubSpec\fR.
+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
+parenthesized subexpression of \fIexp\fR.
+Additional backslashes may be used in \fIsubSpec\fR to prevent special
+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 is generally
+safest to enclose \fIsubSpec\fR in braces if it includes
+backslashes.
+.LP
+If the initial arguments to \fBregsub\fR start with \fB\-\fR then
+they are treated as switches. The following switches are
+currently supported:
+.TP
+\fB\-all\fR
+.
+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
+.QW &
+and
+.QW \e\fIn\fR
+sequences are handled for each substitution using the information
+from the corresponding match.
+.TP
+\fB\-expanded\fR
+.
+Enables use of the expanded regular expression syntax where
+whitespace and comments are ignored. This is the same as specifying
+the \fB(?x)\fR embedded option (see the \fBre_syntax\fR manual page).
+.TP
+\fB\-line\fR
+.
+Enables newline-sensitive matching. By default, newline is a
+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
+.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
+\fB\-linestop\fR
+.
+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
+\fB\-lineanchor\fR
+.
+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).
+.TP
+\fB\-nocase\fR
+.
+Upper-case characters in \fIstring\fR will be converted to lower-case
+before matching against \fIexp\fR; however, substitutions specified
+by \fIsubSpec\fR use the original unconverted form of \fIstring\fR.
+.TP
+\fB\-start\fR \fIindex\fR
+.
+Specifies a character index offset into the string to start
+matching the regular expression at.
+The \fIindex\fR value is interpreted in the same manner
+as the \fIindex\fR argument to \fBstring index\fR.
+When using this switch,
+.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
+\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 \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.
+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:
+.PP
+.CS
+\fBregsub\fR -all {\emfoo\eM} $string bar string
+.CE
+.PP
+or (using the
+.QW "basic regular expression"
+syntax):
+.PP
+.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 capitalized.
+.PP
+.CS
+\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:
+.PP
+.CS
+# 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. 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), string(n)
+.SH KEYWORDS
+match, pattern, quoting, regular expression, substitution
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/rename.n b/pkgs/msgcat/doc/rename.n
new file mode 100644
index 0000000..77dc095
--- /dev/null
+++ b/pkgs/msgcat/doc/rename.n
@@ -0,0 +1,45 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH rename n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+rename \- Rename or delete a command
+.SH SYNOPSIS
+\fBrename \fIoldName newName\fR
+.BE
+.SH DESCRIPTION
+.PP
+Rename the command that used to be called \fIoldName\fR so that it
+is now called \fInewName\fR.
+If \fInewName\fR is an empty string then \fIoldName\fR is deleted.
+\fIoldName\fR and \fInewName\fR may include namespace qualifiers
+(names of containing namespaces).
+If a command is renamed into a different namespace,
+future invocations of it will execute in the new namespace.
+The \fBrename\fR command returns an empty string as result.
+.SH EXAMPLE
+.PP
+The \fBrename\fR command can be used to wrap the standard Tcl commands
+with your own monitoring machinery. For example, you might wish to
+count how often the \fBsource\fR command is called:
+.PP
+.CS
+\fBrename\fR ::source ::theRealSource
+set sourceCount 0
+proc ::source args {
+ global sourceCount
+ puts "called source for the [incr sourceCount]'th time"
+ uplevel 1 ::theRealSource $args
+}
+.CE
+.SH "SEE ALSO"
+namespace(n), proc(n)
+.SH KEYWORDS
+command, delete, namespace, rename
diff --git a/pkgs/msgcat/doc/return.n b/pkgs/msgcat/doc/return.n
new file mode 100644
index 0000000..b59a93d
--- /dev/null
+++ b/pkgs/msgcat/doc/return.n
@@ -0,0 +1,326 @@
+'\"
+'\" 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 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, or set return code of a script
+.SH SYNOPSIS
+\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
+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 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.
+\fICode\fR may have any of the following values:
+.TP 13
+\fBok\fR (or \fB0\fR)
+.
+Normal return: same as if the option is omitted. The return code
+of the procedure is 0 (\fBTCL_OK\fR).
+.TP 13
+\fBerror\fR (or \fB1\fR)
+.
+Error return: the return code of the procedure is 1 (\fBTCL_ERROR\fR).
+The procedure command behaves in its calling context as if it
+were the command \fBerror\fR \fIresult\fR. See below for additional
+options.
+.TP 13
+\fBreturn\fR (or \fB2\fR)
+.
+The return code of the procedure is 2 (\fBTCL_RETURN\fR). The
+procedure command behaves in its calling context as if it
+were the command \fBreturn\fR (with no arguments).
+.TP 13
+\fBbreak\fR (or \fB3\fR)
+.
+The return code of the procedure is 3 (\fBTCL_BREAK\fR). The
+procedure command behaves in its calling context as if it
+were the command \fBbreak\fR.
+.TP 13
+\fBcontinue\fR (or \fB4\fR)
+.
+The return code of the procedure is 4 (\fBTCL_CONTINUE\fR). The
+procedure command behaves in its calling context as if it
+were the command \fBcontinue\fR.
+.TP 13
+\fIvalue\fR
+.
+\fIValue\fR must be an integer; it will be returned as the
+return code for the current procedure.
+.LP
+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
+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.
+.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\-errorstack \fIlist\fR
+.VS 8.6
+The \fB\-errorstack\fR option receives special treatment only when the value
+of the \fB\-code\fR option is \fBTCL_ERROR\fR. Then \fIlist\fR is the initial
+error stack, recording actual argument values passed to each proc level. The error stack will
+also be reachable through \fBinfo errorstack\fR.
+If no \fB\-errorstack\fR option is provided to \fBreturn\fR when
+the \fB\-code error\fR option is provided, Tcl will provide its own
+initial error stack in the entry for \fB\-errorstack\fR. Tcl's
+initial error stack 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 \fIlist\fR value is supplied from
+the value of \fB\-errorstack\fR in a return options dictionary captured
+by the \fBcatch\fR command (or from the copy of that information from
+\fBinfo errorstack\fR).
+.VE 8.6
+.TP
+\fB\-level \fIlevel\fR
+.
+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.
+.TP
+\fB\-options \fIoptions\fR
+.
+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.
+.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
+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.
+.SH EXAMPLES
+.PP
+First, a simple example of using \fBreturn\fR to return from a
+procedure, interrupting the procedure body.
+.PP
+.CS
+proc printOneLine {} {
+ puts "line 1" ;# This line will be printed.
+ \fBreturn\fR
+ puts "line 2" ;# This line will not be printed.
+}
+.CE
+.PP
+Next, an example of using \fBreturn\fR to set the value
+returned by the procedure.
+.PP
+.CS
+proc returnX {} {\fBreturn\fR X}
+puts [returnX] ;# prints "X"
+.CE
+.PP
+Next, a more complete example, using \fBreturn -code error\fR
+to report invalid arguments.
+.PP
+.CS
+proc factorial {n} {
+ if {![string is integer $n] || ($n < 0)} {
+ \fBreturn\fR -code error \e
+ "expected non-negative integer,\e
+ but got \e"$n\e""
+ }
+ if {$n < 2} {
+ \fBreturn\fR 1
+ }
+ set m [expr {$n - 1}]
+ set code [catch {factorial $m} factor]
+ if {$code != 0} {
+ \fBreturn\fR -code $code $factor
+ }
+ set product [expr {$n * $factor}]
+ if {$product < 0} {
+ \fBreturn\fR -code error \e
+ "overflow computing factorial of $n"
+ }
+ \fBreturn\fR $product
+}
+.CE
+.PP
+Next, a procedure replacement for \fBbreak\fR.
+.PP
+.CS
+proc myBreak {} {
+ \fBreturn\fR -code break
+}
+.CE
+.PP
+With the \fB\-level 0\fR option, \fBreturn\fR itself can serve
+as a replacement for \fBbreak\fR, with the help of \fBinterp alias\fR.
+.PP
+.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:
+.PP
+.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:
+.PP
+.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
+.SH "SEE ALSO"
+break(n), catch(n), continue(n), dict(n), error(n), proc(n),
+source(n), tclvars(n), throw(n), try(n)
+.SH KEYWORDS
+break, catch, continue, error, exception, procedure, result, return
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/pkgs/msgcat/doc/safe.n b/pkgs/msgcat/doc/safe.n
new file mode 100644
index 0000000..ebd9b4d
--- /dev/null
+++ b/pkgs/msgcat/doc/safe.n
@@ -0,0 +1,359 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH "Safe Tcl" n 8.0 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+safe \- Creating and manipulating safe interpreters
+.SH SYNOPSIS
+\fB::safe::interpCreate\fR ?\fIslave\fR? ?\fIoptions...\fR?
+.sp
+\fB::safe::interpInit\fR \fIslave\fR ?\fIoptions...\fR?
+.sp
+\fB::safe::interpConfigure\fR \fIslave\fR ?\fIoptions...\fR?
+.sp
+\fB::safe::interpDelete\fR \fIslave\fR
+.sp
+\fB::safe::interpAddToAccessPath\fR \fIslave\fR \fIdirectory\fR
+.sp
+\fB::safe::interpFindInAccessPath\fR \fIslave\fR \fIdirectory\fR
+.sp
+\fB::safe::setLogCmd\fR ?\fIcmd arg...\fR?
+.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
+potentially dangerous functionality.
+.PP
+Safe Tcl ensures that untrusted Tcl scripts cannot harm the
+hosting application.
+It prevents integrity and privacy attacks. Untrusted Tcl
+scripts are prevented from corrupting the state of the hosting
+application or computer. Untrusted scripts are also prevented from
+disclosing information stored on the hosting computer or in the
+hosting application to any party.
+.PP
+Safe Tcl allows a master interpreter to create safe, restricted
+interpreters that contain a set of predefined aliases for the \fBsource\fR,
+\fBload\fR, \fBfile\fR, \fBencoding\fR, and \fBexit\fR commands and
+are able to use the auto-loading and package mechanisms.
+.PP
+No knowledge of the file system structure is leaked to the
+safe interpreter, because it has access only to a virtualized path
+containing tokens. When the safe interpreter requests to source a file, it
+uses the token in the virtual path as part of the file name to source; the
+master interpreter transparently
+translates the token into a real directory name and executes the
+requested operation (see the section \fBSECURITY\fR below for details).
+Different levels of security can be selected by using the optional flags
+of the commands described below.
+.PP
+All commands provided in the master interpreter by Safe Tcl reside in
+the \fBsafe\fR namespace.
+.SH COMMANDS
+The following commands are provided in the master interpreter:
+.TP
+\fB::safe::interpCreate\fR ?\fIslave\fR? ?\fIoptions...\fR?
+Creates a safe interpreter, installs the aliases described in the section
+\fBALIASES\fR and initializes the auto-loading and package mechanism as
+specified by the supplied \fIoptions\fR.
+See the \fBOPTIONS\fR section below for a description of the
+optional arguments.
+If the \fIslave\fR argument is omitted, a name will be generated.
+\fB::safe::interpCreate\fR always returns the interpreter name.
+.TP
+\fB::safe::interpInit\fR \fIslave\fR ?\fIoptions...\fR?
+This command is similar to \fBinterpCreate\fR except it that does not
+create the safe interpreter. \fIslave\fR must have been created by some
+other means, like \fBinterp create\fR \fB\-safe\fR.
+.TP
+\fB::safe::interpConfigure\fR \fIslave\fR ?\fIoptions...\fR?
+If no \fIoptions\fR are given, returns the settings for all options for the
+named safe interpreter as a list of options and their current values
+for that \fIslave\fR.
+If a single additional argument is provided,
+it will return a list of 2 elements \fIname\fR and \fIvalue\fR where
+\fIname\fR is the full name of that option and \fIvalue\fR the current value
+for that option and the \fIslave\fR.
+If more than two additional arguments are provided, it will reconfigure the
+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 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
+.CE
+.RE
+.TP
+\fB::safe::interpDelete\fR \fIslave\fR
+Deletes the safe interpreter and cleans up the corresponding
+master interpreter data structures.
+If a \fIdeleteHook\fR script was specified for this interpreter it is
+evaluated before the interpreter is deleted, with the name of the
+interpreter as an additional argument.
+.TP
+\fB::safe::interpFindInAccessPath\fR \fIslave\fR \fIdirectory\fR
+This command finds and returns the token for the real directory
+\fIdirectory\fR in the safe interpreter's current virtual access path.
+It generates an error if the directory is not found.
+Example of use:
+.RS
+.PP
+.CS
+$slave eval [list set tk_library \e
+ [::safe::interpFindInAccessPath $name $tk_library]]
+.CE
+.RE
+.TP
+\fB::safe::interpAddToAccessPath\fR \fIslave\fR \fIdirectory\fR
+This command adds \fIdirectory\fR to the virtual path maintained for the
+safe interpreter in the master, and returns the token that can be used in
+the safe interpreter to obtain access to files in that directory.
+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 \e
+ [::safe::interpAddToAccessPath $name $tk_library]]
+.CE
+.RE
+.TP
+\fB::safe::setLogCmd\fR ?\fIcmd arg...\fR?
+This command installs a script that will be called when interesting
+life cycle events occur for a safe interpreter.
+When called with no arguments, it returns the currently installed script.
+When called with one argument, an empty string, the currently installed
+script is removed and logging is turned off.
+The script will be invoked with one additional argument, a string
+describing the event of interest.
+The main purpose is to help in debugging safe interpreters.
+Using this facility you can get complete error messages while the safe
+interpreter gets only generic error messages.
+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=()
+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
+.SS OPTIONS
+The following options are common to
+\fB::safe::interpCreate\fR, \fB::safe::interpInit\fR,
+and \fB::safe::interpConfigure\fR.
+Any option name can be abbreviated to its minimal
+non-ambiguous name.
+Option names are not case sensitive.
+.TP
+\fB\-accessPath\fR \fIdirectoryList\fR
+This option sets the list of directories from which the safe interpreter
+can \fBsource\fR and \fBload\fR files.
+If this option is not specified, or if it is given as the
+empty list, the safe interpreter will use the same directories as its
+master for auto-loading.
+See the section \fBSECURITY\fR below for more detail about virtual paths,
+tokens and access control.
+.TP
+\fB\-statics\fR \fIboolean\fR
+This option specifies if the safe interpreter will be allowed
+to load statically linked packages (like \fBload {} Tk\fR).
+The default value is \fBtrue\fR :
+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
+thus specifies that the safe interpreter will not be allowed
+to load statically linked packages.
+.TP
+\fB\-nested\fR \fIboolean\fR
+This option specifies if the safe interpreter will be allowed
+to load packages into its own sub-interpreters.
+The default value is \fBfalse\fR :
+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
+thus specifies the safe interpreter will be allowed
+to load packages into its own sub-interpreters.
+.TP
+\fB\-deleteHook\fR \fIscript\fR
+When this option is given a non-empty \fIscript\fR, it will be
+evaluated in the master with the name of
+the safe interpreter as an additional argument
+just before actually deleting the safe interpreter.
+Giving an empty value removes any currently installed deletion hook
+script for that safe interpreter.
+The default value (\fB{}\fR) is not to have any deletion call back.
+.SH ALIASES
+The following aliases are provided in a safe interpreter:
+.TP
+\fBsource\fR \fIfileName\fR
+The requested file, a Tcl source file, is sourced into the safe interpreter
+if it is found.
+The \fBsource\fR alias can only source files from directories in
+the virtual path for the safe interpreter. The \fBsource\fR alias requires
+the safe interpreter to
+use one of the token names in its virtual path to denote the directory in
+which the file to be sourced can be found.
+See the section on \fBSECURITY\fR for more discussion of restrictions on
+valid filenames.
+.TP
+\fBload\fR \fIfileName\fR
+The requested file, a shared object file, is dynamically loaded into the
+safe interpreter if it is found.
+The filename must contain a token name mentioned in the virtual path for
+the safe interpreter for it to be found successfully.
+Additionally, the shared object file must contain a safe entry point; see
+the manual page for the \fBload\fR command for more details.
+.TP
+\fBfile\fR ?\fIsubCmd args...\fR?
+The \fBfile\fR alias provides access to a safe subset of the subcommands of
+the \fBfile\fR command; it allows only \fBdirname\fR, \fBjoin\fR,
+\fBextension\fR, \fBroot\fR, \fBtail\fR, \fBpathname\fR and \fBsplit\fR
+subcommands. For more details on what these subcommands do see the manual
+page for the \fBfile\fR command.
+.TP
+\fBencoding\fR ?\fIsubCmd args...\fR?
+The \fBencoding\fR alias provides access to a safe subset of the
+subcommands of the \fBencoding\fR command; it disallows setting of
+the system encoding, but allows all other subcommands including
+\fBsystem\fR to check the current encoding.
+.TP
+\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
+Safe Tcl does not attempt to completely prevent annoyance and
+denial of service attacks. These forms of attack prevent the
+application or user from temporarily using the computer to perform
+useful work, for example by consuming all available CPU time or
+all available screen real estate.
+These attacks, while aggravating, are deemed to be of lesser importance
+in general than integrity and privacy attacks that Safe Tcl
+is to prevent.
+.PP
+The commands available in a safe interpreter, in addition to
+the safe set as defined in \fBinterp\fR manual page, are mediated aliases
+for \fBsource\fR, \fBload\fR, \fBexit\fR, and safe subsets of
+\fBfile\fR and \fBencoding\fR. The safe interpreter can also auto-load
+code and it can request that packages be loaded.
+.PP
+Because some of these commands access the local file system, there is a
+potential for information leakage about its directory structure.
+To prevent this, commands that take file names as arguments in a safe
+interpreter use tokens instead of the real directory names.
+These tokens are translated to the real directory name while a request to,
+e.g., source a file is mediated by the master interpreter.
+This virtual path system is maintained in the master interpreter for each safe
+interpreter created by \fB::safe::interpCreate\fR or initialized by
+\fB::safe::interpInit\fR and
+the path maps tokens accessible in the safe interpreter into real path
+names on the local file system thus preventing safe interpreters
+from gaining knowledge about the
+structure of the file system of the host on which the interpreter is
+executing.
+The only valid file names arguments
+for the \fBsource\fR and \fBload\fR aliases provided to the slave
+are path in the form of
+\fB[file join \fItoken filename\fB]\fR (i.e. when using the
+native file path formats: \fItoken\fB/\fIfilename\fR
+on Unix and \fItoken\fB\e\fIfilename\fR on Windows),
+where \fItoken\fR is representing one of the directories
+of the \fIaccessPath\fR list and \fIfilename\fR is
+one file in that directory (no sub directories access are allowed).
+.PP
+When a token is used in a safe interpreter in a request to source or
+load a file, the token is checked and
+translated to a real path name and the file to be
+sourced or loaded is located on the file system.
+The safe interpreter never gains knowledge of the actual path name under
+which the file is stored on the file system.
+.PP
+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
+.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
+the slave \fBauto_path\fR and the first element of that list will be set as
+the \fBtcl_library\fR for that slave.
+.PP
+If the access path argument is not given or is the empty list,
+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 cannot be dangerous
+as they run in the slave interpreter) and C extensions that
+provides a _SafeInit entry point). For that purpose, the master's
+\fBauto_path\fR will be used to construct the slave access path.
+In order that the slave successfully loads the Tcl library files
+(which includes the auto-loading mechanism itself) the \fBtcl_library\fR will be
+added or moved to the first position if necessary, in the
+slave access path, so the slave
+\fBtcl_library\fR will be the same as the master's (its real
+path will still be invisible to the slave though).
+In order that auto-loading works the same for the slave and
+the master in this by default case, the first-level
+sub directories of each directory in the master \fBauto_path\fR will
+also be added (if not already included) to the slave access path.
+You can always specify a more
+restrictive path for which sub directories will never be searched by
+explicitly specifying your directory list with the \fB\-accessPath\fR flag
+instead of relying on this default mechanism.
+.PP
+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
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/scan.n b/pkgs/msgcat/doc/scan.n
new file mode 100644
index 0000000..cc5ed79
--- /dev/null
+++ b/pkgs/msgcat/doc/scan.n
@@ -0,0 +1,293 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Scriptics Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH scan n 8.4 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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 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 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
+the end of the input string is reached before any conversions have been
+performed.
+.SH "DETAILS ON SCANNING"
+.PP
+\fBScan\fR operates by scanning \fIstring\fR and \fIformat\fR together.
+If the next character in \fIformat\fR is a blank or tab then it
+matches any number of white space characters in \fIstring\fR (including
+zero).
+Otherwise, if it is not a \fB%\fR character then it
+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.
+A conversion specifier contains up to four fields after the \fB%\fR:
+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.
+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
+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.
+.SS "OPTIONAL POSITIONAL SPECIFIER"
+.PP
+If the \fB%\fR is followed by a decimal number and a \fB$\fR, as in
+.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
+specifiers must be positional. Every \fIvarName\fR on the argument
+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.
+.SS "OPTIONAL SIZE MODIFIER"
+.PP
+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.
+.SS "MANDATORY CONVERSION CHARACTER"
+.PP
+The following conversion characters are supported:
+.TP
+\fBd\fR
+.
+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
+\fBo\fR
+.
+The input substring must be an octal integer. It is read in and the
+integer value is stored in the variable,
+truncated as required by the size modifier value.
+.TP
+\fBx\fR
+.
+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
+\fBb\fR
+.
+The input substring must be a binary integer.
+It is read in and the integer value is stored in the variable,
+truncated as required by the size modifier value.
+.TP
+\fBu\fR
+.
+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
+\fBi\fR
+.
+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
+\fBc\fR
+.
+A single character is read in and its Unicode value is stored in
+the variable as an integer value.
+Initial white space is not skipped in this case, so the input
+substring may be a white-space character.
+.TP
+\fBs\fR
+.
+The input substring consists of all the characters up to the next
+white-space character; the characters are copied to the variable.
+.TP
+\fBe\fR or \fBf\fR or \fBg\fR
+.
+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 value.
+.TP
+\fB[\fIchars\fB]\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
+bracket for the set.
+If \fIchars\fR
+contains a sequence of the form \fIa\fB\-\fIb\fR then any
+character between \fIa\fR and \fIb\fR (inclusive) will match.
+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
+\fB[^\fIchars\fB]\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
+the set.
+If \fIchars\fR
+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 value.
+.TP
+\fBn\fR
+.
+No input is consumed from the input string. Instead, the total number
+of characters scanned from the input string so far is stored in the variable.
+.PP
+The number of characters read from the input for a conversion is the
+largest number that makes sense for that particular conversion (e.g.
+as many decimal digits as possible for \fB%d\fR, as
+many octal digits as possible for \fB%o\fR, and so on).
+The input substring for a given conversion terminates either when a
+white-space character is encountered or when the maximum substring
+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.
+.SH "DIFFERENCES FROM ANSI SSCANF"
+.PP
+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 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 substring width may be specified for this conversion.
+.IP [3]
+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). 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
+.PP
+Convert a UNICODE character to its numeric value:
+.PP
+.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 substring sizes:
+.PP
+.CS
+set string "#08D03F"
+\fBscan\fR $string "#%2x%2x%2x" r g b
+.CE
+.PP
+Parse a \fIHH:MM\fR time string, noting that this avoids problems with
+octal numbers by forcing interpretation as decimals (if we did not
+care, we would use the \fB%i\fR conversion instead):
+.PP
+.CS
+set string "08:08" ;# *Not* octal!
+if {[\fBscan\fR $string "%d:%d" hours minutes] != 2} {
+ error "not a valid time string"
+}
+# We have to understand numeric ranges ourselves...
+if {$minutes < 0 || $minutes > 59} {
+ error "invalid number of minutes"
+}
+.CE
+.PP
+Break a string up into sequences of non-whitespace characters (note
+the use of the \fB%n\fR conversion so that we get skipping over
+leading whitespace correct):
+.PP
+.CS
+set string " a string {with braced words} + leading space "
+set words {}
+while {[\fBscan\fR $string %s%n word length] == 2} {
+ lappend words $word
+ set string [string range $string $length end]
+}
+.CE
+.PP
+Parse a simple coordinate string, checking that it is complete by
+looking for the terminating character explicitly:
+.PP
+.CS
+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 \eu0029
+if {
+ [\fBscan\fR $string " (%f ,%f %c" x y last] != 3
+ || $last != 0x0029
+} then {
+ error "invalid coordinate string"
+}
+puts "X=$x, Y=$y"
+.CE
+.PP
+An interactive session demonstrating the truncation of integer
+values determined by size modifiers:
+.PP
+.CS
+\fI%\fR set tcl_platform(wordSize)
+4
+\fI%\fR scan 20000000000000000000 %d
+2147483647
+\fI%\fR scan 20000000000000000000 %ld
+9223372036854775807
+\fI%\fR scan 20000000000000000000 %lld
+20000000000000000000
+.CE
+.SH "SEE ALSO"
+format(n), sscanf(3)
+.SH KEYWORDS
+conversion specifier, parse, scan
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/seek.n b/pkgs/msgcat/doc/seek.n
new file mode 100644
index 0000000..96d5c4e
--- /dev/null
+++ b/pkgs/msgcat/doc/seek.n
@@ -0,0 +1,92 @@
+'\"
+'\" 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 seek n 8.1 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+seek \- Change the access position for an open channel
+.SH SYNOPSIS
+\fBseek \fIchannelId offset \fR?\fIorigin\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Changes the current access position for \fIchannelId\fR.
+.PP
+\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.
+.PP
+The \fIoffset\fR and \fIorigin\fR
+arguments specify the position at which the next read or write will occur
+for \fIchannelId\fR. \fIOffset\fR must be an integer (which may be
+negative) and \fIorigin\fR must be one of the following:
+.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
+The command flushes all buffered output for the channel before the command
+returns, even if the channel is in non-blocking mode.
+It also discards any buffered and unread input.
+This command returns an empty string.
+An error occurs if this command is applied to channels whose underlying
+file or device does not support seeking.
+.PP
+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.
+.SH EXAMPLES
+.PP
+Read a file twice:
+.PP
+.CS
+set f [open file.txt]
+set data1 [read $f]
+\fBseek\fR $f 0
+set data2 [read $f]
+close $f
+# $data1 eq $data2 if the file wasn't updated
+.CE
+.PP
+Read the last 10 bytes from a file:
+.PP
+.CS
+set f [open file.data]
+# This is guaranteed to work with binary data but
+# may fail with other encodings...
+fconfigure $f -translation binary
+\fBseek\fR $f -10 end
+set data [read $f 10]
+close $f
+.CE
+.SH "SEE ALSO"
+file(n), open(n), close(n), gets(n), tell(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+access position, file, seek
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/pkgs/msgcat/doc/self.n b/pkgs/msgcat/doc/self.n
new file mode 100644
index 0000000..2a04157
--- /dev/null
+++ b/pkgs/msgcat/doc/self.n
@@ -0,0 +1,152 @@
+'\"
+'\" Copyright (c) 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 self n 0.1 TclOO "TclOO Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+self \- method call internal introspection
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBself\fR ?\fIsubcommand\fR?
+.fi
+.BE
+.SH DESCRIPTION
+The \fBself\fR command, which should only be used from within the context of a
+call to a method (i.e. inside a method, constructor or destructor body) is
+used to allow the method to discover information about how it was called. It
+takes an argument, \fIsubcommand\fR, that tells it what sort of information is
+actually desired; if omitted the result will be the same as if \fBself
+object\fR was invoked. The supported subcommands are:
+.TP
+\fBself call\fR
+.
+This returns a two-element list describing the method implementations used to
+implement the current call chain. The first element is the same as would be
+reported by \fBinfo object\fR \fBcall\fR for the current method (except that this
+also reports useful values from within constructors and destructors, whose
+names are reported as \fB<constructor>\fR and \fB<destructor>\fR
+respectively), and the second element is an index into the first element's
+list that indicates which actual implementation is currently executing (the
+first implementation to execute is always at index 0).
+.TP
+\fBself caller\fR
+.
+When the method was invoked from inside another object method, this subcommand
+returns a three element list describing the containing object and method. The
+first element describes the declaring object or class of the method, the
+second element is the name of the object on which the containing method was
+invoked, and the third element is the name of the method (with the strings
+\fB<constructor>\fR and \fB<destructor>\fR indicating constructors and
+destructors respectively).
+.TP
+\fBself class\fR
+.
+This returns the name of the class that the current method was defined within.
+Note that this will change as the chain of method implementations is traversed
+with \fBnext\fR, and that if the method was defined on an object then this
+will fail.
+.RS
+.PP
+If you want the class of the current object, you need to use this other
+construct:
+.PP
+.CS
+info object class [\fBself object\fR]
+.CE
+.RE
+.TP
+\fBself filter\fR
+.
+When invoked inside a filter, this subcommand returns a three element list
+describing the filter. The first element gives the name of the object or class
+that declared the filter (note that this may be different from the object or
+class that provided the implementation of the filter), the second element is
+either \fBobject\fR or \fBclass\fR depending on whether the declaring entity
+was an object or class, and the third element is the name of the filter.
+.TP
+\fBself method\fR
+.
+This returns the name of the current method (with the strings
+\fB<constructor>\fR and \fB<destructor>\fR indicating constructors and
+destructors respectively).
+.TP
+\fBself namespace\fR
+.
+This returns the name of the unique namespace of the object that the method
+was invoked upon.
+.TP
+\fBself next\fR
+.
+When invoked from a method that is not at the end of a call chain (i.e. where
+the \fBnext\fR command will invoke an actual method implementation), this
+subcommand returns a two element list describing the next element in the
+method call chain; the first element is the name of the class or object that
+declares the next part of the call chain, and the second element is the name
+of the method (with the strings \fB<constructor>\fR and \fB<destructor>\fR
+indicating constructors and destructors respectively). If invoked from a
+method that is at the end of a call chain, this subcommand returns the empty
+string.
+.TP
+\fBself object\fR
+.
+This returns the name of the object that the method was invoked upon.
+.TP
+\fBself target\fR
+.
+When invoked inside a filter implementation, this subcommand returns a two
+element list describing the method being filtered. The first element will be
+the name of the declarer of the method, and the second element will be the
+actual name of the method.
+.SH EXAMPLES
+.PP
+This example shows basic use of \fBself\fR to provide information about the
+current object:
+.PP
+.CS
+oo::class create c {
+ method foo {} {
+ puts "this is the [\fBself\fR] object"
+ }
+}
+c create a
+c create b
+a foo \fI\(-> prints "this is the ::a object"\fR
+b foo \fI\(-> prints "this is the ::b object"\fR
+.CE
+.PP
+This demonstrates what a method call chain looks like, and how traversing
+along it changes the index into it:
+.PP
+.CS
+oo::class create c {
+ method x {} {
+ puts "Cls: [\fBself call\fR]"
+ }
+}
+c create a
+oo::objdefine a {
+ method x {} {
+ puts "Obj: [\fBself call\fR]"
+ next
+ puts "Obj: [\fBself call\fR]"
+ }
+}
+a x \fI\(-> Obj: {{method x object method} {method x ::c method}} 0\fR
+ \fI\(-> Cls: {{method x object method} {method x ::c method}} 1\fR
+ \fI\(-> Obj: {{method x object method} {method x ::c method}} 0\fR
+.CE
+.SH "SEE ALSO"
+info(n), next(n)
+.SH KEYWORDS
+call, introspection, object
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/pkgs/msgcat/doc/set.n b/pkgs/msgcat/doc/set.n
new file mode 100644
index 0000000..32a788e
--- /dev/null
+++ b/pkgs/msgcat/doc/set.n
@@ -0,0 +1,75 @@
+'\"
+'\" 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 set n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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 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,
+and the characters between the parentheses are the index within the array.
+Otherwise \fIvarName\fR refers to a scalar variable.
+.PP
+If \fIvarName\fR includes namespace qualifiers
+(in the array name if it refers to an array element), or if \fIvarName\fR
+is unqualified (does not include the names of any containing namespaces)
+but no procedure is active,
+\fIvarName\fR refers to a namespace variable
+resolved according to the rules described under \fBNAME RESOLUTION\fR in
+the \fBnamespace\fR manual page.
+.PP
+If a procedure is active and \fIvarName\fR is unqualified, then
+\fIvarName\fR refers to a parameter or local variable of the procedure,
+unless \fIvarName\fR was declared to resolve differently through one of the
+\fBglobal\fR, \fBvariable\fR or \fBupvar\fR commands.
+.SH EXAMPLES
+.PP
+Store a random number in the variable \fIr\fR:
+.PP
+.CS
+\fBset\fR r [expr {rand()}]
+.CE
+.PP
+Store a short message in an array element:
+.PP
+.CS
+\fBset\fR anAry(msg) "Hello, World!"
+.CE
+.PP
+Store a short message in an array element specified by a variable:
+.PP
+.CS
+\fBset\fR elemName "msg"
+\fBset\fR anAry($elemName) "Hello, World!"
+.CE
+.PP
+Copy a value into the variable \fIout\fR from a variable whose name is
+stored in the \fIvbl\fR (note that it is often easier to use arrays in
+practice instead of doing double-dereferencing):
+.PP
+.CS
+\fBset\fR in0 "small random"
+\fBset\fR in1 "large random"
+\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/pkgs/msgcat/doc/socket.n b/pkgs/msgcat/doc/socket.n
new file mode 100644
index 0000000..0a60457
--- /dev/null
+++ b/pkgs/msgcat/doc/socket.n
@@ -0,0 +1,227 @@
+'\"
+'\" Copyright (c) 1996 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.
+'\"
+.so man.macros
+.TH socket n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+socket \- Open a TCP network connection
+.SH SYNOPSIS
+.sp
+\fBsocket \fR?\fIoptions\fR? \fIhost port\fR
+.sp
+\fBsocket\fR \fB\-server \fIcommand\fR ?\fIoptions\fR? \fIport\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command opens a network socket and returns a channel identifier
+that may be used in future invocations of commands like \fBread\fR,
+\fBputs\fR and \fBflush\fR. At present only the TCP network protocol
+is supported over IPv4 and IPv6; future releases may include support
+for additional protocols. The \fBsocket\fR command may be used to
+open either the client or server side of a connection, depending on
+whether the \fB\-server\fR switch is specified.
+.PP
+Note that the default encoding for \fIall\fR sockets is the system
+encoding, as returned by \fBencoding system\fR. Most of the time, you
+will need to use \fBchan configure\fR to alter this to something else,
+such as \fIutf\-8\fR (ideal for communicating with other Tcl
+processes) or \fIiso8859\-1\fR (useful for many network protocols,
+especially the older ones).
+.SH "CLIENT SOCKETS"
+.PP
+If the \fB\-server\fR option is not specified, then the client side of a
+connection is opened and the command returns a channel identifier
+that can be used for both reading and writing.
+\fIPort\fR and \fIhost\fR specify a port
+to connect to; there must be a server accepting connections on
+this port. \fIPort\fR is an integer port number
+(or service name, where supported and understood by the host operating
+system) and \fIhost\fR
+is either a domain-style name such as \fBwww.tcl.tk\fR or
+a numerical IPv4 or IPv6 address such as \fB127.0.0.1\fR or \fB2001:DB8::1\fR.
+Use \fIlocalhost\fR to refer to the host on which the command is invoked.
+.PP
+The following options may also be present before \fIhost\fR
+to specify additional information about the connection:
+.TP
+\fB\-myaddr\fI addr\fR
+.
+\fIAddr\fR gives the domain-style name or numerical IP address of
+the client-side network interface to use for the connection.
+This option may be useful if the client machine has multiple network
+interfaces. If the option is omitted then the client-side interface
+will be chosen by the system software.
+.TP
+\fB\-myport\fI port\fR
+.
+\fIPort\fR specifies an integer port number (or service name, where
+supported and understood by the host operating system) to use for the
+client's
+side of the connection. If this option is omitted, the client's
+port number will be chosen at random by the system software.
+.TP
+\fB\-async\fR
+.
+This option will cause the client socket to be connected
+asynchronously. This means that the socket will be created immediately
+but may not yet be connected to the server, when the call to
+\fBsocket\fR returns.
+.RS
+.PP
+When a \fBgets\fR or \fBflush\fR is done on the socket before the
+connection attempt succeeds or fails, if the socket is in blocking
+mode, the operation will wait until the connection is completed or
+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. Synchronous client sockets may
+be switched (after they have connected) to operating in asynchronous
+mode using:
+.PP
+.CS
+\fBchan configure \fIchan \fB\-blocking 0\fR
+.CE
+.PP
+See the \fBchan configure\fR command for more details.
+.PP
+The Tcl event loop should be running while an asynchronous connection
+is in progress, because it may have to do several connection attempts
+in the background. Running the event loop also allows you to set up a
+writable channel event on the socket to get notified when the
+asynchronous connection has succeeded or failed. See the \fBvwait\fR
+and the \fBchan\fR commands for more details on the event loop and
+channel events.
+.RE
+.SH "SERVER SOCKETS"
+.PP
+If the \fB\-server\fR option is specified then the new socket will be
+a server that listens on the given \fIport\fR (either an integer or a
+service name, where supported and understood by the host operating
+system; if \fIport\fR is zero, the operating system will allocate a
+free port to the server socket which may be discovered by using
+\fBchan configure\fR to read the \fB\-sockname\fR option). If the host
+supports both, IPv4 and IPv6, the socket will listen on both address
+families. Tcl will automatically accept connections to the given port.
+For each connection Tcl will create a new channel that may be used to
+communicate with the client. Tcl then invokes \fIcommand\fR (properly
+a command prefix list, see the \fBEXAMPLES\fR below) 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 \fIport\fR:
+.TP
+\fB\-myaddr\fI addr\fR
+.
+\fIAddr\fR gives the domain-style name or numerical IP address of the
+server-side network interface to use for the connection. This option
+may be useful if the server machine has multiple network interfaces.
+If the option is omitted then the server socket is bound to the
+wildcard address so that it can accept connections from any
+interface. If \fIaddr\fR is a domain name that resolves to multiple IP
+addresses that are available on the local machine, the socket will
+listen on all of them.
+.PP
+Server channels cannot be used for input or output; their sole use is to
+accept new client connections. The channels created for each incoming
+client connection are opened for input and output. Closing the server
+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 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.
+.PP
+If \fIport\fR is specified as zero, the operating system will allocate
+an unused port for use as a server socket. The port number actually
+allocated may be retrieved from the created server socket using the
+\fBchan configure\fR command to retrieve the \fB\-sockname\fR option as
+described below.
+.SH "CONFIGURATION OPTIONS"
+.PP
+The \fBchan configure\fR command can be used to query several readonly
+configuration options for socket channels:
+.TP
+\fB\-error\fR
+.
+This option gets the current error status of the given socket. This
+is useful when you need to determine if an asynchronous connect
+operation succeeded. If there was an error, the error message is
+returned. If there was no error, an empty string is returned.
+.RS
+.PP
+Note that the error status is reset by the read operation; this mimics
+the underlying getsockopt(SO_ERROR) call.
+.RE
+.TP
+\fB\-sockname\fR
+.
+For client sockets (including the channels that get created when a
+client connects to a server socket) this option returns a list of
+three elements, the address, the host name and the port number for the
+socket. If the host name cannot be computed, the second element is
+identical to the address, the first element of the list.
+.RS
+.PP
+For server sockets this option returns a list of a multiple of three
+elements each group of which have the same meaning as described
+above. The list contains more than one group when the server socket
+was created without \fB\-myaddr\fR or with the argument to
+\fB\-myaddr\fR being a domain name that resolves multiple IP addresses
+that are local to the invoking host.
+.RE
+.TP
+\fB\-peername\fR
+.
+This option is not supported by server sockets. For client and accepted
+sockets, this option returns a list of three elements; these are the
+address, the host name and the port to which the peer socket is connected
+or bound. If the host name cannot be computed, the second element of the
+list is identical to the address, its first element.
+.PP
+.SH "EXAMPLES"
+.PP
+Here is a very simple time server:
+.PP
+.CS
+proc Server {startTime channel clientaddr clientport} {
+ puts "Connection from $clientaddr registered"
+ set now [clock seconds]
+ puts $channel [clock format $now]
+ puts $channel "[expr {$now - $startTime}] since start"
+ close $channel
+}
+
+\fBsocket -server\fR [list Server [clock seconds]] 9900
+vwait forever
+.CE
+.PP
+And here is the corresponding client to talk to the server and extract
+some information:
+.PP
+.CS
+set server localhost
+set sockChan [\fBsocket\fR $server 9900]
+gets $sockChan line1
+gets $sockChan line2
+close $sockChan
+puts "The time on $server is $line1"
+puts "That is [lindex $line2 0]s since the server started"
+.CE
+.SH "HISTORY"
+Support for IPv6 was added in Tcl 8.6.
+.SH "SEE ALSO"
+chan(n), flush(n), open(n), read(n)
+.SH KEYWORDS
+asynchronous I/O, bind, channel, connection, domain name, host, network address, socket, tcp
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/source.n b/pkgs/msgcat/doc/source.n
new file mode 100644
index 0000000..57a9fa2
--- /dev/null
+++ b/pkgs/msgcat/doc/source.n
@@ -0,0 +1,69 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Scriptics Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH source n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+source \- Evaluate a file or resource as a Tcl script
+.SH SYNOPSIS
+\fBsource \fIfileName\fR
+.sp
+\fBsource\fR \fB\-encoding \fIencodingName fileName\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command takes the contents of the specified file or resource
+and passes it to the Tcl interpreter as a text script. The return
+value from \fBsource\fR is the return value of the last command
+executed in the script. If an error occurs in evaluating the contents
+of the script then the \fBsource\fR command will return that error.
+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
+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
+.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 \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.
+.SH EXAMPLE
+.PP
+Run the script in the file \fBfoo.tcl\fR and then the script in the
+file \fBbar.tcl\fR:
+.PP
+.CS
+\fBsource\fR foo.tcl
+\fBsource\fR bar.tcl
+.CE
+.PP
+Alternatively:
+.PP
+.CS
+foreach scriptFile {foo.tcl bar.tcl} {
+ \fBsource\fR $scriptFile
+}
+.CE
+.SH "SEE ALSO"
+file(n), cd(n), encoding(n), info(n)
+.SH KEYWORDS
+file, script
diff --git a/pkgs/msgcat/doc/split.n b/pkgs/msgcat/doc/split.n
new file mode 100644
index 0000000..e3259df
--- /dev/null
+++ b/pkgs/msgcat/doc/split.n
@@ -0,0 +1,93 @@
+'\"
+'\" 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 split n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+split \- Split a string into a proper Tcl list
+.SH SYNOPSIS
+\fBsplit \fIstring \fR?\fIsplitChars\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Returns a list created by splitting \fIstring\fR at each character
+that is in the \fIsplitChars\fR argument.
+Each element of the result list will consist of the
+characters from \fIstring\fR that lie between instances of the
+characters in \fIsplitChars\fR.
+Empty list elements will be generated if \fIstring\fR contains
+adjacent characters in \fIsplitChars\fR, or if the first or last
+character of \fIstring\fR is in \fIsplitChars\fR.
+If \fIsplitChars\fR is an empty string then each character of
+\fIstring\fR becomes a separate element of the result list.
+\fISplitChars\fR defaults to the standard white-space characters.
+.SH EXAMPLES
+.PP
+Divide up a USENET group name into its hierarchical components:
+.PP
+.CS
+\fBsplit\fR "comp.lang.tcl" .
+ \fI\(-> comp lang tcl\fR
+.CE
+.PP
+See how the \fBsplit\fR command splits on \fIevery\fR character in
+\fIsplitChars\fR, which can result in information loss if you are not
+careful:
+.PP
+.CS
+\fBsplit\fR "alpha beta gamma" "temp"
+ \fI\(-> al {ha b} {} {a ga} {} a\fR
+.CE
+.PP
+Extract the list words from a string that is not a well-formed list:
+.PP
+.CS
+\fBsplit\fR "Example with {unbalanced brace character"
+ \fI\(-> Example with \e{unbalanced brace character\fR
+.CE
+.PP
+Split a string into its constituent characters
+.PP
+.CS
+\fBsplit\fR "Hello world" {}
+ \fI\(-> H e l l o { } w o r l d\fR
+.CE
+.SS "PARSING RECORD-ORIENTED FILES"
+.PP
+Parse a Unix /etc/passwd file, which consists of one entry per line,
+with each line consisting of a colon-separated list of fields:
+.PP
+.CS
+## Read the file
+set fid [open /etc/passwd]
+set content [read $fid]
+close $fid
+
+## Split into records on newlines
+set records [\fBsplit\fR $content "\en"]
+
+## Iterate over the records
+foreach rec $records {
+
+ ## Split into fields on colons
+ set fields [\fBsplit\fR $rec ":"]
+
+ ## Assign fields to variables and print some out...
+ lassign $fields \e
+ userName password uid grp longName homeDir shell
+ puts "$longName uses [file tail $shell] for a login shell"
+}
+.CE
+.SH "SEE ALSO"
+join(n), list(n), string(n)
+.SH KEYWORDS
+list, split, string
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/string.n b/pkgs/msgcat/doc/string.n
new file mode 100644
index 0000000..1cbea16
--- /dev/null
+++ b/pkgs/msgcat/doc/string.n
@@ -0,0 +1,441 @@
+.\"
+.\" 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!
+.SH NAME
+string \- Manipulate strings
+.SH SYNOPSIS
+\fBstring \fIoption arg \fR?\fIarg ...?\fR
+.BE
+.SH DESCRIPTION
+.PP
+Performs one of several string operations, depending on \fIoption\fR.
+The legal \fIoption\fRs (which may be abbreviated) are:
+.TP
+\fBstring bytelength \fIstring\fR
+.
+Returns a decimal string giving the number of bytes used to represent
+\fIstring\fR in memory. Because UTF\-8 uses one to three bytes to
+represent Unicode characters, the byte length will not be the same as
+the character length in general. The cases where a script cares about
+the byte length are rare. In almost all cases, you should use the
+\fBstring length\fR operation (including determining the length of a
+Tcl ByteArray object). Refer to the \fBTcl_NumUtfChars\fR manual
+entry for more details on the UTF\-8 representation.
+.RS
+.PP
+\fICompatibility note:\fR it is likely that this subcommand will be
+withdrawn in a future version of Tcl. It is better to use the
+\fBencoding convertto\fR command to convert a string to a known
+encoding and then apply \fBstring length\fR to that.
+.RE
+.TP
+\fBstring compare\fR ?\fB\-nocase\fR? ?\fB\-length int\fR? \fIstring1 string2\fR
+.
+Perform a character-by-character comparison of strings \fIstring1\fR
+and \fIstring2\fR. Returns \-1, 0, or 1, depending on whether
+\fIstring1\fR is lexicographically less than, equal to, or greater
+than \fIstring2\fR. If \fB\-length\fR is specified, then only 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 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
+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 \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 described in \fBSTRING INDICES\fR), then the search is
+constrained to start with the character in \fIhaystackString\fR specified by
+the index. For example,
+.RS
+.PP
+.CS
+\fBstring first a 0a23456789abcdef 5\fR
+.CE
+.PP
+will return \fB10\fR, but
+.PP
+.CS
+\fBstring first a 0123456789abcdef 11\fR
+.CE
+.PP
+will return \fB\-1\fR.
+.RE
+.TP
+\fBstring index \fIstring charIndex\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 described in the
+\fBSTRING INDICES\fR section.
+.RS
+.PP
+If \fIcharIndex\fR is less than 0 or greater than or equal to the
+length of the string then this command returns an empty string.
+.RE
+.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 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
+will not be set if \fBstring is\fR returns 1. The following character
+classes are recognized (the class name can be abbreviated):
+.RS
+.IP \fBalnum\fR 12
+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 \eu0080 (those that are in the
+7\-bit ascii range).
+.IP \fBboolean\fR 12
+Any of the forms allowed to \fBTcl_GetBoolean\fR.
+.IP \fBcontrol\fR 12
+Any Unicode control character.
+.IP \fBdigit\fR 12
+Any Unicode digit character. Note that this includes characters
+outside of the [0\-9] range.
+.IP \fBdouble\fR 12
+Any of the valid forms for a double in Tcl, with optional surrounding
+whitespace. In case of under/overflow in the value, 0 is returned and
+the \fIvarname\fR will contain \-1.
+.IP \fBentier\fR 12
+.VS 8.6
+Any of the valid string formats for an integer value of arbitrary size
+in Tcl, with optional surrounding whitespace. The formats accepted are
+exactly those accepted by the C routine \fBTcl_GetBignumFromObj\fR.
+.VE
+.IP \fBfalse\fR 12
+Any of the forms allowed to \fBTcl_GetBoolean\fR where the value is
+false.
+.IP \fBgraph\fR 12
+Any Unicode printing character, except space.
+.IP \fBinteger\fR 12
+Any of the valid string formats for a 32-bit integer value in Tcl,
+with optional surrounding whitespace. In case of under/overflow in
+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
+Any Unicode printing character, including space.
+.IP \fBpunct\fR 12
+Any Unicode punctuation character.
+.IP \fBspace\fR 12
+Any Unicode space character.
+.IP \fBtrue\fR 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.
+.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.
+.IP \fBwordchar\fR 12
+Any Unicode word character. That is any alphanumeric character, and
+any Unicode connector punctuation characters (e.g. underscore).
+.IP \fBxdigit\fR 12
+Any hexadecimal digit character ([0\-9A\-Fa\-f]).
+.PP
+In the case of \fBboolean\fR, \fBtrue\fR and \fBfalse\fR, if the
+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 \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 described in \fBSTRING INDICES\fR), then only the
+characters in \fIhaystackString\fR at or before the specified \fIlastIndex\fR
+will be considered by the search. For example,
+.RS
+.PP
+.CS
+\fBstring last a 0a23456789abcdef 15\fR
+.CE
+.PP
+will return \fB10\fR, but
+.PP
+.CS
+\fBstring last a 0a23456789abcdef 9\fR
+.CE
+.PP
+will return \fB1\fR.
+.RE
+.TP
+\fBstring length \fIstring\fR
+.
+Returns a decimal string giving the number of characters in
+\fIstring\fR. Note that this is not necessarily the same as the
+number of bytes used to store the string. If the object is a
+ByteArray object (such as those returned from reading a binary encoded
+channel), then this will return the actual byte length of the object.
+.TP
+\fBstring map\fR ?\fB\-nocase\fR? \fImapping string\fR
+.
+Replaces substrings in \fIstring\fR based on the key-value pairs in
+\fImapping\fR. \fImapping\fR is a list of \fIkey value key value ...\fR
+as in the form returned by \fBarray get\fR. Each instance of a
+key in the string will be replaced with its corresponding value. If
+\fB\-nocase\fR is specified, then matching is done without regard to
+case differences. Both \fIkey\fR and \fIvalue\fR may be multiple
+characters. Replacement is done in an ordered manner, so the key
+appearing first in the list will be checked first, and so on.
+\fIstring\fR is only iterated over once, so earlier key replacements
+will have no affect for later key matches. For example,
+.RS
+.PP
+.CS
+\fBstring map {abc 1 ab 2 a 3 1 0} 1abcaababcabababc\fR
+.CE
+.PP
+will return the string \fB01321221\fR.
+.PP
+Note that if an earlier \fIkey\fR is a prefix of a later one, it will
+completely mask the later one. So if the previous example is
+reordered like this,
+.PP
+.CS
+\fBstring map {1 0 ab 2 a 3 abc 1} 1abcaababcabababc\fR
+.CE
+.PP
+it will return the string \fB02c322c222c\fR.
+.RE
+.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 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:
+.RS
+.IP \fB*\fR 10
+Matches any sequence of characters in \fIstring\fR, including a null
+string.
+.IP \fB?\fR 10
+Matches any single character in \fIstring\fR.
+.IP \fB[\fIchars\fB]\fR 10
+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
+.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
+\fIpattern\fR.
+.RE
+.TP
+\fBstring range \fIstring first last\fR
+.
+Returns a range of consecutive characters from \fIstring\fR, starting
+with the character whose index is \fIfirst\fR and ending with the
+character whose index is \fIlast\fR. An index of 0 refers to the first
+character of the string. \fIfirst\fR and \fIlast\fR may be specified
+as for the \fBindex\fR method. If \fIfirst\fR is less than zero then
+it is treated as if it were zero, 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 then an empty
+string is returned.
+.TP
+\fBstring repeat \fIstring count\fR
+.
+Returns \fIstring\fR repeated \fIcount\fR number of times.
+.TP
+\fBstring replace \fIstring first last\fR ?\fInewstring\fR?
+.
+Removes a range of consecutive characters from \fIstring\fR, starting
+with the character whose index is \fIfirst\fR and ending with the
+character whose index is \fIlast\fR. An index of 0 refers to the
+first character of the string. \fIFirst\fR and \fIlast\fR may be
+specified as for the \fBindex\fR method. If \fInewstring\fR is
+specified, then it is placed in the removed character range. If
+\fIfirst\fR is less than zero then it is treated as if it were zero,
+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.
+.TP
+\fBstring reverse \fIstring\fR
+.
+Returns a string that is the same length as \fIstring\fR but with its
+characters in the reverse order.
+.TP
+\fBstring tolower \fIstring\fR ?\fIfirst\fR? ?\fIlast\fR?
+.
+Returns a value equal to \fIstring\fR except that all upper (or title)
+case letters have been converted to lower case. If \fIfirst\fR is
+specified, it refers to the first char index in the string to start
+modifying. If \fIlast\fR is specified, it refers to the char index in
+the string to stop at (inclusive). \fIfirst\fR and \fIlast\fR may be
+specified using the forms described in \fBSTRING INDICES\fR.
+.TP
+\fBstring totitle \fIstring\fR ?\fIfirst\fR? ?\fIlast\fR?
+.
+Returns a value equal to \fIstring\fR except that the first character
+in \fIstring\fR is converted to its Unicode title case variant (or
+upper case if there is no title case variant) and the rest of the
+string is converted to lower case. If \fIfirst\fR is specified, it
+refers to the first char index in the string to start modifying. If
+\fIlast\fR is specified, it refers to the char index in the string to
+stop at (inclusive). \fIfirst\fR and \fIlast\fR may be specified
+using the forms described in \fBSTRING INDICES\fR.
+.TP
+\fBstring toupper \fIstring\fR ?\fIfirst\fR? ?\fIlast\fR?
+.
+Returns a value equal to \fIstring\fR except that all lower (or title)
+case letters have been converted to upper case. If \fIfirst\fR is
+specified, it refers to the first char index in the string to start
+modifying. If \fIlast\fR is specified, it refers to the char index in
+the string to stop at (inclusive). \fIfirst\fR and \fIlast\fR may be
+specified using the forms described in \fBSTRING INDICES\fR.
+.TP
+\fBstring trim \fIstring\fR ?\fIchars\fR?
+.
+Returns a value equal to \fIstring\fR except that any leading or
+trailing characters present in the string given by \fIchars\fR are removed. If
+\fIchars\fR is not specified then white space is removed (spaces,
+tabs, newlines, and carriage returns).
+.TP
+\fBstring trimleft \fIstring\fR ?\fIchars\fR?
+.
+Returns a value equal to \fIstring\fR except that any leading
+characters present in the string given by \fIchars\fR are removed. If
+\fIchars\fR is not specified then white space is removed (spaces,
+tabs, newlines, and carriage returns).
+.TP
+\fBstring trimright \fIstring\fR ?\fIchars\fR?
+.
+Returns a value equal to \fIstring\fR except that any trailing
+characters present in the string given by \fIchars\fR are removed. If
+\fIchars\fR is not specified then white space is removed (spaces,
+tabs, newlines, and carriage returns).
+.TP
+\fBstring wordend \fIstring charIndex\fR
+.
+Returns the index of the character just after the last one in the word
+containing character \fIcharIndex\fR of \fIstring\fR. \fIcharIndex\fR
+may be specified using the forms in \fBSTRING INDICES\fR. A word is
+considered to be any contiguous range of alphanumeric (Unicode letters
+or decimal digits) or underscore (Unicode connector punctuation)
+characters, or any single character other than these.
+.TP
+\fBstring wordstart \fIstring charIndex\fR
+.
+Returns the index of the first character in the word containing character
+\fIcharIndex\fR of \fIstring\fR. \fIcharIndex\fR may be specified using the
+forms in \fBSTRING INDICES\fR. A word is considered to be any contiguous
+range of alphanumeric (Unicode letters or decimal digits) or underscore
+(Unicode connector punctuation) characters, or any single character other than
+these.
+.SH "STRING INDICES"
+.PP
+When referring to indices into a string (e.g., for \fBstring index\fR
+or \fBstring range\fR) the following formats are supported:
+.IP \fIinteger\fR 10
+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 (e.g., \fBend\fR would refer to the
+.QW d
+in
+.QW abcd ).
+.IP \fBend\-\fIN\fR 10
+The last char of the string minus the specified integer offset \fIN\fR (e.g.,
+.QW \fBend\-1\fR
+would refer to the
+.QW c
+in
+.QW abcd ).
+.IP \fBend+\fIN\fR 10
+The last char of the string plus the specified integer offset \fIN\fR (e.g.,
+.QW \fBend+\-1\fR
+would refer to the
+.QW c
+in
+.QW abcd ).
+.IP \fIM\fB+\fIN\fR 10
+The char specified at the integral index that is the sum of
+integer values \fIM\fR and \fIN\fR (e.g.,
+.QW \fB1+1\fR
+would refer to the
+.QW c
+in
+.QW abcd ).
+.IP \fIM\fB\-\fIN\fR 10
+The char specified at the integral index that is the difference of
+integer values \fIM\fR and \fIN\fR (e.g.,
+.QW \fB2\-1\fR
+would refer to the
+.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.
+.SH EXAMPLE
+.PP
+Test if the string in the variable \fIstring\fR is a proper non-empty
+prefix of the string \fBfoobar\fR.
+.PP
+.CS
+set length [\fBstring length\fR $string]
+if {$length == 0} {
+ set isPrefix 0
+} else {
+ set isPrefix [\fBstring equal\fR \-length $length $string "foobar"]
+}
+.CE
+.SH "SEE ALSO"
+expr(n), list(n)
+.SH KEYWORDS
+case conversion, compare, index, match, pattern, string, word, equal,
+ctype, character, reverse
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/pkgs/msgcat/doc/subst.n b/pkgs/msgcat/doc/subst.n
new file mode 100644
index 0000000..aba2bc9
--- /dev/null
+++ b/pkgs/msgcat/doc/subst.n
@@ -0,0 +1,164 @@
+'\"
+'\" Copyright (c) 1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 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 subst n 7.4 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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,
+and backslash substitutions on its \fIstring\fR argument and
+returns the fully-substituted result.
+The substitutions are performed in exactly the same way as for
+Tcl commands.
+As a result, the \fIstring\fR argument is actually substituted twice,
+once by the Tcl parser in the usual fashion for Tcl commands, and
+again by the \fIsubst\fR command.
+.PP
+If any of the \fB\-nobackslashes\fR, \fB\-nocommands\fR, or
+\fB\-novariables\fR are specified, then the corresponding substitutions
+are not performed.
+For example, if \fB\-nocommands\fR is specified, command substitution
+is not performed: open and close brackets are treated as ordinary characters
+with no special interpretation.
+.PP
+Note that the substitution of one kind can include substitution of
+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
+\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
+substitution, the result of the whole substitution will be the
+string (as substituted) up to the start of the substitution that
+raised the exception. If a continue exception occurs during the
+evaluation of a command or variable substitution, an empty string
+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 \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.
+.SH EXAMPLES
+.PP
+When it performs its substitutions, \fIsubst\fR does not give any
+special treatment to double quotes or curly braces (except within
+command substitutions) so the script
+.PP
+.CS
+set a 44
+\fBsubst\fR {xyz {$a}}
+.CE
+.PP
+returns
+.QW "\fBxyz {44}\fR" ,
+not
+.QW "\fBxyz {$a}\fR"
+and the script
+.PP
+.CS
+set a "p\e} q \e{r"
+\fBsubst\fR {xyz {$a}}
+.CE
+.PP
+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.
+.PP
+.CS
+set a 44
+\fBsubst\fR -novariables {$a [format $a]}
+.CE
+.PP
+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.
+.PP
+.CS
+proc b {} {return c}
+array set a {c c [b] tricky}
+\fBsubst\fR -nocommands {[b] $a([b])}
+.CE
+.PP
+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
+rest of \fIstring\fR respectively, giving script authors more options
+when processing text using \fIsubst\fR. For example, the script
+.PP
+.CS
+\fBsubst\fR {abc,[break],def}
+.CE
+.PP
+returns
+.QW \fBabc,\fR ,
+not
+.QW \fBabc,,def\fR
+and the script
+.PP
+.CS
+\fBsubst\fR {abc,[continue;expr {1+2}],def}
+.CE
+.PP
+returns
+.QW \fBabc,,def\fR ,
+not
+.QW \fBabc,3,def\fR .
+.PP
+Other exceptional return codes substitute the returned value
+.PP
+.CS
+\fBsubst\fR {abc,[return foo;expr {1+2}],def}
+.CE
+.PP
+returns
+.QW \fBabc,foo,def\fR ,
+not
+.QW \fBabc,3,def\fR
+and
+.PP
+.CS
+\fBsubst\fR {abc,[return -code 10 foo;expr {1+2}],def}
+.CE
+.PP
+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, quoting, substitution, variable substitution
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/pkgs/msgcat/doc/switch.n b/pkgs/msgcat/doc/switch.n
new file mode 100644
index 0000000..acde6cb
--- /dev/null
+++ b/pkgs/msgcat/doc/switch.n
@@ -0,0 +1,186 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH switch n 8.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+switch \- Evaluate one of several scripts, depending on a given value
+.SH SYNOPSIS
+\fBswitch \fR?\fIoptions\fR?\fI string pattern body \fR?\fIpattern body \fR...?
+.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
+the \fIpattern\fR arguments in order.
+As soon as it finds a \fIpattern\fR that matches \fIstring\fR it
+evaluates the following \fIbody\fR argument by passing it recursively
+to the Tcl interpreter and returns the result of that evaluation.
+If the last \fIpattern\fR argument is \fBdefault\fR then it matches
+anything.
+If no \fIpattern\fR argument
+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
+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).
+The following options are currently supported:
+.TP 10
+\fB\-exact\fR
+.
+Use exact matching when comparing \fIstring\fR to a pattern. This
+is the default.
+.TP 10
+\fB\-glob\fR
+.
+When matching \fIstring\fR to the patterns, use glob-style matching
+(i.e. the same as implemented by the \fBstring match\fR command).
+.TP 10
+\fB\-regexp\fR
+.
+When matching \fIstring\fR to the patterns, use regular
+expression matching
+(as described in the \fBre_syntax\fR reference page).
+.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.
+.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.
+This is not required when the matching patterns and bodies are grouped
+together in a single argument.
+.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;
+this form is convenient if substitutions are desired on some of the
+patterns or commands.
+The second form places all of the patterns and commands together into
+a single argument; the argument must have proper list structure, with
+the elements of the list being the patterns and commands.
+The second form makes it easy to construct multi-line switch commands,
+since the braces around the whole list make it unnecessary to include a
+backslash at the end of each line.
+Since the \fIpattern\fR arguments are in braces in the second form,
+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
+.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
+.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.
+.PP
+Beware of how you place comments in \fBswitch\fR commands. Comments
+should only be placed \fBinside\fR the execution body of one of the
+patterns, and not intermingled with the patterns.
+.SH "EXAMPLES"
+.PP
+The \fBswitch\fR command can match against variables and not just
+literals, as shown here (the result is \fI2\fR):
+.PP
+.CS
+set foo "abc"
+\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
+writing regular expressions with alternations, as can be seen here
+(this returns \fI1\fR):
+.PP
+.CS
+\fBswitch\fR \-glob aaab {
+ a*b \-
+ b {expr {1}}
+ a* {expr {2}}
+ default {expr {3}}
+}
+.CE
+.PP
+Whenever nothing matches, the \fBdefault\fR clause (which must be
+last) is taken. This example has a result of \fI3\fR:
+.PP
+.CS
+\fBswitch\fR xyz {
+ a \-
+ b {
+ # Correct Comment Placement
+ expr {1}
+ }
+ c {
+ expr {2}
+ }
+ default {
+ expr {3}
+ }
+}
+.CE
+.PP
+When matching against regular expressions, information about what
+exactly matched is easily obtained using the \fB\-matchvar\fR option:
+.PP
+.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
+.SH "SEE ALSO"
+for(n), if(n), regexp(n)
+.SH KEYWORDS
+switch, match, regular expression
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/pkgs/msgcat/doc/tailcall.n b/pkgs/msgcat/doc/tailcall.n
new file mode 100644
index 0000000..6a88aca
--- /dev/null
+++ b/pkgs/msgcat/doc/tailcall.n
@@ -0,0 +1,69 @@
+'\"
+'\" 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 tailcall n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+tailcall \- Replace the current procedure with another command
+.SH SYNOPSIS
+\fBtailcall \fIcommand\fR ?\fIarg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fBtailcall\fR command replaces the currently executing procedure, lambda
+application, or method with another command. The \fIcommand\fR, which will
+have \fIarg ...\fR passed as arguments if they are supplied, will be looked up
+in the current namespace context, not in the caller's. Apart from that
+difference in resolution, it is equivalent to:
+.PP
+.CS
+return [uplevel 1 [list \fIcommand\fR ?\fIarg ...\fR?]]
+.CE
+.PP
+This command may not be invoked from within an \fBuplevel\fR into a procedure
+or inside a \fBcatch\fR inside a procedure or lambda.
+'\" TODO: sort out the mess with the [try] command!
+.SH EXAMPLE
+.PP
+Compute the factorial of a number.
+.PP
+.CS
+proc factorial {n {accum 1}} {
+ if {$n < 2} {
+ return $accum
+ }
+ \fBtailcall\fR factorial [expr {$n - 1}] [expr {$accum * $n}]
+}
+.CE
+.PP
+Print the elements of a list with alternating lines having different
+indentations.
+.PP
+.CS
+proc printList {theList} {
+ if {[llength $theList]} {
+ puts "> [lindex $theList 0]"
+ \fBtailcall\fR printList2 [lrange $theList 1 end]
+ }
+}
+proc printList2 {theList} {
+ if {[llength $theList]} {
+ puts "< [lindex $theList 0]"
+ \fBtailcall\fR printList [lrange $theList 1 end]
+ }
+}
+.CE
+.SH "SEE ALSO"
+apply(n), proc(n), uplevel(n)
+.SH KEYWORDS
+call, recursion, tail recursion
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/pkgs/msgcat/doc/tclsh.1 b/pkgs/msgcat/doc/tclsh.1
new file mode 100644
index 0000000..2819408
--- /dev/null
+++ b/pkgs/msgcat/doc/tclsh.1
@@ -0,0 +1,147 @@
+'\"
+'\" 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 tclsh 1 "" Tcl "Tcl Applications"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+tclsh \- Simple shell containing Tcl interpreter
+.SH SYNOPSIS
+\fBtclsh\fR ?-encoding \fIname\fR? ?\fIfileName arg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+\fBTclsh\fR is a shell-like application that reads Tcl commands
+from its standard input or from a file and evaluates them.
+If invoked with no arguments then it runs interactively, reading
+Tcl commands from standard input and printing command results and
+error messages to standard output.
+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, 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 few arguments
+specify the name of a script file, and, optionally, the encoding of
+the text data stored in that script file. 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.
+The end of the file may be marked either by the physical end of
+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
+.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.
+.PP
+If you create a Tcl script in a file whose first line is
+.PP
+.CS
+\fB#!/usr/local/bin/tclsh\fR
+.CE
+.PP
+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 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.
+.PP
+An even better approach is to start your script files with the
+following three lines:
+.PP
+.CS
+\fB#!/bin/sh
+# the next line restarts using tclsh \e
+exec tclsh "$0" ${1+"$@"}\fR
+.CE
+.PP
+This approach has three advantages over the approach in the previous
+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.
+Third, this approach will work even if \fBtclsh\fR is
+itself a shell script (this is done on some systems in order to
+handle multiple architectures or operating systems: the \fBtclsh\fR
+script selects one of several binaries to run). The three lines
+cause both \fBsh\fR and \fBtclsh\fR to process the script, but the
+\fBexec\fR is only executed by \fBsh\fR.
+\fBsh\fR processes the script first; it treats the second
+line as a comment and executes the third line.
+The \fBexec\fR statement cause the shell to stop processing and
+instead to start up \fBtclsh\fR to reprocess the entire script.
+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
+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.
+.SH "VARIABLES"
+.PP
+\fBTclsh\fR sets the following Tcl variables:
+.TP 15
+\fBargc\fR
+.
+Contains a count of the number of \fIarg\fR arguments (0 if none),
+not including the name of the script file.
+.TP 15
+\fBargv\fR
+.
+Contains a Tcl list whose elements are the \fIarg\fR arguments,
+in order, or an empty string if there are no \fIarg\fR arguments.
+.TP 15
+\fBargv0\fR
+.
+Contains \fIfileName\fR if it was specified.
+Otherwise, contains the name by which \fBtclsh\fR was invoked.
+.TP 15
+\fBtcl_interactive\fR
+.
+Contains 1 if \fBtclsh\fR is running interactively (no
+\fIfileName\fR was specified and standard input is a terminal-like
+device), 0 otherwise.
+.SH PROMPTS
+.PP
+When \fBtclsh\fR is invoked interactively it normally prompts for each
+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 is not yet complete;
+if \fBtcl_prompt2\fR is not set then no prompt is output for
+incomplete commands.
+.SH "STANDARD CHANNELS"
+.PP
+See \fBTcl_StandardChannels\fR for more explanations.
+.SH "SEE ALSO"
+encoding(n), fconfigure(n), tclvars(n)
+.SH KEYWORDS
+application, argument, interpreter, prompt, script file, shell
diff --git a/pkgs/msgcat/doc/tcltest.n b/pkgs/msgcat/doc/tcltest.n
new file mode 100644
index 0000000..731bed7
--- /dev/null
+++ b/pkgs/msgcat/doc/tcltest.n
@@ -0,0 +1,1257 @@
+'\"
+'\" Copyright (c) 1990-1994 The Regents of the University of California
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\" Copyright (c) 2000 Ajuba Solutions
+'\" Contributions from Don Porter, NIST, 2002. (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 "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\fR ?\fB2.3\fR?
+
+\fBtcltest::test \fIname description\fR ?\fI\-option value ...\fR?
+\fBtcltest::test \fIname description\fR ?\fIconstraints\fR? \fIbody result\fR
+
+\fBtcltest::loadTestedCommands\fR
+\fBtcltest::makeDirectory \fIname\fR ?\fIdirectory\fR?
+\fBtcltest::removeDirectory \fIname\fR ?\fIdirectory\fR?
+\fBtcltest::makeFile \fIcontents name\fR ?\fIdirectory\fR?
+\fBtcltest::removeFile \fIname\fR ?\fIdirectory\fR?
+\fBtcltest::viewFile \fIname\fR ?\fIdirectory\fR?
+\fBtcltest::cleanupTests \fR?\fIrunningMultipleTests\fR?
+\fBtcltest::runAllTests\fR
+
+\fBtcltest::configure\fR
+\fBtcltest::configure \fI\-option\fR
+\fBtcltest::configure \fI\-option value\fR ?\fI\-option value ...\fR?
+\fBtcltest::customMatch \fImode command\fR
+\fBtcltest::testConstraint \fIconstraint\fR ?\fIvalue\fR?
+\fBtcltest::outputChannel \fR?\fIchannelID\fR?
+\fBtcltest::errorChannel \fR?\fIchannelID\fR?
+\fBtcltest::interpreter \fR?\fIinterp\fR?
+
+\fBtcltest::debug \fR?\fIlevel\fR?
+\fBtcltest::errorFile \fR?\fIfilename\fR?
+\fBtcltest::limitConstraints \fR?\fIboolean\fR?
+\fBtcltest::loadFile \fR?\fIfilename\fR?
+\fBtcltest::loadScript \fR?\fIscript\fR?
+\fBtcltest::match \fR?\fIpatternList\fR?
+\fBtcltest::matchDirectories \fR?\fIpatternList\fR?
+\fBtcltest::matchFiles \fR?\fIpatternList\fR?
+\fBtcltest::outputFile \fR?\fIfilename\fR?
+\fBtcltest::preserveCore \fR?\fIlevel\fR?
+\fBtcltest::singleProcess \fR?\fIboolean\fR?
+\fBtcltest::skip \fR?\fIpatternList\fR?
+\fBtcltest::skipDirectories \fR?\fIpatternList\fR?
+\fBtcltest::skipFiles \fR?\fIpatternList\fR?
+\fBtcltest::temporaryDirectory \fR?\fIdirectory\fR?
+\fBtcltest::testsDirectory \fR?\fIdirectory\fR?
+\fBtcltest::verbose \fR?\fIlevel\fR?
+
+\fBtcltest::test \fIname description optionList\fR
+\fBtcltest::bytestring \fIstring\fR
+\fBtcltest::normalizeMsg \fImsg\fR
+\fBtcltest::normalizePath \fIpathVar\fR
+\fBtcltest::workingDirectory \fR?\fIdir\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBtcltest\fR package provides several utility commands useful
+in the construction of test suites for code instrumented to be
+run by evaluation of Tcl commands. Notably the built-in commands
+of the Tcl library itself are tested by a test suite using the
+tcltest package.
+.PP
+All the commands provided by the \fBtcltest\fR package are defined
+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
+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
+test suites.
+.PP
+See \fBCREATING TEST SUITES WITH TCLTEST\fR below for an extended example
+of how to use the commands of \fBtcltest\fR to produce test suites
+for your Tcl-enabled code.
+.SH COMMANDS
+.TP
+\fBtest\fR \fIname description\fR ?\fI\-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
+test, as configured by the options of \fBtcltest\fR. The
+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.
+.TP
+\fBtest\fR \fIname description\fR ?\fIconstraints\fR? \fIbody result\fR
+.
+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
+.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
+.QW \- .
+.TP
+\fBloadTestedCommands\fR
+.
+Evaluates in the caller's context the script specified by
+\fBconfigure \-load\fR or \fBconfigure \-loadfile\fR.
+Returns the result of that script evaluation, including any error
+raised by the script. Use this command and the related
+configuration options to provide the commands to be tested to
+the interpreter running the test suite.
+.TP
+\fBmakeFile\fR \fIcontents name\fR ?\fIdirectory\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.
+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.
+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\fR ?\fIdirectory\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.
+Returns an empty string. Use this command to delete files
+created by \fBmakeFile\fR.
+.TP
+\fBmakeDirectory\fR \fIname\fR ?\fIdirectory\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 default value of \fIdirectory\fR is the directory
+\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
+\fBremoveDirectory\fR \fIname\fR ?\fIdirectory\fR?
+.
+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.
+Returns an empty string. Use this command to delete any directories
+created by \fBmakeDirectory\fR.
+.TP
+\fBviewFile\fR \fIfile\fR ?\fIdirectory\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.
+The default value of \fIdirectory\fR is the directory
+\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
+the system encoding, so its usefulness is limited to text
+files.
+.TP
+\fBcleanupTests\fR
+.
+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.
+.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 global \fBenv\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.
+.SS "CONFIGURATION COMMANDS"
+.TP
+\fBconfigure\fR
+.
+Returns the list of configurable options supported by \fBtcltest\fR.
+See \fBCONFIGURABLE OPTIONS\fR below for the full list of options,
+their valid values, and their effect on \fBtcltest\fR operations.
+.TP
+\fBconfigure \fIoption\fR
+.
+Returns the current value of the supported configurable option \fIoption\fR.
+Raises an error if \fIoption\fR is not a supported configurable option.
+.TP
+\fBconfigure \fIoption value\fR ?\fI\-option value ...\fR?
+.
+Sets the value of each configurable option \fIoption\fR to the
+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
+arguments are not processed.
+.RS
+.PP
+If the environment variable \fB::env(TCLTEST_OPTIONS)\fR exists when
+the \fBtcltest\fR package is loaded (by \fBpackage require\fR \fBtcltest\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
+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
+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.
+.TP
+\fBtestConstraint \fIconstraint\fR ?\fIboolean\fR?
+.
+Sets or returns the boolean value associated with the named \fIconstraint\fR.
+See \fBTEST CONSTRAINTS\fR below for more information.
+.TP
+\fBinterpreter\fR ?\fIexecutableName\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 ?\fIchannelID\fR?
+.
+Sets or returns the output channel ID. This defaults to \fBstdout\fR.
+Any test that prints test related output should send
+that output to \fBoutputChannel\fR rather than letting
+that output default to \fBstdout\fR.
+.TP
+\fBerrorChannel\fR ?\fIchannelID\fR?
+.
+Sets or returns the error channel ID. This defaults to \fBstderr\fR.
+Any test that prints error messages should send
+that output to \fBerrorChannel\fR rather than printing
+directly to \fBstderr\fR.
+.SS "SHORTCUT CONFIGURATION COMMANDS"
+.TP
+\fBdebug\fR ?\fIlevel\fR?
+.
+Same as
+.QW "\fBconfigure \-debug\fR ?\fIlevel\fR?" .
+.TP
+\fBerrorFile\fR ?\fIfilename\fR?
+.
+Same as
+.QW "\fBconfigure \-errfile\fR ?\fIfilename\fR?" .
+.TP
+\fBlimitConstraints\fR ?\fIboolean\fR?
+.
+Same as
+.QW "\fBconfigure \-limitconstraints\fR ?\fIboolean\fR?" .
+.TP
+\fBloadFile\fR ?\fIfilename\fR?
+.
+Same as
+.QW "\fBconfigure \-loadfile\fR ?\fIfilename\fR?" .
+.TP
+\fBloadScript\fR ?\fIscript\fR?
+.
+Same as
+.QW "\fBconfigure \-load\fR ?\fIscript\fR?" .
+.TP
+\fBmatch\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-match\fR ?\fIpatternList\fR?" .
+.TP
+\fBmatchDirectories\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-relateddir\fR ?\fIpatternList\fR?" .
+.TP
+\fBmatchFiles\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-file\fR ?\fIpatternList\fR?" .
+.TP
+\fBoutputFile\fR ?\fIfilename\fR?
+.
+Same as
+.QW "\fBconfigure \-outfile\fR ?\fIfilename\fR?" .
+.TP
+\fBpreserveCore\fR ?\fIlevel\fR?
+.
+Same as
+.QW "\fBconfigure \-preservecore\fR ?\fIlevel\fR?" .
+.TP
+\fBsingleProcess\fR ?\fIboolean\fR?
+.
+Same as
+.QW "\fBconfigure \-singleproc\fR ?\fIboolean\fR?" .
+.TP
+\fBskip\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-skip\fR ?\fIpatternList\fR?" .
+.TP
+\fBskipDirectories\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-asidefromdir\fR ?\fIpatternList\fR?" .
+.TP
+\fBskipFiles\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-notfile\fR ?\fIpatternList\fR?" .
+.TP
+\fBtemporaryDirectory\fR ?\fIdirectory\fR?
+.
+Same as
+.QW "\fBconfigure \-tmpdir\fR ?\fIdirectory\fR?" .
+.TP
+\fBtestsDirectory\fR ?\fIdirectory\fR?
+.
+Same as
+.QW "\fBconfigure \-testdir\fR ?\fIdirectory\fR?" .
+.TP
+\fBverbose\fR ?\fIlevel\fR?
+.
+Same as
+.QW "\fBconfigure \-verbose\fR ?\fIlevel\fR?" .
+.SS "OTHER COMMANDS"
+.PP
+The remaining commands provided by \fBtcltest\fR have better
+alternatives provided by \fBtcltest\fR or \fBTcl\fR itself. They
+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
+argument quoted by braces, rather than needing to backslash quote
+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
+an unfortunate attempt to overthrow Tcl's substitution rules by
+performing substitutions on some of the list elements as an attempt to
+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.
+.TP
+\fBworkingDirectory\fR ?\fIdirectoryName\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.
+.TP
+\fBnormalizeMsg \fImsg\fR
+.
+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
+results.
+.TP
+\fBnormalizePath \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
+is a sufficient replacement.
+.TP
+\fBbytestring \fIstring\fR
+.
+Construct a string that consists of the requested sequence of bytes,
+as opposed to a string of properly formed UTF-8 characters using the
+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\fR
+\fBidentity\fR.
+.SH TESTS
+.PP
+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
+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.
+.PP
+The valid options for \fBtest\fR are summarized:
+.PP
+.CS
+\fBtest\fR \fIname\fR \fIdescription\fR
+ ?\fB\-constraints \fIkeywordList|expression\fR?
+ ?\fB\-setup \fIsetupScript\fR?
+ ?\fB\-body \fItestScript\fR?
+ ?\fB\-cleanup \fIcleanupScript\fR?
+ ?\fB\-result \fIexpectedAnswer\fR?
+ ?\fB\-output \fIexpectedOutput\fR?
+ ?\fB\-errorOutput \fIexpectedError\fR?
+ ?\fB\-returnCodes \fIcodeList\fR?
+ ?\fB\-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
+.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
+to the lists of string matching patterns returned by
+\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.
+.PP
+The \fIdescription\fR should be a short textual description of the
+test. The \fIdescription\fR is included in output produced by the
+test, typically test failure messages. Good \fIdescription\fR values
+should briefly explain the purpose of the test to users of a test suite.
+The name of a Tcl or C function being tested should be included in the
+description for regression tests. If the test case exists to reproduce
+a bug, include the bug ID in the description.
+.PP
+Valid attributes and associated values are:
+.TP
+\fB\-constraints \fIkeywordList\fR|\fIexpression\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
+constraints is false or does not exist, the test is skipped. If the
+\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.
+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
+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
+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
+test, which must return a result that can be checked for correctness.
+If evaluation of \fIscript\fR raises an error, the test will fail
+(unless the \fB\-returnCodes\fR option is used to state that an error
+is expected).
+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.
+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
+values for \fImode\fR are \fBregexp\fR, \fBglob\fR, \fBexact\fR, and
+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
+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
+of the script(s) will be compared. Note that only output printed using
+the global \fBputs\fR command 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
+evaluation of the script(s) will be compared. Note that only output
+printed using the global \fBputs\fR command is used for comparison. If
+\fB\-errorOutput\fR is not specified, output sent to \fBstderr\fR and
+\fBerrorChannel\fR is not processed for comparison.
+.TP
+\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
+a code not in the \fIexpectedCodeList\fR, the test fails. All
+return codes known to \fBreturn\fR, in both numeric and symbolic
+form, including extended return codes, are acceptable elements in
+the \fIexpectedCodeList\fR. Default value is
+.QW "\fBok return\fR" .
+.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
+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
+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.
+.PP
+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.
+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
+below. Any output produced by the test scripts themselves should be
+produced using \fBputs\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.
+.SS "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
+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
+only if all constraints in the list are true-valued. Thus,
+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
+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
+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
+may appear within a test file, or within the script specified
+by the \fBconfigure \-load\fR or \fBconfigure \-loadfile\fR
+options.
+.PP
+The following is a list of constraints pre-defined by the
+\fBtcltest\fR package itself:
+.TP
+\fIsingleTestInterp\fR
+.
+This test can only be run if all test files are sourced into a single
+interpreter.
+.TP
+\fIunix\fR
+.
+This test can only be run on any Unix platform.
+.TP
+\fIwin\fR
+.
+This test can only be run on any Windows platform.
+.TP
+\fInt\fR
+.
+This test can only be run on any Windows NT platform.
+.TP
+\fI95\fR
+.
+This test can only be run on any Windows 95 platform.
+.TP
+\fI98\fR
+.
+This test can only be run on any Windows 98 platform.
+.TP
+\fImac\fR
+.
+This test can only be run on any Mac platform.
+.TP
+\fIunixOrWin\fR
+.
+This test can only be run on a Unix or Windows platform.
+.TP
+\fImacOrWin\fR
+.
+This test can only be run on a Mac or Windows platform.
+.TP
+\fImacOrUnix\fR
+.
+This test can only be run on a Mac or Unix platform.
+.TP
+\fItempNotWin\fR
+.
+This test can not be run on Windows. This flag is used to temporarily
+disable a test.
+.TP
+\fItempNotMac\fR
+.
+This test can not be run on a Mac. This flag is used
+to temporarily disable a test.
+.TP
+\fIunixCrash\fR
+.
+This test crashes if it is run on Unix. This flag is used to temporarily
+disable a test.
+.TP
+\fIwinCrash\fR
+.
+This test crashes if it is run on Windows. This flag is used to temporarily
+disable a test.
+.TP
+\fImacCrash\fR
+.
+This test crashes if it is run on a Mac. This flag is used to temporarily
+disable a test.
+.TP
+\fIemptyTest\fR
+.
+This test is empty, and so not worth running, but it remains as a
+place-holder for a test to be written in the future. This constraint
+has value false to cause tests to be skipped unless the user specifies
+otherwise.
+.TP
+\fIknownBug\fR
+.
+This test is known to fail and the bug is not yet fixed. This constraint
+has value false to cause tests to be skipped unless the user specifies
+otherwise.
+.TP
+\fInonPortable\fR
+.
+This test can only be run in some known development environment.
+Some tests are inherently non-portable because they depend on things
+like word length, file system configuration, window manager, etc.
+This constraint has value false to cause tests to be skipped unless
+the user specifies otherwise.
+.TP
+\fIuserInteraction\fR
+.
+This test requires interaction from the user. This constraint has
+value false to causes tests to be skipped unless the user specifies
+otherwise.
+.TP
+\fIinteractive\fR
+.
+This test can only be run in if the interpreter is in interactive mode
+(when the global tcl_interactive variable is set to 1).
+.TP
+\fInonBlockFiles\fR
+.
+This test can only be run if platform supports setting files into
+nonblocking mode.
+.TP
+\fIasyncPipeClose\fR
+.
+This test can only be run if platform supports async flush and async close
+on a pipe.
+.TP
+\fIunixExecs\fR
+.
+This test can only be run if this machine has Unix-style commands
+\fBcat\fR, \fBecho\fR, \fBsh\fR, \fBwc\fR, \fBrm\fR, \fBsleep\fR,
+\fBfgrep\fR, \fBps\fR, \fBchmod\fR, and \fBmkdir\fR available.
+.TP
+\fIhasIsoLocale\fR
+.
+This test can only be run if can switch to an ISO locale.
+.TP
+\fIroot\fR
+.
+This test can only run if Unix user is root.
+.TP
+\fInotRoot\fR
+.
+This test can only run if Unix user is not root.
+.TP
+\fIeformat\fR
+.
+This test can only run if app has a working version of sprintf with respect
+to the
+.QW e
+format of floating-point numbers.
+.TP
+\fIstdio\fR
+.
+This 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
+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
+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
+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.
+.SS "RUNNING ALL TESTS"
+.PP
+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.
+.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
+and sorted. Then each file will be evaluated in turn. If
+\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
+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
+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.
+.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\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
+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.
+.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
+and do not match any of the patterns in
+\fBconfigure \-asidefromdir\fR are examined. If
+a file named \fBall.tcl\fR is found in such a directory,
+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,
+many directories in a directory tree can have all their
+test files evaluated by a single \fBrunAllTests\fR
+command.
+.SH "CONFIGURABLE OPTIONS"
+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
+each test file. No spawning when \fIboolean\fR is true. Default
+value is false.
+.TP
+\fB\-debug \fIlevel\fR
+.
+Sets the debug level to \fIlevel\fR, an integer value indicating how
+much debugging information should be printed to \fBstdout\fR. Note that
+debug messages always go to \fBstdout\fR, independent of the value of
+\fBconfigure \-outfile\fR. Default value is 0. Levels are defined as:
+.RS
+.IP 0 4
+Do not display any debug information.
+.IP 1
+Display information regarding whether a test is skipped because it
+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
+Display the flag array parsed by the command line processor, the
+contents of the global \fBenv\fR array, and all user-defined variables
+that exist in the current namespace as they are used.
+.IP 3
+Display information regarding what individual procs in the test
+harness are doing.
+.RE
+.TP
+\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, \fBerror\fR and \fBline\fR. Default value
+is
+.QW "\fBbody error\fR" .
+Levels are defined as:
+.RS
+.IP "body (\fBb\fR)"
+Display the body of failed tests
+.IP "pass (\fBp\fR)"
+Print output when a test passes
+.IP "skip (\fBs\fR)"
+Print output when a test is skipped
+.IP "start (\fBt\fR)"
+Print output whenever a test starts
+.IP "error (\fBe\fR)"
+Print errorInfo and errorCode, if they exist, when a test return code
+does not match its expected return code
+.IP "line (\fBl\fR)"
+Print source file line information of failed tests
+.PP
+The single letter abbreviations noted above are also recognized
+so that
+.QW "\fBconfigure \-verbose pt\fR"
+is the same as
+.QW "\fBconfigure \-verbose {pass start}\fR" .
+.RE
+.TP
+\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 \(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.
+.IP 2
+Check for core files at all times described above, and save a
+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
+in \fBTESTS\fR above. Default value is false.
+.TP
+\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
+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
+temporary files and directories created by test files should
+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.
+.TP
+\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
+.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
+what subdirectories to search for an \fBall.tcl\fR file. Default
+value is
+.QW \fB*\fR .
+.TP
+\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
+.QW \fB*\fR .
+.TP
+\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.
+Default value is an empty script.
+.TP
+\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.
+.TP
+\fB\-outfile \fIfilename\fR
+.
+Sets the file to which all output produced by tcltest should be
+written. A file named \fIfilename\fR will be \fBopen\fRed for writing,
+and the resulting channel will be set as the value of \fBoutputChannel\fR.
+.TP
+\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\fRed
+for writing, and the resulting channel will be set as the value
+of \fBerrorChannel\fR.
+.SH "CREATING TEST SUITES WITH TCLTEST"
+.PP
+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]
+} -body {
+ file exists $file
+} -cleanup {
+ 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
+} -setup {
+ set file [makeFile {} test]
+} -body {
+ file attributes $file -owner
+} -cleanup {
+ removeFile test
+} -result $::tcl_platform(user)
+.CE
+.RE
+.PP
+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
+.QW \fB.test\fR
+extension, because that is the default pattern
+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.
+Use constraints to skip tests, rather than conditional evaluation
+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
+.RE
+.IP [6]
+Discouraged system for writing conditional tests, using \fBif\fR to
+guard:
+.RS
+.PP
+.CS
+if $myRequirement {
+ \fBtest\fR badConditionalTest {} {
+ #body
+ } result
+}
+.CE
+.RE
+.PP
+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
+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
+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.
+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
+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\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
+package require example
+namespace eval ::example::test {
+ namespace import ::tcltest::*
+ \fBtestConstraint\fR X [expr {...}]
+ variable SETUP {#common setup code}
+ variable CLEANUP {#common cleanup code}
+ \fBtest\fR example-1 {} -setup $SETUP -body {
+ # First test
+ } -cleanup $CLEANUP -result {...}
+ \fBtest\fR example-2 {} -constraints X -setup $SETUP -body {
+ # Second test; constrained
+ } -cleanup $CLEANUP -result {...}
+ \fBtest\fR example-3 {} {
+ # 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
+doing any necessary setup. This script is usually named \fBall.tcl\fR
+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 \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
+provided by earlier releases of \fBtcltest\fR have not been documented
+here. They are no longer part of the supported public interface of
+\fBtcltest\fR and should not be used in new test suites. However,
+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\fR \fBtcltest 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
+or
+.PP
+.CS
+\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.
+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 {
+ \fBtest\fR level-2.1 {level 2} {
+ }
+ }
+}
+.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\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
+.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 \fBputs\fR in your application code. Output is
+intercepted by redefining the global \fBputs\fR 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 \fBtest\fR command.
+Therefore, usage of the \fB\-output\fR and \fB\-errorOutput\fR
+options to \fBtest\fR is useful only for pure Tcl applications
+that use \fBputs\fR to produce output.
+.SH KEYWORDS
+test, test harness, test suite
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/pkgs/msgcat/doc/tclvars.n b/pkgs/msgcat/doc/tclvars.n
new file mode 100644
index 0000000..44a8e11
--- /dev/null
+++ b/pkgs/msgcat/doc/tclvars.n
@@ -0,0 +1,566 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH tclvars n 8.0 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+argc, argv, argv0, auto_path, env, errorCode, errorInfo, tcl_interactive, tcl_library, tcl_nonwordchars, tcl_patchLevel, tcl_pkgPath, tcl_platform, tcl_precision, tcl_rcFileName, tcl_traceCompile, tcl_traceEval, tcl_wordchars, tcl_version \- Variables used by Tcl
+.BE
+.SH DESCRIPTION
+.PP
+The following global variables are created and managed automatically
+by the Tcl library. Except where noted below, these variables should
+normally be treated as read-only by application-specific code and by users.
+.TP
+\fBauto_path\fR
+.
+If set, then it must contain a valid Tcl list giving directories to
+search during auto-load operations (including for package index
+files when using the default \fBpackage unknown\fR handler).
+This variable is initialized during startup to contain, in order:
+the directories listed in the \fBTCLLIBPATH\fR environment variable,
+the directory named by the \fBtcl_library\fR global variable,
+the parent directory of \fBtcl_library\fR,
+the directories listed in the \fBtcl_pkgPath\fR variable.
+Additional locations to look for files and package indices should
+normally be added to this variable using \fBlappend\fR.
+.RS
+.PP
+Additional variables relating to package management exist. More
+details are listed in the \fBVARIABLES\fR section of the \fBlibrary\fR
+manual page.
+.RE
+.TP
+\fBenv\fR
+.
+This variable is maintained by Tcl as an array
+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 does not already
+exist.
+Unsetting an element of \fBenv\fR will remove the corresponding
+environment variable.
+Changes to the \fBenv\fR array will affect the environment
+passed to children by commands like \fBexec\fR.
+If the entire \fBenv\fR array is unset then Tcl will stop
+monitoring \fBenv\fR accesses and will not update environment
+variables.
+.RS
+.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
+.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
+will not work on Windows and is discouraged for cross-platform usage.
+.PP
+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
+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_TZ)\fR, \fBenv(TZ)\fR
+.
+These specify the default timezone used for parsing and formatting times and
+dates in the \fBclock\fR command. On many platforms, the TZ environment
+variable is set up by the operating system.
+.TP
+\fBenv(LC_ALL)\fR, \fBenv(LC_MESSAGES)\fR, \fBenv(LANG)\fR
+.
+These environment variables are used by the \fBmsgcat\fR package to
+determine what locale to format messages using.
+.TP
+\fBenv(TCL_INTERP_DEBUG_FRAME)\fR
+.
+If existing, it has the same effect as running \fBinterp debug\fR
+\fB{} -frame 1\fR
+as the very first command of each new Tcl interpreter.
+.RE
+.TP
+\fBerrorCode\fR
+.
+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 \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 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),
+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 \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 \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 \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 \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 \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 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 is \fBPOSIX\fR, then
+the error occurred during a POSIX kernel call.
+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 \fImsg\fR element will be a human-readable
+message corresponding to \fIerrName\fR, such as
+.QW "no such file or directory"
+for the \fBENOENT\fR case.
+.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.
+.PP
+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
+\fBerrorInfo\fR
+.
+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
+nested Tcl commands that had been invoked at the time of the error.
+.TP
+\fBtcl_library\fR
+.
+This variable holds the name of a directory containing the
+system library of Tcl scripts, such as those used for auto-loading.
+The value of this variable is returned by the \fBinfo library\fR command.
+See the \fBlibrary\fR manual entry for details of the facilities
+provided by the Tcl script library.
+Normally each application or package will have its own application-specific
+script library in addition to the Tcl script library;
+each application should set a global variable with a name like
+\fB$\fIapp\fB_library\fR (where \fIapp\fR is the application's name)
+to hold the network file name for that application's library directory.
+The initial value of \fBtcl_library\fR is set when an interpreter
+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 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
+\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.
+.TP
+\fBtcl_pkgPath\fR
+.
+This variable holds a list of directories indicating where packages are
+normally installed. It is not used on Windows. It typically contains
+either one or two entries; if it contains two entries, the first is
+normally a directory for platform-dependent packages (e.g., shared library
+binaries) and the second is normally a directory for platform-independent
+packages (e.g., script files). Typically a package is installed as a
+subdirectory of one of the entries in the \fBtcl_pkgPath\fR
+variable. The directories in the \fBtcl_pkgPath\fR variable 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 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.
+.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 could not
+retrieve any relevant information. In addition, extensions
+and applications may add additional values to the array. The
+predefined elements are:
+.RS
+.TP
+\fBbyteOrder\fR
+.
+The native byte order of this machine: either \fBlittleEndian\fR or
+\fBbigEndian\fR.
+.TP
+\fBdebug\fR
+.
+If this variable exists, then the interpreter was compiled with and linked
+to a debug-enabled C run-time. This variable will only exist on Windows,
+so extension writers can specify which package to load depending on the
+C run-time library that is in use. This is not an indication that this core
+contains symbols.
+.TP
+\fBmachine\fR
+.
+The instruction set executed by this machine, such as
+\fBintel\fR, \fBPPC\fR, \fB68k\fR, or \fBsun4m\fR. On UNIX machines, this
+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, 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
+distinguish between the two, check the \fBosVersion\fR.
+.TP
+\fBosVersion\fR
+.
+The version number for the operating system running on this machine.
+On UNIX machines, this is the value returned by \fBuname -r\fR. On
+Windows 95, the version will be 4.0; on Windows 98, the version will
+be 4.10.
+.TP
+\fBpathSeparator\fR
+.VS 8.6
+'\" Defined by TIP #315
+The character that should be used to \fBsplit\fR PATH-like environment
+variables into their corresponding list of directory names.
+.VE 8.6
+.TP
+\fBplatform\fR
+.
+Either \fBwindows\fR, or \fBunix\fR. This identifies the
+general operating environment of the machine.
+.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.)
+.TP
+\fBthreaded\fR
+.
+If this variable exists, then the interpreter
+was compiled with threads enabled.
+.TP
+\fBuser\fR
+.
+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.
+.TP
+\fBwordSize\fR
+.
+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.)
+.RE
+.TP
+\fBtcl_precision\fR
+.
+This variable controls the number of digits to generate
+when converting floating-point values to strings. It defaults
+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. 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 thread share a single \fBtcl_precision\fR value:
+changing it in one interpreter will affect all other interpreters as
+well. Safe interpreters are not allowed to modify the
+variable.
+.RE
+.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
+user-specific startup file. If it is set by application-specific
+initialization, then the Tcl startup code will check for the existence
+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_traceCompile\fR
+.
+The value of this variable can be set to control
+how much tracing information
+is displayed during bytecode compilation.
+By default, \fBtcl_traceCompile\fR is zero and no information is displayed.
+Setting \fBtcl_traceCompile\fR to 1 generates a one-line summary in \fBstdout\fR
+whenever a procedure or top-level command is compiled.
+Setting it to 2 generates a detailed listing in \fBstdout\fR of the
+bytecode instructions emitted during every compilation.
+This variable is useful in
+tracking down suspected problems with the Tcl compiler.
+.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
+how much tracing information
+is displayed during bytecode execution.
+By default, \fBtcl_traceExec\fR is zero and no information is displayed.
+Setting \fBtcl_traceExec\fR to 1 generates a one-line trace in \fBstdout\fR
+on each call to a Tcl procedure.
+Setting it to 2 generates a line of output
+whenever any Tcl command is invoked
+that contains the name of the command and its arguments.
+Setting it to 3 produces a detailed trace showing the result of
+executing each bytecode instruction.
+Note that when \fBtcl_traceExec\fR is 2 or 3,
+commands such as \fBset\fR and \fBincr\fR
+that have been entirely replaced by a sequence
+of bytecode instructions are not shown.
+Setting this variable is useful in
+tracking down suspected problems with the bytecode compiler
+and interpreter.
+.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
+.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\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
+.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\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
+.
+When an interpreter is created Tcl initializes this variable to
+hold the version number for this version of Tcl in the form \fIx.y\fR.
+Changes to \fIx\fR represent major changes with probable
+incompatibilities and changes to \fIy\fR represent small enhancements and
+bug fixes that retain backward compatibility.
+The value of this variable is returned by the \fBinfo tclversion\fR
+command.
+.SH "OTHER GLOBAL VARIABLES"
+.PP
+The following variables are only guaranteed to exist in \fBtclsh\fR
+and \fBwish\fR executables; the Tcl library does not define them
+itself but many Tcl environments do.
+.TP 6
+\fBargc\fR
+.
+The number of arguments to \fBtclsh\fR or \fBwish\fR.
+.TP 6
+\fBargv\fR
+.
+Tcl list of arguments to \fBtclsh\fR or \fBwish\fR.
+.TP 6
+\fBargv0\fR
+.
+The script that \fBtclsh\fR or \fBwish\fR started executing (if it was
+specified) or otherwise the name by which \fBtclsh\fR or \fBwish\fR
+was invoked.
+.TP 6
+\fBtcl_interactive\fR
+.
+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.
+.SH EXAMPLES
+.PP
+To add a directory to the collection of locations searched by
+\fBpackage require\fR, e.g., because of some application-specific
+packages that are used, the \fBauto_path\fR variable needs to be
+updated:
+.PP
+.CS
+lappend ::\fBauto_path\fR [file join [pwd] "theLibDir"]
+.CE
+.PP
+A simple though not very robust way to handle command line arguments
+of the form
+.QW "\-foo 1 \-bar 2"
+is to load them into an array having first loaded in the default settings:
+.CS
+array set arguments {-foo 0 -bar 0 -grill 0}
+array set arguments $::\fBargv\fR
+puts "foo is $arguments(-foo)"
+puts "bar is $arguments(-bar)"
+puts "grill is $arguments(-grill)"
+.CE
+.PP
+The \fBargv0\fR global variable can be used (in conjunction with the
+\fBinfo script\fR command) to determine whether the current script is
+being executed as the main script or loaded as a library. This is
+useful because it allows a single script to be used as both a library
+and a demonstration of that library:
+.PP
+.CS
+if {$::\fBargv0\fR eq [info script]} {
+ # running as: tclsh example.tcl
+} else {
+ package provide Example 1.0
+}
+.CE
+.SH "SEE ALSO"
+eval(n), library(n), tclsh(1), tkvars(n), wish(1)
+.SH KEYWORDS
+arithmetic, bytecode, compiler, error, environment, POSIX, precision,
+subprocess, user, variables
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/tell.n b/pkgs/msgcat/doc/tell.n
new file mode 100644
index 0000000..87e63b0
--- /dev/null
+++ b/pkgs/msgcat/doc/tell.n
@@ -0,0 +1,48 @@
+'\"
+'\" 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 tell n 8.1 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+tell \- Return current access position for an open channel
+.SH SYNOPSIS
+\fBtell \fIchannelId\fR
+.BE
+.SH DESCRIPTION
+.PP
+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.
+The value returned is -1 for channels that do not support
+seeking.
+.PP
+\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.
+.SH EXAMPLE
+.PP
+Read a line from a file channel only if it starts with \fBfoobar\fR:
+.PP
+.CS
+# Save the offset in case we need to undo the read...
+set offset [\fBtell\fR $chan]
+if {[read $chan 6] eq "foobar"} {
+ gets $chan line
+} else {
+ set line {}
+ # Undo the read...
+ seek $chan $offset
+}
+.CE
+.SH "SEE ALSO"
+file(n), open(n), close(n), gets(n), seek(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+access position, channel, seeking
diff --git a/pkgs/msgcat/doc/throw.n b/pkgs/msgcat/doc/throw.n
new file mode 100644
index 0000000..d49fb24
--- /dev/null
+++ b/pkgs/msgcat/doc/throw.n
@@ -0,0 +1,48 @@
+'\"
+'\" Copyright (c) 2008 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 throw n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+throw \- Generate a machine-readable error
+.SH SYNOPSIS
+\fBthrow\fI type message\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command causes the current evaluation to be unwound with an error. The
+error created is described by the \fItype\fR and \fImessage\fR arguments:
+\fItype\fR must contain a list of words describing the error in a form that is
+machine-readable (and which will form the error-code part of the result
+dictionary), and \fImessage\fR should contain text that is intended for
+display to a human being.
+.PP
+The stack will be unwound until the error is trapped by a suitable \fBcatch\fR
+or \fBtry\fR command. If it reaches the event loop without being trapped, it
+will be reported through the \fBbgerror\fR mechanism. If it reaches the top
+level of script evaluation in \fBtclsh\fR, it will be printed on the console
+before, in the non-interactive case, causing an exit (the behavior in other
+programs will depend on the details of how Tcl is embedded and used).
+.PP
+By convention, the words in the \fItype\fR argument should go from most
+general to most specific.
+.SH EXAMPLES
+.PP
+The following produces an error that is identical to that produced by
+\fBexpr\fR when trying to divide a value by zero.
+.PP
+.CS
+\fBthrow\fR {ARITH DIVZERO {divide by zero}} {divide by zero}
+.CE
+.SH "SEE ALSO"
+catch(n), error(n), return(n), tclvars(n), try(n)
+.SH "KEYWORDS"
+error, exception
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/time.n b/pkgs/msgcat/doc/time.n
new file mode 100644
index 0000000..52730a1
--- /dev/null
+++ b/pkgs/msgcat/doc/time.n
@@ -0,0 +1,47 @@
+'\"
+'\" 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 time n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+time \- Time the execution of a script
+.SH SYNOPSIS
+\fBtime \fIscript\fR ?\fIcount\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command will call the Tcl interpreter \fIcount\fR
+times to evaluate \fIscript\fR (or once if \fIcount\fR is not
+specified). It will then return a string of the form
+.PP
+.CS
+\fB503.2 microseconds per iteration\fR
+.CE
+.PP
+which indicates the average amount of time required per iteration,
+in microseconds.
+Time is measured in elapsed time, not CPU time.
+.SH EXAMPLE
+Estimate how long it takes for a simple Tcl \fBfor\fR loop to count to
+a thousand:
+.PP
+.CS
+time {
+ for {set i 0} {$i<1000} {incr i} {
+ # empty body
+ }
+}
+.CE
+.SH "SEE ALSO"
+clock(n)
+.SH KEYWORDS
+script, time
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/pkgs/msgcat/doc/tm.n b/pkgs/msgcat/doc/tm.n
new file mode 100644
index 0000000..ddfbac2
--- /dev/null
+++ b/pkgs/msgcat/doc/tm.n
@@ -0,0 +1,308 @@
+'\"
+'\" 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
+.PP
+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"
+.PP
+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:
+.PP
+.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:
+.PP
+.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:
+.PP
+.CS
+package vcompare $version 0
+.CE
+.SH "FINDING MODULES"
+.PP
+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:
+.PP
+.CS
+package ifneeded \fBPNAME PVERSION\fR [list source \fBMF\fR]
+.CE
+.PP
+and the \fIprovide script\fR embedded in the above is:
+.PP
+.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:
+.PP
+.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"
+.PP
+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:
+.PP
+.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 10
+environment variables:
+.PP
+.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
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/pkgs/msgcat/doc/trace.n b/pkgs/msgcat/doc/trace.n
new file mode 100644
index 0000000..940a1e9
--- /dev/null
+++ b/pkgs/msgcat/doc/trace.n
@@ -0,0 +1,426 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Ajuba Solutions.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH trace n "8.4" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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\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 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 \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 \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 \fIcommandPrefix\fR so that the actual command is as
+follows:
+.PP
+.CS
+\fIcommandPrefix oldName newName op\fR
+.CE
+.PP
+\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
+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.
+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 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 \fIcommandPrefix\fR whenever the command \fIname\fR is executed,
+just before the actual execution takes place.
+.TP
+\fBleave\fR
+Invoke \fIcommandPrefix\fR whenever the command \fIname\fR is executed,
+just after the actual execution takes place.
+.TP
+\fBenterstep\fR
+.
+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 \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 \fIcommandPrefix\fR so that the actual
+command is as follows:
+.PP
+For \fBenter\fR and \fBenterstep\fR operations:
+.PP
+.CS
+\fIcommandPrefix command-string op\fR
+.CE
+.PP
+\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
+.QW "invalid command"
+error will occur.
+.PP
+For \fBleave\fR and \fBleavestep\fR operations:
+.PP
+.CS
+\fIcommand command-string code result op\fR
+.CE
+.PP
+\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.
+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
+\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 \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 \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
+and \fIenterstep\fR operations, the traced commands are invoked
+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
+\fIname\fR imported into another namespace.
+.RE
+.TP
+\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
+\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.
+.RS
+.PP
+\fIOps\fR indicates which operations are of interest, and is a list of
+one or more of the following items:
+.TP
+\fBarray\fR
+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 \fIcommandPrefix\fR whenever the variable is read.
+.TP
+\fBwrite\fR
+Invoke \fIcommandPrefix\fR whenever the variable is written.
+.TP
+\fBunset\fR
+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
+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
+\fIcommandPrefix\fR so that the actual command is as follows:
+.PP
+.CS
+\fIcommandPrefix name1 name2 op\fR
+.CE
+.PP
+\fIName1\fR and \fIname2\fR give the name(s) for the variable
+being accessed: if the variable is a scalar then \fIname1\fR
+gives the variable's name and \fIname2\fR is an empty string;
+if the variable is an array element then \fIname1\fR gives the
+name of the array and name2 gives the index into the array;
+if an entire array is being deleted and the trace was registered
+on the overall array, rather than a single element, then \fIname1\fR
+gives the array name and \fIname2\fR is an empty string.
+\fIName1\fR and \fIname2\fR are not necessarily the same as the
+name used in the \fBtrace variable\fR command: the \fBupvar\fR
+command allows a procedure to reference a variable under a
+different name.
+\fIOp\fR indicates what operation is being performed on the
+variable, and is one of \fBread\fR, \fBwrite\fR, or \fBunset\fR as
+defined above.
+.PP
+\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 \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 \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
+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, \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 \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, \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, \fIcommandPrefix\fR will have to restore the
+old value of the variable.
+.PP
+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 \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
+because of a procedure return, then the trace will be invoked in the
+variable context of the procedure being returned to: the stack frame
+of the returning procedure will no longer exist. Traces are not
+disabled during unset traces, so if an unset trace command creates a
+new trace and accesses the variable, the trace will be invoked. Any
+errors in unset traces are ignored.
+.PP
+If there are multiple traces on a variable they are invoked in order
+of creation, most-recent first. If one trace returns an error, then
+no further traces are invoked for the variable. If an array element
+has a trace set, and there is also a trace set on the array as a
+whole, the trace on the overall array is invoked before the one on the
+element.
+.PP
+Once created, the trace remains in effect either until the trace is
+removed with the \fBtrace remove variable\fR command described below,
+until the variable is unset, or until the interpreter is deleted.
+Unsetting an element of array will remove any traces on that element,
+but will not remove traces on the overall array.
+.PP
+This command returns an empty string.
+.RE
+.RE
+.TP
+\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 commandPrefix\fR
+If there is a trace set on command \fIname\fR with the operations and
+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 commandPrefix\fR
+If there is a trace set on command \fIname\fR with the operations and
+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 commandPrefix\fR
+If there is a trace set on variable \fIname\fR with the operations and
+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
+\fBtrace info \fItype name\fR
+Where \fItype\fR is either \fBcommand\fR, \fBexecution\fR or \fBvariable\fR.
+.RS
+.TP
+\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 \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
+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 \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
+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 \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
+.PP
+For backwards compatibility, three other subcommands are available:
+.RS
+.TP
+\fBtrace variable \fIname ops command\fR
+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
+This is equivalent to \fBtrace info variable \fIname\fR
+.RE
+.PP
+These subcommands are deprecated and will likely be removed in a
+future version of Tcl. They use an older syntax in which \fBarray\fR,
+\fBread\fR, \fBwrite\fR, \fBunset\fR are replaced by \fBa\fR, \fBr\fR,
+\fBw\fR and \fBu\fR respectively, and the \fIops\fR argument is not a
+list, but simply a string concatenation of the operations, such as
+\fBrwua\fR.
+.SH EXAMPLES
+.PP
+Print a message whenever either of the global variables \fBfoo\fR and
+\fBbar\fR are updated, even if they have a different local name at the
+time (which can be done with the \fBupvar\fR command):
+.PP
+.CS
+proc tracer {varname args} {
+ upvar #0 $varname var
+ puts "$varname was updated to be \e"$var\e""
+}
+\fBtrace add\fR variable foo write "tracer foo"
+\fBtrace add\fR variable bar write "tracer bar"
+.CE
+.PP
+Ensure that the global variable \fBfoobar\fR always contains the
+product of the global variables \fBfoo\fR and \fBbar\fR:
+.PP
+.CS
+proc doMult args {
+ global foo bar foobar
+ set foobar [expr {$foo * $bar}]
+}
+\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:
+.PP
+.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
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/pkgs/msgcat/doc/transchan.n b/pkgs/msgcat/doc/transchan.n
new file mode 100644
index 0000000..e308e13
--- /dev/null
+++ b/pkgs/msgcat/doc/transchan.n
@@ -0,0 +1,160 @@
+'\"
+'\" Copyright (c) 2008 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 transchan n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+transchan \- command handler API of channel transforms
+.SH SYNOPSIS
+\fBcmdPrefix \fIoption\fR ?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The Tcl-level handler for a channel transformation has to be a command with
+subcommands (termed an \fIensemble\fR despite not implying that it must be
+created with \fBnamespace ensemble create\fR; this mechanism is not tied to
+\fBnamespace ensemble\fR in any way). Note that \fIcmdPrefix\fR is whatever
+was specified in the call to \fBchan push\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 and \fBfinalize\fR. Transformations for writable channels
+must also support \fBwrite\fR, and transformations for readable channels must
+also support \fBread\fR.
+.PP
+Note that in the descriptions below \fIcmdPrefix\fR may be more than one word,
+and \fIhandle\fR is the value returned by the \fBchan push\fR call used to
+create the transformation.
+.SS "GENERIC SUBCOMMANDS"
+.PP
+The following subcommands are relevant to all types of channel.
+.TP
+\fIcmdPrefix \fBclear \fIhandle\fR
+.
+This optional subcommand is called to signify to the transformation that any
+data stored in internal buffers (either incoming or outgoing) must be
+cleared. It is called when a \fBchan seek\fR is performed on the channel being
+transformed.
+.TP
+\fIcmdPrefix \fBfinalize \fIhandle\fR
+.
+This mandatory subcommand is called last for the given \fIhandle\fR, and then
+never again, and it exists to allow for cleaning up any Tcl-level data
+structures associated with the transformation. \fIWarning!\fR Any errors
+thrown by this subcommand will be ignored. It is not guaranteed to be called
+if the interpreter is deleted.
+.TP
+\fIcmdPrefix \fBinitialize \fIhandle mode\fR
+.
+This mandatory subcommand is called first, and then never again (for the given
+\fIhandle\fR). Its responsibility is to initialize all parts of the
+transformation at the Tcl level. The \fImode\fR is a list containing any of
+\fBread \fRand \fBwrite\fR.
+.RS
+.TP
+\fBwrite\fR
+.
+implies that the channel is writable.
+.TP
+\fBread\fR
+.
+implies that the channel is readable.
+.PP
+The return value of the subcommand should be a list containing the names of
+all subcommands supported by this handler. Any error thrown by the subcommand
+will prevent the creation of the transformation. The thrown error will appear
+as error thrown by \fBchan push\fR.
+.RE
+.SS "READ-RELATED SUBCOMMANDS"
+.PP
+These subcommands are used for handling transformations applied to readable
+channels; though strictly \fBread \fRis optional, it must be supported if any
+of the others is or the channel will be made non-readable.
+.TP
+\fIcmdPrefix \fBdrain \fIhandle\fR
+.
+This optional subcommand is called whenever data in the transformation input
+(i.e. read) buffer has to be forced upward, i.e. towards the user or script.
+The result returned by the method is taken as the \fIbinary\fR data to push
+upward to the level above this transformation (the reader or a higher-level
+transformation).
+.RS
+.PP
+In other words, when this method is called the transformation cannot defer the
+actual transformation operation anymore and has to transform all data waiting
+in its internal read buffers and return the result of that action.
+.RE
+.TP
+\fIcmdPrefix \fBlimit? \fIhandle\fR
+.
+This optional subcommand is called to allow the Tcl I/O engine to determine
+how far ahead it should read. If present, it should return an integer number
+greater than zero which indicates how many bytes ahead should be read, or an
+integer less than zero to indicate that the I/O engine may read as far ahead
+as it likes.
+.TP
+\fIcmdPrefix \fBread \fIhandle buffer\fR
+.
+This subcommand, which must be present if the transformation is to work with
+readable channels, is called whenever the base channel, or a transformation
+below this transformation, pushes data upward. The \fIbuffer\fR contains the
+binary data which has been given to us from below. It is the responsibility of
+this subcommand to actually transform the data. The result returned by the
+subcommand is taken as the binary data to push further upward to the
+transformation above this transformation. This can also be the user or script
+that originally read from the channel.
+.RS
+.PP
+Note that the result is allowed to be empty, or even less than the data we
+received; the transformation is not required to transform everything given to
+it right now. It is allowed to store incoming data in internal buffers and to
+defer the actual transformation until it has more data.
+.RE
+.SS "WRITE-RELATED SUBCOMMANDS"
+.PP
+These subcommands are used for handling transformations applied to writable
+channels; though strictly \fBwrite\fR is optional, it must be supported if any
+of the others is or the channel will be made non-writable.
+.TP
+\fIcmdPrefix \fBflush \fIhandle\fR
+.
+This optional subcommand is called whenever data in the transformation 'write'
+buffer has to be forced downward, i.e. towards the base channel. The result
+returned by the subcommand is taken as the binary data to write to the
+transformation below the current transformation. This can be the base channel
+as well.
+.RS
+.PP
+In other words, when this subcommand is called the transformation cannot defer
+the actual transformation operation anymore and has to transform all data
+waiting in its internal write buffers and return the result of that action.
+.RE
+.TP
+\fIcmdPrefix \fBwrite \fIhandle buffer\fR
+.
+This subcommand, which must be present if the transformation is to work with
+writable channels, is called whenever the user, or a transformation above this
+transformation, writes data downward. The \fIbuffer\fR contains the binary
+data which has been written to us. It is the responsibility of this subcommand
+to actually transform the data.
+.RS
+.PP
+The result returned by the subcommand is taken as the binary data to write to
+the transformation below this transformation. This can be the base channel as
+well. Note that the result is allowed to be empty, or less than the data we
+got; the transformation is not required to transform everything which was
+written to it right now. It is allowed to store this data in internal buffers
+and to defer the actual transformation until it has more data.
+.RE
+.SH "SEE ALSO"
+chan(n), refchan(n)
+.SH KEYWORDS
+API, channel, ensemble, prefix, transformation
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/try.n b/pkgs/msgcat/doc/try.n
new file mode 100644
index 0000000..393fe5b
--- /dev/null
+++ b/pkgs/msgcat/doc/try.n
@@ -0,0 +1,103 @@
+'\"
+'\" Copyright (c) 2008 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 try n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+try \- Trap and process errors and exceptions
+.SH SYNOPSIS
+\fBtry\fI body\fR ?\fIhandler...\fR? ?\fBfinally\fI script\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command executes the script \fIbody\fR and, depending on what the outcome
+of that script is (normal exit, error, or some other exceptional result), runs
+a handler script to deal with the case. Once that has all happened, if the
+\fBfinally\fR clause is present, the \fIscript\fR it includes will be run and
+the result of the handler (or the \fIbody\fR if no handler matched) is allowed
+to continue to propagate. Note that the \fBfinally\fR clause is processed even
+if an error occurs and irrespective of which, if any, \fIhandler\fR is used.
+.PP
+The \fIhandler\fR clauses are each expressed as several words, and must have
+one of the following forms:
+.TP
+\fBon \fIcode variableList script\fR
+.
+This clause matches if the evaluation of \fIbody\fR completed with the
+exception code \fIcode\fR. The \fIcode\fR may be expressed as an integer or
+one of the following literal words: \fBok\fR, \fBerror\fR, \fBreturn\fR,
+\fBbreak\fR, or \fBcontinue\fR. Those literals correspond to the integers 0
+through 4 respectively.
+.TP
+\fBtrap \fIpattern variableList script\fR
+.
+This clause matches if the evaluation of \fIbody\fR resulted in an error and
+the prefix of the \fB\-errorcode\fR from the interpreter's status dictionary
+is equal to the \fIpattern\fR. The number of prefix words taken from the
+\fB\-errorcode\fR is equal to the list-length of \fIpattern\fR, and inter-word
+spaces are normalized in both the \fB\-errorcode\fR and \fIpattern\fR before
+comparison.
+.PP
+The \fIvariableList\fR word in each \fIhandler\fR is always interpreted as a
+list of variable names. If the first word of the list is present and
+non-empty, it names a variable into which the result of the evaluation of
+\fIbody\fR (from the main \fBtry\fR) will be placed; this will contain the
+human-readable form of any errors. If the second word of the list is present
+and non-empty, it names a variable into which the options dictionary of the
+interpreter at the moment of completion of execution of \fIbody\fR
+will be placed.
+.PP
+The \fIscript\fR word of each \fIhandler\fR is also always interpreted the
+same: as a Tcl script to evaluate if the clause is matched. If \fIscript\fR is
+a literal
+.QW \-
+and the \fIhandler\fR is not the last one, the \fIscript\fR of the following
+\fIhandler\fR is invoked instead (just like with the \fBswitch\fR command).
+.PP
+Note that \fIhandler\fR clauses are matched against in order, and that the
+first matching one is always selected. At most one \fIhandler\fR clause will
+selected. As a consequence, an \fBon error\fR will mask any subsequent
+\fBtrap\fR in the \fBtry\fR. Also note that \fBon error\fR is equivalent to
+\fBtrap {}\fR.
+.PP
+If an exception (i.e. any non-\fBok\fR result) occurs during the evaluation of
+either the \fIhandler\fR or the \fBfinally\fR clause, the original exception's
+status dictionary will be added to the new exception's status dictionary under
+the \fB\-during\fR key.
+.SH EXAMPLES
+.PP
+Ensure that a file is closed no matter what:
+.PP
+.CS
+set f [open /some/file/name a]
+\fBtry\fR {
+ puts $f "some message"
+ # ...
+} \fBfinally\fR {
+ close $f
+}
+.CE
+.PP
+Handle different reasons for a file to not be openable for reading:
+.PP
+.CS
+\fBtry\fR {
+ set f [open /some/file/name]
+} \fBtrap\fR {POSIX EISDIR} {} {
+ puts "failed to open /some/file/name: it's a directory"
+} \fBtrap\fR {POSIX ENOENT} {} {
+ puts "failed to open /some/file/name: it doesn't exist"
+}
+.CE
+.SH "SEE ALSO"
+catch(n), error(n), return(n), throw(n)
+.SH "KEYWORDS"
+cleanup, error, exception, final, resource management
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/doc/unknown.n b/pkgs/msgcat/doc/unknown.n
new file mode 100644
index 0000000..fc2a5a1
--- /dev/null
+++ b/pkgs/msgcat/doc/unknown.n
@@ -0,0 +1,91 @@
+'\"
+'\" 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 unknown n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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 does not exist. The default implementation
+of \fBunknown\fR is a library procedure defined when Tcl initializes an
+interpreter. You can override the default \fBunknown\fR to change its
+functionality, or you can register a new handler for individual namespaces
+using the \fBnamespace unknown\fR command. Note that there is no default
+implementation of \fBunknown\fR in a safe interpreter.
+.PP
+If the Tcl interpreter encounters a command name for which there
+is not a defined command (in either the current namespace, or the
+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
+through library directories for a command procedure with the name
+\fIcmdName\fR, or expanding abbreviated command names to full-length,
+or automatically executing unknown commands as sub-processes.
+In some cases (such as expanding abbreviations) \fBunknown\fR will
+change the original command slightly and then (re-)execute it.
+The result of the \fBunknown\fR command is used as the result for
+the original non-existent command.
+.PP
+The default implementation of \fBunknown\fR behaves as follows.
+It first calls the \fBauto_load\fR library procedure to load the command.
+If this succeeds, then it executes the original command with its
+original arguments.
+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 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:
+\fB!!\fR, \fB!\fIevent\fR, or \fB^\fIold\fB^\fInew\fR?\fB^\fR?.
+If so, then \fBunknown\fR carries out history substitution
+in the same way that \fBcsh\fR would for these constructs.
+Finally, \fBunknown\fR checks to see if \fIcmd\fR is
+a unique abbreviation for an existing Tcl command.
+If so, it expands the command name and executes the command with
+the original arguments.
+If none of the above efforts has been able to execute
+the command, \fBunknown\fR generates an error return.
+If the global variable \fBauto_noload\fR is defined, then the auto-load
+step is skipped.
+If the global variable \fBauto_noexec\fR is defined then the
+auto-exec step is skipped.
+Under normal circumstances the return value from \fBunknown\fR
+is the return value from the command that was eventually
+executed.
+.SH EXAMPLE
+Arrange for the \fBunknown\fR command to have its standard behavior
+except for first logging the fact that a command was not found:
+.PP
+.CS
+# Save the original one so we can chain to it
+rename \fBunknown\fR _original_unknown
+
+# Provide our own implementation
+proc \fBunknown\fR args {
+ puts stderr "WARNING: unknown command: $args"
+ uplevel 1 [list _original_unknown {*}$args]
+}
+.CE
+.SH "SEE ALSO"
+info(n), proc(n), interp(n), library(n), namespace(n)
+.SH KEYWORDS
+error, non-existent command, unknown
diff --git a/pkgs/msgcat/doc/unload.n b/pkgs/msgcat/doc/unload.n
new file mode 100644
index 0000000..4c0b292
--- /dev/null
+++ b/pkgs/msgcat/doc/unload.n
@@ -0,0 +1,172 @@
+'\"
+'\" 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:
+.PP
+.CS
+typedef int \fBTcl_PackageUnloadProc\fR(
+ 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
+.PP
+If an unloadable module in the file \fBfoobar.dll\fR had been loaded
+using the \fBload\fR command like this (on Windows):
+.PP
+.CS
+load c:/some/dir/foobar.dll
+.CE
+.PP
+then it would be unloaded like this:
+.PP
+.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
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/pkgs/msgcat/doc/unset.n b/pkgs/msgcat/doc/unset.n
new file mode 100644
index 0000000..64b334d
--- /dev/null
+++ b/pkgs/msgcat/doc/unset.n
@@ -0,0 +1,68 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Ajuba Solutions.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH unset n 8.4 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+unset \- Delete variables
+.SH SYNOPSIS
+\fBunset \fR?\fB\-nocomplain\fR? ?\fB\-\-\fR? ?\fIname name name ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command removes one or more variables.
+Each \fIname\fR is a variable name, specified in any of the
+ways acceptable to the \fBset\fR command.
+If a \fIname\fR refers to an element of an array then that
+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.
+If \fB\-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 \fB\-\-\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.
+If an error occurs during variable deletion, any variables after the named one
+causing the error are not
+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
+.PP
+Create an array containing a mapping from some numbers to their
+squares and remove the array elements for non-prime numbers:
+.PP
+.CS
+array set squares {
+ 1 1 6 36
+ 2 4 7 49
+ 3 9 8 64
+ 4 16 9 81
+ 5 25 10 100
+}
+
+puts "The squares are:"
+parray squares
+
+\fBunset\fR squares(1) squares(4) squares(6)
+\fBunset\fR squares(8) squares(9) squares(10)
+
+puts "The prime squares are:"
+parray squares
+.CE
+.SH "SEE ALSO"
+set(n), trace(n), upvar(n)
+.SH KEYWORDS
+remove, variable
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/pkgs/msgcat/doc/update.n b/pkgs/msgcat/doc/update.n
new file mode 100644
index 0000000..0c77c5f
--- /dev/null
+++ b/pkgs/msgcat/doc/update.n
@@ -0,0 +1,65 @@
+'\"
+'\" Copyright (c) 1990-1992 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 update n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+update \- Process pending events and idle callbacks
+.SH SYNOPSIS
+\fBupdate\fR ?\fBidletasks\fR?
+.BE
+.SH DESCRIPTION
+.PP
+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
+If the \fBidletasks\fR keyword is specified as an argument to the
+command, then no new events or errors are processed; only idle
+callbacks are invoked.
+This causes operations that are normally deferred, such as display
+updates and window layout calculations, to be performed immediately.
+.PP
+The \fBupdate idletasks\fR command is useful in scripts where
+changes have been made to the application's state and you want those
+changes to appear on the display immediately, rather than waiting
+for the script to complete. Most display updates are performed as
+idle callbacks, so \fBupdate idletasks\fR will cause them to run.
+However, there are some kinds of updates that only happen in
+response to events, such as those triggered by window size changes;
+these updates will not occur in \fBupdate idletasks\fR.
+.PP
+The \fBupdate\fR command with no options is useful in scripts where
+you are performing a long-running computation but you still want
+the application to respond to events such as user interactions; if
+you occasionally call \fBupdate\fR then user input will be processed
+during the next call to \fBupdate\fR.
+.SH EXAMPLE
+.PP
+Run computations for about a second and then finish:
+.PP
+.CS
+set x 1000
+set done 0
+after 1000 set done 1
+while {!$done} {
+ # A very silly example!
+ set x [expr {log($x) ** 2.8}]
+
+ # Test to see if our time-limit has been hit. This would
+ # also give a chance for serving network sockets and, if
+ # the Tk package is loaded, updating a user interface.
+ \fBupdate\fR
+}
+.CE
+.SH "SEE ALSO"
+after(n), interp(n)
+.SH KEYWORDS
+asynchronous I/O, event, flush, handler, idle, update
diff --git a/pkgs/msgcat/doc/uplevel.n b/pkgs/msgcat/doc/uplevel.n
new file mode 100644
index 0000000..6c8a957
--- /dev/null
+++ b/pkgs/msgcat/doc/uplevel.n
@@ -0,0 +1,103 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH uplevel n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+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
+been passed to \fBconcat\fR; the result is then evaluated in the
+variable context indicated by \fIlevel\fR. \fBUplevel\fR returns
+the result of that evaluation.
+.PP
+If \fIlevel\fR is an integer then
+it gives a distance (up the procedure calling stack) to move before
+executing the command. If \fIlevel\fR consists of \fB#\fR followed by
+a number then the number gives an absolute level number. If \fIlevel\fR
+is omitted then it defaults to \fB1\fR. \fILevel\fR cannot be
+defaulted if the first \fIcommand\fR argument starts with a digit or \fB#\fR.
+.PP
+For example, suppose that procedure \fBa\fR was invoked
+from top-level, and that it called \fBb\fR, and that \fBb\fR called \fBc\fR.
+Suppose that \fBc\fR invokes the \fBuplevel\fR command. If \fIlevel\fR
+is \fB1\fR or \fB#2\fR or omitted, then the command will be executed
+in the variable context of \fBb\fR. If \fIlevel\fR is \fB2\fR or \fB#1\fR
+then the command will be executed in the variable context of \fBa\fR.
+If \fIlevel\fR is \fB3\fR or \fB#0\fR then the command will be executed
+at top-level (only global variables will be visible).
+.PP
+The \fBuplevel\fR command causes the invoking procedure to disappear
+from the procedure calling stack while the command is being executed.
+In the above example, suppose \fBc\fR invokes the command
+.PP
+.CS
+\fBuplevel\fR 1 {set x 43; d}
+.CE
+.PP
+where \fBd\fR is another Tcl procedure. The \fBset\fR command will
+modify the variable \fBx\fR in \fBb\fR's context, and \fBd\fR will execute
+at level 3, as if called from \fBb\fR. If it in turn executes
+the command
+.PP
+.CS
+\fBuplevel\fR {set x 42}
+.CE
+.PP
+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 \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
+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
+describing a command that is either
+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).
+.SH EXAMPLE
+As stated above, the \fBuplevel\fR command is useful for creating new
+control constructs. This example shows how (without error handling)
+it can be used to create a \fBdo\fR command that is the counterpart of
+\fBwhile\fR except for always performing the test after running the
+loop body:
+.PP
+.CS
+proc do {body while condition} {
+ if {$while ne "while"} {
+ error "required word missing"
+ }
+ set conditionCmd [list expr $condition]
+ while {1} {
+ \fBuplevel\fR 1 $body
+ if {![\fBuplevel\fR 1 $conditionCmd]} {
+ break
+ }
+ }
+}
+.CE
+.SH "SEE ALSO"
+apply(n), namespace(n), upvar(n)
+.SH KEYWORDS
+context, level, namespace, stack frame, variable
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/pkgs/msgcat/doc/upvar.n b/pkgs/msgcat/doc/upvar.n
new file mode 100644
index 0000000..60e5324
--- /dev/null
+++ b/pkgs/msgcat/doc/upvar.n
@@ -0,0 +1,122 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH upvar n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+upvar \- Create link to variable in a different stack frame
+.SH SYNOPSIS
+\fBupvar \fR?\fIlevel\fR? \fIotherVar myVar \fR?\fIotherVar myVar \fR...?
+.BE
+
+.SH DESCRIPTION
+.PP
+This command arranges for one or more local variables in the current
+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 (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
+in the current procedure by the name given in the corresponding
+\fImyVar\fR argument.
+The variable named by \fIotherVar\fR need not exist at the time of the
+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. 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.
+.PP
+The \fBupvar\fR command simplifies the implementation of call-by-name
+procedure calling and also makes it easier to build new control constructs
+as Tcl procedures.
+For example, consider the following procedure:
+.PP
+.CS
+proc \fIadd2\fR name {
+ \fBupvar\fR $name x
+ set x [expr {$x + 2}]
+}
+.CE
+.PP
+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 \fIadd2\fR
+to access the variable in the caller's procedure frame.
+.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.
+This means each \fBnamespace eval\fR command
+counts as another call level for \fBuplevel\fR and \fBupvar\fR commands.
+For example, \fBinfo level\fR \fB1\fR will return a list
+describing a command that is either
+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
+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
+by exiting the procedure in which it is defined. However, it is
+possible to retarget an upvar variable by executing another \fBupvar\fR
+command.
+.SH "TRACES AND UPVAR"
+.PP
+Upvar interacts with traces in a straightforward but possibly
+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
+.QW "\fIlocalVar\fR"
+rather than
+.QW "\fIoriginalVar\fR" :
+.PP
+.CS
+proc \fItraceproc\fR { name index op } {
+ puts $name
+}
+proc \fIsetByUpvar\fR { name value } {
+ \fBupvar\fR $name localVar
+ set localVar $value
+}
+set originalVar 1
+trace variable originalVar w \fItraceproc\fR
+\fIsetByUpvar\fR originalVar 2
+.CE
+.PP
+If \fIotherVar\fR refers to an element of an array, then variable
+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.
+.SH EXAMPLE
+A \fBdecr\fR command that works like \fBincr\fR except it subtracts
+the value from the variable instead of adding it:
+.PP
+.CS
+proc decr {varName {decrement 1}} {
+ \fBupvar\fR 1 $varName var
+ incr var [expr {-$decrement}]
+}
+.CE
+.SH "SEE ALSO"
+global(n), namespace(n), uplevel(n), variable(n)
+.SH KEYWORDS
+context, frame, global, level, namespace, procedure, upvar, variable
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/pkgs/msgcat/doc/variable.n b/pkgs/msgcat/doc/variable.n
new file mode 100644
index 0000000..96263b6
--- /dev/null
+++ b/pkgs/msgcat/doc/variable.n
@@ -0,0 +1,100 @@
+'\"
+'\" Copyright (c) 1993-1997 Bell Labs Innovations for Lucent Technologies
+'\" 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 variable n 8.0 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+variable \- create and initialize a namespace variable
+.SH SYNOPSIS
+\fBvariable \fR\fIname\fR
+.sp
+\fBvariable \fR?\fIname value...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command is normally used within a
+\fBnamespace eval\fR command to create one or more variables
+within a namespace.
+Each variable \fIname\fR is initialized with \fIvalue\fR.
+The \fIvalue\fR for the last variable is optional.
+.PP
+If a variable \fIname\fR does not exist, it is created.
+In this case, if \fIvalue\fR is specified,
+it is assigned to the newly created variable.
+If no \fIvalue\fR is specified, the new variable is left undefined.
+If the variable already exists,
+it is set to \fIvalue\fR if \fIvalue\fR is specified
+or left unchanged if no \fIvalue\fR is given.
+Normally, \fIname\fR is unqualified
+(does not include the names of any containing namespaces),
+and the variable is created in the current namespace.
+If \fIname\fR includes any namespace qualifiers,
+the variable is created in the specified namespace. If the variable
+is not defined, it will be visible to the \fBnamespace which\fR
+command, but not to the \fBinfo exists\fR command.
+.PP
+If the \fBvariable\fR command is executed inside a Tcl procedure,
+it creates local variables
+linked to the corresponding namespace variables (and therefore these
+variables are listed by \fBinfo vars\fR.)
+In this way the \fBvariable\fR command resembles the \fBglobal\fR command,
+although the \fBglobal\fR command
+only links to variables in the global namespace.
+If any \fIvalue\fRs are given,
+they are used to modify the values of the associated namespace variables.
+If a namespace variable does not exist,
+it is created and optionally initialized.
+.PP
+A \fIname\fR argument cannot reference an element within an array.
+Instead, \fIname\fR should reference the entire array,
+and the initialization \fIvalue\fR should be left off.
+After the variable has been declared,
+elements within the array can be set using ordinary
+\fBset\fR or \fBarray\fR commands.
+.SH EXAMPLES
+.PP
+Create a variable in a namespace:
+.PP
+.CS
+namespace eval foo {
+ \fBvariable\fR bar 12345
+}
+.CE
+.PP
+Create an array in a namespace:
+.PP
+.CS
+namespace eval someNS {
+ \fBvariable\fR someAry
+ array set someAry {
+ someName someValue
+ otherName otherValue
+ }
+}
+.CE
+.PP
+Access variables in namespaces from a procedure:
+.PP
+.CS
+namespace eval foo {
+ proc spong {} {
+ # Variable in this namespace
+ \fBvariable\fR bar
+ puts "bar is $bar"
+
+ # Variable in another namespace
+ \fBvariable\fR ::someNS::someAry
+ parray someAry
+ }
+}
+.CE
+.SH "SEE ALSO"
+global(n), namespace(n), upvar(n)
+.SH KEYWORDS
+global, namespace, procedure, variable
diff --git a/pkgs/msgcat/doc/vwait.n b/pkgs/msgcat/doc/vwait.n
new file mode 100644
index 0000000..38a8081
--- /dev/null
+++ b/pkgs/msgcat/doc/vwait.n
@@ -0,0 +1,246 @@
+'\"
+'\" 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.
+'\"
+.so man.macros
+.TH vwait n 8.0 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+vwait \- Process events until a variable is written
+.SH SYNOPSIS
+\fBvwait\fR \fIvarName\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command enters the Tcl event loop to process events, blocking
+the application if no events are ready. It continues processing
+events until some event handler sets the value of the global 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. The \fIvarName\fR argument is always interpreted as
+a variable name with respect to the global namespace, but can refer to any
+namespace's variables if the fully-qualified name is given.
+.PP
+In some cases the \fBvwait\fR command may not return immediately
+after \fIvarName\fR is set. This happens if the event handler
+that sets \fIvarName\fR does not complete immediately. For example,
+if an event handler sets \fIvarName\fR and then itself calls
+\fBvwait\fR to wait for a different variable, then it may not return
+for a long time. During this time the top-level \fBvwait\fR is
+blocked waiting for the event handler to complete, so it cannot
+return either. (See the \fBNESTED VWAITS BY EXAMPLE\fR below.)
+.PP
+To be clear, \fImultiple \fBvwait\fI calls will nest and will not happen in
+parallel\fR. The outermost call to \fBvwait\fR will not return until all the
+inner ones do. It is recommended that code should never nest \fBvwait\fR
+calls (by avoiding putting them in event callbacks) but when that is not
+possible, care should be taken to add interlock variables to the code to
+prevent all reentrant calls to \fBvwait\fR that are not \fIstrictly\fR
+necessary. Be aware that the synchronous modes of operation of some Tcl
+packages (e.g.,\ \fBhttp\fR) use \fBvwait\fR internally; if using the event
+loop, it is best to use the asynchronous callback-based modes of operation of
+those packages where available.
+.SH EXAMPLES
+.PP
+Run the event-loop continually until some event calls \fBexit\fR.
+(You can use any variable not mentioned elsewhere, but the name
+\fIforever\fR reminds you at a glance of the intent.)
+.PP
+.CS
+\fBvwait\fR forever
+.CE
+.PP
+Wait five seconds for a connection to a server socket, otherwise
+close the socket and continue running the script:
+.PP
+.CS
+# Initialise the state
+after 5000 set state timeout
+set server [socket -server accept 12345]
+proc accept {args} {
+ global state connectionInfo
+ set state accepted
+ set connectionInfo $args
+}
+
+# Wait for something to happen
+\fBvwait\fR state
+
+# Clean up events that could have happened
+close $server
+after cancel set state timeout
+
+# Do something based on how the vwait finished...
+switch $state {
+ timeout {
+ puts "no connection on port 12345"
+ }
+ accepted {
+ puts "connection: $connectionInfo"
+ puts [lindex $connectionInfo 0] "Hello there!"
+ }
+}
+.CE
+.PP
+A command that will wait for some time delay by waiting for a namespace
+variable to be set. Includes an interlock to prevent nested waits.
+.PP
+.CS
+namespace eval example {
+ variable v done
+ proc wait {delay} {
+ variable v
+ if {$v ne "waiting"} {
+ set v waiting
+ after $delay [namespace code {set v done}]
+ \fBvwait\fR [namespace which -variable v]
+ }
+ return $v
+ }
+}
+.CE
+.PP
+When running inside a \fBcoroutine\fR, an alternative to using \fBvwait\fR is
+to \fByield\fR to an outer event loop and to get recommenced when the variable
+is set, or at an idle moment after that.
+.PP
+.CS
+coroutine task apply {{} {
+ # simulate [after 1000]
+ after 1000 [info coroutine]
+ yield
+
+ # schedule the setting of a global variable, as normal
+ after 2000 {set var 1}
+
+ # simulate [\fBvwait\fR var]
+ proc updatedVar {task args} {
+ after idle $task
+ trace remove variable ::var write "updatedVar $task"
+ }
+ trace add variable ::var write "updatedVar [info coroutine]"
+ yield
+}}
+.CE
+.SS "NESTED VWAITS BY EXAMPLE"
+.PP
+This example demonstrates what can happen when the \fBvwait\fR command is
+nested. The script will never finish because the waiting for the \fIa\fR
+variable never finishes; that \fBvwait\fR command is still waiting for a
+script scheduled with \fBafter\fR to complete, which just happens to be
+running an inner \fBvwait\fR (for \fIb\fR) even though the event that the
+outer \fBvwait\fR was waiting for (the setting of \fIa\fR) has occurred.
+.PP
+.CS
+after 500 {
+ puts "waiting for b"
+ \fBvwait\fR b
+ puts "b was set"
+}
+after 1000 {
+ puts "setting a"
+ set a 10
+}
+puts "waiting for a"
+\fBvwait\fR a
+puts "a was set"
+puts "setting b"
+set b 42
+.CE
+.PP
+If you run the above code, you get this output:
+.PP
+.CS
+waiting for a
+waiting for b
+setting a
+.CE
+.PP
+The script will never print
+.QW "a was set"
+until after it has printed
+.QW "b was set"
+because of the nesting of \fBvwait\fR commands, and yet \fIb\fR will not be
+set until after the outer \fBvwait\fR returns, so the script has deadlocked.
+The only ways to avoid this are to either structure the overall program in
+continuation-passing style or to use \fBcoroutine\fR to make the continuations
+implicit. The first of these options would be written as:
+.PP
+.CS
+after 500 {
+ puts "waiting for b"
+ trace add variable b write {apply {args {
+ global a b
+ trace remove variable ::b write \e
+ [lrange [info level 0] 0 1]
+ puts "b was set"
+ set ::done ok
+ }}}
+}
+after 1000 {
+ puts "setting a"
+ set a 10
+}
+puts "waiting for a"
+trace add variable a write {apply {args {
+ global a b
+ trace remove variable a write [lrange [info level 0] 0 1]
+ puts "a was set"
+ puts "setting b"
+ set b 42
+}}}
+\fBvwait\fR done
+.CE
+.PP
+The second option, with \fBcoroutine\fR and some helper procedures, is done
+like this:
+.PP
+.CS
+# A coroutine-based wait-for-variable command
+proc waitvar globalVar {
+ trace add variable ::$globalVar write \e
+ [list apply {{v c args} {
+ trace remove variable $v write \e
+ [lrange [info level 0] 0 3]
+ after 0 $c
+ }} ::$globalVar [info coroutine]]
+ yield
+}
+# A coroutine-based wait-for-some-time command
+proc waittime ms {
+ after $ms [info coroutine]
+ yield
+}
+
+coroutine task-1 eval {
+ puts "waiting for a"
+ waitvar a
+ puts "a was set"
+ puts "setting b"
+ set b 42
+}
+coroutine task-2 eval {
+ waittime 500
+ puts "waiting for b"
+ waitvar b
+ puts "b was set"
+ set done ok
+}
+coroutine task-3 eval {
+ waittime 1000
+ puts "setting a"
+ set a 10
+}
+\fBvwait\fR done
+.CE
+.SH "SEE ALSO"
+global(n), update(n)
+.SH KEYWORDS
+asynchronous I/O, event, variable, wait
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/pkgs/msgcat/doc/while.n b/pkgs/msgcat/doc/while.n
new file mode 100644
index 0000000..5416e25
--- /dev/null
+++ b/pkgs/msgcat/doc/while.n
@@ -0,0 +1,65 @@
+'\"
+'\" Copyright (c) 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.
+'\"
+.so man.macros
+.TH while n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+while \- Execute script repeatedly as long as a condition is met
+.SH SYNOPSIS
+\fBwhile \fItest body\fR
+.BE
+.SH DESCRIPTION
+.PP
+The \fBwhile\fR command evaluates \fItest\fR as an expression
+(in the same way that \fBexpr\fR evaluates its argument).
+The value of the expression must a proper boolean
+value; if it is a true value
+then \fIbody\fR is executed by passing it to the Tcl interpreter.
+Once \fIbody\fR has been executed then \fItest\fR is evaluated
+again, and the process repeats until eventually \fItest\fR
+evaluates to a false boolean value. \fBContinue\fR
+commands may be executed inside \fIbody\fR to terminate the current
+iteration of the loop, and \fBbreak\fR
+commands may be executed inside \fIbody\fR to cause immediate
+termination of the \fBwhile\fR command. The \fBwhile\fR command
+always returns an empty string.
+.PP
+Note: \fItest\fR should almost always be enclosed in braces. If not,
+variable substitutions will be made before the \fBwhile\fR
+command starts executing, which means that variable changes
+made by the loop body will not be considered in the expression.
+This is likely to result in an infinite loop. If \fItest\fR is
+enclosed in braces, variable substitutions are delayed until the
+expression is evaluated (before
+each loop iteration), so changes in the variables will be visible.
+For an example, try the following script with and without the braces
+around \fB$x<10\fR:
+.PP
+.CS
+set x 0
+\fBwhile\fR {$x<10} {
+ puts "x is $x"
+ incr x
+}
+.CE
+.SH EXAMPLE
+.PP
+Read lines from a channel until we get to the end of the stream, and
+print them out with a line-number prepended:
+.PP
+.CS
+set lineCount 0
+\fBwhile\fR {[gets $chan line] >= 0} {
+ puts "[incr lineCount]: $line"
+}
+.CE
+.SH "SEE ALSO"
+break(n), continue(n), for(n), foreach(n)
+.SH KEYWORDS
+boolean, loop, test, while
diff --git a/pkgs/msgcat/doc/zlib.n b/pkgs/msgcat/doc/zlib.n
new file mode 100644
index 0000000..a4ff7f8
--- /dev/null
+++ b/pkgs/msgcat/doc/zlib.n
@@ -0,0 +1,391 @@
+'\"
+'\" Copyright (c) 2008 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH zlib n 8.6 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+zlib \- compression and decompression operations
+.SH SYNOPSIS
+.nf
+\fBzlib \fIsubcommand arg ...\fR
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBzlib\fR command provides access to the compression and check-summing
+facilities of the Zlib library by Jean-loup Gailly and Mark Adler. It has the
+following subcommands.
+.SS "COMPRESSION SUBCOMMANDS"
+.TP
+\fBzlib compress\fI string\fR ?\fIlevel\fR?
+.
+Returns the zlib-format compressed binary data of the binary string in
+\fIstring\fR. If present, \fIlevel\fR gives the compression level to use (from
+0, which is uncompressed, to 9, maximally compressed).
+.TP
+\fBzlib decompress\fI string\fR ?\fIbufferSize\fR?
+.
+Returns the uncompressed version of the raw compressed binary data in
+\fIstring\fR. If present, \fIbufferSize\fR is a hint as to what size of buffer
+is to be used to receive the data.
+.TP
+\fBzlib deflate\fI string\fR ?\fIlevel\fR?
+.
+Returns the raw compressed binary data of the binary string in \fIstring\fR.
+If present, \fIlevel\fR gives the compression level to use (from 0, which is
+uncompressed, to 9, maximally compressed).
+.TP
+\fBzlib gunzip\fI string\fR ?\fB\-headerVar \fIvarName\fR?
+.
+Return the uncompressed contents of binary string \fIstring\fR, which must
+have been in gzip format. If \fB\-headerVar\fR is given, store a dictionary
+describing the contents of the gzip header in the variable called
+\fIvarName\fR. The keys of the dictionary that may be present are:
+.RS
+.TP
+\fBcomment\fR
+.
+The comment field from the header, if present.
+.TP
+\fBcrc\fR
+.
+A boolean value describing whether a CRC of the header is computed.
+.TP
+\fBfilename\fR
+.
+The filename field from the header, if present.
+.TP
+\fBos\fR
+.
+The operating system type code field from the header (if not the
+QW unknown
+value). See RFC 1952 for the meaning of these codes.
+.TP
+\fBsize\fR
+.
+The size of the uncompressed data.
+.TP
+\fBtime\fR
+.
+The time field from the header if non-zero, expected to be time that the file
+named by the \fBfilename\fR field was modified. Suitable for use with
+\fBclock format\fR.
+.TP
+\fBtype\fR
+.
+The type of the uncompressed data (\fBbinary\fR or \fBtext\fR) if known.
+.RE
+.TP
+\fBzlib gzip\fI string\fR ?\fB\-level \fIlevel\fR? ?\fB\-header \fIdict\fR?
+.
+Return the compressed contents of binary string \fIstring\fR in gzip format.
+If \fB\-level\fR is given, \fIlevel\fR gives the compression level to use
+(from 0, which is uncompressed, to 9, maximally compressed). If \fB\-header\fR
+is given, \fIdict\fR is a dictionary containing values used for the gzip
+header. The following keys may be defined:
+.RS
+.TP
+\fBcomment\fR
+.
+Add the given comment to the header of the gzip-format data.
+.TP
+\fBcrc\fR
+.
+A boolean saying whether to compute a CRC of the header. Note that if the data
+is to be interchanged with the \fBgzip\fR program, a header CRC should
+\fInot\fR be computed.
+.TP
+\fBfilename\fR
+.
+The name of the file that the data to be compressed came from.
+.TP
+\fBos\fR
+.
+The operating system type code, which should be one of the values described in
+RFC 1952.
+.TP
+\fBtime\fR
+.
+The time that the file named in the \fBfilename\fR key was last modified. This
+will be in the same as is returned by \fBclock seconds\fR or \fBfile mtime\fR.
+.TP
+\fBtype\fR
+.
+The type of the data being compressed, being \fBbinary\fR or \fBtext\fR.
+.RE
+.TP
+\fBzlib inflate\fI string\fR ?\fIbufferSize\fR?
+.
+Returns the uncompressed version of the raw compressed binary data in
+\fIstring\fR. If present, \fIbufferSize\fR is a hint as to what size of buffer
+is to be used to receive the data.
+.SS "CHANNEL SUBCOMMAND"
+.TP
+\fBzlib push\fI mode channel\fR ?\fIoptions ...\fR?
+.
+Pushes a compressing or decompressing transformation onto the channel
+\fIchannel\fR.
+The transformation can be removed again with \fBchan pop\fR.
+The \fImode\fR argument determines what type of transformation
+is pushed; the following are supported:
+.RS
+.TP
+\fBcompress\fR
+.
+The transformation will be a compressing transformation that produces
+zlib-format data on \fIchannel\fR, which must be writable.
+.TP
+\fBdecompress\fR
+.
+The transformation will be a decompressing transformation that reads
+zlib-format data from \fIchannel\fR, which must be readable.
+.TP
+\fBdeflate\fR
+.
+The transformation will be a compressing transformation that produces raw
+compressed data on \fIchannel\fR, which must be writable.
+.TP
+\fBgunzip\fR
+.
+The transformation will be a decompressing transformation that reads
+gzip-format data from \fIchannel\fR, which must be readable.
+.TP
+\fBgzip\fR
+.
+The transformation will be a compressing transformation that produces
+gzip-format data on \fIchannel\fR, which must be writable.
+.TP
+\fBinflate\fR
+.
+The transformation will be a decompressing transformation that reads raw
+compressed data from \fIchannel\fR, which must be readable.
+.PP
+The following options may be set when creating a transformation via
+the
+.QW "\fIoptions ...\fR"
+to the \fBzlib push\fR command:
+.TP
+\fB\-header\fI dictionary\fR
+.
+Passes a description of the gzip header to create, in the same format that
+\fBzlib gzip\fR understands.
+.TP
+\fB\-level\fI compressionLevel\fR
+.
+How hard to compress the data. Must be an integer from 0 (uncompressed) to 9
+(maximally compressed).
+'\".TP
+'\"\fB\-limit\fI readaheadLimit\fR
+'\".
+'\"The maximum number of bytes ahead to read.
+'\"\fITODO: not yet implemented!\fR
+.PP
+Both compressing and decompressing channel transformations add extra
+configuration options that may be accessed through \fBchan configure\fR. Each
+option is either a read-only or a write-only option. The options are:
+.TP
+\fB\-flush\fI type\fR
+.
+This write-only operation flushes the current state of the compressor to the
+underlying channel. It is only valid for compressing transformations. The
+\fItype\fR must be either \fBsync\fR or \fBfull\fR for a normal flush or an
+expensive flush respectively. Flushing degrades the compression ratio, but
+makes it easier for a decompressor to recover more of the file in the case of
+data corruption.
+.TP
+\fB\-checksum\fR
+.
+This read-only option gets the current checksum for the uncompressed data
+that the compression engine has seen so far. It is valid for both
+compressing and decompressing transforms, but not for the raw inflate
+and deflate formats. The compression algorithm depends on what
+format is being produced or consumed.
+.TP
+\fB\-header\fR
+.
+This read-only option, only valid for decompressing transforms that are
+processing gzip-format data, returns the dictionary describing the header read
+off the data stream.
+.RE
+.SS "STREAMING SUBCOMMAND"
+.TP
+\fBzlib stream\fI mode\fR ?\fIlevel\fR?
+.
+Creates a streaming compression or decompression command based on the
+\fImode\fR, and return the name of the command. For a description of how that
+command works, see \fBSTREAMING INSTANCE COMMAND\fR below. The following modes
+are supported:
+.RS
+.TP
+\fBzlib stream compress\fR ?\fIlevel\fR?
+.
+The stream will be a compressing stream that produces zlib-format output,
+using compression level \fIlevel\fR (if specified) which will be an integer
+from 0 to 9.
+.TP
+\fBzlib stream decompress\fR
+.
+The stream will be a decompressing stream that takes zlib-format input and
+produces uncompressed output.
+.TP
+\fBzlib stream deflate\fR ?\fIlevel\fR?
+.
+The stream will be a compressing stream that produces raw output, using
+compression level \fIlevel\fR (if specified) which will be an integer from 0
+to 9.
+.TP
+\fBzlib stream gunzip\fR
+.
+The stream will be a decompressing stream that takes gzip-format input and
+produces uncompressed output.
+.TP
+\fBzlib stream gzip\fR ?\fIlevel\fR?
+.
+The stream will be a compressing stream that produces gzip-format output,
+using compression level \fIlevel\fR (if specified) which will be an integer
+from 0 to 9.
+'\" TODO: Header dictionary!
+.TP
+\fBzlib stream inflate\fR
+.
+The stream will be a decompressing stream that takes raw compressed input and
+produces uncompressed output.
+.RE
+.SS "CHECKSUMMING SUBCOMMANDS"
+.TP
+\fBzlib adler32\fI string\fR ?\fIinitValue\fR?
+.
+Compute a checksum of binary string \fIstring\fR using the Adler-32 algorithm.
+If given, \fIinitValue\fR is used to initialize the checksum engine.
+.TP
+\fBzlib crc32\fI string\fR ?\fIinitValue\fR?
+.
+Compute a checksum of binary string \fIstring\fR using the CRC-32 algorithm.
+If given, \fIinitValue\fR is used to initialize the checksum engine.
+.SH "STREAMING INSTANCE COMMAND"
+.PP
+Streaming compression instance commands are produced by the \fBzlib stream\fR
+command. They are used by calling their \fBput\fR subcommand one or more times
+to load data in, and their \fBget\fR subcommand one or more times to extract
+the transformed data.
+.PP
+The full set of subcommands supported by a streaming instance command,
+\fIstream\fR, is as follows:
+.TP
+\fIstream \fBadd\fR ?\fIoption\fR? \fIdata\fR
+.
+A short-cut for
+.QW "\fIstream \fBput \fIoption data\fR"
+followed by
+.QW "\fIstream \fBget\fR" .
+.TP
+\fIstream \fBchecksum\fR
+.
+Returns the checksum of the uncompressed data seen so far by this stream.
+.TP
+\fIstream \fBclose\fR
+.
+Deletes this stream and frees up all resources associated with it.
+.TP
+\fIstream \fBeof\fR
+.
+Returns a boolean indicating whether the end of the stream (as determined by
+the compressed data itself) has been reached. Not all formats support
+detection of the end of the stream.
+.TP
+\fIstream \fBfinalize\fR
+.
+A short-cut for
+.QW "\fIstream \fBput \-finalize {}\fR" .
+.TP
+\fIstream \fBflush\fR
+.
+A short-cut for
+.QW "\fIstream \fBput \-flush {}\fR" .
+.TP
+\fIstream \fBfullflush\fR
+.
+A short-cut for
+.QW "\fIstream \fBput \-fullflush {}\fR" .
+.TP
+\fIstream \fBget \fR?\fIcount\fR?
+.
+Return up to \fIcount\fR bytes from \fIstream\fR's internal buffers with the
+transformation applied. If \fIcount\fR is omitted, the entire contents of the
+buffers are returned.
+.TP
+\fIstream \fBput\fR ?\fIoption\fR? \fIdata\fR
+.
+Append the contents of the binary string \fIdata\fR to \fIstream\fR's internal
+buffers while applying the transformation. If present, \fIoption\fR must be
+one of the following (or an unambiguous prefix) which are used to modify the
+way in which the transformation is applied:
+.RS
+.TP
+\fB\-finalize\fR
+.
+Mark the stream as finished, ensuring that all bytes have been wholly
+compressed or decompressed. For gzip streams, this also ensures that the
+footer is written to the stream. The stream will need to be reset before
+having more data written to it after this, though data can still be read out
+of the stream with the \fBget\fR subcommand.
+.TP
+\fB\-flush\fR
+.
+Ensure that a decompressor consuming the bytes that the current (compressing)
+stream is producing will be able to produce all the bytes that have been
+compressed so far, at some performance penalty.
+.TP
+\fB\-fullflush\fR
+.
+Ensure that not only can a decompressor handle all the bytes produced so far
+(as with \fB\-flush\fR above) but also that it can restart from this point if
+it detects that the stream is partially corrupt. This incurs a substantial
+performance penalty.
+.RE
+.TP
+\fIstream \fBreset\fR
+.
+Puts any stream, including those that have been finalized or that have reached
+eof, back into a state where it can process more data. Throws away all
+internally buffered data.
+.SH EXAMPLES
+.PP
+To compress a Tcl string, it should be first converted to a particular charset
+encoding since the \fBzlib\fR command always operates on binary strings.
+.PP
+.CS
+set binData [encoding convertto utf-8 $string]
+set compData [\fBzlib compress\fR $binData]
+.CE
+.PP
+When converting back, it is also important to reverse the charset encoding:
+.PP
+.CS
+set binData [\fBzlib decompress\fR $compData]
+set string [encoding convertfrom utf-8 $binData]
+.CE
+.PP
+The compression operation from above can also be done with streams, which is
+especially helpful when you want to accumulate the data by stages:
+.PP
+.CS
+set strm [\fBzlib stream\fR compress]
+$\fIstrm \fBput\fR [encoding convertto utf-8 $string]
+# ...
+$\fIstrm \fBfinalize\fR
+set compData [$\fIstrm \fBget\fR]
+$\fIstrm \fBclose\fR
+.CE
+.SH "SEE ALSO"
+binary(n), chan(n), encoding(n), Tcl_ZlibDeflate(3), RFC1950 \- RFC1952
+.SH "KEYWORDS"
+compress, decompress, deflate, gzip, inflate
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/pkgs/msgcat/msgcat.tcl b/pkgs/msgcat/msgcat.tcl
new file mode 100644
index 0000000..369ed52
--- /dev/null
+++ b/pkgs/msgcat/msgcat.tcl
@@ -0,0 +1,497 @@
+# msgcat.tcl --
+#
+# This file defines various procedures which implement a
+# message catalog facility for Tcl programs. It should be
+# loaded with the command "package require msgcat".
+#
+# Copyright (c) 1998-2000 by Ajuba Solutions.
+# Copyright (c) 1998 by Mark Harrison.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require Tcl 8.5
+# When the version number changes, be sure to update the pkgIndex.tcl file,
+# and the installation directory in the Makefiles.
+package provide msgcat 1.4.4
+
+namespace eval msgcat {
+ namespace export mc mcload mclocale mcmax mcmset mcpreferences mcset \
+ mcunknown
+
+ # Records the current locale as passed to mclocale
+ variable Locale ""
+
+ # Records the list of locales to search
+ variable Loclist {}
+
+ # Records the mapping between source strings and translated strings. The
+ # dict key is of the form "<locale> <namespace> <src>", where locale and
+ # namespace should be themselves dict values and the value is
+ # the translated string.
+ variable Msgs [dict create]
+
+ # Map of language codes used in Windows registry to those of ISO-639
+ if { $::tcl_platform(platform) eq "windows" } {
+ variable WinRegToISO639 [dict create {*}{
+ 01 ar 0401 ar_SA 0801 ar_IQ 0c01 ar_EG 1001 ar_LY 1401 ar_DZ
+ 1801 ar_MA 1c01 ar_TN 2001 ar_OM 2401 ar_YE 2801 ar_SY
+ 2c01 ar_JO 3001 ar_LB 3401 ar_KW 3801 ar_AE 3c01 ar_BH
+ 4001 ar_QA
+ 02 bg 0402 bg_BG
+ 03 ca 0403 ca_ES
+ 04 zh 0404 zh_TW 0804 zh_CN 0c04 zh_HK 1004 zh_SG 1404 zh_MO
+ 05 cs 0405 cs_CZ
+ 06 da 0406 da_DK
+ 07 de 0407 de_DE 0807 de_CH 0c07 de_AT 1007 de_LU 1407 de_LI
+ 08 el 0408 el_GR
+ 09 en 0409 en_US 0809 en_GB 0c09 en_AU 1009 en_CA 1409 en_NZ
+ 1809 en_IE 1c09 en_ZA 2009 en_JM 2409 en_GD 2809 en_BZ
+ 2c09 en_TT 3009 en_ZW 3409 en_PH
+ 0a es 040a es_ES 080a es_MX 0c0a es_ES@modern 100a es_GT 140a es_CR
+ 180a es_PA 1c0a es_DO 200a es_VE 240a es_CO 280a es_PE
+ 2c0a es_AR 300a es_EC 340a es_CL 380a es_UY 3c0a es_PY
+ 400a es_BO 440a es_SV 480a es_HN 4c0a es_NI 500a es_PR
+ 0b fi 040b fi_FI
+ 0c fr 040c fr_FR 080c fr_BE 0c0c fr_CA 100c fr_CH 140c fr_LU
+ 180c fr_MC
+ 0d he 040d he_IL
+ 0e hu 040e hu_HU
+ 0f is 040f is_IS
+ 10 it 0410 it_IT 0810 it_CH
+ 11 ja 0411 ja_JP
+ 12 ko 0412 ko_KR
+ 13 nl 0413 nl_NL 0813 nl_BE
+ 14 no 0414 no_NO 0814 nn_NO
+ 15 pl 0415 pl_PL
+ 16 pt 0416 pt_BR 0816 pt_PT
+ 17 rm 0417 rm_CH
+ 18 ro 0418 ro_RO
+ 19 ru
+ 1a hr 041a hr_HR 081a sr_YU 0c1a sr_YU@cyrillic
+ 1b sk 041b sk_SK
+ 1c sq 041c sq_AL
+ 1d sv 041d sv_SE 081d sv_FI
+ 1e th 041e th_TH
+ 1f tr 041f tr_TR
+ 20 ur 0420 ur_PK 0820 ur_IN
+ 21 id 0421 id_ID
+ 22 uk 0422 uk_UA
+ 23 be 0423 be_BY
+ 24 sl 0424 sl_SI
+ 25 et 0425 et_EE
+ 26 lv 0426 lv_LV
+ 27 lt 0427 lt_LT
+ 28 tg 0428 tg_TJ
+ 29 fa 0429 fa_IR
+ 2a vi 042a vi_VN
+ 2b hy 042b hy_AM
+ 2c az 042c az_AZ@latin 082c az_AZ@cyrillic
+ 2d eu
+ 2e wen 042e wen_DE
+ 2f mk 042f mk_MK
+ 30 bnt 0430 bnt_TZ
+ 31 ts 0431 ts_ZA
+ 33 ven 0433 ven_ZA
+ 34 xh 0434 xh_ZA
+ 35 zu 0435 zu_ZA
+ 36 af 0436 af_ZA
+ 37 ka 0437 ka_GE
+ 38 fo 0438 fo_FO
+ 39 hi 0439 hi_IN
+ 3a mt 043a mt_MT
+ 3b se 043b se_NO
+ 043c gd_UK 083c ga_IE
+ 3d yi 043d yi_IL
+ 3e ms 043e ms_MY 083e ms_BN
+ 3f kk 043f kk_KZ
+ 40 ky 0440 ky_KG
+ 41 sw 0441 sw_KE
+ 42 tk 0442 tk_TM
+ 43 uz 0443 uz_UZ@latin 0843 uz_UZ@cyrillic
+ 44 tt 0444 tt_RU
+ 45 bn 0445 bn_IN
+ 46 pa 0446 pa_IN
+ 47 gu 0447 gu_IN
+ 48 or 0448 or_IN
+ 49 ta
+ 4a te 044a te_IN
+ 4b kn 044b kn_IN
+ 4c ml 044c ml_IN
+ 4d as 044d as_IN
+ 4e mr 044e mr_IN
+ 4f sa 044f sa_IN
+ 50 mn
+ 51 bo 0451 bo_CN
+ 52 cy 0452 cy_GB
+ 53 km 0453 km_KH
+ 54 lo 0454 lo_LA
+ 55 my 0455 my_MM
+ 56 gl 0456 gl_ES
+ 57 kok 0457 kok_IN
+ 58 mni 0458 mni_IN
+ 59 sd
+ 5a syr 045a syr_TR
+ 5b si 045b si_LK
+ 5c chr 045c chr_US
+ 5d iu 045d iu_CA
+ 5e am 045e am_ET
+ 5f ber 045f ber_MA
+ 60 ks 0460 ks_PK 0860 ks_IN
+ 61 ne 0461 ne_NP 0861 ne_IN
+ 62 fy 0462 fy_NL
+ 63 ps
+ 64 tl 0464 tl_PH
+ 65 div 0465 div_MV
+ 66 bin 0466 bin_NG
+ 67 ful 0467 ful_NG
+ 68 ha 0468 ha_NG
+ 69 nic 0469 nic_NG
+ 6a yo 046a yo_NG
+ 70 ibo 0470 ibo_NG
+ 71 kau 0471 kau_NG
+ 72 om 0472 om_ET
+ 73 ti 0473 ti_ET
+ 74 gn 0474 gn_PY
+ 75 cpe 0475 cpe_US
+ 76 la 0476 la_VA
+ 77 so 0477 so_SO
+ 78 sit 0478 sit_CN
+ 79 pap 0479 pap_AN
+ }]
+ }
+}
+
+# msgcat::mc --
+#
+# Find the translation for the given string based on the current
+# locale setting. Check the local namespace first, then look in each
+# parent namespace until the source is found. If additional args are
+# specified, use the format command to work them into the traslated
+# string.
+#
+# Arguments:
+# src The string to translate.
+# args Args to pass to the format command
+#
+# Results:
+# Returns the translated string. Propagates errors thrown by the
+# format command.
+
+proc msgcat::mc {src args} {
+ # Check for the src in each namespace starting from the local and
+ # ending in the global.
+
+ variable Msgs
+ variable Loclist
+ variable Locale
+
+ set ns [uplevel 1 [list ::namespace current]]
+
+ while {$ns != ""} {
+ foreach loc $Loclist {
+ if {[dict exists $Msgs $loc $ns $src]} {
+ if {[llength $args] == 0} {
+ return [dict get $Msgs $loc $ns $src]
+ } else {
+ return [format [dict get $Msgs $loc $ns $src] {*}$args]
+ }
+ }
+ }
+ set ns [namespace parent $ns]
+ }
+ # we have not found the translation
+ return [uplevel 1 [list [namespace origin mcunknown] \
+ $Locale $src {*}$args]]
+}
+
+# msgcat::mclocale --
+#
+# Query or set the current locale.
+#
+# Arguments:
+# newLocale (Optional) The new locale string. Locale strings
+# should be composed of one or more sublocale parts
+# separated by underscores (e.g. en_US).
+#
+# Results:
+# Returns the current locale.
+
+proc msgcat::mclocale {args} {
+ variable Loclist
+ variable Locale
+ set len [llength $args]
+
+ if {$len > 1} {
+ return -code error "wrong # args: should be\
+ \"[lindex [info level 0] 0] ?newLocale?\""
+ }
+
+ if {$len == 1} {
+ set newLocale [lindex $args 0]
+ if {$newLocale ne [file tail $newLocale]} {
+ return -code error "invalid newLocale value \"$newLocale\":\
+ could be path to unsafe code."
+ }
+ set Locale [string tolower $newLocale]
+ set Loclist {}
+ set word ""
+ foreach part [split $Locale _] {
+ set word [string trim "${word}_${part}" _]
+ if {$word ne [lindex $Loclist 0]} {
+ set Loclist [linsert $Loclist 0 $word]
+ }
+ }
+ lappend Loclist {}
+ set Locale [lindex $Loclist 0]
+ }
+ return $Locale
+}
+
+# msgcat::mcpreferences --
+#
+# Fetch the list of locales used to look up strings, ordered from
+# most preferred to least preferred.
+#
+# Arguments:
+# None.
+#
+# Results:
+# Returns an ordered list of the locales preferred by the user.
+
+proc msgcat::mcpreferences {} {
+ variable Loclist
+ return $Loclist
+}
+
+# msgcat::mcload --
+#
+# Attempt to load message catalogs for each locale in the
+# preference list from the specified directory.
+#
+# Arguments:
+# langdir The directory to search.
+#
+# Results:
+# Returns the number of message catalogs that were loaded.
+
+proc msgcat::mcload {langdir} {
+ set x 0
+ foreach p [mcpreferences] {
+ if { $p eq {} } {
+ set p ROOT
+ }
+ set langfile [file join $langdir $p.msg]
+ if {[file exists $langfile]} {
+ incr x
+ uplevel 1 [list ::source -encoding utf-8 $langfile]
+ }
+ }
+ return $x
+}
+
+# msgcat::mcset --
+#
+# Set the translation for a given string in a specified locale.
+#
+# Arguments:
+# locale The locale to use.
+# src The source string.
+# dest (Optional) The translated string. If omitted,
+# the source string is used.
+#
+# Results:
+# Returns the new locale.
+
+proc msgcat::mcset {locale src {dest ""}} {
+ variable Msgs
+ if {[llength [info level 0]] == 3} { ;# dest not specified
+ set dest $src
+ }
+
+ set ns [uplevel 1 [list ::namespace current]]
+
+ set locale [string tolower $locale]
+
+ dict set Msgs $locale $ns $src $dest
+ return $dest
+}
+
+# msgcat::mcmset --
+#
+# Set the translation for multiple strings in a specified locale.
+#
+# Arguments:
+# locale The locale to use.
+# pairs One or more src/dest pairs (must be even length)
+#
+# Results:
+# Returns the number of pairs processed
+
+proc msgcat::mcmset {locale pairs } {
+ variable Msgs
+
+ set length [llength $pairs]
+ if {$length % 2} {
+ return -code error "bad translation list:\
+ should be \"[lindex [info level 0] 0] locale {src dest ...}\""
+ }
+
+ set locale [string tolower $locale]
+ set ns [uplevel 1 [list ::namespace current]]
+
+ foreach {src dest} $pairs {
+ dict set Msgs $locale $ns $src $dest
+ }
+
+ return $length
+}
+
+# msgcat::mcunknown --
+#
+# This routine is called by msgcat::mc if a translation cannot
+# be found for a string. This routine is intended to be replaced
+# by an application specific routine for error reporting
+# purposes. The default behavior is to return the source string.
+# If additional args are specified, the format command will be used
+# to work them into the traslated string.
+#
+# Arguments:
+# locale The current locale.
+# src The string to be translated.
+# args Args to pass to the format command
+#
+# Results:
+# Returns the translated value.
+
+proc msgcat::mcunknown {locale src args} {
+ if {[llength $args]} {
+ return [format $src {*}$args]
+ } else {
+ return $src
+ }
+}
+
+# msgcat::mcmax --
+#
+# Calculates the maximum length of the translated strings of the given
+# list.
+#
+# Arguments:
+# args strings to translate.
+#
+# Results:
+# Returns the length of the longest translated string.
+
+proc msgcat::mcmax {args} {
+ set max 0
+ foreach string $args {
+ set translated [uplevel 1 [list [namespace origin mc] $string]]
+ set len [string length $translated]
+ if {$len>$max} {
+ set max $len
+ }
+ }
+ return $max
+}
+
+# Convert the locale values stored in environment variables to a form
+# suitable for passing to [mclocale]
+proc msgcat::ConvertLocale {value} {
+ # Assume $value is of form: $language[_$territory][.$codeset][@modifier]
+ # Convert to form: $language[_$territory][_$modifier]
+ #
+ # Comment out expanded RE version -- bugs alleged
+ # regexp -expanded {
+ # ^ # Match all the way to the beginning
+ # ([^_.@]*) # Match "lanugage"; ends with _, ., or @
+ # (_([^.@]*))? # Match (optional) "territory"; starts with _
+ # ([.]([^@]*))? # Match (optional) "codeset"; starts with .
+ # (@(.*))? # Match (optional) "modifier"; starts with @
+ # $ # Match all the way to the end
+ # } $value -> language _ territory _ codeset _ modifier
+ if {![regexp {^([^_.@]+)(_([^.@]*))?([.]([^@]*))?(@(.*))?$} $value \
+ -> language _ territory _ codeset _ modifier]} {
+ return -code error "invalid locale '$value': empty language part"
+ }
+ set ret $language
+ if {[string length $territory]} {
+ append ret _$territory
+ }
+ if {[string length $modifier]} {
+ append ret _$modifier
+ }
+ return $ret
+}
+
+# Initialize the default locale
+proc msgcat::Init {} {
+ global env tcl_platform
+
+ #
+ # set default locale, try to get from environment
+ #
+ foreach varName {LC_ALL LC_MESSAGES LANG} {
+ if {[info exists env($varName)] && ("" ne $env($varName))} {
+ if {![catch {
+ mclocale [ConvertLocale $env($varName)]
+ }]} {
+ return
+ }
+ }
+ }
+ #
+ # On Darwin, fallback to current CFLocale identifier if available.
+ #
+ if {[info exists ::tcl::mac::locale] && $::tcl::mac::locale ne ""} {
+ if {![catch {
+ mclocale [ConvertLocale $::tcl::mac::locale]
+ }]} {
+ return
+ }
+ }
+ #
+ # The rest of this routine is special processing for Windows;
+ # all other platforms, get out now.
+ #
+ if {$tcl_platform(platform) ne "windows"} {
+ mclocale C
+ return
+ }
+ #
+ # On Windows, try to set locale depending on registry settings,
+ # or fall back on locale of "C".
+ #
+ if {[catch {
+ package require registry
+ set key {HKEY_CURRENT_USER\Control Panel\International}
+ set locale [registry get $key "locale"]
+ }]} {
+ mclocale C
+ return
+ }
+ #
+ # Keep trying to match against smaller and smaller suffixes
+ # of the registry value, since the latter hexadigits appear
+ # to determine general language and earlier hexadigits determine
+ # more precise information, such as territory. For example,
+ # 0409 - English - United States
+ # 0809 - English - United Kingdom
+ # Add more translations to the WinRegToISO639 array above.
+ #
+ variable WinRegToISO639
+ set locale [string tolower $locale]
+ while {[string length $locale]} {
+ if {![catch {
+ mclocale [ConvertLocale [dict get $WinRegToISO639 $locale]]
+ }]} {
+ return
+ }
+ set locale [string range $locale 1 end]
+ }
+ #
+ # No translation known. Fall back on "C" locale
+ #
+ mclocale C
+}
+msgcat::Init
diff --git a/pkgs/msgcat/pkgIndex.tcl b/pkgs/msgcat/pkgIndex.tcl
new file mode 100644
index 0000000..17ad5db
--- /dev/null
+++ b/pkgs/msgcat/pkgIndex.tcl
@@ -0,0 +1,2 @@
+if {![package vsatisfies [package provide Tcl] 8.5]} {return}
+package ifneeded msgcat 1.4.4 [list source [file join $dir msgcat.tcl]]
diff --git a/pkgs/msgcat/tests/README b/pkgs/msgcat/tests/README
new file mode 100644
index 0000000..ce2382e
--- /dev/null
+++ b/pkgs/msgcat/tests/README
@@ -0,0 +1,107 @@
+README -- Tcl test suite design document.
+
+Contents:
+---------
+
+ 1. Introduction
+ 2. Running tests
+ 3. Adding tests
+ 4. Incompatibilities with prior Tcl versions
+
+1. Introduction:
+----------------
+
+This directory contains a set of validation tests for the Tcl commands
+and C Library procedures for Tcl. Each of the files whose name ends
+in ".test" is intended to fully exercise the functions in the C source
+file that corresponds to the file prefix. The C functions and/or Tcl
+commands tested by a given file are listed in the first line of the
+file.
+
+2. Running tests:
+-----------------
+
+We recommend that you use the "test" target of Tcl's Makefile to run
+the test suite. From the directory in which you build Tcl, simply
+type "make test". This will create a special executable named
+tcltest in which the testing scripts will be evaluated. To create
+the tcltest executable without running the test suite, simple type
+"make tcltest".
+
+All the configuration options of the tcltest package are available
+during a "make test" by defining the TESTFLAGS environment variable.
+For example,if you wish to run only those tests in the file append.test,
+you can type:
+
+ make test TESTFLAGS="-file append.test"
+
+For interactive testing, the Tcl Makefile provides the "runtest" target.
+Type "make runtest" in your build directory, and the tcltest executable
+will be created, if necessary, then it will run interactively. At the
+command prompt, you may type any Tcl commands. If you type
+"source ../tests/all.tcl", the test suite will run. You may use the
+tcltest::configure command to configure the test suite run as an
+alternative to command line options via TESTFLAGS. You might also
+wish to use the tcltest::testConstraint command to select the constraints
+that govern which tests are run. See the documentation for the tcltest
+package for details.
+
+3. Adding tests:
+----------------
+
+Please see the tcltest man page for more information regarding how to
+write and run tests.
+
+Please note that the all.tcl file will source your new test file if
+the filename matches the tests/*.test pattern (as it should). The
+names of test files that contain regression (or glass-box) tests
+should correspond to the Tcl or C code file that they are testing.
+For example, the test file for the C file "tclCmdAH.c" is
+"cmdAH.test". Test files that contain black-box tests may not
+correspond to any Tcl or C code file so they should match the pattern
+"*_bb.test".
+
+Be sure your new test file can be run from any working directory.
+
+Be sure no temporary files are left behind by your test file.
+Use [tcltest::makeFile], [tcltest::removeFile], and [tcltest::cleanupTests]
+properly to be sure of this.
+
+Be sure your tests can run cross-platform in both a build environment
+as well as an installation environment. If your test file contains
+tests that should not be run in one or more of those cases, please use
+the constraints mechanism to skip those tests.
+
+4. Incompatibilities of package tcltest 2.1 with
+ testing machinery of very old versions of Tcl:
+------------------------------------------------
+
+1) Global variables such as VERBOSE, TESTS, and testConfig of the
+ old machinery correspond to the [configure -verbose],
+ [configure -match], and [testConstraint] commands of tcltest 2.1,
+ respectively.
+
+2) VERBOSE values were longer numeric. [configure -verbose] values
+ are lists of keywords.
+
+3) When you run "make test", the working dir for the test suite is now
+ the one from which you called "make test", rather than the "tests"
+ directory. This change allows for both unix and windows test
+ suites to be run simultaneously without interference with each
+ other or with existing files. All tests must now run independently
+ of their working directory.
+
+4) The "all" file is now called "all.tcl"
+
+5) The "defs" and "defs.tcl" files no longer exist.
+
+6) Instead of creating a doAllTests file in the tests directory, to
+ run all nonPortable tests, just use the "-constraints nonPortable"
+ command line flag. If you are running interactively, you can run
+ [tcltest::testConstraint nonPortable 1] (after loading the tcltest
+ package).
+
+7) Direct evaluation of the *.test files by the "source" command is no
+ longer recommended. Instead, "source all.tcl" and use the "-file" and
+ "-notfile" options of tcltest::configure to control which *.test files
+ are evaluated.
diff --git a/pkgs/msgcat/tests/all.tcl b/pkgs/msgcat/tests/all.tcl
new file mode 100644
index 0000000..05d3024
--- /dev/null
+++ b/pkgs/msgcat/tests/all.tcl
@@ -0,0 +1,19 @@
+# all.tcl --
+#
+# This file contains a top-level script to run all of the Tcl
+# tests. Execute it by invoking "source all.test" when running tcltest
+# in this directory.
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2000 by Ajuba Solutions
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package prefer latest
+package require Tcl 8.5
+package require tcltest 2.2
+namespace import tcltest::*
+configure {*}$argv -testdir [file dir [info script]]
+runAllTests
+proc exit args {}
diff --git a/pkgs/msgcat/tests/append.test b/pkgs/msgcat/tests/append.test
new file mode 100644
index 0000000..69c6381
--- /dev/null
+++ b/pkgs/msgcat/tests/append.test
@@ -0,0 +1,306 @@
+# Commands covered: append lappend
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+unset -nocomplain x
+
+test append-1.1 {append command} {
+ unset -nocomplain x
+ list [append x 1 2 abc "long string"] $x
+} {{12abclong string} {12abclong string}}
+test append-1.2 {append command} {
+ set x ""
+ list [append x first] [append x second] [append x third] $x
+} {first firstsecond firstsecondthird firstsecondthird}
+test append-1.3 {append command} {
+ set x "abcd"
+ append x
+} abcd
+
+test append-2.1 {long appends} {
+ set x ""
+ for {set i 0} {$i < 1000} {set i [expr $i+1]} {
+ append x "foobar "
+ }
+ set y "foobar"
+ set y "$y $y $y $y $y $y $y $y $y $y"
+ set y "$y $y $y $y $y $y $y $y $y $y"
+ set y "$y $y $y $y $y $y $y $y $y $y "
+ expr {$x == $y}
+} 1
+
+test append-3.1 {append errors} -returnCodes error -body {
+ append
+} -result {wrong # args: should be "append varName ?value ...?"}
+test append-3.2 {append errors} -returnCodes error -body {
+ set x ""
+ append x(0) 44
+} -result {can't set "x(0)": variable isn't array}
+test append-3.3 {append errors} -returnCodes error -body {
+ unset -nocomplain x
+ append x
+} -result {can't read "x": no such variable}
+
+test append-4.1 {lappend command} {
+ unset -nocomplain x
+ list [lappend x 1 2 abc "long string"] $x
+} {{1 2 abc {long string}} {1 2 abc {long string}}}
+test append-4.2 {lappend command} {
+ set x ""
+ list [lappend x first] [lappend x second] [lappend x third] $x
+} {first {first second} {first second third} {first second third}}
+test append-4.3 {lappend command} -body {
+ proc foo {} {
+ global x
+ set x old
+ unset x
+ lappend x new
+ }
+ foo
+} -cleanup {
+ rename foo {}
+} -result {new}
+test append-4.4 {lappend command} {
+ set x {}
+ lappend x \{\ abc
+} {\{\ abc}
+test append-4.5 {lappend command} {
+ set x {}
+ lappend x \{ abc
+} {\{ abc}
+test append-4.6 {lappend command} {
+ set x {1 2 3}
+ lappend x
+} {1 2 3}
+test append-4.7 {lappend command} {
+ set x "a\{"
+ lappend x abc
+} "a\\\{ abc"
+test append-4.8 {lappend command} {
+ set x "\\\{"
+ lappend x abc
+} "\\{ abc"
+test append-4.9 {lappend command} -returnCodes error -body {
+ set x " \{"
+ lappend x abc
+} -result {unmatched open brace in list}
+test append-4.10 {lappend command} -returnCodes error -body {
+ set x " \{"
+ lappend x abc
+} -result {unmatched open brace in list}
+test append-4.11 {lappend command} -returnCodes error -body {
+ set x "\{\{\{"
+ lappend x abc
+} -result {unmatched open brace in list}
+test append-4.12 {lappend command} -returnCodes error -body {
+ set x "x \{\{\{"
+ lappend x abc
+} -result {unmatched open brace in list}
+test append-4.13 {lappend command} {
+ set x "x\{\{\{"
+ lappend x abc
+} "x\\\{\\\{\\\{ abc"
+test append-4.14 {lappend command} {
+ set x " "
+ lappend x abc
+} "abc"
+test append-4.15 {lappend command} {
+ set x "\\ "
+ lappend x abc
+} "{ } abc"
+test append-4.16 {lappend command} {
+ set x "x "
+ lappend x abc
+} "x abc"
+test append-4.17 {lappend command} {
+ unset -nocomplain x
+ lappend x
+} {}
+test append-4.18 {lappend command} {
+ unset -nocomplain x
+ lappend x {}
+} {{}}
+test append-4.19 {lappend command} {
+ unset -nocomplain x
+ lappend x(0)
+} {}
+test append-4.20 {lappend command} {
+ unset -nocomplain x
+ lappend x(0) abc
+} {abc}
+unset -nocomplain x
+test append-4.21 {lappend command} -returnCodes error -body {
+ set x \"
+ lappend x
+} -result {unmatched open quote in list}
+test append-4.22 {lappend command} -returnCodes error -body {
+ set x \"
+ lappend x abc
+} -result {unmatched open quote in list}
+
+test append-5.1 {long lappends} -setup {
+ unset -nocomplain x
+ proc check {var size} {
+ set l [llength $var]
+ if {$l != $size} {
+ return "length mismatch: should have been $size, was $l"
+ }
+ for {set i 0} {$i < $size} {set i [expr $i+1]} {
+ set j [lindex $var $i]
+ if {$j ne "item $i"} {
+ return "element $i should have been \"item $i\", was \"$j\""
+ }
+ }
+ return ok
+ }
+} -body {
+ set x ""
+ for {set i 0} {$i < 300} {incr i} {
+ lappend x "item $i"
+ }
+ check $x 300
+} -cleanup {
+ rename check {}
+} -result ok
+
+test append-6.1 {lappend errors} -returnCodes error -body {
+ lappend
+} -result {wrong # args: should be "lappend varName ?value ...?"}
+test append-6.2 {lappend errors} -returnCodes error -body {
+ set x ""
+ lappend x(0) 44
+} -result {can't set "x(0)": variable isn't array}
+
+test append-7.1 {lappend-created var and error in trace on that var} -setup {
+ catch {rename foo ""}
+ unset -nocomplain x
+} -body {
+ trace variable x w foo
+ proc foo {} {global x; unset x}
+ catch {lappend x 1}
+ proc foo {args} {global x; unset x}
+ info exists x
+ set x
+ lappend x 1
+ list [info exists x] [catch {set x} msg] $msg
+} -result {0 1 {can't read "x": no such variable}}
+test append-7.2 {lappend var triggers read trace} -setup {
+ unset -nocomplain myvar
+ unset -nocomplain ::result
+} -body {
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend myvar a
+ return $::result
+} -result {myvar {} r}
+test append-7.3 {lappend var triggers read trace, array var} -setup {
+ unset -nocomplain myvar
+ unset -nocomplain ::result
+} -body {
+ # The behavior of read triggers on lappend changed in 8.0 to not trigger
+ # them, and was changed back in 8.4.
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend myvar(b) a
+ return $::result
+} -result {myvar b r}
+test append-7.4 {lappend var triggers read trace, array var exists} -setup {
+ unset -nocomplain myvar
+ unset -nocomplain ::result
+} -body {
+ set myvar(0) 1
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend myvar(b) a
+ return $::result
+} -result {myvar b r}
+test append-7.5 {append var does not trigger read trace} -setup {
+ unset -nocomplain myvar
+ unset -nocomplain ::result
+} -body {
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ append myvar a
+ info exists ::result
+} -result {0}
+
+# THERE ARE NO append-8.* TESTS
+
+# New tests for bug 3057639 to show off the more consistent behaviour of
+# lappend in both direct-eval and bytecompiled code paths (see appendComp.test
+# for the compiled variants). lappend now behaves like append. 9.0/1 lappend -
+# 9.2/3 append
+
+test append-9.0 {bug 3057639, lappend direct eval, read trace on non-existing array variable element} -setup {
+ unset -nocomplain myvar
+} -body {
+ array set myvar {}
+ proc nonull {var key val} {
+ upvar 1 $var lvar
+ if {![info exists lvar($key)]} {
+ return -code error "no such variable"
+ }
+ }
+ trace add variable myvar read nonull
+ list [catch {
+ lappend myvar(key) "new value"
+ } msg] $msg
+} -result {0 {{new value}}}
+test append-9.1 {bug 3057639, lappend direct eval, read trace on non-existing env element} -setup {
+ unset -nocomplain ::env(__DUMMY__)
+} -body {
+ list [catch {
+ lappend ::env(__DUMMY__) "new value"
+ } msg] $msg
+} -cleanup {
+ unset -nocomplain ::env(__DUMMY__)
+} -result {0 {{new value}}}
+test append-9.2 {bug 3057639, append direct eval, read trace on non-existing array variable element} -setup {
+ unset -nocomplain myvar
+} -body {
+ array set myvar {}
+ proc nonull {var key val} {
+ upvar 1 $var lvar
+ if {![info exists lvar($key)]} {
+ return -code error "no such variable"
+ }
+ }
+ trace add variable myvar read nonull
+ list [catch {
+ append myvar(key) "new value"
+ } msg] $msg
+} -result {0 {new value}}
+test append-9.3 {bug 3057639, append direct eval, read trace on non-existing env element} -setup {
+ unset -nocomplain ::env(__DUMMY__)
+} -body {
+ list [catch {
+ append ::env(__DUMMY__) "new value"
+ } msg] $msg
+} -cleanup {
+ unset -nocomplain ::env(__DUMMY__)
+} -result {0 {new value}}
+
+unset -nocomplain i x result y
+catch {rename foo ""}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/appendComp.test b/pkgs/msgcat/tests/appendComp.test
new file mode 100644
index 0000000..f85c3ba
--- /dev/null
+++ b/pkgs/msgcat/tests/appendComp.test
@@ -0,0 +1,455 @@
+# Commands covered: append lappend
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+catch {unset x}
+
+test appendComp-1.1 {append command} -setup {
+ unset -nocomplain x
+} -body {
+ proc foo {} {append ::x 1 2 abc "long string"}
+ list [foo] $x
+} -result {{12abclong string} {12abclong string}}
+test appendComp-1.2 {append command} {
+ proc foo {} {
+ set x ""
+ list [append x first] [append x second] [append x third] $x
+ }
+ foo
+} {first firstsecond firstsecondthird firstsecondthird}
+test appendComp-1.3 {append command} {
+ proc foo {} {
+ set x "abcd"
+ append x
+ }
+ foo
+} abcd
+
+test appendComp-2.1 {long appends} {
+ proc foo {} {
+ set x ""
+ for {set i 0} {$i < 1000} {set i [expr $i+1]} {
+ append x "foobar "
+ }
+ set y "foobar"
+ set y "$y $y $y $y $y $y $y $y $y $y"
+ set y "$y $y $y $y $y $y $y $y $y $y"
+ set y "$y $y $y $y $y $y $y $y $y $y "
+ expr {$x == $y}
+ }
+ foo
+} 1
+
+test appendComp-3.1 {append errors} -returnCodes error -body {
+ proc foo {} {append}
+ foo
+} -result {wrong # args: should be "append varName ?value ...?"}
+test appendComp-3.2 {append errors} -returnCodes error -body {
+ proc foo {} {
+ set x ""
+ append x(0) 44
+ }
+ foo
+} -result {can't set "x(0)": variable isn't array}
+test appendComp-3.3 {append errors} -returnCodes error -body {
+ proc foo {} {
+ unset -nocomplain x
+ append x
+ }
+ foo
+} -result {can't read "x": no such variable}
+
+test appendComp-4.1 {lappend command} {
+ proc foo {} {
+ global x
+ unset -nocomplain x
+ lappend x 1 2 abc "long string"
+ }
+ list [foo] $x
+} {{1 2 abc {long string}} {1 2 abc {long string}}}
+test appendComp-4.2 {lappend command} {
+ proc foo {} {
+ set x ""
+ list [lappend x first] [lappend x second] [lappend x third] $x
+ }
+ foo
+} {first {first second} {first second third} {first second third}}
+test appendComp-4.3 {lappend command} {
+ proc foo {} {
+ global x
+ set x old
+ unset x
+ lappend x new
+ }
+ set result [foo]
+ rename foo {}
+ set result
+} {new}
+test appendComp-4.4 {lappend command} {
+ proc foo {} {
+ set x {}
+ lappend x \{\ abc
+ }
+ foo
+} {\{\ abc}
+test appendComp-4.5 {lappend command} {
+ proc foo {} {
+ set x {}
+ lappend x \{ abc
+ }
+ foo
+} {\{ abc}
+test appendComp-4.6 {lappend command} {
+ proc foo {} {
+ set x {1 2 3}
+ lappend x
+ }
+ foo
+} {1 2 3}
+test appendComp-4.7 {lappend command} {
+ proc foo {} {
+ set x "a\{"
+ lappend x abc
+ }
+ foo
+} "a\\\{ abc"
+test appendComp-4.8 {lappend command} {
+ proc foo {} {
+ set x "\\\{"
+ lappend x abc
+ }
+ foo
+} "\\{ abc"
+test appendComp-4.9 {lappend command} -returnCodes error -body {
+ proc foo {} {
+ set x " \{"
+ lappend x abc
+ }
+ foo
+} -result {unmatched open brace in list}
+test appendComp-4.10 {lappend command} -returnCodes error -body {
+ proc foo {} {
+ set x " \{"
+ lappend x abc
+ }
+ foo
+} -result {unmatched open brace in list}
+test appendComp-4.11 {lappend command} -returnCodes error -body {
+ proc foo {} {
+ set x "\{\{\{"
+ lappend x abc
+ }
+ foo
+} -result {unmatched open brace in list}
+test appendComp-4.12 {lappend command} -returnCodes error -body {
+ proc foo {} {
+ set x "x \{\{\{"
+ lappend x abc
+ }
+ foo
+} -result {unmatched open brace in list}
+test appendComp-4.13 {lappend command} {
+ proc foo {} {
+ set x "x\{\{\{"
+ lappend x abc
+ }
+ foo
+} "x\\\{\\\{\\\{ abc"
+test appendComp-4.14 {lappend command} {
+ proc foo {} {
+ set x " "
+ lappend x abc
+ }
+ foo
+} "abc"
+test appendComp-4.15 {lappend command} {
+ proc foo {} {
+ set x "\\ "
+ lappend x abc
+ }
+ foo
+} "{ } abc"
+test appendComp-4.16 {lappend command} {
+ proc foo {} {
+ set x "x "
+ lappend x abc
+ }
+ foo
+} "x abc"
+test appendComp-4.17 {lappend command} {
+ proc foo {} { lappend x }
+ foo
+} {}
+test appendComp-4.18 {lappend command} {
+ proc foo {} { lappend x {} }
+ foo
+} {{}}
+test appendComp-4.19 {lappend command} {
+ proc foo {} { lappend x(0) }
+ foo
+} {}
+test appendComp-4.20 {lappend command} {
+ proc foo {} { lappend x(0) abc }
+ foo
+} {abc}
+
+test appendComp-5.1 {long lappends} -setup {
+ unset -nocomplain x
+ proc check {var size} {
+ set l [llength $var]
+ if {$l != $size} {
+ return "length mismatch: should have been $size, was $l"
+ }
+ for {set i 0} {$i < $size} {incr i} {
+ set j [lindex $var $i]
+ if {$j ne "item $i"} {
+ return "element $i should have been \"item $i\", was \"$j\""
+ }
+ }
+ return ok
+ }
+} -body {
+ set x ""
+ for {set i 0} {$i < 300} {set i [expr $i+1]} {
+ lappend x "item $i"
+ }
+ check $x 300
+} -cleanup {
+ unset -nocomplain x
+ catch {rename check ""}
+} -result ok
+
+test appendComp-6.1 {lappend errors} -returnCodes error -body {
+ proc foo {} {lappend}
+ foo
+} -result {wrong # args: should be "lappend varName ?value ...?"}
+test appendComp-6.2 {lappend errors} -returnCodes error -body {
+ proc foo {} {
+ set x ""
+ lappend x(0) 44
+ }
+ foo
+} -result {can't set "x(0)": variable isn't array}
+
+test appendComp-7.1 {lappendComp-created var and error in trace on that var} -setup {
+ catch {rename foo ""}
+ unset -nocomplain x
+} -body {
+ proc bar {} {
+ global x
+ trace variable x w foo
+ proc foo {} {global x; unset x}
+ catch {lappend x 1}
+ proc foo {args} {global x; unset x}
+ info exists x
+ set x
+ lappend x 1
+ list [info exists x] [catch {set x} msg] $msg
+ }
+ bar
+} -result {0 1 {can't read "x": no such variable}}
+test appendComp-7.2 {lappend var triggers read trace, index var} -setup {
+ unset -nocomplain ::result
+} -body {
+ proc bar {} {
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend myvar a
+ return $::result
+ }
+ bar
+} -result {myvar {} r} -constraints {bug-3057639}
+test appendComp-7.3 {lappend var triggers read trace, stack var} -setup {
+ unset -nocomplain ::result
+ unset -nocomplain ::myvar
+} -body {
+ proc bar {} {
+ trace variable ::myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend ::myvar a
+ return $::result
+ }
+ bar
+} -result {::myvar {} r} -constraints {bug-3057639}
+test appendComp-7.4 {lappend var triggers read trace, array var} -setup {
+ unset -nocomplain ::result
+} -body {
+ # The behavior of read triggers on lappend changed in 8.0 to not trigger
+ # them. Maybe not correct, but been there a while.
+ proc bar {} {
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend myvar(b) a
+ return $::result
+ }
+ bar
+} -result {myvar b r} -constraints {bug-3057639}
+test appendComp-7.5 {lappend var triggers read trace, array var} -setup {
+ unset -nocomplain ::result
+} -body {
+ # The behavior of read triggers on lappend changed in 8.0 to not trigger
+ # them. Maybe not correct, but been there a while.
+ proc bar {} {
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend myvar(b) a b
+ return $::result
+ }
+ bar
+} -result {myvar b r}
+test appendComp-7.6 {lappend var triggers read trace, array var exists} -setup {
+ unset -nocomplain ::result
+} -body {
+ proc bar {} {
+ set myvar(0) 1
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend myvar(b) a
+ return $::result
+ }
+ bar
+} -result {myvar b r} -constraints {bug-3057639}
+test appendComp-7.7 {lappend var triggers read trace, array stack var} -setup {
+ unset -nocomplain ::myvar
+ unset -nocomplain ::result
+} -body {
+ proc bar {} {
+ trace variable ::myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend ::myvar(b) a
+ return $::result
+ }
+ bar
+} -result {::myvar b r} -constraints {bug-3057639}
+test appendComp-7.8 {lappend var triggers read trace, array stack var} -setup {
+ unset -nocomplain ::myvar
+ unset -nocomplain ::result
+} -body {
+ proc bar {} {
+ trace variable ::myvar r foo
+ proc foo {args} {append ::result $args}
+ lappend ::myvar(b) a b
+ return $::result
+ }
+ bar
+} -result {::myvar b r}
+test appendComp-7.9 {append var does not trigger read trace} -setup {
+ unset -nocomplain ::result
+} -body {
+ proc bar {} {
+ trace variable myvar r foo
+ proc foo {args} {append ::result $args}
+ append myvar a
+ info exists ::result
+ }
+ bar
+} -result {0}
+
+test appendComp-8.1 {defer error to runtime} -setup {
+ interp create slave
+} -body {
+ slave eval {
+ proc foo {} {
+ proc append args {}
+ append
+ }
+ foo
+ }
+} -cleanup {
+ interp delete slave
+} -result {}
+
+# New tests for bug 3057639 to show off the more consistent behaviour of
+# lappend in both direct-eval and bytecompiled code paths (see append.test for
+# the direct-eval variants). lappend now behaves like append. 9.0/1 lappend -
+# 9.2/3 append.
+
+# Note also the tests above now constrained by bug-3057639, these changed
+# behaviour with the triggering of read traces in bc mode gone.
+
+# Going back to the tests below. The direct-eval tests are ok before and after
+# patch (no read traces run for lappend, append). The compiled tests are
+# failing for lappend (9.0/1) before the patch, showing how it invokes read
+# traces in the compiled path. The append tests are good (9.2/3). After the
+# patch the failues are gone.
+
+test appendComp-9.0 {bug 3057639, lappend compiled, read trace on non-existing array variable element} -setup {
+ unset -nocomplain myvar
+ array set myvar {}
+} -body {
+ proc nonull {var key val} {
+ upvar 1 $var lvar
+ if {![info exists lvar($key)]} {
+ return -code error "BOOM. no such variable"
+ }
+ }
+ trace add variable myvar read nonull
+ proc foo {} {
+ lappend ::myvar(key) "new value"
+ }
+ list [catch { foo } msg] $msg
+} -result {0 {{new value}}}
+test appendComp-9.1 {bug 3057639, lappend direct eval, read trace on non-existing env element} -setup {
+ unset -nocomplain ::env(__DUMMY__)
+} -body {
+ proc foo {} {
+ lappend ::env(__DUMMY__) "new value"
+ }
+ list [catch { foo } msg] $msg
+} -cleanup {
+ unset -nocomplain ::env(__DUMMY__)
+} -result {0 {{new value}}}
+test appendComp-9.2 {bug 3057639, append compiled, read trace on non-existing array variable element} -setup {
+ unset -nocomplain myvar
+ array set myvar {}
+} -body {
+ proc nonull {var key val} {
+ upvar 1 $var lvar
+ if {![info exists lvar($key)]} {
+ return -code error "BOOM. no such variable"
+ }
+ }
+ trace add variable myvar read nonull
+ proc foo {} {
+ append ::myvar(key) "new value"
+ }
+ list [catch { foo } msg] $msg
+} -result {0 {new value}}
+test appendComp-9.3 {bug 3057639, append direct eval, read trace on non-existing env element} -setup {
+ unset -nocomplain ::env(__DUMMY__)
+} -body {
+ proc foo {} {
+ append ::env(__DUMMY__) "new value"
+ }
+ list [catch { foo } msg] $msg
+} -cleanup {
+ unset -nocomplain ::env(__DUMMY__)
+} -result {0 {new value}}
+
+catch {unset i x result y}
+catch {rename foo ""}
+catch {rename bar ""}
+catch {rename check ""}
+catch {rename bar {}}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/apply.test b/pkgs/msgcat/tests/apply.test
new file mode 100644
index 0000000..ba19b81
--- /dev/null
+++ b/pkgs/msgcat/tests/apply.test
@@ -0,0 +1,321 @@
+# Commands covered: apply
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2005-2006 Miguel Sofer
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2.2
+ namespace import -force ::tcltest::*
+}
+
+if {[info commands ::apply] eq {}} {
+ return
+}
+
+testConstraint memory [llength [info commands memory]]
+
+# Tests for wrong number of arguments
+
+test apply-1.1 {too few arguments} -returnCodes error -body {
+ apply
+} -result {wrong # args: should be "apply lambdaExpr ?arg ...?"}
+
+# Tests for malformed lambda
+
+test apply-2.0 {malformed lambda} -returnCodes error -body {
+ set lambda a
+ apply $lambda
+} -result {can't interpret "a" as a lambda expression}
+test apply-2.1 {malformed lambda} -returnCodes error -body {
+ set lambda [list a b c d]
+ apply $lambda
+} -result {can't interpret "a b c d" as a lambda expression}
+test apply-2.2 {malformed lambda} {
+ set lambda [list {{}} boo]
+ list [catch {apply $lambda} msg] $msg $::errorInfo
+} {1 {argument with no name} {argument with no name
+ (parsing lambda expression "{{}} boo")
+ invoked from within
+"apply $lambda"}}
+test apply-2.3 {malformed lambda} {
+ set lambda [list {{a b c}} boo]
+ list [catch {apply $lambda} msg] $msg $::errorInfo
+} {1 {too many fields in argument specifier "a b c"} {too many fields in argument specifier "a b c"
+ (parsing lambda expression "{{a b c}} boo")
+ invoked from within
+"apply $lambda"}}
+test apply-2.4 {malformed lambda} {
+ set lambda [list a(1) boo]
+ list [catch {apply $lambda} msg] $msg $::errorInfo
+} {1 {formal parameter "a(1)" is an array element} {formal parameter "a(1)" is an array element
+ (parsing lambda expression "a(1) boo")
+ invoked from within
+"apply $lambda"}}
+test apply-2.5 {malformed lambda} {
+ set lambda [list a::b boo]
+ list [catch {apply $lambda} msg] $msg $::errorInfo
+} {1 {formal parameter "a::b" is not a simple name} {formal parameter "a::b" is not a simple name
+ (parsing lambda expression "a::b boo")
+ invoked from within
+"apply $lambda"}}
+
+# Tests for runtime errors in the lambda expression
+
+test apply-3.1 {non-existing namespace} -body {
+ apply [list x {set x 1} ::NONEXIST::FOR::SURE] x
+} -returnCodes error -result {namespace "::NONEXIST::FOR::SURE" not found}
+test apply-3.2 {non-existing namespace} -body {
+ namespace eval ::NONEXIST::FOR::SURE {}
+ set lambda [list x {set x 1} ::NONEXIST::FOR::SURE]
+ apply $lambda x
+ namespace delete ::NONEXIST
+ apply $lambda x
+} -returnCodes error -result {namespace "::NONEXIST::FOR::SURE" not found}
+test apply-3.3 {non-existing namespace} -body {
+ apply [list x {set x 1} NONEXIST::FOR::SURE] x
+} -returnCodes error -result {namespace "::NONEXIST::FOR::SURE" not found}
+test apply-3.4 {non-existing namespace} -body {
+ namespace eval ::NONEXIST::FOR::SURE {}
+ set lambda [list x {set x 1} NONEXIST::FOR::SURE]
+ apply $lambda x
+ namespace delete ::NONEXIST
+ apply $lambda x
+} -returnCodes error -result {namespace "::NONEXIST::FOR::SURE" not found}
+
+test apply-4.1 {error in arguments to lambda expression} -body {
+ set lambda [list x {set x 1}]
+ apply $lambda
+} -returnCodes error -result {wrong # args: should be "apply lambdaExpr x"}
+test apply-4.2 {error in arguments to lambda expression} -body {
+ set lambda [list x {set x 1}]
+ apply $lambda a b
+} -returnCodes error -result {wrong # args: should be "apply lambdaExpr x"}
+test apply-4.3 {error in arguments to lambda expression} -body {
+ interp alias {} foo {} ::apply [list x {set x 1}]
+ foo a b
+} -cleanup {
+ rename foo {}
+} -returnCodes error -result {wrong # args: should be "foo x"}
+test apply-4.4 {error in arguments to lambda expression} -body {
+ interp alias {} foo {} ::apply [list x {set x 1}] a
+ foo b
+} -cleanup {
+ rename foo {}
+} -returnCodes error -result {wrong # args: should be "foo"}
+test apply-4.5 {error in arguments to lambda expression} -body {
+ set lambda [list x {set x 1}]
+ namespace eval a {
+ namespace ensemble create -command ::bar -map {id {::a::const foo}}
+ proc const val { return $val }
+ proc alias {object slot = command args} {
+ set map [namespace ensemble configure $object -map]
+ dict set map $slot [linsert $args 0 $command]
+ namespace ensemble configure $object -map $map
+ }
+ proc method {object name params body} {
+ set params [linsert $params 0 self]
+ alias $object $name = ::apply [list $params $body] $object
+ }
+ method ::bar boo x {return "[expr {$x*$x}] - $self"}
+ }
+ bar boo
+} -cleanup {
+ namespace delete ::a
+} -returnCodes error -result {wrong # args: should be "bar boo x"}
+
+test apply-5.1 {runtime error in lambda expression} {
+ set lambda [list {} {error foo}]
+ set res [catch {apply $lambda}]
+ list $res $::errorInfo
+} {1 {foo
+ while executing
+"error foo"
+ (lambda term "{} {error foo}" line 1)
+ invoked from within
+"apply $lambda"}}
+
+# Tests for correct execution; as the implementation is the same as that for
+# procs, the general functionality is mostly tested elsewhere
+
+test apply-6.1 {info level} {
+ set lev [info level]
+ set lambda [list {} {info level}]
+ expr {[apply $lambda] - $lev}
+} 1
+test apply-6.2 {info level} {
+ set lambda [list {} {info level 0}]
+ apply $lambda
+} {apply {{} {info level 0}}}
+test apply-6.3 {info level} {
+ set lambda [list args {info level 0}]
+ apply $lambda x y
+} {apply {args {info level 0}} x y}
+
+# Tests for correct namespace scope
+
+namespace eval ::testApply {
+ proc testApply args {return testApply}
+}
+
+test apply-7.1 {namespace access} {
+ set ::testApply::x 0
+ set body {set x 1; set x}
+ list [apply [list args $body ::testApply]] $::testApply::x
+} {1 0}
+test apply-7.2 {namespace access} {
+ set ::testApply::x 0
+ set body {variable x; set x}
+ list [apply [list args $body ::testApply]] $::testApply::x
+} {0 0}
+test apply-7.3 {namespace access} {
+ set ::testApply::x 0
+ set body {variable x; set x 1}
+ list [apply [list args $body ::testApply]] $::testApply::x
+} {1 1}
+test apply-7.4 {namespace access} {
+ set ::testApply::x 0
+ set body {testApply}
+ apply [list args $body ::testApply]
+} testApply
+test apply-7.5 {namespace access} {
+ set ::testApply::x 0
+ set body {set x 1; set x}
+ list [apply [list args $body testApply]] $::testApply::x
+} {1 0}
+test apply-7.6 {namespace access} {
+ set ::testApply::x 0
+ set body {variable x; set x}
+ list [apply [list args $body testApply]] $::testApply::x
+} {0 0}
+test apply-7.7 {namespace access} {
+ set ::testApply::x 0
+ set body {variable x; set x 1}
+ list [apply [list args $body testApply]] $::testApply::x
+} {1 1}
+test apply-7.8 {namespace access} {
+ set ::testApply::x 0
+ set body {testApply}
+ apply [list args $body testApply]
+} testApply
+
+# Tests for correct argument treatment
+
+set applyBody {
+ set res {}
+ foreach v [info locals] {
+ if {$v eq "res"} continue
+ lappend res [list $v [set $v]]
+ }
+ set res
+}
+
+test apply-8.1 {args treatment} {
+ apply [list args $applyBody] 1 2 3
+} {{args {1 2 3}}}
+test apply-8.2 {args treatment} {
+ apply [list {x args} $applyBody] 1 2
+} {{x 1} {args 2}}
+test apply-8.3 {args treatment} {
+ apply [list {x args} $applyBody] 1 2 3
+} {{x 1} {args {2 3}}}
+test apply-8.4 {default values} {
+ apply [list {{x 1} {y 2}} $applyBody]
+} {{x 1} {y 2}}
+test apply-8.5 {default values} {
+ apply [list {{x 1} {y 2}} $applyBody] 3 4
+} {{x 3} {y 4}}
+test apply-8.6 {default values} {
+ apply [list {{x 1} {y 2}} $applyBody] 3
+} {{x 3} {y 2}}
+test apply-8.7 {default values} {
+ apply [list {x {y 2}} $applyBody] 1
+} {{x 1} {y 2}}
+test apply-8.8 {default values} {
+ apply [list {x {y 2}} $applyBody] 1 3
+} {{x 1} {y 3}}
+test apply-8.9 {default values} {
+ apply [list {x {y 2} args} $applyBody] 1
+} {{x 1} {y 2} {args {}}}
+test apply-8.10 {default values} {
+ apply [list {x {y 2} args} $applyBody] 1 3
+} {{x 1} {y 3} {args {}}}
+
+# Tests for leaks
+
+test apply-9.1 {leaking internal rep} -setup {
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex $lines 3 3
+ }
+ set lam [list {} {set a 1}]
+} -constraints memory -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ ::apply [lrange $lam 0 end]
+ set tmp $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+ rename getbytes {}
+ unset -nocomplain lam end i tmp leakedBytes
+} -result 0
+test apply-9.2 {leaking internal rep} -setup {
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex $lines 3 3
+ }
+} -constraints memory -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ ::apply [list {} {set a 1}]
+ set tmp $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+ rename getbytes {}
+ unset -nocomplain end i tmp leakedBytes
+} -result 0
+test apply-9.3 {leaking internal rep} -setup {
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex $lines 3 3
+ }
+} -constraints memory -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ set x [list {} {set a 1} ::NS::THAT::DOES::NOT::EXIST]
+ catch {::apply $x}
+ set x {}
+ set tmp $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+ rename getbytes {}
+ unset -nocomplain end i x tmp leakedBytes
+} -result 0
+
+# Tests for the avoidance of recompilation
+
+# cleanup
+
+namespace delete testApply
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/assemble.test b/pkgs/msgcat/tests/assemble.test
new file mode 100644
index 0000000..7d4e5d1
--- /dev/null
+++ b/pkgs/msgcat/tests/assemble.test
@@ -0,0 +1,3293 @@
+# assemble.test --
+#
+# Test suite for the 'tcl::unsupported::assemble' command
+#
+# Copyright (c) 2010 by Ozgur Dogan Ugurlu.
+# Copyright (c) 2010 by Kevin B. Kenny.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#-----------------------------------------------------------------------------
+
+# Commands covered: assemble
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2.2
+ namespace import -force ::tcltest::*
+}
+namespace eval tcl::unsupported {namespace export assemble}
+namespace import tcl::unsupported::assemble
+
+# Procedure to make code that fills the literal and local variable tables, to
+# force instructions to spill to four bytes.
+
+proc fillTables {} {
+ set s {}
+ set sep {}
+ for {set i 0} {$i < 256} {incr i} {
+ append s $sep [list set v$i literal$i]
+ set sep \n
+ }
+ return $s
+}
+
+testConstraint memory [llength [info commands memory]]
+if {[testConstraint memory]} {
+ proc getbytes {} {
+ set lines [split [memory info] \n]
+ return [lindex $lines 3 3]
+ }
+ proc leaktest {script {iterations 3}} {
+ set end [getbytes]
+ for {set i 0} {$i < $iterations} {incr i} {
+ uplevel 1 $script
+ set tmp $end
+ set end [getbytes]
+ }
+ return [expr {$end - $tmp}]
+ }
+}
+
+# assemble-1 - TclNRAssembleObjCmd
+
+test assemble-1.1 {wrong # args, direct eval} {
+ -body {
+ eval [list assemble]
+ }
+ -returnCodes error
+ -result {wrong # args*}
+ -match glob
+}
+test assemble-1.2 {wrong # args, direct eval} {
+ -body {
+ eval [list assemble too many]
+ }
+ -returnCodes error
+ -result {wrong # args*}
+ -match glob
+}
+test assemble-1.3 {error reporting, direct eval} {
+ -body {
+ list [catch {
+ eval [list assemble {
+ # bad opcode
+ rubbish
+ }]
+ } result] $result $errorInfo
+ }
+ -match glob
+ -result {1 {bad instruction "rubbish":*} {bad instruction "rubbish":*
+ while executing
+"rubbish"
+ ("assemble" body, line 3)*}}
+ -cleanup {unset result}
+}
+test assemble-1.4 {simple direct eval} {
+ -body {
+ eval [list assemble {push {this is a test}}]
+ }
+ -result {this is a test}
+}
+
+# assemble-2 - CompileAssembleObj
+
+test assemble-2.1 {bytecode reuse, direct eval} {
+ -body {
+ set x {push "this is a test"}
+ list [eval [list assemble $x]] \
+ [eval [list assemble $x]]
+ }
+ -result {{this is a test} {this is a test}}
+}
+test assemble-2.2 {bytecode discard, direct eval} {
+ -body {
+ set x {load value}
+ proc p1 {x} {
+ set value value1
+ assemble $x
+ }
+ proc p2 {x} {
+ set a b
+ set value value2
+ assemble $x
+ }
+ list [p1 $x] [p2 $x]
+ }
+ -result {value1 value2}
+ -cleanup {
+ unset x
+ rename p1 {}
+ rename p2 {}
+ }
+}
+test assemble-2.3 {null script, direct eval} {
+ -body {
+ set x {}
+ assemble $x
+ }
+ -result {}
+ -cleanup {unset x}
+}
+
+# assemble-3 - TclCompileAssembleCmd
+
+test assemble-3.1 {wrong # args, compiled path} {
+ -body {
+ proc x {} {
+ assemble
+ }
+ x
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args:*}
+}
+test assemble-3.2 {wrong # args, compiled path} {
+ -body {
+ proc x {} {
+ assemble too many
+ }
+ x
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args:*}
+ -cleanup {
+ rename x {}
+ }
+}
+
+# assemble-4 - TclAssembleCode mainline
+
+test assemble-4.1 {syntax error} {
+ -body {
+ proc x {} {
+ assemble {
+ {}extra
+ }
+ }
+ list [catch x result] $result $::errorInfo
+ }
+ -cleanup {
+ rename x {}
+ unset result
+ }
+ -match glob
+ -result {1 {extra characters after close-brace} {extra characters after close-brace
+ while executing
+"{}extra
+ "
+ ("assemble" body, line 2)*}}
+}
+test assemble-4.2 {null command} {
+ -body {
+ proc x {} {
+ assemble {
+ push hello; pop;;push goodbye
+ }
+ }
+ x
+ }
+ -result goodbye
+ -cleanup {
+ rename x {}
+ }
+}
+
+# assemble-5 - GetNextOperand off-nominal cases
+
+test assemble-5.1 {unsupported expansion} {
+ -body {
+ proc x {y} {
+ assemble {
+ {*}$y
+ }
+ }
+ list [catch {x {push hello}} result] $result $::errorCode
+ }
+ -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+ -cleanup {
+ rename x {}
+ unset result
+ }
+}
+test assemble-5.2 {unsupported substitution} {
+ -body {
+ proc x {y} {
+ assemble {
+ $y
+ }
+ }
+ list [catch {x {nop}} result] $result $::errorCode
+ }
+ -cleanup {
+ rename x {}
+ unset result
+ }
+ -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+}
+test assemble-5.3 {unsupported substitution} {
+ -body {
+ proc x {} {
+ assemble {
+ [x]
+ }
+ }
+ list [catch {x} result] $result $::errorCode
+ }
+ -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+}
+test assemble-5.4 {backslash substitution} {
+ -body {
+ proc x {} {
+ assemble {
+ p\x75sh\
+ hello\ world
+ }
+ }
+ x
+ }
+ -cleanup {
+ rename x {}
+ }
+ -result {hello world}
+}
+
+# assemble-6 - ASSEM_PUSH
+
+test assemble-6.1 {push, wrong # args} {
+ -body {
+ assemble push
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-6.2 {push, wrong # args} {
+ -body {
+ assemble {push too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-6.3 {push} {
+ -body {
+ eval [list assemble {push hello}]
+ }
+ -result hello
+}
+test assemble-6.4 {push4} {
+ -body {
+ proc x {} "
+ [fillTables]
+ assemble {push hello}
+ "
+ x
+ }
+ -cleanup {
+ rename x {}
+ }
+ -result hello
+}
+
+# assemble-7 - ASSEM_1BYTE
+
+test assemble-7.1 {add, wrong # args} {
+ -body {
+ assemble {add excess}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-7.2 {add} {
+ -body {
+ assemble {
+ push 2
+ push 2
+ add
+ }
+ }
+ -result {4}
+}
+test assemble-7.3 {appendArrayStk} {
+ -body {
+ set a(b) {hello, }
+ assemble {
+ push a
+ push b
+ push world
+ appendArrayStk
+ }
+ set a(b)
+ }
+ -result {hello, world}
+ -cleanup {unset a}
+}
+test assemble-7.4 {appendStk} {
+ -body {
+ set a {hello, }
+ assemble {
+ push a
+ push world
+ appendStk
+ }
+ set a
+ }
+ -result {hello, world}
+ -cleanup {unset a}
+}
+test assemble-7.5 {bitwise ops} {
+ -body {
+ list \
+ [assemble {push 0b1100; push 0b1010; bitand}] \
+ [assemble {push 0b1100; bitnot}] \
+ [assemble {push 0b1100; push 0b1010; bitor}] \
+ [assemble {push 0b1100; push 0b1010; bitxor}]
+ }
+ -result {8 -13 14 6}
+}
+test assemble-7.6 {div} {
+ -body {
+ assemble {push 999999; push 7; div}
+ }
+ -result 142857
+}
+test assemble-7.7 {dup} {
+ -body {
+ assemble {
+ push 1; dup; dup; add; dup; add; dup; add; add
+ }
+ }
+ -result 9
+}
+test assemble-7.8 {eq} {
+ -body {
+ list \
+ [assemble {push able; push baker; eq}] \
+ [assemble {push able; push able; eq}]
+ }
+ -result {0 1}
+}
+test assemble-7.9 {evalStk} {
+ -body {
+ assemble {
+ push {concat test 7.3}
+ evalStk
+ }
+ }
+ -result {test 7.3}
+}
+test assemble-7.9a {evalStk, syntax} {
+ -body {
+ assemble {
+ push {{}bad}
+ evalStk
+ }
+ }
+ -returnCodes error
+ -result {extra characters after close-brace}
+}
+test assemble-7.9b {evalStk, backtrace} {
+ -body {
+ proc y {z} {
+ error testing
+ }
+ proc x {} {
+ assemble {
+ push {
+ # test error in evalStk
+ y asd
+ }
+ evalStk
+ }
+ }
+ list [catch x result] $result $errorInfo
+ }
+ -result {1 testing {testing
+ while executing
+"error testing"
+ (procedure "y" line 2)
+ invoked from within
+"y asd"*}}
+ -match glob
+ -cleanup {
+ rename y {}
+ rename x {}
+ }
+}
+test assemble-7.10 {existArrayStk} {
+ -body {
+ proc x {name key} {
+ set a(b) c
+ assemble {
+ load name; load key; existArrayStk
+ }
+ }
+ list [x a a] [x a b] [x b a] [x b b]
+ }
+ -result {0 1 0 0}
+ -cleanup {rename x {}}
+}
+test assemble-7.11 {existStk} {
+ -body {
+ proc x {name} {
+ set a b
+ assemble {
+ load name; existStk
+ }
+ }
+ list [x a] [x b]
+ }
+ -result {1 0}
+ -cleanup {rename x {}}
+}
+test assemble-7.12 {expon} {
+ -body {
+ assemble {push 3; push 4; expon}
+ }
+ -result 81
+}
+test assemble-7.13 {exprStk} {
+ -body {
+ assemble {
+ push {acos(-1)}
+ exprStk
+ }
+ }
+ -result 3.141592653589793
+}
+test assemble-7.13a {exprStk, syntax} {
+ -body {
+ assemble {
+ push {2+}
+ exprStk
+ }
+ }
+ -returnCodes error
+ -result {missing operand at _@_
+in expression "2+_@_"}
+}
+test assemble-7.13b {exprStk, backtrace} {
+ -body {
+ proc y {z} {
+ error testing
+ }
+ proc x {} {
+ assemble {
+ push {[y asd]}
+ exprStk
+ }
+ }
+ list [catch x result] $result $errorInfo
+ }
+ -result {1 testing {testing
+ while executing
+"error testing"
+ (procedure "y" line 2)
+ invoked from within
+"y asd"*}}
+ -match glob
+ -cleanup {
+ rename y {}
+ rename x {}
+ }
+}
+test assemble-7.14 {ge gt le lt} {
+ -body {
+ proc x {a b} {
+ list [assemble {load a; load b; ge}] \
+ [assemble {load a; load b; gt}] \
+ [assemble {load a; load b; le}] \
+ [assemble {load a; load b; lt}]
+ }
+ list [x 0 0] [x 0 1] [x 1 0]
+ }
+ -result {{1 0 1 0} {0 0 1 1} {1 1 0 0}}
+ -cleanup {rename x {}}
+}
+test assemble-7.15 {incrArrayStk} {
+ -body {
+ proc x {} {
+ set a(b) 5
+ assemble {
+ push a; push b; push 7; incrArrayStk
+ }
+ }
+ x
+ }
+ -result 12
+ -cleanup {rename x {}}
+}
+test assemble-7.16 {incrStk} {
+ -body {
+ proc x {} {
+ set a 5
+ assemble {
+ push a; push 7; incrStk
+ }
+ }
+ x
+ }
+ -result 12
+ -cleanup {rename x {}}
+}
+test assemble-7.17 {land/lor} {
+ -body {
+ proc x {a b} {
+ list \
+ [assemble {load a; load b; land}] \
+ [assemble {load a; load b; lor}]
+ }
+ list [x 0 0] [x 0 23] [x 35 0] [x 47 59]
+ }
+ -result {{0 0} {0 1} {0 1} {1 1}}
+ -cleanup {rename x {}}
+}
+test assemble-7.18 {lappendArrayStk} {
+ -body {
+ proc x {} {
+ set able(baker) charlie
+ assemble {
+ push able
+ push baker
+ push dog
+ lappendArrayStk
+ }
+ }
+ x
+ }
+ -result {charlie dog}
+ -cleanup {rename x {}}
+}
+test assemble-7.19 {lappendStk} {
+ -body {
+ proc x {} {
+ set able baker
+ assemble {
+ push able
+ push charlie
+ lappendStk
+ }
+ }
+ x
+ }
+ -result {baker charlie}
+ -cleanup {rename x {}}
+}
+test assemble-7.20 {listIndex} {
+ -body {
+ assemble {
+ push {a b c d}
+ push 2
+ listIndex
+ }
+ }
+ -result c
+}
+test assemble-7.21 {listLength} {
+ -body {
+ assemble {
+ push {a b c d}
+ listLength
+ }
+ }
+ -result 4
+}
+test assemble-7.22 {loadArrayStk} {
+ -body {
+ proc x {} {
+ set able(baker) charlie
+ assemble {
+ push able
+ push baker
+ loadArrayStk
+ }
+ }
+ x
+ }
+ -result charlie
+ -cleanup {rename x {}}
+}
+test assemble-7.23 {loadStk} {
+ -body {
+ proc x {} {
+ set able baker
+ assemble {
+ push able
+ loadStk
+ }
+ }
+ x
+ }
+ -result baker
+ -cleanup {rename x {}}
+}
+test assemble-7.24 {lsetList} {
+ -body {
+ proc x {} {
+ set l {{a b} {c d} {e f} {g h}}
+ assemble {
+ push {2 1}; push i; load l; lsetList
+ }
+ }
+ x
+ }
+ -result {{a b} {c d} {e i} {g h}}
+}
+test assemble-7.25 {lshift} {
+ -body {
+ assemble {push 16; push 4; lshift}
+ }
+ -result 256
+}
+test assemble-7.26 {mod} {
+ -body {
+ assemble {push 123456; push 1000; mod}
+ }
+ -result 456
+}
+test assemble-7.27 {mult} {
+ -body {
+ assemble {push 12345679; push 9; mult}
+ }
+ -result 111111111
+}
+test assemble-7.28 {neq} {
+ -body {
+ list \
+ [assemble {push able; push baker; neq}] \
+ [assemble {push able; push able; neq}]
+ }
+ -result {1 0}
+}
+test assemble-7.29 {not} {
+ -body {
+ list \
+ [assemble {push 17; not}] \
+ [assemble {push 0; not}]
+ }
+ -result {0 1}
+}
+test assemble-7.30 {pop} {
+ -body {
+ assemble {push this; pop; push that}
+ }
+ -result that
+}
+test assemble-7.31 {rshift} {
+ -body {
+ assemble {push 257; push 4; rshift}
+ }
+ -result 16
+}
+test assemble-7.32 {storeArrayStk} {
+ -body {
+ proc x {} {
+ assemble {
+ push able; push baker; push charlie; storeArrayStk
+ }
+ array get able
+ }
+ x
+ }
+ -result {baker charlie}
+ -cleanup {rename x {}}
+}
+test assemble-7.33 {storeStk} {
+ -body {
+ proc x {} {
+ assemble {
+ push able; push baker; storeStk
+ }
+ set able
+ }
+ x
+ }
+ -result {baker}
+ -cleanup {rename x {}}
+}
+test assemble-7,34 {strcmp} {
+ -body {
+ proc x {a b} {
+ assemble {
+ load a; load b; strcmp
+ }
+ }
+ list [x able baker] [x baker able] [x baker baker]
+ }
+ -result {-1 1 0}
+ -cleanup {rename x {}}
+}
+test assemble-7.35 {streq/strneq} {
+ -body {
+ proc x {a b} {
+ list \
+ [assemble {load a; load b; streq}] \
+ [assemble {load a; load b; strneq}]
+ }
+ list [x able able] [x able baker]
+ }
+ -result {{1 0} {0 1}}
+ -cleanup {rename x {}}
+}
+test assemble-7.36 {strindex} {
+ -body {
+ assemble {push testing; push 4; strindex}
+ }
+ -result i
+}
+test assemble-7.37 {strlen} {
+ -body {
+ assemble {push testing; strlen}
+ }
+ -result 7
+}
+test assemble-7.38 {sub} {
+ -body {
+ assemble {push 42; push 17; sub}
+ }
+ -result 25
+}
+test assemble-7.39 {tryCvtToNumeric} {
+ -body {
+ assemble {
+ push 42; tryCvtToNumeric
+ }
+ }
+ -result 42
+}
+# assemble-7.40 absent
+test assemble-7.41 {uminus} {
+ -body {
+ assemble {
+ push 42; uminus
+ }
+ }
+ -result -42
+}
+test assemble-7.42 {uplus} {
+ -body {
+ assemble {
+ push 42; uplus
+ }
+ }
+ -result 42
+}
+test assemble-7.43 {uplus} {
+ -body {
+ assemble {
+ push NaN; uplus
+ }
+ }
+ -returnCodes error
+ -result {can't use non-numeric floating-point value as operand of "+"}
+}
+test assemble-7.43.1 {tryCvtToNumeric} {
+ -body {
+ assemble {
+ push NaN; tryCvtToNumeric
+ }
+ }
+ -returnCodes error
+ -result {domain error: argument not in valid range}
+}
+test assemble-7.44 {listIn} {
+ -body {
+ assemble {
+ push b; push {a b c}; listIn
+ }
+ }
+ -result 1
+}
+test assemble-7.45 {listNotIn} {
+ -body {
+ assemble {
+ push d; push {a b c}; listNotIn
+ }
+ }
+ -result 1
+}
+test assemble-7.46 {nop} {
+ -body {
+ assemble { push x; nop; nop; nop}
+ }
+ -result x
+}
+
+# assemble-8 ASSEM_LVT and FindLocalVar
+
+test assemble-8.1 {load, wrong # args} {
+ -body {
+ assemble load
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-8.2 {load, wrong # args} {
+ -body {
+ assemble {load too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-8.3 {nonlocal var} {
+ -body {
+ list [catch {assemble {load ::env}} result] $result $errorCode
+ }
+ -result {1 {variable "::env" is not local} {TCL ASSEM NONLOCAL ::env}}
+ -cleanup {unset result}
+}
+test assemble-8.4 {bad context} {
+ -body {
+ set x 1
+ list [catch {assemble {load x}} result] $result $errorCode
+ }
+ -result {1 {cannot use this instruction to create a variable in a non-proc context} {TCL ASSEM LVT}}
+ -cleanup {unset result}
+}
+test assemble-8.5 {bad context} {
+ -body {
+ namespace eval assem {
+ set x 1
+ list [catch {assemble {load x}} result] $result $errorCode
+ }
+ }
+ -result {1 {cannot use this instruction to create a variable in a non-proc context} {TCL ASSEM LVT}}
+ -cleanup {namespace delete assem}
+}
+test assemble-8.6 {load1} {
+ -body {
+ proc x {a} {
+ assemble {
+ load a
+ }
+ }
+ x able
+ }
+ -result able
+ -cleanup {rename x {}}
+}
+test assemble-8.7 {load4} {
+ -body {
+ proc x {a} "
+ [fillTables]
+ set b \$a
+ assemble {load b}
+ "
+ x able
+ }
+ -result able
+ -cleanup {rename x {}}
+}
+test assemble-8.8 {loadArray1} {
+ -body {
+ proc x {} {
+ set able(baker) charlie
+ assemble {
+ push baker
+ loadArray able
+ }
+ }
+ x
+ }
+ -result charlie
+ -cleanup {rename x {}}
+}
+test assemble-8.9 {loadArray4} {
+ -body "
+ proc x {} {
+ [fillTables]
+ set able(baker) charlie
+ assemble {
+ push baker
+ loadArray able
+ }
+ }
+ x
+ "
+ -result charlie
+ -cleanup {rename x {}}
+}
+test assemble-8.10 {append1} {
+ -body {
+ proc x {} {
+ set y {hello, }
+ assemble {
+ push world; append y
+ }
+ }
+ x
+ }
+ -result {hello, world}
+ -cleanup {rename x {}}
+}
+test assemble-8.11 {append4} {
+ -body {
+ proc x {} "
+ [fillTables]
+ set y {hello, }
+ assemble {
+ push world; append y
+ }
+ "
+ x
+ }
+ -result {hello, world}
+ -cleanup {rename x {}}
+}
+test assemble-8.12 {appendArray1} {
+ -body {
+ proc x {} {
+ set y(z) {hello, }
+ assemble {
+ push z; push world; appendArray y
+ }
+ }
+ x
+ }
+ -result {hello, world}
+ -cleanup {rename x {}}
+}
+test assemble-8.13 {appendArray4} {
+ -body {
+ proc x {} "
+ [fillTables]
+ set y(z) {hello, }
+ assemble {
+ push z; push world; appendArray y
+ }
+ "
+ x
+ }
+ -result {hello, world}
+ -cleanup {rename x {}}
+}
+test assemble-8.14 {lappend1} {
+ -body {
+ proc x {} {
+ set y {hello,}
+ assemble {
+ push world; lappend y
+ }
+ }
+ x
+ }
+ -result {hello, world}
+ -cleanup {rename x {}}
+}
+test assemble-8.15 {lappend4} {
+ -body {
+ proc x {} "
+ [fillTables]
+ set y {hello,}
+ assemble {
+ push world; lappend y
+ }
+ "
+ x
+ }
+ -result {hello, world}
+ -cleanup {rename x {}}
+}
+test assemble-8.16 {lappendArray1} {
+ -body {
+ proc x {} {
+ set y(z) {hello,}
+ assemble {
+ push z; push world; lappendArray y
+ }
+ }
+ x
+ }
+ -result {hello, world}
+ -cleanup {rename x {}}
+}
+test assemble-8.17 {lappendArray4} {
+ -body {
+ proc x {} "
+ [fillTables]
+ set y(z) {hello,}
+ assemble {
+ push z; push world; lappendArray y
+ }
+ "
+ x
+ }
+ -result {hello, world}
+ -cleanup {rename x {}}
+}
+test assemble-8.18 {store1} {
+ -body {
+ proc x {} {
+ assemble {
+ push test; store y
+ }
+ set y
+ }
+ x
+ }
+ -result {test}
+ -cleanup {rename x {}}
+}
+test assemble-8.19 {store4} {
+ -body {
+ proc x {} "
+ [fillTables]
+ assemble {
+ push test; store y
+ }
+ set y
+ "
+ x
+ }
+ -result test
+ -cleanup {rename x {}}
+}
+test assemble-8.20 {storeArray1} {
+ -body {
+ proc x {} {
+ assemble {
+ push z; push test; storeArray y
+ }
+ set y(z)
+ }
+ x
+ }
+ -result test
+ -cleanup {rename x {}}
+}
+test assemble-8.21 {storeArray4} {
+ -body {
+ proc x {} "
+ [fillTables]
+ assemble {
+ push z; push test; storeArray y
+ }
+ "
+ x
+ }
+ -result test
+ -cleanup {rename x {}}
+}
+
+# assemble-9 - ASSEM_CONCAT1, GetIntegerOperand, CheckOneByte
+
+test assemble-9.1 {wrong # args} {
+ -body {assemble concat}
+ -result {wrong # args*}
+ -match glob
+ -returnCodes error
+}
+test assemble-9.2 {wrong # args} {
+ -body {assemble {concat too many}}
+ -result {wrong # args*}
+ -match glob
+ -returnCodes error
+}
+test assemble-9.3 {not a number} {
+ -body {assemble {concat rubbish}}
+ -result {expected integer but got "rubbish"}
+ -returnCodes error
+}
+test assemble-9.4 {too small} {
+ -body {assemble {concat -1}}
+ -result {operand does not fit in one byte}
+ -returnCodes error
+}
+test assemble-9.5 {too small} {
+ -body {assemble {concat 256}}
+ -result {operand does not fit in one byte}
+ -returnCodes error
+}
+test assemble-9.6 {concat} {
+ -body {
+ assemble {push h; push e; push l; push l; push o; concat 5}
+ }
+ -result hello
+}
+test assemble-9.7 {concat} {
+ -body {
+ list [catch {assemble {concat 0}} result] $result $::errorCode
+ }
+ -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+ -cleanup {unset result}
+}
+
+# assemble-10 -- eval and expr
+
+test assemble-10.1 {eval - wrong # args} {
+ -body {
+ assemble {eval}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-10.2 {eval - wrong # args} {
+ -body {
+ assemble {eval too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-10.3 {eval} {
+ -body {
+ proc x {} {
+ assemble {
+ push 3
+ store n
+ pop
+ eval {expr {3*$n + 1}}
+ push 1
+ add
+ }
+ }
+ x
+ }
+ -result 11
+ -cleanup {rename x {}}
+}
+test assemble-10.4 {expr} {
+ -body {
+ proc x {} {
+ assemble {
+ push 3
+ store n
+ pop
+ expr {3*$n + 1}
+ push 1
+ add
+ }
+ }
+ x
+ }
+ -result 11
+ -cleanup {rename x {}}
+}
+test assemble-10.5 {eval and expr - nonsimple} {
+ -body {
+ proc x {} {
+ assemble {
+ eval "s\x65t n 3"
+ pop
+ expr "\x33*\$n + 1"
+ push 1
+ add
+ }
+ }
+ x
+ }
+ -result 11
+ -cleanup {
+ rename x {}
+ }
+}
+test assemble-10.6 {eval - noncompilable} {
+ -body {
+ list [catch {assemble {eval $x}} result] $result $::errorCode
+ }
+ -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+}
+test assemble-10.7 {expr - noncompilable} {
+ -body {
+ list [catch {assemble {expr $x}} result] $result $::errorCode
+ }
+ -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+}
+
+# assemble-11 - ASSEM_LVT4 (exist, existArray, dictAppend, dictLappend,
+# nsupvar, variable, upvar)
+
+test assemble-11.1 {exist - wrong # args} {
+ -body {
+ assemble {exist}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-11.2 {exist - wrong # args} {
+ -body {
+ assemble {exist too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-11.3 {nonlocal var} {
+ -body {
+ list [catch {assemble {exist ::env}} result] $result $errorCode
+ }
+ -result {1 {variable "::env" is not local} {TCL ASSEM NONLOCAL ::env}}
+ -cleanup {unset result}
+}
+test assemble-11.4 {exist} {
+ -body {
+ proc x {} {
+ set y z
+ list [assemble {exist y}] \
+ [assemble {exist z}]
+ }
+ x
+ }
+ -result {1 0}
+ -cleanup {rename x {}}
+}
+test assemble-11.5 {existArray} {
+ -body {
+ proc x {} {
+ set a(b) c
+ list [assemble {push b; existArray a}] \
+ [assemble {push c; existArray a}] \
+ [assemble {push a; existArray b}]
+ }
+ x
+ }
+ -result {1 0 0}
+ -cleanup {rename x {}}
+}
+test assemble-11.6 {dictAppend} {
+ -body {
+ proc x {} {
+ set dict {a 1 b 2 c 3}
+ assemble {push b; push 22; dictAppend dict}
+ }
+ x
+ }
+ -result {a 1 b 222 c 3}
+ -cleanup {rename x {}}
+}
+test assemble-11.7 {dictLappend} {
+ -body {
+ proc x {} {
+ set dict {a 1 b 2 c 3}
+ assemble {push b; push 2; dictLappend dict}
+ }
+ x
+ }
+ -result {a 1 b {2 2} c 3}
+ -cleanup {rename x {}}
+}
+test assemble-11.8 {upvar} {
+ -body {
+ proc x {v} {
+ assemble {push 1; load v; upvar w; pop; load w}
+ }
+ proc y {} {
+ set z 123
+ x z
+ }
+ y
+ }
+ -result 123
+ -cleanup {rename x {}; rename y {}}
+}
+test assemble-11.9 {nsupvar} {
+ -body {
+ namespace eval q { variable v 123 }
+ proc x {} {
+ assemble {push q; push v; nsupvar y; pop; load y}
+ }
+ x
+ }
+ -result 123
+ -cleanup {namespace delete q; rename x {}}
+}
+test assemble-11.10 {variable} {
+ -body {
+ namespace eval q { namespace eval r {variable v 123}}
+ proc x {} {
+ assemble {push q::r::v; variable y; load y}
+ }
+ x
+ }
+ -result 123
+ -cleanup {namespace delete q; rename x {}}
+}
+
+# assemble-12 - ASSEM_LVT1 (incr and incrArray)
+
+test assemble-12.1 {incr - wrong # args} {
+ -body {
+ assemble {incr}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-12.2 {incr - wrong # args} {
+ -body {
+ assemble {incr too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-12.3 {incr nonlocal var} {
+ -body {
+ list [catch {assemble {incr ::env}} result] $result $errorCode
+ }
+ -result {1 {variable "::env" is not local} {TCL ASSEM NONLOCAL ::env}}
+ -cleanup {unset result}
+}
+test assemble-12.4 {incr} {
+ -body {
+ proc x {} {
+ set y 5
+ assemble {push 3; incr y}
+ }
+ x
+ }
+ -result 8
+ -cleanup {rename x {}}
+}
+test assemble-12.5 {incrArray} {
+ -body {
+ proc x {} {
+ set a(b) 5
+ assemble {push b; push 3; incrArray a}
+ }
+ x
+ }
+ -result 8
+ -cleanup {rename x {}}
+}
+test assemble-12.6 {incr, stupid stack restriction} {
+ -body {
+ proc x {} "
+ [fillTables]
+ set y 5
+ assemble {push 3; incr y}
+ "
+ list [catch {x} result] $result $errorCode
+ }
+ -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+ -cleanup {unset result; rename x {}}
+}
+
+# assemble-13 -- ASSEM_LVT1_SINT1 - incrImm and incrArrayImm
+
+test assemble-13.1 {incrImm - wrong # args} {
+ -body {
+ assemble {incrImm x}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-13.2 {incrImm - wrong # args} {
+ -body {
+ assemble {incrImm too many args}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-13.3 {incrImm nonlocal var} {
+ -body {
+ list [catch {assemble {incrImm ::env 2}} result] $result $errorCode
+ }
+ -result {1 {variable "::env" is not local} {TCL ASSEM NONLOCAL ::env}}
+ -cleanup {unset result}
+}
+test assemble-13.4 {incrImm not a number} {
+ -body {
+ proc x {} {
+ assemble {incrImm x rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-13.5 {incrImm too big} {
+ -body {
+ proc x {} {
+ assemble {incrImm x 0x80}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-13.6 {incrImm too small} {
+ -body {
+ proc x {} {
+ assemble {incrImm x -0x81}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-13.7 {incrImm} {
+ -body {
+ proc x {} {
+ set y 1
+ list [assemble {incrImm y -0x80}] [assemble {incrImm y 0x7f}]
+ }
+ x
+ }
+ -result {-127 0}
+ -cleanup {rename x {}}
+}
+test assemble-13.8 {incrArrayImm} {
+ -body {
+ proc x {} {
+ set a(b) 5
+ assemble {push b; incrArrayImm a 3}
+ }
+ x
+ }
+ -result 8
+ -cleanup {rename x {}}
+}
+test assemble-13.9 {incrImm, stupid stack restriction} {
+ -body {
+ proc x {} "
+ [fillTables]
+ set y 5
+ assemble {incrImm y 3}
+ "
+ list [catch {x} result] $result $errorCode
+ }
+ -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+ -cleanup {unset result; rename x {}}
+}
+
+# assemble-14 -- ASSEM_SINT1 (incrArrayStkImm and incrStkImm)
+
+test assemble-14.1 {incrStkImm - wrong # args} {
+ -body {
+ assemble {incrStkImm}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-14.2 {incrStkImm - wrong # args} {
+ -body {
+ assemble {incrStkImm too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-14.3 {incrStkImm not a number} {
+ -body {
+ proc x {} {
+ assemble {incrStkImm rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-14.4 {incrStkImm too big} {
+ -body {
+ proc x {} {
+ assemble {incrStkImm 0x80}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-14.5 {incrStkImm too small} {
+ -body {
+ proc x {} {
+ assemble {incrStkImm -0x81}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-14.6 {incrStkImm} {
+ -body {
+ proc x {} {
+ set y 1
+ list [assemble {push y; incrStkImm -0x80}] \
+ [assemble {push y; incrStkImm 0x7f}]
+ }
+ x
+ }
+ -result {-127 0}
+ -cleanup {rename x {}}
+}
+test assemble-14.7 {incrArrayStkImm} {
+ -body {
+ proc x {} {
+ set a(b) 5
+ assemble {push a; push b; incrArrayStkImm 3}
+ }
+ x
+ }
+ -result 8
+ -cleanup {rename x {}}
+}
+
+# assemble-15 - listIndexImm
+
+test assemble-15.1 {listIndexImm - wrong # args} {
+ -body {
+ assemble {listIndexImm}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-15.2 {listIndexImm - wrong # args} {
+ -body {
+ assemble {listIndexImm too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-15.3 {listIndexImm - bad substitution} {
+ -body {
+ list [catch {assemble {listIndexImm $foo}} result] $result $::errorCode
+ }
+ -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+ -cleanup {unset result}
+}
+test assemble-15.4 {listIndexImm - invalid index} {
+ -body {
+ assemble {listIndexImm rubbish}
+ }
+ -returnCodes error
+ -match glob
+ -result {bad index "rubbish"*}
+}
+test assemble-15.5 {listIndexImm} {
+ -body {
+ assemble {push {a b c}; listIndexImm 2}
+ }
+ -result c
+}
+test assemble-15.6 {listIndexImm} {
+ -body {
+ assemble {push {a b c}; listIndexImm end-1}
+ }
+ -result b
+}
+test assemble-15.7 {listIndexImm} {
+ -body {
+ assemble {push {a b c}; listIndexImm end}
+ }
+ -result c
+}
+
+# assemble-16 - invokeStk
+
+test assemble-16.1 {invokeStk - wrong # args} {
+ -body {
+ assemble {invokeStk}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-16.2 {invokeStk - wrong # args} {
+ -body {
+ assemble {invokeStk too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-16.3 {invokeStk - not a number} {
+ -body {
+ proc x {} {
+ assemble {invokeStk rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-16.4 {invokeStk - no operands} {
+ -body {
+ proc x {} {
+ assemble {invokeStk 0}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-16.5 {invokeStk1} {
+ -body {
+ tcl::unsupported::assemble {push concat; push 1; push 2; invokeStk 3}
+ }
+ -result {1 2}
+}
+test assemble-16.6 {invokeStk4} {
+ -body {
+ proc x {n} {
+ set code {push concat}
+ set shouldbe {}
+ for {set i 1} {$i < $n} {incr i} {
+ append code \n {push a} $i
+ lappend shouldbe a$i
+ }
+ append code \n {invokeStk} { } $n
+ set is [assemble $code]
+ expr {$is eq $shouldbe}
+ }
+ list [x 254] [x 255] [x 256] [x 257]
+ }
+ -result {1 1 1 1}
+ -cleanup {rename x {}}
+}
+
+# assemble-17 -- jumps and labels
+
+test assemble-17.1 {label, wrong # args} {
+ -body {
+ assemble {label}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-17.2 {label, wrong # args} {
+ -body {
+ assemble {label too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-17.3 {label, bad subst} {
+ -body {
+ list [catch {assemble {label $foo}} result] $result $::errorCode
+ }
+ -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+ -cleanup {unset result}
+}
+test assemble-17.4 {duplicate label} {
+ -body {
+ list [catch {assemble {label foo; label foo}} result] \
+ $result $::errorCode
+ }
+ -result {1 {duplicate definition of label "foo"} {TCL ASSEM DUPLABEL foo}}
+}
+test assemble-17.5 {jump, wrong # args} {
+ -body {
+ assemble {jump}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-17.6 {jump, wrong # args} {
+ -body {
+ assemble {jump too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-17.7 {jump, bad subst} {
+ -body {
+ list [catch {assemble {jump $foo}} result] $result $::errorCode
+ }
+ -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+ -cleanup {unset result}
+}
+test assemble-17.8 {jump - ahead and back} {
+ -body {
+ assemble {
+ jump three
+
+ label one
+ push a
+ jump four
+
+ label two
+ push b
+ jump six
+
+ label three
+ push c
+ jump five
+
+ label four
+ push d
+ jump two
+
+ label five
+ push e
+ jump one
+
+ label six
+ push f
+ concat 6
+ }
+ }
+ -result ceadbf
+}
+test assemble-17.9 {jump - resolve a label multiple times} {
+ -body {
+ proc x {} {
+ set case 0
+ set result {}
+ assemble {
+ jump common
+
+ label zero
+ pop
+ incrImm case 1
+ pop
+ push a
+ append result
+ pop
+ jump common
+
+ label one
+ pop
+ incrImm case 1
+ pop
+ push b
+ append result
+ pop
+ jump common
+
+ label common
+ load case
+ dup
+ push 0
+ eq
+ jumpTrue zero
+ dup
+ push 1
+ eq
+ jumpTrue one
+ dup
+ push 2
+ eq
+ jumpTrue two
+ dup
+ push 3
+ eq
+ jumpTrue three
+
+ label two
+ pop
+ incrImm case 1
+ pop
+ push c
+ append result
+ pop
+ jump common
+
+ label three
+ pop
+ incrImm case 1
+ pop
+ push d
+ append result
+ }
+ }
+ x
+ }
+ -result abcd
+ -cleanup {rename x {}}
+}
+test assemble-17.10 {jump4 needed} {
+ -body {
+ assemble "push x; jump one; label two; [string repeat {dup; pop;} 128]
+ jump three; label one; jump two; label three"
+ }
+ -result x
+}
+test assemble-17.11 {jumpTrue} {
+ -body {
+ proc x {y} {
+ assemble {
+ load y
+ jumpTrue then
+ push no
+ jump else
+ label then
+ push yes
+ label else
+ }
+ }
+ list [x 0] [x 1]
+ }
+ -result {no yes}
+ -cleanup {rename x {}}
+}
+test assemble-17.12 {jumpFalse} {
+ -body {
+ proc x {y} {
+ assemble {
+ load y
+ jumpFalse then
+ push no
+ jump else
+ label then
+ push yes
+ label else
+ }
+ }
+ list [x 0] [x 1]
+ }
+ -result {yes no}
+ -cleanup {rename x {}}
+}
+test assemble-17.13 {jump to undefined label} {
+ -body {
+ list [catch {assemble {jump nowhere}} result] $result $::errorCode
+ }
+ -result {1 {undefined label "nowhere"} {TCL ASSEM NOLABEL nowhere}}
+}
+test assemble-17.14 {jump to undefined label, line number correct?} {
+ -body {
+ catch {assemble {#1
+ #2
+ #3
+ jump nowhere
+ #5
+ #6
+ }}
+ set ::errorInfo
+ }
+ -match glob
+ -result {*"assemble" body, line 4*}
+}
+test assemble-17.15 {multiple passes of code resizing} {
+ -setup {
+ set body {
+ push -
+ }
+ for {set i 0} {$i < 14} {incr i} {
+ append body "label a" $i \
+ "; push a; concat 2; nop; nop; jump b" \
+ $i \n
+ }
+ append body {label a14; push a; concat 2; push 1; jumpTrue b14} \n
+ append body {label a15; push a; concat 2; push 0; jumpFalse b15} \n
+ for {set i 0} {$i < 15} {incr i} {
+ append body "label b" $i \
+ "; push b; concat 2; nop; nop; jump a" \
+ [expr {$i+1}] \n
+ }
+ append body {label c; push -; concat 2; nop; nop; nop; jump d} \n
+ append body {label b15; push b; concat 2; nop; nop; jump c} \n
+ append body {label d}
+ proc x {} [list assemble $body]
+ }
+ -body {
+ x
+ }
+ -cleanup {
+ catch {unset body}
+ catch {rename x {}}
+ }
+ -result -abababababababababababababababab-
+}
+
+# assemble-18 - lindexMulti
+
+test assemble-18.1 {lindexMulti - wrong # args} {
+ -body {
+ assemble {lindexMulti}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-18.2 {lindexMulti - wrong # args} {
+ -body {
+ assemble {lindexMulti too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-18.3 {lindexMulti - bad subst} {
+ -body {
+ assemble {lindexMulti $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-18.4 {lindexMulti - not a number} {
+ -body {
+ proc x {} {
+ assemble {lindexMulti rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-18.5 {lindexMulti - bad operand count} {
+ -body {
+ proc x {} {
+ assemble {lindexMulti 0}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-18.6 {lindexMulti} {
+ -body {
+ assemble {push {{a b c} {d e f} {g h j}}; lindexMulti 1}
+ }
+ -result {{a b c} {d e f} {g h j}}
+}
+test assemble-18.7 {lindexMulti} {
+ -body {
+ assemble {push {{a b c} {d e f} {g h j}}; push 1; lindexMulti 2}
+ }
+ -result {d e f}
+}
+test assemble-18.8 {lindexMulti} {
+ -body {
+ assemble {push {{a b c} {d e f} {g h j}}; push 2; push 1; lindexMulti 3}
+ }
+ -result h
+}
+
+# assemble-19 - list
+
+test assemble-19.1 {list - wrong # args} {
+ -body {
+ assemble {list}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-19.2 {list - wrong # args} {
+ -body {
+ assemble {list too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-19.3 {list - bad subst} {
+ -body {
+ assemble {list $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-19.4 {list - not a number} {
+ -body {
+ proc x {} {
+ assemble {list rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-19.5 {list - negative operand count} {
+ -body {
+ proc x {} {
+ assemble {list -1}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be nonnegative} {TCL ASSEM NONNEGATIVE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-19.6 {list - no args} {
+ -body {
+ assemble {list 0}
+ }
+ -result {}
+}
+test assemble-19.7 {list - 1 arg} {
+ -body {
+ assemble {push hello; list 1}
+ }
+ -result hello
+}
+test assemble-19.8 {list - 2 args} {
+ -body {
+ assemble {push hello; push world; list 2}
+ }
+ -result {hello world}
+}
+
+# assemble-20 - lsetFlat
+
+test assemble-20.1 {lsetFlat - wrong # args} {
+ -body {
+ assemble {lsetFlat}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-20.2 {lsetFlat - wrong # args} {
+ -body {
+ assemble {lsetFlat too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-20.3 {lsetFlat - bad subst} {
+ -body {
+ assemble {lsetFlat $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-20.4 {lsetFlat - not a number} {
+ -body {
+ proc x {} {
+ assemble {lsetFlat rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-20.5 {lsetFlat - negative operand count} {
+ -body {
+ proc x {} {
+ assemble {lsetFlat 1}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be >=2} {TCL ASSEM OPERAND>=2}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-20.6 {lsetFlat} {
+ -body {
+ assemble {push b; push a; lsetFlat 2}
+ }
+ -result b
+}
+test assemble-20.7 {lsetFlat} {
+ -body {
+ assemble {push 1; push d; push {a b c}; lsetFlat 3}
+ }
+ -result {a d c}
+}
+
+# assemble-21 - over
+
+test assemble-21.1 {over - wrong # args} {
+ -body {
+ assemble {over}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-21.2 {over - wrong # args} {
+ -body {
+ assemble {over too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-21.3 {over - bad subst} {
+ -body {
+ assemble {over $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-21.4 {over - not a number} {
+ -body {
+ proc x {} {
+ assemble {over rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-21.5 {over - negative operand count} {
+ -body {
+ proc x {} {
+ assemble {over -1}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be nonnegative} {TCL ASSEM NONNEGATIVE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-21.6 {over} {
+ -body {
+ proc x {} {
+ assemble {
+ push 1
+ push 2
+ push 3
+ over 0
+ store x
+ pop
+ pop
+ pop
+ pop
+ load x
+ }
+ }
+ x
+ }
+ -result 3
+ -cleanup {rename x {}}
+}
+test assemble-21.7 {over} {
+ -body {
+ proc x {} {
+ assemble {
+ push 1
+ push 2
+ push 3
+ over 2
+ store x
+ pop
+ pop
+ pop
+ pop
+ load x
+ }
+ }
+ x
+ }
+ -result 1
+ -cleanup {rename x {}}
+}
+
+# assemble-22 - reverse
+
+test assemble-22.1 {reverse - wrong # args} {
+ -body {
+ assemble {reverse}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-22.2 {reverse - wrong # args} {
+ -body {
+ assemble {reverse too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+
+test assemble-22.3 {reverse - bad subst} {
+ -body {
+ assemble {reverse $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+
+test assemble-22.4 {reverse - not a number} {
+ -body {
+ proc x {} {
+ assemble {reverse rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-22.5 {reverse - negative operand count} {
+ -body {
+ proc x {} {
+ assemble {reverse -1}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be nonnegative} {TCL ASSEM NONNEGATIVE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-22.6 {reverse - zero operand count} {
+ -body {
+ proc x {} {
+ assemble {push 1; reverse 0}
+ }
+ x
+ }
+ -result 1
+ -cleanup {rename x {}}
+}
+test assemble-22.7 {reverse} {
+ -body {
+ proc x {} {
+ assemble {
+ push 1
+ push 2
+ push 3
+ reverse 1
+ store x
+ pop
+ pop
+ pop
+ load x
+ }
+ }
+ x
+ }
+ -result 3
+ -cleanup {rename x {}}
+}
+test assemble-22.8 {reverse} {
+ -body {
+ proc x {} {
+ assemble {
+ push 1
+ push 2
+ push 3
+ reverse 3
+ store x
+ pop
+ pop
+ pop
+ load x
+ }
+ }
+ x
+ }
+ -result 1
+ -cleanup {rename x {}}
+}
+
+# assemble-23 - ASSEM_BOOL (strmatch, unsetStk, unsetArrayStk)
+
+test assemble-23.1 {strmatch - wrong # args} {
+ -body {
+ assemble {strmatch}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-23.2 {strmatch - wrong # args} {
+ -body {
+ assemble {strmatch too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-23.3 {strmatch - bad subst} {
+ -body {
+ assemble {strmatch $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-23.4 {strmatch - not a boolean} {
+ -body {
+ proc x {} {
+ assemble {strmatch rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected boolean value but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-23.5 {strmatch} {
+ -body {
+ proc x {a b} {
+ list [assemble {load a; load b; strmatch 0}] \
+ [assemble {load a; load b; strmatch 1}]
+ }
+ list [x foo*.grill fengbar.grill] [x foo*.grill foobar.grill] [x foo*.grill FOOBAR.GRILL]
+ }
+ -result {{0 0} {1 1} {0 1}}
+ -cleanup {rename x {}}
+}
+test assemble-23.6 {unsetStk} {
+ -body {
+ proc x {} {
+ set a {}
+ assemble {push a; unsetStk false}
+ info exists a
+ }
+ x
+ }
+ -result 0
+ -cleanup {rename x {}}
+}
+test assemble-23.7 {unsetStk} {
+ -body {
+ proc x {} {
+ assemble {push a; unsetStk false}
+ info exists a
+ }
+ x
+ }
+ -result 0
+ -cleanup {rename x {}}
+}
+test assemble-23.8 {unsetStk} {
+ -body {
+ proc x {} {
+ assemble {push a; unsetStk true}
+ info exists a
+ }
+ x
+ }
+ -returnCodes error
+ -result {can't unset "a": no such variable}
+ -cleanup {rename x {}}
+}
+test assemble-23.9 {unsetArrayStk} {
+ -body {
+ proc x {} {
+ set a(b) {}
+ assemble {push a; push b; unsetArrayStk false}
+ info exists a(b)
+ }
+ x
+ }
+ -result 0
+ -cleanup {rename x {}}
+}
+test assemble-23.10 {unsetArrayStk} {
+ -body {
+ proc x {} {
+ assemble {push a; push b; unsetArrayStk false}
+ info exists a(b)
+ }
+ x
+ }
+ -result 0
+ -cleanup {rename x {}}
+}
+test assemble-23.11 {unsetArrayStk} {
+ -body {
+ proc x {} {
+ assemble {push a; push b; unsetArrayStk true}
+ info exists a(b)
+ }
+ x
+ }
+ -returnCodes error
+ -result {can't unset "a(b)": no such variable}
+ -cleanup {rename x {}}
+}
+
+# assemble-24 -- ASSEM_BOOL_LVT4 (unset; unsetArray)
+
+test assemble-24.1 {unset - wrong # args} {
+ -body {
+ assemble {unset one}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-24.2 {unset - wrong # args} {
+ -body {
+ assemble {unset too many args}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-24.3 {unset - bad subst -arg 1} {
+ -body {
+ assemble {unset $foo bar}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-24.4 {unset - not a boolean} {
+ -body {
+ proc x {} {
+ assemble {unset rubbish trash}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected boolean value but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-24.5 {unset - bad subst - arg 2} {
+ -body {
+ assemble {unset true $bar}
+ }
+ -returnCodes error
+ -result {assembly code may not contain substitutions}
+}
+test assemble-24.6 {unset - nonlocal var} {
+ -body {
+ assemble {unset true ::foo::bar}
+ }
+ -returnCodes error
+ -result {variable "::foo::bar" is not local}
+}
+test assemble-24.7 {unset} {
+ -body {
+ proc x {} {
+ set a {}
+ assemble {unset false a}
+ info exists a
+ }
+ x
+ }
+ -result 0
+ -cleanup {rename x {}}
+}
+test assemble-24.8 {unset} {
+ -body {
+ proc x {} {
+ assemble {unset false a}
+ info exists a
+ }
+ x
+ }
+ -result 0
+ -cleanup {rename x {}}
+}
+test assemble-24.9 {unset} {
+ -body {
+ proc x {} {
+ assemble {unset true a}
+ info exists a
+ }
+ x
+ }
+ -returnCodes error
+ -result {can't unset "a": no such variable}
+ -cleanup {rename x {}}
+}
+test assemble-24.10 {unsetArray} {
+ -body {
+ proc x {} {
+ set a(b) {}
+ assemble {push b; unsetArray false a}
+ info exists a(b)
+ }
+ x
+ }
+ -result 0
+ -cleanup {rename x {}}
+}
+test assemble-24.11 {unsetArray} {
+ -body {
+ proc x {} {
+ assemble {push b; unsetArray false a}
+ info exists a(b)
+ }
+ x
+ }
+ -result 0
+ -cleanup {rename x {}}
+}
+test assemble-24.12 {unsetArray} {
+ -body {
+ proc x {} {
+ assemble {push b; unsetArray true a}
+ info exists a(b)
+ }
+ x
+ }
+ -returnCodes error
+ -result {can't unset "a(b)": no such variable}
+ -cleanup {rename x {}}
+}
+
+# assemble-25 - dict get
+
+test assemble-25.1 {dict get - wrong # args} {
+ -body {
+ assemble {dictGet}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-25.2 {dict get - wrong # args} {
+ -body {
+ assemble {dictGet too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-25.3 {dictGet - bad subst} {
+ -body {
+ assemble {dictGet $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-25.4 {dict get - not a number} {
+ -body {
+ proc x {} {
+ assemble {dictGet rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-25.5 {dictGet - negative operand count} {
+ -body {
+ proc x {} {
+ assemble {dictGet 0}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-25.6 {dictGet - 1 index} {
+ -body {
+ assemble {push {a 1 b 2}; push a; dictGet 1}
+ }
+ -result 1
+}
+
+# assemble-26 - dict set
+
+test assemble-26.1 {dict set - wrong # args} {
+ -body {
+ assemble {dictSet 1}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-26.2 {dict get - wrong # args} {
+ -body {
+ assemble {dictSet too many args}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-26.3 {dictSet - bad subst} {
+ -body {
+ assemble {dictSet 1 $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-26.4 {dictSet - not a number} {
+ -body {
+ proc x {} {
+ assemble {dictSet rubbish foo}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-26.5 {dictSet - zero operand count} {
+ -body {
+ proc x {} {
+ assemble {dictSet 0 foo}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-26.6 {dictSet - bad local} {
+ -body {
+ proc x {} {
+ assemble {dictSet 1 ::foo::bar}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {variable "::foo::bar" is not local} {TCL ASSEM NONLOCAL ::foo::bar}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-26.7 {dictSet} {
+ -body {
+ proc x {} {
+ set dict {a 1 b 2 c 3}
+ assemble {push b; push 4; dictSet 1 dict}
+ }
+ x
+ }
+ -result {a 1 b 4 c 3}
+ -cleanup {rename x {}}
+}
+
+# assemble-27 - dictUnset
+
+test assemble-27.1 {dictUnset - wrong # args} {
+ -body {
+ assemble {dictUnset 1}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-27.2 {dictUnset - wrong # args} {
+ -body {
+ assemble {dictUnset too many args}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-27.3 {dictUnset - bad subst} {
+ -body {
+ assemble {dictUnset 1 $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-27.4 {dictUnset - not a number} {
+ -body {
+ proc x {} {
+ assemble {dictUnset rubbish foo}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-27.5 {dictUnset - zero operand count} {
+ -body {
+ proc x {} {
+ assemble {dictUnset 0 foo}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-27.6 {dictUnset - bad local} {
+ -body {
+ proc x {} {
+ assemble {dictUnset 1 ::foo::bar}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {variable "::foo::bar" is not local} {TCL ASSEM NONLOCAL ::foo::bar}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-27.7 {dictUnset} {
+ -body {
+ proc x {} {
+ set dict {a 1 b 2 c 3}
+ assemble {push b; dictUnset 1 dict}
+ }
+ x
+ }
+ -result {a 1 c 3}
+ -cleanup {rename x {}}
+}
+
+# assemble-28 - dictIncrImm
+
+test assemble-28.1 {dictIncrImm - wrong # args} {
+ -body {
+ assemble {dictIncrImm 1}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-28.2 {dictIncrImm - wrong # args} {
+ -body {
+ assemble {dictIncrImm too many args}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-28.3 {dictIncrImm - bad subst} {
+ -body {
+ assemble {dictIncrImm 1 $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-28.4 {dictIncrImm - not a number} {
+ -body {
+ proc x {} {
+ assemble {dictIncrImm rubbish foo}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected integer but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-28.5 {dictIncrImm - bad local} {
+ -body {
+ proc x {} {
+ assemble {dictIncrImm 1 ::foo::bar}
+ }
+ list [catch x result] $result $::errorCode
+ }
+ -result {1 {variable "::foo::bar" is not local} {TCL ASSEM NONLOCAL ::foo::bar}}
+ -cleanup {rename x {}; unset result}
+}
+test assemble-28.6 {dictIncrImm} {
+ -body {
+ proc x {} {
+ set dict {a 1 b 2 c 3}
+ assemble {push b; dictIncrImm 42 dict}
+ }
+ x
+ }
+ -result {a 1 b 44 c 3}
+ -cleanup {rename x {}}
+}
+
+# assemble-29 - ASSEM_REGEXP
+
+test assemble-29.1 {regexp - wrong # args} {
+ -body {
+ assemble {regexp}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-29.2 {regexp - wrong # args} {
+ -body {
+ assemble {regexp too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-29.3 {regexp - bad subst} {
+ -body {
+ assemble {regexp $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-29.4 {regexp - not a boolean} {
+ -body {
+ proc x {} {
+ assemble {regexp rubbish}
+ }
+ x
+ }
+ -returnCodes error
+ -result {expected boolean value but got "rubbish"}
+ -cleanup {rename x {}}
+}
+test assemble-29.5 {regexp} {
+ -body {
+ assemble {push br.*br; push abracadabra; regexp false}
+ }
+ -result 1
+}
+test assemble-29.6 {regexp} {
+ -body {
+ assemble {push br.*br; push aBRacadabra; regexp false}
+ }
+ -result 0
+}
+test assemble-29.7 {regexp} {
+ -body {
+ assemble {push br.*br; push aBRacadabra; regexp true}
+ }
+ -result 1
+}
+
+# assemble-30 - Catches
+
+test assemble-30.1 {simplest possible catch} {
+ -body {
+ proc x {} {
+ assemble {
+ beginCatch @bad
+ push error
+ push testing
+ invokeStk 2
+ pop
+ push 0
+ jump @ok
+ label @bad
+ push 1; # should be pushReturnCode
+ label @ok
+ endCatch
+ }
+ }
+ x
+ }
+ -result 1
+ -cleanup {rename x {}}
+}
+test assemble-30.2 {catch in external catch conntext} {
+ -body {
+ proc x {} {
+ list [catch {
+ assemble {
+ beginCatch @bad
+ push error
+ push testing
+ invokeStk 2
+ pop
+ push 0
+ jump @ok
+ label @bad
+ pushReturnCode
+ label @ok
+ endCatch
+ }
+ } result] $result
+ }
+ x
+ }
+ -result {0 1}
+ -cleanup {rename x {}}
+}
+test assemble-30.3 {embedded catches} {
+ -body {
+ proc x {} {
+ list [catch {
+ assemble {
+ beginCatch @bad
+ push error
+ eval { list [catch {error whatever} result] $result }
+ invokeStk 2
+ push 0
+ reverse 2
+ jump @done
+ label @bad
+ pushReturnCode
+ pushResult
+ label @done
+ endCatch
+ list 2
+ }
+ } result2] $result2
+ }
+ x
+ }
+ -result {0 {1 {1 whatever}}}
+ -cleanup {rename x {}}
+}
+test assemble-30.4 {throw in wrong context} {
+ -body {
+ proc x {} {
+ list [catch {
+ assemble {
+ beginCatch @bad
+ push error
+ eval { list [catch {error whatever} result] $result }
+ invokeStk 2
+ push 0
+ reverse 2
+ jump @done
+
+ label @bad
+ load x
+ pushResult
+
+ label @done
+ endCatch
+ list 2
+ }
+ } result] $result $::errorCode [split $::errorInfo \n]
+ }
+ x
+ }
+ -match glob
+ -result {1 {"loadScalar1" instruction may not appear in a context where an exception has been caught and not disposed of.} {TCL ASSEM BADTHROW} {{"loadScalar1" instruction may not appear in a context where an exception has been caught and not disposed of.} { in assembly code between lines 10 and 15}*}}
+ -cleanup {rename x {}}
+}
+test assemble-30.5 {unclosed catch} {
+ -body {
+ proc x {} {
+ assemble {
+ beginCatch @error
+ push 0
+ jump @done
+ label @error
+ push 1
+ label @done
+ push ""
+ pop
+ }
+ }
+ list [catch {x} result] $result $::errorCode $::errorInfo
+ }
+ -match glob
+ -result {1 {catch still active on exit from assembly code} {TCL ASSEM UNCLOSEDCATCH} {catch still active on exit from assembly code
+ ("assemble" body, line 2)*}}
+ -cleanup {rename x {}}
+}
+test assemble-30.6 {inconsistent catch contexts} {
+ -body {
+ proc x {y} {
+ assemble {
+ load y
+ jumpTrue @inblock
+ beginCatch @error
+ label @inblock
+ push 0
+ jump @done
+ label @error
+ push 1
+ label @done
+ }
+ }
+ list [catch {x 2} result] $::errorCode $::errorInfo
+ }
+ -match glob
+ -result {1 {TCL ASSEM BADCATCH} {execution reaches an instruction in inconsistent exception contexts
+ ("assemble" body, line 5)*}}
+ -cleanup {rename x {}}
+}
+
+# assemble-31 - Jump tables
+
+test assemble-31.1 {jumpTable, wrong # args} {
+ -body {
+ assemble {jumpTable}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-31.2 {jumpTable, wrong # args} {
+ -body {
+ assemble {jumpTable too many}
+ }
+ -returnCodes error
+ -match glob
+ -result {wrong # args*}
+}
+test assemble-31.3 {jumpTable - bad subst} {
+ -body {
+ assemble {jumpTable $foo}
+ }
+ -returnCodes error
+ -match glob
+ -result {assembly code may not contain substitutions}
+}
+test assemble-31.4 {jumptable - not a list} {
+ -body {
+ assemble {jumpTable \{rubbish}
+ }
+ -returnCodes error
+ -result {unmatched open brace in list}
+}
+test assemble-31.5 {jumpTable, badly structured} {
+ -body {
+ list [catch {assemble {
+ # line 2
+ jumpTable {one two three};# line 3
+ }} result] \
+ $result $::errorCode $::errorInfo
+ }
+ -match glob
+ -result {1 {jump table must have an even number of list elements} {TCL ASSEM BADJUMPTABLE} {jump table must have an even number of list elements*("assemble" body, line 3)*}}
+}
+test assemble-31.6 {jumpTable, missing symbol} {
+ -body {
+ list [catch {assemble {
+ # line 2
+ jumpTable {1 a};# line 3
+ }} result] \
+ $result $::errorCode $::errorInfo
+ }
+ -match glob
+ -result {1 {undefined label "a"} {TCL ASSEM NOLABEL a} {undefined label "a"*("assemble" body, line 3)*}}
+}
+test assemble-31.7 {jumptable, actual example} {
+ -setup {
+ proc x {} {
+ set result {}
+ for {set i 0} {$i < 5} {incr i} {
+ lappend result [assemble {
+ load i
+ jumpTable {1 @one 2 @two 3 @three}
+ push {none of the above}
+ jump @done
+ label @one
+ push one
+ jump @done
+ label @two
+ push two
+ jump @done
+ label @three
+ push three
+ label @done
+ }]
+ }
+ set tcl_traceCompile 2
+ set result
+ }
+ }
+ -body x
+ -result {{none of the above} one two three {none of the above}}
+ -cleanup {set tcl_traceCompile 0; rename x {}}
+}
+
+test assemble-40.1 {unbalanced stack} {
+ -body {
+ list \
+ [catch {
+ assemble {
+ push 3
+ dup
+ mult
+ push 4
+ dup
+ mult
+ pop
+ expon
+ }
+ } result] $result $::errorInfo
+ }
+ -result {1 {stack underflow} {stack underflow
+ in assembly code between lines 1 and end of assembly code*}}
+ -match glob
+ -returnCodes ok
+}
+test assemble-40.2 {unbalanced stack} {*}{
+ -body {
+ list \
+ [catch {
+ assemble {
+ label a
+ push {}
+ label b
+ pop
+ label c
+ pop
+ label d
+ push {}
+ }
+ } result] $result $::errorInfo
+ }
+ -result {1 {stack underflow} {stack underflow
+ in assembly code between lines 7 and 9*}}
+ -match glob
+ -returnCodes ok
+}
+
+test assemble-41.1 {Inconsistent stack usage} {*}{
+ -body {
+ proc x {y} {
+ assemble {
+ load y
+ jumpFalse else
+ push 0
+ jump then
+ label else
+ push 1
+ push 2
+ label then
+ pop
+ }
+ }
+ catch {x 1}
+ set errorInfo
+ }
+ -match glob
+ -result {inconsistent stack depths on two execution paths
+ ("assemble" body, line 10)*}
+}
+test assemble-41.2 {Inconsistent stack, jumptable and default} {
+ -body {
+ proc x {y} {
+ assemble {
+ load y
+ jumpTable {0 else}
+ push 0
+ label else
+ pop
+ }
+ }
+ catch {x 1}
+ set errorInfo
+ }
+ -match glob
+ -result {inconsistent stack depths on two execution paths
+ ("assemble" body, line 6)*}
+}
+test assemble-41.3 {Inconsistent stack, two legs of jumptable} {
+ -body {
+ proc x {y} {
+ assemble {
+ load y
+ jumpTable {0 no 1 yes}
+ label no
+ push 0
+ label yes
+ pop
+ }
+ }
+ catch {x 1}
+ set errorInfo
+ }
+ -match glob
+ -result {inconsistent stack depths on two execution paths
+ ("assemble" body, line 7)*}
+}
+
+test assemble-50.1 {Ulam's 3n+1 problem, TAL implementation} {
+ -body {
+ proc ulam {n} {
+ assemble {
+ load n; # max
+ dup; # max n
+ jump start; # max n
+
+ label loop; # max n
+ over 1; # max n max
+ over 1; # max in max n
+ ge; # man n max>=n
+ jumpTrue skip; # max n
+
+ reverse 2; # n max
+ pop; # n
+ dup; # n n
+
+ label skip; # max n
+ dup; # max n n
+ push 2; # max n n 2
+ mod; # max n n%2
+ jumpTrue odd; # max n
+
+ push 2; # max n 2
+ div; # max n/2 -> max n
+ jump start; # max n
+
+ label odd; # max n
+ push 3; # max n 3
+ mult; # max 3*n
+ push 1; # max 3*n 1
+ add; # max 3*n+1
+
+ label start; # max n
+ dup; # max n n
+ push 1; # max n n 1
+ neq; # max n n>1
+ jumpTrue loop; # max n
+
+ pop; # max
+ }
+ }
+ set result {}
+ for {set i 1} {$i < 30} {incr i} {
+ lappend result [ulam $i]
+ }
+ set result
+ }
+ -result {1 2 16 4 16 16 52 8 52 16 52 16 40 52 160 16 52 52 88 20 64 52 160 24 88 40 9232 52 88}
+}
+
+test assemble-51.1 {memory leak testing} memory {
+ leaktest {
+ apply {{} {assemble {push hello}}}
+ }
+} 0
+test assemble-51.2 {memory leak testing} memory {
+ leaktest {
+ apply {{{x 0}} {assemble {incrImm x 1}}}
+ }
+} 0
+test assemble-51.3 {memory leak testing} memory {
+ leaktest {
+ apply {{n} {
+ assemble {
+ load n; # max
+ dup; # max n
+ jump start; # max n
+
+ label loop; # max n
+ over 1; # max n max
+ over 1; # max in max n
+ ge; # man n max>=n
+ jumpTrue skip; # max n
+
+ reverse 2; # n max
+ pop; # n
+ dup; # n n
+
+ label skip; # max n
+ dup; # max n n
+ push 2; # max n n 2
+ mod; # max n n%2
+ jumpTrue odd; # max n
+
+ push 2; # max n 2
+ div; # max n/2 -> max n
+ jump start; # max n
+
+ label odd; # max n
+ push 3; # max n 3
+ mult; # max 3*n
+ push 1; # max 3*n 1
+ add; # max 3*n+1
+
+ label start; # max n
+ dup; # max n n
+ push 1; # max n n 1
+ neq; # max n n>1
+ jumpTrue loop; # max n
+
+ pop; # max
+ }
+ }} 1
+ }
+} 0
+test assemble-51.4 {memory leak testing} memory {
+ leaktest {
+ catch {
+ apply {{} {
+ assemble {reverse polish notation}
+ }}
+ }
+ }
+} 0
+
+rename fillTables {}
+rename assemble {}
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/assemble1.bench b/pkgs/msgcat/tests/assemble1.bench
new file mode 100644
index 0000000..18fd3a9
--- /dev/null
+++ b/pkgs/msgcat/tests/assemble1.bench
@@ -0,0 +1,85 @@
+proc ulam1 {n} {
+ set max $n
+ while {$n != 1} {
+ if {$n > $max} {
+ set max $n
+ }
+ if {$n % 2} {
+ set n [expr {3 * $n + 1}]
+ } else {
+ set n [expr {$n / 2}]
+ }
+ }
+ return $max
+}
+
+set tcl_traceCompile 2; ulam1 1; set tcl_traceCompile 0
+
+proc ulam2 {n} {
+ tcl::unsupported::assemble {
+ load n; # max
+ dup; # max n
+ jump start; # max n
+
+ label loop; # max n
+ over 1; # max n max
+ over 1; # max in max n
+ ge; # man n max>=n
+ jumpTrue skip; # max n
+
+ reverse 2; # n max
+ pop; # n
+ dup; # n n
+
+ label skip; # max n
+ dup; # max n n
+ push 2; # max n n 2
+ mod; # max n n%2
+ jumpTrue odd; # max n
+
+ push 2; # max n 2
+ div; # max n/2 -> max n
+ jump start; # max n
+
+ label odd; # max n
+ push 3; # max n 3
+ mult; # max 3*n
+ push 1; # max 3*n 1
+ add; # max 3*n+1
+
+ label start; # max n
+ dup; # max n n
+ push 1; # max n n 1
+ neq; # max n n>1
+ jumpTrue loop; # max n
+
+ pop; # max
+ }
+}
+set tcl_traceCompile 2; ulam2 1; set tcl_traceCompile 0
+
+proc test1 {n} {
+ for {set i 1} {$i <= $n} {incr i} {
+ ulam1 $i
+ }
+}
+proc test2 {n} {
+ for {set i 1} {$i <= $n} {incr i} {
+ ulam2 $i
+ }
+}
+
+for {set j 0} {$j < 10} {incr j} {
+ test1 1
+ set before [clock microseconds]
+ test1 30000
+ set after [clock microseconds]
+ puts "compiled: [expr {1e-6 * ($after - $before)}]"
+
+ test2 1
+ set before [clock microseconds]
+ test2 30000
+ set after [clock microseconds]
+ puts "assembled: [expr {1e-6 * ($after - $before)}]"
+}
+ \ No newline at end of file
diff --git a/pkgs/msgcat/tests/assocd.test b/pkgs/msgcat/tests/assocd.test
new file mode 100644
index 0000000..1ca1c9b
--- /dev/null
+++ b/pkgs/msgcat/tests/assocd.test
@@ -0,0 +1,61 @@
+# This file tests the AssocData facility of Tcl
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testgetassocdata [llength [info commands testgetassocdata]]
+testConstraint testsetassocdata [llength [info commands testsetassocdata]]
+testConstraint testdelassocdata [llength [info commands testdelassocdata]]
+
+test assocd-1.1 {testing setting assoc data} testsetassocdata {
+ testsetassocdata a 1
+} ""
+test assocd-1.2 {testing setting assoc data} testsetassocdata {
+ testsetassocdata a 2
+} ""
+test assocd-1.3 {testing setting assoc data} testsetassocdata {
+ testsetassocdata 123 456
+} ""
+test assocd-1.4 {testing setting assoc data} testsetassocdata {
+ testsetassocdata abc "abc d e f"
+} ""
+
+test assocd-2.1 {testing getting assoc data} testgetassocdata {
+ testgetassocdata a
+} 2
+test assocd-2.2 {testing getting assoc data} testgetassocdata {
+ testgetassocdata 123
+} 456
+test assocd-2.3 {testing getting assoc data} testgetassocdata {
+ testgetassocdata abc
+} {abc d e f}
+test assocd-2.4 {testing getting assoc data} testgetassocdata {
+ testgetassocdata xxx
+} ""
+
+test assocd-3.1 {testing deleting assoc data} testdelassocdata {
+ testdelassocdata a
+} ""
+test assocd-3.2 {testing deleting assoc data} testdelassocdata {
+ testdelassocdata 123
+} ""
+test assocd-3.3 {testing deleting assoc data} testdelassocdata {
+ list [catch {testdelassocdata nonexistent} msg] $msg
+} {0 {}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/async.test b/pkgs/msgcat/tests/async.test
new file mode 100644
index 0000000..35dda88
--- /dev/null
+++ b/pkgs/msgcat/tests/async.test
@@ -0,0 +1,213 @@
+# Commands covered: none
+#
+# This file contains a collection of tests for Tcl_AsyncCreate and related
+# library procedures. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testasync [llength [info commands testasync]]
+testConstraint threaded [::tcl::pkgconfig get threaded]
+
+proc async1 {result code} {
+ global aresult acode
+ set aresult $result
+ set acode $code
+ return "new result"
+}
+proc async2 {result code} {
+ global aresult acode
+ set aresult $result
+ set acode $code
+ return -code error "xyzzy"
+}
+proc async3 {result code} {
+ global aresult
+ set aresult "test pattern"
+ return -code $code $result
+}
+proc \# {result code} {
+ global aresult acode
+ set aresult $result
+ set acode $code
+ return "comment quoting"
+}
+
+if {[testConstraint testasync]} {
+ set handler1 [testasync create async1]
+ set handler2 [testasync create async2]
+ set handler3 [testasync create async3]
+ set handler4 [testasync create \#]
+}
+test async-1.1 {basic async handlers} testasync {
+ set aresult xxx
+ set acode yyy
+ list [catch {testasync mark $handler1 "original" 0} msg] $msg \
+ $acode $aresult
+} {0 {new result} 0 original}
+test async-1.2 {basic async handlers} testasync {
+ set aresult xxx
+ set acode yyy
+ list [catch {testasync mark $handler1 "original" 1} msg] $msg \
+ $acode $aresult
+} {0 {new result} 1 original}
+test async-1.3 {basic async handlers} testasync {
+ set aresult xxx
+ set acode yyy
+ list [catch {testasync mark $handler2 "old" 0} msg] $msg \
+ $acode $aresult
+} {1 xyzzy 0 old}
+test async-1.4 {basic async handlers} testasync {
+ set aresult xxx
+ set acode yyy
+ list [catch {testasync mark $handler2 "old" 3} msg] $msg \
+ $acode $aresult
+} {1 xyzzy 3 old}
+test async-1.5 {basic async handlers} testasync {
+ set aresult xxx
+ list [catch {testasync mark $handler3 "foobar" 0} msg] $msg $aresult
+} {0 foobar {test pattern}}
+test async-1.6 {basic async handlers} testasync {
+ set aresult xxx
+ list [catch {testasync mark $handler3 "foobar" 1} msg] $msg $aresult
+} {1 foobar {test pattern}}
+test async-1.7 {basic async handlers} testasync {
+ set aresult xxx
+ set acode yyy
+ list [catch {testasync mark $handler4 "original" 0} msg] $msg \
+ $acode $aresult
+} {0 {comment quoting} 0 original}
+
+proc mult1 {result code} {
+ global x
+ lappend x mult1
+ return -code 7 mult1
+}
+proc mult2 {result code} {
+ global x
+ lappend x mult2
+ return -code 9 mult2
+}
+proc mult3 {result code} {
+ global x hm1 hm2
+ lappend x [catch {testasync mark $hm2 serial2 0}]
+ lappend x [catch {testasync mark $hm1 serial1 0}]
+ lappend x mult3
+ return -code 11 mult3
+}
+if {[testConstraint testasync]} {
+ set hm1 [testasync create mult1]
+ set hm2 [testasync create mult2]
+ set hm3 [testasync create mult3]
+}
+test async-2.1 {multiple handlers} testasync {
+ set x {}
+ list [catch {testasync mark $hm3 "foobar" 5} msg] $msg $x
+} {9 mult2 {0 0 mult3 mult1 mult2}}
+
+proc del1 {result code} {
+ global x hm1 hm2 hm3 hm4
+ lappend x [catch {testasync mark $hm3 serial2 0}]
+ lappend x [catch {testasync mark $hm1 serial1 0}]
+ lappend x [catch {testasync mark $hm4 serial1 0}]
+ testasync delete $hm1
+ testasync delete $hm2
+ testasync delete $hm3
+ lappend x del1
+ return -code 13 del1
+}
+proc del2 {result code} {
+ global x
+ lappend x del2
+ return -code 3 del2
+}
+if {[testConstraint testasync]} {
+ testasync delete $handler1
+ testasync delete $hm2
+ testasync delete $hm3
+ set hm2 [testasync create del1]
+ set hm3 [testasync create mult2]
+ set hm4 [testasync create del2]
+}
+
+test async-3.1 {deleting handlers} testasync {
+ set x {}
+ list [catch {testasync mark $hm2 "foobar" 5} msg] $msg $x
+} {3 del2 {0 0 0 del1 del2}}
+
+test async-4.1 {async interrupting bytecode sequence} -constraints {
+ testasync threaded
+} -setup {
+ set hm [testasync create async3]
+ proc nothing {} {
+ # empty proc
+ }
+} -body {
+ apply {{handle} {
+ global aresult
+ set aresult {Async event not delivered}
+ testasync marklater $handle
+ for {set i 0} {
+ $i < 2500000 && $aresult eq "Async event not delivered"
+ } {incr i} {
+ nothing
+ }
+ return $aresult
+ }} $hm
+} -result {test pattern} -cleanup {
+ testasync delete $hm
+}
+test async-4.2 {async interrupting straight bytecode sequence} -constraints {
+ testasync threaded
+} -setup {
+ set hm [testasync create async3]
+} -body {
+ apply {{handle} {
+ global aresult
+ set aresult {Async event not delivered}
+ testasync marklater $handle
+ for {set i 0} {
+ $i < 2500000 && $aresult eq "Async event not delivered"
+ } {incr i} {}
+ return $aresult
+ }} $hm
+} -result {test pattern} -cleanup {
+ testasync delete $hm
+}
+test async-4.3 {async interrupting loop-less bytecode sequence} -constraints {
+ testasync threaded
+} -setup {
+ set hm [testasync create async3]
+} -body {
+ apply [list {handle} [concat {
+ global aresult
+ set aresult {Async event not delivered}
+ testasync marklater $handle
+ set i 0
+ } "[string repeat {;incr i;} 1500000]after 10;" {
+ return $aresult
+ }]] $hm
+} -result {test pattern} -cleanup {
+ testasync delete $hm
+}
+
+# cleanup
+if {[testConstraint testasync]} {
+ testasync delete
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/autoMkindex.test b/pkgs/msgcat/tests/autoMkindex.test
new file mode 100644
index 0000000..8f29131
--- /dev/null
+++ b/pkgs/msgcat/tests/autoMkindex.test
@@ -0,0 +1,340 @@
+# Commands covered: auto_mkindex auto_import
+#
+# This file contains tests related to autoloading and generating the
+# autoloading index.
+#
+# Copyright (c) 1998 Lucent Technologies, 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+makeFile {# Test file for:
+# auto_mkindex
+#
+# This file provides example cases for testing the Tcl autoloading facility.
+# Things are much more complicated with namespaces and classes. The
+# "auto_mkindex" facility can no longer be built on top of a simple regular
+# expression parser. It must recognize constructs like this:
+#
+# namespace eval foo {
+# proc test {x y} { ... }
+# namespace eval bar {
+# proc another {args} { ... }
+# }
+# }
+#
+# Note that procedures and itcl class definitions can be nested inside of
+# namespaces.
+#
+# Copyright (c) 1993-1998 Lucent Technologies, Inc.
+
+# This shouldn't cause any problems
+namespace import -force blt::*
+
+# Should be able to handle "proc" definitions, even if they are preceded by
+# white space.
+
+proc normal {x y} {return [expr $x+$y]}
+ proc indented {x y} {return [expr $x+$y]}
+
+#
+# Should be able to handle proc declarations within namespaces, even if they
+# have explicit namespace paths.
+#
+namespace eval buried {
+ proc inside {args} {return "inside: $args"}
+
+ namespace export pub_*
+ proc pub_one {args} {return "one: $args"}
+ proc pub_two {args} {return "two: $args"}
+}
+proc buried::within {args} {return "within: $args"}
+
+namespace eval buried {
+ namespace eval under {
+ proc neath {args} {return "neath: $args"}
+ }
+ namespace eval ::buried {
+ proc relative {args} {return "relative: $args"}
+ proc ::top {args} {return "top: $args"}
+ proc ::buried::explicit {args} {return "explicit: $args"}
+ }
+}
+
+# With proper hooks, we should be able to support other commands that create
+# procedures
+
+proc buried::myproc {name body args} {
+ ::proc $name $body $args
+}
+namespace eval ::buried {
+ proc mycmd1 args {return "mycmd"}
+ myproc mycmd2 args {return "mycmd"}
+}
+::buried::myproc mycmd3 args {return "another"}
+
+proc {buried::my proc} {name body args} {
+ ::proc $name $body $args
+}
+namespace eval ::buried {
+ proc mycmd4 args {return "mycmd"}
+ {my proc} mycmd5 args {return "mycmd"}
+}
+{::buried::my proc} mycmd6 args {return "another"}
+
+# A correctly functioning [auto_import] won't choke when a child namespace
+# [namespace import]s from its parent.
+#
+namespace eval ::parent::child {
+ namespace import ::parent::*
+}
+proc ::parent::child::test {} {}
+} autoMkindex.tcl
+
+# Save initial state of auto_mkindex_parser
+
+auto_load auto_mkindex
+if {[info exists auto_mkindex_parser::initCommands]} {
+ set saveCommands $auto_mkindex_parser::initCommands
+}
+proc AutoMkindexTestReset {} {
+ global saveCommands
+ if {[info exists saveCommands]} {
+ set auto_mkindex_parser::initCommands $saveCommands
+ } elseif {[info exists auto_mkindex_parser::initCommands]} {
+ unset auto_mkindex_parser::initCommands
+ }
+}
+
+set result ""
+
+set origDir [pwd]
+cd $::tcltest::temporaryDirectory
+
+test autoMkindex-1.1 {remove any existing tclIndex file} {
+ file delete tclIndex
+ file exists tclIndex
+} {0}
+test autoMkindex-1.2 {build tclIndex based on a test file} {
+ auto_mkindex . autoMkindex.tcl
+ file exists tclIndex
+} {1}
+set element "{source [file join . autoMkindex.tcl]}"
+test autoMkindex-1.3 {examine tclIndex} -setup {
+ file delete tclIndex
+} -body {
+ auto_mkindex . autoMkindex.tcl
+ namespace eval tcl_autoMkindex_tmp {
+ set dir "."
+ variable auto_index
+ source tclIndex
+ set ::result ""
+ foreach elem [lsort [array names auto_index]] {
+ lappend ::result [list $elem $auto_index($elem)]
+ }
+ }
+ return $result
+} -cleanup {
+ namespace delete tcl_autoMkindex_tmp
+} -result "{::buried::explicit $element} {::buried::inside $element} {{::buried::my proc} $element} {::buried::mycmd1 $element} {::buried::mycmd4 $element} {::buried::myproc $element} {::buried::pub_one $element} {::buried::pub_two $element} {::buried::relative $element} {::buried::under::neath $element} {::buried::within $element} {::parent::child::test $element} {indented $element} {normal $element} {top $element}"
+
+test autoMkindex-2.1 {commands on the autoload path can be imported} -setup {
+ file delete tclIndex
+ interp create slave
+} -body {
+ auto_mkindex . autoMkindex.tcl
+ slave eval {
+ namespace eval blt {}
+ set auto_path [linsert $auto_path 0 .]
+ set info [list [catch {namespace import buried::*} result] $result]
+ foreach name [lsort [info commands pub_*]] {
+ lappend info $name [namespace origin $name]
+ }
+ return $info
+ }
+} -cleanup {
+ interp delete slave
+} -result "0 {} pub_one ::buried::pub_one pub_two ::buried::pub_two"
+
+# Test auto_mkindex hooks
+
+# Slave hook executes interesting code in the interp used to watch code.
+test autoMkindex-3.1 {slaveHook} -setup {
+ file delete tclIndex
+} -body {
+ auto_mkindex_parser::slavehook {
+ _%@namespace eval ::blt {
+ proc foo {} {}
+ _%@namespace export foo
+ }
+ }
+ auto_mkindex_parser::slavehook { _%@namespace import -force ::blt::* }
+ auto_mkindex . autoMkindex.tcl
+ file exists tclIndex
+} -cleanup {
+ # Reset initCommands to avoid trashing other tests
+ AutoMkindexTestReset
+} -result 1
+# The auto_mkindex_parser::command is used to register commands that create
+# new commands.
+test autoMkindex-3.2 {auto_mkindex_parser::command} -setup {
+ file delete tclIndex
+} -body {
+ auto_mkindex_parser::command buried::myproc {name args} {
+ variable index
+ variable scriptFile
+ append index [list set auto_index([fullname $name])] \
+ " \[list source \[file join \$dir [list $scriptFile]\]\]\n"
+ }
+ auto_mkindex . autoMkindex.tcl
+ namespace eval tcl_autoMkindex_tmp {
+ set dir "."
+ variable auto_index
+ source tclIndex
+ set ::result ""
+ foreach elem [lsort [array names auto_index]] {
+ lappend ::result [list $elem $auto_index($elem)]
+ }
+ return $::result
+ }
+} -cleanup {
+ namespace delete tcl_autoMkindex_tmp
+ # Reset initCommands to avoid trashing other tests
+ AutoMkindexTestReset
+} -result "{::buried::explicit $element} {::buried::inside $element} {{::buried::my proc} $element} {::buried::mycmd1 $element} {::buried::mycmd2 $element} {::buried::mycmd4 $element} {::buried::myproc $element} {::buried::pub_one $element} {::buried::pub_two $element} {::buried::relative $element} {::buried::under::neath $element} {::buried::within $element} {::parent::child::test $element} {indented $element} {mycmd3 $element} {normal $element} {top $element}"
+test autoMkindex-3.3 {auto_mkindex_parser::command} -setup {
+ file delete tclIndex
+} -constraints {knownBug} -body {
+ auto_mkindex_parser::command {buried::my proc} {name args} {
+ variable index
+ variable scriptFile
+ puts "my proc $name"
+ append index [list set auto_index([fullname $name])] \
+ " \[list source \[file join \$dir [list $scriptFile]\]\]\n"
+ }
+ auto_mkindex . autoMkindex.tcl
+ namespace eval tcl_autoMkindex_tmp {
+ set dir "."
+ variable auto_index
+ source tclIndex
+ set ::result ""
+ foreach elem [lsort [array names auto_index]] {
+ lappend ::result [list $elem $auto_index($elem)]
+ }
+ }
+ list [lsearch -inline $::result *mycmd4*] \
+ [lsearch -inline $::result *mycmd5*] \
+ [lsearch -inline $::result *mycmd6*]
+} -cleanup {
+ namespace delete tcl_autoMkindex_tmp
+ # Reset initCommands to avoid trashing other tests
+ AutoMkindexTestReset
+} -result "{::buried::mycmd4 $element} {::buried::mycmd5 $element} {mycmd6 $element}"
+
+test autoMkindex-4.1 {platform independent source commands} -setup {
+ file delete tclIndex
+ makeDirectory pkg
+ makeFile {
+ package provide football 1.0
+ namespace eval ::pro:: {
+ #
+ # export only public functions.
+ #
+ namespace export {[a-z]*}
+ }
+ namespace eval ::college:: {
+ #
+ # export only public functions.
+ #
+ namespace export {[a-z]*}
+ }
+ proc ::pro::team {} {
+ puts "go packers!"
+ return true
+ }
+ proc ::college::team {} {
+ puts "go badgers!"
+ return true
+ }
+ } [file join pkg samename.tcl]
+} -body {
+ auto_mkindex . pkg/samename.tcl
+ set f [open tclIndex r]
+ lsort [lrange [split [string trim [read $f]] "\n"] end-1 end]
+} -cleanup {
+ catch {close $f}
+ removeFile [file join pkg samename.tcl]
+ removeDirectory pkg
+} -result {{set auto_index(::college::team) [list source [file join $dir pkg samename.tcl]]} {set auto_index(::pro::team) [list source [file join $dir pkg samename.tcl]]}}
+
+test autoMkindex-5.1 {escape magic tcl chars in general code} -setup {
+ file delete tclIndex
+ makeDirectory pkg
+ makeFile {
+ set dollar1 "this string contains an unescaped dollar sign -> \\$foo"
+ set dollar2 \
+ "this string contains an escaped dollar sign -> \$foo \\\$foo"
+ set bracket1 "this contains an unescaped bracket [NoSuchProc]"
+ set bracket2 "this contains an escaped bracket \[NoSuchProc\]"
+ set bracket3 \
+ "this contains nested unescaped brackets [[NoSuchProc]]"
+ proc testProc {} {}
+ } [file join pkg magicchar.tcl]
+ set result {}
+} -body {
+ auto_mkindex . pkg/magicchar.tcl
+ set f [open tclIndex r]
+ lindex [split [string trim [read $f]] "\n"] end
+} -cleanup {
+ catch {close $f}
+ removeFile [file join pkg magicchar.tcl]
+ removeDirectory pkg
+} -result {set auto_index(testProc) [list source [file join $dir pkg magicchar.tcl]]}
+test autoMkindex-5.2 {correctly locate auto loaded procs with []} -setup {
+ file delete tclIndex
+ makeDirectory pkg
+ makeFile {
+ proc {[magic mojo proc]} {} {}
+ } [file join pkg magicchar2.tcl]
+ set result {}
+ interp create slave
+} -body {
+ auto_mkindex . pkg/magicchar2.tcl
+ # Make a slave interp to test the autoloading
+ slave eval {lappend auto_path [pwd]}
+ slave eval {catch {{[magic mojo proc]}}}
+} -cleanup {
+ interp delete slave
+ removeFile [file join pkg magicchar2.tcl]
+ removeDirectory pkg
+} -result 0
+
+# Clean up.
+
+unset result
+AutoMkindexTestReset
+if {[info exists saveCommands]} {
+ unset saveCommands
+}
+rename AutoMkindexTestReset ""
+
+removeFile autoMkindex.tcl
+if {[file exists tclIndex]} {
+ file delete -force tclIndex
+}
+
+cd $origDir
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/basic.test b/pkgs/msgcat/tests/basic.test
new file mode 100644
index 0000000..e072bea
--- /dev/null
+++ b/pkgs/msgcat/tests/basic.test
@@ -0,0 +1,974 @@
+# This file contains tests for the tclBasic.c source file. Tests appear in
+# the same order as the C code that they test. The set of tests is
+# currently incomplete since it currently includes only new tests for
+# code changed for the addition of Tcl namespaces. Other variable-
+# related tests appear in several other test files including
+# assocd.test, cmdInfo.test, eval.test, expr.test, interp.test,
+# and trace.test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+testConstraint testevalex [llength [info commands testevalex]]
+testConstraint testcmdtoken [llength [info commands testcmdtoken]]
+testConstraint testcreatecommand [llength [info commands testcreatecommand]]
+testConstraint exec [llength [info commands exec]]
+
+catch {namespace delete test_ns_basic}
+catch {interp delete test_interp}
+catch {rename p ""}
+catch {rename q ""}
+catch {rename cmd ""}
+catch {unset x}
+
+test basic-1.1 {Tcl_CreateInterp, creates interp's global namespace} {
+ catch {interp delete test_interp}
+ interp create test_interp
+ interp eval test_interp {
+ namespace eval test_ns_basic {
+ proc p {} {
+ return [namespace current]
+ }
+ }
+ }
+ list [interp eval test_interp {test_ns_basic::p}] \
+ [interp delete test_interp]
+} {::test_ns_basic {}}
+
+test basic-2.1 {TclHideUnsafeCommands} {emptyTest} {
+} {}
+
+test basic-3.1 {Tcl_CallWhenDeleted: see dcall.test} {emptyTest} {
+} {}
+
+test basic-4.1 {Tcl_DontCallWhenDeleted: see dcall.test} {emptyTest} {
+} {}
+
+test basic-5.1 {Tcl_SetAssocData: see assoc.test} {emptyTest} {
+} {}
+
+test basic-6.1 {Tcl_DeleteAssocData: see assoc.test} {emptyTest} {
+} {}
+
+test basic-7.1 {Tcl_GetAssocData: see assoc.test} {emptyTest} {
+} {}
+
+test basic-8.1 {Tcl_InterpDeleted} {emptyTest} {
+} {}
+
+test basic-9.1 {Tcl_DeleteInterp: see interp.test} {emptyTest} {
+} {}
+
+test basic-10.1 {DeleteInterpProc, destroys interp's global namespace} {
+ catch {interp delete test_interp}
+ interp create test_interp
+ interp eval test_interp {
+ namespace eval test_ns_basic {
+ namespace export p
+ proc p {} {
+ return [namespace current]
+ }
+ }
+ namespace eval test_ns_2 {
+ namespace import ::test_ns_basic::p
+ variable v 27
+ proc q {} {
+ variable v
+ return "[p] $v"
+ }
+ }
+ }
+ list [interp eval test_interp {test_ns_2::q}] \
+ [interp eval test_interp {namespace delete ::}] \
+ [catch {interp eval test_interp {set a 123}} msg] $msg \
+ [interp delete test_interp]
+} {{::test_ns_basic 27} {} 1 {invalid command name "set"} {}}
+
+test basic-11.1 {HiddenCmdsDeleteProc, invalidate cached refs to deleted hidden cmd} {
+ catch {interp delete test_interp}
+ interp create test_interp
+ interp eval test_interp {
+ proc p {} {
+ return 27
+ }
+ }
+ interp alias {} localP test_interp p
+ list [interp eval test_interp {p}] \
+ [localP] \
+ [test_interp hide p] \
+ [catch {localP} msg] $msg \
+ [interp delete test_interp] \
+ [catch {localP} msg] $msg
+} {27 27 {} 1 {invalid command name "p"} {} 1 {invalid command name "localP"}}
+
+# NB: More tests about hide/expose are found in interp.test
+
+test basic-12.1 {Tcl_HideCommand, names of hidden cmds can't have namespace qualifiers} {
+ catch {interp delete test_interp}
+ interp create test_interp
+ interp eval test_interp {
+ namespace eval test_ns_basic {
+ proc p {} {
+ return [namespace current]
+ }
+ }
+ }
+ list [catch {test_interp hide test_ns_basic::p x} msg] $msg \
+ [catch {test_interp hide x test_ns_basic::p} msg1] $msg1 \
+ [interp delete test_interp]
+} {1 {can only hide global namespace commands (use rename then hide)} 1 {cannot use namespace qualifiers in hidden command token (rename)} {}}
+
+test basic-12.2 {Tcl_HideCommand, a hidden cmd remembers its containing namespace} {
+ catch {namespace delete test_ns_basic}
+ catch {rename cmd ""}
+ proc cmd {} { ;# note that this is global
+ return [namespace current]
+ }
+ namespace eval test_ns_basic {
+ proc hideCmd {} {
+ interp hide {} cmd
+ }
+ proc exposeCmd {} {
+ interp expose {} cmd
+ }
+ proc callCmd {} {
+ cmd
+ }
+ }
+ list [test_ns_basic::callCmd] \
+ [test_ns_basic::hideCmd] \
+ [catch {cmd} msg] $msg \
+ [test_ns_basic::exposeCmd] \
+ [test_ns_basic::callCmd] \
+ [namespace delete test_ns_basic]
+} {:: {} 1 {invalid command name "cmd"} {} :: {}}
+
+test basic-13.1 {Tcl_ExposeCommand, a command stays in the global namespace and cannot go to another namespace} {
+ catch {namespace delete test_ns_basic}
+ catch {rename cmd ""}
+ proc cmd {} { ;# note that this is global
+ return [namespace current]
+ }
+ namespace eval test_ns_basic {
+ proc hideCmd {} {
+ interp hide {} cmd
+ }
+ proc exposeCmdFailing {} {
+ interp expose {} cmd ::test_ns_basic::newCmd
+ }
+ proc exposeCmdWorkAround {} {
+ interp expose {} cmd;
+ rename cmd ::test_ns_basic::newCmd;
+ }
+ proc callCmd {} {
+ cmd
+ }
+ }
+ list [test_ns_basic::callCmd] \
+ [test_ns_basic::hideCmd] \
+ [catch {test_ns_basic::exposeCmdFailing} msg] $msg \
+ [test_ns_basic::exposeCmdWorkAround] \
+ [test_ns_basic::newCmd] \
+ [namespace delete test_ns_basic]
+} {:: {} 1 {cannot expose to a namespace (use expose to toplevel, then rename)} {} ::test_ns_basic {}}
+test basic-13.2 {Tcl_ExposeCommand, invalidate cached refs to cmd now being exposed} {
+ catch {rename p ""}
+ catch {rename cmd ""}
+ proc p {} {
+ cmd
+ }
+ proc cmd {} {
+ return 42
+ }
+ list [p] \
+ [interp hide {} cmd] \
+ [proc cmd {} {return Hello}] \
+ [cmd] \
+ [rename cmd ""] \
+ [interp expose {} cmd] \
+ [p]
+} {42 {} {} Hello {} {} 42}
+
+test basic-14.1 {Tcl_CreateCommand, new cmd goes into a namespace specified in its name, if any} {testcreatecommand} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [testcreatecommand create] \
+ [test_ns_basic::createdcommand] \
+ [testcreatecommand delete]
+} {{} {CreatedCommandProc in ::test_ns_basic} {}}
+test basic-14.2 {Tcl_CreateCommand, namespace code ignore single ":"s in middle or end of names} {testcreatecommand} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename value:at: ""}
+ list [testcreatecommand create2] \
+ [value:at:] \
+ [testcreatecommand delete2]
+} {{} {CreatedCommandProc2 in ::} {}}
+
+test basic-15.1 {Tcl_CreateObjCommand, new cmd goes into a namespace specified in its name, if any} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_basic {}
+ proc test_ns_basic::cmd {} { ;# proc requires that ns already exist
+ return [namespace current]
+ }
+ list [test_ns_basic::cmd] \
+ [namespace delete test_ns_basic]
+} {::test_ns_basic {}}
+
+test basic-16.1 {TclInvokeStringCommand} {emptyTest} {
+} {}
+
+test basic-17.1 {TclInvokeObjCommand} {emptyTest} {
+} {}
+
+test basic-18.1 {TclRenameCommand, name of existing cmd can have namespace qualifiers} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename cmd ""}
+ namespace eval test_ns_basic {
+ proc p {} {
+ return "p in [namespace current]"
+ }
+ }
+ list [test_ns_basic::p] \
+ [rename test_ns_basic::p test_ns_basic::q] \
+ [test_ns_basic::q]
+} {{p in ::test_ns_basic} {} {p in ::test_ns_basic}}
+test basic-18.2 {TclRenameCommand, existing cmd must be found} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {rename test_ns_basic::p test_ns_basic::q} msg] $msg
+} {1 {can't rename "test_ns_basic::p": command doesn't exist}}
+test basic-18.3 {TclRenameCommand, delete cmd if new name is empty} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_basic {
+ proc p {} {
+ return "p in [namespace current]"
+ }
+ }
+ list [info commands test_ns_basic::*] \
+ [rename test_ns_basic::p ""] \
+ [info commands test_ns_basic::*]
+} {::test_ns_basic::p {} {}}
+test basic-18.4 {TclRenameCommand, bad new name} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_basic {
+ proc p {} {
+ return "p in [namespace current]"
+ }
+ }
+ rename test_ns_basic::p :::george::martha
+} {}
+test basic-18.5 {TclRenameCommand, new name must not already exist} {
+ namespace eval test_ns_basic {
+ proc q {} {
+ return 42
+ }
+ }
+ list [catch {rename test_ns_basic::q :::george::martha} msg] $msg
+} {1 {can't rename to ":::george::martha": command already exists}}
+test basic-18.6 {TclRenameCommand, check for command shadowing by newly renamed cmd} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename p ""}
+ catch {rename q ""}
+ proc p {} {
+ return "p in [namespace current]"
+ }
+ proc q {} {
+ return "q in [namespace current]"
+ }
+ namespace eval test_ns_basic {
+ proc callP {} {
+ p
+ }
+ }
+ list [test_ns_basic::callP] \
+ [rename q test_ns_basic::p] \
+ [test_ns_basic::callP]
+} {{p in ::} {} {q in ::test_ns_basic}}
+
+test basic-19.1 {Tcl_SetCommandInfo} {emptyTest} {
+} {}
+
+test basic-20.1 {Tcl_GetCommandInfo, names for commands created inside namespaces} {testcmdtoken} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename p ""}
+ catch {rename q ""}
+ catch {unset x}
+ set x [namespace eval test_ns_basic::test_ns_basic2 {
+ # the following creates a cmd in the global namespace
+ testcmdtoken create p
+ }]
+ list [testcmdtoken name $x] \
+ [rename ::p q] \
+ [testcmdtoken name $x]
+} {{p ::p} {} {q ::q}}
+test basic-20.2 {Tcl_GetCommandInfo, names for commands created outside namespaces} {testcmdtoken} {
+ catch {rename q ""}
+ set x [testcmdtoken create test_ns_basic::test_ns_basic2::p]
+ list [testcmdtoken name $x] \
+ [rename test_ns_basic::test_ns_basic2::p q] \
+ [testcmdtoken name $x]
+} {{p ::test_ns_basic::test_ns_basic2::p} {} {q ::q}}
+test basic-20.3 {Tcl_GetCommandInfo, #-quoting} testcmdtoken {
+ catch {rename \# ""}
+ set x [testcmdtoken create \#]
+ testcmdtoken name $x
+} {{#} ::#}
+
+test basic-21.1 {Tcl_GetCommandName} {emptyTest} {
+} {}
+
+test basic-22.1 {Tcl_GetCommandFullName} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_basic1 {
+ namespace export cmd*
+ proc cmd1 {} {}
+ proc cmd2 {} {}
+ }
+ namespace eval test_ns_basic2 {
+ namespace export *
+ namespace import ::test_ns_basic1::*
+ proc p {} {}
+ }
+ namespace eval test_ns_basic3 {
+ namespace import ::test_ns_basic2::*
+ proc q {} {}
+ list [namespace which -command foreach] \
+ [namespace which -command q] \
+ [namespace which -command p] \
+ [namespace which -command cmd1] \
+ [namespace which -command ::test_ns_basic2::cmd2]
+ }
+} {::foreach ::test_ns_basic3::q ::test_ns_basic3::p ::test_ns_basic3::cmd1 ::test_ns_basic2::cmd2}
+
+test basic-23.1 {Tcl_DeleteCommand} {emptyTest} {
+} {}
+
+test basic-24.1 {Tcl_DeleteCommandFromToken, invalidate all compiled code if cmd has compile proc} {
+ catch {interp delete test_interp}
+ catch {unset x}
+ interp create test_interp
+ interp eval test_interp {
+ proc useSet {} {
+ return [set a 123]
+ }
+ }
+ set x [interp eval test_interp {useSet}]
+ interp eval test_interp {
+ rename set ""
+ proc set {args} {
+ return "set called with $args"
+ }
+ }
+ list $x \
+ [interp eval test_interp {useSet}] \
+ [interp delete test_interp]
+} {123 {set called with a 123} {}}
+test basic-24.2 {Tcl_DeleteCommandFromToken, deleting commands changes command epoch} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename p ""}
+ proc p {} {
+ return "global p"
+ }
+ namespace eval test_ns_basic {
+ proc p {} {
+ return "namespace p"
+ }
+ proc callP {} {
+ p
+ }
+ }
+ list [test_ns_basic::callP] \
+ [rename test_ns_basic::p ""] \
+ [test_ns_basic::callP]
+} {{namespace p} {} {global p}}
+test basic-24.3 {Tcl_DeleteCommandFromToken, delete imported cmds that refer to a deleted cmd} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename p ""}
+ namespace eval test_ns_basic {
+ namespace export p
+ proc p {} {return 42}
+ }
+ namespace eval test_ns_basic2 {
+ namespace import ::test_ns_basic::*
+ proc callP {} {
+ p
+ }
+ }
+ list [test_ns_basic2::callP] \
+ [info commands test_ns_basic2::*] \
+ [rename test_ns_basic::p ""] \
+ [catch {test_ns_basic2::callP} msg] $msg \
+ [info commands test_ns_basic2::*]
+} {42 {::test_ns_basic2::callP ::test_ns_basic2::p} {} 1 {invalid command name "p"} ::test_ns_basic2::callP}
+
+test basic-25.1 {TclCleanupCommand} {emptyTest} {
+} {}
+
+test basic-26.1 {Tcl_EvalObj: preserve object while evaling it} -setup {
+ proc myHandler {msg options} {
+ set ::x [dict get $options -errorinfo]
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+ set fName [makeFile {} test1]
+} -body {
+ # If object isn't preserved, errorInfo would be set to
+ # "foo\n while executing\n\"garbage bytes\"" because the object's
+ # string would have been freed, leaving garbage bytes for the error
+ # message.
+ set f [open $fName w]
+ fileevent $f writable "fileevent $f writable {}; error foo"
+ set x {}
+ vwait x
+ close $f
+ set x
+} -cleanup {
+ removeFile test1
+ interp bgerror {} $handler
+ rename myHandler {}
+} -result "foo\n while executing\n\"error foo\""
+
+test basic-26.2 {Tcl_EvalObjEx, pure-list branch: preserve "objv"} -body {
+ #
+ # Follow the pure-list branch in a manner that
+ # a - the pure-list internal rep is destroyed by shimmering
+ # b - the command returns an error
+ # As the error code in Tcl_EvalObjv accesses the list elements, this will
+ # cause a segfault if [Bug 1119369] has not been fixed.
+ # NOTE: a MEM_DEBUG build may be necessary to guarantee the segfault.
+ #
+
+ set SRC [list foo 1] ;# pure-list command
+ proc foo str {
+ # Shimmer pure-list to cmdName, cleanup and error
+ proc $::SRC {} {}; $::SRC
+ error "BAD CALL"
+ }
+ catch {eval $SRC}
+} -result 1 -cleanup {
+ rename foo {}
+ rename $::SRC {}
+ unset ::SRC
+}
+
+test basic-26.3 {Tcl_EvalObjEx, pure-list branch: preserve "objv"} -body {
+ #
+ # Follow the pure-list branch in a manner that
+ # a - the pure-list internal rep is destroyed by shimmering
+ # b - the command accesses its command line
+ # This will cause a segfault if [Bug 1119369] has not been fixed.
+ # NOTE: a MEM_DEBUG build may be necessary to guarantee the segfault.
+ #
+
+ set SRC [list foo 1] ;# pure-list command
+ proc foo str {
+ # Shimmer pure-list to cmdName, cleanup and error
+ proc $::SRC {} {}; $::SRC
+ info level 0
+ }
+ catch {eval $SRC}
+} -result 0 -cleanup {
+ rename foo {}
+ rename $::SRC {}
+ unset ::SRC
+}
+
+test basic-27.1 {Tcl_ExprLong} {emptyTest} {
+} {}
+
+test basic-28.1 {Tcl_ExprDouble} {emptyTest} {
+} {}
+
+test basic-29.1 {Tcl_ExprBoolean} {emptyTest} {
+} {}
+
+test basic-30.1 {Tcl_ExprLongObj} {emptyTest} {
+} {}
+
+test basic-31.1 {Tcl_ExprDoubleObj} {emptyTest} {
+} {}
+
+test basic-32.1 {Tcl_ExprBooleanObj} {emptyTest} {
+} {}
+
+test basic-36.1 {Tcl_EvalObjv, lookup of "unknown" command} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {interp delete test_interp}
+ interp create test_interp
+ interp eval test_interp {
+ proc unknown {args} {
+ return "global unknown"
+ }
+ namespace eval test_ns_basic {
+ proc unknown {args} {
+ return "namespace unknown"
+ }
+ }
+ }
+ list [interp alias test_interp newAlias test_interp doesntExist] \
+ [catch {interp eval test_interp {newAlias}} msg] $msg \
+ [interp delete test_interp]
+} {newAlias 0 {global unknown} {}}
+
+test basic-37.1 {Tcl_ExprString: see expr.test} {emptyTest} {
+} {}
+
+test basic-38.1 {Tcl_ExprObj} {emptyTest} {
+} {}
+
+# Tests basic-39.* and basic-40.* refactored into trace.test
+
+test basic-41.1 {Tcl_AddErrorInfo} {emptyTest} {
+} {}
+
+test basic-42.1 {Tcl_AddObjErrorInfo} {emptyTest} {
+} {}
+
+test basic-43.1 {Tcl_VarEval} {emptyTest} {
+} {}
+
+test basic-44.1 {Tcl_GlobalEval} {emptyTest} {
+} {}
+
+test basic-45.1 {Tcl_SetRecursionLimit: see interp.test} {emptyTest} {
+} {}
+
+test basic-46.1 {Tcl_AllowExceptions: exception return not allowed} {stdio} {
+ catch {close $f}
+ set res [catch {
+ set f [open |[list [interpreter]] w+]
+ fconfigure $f -buffering line
+ puts $f {fconfigure stdout -buffering line}
+ puts $f continue
+ puts $f {puts $::errorInfo}
+ puts $f {puts DONE}
+ set newMsg {}
+ set msg {}
+ while {$newMsg != "DONE"} {
+ set newMsg [gets $f]
+ append msg "${newMsg}\n"
+ }
+ close $f
+ } error]
+ list $res $msg
+} {1 {invoked "continue" outside of a loop
+ while executing
+"continue"
+DONE
+}}
+
+test basic-46.2 {Tcl_AllowExceptions: exception return not allowed} -setup {
+ set fName [makeFile {
+ puts hello
+ break
+ } BREAKtest]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $fName
+} -cleanup {
+ removeFile BREAKtest
+} -returnCodes error -match glob -result {hello
+invoked "break" outside of a loop
+ while executing
+"break"
+ (file "*BREAKtest" line 3)}
+
+test basic-46.3 {Tcl_AllowExceptions: exception return not allowed} -setup {
+ set fName [makeFile {
+ interp alias {} patch {} info patchlevel
+ patch
+ break
+ } BREAKtest]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $fName
+} -cleanup {
+ removeFile BREAKtest
+} -returnCodes error -match glob -result {invoked "break" outside of a loop
+ while executing
+"break"
+ (file "*BREAKtest" line 4)}
+
+test basic-46.4 {Tcl_AllowExceptions: exception return not allowed} -setup {
+ set fName [makeFile {
+ foo [set a 1] [break]
+ } BREAKtest]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $fName
+} -cleanup {
+ removeFile BREAKtest
+} -returnCodes error -match glob -result {invoked "break" outside of a loop
+ while executing*
+"foo \[set a 1] \[break]"
+ (file "*BREAKtest" line 2)}
+
+test basic-46.5 {Tcl_AllowExceptions: exception return not allowed} -setup {
+ set fName [makeFile {
+ return -code return
+ } BREAKtest]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $fName
+} -cleanup {
+ removeFile BREAKtest
+} -returnCodes error -match glob -result {command returned bad code: 2
+ while executing
+"return -code return"
+ (file "*BREAKtest" line 2)}
+
+test basic-47.1 {Tcl_EvalEx: check for missing close-bracket} -constraints {
+ testevalex
+} -body {
+ testevalex {a[set b [format cd]}
+} -returnCodes error -result {missing close-bracket}
+
+# Some lists for expansion tests to work with
+set l1 [list a {b b} c d]
+set l2 [list e f {g g} h]
+proc l3 {} {
+ list i j k {l l}
+}
+
+# Do all tests once byte compiled and once with direct string evaluation
+for {set noComp 0} {$noComp <= 1} {incr noComp} {
+
+if $noComp {
+ interp alias {} run {} testevalex
+ set constraints testevalex
+} else {
+ interp alias {} run {} if 1
+ set constraints {}
+}
+
+test basic-47.2.$noComp {Tcl_EvalEx: error during word expansion} -body {
+ run {{*}\{}
+} -constraints $constraints -returnCodes error -result {unmatched open brace in list}
+
+test basic-47.3.$noComp {Tcl_EvalEx, error during substitution} -body {
+ run {{*}[error foo]}
+} -constraints $constraints -returnCodes error -result foo
+
+test basic-47.4.$noComp {Tcl_EvalEx: no expansion} $constraints {
+ run {list {*} {*} {*}}
+} {* * *}
+
+test basic-47.5.$noComp {Tcl_EvalEx: expansion} $constraints {
+ run {list {*}{} {*} {*}x {*}"y z"}
+} {* x y z}
+
+test basic-47.6.$noComp {Tcl_EvalEx: expansion to zero args} $constraints {
+ run {list {*}{}}
+} {}
+
+test basic-47.7.$noComp {Tcl_EvalEx: expansion to one arg} $constraints {
+ run {list {*}x}
+} x
+
+test basic-47.8.$noComp {Tcl_EvalEx: expansion to many args} $constraints {
+ run {list {*}"y z"}
+} {y z}
+
+test basic-47.9.$noComp {Tcl_EvalEx: expansion and subst order} $constraints {
+ set x 0
+ run {list [incr x] {*}[incr x] [incr x] \
+ {*}[list [incr x] [incr x]] [incr x]}
+} {1 2 3 4 5 6}
+
+test basic-47.10.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+ run {concat {*}{} a b c d e f g h i j k l m n o p q r}
+} {a b c d e f g h i j k l m n o p q r}
+
+test basic-47.11.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+ run {concat {*}1 a b c d e f g h i j k l m n o p q r}
+} {1 a b c d e f g h i j k l m n o p q r}
+
+test basic-47.12.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+ run {concat {*}{1 2} a b c d e f g h i j k l m n o p q r}
+} {1 2 a b c d e f g h i j k l m n o p q r}
+
+test basic-47.13.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+ run {concat {*}{} {*}{1 2} a b c d e f g h i j k l m n o p q}
+} {1 2 a b c d e f g h i j k l m n o p q}
+
+test basic-47.14.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+ run {concat {*}{} a b c d e f g h i j k l m n o p q r s}
+} {a b c d e f g h i j k l m n o p q r s}
+
+test basic-47.15.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+ run {concat {*}1 a b c d e f g h i j k l m n o p q r s}
+} {1 a b c d e f g h i j k l m n o p q r s}
+
+test basic-47.16.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+ run {concat {*}{1 2} a b c d e f g h i j k l m n o p q r s}
+} {1 2 a b c d e f g h i j k l m n o p q r s}
+
+test basic-47.17.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+ run {concat {*}{} {*}{1 2} a b c d e f g h i j k l m n o p q r}
+} {1 2 a b c d e f g h i j k l m n o p q r}
+
+test basic-48.1.$noComp {expansion: parsing} $constraints {
+ run { # A comment
+
+ # Another comment
+ list 1 2\
+ 3 {*}$::l1
+
+ # Comment again
+ }
+} {1 2 3 a {b b} c d}
+
+test basic-48.2.$noComp {no expansion} $constraints {
+ run {list $::l1 $::l2 [l3]}
+} {{a {b b} c d} {e f {g g} h} {i j k {l l}}}
+
+test basic-48.3.$noComp {expansion} $constraints {
+ run {list {*}$::l1 $::l2 {*}[l3]}
+} {a {b b} c d {e f {g g} h} i j k {l l}}
+
+test basic-48.4.$noComp {expansion: really long cmd} $constraints {
+ set cmd [list list]
+ for {set t 0} {$t < 500} {incr t} {
+ lappend cmd {{*}$::l1}
+ }
+ llength [run [join $cmd]]
+} 2000
+
+test basic-48.5.$noComp {expansion: error detection} -setup {
+ set l "a {a b}x y"
+} -constraints $constraints -body {
+ run {list $::l1 {*}$l}
+} -cleanup {
+ unset l
+} -returnCodes 1 -result {list element in braces followed by "x" instead of space}
+
+test basic-48.6.$noComp {expansion: odd usage} $constraints {
+ run {list {*}$::l1$::l2}
+} {a {b b} c de f {g g} h}
+
+test basic-48.7.$noComp {expansion: odd usage} -constraints $constraints -body {
+ run {list {*}[l3]$::l1}
+} -returnCodes 1 -result {list element in braces followed by "a" instead of space}
+
+test basic-48.8.$noComp {expansion: odd usage} $constraints {
+ run {list {*}hej$::l1}
+} {heja {b b} c d}
+
+test basic-48.9.$noComp {expansion: Not all {*} should trigger} $constraints {
+ run {list {*}$::l1 \{*\}$::l2 "{*}$::l1" {{*} i j k}}
+} {a {b b} c d {{*}e f {g g} h} {{*}a {b b} c d} {{*} i j k}}
+
+test basic-48.10.$noComp {expansion: expansion of command word} -setup {
+ set cmd [list string range jultomte]
+} -constraints $constraints -body {
+ run {{*}$cmd 2 6}
+} -cleanup {
+ unset cmd
+} -result ltomt
+
+test basic-48.11.$noComp {expansion: expansion into nothing} -setup {
+ set cmd {}
+ set bar {}
+} -constraints $constraints -body {
+ run {{*}$cmd {*}$bar}
+} -cleanup {
+ unset cmd bar
+} -result {}
+
+test basic-48.12.$noComp {expansion: odd usage} $constraints {
+ run {list {*}$::l1 {*}"hej hopp" {*}$::l2}
+} {a {b b} c d hej hopp e f {g g} h}
+
+test basic-48.13.$noComp {expansion: odd usage} $constraints {
+ run {list {*}$::l1 {*}{hej hopp} {*}$::l2}
+} {a {b b} c d hej hopp e f {g g} h}
+
+test basic-48.14.$noComp {expansion: hash command} -setup {
+ catch {rename \# ""}
+ set cmd "#"
+ } -constraints $constraints -body {
+ run { {*}$cmd apa bepa }
+ } -cleanup {
+ unset cmd
+} -returnCodes 1 -result {invalid command name "#"}
+
+test basic-48.15.$noComp {expansion: complex words} -setup {
+ set a(x) [list a {b c} d e]
+ set b x
+ set c [list {f\ g h\ i j k} x y]
+ set d {0\ 1 2 3}
+ } -constraints $constraints -body {
+ run { lappend d {*}$a($b) {*}[lindex $c 0] }
+ } -cleanup {
+ unset a b c d
+} -result {{0 1} 2 3 a {b c} d e {f g} {h i} j k}
+
+testConstraint memory [llength [info commands memory]]
+test basic-48.16.$noComp {expansion: testing for leaks} -setup {
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex [lindex $lines 3] 3
+ }
+ # This test is made to stress the allocation, reallocation and
+ # object reference management in Tcl_EvalEx.
+ proc stress {} {
+ set a x
+ # Create free objects that should disappear
+ set l [list 1$a 2$a 3$a 4$a 5$a 6$a 7$a]
+ # A short number of words and a short result (8)
+ set l [run {list {*}$l $a$a}]
+ # A short number of words and a longer result (27)
+ set l [run {list {*}$l $a$a {*}$l $a$a {*}$l $a$a}]
+ # A short number of words and a longer result, with an error
+ # This is to stress the cleanup in the error case
+ if {![catch {run {_moo_ {*}$l $a$a {*}$l $a$a {*}$l}}]} {
+ error "An error was expected in the previous statement"
+ }
+ # Many words
+ set l [run {list {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a {*}$l $a$a \
+ {*}$l $a$a}]
+
+ if {[llength $l] != 19*28} {
+ error "Bad Length: [llength $l] should be [expr {19*28}]"
+ }
+ }
+ } -constraints [linsert $constraints 0 memory] -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ stress
+ set tmp $end
+ set end [getbytes]
+ }
+ set leak [expr {$end - $tmp}]
+ } -cleanup {
+ unset end i tmp
+ rename getbytes {}
+ rename stress {}
+} -result 0
+
+test basic-48.17.$noComp {expansion: object safety} -setup {
+ set old_precision $::tcl_precision
+ set ::tcl_precision 4
+ } -constraints $constraints -body {
+ set third [expr {1.0/3.0}]
+ set l [list $third $third]
+ set x [run {list $third {*}$l $third}]
+ set res [list]
+ foreach t $x {
+ lappend res [expr {$t * 3.0}]
+ }
+ set res
+ } -cleanup {
+ set ::tcl_precision $old_precision
+ unset old_precision res t l x third
+} -result {1.0 1.0 1.0 1.0}
+
+test basic-48.18.$noComp {expansion: list semantics} -constraints $constraints -body {
+ set badcmd {
+ list a b
+ set apa 10
+ }
+ set apa 0
+ list [llength [run { {*}$badcmd }]] $apa
+ } -cleanup {
+ unset apa badcmd
+} -result {5 0}
+
+test basic-48.19.$noComp {expansion: error checking order} -body {
+ set badlist "a {}x y"
+ set a 0
+ set b 0
+ catch {run {list [incr a] {*}$badlist [incr b]}}
+ list $a $b
+ } -constraints $constraints -cleanup {
+ unset badlist a b
+} -result {1 0}
+
+test basic-48.20.$noComp {expansion: odd case with word boundaries} $constraints {
+ run {list {*}$::l1 {*}"hej hopp" {*}$::l2}
+} {a {b b} c d hej hopp e f {g g} h}
+
+test basic-48.21.$noComp {expansion: odd case with word boundaries} $constraints {
+ run {list {*}$::l1 {*}{hej hopp} {*}$::l2}
+} {a {b b} c d hej hopp e f {g g} h}
+
+test basic-48.22.$noComp {expansion: odd case with word boundaries} -body {
+ run {list {*}$::l1 {*}"hej hopp {*}$::l2}
+} -constraints $constraints -returnCodes error -result {missing "}
+
+test basic-48.23.$noComp {expansion: handle return codes} -constraints $constraints -body {
+ set res {}
+ for {set t 0} {$t < 10} {incr t} {
+ run { {*}break }
+ }
+ lappend res $t
+
+ for {set t 0} {$t < 10} {incr t} {
+ run { {*}continue }
+ set t 20
+ }
+ lappend res $t
+
+ lappend res [catch { run { {*}{error Hejsan} } } err]
+ lappend res $err
+ } -cleanup {
+ unset res t
+} -result {0 10 1 Hejsan}
+
+} ;# End of noComp loop
+
+test basic-49.1 {Tcl_EvalEx: verify TCL_EVAL_GLOBAL operation} testevalex {
+ set ::x global
+ namespace eval ns {
+ variable x namespace
+ testevalex {set x changed} global
+ set ::result [list $::x $x]
+ }
+ namespace delete ns
+ set ::result
+} {changed namespace}
+test basic-49.2 {Tcl_EvalEx: verify TCL_EVAL_GLOBAL operation} testevalex {
+ set ::x global
+ namespace eval ns {
+ variable x namespace
+ testevalex {set ::context $x} global
+ }
+ namespace delete ns
+ set ::context
+} {global}
+
+# Clean up after expand tests
+unset noComp l1 l2 constraints
+rename l3 {}
+rename run {}
+
+ #cleanup
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+catch {namespace delete george}
+catch {interp delete test_interp}
+catch {rename p ""}
+catch {rename q ""}
+catch {rename cmd ""}
+catch {rename value:at: ""}
+catch {unset x}
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/binary.test b/pkgs/msgcat/tests/binary.test
new file mode 100644
index 0000000..6c00508
--- /dev/null
+++ b/pkgs/msgcat/tests/binary.test
@@ -0,0 +1,2781 @@
+# This file tests the tclBinary.c file and the "binary" Tcl command.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+testConstraint bigEndian [expr {$tcl_platform(byteOrder) eq "bigEndian"}]
+testConstraint littleEndian [expr {$tcl_platform(byteOrder) eq "littleEndian"}]
+
+# Big test for correct ordering of data in [expr]
+proc testIEEE {} {
+ variable ieeeValues
+ binary scan [binary format dd -1.0 1.0] c* c
+ switch -exact -- $c {
+ {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+ # little endian
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+ ieeeValues(-Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+ ieeeValues(-Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+ ieeeValues(-Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+ ieeeValues(+Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+ ieeeValues(+Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 1
+ return 1
+ }
+ {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+ binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Infinity)
+ binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Normal)
+ binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Subnormal)
+ binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Normal)
+ binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Infinity)
+ binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 0
+ return 1
+ }
+ default {
+ return 0
+ }
+ }
+}
+
+testConstraint ieeeFloatingPoint [testIEEE]
+
+# ----------------------------------------------------------------------
+
+test binary-0.1 {DupByteArrayInternalRep} {
+ set hdr [binary format cc 0 0316]
+ set buf hellomatt
+ set data $hdr
+ append data $buf
+ string length $data
+} 11
+
+test binary-1.1 {Tcl_BinaryObjCmd: bad args} -body {
+ binary
+} -returnCodes error -match glob -result {wrong # args: *}
+test binary-1.2 {Tcl_BinaryObjCmd: bad args} -returnCodes error -body {
+ binary foo
+} -match glob -result {unknown or ambiguous subcommand "foo": *}
+test binary-1.3 {Tcl_BinaryObjCmd: format error} -returnCodes error -body {
+ binary f
+} -result {wrong # args: should be "binary format formatString ?arg ...?"}
+test binary-1.4 {Tcl_BinaryObjCmd: format} -body {
+ binary format ""
+} -result {}
+
+test binary-2.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format a
+} -result {not enough arguments for all format specifiers}
+test binary-2.2 {Tcl_BinaryObjCmd: format} {
+ binary format a0 foo
+} {}
+test binary-2.3 {Tcl_BinaryObjCmd: format} {
+ binary format a f
+} {f}
+test binary-2.4 {Tcl_BinaryObjCmd: format} {
+ binary format a foo
+} {f}
+test binary-2.5 {Tcl_BinaryObjCmd: format} {
+ binary format a3 foo
+} {foo}
+test binary-2.6 {Tcl_BinaryObjCmd: format} {
+ binary format a5 foo
+} foo\x00\x00
+test binary-2.7 {Tcl_BinaryObjCmd: format} {
+ binary format a*a3 foobarbaz blat
+} foobarbazbla
+test binary-2.8 {Tcl_BinaryObjCmd: format} {
+ binary format a*X3a2 foobar x
+} foox\x00r
+
+test binary-3.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format A
+} -result {not enough arguments for all format specifiers}
+test binary-3.2 {Tcl_BinaryObjCmd: format} {
+ binary format A0 f
+} {}
+test binary-3.3 {Tcl_BinaryObjCmd: format} {
+ binary format A f
+} {f}
+test binary-3.4 {Tcl_BinaryObjCmd: format} {
+ binary format A foo
+} {f}
+test binary-3.5 {Tcl_BinaryObjCmd: format} {
+ binary format A3 foo
+} {foo}
+test binary-3.6 {Tcl_BinaryObjCmd: format} {
+ binary format A5 foo
+} {foo }
+test binary-3.7 {Tcl_BinaryObjCmd: format} {
+ binary format A*A3 foobarbaz blat
+} foobarbazbla
+test binary-3.8 {Tcl_BinaryObjCmd: format} {
+ binary format A*X3A2 foobar x
+} {foox r}
+
+test binary-4.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format B
+} -result {not enough arguments for all format specifiers}
+test binary-4.2 {Tcl_BinaryObjCmd: format} {
+ binary format B0 1
+} {}
+test binary-4.3 {Tcl_BinaryObjCmd: format} {
+ binary format B 1
+} \x80
+test binary-4.4 {Tcl_BinaryObjCmd: format} {
+ binary format B* 010011
+} \x4c
+test binary-4.5 {Tcl_BinaryObjCmd: format} {
+ binary format B8 01001101
+} \x4d
+test binary-4.6 {Tcl_BinaryObjCmd: format} {
+ binary format A2X2B9 oo 01001101
+} \x4d\x00
+test binary-4.7 {Tcl_BinaryObjCmd: format} {
+ binary format B9 010011011010
+} \x4d\x80
+test binary-4.8 {Tcl_BinaryObjCmd: format} {
+ binary format B2B3 10 010
+} \x80\x40
+test binary-4.9 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format B1B5 1 foo
+} -result {expected binary string but got "foo" instead}
+
+test binary-5.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format b
+} -result {not enough arguments for all format specifiers}
+test binary-5.2 {Tcl_BinaryObjCmd: format} {
+ binary format b0 1
+} {}
+test binary-5.3 {Tcl_BinaryObjCmd: format} {
+ binary format b 1
+} \x01
+test binary-5.4 {Tcl_BinaryObjCmd: format} {
+ binary format b* 010011
+} 2
+test binary-5.5 {Tcl_BinaryObjCmd: format} {
+ binary format b8 01001101
+} \xb2
+test binary-5.6 {Tcl_BinaryObjCmd: format} {
+ binary format A2X2b9 oo 01001101
+} \xb2\x00
+test binary-5.7 {Tcl_BinaryObjCmd: format} {
+ binary format b9 010011011010
+} \xb2\x01
+test binary-5.8 {Tcl_BinaryObjCmd: format} {
+ binary format b17 1
+} \x01\00\00
+test binary-5.9 {Tcl_BinaryObjCmd: format} {
+ binary format b2b3 10 010
+} \x01\x02
+test binary-5.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format b1b5 1 foo
+} -result {expected binary string but got "foo" instead}
+
+test binary-6.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format h
+} -result {not enough arguments for all format specifiers}
+test binary-6.2 {Tcl_BinaryObjCmd: format} {
+ binary format h0 1
+} {}
+test binary-6.3 {Tcl_BinaryObjCmd: format} {
+ binary format h 1
+} \x01
+test binary-6.4 {Tcl_BinaryObjCmd: format} {
+ binary format h c
+} \x0c
+test binary-6.5 {Tcl_BinaryObjCmd: format} {
+ binary format h* baadf00d
+} \xab\xda\x0f\xd0
+test binary-6.6 {Tcl_BinaryObjCmd: format} {
+ binary format h4 c410
+} \x4c\x01
+test binary-6.7 {Tcl_BinaryObjCmd: format} {
+ binary format h6 c4102
+} \x4c\x01\x02
+test binary-6.8 {Tcl_BinaryObjCmd: format} {
+ binary format h5 c41020304
+} \x4c\x01\x02
+test binary-6.9 {Tcl_BinaryObjCmd: format} {
+ binary format a3X3h5 foo 2
+} \x02\x00\x00
+test binary-6.10 {Tcl_BinaryObjCmd: format} {
+ binary format h2h3 23 456
+} \x32\x54\x06
+test binary-6.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format h2 foo
+} -result {expected hexadecimal string but got "foo" instead}
+
+test binary-7.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format H
+} -result {not enough arguments for all format specifiers}
+test binary-7.2 {Tcl_BinaryObjCmd: format} {
+ binary format H0 1
+} {}
+test binary-7.3 {Tcl_BinaryObjCmd: format} {
+ binary format H 1
+} \x10
+test binary-7.4 {Tcl_BinaryObjCmd: format} {
+ binary format H c
+} \xc0
+test binary-7.5 {Tcl_BinaryObjCmd: format} {
+ binary format H* baadf00d
+} \xba\xad\xf0\x0d
+test binary-7.6 {Tcl_BinaryObjCmd: format} {
+ binary format H4 c410
+} \xc4\x10
+test binary-7.7 {Tcl_BinaryObjCmd: format} {
+ binary format H6 c4102
+} \xc4\x10\x20
+test binary-7.8 {Tcl_BinaryObjCmd: format} {
+ binary format H5 c41023304
+} \xc4\x10\x20
+test binary-7.9 {Tcl_BinaryObjCmd: format} {
+ binary format a3X3H5 foo 2
+} \x20\x00\x00
+test binary-7.10 {Tcl_BinaryObjCmd: format} {
+ binary format H2H3 23 456
+} \x23\x45\x60
+test binary-7.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format H2 foo
+} -result {expected hexadecimal string but got "foo" instead}
+
+test binary-8.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format c
+} -result {not enough arguments for all format specifiers}
+test binary-8.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format c blat
+} -result {expected integer but got "blat"}
+test binary-8.3 {Tcl_BinaryObjCmd: format} {
+ binary format c0 0x50
+} {}
+test binary-8.4 {Tcl_BinaryObjCmd: format} {
+ binary format c 0x50
+} P
+test binary-8.5 {Tcl_BinaryObjCmd: format} {
+ binary format c 0x5052
+} R
+test binary-8.6 {Tcl_BinaryObjCmd: format} {
+ binary format c2 {0x50 0x52}
+} PR
+test binary-8.7 {Tcl_BinaryObjCmd: format} {
+ binary format c2 {0x50 0x52 0x53}
+} PR
+test binary-8.8 {Tcl_BinaryObjCmd: format} {
+ binary format c* {0x50 0x52}
+} PR
+test binary-8.9 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format c2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-8.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {0x50 0x51}
+ binary format c $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-8.11 {Tcl_BinaryObjCmd: format} {
+ set a {0x50 0x51}
+ binary format c1 $a
+} P
+
+test binary-9.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format s
+} -result {not enough arguments for all format specifiers}
+test binary-9.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format s blat
+} -result {expected integer but got "blat"}
+test binary-9.3 {Tcl_BinaryObjCmd: format} {
+ binary format s0 0x50
+} {}
+test binary-9.4 {Tcl_BinaryObjCmd: format} {
+ binary format s 0x50
+} P\x00
+test binary-9.5 {Tcl_BinaryObjCmd: format} {
+ binary format s 0x5052
+} RP
+test binary-9.6 {Tcl_BinaryObjCmd: format} {
+ binary format s 0x505251 0x53
+} QR
+test binary-9.7 {Tcl_BinaryObjCmd: format} {
+ binary format s2 {0x50 0x52}
+} P\x00R\x00
+test binary-9.8 {Tcl_BinaryObjCmd: format} {
+ binary format s* {0x5051 0x52}
+} QPR\x00
+test binary-9.9 {Tcl_BinaryObjCmd: format} {
+ binary format s2 {0x50 0x52 0x53} 0x54
+} P\x00R\x00
+test binary-9.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format s2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-9.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {0x50 0x51}
+ binary format s $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-9.12 {Tcl_BinaryObjCmd: format} {
+ set a {0x50 0x51}
+ binary format s1 $a
+} P\x00
+
+test binary-10.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format S
+} -result {not enough arguments for all format specifiers}
+test binary-10.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format S blat
+} -result {expected integer but got "blat"}
+test binary-10.3 {Tcl_BinaryObjCmd: format} {
+ binary format S0 0x50
+} {}
+test binary-10.4 {Tcl_BinaryObjCmd: format} {
+ binary format S 0x50
+} \x00P
+test binary-10.5 {Tcl_BinaryObjCmd: format} {
+ binary format S 0x5052
+} PR
+test binary-10.6 {Tcl_BinaryObjCmd: format} {
+ binary format S 0x505251 0x53
+} RQ
+test binary-10.7 {Tcl_BinaryObjCmd: format} {
+ binary format S2 {0x50 0x52}
+} \x00P\x00R
+test binary-10.8 {Tcl_BinaryObjCmd: format} {
+ binary format S* {0x5051 0x52}
+} PQ\x00R
+test binary-10.9 {Tcl_BinaryObjCmd: format} {
+ binary format S2 {0x50 0x52 0x53} 0x54
+} \x00P\x00R
+test binary-10.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format S2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-10.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {0x50 0x51}
+ binary format S $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-10.12 {Tcl_BinaryObjCmd: format} {
+ set a {0x50 0x51}
+ binary format S1 $a
+} \x00P
+
+test binary-11.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format i
+} -result {not enough arguments for all format specifiers}
+test binary-11.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format i blat
+} -result {expected integer but got "blat"}
+test binary-11.3 {Tcl_BinaryObjCmd: format} {
+ binary format i0 0x50
+} {}
+test binary-11.4 {Tcl_BinaryObjCmd: format} {
+ binary format i 0x50
+} P\x00\x00\x00
+test binary-11.5 {Tcl_BinaryObjCmd: format} {
+ binary format i 0x5052
+} RP\x00\x00
+test binary-11.6 {Tcl_BinaryObjCmd: format} {
+ binary format i 0x505251 0x53
+} QRP\x00
+test binary-11.7 {Tcl_BinaryObjCmd: format} {
+ binary format i1 {0x505251 0x53}
+} QRP\x00
+test binary-11.8 {Tcl_BinaryObjCmd: format} {
+ binary format i 0x53525150
+} PQRS
+test binary-11.9 {Tcl_BinaryObjCmd: format} {
+ binary format i2 {0x50 0x52}
+} P\x00\x00\x00R\x00\x00\x00
+test binary-11.10 {Tcl_BinaryObjCmd: format} {
+ binary format i* {0x50515253 0x52}
+} SRQPR\x00\x00\x00
+test binary-11.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format i2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-11.12 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {0x50 0x51}
+ binary format i $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-11.13 {Tcl_BinaryObjCmd: format} {
+ set a {0x50 0x51}
+ binary format i1 $a
+} P\x00\x00\x00
+
+test binary-12.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format I
+} -result {not enough arguments for all format specifiers}
+test binary-12.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format I blat
+} -result {expected integer but got "blat"}
+test binary-12.3 {Tcl_BinaryObjCmd: format} {
+ binary format I0 0x50
+} {}
+test binary-12.4 {Tcl_BinaryObjCmd: format} {
+ binary format I 0x50
+} \x00\x00\x00P
+test binary-12.5 {Tcl_BinaryObjCmd: format} {
+ binary format I 0x5052
+} \x00\x00PR
+test binary-12.6 {Tcl_BinaryObjCmd: format} {
+ binary format I 0x505251 0x53
+} \x00PRQ
+test binary-12.7 {Tcl_BinaryObjCmd: format} {
+ binary format I1 {0x505251 0x53}
+} \x00PRQ
+test binary-12.8 {Tcl_BinaryObjCmd: format} {
+ binary format I 0x53525150
+} SRQP
+test binary-12.9 {Tcl_BinaryObjCmd: format} {
+ binary format I2 {0x50 0x52}
+} \x00\x00\x00P\x00\x00\x00R
+test binary-12.10 {Tcl_BinaryObjCmd: format} {
+ binary format I* {0x50515253 0x52}
+} PQRS\x00\x00\x00R
+test binary-12.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format i2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-12.12 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {0x50 0x51}
+ binary format I $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-12.13 {Tcl_BinaryObjCmd: format} {
+ set a {0x50 0x51}
+ binary format I1 $a
+} \x00\x00\x00P
+
+test binary-13.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format f
+} -result {not enough arguments for all format specifiers}
+test binary-13.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format f blat
+} -result {expected floating-point number but got "blat"}
+test binary-13.3 {Tcl_BinaryObjCmd: format} {
+ binary format f0 1.6
+} {}
+test binary-13.4 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format f 1.6
+} \x3f\xcc\xcc\xcd
+test binary-13.5 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format f 1.6
+} \xcd\xcc\xcc\x3f
+test binary-13.6 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format f* {1.6 3.4}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-13.7 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format f* {1.6 3.4}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-13.8 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format f2 {1.6 3.4}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-13.9 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format f2 {1.6 3.4}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-13.10 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format f2 {1.6 3.4 5.6}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-13.11 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format f2 {1.6 3.4 5.6}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-13.12 {Tcl_BinaryObjCmd: float overflow} bigEndian {
+ binary format f -3.402825e+38
+} \xff\x7f\xff\xff
+test binary-13.13 {Tcl_BinaryObjCmd: float overflow} littleEndian {
+ binary format f -3.402825e+38
+} \xff\xff\x7f\xff
+test binary-13.14 {Tcl_BinaryObjCmd: float underflow} bigEndian {
+ binary format f -3.402825e-100
+} \x80\x00\x00\x00
+test binary-13.15 {Tcl_BinaryObjCmd: float underflow} littleEndian {
+ binary format f -3.402825e-100
+} \x00\x00\x00\x80
+test binary-13.16 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format f2 {1.6}
+} -result {number of elements in list does not match count}
+test binary-13.17 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {1.6 3.4}
+ binary format f $a
+} -result "expected floating-point number but got \"1.6 3.4\""
+test binary-13.18 {Tcl_BinaryObjCmd: format} bigEndian {
+ set a {1.6 3.4}
+ binary format f1 $a
+} \x3f\xcc\xcc\xcd
+test binary-13.19 {Tcl_BinaryObjCmd: format} littleEndian {
+ set a {1.6 3.4}
+ binary format f1 $a
+} \xcd\xcc\xcc\x3f
+
+test binary-14.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format d
+} -result {not enough arguments for all format specifiers}
+test binary-14.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format d blat
+} -result {expected floating-point number but got "blat"}
+test binary-14.3 {Tcl_BinaryObjCmd: format} {
+ binary format d0 1.6
+} {}
+test binary-14.4 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format d 1.6
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a
+test binary-14.5 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format d 1.6
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f
+test binary-14.6 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format d* {1.6 3.4}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-14.7 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format d* {1.6 3.4}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-14.8 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format d2 {1.6 3.4}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-14.9 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format d2 {1.6 3.4}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-14.10 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format d2 {1.6 3.4 5.6}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-14.11 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format d2 {1.6 3.4 5.6}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-14.14 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format d2 {1.6}
+} -result {number of elements in list does not match count}
+test binary-14.15 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {1.6 3.4}
+ binary format d $a
+} -result "expected floating-point number but got \"1.6 3.4\""
+test binary-14.16 {Tcl_BinaryObjCmd: format} bigEndian {
+ set a {1.6 3.4}
+ binary format d1 $a
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a
+test binary-14.17 {Tcl_BinaryObjCmd: format} littleEndian {
+ set a {1.6 3.4}
+ binary format d1 $a
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f
+test binary-14.18 {FormatNumber: Bug 1116542} {
+ binary scan [binary format d 1.25] d w
+ set w
+} 1.25
+
+test binary-15.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format ax*a "y" "z"
+} -result {cannot use "*" in format string with "x"}
+test binary-15.2 {Tcl_BinaryObjCmd: format} {
+ binary format axa "y" "z"
+} y\x00z
+test binary-15.3 {Tcl_BinaryObjCmd: format} {
+ binary format ax3a "y" "z"
+} y\x00\x00\x00z
+test binary-15.4 {Tcl_BinaryObjCmd: format} {
+ binary format a*X3x3a* "foo" "z"
+} \x00\x00\x00z
+test binary-15.5 {Tcl_BinaryObjCmd: format - bug #1923966} {
+ binary format x0s 1
+} \x01\x00
+test binary-15.6 {Tcl_BinaryObjCmd: format - bug #1923966} {
+ binary format x0ss 1 1
+} \x01\x00\x01\x00
+test binary-15.7 {Tcl_BinaryObjCmd: format - bug #1923966} {
+ binary format x1s 1
+} \x00\x01\x00
+test binary-15.8 {Tcl_BinaryObjCmd: format - bug #1923966} {
+ binary format x1ss 1 1
+} \x00\x01\x00\x01\x00
+
+test binary-16.1 {Tcl_BinaryObjCmd: format} {
+ binary format a*X*a "foo" "z"
+} zoo
+test binary-16.2 {Tcl_BinaryObjCmd: format} {
+ binary format aX3a "y" "z"
+} z
+test binary-16.3 {Tcl_BinaryObjCmd: format} {
+ binary format a*Xa* "foo" "zy"
+} fozy
+test binary-16.4 {Tcl_BinaryObjCmd: format} {
+ binary format a*X3a "foobar" "z"
+} foozar
+test binary-16.5 {Tcl_BinaryObjCmd: format} {
+ binary format a*X3aX2a "foobar" "z" "b"
+} fobzar
+
+test binary-17.1 {Tcl_BinaryObjCmd: format} {
+ binary format @1
+} \x00
+test binary-17.2 {Tcl_BinaryObjCmd: format} {
+ binary format @5a2 "ab"
+} \x00\x00\x00\x00\x00\x61\x62
+test binary-17.3 {Tcl_BinaryObjCmd: format} {
+ binary format {a* @0 a2 @* a*} "foobar" "ab" "blat"
+} abobarblat
+
+test binary-18.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format u0a3 abc abd
+} -result {bad field specifier "u"}
+
+test binary-19.1 {Tcl_BinaryObjCmd: errors} -returnCodes error -body {
+ binary s
+} -result {wrong # args: should be "binary scan value formatString ?varName ...?"}
+test binary-19.2 {Tcl_BinaryObjCmd: errors} -returnCodes error -body {
+ binary scan foo
+} -result {wrong # args: should be "binary scan value formatString ?varName ...?"}
+test binary-19.3 {Tcl_BinaryObjCmd: scan} {
+ binary scan {} {}
+} 0
+
+test binary-20.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc a
+} -result {not enough arguments for all format specifiers}
+test binary-20.2 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan abc a arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-20.3 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ set arg1 abc
+ list [binary scan abc a0 arg1] $arg1
+} -result {1 {}}
+test binary-20.4 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc a* arg1] $arg1
+} -result {1 abc}
+test binary-20.5 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc a5 arg1] [info exists arg1]
+} -result {0 0}
+test binary-20.6 {Tcl_BinaryObjCmd: scan} {
+ set arg1 foo
+ list [binary scan abc a2 arg1] $arg1
+} {1 ab}
+test binary-20.7 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+} -body {
+ list [binary scan abcdef a2a2 arg1 arg2] $arg1 $arg2
+} -result {2 ab cd}
+test binary-20.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc a2 arg1(a)] $arg1(a)
+} -result {1 ab}
+test binary-20.9 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc a arg1(a)] $arg1(a)
+} -result {1 a}
+
+test binary-21.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc A
+} -result {not enough arguments for all format specifiers}
+test binary-21.2 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan abc A arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-21.3 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ set arg1 abc
+ list [binary scan abc A0 arg1] $arg1
+} -result {1 {}}
+test binary-21.4 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc A* arg1] $arg1
+} -result {1 abc}
+test binary-21.5 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc A5 arg1] [info exists arg1]
+} -result {0 0}
+test binary-21.6 {Tcl_BinaryObjCmd: scan} {
+ set arg1 foo
+ list [binary scan abc A2 arg1] $arg1
+} {1 ab}
+test binary-21.7 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+} -body {
+ list [binary scan abcdef A2A2 arg1 arg2] $arg1 $arg2
+} -result {2 ab cd}
+test binary-21.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc A2 arg1(a)] $arg1(a)
+} -result {1 ab}
+test binary-21.9 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc A2 arg1(a)] $arg1(a)
+} -result {1 ab}
+test binary-21.10 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan abc A arg1(a)] $arg1(a)
+} -result {1 a}
+test binary-21.11 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan "abc def \x00 " A* arg1] $arg1
+} -result {1 {abc def}}
+test binary-21.12 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -body {
+ list [binary scan "abc def \x00ghi " A* arg1] $arg1
+} -result [list 1 "abc def \x00ghi"]
+
+test binary-22.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc b
+} -result {not enough arguments for all format specifiers}
+test binary-22.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 b* arg1] $arg1
+} {1 0100101011001010}
+test binary-22.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x82\x53 b arg1] $arg1
+} {1 0}
+test binary-22.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x82\x53 b1 arg1] $arg1
+} {1 0}
+test binary-22.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x82\x53 b0 arg1] $arg1
+} {1 {}}
+test binary-22.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 b5 arg1] $arg1
+} {1 01001}
+test binary-22.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 b8 arg1] $arg1
+} {1 01001010}
+test binary-22.8 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 b14 arg1] $arg1
+} {1 01001010110010}
+test binary-22.9 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 b14 arg1] $arg1
+} {0 foo}
+test binary-22.10 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 b1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-22.11 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1 arg2
+} -body {
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x07\x87\x05 b5b* arg1 arg2] $arg1 $arg2
+} -result {2 11100 1110000110100000}
+
+test binary-23.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc B
+} -result {not enough arguments for all format specifiers}
+test binary-23.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 B* arg1] $arg1
+} {1 0101001001010011}
+test binary-23.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x82\x53 B arg1] $arg1
+} {1 1}
+test binary-23.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x82\x53 B1 arg1] $arg1
+} {1 1}
+test binary-23.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 B0 arg1] $arg1
+} {1 {}}
+test binary-23.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 B5 arg1] $arg1
+} {1 01010}
+test binary-23.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 B8 arg1] $arg1
+} {1 01010010}
+test binary-23.8 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 B14 arg1] $arg1
+} {1 01010010010100}
+test binary-23.9 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 B14 arg1] $arg1
+} {0 foo}
+test binary-23.10 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 B1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-23.11 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1 arg2
+} -body {
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x70\x87\x05 B5B* arg1 arg2] $arg1 $arg2
+} -result {2 01110 1000011100000101}
+
+test binary-24.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc h
+} -result {not enough arguments for all format specifiers}
+test binary-24.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 h* arg1] $arg1
+} {1 253a}
+test binary-24.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \xc2\xa3 h arg1] $arg1
+} {1 2}
+test binary-24.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x82\x53 h1 arg1] $arg1
+} {1 2}
+test binary-24.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 h0 arg1] $arg1
+} {1 {}}
+test binary-24.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \xf2\x53 h2 arg1] $arg1
+} {1 2f}
+test binary-24.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 h3 arg1] $arg1
+} {1 253}
+test binary-24.8 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 h3 arg1] $arg1
+} {0 foo}
+test binary-24.9 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 h1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-24.10 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1 arg2
+} -body {
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x70\x87\x05 h2h* arg1 arg2] $arg1 $arg2
+} -result {2 07 7850}
+
+test binary-25.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc H
+} -result {not enough arguments for all format specifiers}
+test binary-25.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 H* arg1] $arg1
+} {1 52a3}
+test binary-25.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \xc2\xa3 H arg1] $arg1
+} {1 c}
+test binary-25.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x82\x53 H1 arg1] $arg1
+} {1 8}
+test binary-25.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 H0 arg1] $arg1
+} {1 {}}
+test binary-25.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \xf2\x53 H2 arg1] $arg1
+} {1 f2}
+test binary-25.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\x53 H3 arg1] $arg1
+} {1 525}
+test binary-25.8 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 H3 arg1] $arg1
+} {0 foo}
+test binary-25.9 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 H1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-25.10 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x70\x87\x05 H2H* arg1 arg2] $arg1 $arg2
+} {2 70 8705}
+
+test binary-26.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc c
+} -result {not enough arguments for all format specifiers}
+test binary-26.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 c* arg1] $arg1
+} {1 {82 -93}}
+test binary-26.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 c arg1] $arg1
+} {1 82}
+test binary-26.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 c1 arg1] $arg1
+} {1 82}
+test binary-26.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 c0 arg1] $arg1
+} {1 {}}
+test binary-26.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 c2 arg1] $arg1
+} {1 {82 -93}}
+test binary-26.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \xff c arg1] $arg1
+} {1 -1}
+test binary-26.8 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 c3 arg1] $arg1
+} {0 foo}
+test binary-26.9 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 c1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-26.10 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x70\x87\x05 c2c* arg1 arg2] $arg1 $arg2
+} {2 {112 -121} 5}
+test binary-26.11 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 cu* arg1] $arg1
+} {1 {82 163}}
+test binary-26.12 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 cu arg1] $arg1
+} {1 82}
+test binary-26.13 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \xff cu arg1] $arg1
+} {1 255}
+test binary-26.14 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x80\x80 cuc arg1 arg2] $arg1 $arg2
+} {2 128 -128}
+test binary-26.15 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x80\x80 ccu arg1 arg2] $arg1 $arg2
+} {2 -128 128}
+
+test binary-27.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc s
+} -result {not enough arguments for all format specifiers}
+test binary-27.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 s* arg1] $arg1
+} {1 {-23726 21587}}
+test binary-27.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 s arg1] $arg1
+} {1 -23726}
+test binary-27.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 s1 arg1] $arg1
+} {1 -23726}
+test binary-27.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 s0 arg1] $arg1
+} {1 {}}
+test binary-27.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 s2 arg1] $arg1
+} {1 {-23726 21587}}
+test binary-27.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 s1 arg1] $arg1
+} {0 foo}
+test binary-27.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 s1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-27.9 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x52\xa3\x53\x54\x05 s2c* arg1 arg2] $arg1 $arg2
+} {2 {-23726 21587} 5}
+test binary-27.10 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 su* arg1] $arg1
+} {1 {41810 21587}}
+test binary-27.11 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \xff\xff\xff\xff sus arg1 arg2] $arg1 $arg2
+} {2 65535 -1}
+test binary-27.12 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \xff\xff\xff\xff ssu arg1 arg2] $arg1 $arg2
+} {2 -1 65535}
+
+test binary-28.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc S
+} -result {not enough arguments for all format specifiers}
+test binary-28.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 S* arg1] $arg1
+} {1 {21155 21332}}
+test binary-28.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 S arg1] $arg1
+} {1 21155}
+test binary-28.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 S1 arg1] $arg1
+} {1 21155}
+test binary-28.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 S0 arg1] $arg1
+} {1 {}}
+test binary-28.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 S2 arg1] $arg1
+} {1 {21155 21332}}
+test binary-28.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 S1 arg1] $arg1
+} {0 foo}
+test binary-28.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 S1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-28.9 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x52\xa3\x53\x54\x05 S2c* arg1 arg2] $arg1 $arg2
+} {2 {21155 21332} 5}
+test binary-28.10 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 Su* arg1] $arg1
+} {1 {21155 21332}}
+test binary-28.11 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \xa3\x52\x54\x53 Su* arg1] $arg1
+} {1 {41810 21587}}
+
+test binary-29.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc i
+} -result {not enough arguments for all format specifiers}
+test binary-29.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 i* arg1] $arg1
+} {1 {1414767442 67305985}}
+test binary-29.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 i arg1] $arg1
+} {1 1414767442}
+test binary-29.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 i1 arg1] $arg1
+} {1 1414767442}
+test binary-29.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53 i0 arg1] $arg1
+} {1 {}}
+test binary-29.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 i2 arg1] $arg1
+} {1 {1414767442 67305985}}
+test binary-29.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 i1 arg1] $arg1
+} {0 foo}
+test binary-29.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53\x53\x54 i1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-29.9 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04\x05 i2c* arg1 arg2] $arg1 $arg2
+} {2 {1414767442 67305985} 5}
+test binary-29.10 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff iui arg1 arg2] $arg1 $arg2
+} {2 4294967295 -1}
+test binary-29.11 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff iiu arg1 arg2] $arg1 $arg2
+} {2 -1 4294967295}
+test binary-29.12 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ list [binary scan \x80\x00\x00\x00\x00\x00\x00\x80 iuiu arg1 arg2] $arg1 $arg2
+} {2 128 2147483648}
+
+test binary-30.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc I
+} -result {not enough arguments for all format specifiers}
+test binary-30.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 I* arg1] $arg1
+} {1 {1386435412 16909060}}
+test binary-30.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 I arg1] $arg1
+} {1 1386435412}
+test binary-30.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 I1 arg1] $arg1
+} {1 1386435412}
+test binary-30.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53 I0 arg1] $arg1
+} {1 {}}
+test binary-30.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 I2 arg1] $arg1
+} {1 {1386435412 16909060}}
+test binary-30.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 I1 arg1] $arg1
+} {0 foo}
+test binary-30.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53\x53\x54 I1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-30.9 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04\x05 I2c* arg1 arg2] $arg1 $arg2
+} {2 {1386435412 16909060} 5}
+test binary-30.10 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff IuI arg1 arg2] $arg1 $arg2
+} {2 4294967295 -1}
+test binary-30.11 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff IIu arg1 arg2] $arg1 $arg2
+} {2 -1 4294967295}
+test binary-30.12 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1 arg2
+ list [binary scan \x80\x00\x00\x00\x00\x00\x00\x80 IuIu arg1 arg2] $arg1 $arg2
+} {2 2147483648 128}
+
+test binary-31.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc f
+} -result {not enough arguments for all format specifiers}
+test binary-31.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a f* arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-31.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 f* arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-31.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a f arg1] $arg1
+} {1 1.600000023841858}
+test binary-31.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 f arg1] $arg1
+} {1 1.600000023841858}
+test binary-31.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd f1 arg1] $arg1
+} {1 1.600000023841858}
+test binary-31.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f f1 arg1] $arg1
+} {1 1.600000023841858}
+test binary-31.8 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd f0 arg1] $arg1
+} {1 {}}
+test binary-31.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f f0 arg1] $arg1
+} {1 {}}
+test binary-31.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a f2 arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-31.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 f2 arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-31.12 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 f1 arg1] $arg1
+} {0 foo}
+test binary-31.13 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x3f\xcc\xcc\xcd f1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-31.14 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a\x05 f2c* arg1 arg2] $arg1 $arg2
+} {2 {1.600000023841858 3.4000000953674316} 5}
+test binary-31.15 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40\x05 f2c* arg1 arg2] $arg1 $arg2
+} {2 {1.600000023841858 3.4000000953674316} 5}
+
+test binary-32.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc d
+} -result {not enough arguments for all format specifiers}
+test binary-32.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 d* arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-32.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 d* arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-32.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 d arg1] $arg1
+} {1 1.6}
+test binary-32.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 d arg1] $arg1
+} {1 1.6}
+test binary-32.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a d1 arg1] $arg1
+} {1 1.6}
+test binary-32.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f d1 arg1] $arg1
+} {1 1.6}
+test binary-32.8 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a d0 arg1] $arg1
+} {1 {}}
+test binary-32.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f d0 arg1] $arg1
+} {1 {}}
+test binary-32.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 d2 arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-32.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 d2 arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-32.12 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 d1 arg1] $arg1
+} {0 foo}
+test binary-32.13 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a d1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-32.14 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33\x05 d2c* arg1 arg2] $arg1 $arg2
+} {2 {1.6 3.4} 5}
+test binary-32.15 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40\x05 d2c* arg1 arg2] $arg1 $arg2
+} {2 {1.6 3.4} 5}
+
+test binary-33.1 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ list [binary scan abcdefg a2xa3 arg1 arg2] $arg1 $arg2
+} {2 ab def}
+test binary-33.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ set arg2 foo
+ list [binary scan abcdefg a3x*a3 arg1 arg2] $arg1 $arg2
+} {1 abc foo}
+test binary-33.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ set arg2 foo
+ list [binary scan abcdefg a3x20a3 arg1 arg2] $arg1 $arg2
+} {1 abc foo}
+test binary-33.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ set arg2 foo
+ list [binary scan abc a3x20a3 arg1 arg2] $arg1 $arg2
+} {1 abc foo}
+test binary-33.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef x1a1 arg1] $arg1
+} {1 b}
+test binary-33.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef x5a1 arg1] $arg1
+} {1 f}
+test binary-33.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef x0a1 arg1] $arg1
+} {1 a}
+
+test binary-34.1 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ list [binary scan abcdefg a2Xa3 arg1 arg2] $arg1 $arg2
+} {2 ab bcd}
+test binary-34.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ set arg2 foo
+ list [binary scan abcdefg a3X*a3 arg1 arg2] $arg1 $arg2
+} {2 abc abc}
+test binary-34.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ set arg2 foo
+ list [binary scan abcdefg a3X20a3 arg1 arg2] $arg1 $arg2
+} {2 abc abc}
+test binary-34.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abc X20a3 arg1] $arg1
+} {1 abc}
+test binary-34.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef x*X1a1 arg1] $arg1
+} {1 f}
+test binary-34.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef x*X5a1 arg1] $arg1
+} {1 b}
+test binary-34.7 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef x3X0a1 arg1] $arg1
+} {1 d}
+
+test binary-35.1 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+} -returnCodes error -body {
+ binary scan abcdefg a2@a3 arg1 arg2
+} -result {missing count for "@" field specifier}
+test binary-35.2 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ set arg2 foo
+ list [binary scan abcdefg a3@*a3 arg1 arg2] $arg1 $arg2
+} {1 abc foo}
+test binary-35.3 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ unset -nocomplain arg2
+ set arg2 foo
+ list [binary scan abcdefg a3@20a3 arg1 arg2] $arg1 $arg2
+} {1 abc foo}
+test binary-35.4 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef @2a3 arg1] $arg1
+} {1 cde}
+test binary-35.5 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef x*@1a1 arg1] $arg1
+} {1 b}
+test binary-35.6 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ list [binary scan abcdef x*@0a1 arg1] $arg1
+} {1 a}
+
+test binary-36.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abcdef u0a3
+} -result {bad field specifier "u"}
+
+# GetFormatSpec is pretty thoroughly tested above, but there are a few cases
+# we should text explicitly
+
+test binary-37.1 {GetFormatSpec: whitespace} {
+ binary format "a3 a5 a3" foo barblat baz
+} foobarblbaz
+test binary-37.2 {GetFormatSpec: whitespace} {
+ binary format " " foo
+} {}
+test binary-37.3 {GetFormatSpec: whitespace} {
+ binary format " a3" foo
+} foo
+test binary-37.4 {GetFormatSpec: whitespace} {
+ binary format "" foo
+} {}
+test binary-37.5 {GetFormatSpec: whitespace} {
+ binary format "" foo
+} {}
+test binary-37.6 {GetFormatSpec: whitespace} {
+ binary format " a3 " foo
+} foo
+test binary-37.7 {GetFormatSpec: numbers} -returnCodes error -body {
+ binary scan abcdef "x-1" foo
+} -result {bad field specifier "-"}
+test binary-37.8 {GetFormatSpec: numbers} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan abcdef "a0x3" arg1] $arg1
+} {1 {}}
+test binary-37.9 {GetFormatSpec: numbers} {
+ # test format of neg numbers
+ # bug report/fix provided by Harald Kirsch
+ set x [binary format f* {1 -1 2 -2 0}]
+ binary scan $x f* bla
+ set bla
+} {1.0 -1.0 2.0 -2.0 0.0}
+
+test binary-38.1 {FormatNumber: word alignment} {
+ set x [binary format c1s1 1 1]
+} \x01\x01\x00
+test binary-38.2 {FormatNumber: word alignment} {
+ set x [binary format c1S1 1 1]
+} \x01\x00\x01
+test binary-38.3 {FormatNumber: word alignment} {
+ set x [binary format c1i1 1 1]
+} \x01\x01\x00\x00\x00
+test binary-38.4 {FormatNumber: word alignment} {
+ set x [binary format c1I1 1 1]
+} \x01\x00\x00\x00\x01
+test binary-38.5 {FormatNumber: word alignment} bigEndian {
+ set x [binary format c1d1 1 1.6]
+} \x01\x3f\xf9\x99\x99\x99\x99\x99\x9a
+test binary-38.6 {FormatNumber: word alignment} littleEndian {
+ set x [binary format c1d1 1 1.6]
+} \x01\x9a\x99\x99\x99\x99\x99\xf9\x3f
+test binary-38.7 {FormatNumber: word alignment} bigEndian {
+ set x [binary format c1f1 1 1.6]
+} \x01\x3f\xcc\xcc\xcd
+test binary-38.8 {FormatNumber: word alignment} littleEndian {
+ set x [binary format c1f1 1 1.6]
+} \x01\xcd\xcc\xcc\x3f
+
+test binary-39.1 {ScanNumber: sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 c2 arg1] $arg1
+} {1 {82 -93}}
+test binary-39.2 {ScanNumber: sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x01\x02\x01\x81\x82\x01\x81\x82 s4 arg1] $arg1
+} {1 {513 -32511 386 -32127}}
+test binary-39.3 {ScanNumber: sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x01\x02\x01\x81\x82\x01\x81\x82 S4 arg1] $arg1
+} {1 {258 385 -32255 -32382}}
+test binary-39.4 {ScanNumber: sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x01\x01\x01\x02\x81\x01\x01\x01\x01\x82\x01\x01\x01\x01\x82\x01\x01\x01\x01\x81 i5 arg1] $arg1
+} {1 {33620225 16843137 16876033 25297153 -2130640639}}
+test binary-39.5 {ScanNumber: sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x01\x01\x01\x02\x81\x01\x01\x01\x01\x82\x01\x01\x01\x01\x82\x01\x01\x01\x01\x81 I5 arg1] $arg1
+} {1 {16843010 -2130640639 25297153 16876033 16843137}}
+test binary-39.6 {ScanNumber: no sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 cu2 arg1] $arg1
+} {1 {82 163}}
+test binary-39.7 {ScanNumber: no sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x01\x02\x01\x81\x82\x01\x81\x82 su4 arg1] $arg1
+} {1 {513 33025 386 33409}}
+test binary-39.8 {ScanNumber: no sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x01\x02\x01\x81\x82\x01\x81\x82 Su4 arg1] $arg1
+} {1 {258 385 33281 33154}}
+test binary-39.9 {ScanNumber: no sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x01\x01\x01\x02\x81\x01\x01\x01\x01\x82\x01\x01\x01\x01\x82\x01\x01\x01\x01\x81 iu5 arg1] $arg1
+} {1 {33620225 16843137 16876033 25297153 2164326657}}
+test binary-39.10 {ScanNumber: no sign extension} {
+ unset -nocomplain arg1
+ list [binary scan \x01\x01\x01\x02\x81\x01\x01\x01\x01\x82\x01\x01\x01\x01\x82\x01\x01\x01\x01\x81 Iu5 arg1] $arg1
+} {1 {16843010 2164326657 25297153 16876033 16843137}}
+
+test binary-40.3 {ScanNumber: NaN} -body {
+ unset -nocomplain arg1
+ list [binary scan \xff\xff\xff\xff f1 arg1] $arg1
+} -match glob -result {1 -NaN*}
+test binary-40.4 {ScanNumber: NaN} -body {
+ unset -nocomplain arg1
+ list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff d arg1] $arg1
+} -match glob -result {1 -NaN*}
+
+test binary-41.1 {ScanNumber: word alignment} {
+ unset -nocomplain arg1; unset arg2
+ list [binary scan \x01\x01\x00 c1s1 arg1 arg2] $arg1 $arg2
+} {2 1 1}
+test binary-41.2 {ScanNumber: word alignment} {
+ unset -nocomplain arg1; unset arg2
+ list [binary scan \x01\x00\x01 c1S1 arg1 arg2] $arg1 $arg2
+} {2 1 1}
+test binary-41.3 {ScanNumber: word alignment} {
+ unset -nocomplain arg1; unset arg2
+ list [binary scan \x01\x01\x00\x00\x00 c1i1 arg1 arg2] $arg1 $arg2
+} {2 1 1}
+test binary-41.4 {ScanNumber: word alignment} {
+ unset -nocomplain arg1; unset arg2
+ list [binary scan \x01\x00\x00\x00\x01 c1I1 arg1 arg2] $arg1 $arg2
+} {2 1 1}
+test binary-41.5 {ScanNumber: word alignment} bigEndian {
+ unset -nocomplain arg1; unset arg2
+ list [binary scan \x01\x3f\xcc\xcc\xcd c1f1 arg1 arg2] $arg1 $arg2
+} {2 1 1.600000023841858}
+test binary-41.6 {ScanNumber: word alignment} littleEndian {
+ unset -nocomplain arg1; unset arg2
+ list [binary scan \x01\xcd\xcc\xcc\x3f c1f1 arg1 arg2] $arg1 $arg2
+} {2 1 1.600000023841858}
+test binary-41.7 {ScanNumber: word alignment} bigEndian {
+ unset -nocomplain arg1; unset arg2
+ list [binary scan \x01\x3f\xf9\x99\x99\x99\x99\x99\x9a c1d1 arg1 arg2] $arg1 $arg2
+} {2 1 1.6}
+test binary-41.8 {ScanNumber: word alignment} littleEndian {
+ unset -nocomplain arg1; unset arg2
+ list [binary scan \x01\x9a\x99\x99\x99\x99\x99\xf9\x3f c1d1 arg1 arg2] $arg1 $arg2
+} {2 1 1.6}
+
+test binary-42.1 {Tcl_BinaryObjCmd: bad arguments} -constraints {} -body {
+ binary ?
+} -returnCodes error -match glob -result {unknown or ambiguous subcommand "?": *}
+
+# Wide int (guaranteed at least 64-bit) handling
+test binary-43.1 {Tcl_BinaryObjCmd: format wide int} {} {
+ binary format w 7810179016327718216
+} HelloTcl
+test binary-43.2 {Tcl_BinaryObjCmd: format wide int} {} {
+ binary format W 7810179016327718216
+} lcTolleH
+
+test binary-44.1 {Tcl_BinaryObjCmd: scan wide int} {} {
+ binary scan HelloTcl W x
+ set x
+} 5216694956358656876
+test binary-44.2 {Tcl_BinaryObjCmd: scan wide int} {} {
+ binary scan lcTolleH w x
+ set x
+} 5216694956358656876
+test binary-44.3 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} {} {
+ binary scan [binary format w [expr {wide(3) << 31}]] w x
+ set x
+} 6442450944
+test binary-44.4 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} {} {
+ binary scan [binary format W [expr {wide(3) << 31}]] W x
+ set x
+} 6442450944
+test binary-43.5 {Tcl_BinaryObjCmd: scan wide int} {} {
+ unset -nocomplain arg1
+ list [binary scan \x80[string repeat \x00 7] W arg1] $arg1
+} {1 -9223372036854775808}
+test binary-43.6 {Tcl_BinaryObjCmd: scan unsigned wide int} {} {
+ unset -nocomplain arg1
+ list [binary scan \x80[string repeat \x00 7] Wu arg1] $arg1
+} {1 9223372036854775808}
+test binary-43.7 {Tcl_BinaryObjCmd: scan unsigned wide int} {} {
+ unset -nocomplain arg1
+ list [binary scan [string repeat \x00 7]\x80 wu arg1] $arg1
+} {1 9223372036854775808}
+test binary-43.8 {Tcl_BinaryObjCmd: scan unsigned wide int} {} {
+ unset -nocomplain arg1 arg2
+ list [binary scan \x80[string repeat \x00 7]\x80[string repeat \x00 7] WuW arg1 arg2] $arg1 $arg2
+} {2 9223372036854775808 -9223372036854775808}
+test binary-43.9 {Tcl_BinaryObjCmd: scan unsigned wide int} {} {
+ unset -nocomplain arg1 arg2
+ list [binary scan [string repeat \x00 7]\x80[string repeat \x00 7]\x80 wuw arg1 arg2] $arg1 $arg2
+} {2 9223372036854775808 -9223372036854775808}
+
+test binary-45.1 {Tcl_BinaryObjCmd: combined wide int handling} {
+ binary scan [binary format sws 16450 -1 19521] c* x
+ set x
+} {66 64 -1 -1 -1 -1 -1 -1 -1 -1 65 76}
+test binary-45.2 {Tcl_BinaryObjCmd: combined wide int handling} {
+ binary scan [binary format sWs 16450 0x7fffffff 19521] c* x
+ set x
+} {66 64 0 0 0 0 127 -1 -1 -1 65 76}
+
+test binary-46.1 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} {
+ binary format a* \u20ac
+} \u00ac
+test binary-46.2 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} {
+ list [binary scan [binary format a* \u20ac\u20bd] s x] $x
+} {1 -16980}
+test binary-46.3 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} {
+ set x {}
+ set y {}
+ set z {}
+ list [binary scan [binary format a* \u20ac\u20bd] aaa x y z] $x $y $z
+} "2 \u00ac \u00bd {}"
+test binary-46.4 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} {
+ set x [encoding convertto iso8859-15 \u20ac]
+ set y [binary format a* $x]
+ list $x $y
+} "\u00a4 \u00a4"
+test binary-46.5 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} {
+ set x [binary scan \u00a4 a* y]
+ list $x $y [encoding convertfrom iso8859-15 $y]
+} "1 \u00a4 \u20ac"
+
+test binary-47.1 {Tcl_BinaryObjCmd: number cache reference count handling} {
+ # This test is only reliable when memory debugging is turned on, but
+ # without even memory debugging it should still generate the expected
+ # answers and might therefore still pick up memory corruption caused by
+ # [Bug 851747].
+ list [binary scan aba ccc x x x] $x
+} {3 97}
+
+### TIP#129: endian specifiers ----
+
+# format t
+test binary-48.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format t
+} -result {not enough arguments for all format specifiers}
+test binary-48.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format t blat
+} -result {expected integer but got "blat"}
+test binary-48.3 {Tcl_BinaryObjCmd: format} {
+ binary format S0 0x50
+} {}
+test binary-48.4 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format t 0x50
+} \x00P
+test binary-48.5 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format t 0x50
+} P\x00
+test binary-48.6 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format t 0x5052
+} PR
+test binary-48.7 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format t 0x5052
+} RP
+test binary-48.8 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format t 0x505251 0x53
+} RQ
+test binary-48.9 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format t 0x505251 0x53
+} QR
+test binary-48.10 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format t2 {0x50 0x52}
+} \x00P\x00R
+test binary-48.11 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format t2 {0x50 0x52}
+} P\x00R\x00
+test binary-48.12 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format t* {0x5051 0x52}
+} PQ\x00R
+test binary-48.13 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format t* {0x5051 0x52}
+} QPR\x00
+test binary-48.14 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format t2 {0x50 0x52 0x53} 0x54
+} \x00P\x00R
+test binary-48.15 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format t2 {0x50 0x52 0x53} 0x54
+} P\x00R\x00
+test binary-48.16 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format t2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-48.17 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {0x50 0x51}
+ binary format t $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-48.18 {Tcl_BinaryObjCmd: format} bigEndian {
+ set a {0x50 0x51}
+ binary format t1 $a
+} \x00P
+test binary-48.19 {Tcl_BinaryObjCmd: format} littleEndian {
+ set a {0x50 0x51}
+ binary format t1 $a
+} P\x00
+
+# format n
+test binary-49.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format n
+} -result {not enough arguments for all format specifiers}
+test binary-49.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format n blat
+} -result {expected integer but got "blat"}
+test binary-49.3 {Tcl_BinaryObjCmd: format} {
+ binary format n0 0x50
+} {}
+test binary-49.4 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format n 0x50
+} P\x00\x00\x00
+test binary-49.5 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format n 0x5052
+} RP\x00\x00
+test binary-49.6 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format n 0x505251 0x53
+} QRP\x00
+test binary-49.7 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format i1 {0x505251 0x53}
+} QRP\x00
+test binary-49.8 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format n 0x53525150
+} PQRS
+test binary-49.9 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format n2 {0x50 0x52}
+} P\x00\x00\x00R\x00\x00\x00
+test binary-49.10 {Tcl_BinaryObjCmd: format} littleEndian {
+ binary format n* {0x50515253 0x52}
+} SRQPR\x00\x00\x00
+test binary-49.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format n2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-49.12 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {0x50 0x51}
+ binary format n $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-49.13 {Tcl_BinaryObjCmd: format} littleEndian {
+ set a {0x50 0x51}
+ binary format n1 $a
+} P\x00\x00\x00
+test binary-49.14 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format n 0x50
+} \x00\x00\x00P
+test binary-49.15 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format n 0x5052
+} \x00\x00PR
+test binary-49.16 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format n 0x505251 0x53
+} \x00PRQ
+test binary-49.17 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format i1 {0x505251 0x53}
+} QRP\x00
+test binary-49.18 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format n 0x53525150
+} SRQP
+test binary-49.19 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format n2 {0x50 0x52}
+} \x00\x00\x00P\x00\x00\x00R
+test binary-49.20 {Tcl_BinaryObjCmd: format} bigEndian {
+ binary format n* {0x50515253 0x52}
+} PQRS\x00\x00\x00R
+
+# format m
+test binary-50.1 {Tcl_BinaryObjCmd: format wide int} littleEndian {
+ binary format m 7810179016327718216
+} HelloTcl
+test binary-50.2 {Tcl_BinaryObjCmd: format wide int} bigEndian {
+ binary format m 7810179016327718216
+} lcTolleH
+test binary-50.3 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} littleEndian {
+ binary scan [binary format m [expr {wide(3) << 31}]] w x
+ set x
+} 6442450944
+test binary-50.4 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} bigEndian {
+ binary scan [binary format m [expr {wide(3) << 31}]] W x
+ set x
+} 6442450944
+
+# format Q/q
+test binary-51.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format Q
+} -result {not enough arguments for all format specifiers}
+test binary-51.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format q blat
+} -result {expected floating-point number but got "blat"}
+test binary-51.3 {Tcl_BinaryObjCmd: format} {
+ binary format q0 1.6
+} {}
+test binary-51.4 {Tcl_BinaryObjCmd: format} {} {
+ binary format Q 1.6
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a
+test binary-51.5 {Tcl_BinaryObjCmd: format} {} {
+ binary format q 1.6
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f
+test binary-51.6 {Tcl_BinaryObjCmd: format} {} {
+ binary format Q* {1.6 3.4}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-51.7 {Tcl_BinaryObjCmd: format} {} {
+ binary format q* {1.6 3.4}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-51.8 {Tcl_BinaryObjCmd: format} {} {
+ binary format Q2 {1.6 3.4}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-51.9 {Tcl_BinaryObjCmd: format} {} {
+ binary format q2 {1.6 3.4}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-51.10 {Tcl_BinaryObjCmd: format} {} {
+ binary format Q2 {1.6 3.4 5.6}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-51.11 {Tcl_BinaryObjCmd: format} {} {
+ binary format q2 {1.6 3.4 5.6}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-51.14 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format q2 {1.6}
+} -result {number of elements in list does not match count}
+test binary-51.15 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {1.6 3.4}
+ binary format q $a
+} -result "expected floating-point number but got \"1.6 3.4\""
+test binary-51.16 {Tcl_BinaryObjCmd: format} {} {
+ set a {1.6 3.4}
+ binary format Q1 $a
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a
+test binary-51.17 {Tcl_BinaryObjCmd: format} {} {
+ set a {1.6 3.4}
+ binary format q1 $a
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f
+
+# format R/r
+test binary-53.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format r
+} -result {not enough arguments for all format specifiers}
+test binary-53.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format r blat
+} -result {expected floating-point number but got "blat"}
+test binary-53.3 {Tcl_BinaryObjCmd: format} {
+ binary format f0 1.6
+} {}
+test binary-53.4 {Tcl_BinaryObjCmd: format} {} {
+ binary format R 1.6
+} \x3f\xcc\xcc\xcd
+test binary-53.5 {Tcl_BinaryObjCmd: format} {} {
+ binary format r 1.6
+} \xcd\xcc\xcc\x3f
+test binary-53.6 {Tcl_BinaryObjCmd: format} {} {
+ binary format R* {1.6 3.4}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-53.7 {Tcl_BinaryObjCmd: format} {} {
+ binary format r* {1.6 3.4}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-53.8 {Tcl_BinaryObjCmd: format} {} {
+ binary format R2 {1.6 3.4}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-53.9 {Tcl_BinaryObjCmd: format} {} {
+ binary format r2 {1.6 3.4}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-53.10 {Tcl_BinaryObjCmd: format} {} {
+ binary format R2 {1.6 3.4 5.6}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-53.11 {Tcl_BinaryObjCmd: format} {} {
+ binary format r2 {1.6 3.4 5.6}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-53.12 {Tcl_BinaryObjCmd: float overflow} {} {
+ binary format R -3.402825e+38
+} \xff\x7f\xff\xff
+test binary-53.13 {Tcl_BinaryObjCmd: float overflow} {} {
+ binary format r -3.402825e+38
+} \xff\xff\x7f\xff
+test binary-53.14 {Tcl_BinaryObjCmd: float underflow} {} {
+ binary format R -3.402825e-100
+} \x80\x00\x00\x00
+test binary-53.15 {Tcl_BinaryObjCmd: float underflow} {} {
+ binary format r -3.402825e-100
+} \x00\x00\x00\x80
+test binary-53.16 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ binary format r2 {1.6}
+} -result {number of elements in list does not match count}
+test binary-53.17 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+ set a {1.6 3.4}
+ binary format r $a
+} -result "expected floating-point number but got \"1.6 3.4\""
+test binary-53.18 {Tcl_BinaryObjCmd: format} {} {
+ set a {1.6 3.4}
+ binary format R1 $a
+} \x3f\xcc\xcc\xcd
+test binary-53.19 {Tcl_BinaryObjCmd: format} {} {
+ set a {1.6 3.4}
+ binary format r1 $a
+} \xcd\xcc\xcc\x3f
+
+# scan t (s)
+test binary-54.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc t
+} -result {not enough arguments for all format specifiers}
+test binary-54.2 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 t* arg1] $arg1
+} {1 {-23726 21587}}
+test binary-54.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 t arg1] $arg1
+} {1 -23726}
+test binary-54.4 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 t1 arg1] $arg1
+} {1 -23726}
+test binary-54.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 t0 arg1] $arg1
+} {1 {}}
+test binary-54.6 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 t2 arg1] $arg1
+} {1 {-23726 21587}}
+test binary-54.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 t1 arg1] $arg1
+} {0 foo}
+test binary-54.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 t1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-54.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x52\xa3\x53\x54\x05 t2c* arg1 arg2] $arg1 $arg2
+} {2 {-23726 21587} 5}
+test binary-54.10 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x00\x80\x00\x80 tut arg1 arg2] $arg1 $arg2
+} {2 32768 -32768}
+test binary-54.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x00\x80\x00\x80 ttu arg1 arg2] $arg1 $arg2
+} {2 -32768 32768}
+
+# scan t (b)
+test binary-55.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc t
+} -result {not enough arguments for all format specifiers}
+test binary-55.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 t* arg1] $arg1
+} {1 {21155 21332}}
+test binary-55.3 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 t arg1] $arg1
+} {1 21155}
+test binary-55.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 t1 arg1] $arg1
+} {1 21155}
+test binary-55.5 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3 t0 arg1] $arg1
+} {1 {}}
+test binary-55.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 t2 arg1] $arg1
+} {1 {21155 21332}}
+test binary-55.7 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 t1 arg1] $arg1
+} {0 foo}
+test binary-55.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53 t1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-55.9 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x52\xa3\x53\x54\x05 t2c* arg1 arg2] $arg1 $arg2
+} {2 {21155 21332} 5}
+test binary-55.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x80\x00\x80\x00 tut arg1 arg2] $arg1 $arg2
+} {2 32768 -32768}
+test binary-55.11 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x80\x00\x80\x00 ttu arg1 arg2] $arg1 $arg2
+} {2 -32768 32768}
+
+# scan n (s)
+test binary-56.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc n
+} -result {not enough arguments for all format specifiers}
+test binary-56.2 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n* arg1] $arg1
+} {1 {1414767442 67305985}}
+test binary-56.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n arg1] $arg1
+} {1 1414767442}
+test binary-56.4 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 n1 arg1] $arg1
+} {1 1414767442}
+test binary-56.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53 n0 arg1] $arg1
+} {1 {}}
+test binary-56.6 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n2 arg1] $arg1
+} {1 {1414767442 67305985}}
+test binary-56.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 n1 arg1] $arg1
+} {0 foo}
+test binary-56.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53\x53\x54 n1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-56.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04\x05 n2c* arg1 arg2] $arg1 $arg2
+} {2 {1414767442 67305985} 5}
+test binary-56.10 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x80\x00\x00\x00\x80\x00\x00\x00 nun arg1 arg2] $arg1 $arg2
+} {2 128 128}
+test binary-56.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x00\x00\x00\x80\x00\x00\x00\x80 nun arg1 arg2] $arg1 $arg2
+} {2 2147483648 -2147483648}
+
+# scan n (b)
+test binary-57.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc n
+} -result {not enough arguments for all format specifiers}
+test binary-57.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n* arg1] $arg1
+} {1 {1386435412 16909060}}
+test binary-57.3 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n arg1] $arg1
+} {1 1386435412}
+test binary-57.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54 n1 arg1] $arg1
+} {1 1386435412}
+test binary-57.5 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53 n0 arg1] $arg1
+} {1 {}}
+test binary-57.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n2 arg1] $arg1
+} {1 {1386435412 16909060}}
+test binary-57.7 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 n1 arg1] $arg1
+} {0 foo}
+test binary-57.8 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x52\x53\x53\x54 n1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-57.9 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04\x05 n2c* arg1 arg2] $arg1 $arg2
+} {2 {1386435412 16909060} 5}
+test binary-57.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x80\x00\x00\x00\x80\x00\x00\x00 nun arg1 arg2] $arg1 $arg2
+} {2 2147483648 -2147483648}
+test binary-57.11 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x00\x00\x00\x80\x00\x00\x00\x80 nun arg1 arg2] $arg1 $arg2
+} {2 128 128}
+
+# scan Q/q
+test binary-58.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc q
+} -result {not enough arguments for all format specifiers}
+test binary-58.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 Q* arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-58.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 q* arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-58.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 Q arg1] $arg1
+} {1 1.6}
+test binary-58.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 q arg1] $arg1
+} {1 1.6}
+test binary-58.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a Q1 arg1] $arg1
+} {1 1.6}
+test binary-58.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f q1 arg1] $arg1
+} {1 1.6}
+test binary-58.8 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a Q0 arg1] $arg1
+} {1 {}}
+test binary-58.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f q0 arg1] $arg1
+} {1 {}}
+test binary-58.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 Q2 arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-58.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 q2 arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-58.12 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 q1 arg1] $arg1
+} {0 foo}
+test binary-58.13 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a q1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-58.14 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33\x05 Q2c* arg1 arg2] $arg1 $arg2
+} {2 {1.6 3.4} 5}
+test binary-58.15 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40\x05 q2c* arg1 arg2] $arg1 $arg2
+} {2 {1.6 3.4} 5}
+
+# scan R/r
+test binary-59.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+ binary scan abc r
+} -result {not enough arguments for all format specifiers}
+test binary-59.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a R* arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-59.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 r* arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-59.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a R arg1] $arg1
+} {1 1.600000023841858}
+test binary-59.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 r arg1] $arg1
+} {1 1.600000023841858}
+test binary-59.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd R1 arg1] $arg1
+} {1 1.600000023841858}
+test binary-59.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f r1 arg1] $arg1
+} {1 1.600000023841858}
+test binary-59.8 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd R0 arg1] $arg1
+} {1 {}}
+test binary-59.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f r0 arg1] $arg1
+} {1 {}}
+test binary-59.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1
+ list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a R2 arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-59.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1
+ list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 r2 arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-59.12 {Tcl_BinaryObjCmd: scan} {
+ unset -nocomplain arg1
+ set arg1 foo
+ list [binary scan \x52 r1 arg1] $arg1
+} {0 foo}
+test binary-59.13 {Tcl_BinaryObjCmd: scan} -setup {
+ unset -nocomplain arg1
+} -returnCodes error -body {
+ set arg1 1
+ binary scan \x3f\xcc\xcc\xcd r1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-59.14 {Tcl_BinaryObjCmd: scan} bigEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a\x05 R2c* arg1 arg2] $arg1 $arg2
+} {2 {1.600000023841858 3.4000000953674316} 5}
+test binary-59.15 {Tcl_BinaryObjCmd: scan} littleEndian {
+ unset -nocomplain arg1 arg2
+ set arg1 foo
+ set arg2 bar
+ list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40\x05 r2c* arg1 arg2] $arg1 $arg2
+} {2 {1.600000023841858 3.4000000953674316} 5}
+
+test binary-60.1 {[binary format] with NaN} -body {
+ binary scan [binary format dqQfrR NaN NaN NaN NaN NaN NaN] dqQfrR \
+ v1 v2 v3 v4 v5 v6
+ list $v1 $v2 $v3 $v4 $v5 $v6
+} -match regexp -result {NaN(\([[:xdigit:]]+\))? NaN(\([[:xdigit:]]+\))? NaN(\([[:xdigit:]]+\))? NaN(\([[:xdigit:]]+\))? NaN(\([[:xdigit:]]+\))? NaN(\([[:xdigit:]]+\))?}
+
+# scan m
+test binary-61.1 {Tcl_BinaryObjCmd: scan wide int} bigEndian {
+ binary scan HelloTcl m x
+ set x
+} 5216694956358656876
+test binary-61.2 {Tcl_BinaryObjCmd: scan wide int} littleEndian {
+ binary scan lcTolleH m x
+ set x
+} 5216694956358656876
+test binary-61.3 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} littleEndian {
+ binary scan [binary format w [expr {wide(3) << 31}]] m x
+ set x
+} 6442450944
+test binary-61.4 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} bigEndian {
+ binary scan [binary format W [expr {wide(3) << 31}]] m x
+ set x
+} 6442450944
+
+# scan/format infinities
+
+test binary-62.1 {infinity} ieeeFloatingPoint {
+ binary scan [binary format q Infinity] w w
+ format 0x%016lx $w
+} 0x7ff0000000000000
+test binary-62.2 {infinity} ieeeFloatingPoint {
+ binary scan [binary format q -Infinity] w w
+ format 0x%016lx $w
+} 0xfff0000000000000
+test binary-62.3 {infinity} ieeeFloatingPoint {
+ binary scan [binary format q Inf] w w
+ format 0x%016lx $w
+} 0x7ff0000000000000
+test binary-62.4 {infinity} ieeeFloatingPoint {
+ binary scan [binary format q -Infinity] w w
+ format 0x%016lx $w
+} 0xfff0000000000000
+test binary-62.5 {infinity} ieeeFloatingPoint {
+ binary scan [binary format w 0x7ff0000000000000] q d
+ set d
+} Inf
+test binary-62.6 {infinity} ieeeFloatingPoint {
+ binary scan [binary format w 0xfff0000000000000] q d
+ set d
+} -Inf
+
+# scan/format Not-a-Number
+
+test binary-63.1 {NaN} ieeeFloatingPoint {
+ binary scan [binary format q NaN] w w
+ format 0x%016lx [expr {$w & 0xfff3ffffffffffff}]
+} 0x7ff0000000000000
+test binary-63.2 {NaN} ieeeFloatingPoint {
+ binary scan [binary format q -NaN] w w
+ format 0x%016lx [expr {$w & 0xfff3ffffffffffff}]
+} 0xfff0000000000000
+test binary-63.3 {NaN} ieeeFloatingPoint {
+ binary scan [binary format q NaN(3123456789aBc)] w w
+ format 0x%016lx [expr {$w & 0xfff3ffffffffffff}]
+} 0x7ff3123456789abc
+test binary-63.4 {NaN} ieeeFloatingPoint {
+ binary scan [binary format q {NaN( 3123456789aBc)}] w w
+ format 0x%016lx [expr {$w & 0xfff3ffffffffffff}]
+} 0x7ff3123456789abc
+
+# Make sure TclParseNumber() rejects invalid nan-hex formats [Bug 3402540]
+test binary-63.5 {NaN} -constraints ieeeFloatingPoint -body {
+ binary format q Nan(
+} -returnCodes error -match glob -result {expected floating-point number*}
+test binary-63.6 {NaN} -constraints ieeeFloatingPoint -body {
+ binary format q Nan()
+} -returnCodes error -match glob -result {expected floating-point number*}
+test binary-63.7 {NaN} -constraints ieeeFloatingPoint -body {
+ binary format q Nan(g)
+} -returnCodes error -match glob -result {expected floating-point number*}
+test binary-63.8 {NaN} -constraints ieeeFloatingPoint -body {
+ binary format q Nan(1,2)
+} -returnCodes error -match glob -result {expected floating-point number*}
+test binary-63.9 {NaN} -constraints ieeeFloatingPoint -body {
+ binary format q Nan(1234567890abcd)
+} -returnCodes error -match glob -result {expected floating-point number*}
+
+test binary-64.1 {NaN} -constraints ieeeFloatingPoint -body {
+ binary scan [binary format w 0x7ff8000000000000] q d
+ set d
+} -match glob -result NaN*
+test binary-64.2 {NaN} -constraints ieeeFloatingPoint -body {
+ binary scan [binary format w 0x7ff0123456789aBc] q d
+ set d
+} -match glob -result NaN(*123456789abc)
+
+test binary-65.1 {largest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x3fcfffffffffffff] q d
+ set d
+} 0.24999999999999997
+test binary-65.2 {smallest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x3fd0000000000000] q d
+ set d
+} 0.25
+test binary-65.3 {largest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x3fdfffffffffffff] q d
+ set d
+} 0.49999999999999994
+test binary-65.4 {smallest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x3fe0000000000000] q d
+ set d
+} 0.5
+test binary-65.5 {largest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x3fffffffffffffff] q d
+ set d
+} 1.9999999999999998
+test binary-65.6 {smallest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x4000000000000000] q d
+ set d
+} 2.0
+test binary-65.7 {smallest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x434fffffffffffff] q d
+ set d
+} 18014398509481982.0
+test binary-65.8 {largest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x4350000000000000] q d
+ set d
+} 18014398509481984.0
+test binary-65.9 {largest significand} ieeeFloatingPoint {
+ binary scan [binary format w 0x4350000000000001] q d
+ set d
+} 18014398509481988.0
+
+test binary-70.1 {binary encode hex} -body {
+ binary encode hex
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-70.2 {binary encode hex} -body {
+ binary encode hex a
+} -result {61}
+test binary-70.3 {binary encode hex} -body {
+ binary encode hex {}
+} -result {}
+test binary-70.4 {binary encode hex} -body {
+ binary encode hex [string repeat a 20]
+} -result [string repeat 61 20]
+test binary-70.5 {binary encode hex} -body {
+ binary encode hex \0\1\2\3\4\0\1\2\3\4
+} -result {00010203040001020304}
+
+test binary-71.1 {binary decode hex} -body {
+ binary decode hex
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-71.2 {binary decode hex} -body {
+ binary decode hex 61
+} -result {a}
+test binary-71.3 {binary decode hex} -body {
+ binary decode hex {}
+} -result {}
+test binary-71.4 {binary decode hex} -body {
+ binary decode hex [string repeat 61 20]
+} -result [string repeat a 20]
+test binary-71.5 {binary decode hex} -body {
+ binary decode hex 00010203040001020304
+} -result "\0\1\2\3\4\0\1\2\3\4"
+test binary-71.6 {binary decode hex} -body {
+ binary decode hex "61 61"
+} -result {aa}
+test binary-71.7 {binary decode hex} -body {
+ binary decode hex "61\n\n\n61"
+} -result {aa}
+test binary-71.8 {binary decode hex} -body {
+ binary decode hex -strict "61 61"
+} -returnCodes error -result {invalid hexadecimal digit " " at position 2}
+test binary-71.9 {binary decode hex} -body {
+ set r [binary decode hex "6"]
+ list [string length $r] $r
+} -result {0 {}}
+test binary-71.10 {binary decode hex} -body {
+ string length [binary decode hex " "]
+} -result 0
+
+test binary-72.1 {binary encode base64} -body {
+ binary encode base64
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-72.2 {binary encode base64} -body {
+ binary encode base64 abc
+} -result {YWJj}
+test binary-72.3 {binary encode base64} -body {
+ binary encode base64 {}
+} -result {}
+test binary-72.4 {binary encode base64} -body {
+ binary encode base64 [string repeat abc 20]
+} -result [string repeat YWJj 20]
+test binary-72.5 {binary encode base64} -body {
+ binary encode base64 \0\1\2\3\4\0\1\2\3
+} -result {AAECAwQAAQID}
+test binary-72.6 {binary encode base64} -body {
+ binary encode base64 \0
+} -result {AA==}
+test binary-72.7 {binary encode base64} -body {
+ binary encode base64 \0\0
+} -result {AAA=}
+test binary-72.8 {binary encode base64} -body {
+ binary encode base64 \0\0\0
+} -result {AAAA}
+test binary-72.9 {binary encode base64} -body {
+ binary encode base64 \0\0\0\0
+} -result {AAAAAA==}
+test binary-72.10 {binary encode base64} -body {
+ binary encode base64 -maxlen 0 -wrapchar : abcabcabc
+} -result {YWJjYWJjYWJj}
+test binary-72.11 {binary encode base64} -body {
+ binary encode base64 -maxlen 1 -wrapchar : abcabcabc
+} -result {Y:W:J:j:Y:W:J:j:Y:W:J:j}
+test binary-72.12 {binary encode base64} -body {
+ binary encode base64 -maxlen 2 -wrapchar : abcabcabc
+} -result {YW:Jj:YW:Jj:YW:Jj}
+test binary-72.13 {binary encode base64} -body {
+ binary encode base64 -maxlen 3 -wrapchar : abcabcabc
+} -result {YWJ:jYW:JjY:WJj}
+test binary-72.14 {binary encode base64} -body {
+ binary encode base64 -maxlen 4 -wrapchar : abcabcabc
+} -result {YWJj:YWJj:YWJj}
+test binary-72.15 {binary encode base64} -body {
+ binary encode base64 -maxlen 5 -wrapchar : abcabcabc
+} -result {YWJjY:WJjYW:Jj}
+test binary-72.16 {binary encode base64} -body {
+ binary encode base64 -maxlen 6 -wrapchar : abcabcabc
+} -result {YWJjYW:JjYWJj}
+test binary-72.17 {binary encode base64} -body {
+ binary encode base64 -maxlen 7 -wrapchar : abcabcabc
+} -result {YWJjYWJ:jYWJj}
+test binary-72.18 {binary encode base64} -body {
+ binary encode base64 -maxlen 8 -wrapchar : abcabcabc
+} -result {YWJjYWJj:YWJj}
+test binary-72.19 {binary encode base64} -body {
+ binary encode base64 -maxlen 9 -wrapchar : abcabcabc
+} -result {YWJjYWJjY:WJj}
+test binary-72.20 {binary encode base64} -body {
+ binary encode base64 -maxlen 10 -wrapchar : abcabcabc
+} -result {YWJjYWJjYW:Jj}
+test binary-72.21 {binary encode base64} -body {
+ binary encode base64 -maxlen 11 -wrapchar : abcabcabc
+} -result {YWJjYWJjYWJ:j}
+test binary-72.22 {binary encode base64} -body {
+ binary encode base64 -maxlen 12 -wrapchar : abcabcabc
+} -result {YWJjYWJjYWJj}
+test binary-72.23 {binary encode base64} -body {
+ binary encode base64 -maxlen 13 -wrapchar : abcabcabc
+} -result {YWJjYWJjYWJj}
+test binary-72.24 {binary encode base64} -body {
+ binary encode base64 -maxlen 60 -wrapchar : abcabcabc
+} -result {YWJjYWJjYWJj}
+test binary-72.25 {binary encode base64} -body {
+ binary encode base64 -maxlen 2 -wrapchar * abcabcabc
+} -result {YW*Jj*YW*Jj*YW*Jj}
+test binary-72.26 {binary encode base64} -body {
+ binary encode base64 -maxlen 6 -wrapchar -*- abcabcabc
+} -result {YWJjYW-*-JjYWJj}
+test binary-72.27 {binary encode base64} -body {
+ binary encode base64 -maxlen 4 -wrapchar -*- abcabcabc
+} -result {YWJj-*-YWJj-*-YWJj}
+test binary-72.28 {binary encode base64} -body {
+ binary encode base64 -maxlen 6 -wrapchar 0123456789 abcabcabc
+} -result {YWJjYW0123456789JjYWJj}
+
+test binary-73.1 {binary decode base64} -body {
+ binary decode base64
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-73.2 {binary decode base64} -body {
+ binary decode base64 YWJj
+} -result {abc}
+test binary-73.3 {binary decode base64} -body {
+ binary decode base64 {}
+} -result {}
+test binary-73.4 {binary decode base64} -body {
+ binary decode base64 [string repeat YWJj 20]
+} -result [string repeat abc 20]
+test binary-73.5 {binary encode base64} -body {
+ binary decode base64 AAECAwQAAQID
+} -result "\0\1\2\3\4\0\1\2\3"
+test binary-73.6 {binary encode base64} -body {
+ binary decode base64 AA==
+} -result "\0"
+test binary-73.7 {binary encode base64} -body {
+ binary decode base64 AAA=
+} -result "\0\0"
+test binary-73.8 {binary encode base64} -body {
+ binary decode base64 AAAA
+} -result "\0\0\0"
+test binary-73.9 {binary encode base64} -body {
+ binary decode base64 AAAAAA==
+} -result "\0\0\0\0"
+test binary-73.10 {binary decode base64} -body {
+ set s "[string repeat YWJj 10]\n[string repeat YWJj 10]"
+ binary decode base64 $s
+} -result [string repeat abc 20]
+test binary-73.11 {binary decode base64} -body {
+ set s "[string repeat YWJj 10]\n [string repeat YWJj 10]"
+ binary decode base64 $s
+} -result [string repeat abc 20]
+test binary-73.12 {binary decode base64} -body {
+ binary decode base64 -strict ":YWJj"
+} -returnCodes error -match glob -result {invalid base64 character ":" at position 0}
+test binary-73.13 {binary decode base64} -body {
+ set s "[string repeat YWJj 10]:[string repeat YWJj 10]"
+ binary decode base64 -strict $s
+} -returnCodes error -match glob -result {invalid base64 character ":" at position 40}
+test binary-73.14 {binary decode base64} -body {
+ set s "[string repeat YWJj 10]\n [string repeat YWJj 10]"
+ binary decode base64 -strict $s
+} -returnCodes error -match glob -result {invalid base64 character *}
+test binary-73.20 {binary decode base64} -body {
+ set r [binary decode base64 Y]
+ list [string length $r] $r
+} -result {0 {}}
+test binary-73.21 {binary decode base64} -body {
+ set r [binary decode base64 YW]
+ list [string length $r] $r
+} -result {1 a}
+test binary-73.22 {binary decode base64} -body {
+ set r [binary decode base64 YWJ]
+ list [string length $r] $r
+} -result {2 ab}
+test binary-73.23 {binary decode base64} -body {
+ set r [binary decode base64 YWJj]
+ list [string length $r] $r
+} -result {3 abc}
+test binary-73.24 {binary decode base64} -body {
+ string length [binary decode base64 " "]
+} -result 0
+
+test binary-74.1 {binary encode uuencode} -body {
+ binary encode uuencode
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-74.2 {binary encode uuencode} -body {
+ binary encode uuencode abc
+} -result {86)C}
+test binary-74.3 {binary encode uuencode} -body {
+ binary encode uuencode {}
+} -result {}
+test binary-74.4 {binary encode uuencode} -body {
+ binary encode uuencode [string repeat abc 20]
+} -result [string repeat 86)C 20]
+test binary-74.5 {binary encode uuencode} -body {
+ binary encode uuencode \0\1\2\3\4\0\1\2\3
+} -result "``\$\"`P0``0(#"
+test binary-74.6 {binary encode uuencode} -body {
+ binary encode uuencode \0
+} -result {````}
+test binary-74.7 {binary encode uuencode} -body {
+ binary encode uuencode \0\0
+} -result {````}
+test binary-74.8 {binary encode uuencode} -body {
+ binary encode uuencode \0\0\0
+} -result {````}
+test binary-74.9 {binary encode uuencode} -body {
+ binary encode uuencode \0\0\0\0
+} -result {````````}
+test binary-74.10 {binary encode uuencode} -body {
+ binary encode uuencode -maxlen 0 -wrapchar | abcabcabc
+} -result {86)C86)C86)C}
+test binary-74.11 {binary encode uuencode} -body {
+ binary encode uuencode -maxlen 1 -wrapchar | abcabcabc
+} -result {8|6|)|C|8|6|)|C|8|6|)|C}
+
+test binary-75.1 {binary decode uuencode} -body {
+ binary decode uuencode
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-75.2 {binary decode uuencode} -body {
+ binary decode uuencode 86)C
+} -result {abc}
+test binary-75.3 {binary decode uuencode} -body {
+ binary decode uuencode {}
+} -result {}
+test binary-75.4 {binary decode uuencode} -body {
+ binary decode uuencode [string repeat "86)C" 20]
+} -result [string repeat abc 20]
+test binary-75.5 {binary decode uuencode} -body {
+ binary decode uuencode "``\$\"`P0``0(#"
+} -result "\0\1\2\3\4\0\1\2\3"
+test binary-75.6 {binary decode uuencode} -body {
+ string length [binary decode uuencode {`}]
+} -result 0
+test binary-75.7 {binary decode uuencode} -body {
+ string length [binary decode uuencode {``}]
+} -result 1
+test binary-75.8 {binary decode uuencode} -body {
+ string length [binary decode uuencode {```}]
+} -result 2
+test binary-75.9 {binary decode uuencode} -body {
+ string length [binary decode uuencode {````}]
+} -result 3
+test binary-75.10 {binary decode uuencode} -body {
+ set s "[string repeat 86)C 10]\n[string repeat 86)C 10]"
+ binary decode uuencode $s
+} -result [string repeat abc 20]
+test binary-75.11 {binary decode uuencode} -body {
+ set s "[string repeat 86)C 10]\n [string repeat 86)C 10]"
+ binary decode uuencode $s
+} -result [string repeat abc 20]
+test binary-75.12 {binary decode uuencode} -body {
+ binary decode uuencode -strict "|86)C"
+} -returnCodes error -match glob -result {invalid uuencode character "|" at position 0}
+test binary-75.13 {binary decode uuencode} -body {
+ set s "[string repeat 86)C 10]|[string repeat 86)C 10]"
+ binary decode uuencode -strict $s
+} -returnCodes error -match glob -result {invalid uuencode character "|" at position 40}
+test binary-75.14 {binary decode uuencode} -body {
+ set s "[string repeat 86)C 10]\n [string repeat 86)C 10]"
+ binary decode uuencode -strict $s
+} -returnCodes error -match glob -result {invalid uuencode character *}
+test binary-75.20 {binary decode uuencode} -body {
+ set r [binary decode uuencode 8]
+ list [string length $r] $r
+} -result {0 {}}
+test binary-75.21 {binary decode uuencode} -body {
+ set r [binary decode uuencode 86]
+ list [string length $r] $r
+} -result {1 a}
+test binary-75.22 {binary decode uuencode} -body {
+ set r [binary decode uuencode 86)]
+ list [string length $r] $r
+} -result {2 ab}
+test binary-75.23 {binary decode uuencode} -body {
+ set r [binary decode uuencode 86)C]
+ list [string length $r] $r
+} -result {3 abc}
+test binary-75.24 {binary decode uuencode} -body {
+ set s "04)\# "
+ binary decode uuencode $s
+} -result ABC
+test binary-75.25 {binary decode uuencode} -body {
+ set s "04)\#z"
+ binary decode uuencode $s
+} -returnCodes error -match glob -result {invalid uuencode character "z" at position 4}
+test binary-75.26 {binary decode uuencode} -body {
+ string length [binary decode uuencode " "]
+} -result 0
+
+test binary-76.1 {binary string appending growth algorithm} unix {
+ # Create zero-length byte array first
+ set f [open /dev/null rb]
+ chan configure $f -blocking 0
+ set str [read $f 2]
+ close $f
+ # Append to it
+ string length [append str [binary format a* foo]]
+} 3
+test binary-76.2 {binary string appending growth algorithm} win {
+ # Create zero-length byte array first
+ set f [open NUL rb]
+ chan configure $f -blocking 0
+ set str [read $f 2]
+ close $f
+ # Append to it
+ string length [append str [binary format a* foo]]
+} 3
+
+# ----------------------------------------------------------------------
+# cleanup
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/case.test b/pkgs/msgcat/tests/case.test
new file mode 100644
index 0000000..6d63cea
--- /dev/null
+++ b/pkgs/msgcat/tests/case.test
@@ -0,0 +1,89 @@
+# Commands covered: case
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test case-1.1 {simple pattern} {
+ case a in a {format 1} b {format 2} c {format 3} default {format 4}
+} 1
+test case-1.2 {simple pattern} {
+ case b a {format 1} b {format 2} c {format 3} default {format 4}
+} 2
+test case-1.3 {simple pattern} {
+ case x in a {format 1} b {format 2} c {format 3} default {format 4}
+} 4
+test case-1.4 {simple pattern} {
+ case x a {format 1} b {format 2} c {format 3}
+} {}
+test case-1.5 {simple pattern matches many times} {
+ case b a {format 1} b {format 2} b {format 3} b {format 4}
+} 2
+test case-1.6 {fancier pattern} {
+ case cx a {format 1} *c {format 2} *x {format 3} default {format 4}
+} 3
+test case-1.7 {list of patterns} {
+ case abc in {a b c} {format 1} {def abc ghi} {format 2}
+} 2
+
+test case-2.1 {error in executed command} {
+ list [catch {case a in a {error "Just a test"} default {format 1}} msg] \
+ $msg $::errorInfo
+} {1 {Just a test} {Just a test
+ while executing
+"error "Just a test""
+ ("a" arm line 1)
+ invoked from within
+"case a in a {error "Just a test"} default {format 1}"}}
+test case-2.2 {error: not enough args} {
+ list [catch {case} msg] $msg
+} {1 {wrong # args: should be "case string ?in? ?pattern body ...? ?default body?"}}
+test case-2.3 {error: pattern with no body} {
+ list [catch {case a b} msg] $msg
+} {1 {extra case pattern with no body}}
+test case-2.4 {error: pattern with no body} {
+ list [catch {case a in b {format 1} c} msg] $msg
+} {1 {extra case pattern with no body}}
+test case-2.5 {error in default command} {
+ list [catch {case foo in a {error case1} default {error case2} \
+ b {error case 3}} msg] $msg $::errorInfo
+} {1 case2 {case2
+ while executing
+"error case2"
+ ("default" arm line 1)
+ invoked from within
+"case foo in a {error case1} default {error case2} b {error case 3}"}}
+
+test case-3.1 {single-argument form for pattern/command pairs} {
+ case b in {
+ a {format 1}
+ b {format 2}
+ default {format 6}
+ }
+} {2}
+test case-3.2 {single-argument form for pattern/command pairs} {
+ case b {
+ a {format 1}
+ b {format 2}
+ default {format 6}
+ }
+} {2}
+test case-3.3 {single-argument form for pattern/command pairs} {
+ list [catch {case z in {a 2 b}} msg] $msg
+} {1 {extra case pattern with no body}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/chan.test b/pkgs/msgcat/tests/chan.test
new file mode 100644
index 0000000..da44ffd
--- /dev/null
+++ b/pkgs/msgcat/tests/chan.test
@@ -0,0 +1,275 @@
+# This file contains a collection of tests for the Tcl built-in 'chan'
+# command. Sourcing this file into Tcl runs the tests and generates
+# output for errors. No output means no errors were found.
+#
+# 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+#
+# Note: The tests for the chan methods "create" and "postevent"
+# currently reside in the file "ioCmd.test".
+#
+
+test chan-1.1 {chan command general syntax} -body {
+ chan
+} -returnCodes error -result "wrong # args: should be \"chan subcommand ?arg ...?\""
+test chan-1.2 {chan command general syntax} -body {
+ chan FOOBAR
+} -returnCodes error -match glob -result "unknown or ambiguous subcommand \"FOOBAR\": must be *"
+
+test chan-2.1 {chan command: blocked subcommand} -body {
+ chan blocked foo bar
+} -returnCodes error -result "wrong # args: should be \"chan blocked channelId\""
+test chan-3.1 {chan command: close subcommand} -body {
+ chan close foo bar zet
+} -returnCodes error -result "wrong # args: should be \"chan close channelId ?direction?\""
+test chan-3.2 {chan command: close subcommand} -setup {
+ set chan [open [info script] r]
+} -body {
+ chan close $chan bar
+} -cleanup {
+ close $chan
+} -returnCodes error -result "bad direction \"bar\": must be read or write"
+test chan-3.3 {chan command: close subcommand} -setup {
+ set chan [open [info script] r]
+} -body {
+ chan close $chan write
+} -cleanup {
+ close $chan
+} -returnCodes error -result "Half-close of write-side not possible, side not opened or already closed"
+test chan-4.1 {chan command: configure subcommand} -body {
+ chan configure
+} -returnCodes error -result "wrong # args: should be \"chan configure channelId ?-option value ...?\""
+test chan-4.2 {chan command: [Bug 800753]} -body {
+ chan configure stdout -eofchar \u0100
+} -returnCodes error -match glob -result {bad value*}
+test chan-4.3 {chan command: [Bug 800753]} -body {
+ chan configure stdout -eofchar \u0000
+} -returnCodes error -match glob -result {bad value*}
+test chan-4.4 {chan command: check valid inValue, no outValue} -body {
+ chan configure stdout -eofchar [list \x27 {}]
+} -returnCodes ok -result {}
+test chan-4.5 {chan command: check valid inValue, invalid outValue} -body {
+ chan configure stdout -eofchar [list \x27 \x80]
+} -returnCodes error -match glob -result {bad value for -eofchar:*}
+test chan-4.6 {chan command: check no inValue, valid outValue} -body {
+ chan configure stdout -eofchar [list {} \x27]
+} -returnCodes ok -result {}
+
+test chan-5.1 {chan command: copy subcommand} -body {
+ chan copy foo
+} -returnCodes error -result "wrong # args: should be \"chan copy input output ?-size size? ?-command callback?\""
+
+test chan-6.1 {chan command: eof subcommand} -body {
+ chan eof foo bar
+} -returnCodes error -result "wrong # args: should be \"chan eof channelId\""
+
+test chan-7.1 {chan command: event subcommand} -body {
+ chan event foo
+} -returnCodes error -result "wrong # args: should be \"chan event channelId event ?script?\""
+
+test chan-8.1 {chan command: flush subcommand} -body {
+ chan flush foo bar
+} -returnCodes error -result "wrong # args: should be \"chan flush channelId\""
+
+test chan-9.1 {chan command: gets subcommand} -body {
+ chan gets
+} -returnCodes error -result "wrong # args: should be \"chan gets channelId ?varName?\""
+
+test chan-10.1 {chan command: names subcommand} -body {
+ chan names foo bar
+} -returnCodes error -result "wrong # args: should be \"chan names ?pattern?\""
+
+test chan-11.1 {chan command: puts subcommand} -body {
+ chan puts foo bar foo bar
+} -returnCodes error -result "wrong # args: should be \"chan puts ?-nonewline? ?channelId? string\""
+
+test chan-12.1 {chan command: read subcommand} -body {
+ chan read
+} -returnCodes error -result "wrong # args: should be \"chan read channelId ?numChars?\" or \"chan read ?-nonewline? channelId\""
+
+test chan-13.1 {chan command: seek subcommand} -body {
+ chan seek foo bar foo bar
+} -returnCodes error -result "wrong # args: should be \"chan seek channelId offset ?origin?\""
+
+test chan-14.1 {chan command: tell subcommand} -body {
+ chan tell foo bar
+} -returnCodes error -result "wrong # args: should be \"chan tell channelId\""
+
+test chan-15.1 {chan command: truncate subcommand} -body {
+ chan truncate foo bar foo bar
+} -returnCodes error -result "wrong \# args: should be \"chan truncate channelId ?length?\""
+test chan-15.2 {chan command: truncate subcommand} -setup {
+ set file [makeFile {} testTruncate]
+ set f [open $file w+]
+ fconfigure $f -translation binary
+} -body {
+ seek $f 0
+ puts -nonewline $f 12345
+ seek $f 0
+ chan truncate $f 2
+ read $f
+} -result 12 -cleanup {
+ catch {close $f}
+ catch {removeFile $file}
+}
+
+# TIP 287: chan pending
+test chan-16.1 {chan command: pending subcommand} -body {
+ chan pending
+} -returnCodes error -result "wrong # args: should be \"chan pending mode channelId\""
+test chan-16.2 {chan command: pending subcommand} -body {
+ chan pending stdin
+} -returnCodes error -result "wrong # args: should be \"chan pending mode channelId\""
+test chan-16.3 {chan command: pending subcommand} -body {
+ chan pending stdin stdout stderr
+} -returnCodes error -result "wrong # args: should be \"chan pending mode channelId\""
+test chan-16.4 {chan command: pending subcommand} -body {
+ chan pending {input output} stdout
+} -returnCodes error -result "bad mode \"input output\": must be input or output"
+test chan-16.5 {chan command: pending input subcommand} -body {
+ chan pending input stdout
+} -result -1
+test chan-16.6 {chan command: pending input subcommand} -body {
+ chan pending input stdin
+} -result 0
+test chan-16.7 {chan command: pending input subcommand} -body {
+ chan pending input FOOBAR
+} -returnCodes error -result "can not find channel named \"FOOBAR\""
+test chan-16.8 {chan command: pending input subcommand} -setup {
+ set file [makeFile {} testAvailable]
+ set f [open $file w+]
+ chan configure $f -translation lf -buffering line
+} -body {
+ chan puts $f foo
+ chan puts $f bar
+ chan puts $f baz
+ chan seek $f 0
+ chan gets $f
+ chan pending input $f
+} -result 8 -cleanup {
+ catch {chan close $f}
+ catch {removeFile $file}
+}
+test chan-16.9 {chan command: pending input subcommand} -setup {
+ proc chan-16.9-accept {sock addr port} {
+ chan configure $sock -blocking 0 -buffering line -buffersize 32
+ chan event $sock readable [list chan-16.9-readable $sock]
+ }
+
+ proc chan-16.9-readable {sock} {
+ set r [chan gets $sock line]
+ set l [string length $line]
+ set e [chan eof $sock]
+ set b [chan blocked $sock]
+ set i [chan pending input $sock]
+
+ lappend ::chan-16.9-data $r $l $e $b $i
+
+ if {$r != -1 || $e || $l || !$b || $i > 128} {
+ set data [read $sock $i]
+ lappend ::chan-16.9-data [string range $data 0 2]
+ lappend ::chan-16.9-data [string range $data end-2 end]
+ set ::chan-16.9-done 1
+ chan event $sock readable {}
+ } else {
+ after idle chan-16.9-client
+ }
+ }
+
+ proc chan-16.9-client {} {
+ chan puts -nonewline $::client ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
+ chan flush $::client
+ }
+
+ set ::server [socket -server chan-16.9-accept -myaddr 127.0.0.1 0]
+ set ::client [socket 127.0.0.1 [lindex [fconfigure $::server -sockname] 2]]
+ set ::chan-16.9-data [list]
+ set ::chan-16.9-done 0
+} -body {
+ after idle chan-16.9-client
+ vwait ::chan-16.9-done
+ set ::chan-16.9-data
+} -result {-1 0 0 1 36 -1 0 0 1 72 -1 0 0 1 108 -1 0 0 1 144 ABC 890} -cleanup {
+ catch {chan close $client}
+ catch {chan close $server}
+ rename chan-16.9-accept {}
+ rename chan-16.9-readable {}
+ rename chan-16.9-client {}
+ unset -nocomplain ::chan-16.9-data
+ unset -nocomplain ::chan-16.9-done
+ unset -nocomplain ::server
+ unset -nocomplain ::client
+}
+test chan-16.10 {chan command: pending output subcommand} -body {
+ chan pending output stdin
+} -result -1
+test chan-16.11 {chan command: pending output subcommand} -body {
+ chan pending output stdout
+} -result 0
+test chan-16.12 {chan command: pending output subcommand} -body {
+ chan pending output FOOBAR
+} -returnCodes error -result "can not find channel named \"FOOBAR\""
+test chan-16.13 {chan command: pending output subcommand} -setup {
+ set file [makeFile {} testPendingOutput]
+ set f [open $file w+]
+ chan configure $f -translation lf -buffering full -buffersize 1024
+} -body {
+ set result [list]
+ chan puts $f [string repeat x 512]
+ lappend result [chan pending output $f]
+ chan flush $f
+ lappend result [chan pending output $f]
+} -result [list 513 0] -cleanup {
+ unset -nocomplain result
+ catch {chan close $f}
+ catch {removeFile $file}
+}
+
+# TIP 304: chan pipe
+
+test chan-17.1 {chan command: pipe subcommand} -body {
+ chan pipe foo
+} -returnCodes error -result "wrong # args: should be \"chan pipe \""
+
+test chan-17.2 {chan command: pipe subcommand} -body {
+ chan pipe foo bar
+} -returnCodes error -result "wrong # args: should be \"chan pipe \""
+
+test chan-17.3 {chan command: pipe subcommand} -body {
+ set l [chan pipe]
+ foreach {pr pw} $l break
+ list [llength $l] [fconfigure $pr -blocking] [fconfigure $pw -blocking]
+} -result [list 2 1 1] -cleanup {
+ close $pw
+ close $pr
+}
+
+test chan-17.4 {chan command: pipe subcommand} -body {
+ set ::done 0
+ foreach {::pr ::pw} [chan pipe] break
+ after 100 {puts $::pw foo;flush $::pw}
+ fileevent $::pr readable {set ::done 1}
+ after 500 {set ::done -1}
+ vwait ::done
+ set out nope
+ if {$::done==1} {gets $::pr out}
+ list $::done $out
+} -result [list 1 foo] -cleanup {
+ close $::pw
+ close $::pr
+}
+
+cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/chanio.test b/pkgs/msgcat/tests/chanio.test
new file mode 100644
index 0000000..fbc9854
--- /dev/null
+++ b/pkgs/msgcat/tests/chanio.test
@@ -0,0 +1,7716 @@
+# -*- tcl -*-
+# Functionality covered: operation of all IO commands, and all procedures
+# defined in generic/tclIO.c.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# 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.
+
+if {[catch {package require tcltest 2}]} {
+ chan puts stderr "Skipping tests in [info script]. tcltest 2 required."
+ return
+}
+namespace eval ::tcl::test::io {
+ namespace import ::tcltest::*
+
+ variable umaskValue
+ variable path
+ variable f
+ variable i
+ variable n
+ variable v
+ variable msg
+ variable expected
+
+ testConstraint testchannel [llength [info commands testchannel]]
+ testConstraint exec [llength [info commands exec]]
+ testConstraint openpipe 1
+ testConstraint fileevent [llength [info commands fileevent]]
+ testConstraint fcopy [llength [info commands fcopy]]
+ testConstraint testfevent [llength [info commands testfevent]]
+ testConstraint testchannelevent [llength [info commands testchannelevent]]
+ testConstraint testmainthread [llength [info commands testmainthread]]
+ testConstraint thread [expr {0 == [catch {package require Thread 2.6}]}]
+
+ # You need a *very* special environment to do some tests. In particular,
+ # many file systems do not support large-files...
+ testConstraint largefileSupport 0
+
+ # some tests can only be run is umask is 2 if "umask" cannot be run, the
+ # tests will be skipped.
+ set umaskValue 0
+ testConstraint umask [expr {![catch {set umaskValue [scan [exec /bin/sh -c umask] %o]}]}]
+
+ testConstraint makeFileInHome [expr {![file exists ~/_test_] && [file writable ~]}]
+
+ # set up a long data file for some of the following tests
+
+ set path(longfile) [makeFile {} longfile]
+ set f [open $path(longfile) w]
+ chan configure $f -eofchar {} -translation lf
+ for { set i 0 } { $i < 100 } { incr i} {
+ chan puts $f "#123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
+\#123456789abcdef01
+\#"
+ }
+ chan close $f
+
+ set path(cat) [makeFile {
+ set f stdin
+ if {$argv != ""} {
+ set f [open [lindex $argv 0]]
+ }
+ chan configure $f -encoding binary -translation lf -blocking 0 -eofchar \x1a
+ chan configure stdout -encoding binary -translation lf -buffering none
+ chan event $f readable "foo $f"
+ proc foo {f} {
+ set x [chan read $f]
+ catch {chan puts -nonewline $x}
+ if {[chan eof $f]} {
+ chan close $f
+ exit 0
+ }
+ }
+ vwait forever
+ } cat]
+
+ set thisScript [file join [pwd] [info script]]
+
+ proc contents {file} {
+ set f [open $file]
+ chan configure $f -translation binary
+ set a [chan read $f]
+ chan close $f
+ return $a
+ }
+
+ # Wrapper round butt-ugly pipe syntax
+ proc openpipe {{mode r+} args} {
+ open "|[list [interpreter] {*}$args]" $mode
+ }
+
+test chan-io-1.5 {Tcl_WriteChars: CheckChannelErrors} {emptyTest} {
+ # no test, need to cause an async error.
+} {}
+set path(test1) [makeFile {} test1]
+test chan-io-1.6 {Tcl_WriteChars: WriteBytes} {
+ set f [open $path(test1) w]
+ chan configure $f -encoding binary
+ chan puts -nonewline $f "a\u4e4d\0"
+ chan close $f
+ contents $path(test1)
+} "a\x4d\x00"
+test chan-io-1.7 {Tcl_WriteChars: WriteChars} {
+ set f [open $path(test1) w]
+ chan configure $f -encoding shiftjis
+ chan puts -nonewline $f "a\u4e4d\0"
+ chan close $f
+ contents $path(test1)
+} "a\x93\xe1\x00"
+set path(test2) [makeFile {} test2]
+test chan-io-1.8 {Tcl_WriteChars: WriteChars} {
+ # This test written for SF bug #506297.
+ #
+ # Executing this test without the fix for the referenced bug applied to
+ # tcl will cause tcl, more specifically WriteChars, to go into an infinite
+ # loop.
+ set f [open $path(test2) w]
+ chan configure $f -encoding iso2022-jp
+ chan puts -nonewline $f [format %s%c [string repeat " " 4] 12399]
+ chan close $f
+ contents $path(test2)
+} " \x1b\$B\$O\x1b(B"
+test chan-io-1.9 {Tcl_WriteChars: WriteChars} {
+ # When closing a channel with an encoding that appends escape bytes, check
+ # for the case where the escape bytes overflow the current IO buffer. The
+ # bytes should be moved into a new buffer.
+ set data "1234567890 [format %c 12399]"
+ set sizes [list]
+ # With default buffer size
+ set f [open $path(test2) w]
+ chan configure $f -encoding iso2022-jp
+ chan puts -nonewline $f $data
+ chan close $f
+ lappend sizes [file size $path(test2)]
+ # With buffer size equal to the length of the data, the escape bytes would
+ # go into the next buffer.
+ set f [open $path(test2) w]
+ chan configure $f -encoding iso2022-jp -buffersize 16
+ chan puts -nonewline $f $data
+ chan close $f
+ lappend sizes [file size $path(test2)]
+ # With buffer size that is large enough to hold 1 byte of escaped data,
+ # but not all 3. This should not write the escape bytes to the first
+ # buffer and then again to the second buffer.
+ set f [open $path(test2) w]
+ chan configure $f -encoding iso2022-jp -buffersize 17
+ chan puts -nonewline $f $data
+ chan close $f
+ lappend sizes [file size $path(test2)]
+ # With buffer size that can hold 2 out of 3 bytes of escaped data.
+ set f [open $path(test2) w]
+ chan configure $f -encoding iso2022-jp -buffersize 18
+ chan puts -nonewline $f $data
+ chan close $f
+ lappend sizes [file size $path(test2)]
+ # With buffer size that can hold all the data and escape bytes.
+ set f [open $path(test2) w]
+ chan configure $f -encoding iso2022-jp -buffersize 19
+ chan puts -nonewline $f $data
+ chan close $f
+ lappend sizes [file size $path(test2)]
+} {19 19 19 19 19}
+
+test chan-io-2.1 {WriteBytes} {
+ # loop until all bytes are written
+ set f [open $path(test1) w]
+ chan configure $f -encoding binary -buffersize 16 -translation crlf
+ chan puts $f "abcdefghijklmnopqrstuvwxyz"
+ chan close $f
+ contents $path(test1)
+} "abcdefghijklmnopqrstuvwxyz\r\n"
+test chan-io-2.2 {WriteBytes: savedLF > 0} {
+ # After flushing buffer, there was a \n left over from the last
+ # \n -> \r\n expansion. It gets stuck at beginning of this buffer.
+ set f [open $path(test1) w]
+ chan configure $f -encoding binary -buffersize 16 -translation crlf
+ chan puts -nonewline $f "123456789012345\n12"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "123456789012345\r" "123456789012345\r\n12"]
+test chan-io-2.3 {WriteBytes: flush on line} -body {
+ # Tcl "line" buffering has weird behavior: if current buffer contains a
+ # \n, entire buffer gets flushed. Logical behavior would be to flush only
+ # up to the \n.
+ set f [open $path(test1) w]
+ chan configure $f -encoding binary -buffering line -translation crlf
+ chan puts -nonewline $f "\n12"
+ contents $path(test1)
+} -cleanup {
+ chan close $f
+} -result "\r\n12"
+test chan-io-2.4 {WriteBytes: reset sawLF after each buffer} {
+ set f [open $path(test1) w]
+ chan configure $f -encoding binary -buffering line -translation lf \
+ -buffersize 16
+ chan puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]
+
+test chan-io-3.1 {WriteChars: compatibility with WriteBytes} {
+ # loop until all bytes are written
+ set f [open $path(test1) w]
+ chan configure $f -encoding ascii -buffersize 16 -translation crlf
+ chan puts $f "abcdefghijklmnopqrstuvwxyz"
+ chan close $f
+ contents $path(test1)
+} "abcdefghijklmnopqrstuvwxyz\r\n"
+test chan-io-3.2 {WriteChars: compatibility with WriteBytes: savedLF > 0} {
+ # After flushing buffer, there was a \n left over from the last
+ # \n -> \r\n expansion. It gets stuck at beginning of this buffer.
+ set f [open $path(test1) w]
+ chan configure $f -encoding ascii -buffersize 16 -translation crlf
+ chan puts -nonewline $f "123456789012345\n12"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "123456789012345\r" "123456789012345\r\n12"]
+test chan-io-3.3 {WriteChars: compatibility with WriteBytes: flush on line} -body {
+ # Tcl "line" buffering has weird behavior: if current buffer contains a
+ # \n, entire buffer gets flushed. Logical behavior would be to flush only
+ # up to the \n.
+ set f [open $path(test1) w]
+ chan configure $f -encoding ascii -buffering line -translation crlf
+ chan puts -nonewline $f "\n12"
+ contents $path(test1)
+} -cleanup {
+ chan close $f
+} -result "\r\n12"
+test chan-io-3.4 {WriteChars: loop over stage buffer} {
+ # stage buffer maps to more than can be queued at once.
+ set f [open $path(test1) w]
+ chan configure $f -encoding jis0208 -buffersize 16
+ chan puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test chan-io-3.5 {WriteChars: saved != 0} {
+ # Bytes produced by UtfToExternal from end of last channel buffer had to
+ # be moved to beginning of next channel buffer to preserve requested
+ # buffersize.
+ set f [open $path(test1) w]
+ chan configure $f -encoding jis0208 -buffersize 17
+ chan puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test chan-io-3.6 {WriteChars: (stageRead + dstWrote == 0)} {
+ # One incomplete UTF-8 character at end of staging buffer. Backup in src
+ # to the beginning of that UTF-8 character and try again.
+ #
+ # Translate the first 16 bytes, produce 14 bytes of output, 2 left over
+ # (first two bytes of \uff21 in UTF-8). Given those two bytes try
+ # translating them again, find that no bytes are read produced, and break
+ # to outer loop where those two bytes will have the remaining 4 bytes (the
+ # last byte of \uff21 plus the all of \uff22) appended.
+ set f [open $path(test1) w]
+ chan configure $f -encoding shiftjis -buffersize 16
+ chan puts -nonewline $f "12345678901234\uff21\uff22"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "12345678901234\x82\x60" "12345678901234\x82\x60\x82\x61"]
+test chan-io-3.7 {WriteChars: (bufPtr->nextAdded > bufPtr->length)} {
+ # When translating UTF-8 to external, the produced bytes went past end of
+ # the channel buffer. This is done on purpose - we then truncate the bytes
+ # at the end of the partial character to preserve the requested blocksize
+ # on flush. The truncated bytes are moved to the beginning of the next
+ # channel buffer.
+ set f [open $path(test1) w]
+ chan configure $f -encoding jis0208 -buffersize 17
+ chan puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test chan-io-3.8 {WriteChars: reset sawLF after each buffer} {
+ set f [open $path(test1) w]
+ chan configure $f -encoding ascii -buffering line -translation lf \
+ -buffersize 16
+ chan puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]
+
+test chan-io-4.1 {TranslateOutputEOL: lf} {
+ # search for \n
+ set f [open $path(test1) w]
+ chan configure $f -buffering line -translation lf
+ chan puts $f "abcde"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "abcde\n" "abcde\n"]
+test chan-io-4.2 {TranslateOutputEOL: cr} {
+ # search for \n, replace with \r
+ set f [open $path(test1) w]
+ chan configure $f -buffering line -translation cr
+ chan puts $f "abcde"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "abcde\r" "abcde\r"]
+test chan-io-4.3 {TranslateOutputEOL: crlf} {
+ # simple case: search for \n, replace with \r
+ set f [open $path(test1) w]
+ chan configure $f -buffering line -translation crlf
+ chan puts $f "abcde"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "abcde\r\n" "abcde\r\n"]
+test chan-io-4.4 {TranslateOutputEOL: crlf} {
+ # Keep storing more bytes in output buffer until output buffer is full. We
+ # have 13 bytes initially that would turn into 18 bytes. Fill dest buffer
+ # while (dstEnd < dstMax).
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -buffersize 16
+ chan puts -nonewline $f "1234567\n\n\n\n\nA"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "1234567\r\n\r\n\r\n\r\n\r" "1234567\r\n\r\n\r\n\r\n\r\nA"]
+test chan-io-4.5 {TranslateOutputEOL: crlf} {
+ # Check for overflow of the destination buffer
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -buffersize 12
+ chan puts -nonewline $f "12345678901\n456789012345678901234"
+ chan close $f
+ set x [contents $path(test1)]
+} "12345678901\r\n456789012345678901234"
+
+test chan-io-5.1 {CheckFlush: not full} {
+ set f [open $path(test1) w]
+ chan configure $f
+ chan puts -nonewline $f "12345678901234567890"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "" "12345678901234567890"]
+test chan-io-5.2 {CheckFlush: full} {
+ set f [open $path(test1) w]
+ chan configure $f -buffersize 16
+ chan puts -nonewline $f "12345678901234567890"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "1234567890123456" "12345678901234567890"]
+test chan-io-5.3 {CheckFlush: not line} {
+ set f [open $path(test1) w]
+ chan configure $f -buffering line
+ chan puts -nonewline $f "12345678901234567890"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "" "12345678901234567890"]
+test chan-io-5.4 {CheckFlush: line} {
+ set f [open $path(test1) w]
+ chan configure $f -buffering line -translation lf -encoding ascii
+ chan puts -nonewline $f "1234567890\n1234567890"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "1234567890\n1234567890" "1234567890\n1234567890"]
+test chan-io-5.5 {CheckFlush: none} {
+ set f [open $path(test1) w]
+ chan configure $f -buffering none
+ chan puts -nonewline $f "1234567890"
+ set x [list [contents $path(test1)]]
+ chan close $f
+ lappend x [contents $path(test1)]
+} [list "1234567890" "1234567890"]
+
+test chan-io-6.1 {Tcl_GetsObj: working} -body {
+ set f [open $path(test1) w]
+ chan puts $f "foo\nboo"
+ chan close $f
+ set f [open $path(test1)]
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result {foo}
+test chan-io-6.2 {Tcl_GetsObj: CheckChannelErrors() != 0} emptyTest {
+ # no test, need to cause an async error.
+} {}
+test chan-io-6.3 {Tcl_GetsObj: how many have we used?} -body {
+ # if (bufPtr != NULL) {oldRemoved = bufPtr->nextRemoved}
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f "abc\ndefg"
+ chan close $f
+ set f [open $path(test1)]
+ list [chan tell $f] [chan gets $f line] [chan tell $f] [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {0 3 5 4 defg}
+test chan-io-6.4 {Tcl_GetsObj: encoding == NULL} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation binary
+ chan puts $f "\x81\u1234\0"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation binary
+ list [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 3 "\x81\x34\x00"]
+test chan-io-6.5 {Tcl_GetsObj: encoding != NULL} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation binary
+ chan puts $f "\x88\xea\x92\x9a"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding shiftjis
+ list [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 2 "\u4e00\u4e01"]
+set a "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
+append a $a
+append a $a
+test chan-io-6.6 {Tcl_GetsObj: loop test} -body {
+ # if (dst >= dstEnd)
+ set f [open $path(test1) w]
+ chan puts $f $a
+ chan puts $f hi
+ chan close $f
+ set f [open $path(test1)]
+ list [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 256 $a]
+test chan-io-6.7 {Tcl_GetsObj: error in input} -constraints {stdio openpipe} -body {
+ # if (FilterInputBytes(chanPtr, &gs) != 0)
+ set f [openpipe w+ $path(cat)]
+ chan puts -nonewline $f "hi\nwould"
+ chan flush $f
+ chan gets $f
+ chan configure $f -blocking 0
+ chan gets $f line
+} -cleanup {
+ chan close $f
+} -result {-1}
+test chan-io-6.8 {Tcl_GetsObj: remember if EOF is seen} -body {
+ set f [open $path(test1) w]
+ chan puts $f "abcdef\x1aghijk\nwombat"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -eofchar \x1a
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {6 abcdef -1 {}}
+test chan-io-6.9 {Tcl_GetsObj: remember if EOF is seen} -body {
+ set f [open $path(test1) w]
+ chan puts $f "abcdefghijk\nwom\u001abat"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -eofchar \x1a
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {11 abcdefghijk 3 wom}
+# Comprehensive tests
+test chan-io-6.10 {Tcl_GetsObj: lf mode: no chars} -body {
+ set f [open $path(test1) w]
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation lf
+ list [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {-1 {}}
+test chan-io-6.11 {Tcl_GetsObj: lf mode: lone \n} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation lf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.12 {Tcl_GetsObj: lf mode: lone \r} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation lf
+ set x [list [chan gets $f line] $line [chan gets $f line] $line]
+} -cleanup {
+ chan close $f
+} -result [list 1 "\r" -1 ""]
+test chan-io-6.13 {Tcl_GetsObj: lf mode: 1 char} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f a
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation lf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.14 {Tcl_GetsObj: lf mode: 1 char followed by EOL} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation lf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.15 {Tcl_GetsObj: lf mode: several chars} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation lf
+ list [chan gets $f line] $line [chan gets $f line] $line \
+ [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 4 "abcd" 10 "efgh\rijkl\r" 4 "mnop" -1 ""]
+test chan-io-6.16 {Tcl_GetsObj: cr mode: no chars} -body {
+ set f [open $path(test1) w]
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation cr
+ list [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {-1 {}}
+test chan-io-6.17 {Tcl_GetsObj: cr mode: lone \n} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation cr
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 1 "\n" -1 ""]
+test chan-io-6.18 {Tcl_GetsObj: cr mode: lone \r} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation cr
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.19 {Tcl_GetsObj: cr mode: 1 char} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f a
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation cr
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.20 {Tcl_GetsObj: cr mode: 1 char followed by EOL} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation cr
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.21 {Tcl_GetsObj: cr mode: several chars} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation cr
+ list [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 9 "abcd\nefgh" 4 "ijkl" 5 "\nmnop" -1 ""]
+test chan-io-6.22 {Tcl_GetsObj: crlf mode: no chars} -body {
+ set f [open $path(test1) w]
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ list [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {-1 {}}
+test chan-io-6.23 {Tcl_GetsObj: crlf mode: lone \n} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 1 "\n" -1 ""]
+test chan-io-6.24 {Tcl_GetsObj: crlf mode: lone \r} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 1 "\r" -1 ""]
+test chan-io-6.25 {Tcl_GetsObj: crlf mode: \r\r} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 2 "\r\r" -1 ""]
+test chan-io-6.26 {Tcl_GetsObj: crlf mode: \r\n} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.27 {Tcl_GetsObj: crlf mode: 1 char} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f a
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.28 {Tcl_GetsObj: crlf mode: 1 char followed by EOL} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\r\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.29 {Tcl_GetsObj: crlf mode: several chars} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ list [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 14 "abcd\nefgh\rijkl" 4 "mnop" -1 ""]
+test chan-io-6.30 {Tcl_GetsObj: crlf mode: buffer exhausted} -constraints {testchannel} -body {
+ # if (eol >= dstEnd)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456789012345\r\nabcdefghijklmnoprstuvwxyz"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf -buffersize 16
+ list [chan gets $f line] $line [testchannel inputbuffered $f]
+} -cleanup {
+ chan close $f
+} -result [list 15 "123456789012345" 15]
+test chan-io-6.31 {Tcl_GetsObj: crlf mode: buffer exhausted, blocked} -setup {
+ set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # (FilterInputBytes() != 0)
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {crlf lf} -buffering none
+ chan puts -nonewline $f "bbbbbbbbbbbbbb\r\n123456789012345\r"
+ chan configure $f -buffersize 16
+ lappend x [chan gets $f]
+ chan configure $f -blocking 0
+ lappend x [chan gets $f line] $line [chan blocked $f] \
+ [testchannel inputbuffered $f]
+} -cleanup {
+ chan close $f
+} -result {bbbbbbbbbbbbbb -1 {} 1 16}
+test chan-io-6.32 {Tcl_GetsObj: crlf mode: buffer exhausted, more data} -constraints {testchannel} -body {
+ # not (FilterInputBytes() != 0)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456789012345\r\n123"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf -buffersize 16
+ list [chan gets $f line] $line [chan tell $f] [testchannel inputbuffered $f]
+} -cleanup {
+ chan close $f
+} -result {15 123456789012345 17 3}
+test chan-io-6.33 {Tcl_GetsObj: crlf mode: buffer exhausted, at eof} -body {
+ # eol still equals dstEnd
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456789012345\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf -buffersize 16
+ list [chan gets $f line] $line [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result [list 16 "123456789012345\r" 1]
+test chan-io-6.34 {Tcl_GetsObj: crlf mode: buffer exhausted, not followed by \n} -body {
+ # not (*eol == '\n')
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456789012345\rabcd\r\nefg"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf -buffersize 16
+ list [chan gets $f line] $line [chan tell $f]
+} -cleanup {
+ chan close $f
+} -result [list 20 "123456789012345\rabcd" 22]
+test chan-io-6.35 {Tcl_GetsObj: auto mode: no chars} -body {
+ set f [open $path(test1) w]
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ list [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {-1 {}}
+test chan-io-6.36 {Tcl_GetsObj: auto mode: lone \n} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.37 {Tcl_GetsObj: auto mode: lone \r} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.38 {Tcl_GetsObj: auto mode: \r\r} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ list [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {0 {} 0 {} -1 {}}
+test chan-io-6.39 {Tcl_GetsObj: auto mode: \r\n} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.40 {Tcl_GetsObj: auto mode: 1 char} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f a
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.41 {Tcl_GetsObj: auto mode: 1 char followed by EOL} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\r\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.42 {Tcl_GetsObj: auto mode: several chars} -setup {
+ set x ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ lappend x [chan gets $f line] $line [chan gets $f line] $line
+ lappend x [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {4 abcd 4 efgh 4 ijkl 4 mnop -1 {}}
+test chan-io-6.43 {Tcl_GetsObj: input saw cr} -setup {
+ set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # if (chanPtr->flags & INPUT_SAW_CR)
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {auto lf} -buffering none
+ chan puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+ chan configure $f -buffersize 16
+ lappend x [chan gets $f]
+ chan configure $f -blocking 0
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+ chan configure $f -blocking 1
+ chan puts -nonewline $f "\nabcd\refg\x1a"
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+ lappend x [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {bbbbbbbbbbbbbbb 15 123456789abcdef 1 4 abcd 0 3 efg}
+test chan-io-6.44 {Tcl_GetsObj: input saw cr, not followed by cr} -setup {
+ set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # not (*eol == '\n')
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {auto lf} -buffering none
+ chan puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+ chan configure $f -buffersize 16
+ lappend x [chan gets $f]
+ chan configure $f -blocking 0
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+ chan configure $f -blocking 1
+ chan puts -nonewline $f "abcd\refg\x1a"
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+ lappend x [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {bbbbbbbbbbbbbbb 15 123456789abcdef 1 4 abcd 0 3 efg}
+test chan-io-6.45 {Tcl_GetsObj: input saw cr, skip right number of bytes} -setup {
+ set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # Tcl_ExternalToUtf()
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {auto lf} -buffering none
+ chan configure $f -encoding unicode
+ chan puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+ chan configure $f -buffersize 16
+ chan gets $f
+ chan configure $f -blocking 0
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+ chan configure $f -blocking 1
+ chan puts -nonewline $f "\nabcd\refg"
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+} -cleanup {
+ chan close $f
+} -result {15 123456789abcdef 1 4 abcd 0}
+test chan-io-6.46 {Tcl_GetsObj: input saw cr, followed by just \n should give eof} -setup {
+ set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # memmove()
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {auto lf} -buffering none
+ chan puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+ chan configure $f -buffersize 16
+ chan gets $f
+ chan configure $f -blocking 0
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+ chan configure $f -blocking 1
+ chan puts -nonewline $f "\n\x1a"
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+} -cleanup {
+ chan close $f
+} -result {15 123456789abcdef 1 -1 {} 0}
+test chan-io-6.47 {Tcl_GetsObj: auto mode: \r at end of buffer, peek for \n} -constraints {testchannel} -body {
+ # (eol == dstEnd)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456789012345\r\nabcdefghijklmnopq"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto -buffersize 16
+ list [chan gets $f] [testchannel inputbuffered $f]
+} -cleanup {
+ chan close $f
+} -result {123456789012345 15}
+test chan-io-6.48 {Tcl_GetsObj: auto mode: \r at end of buffer, no more avail} -constraints {testchannel} -body {
+ # PeekAhead() did not get any, so (eol >= dstEnd)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456789012345\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto -buffersize 16
+ list [chan gets $f] [testchannel queuedcr $f]
+} -cleanup {
+ chan close $f
+} -result {123456789012345 1}
+test chan-io-6.49 {Tcl_GetsObj: auto mode: \r followed by \n} -constraints {testchannel} -body {
+ # if (*eol == '\n') {skip++}
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456\r\n78901"
+ chan close $f
+ set f [open $path(test1)]
+ list [chan gets $f] [testchannel queuedcr $f] [chan tell $f] [chan gets $f]
+} -cleanup {
+ chan close $f
+} -result {123456 0 8 78901}
+test chan-io-6.50 {Tcl_GetsObj: auto mode: \r not followed by \n} -constraints {testchannel} -body {
+ # not (*eol == '\n')
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456\r78901"
+ chan close $f
+ set f [open $path(test1)]
+ list [chan gets $f] [testchannel queuedcr $f] [chan tell $f] [chan gets $f]
+} -cleanup {
+ chan close $f
+} -result {123456 0 7 78901}
+test chan-io-6.51 {Tcl_GetsObj: auto mode: \n} -body {
+ # else if (*eol == '\n') {goto gotoeol;}
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456\n78901"
+ chan close $f
+ set f [open $path(test1)]
+ list [chan gets $f] [chan tell $f] [chan gets $f]
+} -cleanup {
+ chan close $f
+} -result {123456 7 78901}
+test chan-io-6.52 {Tcl_GetsObj: saw EOF character} -constraints {testchannel} -body {
+ # if (eof != NULL)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "123456\x1ak9012345\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -eofchar \x1a
+ list [chan gets $f] [testchannel queuedcr $f] [chan tell $f] [chan gets $f]
+} -cleanup {
+ chan close $f
+} -result {123456 0 6 {}}
+test chan-io-6.53 {Tcl_GetsObj: device EOF} -body {
+ # didn't produce any bytes
+ set f [open $path(test1) w]
+ chan close $f
+ set f [open $path(test1)]
+ list [chan gets $f line] $line [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {-1 {} 1}
+test chan-io-6.54 {Tcl_GetsObj: device EOF} -body {
+ # got some bytes before EOF.
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abc
+ chan close $f
+ set f [open $path(test1)]
+ list [chan gets $f line] $line [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {3 abc 1}
+test chan-io-6.55 {Tcl_GetsObj: overconverted} -body {
+ # Tcl_ExternalToUtf(), make sure state updated
+ set f [open $path(test1) w]
+ chan configure $f -encoding iso2022-jp
+ chan puts $f "there\u4e00ok\n\u4e01more bytes\nhere"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding iso2022-jp
+ list [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 8 "there\u4e00ok" 11 "\u4e01more bytes" 4 "here"]
+test chan-io-6.56 {Tcl_GetsObj: incomplete lines should disable file events} -setup {
+ update
+ variable x {}
+} -constraints {stdio openpipe fileevent} -body {
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -buffering none
+ chan puts -nonewline $f "foobar"
+ chan configure $f -blocking 0
+ after 500 [namespace code {
+ lappend x timeout
+ }]
+ chan event $f readable [namespace code {
+ lappend x [chan gets $f]
+ }]
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ chan configure $f -blocking 1
+ chan puts -nonewline $f "baz\n"
+ after 500 [namespace code {
+ lappend x timeout
+ }]
+ chan configure $f -blocking 0
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ chan close $f
+} -result {{} timeout foobarbaz timeout}
+
+test chan-io-7.1 {FilterInputBytes: split up character at end of buffer} -body {
+ # (result == TCL_CONVERT_MULTIBYTE)
+ set f [open $path(test1) w]
+ chan configure $f -encoding shiftjis
+ chan puts $f "1234567890123\uff10\uff11\uff12\uff13\uff14\nend"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding shiftjis -buffersize 16
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result "1234567890123\uff10\uff11\uff12\uff13\uff14"
+test chan-io-7.2 {FilterInputBytes: split up character in middle of buffer} -body {
+ # (bufPtr->nextAdded < bufPtr->bufLength)
+ set f [open $path(test1) w]
+ chan configure $f -encoding binary
+ chan puts -nonewline $f "1234567890\n123\x82\x4f\x82\x50\x82"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding shiftjis
+ list [chan gets $f line] $line [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {10 1234567890 0}
+test chan-io-7.3 {FilterInputBytes: split up character at EOF} -setup {
+ set x ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ chan configure $f -encoding binary
+ chan puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding shiftjis
+ lappend x [chan gets $f line] $line
+ lappend x [chan tell $f] [testchannel inputbuffered $f] [chan eof $f]
+ lappend x [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result [list 15 "1234567890123\uff10\uff11" 18 0 1 -1 ""]
+test chan-io-7.4 {FilterInputBytes: recover from split up character} -setup {
+ variable x ""
+} -constraints {stdio openpipe fileevent} -body {
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -encoding binary -buffering none
+ chan puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
+ chan configure $f -encoding shiftjis -blocking 0
+ chan event $f read [namespace code {
+ lappend x [chan gets $f line] $line [chan blocked $f]
+ }]
+ vwait [namespace which -variable x]
+ chan configure $f -encoding binary -blocking 1
+ chan puts $f "\x51\x82\x52"
+ chan configure $f -encoding shiftjis
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ chan close $f
+} -result [list -1 "" 1 17 "1234567890123\uff10\uff11\uff12\uff13" 0]
+
+test chan-io-8.1 {PeekAhead: only go to device if no more cached data} -constraints {testchannel} -body {
+ # (bufPtr->nextPtr == NULL)
+ set f [open $path(test1) w]
+ chan configure $f -encoding ascii -translation lf
+ chan puts -nonewline $f "123456789012345\r\n2345678"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding ascii -translation auto -buffersize 16
+ # here
+ chan gets $f
+ testchannel inputbuffered $f
+} -cleanup {
+ chan close $f
+} -result 7
+test chan-io-8.2 {PeekAhead: only go to device if no more cached data} -setup {
+ variable x {}
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # not (bufPtr->nextPtr == NULL)
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation lf -encoding ascii -buffering none
+ chan puts -nonewline $f "123456789012345\r\nbcdefghijklmnopqrstuvwxyz"
+ chan event $f read [namespace code {
+ lappend x [chan gets $f line] $line [testchannel inputbuffered $f]
+ }]
+ chan configure $f -encoding unicode -buffersize 16 -blocking 0
+ vwait [namespace which -variable x]
+ chan configure $f -translation auto -encoding ascii -blocking 1
+ # here
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ chan close $f
+} -result {-1 {} 42 15 123456789012345 25}
+test chan-io-8.3 {PeekAhead: no cached data available} -constraints {stdio testchannel openpipe fileevent} -body {
+ # (bytesLeft == 0)
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {auto binary}
+ chan puts -nonewline $f "abcdefghijklmno\r"
+ chan flush $f
+ list [chan gets $f line] $line [testchannel queuedcr $f]
+} -cleanup {
+ chan close $f
+} -result {15 abcdefghijklmno 1}
+set a "123456789012345678901234567890"
+append a "123456789012345678901234567890"
+append a "1234567890123456789012345678901"
+test chan-io-8.4 {PeekAhead: cached data available in this buffer} -body {
+ # not (bytesLeft == 0)
+ set f [open $path(test1) w+]
+ chan configure $f -translation binary
+ chan puts $f "${a}\r\nabcdef"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding binary -translation auto
+ # "${a}\r" was converted in one operation (because ENCODING_LINESIZE is
+ # 30). To check if "\n" follows, calls PeekAhead and determines that
+ # cached data is available in buffer w/o having to call driver.
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result $a
+unset a
+test chan-io-8.5 {PeekAhead: don't peek if last read was short} -constraints {stdio testchannel openpipe fileevent} -body {
+ # (bufPtr->nextAdded < bufPtr->length)
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {auto binary}
+ chan puts -nonewline $f "abcdefghijklmno\r"
+ chan flush $f
+ # here
+ list [chan gets $f line] $line [testchannel queuedcr $f]
+} -cleanup {
+ chan close $f
+} -result {15 abcdefghijklmno 1}
+test chan-io-8.6 {PeekAhead: change to non-blocking mode} -constraints {stdio testchannel openpipe fileevent} -body {
+ # ((chanPtr->flags & CHANNEL_NONBLOCKING) == 0)
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {auto binary} -buffersize 16
+ chan puts -nonewline $f "abcdefghijklmno\r"
+ chan flush $f
+ # here
+ list [chan gets $f line] $line [testchannel queuedcr $f]
+} -cleanup {
+ chan close $f
+} -result {15 abcdefghijklmno 1}
+test chan-io-8.7 {PeekAhead: cleanup} -setup {
+ set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # Make sure bytes are removed from buffer.
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -translation {auto binary} -buffering none
+ chan puts -nonewline $f "abcdefghijklmno\r"
+ # here
+ lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+ chan puts -nonewline $f "\x1a"
+ lappend x [chan gets $f line] $line
+} -cleanup {
+ chan close $f
+} -result {15 abcdefghijklmno 1 -1 {}}
+
+test chan-io-9.1 {CommonGetsCleanup} emptyTest {
+} {}
+
+test chan-io-10.1 {Tcl_ReadChars: CheckChannelErrors} emptyTest {
+ # no test, need to cause an async error.
+} {}
+test chan-io-10.2 {Tcl_ReadChars: loop until enough copied} -body {
+ # one time
+ # for (copied = 0; (unsigned) toRead > 0; )
+ set f [open $path(test1) w]
+ chan puts $f abcdefghijklmnop
+ chan close $f
+ set f [open $path(test1)]
+ chan read $f 5
+} -cleanup {
+ chan close $f
+} -result {abcde}
+test chan-io-10.3 {Tcl_ReadChars: loop until enough copied} -body {
+ # multiple times
+ # for (copied = 0; (unsigned) toRead > 0; )
+ set f [open $path(test1) w]
+ chan puts $f abcdefghijklmnopqrstuvwxyz
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -buffersize 16
+ # here
+ chan read $f 19
+} -cleanup {
+ chan close $f
+} -result {abcdefghijklmnopqrs}
+test chan-io-10.4 {Tcl_ReadChars: no more in channel buffer} -body {
+ # (copiedNow < 0)
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abcdefghijkl
+ chan close $f
+ set f [open $path(test1)]
+ # here
+ chan read $f 1000
+} -cleanup {
+ chan close $f
+} -result {abcdefghijkl}
+test chan-io-10.5 {Tcl_ReadChars: stop on EOF} -body {
+ # (chanPtr->flags & CHANNEL_EOF)
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abcdefghijkl
+ chan close $f
+ set f [open $path(test1)]
+ # here
+ chan read $f 1000
+} -cleanup {
+ chan close $f
+} -result {abcdefghijkl}
+
+test chan-io-11.1 {ReadBytes: want to read a lot} -body {
+ # ((unsigned) toRead > (unsigned) srcLen)
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abcdefghijkl
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding binary
+ # here
+ chan read $f 1000
+} -cleanup {
+ chan close $f
+} -result {abcdefghijkl}
+test chan-io-11.2 {ReadBytes: want to read all} -body {
+ # ((unsigned) toRead > (unsigned) srcLen)
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abcdefghijkl
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -encoding binary
+ # here
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result {abcdefghijkl}
+test chan-io-11.3 {ReadBytes: allocate more space} -body {
+ # (toRead > length - offset - 1)
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abcdefghijklmnopqrstuvwxyz
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -buffersize 16 -encoding binary
+ # here
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result {abcdefghijklmnopqrstuvwxyz}
+test chan-io-11.4 {ReadBytes: EOF char found} -body {
+ # (TranslateInputEOL() != 0)
+ set f [open $path(test1) w]
+ chan puts $f abcdefghijklmnopqrstuvwxyz
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -eofchar m -encoding binary
+ # here
+ list [chan read $f] [chan eof $f] [chan read $f] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abcdefghijkl 1 {} 1}
+
+test chan-io-12.1 {ReadChars: want to read a lot} -body {
+ # ((unsigned) toRead > (unsigned) srcLen)
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abcdefghijkl
+ chan close $f
+ set f [open $path(test1)]
+ # here
+ chan read $f 1000
+} -cleanup {
+ chan close $f
+} -result {abcdefghijkl}
+test chan-io-12.2 {ReadChars: want to read all} -body {
+ # ((unsigned) toRead > (unsigned) srcLen)
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abcdefghijkl
+ chan close $f
+ set f [open $path(test1)]
+ # here
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result {abcdefghijkl}
+test chan-io-12.3 {ReadChars: allocate more space} -body {
+ # (toRead > length - offset - 1)
+ set f [open $path(test1) w]
+ chan puts -nonewline $f abcdefghijklmnopqrstuvwxyz
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -buffersize 16
+ # here
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result {abcdefghijklmnopqrstuvwxyz}
+test chan-io-12.4 {ReadChars: split-up char} -setup {
+ variable x {}
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # (srcRead == 0)
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -encoding binary -buffering none -buffersize 16
+ chan puts -nonewline $f "123456789012345\x96"
+ chan configure $f -encoding shiftjis -blocking 0
+ chan event $f read [namespace code {
+ lappend x [chan read $f] [testchannel inputbuffered $f]
+ }]
+ chan configure $f -encoding shiftjis
+ vwait [namespace which -variable x]
+ chan configure $f -encoding binary -blocking 1
+ chan puts -nonewline $f "\x7b"
+ after 500 ;# Give the cat process time to catch up
+ chan configure $f -encoding shiftjis -blocking 0
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ chan close $f
+} -result [list "123456789012345" 1 "\u672c" 0]
+test chan-io-12.5 {ReadChars: chan events on partial characters} -setup {
+ variable x {}
+} -constraints {stdio openpipe fileevent} -body {
+ set path(test1) [makeFile {
+ chan configure stdout -encoding binary -buffering none
+ chan gets stdin; chan puts -nonewline "\xe7"
+ chan gets stdin; chan puts -nonewline "\x89"
+ chan gets stdin; chan puts -nonewline "\xa6"
+ } test1]
+ set f [openpipe r+ $path(test1)]
+ chan event $f readable [namespace code {
+ lappend x [chan read $f]
+ if {[chan eof $f]} {
+ lappend x eof
+ }
+ }]
+ chan puts $f "go1"
+ chan flush $f
+ chan configure $f -blocking 0 -encoding utf-8
+ vwait [namespace which -variable x]
+ after 500 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ chan puts $f "go2"
+ chan flush $f
+ vwait [namespace which -variable x]
+ after 500 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ chan puts $f "go3"
+ chan flush $f
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ lappend x [catch {chan close $f} msg] $msg
+} -result "{} timeout {} timeout \u7266 {} eof 0 {}"
+
+test chan-io-13.1 {TranslateInputEOL: cr mode} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\rdef\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation cr
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\ndef\n"
+test chan-io-13.2 {TranslateInputEOL: crlf mode} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\r\ndef\r\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\ndef\n"
+test chan-io-13.3 {TranslateInputEOL: crlf mode: naked cr} -body {
+ # (src >= srcMax)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\r\ndef\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\ndef\r"
+test chan-io-13.4 {TranslateInputEOL: crlf mode: cr followed by not \n} -body {
+ # (src >= srcMax)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\r\ndef\rfgh"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\ndef\rfgh"
+test chan-io-13.5 {TranslateInputEOL: crlf mode: naked lf} -body {
+ # (src >= srcMax)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\r\ndef\nfgh"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation crlf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\ndef\nfgh"
+test chan-io-13.6 {TranslateInputEOL: auto mode: saw cr in last segment} -setup {
+ variable x {}
+ variable y {}
+} -constraints {stdio testchannel openpipe fileevent} -body {
+ # (chanPtr->flags & INPUT_SAW_CR)
+ # This test may fail on slower machines.
+ set f [openpipe w+ $path(cat)]
+ chan configure $f -blocking 0 -buffering none -translation {auto lf}
+ chan event $f read [namespace code {
+ lappend x [chan read $f] [testchannel queuedcr $f]
+ }]
+ chan puts -nonewline $f "abcdefghj\r"
+ after 500 [namespace code {set y ok}]
+ vwait [namespace which -variable y]
+ chan puts -nonewline $f "\n01234"
+ after 500 [namespace code {set y ok}]
+ vwait [namespace which -variable y]
+ return $x
+} -cleanup {
+ chan close $f
+} -result [list "abcdefghj\n" 1 "01234" 0]
+test chan-io-13.7 {TranslateInputEOL: auto mode: naked \r} -constraints {testchannel openpipe} -body {
+ # (src >= srcMax)
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\r"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ list [chan read $f] [testchannel queuedcr $f]
+} -cleanup {
+ chan close $f
+} -result [list "abcd\n" 1]
+test chan-io-13.8 {TranslateInputEOL: auto mode: \r\n} -body {
+ # (*src == '\n')
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\r\ndef"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\ndef"
+test chan-io-13.9 {TranslateInputEOL: auto mode: \r followed by not \n} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\rdef"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\ndef"
+test chan-io-13.10 {TranslateInputEOL: auto mode: \n} -body {
+ # not (*src == '\r')
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\ndef"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\ndef"
+test chan-io-13.11 {TranslateInputEOL: EOF char} -body {
+ # (*chanPtr->inEofChar != '\0')
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "abcd\ndefgh"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto -eofchar e
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "abcd\nd"
+test chan-io-13.12 {TranslateInputEOL: find EOF char in src} -body {
+ # (*chanPtr->inEofChar != '\0')
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "\r\n\r\n\r\nab\r\n\r\ndef\r\n\r\n\r\n"
+ chan close $f
+ set f [open $path(test1)]
+ chan configure $f -translation auto -eofchar e
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "\n\n\nab\n\nd"
+
+# Test standard handle management. The functions tested are Tcl_SetStdChannel
+# and Tcl_GetStdChannel. Incidentally we are also testing channel table
+# management.
+
+if {[testConstraint testchannel]} {
+ set consoleFileNames [lsort [testchannel open]]
+} else {
+ # just to avoid an error
+ set consoleFileNames [list]
+}
+
+test chan-io-14.1 {Tcl_SetStdChannel and Tcl_GetStdChannel} {testchannel} {
+ set result ""
+ lappend result [chan configure stdin -buffering]
+ lappend result [chan configure stdout -buffering]
+ lappend result [chan configure stderr -buffering]
+ lappend result [lsort [testchannel open]]
+} [list line line none $consoleFileNames]
+test chan-io-14.2 {Tcl_SetStdChannel and Tcl_GetStdChannel} -setup {
+ interp create x
+ set result ""
+} -body {
+ lappend result [x eval {chan configure stdin -buffering}]
+ lappend result [x eval {chan configure stdout -buffering}]
+ lappend result [x eval {chan configure stderr -buffering}]
+} -cleanup {
+ interp delete x
+} -result {line line none}
+set path(test3) [makeFile {} test3]
+test chan-io-14.3 {Tcl_SetStdChannel & Tcl_GetStdChannel} -constraints {exec openpipe} -body {
+ set f [open $path(test1) w]
+ chan puts -nonewline $f {
+ chan close stdin
+ chan close stdout
+ chan close stderr
+ set f [}
+ chan puts $f [list open $path(test1) r]]
+ chan puts $f "set f2 \[[list open $path(test2) w]]"
+ chan puts $f "set f3 \[[list open $path(test3) w]]"
+ chan puts $f { chan puts stdout [chan gets stdin]
+ chan puts stdout out
+ chan puts stderr err
+ chan close $f
+ chan close $f2
+ chan close $f3
+ }
+ chan close $f
+ set result [exec [interpreter] $path(test1)]
+ set f [open $path(test2) r]
+ set f2 [open $path(test3) r]
+ lappend result [chan read $f] [chan read $f2]
+} -cleanup {
+ chan close $f
+ chan close $f2
+} -result {{
+out
+} {err
+}}
+# This test relies on the fact that stdout is used before stderr.
+test chan-io-14.4 {Tcl_SetStdChannel & Tcl_GetStdChannel} -constraints {exec} -body {
+ set f [open $path(test1) w]
+ chan puts -nonewline $f { chan close stdin
+ chan close stdout
+ chan close stderr
+ set f [}
+ chan puts $f [list open $path(test1) r]]
+ chan puts $f "set f2 \[[list open $path(test2) w]]"
+ chan puts $f "set f3 \[[list open $path(test3) w]]"
+ chan puts $f {
+ chan puts stdout [chan gets stdin]
+ chan puts stdout $f2
+ chan puts stderr $f3
+ chan close $f
+ chan close $f2
+ chan close $f3
+ }
+ chan close $f
+ set result [exec [interpreter] $path(test1)]
+ set f [open $path(test2) r]
+ set f2 [open $path(test3) r]
+ lappend result [chan read $f] [chan read $f2]
+} -cleanup {
+ chan close $f
+ chan close $f2
+} -result {{ chan close stdin
+stdout
+} {stderr
+}}
+catch {interp delete z}
+test chan-io-14.5 {Tcl_GetChannel: stdio name translation} -setup {
+ interp create z
+} -body {
+ chan eof stdin
+ catch {z eval chan flush stdin} msg1
+ catch {z eval chan close stdin} msg2
+ catch {z eval chan flush stdin} msg3
+ list $msg1 $msg2 $msg3
+} -cleanup {
+ interp delete z
+} -result {{channel "stdin" wasn't opened for writing} {} {can not find channel named "stdin"}}
+test chan-io-14.6 {Tcl_GetChannel: stdio name translation} -setup {
+ interp create z
+} -body {
+ chan eof stdout
+ catch {z eval chan flush stdout} msg1
+ catch {z eval chan close stdout} msg2
+ catch {z eval chan flush stdout} msg3
+ list $msg1 $msg2 $msg3
+} -cleanup {
+ interp delete z
+} -result {{} {} {can not find channel named "stdout"}}
+test chan-io-14.7 {Tcl_GetChannel: stdio name translation} -setup {
+ interp create z
+} -body {
+ chan eof stderr
+ catch {z eval chan flush stderr} msg1
+ catch {z eval chan close stderr} msg2
+ catch {z eval chan flush stderr} msg3
+ list $msg1 $msg2 $msg3
+} -cleanup {
+ interp delete z
+} -result {{} {} {can not find channel named "stderr"}}
+set path(script) [makeFile {} script]
+test chan-io-14.8 {reuse of stdio special channels} -setup {
+ file delete $path(script)
+ file delete $path(test1)
+} -constraints {stdio openpipe} -body {
+ set f [open $path(script) w]
+ chan puts -nonewline $f {
+ chan close stderr
+ set f [}
+ chan puts $f [list open $path(test1) w]]
+ chan puts -nonewline $f {
+ chan puts stderr hello
+ chan close $f
+ set f [}
+ chan puts $f [list open $path(test1) r]]
+ chan puts $f {
+ chan puts [chan gets $f]
+ }
+ chan close $f
+ set f [openpipe r $path(script)]
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result hello
+test chan-io-14.9 {reuse of stdio special channels} -setup {
+ file delete $path(script)
+ file delete $path(test1)
+} -constraints {stdio openpipe fileevent} -body {
+ set f [open $path(script) w]
+ chan puts $f {
+ array set path [lindex $argv 0]
+ set f [open $path(test1) w]
+ chan puts $f hello
+ chan close $f
+ chan close stderr
+ set f [open "|[list [info nameofexecutable] $path(cat) $path(test1)]" r]
+ chan puts [chan gets $f]
+ }
+ chan close $f
+ set f [openpipe r $path(script) [array get path]]
+ chan gets $f
+} -cleanup {
+ chan close $f
+ # Added delay to give Windows time to stop the spawned process and clean
+ # up its grip on the file test1. Added delete as proper test cleanup.
+ # The failing tests were 18.1 and 18.2 as first re-users of file "test1".
+ after [expr {[testConstraint win] ? 10000 : 500}]
+ file delete $path(script)
+ file delete $path(test1)
+} -result hello
+
+test chan-io-15.1 {Tcl_CreateChan CloseHandler} emptyTest {
+} {}
+
+test chan-io-16.1 {Tcl_DeleteChan CloseHandler} emptyTest {
+} {}
+
+# Test channel table management. The functions tested are GetChannelTable,
+# DeleteChannelTable, Tcl_RegisterChannel, Tcl_UnregisterChannel,
+# Tcl_GetChannel and Tcl_CreateChannel.
+#
+# These functions use "eof stdin" to ensure that the standard channels are
+# added to the channel table of the interpreter.
+
+test chan-io-17.1 {GetChannelTable, DeleteChannelTable on std handles} -setup {
+ set l ""
+} -constraints {testchannel} -body {
+ set l1 [testchannel refcount stdin]
+ chan eof stdin
+ interp create x
+ lappend l [expr {[testchannel refcount stdin] - $l1}]
+ x eval {chan eof stdin}
+ lappend l [expr {[testchannel refcount stdin] - $l1}]
+ interp delete x
+ lappend l [expr {[testchannel refcount stdin] - $l1}]
+} -result {0 1 0}
+test chan-io-17.2 {GetChannelTable, DeleteChannelTable on std handles} -setup {
+ set l ""
+} -constraints {testchannel} -body {
+ set l1 [testchannel refcount stdout]
+ chan eof stdin
+ interp create x
+ lappend l [expr {[testchannel refcount stdout] - $l1}]
+ x eval {chan eof stdout}
+ lappend l [expr {[testchannel refcount stdout] - $l1}]
+ interp delete x
+ lappend l [expr {[testchannel refcount stdout] - $l1}]
+} -result {0 1 0}
+test chan-io-17.3 {GetChannelTable, DeleteChannelTable on std handles} -setup {
+ set l ""
+} -constraints {testchannel} -body {
+ set l1 [testchannel refcount stderr]
+ chan eof stdin
+ interp create x
+ lappend l [expr {[testchannel refcount stderr] - $l1}]
+ x eval {chan eof stderr}
+ lappend l [expr {[testchannel refcount stderr] - $l1}]
+ interp delete x
+ lappend l [expr {[testchannel refcount stderr] - $l1}]
+} -result {0 1 0}
+
+test chan-io-18.1 {Tcl_RegisterChannel, Tcl_UnregisterChannel} -setup {
+ file delete -force $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ lappend l [lindex [testchannel info $f] 15]
+ chan close $f
+ if {[catch {lindex [testchannel info $f] 15} msg]} {
+ lappend l $msg
+ } else {
+ lappend l "very broken: $f found after being chan closed"
+ }
+ string equal $l [list 1 "can not find channel named \"$f\""]
+} -result 1
+test chan-io-18.2 {Tcl_RegisterChannel, Tcl_UnregisterChannel} -setup {
+ file delete -force $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ lappend l [lindex [testchannel info $f] 15]
+ interp create x
+ interp share "" $f x
+ lappend l [lindex [testchannel info $f] 15]
+ x eval chan close $f
+ lappend l [lindex [testchannel info $f] 15]
+ interp delete x
+ lappend l [lindex [testchannel info $f] 15]
+ chan close $f
+ if {[catch {lindex [testchannel info $f] 15} msg]} {
+ lappend l $msg
+ } else {
+ lappend l "very broken: $f found after being chan closed"
+ }
+ string equal $l [list 1 2 1 1 "can not find channel named \"$f\""]
+} -result 1
+test chan-io-18.3 {Tcl_RegisterChannel, Tcl_UnregisterChannel} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ lappend l [lindex [testchannel info $f] 15]
+ interp create x
+ interp share "" $f x
+ lappend l [lindex [testchannel info $f] 15]
+ interp delete x
+ lappend l [lindex [testchannel info $f] 15]
+ chan close $f
+ if {[catch {lindex [testchannel info $f] 15} msg]} {
+ lappend l $msg
+ } else {
+ lappend l "very broken: $f found after being chan closed"
+ }
+ string equal $l [list 1 2 1 "can not find channel named \"$f\""]
+} -result 1
+
+test chan-io-19.1 {Tcl_GetChannel->Tcl_GetStdChannel, standard handles} {
+ chan eof stdin
+} 0
+test chan-io-19.2 {testing Tcl_GetChannel, user opened handle} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan eof $f
+} -cleanup {
+ chan close $f
+} -result 0
+test chan-io-19.3 {Tcl_GetChannel, channel not found} -body {
+ chan eof file34
+} -returnCodes error -result {can not find channel named "file34"}
+test chan-io-19.4 {Tcl_CreateChannel, insertion into channel table} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ lappend l [chan eof $f]
+ chan close $f
+ if {[catch {lindex [testchannel info $f] 15} msg]} {
+ lappend l $msg
+ } else {
+ lappend l "very broken: $f found after being chan closed"
+ }
+ string equal $l [list 0 "can not find channel named \"$f\""]
+} -result 1
+
+test chan-io-20.1 {Tcl_CreateChannel: initial settings} -setup {
+ set old [encoding system]
+} -body {
+ set a [open $path(test2) w]
+ encoding system ascii
+ set f [open $path(test1) w]
+ chan configure $f -encoding
+} -cleanup {
+ encoding system $old
+ chan close $f
+ chan close $a
+} -result {ascii}
+test chan-io-20.2 {Tcl_CreateChannel: initial settings} -constraints {win} -body {
+ set f [open $path(test1) w+]
+ list [chan configure $f -eofchar] [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result [list [list \x1a ""] {auto crlf}]
+test chan-io-20.3 {Tcl_CreateChannel: initial settings} -constraints {unix} -body {
+ set f [open $path(test1) w+]
+ list [chan configure $f -eofchar] [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result {{{} {}} {auto lf}}
+test chan-io-20.5 {Tcl_CreateChannel: install channel in empty slot} -setup {
+ set path(stdout) [makeFile {} stdout]
+} -constraints {stdio openpipe} -body {
+ set f [open $path(script) w]
+ chan puts -nonewline $f {
+ chan close stdout
+ set f1 [}
+ chan puts $f [list open $path(stdout) w]]
+ chan puts $f {
+ chan configure $f1 -buffersize 777
+ chan puts stderr [chan configure stdout -buffersize]
+ }
+ chan close $f
+ set f [openpipe r $path(script)]
+ chan close $f
+} -cleanup {
+ removeFile $path(stdout)
+} -returnCodes error -result {777}
+
+test chan-io-21.1 {Chan CloseChannelsOnExit} emptyTest {
+} {}
+
+# Test management of attributes associated with a channel, such as its default
+# translation, its name and type, etc. The functions tested in this group are
+# Tcl_GetChannelName, Tcl_GetChannelType and Tcl_GetChannelFile.
+# Tcl_GetChannelInstanceData not tested because files do not use the instance
+# data.
+
+test chan-io-22.1 {Tcl_GetChannelMode} emptyTest {
+ # Not used anywhere in Tcl.
+} {}
+
+test chan-io-23.1 {Tcl_GetChannelName} -constraints {testchannel} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ set n [testchannel name $f]
+ expr {$n eq $f ? "ok" : "$n != $f"}
+} -cleanup {
+ chan close $f
+} -result ok
+
+test chan-io-24.1 {Tcl_GetChannelType} -constraints {testchannel} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ testchannel type $f
+} -cleanup {
+ chan close $f
+} -result "file"
+
+test chan-io-25.1 {Tcl_GetChannelHandle, input} -setup {
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f "1234567890\n098765432"
+ chan close $f
+ set f [open $path(test1) r]
+ chan gets $f
+ lappend l [testchannel inputbuffered $f]
+ lappend l [chan tell $f]
+} -cleanup {
+ chan close $f
+} -result {10 11}
+test chan-io-25.2 {Tcl_GetChannelHandle, output} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [chan tell $f]
+ chan flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [chan tell $f]
+} -cleanup {
+ chan close $f
+ file delete $path(test1)
+} -result {6 6 0 6}
+
+test chan-io-26.1 {Tcl_GetChannelInstanceData} -body {
+ # "pid" command uses Tcl_GetChannelInstanceData
+ # Don't care what pid is (but must be a number), just want to exercise it.
+ set f [openpipe r << exit]
+ pid $f
+} -constraints {stdio openpipe} -cleanup {
+ chan close $f
+} -match regexp -result {^\d+$}
+
+# Test flushing. The functions tested here are FlushChannel.
+
+test chan-io-27.1 {FlushChannel, no output buffered} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan flush $f
+ file size $path(test1)
+} -cleanup {
+ chan close $f
+} -result 0
+test chan-io-27.2 {FlushChannel, some output buffered} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f hello
+ lappend l [file size $path(test1)]
+ chan flush $f
+ lappend l [file size $path(test1)]
+ chan close $f
+ lappend l [file size $path(test1)]
+} -result {0 6 6}
+test chan-io-27.3 {FlushChannel, implicit flush on chan close} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f hello
+ lappend l [file size $path(test1)]
+ chan close $f
+ lappend l [file size $path(test1)]
+} -result {0 6}
+test chan-io-27.4 {FlushChannel, implicit flush when buffer fills} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan configure $f -buffersize 60
+ lappend l [file size $path(test1)]
+ for {set i 0} {$i < 12} {incr i} {
+ chan puts $f hello
+ }
+ lappend l [file size $path(test1)]
+ chan flush $f
+ lappend l [file size $path(test1)]
+} -cleanup {
+ chan close $f
+} -result {0 60 72}
+test chan-io-27.5 {FlushChannel, implicit flush when buffer fills and on chan close} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {unixOrPc} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -buffersize 60 -eofchar {}
+ lappend l [file size $path(test1)]
+ for {set i 0} {$i < 12} {incr i} {
+ chan puts $f hello
+ }
+ lappend l [file size $path(test1)]
+ chan close $f
+ lappend l [file size $path(test1)]
+} -result {0 60 72}
+set path(pipe) [makeFile {} pipe]
+set path(output) [makeFile {} output]
+test chan-io-27.6 {FlushChannel, async flushing, async chan close} -setup {
+ file delete $path(pipe)
+ file delete $path(output)
+} -constraints {stdio asyncPipeChan Close openpipe} -body {
+ set f [open $path(pipe) w]
+ chan puts $f "set f \[[list open $path(output) w]]"
+ chan puts $f {
+ chan configure $f -translation lf -buffering none -eofchar {}
+ while {![chan eof stdin]} {
+ after 20
+ chan puts -nonewline $f [chan read stdin 1024]
+ }
+ chan close $f
+ }
+ chan close $f
+ set x 01234567890123456789012345678901
+ for {set i 0} {$i < 11} {incr i} {
+ set x "$x$x"
+ }
+ set f [open $path(output) w]
+ chan close $f
+ set f [openpipe w $path(pipe)]
+ chan configure $f -blocking off
+ chan puts -nonewline $f $x
+ chan close $f
+ set counter 0
+ while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+ after 20 [list incr [namespace which -variable counter]]
+ vwait [namespace which -variable counter]
+ }
+ if {$counter == 1000} {
+ set result "file size only [file size $path(output)]"
+ } else {
+ set result ok
+ }
+} -result ok
+
+# Tests closing a channel. The functions tested are Chan CloseChannel and
+# Tcl_Chan Close.
+
+test chan-io-28.1 {Chan CloseChannel called when all references are dropped} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ interp create x
+ interp share "" $f x
+ lappend l [testchannel refcount $f]
+ x eval chan close $f
+ interp delete x
+ lappend l [testchannel refcount $f]
+} -cleanup {
+ chan close $f
+} -result {2 1}
+test chan-io-28.2 {Chan CloseChannel called when all references are dropped} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ interp create x
+ interp share "" $f x
+ chan puts -nonewline $f abc
+ chan close $f
+ x eval chan puts $f def
+ x eval chan close $f
+ interp delete x
+ set f [open $path(test1) r]
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result abcdef
+test chan-io-28.3 {Chan CloseChannel, not called before output queue is empty} -setup {
+ file delete $path(pipe)
+ file delete $path(output)
+} -constraints {stdio asyncPipeChan Close nonPortable openpipe} -body {
+ set f [open $path(pipe) w]
+ chan puts $f {
+ # Need to not have eof char appended on chan close, because the other
+ # side of the pipe already chan closed, so that writing would cause an
+ # error "invalid file".
+ chan configure stdout -eofchar {}
+ chan configure stderr -eofchar {}
+ set f [open $path(output) w]
+ chan configure $f -translation lf -buffering none
+ for {set x 0} {$x < 20} {incr x} {
+ after 20
+ chan puts -nonewline $f [chan read stdin 1024]
+ }
+ chan close $f
+ }
+ chan close $f
+ set x 01234567890123456789012345678901
+ for {set i 0} {$i < 11} {incr i} {
+ set x "$x$x"
+ }
+ set f [open $path(output) w]
+ chan close $f
+ set f [openpipe r+ $path(pipe)]
+ chan configure $f -blocking off -eofchar {}
+ chan puts -nonewline $f $x
+ chan close $f
+ set counter 0
+ while {([file size $path(output)] < 20480) && ($counter < 1000)} {
+ after 20 [list incr [namespace which -variable counter]]
+ vwait [namespace which -variable counter]
+ }
+ if {$counter == 1000} {
+ set result probably_broken
+ } else {
+ set result ok
+ }
+} -result ok
+test chan-io-28.4 {Tcl_Chan Close} -constraints {testchannel} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ lappend l [lsort [testchannel open]]
+ set f [open $path(test1) w]
+ lappend l [lsort [testchannel open]]
+ chan close $f
+ lappend l [lsort [testchannel open]]
+ set x [list $consoleFileNames \
+ [lsort [list {*}$consoleFileNames $f]] \
+ $consoleFileNames]
+ expr {$l eq $x ? "ok" : "{$l} != {$x}"}
+} -result ok
+test chan-io-28.5 {Tcl_Chan Close vs standard handles} -setup {
+ file delete $path(script)
+} -constraints {stdio unix testchannel openpipe} -body {
+ set f [open $path(script) w]
+ chan puts $f {
+ chan close stdin
+ chan puts [testchannel open]
+ }
+ chan close $f
+ set f [openpipe r $path(script)]
+ set l [chan gets $f]
+ chan close $f
+ lsort $l
+} -result {file1 file2}
+test chan-io-28.6 {Tcl_CloseEx (half-close) pipe} -setup {
+ set cat [makeFile {
+ fconfigure stdout -buffering line
+ while {[gets stdin line] >= 0} {puts $line}
+ puts DONE
+ exit 0
+ } cat.tcl]
+ variable done
+} -body {
+ set ff [openpipe r+ $cat]
+ puts $ff Hey
+ close $ff w
+ set timer [after 1000 [namespace code {set done Failed}]]
+ set acc {}
+ fileevent $ff readable [namespace code {
+ if {[gets $ff line] < 0} {
+ set done Succeeded
+ } else {
+ lappend acc $line
+ }
+ }]
+ vwait [namespace which -variable done]
+ after cancel $timer
+ close $ff r
+ list $done $acc
+} -cleanup {
+ removeFile cat.tcl
+} -result {Succeeded {Hey DONE}}
+test chan-io-28.7 {Tcl_CloseEx (half-close) socket} -setup {
+ set echo [makeFile {
+ proc accept {s args} {set ::sok $s}
+ set s [socket -server accept 0]
+ puts [lindex [fconfigure $s -sockname] 2]
+ flush stdout
+ vwait ::sok
+ fconfigure $sok -buffering line
+ while {[gets $sok line]>=0} {puts $sok $line}
+ puts $sok DONE
+ exit 0
+ } echo.tcl]
+} -body {
+ set ff [openpipe r $echo]
+ gets $ff port
+ set s [socket 127.0.0.1 $port]
+ puts $s Hey
+ close $s w
+ set timer [after 1000 [namespace code {set ::done Failed}]]
+ set acc {}
+ fileevent $s readable [namespace code {
+ if {[gets $s line]<0} {
+ set done Succeeded
+ } else {
+ lappend acc $line
+ }
+ }]
+ vwait [namespace which -variable done]
+ after cancel $timer
+ close $s r
+ close $ff
+ list $done $acc
+} -cleanup {
+ removeFile echo.tcl
+} -result {Succeeded {Hey DONE}}
+
+test chan-io-29.1 {Tcl_WriteChars, channel not writable} -body {
+ chan puts stdin hello
+} -returnCodes error -result {channel "stdin" wasn't opened for writing}
+test chan-io-29.2 {Tcl_WriteChars, empty string} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -eofchar {}
+ chan puts -nonewline $f ""
+ chan close $f
+ file size $path(test1)
+} -result 0
+test chan-io-29.3 {Tcl_WriteChars, nonempty string} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -eofchar {}
+ chan puts -nonewline $f hello
+ chan close $f
+ file size $path(test1)
+} -result 5
+test chan-io-29.4 {Tcl_WriteChars, buffering in full buffering mode} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -buffering full -eofchar {}
+ chan puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ chan flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+} -cleanup {
+ chan close $f
+} -result {6 0 0 6}
+test chan-io-29.5 {Tcl_WriteChars, buffering in line buffering mode} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -buffering line -eofchar {}
+ chan puts -nonewline $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ chan puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+} -cleanup {
+ chan close $f
+} -result {5 0 0 11}
+test chan-io-29.6 {Tcl_WriteChars, buffering in no buffering mode} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -buffering none -eofchar {}
+ chan puts -nonewline $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ chan puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+} -cleanup {
+ chan close $f
+} -result {0 5 0 11}
+test chan-io-29.7 {Tcl_Flush, full buffering} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -buffering full -eofchar {}
+ chan puts -nonewline $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ chan puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ chan flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+} -cleanup {
+ chan close $f
+} -result {5 0 11 0 0 11}
+test chan-io-29.8 {Tcl_Flush, full buffering} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -buffering line
+ chan puts -nonewline $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ chan flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ chan puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ chan flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+} -cleanup {
+ chan close $f
+} -result {5 0 0 5 0 11 0 11}
+test chan-io-29.9 {Tcl_Flush, channel not writable} -body {
+ chan flush stdin
+} -returnCodes error -result {channel "stdin" wasn't opened for writing}
+test chan-io-29.10 {Tcl_WriteChars, looping and buffering} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ set f2 [open $path(longfile) r]
+ for {set x 0} {$x < 10} {incr x} {
+ chan puts $f1 [chan gets $f2]
+ }
+ chan close $f2
+ chan close $f1
+ file size $path(test1)
+} -result 387
+test chan-io-29.11 {Tcl_WriteChars, no newline, implicit flush} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -eofchar {}
+ set f2 [open $path(longfile) r]
+ for {set x 0} {$x < 10} {incr x} {
+ chan puts -nonewline $f1 [chan gets $f2]
+ }
+ chan close $f1
+ chan close $f2
+ file size $path(test1)
+} -result 377
+test chan-io-29.12 {Tcl_WriteChars on a pipe} -setup {
+ file delete $path(test1)
+ file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 "set f1 \[[list open $path(longfile) r]]"
+ chan puts $f1 {
+ for {set x 0} {$x < 10} {incr x} {
+ chan puts [chan gets $f1]
+ }
+ }
+ chan close $f1
+ set f1 [openpipe r $path(pipe)]
+ set f2 [open $path(longfile) r]
+ set y ok
+ for {set x 0} {$x < 10} {incr x} {
+ set l1 [chan gets $f1]
+ set l2 [chan gets $f2]
+ if {$l1 ne $l2} {
+ set y broken:$x
+ }
+ }
+ return $y
+} -cleanup {
+ chan close $f1
+ chan close $f2
+} -result ok
+test chan-io-29.13 {Tcl_WriteChars to a pipe, line buffered} -setup {
+ file delete $path(test1)
+ file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {
+ chan puts [chan gets stdin]
+ chan puts [chan gets stdin]
+ }
+ chan close $f1
+ set y ok
+ set f1 [openpipe r+ $path(pipe)]
+ chan configure $f1 -buffering line
+ set f2 [open $path(longfile) r]
+ set line [chan gets $f2]
+ chan puts $f1 $line
+ set backline [chan gets $f1]
+ if {$line ne $backline} {
+ set y broken1
+ }
+ set line [chan gets $f2]
+ chan puts $f1 $line
+ set backline [chan gets $f1]
+ if {$line ne $backline} {
+ set y broken2
+ }
+ return $y
+} -cleanup {
+ chan close $f1
+ chan close $f2
+} -result ok
+test chan-io-29.14 {Tcl_WriteChars, buffering and implicit flush at chan close} -setup {
+ file delete $path(test3)
+} -body {
+ set f [open $path(test3) w]
+ chan puts -nonewline $f "Text1"
+ chan puts -nonewline $f " Text 2"
+ chan puts $f " Text 3"
+ chan close $f
+ set f [open $path(test3) r]
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result {Text1 Text 2 Text 3}
+test chan-io-29.15 {Tcl_Flush, channel not open for writing} -setup {
+ file delete $path(test1)
+ set fd [open $path(test1) w]
+ chan close $fd
+} -body {
+ set fd [open $path(test1) r]
+ chan flush $fd
+} -returnCodes error -cleanup {
+ catch {chan close $fd}
+} -match glob -result {channel "*" wasn't opened for writing}
+test chan-io-29.16 {Tcl_Flush on pipe opened only for reading} -setup {
+ set fd [openpipe r cat longfile]
+} -constraints {stdio openpipe} -body {
+ chan flush $fd
+} -returnCodes error -cleanup {
+ catch {chan close $fd}
+} -match glob -result {channel "*" wasn't opened for writing}
+test chan-io-29.17 {Tcl_WriteChars buffers, then Tcl_Flush flushes} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf
+ chan puts $f1 hello
+ chan puts $f1 hello
+ chan puts $f1 hello
+ chan flush $f1
+ file size $path(test1)
+} -cleanup {
+ chan close $f1
+} -result 18
+test chan-io-29.18 {Tcl_WriteChars and Tcl_Flush intermixed} -setup {
+ file delete $path(test1)
+ set x ""
+ set f1 [open $path(test1) w]
+} -body {
+ chan configure $f1 -translation lf
+ chan puts $f1 hello
+ chan puts $f1 hello
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [file size $path(test1)]
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [file size $path(test1)]
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [file size $path(test1)]
+} -cleanup {
+ chan close $f1
+} -result {18 24 30}
+test chan-io-29.19 {Explicit and implicit flushes} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ set x ""
+ chan puts $f1 hello
+ chan puts $f1 hello
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [file size $path(test1)]
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [file size $path(test1)]
+ chan puts $f1 hello
+ chan close $f1
+ lappend x [file size $path(test1)]
+} -result {18 24 30}
+test chan-io-29.20 {Implicit flush when buffer is full} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ set line "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+ for {set x 0} {$x < 100} {incr x} {
+ chan puts $f1 $line
+ }
+ set z ""
+ lappend z [file size $path(test1)]
+ for {set x 0} {$x < 100} {incr x} {
+ chan puts $f1 $line
+ }
+ lappend z [file size $path(test1)]
+ chan close $f1
+ lappend z [file size $path(test1)]
+} -result {4096 12288 12600}
+test chan-io-29.21 {Tcl_Flush to pipe} -setup {
+ file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {set x [chan read stdin 6]}
+ chan puts $f1 {set cnt [string length $x]}
+ chan puts $f1 {chan puts "read $cnt characters"}
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ chan puts $f1 hello
+ chan flush $f1
+ chan gets $f1
+} -cleanup {
+ catch {chan close $f1}
+} -result "read 6 characters"
+test chan-io-29.22 {Tcl_Flush called at other end of pipe} -setup {
+ file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {
+ chan configure stdout -buffering full
+ chan puts hello
+ chan puts hello
+ chan flush stdout
+ chan gets stdin
+ chan puts bye
+ chan flush stdout
+ }
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ set x ""
+ lappend x [chan gets $f1]
+ lappend x [chan gets $f1]
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [chan gets $f1]
+} -cleanup {
+ chan close $f1
+} -result {hello hello bye}
+test chan-io-29.23 {Tcl_Flush and line buffering at end of pipe} -setup {
+ file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {
+ chan puts hello
+ chan puts hello
+ chan gets stdin
+ chan puts bye
+ }
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ set x ""
+ lappend x [chan gets $f1]
+ lappend x [chan gets $f1]
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [chan gets $f1]
+} -cleanup {
+ chan close $f1
+} -result {hello hello bye}
+test chan-io-29.24 {Tcl_WriteChars and Tcl_Flush move end of file} -setup {
+ variable x {}
+} -body {
+ set f [open $path(test3) w]
+ chan puts $f "Line 1"
+ chan puts $f "Line 2"
+ set f2 [open $path(test3)]
+ lappend x [chan read -nonewline $f2]
+ chan close $f2
+ chan flush $f
+ set f2 [open $path(test3)]
+ lappend x [chan read -nonewline $f2]
+} -cleanup {
+ chan close $f2
+ chan close $f
+} -result "{} {Line 1\nLine 2}"
+test chan-io-29.25 {Implicit flush with Tcl_Flush to command pipelines} -setup {
+ file delete $path(test3)
+} -constraints {stdio openpipe fileevent} -body {
+ set f [openpipe w $path(cat) | [interpreter] $path(cat) > $path(test3)]
+ chan puts $f "Line 1"
+ chan puts $f "Line 2"
+ chan close $f
+ after 100
+ set f [open $path(test3) r]
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "Line 1\nLine 2\n"
+test chan-io-29.26 {Tcl_Flush, Tcl_Write on bidirectional pipelines} -constraints {stdio unixExecs openpipe} -body {
+ set f [open "|[list cat -u]" r+]
+ chan puts $f "Line1"
+ chan flush $f
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result {Line1}
+test chan-io-29.27 {Tcl_Flush on chan closed pipeline} -setup {
+ file delete $path(pipe)
+ set f [open $path(pipe) w]
+ chan puts $f {exit}
+ chan close $f
+} -constraints {stdio openpipe} -body {
+ set f [openpipe r+ $path(pipe)]
+ chan gets $f
+ chan puts $f output
+ after 50
+ #
+ # The flush below will get a SIGPIPE. This is an expected part of the test
+ # and indicates that the test operates correctly. If you run this test
+ # under a debugger, the signal will by intercepted unless you disable the
+ # debugger's signal interception.
+ #
+ if {[catch {chan flush $f} msg]} {
+ set x [list 1 $msg $::errorCode]
+ catch {chan close $f}
+ } elseif {[catch {chan close $f} msg]} {
+ set x [list 1 $msg $::errorCode]
+ } else {
+ set x {this was supposed to fail and did not}
+ }
+ string tolower $x
+} -match glob -result {1 {error flushing "*": broken pipe} {posix epipe {broken pipe}}}
+test chan-io-29.28 {Tcl_WriteChars, lf mode} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f hello\nthere\nand\nhere
+ chan flush $f
+ file size $path(test1)
+} -cleanup {
+ chan close $f
+} -result 21
+test chan-io-29.29 {Tcl_WriteChars, cr mode} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr -eofchar {}
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ file size $path(test1)
+} -result 21
+test chan-io-29.30 {Tcl_WriteChars, crlf mode} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -eofchar {}
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ file size $path(test1)
+} -result 25
+test chan-io-29.31 {Tcl_WriteChars, background flush} -setup {
+ file delete $path(pipe)
+ file delete $path(output)
+} -constraints {stdio openpipe} -body {
+ set f [open $path(pipe) w]
+ chan puts $f "set f \[[list open $path(output) w]]"
+ chan puts $f {chan configure $f -translation lf}
+ set x [list while {![chan eof stdin]}]
+ set x "$x {"
+ chan puts $f $x
+ chan puts $f { chan puts -nonewline $f [chan read stdin 4096]}
+ chan puts $f { chan flush $f}
+ chan puts $f "}"
+ chan puts $f {chan close $f}
+ chan close $f
+ set x 01234567890123456789012345678901
+ for {set i 0} {$i < 11} {incr i} {
+ set x "$x$x"
+ }
+ set f [open $path(output) w]
+ chan close $f
+ set f [openpipe r+ $path(pipe)]
+ chan configure $f -blocking off
+ chan puts -nonewline $f $x
+ chan close $f
+ set counter 0
+ while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+ after 10 [list incr [namespace which -variable counter]]
+ vwait [namespace which -variable counter]
+ }
+ if {$counter == 1000} {
+ set result "file size only [file size $path(output)]"
+ } else {
+ set result ok
+ }
+ # allow a little time for the background process to chan close.
+ # otherwise, the following test fails on the [file delete $path(output)
+ # on Windows because a process still has the file open.
+ after 100 set v 1; vwait v
+ return $result
+} -result ok
+test chan-io-29.32 {Tcl_WriteChars, background flush to slow reader} -setup {
+ file delete $path(pipe)
+ file delete $path(output)
+} -constraints {stdio asyncPipeChan Close openpipe} -body {
+ set f [open $path(pipe) w]
+ chan puts $f "set f \[[list open $path(output) w]]"
+ chan puts $f {chan configure $f -translation lf}
+ set x [list while {![chan eof stdin]}]
+ set x "$x \{"
+ chan puts $f $x
+ chan puts $f { after 20}
+ chan puts $f { chan puts -nonewline $f [chan read stdin 1024]}
+ chan puts $f { chan flush $f}
+ chan puts $f "\}"
+ chan puts $f {chan close $f}
+ chan close $f
+ set x 01234567890123456789012345678901
+ for {set i 0} {$i < 11} {incr i} {
+ set x "$x$x"
+ }
+ set f [open $path(output) w]
+ chan close $f
+ set f [openpipe r+ $path(pipe)]
+ chan configure $f -blocking off
+ chan puts -nonewline $f $x
+ chan close $f
+ set counter 0
+ while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+ after 20 [list incr [namespace which -variable counter]]
+ vwait [namespace which -variable counter]
+ }
+ if {$counter == 1000} {
+ set result "file size only [file size $path(output)]"
+ } else {
+ set result ok
+ }
+} -result ok
+test chan-io-29.33 {Tcl_Flush, implicit flush on exit} -setup {
+ set f [open $path(script) w]
+ chan puts $f "set f \[[list open $path(test1) w]]"
+ chan puts $f {chan configure $f -translation lf
+ chan puts $f hello
+ chan puts $f bye
+ chan puts $f strange
+ }
+ chan close $f
+} -constraints exec -body {
+ exec [interpreter] $path(script)
+ set f [open $path(test1) r]
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\nbye\nstrange\n"
+test chan-io-29.34 {Tcl_Chan Close, async flush on chan close, using sockets} -setup {
+ variable c 0
+ variable x running
+ set l abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
+ proc writelots {s l} {
+ for {set i 0} {$i < 2000} {incr i} {
+ chan puts $s $l
+ }
+ }
+} -constraints {socket tempNotMac fileevent} -body {
+ proc accept {s a p} {
+ variable x
+ chan event $s readable [namespace code [list readit $s]]
+ chan configure $s -blocking off
+ set x accepted
+ }
+ proc readit {s} {
+ variable c
+ variable x
+ set l [chan gets $s]
+ if {[chan eof $s]} {
+ chan close $s
+ set x done
+ } elseif {([string length $l] > 0) || ![chan blocked $s]} {
+ incr c
+ }
+ }
+ set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set cs [socket 127.0.0.1 [lindex [chan configure $ss -sockname] 2]]
+ vwait [namespace which -variable x]
+ chan configure $cs -blocking off
+ writelots $cs $l
+ chan close $cs
+ chan close $ss
+ vwait [namespace which -variable x]
+ return $c
+} -result 2000
+test chan-io-29.35 {Tcl_Chan Close vs chan event vs multiple interpreters} -setup {
+ catch {interp delete x}
+ catch {interp delete y}
+} -constraints {socket tempNotMac fileevent} -body {
+ # On Mac, this test screws up sockets such that subsequent tests using
+ # port 2828 either cause errors or panic().
+ interp create x
+ interp create y
+ set s [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ proc accept {s a p} {
+ chan puts $s hello
+ chan close $s
+ }
+ set c [socket 127.0.0.1 [lindex [chan configure $s -sockname] 2]]
+ interp share {} $c x
+ interp share {} $c y
+ chan close $c
+ x eval {
+ proc readit {s} {
+ chan gets $s
+ if {[chan eof $s]} {
+ chan close $s
+ }
+ }
+ }
+ y eval {
+ proc readit {s} {
+ chan gets $s
+ if {[chan eof $s]} {
+ chan close $s
+ }
+ }
+ }
+ x eval "chan event $c readable \{readit $c\}"
+ y eval "chan event $c readable \{readit $c\}"
+ y eval [list chan close $c]
+ update
+} -cleanup {
+ chan close $s
+ interp delete x
+ interp delete y
+} -result ""
+
+# Test end of line translations. Procedures tested are Tcl_Write, Tcl_Read.
+
+test chan-io-30.1 {Tcl_Write lf, Tcl_Read lf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\nthere\nand\nhere\n"
+test chan-io-30.2 {Tcl_Write lf, Tcl_Read cr} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\nthere\nand\nhere\n"
+test chan-io-30.3 {Tcl_Write lf, Tcl_Read crlf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\nthere\nand\nhere\n"
+test chan-io-30.4 {Tcl_Write cr, Tcl_Read cr} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\nthere\nand\nhere\n"
+test chan-io-30.5 {Tcl_Write cr, Tcl_Read lf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\rthere\rand\rhere\r"
+test chan-io-30.6 {Tcl_Write cr, Tcl_Read crlf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\rthere\rand\rhere\r"
+test chan-io-30.7 {Tcl_Write crlf, Tcl_Read crlf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\nthere\nand\nhere\n"
+test chan-io-30.8 {Tcl_Write crlf, Tcl_Read lf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\r\nthere\r\nand\r\nhere\r\n"
+test chan-io-30.9 {Tcl_Write crlf, Tcl_Read cr} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result "hello\n\nthere\n\nand\n\nhere\n\n"
+test chan-io-30.10 {Tcl_Write lf, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ list [chan read $f] [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result {{hello
+there
+and
+here
+} auto}
+test chan-io-30.11 {Tcl_Write cr, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ list [chan read $f] [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result {{hello
+there
+and
+here
+} auto}
+test chan-io-30.12 {Tcl_Write crlf, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ list [chan read $f] [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result {{hello
+there
+and
+here
+} auto}
+test chan-io-30.13 {Tcl_Write crlf on block boundary, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ set line "123456789ABCDE" ;# 14 char plus crlf
+ chan puts -nonewline $f x ;# shift crlf across block boundary
+ for {set i 0} {$i < 700} {incr i} {
+ chan puts $f $line
+ }
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto
+ string length [chan read $f]
+} -cleanup {
+ chan close $f
+} -result [expr 700*15+1]
+test chan-io-30.14 {Tcl_Write crlf on block boundary, Tcl_Read crlf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ set line "123456789ABCDE" ;# 14 char plus crlf
+ chan puts -nonewline $f x ;# shift crlf across block boundary
+ for {set i 0} {$i < 700} {incr i} {
+ chan puts $f $line
+ }
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf
+ string length [chan read $f]
+} -cleanup {
+ chan close $f
+} -result [expr 700*15+1]
+test chan-io-30.15 {Tcl_Write mixed, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\rhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result {hello
+there
+and
+here
+}
+test chan-io-30.16 {Tcl_Write ^Z at end, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f hello\nthere\nand\rhere\n\x1a
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result {hello
+there
+and
+here
+}
+test chan-io-30.17 {Tcl_Write, implicit ^Z at end, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -constraints {win} -body {
+ set f [open $path(test1) w]
+ chan configure $f -eofchar \x1a -translation lf
+ chan puts $f hello\nthere\nand\rhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result {hello
+there
+and
+here
+}
+test chan-io-30.18 {Tcl_Write, ^Z in middle, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ chan puts $f $s
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ set l ""
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1 {} 1}
+test chan-io-30.19 {Tcl_Write, ^Z no newline in middle, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ chan puts $f $s
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ set l ""
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1 {} 1}
+test chan-io-30.20 {Tcl_Write, ^Z in middle ignored, Tcl_Read lf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f [format "abc\ndef\n%cghi\nqrs" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf -eofchar {}
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result "abc def 0 \x1aghi 0 qrs 0 {} 1"
+test chan-io-30.21 {Tcl_Write, ^Z in middle ignored, Tcl_Read cr} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f [format "abc\ndef\n%cghi\nqrs" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr -eofchar {}
+ set x [chan gets $f]
+ lappend l [string equal $x "abc\ndef\n\x1aghi\nqrs\n"]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {1 1 {} 1}
+test chan-io-30.22 {Tcl_Write, ^Z in middle ignored, Tcl_Read crlf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f [format "abc\ndef\n%cghi\nqrs" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf -eofchar {}
+ set x [chan gets $f]
+ lappend l [string equal $x "abc\ndef\n\x1aghi\nqrs\n"]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {1 1 {} 1}
+test chan-io-30.23 {Tcl_Write lf, ^Z in middle, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f [format abc\ndef\n%cqrs\ntuv 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {8 1}
+test chan-io-30.24 {Tcl_Write lf, ^Z in middle, Tcl_Read lf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ chan puts $f $c
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf -eofchar \x1a
+ list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {8 1}
+test chan-io-30.25 {Tcl_Write cr, ^Z in middle, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ chan puts $f $c
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {8 1}
+test chan-io-30.26 {Tcl_Write cr, ^Z in middle, Tcl_Read cr} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ chan puts $f $c
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr -eofchar \x1a
+ list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {8 1}
+test chan-io-30.27 {Tcl_Write crlf, ^Z in middle, Tcl_Read auto} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ chan puts $f $c
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {8 1}
+test chan-io-30.28 {Tcl_Write crlf, ^Z in middle, Tcl_Read crlf} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ chan puts $f $c
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf -eofchar \x1a
+ list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {8 1}
+
+# Test end of line translations. Functions tested are Tcl_Write and
+# Tcl_Gets.
+
+test chan-io-31.1 {Tcl_Write lf, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result {hello 6 auto there 12 auto}
+test chan-io-31.2 {Tcl_Write cr, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result {hello 6 auto there 12 auto}
+test chan-io-31.3 {Tcl_Write crlf, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result {hello 7 auto there 14 auto}
+test chan-io-31.4 {Tcl_Write lf, Tcl_Gets lf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+} -cleanup {
+ chan close $f
+} -result {hello 6 lf there 12 lf}
+test chan-io-31.5 {Tcl_Write lf, Tcl_Gets cr} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr
+ lappend l [string length [chan gets $f]]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {21 21 cr 1 {} 21 cr 1}
+test chan-io-31.6 {Tcl_Write lf, Tcl_Gets crlf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf
+ lappend l [string length [chan gets $f]]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {21 21 crlf 1 {} 21 crlf 1}
+test chan-io-31.7 {Tcl_Write cr, Tcl_Gets cr} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello 6 cr 0 there 12 cr 0}
+test chan-io-31.8 {Tcl_Write cr, Tcl_Gets lf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf
+ lappend l [string length [chan gets $f]]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {21 21 lf 1 {} 21 lf 1}
+test chan-io-31.9 {Tcl_Write cr, Tcl_Gets crlf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf
+ lappend l [string length [chan gets $f]]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {21 21 crlf 1 {} 21 crlf 1}
+test chan-io-31.10 {Tcl_Write crlf, Tcl_Gets crlf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello 7 crlf 0 there 14 crlf 0}
+test chan-io-31.11 {Tcl_Write crlf, Tcl_Gets cr} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+ lappend l [string length [chan gets $f]]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello 6 cr 0 6 13 cr 0}
+test chan-io-31.12 {Tcl_Write crlf, Tcl_Gets lf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts $f hello\nthere\nand\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf
+ lappend l [string length [chan gets $f]]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+ lappend l [string length [chan gets $f]]
+ lappend l [chan tell $f]
+ lappend l [chan configure $f -translation]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {6 7 lf 0 6 14 lf 0}
+test chan-io-31.13 {binary mode is synonym of lf mode} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation binary
+ chan configure $f -translation
+} -cleanup {
+ chan close $f
+} -result lf
+#
+# Test chan-io-9.14 has been removed because "auto" output translation mode is
+# not supoprted.
+#
+test chan-io-31.14 {Tcl_Write mixed, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f hello\nthere\rand\r\nhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.15 {Tcl_Write mixed, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f hello\nthere\rand\r\nhere\r
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.16 {Tcl_Write mixed, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f hello\nthere\rand\r\nhere\n
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.17 {Tcl_Write mixed, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f hello\nthere\rand\r\nhere\r\n
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.18 {Tcl_Write ^Z at end, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f [format "hello\nthere\nand\rhere\n\%c" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.19 {Tcl_Write, implicit ^Z at end, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -eofchar \x1a -translation lf
+ chan puts $f hello\nthere\nand\rhere
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.20 {Tcl_Write, ^Z in middle, Tcl_Gets auto, eofChar} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a
+ chan configure $f -translation auto
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.21 {Tcl_Write, no newline ^Z in middle, Tcl_Gets auto, eofChar} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.22 {Tcl_Write, ^Z in middle ignored, Tcl_Gets lf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf -eofchar {}
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test chan-io-31.23 {Tcl_Write, ^Z in middle ignored, Tcl_Gets cr} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr -eofchar {}
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr -eofchar {}
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test chan-io-31.24 {Tcl_Write, ^Z in middle ignored, Tcl_Gets crlf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -eofchar {}
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf -eofchar {}
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test chan-io-31.25 {Tcl_Write lf, ^Z in middle, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.26 {Tcl_Write lf, ^Z in middle, Tcl_Gets lf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf -eofchar \x1a
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.27 {Tcl_Write cr, ^Z in middle, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr -eofchar {}
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.28 {Tcl_Write cr, ^Z in middle, Tcl_Gets cr} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr -eofchar {}
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr -eofchar \x1a
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.29 {Tcl_Write crlf, ^Z in middle, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -eofchar {}
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.30 {Tcl_Write crlf, ^Z in middle, Tcl_Gets crlf} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -eofchar {}
+ chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf -eofchar \x1a
+ lappend l [chan gets $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.31 {Tcl_Write crlf on block boundary, Tcl_Gets crlf} -setup {
+ file delete $path(test1)
+ set c ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ set line "123456789ABCDE" ;# 14 char plus crlf
+ chan puts -nonewline $f x ;# shift crlf across block boundary
+ for {set i 0} {$i < 700} {incr i} {
+ chan puts $f $line
+ }
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf
+ while {[chan gets $f line] >= 0} {
+ append c $line\n
+ }
+ chan close $f
+ string length $c
+} -result [expr 700*15+1]
+test chan-io-31.32 {Tcl_Write crlf on block boundary, Tcl_Gets auto} -setup {
+ file delete $path(test1)
+ set c ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ set line "123456789ABCDE" ;# 14 char plus crlf
+ chan puts -nonewline $f x ;# shift crlf across block boundary
+ for {set i 0} {$i < 700} {incr i} {
+ chan puts $f $line
+ }
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto
+ while {[chan gets $f line] >= 0} {
+ append c $line\n
+ }
+ chan close $f
+ string length $c
+} -result [expr 700*15+1]
+
+# Test Tcl_Read and buffering.
+
+test chan-io-32.1 {Tcl_Read, channel not readable} -body {
+ read stdout
+} -returnCodes error -result {channel "stdout" wasn't opened for reading}
+test chan-io-32.2 {Tcl_Read, zero byte count} {
+ chan read stdin 0
+} ""
+test chan-io-32.3 {Tcl_Read, negative byte count} -setup {
+ set f [open $path(longfile) r]
+} -body {
+ chan read $f -1
+} -returnCodes error -cleanup {
+ chan close $f
+} -result {expected non-negative integer but got "-1"}
+test chan-io-32.4 {Tcl_Read, positive byte count} -body {
+ set f [open $path(longfile) r]
+ string length [chan read $f 1024]
+} -cleanup {
+ chan close $f
+} -result 1024
+test chan-io-32.5 {Tcl_Read, multiple buffers} -body {
+ set f [open $path(longfile) r]
+ chan configure $f -buffersize 100
+ string length [chan read $f 1024]
+} -cleanup {
+ chan close $f
+} -result 1024
+test chan-io-32.6 {Tcl_Read, very large read} {
+ set f1 [open $path(longfile) r]
+ set z [chan read $f1 1000000]
+ chan close $f1
+ set l [string length $z]
+ set x ok
+ set z [file size $path(longfile)]
+ if {$z != $l} {
+ set x "$z != $l"
+ }
+ set x
+} ok
+test chan-io-32.7 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
+ set f1 [open $path(longfile) r]
+ chan configure $f1 -blocking off
+ set z [chan read $f1 20]
+ chan close $f1
+ set l [string length $z]
+ set x ok
+ if {$l != 20} {
+ set x "$l != 20"
+ }
+ set x
+} ok
+test chan-io-32.8 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
+ set f1 [open $path(longfile) r]
+ chan configure $f1 -blocking off
+ set z [chan read $f1 1000000]
+ chan close $f1
+ set x ok
+ set l [string length $z]
+ set z [file size $path(longfile)]
+ if {$z != $l} {
+ set x "$z != $l"
+ }
+ set x
+} ok
+test chan-io-32.9 {Tcl_Read, read to end of file} {
+ set f1 [open $path(longfile) r]
+ set z [chan read $f1]
+ chan close $f1
+ set l [string length $z]
+ set x ok
+ set z [file size $path(longfile)]
+ if {$z != $l} {
+ set x "$z != $l"
+ }
+ set x
+} ok
+test chan-io-32.10 {Tcl_Read from a pipe} -setup {
+ file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {chan puts [chan gets stdin]}
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ chan puts $f1 hello
+ chan flush $f1
+ chan read $f1
+} -cleanup {
+ chan close $f1
+} -result "hello\n"
+test chan-io-32.11 {Tcl_Read from a pipe} -setup {
+ file delete $path(pipe)
+ set x ""
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {chan puts [chan gets stdin]}
+ chan puts $f1 {chan puts [chan gets stdin]}
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [chan read $f1 6]
+ chan puts $f1 hello
+ chan flush $f1
+ lappend x [chan read $f1]
+} -cleanup {
+ chan close $f1
+} -result {{hello
+} {hello
+}}
+test chan-io-32.12 {Tcl_Read, -nonewline} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan puts $f1 hello
+ chan puts $f1 bye
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan read -nonewline $f1
+} -cleanup {
+ chan close $f1
+} -result {hello
+bye}
+test chan-io-32.13 {Tcl_Read, -nonewline} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan puts $f1 hello
+ chan puts $f1 bye
+ chan close $f1
+ set f1 [open $path(test1) r]
+ set c [chan read -nonewline $f1]
+ list [string length $c] $c
+} -cleanup {
+ chan close $f1
+} -result {9 {hello
+bye}}
+test chan-io-32.14 {Tcl_Read, reading in small chunks} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan puts $f "Two lines: this one"
+ chan puts $f "and this one"
+ chan close $f
+ set f [open $path(test1)]
+ list [chan read $f 1] [chan read $f 2] [chan read $f]
+} -cleanup {
+ chan close $f
+} -result {T wo { lines: this one
+and this one
+}}
+test chan-io-32.15 {Tcl_Read, asking for more input than available} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan puts $f "Two lines: this one"
+ chan puts $f "and this one"
+ chan close $f
+ set f [open $path(test1)]
+ chan read $f 100
+} -cleanup {
+ chan close $f
+} -result {Two lines: this one
+and this one
+}
+test chan-io-32.16 {Tcl_Read, read to end of file with -nonewline} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan puts $f "Two lines: this one"
+ chan puts $f "and this one"
+ chan close $f
+ set f [open $path(test1)]
+ chan read -nonewline $f
+} -cleanup {
+ chan close $f
+} -result {Two lines: this one
+and this one}
+
+# Test Tcl_Gets.
+
+test chan-io-33.1 {Tcl_Gets, reading what was written} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan puts $f1 "first line"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan gets $f1
+} -cleanup {
+ chan close $f1
+} -result {first line}
+test chan-io-33.2 {Tcl_Gets into variable} {
+ set f1 [open $path(longfile) r]
+ set c [chan gets $f1 x]
+ set l [string length x]
+ set z ok
+ if {$l != $l} {
+ set z broken
+ }
+ chan close $f1
+ set z
+} ok
+test chan-io-33.3 {Tcl_Gets from pipe} -setup {
+ file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {chan puts [chan gets stdin]}
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ chan puts $f1 hello
+ chan flush $f1
+ chan gets $f1
+} -cleanup {
+ chan close $f1
+} -result hello
+test chan-io-33.4 {Tcl_Gets with long line} -setup {
+ file delete $path(test3)
+} -body {
+ set f [open $path(test3) w]
+ chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ chan puts $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ chan close $f
+ set f [open $path(test3)]
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result {abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
+test chan-io-33.5 {Tcl_Gets with long line} {
+ set f [open $path(test3)]
+ set x [chan gets $f y]
+ chan close $f
+ list $x $y
+} {260 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
+test chan-io-33.6 {Tcl_Gets and end of file} -setup {
+ file delete $path(test3)
+ set x {}
+} -body {
+ set f [open $path(test3) w]
+ chan puts -nonewline $f "Test1\nTest2"
+ chan close $f
+ set f [open $path(test3)]
+ set y {}
+ lappend x [chan gets $f y] $y
+ set y {}
+ lappend x [chan gets $f y] $y
+ set y {}
+ lappend x [chan gets $f y] $y
+} -cleanup {
+ chan close $f
+} -result {5 Test1 5 Test2 -1 {}}
+test chan-io-33.7 {Tcl_Gets and bad variable} -setup {
+ set f [open $path(test3) w]
+ chan puts $f "Line 1"
+ chan puts $f "Line 2"
+ chan close $f
+ catch {unset x}
+ set f [open $path(test3) r]
+} -body {
+ set x 24
+ chan gets $f x(0)
+} -returnCodes error -cleanup {
+ chan close $f
+} -result {can't set "x(0)": variable isn't array}
+test chan-io-33.8 {Tcl_Gets, exercising double buffering} {
+ set f [open $path(test3) w]
+ chan configure $f -translation lf -eofchar {}
+ set x ""
+ for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+ for {set y 0} {$y < 100} {incr y} {chan puts $f $x}
+ chan close $f
+ set f [open $path(test3) r]
+ chan configure $f -translation lf
+ for {set y 0} {$y < 100} {incr y} {chan gets $f}
+ chan close $f
+ set y
+} 100
+test chan-io-33.9 {Tcl_Gets, exercising double buffering} {
+ set f [open $path(test3) w]
+ chan configure $f -translation lf -eofchar {}
+ set x ""
+ for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+ for {set y 0} {$y < 200} {incr y} {chan puts $f $x}
+ chan close $f
+ set f [open $path(test3) r]
+ chan configure $f -translation lf
+ for {set y 0} {$y < 200} {incr y} {chan gets $f}
+ chan close $f
+ set y
+} 200
+test chan-io-33.10 {Tcl_Gets, exercising double buffering} {
+ set f [open $path(test3) w]
+ chan configure $f -translation lf -eofchar {}
+ set x ""
+ for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+ for {set y 0} {$y < 300} {incr y} {chan puts $f $x}
+ chan close $f
+ set f [open $path(test3) r]
+ chan configure $f -translation lf
+ for {set y 0} {$y < 300} {incr y} {chan gets $f}
+ chan close $f
+ set y
+} 300
+
+# Test Tcl_Seek and Tcl_Tell.
+
+test chan-io-34.1 {Tcl_Seek to current position at start of file} -body {
+ set f1 [open $path(longfile) r]
+ chan seek $f1 0 current
+ chan tell $f1
+} -cleanup {
+ chan close $f1
+} -result 0
+test chan-io-34.2 {Tcl_Seek to offset from start} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan seek $f1 10 start
+ chan tell $f1
+} -cleanup {
+ chan close $f1
+} -result 10
+test chan-io-34.3 {Tcl_Seek to end of file} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan seek $f1 0 end
+ chan tell $f1
+} -cleanup {
+ chan close $f1
+} -result 54
+test chan-io-34.4 {Tcl_Seek to offset from end of file} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan seek $f1 -10 end
+ chan tell $f1
+} -cleanup {
+ chan close $f1
+} -result 44
+test chan-io-34.5 {Tcl_Seek to offset from current position} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan seek $f1 10 current
+ chan seek $f1 10 current
+ chan tell $f1
+} -cleanup {
+ chan close $f1
+} -result 20
+test chan-io-34.6 {Tcl_Seek to offset from end of file} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan seek $f1 -10 end
+ list [chan tell $f1] [chan read $f1]
+} -cleanup {
+ chan close $f1
+} -result {44 {rstuvwxyz
+}}
+test chan-io-34.7 {Tcl_Seek to offset from end of file, then to current position} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan seek $f1 -10 end
+ set c1 [chan tell $f1]
+ set r1 [chan read $f1 5]
+ chan seek $f1 0 current
+ list $c1 $r1 [chan tell $f1]
+} -cleanup {
+ chan close $f1
+} -result {44 rstuv 49}
+test chan-io-34.8 {Tcl_Seek on pipes: not supported} -setup {
+ set pipe [openpipe]
+} -constraints {stdio openpipe} -body {
+ chan seek $pipe 0 current
+} -returnCodes error -cleanup {
+ chan close $pipe
+} -match glob -result {error during seek on "*": invalid argument}
+test chan-io-34.9 {Tcl_Seek, testing buffered input flushing} -setup {
+ file delete $path(test3)
+} -body {
+ set f [open $path(test3) w]
+ chan configure $f -eofchar {}
+ chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ chan close $f
+ set f [open $path(test3) RDWR]
+ set x [chan read $f 1]
+ chan seek $f 3
+ lappend x [chan read $f 1]
+ chan seek $f 0 start
+ lappend x [chan read $f 1]
+ chan seek $f 10 current
+ lappend x [chan read $f 1]
+ chan seek $f -2 end
+ lappend x [chan read $f 1]
+ chan seek $f 50 end
+ lappend x [chan read $f 1]
+ chan seek $f 1
+ lappend x [chan read $f 1]
+} -cleanup {
+ chan close $f
+} -result {a d a l Y {} b}
+set path(test3) [makeFile {} test3]
+test chan-io-34.10 {Tcl_Seek testing flushing of buffered input} {
+ set f [open $path(test3) w]
+ chan configure $f -translation lf
+ chan puts $f xyz\n123
+ chan close $f
+ set f [open $path(test3) r+]
+ chan configure $f -translation lf
+ set x [chan gets $f]
+ chan seek $f 0 current
+ chan puts $f 456
+ chan close $f
+ list $x [viewFile test3]
+} "xyz {xyz
+456}"
+test chan-io-34.11 {Tcl_Seek testing flushing of buffered output} {
+ set f [open $path(test3) w]
+ chan puts $f xyz\n123
+ chan close $f
+ set f [open $path(test3) w+]
+ chan puts $f xyzzy
+ chan seek $f 2
+ set x [chan gets $f]
+ chan close $f
+ list $x [viewFile test3]
+} "zzy xyzzy"
+test chan-io-34.12 {Tcl_Seek testing combination of write, seek back and read} {
+ set f [open $path(test3) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f xyz\n123
+ chan close $f
+ set f [open $path(test3) a+]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f xyzzy
+ chan flush $f
+ set x [chan tell $f]
+ chan seek $f -4 cur
+ set y [chan gets $f]
+ chan close $f
+ list $x [viewFile test3] $y
+} {14 {xyz
+123
+xyzzy} zzy}
+test chan-io-34.13 {Tcl_Tell at start of file} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan tell $f1
+} -cleanup {
+ chan close $f1
+} -result 0
+test chan-io-34.14 {Tcl_Tell after seek to end of file} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan seek $f1 0 end
+ chan tell $f1
+} -cleanup {
+ chan close $f1
+} -result 54
+test chan-io-34.15 {Tcl_Tell combined with seeking} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -eofchar {}
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ chan close $f1
+ set f1 [open $path(test1) r]
+ chan seek $f1 10 start
+ set c1 [chan tell $f1]
+ chan seek $f1 10 current
+ list $c1 [chan tell $f1]
+} -cleanup {
+ chan close $f1
+} -result {10 20}
+test chan-io-34.16 {Tcl_Tell on pipe: always -1} -constraints {stdio openpipe} -body {
+ set f1 [openpipe]
+ chan tell $f1
+} -cleanup {
+ chan close $f1
+} -result -1
+test chan-io-34.17 {Tcl_Tell on pipe: always -1} {stdio openpipe} {
+ set f1 [openpipe]
+ chan puts $f1 {chan puts hello}
+ chan flush $f1
+ set c [chan tell $f1]
+ chan gets $f1
+ chan close $f1
+ set c
+} -1
+test chan-io-34.18 {Tcl_Tell combined with seeking and reading} -setup {
+ file delete $path(test2)
+} -body {
+ set f [open $path(test2) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts -nonewline $f "line1\nline2\nline3\nline4\nline5\n"
+ chan close $f
+ set f [open $path(test2)]
+ chan configure $f -translation lf
+ set x [chan tell $f]
+ chan read $f 3
+ lappend x [chan tell $f]
+ chan seek $f 2
+ lappend x [chan tell $f]
+ chan seek $f 10 current
+ lappend x [chan tell $f]
+ chan seek $f 0 end
+ lappend x [chan tell $f]
+} -cleanup {
+ chan close $f
+} -result {0 3 2 12 30}
+test chan-io-34.19 {Tcl_Tell combined with opening in append mode} -body {
+ set f [open $path(test3) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f "abcdefghijklmnopqrstuvwxyz"
+ chan puts $f "abcdefghijklmnopqrstuvwxyz"
+ chan close $f
+ set f [open $path(test3) a]
+ chan tell $f
+} -cleanup {
+ chan close $f
+} -result 54
+test chan-io-34.20 {Tcl_Tell combined with writing} -setup {
+ set l ""
+} -body {
+ set f [open $path(test3) w]
+ chan seek $f 29 start
+ lappend l [chan tell $f]
+ chan puts -nonewline $f a
+ chan seek $f 39 start
+ lappend l [chan tell $f]
+ chan puts -nonewline $f a
+ lappend l [chan tell $f]
+ chan seek $f 407 end
+ lappend l [chan tell $f]
+} -cleanup {
+ chan close $f
+} -result {29 39 40 447}
+test chan-io-34.21 {Tcl_Seek and Tcl_Tell on large files} -setup {
+ file delete $path(test3)
+ set l ""
+} -constraints {largefileSupport} -body {
+ set f [open $path(test3) w]
+ chan configure $f -encoding binary
+ lappend l [chan tell $f]
+ chan puts -nonewline $f abcdef
+ lappend l [chan tell $f]
+ chan flush $f
+ lappend l [chan tell $f]
+ # 4GB offset!
+ chan seek $f 0x100000000
+ lappend l [chan tell $f]
+ chan puts -nonewline $f abcdef
+ lappend l [chan tell $f]
+ chan close $f
+ lappend l [file size $f]
+ # truncate...
+ chan close [open $path(test3) w]
+ lappend l [file size $f]
+} -result {0 6 6 4294967296 4294967302 4294967302 0}
+
+# Test Tcl_Eof
+
+test chan-io-35.1 {Tcl_Eof} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan puts $f hello
+ chan puts $f hello
+ chan close $f
+ set f [open $path(test1)]
+ set x [chan eof $f]
+ lappend x [chan eof $f]
+ chan gets $f
+ lappend x [chan eof $f]
+ chan gets $f
+ lappend x [chan eof $f]
+ chan gets $f
+ lappend x [chan eof $f]
+ lappend x [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {0 0 0 0 1 1}
+test chan-io-35.2 {Tcl_Eof with pipe} -constraints {stdio openpipe} -setup {
+ file delete $path(pipe)
+} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {chan gets stdin}
+ chan puts $f1 {chan puts hello}
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ chan puts $f1 hello
+ set x [chan eof $f1]
+ chan flush $f1
+ lappend x [chan eof $f1]
+ chan gets $f1
+ lappend x [chan eof $f1]
+ chan gets $f1
+ lappend x [chan eof $f1]
+} -cleanup {
+ chan close $f1
+} -result {0 0 0 1}
+test chan-io-35.3 {Tcl_Eof with pipe} -constraints {stdio openpipe} -setup {
+ file delete $path(pipe)
+} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {chan gets stdin}
+ chan puts $f1 {chan puts hello}
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ chan puts $f1 hello
+ set x [chan eof $f1]
+ chan flush $f1
+ lappend x [chan eof $f1]
+ chan gets $f1
+ lappend x [chan eof $f1]
+ chan gets $f1
+ lappend x [chan eof $f1]
+ chan gets $f1
+ lappend x [chan eof $f1]
+ chan gets $f1
+ lappend x [chan eof $f1]
+} -cleanup {
+ chan close $f1
+} -result {0 0 0 1 1 1}
+test chan-io-35.4 {Tcl_Eof, eof detection on nonblocking file} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {nonBlockFiles} -body {
+ chan close [open $path(test1) w]
+ set f [open $path(test1) r]
+ chan configure $f -blocking off
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {{} 1}
+test chan-io-35.5 {Tcl_Eof, eof detection on nonblocking pipe} -setup {
+ file delete $path(pipe)
+ set l ""
+} -constraints {stdio openpipe} -body {
+ set f [open $path(pipe) w]
+ chan puts $f {
+ exit
+ }
+ chan close $f
+ set f [openpipe r $path(pipe)]
+ lappend l [chan gets $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {{} 1}
+test chan-io-35.6 {Tcl_Eof, eof char, lf write, auto read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar \x1a
+ chan puts $f abc\ndef
+ chan close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {9 8 1}
+test chan-io-35.7 {Tcl_Eof, eof char, lf write, lf read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar \x1a
+ chan puts $f abc\ndef
+ chan close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation lf -eofchar \x1a
+ list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {9 8 1}
+test chan-io-35.8 {Tcl_Eof, eof char, cr write, auto read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr -eofchar \x1a
+ chan puts $f abc\ndef
+ chan close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {9 8 1}
+test chan-io-35.9 {Tcl_Eof, eof char, cr write, cr read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr -eofchar \x1a
+ chan puts $f abc\ndef
+ chan close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation cr -eofchar \x1a
+ list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {9 8 1}
+test chan-io-35.10 {Tcl_Eof, eof char, crlf write, auto read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -eofchar \x1a
+ chan puts $f abc\ndef
+ chan close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {11 8 1}
+test chan-io-35.11 {Tcl_Eof, eof char, crlf write, crlf read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -eofchar \x1a
+ chan puts $f abc\ndef
+ chan close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf -eofchar \x1a
+ list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {11 8 1}
+test chan-io-35.12 {Tcl_Eof, eof char in middle, lf write, auto read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+ chan close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {17 8 1}
+test chan-io-35.13 {Tcl_Eof, eof char in middle, lf write, lf read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+ chan close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation lf -eofchar \x1a
+ list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {17 8 1}
+test chan-io-35.14 {Tcl_Eof, eof char in middle, cr write, auto read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr -eofchar {}
+ chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+ chan close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {17 8 1}
+test chan-io-35.15 {Tcl_Eof, eof char in middle, cr write, cr read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr -eofchar {}
+ chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+ chan close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation cr -eofchar \x1a
+ list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {17 8 1}
+test chan-io-35.16 {Tcl_Eof, eof char in middle, crlf write, auto read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -eofchar {}
+ chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+ chan close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {21 8 1}
+test chan-io-35.17 {Tcl_Eof, eof char in middle, crlf write, crlf read} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf -eofchar {}
+ chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+ chan close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf -eofchar \x1a
+ list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {21 8 1}
+
+# Test Tcl_InputBlocked
+
+test chan-io-36.1 {Tcl_InputBlocked on nonblocking pipe} -setup {
+ set x ""
+} -constraints {stdio openpipe} -body {
+ set f1 [openpipe]
+ chan puts $f1 {chan puts hello_from_pipe}
+ chan flush $f1
+ chan gets $f1
+ chan configure $f1 -blocking off -buffering full
+ chan puts $f1 {chan puts hello}
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+ chan flush $f1
+ after 200
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+} -cleanup {
+ chan close $f1
+} -result {{} 1 hello 0 {} 1}
+test chan-io-36.2 {Tcl_InputBlocked on blocking pipe} -setup {
+ set x ""
+} -constraints {stdio openpipe} -body {
+ set f1 [openpipe]
+ chan configure $f1 -buffering line
+ chan puts $f1 {chan puts hello_from_pipe}
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+ chan puts $f1 {exit}
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+ lappend x [chan eof $f1]
+} -cleanup {
+ chan close $f1
+} -result {hello_from_pipe 0 {} 0 1}
+test chan-io-36.3 {Tcl_InputBlocked vs files, short read} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan puts $f abcdefghijklmnop
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [chan blocked $f]
+ lappend l [chan read $f 3]
+ lappend l [chan blocked $f]
+ lappend l [chan read -nonewline $f]
+ lappend l [chan blocked $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {0 abc 0 defghijklmnop 0 1}
+test chan-io-36.4 {Tcl_InputBlocked vs files, event driven read} -setup {
+ file delete $path(test1)
+ set l ""
+ variable x
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan puts $f abcdefghijklmnop
+ chan close $f
+ set f [open $path(test1) r]
+ chan event $f readable [namespace code {
+ lappend l [chan read $f 3]
+ if {[chan eof $f]} {lappend l eof; chan close $f; set x done}
+ }]
+ vwait [namespace which -variable x]
+ return $l
+} -result {abc def ghi jkl mno {p
+} eof}
+test chan-io-36.5 {Tcl_InputBlocked vs files, short read, nonblocking} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {nonBlockFiles} -body {
+ set f [open $path(test1) w]
+ chan puts $f abcdefghijklmnop
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -blocking off
+ lappend l [chan blocked $f]
+ lappend l [chan read $f 3]
+ lappend l [chan blocked $f]
+ lappend l [chan read -nonewline $f]
+ lappend l [chan blocked $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result {0 abc 0 defghijklmnop 0 1}
+test chan-io-36.6 {Tcl_InputBlocked vs files, event driven read} -setup {
+ file delete $path(test1)
+ set l ""
+ variable x
+} -constraints {nonBlockFiles fileevent} -body {
+ set f [open $path(test1) w]
+ chan puts $f abcdefghijklmnop
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -blocking off
+ chan event $f readable [namespace code {
+ lappend l [chan read $f 3]
+ if {[chan eof $f]} {lappend l eof; chan close $f; set x done}
+ }]
+ vwait [namespace which -variable x]
+ return $l
+} -result {abc def ghi jkl mno {p
+} eof}
+
+# Test Tcl_InputBuffered
+
+test chan-io-37.1 {Tcl_InputBuffered} -setup {
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(longfile) r]
+ chan configure $f -buffersize 4096
+ chan read $f 3
+ lappend l [testchannel inputbuffered $f]
+ lappend l [chan tell $f]
+} -cleanup {
+ chan close $f
+} -result {4093 3}
+test chan-io-37.2 {Tcl_InputBuffered, test input flushing on seek} -setup {
+ set l ""
+} -constraints {testchannel} -body {
+ set f [open $path(longfile) r]
+ chan configure $f -buffersize 4096
+ chan read $f 3
+ lappend l [testchannel inputbuffered $f]
+ lappend l [chan tell $f]
+ chan seek $f 0 current
+ lappend l [testchannel inputbuffered $f]
+ lappend l [chan tell $f]
+} -cleanup {
+ chan close $f
+} -result {4093 3 0 3}
+
+# Test Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize
+
+test chan-io-38.1 {Tcl_GetChannelBufferSize, default buffer size} -body {
+ set f [open $path(longfile) r]
+ chan configure $f -buffersize
+} -cleanup {
+ chan close $f
+} -result 4096
+test chan-io-38.2 {Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize} -setup {
+ set l ""
+} -body {
+ set f [open $path(longfile) r]
+ lappend l [chan configure $f -buffersize]
+ chan configure $f -buffersize 10000
+ lappend l [chan configure $f -buffersize]
+ chan configure $f -buffersize 1
+ lappend l [chan configure $f -buffersize]
+ chan configure $f -buffersize -1
+ lappend l [chan configure $f -buffersize]
+ chan configure $f -buffersize 0
+ lappend l [chan configure $f -buffersize]
+ chan configure $f -buffersize 100000
+ lappend l [chan configure $f -buffersize]
+ chan configure $f -buffersize 10000000
+ lappend l [chan configure $f -buffersize]
+} -cleanup {
+ chan close $f
+} -result {4096 10000 1 1 1 100000 1048576}
+test chan-io-38.3 {Tcl_SetChannelBufferSize, changing buffersize between reads} {
+ # This test crashes the interp if Bug #427196 is not fixed
+ set chan [open [info script] r]
+ chan configure $chan -buffersize 10
+ set var [chan read $chan 2]
+ chan configure $chan -buffersize 32
+ append var [chan read $chan]
+ chan close $chan
+} {}
+
+# Test Tcl_SetChannelOption, Tcl_GetChannelOption
+
+test chan-io-39.1 {Tcl_GetChannelOption} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -blocking
+} -cleanup {
+ chan close $f1
+} -result 1
+#
+# Test 17.2 was removed.
+#
+test chan-io-39.2 {Tcl_GetChannelOption} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -buffering
+} -cleanup {
+ chan close $f1
+} -result full
+test chan-io-39.3 {Tcl_GetChannelOption} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -buffering line
+ chan configure $f1 -buffering
+} -cleanup {
+ chan close $f1
+} -result line
+test chan-io-39.4 {Tcl_GetChannelOption, Tcl_SetChannelOption} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f1 [open $path(test1) w]
+ lappend l [chan configure $f1 -buffering]
+ chan configure $f1 -buffering line
+ lappend l [chan configure $f1 -buffering]
+ chan configure $f1 -buffering none
+ lappend l [chan configure $f1 -buffering]
+ chan configure $f1 -buffering line
+ lappend l [chan configure $f1 -buffering]
+ chan configure $f1 -buffering full
+ lappend l [chan configure $f1 -buffering]
+} -cleanup {
+ chan close $f1
+} -result {full line none line full}
+test chan-io-39.5 {Tcl_GetChannelOption, invariance} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f1 [open $path(test1) w]
+ lappend l [chan configure $f1 -buffering]
+ lappend l [list [catch {chan configure $f1 -buffering green} msg] $msg]
+ lappend l [chan configure $f1 -buffering]
+} -cleanup {
+ chan close $f1
+} -result {full {1 {bad value for -buffering: must be one of full, line, or none}} full}
+test chan-io-39.6 {Tcl_SetChannelOption, multiple options} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -buffering line
+ chan puts $f1 hello
+ chan puts $f1 bye
+ file size $path(test1)
+} -cleanup {
+ chan close $f1
+} -result 10
+test chan-io-39.7 {Tcl_SetChannelOption, buffering, translation} -setup {
+ file delete $path(test1)
+ set x ""
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf
+ chan puts $f1 hello
+ chan puts $f1 bye
+ chan configure $f1 -buffering line
+ lappend x [file size $path(test1)]
+ chan puts $f1 really_bye
+ lappend x [file size $path(test1)]
+} -cleanup {
+ chan close $f1
+} -result {0 21}
+test chan-io-39.8 {Tcl_SetChannelOption, different buffering options} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f1 [open $path(test1) w]
+ chan configure $f1 -translation lf -buffering none -eofchar {}
+ chan puts -nonewline $f1 hello
+ lappend l [file size $path(test1)]
+ chan puts -nonewline $f1 hello
+ lappend l [file size $path(test1)]
+ chan configure $f1 -buffering full
+ chan puts -nonewline $f1 hello
+ lappend l [file size $path(test1)]
+ chan configure $f1 -buffering none
+ lappend l [file size $path(test1)]
+ chan puts -nonewline $f1 hello
+ lappend l [file size $path(test1)]
+ chan close $f1
+ lappend l [file size $path(test1)]
+} -result {5 10 10 10 20 20}
+test chan-io-39.9 {Tcl_SetChannelOption, blocking mode} -setup {
+ file delete $path(test1)
+ set x ""
+} -constraints {nonBlockFiles} -body {
+ set f1 [open $path(test1) w]
+ chan close $f1
+ set f1 [open $path(test1) r]
+ lappend x [chan configure $f1 -blocking]
+ chan configure $f1 -blocking off
+ lappend x [chan configure $f1 -blocking]
+ lappend x [chan gets $f1]
+ lappend x [chan read $f1 1000]
+ lappend x [chan blocked $f1]
+ lappend x [chan eof $f1]
+} -cleanup {
+ chan close $f1
+} -result {1 0 {} {} 0 1}
+test chan-io-39.10 {Tcl_SetChannelOption, blocking mode} -setup {
+ file delete $path(pipe)
+ set x ""
+} -constraints {stdio openpipe} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {
+ chan gets stdin
+ after 100
+ chan puts hi
+ chan gets stdin
+ }
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ chan configure $f1 -blocking off -buffering line
+ lappend x [chan configure $f1 -blocking]
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+ chan configure $f1 -blocking on
+ chan puts $f1 hello
+ chan configure $f1 -blocking off
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+ chan configure $f1 -blocking on
+ chan puts $f1 bye
+ chan configure $f1 -blocking off
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+ chan configure $f1 -blocking on
+ lappend x [chan configure $f1 -blocking]
+ lappend x [chan gets $f1]
+ lappend x [chan blocked $f1]
+ lappend x [chan eof $f1]
+ lappend x [chan gets $f1]
+ lappend x [chan eof $f1]
+} -cleanup {
+ chan close $f1
+} -result {0 {} 1 {} 1 {} 1 1 hi 0 0 {} 1}
+test chan-io-39.11 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size clipped to lower bound} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -buffersize -10
+ chan configure $f -buffersize
+} -cleanup {
+ chan close $f
+} -result 1
+test chan-io-39.12 {Tcl_SetChannelOption, Tcl_GetChannelOption buffer size clipped to upper bound} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -buffersize 10000000
+ chan configure $f -buffersize
+} -cleanup {
+ chan close $f
+} -result 1048576
+test chan-io-39.13 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -buffersize 40000
+ chan configure $f -buffersize
+} -cleanup {
+ chan close $f
+} -result 40000
+test chan-io-39.14 {Tcl_SetChannelOption: -encoding, binary & utf-8} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -encoding {}
+ chan puts -nonewline $f \xe7\x89\xa6
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -encoding utf-8
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result \u7266
+test chan-io-39.15 {Tcl_SetChannelOption: -encoding, binary & utf-8} -setup {
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -encoding binary
+ chan puts -nonewline $f \xe7\x89\xa6
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -encoding utf-8
+ chan read $f
+} -cleanup {
+ chan close $f
+} -result \u7266
+test chan-io-39.16 {Tcl_SetChannelOption: -encoding, errors} -setup {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+} -body {
+ chan configure $f -encoding foobar
+} -returnCodes error -cleanup {
+ chan close $f
+} -result {unknown encoding "foobar"}
+test chan-io-39.17 {Tcl_SetChannelOption: -encoding, clearing CHANNEL_NEED_MORE_DATA} -setup {
+ variable x {}
+} -constraints {stdio openpipe fileevent} -body {
+ set f [openpipe r+ $path(cat)]
+ chan configure $f -encoding binary
+ chan puts -nonewline $f "\xe7"
+ chan flush $f
+ chan configure $f -encoding utf-8 -blocking 0
+ chan event $f readable [namespace code { lappend x [chan read $f] }]
+ vwait [namespace which -variable x]
+ after 300 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ chan configure $f -encoding utf-8
+ vwait [namespace which -variable x]
+ after 300 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ chan configure $f -encoding binary
+ vwait [namespace which -variable x]
+ after 300 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ chan close $f
+} -result "{} timeout {} timeout \xe7 timeout"
+test chan-io-39.18 {Tcl_SetChannelOption, setting read mode independently} \
+ -constraints {socket} -body {
+ proc accept {s a p} {chan close $s}
+ set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [chan configure $s1 -sockname] 2]
+ set s2 [socket 127.0.0.1 $port]
+ update
+ chan configure $s2 -translation {auto lf}
+ chan configure $s2 -translation
+} -cleanup {
+ chan close $s1
+ chan close $s2
+} -result {auto lf}
+test chan-io-39.19 {Tcl_SetChannelOption, setting read mode independently} \
+ -constraints {socket} -body {
+ proc accept {s a p} {chan close $s}
+ set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [chan configure $s1 -sockname] 2]
+ set s2 [socket 127.0.0.1 $port]
+ update
+ chan configure $s2 -translation {auto crlf}
+ chan configure $s2 -translation
+} -cleanup {
+ chan close $s1
+ chan close $s2
+} -result {auto crlf}
+test chan-io-39.20 {Tcl_SetChannelOption, setting read mode independently} \
+ -constraints {socket} -body {
+ proc accept {s a p} {chan close $s}
+ set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [chan configure $s1 -sockname] 2]
+ set s2 [socket 127.0.0.1 $port]
+ update
+ chan configure $s2 -translation {auto cr}
+ chan configure $s2 -translation
+} -cleanup {
+ chan close $s1
+ chan close $s2
+} -result {auto cr}
+test chan-io-39.21 {Tcl_SetChannelOption, setting read mode independently} \
+ -constraints {socket} -body {
+ proc accept {s a p} {chan close $s}
+ set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [chan configure $s1 -sockname] 2]
+ set s2 [socket 127.0.0.1 $port]
+ update
+ chan configure $s2 -translation {auto auto}
+ chan configure $s2 -translation
+} -cleanup {
+ chan close $s1
+ chan close $s2
+} -result {auto crlf}
+test chan-io-39.22 {Tcl_SetChannelOption, invariance} -setup {
+ file delete $path(test1)
+ set l ""
+} -constraints {unix} -body {
+ set f1 [open $path(test1) w+]
+ lappend l [chan configure $f1 -eofchar]
+ chan configure $f1 -eofchar {ON GO}
+ lappend l [chan configure $f1 -eofchar]
+ chan configure $f1 -eofchar D
+ lappend l [chan configure $f1 -eofchar]
+} -cleanup {
+ chan close $f1
+} -result {{{} {}} {O G} {D D}}
+test chan-io-39.22a {Tcl_SetChannelOption, invariance} -setup {
+ file delete $path(test1)
+ set l [list]
+} -body {
+ set f1 [open $path(test1) w+]
+ chan configure $f1 -eofchar {ON GO}
+ lappend l [chan configure $f1 -eofchar]
+ chan configure $f1 -eofchar D
+ lappend l [chan configure $f1 -eofchar]
+ lappend l [list [catch {chan configure $f1 -eofchar {1 2 3}} msg] $msg]
+} -cleanup {
+ chan close $f1
+} -result {{O G} {D D} {1 {bad value for -eofchar: should be a list of zero, one, or two elements}}}
+test chan-io-39.23 {Tcl_GetChannelOption, server socket is not readable or\
+ writeable, it should still have valid -eofchar and -translation options} -setup {
+ set l [list]
+} -body {
+ set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ lappend l [chan configure $sock -eofchar] \
+ [chan configure $sock -translation]
+} -cleanup {
+ chan close $sock
+} -result {{{}} auto}
+test chan-io-39.24 {Tcl_SetChannelOption, server socket is not readable or\
+ writable so we can't change -eofchar or -translation} -setup {
+ set l [list]
+} -body {
+ set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ chan configure $sock -eofchar D -translation lf
+ lappend l [chan configure $sock -eofchar] \
+ [chan configure $sock -translation]
+} -cleanup {
+ chan close $sock
+} -result {{{}} auto}
+
+test chan-io-40.1 {POSIX open access modes: RDWR} -setup {
+ file delete $path(test3)
+} -body {
+ set f [open $path(test3) w]
+ chan puts $f xyzzy
+ chan close $f
+ set f [open $path(test3) RDWR]
+ chan puts -nonewline $f "ab"
+ chan seek $f 0 current
+ set x [chan gets $f]
+ chan close $f
+ set f [open $path(test3) r]
+ lappend x [chan gets $f]
+} -cleanup {
+ chan close $f
+} -result {zzy abzzy}
+test chan-io-40.2 {POSIX open access modes: CREAT} -setup {
+ file delete $path(test3)
+} -constraints {unix} -body {
+ set f [open $path(test3) {WRONLY CREAT} 0600]
+ file stat $path(test3) stats
+ set x [format "0%o" [expr $stats(mode)&0o777]]
+ chan puts $f "line 1"
+ chan close $f
+ set f [open $path(test3) r]
+ lappend x [chan gets $f]
+} -cleanup {
+ chan close $f
+} -result {0600 {line 1}}
+test chan-io-40.3 {POSIX open access modes: CREAT} -setup {
+ file delete $path(test3)
+} -constraints {unix umask} -body {
+ # This test only works if your umask is 2, like ouster's.
+ chan close [open $path(test3) {WRONLY CREAT}]
+ file stat $path(test3) stats
+ format "0%o" [expr $stats(mode)&0o777]
+} -result [format %04o [expr {0o666 & ~ $umaskValue}]]
+test chan-io-40.4 {POSIX open access modes: CREAT} -setup {
+ file delete $path(test3)
+} -body {
+ set f [open $path(test3) w]
+ chan configure $f -eofchar {}
+ chan puts $f xyzzy
+ chan close $f
+ set f [open $path(test3) {WRONLY CREAT}]
+ chan configure $f -eofchar {}
+ chan puts -nonewline $f "ab"
+ chan close $f
+ set f [open $path(test3) r]
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result abzzy
+test chan-io-40.5 {POSIX open access modes: APPEND} -setup {
+ file delete $path(test3)
+ set x ""
+} -body {
+ set f [open $path(test3) w]
+ chan configure $f -translation lf -eofchar {}
+ chan puts $f xyzzy
+ chan close $f
+ set f [open $path(test3) {WRONLY APPEND}]
+ chan configure $f -translation lf
+ chan puts $f "new line"
+ chan seek $f 0
+ chan puts $f "abc"
+ chan close $f
+ set f [open $path(test3) r]
+ chan configure $f -translation lf
+ chan seek $f 6 current
+ lappend x [chan gets $f]
+ lappend x [chan gets $f]
+} -cleanup {
+ chan close $f
+} -result {{new line} abc}
+test chan-io-40.6 {POSIX open access modes: EXCL} -match regexp -setup {
+ file delete $path(test3)
+} -body {
+ set f [open $path(test3) w]
+ chan puts $f xyzzy
+ chan close $f
+ open $path(test3) {WRONLY CREAT EXCL}
+} -returnCodes error -result {(?i)couldn't open ".*test3": file (already )?exists}
+test chan-io-40.7 {POSIX open access modes: EXCL} -setup {
+ file delete $path(test3)
+} -body {
+ set f [open $path(test3) {WRONLY CREAT EXCL}]
+ chan configure $f -eofchar {}
+ chan puts $f "A test line"
+ chan close $f
+ viewFile test3
+} -result {A test line}
+test chan-io-40.8 {POSIX open access modes: TRUNC} -setup {
+ file delete $path(test3)
+} -body {
+ set f [open $path(test3) w]
+ chan puts $f xyzzy
+ chan close $f
+ set f [open $path(test3) {WRONLY TRUNC}]
+ chan puts $f abc
+ chan close $f
+ set f [open $path(test3) r]
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result abc
+test chan-io-40.9 {POSIX open access modes: NONBLOCK} -setup {
+ file delete $path(test3)
+} -constraints {nonPortable unix} -body {
+ set f [open $path(test3) {WRONLY NONBLOCK CREAT}]
+ chan puts $f "NONBLOCK test"
+ chan close $f
+ set f [open $path(test3) r]
+ chan gets $f
+} -cleanup {
+ chan close $f
+} -result {NONBLOCK test}
+test chan-io-40.10 {POSIX open access modes: RDONLY} -body {
+ set f [open $path(test1) w]
+ chan puts $f "two lines: this one"
+ chan puts $f "and this"
+ chan close $f
+ set f [open $path(test1) RDONLY]
+ list [chan gets $f] [catch {chan puts $f Test} msg] $msg
+} -cleanup {
+ chan close $f
+} -match glob -result {{two lines: this one} 1 {channel "*" wasn't opened for writing}}
+test chan-io-40.11 {POSIX open access modes: RDONLY} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) RDONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test chan-io-40.12 {POSIX open access modes: WRONLY} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) WRONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test chan-io-40.13 {POSIX open access modes: WRONLY} -body {
+ makeFile xyzzy test3
+ set f [open $path(test3) WRONLY]
+ chan configure $f -eofchar {}
+ chan puts -nonewline $f "ab"
+ chan seek $f 0 current
+ set x [list [catch {chan gets $f} msg] $msg]
+ chan close $f
+ lappend x [viewFile test3]
+} -match glob -result {1 {channel "*" wasn't opened for reading} abzzy}
+test chan-io-40.14 {POSIX open access modes: RDWR} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) RDWR
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test chan-io-40.15 {POSIX open access modes: RDWR} {
+ makeFile xyzzy test3
+ set f [open $path(test3) RDWR]
+ chan puts -nonewline $f "ab"
+ chan seek $f 0 current
+ set x [chan gets $f]
+ chan close $f
+ lappend x [viewFile test3]
+} {zzy abzzy}
+test chan-io-40.16 {tilde substitution in open} -constraints makeFileInHome -setup {
+ makeFile {Some text} _test_ ~
+} -body {
+ file exists [file join $::env(HOME) _test_]
+} -cleanup {
+ removeFile _test_ ~
+} -result 1
+test chan-io-40.17 {tilde substitution in open} -setup {
+ set home $::env(HOME)
+} -body {
+ unset ::env(HOME)
+ open ~/foo
+} -returnCodes error -cleanup {
+ set ::env(HOME) $home
+} -result {couldn't find HOME environment variable to expand path}
+
+test chan-io-41.1 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
+ chan event foo
+} -returnCodes error -result {wrong # args: should be "chan event channelId event ?script?"}
+test chan-io-41.2 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
+ chan event foo bar baz q
+} -returnCodes error -result {wrong # args: should be "chan event channelId event ?script?"}
+test chan-io-41.3 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
+ chan event gorp readable
+} -returnCodes error -result {can not find channel named "gorp"}
+test chan-io-41.4 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
+ chan event gorp writable
+} -returnCodes error -result {can not find channel named "gorp"}
+test chan-io-41.5 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
+ chan event gorp who-knows
+} -returnCodes error -result {bad event name "who-knows": must be readable or writable}
+
+#
+# Test chan event on a file
+#
+
+set path(foo) [makeFile {} foo]
+set f [open $path(foo) w+]
+
+test chan-io-42.1 {Tcl_FileeventCmd: creating, deleting, querying} {fileevent} {
+ list [chan event $f readable] [chan event $f writable]
+} {{} {}}
+test chan-io-42.2 {Tcl_FileeventCmd: replacing} {fileevent} {
+ set result {}
+ chan event $f r "first script"
+ lappend result [chan event $f readable]
+ chan event $f r "new script"
+ lappend result [chan event $f readable]
+ chan event $f r "yet another"
+ lappend result [chan event $f readable]
+ chan event $f r ""
+ lappend result [chan event $f readable]
+} {{first script} {new script} {yet another} {}}
+test chan-io-42.3 {Tcl_FileeventCmd: replacing, with NULL chars in script} {fileevent} {
+ set result {}
+ chan event $f r "first scr\0ipt"
+ lappend result [string length [chan event $f readable]]
+ chan event $f r "new scr\0ipt"
+ lappend result [string length [chan event $f readable]]
+ chan event $f r "yet ano\0ther"
+ lappend result [string length [chan event $f readable]]
+ chan event $f r ""
+ lappend result [chan event $f readable]
+} {13 11 12 {}}
+
+test chan-io-43.1 {Tcl_FileeventCmd: creating, deleting, querying} {stdio unixExecs fileevent} {
+ set result {}
+ chan event $f readable "script 1"
+ lappend result [chan event $f readable] [chan event $f writable]
+ chan event $f writable "write script"
+ lappend result [chan event $f readable] [chan event $f writable]
+ chan event $f readable {}
+ lappend result [chan event $f readable] [chan event $f writable]
+ chan event $f writable {}
+ lappend result [chan event $f readable] [chan event $f writable]
+} {{script 1} {} {script 1} {write script} {} {write script} {} {}}
+test chan-io-43.2 {Tcl_FileeventCmd: deleting when many present} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+ set result {}
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+ lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
+ chan event $f r "chan read f"
+ chan event $f2 r "chan read f2"
+ chan event $f3 r "chan read f3"
+ lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
+ chan event $f2 r {}
+ lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
+ chan event $f3 r {}
+ lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
+ chan event $f r {}
+ lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
+} -cleanup {
+ catch {chan close $f2}
+ catch {chan close $f3}
+} -result {{} {} {} {chan read f} {chan read f2} {chan read f3} {chan read f} {} {chan read f3} {chan read f} {} {} {} {} {}}
+
+test chan-io-44.1 {FileEventProc procedure: normal read event} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+ chan event $f2 readable [namespace code {
+ set x [chan gets $f2]; chan event $f2 readable {}
+ }]
+ chan puts $f2 text; chan flush $f2
+ variable x initial
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ catch {chan close $f2}
+ catch {chan close $f3}
+} -result {text}
+test chan-io-44.2 {FileEventProc procedure: error in read event} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+ proc myHandler {msg options} {
+ variable x $msg
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+ chan event $f2 readable {error bogus}
+ chan puts $f2 text; chan flush $f2
+ variable x initial
+ vwait [namespace which -variable x]
+ list $x [chan event $f2 readable]
+} -cleanup {
+ interp bgerror {} $handler
+ catch {chan close $f2}
+ catch {chan close $f3}
+} -result {bogus {}}
+test chan-io-44.3 {FileEventProc procedure: normal write event} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+ chan event $f2 writable [namespace code {
+ lappend x "triggered"
+ incr count -1
+ if {$count <= 0} {
+ chan event $f2 writable {}
+ }
+ }]
+ variable x initial
+ set count 3
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ catch {chan close $f2}
+ catch {chan close $f3}
+} -result {initial triggered triggered triggered}
+test chan-io-44.4 {FileEventProc procedure: eror in write event} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+ proc myHandler {msg options} {
+ variable x $msg
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+ chan event $f2 writable {error bad-write}
+ variable x initial
+ vwait [namespace which -variable x]
+ list $x [chan event $f2 writable]
+} -cleanup {
+ interp bgerror {} $handler
+ catch {chan close $f2}
+ catch {chan close $f3}
+} -result {bad-write {}}
+test chan-io-44.5 {FileEventProc procedure: end of file} {stdio unixExecs openpipe fileevent} {
+ set f4 [openpipe r $path(cat) << foo]
+ chan event $f4 readable [namespace code {
+ if {[chan gets $f4 line] < 0} {
+ lappend x eof
+ chan event $f4 readable {}
+ } else {
+ lappend x $line
+ }
+ }]
+ variable x initial
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ chan close $f4
+ set x
+} {initial foo eof}
+
+chan close $f
+makeFile "foo bar" foo
+
+test chan-io-45.1 {DeleteFileEvent, cleanup on chan close} {fileevent} {
+ set f [open $path(foo) r]
+ chan event $f readable [namespace code {
+ lappend x "binding triggered: \"[chan gets $f]\""
+ chan event $f readable {}
+ }]
+ chan close $f
+ set x initial
+ after 100 [namespace code {
+ set y done
+ }]
+ variable y
+ vwait [namespace which -variable y]
+ set x
+} {initial}
+test chan-io-45.2 {DeleteFileEvent, cleanup on chan close} {fileevent} {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ chan event $f readable [namespace code {
+ lappend x "f triggered: \"[chan gets $f]\""
+ chan event $f readable {}
+ }]
+ chan event $f2 readable [namespace code {
+ lappend x "f2 triggered: \"[chan gets $f2]\""
+ chan event $f2 readable {}
+ }]
+ chan close $f
+ variable x initial
+ vwait [namespace which -variable x]
+ chan close $f2
+ set x
+} {initial {f2 triggered: "foo bar"}}
+test chan-io-45.3 {DeleteFileEvent, cleanup on chan close} {fileevent} {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ set f3 [open $path(foo) r]
+ chan event $f readable {f script}
+ chan event $f2 readable {f2 script}
+ chan event $f3 readable {f3 script}
+ set x {}
+ chan close $f2
+ lappend x [catch {chan event $f readable} msg] $msg \
+ [catch {chan event $f2 readable}] \
+ [catch {chan event $f3 readable} msg] $msg
+ chan close $f3
+ lappend x [catch {chan event $f readable} msg] $msg \
+ [catch {chan event $f2 readable}] \
+ [catch {chan event $f3 readable}]
+ chan close $f
+ lappend x [catch {chan event $f readable}] \
+ [catch {chan event $f2 readable}] \
+ [catch {chan event $f3 readable}]
+} {0 {f script} 1 0 {f3 script} 0 {f script} 1 1 1 1 1}
+
+# Execute these tests only if the "testfevent" command is present.
+
+test chan-io-46.1 {Tcl event loop vs multiple interpreters} {testfevent fileevent} {
+ testfevent create
+ set script "set f \[[list open $path(foo) r]]\n"
+ append script {
+ set x "no event"
+ chan event $f readable [namespace code {
+ set x "f triggered: [chan gets $f]"
+ chan event $f readable {}
+ }]
+ }
+ testfevent cmd $script
+ after 1 ;# We must delay because Windows takes a little time to notice
+ update
+ testfevent cmd {chan close $f}
+ list [testfevent cmd {set x}] [testfevent cmd {info commands after}]
+} {{f triggered: foo bar} after}
+test chan-io-46.2 {Tcl event loop vs multiple interpreters} testfevent {
+ testfevent create
+ testfevent cmd {
+ variable x 0
+ after 100 {set x triggered}
+ vwait [namespace which -variable x]
+ set x
+ }
+} {triggered}
+test chan-io-46.3 {Tcl event loop vs multiple interpreters} testfevent {
+ testfevent create
+ testfevent cmd {
+ set x 0
+ after 10 {lappend x timer}
+ after 30
+ set result $x
+ update idletasks
+ lappend result $x
+ update
+ lappend result $x
+ }
+} {0 0 {0 timer}}
+
+test chan-io-47.1 {chan event vs multiple interpreters} -setup {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ set f3 [open $path(foo) r]
+ set x {}
+} -constraints {testfevent fileevent} -body {
+ chan event $f readable {script 1}
+ testfevent create
+ testfevent share $f2
+ testfevent cmd "chan event $f2 readable {script 2}"
+ chan event $f3 readable {sript 3}
+ lappend x [chan event $f2 readable]
+ testfevent delete
+ lappend x [chan event $f readable] [chan event $f2 readable] \
+ [chan event $f3 readable]
+} -cleanup {
+ chan close $f
+ chan close $f2
+ chan close $f3
+} -result {{} {script 1} {} {sript 3}}
+test chan-io-47.2 {deleting chan event on interpreter delete} -setup {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ set f3 [open $path(foo) r]
+ set f4 [open $path(foo) r]
+} -constraints {testfevent fileevent} -body {
+ chan event $f readable {script 1}
+ testfevent create
+ testfevent share $f2
+ testfevent share $f3
+ testfevent cmd "chan event $f2 readable {script 2}
+ chan event $f3 readable {script 3}"
+ chan event $f4 readable {script 4}
+ testfevent delete
+ list [chan event $f readable] [chan event $f2 readable] \
+ [chan event $f3 readable] [chan event $f4 readable]
+} -cleanup {
+ chan close $f
+ chan close $f2
+ chan close $f3
+ chan close $f4
+} -result {{script 1} {} {} {script 4}}
+test chan-io-47.3 {deleting chan event on interpreter delete} -setup {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ set f3 [open $path(foo) r]
+ set f4 [open $path(foo) r]
+} -constraints {testfevent fileevent} -body {
+ testfevent create
+ testfevent share $f3
+ testfevent share $f4
+ chan event $f readable {script 1}
+ chan event $f2 readable {script 2}
+ testfevent cmd "chan event $f3 readable {script 3}
+ chan event $f4 readable {script 4}"
+ testfevent delete
+ list [chan event $f readable] [chan event $f2 readable] \
+ [chan event $f3 readable] [chan event $f4 readable]
+} -cleanup {
+ chan close $f
+ chan close $f2
+ chan close $f3
+ chan close $f4
+} -result {{script 1} {script 2} {} {}}
+test chan-io-47.4 {file events on shared files and multiple interpreters} -setup {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+} -constraints {testfevent fileevent} -body {
+ testfevent create
+ testfevent share $f
+ testfevent cmd "chan event $f readable {script 1}"
+ chan event $f readable {script 2}
+ chan event $f2 readable {script 3}
+ list [chan event $f2 readable] [testfevent cmd "chan event $f readable"] \
+ [chan event $f readable]
+} -cleanup {
+ testfevent delete
+ chan close $f
+ chan close $f2
+} -result {{script 3} {script 1} {script 2}}
+test chan-io-47.5 {file events on shared files, deleting file events} -setup {
+ set f [open $path(foo) r]
+} -body {
+ testfevent create
+ testfevent share $f
+ testfevent cmd "chan event $f readable {script 1}"
+ chan event $f readable {script 2}
+ testfevent cmd "chan event $f readable {}"
+ list [testfevent cmd "chan event $f readable"] [chan event $f readable]
+} -constraints {testfevent fileevent} -cleanup {
+ testfevent delete
+ chan close $f
+} -result {{} {script 2}}
+test chan-io-47.6 {file events on shared files, deleting file events} -setup {
+ set f [open $path(foo) r]
+} -body {
+ testfevent create
+ testfevent share $f
+ testfevent cmd "chan event $f readable {script 1}"
+ chan event $f readable {script 2}
+ chan event $f readable {}
+ list [testfevent cmd "chan event $f readable"] [chan event $f readable]
+} -constraints {testfevent fileevent} -cleanup {
+ testfevent delete
+ chan close $f
+} -result {{script 1} {}}
+
+set path(bar) [makeFile {} bar]
+
+test chan-io-48.1 {testing readability conditions} {fileevent} {
+ set f [open $path(bar) w]
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan close $f
+ set f [open $path(bar) r]
+ chan event $f readable [namespace code {
+ lappend l called
+ if {[chan eof $f]} {
+ chan close $f
+ set x done
+ } else {
+ chan gets $f
+ }
+ }]
+ set l ""
+ variable x not_done
+ vwait [namespace which -variable x]
+ list $x $l
+} {done {called called called called called called called}}
+test chan-io-48.2 {testing readability conditions} {nonBlockFiles fileevent} {
+ set f [open $path(bar) w]
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan close $f
+ set f [open $path(bar) r]
+ chan event $f readable [namespace code {
+ lappend l called
+ if {[chan eof $f]} {
+ chan close $f
+ set x done
+ } else {
+ chan gets $f
+ }
+ }]
+ chan configure $f -blocking off
+ set l ""
+ variable x not_done
+ vwait [namespace which -variable x]
+ list $x $l
+} {done {called called called called called called called}}
+set path(my_script) [makeFile {} my_script]
+test chan-io-48.3 {testing readability conditions} -setup {
+ set l ""
+} -constraints {stdio unix nonBlockFiles openpipe fileevent} -body {
+ set f [open $path(bar) w]
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan puts $f abcdefg
+ chan close $f
+ set f [open $path(my_script) w]
+ chan puts $f {
+ proc copy_slowly {f} {
+ while {![chan eof $f]} {
+ chan puts [chan gets $f]
+ after 200
+ }
+ chan close $f
+ }
+ }
+ chan close $f
+ set f [openpipe]
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ } else {
+ chan gets $f
+ lappend l [chan blocked $f]
+ chan gets $f
+ lappend l [chan blocked $f]
+ }
+ }]
+ chan configure $f -buffering line
+ chan configure $f -blocking off
+ variable x not_done
+ chan puts $f [list source $path(my_script)]
+ chan puts $f "set f \[[list open $path(bar) r]]"
+ chan puts $f {copy_slowly $f}
+ chan puts $f {exit}
+ vwait [namespace which -variable x]
+ list $x $l
+} -cleanup {
+ chan close $f
+} -result {done {0 1 0 1 0 1 0 1 0 1 0 1 0 0}}
+test chan-io-48.4 {lf write, testing readability, ^Z termination, auto read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.5 {lf write, testing readability, ^Z in middle, auto read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.6 {cr write, testing readability, ^Z termination, auto read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.7 {cr write, testing readability, ^Z in middle, auto read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.8 {crlf write, testing readability, ^Z termination, auto read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation auto -eofchar \x1a
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.9 {crlf write, testing readability, ^Z in middle, auto read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation auto
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.10 {lf write, testing readability, ^Z in middle, lf read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation lf
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.11 {lf write, testing readability, ^Z termination, lf read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation lf -eofchar \x1a
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.12 {cr write, testing readability, ^Z in middle, cr read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation cr
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.13 {cr write, testing readability, ^Z termination, cr read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation cr
+ chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation cr -eofchar \x1a
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.14 {crlf write, testing readability, ^Z in middle, crlf read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -eofchar \x1a -translation crlf
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.15 {crlf write, testing readability, ^Z termi, crlf read mode} -setup {
+ file delete $path(test1)
+ set c 0
+ set l ""
+} -constraints {fileevent} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation crlf
+ chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+ chan close $f
+ set f [open $path(test1) r]
+ chan configure $f -translation crlf -eofchar \x1a
+ chan event $f readable [namespace code {
+ if {[chan eof $f]} {
+ set x done
+ chan close $f
+ } else {
+ lappend l [chan gets $f]
+ incr c
+ }
+ }]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} -result {3 {abc def {}}}
+
+test chan-io-49.1 {testing crlf reading, leftover cr disgorgment} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\rb\rc\r\n"
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [file size $path(test1)]
+ chan configure $f -translation crlf
+ lappend l [chan read $f 1]
+ lappend l [chan tell $f]
+ lappend l [chan read $f 1]
+ lappend l [chan tell $f]
+ lappend l [chan read $f 1]
+ lappend l [chan tell $f]
+ lappend l [chan read $f 1]
+ lappend l [chan tell $f]
+ lappend l [chan read $f 1]
+ lappend l [chan tell $f]
+ lappend l [chan read $f 1]
+ lappend l [chan tell $f]
+ lappend l [chan eof $f]
+ lappend l [chan read $f 1]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result "7 a 1 [list \r] 2 b 3 [list \r] 4 c 5 {
+} 7 0 {} 1"
+test chan-io-49.2 {testing crlf reading, leftover cr disgorgment} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\rb\rc\r\n"
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [file size $path(test1)]
+ chan configure $f -translation crlf
+ lappend l [chan read $f 2]
+ lappend l [chan tell $f]
+ lappend l [chan read $f 2]
+ lappend l [chan tell $f]
+ lappend l [chan read $f 2]
+ lappend l [chan tell $f]
+ lappend l [chan eof $f]
+ lappend l [chan read $f 2]
+ lappend l [chan tell $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result "7 [list a\r] 2 [list b\r] 4 [list c\n] 7 0 {} 7 1"
+test chan-io-49.3 {testing crlf reading, leftover cr disgorgment} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\rb\rc\r\n"
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [file size $path(test1)]
+ chan configure $f -translation crlf
+ lappend l [chan read $f 3]
+ lappend l [chan tell $f]
+ lappend l [chan read $f 3]
+ lappend l [chan tell $f]
+ lappend l [chan eof $f]
+ lappend l [chan read $f 3]
+ lappend l [chan tell $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result "7 [list a\rb] 3 [list \rc\n] 7 0 {} 7 1"
+test chan-io-49.4 {testing crlf reading, leftover cr disgorgment} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\rb\rc\r\n"
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [file size $path(test1)]
+ chan configure $f -translation crlf
+ lappend l [chan read $f 3]
+ lappend l [chan tell $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan eof $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result "7 [list a\rb] 3 [list \rc] 7 0 {} 7 1"
+test chan-io-49.5 {testing crlf reading, leftover cr disgorgment} -setup {
+ file delete $path(test1)
+ set l ""
+} -body {
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts -nonewline $f "a\rb\rc\r\n"
+ chan close $f
+ set f [open $path(test1) r]
+ lappend l [file size $path(test1)]
+ chan configure $f -translation crlf
+ lappend l [set x [chan gets $f]]
+ lappend l [chan tell $f]
+ lappend l [chan gets $f]
+ lappend l [chan tell $f]
+ lappend l [chan eof $f]
+} -cleanup {
+ chan close $f
+} -result [list 7 a\rb\rc 7 {} 7 1]
+
+test chan-io-50.1 {testing handler deletion} -setup {
+ file delete $path(test1)
+} -constraints {testchannelevent} -body {
+ set f [open $path(test1) w]
+ chan close $f
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code {
+ variable z called
+ testchannelevent $f delete 0
+ }]
+ variable z not_called
+ update
+ return $z
+} -cleanup {
+ chan close $f
+} -result called
+test chan-io-50.2 {testing handler deletion with multiple handlers} -setup {
+ file delete $path(test1)
+ chan close [open $path(test1) w]
+ set z ""
+} -constraints {testchannelevent} -body {
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list delhandler $f 1]]
+ testchannelevent $f add readable [namespace code [list delhandler $f 0]]
+ proc delhandler {f i} {
+ variable z
+ lappend z "called delhandler $f $i"
+ testchannelevent $f delete 0
+ }
+ update
+ string equal $z \
+ [list [list called delhandler $f 0] [list called delhandler $f 1]]
+} -cleanup {
+ chan close $f
+} -result 1
+test chan-io-50.3 {testing handler deletion with multiple handlers} -setup {
+ file delete $path(test1)
+ chan close [open $path(test1) w]
+ set z ""
+} -constraints {testchannelevent} -body {
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list notcalled $f 1]]
+ testchannelevent $f add readable [namespace code [list delhandler $f 0]]
+ proc notcalled {f i} {
+ variable z
+ lappend z "notcalled was called!! $f $i"
+ }
+ proc delhandler {f i} {
+ variable z
+ testchannelevent $f delete 1
+ lappend z "delhandler $f $i called"
+ testchannelevent $f delete 0
+ lappend z "delhandler $f $i deleted myself"
+ }
+ update
+ string equal $z \
+ [list [list delhandler $f 0 called] \
+ [list delhandler $f 0 deleted myself]]
+} -cleanup {
+ chan close $f
+} -result 1
+test chan-io-50.4 {testing handler deletion vs reentrant calls} -setup {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ chan close $f
+} -constraints {testchannelevent} -body {
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code {
+ if {$u eq "recursive"} {
+ testchannelevent $f delete 0
+ lappend z "delrecursive deleting recursive"
+ } else {
+ lappend z "delrecursive calling recursive"
+ set u recursive
+ update
+ }
+ }]
+ variable u toplevel
+ variable z ""
+ update
+ return $z
+} -cleanup {
+ chan close $f
+} -result {{delrecursive calling recursive} {delrecursive deleting recursive}}
+test chan-io-50.5 {testing handler deletion vs reentrant calls} -setup {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ chan close $f
+} -constraints {testchannelevent} -body {
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list notcalled $f]]
+ testchannelevent $f add readable [namespace code [list del $f]]
+ proc notcalled {f} {
+ variable z
+ lappend z "notcalled was called!! $f"
+ }
+ proc del {f} {
+ variable u
+ variable z
+ if {$u eq "recursive"} {
+ testchannelevent $f delete 1
+ testchannelevent $f delete 0
+ lappend z "del deleted notcalled"
+ lappend z "del deleted myself"
+ } else {
+ set u recursive
+ lappend z "del calling recursive"
+ update
+ lappend z "del after update"
+ }
+ }
+ set z ""
+ set u toplevel
+ update
+ return $z
+} -cleanup {
+ chan close $f
+} -result [list {del calling recursive} {del deleted notcalled} \
+ {del deleted myself} {del after update}]
+test chan-io-50.6 {testing handler deletion vs reentrant calls} -setup {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ chan close $f
+} -constraints {testchannelevent} -body {
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list second $f]]
+ testchannelevent $f add readable [namespace code [list first $f]]
+ proc first {f} {
+ variable u
+ variable z
+ if {$u eq "toplevel"} {
+ lappend z "first called"
+ set u first
+ update
+ lappend z "first after update"
+ } else {
+ lappend z "first called not toplevel"
+ }
+ }
+ proc second {f} {
+ variable u
+ variable z
+ if {$u eq "first"} {
+ lappend z "second called, first time"
+ set u second
+ testchannelevent $f delete 0
+ } elseif {$u eq "second"} {
+ lappend z "second called, second time"
+ testchannelevent $f delete 0
+ } else {
+ lappend z "second called, cannot happen!"
+ testchannelevent $f removeall
+ }
+ }
+ set z ""
+ set u toplevel
+ update
+ return $z
+} -cleanup {
+ chan close $f
+} -result [list {first called} {first called not toplevel} \
+ {second called, first time} {second called, second time} \
+ {first after update}]
+
+test chan-io-51.1 {Test old socket deletion on Macintosh} -setup {
+ set x 0
+ set result ""
+ variable wait ""
+} -constraints {socket} -body {
+ proc accept {s a p} {
+ variable x
+ chan configure $s -blocking off
+ chan puts $s "sock[incr x]"
+ chan close $s
+ variable wait done
+ }
+ set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [chan configure $ss -sockname] 2]
+ set cs [socket 127.0.0.1 $port]
+ vwait [namespace which -variable wait]
+ lappend result [chan gets $cs]
+ chan close $cs
+ set cs [socket 127.0.0.1 $port]
+ vwait [namespace which -variable wait]
+ lappend result [chan gets $cs]
+ chan close $cs
+ set cs [socket 127.0.0.1 $port]
+ vwait [namespace which -variable wait]
+ lappend result [chan gets $cs]
+ chan close $cs
+ set cs [socket 127.0.0.1 $port]
+ vwait [namespace which -variable wait]
+ lappend result [chan gets $cs]
+} -cleanup {
+ chan close $cs
+ chan close $ss
+} -result {sock1 sock2 sock3 sock4}
+
+test chan-io-52.1 {TclCopyChannel} -constraints {fcopy} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan copy $f1 $f2 -command " # "
+ chan copy $f1 $f2
+} -returnCodes error -cleanup {
+ chan close $f1
+ chan close $f2
+} -match glob -result {channel "*" is busy}
+test chan-io-52.2 {TclCopyChannel} -constraints {fcopy} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ set f3 [open $thisScript]
+ chan copy $f1 $f2 -command " # "
+ chan copy $f3 $f2
+} -returnCodes error -cleanup {
+ chan close $f1
+ chan close $f2
+ chan close $f3
+} -match glob -result {channel "*" is busy}
+test chan-io-52.3 {TclCopyChannel} -constraints {fcopy} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation cr -blocking 0
+ set s0 [chan copy $f1 $f2]
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ chan close $f1
+ chan close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {($s1 == $s2) && ($s0 == $s1)} {
+ lappend result ok
+ }
+ return $result
+} -result {0 0 ok}
+test chan-io-52.4 {TclCopyChannel} -constraints {fcopy} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation cr -blocking 0
+ chan copy $f1 $f2 -size 40
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ chan close $f1
+ chan close $f2
+ lappend result [file size $path(test1)]
+} -result {0 0 40}
+test chan-io-52.5 {TclCopyChannel, all} -constraints {fcopy} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation lf -blocking 0
+ chan copy $f1 $f2 -size -1 ;# -1 means 'copy all', same as if no -size specified.
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ chan close $f1
+ chan close $f2
+ if {[file size $thisScript] == [file size $path(test1)]} {
+ lappend result ok
+ }
+ return $result
+} -result {0 0 ok}
+test chan-io-52.5a {TclCopyChannel, all, other negative value} -setup {
+ file delete $path(test1)
+} -constraints {fcopy} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation lf -blocking 0
+ chan copy $f1 $f2 -size -2 ;# < 0 behaves like -1, copy all
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ chan close $f1
+ chan close $f2
+ if {[file size $thisScript] == [file size $path(test1)]} {
+ lappend result ok
+ }
+ return $result
+} -result {0 0 ok}
+test chan-io-52.5b {TclCopyChannel, all, wrap to negative value} -setup {
+ file delete $path(test1)
+} -constraints {fcopy} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation lf -blocking 0
+ chan copy $f1 $f2 -size 3221176172 ;# Wrapped to < 0, behaves like -1, copy all
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ chan close $f1
+ chan close $f2
+ if {[file size $thisScript] == [file size $path(test1)]} {
+ lappend result ok
+ }
+ return $result
+} -result {0 0 ok}
+test chan-io-52.6 {TclCopyChannel} -setup {
+ file delete $path(test1)
+} -constraints {fcopy} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation lf -blocking 0
+ set s0 [chan copy $f1 $f2 -size [expr [file size $thisScript] + 5]]
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ chan close $f1
+ chan close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {($s1 == $s2) && ($s0 == $s1)} {
+ lappend result ok
+ }
+ return $result
+} -result {0 0 ok}
+test chan-io-52.7 {TclCopyChannel} -constraints {fcopy} -setup {
+ file delete $path(test1)
+} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation lf -blocking 0
+ chan copy $f1 $f2
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ if {[file size $thisScript] == [file size $path(test1)]} {
+ lappend result ok
+ }
+ return $result
+} -cleanup {
+ chan close $f1
+ chan close $f2
+} -result {0 0 ok}
+test chan-io-52.8 {TclCopyChannel} -setup {
+ file delete $path(test1)
+ file delete $path(pipe)
+} -constraints {stdio openpipe fcopy} -body {
+ set f1 [open $path(pipe) w]
+ chan configure $f1 -translation lf
+ chan puts $f1 "
+ chan puts ready
+ chan gets stdin
+ set f1 \[open [list $thisScript] r\]
+ chan configure \$f1 -translation lf
+ chan puts \[chan read \$f1 100\]
+ chan close \$f1
+ "
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ chan configure $f1 -translation lf
+ chan gets $f1
+ chan puts $f1 ready
+ chan flush $f1
+ set f2 [open $path(test1) w]
+ chan configure $f2 -translation lf
+ set s0 [chan copy $f1 $f2 -size 40]
+ catch {chan close $f1}
+ chan close $f2
+ list $s0 [file size $path(test1)]
+} -result {40 40}
+# Empty files, to register them with the test facility
+set path(kyrillic.txt) [makeFile {} kyrillic.txt]
+set path(utf8-fcopy.txt) [makeFile {} utf8-fcopy.txt]
+set path(utf8-rp.txt) [makeFile {} utf8-rp.txt]
+# Create kyrillic file, use lf translation to avoid os eol issues
+set out [open $path(kyrillic.txt) w]
+chan configure $out -encoding koi8-r -translation lf
+chan puts $out "\u0410\u0410"
+chan close $out
+test chan-io-52.9 {TclCopyChannel & encodings} {fcopy} {
+ # Copy kyrillic to UTF-8, using chan copy.
+ set in [open $path(kyrillic.txt) r]
+ set out [open $path(utf8-fcopy.txt) w]
+ chan configure $in -encoding koi8-r -translation lf
+ chan configure $out -encoding utf-8 -translation lf
+ chan copy $in $out
+ chan close $in
+ chan close $out
+ # Do the same again, but differently (read/chan puts).
+ set in [open $path(kyrillic.txt) r]
+ set out [open $path(utf8-rp.txt) w]
+ chan configure $in -encoding koi8-r -translation lf
+ chan configure $out -encoding utf-8 -translation lf
+ chan puts -nonewline $out [chan read $in]
+ chan close $in
+ chan close $out
+ list [file size $path(kyrillic.txt)] \
+ [file size $path(utf8-fcopy.txt)] \
+ [file size $path(utf8-rp.txt)]
+} {3 5 5}
+test chan-io-52.10 {TclCopyChannel & encodings} {fcopy} {
+ # encoding to binary (=> implies that the internal utf-8 is written)
+ set in [open $path(kyrillic.txt) r]
+ set out [open $path(utf8-fcopy.txt) w]
+ chan configure $in -encoding koi8-r -translation lf
+ # -translation binary is also -encoding binary
+ chan configure $out -translation binary
+ chan copy $in $out
+ chan close $in
+ chan close $out
+ file size $path(utf8-fcopy.txt)
+} 5
+test chan-io-52.11 {TclCopyChannel & encodings} {fcopy} {
+ # binary to encoding => the input has to be in utf-8 to make sense to the
+ # encoder
+ set in [open $path(utf8-fcopy.txt) r]
+ set out [open $path(kyrillic.txt) w]
+ # -translation binary is also -encoding binary
+ chan configure $in -translation binary
+ chan configure $out -encoding koi8-r -translation lf
+ chan copy $in $out
+ chan close $in
+ chan close $out
+ file size $path(kyrillic.txt)
+} 3
+
+test chan-io-53.1 {CopyData} -setup {
+ file delete $path(test1)
+} -constraints {fcopy} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation cr -blocking 0
+ chan copy $f1 $f2 -size 0
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ chan close $f1
+ chan close $f2
+ lappend result [file size $path(test1)]
+} -result {0 0 0}
+test chan-io-53.2 {CopyData} -setup {
+ file delete $path(test1)
+} -constraints {fcopy} -body {
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ chan configure $f1 -translation lf -blocking 0
+ chan configure $f2 -translation cr -blocking 0
+ chan copy $f1 $f2 -command [namespace code {set s0}]
+ set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+ variable s0
+ vwait [namespace which -variable s0]
+ chan close $f1
+ chan close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {($s1 == $s2) && ($s0 == $s1)} {
+ lappend result ok
+ }
+ return $result
+} -result {0 0 ok}
+test chan-io-53.3 {CopyData: background read underflow} -setup {
+ file delete $path(test1)
+ file delete $path(pipe)
+} -constraints {stdio unix openpipe fcopy} -body {
+ set f1 [open $path(pipe) w]
+ chan puts -nonewline $f1 {
+ chan puts ready
+ chan flush stdout ;# Don't assume line buffered!
+ chan copy stdin stdout -command { set x }
+ vwait x
+ set f [}
+ chan puts $f1 [list open $path(test1) w]]
+ chan puts $f1 {
+ chan configure $f -translation lf
+ chan puts $f "done"
+ chan close $f
+ }
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ set result [chan gets $f1]
+ chan puts $f1 line1
+ chan flush $f1
+ lappend result [chan gets $f1]
+ chan puts $f1 line2
+ chan flush $f1
+ lappend result [chan gets $f1]
+ chan close $f1
+ after 500
+ set f [open $path(test1)]
+ lappend result [chan read $f]
+} -cleanup {
+ chan close $f
+} -result "ready line1 line2 {done\n}"
+test chan-io-53.4 {CopyData: background write overflow} -setup {
+ set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n
+ variable x
+ for {set x 0} {$x < 12} {incr x} {
+ append big $big
+ }
+ file delete $path(test1)
+ file delete $path(pipe)
+} -constraints {stdio unix openpipe fileevent fcopy} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {
+ chan puts ready
+ chan copy stdin stdout -command { set x }
+ vwait x
+ set f [open $path(test1) w]
+ chan configure $f -translation lf
+ chan puts $f "done"
+ chan close $f
+ }
+ chan close $f1
+ set f1 [openpipe r+ $path(pipe)]
+ set result [chan gets $f1]
+ chan configure $f1 -blocking 0
+ chan puts $f1 $big
+ chan flush $f1
+ after 500
+ set result ""
+ chan event $f1 read [namespace code {
+ append result [chan read $f1 1024]
+ if {[string length $result] >= [string length $big]} {
+ set x done
+ }
+ }]
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ set big {}
+ chan close $f1
+} -result done
+set result {}
+proc FcopyTestAccept {sock args} {
+ after 1000 "chan close $sock"
+}
+proc FcopyTestDone {bytes {error {}}} {
+ variable fcopyTestDone
+ if {[string length $error]} {
+ set fcopyTestDone 1
+ } else {
+ set fcopyTestDone 0
+ }
+}
+test chan-io-53.5 {CopyData: error during chan copy} {socket fcopy} {
+ variable fcopyTestDone
+ set listen [socket -server [namespace code FcopyTestAccept] -myaddr 127.0.0.1 0]
+ set in [open $thisScript] ;# 126 K
+ set out [socket 127.0.0.1 [lindex [chan configure $listen -sockname] 2]]
+ catch {unset fcopyTestDone}
+ chan close $listen ;# This means the socket open never really succeeds
+ chan copy $in $out -command [namespace code FcopyTestDone]
+ variable fcopyTestDone
+ if ![info exists fcopyTestDone] {
+ vwait [namespace which -variable fcopyTestDone] ;# The error occurs here in the b.g.
+ }
+ chan close $in
+ chan close $out
+ set fcopyTestDone ;# 1 for error condition
+} 1
+test chan-io-53.6 {CopyData: error during chan copy} -setup {
+ variable fcopyTestDone
+ file delete $path(pipe)
+ file delete $path(test1)
+ catch {unset fcopyTestDone}
+} -constraints {stdio openpipe fcopy} -body {
+ set f1 [open $path(pipe) w]
+ chan puts $f1 "exit 1"
+ chan close $f1
+ set in [openpipe r+ $path(pipe)]
+ set out [open $path(test1) w]
+ chan copy $in $out -command [namespace code FcopyTestDone]
+ variable fcopyTestDone
+ if ![info exists fcopyTestDone] {
+ vwait [namespace which -variable fcopyTestDone]
+ }
+ return $fcopyTestDone ;# 0 for plain end of file
+} -cleanup {
+ catch {chan close $in}
+ chan close $out
+} -result 0
+proc doFcopy {in out {bytes 0} {error {}}} {
+ variable fcopyTestDone
+ variable fcopyTestCount
+ incr fcopyTestCount $bytes
+ if {[string length $error]} {
+ set fcopyTestDone 1
+ } elseif {[chan eof $in]} {
+ set fcopyTestDone 0
+ } else {
+ # Delay next chan copy to wait for size>0 input bytes
+ after 100 [list chan copy $in $out -size 1000 \
+ -command [namespace code [list doFcopy $in $out]]]
+ }
+}
+test chan-io-53.7 {CopyData: Flooding chan copy from pipe} -setup {
+ variable fcopyTestDone
+ file delete $path(pipe)
+ catch {unset fcopyTestDone}
+} -constraints {stdio openpipe fcopy} -body {
+ set fcopyTestCount 0
+ set f1 [open $path(pipe) w]
+ chan puts $f1 {
+ # Write 10 bytes / 10 msec
+ proc Write {count} {
+ chan puts -nonewline "1234567890"
+ if {[incr count -1]} {
+ after 10 [list Write $count]
+ } else {
+ set ::ready 1
+ }
+ }
+ chan configure stdout -buffering none
+ Write 345 ;# 3450 bytes ~3.45 sec
+ vwait ready
+ exit 0
+ }
+ chan close $f1
+ set in [openpipe r+ $path(pipe) &]
+ set out [open $path(test1) w]
+ doFcopy $in $out
+ variable fcopyTestDone
+ if {![info exists fcopyTestDone]} {
+ vwait [namespace which -variable fcopyTestDone]
+ }
+ # -1=error 0=script error N=number of bytes
+ expr ($fcopyTestDone == 0) ? $fcopyTestCount : -1
+} -cleanup {
+ catch {chan close $in}
+ chan close $out
+} -result {3450}
+test chan-io-53.8 {CopyData: async callback and error handling, Bug 1932639} -setup {
+ # copy progress callback. errors out intentionally
+ proc cmd args {
+ lappend ::RES "CMD $args"
+ error !STOP
+ }
+ # capture callback error here
+ proc ::bgerror args {
+ lappend ::RES "bgerror/OK $args"
+ set ::forever has-been-reached
+ return
+ }
+ # Files we use for our channels
+ set foo [makeFile ashgdfashdgfasdhgfasdhgf foo]
+ set bar [makeFile {} bar]
+ # Channels to copy between
+ set f [open $foo r] ; fconfigure $f -translation binary
+ set g [open $bar w] ; fconfigure $g -translation binary -buffering none
+} -constraints {stdio openpipe fcopy} -body {
+ # Record input size, so that result is always defined
+ lappend ::RES [file size $bar]
+ # Run the copy. Should not invoke -command now.
+ chan copy $f $g -size 2 -command [namespace code cmd]
+ # Check that -command was not called synchronously
+ set sbs [file size $bar]
+ lappend ::RES [expr {($sbs > 0) ? "sync/FAIL" : "sync/OK"}] $sbs
+ # Now let the async part happen. Should capture the error in cmd via
+ # bgerror. If not break the event loop via timer.
+ set token [after 1000 {
+ lappend ::RES {bgerror/FAIL timeout}
+ set ::forever has-been-reached
+ }]
+ vwait ::forever
+ catch {after cancel $token}
+ # Report
+ return $::RES
+} -cleanup {
+ chan close $f
+ chan close $g
+ catch {unset ::RES}
+ catch {unset ::forever}
+ rename ::bgerror {}
+ removeFile foo
+ removeFile bar
+} -result {0 sync/OK 0 {CMD 2} {bgerror/OK !STOP}}
+test chan-io-53.8a {CopyData: async callback and error handling, Bug 1932639, at eof} -setup {
+ # copy progress callback.
+ proc cmd args {
+ lappend ::RES "CMD $args"
+ set ::forever has-been-reached
+ return
+ }
+ # Files we use for our channels
+ set foo [makeFile ashgdfashdgfasdhgfasdhgf foo]
+ set bar [makeFile {} bar]
+ # Channels to copy between
+ set f [open $foo r] ; chan configure $f -translation binary
+ set g [open $bar w] ; chan configure $g -translation binary -buffering none
+} -constraints {stdio openpipe fcopy} -body {
+ # Initialize and force eof on the input.
+ chan seek $f 0 end ; chan read $f 1
+ set ::RES [chan eof $f]
+ # Run the copy. Should not invoke -command now.
+ chan copy $f $g -size 2 -command [namespace code cmd]
+ # Check that -command was not called synchronously
+ lappend ::RES [expr {([llength $::RES] > 1) ? "sync/FAIL" : "sync/OK"}]
+ # Now let the async part happen. Should capture the eof in cmd
+ # If not break the event loop via timer.
+ set token [after 1000 {
+ lappend ::RES {cmd/FAIL timeout}
+ set ::forever has-been-reached
+ }]
+ vwait ::forever
+ catch {after cancel $token}
+ # Report
+ return $::RES
+} -cleanup {
+ chan close $f
+ chan close $g
+ catch {unset ::RES}
+ catch {unset ::forever}
+ removeFile foo
+ removeFile bar
+} -result {1 sync/OK {CMD 0}}
+test chan-io-53.9 {CopyData: -size and event interaction, Bug 780533} -setup {
+ set out [makeFile {} out]
+ set err [makeFile {} err]
+ set pipe [open "|[list [info nameofexecutable] 2> $err]" r+]
+ chan configure $pipe -translation binary -buffering line
+ chan puts $pipe {
+ chan configure stdout -translation binary -buffering line
+ chan puts stderr Waiting...
+ after 1000
+ foreach x {a b c} {
+ chan puts stderr Looping...
+ chan puts $x
+ after 500
+ }
+ proc bye args {
+ if {[chan gets stdin line]<0} {
+ chan puts stderr "CHILD: EOF detected, exiting"
+ exit
+ } else {
+ chan puts stderr "CHILD: ignoring line: $line"
+ }
+ }
+ chan puts stderr Now-sleeping-forever
+ chan event stdin readable bye
+ vwait forever
+ }
+ proc ::done args {
+ set ::forever OK
+ return
+ }
+ set ::forever {}
+ set out [open $out w]
+} -constraints {stdio openpipe fcopy} -body {
+ chan copy $pipe $out -size 6 -command ::done
+ set token [after 5000 {
+ set ::forever {fcopy hangs}
+ }]
+ vwait ::forever
+ catch {after cancel $token}
+ set ::forever
+} -cleanup {
+ chan close $pipe
+ rename ::done {}
+ if {[testConstraint win]} {
+ after 1000; # Allow Windows time to figure out that the
+ # process is gone
+ }
+ catch {close $out}
+ catch {removeFile out}
+ catch {removeFile err}
+ catch {unset ::forever}
+} -result OK
+test chan-io-53.10 {Bug 1350564, multi-directional fcopy} -setup {
+ set err [makeFile {} err]
+ set pipe [open "|[list [info nameofexecutable] 2> $err]" r+]
+ chan configure $pipe -translation binary -buffering line
+ chan puts $pipe {
+ chan configure stderr -buffering line
+ # Kill server when pipe closed by invoker.
+ proc bye args {
+ if {![chan eof stdin]} { chan gets stdin ; return }
+ chan puts stderr BYE
+ exit
+ }
+ # Server code. Bi-directional copy between 2 sockets.
+ proc geof {sok} {
+ chan puts stderr DONE/$sok
+ chan close $sok
+ }
+ proc new {sok args} {
+ chan puts stderr NEW/$sok
+ global l srv
+ chan configure $sok -translation binary -buffering none
+ lappend l $sok
+ if {[llength $l] == 2} {
+ chan close $srv
+ foreach {a b} $l break
+ chan copy $a $b -command [list geof $a]
+ chan copy $b $a -command [list geof $b]
+ chan puts stderr 2COPY
+ }
+ chan puts stderr ...
+ }
+ chan puts stderr SRV
+ set l {}
+ set srv [socket -server new 9999]
+ chan puts stderr WAITING
+ chan event stdin readable bye
+ chan puts OK
+ vwait forever
+ }
+ # wait for OK from server.
+ chan gets $pipe
+ # Now the two clients.
+ proc done {sock} {
+ if {[chan eof $sock]} { chan close $sock ; return }
+ lappend ::forever [chan gets $sock]
+ return
+ }
+ set a [socket 127.0.0.1 9999]
+ set b [socket 127.0.0.1 9999]
+ chan configure $a -translation binary -buffering none
+ chan configure $b -translation binary -buffering none
+ chan event $a readable [namespace code "done $a"]
+ chan event $b readable [namespace code "done $b"]
+} -constraints {stdio openpipe fcopy} -body {
+ # Now pass data through the server in both directions.
+ set ::forever {}
+ chan puts $a AB
+ vwait ::forever
+ chan puts $b BA
+ vwait ::forever
+ set ::forever
+} -cleanup {
+ catch {chan close $a}
+ catch {chan close $b}
+ chan close $pipe
+ if {[testConstraint win]} {
+ after 1000 ;# Give Windows time to kill the process
+ }
+ removeFile err
+ catch {unset ::forever}
+} -result {AB BA}
+
+test chan-io-54.1 {Recursive channel events} {socket fileevent} {
+ # This test checks to see if file events are delivered during recursive
+ # event loops when there is buffered data on the channel.
+ proc accept {s a p} {
+ variable as
+ chan configure $s -translation lf
+ chan puts $s "line 1\nline2\nline3"
+ chan flush $s
+ set as $s
+ }
+ proc readit {s next} {
+ variable x
+ variable result
+ lappend result $next
+ if {$next == 1} {
+ chan event $s readable [namespace code [list readit $s 2]]
+ vwait [namespace which -variable x]
+ }
+ incr x
+ }
+ set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ # We need to delay on some systems until the creation of the server socket
+ # completes.
+ set done 0
+ for {set i 0} {$i < 10} {incr i} {
+ if {![catch {
+ set cs [socket 127.0.0.1 [lindex [chan configure $ss -sockname] 2]]
+ }]} then {
+ set done 1
+ break
+ }
+ after 100
+ }
+ if {$done == 0} {
+ chan close $ss
+ error "failed to connect to server"
+ }
+ variable result {}
+ variable x 0
+ variable as
+ vwait [namespace which -variable as]
+ chan configure $cs -translation lf
+ lappend result [chan gets $cs]
+ chan configure $cs -blocking off
+ chan event $cs readable [namespace code [list readit $cs 1]]
+ set a [after 2000 [namespace code { set x failure }]]
+ vwait [namespace which -variable x]
+ after cancel $a
+ chan close $as
+ chan close $ss
+ chan close $cs
+ list $result $x
+} {{{line 1} 1 2} 2}
+test chan-io-54.2 {Testing for busy-wait in recursive channel events} -setup {
+ set accept {}
+ set after {}
+ variable done 0
+} -constraints {socket fileevent} -body {
+ variable s [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ proc accept {s a p} {
+ variable counter 0
+ variable accept $s
+ chan configure $s -blocking off -buffering line -translation lf
+ chan event $s readable [namespace code "doit $s"]
+ }
+ proc doit {s} {
+ variable counter
+ variable after
+ incr counter
+ if {[chan gets $s] eq ""} {
+ chan event $s readable [namespace code "doit1 $s"]
+ set after [after 1000 [namespace code {
+ chan puts $writer hello
+ chan flush $writer
+ set done 1
+ }]]
+ }
+ }
+ proc doit1 {s} {
+ variable counter
+ variable accept
+ incr counter
+ chan gets $s
+ chan close $s
+ set accept {}
+ }
+ proc producer {} {
+ variable s
+ variable writer
+ set writer [socket 127.0.0.1 [lindex [chan configure $s -sockname] 2]]
+ chan configure $writer -buffering line
+ chan puts -nonewline $writer hello
+ chan flush $writer
+ }
+ producer
+ vwait [namespace which -variable done]
+ chan close $writer
+ chan close $s
+ after cancel $after
+ return $counter
+} -cleanup {
+ if {$accept ne {}} {chan close $accept}
+} -result 1
+
+set path(fooBar) [makeFile {} fooBar]
+
+test chan-io-55.1 {ChannelEventScriptInvoker: deletion} -constraints {
+ fileevent
+} -setup {
+ variable x
+ proc eventScript {fd} {
+ variable x
+ chan close $fd
+ error "planned error"
+ set x whoops
+ }
+ proc myHandler args {
+ variable x got_error
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+} -body {
+ set f [open $path(fooBar) w]
+ chan event $f writable [namespace code [list eventScript $f]]
+ variable x not_done
+ vwait [namespace which -variable x]
+ return $x
+} -cleanup {
+ interp bgerror {} $handler
+} -result {got_error}
+
+test chan-io-56.1 {ChannelTimerProc} {testchannelevent} {
+ set f [open $path(fooBar) w]
+ chan puts $f "this is a test"
+ chan close $f
+ set f [open $path(fooBar) r]
+ testchannelevent $f add readable [namespace code {
+ chan read $f 1
+ incr x
+ }]
+ variable x 0
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ set result $x
+ testchannelevent $f set 0 none
+ after idle [namespace code {set y done}]
+ variable y
+ vwait [namespace which -variable y]
+ chan close $f
+ lappend result $y
+} {2 done}
+
+test chan-io-57.1 {buffered data and file events, gets} -setup {
+ variable s2
+} -constraints {fileevent} -body {
+ proc accept {sock args} {
+ variable s2
+ set s2 $sock
+ }
+ set server [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set s [socket 127.0.0.1 [lindex [chan configure $server -sockname] 2]]
+ vwait [namespace which -variable s2]
+ update
+ chan event $s2 readable [namespace code {lappend result readable}]
+ chan puts $s "12\n34567890"
+ chan flush $s
+ variable result [chan gets $s2]
+ after 1000 [namespace code {lappend result timer}]
+ vwait [namespace which -variable result]
+ lappend result [chan gets $s2]
+ vwait [namespace which -variable result]
+ return $result
+} -cleanup {
+ chan close $s
+ chan close $s2
+ chan close $server
+} -result {12 readable 34567890 timer}
+test chan-io-57.2 {buffered data and file events, read} -setup {
+ variable s2
+} -constraints {fileevent} -body {
+ proc accept {sock args} {
+ variable s2
+ set s2 $sock
+ }
+ set server [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set s [socket 127.0.0.1 [lindex [chan configure $server -sockname] 2]]
+ vwait [namespace which -variable s2]
+ update
+ chan event $s2 readable [namespace code {lappend result readable}]
+ chan puts -nonewline $s "1234567890"
+ chan flush $s
+ variable result [chan read $s2 1]
+ after 1000 [namespace code {lappend result timer}]
+ vwait [namespace which -variable result]
+ lappend result [chan read $s2 9]
+ vwait [namespace which -variable result]
+ return $result
+} -cleanup {
+ chan close $s
+ chan close $s2
+ chan close $server
+} -result {1 readable 234567890 timer}
+
+test chan-io-58.1 {Tcl_NotifyChannel and error when closing} {stdio unixOrPc openpipe fileevent} {
+ set out [open $path(script) w]
+ chan puts $out {
+ chan puts "normal message from pipe"
+ chan puts stderr "error message from pipe"
+ exit 1
+ }
+ proc readit {pipe} {
+ variable x
+ variable result
+ if {[chan eof $pipe]} {
+ set x [catch {chan close $pipe} line]
+ lappend result catch $line
+ } else {
+ chan gets $pipe line
+ lappend result chan gets $line
+ }
+ }
+ chan close $out
+ set pipe [openpipe r $path(script)]
+ chan event $pipe readable [namespace code [list readit $pipe]]
+ variable x ""
+ set result ""
+ vwait [namespace which -variable x]
+ list $x $result
+} {1 {chan gets {normal message from pipe} chan gets {} catch {error message from pipe}}}
+
+test chan-io-59.1 {Thread reference of channels} {testmainthread testchannel} {
+ # TIP #10
+ # More complicated tests (like that the reference changes as a channel is
+ # moved from thread to thread) can be done only in the extension which
+ # fully implements the moving of channels between threads, i.e. 'Threads'.
+ set f [open $path(longfile) r]
+ set result [testchannel mthread $f]
+ chan close $f
+ string equal $result [testmainthread]
+} {1}
+
+test chan-io-60.1 {writing illegal utf sequences} {openpipe fileevent} {
+ # This test will hang in older revisions of the core.
+ set out [open $path(script) w]
+ chan puts $out {
+ chan puts [encoding convertfrom identity \xe2]
+ exit 1
+ }
+ proc readit {pipe} {
+ variable x
+ variable result
+ if {[chan eof $pipe]} {
+ set x [catch {chan close $pipe} line]
+ lappend result catch $line
+ } else {
+ chan gets $pipe line
+ lappend result gets $line
+ }
+ }
+ chan close $out
+ set pipe [openpipe r $path(script)]
+ chan event $pipe readable [namespace code [list readit $pipe]]
+ variable x ""
+ set result ""
+ vwait [namespace which -variable x]
+ # cut of the remainder of the error stack, especially the filename
+ set result [lreplace $result 3 3 [lindex [split [lindex $result 3] \n] 0]]
+ list $x $result
+} {1 {gets {} catch {error writing "stdout": invalid argument}}}
+
+test chan-io-61.1 {Reset eof state after changing the eof char} -setup {
+ set datafile [makeFile {} eofchar]
+ set f [open $datafile w]
+ chan configure $f -translation binary
+ chan puts -nonewline $f [string repeat "Ho hum\n" 11]
+ chan puts $f =
+ set line [string repeat "Ge gla " 4]
+ chan puts -nonewline $f [string repeat [string trimright $line]\n 834]
+ chan close $f
+} -body {
+ set f [open $datafile r]
+ chan configure $f -eofchar =
+ set res {}
+ lappend res [chan read $f; chan tell $f]
+ chan configure $f -eofchar {}
+ lappend res [chan read $f 1]
+ lappend res [chan read $f; chan tell $f]
+ # Any seek zaps the internals into a good state.
+ #chan seek $f 0 start
+ #chan seek $f 0 current
+ #lappend res [chan read $f; chan tell $f]
+} -cleanup {
+ chan close $f
+ removeFile eofchar
+} -result {77 = 23431}
+
+# Test the cutting and splicing of channels, this is incidentially the
+# attach/detach facility of package Thread, but __without any safeguards__. It
+# can also be used to emulate transfer of channels between threads, and is
+# used for that here.
+
+test chan-io-70.0 {Cutting & Splicing channels} -setup {
+ set f [makeFile {... dummy ...} cutsplice]
+ set res {}
+} -constraints {testchannel} -body {
+ set c [open $f r]
+ lappend res [catch {chan seek $c 0 start}]
+ testchannel cut $c
+ lappend res [catch {chan seek $c 0 start}]
+ testchannel splice $c
+ lappend res [catch {chan seek $c 0 start}]
+} -cleanup {
+ chan close $c
+ removeFile cutsplice
+} -result {0 1 0}
+
+test chan-io-70.1 {Transfer channel} -setup {
+ set f [makeFile {... dummy ...} cutsplice]
+ set res {}
+} -constraints {testchannel thread} -body {
+ set c [open $f r]
+ lappend res [catch {chan seek $c 0 start}]
+ testchannel cut $c
+ lappend res [catch {chan seek $c 0 start}]
+ set tid [thread::create -preserved]
+ thread::send $tid [list set c $c]
+ thread::send $tid {load {} Tcltest}
+ lappend res [thread::send $tid {
+ testchannel splice $c
+ set res [catch {chan seek $c 0 start}]
+ chan close $c
+ set res
+ }]
+} -cleanup {
+ thread::release $tid
+ removeFile cutsplice
+} -result {0 1 0}
+
+# ### ### ### ######### ######### #########
+
+foreach {n msg expected} {
+ 0 {} {}
+ 1 {{message only}} {{message only}}
+ 2 {-options x} {-options x}
+ 3 {-options {x y} {the message}} {-options {x y} {the message}}
+
+ 4 {-code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 5 {-code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 6 {-code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 7 {-code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 8 {-code error -level 0 -f ba snarf} {-code error -level 0 -f ba snarf}
+ 9 {-code ok -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 10 {-code error -level 5 -f ba snarf} {-code error -level 0 -f ba snarf}
+ 11 {-code ok -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 12 {-code boss -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 13 {-code boss -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 14 {-code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 15 {-code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 16 {-code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 17 {-code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 18 {-code error -level 0 -f ba} {-code error -level 0 -f ba}
+ 19 {-code ok -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 20 {-code error -level 5 -f ba} {-code error -level 0 -f ba}
+ 21 {-code ok -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 22 {-code boss -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 23 {-code boss -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 24 {-code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 25 {-code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 26 {-code error -level X -f ba snarf} {-code error -level 0 -f ba snarf}
+ 27 {-code ok -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 28 {-code boss -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 29 {-code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+ 30 {-code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ 31 {-code error -level X -f ba} {-code error -level 0 -f ba}
+ 32 {-code ok -level X -f ba} {-code 1 -level 0 -f ba}
+ 33 {-code boss -level X -f ba} {-code 1 -level 0 -f ba}
+
+ 34 {-code 1 -code 1 -level 0 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 35 {-code 1 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 36 {-code 1 -code 1 -level 5 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 37 {-code 1 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 38 {-code 1 -code error -level 0 -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+ 39 {-code 1 -code ok -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 40 {-code 1 -code error -level 5 -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+ 41 {-code 1 -code ok -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 42 {-code 1 -code boss -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 43 {-code 1 -code boss -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 44 {-code 1 -code 1 -level 0 -f ba} {-code 1 -code 1 -level 0 -f ba}
+ 45 {-code 1 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 46 {-code 1 -code 1 -level 5 -f ba} {-code 1 -code 1 -level 0 -f ba}
+ 47 {-code 1 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 48 {-code 1 -code error -level 0 -f ba} {-code 1 -code error -level 0 -f ba}
+ 49 {-code 1 -code ok -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 50 {-code 1 -code error -level 5 -f ba} {-code 1 -code error -level 0 -f ba}
+ 51 {-code 1 -code ok -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 52 {-code 1 -code boss -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 53 {-code 1 -code boss -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 54 {-code 1 -code 1 -level X -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 55 {-code 1 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 56 {-code 1 -code error -level X -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+ 57 {-code 1 -code ok -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 58 {-code 1 -code boss -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 59 {-code 1 -code 1 -level X -f ba} {-code 1 -code 1 -level 0 -f ba}
+ 60 {-code 1 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ 61 {-code 1 -code error -level X -f ba} {-code 1 -code error -level 0 -f ba}
+ 62 {-code 1 -code ok -level X -f ba} {-code 1 -level 0 -f ba}
+ 63 {-code 1 -code boss -level X -f ba} {-code 1 -level 0 -f ba}
+
+ 64 {-code 0 -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 65 {-code 0 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 66 {-code 0 -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 67 {-code 0 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 68 {-code 0 -code error -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 69 {-code 0 -code ok -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 70 {-code 0 -code error -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 71 {-code 0 -code ok -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 72 {-code 0 -code boss -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 73 {-code 0 -code boss -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 74 {-code 0 -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 75 {-code 0 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 76 {-code 0 -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 77 {-code 0 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 78 {-code 0 -code error -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 79 {-code 0 -code ok -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 80 {-code 0 -code error -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 81 {-code 0 -code ok -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 82 {-code 0 -code boss -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 83 {-code 0 -code boss -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 84 {-code 0 -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 85 {-code 0 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 86 {-code 0 -code error -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 87 {-code 0 -code ok -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 88 {-code 0 -code boss -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 89 {-code 0 -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+ 90 {-code 0 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ 91 {-code 0 -code error -level X -f ba} {-code 1 -level 0 -f ba}
+ 92 {-code 0 -code ok -level X -f ba} {-code 1 -level 0 -f ba}
+ 93 {-code 0 -code boss -level X -f ba} {-code 1 -level 0 -f ba}
+
+ 94 {-code 1 -code 1 -level 0 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 95 {-code 0 -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 96 {-code 1 -code 1 -level 5 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 97 {-code 0 -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 98 {-code error -code 1 -level 0 -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+ 99 {-code ok -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ a0 {-code error -code 1 -level 5 -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+ a1 {-code ok -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ a2 {-code boss -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ a3 {-code boss -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ a4 {-code 1 -code 1 -level 0 -f ba} {-code 1 -code 1 -level 0 -f ba}
+ a5 {-code 0 -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ a6 {-code 1 -code 1 -level 5 -f ba} {-code 1 -code 1 -level 0 -f ba}
+ a7 {-code 0 -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ a8 {-code error -code 1 -level 0 -f ba} {-code error -code 1 -level 0 -f ba}
+ a9 {-code ok -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ b0 {-code error -code 1 -level 5 -f ba} {-code error -code 1 -level 0 -f ba}
+ b1 {-code ok -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ b2 {-code boss -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ b3 {-code boss -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ b4 {-code 1 -code 1 -level X -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ b5 {-code 0 -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ b6 {-code error -code 1 -level X -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+ b7 {-code ok -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ b8 {-code boss -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ b9 {-code 1 -code 1 -level X -f ba} {-code 1 -code 1 -level 0 -f ba}
+ c0 {-code 0 -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+ c1 {-code error -code 1 -level X -f ba} {-code error -code 1 -level 0 -f ba}
+ c2 {-code ok -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+ c3 {-code boss -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+
+ c4 {-code 1 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c5 {-code 0 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c6 {-code 1 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c7 {-code 0 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c8 {-code error -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c9 {-code ok -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d0 {-code error -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d1 {-code ok -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d2 {-code boss -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d3 {-code boss -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d4 {-code 1 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ d5 {-code 0 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ d6 {-code 1 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ d7 {-code 0 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ d8 {-code error -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ d9 {-code ok -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ e0 {-code error -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ e1 {-code ok -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ e2 {-code boss -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ e3 {-code boss -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ e4 {-code 1 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e5 {-code 0 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e6 {-code error -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e7 {-code ok -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e8 {-code boss -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e9 {-code 1 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ f0 {-code 0 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ f1 {-code error -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ f2 {-code ok -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ f3 {-code boss -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+} {
+ test chan-io-71.$n {Tcl_SetChannelError} -setup {
+ set f [makeFile {... dummy ...} cutsplice]
+ } -constraints {testchannel} -body {
+ set c [open $f r]
+ testchannel setchannelerror $c [lrange $msg 0 end]
+ } -cleanup {
+ chan close $c
+ removeFile cutsplice
+ } -result [lrange $expected 0 end]
+ test chan-io-72.$n {Tcl_SetChannelErrorInterp} -setup {
+ set f [makeFile {... dummy ...} cutsplice]
+ } -constraints {testchannel} -body {
+ set c [open $f r]
+ testchannel setchannelerrorinterp $c [lrange $msg 0 end]
+ } -cleanup {
+ chan close $c
+ removeFile cutsplice
+ } -result [lrange $expected 0 end]
+}
+
+test chan-io-73.1 {channel Tcl_Obj SetChannelFromAny} -body {
+ # Test for Bug 1847044 - don't spoil type unless we have a valid channel
+ chan close [lreplace [list a] 0 end]
+} -returnCodes error -match glob -result *
+
+# ### ### ### ######### ######### #########
+
+# cleanup
+foreach file [list fooBar longfile script output test1 pipe my_script \
+ test2 test3 cat kyrillic.txt utf8-fcopy.txt utf8-rp.txt] {
+ removeFile $file
+}
+cleanupTests
+}
+namespace delete ::tcl::test::io
diff --git a/pkgs/msgcat/tests/clock.test b/pkgs/msgcat/tests/clock.test
new file mode 100644
index 0000000..fd74512
--- /dev/null
+++ b/pkgs/msgcat/tests/clock.test
@@ -0,0 +1,36941 @@
+# clock.test --
+#
+# This test file covers the 'clock' command that manipulates time.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+if {[testConstraint win]} {
+ if {[catch {package require registry 1.1}]
+ && [catch {load {} Registry}]
+ && [catch {
+ ::tcltest::loadTestedCommands
+ load $::reglib Registry
+ }]} {
+ namespace eval ::tcl::clock {variable NoRegistry {}}
+ }
+}
+
+package require msgcat 1.4
+
+testConstraint detroit \
+ [expr {![catch {clock format 0 -timezone :America/Detroit -format %z}]}]
+testConstraint y2038 \
+ [expr {[clock format 2158894800 -format %z -timezone :America/Detroit] eq {-0400}}]
+
+# TEST PLAN
+
+# clock-1:
+# [clock format] - tests of bad and empty arguments
+#
+# clock-2
+# formatting of year, month and day of month
+#
+# clock-3
+# formatting of fiscal year, fiscal week and day of week.
+#
+# clock-4
+# formatting of time of day.
+#
+# clock-5
+# handling of Daylight Saving Time in a known locale, formatting of
+# %z and %Z
+#
+# clock-6
+# input conversion - seconds
+#
+# clock-7
+# input conversion - Julian Day
+#
+# clock-8
+# input conversion - ccyymmdd
+#
+# clock-9
+# input conversion - ccyymmdd (test that %s and %J take precedence)
+#
+# clock-10
+# input conversion - ccyyddd
+#
+# clock-11
+# input conversion - relative precedence of ccyyddd and ccyymmdd
+# (tests the 'rightmost field' comparison)
+#
+# clock-12
+# input conversion - ccyyWwwd
+#
+# clock-13
+# input conversion - ccyyWwwd (test that %s and %J take precedence,
+# and that invalid days are rejected).
+#
+# clock-14
+# input conversion - yymmdd
+#
+# clock-15
+# precedence - yymmdd
+#
+# clock-16
+# input conversion and precedence - yyddd
+#
+# clock-17
+# input conversion - yyWwwd
+#
+# clock-18
+# precedence - yyWwwd
+#
+# clock-19
+# input conversion - mmdd
+#
+# clock-20
+# precedence - mmdd
+#
+# clock-21
+# input conversion and precedence - ddd
+#
+# clock-22
+# input conversion - Wwwd
+#
+# clock-23
+# precedence - Wwwd
+#
+# clock-24
+# input conversion - naked day of month
+#
+# clock-25
+# precedence - naked day of month
+#
+# clock-26
+# input conversion - naked day of week
+#
+# clock-27
+# precedence - day of week
+#
+# clock-28
+# scan with empty -format is midnight of base date
+#
+# clock-29
+# scanning of all time-of-day formats
+#
+# clock-30
+# [clock add]
+#
+# clock-31
+# Use of -locale system on Windows
+#
+# clock-32
+# Handling of the Julian-Gregorian transition
+#
+# clock-33
+# Legacy tests - [clock clicks]
+#
+# clock-34
+# Legacy tests - [clock scan] without -format
+#
+# clock-35
+# Legacy tests - [clock seconds]
+#
+# clock-36
+# Legacy tests - [clock scan] with 'next monthname'
+#
+# clock-37
+# Test that -gmt does not affect the value of %s
+#
+# clock-38
+# Regression test to verify that changes in TZ work
+# both east and west of Greenwich
+
+
+# Note that all code between comments '# BEGIN' and '# END' is
+# autogenerated by 'tools/makeTestCases.tcl'. DO NOT EDIT CODE BETWEEN
+# '# BEGIN' and '# END'.
+
+# Define a fictitious locale, 'en_US_roman', for formatting of clock
+# strings with localized numerics and eras. This locale will be used
+# in testing the 'clock' command.
+
+namespace eval ::tcl::clock {
+ ::msgcat::mcmset en_US_roman {
+ LOCALE_ERAS {
+ {-62164627200 {} 0}
+ {-59008867200 c 100}
+ {-55853107200 cc 200}
+ {-52697347200 ccc 300}
+ {-49541587200 cd 400}
+ {-46385827200 d 500}
+ {-43230067200 dc 600}
+ {-40074307200 dcc 700}
+ {-36918547200 dccc 800}
+ {-33762787200 cm 900}
+ {-30607027200 m 1000}
+ {-27451267200 mc 1100}
+ {-24295507200 mcc 1200}
+ {-21139747200 mccc 1300}
+ {-17983987200 mcd 1400}
+ {-14828227200 md 1500}
+ {-11672467200 mdc 1600}
+ {-8516707200 mdcc 1700}
+ {-5364662400 mdccc 1800}
+ {-2208988800 mcm 1900}
+ {946684800 mm 2000}
+ }
+ LOCALE_NUMERALS {
+ ? i ii iii iv v vi vii viii ix
+ x xi xii xiii xiv xv xvi xvii xviii xix
+ xx xxi xxii xxiii xxiv xxv xxvi xxvii xxviii xxix
+ xxx xxxi xxxii xxxiii xxxiv xxxv xxxvi xxxvii xxxviii xxxix
+ xl xli xlii xliii xliv xlv xlvi xlvii xlviii xlix
+ l li lii liii liv lv lvi lvii lviii lix
+ lx lxi lxii lxiii lxiv lxv lxvi lxvii lxviii lxix
+ lxx lxxi lxxii lxxiii lxxiv lxxv lxxvi lxxvii lxxviii lxxix
+ lxxx lxxxi lxxxii lxxxiii lxxxiv lxxxv lxxxvi lxxxvii lxxxviii
+ lxxxix
+ xc xci xcii xciii xciv xcv xcvi xcvii xcviii xcix
+ c
+ }
+ DATE_FORMAT {%m/%d/%Y}
+ TIME_FORMAT {%H:%M:%S}
+ DATE_TIME_FORMAT {%x %X}
+ LOCALE_DATE_FORMAT {die %Od mensis %Om annoque %EY}
+ LOCALE_TIME_FORMAT {%OH h %OM m %OS s}
+ LOCALE_DATE_TIME_FORMAT {%Ex %EX}
+ BCE {Before Christ}
+ CE {Anno Domini}
+ }
+}
+
+#----------------------------------------------------------------------
+#
+# The tests for the Windows platform are careful *not* to muck with
+# the system registry. Instead, the 'registry' command is overridden
+# in the '::tcl::clock' namespace.
+#
+#----------------------------------------------------------------------
+
+namespace eval ::testClock {
+ namespace export registry
+ set reg \
+ [dict create \
+ HKEY_CURRENT_USER\\Control\ Panel\\International \
+ [dict create \
+ locale 0409 \
+ sShortDate dd-MMM-yyyy \
+ sLongDate "'the' dd''' day of' MMMM yyyy" \
+ sTimeFormat "h:mm:ss tt"] \
+ HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\TimeZoneInformation \
+ [dict create \
+ Bias 300 \
+ StandardBias 0 \
+ DaylightBias -60 \
+ StandardStart \x00\x00\x0b\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00 \
+ DaylightStart \x00\x00\x03\x00\x02\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00]]
+}
+
+
+proc ::testClock::registry { cmd path key } {
+ variable reg
+ if { $cmd ne {get} } {
+ return -code error "test case attempts to write/query the registry"
+ }
+ if { ![dict exists $reg $path $key] } {
+ return -code error "test case attempts to read unknown registry entry $path $key"
+ }
+ return [dict get $reg $path $key]
+}
+
+# Test some of the basics of [clock format]
+
+test clock-1.0 "clock format - wrong # args" {
+ list [catch {clock format} msg] $msg $::errorCode
+} {1 {wrong # args: should be "clock format clockval ?-format string? ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?"} {CLOCK wrongNumArgs}}
+
+test clock-1.1 "clock format - bad time" {
+ list [catch {clock format foo} msg] $msg
+} {1 {expected integer but got "foo"}}
+
+test clock-1.2 "clock format - bad gmt val" {
+ list [catch {clock format 0 -gmt foo} msg] $msg
+} {1 {expected boolean value but got "foo"}}
+
+test clock-1.3 "clock format - empty val" {
+ clock format 0 -gmt 1 -format ""
+} {}
+
+test clock-1.4 "clock format - bad flag" {*}{
+ -body {
+ list [catch {clock format 0 -oops badflag} msg] $msg $::errorCode
+ }
+ -match glob
+ -result {1 {bad switch "-oops": must be -format, -gmt, -locale, or -timezone} {CLOCK badSwitch -oops}}
+}
+
+test clock-1.5 "clock format - bad timezone" {
+ list [catch {clock format 0 -format "%s" -timezone :NOWHERE} msg] $msg $::errorCode
+} {1 {time zone ":NOWHERE" not found} {CLOCK badTimeZone :NOWHERE}}
+
+test clock-1.6 "clock format - gmt + timezone" {
+ list [catch {clock format 0 -timezone :GMT -gmt true} msg] $msg $::errorCode
+} {1 {cannot use -gmt and -timezone in same call} {CLOCK gmtWithTimezone}}
+
+test clock-1.7 "clock format - option abbreviations" {
+ clock format 0 -g true -f "%Y-%m-%d"
+} 1970-01-01
+
+# BEGIN testcases2
+
+# Test formatting of Gregorian year, month, day, all formats
+# Formats tested: %b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y %EY
+
+test clock-2.1 {conversion of 1872-01-01} {
+ clock format -3092556304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1872 12:34:56 die i mensis i annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2404794 01 i 1 01/01/1872 die i mensis i annoque mdccclxxii 72 lxxii 1872}
+test clock-2.2 {conversion of 1872-01-31} {
+ clock format -3089964304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1872 12:34:56 die xxxi mensis i annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2404824 01 i 1 01/31/1872 die xxxi mensis i annoque mdccclxxii 72 lxxii 1872}
+test clock-2.3 {conversion of 1872-02-01} {
+ clock format -3089877904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1872 12:34:56 die i mensis ii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2404825 02 ii 2 02/01/1872 die i mensis ii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.4 {conversion of 1872-02-29} {
+ clock format -3087458704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1872 12:34:56 die xxix mensis ii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2404853 02 ii 2 02/29/1872 die xxix mensis ii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.5 {conversion of 1872-03-01} {
+ clock format -3087372304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1872 12:34:56 die i mensis iii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 061 2404854 03 iii 3 03/01/1872 die i mensis iii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.6 {conversion of 1872-03-31} {
+ clock format -3084780304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1872 12:34:56 die xxxi mensis iii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2404884 03 iii 3 03/31/1872 die xxxi mensis iii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.7 {conversion of 1872-04-01} {
+ clock format -3084693904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1872 12:34:56 die i mensis iv annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 092 2404885 04 iv 4 04/01/1872 die i mensis iv annoque mdccclxxii 72 lxxii 1872}
+test clock-2.8 {conversion of 1872-04-30} {
+ clock format -3082188304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1872 12:34:56 die xxx mensis iv annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2404914 04 iv 4 04/30/1872 die xxx mensis iv annoque mdccclxxii 72 lxxii 1872}
+test clock-2.9 {conversion of 1872-05-01} {
+ clock format -3082101904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1872 12:34:56 die i mensis v annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 122 2404915 05 v 5 05/01/1872 die i mensis v annoque mdccclxxii 72 lxxii 1872}
+test clock-2.10 {conversion of 1872-05-31} {
+ clock format -3079509904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1872 12:34:56 die xxxi mensis v annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2404945 05 v 5 05/31/1872 die xxxi mensis v annoque mdccclxxii 72 lxxii 1872}
+test clock-2.11 {conversion of 1872-06-01} {
+ clock format -3079423504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1872 12:34:56 die i mensis vi annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 153 2404946 06 vi 6 06/01/1872 die i mensis vi annoque mdccclxxii 72 lxxii 1872}
+test clock-2.12 {conversion of 1872-06-30} {
+ clock format -3076917904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1872 12:34:56 die xxx mensis vi annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2404975 06 vi 6 06/30/1872 die xxx mensis vi annoque mdccclxxii 72 lxxii 1872}
+test clock-2.13 {conversion of 1872-07-01} {
+ clock format -3076831504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1872 12:34:56 die i mensis vii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 183 2404976 07 vii 7 07/01/1872 die i mensis vii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.14 {conversion of 1872-07-31} {
+ clock format -3074239504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1872 12:34:56 die xxxi mensis vii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2405006 07 vii 7 07/31/1872 die xxxi mensis vii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.15 {conversion of 1872-08-01} {
+ clock format -3074153104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1872 12:34:56 die i mensis viii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 214 2405007 08 viii 8 08/01/1872 die i mensis viii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.16 {conversion of 1872-08-31} {
+ clock format -3071561104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1872 12:34:56 die xxxi mensis viii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2405037 08 viii 8 08/31/1872 die xxxi mensis viii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.17 {conversion of 1872-09-01} {
+ clock format -3071474704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1872 12:34:56 die i mensis ix annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 245 2405038 09 ix 9 09/01/1872 die i mensis ix annoque mdccclxxii 72 lxxii 1872}
+test clock-2.18 {conversion of 1872-09-30} {
+ clock format -3068969104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1872 12:34:56 die xxx mensis ix annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2405067 09 ix 9 09/30/1872 die xxx mensis ix annoque mdccclxxii 72 lxxii 1872}
+test clock-2.19 {conversion of 1872-10-01} {
+ clock format -3068882704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1872 12:34:56 die i mensis x annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 275 2405068 10 x 10 10/01/1872 die i mensis x annoque mdccclxxii 72 lxxii 1872}
+test clock-2.20 {conversion of 1872-10-31} {
+ clock format -3066290704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1872 12:34:56 die xxxi mensis x annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2405098 10 x 10 10/31/1872 die xxxi mensis x annoque mdccclxxii 72 lxxii 1872}
+test clock-2.21 {conversion of 1872-11-01} {
+ clock format -3066204304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1872 12:34:56 die i mensis xi annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 306 2405099 11 xi 11 11/01/1872 die i mensis xi annoque mdccclxxii 72 lxxii 1872}
+test clock-2.22 {conversion of 1872-11-30} {
+ clock format -3063698704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1872 12:34:56 die xxx mensis xi annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2405128 11 xi 11 11/30/1872 die xxx mensis xi annoque mdccclxxii 72 lxxii 1872}
+test clock-2.23 {conversion of 1872-12-01} {
+ clock format -3063612304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1872 12:34:56 die i mensis xii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 336 2405129 12 xii 12 12/01/1872 die i mensis xii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.24 {conversion of 1872-12-31} {
+ clock format -3061020304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1872 12:34:56 die xxxi mensis xii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2405159 12 xii 12 12/31/1872 die xxxi mensis xii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.25 {conversion of 1873-01-01} {
+ clock format -3060933904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1873 12:34:56 die i mensis i annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2405160 01 i 1 01/01/1873 die i mensis i annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.26 {conversion of 1873-01-31} {
+ clock format -3058341904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1873 12:34:56 die xxxi mensis i annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2405190 01 i 1 01/31/1873 die xxxi mensis i annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.27 {conversion of 1873-02-01} {
+ clock format -3058255504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1873 12:34:56 die i mensis ii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2405191 02 ii 2 02/01/1873 die i mensis ii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.28 {conversion of 1873-02-28} {
+ clock format -3055922704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1873 12:34:56 die xxviii mensis ii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2405218 02 ii 2 02/28/1873 die xxviii mensis ii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.29 {conversion of 1873-03-01} {
+ clock format -3055836304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1873 12:34:56 die i mensis iii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2405219 03 iii 3 03/01/1873 die i mensis iii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.30 {conversion of 1873-03-31} {
+ clock format -3053244304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1873 12:34:56 die xxxi mensis iii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2405249 03 iii 3 03/31/1873 die xxxi mensis iii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.31 {conversion of 1873-04-01} {
+ clock format -3053157904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1873 12:34:56 die i mensis iv annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2405250 04 iv 4 04/01/1873 die i mensis iv annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.32 {conversion of 1873-04-30} {
+ clock format -3050652304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1873 12:34:56 die xxx mensis iv annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2405279 04 iv 4 04/30/1873 die xxx mensis iv annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.33 {conversion of 1873-05-01} {
+ clock format -3050565904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1873 12:34:56 die i mensis v annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2405280 05 v 5 05/01/1873 die i mensis v annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.34 {conversion of 1873-05-31} {
+ clock format -3047973904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1873 12:34:56 die xxxi mensis v annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2405310 05 v 5 05/31/1873 die xxxi mensis v annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.35 {conversion of 1873-06-01} {
+ clock format -3047887504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1873 12:34:56 die i mensis vi annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2405311 06 vi 6 06/01/1873 die i mensis vi annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.36 {conversion of 1873-06-30} {
+ clock format -3045381904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1873 12:34:56 die xxx mensis vi annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2405340 06 vi 6 06/30/1873 die xxx mensis vi annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.37 {conversion of 1873-07-01} {
+ clock format -3045295504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1873 12:34:56 die i mensis vii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2405341 07 vii 7 07/01/1873 die i mensis vii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.38 {conversion of 1873-07-31} {
+ clock format -3042703504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1873 12:34:56 die xxxi mensis vii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2405371 07 vii 7 07/31/1873 die xxxi mensis vii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.39 {conversion of 1873-08-01} {
+ clock format -3042617104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1873 12:34:56 die i mensis viii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2405372 08 viii 8 08/01/1873 die i mensis viii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.40 {conversion of 1873-08-31} {
+ clock format -3040025104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1873 12:34:56 die xxxi mensis viii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2405402 08 viii 8 08/31/1873 die xxxi mensis viii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.41 {conversion of 1873-09-01} {
+ clock format -3039938704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1873 12:34:56 die i mensis ix annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2405403 09 ix 9 09/01/1873 die i mensis ix annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.42 {conversion of 1873-09-30} {
+ clock format -3037433104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1873 12:34:56 die xxx mensis ix annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2405432 09 ix 9 09/30/1873 die xxx mensis ix annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.43 {conversion of 1873-10-01} {
+ clock format -3037346704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1873 12:34:56 die i mensis x annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2405433 10 x 10 10/01/1873 die i mensis x annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.44 {conversion of 1873-10-31} {
+ clock format -3034754704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1873 12:34:56 die xxxi mensis x annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2405463 10 x 10 10/31/1873 die xxxi mensis x annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.45 {conversion of 1873-11-01} {
+ clock format -3034668304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1873 12:34:56 die i mensis xi annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2405464 11 xi 11 11/01/1873 die i mensis xi annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.46 {conversion of 1873-11-30} {
+ clock format -3032162704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1873 12:34:56 die xxx mensis xi annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2405493 11 xi 11 11/30/1873 die xxx mensis xi annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.47 {conversion of 1873-12-01} {
+ clock format -3032076304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1873 12:34:56 die i mensis xii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2405494 12 xii 12 12/01/1873 die i mensis xii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.48 {conversion of 1873-12-31} {
+ clock format -3029484304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1873 12:34:56 die xxxi mensis xii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2405524 12 xii 12 12/31/1873 die xxxi mensis xii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.49 {conversion of 1876-01-01} {
+ clock format -2966325904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1876 12:34:56 die i mensis i annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2406255 01 i 1 01/01/1876 die i mensis i annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.50 {conversion of 1876-01-31} {
+ clock format -2963733904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1876 12:34:56 die xxxi mensis i annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2406285 01 i 1 01/31/1876 die xxxi mensis i annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.51 {conversion of 1876-02-01} {
+ clock format -2963647504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1876 12:34:56 die i mensis ii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2406286 02 ii 2 02/01/1876 die i mensis ii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.52 {conversion of 1876-02-29} {
+ clock format -2961228304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1876 12:34:56 die xxix mensis ii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2406314 02 ii 2 02/29/1876 die xxix mensis ii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.53 {conversion of 1876-03-01} {
+ clock format -2961141904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1876 12:34:56 die i mensis iii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 061 2406315 03 iii 3 03/01/1876 die i mensis iii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.54 {conversion of 1876-03-31} {
+ clock format -2958549904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1876 12:34:56 die xxxi mensis iii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2406345 03 iii 3 03/31/1876 die xxxi mensis iii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.55 {conversion of 1876-04-01} {
+ clock format -2958463504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1876 12:34:56 die i mensis iv annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 092 2406346 04 iv 4 04/01/1876 die i mensis iv annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.56 {conversion of 1876-04-30} {
+ clock format -2955957904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1876 12:34:56 die xxx mensis iv annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2406375 04 iv 4 04/30/1876 die xxx mensis iv annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.57 {conversion of 1876-05-01} {
+ clock format -2955871504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1876 12:34:56 die i mensis v annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 122 2406376 05 v 5 05/01/1876 die i mensis v annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.58 {conversion of 1876-05-31} {
+ clock format -2953279504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1876 12:34:56 die xxxi mensis v annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2406406 05 v 5 05/31/1876 die xxxi mensis v annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.59 {conversion of 1876-06-01} {
+ clock format -2953193104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1876 12:34:56 die i mensis vi annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 153 2406407 06 vi 6 06/01/1876 die i mensis vi annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.60 {conversion of 1876-06-30} {
+ clock format -2950687504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1876 12:34:56 die xxx mensis vi annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2406436 06 vi 6 06/30/1876 die xxx mensis vi annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.61 {conversion of 1876-07-01} {
+ clock format -2950601104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1876 12:34:56 die i mensis vii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 183 2406437 07 vii 7 07/01/1876 die i mensis vii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.62 {conversion of 1876-07-31} {
+ clock format -2948009104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1876 12:34:56 die xxxi mensis vii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2406467 07 vii 7 07/31/1876 die xxxi mensis vii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.63 {conversion of 1876-08-01} {
+ clock format -2947922704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1876 12:34:56 die i mensis viii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 214 2406468 08 viii 8 08/01/1876 die i mensis viii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.64 {conversion of 1876-08-31} {
+ clock format -2945330704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1876 12:34:56 die xxxi mensis viii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2406498 08 viii 8 08/31/1876 die xxxi mensis viii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.65 {conversion of 1876-09-01} {
+ clock format -2945244304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1876 12:34:56 die i mensis ix annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 245 2406499 09 ix 9 09/01/1876 die i mensis ix annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.66 {conversion of 1876-09-30} {
+ clock format -2942738704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1876 12:34:56 die xxx mensis ix annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2406528 09 ix 9 09/30/1876 die xxx mensis ix annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.67 {conversion of 1876-10-01} {
+ clock format -2942652304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1876 12:34:56 die i mensis x annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 275 2406529 10 x 10 10/01/1876 die i mensis x annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.68 {conversion of 1876-10-31} {
+ clock format -2940060304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1876 12:34:56 die xxxi mensis x annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2406559 10 x 10 10/31/1876 die xxxi mensis x annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.69 {conversion of 1876-11-01} {
+ clock format -2939973904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1876 12:34:56 die i mensis xi annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 306 2406560 11 xi 11 11/01/1876 die i mensis xi annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.70 {conversion of 1876-11-30} {
+ clock format -2937468304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1876 12:34:56 die xxx mensis xi annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2406589 11 xi 11 11/30/1876 die xxx mensis xi annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.71 {conversion of 1876-12-01} {
+ clock format -2937381904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1876 12:34:56 die i mensis xii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 336 2406590 12 xii 12 12/01/1876 die i mensis xii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.72 {conversion of 1876-12-31} {
+ clock format -2934789904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1876 12:34:56 die xxxi mensis xii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2406620 12 xii 12 12/31/1876 die xxxi mensis xii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.73 {conversion of 1877-01-01} {
+ clock format -2934703504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1877 12:34:56 die i mensis i annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2406621 01 i 1 01/01/1877 die i mensis i annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.74 {conversion of 1877-01-31} {
+ clock format -2932111504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1877 12:34:56 die xxxi mensis i annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2406651 01 i 1 01/31/1877 die xxxi mensis i annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.75 {conversion of 1877-02-01} {
+ clock format -2932025104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1877 12:34:56 die i mensis ii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2406652 02 ii 2 02/01/1877 die i mensis ii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.76 {conversion of 1877-02-28} {
+ clock format -2929692304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1877 12:34:56 die xxviii mensis ii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2406679 02 ii 2 02/28/1877 die xxviii mensis ii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.77 {conversion of 1877-03-01} {
+ clock format -2929605904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1877 12:34:56 die i mensis iii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2406680 03 iii 3 03/01/1877 die i mensis iii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.78 {conversion of 1877-03-31} {
+ clock format -2927013904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1877 12:34:56 die xxxi mensis iii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2406710 03 iii 3 03/31/1877 die xxxi mensis iii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.79 {conversion of 1877-04-01} {
+ clock format -2926927504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1877 12:34:56 die i mensis iv annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2406711 04 iv 4 04/01/1877 die i mensis iv annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.80 {conversion of 1877-04-30} {
+ clock format -2924421904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1877 12:34:56 die xxx mensis iv annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2406740 04 iv 4 04/30/1877 die xxx mensis iv annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.81 {conversion of 1877-05-01} {
+ clock format -2924335504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1877 12:34:56 die i mensis v annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2406741 05 v 5 05/01/1877 die i mensis v annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.82 {conversion of 1877-05-31} {
+ clock format -2921743504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1877 12:34:56 die xxxi mensis v annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2406771 05 v 5 05/31/1877 die xxxi mensis v annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.83 {conversion of 1877-06-01} {
+ clock format -2921657104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1877 12:34:56 die i mensis vi annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2406772 06 vi 6 06/01/1877 die i mensis vi annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.84 {conversion of 1877-06-30} {
+ clock format -2919151504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1877 12:34:56 die xxx mensis vi annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2406801 06 vi 6 06/30/1877 die xxx mensis vi annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.85 {conversion of 1877-07-01} {
+ clock format -2919065104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1877 12:34:56 die i mensis vii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2406802 07 vii 7 07/01/1877 die i mensis vii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.86 {conversion of 1877-07-31} {
+ clock format -2916473104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1877 12:34:56 die xxxi mensis vii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2406832 07 vii 7 07/31/1877 die xxxi mensis vii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.87 {conversion of 1877-08-01} {
+ clock format -2916386704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1877 12:34:56 die i mensis viii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2406833 08 viii 8 08/01/1877 die i mensis viii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.88 {conversion of 1877-08-31} {
+ clock format -2913794704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1877 12:34:56 die xxxi mensis viii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2406863 08 viii 8 08/31/1877 die xxxi mensis viii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.89 {conversion of 1877-09-01} {
+ clock format -2913708304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1877 12:34:56 die i mensis ix annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2406864 09 ix 9 09/01/1877 die i mensis ix annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.90 {conversion of 1877-09-30} {
+ clock format -2911202704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1877 12:34:56 die xxx mensis ix annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2406893 09 ix 9 09/30/1877 die xxx mensis ix annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.91 {conversion of 1877-10-01} {
+ clock format -2911116304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1877 12:34:56 die i mensis x annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2406894 10 x 10 10/01/1877 die i mensis x annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.92 {conversion of 1877-10-31} {
+ clock format -2908524304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1877 12:34:56 die xxxi mensis x annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2406924 10 x 10 10/31/1877 die xxxi mensis x annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.93 {conversion of 1877-11-01} {
+ clock format -2908437904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1877 12:34:56 die i mensis xi annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2406925 11 xi 11 11/01/1877 die i mensis xi annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.94 {conversion of 1877-11-30} {
+ clock format -2905932304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1877 12:34:56 die xxx mensis xi annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2406954 11 xi 11 11/30/1877 die xxx mensis xi annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.95 {conversion of 1877-12-01} {
+ clock format -2905845904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1877 12:34:56 die i mensis xii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2406955 12 xii 12 12/01/1877 die i mensis xii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.96 {conversion of 1877-12-31} {
+ clock format -2903253904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1877 12:34:56 die xxxi mensis xii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2406985 12 xii 12 12/31/1877 die xxxi mensis xii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.97 {conversion of 1880-01-01} {
+ clock format -2840095504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1880 12:34:56 die i mensis i annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2407716 01 i 1 01/01/1880 die i mensis i annoque mdccclxxx 80 lxxx 1880}
+test clock-2.98 {conversion of 1880-01-31} {
+ clock format -2837503504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1880 12:34:56 die xxxi mensis i annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2407746 01 i 1 01/31/1880 die xxxi mensis i annoque mdccclxxx 80 lxxx 1880}
+test clock-2.99 {conversion of 1880-02-01} {
+ clock format -2837417104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1880 12:34:56 die i mensis ii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2407747 02 ii 2 02/01/1880 die i mensis ii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.100 {conversion of 1880-02-29} {
+ clock format -2834997904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1880 12:34:56 die xxix mensis ii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2407775 02 ii 2 02/29/1880 die xxix mensis ii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.101 {conversion of 1880-03-01} {
+ clock format -2834911504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1880 12:34:56 die i mensis iii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 061 2407776 03 iii 3 03/01/1880 die i mensis iii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.102 {conversion of 1880-03-31} {
+ clock format -2832319504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1880 12:34:56 die xxxi mensis iii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2407806 03 iii 3 03/31/1880 die xxxi mensis iii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.103 {conversion of 1880-04-01} {
+ clock format -2832233104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1880 12:34:56 die i mensis iv annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 092 2407807 04 iv 4 04/01/1880 die i mensis iv annoque mdccclxxx 80 lxxx 1880}
+test clock-2.104 {conversion of 1880-04-30} {
+ clock format -2829727504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1880 12:34:56 die xxx mensis iv annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2407836 04 iv 4 04/30/1880 die xxx mensis iv annoque mdccclxxx 80 lxxx 1880}
+test clock-2.105 {conversion of 1880-05-01} {
+ clock format -2829641104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1880 12:34:56 die i mensis v annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 122 2407837 05 v 5 05/01/1880 die i mensis v annoque mdccclxxx 80 lxxx 1880}
+test clock-2.106 {conversion of 1880-05-31} {
+ clock format -2827049104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1880 12:34:56 die xxxi mensis v annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2407867 05 v 5 05/31/1880 die xxxi mensis v annoque mdccclxxx 80 lxxx 1880}
+test clock-2.107 {conversion of 1880-06-01} {
+ clock format -2826962704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1880 12:34:56 die i mensis vi annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 153 2407868 06 vi 6 06/01/1880 die i mensis vi annoque mdccclxxx 80 lxxx 1880}
+test clock-2.108 {conversion of 1880-06-30} {
+ clock format -2824457104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1880 12:34:56 die xxx mensis vi annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2407897 06 vi 6 06/30/1880 die xxx mensis vi annoque mdccclxxx 80 lxxx 1880}
+test clock-2.109 {conversion of 1880-07-01} {
+ clock format -2824370704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1880 12:34:56 die i mensis vii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 183 2407898 07 vii 7 07/01/1880 die i mensis vii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.110 {conversion of 1880-07-31} {
+ clock format -2821778704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1880 12:34:56 die xxxi mensis vii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2407928 07 vii 7 07/31/1880 die xxxi mensis vii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.111 {conversion of 1880-08-01} {
+ clock format -2821692304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1880 12:34:56 die i mensis viii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 214 2407929 08 viii 8 08/01/1880 die i mensis viii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.112 {conversion of 1880-08-31} {
+ clock format -2819100304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1880 12:34:56 die xxxi mensis viii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2407959 08 viii 8 08/31/1880 die xxxi mensis viii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.113 {conversion of 1880-09-01} {
+ clock format -2819013904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1880 12:34:56 die i mensis ix annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 245 2407960 09 ix 9 09/01/1880 die i mensis ix annoque mdccclxxx 80 lxxx 1880}
+test clock-2.114 {conversion of 1880-09-30} {
+ clock format -2816508304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1880 12:34:56 die xxx mensis ix annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2407989 09 ix 9 09/30/1880 die xxx mensis ix annoque mdccclxxx 80 lxxx 1880}
+test clock-2.115 {conversion of 1880-10-01} {
+ clock format -2816421904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1880 12:34:56 die i mensis x annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 275 2407990 10 x 10 10/01/1880 die i mensis x annoque mdccclxxx 80 lxxx 1880}
+test clock-2.116 {conversion of 1880-10-31} {
+ clock format -2813829904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1880 12:34:56 die xxxi mensis x annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2408020 10 x 10 10/31/1880 die xxxi mensis x annoque mdccclxxx 80 lxxx 1880}
+test clock-2.117 {conversion of 1880-11-01} {
+ clock format -2813743504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1880 12:34:56 die i mensis xi annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 306 2408021 11 xi 11 11/01/1880 die i mensis xi annoque mdccclxxx 80 lxxx 1880}
+test clock-2.118 {conversion of 1880-11-30} {
+ clock format -2811237904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1880 12:34:56 die xxx mensis xi annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2408050 11 xi 11 11/30/1880 die xxx mensis xi annoque mdccclxxx 80 lxxx 1880}
+test clock-2.119 {conversion of 1880-12-01} {
+ clock format -2811151504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1880 12:34:56 die i mensis xii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 336 2408051 12 xii 12 12/01/1880 die i mensis xii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.120 {conversion of 1880-12-31} {
+ clock format -2808559504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1880 12:34:56 die xxxi mensis xii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2408081 12 xii 12 12/31/1880 die xxxi mensis xii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.121 {conversion of 1881-01-01} {
+ clock format -2808473104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1881 12:34:56 die i mensis i annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2408082 01 i 1 01/01/1881 die i mensis i annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.122 {conversion of 1881-01-31} {
+ clock format -2805881104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1881 12:34:56 die xxxi mensis i annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2408112 01 i 1 01/31/1881 die xxxi mensis i annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.123 {conversion of 1881-02-01} {
+ clock format -2805794704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1881 12:34:56 die i mensis ii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2408113 02 ii 2 02/01/1881 die i mensis ii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.124 {conversion of 1881-02-28} {
+ clock format -2803461904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1881 12:34:56 die xxviii mensis ii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2408140 02 ii 2 02/28/1881 die xxviii mensis ii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.125 {conversion of 1881-03-01} {
+ clock format -2803375504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1881 12:34:56 die i mensis iii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2408141 03 iii 3 03/01/1881 die i mensis iii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.126 {conversion of 1881-03-31} {
+ clock format -2800783504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1881 12:34:56 die xxxi mensis iii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2408171 03 iii 3 03/31/1881 die xxxi mensis iii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.127 {conversion of 1881-04-01} {
+ clock format -2800697104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1881 12:34:56 die i mensis iv annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2408172 04 iv 4 04/01/1881 die i mensis iv annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.128 {conversion of 1881-04-30} {
+ clock format -2798191504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1881 12:34:56 die xxx mensis iv annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2408201 04 iv 4 04/30/1881 die xxx mensis iv annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.129 {conversion of 1881-05-01} {
+ clock format -2798105104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1881 12:34:56 die i mensis v annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2408202 05 v 5 05/01/1881 die i mensis v annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.130 {conversion of 1881-05-31} {
+ clock format -2795513104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1881 12:34:56 die xxxi mensis v annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2408232 05 v 5 05/31/1881 die xxxi mensis v annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.131 {conversion of 1881-06-01} {
+ clock format -2795426704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1881 12:34:56 die i mensis vi annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2408233 06 vi 6 06/01/1881 die i mensis vi annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.132 {conversion of 1881-06-30} {
+ clock format -2792921104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1881 12:34:56 die xxx mensis vi annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2408262 06 vi 6 06/30/1881 die xxx mensis vi annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.133 {conversion of 1881-07-01} {
+ clock format -2792834704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1881 12:34:56 die i mensis vii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2408263 07 vii 7 07/01/1881 die i mensis vii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.134 {conversion of 1881-07-31} {
+ clock format -2790242704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1881 12:34:56 die xxxi mensis vii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2408293 07 vii 7 07/31/1881 die xxxi mensis vii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.135 {conversion of 1881-08-01} {
+ clock format -2790156304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1881 12:34:56 die i mensis viii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2408294 08 viii 8 08/01/1881 die i mensis viii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.136 {conversion of 1881-08-31} {
+ clock format -2787564304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1881 12:34:56 die xxxi mensis viii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2408324 08 viii 8 08/31/1881 die xxxi mensis viii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.137 {conversion of 1881-09-01} {
+ clock format -2787477904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1881 12:34:56 die i mensis ix annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2408325 09 ix 9 09/01/1881 die i mensis ix annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.138 {conversion of 1881-09-30} {
+ clock format -2784972304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1881 12:34:56 die xxx mensis ix annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2408354 09 ix 9 09/30/1881 die xxx mensis ix annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.139 {conversion of 1881-10-01} {
+ clock format -2784885904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1881 12:34:56 die i mensis x annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2408355 10 x 10 10/01/1881 die i mensis x annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.140 {conversion of 1881-10-31} {
+ clock format -2782293904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1881 12:34:56 die xxxi mensis x annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2408385 10 x 10 10/31/1881 die xxxi mensis x annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.141 {conversion of 1881-11-01} {
+ clock format -2782207504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1881 12:34:56 die i mensis xi annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2408386 11 xi 11 11/01/1881 die i mensis xi annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.142 {conversion of 1881-11-30} {
+ clock format -2779701904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1881 12:34:56 die xxx mensis xi annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2408415 11 xi 11 11/30/1881 die xxx mensis xi annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.143 {conversion of 1881-12-01} {
+ clock format -2779615504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1881 12:34:56 die i mensis xii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2408416 12 xii 12 12/01/1881 die i mensis xii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.144 {conversion of 1881-12-31} {
+ clock format -2777023504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1881 12:34:56 die xxxi mensis xii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2408446 12 xii 12 12/31/1881 die xxxi mensis xii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.145 {conversion of 1884-01-01} {
+ clock format -2713865104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1884 12:34:56 die i mensis i annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2409177 01 i 1 01/01/1884 die i mensis i annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.146 {conversion of 1884-01-31} {
+ clock format -2711273104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1884 12:34:56 die xxxi mensis i annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2409207 01 i 1 01/31/1884 die xxxi mensis i annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.147 {conversion of 1884-02-01} {
+ clock format -2711186704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1884 12:34:56 die i mensis ii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2409208 02 ii 2 02/01/1884 die i mensis ii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.148 {conversion of 1884-02-29} {
+ clock format -2708767504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1884 12:34:56 die xxix mensis ii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2409236 02 ii 2 02/29/1884 die xxix mensis ii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.149 {conversion of 1884-03-01} {
+ clock format -2708681104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1884 12:34:56 die i mensis iii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 061 2409237 03 iii 3 03/01/1884 die i mensis iii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.150 {conversion of 1884-03-31} {
+ clock format -2706089104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1884 12:34:56 die xxxi mensis iii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2409267 03 iii 3 03/31/1884 die xxxi mensis iii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.151 {conversion of 1884-04-01} {
+ clock format -2706002704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1884 12:34:56 die i mensis iv annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 092 2409268 04 iv 4 04/01/1884 die i mensis iv annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.152 {conversion of 1884-04-30} {
+ clock format -2703497104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1884 12:34:56 die xxx mensis iv annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2409297 04 iv 4 04/30/1884 die xxx mensis iv annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.153 {conversion of 1884-05-01} {
+ clock format -2703410704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1884 12:34:56 die i mensis v annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 122 2409298 05 v 5 05/01/1884 die i mensis v annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.154 {conversion of 1884-05-31} {
+ clock format -2700818704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1884 12:34:56 die xxxi mensis v annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2409328 05 v 5 05/31/1884 die xxxi mensis v annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.155 {conversion of 1884-06-01} {
+ clock format -2700732304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1884 12:34:56 die i mensis vi annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 153 2409329 06 vi 6 06/01/1884 die i mensis vi annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.156 {conversion of 1884-06-30} {
+ clock format -2698226704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1884 12:34:56 die xxx mensis vi annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2409358 06 vi 6 06/30/1884 die xxx mensis vi annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.157 {conversion of 1884-07-01} {
+ clock format -2698140304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1884 12:34:56 die i mensis vii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 183 2409359 07 vii 7 07/01/1884 die i mensis vii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.158 {conversion of 1884-07-31} {
+ clock format -2695548304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1884 12:34:56 die xxxi mensis vii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2409389 07 vii 7 07/31/1884 die xxxi mensis vii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.159 {conversion of 1884-08-01} {
+ clock format -2695461904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1884 12:34:56 die i mensis viii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 214 2409390 08 viii 8 08/01/1884 die i mensis viii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.160 {conversion of 1884-08-31} {
+ clock format -2692869904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1884 12:34:56 die xxxi mensis viii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2409420 08 viii 8 08/31/1884 die xxxi mensis viii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.161 {conversion of 1884-09-01} {
+ clock format -2692783504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1884 12:34:56 die i mensis ix annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 245 2409421 09 ix 9 09/01/1884 die i mensis ix annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.162 {conversion of 1884-09-30} {
+ clock format -2690277904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1884 12:34:56 die xxx mensis ix annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2409450 09 ix 9 09/30/1884 die xxx mensis ix annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.163 {conversion of 1884-10-01} {
+ clock format -2690191504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1884 12:34:56 die i mensis x annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 275 2409451 10 x 10 10/01/1884 die i mensis x annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.164 {conversion of 1884-10-31} {
+ clock format -2687599504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1884 12:34:56 die xxxi mensis x annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2409481 10 x 10 10/31/1884 die xxxi mensis x annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.165 {conversion of 1884-11-01} {
+ clock format -2687513104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1884 12:34:56 die i mensis xi annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 306 2409482 11 xi 11 11/01/1884 die i mensis xi annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.166 {conversion of 1884-11-30} {
+ clock format -2685007504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1884 12:34:56 die xxx mensis xi annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2409511 11 xi 11 11/30/1884 die xxx mensis xi annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.167 {conversion of 1884-12-01} {
+ clock format -2684921104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1884 12:34:56 die i mensis xii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 336 2409512 12 xii 12 12/01/1884 die i mensis xii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.168 {conversion of 1884-12-31} {
+ clock format -2682329104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1884 12:34:56 die xxxi mensis xii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2409542 12 xii 12 12/31/1884 die xxxi mensis xii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.169 {conversion of 1885-01-01} {
+ clock format -2682242704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1885 12:34:56 die i mensis i annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2409543 01 i 1 01/01/1885 die i mensis i annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.170 {conversion of 1885-01-31} {
+ clock format -2679650704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1885 12:34:56 die xxxi mensis i annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2409573 01 i 1 01/31/1885 die xxxi mensis i annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.171 {conversion of 1885-02-01} {
+ clock format -2679564304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1885 12:34:56 die i mensis ii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2409574 02 ii 2 02/01/1885 die i mensis ii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.172 {conversion of 1885-02-28} {
+ clock format -2677231504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1885 12:34:56 die xxviii mensis ii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2409601 02 ii 2 02/28/1885 die xxviii mensis ii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.173 {conversion of 1885-03-01} {
+ clock format -2677145104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1885 12:34:56 die i mensis iii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2409602 03 iii 3 03/01/1885 die i mensis iii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.174 {conversion of 1885-03-31} {
+ clock format -2674553104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1885 12:34:56 die xxxi mensis iii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2409632 03 iii 3 03/31/1885 die xxxi mensis iii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.175 {conversion of 1885-04-01} {
+ clock format -2674466704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1885 12:34:56 die i mensis iv annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2409633 04 iv 4 04/01/1885 die i mensis iv annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.176 {conversion of 1885-04-30} {
+ clock format -2671961104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1885 12:34:56 die xxx mensis iv annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2409662 04 iv 4 04/30/1885 die xxx mensis iv annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.177 {conversion of 1885-05-01} {
+ clock format -2671874704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1885 12:34:56 die i mensis v annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2409663 05 v 5 05/01/1885 die i mensis v annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.178 {conversion of 1885-05-31} {
+ clock format -2669282704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1885 12:34:56 die xxxi mensis v annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2409693 05 v 5 05/31/1885 die xxxi mensis v annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.179 {conversion of 1885-06-01} {
+ clock format -2669196304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1885 12:34:56 die i mensis vi annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2409694 06 vi 6 06/01/1885 die i mensis vi annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.180 {conversion of 1885-06-30} {
+ clock format -2666690704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1885 12:34:56 die xxx mensis vi annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2409723 06 vi 6 06/30/1885 die xxx mensis vi annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.181 {conversion of 1885-07-01} {
+ clock format -2666604304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1885 12:34:56 die i mensis vii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2409724 07 vii 7 07/01/1885 die i mensis vii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.182 {conversion of 1885-07-31} {
+ clock format -2664012304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1885 12:34:56 die xxxi mensis vii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2409754 07 vii 7 07/31/1885 die xxxi mensis vii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.183 {conversion of 1885-08-01} {
+ clock format -2663925904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1885 12:34:56 die i mensis viii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2409755 08 viii 8 08/01/1885 die i mensis viii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.184 {conversion of 1885-08-31} {
+ clock format -2661333904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1885 12:34:56 die xxxi mensis viii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2409785 08 viii 8 08/31/1885 die xxxi mensis viii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.185 {conversion of 1885-09-01} {
+ clock format -2661247504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1885 12:34:56 die i mensis ix annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2409786 09 ix 9 09/01/1885 die i mensis ix annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.186 {conversion of 1885-09-30} {
+ clock format -2658741904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1885 12:34:56 die xxx mensis ix annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2409815 09 ix 9 09/30/1885 die xxx mensis ix annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.187 {conversion of 1885-10-01} {
+ clock format -2658655504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1885 12:34:56 die i mensis x annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2409816 10 x 10 10/01/1885 die i mensis x annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.188 {conversion of 1885-10-31} {
+ clock format -2656063504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1885 12:34:56 die xxxi mensis x annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2409846 10 x 10 10/31/1885 die xxxi mensis x annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.189 {conversion of 1885-11-01} {
+ clock format -2655977104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1885 12:34:56 die i mensis xi annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2409847 11 xi 11 11/01/1885 die i mensis xi annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.190 {conversion of 1885-11-30} {
+ clock format -2653471504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1885 12:34:56 die xxx mensis xi annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2409876 11 xi 11 11/30/1885 die xxx mensis xi annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.191 {conversion of 1885-12-01} {
+ clock format -2653385104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1885 12:34:56 die i mensis xii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2409877 12 xii 12 12/01/1885 die i mensis xii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.192 {conversion of 1885-12-31} {
+ clock format -2650793104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1885 12:34:56 die xxxi mensis xii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2409907 12 xii 12 12/31/1885 die xxxi mensis xii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.193 {conversion of 1888-01-01} {
+ clock format -2587634704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1888 12:34:56 die i mensis i annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2410638 01 i 1 01/01/1888 die i mensis i annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.194 {conversion of 1888-01-31} {
+ clock format -2585042704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1888 12:34:56 die xxxi mensis i annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2410668 01 i 1 01/31/1888 die xxxi mensis i annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.195 {conversion of 1888-02-01} {
+ clock format -2584956304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1888 12:34:56 die i mensis ii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2410669 02 ii 2 02/01/1888 die i mensis ii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.196 {conversion of 1888-02-29} {
+ clock format -2582537104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1888 12:34:56 die xxix mensis ii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2410697 02 ii 2 02/29/1888 die xxix mensis ii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.197 {conversion of 1888-03-01} {
+ clock format -2582450704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1888 12:34:56 die i mensis iii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 061 2410698 03 iii 3 03/01/1888 die i mensis iii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.198 {conversion of 1888-03-31} {
+ clock format -2579858704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1888 12:34:56 die xxxi mensis iii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2410728 03 iii 3 03/31/1888 die xxxi mensis iii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.199 {conversion of 1888-04-01} {
+ clock format -2579772304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1888 12:34:56 die i mensis iv annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 092 2410729 04 iv 4 04/01/1888 die i mensis iv annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.200 {conversion of 1888-04-30} {
+ clock format -2577266704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1888 12:34:56 die xxx mensis iv annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2410758 04 iv 4 04/30/1888 die xxx mensis iv annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.201 {conversion of 1888-05-01} {
+ clock format -2577180304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1888 12:34:56 die i mensis v annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 122 2410759 05 v 5 05/01/1888 die i mensis v annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.202 {conversion of 1888-05-31} {
+ clock format -2574588304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1888 12:34:56 die xxxi mensis v annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2410789 05 v 5 05/31/1888 die xxxi mensis v annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.203 {conversion of 1888-06-01} {
+ clock format -2574501904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1888 12:34:56 die i mensis vi annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 153 2410790 06 vi 6 06/01/1888 die i mensis vi annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.204 {conversion of 1888-06-30} {
+ clock format -2571996304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1888 12:34:56 die xxx mensis vi annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2410819 06 vi 6 06/30/1888 die xxx mensis vi annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.205 {conversion of 1888-07-01} {
+ clock format -2571909904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1888 12:34:56 die i mensis vii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 183 2410820 07 vii 7 07/01/1888 die i mensis vii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.206 {conversion of 1888-07-31} {
+ clock format -2569317904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1888 12:34:56 die xxxi mensis vii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2410850 07 vii 7 07/31/1888 die xxxi mensis vii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.207 {conversion of 1888-08-01} {
+ clock format -2569231504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1888 12:34:56 die i mensis viii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 214 2410851 08 viii 8 08/01/1888 die i mensis viii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.208 {conversion of 1888-08-31} {
+ clock format -2566639504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1888 12:34:56 die xxxi mensis viii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2410881 08 viii 8 08/31/1888 die xxxi mensis viii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.209 {conversion of 1888-09-01} {
+ clock format -2566553104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1888 12:34:56 die i mensis ix annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 245 2410882 09 ix 9 09/01/1888 die i mensis ix annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.210 {conversion of 1888-09-30} {
+ clock format -2564047504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1888 12:34:56 die xxx mensis ix annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2410911 09 ix 9 09/30/1888 die xxx mensis ix annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.211 {conversion of 1888-10-01} {
+ clock format -2563961104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1888 12:34:56 die i mensis x annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 275 2410912 10 x 10 10/01/1888 die i mensis x annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.212 {conversion of 1888-10-31} {
+ clock format -2561369104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1888 12:34:56 die xxxi mensis x annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2410942 10 x 10 10/31/1888 die xxxi mensis x annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.213 {conversion of 1888-11-01} {
+ clock format -2561282704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1888 12:34:56 die i mensis xi annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 306 2410943 11 xi 11 11/01/1888 die i mensis xi annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.214 {conversion of 1888-11-30} {
+ clock format -2558777104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1888 12:34:56 die xxx mensis xi annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2410972 11 xi 11 11/30/1888 die xxx mensis xi annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.215 {conversion of 1888-12-01} {
+ clock format -2558690704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1888 12:34:56 die i mensis xii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 336 2410973 12 xii 12 12/01/1888 die i mensis xii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.216 {conversion of 1888-12-31} {
+ clock format -2556098704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1888 12:34:56 die xxxi mensis xii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2411003 12 xii 12 12/31/1888 die xxxi mensis xii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.217 {conversion of 1889-01-01} {
+ clock format -2556012304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1889 12:34:56 die i mensis i annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2411004 01 i 1 01/01/1889 die i mensis i annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.218 {conversion of 1889-01-31} {
+ clock format -2553420304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1889 12:34:56 die xxxi mensis i annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2411034 01 i 1 01/31/1889 die xxxi mensis i annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.219 {conversion of 1889-02-01} {
+ clock format -2553333904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1889 12:34:56 die i mensis ii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2411035 02 ii 2 02/01/1889 die i mensis ii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.220 {conversion of 1889-02-28} {
+ clock format -2551001104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1889 12:34:56 die xxviii mensis ii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2411062 02 ii 2 02/28/1889 die xxviii mensis ii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.221 {conversion of 1889-03-01} {
+ clock format -2550914704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1889 12:34:56 die i mensis iii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2411063 03 iii 3 03/01/1889 die i mensis iii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.222 {conversion of 1889-03-31} {
+ clock format -2548322704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1889 12:34:56 die xxxi mensis iii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2411093 03 iii 3 03/31/1889 die xxxi mensis iii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.223 {conversion of 1889-04-01} {
+ clock format -2548236304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1889 12:34:56 die i mensis iv annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2411094 04 iv 4 04/01/1889 die i mensis iv annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.224 {conversion of 1889-04-30} {
+ clock format -2545730704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1889 12:34:56 die xxx mensis iv annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2411123 04 iv 4 04/30/1889 die xxx mensis iv annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.225 {conversion of 1889-05-01} {
+ clock format -2545644304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1889 12:34:56 die i mensis v annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2411124 05 v 5 05/01/1889 die i mensis v annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.226 {conversion of 1889-05-31} {
+ clock format -2543052304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1889 12:34:56 die xxxi mensis v annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2411154 05 v 5 05/31/1889 die xxxi mensis v annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.227 {conversion of 1889-06-01} {
+ clock format -2542965904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1889 12:34:56 die i mensis vi annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2411155 06 vi 6 06/01/1889 die i mensis vi annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.228 {conversion of 1889-06-30} {
+ clock format -2540460304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1889 12:34:56 die xxx mensis vi annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2411184 06 vi 6 06/30/1889 die xxx mensis vi annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.229 {conversion of 1889-07-01} {
+ clock format -2540373904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1889 12:34:56 die i mensis vii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2411185 07 vii 7 07/01/1889 die i mensis vii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.230 {conversion of 1889-07-31} {
+ clock format -2537781904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1889 12:34:56 die xxxi mensis vii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2411215 07 vii 7 07/31/1889 die xxxi mensis vii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.231 {conversion of 1889-08-01} {
+ clock format -2537695504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1889 12:34:56 die i mensis viii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2411216 08 viii 8 08/01/1889 die i mensis viii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.232 {conversion of 1889-08-31} {
+ clock format -2535103504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1889 12:34:56 die xxxi mensis viii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2411246 08 viii 8 08/31/1889 die xxxi mensis viii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.233 {conversion of 1889-09-01} {
+ clock format -2535017104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1889 12:34:56 die i mensis ix annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2411247 09 ix 9 09/01/1889 die i mensis ix annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.234 {conversion of 1889-09-30} {
+ clock format -2532511504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1889 12:34:56 die xxx mensis ix annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2411276 09 ix 9 09/30/1889 die xxx mensis ix annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.235 {conversion of 1889-10-01} {
+ clock format -2532425104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1889 12:34:56 die i mensis x annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2411277 10 x 10 10/01/1889 die i mensis x annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.236 {conversion of 1889-10-31} {
+ clock format -2529833104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1889 12:34:56 die xxxi mensis x annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2411307 10 x 10 10/31/1889 die xxxi mensis x annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.237 {conversion of 1889-11-01} {
+ clock format -2529746704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1889 12:34:56 die i mensis xi annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2411308 11 xi 11 11/01/1889 die i mensis xi annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.238 {conversion of 1889-11-30} {
+ clock format -2527241104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1889 12:34:56 die xxx mensis xi annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2411337 11 xi 11 11/30/1889 die xxx mensis xi annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.239 {conversion of 1889-12-01} {
+ clock format -2527154704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1889 12:34:56 die i mensis xii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2411338 12 xii 12 12/01/1889 die i mensis xii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.240 {conversion of 1889-12-31} {
+ clock format -2524562704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1889 12:34:56 die xxxi mensis xii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2411368 12 xii 12 12/31/1889 die xxxi mensis xii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.241 {conversion of 1890-01-01} {
+ clock format -2524476304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1890 12:34:56 die i mensis i annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2411369 01 i 1 01/01/1890 die i mensis i annoque mdcccxc 90 xc 1890}
+test clock-2.242 {conversion of 1890-01-31} {
+ clock format -2521884304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1890 12:34:56 die xxxi mensis i annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2411399 01 i 1 01/31/1890 die xxxi mensis i annoque mdcccxc 90 xc 1890}
+test clock-2.243 {conversion of 1890-02-01} {
+ clock format -2521797904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1890 12:34:56 die i mensis ii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2411400 02 ii 2 02/01/1890 die i mensis ii annoque mdcccxc 90 xc 1890}
+test clock-2.244 {conversion of 1890-02-28} {
+ clock format -2519465104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1890 12:34:56 die xxviii mensis ii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2411427 02 ii 2 02/28/1890 die xxviii mensis ii annoque mdcccxc 90 xc 1890}
+test clock-2.245 {conversion of 1890-03-01} {
+ clock format -2519378704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1890 12:34:56 die i mensis iii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2411428 03 iii 3 03/01/1890 die i mensis iii annoque mdcccxc 90 xc 1890}
+test clock-2.246 {conversion of 1890-03-31} {
+ clock format -2516786704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1890 12:34:56 die xxxi mensis iii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2411458 03 iii 3 03/31/1890 die xxxi mensis iii annoque mdcccxc 90 xc 1890}
+test clock-2.247 {conversion of 1890-04-01} {
+ clock format -2516700304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1890 12:34:56 die i mensis iv annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2411459 04 iv 4 04/01/1890 die i mensis iv annoque mdcccxc 90 xc 1890}
+test clock-2.248 {conversion of 1890-04-30} {
+ clock format -2514194704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1890 12:34:56 die xxx mensis iv annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2411488 04 iv 4 04/30/1890 die xxx mensis iv annoque mdcccxc 90 xc 1890}
+test clock-2.249 {conversion of 1890-05-01} {
+ clock format -2514108304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1890 12:34:56 die i mensis v annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2411489 05 v 5 05/01/1890 die i mensis v annoque mdcccxc 90 xc 1890}
+test clock-2.250 {conversion of 1890-05-31} {
+ clock format -2511516304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1890 12:34:56 die xxxi mensis v annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2411519 05 v 5 05/31/1890 die xxxi mensis v annoque mdcccxc 90 xc 1890}
+test clock-2.251 {conversion of 1890-06-01} {
+ clock format -2511429904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1890 12:34:56 die i mensis vi annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2411520 06 vi 6 06/01/1890 die i mensis vi annoque mdcccxc 90 xc 1890}
+test clock-2.252 {conversion of 1890-06-30} {
+ clock format -2508924304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1890 12:34:56 die xxx mensis vi annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2411549 06 vi 6 06/30/1890 die xxx mensis vi annoque mdcccxc 90 xc 1890}
+test clock-2.253 {conversion of 1890-07-01} {
+ clock format -2508837904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1890 12:34:56 die i mensis vii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2411550 07 vii 7 07/01/1890 die i mensis vii annoque mdcccxc 90 xc 1890}
+test clock-2.254 {conversion of 1890-07-31} {
+ clock format -2506245904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1890 12:34:56 die xxxi mensis vii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2411580 07 vii 7 07/31/1890 die xxxi mensis vii annoque mdcccxc 90 xc 1890}
+test clock-2.255 {conversion of 1890-08-01} {
+ clock format -2506159504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1890 12:34:56 die i mensis viii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2411581 08 viii 8 08/01/1890 die i mensis viii annoque mdcccxc 90 xc 1890}
+test clock-2.256 {conversion of 1890-08-31} {
+ clock format -2503567504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1890 12:34:56 die xxxi mensis viii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2411611 08 viii 8 08/31/1890 die xxxi mensis viii annoque mdcccxc 90 xc 1890}
+test clock-2.257 {conversion of 1890-09-01} {
+ clock format -2503481104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1890 12:34:56 die i mensis ix annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2411612 09 ix 9 09/01/1890 die i mensis ix annoque mdcccxc 90 xc 1890}
+test clock-2.258 {conversion of 1890-09-30} {
+ clock format -2500975504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1890 12:34:56 die xxx mensis ix annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2411641 09 ix 9 09/30/1890 die xxx mensis ix annoque mdcccxc 90 xc 1890}
+test clock-2.259 {conversion of 1890-10-01} {
+ clock format -2500889104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1890 12:34:56 die i mensis x annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2411642 10 x 10 10/01/1890 die i mensis x annoque mdcccxc 90 xc 1890}
+test clock-2.260 {conversion of 1890-10-31} {
+ clock format -2498297104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1890 12:34:56 die xxxi mensis x annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2411672 10 x 10 10/31/1890 die xxxi mensis x annoque mdcccxc 90 xc 1890}
+test clock-2.261 {conversion of 1890-11-01} {
+ clock format -2498210704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1890 12:34:56 die i mensis xi annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2411673 11 xi 11 11/01/1890 die i mensis xi annoque mdcccxc 90 xc 1890}
+test clock-2.262 {conversion of 1890-11-30} {
+ clock format -2495705104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1890 12:34:56 die xxx mensis xi annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2411702 11 xi 11 11/30/1890 die xxx mensis xi annoque mdcccxc 90 xc 1890}
+test clock-2.263 {conversion of 1890-12-01} {
+ clock format -2495618704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1890 12:34:56 die i mensis xii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2411703 12 xii 12 12/01/1890 die i mensis xii annoque mdcccxc 90 xc 1890}
+test clock-2.264 {conversion of 1890-12-31} {
+ clock format -2493026704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1890 12:34:56 die xxxi mensis xii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2411733 12 xii 12 12/31/1890 die xxxi mensis xii annoque mdcccxc 90 xc 1890}
+test clock-2.265 {conversion of 1891-01-01} {
+ clock format -2492940304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1891 12:34:56 die i mensis i annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2411734 01 i 1 01/01/1891 die i mensis i annoque mdcccxci 91 xci 1891}
+test clock-2.266 {conversion of 1891-01-31} {
+ clock format -2490348304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1891 12:34:56 die xxxi mensis i annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2411764 01 i 1 01/31/1891 die xxxi mensis i annoque mdcccxci 91 xci 1891}
+test clock-2.267 {conversion of 1891-02-01} {
+ clock format -2490261904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1891 12:34:56 die i mensis ii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2411765 02 ii 2 02/01/1891 die i mensis ii annoque mdcccxci 91 xci 1891}
+test clock-2.268 {conversion of 1891-02-28} {
+ clock format -2487929104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1891 12:34:56 die xxviii mensis ii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2411792 02 ii 2 02/28/1891 die xxviii mensis ii annoque mdcccxci 91 xci 1891}
+test clock-2.269 {conversion of 1891-03-01} {
+ clock format -2487842704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1891 12:34:56 die i mensis iii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2411793 03 iii 3 03/01/1891 die i mensis iii annoque mdcccxci 91 xci 1891}
+test clock-2.270 {conversion of 1891-03-31} {
+ clock format -2485250704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1891 12:34:56 die xxxi mensis iii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2411823 03 iii 3 03/31/1891 die xxxi mensis iii annoque mdcccxci 91 xci 1891}
+test clock-2.271 {conversion of 1891-04-01} {
+ clock format -2485164304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1891 12:34:56 die i mensis iv annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2411824 04 iv 4 04/01/1891 die i mensis iv annoque mdcccxci 91 xci 1891}
+test clock-2.272 {conversion of 1891-04-30} {
+ clock format -2482658704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1891 12:34:56 die xxx mensis iv annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2411853 04 iv 4 04/30/1891 die xxx mensis iv annoque mdcccxci 91 xci 1891}
+test clock-2.273 {conversion of 1891-05-01} {
+ clock format -2482572304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1891 12:34:56 die i mensis v annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2411854 05 v 5 05/01/1891 die i mensis v annoque mdcccxci 91 xci 1891}
+test clock-2.274 {conversion of 1891-05-31} {
+ clock format -2479980304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1891 12:34:56 die xxxi mensis v annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2411884 05 v 5 05/31/1891 die xxxi mensis v annoque mdcccxci 91 xci 1891}
+test clock-2.275 {conversion of 1891-06-01} {
+ clock format -2479893904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1891 12:34:56 die i mensis vi annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2411885 06 vi 6 06/01/1891 die i mensis vi annoque mdcccxci 91 xci 1891}
+test clock-2.276 {conversion of 1891-06-30} {
+ clock format -2477388304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1891 12:34:56 die xxx mensis vi annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2411914 06 vi 6 06/30/1891 die xxx mensis vi annoque mdcccxci 91 xci 1891}
+test clock-2.277 {conversion of 1891-07-01} {
+ clock format -2477301904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1891 12:34:56 die i mensis vii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2411915 07 vii 7 07/01/1891 die i mensis vii annoque mdcccxci 91 xci 1891}
+test clock-2.278 {conversion of 1891-07-31} {
+ clock format -2474709904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1891 12:34:56 die xxxi mensis vii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2411945 07 vii 7 07/31/1891 die xxxi mensis vii annoque mdcccxci 91 xci 1891}
+test clock-2.279 {conversion of 1891-08-01} {
+ clock format -2474623504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1891 12:34:56 die i mensis viii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2411946 08 viii 8 08/01/1891 die i mensis viii annoque mdcccxci 91 xci 1891}
+test clock-2.280 {conversion of 1891-08-31} {
+ clock format -2472031504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1891 12:34:56 die xxxi mensis viii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2411976 08 viii 8 08/31/1891 die xxxi mensis viii annoque mdcccxci 91 xci 1891}
+test clock-2.281 {conversion of 1891-09-01} {
+ clock format -2471945104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1891 12:34:56 die i mensis ix annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2411977 09 ix 9 09/01/1891 die i mensis ix annoque mdcccxci 91 xci 1891}
+test clock-2.282 {conversion of 1891-09-30} {
+ clock format -2469439504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1891 12:34:56 die xxx mensis ix annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2412006 09 ix 9 09/30/1891 die xxx mensis ix annoque mdcccxci 91 xci 1891}
+test clock-2.283 {conversion of 1891-10-01} {
+ clock format -2469353104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1891 12:34:56 die i mensis x annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2412007 10 x 10 10/01/1891 die i mensis x annoque mdcccxci 91 xci 1891}
+test clock-2.284 {conversion of 1891-10-31} {
+ clock format -2466761104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1891 12:34:56 die xxxi mensis x annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2412037 10 x 10 10/31/1891 die xxxi mensis x annoque mdcccxci 91 xci 1891}
+test clock-2.285 {conversion of 1891-11-01} {
+ clock format -2466674704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1891 12:34:56 die i mensis xi annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2412038 11 xi 11 11/01/1891 die i mensis xi annoque mdcccxci 91 xci 1891}
+test clock-2.286 {conversion of 1891-11-30} {
+ clock format -2464169104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1891 12:34:56 die xxx mensis xi annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2412067 11 xi 11 11/30/1891 die xxx mensis xi annoque mdcccxci 91 xci 1891}
+test clock-2.287 {conversion of 1891-12-01} {
+ clock format -2464082704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1891 12:34:56 die i mensis xii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2412068 12 xii 12 12/01/1891 die i mensis xii annoque mdcccxci 91 xci 1891}
+test clock-2.288 {conversion of 1891-12-31} {
+ clock format -2461490704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1891 12:34:56 die xxxi mensis xii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2412098 12 xii 12 12/31/1891 die xxxi mensis xii annoque mdcccxci 91 xci 1891}
+test clock-2.289 {conversion of 1892-01-01} {
+ clock format -2461404304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1892 12:34:56 die i mensis i annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2412099 01 i 1 01/01/1892 die i mensis i annoque mdcccxcii 92 xcii 1892}
+test clock-2.290 {conversion of 1892-01-31} {
+ clock format -2458812304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1892 12:34:56 die xxxi mensis i annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2412129 01 i 1 01/31/1892 die xxxi mensis i annoque mdcccxcii 92 xcii 1892}
+test clock-2.291 {conversion of 1892-02-01} {
+ clock format -2458725904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1892 12:34:56 die i mensis ii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2412130 02 ii 2 02/01/1892 die i mensis ii annoque mdcccxcii 92 xcii 1892}
+test clock-2.292 {conversion of 1892-02-29} {
+ clock format -2456306704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1892 12:34:56 die xxix mensis ii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2412158 02 ii 2 02/29/1892 die xxix mensis ii annoque mdcccxcii 92 xcii 1892}
+test clock-2.293 {conversion of 1892-03-01} {
+ clock format -2456220304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1892 12:34:56 die i mensis iii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 061 2412159 03 iii 3 03/01/1892 die i mensis iii annoque mdcccxcii 92 xcii 1892}
+test clock-2.294 {conversion of 1892-03-31} {
+ clock format -2453628304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1892 12:34:56 die xxxi mensis iii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2412189 03 iii 3 03/31/1892 die xxxi mensis iii annoque mdcccxcii 92 xcii 1892}
+test clock-2.295 {conversion of 1892-04-01} {
+ clock format -2453541904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1892 12:34:56 die i mensis iv annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 092 2412190 04 iv 4 04/01/1892 die i mensis iv annoque mdcccxcii 92 xcii 1892}
+test clock-2.296 {conversion of 1892-04-30} {
+ clock format -2451036304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1892 12:34:56 die xxx mensis iv annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2412219 04 iv 4 04/30/1892 die xxx mensis iv annoque mdcccxcii 92 xcii 1892}
+test clock-2.297 {conversion of 1892-05-01} {
+ clock format -2450949904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1892 12:34:56 die i mensis v annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 122 2412220 05 v 5 05/01/1892 die i mensis v annoque mdcccxcii 92 xcii 1892}
+test clock-2.298 {conversion of 1892-05-31} {
+ clock format -2448357904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1892 12:34:56 die xxxi mensis v annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2412250 05 v 5 05/31/1892 die xxxi mensis v annoque mdcccxcii 92 xcii 1892}
+test clock-2.299 {conversion of 1892-06-01} {
+ clock format -2448271504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1892 12:34:56 die i mensis vi annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 153 2412251 06 vi 6 06/01/1892 die i mensis vi annoque mdcccxcii 92 xcii 1892}
+test clock-2.300 {conversion of 1892-06-30} {
+ clock format -2445765904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1892 12:34:56 die xxx mensis vi annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2412280 06 vi 6 06/30/1892 die xxx mensis vi annoque mdcccxcii 92 xcii 1892}
+test clock-2.301 {conversion of 1892-07-01} {
+ clock format -2445679504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1892 12:34:56 die i mensis vii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 183 2412281 07 vii 7 07/01/1892 die i mensis vii annoque mdcccxcii 92 xcii 1892}
+test clock-2.302 {conversion of 1892-07-31} {
+ clock format -2443087504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1892 12:34:56 die xxxi mensis vii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2412311 07 vii 7 07/31/1892 die xxxi mensis vii annoque mdcccxcii 92 xcii 1892}
+test clock-2.303 {conversion of 1892-08-01} {
+ clock format -2443001104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1892 12:34:56 die i mensis viii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 214 2412312 08 viii 8 08/01/1892 die i mensis viii annoque mdcccxcii 92 xcii 1892}
+test clock-2.304 {conversion of 1892-08-31} {
+ clock format -2440409104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1892 12:34:56 die xxxi mensis viii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2412342 08 viii 8 08/31/1892 die xxxi mensis viii annoque mdcccxcii 92 xcii 1892}
+test clock-2.305 {conversion of 1892-09-01} {
+ clock format -2440322704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1892 12:34:56 die i mensis ix annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 245 2412343 09 ix 9 09/01/1892 die i mensis ix annoque mdcccxcii 92 xcii 1892}
+test clock-2.306 {conversion of 1892-09-30} {
+ clock format -2437817104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1892 12:34:56 die xxx mensis ix annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2412372 09 ix 9 09/30/1892 die xxx mensis ix annoque mdcccxcii 92 xcii 1892}
+test clock-2.307 {conversion of 1892-10-01} {
+ clock format -2437730704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1892 12:34:56 die i mensis x annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 275 2412373 10 x 10 10/01/1892 die i mensis x annoque mdcccxcii 92 xcii 1892}
+test clock-2.308 {conversion of 1892-10-31} {
+ clock format -2435138704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1892 12:34:56 die xxxi mensis x annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2412403 10 x 10 10/31/1892 die xxxi mensis x annoque mdcccxcii 92 xcii 1892}
+test clock-2.309 {conversion of 1892-11-01} {
+ clock format -2435052304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1892 12:34:56 die i mensis xi annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 306 2412404 11 xi 11 11/01/1892 die i mensis xi annoque mdcccxcii 92 xcii 1892}
+test clock-2.310 {conversion of 1892-11-30} {
+ clock format -2432546704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1892 12:34:56 die xxx mensis xi annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2412433 11 xi 11 11/30/1892 die xxx mensis xi annoque mdcccxcii 92 xcii 1892}
+test clock-2.311 {conversion of 1892-12-01} {
+ clock format -2432460304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1892 12:34:56 die i mensis xii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 336 2412434 12 xii 12 12/01/1892 die i mensis xii annoque mdcccxcii 92 xcii 1892}
+test clock-2.312 {conversion of 1892-12-31} {
+ clock format -2429868304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1892 12:34:56 die xxxi mensis xii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2412464 12 xii 12 12/31/1892 die xxxi mensis xii annoque mdcccxcii 92 xcii 1892}
+test clock-2.313 {conversion of 1893-01-01} {
+ clock format -2429781904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1893 12:34:56 die i mensis i annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2412465 01 i 1 01/01/1893 die i mensis i annoque mdcccxciii 93 xciii 1893}
+test clock-2.314 {conversion of 1893-01-31} {
+ clock format -2427189904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1893 12:34:56 die xxxi mensis i annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2412495 01 i 1 01/31/1893 die xxxi mensis i annoque mdcccxciii 93 xciii 1893}
+test clock-2.315 {conversion of 1893-02-01} {
+ clock format -2427103504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1893 12:34:56 die i mensis ii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2412496 02 ii 2 02/01/1893 die i mensis ii annoque mdcccxciii 93 xciii 1893}
+test clock-2.316 {conversion of 1893-02-28} {
+ clock format -2424770704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1893 12:34:56 die xxviii mensis ii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2412523 02 ii 2 02/28/1893 die xxviii mensis ii annoque mdcccxciii 93 xciii 1893}
+test clock-2.317 {conversion of 1893-03-01} {
+ clock format -2424684304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1893 12:34:56 die i mensis iii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2412524 03 iii 3 03/01/1893 die i mensis iii annoque mdcccxciii 93 xciii 1893}
+test clock-2.318 {conversion of 1893-03-31} {
+ clock format -2422092304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1893 12:34:56 die xxxi mensis iii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2412554 03 iii 3 03/31/1893 die xxxi mensis iii annoque mdcccxciii 93 xciii 1893}
+test clock-2.319 {conversion of 1893-04-01} {
+ clock format -2422005904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1893 12:34:56 die i mensis iv annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2412555 04 iv 4 04/01/1893 die i mensis iv annoque mdcccxciii 93 xciii 1893}
+test clock-2.320 {conversion of 1893-04-30} {
+ clock format -2419500304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1893 12:34:56 die xxx mensis iv annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2412584 04 iv 4 04/30/1893 die xxx mensis iv annoque mdcccxciii 93 xciii 1893}
+test clock-2.321 {conversion of 1893-05-01} {
+ clock format -2419413904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1893 12:34:56 die i mensis v annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2412585 05 v 5 05/01/1893 die i mensis v annoque mdcccxciii 93 xciii 1893}
+test clock-2.322 {conversion of 1893-05-31} {
+ clock format -2416821904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1893 12:34:56 die xxxi mensis v annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2412615 05 v 5 05/31/1893 die xxxi mensis v annoque mdcccxciii 93 xciii 1893}
+test clock-2.323 {conversion of 1893-06-01} {
+ clock format -2416735504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1893 12:34:56 die i mensis vi annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2412616 06 vi 6 06/01/1893 die i mensis vi annoque mdcccxciii 93 xciii 1893}
+test clock-2.324 {conversion of 1893-06-30} {
+ clock format -2414229904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1893 12:34:56 die xxx mensis vi annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2412645 06 vi 6 06/30/1893 die xxx mensis vi annoque mdcccxciii 93 xciii 1893}
+test clock-2.325 {conversion of 1893-07-01} {
+ clock format -2414143504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1893 12:34:56 die i mensis vii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2412646 07 vii 7 07/01/1893 die i mensis vii annoque mdcccxciii 93 xciii 1893}
+test clock-2.326 {conversion of 1893-07-31} {
+ clock format -2411551504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1893 12:34:56 die xxxi mensis vii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2412676 07 vii 7 07/31/1893 die xxxi mensis vii annoque mdcccxciii 93 xciii 1893}
+test clock-2.327 {conversion of 1893-08-01} {
+ clock format -2411465104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1893 12:34:56 die i mensis viii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2412677 08 viii 8 08/01/1893 die i mensis viii annoque mdcccxciii 93 xciii 1893}
+test clock-2.328 {conversion of 1893-08-31} {
+ clock format -2408873104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1893 12:34:56 die xxxi mensis viii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2412707 08 viii 8 08/31/1893 die xxxi mensis viii annoque mdcccxciii 93 xciii 1893}
+test clock-2.329 {conversion of 1893-09-01} {
+ clock format -2408786704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1893 12:34:56 die i mensis ix annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2412708 09 ix 9 09/01/1893 die i mensis ix annoque mdcccxciii 93 xciii 1893}
+test clock-2.330 {conversion of 1893-09-30} {
+ clock format -2406281104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1893 12:34:56 die xxx mensis ix annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2412737 09 ix 9 09/30/1893 die xxx mensis ix annoque mdcccxciii 93 xciii 1893}
+test clock-2.331 {conversion of 1893-10-01} {
+ clock format -2406194704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1893 12:34:56 die i mensis x annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2412738 10 x 10 10/01/1893 die i mensis x annoque mdcccxciii 93 xciii 1893}
+test clock-2.332 {conversion of 1893-10-31} {
+ clock format -2403602704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1893 12:34:56 die xxxi mensis x annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2412768 10 x 10 10/31/1893 die xxxi mensis x annoque mdcccxciii 93 xciii 1893}
+test clock-2.333 {conversion of 1893-11-01} {
+ clock format -2403516304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1893 12:34:56 die i mensis xi annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2412769 11 xi 11 11/01/1893 die i mensis xi annoque mdcccxciii 93 xciii 1893}
+test clock-2.334 {conversion of 1893-11-30} {
+ clock format -2401010704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1893 12:34:56 die xxx mensis xi annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2412798 11 xi 11 11/30/1893 die xxx mensis xi annoque mdcccxciii 93 xciii 1893}
+test clock-2.335 {conversion of 1893-12-01} {
+ clock format -2400924304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1893 12:34:56 die i mensis xii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2412799 12 xii 12 12/01/1893 die i mensis xii annoque mdcccxciii 93 xciii 1893}
+test clock-2.336 {conversion of 1893-12-31} {
+ clock format -2398332304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1893 12:34:56 die xxxi mensis xii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2412829 12 xii 12 12/31/1893 die xxxi mensis xii annoque mdcccxciii 93 xciii 1893}
+test clock-2.337 {conversion of 1894-01-01} {
+ clock format -2398245904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1894 12:34:56 die i mensis i annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2412830 01 i 1 01/01/1894 die i mensis i annoque mdcccxciv 94 xciv 1894}
+test clock-2.338 {conversion of 1894-01-31} {
+ clock format -2395653904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1894 12:34:56 die xxxi mensis i annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2412860 01 i 1 01/31/1894 die xxxi mensis i annoque mdcccxciv 94 xciv 1894}
+test clock-2.339 {conversion of 1894-02-01} {
+ clock format -2395567504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1894 12:34:56 die i mensis ii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2412861 02 ii 2 02/01/1894 die i mensis ii annoque mdcccxciv 94 xciv 1894}
+test clock-2.340 {conversion of 1894-02-28} {
+ clock format -2393234704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1894 12:34:56 die xxviii mensis ii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2412888 02 ii 2 02/28/1894 die xxviii mensis ii annoque mdcccxciv 94 xciv 1894}
+test clock-2.341 {conversion of 1894-03-01} {
+ clock format -2393148304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1894 12:34:56 die i mensis iii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2412889 03 iii 3 03/01/1894 die i mensis iii annoque mdcccxciv 94 xciv 1894}
+test clock-2.342 {conversion of 1894-03-31} {
+ clock format -2390556304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1894 12:34:56 die xxxi mensis iii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2412919 03 iii 3 03/31/1894 die xxxi mensis iii annoque mdcccxciv 94 xciv 1894}
+test clock-2.343 {conversion of 1894-04-01} {
+ clock format -2390469904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1894 12:34:56 die i mensis iv annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2412920 04 iv 4 04/01/1894 die i mensis iv annoque mdcccxciv 94 xciv 1894}
+test clock-2.344 {conversion of 1894-04-30} {
+ clock format -2387964304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1894 12:34:56 die xxx mensis iv annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2412949 04 iv 4 04/30/1894 die xxx mensis iv annoque mdcccxciv 94 xciv 1894}
+test clock-2.345 {conversion of 1894-05-01} {
+ clock format -2387877904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1894 12:34:56 die i mensis v annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2412950 05 v 5 05/01/1894 die i mensis v annoque mdcccxciv 94 xciv 1894}
+test clock-2.346 {conversion of 1894-05-31} {
+ clock format -2385285904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1894 12:34:56 die xxxi mensis v annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2412980 05 v 5 05/31/1894 die xxxi mensis v annoque mdcccxciv 94 xciv 1894}
+test clock-2.347 {conversion of 1894-06-01} {
+ clock format -2385199504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1894 12:34:56 die i mensis vi annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2412981 06 vi 6 06/01/1894 die i mensis vi annoque mdcccxciv 94 xciv 1894}
+test clock-2.348 {conversion of 1894-06-30} {
+ clock format -2382693904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1894 12:34:56 die xxx mensis vi annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2413010 06 vi 6 06/30/1894 die xxx mensis vi annoque mdcccxciv 94 xciv 1894}
+test clock-2.349 {conversion of 1894-07-01} {
+ clock format -2382607504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1894 12:34:56 die i mensis vii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2413011 07 vii 7 07/01/1894 die i mensis vii annoque mdcccxciv 94 xciv 1894}
+test clock-2.350 {conversion of 1894-07-31} {
+ clock format -2380015504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1894 12:34:56 die xxxi mensis vii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2413041 07 vii 7 07/31/1894 die xxxi mensis vii annoque mdcccxciv 94 xciv 1894}
+test clock-2.351 {conversion of 1894-08-01} {
+ clock format -2379929104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1894 12:34:56 die i mensis viii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2413042 08 viii 8 08/01/1894 die i mensis viii annoque mdcccxciv 94 xciv 1894}
+test clock-2.352 {conversion of 1894-08-31} {
+ clock format -2377337104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1894 12:34:56 die xxxi mensis viii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2413072 08 viii 8 08/31/1894 die xxxi mensis viii annoque mdcccxciv 94 xciv 1894}
+test clock-2.353 {conversion of 1894-09-01} {
+ clock format -2377250704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1894 12:34:56 die i mensis ix annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2413073 09 ix 9 09/01/1894 die i mensis ix annoque mdcccxciv 94 xciv 1894}
+test clock-2.354 {conversion of 1894-09-30} {
+ clock format -2374745104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1894 12:34:56 die xxx mensis ix annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2413102 09 ix 9 09/30/1894 die xxx mensis ix annoque mdcccxciv 94 xciv 1894}
+test clock-2.355 {conversion of 1894-10-01} {
+ clock format -2374658704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1894 12:34:56 die i mensis x annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2413103 10 x 10 10/01/1894 die i mensis x annoque mdcccxciv 94 xciv 1894}
+test clock-2.356 {conversion of 1894-10-31} {
+ clock format -2372066704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1894 12:34:56 die xxxi mensis x annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2413133 10 x 10 10/31/1894 die xxxi mensis x annoque mdcccxciv 94 xciv 1894}
+test clock-2.357 {conversion of 1894-11-01} {
+ clock format -2371980304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1894 12:34:56 die i mensis xi annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2413134 11 xi 11 11/01/1894 die i mensis xi annoque mdcccxciv 94 xciv 1894}
+test clock-2.358 {conversion of 1894-11-30} {
+ clock format -2369474704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1894 12:34:56 die xxx mensis xi annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2413163 11 xi 11 11/30/1894 die xxx mensis xi annoque mdcccxciv 94 xciv 1894}
+test clock-2.359 {conversion of 1894-12-01} {
+ clock format -2369388304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1894 12:34:56 die i mensis xii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2413164 12 xii 12 12/01/1894 die i mensis xii annoque mdcccxciv 94 xciv 1894}
+test clock-2.360 {conversion of 1894-12-31} {
+ clock format -2366796304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1894 12:34:56 die xxxi mensis xii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2413194 12 xii 12 12/31/1894 die xxxi mensis xii annoque mdcccxciv 94 xciv 1894}
+test clock-2.361 {conversion of 1895-01-01} {
+ clock format -2366709904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1895 12:34:56 die i mensis i annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2413195 01 i 1 01/01/1895 die i mensis i annoque mdcccxcv 95 xcv 1895}
+test clock-2.362 {conversion of 1895-01-31} {
+ clock format -2364117904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1895 12:34:56 die xxxi mensis i annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2413225 01 i 1 01/31/1895 die xxxi mensis i annoque mdcccxcv 95 xcv 1895}
+test clock-2.363 {conversion of 1895-02-01} {
+ clock format -2364031504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1895 12:34:56 die i mensis ii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2413226 02 ii 2 02/01/1895 die i mensis ii annoque mdcccxcv 95 xcv 1895}
+test clock-2.364 {conversion of 1895-02-28} {
+ clock format -2361698704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1895 12:34:56 die xxviii mensis ii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2413253 02 ii 2 02/28/1895 die xxviii mensis ii annoque mdcccxcv 95 xcv 1895}
+test clock-2.365 {conversion of 1895-03-01} {
+ clock format -2361612304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1895 12:34:56 die i mensis iii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2413254 03 iii 3 03/01/1895 die i mensis iii annoque mdcccxcv 95 xcv 1895}
+test clock-2.366 {conversion of 1895-03-31} {
+ clock format -2359020304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1895 12:34:56 die xxxi mensis iii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2413284 03 iii 3 03/31/1895 die xxxi mensis iii annoque mdcccxcv 95 xcv 1895}
+test clock-2.367 {conversion of 1895-04-01} {
+ clock format -2358933904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1895 12:34:56 die i mensis iv annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2413285 04 iv 4 04/01/1895 die i mensis iv annoque mdcccxcv 95 xcv 1895}
+test clock-2.368 {conversion of 1895-04-30} {
+ clock format -2356428304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1895 12:34:56 die xxx mensis iv annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2413314 04 iv 4 04/30/1895 die xxx mensis iv annoque mdcccxcv 95 xcv 1895}
+test clock-2.369 {conversion of 1895-05-01} {
+ clock format -2356341904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1895 12:34:56 die i mensis v annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2413315 05 v 5 05/01/1895 die i mensis v annoque mdcccxcv 95 xcv 1895}
+test clock-2.370 {conversion of 1895-05-31} {
+ clock format -2353749904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1895 12:34:56 die xxxi mensis v annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2413345 05 v 5 05/31/1895 die xxxi mensis v annoque mdcccxcv 95 xcv 1895}
+test clock-2.371 {conversion of 1895-06-01} {
+ clock format -2353663504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1895 12:34:56 die i mensis vi annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2413346 06 vi 6 06/01/1895 die i mensis vi annoque mdcccxcv 95 xcv 1895}
+test clock-2.372 {conversion of 1895-06-30} {
+ clock format -2351157904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1895 12:34:56 die xxx mensis vi annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2413375 06 vi 6 06/30/1895 die xxx mensis vi annoque mdcccxcv 95 xcv 1895}
+test clock-2.373 {conversion of 1895-07-01} {
+ clock format -2351071504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1895 12:34:56 die i mensis vii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2413376 07 vii 7 07/01/1895 die i mensis vii annoque mdcccxcv 95 xcv 1895}
+test clock-2.374 {conversion of 1895-07-31} {
+ clock format -2348479504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1895 12:34:56 die xxxi mensis vii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2413406 07 vii 7 07/31/1895 die xxxi mensis vii annoque mdcccxcv 95 xcv 1895}
+test clock-2.375 {conversion of 1895-08-01} {
+ clock format -2348393104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1895 12:34:56 die i mensis viii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2413407 08 viii 8 08/01/1895 die i mensis viii annoque mdcccxcv 95 xcv 1895}
+test clock-2.376 {conversion of 1895-08-31} {
+ clock format -2345801104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1895 12:34:56 die xxxi mensis viii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2413437 08 viii 8 08/31/1895 die xxxi mensis viii annoque mdcccxcv 95 xcv 1895}
+test clock-2.377 {conversion of 1895-09-01} {
+ clock format -2345714704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1895 12:34:56 die i mensis ix annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2413438 09 ix 9 09/01/1895 die i mensis ix annoque mdcccxcv 95 xcv 1895}
+test clock-2.378 {conversion of 1895-09-30} {
+ clock format -2343209104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1895 12:34:56 die xxx mensis ix annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2413467 09 ix 9 09/30/1895 die xxx mensis ix annoque mdcccxcv 95 xcv 1895}
+test clock-2.379 {conversion of 1895-10-01} {
+ clock format -2343122704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1895 12:34:56 die i mensis x annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2413468 10 x 10 10/01/1895 die i mensis x annoque mdcccxcv 95 xcv 1895}
+test clock-2.380 {conversion of 1895-10-31} {
+ clock format -2340530704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1895 12:34:56 die xxxi mensis x annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2413498 10 x 10 10/31/1895 die xxxi mensis x annoque mdcccxcv 95 xcv 1895}
+test clock-2.381 {conversion of 1895-11-01} {
+ clock format -2340444304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1895 12:34:56 die i mensis xi annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2413499 11 xi 11 11/01/1895 die i mensis xi annoque mdcccxcv 95 xcv 1895}
+test clock-2.382 {conversion of 1895-11-30} {
+ clock format -2337938704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1895 12:34:56 die xxx mensis xi annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2413528 11 xi 11 11/30/1895 die xxx mensis xi annoque mdcccxcv 95 xcv 1895}
+test clock-2.383 {conversion of 1895-12-01} {
+ clock format -2337852304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1895 12:34:56 die i mensis xii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2413529 12 xii 12 12/01/1895 die i mensis xii annoque mdcccxcv 95 xcv 1895}
+test clock-2.384 {conversion of 1895-12-31} {
+ clock format -2335260304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1895 12:34:56 die xxxi mensis xii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2413559 12 xii 12 12/31/1895 die xxxi mensis xii annoque mdcccxcv 95 xcv 1895}
+test clock-2.385 {conversion of 1896-01-01} {
+ clock format -2335173904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1896 12:34:56 die i mensis i annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2413560 01 i 1 01/01/1896 die i mensis i annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.386 {conversion of 1896-01-31} {
+ clock format -2332581904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1896 12:34:56 die xxxi mensis i annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2413590 01 i 1 01/31/1896 die xxxi mensis i annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.387 {conversion of 1896-02-01} {
+ clock format -2332495504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1896 12:34:56 die i mensis ii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2413591 02 ii 2 02/01/1896 die i mensis ii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.388 {conversion of 1896-02-29} {
+ clock format -2330076304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1896 12:34:56 die xxix mensis ii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2413619 02 ii 2 02/29/1896 die xxix mensis ii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.389 {conversion of 1896-03-01} {
+ clock format -2329989904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1896 12:34:56 die i mensis iii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 061 2413620 03 iii 3 03/01/1896 die i mensis iii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.390 {conversion of 1896-03-31} {
+ clock format -2327397904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1896 12:34:56 die xxxi mensis iii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2413650 03 iii 3 03/31/1896 die xxxi mensis iii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.391 {conversion of 1896-04-01} {
+ clock format -2327311504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1896 12:34:56 die i mensis iv annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 092 2413651 04 iv 4 04/01/1896 die i mensis iv annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.392 {conversion of 1896-04-30} {
+ clock format -2324805904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1896 12:34:56 die xxx mensis iv annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2413680 04 iv 4 04/30/1896 die xxx mensis iv annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.393 {conversion of 1896-05-01} {
+ clock format -2324719504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1896 12:34:56 die i mensis v annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 122 2413681 05 v 5 05/01/1896 die i mensis v annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.394 {conversion of 1896-05-31} {
+ clock format -2322127504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1896 12:34:56 die xxxi mensis v annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2413711 05 v 5 05/31/1896 die xxxi mensis v annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.395 {conversion of 1896-06-01} {
+ clock format -2322041104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1896 12:34:56 die i mensis vi annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 153 2413712 06 vi 6 06/01/1896 die i mensis vi annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.396 {conversion of 1896-06-30} {
+ clock format -2319535504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1896 12:34:56 die xxx mensis vi annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2413741 06 vi 6 06/30/1896 die xxx mensis vi annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.397 {conversion of 1896-07-01} {
+ clock format -2319449104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1896 12:34:56 die i mensis vii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 183 2413742 07 vii 7 07/01/1896 die i mensis vii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.398 {conversion of 1896-07-31} {
+ clock format -2316857104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1896 12:34:56 die xxxi mensis vii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2413772 07 vii 7 07/31/1896 die xxxi mensis vii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.399 {conversion of 1896-08-01} {
+ clock format -2316770704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1896 12:34:56 die i mensis viii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 214 2413773 08 viii 8 08/01/1896 die i mensis viii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.400 {conversion of 1896-08-31} {
+ clock format -2314178704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1896 12:34:56 die xxxi mensis viii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2413803 08 viii 8 08/31/1896 die xxxi mensis viii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.401 {conversion of 1896-09-01} {
+ clock format -2314092304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1896 12:34:56 die i mensis ix annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 245 2413804 09 ix 9 09/01/1896 die i mensis ix annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.402 {conversion of 1896-09-30} {
+ clock format -2311586704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1896 12:34:56 die xxx mensis ix annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2413833 09 ix 9 09/30/1896 die xxx mensis ix annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.403 {conversion of 1896-10-01} {
+ clock format -2311500304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1896 12:34:56 die i mensis x annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 275 2413834 10 x 10 10/01/1896 die i mensis x annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.404 {conversion of 1896-10-31} {
+ clock format -2308908304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1896 12:34:56 die xxxi mensis x annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2413864 10 x 10 10/31/1896 die xxxi mensis x annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.405 {conversion of 1896-11-01} {
+ clock format -2308821904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1896 12:34:56 die i mensis xi annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 306 2413865 11 xi 11 11/01/1896 die i mensis xi annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.406 {conversion of 1896-11-30} {
+ clock format -2306316304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1896 12:34:56 die xxx mensis xi annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2413894 11 xi 11 11/30/1896 die xxx mensis xi annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.407 {conversion of 1896-12-01} {
+ clock format -2306229904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1896 12:34:56 die i mensis xii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 336 2413895 12 xii 12 12/01/1896 die i mensis xii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.408 {conversion of 1896-12-31} {
+ clock format -2303637904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1896 12:34:56 die xxxi mensis xii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2413925 12 xii 12 12/31/1896 die xxxi mensis xii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.409 {conversion of 1897-01-01} {
+ clock format -2303551504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1897 12:34:56 die i mensis i annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2413926 01 i 1 01/01/1897 die i mensis i annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.410 {conversion of 1897-01-31} {
+ clock format -2300959504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1897 12:34:56 die xxxi mensis i annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2413956 01 i 1 01/31/1897 die xxxi mensis i annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.411 {conversion of 1897-02-01} {
+ clock format -2300873104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1897 12:34:56 die i mensis ii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2413957 02 ii 2 02/01/1897 die i mensis ii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.412 {conversion of 1897-02-28} {
+ clock format -2298540304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1897 12:34:56 die xxviii mensis ii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2413984 02 ii 2 02/28/1897 die xxviii mensis ii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.413 {conversion of 1897-03-01} {
+ clock format -2298453904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1897 12:34:56 die i mensis iii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2413985 03 iii 3 03/01/1897 die i mensis iii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.414 {conversion of 1897-03-31} {
+ clock format -2295861904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1897 12:34:56 die xxxi mensis iii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2414015 03 iii 3 03/31/1897 die xxxi mensis iii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.415 {conversion of 1897-04-01} {
+ clock format -2295775504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1897 12:34:56 die i mensis iv annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2414016 04 iv 4 04/01/1897 die i mensis iv annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.416 {conversion of 1897-04-30} {
+ clock format -2293269904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1897 12:34:56 die xxx mensis iv annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2414045 04 iv 4 04/30/1897 die xxx mensis iv annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.417 {conversion of 1897-05-01} {
+ clock format -2293183504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1897 12:34:56 die i mensis v annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2414046 05 v 5 05/01/1897 die i mensis v annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.418 {conversion of 1897-05-31} {
+ clock format -2290591504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1897 12:34:56 die xxxi mensis v annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2414076 05 v 5 05/31/1897 die xxxi mensis v annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.419 {conversion of 1897-06-01} {
+ clock format -2290505104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1897 12:34:56 die i mensis vi annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2414077 06 vi 6 06/01/1897 die i mensis vi annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.420 {conversion of 1897-06-30} {
+ clock format -2287999504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1897 12:34:56 die xxx mensis vi annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2414106 06 vi 6 06/30/1897 die xxx mensis vi annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.421 {conversion of 1897-07-01} {
+ clock format -2287913104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1897 12:34:56 die i mensis vii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2414107 07 vii 7 07/01/1897 die i mensis vii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.422 {conversion of 1897-07-31} {
+ clock format -2285321104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1897 12:34:56 die xxxi mensis vii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2414137 07 vii 7 07/31/1897 die xxxi mensis vii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.423 {conversion of 1897-08-01} {
+ clock format -2285234704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1897 12:34:56 die i mensis viii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2414138 08 viii 8 08/01/1897 die i mensis viii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.424 {conversion of 1897-08-31} {
+ clock format -2282642704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1897 12:34:56 die xxxi mensis viii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2414168 08 viii 8 08/31/1897 die xxxi mensis viii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.425 {conversion of 1897-09-01} {
+ clock format -2282556304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1897 12:34:56 die i mensis ix annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2414169 09 ix 9 09/01/1897 die i mensis ix annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.426 {conversion of 1897-09-30} {
+ clock format -2280050704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1897 12:34:56 die xxx mensis ix annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2414198 09 ix 9 09/30/1897 die xxx mensis ix annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.427 {conversion of 1897-10-01} {
+ clock format -2279964304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1897 12:34:56 die i mensis x annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2414199 10 x 10 10/01/1897 die i mensis x annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.428 {conversion of 1897-10-31} {
+ clock format -2277372304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1897 12:34:56 die xxxi mensis x annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2414229 10 x 10 10/31/1897 die xxxi mensis x annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.429 {conversion of 1897-11-01} {
+ clock format -2277285904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1897 12:34:56 die i mensis xi annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2414230 11 xi 11 11/01/1897 die i mensis xi annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.430 {conversion of 1897-11-30} {
+ clock format -2274780304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1897 12:34:56 die xxx mensis xi annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2414259 11 xi 11 11/30/1897 die xxx mensis xi annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.431 {conversion of 1897-12-01} {
+ clock format -2274693904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1897 12:34:56 die i mensis xii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2414260 12 xii 12 12/01/1897 die i mensis xii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.432 {conversion of 1897-12-31} {
+ clock format -2272101904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1897 12:34:56 die xxxi mensis xii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2414290 12 xii 12 12/31/1897 die xxxi mensis xii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.433 {conversion of 1898-01-01} {
+ clock format -2272015504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1898 12:34:56 die i mensis i annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2414291 01 i 1 01/01/1898 die i mensis i annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.434 {conversion of 1898-01-31} {
+ clock format -2269423504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1898 12:34:56 die xxxi mensis i annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2414321 01 i 1 01/31/1898 die xxxi mensis i annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.435 {conversion of 1898-02-01} {
+ clock format -2269337104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1898 12:34:56 die i mensis ii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2414322 02 ii 2 02/01/1898 die i mensis ii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.436 {conversion of 1898-02-28} {
+ clock format -2267004304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1898 12:34:56 die xxviii mensis ii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2414349 02 ii 2 02/28/1898 die xxviii mensis ii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.437 {conversion of 1898-03-01} {
+ clock format -2266917904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1898 12:34:56 die i mensis iii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2414350 03 iii 3 03/01/1898 die i mensis iii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.438 {conversion of 1898-03-31} {
+ clock format -2264325904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1898 12:34:56 die xxxi mensis iii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2414380 03 iii 3 03/31/1898 die xxxi mensis iii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.439 {conversion of 1898-04-01} {
+ clock format -2264239504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1898 12:34:56 die i mensis iv annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2414381 04 iv 4 04/01/1898 die i mensis iv annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.440 {conversion of 1898-04-30} {
+ clock format -2261733904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1898 12:34:56 die xxx mensis iv annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2414410 04 iv 4 04/30/1898 die xxx mensis iv annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.441 {conversion of 1898-05-01} {
+ clock format -2261647504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1898 12:34:56 die i mensis v annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2414411 05 v 5 05/01/1898 die i mensis v annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.442 {conversion of 1898-05-31} {
+ clock format -2259055504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1898 12:34:56 die xxxi mensis v annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2414441 05 v 5 05/31/1898 die xxxi mensis v annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.443 {conversion of 1898-06-01} {
+ clock format -2258969104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1898 12:34:56 die i mensis vi annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2414442 06 vi 6 06/01/1898 die i mensis vi annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.444 {conversion of 1898-06-30} {
+ clock format -2256463504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1898 12:34:56 die xxx mensis vi annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2414471 06 vi 6 06/30/1898 die xxx mensis vi annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.445 {conversion of 1898-07-01} {
+ clock format -2256377104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1898 12:34:56 die i mensis vii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2414472 07 vii 7 07/01/1898 die i mensis vii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.446 {conversion of 1898-07-31} {
+ clock format -2253785104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1898 12:34:56 die xxxi mensis vii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2414502 07 vii 7 07/31/1898 die xxxi mensis vii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.447 {conversion of 1898-08-01} {
+ clock format -2253698704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1898 12:34:56 die i mensis viii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2414503 08 viii 8 08/01/1898 die i mensis viii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.448 {conversion of 1898-08-31} {
+ clock format -2251106704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1898 12:34:56 die xxxi mensis viii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2414533 08 viii 8 08/31/1898 die xxxi mensis viii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.449 {conversion of 1898-09-01} {
+ clock format -2251020304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1898 12:34:56 die i mensis ix annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2414534 09 ix 9 09/01/1898 die i mensis ix annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.450 {conversion of 1898-09-30} {
+ clock format -2248514704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1898 12:34:56 die xxx mensis ix annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2414563 09 ix 9 09/30/1898 die xxx mensis ix annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.451 {conversion of 1898-10-01} {
+ clock format -2248428304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1898 12:34:56 die i mensis x annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2414564 10 x 10 10/01/1898 die i mensis x annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.452 {conversion of 1898-10-31} {
+ clock format -2245836304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1898 12:34:56 die xxxi mensis x annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2414594 10 x 10 10/31/1898 die xxxi mensis x annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.453 {conversion of 1898-11-01} {
+ clock format -2245749904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1898 12:34:56 die i mensis xi annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2414595 11 xi 11 11/01/1898 die i mensis xi annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.454 {conversion of 1898-11-30} {
+ clock format -2243244304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1898 12:34:56 die xxx mensis xi annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2414624 11 xi 11 11/30/1898 die xxx mensis xi annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.455 {conversion of 1898-12-01} {
+ clock format -2243157904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1898 12:34:56 die i mensis xii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2414625 12 xii 12 12/01/1898 die i mensis xii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.456 {conversion of 1898-12-31} {
+ clock format -2240565904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1898 12:34:56 die xxxi mensis xii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2414655 12 xii 12 12/31/1898 die xxxi mensis xii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.457 {conversion of 1899-01-01} {
+ clock format -2240479504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1899 12:34:56 die i mensis i annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jan 001 2414656 01 i 1 01/01/1899 die i mensis i annoque mdcccxcix 99 xcix 1899}
+test clock-2.458 {conversion of 1899-01-31} {
+ clock format -2237887504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1899 12:34:56 die xxxi mensis i annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2414686 01 i 1 01/31/1899 die xxxi mensis i annoque mdcccxcix 99 xcix 1899}
+test clock-2.459 {conversion of 1899-02-01} {
+ clock format -2237801104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1899 12:34:56 die i mensis ii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Feb 032 2414687 02 ii 2 02/01/1899 die i mensis ii annoque mdcccxcix 99 xcix 1899}
+test clock-2.460 {conversion of 1899-02-28} {
+ clock format -2235468304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1899 12:34:56 die xxviii mensis ii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2414714 02 ii 2 02/28/1899 die xxviii mensis ii annoque mdcccxcix 99 xcix 1899}
+test clock-2.461 {conversion of 1899-03-01} {
+ clock format -2235381904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1899 12:34:56 die i mensis iii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Mar 060 2414715 03 iii 3 03/01/1899 die i mensis iii annoque mdcccxcix 99 xcix 1899}
+test clock-2.462 {conversion of 1899-03-31} {
+ clock format -2232789904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1899 12:34:56 die xxxi mensis iii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2414745 03 iii 3 03/31/1899 die xxxi mensis iii annoque mdcccxcix 99 xcix 1899}
+test clock-2.463 {conversion of 1899-04-01} {
+ clock format -2232703504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1899 12:34:56 die i mensis iv annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Apr 091 2414746 04 iv 4 04/01/1899 die i mensis iv annoque mdcccxcix 99 xcix 1899}
+test clock-2.464 {conversion of 1899-04-30} {
+ clock format -2230197904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1899 12:34:56 die xxx mensis iv annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2414775 04 iv 4 04/30/1899 die xxx mensis iv annoque mdcccxcix 99 xcix 1899}
+test clock-2.465 {conversion of 1899-05-01} {
+ clock format -2230111504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1899 12:34:56 die i mensis v annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i May 121 2414776 05 v 5 05/01/1899 die i mensis v annoque mdcccxcix 99 xcix 1899}
+test clock-2.466 {conversion of 1899-05-31} {
+ clock format -2227519504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1899 12:34:56 die xxxi mensis v annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2414806 05 v 5 05/31/1899 die xxxi mensis v annoque mdcccxcix 99 xcix 1899}
+test clock-2.467 {conversion of 1899-06-01} {
+ clock format -2227433104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1899 12:34:56 die i mensis vi annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jun 152 2414807 06 vi 6 06/01/1899 die i mensis vi annoque mdcccxcix 99 xcix 1899}
+test clock-2.468 {conversion of 1899-06-30} {
+ clock format -2224927504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1899 12:34:56 die xxx mensis vi annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2414836 06 vi 6 06/30/1899 die xxx mensis vi annoque mdcccxcix 99 xcix 1899}
+test clock-2.469 {conversion of 1899-07-01} {
+ clock format -2224841104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1899 12:34:56 die i mensis vii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Jul 182 2414837 07 vii 7 07/01/1899 die i mensis vii annoque mdcccxcix 99 xcix 1899}
+test clock-2.470 {conversion of 1899-07-31} {
+ clock format -2222249104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1899 12:34:56 die xxxi mensis vii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2414867 07 vii 7 07/31/1899 die xxxi mensis vii annoque mdcccxcix 99 xcix 1899}
+test clock-2.471 {conversion of 1899-08-01} {
+ clock format -2222162704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1899 12:34:56 die i mensis viii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Aug 213 2414868 08 viii 8 08/01/1899 die i mensis viii annoque mdcccxcix 99 xcix 1899}
+test clock-2.472 {conversion of 1899-08-31} {
+ clock format -2219570704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1899 12:34:56 die xxxi mensis viii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2414898 08 viii 8 08/31/1899 die xxxi mensis viii annoque mdcccxcix 99 xcix 1899}
+test clock-2.473 {conversion of 1899-09-01} {
+ clock format -2219484304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1899 12:34:56 die i mensis ix annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Sep 244 2414899 09 ix 9 09/01/1899 die i mensis ix annoque mdcccxcix 99 xcix 1899}
+test clock-2.474 {conversion of 1899-09-30} {
+ clock format -2216978704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1899 12:34:56 die xxx mensis ix annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2414928 09 ix 9 09/30/1899 die xxx mensis ix annoque mdcccxcix 99 xcix 1899}
+test clock-2.475 {conversion of 1899-10-01} {
+ clock format -2216892304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1899 12:34:56 die i mensis x annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Oct 274 2414929 10 x 10 10/01/1899 die i mensis x annoque mdcccxcix 99 xcix 1899}
+test clock-2.476 {conversion of 1899-10-31} {
+ clock format -2214300304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1899 12:34:56 die xxxi mensis x annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2414959 10 x 10 10/31/1899 die xxxi mensis x annoque mdcccxcix 99 xcix 1899}
+test clock-2.477 {conversion of 1899-11-01} {
+ clock format -2214213904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1899 12:34:56 die i mensis xi annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Nov 305 2414960 11 xi 11 11/01/1899 die i mensis xi annoque mdcccxcix 99 xcix 1899}
+test clock-2.478 {conversion of 1899-11-30} {
+ clock format -2211708304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1899 12:34:56 die xxx mensis xi annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2414989 11 xi 11 11/30/1899 die xxx mensis xi annoque mdcccxcix 99 xcix 1899}
+test clock-2.479 {conversion of 1899-12-01} {
+ clock format -2211621904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1899 12:34:56 die i mensis xii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i 1 i Dec 335 2414990 12 xii 12 12/01/1899 die i mensis xii annoque mdcccxcix 99 xcix 1899}
+test clock-2.480 {conversion of 1899-12-31} {
+ clock format -2209029904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1899 12:34:56 die xxxi mensis xii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2415020 12 xii 12 12/31/1899 die xxxi mensis xii annoque mdcccxcix 99 xcix 1899}
+test clock-2.481 {conversion of 1900-01-01} {
+ clock format -2208943504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1900 12:34:56 die i mensis i annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2415021 01 i 1 01/01/1900 die i mensis i annoque mcm? 00 ? 1900}
+test clock-2.482 {conversion of 1900-01-31} {
+ clock format -2206351504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1900 12:34:56 die xxxi mensis i annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2415051 01 i 1 01/31/1900 die xxxi mensis i annoque mcm? 00 ? 1900}
+test clock-2.483 {conversion of 1900-02-01} {
+ clock format -2206265104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1900 12:34:56 die i mensis ii annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2415052 02 ii 2 02/01/1900 die i mensis ii annoque mcm? 00 ? 1900}
+test clock-2.484 {conversion of 1900-02-28} {
+ clock format -2203932304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1900 12:34:56 die xxviii mensis ii annoque mcm? xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2415079 02 ii 2 02/28/1900 die xxviii mensis ii annoque mcm? 00 ? 1900}
+test clock-2.485 {conversion of 1900-03-01} {
+ clock format -2203845904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1900 12:34:56 die i mensis iii annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2415080 03 iii 3 03/01/1900 die i mensis iii annoque mcm? 00 ? 1900}
+test clock-2.486 {conversion of 1900-03-31} {
+ clock format -2201253904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1900 12:34:56 die xxxi mensis iii annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2415110 03 iii 3 03/31/1900 die xxxi mensis iii annoque mcm? 00 ? 1900}
+test clock-2.487 {conversion of 1900-04-01} {
+ clock format -2201167504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1900 12:34:56 die i mensis iv annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2415111 04 iv 4 04/01/1900 die i mensis iv annoque mcm? 00 ? 1900}
+test clock-2.488 {conversion of 1900-04-30} {
+ clock format -2198661904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1900 12:34:56 die xxx mensis iv annoque mcm? xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2415140 04 iv 4 04/30/1900 die xxx mensis iv annoque mcm? 00 ? 1900}
+test clock-2.489 {conversion of 1900-05-01} {
+ clock format -2198575504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1900 12:34:56 die i mensis v annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2415141 05 v 5 05/01/1900 die i mensis v annoque mcm? 00 ? 1900}
+test clock-2.490 {conversion of 1900-05-31} {
+ clock format -2195983504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1900 12:34:56 die xxxi mensis v annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2415171 05 v 5 05/31/1900 die xxxi mensis v annoque mcm? 00 ? 1900}
+test clock-2.491 {conversion of 1900-06-01} {
+ clock format -2195897104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1900 12:34:56 die i mensis vi annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2415172 06 vi 6 06/01/1900 die i mensis vi annoque mcm? 00 ? 1900}
+test clock-2.492 {conversion of 1900-06-30} {
+ clock format -2193391504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1900 12:34:56 die xxx mensis vi annoque mcm? xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2415201 06 vi 6 06/30/1900 die xxx mensis vi annoque mcm? 00 ? 1900}
+test clock-2.493 {conversion of 1900-07-01} {
+ clock format -2193305104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1900 12:34:56 die i mensis vii annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2415202 07 vii 7 07/01/1900 die i mensis vii annoque mcm? 00 ? 1900}
+test clock-2.494 {conversion of 1900-07-31} {
+ clock format -2190713104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1900 12:34:56 die xxxi mensis vii annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2415232 07 vii 7 07/31/1900 die xxxi mensis vii annoque mcm? 00 ? 1900}
+test clock-2.495 {conversion of 1900-08-01} {
+ clock format -2190626704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1900 12:34:56 die i mensis viii annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2415233 08 viii 8 08/01/1900 die i mensis viii annoque mcm? 00 ? 1900}
+test clock-2.496 {conversion of 1900-08-31} {
+ clock format -2188034704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1900 12:34:56 die xxxi mensis viii annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2415263 08 viii 8 08/31/1900 die xxxi mensis viii annoque mcm? 00 ? 1900}
+test clock-2.497 {conversion of 1900-09-01} {
+ clock format -2187948304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1900 12:34:56 die i mensis ix annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2415264 09 ix 9 09/01/1900 die i mensis ix annoque mcm? 00 ? 1900}
+test clock-2.498 {conversion of 1900-09-30} {
+ clock format -2185442704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1900 12:34:56 die xxx mensis ix annoque mcm? xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2415293 09 ix 9 09/30/1900 die xxx mensis ix annoque mcm? 00 ? 1900}
+test clock-2.499 {conversion of 1900-10-01} {
+ clock format -2185356304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1900 12:34:56 die i mensis x annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2415294 10 x 10 10/01/1900 die i mensis x annoque mcm? 00 ? 1900}
+test clock-2.500 {conversion of 1900-10-31} {
+ clock format -2182764304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1900 12:34:56 die xxxi mensis x annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2415324 10 x 10 10/31/1900 die xxxi mensis x annoque mcm? 00 ? 1900}
+test clock-2.501 {conversion of 1900-11-01} {
+ clock format -2182677904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1900 12:34:56 die i mensis xi annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2415325 11 xi 11 11/01/1900 die i mensis xi annoque mcm? 00 ? 1900}
+test clock-2.502 {conversion of 1900-11-30} {
+ clock format -2180172304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1900 12:34:56 die xxx mensis xi annoque mcm? xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2415354 11 xi 11 11/30/1900 die xxx mensis xi annoque mcm? 00 ? 1900}
+test clock-2.503 {conversion of 1900-12-01} {
+ clock format -2180085904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1900 12:34:56 die i mensis xii annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2415355 12 xii 12 12/01/1900 die i mensis xii annoque mcm? 00 ? 1900}
+test clock-2.504 {conversion of 1900-12-31} {
+ clock format -2177493904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1900 12:34:56 die xxxi mensis xii annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2415385 12 xii 12 12/31/1900 die xxxi mensis xii annoque mcm? 00 ? 1900}
+test clock-2.505 {conversion of 1944-01-01} {
+ clock format -820495504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1944 12:34:56 die i mensis i annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2431091 01 i 1 01/01/1944 die i mensis i annoque mcmxliv 44 xliv 1944}
+test clock-2.506 {conversion of 1944-01-31} {
+ clock format -817903504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1944 12:34:56 die xxxi mensis i annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2431121 01 i 1 01/31/1944 die xxxi mensis i annoque mcmxliv 44 xliv 1944}
+test clock-2.507 {conversion of 1944-02-01} {
+ clock format -817817104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1944 12:34:56 die i mensis ii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2431122 02 ii 2 02/01/1944 die i mensis ii annoque mcmxliv 44 xliv 1944}
+test clock-2.508 {conversion of 1944-02-29} {
+ clock format -815397904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1944 12:34:56 die xxix mensis ii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2431150 02 ii 2 02/29/1944 die xxix mensis ii annoque mcmxliv 44 xliv 1944}
+test clock-2.509 {conversion of 1944-03-01} {
+ clock format -815311504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1944 12:34:56 die i mensis iii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2431151 03 iii 3 03/01/1944 die i mensis iii annoque mcmxliv 44 xliv 1944}
+test clock-2.510 {conversion of 1944-03-31} {
+ clock format -812719504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1944 12:34:56 die xxxi mensis iii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2431181 03 iii 3 03/31/1944 die xxxi mensis iii annoque mcmxliv 44 xliv 1944}
+test clock-2.511 {conversion of 1944-04-01} {
+ clock format -812633104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1944 12:34:56 die i mensis iv annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2431182 04 iv 4 04/01/1944 die i mensis iv annoque mcmxliv 44 xliv 1944}
+test clock-2.512 {conversion of 1944-04-30} {
+ clock format -810127504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1944 12:34:56 die xxx mensis iv annoque mcmxliv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2431211 04 iv 4 04/30/1944 die xxx mensis iv annoque mcmxliv 44 xliv 1944}
+test clock-2.513 {conversion of 1944-05-01} {
+ clock format -810041104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1944 12:34:56 die i mensis v annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2431212 05 v 5 05/01/1944 die i mensis v annoque mcmxliv 44 xliv 1944}
+test clock-2.514 {conversion of 1944-05-31} {
+ clock format -807449104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1944 12:34:56 die xxxi mensis v annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2431242 05 v 5 05/31/1944 die xxxi mensis v annoque mcmxliv 44 xliv 1944}
+test clock-2.515 {conversion of 1944-06-01} {
+ clock format -807362704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1944 12:34:56 die i mensis vi annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2431243 06 vi 6 06/01/1944 die i mensis vi annoque mcmxliv 44 xliv 1944}
+test clock-2.516 {conversion of 1944-06-30} {
+ clock format -804857104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1944 12:34:56 die xxx mensis vi annoque mcmxliv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2431272 06 vi 6 06/30/1944 die xxx mensis vi annoque mcmxliv 44 xliv 1944}
+test clock-2.517 {conversion of 1944-07-01} {
+ clock format -804770704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1944 12:34:56 die i mensis vii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2431273 07 vii 7 07/01/1944 die i mensis vii annoque mcmxliv 44 xliv 1944}
+test clock-2.518 {conversion of 1944-07-31} {
+ clock format -802178704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1944 12:34:56 die xxxi mensis vii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2431303 07 vii 7 07/31/1944 die xxxi mensis vii annoque mcmxliv 44 xliv 1944}
+test clock-2.519 {conversion of 1944-08-01} {
+ clock format -802092304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1944 12:34:56 die i mensis viii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2431304 08 viii 8 08/01/1944 die i mensis viii annoque mcmxliv 44 xliv 1944}
+test clock-2.520 {conversion of 1944-08-31} {
+ clock format -799500304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1944 12:34:56 die xxxi mensis viii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2431334 08 viii 8 08/31/1944 die xxxi mensis viii annoque mcmxliv 44 xliv 1944}
+test clock-2.521 {conversion of 1944-09-01} {
+ clock format -799413904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1944 12:34:56 die i mensis ix annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2431335 09 ix 9 09/01/1944 die i mensis ix annoque mcmxliv 44 xliv 1944}
+test clock-2.522 {conversion of 1944-09-30} {
+ clock format -796908304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1944 12:34:56 die xxx mensis ix annoque mcmxliv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2431364 09 ix 9 09/30/1944 die xxx mensis ix annoque mcmxliv 44 xliv 1944}
+test clock-2.523 {conversion of 1944-10-01} {
+ clock format -796821904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1944 12:34:56 die i mensis x annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2431365 10 x 10 10/01/1944 die i mensis x annoque mcmxliv 44 xliv 1944}
+test clock-2.524 {conversion of 1944-10-31} {
+ clock format -794229904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1944 12:34:56 die xxxi mensis x annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2431395 10 x 10 10/31/1944 die xxxi mensis x annoque mcmxliv 44 xliv 1944}
+test clock-2.525 {conversion of 1944-11-01} {
+ clock format -794143504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1944 12:34:56 die i mensis xi annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2431396 11 xi 11 11/01/1944 die i mensis xi annoque mcmxliv 44 xliv 1944}
+test clock-2.526 {conversion of 1944-11-30} {
+ clock format -791637904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1944 12:34:56 die xxx mensis xi annoque mcmxliv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2431425 11 xi 11 11/30/1944 die xxx mensis xi annoque mcmxliv 44 xliv 1944}
+test clock-2.527 {conversion of 1944-12-01} {
+ clock format -791551504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1944 12:34:56 die i mensis xii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2431426 12 xii 12 12/01/1944 die i mensis xii annoque mcmxliv 44 xliv 1944}
+test clock-2.528 {conversion of 1944-12-31} {
+ clock format -788959504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1944 12:34:56 die xxxi mensis xii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2431456 12 xii 12 12/31/1944 die xxxi mensis xii annoque mcmxliv 44 xliv 1944}
+test clock-2.529 {conversion of 1945-01-01} {
+ clock format -788873104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1945 12:34:56 die i mensis i annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2431457 01 i 1 01/01/1945 die i mensis i annoque mcmxlv 45 xlv 1945}
+test clock-2.530 {conversion of 1945-01-31} {
+ clock format -786281104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1945 12:34:56 die xxxi mensis i annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2431487 01 i 1 01/31/1945 die xxxi mensis i annoque mcmxlv 45 xlv 1945}
+test clock-2.531 {conversion of 1945-02-01} {
+ clock format -786194704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1945 12:34:56 die i mensis ii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2431488 02 ii 2 02/01/1945 die i mensis ii annoque mcmxlv 45 xlv 1945}
+test clock-2.532 {conversion of 1945-02-28} {
+ clock format -783861904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1945 12:34:56 die xxviii mensis ii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2431515 02 ii 2 02/28/1945 die xxviii mensis ii annoque mcmxlv 45 xlv 1945}
+test clock-2.533 {conversion of 1945-03-01} {
+ clock format -783775504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1945 12:34:56 die i mensis iii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2431516 03 iii 3 03/01/1945 die i mensis iii annoque mcmxlv 45 xlv 1945}
+test clock-2.534 {conversion of 1945-03-31} {
+ clock format -781183504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1945 12:34:56 die xxxi mensis iii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2431546 03 iii 3 03/31/1945 die xxxi mensis iii annoque mcmxlv 45 xlv 1945}
+test clock-2.535 {conversion of 1945-04-01} {
+ clock format -781097104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1945 12:34:56 die i mensis iv annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2431547 04 iv 4 04/01/1945 die i mensis iv annoque mcmxlv 45 xlv 1945}
+test clock-2.536 {conversion of 1945-04-30} {
+ clock format -778591504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1945 12:34:56 die xxx mensis iv annoque mcmxlv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2431576 04 iv 4 04/30/1945 die xxx mensis iv annoque mcmxlv 45 xlv 1945}
+test clock-2.537 {conversion of 1945-05-01} {
+ clock format -778505104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1945 12:34:56 die i mensis v annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2431577 05 v 5 05/01/1945 die i mensis v annoque mcmxlv 45 xlv 1945}
+test clock-2.538 {conversion of 1945-05-31} {
+ clock format -775913104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1945 12:34:56 die xxxi mensis v annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2431607 05 v 5 05/31/1945 die xxxi mensis v annoque mcmxlv 45 xlv 1945}
+test clock-2.539 {conversion of 1945-06-01} {
+ clock format -775826704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1945 12:34:56 die i mensis vi annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2431608 06 vi 6 06/01/1945 die i mensis vi annoque mcmxlv 45 xlv 1945}
+test clock-2.540 {conversion of 1945-06-30} {
+ clock format -773321104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1945 12:34:56 die xxx mensis vi annoque mcmxlv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2431637 06 vi 6 06/30/1945 die xxx mensis vi annoque mcmxlv 45 xlv 1945}
+test clock-2.541 {conversion of 1945-07-01} {
+ clock format -773234704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1945 12:34:56 die i mensis vii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2431638 07 vii 7 07/01/1945 die i mensis vii annoque mcmxlv 45 xlv 1945}
+test clock-2.542 {conversion of 1945-07-31} {
+ clock format -770642704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1945 12:34:56 die xxxi mensis vii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2431668 07 vii 7 07/31/1945 die xxxi mensis vii annoque mcmxlv 45 xlv 1945}
+test clock-2.543 {conversion of 1945-08-01} {
+ clock format -770556304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1945 12:34:56 die i mensis viii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2431669 08 viii 8 08/01/1945 die i mensis viii annoque mcmxlv 45 xlv 1945}
+test clock-2.544 {conversion of 1945-08-31} {
+ clock format -767964304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1945 12:34:56 die xxxi mensis viii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2431699 08 viii 8 08/31/1945 die xxxi mensis viii annoque mcmxlv 45 xlv 1945}
+test clock-2.545 {conversion of 1945-09-01} {
+ clock format -767877904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1945 12:34:56 die i mensis ix annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2431700 09 ix 9 09/01/1945 die i mensis ix annoque mcmxlv 45 xlv 1945}
+test clock-2.546 {conversion of 1945-09-30} {
+ clock format -765372304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1945 12:34:56 die xxx mensis ix annoque mcmxlv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2431729 09 ix 9 09/30/1945 die xxx mensis ix annoque mcmxlv 45 xlv 1945}
+test clock-2.547 {conversion of 1945-10-01} {
+ clock format -765285904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1945 12:34:56 die i mensis x annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2431730 10 x 10 10/01/1945 die i mensis x annoque mcmxlv 45 xlv 1945}
+test clock-2.548 {conversion of 1945-10-31} {
+ clock format -762693904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1945 12:34:56 die xxxi mensis x annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2431760 10 x 10 10/31/1945 die xxxi mensis x annoque mcmxlv 45 xlv 1945}
+test clock-2.549 {conversion of 1945-11-01} {
+ clock format -762607504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1945 12:34:56 die i mensis xi annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2431761 11 xi 11 11/01/1945 die i mensis xi annoque mcmxlv 45 xlv 1945}
+test clock-2.550 {conversion of 1945-11-30} {
+ clock format -760101904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1945 12:34:56 die xxx mensis xi annoque mcmxlv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2431790 11 xi 11 11/30/1945 die xxx mensis xi annoque mcmxlv 45 xlv 1945}
+test clock-2.551 {conversion of 1945-12-01} {
+ clock format -760015504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1945 12:34:56 die i mensis xii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2431791 12 xii 12 12/01/1945 die i mensis xii annoque mcmxlv 45 xlv 1945}
+test clock-2.552 {conversion of 1945-12-31} {
+ clock format -757423504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1945 12:34:56 die xxxi mensis xii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2431821 12 xii 12 12/31/1945 die xxxi mensis xii annoque mcmxlv 45 xlv 1945}
+test clock-2.553 {conversion of 1948-01-01} {
+ clock format -694265104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1948 12:34:56 die i mensis i annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2432552 01 i 1 01/01/1948 die i mensis i annoque mcmxlviii 48 xlviii 1948}
+test clock-2.554 {conversion of 1948-01-31} {
+ clock format -691673104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1948 12:34:56 die xxxi mensis i annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2432582 01 i 1 01/31/1948 die xxxi mensis i annoque mcmxlviii 48 xlviii 1948}
+test clock-2.555 {conversion of 1948-02-01} {
+ clock format -691586704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1948 12:34:56 die i mensis ii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2432583 02 ii 2 02/01/1948 die i mensis ii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.556 {conversion of 1948-02-29} {
+ clock format -689167504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1948 12:34:56 die xxix mensis ii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2432611 02 ii 2 02/29/1948 die xxix mensis ii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.557 {conversion of 1948-03-01} {
+ clock format -689081104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1948 12:34:56 die i mensis iii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2432612 03 iii 3 03/01/1948 die i mensis iii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.558 {conversion of 1948-03-31} {
+ clock format -686489104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1948 12:34:56 die xxxi mensis iii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2432642 03 iii 3 03/31/1948 die xxxi mensis iii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.559 {conversion of 1948-04-01} {
+ clock format -686402704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1948 12:34:56 die i mensis iv annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2432643 04 iv 4 04/01/1948 die i mensis iv annoque mcmxlviii 48 xlviii 1948}
+test clock-2.560 {conversion of 1948-04-30} {
+ clock format -683897104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1948 12:34:56 die xxx mensis iv annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2432672 04 iv 4 04/30/1948 die xxx mensis iv annoque mcmxlviii 48 xlviii 1948}
+test clock-2.561 {conversion of 1948-05-01} {
+ clock format -683810704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1948 12:34:56 die i mensis v annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2432673 05 v 5 05/01/1948 die i mensis v annoque mcmxlviii 48 xlviii 1948}
+test clock-2.562 {conversion of 1948-05-31} {
+ clock format -681218704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1948 12:34:56 die xxxi mensis v annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2432703 05 v 5 05/31/1948 die xxxi mensis v annoque mcmxlviii 48 xlviii 1948}
+test clock-2.563 {conversion of 1948-06-01} {
+ clock format -681132304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1948 12:34:56 die i mensis vi annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2432704 06 vi 6 06/01/1948 die i mensis vi annoque mcmxlviii 48 xlviii 1948}
+test clock-2.564 {conversion of 1948-06-30} {
+ clock format -678626704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1948 12:34:56 die xxx mensis vi annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2432733 06 vi 6 06/30/1948 die xxx mensis vi annoque mcmxlviii 48 xlviii 1948}
+test clock-2.565 {conversion of 1948-07-01} {
+ clock format -678540304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1948 12:34:56 die i mensis vii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2432734 07 vii 7 07/01/1948 die i mensis vii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.566 {conversion of 1948-07-31} {
+ clock format -675948304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1948 12:34:56 die xxxi mensis vii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2432764 07 vii 7 07/31/1948 die xxxi mensis vii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.567 {conversion of 1948-08-01} {
+ clock format -675861904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1948 12:34:56 die i mensis viii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2432765 08 viii 8 08/01/1948 die i mensis viii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.568 {conversion of 1948-08-31} {
+ clock format -673269904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1948 12:34:56 die xxxi mensis viii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2432795 08 viii 8 08/31/1948 die xxxi mensis viii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.569 {conversion of 1948-09-01} {
+ clock format -673183504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1948 12:34:56 die i mensis ix annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2432796 09 ix 9 09/01/1948 die i mensis ix annoque mcmxlviii 48 xlviii 1948}
+test clock-2.570 {conversion of 1948-09-30} {
+ clock format -670677904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1948 12:34:56 die xxx mensis ix annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2432825 09 ix 9 09/30/1948 die xxx mensis ix annoque mcmxlviii 48 xlviii 1948}
+test clock-2.571 {conversion of 1948-10-01} {
+ clock format -670591504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1948 12:34:56 die i mensis x annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2432826 10 x 10 10/01/1948 die i mensis x annoque mcmxlviii 48 xlviii 1948}
+test clock-2.572 {conversion of 1948-10-31} {
+ clock format -667999504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1948 12:34:56 die xxxi mensis x annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2432856 10 x 10 10/31/1948 die xxxi mensis x annoque mcmxlviii 48 xlviii 1948}
+test clock-2.573 {conversion of 1948-11-01} {
+ clock format -667913104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1948 12:34:56 die i mensis xi annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2432857 11 xi 11 11/01/1948 die i mensis xi annoque mcmxlviii 48 xlviii 1948}
+test clock-2.574 {conversion of 1948-11-30} {
+ clock format -665407504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1948 12:34:56 die xxx mensis xi annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2432886 11 xi 11 11/30/1948 die xxx mensis xi annoque mcmxlviii 48 xlviii 1948}
+test clock-2.575 {conversion of 1948-12-01} {
+ clock format -665321104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1948 12:34:56 die i mensis xii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2432887 12 xii 12 12/01/1948 die i mensis xii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.576 {conversion of 1948-12-31} {
+ clock format -662729104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1948 12:34:56 die xxxi mensis xii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2432917 12 xii 12 12/31/1948 die xxxi mensis xii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.577 {conversion of 1949-01-01} {
+ clock format -662642704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1949 12:34:56 die i mensis i annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2432918 01 i 1 01/01/1949 die i mensis i annoque mcmxlix 49 xlix 1949}
+test clock-2.578 {conversion of 1949-01-31} {
+ clock format -660050704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1949 12:34:56 die xxxi mensis i annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2432948 01 i 1 01/31/1949 die xxxi mensis i annoque mcmxlix 49 xlix 1949}
+test clock-2.579 {conversion of 1949-02-01} {
+ clock format -659964304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1949 12:34:56 die i mensis ii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2432949 02 ii 2 02/01/1949 die i mensis ii annoque mcmxlix 49 xlix 1949}
+test clock-2.580 {conversion of 1949-02-28} {
+ clock format -657631504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1949 12:34:56 die xxviii mensis ii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2432976 02 ii 2 02/28/1949 die xxviii mensis ii annoque mcmxlix 49 xlix 1949}
+test clock-2.581 {conversion of 1949-03-01} {
+ clock format -657545104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1949 12:34:56 die i mensis iii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2432977 03 iii 3 03/01/1949 die i mensis iii annoque mcmxlix 49 xlix 1949}
+test clock-2.582 {conversion of 1949-03-31} {
+ clock format -654953104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1949 12:34:56 die xxxi mensis iii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2433007 03 iii 3 03/31/1949 die xxxi mensis iii annoque mcmxlix 49 xlix 1949}
+test clock-2.583 {conversion of 1949-04-01} {
+ clock format -654866704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1949 12:34:56 die i mensis iv annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2433008 04 iv 4 04/01/1949 die i mensis iv annoque mcmxlix 49 xlix 1949}
+test clock-2.584 {conversion of 1949-04-30} {
+ clock format -652361104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1949 12:34:56 die xxx mensis iv annoque mcmxlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2433037 04 iv 4 04/30/1949 die xxx mensis iv annoque mcmxlix 49 xlix 1949}
+test clock-2.585 {conversion of 1949-05-01} {
+ clock format -652274704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1949 12:34:56 die i mensis v annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2433038 05 v 5 05/01/1949 die i mensis v annoque mcmxlix 49 xlix 1949}
+test clock-2.586 {conversion of 1949-05-31} {
+ clock format -649682704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1949 12:34:56 die xxxi mensis v annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2433068 05 v 5 05/31/1949 die xxxi mensis v annoque mcmxlix 49 xlix 1949}
+test clock-2.587 {conversion of 1949-06-01} {
+ clock format -649596304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1949 12:34:56 die i mensis vi annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2433069 06 vi 6 06/01/1949 die i mensis vi annoque mcmxlix 49 xlix 1949}
+test clock-2.588 {conversion of 1949-06-30} {
+ clock format -647090704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1949 12:34:56 die xxx mensis vi annoque mcmxlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2433098 06 vi 6 06/30/1949 die xxx mensis vi annoque mcmxlix 49 xlix 1949}
+test clock-2.589 {conversion of 1949-07-01} {
+ clock format -647004304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1949 12:34:56 die i mensis vii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2433099 07 vii 7 07/01/1949 die i mensis vii annoque mcmxlix 49 xlix 1949}
+test clock-2.590 {conversion of 1949-07-31} {
+ clock format -644412304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1949 12:34:56 die xxxi mensis vii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2433129 07 vii 7 07/31/1949 die xxxi mensis vii annoque mcmxlix 49 xlix 1949}
+test clock-2.591 {conversion of 1949-08-01} {
+ clock format -644325904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1949 12:34:56 die i mensis viii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2433130 08 viii 8 08/01/1949 die i mensis viii annoque mcmxlix 49 xlix 1949}
+test clock-2.592 {conversion of 1949-08-31} {
+ clock format -641733904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1949 12:34:56 die xxxi mensis viii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2433160 08 viii 8 08/31/1949 die xxxi mensis viii annoque mcmxlix 49 xlix 1949}
+test clock-2.593 {conversion of 1949-09-01} {
+ clock format -641647504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1949 12:34:56 die i mensis ix annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2433161 09 ix 9 09/01/1949 die i mensis ix annoque mcmxlix 49 xlix 1949}
+test clock-2.594 {conversion of 1949-09-30} {
+ clock format -639141904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1949 12:34:56 die xxx mensis ix annoque mcmxlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2433190 09 ix 9 09/30/1949 die xxx mensis ix annoque mcmxlix 49 xlix 1949}
+test clock-2.595 {conversion of 1949-10-01} {
+ clock format -639055504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1949 12:34:56 die i mensis x annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2433191 10 x 10 10/01/1949 die i mensis x annoque mcmxlix 49 xlix 1949}
+test clock-2.596 {conversion of 1949-10-31} {
+ clock format -636463504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1949 12:34:56 die xxxi mensis x annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2433221 10 x 10 10/31/1949 die xxxi mensis x annoque mcmxlix 49 xlix 1949}
+test clock-2.597 {conversion of 1949-11-01} {
+ clock format -636377104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1949 12:34:56 die i mensis xi annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2433222 11 xi 11 11/01/1949 die i mensis xi annoque mcmxlix 49 xlix 1949}
+test clock-2.598 {conversion of 1949-11-30} {
+ clock format -633871504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1949 12:34:56 die xxx mensis xi annoque mcmxlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2433251 11 xi 11 11/30/1949 die xxx mensis xi annoque mcmxlix 49 xlix 1949}
+test clock-2.599 {conversion of 1949-12-01} {
+ clock format -633785104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1949 12:34:56 die i mensis xii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2433252 12 xii 12 12/01/1949 die i mensis xii annoque mcmxlix 49 xlix 1949}
+test clock-2.600 {conversion of 1949-12-31} {
+ clock format -631193104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1949 12:34:56 die xxxi mensis xii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2433282 12 xii 12 12/31/1949 die xxxi mensis xii annoque mcmxlix 49 xlix 1949}
+test clock-2.601 {conversion of 1952-01-01} {
+ clock format -568034704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1952 12:34:56 die i mensis i annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2434013 01 i 1 01/01/1952 die i mensis i annoque mcmlii 52 lii 1952}
+test clock-2.602 {conversion of 1952-01-31} {
+ clock format -565442704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1952 12:34:56 die xxxi mensis i annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2434043 01 i 1 01/31/1952 die xxxi mensis i annoque mcmlii 52 lii 1952}
+test clock-2.603 {conversion of 1952-02-01} {
+ clock format -565356304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1952 12:34:56 die i mensis ii annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2434044 02 ii 2 02/01/1952 die i mensis ii annoque mcmlii 52 lii 1952}
+test clock-2.604 {conversion of 1952-02-29} {
+ clock format -562937104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1952 12:34:56 die xxix mensis ii annoque mcmlii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2434072 02 ii 2 02/29/1952 die xxix mensis ii annoque mcmlii 52 lii 1952}
+test clock-2.605 {conversion of 1952-03-01} {
+ clock format -562850704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1952 12:34:56 die i mensis iii annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2434073 03 iii 3 03/01/1952 die i mensis iii annoque mcmlii 52 lii 1952}
+test clock-2.606 {conversion of 1952-03-31} {
+ clock format -560258704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1952 12:34:56 die xxxi mensis iii annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2434103 03 iii 3 03/31/1952 die xxxi mensis iii annoque mcmlii 52 lii 1952}
+test clock-2.607 {conversion of 1952-04-01} {
+ clock format -560172304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1952 12:34:56 die i mensis iv annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2434104 04 iv 4 04/01/1952 die i mensis iv annoque mcmlii 52 lii 1952}
+test clock-2.608 {conversion of 1952-04-30} {
+ clock format -557666704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1952 12:34:56 die xxx mensis iv annoque mcmlii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2434133 04 iv 4 04/30/1952 die xxx mensis iv annoque mcmlii 52 lii 1952}
+test clock-2.609 {conversion of 1952-05-01} {
+ clock format -557580304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1952 12:34:56 die i mensis v annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2434134 05 v 5 05/01/1952 die i mensis v annoque mcmlii 52 lii 1952}
+test clock-2.610 {conversion of 1952-05-31} {
+ clock format -554988304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1952 12:34:56 die xxxi mensis v annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2434164 05 v 5 05/31/1952 die xxxi mensis v annoque mcmlii 52 lii 1952}
+test clock-2.611 {conversion of 1952-06-01} {
+ clock format -554901904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1952 12:34:56 die i mensis vi annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2434165 06 vi 6 06/01/1952 die i mensis vi annoque mcmlii 52 lii 1952}
+test clock-2.612 {conversion of 1952-06-30} {
+ clock format -552396304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1952 12:34:56 die xxx mensis vi annoque mcmlii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2434194 06 vi 6 06/30/1952 die xxx mensis vi annoque mcmlii 52 lii 1952}
+test clock-2.613 {conversion of 1952-07-01} {
+ clock format -552309904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1952 12:34:56 die i mensis vii annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2434195 07 vii 7 07/01/1952 die i mensis vii annoque mcmlii 52 lii 1952}
+test clock-2.614 {conversion of 1952-07-31} {
+ clock format -549717904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1952 12:34:56 die xxxi mensis vii annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2434225 07 vii 7 07/31/1952 die xxxi mensis vii annoque mcmlii 52 lii 1952}
+test clock-2.615 {conversion of 1952-08-01} {
+ clock format -549631504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1952 12:34:56 die i mensis viii annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2434226 08 viii 8 08/01/1952 die i mensis viii annoque mcmlii 52 lii 1952}
+test clock-2.616 {conversion of 1952-08-31} {
+ clock format -547039504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1952 12:34:56 die xxxi mensis viii annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2434256 08 viii 8 08/31/1952 die xxxi mensis viii annoque mcmlii 52 lii 1952}
+test clock-2.617 {conversion of 1952-09-01} {
+ clock format -546953104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1952 12:34:56 die i mensis ix annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2434257 09 ix 9 09/01/1952 die i mensis ix annoque mcmlii 52 lii 1952}
+test clock-2.618 {conversion of 1952-09-30} {
+ clock format -544447504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1952 12:34:56 die xxx mensis ix annoque mcmlii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2434286 09 ix 9 09/30/1952 die xxx mensis ix annoque mcmlii 52 lii 1952}
+test clock-2.619 {conversion of 1952-10-01} {
+ clock format -544361104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1952 12:34:56 die i mensis x annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2434287 10 x 10 10/01/1952 die i mensis x annoque mcmlii 52 lii 1952}
+test clock-2.620 {conversion of 1952-10-31} {
+ clock format -541769104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1952 12:34:56 die xxxi mensis x annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2434317 10 x 10 10/31/1952 die xxxi mensis x annoque mcmlii 52 lii 1952}
+test clock-2.621 {conversion of 1952-11-01} {
+ clock format -541682704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1952 12:34:56 die i mensis xi annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2434318 11 xi 11 11/01/1952 die i mensis xi annoque mcmlii 52 lii 1952}
+test clock-2.622 {conversion of 1952-11-30} {
+ clock format -539177104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1952 12:34:56 die xxx mensis xi annoque mcmlii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2434347 11 xi 11 11/30/1952 die xxx mensis xi annoque mcmlii 52 lii 1952}
+test clock-2.623 {conversion of 1952-12-01} {
+ clock format -539090704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1952 12:34:56 die i mensis xii annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2434348 12 xii 12 12/01/1952 die i mensis xii annoque mcmlii 52 lii 1952}
+test clock-2.624 {conversion of 1952-12-31} {
+ clock format -536498704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1952 12:34:56 die xxxi mensis xii annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2434378 12 xii 12 12/31/1952 die xxxi mensis xii annoque mcmlii 52 lii 1952}
+test clock-2.625 {conversion of 1953-01-01} {
+ clock format -536412304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1953 12:34:56 die i mensis i annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2434379 01 i 1 01/01/1953 die i mensis i annoque mcmliii 53 liii 1953}
+test clock-2.626 {conversion of 1953-01-31} {
+ clock format -533820304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1953 12:34:56 die xxxi mensis i annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2434409 01 i 1 01/31/1953 die xxxi mensis i annoque mcmliii 53 liii 1953}
+test clock-2.627 {conversion of 1953-02-01} {
+ clock format -533733904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1953 12:34:56 die i mensis ii annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2434410 02 ii 2 02/01/1953 die i mensis ii annoque mcmliii 53 liii 1953}
+test clock-2.628 {conversion of 1953-02-28} {
+ clock format -531401104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1953 12:34:56 die xxviii mensis ii annoque mcmliii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2434437 02 ii 2 02/28/1953 die xxviii mensis ii annoque mcmliii 53 liii 1953}
+test clock-2.629 {conversion of 1953-03-01} {
+ clock format -531314704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1953 12:34:56 die i mensis iii annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2434438 03 iii 3 03/01/1953 die i mensis iii annoque mcmliii 53 liii 1953}
+test clock-2.630 {conversion of 1953-03-31} {
+ clock format -528722704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1953 12:34:56 die xxxi mensis iii annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2434468 03 iii 3 03/31/1953 die xxxi mensis iii annoque mcmliii 53 liii 1953}
+test clock-2.631 {conversion of 1953-04-01} {
+ clock format -528636304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1953 12:34:56 die i mensis iv annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2434469 04 iv 4 04/01/1953 die i mensis iv annoque mcmliii 53 liii 1953}
+test clock-2.632 {conversion of 1953-04-30} {
+ clock format -526130704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1953 12:34:56 die xxx mensis iv annoque mcmliii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2434498 04 iv 4 04/30/1953 die xxx mensis iv annoque mcmliii 53 liii 1953}
+test clock-2.633 {conversion of 1953-05-01} {
+ clock format -526044304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1953 12:34:56 die i mensis v annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2434499 05 v 5 05/01/1953 die i mensis v annoque mcmliii 53 liii 1953}
+test clock-2.634 {conversion of 1953-05-31} {
+ clock format -523452304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1953 12:34:56 die xxxi mensis v annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2434529 05 v 5 05/31/1953 die xxxi mensis v annoque mcmliii 53 liii 1953}
+test clock-2.635 {conversion of 1953-06-01} {
+ clock format -523365904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1953 12:34:56 die i mensis vi annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2434530 06 vi 6 06/01/1953 die i mensis vi annoque mcmliii 53 liii 1953}
+test clock-2.636 {conversion of 1953-06-30} {
+ clock format -520860304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1953 12:34:56 die xxx mensis vi annoque mcmliii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2434559 06 vi 6 06/30/1953 die xxx mensis vi annoque mcmliii 53 liii 1953}
+test clock-2.637 {conversion of 1953-07-01} {
+ clock format -520773904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1953 12:34:56 die i mensis vii annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2434560 07 vii 7 07/01/1953 die i mensis vii annoque mcmliii 53 liii 1953}
+test clock-2.638 {conversion of 1953-07-31} {
+ clock format -518181904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1953 12:34:56 die xxxi mensis vii annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2434590 07 vii 7 07/31/1953 die xxxi mensis vii annoque mcmliii 53 liii 1953}
+test clock-2.639 {conversion of 1953-08-01} {
+ clock format -518095504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1953 12:34:56 die i mensis viii annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2434591 08 viii 8 08/01/1953 die i mensis viii annoque mcmliii 53 liii 1953}
+test clock-2.640 {conversion of 1953-08-31} {
+ clock format -515503504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1953 12:34:56 die xxxi mensis viii annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2434621 08 viii 8 08/31/1953 die xxxi mensis viii annoque mcmliii 53 liii 1953}
+test clock-2.641 {conversion of 1953-09-01} {
+ clock format -515417104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1953 12:34:56 die i mensis ix annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2434622 09 ix 9 09/01/1953 die i mensis ix annoque mcmliii 53 liii 1953}
+test clock-2.642 {conversion of 1953-09-30} {
+ clock format -512911504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1953 12:34:56 die xxx mensis ix annoque mcmliii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2434651 09 ix 9 09/30/1953 die xxx mensis ix annoque mcmliii 53 liii 1953}
+test clock-2.643 {conversion of 1953-10-01} {
+ clock format -512825104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1953 12:34:56 die i mensis x annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2434652 10 x 10 10/01/1953 die i mensis x annoque mcmliii 53 liii 1953}
+test clock-2.644 {conversion of 1953-10-31} {
+ clock format -510233104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1953 12:34:56 die xxxi mensis x annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2434682 10 x 10 10/31/1953 die xxxi mensis x annoque mcmliii 53 liii 1953}
+test clock-2.645 {conversion of 1953-11-01} {
+ clock format -510146704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1953 12:34:56 die i mensis xi annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2434683 11 xi 11 11/01/1953 die i mensis xi annoque mcmliii 53 liii 1953}
+test clock-2.646 {conversion of 1953-11-30} {
+ clock format -507641104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1953 12:34:56 die xxx mensis xi annoque mcmliii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2434712 11 xi 11 11/30/1953 die xxx mensis xi annoque mcmliii 53 liii 1953}
+test clock-2.647 {conversion of 1953-12-01} {
+ clock format -507554704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1953 12:34:56 die i mensis xii annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2434713 12 xii 12 12/01/1953 die i mensis xii annoque mcmliii 53 liii 1953}
+test clock-2.648 {conversion of 1953-12-31} {
+ clock format -504962704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1953 12:34:56 die xxxi mensis xii annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2434743 12 xii 12 12/31/1953 die xxxi mensis xii annoque mcmliii 53 liii 1953}
+test clock-2.649 {conversion of 1956-01-01} {
+ clock format -441804304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1956 12:34:56 die i mensis i annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2435474 01 i 1 01/01/1956 die i mensis i annoque mcmlvi 56 lvi 1956}
+test clock-2.650 {conversion of 1956-01-31} {
+ clock format -439212304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1956 12:34:56 die xxxi mensis i annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2435504 01 i 1 01/31/1956 die xxxi mensis i annoque mcmlvi 56 lvi 1956}
+test clock-2.651 {conversion of 1956-02-01} {
+ clock format -439125904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1956 12:34:56 die i mensis ii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2435505 02 ii 2 02/01/1956 die i mensis ii annoque mcmlvi 56 lvi 1956}
+test clock-2.652 {conversion of 1956-02-29} {
+ clock format -436706704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1956 12:34:56 die xxix mensis ii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2435533 02 ii 2 02/29/1956 die xxix mensis ii annoque mcmlvi 56 lvi 1956}
+test clock-2.653 {conversion of 1956-03-01} {
+ clock format -436620304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1956 12:34:56 die i mensis iii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2435534 03 iii 3 03/01/1956 die i mensis iii annoque mcmlvi 56 lvi 1956}
+test clock-2.654 {conversion of 1956-03-31} {
+ clock format -434028304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1956 12:34:56 die xxxi mensis iii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2435564 03 iii 3 03/31/1956 die xxxi mensis iii annoque mcmlvi 56 lvi 1956}
+test clock-2.655 {conversion of 1956-04-01} {
+ clock format -433941904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1956 12:34:56 die i mensis iv annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2435565 04 iv 4 04/01/1956 die i mensis iv annoque mcmlvi 56 lvi 1956}
+test clock-2.656 {conversion of 1956-04-30} {
+ clock format -431436304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1956 12:34:56 die xxx mensis iv annoque mcmlvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2435594 04 iv 4 04/30/1956 die xxx mensis iv annoque mcmlvi 56 lvi 1956}
+test clock-2.657 {conversion of 1956-05-01} {
+ clock format -431349904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1956 12:34:56 die i mensis v annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2435595 05 v 5 05/01/1956 die i mensis v annoque mcmlvi 56 lvi 1956}
+test clock-2.658 {conversion of 1956-05-31} {
+ clock format -428757904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1956 12:34:56 die xxxi mensis v annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2435625 05 v 5 05/31/1956 die xxxi mensis v annoque mcmlvi 56 lvi 1956}
+test clock-2.659 {conversion of 1956-06-01} {
+ clock format -428671504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1956 12:34:56 die i mensis vi annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2435626 06 vi 6 06/01/1956 die i mensis vi annoque mcmlvi 56 lvi 1956}
+test clock-2.660 {conversion of 1956-06-30} {
+ clock format -426165904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1956 12:34:56 die xxx mensis vi annoque mcmlvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2435655 06 vi 6 06/30/1956 die xxx mensis vi annoque mcmlvi 56 lvi 1956}
+test clock-2.661 {conversion of 1956-07-01} {
+ clock format -426079504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1956 12:34:56 die i mensis vii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2435656 07 vii 7 07/01/1956 die i mensis vii annoque mcmlvi 56 lvi 1956}
+test clock-2.662 {conversion of 1956-07-31} {
+ clock format -423487504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1956 12:34:56 die xxxi mensis vii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2435686 07 vii 7 07/31/1956 die xxxi mensis vii annoque mcmlvi 56 lvi 1956}
+test clock-2.663 {conversion of 1956-08-01} {
+ clock format -423401104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1956 12:34:56 die i mensis viii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2435687 08 viii 8 08/01/1956 die i mensis viii annoque mcmlvi 56 lvi 1956}
+test clock-2.664 {conversion of 1956-08-31} {
+ clock format -420809104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1956 12:34:56 die xxxi mensis viii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2435717 08 viii 8 08/31/1956 die xxxi mensis viii annoque mcmlvi 56 lvi 1956}
+test clock-2.665 {conversion of 1956-09-01} {
+ clock format -420722704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1956 12:34:56 die i mensis ix annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2435718 09 ix 9 09/01/1956 die i mensis ix annoque mcmlvi 56 lvi 1956}
+test clock-2.666 {conversion of 1956-09-30} {
+ clock format -418217104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1956 12:34:56 die xxx mensis ix annoque mcmlvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2435747 09 ix 9 09/30/1956 die xxx mensis ix annoque mcmlvi 56 lvi 1956}
+test clock-2.667 {conversion of 1956-10-01} {
+ clock format -418130704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1956 12:34:56 die i mensis x annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2435748 10 x 10 10/01/1956 die i mensis x annoque mcmlvi 56 lvi 1956}
+test clock-2.668 {conversion of 1956-10-31} {
+ clock format -415538704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1956 12:34:56 die xxxi mensis x annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2435778 10 x 10 10/31/1956 die xxxi mensis x annoque mcmlvi 56 lvi 1956}
+test clock-2.669 {conversion of 1956-11-01} {
+ clock format -415452304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1956 12:34:56 die i mensis xi annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2435779 11 xi 11 11/01/1956 die i mensis xi annoque mcmlvi 56 lvi 1956}
+test clock-2.670 {conversion of 1956-11-30} {
+ clock format -412946704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1956 12:34:56 die xxx mensis xi annoque mcmlvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2435808 11 xi 11 11/30/1956 die xxx mensis xi annoque mcmlvi 56 lvi 1956}
+test clock-2.671 {conversion of 1956-12-01} {
+ clock format -412860304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1956 12:34:56 die i mensis xii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2435809 12 xii 12 12/01/1956 die i mensis xii annoque mcmlvi 56 lvi 1956}
+test clock-2.672 {conversion of 1956-12-31} {
+ clock format -410268304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1956 12:34:56 die xxxi mensis xii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2435839 12 xii 12 12/31/1956 die xxxi mensis xii annoque mcmlvi 56 lvi 1956}
+test clock-2.673 {conversion of 1957-01-01} {
+ clock format -410181904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1957 12:34:56 die i mensis i annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2435840 01 i 1 01/01/1957 die i mensis i annoque mcmlvii 57 lvii 1957}
+test clock-2.674 {conversion of 1957-01-31} {
+ clock format -407589904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1957 12:34:56 die xxxi mensis i annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2435870 01 i 1 01/31/1957 die xxxi mensis i annoque mcmlvii 57 lvii 1957}
+test clock-2.675 {conversion of 1957-02-01} {
+ clock format -407503504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1957 12:34:56 die i mensis ii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2435871 02 ii 2 02/01/1957 die i mensis ii annoque mcmlvii 57 lvii 1957}
+test clock-2.676 {conversion of 1957-02-28} {
+ clock format -405170704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1957 12:34:56 die xxviii mensis ii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2435898 02 ii 2 02/28/1957 die xxviii mensis ii annoque mcmlvii 57 lvii 1957}
+test clock-2.677 {conversion of 1957-03-01} {
+ clock format -405084304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1957 12:34:56 die i mensis iii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2435899 03 iii 3 03/01/1957 die i mensis iii annoque mcmlvii 57 lvii 1957}
+test clock-2.678 {conversion of 1957-03-31} {
+ clock format -402492304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1957 12:34:56 die xxxi mensis iii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2435929 03 iii 3 03/31/1957 die xxxi mensis iii annoque mcmlvii 57 lvii 1957}
+test clock-2.679 {conversion of 1957-04-01} {
+ clock format -402405904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1957 12:34:56 die i mensis iv annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2435930 04 iv 4 04/01/1957 die i mensis iv annoque mcmlvii 57 lvii 1957}
+test clock-2.680 {conversion of 1957-04-30} {
+ clock format -399900304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1957 12:34:56 die xxx mensis iv annoque mcmlvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2435959 04 iv 4 04/30/1957 die xxx mensis iv annoque mcmlvii 57 lvii 1957}
+test clock-2.681 {conversion of 1957-05-01} {
+ clock format -399813904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1957 12:34:56 die i mensis v annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2435960 05 v 5 05/01/1957 die i mensis v annoque mcmlvii 57 lvii 1957}
+test clock-2.682 {conversion of 1957-05-31} {
+ clock format -397221904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1957 12:34:56 die xxxi mensis v annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2435990 05 v 5 05/31/1957 die xxxi mensis v annoque mcmlvii 57 lvii 1957}
+test clock-2.683 {conversion of 1957-06-01} {
+ clock format -397135504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1957 12:34:56 die i mensis vi annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2435991 06 vi 6 06/01/1957 die i mensis vi annoque mcmlvii 57 lvii 1957}
+test clock-2.684 {conversion of 1957-06-30} {
+ clock format -394629904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1957 12:34:56 die xxx mensis vi annoque mcmlvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2436020 06 vi 6 06/30/1957 die xxx mensis vi annoque mcmlvii 57 lvii 1957}
+test clock-2.685 {conversion of 1957-07-01} {
+ clock format -394543504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1957 12:34:56 die i mensis vii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2436021 07 vii 7 07/01/1957 die i mensis vii annoque mcmlvii 57 lvii 1957}
+test clock-2.686 {conversion of 1957-07-31} {
+ clock format -391951504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1957 12:34:56 die xxxi mensis vii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2436051 07 vii 7 07/31/1957 die xxxi mensis vii annoque mcmlvii 57 lvii 1957}
+test clock-2.687 {conversion of 1957-08-01} {
+ clock format -391865104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1957 12:34:56 die i mensis viii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2436052 08 viii 8 08/01/1957 die i mensis viii annoque mcmlvii 57 lvii 1957}
+test clock-2.688 {conversion of 1957-08-31} {
+ clock format -389273104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1957 12:34:56 die xxxi mensis viii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2436082 08 viii 8 08/31/1957 die xxxi mensis viii annoque mcmlvii 57 lvii 1957}
+test clock-2.689 {conversion of 1957-09-01} {
+ clock format -389186704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1957 12:34:56 die i mensis ix annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2436083 09 ix 9 09/01/1957 die i mensis ix annoque mcmlvii 57 lvii 1957}
+test clock-2.690 {conversion of 1957-09-30} {
+ clock format -386681104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1957 12:34:56 die xxx mensis ix annoque mcmlvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2436112 09 ix 9 09/30/1957 die xxx mensis ix annoque mcmlvii 57 lvii 1957}
+test clock-2.691 {conversion of 1957-10-01} {
+ clock format -386594704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1957 12:34:56 die i mensis x annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2436113 10 x 10 10/01/1957 die i mensis x annoque mcmlvii 57 lvii 1957}
+test clock-2.692 {conversion of 1957-10-31} {
+ clock format -384002704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1957 12:34:56 die xxxi mensis x annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2436143 10 x 10 10/31/1957 die xxxi mensis x annoque mcmlvii 57 lvii 1957}
+test clock-2.693 {conversion of 1957-11-01} {
+ clock format -383916304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1957 12:34:56 die i mensis xi annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2436144 11 xi 11 11/01/1957 die i mensis xi annoque mcmlvii 57 lvii 1957}
+test clock-2.694 {conversion of 1957-11-30} {
+ clock format -381410704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1957 12:34:56 die xxx mensis xi annoque mcmlvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2436173 11 xi 11 11/30/1957 die xxx mensis xi annoque mcmlvii 57 lvii 1957}
+test clock-2.695 {conversion of 1957-12-01} {
+ clock format -381324304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1957 12:34:56 die i mensis xii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2436174 12 xii 12 12/01/1957 die i mensis xii annoque mcmlvii 57 lvii 1957}
+test clock-2.696 {conversion of 1957-12-31} {
+ clock format -378732304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1957 12:34:56 die xxxi mensis xii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2436204 12 xii 12 12/31/1957 die xxxi mensis xii annoque mcmlvii 57 lvii 1957}
+test clock-2.697 {conversion of 1959-01-01} {
+ clock format -347109904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1959 12:34:56 die i mensis i annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2436570 01 i 1 01/01/1959 die i mensis i annoque mcmlix 59 lix 1959}
+test clock-2.698 {conversion of 1959-01-31} {
+ clock format -344517904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1959 12:34:56 die xxxi mensis i annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2436600 01 i 1 01/31/1959 die xxxi mensis i annoque mcmlix 59 lix 1959}
+test clock-2.699 {conversion of 1959-02-01} {
+ clock format -344431504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1959 12:34:56 die i mensis ii annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2436601 02 ii 2 02/01/1959 die i mensis ii annoque mcmlix 59 lix 1959}
+test clock-2.700 {conversion of 1959-02-28} {
+ clock format -342098704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1959 12:34:56 die xxviii mensis ii annoque mcmlix xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2436628 02 ii 2 02/28/1959 die xxviii mensis ii annoque mcmlix 59 lix 1959}
+test clock-2.701 {conversion of 1959-03-01} {
+ clock format -342012304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1959 12:34:56 die i mensis iii annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2436629 03 iii 3 03/01/1959 die i mensis iii annoque mcmlix 59 lix 1959}
+test clock-2.702 {conversion of 1959-03-31} {
+ clock format -339420304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1959 12:34:56 die xxxi mensis iii annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2436659 03 iii 3 03/31/1959 die xxxi mensis iii annoque mcmlix 59 lix 1959}
+test clock-2.703 {conversion of 1959-04-01} {
+ clock format -339333904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1959 12:34:56 die i mensis iv annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2436660 04 iv 4 04/01/1959 die i mensis iv annoque mcmlix 59 lix 1959}
+test clock-2.704 {conversion of 1959-04-30} {
+ clock format -336828304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1959 12:34:56 die xxx mensis iv annoque mcmlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2436689 04 iv 4 04/30/1959 die xxx mensis iv annoque mcmlix 59 lix 1959}
+test clock-2.705 {conversion of 1959-05-01} {
+ clock format -336741904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1959 12:34:56 die i mensis v annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2436690 05 v 5 05/01/1959 die i mensis v annoque mcmlix 59 lix 1959}
+test clock-2.706 {conversion of 1959-05-31} {
+ clock format -334149904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1959 12:34:56 die xxxi mensis v annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2436720 05 v 5 05/31/1959 die xxxi mensis v annoque mcmlix 59 lix 1959}
+test clock-2.707 {conversion of 1959-06-01} {
+ clock format -334063504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1959 12:34:56 die i mensis vi annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2436721 06 vi 6 06/01/1959 die i mensis vi annoque mcmlix 59 lix 1959}
+test clock-2.708 {conversion of 1959-06-30} {
+ clock format -331557904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1959 12:34:56 die xxx mensis vi annoque mcmlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2436750 06 vi 6 06/30/1959 die xxx mensis vi annoque mcmlix 59 lix 1959}
+test clock-2.709 {conversion of 1959-07-01} {
+ clock format -331471504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1959 12:34:56 die i mensis vii annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2436751 07 vii 7 07/01/1959 die i mensis vii annoque mcmlix 59 lix 1959}
+test clock-2.710 {conversion of 1959-07-31} {
+ clock format -328879504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1959 12:34:56 die xxxi mensis vii annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2436781 07 vii 7 07/31/1959 die xxxi mensis vii annoque mcmlix 59 lix 1959}
+test clock-2.711 {conversion of 1959-08-01} {
+ clock format -328793104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1959 12:34:56 die i mensis viii annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2436782 08 viii 8 08/01/1959 die i mensis viii annoque mcmlix 59 lix 1959}
+test clock-2.712 {conversion of 1959-08-31} {
+ clock format -326201104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1959 12:34:56 die xxxi mensis viii annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2436812 08 viii 8 08/31/1959 die xxxi mensis viii annoque mcmlix 59 lix 1959}
+test clock-2.713 {conversion of 1959-09-01} {
+ clock format -326114704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1959 12:34:56 die i mensis ix annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2436813 09 ix 9 09/01/1959 die i mensis ix annoque mcmlix 59 lix 1959}
+test clock-2.714 {conversion of 1959-09-30} {
+ clock format -323609104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1959 12:34:56 die xxx mensis ix annoque mcmlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2436842 09 ix 9 09/30/1959 die xxx mensis ix annoque mcmlix 59 lix 1959}
+test clock-2.715 {conversion of 1959-10-01} {
+ clock format -323522704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1959 12:34:56 die i mensis x annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2436843 10 x 10 10/01/1959 die i mensis x annoque mcmlix 59 lix 1959}
+test clock-2.716 {conversion of 1959-10-31} {
+ clock format -320930704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1959 12:34:56 die xxxi mensis x annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2436873 10 x 10 10/31/1959 die xxxi mensis x annoque mcmlix 59 lix 1959}
+test clock-2.717 {conversion of 1959-11-01} {
+ clock format -320844304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1959 12:34:56 die i mensis xi annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2436874 11 xi 11 11/01/1959 die i mensis xi annoque mcmlix 59 lix 1959}
+test clock-2.718 {conversion of 1959-11-30} {
+ clock format -318338704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1959 12:34:56 die xxx mensis xi annoque mcmlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2436903 11 xi 11 11/30/1959 die xxx mensis xi annoque mcmlix 59 lix 1959}
+test clock-2.719 {conversion of 1959-12-01} {
+ clock format -318252304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1959 12:34:56 die i mensis xii annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2436904 12 xii 12 12/01/1959 die i mensis xii annoque mcmlix 59 lix 1959}
+test clock-2.720 {conversion of 1959-12-31} {
+ clock format -315660304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1959 12:34:56 die xxxi mensis xii annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2436934 12 xii 12 12/31/1959 die xxxi mensis xii annoque mcmlix 59 lix 1959}
+test clock-2.721 {conversion of 1960-01-01} {
+ clock format -315573904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1960 12:34:56 die i mensis i annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2436935 01 i 1 01/01/1960 die i mensis i annoque mcmlx 60 lx 1960}
+test clock-2.722 {conversion of 1960-01-31} {
+ clock format -312981904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1960 12:34:56 die xxxi mensis i annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2436965 01 i 1 01/31/1960 die xxxi mensis i annoque mcmlx 60 lx 1960}
+test clock-2.723 {conversion of 1960-02-01} {
+ clock format -312895504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1960 12:34:56 die i mensis ii annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2436966 02 ii 2 02/01/1960 die i mensis ii annoque mcmlx 60 lx 1960}
+test clock-2.724 {conversion of 1960-02-29} {
+ clock format -310476304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1960 12:34:56 die xxix mensis ii annoque mcmlx xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2436994 02 ii 2 02/29/1960 die xxix mensis ii annoque mcmlx 60 lx 1960}
+test clock-2.725 {conversion of 1960-03-01} {
+ clock format -310389904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1960 12:34:56 die i mensis iii annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2436995 03 iii 3 03/01/1960 die i mensis iii annoque mcmlx 60 lx 1960}
+test clock-2.726 {conversion of 1960-03-31} {
+ clock format -307797904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1960 12:34:56 die xxxi mensis iii annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2437025 03 iii 3 03/31/1960 die xxxi mensis iii annoque mcmlx 60 lx 1960}
+test clock-2.727 {conversion of 1960-04-01} {
+ clock format -307711504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1960 12:34:56 die i mensis iv annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2437026 04 iv 4 04/01/1960 die i mensis iv annoque mcmlx 60 lx 1960}
+test clock-2.728 {conversion of 1960-04-30} {
+ clock format -305205904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1960 12:34:56 die xxx mensis iv annoque mcmlx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2437055 04 iv 4 04/30/1960 die xxx mensis iv annoque mcmlx 60 lx 1960}
+test clock-2.729 {conversion of 1960-05-01} {
+ clock format -305119504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1960 12:34:56 die i mensis v annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2437056 05 v 5 05/01/1960 die i mensis v annoque mcmlx 60 lx 1960}
+test clock-2.730 {conversion of 1960-05-31} {
+ clock format -302527504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1960 12:34:56 die xxxi mensis v annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2437086 05 v 5 05/31/1960 die xxxi mensis v annoque mcmlx 60 lx 1960}
+test clock-2.731 {conversion of 1960-06-01} {
+ clock format -302441104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1960 12:34:56 die i mensis vi annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2437087 06 vi 6 06/01/1960 die i mensis vi annoque mcmlx 60 lx 1960}
+test clock-2.732 {conversion of 1960-06-30} {
+ clock format -299935504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1960 12:34:56 die xxx mensis vi annoque mcmlx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2437116 06 vi 6 06/30/1960 die xxx mensis vi annoque mcmlx 60 lx 1960}
+test clock-2.733 {conversion of 1960-07-01} {
+ clock format -299849104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1960 12:34:56 die i mensis vii annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2437117 07 vii 7 07/01/1960 die i mensis vii annoque mcmlx 60 lx 1960}
+test clock-2.734 {conversion of 1960-07-31} {
+ clock format -297257104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1960 12:34:56 die xxxi mensis vii annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2437147 07 vii 7 07/31/1960 die xxxi mensis vii annoque mcmlx 60 lx 1960}
+test clock-2.735 {conversion of 1960-08-01} {
+ clock format -297170704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1960 12:34:56 die i mensis viii annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2437148 08 viii 8 08/01/1960 die i mensis viii annoque mcmlx 60 lx 1960}
+test clock-2.736 {conversion of 1960-08-31} {
+ clock format -294578704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1960 12:34:56 die xxxi mensis viii annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2437178 08 viii 8 08/31/1960 die xxxi mensis viii annoque mcmlx 60 lx 1960}
+test clock-2.737 {conversion of 1960-09-01} {
+ clock format -294492304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1960 12:34:56 die i mensis ix annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2437179 09 ix 9 09/01/1960 die i mensis ix annoque mcmlx 60 lx 1960}
+test clock-2.738 {conversion of 1960-09-30} {
+ clock format -291986704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1960 12:34:56 die xxx mensis ix annoque mcmlx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2437208 09 ix 9 09/30/1960 die xxx mensis ix annoque mcmlx 60 lx 1960}
+test clock-2.739 {conversion of 1960-10-01} {
+ clock format -291900304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1960 12:34:56 die i mensis x annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2437209 10 x 10 10/01/1960 die i mensis x annoque mcmlx 60 lx 1960}
+test clock-2.740 {conversion of 1960-10-31} {
+ clock format -289308304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1960 12:34:56 die xxxi mensis x annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2437239 10 x 10 10/31/1960 die xxxi mensis x annoque mcmlx 60 lx 1960}
+test clock-2.741 {conversion of 1960-11-01} {
+ clock format -289221904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1960 12:34:56 die i mensis xi annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2437240 11 xi 11 11/01/1960 die i mensis xi annoque mcmlx 60 lx 1960}
+test clock-2.742 {conversion of 1960-11-30} {
+ clock format -286716304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1960 12:34:56 die xxx mensis xi annoque mcmlx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2437269 11 xi 11 11/30/1960 die xxx mensis xi annoque mcmlx 60 lx 1960}
+test clock-2.743 {conversion of 1960-12-01} {
+ clock format -286629904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1960 12:34:56 die i mensis xii annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2437270 12 xii 12 12/01/1960 die i mensis xii annoque mcmlx 60 lx 1960}
+test clock-2.744 {conversion of 1960-12-31} {
+ clock format -284037904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1960 12:34:56 die xxxi mensis xii annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2437300 12 xii 12 12/31/1960 die xxxi mensis xii annoque mcmlx 60 lx 1960}
+test clock-2.745 {conversion of 1961-01-01} {
+ clock format -283951504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1961 12:34:56 die i mensis i annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2437301 01 i 1 01/01/1961 die i mensis i annoque mcmlxi 61 lxi 1961}
+test clock-2.746 {conversion of 1961-01-31} {
+ clock format -281359504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1961 12:34:56 die xxxi mensis i annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2437331 01 i 1 01/31/1961 die xxxi mensis i annoque mcmlxi 61 lxi 1961}
+test clock-2.747 {conversion of 1961-02-01} {
+ clock format -281273104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1961 12:34:56 die i mensis ii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2437332 02 ii 2 02/01/1961 die i mensis ii annoque mcmlxi 61 lxi 1961}
+test clock-2.748 {conversion of 1961-02-28} {
+ clock format -278940304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1961 12:34:56 die xxviii mensis ii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2437359 02 ii 2 02/28/1961 die xxviii mensis ii annoque mcmlxi 61 lxi 1961}
+test clock-2.749 {conversion of 1961-03-01} {
+ clock format -278853904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1961 12:34:56 die i mensis iii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2437360 03 iii 3 03/01/1961 die i mensis iii annoque mcmlxi 61 lxi 1961}
+test clock-2.750 {conversion of 1961-03-31} {
+ clock format -276261904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1961 12:34:56 die xxxi mensis iii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2437390 03 iii 3 03/31/1961 die xxxi mensis iii annoque mcmlxi 61 lxi 1961}
+test clock-2.751 {conversion of 1961-04-01} {
+ clock format -276175504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1961 12:34:56 die i mensis iv annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2437391 04 iv 4 04/01/1961 die i mensis iv annoque mcmlxi 61 lxi 1961}
+test clock-2.752 {conversion of 1961-04-30} {
+ clock format -273669904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1961 12:34:56 die xxx mensis iv annoque mcmlxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2437420 04 iv 4 04/30/1961 die xxx mensis iv annoque mcmlxi 61 lxi 1961}
+test clock-2.753 {conversion of 1961-05-01} {
+ clock format -273583504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1961 12:34:56 die i mensis v annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2437421 05 v 5 05/01/1961 die i mensis v annoque mcmlxi 61 lxi 1961}
+test clock-2.754 {conversion of 1961-05-31} {
+ clock format -270991504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1961 12:34:56 die xxxi mensis v annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2437451 05 v 5 05/31/1961 die xxxi mensis v annoque mcmlxi 61 lxi 1961}
+test clock-2.755 {conversion of 1961-06-01} {
+ clock format -270905104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1961 12:34:56 die i mensis vi annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2437452 06 vi 6 06/01/1961 die i mensis vi annoque mcmlxi 61 lxi 1961}
+test clock-2.756 {conversion of 1961-06-30} {
+ clock format -268399504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1961 12:34:56 die xxx mensis vi annoque mcmlxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2437481 06 vi 6 06/30/1961 die xxx mensis vi annoque mcmlxi 61 lxi 1961}
+test clock-2.757 {conversion of 1961-07-01} {
+ clock format -268313104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1961 12:34:56 die i mensis vii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2437482 07 vii 7 07/01/1961 die i mensis vii annoque mcmlxi 61 lxi 1961}
+test clock-2.758 {conversion of 1961-07-31} {
+ clock format -265721104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1961 12:34:56 die xxxi mensis vii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2437512 07 vii 7 07/31/1961 die xxxi mensis vii annoque mcmlxi 61 lxi 1961}
+test clock-2.759 {conversion of 1961-08-01} {
+ clock format -265634704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1961 12:34:56 die i mensis viii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2437513 08 viii 8 08/01/1961 die i mensis viii annoque mcmlxi 61 lxi 1961}
+test clock-2.760 {conversion of 1961-08-31} {
+ clock format -263042704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1961 12:34:56 die xxxi mensis viii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2437543 08 viii 8 08/31/1961 die xxxi mensis viii annoque mcmlxi 61 lxi 1961}
+test clock-2.761 {conversion of 1961-09-01} {
+ clock format -262956304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1961 12:34:56 die i mensis ix annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2437544 09 ix 9 09/01/1961 die i mensis ix annoque mcmlxi 61 lxi 1961}
+test clock-2.762 {conversion of 1961-09-30} {
+ clock format -260450704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1961 12:34:56 die xxx mensis ix annoque mcmlxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2437573 09 ix 9 09/30/1961 die xxx mensis ix annoque mcmlxi 61 lxi 1961}
+test clock-2.763 {conversion of 1961-10-01} {
+ clock format -260364304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1961 12:34:56 die i mensis x annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2437574 10 x 10 10/01/1961 die i mensis x annoque mcmlxi 61 lxi 1961}
+test clock-2.764 {conversion of 1961-10-31} {
+ clock format -257772304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1961 12:34:56 die xxxi mensis x annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2437604 10 x 10 10/31/1961 die xxxi mensis x annoque mcmlxi 61 lxi 1961}
+test clock-2.765 {conversion of 1961-11-01} {
+ clock format -257685904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1961 12:34:56 die i mensis xi annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2437605 11 xi 11 11/01/1961 die i mensis xi annoque mcmlxi 61 lxi 1961}
+test clock-2.766 {conversion of 1961-11-30} {
+ clock format -255180304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1961 12:34:56 die xxx mensis xi annoque mcmlxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2437634 11 xi 11 11/30/1961 die xxx mensis xi annoque mcmlxi 61 lxi 1961}
+test clock-2.767 {conversion of 1961-12-01} {
+ clock format -255093904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1961 12:34:56 die i mensis xii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2437635 12 xii 12 12/01/1961 die i mensis xii annoque mcmlxi 61 lxi 1961}
+test clock-2.768 {conversion of 1961-12-31} {
+ clock format -252501904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1961 12:34:56 die xxxi mensis xii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2437665 12 xii 12 12/31/1961 die xxxi mensis xii annoque mcmlxi 61 lxi 1961}
+test clock-2.769 {conversion of 1962-01-01} {
+ clock format -252415504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1962 12:34:56 die i mensis i annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2437666 01 i 1 01/01/1962 die i mensis i annoque mcmlxii 62 lxii 1962}
+test clock-2.770 {conversion of 1962-01-31} {
+ clock format -249823504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1962 12:34:56 die xxxi mensis i annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2437696 01 i 1 01/31/1962 die xxxi mensis i annoque mcmlxii 62 lxii 1962}
+test clock-2.771 {conversion of 1962-02-01} {
+ clock format -249737104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1962 12:34:56 die i mensis ii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2437697 02 ii 2 02/01/1962 die i mensis ii annoque mcmlxii 62 lxii 1962}
+test clock-2.772 {conversion of 1962-02-28} {
+ clock format -247404304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1962 12:34:56 die xxviii mensis ii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2437724 02 ii 2 02/28/1962 die xxviii mensis ii annoque mcmlxii 62 lxii 1962}
+test clock-2.773 {conversion of 1962-03-01} {
+ clock format -247317904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1962 12:34:56 die i mensis iii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2437725 03 iii 3 03/01/1962 die i mensis iii annoque mcmlxii 62 lxii 1962}
+test clock-2.774 {conversion of 1962-03-31} {
+ clock format -244725904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1962 12:34:56 die xxxi mensis iii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2437755 03 iii 3 03/31/1962 die xxxi mensis iii annoque mcmlxii 62 lxii 1962}
+test clock-2.775 {conversion of 1962-04-01} {
+ clock format -244639504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1962 12:34:56 die i mensis iv annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2437756 04 iv 4 04/01/1962 die i mensis iv annoque mcmlxii 62 lxii 1962}
+test clock-2.776 {conversion of 1962-04-30} {
+ clock format -242133904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1962 12:34:56 die xxx mensis iv annoque mcmlxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2437785 04 iv 4 04/30/1962 die xxx mensis iv annoque mcmlxii 62 lxii 1962}
+test clock-2.777 {conversion of 1962-05-01} {
+ clock format -242047504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1962 12:34:56 die i mensis v annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2437786 05 v 5 05/01/1962 die i mensis v annoque mcmlxii 62 lxii 1962}
+test clock-2.778 {conversion of 1962-05-31} {
+ clock format -239455504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1962 12:34:56 die xxxi mensis v annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2437816 05 v 5 05/31/1962 die xxxi mensis v annoque mcmlxii 62 lxii 1962}
+test clock-2.779 {conversion of 1962-06-01} {
+ clock format -239369104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1962 12:34:56 die i mensis vi annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2437817 06 vi 6 06/01/1962 die i mensis vi annoque mcmlxii 62 lxii 1962}
+test clock-2.780 {conversion of 1962-06-30} {
+ clock format -236863504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1962 12:34:56 die xxx mensis vi annoque mcmlxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2437846 06 vi 6 06/30/1962 die xxx mensis vi annoque mcmlxii 62 lxii 1962}
+test clock-2.781 {conversion of 1962-07-01} {
+ clock format -236777104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1962 12:34:56 die i mensis vii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2437847 07 vii 7 07/01/1962 die i mensis vii annoque mcmlxii 62 lxii 1962}
+test clock-2.782 {conversion of 1962-07-31} {
+ clock format -234185104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1962 12:34:56 die xxxi mensis vii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2437877 07 vii 7 07/31/1962 die xxxi mensis vii annoque mcmlxii 62 lxii 1962}
+test clock-2.783 {conversion of 1962-08-01} {
+ clock format -234098704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1962 12:34:56 die i mensis viii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2437878 08 viii 8 08/01/1962 die i mensis viii annoque mcmlxii 62 lxii 1962}
+test clock-2.784 {conversion of 1962-08-31} {
+ clock format -231506704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1962 12:34:56 die xxxi mensis viii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2437908 08 viii 8 08/31/1962 die xxxi mensis viii annoque mcmlxii 62 lxii 1962}
+test clock-2.785 {conversion of 1962-09-01} {
+ clock format -231420304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1962 12:34:56 die i mensis ix annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2437909 09 ix 9 09/01/1962 die i mensis ix annoque mcmlxii 62 lxii 1962}
+test clock-2.786 {conversion of 1962-09-30} {
+ clock format -228914704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1962 12:34:56 die xxx mensis ix annoque mcmlxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2437938 09 ix 9 09/30/1962 die xxx mensis ix annoque mcmlxii 62 lxii 1962}
+test clock-2.787 {conversion of 1962-10-01} {
+ clock format -228828304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1962 12:34:56 die i mensis x annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2437939 10 x 10 10/01/1962 die i mensis x annoque mcmlxii 62 lxii 1962}
+test clock-2.788 {conversion of 1962-10-31} {
+ clock format -226236304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1962 12:34:56 die xxxi mensis x annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2437969 10 x 10 10/31/1962 die xxxi mensis x annoque mcmlxii 62 lxii 1962}
+test clock-2.789 {conversion of 1962-11-01} {
+ clock format -226149904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1962 12:34:56 die i mensis xi annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2437970 11 xi 11 11/01/1962 die i mensis xi annoque mcmlxii 62 lxii 1962}
+test clock-2.790 {conversion of 1962-11-30} {
+ clock format -223644304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1962 12:34:56 die xxx mensis xi annoque mcmlxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2437999 11 xi 11 11/30/1962 die xxx mensis xi annoque mcmlxii 62 lxii 1962}
+test clock-2.791 {conversion of 1962-12-01} {
+ clock format -223557904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1962 12:34:56 die i mensis xii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2438000 12 xii 12 12/01/1962 die i mensis xii annoque mcmlxii 62 lxii 1962}
+test clock-2.792 {conversion of 1962-12-31} {
+ clock format -220965904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1962 12:34:56 die xxxi mensis xii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2438030 12 xii 12 12/31/1962 die xxxi mensis xii annoque mcmlxii 62 lxii 1962}
+test clock-2.793 {conversion of 1963-01-01} {
+ clock format -220879504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1963 12:34:56 die i mensis i annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2438031 01 i 1 01/01/1963 die i mensis i annoque mcmlxiii 63 lxiii 1963}
+test clock-2.794 {conversion of 1963-01-31} {
+ clock format -218287504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1963 12:34:56 die xxxi mensis i annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2438061 01 i 1 01/31/1963 die xxxi mensis i annoque mcmlxiii 63 lxiii 1963}
+test clock-2.795 {conversion of 1963-02-01} {
+ clock format -218201104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1963 12:34:56 die i mensis ii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2438062 02 ii 2 02/01/1963 die i mensis ii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.796 {conversion of 1963-02-28} {
+ clock format -215868304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1963 12:34:56 die xxviii mensis ii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2438089 02 ii 2 02/28/1963 die xxviii mensis ii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.797 {conversion of 1963-03-01} {
+ clock format -215781904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1963 12:34:56 die i mensis iii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2438090 03 iii 3 03/01/1963 die i mensis iii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.798 {conversion of 1963-03-31} {
+ clock format -213189904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1963 12:34:56 die xxxi mensis iii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2438120 03 iii 3 03/31/1963 die xxxi mensis iii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.799 {conversion of 1963-04-01} {
+ clock format -213103504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1963 12:34:56 die i mensis iv annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2438121 04 iv 4 04/01/1963 die i mensis iv annoque mcmlxiii 63 lxiii 1963}
+test clock-2.800 {conversion of 1963-04-30} {
+ clock format -210597904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1963 12:34:56 die xxx mensis iv annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2438150 04 iv 4 04/30/1963 die xxx mensis iv annoque mcmlxiii 63 lxiii 1963}
+test clock-2.801 {conversion of 1963-05-01} {
+ clock format -210511504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1963 12:34:56 die i mensis v annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2438151 05 v 5 05/01/1963 die i mensis v annoque mcmlxiii 63 lxiii 1963}
+test clock-2.802 {conversion of 1963-05-31} {
+ clock format -207919504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1963 12:34:56 die xxxi mensis v annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2438181 05 v 5 05/31/1963 die xxxi mensis v annoque mcmlxiii 63 lxiii 1963}
+test clock-2.803 {conversion of 1963-06-01} {
+ clock format -207833104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1963 12:34:56 die i mensis vi annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2438182 06 vi 6 06/01/1963 die i mensis vi annoque mcmlxiii 63 lxiii 1963}
+test clock-2.804 {conversion of 1963-06-30} {
+ clock format -205327504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1963 12:34:56 die xxx mensis vi annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2438211 06 vi 6 06/30/1963 die xxx mensis vi annoque mcmlxiii 63 lxiii 1963}
+test clock-2.805 {conversion of 1963-07-01} {
+ clock format -205241104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1963 12:34:56 die i mensis vii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2438212 07 vii 7 07/01/1963 die i mensis vii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.806 {conversion of 1963-07-31} {
+ clock format -202649104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1963 12:34:56 die xxxi mensis vii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2438242 07 vii 7 07/31/1963 die xxxi mensis vii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.807 {conversion of 1963-08-01} {
+ clock format -202562704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1963 12:34:56 die i mensis viii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2438243 08 viii 8 08/01/1963 die i mensis viii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.808 {conversion of 1963-08-31} {
+ clock format -199970704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1963 12:34:56 die xxxi mensis viii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2438273 08 viii 8 08/31/1963 die xxxi mensis viii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.809 {conversion of 1963-09-01} {
+ clock format -199884304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1963 12:34:56 die i mensis ix annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2438274 09 ix 9 09/01/1963 die i mensis ix annoque mcmlxiii 63 lxiii 1963}
+test clock-2.810 {conversion of 1963-09-30} {
+ clock format -197378704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1963 12:34:56 die xxx mensis ix annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2438303 09 ix 9 09/30/1963 die xxx mensis ix annoque mcmlxiii 63 lxiii 1963}
+test clock-2.811 {conversion of 1963-10-01} {
+ clock format -197292304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1963 12:34:56 die i mensis x annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2438304 10 x 10 10/01/1963 die i mensis x annoque mcmlxiii 63 lxiii 1963}
+test clock-2.812 {conversion of 1963-10-31} {
+ clock format -194700304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1963 12:34:56 die xxxi mensis x annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2438334 10 x 10 10/31/1963 die xxxi mensis x annoque mcmlxiii 63 lxiii 1963}
+test clock-2.813 {conversion of 1963-11-01} {
+ clock format -194613904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1963 12:34:56 die i mensis xi annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2438335 11 xi 11 11/01/1963 die i mensis xi annoque mcmlxiii 63 lxiii 1963}
+test clock-2.814 {conversion of 1963-11-30} {
+ clock format -192108304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1963 12:34:56 die xxx mensis xi annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2438364 11 xi 11 11/30/1963 die xxx mensis xi annoque mcmlxiii 63 lxiii 1963}
+test clock-2.815 {conversion of 1963-12-01} {
+ clock format -192021904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1963 12:34:56 die i mensis xii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2438365 12 xii 12 12/01/1963 die i mensis xii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.816 {conversion of 1963-12-31} {
+ clock format -189429904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1963 12:34:56 die xxxi mensis xii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2438395 12 xii 12 12/31/1963 die xxxi mensis xii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.817 {conversion of 1964-01-01} {
+ clock format -189343504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1964 12:34:56 die i mensis i annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2438396 01 i 1 01/01/1964 die i mensis i annoque mcmlxiv 64 lxiv 1964}
+test clock-2.818 {conversion of 1964-01-31} {
+ clock format -186751504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1964 12:34:56 die xxxi mensis i annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2438426 01 i 1 01/31/1964 die xxxi mensis i annoque mcmlxiv 64 lxiv 1964}
+test clock-2.819 {conversion of 1964-02-01} {
+ clock format -186665104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1964 12:34:56 die i mensis ii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2438427 02 ii 2 02/01/1964 die i mensis ii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.820 {conversion of 1964-02-29} {
+ clock format -184245904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1964 12:34:56 die xxix mensis ii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2438455 02 ii 2 02/29/1964 die xxix mensis ii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.821 {conversion of 1964-03-01} {
+ clock format -184159504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1964 12:34:56 die i mensis iii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2438456 03 iii 3 03/01/1964 die i mensis iii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.822 {conversion of 1964-03-31} {
+ clock format -181567504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1964 12:34:56 die xxxi mensis iii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2438486 03 iii 3 03/31/1964 die xxxi mensis iii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.823 {conversion of 1964-04-01} {
+ clock format -181481104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1964 12:34:56 die i mensis iv annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2438487 04 iv 4 04/01/1964 die i mensis iv annoque mcmlxiv 64 lxiv 1964}
+test clock-2.824 {conversion of 1964-04-30} {
+ clock format -178975504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1964 12:34:56 die xxx mensis iv annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2438516 04 iv 4 04/30/1964 die xxx mensis iv annoque mcmlxiv 64 lxiv 1964}
+test clock-2.825 {conversion of 1964-05-01} {
+ clock format -178889104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1964 12:34:56 die i mensis v annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2438517 05 v 5 05/01/1964 die i mensis v annoque mcmlxiv 64 lxiv 1964}
+test clock-2.826 {conversion of 1964-05-31} {
+ clock format -176297104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1964 12:34:56 die xxxi mensis v annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2438547 05 v 5 05/31/1964 die xxxi mensis v annoque mcmlxiv 64 lxiv 1964}
+test clock-2.827 {conversion of 1964-06-01} {
+ clock format -176210704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1964 12:34:56 die i mensis vi annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2438548 06 vi 6 06/01/1964 die i mensis vi annoque mcmlxiv 64 lxiv 1964}
+test clock-2.828 {conversion of 1964-06-30} {
+ clock format -173705104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1964 12:34:56 die xxx mensis vi annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2438577 06 vi 6 06/30/1964 die xxx mensis vi annoque mcmlxiv 64 lxiv 1964}
+test clock-2.829 {conversion of 1964-07-01} {
+ clock format -173618704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1964 12:34:56 die i mensis vii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2438578 07 vii 7 07/01/1964 die i mensis vii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.830 {conversion of 1964-07-31} {
+ clock format -171026704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1964 12:34:56 die xxxi mensis vii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2438608 07 vii 7 07/31/1964 die xxxi mensis vii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.831 {conversion of 1964-08-01} {
+ clock format -170940304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1964 12:34:56 die i mensis viii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2438609 08 viii 8 08/01/1964 die i mensis viii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.832 {conversion of 1964-08-31} {
+ clock format -168348304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1964 12:34:56 die xxxi mensis viii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2438639 08 viii 8 08/31/1964 die xxxi mensis viii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.833 {conversion of 1964-09-01} {
+ clock format -168261904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1964 12:34:56 die i mensis ix annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2438640 09 ix 9 09/01/1964 die i mensis ix annoque mcmlxiv 64 lxiv 1964}
+test clock-2.834 {conversion of 1964-09-30} {
+ clock format -165756304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1964 12:34:56 die xxx mensis ix annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2438669 09 ix 9 09/30/1964 die xxx mensis ix annoque mcmlxiv 64 lxiv 1964}
+test clock-2.835 {conversion of 1964-10-01} {
+ clock format -165669904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1964 12:34:56 die i mensis x annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2438670 10 x 10 10/01/1964 die i mensis x annoque mcmlxiv 64 lxiv 1964}
+test clock-2.836 {conversion of 1964-10-31} {
+ clock format -163077904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1964 12:34:56 die xxxi mensis x annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2438700 10 x 10 10/31/1964 die xxxi mensis x annoque mcmlxiv 64 lxiv 1964}
+test clock-2.837 {conversion of 1964-11-01} {
+ clock format -162991504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1964 12:34:56 die i mensis xi annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2438701 11 xi 11 11/01/1964 die i mensis xi annoque mcmlxiv 64 lxiv 1964}
+test clock-2.838 {conversion of 1964-11-30} {
+ clock format -160485904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1964 12:34:56 die xxx mensis xi annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2438730 11 xi 11 11/30/1964 die xxx mensis xi annoque mcmlxiv 64 lxiv 1964}
+test clock-2.839 {conversion of 1964-12-01} {
+ clock format -160399504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1964 12:34:56 die i mensis xii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2438731 12 xii 12 12/01/1964 die i mensis xii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.840 {conversion of 1964-12-31} {
+ clock format -157807504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1964 12:34:56 die xxxi mensis xii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2438761 12 xii 12 12/31/1964 die xxxi mensis xii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.841 {conversion of 1965-01-01} {
+ clock format -157721104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1965 12:34:56 die i mensis i annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2438762 01 i 1 01/01/1965 die i mensis i annoque mcmlxv 65 lxv 1965}
+test clock-2.842 {conversion of 1965-01-31} {
+ clock format -155129104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1965 12:34:56 die xxxi mensis i annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2438792 01 i 1 01/31/1965 die xxxi mensis i annoque mcmlxv 65 lxv 1965}
+test clock-2.843 {conversion of 1965-02-01} {
+ clock format -155042704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1965 12:34:56 die i mensis ii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2438793 02 ii 2 02/01/1965 die i mensis ii annoque mcmlxv 65 lxv 1965}
+test clock-2.844 {conversion of 1965-02-28} {
+ clock format -152709904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1965 12:34:56 die xxviii mensis ii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2438820 02 ii 2 02/28/1965 die xxviii mensis ii annoque mcmlxv 65 lxv 1965}
+test clock-2.845 {conversion of 1965-03-01} {
+ clock format -152623504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1965 12:34:56 die i mensis iii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2438821 03 iii 3 03/01/1965 die i mensis iii annoque mcmlxv 65 lxv 1965}
+test clock-2.846 {conversion of 1965-03-31} {
+ clock format -150031504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1965 12:34:56 die xxxi mensis iii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2438851 03 iii 3 03/31/1965 die xxxi mensis iii annoque mcmlxv 65 lxv 1965}
+test clock-2.847 {conversion of 1965-04-01} {
+ clock format -149945104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1965 12:34:56 die i mensis iv annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2438852 04 iv 4 04/01/1965 die i mensis iv annoque mcmlxv 65 lxv 1965}
+test clock-2.848 {conversion of 1965-04-30} {
+ clock format -147439504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1965 12:34:56 die xxx mensis iv annoque mcmlxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2438881 04 iv 4 04/30/1965 die xxx mensis iv annoque mcmlxv 65 lxv 1965}
+test clock-2.849 {conversion of 1965-05-01} {
+ clock format -147353104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1965 12:34:56 die i mensis v annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2438882 05 v 5 05/01/1965 die i mensis v annoque mcmlxv 65 lxv 1965}
+test clock-2.850 {conversion of 1965-05-31} {
+ clock format -144761104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1965 12:34:56 die xxxi mensis v annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2438912 05 v 5 05/31/1965 die xxxi mensis v annoque mcmlxv 65 lxv 1965}
+test clock-2.851 {conversion of 1965-06-01} {
+ clock format -144674704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1965 12:34:56 die i mensis vi annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2438913 06 vi 6 06/01/1965 die i mensis vi annoque mcmlxv 65 lxv 1965}
+test clock-2.852 {conversion of 1965-06-30} {
+ clock format -142169104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1965 12:34:56 die xxx mensis vi annoque mcmlxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2438942 06 vi 6 06/30/1965 die xxx mensis vi annoque mcmlxv 65 lxv 1965}
+test clock-2.853 {conversion of 1965-07-01} {
+ clock format -142082704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1965 12:34:56 die i mensis vii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2438943 07 vii 7 07/01/1965 die i mensis vii annoque mcmlxv 65 lxv 1965}
+test clock-2.854 {conversion of 1965-07-31} {
+ clock format -139490704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1965 12:34:56 die xxxi mensis vii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2438973 07 vii 7 07/31/1965 die xxxi mensis vii annoque mcmlxv 65 lxv 1965}
+test clock-2.855 {conversion of 1965-08-01} {
+ clock format -139404304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1965 12:34:56 die i mensis viii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2438974 08 viii 8 08/01/1965 die i mensis viii annoque mcmlxv 65 lxv 1965}
+test clock-2.856 {conversion of 1965-08-31} {
+ clock format -136812304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1965 12:34:56 die xxxi mensis viii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2439004 08 viii 8 08/31/1965 die xxxi mensis viii annoque mcmlxv 65 lxv 1965}
+test clock-2.857 {conversion of 1965-09-01} {
+ clock format -136725904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1965 12:34:56 die i mensis ix annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2439005 09 ix 9 09/01/1965 die i mensis ix annoque mcmlxv 65 lxv 1965}
+test clock-2.858 {conversion of 1965-09-30} {
+ clock format -134220304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1965 12:34:56 die xxx mensis ix annoque mcmlxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2439034 09 ix 9 09/30/1965 die xxx mensis ix annoque mcmlxv 65 lxv 1965}
+test clock-2.859 {conversion of 1965-10-01} {
+ clock format -134133904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1965 12:34:56 die i mensis x annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2439035 10 x 10 10/01/1965 die i mensis x annoque mcmlxv 65 lxv 1965}
+test clock-2.860 {conversion of 1965-10-31} {
+ clock format -131541904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1965 12:34:56 die xxxi mensis x annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2439065 10 x 10 10/31/1965 die xxxi mensis x annoque mcmlxv 65 lxv 1965}
+test clock-2.861 {conversion of 1965-11-01} {
+ clock format -131455504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1965 12:34:56 die i mensis xi annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2439066 11 xi 11 11/01/1965 die i mensis xi annoque mcmlxv 65 lxv 1965}
+test clock-2.862 {conversion of 1965-11-30} {
+ clock format -128949904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1965 12:34:56 die xxx mensis xi annoque mcmlxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2439095 11 xi 11 11/30/1965 die xxx mensis xi annoque mcmlxv 65 lxv 1965}
+test clock-2.863 {conversion of 1965-12-01} {
+ clock format -128863504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1965 12:34:56 die i mensis xii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2439096 12 xii 12 12/01/1965 die i mensis xii annoque mcmlxv 65 lxv 1965}
+test clock-2.864 {conversion of 1965-12-31} {
+ clock format -126271504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1965 12:34:56 die xxxi mensis xii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2439126 12 xii 12 12/31/1965 die xxxi mensis xii annoque mcmlxv 65 lxv 1965}
+test clock-2.865 {conversion of 1966-01-01} {
+ clock format -126185104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1966 12:34:56 die i mensis i annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2439127 01 i 1 01/01/1966 die i mensis i annoque mcmlxvi 66 lxvi 1966}
+test clock-2.866 {conversion of 1966-01-31} {
+ clock format -123593104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1966 12:34:56 die xxxi mensis i annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2439157 01 i 1 01/31/1966 die xxxi mensis i annoque mcmlxvi 66 lxvi 1966}
+test clock-2.867 {conversion of 1966-02-01} {
+ clock format -123506704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1966 12:34:56 die i mensis ii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2439158 02 ii 2 02/01/1966 die i mensis ii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.868 {conversion of 1966-02-28} {
+ clock format -121173904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1966 12:34:56 die xxviii mensis ii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2439185 02 ii 2 02/28/1966 die xxviii mensis ii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.869 {conversion of 1966-03-01} {
+ clock format -121087504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1966 12:34:56 die i mensis iii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2439186 03 iii 3 03/01/1966 die i mensis iii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.870 {conversion of 1966-03-31} {
+ clock format -118495504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1966 12:34:56 die xxxi mensis iii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2439216 03 iii 3 03/31/1966 die xxxi mensis iii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.871 {conversion of 1966-04-01} {
+ clock format -118409104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1966 12:34:56 die i mensis iv annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2439217 04 iv 4 04/01/1966 die i mensis iv annoque mcmlxvi 66 lxvi 1966}
+test clock-2.872 {conversion of 1966-04-30} {
+ clock format -115903504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1966 12:34:56 die xxx mensis iv annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2439246 04 iv 4 04/30/1966 die xxx mensis iv annoque mcmlxvi 66 lxvi 1966}
+test clock-2.873 {conversion of 1966-05-01} {
+ clock format -115817104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1966 12:34:56 die i mensis v annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2439247 05 v 5 05/01/1966 die i mensis v annoque mcmlxvi 66 lxvi 1966}
+test clock-2.874 {conversion of 1966-05-31} {
+ clock format -113225104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1966 12:34:56 die xxxi mensis v annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2439277 05 v 5 05/31/1966 die xxxi mensis v annoque mcmlxvi 66 lxvi 1966}
+test clock-2.875 {conversion of 1966-06-01} {
+ clock format -113138704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1966 12:34:56 die i mensis vi annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2439278 06 vi 6 06/01/1966 die i mensis vi annoque mcmlxvi 66 lxvi 1966}
+test clock-2.876 {conversion of 1966-06-30} {
+ clock format -110633104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1966 12:34:56 die xxx mensis vi annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2439307 06 vi 6 06/30/1966 die xxx mensis vi annoque mcmlxvi 66 lxvi 1966}
+test clock-2.877 {conversion of 1966-07-01} {
+ clock format -110546704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1966 12:34:56 die i mensis vii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2439308 07 vii 7 07/01/1966 die i mensis vii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.878 {conversion of 1966-07-31} {
+ clock format -107954704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1966 12:34:56 die xxxi mensis vii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2439338 07 vii 7 07/31/1966 die xxxi mensis vii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.879 {conversion of 1966-08-01} {
+ clock format -107868304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1966 12:34:56 die i mensis viii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2439339 08 viii 8 08/01/1966 die i mensis viii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.880 {conversion of 1966-08-31} {
+ clock format -105276304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1966 12:34:56 die xxxi mensis viii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2439369 08 viii 8 08/31/1966 die xxxi mensis viii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.881 {conversion of 1966-09-01} {
+ clock format -105189904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1966 12:34:56 die i mensis ix annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2439370 09 ix 9 09/01/1966 die i mensis ix annoque mcmlxvi 66 lxvi 1966}
+test clock-2.882 {conversion of 1966-09-30} {
+ clock format -102684304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1966 12:34:56 die xxx mensis ix annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2439399 09 ix 9 09/30/1966 die xxx mensis ix annoque mcmlxvi 66 lxvi 1966}
+test clock-2.883 {conversion of 1966-10-01} {
+ clock format -102597904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1966 12:34:56 die i mensis x annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2439400 10 x 10 10/01/1966 die i mensis x annoque mcmlxvi 66 lxvi 1966}
+test clock-2.884 {conversion of 1966-10-31} {
+ clock format -100005904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1966 12:34:56 die xxxi mensis x annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2439430 10 x 10 10/31/1966 die xxxi mensis x annoque mcmlxvi 66 lxvi 1966}
+test clock-2.885 {conversion of 1966-11-01} {
+ clock format -99919504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1966 12:34:56 die i mensis xi annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2439431 11 xi 11 11/01/1966 die i mensis xi annoque mcmlxvi 66 lxvi 1966}
+test clock-2.886 {conversion of 1966-11-30} {
+ clock format -97413904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1966 12:34:56 die xxx mensis xi annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2439460 11 xi 11 11/30/1966 die xxx mensis xi annoque mcmlxvi 66 lxvi 1966}
+test clock-2.887 {conversion of 1966-12-01} {
+ clock format -97327504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1966 12:34:56 die i mensis xii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2439461 12 xii 12 12/01/1966 die i mensis xii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.888 {conversion of 1966-12-31} {
+ clock format -94735504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1966 12:34:56 die xxxi mensis xii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2439491 12 xii 12 12/31/1966 die xxxi mensis xii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.889 {conversion of 1967-01-01} {
+ clock format -94649104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1967 12:34:56 die i mensis i annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2439492 01 i 1 01/01/1967 die i mensis i annoque mcmlxvii 67 lxvii 1967}
+test clock-2.890 {conversion of 1967-01-31} {
+ clock format -92057104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1967 12:34:56 die xxxi mensis i annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2439522 01 i 1 01/31/1967 die xxxi mensis i annoque mcmlxvii 67 lxvii 1967}
+test clock-2.891 {conversion of 1967-02-01} {
+ clock format -91970704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1967 12:34:56 die i mensis ii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2439523 02 ii 2 02/01/1967 die i mensis ii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.892 {conversion of 1967-02-28} {
+ clock format -89637904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1967 12:34:56 die xxviii mensis ii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2439550 02 ii 2 02/28/1967 die xxviii mensis ii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.893 {conversion of 1967-03-01} {
+ clock format -89551504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1967 12:34:56 die i mensis iii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2439551 03 iii 3 03/01/1967 die i mensis iii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.894 {conversion of 1967-03-31} {
+ clock format -86959504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1967 12:34:56 die xxxi mensis iii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2439581 03 iii 3 03/31/1967 die xxxi mensis iii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.895 {conversion of 1967-04-01} {
+ clock format -86873104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1967 12:34:56 die i mensis iv annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2439582 04 iv 4 04/01/1967 die i mensis iv annoque mcmlxvii 67 lxvii 1967}
+test clock-2.896 {conversion of 1967-04-30} {
+ clock format -84367504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1967 12:34:56 die xxx mensis iv annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2439611 04 iv 4 04/30/1967 die xxx mensis iv annoque mcmlxvii 67 lxvii 1967}
+test clock-2.897 {conversion of 1967-05-01} {
+ clock format -84281104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1967 12:34:56 die i mensis v annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2439612 05 v 5 05/01/1967 die i mensis v annoque mcmlxvii 67 lxvii 1967}
+test clock-2.898 {conversion of 1967-05-31} {
+ clock format -81689104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1967 12:34:56 die xxxi mensis v annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2439642 05 v 5 05/31/1967 die xxxi mensis v annoque mcmlxvii 67 lxvii 1967}
+test clock-2.899 {conversion of 1967-06-01} {
+ clock format -81602704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1967 12:34:56 die i mensis vi annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2439643 06 vi 6 06/01/1967 die i mensis vi annoque mcmlxvii 67 lxvii 1967}
+test clock-2.900 {conversion of 1967-06-30} {
+ clock format -79097104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1967 12:34:56 die xxx mensis vi annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2439672 06 vi 6 06/30/1967 die xxx mensis vi annoque mcmlxvii 67 lxvii 1967}
+test clock-2.901 {conversion of 1967-07-01} {
+ clock format -79010704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1967 12:34:56 die i mensis vii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2439673 07 vii 7 07/01/1967 die i mensis vii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.902 {conversion of 1967-07-31} {
+ clock format -76418704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1967 12:34:56 die xxxi mensis vii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2439703 07 vii 7 07/31/1967 die xxxi mensis vii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.903 {conversion of 1967-08-01} {
+ clock format -76332304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1967 12:34:56 die i mensis viii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2439704 08 viii 8 08/01/1967 die i mensis viii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.904 {conversion of 1967-08-31} {
+ clock format -73740304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1967 12:34:56 die xxxi mensis viii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2439734 08 viii 8 08/31/1967 die xxxi mensis viii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.905 {conversion of 1967-09-01} {
+ clock format -73653904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1967 12:34:56 die i mensis ix annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2439735 09 ix 9 09/01/1967 die i mensis ix annoque mcmlxvii 67 lxvii 1967}
+test clock-2.906 {conversion of 1967-09-30} {
+ clock format -71148304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1967 12:34:56 die xxx mensis ix annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2439764 09 ix 9 09/30/1967 die xxx mensis ix annoque mcmlxvii 67 lxvii 1967}
+test clock-2.907 {conversion of 1967-10-01} {
+ clock format -71061904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1967 12:34:56 die i mensis x annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2439765 10 x 10 10/01/1967 die i mensis x annoque mcmlxvii 67 lxvii 1967}
+test clock-2.908 {conversion of 1967-10-31} {
+ clock format -68469904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1967 12:34:56 die xxxi mensis x annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2439795 10 x 10 10/31/1967 die xxxi mensis x annoque mcmlxvii 67 lxvii 1967}
+test clock-2.909 {conversion of 1967-11-01} {
+ clock format -68383504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1967 12:34:56 die i mensis xi annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2439796 11 xi 11 11/01/1967 die i mensis xi annoque mcmlxvii 67 lxvii 1967}
+test clock-2.910 {conversion of 1967-11-30} {
+ clock format -65877904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1967 12:34:56 die xxx mensis xi annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2439825 11 xi 11 11/30/1967 die xxx mensis xi annoque mcmlxvii 67 lxvii 1967}
+test clock-2.911 {conversion of 1967-12-01} {
+ clock format -65791504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1967 12:34:56 die i mensis xii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2439826 12 xii 12 12/01/1967 die i mensis xii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.912 {conversion of 1967-12-31} {
+ clock format -63199504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1967 12:34:56 die xxxi mensis xii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2439856 12 xii 12 12/31/1967 die xxxi mensis xii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.913 {conversion of 1968-01-01} {
+ clock format -63113104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1968 12:34:56 die i mensis i annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2439857 01 i 1 01/01/1968 die i mensis i annoque mcmlxviii 68 lxviii 1968}
+test clock-2.914 {conversion of 1968-01-31} {
+ clock format -60521104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1968 12:34:56 die xxxi mensis i annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2439887 01 i 1 01/31/1968 die xxxi mensis i annoque mcmlxviii 68 lxviii 1968}
+test clock-2.915 {conversion of 1968-02-01} {
+ clock format -60434704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1968 12:34:56 die i mensis ii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2439888 02 ii 2 02/01/1968 die i mensis ii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.916 {conversion of 1968-02-29} {
+ clock format -58015504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1968 12:34:56 die xxix mensis ii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2439916 02 ii 2 02/29/1968 die xxix mensis ii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.917 {conversion of 1968-03-01} {
+ clock format -57929104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1968 12:34:56 die i mensis iii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2439917 03 iii 3 03/01/1968 die i mensis iii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.918 {conversion of 1968-03-31} {
+ clock format -55337104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1968 12:34:56 die xxxi mensis iii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2439947 03 iii 3 03/31/1968 die xxxi mensis iii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.919 {conversion of 1968-04-01} {
+ clock format -55250704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1968 12:34:56 die i mensis iv annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2439948 04 iv 4 04/01/1968 die i mensis iv annoque mcmlxviii 68 lxviii 1968}
+test clock-2.920 {conversion of 1968-04-30} {
+ clock format -52745104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1968 12:34:56 die xxx mensis iv annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2439977 04 iv 4 04/30/1968 die xxx mensis iv annoque mcmlxviii 68 lxviii 1968}
+test clock-2.921 {conversion of 1968-05-01} {
+ clock format -52658704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1968 12:34:56 die i mensis v annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2439978 05 v 5 05/01/1968 die i mensis v annoque mcmlxviii 68 lxviii 1968}
+test clock-2.922 {conversion of 1968-05-31} {
+ clock format -50066704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1968 12:34:56 die xxxi mensis v annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2440008 05 v 5 05/31/1968 die xxxi mensis v annoque mcmlxviii 68 lxviii 1968}
+test clock-2.923 {conversion of 1968-06-01} {
+ clock format -49980304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1968 12:34:56 die i mensis vi annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2440009 06 vi 6 06/01/1968 die i mensis vi annoque mcmlxviii 68 lxviii 1968}
+test clock-2.924 {conversion of 1968-06-30} {
+ clock format -47474704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1968 12:34:56 die xxx mensis vi annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2440038 06 vi 6 06/30/1968 die xxx mensis vi annoque mcmlxviii 68 lxviii 1968}
+test clock-2.925 {conversion of 1968-07-01} {
+ clock format -47388304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1968 12:34:56 die i mensis vii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2440039 07 vii 7 07/01/1968 die i mensis vii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.926 {conversion of 1968-07-31} {
+ clock format -44796304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1968 12:34:56 die xxxi mensis vii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2440069 07 vii 7 07/31/1968 die xxxi mensis vii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.927 {conversion of 1968-08-01} {
+ clock format -44709904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1968 12:34:56 die i mensis viii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2440070 08 viii 8 08/01/1968 die i mensis viii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.928 {conversion of 1968-08-31} {
+ clock format -42117904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1968 12:34:56 die xxxi mensis viii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2440100 08 viii 8 08/31/1968 die xxxi mensis viii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.929 {conversion of 1968-09-01} {
+ clock format -42031504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1968 12:34:56 die i mensis ix annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2440101 09 ix 9 09/01/1968 die i mensis ix annoque mcmlxviii 68 lxviii 1968}
+test clock-2.930 {conversion of 1968-09-30} {
+ clock format -39525904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1968 12:34:56 die xxx mensis ix annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2440130 09 ix 9 09/30/1968 die xxx mensis ix annoque mcmlxviii 68 lxviii 1968}
+test clock-2.931 {conversion of 1968-10-01} {
+ clock format -39439504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1968 12:34:56 die i mensis x annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2440131 10 x 10 10/01/1968 die i mensis x annoque mcmlxviii 68 lxviii 1968}
+test clock-2.932 {conversion of 1968-10-31} {
+ clock format -36847504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1968 12:34:56 die xxxi mensis x annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2440161 10 x 10 10/31/1968 die xxxi mensis x annoque mcmlxviii 68 lxviii 1968}
+test clock-2.933 {conversion of 1968-11-01} {
+ clock format -36761104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1968 12:34:56 die i mensis xi annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2440162 11 xi 11 11/01/1968 die i mensis xi annoque mcmlxviii 68 lxviii 1968}
+test clock-2.934 {conversion of 1968-11-30} {
+ clock format -34255504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1968 12:34:56 die xxx mensis xi annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2440191 11 xi 11 11/30/1968 die xxx mensis xi annoque mcmlxviii 68 lxviii 1968}
+test clock-2.935 {conversion of 1968-12-01} {
+ clock format -34169104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1968 12:34:56 die i mensis xii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2440192 12 xii 12 12/01/1968 die i mensis xii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.936 {conversion of 1968-12-31} {
+ clock format -31577104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1968 12:34:56 die xxxi mensis xii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2440222 12 xii 12 12/31/1968 die xxxi mensis xii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.937 {conversion of 1969-01-01} {
+ clock format -31490704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1969 12:34:56 die i mensis i annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2440223 01 i 1 01/01/1969 die i mensis i annoque mcmlxix 69 lxix 1969}
+test clock-2.938 {conversion of 1969-01-31} {
+ clock format -28898704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1969 12:34:56 die xxxi mensis i annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2440253 01 i 1 01/31/1969 die xxxi mensis i annoque mcmlxix 69 lxix 1969}
+test clock-2.939 {conversion of 1969-02-01} {
+ clock format -28812304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1969 12:34:56 die i mensis ii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2440254 02 ii 2 02/01/1969 die i mensis ii annoque mcmlxix 69 lxix 1969}
+test clock-2.940 {conversion of 1969-02-28} {
+ clock format -26479504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1969 12:34:56 die xxviii mensis ii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2440281 02 ii 2 02/28/1969 die xxviii mensis ii annoque mcmlxix 69 lxix 1969}
+test clock-2.941 {conversion of 1969-03-01} {
+ clock format -26393104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1969 12:34:56 die i mensis iii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2440282 03 iii 3 03/01/1969 die i mensis iii annoque mcmlxix 69 lxix 1969}
+test clock-2.942 {conversion of 1969-03-31} {
+ clock format -23801104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1969 12:34:56 die xxxi mensis iii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2440312 03 iii 3 03/31/1969 die xxxi mensis iii annoque mcmlxix 69 lxix 1969}
+test clock-2.943 {conversion of 1969-04-01} {
+ clock format -23714704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1969 12:34:56 die i mensis iv annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2440313 04 iv 4 04/01/1969 die i mensis iv annoque mcmlxix 69 lxix 1969}
+test clock-2.944 {conversion of 1969-04-30} {
+ clock format -21209104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1969 12:34:56 die xxx mensis iv annoque mcmlxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2440342 04 iv 4 04/30/1969 die xxx mensis iv annoque mcmlxix 69 lxix 1969}
+test clock-2.945 {conversion of 1969-05-01} {
+ clock format -21122704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1969 12:34:56 die i mensis v annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2440343 05 v 5 05/01/1969 die i mensis v annoque mcmlxix 69 lxix 1969}
+test clock-2.946 {conversion of 1969-05-31} {
+ clock format -18530704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1969 12:34:56 die xxxi mensis v annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2440373 05 v 5 05/31/1969 die xxxi mensis v annoque mcmlxix 69 lxix 1969}
+test clock-2.947 {conversion of 1969-06-01} {
+ clock format -18444304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1969 12:34:56 die i mensis vi annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2440374 06 vi 6 06/01/1969 die i mensis vi annoque mcmlxix 69 lxix 1969}
+test clock-2.948 {conversion of 1969-06-30} {
+ clock format -15938704 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1969 12:34:56 die xxx mensis vi annoque mcmlxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2440403 06 vi 6 06/30/1969 die xxx mensis vi annoque mcmlxix 69 lxix 1969}
+test clock-2.949 {conversion of 1969-07-01} {
+ clock format -15852304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1969 12:34:56 die i mensis vii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2440404 07 vii 7 07/01/1969 die i mensis vii annoque mcmlxix 69 lxix 1969}
+test clock-2.950 {conversion of 1969-07-31} {
+ clock format -13260304 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1969 12:34:56 die xxxi mensis vii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2440434 07 vii 7 07/31/1969 die xxxi mensis vii annoque mcmlxix 69 lxix 1969}
+test clock-2.951 {conversion of 1969-08-01} {
+ clock format -13173904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1969 12:34:56 die i mensis viii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2440435 08 viii 8 08/01/1969 die i mensis viii annoque mcmlxix 69 lxix 1969}
+test clock-2.952 {conversion of 1969-08-31} {
+ clock format -10581904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1969 12:34:56 die xxxi mensis viii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2440465 08 viii 8 08/31/1969 die xxxi mensis viii annoque mcmlxix 69 lxix 1969}
+test clock-2.953 {conversion of 1969-09-01} {
+ clock format -10495504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1969 12:34:56 die i mensis ix annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2440466 09 ix 9 09/01/1969 die i mensis ix annoque mcmlxix 69 lxix 1969}
+test clock-2.954 {conversion of 1969-09-30} {
+ clock format -7989904 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1969 12:34:56 die xxx mensis ix annoque mcmlxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2440495 09 ix 9 09/30/1969 die xxx mensis ix annoque mcmlxix 69 lxix 1969}
+test clock-2.955 {conversion of 1969-10-01} {
+ clock format -7903504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1969 12:34:56 die i mensis x annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2440496 10 x 10 10/01/1969 die i mensis x annoque mcmlxix 69 lxix 1969}
+test clock-2.956 {conversion of 1969-10-31} {
+ clock format -5311504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1969 12:34:56 die xxxi mensis x annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2440526 10 x 10 10/31/1969 die xxxi mensis x annoque mcmlxix 69 lxix 1969}
+test clock-2.957 {conversion of 1969-11-01} {
+ clock format -5225104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1969 12:34:56 die i mensis xi annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2440527 11 xi 11 11/01/1969 die i mensis xi annoque mcmlxix 69 lxix 1969}
+test clock-2.958 {conversion of 1969-11-30} {
+ clock format -2719504 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1969 12:34:56 die xxx mensis xi annoque mcmlxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2440556 11 xi 11 11/30/1969 die xxx mensis xi annoque mcmlxix 69 lxix 1969}
+test clock-2.959 {conversion of 1969-12-01} {
+ clock format -2633104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1969 12:34:56 die i mensis xii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2440557 12 xii 12 12/01/1969 die i mensis xii annoque mcmlxix 69 lxix 1969}
+test clock-2.960 {conversion of 1969-12-31} {
+ clock format -41104 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1969 12:34:56 die xxxi mensis xii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2440587 12 xii 12 12/31/1969 die xxxi mensis xii annoque mcmlxix 69 lxix 1969}
+test clock-2.961 {conversion of 1970-01-01} {
+ clock format 45296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1970 12:34:56 die i mensis i annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2440588 01 i 1 01/01/1970 die i mensis i annoque mcmlxx 70 lxx 1970}
+test clock-2.962 {conversion of 1970-01-31} {
+ clock format 2637296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1970 12:34:56 die xxxi mensis i annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2440618 01 i 1 01/31/1970 die xxxi mensis i annoque mcmlxx 70 lxx 1970}
+test clock-2.963 {conversion of 1970-02-01} {
+ clock format 2723696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1970 12:34:56 die i mensis ii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2440619 02 ii 2 02/01/1970 die i mensis ii annoque mcmlxx 70 lxx 1970}
+test clock-2.964 {conversion of 1970-02-28} {
+ clock format 5056496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1970 12:34:56 die xxviii mensis ii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2440646 02 ii 2 02/28/1970 die xxviii mensis ii annoque mcmlxx 70 lxx 1970}
+test clock-2.965 {conversion of 1970-03-01} {
+ clock format 5142896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1970 12:34:56 die i mensis iii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2440647 03 iii 3 03/01/1970 die i mensis iii annoque mcmlxx 70 lxx 1970}
+test clock-2.966 {conversion of 1970-03-31} {
+ clock format 7734896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1970 12:34:56 die xxxi mensis iii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2440677 03 iii 3 03/31/1970 die xxxi mensis iii annoque mcmlxx 70 lxx 1970}
+test clock-2.967 {conversion of 1970-04-01} {
+ clock format 7821296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1970 12:34:56 die i mensis iv annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2440678 04 iv 4 04/01/1970 die i mensis iv annoque mcmlxx 70 lxx 1970}
+test clock-2.968 {conversion of 1970-04-30} {
+ clock format 10326896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1970 12:34:56 die xxx mensis iv annoque mcmlxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2440707 04 iv 4 04/30/1970 die xxx mensis iv annoque mcmlxx 70 lxx 1970}
+test clock-2.969 {conversion of 1970-05-01} {
+ clock format 10413296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1970 12:34:56 die i mensis v annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2440708 05 v 5 05/01/1970 die i mensis v annoque mcmlxx 70 lxx 1970}
+test clock-2.970 {conversion of 1970-05-31} {
+ clock format 13005296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1970 12:34:56 die xxxi mensis v annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2440738 05 v 5 05/31/1970 die xxxi mensis v annoque mcmlxx 70 lxx 1970}
+test clock-2.971 {conversion of 1970-06-01} {
+ clock format 13091696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1970 12:34:56 die i mensis vi annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2440739 06 vi 6 06/01/1970 die i mensis vi annoque mcmlxx 70 lxx 1970}
+test clock-2.972 {conversion of 1970-06-30} {
+ clock format 15597296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1970 12:34:56 die xxx mensis vi annoque mcmlxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2440768 06 vi 6 06/30/1970 die xxx mensis vi annoque mcmlxx 70 lxx 1970}
+test clock-2.973 {conversion of 1970-07-01} {
+ clock format 15683696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1970 12:34:56 die i mensis vii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2440769 07 vii 7 07/01/1970 die i mensis vii annoque mcmlxx 70 lxx 1970}
+test clock-2.974 {conversion of 1970-07-31} {
+ clock format 18275696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1970 12:34:56 die xxxi mensis vii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2440799 07 vii 7 07/31/1970 die xxxi mensis vii annoque mcmlxx 70 lxx 1970}
+test clock-2.975 {conversion of 1970-08-01} {
+ clock format 18362096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1970 12:34:56 die i mensis viii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2440800 08 viii 8 08/01/1970 die i mensis viii annoque mcmlxx 70 lxx 1970}
+test clock-2.976 {conversion of 1970-08-31} {
+ clock format 20954096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1970 12:34:56 die xxxi mensis viii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2440830 08 viii 8 08/31/1970 die xxxi mensis viii annoque mcmlxx 70 lxx 1970}
+test clock-2.977 {conversion of 1970-09-01} {
+ clock format 21040496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1970 12:34:56 die i mensis ix annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2440831 09 ix 9 09/01/1970 die i mensis ix annoque mcmlxx 70 lxx 1970}
+test clock-2.978 {conversion of 1970-09-30} {
+ clock format 23546096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1970 12:34:56 die xxx mensis ix annoque mcmlxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2440860 09 ix 9 09/30/1970 die xxx mensis ix annoque mcmlxx 70 lxx 1970}
+test clock-2.979 {conversion of 1970-10-01} {
+ clock format 23632496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1970 12:34:56 die i mensis x annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2440861 10 x 10 10/01/1970 die i mensis x annoque mcmlxx 70 lxx 1970}
+test clock-2.980 {conversion of 1970-10-31} {
+ clock format 26224496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1970 12:34:56 die xxxi mensis x annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2440891 10 x 10 10/31/1970 die xxxi mensis x annoque mcmlxx 70 lxx 1970}
+test clock-2.981 {conversion of 1970-11-01} {
+ clock format 26310896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1970 12:34:56 die i mensis xi annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2440892 11 xi 11 11/01/1970 die i mensis xi annoque mcmlxx 70 lxx 1970}
+test clock-2.982 {conversion of 1970-11-30} {
+ clock format 28816496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1970 12:34:56 die xxx mensis xi annoque mcmlxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2440921 11 xi 11 11/30/1970 die xxx mensis xi annoque mcmlxx 70 lxx 1970}
+test clock-2.983 {conversion of 1970-12-01} {
+ clock format 28902896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1970 12:34:56 die i mensis xii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2440922 12 xii 12 12/01/1970 die i mensis xii annoque mcmlxx 70 lxx 1970}
+test clock-2.984 {conversion of 1970-12-31} {
+ clock format 31494896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1970 12:34:56 die xxxi mensis xii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2440952 12 xii 12 12/31/1970 die xxxi mensis xii annoque mcmlxx 70 lxx 1970}
+test clock-2.985 {conversion of 1971-01-01} {
+ clock format 31581296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1971 12:34:56 die i mensis i annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2440953 01 i 1 01/01/1971 die i mensis i annoque mcmlxxi 71 lxxi 1971}
+test clock-2.986 {conversion of 1971-01-31} {
+ clock format 34173296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1971 12:34:56 die xxxi mensis i annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2440983 01 i 1 01/31/1971 die xxxi mensis i annoque mcmlxxi 71 lxxi 1971}
+test clock-2.987 {conversion of 1971-02-01} {
+ clock format 34259696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1971 12:34:56 die i mensis ii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2440984 02 ii 2 02/01/1971 die i mensis ii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.988 {conversion of 1971-02-28} {
+ clock format 36592496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1971 12:34:56 die xxviii mensis ii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2441011 02 ii 2 02/28/1971 die xxviii mensis ii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.989 {conversion of 1971-03-01} {
+ clock format 36678896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1971 12:34:56 die i mensis iii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2441012 03 iii 3 03/01/1971 die i mensis iii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.990 {conversion of 1971-03-31} {
+ clock format 39270896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1971 12:34:56 die xxxi mensis iii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2441042 03 iii 3 03/31/1971 die xxxi mensis iii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.991 {conversion of 1971-04-01} {
+ clock format 39357296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1971 12:34:56 die i mensis iv annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2441043 04 iv 4 04/01/1971 die i mensis iv annoque mcmlxxi 71 lxxi 1971}
+test clock-2.992 {conversion of 1971-04-30} {
+ clock format 41862896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1971 12:34:56 die xxx mensis iv annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2441072 04 iv 4 04/30/1971 die xxx mensis iv annoque mcmlxxi 71 lxxi 1971}
+test clock-2.993 {conversion of 1971-05-01} {
+ clock format 41949296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1971 12:34:56 die i mensis v annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2441073 05 v 5 05/01/1971 die i mensis v annoque mcmlxxi 71 lxxi 1971}
+test clock-2.994 {conversion of 1971-05-31} {
+ clock format 44541296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1971 12:34:56 die xxxi mensis v annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2441103 05 v 5 05/31/1971 die xxxi mensis v annoque mcmlxxi 71 lxxi 1971}
+test clock-2.995 {conversion of 1971-06-01} {
+ clock format 44627696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1971 12:34:56 die i mensis vi annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2441104 06 vi 6 06/01/1971 die i mensis vi annoque mcmlxxi 71 lxxi 1971}
+test clock-2.996 {conversion of 1971-06-30} {
+ clock format 47133296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1971 12:34:56 die xxx mensis vi annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2441133 06 vi 6 06/30/1971 die xxx mensis vi annoque mcmlxxi 71 lxxi 1971}
+test clock-2.997 {conversion of 1971-07-01} {
+ clock format 47219696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1971 12:34:56 die i mensis vii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2441134 07 vii 7 07/01/1971 die i mensis vii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.998 {conversion of 1971-07-31} {
+ clock format 49811696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1971 12:34:56 die xxxi mensis vii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2441164 07 vii 7 07/31/1971 die xxxi mensis vii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.999 {conversion of 1971-08-01} {
+ clock format 49898096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1971 12:34:56 die i mensis viii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2441165 08 viii 8 08/01/1971 die i mensis viii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1000 {conversion of 1971-08-31} {
+ clock format 52490096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1971 12:34:56 die xxxi mensis viii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2441195 08 viii 8 08/31/1971 die xxxi mensis viii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1001 {conversion of 1971-09-01} {
+ clock format 52576496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1971 12:34:56 die i mensis ix annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2441196 09 ix 9 09/01/1971 die i mensis ix annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1002 {conversion of 1971-09-30} {
+ clock format 55082096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1971 12:34:56 die xxx mensis ix annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2441225 09 ix 9 09/30/1971 die xxx mensis ix annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1003 {conversion of 1971-10-01} {
+ clock format 55168496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1971 12:34:56 die i mensis x annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2441226 10 x 10 10/01/1971 die i mensis x annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1004 {conversion of 1971-10-31} {
+ clock format 57760496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1971 12:34:56 die xxxi mensis x annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2441256 10 x 10 10/31/1971 die xxxi mensis x annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1005 {conversion of 1971-11-01} {
+ clock format 57846896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1971 12:34:56 die i mensis xi annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2441257 11 xi 11 11/01/1971 die i mensis xi annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1006 {conversion of 1971-11-30} {
+ clock format 60352496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1971 12:34:56 die xxx mensis xi annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2441286 11 xi 11 11/30/1971 die xxx mensis xi annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1007 {conversion of 1971-12-01} {
+ clock format 60438896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1971 12:34:56 die i mensis xii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2441287 12 xii 12 12/01/1971 die i mensis xii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1008 {conversion of 1971-12-31} {
+ clock format 63030896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1971 12:34:56 die xxxi mensis xii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2441317 12 xii 12 12/31/1971 die xxxi mensis xii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1009 {conversion of 1972-01-01} {
+ clock format 63117296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1972 12:34:56 die i mensis i annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2441318 01 i 1 01/01/1972 die i mensis i annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1010 {conversion of 1972-01-31} {
+ clock format 65709296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1972 12:34:56 die xxxi mensis i annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2441348 01 i 1 01/31/1972 die xxxi mensis i annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1011 {conversion of 1972-02-01} {
+ clock format 65795696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1972 12:34:56 die i mensis ii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2441349 02 ii 2 02/01/1972 die i mensis ii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1012 {conversion of 1972-02-29} {
+ clock format 68214896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1972 12:34:56 die xxix mensis ii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2441377 02 ii 2 02/29/1972 die xxix mensis ii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1013 {conversion of 1972-03-01} {
+ clock format 68301296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1972 12:34:56 die i mensis iii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2441378 03 iii 3 03/01/1972 die i mensis iii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1014 {conversion of 1972-03-31} {
+ clock format 70893296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1972 12:34:56 die xxxi mensis iii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2441408 03 iii 3 03/31/1972 die xxxi mensis iii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1015 {conversion of 1972-04-01} {
+ clock format 70979696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1972 12:34:56 die i mensis iv annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2441409 04 iv 4 04/01/1972 die i mensis iv annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1016 {conversion of 1972-04-30} {
+ clock format 73485296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1972 12:34:56 die xxx mensis iv annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2441438 04 iv 4 04/30/1972 die xxx mensis iv annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1017 {conversion of 1972-05-01} {
+ clock format 73571696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1972 12:34:56 die i mensis v annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2441439 05 v 5 05/01/1972 die i mensis v annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1018 {conversion of 1972-05-31} {
+ clock format 76163696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1972 12:34:56 die xxxi mensis v annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2441469 05 v 5 05/31/1972 die xxxi mensis v annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1019 {conversion of 1972-06-01} {
+ clock format 76250096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1972 12:34:56 die i mensis vi annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2441470 06 vi 6 06/01/1972 die i mensis vi annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1020 {conversion of 1972-06-30} {
+ clock format 78755696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1972 12:34:56 die xxx mensis vi annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2441499 06 vi 6 06/30/1972 die xxx mensis vi annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1021 {conversion of 1972-07-01} {
+ clock format 78842096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1972 12:34:56 die i mensis vii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2441500 07 vii 7 07/01/1972 die i mensis vii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1022 {conversion of 1972-07-31} {
+ clock format 81434096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1972 12:34:56 die xxxi mensis vii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2441530 07 vii 7 07/31/1972 die xxxi mensis vii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1023 {conversion of 1972-08-01} {
+ clock format 81520496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1972 12:34:56 die i mensis viii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2441531 08 viii 8 08/01/1972 die i mensis viii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1024 {conversion of 1972-08-31} {
+ clock format 84112496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1972 12:34:56 die xxxi mensis viii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2441561 08 viii 8 08/31/1972 die xxxi mensis viii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1025 {conversion of 1972-09-01} {
+ clock format 84198896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1972 12:34:56 die i mensis ix annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2441562 09 ix 9 09/01/1972 die i mensis ix annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1026 {conversion of 1972-09-30} {
+ clock format 86704496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1972 12:34:56 die xxx mensis ix annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2441591 09 ix 9 09/30/1972 die xxx mensis ix annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1027 {conversion of 1972-10-01} {
+ clock format 86790896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1972 12:34:56 die i mensis x annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2441592 10 x 10 10/01/1972 die i mensis x annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1028 {conversion of 1972-10-31} {
+ clock format 89382896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1972 12:34:56 die xxxi mensis x annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2441622 10 x 10 10/31/1972 die xxxi mensis x annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1029 {conversion of 1972-11-01} {
+ clock format 89469296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1972 12:34:56 die i mensis xi annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2441623 11 xi 11 11/01/1972 die i mensis xi annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1030 {conversion of 1972-11-30} {
+ clock format 91974896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1972 12:34:56 die xxx mensis xi annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2441652 11 xi 11 11/30/1972 die xxx mensis xi annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1031 {conversion of 1972-12-01} {
+ clock format 92061296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1972 12:34:56 die i mensis xii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2441653 12 xii 12 12/01/1972 die i mensis xii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1032 {conversion of 1972-12-31} {
+ clock format 94653296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1972 12:34:56 die xxxi mensis xii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2441683 12 xii 12 12/31/1972 die xxxi mensis xii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1033 {conversion of 1973-01-01} {
+ clock format 94739696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1973 12:34:56 die i mensis i annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2441684 01 i 1 01/01/1973 die i mensis i annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1034 {conversion of 1973-01-31} {
+ clock format 97331696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1973 12:34:56 die xxxi mensis i annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2441714 01 i 1 01/31/1973 die xxxi mensis i annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1035 {conversion of 1973-02-01} {
+ clock format 97418096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1973 12:34:56 die i mensis ii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2441715 02 ii 2 02/01/1973 die i mensis ii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1036 {conversion of 1973-02-28} {
+ clock format 99750896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1973 12:34:56 die xxviii mensis ii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2441742 02 ii 2 02/28/1973 die xxviii mensis ii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1037 {conversion of 1973-03-01} {
+ clock format 99837296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1973 12:34:56 die i mensis iii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2441743 03 iii 3 03/01/1973 die i mensis iii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1038 {conversion of 1973-03-31} {
+ clock format 102429296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1973 12:34:56 die xxxi mensis iii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2441773 03 iii 3 03/31/1973 die xxxi mensis iii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1039 {conversion of 1973-04-01} {
+ clock format 102515696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1973 12:34:56 die i mensis iv annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2441774 04 iv 4 04/01/1973 die i mensis iv annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1040 {conversion of 1973-04-30} {
+ clock format 105021296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1973 12:34:56 die xxx mensis iv annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2441803 04 iv 4 04/30/1973 die xxx mensis iv annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1041 {conversion of 1973-05-01} {
+ clock format 105107696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1973 12:34:56 die i mensis v annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2441804 05 v 5 05/01/1973 die i mensis v annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1042 {conversion of 1973-05-31} {
+ clock format 107699696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1973 12:34:56 die xxxi mensis v annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2441834 05 v 5 05/31/1973 die xxxi mensis v annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1043 {conversion of 1973-06-01} {
+ clock format 107786096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1973 12:34:56 die i mensis vi annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2441835 06 vi 6 06/01/1973 die i mensis vi annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1044 {conversion of 1973-06-30} {
+ clock format 110291696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1973 12:34:56 die xxx mensis vi annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2441864 06 vi 6 06/30/1973 die xxx mensis vi annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1045 {conversion of 1973-07-01} {
+ clock format 110378096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1973 12:34:56 die i mensis vii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2441865 07 vii 7 07/01/1973 die i mensis vii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1046 {conversion of 1973-07-31} {
+ clock format 112970096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1973 12:34:56 die xxxi mensis vii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2441895 07 vii 7 07/31/1973 die xxxi mensis vii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1047 {conversion of 1973-08-01} {
+ clock format 113056496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1973 12:34:56 die i mensis viii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2441896 08 viii 8 08/01/1973 die i mensis viii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1048 {conversion of 1973-08-31} {
+ clock format 115648496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1973 12:34:56 die xxxi mensis viii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2441926 08 viii 8 08/31/1973 die xxxi mensis viii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1049 {conversion of 1973-09-01} {
+ clock format 115734896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1973 12:34:56 die i mensis ix annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2441927 09 ix 9 09/01/1973 die i mensis ix annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1050 {conversion of 1973-09-30} {
+ clock format 118240496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1973 12:34:56 die xxx mensis ix annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2441956 09 ix 9 09/30/1973 die xxx mensis ix annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1051 {conversion of 1973-10-01} {
+ clock format 118326896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1973 12:34:56 die i mensis x annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2441957 10 x 10 10/01/1973 die i mensis x annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1052 {conversion of 1973-10-31} {
+ clock format 120918896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1973 12:34:56 die xxxi mensis x annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2441987 10 x 10 10/31/1973 die xxxi mensis x annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1053 {conversion of 1973-11-01} {
+ clock format 121005296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1973 12:34:56 die i mensis xi annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2441988 11 xi 11 11/01/1973 die i mensis xi annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1054 {conversion of 1973-11-30} {
+ clock format 123510896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1973 12:34:56 die xxx mensis xi annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2442017 11 xi 11 11/30/1973 die xxx mensis xi annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1055 {conversion of 1973-12-01} {
+ clock format 123597296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1973 12:34:56 die i mensis xii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2442018 12 xii 12 12/01/1973 die i mensis xii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1056 {conversion of 1973-12-31} {
+ clock format 126189296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1973 12:34:56 die xxxi mensis xii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2442048 12 xii 12 12/31/1973 die xxxi mensis xii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1057 {conversion of 1974-01-01} {
+ clock format 126275696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1974 12:34:56 die i mensis i annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2442049 01 i 1 01/01/1974 die i mensis i annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1058 {conversion of 1974-01-31} {
+ clock format 128867696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1974 12:34:56 die xxxi mensis i annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2442079 01 i 1 01/31/1974 die xxxi mensis i annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1059 {conversion of 1974-02-01} {
+ clock format 128954096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1974 12:34:56 die i mensis ii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2442080 02 ii 2 02/01/1974 die i mensis ii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1060 {conversion of 1974-02-28} {
+ clock format 131286896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1974 12:34:56 die xxviii mensis ii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2442107 02 ii 2 02/28/1974 die xxviii mensis ii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1061 {conversion of 1974-03-01} {
+ clock format 131373296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1974 12:34:56 die i mensis iii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2442108 03 iii 3 03/01/1974 die i mensis iii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1062 {conversion of 1974-03-31} {
+ clock format 133965296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1974 12:34:56 die xxxi mensis iii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2442138 03 iii 3 03/31/1974 die xxxi mensis iii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1063 {conversion of 1974-04-01} {
+ clock format 134051696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1974 12:34:56 die i mensis iv annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2442139 04 iv 4 04/01/1974 die i mensis iv annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1064 {conversion of 1974-04-30} {
+ clock format 136557296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1974 12:34:56 die xxx mensis iv annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2442168 04 iv 4 04/30/1974 die xxx mensis iv annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1065 {conversion of 1974-05-01} {
+ clock format 136643696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1974 12:34:56 die i mensis v annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2442169 05 v 5 05/01/1974 die i mensis v annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1066 {conversion of 1974-05-31} {
+ clock format 139235696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1974 12:34:56 die xxxi mensis v annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2442199 05 v 5 05/31/1974 die xxxi mensis v annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1067 {conversion of 1974-06-01} {
+ clock format 139322096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1974 12:34:56 die i mensis vi annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2442200 06 vi 6 06/01/1974 die i mensis vi annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1068 {conversion of 1974-06-30} {
+ clock format 141827696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1974 12:34:56 die xxx mensis vi annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2442229 06 vi 6 06/30/1974 die xxx mensis vi annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1069 {conversion of 1974-07-01} {
+ clock format 141914096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1974 12:34:56 die i mensis vii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2442230 07 vii 7 07/01/1974 die i mensis vii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1070 {conversion of 1974-07-31} {
+ clock format 144506096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1974 12:34:56 die xxxi mensis vii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2442260 07 vii 7 07/31/1974 die xxxi mensis vii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1071 {conversion of 1974-08-01} {
+ clock format 144592496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1974 12:34:56 die i mensis viii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2442261 08 viii 8 08/01/1974 die i mensis viii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1072 {conversion of 1974-08-31} {
+ clock format 147184496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1974 12:34:56 die xxxi mensis viii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2442291 08 viii 8 08/31/1974 die xxxi mensis viii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1073 {conversion of 1974-09-01} {
+ clock format 147270896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1974 12:34:56 die i mensis ix annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2442292 09 ix 9 09/01/1974 die i mensis ix annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1074 {conversion of 1974-09-30} {
+ clock format 149776496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1974 12:34:56 die xxx mensis ix annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2442321 09 ix 9 09/30/1974 die xxx mensis ix annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1075 {conversion of 1974-10-01} {
+ clock format 149862896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1974 12:34:56 die i mensis x annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2442322 10 x 10 10/01/1974 die i mensis x annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1076 {conversion of 1974-10-31} {
+ clock format 152454896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1974 12:34:56 die xxxi mensis x annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2442352 10 x 10 10/31/1974 die xxxi mensis x annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1077 {conversion of 1974-11-01} {
+ clock format 152541296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1974 12:34:56 die i mensis xi annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2442353 11 xi 11 11/01/1974 die i mensis xi annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1078 {conversion of 1974-11-30} {
+ clock format 155046896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1974 12:34:56 die xxx mensis xi annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2442382 11 xi 11 11/30/1974 die xxx mensis xi annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1079 {conversion of 1974-12-01} {
+ clock format 155133296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1974 12:34:56 die i mensis xii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2442383 12 xii 12 12/01/1974 die i mensis xii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1080 {conversion of 1974-12-31} {
+ clock format 157725296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1974 12:34:56 die xxxi mensis xii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2442413 12 xii 12 12/31/1974 die xxxi mensis xii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1081 {conversion of 1975-01-01} {
+ clock format 157811696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1975 12:34:56 die i mensis i annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2442414 01 i 1 01/01/1975 die i mensis i annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1082 {conversion of 1975-01-31} {
+ clock format 160403696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1975 12:34:56 die xxxi mensis i annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2442444 01 i 1 01/31/1975 die xxxi mensis i annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1083 {conversion of 1975-02-01} {
+ clock format 160490096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1975 12:34:56 die i mensis ii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2442445 02 ii 2 02/01/1975 die i mensis ii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1084 {conversion of 1975-02-28} {
+ clock format 162822896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1975 12:34:56 die xxviii mensis ii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2442472 02 ii 2 02/28/1975 die xxviii mensis ii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1085 {conversion of 1975-03-01} {
+ clock format 162909296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1975 12:34:56 die i mensis iii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2442473 03 iii 3 03/01/1975 die i mensis iii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1086 {conversion of 1975-03-31} {
+ clock format 165501296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1975 12:34:56 die xxxi mensis iii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2442503 03 iii 3 03/31/1975 die xxxi mensis iii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1087 {conversion of 1975-04-01} {
+ clock format 165587696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1975 12:34:56 die i mensis iv annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2442504 04 iv 4 04/01/1975 die i mensis iv annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1088 {conversion of 1975-04-30} {
+ clock format 168093296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1975 12:34:56 die xxx mensis iv annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2442533 04 iv 4 04/30/1975 die xxx mensis iv annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1089 {conversion of 1975-05-01} {
+ clock format 168179696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1975 12:34:56 die i mensis v annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2442534 05 v 5 05/01/1975 die i mensis v annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1090 {conversion of 1975-05-31} {
+ clock format 170771696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1975 12:34:56 die xxxi mensis v annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2442564 05 v 5 05/31/1975 die xxxi mensis v annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1091 {conversion of 1975-06-01} {
+ clock format 170858096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1975 12:34:56 die i mensis vi annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2442565 06 vi 6 06/01/1975 die i mensis vi annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1092 {conversion of 1975-06-30} {
+ clock format 173363696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1975 12:34:56 die xxx mensis vi annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2442594 06 vi 6 06/30/1975 die xxx mensis vi annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1093 {conversion of 1975-07-01} {
+ clock format 173450096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1975 12:34:56 die i mensis vii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2442595 07 vii 7 07/01/1975 die i mensis vii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1094 {conversion of 1975-07-31} {
+ clock format 176042096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1975 12:34:56 die xxxi mensis vii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2442625 07 vii 7 07/31/1975 die xxxi mensis vii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1095 {conversion of 1975-08-01} {
+ clock format 176128496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1975 12:34:56 die i mensis viii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2442626 08 viii 8 08/01/1975 die i mensis viii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1096 {conversion of 1975-08-31} {
+ clock format 178720496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1975 12:34:56 die xxxi mensis viii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2442656 08 viii 8 08/31/1975 die xxxi mensis viii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1097 {conversion of 1975-09-01} {
+ clock format 178806896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1975 12:34:56 die i mensis ix annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2442657 09 ix 9 09/01/1975 die i mensis ix annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1098 {conversion of 1975-09-30} {
+ clock format 181312496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1975 12:34:56 die xxx mensis ix annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2442686 09 ix 9 09/30/1975 die xxx mensis ix annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1099 {conversion of 1975-10-01} {
+ clock format 181398896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1975 12:34:56 die i mensis x annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2442687 10 x 10 10/01/1975 die i mensis x annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1100 {conversion of 1975-10-31} {
+ clock format 183990896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1975 12:34:56 die xxxi mensis x annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2442717 10 x 10 10/31/1975 die xxxi mensis x annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1101 {conversion of 1975-11-01} {
+ clock format 184077296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1975 12:34:56 die i mensis xi annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2442718 11 xi 11 11/01/1975 die i mensis xi annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1102 {conversion of 1975-11-30} {
+ clock format 186582896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1975 12:34:56 die xxx mensis xi annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2442747 11 xi 11 11/30/1975 die xxx mensis xi annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1103 {conversion of 1975-12-01} {
+ clock format 186669296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1975 12:34:56 die i mensis xii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2442748 12 xii 12 12/01/1975 die i mensis xii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1104 {conversion of 1975-12-31} {
+ clock format 189261296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1975 12:34:56 die xxxi mensis xii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2442778 12 xii 12 12/31/1975 die xxxi mensis xii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1105 {conversion of 1976-01-01} {
+ clock format 189347696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1976 12:34:56 die i mensis i annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2442779 01 i 1 01/01/1976 die i mensis i annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1106 {conversion of 1976-01-31} {
+ clock format 191939696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1976 12:34:56 die xxxi mensis i annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2442809 01 i 1 01/31/1976 die xxxi mensis i annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1107 {conversion of 1976-02-01} {
+ clock format 192026096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1976 12:34:56 die i mensis ii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2442810 02 ii 2 02/01/1976 die i mensis ii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1108 {conversion of 1976-02-29} {
+ clock format 194445296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1976 12:34:56 die xxix mensis ii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2442838 02 ii 2 02/29/1976 die xxix mensis ii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1109 {conversion of 1976-03-01} {
+ clock format 194531696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1976 12:34:56 die i mensis iii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2442839 03 iii 3 03/01/1976 die i mensis iii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1110 {conversion of 1976-03-31} {
+ clock format 197123696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1976 12:34:56 die xxxi mensis iii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2442869 03 iii 3 03/31/1976 die xxxi mensis iii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1111 {conversion of 1976-04-01} {
+ clock format 197210096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1976 12:34:56 die i mensis iv annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2442870 04 iv 4 04/01/1976 die i mensis iv annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1112 {conversion of 1976-04-30} {
+ clock format 199715696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1976 12:34:56 die xxx mensis iv annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2442899 04 iv 4 04/30/1976 die xxx mensis iv annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1113 {conversion of 1976-05-01} {
+ clock format 199802096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1976 12:34:56 die i mensis v annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2442900 05 v 5 05/01/1976 die i mensis v annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1114 {conversion of 1976-05-31} {
+ clock format 202394096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1976 12:34:56 die xxxi mensis v annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2442930 05 v 5 05/31/1976 die xxxi mensis v annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1115 {conversion of 1976-06-01} {
+ clock format 202480496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1976 12:34:56 die i mensis vi annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2442931 06 vi 6 06/01/1976 die i mensis vi annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1116 {conversion of 1976-06-30} {
+ clock format 204986096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1976 12:34:56 die xxx mensis vi annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2442960 06 vi 6 06/30/1976 die xxx mensis vi annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1117 {conversion of 1976-07-01} {
+ clock format 205072496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1976 12:34:56 die i mensis vii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2442961 07 vii 7 07/01/1976 die i mensis vii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1118 {conversion of 1976-07-31} {
+ clock format 207664496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1976 12:34:56 die xxxi mensis vii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2442991 07 vii 7 07/31/1976 die xxxi mensis vii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1119 {conversion of 1976-08-01} {
+ clock format 207750896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1976 12:34:56 die i mensis viii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2442992 08 viii 8 08/01/1976 die i mensis viii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1120 {conversion of 1976-08-31} {
+ clock format 210342896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1976 12:34:56 die xxxi mensis viii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2443022 08 viii 8 08/31/1976 die xxxi mensis viii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1121 {conversion of 1976-09-01} {
+ clock format 210429296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1976 12:34:56 die i mensis ix annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2443023 09 ix 9 09/01/1976 die i mensis ix annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1122 {conversion of 1976-09-30} {
+ clock format 212934896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1976 12:34:56 die xxx mensis ix annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2443052 09 ix 9 09/30/1976 die xxx mensis ix annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1123 {conversion of 1976-10-01} {
+ clock format 213021296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1976 12:34:56 die i mensis x annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2443053 10 x 10 10/01/1976 die i mensis x annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1124 {conversion of 1976-10-31} {
+ clock format 215613296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1976 12:34:56 die xxxi mensis x annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2443083 10 x 10 10/31/1976 die xxxi mensis x annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1125 {conversion of 1976-11-01} {
+ clock format 215699696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1976 12:34:56 die i mensis xi annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2443084 11 xi 11 11/01/1976 die i mensis xi annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1126 {conversion of 1976-11-30} {
+ clock format 218205296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1976 12:34:56 die xxx mensis xi annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2443113 11 xi 11 11/30/1976 die xxx mensis xi annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1127 {conversion of 1976-12-01} {
+ clock format 218291696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1976 12:34:56 die i mensis xii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2443114 12 xii 12 12/01/1976 die i mensis xii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1128 {conversion of 1976-12-31} {
+ clock format 220883696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1976 12:34:56 die xxxi mensis xii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2443144 12 xii 12 12/31/1976 die xxxi mensis xii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1129 {conversion of 1977-01-01} {
+ clock format 220970096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1977 12:34:56 die i mensis i annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2443145 01 i 1 01/01/1977 die i mensis i annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1130 {conversion of 1977-01-31} {
+ clock format 223562096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1977 12:34:56 die xxxi mensis i annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2443175 01 i 1 01/31/1977 die xxxi mensis i annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1131 {conversion of 1977-02-01} {
+ clock format 223648496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1977 12:34:56 die i mensis ii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2443176 02 ii 2 02/01/1977 die i mensis ii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1132 {conversion of 1977-02-28} {
+ clock format 225981296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1977 12:34:56 die xxviii mensis ii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2443203 02 ii 2 02/28/1977 die xxviii mensis ii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1133 {conversion of 1977-03-01} {
+ clock format 226067696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1977 12:34:56 die i mensis iii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2443204 03 iii 3 03/01/1977 die i mensis iii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1134 {conversion of 1977-03-31} {
+ clock format 228659696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1977 12:34:56 die xxxi mensis iii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2443234 03 iii 3 03/31/1977 die xxxi mensis iii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1135 {conversion of 1977-04-01} {
+ clock format 228746096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1977 12:34:56 die i mensis iv annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2443235 04 iv 4 04/01/1977 die i mensis iv annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1136 {conversion of 1977-04-30} {
+ clock format 231251696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1977 12:34:56 die xxx mensis iv annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2443264 04 iv 4 04/30/1977 die xxx mensis iv annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1137 {conversion of 1977-05-01} {
+ clock format 231338096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1977 12:34:56 die i mensis v annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2443265 05 v 5 05/01/1977 die i mensis v annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1138 {conversion of 1977-05-31} {
+ clock format 233930096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1977 12:34:56 die xxxi mensis v annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2443295 05 v 5 05/31/1977 die xxxi mensis v annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1139 {conversion of 1977-06-01} {
+ clock format 234016496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1977 12:34:56 die i mensis vi annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2443296 06 vi 6 06/01/1977 die i mensis vi annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1140 {conversion of 1977-06-30} {
+ clock format 236522096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1977 12:34:56 die xxx mensis vi annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2443325 06 vi 6 06/30/1977 die xxx mensis vi annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1141 {conversion of 1977-07-01} {
+ clock format 236608496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1977 12:34:56 die i mensis vii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2443326 07 vii 7 07/01/1977 die i mensis vii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1142 {conversion of 1977-07-31} {
+ clock format 239200496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1977 12:34:56 die xxxi mensis vii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2443356 07 vii 7 07/31/1977 die xxxi mensis vii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1143 {conversion of 1977-08-01} {
+ clock format 239286896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1977 12:34:56 die i mensis viii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2443357 08 viii 8 08/01/1977 die i mensis viii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1144 {conversion of 1977-08-31} {
+ clock format 241878896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1977 12:34:56 die xxxi mensis viii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2443387 08 viii 8 08/31/1977 die xxxi mensis viii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1145 {conversion of 1977-09-01} {
+ clock format 241965296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1977 12:34:56 die i mensis ix annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2443388 09 ix 9 09/01/1977 die i mensis ix annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1146 {conversion of 1977-09-30} {
+ clock format 244470896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1977 12:34:56 die xxx mensis ix annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2443417 09 ix 9 09/30/1977 die xxx mensis ix annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1147 {conversion of 1977-10-01} {
+ clock format 244557296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1977 12:34:56 die i mensis x annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2443418 10 x 10 10/01/1977 die i mensis x annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1148 {conversion of 1977-10-31} {
+ clock format 247149296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1977 12:34:56 die xxxi mensis x annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2443448 10 x 10 10/31/1977 die xxxi mensis x annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1149 {conversion of 1977-11-01} {
+ clock format 247235696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1977 12:34:56 die i mensis xi annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2443449 11 xi 11 11/01/1977 die i mensis xi annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1150 {conversion of 1977-11-30} {
+ clock format 249741296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1977 12:34:56 die xxx mensis xi annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2443478 11 xi 11 11/30/1977 die xxx mensis xi annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1151 {conversion of 1977-12-01} {
+ clock format 249827696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1977 12:34:56 die i mensis xii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2443479 12 xii 12 12/01/1977 die i mensis xii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1152 {conversion of 1977-12-31} {
+ clock format 252419696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1977 12:34:56 die xxxi mensis xii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2443509 12 xii 12 12/31/1977 die xxxi mensis xii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1153 {conversion of 1978-01-01} {
+ clock format 252506096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1978 12:34:56 die i mensis i annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2443510 01 i 1 01/01/1978 die i mensis i annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1154 {conversion of 1978-01-31} {
+ clock format 255098096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1978 12:34:56 die xxxi mensis i annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2443540 01 i 1 01/31/1978 die xxxi mensis i annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1155 {conversion of 1978-02-01} {
+ clock format 255184496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1978 12:34:56 die i mensis ii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2443541 02 ii 2 02/01/1978 die i mensis ii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1156 {conversion of 1978-02-28} {
+ clock format 257517296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1978 12:34:56 die xxviii mensis ii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2443568 02 ii 2 02/28/1978 die xxviii mensis ii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1157 {conversion of 1978-03-01} {
+ clock format 257603696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1978 12:34:56 die i mensis iii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2443569 03 iii 3 03/01/1978 die i mensis iii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1158 {conversion of 1978-03-31} {
+ clock format 260195696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1978 12:34:56 die xxxi mensis iii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2443599 03 iii 3 03/31/1978 die xxxi mensis iii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1159 {conversion of 1978-04-01} {
+ clock format 260282096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1978 12:34:56 die i mensis iv annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2443600 04 iv 4 04/01/1978 die i mensis iv annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1160 {conversion of 1978-04-30} {
+ clock format 262787696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1978 12:34:56 die xxx mensis iv annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2443629 04 iv 4 04/30/1978 die xxx mensis iv annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1161 {conversion of 1978-05-01} {
+ clock format 262874096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1978 12:34:56 die i mensis v annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2443630 05 v 5 05/01/1978 die i mensis v annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1162 {conversion of 1978-05-31} {
+ clock format 265466096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1978 12:34:56 die xxxi mensis v annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2443660 05 v 5 05/31/1978 die xxxi mensis v annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1163 {conversion of 1978-06-01} {
+ clock format 265552496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1978 12:34:56 die i mensis vi annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2443661 06 vi 6 06/01/1978 die i mensis vi annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1164 {conversion of 1978-06-30} {
+ clock format 268058096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1978 12:34:56 die xxx mensis vi annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2443690 06 vi 6 06/30/1978 die xxx mensis vi annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1165 {conversion of 1978-07-01} {
+ clock format 268144496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1978 12:34:56 die i mensis vii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2443691 07 vii 7 07/01/1978 die i mensis vii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1166 {conversion of 1978-07-31} {
+ clock format 270736496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1978 12:34:56 die xxxi mensis vii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2443721 07 vii 7 07/31/1978 die xxxi mensis vii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1167 {conversion of 1978-08-01} {
+ clock format 270822896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1978 12:34:56 die i mensis viii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2443722 08 viii 8 08/01/1978 die i mensis viii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1168 {conversion of 1978-08-31} {
+ clock format 273414896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1978 12:34:56 die xxxi mensis viii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2443752 08 viii 8 08/31/1978 die xxxi mensis viii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1169 {conversion of 1978-09-01} {
+ clock format 273501296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1978 12:34:56 die i mensis ix annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2443753 09 ix 9 09/01/1978 die i mensis ix annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1170 {conversion of 1978-09-30} {
+ clock format 276006896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1978 12:34:56 die xxx mensis ix annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2443782 09 ix 9 09/30/1978 die xxx mensis ix annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1171 {conversion of 1978-10-01} {
+ clock format 276093296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1978 12:34:56 die i mensis x annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2443783 10 x 10 10/01/1978 die i mensis x annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1172 {conversion of 1978-10-31} {
+ clock format 278685296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1978 12:34:56 die xxxi mensis x annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2443813 10 x 10 10/31/1978 die xxxi mensis x annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1173 {conversion of 1978-11-01} {
+ clock format 278771696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1978 12:34:56 die i mensis xi annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2443814 11 xi 11 11/01/1978 die i mensis xi annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1174 {conversion of 1978-11-30} {
+ clock format 281277296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1978 12:34:56 die xxx mensis xi annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2443843 11 xi 11 11/30/1978 die xxx mensis xi annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1175 {conversion of 1978-12-01} {
+ clock format 281363696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1978 12:34:56 die i mensis xii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2443844 12 xii 12 12/01/1978 die i mensis xii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1176 {conversion of 1978-12-31} {
+ clock format 283955696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1978 12:34:56 die xxxi mensis xii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2443874 12 xii 12 12/31/1978 die xxxi mensis xii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1177 {conversion of 1979-01-01} {
+ clock format 284042096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1979 12:34:56 die i mensis i annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2443875 01 i 1 01/01/1979 die i mensis i annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1178 {conversion of 1979-01-31} {
+ clock format 286634096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1979 12:34:56 die xxxi mensis i annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2443905 01 i 1 01/31/1979 die xxxi mensis i annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1179 {conversion of 1979-02-01} {
+ clock format 286720496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1979 12:34:56 die i mensis ii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2443906 02 ii 2 02/01/1979 die i mensis ii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1180 {conversion of 1979-02-28} {
+ clock format 289053296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1979 12:34:56 die xxviii mensis ii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2443933 02 ii 2 02/28/1979 die xxviii mensis ii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1181 {conversion of 1979-03-01} {
+ clock format 289139696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1979 12:34:56 die i mensis iii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2443934 03 iii 3 03/01/1979 die i mensis iii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1182 {conversion of 1979-03-31} {
+ clock format 291731696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1979 12:34:56 die xxxi mensis iii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2443964 03 iii 3 03/31/1979 die xxxi mensis iii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1183 {conversion of 1979-04-01} {
+ clock format 291818096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1979 12:34:56 die i mensis iv annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2443965 04 iv 4 04/01/1979 die i mensis iv annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1184 {conversion of 1979-04-30} {
+ clock format 294323696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1979 12:34:56 die xxx mensis iv annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2443994 04 iv 4 04/30/1979 die xxx mensis iv annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1185 {conversion of 1979-05-01} {
+ clock format 294410096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1979 12:34:56 die i mensis v annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2443995 05 v 5 05/01/1979 die i mensis v annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1186 {conversion of 1979-05-31} {
+ clock format 297002096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1979 12:34:56 die xxxi mensis v annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2444025 05 v 5 05/31/1979 die xxxi mensis v annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1187 {conversion of 1979-06-01} {
+ clock format 297088496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1979 12:34:56 die i mensis vi annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2444026 06 vi 6 06/01/1979 die i mensis vi annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1188 {conversion of 1979-06-30} {
+ clock format 299594096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1979 12:34:56 die xxx mensis vi annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2444055 06 vi 6 06/30/1979 die xxx mensis vi annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1189 {conversion of 1979-07-01} {
+ clock format 299680496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1979 12:34:56 die i mensis vii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2444056 07 vii 7 07/01/1979 die i mensis vii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1190 {conversion of 1979-07-31} {
+ clock format 302272496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1979 12:34:56 die xxxi mensis vii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2444086 07 vii 7 07/31/1979 die xxxi mensis vii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1191 {conversion of 1979-08-01} {
+ clock format 302358896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1979 12:34:56 die i mensis viii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2444087 08 viii 8 08/01/1979 die i mensis viii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1192 {conversion of 1979-08-31} {
+ clock format 304950896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1979 12:34:56 die xxxi mensis viii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2444117 08 viii 8 08/31/1979 die xxxi mensis viii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1193 {conversion of 1979-09-01} {
+ clock format 305037296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1979 12:34:56 die i mensis ix annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2444118 09 ix 9 09/01/1979 die i mensis ix annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1194 {conversion of 1979-09-30} {
+ clock format 307542896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1979 12:34:56 die xxx mensis ix annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2444147 09 ix 9 09/30/1979 die xxx mensis ix annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1195 {conversion of 1979-10-01} {
+ clock format 307629296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1979 12:34:56 die i mensis x annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2444148 10 x 10 10/01/1979 die i mensis x annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1196 {conversion of 1979-10-31} {
+ clock format 310221296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1979 12:34:56 die xxxi mensis x annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2444178 10 x 10 10/31/1979 die xxxi mensis x annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1197 {conversion of 1979-11-01} {
+ clock format 310307696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1979 12:34:56 die i mensis xi annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2444179 11 xi 11 11/01/1979 die i mensis xi annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1198 {conversion of 1979-11-30} {
+ clock format 312813296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1979 12:34:56 die xxx mensis xi annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2444208 11 xi 11 11/30/1979 die xxx mensis xi annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1199 {conversion of 1979-12-01} {
+ clock format 312899696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1979 12:34:56 die i mensis xii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2444209 12 xii 12 12/01/1979 die i mensis xii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1200 {conversion of 1979-12-31} {
+ clock format 315491696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1979 12:34:56 die xxxi mensis xii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2444239 12 xii 12 12/31/1979 die xxxi mensis xii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1201 {conversion of 1980-01-01} {
+ clock format 315578096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1980 12:34:56 die i mensis i annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2444240 01 i 1 01/01/1980 die i mensis i annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1202 {conversion of 1980-01-31} {
+ clock format 318170096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1980 12:34:56 die xxxi mensis i annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2444270 01 i 1 01/31/1980 die xxxi mensis i annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1203 {conversion of 1980-02-01} {
+ clock format 318256496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1980 12:34:56 die i mensis ii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2444271 02 ii 2 02/01/1980 die i mensis ii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1204 {conversion of 1980-02-29} {
+ clock format 320675696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1980 12:34:56 die xxix mensis ii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2444299 02 ii 2 02/29/1980 die xxix mensis ii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1205 {conversion of 1980-03-01} {
+ clock format 320762096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1980 12:34:56 die i mensis iii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2444300 03 iii 3 03/01/1980 die i mensis iii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1206 {conversion of 1980-03-31} {
+ clock format 323354096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1980 12:34:56 die xxxi mensis iii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2444330 03 iii 3 03/31/1980 die xxxi mensis iii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1207 {conversion of 1980-04-01} {
+ clock format 323440496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1980 12:34:56 die i mensis iv annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2444331 04 iv 4 04/01/1980 die i mensis iv annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1208 {conversion of 1980-04-30} {
+ clock format 325946096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1980 12:34:56 die xxx mensis iv annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2444360 04 iv 4 04/30/1980 die xxx mensis iv annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1209 {conversion of 1980-05-01} {
+ clock format 326032496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1980 12:34:56 die i mensis v annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2444361 05 v 5 05/01/1980 die i mensis v annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1210 {conversion of 1980-05-31} {
+ clock format 328624496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1980 12:34:56 die xxxi mensis v annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2444391 05 v 5 05/31/1980 die xxxi mensis v annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1211 {conversion of 1980-06-01} {
+ clock format 328710896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1980 12:34:56 die i mensis vi annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2444392 06 vi 6 06/01/1980 die i mensis vi annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1212 {conversion of 1980-06-30} {
+ clock format 331216496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1980 12:34:56 die xxx mensis vi annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2444421 06 vi 6 06/30/1980 die xxx mensis vi annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1213 {conversion of 1980-07-01} {
+ clock format 331302896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1980 12:34:56 die i mensis vii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2444422 07 vii 7 07/01/1980 die i mensis vii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1214 {conversion of 1980-07-31} {
+ clock format 333894896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1980 12:34:56 die xxxi mensis vii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2444452 07 vii 7 07/31/1980 die xxxi mensis vii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1215 {conversion of 1980-08-01} {
+ clock format 333981296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1980 12:34:56 die i mensis viii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2444453 08 viii 8 08/01/1980 die i mensis viii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1216 {conversion of 1980-08-31} {
+ clock format 336573296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1980 12:34:56 die xxxi mensis viii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2444483 08 viii 8 08/31/1980 die xxxi mensis viii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1217 {conversion of 1980-09-01} {
+ clock format 336659696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1980 12:34:56 die i mensis ix annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2444484 09 ix 9 09/01/1980 die i mensis ix annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1218 {conversion of 1980-09-30} {
+ clock format 339165296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1980 12:34:56 die xxx mensis ix annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2444513 09 ix 9 09/30/1980 die xxx mensis ix annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1219 {conversion of 1980-10-01} {
+ clock format 339251696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1980 12:34:56 die i mensis x annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2444514 10 x 10 10/01/1980 die i mensis x annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1220 {conversion of 1980-10-31} {
+ clock format 341843696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1980 12:34:56 die xxxi mensis x annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2444544 10 x 10 10/31/1980 die xxxi mensis x annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1221 {conversion of 1980-11-01} {
+ clock format 341930096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1980 12:34:56 die i mensis xi annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2444545 11 xi 11 11/01/1980 die i mensis xi annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1222 {conversion of 1980-11-30} {
+ clock format 344435696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1980 12:34:56 die xxx mensis xi annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2444574 11 xi 11 11/30/1980 die xxx mensis xi annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1223 {conversion of 1980-12-01} {
+ clock format 344522096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1980 12:34:56 die i mensis xii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2444575 12 xii 12 12/01/1980 die i mensis xii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1224 {conversion of 1980-12-31} {
+ clock format 347114096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1980 12:34:56 die xxxi mensis xii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2444605 12 xii 12 12/31/1980 die xxxi mensis xii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1225 {conversion of 1981-01-01} {
+ clock format 347200496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1981 12:34:56 die i mensis i annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2444606 01 i 1 01/01/1981 die i mensis i annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1226 {conversion of 1981-01-31} {
+ clock format 349792496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1981 12:34:56 die xxxi mensis i annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2444636 01 i 1 01/31/1981 die xxxi mensis i annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1227 {conversion of 1981-02-01} {
+ clock format 349878896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1981 12:34:56 die i mensis ii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2444637 02 ii 2 02/01/1981 die i mensis ii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1228 {conversion of 1981-02-28} {
+ clock format 352211696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1981 12:34:56 die xxviii mensis ii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2444664 02 ii 2 02/28/1981 die xxviii mensis ii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1229 {conversion of 1981-03-01} {
+ clock format 352298096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1981 12:34:56 die i mensis iii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2444665 03 iii 3 03/01/1981 die i mensis iii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1230 {conversion of 1981-03-31} {
+ clock format 354890096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1981 12:34:56 die xxxi mensis iii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2444695 03 iii 3 03/31/1981 die xxxi mensis iii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1231 {conversion of 1981-04-01} {
+ clock format 354976496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1981 12:34:56 die i mensis iv annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2444696 04 iv 4 04/01/1981 die i mensis iv annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1232 {conversion of 1981-04-30} {
+ clock format 357482096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1981 12:34:56 die xxx mensis iv annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2444725 04 iv 4 04/30/1981 die xxx mensis iv annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1233 {conversion of 1981-05-01} {
+ clock format 357568496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1981 12:34:56 die i mensis v annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2444726 05 v 5 05/01/1981 die i mensis v annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1234 {conversion of 1981-05-31} {
+ clock format 360160496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1981 12:34:56 die xxxi mensis v annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2444756 05 v 5 05/31/1981 die xxxi mensis v annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1235 {conversion of 1981-06-01} {
+ clock format 360246896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1981 12:34:56 die i mensis vi annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2444757 06 vi 6 06/01/1981 die i mensis vi annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1236 {conversion of 1981-06-30} {
+ clock format 362752496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1981 12:34:56 die xxx mensis vi annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2444786 06 vi 6 06/30/1981 die xxx mensis vi annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1237 {conversion of 1981-07-01} {
+ clock format 362838896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1981 12:34:56 die i mensis vii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2444787 07 vii 7 07/01/1981 die i mensis vii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1238 {conversion of 1981-07-31} {
+ clock format 365430896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1981 12:34:56 die xxxi mensis vii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2444817 07 vii 7 07/31/1981 die xxxi mensis vii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1239 {conversion of 1981-08-01} {
+ clock format 365517296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1981 12:34:56 die i mensis viii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2444818 08 viii 8 08/01/1981 die i mensis viii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1240 {conversion of 1981-08-31} {
+ clock format 368109296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1981 12:34:56 die xxxi mensis viii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2444848 08 viii 8 08/31/1981 die xxxi mensis viii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1241 {conversion of 1981-09-01} {
+ clock format 368195696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1981 12:34:56 die i mensis ix annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2444849 09 ix 9 09/01/1981 die i mensis ix annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1242 {conversion of 1981-09-30} {
+ clock format 370701296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1981 12:34:56 die xxx mensis ix annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2444878 09 ix 9 09/30/1981 die xxx mensis ix annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1243 {conversion of 1981-10-01} {
+ clock format 370787696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1981 12:34:56 die i mensis x annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2444879 10 x 10 10/01/1981 die i mensis x annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1244 {conversion of 1981-10-31} {
+ clock format 373379696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1981 12:34:56 die xxxi mensis x annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2444909 10 x 10 10/31/1981 die xxxi mensis x annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1245 {conversion of 1981-11-01} {
+ clock format 373466096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1981 12:34:56 die i mensis xi annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2444910 11 xi 11 11/01/1981 die i mensis xi annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1246 {conversion of 1981-11-30} {
+ clock format 375971696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1981 12:34:56 die xxx mensis xi annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2444939 11 xi 11 11/30/1981 die xxx mensis xi annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1247 {conversion of 1981-12-01} {
+ clock format 376058096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1981 12:34:56 die i mensis xii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2444940 12 xii 12 12/01/1981 die i mensis xii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1248 {conversion of 1981-12-31} {
+ clock format 378650096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1981 12:34:56 die xxxi mensis xii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2444970 12 xii 12 12/31/1981 die xxxi mensis xii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1249 {conversion of 1984-01-01} {
+ clock format 441808496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1984 12:34:56 die i mensis i annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2445701 01 i 1 01/01/1984 die i mensis i annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1250 {conversion of 1984-01-31} {
+ clock format 444400496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1984 12:34:56 die xxxi mensis i annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2445731 01 i 1 01/31/1984 die xxxi mensis i annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1251 {conversion of 1984-02-01} {
+ clock format 444486896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1984 12:34:56 die i mensis ii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2445732 02 ii 2 02/01/1984 die i mensis ii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1252 {conversion of 1984-02-29} {
+ clock format 446906096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1984 12:34:56 die xxix mensis ii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2445760 02 ii 2 02/29/1984 die xxix mensis ii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1253 {conversion of 1984-03-01} {
+ clock format 446992496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1984 12:34:56 die i mensis iii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2445761 03 iii 3 03/01/1984 die i mensis iii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1254 {conversion of 1984-03-31} {
+ clock format 449584496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1984 12:34:56 die xxxi mensis iii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2445791 03 iii 3 03/31/1984 die xxxi mensis iii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1255 {conversion of 1984-04-01} {
+ clock format 449670896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1984 12:34:56 die i mensis iv annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2445792 04 iv 4 04/01/1984 die i mensis iv annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1256 {conversion of 1984-04-30} {
+ clock format 452176496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1984 12:34:56 die xxx mensis iv annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2445821 04 iv 4 04/30/1984 die xxx mensis iv annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1257 {conversion of 1984-05-01} {
+ clock format 452262896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1984 12:34:56 die i mensis v annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2445822 05 v 5 05/01/1984 die i mensis v annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1258 {conversion of 1984-05-31} {
+ clock format 454854896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1984 12:34:56 die xxxi mensis v annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2445852 05 v 5 05/31/1984 die xxxi mensis v annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1259 {conversion of 1984-06-01} {
+ clock format 454941296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1984 12:34:56 die i mensis vi annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2445853 06 vi 6 06/01/1984 die i mensis vi annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1260 {conversion of 1984-06-30} {
+ clock format 457446896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1984 12:34:56 die xxx mensis vi annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2445882 06 vi 6 06/30/1984 die xxx mensis vi annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1261 {conversion of 1984-07-01} {
+ clock format 457533296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1984 12:34:56 die i mensis vii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2445883 07 vii 7 07/01/1984 die i mensis vii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1262 {conversion of 1984-07-31} {
+ clock format 460125296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1984 12:34:56 die xxxi mensis vii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2445913 07 vii 7 07/31/1984 die xxxi mensis vii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1263 {conversion of 1984-08-01} {
+ clock format 460211696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1984 12:34:56 die i mensis viii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2445914 08 viii 8 08/01/1984 die i mensis viii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1264 {conversion of 1984-08-31} {
+ clock format 462803696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1984 12:34:56 die xxxi mensis viii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2445944 08 viii 8 08/31/1984 die xxxi mensis viii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1265 {conversion of 1984-09-01} {
+ clock format 462890096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1984 12:34:56 die i mensis ix annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2445945 09 ix 9 09/01/1984 die i mensis ix annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1266 {conversion of 1984-09-30} {
+ clock format 465395696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1984 12:34:56 die xxx mensis ix annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2445974 09 ix 9 09/30/1984 die xxx mensis ix annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1267 {conversion of 1984-10-01} {
+ clock format 465482096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1984 12:34:56 die i mensis x annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2445975 10 x 10 10/01/1984 die i mensis x annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1268 {conversion of 1984-10-31} {
+ clock format 468074096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1984 12:34:56 die xxxi mensis x annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2446005 10 x 10 10/31/1984 die xxxi mensis x annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1269 {conversion of 1984-11-01} {
+ clock format 468160496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1984 12:34:56 die i mensis xi annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2446006 11 xi 11 11/01/1984 die i mensis xi annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1270 {conversion of 1984-11-30} {
+ clock format 470666096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1984 12:34:56 die xxx mensis xi annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2446035 11 xi 11 11/30/1984 die xxx mensis xi annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1271 {conversion of 1984-12-01} {
+ clock format 470752496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1984 12:34:56 die i mensis xii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2446036 12 xii 12 12/01/1984 die i mensis xii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1272 {conversion of 1984-12-31} {
+ clock format 473344496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1984 12:34:56 die xxxi mensis xii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2446066 12 xii 12 12/31/1984 die xxxi mensis xii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1273 {conversion of 1985-01-01} {
+ clock format 473430896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1985 12:34:56 die i mensis i annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2446067 01 i 1 01/01/1985 die i mensis i annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1274 {conversion of 1985-01-31} {
+ clock format 476022896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1985 12:34:56 die xxxi mensis i annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2446097 01 i 1 01/31/1985 die xxxi mensis i annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1275 {conversion of 1985-02-01} {
+ clock format 476109296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1985 12:34:56 die i mensis ii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2446098 02 ii 2 02/01/1985 die i mensis ii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1276 {conversion of 1985-02-28} {
+ clock format 478442096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1985 12:34:56 die xxviii mensis ii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2446125 02 ii 2 02/28/1985 die xxviii mensis ii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1277 {conversion of 1985-03-01} {
+ clock format 478528496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1985 12:34:56 die i mensis iii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2446126 03 iii 3 03/01/1985 die i mensis iii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1278 {conversion of 1985-03-31} {
+ clock format 481120496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1985 12:34:56 die xxxi mensis iii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2446156 03 iii 3 03/31/1985 die xxxi mensis iii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1279 {conversion of 1985-04-01} {
+ clock format 481206896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1985 12:34:56 die i mensis iv annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2446157 04 iv 4 04/01/1985 die i mensis iv annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1280 {conversion of 1985-04-30} {
+ clock format 483712496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1985 12:34:56 die xxx mensis iv annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2446186 04 iv 4 04/30/1985 die xxx mensis iv annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1281 {conversion of 1985-05-01} {
+ clock format 483798896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1985 12:34:56 die i mensis v annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2446187 05 v 5 05/01/1985 die i mensis v annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1282 {conversion of 1985-05-31} {
+ clock format 486390896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1985 12:34:56 die xxxi mensis v annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2446217 05 v 5 05/31/1985 die xxxi mensis v annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1283 {conversion of 1985-06-01} {
+ clock format 486477296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1985 12:34:56 die i mensis vi annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2446218 06 vi 6 06/01/1985 die i mensis vi annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1284 {conversion of 1985-06-30} {
+ clock format 488982896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1985 12:34:56 die xxx mensis vi annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2446247 06 vi 6 06/30/1985 die xxx mensis vi annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1285 {conversion of 1985-07-01} {
+ clock format 489069296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1985 12:34:56 die i mensis vii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2446248 07 vii 7 07/01/1985 die i mensis vii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1286 {conversion of 1985-07-31} {
+ clock format 491661296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1985 12:34:56 die xxxi mensis vii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2446278 07 vii 7 07/31/1985 die xxxi mensis vii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1287 {conversion of 1985-08-01} {
+ clock format 491747696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1985 12:34:56 die i mensis viii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2446279 08 viii 8 08/01/1985 die i mensis viii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1288 {conversion of 1985-08-31} {
+ clock format 494339696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1985 12:34:56 die xxxi mensis viii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2446309 08 viii 8 08/31/1985 die xxxi mensis viii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1289 {conversion of 1985-09-01} {
+ clock format 494426096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1985 12:34:56 die i mensis ix annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2446310 09 ix 9 09/01/1985 die i mensis ix annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1290 {conversion of 1985-09-30} {
+ clock format 496931696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1985 12:34:56 die xxx mensis ix annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2446339 09 ix 9 09/30/1985 die xxx mensis ix annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1291 {conversion of 1985-10-01} {
+ clock format 497018096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1985 12:34:56 die i mensis x annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2446340 10 x 10 10/01/1985 die i mensis x annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1292 {conversion of 1985-10-31} {
+ clock format 499610096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1985 12:34:56 die xxxi mensis x annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2446370 10 x 10 10/31/1985 die xxxi mensis x annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1293 {conversion of 1985-11-01} {
+ clock format 499696496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1985 12:34:56 die i mensis xi annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2446371 11 xi 11 11/01/1985 die i mensis xi annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1294 {conversion of 1985-11-30} {
+ clock format 502202096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1985 12:34:56 die xxx mensis xi annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2446400 11 xi 11 11/30/1985 die xxx mensis xi annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1295 {conversion of 1985-12-01} {
+ clock format 502288496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1985 12:34:56 die i mensis xii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2446401 12 xii 12 12/01/1985 die i mensis xii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1296 {conversion of 1985-12-31} {
+ clock format 504880496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1985 12:34:56 die xxxi mensis xii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2446431 12 xii 12 12/31/1985 die xxxi mensis xii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1297 {conversion of 1988-01-01} {
+ clock format 568038896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1988 12:34:56 die i mensis i annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2447162 01 i 1 01/01/1988 die i mensis i annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1298 {conversion of 1988-01-31} {
+ clock format 570630896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1988 12:34:56 die xxxi mensis i annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2447192 01 i 1 01/31/1988 die xxxi mensis i annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1299 {conversion of 1988-02-01} {
+ clock format 570717296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1988 12:34:56 die i mensis ii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2447193 02 ii 2 02/01/1988 die i mensis ii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1300 {conversion of 1988-02-29} {
+ clock format 573136496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1988 12:34:56 die xxix mensis ii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2447221 02 ii 2 02/29/1988 die xxix mensis ii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1301 {conversion of 1988-03-01} {
+ clock format 573222896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1988 12:34:56 die i mensis iii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2447222 03 iii 3 03/01/1988 die i mensis iii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1302 {conversion of 1988-03-31} {
+ clock format 575814896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1988 12:34:56 die xxxi mensis iii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2447252 03 iii 3 03/31/1988 die xxxi mensis iii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1303 {conversion of 1988-04-01} {
+ clock format 575901296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1988 12:34:56 die i mensis iv annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2447253 04 iv 4 04/01/1988 die i mensis iv annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1304 {conversion of 1988-04-30} {
+ clock format 578406896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1988 12:34:56 die xxx mensis iv annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2447282 04 iv 4 04/30/1988 die xxx mensis iv annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1305 {conversion of 1988-05-01} {
+ clock format 578493296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1988 12:34:56 die i mensis v annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2447283 05 v 5 05/01/1988 die i mensis v annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1306 {conversion of 1988-05-31} {
+ clock format 581085296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1988 12:34:56 die xxxi mensis v annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2447313 05 v 5 05/31/1988 die xxxi mensis v annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1307 {conversion of 1988-06-01} {
+ clock format 581171696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1988 12:34:56 die i mensis vi annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2447314 06 vi 6 06/01/1988 die i mensis vi annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1308 {conversion of 1988-06-30} {
+ clock format 583677296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1988 12:34:56 die xxx mensis vi annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2447343 06 vi 6 06/30/1988 die xxx mensis vi annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1309 {conversion of 1988-07-01} {
+ clock format 583763696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1988 12:34:56 die i mensis vii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2447344 07 vii 7 07/01/1988 die i mensis vii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1310 {conversion of 1988-07-31} {
+ clock format 586355696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1988 12:34:56 die xxxi mensis vii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2447374 07 vii 7 07/31/1988 die xxxi mensis vii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1311 {conversion of 1988-08-01} {
+ clock format 586442096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1988 12:34:56 die i mensis viii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2447375 08 viii 8 08/01/1988 die i mensis viii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1312 {conversion of 1988-08-31} {
+ clock format 589034096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1988 12:34:56 die xxxi mensis viii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2447405 08 viii 8 08/31/1988 die xxxi mensis viii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1313 {conversion of 1988-09-01} {
+ clock format 589120496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1988 12:34:56 die i mensis ix annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2447406 09 ix 9 09/01/1988 die i mensis ix annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1314 {conversion of 1988-09-30} {
+ clock format 591626096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1988 12:34:56 die xxx mensis ix annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2447435 09 ix 9 09/30/1988 die xxx mensis ix annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1315 {conversion of 1988-10-01} {
+ clock format 591712496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1988 12:34:56 die i mensis x annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2447436 10 x 10 10/01/1988 die i mensis x annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1316 {conversion of 1988-10-31} {
+ clock format 594304496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1988 12:34:56 die xxxi mensis x annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2447466 10 x 10 10/31/1988 die xxxi mensis x annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1317 {conversion of 1988-11-01} {
+ clock format 594390896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1988 12:34:56 die i mensis xi annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2447467 11 xi 11 11/01/1988 die i mensis xi annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1318 {conversion of 1988-11-30} {
+ clock format 596896496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1988 12:34:56 die xxx mensis xi annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2447496 11 xi 11 11/30/1988 die xxx mensis xi annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1319 {conversion of 1988-12-01} {
+ clock format 596982896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1988 12:34:56 die i mensis xii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2447497 12 xii 12 12/01/1988 die i mensis xii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1320 {conversion of 1988-12-31} {
+ clock format 599574896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1988 12:34:56 die xxxi mensis xii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2447527 12 xii 12 12/31/1988 die xxxi mensis xii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1321 {conversion of 1989-01-01} {
+ clock format 599661296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1989 12:34:56 die i mensis i annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2447528 01 i 1 01/01/1989 die i mensis i annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1322 {conversion of 1989-01-31} {
+ clock format 602253296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1989 12:34:56 die xxxi mensis i annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2447558 01 i 1 01/31/1989 die xxxi mensis i annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1323 {conversion of 1989-02-01} {
+ clock format 602339696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1989 12:34:56 die i mensis ii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2447559 02 ii 2 02/01/1989 die i mensis ii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1324 {conversion of 1989-02-28} {
+ clock format 604672496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1989 12:34:56 die xxviii mensis ii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2447586 02 ii 2 02/28/1989 die xxviii mensis ii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1325 {conversion of 1989-03-01} {
+ clock format 604758896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1989 12:34:56 die i mensis iii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2447587 03 iii 3 03/01/1989 die i mensis iii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1326 {conversion of 1989-03-31} {
+ clock format 607350896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1989 12:34:56 die xxxi mensis iii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2447617 03 iii 3 03/31/1989 die xxxi mensis iii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1327 {conversion of 1989-04-01} {
+ clock format 607437296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1989 12:34:56 die i mensis iv annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2447618 04 iv 4 04/01/1989 die i mensis iv annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1328 {conversion of 1989-04-30} {
+ clock format 609942896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1989 12:34:56 die xxx mensis iv annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2447647 04 iv 4 04/30/1989 die xxx mensis iv annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1329 {conversion of 1989-05-01} {
+ clock format 610029296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1989 12:34:56 die i mensis v annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2447648 05 v 5 05/01/1989 die i mensis v annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1330 {conversion of 1989-05-31} {
+ clock format 612621296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1989 12:34:56 die xxxi mensis v annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2447678 05 v 5 05/31/1989 die xxxi mensis v annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1331 {conversion of 1989-06-01} {
+ clock format 612707696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1989 12:34:56 die i mensis vi annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2447679 06 vi 6 06/01/1989 die i mensis vi annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1332 {conversion of 1989-06-30} {
+ clock format 615213296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1989 12:34:56 die xxx mensis vi annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2447708 06 vi 6 06/30/1989 die xxx mensis vi annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1333 {conversion of 1989-07-01} {
+ clock format 615299696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1989 12:34:56 die i mensis vii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2447709 07 vii 7 07/01/1989 die i mensis vii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1334 {conversion of 1989-07-31} {
+ clock format 617891696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1989 12:34:56 die xxxi mensis vii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2447739 07 vii 7 07/31/1989 die xxxi mensis vii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1335 {conversion of 1989-08-01} {
+ clock format 617978096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1989 12:34:56 die i mensis viii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2447740 08 viii 8 08/01/1989 die i mensis viii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1336 {conversion of 1989-08-31} {
+ clock format 620570096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1989 12:34:56 die xxxi mensis viii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2447770 08 viii 8 08/31/1989 die xxxi mensis viii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1337 {conversion of 1989-09-01} {
+ clock format 620656496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1989 12:34:56 die i mensis ix annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2447771 09 ix 9 09/01/1989 die i mensis ix annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1338 {conversion of 1989-09-30} {
+ clock format 623162096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1989 12:34:56 die xxx mensis ix annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2447800 09 ix 9 09/30/1989 die xxx mensis ix annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1339 {conversion of 1989-10-01} {
+ clock format 623248496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1989 12:34:56 die i mensis x annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2447801 10 x 10 10/01/1989 die i mensis x annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1340 {conversion of 1989-10-31} {
+ clock format 625840496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1989 12:34:56 die xxxi mensis x annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2447831 10 x 10 10/31/1989 die xxxi mensis x annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1341 {conversion of 1989-11-01} {
+ clock format 625926896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1989 12:34:56 die i mensis xi annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2447832 11 xi 11 11/01/1989 die i mensis xi annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1342 {conversion of 1989-11-30} {
+ clock format 628432496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1989 12:34:56 die xxx mensis xi annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2447861 11 xi 11 11/30/1989 die xxx mensis xi annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1343 {conversion of 1989-12-01} {
+ clock format 628518896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1989 12:34:56 die i mensis xii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2447862 12 xii 12 12/01/1989 die i mensis xii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1344 {conversion of 1989-12-31} {
+ clock format 631110896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1989 12:34:56 die xxxi mensis xii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2447892 12 xii 12 12/31/1989 die xxxi mensis xii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1345 {conversion of 1992-01-01} {
+ clock format 694269296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1992 12:34:56 die i mensis i annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2448623 01 i 1 01/01/1992 die i mensis i annoque mcmxcii 92 xcii 1992}
+test clock-2.1346 {conversion of 1992-01-31} {
+ clock format 696861296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1992 12:34:56 die xxxi mensis i annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2448653 01 i 1 01/31/1992 die xxxi mensis i annoque mcmxcii 92 xcii 1992}
+test clock-2.1347 {conversion of 1992-02-01} {
+ clock format 696947696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1992 12:34:56 die i mensis ii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2448654 02 ii 2 02/01/1992 die i mensis ii annoque mcmxcii 92 xcii 1992}
+test clock-2.1348 {conversion of 1992-02-29} {
+ clock format 699366896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1992 12:34:56 die xxix mensis ii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2448682 02 ii 2 02/29/1992 die xxix mensis ii annoque mcmxcii 92 xcii 1992}
+test clock-2.1349 {conversion of 1992-03-01} {
+ clock format 699453296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1992 12:34:56 die i mensis iii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2448683 03 iii 3 03/01/1992 die i mensis iii annoque mcmxcii 92 xcii 1992}
+test clock-2.1350 {conversion of 1992-03-31} {
+ clock format 702045296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1992 12:34:56 die xxxi mensis iii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2448713 03 iii 3 03/31/1992 die xxxi mensis iii annoque mcmxcii 92 xcii 1992}
+test clock-2.1351 {conversion of 1992-04-01} {
+ clock format 702131696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1992 12:34:56 die i mensis iv annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2448714 04 iv 4 04/01/1992 die i mensis iv annoque mcmxcii 92 xcii 1992}
+test clock-2.1352 {conversion of 1992-04-30} {
+ clock format 704637296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1992 12:34:56 die xxx mensis iv annoque mcmxcii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2448743 04 iv 4 04/30/1992 die xxx mensis iv annoque mcmxcii 92 xcii 1992}
+test clock-2.1353 {conversion of 1992-05-01} {
+ clock format 704723696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1992 12:34:56 die i mensis v annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2448744 05 v 5 05/01/1992 die i mensis v annoque mcmxcii 92 xcii 1992}
+test clock-2.1354 {conversion of 1992-05-31} {
+ clock format 707315696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1992 12:34:56 die xxxi mensis v annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2448774 05 v 5 05/31/1992 die xxxi mensis v annoque mcmxcii 92 xcii 1992}
+test clock-2.1355 {conversion of 1992-06-01} {
+ clock format 707402096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1992 12:34:56 die i mensis vi annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2448775 06 vi 6 06/01/1992 die i mensis vi annoque mcmxcii 92 xcii 1992}
+test clock-2.1356 {conversion of 1992-06-30} {
+ clock format 709907696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1992 12:34:56 die xxx mensis vi annoque mcmxcii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2448804 06 vi 6 06/30/1992 die xxx mensis vi annoque mcmxcii 92 xcii 1992}
+test clock-2.1357 {conversion of 1992-07-01} {
+ clock format 709994096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1992 12:34:56 die i mensis vii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2448805 07 vii 7 07/01/1992 die i mensis vii annoque mcmxcii 92 xcii 1992}
+test clock-2.1358 {conversion of 1992-07-31} {
+ clock format 712586096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1992 12:34:56 die xxxi mensis vii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2448835 07 vii 7 07/31/1992 die xxxi mensis vii annoque mcmxcii 92 xcii 1992}
+test clock-2.1359 {conversion of 1992-08-01} {
+ clock format 712672496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1992 12:34:56 die i mensis viii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2448836 08 viii 8 08/01/1992 die i mensis viii annoque mcmxcii 92 xcii 1992}
+test clock-2.1360 {conversion of 1992-08-31} {
+ clock format 715264496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1992 12:34:56 die xxxi mensis viii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2448866 08 viii 8 08/31/1992 die xxxi mensis viii annoque mcmxcii 92 xcii 1992}
+test clock-2.1361 {conversion of 1992-09-01} {
+ clock format 715350896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1992 12:34:56 die i mensis ix annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2448867 09 ix 9 09/01/1992 die i mensis ix annoque mcmxcii 92 xcii 1992}
+test clock-2.1362 {conversion of 1992-09-30} {
+ clock format 717856496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1992 12:34:56 die xxx mensis ix annoque mcmxcii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2448896 09 ix 9 09/30/1992 die xxx mensis ix annoque mcmxcii 92 xcii 1992}
+test clock-2.1363 {conversion of 1992-10-01} {
+ clock format 717942896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1992 12:34:56 die i mensis x annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2448897 10 x 10 10/01/1992 die i mensis x annoque mcmxcii 92 xcii 1992}
+test clock-2.1364 {conversion of 1992-10-31} {
+ clock format 720534896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1992 12:34:56 die xxxi mensis x annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2448927 10 x 10 10/31/1992 die xxxi mensis x annoque mcmxcii 92 xcii 1992}
+test clock-2.1365 {conversion of 1992-11-01} {
+ clock format 720621296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1992 12:34:56 die i mensis xi annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2448928 11 xi 11 11/01/1992 die i mensis xi annoque mcmxcii 92 xcii 1992}
+test clock-2.1366 {conversion of 1992-11-30} {
+ clock format 723126896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1992 12:34:56 die xxx mensis xi annoque mcmxcii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2448957 11 xi 11 11/30/1992 die xxx mensis xi annoque mcmxcii 92 xcii 1992}
+test clock-2.1367 {conversion of 1992-12-01} {
+ clock format 723213296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1992 12:34:56 die i mensis xii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2448958 12 xii 12 12/01/1992 die i mensis xii annoque mcmxcii 92 xcii 1992}
+test clock-2.1368 {conversion of 1992-12-31} {
+ clock format 725805296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1992 12:34:56 die xxxi mensis xii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2448988 12 xii 12 12/31/1992 die xxxi mensis xii annoque mcmxcii 92 xcii 1992}
+test clock-2.1369 {conversion of 1993-01-01} {
+ clock format 725891696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1993 12:34:56 die i mensis i annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2448989 01 i 1 01/01/1993 die i mensis i annoque mcmxciii 93 xciii 1993}
+test clock-2.1370 {conversion of 1993-01-31} {
+ clock format 728483696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1993 12:34:56 die xxxi mensis i annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2449019 01 i 1 01/31/1993 die xxxi mensis i annoque mcmxciii 93 xciii 1993}
+test clock-2.1371 {conversion of 1993-02-01} {
+ clock format 728570096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1993 12:34:56 die i mensis ii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2449020 02 ii 2 02/01/1993 die i mensis ii annoque mcmxciii 93 xciii 1993}
+test clock-2.1372 {conversion of 1993-02-28} {
+ clock format 730902896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1993 12:34:56 die xxviii mensis ii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2449047 02 ii 2 02/28/1993 die xxviii mensis ii annoque mcmxciii 93 xciii 1993}
+test clock-2.1373 {conversion of 1993-03-01} {
+ clock format 730989296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1993 12:34:56 die i mensis iii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2449048 03 iii 3 03/01/1993 die i mensis iii annoque mcmxciii 93 xciii 1993}
+test clock-2.1374 {conversion of 1993-03-31} {
+ clock format 733581296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1993 12:34:56 die xxxi mensis iii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2449078 03 iii 3 03/31/1993 die xxxi mensis iii annoque mcmxciii 93 xciii 1993}
+test clock-2.1375 {conversion of 1993-04-01} {
+ clock format 733667696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1993 12:34:56 die i mensis iv annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2449079 04 iv 4 04/01/1993 die i mensis iv annoque mcmxciii 93 xciii 1993}
+test clock-2.1376 {conversion of 1993-04-30} {
+ clock format 736173296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1993 12:34:56 die xxx mensis iv annoque mcmxciii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2449108 04 iv 4 04/30/1993 die xxx mensis iv annoque mcmxciii 93 xciii 1993}
+test clock-2.1377 {conversion of 1993-05-01} {
+ clock format 736259696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1993 12:34:56 die i mensis v annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2449109 05 v 5 05/01/1993 die i mensis v annoque mcmxciii 93 xciii 1993}
+test clock-2.1378 {conversion of 1993-05-31} {
+ clock format 738851696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1993 12:34:56 die xxxi mensis v annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2449139 05 v 5 05/31/1993 die xxxi mensis v annoque mcmxciii 93 xciii 1993}
+test clock-2.1379 {conversion of 1993-06-01} {
+ clock format 738938096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1993 12:34:56 die i mensis vi annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2449140 06 vi 6 06/01/1993 die i mensis vi annoque mcmxciii 93 xciii 1993}
+test clock-2.1380 {conversion of 1993-06-30} {
+ clock format 741443696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1993 12:34:56 die xxx mensis vi annoque mcmxciii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2449169 06 vi 6 06/30/1993 die xxx mensis vi annoque mcmxciii 93 xciii 1993}
+test clock-2.1381 {conversion of 1993-07-01} {
+ clock format 741530096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1993 12:34:56 die i mensis vii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2449170 07 vii 7 07/01/1993 die i mensis vii annoque mcmxciii 93 xciii 1993}
+test clock-2.1382 {conversion of 1993-07-31} {
+ clock format 744122096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1993 12:34:56 die xxxi mensis vii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2449200 07 vii 7 07/31/1993 die xxxi mensis vii annoque mcmxciii 93 xciii 1993}
+test clock-2.1383 {conversion of 1993-08-01} {
+ clock format 744208496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1993 12:34:56 die i mensis viii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2449201 08 viii 8 08/01/1993 die i mensis viii annoque mcmxciii 93 xciii 1993}
+test clock-2.1384 {conversion of 1993-08-31} {
+ clock format 746800496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1993 12:34:56 die xxxi mensis viii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2449231 08 viii 8 08/31/1993 die xxxi mensis viii annoque mcmxciii 93 xciii 1993}
+test clock-2.1385 {conversion of 1993-09-01} {
+ clock format 746886896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1993 12:34:56 die i mensis ix annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2449232 09 ix 9 09/01/1993 die i mensis ix annoque mcmxciii 93 xciii 1993}
+test clock-2.1386 {conversion of 1993-09-30} {
+ clock format 749392496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1993 12:34:56 die xxx mensis ix annoque mcmxciii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2449261 09 ix 9 09/30/1993 die xxx mensis ix annoque mcmxciii 93 xciii 1993}
+test clock-2.1387 {conversion of 1993-10-01} {
+ clock format 749478896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1993 12:34:56 die i mensis x annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2449262 10 x 10 10/01/1993 die i mensis x annoque mcmxciii 93 xciii 1993}
+test clock-2.1388 {conversion of 1993-10-31} {
+ clock format 752070896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1993 12:34:56 die xxxi mensis x annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2449292 10 x 10 10/31/1993 die xxxi mensis x annoque mcmxciii 93 xciii 1993}
+test clock-2.1389 {conversion of 1993-11-01} {
+ clock format 752157296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1993 12:34:56 die i mensis xi annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2449293 11 xi 11 11/01/1993 die i mensis xi annoque mcmxciii 93 xciii 1993}
+test clock-2.1390 {conversion of 1993-11-30} {
+ clock format 754662896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1993 12:34:56 die xxx mensis xi annoque mcmxciii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2449322 11 xi 11 11/30/1993 die xxx mensis xi annoque mcmxciii 93 xciii 1993}
+test clock-2.1391 {conversion of 1993-12-01} {
+ clock format 754749296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1993 12:34:56 die i mensis xii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2449323 12 xii 12 12/01/1993 die i mensis xii annoque mcmxciii 93 xciii 1993}
+test clock-2.1392 {conversion of 1993-12-31} {
+ clock format 757341296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1993 12:34:56 die xxxi mensis xii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2449353 12 xii 12 12/31/1993 die xxxi mensis xii annoque mcmxciii 93 xciii 1993}
+test clock-2.1393 {conversion of 1996-01-01} {
+ clock format 820499696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1996 12:34:56 die i mensis i annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2450084 01 i 1 01/01/1996 die i mensis i annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1394 {conversion of 1996-01-31} {
+ clock format 823091696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1996 12:34:56 die xxxi mensis i annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2450114 01 i 1 01/31/1996 die xxxi mensis i annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1395 {conversion of 1996-02-01} {
+ clock format 823178096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1996 12:34:56 die i mensis ii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2450115 02 ii 2 02/01/1996 die i mensis ii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1396 {conversion of 1996-02-29} {
+ clock format 825597296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/1996 12:34:56 die xxix mensis ii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2450143 02 ii 2 02/29/1996 die xxix mensis ii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1397 {conversion of 1996-03-01} {
+ clock format 825683696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1996 12:34:56 die i mensis iii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 061 2450144 03 iii 3 03/01/1996 die i mensis iii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1398 {conversion of 1996-03-31} {
+ clock format 828275696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1996 12:34:56 die xxxi mensis iii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2450174 03 iii 3 03/31/1996 die xxxi mensis iii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1399 {conversion of 1996-04-01} {
+ clock format 828362096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1996 12:34:56 die i mensis iv annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 092 2450175 04 iv 4 04/01/1996 die i mensis iv annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1400 {conversion of 1996-04-30} {
+ clock format 830867696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1996 12:34:56 die xxx mensis iv annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2450204 04 iv 4 04/30/1996 die xxx mensis iv annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1401 {conversion of 1996-05-01} {
+ clock format 830954096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1996 12:34:56 die i mensis v annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i May 122 2450205 05 v 5 05/01/1996 die i mensis v annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1402 {conversion of 1996-05-31} {
+ clock format 833546096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1996 12:34:56 die xxxi mensis v annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2450235 05 v 5 05/31/1996 die xxxi mensis v annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1403 {conversion of 1996-06-01} {
+ clock format 833632496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1996 12:34:56 die i mensis vi annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 153 2450236 06 vi 6 06/01/1996 die i mensis vi annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1404 {conversion of 1996-06-30} {
+ clock format 836138096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1996 12:34:56 die xxx mensis vi annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2450265 06 vi 6 06/30/1996 die xxx mensis vi annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1405 {conversion of 1996-07-01} {
+ clock format 836224496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1996 12:34:56 die i mensis vii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 183 2450266 07 vii 7 07/01/1996 die i mensis vii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1406 {conversion of 1996-07-31} {
+ clock format 838816496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1996 12:34:56 die xxxi mensis vii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2450296 07 vii 7 07/31/1996 die xxxi mensis vii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1407 {conversion of 1996-08-01} {
+ clock format 838902896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1996 12:34:56 die i mensis viii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 214 2450297 08 viii 8 08/01/1996 die i mensis viii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1408 {conversion of 1996-08-31} {
+ clock format 841494896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1996 12:34:56 die xxxi mensis viii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2450327 08 viii 8 08/31/1996 die xxxi mensis viii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1409 {conversion of 1996-09-01} {
+ clock format 841581296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1996 12:34:56 die i mensis ix annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 245 2450328 09 ix 9 09/01/1996 die i mensis ix annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1410 {conversion of 1996-09-30} {
+ clock format 844086896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1996 12:34:56 die xxx mensis ix annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2450357 09 ix 9 09/30/1996 die xxx mensis ix annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1411 {conversion of 1996-10-01} {
+ clock format 844173296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1996 12:34:56 die i mensis x annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 275 2450358 10 x 10 10/01/1996 die i mensis x annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1412 {conversion of 1996-10-31} {
+ clock format 846765296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1996 12:34:56 die xxxi mensis x annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2450388 10 x 10 10/31/1996 die xxxi mensis x annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1413 {conversion of 1996-11-01} {
+ clock format 846851696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1996 12:34:56 die i mensis xi annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 306 2450389 11 xi 11 11/01/1996 die i mensis xi annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1414 {conversion of 1996-11-30} {
+ clock format 849357296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1996 12:34:56 die xxx mensis xi annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2450418 11 xi 11 11/30/1996 die xxx mensis xi annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1415 {conversion of 1996-12-01} {
+ clock format 849443696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1996 12:34:56 die i mensis xii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 336 2450419 12 xii 12 12/01/1996 die i mensis xii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1416 {conversion of 1996-12-31} {
+ clock format 852035696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1996 12:34:56 die xxxi mensis xii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2450449 12 xii 12 12/31/1996 die xxxi mensis xii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1417 {conversion of 1997-01-01} {
+ clock format 852122096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/1997 12:34:56 die i mensis i annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jan 001 2450450 01 i 1 01/01/1997 die i mensis i annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1418 {conversion of 1997-01-31} {
+ clock format 854714096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/1997 12:34:56 die xxxi mensis i annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2450480 01 i 1 01/31/1997 die xxxi mensis i annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1419 {conversion of 1997-02-01} {
+ clock format 854800496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/1997 12:34:56 die i mensis ii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Feb 032 2450481 02 ii 2 02/01/1997 die i mensis ii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1420 {conversion of 1997-02-28} {
+ clock format 857133296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/1997 12:34:56 die xxviii mensis ii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2450508 02 ii 2 02/28/1997 die xxviii mensis ii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1421 {conversion of 1997-03-01} {
+ clock format 857219696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/1997 12:34:56 die i mensis iii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Mar 060 2450509 03 iii 3 03/01/1997 die i mensis iii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1422 {conversion of 1997-03-31} {
+ clock format 859811696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/1997 12:34:56 die xxxi mensis iii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2450539 03 iii 3 03/31/1997 die xxxi mensis iii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1423 {conversion of 1997-04-01} {
+ clock format 859898096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/1997 12:34:56 die i mensis iv annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Apr 091 2450540 04 iv 4 04/01/1997 die i mensis iv annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1424 {conversion of 1997-04-30} {
+ clock format 862403696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/1997 12:34:56 die xxx mensis iv annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2450569 04 iv 4 04/30/1997 die xxx mensis iv annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1425 {conversion of 1997-05-01} {
+ clock format 862490096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/1997 12:34:56 die i mensis v annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i May 121 2450570 05 v 5 05/01/1997 die i mensis v annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1426 {conversion of 1997-05-31} {
+ clock format 865082096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/1997 12:34:56 die xxxi mensis v annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2450600 05 v 5 05/31/1997 die xxxi mensis v annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1427 {conversion of 1997-06-01} {
+ clock format 865168496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/1997 12:34:56 die i mensis vi annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jun 152 2450601 06 vi 6 06/01/1997 die i mensis vi annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1428 {conversion of 1997-06-30} {
+ clock format 867674096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/1997 12:34:56 die xxx mensis vi annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2450630 06 vi 6 06/30/1997 die xxx mensis vi annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1429 {conversion of 1997-07-01} {
+ clock format 867760496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/1997 12:34:56 die i mensis vii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Jul 182 2450631 07 vii 7 07/01/1997 die i mensis vii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1430 {conversion of 1997-07-31} {
+ clock format 870352496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/1997 12:34:56 die xxxi mensis vii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2450661 07 vii 7 07/31/1997 die xxxi mensis vii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1431 {conversion of 1997-08-01} {
+ clock format 870438896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/1997 12:34:56 die i mensis viii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Aug 213 2450662 08 viii 8 08/01/1997 die i mensis viii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1432 {conversion of 1997-08-31} {
+ clock format 873030896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/1997 12:34:56 die xxxi mensis viii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2450692 08 viii 8 08/31/1997 die xxxi mensis viii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1433 {conversion of 1997-09-01} {
+ clock format 873117296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/1997 12:34:56 die i mensis ix annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Sep 244 2450693 09 ix 9 09/01/1997 die i mensis ix annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1434 {conversion of 1997-09-30} {
+ clock format 875622896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/1997 12:34:56 die xxx mensis ix annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2450722 09 ix 9 09/30/1997 die xxx mensis ix annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1435 {conversion of 1997-10-01} {
+ clock format 875709296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/1997 12:34:56 die i mensis x annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Oct 274 2450723 10 x 10 10/01/1997 die i mensis x annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1436 {conversion of 1997-10-31} {
+ clock format 878301296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/1997 12:34:56 die xxxi mensis x annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2450753 10 x 10 10/31/1997 die xxxi mensis x annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1437 {conversion of 1997-11-01} {
+ clock format 878387696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/1997 12:34:56 die i mensis xi annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Nov 305 2450754 11 xi 11 11/01/1997 die i mensis xi annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1438 {conversion of 1997-11-30} {
+ clock format 880893296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/1997 12:34:56 die xxx mensis xi annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2450783 11 xi 11 11/30/1997 die xxx mensis xi annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1439 {conversion of 1997-12-01} {
+ clock format 880979696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/1997 12:34:56 die i mensis xii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i 1 i Dec 335 2450784 12 xii 12 12/01/1997 die i mensis xii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1440 {conversion of 1997-12-31} {
+ clock format 883571696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/1997 12:34:56 die xxxi mensis xii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2450814 12 xii 12 12/31/1997 die xxxi mensis xii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1441 {conversion of 2000-01-01} {
+ clock format 946730096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2000 12:34:56 die i mensis i annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2451545 01 i 1 01/01/2000 die i mensis i annoque mm? 00 ? 2000}
+test clock-2.1442 {conversion of 2000-01-31} {
+ clock format 949322096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2000 12:34:56 die xxxi mensis i annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2451575 01 i 1 01/31/2000 die xxxi mensis i annoque mm? 00 ? 2000}
+test clock-2.1443 {conversion of 2000-02-01} {
+ clock format 949408496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2000 12:34:56 die i mensis ii annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2451576 02 ii 2 02/01/2000 die i mensis ii annoque mm? 00 ? 2000}
+test clock-2.1444 {conversion of 2000-02-29} {
+ clock format 951827696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2000 12:34:56 die xxix mensis ii annoque mm? xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2451604 02 ii 2 02/29/2000 die xxix mensis ii annoque mm? 00 ? 2000}
+test clock-2.1445 {conversion of 2000-03-01} {
+ clock format 951914096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2000 12:34:56 die i mensis iii annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2451605 03 iii 3 03/01/2000 die i mensis iii annoque mm? 00 ? 2000}
+test clock-2.1446 {conversion of 2000-03-31} {
+ clock format 954506096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2000 12:34:56 die xxxi mensis iii annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2451635 03 iii 3 03/31/2000 die xxxi mensis iii annoque mm? 00 ? 2000}
+test clock-2.1447 {conversion of 2000-04-01} {
+ clock format 954592496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2000 12:34:56 die i mensis iv annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2451636 04 iv 4 04/01/2000 die i mensis iv annoque mm? 00 ? 2000}
+test clock-2.1448 {conversion of 2000-04-30} {
+ clock format 957098096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2000 12:34:56 die xxx mensis iv annoque mm? xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2451665 04 iv 4 04/30/2000 die xxx mensis iv annoque mm? 00 ? 2000}
+test clock-2.1449 {conversion of 2000-05-01} {
+ clock format 957184496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2000 12:34:56 die i mensis v annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2451666 05 v 5 05/01/2000 die i mensis v annoque mm? 00 ? 2000}
+test clock-2.1450 {conversion of 2000-05-31} {
+ clock format 959776496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2000 12:34:56 die xxxi mensis v annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2451696 05 v 5 05/31/2000 die xxxi mensis v annoque mm? 00 ? 2000}
+test clock-2.1451 {conversion of 2000-06-01} {
+ clock format 959862896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2000 12:34:56 die i mensis vi annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2451697 06 vi 6 06/01/2000 die i mensis vi annoque mm? 00 ? 2000}
+test clock-2.1452 {conversion of 2000-06-30} {
+ clock format 962368496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2000 12:34:56 die xxx mensis vi annoque mm? xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2451726 06 vi 6 06/30/2000 die xxx mensis vi annoque mm? 00 ? 2000}
+test clock-2.1453 {conversion of 2000-07-01} {
+ clock format 962454896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2000 12:34:56 die i mensis vii annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2451727 07 vii 7 07/01/2000 die i mensis vii annoque mm? 00 ? 2000}
+test clock-2.1454 {conversion of 2000-07-31} {
+ clock format 965046896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2000 12:34:56 die xxxi mensis vii annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2451757 07 vii 7 07/31/2000 die xxxi mensis vii annoque mm? 00 ? 2000}
+test clock-2.1455 {conversion of 2000-08-01} {
+ clock format 965133296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2000 12:34:56 die i mensis viii annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2451758 08 viii 8 08/01/2000 die i mensis viii annoque mm? 00 ? 2000}
+test clock-2.1456 {conversion of 2000-08-31} {
+ clock format 967725296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2000 12:34:56 die xxxi mensis viii annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2451788 08 viii 8 08/31/2000 die xxxi mensis viii annoque mm? 00 ? 2000}
+test clock-2.1457 {conversion of 2000-09-01} {
+ clock format 967811696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2000 12:34:56 die i mensis ix annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2451789 09 ix 9 09/01/2000 die i mensis ix annoque mm? 00 ? 2000}
+test clock-2.1458 {conversion of 2000-09-30} {
+ clock format 970317296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2000 12:34:56 die xxx mensis ix annoque mm? xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2451818 09 ix 9 09/30/2000 die xxx mensis ix annoque mm? 00 ? 2000}
+test clock-2.1459 {conversion of 2000-10-01} {
+ clock format 970403696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2000 12:34:56 die i mensis x annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2451819 10 x 10 10/01/2000 die i mensis x annoque mm? 00 ? 2000}
+test clock-2.1460 {conversion of 2000-10-31} {
+ clock format 972995696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2000 12:34:56 die xxxi mensis x annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2451849 10 x 10 10/31/2000 die xxxi mensis x annoque mm? 00 ? 2000}
+test clock-2.1461 {conversion of 2000-11-01} {
+ clock format 973082096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2000 12:34:56 die i mensis xi annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2451850 11 xi 11 11/01/2000 die i mensis xi annoque mm? 00 ? 2000}
+test clock-2.1462 {conversion of 2000-11-30} {
+ clock format 975587696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2000 12:34:56 die xxx mensis xi annoque mm? xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2451879 11 xi 11 11/30/2000 die xxx mensis xi annoque mm? 00 ? 2000}
+test clock-2.1463 {conversion of 2000-12-01} {
+ clock format 975674096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2000 12:34:56 die i mensis xii annoque mm? xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2451880 12 xii 12 12/01/2000 die i mensis xii annoque mm? 00 ? 2000}
+test clock-2.1464 {conversion of 2000-12-31} {
+ clock format 978266096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2000 12:34:56 die xxxi mensis xii annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2451910 12 xii 12 12/31/2000 die xxxi mensis xii annoque mm? 00 ? 2000}
+test clock-2.1465 {conversion of 2001-01-01} {
+ clock format 978352496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2001 12:34:56 die i mensis i annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2451911 01 i 1 01/01/2001 die i mensis i annoque mmi 01 i 2001}
+test clock-2.1466 {conversion of 2001-01-31} {
+ clock format 980944496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2001 12:34:56 die xxxi mensis i annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2451941 01 i 1 01/31/2001 die xxxi mensis i annoque mmi 01 i 2001}
+test clock-2.1467 {conversion of 2001-02-01} {
+ clock format 981030896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2001 12:34:56 die i mensis ii annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2451942 02 ii 2 02/01/2001 die i mensis ii annoque mmi 01 i 2001}
+test clock-2.1468 {conversion of 2001-02-28} {
+ clock format 983363696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2001 12:34:56 die xxviii mensis ii annoque mmi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2451969 02 ii 2 02/28/2001 die xxviii mensis ii annoque mmi 01 i 2001}
+test clock-2.1469 {conversion of 2001-03-01} {
+ clock format 983450096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2001 12:34:56 die i mensis iii annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2451970 03 iii 3 03/01/2001 die i mensis iii annoque mmi 01 i 2001}
+test clock-2.1470 {conversion of 2001-03-31} {
+ clock format 986042096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2001 12:34:56 die xxxi mensis iii annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2452000 03 iii 3 03/31/2001 die xxxi mensis iii annoque mmi 01 i 2001}
+test clock-2.1471 {conversion of 2001-04-01} {
+ clock format 986128496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2001 12:34:56 die i mensis iv annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2452001 04 iv 4 04/01/2001 die i mensis iv annoque mmi 01 i 2001}
+test clock-2.1472 {conversion of 2001-04-30} {
+ clock format 988634096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2001 12:34:56 die xxx mensis iv annoque mmi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2452030 04 iv 4 04/30/2001 die xxx mensis iv annoque mmi 01 i 2001}
+test clock-2.1473 {conversion of 2001-05-01} {
+ clock format 988720496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2001 12:34:56 die i mensis v annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2452031 05 v 5 05/01/2001 die i mensis v annoque mmi 01 i 2001}
+test clock-2.1474 {conversion of 2001-05-31} {
+ clock format 991312496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2001 12:34:56 die xxxi mensis v annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2452061 05 v 5 05/31/2001 die xxxi mensis v annoque mmi 01 i 2001}
+test clock-2.1475 {conversion of 2001-06-01} {
+ clock format 991398896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2001 12:34:56 die i mensis vi annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2452062 06 vi 6 06/01/2001 die i mensis vi annoque mmi 01 i 2001}
+test clock-2.1476 {conversion of 2001-06-30} {
+ clock format 993904496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2001 12:34:56 die xxx mensis vi annoque mmi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2452091 06 vi 6 06/30/2001 die xxx mensis vi annoque mmi 01 i 2001}
+test clock-2.1477 {conversion of 2001-07-01} {
+ clock format 993990896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2001 12:34:56 die i mensis vii annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2452092 07 vii 7 07/01/2001 die i mensis vii annoque mmi 01 i 2001}
+test clock-2.1478 {conversion of 2001-07-31} {
+ clock format 996582896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2001 12:34:56 die xxxi mensis vii annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2452122 07 vii 7 07/31/2001 die xxxi mensis vii annoque mmi 01 i 2001}
+test clock-2.1479 {conversion of 2001-08-01} {
+ clock format 996669296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2001 12:34:56 die i mensis viii annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2452123 08 viii 8 08/01/2001 die i mensis viii annoque mmi 01 i 2001}
+test clock-2.1480 {conversion of 2001-08-31} {
+ clock format 999261296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2001 12:34:56 die xxxi mensis viii annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2452153 08 viii 8 08/31/2001 die xxxi mensis viii annoque mmi 01 i 2001}
+test clock-2.1481 {conversion of 2001-09-01} {
+ clock format 999347696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2001 12:34:56 die i mensis ix annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2452154 09 ix 9 09/01/2001 die i mensis ix annoque mmi 01 i 2001}
+test clock-2.1482 {conversion of 2001-09-30} {
+ clock format 1001853296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2001 12:34:56 die xxx mensis ix annoque mmi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2452183 09 ix 9 09/30/2001 die xxx mensis ix annoque mmi 01 i 2001}
+test clock-2.1483 {conversion of 2001-10-01} {
+ clock format 1001939696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2001 12:34:56 die i mensis x annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2452184 10 x 10 10/01/2001 die i mensis x annoque mmi 01 i 2001}
+test clock-2.1484 {conversion of 2001-10-31} {
+ clock format 1004531696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2001 12:34:56 die xxxi mensis x annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2452214 10 x 10 10/31/2001 die xxxi mensis x annoque mmi 01 i 2001}
+test clock-2.1485 {conversion of 2001-11-01} {
+ clock format 1004618096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2001 12:34:56 die i mensis xi annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2452215 11 xi 11 11/01/2001 die i mensis xi annoque mmi 01 i 2001}
+test clock-2.1486 {conversion of 2001-11-30} {
+ clock format 1007123696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2001 12:34:56 die xxx mensis xi annoque mmi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2452244 11 xi 11 11/30/2001 die xxx mensis xi annoque mmi 01 i 2001}
+test clock-2.1487 {conversion of 2001-12-01} {
+ clock format 1007210096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2001 12:34:56 die i mensis xii annoque mmi xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2452245 12 xii 12 12/01/2001 die i mensis xii annoque mmi 01 i 2001}
+test clock-2.1488 {conversion of 2001-12-31} {
+ clock format 1009802096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2001 12:34:56 die xxxi mensis xii annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2452275 12 xii 12 12/31/2001 die xxxi mensis xii annoque mmi 01 i 2001}
+test clock-2.1489 {conversion of 2002-01-01} {
+ clock format 1009888496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2002 12:34:56 die i mensis i annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2452276 01 i 1 01/01/2002 die i mensis i annoque mmii 02 ii 2002}
+test clock-2.1490 {conversion of 2002-01-31} {
+ clock format 1012480496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2002 12:34:56 die xxxi mensis i annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2452306 01 i 1 01/31/2002 die xxxi mensis i annoque mmii 02 ii 2002}
+test clock-2.1491 {conversion of 2002-02-01} {
+ clock format 1012566896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2002 12:34:56 die i mensis ii annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2452307 02 ii 2 02/01/2002 die i mensis ii annoque mmii 02 ii 2002}
+test clock-2.1492 {conversion of 2002-02-28} {
+ clock format 1014899696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2002 12:34:56 die xxviii mensis ii annoque mmii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2452334 02 ii 2 02/28/2002 die xxviii mensis ii annoque mmii 02 ii 2002}
+test clock-2.1493 {conversion of 2002-03-01} {
+ clock format 1014986096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2002 12:34:56 die i mensis iii annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2452335 03 iii 3 03/01/2002 die i mensis iii annoque mmii 02 ii 2002}
+test clock-2.1494 {conversion of 2002-03-31} {
+ clock format 1017578096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2002 12:34:56 die xxxi mensis iii annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2452365 03 iii 3 03/31/2002 die xxxi mensis iii annoque mmii 02 ii 2002}
+test clock-2.1495 {conversion of 2002-04-01} {
+ clock format 1017664496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2002 12:34:56 die i mensis iv annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2452366 04 iv 4 04/01/2002 die i mensis iv annoque mmii 02 ii 2002}
+test clock-2.1496 {conversion of 2002-04-30} {
+ clock format 1020170096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2002 12:34:56 die xxx mensis iv annoque mmii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2452395 04 iv 4 04/30/2002 die xxx mensis iv annoque mmii 02 ii 2002}
+test clock-2.1497 {conversion of 2002-05-01} {
+ clock format 1020256496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2002 12:34:56 die i mensis v annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2452396 05 v 5 05/01/2002 die i mensis v annoque mmii 02 ii 2002}
+test clock-2.1498 {conversion of 2002-05-31} {
+ clock format 1022848496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2002 12:34:56 die xxxi mensis v annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2452426 05 v 5 05/31/2002 die xxxi mensis v annoque mmii 02 ii 2002}
+test clock-2.1499 {conversion of 2002-06-01} {
+ clock format 1022934896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2002 12:34:56 die i mensis vi annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2452427 06 vi 6 06/01/2002 die i mensis vi annoque mmii 02 ii 2002}
+test clock-2.1500 {conversion of 2002-06-30} {
+ clock format 1025440496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2002 12:34:56 die xxx mensis vi annoque mmii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2452456 06 vi 6 06/30/2002 die xxx mensis vi annoque mmii 02 ii 2002}
+test clock-2.1501 {conversion of 2002-07-01} {
+ clock format 1025526896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2002 12:34:56 die i mensis vii annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2452457 07 vii 7 07/01/2002 die i mensis vii annoque mmii 02 ii 2002}
+test clock-2.1502 {conversion of 2002-07-31} {
+ clock format 1028118896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2002 12:34:56 die xxxi mensis vii annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2452487 07 vii 7 07/31/2002 die xxxi mensis vii annoque mmii 02 ii 2002}
+test clock-2.1503 {conversion of 2002-08-01} {
+ clock format 1028205296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2002 12:34:56 die i mensis viii annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2452488 08 viii 8 08/01/2002 die i mensis viii annoque mmii 02 ii 2002}
+test clock-2.1504 {conversion of 2002-08-31} {
+ clock format 1030797296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2002 12:34:56 die xxxi mensis viii annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2452518 08 viii 8 08/31/2002 die xxxi mensis viii annoque mmii 02 ii 2002}
+test clock-2.1505 {conversion of 2002-09-01} {
+ clock format 1030883696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2002 12:34:56 die i mensis ix annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2452519 09 ix 9 09/01/2002 die i mensis ix annoque mmii 02 ii 2002}
+test clock-2.1506 {conversion of 2002-09-30} {
+ clock format 1033389296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2002 12:34:56 die xxx mensis ix annoque mmii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2452548 09 ix 9 09/30/2002 die xxx mensis ix annoque mmii 02 ii 2002}
+test clock-2.1507 {conversion of 2002-10-01} {
+ clock format 1033475696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2002 12:34:56 die i mensis x annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2452549 10 x 10 10/01/2002 die i mensis x annoque mmii 02 ii 2002}
+test clock-2.1508 {conversion of 2002-10-31} {
+ clock format 1036067696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2002 12:34:56 die xxxi mensis x annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2452579 10 x 10 10/31/2002 die xxxi mensis x annoque mmii 02 ii 2002}
+test clock-2.1509 {conversion of 2002-11-01} {
+ clock format 1036154096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2002 12:34:56 die i mensis xi annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2452580 11 xi 11 11/01/2002 die i mensis xi annoque mmii 02 ii 2002}
+test clock-2.1510 {conversion of 2002-11-30} {
+ clock format 1038659696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2002 12:34:56 die xxx mensis xi annoque mmii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2452609 11 xi 11 11/30/2002 die xxx mensis xi annoque mmii 02 ii 2002}
+test clock-2.1511 {conversion of 2002-12-01} {
+ clock format 1038746096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2002 12:34:56 die i mensis xii annoque mmii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2452610 12 xii 12 12/01/2002 die i mensis xii annoque mmii 02 ii 2002}
+test clock-2.1512 {conversion of 2002-12-31} {
+ clock format 1041338096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2002 12:34:56 die xxxi mensis xii annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2452640 12 xii 12 12/31/2002 die xxxi mensis xii annoque mmii 02 ii 2002}
+test clock-2.1513 {conversion of 2003-01-01} {
+ clock format 1041424496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2003 12:34:56 die i mensis i annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2452641 01 i 1 01/01/2003 die i mensis i annoque mmiii 03 iii 2003}
+test clock-2.1514 {conversion of 2003-01-31} {
+ clock format 1044016496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2003 12:34:56 die xxxi mensis i annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2452671 01 i 1 01/31/2003 die xxxi mensis i annoque mmiii 03 iii 2003}
+test clock-2.1515 {conversion of 2003-02-01} {
+ clock format 1044102896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2003 12:34:56 die i mensis ii annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2452672 02 ii 2 02/01/2003 die i mensis ii annoque mmiii 03 iii 2003}
+test clock-2.1516 {conversion of 2003-02-28} {
+ clock format 1046435696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2003 12:34:56 die xxviii mensis ii annoque mmiii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2452699 02 ii 2 02/28/2003 die xxviii mensis ii annoque mmiii 03 iii 2003}
+test clock-2.1517 {conversion of 2003-03-01} {
+ clock format 1046522096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2003 12:34:56 die i mensis iii annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2452700 03 iii 3 03/01/2003 die i mensis iii annoque mmiii 03 iii 2003}
+test clock-2.1518 {conversion of 2003-03-31} {
+ clock format 1049114096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2003 12:34:56 die xxxi mensis iii annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2452730 03 iii 3 03/31/2003 die xxxi mensis iii annoque mmiii 03 iii 2003}
+test clock-2.1519 {conversion of 2003-04-01} {
+ clock format 1049200496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2003 12:34:56 die i mensis iv annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2452731 04 iv 4 04/01/2003 die i mensis iv annoque mmiii 03 iii 2003}
+test clock-2.1520 {conversion of 2003-04-30} {
+ clock format 1051706096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2003 12:34:56 die xxx mensis iv annoque mmiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2452760 04 iv 4 04/30/2003 die xxx mensis iv annoque mmiii 03 iii 2003}
+test clock-2.1521 {conversion of 2003-05-01} {
+ clock format 1051792496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2003 12:34:56 die i mensis v annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2452761 05 v 5 05/01/2003 die i mensis v annoque mmiii 03 iii 2003}
+test clock-2.1522 {conversion of 2003-05-31} {
+ clock format 1054384496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2003 12:34:56 die xxxi mensis v annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2452791 05 v 5 05/31/2003 die xxxi mensis v annoque mmiii 03 iii 2003}
+test clock-2.1523 {conversion of 2003-06-01} {
+ clock format 1054470896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2003 12:34:56 die i mensis vi annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2452792 06 vi 6 06/01/2003 die i mensis vi annoque mmiii 03 iii 2003}
+test clock-2.1524 {conversion of 2003-06-30} {
+ clock format 1056976496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2003 12:34:56 die xxx mensis vi annoque mmiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2452821 06 vi 6 06/30/2003 die xxx mensis vi annoque mmiii 03 iii 2003}
+test clock-2.1525 {conversion of 2003-07-01} {
+ clock format 1057062896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2003 12:34:56 die i mensis vii annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2452822 07 vii 7 07/01/2003 die i mensis vii annoque mmiii 03 iii 2003}
+test clock-2.1526 {conversion of 2003-07-31} {
+ clock format 1059654896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2003 12:34:56 die xxxi mensis vii annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2452852 07 vii 7 07/31/2003 die xxxi mensis vii annoque mmiii 03 iii 2003}
+test clock-2.1527 {conversion of 2003-08-01} {
+ clock format 1059741296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2003 12:34:56 die i mensis viii annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2452853 08 viii 8 08/01/2003 die i mensis viii annoque mmiii 03 iii 2003}
+test clock-2.1528 {conversion of 2003-08-31} {
+ clock format 1062333296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2003 12:34:56 die xxxi mensis viii annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2452883 08 viii 8 08/31/2003 die xxxi mensis viii annoque mmiii 03 iii 2003}
+test clock-2.1529 {conversion of 2003-09-01} {
+ clock format 1062419696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2003 12:34:56 die i mensis ix annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2452884 09 ix 9 09/01/2003 die i mensis ix annoque mmiii 03 iii 2003}
+test clock-2.1530 {conversion of 2003-09-30} {
+ clock format 1064925296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2003 12:34:56 die xxx mensis ix annoque mmiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2452913 09 ix 9 09/30/2003 die xxx mensis ix annoque mmiii 03 iii 2003}
+test clock-2.1531 {conversion of 2003-10-01} {
+ clock format 1065011696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2003 12:34:56 die i mensis x annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2452914 10 x 10 10/01/2003 die i mensis x annoque mmiii 03 iii 2003}
+test clock-2.1532 {conversion of 2003-10-31} {
+ clock format 1067603696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2003 12:34:56 die xxxi mensis x annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2452944 10 x 10 10/31/2003 die xxxi mensis x annoque mmiii 03 iii 2003}
+test clock-2.1533 {conversion of 2003-11-01} {
+ clock format 1067690096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2003 12:34:56 die i mensis xi annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2452945 11 xi 11 11/01/2003 die i mensis xi annoque mmiii 03 iii 2003}
+test clock-2.1534 {conversion of 2003-11-30} {
+ clock format 1070195696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2003 12:34:56 die xxx mensis xi annoque mmiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2452974 11 xi 11 11/30/2003 die xxx mensis xi annoque mmiii 03 iii 2003}
+test clock-2.1535 {conversion of 2003-12-01} {
+ clock format 1070282096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2003 12:34:56 die i mensis xii annoque mmiii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2452975 12 xii 12 12/01/2003 die i mensis xii annoque mmiii 03 iii 2003}
+test clock-2.1536 {conversion of 2003-12-31} {
+ clock format 1072874096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2003 12:34:56 die xxxi mensis xii annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2453005 12 xii 12 12/31/2003 die xxxi mensis xii annoque mmiii 03 iii 2003}
+test clock-2.1537 {conversion of 2004-01-01} {
+ clock format 1072960496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2004 12:34:56 die i mensis i annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2453006 01 i 1 01/01/2004 die i mensis i annoque mmiv 04 iv 2004}
+test clock-2.1538 {conversion of 2004-01-31} {
+ clock format 1075552496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2004 12:34:56 die xxxi mensis i annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2453036 01 i 1 01/31/2004 die xxxi mensis i annoque mmiv 04 iv 2004}
+test clock-2.1539 {conversion of 2004-02-01} {
+ clock format 1075638896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2004 12:34:56 die i mensis ii annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2453037 02 ii 2 02/01/2004 die i mensis ii annoque mmiv 04 iv 2004}
+test clock-2.1540 {conversion of 2004-02-29} {
+ clock format 1078058096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2004 12:34:56 die xxix mensis ii annoque mmiv xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2453065 02 ii 2 02/29/2004 die xxix mensis ii annoque mmiv 04 iv 2004}
+test clock-2.1541 {conversion of 2004-03-01} {
+ clock format 1078144496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2004 12:34:56 die i mensis iii annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2453066 03 iii 3 03/01/2004 die i mensis iii annoque mmiv 04 iv 2004}
+test clock-2.1542 {conversion of 2004-03-31} {
+ clock format 1080736496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2004 12:34:56 die xxxi mensis iii annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2453096 03 iii 3 03/31/2004 die xxxi mensis iii annoque mmiv 04 iv 2004}
+test clock-2.1543 {conversion of 2004-04-01} {
+ clock format 1080822896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2004 12:34:56 die i mensis iv annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2453097 04 iv 4 04/01/2004 die i mensis iv annoque mmiv 04 iv 2004}
+test clock-2.1544 {conversion of 2004-04-30} {
+ clock format 1083328496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2004 12:34:56 die xxx mensis iv annoque mmiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2453126 04 iv 4 04/30/2004 die xxx mensis iv annoque mmiv 04 iv 2004}
+test clock-2.1545 {conversion of 2004-05-01} {
+ clock format 1083414896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2004 12:34:56 die i mensis v annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2453127 05 v 5 05/01/2004 die i mensis v annoque mmiv 04 iv 2004}
+test clock-2.1546 {conversion of 2004-05-31} {
+ clock format 1086006896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2004 12:34:56 die xxxi mensis v annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2453157 05 v 5 05/31/2004 die xxxi mensis v annoque mmiv 04 iv 2004}
+test clock-2.1547 {conversion of 2004-06-01} {
+ clock format 1086093296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2004 12:34:56 die i mensis vi annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2453158 06 vi 6 06/01/2004 die i mensis vi annoque mmiv 04 iv 2004}
+test clock-2.1548 {conversion of 2004-06-30} {
+ clock format 1088598896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2004 12:34:56 die xxx mensis vi annoque mmiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2453187 06 vi 6 06/30/2004 die xxx mensis vi annoque mmiv 04 iv 2004}
+test clock-2.1549 {conversion of 2004-07-01} {
+ clock format 1088685296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2004 12:34:56 die i mensis vii annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2453188 07 vii 7 07/01/2004 die i mensis vii annoque mmiv 04 iv 2004}
+test clock-2.1550 {conversion of 2004-07-31} {
+ clock format 1091277296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2004 12:34:56 die xxxi mensis vii annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2453218 07 vii 7 07/31/2004 die xxxi mensis vii annoque mmiv 04 iv 2004}
+test clock-2.1551 {conversion of 2004-08-01} {
+ clock format 1091363696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2004 12:34:56 die i mensis viii annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2453219 08 viii 8 08/01/2004 die i mensis viii annoque mmiv 04 iv 2004}
+test clock-2.1552 {conversion of 2004-08-31} {
+ clock format 1093955696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2004 12:34:56 die xxxi mensis viii annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2453249 08 viii 8 08/31/2004 die xxxi mensis viii annoque mmiv 04 iv 2004}
+test clock-2.1553 {conversion of 2004-09-01} {
+ clock format 1094042096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2004 12:34:56 die i mensis ix annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2453250 09 ix 9 09/01/2004 die i mensis ix annoque mmiv 04 iv 2004}
+test clock-2.1554 {conversion of 2004-09-30} {
+ clock format 1096547696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2004 12:34:56 die xxx mensis ix annoque mmiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2453279 09 ix 9 09/30/2004 die xxx mensis ix annoque mmiv 04 iv 2004}
+test clock-2.1555 {conversion of 2004-10-01} {
+ clock format 1096634096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2004 12:34:56 die i mensis x annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2453280 10 x 10 10/01/2004 die i mensis x annoque mmiv 04 iv 2004}
+test clock-2.1556 {conversion of 2004-10-31} {
+ clock format 1099226096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2004 12:34:56 die xxxi mensis x annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2453310 10 x 10 10/31/2004 die xxxi mensis x annoque mmiv 04 iv 2004}
+test clock-2.1557 {conversion of 2004-11-01} {
+ clock format 1099312496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2004 12:34:56 die i mensis xi annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2453311 11 xi 11 11/01/2004 die i mensis xi annoque mmiv 04 iv 2004}
+test clock-2.1558 {conversion of 2004-11-30} {
+ clock format 1101818096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2004 12:34:56 die xxx mensis xi annoque mmiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2453340 11 xi 11 11/30/2004 die xxx mensis xi annoque mmiv 04 iv 2004}
+test clock-2.1559 {conversion of 2004-12-01} {
+ clock format 1101904496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2004 12:34:56 die i mensis xii annoque mmiv xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2453341 12 xii 12 12/01/2004 die i mensis xii annoque mmiv 04 iv 2004}
+test clock-2.1560 {conversion of 2004-12-31} {
+ clock format 1104496496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2004 12:34:56 die xxxi mensis xii annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2453371 12 xii 12 12/31/2004 die xxxi mensis xii annoque mmiv 04 iv 2004}
+test clock-2.1561 {conversion of 2005-01-01} {
+ clock format 1104582896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2005 12:34:56 die i mensis i annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2453372 01 i 1 01/01/2005 die i mensis i annoque mmv 05 v 2005}
+test clock-2.1562 {conversion of 2005-01-31} {
+ clock format 1107174896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2005 12:34:56 die xxxi mensis i annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2453402 01 i 1 01/31/2005 die xxxi mensis i annoque mmv 05 v 2005}
+test clock-2.1563 {conversion of 2005-02-01} {
+ clock format 1107261296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2005 12:34:56 die i mensis ii annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2453403 02 ii 2 02/01/2005 die i mensis ii annoque mmv 05 v 2005}
+test clock-2.1564 {conversion of 2005-02-28} {
+ clock format 1109594096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2005 12:34:56 die xxviii mensis ii annoque mmv xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2453430 02 ii 2 02/28/2005 die xxviii mensis ii annoque mmv 05 v 2005}
+test clock-2.1565 {conversion of 2005-03-01} {
+ clock format 1109680496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2005 12:34:56 die i mensis iii annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2453431 03 iii 3 03/01/2005 die i mensis iii annoque mmv 05 v 2005}
+test clock-2.1566 {conversion of 2005-03-31} {
+ clock format 1112272496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2005 12:34:56 die xxxi mensis iii annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2453461 03 iii 3 03/31/2005 die xxxi mensis iii annoque mmv 05 v 2005}
+test clock-2.1567 {conversion of 2005-04-01} {
+ clock format 1112358896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2005 12:34:56 die i mensis iv annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2453462 04 iv 4 04/01/2005 die i mensis iv annoque mmv 05 v 2005}
+test clock-2.1568 {conversion of 2005-04-30} {
+ clock format 1114864496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2005 12:34:56 die xxx mensis iv annoque mmv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2453491 04 iv 4 04/30/2005 die xxx mensis iv annoque mmv 05 v 2005}
+test clock-2.1569 {conversion of 2005-05-01} {
+ clock format 1114950896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2005 12:34:56 die i mensis v annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2453492 05 v 5 05/01/2005 die i mensis v annoque mmv 05 v 2005}
+test clock-2.1570 {conversion of 2005-05-31} {
+ clock format 1117542896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2005 12:34:56 die xxxi mensis v annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2453522 05 v 5 05/31/2005 die xxxi mensis v annoque mmv 05 v 2005}
+test clock-2.1571 {conversion of 2005-06-01} {
+ clock format 1117629296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2005 12:34:56 die i mensis vi annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2453523 06 vi 6 06/01/2005 die i mensis vi annoque mmv 05 v 2005}
+test clock-2.1572 {conversion of 2005-06-30} {
+ clock format 1120134896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2005 12:34:56 die xxx mensis vi annoque mmv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2453552 06 vi 6 06/30/2005 die xxx mensis vi annoque mmv 05 v 2005}
+test clock-2.1573 {conversion of 2005-07-01} {
+ clock format 1120221296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2005 12:34:56 die i mensis vii annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2453553 07 vii 7 07/01/2005 die i mensis vii annoque mmv 05 v 2005}
+test clock-2.1574 {conversion of 2005-07-31} {
+ clock format 1122813296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2005 12:34:56 die xxxi mensis vii annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2453583 07 vii 7 07/31/2005 die xxxi mensis vii annoque mmv 05 v 2005}
+test clock-2.1575 {conversion of 2005-08-01} {
+ clock format 1122899696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2005 12:34:56 die i mensis viii annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2453584 08 viii 8 08/01/2005 die i mensis viii annoque mmv 05 v 2005}
+test clock-2.1576 {conversion of 2005-08-31} {
+ clock format 1125491696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2005 12:34:56 die xxxi mensis viii annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2453614 08 viii 8 08/31/2005 die xxxi mensis viii annoque mmv 05 v 2005}
+test clock-2.1577 {conversion of 2005-09-01} {
+ clock format 1125578096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2005 12:34:56 die i mensis ix annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2453615 09 ix 9 09/01/2005 die i mensis ix annoque mmv 05 v 2005}
+test clock-2.1578 {conversion of 2005-09-30} {
+ clock format 1128083696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2005 12:34:56 die xxx mensis ix annoque mmv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2453644 09 ix 9 09/30/2005 die xxx mensis ix annoque mmv 05 v 2005}
+test clock-2.1579 {conversion of 2005-10-01} {
+ clock format 1128170096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2005 12:34:56 die i mensis x annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2453645 10 x 10 10/01/2005 die i mensis x annoque mmv 05 v 2005}
+test clock-2.1580 {conversion of 2005-10-31} {
+ clock format 1130762096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2005 12:34:56 die xxxi mensis x annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2453675 10 x 10 10/31/2005 die xxxi mensis x annoque mmv 05 v 2005}
+test clock-2.1581 {conversion of 2005-11-01} {
+ clock format 1130848496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2005 12:34:56 die i mensis xi annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2453676 11 xi 11 11/01/2005 die i mensis xi annoque mmv 05 v 2005}
+test clock-2.1582 {conversion of 2005-11-30} {
+ clock format 1133354096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2005 12:34:56 die xxx mensis xi annoque mmv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2453705 11 xi 11 11/30/2005 die xxx mensis xi annoque mmv 05 v 2005}
+test clock-2.1583 {conversion of 2005-12-01} {
+ clock format 1133440496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2005 12:34:56 die i mensis xii annoque mmv xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2453706 12 xii 12 12/01/2005 die i mensis xii annoque mmv 05 v 2005}
+test clock-2.1584 {conversion of 2005-12-31} {
+ clock format 1136032496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2005 12:34:56 die xxxi mensis xii annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2453736 12 xii 12 12/31/2005 die xxxi mensis xii annoque mmv 05 v 2005}
+test clock-2.1585 {conversion of 2006-01-01} {
+ clock format 1136118896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2006 12:34:56 die i mensis i annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2453737 01 i 1 01/01/2006 die i mensis i annoque mmvi 06 vi 2006}
+test clock-2.1586 {conversion of 2006-01-31} {
+ clock format 1138710896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2006 12:34:56 die xxxi mensis i annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2453767 01 i 1 01/31/2006 die xxxi mensis i annoque mmvi 06 vi 2006}
+test clock-2.1587 {conversion of 2006-02-01} {
+ clock format 1138797296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2006 12:34:56 die i mensis ii annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2453768 02 ii 2 02/01/2006 die i mensis ii annoque mmvi 06 vi 2006}
+test clock-2.1588 {conversion of 2006-02-28} {
+ clock format 1141130096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2006 12:34:56 die xxviii mensis ii annoque mmvi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2453795 02 ii 2 02/28/2006 die xxviii mensis ii annoque mmvi 06 vi 2006}
+test clock-2.1589 {conversion of 2006-03-01} {
+ clock format 1141216496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2006 12:34:56 die i mensis iii annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2453796 03 iii 3 03/01/2006 die i mensis iii annoque mmvi 06 vi 2006}
+test clock-2.1590 {conversion of 2006-03-31} {
+ clock format 1143808496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2006 12:34:56 die xxxi mensis iii annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2453826 03 iii 3 03/31/2006 die xxxi mensis iii annoque mmvi 06 vi 2006}
+test clock-2.1591 {conversion of 2006-04-01} {
+ clock format 1143894896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2006 12:34:56 die i mensis iv annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2453827 04 iv 4 04/01/2006 die i mensis iv annoque mmvi 06 vi 2006}
+test clock-2.1592 {conversion of 2006-04-30} {
+ clock format 1146400496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2006 12:34:56 die xxx mensis iv annoque mmvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2453856 04 iv 4 04/30/2006 die xxx mensis iv annoque mmvi 06 vi 2006}
+test clock-2.1593 {conversion of 2006-05-01} {
+ clock format 1146486896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2006 12:34:56 die i mensis v annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2453857 05 v 5 05/01/2006 die i mensis v annoque mmvi 06 vi 2006}
+test clock-2.1594 {conversion of 2006-05-31} {
+ clock format 1149078896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2006 12:34:56 die xxxi mensis v annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2453887 05 v 5 05/31/2006 die xxxi mensis v annoque mmvi 06 vi 2006}
+test clock-2.1595 {conversion of 2006-06-01} {
+ clock format 1149165296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2006 12:34:56 die i mensis vi annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2453888 06 vi 6 06/01/2006 die i mensis vi annoque mmvi 06 vi 2006}
+test clock-2.1596 {conversion of 2006-06-30} {
+ clock format 1151670896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2006 12:34:56 die xxx mensis vi annoque mmvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2453917 06 vi 6 06/30/2006 die xxx mensis vi annoque mmvi 06 vi 2006}
+test clock-2.1597 {conversion of 2006-07-01} {
+ clock format 1151757296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2006 12:34:56 die i mensis vii annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2453918 07 vii 7 07/01/2006 die i mensis vii annoque mmvi 06 vi 2006}
+test clock-2.1598 {conversion of 2006-07-31} {
+ clock format 1154349296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2006 12:34:56 die xxxi mensis vii annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2453948 07 vii 7 07/31/2006 die xxxi mensis vii annoque mmvi 06 vi 2006}
+test clock-2.1599 {conversion of 2006-08-01} {
+ clock format 1154435696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2006 12:34:56 die i mensis viii annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2453949 08 viii 8 08/01/2006 die i mensis viii annoque mmvi 06 vi 2006}
+test clock-2.1600 {conversion of 2006-08-31} {
+ clock format 1157027696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2006 12:34:56 die xxxi mensis viii annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2453979 08 viii 8 08/31/2006 die xxxi mensis viii annoque mmvi 06 vi 2006}
+test clock-2.1601 {conversion of 2006-09-01} {
+ clock format 1157114096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2006 12:34:56 die i mensis ix annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2453980 09 ix 9 09/01/2006 die i mensis ix annoque mmvi 06 vi 2006}
+test clock-2.1602 {conversion of 2006-09-30} {
+ clock format 1159619696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2006 12:34:56 die xxx mensis ix annoque mmvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2454009 09 ix 9 09/30/2006 die xxx mensis ix annoque mmvi 06 vi 2006}
+test clock-2.1603 {conversion of 2006-10-01} {
+ clock format 1159706096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2006 12:34:56 die i mensis x annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2454010 10 x 10 10/01/2006 die i mensis x annoque mmvi 06 vi 2006}
+test clock-2.1604 {conversion of 2006-10-31} {
+ clock format 1162298096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2006 12:34:56 die xxxi mensis x annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2454040 10 x 10 10/31/2006 die xxxi mensis x annoque mmvi 06 vi 2006}
+test clock-2.1605 {conversion of 2006-11-01} {
+ clock format 1162384496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2006 12:34:56 die i mensis xi annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2454041 11 xi 11 11/01/2006 die i mensis xi annoque mmvi 06 vi 2006}
+test clock-2.1606 {conversion of 2006-11-30} {
+ clock format 1164890096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2006 12:34:56 die xxx mensis xi annoque mmvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2454070 11 xi 11 11/30/2006 die xxx mensis xi annoque mmvi 06 vi 2006}
+test clock-2.1607 {conversion of 2006-12-01} {
+ clock format 1164976496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2006 12:34:56 die i mensis xii annoque mmvi xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2454071 12 xii 12 12/01/2006 die i mensis xii annoque mmvi 06 vi 2006}
+test clock-2.1608 {conversion of 2006-12-31} {
+ clock format 1167568496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2006 12:34:56 die xxxi mensis xii annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2454101 12 xii 12 12/31/2006 die xxxi mensis xii annoque mmvi 06 vi 2006}
+test clock-2.1609 {conversion of 2007-01-01} {
+ clock format 1167654896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2007 12:34:56 die i mensis i annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2454102 01 i 1 01/01/2007 die i mensis i annoque mmvii 07 vii 2007}
+test clock-2.1610 {conversion of 2007-01-31} {
+ clock format 1170246896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2007 12:34:56 die xxxi mensis i annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2454132 01 i 1 01/31/2007 die xxxi mensis i annoque mmvii 07 vii 2007}
+test clock-2.1611 {conversion of 2007-02-01} {
+ clock format 1170333296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2007 12:34:56 die i mensis ii annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2454133 02 ii 2 02/01/2007 die i mensis ii annoque mmvii 07 vii 2007}
+test clock-2.1612 {conversion of 2007-02-28} {
+ clock format 1172666096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2007 12:34:56 die xxviii mensis ii annoque mmvii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2454160 02 ii 2 02/28/2007 die xxviii mensis ii annoque mmvii 07 vii 2007}
+test clock-2.1613 {conversion of 2007-03-01} {
+ clock format 1172752496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2007 12:34:56 die i mensis iii annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2454161 03 iii 3 03/01/2007 die i mensis iii annoque mmvii 07 vii 2007}
+test clock-2.1614 {conversion of 2007-03-31} {
+ clock format 1175344496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2007 12:34:56 die xxxi mensis iii annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2454191 03 iii 3 03/31/2007 die xxxi mensis iii annoque mmvii 07 vii 2007}
+test clock-2.1615 {conversion of 2007-04-01} {
+ clock format 1175430896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2007 12:34:56 die i mensis iv annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2454192 04 iv 4 04/01/2007 die i mensis iv annoque mmvii 07 vii 2007}
+test clock-2.1616 {conversion of 2007-04-30} {
+ clock format 1177936496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2007 12:34:56 die xxx mensis iv annoque mmvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2454221 04 iv 4 04/30/2007 die xxx mensis iv annoque mmvii 07 vii 2007}
+test clock-2.1617 {conversion of 2007-05-01} {
+ clock format 1178022896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2007 12:34:56 die i mensis v annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2454222 05 v 5 05/01/2007 die i mensis v annoque mmvii 07 vii 2007}
+test clock-2.1618 {conversion of 2007-05-31} {
+ clock format 1180614896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2007 12:34:56 die xxxi mensis v annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2454252 05 v 5 05/31/2007 die xxxi mensis v annoque mmvii 07 vii 2007}
+test clock-2.1619 {conversion of 2007-06-01} {
+ clock format 1180701296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2007 12:34:56 die i mensis vi annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2454253 06 vi 6 06/01/2007 die i mensis vi annoque mmvii 07 vii 2007}
+test clock-2.1620 {conversion of 2007-06-30} {
+ clock format 1183206896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2007 12:34:56 die xxx mensis vi annoque mmvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2454282 06 vi 6 06/30/2007 die xxx mensis vi annoque mmvii 07 vii 2007}
+test clock-2.1621 {conversion of 2007-07-01} {
+ clock format 1183293296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2007 12:34:56 die i mensis vii annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2454283 07 vii 7 07/01/2007 die i mensis vii annoque mmvii 07 vii 2007}
+test clock-2.1622 {conversion of 2007-07-31} {
+ clock format 1185885296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2007 12:34:56 die xxxi mensis vii annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2454313 07 vii 7 07/31/2007 die xxxi mensis vii annoque mmvii 07 vii 2007}
+test clock-2.1623 {conversion of 2007-08-01} {
+ clock format 1185971696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2007 12:34:56 die i mensis viii annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2454314 08 viii 8 08/01/2007 die i mensis viii annoque mmvii 07 vii 2007}
+test clock-2.1624 {conversion of 2007-08-31} {
+ clock format 1188563696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2007 12:34:56 die xxxi mensis viii annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2454344 08 viii 8 08/31/2007 die xxxi mensis viii annoque mmvii 07 vii 2007}
+test clock-2.1625 {conversion of 2007-09-01} {
+ clock format 1188650096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2007 12:34:56 die i mensis ix annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2454345 09 ix 9 09/01/2007 die i mensis ix annoque mmvii 07 vii 2007}
+test clock-2.1626 {conversion of 2007-09-30} {
+ clock format 1191155696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2007 12:34:56 die xxx mensis ix annoque mmvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2454374 09 ix 9 09/30/2007 die xxx mensis ix annoque mmvii 07 vii 2007}
+test clock-2.1627 {conversion of 2007-10-01} {
+ clock format 1191242096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2007 12:34:56 die i mensis x annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2454375 10 x 10 10/01/2007 die i mensis x annoque mmvii 07 vii 2007}
+test clock-2.1628 {conversion of 2007-10-31} {
+ clock format 1193834096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2007 12:34:56 die xxxi mensis x annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2454405 10 x 10 10/31/2007 die xxxi mensis x annoque mmvii 07 vii 2007}
+test clock-2.1629 {conversion of 2007-11-01} {
+ clock format 1193920496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2007 12:34:56 die i mensis xi annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2454406 11 xi 11 11/01/2007 die i mensis xi annoque mmvii 07 vii 2007}
+test clock-2.1630 {conversion of 2007-11-30} {
+ clock format 1196426096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2007 12:34:56 die xxx mensis xi annoque mmvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2454435 11 xi 11 11/30/2007 die xxx mensis xi annoque mmvii 07 vii 2007}
+test clock-2.1631 {conversion of 2007-12-01} {
+ clock format 1196512496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2007 12:34:56 die i mensis xii annoque mmvii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2454436 12 xii 12 12/01/2007 die i mensis xii annoque mmvii 07 vii 2007}
+test clock-2.1632 {conversion of 2007-12-31} {
+ clock format 1199104496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2007 12:34:56 die xxxi mensis xii annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2454466 12 xii 12 12/31/2007 die xxxi mensis xii annoque mmvii 07 vii 2007}
+test clock-2.1633 {conversion of 2008-01-01} {
+ clock format 1199190896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2008 12:34:56 die i mensis i annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2454467 01 i 1 01/01/2008 die i mensis i annoque mmviii 08 viii 2008}
+test clock-2.1634 {conversion of 2008-01-31} {
+ clock format 1201782896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2008 12:34:56 die xxxi mensis i annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2454497 01 i 1 01/31/2008 die xxxi mensis i annoque mmviii 08 viii 2008}
+test clock-2.1635 {conversion of 2008-02-01} {
+ clock format 1201869296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2008 12:34:56 die i mensis ii annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2454498 02 ii 2 02/01/2008 die i mensis ii annoque mmviii 08 viii 2008}
+test clock-2.1636 {conversion of 2008-02-29} {
+ clock format 1204288496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2008 12:34:56 die xxix mensis ii annoque mmviii xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2454526 02 ii 2 02/29/2008 die xxix mensis ii annoque mmviii 08 viii 2008}
+test clock-2.1637 {conversion of 2008-03-01} {
+ clock format 1204374896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2008 12:34:56 die i mensis iii annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2454527 03 iii 3 03/01/2008 die i mensis iii annoque mmviii 08 viii 2008}
+test clock-2.1638 {conversion of 2008-03-31} {
+ clock format 1206966896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2008 12:34:56 die xxxi mensis iii annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2454557 03 iii 3 03/31/2008 die xxxi mensis iii annoque mmviii 08 viii 2008}
+test clock-2.1639 {conversion of 2008-04-01} {
+ clock format 1207053296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2008 12:34:56 die i mensis iv annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2454558 04 iv 4 04/01/2008 die i mensis iv annoque mmviii 08 viii 2008}
+test clock-2.1640 {conversion of 2008-04-30} {
+ clock format 1209558896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2008 12:34:56 die xxx mensis iv annoque mmviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2454587 04 iv 4 04/30/2008 die xxx mensis iv annoque mmviii 08 viii 2008}
+test clock-2.1641 {conversion of 2008-05-01} {
+ clock format 1209645296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2008 12:34:56 die i mensis v annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2454588 05 v 5 05/01/2008 die i mensis v annoque mmviii 08 viii 2008}
+test clock-2.1642 {conversion of 2008-05-31} {
+ clock format 1212237296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2008 12:34:56 die xxxi mensis v annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2454618 05 v 5 05/31/2008 die xxxi mensis v annoque mmviii 08 viii 2008}
+test clock-2.1643 {conversion of 2008-06-01} {
+ clock format 1212323696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2008 12:34:56 die i mensis vi annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2454619 06 vi 6 06/01/2008 die i mensis vi annoque mmviii 08 viii 2008}
+test clock-2.1644 {conversion of 2008-06-30} {
+ clock format 1214829296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2008 12:34:56 die xxx mensis vi annoque mmviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2454648 06 vi 6 06/30/2008 die xxx mensis vi annoque mmviii 08 viii 2008}
+test clock-2.1645 {conversion of 2008-07-01} {
+ clock format 1214915696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2008 12:34:56 die i mensis vii annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2454649 07 vii 7 07/01/2008 die i mensis vii annoque mmviii 08 viii 2008}
+test clock-2.1646 {conversion of 2008-07-31} {
+ clock format 1217507696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2008 12:34:56 die xxxi mensis vii annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2454679 07 vii 7 07/31/2008 die xxxi mensis vii annoque mmviii 08 viii 2008}
+test clock-2.1647 {conversion of 2008-08-01} {
+ clock format 1217594096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2008 12:34:56 die i mensis viii annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2454680 08 viii 8 08/01/2008 die i mensis viii annoque mmviii 08 viii 2008}
+test clock-2.1648 {conversion of 2008-08-31} {
+ clock format 1220186096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2008 12:34:56 die xxxi mensis viii annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2454710 08 viii 8 08/31/2008 die xxxi mensis viii annoque mmviii 08 viii 2008}
+test clock-2.1649 {conversion of 2008-09-01} {
+ clock format 1220272496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2008 12:34:56 die i mensis ix annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2454711 09 ix 9 09/01/2008 die i mensis ix annoque mmviii 08 viii 2008}
+test clock-2.1650 {conversion of 2008-09-30} {
+ clock format 1222778096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2008 12:34:56 die xxx mensis ix annoque mmviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2454740 09 ix 9 09/30/2008 die xxx mensis ix annoque mmviii 08 viii 2008}
+test clock-2.1651 {conversion of 2008-10-01} {
+ clock format 1222864496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2008 12:34:56 die i mensis x annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2454741 10 x 10 10/01/2008 die i mensis x annoque mmviii 08 viii 2008}
+test clock-2.1652 {conversion of 2008-10-31} {
+ clock format 1225456496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2008 12:34:56 die xxxi mensis x annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2454771 10 x 10 10/31/2008 die xxxi mensis x annoque mmviii 08 viii 2008}
+test clock-2.1653 {conversion of 2008-11-01} {
+ clock format 1225542896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2008 12:34:56 die i mensis xi annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2454772 11 xi 11 11/01/2008 die i mensis xi annoque mmviii 08 viii 2008}
+test clock-2.1654 {conversion of 2008-11-30} {
+ clock format 1228048496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2008 12:34:56 die xxx mensis xi annoque mmviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2454801 11 xi 11 11/30/2008 die xxx mensis xi annoque mmviii 08 viii 2008}
+test clock-2.1655 {conversion of 2008-12-01} {
+ clock format 1228134896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2008 12:34:56 die i mensis xii annoque mmviii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2454802 12 xii 12 12/01/2008 die i mensis xii annoque mmviii 08 viii 2008}
+test clock-2.1656 {conversion of 2008-12-31} {
+ clock format 1230726896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2008 12:34:56 die xxxi mensis xii annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2454832 12 xii 12 12/31/2008 die xxxi mensis xii annoque mmviii 08 viii 2008}
+test clock-2.1657 {conversion of 2009-01-01} {
+ clock format 1230813296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2009 12:34:56 die i mensis i annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2454833 01 i 1 01/01/2009 die i mensis i annoque mmix 09 ix 2009}
+test clock-2.1658 {conversion of 2009-01-31} {
+ clock format 1233405296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2009 12:34:56 die xxxi mensis i annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2454863 01 i 1 01/31/2009 die xxxi mensis i annoque mmix 09 ix 2009}
+test clock-2.1659 {conversion of 2009-02-01} {
+ clock format 1233491696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2009 12:34:56 die i mensis ii annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2454864 02 ii 2 02/01/2009 die i mensis ii annoque mmix 09 ix 2009}
+test clock-2.1660 {conversion of 2009-02-28} {
+ clock format 1235824496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2009 12:34:56 die xxviii mensis ii annoque mmix xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2454891 02 ii 2 02/28/2009 die xxviii mensis ii annoque mmix 09 ix 2009}
+test clock-2.1661 {conversion of 2009-03-01} {
+ clock format 1235910896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2009 12:34:56 die i mensis iii annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2454892 03 iii 3 03/01/2009 die i mensis iii annoque mmix 09 ix 2009}
+test clock-2.1662 {conversion of 2009-03-31} {
+ clock format 1238502896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2009 12:34:56 die xxxi mensis iii annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2454922 03 iii 3 03/31/2009 die xxxi mensis iii annoque mmix 09 ix 2009}
+test clock-2.1663 {conversion of 2009-04-01} {
+ clock format 1238589296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2009 12:34:56 die i mensis iv annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2454923 04 iv 4 04/01/2009 die i mensis iv annoque mmix 09 ix 2009}
+test clock-2.1664 {conversion of 2009-04-30} {
+ clock format 1241094896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2009 12:34:56 die xxx mensis iv annoque mmix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2454952 04 iv 4 04/30/2009 die xxx mensis iv annoque mmix 09 ix 2009}
+test clock-2.1665 {conversion of 2009-05-01} {
+ clock format 1241181296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2009 12:34:56 die i mensis v annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2454953 05 v 5 05/01/2009 die i mensis v annoque mmix 09 ix 2009}
+test clock-2.1666 {conversion of 2009-05-31} {
+ clock format 1243773296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2009 12:34:56 die xxxi mensis v annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2454983 05 v 5 05/31/2009 die xxxi mensis v annoque mmix 09 ix 2009}
+test clock-2.1667 {conversion of 2009-06-01} {
+ clock format 1243859696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2009 12:34:56 die i mensis vi annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2454984 06 vi 6 06/01/2009 die i mensis vi annoque mmix 09 ix 2009}
+test clock-2.1668 {conversion of 2009-06-30} {
+ clock format 1246365296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2009 12:34:56 die xxx mensis vi annoque mmix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2455013 06 vi 6 06/30/2009 die xxx mensis vi annoque mmix 09 ix 2009}
+test clock-2.1669 {conversion of 2009-07-01} {
+ clock format 1246451696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2009 12:34:56 die i mensis vii annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2455014 07 vii 7 07/01/2009 die i mensis vii annoque mmix 09 ix 2009}
+test clock-2.1670 {conversion of 2009-07-31} {
+ clock format 1249043696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2009 12:34:56 die xxxi mensis vii annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2455044 07 vii 7 07/31/2009 die xxxi mensis vii annoque mmix 09 ix 2009}
+test clock-2.1671 {conversion of 2009-08-01} {
+ clock format 1249130096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2009 12:34:56 die i mensis viii annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2455045 08 viii 8 08/01/2009 die i mensis viii annoque mmix 09 ix 2009}
+test clock-2.1672 {conversion of 2009-08-31} {
+ clock format 1251722096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2009 12:34:56 die xxxi mensis viii annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2455075 08 viii 8 08/31/2009 die xxxi mensis viii annoque mmix 09 ix 2009}
+test clock-2.1673 {conversion of 2009-09-01} {
+ clock format 1251808496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2009 12:34:56 die i mensis ix annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2455076 09 ix 9 09/01/2009 die i mensis ix annoque mmix 09 ix 2009}
+test clock-2.1674 {conversion of 2009-09-30} {
+ clock format 1254314096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2009 12:34:56 die xxx mensis ix annoque mmix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2455105 09 ix 9 09/30/2009 die xxx mensis ix annoque mmix 09 ix 2009}
+test clock-2.1675 {conversion of 2009-10-01} {
+ clock format 1254400496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2009 12:34:56 die i mensis x annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2455106 10 x 10 10/01/2009 die i mensis x annoque mmix 09 ix 2009}
+test clock-2.1676 {conversion of 2009-10-31} {
+ clock format 1256992496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2009 12:34:56 die xxxi mensis x annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2455136 10 x 10 10/31/2009 die xxxi mensis x annoque mmix 09 ix 2009}
+test clock-2.1677 {conversion of 2009-11-01} {
+ clock format 1257078896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2009 12:34:56 die i mensis xi annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2455137 11 xi 11 11/01/2009 die i mensis xi annoque mmix 09 ix 2009}
+test clock-2.1678 {conversion of 2009-11-30} {
+ clock format 1259584496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2009 12:34:56 die xxx mensis xi annoque mmix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2455166 11 xi 11 11/30/2009 die xxx mensis xi annoque mmix 09 ix 2009}
+test clock-2.1679 {conversion of 2009-12-01} {
+ clock format 1259670896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2009 12:34:56 die i mensis xii annoque mmix xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2455167 12 xii 12 12/01/2009 die i mensis xii annoque mmix 09 ix 2009}
+test clock-2.1680 {conversion of 2009-12-31} {
+ clock format 1262262896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2009 12:34:56 die xxxi mensis xii annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2455197 12 xii 12 12/31/2009 die xxxi mensis xii annoque mmix 09 ix 2009}
+test clock-2.1681 {conversion of 2010-01-01} {
+ clock format 1262349296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2010 12:34:56 die i mensis i annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2455198 01 i 1 01/01/2010 die i mensis i annoque mmx 10 x 2010}
+test clock-2.1682 {conversion of 2010-01-31} {
+ clock format 1264941296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2010 12:34:56 die xxxi mensis i annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2455228 01 i 1 01/31/2010 die xxxi mensis i annoque mmx 10 x 2010}
+test clock-2.1683 {conversion of 2010-02-01} {
+ clock format 1265027696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2010 12:34:56 die i mensis ii annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2455229 02 ii 2 02/01/2010 die i mensis ii annoque mmx 10 x 2010}
+test clock-2.1684 {conversion of 2010-02-28} {
+ clock format 1267360496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2010 12:34:56 die xxviii mensis ii annoque mmx xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2455256 02 ii 2 02/28/2010 die xxviii mensis ii annoque mmx 10 x 2010}
+test clock-2.1685 {conversion of 2010-03-01} {
+ clock format 1267446896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2010 12:34:56 die i mensis iii annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2455257 03 iii 3 03/01/2010 die i mensis iii annoque mmx 10 x 2010}
+test clock-2.1686 {conversion of 2010-03-31} {
+ clock format 1270038896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2010 12:34:56 die xxxi mensis iii annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2455287 03 iii 3 03/31/2010 die xxxi mensis iii annoque mmx 10 x 2010}
+test clock-2.1687 {conversion of 2010-04-01} {
+ clock format 1270125296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2010 12:34:56 die i mensis iv annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2455288 04 iv 4 04/01/2010 die i mensis iv annoque mmx 10 x 2010}
+test clock-2.1688 {conversion of 2010-04-30} {
+ clock format 1272630896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2010 12:34:56 die xxx mensis iv annoque mmx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2455317 04 iv 4 04/30/2010 die xxx mensis iv annoque mmx 10 x 2010}
+test clock-2.1689 {conversion of 2010-05-01} {
+ clock format 1272717296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2010 12:34:56 die i mensis v annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2455318 05 v 5 05/01/2010 die i mensis v annoque mmx 10 x 2010}
+test clock-2.1690 {conversion of 2010-05-31} {
+ clock format 1275309296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2010 12:34:56 die xxxi mensis v annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2455348 05 v 5 05/31/2010 die xxxi mensis v annoque mmx 10 x 2010}
+test clock-2.1691 {conversion of 2010-06-01} {
+ clock format 1275395696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2010 12:34:56 die i mensis vi annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2455349 06 vi 6 06/01/2010 die i mensis vi annoque mmx 10 x 2010}
+test clock-2.1692 {conversion of 2010-06-30} {
+ clock format 1277901296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2010 12:34:56 die xxx mensis vi annoque mmx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2455378 06 vi 6 06/30/2010 die xxx mensis vi annoque mmx 10 x 2010}
+test clock-2.1693 {conversion of 2010-07-01} {
+ clock format 1277987696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2010 12:34:56 die i mensis vii annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2455379 07 vii 7 07/01/2010 die i mensis vii annoque mmx 10 x 2010}
+test clock-2.1694 {conversion of 2010-07-31} {
+ clock format 1280579696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2010 12:34:56 die xxxi mensis vii annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2455409 07 vii 7 07/31/2010 die xxxi mensis vii annoque mmx 10 x 2010}
+test clock-2.1695 {conversion of 2010-08-01} {
+ clock format 1280666096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2010 12:34:56 die i mensis viii annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2455410 08 viii 8 08/01/2010 die i mensis viii annoque mmx 10 x 2010}
+test clock-2.1696 {conversion of 2010-08-31} {
+ clock format 1283258096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2010 12:34:56 die xxxi mensis viii annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2455440 08 viii 8 08/31/2010 die xxxi mensis viii annoque mmx 10 x 2010}
+test clock-2.1697 {conversion of 2010-09-01} {
+ clock format 1283344496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2010 12:34:56 die i mensis ix annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2455441 09 ix 9 09/01/2010 die i mensis ix annoque mmx 10 x 2010}
+test clock-2.1698 {conversion of 2010-09-30} {
+ clock format 1285850096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2010 12:34:56 die xxx mensis ix annoque mmx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2455470 09 ix 9 09/30/2010 die xxx mensis ix annoque mmx 10 x 2010}
+test clock-2.1699 {conversion of 2010-10-01} {
+ clock format 1285936496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2010 12:34:56 die i mensis x annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2455471 10 x 10 10/01/2010 die i mensis x annoque mmx 10 x 2010}
+test clock-2.1700 {conversion of 2010-10-31} {
+ clock format 1288528496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2010 12:34:56 die xxxi mensis x annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2455501 10 x 10 10/31/2010 die xxxi mensis x annoque mmx 10 x 2010}
+test clock-2.1701 {conversion of 2010-11-01} {
+ clock format 1288614896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2010 12:34:56 die i mensis xi annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2455502 11 xi 11 11/01/2010 die i mensis xi annoque mmx 10 x 2010}
+test clock-2.1702 {conversion of 2010-11-30} {
+ clock format 1291120496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2010 12:34:56 die xxx mensis xi annoque mmx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2455531 11 xi 11 11/30/2010 die xxx mensis xi annoque mmx 10 x 2010}
+test clock-2.1703 {conversion of 2010-12-01} {
+ clock format 1291206896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2010 12:34:56 die i mensis xii annoque mmx xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2455532 12 xii 12 12/01/2010 die i mensis xii annoque mmx 10 x 2010}
+test clock-2.1704 {conversion of 2010-12-31} {
+ clock format 1293798896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2010 12:34:56 die xxxi mensis xii annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2455562 12 xii 12 12/31/2010 die xxxi mensis xii annoque mmx 10 x 2010}
+test clock-2.1705 {conversion of 2011-01-01} {
+ clock format 1293885296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2011 12:34:56 die i mensis i annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2455563 01 i 1 01/01/2011 die i mensis i annoque mmxi 11 xi 2011}
+test clock-2.1706 {conversion of 2011-01-31} {
+ clock format 1296477296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2011 12:34:56 die xxxi mensis i annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2455593 01 i 1 01/31/2011 die xxxi mensis i annoque mmxi 11 xi 2011}
+test clock-2.1707 {conversion of 2011-02-01} {
+ clock format 1296563696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2011 12:34:56 die i mensis ii annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2455594 02 ii 2 02/01/2011 die i mensis ii annoque mmxi 11 xi 2011}
+test clock-2.1708 {conversion of 2011-02-28} {
+ clock format 1298896496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2011 12:34:56 die xxviii mensis ii annoque mmxi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2455621 02 ii 2 02/28/2011 die xxviii mensis ii annoque mmxi 11 xi 2011}
+test clock-2.1709 {conversion of 2011-03-01} {
+ clock format 1298982896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2011 12:34:56 die i mensis iii annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2455622 03 iii 3 03/01/2011 die i mensis iii annoque mmxi 11 xi 2011}
+test clock-2.1710 {conversion of 2011-03-31} {
+ clock format 1301574896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2011 12:34:56 die xxxi mensis iii annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2455652 03 iii 3 03/31/2011 die xxxi mensis iii annoque mmxi 11 xi 2011}
+test clock-2.1711 {conversion of 2011-04-01} {
+ clock format 1301661296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2011 12:34:56 die i mensis iv annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2455653 04 iv 4 04/01/2011 die i mensis iv annoque mmxi 11 xi 2011}
+test clock-2.1712 {conversion of 2011-04-30} {
+ clock format 1304166896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2011 12:34:56 die xxx mensis iv annoque mmxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2455682 04 iv 4 04/30/2011 die xxx mensis iv annoque mmxi 11 xi 2011}
+test clock-2.1713 {conversion of 2011-05-01} {
+ clock format 1304253296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2011 12:34:56 die i mensis v annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2455683 05 v 5 05/01/2011 die i mensis v annoque mmxi 11 xi 2011}
+test clock-2.1714 {conversion of 2011-05-31} {
+ clock format 1306845296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2011 12:34:56 die xxxi mensis v annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2455713 05 v 5 05/31/2011 die xxxi mensis v annoque mmxi 11 xi 2011}
+test clock-2.1715 {conversion of 2011-06-01} {
+ clock format 1306931696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2011 12:34:56 die i mensis vi annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2455714 06 vi 6 06/01/2011 die i mensis vi annoque mmxi 11 xi 2011}
+test clock-2.1716 {conversion of 2011-06-30} {
+ clock format 1309437296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2011 12:34:56 die xxx mensis vi annoque mmxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2455743 06 vi 6 06/30/2011 die xxx mensis vi annoque mmxi 11 xi 2011}
+test clock-2.1717 {conversion of 2011-07-01} {
+ clock format 1309523696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2011 12:34:56 die i mensis vii annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2455744 07 vii 7 07/01/2011 die i mensis vii annoque mmxi 11 xi 2011}
+test clock-2.1718 {conversion of 2011-07-31} {
+ clock format 1312115696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2011 12:34:56 die xxxi mensis vii annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2455774 07 vii 7 07/31/2011 die xxxi mensis vii annoque mmxi 11 xi 2011}
+test clock-2.1719 {conversion of 2011-08-01} {
+ clock format 1312202096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2011 12:34:56 die i mensis viii annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2455775 08 viii 8 08/01/2011 die i mensis viii annoque mmxi 11 xi 2011}
+test clock-2.1720 {conversion of 2011-08-31} {
+ clock format 1314794096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2011 12:34:56 die xxxi mensis viii annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2455805 08 viii 8 08/31/2011 die xxxi mensis viii annoque mmxi 11 xi 2011}
+test clock-2.1721 {conversion of 2011-09-01} {
+ clock format 1314880496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2011 12:34:56 die i mensis ix annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2455806 09 ix 9 09/01/2011 die i mensis ix annoque mmxi 11 xi 2011}
+test clock-2.1722 {conversion of 2011-09-30} {
+ clock format 1317386096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2011 12:34:56 die xxx mensis ix annoque mmxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2455835 09 ix 9 09/30/2011 die xxx mensis ix annoque mmxi 11 xi 2011}
+test clock-2.1723 {conversion of 2011-10-01} {
+ clock format 1317472496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2011 12:34:56 die i mensis x annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2455836 10 x 10 10/01/2011 die i mensis x annoque mmxi 11 xi 2011}
+test clock-2.1724 {conversion of 2011-10-31} {
+ clock format 1320064496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2011 12:34:56 die xxxi mensis x annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2455866 10 x 10 10/31/2011 die xxxi mensis x annoque mmxi 11 xi 2011}
+test clock-2.1725 {conversion of 2011-11-01} {
+ clock format 1320150896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2011 12:34:56 die i mensis xi annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2455867 11 xi 11 11/01/2011 die i mensis xi annoque mmxi 11 xi 2011}
+test clock-2.1726 {conversion of 2011-11-30} {
+ clock format 1322656496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2011 12:34:56 die xxx mensis xi annoque mmxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2455896 11 xi 11 11/30/2011 die xxx mensis xi annoque mmxi 11 xi 2011}
+test clock-2.1727 {conversion of 2011-12-01} {
+ clock format 1322742896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2011 12:34:56 die i mensis xii annoque mmxi xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2455897 12 xii 12 12/01/2011 die i mensis xii annoque mmxi 11 xi 2011}
+test clock-2.1728 {conversion of 2011-12-31} {
+ clock format 1325334896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2011 12:34:56 die xxxi mensis xii annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2455927 12 xii 12 12/31/2011 die xxxi mensis xii annoque mmxi 11 xi 2011}
+test clock-2.1729 {conversion of 2012-01-01} {
+ clock format 1325421296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2012 12:34:56 die i mensis i annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2455928 01 i 1 01/01/2012 die i mensis i annoque mmxii 12 xii 2012}
+test clock-2.1730 {conversion of 2012-01-31} {
+ clock format 1328013296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2012 12:34:56 die xxxi mensis i annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2455958 01 i 1 01/31/2012 die xxxi mensis i annoque mmxii 12 xii 2012}
+test clock-2.1731 {conversion of 2012-02-01} {
+ clock format 1328099696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2012 12:34:56 die i mensis ii annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2455959 02 ii 2 02/01/2012 die i mensis ii annoque mmxii 12 xii 2012}
+test clock-2.1732 {conversion of 2012-02-29} {
+ clock format 1330518896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2012 12:34:56 die xxix mensis ii annoque mmxii xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2455987 02 ii 2 02/29/2012 die xxix mensis ii annoque mmxii 12 xii 2012}
+test clock-2.1733 {conversion of 2012-03-01} {
+ clock format 1330605296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2012 12:34:56 die i mensis iii annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2455988 03 iii 3 03/01/2012 die i mensis iii annoque mmxii 12 xii 2012}
+test clock-2.1734 {conversion of 2012-03-31} {
+ clock format 1333197296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2012 12:34:56 die xxxi mensis iii annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2456018 03 iii 3 03/31/2012 die xxxi mensis iii annoque mmxii 12 xii 2012}
+test clock-2.1735 {conversion of 2012-04-01} {
+ clock format 1333283696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2012 12:34:56 die i mensis iv annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2456019 04 iv 4 04/01/2012 die i mensis iv annoque mmxii 12 xii 2012}
+test clock-2.1736 {conversion of 2012-04-30} {
+ clock format 1335789296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2012 12:34:56 die xxx mensis iv annoque mmxii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2456048 04 iv 4 04/30/2012 die xxx mensis iv annoque mmxii 12 xii 2012}
+test clock-2.1737 {conversion of 2012-05-01} {
+ clock format 1335875696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2012 12:34:56 die i mensis v annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2456049 05 v 5 05/01/2012 die i mensis v annoque mmxii 12 xii 2012}
+test clock-2.1738 {conversion of 2012-05-31} {
+ clock format 1338467696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2012 12:34:56 die xxxi mensis v annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2456079 05 v 5 05/31/2012 die xxxi mensis v annoque mmxii 12 xii 2012}
+test clock-2.1739 {conversion of 2012-06-01} {
+ clock format 1338554096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2012 12:34:56 die i mensis vi annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2456080 06 vi 6 06/01/2012 die i mensis vi annoque mmxii 12 xii 2012}
+test clock-2.1740 {conversion of 2012-06-30} {
+ clock format 1341059696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2012 12:34:56 die xxx mensis vi annoque mmxii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2456109 06 vi 6 06/30/2012 die xxx mensis vi annoque mmxii 12 xii 2012}
+test clock-2.1741 {conversion of 2012-07-01} {
+ clock format 1341146096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2012 12:34:56 die i mensis vii annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2456110 07 vii 7 07/01/2012 die i mensis vii annoque mmxii 12 xii 2012}
+test clock-2.1742 {conversion of 2012-07-31} {
+ clock format 1343738096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2012 12:34:56 die xxxi mensis vii annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2456140 07 vii 7 07/31/2012 die xxxi mensis vii annoque mmxii 12 xii 2012}
+test clock-2.1743 {conversion of 2012-08-01} {
+ clock format 1343824496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2012 12:34:56 die i mensis viii annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2456141 08 viii 8 08/01/2012 die i mensis viii annoque mmxii 12 xii 2012}
+test clock-2.1744 {conversion of 2012-08-31} {
+ clock format 1346416496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2012 12:34:56 die xxxi mensis viii annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2456171 08 viii 8 08/31/2012 die xxxi mensis viii annoque mmxii 12 xii 2012}
+test clock-2.1745 {conversion of 2012-09-01} {
+ clock format 1346502896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2012 12:34:56 die i mensis ix annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2456172 09 ix 9 09/01/2012 die i mensis ix annoque mmxii 12 xii 2012}
+test clock-2.1746 {conversion of 2012-09-30} {
+ clock format 1349008496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2012 12:34:56 die xxx mensis ix annoque mmxii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2456201 09 ix 9 09/30/2012 die xxx mensis ix annoque mmxii 12 xii 2012}
+test clock-2.1747 {conversion of 2012-10-01} {
+ clock format 1349094896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2012 12:34:56 die i mensis x annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2456202 10 x 10 10/01/2012 die i mensis x annoque mmxii 12 xii 2012}
+test clock-2.1748 {conversion of 2012-10-31} {
+ clock format 1351686896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2012 12:34:56 die xxxi mensis x annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2456232 10 x 10 10/31/2012 die xxxi mensis x annoque mmxii 12 xii 2012}
+test clock-2.1749 {conversion of 2012-11-01} {
+ clock format 1351773296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2012 12:34:56 die i mensis xi annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2456233 11 xi 11 11/01/2012 die i mensis xi annoque mmxii 12 xii 2012}
+test clock-2.1750 {conversion of 2012-11-30} {
+ clock format 1354278896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2012 12:34:56 die xxx mensis xi annoque mmxii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2456262 11 xi 11 11/30/2012 die xxx mensis xi annoque mmxii 12 xii 2012}
+test clock-2.1751 {conversion of 2012-12-01} {
+ clock format 1354365296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2012 12:34:56 die i mensis xii annoque mmxii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2456263 12 xii 12 12/01/2012 die i mensis xii annoque mmxii 12 xii 2012}
+test clock-2.1752 {conversion of 2012-12-31} {
+ clock format 1356957296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2012 12:34:56 die xxxi mensis xii annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2456293 12 xii 12 12/31/2012 die xxxi mensis xii annoque mmxii 12 xii 2012}
+test clock-2.1753 {conversion of 2013-01-01} {
+ clock format 1357043696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2013 12:34:56 die i mensis i annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2456294 01 i 1 01/01/2013 die i mensis i annoque mmxiii 13 xiii 2013}
+test clock-2.1754 {conversion of 2013-01-31} {
+ clock format 1359635696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2013 12:34:56 die xxxi mensis i annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2456324 01 i 1 01/31/2013 die xxxi mensis i annoque mmxiii 13 xiii 2013}
+test clock-2.1755 {conversion of 2013-02-01} {
+ clock format 1359722096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2013 12:34:56 die i mensis ii annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2456325 02 ii 2 02/01/2013 die i mensis ii annoque mmxiii 13 xiii 2013}
+test clock-2.1756 {conversion of 2013-02-28} {
+ clock format 1362054896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2013 12:34:56 die xxviii mensis ii annoque mmxiii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2456352 02 ii 2 02/28/2013 die xxviii mensis ii annoque mmxiii 13 xiii 2013}
+test clock-2.1757 {conversion of 2013-03-01} {
+ clock format 1362141296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2013 12:34:56 die i mensis iii annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2456353 03 iii 3 03/01/2013 die i mensis iii annoque mmxiii 13 xiii 2013}
+test clock-2.1758 {conversion of 2013-03-31} {
+ clock format 1364733296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2013 12:34:56 die xxxi mensis iii annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2456383 03 iii 3 03/31/2013 die xxxi mensis iii annoque mmxiii 13 xiii 2013}
+test clock-2.1759 {conversion of 2013-04-01} {
+ clock format 1364819696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2013 12:34:56 die i mensis iv annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2456384 04 iv 4 04/01/2013 die i mensis iv annoque mmxiii 13 xiii 2013}
+test clock-2.1760 {conversion of 2013-04-30} {
+ clock format 1367325296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2013 12:34:56 die xxx mensis iv annoque mmxiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2456413 04 iv 4 04/30/2013 die xxx mensis iv annoque mmxiii 13 xiii 2013}
+test clock-2.1761 {conversion of 2013-05-01} {
+ clock format 1367411696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2013 12:34:56 die i mensis v annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2456414 05 v 5 05/01/2013 die i mensis v annoque mmxiii 13 xiii 2013}
+test clock-2.1762 {conversion of 2013-05-31} {
+ clock format 1370003696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2013 12:34:56 die xxxi mensis v annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2456444 05 v 5 05/31/2013 die xxxi mensis v annoque mmxiii 13 xiii 2013}
+test clock-2.1763 {conversion of 2013-06-01} {
+ clock format 1370090096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2013 12:34:56 die i mensis vi annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2456445 06 vi 6 06/01/2013 die i mensis vi annoque mmxiii 13 xiii 2013}
+test clock-2.1764 {conversion of 2013-06-30} {
+ clock format 1372595696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2013 12:34:56 die xxx mensis vi annoque mmxiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2456474 06 vi 6 06/30/2013 die xxx mensis vi annoque mmxiii 13 xiii 2013}
+test clock-2.1765 {conversion of 2013-07-01} {
+ clock format 1372682096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2013 12:34:56 die i mensis vii annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2456475 07 vii 7 07/01/2013 die i mensis vii annoque mmxiii 13 xiii 2013}
+test clock-2.1766 {conversion of 2013-07-31} {
+ clock format 1375274096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2013 12:34:56 die xxxi mensis vii annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2456505 07 vii 7 07/31/2013 die xxxi mensis vii annoque mmxiii 13 xiii 2013}
+test clock-2.1767 {conversion of 2013-08-01} {
+ clock format 1375360496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2013 12:34:56 die i mensis viii annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2456506 08 viii 8 08/01/2013 die i mensis viii annoque mmxiii 13 xiii 2013}
+test clock-2.1768 {conversion of 2013-08-31} {
+ clock format 1377952496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2013 12:34:56 die xxxi mensis viii annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2456536 08 viii 8 08/31/2013 die xxxi mensis viii annoque mmxiii 13 xiii 2013}
+test clock-2.1769 {conversion of 2013-09-01} {
+ clock format 1378038896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2013 12:34:56 die i mensis ix annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2456537 09 ix 9 09/01/2013 die i mensis ix annoque mmxiii 13 xiii 2013}
+test clock-2.1770 {conversion of 2013-09-30} {
+ clock format 1380544496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2013 12:34:56 die xxx mensis ix annoque mmxiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2456566 09 ix 9 09/30/2013 die xxx mensis ix annoque mmxiii 13 xiii 2013}
+test clock-2.1771 {conversion of 2013-10-01} {
+ clock format 1380630896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2013 12:34:56 die i mensis x annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2456567 10 x 10 10/01/2013 die i mensis x annoque mmxiii 13 xiii 2013}
+test clock-2.1772 {conversion of 2013-10-31} {
+ clock format 1383222896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2013 12:34:56 die xxxi mensis x annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2456597 10 x 10 10/31/2013 die xxxi mensis x annoque mmxiii 13 xiii 2013}
+test clock-2.1773 {conversion of 2013-11-01} {
+ clock format 1383309296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2013 12:34:56 die i mensis xi annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2456598 11 xi 11 11/01/2013 die i mensis xi annoque mmxiii 13 xiii 2013}
+test clock-2.1774 {conversion of 2013-11-30} {
+ clock format 1385814896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2013 12:34:56 die xxx mensis xi annoque mmxiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2456627 11 xi 11 11/30/2013 die xxx mensis xi annoque mmxiii 13 xiii 2013}
+test clock-2.1775 {conversion of 2013-12-01} {
+ clock format 1385901296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2013 12:34:56 die i mensis xii annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2456628 12 xii 12 12/01/2013 die i mensis xii annoque mmxiii 13 xiii 2013}
+test clock-2.1776 {conversion of 2013-12-31} {
+ clock format 1388493296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2013 12:34:56 die xxxi mensis xii annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2456658 12 xii 12 12/31/2013 die xxxi mensis xii annoque mmxiii 13 xiii 2013}
+test clock-2.1777 {conversion of 2016-01-01} {
+ clock format 1451651696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2016 12:34:56 die i mensis i annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2457389 01 i 1 01/01/2016 die i mensis i annoque mmxvi 16 xvi 2016}
+test clock-2.1778 {conversion of 2016-01-31} {
+ clock format 1454243696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2016 12:34:56 die xxxi mensis i annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2457419 01 i 1 01/31/2016 die xxxi mensis i annoque mmxvi 16 xvi 2016}
+test clock-2.1779 {conversion of 2016-02-01} {
+ clock format 1454330096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2016 12:34:56 die i mensis ii annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2457420 02 ii 2 02/01/2016 die i mensis ii annoque mmxvi 16 xvi 2016}
+test clock-2.1780 {conversion of 2016-02-29} {
+ clock format 1456749296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2016 12:34:56 die xxix mensis ii annoque mmxvi xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2457448 02 ii 2 02/29/2016 die xxix mensis ii annoque mmxvi 16 xvi 2016}
+test clock-2.1781 {conversion of 2016-03-01} {
+ clock format 1456835696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2016 12:34:56 die i mensis iii annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2457449 03 iii 3 03/01/2016 die i mensis iii annoque mmxvi 16 xvi 2016}
+test clock-2.1782 {conversion of 2016-03-31} {
+ clock format 1459427696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2016 12:34:56 die xxxi mensis iii annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2457479 03 iii 3 03/31/2016 die xxxi mensis iii annoque mmxvi 16 xvi 2016}
+test clock-2.1783 {conversion of 2016-04-01} {
+ clock format 1459514096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2016 12:34:56 die i mensis iv annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2457480 04 iv 4 04/01/2016 die i mensis iv annoque mmxvi 16 xvi 2016}
+test clock-2.1784 {conversion of 2016-04-30} {
+ clock format 1462019696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2016 12:34:56 die xxx mensis iv annoque mmxvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2457509 04 iv 4 04/30/2016 die xxx mensis iv annoque mmxvi 16 xvi 2016}
+test clock-2.1785 {conversion of 2016-05-01} {
+ clock format 1462106096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2016 12:34:56 die i mensis v annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2457510 05 v 5 05/01/2016 die i mensis v annoque mmxvi 16 xvi 2016}
+test clock-2.1786 {conversion of 2016-05-31} {
+ clock format 1464698096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2016 12:34:56 die xxxi mensis v annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2457540 05 v 5 05/31/2016 die xxxi mensis v annoque mmxvi 16 xvi 2016}
+test clock-2.1787 {conversion of 2016-06-01} {
+ clock format 1464784496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2016 12:34:56 die i mensis vi annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2457541 06 vi 6 06/01/2016 die i mensis vi annoque mmxvi 16 xvi 2016}
+test clock-2.1788 {conversion of 2016-06-30} {
+ clock format 1467290096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2016 12:34:56 die xxx mensis vi annoque mmxvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2457570 06 vi 6 06/30/2016 die xxx mensis vi annoque mmxvi 16 xvi 2016}
+test clock-2.1789 {conversion of 2016-07-01} {
+ clock format 1467376496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2016 12:34:56 die i mensis vii annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2457571 07 vii 7 07/01/2016 die i mensis vii annoque mmxvi 16 xvi 2016}
+test clock-2.1790 {conversion of 2016-07-31} {
+ clock format 1469968496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2016 12:34:56 die xxxi mensis vii annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2457601 07 vii 7 07/31/2016 die xxxi mensis vii annoque mmxvi 16 xvi 2016}
+test clock-2.1791 {conversion of 2016-08-01} {
+ clock format 1470054896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2016 12:34:56 die i mensis viii annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2457602 08 viii 8 08/01/2016 die i mensis viii annoque mmxvi 16 xvi 2016}
+test clock-2.1792 {conversion of 2016-08-31} {
+ clock format 1472646896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2016 12:34:56 die xxxi mensis viii annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2457632 08 viii 8 08/31/2016 die xxxi mensis viii annoque mmxvi 16 xvi 2016}
+test clock-2.1793 {conversion of 2016-09-01} {
+ clock format 1472733296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2016 12:34:56 die i mensis ix annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2457633 09 ix 9 09/01/2016 die i mensis ix annoque mmxvi 16 xvi 2016}
+test clock-2.1794 {conversion of 2016-09-30} {
+ clock format 1475238896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2016 12:34:56 die xxx mensis ix annoque mmxvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2457662 09 ix 9 09/30/2016 die xxx mensis ix annoque mmxvi 16 xvi 2016}
+test clock-2.1795 {conversion of 2016-10-01} {
+ clock format 1475325296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2016 12:34:56 die i mensis x annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2457663 10 x 10 10/01/2016 die i mensis x annoque mmxvi 16 xvi 2016}
+test clock-2.1796 {conversion of 2016-10-31} {
+ clock format 1477917296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2016 12:34:56 die xxxi mensis x annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2457693 10 x 10 10/31/2016 die xxxi mensis x annoque mmxvi 16 xvi 2016}
+test clock-2.1797 {conversion of 2016-11-01} {
+ clock format 1478003696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2016 12:34:56 die i mensis xi annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2457694 11 xi 11 11/01/2016 die i mensis xi annoque mmxvi 16 xvi 2016}
+test clock-2.1798 {conversion of 2016-11-30} {
+ clock format 1480509296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2016 12:34:56 die xxx mensis xi annoque mmxvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2457723 11 xi 11 11/30/2016 die xxx mensis xi annoque mmxvi 16 xvi 2016}
+test clock-2.1799 {conversion of 2016-12-01} {
+ clock format 1480595696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2016 12:34:56 die i mensis xii annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2457724 12 xii 12 12/01/2016 die i mensis xii annoque mmxvi 16 xvi 2016}
+test clock-2.1800 {conversion of 2016-12-31} {
+ clock format 1483187696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2016 12:34:56 die xxxi mensis xii annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2457754 12 xii 12 12/31/2016 die xxxi mensis xii annoque mmxvi 16 xvi 2016}
+test clock-2.1801 {conversion of 2017-01-01} {
+ clock format 1483274096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2017 12:34:56 die i mensis i annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2457755 01 i 1 01/01/2017 die i mensis i annoque mmxvii 17 xvii 2017}
+test clock-2.1802 {conversion of 2017-01-31} {
+ clock format 1485866096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2017 12:34:56 die xxxi mensis i annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2457785 01 i 1 01/31/2017 die xxxi mensis i annoque mmxvii 17 xvii 2017}
+test clock-2.1803 {conversion of 2017-02-01} {
+ clock format 1485952496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2017 12:34:56 die i mensis ii annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2457786 02 ii 2 02/01/2017 die i mensis ii annoque mmxvii 17 xvii 2017}
+test clock-2.1804 {conversion of 2017-02-28} {
+ clock format 1488285296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2017 12:34:56 die xxviii mensis ii annoque mmxvii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2457813 02 ii 2 02/28/2017 die xxviii mensis ii annoque mmxvii 17 xvii 2017}
+test clock-2.1805 {conversion of 2017-03-01} {
+ clock format 1488371696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2017 12:34:56 die i mensis iii annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2457814 03 iii 3 03/01/2017 die i mensis iii annoque mmxvii 17 xvii 2017}
+test clock-2.1806 {conversion of 2017-03-31} {
+ clock format 1490963696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2017 12:34:56 die xxxi mensis iii annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2457844 03 iii 3 03/31/2017 die xxxi mensis iii annoque mmxvii 17 xvii 2017}
+test clock-2.1807 {conversion of 2017-04-01} {
+ clock format 1491050096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2017 12:34:56 die i mensis iv annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2457845 04 iv 4 04/01/2017 die i mensis iv annoque mmxvii 17 xvii 2017}
+test clock-2.1808 {conversion of 2017-04-30} {
+ clock format 1493555696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2017 12:34:56 die xxx mensis iv annoque mmxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2457874 04 iv 4 04/30/2017 die xxx mensis iv annoque mmxvii 17 xvii 2017}
+test clock-2.1809 {conversion of 2017-05-01} {
+ clock format 1493642096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2017 12:34:56 die i mensis v annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2457875 05 v 5 05/01/2017 die i mensis v annoque mmxvii 17 xvii 2017}
+test clock-2.1810 {conversion of 2017-05-31} {
+ clock format 1496234096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2017 12:34:56 die xxxi mensis v annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2457905 05 v 5 05/31/2017 die xxxi mensis v annoque mmxvii 17 xvii 2017}
+test clock-2.1811 {conversion of 2017-06-01} {
+ clock format 1496320496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2017 12:34:56 die i mensis vi annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2457906 06 vi 6 06/01/2017 die i mensis vi annoque mmxvii 17 xvii 2017}
+test clock-2.1812 {conversion of 2017-06-30} {
+ clock format 1498826096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2017 12:34:56 die xxx mensis vi annoque mmxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2457935 06 vi 6 06/30/2017 die xxx mensis vi annoque mmxvii 17 xvii 2017}
+test clock-2.1813 {conversion of 2017-07-01} {
+ clock format 1498912496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2017 12:34:56 die i mensis vii annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2457936 07 vii 7 07/01/2017 die i mensis vii annoque mmxvii 17 xvii 2017}
+test clock-2.1814 {conversion of 2017-07-31} {
+ clock format 1501504496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2017 12:34:56 die xxxi mensis vii annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2457966 07 vii 7 07/31/2017 die xxxi mensis vii annoque mmxvii 17 xvii 2017}
+test clock-2.1815 {conversion of 2017-08-01} {
+ clock format 1501590896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2017 12:34:56 die i mensis viii annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2457967 08 viii 8 08/01/2017 die i mensis viii annoque mmxvii 17 xvii 2017}
+test clock-2.1816 {conversion of 2017-08-31} {
+ clock format 1504182896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2017 12:34:56 die xxxi mensis viii annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2457997 08 viii 8 08/31/2017 die xxxi mensis viii annoque mmxvii 17 xvii 2017}
+test clock-2.1817 {conversion of 2017-09-01} {
+ clock format 1504269296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2017 12:34:56 die i mensis ix annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2457998 09 ix 9 09/01/2017 die i mensis ix annoque mmxvii 17 xvii 2017}
+test clock-2.1818 {conversion of 2017-09-30} {
+ clock format 1506774896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2017 12:34:56 die xxx mensis ix annoque mmxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2458027 09 ix 9 09/30/2017 die xxx mensis ix annoque mmxvii 17 xvii 2017}
+test clock-2.1819 {conversion of 2017-10-01} {
+ clock format 1506861296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2017 12:34:56 die i mensis x annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2458028 10 x 10 10/01/2017 die i mensis x annoque mmxvii 17 xvii 2017}
+test clock-2.1820 {conversion of 2017-10-31} {
+ clock format 1509453296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2017 12:34:56 die xxxi mensis x annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2458058 10 x 10 10/31/2017 die xxxi mensis x annoque mmxvii 17 xvii 2017}
+test clock-2.1821 {conversion of 2017-11-01} {
+ clock format 1509539696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2017 12:34:56 die i mensis xi annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2458059 11 xi 11 11/01/2017 die i mensis xi annoque mmxvii 17 xvii 2017}
+test clock-2.1822 {conversion of 2017-11-30} {
+ clock format 1512045296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2017 12:34:56 die xxx mensis xi annoque mmxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2458088 11 xi 11 11/30/2017 die xxx mensis xi annoque mmxvii 17 xvii 2017}
+test clock-2.1823 {conversion of 2017-12-01} {
+ clock format 1512131696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2017 12:34:56 die i mensis xii annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2458089 12 xii 12 12/01/2017 die i mensis xii annoque mmxvii 17 xvii 2017}
+test clock-2.1824 {conversion of 2017-12-31} {
+ clock format 1514723696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2017 12:34:56 die xxxi mensis xii annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2458119 12 xii 12 12/31/2017 die xxxi mensis xii annoque mmxvii 17 xvii 2017}
+test clock-2.1825 {conversion of 2020-01-01} {
+ clock format 1577882096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2020 12:34:56 die i mensis i annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2458850 01 i 1 01/01/2020 die i mensis i annoque mmxx 20 xx 2020}
+test clock-2.1826 {conversion of 2020-01-31} {
+ clock format 1580474096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2020 12:34:56 die xxxi mensis i annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2458880 01 i 1 01/31/2020 die xxxi mensis i annoque mmxx 20 xx 2020}
+test clock-2.1827 {conversion of 2020-02-01} {
+ clock format 1580560496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2020 12:34:56 die i mensis ii annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2458881 02 ii 2 02/01/2020 die i mensis ii annoque mmxx 20 xx 2020}
+test clock-2.1828 {conversion of 2020-02-29} {
+ clock format 1582979696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2020 12:34:56 die xxix mensis ii annoque mmxx xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2458909 02 ii 2 02/29/2020 die xxix mensis ii annoque mmxx 20 xx 2020}
+test clock-2.1829 {conversion of 2020-03-01} {
+ clock format 1583066096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2020 12:34:56 die i mensis iii annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2458910 03 iii 3 03/01/2020 die i mensis iii annoque mmxx 20 xx 2020}
+test clock-2.1830 {conversion of 2020-03-31} {
+ clock format 1585658096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2020 12:34:56 die xxxi mensis iii annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2458940 03 iii 3 03/31/2020 die xxxi mensis iii annoque mmxx 20 xx 2020}
+test clock-2.1831 {conversion of 2020-04-01} {
+ clock format 1585744496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2020 12:34:56 die i mensis iv annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2458941 04 iv 4 04/01/2020 die i mensis iv annoque mmxx 20 xx 2020}
+test clock-2.1832 {conversion of 2020-04-30} {
+ clock format 1588250096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2020 12:34:56 die xxx mensis iv annoque mmxx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2458970 04 iv 4 04/30/2020 die xxx mensis iv annoque mmxx 20 xx 2020}
+test clock-2.1833 {conversion of 2020-05-01} {
+ clock format 1588336496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2020 12:34:56 die i mensis v annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2458971 05 v 5 05/01/2020 die i mensis v annoque mmxx 20 xx 2020}
+test clock-2.1834 {conversion of 2020-05-31} {
+ clock format 1590928496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2020 12:34:56 die xxxi mensis v annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2459001 05 v 5 05/31/2020 die xxxi mensis v annoque mmxx 20 xx 2020}
+test clock-2.1835 {conversion of 2020-06-01} {
+ clock format 1591014896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2020 12:34:56 die i mensis vi annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2459002 06 vi 6 06/01/2020 die i mensis vi annoque mmxx 20 xx 2020}
+test clock-2.1836 {conversion of 2020-06-30} {
+ clock format 1593520496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2020 12:34:56 die xxx mensis vi annoque mmxx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2459031 06 vi 6 06/30/2020 die xxx mensis vi annoque mmxx 20 xx 2020}
+test clock-2.1837 {conversion of 2020-07-01} {
+ clock format 1593606896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2020 12:34:56 die i mensis vii annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2459032 07 vii 7 07/01/2020 die i mensis vii annoque mmxx 20 xx 2020}
+test clock-2.1838 {conversion of 2020-07-31} {
+ clock format 1596198896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2020 12:34:56 die xxxi mensis vii annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2459062 07 vii 7 07/31/2020 die xxxi mensis vii annoque mmxx 20 xx 2020}
+test clock-2.1839 {conversion of 2020-08-01} {
+ clock format 1596285296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2020 12:34:56 die i mensis viii annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2459063 08 viii 8 08/01/2020 die i mensis viii annoque mmxx 20 xx 2020}
+test clock-2.1840 {conversion of 2020-08-31} {
+ clock format 1598877296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2020 12:34:56 die xxxi mensis viii annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2459093 08 viii 8 08/31/2020 die xxxi mensis viii annoque mmxx 20 xx 2020}
+test clock-2.1841 {conversion of 2020-09-01} {
+ clock format 1598963696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2020 12:34:56 die i mensis ix annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2459094 09 ix 9 09/01/2020 die i mensis ix annoque mmxx 20 xx 2020}
+test clock-2.1842 {conversion of 2020-09-30} {
+ clock format 1601469296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2020 12:34:56 die xxx mensis ix annoque mmxx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2459123 09 ix 9 09/30/2020 die xxx mensis ix annoque mmxx 20 xx 2020}
+test clock-2.1843 {conversion of 2020-10-01} {
+ clock format 1601555696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2020 12:34:56 die i mensis x annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2459124 10 x 10 10/01/2020 die i mensis x annoque mmxx 20 xx 2020}
+test clock-2.1844 {conversion of 2020-10-31} {
+ clock format 1604147696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2020 12:34:56 die xxxi mensis x annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2459154 10 x 10 10/31/2020 die xxxi mensis x annoque mmxx 20 xx 2020}
+test clock-2.1845 {conversion of 2020-11-01} {
+ clock format 1604234096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2020 12:34:56 die i mensis xi annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2459155 11 xi 11 11/01/2020 die i mensis xi annoque mmxx 20 xx 2020}
+test clock-2.1846 {conversion of 2020-11-30} {
+ clock format 1606739696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2020 12:34:56 die xxx mensis xi annoque mmxx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2459184 11 xi 11 11/30/2020 die xxx mensis xi annoque mmxx 20 xx 2020}
+test clock-2.1847 {conversion of 2020-12-01} {
+ clock format 1606826096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2020 12:34:56 die i mensis xii annoque mmxx xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2459185 12 xii 12 12/01/2020 die i mensis xii annoque mmxx 20 xx 2020}
+test clock-2.1848 {conversion of 2020-12-31} {
+ clock format 1609418096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2020 12:34:56 die xxxi mensis xii annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2459215 12 xii 12 12/31/2020 die xxxi mensis xii annoque mmxx 20 xx 2020}
+test clock-2.1849 {conversion of 2021-01-01} {
+ clock format 1609504496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2021 12:34:56 die i mensis i annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2459216 01 i 1 01/01/2021 die i mensis i annoque mmxxi 21 xxi 2021}
+test clock-2.1850 {conversion of 2021-01-31} {
+ clock format 1612096496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2021 12:34:56 die xxxi mensis i annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2459246 01 i 1 01/31/2021 die xxxi mensis i annoque mmxxi 21 xxi 2021}
+test clock-2.1851 {conversion of 2021-02-01} {
+ clock format 1612182896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2021 12:34:56 die i mensis ii annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2459247 02 ii 2 02/01/2021 die i mensis ii annoque mmxxi 21 xxi 2021}
+test clock-2.1852 {conversion of 2021-02-28} {
+ clock format 1614515696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2021 12:34:56 die xxviii mensis ii annoque mmxxi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2459274 02 ii 2 02/28/2021 die xxviii mensis ii annoque mmxxi 21 xxi 2021}
+test clock-2.1853 {conversion of 2021-03-01} {
+ clock format 1614602096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2021 12:34:56 die i mensis iii annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2459275 03 iii 3 03/01/2021 die i mensis iii annoque mmxxi 21 xxi 2021}
+test clock-2.1854 {conversion of 2021-03-31} {
+ clock format 1617194096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2021 12:34:56 die xxxi mensis iii annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2459305 03 iii 3 03/31/2021 die xxxi mensis iii annoque mmxxi 21 xxi 2021}
+test clock-2.1855 {conversion of 2021-04-01} {
+ clock format 1617280496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2021 12:34:56 die i mensis iv annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2459306 04 iv 4 04/01/2021 die i mensis iv annoque mmxxi 21 xxi 2021}
+test clock-2.1856 {conversion of 2021-04-30} {
+ clock format 1619786096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2021 12:34:56 die xxx mensis iv annoque mmxxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2459335 04 iv 4 04/30/2021 die xxx mensis iv annoque mmxxi 21 xxi 2021}
+test clock-2.1857 {conversion of 2021-05-01} {
+ clock format 1619872496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2021 12:34:56 die i mensis v annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2459336 05 v 5 05/01/2021 die i mensis v annoque mmxxi 21 xxi 2021}
+test clock-2.1858 {conversion of 2021-05-31} {
+ clock format 1622464496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2021 12:34:56 die xxxi mensis v annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2459366 05 v 5 05/31/2021 die xxxi mensis v annoque mmxxi 21 xxi 2021}
+test clock-2.1859 {conversion of 2021-06-01} {
+ clock format 1622550896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2021 12:34:56 die i mensis vi annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2459367 06 vi 6 06/01/2021 die i mensis vi annoque mmxxi 21 xxi 2021}
+test clock-2.1860 {conversion of 2021-06-30} {
+ clock format 1625056496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2021 12:34:56 die xxx mensis vi annoque mmxxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2459396 06 vi 6 06/30/2021 die xxx mensis vi annoque mmxxi 21 xxi 2021}
+test clock-2.1861 {conversion of 2021-07-01} {
+ clock format 1625142896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2021 12:34:56 die i mensis vii annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2459397 07 vii 7 07/01/2021 die i mensis vii annoque mmxxi 21 xxi 2021}
+test clock-2.1862 {conversion of 2021-07-31} {
+ clock format 1627734896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2021 12:34:56 die xxxi mensis vii annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2459427 07 vii 7 07/31/2021 die xxxi mensis vii annoque mmxxi 21 xxi 2021}
+test clock-2.1863 {conversion of 2021-08-01} {
+ clock format 1627821296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2021 12:34:56 die i mensis viii annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2459428 08 viii 8 08/01/2021 die i mensis viii annoque mmxxi 21 xxi 2021}
+test clock-2.1864 {conversion of 2021-08-31} {
+ clock format 1630413296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2021 12:34:56 die xxxi mensis viii annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2459458 08 viii 8 08/31/2021 die xxxi mensis viii annoque mmxxi 21 xxi 2021}
+test clock-2.1865 {conversion of 2021-09-01} {
+ clock format 1630499696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2021 12:34:56 die i mensis ix annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2459459 09 ix 9 09/01/2021 die i mensis ix annoque mmxxi 21 xxi 2021}
+test clock-2.1866 {conversion of 2021-09-30} {
+ clock format 1633005296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2021 12:34:56 die xxx mensis ix annoque mmxxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2459488 09 ix 9 09/30/2021 die xxx mensis ix annoque mmxxi 21 xxi 2021}
+test clock-2.1867 {conversion of 2021-10-01} {
+ clock format 1633091696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2021 12:34:56 die i mensis x annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2459489 10 x 10 10/01/2021 die i mensis x annoque mmxxi 21 xxi 2021}
+test clock-2.1868 {conversion of 2021-10-31} {
+ clock format 1635683696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2021 12:34:56 die xxxi mensis x annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2459519 10 x 10 10/31/2021 die xxxi mensis x annoque mmxxi 21 xxi 2021}
+test clock-2.1869 {conversion of 2021-11-01} {
+ clock format 1635770096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2021 12:34:56 die i mensis xi annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2459520 11 xi 11 11/01/2021 die i mensis xi annoque mmxxi 21 xxi 2021}
+test clock-2.1870 {conversion of 2021-11-30} {
+ clock format 1638275696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2021 12:34:56 die xxx mensis xi annoque mmxxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2459549 11 xi 11 11/30/2021 die xxx mensis xi annoque mmxxi 21 xxi 2021}
+test clock-2.1871 {conversion of 2021-12-01} {
+ clock format 1638362096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2021 12:34:56 die i mensis xii annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2459550 12 xii 12 12/01/2021 die i mensis xii annoque mmxxi 21 xxi 2021}
+test clock-2.1872 {conversion of 2021-12-31} {
+ clock format 1640954096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2021 12:34:56 die xxxi mensis xii annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2459580 12 xii 12 12/31/2021 die xxxi mensis xii annoque mmxxi 21 xxi 2021}
+test clock-2.1873 {conversion of 2024-01-01} {
+ clock format 1704112496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2024 12:34:56 die i mensis i annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2460311 01 i 1 01/01/2024 die i mensis i annoque mmxxiv 24 xxiv 2024}
+test clock-2.1874 {conversion of 2024-01-31} {
+ clock format 1706704496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2024 12:34:56 die xxxi mensis i annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2460341 01 i 1 01/31/2024 die xxxi mensis i annoque mmxxiv 24 xxiv 2024}
+test clock-2.1875 {conversion of 2024-02-01} {
+ clock format 1706790896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2024 12:34:56 die i mensis ii annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2460342 02 ii 2 02/01/2024 die i mensis ii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1876 {conversion of 2024-02-29} {
+ clock format 1709210096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2024 12:34:56 die xxix mensis ii annoque mmxxiv xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2460370 02 ii 2 02/29/2024 die xxix mensis ii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1877 {conversion of 2024-03-01} {
+ clock format 1709296496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2024 12:34:56 die i mensis iii annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2460371 03 iii 3 03/01/2024 die i mensis iii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1878 {conversion of 2024-03-31} {
+ clock format 1711888496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2024 12:34:56 die xxxi mensis iii annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2460401 03 iii 3 03/31/2024 die xxxi mensis iii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1879 {conversion of 2024-04-01} {
+ clock format 1711974896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2024 12:34:56 die i mensis iv annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2460402 04 iv 4 04/01/2024 die i mensis iv annoque mmxxiv 24 xxiv 2024}
+test clock-2.1880 {conversion of 2024-04-30} {
+ clock format 1714480496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2024 12:34:56 die xxx mensis iv annoque mmxxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2460431 04 iv 4 04/30/2024 die xxx mensis iv annoque mmxxiv 24 xxiv 2024}
+test clock-2.1881 {conversion of 2024-05-01} {
+ clock format 1714566896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2024 12:34:56 die i mensis v annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2460432 05 v 5 05/01/2024 die i mensis v annoque mmxxiv 24 xxiv 2024}
+test clock-2.1882 {conversion of 2024-05-31} {
+ clock format 1717158896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2024 12:34:56 die xxxi mensis v annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2460462 05 v 5 05/31/2024 die xxxi mensis v annoque mmxxiv 24 xxiv 2024}
+test clock-2.1883 {conversion of 2024-06-01} {
+ clock format 1717245296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2024 12:34:56 die i mensis vi annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2460463 06 vi 6 06/01/2024 die i mensis vi annoque mmxxiv 24 xxiv 2024}
+test clock-2.1884 {conversion of 2024-06-30} {
+ clock format 1719750896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2024 12:34:56 die xxx mensis vi annoque mmxxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2460492 06 vi 6 06/30/2024 die xxx mensis vi annoque mmxxiv 24 xxiv 2024}
+test clock-2.1885 {conversion of 2024-07-01} {
+ clock format 1719837296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2024 12:34:56 die i mensis vii annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2460493 07 vii 7 07/01/2024 die i mensis vii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1886 {conversion of 2024-07-31} {
+ clock format 1722429296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2024 12:34:56 die xxxi mensis vii annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2460523 07 vii 7 07/31/2024 die xxxi mensis vii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1887 {conversion of 2024-08-01} {
+ clock format 1722515696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2024 12:34:56 die i mensis viii annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2460524 08 viii 8 08/01/2024 die i mensis viii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1888 {conversion of 2024-08-31} {
+ clock format 1725107696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2024 12:34:56 die xxxi mensis viii annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2460554 08 viii 8 08/31/2024 die xxxi mensis viii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1889 {conversion of 2024-09-01} {
+ clock format 1725194096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2024 12:34:56 die i mensis ix annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2460555 09 ix 9 09/01/2024 die i mensis ix annoque mmxxiv 24 xxiv 2024}
+test clock-2.1890 {conversion of 2024-09-30} {
+ clock format 1727699696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2024 12:34:56 die xxx mensis ix annoque mmxxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2460584 09 ix 9 09/30/2024 die xxx mensis ix annoque mmxxiv 24 xxiv 2024}
+test clock-2.1891 {conversion of 2024-10-01} {
+ clock format 1727786096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2024 12:34:56 die i mensis x annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2460585 10 x 10 10/01/2024 die i mensis x annoque mmxxiv 24 xxiv 2024}
+test clock-2.1892 {conversion of 2024-10-31} {
+ clock format 1730378096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2024 12:34:56 die xxxi mensis x annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2460615 10 x 10 10/31/2024 die xxxi mensis x annoque mmxxiv 24 xxiv 2024}
+test clock-2.1893 {conversion of 2024-11-01} {
+ clock format 1730464496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2024 12:34:56 die i mensis xi annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2460616 11 xi 11 11/01/2024 die i mensis xi annoque mmxxiv 24 xxiv 2024}
+test clock-2.1894 {conversion of 2024-11-30} {
+ clock format 1732970096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2024 12:34:56 die xxx mensis xi annoque mmxxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2460645 11 xi 11 11/30/2024 die xxx mensis xi annoque mmxxiv 24 xxiv 2024}
+test clock-2.1895 {conversion of 2024-12-01} {
+ clock format 1733056496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2024 12:34:56 die i mensis xii annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2460646 12 xii 12 12/01/2024 die i mensis xii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1896 {conversion of 2024-12-31} {
+ clock format 1735648496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2024 12:34:56 die xxxi mensis xii annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2460676 12 xii 12 12/31/2024 die xxxi mensis xii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1897 {conversion of 2025-01-01} {
+ clock format 1735734896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2025 12:34:56 die i mensis i annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2460677 01 i 1 01/01/2025 die i mensis i annoque mmxxv 25 xxv 2025}
+test clock-2.1898 {conversion of 2025-01-31} {
+ clock format 1738326896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2025 12:34:56 die xxxi mensis i annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2460707 01 i 1 01/31/2025 die xxxi mensis i annoque mmxxv 25 xxv 2025}
+test clock-2.1899 {conversion of 2025-02-01} {
+ clock format 1738413296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2025 12:34:56 die i mensis ii annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2460708 02 ii 2 02/01/2025 die i mensis ii annoque mmxxv 25 xxv 2025}
+test clock-2.1900 {conversion of 2025-02-28} {
+ clock format 1740746096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2025 12:34:56 die xxviii mensis ii annoque mmxxv xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2460735 02 ii 2 02/28/2025 die xxviii mensis ii annoque mmxxv 25 xxv 2025}
+test clock-2.1901 {conversion of 2025-03-01} {
+ clock format 1740832496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2025 12:34:56 die i mensis iii annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2460736 03 iii 3 03/01/2025 die i mensis iii annoque mmxxv 25 xxv 2025}
+test clock-2.1902 {conversion of 2025-03-31} {
+ clock format 1743424496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2025 12:34:56 die xxxi mensis iii annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2460766 03 iii 3 03/31/2025 die xxxi mensis iii annoque mmxxv 25 xxv 2025}
+test clock-2.1903 {conversion of 2025-04-01} {
+ clock format 1743510896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2025 12:34:56 die i mensis iv annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2460767 04 iv 4 04/01/2025 die i mensis iv annoque mmxxv 25 xxv 2025}
+test clock-2.1904 {conversion of 2025-04-30} {
+ clock format 1746016496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2025 12:34:56 die xxx mensis iv annoque mmxxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2460796 04 iv 4 04/30/2025 die xxx mensis iv annoque mmxxv 25 xxv 2025}
+test clock-2.1905 {conversion of 2025-05-01} {
+ clock format 1746102896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2025 12:34:56 die i mensis v annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2460797 05 v 5 05/01/2025 die i mensis v annoque mmxxv 25 xxv 2025}
+test clock-2.1906 {conversion of 2025-05-31} {
+ clock format 1748694896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2025 12:34:56 die xxxi mensis v annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2460827 05 v 5 05/31/2025 die xxxi mensis v annoque mmxxv 25 xxv 2025}
+test clock-2.1907 {conversion of 2025-06-01} {
+ clock format 1748781296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2025 12:34:56 die i mensis vi annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2460828 06 vi 6 06/01/2025 die i mensis vi annoque mmxxv 25 xxv 2025}
+test clock-2.1908 {conversion of 2025-06-30} {
+ clock format 1751286896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2025 12:34:56 die xxx mensis vi annoque mmxxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2460857 06 vi 6 06/30/2025 die xxx mensis vi annoque mmxxv 25 xxv 2025}
+test clock-2.1909 {conversion of 2025-07-01} {
+ clock format 1751373296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2025 12:34:56 die i mensis vii annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2460858 07 vii 7 07/01/2025 die i mensis vii annoque mmxxv 25 xxv 2025}
+test clock-2.1910 {conversion of 2025-07-31} {
+ clock format 1753965296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2025 12:34:56 die xxxi mensis vii annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2460888 07 vii 7 07/31/2025 die xxxi mensis vii annoque mmxxv 25 xxv 2025}
+test clock-2.1911 {conversion of 2025-08-01} {
+ clock format 1754051696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2025 12:34:56 die i mensis viii annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2460889 08 viii 8 08/01/2025 die i mensis viii annoque mmxxv 25 xxv 2025}
+test clock-2.1912 {conversion of 2025-08-31} {
+ clock format 1756643696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2025 12:34:56 die xxxi mensis viii annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2460919 08 viii 8 08/31/2025 die xxxi mensis viii annoque mmxxv 25 xxv 2025}
+test clock-2.1913 {conversion of 2025-09-01} {
+ clock format 1756730096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2025 12:34:56 die i mensis ix annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2460920 09 ix 9 09/01/2025 die i mensis ix annoque mmxxv 25 xxv 2025}
+test clock-2.1914 {conversion of 2025-09-30} {
+ clock format 1759235696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2025 12:34:56 die xxx mensis ix annoque mmxxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2460949 09 ix 9 09/30/2025 die xxx mensis ix annoque mmxxv 25 xxv 2025}
+test clock-2.1915 {conversion of 2025-10-01} {
+ clock format 1759322096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2025 12:34:56 die i mensis x annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2460950 10 x 10 10/01/2025 die i mensis x annoque mmxxv 25 xxv 2025}
+test clock-2.1916 {conversion of 2025-10-31} {
+ clock format 1761914096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2025 12:34:56 die xxxi mensis x annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2460980 10 x 10 10/31/2025 die xxxi mensis x annoque mmxxv 25 xxv 2025}
+test clock-2.1917 {conversion of 2025-11-01} {
+ clock format 1762000496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2025 12:34:56 die i mensis xi annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2460981 11 xi 11 11/01/2025 die i mensis xi annoque mmxxv 25 xxv 2025}
+test clock-2.1918 {conversion of 2025-11-30} {
+ clock format 1764506096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2025 12:34:56 die xxx mensis xi annoque mmxxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2461010 11 xi 11 11/30/2025 die xxx mensis xi annoque mmxxv 25 xxv 2025}
+test clock-2.1919 {conversion of 2025-12-01} {
+ clock format 1764592496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2025 12:34:56 die i mensis xii annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2461011 12 xii 12 12/01/2025 die i mensis xii annoque mmxxv 25 xxv 2025}
+test clock-2.1920 {conversion of 2025-12-31} {
+ clock format 1767184496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2025 12:34:56 die xxxi mensis xii annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2461041 12 xii 12 12/31/2025 die xxxi mensis xii annoque mmxxv 25 xxv 2025}
+test clock-2.1921 {conversion of 2037-01-01} {
+ clock format 2114426096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2037 12:34:56 die i mensis i annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2465060 01 i 1 01/01/2037 die i mensis i annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1922 {conversion of 2037-01-31} {
+ clock format 2117018096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2037 12:34:56 die xxxi mensis i annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2465090 01 i 1 01/31/2037 die xxxi mensis i annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1923 {conversion of 2037-02-01} {
+ clock format 2117104496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2037 12:34:56 die i mensis ii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2465091 02 ii 2 02/01/2037 die i mensis ii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1924 {conversion of 2037-02-28} {
+ clock format 2119437296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2037 12:34:56 die xxviii mensis ii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2465118 02 ii 2 02/28/2037 die xxviii mensis ii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1925 {conversion of 2037-03-01} {
+ clock format 2119523696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2037 12:34:56 die i mensis iii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2465119 03 iii 3 03/01/2037 die i mensis iii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1926 {conversion of 2037-03-31} {
+ clock format 2122115696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2037 12:34:56 die xxxi mensis iii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2465149 03 iii 3 03/31/2037 die xxxi mensis iii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1927 {conversion of 2037-04-01} {
+ clock format 2122202096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2037 12:34:56 die i mensis iv annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2465150 04 iv 4 04/01/2037 die i mensis iv annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1928 {conversion of 2037-04-30} {
+ clock format 2124707696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2037 12:34:56 die xxx mensis iv annoque mmxxxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2465179 04 iv 4 04/30/2037 die xxx mensis iv annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1929 {conversion of 2037-05-01} {
+ clock format 2124794096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2037 12:34:56 die i mensis v annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2465180 05 v 5 05/01/2037 die i mensis v annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1930 {conversion of 2037-05-31} {
+ clock format 2127386096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2037 12:34:56 die xxxi mensis v annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2465210 05 v 5 05/31/2037 die xxxi mensis v annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1931 {conversion of 2037-06-01} {
+ clock format 2127472496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2037 12:34:56 die i mensis vi annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2465211 06 vi 6 06/01/2037 die i mensis vi annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1932 {conversion of 2037-06-30} {
+ clock format 2129978096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2037 12:34:56 die xxx mensis vi annoque mmxxxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2465240 06 vi 6 06/30/2037 die xxx mensis vi annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1933 {conversion of 2037-07-01} {
+ clock format 2130064496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2037 12:34:56 die i mensis vii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2465241 07 vii 7 07/01/2037 die i mensis vii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1934 {conversion of 2037-07-31} {
+ clock format 2132656496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2037 12:34:56 die xxxi mensis vii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2465271 07 vii 7 07/31/2037 die xxxi mensis vii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1935 {conversion of 2037-08-01} {
+ clock format 2132742896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2037 12:34:56 die i mensis viii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2465272 08 viii 8 08/01/2037 die i mensis viii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1936 {conversion of 2037-08-31} {
+ clock format 2135334896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2037 12:34:56 die xxxi mensis viii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2465302 08 viii 8 08/31/2037 die xxxi mensis viii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1937 {conversion of 2037-09-01} {
+ clock format 2135421296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2037 12:34:56 die i mensis ix annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2465303 09 ix 9 09/01/2037 die i mensis ix annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1938 {conversion of 2037-09-30} {
+ clock format 2137926896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2037 12:34:56 die xxx mensis ix annoque mmxxxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2465332 09 ix 9 09/30/2037 die xxx mensis ix annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1939 {conversion of 2037-10-01} {
+ clock format 2138013296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2037 12:34:56 die i mensis x annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2465333 10 x 10 10/01/2037 die i mensis x annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1940 {conversion of 2037-10-31} {
+ clock format 2140605296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2037 12:34:56 die xxxi mensis x annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2465363 10 x 10 10/31/2037 die xxxi mensis x annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1941 {conversion of 2037-11-01} {
+ clock format 2140691696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2037 12:34:56 die i mensis xi annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2465364 11 xi 11 11/01/2037 die i mensis xi annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1942 {conversion of 2037-11-30} {
+ clock format 2143197296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2037 12:34:56 die xxx mensis xi annoque mmxxxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2465393 11 xi 11 11/30/2037 die xxx mensis xi annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1943 {conversion of 2037-12-01} {
+ clock format 2143283696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2037 12:34:56 die i mensis xii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2465394 12 xii 12 12/01/2037 die i mensis xii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1944 {conversion of 2037-12-31} {
+ clock format 2145875696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2037 12:34:56 die xxxi mensis xii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2465424 12 xii 12 12/31/2037 die xxxi mensis xii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1945 {conversion of 2038-01-01} {
+ clock format 2145962096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2038 12:34:56 die i mensis i annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2465425 01 i 1 01/01/2038 die i mensis i annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1946 {conversion of 2038-01-31} {
+ clock format 2148554096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2038 12:34:56 die xxxi mensis i annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2465455 01 i 1 01/31/2038 die xxxi mensis i annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1947 {conversion of 2038-02-01} {
+ clock format 2148640496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2038 12:34:56 die i mensis ii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2465456 02 ii 2 02/01/2038 die i mensis ii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1948 {conversion of 2038-02-28} {
+ clock format 2150973296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2038 12:34:56 die xxviii mensis ii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2465483 02 ii 2 02/28/2038 die xxviii mensis ii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1949 {conversion of 2038-03-01} {
+ clock format 2151059696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2038 12:34:56 die i mensis iii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2465484 03 iii 3 03/01/2038 die i mensis iii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1950 {conversion of 2038-03-31} {
+ clock format 2153651696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2038 12:34:56 die xxxi mensis iii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2465514 03 iii 3 03/31/2038 die xxxi mensis iii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1951 {conversion of 2038-04-01} {
+ clock format 2153738096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2038 12:34:56 die i mensis iv annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2465515 04 iv 4 04/01/2038 die i mensis iv annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1952 {conversion of 2038-04-30} {
+ clock format 2156243696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2038 12:34:56 die xxx mensis iv annoque mmxxxviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2465544 04 iv 4 04/30/2038 die xxx mensis iv annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1953 {conversion of 2038-05-01} {
+ clock format 2156330096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2038 12:34:56 die i mensis v annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2465545 05 v 5 05/01/2038 die i mensis v annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1954 {conversion of 2038-05-31} {
+ clock format 2158922096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2038 12:34:56 die xxxi mensis v annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2465575 05 v 5 05/31/2038 die xxxi mensis v annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1955 {conversion of 2038-06-01} {
+ clock format 2159008496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2038 12:34:56 die i mensis vi annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2465576 06 vi 6 06/01/2038 die i mensis vi annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1956 {conversion of 2038-06-30} {
+ clock format 2161514096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2038 12:34:56 die xxx mensis vi annoque mmxxxviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2465605 06 vi 6 06/30/2038 die xxx mensis vi annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1957 {conversion of 2038-07-01} {
+ clock format 2161600496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2038 12:34:56 die i mensis vii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2465606 07 vii 7 07/01/2038 die i mensis vii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1958 {conversion of 2038-07-31} {
+ clock format 2164192496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2038 12:34:56 die xxxi mensis vii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2465636 07 vii 7 07/31/2038 die xxxi mensis vii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1959 {conversion of 2038-08-01} {
+ clock format 2164278896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2038 12:34:56 die i mensis viii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2465637 08 viii 8 08/01/2038 die i mensis viii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1960 {conversion of 2038-08-31} {
+ clock format 2166870896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2038 12:34:56 die xxxi mensis viii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2465667 08 viii 8 08/31/2038 die xxxi mensis viii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1961 {conversion of 2038-09-01} {
+ clock format 2166957296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2038 12:34:56 die i mensis ix annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2465668 09 ix 9 09/01/2038 die i mensis ix annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1962 {conversion of 2038-09-30} {
+ clock format 2169462896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2038 12:34:56 die xxx mensis ix annoque mmxxxviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2465697 09 ix 9 09/30/2038 die xxx mensis ix annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1963 {conversion of 2038-10-01} {
+ clock format 2169549296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2038 12:34:56 die i mensis x annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2465698 10 x 10 10/01/2038 die i mensis x annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1964 {conversion of 2038-10-31} {
+ clock format 2172141296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2038 12:34:56 die xxxi mensis x annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2465728 10 x 10 10/31/2038 die xxxi mensis x annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1965 {conversion of 2038-11-01} {
+ clock format 2172227696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2038 12:34:56 die i mensis xi annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2465729 11 xi 11 11/01/2038 die i mensis xi annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1966 {conversion of 2038-11-30} {
+ clock format 2174733296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2038 12:34:56 die xxx mensis xi annoque mmxxxviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2465758 11 xi 11 11/30/2038 die xxx mensis xi annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1967 {conversion of 2038-12-01} {
+ clock format 2174819696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2038 12:34:56 die i mensis xii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2465759 12 xii 12 12/01/2038 die i mensis xii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1968 {conversion of 2038-12-31} {
+ clock format 2177411696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2038 12:34:56 die xxxi mensis xii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2465789 12 xii 12 12/31/2038 die xxxi mensis xii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1969 {conversion of 2039-01-01} {
+ clock format 2177498096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2039 12:34:56 die i mensis i annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2465790 01 i 1 01/01/2039 die i mensis i annoque mmxxxix 39 xxxix 2039}
+test clock-2.1970 {conversion of 2039-01-31} {
+ clock format 2180090096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2039 12:34:56 die xxxi mensis i annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2465820 01 i 1 01/31/2039 die xxxi mensis i annoque mmxxxix 39 xxxix 2039}
+test clock-2.1971 {conversion of 2039-02-01} {
+ clock format 2180176496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2039 12:34:56 die i mensis ii annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2465821 02 ii 2 02/01/2039 die i mensis ii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1972 {conversion of 2039-02-28} {
+ clock format 2182509296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2039 12:34:56 die xxviii mensis ii annoque mmxxxix xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2465848 02 ii 2 02/28/2039 die xxviii mensis ii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1973 {conversion of 2039-03-01} {
+ clock format 2182595696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2039 12:34:56 die i mensis iii annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2465849 03 iii 3 03/01/2039 die i mensis iii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1974 {conversion of 2039-03-31} {
+ clock format 2185187696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2039 12:34:56 die xxxi mensis iii annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2465879 03 iii 3 03/31/2039 die xxxi mensis iii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1975 {conversion of 2039-04-01} {
+ clock format 2185274096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2039 12:34:56 die i mensis iv annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2465880 04 iv 4 04/01/2039 die i mensis iv annoque mmxxxix 39 xxxix 2039}
+test clock-2.1976 {conversion of 2039-04-30} {
+ clock format 2187779696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2039 12:34:56 die xxx mensis iv annoque mmxxxix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2465909 04 iv 4 04/30/2039 die xxx mensis iv annoque mmxxxix 39 xxxix 2039}
+test clock-2.1977 {conversion of 2039-05-01} {
+ clock format 2187866096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2039 12:34:56 die i mensis v annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2465910 05 v 5 05/01/2039 die i mensis v annoque mmxxxix 39 xxxix 2039}
+test clock-2.1978 {conversion of 2039-05-31} {
+ clock format 2190458096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2039 12:34:56 die xxxi mensis v annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2465940 05 v 5 05/31/2039 die xxxi mensis v annoque mmxxxix 39 xxxix 2039}
+test clock-2.1979 {conversion of 2039-06-01} {
+ clock format 2190544496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2039 12:34:56 die i mensis vi annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2465941 06 vi 6 06/01/2039 die i mensis vi annoque mmxxxix 39 xxxix 2039}
+test clock-2.1980 {conversion of 2039-06-30} {
+ clock format 2193050096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2039 12:34:56 die xxx mensis vi annoque mmxxxix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2465970 06 vi 6 06/30/2039 die xxx mensis vi annoque mmxxxix 39 xxxix 2039}
+test clock-2.1981 {conversion of 2039-07-01} {
+ clock format 2193136496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2039 12:34:56 die i mensis vii annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2465971 07 vii 7 07/01/2039 die i mensis vii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1982 {conversion of 2039-07-31} {
+ clock format 2195728496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2039 12:34:56 die xxxi mensis vii annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2466001 07 vii 7 07/31/2039 die xxxi mensis vii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1983 {conversion of 2039-08-01} {
+ clock format 2195814896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2039 12:34:56 die i mensis viii annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2466002 08 viii 8 08/01/2039 die i mensis viii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1984 {conversion of 2039-08-31} {
+ clock format 2198406896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2039 12:34:56 die xxxi mensis viii annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2466032 08 viii 8 08/31/2039 die xxxi mensis viii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1985 {conversion of 2039-09-01} {
+ clock format 2198493296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2039 12:34:56 die i mensis ix annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2466033 09 ix 9 09/01/2039 die i mensis ix annoque mmxxxix 39 xxxix 2039}
+test clock-2.1986 {conversion of 2039-09-30} {
+ clock format 2200998896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2039 12:34:56 die xxx mensis ix annoque mmxxxix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2466062 09 ix 9 09/30/2039 die xxx mensis ix annoque mmxxxix 39 xxxix 2039}
+test clock-2.1987 {conversion of 2039-10-01} {
+ clock format 2201085296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2039 12:34:56 die i mensis x annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2466063 10 x 10 10/01/2039 die i mensis x annoque mmxxxix 39 xxxix 2039}
+test clock-2.1988 {conversion of 2039-10-31} {
+ clock format 2203677296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2039 12:34:56 die xxxi mensis x annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2466093 10 x 10 10/31/2039 die xxxi mensis x annoque mmxxxix 39 xxxix 2039}
+test clock-2.1989 {conversion of 2039-11-01} {
+ clock format 2203763696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2039 12:34:56 die i mensis xi annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2466094 11 xi 11 11/01/2039 die i mensis xi annoque mmxxxix 39 xxxix 2039}
+test clock-2.1990 {conversion of 2039-11-30} {
+ clock format 2206269296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2039 12:34:56 die xxx mensis xi annoque mmxxxix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2466123 11 xi 11 11/30/2039 die xxx mensis xi annoque mmxxxix 39 xxxix 2039}
+test clock-2.1991 {conversion of 2039-12-01} {
+ clock format 2206355696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2039 12:34:56 die i mensis xii annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2466124 12 xii 12 12/01/2039 die i mensis xii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1992 {conversion of 2039-12-31} {
+ clock format 2208947696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2039 12:34:56 die xxxi mensis xii annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2466154 12 xii 12 12/31/2039 die xxxi mensis xii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1993 {conversion of 2040-01-01} {
+ clock format 2209034096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2040 12:34:56 die i mensis i annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2466155 01 i 1 01/01/2040 die i mensis i annoque mmxl 40 xl 2040}
+test clock-2.1994 {conversion of 2040-01-31} {
+ clock format 2211626096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2040 12:34:56 die xxxi mensis i annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2466185 01 i 1 01/31/2040 die xxxi mensis i annoque mmxl 40 xl 2040}
+test clock-2.1995 {conversion of 2040-02-01} {
+ clock format 2211712496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2040 12:34:56 die i mensis ii annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2466186 02 ii 2 02/01/2040 die i mensis ii annoque mmxl 40 xl 2040}
+test clock-2.1996 {conversion of 2040-02-29} {
+ clock format 2214131696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2040 12:34:56 die xxix mensis ii annoque mmxl xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2466214 02 ii 2 02/29/2040 die xxix mensis ii annoque mmxl 40 xl 2040}
+test clock-2.1997 {conversion of 2040-03-01} {
+ clock format 2214218096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2040 12:34:56 die i mensis iii annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2466215 03 iii 3 03/01/2040 die i mensis iii annoque mmxl 40 xl 2040}
+test clock-2.1998 {conversion of 2040-03-31} {
+ clock format 2216810096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2040 12:34:56 die xxxi mensis iii annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2466245 03 iii 3 03/31/2040 die xxxi mensis iii annoque mmxl 40 xl 2040}
+test clock-2.1999 {conversion of 2040-04-01} {
+ clock format 2216896496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2040 12:34:56 die i mensis iv annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2466246 04 iv 4 04/01/2040 die i mensis iv annoque mmxl 40 xl 2040}
+test clock-2.2000 {conversion of 2040-04-30} {
+ clock format 2219402096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2040 12:34:56 die xxx mensis iv annoque mmxl xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2466275 04 iv 4 04/30/2040 die xxx mensis iv annoque mmxl 40 xl 2040}
+test clock-2.2001 {conversion of 2040-05-01} {
+ clock format 2219488496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2040 12:34:56 die i mensis v annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2466276 05 v 5 05/01/2040 die i mensis v annoque mmxl 40 xl 2040}
+test clock-2.2002 {conversion of 2040-05-31} {
+ clock format 2222080496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2040 12:34:56 die xxxi mensis v annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2466306 05 v 5 05/31/2040 die xxxi mensis v annoque mmxl 40 xl 2040}
+test clock-2.2003 {conversion of 2040-06-01} {
+ clock format 2222166896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2040 12:34:56 die i mensis vi annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2466307 06 vi 6 06/01/2040 die i mensis vi annoque mmxl 40 xl 2040}
+test clock-2.2004 {conversion of 2040-06-30} {
+ clock format 2224672496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2040 12:34:56 die xxx mensis vi annoque mmxl xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2466336 06 vi 6 06/30/2040 die xxx mensis vi annoque mmxl 40 xl 2040}
+test clock-2.2005 {conversion of 2040-07-01} {
+ clock format 2224758896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2040 12:34:56 die i mensis vii annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2466337 07 vii 7 07/01/2040 die i mensis vii annoque mmxl 40 xl 2040}
+test clock-2.2006 {conversion of 2040-07-31} {
+ clock format 2227350896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2040 12:34:56 die xxxi mensis vii annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2466367 07 vii 7 07/31/2040 die xxxi mensis vii annoque mmxl 40 xl 2040}
+test clock-2.2007 {conversion of 2040-08-01} {
+ clock format 2227437296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2040 12:34:56 die i mensis viii annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2466368 08 viii 8 08/01/2040 die i mensis viii annoque mmxl 40 xl 2040}
+test clock-2.2008 {conversion of 2040-08-31} {
+ clock format 2230029296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2040 12:34:56 die xxxi mensis viii annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2466398 08 viii 8 08/31/2040 die xxxi mensis viii annoque mmxl 40 xl 2040}
+test clock-2.2009 {conversion of 2040-09-01} {
+ clock format 2230115696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2040 12:34:56 die i mensis ix annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2466399 09 ix 9 09/01/2040 die i mensis ix annoque mmxl 40 xl 2040}
+test clock-2.2010 {conversion of 2040-09-30} {
+ clock format 2232621296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2040 12:34:56 die xxx mensis ix annoque mmxl xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2466428 09 ix 9 09/30/2040 die xxx mensis ix annoque mmxl 40 xl 2040}
+test clock-2.2011 {conversion of 2040-10-01} {
+ clock format 2232707696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2040 12:34:56 die i mensis x annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2466429 10 x 10 10/01/2040 die i mensis x annoque mmxl 40 xl 2040}
+test clock-2.2012 {conversion of 2040-10-31} {
+ clock format 2235299696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2040 12:34:56 die xxxi mensis x annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2466459 10 x 10 10/31/2040 die xxxi mensis x annoque mmxl 40 xl 2040}
+test clock-2.2013 {conversion of 2040-11-01} {
+ clock format 2235386096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2040 12:34:56 die i mensis xi annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2466460 11 xi 11 11/01/2040 die i mensis xi annoque mmxl 40 xl 2040}
+test clock-2.2014 {conversion of 2040-11-30} {
+ clock format 2237891696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2040 12:34:56 die xxx mensis xi annoque mmxl xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2466489 11 xi 11 11/30/2040 die xxx mensis xi annoque mmxl 40 xl 2040}
+test clock-2.2015 {conversion of 2040-12-01} {
+ clock format 2237978096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2040 12:34:56 die i mensis xii annoque mmxl xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2466490 12 xii 12 12/01/2040 die i mensis xii annoque mmxl 40 xl 2040}
+test clock-2.2016 {conversion of 2040-12-31} {
+ clock format 2240570096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2040 12:34:56 die xxxi mensis xii annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2466520 12 xii 12 12/31/2040 die xxxi mensis xii annoque mmxl 40 xl 2040}
+test clock-2.2017 {conversion of 2041-01-01} {
+ clock format 2240656496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2041 12:34:56 die i mensis i annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2466521 01 i 1 01/01/2041 die i mensis i annoque mmxli 41 xli 2041}
+test clock-2.2018 {conversion of 2041-01-31} {
+ clock format 2243248496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2041 12:34:56 die xxxi mensis i annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2466551 01 i 1 01/31/2041 die xxxi mensis i annoque mmxli 41 xli 2041}
+test clock-2.2019 {conversion of 2041-02-01} {
+ clock format 2243334896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2041 12:34:56 die i mensis ii annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2466552 02 ii 2 02/01/2041 die i mensis ii annoque mmxli 41 xli 2041}
+test clock-2.2020 {conversion of 2041-02-28} {
+ clock format 2245667696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2041 12:34:56 die xxviii mensis ii annoque mmxli xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2466579 02 ii 2 02/28/2041 die xxviii mensis ii annoque mmxli 41 xli 2041}
+test clock-2.2021 {conversion of 2041-03-01} {
+ clock format 2245754096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2041 12:34:56 die i mensis iii annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2466580 03 iii 3 03/01/2041 die i mensis iii annoque mmxli 41 xli 2041}
+test clock-2.2022 {conversion of 2041-03-31} {
+ clock format 2248346096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2041 12:34:56 die xxxi mensis iii annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2466610 03 iii 3 03/31/2041 die xxxi mensis iii annoque mmxli 41 xli 2041}
+test clock-2.2023 {conversion of 2041-04-01} {
+ clock format 2248432496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2041 12:34:56 die i mensis iv annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2466611 04 iv 4 04/01/2041 die i mensis iv annoque mmxli 41 xli 2041}
+test clock-2.2024 {conversion of 2041-04-30} {
+ clock format 2250938096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2041 12:34:56 die xxx mensis iv annoque mmxli xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2466640 04 iv 4 04/30/2041 die xxx mensis iv annoque mmxli 41 xli 2041}
+test clock-2.2025 {conversion of 2041-05-01} {
+ clock format 2251024496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2041 12:34:56 die i mensis v annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2466641 05 v 5 05/01/2041 die i mensis v annoque mmxli 41 xli 2041}
+test clock-2.2026 {conversion of 2041-05-31} {
+ clock format 2253616496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2041 12:34:56 die xxxi mensis v annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2466671 05 v 5 05/31/2041 die xxxi mensis v annoque mmxli 41 xli 2041}
+test clock-2.2027 {conversion of 2041-06-01} {
+ clock format 2253702896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2041 12:34:56 die i mensis vi annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2466672 06 vi 6 06/01/2041 die i mensis vi annoque mmxli 41 xli 2041}
+test clock-2.2028 {conversion of 2041-06-30} {
+ clock format 2256208496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2041 12:34:56 die xxx mensis vi annoque mmxli xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2466701 06 vi 6 06/30/2041 die xxx mensis vi annoque mmxli 41 xli 2041}
+test clock-2.2029 {conversion of 2041-07-01} {
+ clock format 2256294896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2041 12:34:56 die i mensis vii annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2466702 07 vii 7 07/01/2041 die i mensis vii annoque mmxli 41 xli 2041}
+test clock-2.2030 {conversion of 2041-07-31} {
+ clock format 2258886896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2041 12:34:56 die xxxi mensis vii annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2466732 07 vii 7 07/31/2041 die xxxi mensis vii annoque mmxli 41 xli 2041}
+test clock-2.2031 {conversion of 2041-08-01} {
+ clock format 2258973296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2041 12:34:56 die i mensis viii annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2466733 08 viii 8 08/01/2041 die i mensis viii annoque mmxli 41 xli 2041}
+test clock-2.2032 {conversion of 2041-08-31} {
+ clock format 2261565296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2041 12:34:56 die xxxi mensis viii annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2466763 08 viii 8 08/31/2041 die xxxi mensis viii annoque mmxli 41 xli 2041}
+test clock-2.2033 {conversion of 2041-09-01} {
+ clock format 2261651696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2041 12:34:56 die i mensis ix annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2466764 09 ix 9 09/01/2041 die i mensis ix annoque mmxli 41 xli 2041}
+test clock-2.2034 {conversion of 2041-09-30} {
+ clock format 2264157296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2041 12:34:56 die xxx mensis ix annoque mmxli xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2466793 09 ix 9 09/30/2041 die xxx mensis ix annoque mmxli 41 xli 2041}
+test clock-2.2035 {conversion of 2041-10-01} {
+ clock format 2264243696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2041 12:34:56 die i mensis x annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2466794 10 x 10 10/01/2041 die i mensis x annoque mmxli 41 xli 2041}
+test clock-2.2036 {conversion of 2041-10-31} {
+ clock format 2266835696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2041 12:34:56 die xxxi mensis x annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2466824 10 x 10 10/31/2041 die xxxi mensis x annoque mmxli 41 xli 2041}
+test clock-2.2037 {conversion of 2041-11-01} {
+ clock format 2266922096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2041 12:34:56 die i mensis xi annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2466825 11 xi 11 11/01/2041 die i mensis xi annoque mmxli 41 xli 2041}
+test clock-2.2038 {conversion of 2041-11-30} {
+ clock format 2269427696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2041 12:34:56 die xxx mensis xi annoque mmxli xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2466854 11 xi 11 11/30/2041 die xxx mensis xi annoque mmxli 41 xli 2041}
+test clock-2.2039 {conversion of 2041-12-01} {
+ clock format 2269514096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2041 12:34:56 die i mensis xii annoque mmxli xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2466855 12 xii 12 12/01/2041 die i mensis xii annoque mmxli 41 xli 2041}
+test clock-2.2040 {conversion of 2041-12-31} {
+ clock format 2272106096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2041 12:34:56 die xxxi mensis xii annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2466885 12 xii 12 12/31/2041 die xxxi mensis xii annoque mmxli 41 xli 2041}
+test clock-2.2041 {conversion of 2042-01-01} {
+ clock format 2272192496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2042 12:34:56 die i mensis i annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2466886 01 i 1 01/01/2042 die i mensis i annoque mmxlii 42 xlii 2042}
+test clock-2.2042 {conversion of 2042-01-31} {
+ clock format 2274784496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2042 12:34:56 die xxxi mensis i annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2466916 01 i 1 01/31/2042 die xxxi mensis i annoque mmxlii 42 xlii 2042}
+test clock-2.2043 {conversion of 2042-02-01} {
+ clock format 2274870896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2042 12:34:56 die i mensis ii annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2466917 02 ii 2 02/01/2042 die i mensis ii annoque mmxlii 42 xlii 2042}
+test clock-2.2044 {conversion of 2042-02-28} {
+ clock format 2277203696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2042 12:34:56 die xxviii mensis ii annoque mmxlii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2466944 02 ii 2 02/28/2042 die xxviii mensis ii annoque mmxlii 42 xlii 2042}
+test clock-2.2045 {conversion of 2042-03-01} {
+ clock format 2277290096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2042 12:34:56 die i mensis iii annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2466945 03 iii 3 03/01/2042 die i mensis iii annoque mmxlii 42 xlii 2042}
+test clock-2.2046 {conversion of 2042-03-31} {
+ clock format 2279882096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2042 12:34:56 die xxxi mensis iii annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2466975 03 iii 3 03/31/2042 die xxxi mensis iii annoque mmxlii 42 xlii 2042}
+test clock-2.2047 {conversion of 2042-04-01} {
+ clock format 2279968496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2042 12:34:56 die i mensis iv annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2466976 04 iv 4 04/01/2042 die i mensis iv annoque mmxlii 42 xlii 2042}
+test clock-2.2048 {conversion of 2042-04-30} {
+ clock format 2282474096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2042 12:34:56 die xxx mensis iv annoque mmxlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2467005 04 iv 4 04/30/2042 die xxx mensis iv annoque mmxlii 42 xlii 2042}
+test clock-2.2049 {conversion of 2042-05-01} {
+ clock format 2282560496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2042 12:34:56 die i mensis v annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2467006 05 v 5 05/01/2042 die i mensis v annoque mmxlii 42 xlii 2042}
+test clock-2.2050 {conversion of 2042-05-31} {
+ clock format 2285152496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2042 12:34:56 die xxxi mensis v annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2467036 05 v 5 05/31/2042 die xxxi mensis v annoque mmxlii 42 xlii 2042}
+test clock-2.2051 {conversion of 2042-06-01} {
+ clock format 2285238896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2042 12:34:56 die i mensis vi annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2467037 06 vi 6 06/01/2042 die i mensis vi annoque mmxlii 42 xlii 2042}
+test clock-2.2052 {conversion of 2042-06-30} {
+ clock format 2287744496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2042 12:34:56 die xxx mensis vi annoque mmxlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2467066 06 vi 6 06/30/2042 die xxx mensis vi annoque mmxlii 42 xlii 2042}
+test clock-2.2053 {conversion of 2042-07-01} {
+ clock format 2287830896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2042 12:34:56 die i mensis vii annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2467067 07 vii 7 07/01/2042 die i mensis vii annoque mmxlii 42 xlii 2042}
+test clock-2.2054 {conversion of 2042-07-31} {
+ clock format 2290422896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2042 12:34:56 die xxxi mensis vii annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2467097 07 vii 7 07/31/2042 die xxxi mensis vii annoque mmxlii 42 xlii 2042}
+test clock-2.2055 {conversion of 2042-08-01} {
+ clock format 2290509296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2042 12:34:56 die i mensis viii annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2467098 08 viii 8 08/01/2042 die i mensis viii annoque mmxlii 42 xlii 2042}
+test clock-2.2056 {conversion of 2042-08-31} {
+ clock format 2293101296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2042 12:34:56 die xxxi mensis viii annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2467128 08 viii 8 08/31/2042 die xxxi mensis viii annoque mmxlii 42 xlii 2042}
+test clock-2.2057 {conversion of 2042-09-01} {
+ clock format 2293187696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2042 12:34:56 die i mensis ix annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2467129 09 ix 9 09/01/2042 die i mensis ix annoque mmxlii 42 xlii 2042}
+test clock-2.2058 {conversion of 2042-09-30} {
+ clock format 2295693296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2042 12:34:56 die xxx mensis ix annoque mmxlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2467158 09 ix 9 09/30/2042 die xxx mensis ix annoque mmxlii 42 xlii 2042}
+test clock-2.2059 {conversion of 2042-10-01} {
+ clock format 2295779696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2042 12:34:56 die i mensis x annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2467159 10 x 10 10/01/2042 die i mensis x annoque mmxlii 42 xlii 2042}
+test clock-2.2060 {conversion of 2042-10-31} {
+ clock format 2298371696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2042 12:34:56 die xxxi mensis x annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2467189 10 x 10 10/31/2042 die xxxi mensis x annoque mmxlii 42 xlii 2042}
+test clock-2.2061 {conversion of 2042-11-01} {
+ clock format 2298458096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2042 12:34:56 die i mensis xi annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2467190 11 xi 11 11/01/2042 die i mensis xi annoque mmxlii 42 xlii 2042}
+test clock-2.2062 {conversion of 2042-11-30} {
+ clock format 2300963696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2042 12:34:56 die xxx mensis xi annoque mmxlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2467219 11 xi 11 11/30/2042 die xxx mensis xi annoque mmxlii 42 xlii 2042}
+test clock-2.2063 {conversion of 2042-12-01} {
+ clock format 2301050096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2042 12:34:56 die i mensis xii annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2467220 12 xii 12 12/01/2042 die i mensis xii annoque mmxlii 42 xlii 2042}
+test clock-2.2064 {conversion of 2042-12-31} {
+ clock format 2303642096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2042 12:34:56 die xxxi mensis xii annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2467250 12 xii 12 12/31/2042 die xxxi mensis xii annoque mmxlii 42 xlii 2042}
+test clock-2.2065 {conversion of 2043-01-01} {
+ clock format 2303728496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2043 12:34:56 die i mensis i annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2467251 01 i 1 01/01/2043 die i mensis i annoque mmxliii 43 xliii 2043}
+test clock-2.2066 {conversion of 2043-01-31} {
+ clock format 2306320496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2043 12:34:56 die xxxi mensis i annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2467281 01 i 1 01/31/2043 die xxxi mensis i annoque mmxliii 43 xliii 2043}
+test clock-2.2067 {conversion of 2043-02-01} {
+ clock format 2306406896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2043 12:34:56 die i mensis ii annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2467282 02 ii 2 02/01/2043 die i mensis ii annoque mmxliii 43 xliii 2043}
+test clock-2.2068 {conversion of 2043-02-28} {
+ clock format 2308739696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2043 12:34:56 die xxviii mensis ii annoque mmxliii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2467309 02 ii 2 02/28/2043 die xxviii mensis ii annoque mmxliii 43 xliii 2043}
+test clock-2.2069 {conversion of 2043-03-01} {
+ clock format 2308826096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2043 12:34:56 die i mensis iii annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2467310 03 iii 3 03/01/2043 die i mensis iii annoque mmxliii 43 xliii 2043}
+test clock-2.2070 {conversion of 2043-03-31} {
+ clock format 2311418096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2043 12:34:56 die xxxi mensis iii annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2467340 03 iii 3 03/31/2043 die xxxi mensis iii annoque mmxliii 43 xliii 2043}
+test clock-2.2071 {conversion of 2043-04-01} {
+ clock format 2311504496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2043 12:34:56 die i mensis iv annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2467341 04 iv 4 04/01/2043 die i mensis iv annoque mmxliii 43 xliii 2043}
+test clock-2.2072 {conversion of 2043-04-30} {
+ clock format 2314010096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2043 12:34:56 die xxx mensis iv annoque mmxliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2467370 04 iv 4 04/30/2043 die xxx mensis iv annoque mmxliii 43 xliii 2043}
+test clock-2.2073 {conversion of 2043-05-01} {
+ clock format 2314096496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2043 12:34:56 die i mensis v annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2467371 05 v 5 05/01/2043 die i mensis v annoque mmxliii 43 xliii 2043}
+test clock-2.2074 {conversion of 2043-05-31} {
+ clock format 2316688496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2043 12:34:56 die xxxi mensis v annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2467401 05 v 5 05/31/2043 die xxxi mensis v annoque mmxliii 43 xliii 2043}
+test clock-2.2075 {conversion of 2043-06-01} {
+ clock format 2316774896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2043 12:34:56 die i mensis vi annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2467402 06 vi 6 06/01/2043 die i mensis vi annoque mmxliii 43 xliii 2043}
+test clock-2.2076 {conversion of 2043-06-30} {
+ clock format 2319280496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2043 12:34:56 die xxx mensis vi annoque mmxliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2467431 06 vi 6 06/30/2043 die xxx mensis vi annoque mmxliii 43 xliii 2043}
+test clock-2.2077 {conversion of 2043-07-01} {
+ clock format 2319366896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2043 12:34:56 die i mensis vii annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2467432 07 vii 7 07/01/2043 die i mensis vii annoque mmxliii 43 xliii 2043}
+test clock-2.2078 {conversion of 2043-07-31} {
+ clock format 2321958896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2043 12:34:56 die xxxi mensis vii annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2467462 07 vii 7 07/31/2043 die xxxi mensis vii annoque mmxliii 43 xliii 2043}
+test clock-2.2079 {conversion of 2043-08-01} {
+ clock format 2322045296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2043 12:34:56 die i mensis viii annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2467463 08 viii 8 08/01/2043 die i mensis viii annoque mmxliii 43 xliii 2043}
+test clock-2.2080 {conversion of 2043-08-31} {
+ clock format 2324637296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2043 12:34:56 die xxxi mensis viii annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2467493 08 viii 8 08/31/2043 die xxxi mensis viii annoque mmxliii 43 xliii 2043}
+test clock-2.2081 {conversion of 2043-09-01} {
+ clock format 2324723696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2043 12:34:56 die i mensis ix annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2467494 09 ix 9 09/01/2043 die i mensis ix annoque mmxliii 43 xliii 2043}
+test clock-2.2082 {conversion of 2043-09-30} {
+ clock format 2327229296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2043 12:34:56 die xxx mensis ix annoque mmxliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2467523 09 ix 9 09/30/2043 die xxx mensis ix annoque mmxliii 43 xliii 2043}
+test clock-2.2083 {conversion of 2043-10-01} {
+ clock format 2327315696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2043 12:34:56 die i mensis x annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2467524 10 x 10 10/01/2043 die i mensis x annoque mmxliii 43 xliii 2043}
+test clock-2.2084 {conversion of 2043-10-31} {
+ clock format 2329907696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2043 12:34:56 die xxxi mensis x annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2467554 10 x 10 10/31/2043 die xxxi mensis x annoque mmxliii 43 xliii 2043}
+test clock-2.2085 {conversion of 2043-11-01} {
+ clock format 2329994096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2043 12:34:56 die i mensis xi annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2467555 11 xi 11 11/01/2043 die i mensis xi annoque mmxliii 43 xliii 2043}
+test clock-2.2086 {conversion of 2043-11-30} {
+ clock format 2332499696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2043 12:34:56 die xxx mensis xi annoque mmxliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2467584 11 xi 11 11/30/2043 die xxx mensis xi annoque mmxliii 43 xliii 2043}
+test clock-2.2087 {conversion of 2043-12-01} {
+ clock format 2332586096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2043 12:34:56 die i mensis xii annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2467585 12 xii 12 12/01/2043 die i mensis xii annoque mmxliii 43 xliii 2043}
+test clock-2.2088 {conversion of 2043-12-31} {
+ clock format 2335178096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2043 12:34:56 die xxxi mensis xii annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2467615 12 xii 12 12/31/2043 die xxxi mensis xii annoque mmxliii 43 xliii 2043}
+test clock-2.2089 {conversion of 2044-01-01} {
+ clock format 2335264496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2044 12:34:56 die i mensis i annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2467616 01 i 1 01/01/2044 die i mensis i annoque mmxliv 44 xliv 2044}
+test clock-2.2090 {conversion of 2044-01-31} {
+ clock format 2337856496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2044 12:34:56 die xxxi mensis i annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2467646 01 i 1 01/31/2044 die xxxi mensis i annoque mmxliv 44 xliv 2044}
+test clock-2.2091 {conversion of 2044-02-01} {
+ clock format 2337942896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2044 12:34:56 die i mensis ii annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2467647 02 ii 2 02/01/2044 die i mensis ii annoque mmxliv 44 xliv 2044}
+test clock-2.2092 {conversion of 2044-02-29} {
+ clock format 2340362096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2044 12:34:56 die xxix mensis ii annoque mmxliv xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2467675 02 ii 2 02/29/2044 die xxix mensis ii annoque mmxliv 44 xliv 2044}
+test clock-2.2093 {conversion of 2044-03-01} {
+ clock format 2340448496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2044 12:34:56 die i mensis iii annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2467676 03 iii 3 03/01/2044 die i mensis iii annoque mmxliv 44 xliv 2044}
+test clock-2.2094 {conversion of 2044-03-31} {
+ clock format 2343040496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2044 12:34:56 die xxxi mensis iii annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2467706 03 iii 3 03/31/2044 die xxxi mensis iii annoque mmxliv 44 xliv 2044}
+test clock-2.2095 {conversion of 2044-04-01} {
+ clock format 2343126896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2044 12:34:56 die i mensis iv annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2467707 04 iv 4 04/01/2044 die i mensis iv annoque mmxliv 44 xliv 2044}
+test clock-2.2096 {conversion of 2044-04-30} {
+ clock format 2345632496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2044 12:34:56 die xxx mensis iv annoque mmxliv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2467736 04 iv 4 04/30/2044 die xxx mensis iv annoque mmxliv 44 xliv 2044}
+test clock-2.2097 {conversion of 2044-05-01} {
+ clock format 2345718896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2044 12:34:56 die i mensis v annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2467737 05 v 5 05/01/2044 die i mensis v annoque mmxliv 44 xliv 2044}
+test clock-2.2098 {conversion of 2044-05-31} {
+ clock format 2348310896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2044 12:34:56 die xxxi mensis v annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2467767 05 v 5 05/31/2044 die xxxi mensis v annoque mmxliv 44 xliv 2044}
+test clock-2.2099 {conversion of 2044-06-01} {
+ clock format 2348397296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2044 12:34:56 die i mensis vi annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2467768 06 vi 6 06/01/2044 die i mensis vi annoque mmxliv 44 xliv 2044}
+test clock-2.2100 {conversion of 2044-06-30} {
+ clock format 2350902896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2044 12:34:56 die xxx mensis vi annoque mmxliv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2467797 06 vi 6 06/30/2044 die xxx mensis vi annoque mmxliv 44 xliv 2044}
+test clock-2.2101 {conversion of 2044-07-01} {
+ clock format 2350989296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2044 12:34:56 die i mensis vii annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2467798 07 vii 7 07/01/2044 die i mensis vii annoque mmxliv 44 xliv 2044}
+test clock-2.2102 {conversion of 2044-07-31} {
+ clock format 2353581296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2044 12:34:56 die xxxi mensis vii annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2467828 07 vii 7 07/31/2044 die xxxi mensis vii annoque mmxliv 44 xliv 2044}
+test clock-2.2103 {conversion of 2044-08-01} {
+ clock format 2353667696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2044 12:34:56 die i mensis viii annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2467829 08 viii 8 08/01/2044 die i mensis viii annoque mmxliv 44 xliv 2044}
+test clock-2.2104 {conversion of 2044-08-31} {
+ clock format 2356259696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2044 12:34:56 die xxxi mensis viii annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2467859 08 viii 8 08/31/2044 die xxxi mensis viii annoque mmxliv 44 xliv 2044}
+test clock-2.2105 {conversion of 2044-09-01} {
+ clock format 2356346096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2044 12:34:56 die i mensis ix annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2467860 09 ix 9 09/01/2044 die i mensis ix annoque mmxliv 44 xliv 2044}
+test clock-2.2106 {conversion of 2044-09-30} {
+ clock format 2358851696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2044 12:34:56 die xxx mensis ix annoque mmxliv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2467889 09 ix 9 09/30/2044 die xxx mensis ix annoque mmxliv 44 xliv 2044}
+test clock-2.2107 {conversion of 2044-10-01} {
+ clock format 2358938096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2044 12:34:56 die i mensis x annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2467890 10 x 10 10/01/2044 die i mensis x annoque mmxliv 44 xliv 2044}
+test clock-2.2108 {conversion of 2044-10-31} {
+ clock format 2361530096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2044 12:34:56 die xxxi mensis x annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2467920 10 x 10 10/31/2044 die xxxi mensis x annoque mmxliv 44 xliv 2044}
+test clock-2.2109 {conversion of 2044-11-01} {
+ clock format 2361616496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2044 12:34:56 die i mensis xi annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2467921 11 xi 11 11/01/2044 die i mensis xi annoque mmxliv 44 xliv 2044}
+test clock-2.2110 {conversion of 2044-11-30} {
+ clock format 2364122096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2044 12:34:56 die xxx mensis xi annoque mmxliv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2467950 11 xi 11 11/30/2044 die xxx mensis xi annoque mmxliv 44 xliv 2044}
+test clock-2.2111 {conversion of 2044-12-01} {
+ clock format 2364208496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2044 12:34:56 die i mensis xii annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2467951 12 xii 12 12/01/2044 die i mensis xii annoque mmxliv 44 xliv 2044}
+test clock-2.2112 {conversion of 2044-12-31} {
+ clock format 2366800496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2044 12:34:56 die xxxi mensis xii annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2467981 12 xii 12 12/31/2044 die xxxi mensis xii annoque mmxliv 44 xliv 2044}
+test clock-2.2113 {conversion of 2045-01-01} {
+ clock format 2366886896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2045 12:34:56 die i mensis i annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2467982 01 i 1 01/01/2045 die i mensis i annoque mmxlv 45 xlv 2045}
+test clock-2.2114 {conversion of 2045-01-31} {
+ clock format 2369478896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2045 12:34:56 die xxxi mensis i annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2468012 01 i 1 01/31/2045 die xxxi mensis i annoque mmxlv 45 xlv 2045}
+test clock-2.2115 {conversion of 2045-02-01} {
+ clock format 2369565296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2045 12:34:56 die i mensis ii annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2468013 02 ii 2 02/01/2045 die i mensis ii annoque mmxlv 45 xlv 2045}
+test clock-2.2116 {conversion of 2045-02-28} {
+ clock format 2371898096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2045 12:34:56 die xxviii mensis ii annoque mmxlv xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2468040 02 ii 2 02/28/2045 die xxviii mensis ii annoque mmxlv 45 xlv 2045}
+test clock-2.2117 {conversion of 2045-03-01} {
+ clock format 2371984496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2045 12:34:56 die i mensis iii annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2468041 03 iii 3 03/01/2045 die i mensis iii annoque mmxlv 45 xlv 2045}
+test clock-2.2118 {conversion of 2045-03-31} {
+ clock format 2374576496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2045 12:34:56 die xxxi mensis iii annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2468071 03 iii 3 03/31/2045 die xxxi mensis iii annoque mmxlv 45 xlv 2045}
+test clock-2.2119 {conversion of 2045-04-01} {
+ clock format 2374662896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2045 12:34:56 die i mensis iv annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2468072 04 iv 4 04/01/2045 die i mensis iv annoque mmxlv 45 xlv 2045}
+test clock-2.2120 {conversion of 2045-04-30} {
+ clock format 2377168496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2045 12:34:56 die xxx mensis iv annoque mmxlv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2468101 04 iv 4 04/30/2045 die xxx mensis iv annoque mmxlv 45 xlv 2045}
+test clock-2.2121 {conversion of 2045-05-01} {
+ clock format 2377254896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2045 12:34:56 die i mensis v annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2468102 05 v 5 05/01/2045 die i mensis v annoque mmxlv 45 xlv 2045}
+test clock-2.2122 {conversion of 2045-05-31} {
+ clock format 2379846896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2045 12:34:56 die xxxi mensis v annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2468132 05 v 5 05/31/2045 die xxxi mensis v annoque mmxlv 45 xlv 2045}
+test clock-2.2123 {conversion of 2045-06-01} {
+ clock format 2379933296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2045 12:34:56 die i mensis vi annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2468133 06 vi 6 06/01/2045 die i mensis vi annoque mmxlv 45 xlv 2045}
+test clock-2.2124 {conversion of 2045-06-30} {
+ clock format 2382438896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2045 12:34:56 die xxx mensis vi annoque mmxlv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2468162 06 vi 6 06/30/2045 die xxx mensis vi annoque mmxlv 45 xlv 2045}
+test clock-2.2125 {conversion of 2045-07-01} {
+ clock format 2382525296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2045 12:34:56 die i mensis vii annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2468163 07 vii 7 07/01/2045 die i mensis vii annoque mmxlv 45 xlv 2045}
+test clock-2.2126 {conversion of 2045-07-31} {
+ clock format 2385117296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2045 12:34:56 die xxxi mensis vii annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2468193 07 vii 7 07/31/2045 die xxxi mensis vii annoque mmxlv 45 xlv 2045}
+test clock-2.2127 {conversion of 2045-08-01} {
+ clock format 2385203696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2045 12:34:56 die i mensis viii annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2468194 08 viii 8 08/01/2045 die i mensis viii annoque mmxlv 45 xlv 2045}
+test clock-2.2128 {conversion of 2045-08-31} {
+ clock format 2387795696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2045 12:34:56 die xxxi mensis viii annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2468224 08 viii 8 08/31/2045 die xxxi mensis viii annoque mmxlv 45 xlv 2045}
+test clock-2.2129 {conversion of 2045-09-01} {
+ clock format 2387882096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2045 12:34:56 die i mensis ix annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2468225 09 ix 9 09/01/2045 die i mensis ix annoque mmxlv 45 xlv 2045}
+test clock-2.2130 {conversion of 2045-09-30} {
+ clock format 2390387696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2045 12:34:56 die xxx mensis ix annoque mmxlv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2468254 09 ix 9 09/30/2045 die xxx mensis ix annoque mmxlv 45 xlv 2045}
+test clock-2.2131 {conversion of 2045-10-01} {
+ clock format 2390474096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2045 12:34:56 die i mensis x annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2468255 10 x 10 10/01/2045 die i mensis x annoque mmxlv 45 xlv 2045}
+test clock-2.2132 {conversion of 2045-10-31} {
+ clock format 2393066096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2045 12:34:56 die xxxi mensis x annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2468285 10 x 10 10/31/2045 die xxxi mensis x annoque mmxlv 45 xlv 2045}
+test clock-2.2133 {conversion of 2045-11-01} {
+ clock format 2393152496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2045 12:34:56 die i mensis xi annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2468286 11 xi 11 11/01/2045 die i mensis xi annoque mmxlv 45 xlv 2045}
+test clock-2.2134 {conversion of 2045-11-30} {
+ clock format 2395658096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2045 12:34:56 die xxx mensis xi annoque mmxlv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2468315 11 xi 11 11/30/2045 die xxx mensis xi annoque mmxlv 45 xlv 2045}
+test clock-2.2135 {conversion of 2045-12-01} {
+ clock format 2395744496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2045 12:34:56 die i mensis xii annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2468316 12 xii 12 12/01/2045 die i mensis xii annoque mmxlv 45 xlv 2045}
+test clock-2.2136 {conversion of 2045-12-31} {
+ clock format 2398336496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2045 12:34:56 die xxxi mensis xii annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2468346 12 xii 12 12/31/2045 die xxxi mensis xii annoque mmxlv 45 xlv 2045}
+test clock-2.2137 {conversion of 2046-01-01} {
+ clock format 2398422896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2046 12:34:56 die i mensis i annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2468347 01 i 1 01/01/2046 die i mensis i annoque mmxlvi 46 xlvi 2046}
+test clock-2.2138 {conversion of 2046-01-31} {
+ clock format 2401014896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2046 12:34:56 die xxxi mensis i annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2468377 01 i 1 01/31/2046 die xxxi mensis i annoque mmxlvi 46 xlvi 2046}
+test clock-2.2139 {conversion of 2046-02-01} {
+ clock format 2401101296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2046 12:34:56 die i mensis ii annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2468378 02 ii 2 02/01/2046 die i mensis ii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2140 {conversion of 2046-02-28} {
+ clock format 2403434096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2046 12:34:56 die xxviii mensis ii annoque mmxlvi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2468405 02 ii 2 02/28/2046 die xxviii mensis ii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2141 {conversion of 2046-03-01} {
+ clock format 2403520496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2046 12:34:56 die i mensis iii annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2468406 03 iii 3 03/01/2046 die i mensis iii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2142 {conversion of 2046-03-31} {
+ clock format 2406112496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2046 12:34:56 die xxxi mensis iii annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2468436 03 iii 3 03/31/2046 die xxxi mensis iii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2143 {conversion of 2046-04-01} {
+ clock format 2406198896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2046 12:34:56 die i mensis iv annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2468437 04 iv 4 04/01/2046 die i mensis iv annoque mmxlvi 46 xlvi 2046}
+test clock-2.2144 {conversion of 2046-04-30} {
+ clock format 2408704496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2046 12:34:56 die xxx mensis iv annoque mmxlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2468466 04 iv 4 04/30/2046 die xxx mensis iv annoque mmxlvi 46 xlvi 2046}
+test clock-2.2145 {conversion of 2046-05-01} {
+ clock format 2408790896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2046 12:34:56 die i mensis v annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2468467 05 v 5 05/01/2046 die i mensis v annoque mmxlvi 46 xlvi 2046}
+test clock-2.2146 {conversion of 2046-05-31} {
+ clock format 2411382896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2046 12:34:56 die xxxi mensis v annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2468497 05 v 5 05/31/2046 die xxxi mensis v annoque mmxlvi 46 xlvi 2046}
+test clock-2.2147 {conversion of 2046-06-01} {
+ clock format 2411469296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2046 12:34:56 die i mensis vi annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2468498 06 vi 6 06/01/2046 die i mensis vi annoque mmxlvi 46 xlvi 2046}
+test clock-2.2148 {conversion of 2046-06-30} {
+ clock format 2413974896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2046 12:34:56 die xxx mensis vi annoque mmxlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2468527 06 vi 6 06/30/2046 die xxx mensis vi annoque mmxlvi 46 xlvi 2046}
+test clock-2.2149 {conversion of 2046-07-01} {
+ clock format 2414061296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2046 12:34:56 die i mensis vii annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2468528 07 vii 7 07/01/2046 die i mensis vii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2150 {conversion of 2046-07-31} {
+ clock format 2416653296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2046 12:34:56 die xxxi mensis vii annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2468558 07 vii 7 07/31/2046 die xxxi mensis vii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2151 {conversion of 2046-08-01} {
+ clock format 2416739696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2046 12:34:56 die i mensis viii annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2468559 08 viii 8 08/01/2046 die i mensis viii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2152 {conversion of 2046-08-31} {
+ clock format 2419331696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2046 12:34:56 die xxxi mensis viii annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2468589 08 viii 8 08/31/2046 die xxxi mensis viii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2153 {conversion of 2046-09-01} {
+ clock format 2419418096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2046 12:34:56 die i mensis ix annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2468590 09 ix 9 09/01/2046 die i mensis ix annoque mmxlvi 46 xlvi 2046}
+test clock-2.2154 {conversion of 2046-09-30} {
+ clock format 2421923696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2046 12:34:56 die xxx mensis ix annoque mmxlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2468619 09 ix 9 09/30/2046 die xxx mensis ix annoque mmxlvi 46 xlvi 2046}
+test clock-2.2155 {conversion of 2046-10-01} {
+ clock format 2422010096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2046 12:34:56 die i mensis x annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2468620 10 x 10 10/01/2046 die i mensis x annoque mmxlvi 46 xlvi 2046}
+test clock-2.2156 {conversion of 2046-10-31} {
+ clock format 2424602096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2046 12:34:56 die xxxi mensis x annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2468650 10 x 10 10/31/2046 die xxxi mensis x annoque mmxlvi 46 xlvi 2046}
+test clock-2.2157 {conversion of 2046-11-01} {
+ clock format 2424688496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2046 12:34:56 die i mensis xi annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2468651 11 xi 11 11/01/2046 die i mensis xi annoque mmxlvi 46 xlvi 2046}
+test clock-2.2158 {conversion of 2046-11-30} {
+ clock format 2427194096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2046 12:34:56 die xxx mensis xi annoque mmxlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2468680 11 xi 11 11/30/2046 die xxx mensis xi annoque mmxlvi 46 xlvi 2046}
+test clock-2.2159 {conversion of 2046-12-01} {
+ clock format 2427280496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2046 12:34:56 die i mensis xii annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2468681 12 xii 12 12/01/2046 die i mensis xii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2160 {conversion of 2046-12-31} {
+ clock format 2429872496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2046 12:34:56 die xxxi mensis xii annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2468711 12 xii 12 12/31/2046 die xxxi mensis xii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2161 {conversion of 2047-01-01} {
+ clock format 2429958896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2047 12:34:56 die i mensis i annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2468712 01 i 1 01/01/2047 die i mensis i annoque mmxlvii 47 xlvii 2047}
+test clock-2.2162 {conversion of 2047-01-31} {
+ clock format 2432550896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2047 12:34:56 die xxxi mensis i annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2468742 01 i 1 01/31/2047 die xxxi mensis i annoque mmxlvii 47 xlvii 2047}
+test clock-2.2163 {conversion of 2047-02-01} {
+ clock format 2432637296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2047 12:34:56 die i mensis ii annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2468743 02 ii 2 02/01/2047 die i mensis ii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2164 {conversion of 2047-02-28} {
+ clock format 2434970096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2047 12:34:56 die xxviii mensis ii annoque mmxlvii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2468770 02 ii 2 02/28/2047 die xxviii mensis ii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2165 {conversion of 2047-03-01} {
+ clock format 2435056496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2047 12:34:56 die i mensis iii annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2468771 03 iii 3 03/01/2047 die i mensis iii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2166 {conversion of 2047-03-31} {
+ clock format 2437648496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2047 12:34:56 die xxxi mensis iii annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2468801 03 iii 3 03/31/2047 die xxxi mensis iii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2167 {conversion of 2047-04-01} {
+ clock format 2437734896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2047 12:34:56 die i mensis iv annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2468802 04 iv 4 04/01/2047 die i mensis iv annoque mmxlvii 47 xlvii 2047}
+test clock-2.2168 {conversion of 2047-04-30} {
+ clock format 2440240496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2047 12:34:56 die xxx mensis iv annoque mmxlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2468831 04 iv 4 04/30/2047 die xxx mensis iv annoque mmxlvii 47 xlvii 2047}
+test clock-2.2169 {conversion of 2047-05-01} {
+ clock format 2440326896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2047 12:34:56 die i mensis v annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2468832 05 v 5 05/01/2047 die i mensis v annoque mmxlvii 47 xlvii 2047}
+test clock-2.2170 {conversion of 2047-05-31} {
+ clock format 2442918896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2047 12:34:56 die xxxi mensis v annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2468862 05 v 5 05/31/2047 die xxxi mensis v annoque mmxlvii 47 xlvii 2047}
+test clock-2.2171 {conversion of 2047-06-01} {
+ clock format 2443005296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2047 12:34:56 die i mensis vi annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2468863 06 vi 6 06/01/2047 die i mensis vi annoque mmxlvii 47 xlvii 2047}
+test clock-2.2172 {conversion of 2047-06-30} {
+ clock format 2445510896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2047 12:34:56 die xxx mensis vi annoque mmxlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2468892 06 vi 6 06/30/2047 die xxx mensis vi annoque mmxlvii 47 xlvii 2047}
+test clock-2.2173 {conversion of 2047-07-01} {
+ clock format 2445597296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2047 12:34:56 die i mensis vii annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2468893 07 vii 7 07/01/2047 die i mensis vii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2174 {conversion of 2047-07-31} {
+ clock format 2448189296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2047 12:34:56 die xxxi mensis vii annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2468923 07 vii 7 07/31/2047 die xxxi mensis vii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2175 {conversion of 2047-08-01} {
+ clock format 2448275696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2047 12:34:56 die i mensis viii annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2468924 08 viii 8 08/01/2047 die i mensis viii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2176 {conversion of 2047-08-31} {
+ clock format 2450867696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2047 12:34:56 die xxxi mensis viii annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2468954 08 viii 8 08/31/2047 die xxxi mensis viii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2177 {conversion of 2047-09-01} {
+ clock format 2450954096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2047 12:34:56 die i mensis ix annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2468955 09 ix 9 09/01/2047 die i mensis ix annoque mmxlvii 47 xlvii 2047}
+test clock-2.2178 {conversion of 2047-09-30} {
+ clock format 2453459696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2047 12:34:56 die xxx mensis ix annoque mmxlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2468984 09 ix 9 09/30/2047 die xxx mensis ix annoque mmxlvii 47 xlvii 2047}
+test clock-2.2179 {conversion of 2047-10-01} {
+ clock format 2453546096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2047 12:34:56 die i mensis x annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2468985 10 x 10 10/01/2047 die i mensis x annoque mmxlvii 47 xlvii 2047}
+test clock-2.2180 {conversion of 2047-10-31} {
+ clock format 2456138096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2047 12:34:56 die xxxi mensis x annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2469015 10 x 10 10/31/2047 die xxxi mensis x annoque mmxlvii 47 xlvii 2047}
+test clock-2.2181 {conversion of 2047-11-01} {
+ clock format 2456224496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2047 12:34:56 die i mensis xi annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2469016 11 xi 11 11/01/2047 die i mensis xi annoque mmxlvii 47 xlvii 2047}
+test clock-2.2182 {conversion of 2047-11-30} {
+ clock format 2458730096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2047 12:34:56 die xxx mensis xi annoque mmxlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2469045 11 xi 11 11/30/2047 die xxx mensis xi annoque mmxlvii 47 xlvii 2047}
+test clock-2.2183 {conversion of 2047-12-01} {
+ clock format 2458816496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2047 12:34:56 die i mensis xii annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2469046 12 xii 12 12/01/2047 die i mensis xii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2184 {conversion of 2047-12-31} {
+ clock format 2461408496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2047 12:34:56 die xxxi mensis xii annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2469076 12 xii 12 12/31/2047 die xxxi mensis xii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2185 {conversion of 2048-01-01} {
+ clock format 2461494896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2048 12:34:56 die i mensis i annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2469077 01 i 1 01/01/2048 die i mensis i annoque mmxlviii 48 xlviii 2048}
+test clock-2.2186 {conversion of 2048-01-31} {
+ clock format 2464086896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2048 12:34:56 die xxxi mensis i annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2469107 01 i 1 01/31/2048 die xxxi mensis i annoque mmxlviii 48 xlviii 2048}
+test clock-2.2187 {conversion of 2048-02-01} {
+ clock format 2464173296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2048 12:34:56 die i mensis ii annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2469108 02 ii 2 02/01/2048 die i mensis ii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2188 {conversion of 2048-02-29} {
+ clock format 2466592496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2048 12:34:56 die xxix mensis ii annoque mmxlviii xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2469136 02 ii 2 02/29/2048 die xxix mensis ii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2189 {conversion of 2048-03-01} {
+ clock format 2466678896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2048 12:34:56 die i mensis iii annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2469137 03 iii 3 03/01/2048 die i mensis iii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2190 {conversion of 2048-03-31} {
+ clock format 2469270896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2048 12:34:56 die xxxi mensis iii annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2469167 03 iii 3 03/31/2048 die xxxi mensis iii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2191 {conversion of 2048-04-01} {
+ clock format 2469357296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2048 12:34:56 die i mensis iv annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2469168 04 iv 4 04/01/2048 die i mensis iv annoque mmxlviii 48 xlviii 2048}
+test clock-2.2192 {conversion of 2048-04-30} {
+ clock format 2471862896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2048 12:34:56 die xxx mensis iv annoque mmxlviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2469197 04 iv 4 04/30/2048 die xxx mensis iv annoque mmxlviii 48 xlviii 2048}
+test clock-2.2193 {conversion of 2048-05-01} {
+ clock format 2471949296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2048 12:34:56 die i mensis v annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2469198 05 v 5 05/01/2048 die i mensis v annoque mmxlviii 48 xlviii 2048}
+test clock-2.2194 {conversion of 2048-05-31} {
+ clock format 2474541296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2048 12:34:56 die xxxi mensis v annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2469228 05 v 5 05/31/2048 die xxxi mensis v annoque mmxlviii 48 xlviii 2048}
+test clock-2.2195 {conversion of 2048-06-01} {
+ clock format 2474627696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2048 12:34:56 die i mensis vi annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2469229 06 vi 6 06/01/2048 die i mensis vi annoque mmxlviii 48 xlviii 2048}
+test clock-2.2196 {conversion of 2048-06-30} {
+ clock format 2477133296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2048 12:34:56 die xxx mensis vi annoque mmxlviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2469258 06 vi 6 06/30/2048 die xxx mensis vi annoque mmxlviii 48 xlviii 2048}
+test clock-2.2197 {conversion of 2048-07-01} {
+ clock format 2477219696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2048 12:34:56 die i mensis vii annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2469259 07 vii 7 07/01/2048 die i mensis vii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2198 {conversion of 2048-07-31} {
+ clock format 2479811696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2048 12:34:56 die xxxi mensis vii annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2469289 07 vii 7 07/31/2048 die xxxi mensis vii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2199 {conversion of 2048-08-01} {
+ clock format 2479898096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2048 12:34:56 die i mensis viii annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2469290 08 viii 8 08/01/2048 die i mensis viii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2200 {conversion of 2048-08-31} {
+ clock format 2482490096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2048 12:34:56 die xxxi mensis viii annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2469320 08 viii 8 08/31/2048 die xxxi mensis viii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2201 {conversion of 2048-09-01} {
+ clock format 2482576496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2048 12:34:56 die i mensis ix annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2469321 09 ix 9 09/01/2048 die i mensis ix annoque mmxlviii 48 xlviii 2048}
+test clock-2.2202 {conversion of 2048-09-30} {
+ clock format 2485082096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2048 12:34:56 die xxx mensis ix annoque mmxlviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2469350 09 ix 9 09/30/2048 die xxx mensis ix annoque mmxlviii 48 xlviii 2048}
+test clock-2.2203 {conversion of 2048-10-01} {
+ clock format 2485168496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2048 12:34:56 die i mensis x annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2469351 10 x 10 10/01/2048 die i mensis x annoque mmxlviii 48 xlviii 2048}
+test clock-2.2204 {conversion of 2048-10-31} {
+ clock format 2487760496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2048 12:34:56 die xxxi mensis x annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2469381 10 x 10 10/31/2048 die xxxi mensis x annoque mmxlviii 48 xlviii 2048}
+test clock-2.2205 {conversion of 2048-11-01} {
+ clock format 2487846896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2048 12:34:56 die i mensis xi annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2469382 11 xi 11 11/01/2048 die i mensis xi annoque mmxlviii 48 xlviii 2048}
+test clock-2.2206 {conversion of 2048-11-30} {
+ clock format 2490352496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2048 12:34:56 die xxx mensis xi annoque mmxlviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2469411 11 xi 11 11/30/2048 die xxx mensis xi annoque mmxlviii 48 xlviii 2048}
+test clock-2.2207 {conversion of 2048-12-01} {
+ clock format 2490438896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2048 12:34:56 die i mensis xii annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2469412 12 xii 12 12/01/2048 die i mensis xii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2208 {conversion of 2048-12-31} {
+ clock format 2493030896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2048 12:34:56 die xxxi mensis xii annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2469442 12 xii 12 12/31/2048 die xxxi mensis xii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2209 {conversion of 2049-01-01} {
+ clock format 2493117296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2049 12:34:56 die i mensis i annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2469443 01 i 1 01/01/2049 die i mensis i annoque mmxlix 49 xlix 2049}
+test clock-2.2210 {conversion of 2049-01-31} {
+ clock format 2495709296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2049 12:34:56 die xxxi mensis i annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2469473 01 i 1 01/31/2049 die xxxi mensis i annoque mmxlix 49 xlix 2049}
+test clock-2.2211 {conversion of 2049-02-01} {
+ clock format 2495795696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2049 12:34:56 die i mensis ii annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2469474 02 ii 2 02/01/2049 die i mensis ii annoque mmxlix 49 xlix 2049}
+test clock-2.2212 {conversion of 2049-02-28} {
+ clock format 2498128496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2049 12:34:56 die xxviii mensis ii annoque mmxlix xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2469501 02 ii 2 02/28/2049 die xxviii mensis ii annoque mmxlix 49 xlix 2049}
+test clock-2.2213 {conversion of 2049-03-01} {
+ clock format 2498214896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2049 12:34:56 die i mensis iii annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2469502 03 iii 3 03/01/2049 die i mensis iii annoque mmxlix 49 xlix 2049}
+test clock-2.2214 {conversion of 2049-03-31} {
+ clock format 2500806896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2049 12:34:56 die xxxi mensis iii annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2469532 03 iii 3 03/31/2049 die xxxi mensis iii annoque mmxlix 49 xlix 2049}
+test clock-2.2215 {conversion of 2049-04-01} {
+ clock format 2500893296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2049 12:34:56 die i mensis iv annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2469533 04 iv 4 04/01/2049 die i mensis iv annoque mmxlix 49 xlix 2049}
+test clock-2.2216 {conversion of 2049-04-30} {
+ clock format 2503398896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2049 12:34:56 die xxx mensis iv annoque mmxlix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2469562 04 iv 4 04/30/2049 die xxx mensis iv annoque mmxlix 49 xlix 2049}
+test clock-2.2217 {conversion of 2049-05-01} {
+ clock format 2503485296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2049 12:34:56 die i mensis v annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2469563 05 v 5 05/01/2049 die i mensis v annoque mmxlix 49 xlix 2049}
+test clock-2.2218 {conversion of 2049-05-31} {
+ clock format 2506077296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2049 12:34:56 die xxxi mensis v annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2469593 05 v 5 05/31/2049 die xxxi mensis v annoque mmxlix 49 xlix 2049}
+test clock-2.2219 {conversion of 2049-06-01} {
+ clock format 2506163696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2049 12:34:56 die i mensis vi annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2469594 06 vi 6 06/01/2049 die i mensis vi annoque mmxlix 49 xlix 2049}
+test clock-2.2220 {conversion of 2049-06-30} {
+ clock format 2508669296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2049 12:34:56 die xxx mensis vi annoque mmxlix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2469623 06 vi 6 06/30/2049 die xxx mensis vi annoque mmxlix 49 xlix 2049}
+test clock-2.2221 {conversion of 2049-07-01} {
+ clock format 2508755696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2049 12:34:56 die i mensis vii annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2469624 07 vii 7 07/01/2049 die i mensis vii annoque mmxlix 49 xlix 2049}
+test clock-2.2222 {conversion of 2049-07-31} {
+ clock format 2511347696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2049 12:34:56 die xxxi mensis vii annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2469654 07 vii 7 07/31/2049 die xxxi mensis vii annoque mmxlix 49 xlix 2049}
+test clock-2.2223 {conversion of 2049-08-01} {
+ clock format 2511434096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2049 12:34:56 die i mensis viii annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2469655 08 viii 8 08/01/2049 die i mensis viii annoque mmxlix 49 xlix 2049}
+test clock-2.2224 {conversion of 2049-08-31} {
+ clock format 2514026096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2049 12:34:56 die xxxi mensis viii annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2469685 08 viii 8 08/31/2049 die xxxi mensis viii annoque mmxlix 49 xlix 2049}
+test clock-2.2225 {conversion of 2049-09-01} {
+ clock format 2514112496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2049 12:34:56 die i mensis ix annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2469686 09 ix 9 09/01/2049 die i mensis ix annoque mmxlix 49 xlix 2049}
+test clock-2.2226 {conversion of 2049-09-30} {
+ clock format 2516618096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2049 12:34:56 die xxx mensis ix annoque mmxlix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2469715 09 ix 9 09/30/2049 die xxx mensis ix annoque mmxlix 49 xlix 2049}
+test clock-2.2227 {conversion of 2049-10-01} {
+ clock format 2516704496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2049 12:34:56 die i mensis x annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2469716 10 x 10 10/01/2049 die i mensis x annoque mmxlix 49 xlix 2049}
+test clock-2.2228 {conversion of 2049-10-31} {
+ clock format 2519296496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2049 12:34:56 die xxxi mensis x annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2469746 10 x 10 10/31/2049 die xxxi mensis x annoque mmxlix 49 xlix 2049}
+test clock-2.2229 {conversion of 2049-11-01} {
+ clock format 2519382896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2049 12:34:56 die i mensis xi annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2469747 11 xi 11 11/01/2049 die i mensis xi annoque mmxlix 49 xlix 2049}
+test clock-2.2230 {conversion of 2049-11-30} {
+ clock format 2521888496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2049 12:34:56 die xxx mensis xi annoque mmxlix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2469776 11 xi 11 11/30/2049 die xxx mensis xi annoque mmxlix 49 xlix 2049}
+test clock-2.2231 {conversion of 2049-12-01} {
+ clock format 2521974896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2049 12:34:56 die i mensis xii annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2469777 12 xii 12 12/01/2049 die i mensis xii annoque mmxlix 49 xlix 2049}
+test clock-2.2232 {conversion of 2049-12-31} {
+ clock format 2524566896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2049 12:34:56 die xxxi mensis xii annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2469807 12 xii 12 12/31/2049 die xxxi mensis xii annoque mmxlix 49 xlix 2049}
+test clock-2.2233 {conversion of 2052-01-01} {
+ clock format 2587725296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2052 12:34:56 die i mensis i annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2470538 01 i 1 01/01/2052 die i mensis i annoque mmlii 52 lii 2052}
+test clock-2.2234 {conversion of 2052-01-31} {
+ clock format 2590317296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2052 12:34:56 die xxxi mensis i annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2470568 01 i 1 01/31/2052 die xxxi mensis i annoque mmlii 52 lii 2052}
+test clock-2.2235 {conversion of 2052-02-01} {
+ clock format 2590403696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2052 12:34:56 die i mensis ii annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2470569 02 ii 2 02/01/2052 die i mensis ii annoque mmlii 52 lii 2052}
+test clock-2.2236 {conversion of 2052-02-29} {
+ clock format 2592822896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2052 12:34:56 die xxix mensis ii annoque mmlii xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2470597 02 ii 2 02/29/2052 die xxix mensis ii annoque mmlii 52 lii 2052}
+test clock-2.2237 {conversion of 2052-03-01} {
+ clock format 2592909296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2052 12:34:56 die i mensis iii annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2470598 03 iii 3 03/01/2052 die i mensis iii annoque mmlii 52 lii 2052}
+test clock-2.2238 {conversion of 2052-03-31} {
+ clock format 2595501296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2052 12:34:56 die xxxi mensis iii annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2470628 03 iii 3 03/31/2052 die xxxi mensis iii annoque mmlii 52 lii 2052}
+test clock-2.2239 {conversion of 2052-04-01} {
+ clock format 2595587696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2052 12:34:56 die i mensis iv annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2470629 04 iv 4 04/01/2052 die i mensis iv annoque mmlii 52 lii 2052}
+test clock-2.2240 {conversion of 2052-04-30} {
+ clock format 2598093296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2052 12:34:56 die xxx mensis iv annoque mmlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2470658 04 iv 4 04/30/2052 die xxx mensis iv annoque mmlii 52 lii 2052}
+test clock-2.2241 {conversion of 2052-05-01} {
+ clock format 2598179696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2052 12:34:56 die i mensis v annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2470659 05 v 5 05/01/2052 die i mensis v annoque mmlii 52 lii 2052}
+test clock-2.2242 {conversion of 2052-05-31} {
+ clock format 2600771696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2052 12:34:56 die xxxi mensis v annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2470689 05 v 5 05/31/2052 die xxxi mensis v annoque mmlii 52 lii 2052}
+test clock-2.2243 {conversion of 2052-06-01} {
+ clock format 2600858096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2052 12:34:56 die i mensis vi annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2470690 06 vi 6 06/01/2052 die i mensis vi annoque mmlii 52 lii 2052}
+test clock-2.2244 {conversion of 2052-06-30} {
+ clock format 2603363696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2052 12:34:56 die xxx mensis vi annoque mmlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2470719 06 vi 6 06/30/2052 die xxx mensis vi annoque mmlii 52 lii 2052}
+test clock-2.2245 {conversion of 2052-07-01} {
+ clock format 2603450096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2052 12:34:56 die i mensis vii annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2470720 07 vii 7 07/01/2052 die i mensis vii annoque mmlii 52 lii 2052}
+test clock-2.2246 {conversion of 2052-07-31} {
+ clock format 2606042096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2052 12:34:56 die xxxi mensis vii annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2470750 07 vii 7 07/31/2052 die xxxi mensis vii annoque mmlii 52 lii 2052}
+test clock-2.2247 {conversion of 2052-08-01} {
+ clock format 2606128496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2052 12:34:56 die i mensis viii annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2470751 08 viii 8 08/01/2052 die i mensis viii annoque mmlii 52 lii 2052}
+test clock-2.2248 {conversion of 2052-08-31} {
+ clock format 2608720496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2052 12:34:56 die xxxi mensis viii annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2470781 08 viii 8 08/31/2052 die xxxi mensis viii annoque mmlii 52 lii 2052}
+test clock-2.2249 {conversion of 2052-09-01} {
+ clock format 2608806896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2052 12:34:56 die i mensis ix annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2470782 09 ix 9 09/01/2052 die i mensis ix annoque mmlii 52 lii 2052}
+test clock-2.2250 {conversion of 2052-09-30} {
+ clock format 2611312496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2052 12:34:56 die xxx mensis ix annoque mmlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2470811 09 ix 9 09/30/2052 die xxx mensis ix annoque mmlii 52 lii 2052}
+test clock-2.2251 {conversion of 2052-10-01} {
+ clock format 2611398896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2052 12:34:56 die i mensis x annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2470812 10 x 10 10/01/2052 die i mensis x annoque mmlii 52 lii 2052}
+test clock-2.2252 {conversion of 2052-10-31} {
+ clock format 2613990896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2052 12:34:56 die xxxi mensis x annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2470842 10 x 10 10/31/2052 die xxxi mensis x annoque mmlii 52 lii 2052}
+test clock-2.2253 {conversion of 2052-11-01} {
+ clock format 2614077296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2052 12:34:56 die i mensis xi annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2470843 11 xi 11 11/01/2052 die i mensis xi annoque mmlii 52 lii 2052}
+test clock-2.2254 {conversion of 2052-11-30} {
+ clock format 2616582896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2052 12:34:56 die xxx mensis xi annoque mmlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2470872 11 xi 11 11/30/2052 die xxx mensis xi annoque mmlii 52 lii 2052}
+test clock-2.2255 {conversion of 2052-12-01} {
+ clock format 2616669296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2052 12:34:56 die i mensis xii annoque mmlii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2470873 12 xii 12 12/01/2052 die i mensis xii annoque mmlii 52 lii 2052}
+test clock-2.2256 {conversion of 2052-12-31} {
+ clock format 2619261296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2052 12:34:56 die xxxi mensis xii annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2470903 12 xii 12 12/31/2052 die xxxi mensis xii annoque mmlii 52 lii 2052}
+test clock-2.2257 {conversion of 2053-01-01} {
+ clock format 2619347696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2053 12:34:56 die i mensis i annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2470904 01 i 1 01/01/2053 die i mensis i annoque mmliii 53 liii 2053}
+test clock-2.2258 {conversion of 2053-01-31} {
+ clock format 2621939696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2053 12:34:56 die xxxi mensis i annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2470934 01 i 1 01/31/2053 die xxxi mensis i annoque mmliii 53 liii 2053}
+test clock-2.2259 {conversion of 2053-02-01} {
+ clock format 2622026096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2053 12:34:56 die i mensis ii annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2470935 02 ii 2 02/01/2053 die i mensis ii annoque mmliii 53 liii 2053}
+test clock-2.2260 {conversion of 2053-02-28} {
+ clock format 2624358896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2053 12:34:56 die xxviii mensis ii annoque mmliii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2470962 02 ii 2 02/28/2053 die xxviii mensis ii annoque mmliii 53 liii 2053}
+test clock-2.2261 {conversion of 2053-03-01} {
+ clock format 2624445296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2053 12:34:56 die i mensis iii annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2470963 03 iii 3 03/01/2053 die i mensis iii annoque mmliii 53 liii 2053}
+test clock-2.2262 {conversion of 2053-03-31} {
+ clock format 2627037296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2053 12:34:56 die xxxi mensis iii annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2470993 03 iii 3 03/31/2053 die xxxi mensis iii annoque mmliii 53 liii 2053}
+test clock-2.2263 {conversion of 2053-04-01} {
+ clock format 2627123696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2053 12:34:56 die i mensis iv annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2470994 04 iv 4 04/01/2053 die i mensis iv annoque mmliii 53 liii 2053}
+test clock-2.2264 {conversion of 2053-04-30} {
+ clock format 2629629296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2053 12:34:56 die xxx mensis iv annoque mmliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2471023 04 iv 4 04/30/2053 die xxx mensis iv annoque mmliii 53 liii 2053}
+test clock-2.2265 {conversion of 2053-05-01} {
+ clock format 2629715696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2053 12:34:56 die i mensis v annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2471024 05 v 5 05/01/2053 die i mensis v annoque mmliii 53 liii 2053}
+test clock-2.2266 {conversion of 2053-05-31} {
+ clock format 2632307696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2053 12:34:56 die xxxi mensis v annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2471054 05 v 5 05/31/2053 die xxxi mensis v annoque mmliii 53 liii 2053}
+test clock-2.2267 {conversion of 2053-06-01} {
+ clock format 2632394096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2053 12:34:56 die i mensis vi annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2471055 06 vi 6 06/01/2053 die i mensis vi annoque mmliii 53 liii 2053}
+test clock-2.2268 {conversion of 2053-06-30} {
+ clock format 2634899696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2053 12:34:56 die xxx mensis vi annoque mmliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2471084 06 vi 6 06/30/2053 die xxx mensis vi annoque mmliii 53 liii 2053}
+test clock-2.2269 {conversion of 2053-07-01} {
+ clock format 2634986096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2053 12:34:56 die i mensis vii annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2471085 07 vii 7 07/01/2053 die i mensis vii annoque mmliii 53 liii 2053}
+test clock-2.2270 {conversion of 2053-07-31} {
+ clock format 2637578096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2053 12:34:56 die xxxi mensis vii annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2471115 07 vii 7 07/31/2053 die xxxi mensis vii annoque mmliii 53 liii 2053}
+test clock-2.2271 {conversion of 2053-08-01} {
+ clock format 2637664496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2053 12:34:56 die i mensis viii annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2471116 08 viii 8 08/01/2053 die i mensis viii annoque mmliii 53 liii 2053}
+test clock-2.2272 {conversion of 2053-08-31} {
+ clock format 2640256496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2053 12:34:56 die xxxi mensis viii annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2471146 08 viii 8 08/31/2053 die xxxi mensis viii annoque mmliii 53 liii 2053}
+test clock-2.2273 {conversion of 2053-09-01} {
+ clock format 2640342896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2053 12:34:56 die i mensis ix annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2471147 09 ix 9 09/01/2053 die i mensis ix annoque mmliii 53 liii 2053}
+test clock-2.2274 {conversion of 2053-09-30} {
+ clock format 2642848496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2053 12:34:56 die xxx mensis ix annoque mmliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2471176 09 ix 9 09/30/2053 die xxx mensis ix annoque mmliii 53 liii 2053}
+test clock-2.2275 {conversion of 2053-10-01} {
+ clock format 2642934896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2053 12:34:56 die i mensis x annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2471177 10 x 10 10/01/2053 die i mensis x annoque mmliii 53 liii 2053}
+test clock-2.2276 {conversion of 2053-10-31} {
+ clock format 2645526896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2053 12:34:56 die xxxi mensis x annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2471207 10 x 10 10/31/2053 die xxxi mensis x annoque mmliii 53 liii 2053}
+test clock-2.2277 {conversion of 2053-11-01} {
+ clock format 2645613296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2053 12:34:56 die i mensis xi annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2471208 11 xi 11 11/01/2053 die i mensis xi annoque mmliii 53 liii 2053}
+test clock-2.2278 {conversion of 2053-11-30} {
+ clock format 2648118896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2053 12:34:56 die xxx mensis xi annoque mmliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2471237 11 xi 11 11/30/2053 die xxx mensis xi annoque mmliii 53 liii 2053}
+test clock-2.2279 {conversion of 2053-12-01} {
+ clock format 2648205296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2053 12:34:56 die i mensis xii annoque mmliii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2471238 12 xii 12 12/01/2053 die i mensis xii annoque mmliii 53 liii 2053}
+test clock-2.2280 {conversion of 2053-12-31} {
+ clock format 2650797296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2053 12:34:56 die xxxi mensis xii annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2471268 12 xii 12 12/31/2053 die xxxi mensis xii annoque mmliii 53 liii 2053}
+test clock-2.2281 {conversion of 2056-01-01} {
+ clock format 2713955696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2056 12:34:56 die i mensis i annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2471999 01 i 1 01/01/2056 die i mensis i annoque mmlvi 56 lvi 2056}
+test clock-2.2282 {conversion of 2056-01-31} {
+ clock format 2716547696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2056 12:34:56 die xxxi mensis i annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2472029 01 i 1 01/31/2056 die xxxi mensis i annoque mmlvi 56 lvi 2056}
+test clock-2.2283 {conversion of 2056-02-01} {
+ clock format 2716634096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2056 12:34:56 die i mensis ii annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2472030 02 ii 2 02/01/2056 die i mensis ii annoque mmlvi 56 lvi 2056}
+test clock-2.2284 {conversion of 2056-02-29} {
+ clock format 2719053296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2056 12:34:56 die xxix mensis ii annoque mmlvi xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2472058 02 ii 2 02/29/2056 die xxix mensis ii annoque mmlvi 56 lvi 2056}
+test clock-2.2285 {conversion of 2056-03-01} {
+ clock format 2719139696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2056 12:34:56 die i mensis iii annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2472059 03 iii 3 03/01/2056 die i mensis iii annoque mmlvi 56 lvi 2056}
+test clock-2.2286 {conversion of 2056-03-31} {
+ clock format 2721731696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2056 12:34:56 die xxxi mensis iii annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2472089 03 iii 3 03/31/2056 die xxxi mensis iii annoque mmlvi 56 lvi 2056}
+test clock-2.2287 {conversion of 2056-04-01} {
+ clock format 2721818096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2056 12:34:56 die i mensis iv annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2472090 04 iv 4 04/01/2056 die i mensis iv annoque mmlvi 56 lvi 2056}
+test clock-2.2288 {conversion of 2056-04-30} {
+ clock format 2724323696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2056 12:34:56 die xxx mensis iv annoque mmlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2472119 04 iv 4 04/30/2056 die xxx mensis iv annoque mmlvi 56 lvi 2056}
+test clock-2.2289 {conversion of 2056-05-01} {
+ clock format 2724410096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2056 12:34:56 die i mensis v annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2472120 05 v 5 05/01/2056 die i mensis v annoque mmlvi 56 lvi 2056}
+test clock-2.2290 {conversion of 2056-05-31} {
+ clock format 2727002096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2056 12:34:56 die xxxi mensis v annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2472150 05 v 5 05/31/2056 die xxxi mensis v annoque mmlvi 56 lvi 2056}
+test clock-2.2291 {conversion of 2056-06-01} {
+ clock format 2727088496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2056 12:34:56 die i mensis vi annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2472151 06 vi 6 06/01/2056 die i mensis vi annoque mmlvi 56 lvi 2056}
+test clock-2.2292 {conversion of 2056-06-30} {
+ clock format 2729594096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2056 12:34:56 die xxx mensis vi annoque mmlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2472180 06 vi 6 06/30/2056 die xxx mensis vi annoque mmlvi 56 lvi 2056}
+test clock-2.2293 {conversion of 2056-07-01} {
+ clock format 2729680496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2056 12:34:56 die i mensis vii annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2472181 07 vii 7 07/01/2056 die i mensis vii annoque mmlvi 56 lvi 2056}
+test clock-2.2294 {conversion of 2056-07-31} {
+ clock format 2732272496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2056 12:34:56 die xxxi mensis vii annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2472211 07 vii 7 07/31/2056 die xxxi mensis vii annoque mmlvi 56 lvi 2056}
+test clock-2.2295 {conversion of 2056-08-01} {
+ clock format 2732358896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2056 12:34:56 die i mensis viii annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2472212 08 viii 8 08/01/2056 die i mensis viii annoque mmlvi 56 lvi 2056}
+test clock-2.2296 {conversion of 2056-08-31} {
+ clock format 2734950896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2056 12:34:56 die xxxi mensis viii annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2472242 08 viii 8 08/31/2056 die xxxi mensis viii annoque mmlvi 56 lvi 2056}
+test clock-2.2297 {conversion of 2056-09-01} {
+ clock format 2735037296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2056 12:34:56 die i mensis ix annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2472243 09 ix 9 09/01/2056 die i mensis ix annoque mmlvi 56 lvi 2056}
+test clock-2.2298 {conversion of 2056-09-30} {
+ clock format 2737542896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2056 12:34:56 die xxx mensis ix annoque mmlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2472272 09 ix 9 09/30/2056 die xxx mensis ix annoque mmlvi 56 lvi 2056}
+test clock-2.2299 {conversion of 2056-10-01} {
+ clock format 2737629296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2056 12:34:56 die i mensis x annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2472273 10 x 10 10/01/2056 die i mensis x annoque mmlvi 56 lvi 2056}
+test clock-2.2300 {conversion of 2056-10-31} {
+ clock format 2740221296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2056 12:34:56 die xxxi mensis x annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2472303 10 x 10 10/31/2056 die xxxi mensis x annoque mmlvi 56 lvi 2056}
+test clock-2.2301 {conversion of 2056-11-01} {
+ clock format 2740307696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2056 12:34:56 die i mensis xi annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2472304 11 xi 11 11/01/2056 die i mensis xi annoque mmlvi 56 lvi 2056}
+test clock-2.2302 {conversion of 2056-11-30} {
+ clock format 2742813296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2056 12:34:56 die xxx mensis xi annoque mmlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2472333 11 xi 11 11/30/2056 die xxx mensis xi annoque mmlvi 56 lvi 2056}
+test clock-2.2303 {conversion of 2056-12-01} {
+ clock format 2742899696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2056 12:34:56 die i mensis xii annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2472334 12 xii 12 12/01/2056 die i mensis xii annoque mmlvi 56 lvi 2056}
+test clock-2.2304 {conversion of 2056-12-31} {
+ clock format 2745491696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2056 12:34:56 die xxxi mensis xii annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2472364 12 xii 12 12/31/2056 die xxxi mensis xii annoque mmlvi 56 lvi 2056}
+test clock-2.2305 {conversion of 2057-01-01} {
+ clock format 2745578096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2057 12:34:56 die i mensis i annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2472365 01 i 1 01/01/2057 die i mensis i annoque mmlvii 57 lvii 2057}
+test clock-2.2306 {conversion of 2057-01-31} {
+ clock format 2748170096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2057 12:34:56 die xxxi mensis i annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2472395 01 i 1 01/31/2057 die xxxi mensis i annoque mmlvii 57 lvii 2057}
+test clock-2.2307 {conversion of 2057-02-01} {
+ clock format 2748256496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2057 12:34:56 die i mensis ii annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2472396 02 ii 2 02/01/2057 die i mensis ii annoque mmlvii 57 lvii 2057}
+test clock-2.2308 {conversion of 2057-02-28} {
+ clock format 2750589296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2057 12:34:56 die xxviii mensis ii annoque mmlvii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2472423 02 ii 2 02/28/2057 die xxviii mensis ii annoque mmlvii 57 lvii 2057}
+test clock-2.2309 {conversion of 2057-03-01} {
+ clock format 2750675696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2057 12:34:56 die i mensis iii annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2472424 03 iii 3 03/01/2057 die i mensis iii annoque mmlvii 57 lvii 2057}
+test clock-2.2310 {conversion of 2057-03-31} {
+ clock format 2753267696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2057 12:34:56 die xxxi mensis iii annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2472454 03 iii 3 03/31/2057 die xxxi mensis iii annoque mmlvii 57 lvii 2057}
+test clock-2.2311 {conversion of 2057-04-01} {
+ clock format 2753354096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2057 12:34:56 die i mensis iv annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2472455 04 iv 4 04/01/2057 die i mensis iv annoque mmlvii 57 lvii 2057}
+test clock-2.2312 {conversion of 2057-04-30} {
+ clock format 2755859696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2057 12:34:56 die xxx mensis iv annoque mmlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2472484 04 iv 4 04/30/2057 die xxx mensis iv annoque mmlvii 57 lvii 2057}
+test clock-2.2313 {conversion of 2057-05-01} {
+ clock format 2755946096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2057 12:34:56 die i mensis v annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2472485 05 v 5 05/01/2057 die i mensis v annoque mmlvii 57 lvii 2057}
+test clock-2.2314 {conversion of 2057-05-31} {
+ clock format 2758538096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2057 12:34:56 die xxxi mensis v annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2472515 05 v 5 05/31/2057 die xxxi mensis v annoque mmlvii 57 lvii 2057}
+test clock-2.2315 {conversion of 2057-06-01} {
+ clock format 2758624496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2057 12:34:56 die i mensis vi annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2472516 06 vi 6 06/01/2057 die i mensis vi annoque mmlvii 57 lvii 2057}
+test clock-2.2316 {conversion of 2057-06-30} {
+ clock format 2761130096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2057 12:34:56 die xxx mensis vi annoque mmlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2472545 06 vi 6 06/30/2057 die xxx mensis vi annoque mmlvii 57 lvii 2057}
+test clock-2.2317 {conversion of 2057-07-01} {
+ clock format 2761216496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2057 12:34:56 die i mensis vii annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2472546 07 vii 7 07/01/2057 die i mensis vii annoque mmlvii 57 lvii 2057}
+test clock-2.2318 {conversion of 2057-07-31} {
+ clock format 2763808496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2057 12:34:56 die xxxi mensis vii annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2472576 07 vii 7 07/31/2057 die xxxi mensis vii annoque mmlvii 57 lvii 2057}
+test clock-2.2319 {conversion of 2057-08-01} {
+ clock format 2763894896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2057 12:34:56 die i mensis viii annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2472577 08 viii 8 08/01/2057 die i mensis viii annoque mmlvii 57 lvii 2057}
+test clock-2.2320 {conversion of 2057-08-31} {
+ clock format 2766486896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2057 12:34:56 die xxxi mensis viii annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2472607 08 viii 8 08/31/2057 die xxxi mensis viii annoque mmlvii 57 lvii 2057}
+test clock-2.2321 {conversion of 2057-09-01} {
+ clock format 2766573296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2057 12:34:56 die i mensis ix annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2472608 09 ix 9 09/01/2057 die i mensis ix annoque mmlvii 57 lvii 2057}
+test clock-2.2322 {conversion of 2057-09-30} {
+ clock format 2769078896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2057 12:34:56 die xxx mensis ix annoque mmlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2472637 09 ix 9 09/30/2057 die xxx mensis ix annoque mmlvii 57 lvii 2057}
+test clock-2.2323 {conversion of 2057-10-01} {
+ clock format 2769165296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2057 12:34:56 die i mensis x annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2472638 10 x 10 10/01/2057 die i mensis x annoque mmlvii 57 lvii 2057}
+test clock-2.2324 {conversion of 2057-10-31} {
+ clock format 2771757296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2057 12:34:56 die xxxi mensis x annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2472668 10 x 10 10/31/2057 die xxxi mensis x annoque mmlvii 57 lvii 2057}
+test clock-2.2325 {conversion of 2057-11-01} {
+ clock format 2771843696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2057 12:34:56 die i mensis xi annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2472669 11 xi 11 11/01/2057 die i mensis xi annoque mmlvii 57 lvii 2057}
+test clock-2.2326 {conversion of 2057-11-30} {
+ clock format 2774349296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2057 12:34:56 die xxx mensis xi annoque mmlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2472698 11 xi 11 11/30/2057 die xxx mensis xi annoque mmlvii 57 lvii 2057}
+test clock-2.2327 {conversion of 2057-12-01} {
+ clock format 2774435696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2057 12:34:56 die i mensis xii annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2472699 12 xii 12 12/01/2057 die i mensis xii annoque mmlvii 57 lvii 2057}
+test clock-2.2328 {conversion of 2057-12-31} {
+ clock format 2777027696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2057 12:34:56 die xxxi mensis xii annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2472729 12 xii 12 12/31/2057 die xxxi mensis xii annoque mmlvii 57 lvii 2057}
+test clock-2.2329 {conversion of 2060-01-01} {
+ clock format 2840186096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2060 12:34:56 die i mensis i annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2473460 01 i 1 01/01/2060 die i mensis i annoque mmlx 60 lx 2060}
+test clock-2.2330 {conversion of 2060-01-31} {
+ clock format 2842778096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2060 12:34:56 die xxxi mensis i annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2473490 01 i 1 01/31/2060 die xxxi mensis i annoque mmlx 60 lx 2060}
+test clock-2.2331 {conversion of 2060-02-01} {
+ clock format 2842864496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2060 12:34:56 die i mensis ii annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2473491 02 ii 2 02/01/2060 die i mensis ii annoque mmlx 60 lx 2060}
+test clock-2.2332 {conversion of 2060-02-29} {
+ clock format 2845283696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2060 12:34:56 die xxix mensis ii annoque mmlx xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2473519 02 ii 2 02/29/2060 die xxix mensis ii annoque mmlx 60 lx 2060}
+test clock-2.2333 {conversion of 2060-03-01} {
+ clock format 2845370096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2060 12:34:56 die i mensis iii annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2473520 03 iii 3 03/01/2060 die i mensis iii annoque mmlx 60 lx 2060}
+test clock-2.2334 {conversion of 2060-03-31} {
+ clock format 2847962096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2060 12:34:56 die xxxi mensis iii annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2473550 03 iii 3 03/31/2060 die xxxi mensis iii annoque mmlx 60 lx 2060}
+test clock-2.2335 {conversion of 2060-04-01} {
+ clock format 2848048496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2060 12:34:56 die i mensis iv annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2473551 04 iv 4 04/01/2060 die i mensis iv annoque mmlx 60 lx 2060}
+test clock-2.2336 {conversion of 2060-04-30} {
+ clock format 2850554096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2060 12:34:56 die xxx mensis iv annoque mmlx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2473580 04 iv 4 04/30/2060 die xxx mensis iv annoque mmlx 60 lx 2060}
+test clock-2.2337 {conversion of 2060-05-01} {
+ clock format 2850640496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2060 12:34:56 die i mensis v annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2473581 05 v 5 05/01/2060 die i mensis v annoque mmlx 60 lx 2060}
+test clock-2.2338 {conversion of 2060-05-31} {
+ clock format 2853232496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2060 12:34:56 die xxxi mensis v annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2473611 05 v 5 05/31/2060 die xxxi mensis v annoque mmlx 60 lx 2060}
+test clock-2.2339 {conversion of 2060-06-01} {
+ clock format 2853318896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2060 12:34:56 die i mensis vi annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2473612 06 vi 6 06/01/2060 die i mensis vi annoque mmlx 60 lx 2060}
+test clock-2.2340 {conversion of 2060-06-30} {
+ clock format 2855824496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2060 12:34:56 die xxx mensis vi annoque mmlx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2473641 06 vi 6 06/30/2060 die xxx mensis vi annoque mmlx 60 lx 2060}
+test clock-2.2341 {conversion of 2060-07-01} {
+ clock format 2855910896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2060 12:34:56 die i mensis vii annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2473642 07 vii 7 07/01/2060 die i mensis vii annoque mmlx 60 lx 2060}
+test clock-2.2342 {conversion of 2060-07-31} {
+ clock format 2858502896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2060 12:34:56 die xxxi mensis vii annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2473672 07 vii 7 07/31/2060 die xxxi mensis vii annoque mmlx 60 lx 2060}
+test clock-2.2343 {conversion of 2060-08-01} {
+ clock format 2858589296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2060 12:34:56 die i mensis viii annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2473673 08 viii 8 08/01/2060 die i mensis viii annoque mmlx 60 lx 2060}
+test clock-2.2344 {conversion of 2060-08-31} {
+ clock format 2861181296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2060 12:34:56 die xxxi mensis viii annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2473703 08 viii 8 08/31/2060 die xxxi mensis viii annoque mmlx 60 lx 2060}
+test clock-2.2345 {conversion of 2060-09-01} {
+ clock format 2861267696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2060 12:34:56 die i mensis ix annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2473704 09 ix 9 09/01/2060 die i mensis ix annoque mmlx 60 lx 2060}
+test clock-2.2346 {conversion of 2060-09-30} {
+ clock format 2863773296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2060 12:34:56 die xxx mensis ix annoque mmlx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2473733 09 ix 9 09/30/2060 die xxx mensis ix annoque mmlx 60 lx 2060}
+test clock-2.2347 {conversion of 2060-10-01} {
+ clock format 2863859696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2060 12:34:56 die i mensis x annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2473734 10 x 10 10/01/2060 die i mensis x annoque mmlx 60 lx 2060}
+test clock-2.2348 {conversion of 2060-10-31} {
+ clock format 2866451696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2060 12:34:56 die xxxi mensis x annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2473764 10 x 10 10/31/2060 die xxxi mensis x annoque mmlx 60 lx 2060}
+test clock-2.2349 {conversion of 2060-11-01} {
+ clock format 2866538096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2060 12:34:56 die i mensis xi annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2473765 11 xi 11 11/01/2060 die i mensis xi annoque mmlx 60 lx 2060}
+test clock-2.2350 {conversion of 2060-11-30} {
+ clock format 2869043696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2060 12:34:56 die xxx mensis xi annoque mmlx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2473794 11 xi 11 11/30/2060 die xxx mensis xi annoque mmlx 60 lx 2060}
+test clock-2.2351 {conversion of 2060-12-01} {
+ clock format 2869130096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2060 12:34:56 die i mensis xii annoque mmlx xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2473795 12 xii 12 12/01/2060 die i mensis xii annoque mmlx 60 lx 2060}
+test clock-2.2352 {conversion of 2060-12-31} {
+ clock format 2871722096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2060 12:34:56 die xxxi mensis xii annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2473825 12 xii 12 12/31/2060 die xxxi mensis xii annoque mmlx 60 lx 2060}
+test clock-2.2353 {conversion of 2061-01-01} {
+ clock format 2871808496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2061 12:34:56 die i mensis i annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2473826 01 i 1 01/01/2061 die i mensis i annoque mmlxi 61 lxi 2061}
+test clock-2.2354 {conversion of 2061-01-31} {
+ clock format 2874400496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2061 12:34:56 die xxxi mensis i annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2473856 01 i 1 01/31/2061 die xxxi mensis i annoque mmlxi 61 lxi 2061}
+test clock-2.2355 {conversion of 2061-02-01} {
+ clock format 2874486896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2061 12:34:56 die i mensis ii annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2473857 02 ii 2 02/01/2061 die i mensis ii annoque mmlxi 61 lxi 2061}
+test clock-2.2356 {conversion of 2061-02-28} {
+ clock format 2876819696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2061 12:34:56 die xxviii mensis ii annoque mmlxi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2473884 02 ii 2 02/28/2061 die xxviii mensis ii annoque mmlxi 61 lxi 2061}
+test clock-2.2357 {conversion of 2061-03-01} {
+ clock format 2876906096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2061 12:34:56 die i mensis iii annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2473885 03 iii 3 03/01/2061 die i mensis iii annoque mmlxi 61 lxi 2061}
+test clock-2.2358 {conversion of 2061-03-31} {
+ clock format 2879498096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2061 12:34:56 die xxxi mensis iii annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2473915 03 iii 3 03/31/2061 die xxxi mensis iii annoque mmlxi 61 lxi 2061}
+test clock-2.2359 {conversion of 2061-04-01} {
+ clock format 2879584496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2061 12:34:56 die i mensis iv annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2473916 04 iv 4 04/01/2061 die i mensis iv annoque mmlxi 61 lxi 2061}
+test clock-2.2360 {conversion of 2061-04-30} {
+ clock format 2882090096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2061 12:34:56 die xxx mensis iv annoque mmlxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2473945 04 iv 4 04/30/2061 die xxx mensis iv annoque mmlxi 61 lxi 2061}
+test clock-2.2361 {conversion of 2061-05-01} {
+ clock format 2882176496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2061 12:34:56 die i mensis v annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2473946 05 v 5 05/01/2061 die i mensis v annoque mmlxi 61 lxi 2061}
+test clock-2.2362 {conversion of 2061-05-31} {
+ clock format 2884768496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2061 12:34:56 die xxxi mensis v annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2473976 05 v 5 05/31/2061 die xxxi mensis v annoque mmlxi 61 lxi 2061}
+test clock-2.2363 {conversion of 2061-06-01} {
+ clock format 2884854896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2061 12:34:56 die i mensis vi annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2473977 06 vi 6 06/01/2061 die i mensis vi annoque mmlxi 61 lxi 2061}
+test clock-2.2364 {conversion of 2061-06-30} {
+ clock format 2887360496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2061 12:34:56 die xxx mensis vi annoque mmlxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2474006 06 vi 6 06/30/2061 die xxx mensis vi annoque mmlxi 61 lxi 2061}
+test clock-2.2365 {conversion of 2061-07-01} {
+ clock format 2887446896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2061 12:34:56 die i mensis vii annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2474007 07 vii 7 07/01/2061 die i mensis vii annoque mmlxi 61 lxi 2061}
+test clock-2.2366 {conversion of 2061-07-31} {
+ clock format 2890038896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2061 12:34:56 die xxxi mensis vii annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2474037 07 vii 7 07/31/2061 die xxxi mensis vii annoque mmlxi 61 lxi 2061}
+test clock-2.2367 {conversion of 2061-08-01} {
+ clock format 2890125296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2061 12:34:56 die i mensis viii annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2474038 08 viii 8 08/01/2061 die i mensis viii annoque mmlxi 61 lxi 2061}
+test clock-2.2368 {conversion of 2061-08-31} {
+ clock format 2892717296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2061 12:34:56 die xxxi mensis viii annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2474068 08 viii 8 08/31/2061 die xxxi mensis viii annoque mmlxi 61 lxi 2061}
+test clock-2.2369 {conversion of 2061-09-01} {
+ clock format 2892803696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2061 12:34:56 die i mensis ix annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2474069 09 ix 9 09/01/2061 die i mensis ix annoque mmlxi 61 lxi 2061}
+test clock-2.2370 {conversion of 2061-09-30} {
+ clock format 2895309296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2061 12:34:56 die xxx mensis ix annoque mmlxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2474098 09 ix 9 09/30/2061 die xxx mensis ix annoque mmlxi 61 lxi 2061}
+test clock-2.2371 {conversion of 2061-10-01} {
+ clock format 2895395696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2061 12:34:56 die i mensis x annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2474099 10 x 10 10/01/2061 die i mensis x annoque mmlxi 61 lxi 2061}
+test clock-2.2372 {conversion of 2061-10-31} {
+ clock format 2897987696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2061 12:34:56 die xxxi mensis x annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2474129 10 x 10 10/31/2061 die xxxi mensis x annoque mmlxi 61 lxi 2061}
+test clock-2.2373 {conversion of 2061-11-01} {
+ clock format 2898074096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2061 12:34:56 die i mensis xi annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2474130 11 xi 11 11/01/2061 die i mensis xi annoque mmlxi 61 lxi 2061}
+test clock-2.2374 {conversion of 2061-11-30} {
+ clock format 2900579696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2061 12:34:56 die xxx mensis xi annoque mmlxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2474159 11 xi 11 11/30/2061 die xxx mensis xi annoque mmlxi 61 lxi 2061}
+test clock-2.2375 {conversion of 2061-12-01} {
+ clock format 2900666096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2061 12:34:56 die i mensis xii annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2474160 12 xii 12 12/01/2061 die i mensis xii annoque mmlxi 61 lxi 2061}
+test clock-2.2376 {conversion of 2061-12-31} {
+ clock format 2903258096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2061 12:34:56 die xxxi mensis xii annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2474190 12 xii 12 12/31/2061 die xxxi mensis xii annoque mmlxi 61 lxi 2061}
+test clock-2.2377 {conversion of 2064-01-01} {
+ clock format 2966416496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2064 12:34:56 die i mensis i annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2474921 01 i 1 01/01/2064 die i mensis i annoque mmlxiv 64 lxiv 2064}
+test clock-2.2378 {conversion of 2064-01-31} {
+ clock format 2969008496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2064 12:34:56 die xxxi mensis i annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2474951 01 i 1 01/31/2064 die xxxi mensis i annoque mmlxiv 64 lxiv 2064}
+test clock-2.2379 {conversion of 2064-02-01} {
+ clock format 2969094896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2064 12:34:56 die i mensis ii annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2474952 02 ii 2 02/01/2064 die i mensis ii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2380 {conversion of 2064-02-29} {
+ clock format 2971514096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/29/2064 12:34:56 die xxix mensis ii annoque mmlxiv xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2474980 02 ii 2 02/29/2064 die xxix mensis ii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2381 {conversion of 2064-03-01} {
+ clock format 2971600496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2064 12:34:56 die i mensis iii annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 061 2474981 03 iii 3 03/01/2064 die i mensis iii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2382 {conversion of 2064-03-31} {
+ clock format 2974192496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2064 12:34:56 die xxxi mensis iii annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2475011 03 iii 3 03/31/2064 die xxxi mensis iii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2383 {conversion of 2064-04-01} {
+ clock format 2974278896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2064 12:34:56 die i mensis iv annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 092 2475012 04 iv 4 04/01/2064 die i mensis iv annoque mmlxiv 64 lxiv 2064}
+test clock-2.2384 {conversion of 2064-04-30} {
+ clock format 2976784496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2064 12:34:56 die xxx mensis iv annoque mmlxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2475041 04 iv 4 04/30/2064 die xxx mensis iv annoque mmlxiv 64 lxiv 2064}
+test clock-2.2385 {conversion of 2064-05-01} {
+ clock format 2976870896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2064 12:34:56 die i mensis v annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i May 122 2475042 05 v 5 05/01/2064 die i mensis v annoque mmlxiv 64 lxiv 2064}
+test clock-2.2386 {conversion of 2064-05-31} {
+ clock format 2979462896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2064 12:34:56 die xxxi mensis v annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2475072 05 v 5 05/31/2064 die xxxi mensis v annoque mmlxiv 64 lxiv 2064}
+test clock-2.2387 {conversion of 2064-06-01} {
+ clock format 2979549296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2064 12:34:56 die i mensis vi annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 153 2475073 06 vi 6 06/01/2064 die i mensis vi annoque mmlxiv 64 lxiv 2064}
+test clock-2.2388 {conversion of 2064-06-30} {
+ clock format 2982054896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2064 12:34:56 die xxx mensis vi annoque mmlxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2475102 06 vi 6 06/30/2064 die xxx mensis vi annoque mmlxiv 64 lxiv 2064}
+test clock-2.2389 {conversion of 2064-07-01} {
+ clock format 2982141296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2064 12:34:56 die i mensis vii annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 183 2475103 07 vii 7 07/01/2064 die i mensis vii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2390 {conversion of 2064-07-31} {
+ clock format 2984733296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2064 12:34:56 die xxxi mensis vii annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2475133 07 vii 7 07/31/2064 die xxxi mensis vii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2391 {conversion of 2064-08-01} {
+ clock format 2984819696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2064 12:34:56 die i mensis viii annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 214 2475134 08 viii 8 08/01/2064 die i mensis viii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2392 {conversion of 2064-08-31} {
+ clock format 2987411696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2064 12:34:56 die xxxi mensis viii annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2475164 08 viii 8 08/31/2064 die xxxi mensis viii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2393 {conversion of 2064-09-01} {
+ clock format 2987498096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2064 12:34:56 die i mensis ix annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 245 2475165 09 ix 9 09/01/2064 die i mensis ix annoque mmlxiv 64 lxiv 2064}
+test clock-2.2394 {conversion of 2064-09-30} {
+ clock format 2990003696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2064 12:34:56 die xxx mensis ix annoque mmlxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2475194 09 ix 9 09/30/2064 die xxx mensis ix annoque mmlxiv 64 lxiv 2064}
+test clock-2.2395 {conversion of 2064-10-01} {
+ clock format 2990090096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2064 12:34:56 die i mensis x annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 275 2475195 10 x 10 10/01/2064 die i mensis x annoque mmlxiv 64 lxiv 2064}
+test clock-2.2396 {conversion of 2064-10-31} {
+ clock format 2992682096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2064 12:34:56 die xxxi mensis x annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2475225 10 x 10 10/31/2064 die xxxi mensis x annoque mmlxiv 64 lxiv 2064}
+test clock-2.2397 {conversion of 2064-11-01} {
+ clock format 2992768496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2064 12:34:56 die i mensis xi annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 306 2475226 11 xi 11 11/01/2064 die i mensis xi annoque mmlxiv 64 lxiv 2064}
+test clock-2.2398 {conversion of 2064-11-30} {
+ clock format 2995274096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2064 12:34:56 die xxx mensis xi annoque mmlxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2475255 11 xi 11 11/30/2064 die xxx mensis xi annoque mmlxiv 64 lxiv 2064}
+test clock-2.2399 {conversion of 2064-12-01} {
+ clock format 2995360496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2064 12:34:56 die i mensis xii annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 336 2475256 12 xii 12 12/01/2064 die i mensis xii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2400 {conversion of 2064-12-31} {
+ clock format 2997952496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2064 12:34:56 die xxxi mensis xii annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2475286 12 xii 12 12/31/2064 die xxxi mensis xii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2401 {conversion of 2065-01-01} {
+ clock format 2998038896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/01/2065 12:34:56 die i mensis i annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Jan 001 2475287 01 i 1 01/01/2065 die i mensis i annoque mmlxv 65 lxv 2065}
+test clock-2.2402 {conversion of 2065-01-31} {
+ clock format 3000630896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jan January 01/31/2065 12:34:56 die xxxi mensis i annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2475317 01 i 1 01/31/2065 die xxxi mensis i annoque mmlxv 65 lxv 2065}
+test clock-2.2403 {conversion of 2065-02-01} {
+ clock format 3000717296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/01/2065 12:34:56 die i mensis ii annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Feb 032 2475318 02 ii 2 02/01/2065 die i mensis ii annoque mmlxv 65 lxv 2065}
+test clock-2.2404 {conversion of 2065-02-28} {
+ clock format 3003050096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Feb February 02/28/2065 12:34:56 die xxviii mensis ii annoque mmlxv xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2475345 02 ii 2 02/28/2065 die xxviii mensis ii annoque mmlxv 65 lxv 2065}
+test clock-2.2405 {conversion of 2065-03-01} {
+ clock format 3003136496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/01/2065 12:34:56 die i mensis iii annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Mar 060 2475346 03 iii 3 03/01/2065 die i mensis iii annoque mmlxv 65 lxv 2065}
+test clock-2.2406 {conversion of 2065-03-31} {
+ clock format 3005728496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Mar March 03/31/2065 12:34:56 die xxxi mensis iii annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2475376 03 iii 3 03/31/2065 die xxxi mensis iii annoque mmlxv 65 lxv 2065}
+test clock-2.2407 {conversion of 2065-04-01} {
+ clock format 3005814896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/01/2065 12:34:56 die i mensis iv annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Apr 091 2475377 04 iv 4 04/01/2065 die i mensis iv annoque mmlxv 65 lxv 2065}
+test clock-2.2408 {conversion of 2065-04-30} {
+ clock format 3008320496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Apr April 04/30/2065 12:34:56 die xxx mensis iv annoque mmlxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2475406 04 iv 4 04/30/2065 die xxx mensis iv annoque mmlxv 65 lxv 2065}
+test clock-2.2409 {conversion of 2065-05-01} {
+ clock format 3008406896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/01/2065 12:34:56 die i mensis v annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i May 121 2475407 05 v 5 05/01/2065 die i mensis v annoque mmlxv 65 lxv 2065}
+test clock-2.2410 {conversion of 2065-05-31} {
+ clock format 3010998896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {May May 05/31/2065 12:34:56 die xxxi mensis v annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2475437 05 v 5 05/31/2065 die xxxi mensis v annoque mmlxv 65 lxv 2065}
+test clock-2.2411 {conversion of 2065-06-01} {
+ clock format 3011085296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/01/2065 12:34:56 die i mensis vi annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Jun 152 2475438 06 vi 6 06/01/2065 die i mensis vi annoque mmlxv 65 lxv 2065}
+test clock-2.2412 {conversion of 2065-06-30} {
+ clock format 3013590896 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jun June 06/30/2065 12:34:56 die xxx mensis vi annoque mmlxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2475467 06 vi 6 06/30/2065 die xxx mensis vi annoque mmlxv 65 lxv 2065}
+test clock-2.2413 {conversion of 2065-07-01} {
+ clock format 3013677296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/01/2065 12:34:56 die i mensis vii annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Jul 182 2475468 07 vii 7 07/01/2065 die i mensis vii annoque mmlxv 65 lxv 2065}
+test clock-2.2414 {conversion of 2065-07-31} {
+ clock format 3016269296 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Jul July 07/31/2065 12:34:56 die xxxi mensis vii annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2475498 07 vii 7 07/31/2065 die xxxi mensis vii annoque mmlxv 65 lxv 2065}
+test clock-2.2415 {conversion of 2065-08-01} {
+ clock format 3016355696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/01/2065 12:34:56 die i mensis viii annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Aug 213 2475499 08 viii 8 08/01/2065 die i mensis viii annoque mmlxv 65 lxv 2065}
+test clock-2.2416 {conversion of 2065-08-31} {
+ clock format 3018947696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Aug August 08/31/2065 12:34:56 die xxxi mensis viii annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2475529 08 viii 8 08/31/2065 die xxxi mensis viii annoque mmlxv 65 lxv 2065}
+test clock-2.2417 {conversion of 2065-09-01} {
+ clock format 3019034096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/01/2065 12:34:56 die i mensis ix annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Sep 244 2475530 09 ix 9 09/01/2065 die i mensis ix annoque mmlxv 65 lxv 2065}
+test clock-2.2418 {conversion of 2065-09-30} {
+ clock format 3021539696 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Sep September 09/30/2065 12:34:56 die xxx mensis ix annoque mmlxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2475559 09 ix 9 09/30/2065 die xxx mensis ix annoque mmlxv 65 lxv 2065}
+test clock-2.2419 {conversion of 2065-10-01} {
+ clock format 3021626096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/01/2065 12:34:56 die i mensis x annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Oct 274 2475560 10 x 10 10/01/2065 die i mensis x annoque mmlxv 65 lxv 2065}
+test clock-2.2420 {conversion of 2065-10-31} {
+ clock format 3024218096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Oct October 10/31/2065 12:34:56 die xxxi mensis x annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2475590 10 x 10 10/31/2065 die xxxi mensis x annoque mmlxv 65 lxv 2065}
+test clock-2.2421 {conversion of 2065-11-01} {
+ clock format 3024304496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/01/2065 12:34:56 die i mensis xi annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Nov 305 2475591 11 xi 11 11/01/2065 die i mensis xi annoque mmlxv 65 lxv 2065}
+test clock-2.2422 {conversion of 2065-11-30} {
+ clock format 3026810096 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Nov November 11/30/2065 12:34:56 die xxx mensis xi annoque mmlxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2475620 11 xi 11 11/30/2065 die xxx mensis xi annoque mmlxv 65 lxv 2065}
+test clock-2.2423 {conversion of 2065-12-01} {
+ clock format 3026896496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/01/2065 12:34:56 die i mensis xii annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i 1 i Dec 335 2475621 12 xii 12 12/01/2065 die i mensis xii annoque mmlxv 65 lxv 2065}
+test clock-2.2424 {conversion of 2065-12-31} {
+ clock format 3029488496 \
+ -format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+ -gmt true -locale en_US_roman
+} {Dec December 12/31/2065 12:34:56 die xxxi mensis xii annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2475651 12 xii 12 12/31/2065 die xxxi mensis xii annoque mmlxv 65 lxv 2065}
+# END testcases2
+
+# BEGIN testcases3
+test clock-3.1 {ISO week-based calendar 1871-W52-1} {
+ clock format -3093206400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1871-W52-1
+} {Mon Monday 71 1871 1 52 52 1 52}
+test clock-3.2 {ISO week-based calendar 1871-W52-6} {
+ clock format -3092774400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1871-W52-6
+} {Sat Saturday 71 1871 6 52 52 6 52}
+test clock-3.3 {ISO week-based calendar 1871-W52-7} {
+ clock format -3092688000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1871-W52-7
+} {Sun Sunday 71 1871 7 53 52 0 52}
+test clock-3.4 {ISO week-based calendar 1872-W01-1} {
+ clock format -3092601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W01-1
+} {Mon Monday 72 1872 1 00 01 1 01}
+test clock-3.5 {ISO week-based calendar 1872-W01-6} {
+ clock format -3092169600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W01-6
+} {Sat Saturday 72 1872 6 00 01 6 01}
+test clock-3.6 {ISO week-based calendar 1872-W01-7} {
+ clock format -3092083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W01-7
+} {Sun Sunday 72 1872 7 01 01 0 01}
+test clock-3.7 {ISO week-based calendar 1872-W02-1} {
+ clock format -3091996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W02-1
+} {Mon Monday 72 1872 1 01 02 1 02}
+test clock-3.8 {ISO week-based calendar 1872-W52-1} {
+ clock format -3061756800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W52-1
+} {Mon Monday 72 1872 1 51 52 1 52}
+test clock-3.9 {ISO week-based calendar 1872-W52-6} {
+ clock format -3061324800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W52-6
+} {Sat Saturday 72 1872 6 51 52 6 52}
+test clock-3.10 {ISO week-based calendar 1872-W52-7} {
+ clock format -3061238400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W52-7
+} {Sun Sunday 72 1872 7 52 52 0 52}
+test clock-3.11 {ISO week-based calendar 1873-W01-1} {
+ clock format -3061152000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1873-W01-1
+} {Mon Monday 73 1873 1 52 01 1 53}
+test clock-3.12 {ISO week-based calendar 1873-W01-3} {
+ clock format -3060979200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1873-W01-3
+} {Wed Wednesday 73 1873 3 00 01 3 00}
+test clock-3.13 {ISO week-based calendar 1873-W01-6} {
+ clock format -3060720000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1873-W01-6
+} {Sat Saturday 73 1873 6 00 01 6 00}
+test clock-3.14 {ISO week-based calendar 1873-W01-7} {
+ clock format -3060633600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1873-W01-7
+} {Sun Sunday 73 1873 7 01 01 0 00}
+test clock-3.15 {ISO week-based calendar 1873-W02-1} {
+ clock format -3060547200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1873-W02-1
+} {Mon Monday 73 1873 1 01 02 1 01}
+test clock-3.16 {ISO week-based calendar 1875-W52-1} {
+ clock format -2966803200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1875-W52-1
+} {Mon Monday 75 1875 1 52 52 1 52}
+test clock-3.17 {ISO week-based calendar 1875-W52-6} {
+ clock format -2966371200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1875-W52-6
+} {Sat Saturday 75 1875 6 00 52 6 00}
+test clock-3.18 {ISO week-based calendar 1875-W52-7} {
+ clock format -2966284800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1875-W52-7
+} {Sun Sunday 75 1875 7 01 52 0 00}
+test clock-3.19 {ISO week-based calendar 1876-W01-1} {
+ clock format -2966198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W01-1
+} {Mon Monday 76 1876 1 01 01 1 01}
+test clock-3.20 {ISO week-based calendar 1876-W01-6} {
+ clock format -2965766400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W01-6
+} {Sat Saturday 76 1876 6 01 01 6 01}
+test clock-3.21 {ISO week-based calendar 1876-W01-7} {
+ clock format -2965680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W01-7
+} {Sun Sunday 76 1876 7 02 01 0 01}
+test clock-3.22 {ISO week-based calendar 1876-W02-1} {
+ clock format -2965593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W02-1
+} {Mon Monday 76 1876 1 02 02 1 02}
+test clock-3.23 {ISO week-based calendar 1876-W52-1} {
+ clock format -2935353600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W52-1
+} {Mon Monday 76 1876 1 52 52 1 52}
+test clock-3.24 {ISO week-based calendar 1876-W52-6} {
+ clock format -2934921600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W52-6
+} {Sat Saturday 76 1876 6 52 52 6 52}
+test clock-3.25 {ISO week-based calendar 1876-W52-7} {
+ clock format -2934835200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W52-7
+} {Sun Sunday 76 1876 7 53 52 0 52}
+test clock-3.26 {ISO week-based calendar 1877-W01-1} {
+ clock format -2934748800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1877-W01-1
+} {Mon Monday 77 1877 1 00 01 1 01}
+test clock-3.27 {ISO week-based calendar 1877-W01-6} {
+ clock format -2934316800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1877-W01-6
+} {Sat Saturday 77 1877 6 00 01 6 01}
+test clock-3.28 {ISO week-based calendar 1877-W01-7} {
+ clock format -2934230400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1877-W01-7
+} {Sun Sunday 77 1877 7 01 01 0 01}
+test clock-3.29 {ISO week-based calendar 1877-W02-1} {
+ clock format -2934144000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1877-W02-1
+} {Mon Monday 77 1877 1 01 02 1 02}
+test clock-3.30 {ISO week-based calendar 1879-W52-1} {
+ clock format -2841004800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1879-W52-1
+} {Mon Monday 79 1879 1 51 52 1 51}
+test clock-3.31 {ISO week-based calendar 1879-W52-6} {
+ clock format -2840572800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1879-W52-6
+} {Sat Saturday 79 1879 6 51 52 6 51}
+test clock-3.32 {ISO week-based calendar 1879-W52-7} {
+ clock format -2840486400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1879-W52-7
+} {Sun Sunday 79 1879 7 52 52 0 51}
+test clock-3.33 {ISO week-based calendar 1880-W01-1} {
+ clock format -2840400000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W01-1
+} {Mon Monday 80 1880 1 52 01 1 52}
+test clock-3.34 {ISO week-based calendar 1880-W01-4} {
+ clock format -2840140800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W01-4
+} {Thu Thursday 80 1880 4 00 01 4 00}
+test clock-3.35 {ISO week-based calendar 1880-W01-6} {
+ clock format -2839968000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W01-6
+} {Sat Saturday 80 1880 6 00 01 6 00}
+test clock-3.36 {ISO week-based calendar 1880-W01-7} {
+ clock format -2839881600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W01-7
+} {Sun Sunday 80 1880 7 01 01 0 00}
+test clock-3.37 {ISO week-based calendar 1880-W02-1} {
+ clock format -2839795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W02-1
+} {Mon Monday 80 1880 1 01 02 1 01}
+test clock-3.38 {ISO week-based calendar 1880-W53-1} {
+ clock format -2808950400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W53-1
+} {Mon Monday 80 1880 1 52 53 1 52}
+test clock-3.39 {ISO week-based calendar 1880-W53-6} {
+ clock format -2808518400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W53-6
+} {Sat Saturday 80 1880 6 00 53 6 00}
+test clock-3.40 {ISO week-based calendar 1880-W53-7} {
+ clock format -2808432000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W53-7
+} {Sun Sunday 80 1880 7 01 53 0 00}
+test clock-3.41 {ISO week-based calendar 1881-W01-1} {
+ clock format -2808345600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1881-W01-1
+} {Mon Monday 81 1881 1 01 01 1 01}
+test clock-3.42 {ISO week-based calendar 1881-W01-6} {
+ clock format -2807913600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1881-W01-6
+} {Sat Saturday 81 1881 6 01 01 6 01}
+test clock-3.43 {ISO week-based calendar 1881-W01-7} {
+ clock format -2807827200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1881-W01-7
+} {Sun Sunday 81 1881 7 02 01 0 01}
+test clock-3.44 {ISO week-based calendar 1881-W02-1} {
+ clock format -2807740800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1881-W02-1
+} {Mon Monday 81 1881 1 02 02 1 02}
+test clock-3.45 {ISO week-based calendar 1883-W52-1} {
+ clock format -2714601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1883-W52-1
+} {Mon Monday 83 1883 1 51 52 1 52}
+test clock-3.46 {ISO week-based calendar 1883-W52-6} {
+ clock format -2714169600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1883-W52-6
+} {Sat Saturday 83 1883 6 51 52 6 52}
+test clock-3.47 {ISO week-based calendar 1883-W52-7} {
+ clock format -2714083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1883-W52-7
+} {Sun Sunday 83 1883 7 52 52 0 52}
+test clock-3.48 {ISO week-based calendar 1884-W01-1} {
+ clock format -2713996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W01-1
+} {Mon Monday 84 1884 1 52 01 1 53}
+test clock-3.49 {ISO week-based calendar 1884-W01-2} {
+ clock format -2713910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W01-2
+} {Tue Tuesday 84 1884 2 00 01 2 00}
+test clock-3.50 {ISO week-based calendar 1884-W01-6} {
+ clock format -2713564800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W01-6
+} {Sat Saturday 84 1884 6 00 01 6 00}
+test clock-3.51 {ISO week-based calendar 1884-W01-7} {
+ clock format -2713478400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W01-7
+} {Sun Sunday 84 1884 7 01 01 0 00}
+test clock-3.52 {ISO week-based calendar 1884-W02-1} {
+ clock format -2713392000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W02-1
+} {Mon Monday 84 1884 1 01 02 1 01}
+test clock-3.53 {ISO week-based calendar 1884-W52-1} {
+ clock format -2683152000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W52-1
+} {Mon Monday 84 1884 1 51 52 1 51}
+test clock-3.54 {ISO week-based calendar 1884-W52-6} {
+ clock format -2682720000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W52-6
+} {Sat Saturday 84 1884 6 51 52 6 51}
+test clock-3.55 {ISO week-based calendar 1884-W52-7} {
+ clock format -2682633600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W52-7
+} {Sun Sunday 84 1884 7 52 52 0 51}
+test clock-3.56 {ISO week-based calendar 1885-W01-1} {
+ clock format -2682547200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1885-W01-1
+} {Mon Monday 85 1885 1 52 01 1 52}
+test clock-3.57 {ISO week-based calendar 1885-W01-4} {
+ clock format -2682288000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1885-W01-4
+} {Thu Thursday 85 1885 4 00 01 4 00}
+test clock-3.58 {ISO week-based calendar 1885-W01-6} {
+ clock format -2682115200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1885-W01-6
+} {Sat Saturday 85 1885 6 00 01 6 00}
+test clock-3.59 {ISO week-based calendar 1885-W01-7} {
+ clock format -2682028800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1885-W01-7
+} {Sun Sunday 85 1885 7 01 01 0 00}
+test clock-3.60 {ISO week-based calendar 1885-W02-1} {
+ clock format -2681942400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1885-W02-1
+} {Mon Monday 85 1885 1 01 02 1 01}
+test clock-3.61 {ISO week-based calendar 1887-W52-1} {
+ clock format -2588198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1887-W52-1
+} {Mon Monday 87 1887 1 52 52 1 52}
+test clock-3.62 {ISO week-based calendar 1887-W52-6} {
+ clock format -2587766400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1887-W52-6
+} {Sat Saturday 87 1887 6 52 52 6 52}
+test clock-3.63 {ISO week-based calendar 1887-W52-7} {
+ clock format -2587680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1887-W52-7
+} {Sun Sunday 87 1887 7 01 52 0 00}
+test clock-3.64 {ISO week-based calendar 1888-W01-1} {
+ clock format -2587593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W01-1
+} {Mon Monday 88 1888 1 01 01 1 01}
+test clock-3.65 {ISO week-based calendar 1888-W01-6} {
+ clock format -2587161600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W01-6
+} {Sat Saturday 88 1888 6 01 01 6 01}
+test clock-3.66 {ISO week-based calendar 1888-W01-7} {
+ clock format -2587075200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W01-7
+} {Sun Sunday 88 1888 7 02 01 0 01}
+test clock-3.67 {ISO week-based calendar 1888-W02-1} {
+ clock format -2586988800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W02-1
+} {Mon Monday 88 1888 1 02 02 1 02}
+test clock-3.68 {ISO week-based calendar 1888-W52-1} {
+ clock format -2556748800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W52-1
+} {Mon Monday 88 1888 1 52 52 1 52}
+test clock-3.69 {ISO week-based calendar 1888-W52-6} {
+ clock format -2556316800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W52-6
+} {Sat Saturday 88 1888 6 52 52 6 52}
+test clock-3.70 {ISO week-based calendar 1888-W52-7} {
+ clock format -2556230400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W52-7
+} {Sun Sunday 88 1888 7 53 52 0 52}
+test clock-3.71 {ISO week-based calendar 1889-W01-1} {
+ clock format -2556144000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W01-1
+} {Mon Monday 89 1889 1 53 01 1 53}
+test clock-3.72 {ISO week-based calendar 1889-W01-2} {
+ clock format -2556057600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W01-2
+} {Tue Tuesday 89 1889 2 00 01 2 00}
+test clock-3.73 {ISO week-based calendar 1889-W01-6} {
+ clock format -2555712000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W01-6
+} {Sat Saturday 89 1889 6 00 01 6 00}
+test clock-3.74 {ISO week-based calendar 1889-W01-7} {
+ clock format -2555625600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W01-7
+} {Sun Sunday 89 1889 7 01 01 0 00}
+test clock-3.75 {ISO week-based calendar 1889-W02-1} {
+ clock format -2555539200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W02-1
+} {Mon Monday 89 1889 1 01 02 1 01}
+test clock-3.76 {ISO week-based calendar 1889-W52-1} {
+ clock format -2525299200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W52-1
+} {Mon Monday 89 1889 1 51 52 1 51}
+test clock-3.77 {ISO week-based calendar 1889-W52-6} {
+ clock format -2524867200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W52-6
+} {Sat Saturday 89 1889 6 51 52 6 51}
+test clock-3.78 {ISO week-based calendar 1889-W52-7} {
+ clock format -2524780800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W52-7
+} {Sun Sunday 89 1889 7 52 52 0 51}
+test clock-3.79 {ISO week-based calendar 1890-W01-1} {
+ clock format -2524694400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W01-1
+} {Mon Monday 90 1890 1 52 01 1 52}
+test clock-3.80 {ISO week-based calendar 1890-W01-3} {
+ clock format -2524521600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W01-3
+} {Wed Wednesday 90 1890 3 00 01 3 00}
+test clock-3.81 {ISO week-based calendar 1890-W01-6} {
+ clock format -2524262400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W01-6
+} {Sat Saturday 90 1890 6 00 01 6 00}
+test clock-3.82 {ISO week-based calendar 1890-W01-7} {
+ clock format -2524176000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W01-7
+} {Sun Sunday 90 1890 7 01 01 0 00}
+test clock-3.83 {ISO week-based calendar 1890-W02-1} {
+ clock format -2524089600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W02-1
+} {Mon Monday 90 1890 1 01 02 1 01}
+test clock-3.84 {ISO week-based calendar 1890-W52-1} {
+ clock format -2493849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W52-1
+} {Mon Monday 90 1890 1 51 52 1 51}
+test clock-3.85 {ISO week-based calendar 1890-W52-6} {
+ clock format -2493417600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W52-6
+} {Sat Saturday 90 1890 6 51 52 6 51}
+test clock-3.86 {ISO week-based calendar 1890-W52-7} {
+ clock format -2493331200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W52-7
+} {Sun Sunday 90 1890 7 52 52 0 51}
+test clock-3.87 {ISO week-based calendar 1891-W01-1} {
+ clock format -2493244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W01-1
+} {Mon Monday 91 1891 1 52 01 1 52}
+test clock-3.88 {ISO week-based calendar 1891-W01-4} {
+ clock format -2492985600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W01-4
+} {Thu Thursday 91 1891 4 00 01 4 00}
+test clock-3.89 {ISO week-based calendar 1891-W01-6} {
+ clock format -2492812800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W01-6
+} {Sat Saturday 91 1891 6 00 01 6 00}
+test clock-3.90 {ISO week-based calendar 1891-W01-7} {
+ clock format -2492726400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W01-7
+} {Sun Sunday 91 1891 7 01 01 0 00}
+test clock-3.91 {ISO week-based calendar 1891-W02-1} {
+ clock format -2492640000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W02-1
+} {Mon Monday 91 1891 1 01 02 1 01}
+test clock-3.92 {ISO week-based calendar 1891-W53-1} {
+ clock format -2461795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W53-1
+} {Mon Monday 91 1891 1 52 53 1 52}
+test clock-3.93 {ISO week-based calendar 1891-W53-5} {
+ clock format -2461449600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W53-5
+} {Fri Friday 91 1891 5 00 53 5 00}
+test clock-3.94 {ISO week-based calendar 1891-W53-6} {
+ clock format -2461363200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W53-6
+} {Sat Saturday 91 1891 6 00 53 6 00}
+test clock-3.95 {ISO week-based calendar 1891-W53-7} {
+ clock format -2461276800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W53-7
+} {Sun Sunday 91 1891 7 01 53 0 00}
+test clock-3.96 {ISO week-based calendar 1892-W01-1} {
+ clock format -2461190400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W01-1
+} {Mon Monday 92 1892 1 01 01 1 01}
+test clock-3.97 {ISO week-based calendar 1892-W01-6} {
+ clock format -2460758400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W01-6
+} {Sat Saturday 92 1892 6 01 01 6 01}
+test clock-3.98 {ISO week-based calendar 1892-W01-7} {
+ clock format -2460672000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W01-7
+} {Sun Sunday 92 1892 7 02 01 0 01}
+test clock-3.99 {ISO week-based calendar 1892-W02-1} {
+ clock format -2460585600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W02-1
+} {Mon Monday 92 1892 1 02 02 1 02}
+test clock-3.100 {ISO week-based calendar 1892-W52-1} {
+ clock format -2430345600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W52-1
+} {Mon Monday 92 1892 1 52 52 1 52}
+test clock-3.101 {ISO week-based calendar 1892-W52-6} {
+ clock format -2429913600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W52-6
+} {Sat Saturday 92 1892 6 52 52 6 52}
+test clock-3.102 {ISO week-based calendar 1892-W52-7} {
+ clock format -2429827200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W52-7
+} {Sun Sunday 92 1892 7 01 52 0 00}
+test clock-3.103 {ISO week-based calendar 1893-W01-1} {
+ clock format -2429740800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W01-1
+} {Mon Monday 93 1893 1 01 01 1 01}
+test clock-3.104 {ISO week-based calendar 1893-W01-6} {
+ clock format -2429308800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W01-6
+} {Sat Saturday 93 1893 6 01 01 6 01}
+test clock-3.105 {ISO week-based calendar 1893-W01-7} {
+ clock format -2429222400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W01-7
+} {Sun Sunday 93 1893 7 02 01 0 01}
+test clock-3.106 {ISO week-based calendar 1893-W02-1} {
+ clock format -2429136000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W02-1
+} {Mon Monday 93 1893 1 02 02 1 02}
+test clock-3.107 {ISO week-based calendar 1893-W52-1} {
+ clock format -2398896000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W52-1
+} {Mon Monday 93 1893 1 52 52 1 52}
+test clock-3.108 {ISO week-based calendar 1893-W52-6} {
+ clock format -2398464000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W52-6
+} {Sat Saturday 93 1893 6 52 52 6 52}
+test clock-3.109 {ISO week-based calendar 1893-W52-7} {
+ clock format -2398377600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W52-7
+} {Sun Sunday 93 1893 7 53 52 0 52}
+test clock-3.110 {ISO week-based calendar 1894-W01-1} {
+ clock format -2398291200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W01-1
+} {Mon Monday 94 1894 1 00 01 1 01}
+test clock-3.111 {ISO week-based calendar 1894-W01-6} {
+ clock format -2397859200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W01-6
+} {Sat Saturday 94 1894 6 00 01 6 01}
+test clock-3.112 {ISO week-based calendar 1894-W01-7} {
+ clock format -2397772800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W01-7
+} {Sun Sunday 94 1894 7 01 01 0 01}
+test clock-3.113 {ISO week-based calendar 1894-W02-1} {
+ clock format -2397686400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W02-1
+} {Mon Monday 94 1894 1 01 02 1 02}
+test clock-3.114 {ISO week-based calendar 1894-W52-1} {
+ clock format -2367446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W52-1
+} {Mon Monday 94 1894 1 51 52 1 52}
+test clock-3.115 {ISO week-based calendar 1894-W52-6} {
+ clock format -2367014400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W52-6
+} {Sat Saturday 94 1894 6 51 52 6 52}
+test clock-3.116 {ISO week-based calendar 1894-W52-7} {
+ clock format -2366928000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W52-7
+} {Sun Sunday 94 1894 7 52 52 0 52}
+test clock-3.117 {ISO week-based calendar 1895-W01-1} {
+ clock format -2366841600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W01-1
+} {Mon Monday 95 1895 1 52 01 1 53}
+test clock-3.118 {ISO week-based calendar 1895-W01-2} {
+ clock format -2366755200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W01-2
+} {Tue Tuesday 95 1895 2 00 01 2 00}
+test clock-3.119 {ISO week-based calendar 1895-W01-6} {
+ clock format -2366409600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W01-6
+} {Sat Saturday 95 1895 6 00 01 6 00}
+test clock-3.120 {ISO week-based calendar 1895-W01-7} {
+ clock format -2366323200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W01-7
+} {Sun Sunday 95 1895 7 01 01 0 00}
+test clock-3.121 {ISO week-based calendar 1895-W02-1} {
+ clock format -2366236800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W02-1
+} {Mon Monday 95 1895 1 01 02 1 01}
+test clock-3.122 {ISO week-based calendar 1895-W52-1} {
+ clock format -2335996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W52-1
+} {Mon Monday 95 1895 1 51 52 1 51}
+test clock-3.123 {ISO week-based calendar 1895-W52-6} {
+ clock format -2335564800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W52-6
+} {Sat Saturday 95 1895 6 51 52 6 51}
+test clock-3.124 {ISO week-based calendar 1895-W52-7} {
+ clock format -2335478400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W52-7
+} {Sun Sunday 95 1895 7 52 52 0 51}
+test clock-3.125 {ISO week-based calendar 1896-W01-1} {
+ clock format -2335392000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W01-1
+} {Mon Monday 96 1896 1 52 01 1 52}
+test clock-3.126 {ISO week-based calendar 1896-W01-3} {
+ clock format -2335219200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W01-3
+} {Wed Wednesday 96 1896 3 00 01 3 00}
+test clock-3.127 {ISO week-based calendar 1896-W01-6} {
+ clock format -2334960000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W01-6
+} {Sat Saturday 96 1896 6 00 01 6 00}
+test clock-3.128 {ISO week-based calendar 1896-W01-7} {
+ clock format -2334873600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W01-7
+} {Sun Sunday 96 1896 7 01 01 0 00}
+test clock-3.129 {ISO week-based calendar 1896-W02-1} {
+ clock format -2334787200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W02-1
+} {Mon Monday 96 1896 1 01 02 1 01}
+test clock-3.130 {ISO week-based calendar 1896-W53-1} {
+ clock format -2303942400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W53-1
+} {Mon Monday 96 1896 1 52 53 1 52}
+test clock-3.131 {ISO week-based calendar 1896-W53-5} {
+ clock format -2303596800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W53-5
+} {Fri Friday 96 1896 5 00 53 5 00}
+test clock-3.132 {ISO week-based calendar 1896-W53-6} {
+ clock format -2303510400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W53-6
+} {Sat Saturday 96 1896 6 00 53 6 00}
+test clock-3.133 {ISO week-based calendar 1896-W53-7} {
+ clock format -2303424000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W53-7
+} {Sun Sunday 96 1896 7 01 53 0 00}
+test clock-3.134 {ISO week-based calendar 1897-W01-1} {
+ clock format -2303337600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W01-1
+} {Mon Monday 97 1897 1 01 01 1 01}
+test clock-3.135 {ISO week-based calendar 1897-W01-6} {
+ clock format -2302905600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W01-6
+} {Sat Saturday 97 1897 6 01 01 6 01}
+test clock-3.136 {ISO week-based calendar 1897-W01-7} {
+ clock format -2302819200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W01-7
+} {Sun Sunday 97 1897 7 02 01 0 01}
+test clock-3.137 {ISO week-based calendar 1897-W02-1} {
+ clock format -2302732800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W02-1
+} {Mon Monday 97 1897 1 02 02 1 02}
+test clock-3.138 {ISO week-based calendar 1897-W52-1} {
+ clock format -2272492800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W52-1
+} {Mon Monday 97 1897 1 52 52 1 52}
+test clock-3.139 {ISO week-based calendar 1897-W52-6} {
+ clock format -2272060800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W52-6
+} {Sat Saturday 97 1897 6 00 52 6 00}
+test clock-3.140 {ISO week-based calendar 1897-W52-7} {
+ clock format -2271974400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W52-7
+} {Sun Sunday 97 1897 7 01 52 0 00}
+test clock-3.141 {ISO week-based calendar 1898-W01-1} {
+ clock format -2271888000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W01-1
+} {Mon Monday 98 1898 1 01 01 1 01}
+test clock-3.142 {ISO week-based calendar 1898-W01-6} {
+ clock format -2271456000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W01-6
+} {Sat Saturday 98 1898 6 01 01 6 01}
+test clock-3.143 {ISO week-based calendar 1898-W01-7} {
+ clock format -2271369600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W01-7
+} {Sun Sunday 98 1898 7 02 01 0 01}
+test clock-3.144 {ISO week-based calendar 1898-W02-1} {
+ clock format -2271283200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W02-1
+} {Mon Monday 98 1898 1 02 02 1 02}
+test clock-3.145 {ISO week-based calendar 1898-W52-1} {
+ clock format -2241043200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W52-1
+} {Mon Monday 98 1898 1 52 52 1 52}
+test clock-3.146 {ISO week-based calendar 1898-W52-6} {
+ clock format -2240611200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W52-6
+} {Sat Saturday 98 1898 6 52 52 6 52}
+test clock-3.147 {ISO week-based calendar 1898-W52-7} {
+ clock format -2240524800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W52-7
+} {Sun Sunday 98 1898 7 01 52 0 00}
+test clock-3.148 {ISO week-based calendar 1899-W01-1} {
+ clock format -2240438400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W01-1
+} {Mon Monday 99 1899 1 01 01 1 01}
+test clock-3.149 {ISO week-based calendar 1899-W01-6} {
+ clock format -2240006400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W01-6
+} {Sat Saturday 99 1899 6 01 01 6 01}
+test clock-3.150 {ISO week-based calendar 1899-W01-7} {
+ clock format -2239920000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W01-7
+} {Sun Sunday 99 1899 7 02 01 0 01}
+test clock-3.151 {ISO week-based calendar 1899-W02-1} {
+ clock format -2239833600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W02-1
+} {Mon Monday 99 1899 1 02 02 1 02}
+test clock-3.152 {ISO week-based calendar 1899-W52-1} {
+ clock format -2209593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W52-1
+} {Mon Monday 99 1899 1 52 52 1 52}
+test clock-3.153 {ISO week-based calendar 1899-W52-6} {
+ clock format -2209161600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W52-6
+} {Sat Saturday 99 1899 6 52 52 6 52}
+test clock-3.154 {ISO week-based calendar 1899-W52-7} {
+ clock format -2209075200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W52-7
+} {Sun Sunday 99 1899 7 53 52 0 52}
+test clock-3.155 {ISO week-based calendar 1900-W01-1} {
+ clock format -2208988800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1900-W01-1
+} {Mon Monday 00 1900 1 00 01 1 01}
+test clock-3.156 {ISO week-based calendar 1900-W01-6} {
+ clock format -2208556800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1900-W01-6
+} {Sat Saturday 00 1900 6 00 01 6 01}
+test clock-3.157 {ISO week-based calendar 1900-W01-7} {
+ clock format -2208470400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1900-W01-7
+} {Sun Sunday 00 1900 7 01 01 0 01}
+test clock-3.158 {ISO week-based calendar 1900-W02-1} {
+ clock format -2208384000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1900-W02-1
+} {Mon Monday 00 1900 1 01 02 1 02}
+test clock-3.159 {ISO week-based calendar 1943-W52-1} {
+ clock format -820972800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1943-W52-1
+} {Mon Monday 43 1943 1 52 52 1 52}
+test clock-3.160 {ISO week-based calendar 1943-W52-6} {
+ clock format -820540800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1943-W52-6
+} {Sat Saturday 43 1943 6 00 52 6 00}
+test clock-3.161 {ISO week-based calendar 1943-W52-7} {
+ clock format -820454400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1943-W52-7
+} {Sun Sunday 43 1943 7 01 52 0 00}
+test clock-3.162 {ISO week-based calendar 1944-W01-1} {
+ clock format -820368000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W01-1
+} {Mon Monday 44 1944 1 01 01 1 01}
+test clock-3.163 {ISO week-based calendar 1944-W01-6} {
+ clock format -819936000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W01-6
+} {Sat Saturday 44 1944 6 01 01 6 01}
+test clock-3.164 {ISO week-based calendar 1944-W01-7} {
+ clock format -819849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W01-7
+} {Sun Sunday 44 1944 7 02 01 0 01}
+test clock-3.165 {ISO week-based calendar 1944-W02-1} {
+ clock format -819763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W02-1
+} {Mon Monday 44 1944 1 02 02 1 02}
+test clock-3.166 {ISO week-based calendar 1944-W52-1} {
+ clock format -789523200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W52-1
+} {Mon Monday 44 1944 1 52 52 1 52}
+test clock-3.167 {ISO week-based calendar 1944-W52-6} {
+ clock format -789091200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W52-6
+} {Sat Saturday 44 1944 6 52 52 6 52}
+test clock-3.168 {ISO week-based calendar 1944-W52-7} {
+ clock format -789004800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W52-7
+} {Sun Sunday 44 1944 7 53 52 0 52}
+test clock-3.169 {ISO week-based calendar 1945-W01-1} {
+ clock format -788918400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1945-W01-1
+} {Mon Monday 45 1945 1 00 01 1 01}
+test clock-3.170 {ISO week-based calendar 1945-W01-6} {
+ clock format -788486400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1945-W01-6
+} {Sat Saturday 45 1945 6 00 01 6 01}
+test clock-3.171 {ISO week-based calendar 1945-W01-7} {
+ clock format -788400000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1945-W01-7
+} {Sun Sunday 45 1945 7 01 01 0 01}
+test clock-3.172 {ISO week-based calendar 1945-W02-1} {
+ clock format -788313600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1945-W02-1
+} {Mon Monday 45 1945 1 01 02 1 02}
+test clock-3.173 {ISO week-based calendar 1947-W52-1} {
+ clock format -695174400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1947-W52-1
+} {Mon Monday 47 1947 1 51 52 1 51}
+test clock-3.174 {ISO week-based calendar 1947-W52-6} {
+ clock format -694742400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1947-W52-6
+} {Sat Saturday 47 1947 6 51 52 6 51}
+test clock-3.175 {ISO week-based calendar 1947-W52-7} {
+ clock format -694656000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1947-W52-7
+} {Sun Sunday 47 1947 7 52 52 0 51}
+test clock-3.176 {ISO week-based calendar 1948-W01-1} {
+ clock format -694569600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W01-1
+} {Mon Monday 48 1948 1 52 01 1 52}
+test clock-3.177 {ISO week-based calendar 1948-W01-4} {
+ clock format -694310400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W01-4
+} {Thu Thursday 48 1948 4 00 01 4 00}
+test clock-3.178 {ISO week-based calendar 1948-W01-6} {
+ clock format -694137600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W01-6
+} {Sat Saturday 48 1948 6 00 01 6 00}
+test clock-3.179 {ISO week-based calendar 1948-W01-7} {
+ clock format -694051200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W01-7
+} {Sun Sunday 48 1948 7 01 01 0 00}
+test clock-3.180 {ISO week-based calendar 1948-W02-1} {
+ clock format -693964800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W02-1
+} {Mon Monday 48 1948 1 01 02 1 01}
+test clock-3.181 {ISO week-based calendar 1948-W53-1} {
+ clock format -663120000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W53-1
+} {Mon Monday 48 1948 1 52 53 1 52}
+test clock-3.182 {ISO week-based calendar 1948-W53-6} {
+ clock format -662688000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W53-6
+} {Sat Saturday 48 1948 6 00 53 6 00}
+test clock-3.183 {ISO week-based calendar 1948-W53-7} {
+ clock format -662601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W53-7
+} {Sun Sunday 48 1948 7 01 53 0 00}
+test clock-3.184 {ISO week-based calendar 1949-W01-1} {
+ clock format -662515200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1949-W01-1
+} {Mon Monday 49 1949 1 01 01 1 01}
+test clock-3.185 {ISO week-based calendar 1949-W01-6} {
+ clock format -662083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1949-W01-6
+} {Sat Saturday 49 1949 6 01 01 6 01}
+test clock-3.186 {ISO week-based calendar 1949-W01-7} {
+ clock format -661996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1949-W01-7
+} {Sun Sunday 49 1949 7 02 01 0 01}
+test clock-3.187 {ISO week-based calendar 1949-W02-1} {
+ clock format -661910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1949-W02-1
+} {Mon Monday 49 1949 1 02 02 1 02}
+test clock-3.188 {ISO week-based calendar 1951-W52-1} {
+ clock format -568771200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1951-W52-1
+} {Mon Monday 51 1951 1 51 52 1 52}
+test clock-3.189 {ISO week-based calendar 1951-W52-6} {
+ clock format -568339200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1951-W52-6
+} {Sat Saturday 51 1951 6 51 52 6 52}
+test clock-3.190 {ISO week-based calendar 1951-W52-7} {
+ clock format -568252800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1951-W52-7
+} {Sun Sunday 51 1951 7 52 52 0 52}
+test clock-3.191 {ISO week-based calendar 1952-W01-1} {
+ clock format -568166400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W01-1
+} {Mon Monday 52 1952 1 52 01 1 53}
+test clock-3.192 {ISO week-based calendar 1952-W01-2} {
+ clock format -568080000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W01-2
+} {Tue Tuesday 52 1952 2 00 01 2 00}
+test clock-3.193 {ISO week-based calendar 1952-W01-6} {
+ clock format -567734400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W01-6
+} {Sat Saturday 52 1952 6 00 01 6 00}
+test clock-3.194 {ISO week-based calendar 1952-W01-7} {
+ clock format -567648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W01-7
+} {Sun Sunday 52 1952 7 01 01 0 00}
+test clock-3.195 {ISO week-based calendar 1952-W02-1} {
+ clock format -567561600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W02-1
+} {Mon Monday 52 1952 1 01 02 1 01}
+test clock-3.196 {ISO week-based calendar 1952-W52-1} {
+ clock format -537321600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W52-1
+} {Mon Monday 52 1952 1 51 52 1 51}
+test clock-3.197 {ISO week-based calendar 1952-W52-6} {
+ clock format -536889600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W52-6
+} {Sat Saturday 52 1952 6 51 52 6 51}
+test clock-3.198 {ISO week-based calendar 1952-W52-7} {
+ clock format -536803200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W52-7
+} {Sun Sunday 52 1952 7 52 52 0 51}
+test clock-3.199 {ISO week-based calendar 1953-W01-1} {
+ clock format -536716800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1953-W01-1
+} {Mon Monday 53 1953 1 52 01 1 52}
+test clock-3.200 {ISO week-based calendar 1953-W01-4} {
+ clock format -536457600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1953-W01-4
+} {Thu Thursday 53 1953 4 00 01 4 00}
+test clock-3.201 {ISO week-based calendar 1953-W01-6} {
+ clock format -536284800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1953-W01-6
+} {Sat Saturday 53 1953 6 00 01 6 00}
+test clock-3.202 {ISO week-based calendar 1953-W01-7} {
+ clock format -536198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1953-W01-7
+} {Sun Sunday 53 1953 7 01 01 0 00}
+test clock-3.203 {ISO week-based calendar 1953-W02-1} {
+ clock format -536112000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1953-W02-1
+} {Mon Monday 53 1953 1 01 02 1 01}
+test clock-3.204 {ISO week-based calendar 1955-W52-1} {
+ clock format -442368000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1955-W52-1
+} {Mon Monday 55 1955 1 52 52 1 52}
+test clock-3.205 {ISO week-based calendar 1955-W52-6} {
+ clock format -441936000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1955-W52-6
+} {Sat Saturday 55 1955 6 52 52 6 52}
+test clock-3.206 {ISO week-based calendar 1955-W52-7} {
+ clock format -441849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1955-W52-7
+} {Sun Sunday 55 1955 7 01 52 0 00}
+test clock-3.207 {ISO week-based calendar 1956-W01-1} {
+ clock format -441763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W01-1
+} {Mon Monday 56 1956 1 01 01 1 01}
+test clock-3.208 {ISO week-based calendar 1956-W01-6} {
+ clock format -441331200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W01-6
+} {Sat Saturday 56 1956 6 01 01 6 01}
+test clock-3.209 {ISO week-based calendar 1956-W01-7} {
+ clock format -441244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W01-7
+} {Sun Sunday 56 1956 7 02 01 0 01}
+test clock-3.210 {ISO week-based calendar 1956-W02-1} {
+ clock format -441158400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W02-1
+} {Mon Monday 56 1956 1 02 02 1 02}
+test clock-3.211 {ISO week-based calendar 1956-W52-1} {
+ clock format -410918400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W52-1
+} {Mon Monday 56 1956 1 52 52 1 52}
+test clock-3.212 {ISO week-based calendar 1956-W52-6} {
+ clock format -410486400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W52-6
+} {Sat Saturday 56 1956 6 52 52 6 52}
+test clock-3.213 {ISO week-based calendar 1956-W52-7} {
+ clock format -410400000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W52-7
+} {Sun Sunday 56 1956 7 53 52 0 52}
+test clock-3.214 {ISO week-based calendar 1957-W01-1} {
+ clock format -410313600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1957-W01-1
+} {Mon Monday 57 1957 1 53 01 1 53}
+test clock-3.215 {ISO week-based calendar 1957-W01-2} {
+ clock format -410227200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1957-W01-2
+} {Tue Tuesday 57 1957 2 00 01 2 00}
+test clock-3.216 {ISO week-based calendar 1957-W01-6} {
+ clock format -409881600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1957-W01-6
+} {Sat Saturday 57 1957 6 00 01 6 00}
+test clock-3.217 {ISO week-based calendar 1957-W01-7} {
+ clock format -409795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1957-W01-7
+} {Sun Sunday 57 1957 7 01 01 0 00}
+test clock-3.218 {ISO week-based calendar 1957-W02-1} {
+ clock format -409708800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1957-W02-1
+} {Mon Monday 57 1957 1 01 02 1 01}
+test clock-3.219 {ISO week-based calendar 1958-W52-1} {
+ clock format -348019200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1958-W52-1
+} {Mon Monday 58 1958 1 51 52 1 51}
+test clock-3.220 {ISO week-based calendar 1958-W52-6} {
+ clock format -347587200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1958-W52-6
+} {Sat Saturday 58 1958 6 51 52 6 51}
+test clock-3.221 {ISO week-based calendar 1958-W52-7} {
+ clock format -347500800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1958-W52-7
+} {Sun Sunday 58 1958 7 52 52 0 51}
+test clock-3.222 {ISO week-based calendar 1959-W01-1} {
+ clock format -347414400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W01-1
+} {Mon Monday 59 1959 1 52 01 1 52}
+test clock-3.223 {ISO week-based calendar 1959-W01-4} {
+ clock format -347155200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W01-4
+} {Thu Thursday 59 1959 4 00 01 4 00}
+test clock-3.224 {ISO week-based calendar 1959-W01-6} {
+ clock format -346982400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W01-6
+} {Sat Saturday 59 1959 6 00 01 6 00}
+test clock-3.225 {ISO week-based calendar 1959-W01-7} {
+ clock format -346896000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W01-7
+} {Sun Sunday 59 1959 7 01 01 0 00}
+test clock-3.226 {ISO week-based calendar 1959-W02-1} {
+ clock format -346809600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W02-1
+} {Mon Monday 59 1959 1 01 02 1 01}
+test clock-3.227 {ISO week-based calendar 1959-W53-1} {
+ clock format -315964800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W53-1
+} {Mon Monday 59 1959 1 52 53 1 52}
+test clock-3.228 {ISO week-based calendar 1959-W53-5} {
+ clock format -315619200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W53-5
+} {Fri Friday 59 1959 5 00 53 5 00}
+test clock-3.229 {ISO week-based calendar 1959-W53-6} {
+ clock format -315532800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W53-6
+} {Sat Saturday 59 1959 6 00 53 6 00}
+test clock-3.230 {ISO week-based calendar 1959-W53-7} {
+ clock format -315446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W53-7
+} {Sun Sunday 59 1959 7 01 53 0 00}
+test clock-3.231 {ISO week-based calendar 1960-W01-1} {
+ clock format -315360000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W01-1
+} {Mon Monday 60 1960 1 01 01 1 01}
+test clock-3.232 {ISO week-based calendar 1960-W01-6} {
+ clock format -314928000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W01-6
+} {Sat Saturday 60 1960 6 01 01 6 01}
+test clock-3.233 {ISO week-based calendar 1960-W01-7} {
+ clock format -314841600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W01-7
+} {Sun Sunday 60 1960 7 02 01 0 01}
+test clock-3.234 {ISO week-based calendar 1960-W02-1} {
+ clock format -314755200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W02-1
+} {Mon Monday 60 1960 1 02 02 1 02}
+test clock-3.235 {ISO week-based calendar 1960-W52-1} {
+ clock format -284515200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W52-1
+} {Mon Monday 60 1960 1 52 52 1 52}
+test clock-3.236 {ISO week-based calendar 1960-W52-6} {
+ clock format -284083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W52-6
+} {Sat Saturday 60 1960 6 52 52 6 52}
+test clock-3.237 {ISO week-based calendar 1960-W52-7} {
+ clock format -283996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W52-7
+} {Sun Sunday 60 1960 7 01 52 0 00}
+test clock-3.238 {ISO week-based calendar 1961-W01-1} {
+ clock format -283910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W01-1
+} {Mon Monday 61 1961 1 01 01 1 01}
+test clock-3.239 {ISO week-based calendar 1961-W01-6} {
+ clock format -283478400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W01-6
+} {Sat Saturday 61 1961 6 01 01 6 01}
+test clock-3.240 {ISO week-based calendar 1961-W01-7} {
+ clock format -283392000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W01-7
+} {Sun Sunday 61 1961 7 02 01 0 01}
+test clock-3.241 {ISO week-based calendar 1961-W02-1} {
+ clock format -283305600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W02-1
+} {Mon Monday 61 1961 1 02 02 1 02}
+test clock-3.242 {ISO week-based calendar 1961-W52-1} {
+ clock format -253065600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W52-1
+} {Mon Monday 61 1961 1 52 52 1 52}
+test clock-3.243 {ISO week-based calendar 1961-W52-6} {
+ clock format -252633600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W52-6
+} {Sat Saturday 61 1961 6 52 52 6 52}
+test clock-3.244 {ISO week-based calendar 1961-W52-7} {
+ clock format -252547200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W52-7
+} {Sun Sunday 61 1961 7 53 52 0 52}
+test clock-3.245 {ISO week-based calendar 1962-W01-1} {
+ clock format -252460800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W01-1
+} {Mon Monday 62 1962 1 00 01 1 01}
+test clock-3.246 {ISO week-based calendar 1962-W01-6} {
+ clock format -252028800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W01-6
+} {Sat Saturday 62 1962 6 00 01 6 01}
+test clock-3.247 {ISO week-based calendar 1962-W01-7} {
+ clock format -251942400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W01-7
+} {Sun Sunday 62 1962 7 01 01 0 01}
+test clock-3.248 {ISO week-based calendar 1962-W02-1} {
+ clock format -251856000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W02-1
+} {Mon Monday 62 1962 1 01 02 1 02}
+test clock-3.249 {ISO week-based calendar 1962-W52-1} {
+ clock format -221616000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W52-1
+} {Mon Monday 62 1962 1 51 52 1 52}
+test clock-3.250 {ISO week-based calendar 1962-W52-6} {
+ clock format -221184000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W52-6
+} {Sat Saturday 62 1962 6 51 52 6 52}
+test clock-3.251 {ISO week-based calendar 1962-W52-7} {
+ clock format -221097600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W52-7
+} {Sun Sunday 62 1962 7 52 52 0 52}
+test clock-3.252 {ISO week-based calendar 1963-W01-1} {
+ clock format -221011200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W01-1
+} {Mon Monday 63 1963 1 52 01 1 53}
+test clock-3.253 {ISO week-based calendar 1963-W01-2} {
+ clock format -220924800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W01-2
+} {Tue Tuesday 63 1963 2 00 01 2 00}
+test clock-3.254 {ISO week-based calendar 1963-W01-6} {
+ clock format -220579200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W01-6
+} {Sat Saturday 63 1963 6 00 01 6 00}
+test clock-3.255 {ISO week-based calendar 1963-W01-7} {
+ clock format -220492800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W01-7
+} {Sun Sunday 63 1963 7 01 01 0 00}
+test clock-3.256 {ISO week-based calendar 1963-W02-1} {
+ clock format -220406400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W02-1
+} {Mon Monday 63 1963 1 01 02 1 01}
+test clock-3.257 {ISO week-based calendar 1963-W52-1} {
+ clock format -190166400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W52-1
+} {Mon Monday 63 1963 1 51 52 1 51}
+test clock-3.258 {ISO week-based calendar 1963-W52-6} {
+ clock format -189734400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W52-6
+} {Sat Saturday 63 1963 6 51 52 6 51}
+test clock-3.259 {ISO week-based calendar 1963-W52-7} {
+ clock format -189648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W52-7
+} {Sun Sunday 63 1963 7 52 52 0 51}
+test clock-3.260 {ISO week-based calendar 1964-W01-1} {
+ clock format -189561600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W01-1
+} {Mon Monday 64 1964 1 52 01 1 52}
+test clock-3.261 {ISO week-based calendar 1964-W01-3} {
+ clock format -189388800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W01-3
+} {Wed Wednesday 64 1964 3 00 01 3 00}
+test clock-3.262 {ISO week-based calendar 1964-W01-6} {
+ clock format -189129600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W01-6
+} {Sat Saturday 64 1964 6 00 01 6 00}
+test clock-3.263 {ISO week-based calendar 1964-W01-7} {
+ clock format -189043200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W01-7
+} {Sun Sunday 64 1964 7 01 01 0 00}
+test clock-3.264 {ISO week-based calendar 1964-W02-1} {
+ clock format -188956800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W02-1
+} {Mon Monday 64 1964 1 01 02 1 01}
+test clock-3.265 {ISO week-based calendar 1964-W53-1} {
+ clock format -158112000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W53-1
+} {Mon Monday 64 1964 1 52 53 1 52}
+test clock-3.266 {ISO week-based calendar 1964-W53-5} {
+ clock format -157766400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W53-5
+} {Fri Friday 64 1964 5 00 53 5 00}
+test clock-3.267 {ISO week-based calendar 1964-W53-6} {
+ clock format -157680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W53-6
+} {Sat Saturday 64 1964 6 00 53 6 00}
+test clock-3.268 {ISO week-based calendar 1964-W53-7} {
+ clock format -157593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W53-7
+} {Sun Sunday 64 1964 7 01 53 0 00}
+test clock-3.269 {ISO week-based calendar 1965-W01-1} {
+ clock format -157507200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W01-1
+} {Mon Monday 65 1965 1 01 01 1 01}
+test clock-3.270 {ISO week-based calendar 1965-W01-6} {
+ clock format -157075200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W01-6
+} {Sat Saturday 65 1965 6 01 01 6 01}
+test clock-3.271 {ISO week-based calendar 1965-W01-7} {
+ clock format -156988800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W01-7
+} {Sun Sunday 65 1965 7 02 01 0 01}
+test clock-3.272 {ISO week-based calendar 1965-W02-1} {
+ clock format -156902400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W02-1
+} {Mon Monday 65 1965 1 02 02 1 02}
+test clock-3.273 {ISO week-based calendar 1965-W52-1} {
+ clock format -126662400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W52-1
+} {Mon Monday 65 1965 1 52 52 1 52}
+test clock-3.274 {ISO week-based calendar 1965-W52-6} {
+ clock format -126230400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W52-6
+} {Sat Saturday 65 1965 6 00 52 6 00}
+test clock-3.275 {ISO week-based calendar 1965-W52-7} {
+ clock format -126144000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W52-7
+} {Sun Sunday 65 1965 7 01 52 0 00}
+test clock-3.276 {ISO week-based calendar 1966-W01-1} {
+ clock format -126057600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W01-1
+} {Mon Monday 66 1966 1 01 01 1 01}
+test clock-3.277 {ISO week-based calendar 1966-W01-6} {
+ clock format -125625600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W01-6
+} {Sat Saturday 66 1966 6 01 01 6 01}
+test clock-3.278 {ISO week-based calendar 1966-W01-7} {
+ clock format -125539200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W01-7
+} {Sun Sunday 66 1966 7 02 01 0 01}
+test clock-3.279 {ISO week-based calendar 1966-W02-1} {
+ clock format -125452800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W02-1
+} {Mon Monday 66 1966 1 02 02 1 02}
+test clock-3.280 {ISO week-based calendar 1966-W52-1} {
+ clock format -95212800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W52-1
+} {Mon Monday 66 1966 1 52 52 1 52}
+test clock-3.281 {ISO week-based calendar 1966-W52-6} {
+ clock format -94780800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W52-6
+} {Sat Saturday 66 1966 6 52 52 6 52}
+test clock-3.282 {ISO week-based calendar 1966-W52-7} {
+ clock format -94694400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W52-7
+} {Sun Sunday 66 1966 7 01 52 0 00}
+test clock-3.283 {ISO week-based calendar 1967-W01-1} {
+ clock format -94608000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W01-1
+} {Mon Monday 67 1967 1 01 01 1 01}
+test clock-3.284 {ISO week-based calendar 1967-W01-6} {
+ clock format -94176000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W01-6
+} {Sat Saturday 67 1967 6 01 01 6 01}
+test clock-3.285 {ISO week-based calendar 1967-W01-7} {
+ clock format -94089600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W01-7
+} {Sun Sunday 67 1967 7 02 01 0 01}
+test clock-3.286 {ISO week-based calendar 1967-W02-1} {
+ clock format -94003200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W02-1
+} {Mon Monday 67 1967 1 02 02 1 02}
+test clock-3.287 {ISO week-based calendar 1967-W52-1} {
+ clock format -63763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W52-1
+} {Mon Monday 67 1967 1 52 52 1 52}
+test clock-3.288 {ISO week-based calendar 1967-W52-6} {
+ clock format -63331200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W52-6
+} {Sat Saturday 67 1967 6 52 52 6 52}
+test clock-3.289 {ISO week-based calendar 1967-W52-7} {
+ clock format -63244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W52-7
+} {Sun Sunday 67 1967 7 53 52 0 52}
+test clock-3.290 {ISO week-based calendar 1968-W01-1} {
+ clock format -63158400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W01-1
+} {Mon Monday 68 1968 1 00 01 1 01}
+test clock-3.291 {ISO week-based calendar 1968-W01-6} {
+ clock format -62726400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W01-6
+} {Sat Saturday 68 1968 6 00 01 6 01}
+test clock-3.292 {ISO week-based calendar 1968-W01-7} {
+ clock format -62640000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W01-7
+} {Sun Sunday 68 1968 7 01 01 0 01}
+test clock-3.293 {ISO week-based calendar 1968-W02-1} {
+ clock format -62553600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W02-1
+} {Mon Monday 68 1968 1 01 02 1 02}
+test clock-3.294 {ISO week-based calendar 1968-W52-1} {
+ clock format -32313600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W52-1
+} {Mon Monday 68 1968 1 51 52 1 52}
+test clock-3.295 {ISO week-based calendar 1968-W52-6} {
+ clock format -31881600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W52-6
+} {Sat Saturday 68 1968 6 51 52 6 52}
+test clock-3.296 {ISO week-based calendar 1968-W52-7} {
+ clock format -31795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W52-7
+} {Sun Sunday 68 1968 7 52 52 0 52}
+test clock-3.297 {ISO week-based calendar 1969-W01-1} {
+ clock format -31708800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W01-1
+} {Mon Monday 69 1969 1 52 01 1 53}
+test clock-3.298 {ISO week-based calendar 1969-W01-3} {
+ clock format -31536000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W01-3
+} {Wed Wednesday 69 1969 3 00 01 3 00}
+test clock-3.299 {ISO week-based calendar 1969-W01-6} {
+ clock format -31276800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W01-6
+} {Sat Saturday 69 1969 6 00 01 6 00}
+test clock-3.300 {ISO week-based calendar 1969-W01-7} {
+ clock format -31190400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W01-7
+} {Sun Sunday 69 1969 7 01 01 0 00}
+test clock-3.301 {ISO week-based calendar 1969-W02-1} {
+ clock format -31104000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W02-1
+} {Mon Monday 69 1969 1 01 02 1 01}
+test clock-3.302 {ISO week-based calendar 1969-W52-1} {
+ clock format -864000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W52-1
+} {Mon Monday 69 1969 1 51 52 1 51}
+test clock-3.303 {ISO week-based calendar 1969-W52-6} {
+ clock format -432000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W52-6
+} {Sat Saturday 69 1969 6 51 52 6 51}
+test clock-3.304 {ISO week-based calendar 1969-W52-7} {
+ clock format -345600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W52-7
+} {Sun Sunday 69 1969 7 52 52 0 51}
+test clock-3.305 {ISO week-based calendar 1970-W01-1} {
+ clock format -259200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W01-1
+} {Mon Monday 70 1970 1 52 01 1 52}
+test clock-3.306 {ISO week-based calendar 1970-W01-4} {
+ clock format 0 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W01-4
+} {Thu Thursday 70 1970 4 00 01 4 00}
+test clock-3.307 {ISO week-based calendar 1970-W01-6} {
+ clock format 172800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W01-6
+} {Sat Saturday 70 1970 6 00 01 6 00}
+test clock-3.308 {ISO week-based calendar 1970-W01-7} {
+ clock format 259200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W01-7
+} {Sun Sunday 70 1970 7 01 01 0 00}
+test clock-3.309 {ISO week-based calendar 1970-W02-1} {
+ clock format 345600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W02-1
+} {Mon Monday 70 1970 1 01 02 1 01}
+test clock-3.310 {ISO week-based calendar 1970-W53-1} {
+ clock format 31190400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W53-1
+} {Mon Monday 70 1970 1 52 53 1 52}
+test clock-3.311 {ISO week-based calendar 1970-W53-5} {
+ clock format 31536000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W53-5
+} {Fri Friday 70 1970 5 00 53 5 00}
+test clock-3.312 {ISO week-based calendar 1970-W53-6} {
+ clock format 31622400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W53-6
+} {Sat Saturday 70 1970 6 00 53 6 00}
+test clock-3.313 {ISO week-based calendar 1970-W53-7} {
+ clock format 31708800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W53-7
+} {Sun Sunday 70 1970 7 01 53 0 00}
+test clock-3.314 {ISO week-based calendar 1971-W01-1} {
+ clock format 31795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W01-1
+} {Mon Monday 71 1971 1 01 01 1 01}
+test clock-3.315 {ISO week-based calendar 1971-W01-6} {
+ clock format 32227200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W01-6
+} {Sat Saturday 71 1971 6 01 01 6 01}
+test clock-3.316 {ISO week-based calendar 1971-W01-7} {
+ clock format 32313600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W01-7
+} {Sun Sunday 71 1971 7 02 01 0 01}
+test clock-3.317 {ISO week-based calendar 1971-W02-1} {
+ clock format 32400000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W02-1
+} {Mon Monday 71 1971 1 02 02 1 02}
+test clock-3.318 {ISO week-based calendar 1971-W52-1} {
+ clock format 62640000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W52-1
+} {Mon Monday 71 1971 1 52 52 1 52}
+test clock-3.319 {ISO week-based calendar 1971-W52-6} {
+ clock format 63072000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W52-6
+} {Sat Saturday 71 1971 6 00 52 6 00}
+test clock-3.320 {ISO week-based calendar 1971-W52-7} {
+ clock format 63158400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W52-7
+} {Sun Sunday 71 1971 7 01 52 0 00}
+test clock-3.321 {ISO week-based calendar 1972-W01-1} {
+ clock format 63244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W01-1
+} {Mon Monday 72 1972 1 01 01 1 01}
+test clock-3.322 {ISO week-based calendar 1972-W01-6} {
+ clock format 63676800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W01-6
+} {Sat Saturday 72 1972 6 01 01 6 01}
+test clock-3.323 {ISO week-based calendar 1972-W01-7} {
+ clock format 63763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W01-7
+} {Sun Sunday 72 1972 7 02 01 0 01}
+test clock-3.324 {ISO week-based calendar 1972-W02-1} {
+ clock format 63849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W02-1
+} {Mon Monday 72 1972 1 02 02 1 02}
+test clock-3.325 {ISO week-based calendar 1972-W52-1} {
+ clock format 94089600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W52-1
+} {Mon Monday 72 1972 1 52 52 1 52}
+test clock-3.326 {ISO week-based calendar 1972-W52-6} {
+ clock format 94521600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W52-6
+} {Sat Saturday 72 1972 6 52 52 6 52}
+test clock-3.327 {ISO week-based calendar 1972-W52-7} {
+ clock format 94608000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W52-7
+} {Sun Sunday 72 1972 7 53 52 0 52}
+test clock-3.328 {ISO week-based calendar 1973-W01-1} {
+ clock format 94694400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W01-1
+} {Mon Monday 73 1973 1 00 01 1 01}
+test clock-3.329 {ISO week-based calendar 1973-W01-6} {
+ clock format 95126400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W01-6
+} {Sat Saturday 73 1973 6 00 01 6 01}
+test clock-3.330 {ISO week-based calendar 1973-W01-7} {
+ clock format 95212800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W01-7
+} {Sun Sunday 73 1973 7 01 01 0 01}
+test clock-3.331 {ISO week-based calendar 1973-W02-1} {
+ clock format 95299200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W02-1
+} {Mon Monday 73 1973 1 01 02 1 02}
+test clock-3.332 {ISO week-based calendar 1973-W52-1} {
+ clock format 125539200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W52-1
+} {Mon Monday 73 1973 1 51 52 1 52}
+test clock-3.333 {ISO week-based calendar 1973-W52-6} {
+ clock format 125971200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W52-6
+} {Sat Saturday 73 1973 6 51 52 6 52}
+test clock-3.334 {ISO week-based calendar 1973-W52-7} {
+ clock format 126057600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W52-7
+} {Sun Sunday 73 1973 7 52 52 0 52}
+test clock-3.335 {ISO week-based calendar 1974-W01-1} {
+ clock format 126144000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W01-1
+} {Mon Monday 74 1974 1 52 01 1 53}
+test clock-3.336 {ISO week-based calendar 1974-W01-2} {
+ clock format 126230400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W01-2
+} {Tue Tuesday 74 1974 2 00 01 2 00}
+test clock-3.337 {ISO week-based calendar 1974-W01-6} {
+ clock format 126576000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W01-6
+} {Sat Saturday 74 1974 6 00 01 6 00}
+test clock-3.338 {ISO week-based calendar 1974-W01-7} {
+ clock format 126662400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W01-7
+} {Sun Sunday 74 1974 7 01 01 0 00}
+test clock-3.339 {ISO week-based calendar 1974-W02-1} {
+ clock format 126748800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W02-1
+} {Mon Monday 74 1974 1 01 02 1 01}
+test clock-3.340 {ISO week-based calendar 1974-W52-1} {
+ clock format 156988800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W52-1
+} {Mon Monday 74 1974 1 51 52 1 51}
+test clock-3.341 {ISO week-based calendar 1974-W52-6} {
+ clock format 157420800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W52-6
+} {Sat Saturday 74 1974 6 51 52 6 51}
+test clock-3.342 {ISO week-based calendar 1974-W52-7} {
+ clock format 157507200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W52-7
+} {Sun Sunday 74 1974 7 52 52 0 51}
+test clock-3.343 {ISO week-based calendar 1975-W01-1} {
+ clock format 157593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W01-1
+} {Mon Monday 75 1975 1 52 01 1 52}
+test clock-3.344 {ISO week-based calendar 1975-W01-3} {
+ clock format 157766400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W01-3
+} {Wed Wednesday 75 1975 3 00 01 3 00}
+test clock-3.345 {ISO week-based calendar 1975-W01-6} {
+ clock format 158025600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W01-6
+} {Sat Saturday 75 1975 6 00 01 6 00}
+test clock-3.346 {ISO week-based calendar 1975-W01-7} {
+ clock format 158112000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W01-7
+} {Sun Sunday 75 1975 7 01 01 0 00}
+test clock-3.347 {ISO week-based calendar 1975-W02-1} {
+ clock format 158198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W02-1
+} {Mon Monday 75 1975 1 01 02 1 01}
+test clock-3.348 {ISO week-based calendar 1975-W52-1} {
+ clock format 188438400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W52-1
+} {Mon Monday 75 1975 1 51 52 1 51}
+test clock-3.349 {ISO week-based calendar 1975-W52-6} {
+ clock format 188870400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W52-6
+} {Sat Saturday 75 1975 6 51 52 6 51}
+test clock-3.350 {ISO week-based calendar 1975-W52-7} {
+ clock format 188956800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W52-7
+} {Sun Sunday 75 1975 7 52 52 0 51}
+test clock-3.351 {ISO week-based calendar 1976-W01-1} {
+ clock format 189043200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W01-1
+} {Mon Monday 76 1976 1 52 01 1 52}
+test clock-3.352 {ISO week-based calendar 1976-W01-4} {
+ clock format 189302400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W01-4
+} {Thu Thursday 76 1976 4 00 01 4 00}
+test clock-3.353 {ISO week-based calendar 1976-W01-6} {
+ clock format 189475200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W01-6
+} {Sat Saturday 76 1976 6 00 01 6 00}
+test clock-3.354 {ISO week-based calendar 1976-W01-7} {
+ clock format 189561600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W01-7
+} {Sun Sunday 76 1976 7 01 01 0 00}
+test clock-3.355 {ISO week-based calendar 1976-W02-1} {
+ clock format 189648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W02-1
+} {Mon Monday 76 1976 1 01 02 1 01}
+test clock-3.356 {ISO week-based calendar 1976-W53-1} {
+ clock format 220492800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W53-1
+} {Mon Monday 76 1976 1 52 53 1 52}
+test clock-3.357 {ISO week-based calendar 1976-W53-6} {
+ clock format 220924800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W53-6
+} {Sat Saturday 76 1976 6 00 53 6 00}
+test clock-3.358 {ISO week-based calendar 1976-W53-7} {
+ clock format 221011200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W53-7
+} {Sun Sunday 76 1976 7 01 53 0 00}
+test clock-3.359 {ISO week-based calendar 1977-W01-1} {
+ clock format 221097600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W01-1
+} {Mon Monday 77 1977 1 01 01 1 01}
+test clock-3.360 {ISO week-based calendar 1977-W01-6} {
+ clock format 221529600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W01-6
+} {Sat Saturday 77 1977 6 01 01 6 01}
+test clock-3.361 {ISO week-based calendar 1977-W01-7} {
+ clock format 221616000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W01-7
+} {Sun Sunday 77 1977 7 02 01 0 01}
+test clock-3.362 {ISO week-based calendar 1977-W02-1} {
+ clock format 221702400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W02-1
+} {Mon Monday 77 1977 1 02 02 1 02}
+test clock-3.363 {ISO week-based calendar 1977-W52-1} {
+ clock format 251942400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W52-1
+} {Mon Monday 77 1977 1 52 52 1 52}
+test clock-3.364 {ISO week-based calendar 1977-W52-6} {
+ clock format 252374400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W52-6
+} {Sat Saturday 77 1977 6 52 52 6 52}
+test clock-3.365 {ISO week-based calendar 1977-W52-7} {
+ clock format 252460800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W52-7
+} {Sun Sunday 77 1977 7 01 52 0 00}
+test clock-3.366 {ISO week-based calendar 1978-W01-1} {
+ clock format 252547200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W01-1
+} {Mon Monday 78 1978 1 01 01 1 01}
+test clock-3.367 {ISO week-based calendar 1978-W01-6} {
+ clock format 252979200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W01-6
+} {Sat Saturday 78 1978 6 01 01 6 01}
+test clock-3.368 {ISO week-based calendar 1978-W01-7} {
+ clock format 253065600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W01-7
+} {Sun Sunday 78 1978 7 02 01 0 01}
+test clock-3.369 {ISO week-based calendar 1978-W02-1} {
+ clock format 253152000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W02-1
+} {Mon Monday 78 1978 1 02 02 1 02}
+test clock-3.370 {ISO week-based calendar 1978-W52-1} {
+ clock format 283392000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W52-1
+} {Mon Monday 78 1978 1 52 52 1 52}
+test clock-3.371 {ISO week-based calendar 1978-W52-6} {
+ clock format 283824000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W52-6
+} {Sat Saturday 78 1978 6 52 52 6 52}
+test clock-3.372 {ISO week-based calendar 1978-W52-7} {
+ clock format 283910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W52-7
+} {Sun Sunday 78 1978 7 53 52 0 52}
+test clock-3.373 {ISO week-based calendar 1979-W01-1} {
+ clock format 283996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W01-1
+} {Mon Monday 79 1979 1 00 01 1 01}
+test clock-3.374 {ISO week-based calendar 1979-W01-6} {
+ clock format 284428800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W01-6
+} {Sat Saturday 79 1979 6 00 01 6 01}
+test clock-3.375 {ISO week-based calendar 1979-W01-7} {
+ clock format 284515200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W01-7
+} {Sun Sunday 79 1979 7 01 01 0 01}
+test clock-3.376 {ISO week-based calendar 1979-W02-1} {
+ clock format 284601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W02-1
+} {Mon Monday 79 1979 1 01 02 1 02}
+test clock-3.377 {ISO week-based calendar 1979-W52-1} {
+ clock format 314841600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W52-1
+} {Mon Monday 79 1979 1 51 52 1 52}
+test clock-3.378 {ISO week-based calendar 1979-W52-6} {
+ clock format 315273600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W52-6
+} {Sat Saturday 79 1979 6 51 52 6 52}
+test clock-3.379 {ISO week-based calendar 1979-W52-7} {
+ clock format 315360000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W52-7
+} {Sun Sunday 79 1979 7 52 52 0 52}
+test clock-3.380 {ISO week-based calendar 1980-W01-1} {
+ clock format 315446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W01-1
+} {Mon Monday 80 1980 1 52 01 1 53}
+test clock-3.381 {ISO week-based calendar 1980-W01-2} {
+ clock format 315532800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W01-2
+} {Tue Tuesday 80 1980 2 00 01 2 00}
+test clock-3.382 {ISO week-based calendar 1980-W01-6} {
+ clock format 315878400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W01-6
+} {Sat Saturday 80 1980 6 00 01 6 00}
+test clock-3.383 {ISO week-based calendar 1980-W01-7} {
+ clock format 315964800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W01-7
+} {Sun Sunday 80 1980 7 01 01 0 00}
+test clock-3.384 {ISO week-based calendar 1980-W02-1} {
+ clock format 316051200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W02-1
+} {Mon Monday 80 1980 1 01 02 1 01}
+test clock-3.385 {ISO week-based calendar 1980-W52-1} {
+ clock format 346291200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W52-1
+} {Mon Monday 80 1980 1 51 52 1 51}
+test clock-3.386 {ISO week-based calendar 1980-W52-6} {
+ clock format 346723200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W52-6
+} {Sat Saturday 80 1980 6 51 52 6 51}
+test clock-3.387 {ISO week-based calendar 1980-W52-7} {
+ clock format 346809600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W52-7
+} {Sun Sunday 80 1980 7 52 52 0 51}
+test clock-3.388 {ISO week-based calendar 1981-W01-1} {
+ clock format 346896000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1981-W01-1
+} {Mon Monday 81 1981 1 52 01 1 52}
+test clock-3.389 {ISO week-based calendar 1981-W01-4} {
+ clock format 347155200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1981-W01-4
+} {Thu Thursday 81 1981 4 00 01 4 00}
+test clock-3.390 {ISO week-based calendar 1981-W01-6} {
+ clock format 347328000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1981-W01-6
+} {Sat Saturday 81 1981 6 00 01 6 00}
+test clock-3.391 {ISO week-based calendar 1981-W01-7} {
+ clock format 347414400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1981-W01-7
+} {Sun Sunday 81 1981 7 01 01 0 00}
+test clock-3.392 {ISO week-based calendar 1981-W02-1} {
+ clock format 347500800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1981-W02-1
+} {Mon Monday 81 1981 1 01 02 1 01}
+test clock-3.393 {ISO week-based calendar 1983-W52-1} {
+ clock format 441244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1983-W52-1
+} {Mon Monday 83 1983 1 52 52 1 52}
+test clock-3.394 {ISO week-based calendar 1983-W52-6} {
+ clock format 441676800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1983-W52-6
+} {Sat Saturday 83 1983 6 52 52 6 52}
+test clock-3.395 {ISO week-based calendar 1983-W52-7} {
+ clock format 441763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1983-W52-7
+} {Sun Sunday 83 1983 7 01 52 0 00}
+test clock-3.396 {ISO week-based calendar 1984-W01-1} {
+ clock format 441849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W01-1
+} {Mon Monday 84 1984 1 01 01 1 01}
+test clock-3.397 {ISO week-based calendar 1984-W01-6} {
+ clock format 442281600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W01-6
+} {Sat Saturday 84 1984 6 01 01 6 01}
+test clock-3.398 {ISO week-based calendar 1984-W01-7} {
+ clock format 442368000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W01-7
+} {Sun Sunday 84 1984 7 02 01 0 01}
+test clock-3.399 {ISO week-based calendar 1984-W02-1} {
+ clock format 442454400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W02-1
+} {Mon Monday 84 1984 1 02 02 1 02}
+test clock-3.400 {ISO week-based calendar 1984-W52-1} {
+ clock format 472694400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W52-1
+} {Mon Monday 84 1984 1 52 52 1 52}
+test clock-3.401 {ISO week-based calendar 1984-W52-6} {
+ clock format 473126400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W52-6
+} {Sat Saturday 84 1984 6 52 52 6 52}
+test clock-3.402 {ISO week-based calendar 1984-W52-7} {
+ clock format 473212800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W52-7
+} {Sun Sunday 84 1984 7 53 52 0 52}
+test clock-3.403 {ISO week-based calendar 1985-W01-1} {
+ clock format 473299200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1985-W01-1
+} {Mon Monday 85 1985 1 53 01 1 53}
+test clock-3.404 {ISO week-based calendar 1985-W01-2} {
+ clock format 473385600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1985-W01-2
+} {Tue Tuesday 85 1985 2 00 01 2 00}
+test clock-3.405 {ISO week-based calendar 1985-W01-6} {
+ clock format 473731200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1985-W01-6
+} {Sat Saturday 85 1985 6 00 01 6 00}
+test clock-3.406 {ISO week-based calendar 1985-W01-7} {
+ clock format 473817600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1985-W01-7
+} {Sun Sunday 85 1985 7 01 01 0 00}
+test clock-3.407 {ISO week-based calendar 1985-W02-1} {
+ clock format 473904000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1985-W02-1
+} {Mon Monday 85 1985 1 01 02 1 01}
+test clock-3.408 {ISO week-based calendar 1987-W53-1} {
+ clock format 567648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1987-W53-1
+} {Mon Monday 87 1987 1 52 53 1 52}
+test clock-3.409 {ISO week-based calendar 1987-W53-5} {
+ clock format 567993600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1987-W53-5
+} {Fri Friday 87 1987 5 00 53 5 00}
+test clock-3.410 {ISO week-based calendar 1987-W53-6} {
+ clock format 568080000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1987-W53-6
+} {Sat Saturday 87 1987 6 00 53 6 00}
+test clock-3.411 {ISO week-based calendar 1987-W53-7} {
+ clock format 568166400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1987-W53-7
+} {Sun Sunday 87 1987 7 01 53 0 00}
+test clock-3.412 {ISO week-based calendar 1988-W01-1} {
+ clock format 568252800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W01-1
+} {Mon Monday 88 1988 1 01 01 1 01}
+test clock-3.413 {ISO week-based calendar 1988-W01-6} {
+ clock format 568684800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W01-6
+} {Sat Saturday 88 1988 6 01 01 6 01}
+test clock-3.414 {ISO week-based calendar 1988-W01-7} {
+ clock format 568771200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W01-7
+} {Sun Sunday 88 1988 7 02 01 0 01}
+test clock-3.415 {ISO week-based calendar 1988-W02-1} {
+ clock format 568857600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W02-1
+} {Mon Monday 88 1988 1 02 02 1 02}
+test clock-3.416 {ISO week-based calendar 1988-W52-1} {
+ clock format 599097600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W52-1
+} {Mon Monday 88 1988 1 52 52 1 52}
+test clock-3.417 {ISO week-based calendar 1988-W52-6} {
+ clock format 599529600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W52-6
+} {Sat Saturday 88 1988 6 52 52 6 52}
+test clock-3.418 {ISO week-based calendar 1988-W52-7} {
+ clock format 599616000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W52-7
+} {Sun Sunday 88 1988 7 01 52 0 00}
+test clock-3.419 {ISO week-based calendar 1989-W01-1} {
+ clock format 599702400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1989-W01-1
+} {Mon Monday 89 1989 1 01 01 1 01}
+test clock-3.420 {ISO week-based calendar 1989-W01-6} {
+ clock format 600134400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1989-W01-6
+} {Sat Saturday 89 1989 6 01 01 6 01}
+test clock-3.421 {ISO week-based calendar 1989-W01-7} {
+ clock format 600220800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1989-W01-7
+} {Sun Sunday 89 1989 7 02 01 0 01}
+test clock-3.422 {ISO week-based calendar 1989-W02-1} {
+ clock format 600307200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1989-W02-1
+} {Mon Monday 89 1989 1 02 02 1 02}
+test clock-3.423 {ISO week-based calendar 1991-W52-1} {
+ clock format 693446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1991-W52-1
+} {Mon Monday 91 1991 1 51 52 1 51}
+test clock-3.424 {ISO week-based calendar 1991-W52-6} {
+ clock format 693878400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1991-W52-6
+} {Sat Saturday 91 1991 6 51 52 6 51}
+test clock-3.425 {ISO week-based calendar 1991-W52-7} {
+ clock format 693964800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1991-W52-7
+} {Sun Sunday 91 1991 7 52 52 0 51}
+test clock-3.426 {ISO week-based calendar 1992-W01-1} {
+ clock format 694051200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W01-1
+} {Mon Monday 92 1992 1 52 01 1 52}
+test clock-3.427 {ISO week-based calendar 1992-W01-3} {
+ clock format 694224000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W01-3
+} {Wed Wednesday 92 1992 3 00 01 3 00}
+test clock-3.428 {ISO week-based calendar 1992-W01-6} {
+ clock format 694483200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W01-6
+} {Sat Saturday 92 1992 6 00 01 6 00}
+test clock-3.429 {ISO week-based calendar 1992-W01-7} {
+ clock format 694569600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W01-7
+} {Sun Sunday 92 1992 7 01 01 0 00}
+test clock-3.430 {ISO week-based calendar 1992-W02-1} {
+ clock format 694656000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W02-1
+} {Mon Monday 92 1992 1 01 02 1 01}
+test clock-3.431 {ISO week-based calendar 1992-W53-1} {
+ clock format 725500800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W53-1
+} {Mon Monday 92 1992 1 52 53 1 52}
+test clock-3.432 {ISO week-based calendar 1992-W53-5} {
+ clock format 725846400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W53-5
+} {Fri Friday 92 1992 5 00 53 5 00}
+test clock-3.433 {ISO week-based calendar 1992-W53-6} {
+ clock format 725932800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W53-6
+} {Sat Saturday 92 1992 6 00 53 6 00}
+test clock-3.434 {ISO week-based calendar 1992-W53-7} {
+ clock format 726019200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W53-7
+} {Sun Sunday 92 1992 7 01 53 0 00}
+test clock-3.435 {ISO week-based calendar 1993-W01-1} {
+ clock format 726105600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1993-W01-1
+} {Mon Monday 93 1993 1 01 01 1 01}
+test clock-3.436 {ISO week-based calendar 1993-W01-6} {
+ clock format 726537600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1993-W01-6
+} {Sat Saturday 93 1993 6 01 01 6 01}
+test clock-3.437 {ISO week-based calendar 1993-W01-7} {
+ clock format 726624000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1993-W01-7
+} {Sun Sunday 93 1993 7 02 01 0 01}
+test clock-3.438 {ISO week-based calendar 1993-W02-1} {
+ clock format 726710400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1993-W02-1
+} {Mon Monday 93 1993 1 02 02 1 02}
+test clock-3.439 {ISO week-based calendar 1995-W52-1} {
+ clock format 819849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1995-W52-1
+} {Mon Monday 95 1995 1 52 52 1 52}
+test clock-3.440 {ISO week-based calendar 1995-W52-6} {
+ clock format 820281600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1995-W52-6
+} {Sat Saturday 95 1995 6 52 52 6 52}
+test clock-3.441 {ISO week-based calendar 1995-W52-7} {
+ clock format 820368000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1995-W52-7
+} {Sun Sunday 95 1995 7 53 52 0 52}
+test clock-3.442 {ISO week-based calendar 1996-W01-1} {
+ clock format 820454400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W01-1
+} {Mon Monday 96 1996 1 00 01 1 01}
+test clock-3.443 {ISO week-based calendar 1996-W01-6} {
+ clock format 820886400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W01-6
+} {Sat Saturday 96 1996 6 00 01 6 01}
+test clock-3.444 {ISO week-based calendar 1996-W01-7} {
+ clock format 820972800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W01-7
+} {Sun Sunday 96 1996 7 01 01 0 01}
+test clock-3.445 {ISO week-based calendar 1996-W02-1} {
+ clock format 821059200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W02-1
+} {Mon Monday 96 1996 1 01 02 1 02}
+test clock-3.446 {ISO week-based calendar 1996-W52-1} {
+ clock format 851299200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W52-1
+} {Mon Monday 96 1996 1 51 52 1 52}
+test clock-3.447 {ISO week-based calendar 1996-W52-6} {
+ clock format 851731200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W52-6
+} {Sat Saturday 96 1996 6 51 52 6 52}
+test clock-3.448 {ISO week-based calendar 1996-W52-7} {
+ clock format 851817600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W52-7
+} {Sun Sunday 96 1996 7 52 52 0 52}
+test clock-3.449 {ISO week-based calendar 1997-W01-1} {
+ clock format 851904000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1997-W01-1
+} {Mon Monday 97 1997 1 52 01 1 53}
+test clock-3.450 {ISO week-based calendar 1997-W01-3} {
+ clock format 852076800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1997-W01-3
+} {Wed Wednesday 97 1997 3 00 01 3 00}
+test clock-3.451 {ISO week-based calendar 1997-W01-6} {
+ clock format 852336000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1997-W01-6
+} {Sat Saturday 97 1997 6 00 01 6 00}
+test clock-3.452 {ISO week-based calendar 1997-W01-7} {
+ clock format 852422400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1997-W01-7
+} {Sun Sunday 97 1997 7 01 01 0 00}
+test clock-3.453 {ISO week-based calendar 1997-W02-1} {
+ clock format 852508800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1997-W02-1
+} {Mon Monday 97 1997 1 01 02 1 01}
+test clock-3.454 {ISO week-based calendar 1999-W52-1} {
+ clock format 946252800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1999-W52-1
+} {Mon Monday 99 1999 1 52 52 1 52}
+test clock-3.455 {ISO week-based calendar 1999-W52-6} {
+ clock format 946684800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1999-W52-6
+} {Sat Saturday 99 1999 6 00 52 6 00}
+test clock-3.456 {ISO week-based calendar 1999-W52-7} {
+ clock format 946771200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1999-W52-7
+} {Sun Sunday 99 1999 7 01 52 0 00}
+test clock-3.457 {ISO week-based calendar 2000-W01-1} {
+ clock format 946857600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W01-1
+} {Mon Monday 00 2000 1 01 01 1 01}
+test clock-3.458 {ISO week-based calendar 2000-W01-6} {
+ clock format 947289600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W01-6
+} {Sat Saturday 00 2000 6 01 01 6 01}
+test clock-3.459 {ISO week-based calendar 2000-W01-7} {
+ clock format 947376000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W01-7
+} {Sun Sunday 00 2000 7 02 01 0 01}
+test clock-3.460 {ISO week-based calendar 2000-W02-1} {
+ clock format 947462400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W02-1
+} {Mon Monday 00 2000 1 02 02 1 02}
+test clock-3.461 {ISO week-based calendar 2000-W52-1} {
+ clock format 977702400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W52-1
+} {Mon Monday 00 2000 1 52 52 1 52}
+test clock-3.462 {ISO week-based calendar 2000-W52-6} {
+ clock format 978134400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W52-6
+} {Sat Saturday 00 2000 6 52 52 6 52}
+test clock-3.463 {ISO week-based calendar 2000-W52-7} {
+ clock format 978220800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W52-7
+} {Sun Sunday 00 2000 7 53 52 0 52}
+test clock-3.464 {ISO week-based calendar 2001-W01-1} {
+ clock format 978307200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W01-1
+} {Mon Monday 01 2001 1 00 01 1 01}
+test clock-3.465 {ISO week-based calendar 2001-W01-6} {
+ clock format 978739200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W01-6
+} {Sat Saturday 01 2001 6 00 01 6 01}
+test clock-3.466 {ISO week-based calendar 2001-W01-7} {
+ clock format 978825600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W01-7
+} {Sun Sunday 01 2001 7 01 01 0 01}
+test clock-3.467 {ISO week-based calendar 2001-W02-1} {
+ clock format 978912000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W02-1
+} {Mon Monday 01 2001 1 01 02 1 02}
+test clock-3.468 {ISO week-based calendar 2001-W52-1} {
+ clock format 1009152000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W52-1
+} {Mon Monday 01 2001 1 51 52 1 52}
+test clock-3.469 {ISO week-based calendar 2001-W52-6} {
+ clock format 1009584000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W52-6
+} {Sat Saturday 01 2001 6 51 52 6 52}
+test clock-3.470 {ISO week-based calendar 2001-W52-7} {
+ clock format 1009670400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W52-7
+} {Sun Sunday 01 2001 7 52 52 0 52}
+test clock-3.471 {ISO week-based calendar 2002-W01-1} {
+ clock format 1009756800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W01-1
+} {Mon Monday 02 2002 1 52 01 1 53}
+test clock-3.472 {ISO week-based calendar 2002-W01-2} {
+ clock format 1009843200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W01-2
+} {Tue Tuesday 02 2002 2 00 01 2 00}
+test clock-3.473 {ISO week-based calendar 2002-W01-6} {
+ clock format 1010188800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W01-6
+} {Sat Saturday 02 2002 6 00 01 6 00}
+test clock-3.474 {ISO week-based calendar 2002-W01-7} {
+ clock format 1010275200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W01-7
+} {Sun Sunday 02 2002 7 01 01 0 00}
+test clock-3.475 {ISO week-based calendar 2002-W02-1} {
+ clock format 1010361600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W02-1
+} {Mon Monday 02 2002 1 01 02 1 01}
+test clock-3.476 {ISO week-based calendar 2002-W52-1} {
+ clock format 1040601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W52-1
+} {Mon Monday 02 2002 1 51 52 1 51}
+test clock-3.477 {ISO week-based calendar 2002-W52-6} {
+ clock format 1041033600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W52-6
+} {Sat Saturday 02 2002 6 51 52 6 51}
+test clock-3.478 {ISO week-based calendar 2002-W52-7} {
+ clock format 1041120000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W52-7
+} {Sun Sunday 02 2002 7 52 52 0 51}
+test clock-3.479 {ISO week-based calendar 2003-W01-1} {
+ clock format 1041206400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W01-1
+} {Mon Monday 03 2003 1 52 01 1 52}
+test clock-3.480 {ISO week-based calendar 2003-W01-3} {
+ clock format 1041379200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W01-3
+} {Wed Wednesday 03 2003 3 00 01 3 00}
+test clock-3.481 {ISO week-based calendar 2003-W01-6} {
+ clock format 1041638400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W01-6
+} {Sat Saturday 03 2003 6 00 01 6 00}
+test clock-3.482 {ISO week-based calendar 2003-W01-7} {
+ clock format 1041724800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W01-7
+} {Sun Sunday 03 2003 7 01 01 0 00}
+test clock-3.483 {ISO week-based calendar 2003-W02-1} {
+ clock format 1041811200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W02-1
+} {Mon Monday 03 2003 1 01 02 1 01}
+test clock-3.484 {ISO week-based calendar 2003-W52-1} {
+ clock format 1072051200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W52-1
+} {Mon Monday 03 2003 1 51 52 1 51}
+test clock-3.485 {ISO week-based calendar 2003-W52-6} {
+ clock format 1072483200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W52-6
+} {Sat Saturday 03 2003 6 51 52 6 51}
+test clock-3.486 {ISO week-based calendar 2003-W52-7} {
+ clock format 1072569600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W52-7
+} {Sun Sunday 03 2003 7 52 52 0 51}
+test clock-3.487 {ISO week-based calendar 2004-W01-1} {
+ clock format 1072656000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W01-1
+} {Mon Monday 04 2004 1 52 01 1 52}
+test clock-3.488 {ISO week-based calendar 2004-W01-4} {
+ clock format 1072915200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W01-4
+} {Thu Thursday 04 2004 4 00 01 4 00}
+test clock-3.489 {ISO week-based calendar 2004-W01-6} {
+ clock format 1073088000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W01-6
+} {Sat Saturday 04 2004 6 00 01 6 00}
+test clock-3.490 {ISO week-based calendar 2004-W01-7} {
+ clock format 1073174400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W01-7
+} {Sun Sunday 04 2004 7 01 01 0 00}
+test clock-3.491 {ISO week-based calendar 2004-W02-1} {
+ clock format 1073260800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W02-1
+} {Mon Monday 04 2004 1 01 02 1 01}
+test clock-3.492 {ISO week-based calendar 2004-W53-1} {
+ clock format 1104105600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W53-1
+} {Mon Monday 04 2004 1 52 53 1 52}
+test clock-3.493 {ISO week-based calendar 2004-W53-6} {
+ clock format 1104537600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W53-6
+} {Sat Saturday 04 2004 6 00 53 6 00}
+test clock-3.494 {ISO week-based calendar 2004-W53-7} {
+ clock format 1104624000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W53-7
+} {Sun Sunday 04 2004 7 01 53 0 00}
+test clock-3.495 {ISO week-based calendar 2005-W01-1} {
+ clock format 1104710400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W01-1
+} {Mon Monday 05 2005 1 01 01 1 01}
+test clock-3.496 {ISO week-based calendar 2005-W01-6} {
+ clock format 1105142400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W01-6
+} {Sat Saturday 05 2005 6 01 01 6 01}
+test clock-3.497 {ISO week-based calendar 2005-W01-7} {
+ clock format 1105228800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W01-7
+} {Sun Sunday 05 2005 7 02 01 0 01}
+test clock-3.498 {ISO week-based calendar 2005-W02-1} {
+ clock format 1105315200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W02-1
+} {Mon Monday 05 2005 1 02 02 1 02}
+test clock-3.499 {ISO week-based calendar 2005-W52-1} {
+ clock format 1135555200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W52-1
+} {Mon Monday 05 2005 1 52 52 1 52}
+test clock-3.500 {ISO week-based calendar 2005-W52-6} {
+ clock format 1135987200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W52-6
+} {Sat Saturday 05 2005 6 52 52 6 52}
+test clock-3.501 {ISO week-based calendar 2005-W52-7} {
+ clock format 1136073600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W52-7
+} {Sun Sunday 05 2005 7 01 52 0 00}
+test clock-3.502 {ISO week-based calendar 2006-W01-1} {
+ clock format 1136160000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W01-1
+} {Mon Monday 06 2006 1 01 01 1 01}
+test clock-3.503 {ISO week-based calendar 2006-W01-6} {
+ clock format 1136592000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W01-6
+} {Sat Saturday 06 2006 6 01 01 6 01}
+test clock-3.504 {ISO week-based calendar 2006-W01-7} {
+ clock format 1136678400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W01-7
+} {Sun Sunday 06 2006 7 02 01 0 01}
+test clock-3.505 {ISO week-based calendar 2006-W02-1} {
+ clock format 1136764800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W02-1
+} {Mon Monday 06 2006 1 02 02 1 02}
+test clock-3.506 {ISO week-based calendar 2006-W52-1} {
+ clock format 1167004800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W52-1
+} {Mon Monday 06 2006 1 52 52 1 52}
+test clock-3.507 {ISO week-based calendar 2006-W52-6} {
+ clock format 1167436800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W52-6
+} {Sat Saturday 06 2006 6 52 52 6 52}
+test clock-3.508 {ISO week-based calendar 2006-W52-7} {
+ clock format 1167523200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W52-7
+} {Sun Sunday 06 2006 7 53 52 0 52}
+test clock-3.509 {ISO week-based calendar 2007-W01-1} {
+ clock format 1167609600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W01-1
+} {Mon Monday 07 2007 1 00 01 1 01}
+test clock-3.510 {ISO week-based calendar 2007-W01-6} {
+ clock format 1168041600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W01-6
+} {Sat Saturday 07 2007 6 00 01 6 01}
+test clock-3.511 {ISO week-based calendar 2007-W01-7} {
+ clock format 1168128000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W01-7
+} {Sun Sunday 07 2007 7 01 01 0 01}
+test clock-3.512 {ISO week-based calendar 2007-W02-1} {
+ clock format 1168214400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W02-1
+} {Mon Monday 07 2007 1 01 02 1 02}
+test clock-3.513 {ISO week-based calendar 2007-W52-1} {
+ clock format 1198454400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W52-1
+} {Mon Monday 07 2007 1 51 52 1 52}
+test clock-3.514 {ISO week-based calendar 2007-W52-6} {
+ clock format 1198886400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W52-6
+} {Sat Saturday 07 2007 6 51 52 6 52}
+test clock-3.515 {ISO week-based calendar 2007-W52-7} {
+ clock format 1198972800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W52-7
+} {Sun Sunday 07 2007 7 52 52 0 52}
+test clock-3.516 {ISO week-based calendar 2008-W01-1} {
+ clock format 1199059200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W01-1
+} {Mon Monday 08 2008 1 52 01 1 53}
+test clock-3.517 {ISO week-based calendar 2008-W01-2} {
+ clock format 1199145600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W01-2
+} {Tue Tuesday 08 2008 2 00 01 2 00}
+test clock-3.518 {ISO week-based calendar 2008-W01-6} {
+ clock format 1199491200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W01-6
+} {Sat Saturday 08 2008 6 00 01 6 00}
+test clock-3.519 {ISO week-based calendar 2008-W01-7} {
+ clock format 1199577600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W01-7
+} {Sun Sunday 08 2008 7 01 01 0 00}
+test clock-3.520 {ISO week-based calendar 2008-W02-1} {
+ clock format 1199664000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W02-1
+} {Mon Monday 08 2008 1 01 02 1 01}
+test clock-3.521 {ISO week-based calendar 2008-W52-1} {
+ clock format 1229904000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W52-1
+} {Mon Monday 08 2008 1 51 52 1 51}
+test clock-3.522 {ISO week-based calendar 2008-W52-6} {
+ clock format 1230336000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W52-6
+} {Sat Saturday 08 2008 6 51 52 6 51}
+test clock-3.523 {ISO week-based calendar 2008-W52-7} {
+ clock format 1230422400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W52-7
+} {Sun Sunday 08 2008 7 52 52 0 51}
+test clock-3.524 {ISO week-based calendar 2009-W01-1} {
+ clock format 1230508800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W01-1
+} {Mon Monday 09 2009 1 52 01 1 52}
+test clock-3.525 {ISO week-based calendar 2009-W01-4} {
+ clock format 1230768000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W01-4
+} {Thu Thursday 09 2009 4 00 01 4 00}
+test clock-3.526 {ISO week-based calendar 2009-W01-6} {
+ clock format 1230940800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W01-6
+} {Sat Saturday 09 2009 6 00 01 6 00}
+test clock-3.527 {ISO week-based calendar 2009-W01-7} {
+ clock format 1231027200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W01-7
+} {Sun Sunday 09 2009 7 01 01 0 00}
+test clock-3.528 {ISO week-based calendar 2009-W02-1} {
+ clock format 1231113600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W02-1
+} {Mon Monday 09 2009 1 01 02 1 01}
+test clock-3.529 {ISO week-based calendar 2009-W53-1} {
+ clock format 1261958400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W53-1
+} {Mon Monday 09 2009 1 52 53 1 52}
+test clock-3.530 {ISO week-based calendar 2009-W53-5} {
+ clock format 1262304000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W53-5
+} {Fri Friday 09 2009 5 00 53 5 00}
+test clock-3.531 {ISO week-based calendar 2009-W53-6} {
+ clock format 1262390400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W53-6
+} {Sat Saturday 09 2009 6 00 53 6 00}
+test clock-3.532 {ISO week-based calendar 2009-W53-7} {
+ clock format 1262476800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W53-7
+} {Sun Sunday 09 2009 7 01 53 0 00}
+test clock-3.533 {ISO week-based calendar 2010-W01-1} {
+ clock format 1262563200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W01-1
+} {Mon Monday 10 2010 1 01 01 1 01}
+test clock-3.534 {ISO week-based calendar 2010-W01-6} {
+ clock format 1262995200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W01-6
+} {Sat Saturday 10 2010 6 01 01 6 01}
+test clock-3.535 {ISO week-based calendar 2010-W01-7} {
+ clock format 1263081600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W01-7
+} {Sun Sunday 10 2010 7 02 01 0 01}
+test clock-3.536 {ISO week-based calendar 2010-W02-1} {
+ clock format 1263168000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W02-1
+} {Mon Monday 10 2010 1 02 02 1 02}
+test clock-3.537 {ISO week-based calendar 2010-W52-1} {
+ clock format 1293408000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W52-1
+} {Mon Monday 10 2010 1 52 52 1 52}
+test clock-3.538 {ISO week-based calendar 2010-W52-6} {
+ clock format 1293840000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W52-6
+} {Sat Saturday 10 2010 6 00 52 6 00}
+test clock-3.539 {ISO week-based calendar 2010-W52-7} {
+ clock format 1293926400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W52-7
+} {Sun Sunday 10 2010 7 01 52 0 00}
+test clock-3.540 {ISO week-based calendar 2011-W01-1} {
+ clock format 1294012800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W01-1
+} {Mon Monday 11 2011 1 01 01 1 01}
+test clock-3.541 {ISO week-based calendar 2011-W01-6} {
+ clock format 1294444800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W01-6
+} {Sat Saturday 11 2011 6 01 01 6 01}
+test clock-3.542 {ISO week-based calendar 2011-W01-7} {
+ clock format 1294531200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W01-7
+} {Sun Sunday 11 2011 7 02 01 0 01}
+test clock-3.543 {ISO week-based calendar 2011-W02-1} {
+ clock format 1294617600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W02-1
+} {Mon Monday 11 2011 1 02 02 1 02}
+test clock-3.544 {ISO week-based calendar 2011-W52-1} {
+ clock format 1324857600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W52-1
+} {Mon Monday 11 2011 1 52 52 1 52}
+test clock-3.545 {ISO week-based calendar 2011-W52-6} {
+ clock format 1325289600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W52-6
+} {Sat Saturday 11 2011 6 52 52 6 52}
+test clock-3.546 {ISO week-based calendar 2011-W52-7} {
+ clock format 1325376000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W52-7
+} {Sun Sunday 11 2011 7 01 52 0 00}
+test clock-3.547 {ISO week-based calendar 2012-W01-1} {
+ clock format 1325462400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W01-1
+} {Mon Monday 12 2012 1 01 01 1 01}
+test clock-3.548 {ISO week-based calendar 2012-W01-6} {
+ clock format 1325894400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W01-6
+} {Sat Saturday 12 2012 6 01 01 6 01}
+test clock-3.549 {ISO week-based calendar 2012-W01-7} {
+ clock format 1325980800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W01-7
+} {Sun Sunday 12 2012 7 02 01 0 01}
+test clock-3.550 {ISO week-based calendar 2012-W02-1} {
+ clock format 1326067200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W02-1
+} {Mon Monday 12 2012 1 02 02 1 02}
+test clock-3.551 {ISO week-based calendar 2012-W52-1} {
+ clock format 1356307200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W52-1
+} {Mon Monday 12 2012 1 52 52 1 52}
+test clock-3.552 {ISO week-based calendar 2012-W52-6} {
+ clock format 1356739200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W52-6
+} {Sat Saturday 12 2012 6 52 52 6 52}
+test clock-3.553 {ISO week-based calendar 2012-W52-7} {
+ clock format 1356825600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W52-7
+} {Sun Sunday 12 2012 7 53 52 0 52}
+test clock-3.554 {ISO week-based calendar 2013-W01-1} {
+ clock format 1356912000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2013-W01-1
+} {Mon Monday 13 2013 1 53 01 1 53}
+test clock-3.555 {ISO week-based calendar 2013-W01-2} {
+ clock format 1356998400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2013-W01-2
+} {Tue Tuesday 13 2013 2 00 01 2 00}
+test clock-3.556 {ISO week-based calendar 2013-W01-6} {
+ clock format 1357344000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2013-W01-6
+} {Sat Saturday 13 2013 6 00 01 6 00}
+test clock-3.557 {ISO week-based calendar 2013-W01-7} {
+ clock format 1357430400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2013-W01-7
+} {Sun Sunday 13 2013 7 01 01 0 00}
+test clock-3.558 {ISO week-based calendar 2013-W02-1} {
+ clock format 1357516800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2013-W02-1
+} {Mon Monday 13 2013 1 01 02 1 01}
+test clock-3.559 {ISO week-based calendar 2015-W53-1} {
+ clock format 1451260800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2015-W53-1
+} {Mon Monday 15 2015 1 52 53 1 52}
+test clock-3.560 {ISO week-based calendar 2015-W53-5} {
+ clock format 1451606400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2015-W53-5
+} {Fri Friday 15 2015 5 00 53 5 00}
+test clock-3.561 {ISO week-based calendar 2015-W53-6} {
+ clock format 1451692800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2015-W53-6
+} {Sat Saturday 15 2015 6 00 53 6 00}
+test clock-3.562 {ISO week-based calendar 2015-W53-7} {
+ clock format 1451779200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2015-W53-7
+} {Sun Sunday 15 2015 7 01 53 0 00}
+test clock-3.563 {ISO week-based calendar 2016-W01-1} {
+ clock format 1451865600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W01-1
+} {Mon Monday 16 2016 1 01 01 1 01}
+test clock-3.564 {ISO week-based calendar 2016-W01-6} {
+ clock format 1452297600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W01-6
+} {Sat Saturday 16 2016 6 01 01 6 01}
+test clock-3.565 {ISO week-based calendar 2016-W01-7} {
+ clock format 1452384000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W01-7
+} {Sun Sunday 16 2016 7 02 01 0 01}
+test clock-3.566 {ISO week-based calendar 2016-W02-1} {
+ clock format 1452470400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W02-1
+} {Mon Monday 16 2016 1 02 02 1 02}
+test clock-3.567 {ISO week-based calendar 2016-W52-1} {
+ clock format 1482710400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W52-1
+} {Mon Monday 16 2016 1 52 52 1 52}
+test clock-3.568 {ISO week-based calendar 2016-W52-6} {
+ clock format 1483142400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W52-6
+} {Sat Saturday 16 2016 6 52 52 6 52}
+test clock-3.569 {ISO week-based calendar 2016-W52-7} {
+ clock format 1483228800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W52-7
+} {Sun Sunday 16 2016 7 01 52 0 00}
+test clock-3.570 {ISO week-based calendar 2017-W01-1} {
+ clock format 1483315200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2017-W01-1
+} {Mon Monday 17 2017 1 01 01 1 01}
+test clock-3.571 {ISO week-based calendar 2017-W01-6} {
+ clock format 1483747200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2017-W01-6
+} {Sat Saturday 17 2017 6 01 01 6 01}
+test clock-3.572 {ISO week-based calendar 2017-W01-7} {
+ clock format 1483833600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2017-W01-7
+} {Sun Sunday 17 2017 7 02 01 0 01}
+test clock-3.573 {ISO week-based calendar 2017-W02-1} {
+ clock format 1483920000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2017-W02-1
+} {Mon Monday 17 2017 1 02 02 1 02}
+test clock-3.574 {ISO week-based calendar 2019-W52-1} {
+ clock format 1577059200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2019-W52-1
+} {Mon Monday 19 2019 1 51 52 1 51}
+test clock-3.575 {ISO week-based calendar 2019-W52-6} {
+ clock format 1577491200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2019-W52-6
+} {Sat Saturday 19 2019 6 51 52 6 51}
+test clock-3.576 {ISO week-based calendar 2019-W52-7} {
+ clock format 1577577600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2019-W52-7
+} {Sun Sunday 19 2019 7 52 52 0 51}
+test clock-3.577 {ISO week-based calendar 2020-W01-1} {
+ clock format 1577664000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W01-1
+} {Mon Monday 20 2020 1 52 01 1 52}
+test clock-3.578 {ISO week-based calendar 2020-W01-3} {
+ clock format 1577836800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W01-3
+} {Wed Wednesday 20 2020 3 00 01 3 00}
+test clock-3.579 {ISO week-based calendar 2020-W01-6} {
+ clock format 1578096000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W01-6
+} {Sat Saturday 20 2020 6 00 01 6 00}
+test clock-3.580 {ISO week-based calendar 2020-W01-7} {
+ clock format 1578182400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W01-7
+} {Sun Sunday 20 2020 7 01 01 0 00}
+test clock-3.581 {ISO week-based calendar 2020-W02-1} {
+ clock format 1578268800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W02-1
+} {Mon Monday 20 2020 1 01 02 1 01}
+test clock-3.582 {ISO week-based calendar 2020-W53-1} {
+ clock format 1609113600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W53-1
+} {Mon Monday 20 2020 1 52 53 1 52}
+test clock-3.583 {ISO week-based calendar 2020-W53-5} {
+ clock format 1609459200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W53-5
+} {Fri Friday 20 2020 5 00 53 5 00}
+test clock-3.584 {ISO week-based calendar 2020-W53-6} {
+ clock format 1609545600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W53-6
+} {Sat Saturday 20 2020 6 00 53 6 00}
+test clock-3.585 {ISO week-based calendar 2020-W53-7} {
+ clock format 1609632000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W53-7
+} {Sun Sunday 20 2020 7 01 53 0 00}
+test clock-3.586 {ISO week-based calendar 2021-W01-1} {
+ clock format 1609718400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2021-W01-1
+} {Mon Monday 21 2021 1 01 01 1 01}
+test clock-3.587 {ISO week-based calendar 2021-W01-6} {
+ clock format 1610150400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2021-W01-6
+} {Sat Saturday 21 2021 6 01 01 6 01}
+test clock-3.588 {ISO week-based calendar 2021-W01-7} {
+ clock format 1610236800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2021-W01-7
+} {Sun Sunday 21 2021 7 02 01 0 01}
+test clock-3.589 {ISO week-based calendar 2021-W02-1} {
+ clock format 1610323200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2021-W02-1
+} {Mon Monday 21 2021 1 02 02 1 02}
+test clock-3.590 {ISO week-based calendar 2023-W52-1} {
+ clock format 1703462400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2023-W52-1
+} {Mon Monday 23 2023 1 52 52 1 52}
+test clock-3.591 {ISO week-based calendar 2023-W52-6} {
+ clock format 1703894400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2023-W52-6
+} {Sat Saturday 23 2023 6 52 52 6 52}
+test clock-3.592 {ISO week-based calendar 2023-W52-7} {
+ clock format 1703980800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2023-W52-7
+} {Sun Sunday 23 2023 7 53 52 0 52}
+test clock-3.593 {ISO week-based calendar 2024-W01-1} {
+ clock format 1704067200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W01-1
+} {Mon Monday 24 2024 1 00 01 1 01}
+test clock-3.594 {ISO week-based calendar 2024-W01-6} {
+ clock format 1704499200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W01-6
+} {Sat Saturday 24 2024 6 00 01 6 01}
+test clock-3.595 {ISO week-based calendar 2024-W01-7} {
+ clock format 1704585600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W01-7
+} {Sun Sunday 24 2024 7 01 01 0 01}
+test clock-3.596 {ISO week-based calendar 2024-W02-1} {
+ clock format 1704672000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W02-1
+} {Mon Monday 24 2024 1 01 02 1 02}
+test clock-3.597 {ISO week-based calendar 2024-W52-1} {
+ clock format 1734912000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W52-1
+} {Mon Monday 24 2024 1 51 52 1 52}
+test clock-3.598 {ISO week-based calendar 2024-W52-6} {
+ clock format 1735344000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W52-6
+} {Sat Saturday 24 2024 6 51 52 6 52}
+test clock-3.599 {ISO week-based calendar 2024-W52-7} {
+ clock format 1735430400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W52-7
+} {Sun Sunday 24 2024 7 52 52 0 52}
+test clock-3.600 {ISO week-based calendar 2025-W01-1} {
+ clock format 1735516800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2025-W01-1
+} {Mon Monday 25 2025 1 52 01 1 53}
+test clock-3.601 {ISO week-based calendar 2025-W01-3} {
+ clock format 1735689600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2025-W01-3
+} {Wed Wednesday 25 2025 3 00 01 3 00}
+test clock-3.602 {ISO week-based calendar 2025-W01-6} {
+ clock format 1735948800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2025-W01-6
+} {Sat Saturday 25 2025 6 00 01 6 00}
+test clock-3.603 {ISO week-based calendar 2025-W01-7} {
+ clock format 1736035200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2025-W01-7
+} {Sun Sunday 25 2025 7 01 01 0 00}
+test clock-3.604 {ISO week-based calendar 2025-W02-1} {
+ clock format 1736121600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2025-W02-1
+} {Mon Monday 25 2025 1 01 02 1 01}
+test clock-3.605 {ISO week-based calendar 2036-W52-1} {
+ clock format 2113516800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2036-W52-1
+} {Mon Monday 36 2036 1 51 52 1 51}
+test clock-3.606 {ISO week-based calendar 2036-W52-6} {
+ clock format 2113948800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2036-W52-6
+} {Sat Saturday 36 2036 6 51 52 6 51}
+test clock-3.607 {ISO week-based calendar 2036-W52-7} {
+ clock format 2114035200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2036-W52-7
+} {Sun Sunday 36 2036 7 52 52 0 51}
+test clock-3.608 {ISO week-based calendar 2037-W01-1} {
+ clock format 2114121600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W01-1
+} {Mon Monday 37 2037 1 52 01 1 52}
+test clock-3.609 {ISO week-based calendar 2037-W01-4} {
+ clock format 2114380800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W01-4
+} {Thu Thursday 37 2037 4 00 01 4 00}
+test clock-3.610 {ISO week-based calendar 2037-W01-6} {
+ clock format 2114553600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W01-6
+} {Sat Saturday 37 2037 6 00 01 6 00}
+test clock-3.611 {ISO week-based calendar 2037-W01-7} {
+ clock format 2114640000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W01-7
+} {Sun Sunday 37 2037 7 01 01 0 00}
+test clock-3.612 {ISO week-based calendar 2037-W02-1} {
+ clock format 2114726400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W02-1
+} {Mon Monday 37 2037 1 01 02 1 01}
+test clock-3.613 {ISO week-based calendar 2037-W53-1} {
+ clock format 2145571200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W53-1
+} {Mon Monday 37 2037 1 52 53 1 52}
+test clock-3.614 {ISO week-based calendar 2037-W53-5} {
+ clock format 2145916800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W53-5
+} {Fri Friday 37 2037 5 00 53 5 00}
+test clock-3.615 {ISO week-based calendar 2037-W53-6} {
+ clock format 2146003200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W53-6
+} {Sat Saturday 37 2037 6 00 53 6 00}
+test clock-3.616 {ISO week-based calendar 2037-W53-7} {
+ clock format 2146089600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W53-7
+} {Sun Sunday 37 2037 7 01 53 0 00}
+test clock-3.617 {ISO week-based calendar 2038-W01-1} {
+ clock format 2146176000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W01-1
+} {Mon Monday 38 2038 1 01 01 1 01}
+test clock-3.618 {ISO week-based calendar 2038-W01-6} {
+ clock format 2146608000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W01-6
+} {Sat Saturday 38 2038 6 01 01 6 01}
+test clock-3.619 {ISO week-based calendar 2038-W01-7} {
+ clock format 2146694400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W01-7
+} {Sun Sunday 38 2038 7 02 01 0 01}
+test clock-3.620 {ISO week-based calendar 2038-W02-1} {
+ clock format 2146780800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W02-1
+} {Mon Monday 38 2038 1 02 02 1 02}
+test clock-3.621 {ISO week-based calendar 2038-W52-1} {
+ clock format 2177020800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W52-1
+} {Mon Monday 38 2038 1 52 52 1 52}
+test clock-3.622 {ISO week-based calendar 2038-W52-6} {
+ clock format 2177452800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W52-6
+} {Sat Saturday 38 2038 6 00 52 6 00}
+test clock-3.623 {ISO week-based calendar 2038-W52-7} {
+ clock format 2177539200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W52-7
+} {Sun Sunday 38 2038 7 01 52 0 00}
+test clock-3.624 {ISO week-based calendar 2039-W01-1} {
+ clock format 2177625600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W01-1
+} {Mon Monday 39 2039 1 01 01 1 01}
+test clock-3.625 {ISO week-based calendar 2039-W01-6} {
+ clock format 2178057600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W01-6
+} {Sat Saturday 39 2039 6 01 01 6 01}
+test clock-3.626 {ISO week-based calendar 2039-W01-7} {
+ clock format 2178144000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W01-7
+} {Sun Sunday 39 2039 7 02 01 0 01}
+test clock-3.627 {ISO week-based calendar 2039-W02-1} {
+ clock format 2178230400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W02-1
+} {Mon Monday 39 2039 1 02 02 1 02}
+test clock-3.628 {ISO week-based calendar 2039-W52-1} {
+ clock format 2208470400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W52-1
+} {Mon Monday 39 2039 1 52 52 1 52}
+test clock-3.629 {ISO week-based calendar 2039-W52-6} {
+ clock format 2208902400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W52-6
+} {Sat Saturday 39 2039 6 52 52 6 52}
+test clock-3.630 {ISO week-based calendar 2039-W52-7} {
+ clock format 2208988800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W52-7
+} {Sun Sunday 39 2039 7 01 52 0 00}
+test clock-3.631 {ISO week-based calendar 2040-W01-1} {
+ clock format 2209075200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W01-1
+} {Mon Monday 40 2040 1 01 01 1 01}
+test clock-3.632 {ISO week-based calendar 2040-W01-6} {
+ clock format 2209507200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W01-6
+} {Sat Saturday 40 2040 6 01 01 6 01}
+test clock-3.633 {ISO week-based calendar 2040-W01-7} {
+ clock format 2209593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W01-7
+} {Sun Sunday 40 2040 7 02 01 0 01}
+test clock-3.634 {ISO week-based calendar 2040-W02-1} {
+ clock format 2209680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W02-1
+} {Mon Monday 40 2040 1 02 02 1 02}
+test clock-3.635 {ISO week-based calendar 2040-W52-1} {
+ clock format 2239920000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W52-1
+} {Mon Monday 40 2040 1 52 52 1 52}
+test clock-3.636 {ISO week-based calendar 2040-W52-6} {
+ clock format 2240352000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W52-6
+} {Sat Saturday 40 2040 6 52 52 6 52}
+test clock-3.637 {ISO week-based calendar 2040-W52-7} {
+ clock format 2240438400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W52-7
+} {Sun Sunday 40 2040 7 53 52 0 52}
+test clock-3.638 {ISO week-based calendar 2041-W01-1} {
+ clock format 2240524800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W01-1
+} {Mon Monday 41 2041 1 53 01 1 53}
+test clock-3.639 {ISO week-based calendar 2041-W01-2} {
+ clock format 2240611200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W01-2
+} {Tue Tuesday 41 2041 2 00 01 2 00}
+test clock-3.640 {ISO week-based calendar 2041-W01-6} {
+ clock format 2240956800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W01-6
+} {Sat Saturday 41 2041 6 00 01 6 00}
+test clock-3.641 {ISO week-based calendar 2041-W01-7} {
+ clock format 2241043200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W01-7
+} {Sun Sunday 41 2041 7 01 01 0 00}
+test clock-3.642 {ISO week-based calendar 2041-W02-1} {
+ clock format 2241129600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W02-1
+} {Mon Monday 41 2041 1 01 02 1 01}
+test clock-3.643 {ISO week-based calendar 2041-W52-1} {
+ clock format 2271369600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W52-1
+} {Mon Monday 41 2041 1 51 52 1 51}
+test clock-3.644 {ISO week-based calendar 2041-W52-6} {
+ clock format 2271801600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W52-6
+} {Sat Saturday 41 2041 6 51 52 6 51}
+test clock-3.645 {ISO week-based calendar 2041-W52-7} {
+ clock format 2271888000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W52-7
+} {Sun Sunday 41 2041 7 52 52 0 51}
+test clock-3.646 {ISO week-based calendar 2042-W01-1} {
+ clock format 2271974400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W01-1
+} {Mon Monday 42 2042 1 52 01 1 52}
+test clock-3.647 {ISO week-based calendar 2042-W01-3} {
+ clock format 2272147200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W01-3
+} {Wed Wednesday 42 2042 3 00 01 3 00}
+test clock-3.648 {ISO week-based calendar 2042-W01-6} {
+ clock format 2272406400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W01-6
+} {Sat Saturday 42 2042 6 00 01 6 00}
+test clock-3.649 {ISO week-based calendar 2042-W01-7} {
+ clock format 2272492800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W01-7
+} {Sun Sunday 42 2042 7 01 01 0 00}
+test clock-3.650 {ISO week-based calendar 2042-W02-1} {
+ clock format 2272579200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W02-1
+} {Mon Monday 42 2042 1 01 02 1 01}
+test clock-3.651 {ISO week-based calendar 2042-W52-1} {
+ clock format 2302819200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W52-1
+} {Mon Monday 42 2042 1 51 52 1 51}
+test clock-3.652 {ISO week-based calendar 2042-W52-6} {
+ clock format 2303251200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W52-6
+} {Sat Saturday 42 2042 6 51 52 6 51}
+test clock-3.653 {ISO week-based calendar 2042-W52-7} {
+ clock format 2303337600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W52-7
+} {Sun Sunday 42 2042 7 52 52 0 51}
+test clock-3.654 {ISO week-based calendar 2043-W01-1} {
+ clock format 2303424000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W01-1
+} {Mon Monday 43 2043 1 52 01 1 52}
+test clock-3.655 {ISO week-based calendar 2043-W01-4} {
+ clock format 2303683200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W01-4
+} {Thu Thursday 43 2043 4 00 01 4 00}
+test clock-3.656 {ISO week-based calendar 2043-W01-6} {
+ clock format 2303856000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W01-6
+} {Sat Saturday 43 2043 6 00 01 6 00}
+test clock-3.657 {ISO week-based calendar 2043-W01-7} {
+ clock format 2303942400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W01-7
+} {Sun Sunday 43 2043 7 01 01 0 00}
+test clock-3.658 {ISO week-based calendar 2043-W02-1} {
+ clock format 2304028800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W02-1
+} {Mon Monday 43 2043 1 01 02 1 01}
+test clock-3.659 {ISO week-based calendar 2043-W53-1} {
+ clock format 2334873600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W53-1
+} {Mon Monday 43 2043 1 52 53 1 52}
+test clock-3.660 {ISO week-based calendar 2043-W53-5} {
+ clock format 2335219200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W53-5
+} {Fri Friday 43 2043 5 00 53 5 00}
+test clock-3.661 {ISO week-based calendar 2043-W53-6} {
+ clock format 2335305600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W53-6
+} {Sat Saturday 43 2043 6 00 53 6 00}
+test clock-3.662 {ISO week-based calendar 2043-W53-7} {
+ clock format 2335392000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W53-7
+} {Sun Sunday 43 2043 7 01 53 0 00}
+test clock-3.663 {ISO week-based calendar 2044-W01-1} {
+ clock format 2335478400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W01-1
+} {Mon Monday 44 2044 1 01 01 1 01}
+test clock-3.664 {ISO week-based calendar 2044-W01-6} {
+ clock format 2335910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W01-6
+} {Sat Saturday 44 2044 6 01 01 6 01}
+test clock-3.665 {ISO week-based calendar 2044-W01-7} {
+ clock format 2335996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W01-7
+} {Sun Sunday 44 2044 7 02 01 0 01}
+test clock-3.666 {ISO week-based calendar 2044-W02-1} {
+ clock format 2336083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W02-1
+} {Mon Monday 44 2044 1 02 02 1 02}
+test clock-3.667 {ISO week-based calendar 2044-W52-1} {
+ clock format 2366323200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W52-1
+} {Mon Monday 44 2044 1 52 52 1 52}
+test clock-3.668 {ISO week-based calendar 2044-W52-6} {
+ clock format 2366755200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W52-6
+} {Sat Saturday 44 2044 6 52 52 6 52}
+test clock-3.669 {ISO week-based calendar 2044-W52-7} {
+ clock format 2366841600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W52-7
+} {Sun Sunday 44 2044 7 01 52 0 00}
+test clock-3.670 {ISO week-based calendar 2045-W01-1} {
+ clock format 2366928000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W01-1
+} {Mon Monday 45 2045 1 01 01 1 01}
+test clock-3.671 {ISO week-based calendar 2045-W01-6} {
+ clock format 2367360000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W01-6
+} {Sat Saturday 45 2045 6 01 01 6 01}
+test clock-3.672 {ISO week-based calendar 2045-W01-7} {
+ clock format 2367446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W01-7
+} {Sun Sunday 45 2045 7 02 01 0 01}
+test clock-3.673 {ISO week-based calendar 2045-W02-1} {
+ clock format 2367532800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W02-1
+} {Mon Monday 45 2045 1 02 02 1 02}
+test clock-3.674 {ISO week-based calendar 2045-W52-1} {
+ clock format 2397772800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W52-1
+} {Mon Monday 45 2045 1 52 52 1 52}
+test clock-3.675 {ISO week-based calendar 2045-W52-6} {
+ clock format 2398204800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W52-6
+} {Sat Saturday 45 2045 6 52 52 6 52}
+test clock-3.676 {ISO week-based calendar 2045-W52-7} {
+ clock format 2398291200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W52-7
+} {Sun Sunday 45 2045 7 53 52 0 52}
+test clock-3.677 {ISO week-based calendar 2046-W01-1} {
+ clock format 2398377600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W01-1
+} {Mon Monday 46 2046 1 00 01 1 01}
+test clock-3.678 {ISO week-based calendar 2046-W01-6} {
+ clock format 2398809600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W01-6
+} {Sat Saturday 46 2046 6 00 01 6 01}
+test clock-3.679 {ISO week-based calendar 2046-W01-7} {
+ clock format 2398896000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W01-7
+} {Sun Sunday 46 2046 7 01 01 0 01}
+test clock-3.680 {ISO week-based calendar 2046-W02-1} {
+ clock format 2398982400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W02-1
+} {Mon Monday 46 2046 1 01 02 1 02}
+test clock-3.681 {ISO week-based calendar 2046-W52-1} {
+ clock format 2429222400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W52-1
+} {Mon Monday 46 2046 1 51 52 1 52}
+test clock-3.682 {ISO week-based calendar 2046-W52-6} {
+ clock format 2429654400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W52-6
+} {Sat Saturday 46 2046 6 51 52 6 52}
+test clock-3.683 {ISO week-based calendar 2046-W52-7} {
+ clock format 2429740800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W52-7
+} {Sun Sunday 46 2046 7 52 52 0 52}
+test clock-3.684 {ISO week-based calendar 2047-W01-1} {
+ clock format 2429827200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W01-1
+} {Mon Monday 47 2047 1 52 01 1 53}
+test clock-3.685 {ISO week-based calendar 2047-W01-2} {
+ clock format 2429913600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W01-2
+} {Tue Tuesday 47 2047 2 00 01 2 00}
+test clock-3.686 {ISO week-based calendar 2047-W01-6} {
+ clock format 2430259200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W01-6
+} {Sat Saturday 47 2047 6 00 01 6 00}
+test clock-3.687 {ISO week-based calendar 2047-W01-7} {
+ clock format 2430345600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W01-7
+} {Sun Sunday 47 2047 7 01 01 0 00}
+test clock-3.688 {ISO week-based calendar 2047-W02-1} {
+ clock format 2430432000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W02-1
+} {Mon Monday 47 2047 1 01 02 1 01}
+test clock-3.689 {ISO week-based calendar 2047-W52-1} {
+ clock format 2460672000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W52-1
+} {Mon Monday 47 2047 1 51 52 1 51}
+test clock-3.690 {ISO week-based calendar 2047-W52-6} {
+ clock format 2461104000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W52-6
+} {Sat Saturday 47 2047 6 51 52 6 51}
+test clock-3.691 {ISO week-based calendar 2047-W52-7} {
+ clock format 2461190400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W52-7
+} {Sun Sunday 47 2047 7 52 52 0 51}
+test clock-3.692 {ISO week-based calendar 2048-W01-1} {
+ clock format 2461276800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W01-1
+} {Mon Monday 48 2048 1 52 01 1 52}
+test clock-3.693 {ISO week-based calendar 2048-W01-3} {
+ clock format 2461449600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W01-3
+} {Wed Wednesday 48 2048 3 00 01 3 00}
+test clock-3.694 {ISO week-based calendar 2048-W01-6} {
+ clock format 2461708800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W01-6
+} {Sat Saturday 48 2048 6 00 01 6 00}
+test clock-3.695 {ISO week-based calendar 2048-W01-7} {
+ clock format 2461795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W01-7
+} {Sun Sunday 48 2048 7 01 01 0 00}
+test clock-3.696 {ISO week-based calendar 2048-W02-1} {
+ clock format 2461881600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W02-1
+} {Mon Monday 48 2048 1 01 02 1 01}
+test clock-3.697 {ISO week-based calendar 2048-W53-1} {
+ clock format 2492726400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W53-1
+} {Mon Monday 48 2048 1 52 53 1 52}
+test clock-3.698 {ISO week-based calendar 2048-W53-5} {
+ clock format 2493072000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W53-5
+} {Fri Friday 48 2048 5 00 53 5 00}
+test clock-3.699 {ISO week-based calendar 2048-W53-6} {
+ clock format 2493158400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W53-6
+} {Sat Saturday 48 2048 6 00 53 6 00}
+test clock-3.700 {ISO week-based calendar 2048-W53-7} {
+ clock format 2493244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W53-7
+} {Sun Sunday 48 2048 7 01 53 0 00}
+test clock-3.701 {ISO week-based calendar 2049-W01-1} {
+ clock format 2493331200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2049-W01-1
+} {Mon Monday 49 2049 1 01 01 1 01}
+test clock-3.702 {ISO week-based calendar 2049-W01-6} {
+ clock format 2493763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2049-W01-6
+} {Sat Saturday 49 2049 6 01 01 6 01}
+test clock-3.703 {ISO week-based calendar 2049-W01-7} {
+ clock format 2493849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2049-W01-7
+} {Sun Sunday 49 2049 7 02 01 0 01}
+test clock-3.704 {ISO week-based calendar 2049-W02-1} {
+ clock format 2493936000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2049-W02-1
+} {Mon Monday 49 2049 1 02 02 1 02}
+test clock-3.705 {ISO week-based calendar 2051-W52-1} {
+ clock format 2587075200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2051-W52-1
+} {Mon Monday 51 2051 1 52 52 1 52}
+test clock-3.706 {ISO week-based calendar 2051-W52-6} {
+ clock format 2587507200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2051-W52-6
+} {Sat Saturday 51 2051 6 52 52 6 52}
+test clock-3.707 {ISO week-based calendar 2051-W52-7} {
+ clock format 2587593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2051-W52-7
+} {Sun Sunday 51 2051 7 53 52 0 52}
+test clock-3.708 {ISO week-based calendar 2052-W01-1} {
+ clock format 2587680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W01-1
+} {Mon Monday 52 2052 1 00 01 1 01}
+test clock-3.709 {ISO week-based calendar 2052-W01-6} {
+ clock format 2588112000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W01-6
+} {Sat Saturday 52 2052 6 00 01 6 01}
+test clock-3.710 {ISO week-based calendar 2052-W01-7} {
+ clock format 2588198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W01-7
+} {Sun Sunday 52 2052 7 01 01 0 01}
+test clock-3.711 {ISO week-based calendar 2052-W02-1} {
+ clock format 2588284800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W02-1
+} {Mon Monday 52 2052 1 01 02 1 02}
+test clock-3.712 {ISO week-based calendar 2052-W52-1} {
+ clock format 2618524800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W52-1
+} {Mon Monday 52 2052 1 51 52 1 52}
+test clock-3.713 {ISO week-based calendar 2052-W52-6} {
+ clock format 2618956800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W52-6
+} {Sat Saturday 52 2052 6 51 52 6 52}
+test clock-3.714 {ISO week-based calendar 2052-W52-7} {
+ clock format 2619043200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W52-7
+} {Sun Sunday 52 2052 7 52 52 0 52}
+test clock-3.715 {ISO week-based calendar 2053-W01-1} {
+ clock format 2619129600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2053-W01-1
+} {Mon Monday 53 2053 1 52 01 1 53}
+test clock-3.716 {ISO week-based calendar 2053-W01-3} {
+ clock format 2619302400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2053-W01-3
+} {Wed Wednesday 53 2053 3 00 01 3 00}
+test clock-3.717 {ISO week-based calendar 2053-W01-6} {
+ clock format 2619561600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2053-W01-6
+} {Sat Saturday 53 2053 6 00 01 6 00}
+test clock-3.718 {ISO week-based calendar 2053-W01-7} {
+ clock format 2619648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2053-W01-7
+} {Sun Sunday 53 2053 7 01 01 0 00}
+test clock-3.719 {ISO week-based calendar 2053-W02-1} {
+ clock format 2619734400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2053-W02-1
+} {Mon Monday 53 2053 1 01 02 1 01}
+test clock-3.720 {ISO week-based calendar 2055-W52-1} {
+ clock format 2713478400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2055-W52-1
+} {Mon Monday 55 2055 1 52 52 1 52}
+test clock-3.721 {ISO week-based calendar 2055-W52-6} {
+ clock format 2713910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2055-W52-6
+} {Sat Saturday 55 2055 6 00 52 6 00}
+test clock-3.722 {ISO week-based calendar 2055-W52-7} {
+ clock format 2713996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2055-W52-7
+} {Sun Sunday 55 2055 7 01 52 0 00}
+test clock-3.723 {ISO week-based calendar 2056-W01-1} {
+ clock format 2714083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W01-1
+} {Mon Monday 56 2056 1 01 01 1 01}
+test clock-3.724 {ISO week-based calendar 2056-W01-6} {
+ clock format 2714515200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W01-6
+} {Sat Saturday 56 2056 6 01 01 6 01}
+test clock-3.725 {ISO week-based calendar 2056-W01-7} {
+ clock format 2714601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W01-7
+} {Sun Sunday 56 2056 7 02 01 0 01}
+test clock-3.726 {ISO week-based calendar 2056-W02-1} {
+ clock format 2714688000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W02-1
+} {Mon Monday 56 2056 1 02 02 1 02}
+test clock-3.727 {ISO week-based calendar 2056-W52-1} {
+ clock format 2744928000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W52-1
+} {Mon Monday 56 2056 1 52 52 1 52}
+test clock-3.728 {ISO week-based calendar 2056-W52-6} {
+ clock format 2745360000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W52-6
+} {Sat Saturday 56 2056 6 52 52 6 52}
+test clock-3.729 {ISO week-based calendar 2056-W52-7} {
+ clock format 2745446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W52-7
+} {Sun Sunday 56 2056 7 53 52 0 52}
+test clock-3.730 {ISO week-based calendar 2057-W01-1} {
+ clock format 2745532800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2057-W01-1
+} {Mon Monday 57 2057 1 00 01 1 01}
+test clock-3.731 {ISO week-based calendar 2057-W01-6} {
+ clock format 2745964800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2057-W01-6
+} {Sat Saturday 57 2057 6 00 01 6 01}
+test clock-3.732 {ISO week-based calendar 2057-W01-7} {
+ clock format 2746051200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2057-W01-7
+} {Sun Sunday 57 2057 7 01 01 0 01}
+test clock-3.733 {ISO week-based calendar 2057-W02-1} {
+ clock format 2746137600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2057-W02-1
+} {Mon Monday 57 2057 1 01 02 1 02}
+test clock-3.734 {ISO week-based calendar 2059-W52-1} {
+ clock format 2839276800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2059-W52-1
+} {Mon Monday 59 2059 1 51 52 1 51}
+test clock-3.735 {ISO week-based calendar 2059-W52-6} {
+ clock format 2839708800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2059-W52-6
+} {Sat Saturday 59 2059 6 51 52 6 51}
+test clock-3.736 {ISO week-based calendar 2059-W52-7} {
+ clock format 2839795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2059-W52-7
+} {Sun Sunday 59 2059 7 52 52 0 51}
+test clock-3.737 {ISO week-based calendar 2060-W01-1} {
+ clock format 2839881600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W01-1
+} {Mon Monday 60 2060 1 52 01 1 52}
+test clock-3.738 {ISO week-based calendar 2060-W01-4} {
+ clock format 2840140800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W01-4
+} {Thu Thursday 60 2060 4 00 01 4 00}
+test clock-3.739 {ISO week-based calendar 2060-W01-6} {
+ clock format 2840313600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W01-6
+} {Sat Saturday 60 2060 6 00 01 6 00}
+test clock-3.740 {ISO week-based calendar 2060-W01-7} {
+ clock format 2840400000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W01-7
+} {Sun Sunday 60 2060 7 01 01 0 00}
+test clock-3.741 {ISO week-based calendar 2060-W02-1} {
+ clock format 2840486400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W02-1
+} {Mon Monday 60 2060 1 01 02 1 01}
+test clock-3.742 {ISO week-based calendar 2060-W53-1} {
+ clock format 2871331200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W53-1
+} {Mon Monday 60 2060 1 52 53 1 52}
+test clock-3.743 {ISO week-based calendar 2060-W53-6} {
+ clock format 2871763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W53-6
+} {Sat Saturday 60 2060 6 00 53 6 00}
+test clock-3.744 {ISO week-based calendar 2060-W53-7} {
+ clock format 2871849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W53-7
+} {Sun Sunday 60 2060 7 01 53 0 00}
+test clock-3.745 {ISO week-based calendar 2061-W01-1} {
+ clock format 2871936000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2061-W01-1
+} {Mon Monday 61 2061 1 01 01 1 01}
+test clock-3.746 {ISO week-based calendar 2061-W01-6} {
+ clock format 2872368000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2061-W01-6
+} {Sat Saturday 61 2061 6 01 01 6 01}
+test clock-3.747 {ISO week-based calendar 2061-W01-7} {
+ clock format 2872454400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2061-W01-7
+} {Sun Sunday 61 2061 7 02 01 0 01}
+test clock-3.748 {ISO week-based calendar 2061-W02-1} {
+ clock format 2872540800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2061-W02-1
+} {Mon Monday 61 2061 1 02 02 1 02}
+test clock-3.749 {ISO week-based calendar 2063-W52-1} {
+ clock format 2965680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2063-W52-1
+} {Mon Monday 63 2063 1 51 52 1 52}
+test clock-3.750 {ISO week-based calendar 2063-W52-6} {
+ clock format 2966112000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2063-W52-6
+} {Sat Saturday 63 2063 6 51 52 6 52}
+test clock-3.751 {ISO week-based calendar 2063-W52-7} {
+ clock format 2966198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2063-W52-7
+} {Sun Sunday 63 2063 7 52 52 0 52}
+test clock-3.752 {ISO week-based calendar 2064-W01-1} {
+ clock format 2966284800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W01-1
+} {Mon Monday 64 2064 1 52 01 1 53}
+test clock-3.753 {ISO week-based calendar 2064-W01-2} {
+ clock format 2966371200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W01-2
+} {Tue Tuesday 64 2064 2 00 01 2 00}
+test clock-3.754 {ISO week-based calendar 2064-W01-6} {
+ clock format 2966716800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W01-6
+} {Sat Saturday 64 2064 6 00 01 6 00}
+test clock-3.755 {ISO week-based calendar 2064-W01-7} {
+ clock format 2966803200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W01-7
+} {Sun Sunday 64 2064 7 01 01 0 00}
+test clock-3.756 {ISO week-based calendar 2064-W02-1} {
+ clock format 2966889600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W02-1
+} {Mon Monday 64 2064 1 01 02 1 01}
+test clock-3.757 {ISO week-based calendar 2064-W52-1} {
+ clock format 2997129600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W52-1
+} {Mon Monday 64 2064 1 51 52 1 51}
+test clock-3.758 {ISO week-based calendar 2064-W52-6} {
+ clock format 2997561600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W52-6
+} {Sat Saturday 64 2064 6 51 52 6 51}
+test clock-3.759 {ISO week-based calendar 2064-W52-7} {
+ clock format 2997648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W52-7
+} {Sun Sunday 64 2064 7 52 52 0 51}
+test clock-3.760 {ISO week-based calendar 2065-W01-1} {
+ clock format 2997734400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2065-W01-1
+} {Mon Monday 65 2065 1 52 01 1 52}
+test clock-3.761 {ISO week-based calendar 2065-W01-4} {
+ clock format 2997993600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2065-W01-4
+} {Thu Thursday 65 2065 4 00 01 4 00}
+test clock-3.762 {ISO week-based calendar 2065-W01-6} {
+ clock format 2998166400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2065-W01-6
+} {Sat Saturday 65 2065 6 00 01 6 00}
+test clock-3.763 {ISO week-based calendar 2065-W01-7} {
+ clock format 2998252800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2065-W01-7
+} {Sun Sunday 65 2065 7 01 01 0 00}
+test clock-3.764 {ISO week-based calendar 2065-W02-1} {
+ clock format 2998339200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2065-W02-1
+} {Mon Monday 65 2065 1 01 02 1 01}
+# END testcases3
+
+# BEGIN testcases4
+
+# Test formatting of time of day
+# Format groups tested: %H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+
+
+test clock-4.1 { format time of day 00:00:00 } {
+ clock format 0 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 00 ? AM am 12:00:00 am 00:00 00 ? 00:00:00 00:00:00 ? h ? m ? s Thu Jan 1 00:00:00 GMT 1970}
+test clock-4.2 { format time of day 00:00:01 } {
+ clock format 1 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 00 ? AM am 12:00:01 am 00:00 01 i 00:00:01 00:00:01 ? h ? m i s Thu Jan 1 00:00:01 GMT 1970}
+test clock-4.3 { format time of day 00:00:58 } {
+ clock format 58 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 00 ? AM am 12:00:58 am 00:00 58 lviii 00:00:58 00:00:58 ? h ? m lviii s Thu Jan 1 00:00:58 GMT 1970}
+test clock-4.4 { format time of day 00:00:59 } {
+ clock format 59 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 00 ? AM am 12:00:59 am 00:00 59 lix 00:00:59 00:00:59 ? h ? m lix s Thu Jan 1 00:00:59 GMT 1970}
+test clock-4.5 { format time of day 00:01:00 } {
+ clock format 60 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 01 i AM am 12:01:00 am 00:01 00 ? 00:01:00 00:01:00 ? h i m ? s Thu Jan 1 00:01:00 GMT 1970}
+test clock-4.6 { format time of day 00:01:01 } {
+ clock format 61 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 01 i AM am 12:01:01 am 00:01 01 i 00:01:01 00:01:01 ? h i m i s Thu Jan 1 00:01:01 GMT 1970}
+test clock-4.7 { format time of day 00:01:58 } {
+ clock format 118 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 01 i AM am 12:01:58 am 00:01 58 lviii 00:01:58 00:01:58 ? h i m lviii s Thu Jan 1 00:01:58 GMT 1970}
+test clock-4.8 { format time of day 00:01:59 } {
+ clock format 119 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 01 i AM am 12:01:59 am 00:01 59 lix 00:01:59 00:01:59 ? h i m lix s Thu Jan 1 00:01:59 GMT 1970}
+test clock-4.9 { format time of day 00:58:00 } {
+ clock format 3480 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 58 lviii AM am 12:58:00 am 00:58 00 ? 00:58:00 00:58:00 ? h lviii m ? s Thu Jan 1 00:58:00 GMT 1970}
+test clock-4.10 { format time of day 00:58:01 } {
+ clock format 3481 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 58 lviii AM am 12:58:01 am 00:58 01 i 00:58:01 00:58:01 ? h lviii m i s Thu Jan 1 00:58:01 GMT 1970}
+test clock-4.11 { format time of day 00:58:58 } {
+ clock format 3538 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 58 lviii AM am 12:58:58 am 00:58 58 lviii 00:58:58 00:58:58 ? h lviii m lviii s Thu Jan 1 00:58:58 GMT 1970}
+test clock-4.12 { format time of day 00:58:59 } {
+ clock format 3539 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 58 lviii AM am 12:58:59 am 00:58 59 lix 00:58:59 00:58:59 ? h lviii m lix s Thu Jan 1 00:58:59 GMT 1970}
+test clock-4.13 { format time of day 00:59:00 } {
+ clock format 3540 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 59 lix AM am 12:59:00 am 00:59 00 ? 00:59:00 00:59:00 ? h lix m ? s Thu Jan 1 00:59:00 GMT 1970}
+test clock-4.14 { format time of day 00:59:01 } {
+ clock format 3541 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 59 lix AM am 12:59:01 am 00:59 01 i 00:59:01 00:59:01 ? h lix m i s Thu Jan 1 00:59:01 GMT 1970}
+test clock-4.15 { format time of day 00:59:58 } {
+ clock format 3598 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 59 lix AM am 12:59:58 am 00:59 58 lviii 00:59:58 00:59:58 ? h lix m lviii s Thu Jan 1 00:59:58 GMT 1970}
+test clock-4.16 { format time of day 00:59:59 } {
+ clock format 3599 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {00 ? 12 xii 0 ? 12 xii 59 lix AM am 12:59:59 am 00:59 59 lix 00:59:59 00:59:59 ? h lix m lix s Thu Jan 1 00:59:59 GMT 1970}
+test clock-4.17 { format time of day 01:00:00 } {
+ clock format 3600 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 00 ? AM am 01:00:00 am 01:00 00 ? 01:00:00 01:00:00 i h ? m ? s Thu Jan 1 01:00:00 GMT 1970}
+test clock-4.18 { format time of day 01:00:01 } {
+ clock format 3601 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 00 ? AM am 01:00:01 am 01:00 01 i 01:00:01 01:00:01 i h ? m i s Thu Jan 1 01:00:01 GMT 1970}
+test clock-4.19 { format time of day 01:00:58 } {
+ clock format 3658 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 00 ? AM am 01:00:58 am 01:00 58 lviii 01:00:58 01:00:58 i h ? m lviii s Thu Jan 1 01:00:58 GMT 1970}
+test clock-4.20 { format time of day 01:00:59 } {
+ clock format 3659 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 00 ? AM am 01:00:59 am 01:00 59 lix 01:00:59 01:00:59 i h ? m lix s Thu Jan 1 01:00:59 GMT 1970}
+test clock-4.21 { format time of day 01:01:00 } {
+ clock format 3660 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 01 i AM am 01:01:00 am 01:01 00 ? 01:01:00 01:01:00 i h i m ? s Thu Jan 1 01:01:00 GMT 1970}
+test clock-4.22 { format time of day 01:01:01 } {
+ clock format 3661 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 01 i AM am 01:01:01 am 01:01 01 i 01:01:01 01:01:01 i h i m i s Thu Jan 1 01:01:01 GMT 1970}
+test clock-4.23 { format time of day 01:01:58 } {
+ clock format 3718 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 01 i AM am 01:01:58 am 01:01 58 lviii 01:01:58 01:01:58 i h i m lviii s Thu Jan 1 01:01:58 GMT 1970}
+test clock-4.24 { format time of day 01:01:59 } {
+ clock format 3719 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 01 i AM am 01:01:59 am 01:01 59 lix 01:01:59 01:01:59 i h i m lix s Thu Jan 1 01:01:59 GMT 1970}
+test clock-4.25 { format time of day 01:58:00 } {
+ clock format 7080 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 58 lviii AM am 01:58:00 am 01:58 00 ? 01:58:00 01:58:00 i h lviii m ? s Thu Jan 1 01:58:00 GMT 1970}
+test clock-4.26 { format time of day 01:58:01 } {
+ clock format 7081 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 58 lviii AM am 01:58:01 am 01:58 01 i 01:58:01 01:58:01 i h lviii m i s Thu Jan 1 01:58:01 GMT 1970}
+test clock-4.27 { format time of day 01:58:58 } {
+ clock format 7138 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 58 lviii AM am 01:58:58 am 01:58 58 lviii 01:58:58 01:58:58 i h lviii m lviii s Thu Jan 1 01:58:58 GMT 1970}
+test clock-4.28 { format time of day 01:58:59 } {
+ clock format 7139 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 58 lviii AM am 01:58:59 am 01:58 59 lix 01:58:59 01:58:59 i h lviii m lix s Thu Jan 1 01:58:59 GMT 1970}
+test clock-4.29 { format time of day 01:59:00 } {
+ clock format 7140 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 59 lix AM am 01:59:00 am 01:59 00 ? 01:59:00 01:59:00 i h lix m ? s Thu Jan 1 01:59:00 GMT 1970}
+test clock-4.30 { format time of day 01:59:01 } {
+ clock format 7141 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 59 lix AM am 01:59:01 am 01:59 01 i 01:59:01 01:59:01 i h lix m i s Thu Jan 1 01:59:01 GMT 1970}
+test clock-4.31 { format time of day 01:59:58 } {
+ clock format 7198 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 59 lix AM am 01:59:58 am 01:59 58 lviii 01:59:58 01:59:58 i h lix m lviii s Thu Jan 1 01:59:58 GMT 1970}
+test clock-4.32 { format time of day 01:59:59 } {
+ clock format 7199 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {01 i 01 i 1 i 1 i 59 lix AM am 01:59:59 am 01:59 59 lix 01:59:59 01:59:59 i h lix m lix s Thu Jan 1 01:59:59 GMT 1970}
+test clock-4.33 { format time of day 11:00:00 } {
+ clock format 39600 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:00 am 11:00 00 ? 11:00:00 11:00:00 xi h ? m ? s Thu Jan 1 11:00:00 GMT 1970}
+test clock-4.34 { format time of day 11:00:01 } {
+ clock format 39601 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:01 am 11:00 01 i 11:00:01 11:00:01 xi h ? m i s Thu Jan 1 11:00:01 GMT 1970}
+test clock-4.35 { format time of day 11:00:58 } {
+ clock format 39658 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:58 am 11:00 58 lviii 11:00:58 11:00:58 xi h ? m lviii s Thu Jan 1 11:00:58 GMT 1970}
+test clock-4.36 { format time of day 11:00:59 } {
+ clock format 39659 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:59 am 11:00 59 lix 11:00:59 11:00:59 xi h ? m lix s Thu Jan 1 11:00:59 GMT 1970}
+test clock-4.37 { format time of day 11:01:00 } {
+ clock format 39660 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:00 am 11:01 00 ? 11:01:00 11:01:00 xi h i m ? s Thu Jan 1 11:01:00 GMT 1970}
+test clock-4.38 { format time of day 11:01:01 } {
+ clock format 39661 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:01 am 11:01 01 i 11:01:01 11:01:01 xi h i m i s Thu Jan 1 11:01:01 GMT 1970}
+test clock-4.39 { format time of day 11:01:58 } {
+ clock format 39718 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:58 am 11:01 58 lviii 11:01:58 11:01:58 xi h i m lviii s Thu Jan 1 11:01:58 GMT 1970}
+test clock-4.40 { format time of day 11:01:59 } {
+ clock format 39719 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:59 am 11:01 59 lix 11:01:59 11:01:59 xi h i m lix s Thu Jan 1 11:01:59 GMT 1970}
+test clock-4.41 { format time of day 11:58:00 } {
+ clock format 43080 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:00 am 11:58 00 ? 11:58:00 11:58:00 xi h lviii m ? s Thu Jan 1 11:58:00 GMT 1970}
+test clock-4.42 { format time of day 11:58:01 } {
+ clock format 43081 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:01 am 11:58 01 i 11:58:01 11:58:01 xi h lviii m i s Thu Jan 1 11:58:01 GMT 1970}
+test clock-4.43 { format time of day 11:58:58 } {
+ clock format 43138 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:58 am 11:58 58 lviii 11:58:58 11:58:58 xi h lviii m lviii s Thu Jan 1 11:58:58 GMT 1970}
+test clock-4.44 { format time of day 11:58:59 } {
+ clock format 43139 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:59 am 11:58 59 lix 11:58:59 11:58:59 xi h lviii m lix s Thu Jan 1 11:58:59 GMT 1970}
+test clock-4.45 { format time of day 11:59:00 } {
+ clock format 43140 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:00 am 11:59 00 ? 11:59:00 11:59:00 xi h lix m ? s Thu Jan 1 11:59:00 GMT 1970}
+test clock-4.46 { format time of day 11:59:01 } {
+ clock format 43141 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:01 am 11:59 01 i 11:59:01 11:59:01 xi h lix m i s Thu Jan 1 11:59:01 GMT 1970}
+test clock-4.47 { format time of day 11:59:58 } {
+ clock format 43198 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:58 am 11:59 58 lviii 11:59:58 11:59:58 xi h lix m lviii s Thu Jan 1 11:59:58 GMT 1970}
+test clock-4.48 { format time of day 11:59:59 } {
+ clock format 43199 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:59 am 11:59 59 lix 11:59:59 11:59:59 xi h lix m lix s Thu Jan 1 11:59:59 GMT 1970}
+test clock-4.49 { format time of day 12:00:00 } {
+ clock format 43200 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:00 pm 12:00 00 ? 12:00:00 12:00:00 xii h ? m ? s Thu Jan 1 12:00:00 GMT 1970}
+test clock-4.50 { format time of day 12:00:01 } {
+ clock format 43201 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:01 pm 12:00 01 i 12:00:01 12:00:01 xii h ? m i s Thu Jan 1 12:00:01 GMT 1970}
+test clock-4.51 { format time of day 12:00:58 } {
+ clock format 43258 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:58 pm 12:00 58 lviii 12:00:58 12:00:58 xii h ? m lviii s Thu Jan 1 12:00:58 GMT 1970}
+test clock-4.52 { format time of day 12:00:59 } {
+ clock format 43259 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:59 pm 12:00 59 lix 12:00:59 12:00:59 xii h ? m lix s Thu Jan 1 12:00:59 GMT 1970}
+test clock-4.53 { format time of day 12:01:00 } {
+ clock format 43260 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:00 pm 12:01 00 ? 12:01:00 12:01:00 xii h i m ? s Thu Jan 1 12:01:00 GMT 1970}
+test clock-4.54 { format time of day 12:01:01 } {
+ clock format 43261 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:01 pm 12:01 01 i 12:01:01 12:01:01 xii h i m i s Thu Jan 1 12:01:01 GMT 1970}
+test clock-4.55 { format time of day 12:01:58 } {
+ clock format 43318 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:58 pm 12:01 58 lviii 12:01:58 12:01:58 xii h i m lviii s Thu Jan 1 12:01:58 GMT 1970}
+test clock-4.56 { format time of day 12:01:59 } {
+ clock format 43319 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:59 pm 12:01 59 lix 12:01:59 12:01:59 xii h i m lix s Thu Jan 1 12:01:59 GMT 1970}
+test clock-4.57 { format time of day 12:58:00 } {
+ clock format 46680 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:00 pm 12:58 00 ? 12:58:00 12:58:00 xii h lviii m ? s Thu Jan 1 12:58:00 GMT 1970}
+test clock-4.58 { format time of day 12:58:01 } {
+ clock format 46681 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:01 pm 12:58 01 i 12:58:01 12:58:01 xii h lviii m i s Thu Jan 1 12:58:01 GMT 1970}
+test clock-4.59 { format time of day 12:58:58 } {
+ clock format 46738 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:58 pm 12:58 58 lviii 12:58:58 12:58:58 xii h lviii m lviii s Thu Jan 1 12:58:58 GMT 1970}
+test clock-4.60 { format time of day 12:58:59 } {
+ clock format 46739 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:59 pm 12:58 59 lix 12:58:59 12:58:59 xii h lviii m lix s Thu Jan 1 12:58:59 GMT 1970}
+test clock-4.61 { format time of day 12:59:00 } {
+ clock format 46740 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:00 pm 12:59 00 ? 12:59:00 12:59:00 xii h lix m ? s Thu Jan 1 12:59:00 GMT 1970}
+test clock-4.62 { format time of day 12:59:01 } {
+ clock format 46741 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:01 pm 12:59 01 i 12:59:01 12:59:01 xii h lix m i s Thu Jan 1 12:59:01 GMT 1970}
+test clock-4.63 { format time of day 12:59:58 } {
+ clock format 46798 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:58 pm 12:59 58 lviii 12:59:58 12:59:58 xii h lix m lviii s Thu Jan 1 12:59:58 GMT 1970}
+test clock-4.64 { format time of day 12:59:59 } {
+ clock format 46799 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:59 pm 12:59 59 lix 12:59:59 12:59:59 xii h lix m lix s Thu Jan 1 12:59:59 GMT 1970}
+test clock-4.65 { format time of day 13:00:00 } {
+ clock format 46800 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 00 ? PM pm 01:00:00 pm 13:00 00 ? 13:00:00 13:00:00 xiii h ? m ? s Thu Jan 1 13:00:00 GMT 1970}
+test clock-4.66 { format time of day 13:00:01 } {
+ clock format 46801 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 00 ? PM pm 01:00:01 pm 13:00 01 i 13:00:01 13:00:01 xiii h ? m i s Thu Jan 1 13:00:01 GMT 1970}
+test clock-4.67 { format time of day 13:00:58 } {
+ clock format 46858 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 00 ? PM pm 01:00:58 pm 13:00 58 lviii 13:00:58 13:00:58 xiii h ? m lviii s Thu Jan 1 13:00:58 GMT 1970}
+test clock-4.68 { format time of day 13:00:59 } {
+ clock format 46859 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 00 ? PM pm 01:00:59 pm 13:00 59 lix 13:00:59 13:00:59 xiii h ? m lix s Thu Jan 1 13:00:59 GMT 1970}
+test clock-4.69 { format time of day 13:01:00 } {
+ clock format 46860 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 01 i PM pm 01:01:00 pm 13:01 00 ? 13:01:00 13:01:00 xiii h i m ? s Thu Jan 1 13:01:00 GMT 1970}
+test clock-4.70 { format time of day 13:01:01 } {
+ clock format 46861 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 01 i PM pm 01:01:01 pm 13:01 01 i 13:01:01 13:01:01 xiii h i m i s Thu Jan 1 13:01:01 GMT 1970}
+test clock-4.71 { format time of day 13:01:58 } {
+ clock format 46918 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 01 i PM pm 01:01:58 pm 13:01 58 lviii 13:01:58 13:01:58 xiii h i m lviii s Thu Jan 1 13:01:58 GMT 1970}
+test clock-4.72 { format time of day 13:01:59 } {
+ clock format 46919 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 01 i PM pm 01:01:59 pm 13:01 59 lix 13:01:59 13:01:59 xiii h i m lix s Thu Jan 1 13:01:59 GMT 1970}
+test clock-4.73 { format time of day 13:58:00 } {
+ clock format 50280 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 58 lviii PM pm 01:58:00 pm 13:58 00 ? 13:58:00 13:58:00 xiii h lviii m ? s Thu Jan 1 13:58:00 GMT 1970}
+test clock-4.74 { format time of day 13:58:01 } {
+ clock format 50281 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 58 lviii PM pm 01:58:01 pm 13:58 01 i 13:58:01 13:58:01 xiii h lviii m i s Thu Jan 1 13:58:01 GMT 1970}
+test clock-4.75 { format time of day 13:58:58 } {
+ clock format 50338 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 58 lviii PM pm 01:58:58 pm 13:58 58 lviii 13:58:58 13:58:58 xiii h lviii m lviii s Thu Jan 1 13:58:58 GMT 1970}
+test clock-4.76 { format time of day 13:58:59 } {
+ clock format 50339 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 58 lviii PM pm 01:58:59 pm 13:58 59 lix 13:58:59 13:58:59 xiii h lviii m lix s Thu Jan 1 13:58:59 GMT 1970}
+test clock-4.77 { format time of day 13:59:00 } {
+ clock format 50340 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 59 lix PM pm 01:59:00 pm 13:59 00 ? 13:59:00 13:59:00 xiii h lix m ? s Thu Jan 1 13:59:00 GMT 1970}
+test clock-4.78 { format time of day 13:59:01 } {
+ clock format 50341 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 59 lix PM pm 01:59:01 pm 13:59 01 i 13:59:01 13:59:01 xiii h lix m i s Thu Jan 1 13:59:01 GMT 1970}
+test clock-4.79 { format time of day 13:59:58 } {
+ clock format 50398 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 59 lix PM pm 01:59:58 pm 13:59 58 lviii 13:59:58 13:59:58 xiii h lix m lviii s Thu Jan 1 13:59:58 GMT 1970}
+test clock-4.80 { format time of day 13:59:59 } {
+ clock format 50399 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {13 xiii 01 i 13 xiii 1 i 59 lix PM pm 01:59:59 pm 13:59 59 lix 13:59:59 13:59:59 xiii h lix m lix s Thu Jan 1 13:59:59 GMT 1970}
+test clock-4.81 { format time of day 23:00:00 } {
+ clock format 82800 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:00 pm 23:00 00 ? 23:00:00 23:00:00 xxiii h ? m ? s Thu Jan 1 23:00:00 GMT 1970}
+test clock-4.82 { format time of day 23:00:01 } {
+ clock format 82801 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:01 pm 23:00 01 i 23:00:01 23:00:01 xxiii h ? m i s Thu Jan 1 23:00:01 GMT 1970}
+test clock-4.83 { format time of day 23:00:58 } {
+ clock format 82858 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:58 pm 23:00 58 lviii 23:00:58 23:00:58 xxiii h ? m lviii s Thu Jan 1 23:00:58 GMT 1970}
+test clock-4.84 { format time of day 23:00:59 } {
+ clock format 82859 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:59 pm 23:00 59 lix 23:00:59 23:00:59 xxiii h ? m lix s Thu Jan 1 23:00:59 GMT 1970}
+test clock-4.85 { format time of day 23:01:00 } {
+ clock format 82860 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:00 pm 23:01 00 ? 23:01:00 23:01:00 xxiii h i m ? s Thu Jan 1 23:01:00 GMT 1970}
+test clock-4.86 { format time of day 23:01:01 } {
+ clock format 82861 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:01 pm 23:01 01 i 23:01:01 23:01:01 xxiii h i m i s Thu Jan 1 23:01:01 GMT 1970}
+test clock-4.87 { format time of day 23:01:58 } {
+ clock format 82918 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:58 pm 23:01 58 lviii 23:01:58 23:01:58 xxiii h i m lviii s Thu Jan 1 23:01:58 GMT 1970}
+test clock-4.88 { format time of day 23:01:59 } {
+ clock format 82919 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:59 pm 23:01 59 lix 23:01:59 23:01:59 xxiii h i m lix s Thu Jan 1 23:01:59 GMT 1970}
+test clock-4.89 { format time of day 23:58:00 } {
+ clock format 86280 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:00 pm 23:58 00 ? 23:58:00 23:58:00 xxiii h lviii m ? s Thu Jan 1 23:58:00 GMT 1970}
+test clock-4.90 { format time of day 23:58:01 } {
+ clock format 86281 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:01 pm 23:58 01 i 23:58:01 23:58:01 xxiii h lviii m i s Thu Jan 1 23:58:01 GMT 1970}
+test clock-4.91 { format time of day 23:58:58 } {
+ clock format 86338 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:58 pm 23:58 58 lviii 23:58:58 23:58:58 xxiii h lviii m lviii s Thu Jan 1 23:58:58 GMT 1970}
+test clock-4.92 { format time of day 23:58:59 } {
+ clock format 86339 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:59 pm 23:58 59 lix 23:58:59 23:58:59 xxiii h lviii m lix s Thu Jan 1 23:58:59 GMT 1970}
+test clock-4.93 { format time of day 23:59:00 } {
+ clock format 86340 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:00 pm 23:59 00 ? 23:59:00 23:59:00 xxiii h lix m ? s Thu Jan 1 23:59:00 GMT 1970}
+test clock-4.94 { format time of day 23:59:01 } {
+ clock format 86341 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:01 pm 23:59 01 i 23:59:01 23:59:01 xxiii h lix m i s Thu Jan 1 23:59:01 GMT 1970}
+test clock-4.95 { format time of day 23:59:58 } {
+ clock format 86398 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:58 pm 23:59 58 lviii 23:59:58 23:59:58 xxiii h lix m lviii s Thu Jan 1 23:59:58 GMT 1970}
+test clock-4.96 { format time of day 23:59:59 } {
+ clock format 86399 \
+ -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+ -locale en_US_roman \
+ -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:59 pm 23:59 59 lix 23:59:59 23:59:59 xxiii h lix m lix s Thu Jan 1 23:59:59 GMT 1970}
+# END testcases4
+
+# BEGIN testcases5
+
+# Test formatting of Daylight Saving Time
+
+test clock-5.1 {does Detroit exist} {
+ clock format 0 -format {} -timezone :America/Detroit
+ concat
+} {}
+test clock-5.2 {does Detroit have a Y2038 problem} detroit {
+ if { [clock format 2158894800 -format %z -timezone :America/Detroit] ne {-0400} } {
+ concat {y2038 problem}
+ } else {
+ concat {ok}
+ }
+} ok
+test clock-5.3 {time zone boundary case 1904-12-31 23:59:59} detroit {
+ clock format -2051202470 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {23:59:59 -053211 LMT}
+test clock-5.4 {time zone boundary case 1904-12-31 23:32:11} detroit {
+ clock format -2051202469 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {23:32:11 -0600 CST}
+test clock-5.5 {time zone boundary case 1904-12-31 23:32:12} detroit {
+ clock format -2051202468 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {23:32:12 -0600 CST}
+test clock-5.6 {time zone boundary case 1915-05-15 01:59:59} detroit {
+ clock format -1724083201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0600 CST}
+test clock-5.7 {time zone boundary case 1915-05-15 03:00:00} detroit {
+ clock format -1724083200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0500 EST}
+test clock-5.8 {time zone boundary case 1915-05-15 03:00:01} detroit {
+ clock format -1724083199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0500 EST}
+test clock-5.9 {time zone boundary case 1941-12-31 23:59:59} detroit {
+ clock format -883594801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {23:59:59 -0500 EST}
+test clock-5.10 {time zone boundary case 1942-01-01 00:00:00} detroit {
+ clock format -883594800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {00:00:00 -0500 EST}
+test clock-5.11 {time zone boundary case 1942-01-01 00:00:01} detroit {
+ clock format -883594799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {00:00:01 -0500 EST}
+test clock-5.12 {time zone boundary case 1942-02-09 01:59:59} detroit {
+ clock format -880218001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.13 {time zone boundary case 1942-02-09 03:00:00} detroit {
+ clock format -880218000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EWT}
+test clock-5.14 {time zone boundary case 1942-02-09 03:00:01} detroit {
+ clock format -880217999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EWT}
+test clock-5.15 {time zone boundary case 1945-08-14 18:59:59} detroit {
+ clock format -769395601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {18:59:59 -0400 EWT}
+test clock-5.16 {time zone boundary case 1945-08-14 19:00:00} detroit {
+ clock format -769395600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {19:00:00 -0400 EPT}
+test clock-5.17 {time zone boundary case 1945-08-14 19:00:01} detroit {
+ clock format -769395599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {19:00:01 -0400 EPT}
+test clock-5.18 {time zone boundary case 1945-09-30 01:59:59} detroit {
+ clock format -765396001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EPT}
+test clock-5.19 {time zone boundary case 1945-09-30 01:00:00} detroit {
+ clock format -765396000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.20 {time zone boundary case 1945-09-30 01:00:01} detroit {
+ clock format -765395999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.21 {time zone boundary case 1945-12-31 23:59:59} detroit {
+ clock format -757364401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {23:59:59 -0500 EST}
+test clock-5.22 {time zone boundary case 1946-01-01 00:00:00} detroit {
+ clock format -757364400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {00:00:00 -0500 EST}
+test clock-5.23 {time zone boundary case 1946-01-01 00:00:01} detroit {
+ clock format -757364399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {00:00:01 -0500 EST}
+test clock-5.24 {time zone boundary case 1948-04-25 01:59:59} detroit {
+ clock format -684349201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.25 {time zone boundary case 1948-04-25 03:00:00} detroit {
+ clock format -684349200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.26 {time zone boundary case 1948-04-25 03:00:01} detroit {
+ clock format -684349199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.27 {time zone boundary case 1948-09-26 01:59:59} detroit {
+ clock format -671047201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.28 {time zone boundary case 1948-09-26 01:00:00} detroit {
+ clock format -671047200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.29 {time zone boundary case 1948-09-26 01:00:01} detroit {
+ clock format -671047199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.30 {time zone boundary case 1967-06-14 01:59:59} detroit {
+ clock format -80499601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.31 {time zone boundary case 1967-06-14 03:00:00} detroit {
+ clock format -80499600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.32 {time zone boundary case 1967-06-14 03:00:01} detroit {
+ clock format -80499599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.33 {time zone boundary case 1967-10-29 01:59:59} detroit {
+ clock format -68666401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.34 {time zone boundary case 1967-10-29 01:00:00} detroit {
+ clock format -68666400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.35 {time zone boundary case 1967-10-29 01:00:01} detroit {
+ clock format -68666399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.36 {time zone boundary case 1972-12-31 23:59:59} detroit {
+ clock format 94712399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {23:59:59 -0500 EST}
+test clock-5.37 {time zone boundary case 1973-01-01 00:00:00} detroit {
+ clock format 94712400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {00:00:00 -0500 EST}
+test clock-5.38 {time zone boundary case 1973-01-01 00:00:01} detroit {
+ clock format 94712401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {00:00:01 -0500 EST}
+test clock-5.39 {time zone boundary case 1973-04-29 01:59:59} detroit {
+ clock format 104914799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.40 {time zone boundary case 1973-04-29 03:00:00} detroit {
+ clock format 104914800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.41 {time zone boundary case 1973-04-29 03:00:01} detroit {
+ clock format 104914801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.42 {time zone boundary case 1973-10-28 01:59:59} detroit {
+ clock format 120635999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.43 {time zone boundary case 1973-10-28 01:00:00} detroit {
+ clock format 120636000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.44 {time zone boundary case 1973-10-28 01:00:01} detroit {
+ clock format 120636001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.45 {time zone boundary case 1974-01-06 01:59:59} detroit {
+ clock format 126687599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.46 {time zone boundary case 1974-01-06 03:00:00} detroit {
+ clock format 126687600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.47 {time zone boundary case 1974-01-06 03:00:01} detroit {
+ clock format 126687601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.48 {time zone boundary case 1974-10-27 01:59:59} detroit {
+ clock format 152085599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.49 {time zone boundary case 1974-10-27 01:00:00} detroit {
+ clock format 152085600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.50 {time zone boundary case 1974-10-27 01:00:01} detroit {
+ clock format 152085601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.51 {time zone boundary case 1974-12-31 23:59:59} detroit {
+ clock format 157784399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {23:59:59 -0500 EST}
+test clock-5.52 {time zone boundary case 1975-01-01 00:00:00} detroit {
+ clock format 157784400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {00:00:00 -0500 EST}
+test clock-5.53 {time zone boundary case 1975-01-01 00:00:01} detroit {
+ clock format 157784401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {00:00:01 -0500 EST}
+test clock-5.54 {time zone boundary case 1975-04-27 01:59:59} detroit {
+ clock format 167813999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.55 {time zone boundary case 1975-04-27 03:00:00} detroit {
+ clock format 167814000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.56 {time zone boundary case 1975-04-27 03:00:01} detroit {
+ clock format 167814001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.57 {time zone boundary case 1975-10-26 01:59:59} detroit {
+ clock format 183535199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.58 {time zone boundary case 1975-10-26 01:00:00} detroit {
+ clock format 183535200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.59 {time zone boundary case 1975-10-26 01:00:01} detroit {
+ clock format 183535201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.60 {time zone boundary case 1976-04-25 01:59:59} detroit {
+ clock format 199263599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.61 {time zone boundary case 1976-04-25 03:00:00} detroit {
+ clock format 199263600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.62 {time zone boundary case 1976-04-25 03:00:01} detroit {
+ clock format 199263601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.63 {time zone boundary case 1976-10-31 01:59:59} detroit {
+ clock format 215589599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.64 {time zone boundary case 1976-10-31 01:00:00} detroit {
+ clock format 215589600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.65 {time zone boundary case 1976-10-31 01:00:01} detroit {
+ clock format 215589601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.66 {time zone boundary case 1977-04-24 01:59:59} detroit {
+ clock format 230713199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.67 {time zone boundary case 1977-04-24 03:00:00} detroit {
+ clock format 230713200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.68 {time zone boundary case 1977-04-24 03:00:01} detroit {
+ clock format 230713201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.69 {time zone boundary case 1977-10-30 01:59:59} detroit {
+ clock format 247039199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.70 {time zone boundary case 1977-10-30 01:00:00} detroit {
+ clock format 247039200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.71 {time zone boundary case 1977-10-30 01:00:01} detroit {
+ clock format 247039201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.72 {time zone boundary case 1978-04-30 01:59:59} detroit {
+ clock format 262767599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.73 {time zone boundary case 1978-04-30 03:00:00} detroit {
+ clock format 262767600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.74 {time zone boundary case 1978-04-30 03:00:01} detroit {
+ clock format 262767601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.75 {time zone boundary case 1978-10-29 01:59:59} detroit {
+ clock format 278488799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.76 {time zone boundary case 1978-10-29 01:00:00} detroit {
+ clock format 278488800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.77 {time zone boundary case 1978-10-29 01:00:01} detroit {
+ clock format 278488801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.78 {time zone boundary case 1979-04-29 01:59:59} detroit {
+ clock format 294217199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.79 {time zone boundary case 1979-04-29 03:00:00} detroit {
+ clock format 294217200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.80 {time zone boundary case 1979-04-29 03:00:01} detroit {
+ clock format 294217201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.81 {time zone boundary case 1979-10-28 01:59:59} detroit {
+ clock format 309938399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.82 {time zone boundary case 1979-10-28 01:00:00} detroit {
+ clock format 309938400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.83 {time zone boundary case 1979-10-28 01:00:01} detroit {
+ clock format 309938401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.84 {time zone boundary case 1980-04-27 01:59:59} detroit {
+ clock format 325666799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.85 {time zone boundary case 1980-04-27 03:00:00} detroit {
+ clock format 325666800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.86 {time zone boundary case 1980-04-27 03:00:01} detroit {
+ clock format 325666801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.87 {time zone boundary case 1980-10-26 01:59:59} detroit {
+ clock format 341387999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.88 {time zone boundary case 1980-10-26 01:00:00} detroit {
+ clock format 341388000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.89 {time zone boundary case 1980-10-26 01:00:01} detroit {
+ clock format 341388001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.90 {time zone boundary case 1981-04-26 01:59:59} detroit {
+ clock format 357116399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.91 {time zone boundary case 1981-04-26 03:00:00} detroit {
+ clock format 357116400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.92 {time zone boundary case 1981-04-26 03:00:01} detroit {
+ clock format 357116401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.93 {time zone boundary case 1981-10-25 01:59:59} detroit {
+ clock format 372837599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.94 {time zone boundary case 1981-10-25 01:00:00} detroit {
+ clock format 372837600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.95 {time zone boundary case 1981-10-25 01:00:01} detroit {
+ clock format 372837601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.96 {time zone boundary case 1982-04-25 01:59:59} detroit {
+ clock format 388565999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.97 {time zone boundary case 1982-04-25 03:00:00} detroit {
+ clock format 388566000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.98 {time zone boundary case 1982-04-25 03:00:01} detroit {
+ clock format 388566001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.99 {time zone boundary case 1982-10-31 01:59:59} detroit {
+ clock format 404891999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.100 {time zone boundary case 1982-10-31 01:00:00} detroit {
+ clock format 404892000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.101 {time zone boundary case 1982-10-31 01:00:01} detroit {
+ clock format 404892001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.102 {time zone boundary case 1983-04-24 01:59:59} detroit {
+ clock format 420015599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.103 {time zone boundary case 1983-04-24 03:00:00} detroit {
+ clock format 420015600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.104 {time zone boundary case 1983-04-24 03:00:01} detroit {
+ clock format 420015601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.105 {time zone boundary case 1983-10-30 01:59:59} detroit {
+ clock format 436341599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.106 {time zone boundary case 1983-10-30 01:00:00} detroit {
+ clock format 436341600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.107 {time zone boundary case 1983-10-30 01:00:01} detroit {
+ clock format 436341601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.108 {time zone boundary case 1984-04-29 01:59:59} detroit {
+ clock format 452069999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.109 {time zone boundary case 1984-04-29 03:00:00} detroit {
+ clock format 452070000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.110 {time zone boundary case 1984-04-29 03:00:01} detroit {
+ clock format 452070001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.111 {time zone boundary case 1984-10-28 01:59:59} detroit {
+ clock format 467791199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.112 {time zone boundary case 1984-10-28 01:00:00} detroit {
+ clock format 467791200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.113 {time zone boundary case 1984-10-28 01:00:01} detroit {
+ clock format 467791201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.114 {time zone boundary case 1985-04-28 01:59:59} detroit {
+ clock format 483519599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.115 {time zone boundary case 1985-04-28 03:00:00} detroit {
+ clock format 483519600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.116 {time zone boundary case 1985-04-28 03:00:01} detroit {
+ clock format 483519601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.117 {time zone boundary case 1985-10-27 01:59:59} detroit {
+ clock format 499240799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.118 {time zone boundary case 1985-10-27 01:00:00} detroit {
+ clock format 499240800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.119 {time zone boundary case 1985-10-27 01:00:01} detroit {
+ clock format 499240801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.120 {time zone boundary case 1986-04-27 01:59:59} detroit {
+ clock format 514969199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.121 {time zone boundary case 1986-04-27 03:00:00} detroit {
+ clock format 514969200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.122 {time zone boundary case 1986-04-27 03:00:01} detroit {
+ clock format 514969201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.123 {time zone boundary case 1986-10-26 01:59:59} detroit {
+ clock format 530690399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.124 {time zone boundary case 1986-10-26 01:00:00} detroit {
+ clock format 530690400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.125 {time zone boundary case 1986-10-26 01:00:01} detroit {
+ clock format 530690401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.126 {time zone boundary case 1987-04-05 01:59:59} detroit {
+ clock format 544604399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.127 {time zone boundary case 1987-04-05 03:00:00} detroit {
+ clock format 544604400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.128 {time zone boundary case 1987-04-05 03:00:01} detroit {
+ clock format 544604401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.129 {time zone boundary case 1987-10-25 01:59:59} detroit {
+ clock format 562139999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.130 {time zone boundary case 1987-10-25 01:00:00} detroit {
+ clock format 562140000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.131 {time zone boundary case 1987-10-25 01:00:01} detroit {
+ clock format 562140001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.132 {time zone boundary case 1988-04-03 01:59:59} detroit {
+ clock format 576053999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.133 {time zone boundary case 1988-04-03 03:00:00} detroit {
+ clock format 576054000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.134 {time zone boundary case 1988-04-03 03:00:01} detroit {
+ clock format 576054001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.135 {time zone boundary case 1988-10-30 01:59:59} detroit {
+ clock format 594194399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.136 {time zone boundary case 1988-10-30 01:00:00} detroit {
+ clock format 594194400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.137 {time zone boundary case 1988-10-30 01:00:01} detroit {
+ clock format 594194401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.138 {time zone boundary case 1989-04-02 01:59:59} detroit {
+ clock format 607503599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.139 {time zone boundary case 1989-04-02 03:00:00} detroit {
+ clock format 607503600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.140 {time zone boundary case 1989-04-02 03:00:01} detroit {
+ clock format 607503601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.141 {time zone boundary case 1989-10-29 01:59:59} detroit {
+ clock format 625643999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.142 {time zone boundary case 1989-10-29 01:00:00} detroit {
+ clock format 625644000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.143 {time zone boundary case 1989-10-29 01:00:01} detroit {
+ clock format 625644001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.144 {time zone boundary case 1990-04-01 01:59:59} detroit {
+ clock format 638953199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.145 {time zone boundary case 1990-04-01 03:00:00} detroit {
+ clock format 638953200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.146 {time zone boundary case 1990-04-01 03:00:01} detroit {
+ clock format 638953201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.147 {time zone boundary case 1990-10-28 01:59:59} detroit {
+ clock format 657093599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.148 {time zone boundary case 1990-10-28 01:00:00} detroit {
+ clock format 657093600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.149 {time zone boundary case 1990-10-28 01:00:01} detroit {
+ clock format 657093601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.150 {time zone boundary case 1991-04-07 01:59:59} detroit {
+ clock format 671007599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.151 {time zone boundary case 1991-04-07 03:00:00} detroit {
+ clock format 671007600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.152 {time zone boundary case 1991-04-07 03:00:01} detroit {
+ clock format 671007601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.153 {time zone boundary case 1991-10-27 01:59:59} detroit {
+ clock format 688543199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.154 {time zone boundary case 1991-10-27 01:00:00} detroit {
+ clock format 688543200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.155 {time zone boundary case 1991-10-27 01:00:01} detroit {
+ clock format 688543201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.156 {time zone boundary case 1992-04-05 01:59:59} detroit {
+ clock format 702457199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.157 {time zone boundary case 1992-04-05 03:00:00} detroit {
+ clock format 702457200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.158 {time zone boundary case 1992-04-05 03:00:01} detroit {
+ clock format 702457201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.159 {time zone boundary case 1992-10-25 01:59:59} detroit {
+ clock format 719992799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.160 {time zone boundary case 1992-10-25 01:00:00} detroit {
+ clock format 719992800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.161 {time zone boundary case 1992-10-25 01:00:01} detroit {
+ clock format 719992801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.162 {time zone boundary case 1993-04-04 01:59:59} detroit {
+ clock format 733906799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.163 {time zone boundary case 1993-04-04 03:00:00} detroit {
+ clock format 733906800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.164 {time zone boundary case 1993-04-04 03:00:01} detroit {
+ clock format 733906801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.165 {time zone boundary case 1993-10-31 01:59:59} detroit {
+ clock format 752047199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.166 {time zone boundary case 1993-10-31 01:00:00} detroit {
+ clock format 752047200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.167 {time zone boundary case 1993-10-31 01:00:01} detroit {
+ clock format 752047201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.168 {time zone boundary case 1994-04-03 01:59:59} detroit {
+ clock format 765356399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.169 {time zone boundary case 1994-04-03 03:00:00} detroit {
+ clock format 765356400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.170 {time zone boundary case 1994-04-03 03:00:01} detroit {
+ clock format 765356401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.171 {time zone boundary case 1994-10-30 01:59:59} detroit {
+ clock format 783496799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.172 {time zone boundary case 1994-10-30 01:00:00} detroit {
+ clock format 783496800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.173 {time zone boundary case 1994-10-30 01:00:01} detroit {
+ clock format 783496801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.174 {time zone boundary case 1995-04-02 01:59:59} detroit {
+ clock format 796805999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.175 {time zone boundary case 1995-04-02 03:00:00} detroit {
+ clock format 796806000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.176 {time zone boundary case 1995-04-02 03:00:01} detroit {
+ clock format 796806001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.177 {time zone boundary case 1995-10-29 01:59:59} detroit {
+ clock format 814946399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.178 {time zone boundary case 1995-10-29 01:00:00} detroit {
+ clock format 814946400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.179 {time zone boundary case 1995-10-29 01:00:01} detroit {
+ clock format 814946401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.180 {time zone boundary case 1996-04-07 01:59:59} detroit {
+ clock format 828860399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.181 {time zone boundary case 1996-04-07 03:00:00} detroit {
+ clock format 828860400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.182 {time zone boundary case 1996-04-07 03:00:01} detroit {
+ clock format 828860401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.183 {time zone boundary case 1996-10-27 01:59:59} detroit {
+ clock format 846395999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.184 {time zone boundary case 1996-10-27 01:00:00} detroit {
+ clock format 846396000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.185 {time zone boundary case 1996-10-27 01:00:01} detroit {
+ clock format 846396001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.186 {time zone boundary case 1997-04-06 01:59:59} detroit {
+ clock format 860309999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.187 {time zone boundary case 1997-04-06 03:00:00} detroit {
+ clock format 860310000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.188 {time zone boundary case 1997-04-06 03:00:01} detroit {
+ clock format 860310001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.189 {time zone boundary case 1997-10-26 01:59:59} detroit {
+ clock format 877845599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.190 {time zone boundary case 1997-10-26 01:00:00} detroit {
+ clock format 877845600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.191 {time zone boundary case 1997-10-26 01:00:01} detroit {
+ clock format 877845601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.192 {time zone boundary case 1998-04-05 01:59:59} detroit {
+ clock format 891759599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.193 {time zone boundary case 1998-04-05 03:00:00} detroit {
+ clock format 891759600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.194 {time zone boundary case 1998-04-05 03:00:01} detroit {
+ clock format 891759601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.195 {time zone boundary case 1998-10-25 01:59:59} detroit {
+ clock format 909295199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.196 {time zone boundary case 1998-10-25 01:00:00} detroit {
+ clock format 909295200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.197 {time zone boundary case 1998-10-25 01:00:01} detroit {
+ clock format 909295201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.198 {time zone boundary case 1999-04-04 01:59:59} detroit {
+ clock format 923209199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.199 {time zone boundary case 1999-04-04 03:00:00} detroit {
+ clock format 923209200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.200 {time zone boundary case 1999-04-04 03:00:01} detroit {
+ clock format 923209201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.201 {time zone boundary case 1999-10-31 01:59:59} detroit {
+ clock format 941349599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.202 {time zone boundary case 1999-10-31 01:00:00} detroit {
+ clock format 941349600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.203 {time zone boundary case 1999-10-31 01:00:01} detroit {
+ clock format 941349601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.204 {time zone boundary case 2000-04-02 01:59:59} detroit {
+ clock format 954658799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.205 {time zone boundary case 2000-04-02 03:00:00} detroit {
+ clock format 954658800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.206 {time zone boundary case 2000-04-02 03:00:01} detroit {
+ clock format 954658801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.207 {time zone boundary case 2000-10-29 01:59:59} detroit {
+ clock format 972799199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.208 {time zone boundary case 2000-10-29 01:00:00} detroit {
+ clock format 972799200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.209 {time zone boundary case 2000-10-29 01:00:01} detroit {
+ clock format 972799201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.210 {time zone boundary case 2001-04-01 01:59:59} detroit {
+ clock format 986108399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.211 {time zone boundary case 2001-04-01 03:00:00} detroit {
+ clock format 986108400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.212 {time zone boundary case 2001-04-01 03:00:01} detroit {
+ clock format 986108401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.213 {time zone boundary case 2001-10-28 01:59:59} detroit {
+ clock format 1004248799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.214 {time zone boundary case 2001-10-28 01:00:00} detroit {
+ clock format 1004248800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.215 {time zone boundary case 2001-10-28 01:00:01} detroit {
+ clock format 1004248801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.216 {time zone boundary case 2002-04-07 01:59:59} detroit {
+ clock format 1018162799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.217 {time zone boundary case 2002-04-07 03:00:00} detroit {
+ clock format 1018162800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.218 {time zone boundary case 2002-04-07 03:00:01} detroit {
+ clock format 1018162801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.219 {time zone boundary case 2002-10-27 01:59:59} detroit {
+ clock format 1035698399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.220 {time zone boundary case 2002-10-27 01:00:00} detroit {
+ clock format 1035698400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.221 {time zone boundary case 2002-10-27 01:00:01} detroit {
+ clock format 1035698401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.222 {time zone boundary case 2003-04-06 01:59:59} detroit {
+ clock format 1049612399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.223 {time zone boundary case 2003-04-06 03:00:00} detroit {
+ clock format 1049612400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.224 {time zone boundary case 2003-04-06 03:00:01} detroit {
+ clock format 1049612401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.225 {time zone boundary case 2003-10-26 01:59:59} detroit {
+ clock format 1067147999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.226 {time zone boundary case 2003-10-26 01:00:00} detroit {
+ clock format 1067148000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.227 {time zone boundary case 2003-10-26 01:00:01} detroit {
+ clock format 1067148001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.228 {time zone boundary case 2004-04-04 01:59:59} detroit {
+ clock format 1081061999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.229 {time zone boundary case 2004-04-04 03:00:00} detroit {
+ clock format 1081062000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.230 {time zone boundary case 2004-04-04 03:00:01} detroit {
+ clock format 1081062001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.231 {time zone boundary case 2004-10-31 01:59:59} detroit {
+ clock format 1099202399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.232 {time zone boundary case 2004-10-31 01:00:00} detroit {
+ clock format 1099202400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.233 {time zone boundary case 2004-10-31 01:00:01} detroit {
+ clock format 1099202401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.234 {time zone boundary case 2005-04-03 01:59:59} detroit {
+ clock format 1112511599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.235 {time zone boundary case 2005-04-03 03:00:00} detroit {
+ clock format 1112511600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.236 {time zone boundary case 2005-04-03 03:00:01} detroit {
+ clock format 1112511601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.237 {time zone boundary case 2005-10-30 01:59:59} detroit {
+ clock format 1130651999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.238 {time zone boundary case 2005-10-30 01:00:00} detroit {
+ clock format 1130652000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.239 {time zone boundary case 2005-10-30 01:00:01} detroit {
+ clock format 1130652001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.240 {time zone boundary case 2006-04-02 01:59:59} detroit {
+ clock format 1143961199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.241 {time zone boundary case 2006-04-02 03:00:00} detroit {
+ clock format 1143961200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.242 {time zone boundary case 2006-04-02 03:00:01} detroit {
+ clock format 1143961201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.243 {time zone boundary case 2006-10-29 01:59:59} detroit {
+ clock format 1162101599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.244 {time zone boundary case 2006-10-29 01:00:00} detroit {
+ clock format 1162101600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.245 {time zone boundary case 2006-10-29 01:00:01} detroit {
+ clock format 1162101601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.246 {time zone boundary case 2007-03-11 01:59:59} detroit {
+ clock format 1173596399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.247 {time zone boundary case 2007-03-11 03:00:00} detroit {
+ clock format 1173596400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.248 {time zone boundary case 2007-03-11 03:00:01} detroit {
+ clock format 1173596401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.249 {time zone boundary case 2007-11-04 01:59:59} detroit {
+ clock format 1194155999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.250 {time zone boundary case 2007-11-04 01:00:00} detroit {
+ clock format 1194156000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.251 {time zone boundary case 2007-11-04 01:00:01} detroit {
+ clock format 1194156001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.252 {time zone boundary case 2008-03-09 01:59:59} detroit {
+ clock format 1205045999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.253 {time zone boundary case 2008-03-09 03:00:00} detroit {
+ clock format 1205046000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.254 {time zone boundary case 2008-03-09 03:00:01} detroit {
+ clock format 1205046001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.255 {time zone boundary case 2008-11-02 01:59:59} detroit {
+ clock format 1225605599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.256 {time zone boundary case 2008-11-02 01:00:00} detroit {
+ clock format 1225605600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.257 {time zone boundary case 2008-11-02 01:00:01} detroit {
+ clock format 1225605601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.258 {time zone boundary case 2009-03-08 01:59:59} detroit {
+ clock format 1236495599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.259 {time zone boundary case 2009-03-08 03:00:00} detroit {
+ clock format 1236495600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.260 {time zone boundary case 2009-03-08 03:00:01} detroit {
+ clock format 1236495601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.261 {time zone boundary case 2009-11-01 01:59:59} detroit {
+ clock format 1257055199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.262 {time zone boundary case 2009-11-01 01:00:00} detroit {
+ clock format 1257055200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.263 {time zone boundary case 2009-11-01 01:00:01} detroit {
+ clock format 1257055201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.264 {time zone boundary case 2010-03-14 01:59:59} detroit {
+ clock format 1268549999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.265 {time zone boundary case 2010-03-14 03:00:00} detroit {
+ clock format 1268550000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.266 {time zone boundary case 2010-03-14 03:00:01} detroit {
+ clock format 1268550001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.267 {time zone boundary case 2010-11-07 01:59:59} detroit {
+ clock format 1289109599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.268 {time zone boundary case 2010-11-07 01:00:00} detroit {
+ clock format 1289109600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.269 {time zone boundary case 2010-11-07 01:00:01} detroit {
+ clock format 1289109601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.270 {time zone boundary case 2011-03-13 01:59:59} detroit {
+ clock format 1299999599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.271 {time zone boundary case 2011-03-13 03:00:00} detroit {
+ clock format 1299999600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.272 {time zone boundary case 2011-03-13 03:00:01} detroit {
+ clock format 1299999601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.273 {time zone boundary case 2011-11-06 01:59:59} detroit {
+ clock format 1320559199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.274 {time zone boundary case 2011-11-06 01:00:00} detroit {
+ clock format 1320559200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.275 {time zone boundary case 2011-11-06 01:00:01} detroit {
+ clock format 1320559201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.276 {time zone boundary case 2012-03-11 01:59:59} detroit {
+ clock format 1331449199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.277 {time zone boundary case 2012-03-11 03:00:00} detroit {
+ clock format 1331449200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.278 {time zone boundary case 2012-03-11 03:00:01} detroit {
+ clock format 1331449201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.279 {time zone boundary case 2012-11-04 01:59:59} detroit {
+ clock format 1352008799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.280 {time zone boundary case 2012-11-04 01:00:00} detroit {
+ clock format 1352008800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.281 {time zone boundary case 2012-11-04 01:00:01} detroit {
+ clock format 1352008801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.282 {time zone boundary case 2013-03-10 01:59:59} detroit {
+ clock format 1362898799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.283 {time zone boundary case 2013-03-10 03:00:00} detroit {
+ clock format 1362898800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.284 {time zone boundary case 2013-03-10 03:00:01} detroit {
+ clock format 1362898801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.285 {time zone boundary case 2013-11-03 01:59:59} detroit {
+ clock format 1383458399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.286 {time zone boundary case 2013-11-03 01:00:00} detroit {
+ clock format 1383458400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.287 {time zone boundary case 2013-11-03 01:00:01} detroit {
+ clock format 1383458401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.288 {time zone boundary case 2014-03-09 01:59:59} detroit {
+ clock format 1394348399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.289 {time zone boundary case 2014-03-09 03:00:00} detroit {
+ clock format 1394348400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.290 {time zone boundary case 2014-03-09 03:00:01} detroit {
+ clock format 1394348401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.291 {time zone boundary case 2014-11-02 01:59:59} detroit {
+ clock format 1414907999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.292 {time zone boundary case 2014-11-02 01:00:00} detroit {
+ clock format 1414908000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.293 {time zone boundary case 2014-11-02 01:00:01} detroit {
+ clock format 1414908001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.294 {time zone boundary case 2015-03-08 01:59:59} detroit {
+ clock format 1425797999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.295 {time zone boundary case 2015-03-08 03:00:00} detroit {
+ clock format 1425798000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.296 {time zone boundary case 2015-03-08 03:00:01} detroit {
+ clock format 1425798001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.297 {time zone boundary case 2015-11-01 01:59:59} detroit {
+ clock format 1446357599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.298 {time zone boundary case 2015-11-01 01:00:00} detroit {
+ clock format 1446357600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.299 {time zone boundary case 2015-11-01 01:00:01} detroit {
+ clock format 1446357601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.300 {time zone boundary case 2016-03-13 01:59:59} detroit {
+ clock format 1457852399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.301 {time zone boundary case 2016-03-13 03:00:00} detroit {
+ clock format 1457852400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.302 {time zone boundary case 2016-03-13 03:00:01} detroit {
+ clock format 1457852401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.303 {time zone boundary case 2016-11-06 01:59:59} detroit {
+ clock format 1478411999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.304 {time zone boundary case 2016-11-06 01:00:00} detroit {
+ clock format 1478412000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.305 {time zone boundary case 2016-11-06 01:00:01} detroit {
+ clock format 1478412001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.306 {time zone boundary case 2017-03-12 01:59:59} detroit {
+ clock format 1489301999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.307 {time zone boundary case 2017-03-12 03:00:00} detroit {
+ clock format 1489302000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.308 {time zone boundary case 2017-03-12 03:00:01} detroit {
+ clock format 1489302001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.309 {time zone boundary case 2017-11-05 01:59:59} detroit {
+ clock format 1509861599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.310 {time zone boundary case 2017-11-05 01:00:00} detroit {
+ clock format 1509861600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.311 {time zone boundary case 2017-11-05 01:00:01} detroit {
+ clock format 1509861601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.312 {time zone boundary case 2018-03-11 01:59:59} detroit {
+ clock format 1520751599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.313 {time zone boundary case 2018-03-11 03:00:00} detroit {
+ clock format 1520751600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.314 {time zone boundary case 2018-03-11 03:00:01} detroit {
+ clock format 1520751601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.315 {time zone boundary case 2018-11-04 01:59:59} detroit {
+ clock format 1541311199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.316 {time zone boundary case 2018-11-04 01:00:00} detroit {
+ clock format 1541311200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.317 {time zone boundary case 2018-11-04 01:00:01} detroit {
+ clock format 1541311201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.318 {time zone boundary case 2019-03-10 01:59:59} detroit {
+ clock format 1552201199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.319 {time zone boundary case 2019-03-10 03:00:00} detroit {
+ clock format 1552201200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.320 {time zone boundary case 2019-03-10 03:00:01} detroit {
+ clock format 1552201201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.321 {time zone boundary case 2019-11-03 01:59:59} detroit {
+ clock format 1572760799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.322 {time zone boundary case 2019-11-03 01:00:00} detroit {
+ clock format 1572760800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.323 {time zone boundary case 2019-11-03 01:00:01} detroit {
+ clock format 1572760801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.324 {time zone boundary case 2020-03-08 01:59:59} detroit {
+ clock format 1583650799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.325 {time zone boundary case 2020-03-08 03:00:00} detroit {
+ clock format 1583650800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.326 {time zone boundary case 2020-03-08 03:00:01} detroit {
+ clock format 1583650801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.327 {time zone boundary case 2020-11-01 01:59:59} detroit {
+ clock format 1604210399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.328 {time zone boundary case 2020-11-01 01:00:00} detroit {
+ clock format 1604210400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.329 {time zone boundary case 2020-11-01 01:00:01} detroit {
+ clock format 1604210401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.330 {time zone boundary case 2021-03-14 01:59:59} detroit {
+ clock format 1615705199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.331 {time zone boundary case 2021-03-14 03:00:00} detroit {
+ clock format 1615705200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.332 {time zone boundary case 2021-03-14 03:00:01} detroit {
+ clock format 1615705201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.333 {time zone boundary case 2021-11-07 01:59:59} detroit {
+ clock format 1636264799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.334 {time zone boundary case 2021-11-07 01:00:00} detroit {
+ clock format 1636264800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.335 {time zone boundary case 2021-11-07 01:00:01} detroit {
+ clock format 1636264801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.336 {time zone boundary case 2022-03-13 01:59:59} detroit {
+ clock format 1647154799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.337 {time zone boundary case 2022-03-13 03:00:00} detroit {
+ clock format 1647154800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.338 {time zone boundary case 2022-03-13 03:00:01} detroit {
+ clock format 1647154801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.339 {time zone boundary case 2022-11-06 01:59:59} detroit {
+ clock format 1667714399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.340 {time zone boundary case 2022-11-06 01:00:00} detroit {
+ clock format 1667714400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.341 {time zone boundary case 2022-11-06 01:00:01} detroit {
+ clock format 1667714401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.342 {time zone boundary case 2023-03-12 01:59:59} detroit {
+ clock format 1678604399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.343 {time zone boundary case 2023-03-12 03:00:00} detroit {
+ clock format 1678604400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.344 {time zone boundary case 2023-03-12 03:00:01} detroit {
+ clock format 1678604401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.345 {time zone boundary case 2023-11-05 01:59:59} detroit {
+ clock format 1699163999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.346 {time zone boundary case 2023-11-05 01:00:00} detroit {
+ clock format 1699164000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.347 {time zone boundary case 2023-11-05 01:00:01} detroit {
+ clock format 1699164001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.348 {time zone boundary case 2024-03-10 01:59:59} detroit {
+ clock format 1710053999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.349 {time zone boundary case 2024-03-10 03:00:00} detroit {
+ clock format 1710054000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.350 {time zone boundary case 2024-03-10 03:00:01} detroit {
+ clock format 1710054001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.351 {time zone boundary case 2024-11-03 01:59:59} detroit {
+ clock format 1730613599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.352 {time zone boundary case 2024-11-03 01:00:00} detroit {
+ clock format 1730613600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.353 {time zone boundary case 2024-11-03 01:00:01} detroit {
+ clock format 1730613601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.354 {time zone boundary case 2025-03-09 01:59:59} detroit {
+ clock format 1741503599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.355 {time zone boundary case 2025-03-09 03:00:00} detroit {
+ clock format 1741503600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.356 {time zone boundary case 2025-03-09 03:00:01} detroit {
+ clock format 1741503601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.357 {time zone boundary case 2025-11-02 01:59:59} detroit {
+ clock format 1762063199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.358 {time zone boundary case 2025-11-02 01:00:00} detroit {
+ clock format 1762063200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.359 {time zone boundary case 2025-11-02 01:00:01} detroit {
+ clock format 1762063201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.360 {time zone boundary case 2026-03-08 01:59:59} detroit {
+ clock format 1772953199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.361 {time zone boundary case 2026-03-08 03:00:00} detroit {
+ clock format 1772953200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.362 {time zone boundary case 2026-03-08 03:00:01} detroit {
+ clock format 1772953201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.363 {time zone boundary case 2026-11-01 01:59:59} detroit {
+ clock format 1793512799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.364 {time zone boundary case 2026-11-01 01:00:00} detroit {
+ clock format 1793512800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.365 {time zone boundary case 2026-11-01 01:00:01} detroit {
+ clock format 1793512801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.366 {time zone boundary case 2027-03-14 01:59:59} detroit {
+ clock format 1805007599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.367 {time zone boundary case 2027-03-14 03:00:00} detroit {
+ clock format 1805007600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.368 {time zone boundary case 2027-03-14 03:00:01} detroit {
+ clock format 1805007601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.369 {time zone boundary case 2027-11-07 01:59:59} detroit {
+ clock format 1825567199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.370 {time zone boundary case 2027-11-07 01:00:00} detroit {
+ clock format 1825567200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.371 {time zone boundary case 2027-11-07 01:00:01} detroit {
+ clock format 1825567201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.372 {time zone boundary case 2028-03-12 01:59:59} detroit {
+ clock format 1836457199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.373 {time zone boundary case 2028-03-12 03:00:00} detroit {
+ clock format 1836457200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.374 {time zone boundary case 2028-03-12 03:00:01} detroit {
+ clock format 1836457201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.375 {time zone boundary case 2028-11-05 01:59:59} detroit {
+ clock format 1857016799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.376 {time zone boundary case 2028-11-05 01:00:00} detroit {
+ clock format 1857016800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.377 {time zone boundary case 2028-11-05 01:00:01} detroit {
+ clock format 1857016801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.378 {time zone boundary case 2029-03-11 01:59:59} detroit {
+ clock format 1867906799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.379 {time zone boundary case 2029-03-11 03:00:00} detroit {
+ clock format 1867906800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.380 {time zone boundary case 2029-03-11 03:00:01} detroit {
+ clock format 1867906801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.381 {time zone boundary case 2029-11-04 01:59:59} detroit {
+ clock format 1888466399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.382 {time zone boundary case 2029-11-04 01:00:00} detroit {
+ clock format 1888466400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.383 {time zone boundary case 2029-11-04 01:00:01} detroit {
+ clock format 1888466401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.384 {time zone boundary case 2030-03-10 01:59:59} detroit {
+ clock format 1899356399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.385 {time zone boundary case 2030-03-10 03:00:00} detroit {
+ clock format 1899356400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.386 {time zone boundary case 2030-03-10 03:00:01} detroit {
+ clock format 1899356401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.387 {time zone boundary case 2030-11-03 01:59:59} detroit {
+ clock format 1919915999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.388 {time zone boundary case 2030-11-03 01:00:00} detroit {
+ clock format 1919916000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.389 {time zone boundary case 2030-11-03 01:00:01} detroit {
+ clock format 1919916001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.390 {time zone boundary case 2031-03-09 01:59:59} detroit {
+ clock format 1930805999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.391 {time zone boundary case 2031-03-09 03:00:00} detroit {
+ clock format 1930806000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.392 {time zone boundary case 2031-03-09 03:00:01} detroit {
+ clock format 1930806001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.393 {time zone boundary case 2031-11-02 01:59:59} detroit {
+ clock format 1951365599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.394 {time zone boundary case 2031-11-02 01:00:00} detroit {
+ clock format 1951365600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.395 {time zone boundary case 2031-11-02 01:00:01} detroit {
+ clock format 1951365601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.396 {time zone boundary case 2032-03-14 01:59:59} detroit {
+ clock format 1962860399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.397 {time zone boundary case 2032-03-14 03:00:00} detroit {
+ clock format 1962860400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.398 {time zone boundary case 2032-03-14 03:00:01} detroit {
+ clock format 1962860401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.399 {time zone boundary case 2032-11-07 01:59:59} detroit {
+ clock format 1983419999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.400 {time zone boundary case 2032-11-07 01:00:00} detroit {
+ clock format 1983420000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.401 {time zone boundary case 2032-11-07 01:00:01} detroit {
+ clock format 1983420001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.402 {time zone boundary case 2033-03-13 01:59:59} detroit {
+ clock format 1994309999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.403 {time zone boundary case 2033-03-13 03:00:00} detroit {
+ clock format 1994310000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.404 {time zone boundary case 2033-03-13 03:00:01} detroit {
+ clock format 1994310001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.405 {time zone boundary case 2033-11-06 01:59:59} detroit {
+ clock format 2014869599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.406 {time zone boundary case 2033-11-06 01:00:00} detroit {
+ clock format 2014869600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.407 {time zone boundary case 2033-11-06 01:00:01} detroit {
+ clock format 2014869601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.408 {time zone boundary case 2034-03-12 01:59:59} detroit {
+ clock format 2025759599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.409 {time zone boundary case 2034-03-12 03:00:00} detroit {
+ clock format 2025759600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.410 {time zone boundary case 2034-03-12 03:00:01} detroit {
+ clock format 2025759601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.411 {time zone boundary case 2034-11-05 01:59:59} detroit {
+ clock format 2046319199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.412 {time zone boundary case 2034-11-05 01:00:00} detroit {
+ clock format 2046319200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.413 {time zone boundary case 2034-11-05 01:00:01} detroit {
+ clock format 2046319201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.414 {time zone boundary case 2035-03-11 01:59:59} detroit {
+ clock format 2057209199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.415 {time zone boundary case 2035-03-11 03:00:00} detroit {
+ clock format 2057209200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.416 {time zone boundary case 2035-03-11 03:00:01} detroit {
+ clock format 2057209201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.417 {time zone boundary case 2035-11-04 01:59:59} detroit {
+ clock format 2077768799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.418 {time zone boundary case 2035-11-04 01:00:00} detroit {
+ clock format 2077768800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.419 {time zone boundary case 2035-11-04 01:00:01} detroit {
+ clock format 2077768801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.420 {time zone boundary case 2036-03-09 01:59:59} detroit {
+ clock format 2088658799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.421 {time zone boundary case 2036-03-09 03:00:00} detroit {
+ clock format 2088658800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.422 {time zone boundary case 2036-03-09 03:00:01} detroit {
+ clock format 2088658801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.423 {time zone boundary case 2036-11-02 01:59:59} detroit {
+ clock format 2109218399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.424 {time zone boundary case 2036-11-02 01:00:00} detroit {
+ clock format 2109218400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.425 {time zone boundary case 2036-11-02 01:00:01} detroit {
+ clock format 2109218401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.426 {time zone boundary case 2037-03-08 01:59:59} detroit {
+ clock format 2120108399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.427 {time zone boundary case 2037-03-08 03:00:00} detroit {
+ clock format 2120108400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.428 {time zone boundary case 2037-03-08 03:00:01} detroit {
+ clock format 2120108401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.429 {time zone boundary case 2037-11-01 01:59:59} detroit {
+ clock format 2140667999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.430 {time zone boundary case 2037-11-01 01:00:00} detroit {
+ clock format 2140668000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.431 {time zone boundary case 2037-11-01 01:00:01} detroit {
+ clock format 2140668001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.432 {time zone boundary case 2038-03-14 01:59:59} {detroit y2038} {
+ clock format 2152162799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.433 {time zone boundary case 2038-03-14 03:00:00} {detroit y2038} {
+ clock format 2152162800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.434 {time zone boundary case 2038-03-14 03:00:01} {detroit y2038} {
+ clock format 2152162801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.435 {time zone boundary case 2038-11-07 01:59:59} {detroit y2038} {
+ clock format 2172722399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.436 {time zone boundary case 2038-11-07 01:00:00} {detroit y2038} {
+ clock format 2172722400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.437 {time zone boundary case 2038-11-07 01:00:01} {detroit y2038} {
+ clock format 2172722401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.438 {time zone boundary case 2039-03-13 01:59:59} {detroit y2038} {
+ clock format 2183612399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.439 {time zone boundary case 2039-03-13 03:00:00} {detroit y2038} {
+ clock format 2183612400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.440 {time zone boundary case 2039-03-13 03:00:01} {detroit y2038} {
+ clock format 2183612401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.441 {time zone boundary case 2039-11-06 01:59:59} {detroit y2038} {
+ clock format 2204171999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.442 {time zone boundary case 2039-11-06 01:00:00} {detroit y2038} {
+ clock format 2204172000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.443 {time zone boundary case 2039-11-06 01:00:01} {detroit y2038} {
+ clock format 2204172001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.444 {time zone boundary case 2040-03-11 01:59:59} {detroit y2038} {
+ clock format 2215061999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.445 {time zone boundary case 2040-03-11 03:00:00} {detroit y2038} {
+ clock format 2215062000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.446 {time zone boundary case 2040-03-11 03:00:01} {detroit y2038} {
+ clock format 2215062001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.447 {time zone boundary case 2040-11-04 01:59:59} {detroit y2038} {
+ clock format 2235621599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.448 {time zone boundary case 2040-11-04 01:00:00} {detroit y2038} {
+ clock format 2235621600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.449 {time zone boundary case 2040-11-04 01:00:01} {detroit y2038} {
+ clock format 2235621601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.450 {time zone boundary case 2041-03-10 01:59:59} {detroit y2038} {
+ clock format 2246511599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.451 {time zone boundary case 2041-03-10 03:00:00} {detroit y2038} {
+ clock format 2246511600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.452 {time zone boundary case 2041-03-10 03:00:01} {detroit y2038} {
+ clock format 2246511601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.453 {time zone boundary case 2041-11-03 01:59:59} {detroit y2038} {
+ clock format 2267071199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.454 {time zone boundary case 2041-11-03 01:00:00} {detroit y2038} {
+ clock format 2267071200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.455 {time zone boundary case 2041-11-03 01:00:01} {detroit y2038} {
+ clock format 2267071201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.456 {time zone boundary case 2042-03-09 01:59:59} {detroit y2038} {
+ clock format 2277961199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.457 {time zone boundary case 2042-03-09 03:00:00} {detroit y2038} {
+ clock format 2277961200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.458 {time zone boundary case 2042-03-09 03:00:01} {detroit y2038} {
+ clock format 2277961201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.459 {time zone boundary case 2042-11-02 01:59:59} {detroit y2038} {
+ clock format 2298520799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.460 {time zone boundary case 2042-11-02 01:00:00} {detroit y2038} {
+ clock format 2298520800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.461 {time zone boundary case 2042-11-02 01:00:01} {detroit y2038} {
+ clock format 2298520801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.462 {time zone boundary case 2043-03-08 01:59:59} {detroit y2038} {
+ clock format 2309410799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.463 {time zone boundary case 2043-03-08 03:00:00} {detroit y2038} {
+ clock format 2309410800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.464 {time zone boundary case 2043-03-08 03:00:01} {detroit y2038} {
+ clock format 2309410801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.465 {time zone boundary case 2043-11-01 01:59:59} {detroit y2038} {
+ clock format 2329970399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.466 {time zone boundary case 2043-11-01 01:00:00} {detroit y2038} {
+ clock format 2329970400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.467 {time zone boundary case 2043-11-01 01:00:01} {detroit y2038} {
+ clock format 2329970401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.468 {time zone boundary case 2044-03-13 01:59:59} {detroit y2038} {
+ clock format 2341465199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.469 {time zone boundary case 2044-03-13 03:00:00} {detroit y2038} {
+ clock format 2341465200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.470 {time zone boundary case 2044-03-13 03:00:01} {detroit y2038} {
+ clock format 2341465201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.471 {time zone boundary case 2044-11-06 01:59:59} {detroit y2038} {
+ clock format 2362024799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.472 {time zone boundary case 2044-11-06 01:00:00} {detroit y2038} {
+ clock format 2362024800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.473 {time zone boundary case 2044-11-06 01:00:01} {detroit y2038} {
+ clock format 2362024801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.474 {time zone boundary case 2045-03-12 01:59:59} {detroit y2038} {
+ clock format 2372914799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.475 {time zone boundary case 2045-03-12 03:00:00} {detroit y2038} {
+ clock format 2372914800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.476 {time zone boundary case 2045-03-12 03:00:01} {detroit y2038} {
+ clock format 2372914801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.477 {time zone boundary case 2045-11-05 01:59:59} {detroit y2038} {
+ clock format 2393474399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.478 {time zone boundary case 2045-11-05 01:00:00} {detroit y2038} {
+ clock format 2393474400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.479 {time zone boundary case 2045-11-05 01:00:01} {detroit y2038} {
+ clock format 2393474401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.480 {time zone boundary case 2046-03-11 01:59:59} {detroit y2038} {
+ clock format 2404364399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.481 {time zone boundary case 2046-03-11 03:00:00} {detroit y2038} {
+ clock format 2404364400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.482 {time zone boundary case 2046-03-11 03:00:01} {detroit y2038} {
+ clock format 2404364401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.483 {time zone boundary case 2046-11-04 01:59:59} {detroit y2038} {
+ clock format 2424923999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.484 {time zone boundary case 2046-11-04 01:00:00} {detroit y2038} {
+ clock format 2424924000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.485 {time zone boundary case 2046-11-04 01:00:01} {detroit y2038} {
+ clock format 2424924001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.486 {time zone boundary case 2047-03-10 01:59:59} {detroit y2038} {
+ clock format 2435813999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.487 {time zone boundary case 2047-03-10 03:00:00} {detroit y2038} {
+ clock format 2435814000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.488 {time zone boundary case 2047-03-10 03:00:01} {detroit y2038} {
+ clock format 2435814001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.489 {time zone boundary case 2047-11-03 01:59:59} {detroit y2038} {
+ clock format 2456373599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.490 {time zone boundary case 2047-11-03 01:00:00} {detroit y2038} {
+ clock format 2456373600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.491 {time zone boundary case 2047-11-03 01:00:01} {detroit y2038} {
+ clock format 2456373601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.492 {time zone boundary case 2048-03-08 01:59:59} {detroit y2038} {
+ clock format 2467263599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.493 {time zone boundary case 2048-03-08 03:00:00} {detroit y2038} {
+ clock format 2467263600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.494 {time zone boundary case 2048-03-08 03:00:01} {detroit y2038} {
+ clock format 2467263601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.495 {time zone boundary case 2048-11-01 01:59:59} {detroit y2038} {
+ clock format 2487823199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.496 {time zone boundary case 2048-11-01 01:00:00} {detroit y2038} {
+ clock format 2487823200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.497 {time zone boundary case 2048-11-01 01:00:01} {detroit y2038} {
+ clock format 2487823201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.498 {time zone boundary case 2049-03-14 01:59:59} {detroit y2038} {
+ clock format 2499317999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.499 {time zone boundary case 2049-03-14 03:00:00} {detroit y2038} {
+ clock format 2499318000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.500 {time zone boundary case 2049-03-14 03:00:01} {detroit y2038} {
+ clock format 2499318001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.501 {time zone boundary case 2049-11-07 01:59:59} {detroit y2038} {
+ clock format 2519877599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.502 {time zone boundary case 2049-11-07 01:00:00} {detroit y2038} {
+ clock format 2519877600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.503 {time zone boundary case 2049-11-07 01:00:01} {detroit y2038} {
+ clock format 2519877601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.504 {time zone boundary case 2050-03-13 01:59:59} {detroit y2038} {
+ clock format 2530767599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.505 {time zone boundary case 2050-03-13 03:00:00} {detroit y2038} {
+ clock format 2530767600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.506 {time zone boundary case 2050-03-13 03:00:01} {detroit y2038} {
+ clock format 2530767601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.507 {time zone boundary case 2050-11-06 01:59:59} {detroit y2038} {
+ clock format 2551327199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.508 {time zone boundary case 2050-11-06 01:00:00} {detroit y2038} {
+ clock format 2551327200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.509 {time zone boundary case 2050-11-06 01:00:01} {detroit y2038} {
+ clock format 2551327201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.510 {time zone boundary case 2051-03-12 01:59:59} {detroit y2038} {
+ clock format 2562217199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.511 {time zone boundary case 2051-03-12 03:00:00} {detroit y2038} {
+ clock format 2562217200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.512 {time zone boundary case 2051-03-12 03:00:01} {detroit y2038} {
+ clock format 2562217201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.513 {time zone boundary case 2051-11-05 01:59:59} {detroit y2038} {
+ clock format 2582776799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.514 {time zone boundary case 2051-11-05 01:00:00} {detroit y2038} {
+ clock format 2582776800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.515 {time zone boundary case 2051-11-05 01:00:01} {detroit y2038} {
+ clock format 2582776801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.516 {time zone boundary case 2052-03-10 01:59:59} {detroit y2038} {
+ clock format 2593666799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.517 {time zone boundary case 2052-03-10 03:00:00} {detroit y2038} {
+ clock format 2593666800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.518 {time zone boundary case 2052-03-10 03:00:01} {detroit y2038} {
+ clock format 2593666801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.519 {time zone boundary case 2052-11-03 01:59:59} {detroit y2038} {
+ clock format 2614226399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.520 {time zone boundary case 2052-11-03 01:00:00} {detroit y2038} {
+ clock format 2614226400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.521 {time zone boundary case 2052-11-03 01:00:01} {detroit y2038} {
+ clock format 2614226401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.522 {time zone boundary case 2053-03-09 01:59:59} {detroit y2038} {
+ clock format 2625116399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.523 {time zone boundary case 2053-03-09 03:00:00} {detroit y2038} {
+ clock format 2625116400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.524 {time zone boundary case 2053-03-09 03:00:01} {detroit y2038} {
+ clock format 2625116401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.525 {time zone boundary case 2053-11-02 01:59:59} {detroit y2038} {
+ clock format 2645675999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.526 {time zone boundary case 2053-11-02 01:00:00} {detroit y2038} {
+ clock format 2645676000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.527 {time zone boundary case 2053-11-02 01:00:01} {detroit y2038} {
+ clock format 2645676001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.528 {time zone boundary case 2054-03-08 01:59:59} {detroit y2038} {
+ clock format 2656565999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.529 {time zone boundary case 2054-03-08 03:00:00} {detroit y2038} {
+ clock format 2656566000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.530 {time zone boundary case 2054-03-08 03:00:01} {detroit y2038} {
+ clock format 2656566001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.531 {time zone boundary case 2054-11-01 01:59:59} {detroit y2038} {
+ clock format 2677125599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.532 {time zone boundary case 2054-11-01 01:00:00} {detroit y2038} {
+ clock format 2677125600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.533 {time zone boundary case 2054-11-01 01:00:01} {detroit y2038} {
+ clock format 2677125601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.534 {time zone boundary case 2055-03-14 01:59:59} {detroit y2038} {
+ clock format 2688620399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.535 {time zone boundary case 2055-03-14 03:00:00} {detroit y2038} {
+ clock format 2688620400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.536 {time zone boundary case 2055-03-14 03:00:01} {detroit y2038} {
+ clock format 2688620401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.537 {time zone boundary case 2055-11-07 01:59:59} {detroit y2038} {
+ clock format 2709179999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.538 {time zone boundary case 2055-11-07 01:00:00} {detroit y2038} {
+ clock format 2709180000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.539 {time zone boundary case 2055-11-07 01:00:01} {detroit y2038} {
+ clock format 2709180001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.540 {time zone boundary case 2056-03-12 01:59:59} {detroit y2038} {
+ clock format 2720069999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.541 {time zone boundary case 2056-03-12 03:00:00} {detroit y2038} {
+ clock format 2720070000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.542 {time zone boundary case 2056-03-12 03:00:01} {detroit y2038} {
+ clock format 2720070001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.543 {time zone boundary case 2056-11-05 01:59:59} {detroit y2038} {
+ clock format 2740629599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.544 {time zone boundary case 2056-11-05 01:00:00} {detroit y2038} {
+ clock format 2740629600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.545 {time zone boundary case 2056-11-05 01:00:01} {detroit y2038} {
+ clock format 2740629601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.546 {time zone boundary case 2057-03-11 01:59:59} {detroit y2038} {
+ clock format 2751519599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.547 {time zone boundary case 2057-03-11 03:00:00} {detroit y2038} {
+ clock format 2751519600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.548 {time zone boundary case 2057-03-11 03:00:01} {detroit y2038} {
+ clock format 2751519601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.549 {time zone boundary case 2057-11-04 01:59:59} {detroit y2038} {
+ clock format 2772079199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.550 {time zone boundary case 2057-11-04 01:00:00} {detroit y2038} {
+ clock format 2772079200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.551 {time zone boundary case 2057-11-04 01:00:01} {detroit y2038} {
+ clock format 2772079201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.552 {time zone boundary case 2058-03-10 01:59:59} {detroit y2038} {
+ clock format 2782969199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.553 {time zone boundary case 2058-03-10 03:00:00} {detroit y2038} {
+ clock format 2782969200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.554 {time zone boundary case 2058-03-10 03:00:01} {detroit y2038} {
+ clock format 2782969201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.555 {time zone boundary case 2058-11-03 01:59:59} {detroit y2038} {
+ clock format 2803528799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.556 {time zone boundary case 2058-11-03 01:00:00} {detroit y2038} {
+ clock format 2803528800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.557 {time zone boundary case 2058-11-03 01:00:01} {detroit y2038} {
+ clock format 2803528801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.558 {time zone boundary case 2059-03-09 01:59:59} {detroit y2038} {
+ clock format 2814418799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.559 {time zone boundary case 2059-03-09 03:00:00} {detroit y2038} {
+ clock format 2814418800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.560 {time zone boundary case 2059-03-09 03:00:01} {detroit y2038} {
+ clock format 2814418801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.561 {time zone boundary case 2059-11-02 01:59:59} {detroit y2038} {
+ clock format 2834978399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.562 {time zone boundary case 2059-11-02 01:00:00} {detroit y2038} {
+ clock format 2834978400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.563 {time zone boundary case 2059-11-02 01:00:01} {detroit y2038} {
+ clock format 2834978401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.564 {time zone boundary case 2060-03-14 01:59:59} {detroit y2038} {
+ clock format 2846473199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.565 {time zone boundary case 2060-03-14 03:00:00} {detroit y2038} {
+ clock format 2846473200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.566 {time zone boundary case 2060-03-14 03:00:01} {detroit y2038} {
+ clock format 2846473201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.567 {time zone boundary case 2060-11-07 01:59:59} {detroit y2038} {
+ clock format 2867032799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.568 {time zone boundary case 2060-11-07 01:00:00} {detroit y2038} {
+ clock format 2867032800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.569 {time zone boundary case 2060-11-07 01:00:01} {detroit y2038} {
+ clock format 2867032801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.570 {time zone boundary case 2061-03-13 01:59:59} {detroit y2038} {
+ clock format 2877922799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.571 {time zone boundary case 2061-03-13 03:00:00} {detroit y2038} {
+ clock format 2877922800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.572 {time zone boundary case 2061-03-13 03:00:01} {detroit y2038} {
+ clock format 2877922801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.573 {time zone boundary case 2061-11-06 01:59:59} {detroit y2038} {
+ clock format 2898482399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.574 {time zone boundary case 2061-11-06 01:00:00} {detroit y2038} {
+ clock format 2898482400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.575 {time zone boundary case 2061-11-06 01:00:01} {detroit y2038} {
+ clock format 2898482401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.576 {time zone boundary case 2062-03-12 01:59:59} {detroit y2038} {
+ clock format 2909372399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.577 {time zone boundary case 2062-03-12 03:00:00} {detroit y2038} {
+ clock format 2909372400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.578 {time zone boundary case 2062-03-12 03:00:01} {detroit y2038} {
+ clock format 2909372401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.579 {time zone boundary case 2062-11-05 01:59:59} {detroit y2038} {
+ clock format 2929931999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.580 {time zone boundary case 2062-11-05 01:00:00} {detroit y2038} {
+ clock format 2929932000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.581 {time zone boundary case 2062-11-05 01:00:01} {detroit y2038} {
+ clock format 2929932001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.582 {time zone boundary case 2063-03-11 01:59:59} {detroit y2038} {
+ clock format 2940821999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.583 {time zone boundary case 2063-03-11 03:00:00} {detroit y2038} {
+ clock format 2940822000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.584 {time zone boundary case 2063-03-11 03:00:01} {detroit y2038} {
+ clock format 2940822001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.585 {time zone boundary case 2063-11-04 01:59:59} {detroit y2038} {
+ clock format 2961381599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.586 {time zone boundary case 2063-11-04 01:00:00} {detroit y2038} {
+ clock format 2961381600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.587 {time zone boundary case 2063-11-04 01:00:01} {detroit y2038} {
+ clock format 2961381601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.588 {time zone boundary case 2064-03-09 01:59:59} {detroit y2038} {
+ clock format 2972271599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.589 {time zone boundary case 2064-03-09 03:00:00} {detroit y2038} {
+ clock format 2972271600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.590 {time zone boundary case 2064-03-09 03:00:01} {detroit y2038} {
+ clock format 2972271601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.591 {time zone boundary case 2064-11-02 01:59:59} {detroit y2038} {
+ clock format 2992831199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.592 {time zone boundary case 2064-11-02 01:00:00} {detroit y2038} {
+ clock format 2992831200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.593 {time zone boundary case 2064-11-02 01:00:01} {detroit y2038} {
+ clock format 2992831201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.594 {time zone boundary case 2065-03-08 01:59:59} {detroit y2038} {
+ clock format 3003721199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.595 {time zone boundary case 2065-03-08 03:00:00} {detroit y2038} {
+ clock format 3003721200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.596 {time zone boundary case 2065-03-08 03:00:01} {detroit y2038} {
+ clock format 3003721201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.597 {time zone boundary case 2065-11-01 01:59:59} {detroit y2038} {
+ clock format 3024280799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.598 {time zone boundary case 2065-11-01 01:00:00} {detroit y2038} {
+ clock format 3024280800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.599 {time zone boundary case 2065-11-01 01:00:01} {detroit y2038} {
+ clock format 3024280801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.600 {time zone boundary case 2066-03-14 01:59:59} {detroit y2038} {
+ clock format 3035775599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.601 {time zone boundary case 2066-03-14 03:00:00} {detroit y2038} {
+ clock format 3035775600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.602 {time zone boundary case 2066-03-14 03:00:01} {detroit y2038} {
+ clock format 3035775601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.603 {time zone boundary case 2066-11-07 01:59:59} {detroit y2038} {
+ clock format 3056335199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.604 {time zone boundary case 2066-11-07 01:00:00} {detroit y2038} {
+ clock format 3056335200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.605 {time zone boundary case 2066-11-07 01:00:01} {detroit y2038} {
+ clock format 3056335201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.606 {time zone boundary case 2067-03-13 01:59:59} {detroit y2038} {
+ clock format 3067225199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.607 {time zone boundary case 2067-03-13 03:00:00} {detroit y2038} {
+ clock format 3067225200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.608 {time zone boundary case 2067-03-13 03:00:01} {detroit y2038} {
+ clock format 3067225201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.609 {time zone boundary case 2067-11-06 01:59:59} {detroit y2038} {
+ clock format 3087784799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.610 {time zone boundary case 2067-11-06 01:00:00} {detroit y2038} {
+ clock format 3087784800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.611 {time zone boundary case 2067-11-06 01:00:01} {detroit y2038} {
+ clock format 3087784801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.612 {time zone boundary case 2068-03-11 01:59:59} {detroit y2038} {
+ clock format 3098674799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.613 {time zone boundary case 2068-03-11 03:00:00} {detroit y2038} {
+ clock format 3098674800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.614 {time zone boundary case 2068-03-11 03:00:01} {detroit y2038} {
+ clock format 3098674801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.615 {time zone boundary case 2068-11-04 01:59:59} {detroit y2038} {
+ clock format 3119234399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.616 {time zone boundary case 2068-11-04 01:00:00} {detroit y2038} {
+ clock format 3119234400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.617 {time zone boundary case 2068-11-04 01:00:01} {detroit y2038} {
+ clock format 3119234401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.618 {time zone boundary case 2069-03-10 01:59:59} {detroit y2038} {
+ clock format 3130124399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.619 {time zone boundary case 2069-03-10 03:00:00} {detroit y2038} {
+ clock format 3130124400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.620 {time zone boundary case 2069-03-10 03:00:01} {detroit y2038} {
+ clock format 3130124401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.621 {time zone boundary case 2069-11-03 01:59:59} {detroit y2038} {
+ clock format 3150683999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.622 {time zone boundary case 2069-11-03 01:00:00} {detroit y2038} {
+ clock format 3150684000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.623 {time zone boundary case 2069-11-03 01:00:01} {detroit y2038} {
+ clock format 3150684001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.624 {time zone boundary case 2070-03-09 01:59:59} {detroit y2038} {
+ clock format 3161573999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.625 {time zone boundary case 2070-03-09 03:00:00} {detroit y2038} {
+ clock format 3161574000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.626 {time zone boundary case 2070-03-09 03:00:01} {detroit y2038} {
+ clock format 3161574001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.627 {time zone boundary case 2070-11-02 01:59:59} {detroit y2038} {
+ clock format 3182133599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.628 {time zone boundary case 2070-11-02 01:00:00} {detroit y2038} {
+ clock format 3182133600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.629 {time zone boundary case 2070-11-02 01:00:01} {detroit y2038} {
+ clock format 3182133601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.630 {time zone boundary case 2071-03-08 01:59:59} {detroit y2038} {
+ clock format 3193023599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.631 {time zone boundary case 2071-03-08 03:00:00} {detroit y2038} {
+ clock format 3193023600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.632 {time zone boundary case 2071-03-08 03:00:01} {detroit y2038} {
+ clock format 3193023601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.633 {time zone boundary case 2071-11-01 01:59:59} {detroit y2038} {
+ clock format 3213583199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.634 {time zone boundary case 2071-11-01 01:00:00} {detroit y2038} {
+ clock format 3213583200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.635 {time zone boundary case 2071-11-01 01:00:01} {detroit y2038} {
+ clock format 3213583201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.636 {time zone boundary case 2072-03-13 01:59:59} {detroit y2038} {
+ clock format 3225077999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.637 {time zone boundary case 2072-03-13 03:00:00} {detroit y2038} {
+ clock format 3225078000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.638 {time zone boundary case 2072-03-13 03:00:01} {detroit y2038} {
+ clock format 3225078001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.639 {time zone boundary case 2072-11-06 01:59:59} {detroit y2038} {
+ clock format 3245637599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.640 {time zone boundary case 2072-11-06 01:00:00} {detroit y2038} {
+ clock format 3245637600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.641 {time zone boundary case 2072-11-06 01:00:01} {detroit y2038} {
+ clock format 3245637601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.642 {time zone boundary case 2073-03-12 01:59:59} {detroit y2038} {
+ clock format 3256527599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.643 {time zone boundary case 2073-03-12 03:00:00} {detroit y2038} {
+ clock format 3256527600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.644 {time zone boundary case 2073-03-12 03:00:01} {detroit y2038} {
+ clock format 3256527601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.645 {time zone boundary case 2073-11-05 01:59:59} {detroit y2038} {
+ clock format 3277087199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.646 {time zone boundary case 2073-11-05 01:00:00} {detroit y2038} {
+ clock format 3277087200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.647 {time zone boundary case 2073-11-05 01:00:01} {detroit y2038} {
+ clock format 3277087201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.648 {time zone boundary case 2074-03-11 01:59:59} {detroit y2038} {
+ clock format 3287977199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.649 {time zone boundary case 2074-03-11 03:00:00} {detroit y2038} {
+ clock format 3287977200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.650 {time zone boundary case 2074-03-11 03:00:01} {detroit y2038} {
+ clock format 3287977201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.651 {time zone boundary case 2074-11-04 01:59:59} {detroit y2038} {
+ clock format 3308536799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.652 {time zone boundary case 2074-11-04 01:00:00} {detroit y2038} {
+ clock format 3308536800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.653 {time zone boundary case 2074-11-04 01:00:01} {detroit y2038} {
+ clock format 3308536801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.654 {time zone boundary case 2075-03-10 01:59:59} {detroit y2038} {
+ clock format 3319426799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.655 {time zone boundary case 2075-03-10 03:00:00} {detroit y2038} {
+ clock format 3319426800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.656 {time zone boundary case 2075-03-10 03:00:01} {detroit y2038} {
+ clock format 3319426801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.657 {time zone boundary case 2075-11-03 01:59:59} {detroit y2038} {
+ clock format 3339986399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.658 {time zone boundary case 2075-11-03 01:00:00} {detroit y2038} {
+ clock format 3339986400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.659 {time zone boundary case 2075-11-03 01:00:01} {detroit y2038} {
+ clock format 3339986401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.660 {time zone boundary case 2076-03-08 01:59:59} {detroit y2038} {
+ clock format 3350876399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.661 {time zone boundary case 2076-03-08 03:00:00} {detroit y2038} {
+ clock format 3350876400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.662 {time zone boundary case 2076-03-08 03:00:01} {detroit y2038} {
+ clock format 3350876401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.663 {time zone boundary case 2076-11-01 01:59:59} {detroit y2038} {
+ clock format 3371435999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.664 {time zone boundary case 2076-11-01 01:00:00} {detroit y2038} {
+ clock format 3371436000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.665 {time zone boundary case 2076-11-01 01:00:01} {detroit y2038} {
+ clock format 3371436001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.666 {time zone boundary case 2077-03-14 01:59:59} {detroit y2038} {
+ clock format 3382930799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.667 {time zone boundary case 2077-03-14 03:00:00} {detroit y2038} {
+ clock format 3382930800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.668 {time zone boundary case 2077-03-14 03:00:01} {detroit y2038} {
+ clock format 3382930801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.669 {time zone boundary case 2077-11-07 01:59:59} {detroit y2038} {
+ clock format 3403490399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.670 {time zone boundary case 2077-11-07 01:00:00} {detroit y2038} {
+ clock format 3403490400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.671 {time zone boundary case 2077-11-07 01:00:01} {detroit y2038} {
+ clock format 3403490401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.672 {time zone boundary case 2078-03-13 01:59:59} {detroit y2038} {
+ clock format 3414380399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.673 {time zone boundary case 2078-03-13 03:00:00} {detroit y2038} {
+ clock format 3414380400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.674 {time zone boundary case 2078-03-13 03:00:01} {detroit y2038} {
+ clock format 3414380401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.675 {time zone boundary case 2078-11-06 01:59:59} {detroit y2038} {
+ clock format 3434939999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.676 {time zone boundary case 2078-11-06 01:00:00} {detroit y2038} {
+ clock format 3434940000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.677 {time zone boundary case 2078-11-06 01:00:01} {detroit y2038} {
+ clock format 3434940001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.678 {time zone boundary case 2079-03-12 01:59:59} {detroit y2038} {
+ clock format 3445829999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.679 {time zone boundary case 2079-03-12 03:00:00} {detroit y2038} {
+ clock format 3445830000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.680 {time zone boundary case 2079-03-12 03:00:01} {detroit y2038} {
+ clock format 3445830001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.681 {time zone boundary case 2079-11-05 01:59:59} {detroit y2038} {
+ clock format 3466389599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.682 {time zone boundary case 2079-11-05 01:00:00} {detroit y2038} {
+ clock format 3466389600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.683 {time zone boundary case 2079-11-05 01:00:01} {detroit y2038} {
+ clock format 3466389601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.684 {time zone boundary case 2080-03-10 01:59:59} {detroit y2038} {
+ clock format 3477279599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.685 {time zone boundary case 2080-03-10 03:00:00} {detroit y2038} {
+ clock format 3477279600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.686 {time zone boundary case 2080-03-10 03:00:01} {detroit y2038} {
+ clock format 3477279601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.687 {time zone boundary case 2080-11-03 01:59:59} {detroit y2038} {
+ clock format 3497839199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.688 {time zone boundary case 2080-11-03 01:00:00} {detroit y2038} {
+ clock format 3497839200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.689 {time zone boundary case 2080-11-03 01:00:01} {detroit y2038} {
+ clock format 3497839201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.690 {time zone boundary case 2081-03-09 01:59:59} {detroit y2038} {
+ clock format 3508729199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.691 {time zone boundary case 2081-03-09 03:00:00} {detroit y2038} {
+ clock format 3508729200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.692 {time zone boundary case 2081-03-09 03:00:01} {detroit y2038} {
+ clock format 3508729201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.693 {time zone boundary case 2081-11-02 01:59:59} {detroit y2038} {
+ clock format 3529288799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.694 {time zone boundary case 2081-11-02 01:00:00} {detroit y2038} {
+ clock format 3529288800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.695 {time zone boundary case 2081-11-02 01:00:01} {detroit y2038} {
+ clock format 3529288801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.696 {time zone boundary case 2082-03-08 01:59:59} {detroit y2038} {
+ clock format 3540178799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.697 {time zone boundary case 2082-03-08 03:00:00} {detroit y2038} {
+ clock format 3540178800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.698 {time zone boundary case 2082-03-08 03:00:01} {detroit y2038} {
+ clock format 3540178801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.699 {time zone boundary case 2082-11-01 01:59:59} {detroit y2038} {
+ clock format 3560738399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.700 {time zone boundary case 2082-11-01 01:00:00} {detroit y2038} {
+ clock format 3560738400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.701 {time zone boundary case 2082-11-01 01:00:01} {detroit y2038} {
+ clock format 3560738401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.702 {time zone boundary case 2083-03-14 01:59:59} {detroit y2038} {
+ clock format 3572233199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.703 {time zone boundary case 2083-03-14 03:00:00} {detroit y2038} {
+ clock format 3572233200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.704 {time zone boundary case 2083-03-14 03:00:01} {detroit y2038} {
+ clock format 3572233201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.705 {time zone boundary case 2083-11-07 01:59:59} {detroit y2038} {
+ clock format 3592792799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.706 {time zone boundary case 2083-11-07 01:00:00} {detroit y2038} {
+ clock format 3592792800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.707 {time zone boundary case 2083-11-07 01:00:01} {detroit y2038} {
+ clock format 3592792801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.708 {time zone boundary case 2084-03-12 01:59:59} {detroit y2038} {
+ clock format 3603682799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.709 {time zone boundary case 2084-03-12 03:00:00} {detroit y2038} {
+ clock format 3603682800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.710 {time zone boundary case 2084-03-12 03:00:01} {detroit y2038} {
+ clock format 3603682801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.711 {time zone boundary case 2084-11-05 01:59:59} {detroit y2038} {
+ clock format 3624242399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.712 {time zone boundary case 2084-11-05 01:00:00} {detroit y2038} {
+ clock format 3624242400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.713 {time zone boundary case 2084-11-05 01:00:01} {detroit y2038} {
+ clock format 3624242401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.714 {time zone boundary case 2085-03-11 01:59:59} {detroit y2038} {
+ clock format 3635132399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.715 {time zone boundary case 2085-03-11 03:00:00} {detroit y2038} {
+ clock format 3635132400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.716 {time zone boundary case 2085-03-11 03:00:01} {detroit y2038} {
+ clock format 3635132401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.717 {time zone boundary case 2085-11-04 01:59:59} {detroit y2038} {
+ clock format 3655691999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.718 {time zone boundary case 2085-11-04 01:00:00} {detroit y2038} {
+ clock format 3655692000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.719 {time zone boundary case 2085-11-04 01:00:01} {detroit y2038} {
+ clock format 3655692001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.720 {time zone boundary case 2086-03-10 01:59:59} {detroit y2038} {
+ clock format 3666581999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.721 {time zone boundary case 2086-03-10 03:00:00} {detroit y2038} {
+ clock format 3666582000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.722 {time zone boundary case 2086-03-10 03:00:01} {detroit y2038} {
+ clock format 3666582001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.723 {time zone boundary case 2086-11-03 01:59:59} {detroit y2038} {
+ clock format 3687141599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.724 {time zone boundary case 2086-11-03 01:00:00} {detroit y2038} {
+ clock format 3687141600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.725 {time zone boundary case 2086-11-03 01:00:01} {detroit y2038} {
+ clock format 3687141601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.726 {time zone boundary case 2087-03-09 01:59:59} {detroit y2038} {
+ clock format 3698031599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.727 {time zone boundary case 2087-03-09 03:00:00} {detroit y2038} {
+ clock format 3698031600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.728 {time zone boundary case 2087-03-09 03:00:01} {detroit y2038} {
+ clock format 3698031601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.729 {time zone boundary case 2087-11-02 01:59:59} {detroit y2038} {
+ clock format 3718591199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.730 {time zone boundary case 2087-11-02 01:00:00} {detroit y2038} {
+ clock format 3718591200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.731 {time zone boundary case 2087-11-02 01:00:01} {detroit y2038} {
+ clock format 3718591201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.732 {time zone boundary case 2088-03-14 01:59:59} {detroit y2038} {
+ clock format 3730085999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.733 {time zone boundary case 2088-03-14 03:00:00} {detroit y2038} {
+ clock format 3730086000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.734 {time zone boundary case 2088-03-14 03:00:01} {detroit y2038} {
+ clock format 3730086001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.735 {time zone boundary case 2088-11-07 01:59:59} {detroit y2038} {
+ clock format 3750645599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.736 {time zone boundary case 2088-11-07 01:00:00} {detroit y2038} {
+ clock format 3750645600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.737 {time zone boundary case 2088-11-07 01:00:01} {detroit y2038} {
+ clock format 3750645601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.738 {time zone boundary case 2089-03-13 01:59:59} {detroit y2038} {
+ clock format 3761535599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.739 {time zone boundary case 2089-03-13 03:00:00} {detroit y2038} {
+ clock format 3761535600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.740 {time zone boundary case 2089-03-13 03:00:01} {detroit y2038} {
+ clock format 3761535601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.741 {time zone boundary case 2089-11-06 01:59:59} {detroit y2038} {
+ clock format 3782095199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.742 {time zone boundary case 2089-11-06 01:00:00} {detroit y2038} {
+ clock format 3782095200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.743 {time zone boundary case 2089-11-06 01:00:01} {detroit y2038} {
+ clock format 3782095201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.744 {time zone boundary case 2090-03-12 01:59:59} {detroit y2038} {
+ clock format 3792985199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.745 {time zone boundary case 2090-03-12 03:00:00} {detroit y2038} {
+ clock format 3792985200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.746 {time zone boundary case 2090-03-12 03:00:01} {detroit y2038} {
+ clock format 3792985201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.747 {time zone boundary case 2090-11-05 01:59:59} {detroit y2038} {
+ clock format 3813544799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.748 {time zone boundary case 2090-11-05 01:00:00} {detroit y2038} {
+ clock format 3813544800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.749 {time zone boundary case 2090-11-05 01:00:01} {detroit y2038} {
+ clock format 3813544801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.750 {time zone boundary case 2091-03-11 01:59:59} {detroit y2038} {
+ clock format 3824434799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.751 {time zone boundary case 2091-03-11 03:00:00} {detroit y2038} {
+ clock format 3824434800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.752 {time zone boundary case 2091-03-11 03:00:01} {detroit y2038} {
+ clock format 3824434801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.753 {time zone boundary case 2091-11-04 01:59:59} {detroit y2038} {
+ clock format 3844994399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.754 {time zone boundary case 2091-11-04 01:00:00} {detroit y2038} {
+ clock format 3844994400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.755 {time zone boundary case 2091-11-04 01:00:01} {detroit y2038} {
+ clock format 3844994401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.756 {time zone boundary case 2092-03-09 01:59:59} {detroit y2038} {
+ clock format 3855884399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.757 {time zone boundary case 2092-03-09 03:00:00} {detroit y2038} {
+ clock format 3855884400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.758 {time zone boundary case 2092-03-09 03:00:01} {detroit y2038} {
+ clock format 3855884401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.759 {time zone boundary case 2092-11-02 01:59:59} {detroit y2038} {
+ clock format 3876443999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.760 {time zone boundary case 2092-11-02 01:00:00} {detroit y2038} {
+ clock format 3876444000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.761 {time zone boundary case 2092-11-02 01:00:01} {detroit y2038} {
+ clock format 3876444001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.762 {time zone boundary case 2093-03-08 01:59:59} {detroit y2038} {
+ clock format 3887333999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.763 {time zone boundary case 2093-03-08 03:00:00} {detroit y2038} {
+ clock format 3887334000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.764 {time zone boundary case 2093-03-08 03:00:01} {detroit y2038} {
+ clock format 3887334001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.765 {time zone boundary case 2093-11-01 01:59:59} {detroit y2038} {
+ clock format 3907893599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.766 {time zone boundary case 2093-11-01 01:00:00} {detroit y2038} {
+ clock format 3907893600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.767 {time zone boundary case 2093-11-01 01:00:01} {detroit y2038} {
+ clock format 3907893601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.768 {time zone boundary case 2094-03-14 01:59:59} {detroit y2038} {
+ clock format 3919388399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.769 {time zone boundary case 2094-03-14 03:00:00} {detroit y2038} {
+ clock format 3919388400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.770 {time zone boundary case 2094-03-14 03:00:01} {detroit y2038} {
+ clock format 3919388401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.771 {time zone boundary case 2094-11-07 01:59:59} {detroit y2038} {
+ clock format 3939947999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.772 {time zone boundary case 2094-11-07 01:00:00} {detroit y2038} {
+ clock format 3939948000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.773 {time zone boundary case 2094-11-07 01:00:01} {detroit y2038} {
+ clock format 3939948001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.774 {time zone boundary case 2095-03-13 01:59:59} {detroit y2038} {
+ clock format 3950837999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.775 {time zone boundary case 2095-03-13 03:00:00} {detroit y2038} {
+ clock format 3950838000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.776 {time zone boundary case 2095-03-13 03:00:01} {detroit y2038} {
+ clock format 3950838001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.777 {time zone boundary case 2095-11-06 01:59:59} {detroit y2038} {
+ clock format 3971397599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.778 {time zone boundary case 2095-11-06 01:00:00} {detroit y2038} {
+ clock format 3971397600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.779 {time zone boundary case 2095-11-06 01:00:01} {detroit y2038} {
+ clock format 3971397601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.780 {time zone boundary case 2096-03-11 01:59:59} {detroit y2038} {
+ clock format 3982287599 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.781 {time zone boundary case 2096-03-11 03:00:00} {detroit y2038} {
+ clock format 3982287600 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.782 {time zone boundary case 2096-03-11 03:00:01} {detroit y2038} {
+ clock format 3982287601 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.783 {time zone boundary case 2096-11-04 01:59:59} {detroit y2038} {
+ clock format 4002847199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.784 {time zone boundary case 2096-11-04 01:00:00} {detroit y2038} {
+ clock format 4002847200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.785 {time zone boundary case 2096-11-04 01:00:01} {detroit y2038} {
+ clock format 4002847201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.786 {time zone boundary case 2097-03-10 01:59:59} {detroit y2038} {
+ clock format 4013737199 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.787 {time zone boundary case 2097-03-10 03:00:00} {detroit y2038} {
+ clock format 4013737200 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.788 {time zone boundary case 2097-03-10 03:00:01} {detroit y2038} {
+ clock format 4013737201 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.789 {time zone boundary case 2097-11-03 01:59:59} {detroit y2038} {
+ clock format 4034296799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.790 {time zone boundary case 2097-11-03 01:00:00} {detroit y2038} {
+ clock format 4034296800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.791 {time zone boundary case 2097-11-03 01:00:01} {detroit y2038} {
+ clock format 4034296801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.792 {time zone boundary case 2098-03-09 01:59:59} {detroit y2038} {
+ clock format 4045186799 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.793 {time zone boundary case 2098-03-09 03:00:00} {detroit y2038} {
+ clock format 4045186800 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.794 {time zone boundary case 2098-03-09 03:00:01} {detroit y2038} {
+ clock format 4045186801 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.795 {time zone boundary case 2098-11-02 01:59:59} {detroit y2038} {
+ clock format 4065746399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.796 {time zone boundary case 2098-11-02 01:00:00} {detroit y2038} {
+ clock format 4065746400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.797 {time zone boundary case 2098-11-02 01:00:01} {detroit y2038} {
+ clock format 4065746401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.798 {time zone boundary case 2099-03-08 01:59:59} {detroit y2038} {
+ clock format 4076636399 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.799 {time zone boundary case 2099-03-08 03:00:00} {detroit y2038} {
+ clock format 4076636400 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.800 {time zone boundary case 2099-03-08 03:00:01} {detroit y2038} {
+ clock format 4076636401 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.801 {time zone boundary case 2099-11-01 01:59:59} {detroit y2038} {
+ clock format 4097195999 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.802 {time zone boundary case 2099-11-01 01:00:00} {detroit y2038} {
+ clock format 4097196000 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.803 {time zone boundary case 2099-11-01 01:00:01} {detroit y2038} {
+ clock format 4097196001 -format {%H:%M:%S %z %Z} \
+ -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+# END testcases5
+
+# Test input conversions.
+
+test clock-6.0 {input of seconds} {
+ clock scan {-9223372036854775808} -format %s -gmt true
+} -9223372036854775808
+
+test clock-6.1 {input of seconds} {
+ clock scan {-2147483649} -format %s -gmt true
+} -2147483649
+
+test clock-6.2 {input of seconds} {
+ clock scan {-2147483648} -format %s -gmt true
+} -2147483648
+
+test clock-6.3 {input of seconds} {
+ clock scan {-1} -format %s -gmt true
+} -1
+
+test clock-6.4 {input of seconds} {
+ clock scan {0} -format %s -gmt true
+} 0
+
+test clock-6.5 {input of seconds} {
+ clock scan {1} -format %s -gmt true
+} 1
+
+test clock-6.6 {input of seconds} {
+ clock scan {2147483647} -format %s -gmt true
+} 2147483647
+
+test clock-6.7 {input of seconds} {
+ clock scan {2147483648} -format %s -gmt true
+} 2147483648
+
+test clock-6.8 {input of seconds} {
+ clock scan {9223372036854775807} -format %s -gmt true
+} 9223372036854775807
+
+test clock-6.9 {input of seconds - overflow} {
+ list [catch {clock scan -9223372036854775809 -format %s -gmt true} result] $result
+} {1 {integer value too large to represent}}
+
+test clock-6.10 {input of seconds - overflow} {
+ list [catch {clock scan 9223372036854775808 -format %s -gmt true} result] $result
+} {1 {integer value too large to represent}}
+
+test clock-6.11 {input of seconds - two values} {
+ clock scan {1 2} -format {%s %s} -gmt true
+} 2
+
+test clock-7.1 {Julian Day} {
+ clock scan 0 -format %J -gmt true
+} -210866803200
+
+test clock-7.2 {Julian Day} {
+ clock format [clock scan 2440588 -format %J -gmt true] \
+ -format %Y-%m-%d -gmt true
+} 1970-01-01
+
+test clock-7.3 {Julian Day} {
+ clock format [clock scan 2451545 -format %J -gmt true] \
+ -format %Y-%m-%d -gmt true
+} 2000-01-01
+
+test clock-7.3.1 {Julian Day} {
+ clock format [clock scan 2488070 -format %J -gmt true] \
+ -format %Y-%m-%d -gmt true
+} 2100-01-01
+
+test clock-7.4 {Julian Day} {
+ clock format [clock scan 5373484 -format %J -gmt true] \
+ -format %Y-%m-%d -gmt true
+} 9999-12-31
+
+test clock-7.5 {Julian Day, bad} {
+ list [catch {
+ clock scan bogus -format %J
+ } result] $result $errorCode
+} {1 {input string does not match supplied format} {CLOCK badInputString}}
+
+test clock-7.6 {Julian Day, overflow} {
+ list [catch {
+ clock scan 5373485 -format %J
+ } result] $result $errorCode
+} {1 {requested date too large to represent} {CLOCK dateTooLarge}}
+
+test clock-7.7 {Julian Day, overflow} {
+ list [catch {
+ clock scan 2147483648 -format %J
+ } result] $result $errorCode
+} {1 {requested date too large to represent} {CLOCK dateTooLarge}}
+
+test clock-7.8 {Julian Day, precedence below seconds} {
+ list [clock scan {2440588 86400} -format {%J %s} -gmt true] \
+ [clock scan {2440589 0} -format {%J %s} -gmt true] \
+ [clock scan {86400 2440588} -format {%s %J} -gmt true] \
+ [clock scan {0 2440589} -format {%s %J} -gmt true]
+} {86400 0 86400 0}
+
+test clock-7.9 {Julian Day, two values} {
+ clock scan {2440588 2440589} -format {%J %J} -gmt true
+} 86400
+
+# BEGIN testcases8
+
+# Test parsing of ccyymmdd
+
+test clock-8.1 {parse ccyymmdd} {
+ clock scan {1970 Jan 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.2 {parse ccyymmdd} {
+ clock scan {1970 Jan ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.3 {parse ccyymmdd} {
+ clock scan {1970 Jan 2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.4 {parse ccyymmdd} {
+ clock scan {1970 Jan ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.5 {parse ccyymmdd} {
+ clock scan {1970 January 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.6 {parse ccyymmdd} {
+ clock scan {1970 January ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.7 {parse ccyymmdd} {
+ clock scan {1970 January 2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.8 {parse ccyymmdd} {
+ clock scan {1970 January ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.9 {parse ccyymmdd} {
+ clock scan {1970 Jan 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.10 {parse ccyymmdd} {
+ clock scan {1970 Jan ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.11 {parse ccyymmdd} {
+ clock scan {1970 Jan 2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.12 {parse ccyymmdd} {
+ clock scan {1970 Jan ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.13 {parse ccyymmdd} {
+ clock scan {1970 01 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.14 {parse ccyymmdd} {
+ clock scan {1970 01 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.15 {parse ccyymmdd} {
+ clock scan {1970 01 2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.16 {parse ccyymmdd} {
+ clock scan {1970 01 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.17 {parse ccyymmdd} {
+ clock scan {1970 i 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.18 {parse ccyymmdd} {
+ clock scan {1970 i ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.19 {parse ccyymmdd} {
+ clock scan {1970 i 2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.20 {parse ccyymmdd} {
+ clock scan {1970 i ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.21 {parse ccyymmdd} {
+ clock scan {1970 1 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.22 {parse ccyymmdd} {
+ clock scan {1970 1 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.23 {parse ccyymmdd} {
+ clock scan {1970 1 2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.24 {parse ccyymmdd} {
+ clock scan {1970 1 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.25 {parse ccyymmdd} {
+ clock scan {1970 Jan 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.26 {parse ccyymmdd} {
+ clock scan {1970 Jan ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.27 {parse ccyymmdd} {
+ clock scan {1970 Jan 2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.28 {parse ccyymmdd} {
+ clock scan {1970 Jan ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.29 {parse ccyymmdd} {
+ clock scan {1970 January 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.30 {parse ccyymmdd} {
+ clock scan {1970 January ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.31 {parse ccyymmdd} {
+ clock scan {1970 January 2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.32 {parse ccyymmdd} {
+ clock scan {1970 January ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.33 {parse ccyymmdd} {
+ clock scan {1970 Jan 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.34 {parse ccyymmdd} {
+ clock scan {1970 Jan ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.35 {parse ccyymmdd} {
+ clock scan {1970 Jan 2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.36 {parse ccyymmdd} {
+ clock scan {1970 Jan ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.37 {parse ccyymmdd} {
+ clock scan {1970 01 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.38 {parse ccyymmdd} {
+ clock scan {1970 01 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.39 {parse ccyymmdd} {
+ clock scan {1970 01 2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.40 {parse ccyymmdd} {
+ clock scan {1970 01 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.41 {parse ccyymmdd} {
+ clock scan {1970 i 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.42 {parse ccyymmdd} {
+ clock scan {1970 i ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.43 {parse ccyymmdd} {
+ clock scan {1970 i 2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.44 {parse ccyymmdd} {
+ clock scan {1970 i ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.45 {parse ccyymmdd} {
+ clock scan {1970 1 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.46 {parse ccyymmdd} {
+ clock scan {1970 1 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.47 {parse ccyymmdd} {
+ clock scan {1970 1 2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.48 {parse ccyymmdd} {
+ clock scan {1970 1 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.49 {parse ccyymmdd} {
+ clock scan 01/02/1970 -format %x -locale en_US_roman -gmt 1
+} 86400
+test clock-8.50 {parse ccyymmdd} {
+ clock scan 01/02/1970 -format %D -locale en_US_roman -gmt 1
+} 86400
+test clock-8.51 {parse ccyymmdd} {
+ clock scan {1970 Jan 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.52 {parse ccyymmdd} {
+ clock scan {1970 Jan xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.53 {parse ccyymmdd} {
+ clock scan {1970 Jan 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.54 {parse ccyymmdd} {
+ clock scan {1970 Jan xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.55 {parse ccyymmdd} {
+ clock scan {1970 January 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.56 {parse ccyymmdd} {
+ clock scan {1970 January xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.57 {parse ccyymmdd} {
+ clock scan {1970 January 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.58 {parse ccyymmdd} {
+ clock scan {1970 January xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.59 {parse ccyymmdd} {
+ clock scan {1970 Jan 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.60 {parse ccyymmdd} {
+ clock scan {1970 Jan xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.61 {parse ccyymmdd} {
+ clock scan {1970 Jan 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.62 {parse ccyymmdd} {
+ clock scan {1970 Jan xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.63 {parse ccyymmdd} {
+ clock scan {1970 01 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.64 {parse ccyymmdd} {
+ clock scan {1970 01 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.65 {parse ccyymmdd} {
+ clock scan {1970 01 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.66 {parse ccyymmdd} {
+ clock scan {1970 01 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.67 {parse ccyymmdd} {
+ clock scan {1970 i 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.68 {parse ccyymmdd} {
+ clock scan {1970 i xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.69 {parse ccyymmdd} {
+ clock scan {1970 i 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.70 {parse ccyymmdd} {
+ clock scan {1970 i xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.71 {parse ccyymmdd} {
+ clock scan {1970 1 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.72 {parse ccyymmdd} {
+ clock scan {1970 1 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.73 {parse ccyymmdd} {
+ clock scan {1970 1 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.74 {parse ccyymmdd} {
+ clock scan {1970 1 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.75 {parse ccyymmdd} {
+ clock scan {1970 Jan 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.76 {parse ccyymmdd} {
+ clock scan {1970 Jan xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.77 {parse ccyymmdd} {
+ clock scan {1970 Jan 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.78 {parse ccyymmdd} {
+ clock scan {1970 Jan xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.79 {parse ccyymmdd} {
+ clock scan {1970 January 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.80 {parse ccyymmdd} {
+ clock scan {1970 January xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.81 {parse ccyymmdd} {
+ clock scan {1970 January 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.82 {parse ccyymmdd} {
+ clock scan {1970 January xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.83 {parse ccyymmdd} {
+ clock scan {1970 Jan 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.84 {parse ccyymmdd} {
+ clock scan {1970 Jan xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.85 {parse ccyymmdd} {
+ clock scan {1970 Jan 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.86 {parse ccyymmdd} {
+ clock scan {1970 Jan xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.87 {parse ccyymmdd} {
+ clock scan {1970 01 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.88 {parse ccyymmdd} {
+ clock scan {1970 01 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.89 {parse ccyymmdd} {
+ clock scan {1970 01 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.90 {parse ccyymmdd} {
+ clock scan {1970 01 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.91 {parse ccyymmdd} {
+ clock scan {1970 i 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.92 {parse ccyymmdd} {
+ clock scan {1970 i xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.93 {parse ccyymmdd} {
+ clock scan {1970 i 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.94 {parse ccyymmdd} {
+ clock scan {1970 i xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.95 {parse ccyymmdd} {
+ clock scan {1970 1 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.96 {parse ccyymmdd} {
+ clock scan {1970 1 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.97 {parse ccyymmdd} {
+ clock scan {1970 1 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.98 {parse ccyymmdd} {
+ clock scan {1970 1 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.99 {parse ccyymmdd} {
+ clock scan 01/31/1970 -format %x -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.100 {parse ccyymmdd} {
+ clock scan 01/31/1970 -format %D -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.101 {parse ccyymmdd} {
+ clock scan {1970 Dec 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.102 {parse ccyymmdd} {
+ clock scan {1970 Dec ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.103 {parse ccyymmdd} {
+ clock scan {1970 Dec 2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.104 {parse ccyymmdd} {
+ clock scan {1970 Dec ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.105 {parse ccyymmdd} {
+ clock scan {1970 December 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.106 {parse ccyymmdd} {
+ clock scan {1970 December ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.107 {parse ccyymmdd} {
+ clock scan {1970 December 2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.108 {parse ccyymmdd} {
+ clock scan {1970 December ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.109 {parse ccyymmdd} {
+ clock scan {1970 Dec 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.110 {parse ccyymmdd} {
+ clock scan {1970 Dec ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.111 {parse ccyymmdd} {
+ clock scan {1970 Dec 2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.112 {parse ccyymmdd} {
+ clock scan {1970 Dec ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.113 {parse ccyymmdd} {
+ clock scan {1970 12 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.114 {parse ccyymmdd} {
+ clock scan {1970 12 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.115 {parse ccyymmdd} {
+ clock scan {1970 12 2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.116 {parse ccyymmdd} {
+ clock scan {1970 12 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.117 {parse ccyymmdd} {
+ clock scan {1970 xii 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.118 {parse ccyymmdd} {
+ clock scan {1970 xii ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.119 {parse ccyymmdd} {
+ clock scan {1970 xii 2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.120 {parse ccyymmdd} {
+ clock scan {1970 xii ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.121 {parse ccyymmdd} {
+ clock scan {1970 12 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.122 {parse ccyymmdd} {
+ clock scan {1970 12 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.123 {parse ccyymmdd} {
+ clock scan {1970 12 2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.124 {parse ccyymmdd} {
+ clock scan {1970 12 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.125 {parse ccyymmdd} {
+ clock scan {1970 Dec 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.126 {parse ccyymmdd} {
+ clock scan {1970 Dec ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.127 {parse ccyymmdd} {
+ clock scan {1970 Dec 2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.128 {parse ccyymmdd} {
+ clock scan {1970 Dec ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.129 {parse ccyymmdd} {
+ clock scan {1970 December 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.130 {parse ccyymmdd} {
+ clock scan {1970 December ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.131 {parse ccyymmdd} {
+ clock scan {1970 December 2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.132 {parse ccyymmdd} {
+ clock scan {1970 December ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.133 {parse ccyymmdd} {
+ clock scan {1970 Dec 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.134 {parse ccyymmdd} {
+ clock scan {1970 Dec ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.135 {parse ccyymmdd} {
+ clock scan {1970 Dec 2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.136 {parse ccyymmdd} {
+ clock scan {1970 Dec ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.137 {parse ccyymmdd} {
+ clock scan {1970 12 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.138 {parse ccyymmdd} {
+ clock scan {1970 12 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.139 {parse ccyymmdd} {
+ clock scan {1970 12 2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.140 {parse ccyymmdd} {
+ clock scan {1970 12 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.141 {parse ccyymmdd} {
+ clock scan {1970 xii 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.142 {parse ccyymmdd} {
+ clock scan {1970 xii ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.143 {parse ccyymmdd} {
+ clock scan {1970 xii 2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.144 {parse ccyymmdd} {
+ clock scan {1970 xii ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.145 {parse ccyymmdd} {
+ clock scan {1970 12 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.146 {parse ccyymmdd} {
+ clock scan {1970 12 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.147 {parse ccyymmdd} {
+ clock scan {1970 12 2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.148 {parse ccyymmdd} {
+ clock scan {1970 12 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.149 {parse ccyymmdd} {
+ clock scan 12/02/1970 -format %x -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.150 {parse ccyymmdd} {
+ clock scan 12/02/1970 -format %D -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.151 {parse ccyymmdd} {
+ clock scan {1970 Dec 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.152 {parse ccyymmdd} {
+ clock scan {1970 Dec xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.153 {parse ccyymmdd} {
+ clock scan {1970 Dec 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.154 {parse ccyymmdd} {
+ clock scan {1970 Dec xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.155 {parse ccyymmdd} {
+ clock scan {1970 December 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.156 {parse ccyymmdd} {
+ clock scan {1970 December xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.157 {parse ccyymmdd} {
+ clock scan {1970 December 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.158 {parse ccyymmdd} {
+ clock scan {1970 December xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.159 {parse ccyymmdd} {
+ clock scan {1970 Dec 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.160 {parse ccyymmdd} {
+ clock scan {1970 Dec xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.161 {parse ccyymmdd} {
+ clock scan {1970 Dec 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.162 {parse ccyymmdd} {
+ clock scan {1970 Dec xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.163 {parse ccyymmdd} {
+ clock scan {1970 12 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.164 {parse ccyymmdd} {
+ clock scan {1970 12 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.165 {parse ccyymmdd} {
+ clock scan {1970 12 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.166 {parse ccyymmdd} {
+ clock scan {1970 12 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.167 {parse ccyymmdd} {
+ clock scan {1970 xii 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.168 {parse ccyymmdd} {
+ clock scan {1970 xii xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.169 {parse ccyymmdd} {
+ clock scan {1970 xii 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.170 {parse ccyymmdd} {
+ clock scan {1970 xii xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.171 {parse ccyymmdd} {
+ clock scan {1970 12 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.172 {parse ccyymmdd} {
+ clock scan {1970 12 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.173 {parse ccyymmdd} {
+ clock scan {1970 12 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.174 {parse ccyymmdd} {
+ clock scan {1970 12 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.175 {parse ccyymmdd} {
+ clock scan {1970 Dec 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.176 {parse ccyymmdd} {
+ clock scan {1970 Dec xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.177 {parse ccyymmdd} {
+ clock scan {1970 Dec 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.178 {parse ccyymmdd} {
+ clock scan {1970 Dec xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.179 {parse ccyymmdd} {
+ clock scan {1970 December 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.180 {parse ccyymmdd} {
+ clock scan {1970 December xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.181 {parse ccyymmdd} {
+ clock scan {1970 December 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.182 {parse ccyymmdd} {
+ clock scan {1970 December xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.183 {parse ccyymmdd} {
+ clock scan {1970 Dec 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.184 {parse ccyymmdd} {
+ clock scan {1970 Dec xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.185 {parse ccyymmdd} {
+ clock scan {1970 Dec 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.186 {parse ccyymmdd} {
+ clock scan {1970 Dec xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.187 {parse ccyymmdd} {
+ clock scan {1970 12 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.188 {parse ccyymmdd} {
+ clock scan {1970 12 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.189 {parse ccyymmdd} {
+ clock scan {1970 12 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.190 {parse ccyymmdd} {
+ clock scan {1970 12 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.191 {parse ccyymmdd} {
+ clock scan {1970 xii 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.192 {parse ccyymmdd} {
+ clock scan {1970 xii xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.193 {parse ccyymmdd} {
+ clock scan {1970 xii 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.194 {parse ccyymmdd} {
+ clock scan {1970 xii xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.195 {parse ccyymmdd} {
+ clock scan {1970 12 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.196 {parse ccyymmdd} {
+ clock scan {1970 12 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.197 {parse ccyymmdd} {
+ clock scan {1970 12 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.198 {parse ccyymmdd} {
+ clock scan {1970 12 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.199 {parse ccyymmdd} {
+ clock scan 12/31/1970 -format %x -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.200 {parse ccyymmdd} {
+ clock scan 12/31/1970 -format %D -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.201 {parse ccyymmdd} {
+ clock scan {1971 Jan 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.202 {parse ccyymmdd} {
+ clock scan {1971 Jan ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.203 {parse ccyymmdd} {
+ clock scan {1971 Jan 2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.204 {parse ccyymmdd} {
+ clock scan {1971 Jan ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.205 {parse ccyymmdd} {
+ clock scan {1971 January 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.206 {parse ccyymmdd} {
+ clock scan {1971 January ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.207 {parse ccyymmdd} {
+ clock scan {1971 January 2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.208 {parse ccyymmdd} {
+ clock scan {1971 January ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.209 {parse ccyymmdd} {
+ clock scan {1971 Jan 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.210 {parse ccyymmdd} {
+ clock scan {1971 Jan ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.211 {parse ccyymmdd} {
+ clock scan {1971 Jan 2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.212 {parse ccyymmdd} {
+ clock scan {1971 Jan ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.213 {parse ccyymmdd} {
+ clock scan {1971 01 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.214 {parse ccyymmdd} {
+ clock scan {1971 01 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.215 {parse ccyymmdd} {
+ clock scan {1971 01 2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.216 {parse ccyymmdd} {
+ clock scan {1971 01 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.217 {parse ccyymmdd} {
+ clock scan {1971 i 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.218 {parse ccyymmdd} {
+ clock scan {1971 i ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.219 {parse ccyymmdd} {
+ clock scan {1971 i 2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.220 {parse ccyymmdd} {
+ clock scan {1971 i ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.221 {parse ccyymmdd} {
+ clock scan {1971 1 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.222 {parse ccyymmdd} {
+ clock scan {1971 1 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.223 {parse ccyymmdd} {
+ clock scan {1971 1 2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.224 {parse ccyymmdd} {
+ clock scan {1971 1 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.225 {parse ccyymmdd} {
+ clock scan {1971 Jan 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.226 {parse ccyymmdd} {
+ clock scan {1971 Jan ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.227 {parse ccyymmdd} {
+ clock scan {1971 Jan 2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.228 {parse ccyymmdd} {
+ clock scan {1971 Jan ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.229 {parse ccyymmdd} {
+ clock scan {1971 January 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.230 {parse ccyymmdd} {
+ clock scan {1971 January ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.231 {parse ccyymmdd} {
+ clock scan {1971 January 2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.232 {parse ccyymmdd} {
+ clock scan {1971 January ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.233 {parse ccyymmdd} {
+ clock scan {1971 Jan 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.234 {parse ccyymmdd} {
+ clock scan {1971 Jan ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.235 {parse ccyymmdd} {
+ clock scan {1971 Jan 2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.236 {parse ccyymmdd} {
+ clock scan {1971 Jan ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.237 {parse ccyymmdd} {
+ clock scan {1971 01 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.238 {parse ccyymmdd} {
+ clock scan {1971 01 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.239 {parse ccyymmdd} {
+ clock scan {1971 01 2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.240 {parse ccyymmdd} {
+ clock scan {1971 01 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.241 {parse ccyymmdd} {
+ clock scan {1971 i 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.242 {parse ccyymmdd} {
+ clock scan {1971 i ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.243 {parse ccyymmdd} {
+ clock scan {1971 i 2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.244 {parse ccyymmdd} {
+ clock scan {1971 i ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.245 {parse ccyymmdd} {
+ clock scan {1971 1 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.246 {parse ccyymmdd} {
+ clock scan {1971 1 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.247 {parse ccyymmdd} {
+ clock scan {1971 1 2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.248 {parse ccyymmdd} {
+ clock scan {1971 1 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.249 {parse ccyymmdd} {
+ clock scan 01/02/1971 -format %x -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.250 {parse ccyymmdd} {
+ clock scan 01/02/1971 -format %D -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.251 {parse ccyymmdd} {
+ clock scan {1971 Jan 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.252 {parse ccyymmdd} {
+ clock scan {1971 Jan xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.253 {parse ccyymmdd} {
+ clock scan {1971 Jan 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.254 {parse ccyymmdd} {
+ clock scan {1971 Jan xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.255 {parse ccyymmdd} {
+ clock scan {1971 January 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.256 {parse ccyymmdd} {
+ clock scan {1971 January xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.257 {parse ccyymmdd} {
+ clock scan {1971 January 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.258 {parse ccyymmdd} {
+ clock scan {1971 January xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.259 {parse ccyymmdd} {
+ clock scan {1971 Jan 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.260 {parse ccyymmdd} {
+ clock scan {1971 Jan xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.261 {parse ccyymmdd} {
+ clock scan {1971 Jan 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.262 {parse ccyymmdd} {
+ clock scan {1971 Jan xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.263 {parse ccyymmdd} {
+ clock scan {1971 01 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.264 {parse ccyymmdd} {
+ clock scan {1971 01 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.265 {parse ccyymmdd} {
+ clock scan {1971 01 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.266 {parse ccyymmdd} {
+ clock scan {1971 01 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.267 {parse ccyymmdd} {
+ clock scan {1971 i 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.268 {parse ccyymmdd} {
+ clock scan {1971 i xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.269 {parse ccyymmdd} {
+ clock scan {1971 i 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.270 {parse ccyymmdd} {
+ clock scan {1971 i xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.271 {parse ccyymmdd} {
+ clock scan {1971 1 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.272 {parse ccyymmdd} {
+ clock scan {1971 1 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.273 {parse ccyymmdd} {
+ clock scan {1971 1 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.274 {parse ccyymmdd} {
+ clock scan {1971 1 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.275 {parse ccyymmdd} {
+ clock scan {1971 Jan 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.276 {parse ccyymmdd} {
+ clock scan {1971 Jan xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.277 {parse ccyymmdd} {
+ clock scan {1971 Jan 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.278 {parse ccyymmdd} {
+ clock scan {1971 Jan xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.279 {parse ccyymmdd} {
+ clock scan {1971 January 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.280 {parse ccyymmdd} {
+ clock scan {1971 January xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.281 {parse ccyymmdd} {
+ clock scan {1971 January 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.282 {parse ccyymmdd} {
+ clock scan {1971 January xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.283 {parse ccyymmdd} {
+ clock scan {1971 Jan 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.284 {parse ccyymmdd} {
+ clock scan {1971 Jan xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.285 {parse ccyymmdd} {
+ clock scan {1971 Jan 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.286 {parse ccyymmdd} {
+ clock scan {1971 Jan xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.287 {parse ccyymmdd} {
+ clock scan {1971 01 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.288 {parse ccyymmdd} {
+ clock scan {1971 01 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.289 {parse ccyymmdd} {
+ clock scan {1971 01 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.290 {parse ccyymmdd} {
+ clock scan {1971 01 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.291 {parse ccyymmdd} {
+ clock scan {1971 i 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.292 {parse ccyymmdd} {
+ clock scan {1971 i xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.293 {parse ccyymmdd} {
+ clock scan {1971 i 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.294 {parse ccyymmdd} {
+ clock scan {1971 i xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.295 {parse ccyymmdd} {
+ clock scan {1971 1 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.296 {parse ccyymmdd} {
+ clock scan {1971 1 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.297 {parse ccyymmdd} {
+ clock scan {1971 1 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.298 {parse ccyymmdd} {
+ clock scan {1971 1 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.299 {parse ccyymmdd} {
+ clock scan 01/31/1971 -format %x -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.300 {parse ccyymmdd} {
+ clock scan 01/31/1971 -format %D -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.301 {parse ccyymmdd} {
+ clock scan {1971 Dec 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.302 {parse ccyymmdd} {
+ clock scan {1971 Dec ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.303 {parse ccyymmdd} {
+ clock scan {1971 Dec 2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.304 {parse ccyymmdd} {
+ clock scan {1971 Dec ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.305 {parse ccyymmdd} {
+ clock scan {1971 December 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.306 {parse ccyymmdd} {
+ clock scan {1971 December ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.307 {parse ccyymmdd} {
+ clock scan {1971 December 2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.308 {parse ccyymmdd} {
+ clock scan {1971 December ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.309 {parse ccyymmdd} {
+ clock scan {1971 Dec 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.310 {parse ccyymmdd} {
+ clock scan {1971 Dec ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.311 {parse ccyymmdd} {
+ clock scan {1971 Dec 2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.312 {parse ccyymmdd} {
+ clock scan {1971 Dec ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.313 {parse ccyymmdd} {
+ clock scan {1971 12 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.314 {parse ccyymmdd} {
+ clock scan {1971 12 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.315 {parse ccyymmdd} {
+ clock scan {1971 12 2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.316 {parse ccyymmdd} {
+ clock scan {1971 12 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.317 {parse ccyymmdd} {
+ clock scan {1971 xii 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.318 {parse ccyymmdd} {
+ clock scan {1971 xii ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.319 {parse ccyymmdd} {
+ clock scan {1971 xii 2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.320 {parse ccyymmdd} {
+ clock scan {1971 xii ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.321 {parse ccyymmdd} {
+ clock scan {1971 12 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.322 {parse ccyymmdd} {
+ clock scan {1971 12 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.323 {parse ccyymmdd} {
+ clock scan {1971 12 2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.324 {parse ccyymmdd} {
+ clock scan {1971 12 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.325 {parse ccyymmdd} {
+ clock scan {1971 Dec 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.326 {parse ccyymmdd} {
+ clock scan {1971 Dec ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.327 {parse ccyymmdd} {
+ clock scan {1971 Dec 2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.328 {parse ccyymmdd} {
+ clock scan {1971 Dec ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.329 {parse ccyymmdd} {
+ clock scan {1971 December 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.330 {parse ccyymmdd} {
+ clock scan {1971 December ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.331 {parse ccyymmdd} {
+ clock scan {1971 December 2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.332 {parse ccyymmdd} {
+ clock scan {1971 December ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.333 {parse ccyymmdd} {
+ clock scan {1971 Dec 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.334 {parse ccyymmdd} {
+ clock scan {1971 Dec ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.335 {parse ccyymmdd} {
+ clock scan {1971 Dec 2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.336 {parse ccyymmdd} {
+ clock scan {1971 Dec ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.337 {parse ccyymmdd} {
+ clock scan {1971 12 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.338 {parse ccyymmdd} {
+ clock scan {1971 12 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.339 {parse ccyymmdd} {
+ clock scan {1971 12 2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.340 {parse ccyymmdd} {
+ clock scan {1971 12 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.341 {parse ccyymmdd} {
+ clock scan {1971 xii 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.342 {parse ccyymmdd} {
+ clock scan {1971 xii ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.343 {parse ccyymmdd} {
+ clock scan {1971 xii 2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.344 {parse ccyymmdd} {
+ clock scan {1971 xii ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.345 {parse ccyymmdd} {
+ clock scan {1971 12 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.346 {parse ccyymmdd} {
+ clock scan {1971 12 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.347 {parse ccyymmdd} {
+ clock scan {1971 12 2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.348 {parse ccyymmdd} {
+ clock scan {1971 12 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.349 {parse ccyymmdd} {
+ clock scan 12/02/1971 -format %x -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.350 {parse ccyymmdd} {
+ clock scan 12/02/1971 -format %D -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.351 {parse ccyymmdd} {
+ clock scan {1971 Dec 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.352 {parse ccyymmdd} {
+ clock scan {1971 Dec xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.353 {parse ccyymmdd} {
+ clock scan {1971 Dec 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.354 {parse ccyymmdd} {
+ clock scan {1971 Dec xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.355 {parse ccyymmdd} {
+ clock scan {1971 December 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.356 {parse ccyymmdd} {
+ clock scan {1971 December xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.357 {parse ccyymmdd} {
+ clock scan {1971 December 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.358 {parse ccyymmdd} {
+ clock scan {1971 December xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.359 {parse ccyymmdd} {
+ clock scan {1971 Dec 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.360 {parse ccyymmdd} {
+ clock scan {1971 Dec xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.361 {parse ccyymmdd} {
+ clock scan {1971 Dec 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.362 {parse ccyymmdd} {
+ clock scan {1971 Dec xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.363 {parse ccyymmdd} {
+ clock scan {1971 12 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.364 {parse ccyymmdd} {
+ clock scan {1971 12 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.365 {parse ccyymmdd} {
+ clock scan {1971 12 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.366 {parse ccyymmdd} {
+ clock scan {1971 12 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.367 {parse ccyymmdd} {
+ clock scan {1971 xii 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.368 {parse ccyymmdd} {
+ clock scan {1971 xii xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.369 {parse ccyymmdd} {
+ clock scan {1971 xii 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.370 {parse ccyymmdd} {
+ clock scan {1971 xii xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.371 {parse ccyymmdd} {
+ clock scan {1971 12 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.372 {parse ccyymmdd} {
+ clock scan {1971 12 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.373 {parse ccyymmdd} {
+ clock scan {1971 12 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.374 {parse ccyymmdd} {
+ clock scan {1971 12 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.375 {parse ccyymmdd} {
+ clock scan {1971 Dec 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.376 {parse ccyymmdd} {
+ clock scan {1971 Dec xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.377 {parse ccyymmdd} {
+ clock scan {1971 Dec 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.378 {parse ccyymmdd} {
+ clock scan {1971 Dec xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.379 {parse ccyymmdd} {
+ clock scan {1971 December 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.380 {parse ccyymmdd} {
+ clock scan {1971 December xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.381 {parse ccyymmdd} {
+ clock scan {1971 December 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.382 {parse ccyymmdd} {
+ clock scan {1971 December xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.383 {parse ccyymmdd} {
+ clock scan {1971 Dec 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.384 {parse ccyymmdd} {
+ clock scan {1971 Dec xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.385 {parse ccyymmdd} {
+ clock scan {1971 Dec 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.386 {parse ccyymmdd} {
+ clock scan {1971 Dec xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.387 {parse ccyymmdd} {
+ clock scan {1971 12 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.388 {parse ccyymmdd} {
+ clock scan {1971 12 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.389 {parse ccyymmdd} {
+ clock scan {1971 12 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.390 {parse ccyymmdd} {
+ clock scan {1971 12 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.391 {parse ccyymmdd} {
+ clock scan {1971 xii 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.392 {parse ccyymmdd} {
+ clock scan {1971 xii xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.393 {parse ccyymmdd} {
+ clock scan {1971 xii 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.394 {parse ccyymmdd} {
+ clock scan {1971 xii xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.395 {parse ccyymmdd} {
+ clock scan {1971 12 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.396 {parse ccyymmdd} {
+ clock scan {1971 12 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.397 {parse ccyymmdd} {
+ clock scan {1971 12 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.398 {parse ccyymmdd} {
+ clock scan {1971 12 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.399 {parse ccyymmdd} {
+ clock scan 12/31/1971 -format %x -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.400 {parse ccyymmdd} {
+ clock scan 12/31/1971 -format %D -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.401 {parse ccyymmdd} {
+ clock scan {2000 Jan 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.402 {parse ccyymmdd} {
+ clock scan {2000 Jan ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.403 {parse ccyymmdd} {
+ clock scan {2000 Jan 2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.404 {parse ccyymmdd} {
+ clock scan {2000 Jan ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.405 {parse ccyymmdd} {
+ clock scan {2000 January 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.406 {parse ccyymmdd} {
+ clock scan {2000 January ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.407 {parse ccyymmdd} {
+ clock scan {2000 January 2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.408 {parse ccyymmdd} {
+ clock scan {2000 January ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.409 {parse ccyymmdd} {
+ clock scan {2000 Jan 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.410 {parse ccyymmdd} {
+ clock scan {2000 Jan ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.411 {parse ccyymmdd} {
+ clock scan {2000 Jan 2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.412 {parse ccyymmdd} {
+ clock scan {2000 Jan ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.413 {parse ccyymmdd} {
+ clock scan {2000 01 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.414 {parse ccyymmdd} {
+ clock scan {2000 01 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.415 {parse ccyymmdd} {
+ clock scan {2000 01 2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.416 {parse ccyymmdd} {
+ clock scan {2000 01 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.417 {parse ccyymmdd} {
+ clock scan {2000 i 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.418 {parse ccyymmdd} {
+ clock scan {2000 i ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.419 {parse ccyymmdd} {
+ clock scan {2000 i 2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.420 {parse ccyymmdd} {
+ clock scan {2000 i ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.421 {parse ccyymmdd} {
+ clock scan {2000 1 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.422 {parse ccyymmdd} {
+ clock scan {2000 1 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.423 {parse ccyymmdd} {
+ clock scan {2000 1 2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.424 {parse ccyymmdd} {
+ clock scan {2000 1 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.425 {parse ccyymmdd} {
+ clock scan {2000 Jan 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.426 {parse ccyymmdd} {
+ clock scan {2000 Jan ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.427 {parse ccyymmdd} {
+ clock scan {2000 Jan 2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.428 {parse ccyymmdd} {
+ clock scan {2000 Jan ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.429 {parse ccyymmdd} {
+ clock scan {2000 January 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.430 {parse ccyymmdd} {
+ clock scan {2000 January ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.431 {parse ccyymmdd} {
+ clock scan {2000 January 2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.432 {parse ccyymmdd} {
+ clock scan {2000 January ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.433 {parse ccyymmdd} {
+ clock scan {2000 Jan 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.434 {parse ccyymmdd} {
+ clock scan {2000 Jan ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.435 {parse ccyymmdd} {
+ clock scan {2000 Jan 2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.436 {parse ccyymmdd} {
+ clock scan {2000 Jan ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.437 {parse ccyymmdd} {
+ clock scan {2000 01 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.438 {parse ccyymmdd} {
+ clock scan {2000 01 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.439 {parse ccyymmdd} {
+ clock scan {2000 01 2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.440 {parse ccyymmdd} {
+ clock scan {2000 01 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.441 {parse ccyymmdd} {
+ clock scan {2000 i 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.442 {parse ccyymmdd} {
+ clock scan {2000 i ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.443 {parse ccyymmdd} {
+ clock scan {2000 i 2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.444 {parse ccyymmdd} {
+ clock scan {2000 i ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.445 {parse ccyymmdd} {
+ clock scan {2000 1 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.446 {parse ccyymmdd} {
+ clock scan {2000 1 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.447 {parse ccyymmdd} {
+ clock scan {2000 1 2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.448 {parse ccyymmdd} {
+ clock scan {2000 1 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.449 {parse ccyymmdd} {
+ clock scan 01/02/2000 -format %x -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.450 {parse ccyymmdd} {
+ clock scan 01/02/2000 -format %D -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.451 {parse ccyymmdd} {
+ clock scan {2000 Jan 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.452 {parse ccyymmdd} {
+ clock scan {2000 Jan xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.453 {parse ccyymmdd} {
+ clock scan {2000 Jan 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.454 {parse ccyymmdd} {
+ clock scan {2000 Jan xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.455 {parse ccyymmdd} {
+ clock scan {2000 January 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.456 {parse ccyymmdd} {
+ clock scan {2000 January xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.457 {parse ccyymmdd} {
+ clock scan {2000 January 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.458 {parse ccyymmdd} {
+ clock scan {2000 January xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.459 {parse ccyymmdd} {
+ clock scan {2000 Jan 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.460 {parse ccyymmdd} {
+ clock scan {2000 Jan xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.461 {parse ccyymmdd} {
+ clock scan {2000 Jan 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.462 {parse ccyymmdd} {
+ clock scan {2000 Jan xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.463 {parse ccyymmdd} {
+ clock scan {2000 01 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.464 {parse ccyymmdd} {
+ clock scan {2000 01 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.465 {parse ccyymmdd} {
+ clock scan {2000 01 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.466 {parse ccyymmdd} {
+ clock scan {2000 01 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.467 {parse ccyymmdd} {
+ clock scan {2000 i 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.468 {parse ccyymmdd} {
+ clock scan {2000 i xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.469 {parse ccyymmdd} {
+ clock scan {2000 i 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.470 {parse ccyymmdd} {
+ clock scan {2000 i xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.471 {parse ccyymmdd} {
+ clock scan {2000 1 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.472 {parse ccyymmdd} {
+ clock scan {2000 1 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.473 {parse ccyymmdd} {
+ clock scan {2000 1 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.474 {parse ccyymmdd} {
+ clock scan {2000 1 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.475 {parse ccyymmdd} {
+ clock scan {2000 Jan 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.476 {parse ccyymmdd} {
+ clock scan {2000 Jan xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.477 {parse ccyymmdd} {
+ clock scan {2000 Jan 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.478 {parse ccyymmdd} {
+ clock scan {2000 Jan xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.479 {parse ccyymmdd} {
+ clock scan {2000 January 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.480 {parse ccyymmdd} {
+ clock scan {2000 January xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.481 {parse ccyymmdd} {
+ clock scan {2000 January 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.482 {parse ccyymmdd} {
+ clock scan {2000 January xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.483 {parse ccyymmdd} {
+ clock scan {2000 Jan 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.484 {parse ccyymmdd} {
+ clock scan {2000 Jan xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.485 {parse ccyymmdd} {
+ clock scan {2000 Jan 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.486 {parse ccyymmdd} {
+ clock scan {2000 Jan xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.487 {parse ccyymmdd} {
+ clock scan {2000 01 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.488 {parse ccyymmdd} {
+ clock scan {2000 01 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.489 {parse ccyymmdd} {
+ clock scan {2000 01 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.490 {parse ccyymmdd} {
+ clock scan {2000 01 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.491 {parse ccyymmdd} {
+ clock scan {2000 i 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.492 {parse ccyymmdd} {
+ clock scan {2000 i xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.493 {parse ccyymmdd} {
+ clock scan {2000 i 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.494 {parse ccyymmdd} {
+ clock scan {2000 i xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.495 {parse ccyymmdd} {
+ clock scan {2000 1 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.496 {parse ccyymmdd} {
+ clock scan {2000 1 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.497 {parse ccyymmdd} {
+ clock scan {2000 1 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.498 {parse ccyymmdd} {
+ clock scan {2000 1 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.499 {parse ccyymmdd} {
+ clock scan 01/31/2000 -format %x -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.500 {parse ccyymmdd} {
+ clock scan 01/31/2000 -format %D -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.501 {parse ccyymmdd} {
+ clock scan {2000 Dec 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.502 {parse ccyymmdd} {
+ clock scan {2000 Dec ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.503 {parse ccyymmdd} {
+ clock scan {2000 Dec 2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.504 {parse ccyymmdd} {
+ clock scan {2000 Dec ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.505 {parse ccyymmdd} {
+ clock scan {2000 December 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.506 {parse ccyymmdd} {
+ clock scan {2000 December ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.507 {parse ccyymmdd} {
+ clock scan {2000 December 2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.508 {parse ccyymmdd} {
+ clock scan {2000 December ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.509 {parse ccyymmdd} {
+ clock scan {2000 Dec 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.510 {parse ccyymmdd} {
+ clock scan {2000 Dec ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.511 {parse ccyymmdd} {
+ clock scan {2000 Dec 2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.512 {parse ccyymmdd} {
+ clock scan {2000 Dec ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.513 {parse ccyymmdd} {
+ clock scan {2000 12 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.514 {parse ccyymmdd} {
+ clock scan {2000 12 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.515 {parse ccyymmdd} {
+ clock scan {2000 12 2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.516 {parse ccyymmdd} {
+ clock scan {2000 12 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.517 {parse ccyymmdd} {
+ clock scan {2000 xii 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.518 {parse ccyymmdd} {
+ clock scan {2000 xii ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.519 {parse ccyymmdd} {
+ clock scan {2000 xii 2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.520 {parse ccyymmdd} {
+ clock scan {2000 xii ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.521 {parse ccyymmdd} {
+ clock scan {2000 12 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.522 {parse ccyymmdd} {
+ clock scan {2000 12 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.523 {parse ccyymmdd} {
+ clock scan {2000 12 2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.524 {parse ccyymmdd} {
+ clock scan {2000 12 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.525 {parse ccyymmdd} {
+ clock scan {2000 Dec 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.526 {parse ccyymmdd} {
+ clock scan {2000 Dec ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.527 {parse ccyymmdd} {
+ clock scan {2000 Dec 2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.528 {parse ccyymmdd} {
+ clock scan {2000 Dec ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.529 {parse ccyymmdd} {
+ clock scan {2000 December 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.530 {parse ccyymmdd} {
+ clock scan {2000 December ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.531 {parse ccyymmdd} {
+ clock scan {2000 December 2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.532 {parse ccyymmdd} {
+ clock scan {2000 December ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.533 {parse ccyymmdd} {
+ clock scan {2000 Dec 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.534 {parse ccyymmdd} {
+ clock scan {2000 Dec ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.535 {parse ccyymmdd} {
+ clock scan {2000 Dec 2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.536 {parse ccyymmdd} {
+ clock scan {2000 Dec ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.537 {parse ccyymmdd} {
+ clock scan {2000 12 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.538 {parse ccyymmdd} {
+ clock scan {2000 12 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.539 {parse ccyymmdd} {
+ clock scan {2000 12 2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.540 {parse ccyymmdd} {
+ clock scan {2000 12 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.541 {parse ccyymmdd} {
+ clock scan {2000 xii 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.542 {parse ccyymmdd} {
+ clock scan {2000 xii ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.543 {parse ccyymmdd} {
+ clock scan {2000 xii 2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.544 {parse ccyymmdd} {
+ clock scan {2000 xii ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.545 {parse ccyymmdd} {
+ clock scan {2000 12 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.546 {parse ccyymmdd} {
+ clock scan {2000 12 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.547 {parse ccyymmdd} {
+ clock scan {2000 12 2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.548 {parse ccyymmdd} {
+ clock scan {2000 12 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.549 {parse ccyymmdd} {
+ clock scan 12/02/2000 -format %x -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.550 {parse ccyymmdd} {
+ clock scan 12/02/2000 -format %D -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.551 {parse ccyymmdd} {
+ clock scan {2000 Dec 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.552 {parse ccyymmdd} {
+ clock scan {2000 Dec xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.553 {parse ccyymmdd} {
+ clock scan {2000 Dec 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.554 {parse ccyymmdd} {
+ clock scan {2000 Dec xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.555 {parse ccyymmdd} {
+ clock scan {2000 December 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.556 {parse ccyymmdd} {
+ clock scan {2000 December xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.557 {parse ccyymmdd} {
+ clock scan {2000 December 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.558 {parse ccyymmdd} {
+ clock scan {2000 December xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.559 {parse ccyymmdd} {
+ clock scan {2000 Dec 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.560 {parse ccyymmdd} {
+ clock scan {2000 Dec xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.561 {parse ccyymmdd} {
+ clock scan {2000 Dec 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.562 {parse ccyymmdd} {
+ clock scan {2000 Dec xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.563 {parse ccyymmdd} {
+ clock scan {2000 12 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.564 {parse ccyymmdd} {
+ clock scan {2000 12 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.565 {parse ccyymmdd} {
+ clock scan {2000 12 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.566 {parse ccyymmdd} {
+ clock scan {2000 12 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.567 {parse ccyymmdd} {
+ clock scan {2000 xii 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.568 {parse ccyymmdd} {
+ clock scan {2000 xii xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.569 {parse ccyymmdd} {
+ clock scan {2000 xii 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.570 {parse ccyymmdd} {
+ clock scan {2000 xii xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.571 {parse ccyymmdd} {
+ clock scan {2000 12 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.572 {parse ccyymmdd} {
+ clock scan {2000 12 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.573 {parse ccyymmdd} {
+ clock scan {2000 12 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.574 {parse ccyymmdd} {
+ clock scan {2000 12 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.575 {parse ccyymmdd} {
+ clock scan {2000 Dec 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.576 {parse ccyymmdd} {
+ clock scan {2000 Dec xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.577 {parse ccyymmdd} {
+ clock scan {2000 Dec 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.578 {parse ccyymmdd} {
+ clock scan {2000 Dec xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.579 {parse ccyymmdd} {
+ clock scan {2000 December 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.580 {parse ccyymmdd} {
+ clock scan {2000 December xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.581 {parse ccyymmdd} {
+ clock scan {2000 December 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.582 {parse ccyymmdd} {
+ clock scan {2000 December xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.583 {parse ccyymmdd} {
+ clock scan {2000 Dec 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.584 {parse ccyymmdd} {
+ clock scan {2000 Dec xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.585 {parse ccyymmdd} {
+ clock scan {2000 Dec 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.586 {parse ccyymmdd} {
+ clock scan {2000 Dec xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.587 {parse ccyymmdd} {
+ clock scan {2000 12 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.588 {parse ccyymmdd} {
+ clock scan {2000 12 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.589 {parse ccyymmdd} {
+ clock scan {2000 12 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.590 {parse ccyymmdd} {
+ clock scan {2000 12 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.591 {parse ccyymmdd} {
+ clock scan {2000 xii 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.592 {parse ccyymmdd} {
+ clock scan {2000 xii xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.593 {parse ccyymmdd} {
+ clock scan {2000 xii 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.594 {parse ccyymmdd} {
+ clock scan {2000 xii xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.595 {parse ccyymmdd} {
+ clock scan {2000 12 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.596 {parse ccyymmdd} {
+ clock scan {2000 12 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.597 {parse ccyymmdd} {
+ clock scan {2000 12 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.598 {parse ccyymmdd} {
+ clock scan {2000 12 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.599 {parse ccyymmdd} {
+ clock scan 12/31/2000 -format %x -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.600 {parse ccyymmdd} {
+ clock scan 12/31/2000 -format %D -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.601 {parse ccyymmdd} {
+ clock scan {2001 Jan 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.602 {parse ccyymmdd} {
+ clock scan {2001 Jan ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.603 {parse ccyymmdd} {
+ clock scan {2001 Jan 2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.604 {parse ccyymmdd} {
+ clock scan {2001 Jan ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.605 {parse ccyymmdd} {
+ clock scan {2001 January 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.606 {parse ccyymmdd} {
+ clock scan {2001 January ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.607 {parse ccyymmdd} {
+ clock scan {2001 January 2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.608 {parse ccyymmdd} {
+ clock scan {2001 January ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.609 {parse ccyymmdd} {
+ clock scan {2001 Jan 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.610 {parse ccyymmdd} {
+ clock scan {2001 Jan ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.611 {parse ccyymmdd} {
+ clock scan {2001 Jan 2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.612 {parse ccyymmdd} {
+ clock scan {2001 Jan ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.613 {parse ccyymmdd} {
+ clock scan {2001 01 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.614 {parse ccyymmdd} {
+ clock scan {2001 01 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.615 {parse ccyymmdd} {
+ clock scan {2001 01 2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.616 {parse ccyymmdd} {
+ clock scan {2001 01 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.617 {parse ccyymmdd} {
+ clock scan {2001 i 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.618 {parse ccyymmdd} {
+ clock scan {2001 i ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.619 {parse ccyymmdd} {
+ clock scan {2001 i 2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.620 {parse ccyymmdd} {
+ clock scan {2001 i ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.621 {parse ccyymmdd} {
+ clock scan {2001 1 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.622 {parse ccyymmdd} {
+ clock scan {2001 1 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.623 {parse ccyymmdd} {
+ clock scan {2001 1 2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.624 {parse ccyymmdd} {
+ clock scan {2001 1 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.625 {parse ccyymmdd} {
+ clock scan {2001 Jan 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.626 {parse ccyymmdd} {
+ clock scan {2001 Jan ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.627 {parse ccyymmdd} {
+ clock scan {2001 Jan 2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.628 {parse ccyymmdd} {
+ clock scan {2001 Jan ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.629 {parse ccyymmdd} {
+ clock scan {2001 January 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.630 {parse ccyymmdd} {
+ clock scan {2001 January ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.631 {parse ccyymmdd} {
+ clock scan {2001 January 2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.632 {parse ccyymmdd} {
+ clock scan {2001 January ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.633 {parse ccyymmdd} {
+ clock scan {2001 Jan 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.634 {parse ccyymmdd} {
+ clock scan {2001 Jan ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.635 {parse ccyymmdd} {
+ clock scan {2001 Jan 2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.636 {parse ccyymmdd} {
+ clock scan {2001 Jan ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.637 {parse ccyymmdd} {
+ clock scan {2001 01 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.638 {parse ccyymmdd} {
+ clock scan {2001 01 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.639 {parse ccyymmdd} {
+ clock scan {2001 01 2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.640 {parse ccyymmdd} {
+ clock scan {2001 01 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.641 {parse ccyymmdd} {
+ clock scan {2001 i 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.642 {parse ccyymmdd} {
+ clock scan {2001 i ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.643 {parse ccyymmdd} {
+ clock scan {2001 i 2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.644 {parse ccyymmdd} {
+ clock scan {2001 i ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.645 {parse ccyymmdd} {
+ clock scan {2001 1 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.646 {parse ccyymmdd} {
+ clock scan {2001 1 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.647 {parse ccyymmdd} {
+ clock scan {2001 1 2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.648 {parse ccyymmdd} {
+ clock scan {2001 1 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.649 {parse ccyymmdd} {
+ clock scan 01/02/2001 -format %x -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.650 {parse ccyymmdd} {
+ clock scan 01/02/2001 -format %D -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.651 {parse ccyymmdd} {
+ clock scan {2001 Jan 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.652 {parse ccyymmdd} {
+ clock scan {2001 Jan xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.653 {parse ccyymmdd} {
+ clock scan {2001 Jan 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.654 {parse ccyymmdd} {
+ clock scan {2001 Jan xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.655 {parse ccyymmdd} {
+ clock scan {2001 January 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.656 {parse ccyymmdd} {
+ clock scan {2001 January xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.657 {parse ccyymmdd} {
+ clock scan {2001 January 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.658 {parse ccyymmdd} {
+ clock scan {2001 January xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.659 {parse ccyymmdd} {
+ clock scan {2001 Jan 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.660 {parse ccyymmdd} {
+ clock scan {2001 Jan xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.661 {parse ccyymmdd} {
+ clock scan {2001 Jan 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.662 {parse ccyymmdd} {
+ clock scan {2001 Jan xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.663 {parse ccyymmdd} {
+ clock scan {2001 01 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.664 {parse ccyymmdd} {
+ clock scan {2001 01 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.665 {parse ccyymmdd} {
+ clock scan {2001 01 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.666 {parse ccyymmdd} {
+ clock scan {2001 01 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.667 {parse ccyymmdd} {
+ clock scan {2001 i 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.668 {parse ccyymmdd} {
+ clock scan {2001 i xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.669 {parse ccyymmdd} {
+ clock scan {2001 i 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.670 {parse ccyymmdd} {
+ clock scan {2001 i xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.671 {parse ccyymmdd} {
+ clock scan {2001 1 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.672 {parse ccyymmdd} {
+ clock scan {2001 1 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.673 {parse ccyymmdd} {
+ clock scan {2001 1 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.674 {parse ccyymmdd} {
+ clock scan {2001 1 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.675 {parse ccyymmdd} {
+ clock scan {2001 Jan 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.676 {parse ccyymmdd} {
+ clock scan {2001 Jan xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.677 {parse ccyymmdd} {
+ clock scan {2001 Jan 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.678 {parse ccyymmdd} {
+ clock scan {2001 Jan xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.679 {parse ccyymmdd} {
+ clock scan {2001 January 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.680 {parse ccyymmdd} {
+ clock scan {2001 January xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.681 {parse ccyymmdd} {
+ clock scan {2001 January 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.682 {parse ccyymmdd} {
+ clock scan {2001 January xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.683 {parse ccyymmdd} {
+ clock scan {2001 Jan 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.684 {parse ccyymmdd} {
+ clock scan {2001 Jan xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.685 {parse ccyymmdd} {
+ clock scan {2001 Jan 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.686 {parse ccyymmdd} {
+ clock scan {2001 Jan xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.687 {parse ccyymmdd} {
+ clock scan {2001 01 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.688 {parse ccyymmdd} {
+ clock scan {2001 01 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.689 {parse ccyymmdd} {
+ clock scan {2001 01 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.690 {parse ccyymmdd} {
+ clock scan {2001 01 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.691 {parse ccyymmdd} {
+ clock scan {2001 i 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.692 {parse ccyymmdd} {
+ clock scan {2001 i xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.693 {parse ccyymmdd} {
+ clock scan {2001 i 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.694 {parse ccyymmdd} {
+ clock scan {2001 i xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.695 {parse ccyymmdd} {
+ clock scan {2001 1 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.696 {parse ccyymmdd} {
+ clock scan {2001 1 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.697 {parse ccyymmdd} {
+ clock scan {2001 1 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.698 {parse ccyymmdd} {
+ clock scan {2001 1 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.699 {parse ccyymmdd} {
+ clock scan 01/31/2001 -format %x -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.700 {parse ccyymmdd} {
+ clock scan 01/31/2001 -format %D -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.701 {parse ccyymmdd} {
+ clock scan {2001 Dec 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.702 {parse ccyymmdd} {
+ clock scan {2001 Dec ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.703 {parse ccyymmdd} {
+ clock scan {2001 Dec 2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.704 {parse ccyymmdd} {
+ clock scan {2001 Dec ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.705 {parse ccyymmdd} {
+ clock scan {2001 December 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.706 {parse ccyymmdd} {
+ clock scan {2001 December ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.707 {parse ccyymmdd} {
+ clock scan {2001 December 2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.708 {parse ccyymmdd} {
+ clock scan {2001 December ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.709 {parse ccyymmdd} {
+ clock scan {2001 Dec 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.710 {parse ccyymmdd} {
+ clock scan {2001 Dec ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.711 {parse ccyymmdd} {
+ clock scan {2001 Dec 2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.712 {parse ccyymmdd} {
+ clock scan {2001 Dec ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.713 {parse ccyymmdd} {
+ clock scan {2001 12 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.714 {parse ccyymmdd} {
+ clock scan {2001 12 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.715 {parse ccyymmdd} {
+ clock scan {2001 12 2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.716 {parse ccyymmdd} {
+ clock scan {2001 12 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.717 {parse ccyymmdd} {
+ clock scan {2001 xii 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.718 {parse ccyymmdd} {
+ clock scan {2001 xii ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.719 {parse ccyymmdd} {
+ clock scan {2001 xii 2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.720 {parse ccyymmdd} {
+ clock scan {2001 xii ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.721 {parse ccyymmdd} {
+ clock scan {2001 12 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.722 {parse ccyymmdd} {
+ clock scan {2001 12 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.723 {parse ccyymmdd} {
+ clock scan {2001 12 2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.724 {parse ccyymmdd} {
+ clock scan {2001 12 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.725 {parse ccyymmdd} {
+ clock scan {2001 Dec 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.726 {parse ccyymmdd} {
+ clock scan {2001 Dec ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.727 {parse ccyymmdd} {
+ clock scan {2001 Dec 2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.728 {parse ccyymmdd} {
+ clock scan {2001 Dec ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.729 {parse ccyymmdd} {
+ clock scan {2001 December 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.730 {parse ccyymmdd} {
+ clock scan {2001 December ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.731 {parse ccyymmdd} {
+ clock scan {2001 December 2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.732 {parse ccyymmdd} {
+ clock scan {2001 December ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.733 {parse ccyymmdd} {
+ clock scan {2001 Dec 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.734 {parse ccyymmdd} {
+ clock scan {2001 Dec ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.735 {parse ccyymmdd} {
+ clock scan {2001 Dec 2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.736 {parse ccyymmdd} {
+ clock scan {2001 Dec ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.737 {parse ccyymmdd} {
+ clock scan {2001 12 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.738 {parse ccyymmdd} {
+ clock scan {2001 12 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.739 {parse ccyymmdd} {
+ clock scan {2001 12 2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.740 {parse ccyymmdd} {
+ clock scan {2001 12 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.741 {parse ccyymmdd} {
+ clock scan {2001 xii 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.742 {parse ccyymmdd} {
+ clock scan {2001 xii ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.743 {parse ccyymmdd} {
+ clock scan {2001 xii 2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.744 {parse ccyymmdd} {
+ clock scan {2001 xii ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.745 {parse ccyymmdd} {
+ clock scan {2001 12 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.746 {parse ccyymmdd} {
+ clock scan {2001 12 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.747 {parse ccyymmdd} {
+ clock scan {2001 12 2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.748 {parse ccyymmdd} {
+ clock scan {2001 12 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.749 {parse ccyymmdd} {
+ clock scan 12/02/2001 -format %x -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.750 {parse ccyymmdd} {
+ clock scan 12/02/2001 -format %D -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.751 {parse ccyymmdd} {
+ clock scan {2001 Dec 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.752 {parse ccyymmdd} {
+ clock scan {2001 Dec xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.753 {parse ccyymmdd} {
+ clock scan {2001 Dec 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.754 {parse ccyymmdd} {
+ clock scan {2001 Dec xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.755 {parse ccyymmdd} {
+ clock scan {2001 December 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.756 {parse ccyymmdd} {
+ clock scan {2001 December xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.757 {parse ccyymmdd} {
+ clock scan {2001 December 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.758 {parse ccyymmdd} {
+ clock scan {2001 December xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.759 {parse ccyymmdd} {
+ clock scan {2001 Dec 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.760 {parse ccyymmdd} {
+ clock scan {2001 Dec xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.761 {parse ccyymmdd} {
+ clock scan {2001 Dec 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.762 {parse ccyymmdd} {
+ clock scan {2001 Dec xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.763 {parse ccyymmdd} {
+ clock scan {2001 12 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.764 {parse ccyymmdd} {
+ clock scan {2001 12 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.765 {parse ccyymmdd} {
+ clock scan {2001 12 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.766 {parse ccyymmdd} {
+ clock scan {2001 12 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.767 {parse ccyymmdd} {
+ clock scan {2001 xii 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.768 {parse ccyymmdd} {
+ clock scan {2001 xii xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.769 {parse ccyymmdd} {
+ clock scan {2001 xii 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.770 {parse ccyymmdd} {
+ clock scan {2001 xii xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.771 {parse ccyymmdd} {
+ clock scan {2001 12 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.772 {parse ccyymmdd} {
+ clock scan {2001 12 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.773 {parse ccyymmdd} {
+ clock scan {2001 12 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.774 {parse ccyymmdd} {
+ clock scan {2001 12 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.775 {parse ccyymmdd} {
+ clock scan {2001 Dec 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.776 {parse ccyymmdd} {
+ clock scan {2001 Dec xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.777 {parse ccyymmdd} {
+ clock scan {2001 Dec 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.778 {parse ccyymmdd} {
+ clock scan {2001 Dec xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.779 {parse ccyymmdd} {
+ clock scan {2001 December 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.780 {parse ccyymmdd} {
+ clock scan {2001 December xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.781 {parse ccyymmdd} {
+ clock scan {2001 December 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.782 {parse ccyymmdd} {
+ clock scan {2001 December xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.783 {parse ccyymmdd} {
+ clock scan {2001 Dec 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.784 {parse ccyymmdd} {
+ clock scan {2001 Dec xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.785 {parse ccyymmdd} {
+ clock scan {2001 Dec 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.786 {parse ccyymmdd} {
+ clock scan {2001 Dec xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.787 {parse ccyymmdd} {
+ clock scan {2001 12 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.788 {parse ccyymmdd} {
+ clock scan {2001 12 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.789 {parse ccyymmdd} {
+ clock scan {2001 12 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.790 {parse ccyymmdd} {
+ clock scan {2001 12 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.791 {parse ccyymmdd} {
+ clock scan {2001 xii 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.792 {parse ccyymmdd} {
+ clock scan {2001 xii xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.793 {parse ccyymmdd} {
+ clock scan {2001 xii 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.794 {parse ccyymmdd} {
+ clock scan {2001 xii xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.795 {parse ccyymmdd} {
+ clock scan {2001 12 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.796 {parse ccyymmdd} {
+ clock scan {2001 12 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.797 {parse ccyymmdd} {
+ clock scan {2001 12 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.798 {parse ccyymmdd} {
+ clock scan {2001 12 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.799 {parse ccyymmdd} {
+ clock scan 12/31/2001 -format %x -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.800 {parse ccyymmdd} {
+ clock scan 12/31/2001 -format %D -locale en_US_roman -gmt 1
+} 1009756800
+# END testcases8
+
+test clock-9.1 {seconds take precedence over ccyymmdd} {
+ clock scan {0 20000101} -format {%s %Y%m%d} -gmt true
+} 0
+
+test clock-9.2 {Julian day takes precedence over ccyymmdd} {
+ clock scan {2440588 20000101} -format {%J %Y%m%d} -gmt true
+} 0
+
+# Test parsing of ccyyddd
+
+test clock-10.1 {parse ccyyddd} {
+ clock scan {1970 001} -format {%Y %j} -locale en_US_roman -gmt 1
+} 0
+test clock-10.2 {parse ccyyddd} {
+ clock scan {1970 365} -format {%Y %j} -locale en_US_roman -gmt 1
+} 31449600
+test clock-10.3 {parse ccyyddd} {
+ clock scan {1971 001} -format {%Y %j} -locale en_US_roman -gmt 1
+} 31536000
+test clock-10.4 {parse ccyyddd} {
+ clock scan {1971 365} -format {%Y %j} -locale en_US_roman -gmt 1
+} 62985600
+test clock-10.5 {parse ccyyddd} {
+ clock scan {2000 001} -format {%Y %j} -locale en_US_roman -gmt 1
+} 946684800
+test clock-10.6 {parse ccyyddd} {
+ clock scan {2000 365} -format {%Y %j} -locale en_US_roman -gmt 1
+} 978134400
+test clock-10.7 {parse ccyyddd} {
+ clock scan {2001 001} -format {%Y %j} -locale en_US_roman -gmt 1
+} 978307200
+test clock-10.8 {parse ccyyddd} {
+ clock scan {2001 365} -format {%Y %j} -locale en_US_roman -gmt 1
+} 1009756800
+
+
+test clock-10.9 {seconds take precedence over ccyyddd} {
+ list [clock scan {0 2000001} -format {%s %Y%j} -gmt true] \
+ [clock scan {2000001 0} -format {%Y%j %s} -gmt true]
+} {0 0}
+test clock-10.10 {julian day takes precedence over ccyyddd} {
+ list [clock scan {2440588 2000001} -format {%J %Y%j} -gmt true] \
+ [clock scan {2000001 2440588} -format {%Y%j %J} -gmt true]
+} {0 0}
+
+# BEGIN testcases11
+
+# Test precedence among yyyymmdd and yyyyddd
+
+test clock-11.1 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 19700101002 -format %Y%m%d%j -gmt 1
+} 86400
+test clock-11.2 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01197001002 -format %m%Y%d%j -gmt 1
+} 86400
+test clock-11.3 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01197001002 -format %d%Y%m%j -gmt 1
+} 86400
+test clock-11.4 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 00219700101 -format %j%Y%m%d -gmt 1
+} 0
+test clock-11.5 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 19700100201 -format %Y%m%j%d -gmt 1
+} 0
+test clock-11.6 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01197000201 -format %m%Y%j%d -gmt 1
+} 0
+test clock-11.7 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01197000201 -format %d%Y%j%m -gmt 1
+} 0
+test clock-11.8 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 00219700101 -format %j%Y%d%m -gmt 1
+} 0
+test clock-11.9 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 19700101002 -format %Y%d%m%j -gmt 1
+} 86400
+test clock-11.10 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01011970002 -format %m%d%Y%j -gmt 1
+} 86400
+test clock-11.11 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01011970002 -format %d%m%Y%j -gmt 1
+} 86400
+test clock-11.12 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 00201197001 -format %j%m%Y%d -gmt 1
+} 0
+test clock-11.13 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 19700100201 -format %Y%d%j%m -gmt 1
+} 0
+test clock-11.14 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01010021970 -format %m%d%j%Y -gmt 1
+} 86400
+test clock-11.15 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01010021970 -format %d%m%j%Y -gmt 1
+} 86400
+test clock-11.16 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 00201011970 -format %j%m%d%Y -gmt 1
+} 0
+test clock-11.17 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 19700020101 -format %Y%j%m%d -gmt 1
+} 0
+test clock-11.18 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01002197001 -format %m%j%Y%d -gmt 1
+} 0
+test clock-11.19 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01002197001 -format %d%j%Y%m -gmt 1
+} 0
+test clock-11.20 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 00201197001 -format %j%d%Y%m -gmt 1
+} 0
+test clock-11.21 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 19700020101 -format %Y%j%d%m -gmt 1
+} 0
+test clock-11.22 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01002011970 -format %m%j%d%Y -gmt 1
+} 0
+test clock-11.23 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 01002011970 -format %d%j%m%Y -gmt 1
+} 0
+test clock-11.24 {precedence of ccyyddd and ccyymmdd} {
+ clock scan 00201011970 -format %j%d%m%Y -gmt 1
+} 0
+# END testcases11
+
+# BEGIN testcases12
+
+# Test parsing of ccyyWwwd
+
+test clock-12.1 {parse ccyyWwwd} {
+ clock scan {1970 W01 Fri} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.2 {parse ccyyWwwd} {
+ clock scan {1970 W01 Friday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.3 {parse ccyyWwwd} {
+ clock scan {1970 W01 5} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.4 {parse ccyyWwwd} {
+ clock scan {1970 W01 5} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.5 {parse ccyyWwwd} {
+ clock scan {1970 W01 v} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.6 {parse ccyyWwwd} {
+ clock scan {1970 W01 v} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.7 {parse ccyyWwwd} {
+ clock scan {1970 W05 Sat} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.8 {parse ccyyWwwd} {
+ clock scan {1970 W05 Saturday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.9 {parse ccyyWwwd} {
+ clock scan {1970 W05 6} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.10 {parse ccyyWwwd} {
+ clock scan {1970 W05 6} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.11 {parse ccyyWwwd} {
+ clock scan {1970 W05 vi} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.12 {parse ccyyWwwd} {
+ clock scan {1970 W05 vi} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.13 {parse ccyyWwwd} {
+ clock scan {1970 W49 Wed} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.14 {parse ccyyWwwd} {
+ clock scan {1970 W49 Wednesday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.15 {parse ccyyWwwd} {
+ clock scan {1970 W49 3} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.16 {parse ccyyWwwd} {
+ clock scan {1970 W49 3} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.17 {parse ccyyWwwd} {
+ clock scan {1970 W49 iii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.18 {parse ccyyWwwd} {
+ clock scan {1970 W49 iii} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.19 {parse ccyyWwwd} {
+ clock scan {1970 W53 Thu} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.20 {parse ccyyWwwd} {
+ clock scan {1970 W53 Thursday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.21 {parse ccyyWwwd} {
+ clock scan {1970 W53 4} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.22 {parse ccyyWwwd} {
+ clock scan {1970 W53 4} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.23 {parse ccyyWwwd} {
+ clock scan {1970 W53 iv} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.24 {parse ccyyWwwd} {
+ clock scan {1970 W53 iv} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.25 {parse ccyyWwwd} {
+ clock scan {1970 W53 Sat} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.26 {parse ccyyWwwd} {
+ clock scan {1970 W53 Saturday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.27 {parse ccyyWwwd} {
+ clock scan {1970 W53 6} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.28 {parse ccyyWwwd} {
+ clock scan {1970 W53 6} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.29 {parse ccyyWwwd} {
+ clock scan {1970 W53 vi} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.30 {parse ccyyWwwd} {
+ clock scan {1970 W53 vi} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.31 {parse ccyyWwwd} {
+ clock scan {1971 W04 Sun} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.32 {parse ccyyWwwd} {
+ clock scan {1971 W04 Sunday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.33 {parse ccyyWwwd} {
+ clock scan {1971 W04 7} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.34 {parse ccyyWwwd} {
+ clock scan {1971 W04 0} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.35 {parse ccyyWwwd} {
+ clock scan {1971 W04 vii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.36 {parse ccyyWwwd} {
+ clock scan {1971 W04 ?} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.37 {parse ccyyWwwd} {
+ clock scan {1971 W48 Thu} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.38 {parse ccyyWwwd} {
+ clock scan {1971 W48 Thursday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.39 {parse ccyyWwwd} {
+ clock scan {1971 W48 4} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.40 {parse ccyyWwwd} {
+ clock scan {1971 W48 4} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.41 {parse ccyyWwwd} {
+ clock scan {1971 W48 iv} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.42 {parse ccyyWwwd} {
+ clock scan {1971 W48 iv} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.43 {parse ccyyWwwd} {
+ clock scan {1971 W52 Fri} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.44 {parse ccyyWwwd} {
+ clock scan {1971 W52 Friday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.45 {parse ccyyWwwd} {
+ clock scan {1971 W52 5} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.46 {parse ccyyWwwd} {
+ clock scan {1971 W52 5} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.47 {parse ccyyWwwd} {
+ clock scan {1971 W52 v} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.48 {parse ccyyWwwd} {
+ clock scan {1971 W52 v} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.49 {parse ccyyWwwd} {
+ clock scan {1999 W52 Sun} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.50 {parse ccyyWwwd} {
+ clock scan {1999 W52 Sunday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.51 {parse ccyyWwwd} {
+ clock scan {1999 W52 7} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.52 {parse ccyyWwwd} {
+ clock scan {1999 W52 0} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.53 {parse ccyyWwwd} {
+ clock scan {1999 W52 vii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.54 {parse ccyyWwwd} {
+ clock scan {1999 W52 ?} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.55 {parse ccyyWwwd} {
+ clock scan {2000 W05 Mon} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.56 {parse ccyyWwwd} {
+ clock scan {2000 W05 Monday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.57 {parse ccyyWwwd} {
+ clock scan {2000 W05 1} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.58 {parse ccyyWwwd} {
+ clock scan {2000 W05 1} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.59 {parse ccyyWwwd} {
+ clock scan {2000 W05 i} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.60 {parse ccyyWwwd} {
+ clock scan {2000 W05 i} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.61 {parse ccyyWwwd} {
+ clock scan {2000 W48 Sat} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.62 {parse ccyyWwwd} {
+ clock scan {2000 W48 Saturday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.63 {parse ccyyWwwd} {
+ clock scan {2000 W48 6} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.64 {parse ccyyWwwd} {
+ clock scan {2000 W48 6} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.65 {parse ccyyWwwd} {
+ clock scan {2000 W48 vi} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.66 {parse ccyyWwwd} {
+ clock scan {2000 W48 vi} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.67 {parse ccyyWwwd} {
+ clock scan {2000 W52 Sun} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.68 {parse ccyyWwwd} {
+ clock scan {2000 W52 Sunday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.69 {parse ccyyWwwd} {
+ clock scan {2000 W52 7} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.70 {parse ccyyWwwd} {
+ clock scan {2000 W52 0} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.71 {parse ccyyWwwd} {
+ clock scan {2000 W52 vii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.72 {parse ccyyWwwd} {
+ clock scan {2000 W52 ?} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.73 {parse ccyyWwwd} {
+ clock scan {2001 W01 Tue} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.74 {parse ccyyWwwd} {
+ clock scan {2001 W01 Tuesday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.75 {parse ccyyWwwd} {
+ clock scan {2001 W01 2} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.76 {parse ccyyWwwd} {
+ clock scan {2001 W01 2} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.77 {parse ccyyWwwd} {
+ clock scan {2001 W01 ii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.78 {parse ccyyWwwd} {
+ clock scan {2001 W01 ii} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.79 {parse ccyyWwwd} {
+ clock scan {2001 W05 Wed} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.80 {parse ccyyWwwd} {
+ clock scan {2001 W05 Wednesday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.81 {parse ccyyWwwd} {
+ clock scan {2001 W05 3} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.82 {parse ccyyWwwd} {
+ clock scan {2001 W05 3} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.83 {parse ccyyWwwd} {
+ clock scan {2001 W05 iii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.84 {parse ccyyWwwd} {
+ clock scan {2001 W05 iii} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.85 {parse ccyyWwwd} {
+ clock scan {2001 W48 Sun} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.86 {parse ccyyWwwd} {
+ clock scan {2001 W48 Sunday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.87 {parse ccyyWwwd} {
+ clock scan {2001 W48 7} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.88 {parse ccyyWwwd} {
+ clock scan {2001 W48 0} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.89 {parse ccyyWwwd} {
+ clock scan {2001 W48 vii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.90 {parse ccyyWwwd} {
+ clock scan {2001 W48 ?} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.91 {parse ccyyWwwd} {
+ clock scan {2002 W01 Mon} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-12.92 {parse ccyyWwwd} {
+ clock scan {2002 W01 Monday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-12.93 {parse ccyyWwwd} {
+ clock scan {2002 W01 1} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-12.94 {parse ccyyWwwd} {
+ clock scan {2002 W01 1} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-12.95 {parse ccyyWwwd} {
+ clock scan {2002 W01 i} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-12.96 {parse ccyyWwwd} {
+ clock scan {2002 W01 i} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 1009756800
+# END testcases12
+
+test clock-13.1 {test that %s takes precedence over ccyyWwwd} {
+ list [clock scan {0 2000W011} -format {%s %GW%V%u} -gmt true] \
+ [clock scan {2000W011 0} -format {%GW%V%u %s} -gmt true]
+} {0 0}
+test clock-13.2 {test that %J takes precedence over ccyyWwwd} {
+ list [clock scan {2440588 2000W011} -format {%J %GW%V%u} -gmt true] \
+ [clock scan {2000W011 2440588} -format {%GW%V%u %J} -gmt true]
+} {0 0}
+test clock-13.3 {invalid weekday} {
+ catch {clock scan 2000W018 -format %GW%V%u -gmt true} result
+ list $result $::errorCode
+} {{day of week is greater than 7} {CLOCK badDayOfWeek}}
+test clock-13.4 {invalid weekday} {
+ catch {
+ clock scan {2000 W01 viii} \
+ -format {%G W%V %Ou} -gmt true -locale en_US_roman
+ } result
+ list $result $::errorCode
+} {{day of week is greater than 7} {CLOCK badDayOfWeek}}
+
+# BEGIN testcases14
+
+# Test parsing of yymmdd
+
+test clock-14.1 {parse yymmdd} {
+ clock scan {38 Jan 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.2 {parse yymmdd} {
+ clock scan {38 Jan ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.3 {parse yymmdd} {
+ clock scan {38 Jan 2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.4 {parse yymmdd} {
+ clock scan {38 Jan ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.5 {parse yymmdd} {
+ clock scan {38 January 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.6 {parse yymmdd} {
+ clock scan {38 January ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.7 {parse yymmdd} {
+ clock scan {38 January 2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.8 {parse yymmdd} {
+ clock scan {38 January ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.9 {parse yymmdd} {
+ clock scan {38 Jan 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.10 {parse yymmdd} {
+ clock scan {38 Jan ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.11 {parse yymmdd} {
+ clock scan {38 Jan 2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.12 {parse yymmdd} {
+ clock scan {38 Jan ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.13 {parse yymmdd} {
+ clock scan {38 01 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.14 {parse yymmdd} {
+ clock scan {38 01 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.15 {parse yymmdd} {
+ clock scan {38 01 2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.16 {parse yymmdd} {
+ clock scan {38 01 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.17 {parse yymmdd} {
+ clock scan {38 i 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.18 {parse yymmdd} {
+ clock scan {38 i ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.19 {parse yymmdd} {
+ clock scan {38 i 2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.20 {parse yymmdd} {
+ clock scan {38 i ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.21 {parse yymmdd} {
+ clock scan {38 1 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.22 {parse yymmdd} {
+ clock scan {38 1 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.23 {parse yymmdd} {
+ clock scan {38 1 2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.24 {parse yymmdd} {
+ clock scan {38 1 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.25 {parse yymmdd} {
+ clock scan {xxxviii Jan 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.26 {parse yymmdd} {
+ clock scan {xxxviii Jan ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.27 {parse yymmdd} {
+ clock scan {xxxviii Jan 2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.28 {parse yymmdd} {
+ clock scan {xxxviii Jan ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.29 {parse yymmdd} {
+ clock scan {xxxviii January 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.30 {parse yymmdd} {
+ clock scan {xxxviii January ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.31 {parse yymmdd} {
+ clock scan {xxxviii January 2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.32 {parse yymmdd} {
+ clock scan {xxxviii January ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.33 {parse yymmdd} {
+ clock scan {xxxviii Jan 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.34 {parse yymmdd} {
+ clock scan {xxxviii Jan ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.35 {parse yymmdd} {
+ clock scan {xxxviii Jan 2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.36 {parse yymmdd} {
+ clock scan {xxxviii Jan ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.37 {parse yymmdd} {
+ clock scan {xxxviii 01 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.38 {parse yymmdd} {
+ clock scan {xxxviii 01 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.39 {parse yymmdd} {
+ clock scan {xxxviii 01 2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.40 {parse yymmdd} {
+ clock scan {xxxviii 01 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.41 {parse yymmdd} {
+ clock scan {xxxviii i 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.42 {parse yymmdd} {
+ clock scan {xxxviii i ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.43 {parse yymmdd} {
+ clock scan {xxxviii i 2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.44 {parse yymmdd} {
+ clock scan {xxxviii i ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.45 {parse yymmdd} {
+ clock scan {xxxviii 1 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.46 {parse yymmdd} {
+ clock scan {xxxviii 1 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.47 {parse yymmdd} {
+ clock scan {xxxviii 1 2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.48 {parse yymmdd} {
+ clock scan {xxxviii 1 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.49 {parse yymmdd} {
+ clock scan {38 Jan 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.50 {parse yymmdd} {
+ clock scan {38 Jan xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.51 {parse yymmdd} {
+ clock scan {38 Jan 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.52 {parse yymmdd} {
+ clock scan {38 Jan xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.53 {parse yymmdd} {
+ clock scan {38 January 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.54 {parse yymmdd} {
+ clock scan {38 January xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.55 {parse yymmdd} {
+ clock scan {38 January 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.56 {parse yymmdd} {
+ clock scan {38 January xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.57 {parse yymmdd} {
+ clock scan {38 Jan 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.58 {parse yymmdd} {
+ clock scan {38 Jan xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.59 {parse yymmdd} {
+ clock scan {38 Jan 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.60 {parse yymmdd} {
+ clock scan {38 Jan xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.61 {parse yymmdd} {
+ clock scan {38 01 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.62 {parse yymmdd} {
+ clock scan {38 01 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.63 {parse yymmdd} {
+ clock scan {38 01 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.64 {parse yymmdd} {
+ clock scan {38 01 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.65 {parse yymmdd} {
+ clock scan {38 i 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.66 {parse yymmdd} {
+ clock scan {38 i xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.67 {parse yymmdd} {
+ clock scan {38 i 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.68 {parse yymmdd} {
+ clock scan {38 i xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.69 {parse yymmdd} {
+ clock scan {38 1 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.70 {parse yymmdd} {
+ clock scan {38 1 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.71 {parse yymmdd} {
+ clock scan {38 1 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.72 {parse yymmdd} {
+ clock scan {38 1 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.73 {parse yymmdd} {
+ clock scan {xxxviii Jan 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.74 {parse yymmdd} {
+ clock scan {xxxviii Jan xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.75 {parse yymmdd} {
+ clock scan {xxxviii Jan 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.76 {parse yymmdd} {
+ clock scan {xxxviii Jan xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.77 {parse yymmdd} {
+ clock scan {xxxviii January 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.78 {parse yymmdd} {
+ clock scan {xxxviii January xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.79 {parse yymmdd} {
+ clock scan {xxxviii January 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.80 {parse yymmdd} {
+ clock scan {xxxviii January xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.81 {parse yymmdd} {
+ clock scan {xxxviii Jan 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.82 {parse yymmdd} {
+ clock scan {xxxviii Jan xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.83 {parse yymmdd} {
+ clock scan {xxxviii Jan 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.84 {parse yymmdd} {
+ clock scan {xxxviii Jan xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.85 {parse yymmdd} {
+ clock scan {xxxviii 01 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.86 {parse yymmdd} {
+ clock scan {xxxviii 01 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.87 {parse yymmdd} {
+ clock scan {xxxviii 01 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.88 {parse yymmdd} {
+ clock scan {xxxviii 01 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.89 {parse yymmdd} {
+ clock scan {xxxviii i 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.90 {parse yymmdd} {
+ clock scan {xxxviii i xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.91 {parse yymmdd} {
+ clock scan {xxxviii i 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.92 {parse yymmdd} {
+ clock scan {xxxviii i xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.93 {parse yymmdd} {
+ clock scan {xxxviii 1 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.94 {parse yymmdd} {
+ clock scan {xxxviii 1 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.95 {parse yymmdd} {
+ clock scan {xxxviii 1 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.96 {parse yymmdd} {
+ clock scan {xxxviii 1 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.97 {parse yymmdd} {
+ clock scan {38 Dec 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.98 {parse yymmdd} {
+ clock scan {38 Dec ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.99 {parse yymmdd} {
+ clock scan {38 Dec 2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.100 {parse yymmdd} {
+ clock scan {38 Dec ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.101 {parse yymmdd} {
+ clock scan {38 December 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.102 {parse yymmdd} {
+ clock scan {38 December ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.103 {parse yymmdd} {
+ clock scan {38 December 2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.104 {parse yymmdd} {
+ clock scan {38 December ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.105 {parse yymmdd} {
+ clock scan {38 Dec 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.106 {parse yymmdd} {
+ clock scan {38 Dec ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.107 {parse yymmdd} {
+ clock scan {38 Dec 2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.108 {parse yymmdd} {
+ clock scan {38 Dec ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.109 {parse yymmdd} {
+ clock scan {38 12 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.110 {parse yymmdd} {
+ clock scan {38 12 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.111 {parse yymmdd} {
+ clock scan {38 12 2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.112 {parse yymmdd} {
+ clock scan {38 12 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.113 {parse yymmdd} {
+ clock scan {38 xii 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.114 {parse yymmdd} {
+ clock scan {38 xii ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.115 {parse yymmdd} {
+ clock scan {38 xii 2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.116 {parse yymmdd} {
+ clock scan {38 xii ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.117 {parse yymmdd} {
+ clock scan {38 12 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.118 {parse yymmdd} {
+ clock scan {38 12 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.119 {parse yymmdd} {
+ clock scan {38 12 2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.120 {parse yymmdd} {
+ clock scan {38 12 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.121 {parse yymmdd} {
+ clock scan {xxxviii Dec 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.122 {parse yymmdd} {
+ clock scan {xxxviii Dec ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.123 {parse yymmdd} {
+ clock scan {xxxviii Dec 2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.124 {parse yymmdd} {
+ clock scan {xxxviii Dec ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.125 {parse yymmdd} {
+ clock scan {xxxviii December 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.126 {parse yymmdd} {
+ clock scan {xxxviii December ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.127 {parse yymmdd} {
+ clock scan {xxxviii December 2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.128 {parse yymmdd} {
+ clock scan {xxxviii December ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.129 {parse yymmdd} {
+ clock scan {xxxviii Dec 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.130 {parse yymmdd} {
+ clock scan {xxxviii Dec ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.131 {parse yymmdd} {
+ clock scan {xxxviii Dec 2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.132 {parse yymmdd} {
+ clock scan {xxxviii Dec ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.133 {parse yymmdd} {
+ clock scan {xxxviii 12 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.134 {parse yymmdd} {
+ clock scan {xxxviii 12 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.135 {parse yymmdd} {
+ clock scan {xxxviii 12 2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.136 {parse yymmdd} {
+ clock scan {xxxviii 12 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.137 {parse yymmdd} {
+ clock scan {xxxviii xii 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.138 {parse yymmdd} {
+ clock scan {xxxviii xii ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.139 {parse yymmdd} {
+ clock scan {xxxviii xii 2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.140 {parse yymmdd} {
+ clock scan {xxxviii xii ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.141 {parse yymmdd} {
+ clock scan {xxxviii 12 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.142 {parse yymmdd} {
+ clock scan {xxxviii 12 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.143 {parse yymmdd} {
+ clock scan {xxxviii 12 2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.144 {parse yymmdd} {
+ clock scan {xxxviii 12 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.145 {parse yymmdd} {
+ clock scan {38 Dec 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.146 {parse yymmdd} {
+ clock scan {38 Dec xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.147 {parse yymmdd} {
+ clock scan {38 Dec 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.148 {parse yymmdd} {
+ clock scan {38 Dec xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.149 {parse yymmdd} {
+ clock scan {38 December 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.150 {parse yymmdd} {
+ clock scan {38 December xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.151 {parse yymmdd} {
+ clock scan {38 December 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.152 {parse yymmdd} {
+ clock scan {38 December xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.153 {parse yymmdd} {
+ clock scan {38 Dec 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.154 {parse yymmdd} {
+ clock scan {38 Dec xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.155 {parse yymmdd} {
+ clock scan {38 Dec 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.156 {parse yymmdd} {
+ clock scan {38 Dec xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.157 {parse yymmdd} {
+ clock scan {38 12 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.158 {parse yymmdd} {
+ clock scan {38 12 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.159 {parse yymmdd} {
+ clock scan {38 12 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.160 {parse yymmdd} {
+ clock scan {38 12 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.161 {parse yymmdd} {
+ clock scan {38 xii 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.162 {parse yymmdd} {
+ clock scan {38 xii xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.163 {parse yymmdd} {
+ clock scan {38 xii 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.164 {parse yymmdd} {
+ clock scan {38 xii xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.165 {parse yymmdd} {
+ clock scan {38 12 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.166 {parse yymmdd} {
+ clock scan {38 12 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.167 {parse yymmdd} {
+ clock scan {38 12 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.168 {parse yymmdd} {
+ clock scan {38 12 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.169 {parse yymmdd} {
+ clock scan {xxxviii Dec 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.170 {parse yymmdd} {
+ clock scan {xxxviii Dec xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.171 {parse yymmdd} {
+ clock scan {xxxviii Dec 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.172 {parse yymmdd} {
+ clock scan {xxxviii Dec xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.173 {parse yymmdd} {
+ clock scan {xxxviii December 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.174 {parse yymmdd} {
+ clock scan {xxxviii December xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.175 {parse yymmdd} {
+ clock scan {xxxviii December 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.176 {parse yymmdd} {
+ clock scan {xxxviii December xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.177 {parse yymmdd} {
+ clock scan {xxxviii Dec 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.178 {parse yymmdd} {
+ clock scan {xxxviii Dec xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.179 {parse yymmdd} {
+ clock scan {xxxviii Dec 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.180 {parse yymmdd} {
+ clock scan {xxxviii Dec xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.181 {parse yymmdd} {
+ clock scan {xxxviii 12 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.182 {parse yymmdd} {
+ clock scan {xxxviii 12 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.183 {parse yymmdd} {
+ clock scan {xxxviii 12 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.184 {parse yymmdd} {
+ clock scan {xxxviii 12 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.185 {parse yymmdd} {
+ clock scan {xxxviii xii 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.186 {parse yymmdd} {
+ clock scan {xxxviii xii xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.187 {parse yymmdd} {
+ clock scan {xxxviii xii 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.188 {parse yymmdd} {
+ clock scan {xxxviii xii xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.189 {parse yymmdd} {
+ clock scan {xxxviii 12 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.190 {parse yymmdd} {
+ clock scan {xxxviii 12 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.191 {parse yymmdd} {
+ clock scan {xxxviii 12 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.192 {parse yymmdd} {
+ clock scan {xxxviii 12 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.193 {parse yymmdd} {
+ clock scan {70 Jan 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.194 {parse yymmdd} {
+ clock scan {70 Jan ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.195 {parse yymmdd} {
+ clock scan {70 Jan 2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.196 {parse yymmdd} {
+ clock scan {70 Jan ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.197 {parse yymmdd} {
+ clock scan {70 January 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.198 {parse yymmdd} {
+ clock scan {70 January ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.199 {parse yymmdd} {
+ clock scan {70 January 2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.200 {parse yymmdd} {
+ clock scan {70 January ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.201 {parse yymmdd} {
+ clock scan {70 Jan 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.202 {parse yymmdd} {
+ clock scan {70 Jan ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.203 {parse yymmdd} {
+ clock scan {70 Jan 2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.204 {parse yymmdd} {
+ clock scan {70 Jan ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.205 {parse yymmdd} {
+ clock scan {70 01 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.206 {parse yymmdd} {
+ clock scan {70 01 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.207 {parse yymmdd} {
+ clock scan {70 01 2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.208 {parse yymmdd} {
+ clock scan {70 01 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.209 {parse yymmdd} {
+ clock scan {70 i 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.210 {parse yymmdd} {
+ clock scan {70 i ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.211 {parse yymmdd} {
+ clock scan {70 i 2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.212 {parse yymmdd} {
+ clock scan {70 i ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.213 {parse yymmdd} {
+ clock scan {70 1 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.214 {parse yymmdd} {
+ clock scan {70 1 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.215 {parse yymmdd} {
+ clock scan {70 1 2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.216 {parse yymmdd} {
+ clock scan {70 1 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.217 {parse yymmdd} {
+ clock scan {lxx Jan 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.218 {parse yymmdd} {
+ clock scan {lxx Jan ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.219 {parse yymmdd} {
+ clock scan {lxx Jan 2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.220 {parse yymmdd} {
+ clock scan {lxx Jan ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.221 {parse yymmdd} {
+ clock scan {lxx January 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.222 {parse yymmdd} {
+ clock scan {lxx January ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.223 {parse yymmdd} {
+ clock scan {lxx January 2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.224 {parse yymmdd} {
+ clock scan {lxx January ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.225 {parse yymmdd} {
+ clock scan {lxx Jan 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.226 {parse yymmdd} {
+ clock scan {lxx Jan ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.227 {parse yymmdd} {
+ clock scan {lxx Jan 2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.228 {parse yymmdd} {
+ clock scan {lxx Jan ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.229 {parse yymmdd} {
+ clock scan {lxx 01 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.230 {parse yymmdd} {
+ clock scan {lxx 01 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.231 {parse yymmdd} {
+ clock scan {lxx 01 2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.232 {parse yymmdd} {
+ clock scan {lxx 01 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.233 {parse yymmdd} {
+ clock scan {lxx i 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.234 {parse yymmdd} {
+ clock scan {lxx i ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.235 {parse yymmdd} {
+ clock scan {lxx i 2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.236 {parse yymmdd} {
+ clock scan {lxx i ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.237 {parse yymmdd} {
+ clock scan {lxx 1 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.238 {parse yymmdd} {
+ clock scan {lxx 1 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.239 {parse yymmdd} {
+ clock scan {lxx 1 2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.240 {parse yymmdd} {
+ clock scan {lxx 1 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.241 {parse yymmdd} {
+ clock scan {70 Jan 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.242 {parse yymmdd} {
+ clock scan {70 Jan xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.243 {parse yymmdd} {
+ clock scan {70 Jan 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.244 {parse yymmdd} {
+ clock scan {70 Jan xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.245 {parse yymmdd} {
+ clock scan {70 January 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.246 {parse yymmdd} {
+ clock scan {70 January xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.247 {parse yymmdd} {
+ clock scan {70 January 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.248 {parse yymmdd} {
+ clock scan {70 January xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.249 {parse yymmdd} {
+ clock scan {70 Jan 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.250 {parse yymmdd} {
+ clock scan {70 Jan xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.251 {parse yymmdd} {
+ clock scan {70 Jan 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.252 {parse yymmdd} {
+ clock scan {70 Jan xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.253 {parse yymmdd} {
+ clock scan {70 01 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.254 {parse yymmdd} {
+ clock scan {70 01 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.255 {parse yymmdd} {
+ clock scan {70 01 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.256 {parse yymmdd} {
+ clock scan {70 01 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.257 {parse yymmdd} {
+ clock scan {70 i 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.258 {parse yymmdd} {
+ clock scan {70 i xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.259 {parse yymmdd} {
+ clock scan {70 i 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.260 {parse yymmdd} {
+ clock scan {70 i xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.261 {parse yymmdd} {
+ clock scan {70 1 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.262 {parse yymmdd} {
+ clock scan {70 1 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.263 {parse yymmdd} {
+ clock scan {70 1 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.264 {parse yymmdd} {
+ clock scan {70 1 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.265 {parse yymmdd} {
+ clock scan {lxx Jan 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.266 {parse yymmdd} {
+ clock scan {lxx Jan xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.267 {parse yymmdd} {
+ clock scan {lxx Jan 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.268 {parse yymmdd} {
+ clock scan {lxx Jan xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.269 {parse yymmdd} {
+ clock scan {lxx January 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.270 {parse yymmdd} {
+ clock scan {lxx January xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.271 {parse yymmdd} {
+ clock scan {lxx January 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.272 {parse yymmdd} {
+ clock scan {lxx January xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.273 {parse yymmdd} {
+ clock scan {lxx Jan 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.274 {parse yymmdd} {
+ clock scan {lxx Jan xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.275 {parse yymmdd} {
+ clock scan {lxx Jan 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.276 {parse yymmdd} {
+ clock scan {lxx Jan xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.277 {parse yymmdd} {
+ clock scan {lxx 01 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.278 {parse yymmdd} {
+ clock scan {lxx 01 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.279 {parse yymmdd} {
+ clock scan {lxx 01 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.280 {parse yymmdd} {
+ clock scan {lxx 01 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.281 {parse yymmdd} {
+ clock scan {lxx i 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.282 {parse yymmdd} {
+ clock scan {lxx i xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.283 {parse yymmdd} {
+ clock scan {lxx i 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.284 {parse yymmdd} {
+ clock scan {lxx i xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.285 {parse yymmdd} {
+ clock scan {lxx 1 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.286 {parse yymmdd} {
+ clock scan {lxx 1 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.287 {parse yymmdd} {
+ clock scan {lxx 1 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.288 {parse yymmdd} {
+ clock scan {lxx 1 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.289 {parse yymmdd} {
+ clock scan {70 Dec 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.290 {parse yymmdd} {
+ clock scan {70 Dec ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.291 {parse yymmdd} {
+ clock scan {70 Dec 2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.292 {parse yymmdd} {
+ clock scan {70 Dec ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.293 {parse yymmdd} {
+ clock scan {70 December 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.294 {parse yymmdd} {
+ clock scan {70 December ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.295 {parse yymmdd} {
+ clock scan {70 December 2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.296 {parse yymmdd} {
+ clock scan {70 December ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.297 {parse yymmdd} {
+ clock scan {70 Dec 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.298 {parse yymmdd} {
+ clock scan {70 Dec ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.299 {parse yymmdd} {
+ clock scan {70 Dec 2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.300 {parse yymmdd} {
+ clock scan {70 Dec ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.301 {parse yymmdd} {
+ clock scan {70 12 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.302 {parse yymmdd} {
+ clock scan {70 12 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.303 {parse yymmdd} {
+ clock scan {70 12 2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.304 {parse yymmdd} {
+ clock scan {70 12 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.305 {parse yymmdd} {
+ clock scan {70 xii 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.306 {parse yymmdd} {
+ clock scan {70 xii ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.307 {parse yymmdd} {
+ clock scan {70 xii 2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.308 {parse yymmdd} {
+ clock scan {70 xii ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.309 {parse yymmdd} {
+ clock scan {70 12 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.310 {parse yymmdd} {
+ clock scan {70 12 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.311 {parse yymmdd} {
+ clock scan {70 12 2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.312 {parse yymmdd} {
+ clock scan {70 12 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.313 {parse yymmdd} {
+ clock scan {lxx Dec 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.314 {parse yymmdd} {
+ clock scan {lxx Dec ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.315 {parse yymmdd} {
+ clock scan {lxx Dec 2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.316 {parse yymmdd} {
+ clock scan {lxx Dec ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.317 {parse yymmdd} {
+ clock scan {lxx December 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.318 {parse yymmdd} {
+ clock scan {lxx December ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.319 {parse yymmdd} {
+ clock scan {lxx December 2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.320 {parse yymmdd} {
+ clock scan {lxx December ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.321 {parse yymmdd} {
+ clock scan {lxx Dec 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.322 {parse yymmdd} {
+ clock scan {lxx Dec ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.323 {parse yymmdd} {
+ clock scan {lxx Dec 2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.324 {parse yymmdd} {
+ clock scan {lxx Dec ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.325 {parse yymmdd} {
+ clock scan {lxx 12 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.326 {parse yymmdd} {
+ clock scan {lxx 12 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.327 {parse yymmdd} {
+ clock scan {lxx 12 2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.328 {parse yymmdd} {
+ clock scan {lxx 12 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.329 {parse yymmdd} {
+ clock scan {lxx xii 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.330 {parse yymmdd} {
+ clock scan {lxx xii ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.331 {parse yymmdd} {
+ clock scan {lxx xii 2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.332 {parse yymmdd} {
+ clock scan {lxx xii ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.333 {parse yymmdd} {
+ clock scan {lxx 12 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.334 {parse yymmdd} {
+ clock scan {lxx 12 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.335 {parse yymmdd} {
+ clock scan {lxx 12 2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.336 {parse yymmdd} {
+ clock scan {lxx 12 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.337 {parse yymmdd} {
+ clock scan {70 Dec 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.338 {parse yymmdd} {
+ clock scan {70 Dec xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.339 {parse yymmdd} {
+ clock scan {70 Dec 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.340 {parse yymmdd} {
+ clock scan {70 Dec xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.341 {parse yymmdd} {
+ clock scan {70 December 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.342 {parse yymmdd} {
+ clock scan {70 December xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.343 {parse yymmdd} {
+ clock scan {70 December 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.344 {parse yymmdd} {
+ clock scan {70 December xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.345 {parse yymmdd} {
+ clock scan {70 Dec 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.346 {parse yymmdd} {
+ clock scan {70 Dec xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.347 {parse yymmdd} {
+ clock scan {70 Dec 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.348 {parse yymmdd} {
+ clock scan {70 Dec xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.349 {parse yymmdd} {
+ clock scan {70 12 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.350 {parse yymmdd} {
+ clock scan {70 12 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.351 {parse yymmdd} {
+ clock scan {70 12 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.352 {parse yymmdd} {
+ clock scan {70 12 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.353 {parse yymmdd} {
+ clock scan {70 xii 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.354 {parse yymmdd} {
+ clock scan {70 xii xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.355 {parse yymmdd} {
+ clock scan {70 xii 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.356 {parse yymmdd} {
+ clock scan {70 xii xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.357 {parse yymmdd} {
+ clock scan {70 12 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.358 {parse yymmdd} {
+ clock scan {70 12 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.359 {parse yymmdd} {
+ clock scan {70 12 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.360 {parse yymmdd} {
+ clock scan {70 12 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.361 {parse yymmdd} {
+ clock scan {lxx Dec 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.362 {parse yymmdd} {
+ clock scan {lxx Dec xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.363 {parse yymmdd} {
+ clock scan {lxx Dec 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.364 {parse yymmdd} {
+ clock scan {lxx Dec xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.365 {parse yymmdd} {
+ clock scan {lxx December 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.366 {parse yymmdd} {
+ clock scan {lxx December xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.367 {parse yymmdd} {
+ clock scan {lxx December 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.368 {parse yymmdd} {
+ clock scan {lxx December xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.369 {parse yymmdd} {
+ clock scan {lxx Dec 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.370 {parse yymmdd} {
+ clock scan {lxx Dec xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.371 {parse yymmdd} {
+ clock scan {lxx Dec 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.372 {parse yymmdd} {
+ clock scan {lxx Dec xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.373 {parse yymmdd} {
+ clock scan {lxx 12 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.374 {parse yymmdd} {
+ clock scan {lxx 12 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.375 {parse yymmdd} {
+ clock scan {lxx 12 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.376 {parse yymmdd} {
+ clock scan {lxx 12 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.377 {parse yymmdd} {
+ clock scan {lxx xii 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.378 {parse yymmdd} {
+ clock scan {lxx xii xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.379 {parse yymmdd} {
+ clock scan {lxx xii 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.380 {parse yymmdd} {
+ clock scan {lxx xii xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.381 {parse yymmdd} {
+ clock scan {lxx 12 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.382 {parse yymmdd} {
+ clock scan {lxx 12 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.383 {parse yymmdd} {
+ clock scan {lxx 12 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.384 {parse yymmdd} {
+ clock scan {lxx 12 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.385 {parse yymmdd} {
+ clock scan {00 Jan 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.386 {parse yymmdd} {
+ clock scan {00 Jan ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.387 {parse yymmdd} {
+ clock scan {00 Jan 2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.388 {parse yymmdd} {
+ clock scan {00 Jan ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.389 {parse yymmdd} {
+ clock scan {00 January 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.390 {parse yymmdd} {
+ clock scan {00 January ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.391 {parse yymmdd} {
+ clock scan {00 January 2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.392 {parse yymmdd} {
+ clock scan {00 January ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.393 {parse yymmdd} {
+ clock scan {00 Jan 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.394 {parse yymmdd} {
+ clock scan {00 Jan ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.395 {parse yymmdd} {
+ clock scan {00 Jan 2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.396 {parse yymmdd} {
+ clock scan {00 Jan ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.397 {parse yymmdd} {
+ clock scan {00 01 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.398 {parse yymmdd} {
+ clock scan {00 01 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.399 {parse yymmdd} {
+ clock scan {00 01 2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.400 {parse yymmdd} {
+ clock scan {00 01 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.401 {parse yymmdd} {
+ clock scan {00 i 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.402 {parse yymmdd} {
+ clock scan {00 i ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.403 {parse yymmdd} {
+ clock scan {00 i 2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.404 {parse yymmdd} {
+ clock scan {00 i ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.405 {parse yymmdd} {
+ clock scan {00 1 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.406 {parse yymmdd} {
+ clock scan {00 1 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.407 {parse yymmdd} {
+ clock scan {00 1 2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.408 {parse yymmdd} {
+ clock scan {00 1 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.409 {parse yymmdd} {
+ clock scan {? Jan 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.410 {parse yymmdd} {
+ clock scan {? Jan ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.411 {parse yymmdd} {
+ clock scan {? Jan 2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.412 {parse yymmdd} {
+ clock scan {? Jan ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.413 {parse yymmdd} {
+ clock scan {? January 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.414 {parse yymmdd} {
+ clock scan {? January ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.415 {parse yymmdd} {
+ clock scan {? January 2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.416 {parse yymmdd} {
+ clock scan {? January ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.417 {parse yymmdd} {
+ clock scan {? Jan 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.418 {parse yymmdd} {
+ clock scan {? Jan ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.419 {parse yymmdd} {
+ clock scan {? Jan 2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.420 {parse yymmdd} {
+ clock scan {? Jan ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.421 {parse yymmdd} {
+ clock scan {? 01 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.422 {parse yymmdd} {
+ clock scan {? 01 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.423 {parse yymmdd} {
+ clock scan {? 01 2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.424 {parse yymmdd} {
+ clock scan {? 01 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.425 {parse yymmdd} {
+ clock scan {? i 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.426 {parse yymmdd} {
+ clock scan {? i ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.427 {parse yymmdd} {
+ clock scan {? i 2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.428 {parse yymmdd} {
+ clock scan {? i ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.429 {parse yymmdd} {
+ clock scan {? 1 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.430 {parse yymmdd} {
+ clock scan {? 1 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.431 {parse yymmdd} {
+ clock scan {? 1 2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.432 {parse yymmdd} {
+ clock scan {? 1 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.433 {parse yymmdd} {
+ clock scan {00 Jan 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.434 {parse yymmdd} {
+ clock scan {00 Jan xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.435 {parse yymmdd} {
+ clock scan {00 Jan 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.436 {parse yymmdd} {
+ clock scan {00 Jan xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.437 {parse yymmdd} {
+ clock scan {00 January 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.438 {parse yymmdd} {
+ clock scan {00 January xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.439 {parse yymmdd} {
+ clock scan {00 January 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.440 {parse yymmdd} {
+ clock scan {00 January xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.441 {parse yymmdd} {
+ clock scan {00 Jan 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.442 {parse yymmdd} {
+ clock scan {00 Jan xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.443 {parse yymmdd} {
+ clock scan {00 Jan 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.444 {parse yymmdd} {
+ clock scan {00 Jan xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.445 {parse yymmdd} {
+ clock scan {00 01 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.446 {parse yymmdd} {
+ clock scan {00 01 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.447 {parse yymmdd} {
+ clock scan {00 01 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.448 {parse yymmdd} {
+ clock scan {00 01 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.449 {parse yymmdd} {
+ clock scan {00 i 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.450 {parse yymmdd} {
+ clock scan {00 i xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.451 {parse yymmdd} {
+ clock scan {00 i 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.452 {parse yymmdd} {
+ clock scan {00 i xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.453 {parse yymmdd} {
+ clock scan {00 1 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.454 {parse yymmdd} {
+ clock scan {00 1 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.455 {parse yymmdd} {
+ clock scan {00 1 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.456 {parse yymmdd} {
+ clock scan {00 1 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.457 {parse yymmdd} {
+ clock scan {? Jan 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.458 {parse yymmdd} {
+ clock scan {? Jan xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.459 {parse yymmdd} {
+ clock scan {? Jan 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.460 {parse yymmdd} {
+ clock scan {? Jan xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.461 {parse yymmdd} {
+ clock scan {? January 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.462 {parse yymmdd} {
+ clock scan {? January xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.463 {parse yymmdd} {
+ clock scan {? January 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.464 {parse yymmdd} {
+ clock scan {? January xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.465 {parse yymmdd} {
+ clock scan {? Jan 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.466 {parse yymmdd} {
+ clock scan {? Jan xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.467 {parse yymmdd} {
+ clock scan {? Jan 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.468 {parse yymmdd} {
+ clock scan {? Jan xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.469 {parse yymmdd} {
+ clock scan {? 01 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.470 {parse yymmdd} {
+ clock scan {? 01 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.471 {parse yymmdd} {
+ clock scan {? 01 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.472 {parse yymmdd} {
+ clock scan {? 01 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.473 {parse yymmdd} {
+ clock scan {? i 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.474 {parse yymmdd} {
+ clock scan {? i xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.475 {parse yymmdd} {
+ clock scan {? i 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.476 {parse yymmdd} {
+ clock scan {? i xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.477 {parse yymmdd} {
+ clock scan {? 1 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.478 {parse yymmdd} {
+ clock scan {? 1 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.479 {parse yymmdd} {
+ clock scan {? 1 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.480 {parse yymmdd} {
+ clock scan {? 1 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.481 {parse yymmdd} {
+ clock scan {00 Dec 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.482 {parse yymmdd} {
+ clock scan {00 Dec ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.483 {parse yymmdd} {
+ clock scan {00 Dec 2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.484 {parse yymmdd} {
+ clock scan {00 Dec ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.485 {parse yymmdd} {
+ clock scan {00 December 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.486 {parse yymmdd} {
+ clock scan {00 December ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.487 {parse yymmdd} {
+ clock scan {00 December 2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.488 {parse yymmdd} {
+ clock scan {00 December ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.489 {parse yymmdd} {
+ clock scan {00 Dec 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.490 {parse yymmdd} {
+ clock scan {00 Dec ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.491 {parse yymmdd} {
+ clock scan {00 Dec 2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.492 {parse yymmdd} {
+ clock scan {00 Dec ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.493 {parse yymmdd} {
+ clock scan {00 12 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.494 {parse yymmdd} {
+ clock scan {00 12 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.495 {parse yymmdd} {
+ clock scan {00 12 2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.496 {parse yymmdd} {
+ clock scan {00 12 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.497 {parse yymmdd} {
+ clock scan {00 xii 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.498 {parse yymmdd} {
+ clock scan {00 xii ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.499 {parse yymmdd} {
+ clock scan {00 xii 2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.500 {parse yymmdd} {
+ clock scan {00 xii ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.501 {parse yymmdd} {
+ clock scan {00 12 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.502 {parse yymmdd} {
+ clock scan {00 12 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.503 {parse yymmdd} {
+ clock scan {00 12 2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.504 {parse yymmdd} {
+ clock scan {00 12 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.505 {parse yymmdd} {
+ clock scan {? Dec 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.506 {parse yymmdd} {
+ clock scan {? Dec ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.507 {parse yymmdd} {
+ clock scan {? Dec 2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.508 {parse yymmdd} {
+ clock scan {? Dec ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.509 {parse yymmdd} {
+ clock scan {? December 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.510 {parse yymmdd} {
+ clock scan {? December ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.511 {parse yymmdd} {
+ clock scan {? December 2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.512 {parse yymmdd} {
+ clock scan {? December ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.513 {parse yymmdd} {
+ clock scan {? Dec 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.514 {parse yymmdd} {
+ clock scan {? Dec ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.515 {parse yymmdd} {
+ clock scan {? Dec 2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.516 {parse yymmdd} {
+ clock scan {? Dec ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.517 {parse yymmdd} {
+ clock scan {? 12 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.518 {parse yymmdd} {
+ clock scan {? 12 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.519 {parse yymmdd} {
+ clock scan {? 12 2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.520 {parse yymmdd} {
+ clock scan {? 12 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.521 {parse yymmdd} {
+ clock scan {? xii 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.522 {parse yymmdd} {
+ clock scan {? xii ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.523 {parse yymmdd} {
+ clock scan {? xii 2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.524 {parse yymmdd} {
+ clock scan {? xii ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.525 {parse yymmdd} {
+ clock scan {? 12 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.526 {parse yymmdd} {
+ clock scan {? 12 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.527 {parse yymmdd} {
+ clock scan {? 12 2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.528 {parse yymmdd} {
+ clock scan {? 12 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.529 {parse yymmdd} {
+ clock scan {00 Dec 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.530 {parse yymmdd} {
+ clock scan {00 Dec xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.531 {parse yymmdd} {
+ clock scan {00 Dec 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.532 {parse yymmdd} {
+ clock scan {00 Dec xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.533 {parse yymmdd} {
+ clock scan {00 December 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.534 {parse yymmdd} {
+ clock scan {00 December xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.535 {parse yymmdd} {
+ clock scan {00 December 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.536 {parse yymmdd} {
+ clock scan {00 December xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.537 {parse yymmdd} {
+ clock scan {00 Dec 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.538 {parse yymmdd} {
+ clock scan {00 Dec xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.539 {parse yymmdd} {
+ clock scan {00 Dec 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.540 {parse yymmdd} {
+ clock scan {00 Dec xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.541 {parse yymmdd} {
+ clock scan {00 12 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.542 {parse yymmdd} {
+ clock scan {00 12 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.543 {parse yymmdd} {
+ clock scan {00 12 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.544 {parse yymmdd} {
+ clock scan {00 12 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.545 {parse yymmdd} {
+ clock scan {00 xii 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.546 {parse yymmdd} {
+ clock scan {00 xii xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.547 {parse yymmdd} {
+ clock scan {00 xii 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.548 {parse yymmdd} {
+ clock scan {00 xii xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.549 {parse yymmdd} {
+ clock scan {00 12 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.550 {parse yymmdd} {
+ clock scan {00 12 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.551 {parse yymmdd} {
+ clock scan {00 12 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.552 {parse yymmdd} {
+ clock scan {00 12 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.553 {parse yymmdd} {
+ clock scan {? Dec 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.554 {parse yymmdd} {
+ clock scan {? Dec xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.555 {parse yymmdd} {
+ clock scan {? Dec 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.556 {parse yymmdd} {
+ clock scan {? Dec xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.557 {parse yymmdd} {
+ clock scan {? December 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.558 {parse yymmdd} {
+ clock scan {? December xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.559 {parse yymmdd} {
+ clock scan {? December 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.560 {parse yymmdd} {
+ clock scan {? December xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.561 {parse yymmdd} {
+ clock scan {? Dec 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.562 {parse yymmdd} {
+ clock scan {? Dec xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.563 {parse yymmdd} {
+ clock scan {? Dec 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.564 {parse yymmdd} {
+ clock scan {? Dec xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.565 {parse yymmdd} {
+ clock scan {? 12 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.566 {parse yymmdd} {
+ clock scan {? 12 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.567 {parse yymmdd} {
+ clock scan {? 12 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.568 {parse yymmdd} {
+ clock scan {? 12 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.569 {parse yymmdd} {
+ clock scan {? xii 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.570 {parse yymmdd} {
+ clock scan {? xii xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.571 {parse yymmdd} {
+ clock scan {? xii 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.572 {parse yymmdd} {
+ clock scan {? xii xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.573 {parse yymmdd} {
+ clock scan {? 12 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.574 {parse yymmdd} {
+ clock scan {? 12 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.575 {parse yymmdd} {
+ clock scan {? 12 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.576 {parse yymmdd} {
+ clock scan {? 12 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.577 {parse yymmdd} {
+ clock scan {37 Jan 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.578 {parse yymmdd} {
+ clock scan {37 Jan ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.579 {parse yymmdd} {
+ clock scan {37 Jan 2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.580 {parse yymmdd} {
+ clock scan {37 Jan ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.581 {parse yymmdd} {
+ clock scan {37 January 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.582 {parse yymmdd} {
+ clock scan {37 January ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.583 {parse yymmdd} {
+ clock scan {37 January 2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.584 {parse yymmdd} {
+ clock scan {37 January ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.585 {parse yymmdd} {
+ clock scan {37 Jan 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.586 {parse yymmdd} {
+ clock scan {37 Jan ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.587 {parse yymmdd} {
+ clock scan {37 Jan 2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.588 {parse yymmdd} {
+ clock scan {37 Jan ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.589 {parse yymmdd} {
+ clock scan {37 01 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.590 {parse yymmdd} {
+ clock scan {37 01 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.591 {parse yymmdd} {
+ clock scan {37 01 2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.592 {parse yymmdd} {
+ clock scan {37 01 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.593 {parse yymmdd} {
+ clock scan {37 i 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.594 {parse yymmdd} {
+ clock scan {37 i ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.595 {parse yymmdd} {
+ clock scan {37 i 2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.596 {parse yymmdd} {
+ clock scan {37 i ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.597 {parse yymmdd} {
+ clock scan {37 1 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.598 {parse yymmdd} {
+ clock scan {37 1 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.599 {parse yymmdd} {
+ clock scan {37 1 2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.600 {parse yymmdd} {
+ clock scan {37 1 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.601 {parse yymmdd} {
+ clock scan {xxxvii Jan 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.602 {parse yymmdd} {
+ clock scan {xxxvii Jan ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.603 {parse yymmdd} {
+ clock scan {xxxvii Jan 2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.604 {parse yymmdd} {
+ clock scan {xxxvii Jan ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.605 {parse yymmdd} {
+ clock scan {xxxvii January 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.606 {parse yymmdd} {
+ clock scan {xxxvii January ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.607 {parse yymmdd} {
+ clock scan {xxxvii January 2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.608 {parse yymmdd} {
+ clock scan {xxxvii January ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.609 {parse yymmdd} {
+ clock scan {xxxvii Jan 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.610 {parse yymmdd} {
+ clock scan {xxxvii Jan ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.611 {parse yymmdd} {
+ clock scan {xxxvii Jan 2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.612 {parse yymmdd} {
+ clock scan {xxxvii Jan ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.613 {parse yymmdd} {
+ clock scan {xxxvii 01 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.614 {parse yymmdd} {
+ clock scan {xxxvii 01 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.615 {parse yymmdd} {
+ clock scan {xxxvii 01 2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.616 {parse yymmdd} {
+ clock scan {xxxvii 01 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.617 {parse yymmdd} {
+ clock scan {xxxvii i 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.618 {parse yymmdd} {
+ clock scan {xxxvii i ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.619 {parse yymmdd} {
+ clock scan {xxxvii i 2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.620 {parse yymmdd} {
+ clock scan {xxxvii i ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.621 {parse yymmdd} {
+ clock scan {xxxvii 1 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.622 {parse yymmdd} {
+ clock scan {xxxvii 1 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.623 {parse yymmdd} {
+ clock scan {xxxvii 1 2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.624 {parse yymmdd} {
+ clock scan {xxxvii 1 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.625 {parse yymmdd} {
+ clock scan {37 Jan 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.626 {parse yymmdd} {
+ clock scan {37 Jan xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.627 {parse yymmdd} {
+ clock scan {37 Jan 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.628 {parse yymmdd} {
+ clock scan {37 Jan xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.629 {parse yymmdd} {
+ clock scan {37 January 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.630 {parse yymmdd} {
+ clock scan {37 January xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.631 {parse yymmdd} {
+ clock scan {37 January 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.632 {parse yymmdd} {
+ clock scan {37 January xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.633 {parse yymmdd} {
+ clock scan {37 Jan 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.634 {parse yymmdd} {
+ clock scan {37 Jan xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.635 {parse yymmdd} {
+ clock scan {37 Jan 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.636 {parse yymmdd} {
+ clock scan {37 Jan xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.637 {parse yymmdd} {
+ clock scan {37 01 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.638 {parse yymmdd} {
+ clock scan {37 01 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.639 {parse yymmdd} {
+ clock scan {37 01 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.640 {parse yymmdd} {
+ clock scan {37 01 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.641 {parse yymmdd} {
+ clock scan {37 i 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.642 {parse yymmdd} {
+ clock scan {37 i xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.643 {parse yymmdd} {
+ clock scan {37 i 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.644 {parse yymmdd} {
+ clock scan {37 i xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.645 {parse yymmdd} {
+ clock scan {37 1 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.646 {parse yymmdd} {
+ clock scan {37 1 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.647 {parse yymmdd} {
+ clock scan {37 1 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.648 {parse yymmdd} {
+ clock scan {37 1 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.649 {parse yymmdd} {
+ clock scan {xxxvii Jan 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.650 {parse yymmdd} {
+ clock scan {xxxvii Jan xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.651 {parse yymmdd} {
+ clock scan {xxxvii Jan 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.652 {parse yymmdd} {
+ clock scan {xxxvii Jan xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.653 {parse yymmdd} {
+ clock scan {xxxvii January 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.654 {parse yymmdd} {
+ clock scan {xxxvii January xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.655 {parse yymmdd} {
+ clock scan {xxxvii January 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.656 {parse yymmdd} {
+ clock scan {xxxvii January xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.657 {parse yymmdd} {
+ clock scan {xxxvii Jan 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.658 {parse yymmdd} {
+ clock scan {xxxvii Jan xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.659 {parse yymmdd} {
+ clock scan {xxxvii Jan 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.660 {parse yymmdd} {
+ clock scan {xxxvii Jan xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.661 {parse yymmdd} {
+ clock scan {xxxvii 01 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.662 {parse yymmdd} {
+ clock scan {xxxvii 01 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.663 {parse yymmdd} {
+ clock scan {xxxvii 01 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.664 {parse yymmdd} {
+ clock scan {xxxvii 01 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.665 {parse yymmdd} {
+ clock scan {xxxvii i 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.666 {parse yymmdd} {
+ clock scan {xxxvii i xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.667 {parse yymmdd} {
+ clock scan {xxxvii i 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.668 {parse yymmdd} {
+ clock scan {xxxvii i xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.669 {parse yymmdd} {
+ clock scan {xxxvii 1 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.670 {parse yymmdd} {
+ clock scan {xxxvii 1 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.671 {parse yymmdd} {
+ clock scan {xxxvii 1 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.672 {parse yymmdd} {
+ clock scan {xxxvii 1 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.673 {parse yymmdd} {
+ clock scan {37 Dec 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.674 {parse yymmdd} {
+ clock scan {37 Dec ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.675 {parse yymmdd} {
+ clock scan {37 Dec 2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.676 {parse yymmdd} {
+ clock scan {37 Dec ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.677 {parse yymmdd} {
+ clock scan {37 December 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.678 {parse yymmdd} {
+ clock scan {37 December ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.679 {parse yymmdd} {
+ clock scan {37 December 2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.680 {parse yymmdd} {
+ clock scan {37 December ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.681 {parse yymmdd} {
+ clock scan {37 Dec 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.682 {parse yymmdd} {
+ clock scan {37 Dec ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.683 {parse yymmdd} {
+ clock scan {37 Dec 2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.684 {parse yymmdd} {
+ clock scan {37 Dec ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.685 {parse yymmdd} {
+ clock scan {37 12 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.686 {parse yymmdd} {
+ clock scan {37 12 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.687 {parse yymmdd} {
+ clock scan {37 12 2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.688 {parse yymmdd} {
+ clock scan {37 12 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.689 {parse yymmdd} {
+ clock scan {37 xii 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.690 {parse yymmdd} {
+ clock scan {37 xii ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.691 {parse yymmdd} {
+ clock scan {37 xii 2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.692 {parse yymmdd} {
+ clock scan {37 xii ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.693 {parse yymmdd} {
+ clock scan {37 12 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.694 {parse yymmdd} {
+ clock scan {37 12 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.695 {parse yymmdd} {
+ clock scan {37 12 2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.696 {parse yymmdd} {
+ clock scan {37 12 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.697 {parse yymmdd} {
+ clock scan {xxxvii Dec 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.698 {parse yymmdd} {
+ clock scan {xxxvii Dec ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.699 {parse yymmdd} {
+ clock scan {xxxvii Dec 2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.700 {parse yymmdd} {
+ clock scan {xxxvii Dec ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.701 {parse yymmdd} {
+ clock scan {xxxvii December 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.702 {parse yymmdd} {
+ clock scan {xxxvii December ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.703 {parse yymmdd} {
+ clock scan {xxxvii December 2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.704 {parse yymmdd} {
+ clock scan {xxxvii December ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.705 {parse yymmdd} {
+ clock scan {xxxvii Dec 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.706 {parse yymmdd} {
+ clock scan {xxxvii Dec ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.707 {parse yymmdd} {
+ clock scan {xxxvii Dec 2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.708 {parse yymmdd} {
+ clock scan {xxxvii Dec ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.709 {parse yymmdd} {
+ clock scan {xxxvii 12 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.710 {parse yymmdd} {
+ clock scan {xxxvii 12 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.711 {parse yymmdd} {
+ clock scan {xxxvii 12 2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.712 {parse yymmdd} {
+ clock scan {xxxvii 12 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.713 {parse yymmdd} {
+ clock scan {xxxvii xii 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.714 {parse yymmdd} {
+ clock scan {xxxvii xii ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.715 {parse yymmdd} {
+ clock scan {xxxvii xii 2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.716 {parse yymmdd} {
+ clock scan {xxxvii xii ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.717 {parse yymmdd} {
+ clock scan {xxxvii 12 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.718 {parse yymmdd} {
+ clock scan {xxxvii 12 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.719 {parse yymmdd} {
+ clock scan {xxxvii 12 2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.720 {parse yymmdd} {
+ clock scan {xxxvii 12 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.721 {parse yymmdd} {
+ clock scan {37 Dec 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.722 {parse yymmdd} {
+ clock scan {37 Dec xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.723 {parse yymmdd} {
+ clock scan {37 Dec 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.724 {parse yymmdd} {
+ clock scan {37 Dec xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.725 {parse yymmdd} {
+ clock scan {37 December 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.726 {parse yymmdd} {
+ clock scan {37 December xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.727 {parse yymmdd} {
+ clock scan {37 December 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.728 {parse yymmdd} {
+ clock scan {37 December xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.729 {parse yymmdd} {
+ clock scan {37 Dec 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.730 {parse yymmdd} {
+ clock scan {37 Dec xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.731 {parse yymmdd} {
+ clock scan {37 Dec 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.732 {parse yymmdd} {
+ clock scan {37 Dec xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.733 {parse yymmdd} {
+ clock scan {37 12 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.734 {parse yymmdd} {
+ clock scan {37 12 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.735 {parse yymmdd} {
+ clock scan {37 12 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.736 {parse yymmdd} {
+ clock scan {37 12 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.737 {parse yymmdd} {
+ clock scan {37 xii 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.738 {parse yymmdd} {
+ clock scan {37 xii xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.739 {parse yymmdd} {
+ clock scan {37 xii 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.740 {parse yymmdd} {
+ clock scan {37 xii xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.741 {parse yymmdd} {
+ clock scan {37 12 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.742 {parse yymmdd} {
+ clock scan {37 12 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.743 {parse yymmdd} {
+ clock scan {37 12 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.744 {parse yymmdd} {
+ clock scan {37 12 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.745 {parse yymmdd} {
+ clock scan {xxxvii Dec 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.746 {parse yymmdd} {
+ clock scan {xxxvii Dec xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.747 {parse yymmdd} {
+ clock scan {xxxvii Dec 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.748 {parse yymmdd} {
+ clock scan {xxxvii Dec xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.749 {parse yymmdd} {
+ clock scan {xxxvii December 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.750 {parse yymmdd} {
+ clock scan {xxxvii December xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.751 {parse yymmdd} {
+ clock scan {xxxvii December 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.752 {parse yymmdd} {
+ clock scan {xxxvii December xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.753 {parse yymmdd} {
+ clock scan {xxxvii Dec 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.754 {parse yymmdd} {
+ clock scan {xxxvii Dec xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.755 {parse yymmdd} {
+ clock scan {xxxvii Dec 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.756 {parse yymmdd} {
+ clock scan {xxxvii Dec xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.757 {parse yymmdd} {
+ clock scan {xxxvii 12 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.758 {parse yymmdd} {
+ clock scan {xxxvii 12 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.759 {parse yymmdd} {
+ clock scan {xxxvii 12 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.760 {parse yymmdd} {
+ clock scan {xxxvii 12 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.761 {parse yymmdd} {
+ clock scan {xxxvii xii 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.762 {parse yymmdd} {
+ clock scan {xxxvii xii xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.763 {parse yymmdd} {
+ clock scan {xxxvii xii 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.764 {parse yymmdd} {
+ clock scan {xxxvii xii xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.765 {parse yymmdd} {
+ clock scan {xxxvii 12 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.766 {parse yymmdd} {
+ clock scan {xxxvii 12 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.767 {parse yymmdd} {
+ clock scan {xxxvii 12 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.768 {parse yymmdd} {
+ clock scan {xxxvii 12 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+# END testcases14
+
+test clock-15.1 {yymmdd precedence below seconds} {
+ list [clock scan {0 000101} -format {%s %y%m%d} -gmt true] \
+ [clock scan {000101 0} -format {%y%m%d %s} -gmt true]
+} {0 0}
+
+test clock-15.2 {yymmdd precedence below julian day} {
+ list [clock scan {2440588 000101} -format {%J %y%m%d} -gmt true] \
+ [clock scan {000101 2440588} -format {%y%m%d %J} -gmt true]
+} {0 0}
+
+test clock-15.3 {yymmdd precedence below yyyyWwwd} {
+ list [clock scan {1970W014000101} -format {%GW%V%u%y%m%d} -gmt true] \
+ [clock scan {0001011970W014} -format {%y%m%d%GW%V%u} -gmt true]
+} {0 0}
+
+# Test parsing of yyddd
+
+test clock-16.1 {parse yyddd} {
+ clock scan {70 001} -format {%y %j} -locale en_US_roman -gmt 1
+} 0
+test clock-16.2 {parse yyddd} {
+ clock scan {70 365} -format {%y %j} -locale en_US_roman -gmt 1
+} 31449600
+test clock-16.3 {parse yyddd} {
+ clock scan {71 001} -format {%y %j} -locale en_US_roman -gmt 1
+} 31536000
+test clock-16.4 {parse yyddd} {
+ clock scan {71 365} -format {%y %j} -locale en_US_roman -gmt 1
+} 62985600
+test clock-16.5 {parse yyddd} {
+ clock scan {00 001} -format {%y %j} -locale en_US_roman -gmt 1
+} 946684800
+test clock-16.6 {parse yyddd} {
+ clock scan {00 365} -format {%y %j} -locale en_US_roman -gmt 1
+} 978134400
+test clock-16.7 {parse yyddd} {
+ clock scan {01 001} -format {%y %j} -locale en_US_roman -gmt 1
+} 978307200
+test clock-16.8 {parse yyddd} {
+ clock scan {01 365} -format {%y %j} -locale en_US_roman -gmt 1
+} 1009756800
+
+test clock-16.9 {seconds take precedence over yyddd} {
+ list [clock scan {0 00001} -format {%s %y%j} -gmt true] \
+ [clock scan {00001 0} -format {%y%j %s} -gmt true]
+} {0 0}
+test clock-16.10 {julian day takes precedence over yyddd} {
+ list [clock scan {2440588 00001} -format {%J %y%j} -gmt true] \
+ [clock scan {00001 2440588} -format {%Y%j %J} -gmt true]
+} {0 0}
+test clock-16.11 {yyddd precedence below yyyyWwwd} {
+ list [clock scan {1970W01400001} -format {%GW%V%u%y%j} -gmt true] \
+ [clock scan {000011970W014} -format {%y%j%GW%V%u} -gmt true]
+} {0 0}
+
+# BEGIN testcases17
+
+# Test parsing of yyWwwd
+
+test clock-17.1 {parse yyWwwd} {
+ clock scan {70 W01 Fri} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.2 {parse yyWwwd} {
+ clock scan {70 W01 Friday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.3 {parse yyWwwd} {
+ clock scan {70 W01 5} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.4 {parse yyWwwd} {
+ clock scan {70 W01 5} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.5 {parse yyWwwd} {
+ clock scan {70 W01 v} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.6 {parse yyWwwd} {
+ clock scan {70 W01 v} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.7 {parse yyWwwd} {
+ clock scan {70 W05 Sat} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.8 {parse yyWwwd} {
+ clock scan {70 W05 Saturday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.9 {parse yyWwwd} {
+ clock scan {70 W05 6} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.10 {parse yyWwwd} {
+ clock scan {70 W05 6} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.11 {parse yyWwwd} {
+ clock scan {70 W05 vi} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.12 {parse yyWwwd} {
+ clock scan {70 W05 vi} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.13 {parse yyWwwd} {
+ clock scan {70 W49 Wed} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.14 {parse yyWwwd} {
+ clock scan {70 W49 Wednesday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.15 {parse yyWwwd} {
+ clock scan {70 W49 3} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.16 {parse yyWwwd} {
+ clock scan {70 W49 3} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.17 {parse yyWwwd} {
+ clock scan {70 W49 iii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.18 {parse yyWwwd} {
+ clock scan {70 W49 iii} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.19 {parse yyWwwd} {
+ clock scan {70 W53 Thu} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.20 {parse yyWwwd} {
+ clock scan {70 W53 Thursday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.21 {parse yyWwwd} {
+ clock scan {70 W53 4} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.22 {parse yyWwwd} {
+ clock scan {70 W53 4} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.23 {parse yyWwwd} {
+ clock scan {70 W53 iv} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.24 {parse yyWwwd} {
+ clock scan {70 W53 iv} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.25 {parse yyWwwd} {
+ clock scan {70 W53 Sat} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.26 {parse yyWwwd} {
+ clock scan {70 W53 Saturday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.27 {parse yyWwwd} {
+ clock scan {70 W53 6} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.28 {parse yyWwwd} {
+ clock scan {70 W53 6} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.29 {parse yyWwwd} {
+ clock scan {70 W53 vi} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.30 {parse yyWwwd} {
+ clock scan {70 W53 vi} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.31 {parse yyWwwd} {
+ clock scan {71 W04 Sun} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.32 {parse yyWwwd} {
+ clock scan {71 W04 Sunday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.33 {parse yyWwwd} {
+ clock scan {71 W04 7} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.34 {parse yyWwwd} {
+ clock scan {71 W04 0} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.35 {parse yyWwwd} {
+ clock scan {71 W04 vii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.36 {parse yyWwwd} {
+ clock scan {71 W04 ?} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.37 {parse yyWwwd} {
+ clock scan {71 W48 Thu} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.38 {parse yyWwwd} {
+ clock scan {71 W48 Thursday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.39 {parse yyWwwd} {
+ clock scan {71 W48 4} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.40 {parse yyWwwd} {
+ clock scan {71 W48 4} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.41 {parse yyWwwd} {
+ clock scan {71 W48 iv} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.42 {parse yyWwwd} {
+ clock scan {71 W48 iv} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.43 {parse yyWwwd} {
+ clock scan {71 W52 Fri} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.44 {parse yyWwwd} {
+ clock scan {71 W52 Friday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.45 {parse yyWwwd} {
+ clock scan {71 W52 5} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.46 {parse yyWwwd} {
+ clock scan {71 W52 5} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.47 {parse yyWwwd} {
+ clock scan {71 W52 v} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.48 {parse yyWwwd} {
+ clock scan {71 W52 v} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.49 {parse yyWwwd} {
+ clock scan {99 W52 Sun} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.50 {parse yyWwwd} {
+ clock scan {99 W52 Sunday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.51 {parse yyWwwd} {
+ clock scan {99 W52 7} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.52 {parse yyWwwd} {
+ clock scan {99 W52 0} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.53 {parse yyWwwd} {
+ clock scan {99 W52 vii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.54 {parse yyWwwd} {
+ clock scan {99 W52 ?} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.55 {parse yyWwwd} {
+ clock scan {00 W05 Mon} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.56 {parse yyWwwd} {
+ clock scan {00 W05 Monday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.57 {parse yyWwwd} {
+ clock scan {00 W05 1} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.58 {parse yyWwwd} {
+ clock scan {00 W05 1} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.59 {parse yyWwwd} {
+ clock scan {00 W05 i} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.60 {parse yyWwwd} {
+ clock scan {00 W05 i} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.61 {parse yyWwwd} {
+ clock scan {00 W48 Sat} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.62 {parse yyWwwd} {
+ clock scan {00 W48 Saturday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.63 {parse yyWwwd} {
+ clock scan {00 W48 6} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.64 {parse yyWwwd} {
+ clock scan {00 W48 6} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.65 {parse yyWwwd} {
+ clock scan {00 W48 vi} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.66 {parse yyWwwd} {
+ clock scan {00 W48 vi} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.67 {parse yyWwwd} {
+ clock scan {00 W52 Sun} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.68 {parse yyWwwd} {
+ clock scan {00 W52 Sunday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.69 {parse yyWwwd} {
+ clock scan {00 W52 7} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.70 {parse yyWwwd} {
+ clock scan {00 W52 0} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.71 {parse yyWwwd} {
+ clock scan {00 W52 vii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.72 {parse yyWwwd} {
+ clock scan {00 W52 ?} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.73 {parse yyWwwd} {
+ clock scan {01 W01 Tue} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.74 {parse yyWwwd} {
+ clock scan {01 W01 Tuesday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.75 {parse yyWwwd} {
+ clock scan {01 W01 2} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.76 {parse yyWwwd} {
+ clock scan {01 W01 2} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.77 {parse yyWwwd} {
+ clock scan {01 W01 ii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.78 {parse yyWwwd} {
+ clock scan {01 W01 ii} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.79 {parse yyWwwd} {
+ clock scan {01 W05 Wed} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.80 {parse yyWwwd} {
+ clock scan {01 W05 Wednesday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.81 {parse yyWwwd} {
+ clock scan {01 W05 3} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.82 {parse yyWwwd} {
+ clock scan {01 W05 3} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.83 {parse yyWwwd} {
+ clock scan {01 W05 iii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.84 {parse yyWwwd} {
+ clock scan {01 W05 iii} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.85 {parse yyWwwd} {
+ clock scan {01 W48 Sun} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.86 {parse yyWwwd} {
+ clock scan {01 W48 Sunday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.87 {parse yyWwwd} {
+ clock scan {01 W48 7} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.88 {parse yyWwwd} {
+ clock scan {01 W48 0} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.89 {parse yyWwwd} {
+ clock scan {01 W48 vii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.90 {parse yyWwwd} {
+ clock scan {01 W48 ?} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.91 {parse yyWwwd} {
+ clock scan {02 W01 Mon} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-17.92 {parse yyWwwd} {
+ clock scan {02 W01 Monday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-17.93 {parse yyWwwd} {
+ clock scan {02 W01 1} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-17.94 {parse yyWwwd} {
+ clock scan {02 W01 1} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-17.95 {parse yyWwwd} {
+ clock scan {02 W01 i} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-17.96 {parse yyWwwd} {
+ clock scan {02 W01 i} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 1009756800
+# END testcases17
+
+# Test precedence of yyWwwd
+
+test clock-18.1 {seconds take precedence over yyWwwd} {
+ list [clock scan {0 00W014} -format {%s %gW%V%u} -gmt true] \
+ [clock scan {00W014 0} -format {%gW%V%u %s} -gmt true]
+} {0 0}
+test clock-18.2 {julian day takes precedence over yyddd} {
+ list [clock scan {2440588 00W014} -format {%J %gW%V%u} -gmt true] \
+ [clock scan {00W014 2440588} -format {%gW%V%u %J} -gmt true]
+} {0 0}
+test clock-18.3 {yyWwwd precedence below yyyymmdd} {
+ list [clock scan {19700101 00W014} -format {%Y%m%d %gW%V%u} -gmt true] \
+ [clock scan {00W014 19700101} -format {%gW%V%u %Y%m%d} -gmt true]
+} {0 0}
+test clock-18.4 {yyWwwd precedence below yyyyddd} {
+ list [clock scan {1970001 00W014} -format {%Y%j %gW%V%u} -gmt true] \
+ [clock scan {00W014 1970001} -format {%gW%V%u %Y%j} -gmt true]
+} {0 0}
+
+# BEGIN testcases19
+
+# Test parsing of mmdd
+
+test clock-19.1 {parse mmdd} {
+ clock scan {Jan 02} -format {%b %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.2 {parse mmdd} {
+ clock scan {Jan ii} -format {%b %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.3 {parse mmdd} {
+ clock scan {Jan 2} -format {%b %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.4 {parse mmdd} {
+ clock scan {Jan ii} -format {%b %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.5 {parse mmdd} {
+ clock scan {January 02} -format {%B %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.6 {parse mmdd} {
+ clock scan {January ii} -format {%B %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.7 {parse mmdd} {
+ clock scan {January 2} -format {%B %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.8 {parse mmdd} {
+ clock scan {January ii} -format {%B %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.9 {parse mmdd} {
+ clock scan {Jan 02} -format {%h %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.10 {parse mmdd} {
+ clock scan {Jan ii} -format {%h %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.11 {parse mmdd} {
+ clock scan {Jan 2} -format {%h %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.12 {parse mmdd} {
+ clock scan {Jan ii} -format {%h %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.13 {parse mmdd} {
+ clock scan {01 02} -format {%m %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.14 {parse mmdd} {
+ clock scan {01 ii} -format {%m %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.15 {parse mmdd} {
+ clock scan {01 2} -format {%m %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.16 {parse mmdd} {
+ clock scan {01 ii} -format {%m %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.17 {parse mmdd} {
+ clock scan {i 02} -format {%Om %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.18 {parse mmdd} {
+ clock scan {i ii} -format {%Om %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.19 {parse mmdd} {
+ clock scan {i 2} -format {%Om %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.20 {parse mmdd} {
+ clock scan {i ii} -format {%Om %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.21 {parse mmdd} {
+ clock scan { 1 02} -format {%N %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.22 {parse mmdd} {
+ clock scan { 1 ii} -format {%N %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.23 {parse mmdd} {
+ clock scan { 1 2} -format {%N %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.24 {parse mmdd} {
+ clock scan { 1 ii} -format {%N %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.25 {parse mmdd} {
+ clock scan {Jan 31} -format {%b %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.26 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%b %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.27 {parse mmdd} {
+ clock scan {Jan 31} -format {%b %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.28 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%b %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.29 {parse mmdd} {
+ clock scan {January 31} -format {%B %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.30 {parse mmdd} {
+ clock scan {January xxxi} -format {%B %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.31 {parse mmdd} {
+ clock scan {January 31} -format {%B %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.32 {parse mmdd} {
+ clock scan {January xxxi} -format {%B %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.33 {parse mmdd} {
+ clock scan {Jan 31} -format {%h %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.34 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%h %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.35 {parse mmdd} {
+ clock scan {Jan 31} -format {%h %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.36 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%h %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.37 {parse mmdd} {
+ clock scan {01 31} -format {%m %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.38 {parse mmdd} {
+ clock scan {01 xxxi} -format {%m %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.39 {parse mmdd} {
+ clock scan {01 31} -format {%m %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.40 {parse mmdd} {
+ clock scan {01 xxxi} -format {%m %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.41 {parse mmdd} {
+ clock scan {i 31} -format {%Om %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.42 {parse mmdd} {
+ clock scan {i xxxi} -format {%Om %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.43 {parse mmdd} {
+ clock scan {i 31} -format {%Om %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.44 {parse mmdd} {
+ clock scan {i xxxi} -format {%Om %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.45 {parse mmdd} {
+ clock scan { 1 31} -format {%N %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.46 {parse mmdd} {
+ clock scan { 1 xxxi} -format {%N %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.47 {parse mmdd} {
+ clock scan { 1 31} -format {%N %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.48 {parse mmdd} {
+ clock scan { 1 xxxi} -format {%N %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.49 {parse mmdd} {
+ clock scan {Dec 02} -format {%b %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.50 {parse mmdd} {
+ clock scan {Dec ii} -format {%b %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.51 {parse mmdd} {
+ clock scan {Dec 2} -format {%b %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.52 {parse mmdd} {
+ clock scan {Dec ii} -format {%b %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.53 {parse mmdd} {
+ clock scan {December 02} -format {%B %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.54 {parse mmdd} {
+ clock scan {December ii} -format {%B %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.55 {parse mmdd} {
+ clock scan {December 2} -format {%B %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.56 {parse mmdd} {
+ clock scan {December ii} -format {%B %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.57 {parse mmdd} {
+ clock scan {Dec 02} -format {%h %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.58 {parse mmdd} {
+ clock scan {Dec ii} -format {%h %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.59 {parse mmdd} {
+ clock scan {Dec 2} -format {%h %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.60 {parse mmdd} {
+ clock scan {Dec ii} -format {%h %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.61 {parse mmdd} {
+ clock scan {12 02} -format {%m %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.62 {parse mmdd} {
+ clock scan {12 ii} -format {%m %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.63 {parse mmdd} {
+ clock scan {12 2} -format {%m %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.64 {parse mmdd} {
+ clock scan {12 ii} -format {%m %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.65 {parse mmdd} {
+ clock scan {xii 02} -format {%Om %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.66 {parse mmdd} {
+ clock scan {xii ii} -format {%Om %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.67 {parse mmdd} {
+ clock scan {xii 2} -format {%Om %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.68 {parse mmdd} {
+ clock scan {xii ii} -format {%Om %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.69 {parse mmdd} {
+ clock scan {12 02} -format {%N %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.70 {parse mmdd} {
+ clock scan {12 ii} -format {%N %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.71 {parse mmdd} {
+ clock scan {12 2} -format {%N %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.72 {parse mmdd} {
+ clock scan {12 ii} -format {%N %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.73 {parse mmdd} {
+ clock scan {Dec 31} -format {%b %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.74 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%b %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.75 {parse mmdd} {
+ clock scan {Dec 31} -format {%b %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.76 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%b %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.77 {parse mmdd} {
+ clock scan {December 31} -format {%B %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.78 {parse mmdd} {
+ clock scan {December xxxi} -format {%B %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.79 {parse mmdd} {
+ clock scan {December 31} -format {%B %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.80 {parse mmdd} {
+ clock scan {December xxxi} -format {%B %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.81 {parse mmdd} {
+ clock scan {Dec 31} -format {%h %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.82 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%h %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.83 {parse mmdd} {
+ clock scan {Dec 31} -format {%h %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.84 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%h %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.85 {parse mmdd} {
+ clock scan {12 31} -format {%m %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.86 {parse mmdd} {
+ clock scan {12 xxxi} -format {%m %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.87 {parse mmdd} {
+ clock scan {12 31} -format {%m %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.88 {parse mmdd} {
+ clock scan {12 xxxi} -format {%m %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.89 {parse mmdd} {
+ clock scan {xii 31} -format {%Om %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.90 {parse mmdd} {
+ clock scan {xii xxxi} -format {%Om %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.91 {parse mmdd} {
+ clock scan {xii 31} -format {%Om %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.92 {parse mmdd} {
+ clock scan {xii xxxi} -format {%Om %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.93 {parse mmdd} {
+ clock scan {12 31} -format {%N %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.94 {parse mmdd} {
+ clock scan {12 xxxi} -format {%N %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.95 {parse mmdd} {
+ clock scan {12 31} -format {%N %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.96 {parse mmdd} {
+ clock scan {12 xxxi} -format {%N %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.97 {parse mmdd} {
+ clock scan {Jan 02} -format {%b %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.98 {parse mmdd} {
+ clock scan {Jan ii} -format {%b %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.99 {parse mmdd} {
+ clock scan {Jan 2} -format {%b %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.100 {parse mmdd} {
+ clock scan {Jan ii} -format {%b %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.101 {parse mmdd} {
+ clock scan {January 02} -format {%B %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.102 {parse mmdd} {
+ clock scan {January ii} -format {%B %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.103 {parse mmdd} {
+ clock scan {January 2} -format {%B %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.104 {parse mmdd} {
+ clock scan {January ii} -format {%B %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.105 {parse mmdd} {
+ clock scan {Jan 02} -format {%h %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.106 {parse mmdd} {
+ clock scan {Jan ii} -format {%h %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.107 {parse mmdd} {
+ clock scan {Jan 2} -format {%h %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.108 {parse mmdd} {
+ clock scan {Jan ii} -format {%h %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.109 {parse mmdd} {
+ clock scan {01 02} -format {%m %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.110 {parse mmdd} {
+ clock scan {01 ii} -format {%m %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.111 {parse mmdd} {
+ clock scan {01 2} -format {%m %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.112 {parse mmdd} {
+ clock scan {01 ii} -format {%m %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.113 {parse mmdd} {
+ clock scan {i 02} -format {%Om %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.114 {parse mmdd} {
+ clock scan {i ii} -format {%Om %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.115 {parse mmdd} {
+ clock scan {i 2} -format {%Om %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.116 {parse mmdd} {
+ clock scan {i ii} -format {%Om %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.117 {parse mmdd} {
+ clock scan { 1 02} -format {%N %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.118 {parse mmdd} {
+ clock scan { 1 ii} -format {%N %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.119 {parse mmdd} {
+ clock scan { 1 2} -format {%N %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.120 {parse mmdd} {
+ clock scan { 1 ii} -format {%N %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.121 {parse mmdd} {
+ clock scan {Jan 31} -format {%b %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.122 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%b %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.123 {parse mmdd} {
+ clock scan {Jan 31} -format {%b %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.124 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%b %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.125 {parse mmdd} {
+ clock scan {January 31} -format {%B %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.126 {parse mmdd} {
+ clock scan {January xxxi} -format {%B %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.127 {parse mmdd} {
+ clock scan {January 31} -format {%B %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.128 {parse mmdd} {
+ clock scan {January xxxi} -format {%B %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.129 {parse mmdd} {
+ clock scan {Jan 31} -format {%h %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.130 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%h %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.131 {parse mmdd} {
+ clock scan {Jan 31} -format {%h %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.132 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%h %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.133 {parse mmdd} {
+ clock scan {01 31} -format {%m %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.134 {parse mmdd} {
+ clock scan {01 xxxi} -format {%m %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.135 {parse mmdd} {
+ clock scan {01 31} -format {%m %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.136 {parse mmdd} {
+ clock scan {01 xxxi} -format {%m %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.137 {parse mmdd} {
+ clock scan {i 31} -format {%Om %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.138 {parse mmdd} {
+ clock scan {i xxxi} -format {%Om %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.139 {parse mmdd} {
+ clock scan {i 31} -format {%Om %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.140 {parse mmdd} {
+ clock scan {i xxxi} -format {%Om %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.141 {parse mmdd} {
+ clock scan { 1 31} -format {%N %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.142 {parse mmdd} {
+ clock scan { 1 xxxi} -format {%N %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.143 {parse mmdd} {
+ clock scan { 1 31} -format {%N %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.144 {parse mmdd} {
+ clock scan { 1 xxxi} -format {%N %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.145 {parse mmdd} {
+ clock scan {Dec 02} -format {%b %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.146 {parse mmdd} {
+ clock scan {Dec ii} -format {%b %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.147 {parse mmdd} {
+ clock scan {Dec 2} -format {%b %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.148 {parse mmdd} {
+ clock scan {Dec ii} -format {%b %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.149 {parse mmdd} {
+ clock scan {December 02} -format {%B %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.150 {parse mmdd} {
+ clock scan {December ii} -format {%B %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.151 {parse mmdd} {
+ clock scan {December 2} -format {%B %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.152 {parse mmdd} {
+ clock scan {December ii} -format {%B %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.153 {parse mmdd} {
+ clock scan {Dec 02} -format {%h %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.154 {parse mmdd} {
+ clock scan {Dec ii} -format {%h %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.155 {parse mmdd} {
+ clock scan {Dec 2} -format {%h %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.156 {parse mmdd} {
+ clock scan {Dec ii} -format {%h %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.157 {parse mmdd} {
+ clock scan {12 02} -format {%m %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.158 {parse mmdd} {
+ clock scan {12 ii} -format {%m %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.159 {parse mmdd} {
+ clock scan {12 2} -format {%m %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.160 {parse mmdd} {
+ clock scan {12 ii} -format {%m %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.161 {parse mmdd} {
+ clock scan {xii 02} -format {%Om %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.162 {parse mmdd} {
+ clock scan {xii ii} -format {%Om %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.163 {parse mmdd} {
+ clock scan {xii 2} -format {%Om %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.164 {parse mmdd} {
+ clock scan {xii ii} -format {%Om %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.165 {parse mmdd} {
+ clock scan {12 02} -format {%N %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.166 {parse mmdd} {
+ clock scan {12 ii} -format {%N %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.167 {parse mmdd} {
+ clock scan {12 2} -format {%N %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.168 {parse mmdd} {
+ clock scan {12 ii} -format {%N %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.169 {parse mmdd} {
+ clock scan {Dec 31} -format {%b %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.170 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%b %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.171 {parse mmdd} {
+ clock scan {Dec 31} -format {%b %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.172 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%b %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.173 {parse mmdd} {
+ clock scan {December 31} -format {%B %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.174 {parse mmdd} {
+ clock scan {December xxxi} -format {%B %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.175 {parse mmdd} {
+ clock scan {December 31} -format {%B %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.176 {parse mmdd} {
+ clock scan {December xxxi} -format {%B %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.177 {parse mmdd} {
+ clock scan {Dec 31} -format {%h %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.178 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%h %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.179 {parse mmdd} {
+ clock scan {Dec 31} -format {%h %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.180 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%h %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.181 {parse mmdd} {
+ clock scan {12 31} -format {%m %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.182 {parse mmdd} {
+ clock scan {12 xxxi} -format {%m %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.183 {parse mmdd} {
+ clock scan {12 31} -format {%m %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.184 {parse mmdd} {
+ clock scan {12 xxxi} -format {%m %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.185 {parse mmdd} {
+ clock scan {xii 31} -format {%Om %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.186 {parse mmdd} {
+ clock scan {xii xxxi} -format {%Om %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.187 {parse mmdd} {
+ clock scan {xii 31} -format {%Om %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.188 {parse mmdd} {
+ clock scan {xii xxxi} -format {%Om %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.189 {parse mmdd} {
+ clock scan {12 31} -format {%N %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.190 {parse mmdd} {
+ clock scan {12 xxxi} -format {%N %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.191 {parse mmdd} {
+ clock scan {12 31} -format {%N %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.192 {parse mmdd} {
+ clock scan {12 xxxi} -format {%N %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.193 {parse mmdd} {
+ clock scan {Jan 02} -format {%b %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.194 {parse mmdd} {
+ clock scan {Jan ii} -format {%b %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.195 {parse mmdd} {
+ clock scan {Jan 2} -format {%b %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.196 {parse mmdd} {
+ clock scan {Jan ii} -format {%b %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.197 {parse mmdd} {
+ clock scan {January 02} -format {%B %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.198 {parse mmdd} {
+ clock scan {January ii} -format {%B %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.199 {parse mmdd} {
+ clock scan {January 2} -format {%B %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.200 {parse mmdd} {
+ clock scan {January ii} -format {%B %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.201 {parse mmdd} {
+ clock scan {Jan 02} -format {%h %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.202 {parse mmdd} {
+ clock scan {Jan ii} -format {%h %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.203 {parse mmdd} {
+ clock scan {Jan 2} -format {%h %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.204 {parse mmdd} {
+ clock scan {Jan ii} -format {%h %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.205 {parse mmdd} {
+ clock scan {01 02} -format {%m %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.206 {parse mmdd} {
+ clock scan {01 ii} -format {%m %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.207 {parse mmdd} {
+ clock scan {01 2} -format {%m %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.208 {parse mmdd} {
+ clock scan {01 ii} -format {%m %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.209 {parse mmdd} {
+ clock scan {i 02} -format {%Om %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.210 {parse mmdd} {
+ clock scan {i ii} -format {%Om %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.211 {parse mmdd} {
+ clock scan {i 2} -format {%Om %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.212 {parse mmdd} {
+ clock scan {i ii} -format {%Om %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.213 {parse mmdd} {
+ clock scan { 1 02} -format {%N %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.214 {parse mmdd} {
+ clock scan { 1 ii} -format {%N %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.215 {parse mmdd} {
+ clock scan { 1 2} -format {%N %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.216 {parse mmdd} {
+ clock scan { 1 ii} -format {%N %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.217 {parse mmdd} {
+ clock scan {Jan 31} -format {%b %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.218 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%b %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.219 {parse mmdd} {
+ clock scan {Jan 31} -format {%b %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.220 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%b %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.221 {parse mmdd} {
+ clock scan {January 31} -format {%B %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.222 {parse mmdd} {
+ clock scan {January xxxi} -format {%B %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.223 {parse mmdd} {
+ clock scan {January 31} -format {%B %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.224 {parse mmdd} {
+ clock scan {January xxxi} -format {%B %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.225 {parse mmdd} {
+ clock scan {Jan 31} -format {%h %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.226 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%h %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.227 {parse mmdd} {
+ clock scan {Jan 31} -format {%h %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.228 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%h %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.229 {parse mmdd} {
+ clock scan {01 31} -format {%m %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.230 {parse mmdd} {
+ clock scan {01 xxxi} -format {%m %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.231 {parse mmdd} {
+ clock scan {01 31} -format {%m %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.232 {parse mmdd} {
+ clock scan {01 xxxi} -format {%m %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.233 {parse mmdd} {
+ clock scan {i 31} -format {%Om %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.234 {parse mmdd} {
+ clock scan {i xxxi} -format {%Om %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.235 {parse mmdd} {
+ clock scan {i 31} -format {%Om %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.236 {parse mmdd} {
+ clock scan {i xxxi} -format {%Om %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.237 {parse mmdd} {
+ clock scan { 1 31} -format {%N %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.238 {parse mmdd} {
+ clock scan { 1 xxxi} -format {%N %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.239 {parse mmdd} {
+ clock scan { 1 31} -format {%N %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.240 {parse mmdd} {
+ clock scan { 1 xxxi} -format {%N %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.241 {parse mmdd} {
+ clock scan {Dec 02} -format {%b %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.242 {parse mmdd} {
+ clock scan {Dec ii} -format {%b %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.243 {parse mmdd} {
+ clock scan {Dec 2} -format {%b %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.244 {parse mmdd} {
+ clock scan {Dec ii} -format {%b %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.245 {parse mmdd} {
+ clock scan {December 02} -format {%B %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.246 {parse mmdd} {
+ clock scan {December ii} -format {%B %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.247 {parse mmdd} {
+ clock scan {December 2} -format {%B %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.248 {parse mmdd} {
+ clock scan {December ii} -format {%B %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.249 {parse mmdd} {
+ clock scan {Dec 02} -format {%h %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.250 {parse mmdd} {
+ clock scan {Dec ii} -format {%h %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.251 {parse mmdd} {
+ clock scan {Dec 2} -format {%h %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.252 {parse mmdd} {
+ clock scan {Dec ii} -format {%h %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.253 {parse mmdd} {
+ clock scan {12 02} -format {%m %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.254 {parse mmdd} {
+ clock scan {12 ii} -format {%m %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.255 {parse mmdd} {
+ clock scan {12 2} -format {%m %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.256 {parse mmdd} {
+ clock scan {12 ii} -format {%m %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.257 {parse mmdd} {
+ clock scan {xii 02} -format {%Om %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.258 {parse mmdd} {
+ clock scan {xii ii} -format {%Om %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.259 {parse mmdd} {
+ clock scan {xii 2} -format {%Om %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.260 {parse mmdd} {
+ clock scan {xii ii} -format {%Om %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.261 {parse mmdd} {
+ clock scan {12 02} -format {%N %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.262 {parse mmdd} {
+ clock scan {12 ii} -format {%N %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.263 {parse mmdd} {
+ clock scan {12 2} -format {%N %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.264 {parse mmdd} {
+ clock scan {12 ii} -format {%N %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.265 {parse mmdd} {
+ clock scan {Dec 31} -format {%b %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.266 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%b %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.267 {parse mmdd} {
+ clock scan {Dec 31} -format {%b %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.268 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%b %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.269 {parse mmdd} {
+ clock scan {December 31} -format {%B %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.270 {parse mmdd} {
+ clock scan {December xxxi} -format {%B %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.271 {parse mmdd} {
+ clock scan {December 31} -format {%B %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.272 {parse mmdd} {
+ clock scan {December xxxi} -format {%B %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.273 {parse mmdd} {
+ clock scan {Dec 31} -format {%h %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.274 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%h %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.275 {parse mmdd} {
+ clock scan {Dec 31} -format {%h %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.276 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%h %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.277 {parse mmdd} {
+ clock scan {12 31} -format {%m %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.278 {parse mmdd} {
+ clock scan {12 xxxi} -format {%m %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.279 {parse mmdd} {
+ clock scan {12 31} -format {%m %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.280 {parse mmdd} {
+ clock scan {12 xxxi} -format {%m %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.281 {parse mmdd} {
+ clock scan {xii 31} -format {%Om %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.282 {parse mmdd} {
+ clock scan {xii xxxi} -format {%Om %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.283 {parse mmdd} {
+ clock scan {xii 31} -format {%Om %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.284 {parse mmdd} {
+ clock scan {xii xxxi} -format {%Om %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.285 {parse mmdd} {
+ clock scan {12 31} -format {%N %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.286 {parse mmdd} {
+ clock scan {12 xxxi} -format {%N %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.287 {parse mmdd} {
+ clock scan {12 31} -format {%N %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.288 {parse mmdd} {
+ clock scan {12 xxxi} -format {%N %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.289 {parse mmdd} {
+ clock scan {Jan 02} -format {%b %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.290 {parse mmdd} {
+ clock scan {Jan ii} -format {%b %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.291 {parse mmdd} {
+ clock scan {Jan 2} -format {%b %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.292 {parse mmdd} {
+ clock scan {Jan ii} -format {%b %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.293 {parse mmdd} {
+ clock scan {January 02} -format {%B %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.294 {parse mmdd} {
+ clock scan {January ii} -format {%B %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.295 {parse mmdd} {
+ clock scan {January 2} -format {%B %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.296 {parse mmdd} {
+ clock scan {January ii} -format {%B %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.297 {parse mmdd} {
+ clock scan {Jan 02} -format {%h %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.298 {parse mmdd} {
+ clock scan {Jan ii} -format {%h %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.299 {parse mmdd} {
+ clock scan {Jan 2} -format {%h %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.300 {parse mmdd} {
+ clock scan {Jan ii} -format {%h %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.301 {parse mmdd} {
+ clock scan {01 02} -format {%m %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.302 {parse mmdd} {
+ clock scan {01 ii} -format {%m %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.303 {parse mmdd} {
+ clock scan {01 2} -format {%m %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.304 {parse mmdd} {
+ clock scan {01 ii} -format {%m %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.305 {parse mmdd} {
+ clock scan {i 02} -format {%Om %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.306 {parse mmdd} {
+ clock scan {i ii} -format {%Om %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.307 {parse mmdd} {
+ clock scan {i 2} -format {%Om %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.308 {parse mmdd} {
+ clock scan {i ii} -format {%Om %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.309 {parse mmdd} {
+ clock scan { 1 02} -format {%N %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.310 {parse mmdd} {
+ clock scan { 1 ii} -format {%N %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.311 {parse mmdd} {
+ clock scan { 1 2} -format {%N %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.312 {parse mmdd} {
+ clock scan { 1 ii} -format {%N %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.313 {parse mmdd} {
+ clock scan {Jan 31} -format {%b %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.314 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%b %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.315 {parse mmdd} {
+ clock scan {Jan 31} -format {%b %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.316 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%b %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.317 {parse mmdd} {
+ clock scan {January 31} -format {%B %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.318 {parse mmdd} {
+ clock scan {January xxxi} -format {%B %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.319 {parse mmdd} {
+ clock scan {January 31} -format {%B %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.320 {parse mmdd} {
+ clock scan {January xxxi} -format {%B %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.321 {parse mmdd} {
+ clock scan {Jan 31} -format {%h %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.322 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%h %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.323 {parse mmdd} {
+ clock scan {Jan 31} -format {%h %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.324 {parse mmdd} {
+ clock scan {Jan xxxi} -format {%h %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.325 {parse mmdd} {
+ clock scan {01 31} -format {%m %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.326 {parse mmdd} {
+ clock scan {01 xxxi} -format {%m %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.327 {parse mmdd} {
+ clock scan {01 31} -format {%m %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.328 {parse mmdd} {
+ clock scan {01 xxxi} -format {%m %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.329 {parse mmdd} {
+ clock scan {i 31} -format {%Om %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.330 {parse mmdd} {
+ clock scan {i xxxi} -format {%Om %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.331 {parse mmdd} {
+ clock scan {i 31} -format {%Om %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.332 {parse mmdd} {
+ clock scan {i xxxi} -format {%Om %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.333 {parse mmdd} {
+ clock scan { 1 31} -format {%N %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.334 {parse mmdd} {
+ clock scan { 1 xxxi} -format {%N %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.335 {parse mmdd} {
+ clock scan { 1 31} -format {%N %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.336 {parse mmdd} {
+ clock scan { 1 xxxi} -format {%N %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.337 {parse mmdd} {
+ clock scan {Dec 02} -format {%b %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.338 {parse mmdd} {
+ clock scan {Dec ii} -format {%b %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.339 {parse mmdd} {
+ clock scan {Dec 2} -format {%b %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.340 {parse mmdd} {
+ clock scan {Dec ii} -format {%b %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.341 {parse mmdd} {
+ clock scan {December 02} -format {%B %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.342 {parse mmdd} {
+ clock scan {December ii} -format {%B %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.343 {parse mmdd} {
+ clock scan {December 2} -format {%B %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.344 {parse mmdd} {
+ clock scan {December ii} -format {%B %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.345 {parse mmdd} {
+ clock scan {Dec 02} -format {%h %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.346 {parse mmdd} {
+ clock scan {Dec ii} -format {%h %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.347 {parse mmdd} {
+ clock scan {Dec 2} -format {%h %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.348 {parse mmdd} {
+ clock scan {Dec ii} -format {%h %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.349 {parse mmdd} {
+ clock scan {12 02} -format {%m %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.350 {parse mmdd} {
+ clock scan {12 ii} -format {%m %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.351 {parse mmdd} {
+ clock scan {12 2} -format {%m %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.352 {parse mmdd} {
+ clock scan {12 ii} -format {%m %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.353 {parse mmdd} {
+ clock scan {xii 02} -format {%Om %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.354 {parse mmdd} {
+ clock scan {xii ii} -format {%Om %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.355 {parse mmdd} {
+ clock scan {xii 2} -format {%Om %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.356 {parse mmdd} {
+ clock scan {xii ii} -format {%Om %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.357 {parse mmdd} {
+ clock scan {12 02} -format {%N %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.358 {parse mmdd} {
+ clock scan {12 ii} -format {%N %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.359 {parse mmdd} {
+ clock scan {12 2} -format {%N %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.360 {parse mmdd} {
+ clock scan {12 ii} -format {%N %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.361 {parse mmdd} {
+ clock scan {Dec 31} -format {%b %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.362 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%b %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.363 {parse mmdd} {
+ clock scan {Dec 31} -format {%b %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.364 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%b %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.365 {parse mmdd} {
+ clock scan {December 31} -format {%B %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.366 {parse mmdd} {
+ clock scan {December xxxi} -format {%B %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.367 {parse mmdd} {
+ clock scan {December 31} -format {%B %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.368 {parse mmdd} {
+ clock scan {December xxxi} -format {%B %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.369 {parse mmdd} {
+ clock scan {Dec 31} -format {%h %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.370 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%h %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.371 {parse mmdd} {
+ clock scan {Dec 31} -format {%h %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.372 {parse mmdd} {
+ clock scan {Dec xxxi} -format {%h %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.373 {parse mmdd} {
+ clock scan {12 31} -format {%m %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.374 {parse mmdd} {
+ clock scan {12 xxxi} -format {%m %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.375 {parse mmdd} {
+ clock scan {12 31} -format {%m %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.376 {parse mmdd} {
+ clock scan {12 xxxi} -format {%m %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.377 {parse mmdd} {
+ clock scan {xii 31} -format {%Om %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.378 {parse mmdd} {
+ clock scan {xii xxxi} -format {%Om %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.379 {parse mmdd} {
+ clock scan {xii 31} -format {%Om %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.380 {parse mmdd} {
+ clock scan {xii xxxi} -format {%Om %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.381 {parse mmdd} {
+ clock scan {12 31} -format {%N %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.382 {parse mmdd} {
+ clock scan {12 xxxi} -format {%N %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.383 {parse mmdd} {
+ clock scan {12 31} -format {%N %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.384 {parse mmdd} {
+ clock scan {12 xxxi} -format {%N %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+# END testcases19
+
+test clock-20.1 {seconds take precedence over mmdd} {
+ list [clock scan {0 0201} -format {%s %m%d} -gmt true -base 0] \
+ [clock scan {0201 0} -format {%m%d %s} -gmt true -base 0]
+} {0 0}
+test clock-20.2 {julian day takes precedence over yyddd} {
+ list [clock scan {2440588 0201} -format {%J %m%d} -gmt true -base 0] \
+ [clock scan {0201 2440588} -format {%m%d %J} -gmt true -base 0]
+} {0 0}
+test clock-20.3 {yyyyWwwd over mmdd} {
+ list [clock scan {1970W014 0201} -format {%GW%V%u %m%d} -gmt true -base 0] \
+ [clock scan {0201 1970W014} -format {%m%d %GW%V%u} -gmt true -base 0]
+} {0 0}
+test clock-20.4 {yyWwwd over mmdd} {
+ list [clock scan {70W014 0201} -format {%gW%V%u %m%d} -gmt true -base 0] \
+ [clock scan {0201 70W014} -format {%m%d %gW%V%u} -gmt true -base 0]
+} {0 0}
+
+# Test parsing of ddd
+
+test clock-21.1 {parse ddd} {
+ clock scan {001} -format {%j} -locale en_US_roman -gmt 1 -base 0
+} 0
+test clock-21.2 {parse ddd} {
+ clock scan {365} -format {%j} -locale en_US_roman -gmt 1 -base 0
+} 31449600
+test clock-21.3 {parse ddd} {
+ clock scan {001} -format {%j} -locale en_US_roman -gmt 1 -base 31536000
+} 31536000
+test clock-21.4 {parse ddd} {
+ clock scan {365} -format {%j} -locale en_US_roman -gmt 1 -base 31536000
+} 62985600
+test clock-21.5 {seconds take precedence over ddd} {
+ list [clock scan {0 002} -format {%s %j} -gmt true -base 0] \
+ [clock scan {002 0} -format {%j %s} -gmt true -base 0]
+} {0 0}
+test clock-21.6 {julian day takes precedence over yyddd} {
+ list [clock scan {2440588 002} -format {%J %j} -gmt true -base 0] \
+ [clock scan {002 2440588} -format {%j %J} -gmt true -base 0]
+} {0 0}
+test clock-21.7 {yyyyWwwd over ddd} {
+ list [clock scan {1970W014 002} -format {%GW%V%u %j} -gmt true -base 0] \
+ [clock scan {002 1970W014} -format {%j %GW%V%u} -gmt true -base 0]
+} {0 0}
+test clock-21.8 {yyWwwd over ddd} {
+ list [clock scan {70W014 002} -format {%gW%V%u %j} -gmt true -base 0] \
+ [clock scan {002 70W014} -format {%j %gW%V%u} -gmt true -base 0]
+} {0 0}
+
+# BEGIN testcases22
+
+# Test parsing of Wwwd
+
+test clock-22.1 {parse Wwwd} {
+ clock scan {W09 Sun} -format {W%V %a} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.2 {parse Wwwd} {
+ clock scan {W09 Sunday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.3 {parse Wwwd} {
+ clock scan {W09 7} -format {W%V %u} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.4 {parse Wwwd} {
+ clock scan {W09 0} -format {W%V %w} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.5 {parse Wwwd} {
+ clock scan {W09 vii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.6 {parse Wwwd} {
+ clock scan {W09 ?} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.7 {parse Wwwd} {
+ clock scan {W14 Tue} -format {W%V %a} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.8 {parse Wwwd} {
+ clock scan {W14 Tuesday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.9 {parse Wwwd} {
+ clock scan {W14 2} -format {W%V %u} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.10 {parse Wwwd} {
+ clock scan {W14 2} -format {W%V %w} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.11 {parse Wwwd} {
+ clock scan {W14 ii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.12 {parse Wwwd} {
+ clock scan {W14 ii} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.13 {parse Wwwd} {
+ clock scan {W40 Thu} -format {W%V %a} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.14 {parse Wwwd} {
+ clock scan {W40 Thursday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.15 {parse Wwwd} {
+ clock scan {W40 4} -format {W%V %u} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.16 {parse Wwwd} {
+ clock scan {W40 4} -format {W%V %w} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.17 {parse Wwwd} {
+ clock scan {W40 iv} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.18 {parse Wwwd} {
+ clock scan {W40 iv} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.19 {parse Wwwd} {
+ clock scan {W44 Sat} -format {W%V %a} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.20 {parse Wwwd} {
+ clock scan {W44 Saturday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.21 {parse Wwwd} {
+ clock scan {W44 6} -format {W%V %u} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.22 {parse Wwwd} {
+ clock scan {W44 6} -format {W%V %w} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.23 {parse Wwwd} {
+ clock scan {W44 vi} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.24 {parse Wwwd} {
+ clock scan {W44 vi} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.25 {parse Wwwd} {
+ clock scan {W09 Mon} -format {W%V %a} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.26 {parse Wwwd} {
+ clock scan {W09 Monday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.27 {parse Wwwd} {
+ clock scan {W09 1} -format {W%V %u} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.28 {parse Wwwd} {
+ clock scan {W09 1} -format {W%V %w} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.29 {parse Wwwd} {
+ clock scan {W09 i} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.30 {parse Wwwd} {
+ clock scan {W09 i} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.31 {parse Wwwd} {
+ clock scan {W13 Wed} -format {W%V %a} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.32 {parse Wwwd} {
+ clock scan {W13 Wednesday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.33 {parse Wwwd} {
+ clock scan {W13 3} -format {W%V %u} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.34 {parse Wwwd} {
+ clock scan {W13 3} -format {W%V %w} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.35 {parse Wwwd} {
+ clock scan {W13 iii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.36 {parse Wwwd} {
+ clock scan {W13 iii} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.37 {parse Wwwd} {
+ clock scan {W39 Fri} -format {W%V %a} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.38 {parse Wwwd} {
+ clock scan {W39 Friday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.39 {parse Wwwd} {
+ clock scan {W39 5} -format {W%V %u} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.40 {parse Wwwd} {
+ clock scan {W39 5} -format {W%V %w} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.41 {parse Wwwd} {
+ clock scan {W39 v} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.42 {parse Wwwd} {
+ clock scan {W39 v} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.43 {parse Wwwd} {
+ clock scan {W43 Sun} -format {W%V %a} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.44 {parse Wwwd} {
+ clock scan {W43 Sunday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.45 {parse Wwwd} {
+ clock scan {W43 7} -format {W%V %u} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.46 {parse Wwwd} {
+ clock scan {W43 0} -format {W%V %w} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.47 {parse Wwwd} {
+ clock scan {W43 vii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.48 {parse Wwwd} {
+ clock scan {W43 ?} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.49 {parse Wwwd} {
+ clock scan {W09 Wed} -format {W%V %a} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.50 {parse Wwwd} {
+ clock scan {W09 Wednesday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.51 {parse Wwwd} {
+ clock scan {W09 3} -format {W%V %u} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.52 {parse Wwwd} {
+ clock scan {W09 3} -format {W%V %w} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.53 {parse Wwwd} {
+ clock scan {W09 iii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.54 {parse Wwwd} {
+ clock scan {W09 iii} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.55 {parse Wwwd} {
+ clock scan {W13 Fri} -format {W%V %a} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.56 {parse Wwwd} {
+ clock scan {W13 Friday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.57 {parse Wwwd} {
+ clock scan {W13 5} -format {W%V %u} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.58 {parse Wwwd} {
+ clock scan {W13 5} -format {W%V %w} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.59 {parse Wwwd} {
+ clock scan {W13 v} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.60 {parse Wwwd} {
+ clock scan {W13 v} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.61 {parse Wwwd} {
+ clock scan {W39 Sun} -format {W%V %a} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.62 {parse Wwwd} {
+ clock scan {W39 Sunday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.63 {parse Wwwd} {
+ clock scan {W39 7} -format {W%V %u} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.64 {parse Wwwd} {
+ clock scan {W39 0} -format {W%V %w} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.65 {parse Wwwd} {
+ clock scan {W39 vii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.66 {parse Wwwd} {
+ clock scan {W39 ?} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.67 {parse Wwwd} {
+ clock scan {W44 Tue} -format {W%V %a} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.68 {parse Wwwd} {
+ clock scan {W44 Tuesday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.69 {parse Wwwd} {
+ clock scan {W44 2} -format {W%V %u} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.70 {parse Wwwd} {
+ clock scan {W44 2} -format {W%V %w} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.71 {parse Wwwd} {
+ clock scan {W44 ii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.72 {parse Wwwd} {
+ clock scan {W44 ii} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.73 {parse Wwwd} {
+ clock scan {W09 Thu} -format {W%V %a} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.74 {parse Wwwd} {
+ clock scan {W09 Thursday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.75 {parse Wwwd} {
+ clock scan {W09 4} -format {W%V %u} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.76 {parse Wwwd} {
+ clock scan {W09 4} -format {W%V %w} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.77 {parse Wwwd} {
+ clock scan {W09 iv} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.78 {parse Wwwd} {
+ clock scan {W09 iv} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.79 {parse Wwwd} {
+ clock scan {W13 Sat} -format {W%V %a} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.80 {parse Wwwd} {
+ clock scan {W13 Saturday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.81 {parse Wwwd} {
+ clock scan {W13 6} -format {W%V %u} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.82 {parse Wwwd} {
+ clock scan {W13 6} -format {W%V %w} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.83 {parse Wwwd} {
+ clock scan {W13 vi} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.84 {parse Wwwd} {
+ clock scan {W13 vi} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.85 {parse Wwwd} {
+ clock scan {W40 Mon} -format {W%V %a} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.86 {parse Wwwd} {
+ clock scan {W40 Monday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.87 {parse Wwwd} {
+ clock scan {W40 1} -format {W%V %u} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.88 {parse Wwwd} {
+ clock scan {W40 1} -format {W%V %w} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.89 {parse Wwwd} {
+ clock scan {W40 i} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.90 {parse Wwwd} {
+ clock scan {W40 i} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.91 {parse Wwwd} {
+ clock scan {W44 Wed} -format {W%V %a} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+test clock-22.92 {parse Wwwd} {
+ clock scan {W44 Wednesday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+test clock-22.93 {parse Wwwd} {
+ clock scan {W44 3} -format {W%V %u} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+test clock-22.94 {parse Wwwd} {
+ clock scan {W44 3} -format {W%V %w} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+test clock-22.95 {parse Wwwd} {
+ clock scan {W44 iii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+test clock-22.96 {parse Wwwd} {
+ clock scan {W44 iii} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+# END testcases22
+
+# Test precedence of Wwwd
+test clock-23.1 {seconds take precedence over Wwwd} {
+ list [clock scan {0 W024} -format {%s W%V%u} -gmt true -base 0] \
+ [clock scan {W024 0} -format {W%V%u %s} -gmt true -base 0]
+} {0 0}
+test clock-23.2 {julian day takes precedence over Wwwd} {
+ list [clock scan {2440588 W024} -format {%J W%V%u} -gmt true -base 0] \
+ [clock scan {W024 2440588} -format {W%V%u %J} -gmt true -base 0]
+} {0 0}
+test clock-23.3 {Wwwd precedence below yyyymmdd} {
+ list [clock scan {19700101 W014} -format {%Y%m%d W%V%u} -gmt true -base 0] \
+ [clock scan {W014 19700101} -format {W%V%u %Y%m%d} -gmt true -base 0]
+} {0 0}
+test clock-23.4 {Wwwd precedence below yyyyddd} {
+ list [clock scan {1970001 W014} -format {%Y%j W%V%u} -gmt true -base 0] \
+ [clock scan {W014 1970001} -format {W%V%u %Y%j} -gmt true -base 0]
+} {0 0}
+test clock-23.5 {Wwwd precedence below yymmdd} {
+ list [clock scan {700101 W014} -format {%y%m%d W%V%u} -gmt true -base 0] \
+ [clock scan {W014 700101} -format {W%V%u %y%m%d} -gmt true -base 0]
+} {0 0}
+test clock-23.6 {Wwwd precedence below yyddd} {
+ list [clock scan {70001 W014} -format {%y%j W%V%u} -gmt true -base 0] \
+ [clock scan {W014 70001} -format {W%V%u %y%j} -gmt true -base 0]
+} {0 0}
+
+# BEGIN testcases24
+
+# Test parsing of naked day-of-month
+
+test clock-24.1 {parse naked day of month} {
+ clock scan 02 -format %d -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-24.2 {parse naked day of month} {
+ clock scan ii -format %Od -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-24.3 {parse naked day of month} {
+ clock scan { 2} -format %e -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-24.4 {parse naked day of month} {
+ clock scan ii -format %Oe -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-24.5 {parse naked day of month} {
+ clock scan 28 -format %d -locale en_US_roman -base 0 -gmt 1
+} 2332800
+test clock-24.6 {parse naked day of month} {
+ clock scan xxviii -format %Od -locale en_US_roman -base 0 -gmt 1
+} 2332800
+test clock-24.7 {parse naked day of month} {
+ clock scan 28 -format %e -locale en_US_roman -base 0 -gmt 1
+} 2332800
+test clock-24.8 {parse naked day of month} {
+ clock scan xxviii -format %Oe -locale en_US_roman -base 0 -gmt 1
+} 2332800
+test clock-24.9 {parse naked day of month} {
+ clock scan 02 -format %d -locale en_US_roman -base 28857600 -gmt 1
+} 28944000
+test clock-24.10 {parse naked day of month} {
+ clock scan ii -format %Od -locale en_US_roman -base 28857600 -gmt 1
+} 28944000
+test clock-24.11 {parse naked day of month} {
+ clock scan { 2} -format %e -locale en_US_roman -base 28857600 -gmt 1
+} 28944000
+test clock-24.12 {parse naked day of month} {
+ clock scan ii -format %Oe -locale en_US_roman -base 28857600 -gmt 1
+} 28944000
+test clock-24.13 {parse naked day of month} {
+ clock scan 28 -format %d -locale en_US_roman -base 28857600 -gmt 1
+} 31190400
+test clock-24.14 {parse naked day of month} {
+ clock scan xxviii -format %Od -locale en_US_roman -base 28857600 -gmt 1
+} 31190400
+test clock-24.15 {parse naked day of month} {
+ clock scan 28 -format %e -locale en_US_roman -base 28857600 -gmt 1
+} 31190400
+test clock-24.16 {parse naked day of month} {
+ clock scan xxviii -format %Oe -locale en_US_roman -base 28857600 -gmt 1
+} 31190400
+test clock-24.17 {parse naked day of month} {
+ clock scan 02 -format %d -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-24.18 {parse naked day of month} {
+ clock scan ii -format %Od -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-24.19 {parse naked day of month} {
+ clock scan { 2} -format %e -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-24.20 {parse naked day of month} {
+ clock scan ii -format %Oe -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-24.21 {parse naked day of month} {
+ clock scan 28 -format %d -locale en_US_roman -base 946684800 -gmt 1
+} 949017600
+test clock-24.22 {parse naked day of month} {
+ clock scan xxviii -format %Od -locale en_US_roman -base 946684800 -gmt 1
+} 949017600
+test clock-24.23 {parse naked day of month} {
+ clock scan 28 -format %e -locale en_US_roman -base 946684800 -gmt 1
+} 949017600
+test clock-24.24 {parse naked day of month} {
+ clock scan xxviii -format %Oe -locale en_US_roman -base 946684800 -gmt 1
+} 949017600
+test clock-24.25 {parse naked day of month} {
+ clock scan 02 -format %d -locale en_US_roman -base 975628800 -gmt 1
+} 975715200
+test clock-24.26 {parse naked day of month} {
+ clock scan ii -format %Od -locale en_US_roman -base 975628800 -gmt 1
+} 975715200
+test clock-24.27 {parse naked day of month} {
+ clock scan { 2} -format %e -locale en_US_roman -base 975628800 -gmt 1
+} 975715200
+test clock-24.28 {parse naked day of month} {
+ clock scan ii -format %Oe -locale en_US_roman -base 975628800 -gmt 1
+} 975715200
+test clock-24.29 {parse naked day of month} {
+ clock scan 28 -format %d -locale en_US_roman -base 975628800 -gmt 1
+} 977961600
+test clock-24.30 {parse naked day of month} {
+ clock scan xxviii -format %Od -locale en_US_roman -base 975628800 -gmt 1
+} 977961600
+test clock-24.31 {parse naked day of month} {
+ clock scan 28 -format %e -locale en_US_roman -base 975628800 -gmt 1
+} 977961600
+test clock-24.32 {parse naked day of month} {
+ clock scan xxviii -format %Oe -locale en_US_roman -base 975628800 -gmt 1
+} 977961600
+# END testcases24
+
+test clock-25.1 {seconds take precedence over dd} {
+ list [clock scan {0 02} -format {%s %d} -gmt true -base 0] \
+ [clock scan {02 0} -format {%d %s} -gmt true -base 0]
+} {0 0}
+test clock-25.2 {julian day takes precedence over dd} {
+ list [clock scan {2440588 02} -format {%J %d} -gmt true -base 0] \
+ [clock scan {02 2440588} -format {%d %J} -gmt true -base 0]
+} {0 0}
+test clock-25.3 {yyyyddd over dd} {
+ list [clock scan {1970001 02} -format {%Y%j %d} -gmt true -base 0] \
+ [clock scan {02 1970001} -format {%d %Y%j} -gmt true -base 0]
+} {0 0}
+test clock-25.4 {yyyyWwwd over dd} {
+ list [clock scan {1970W014 02} -format {%GW%V%u %d} -gmt true -base 0] \
+ [clock scan {02 1970W014} -format {%d %GW%V%u} -gmt true -base 0]
+} {0 0}
+test clock-25.5 {yyWwwd over dd} {
+ list [clock scan {70W014 02} -format {%gW%V%u %d} -gmt true -base 0] \
+ [clock scan {02 70W014} -format {%d %gW%V%u} -gmt true -base 0]
+} {0 0}
+test clock-25.6 {yyddd over dd} {
+ list [clock scan {70001 02} -format {%y%j %d} -gmt true -base 0] \
+ [clock scan {02 70001} -format {%d %y%j} -gmt true -base 0]
+} {0 0}
+test clock-25.7 {ddd over dd} {
+ list [clock scan {001 02} -format {%j %d} -gmt true -base 0] \
+ [clock scan {02 001} -format {%d %j} -gmt true -base 0]
+} {0 0}
+
+# BEGIN testcases26
+
+# Test parsing of naked day of week
+
+test clock-26.1 {parse naked day of week} {
+ clock scan Mon -format %a -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.2 {parse naked day of week} {
+ clock scan Monday -format %A -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.3 {parse naked day of week} {
+ clock scan 1 -format %u -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.4 {parse naked day of week} {
+ clock scan 1 -format %w -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.5 {parse naked day of week} {
+ clock scan i -format %Ou -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.6 {parse naked day of week} {
+ clock scan i -format %Ow -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.7 {parse naked day of week} {
+ clock scan Sun -format %a -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.8 {parse naked day of week} {
+ clock scan Sunday -format %A -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.9 {parse naked day of week} {
+ clock scan 7 -format %u -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.10 {parse naked day of week} {
+ clock scan 0 -format %w -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.11 {parse naked day of week} {
+ clock scan vii -format %Ou -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.12 {parse naked day of week} {
+ clock scan ? -format %Ow -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.13 {parse naked day of week} {
+ clock scan Mon -format %a -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.14 {parse naked day of week} {
+ clock scan Monday -format %A -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.15 {parse naked day of week} {
+ clock scan 1 -format %u -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.16 {parse naked day of week} {
+ clock scan 1 -format %w -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.17 {parse naked day of week} {
+ clock scan i -format %Ou -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.18 {parse naked day of week} {
+ clock scan i -format %Ow -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.19 {parse naked day of week} {
+ clock scan Sun -format %a -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.20 {parse naked day of week} {
+ clock scan Sunday -format %A -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.21 {parse naked day of week} {
+ clock scan 7 -format %u -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.22 {parse naked day of week} {
+ clock scan 0 -format %w -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.23 {parse naked day of week} {
+ clock scan vii -format %Ou -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.24 {parse naked day of week} {
+ clock scan ? -format %Ow -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.25 {parse naked day of week} {
+ clock scan Mon -format %a -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.26 {parse naked day of week} {
+ clock scan Monday -format %A -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.27 {parse naked day of week} {
+ clock scan 1 -format %u -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.28 {parse naked day of week} {
+ clock scan 1 -format %w -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.29 {parse naked day of week} {
+ clock scan i -format %Ou -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.30 {parse naked day of week} {
+ clock scan i -format %Ow -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.31 {parse naked day of week} {
+ clock scan Sun -format %a -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.32 {parse naked day of week} {
+ clock scan Sunday -format %A -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.33 {parse naked day of week} {
+ clock scan 7 -format %u -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.34 {parse naked day of week} {
+ clock scan 0 -format %w -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.35 {parse naked day of week} {
+ clock scan vii -format %Ou -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.36 {parse naked day of week} {
+ clock scan ? -format %Ow -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.37 {parse naked day of week} {
+ clock scan Mon -format %a -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.38 {parse naked day of week} {
+ clock scan Monday -format %A -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.39 {parse naked day of week} {
+ clock scan 1 -format %u -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.40 {parse naked day of week} {
+ clock scan 1 -format %w -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.41 {parse naked day of week} {
+ clock scan i -format %Ou -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.42 {parse naked day of week} {
+ clock scan i -format %Ow -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.43 {parse naked day of week} {
+ clock scan Sun -format %a -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+test clock-26.44 {parse naked day of week} {
+ clock scan Sunday -format %A -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+test clock-26.45 {parse naked day of week} {
+ clock scan 7 -format %u -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+test clock-26.46 {parse naked day of week} {
+ clock scan 0 -format %w -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+test clock-26.47 {parse naked day of week} {
+ clock scan vii -format %Ou -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+test clock-26.48 {parse naked day of week} {
+ clock scan ? -format %Ow -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+# END testcases26
+
+test clock-27.1 {seconds take precedence over naked weekday} {
+ list [clock scan {0 1} -format {%s %u} -gmt true -base 0] \
+ [clock scan {1 0} -format {%u %s} -gmt true -base 0]
+} {0 0}
+test clock-27.2 {julian day takes precedence over naked weekday} {
+ list [clock scan {2440588 1} -format {%J %u} -gmt true -base 0] \
+ [clock scan {1 2440588} -format {%u %J} -gmt true -base 0]
+} {0 0}
+test clock-27.3 {yyyymmdd over naked weekday} {
+ list [clock scan {19700101 1} -format {%Y%m%d %u} -gmt true -base 0] \
+ [clock scan {1 19700101} -format {%u %Y%m%d} -gmt true -base 0]
+} {0 0}
+test clock-27.4 {yyyyddd over naked weekday} {
+ list [clock scan {1970001 1} -format {%Y%j %u} -gmt true -base 0] \
+ [clock scan {1 1970001} -format {%u %Y%j} -gmt true -base 0]
+} {0 0}
+test clock-27.5 {yymmdd over naked weekday} {
+ list [clock scan {700101 1} -format {%y%m%d %u} -gmt true -base 0] \
+ [clock scan {1 700101} -format {%u %y%m%d} -gmt true -base 0]
+} {0 0}
+test clock-27.6 {yyddd over naked weekday} {
+ list [clock scan {70001 1} -format {%y%j %u} -gmt true -base 0] \
+ [clock scan {1 70001} -format {%u %y%j} -gmt true -base 0]
+} {0 0}
+test clock-27.7 {mmdd over naked weekday} {
+ list [clock scan {0101 1} -format {%m%d %u} -gmt true -base 0] \
+ [clock scan {1 0101} -format {%u %m%d} -gmt true -base 0]
+} {0 0}
+test clock-27.8 {ddd over naked weekday} {
+ list [clock scan {001 1} -format {%j %u} -gmt true -base 0] \
+ [clock scan {1 001} -format {%u %j} -gmt true -base 0]
+} {0 0}
+test clock-27.9 {naked day of month over naked weekday} {
+ list [clock scan {01 1} -format {%d %u} -gmt true -base 0] \
+ [clock scan {1 01} -format {%u %d} -gmt true -base 0]
+} {0 0}
+
+test clock-28.1 {base date} {
+ clock scan {} -format {} -gmt true -base 1234567890
+} 1234483200
+
+# BEGIN testcases29
+
+# Test parsing of time of day
+
+test clock-29.1 {time parsing} {
+ clock scan {2440588 00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H }
+} 0
+test clock-29.2 {time parsing} {
+ clock scan {2440588 00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 0
+test clock-29.3 {time parsing} {
+ clock scan {2440588 00:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 0
+test clock-29.4 {time parsing} {
+ clock scan {2440588 00:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 0
+test clock-29.5 {time parsing} {
+ clock scan {2440588 00:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 0
+test clock-29.6 {time parsing} {
+ clock scan {2440588 0 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k }
+} 0
+test clock-29.7 {time parsing} {
+ clock scan {2440588 0:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 0
+test clock-29.8 {time parsing} {
+ clock scan {2440588 0:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 0
+test clock-29.9 {time parsing} {
+ clock scan {2440588 0:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 0
+test clock-29.10 {time parsing} {
+ clock scan {2440588 0:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 0
+test clock-29.11 {time parsing} {
+ clock scan {2440588 ? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH }
+} 0
+test clock-29.12 {time parsing} {
+ clock scan {2440588 ?:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 0
+test clock-29.13 {time parsing} {
+ clock scan {2440588 ?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 0
+test clock-29.14 {time parsing} {
+ clock scan {2440588 ?:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 0
+test clock-29.15 {time parsing} {
+ clock scan {2440588 ?:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 0
+test clock-29.16 {time parsing} {
+ clock scan {2440588 ? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok }
+} 0
+test clock-29.17 {time parsing} {
+ clock scan {2440588 ?:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 0
+test clock-29.18 {time parsing} {
+ clock scan {2440588 ?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 0
+test clock-29.19 {time parsing} {
+ clock scan {2440588 ?:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 0
+test clock-29.20 {time parsing} {
+ clock scan {2440588 ?:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 0
+test clock-29.21 {time parsing} {
+ clock scan {2440588 12 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %p}
+} 0
+test clock-29.22 {time parsing} {
+ clock scan {2440588 12:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 0
+test clock-29.23 {time parsing} {
+ clock scan {2440588 12:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 0
+test clock-29.24 {time parsing} {
+ clock scan {2440588 12:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 0
+test clock-29.25 {time parsing} {
+ clock scan {2440588 12:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 0
+test clock-29.26 {time parsing} {
+ clock scan {2440588 12 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %p}
+} 0
+test clock-29.27 {time parsing} {
+ clock scan {2440588 12:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 0
+test clock-29.28 {time parsing} {
+ clock scan {2440588 12:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 0
+test clock-29.29 {time parsing} {
+ clock scan {2440588 12:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 0
+test clock-29.30 {time parsing} {
+ clock scan {2440588 12:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 0
+test clock-29.31 {time parsing} {
+ clock scan {2440588 xii AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %p}
+} 0
+test clock-29.32 {time parsing} {
+ clock scan {2440588 xii:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 0
+test clock-29.33 {time parsing} {
+ clock scan {2440588 xii:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 0
+test clock-29.34 {time parsing} {
+ clock scan {2440588 xii:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 0
+test clock-29.35 {time parsing} {
+ clock scan {2440588 xii:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 0
+test clock-29.36 {time parsing} {
+ clock scan {2440588 xii AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %p}
+} 0
+test clock-29.37 {time parsing} {
+ clock scan {2440588 xii:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 0
+test clock-29.38 {time parsing} {
+ clock scan {2440588 xii:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 0
+test clock-29.39 {time parsing} {
+ clock scan {2440588 xii:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 0
+test clock-29.40 {time parsing} {
+ clock scan {2440588 xii:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 0
+test clock-29.41 {time parsing} {
+ clock scan {2440588 12 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %P}
+} 0
+test clock-29.42 {time parsing} {
+ clock scan {2440588 12:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 0
+test clock-29.43 {time parsing} {
+ clock scan {2440588 12:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 0
+test clock-29.44 {time parsing} {
+ clock scan {2440588 12:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 0
+test clock-29.45 {time parsing} {
+ clock scan {2440588 12:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 0
+test clock-29.46 {time parsing} {
+ clock scan {2440588 12 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %P}
+} 0
+test clock-29.47 {time parsing} {
+ clock scan {2440588 12:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 0
+test clock-29.48 {time parsing} {
+ clock scan {2440588 12:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 0
+test clock-29.49 {time parsing} {
+ clock scan {2440588 12:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 0
+test clock-29.50 {time parsing} {
+ clock scan {2440588 12:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 0
+test clock-29.51 {time parsing} {
+ clock scan {2440588 xii am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %P}
+} 0
+test clock-29.52 {time parsing} {
+ clock scan {2440588 xii:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 0
+test clock-29.53 {time parsing} {
+ clock scan {2440588 xii:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 0
+test clock-29.54 {time parsing} {
+ clock scan {2440588 xii:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 0
+test clock-29.55 {time parsing} {
+ clock scan {2440588 xii:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 0
+test clock-29.56 {time parsing} {
+ clock scan {2440588 xii am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %P}
+} 0
+test clock-29.57 {time parsing} {
+ clock scan {2440588 xii:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 0
+test clock-29.58 {time parsing} {
+ clock scan {2440588 xii:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 0
+test clock-29.59 {time parsing} {
+ clock scan {2440588 xii:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 0
+test clock-29.60 {time parsing} {
+ clock scan {2440588 xii:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 0
+test clock-29.61 {time parsing} {
+ clock scan {2440588 00:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 1
+test clock-29.62 {time parsing} {
+ clock scan {2440588 00:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 1
+test clock-29.63 {time parsing} {
+ clock scan {2440588 0:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 1
+test clock-29.64 {time parsing} {
+ clock scan {2440588 0:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 1
+test clock-29.65 {time parsing} {
+ clock scan {2440588 ?:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 1
+test clock-29.66 {time parsing} {
+ clock scan {2440588 ?:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 1
+test clock-29.67 {time parsing} {
+ clock scan {2440588 ?:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 1
+test clock-29.68 {time parsing} {
+ clock scan {2440588 ?:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 1
+test clock-29.69 {time parsing} {
+ clock scan {2440588 12:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 1
+test clock-29.70 {time parsing} {
+ clock scan {2440588 12:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 1
+test clock-29.71 {time parsing} {
+ clock scan {2440588 12:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 1
+test clock-29.72 {time parsing} {
+ clock scan {2440588 12:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 1
+test clock-29.73 {time parsing} {
+ clock scan {2440588 xii:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 1
+test clock-29.74 {time parsing} {
+ clock scan {2440588 xii:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 1
+test clock-29.75 {time parsing} {
+ clock scan {2440588 xii:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 1
+test clock-29.76 {time parsing} {
+ clock scan {2440588 xii:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 1
+test clock-29.77 {time parsing} {
+ clock scan {2440588 12:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 1
+test clock-29.78 {time parsing} {
+ clock scan {2440588 12:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 1
+test clock-29.79 {time parsing} {
+ clock scan {2440588 12:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 1
+test clock-29.80 {time parsing} {
+ clock scan {2440588 12:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 1
+test clock-29.81 {time parsing} {
+ clock scan {2440588 xii:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 1
+test clock-29.82 {time parsing} {
+ clock scan {2440588 xii:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 1
+test clock-29.83 {time parsing} {
+ clock scan {2440588 xii:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 1
+test clock-29.84 {time parsing} {
+ clock scan {2440588 xii:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 1
+test clock-29.85 {time parsing} {
+ clock scan {2440588 00:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 59
+test clock-29.86 {time parsing} {
+ clock scan {2440588 00:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 59
+test clock-29.87 {time parsing} {
+ clock scan {2440588 0:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 59
+test clock-29.88 {time parsing} {
+ clock scan {2440588 0:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 59
+test clock-29.89 {time parsing} {
+ clock scan {2440588 ?:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 59
+test clock-29.90 {time parsing} {
+ clock scan {2440588 ?:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 59
+test clock-29.91 {time parsing} {
+ clock scan {2440588 ?:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 59
+test clock-29.92 {time parsing} {
+ clock scan {2440588 ?:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 59
+test clock-29.93 {time parsing} {
+ clock scan {2440588 12:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 59
+test clock-29.94 {time parsing} {
+ clock scan {2440588 12:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 59
+test clock-29.95 {time parsing} {
+ clock scan {2440588 12:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 59
+test clock-29.96 {time parsing} {
+ clock scan {2440588 12:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 59
+test clock-29.97 {time parsing} {
+ clock scan {2440588 xii:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 59
+test clock-29.98 {time parsing} {
+ clock scan {2440588 xii:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 59
+test clock-29.99 {time parsing} {
+ clock scan {2440588 xii:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 59
+test clock-29.100 {time parsing} {
+ clock scan {2440588 xii:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 59
+test clock-29.101 {time parsing} {
+ clock scan {2440588 12:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 59
+test clock-29.102 {time parsing} {
+ clock scan {2440588 12:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 59
+test clock-29.103 {time parsing} {
+ clock scan {2440588 12:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 59
+test clock-29.104 {time parsing} {
+ clock scan {2440588 12:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 59
+test clock-29.105 {time parsing} {
+ clock scan {2440588 xii:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 59
+test clock-29.106 {time parsing} {
+ clock scan {2440588 xii:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 59
+test clock-29.107 {time parsing} {
+ clock scan {2440588 xii:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 59
+test clock-29.108 {time parsing} {
+ clock scan {2440588 xii:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 59
+test clock-29.109 {time parsing} {
+ clock scan {2440588 00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 60
+test clock-29.110 {time parsing} {
+ clock scan {2440588 00:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 60
+test clock-29.111 {time parsing} {
+ clock scan {2440588 00:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 60
+test clock-29.112 {time parsing} {
+ clock scan {2440588 00:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 60
+test clock-29.113 {time parsing} {
+ clock scan {2440588 0:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 60
+test clock-29.114 {time parsing} {
+ clock scan {2440588 0:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 60
+test clock-29.115 {time parsing} {
+ clock scan {2440588 0:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 60
+test clock-29.116 {time parsing} {
+ clock scan {2440588 0:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 60
+test clock-29.117 {time parsing} {
+ clock scan {2440588 ?:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 60
+test clock-29.118 {time parsing} {
+ clock scan {2440588 ?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 60
+test clock-29.119 {time parsing} {
+ clock scan {2440588 ?:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 60
+test clock-29.120 {time parsing} {
+ clock scan {2440588 ?:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 60
+test clock-29.121 {time parsing} {
+ clock scan {2440588 ?:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 60
+test clock-29.122 {time parsing} {
+ clock scan {2440588 ?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 60
+test clock-29.123 {time parsing} {
+ clock scan {2440588 ?:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 60
+test clock-29.124 {time parsing} {
+ clock scan {2440588 ?:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 60
+test clock-29.125 {time parsing} {
+ clock scan {2440588 12:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 60
+test clock-29.126 {time parsing} {
+ clock scan {2440588 12:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 60
+test clock-29.127 {time parsing} {
+ clock scan {2440588 12:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 60
+test clock-29.128 {time parsing} {
+ clock scan {2440588 12:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 60
+test clock-29.129 {time parsing} {
+ clock scan {2440588 12:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 60
+test clock-29.130 {time parsing} {
+ clock scan {2440588 12:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 60
+test clock-29.131 {time parsing} {
+ clock scan {2440588 12:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 60
+test clock-29.132 {time parsing} {
+ clock scan {2440588 12:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 60
+test clock-29.133 {time parsing} {
+ clock scan {2440588 xii:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 60
+test clock-29.134 {time parsing} {
+ clock scan {2440588 xii:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 60
+test clock-29.135 {time parsing} {
+ clock scan {2440588 xii:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 60
+test clock-29.136 {time parsing} {
+ clock scan {2440588 xii:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 60
+test clock-29.137 {time parsing} {
+ clock scan {2440588 xii:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 60
+test clock-29.138 {time parsing} {
+ clock scan {2440588 xii:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 60
+test clock-29.139 {time parsing} {
+ clock scan {2440588 xii:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 60
+test clock-29.140 {time parsing} {
+ clock scan {2440588 xii:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 60
+test clock-29.141 {time parsing} {
+ clock scan {2440588 12:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 60
+test clock-29.142 {time parsing} {
+ clock scan {2440588 12:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 60
+test clock-29.143 {time parsing} {
+ clock scan {2440588 12:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 60
+test clock-29.144 {time parsing} {
+ clock scan {2440588 12:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 60
+test clock-29.145 {time parsing} {
+ clock scan {2440588 12:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 60
+test clock-29.146 {time parsing} {
+ clock scan {2440588 12:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 60
+test clock-29.147 {time parsing} {
+ clock scan {2440588 12:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 60
+test clock-29.148 {time parsing} {
+ clock scan {2440588 12:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 60
+test clock-29.149 {time parsing} {
+ clock scan {2440588 xii:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 60
+test clock-29.150 {time parsing} {
+ clock scan {2440588 xii:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 60
+test clock-29.151 {time parsing} {
+ clock scan {2440588 xii:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 60
+test clock-29.152 {time parsing} {
+ clock scan {2440588 xii:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 60
+test clock-29.153 {time parsing} {
+ clock scan {2440588 xii:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 60
+test clock-29.154 {time parsing} {
+ clock scan {2440588 xii:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 60
+test clock-29.155 {time parsing} {
+ clock scan {2440588 xii:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 60
+test clock-29.156 {time parsing} {
+ clock scan {2440588 xii:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 60
+test clock-29.157 {time parsing} {
+ clock scan {2440588 00:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 61
+test clock-29.158 {time parsing} {
+ clock scan {2440588 00:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 61
+test clock-29.159 {time parsing} {
+ clock scan {2440588 0:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 61
+test clock-29.160 {time parsing} {
+ clock scan {2440588 0:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 61
+test clock-29.161 {time parsing} {
+ clock scan {2440588 ?:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 61
+test clock-29.162 {time parsing} {
+ clock scan {2440588 ?:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 61
+test clock-29.163 {time parsing} {
+ clock scan {2440588 ?:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 61
+test clock-29.164 {time parsing} {
+ clock scan {2440588 ?:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 61
+test clock-29.165 {time parsing} {
+ clock scan {2440588 12:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 61
+test clock-29.166 {time parsing} {
+ clock scan {2440588 12:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 61
+test clock-29.167 {time parsing} {
+ clock scan {2440588 12:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 61
+test clock-29.168 {time parsing} {
+ clock scan {2440588 12:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 61
+test clock-29.169 {time parsing} {
+ clock scan {2440588 xii:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 61
+test clock-29.170 {time parsing} {
+ clock scan {2440588 xii:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 61
+test clock-29.171 {time parsing} {
+ clock scan {2440588 xii:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 61
+test clock-29.172 {time parsing} {
+ clock scan {2440588 xii:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 61
+test clock-29.173 {time parsing} {
+ clock scan {2440588 12:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 61
+test clock-29.174 {time parsing} {
+ clock scan {2440588 12:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 61
+test clock-29.175 {time parsing} {
+ clock scan {2440588 12:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 61
+test clock-29.176 {time parsing} {
+ clock scan {2440588 12:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 61
+test clock-29.177 {time parsing} {
+ clock scan {2440588 xii:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 61
+test clock-29.178 {time parsing} {
+ clock scan {2440588 xii:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 61
+test clock-29.179 {time parsing} {
+ clock scan {2440588 xii:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 61
+test clock-29.180 {time parsing} {
+ clock scan {2440588 xii:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 61
+test clock-29.181 {time parsing} {
+ clock scan {2440588 00:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 119
+test clock-29.182 {time parsing} {
+ clock scan {2440588 00:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 119
+test clock-29.183 {time parsing} {
+ clock scan {2440588 0:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 119
+test clock-29.184 {time parsing} {
+ clock scan {2440588 0:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 119
+test clock-29.185 {time parsing} {
+ clock scan {2440588 ?:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 119
+test clock-29.186 {time parsing} {
+ clock scan {2440588 ?:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 119
+test clock-29.187 {time parsing} {
+ clock scan {2440588 ?:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 119
+test clock-29.188 {time parsing} {
+ clock scan {2440588 ?:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 119
+test clock-29.189 {time parsing} {
+ clock scan {2440588 12:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 119
+test clock-29.190 {time parsing} {
+ clock scan {2440588 12:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 119
+test clock-29.191 {time parsing} {
+ clock scan {2440588 12:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 119
+test clock-29.192 {time parsing} {
+ clock scan {2440588 12:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 119
+test clock-29.193 {time parsing} {
+ clock scan {2440588 xii:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 119
+test clock-29.194 {time parsing} {
+ clock scan {2440588 xii:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 119
+test clock-29.195 {time parsing} {
+ clock scan {2440588 xii:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 119
+test clock-29.196 {time parsing} {
+ clock scan {2440588 xii:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 119
+test clock-29.197 {time parsing} {
+ clock scan {2440588 12:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 119
+test clock-29.198 {time parsing} {
+ clock scan {2440588 12:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 119
+test clock-29.199 {time parsing} {
+ clock scan {2440588 12:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 119
+test clock-29.200 {time parsing} {
+ clock scan {2440588 12:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 119
+test clock-29.201 {time parsing} {
+ clock scan {2440588 xii:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 119
+test clock-29.202 {time parsing} {
+ clock scan {2440588 xii:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 119
+test clock-29.203 {time parsing} {
+ clock scan {2440588 xii:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 119
+test clock-29.204 {time parsing} {
+ clock scan {2440588 xii:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 119
+test clock-29.205 {time parsing} {
+ clock scan {2440588 00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 3540
+test clock-29.206 {time parsing} {
+ clock scan {2440588 00:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 3540
+test clock-29.207 {time parsing} {
+ clock scan {2440588 00:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3540
+test clock-29.208 {time parsing} {
+ clock scan {2440588 00:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3540
+test clock-29.209 {time parsing} {
+ clock scan {2440588 0:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 3540
+test clock-29.210 {time parsing} {
+ clock scan {2440588 0:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 3540
+test clock-29.211 {time parsing} {
+ clock scan {2440588 0:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3540
+test clock-29.212 {time parsing} {
+ clock scan {2440588 0:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3540
+test clock-29.213 {time parsing} {
+ clock scan {2440588 ?:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 3540
+test clock-29.214 {time parsing} {
+ clock scan {2440588 ?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 3540
+test clock-29.215 {time parsing} {
+ clock scan {2440588 ?:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3540
+test clock-29.216 {time parsing} {
+ clock scan {2440588 ?:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3540
+test clock-29.217 {time parsing} {
+ clock scan {2440588 ?:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 3540
+test clock-29.218 {time parsing} {
+ clock scan {2440588 ?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 3540
+test clock-29.219 {time parsing} {
+ clock scan {2440588 ?:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3540
+test clock-29.220 {time parsing} {
+ clock scan {2440588 ?:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3540
+test clock-29.221 {time parsing} {
+ clock scan {2440588 12:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 3540
+test clock-29.222 {time parsing} {
+ clock scan {2440588 12:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 3540
+test clock-29.223 {time parsing} {
+ clock scan {2440588 12:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3540
+test clock-29.224 {time parsing} {
+ clock scan {2440588 12:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3540
+test clock-29.225 {time parsing} {
+ clock scan {2440588 12:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 3540
+test clock-29.226 {time parsing} {
+ clock scan {2440588 12:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 3540
+test clock-29.227 {time parsing} {
+ clock scan {2440588 12:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3540
+test clock-29.228 {time parsing} {
+ clock scan {2440588 12:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3540
+test clock-29.229 {time parsing} {
+ clock scan {2440588 xii:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 3540
+test clock-29.230 {time parsing} {
+ clock scan {2440588 xii:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 3540
+test clock-29.231 {time parsing} {
+ clock scan {2440588 xii:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3540
+test clock-29.232 {time parsing} {
+ clock scan {2440588 xii:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3540
+test clock-29.233 {time parsing} {
+ clock scan {2440588 xii:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 3540
+test clock-29.234 {time parsing} {
+ clock scan {2440588 xii:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 3540
+test clock-29.235 {time parsing} {
+ clock scan {2440588 xii:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3540
+test clock-29.236 {time parsing} {
+ clock scan {2440588 xii:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3540
+test clock-29.237 {time parsing} {
+ clock scan {2440588 12:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 3540
+test clock-29.238 {time parsing} {
+ clock scan {2440588 12:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 3540
+test clock-29.239 {time parsing} {
+ clock scan {2440588 12:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3540
+test clock-29.240 {time parsing} {
+ clock scan {2440588 12:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3540
+test clock-29.241 {time parsing} {
+ clock scan {2440588 12:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 3540
+test clock-29.242 {time parsing} {
+ clock scan {2440588 12:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 3540
+test clock-29.243 {time parsing} {
+ clock scan {2440588 12:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3540
+test clock-29.244 {time parsing} {
+ clock scan {2440588 12:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3540
+test clock-29.245 {time parsing} {
+ clock scan {2440588 xii:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 3540
+test clock-29.246 {time parsing} {
+ clock scan {2440588 xii:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 3540
+test clock-29.247 {time parsing} {
+ clock scan {2440588 xii:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3540
+test clock-29.248 {time parsing} {
+ clock scan {2440588 xii:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3540
+test clock-29.249 {time parsing} {
+ clock scan {2440588 xii:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 3540
+test clock-29.250 {time parsing} {
+ clock scan {2440588 xii:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 3540
+test clock-29.251 {time parsing} {
+ clock scan {2440588 xii:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3540
+test clock-29.252 {time parsing} {
+ clock scan {2440588 xii:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3540
+test clock-29.253 {time parsing} {
+ clock scan {2440588 00:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3541
+test clock-29.254 {time parsing} {
+ clock scan {2440588 00:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3541
+test clock-29.255 {time parsing} {
+ clock scan {2440588 0:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3541
+test clock-29.256 {time parsing} {
+ clock scan {2440588 0:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3541
+test clock-29.257 {time parsing} {
+ clock scan {2440588 ?:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3541
+test clock-29.258 {time parsing} {
+ clock scan {2440588 ?:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3541
+test clock-29.259 {time parsing} {
+ clock scan {2440588 ?:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3541
+test clock-29.260 {time parsing} {
+ clock scan {2440588 ?:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3541
+test clock-29.261 {time parsing} {
+ clock scan {2440588 12:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3541
+test clock-29.262 {time parsing} {
+ clock scan {2440588 12:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3541
+test clock-29.263 {time parsing} {
+ clock scan {2440588 12:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3541
+test clock-29.264 {time parsing} {
+ clock scan {2440588 12:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3541
+test clock-29.265 {time parsing} {
+ clock scan {2440588 xii:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3541
+test clock-29.266 {time parsing} {
+ clock scan {2440588 xii:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3541
+test clock-29.267 {time parsing} {
+ clock scan {2440588 xii:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3541
+test clock-29.268 {time parsing} {
+ clock scan {2440588 xii:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3541
+test clock-29.269 {time parsing} {
+ clock scan {2440588 12:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3541
+test clock-29.270 {time parsing} {
+ clock scan {2440588 12:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3541
+test clock-29.271 {time parsing} {
+ clock scan {2440588 12:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3541
+test clock-29.272 {time parsing} {
+ clock scan {2440588 12:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3541
+test clock-29.273 {time parsing} {
+ clock scan {2440588 xii:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3541
+test clock-29.274 {time parsing} {
+ clock scan {2440588 xii:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3541
+test clock-29.275 {time parsing} {
+ clock scan {2440588 xii:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3541
+test clock-29.276 {time parsing} {
+ clock scan {2440588 xii:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3541
+test clock-29.277 {time parsing} {
+ clock scan {2440588 00:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3599
+test clock-29.278 {time parsing} {
+ clock scan {2440588 00:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3599
+test clock-29.279 {time parsing} {
+ clock scan {2440588 0:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3599
+test clock-29.280 {time parsing} {
+ clock scan {2440588 0:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3599
+test clock-29.281 {time parsing} {
+ clock scan {2440588 ?:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3599
+test clock-29.282 {time parsing} {
+ clock scan {2440588 ?:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3599
+test clock-29.283 {time parsing} {
+ clock scan {2440588 ?:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3599
+test clock-29.284 {time parsing} {
+ clock scan {2440588 ?:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3599
+test clock-29.285 {time parsing} {
+ clock scan {2440588 12:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3599
+test clock-29.286 {time parsing} {
+ clock scan {2440588 12:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3599
+test clock-29.287 {time parsing} {
+ clock scan {2440588 12:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3599
+test clock-29.288 {time parsing} {
+ clock scan {2440588 12:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3599
+test clock-29.289 {time parsing} {
+ clock scan {2440588 xii:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3599
+test clock-29.290 {time parsing} {
+ clock scan {2440588 xii:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3599
+test clock-29.291 {time parsing} {
+ clock scan {2440588 xii:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3599
+test clock-29.292 {time parsing} {
+ clock scan {2440588 xii:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3599
+test clock-29.293 {time parsing} {
+ clock scan {2440588 12:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3599
+test clock-29.294 {time parsing} {
+ clock scan {2440588 12:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3599
+test clock-29.295 {time parsing} {
+ clock scan {2440588 12:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3599
+test clock-29.296 {time parsing} {
+ clock scan {2440588 12:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3599
+test clock-29.297 {time parsing} {
+ clock scan {2440588 xii:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3599
+test clock-29.298 {time parsing} {
+ clock scan {2440588 xii:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3599
+test clock-29.299 {time parsing} {
+ clock scan {2440588 xii:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3599
+test clock-29.300 {time parsing} {
+ clock scan {2440588 xii:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3599
+test clock-29.301 {time parsing} {
+ clock scan {2440588 01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H }
+} 3600
+test clock-29.302 {time parsing} {
+ clock scan {2440588 01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 3600
+test clock-29.303 {time parsing} {
+ clock scan {2440588 01:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 3600
+test clock-29.304 {time parsing} {
+ clock scan {2440588 01:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3600
+test clock-29.305 {time parsing} {
+ clock scan {2440588 01:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3600
+test clock-29.306 {time parsing} {
+ clock scan {2440588 1 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k }
+} 3600
+test clock-29.307 {time parsing} {
+ clock scan {2440588 1:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 3600
+test clock-29.308 {time parsing} {
+ clock scan {2440588 1:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 3600
+test clock-29.309 {time parsing} {
+ clock scan {2440588 1:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3600
+test clock-29.310 {time parsing} {
+ clock scan {2440588 1:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3600
+test clock-29.311 {time parsing} {
+ clock scan {2440588 i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH }
+} 3600
+test clock-29.312 {time parsing} {
+ clock scan {2440588 i:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 3600
+test clock-29.313 {time parsing} {
+ clock scan {2440588 i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 3600
+test clock-29.314 {time parsing} {
+ clock scan {2440588 i:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3600
+test clock-29.315 {time parsing} {
+ clock scan {2440588 i:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3600
+test clock-29.316 {time parsing} {
+ clock scan {2440588 i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok }
+} 3600
+test clock-29.317 {time parsing} {
+ clock scan {2440588 i:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 3600
+test clock-29.318 {time parsing} {
+ clock scan {2440588 i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 3600
+test clock-29.319 {time parsing} {
+ clock scan {2440588 i:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3600
+test clock-29.320 {time parsing} {
+ clock scan {2440588 i:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3600
+test clock-29.321 {time parsing} {
+ clock scan {2440588 01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %p}
+} 3600
+test clock-29.322 {time parsing} {
+ clock scan {2440588 01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 3600
+test clock-29.323 {time parsing} {
+ clock scan {2440588 01:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 3600
+test clock-29.324 {time parsing} {
+ clock scan {2440588 01:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3600
+test clock-29.325 {time parsing} {
+ clock scan {2440588 01:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3600
+test clock-29.326 {time parsing} {
+ clock scan {2440588 1 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %p}
+} 3600
+test clock-29.327 {time parsing} {
+ clock scan {2440588 1:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 3600
+test clock-29.328 {time parsing} {
+ clock scan {2440588 1:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 3600
+test clock-29.329 {time parsing} {
+ clock scan {2440588 1:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3600
+test clock-29.330 {time parsing} {
+ clock scan {2440588 1:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3600
+test clock-29.331 {time parsing} {
+ clock scan {2440588 i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %p}
+} 3600
+test clock-29.332 {time parsing} {
+ clock scan {2440588 i:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 3600
+test clock-29.333 {time parsing} {
+ clock scan {2440588 i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 3600
+test clock-29.334 {time parsing} {
+ clock scan {2440588 i:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3600
+test clock-29.335 {time parsing} {
+ clock scan {2440588 i:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3600
+test clock-29.336 {time parsing} {
+ clock scan {2440588 i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %p}
+} 3600
+test clock-29.337 {time parsing} {
+ clock scan {2440588 i:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 3600
+test clock-29.338 {time parsing} {
+ clock scan {2440588 i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 3600
+test clock-29.339 {time parsing} {
+ clock scan {2440588 i:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3600
+test clock-29.340 {time parsing} {
+ clock scan {2440588 i:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3600
+test clock-29.341 {time parsing} {
+ clock scan {2440588 01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %P}
+} 3600
+test clock-29.342 {time parsing} {
+ clock scan {2440588 01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 3600
+test clock-29.343 {time parsing} {
+ clock scan {2440588 01:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 3600
+test clock-29.344 {time parsing} {
+ clock scan {2440588 01:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3600
+test clock-29.345 {time parsing} {
+ clock scan {2440588 01:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3600
+test clock-29.346 {time parsing} {
+ clock scan {2440588 1 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %P}
+} 3600
+test clock-29.347 {time parsing} {
+ clock scan {2440588 1:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 3600
+test clock-29.348 {time parsing} {
+ clock scan {2440588 1:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 3600
+test clock-29.349 {time parsing} {
+ clock scan {2440588 1:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3600
+test clock-29.350 {time parsing} {
+ clock scan {2440588 1:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3600
+test clock-29.351 {time parsing} {
+ clock scan {2440588 i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %P}
+} 3600
+test clock-29.352 {time parsing} {
+ clock scan {2440588 i:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 3600
+test clock-29.353 {time parsing} {
+ clock scan {2440588 i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 3600
+test clock-29.354 {time parsing} {
+ clock scan {2440588 i:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3600
+test clock-29.355 {time parsing} {
+ clock scan {2440588 i:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3600
+test clock-29.356 {time parsing} {
+ clock scan {2440588 i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %P}
+} 3600
+test clock-29.357 {time parsing} {
+ clock scan {2440588 i:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 3600
+test clock-29.358 {time parsing} {
+ clock scan {2440588 i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 3600
+test clock-29.359 {time parsing} {
+ clock scan {2440588 i:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3600
+test clock-29.360 {time parsing} {
+ clock scan {2440588 i:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3600
+test clock-29.361 {time parsing} {
+ clock scan {2440588 01:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3601
+test clock-29.362 {time parsing} {
+ clock scan {2440588 01:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3601
+test clock-29.363 {time parsing} {
+ clock scan {2440588 1:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3601
+test clock-29.364 {time parsing} {
+ clock scan {2440588 1:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3601
+test clock-29.365 {time parsing} {
+ clock scan {2440588 i:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3601
+test clock-29.366 {time parsing} {
+ clock scan {2440588 i:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3601
+test clock-29.367 {time parsing} {
+ clock scan {2440588 i:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3601
+test clock-29.368 {time parsing} {
+ clock scan {2440588 i:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3601
+test clock-29.369 {time parsing} {
+ clock scan {2440588 01:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3601
+test clock-29.370 {time parsing} {
+ clock scan {2440588 01:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3601
+test clock-29.371 {time parsing} {
+ clock scan {2440588 1:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3601
+test clock-29.372 {time parsing} {
+ clock scan {2440588 1:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3601
+test clock-29.373 {time parsing} {
+ clock scan {2440588 i:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3601
+test clock-29.374 {time parsing} {
+ clock scan {2440588 i:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3601
+test clock-29.375 {time parsing} {
+ clock scan {2440588 i:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3601
+test clock-29.376 {time parsing} {
+ clock scan {2440588 i:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3601
+test clock-29.377 {time parsing} {
+ clock scan {2440588 01:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3601
+test clock-29.378 {time parsing} {
+ clock scan {2440588 01:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3601
+test clock-29.379 {time parsing} {
+ clock scan {2440588 1:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3601
+test clock-29.380 {time parsing} {
+ clock scan {2440588 1:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3601
+test clock-29.381 {time parsing} {
+ clock scan {2440588 i:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3601
+test clock-29.382 {time parsing} {
+ clock scan {2440588 i:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3601
+test clock-29.383 {time parsing} {
+ clock scan {2440588 i:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3601
+test clock-29.384 {time parsing} {
+ clock scan {2440588 i:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3601
+test clock-29.385 {time parsing} {
+ clock scan {2440588 01:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3659
+test clock-29.386 {time parsing} {
+ clock scan {2440588 01:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3659
+test clock-29.387 {time parsing} {
+ clock scan {2440588 1:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3659
+test clock-29.388 {time parsing} {
+ clock scan {2440588 1:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3659
+test clock-29.389 {time parsing} {
+ clock scan {2440588 i:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3659
+test clock-29.390 {time parsing} {
+ clock scan {2440588 i:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3659
+test clock-29.391 {time parsing} {
+ clock scan {2440588 i:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3659
+test clock-29.392 {time parsing} {
+ clock scan {2440588 i:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3659
+test clock-29.393 {time parsing} {
+ clock scan {2440588 01:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3659
+test clock-29.394 {time parsing} {
+ clock scan {2440588 01:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3659
+test clock-29.395 {time parsing} {
+ clock scan {2440588 1:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3659
+test clock-29.396 {time parsing} {
+ clock scan {2440588 1:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3659
+test clock-29.397 {time parsing} {
+ clock scan {2440588 i:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3659
+test clock-29.398 {time parsing} {
+ clock scan {2440588 i:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3659
+test clock-29.399 {time parsing} {
+ clock scan {2440588 i:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3659
+test clock-29.400 {time parsing} {
+ clock scan {2440588 i:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3659
+test clock-29.401 {time parsing} {
+ clock scan {2440588 01:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3659
+test clock-29.402 {time parsing} {
+ clock scan {2440588 01:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3659
+test clock-29.403 {time parsing} {
+ clock scan {2440588 1:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3659
+test clock-29.404 {time parsing} {
+ clock scan {2440588 1:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3659
+test clock-29.405 {time parsing} {
+ clock scan {2440588 i:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3659
+test clock-29.406 {time parsing} {
+ clock scan {2440588 i:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3659
+test clock-29.407 {time parsing} {
+ clock scan {2440588 i:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3659
+test clock-29.408 {time parsing} {
+ clock scan {2440588 i:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3659
+test clock-29.409 {time parsing} {
+ clock scan {2440588 01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 3660
+test clock-29.410 {time parsing} {
+ clock scan {2440588 01:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 3660
+test clock-29.411 {time parsing} {
+ clock scan {2440588 01:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3660
+test clock-29.412 {time parsing} {
+ clock scan {2440588 01:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3660
+test clock-29.413 {time parsing} {
+ clock scan {2440588 1:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 3660
+test clock-29.414 {time parsing} {
+ clock scan {2440588 1:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 3660
+test clock-29.415 {time parsing} {
+ clock scan {2440588 1:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3660
+test clock-29.416 {time parsing} {
+ clock scan {2440588 1:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3660
+test clock-29.417 {time parsing} {
+ clock scan {2440588 i:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 3660
+test clock-29.418 {time parsing} {
+ clock scan {2440588 i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 3660
+test clock-29.419 {time parsing} {
+ clock scan {2440588 i:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3660
+test clock-29.420 {time parsing} {
+ clock scan {2440588 i:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3660
+test clock-29.421 {time parsing} {
+ clock scan {2440588 i:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 3660
+test clock-29.422 {time parsing} {
+ clock scan {2440588 i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 3660
+test clock-29.423 {time parsing} {
+ clock scan {2440588 i:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3660
+test clock-29.424 {time parsing} {
+ clock scan {2440588 i:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3660
+test clock-29.425 {time parsing} {
+ clock scan {2440588 01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 3660
+test clock-29.426 {time parsing} {
+ clock scan {2440588 01:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 3660
+test clock-29.427 {time parsing} {
+ clock scan {2440588 01:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3660
+test clock-29.428 {time parsing} {
+ clock scan {2440588 01:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3660
+test clock-29.429 {time parsing} {
+ clock scan {2440588 1:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 3660
+test clock-29.430 {time parsing} {
+ clock scan {2440588 1:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 3660
+test clock-29.431 {time parsing} {
+ clock scan {2440588 1:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3660
+test clock-29.432 {time parsing} {
+ clock scan {2440588 1:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3660
+test clock-29.433 {time parsing} {
+ clock scan {2440588 i:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 3660
+test clock-29.434 {time parsing} {
+ clock scan {2440588 i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 3660
+test clock-29.435 {time parsing} {
+ clock scan {2440588 i:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3660
+test clock-29.436 {time parsing} {
+ clock scan {2440588 i:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3660
+test clock-29.437 {time parsing} {
+ clock scan {2440588 i:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 3660
+test clock-29.438 {time parsing} {
+ clock scan {2440588 i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 3660
+test clock-29.439 {time parsing} {
+ clock scan {2440588 i:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3660
+test clock-29.440 {time parsing} {
+ clock scan {2440588 i:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3660
+test clock-29.441 {time parsing} {
+ clock scan {2440588 01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 3660
+test clock-29.442 {time parsing} {
+ clock scan {2440588 01:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 3660
+test clock-29.443 {time parsing} {
+ clock scan {2440588 01:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3660
+test clock-29.444 {time parsing} {
+ clock scan {2440588 01:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3660
+test clock-29.445 {time parsing} {
+ clock scan {2440588 1:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 3660
+test clock-29.446 {time parsing} {
+ clock scan {2440588 1:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 3660
+test clock-29.447 {time parsing} {
+ clock scan {2440588 1:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3660
+test clock-29.448 {time parsing} {
+ clock scan {2440588 1:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3660
+test clock-29.449 {time parsing} {
+ clock scan {2440588 i:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 3660
+test clock-29.450 {time parsing} {
+ clock scan {2440588 i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 3660
+test clock-29.451 {time parsing} {
+ clock scan {2440588 i:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3660
+test clock-29.452 {time parsing} {
+ clock scan {2440588 i:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3660
+test clock-29.453 {time parsing} {
+ clock scan {2440588 i:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 3660
+test clock-29.454 {time parsing} {
+ clock scan {2440588 i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 3660
+test clock-29.455 {time parsing} {
+ clock scan {2440588 i:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3660
+test clock-29.456 {time parsing} {
+ clock scan {2440588 i:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3660
+test clock-29.457 {time parsing} {
+ clock scan {2440588 01:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3661
+test clock-29.458 {time parsing} {
+ clock scan {2440588 01:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3661
+test clock-29.459 {time parsing} {
+ clock scan {2440588 1:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3661
+test clock-29.460 {time parsing} {
+ clock scan {2440588 1:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3661
+test clock-29.461 {time parsing} {
+ clock scan {2440588 i:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3661
+test clock-29.462 {time parsing} {
+ clock scan {2440588 i:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3661
+test clock-29.463 {time parsing} {
+ clock scan {2440588 i:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3661
+test clock-29.464 {time parsing} {
+ clock scan {2440588 i:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3661
+test clock-29.465 {time parsing} {
+ clock scan {2440588 01:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3661
+test clock-29.466 {time parsing} {
+ clock scan {2440588 01:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3661
+test clock-29.467 {time parsing} {
+ clock scan {2440588 1:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3661
+test clock-29.468 {time parsing} {
+ clock scan {2440588 1:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3661
+test clock-29.469 {time parsing} {
+ clock scan {2440588 i:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3661
+test clock-29.470 {time parsing} {
+ clock scan {2440588 i:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3661
+test clock-29.471 {time parsing} {
+ clock scan {2440588 i:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3661
+test clock-29.472 {time parsing} {
+ clock scan {2440588 i:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3661
+test clock-29.473 {time parsing} {
+ clock scan {2440588 01:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3661
+test clock-29.474 {time parsing} {
+ clock scan {2440588 01:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3661
+test clock-29.475 {time parsing} {
+ clock scan {2440588 1:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3661
+test clock-29.476 {time parsing} {
+ clock scan {2440588 1:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3661
+test clock-29.477 {time parsing} {
+ clock scan {2440588 i:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3661
+test clock-29.478 {time parsing} {
+ clock scan {2440588 i:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3661
+test clock-29.479 {time parsing} {
+ clock scan {2440588 i:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3661
+test clock-29.480 {time parsing} {
+ clock scan {2440588 i:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3661
+test clock-29.481 {time parsing} {
+ clock scan {2440588 01:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 3719
+test clock-29.482 {time parsing} {
+ clock scan {2440588 01:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 3719
+test clock-29.483 {time parsing} {
+ clock scan {2440588 1:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 3719
+test clock-29.484 {time parsing} {
+ clock scan {2440588 1:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 3719
+test clock-29.485 {time parsing} {
+ clock scan {2440588 i:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 3719
+test clock-29.486 {time parsing} {
+ clock scan {2440588 i:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 3719
+test clock-29.487 {time parsing} {
+ clock scan {2440588 i:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 3719
+test clock-29.488 {time parsing} {
+ clock scan {2440588 i:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 3719
+test clock-29.489 {time parsing} {
+ clock scan {2440588 01:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 3719
+test clock-29.490 {time parsing} {
+ clock scan {2440588 01:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 3719
+test clock-29.491 {time parsing} {
+ clock scan {2440588 1:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 3719
+test clock-29.492 {time parsing} {
+ clock scan {2440588 1:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 3719
+test clock-29.493 {time parsing} {
+ clock scan {2440588 i:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 3719
+test clock-29.494 {time parsing} {
+ clock scan {2440588 i:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 3719
+test clock-29.495 {time parsing} {
+ clock scan {2440588 i:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 3719
+test clock-29.496 {time parsing} {
+ clock scan {2440588 i:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 3719
+test clock-29.497 {time parsing} {
+ clock scan {2440588 01:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 3719
+test clock-29.498 {time parsing} {
+ clock scan {2440588 01:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 3719
+test clock-29.499 {time parsing} {
+ clock scan {2440588 1:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 3719
+test clock-29.500 {time parsing} {
+ clock scan {2440588 1:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 3719
+test clock-29.501 {time parsing} {
+ clock scan {2440588 i:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 3719
+test clock-29.502 {time parsing} {
+ clock scan {2440588 i:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 3719
+test clock-29.503 {time parsing} {
+ clock scan {2440588 i:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 3719
+test clock-29.504 {time parsing} {
+ clock scan {2440588 i:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 3719
+test clock-29.505 {time parsing} {
+ clock scan {2440588 01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 7140
+test clock-29.506 {time parsing} {
+ clock scan {2440588 01:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 7140
+test clock-29.507 {time parsing} {
+ clock scan {2440588 01:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 7140
+test clock-29.508 {time parsing} {
+ clock scan {2440588 01:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 7140
+test clock-29.509 {time parsing} {
+ clock scan {2440588 1:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 7140
+test clock-29.510 {time parsing} {
+ clock scan {2440588 1:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 7140
+test clock-29.511 {time parsing} {
+ clock scan {2440588 1:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 7140
+test clock-29.512 {time parsing} {
+ clock scan {2440588 1:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 7140
+test clock-29.513 {time parsing} {
+ clock scan {2440588 i:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 7140
+test clock-29.514 {time parsing} {
+ clock scan {2440588 i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 7140
+test clock-29.515 {time parsing} {
+ clock scan {2440588 i:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 7140
+test clock-29.516 {time parsing} {
+ clock scan {2440588 i:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 7140
+test clock-29.517 {time parsing} {
+ clock scan {2440588 i:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 7140
+test clock-29.518 {time parsing} {
+ clock scan {2440588 i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 7140
+test clock-29.519 {time parsing} {
+ clock scan {2440588 i:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 7140
+test clock-29.520 {time parsing} {
+ clock scan {2440588 i:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 7140
+test clock-29.521 {time parsing} {
+ clock scan {2440588 01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 7140
+test clock-29.522 {time parsing} {
+ clock scan {2440588 01:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 7140
+test clock-29.523 {time parsing} {
+ clock scan {2440588 01:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 7140
+test clock-29.524 {time parsing} {
+ clock scan {2440588 01:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 7140
+test clock-29.525 {time parsing} {
+ clock scan {2440588 1:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 7140
+test clock-29.526 {time parsing} {
+ clock scan {2440588 1:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 7140
+test clock-29.527 {time parsing} {
+ clock scan {2440588 1:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 7140
+test clock-29.528 {time parsing} {
+ clock scan {2440588 1:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 7140
+test clock-29.529 {time parsing} {
+ clock scan {2440588 i:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 7140
+test clock-29.530 {time parsing} {
+ clock scan {2440588 i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 7140
+test clock-29.531 {time parsing} {
+ clock scan {2440588 i:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 7140
+test clock-29.532 {time parsing} {
+ clock scan {2440588 i:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 7140
+test clock-29.533 {time parsing} {
+ clock scan {2440588 i:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 7140
+test clock-29.534 {time parsing} {
+ clock scan {2440588 i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 7140
+test clock-29.535 {time parsing} {
+ clock scan {2440588 i:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 7140
+test clock-29.536 {time parsing} {
+ clock scan {2440588 i:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 7140
+test clock-29.537 {time parsing} {
+ clock scan {2440588 01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 7140
+test clock-29.538 {time parsing} {
+ clock scan {2440588 01:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 7140
+test clock-29.539 {time parsing} {
+ clock scan {2440588 01:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 7140
+test clock-29.540 {time parsing} {
+ clock scan {2440588 01:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 7140
+test clock-29.541 {time parsing} {
+ clock scan {2440588 1:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 7140
+test clock-29.542 {time parsing} {
+ clock scan {2440588 1:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 7140
+test clock-29.543 {time parsing} {
+ clock scan {2440588 1:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 7140
+test clock-29.544 {time parsing} {
+ clock scan {2440588 1:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 7140
+test clock-29.545 {time parsing} {
+ clock scan {2440588 i:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 7140
+test clock-29.546 {time parsing} {
+ clock scan {2440588 i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 7140
+test clock-29.547 {time parsing} {
+ clock scan {2440588 i:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 7140
+test clock-29.548 {time parsing} {
+ clock scan {2440588 i:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 7140
+test clock-29.549 {time parsing} {
+ clock scan {2440588 i:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 7140
+test clock-29.550 {time parsing} {
+ clock scan {2440588 i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 7140
+test clock-29.551 {time parsing} {
+ clock scan {2440588 i:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 7140
+test clock-29.552 {time parsing} {
+ clock scan {2440588 i:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 7140
+test clock-29.553 {time parsing} {
+ clock scan {2440588 01:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 7141
+test clock-29.554 {time parsing} {
+ clock scan {2440588 01:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 7141
+test clock-29.555 {time parsing} {
+ clock scan {2440588 1:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 7141
+test clock-29.556 {time parsing} {
+ clock scan {2440588 1:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 7141
+test clock-29.557 {time parsing} {
+ clock scan {2440588 i:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 7141
+test clock-29.558 {time parsing} {
+ clock scan {2440588 i:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 7141
+test clock-29.559 {time parsing} {
+ clock scan {2440588 i:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 7141
+test clock-29.560 {time parsing} {
+ clock scan {2440588 i:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 7141
+test clock-29.561 {time parsing} {
+ clock scan {2440588 01:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 7141
+test clock-29.562 {time parsing} {
+ clock scan {2440588 01:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 7141
+test clock-29.563 {time parsing} {
+ clock scan {2440588 1:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 7141
+test clock-29.564 {time parsing} {
+ clock scan {2440588 1:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 7141
+test clock-29.565 {time parsing} {
+ clock scan {2440588 i:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 7141
+test clock-29.566 {time parsing} {
+ clock scan {2440588 i:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 7141
+test clock-29.567 {time parsing} {
+ clock scan {2440588 i:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 7141
+test clock-29.568 {time parsing} {
+ clock scan {2440588 i:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 7141
+test clock-29.569 {time parsing} {
+ clock scan {2440588 01:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 7141
+test clock-29.570 {time parsing} {
+ clock scan {2440588 01:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 7141
+test clock-29.571 {time parsing} {
+ clock scan {2440588 1:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 7141
+test clock-29.572 {time parsing} {
+ clock scan {2440588 1:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 7141
+test clock-29.573 {time parsing} {
+ clock scan {2440588 i:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 7141
+test clock-29.574 {time parsing} {
+ clock scan {2440588 i:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 7141
+test clock-29.575 {time parsing} {
+ clock scan {2440588 i:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 7141
+test clock-29.576 {time parsing} {
+ clock scan {2440588 i:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 7141
+test clock-29.577 {time parsing} {
+ clock scan {2440588 01:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 7199
+test clock-29.578 {time parsing} {
+ clock scan {2440588 01:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 7199
+test clock-29.579 {time parsing} {
+ clock scan {2440588 1:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 7199
+test clock-29.580 {time parsing} {
+ clock scan {2440588 1:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 7199
+test clock-29.581 {time parsing} {
+ clock scan {2440588 i:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 7199
+test clock-29.582 {time parsing} {
+ clock scan {2440588 i:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 7199
+test clock-29.583 {time parsing} {
+ clock scan {2440588 i:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 7199
+test clock-29.584 {time parsing} {
+ clock scan {2440588 i:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 7199
+test clock-29.585 {time parsing} {
+ clock scan {2440588 01:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 7199
+test clock-29.586 {time parsing} {
+ clock scan {2440588 01:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 7199
+test clock-29.587 {time parsing} {
+ clock scan {2440588 1:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 7199
+test clock-29.588 {time parsing} {
+ clock scan {2440588 1:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 7199
+test clock-29.589 {time parsing} {
+ clock scan {2440588 i:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 7199
+test clock-29.590 {time parsing} {
+ clock scan {2440588 i:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 7199
+test clock-29.591 {time parsing} {
+ clock scan {2440588 i:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 7199
+test clock-29.592 {time parsing} {
+ clock scan {2440588 i:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 7199
+test clock-29.593 {time parsing} {
+ clock scan {2440588 01:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 7199
+test clock-29.594 {time parsing} {
+ clock scan {2440588 01:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 7199
+test clock-29.595 {time parsing} {
+ clock scan {2440588 1:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 7199
+test clock-29.596 {time parsing} {
+ clock scan {2440588 1:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 7199
+test clock-29.597 {time parsing} {
+ clock scan {2440588 i:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 7199
+test clock-29.598 {time parsing} {
+ clock scan {2440588 i:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 7199
+test clock-29.599 {time parsing} {
+ clock scan {2440588 i:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 7199
+test clock-29.600 {time parsing} {
+ clock scan {2440588 i:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 7199
+test clock-29.601 {time parsing} {
+ clock scan {2440588 11 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H }
+} 39600
+test clock-29.602 {time parsing} {
+ clock scan {2440588 11:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 39600
+test clock-29.603 {time parsing} {
+ clock scan {2440588 11:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 39600
+test clock-29.604 {time parsing} {
+ clock scan {2440588 11:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 39600
+test clock-29.605 {time parsing} {
+ clock scan {2440588 11:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 39600
+test clock-29.606 {time parsing} {
+ clock scan {2440588 11 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k }
+} 39600
+test clock-29.607 {time parsing} {
+ clock scan {2440588 11:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 39600
+test clock-29.608 {time parsing} {
+ clock scan {2440588 11:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 39600
+test clock-29.609 {time parsing} {
+ clock scan {2440588 11:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 39600
+test clock-29.610 {time parsing} {
+ clock scan {2440588 11:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 39600
+test clock-29.611 {time parsing} {
+ clock scan {2440588 xi } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH }
+} 39600
+test clock-29.612 {time parsing} {
+ clock scan {2440588 xi:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 39600
+test clock-29.613 {time parsing} {
+ clock scan {2440588 xi:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 39600
+test clock-29.614 {time parsing} {
+ clock scan {2440588 xi:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 39600
+test clock-29.615 {time parsing} {
+ clock scan {2440588 xi:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 39600
+test clock-29.616 {time parsing} {
+ clock scan {2440588 xi } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok }
+} 39600
+test clock-29.617 {time parsing} {
+ clock scan {2440588 xi:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 39600
+test clock-29.618 {time parsing} {
+ clock scan {2440588 xi:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 39600
+test clock-29.619 {time parsing} {
+ clock scan {2440588 xi:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 39600
+test clock-29.620 {time parsing} {
+ clock scan {2440588 xi:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 39600
+test clock-29.621 {time parsing} {
+ clock scan {2440588 11 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %p}
+} 39600
+test clock-29.622 {time parsing} {
+ clock scan {2440588 11:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 39600
+test clock-29.623 {time parsing} {
+ clock scan {2440588 11:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 39600
+test clock-29.624 {time parsing} {
+ clock scan {2440588 11:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 39600
+test clock-29.625 {time parsing} {
+ clock scan {2440588 11:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 39600
+test clock-29.626 {time parsing} {
+ clock scan {2440588 11 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %p}
+} 39600
+test clock-29.627 {time parsing} {
+ clock scan {2440588 11:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 39600
+test clock-29.628 {time parsing} {
+ clock scan {2440588 11:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 39600
+test clock-29.629 {time parsing} {
+ clock scan {2440588 11:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 39600
+test clock-29.630 {time parsing} {
+ clock scan {2440588 11:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 39600
+test clock-29.631 {time parsing} {
+ clock scan {2440588 xi AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %p}
+} 39600
+test clock-29.632 {time parsing} {
+ clock scan {2440588 xi:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 39600
+test clock-29.633 {time parsing} {
+ clock scan {2440588 xi:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 39600
+test clock-29.634 {time parsing} {
+ clock scan {2440588 xi:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 39600
+test clock-29.635 {time parsing} {
+ clock scan {2440588 xi:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 39600
+test clock-29.636 {time parsing} {
+ clock scan {2440588 xi AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %p}
+} 39600
+test clock-29.637 {time parsing} {
+ clock scan {2440588 xi:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 39600
+test clock-29.638 {time parsing} {
+ clock scan {2440588 xi:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 39600
+test clock-29.639 {time parsing} {
+ clock scan {2440588 xi:00:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 39600
+test clock-29.640 {time parsing} {
+ clock scan {2440588 xi:?:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 39600
+test clock-29.641 {time parsing} {
+ clock scan {2440588 11 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %P}
+} 39600
+test clock-29.642 {time parsing} {
+ clock scan {2440588 11:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 39600
+test clock-29.643 {time parsing} {
+ clock scan {2440588 11:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 39600
+test clock-29.644 {time parsing} {
+ clock scan {2440588 11:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 39600
+test clock-29.645 {time parsing} {
+ clock scan {2440588 11:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 39600
+test clock-29.646 {time parsing} {
+ clock scan {2440588 11 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %P}
+} 39600
+test clock-29.647 {time parsing} {
+ clock scan {2440588 11:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 39600
+test clock-29.648 {time parsing} {
+ clock scan {2440588 11:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 39600
+test clock-29.649 {time parsing} {
+ clock scan {2440588 11:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 39600
+test clock-29.650 {time parsing} {
+ clock scan {2440588 11:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 39600
+test clock-29.651 {time parsing} {
+ clock scan {2440588 xi am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %P}
+} 39600
+test clock-29.652 {time parsing} {
+ clock scan {2440588 xi:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 39600
+test clock-29.653 {time parsing} {
+ clock scan {2440588 xi:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 39600
+test clock-29.654 {time parsing} {
+ clock scan {2440588 xi:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 39600
+test clock-29.655 {time parsing} {
+ clock scan {2440588 xi:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 39600
+test clock-29.656 {time parsing} {
+ clock scan {2440588 xi am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %P}
+} 39600
+test clock-29.657 {time parsing} {
+ clock scan {2440588 xi:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 39600
+test clock-29.658 {time parsing} {
+ clock scan {2440588 xi:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 39600
+test clock-29.659 {time parsing} {
+ clock scan {2440588 xi:00:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 39600
+test clock-29.660 {time parsing} {
+ clock scan {2440588 xi:?:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 39600
+test clock-29.661 {time parsing} {
+ clock scan {2440588 11:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 39601
+test clock-29.662 {time parsing} {
+ clock scan {2440588 11:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 39601
+test clock-29.663 {time parsing} {
+ clock scan {2440588 11:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 39601
+test clock-29.664 {time parsing} {
+ clock scan {2440588 11:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 39601
+test clock-29.665 {time parsing} {
+ clock scan {2440588 xi:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 39601
+test clock-29.666 {time parsing} {
+ clock scan {2440588 xi:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 39601
+test clock-29.667 {time parsing} {
+ clock scan {2440588 xi:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 39601
+test clock-29.668 {time parsing} {
+ clock scan {2440588 xi:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 39601
+test clock-29.669 {time parsing} {
+ clock scan {2440588 11:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 39601
+test clock-29.670 {time parsing} {
+ clock scan {2440588 11:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 39601
+test clock-29.671 {time parsing} {
+ clock scan {2440588 11:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 39601
+test clock-29.672 {time parsing} {
+ clock scan {2440588 11:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 39601
+test clock-29.673 {time parsing} {
+ clock scan {2440588 xi:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 39601
+test clock-29.674 {time parsing} {
+ clock scan {2440588 xi:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 39601
+test clock-29.675 {time parsing} {
+ clock scan {2440588 xi:00:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 39601
+test clock-29.676 {time parsing} {
+ clock scan {2440588 xi:?:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 39601
+test clock-29.677 {time parsing} {
+ clock scan {2440588 11:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 39601
+test clock-29.678 {time parsing} {
+ clock scan {2440588 11:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 39601
+test clock-29.679 {time parsing} {
+ clock scan {2440588 11:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 39601
+test clock-29.680 {time parsing} {
+ clock scan {2440588 11:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 39601
+test clock-29.681 {time parsing} {
+ clock scan {2440588 xi:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 39601
+test clock-29.682 {time parsing} {
+ clock scan {2440588 xi:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 39601
+test clock-29.683 {time parsing} {
+ clock scan {2440588 xi:00:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 39601
+test clock-29.684 {time parsing} {
+ clock scan {2440588 xi:?:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 39601
+test clock-29.685 {time parsing} {
+ clock scan {2440588 11:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 39659
+test clock-29.686 {time parsing} {
+ clock scan {2440588 11:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 39659
+test clock-29.687 {time parsing} {
+ clock scan {2440588 11:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 39659
+test clock-29.688 {time parsing} {
+ clock scan {2440588 11:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 39659
+test clock-29.689 {time parsing} {
+ clock scan {2440588 xi:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 39659
+test clock-29.690 {time parsing} {
+ clock scan {2440588 xi:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 39659
+test clock-29.691 {time parsing} {
+ clock scan {2440588 xi:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 39659
+test clock-29.692 {time parsing} {
+ clock scan {2440588 xi:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 39659
+test clock-29.693 {time parsing} {
+ clock scan {2440588 11:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 39659
+test clock-29.694 {time parsing} {
+ clock scan {2440588 11:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 39659
+test clock-29.695 {time parsing} {
+ clock scan {2440588 11:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 39659
+test clock-29.696 {time parsing} {
+ clock scan {2440588 11:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 39659
+test clock-29.697 {time parsing} {
+ clock scan {2440588 xi:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 39659
+test clock-29.698 {time parsing} {
+ clock scan {2440588 xi:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 39659
+test clock-29.699 {time parsing} {
+ clock scan {2440588 xi:00:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 39659
+test clock-29.700 {time parsing} {
+ clock scan {2440588 xi:?:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 39659
+test clock-29.701 {time parsing} {
+ clock scan {2440588 11:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 39659
+test clock-29.702 {time parsing} {
+ clock scan {2440588 11:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 39659
+test clock-29.703 {time parsing} {
+ clock scan {2440588 11:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 39659
+test clock-29.704 {time parsing} {
+ clock scan {2440588 11:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 39659
+test clock-29.705 {time parsing} {
+ clock scan {2440588 xi:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 39659
+test clock-29.706 {time parsing} {
+ clock scan {2440588 xi:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 39659
+test clock-29.707 {time parsing} {
+ clock scan {2440588 xi:00:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 39659
+test clock-29.708 {time parsing} {
+ clock scan {2440588 xi:?:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 39659
+test clock-29.709 {time parsing} {
+ clock scan {2440588 11:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 39660
+test clock-29.710 {time parsing} {
+ clock scan {2440588 11:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 39660
+test clock-29.711 {time parsing} {
+ clock scan {2440588 11:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 39660
+test clock-29.712 {time parsing} {
+ clock scan {2440588 11:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 39660
+test clock-29.713 {time parsing} {
+ clock scan {2440588 11:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 39660
+test clock-29.714 {time parsing} {
+ clock scan {2440588 11:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 39660
+test clock-29.715 {time parsing} {
+ clock scan {2440588 11:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 39660
+test clock-29.716 {time parsing} {
+ clock scan {2440588 11:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 39660
+test clock-29.717 {time parsing} {
+ clock scan {2440588 xi:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 39660
+test clock-29.718 {time parsing} {
+ clock scan {2440588 xi:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 39660
+test clock-29.719 {time parsing} {
+ clock scan {2440588 xi:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 39660
+test clock-29.720 {time parsing} {
+ clock scan {2440588 xi:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 39660
+test clock-29.721 {time parsing} {
+ clock scan {2440588 xi:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 39660
+test clock-29.722 {time parsing} {
+ clock scan {2440588 xi:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 39660
+test clock-29.723 {time parsing} {
+ clock scan {2440588 xi:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 39660
+test clock-29.724 {time parsing} {
+ clock scan {2440588 xi:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 39660
+test clock-29.725 {time parsing} {
+ clock scan {2440588 11:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 39660
+test clock-29.726 {time parsing} {
+ clock scan {2440588 11:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 39660
+test clock-29.727 {time parsing} {
+ clock scan {2440588 11:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 39660
+test clock-29.728 {time parsing} {
+ clock scan {2440588 11:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 39660
+test clock-29.729 {time parsing} {
+ clock scan {2440588 11:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 39660
+test clock-29.730 {time parsing} {
+ clock scan {2440588 11:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 39660
+test clock-29.731 {time parsing} {
+ clock scan {2440588 11:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 39660
+test clock-29.732 {time parsing} {
+ clock scan {2440588 11:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 39660
+test clock-29.733 {time parsing} {
+ clock scan {2440588 xi:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 39660
+test clock-29.734 {time parsing} {
+ clock scan {2440588 xi:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 39660
+test clock-29.735 {time parsing} {
+ clock scan {2440588 xi:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 39660
+test clock-29.736 {time parsing} {
+ clock scan {2440588 xi:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 39660
+test clock-29.737 {time parsing} {
+ clock scan {2440588 xi:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 39660
+test clock-29.738 {time parsing} {
+ clock scan {2440588 xi:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 39660
+test clock-29.739 {time parsing} {
+ clock scan {2440588 xi:01:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 39660
+test clock-29.740 {time parsing} {
+ clock scan {2440588 xi:i:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 39660
+test clock-29.741 {time parsing} {
+ clock scan {2440588 11:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 39660
+test clock-29.742 {time parsing} {
+ clock scan {2440588 11:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 39660
+test clock-29.743 {time parsing} {
+ clock scan {2440588 11:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 39660
+test clock-29.744 {time parsing} {
+ clock scan {2440588 11:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 39660
+test clock-29.745 {time parsing} {
+ clock scan {2440588 11:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 39660
+test clock-29.746 {time parsing} {
+ clock scan {2440588 11:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 39660
+test clock-29.747 {time parsing} {
+ clock scan {2440588 11:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 39660
+test clock-29.748 {time parsing} {
+ clock scan {2440588 11:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 39660
+test clock-29.749 {time parsing} {
+ clock scan {2440588 xi:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 39660
+test clock-29.750 {time parsing} {
+ clock scan {2440588 xi:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 39660
+test clock-29.751 {time parsing} {
+ clock scan {2440588 xi:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 39660
+test clock-29.752 {time parsing} {
+ clock scan {2440588 xi:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 39660
+test clock-29.753 {time parsing} {
+ clock scan {2440588 xi:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 39660
+test clock-29.754 {time parsing} {
+ clock scan {2440588 xi:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 39660
+test clock-29.755 {time parsing} {
+ clock scan {2440588 xi:01:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 39660
+test clock-29.756 {time parsing} {
+ clock scan {2440588 xi:i:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 39660
+test clock-29.757 {time parsing} {
+ clock scan {2440588 11:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 39661
+test clock-29.758 {time parsing} {
+ clock scan {2440588 11:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 39661
+test clock-29.759 {time parsing} {
+ clock scan {2440588 11:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 39661
+test clock-29.760 {time parsing} {
+ clock scan {2440588 11:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 39661
+test clock-29.761 {time parsing} {
+ clock scan {2440588 xi:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 39661
+test clock-29.762 {time parsing} {
+ clock scan {2440588 xi:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 39661
+test clock-29.763 {time parsing} {
+ clock scan {2440588 xi:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 39661
+test clock-29.764 {time parsing} {
+ clock scan {2440588 xi:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 39661
+test clock-29.765 {time parsing} {
+ clock scan {2440588 11:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 39661
+test clock-29.766 {time parsing} {
+ clock scan {2440588 11:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 39661
+test clock-29.767 {time parsing} {
+ clock scan {2440588 11:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 39661
+test clock-29.768 {time parsing} {
+ clock scan {2440588 11:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 39661
+test clock-29.769 {time parsing} {
+ clock scan {2440588 xi:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 39661
+test clock-29.770 {time parsing} {
+ clock scan {2440588 xi:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 39661
+test clock-29.771 {time parsing} {
+ clock scan {2440588 xi:01:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 39661
+test clock-29.772 {time parsing} {
+ clock scan {2440588 xi:i:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 39661
+test clock-29.773 {time parsing} {
+ clock scan {2440588 11:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 39661
+test clock-29.774 {time parsing} {
+ clock scan {2440588 11:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 39661
+test clock-29.775 {time parsing} {
+ clock scan {2440588 11:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 39661
+test clock-29.776 {time parsing} {
+ clock scan {2440588 11:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 39661
+test clock-29.777 {time parsing} {
+ clock scan {2440588 xi:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 39661
+test clock-29.778 {time parsing} {
+ clock scan {2440588 xi:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 39661
+test clock-29.779 {time parsing} {
+ clock scan {2440588 xi:01:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 39661
+test clock-29.780 {time parsing} {
+ clock scan {2440588 xi:i:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 39661
+test clock-29.781 {time parsing} {
+ clock scan {2440588 11:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 39719
+test clock-29.782 {time parsing} {
+ clock scan {2440588 11:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 39719
+test clock-29.783 {time parsing} {
+ clock scan {2440588 11:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 39719
+test clock-29.784 {time parsing} {
+ clock scan {2440588 11:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 39719
+test clock-29.785 {time parsing} {
+ clock scan {2440588 xi:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 39719
+test clock-29.786 {time parsing} {
+ clock scan {2440588 xi:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 39719
+test clock-29.787 {time parsing} {
+ clock scan {2440588 xi:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 39719
+test clock-29.788 {time parsing} {
+ clock scan {2440588 xi:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 39719
+test clock-29.789 {time parsing} {
+ clock scan {2440588 11:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 39719
+test clock-29.790 {time parsing} {
+ clock scan {2440588 11:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 39719
+test clock-29.791 {time parsing} {
+ clock scan {2440588 11:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 39719
+test clock-29.792 {time parsing} {
+ clock scan {2440588 11:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 39719
+test clock-29.793 {time parsing} {
+ clock scan {2440588 xi:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 39719
+test clock-29.794 {time parsing} {
+ clock scan {2440588 xi:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 39719
+test clock-29.795 {time parsing} {
+ clock scan {2440588 xi:01:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 39719
+test clock-29.796 {time parsing} {
+ clock scan {2440588 xi:i:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 39719
+test clock-29.797 {time parsing} {
+ clock scan {2440588 11:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 39719
+test clock-29.798 {time parsing} {
+ clock scan {2440588 11:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 39719
+test clock-29.799 {time parsing} {
+ clock scan {2440588 11:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 39719
+test clock-29.800 {time parsing} {
+ clock scan {2440588 11:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 39719
+test clock-29.801 {time parsing} {
+ clock scan {2440588 xi:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 39719
+test clock-29.802 {time parsing} {
+ clock scan {2440588 xi:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 39719
+test clock-29.803 {time parsing} {
+ clock scan {2440588 xi:01:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 39719
+test clock-29.804 {time parsing} {
+ clock scan {2440588 xi:i:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 39719
+test clock-29.805 {time parsing} {
+ clock scan {2440588 11:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 43140
+test clock-29.806 {time parsing} {
+ clock scan {2440588 11:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 43140
+test clock-29.807 {time parsing} {
+ clock scan {2440588 11:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43140
+test clock-29.808 {time parsing} {
+ clock scan {2440588 11:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43140
+test clock-29.809 {time parsing} {
+ clock scan {2440588 11:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 43140
+test clock-29.810 {time parsing} {
+ clock scan {2440588 11:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 43140
+test clock-29.811 {time parsing} {
+ clock scan {2440588 11:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43140
+test clock-29.812 {time parsing} {
+ clock scan {2440588 11:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43140
+test clock-29.813 {time parsing} {
+ clock scan {2440588 xi:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 43140
+test clock-29.814 {time parsing} {
+ clock scan {2440588 xi:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 43140
+test clock-29.815 {time parsing} {
+ clock scan {2440588 xi:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43140
+test clock-29.816 {time parsing} {
+ clock scan {2440588 xi:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43140
+test clock-29.817 {time parsing} {
+ clock scan {2440588 xi:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 43140
+test clock-29.818 {time parsing} {
+ clock scan {2440588 xi:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 43140
+test clock-29.819 {time parsing} {
+ clock scan {2440588 xi:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43140
+test clock-29.820 {time parsing} {
+ clock scan {2440588 xi:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43140
+test clock-29.821 {time parsing} {
+ clock scan {2440588 11:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 43140
+test clock-29.822 {time parsing} {
+ clock scan {2440588 11:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 43140
+test clock-29.823 {time parsing} {
+ clock scan {2440588 11:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43140
+test clock-29.824 {time parsing} {
+ clock scan {2440588 11:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43140
+test clock-29.825 {time parsing} {
+ clock scan {2440588 11:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 43140
+test clock-29.826 {time parsing} {
+ clock scan {2440588 11:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 43140
+test clock-29.827 {time parsing} {
+ clock scan {2440588 11:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43140
+test clock-29.828 {time parsing} {
+ clock scan {2440588 11:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43140
+test clock-29.829 {time parsing} {
+ clock scan {2440588 xi:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 43140
+test clock-29.830 {time parsing} {
+ clock scan {2440588 xi:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 43140
+test clock-29.831 {time parsing} {
+ clock scan {2440588 xi:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43140
+test clock-29.832 {time parsing} {
+ clock scan {2440588 xi:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43140
+test clock-29.833 {time parsing} {
+ clock scan {2440588 xi:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 43140
+test clock-29.834 {time parsing} {
+ clock scan {2440588 xi:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 43140
+test clock-29.835 {time parsing} {
+ clock scan {2440588 xi:59:00 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43140
+test clock-29.836 {time parsing} {
+ clock scan {2440588 xi:lix:? AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43140
+test clock-29.837 {time parsing} {
+ clock scan {2440588 11:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 43140
+test clock-29.838 {time parsing} {
+ clock scan {2440588 11:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 43140
+test clock-29.839 {time parsing} {
+ clock scan {2440588 11:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43140
+test clock-29.840 {time parsing} {
+ clock scan {2440588 11:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43140
+test clock-29.841 {time parsing} {
+ clock scan {2440588 11:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 43140
+test clock-29.842 {time parsing} {
+ clock scan {2440588 11:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 43140
+test clock-29.843 {time parsing} {
+ clock scan {2440588 11:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43140
+test clock-29.844 {time parsing} {
+ clock scan {2440588 11:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43140
+test clock-29.845 {time parsing} {
+ clock scan {2440588 xi:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 43140
+test clock-29.846 {time parsing} {
+ clock scan {2440588 xi:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 43140
+test clock-29.847 {time parsing} {
+ clock scan {2440588 xi:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43140
+test clock-29.848 {time parsing} {
+ clock scan {2440588 xi:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43140
+test clock-29.849 {time parsing} {
+ clock scan {2440588 xi:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 43140
+test clock-29.850 {time parsing} {
+ clock scan {2440588 xi:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 43140
+test clock-29.851 {time parsing} {
+ clock scan {2440588 xi:59:00 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43140
+test clock-29.852 {time parsing} {
+ clock scan {2440588 xi:lix:? am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43140
+test clock-29.853 {time parsing} {
+ clock scan {2440588 11:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43141
+test clock-29.854 {time parsing} {
+ clock scan {2440588 11:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43141
+test clock-29.855 {time parsing} {
+ clock scan {2440588 11:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43141
+test clock-29.856 {time parsing} {
+ clock scan {2440588 11:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43141
+test clock-29.857 {time parsing} {
+ clock scan {2440588 xi:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43141
+test clock-29.858 {time parsing} {
+ clock scan {2440588 xi:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43141
+test clock-29.859 {time parsing} {
+ clock scan {2440588 xi:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43141
+test clock-29.860 {time parsing} {
+ clock scan {2440588 xi:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43141
+test clock-29.861 {time parsing} {
+ clock scan {2440588 11:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43141
+test clock-29.862 {time parsing} {
+ clock scan {2440588 11:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43141
+test clock-29.863 {time parsing} {
+ clock scan {2440588 11:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43141
+test clock-29.864 {time parsing} {
+ clock scan {2440588 11:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43141
+test clock-29.865 {time parsing} {
+ clock scan {2440588 xi:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43141
+test clock-29.866 {time parsing} {
+ clock scan {2440588 xi:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43141
+test clock-29.867 {time parsing} {
+ clock scan {2440588 xi:59:01 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43141
+test clock-29.868 {time parsing} {
+ clock scan {2440588 xi:lix:i AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43141
+test clock-29.869 {time parsing} {
+ clock scan {2440588 11:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43141
+test clock-29.870 {time parsing} {
+ clock scan {2440588 11:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43141
+test clock-29.871 {time parsing} {
+ clock scan {2440588 11:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43141
+test clock-29.872 {time parsing} {
+ clock scan {2440588 11:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43141
+test clock-29.873 {time parsing} {
+ clock scan {2440588 xi:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43141
+test clock-29.874 {time parsing} {
+ clock scan {2440588 xi:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43141
+test clock-29.875 {time parsing} {
+ clock scan {2440588 xi:59:01 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43141
+test clock-29.876 {time parsing} {
+ clock scan {2440588 xi:lix:i am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43141
+test clock-29.877 {time parsing} {
+ clock scan {2440588 11:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43199
+test clock-29.878 {time parsing} {
+ clock scan {2440588 11:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43199
+test clock-29.879 {time parsing} {
+ clock scan {2440588 11:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43199
+test clock-29.880 {time parsing} {
+ clock scan {2440588 11:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43199
+test clock-29.881 {time parsing} {
+ clock scan {2440588 xi:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43199
+test clock-29.882 {time parsing} {
+ clock scan {2440588 xi:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43199
+test clock-29.883 {time parsing} {
+ clock scan {2440588 xi:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43199
+test clock-29.884 {time parsing} {
+ clock scan {2440588 xi:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43199
+test clock-29.885 {time parsing} {
+ clock scan {2440588 11:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43199
+test clock-29.886 {time parsing} {
+ clock scan {2440588 11:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43199
+test clock-29.887 {time parsing} {
+ clock scan {2440588 11:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43199
+test clock-29.888 {time parsing} {
+ clock scan {2440588 11:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43199
+test clock-29.889 {time parsing} {
+ clock scan {2440588 xi:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43199
+test clock-29.890 {time parsing} {
+ clock scan {2440588 xi:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43199
+test clock-29.891 {time parsing} {
+ clock scan {2440588 xi:59:59 AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43199
+test clock-29.892 {time parsing} {
+ clock scan {2440588 xi:lix:lix AM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43199
+test clock-29.893 {time parsing} {
+ clock scan {2440588 11:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43199
+test clock-29.894 {time parsing} {
+ clock scan {2440588 11:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43199
+test clock-29.895 {time parsing} {
+ clock scan {2440588 11:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43199
+test clock-29.896 {time parsing} {
+ clock scan {2440588 11:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43199
+test clock-29.897 {time parsing} {
+ clock scan {2440588 xi:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43199
+test clock-29.898 {time parsing} {
+ clock scan {2440588 xi:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43199
+test clock-29.899 {time parsing} {
+ clock scan {2440588 xi:59:59 am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43199
+test clock-29.900 {time parsing} {
+ clock scan {2440588 xi:lix:lix am} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43199
+test clock-29.901 {time parsing} {
+ clock scan {2440588 12 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H }
+} 43200
+test clock-29.902 {time parsing} {
+ clock scan {2440588 12:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 43200
+test clock-29.903 {time parsing} {
+ clock scan {2440588 12:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 43200
+test clock-29.904 {time parsing} {
+ clock scan {2440588 12:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43200
+test clock-29.905 {time parsing} {
+ clock scan {2440588 12:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43200
+test clock-29.906 {time parsing} {
+ clock scan {2440588 12 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k }
+} 43200
+test clock-29.907 {time parsing} {
+ clock scan {2440588 12:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 43200
+test clock-29.908 {time parsing} {
+ clock scan {2440588 12:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 43200
+test clock-29.909 {time parsing} {
+ clock scan {2440588 12:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43200
+test clock-29.910 {time parsing} {
+ clock scan {2440588 12:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43200
+test clock-29.911 {time parsing} {
+ clock scan {2440588 xii } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH }
+} 43200
+test clock-29.912 {time parsing} {
+ clock scan {2440588 xii:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 43200
+test clock-29.913 {time parsing} {
+ clock scan {2440588 xii:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 43200
+test clock-29.914 {time parsing} {
+ clock scan {2440588 xii:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43200
+test clock-29.915 {time parsing} {
+ clock scan {2440588 xii:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43200
+test clock-29.916 {time parsing} {
+ clock scan {2440588 xii } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok }
+} 43200
+test clock-29.917 {time parsing} {
+ clock scan {2440588 xii:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 43200
+test clock-29.918 {time parsing} {
+ clock scan {2440588 xii:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 43200
+test clock-29.919 {time parsing} {
+ clock scan {2440588 xii:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43200
+test clock-29.920 {time parsing} {
+ clock scan {2440588 xii:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43200
+test clock-29.921 {time parsing} {
+ clock scan {2440588 12 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %p}
+} 43200
+test clock-29.922 {time parsing} {
+ clock scan {2440588 12:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 43200
+test clock-29.923 {time parsing} {
+ clock scan {2440588 12:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 43200
+test clock-29.924 {time parsing} {
+ clock scan {2440588 12:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43200
+test clock-29.925 {time parsing} {
+ clock scan {2440588 12:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43200
+test clock-29.926 {time parsing} {
+ clock scan {2440588 12 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %p}
+} 43200
+test clock-29.927 {time parsing} {
+ clock scan {2440588 12:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 43200
+test clock-29.928 {time parsing} {
+ clock scan {2440588 12:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 43200
+test clock-29.929 {time parsing} {
+ clock scan {2440588 12:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43200
+test clock-29.930 {time parsing} {
+ clock scan {2440588 12:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43200
+test clock-29.931 {time parsing} {
+ clock scan {2440588 xii PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %p}
+} 43200
+test clock-29.932 {time parsing} {
+ clock scan {2440588 xii:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 43200
+test clock-29.933 {time parsing} {
+ clock scan {2440588 xii:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 43200
+test clock-29.934 {time parsing} {
+ clock scan {2440588 xii:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43200
+test clock-29.935 {time parsing} {
+ clock scan {2440588 xii:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43200
+test clock-29.936 {time parsing} {
+ clock scan {2440588 xii PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %p}
+} 43200
+test clock-29.937 {time parsing} {
+ clock scan {2440588 xii:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 43200
+test clock-29.938 {time parsing} {
+ clock scan {2440588 xii:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 43200
+test clock-29.939 {time parsing} {
+ clock scan {2440588 xii:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43200
+test clock-29.940 {time parsing} {
+ clock scan {2440588 xii:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43200
+test clock-29.941 {time parsing} {
+ clock scan {2440588 12 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %P}
+} 43200
+test clock-29.942 {time parsing} {
+ clock scan {2440588 12:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 43200
+test clock-29.943 {time parsing} {
+ clock scan {2440588 12:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 43200
+test clock-29.944 {time parsing} {
+ clock scan {2440588 12:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43200
+test clock-29.945 {time parsing} {
+ clock scan {2440588 12:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43200
+test clock-29.946 {time parsing} {
+ clock scan {2440588 12 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %P}
+} 43200
+test clock-29.947 {time parsing} {
+ clock scan {2440588 12:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 43200
+test clock-29.948 {time parsing} {
+ clock scan {2440588 12:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 43200
+test clock-29.949 {time parsing} {
+ clock scan {2440588 12:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43200
+test clock-29.950 {time parsing} {
+ clock scan {2440588 12:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43200
+test clock-29.951 {time parsing} {
+ clock scan {2440588 xii pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %P}
+} 43200
+test clock-29.952 {time parsing} {
+ clock scan {2440588 xii:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 43200
+test clock-29.953 {time parsing} {
+ clock scan {2440588 xii:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 43200
+test clock-29.954 {time parsing} {
+ clock scan {2440588 xii:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43200
+test clock-29.955 {time parsing} {
+ clock scan {2440588 xii:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43200
+test clock-29.956 {time parsing} {
+ clock scan {2440588 xii pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %P}
+} 43200
+test clock-29.957 {time parsing} {
+ clock scan {2440588 xii:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 43200
+test clock-29.958 {time parsing} {
+ clock scan {2440588 xii:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 43200
+test clock-29.959 {time parsing} {
+ clock scan {2440588 xii:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43200
+test clock-29.960 {time parsing} {
+ clock scan {2440588 xii:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43200
+test clock-29.961 {time parsing} {
+ clock scan {2440588 12:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43201
+test clock-29.962 {time parsing} {
+ clock scan {2440588 12:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43201
+test clock-29.963 {time parsing} {
+ clock scan {2440588 12:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43201
+test clock-29.964 {time parsing} {
+ clock scan {2440588 12:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43201
+test clock-29.965 {time parsing} {
+ clock scan {2440588 xii:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43201
+test clock-29.966 {time parsing} {
+ clock scan {2440588 xii:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43201
+test clock-29.967 {time parsing} {
+ clock scan {2440588 xii:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43201
+test clock-29.968 {time parsing} {
+ clock scan {2440588 xii:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43201
+test clock-29.969 {time parsing} {
+ clock scan {2440588 12:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43201
+test clock-29.970 {time parsing} {
+ clock scan {2440588 12:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43201
+test clock-29.971 {time parsing} {
+ clock scan {2440588 12:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43201
+test clock-29.972 {time parsing} {
+ clock scan {2440588 12:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43201
+test clock-29.973 {time parsing} {
+ clock scan {2440588 xii:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43201
+test clock-29.974 {time parsing} {
+ clock scan {2440588 xii:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43201
+test clock-29.975 {time parsing} {
+ clock scan {2440588 xii:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43201
+test clock-29.976 {time parsing} {
+ clock scan {2440588 xii:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43201
+test clock-29.977 {time parsing} {
+ clock scan {2440588 12:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43201
+test clock-29.978 {time parsing} {
+ clock scan {2440588 12:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43201
+test clock-29.979 {time parsing} {
+ clock scan {2440588 12:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43201
+test clock-29.980 {time parsing} {
+ clock scan {2440588 12:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43201
+test clock-29.981 {time parsing} {
+ clock scan {2440588 xii:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43201
+test clock-29.982 {time parsing} {
+ clock scan {2440588 xii:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43201
+test clock-29.983 {time parsing} {
+ clock scan {2440588 xii:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43201
+test clock-29.984 {time parsing} {
+ clock scan {2440588 xii:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43201
+test clock-29.985 {time parsing} {
+ clock scan {2440588 12:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43259
+test clock-29.986 {time parsing} {
+ clock scan {2440588 12:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43259
+test clock-29.987 {time parsing} {
+ clock scan {2440588 12:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43259
+test clock-29.988 {time parsing} {
+ clock scan {2440588 12:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43259
+test clock-29.989 {time parsing} {
+ clock scan {2440588 xii:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43259
+test clock-29.990 {time parsing} {
+ clock scan {2440588 xii:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43259
+test clock-29.991 {time parsing} {
+ clock scan {2440588 xii:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43259
+test clock-29.992 {time parsing} {
+ clock scan {2440588 xii:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43259
+test clock-29.993 {time parsing} {
+ clock scan {2440588 12:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43259
+test clock-29.994 {time parsing} {
+ clock scan {2440588 12:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43259
+test clock-29.995 {time parsing} {
+ clock scan {2440588 12:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43259
+test clock-29.996 {time parsing} {
+ clock scan {2440588 12:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43259
+test clock-29.997 {time parsing} {
+ clock scan {2440588 xii:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43259
+test clock-29.998 {time parsing} {
+ clock scan {2440588 xii:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43259
+test clock-29.999 {time parsing} {
+ clock scan {2440588 xii:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43259
+test clock-29.1000 {time parsing} {
+ clock scan {2440588 xii:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43259
+test clock-29.1001 {time parsing} {
+ clock scan {2440588 12:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43259
+test clock-29.1002 {time parsing} {
+ clock scan {2440588 12:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43259
+test clock-29.1003 {time parsing} {
+ clock scan {2440588 12:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43259
+test clock-29.1004 {time parsing} {
+ clock scan {2440588 12:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43259
+test clock-29.1005 {time parsing} {
+ clock scan {2440588 xii:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43259
+test clock-29.1006 {time parsing} {
+ clock scan {2440588 xii:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43259
+test clock-29.1007 {time parsing} {
+ clock scan {2440588 xii:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43259
+test clock-29.1008 {time parsing} {
+ clock scan {2440588 xii:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43259
+test clock-29.1009 {time parsing} {
+ clock scan {2440588 12:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 43260
+test clock-29.1010 {time parsing} {
+ clock scan {2440588 12:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 43260
+test clock-29.1011 {time parsing} {
+ clock scan {2440588 12:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43260
+test clock-29.1012 {time parsing} {
+ clock scan {2440588 12:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43260
+test clock-29.1013 {time parsing} {
+ clock scan {2440588 12:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 43260
+test clock-29.1014 {time parsing} {
+ clock scan {2440588 12:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 43260
+test clock-29.1015 {time parsing} {
+ clock scan {2440588 12:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43260
+test clock-29.1016 {time parsing} {
+ clock scan {2440588 12:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43260
+test clock-29.1017 {time parsing} {
+ clock scan {2440588 xii:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 43260
+test clock-29.1018 {time parsing} {
+ clock scan {2440588 xii:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 43260
+test clock-29.1019 {time parsing} {
+ clock scan {2440588 xii:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43260
+test clock-29.1020 {time parsing} {
+ clock scan {2440588 xii:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43260
+test clock-29.1021 {time parsing} {
+ clock scan {2440588 xii:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 43260
+test clock-29.1022 {time parsing} {
+ clock scan {2440588 xii:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 43260
+test clock-29.1023 {time parsing} {
+ clock scan {2440588 xii:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43260
+test clock-29.1024 {time parsing} {
+ clock scan {2440588 xii:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43260
+test clock-29.1025 {time parsing} {
+ clock scan {2440588 12:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 43260
+test clock-29.1026 {time parsing} {
+ clock scan {2440588 12:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 43260
+test clock-29.1027 {time parsing} {
+ clock scan {2440588 12:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43260
+test clock-29.1028 {time parsing} {
+ clock scan {2440588 12:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43260
+test clock-29.1029 {time parsing} {
+ clock scan {2440588 12:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 43260
+test clock-29.1030 {time parsing} {
+ clock scan {2440588 12:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 43260
+test clock-29.1031 {time parsing} {
+ clock scan {2440588 12:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43260
+test clock-29.1032 {time parsing} {
+ clock scan {2440588 12:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43260
+test clock-29.1033 {time parsing} {
+ clock scan {2440588 xii:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 43260
+test clock-29.1034 {time parsing} {
+ clock scan {2440588 xii:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 43260
+test clock-29.1035 {time parsing} {
+ clock scan {2440588 xii:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43260
+test clock-29.1036 {time parsing} {
+ clock scan {2440588 xii:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43260
+test clock-29.1037 {time parsing} {
+ clock scan {2440588 xii:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 43260
+test clock-29.1038 {time parsing} {
+ clock scan {2440588 xii:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 43260
+test clock-29.1039 {time parsing} {
+ clock scan {2440588 xii:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43260
+test clock-29.1040 {time parsing} {
+ clock scan {2440588 xii:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43260
+test clock-29.1041 {time parsing} {
+ clock scan {2440588 12:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 43260
+test clock-29.1042 {time parsing} {
+ clock scan {2440588 12:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 43260
+test clock-29.1043 {time parsing} {
+ clock scan {2440588 12:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43260
+test clock-29.1044 {time parsing} {
+ clock scan {2440588 12:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43260
+test clock-29.1045 {time parsing} {
+ clock scan {2440588 12:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 43260
+test clock-29.1046 {time parsing} {
+ clock scan {2440588 12:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 43260
+test clock-29.1047 {time parsing} {
+ clock scan {2440588 12:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43260
+test clock-29.1048 {time parsing} {
+ clock scan {2440588 12:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43260
+test clock-29.1049 {time parsing} {
+ clock scan {2440588 xii:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 43260
+test clock-29.1050 {time parsing} {
+ clock scan {2440588 xii:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 43260
+test clock-29.1051 {time parsing} {
+ clock scan {2440588 xii:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43260
+test clock-29.1052 {time parsing} {
+ clock scan {2440588 xii:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43260
+test clock-29.1053 {time parsing} {
+ clock scan {2440588 xii:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 43260
+test clock-29.1054 {time parsing} {
+ clock scan {2440588 xii:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 43260
+test clock-29.1055 {time parsing} {
+ clock scan {2440588 xii:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43260
+test clock-29.1056 {time parsing} {
+ clock scan {2440588 xii:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43260
+test clock-29.1057 {time parsing} {
+ clock scan {2440588 12:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43261
+test clock-29.1058 {time parsing} {
+ clock scan {2440588 12:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43261
+test clock-29.1059 {time parsing} {
+ clock scan {2440588 12:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43261
+test clock-29.1060 {time parsing} {
+ clock scan {2440588 12:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43261
+test clock-29.1061 {time parsing} {
+ clock scan {2440588 xii:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43261
+test clock-29.1062 {time parsing} {
+ clock scan {2440588 xii:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43261
+test clock-29.1063 {time parsing} {
+ clock scan {2440588 xii:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43261
+test clock-29.1064 {time parsing} {
+ clock scan {2440588 xii:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43261
+test clock-29.1065 {time parsing} {
+ clock scan {2440588 12:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43261
+test clock-29.1066 {time parsing} {
+ clock scan {2440588 12:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43261
+test clock-29.1067 {time parsing} {
+ clock scan {2440588 12:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43261
+test clock-29.1068 {time parsing} {
+ clock scan {2440588 12:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43261
+test clock-29.1069 {time parsing} {
+ clock scan {2440588 xii:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43261
+test clock-29.1070 {time parsing} {
+ clock scan {2440588 xii:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43261
+test clock-29.1071 {time parsing} {
+ clock scan {2440588 xii:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43261
+test clock-29.1072 {time parsing} {
+ clock scan {2440588 xii:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43261
+test clock-29.1073 {time parsing} {
+ clock scan {2440588 12:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43261
+test clock-29.1074 {time parsing} {
+ clock scan {2440588 12:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43261
+test clock-29.1075 {time parsing} {
+ clock scan {2440588 12:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43261
+test clock-29.1076 {time parsing} {
+ clock scan {2440588 12:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43261
+test clock-29.1077 {time parsing} {
+ clock scan {2440588 xii:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43261
+test clock-29.1078 {time parsing} {
+ clock scan {2440588 xii:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43261
+test clock-29.1079 {time parsing} {
+ clock scan {2440588 xii:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43261
+test clock-29.1080 {time parsing} {
+ clock scan {2440588 xii:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43261
+test clock-29.1081 {time parsing} {
+ clock scan {2440588 12:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 43319
+test clock-29.1082 {time parsing} {
+ clock scan {2440588 12:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 43319
+test clock-29.1083 {time parsing} {
+ clock scan {2440588 12:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 43319
+test clock-29.1084 {time parsing} {
+ clock scan {2440588 12:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 43319
+test clock-29.1085 {time parsing} {
+ clock scan {2440588 xii:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 43319
+test clock-29.1086 {time parsing} {
+ clock scan {2440588 xii:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 43319
+test clock-29.1087 {time parsing} {
+ clock scan {2440588 xii:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 43319
+test clock-29.1088 {time parsing} {
+ clock scan {2440588 xii:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 43319
+test clock-29.1089 {time parsing} {
+ clock scan {2440588 12:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 43319
+test clock-29.1090 {time parsing} {
+ clock scan {2440588 12:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 43319
+test clock-29.1091 {time parsing} {
+ clock scan {2440588 12:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 43319
+test clock-29.1092 {time parsing} {
+ clock scan {2440588 12:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 43319
+test clock-29.1093 {time parsing} {
+ clock scan {2440588 xii:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 43319
+test clock-29.1094 {time parsing} {
+ clock scan {2440588 xii:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 43319
+test clock-29.1095 {time parsing} {
+ clock scan {2440588 xii:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 43319
+test clock-29.1096 {time parsing} {
+ clock scan {2440588 xii:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 43319
+test clock-29.1097 {time parsing} {
+ clock scan {2440588 12:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 43319
+test clock-29.1098 {time parsing} {
+ clock scan {2440588 12:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 43319
+test clock-29.1099 {time parsing} {
+ clock scan {2440588 12:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 43319
+test clock-29.1100 {time parsing} {
+ clock scan {2440588 12:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 43319
+test clock-29.1101 {time parsing} {
+ clock scan {2440588 xii:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 43319
+test clock-29.1102 {time parsing} {
+ clock scan {2440588 xii:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 43319
+test clock-29.1103 {time parsing} {
+ clock scan {2440588 xii:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 43319
+test clock-29.1104 {time parsing} {
+ clock scan {2440588 xii:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 43319
+test clock-29.1105 {time parsing} {
+ clock scan {2440588 12:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 46740
+test clock-29.1106 {time parsing} {
+ clock scan {2440588 12:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 46740
+test clock-29.1107 {time parsing} {
+ clock scan {2440588 12:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46740
+test clock-29.1108 {time parsing} {
+ clock scan {2440588 12:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46740
+test clock-29.1109 {time parsing} {
+ clock scan {2440588 12:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 46740
+test clock-29.1110 {time parsing} {
+ clock scan {2440588 12:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 46740
+test clock-29.1111 {time parsing} {
+ clock scan {2440588 12:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46740
+test clock-29.1112 {time parsing} {
+ clock scan {2440588 12:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46740
+test clock-29.1113 {time parsing} {
+ clock scan {2440588 xii:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 46740
+test clock-29.1114 {time parsing} {
+ clock scan {2440588 xii:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 46740
+test clock-29.1115 {time parsing} {
+ clock scan {2440588 xii:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46740
+test clock-29.1116 {time parsing} {
+ clock scan {2440588 xii:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46740
+test clock-29.1117 {time parsing} {
+ clock scan {2440588 xii:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 46740
+test clock-29.1118 {time parsing} {
+ clock scan {2440588 xii:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 46740
+test clock-29.1119 {time parsing} {
+ clock scan {2440588 xii:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46740
+test clock-29.1120 {time parsing} {
+ clock scan {2440588 xii:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46740
+test clock-29.1121 {time parsing} {
+ clock scan {2440588 12:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 46740
+test clock-29.1122 {time parsing} {
+ clock scan {2440588 12:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 46740
+test clock-29.1123 {time parsing} {
+ clock scan {2440588 12:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46740
+test clock-29.1124 {time parsing} {
+ clock scan {2440588 12:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46740
+test clock-29.1125 {time parsing} {
+ clock scan {2440588 12:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 46740
+test clock-29.1126 {time parsing} {
+ clock scan {2440588 12:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 46740
+test clock-29.1127 {time parsing} {
+ clock scan {2440588 12:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46740
+test clock-29.1128 {time parsing} {
+ clock scan {2440588 12:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46740
+test clock-29.1129 {time parsing} {
+ clock scan {2440588 xii:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 46740
+test clock-29.1130 {time parsing} {
+ clock scan {2440588 xii:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 46740
+test clock-29.1131 {time parsing} {
+ clock scan {2440588 xii:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46740
+test clock-29.1132 {time parsing} {
+ clock scan {2440588 xii:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46740
+test clock-29.1133 {time parsing} {
+ clock scan {2440588 xii:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 46740
+test clock-29.1134 {time parsing} {
+ clock scan {2440588 xii:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 46740
+test clock-29.1135 {time parsing} {
+ clock scan {2440588 xii:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46740
+test clock-29.1136 {time parsing} {
+ clock scan {2440588 xii:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46740
+test clock-29.1137 {time parsing} {
+ clock scan {2440588 12:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 46740
+test clock-29.1138 {time parsing} {
+ clock scan {2440588 12:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 46740
+test clock-29.1139 {time parsing} {
+ clock scan {2440588 12:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46740
+test clock-29.1140 {time parsing} {
+ clock scan {2440588 12:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46740
+test clock-29.1141 {time parsing} {
+ clock scan {2440588 12:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 46740
+test clock-29.1142 {time parsing} {
+ clock scan {2440588 12:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 46740
+test clock-29.1143 {time parsing} {
+ clock scan {2440588 12:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46740
+test clock-29.1144 {time parsing} {
+ clock scan {2440588 12:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46740
+test clock-29.1145 {time parsing} {
+ clock scan {2440588 xii:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 46740
+test clock-29.1146 {time parsing} {
+ clock scan {2440588 xii:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 46740
+test clock-29.1147 {time parsing} {
+ clock scan {2440588 xii:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46740
+test clock-29.1148 {time parsing} {
+ clock scan {2440588 xii:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46740
+test clock-29.1149 {time parsing} {
+ clock scan {2440588 xii:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 46740
+test clock-29.1150 {time parsing} {
+ clock scan {2440588 xii:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 46740
+test clock-29.1151 {time parsing} {
+ clock scan {2440588 xii:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46740
+test clock-29.1152 {time parsing} {
+ clock scan {2440588 xii:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46740
+test clock-29.1153 {time parsing} {
+ clock scan {2440588 12:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46741
+test clock-29.1154 {time parsing} {
+ clock scan {2440588 12:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46741
+test clock-29.1155 {time parsing} {
+ clock scan {2440588 12:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46741
+test clock-29.1156 {time parsing} {
+ clock scan {2440588 12:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46741
+test clock-29.1157 {time parsing} {
+ clock scan {2440588 xii:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46741
+test clock-29.1158 {time parsing} {
+ clock scan {2440588 xii:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46741
+test clock-29.1159 {time parsing} {
+ clock scan {2440588 xii:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46741
+test clock-29.1160 {time parsing} {
+ clock scan {2440588 xii:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46741
+test clock-29.1161 {time parsing} {
+ clock scan {2440588 12:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46741
+test clock-29.1162 {time parsing} {
+ clock scan {2440588 12:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46741
+test clock-29.1163 {time parsing} {
+ clock scan {2440588 12:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46741
+test clock-29.1164 {time parsing} {
+ clock scan {2440588 12:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46741
+test clock-29.1165 {time parsing} {
+ clock scan {2440588 xii:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46741
+test clock-29.1166 {time parsing} {
+ clock scan {2440588 xii:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46741
+test clock-29.1167 {time parsing} {
+ clock scan {2440588 xii:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46741
+test clock-29.1168 {time parsing} {
+ clock scan {2440588 xii:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46741
+test clock-29.1169 {time parsing} {
+ clock scan {2440588 12:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46741
+test clock-29.1170 {time parsing} {
+ clock scan {2440588 12:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46741
+test clock-29.1171 {time parsing} {
+ clock scan {2440588 12:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46741
+test clock-29.1172 {time parsing} {
+ clock scan {2440588 12:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46741
+test clock-29.1173 {time parsing} {
+ clock scan {2440588 xii:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46741
+test clock-29.1174 {time parsing} {
+ clock scan {2440588 xii:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46741
+test clock-29.1175 {time parsing} {
+ clock scan {2440588 xii:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46741
+test clock-29.1176 {time parsing} {
+ clock scan {2440588 xii:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46741
+test clock-29.1177 {time parsing} {
+ clock scan {2440588 12:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46799
+test clock-29.1178 {time parsing} {
+ clock scan {2440588 12:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46799
+test clock-29.1179 {time parsing} {
+ clock scan {2440588 12:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46799
+test clock-29.1180 {time parsing} {
+ clock scan {2440588 12:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46799
+test clock-29.1181 {time parsing} {
+ clock scan {2440588 xii:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46799
+test clock-29.1182 {time parsing} {
+ clock scan {2440588 xii:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46799
+test clock-29.1183 {time parsing} {
+ clock scan {2440588 xii:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46799
+test clock-29.1184 {time parsing} {
+ clock scan {2440588 xii:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46799
+test clock-29.1185 {time parsing} {
+ clock scan {2440588 12:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46799
+test clock-29.1186 {time parsing} {
+ clock scan {2440588 12:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46799
+test clock-29.1187 {time parsing} {
+ clock scan {2440588 12:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46799
+test clock-29.1188 {time parsing} {
+ clock scan {2440588 12:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46799
+test clock-29.1189 {time parsing} {
+ clock scan {2440588 xii:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46799
+test clock-29.1190 {time parsing} {
+ clock scan {2440588 xii:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46799
+test clock-29.1191 {time parsing} {
+ clock scan {2440588 xii:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46799
+test clock-29.1192 {time parsing} {
+ clock scan {2440588 xii:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46799
+test clock-29.1193 {time parsing} {
+ clock scan {2440588 12:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46799
+test clock-29.1194 {time parsing} {
+ clock scan {2440588 12:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46799
+test clock-29.1195 {time parsing} {
+ clock scan {2440588 12:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46799
+test clock-29.1196 {time parsing} {
+ clock scan {2440588 12:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46799
+test clock-29.1197 {time parsing} {
+ clock scan {2440588 xii:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46799
+test clock-29.1198 {time parsing} {
+ clock scan {2440588 xii:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46799
+test clock-29.1199 {time parsing} {
+ clock scan {2440588 xii:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46799
+test clock-29.1200 {time parsing} {
+ clock scan {2440588 xii:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46799
+test clock-29.1201 {time parsing} {
+ clock scan {2440588 13 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H }
+} 46800
+test clock-29.1202 {time parsing} {
+ clock scan {2440588 13:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 46800
+test clock-29.1203 {time parsing} {
+ clock scan {2440588 13:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 46800
+test clock-29.1204 {time parsing} {
+ clock scan {2440588 13:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46800
+test clock-29.1205 {time parsing} {
+ clock scan {2440588 13:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46800
+test clock-29.1206 {time parsing} {
+ clock scan {2440588 13 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k }
+} 46800
+test clock-29.1207 {time parsing} {
+ clock scan {2440588 13:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 46800
+test clock-29.1208 {time parsing} {
+ clock scan {2440588 13:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 46800
+test clock-29.1209 {time parsing} {
+ clock scan {2440588 13:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46800
+test clock-29.1210 {time parsing} {
+ clock scan {2440588 13:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46800
+test clock-29.1211 {time parsing} {
+ clock scan {2440588 xiii } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH }
+} 46800
+test clock-29.1212 {time parsing} {
+ clock scan {2440588 xiii:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 46800
+test clock-29.1213 {time parsing} {
+ clock scan {2440588 xiii:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 46800
+test clock-29.1214 {time parsing} {
+ clock scan {2440588 xiii:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46800
+test clock-29.1215 {time parsing} {
+ clock scan {2440588 xiii:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46800
+test clock-29.1216 {time parsing} {
+ clock scan {2440588 xiii } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok }
+} 46800
+test clock-29.1217 {time parsing} {
+ clock scan {2440588 xiii:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 46800
+test clock-29.1218 {time parsing} {
+ clock scan {2440588 xiii:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 46800
+test clock-29.1219 {time parsing} {
+ clock scan {2440588 xiii:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46800
+test clock-29.1220 {time parsing} {
+ clock scan {2440588 xiii:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46800
+test clock-29.1221 {time parsing} {
+ clock scan {2440588 01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %p}
+} 46800
+test clock-29.1222 {time parsing} {
+ clock scan {2440588 01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 46800
+test clock-29.1223 {time parsing} {
+ clock scan {2440588 01:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 46800
+test clock-29.1224 {time parsing} {
+ clock scan {2440588 01:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46800
+test clock-29.1225 {time parsing} {
+ clock scan {2440588 01:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46800
+test clock-29.1226 {time parsing} {
+ clock scan {2440588 1 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %p}
+} 46800
+test clock-29.1227 {time parsing} {
+ clock scan {2440588 1:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 46800
+test clock-29.1228 {time parsing} {
+ clock scan {2440588 1:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 46800
+test clock-29.1229 {time parsing} {
+ clock scan {2440588 1:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46800
+test clock-29.1230 {time parsing} {
+ clock scan {2440588 1:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46800
+test clock-29.1231 {time parsing} {
+ clock scan {2440588 i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %p}
+} 46800
+test clock-29.1232 {time parsing} {
+ clock scan {2440588 i:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 46800
+test clock-29.1233 {time parsing} {
+ clock scan {2440588 i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 46800
+test clock-29.1234 {time parsing} {
+ clock scan {2440588 i:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46800
+test clock-29.1235 {time parsing} {
+ clock scan {2440588 i:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46800
+test clock-29.1236 {time parsing} {
+ clock scan {2440588 i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %p}
+} 46800
+test clock-29.1237 {time parsing} {
+ clock scan {2440588 i:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 46800
+test clock-29.1238 {time parsing} {
+ clock scan {2440588 i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 46800
+test clock-29.1239 {time parsing} {
+ clock scan {2440588 i:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46800
+test clock-29.1240 {time parsing} {
+ clock scan {2440588 i:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46800
+test clock-29.1241 {time parsing} {
+ clock scan {2440588 01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %P}
+} 46800
+test clock-29.1242 {time parsing} {
+ clock scan {2440588 01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 46800
+test clock-29.1243 {time parsing} {
+ clock scan {2440588 01:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 46800
+test clock-29.1244 {time parsing} {
+ clock scan {2440588 01:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46800
+test clock-29.1245 {time parsing} {
+ clock scan {2440588 01:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46800
+test clock-29.1246 {time parsing} {
+ clock scan {2440588 1 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %P}
+} 46800
+test clock-29.1247 {time parsing} {
+ clock scan {2440588 1:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 46800
+test clock-29.1248 {time parsing} {
+ clock scan {2440588 1:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 46800
+test clock-29.1249 {time parsing} {
+ clock scan {2440588 1:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46800
+test clock-29.1250 {time parsing} {
+ clock scan {2440588 1:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46800
+test clock-29.1251 {time parsing} {
+ clock scan {2440588 i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %P}
+} 46800
+test clock-29.1252 {time parsing} {
+ clock scan {2440588 i:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 46800
+test clock-29.1253 {time parsing} {
+ clock scan {2440588 i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 46800
+test clock-29.1254 {time parsing} {
+ clock scan {2440588 i:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46800
+test clock-29.1255 {time parsing} {
+ clock scan {2440588 i:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46800
+test clock-29.1256 {time parsing} {
+ clock scan {2440588 i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %P}
+} 46800
+test clock-29.1257 {time parsing} {
+ clock scan {2440588 i:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 46800
+test clock-29.1258 {time parsing} {
+ clock scan {2440588 i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 46800
+test clock-29.1259 {time parsing} {
+ clock scan {2440588 i:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46800
+test clock-29.1260 {time parsing} {
+ clock scan {2440588 i:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46800
+test clock-29.1261 {time parsing} {
+ clock scan {2440588 13:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46801
+test clock-29.1262 {time parsing} {
+ clock scan {2440588 13:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46801
+test clock-29.1263 {time parsing} {
+ clock scan {2440588 13:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46801
+test clock-29.1264 {time parsing} {
+ clock scan {2440588 13:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46801
+test clock-29.1265 {time parsing} {
+ clock scan {2440588 xiii:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46801
+test clock-29.1266 {time parsing} {
+ clock scan {2440588 xiii:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46801
+test clock-29.1267 {time parsing} {
+ clock scan {2440588 xiii:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46801
+test clock-29.1268 {time parsing} {
+ clock scan {2440588 xiii:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46801
+test clock-29.1269 {time parsing} {
+ clock scan {2440588 01:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46801
+test clock-29.1270 {time parsing} {
+ clock scan {2440588 01:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46801
+test clock-29.1271 {time parsing} {
+ clock scan {2440588 1:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46801
+test clock-29.1272 {time parsing} {
+ clock scan {2440588 1:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46801
+test clock-29.1273 {time parsing} {
+ clock scan {2440588 i:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46801
+test clock-29.1274 {time parsing} {
+ clock scan {2440588 i:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46801
+test clock-29.1275 {time parsing} {
+ clock scan {2440588 i:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46801
+test clock-29.1276 {time parsing} {
+ clock scan {2440588 i:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46801
+test clock-29.1277 {time parsing} {
+ clock scan {2440588 01:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46801
+test clock-29.1278 {time parsing} {
+ clock scan {2440588 01:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46801
+test clock-29.1279 {time parsing} {
+ clock scan {2440588 1:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46801
+test clock-29.1280 {time parsing} {
+ clock scan {2440588 1:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46801
+test clock-29.1281 {time parsing} {
+ clock scan {2440588 i:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46801
+test clock-29.1282 {time parsing} {
+ clock scan {2440588 i:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46801
+test clock-29.1283 {time parsing} {
+ clock scan {2440588 i:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46801
+test clock-29.1284 {time parsing} {
+ clock scan {2440588 i:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46801
+test clock-29.1285 {time parsing} {
+ clock scan {2440588 13:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46859
+test clock-29.1286 {time parsing} {
+ clock scan {2440588 13:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46859
+test clock-29.1287 {time parsing} {
+ clock scan {2440588 13:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46859
+test clock-29.1288 {time parsing} {
+ clock scan {2440588 13:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46859
+test clock-29.1289 {time parsing} {
+ clock scan {2440588 xiii:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46859
+test clock-29.1290 {time parsing} {
+ clock scan {2440588 xiii:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46859
+test clock-29.1291 {time parsing} {
+ clock scan {2440588 xiii:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46859
+test clock-29.1292 {time parsing} {
+ clock scan {2440588 xiii:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46859
+test clock-29.1293 {time parsing} {
+ clock scan {2440588 01:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46859
+test clock-29.1294 {time parsing} {
+ clock scan {2440588 01:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46859
+test clock-29.1295 {time parsing} {
+ clock scan {2440588 1:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46859
+test clock-29.1296 {time parsing} {
+ clock scan {2440588 1:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46859
+test clock-29.1297 {time parsing} {
+ clock scan {2440588 i:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46859
+test clock-29.1298 {time parsing} {
+ clock scan {2440588 i:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46859
+test clock-29.1299 {time parsing} {
+ clock scan {2440588 i:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46859
+test clock-29.1300 {time parsing} {
+ clock scan {2440588 i:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46859
+test clock-29.1301 {time parsing} {
+ clock scan {2440588 01:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46859
+test clock-29.1302 {time parsing} {
+ clock scan {2440588 01:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46859
+test clock-29.1303 {time parsing} {
+ clock scan {2440588 1:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46859
+test clock-29.1304 {time parsing} {
+ clock scan {2440588 1:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46859
+test clock-29.1305 {time parsing} {
+ clock scan {2440588 i:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46859
+test clock-29.1306 {time parsing} {
+ clock scan {2440588 i:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46859
+test clock-29.1307 {time parsing} {
+ clock scan {2440588 i:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46859
+test clock-29.1308 {time parsing} {
+ clock scan {2440588 i:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46859
+test clock-29.1309 {time parsing} {
+ clock scan {2440588 13:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 46860
+test clock-29.1310 {time parsing} {
+ clock scan {2440588 13:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 46860
+test clock-29.1311 {time parsing} {
+ clock scan {2440588 13:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46860
+test clock-29.1312 {time parsing} {
+ clock scan {2440588 13:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46860
+test clock-29.1313 {time parsing} {
+ clock scan {2440588 13:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 46860
+test clock-29.1314 {time parsing} {
+ clock scan {2440588 13:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 46860
+test clock-29.1315 {time parsing} {
+ clock scan {2440588 13:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46860
+test clock-29.1316 {time parsing} {
+ clock scan {2440588 13:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46860
+test clock-29.1317 {time parsing} {
+ clock scan {2440588 xiii:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 46860
+test clock-29.1318 {time parsing} {
+ clock scan {2440588 xiii:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 46860
+test clock-29.1319 {time parsing} {
+ clock scan {2440588 xiii:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46860
+test clock-29.1320 {time parsing} {
+ clock scan {2440588 xiii:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46860
+test clock-29.1321 {time parsing} {
+ clock scan {2440588 xiii:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 46860
+test clock-29.1322 {time parsing} {
+ clock scan {2440588 xiii:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 46860
+test clock-29.1323 {time parsing} {
+ clock scan {2440588 xiii:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46860
+test clock-29.1324 {time parsing} {
+ clock scan {2440588 xiii:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46860
+test clock-29.1325 {time parsing} {
+ clock scan {2440588 01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 46860
+test clock-29.1326 {time parsing} {
+ clock scan {2440588 01:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 46860
+test clock-29.1327 {time parsing} {
+ clock scan {2440588 01:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46860
+test clock-29.1328 {time parsing} {
+ clock scan {2440588 01:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46860
+test clock-29.1329 {time parsing} {
+ clock scan {2440588 1:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 46860
+test clock-29.1330 {time parsing} {
+ clock scan {2440588 1:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 46860
+test clock-29.1331 {time parsing} {
+ clock scan {2440588 1:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46860
+test clock-29.1332 {time parsing} {
+ clock scan {2440588 1:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46860
+test clock-29.1333 {time parsing} {
+ clock scan {2440588 i:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 46860
+test clock-29.1334 {time parsing} {
+ clock scan {2440588 i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 46860
+test clock-29.1335 {time parsing} {
+ clock scan {2440588 i:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46860
+test clock-29.1336 {time parsing} {
+ clock scan {2440588 i:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46860
+test clock-29.1337 {time parsing} {
+ clock scan {2440588 i:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 46860
+test clock-29.1338 {time parsing} {
+ clock scan {2440588 i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 46860
+test clock-29.1339 {time parsing} {
+ clock scan {2440588 i:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46860
+test clock-29.1340 {time parsing} {
+ clock scan {2440588 i:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46860
+test clock-29.1341 {time parsing} {
+ clock scan {2440588 01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 46860
+test clock-29.1342 {time parsing} {
+ clock scan {2440588 01:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 46860
+test clock-29.1343 {time parsing} {
+ clock scan {2440588 01:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46860
+test clock-29.1344 {time parsing} {
+ clock scan {2440588 01:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46860
+test clock-29.1345 {time parsing} {
+ clock scan {2440588 1:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 46860
+test clock-29.1346 {time parsing} {
+ clock scan {2440588 1:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 46860
+test clock-29.1347 {time parsing} {
+ clock scan {2440588 1:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46860
+test clock-29.1348 {time parsing} {
+ clock scan {2440588 1:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46860
+test clock-29.1349 {time parsing} {
+ clock scan {2440588 i:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 46860
+test clock-29.1350 {time parsing} {
+ clock scan {2440588 i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 46860
+test clock-29.1351 {time parsing} {
+ clock scan {2440588 i:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46860
+test clock-29.1352 {time parsing} {
+ clock scan {2440588 i:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46860
+test clock-29.1353 {time parsing} {
+ clock scan {2440588 i:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 46860
+test clock-29.1354 {time parsing} {
+ clock scan {2440588 i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 46860
+test clock-29.1355 {time parsing} {
+ clock scan {2440588 i:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46860
+test clock-29.1356 {time parsing} {
+ clock scan {2440588 i:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46860
+test clock-29.1357 {time parsing} {
+ clock scan {2440588 13:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46861
+test clock-29.1358 {time parsing} {
+ clock scan {2440588 13:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46861
+test clock-29.1359 {time parsing} {
+ clock scan {2440588 13:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46861
+test clock-29.1360 {time parsing} {
+ clock scan {2440588 13:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46861
+test clock-29.1361 {time parsing} {
+ clock scan {2440588 xiii:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46861
+test clock-29.1362 {time parsing} {
+ clock scan {2440588 xiii:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46861
+test clock-29.1363 {time parsing} {
+ clock scan {2440588 xiii:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46861
+test clock-29.1364 {time parsing} {
+ clock scan {2440588 xiii:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46861
+test clock-29.1365 {time parsing} {
+ clock scan {2440588 01:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46861
+test clock-29.1366 {time parsing} {
+ clock scan {2440588 01:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46861
+test clock-29.1367 {time parsing} {
+ clock scan {2440588 1:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46861
+test clock-29.1368 {time parsing} {
+ clock scan {2440588 1:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46861
+test clock-29.1369 {time parsing} {
+ clock scan {2440588 i:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46861
+test clock-29.1370 {time parsing} {
+ clock scan {2440588 i:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46861
+test clock-29.1371 {time parsing} {
+ clock scan {2440588 i:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46861
+test clock-29.1372 {time parsing} {
+ clock scan {2440588 i:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46861
+test clock-29.1373 {time parsing} {
+ clock scan {2440588 01:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46861
+test clock-29.1374 {time parsing} {
+ clock scan {2440588 01:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46861
+test clock-29.1375 {time parsing} {
+ clock scan {2440588 1:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46861
+test clock-29.1376 {time parsing} {
+ clock scan {2440588 1:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46861
+test clock-29.1377 {time parsing} {
+ clock scan {2440588 i:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46861
+test clock-29.1378 {time parsing} {
+ clock scan {2440588 i:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46861
+test clock-29.1379 {time parsing} {
+ clock scan {2440588 i:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46861
+test clock-29.1380 {time parsing} {
+ clock scan {2440588 i:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46861
+test clock-29.1381 {time parsing} {
+ clock scan {2440588 13:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 46919
+test clock-29.1382 {time parsing} {
+ clock scan {2440588 13:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 46919
+test clock-29.1383 {time parsing} {
+ clock scan {2440588 13:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 46919
+test clock-29.1384 {time parsing} {
+ clock scan {2440588 13:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 46919
+test clock-29.1385 {time parsing} {
+ clock scan {2440588 xiii:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 46919
+test clock-29.1386 {time parsing} {
+ clock scan {2440588 xiii:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 46919
+test clock-29.1387 {time parsing} {
+ clock scan {2440588 xiii:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 46919
+test clock-29.1388 {time parsing} {
+ clock scan {2440588 xiii:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 46919
+test clock-29.1389 {time parsing} {
+ clock scan {2440588 01:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 46919
+test clock-29.1390 {time parsing} {
+ clock scan {2440588 01:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 46919
+test clock-29.1391 {time parsing} {
+ clock scan {2440588 1:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 46919
+test clock-29.1392 {time parsing} {
+ clock scan {2440588 1:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 46919
+test clock-29.1393 {time parsing} {
+ clock scan {2440588 i:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 46919
+test clock-29.1394 {time parsing} {
+ clock scan {2440588 i:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 46919
+test clock-29.1395 {time parsing} {
+ clock scan {2440588 i:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 46919
+test clock-29.1396 {time parsing} {
+ clock scan {2440588 i:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 46919
+test clock-29.1397 {time parsing} {
+ clock scan {2440588 01:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 46919
+test clock-29.1398 {time parsing} {
+ clock scan {2440588 01:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 46919
+test clock-29.1399 {time parsing} {
+ clock scan {2440588 1:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 46919
+test clock-29.1400 {time parsing} {
+ clock scan {2440588 1:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 46919
+test clock-29.1401 {time parsing} {
+ clock scan {2440588 i:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 46919
+test clock-29.1402 {time parsing} {
+ clock scan {2440588 i:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 46919
+test clock-29.1403 {time parsing} {
+ clock scan {2440588 i:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 46919
+test clock-29.1404 {time parsing} {
+ clock scan {2440588 i:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 46919
+test clock-29.1405 {time parsing} {
+ clock scan {2440588 13:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 50340
+test clock-29.1406 {time parsing} {
+ clock scan {2440588 13:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 50340
+test clock-29.1407 {time parsing} {
+ clock scan {2440588 13:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 50340
+test clock-29.1408 {time parsing} {
+ clock scan {2440588 13:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 50340
+test clock-29.1409 {time parsing} {
+ clock scan {2440588 13:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 50340
+test clock-29.1410 {time parsing} {
+ clock scan {2440588 13:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 50340
+test clock-29.1411 {time parsing} {
+ clock scan {2440588 13:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 50340
+test clock-29.1412 {time parsing} {
+ clock scan {2440588 13:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 50340
+test clock-29.1413 {time parsing} {
+ clock scan {2440588 xiii:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 50340
+test clock-29.1414 {time parsing} {
+ clock scan {2440588 xiii:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 50340
+test clock-29.1415 {time parsing} {
+ clock scan {2440588 xiii:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 50340
+test clock-29.1416 {time parsing} {
+ clock scan {2440588 xiii:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 50340
+test clock-29.1417 {time parsing} {
+ clock scan {2440588 xiii:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 50340
+test clock-29.1418 {time parsing} {
+ clock scan {2440588 xiii:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 50340
+test clock-29.1419 {time parsing} {
+ clock scan {2440588 xiii:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 50340
+test clock-29.1420 {time parsing} {
+ clock scan {2440588 xiii:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 50340
+test clock-29.1421 {time parsing} {
+ clock scan {2440588 01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 50340
+test clock-29.1422 {time parsing} {
+ clock scan {2440588 01:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 50340
+test clock-29.1423 {time parsing} {
+ clock scan {2440588 01:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 50340
+test clock-29.1424 {time parsing} {
+ clock scan {2440588 01:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 50340
+test clock-29.1425 {time parsing} {
+ clock scan {2440588 1:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 50340
+test clock-29.1426 {time parsing} {
+ clock scan {2440588 1:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 50340
+test clock-29.1427 {time parsing} {
+ clock scan {2440588 1:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 50340
+test clock-29.1428 {time parsing} {
+ clock scan {2440588 1:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 50340
+test clock-29.1429 {time parsing} {
+ clock scan {2440588 i:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 50340
+test clock-29.1430 {time parsing} {
+ clock scan {2440588 i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 50340
+test clock-29.1431 {time parsing} {
+ clock scan {2440588 i:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 50340
+test clock-29.1432 {time parsing} {
+ clock scan {2440588 i:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 50340
+test clock-29.1433 {time parsing} {
+ clock scan {2440588 i:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 50340
+test clock-29.1434 {time parsing} {
+ clock scan {2440588 i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 50340
+test clock-29.1435 {time parsing} {
+ clock scan {2440588 i:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 50340
+test clock-29.1436 {time parsing} {
+ clock scan {2440588 i:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 50340
+test clock-29.1437 {time parsing} {
+ clock scan {2440588 01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 50340
+test clock-29.1438 {time parsing} {
+ clock scan {2440588 01:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 50340
+test clock-29.1439 {time parsing} {
+ clock scan {2440588 01:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 50340
+test clock-29.1440 {time parsing} {
+ clock scan {2440588 01:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 50340
+test clock-29.1441 {time parsing} {
+ clock scan {2440588 1:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 50340
+test clock-29.1442 {time parsing} {
+ clock scan {2440588 1:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 50340
+test clock-29.1443 {time parsing} {
+ clock scan {2440588 1:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 50340
+test clock-29.1444 {time parsing} {
+ clock scan {2440588 1:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 50340
+test clock-29.1445 {time parsing} {
+ clock scan {2440588 i:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 50340
+test clock-29.1446 {time parsing} {
+ clock scan {2440588 i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 50340
+test clock-29.1447 {time parsing} {
+ clock scan {2440588 i:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 50340
+test clock-29.1448 {time parsing} {
+ clock scan {2440588 i:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 50340
+test clock-29.1449 {time parsing} {
+ clock scan {2440588 i:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 50340
+test clock-29.1450 {time parsing} {
+ clock scan {2440588 i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 50340
+test clock-29.1451 {time parsing} {
+ clock scan {2440588 i:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 50340
+test clock-29.1452 {time parsing} {
+ clock scan {2440588 i:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 50340
+test clock-29.1453 {time parsing} {
+ clock scan {2440588 13:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 50341
+test clock-29.1454 {time parsing} {
+ clock scan {2440588 13:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 50341
+test clock-29.1455 {time parsing} {
+ clock scan {2440588 13:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 50341
+test clock-29.1456 {time parsing} {
+ clock scan {2440588 13:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 50341
+test clock-29.1457 {time parsing} {
+ clock scan {2440588 xiii:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 50341
+test clock-29.1458 {time parsing} {
+ clock scan {2440588 xiii:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 50341
+test clock-29.1459 {time parsing} {
+ clock scan {2440588 xiii:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 50341
+test clock-29.1460 {time parsing} {
+ clock scan {2440588 xiii:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 50341
+test clock-29.1461 {time parsing} {
+ clock scan {2440588 01:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 50341
+test clock-29.1462 {time parsing} {
+ clock scan {2440588 01:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 50341
+test clock-29.1463 {time parsing} {
+ clock scan {2440588 1:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 50341
+test clock-29.1464 {time parsing} {
+ clock scan {2440588 1:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 50341
+test clock-29.1465 {time parsing} {
+ clock scan {2440588 i:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 50341
+test clock-29.1466 {time parsing} {
+ clock scan {2440588 i:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 50341
+test clock-29.1467 {time parsing} {
+ clock scan {2440588 i:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 50341
+test clock-29.1468 {time parsing} {
+ clock scan {2440588 i:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 50341
+test clock-29.1469 {time parsing} {
+ clock scan {2440588 01:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 50341
+test clock-29.1470 {time parsing} {
+ clock scan {2440588 01:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 50341
+test clock-29.1471 {time parsing} {
+ clock scan {2440588 1:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 50341
+test clock-29.1472 {time parsing} {
+ clock scan {2440588 1:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 50341
+test clock-29.1473 {time parsing} {
+ clock scan {2440588 i:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 50341
+test clock-29.1474 {time parsing} {
+ clock scan {2440588 i:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 50341
+test clock-29.1475 {time parsing} {
+ clock scan {2440588 i:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 50341
+test clock-29.1476 {time parsing} {
+ clock scan {2440588 i:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 50341
+test clock-29.1477 {time parsing} {
+ clock scan {2440588 13:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 50399
+test clock-29.1478 {time parsing} {
+ clock scan {2440588 13:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 50399
+test clock-29.1479 {time parsing} {
+ clock scan {2440588 13:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 50399
+test clock-29.1480 {time parsing} {
+ clock scan {2440588 13:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 50399
+test clock-29.1481 {time parsing} {
+ clock scan {2440588 xiii:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 50399
+test clock-29.1482 {time parsing} {
+ clock scan {2440588 xiii:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 50399
+test clock-29.1483 {time parsing} {
+ clock scan {2440588 xiii:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 50399
+test clock-29.1484 {time parsing} {
+ clock scan {2440588 xiii:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 50399
+test clock-29.1485 {time parsing} {
+ clock scan {2440588 01:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 50399
+test clock-29.1486 {time parsing} {
+ clock scan {2440588 01:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 50399
+test clock-29.1487 {time parsing} {
+ clock scan {2440588 1:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 50399
+test clock-29.1488 {time parsing} {
+ clock scan {2440588 1:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 50399
+test clock-29.1489 {time parsing} {
+ clock scan {2440588 i:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 50399
+test clock-29.1490 {time parsing} {
+ clock scan {2440588 i:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 50399
+test clock-29.1491 {time parsing} {
+ clock scan {2440588 i:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 50399
+test clock-29.1492 {time parsing} {
+ clock scan {2440588 i:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 50399
+test clock-29.1493 {time parsing} {
+ clock scan {2440588 01:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 50399
+test clock-29.1494 {time parsing} {
+ clock scan {2440588 01:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 50399
+test clock-29.1495 {time parsing} {
+ clock scan {2440588 1:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 50399
+test clock-29.1496 {time parsing} {
+ clock scan {2440588 1:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 50399
+test clock-29.1497 {time parsing} {
+ clock scan {2440588 i:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 50399
+test clock-29.1498 {time parsing} {
+ clock scan {2440588 i:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 50399
+test clock-29.1499 {time parsing} {
+ clock scan {2440588 i:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 50399
+test clock-29.1500 {time parsing} {
+ clock scan {2440588 i:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 50399
+test clock-29.1501 {time parsing} {
+ clock scan {2440588 23 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H }
+} 82800
+test clock-29.1502 {time parsing} {
+ clock scan {2440588 23:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 82800
+test clock-29.1503 {time parsing} {
+ clock scan {2440588 23:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 82800
+test clock-29.1504 {time parsing} {
+ clock scan {2440588 23:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 82800
+test clock-29.1505 {time parsing} {
+ clock scan {2440588 23:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 82800
+test clock-29.1506 {time parsing} {
+ clock scan {2440588 23 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k }
+} 82800
+test clock-29.1507 {time parsing} {
+ clock scan {2440588 23:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 82800
+test clock-29.1508 {time parsing} {
+ clock scan {2440588 23:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 82800
+test clock-29.1509 {time parsing} {
+ clock scan {2440588 23:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 82800
+test clock-29.1510 {time parsing} {
+ clock scan {2440588 23:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 82800
+test clock-29.1511 {time parsing} {
+ clock scan {2440588 xxiii } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH }
+} 82800
+test clock-29.1512 {time parsing} {
+ clock scan {2440588 xxiii:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 82800
+test clock-29.1513 {time parsing} {
+ clock scan {2440588 xxiii:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 82800
+test clock-29.1514 {time parsing} {
+ clock scan {2440588 xxiii:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 82800
+test clock-29.1515 {time parsing} {
+ clock scan {2440588 xxiii:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 82800
+test clock-29.1516 {time parsing} {
+ clock scan {2440588 xxiii } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok }
+} 82800
+test clock-29.1517 {time parsing} {
+ clock scan {2440588 xxiii:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 82800
+test clock-29.1518 {time parsing} {
+ clock scan {2440588 xxiii:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 82800
+test clock-29.1519 {time parsing} {
+ clock scan {2440588 xxiii:00:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 82800
+test clock-29.1520 {time parsing} {
+ clock scan {2440588 xxiii:?:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 82800
+test clock-29.1521 {time parsing} {
+ clock scan {2440588 11 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %p}
+} 82800
+test clock-29.1522 {time parsing} {
+ clock scan {2440588 11:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 82800
+test clock-29.1523 {time parsing} {
+ clock scan {2440588 11:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 82800
+test clock-29.1524 {time parsing} {
+ clock scan {2440588 11:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 82800
+test clock-29.1525 {time parsing} {
+ clock scan {2440588 11:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 82800
+test clock-29.1526 {time parsing} {
+ clock scan {2440588 11 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %p}
+} 82800
+test clock-29.1527 {time parsing} {
+ clock scan {2440588 11:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 82800
+test clock-29.1528 {time parsing} {
+ clock scan {2440588 11:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 82800
+test clock-29.1529 {time parsing} {
+ clock scan {2440588 11:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 82800
+test clock-29.1530 {time parsing} {
+ clock scan {2440588 11:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 82800
+test clock-29.1531 {time parsing} {
+ clock scan {2440588 xi PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %p}
+} 82800
+test clock-29.1532 {time parsing} {
+ clock scan {2440588 xi:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 82800
+test clock-29.1533 {time parsing} {
+ clock scan {2440588 xi:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 82800
+test clock-29.1534 {time parsing} {
+ clock scan {2440588 xi:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 82800
+test clock-29.1535 {time parsing} {
+ clock scan {2440588 xi:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 82800
+test clock-29.1536 {time parsing} {
+ clock scan {2440588 xi PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %p}
+} 82800
+test clock-29.1537 {time parsing} {
+ clock scan {2440588 xi:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 82800
+test clock-29.1538 {time parsing} {
+ clock scan {2440588 xi:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 82800
+test clock-29.1539 {time parsing} {
+ clock scan {2440588 xi:00:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 82800
+test clock-29.1540 {time parsing} {
+ clock scan {2440588 xi:?:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 82800
+test clock-29.1541 {time parsing} {
+ clock scan {2440588 11 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I %P}
+} 82800
+test clock-29.1542 {time parsing} {
+ clock scan {2440588 11:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 82800
+test clock-29.1543 {time parsing} {
+ clock scan {2440588 11:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 82800
+test clock-29.1544 {time parsing} {
+ clock scan {2440588 11:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 82800
+test clock-29.1545 {time parsing} {
+ clock scan {2440588 11:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 82800
+test clock-29.1546 {time parsing} {
+ clock scan {2440588 11 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l %P}
+} 82800
+test clock-29.1547 {time parsing} {
+ clock scan {2440588 11:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 82800
+test clock-29.1548 {time parsing} {
+ clock scan {2440588 11:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 82800
+test clock-29.1549 {time parsing} {
+ clock scan {2440588 11:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 82800
+test clock-29.1550 {time parsing} {
+ clock scan {2440588 11:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 82800
+test clock-29.1551 {time parsing} {
+ clock scan {2440588 xi pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI %P}
+} 82800
+test clock-29.1552 {time parsing} {
+ clock scan {2440588 xi:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 82800
+test clock-29.1553 {time parsing} {
+ clock scan {2440588 xi:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 82800
+test clock-29.1554 {time parsing} {
+ clock scan {2440588 xi:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 82800
+test clock-29.1555 {time parsing} {
+ clock scan {2440588 xi:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 82800
+test clock-29.1556 {time parsing} {
+ clock scan {2440588 xi pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol %P}
+} 82800
+test clock-29.1557 {time parsing} {
+ clock scan {2440588 xi:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 82800
+test clock-29.1558 {time parsing} {
+ clock scan {2440588 xi:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 82800
+test clock-29.1559 {time parsing} {
+ clock scan {2440588 xi:00:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 82800
+test clock-29.1560 {time parsing} {
+ clock scan {2440588 xi:?:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 82800
+test clock-29.1561 {time parsing} {
+ clock scan {2440588 23:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 82801
+test clock-29.1562 {time parsing} {
+ clock scan {2440588 23:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 82801
+test clock-29.1563 {time parsing} {
+ clock scan {2440588 23:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 82801
+test clock-29.1564 {time parsing} {
+ clock scan {2440588 23:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 82801
+test clock-29.1565 {time parsing} {
+ clock scan {2440588 xxiii:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 82801
+test clock-29.1566 {time parsing} {
+ clock scan {2440588 xxiii:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 82801
+test clock-29.1567 {time parsing} {
+ clock scan {2440588 xxiii:00:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 82801
+test clock-29.1568 {time parsing} {
+ clock scan {2440588 xxiii:?:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 82801
+test clock-29.1569 {time parsing} {
+ clock scan {2440588 11:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 82801
+test clock-29.1570 {time parsing} {
+ clock scan {2440588 11:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 82801
+test clock-29.1571 {time parsing} {
+ clock scan {2440588 11:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 82801
+test clock-29.1572 {time parsing} {
+ clock scan {2440588 11:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 82801
+test clock-29.1573 {time parsing} {
+ clock scan {2440588 xi:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 82801
+test clock-29.1574 {time parsing} {
+ clock scan {2440588 xi:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 82801
+test clock-29.1575 {time parsing} {
+ clock scan {2440588 xi:00:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 82801
+test clock-29.1576 {time parsing} {
+ clock scan {2440588 xi:?:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 82801
+test clock-29.1577 {time parsing} {
+ clock scan {2440588 11:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 82801
+test clock-29.1578 {time parsing} {
+ clock scan {2440588 11:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 82801
+test clock-29.1579 {time parsing} {
+ clock scan {2440588 11:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 82801
+test clock-29.1580 {time parsing} {
+ clock scan {2440588 11:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 82801
+test clock-29.1581 {time parsing} {
+ clock scan {2440588 xi:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 82801
+test clock-29.1582 {time parsing} {
+ clock scan {2440588 xi:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 82801
+test clock-29.1583 {time parsing} {
+ clock scan {2440588 xi:00:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 82801
+test clock-29.1584 {time parsing} {
+ clock scan {2440588 xi:?:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 82801
+test clock-29.1585 {time parsing} {
+ clock scan {2440588 23:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 82859
+test clock-29.1586 {time parsing} {
+ clock scan {2440588 23:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 82859
+test clock-29.1587 {time parsing} {
+ clock scan {2440588 23:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 82859
+test clock-29.1588 {time parsing} {
+ clock scan {2440588 23:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 82859
+test clock-29.1589 {time parsing} {
+ clock scan {2440588 xxiii:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 82859
+test clock-29.1590 {time parsing} {
+ clock scan {2440588 xxiii:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 82859
+test clock-29.1591 {time parsing} {
+ clock scan {2440588 xxiii:00:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 82859
+test clock-29.1592 {time parsing} {
+ clock scan {2440588 xxiii:?:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 82859
+test clock-29.1593 {time parsing} {
+ clock scan {2440588 11:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 82859
+test clock-29.1594 {time parsing} {
+ clock scan {2440588 11:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 82859
+test clock-29.1595 {time parsing} {
+ clock scan {2440588 11:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 82859
+test clock-29.1596 {time parsing} {
+ clock scan {2440588 11:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 82859
+test clock-29.1597 {time parsing} {
+ clock scan {2440588 xi:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 82859
+test clock-29.1598 {time parsing} {
+ clock scan {2440588 xi:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 82859
+test clock-29.1599 {time parsing} {
+ clock scan {2440588 xi:00:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 82859
+test clock-29.1600 {time parsing} {
+ clock scan {2440588 xi:?:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 82859
+test clock-29.1601 {time parsing} {
+ clock scan {2440588 11:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 82859
+test clock-29.1602 {time parsing} {
+ clock scan {2440588 11:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 82859
+test clock-29.1603 {time parsing} {
+ clock scan {2440588 11:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 82859
+test clock-29.1604 {time parsing} {
+ clock scan {2440588 11:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 82859
+test clock-29.1605 {time parsing} {
+ clock scan {2440588 xi:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 82859
+test clock-29.1606 {time parsing} {
+ clock scan {2440588 xi:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 82859
+test clock-29.1607 {time parsing} {
+ clock scan {2440588 xi:00:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 82859
+test clock-29.1608 {time parsing} {
+ clock scan {2440588 xi:?:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 82859
+test clock-29.1609 {time parsing} {
+ clock scan {2440588 23:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 82860
+test clock-29.1610 {time parsing} {
+ clock scan {2440588 23:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 82860
+test clock-29.1611 {time parsing} {
+ clock scan {2440588 23:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 82860
+test clock-29.1612 {time parsing} {
+ clock scan {2440588 23:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 82860
+test clock-29.1613 {time parsing} {
+ clock scan {2440588 23:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 82860
+test clock-29.1614 {time parsing} {
+ clock scan {2440588 23:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 82860
+test clock-29.1615 {time parsing} {
+ clock scan {2440588 23:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 82860
+test clock-29.1616 {time parsing} {
+ clock scan {2440588 23:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 82860
+test clock-29.1617 {time parsing} {
+ clock scan {2440588 xxiii:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 82860
+test clock-29.1618 {time parsing} {
+ clock scan {2440588 xxiii:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 82860
+test clock-29.1619 {time parsing} {
+ clock scan {2440588 xxiii:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 82860
+test clock-29.1620 {time parsing} {
+ clock scan {2440588 xxiii:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 82860
+test clock-29.1621 {time parsing} {
+ clock scan {2440588 xxiii:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 82860
+test clock-29.1622 {time parsing} {
+ clock scan {2440588 xxiii:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 82860
+test clock-29.1623 {time parsing} {
+ clock scan {2440588 xxiii:01:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 82860
+test clock-29.1624 {time parsing} {
+ clock scan {2440588 xxiii:i:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 82860
+test clock-29.1625 {time parsing} {
+ clock scan {2440588 11:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 82860
+test clock-29.1626 {time parsing} {
+ clock scan {2440588 11:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 82860
+test clock-29.1627 {time parsing} {
+ clock scan {2440588 11:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 82860
+test clock-29.1628 {time parsing} {
+ clock scan {2440588 11:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 82860
+test clock-29.1629 {time parsing} {
+ clock scan {2440588 11:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 82860
+test clock-29.1630 {time parsing} {
+ clock scan {2440588 11:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 82860
+test clock-29.1631 {time parsing} {
+ clock scan {2440588 11:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 82860
+test clock-29.1632 {time parsing} {
+ clock scan {2440588 11:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 82860
+test clock-29.1633 {time parsing} {
+ clock scan {2440588 xi:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 82860
+test clock-29.1634 {time parsing} {
+ clock scan {2440588 xi:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 82860
+test clock-29.1635 {time parsing} {
+ clock scan {2440588 xi:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 82860
+test clock-29.1636 {time parsing} {
+ clock scan {2440588 xi:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 82860
+test clock-29.1637 {time parsing} {
+ clock scan {2440588 xi:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 82860
+test clock-29.1638 {time parsing} {
+ clock scan {2440588 xi:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 82860
+test clock-29.1639 {time parsing} {
+ clock scan {2440588 xi:01:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 82860
+test clock-29.1640 {time parsing} {
+ clock scan {2440588 xi:i:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 82860
+test clock-29.1641 {time parsing} {
+ clock scan {2440588 11:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 82860
+test clock-29.1642 {time parsing} {
+ clock scan {2440588 11:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 82860
+test clock-29.1643 {time parsing} {
+ clock scan {2440588 11:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 82860
+test clock-29.1644 {time parsing} {
+ clock scan {2440588 11:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 82860
+test clock-29.1645 {time parsing} {
+ clock scan {2440588 11:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 82860
+test clock-29.1646 {time parsing} {
+ clock scan {2440588 11:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 82860
+test clock-29.1647 {time parsing} {
+ clock scan {2440588 11:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 82860
+test clock-29.1648 {time parsing} {
+ clock scan {2440588 11:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 82860
+test clock-29.1649 {time parsing} {
+ clock scan {2440588 xi:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 82860
+test clock-29.1650 {time parsing} {
+ clock scan {2440588 xi:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 82860
+test clock-29.1651 {time parsing} {
+ clock scan {2440588 xi:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 82860
+test clock-29.1652 {time parsing} {
+ clock scan {2440588 xi:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 82860
+test clock-29.1653 {time parsing} {
+ clock scan {2440588 xi:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 82860
+test clock-29.1654 {time parsing} {
+ clock scan {2440588 xi:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 82860
+test clock-29.1655 {time parsing} {
+ clock scan {2440588 xi:01:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 82860
+test clock-29.1656 {time parsing} {
+ clock scan {2440588 xi:i:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 82860
+test clock-29.1657 {time parsing} {
+ clock scan {2440588 23:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 82861
+test clock-29.1658 {time parsing} {
+ clock scan {2440588 23:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 82861
+test clock-29.1659 {time parsing} {
+ clock scan {2440588 23:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 82861
+test clock-29.1660 {time parsing} {
+ clock scan {2440588 23:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 82861
+test clock-29.1661 {time parsing} {
+ clock scan {2440588 xxiii:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 82861
+test clock-29.1662 {time parsing} {
+ clock scan {2440588 xxiii:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 82861
+test clock-29.1663 {time parsing} {
+ clock scan {2440588 xxiii:01:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 82861
+test clock-29.1664 {time parsing} {
+ clock scan {2440588 xxiii:i:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 82861
+test clock-29.1665 {time parsing} {
+ clock scan {2440588 11:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 82861
+test clock-29.1666 {time parsing} {
+ clock scan {2440588 11:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 82861
+test clock-29.1667 {time parsing} {
+ clock scan {2440588 11:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 82861
+test clock-29.1668 {time parsing} {
+ clock scan {2440588 11:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 82861
+test clock-29.1669 {time parsing} {
+ clock scan {2440588 xi:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 82861
+test clock-29.1670 {time parsing} {
+ clock scan {2440588 xi:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 82861
+test clock-29.1671 {time parsing} {
+ clock scan {2440588 xi:01:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 82861
+test clock-29.1672 {time parsing} {
+ clock scan {2440588 xi:i:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 82861
+test clock-29.1673 {time parsing} {
+ clock scan {2440588 11:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 82861
+test clock-29.1674 {time parsing} {
+ clock scan {2440588 11:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 82861
+test clock-29.1675 {time parsing} {
+ clock scan {2440588 11:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 82861
+test clock-29.1676 {time parsing} {
+ clock scan {2440588 11:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 82861
+test clock-29.1677 {time parsing} {
+ clock scan {2440588 xi:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 82861
+test clock-29.1678 {time parsing} {
+ clock scan {2440588 xi:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 82861
+test clock-29.1679 {time parsing} {
+ clock scan {2440588 xi:01:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 82861
+test clock-29.1680 {time parsing} {
+ clock scan {2440588 xi:i:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 82861
+test clock-29.1681 {time parsing} {
+ clock scan {2440588 23:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 82919
+test clock-29.1682 {time parsing} {
+ clock scan {2440588 23:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 82919
+test clock-29.1683 {time parsing} {
+ clock scan {2440588 23:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 82919
+test clock-29.1684 {time parsing} {
+ clock scan {2440588 23:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 82919
+test clock-29.1685 {time parsing} {
+ clock scan {2440588 xxiii:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 82919
+test clock-29.1686 {time parsing} {
+ clock scan {2440588 xxiii:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 82919
+test clock-29.1687 {time parsing} {
+ clock scan {2440588 xxiii:01:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 82919
+test clock-29.1688 {time parsing} {
+ clock scan {2440588 xxiii:i:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 82919
+test clock-29.1689 {time parsing} {
+ clock scan {2440588 11:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 82919
+test clock-29.1690 {time parsing} {
+ clock scan {2440588 11:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 82919
+test clock-29.1691 {time parsing} {
+ clock scan {2440588 11:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 82919
+test clock-29.1692 {time parsing} {
+ clock scan {2440588 11:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 82919
+test clock-29.1693 {time parsing} {
+ clock scan {2440588 xi:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 82919
+test clock-29.1694 {time parsing} {
+ clock scan {2440588 xi:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 82919
+test clock-29.1695 {time parsing} {
+ clock scan {2440588 xi:01:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 82919
+test clock-29.1696 {time parsing} {
+ clock scan {2440588 xi:i:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 82919
+test clock-29.1697 {time parsing} {
+ clock scan {2440588 11:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 82919
+test clock-29.1698 {time parsing} {
+ clock scan {2440588 11:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 82919
+test clock-29.1699 {time parsing} {
+ clock scan {2440588 11:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 82919
+test clock-29.1700 {time parsing} {
+ clock scan {2440588 11:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 82919
+test clock-29.1701 {time parsing} {
+ clock scan {2440588 xi:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 82919
+test clock-29.1702 {time parsing} {
+ clock scan {2440588 xi:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 82919
+test clock-29.1703 {time parsing} {
+ clock scan {2440588 xi:01:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 82919
+test clock-29.1704 {time parsing} {
+ clock scan {2440588 xi:i:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 82919
+test clock-29.1705 {time parsing} {
+ clock scan {2440588 23:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M }
+} 86340
+test clock-29.1706 {time parsing} {
+ clock scan {2440588 23:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM }
+} 86340
+test clock-29.1707 {time parsing} {
+ clock scan {2440588 23:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 86340
+test clock-29.1708 {time parsing} {
+ clock scan {2440588 23:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 86340
+test clock-29.1709 {time parsing} {
+ clock scan {2440588 23:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M }
+} 86340
+test clock-29.1710 {time parsing} {
+ clock scan {2440588 23:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM }
+} 86340
+test clock-29.1711 {time parsing} {
+ clock scan {2440588 23:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 86340
+test clock-29.1712 {time parsing} {
+ clock scan {2440588 23:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 86340
+test clock-29.1713 {time parsing} {
+ clock scan {2440588 xxiii:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M }
+} 86340
+test clock-29.1714 {time parsing} {
+ clock scan {2440588 xxiii:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM }
+} 86340
+test clock-29.1715 {time parsing} {
+ clock scan {2440588 xxiii:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 86340
+test clock-29.1716 {time parsing} {
+ clock scan {2440588 xxiii:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 86340
+test clock-29.1717 {time parsing} {
+ clock scan {2440588 xxiii:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M }
+} 86340
+test clock-29.1718 {time parsing} {
+ clock scan {2440588 xxiii:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM }
+} 86340
+test clock-29.1719 {time parsing} {
+ clock scan {2440588 xxiii:59:00 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 86340
+test clock-29.1720 {time parsing} {
+ clock scan {2440588 xxiii:lix:? } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 86340
+test clock-29.1721 {time parsing} {
+ clock scan {2440588 11:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %p}
+} 86340
+test clock-29.1722 {time parsing} {
+ clock scan {2440588 11:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %p}
+} 86340
+test clock-29.1723 {time parsing} {
+ clock scan {2440588 11:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 86340
+test clock-29.1724 {time parsing} {
+ clock scan {2440588 11:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 86340
+test clock-29.1725 {time parsing} {
+ clock scan {2440588 11:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %p}
+} 86340
+test clock-29.1726 {time parsing} {
+ clock scan {2440588 11:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %p}
+} 86340
+test clock-29.1727 {time parsing} {
+ clock scan {2440588 11:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 86340
+test clock-29.1728 {time parsing} {
+ clock scan {2440588 11:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 86340
+test clock-29.1729 {time parsing} {
+ clock scan {2440588 xi:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %p}
+} 86340
+test clock-29.1730 {time parsing} {
+ clock scan {2440588 xi:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %p}
+} 86340
+test clock-29.1731 {time parsing} {
+ clock scan {2440588 xi:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 86340
+test clock-29.1732 {time parsing} {
+ clock scan {2440588 xi:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 86340
+test clock-29.1733 {time parsing} {
+ clock scan {2440588 xi:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %p}
+} 86340
+test clock-29.1734 {time parsing} {
+ clock scan {2440588 xi:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %p}
+} 86340
+test clock-29.1735 {time parsing} {
+ clock scan {2440588 xi:59:00 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 86340
+test clock-29.1736 {time parsing} {
+ clock scan {2440588 xi:lix:? PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 86340
+test clock-29.1737 {time parsing} {
+ clock scan {2440588 11:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M %P}
+} 86340
+test clock-29.1738 {time parsing} {
+ clock scan {2440588 11:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM %P}
+} 86340
+test clock-29.1739 {time parsing} {
+ clock scan {2440588 11:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 86340
+test clock-29.1740 {time parsing} {
+ clock scan {2440588 11:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 86340
+test clock-29.1741 {time parsing} {
+ clock scan {2440588 11:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M %P}
+} 86340
+test clock-29.1742 {time parsing} {
+ clock scan {2440588 11:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM %P}
+} 86340
+test clock-29.1743 {time parsing} {
+ clock scan {2440588 11:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 86340
+test clock-29.1744 {time parsing} {
+ clock scan {2440588 11:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 86340
+test clock-29.1745 {time parsing} {
+ clock scan {2440588 xi:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M %P}
+} 86340
+test clock-29.1746 {time parsing} {
+ clock scan {2440588 xi:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM %P}
+} 86340
+test clock-29.1747 {time parsing} {
+ clock scan {2440588 xi:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 86340
+test clock-29.1748 {time parsing} {
+ clock scan {2440588 xi:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 86340
+test clock-29.1749 {time parsing} {
+ clock scan {2440588 xi:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M %P}
+} 86340
+test clock-29.1750 {time parsing} {
+ clock scan {2440588 xi:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM %P}
+} 86340
+test clock-29.1751 {time parsing} {
+ clock scan {2440588 xi:59:00 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 86340
+test clock-29.1752 {time parsing} {
+ clock scan {2440588 xi:lix:? pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 86340
+test clock-29.1753 {time parsing} {
+ clock scan {2440588 23:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 86341
+test clock-29.1754 {time parsing} {
+ clock scan {2440588 23:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 86341
+test clock-29.1755 {time parsing} {
+ clock scan {2440588 23:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 86341
+test clock-29.1756 {time parsing} {
+ clock scan {2440588 23:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 86341
+test clock-29.1757 {time parsing} {
+ clock scan {2440588 xxiii:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 86341
+test clock-29.1758 {time parsing} {
+ clock scan {2440588 xxiii:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 86341
+test clock-29.1759 {time parsing} {
+ clock scan {2440588 xxiii:59:01 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 86341
+test clock-29.1760 {time parsing} {
+ clock scan {2440588 xxiii:lix:i } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 86341
+test clock-29.1761 {time parsing} {
+ clock scan {2440588 11:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 86341
+test clock-29.1762 {time parsing} {
+ clock scan {2440588 11:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 86341
+test clock-29.1763 {time parsing} {
+ clock scan {2440588 11:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 86341
+test clock-29.1764 {time parsing} {
+ clock scan {2440588 11:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 86341
+test clock-29.1765 {time parsing} {
+ clock scan {2440588 xi:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 86341
+test clock-29.1766 {time parsing} {
+ clock scan {2440588 xi:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 86341
+test clock-29.1767 {time parsing} {
+ clock scan {2440588 xi:59:01 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 86341
+test clock-29.1768 {time parsing} {
+ clock scan {2440588 xi:lix:i PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 86341
+test clock-29.1769 {time parsing} {
+ clock scan {2440588 11:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 86341
+test clock-29.1770 {time parsing} {
+ clock scan {2440588 11:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 86341
+test clock-29.1771 {time parsing} {
+ clock scan {2440588 11:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 86341
+test clock-29.1772 {time parsing} {
+ clock scan {2440588 11:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 86341
+test clock-29.1773 {time parsing} {
+ clock scan {2440588 xi:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 86341
+test clock-29.1774 {time parsing} {
+ clock scan {2440588 xi:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 86341
+test clock-29.1775 {time parsing} {
+ clock scan {2440588 xi:59:01 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 86341
+test clock-29.1776 {time parsing} {
+ clock scan {2440588 xi:lix:i pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 86341
+test clock-29.1777 {time parsing} {
+ clock scan {2440588 23:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%M:%S }
+} 86399
+test clock-29.1778 {time parsing} {
+ clock scan {2440588 23:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %H:%OM:%OS }
+} 86399
+test clock-29.1779 {time parsing} {
+ clock scan {2440588 23:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%M:%S }
+} 86399
+test clock-29.1780 {time parsing} {
+ clock scan {2440588 23:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %k:%OM:%OS }
+} 86399
+test clock-29.1781 {time parsing} {
+ clock scan {2440588 xxiii:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%M:%S }
+} 86399
+test clock-29.1782 {time parsing} {
+ clock scan {2440588 xxiii:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %OH:%OM:%OS }
+} 86399
+test clock-29.1783 {time parsing} {
+ clock scan {2440588 xxiii:59:59 } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%M:%S }
+} 86399
+test clock-29.1784 {time parsing} {
+ clock scan {2440588 xxiii:lix:lix } \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ok:%OM:%OS }
+} 86399
+test clock-29.1785 {time parsing} {
+ clock scan {2440588 11:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %p}
+} 86399
+test clock-29.1786 {time parsing} {
+ clock scan {2440588 11:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %p}
+} 86399
+test clock-29.1787 {time parsing} {
+ clock scan {2440588 11:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %p}
+} 86399
+test clock-29.1788 {time parsing} {
+ clock scan {2440588 11:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %p}
+} 86399
+test clock-29.1789 {time parsing} {
+ clock scan {2440588 xi:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %p}
+} 86399
+test clock-29.1790 {time parsing} {
+ clock scan {2440588 xi:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %p}
+} 86399
+test clock-29.1791 {time parsing} {
+ clock scan {2440588 xi:59:59 PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %p}
+} 86399
+test clock-29.1792 {time parsing} {
+ clock scan {2440588 xi:lix:lix PM} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %p}
+} 86399
+test clock-29.1793 {time parsing} {
+ clock scan {2440588 11:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%M:%S %P}
+} 86399
+test clock-29.1794 {time parsing} {
+ clock scan {2440588 11:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %I:%OM:%OS %P}
+} 86399
+test clock-29.1795 {time parsing} {
+ clock scan {2440588 11:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%M:%S %P}
+} 86399
+test clock-29.1796 {time parsing} {
+ clock scan {2440588 11:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %l:%OM:%OS %P}
+} 86399
+test clock-29.1797 {time parsing} {
+ clock scan {2440588 xi:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%M:%S %P}
+} 86399
+test clock-29.1798 {time parsing} {
+ clock scan {2440588 xi:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %OI:%OM:%OS %P}
+} 86399
+test clock-29.1799 {time parsing} {
+ clock scan {2440588 xi:59:59 pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%M:%S %P}
+} 86399
+test clock-29.1800 {time parsing} {
+ clock scan {2440588 xi:lix:lix pm} \
+ -gmt true -locale en_US_roman \
+ -format {%J %Ol:%OM:%OS %P}
+} 86399
+# END testcases29
+
+test clock-30.1 {clock add years} {
+ set t [clock scan 2000-01-01 -format %Y-%m-%d -timezone :UTC]
+ set f [clock add $t 1 year -timezone :UTC]
+ clock format $f -format %Y-%m-%d -timezone :UTC
+} {2001-01-01}
+test clock-30.2 {clock add years - leap day} {
+ set t [clock scan 2000-02-29 -format %Y-%m-%d -timezone :UTC]
+ set f [clock add $t 1 years -timezone :UTC]
+ clock format $f -format %Y-%m-%d -timezone :UTC
+} {2001-02-28}
+test clock-30.3 {clock add months} {
+ set t [clock scan 2000-01-01 -format %Y-%m-%d -timezone :UTC]
+ set f [clock add $t 1 month -timezone :UTC]
+ clock format $f -format %Y-%m-%d -timezone :UTC
+} {2000-02-01}
+test clock-30.4 {clock add months, short month} {
+ set t [clock scan 2000-01-31 -format %Y-%m-%d -timezone :UTC]
+ set f [clock add $t 1 months -timezone :UTC]
+ clock format $f -format %Y-%m-%d -timezone :UTC
+} {2000-02-29}
+test clock-30.5 {clock add months, end of year} {
+ set t [clock scan 2000-12-01 -format %Y-%m-%d -timezone :UTC]
+ set f [clock add $t 1 month -timezone :UTC]
+ clock format $f -format %Y-%m-%d -timezone :UTC
+} {2001-01-01}
+test clock-30.6 {clock add months, one year one month vs 13 months} {
+ set t [clock scan 2000-02-29 -format %Y-%m-%d -timezone :UTC]
+ set f1 [clock add $t 1 year 1 month -timezone :UTC]
+ set f2 [clock add $t 13 months -timezone :UTC]
+ set x1 [clock format $f1 -format %Y-%m-%d -timezone :UTC]
+ set x2 [clock format $f2 -format %Y-%m-%d -timezone :UTC]
+ list $x1 $x2
+} {2001-03-28 2001-03-29}
+test clock-30.7 {clock add months, 1 year 1 month vs 1 month 1 year} {
+ set t [clock scan 2000-02-29 -format %Y-%m-%d -timezone :UTC]
+ set f1 [clock add $t 1 year 1 month -timezone :UTC]
+ set f2 [clock add $t 1 month 1 year -timezone :UTC]
+ set x1 [clock format $f1 -format %Y-%m-%d -timezone :UTC]
+ set x2 [clock format $f2 -format %Y-%m-%d -timezone :UTC]
+ list $x1 $x2
+} {2001-03-28 2001-03-29}
+test clock-30.8 {clock add months, negative} {
+ set t [clock scan 2000-03-31 -format %Y-%m-%d -timezone :UTC]
+ set f1 [clock add $t -1 month -timezone :UTC]
+ set f2 [clock add $t -2 month -timezone :UTC]
+ set f3 [clock add $t -3 month -timezone :UTC]
+ set f4 [clock add $t -4 month -timezone :UTC]
+ set x1 [clock format $f1 -format %Y-%m-%d -timezone :UTC]
+ set x2 [clock format $f2 -format %Y-%m-%d -timezone :UTC]
+ set x3 [clock format $f3 -format %Y-%m-%d -timezone :UTC]
+ set x4 [clock format $f4 -format %Y-%m-%d -timezone :UTC]
+ list $x1 $x2 $x3 $x4
+} {2000-02-29 2000-01-31 1999-12-31 1999-11-30}
+test clock-30.9 {clock add days} {
+ set t [clock scan {2000-01-01 12:34:56} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone :UTC]
+ set f1 [clock add $t 1 day -timezone :UTC]
+ set f2 [clock add $t -1 day -timezone :UTC]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ list $x1 $x2
+} {{2000-01-02 12:34:56} {1999-12-31 12:34:56}}
+test clock-30.10 {clock add days, spring DST conversion, before} {
+ set t [clock scan {2004-04-03 01:59:59} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 1 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f2 [clock add $t 2 days \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ list $x1 $x2
+} {{2004-04-04 01:59:59 -0500} {2004-04-05 01:59:59 -0400}}
+test clock-30.11 {clock add days, spring DST conversion, bad case} {
+ set t [clock scan {2004-04-03 02:30:00} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 1 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f2 [clock add $t 2 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ list $x1 $x2
+} {{2004-04-04 03:30:00 -0400} {2004-04-05 02:30:00 -0400}}
+test clock-30.12 {clock add days, spring DST conversion, after} {
+ set t [clock scan {2004-04-03 03:00:00} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 1 day -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f2 [clock add $t 2 day -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ list $x1 $x2
+} {{2004-04-04 03:00:00 -0400} {2004-04-05 03:00:00 -0400}}
+test clock-30.13 {clock add days, fall DST conversion, before} {
+ set t [clock scan {2004-10-30 00:59:59} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 1 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f2 [clock add $t 2 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ list $x1 $x2
+} {{2004-10-31 00:59:59 -0400} {2004-11-01 00:59:59 -0500}}
+test clock-30.14 {clock add days, fall DST conversion, bad case} {
+ set t [clock scan {2004-10-30 01:30:00} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 1 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f2 [clock add $t 2 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ list $x1 $x2
+} {{2004-10-31 01:30:00 -0400} {2004-11-01 01:30:00 -0500}}
+test clock-30.15 {clock add days, fall DST conversion, after} {
+ set t [clock scan {2004-10-30 02:30:00} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 1 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f2 [clock add $t 2 day \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ list $x1 $x2
+} {{2004-10-31 02:30:00 -0500} {2004-11-01 02:30:00 -0500}}
+test clock-30.16 {clock add weeks} {
+ set t [clock scan {2000-01-01 12:34:56} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone :UTC]
+ set f1 [clock add $t 1 week -timezone :UTC]
+ set f2 [clock add $t -1 weeks -timezone :UTC]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ list $x1 $x2
+} {{2000-01-08 12:34:56} {1999-12-25 12:34:56}}
+test clock-30.17 {clock add hours} {
+ set t [clock scan {2000-01-01 12:34:56} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone :UTC]
+ set f1 [clock add $t 1 hour -timezone :UTC]
+ set f2 [clock add $t -1 hours -timezone :UTC]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ list $x1 $x2
+} {{2000-01-01 13:34:56} {2000-01-01 11:34:56}}
+test clock-30.18 {clock add hours at DST conversion} {
+ set t [clock scan {2004-04-04 01:00:00 -0500} \
+ -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 1 hour -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-04-04 03:00:00 -0400}
+test clock-30.19 {clock add hours at DST conversion} {
+ set t [clock scan {2004-10-31 01:00:00 -0400} \
+ -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 1 hour \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-10-31 01:00:00 -0500}
+test clock-30.20 {clock add minutes} {
+ set t [clock scan {2000-01-01 12:34:56} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone :UTC]
+ set f1 [clock add $t 60 minute -timezone :UTC]
+ set f2 [clock add $t -60 minutes -timezone :UTC]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ list $x1 $x2
+} {{2000-01-01 13:34:56} {2000-01-01 11:34:56}}
+test clock-30.21 {clock add minutes at DST conversion} {
+ set t [clock scan {2004-04-04 01:00:00 -0500} \
+ -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 60 minutes \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-04-04 03:00:00 -0400}
+test clock-30.22 {clock add minutes at DST conversion} {
+ set t [clock scan {2004-10-31 01:00:00 -0400} \
+ -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 60 minutes \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-10-31 01:00:00 -0500}
+test clock-30.23 {clock add seconds} {
+ set t [clock scan {2000-01-01 12:34:56} -format {%Y-%m-%d %H:%M:%S} \
+ -timezone :UTC]
+ set f1 [clock add $t 3600 second -timezone :UTC]
+ set f2 [clock add $t -3600 seconds -timezone :UTC]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+ list $x1 $x2
+} {{2000-01-01 13:34:56} {2000-01-01 11:34:56}}
+test clock-30.24 {clock add seconds at DST conversion} {
+ set t [clock scan {2004-04-04 01:00:00 -0500} \
+ -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 3600 seconds \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-04-04 03:00:00 -0400}
+test clock-30.25 {clock add seconds at DST conversion} {
+ set t [clock scan {2004-10-31 01:00:00 -0400} \
+ -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set f1 [clock add $t 3600 seconds -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+ set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-10-31 01:00:00 -0500}
+
+test clock-31.1 {system locale} \
+ -constraints win \
+ -setup {
+ namespace eval ::tcl::clock {
+ namespace import -force ::testClock::registry
+ }
+ set noreg [info exists ::tcl::clock::NoRegistry]
+ if {$noreg} {unset ::tcl::clock::NoRegistry}
+ ::tcl::clock::ClearCaches
+ } \
+ -body {
+ clock format 0 -timezone :UTC -locale system -format %x
+ } \
+ -cleanup {
+ namespace eval ::tcl::clock {
+ rename registry {}
+ }
+ if {$noreg} {set ::tcl::clock::NoRegistry {}}
+ ::tcl::clock::ClearCaches
+ } \
+ -result [clock format 0 -timezone :UTC -locale current \
+ -format {%d-%b-%Y}]
+
+test clock-31.2 {system locale} \
+ -constraints win \
+ -setup {
+ namespace eval ::tcl::clock {
+ namespace import -force ::testClock::registry
+ }
+ set noreg [info exists ::tcl::clock::NoRegistry]
+ if {$noreg} {unset ::tcl::clock::NoRegistry}
+ ::tcl::clock::ClearCaches
+ } \
+ -body {
+ clock format 0 -timezone :UTC -locale system -format %Ex
+ } \
+ -cleanup {
+ namespace eval ::tcl::clock {
+ rename registry {}
+ }
+ if {$noreg} {set ::tcl::clock::NoRegistry {}}
+ ::tcl::clock::ClearCaches
+ } \
+ -result [clock format 0 -timezone :UTC -locale current \
+ -format {the %d' day of %B %Y}]
+
+test clock-31.3 {system locale} \
+ -constraints win \
+ -setup {
+ namespace eval ::tcl::clock {
+ namespace import -force ::testClock::registry
+ }
+ set noreg [info exists ::tcl::clock::NoRegistry]
+ if {$noreg} {unset ::tcl::clock::NoRegistry}
+ ::tcl::clock::ClearCaches
+ } \
+ -body {
+ clock format 0 -timezone :UTC -locale system -format %X
+ } \
+ -cleanup {
+ namespace eval ::tcl::clock {
+ rename registry {}
+ }
+ if {$noreg} {set ::tcl::clock::NoRegistry {}}
+ ::tcl::clock::ClearCaches
+ } \
+ -result [clock format 0 -timezone :UTC -locale current \
+ -format {%l:%M:%S %p}]
+
+test clock-31.4 {system locale} \
+ -constraints win \
+ -setup {
+ namespace eval ::tcl::clock {
+ namespace import -force ::testClock::registry
+ }
+ set noreg [info exists ::tcl::clock::NoRegistry]
+ if {$noreg} {unset ::tcl::clock::NoRegistry}
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ unset env(TZ)
+ }
+ if { [info exists env(TCL_TZ)] } {
+ set oldTclTZ $env(TCL_TZ)
+ unset env(TCL_TZ)
+ }
+ ::tcl::clock::ClearCaches
+ } \
+ -body {
+ clock format 0 -locale system -format %x
+ } \
+ -cleanup {
+ namespace eval ::tcl::clock {
+ rename registry {}
+ }
+ if { [info exists oldTclTZ] } {
+ set env(TCL_TZ) $oldTclTZ
+ }
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ }
+ if {$noreg} {set ::tcl::clock::NoRegistry {}}
+ ::tcl::clock::ClearCaches
+ } \
+ -result [clock format 0 -locale current -timezone EST5 \
+ -format {%d-%b-%Y}]
+
+test clock-31.5 {system locale} \
+ -constraints win \
+ -setup {
+ namespace eval ::tcl::clock {
+ namespace import -force ::testClock::registry
+ }
+ set noreg [info exists ::tcl::clock::NoRegistry]
+ if {$noreg} {unset ::tcl::clock::NoRegistry}
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ unset env(TZ)
+ }
+ if { [info exists env(TCL_TZ)] } {
+ set oldTclTZ $env(TCL_TZ)
+ unset env(TCL_TZ)
+ }
+ ::tcl::clock::ClearCaches
+ } \
+ -body {
+ clock format 0 -locale system -format %Ex
+ } \
+ -cleanup {
+ namespace eval ::tcl::clock {
+ rename registry {}
+ }
+ if {$noreg} {set ::tcl::clock::NoRegistry {}}
+ if { [info exists oldTclTZ] } {
+ set env(TCL_TZ) $oldTclTZ
+ }
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ }
+ ::tcl::clock::ClearCaches
+ } \
+ -result [clock format 0 -locale current -timezone EST5 \
+ -format {the %d' day of %B %Y}]
+
+test clock-31.6 {system locale} \
+ -constraints win \
+ -setup {
+ namespace eval ::tcl::clock {
+ namespace import -force ::testClock::registry
+ }
+ set noreg [info exists ::tcl::clock::NoRegistry]
+ if {$noreg} {unset ::tcl::clock::NoRegistry}
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ unset env(TZ)
+ }
+ if { [info exists env(TCL_TZ)] } {
+ set oldTclTZ $env(TCL_TZ)
+ unset env(TCL_TZ)
+ }
+ ::tcl::clock::ClearCaches
+ } \
+ -body {
+ clock format 0 -locale system -format "%X %Z"
+ } \
+ -cleanup {
+ namespace eval ::tcl::clock {
+ rename registry {}
+ }
+ if {$noreg} {set ::tcl::clock::NoRegistry {}}
+ if { [info exists oldTclTZ] } {
+ set env(TCL_TZ) $oldTclTZ
+ }
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ }
+ ::tcl::clock::ClearCaches
+ } \
+ -result [clock format 0 -locale current -timezone EST5 \
+ -format {%l:%M:%S %p %Z}]
+
+test clock-32.1 {scan/format across the Gregorian change} {
+ set problems {}
+ set t [expr { wide(-6857395200) }]
+ foreach d { 1 2 14 15 16
+ 17 18 19 20 21 22 23
+ 24 25 26 27 28 29 30 } \
+ j { 245 246 258 259 260
+ 261 262 263 264 265 266 267
+ 268 269 270 271 272 273 274 } {
+ set u [format 1752-09-%02d $d]
+ set s [clock format $t -format %Y-%m-%d \
+ -locale en_US_roman -timezone :UTC]
+ if { $s ne $u } {
+ append problems "formatting $t: $s should be $u\n"
+ }
+ set v [clock scan $u -format %Y-%m-%d \
+ -locale en_US_roman -timezone :UTC]
+ if { $t ne $v } {
+ append problems "scanning $u: $t should be $v\n"
+ }
+ set u [format 1752-%03d $j]
+ set s [clock format $t -format %Y-%j \
+ -locale en_US_roman -timezone :UTC]
+ if { $s ne $u } {
+ append problems "formatting $t: $s should be $u\n"
+ }
+ set v [clock scan $u -format %Y-%j \
+ -locale en_US_roman -timezone :UTC]
+ if { $t ne $v } {
+ append problems "scanning $u: $t should be $v\n"
+ }
+ incr t 86400
+ }
+ set problems
+} {}
+
+# Legacy tests
+
+# clock clicks
+test clock-33.1 {clock clicks tests} {
+ expr [clock clicks]+1
+ concat {}
+} {}
+test clock-33.2 {clock clicks tests} {
+ set start [clock clicks]
+ after 10
+ set end [clock clicks]
+ expr "$end > $start"
+} {1}
+test clock-33.3 {clock clicks tests} {
+ list [catch {clock clicks foo} msg] $msg
+} {1 {bad switch "foo": must be -milliseconds or -microseconds}}
+test clock-33.4 {clock clicks tests} {
+ expr [clock clicks -milliseconds]+1
+ concat {}
+} {}
+test clock-33.4a {clock milliseconds} {
+ expr { [clock milliseconds] + 1 }
+ concat {}
+} {}
+test clock-33.5 {clock clicks tests, millisecond timing test} {
+ # This test can fail on a system that is so heavily loaded that
+ # the test takes >60 ms to run.
+ set start [clock clicks -milli]
+ after 10
+ set end [clock clicks -milli]
+ # 60 msecs seems to be the max time slice under Windows 95/98
+ expr {
+ ($end > $start) && (($end - $start) <= 60) ?
+ "ok" :
+ "test should have taken 0-60 ms, actually took [expr $end - $start]"}
+} {ok}
+test clock-33.5a {clock tests, millisecond timing test} {
+ # This test can fail on a system that is so heavily loaded that
+ # the test takes >60 ms to run.
+ set start [clock milliseconds]
+ after 10
+ set end [clock milliseconds]
+ # 60 msecs seems to be the max time slice under Windows 95/98
+ expr {
+ ($end > $start) && (($end - $start) <= 60) ?
+ "ok" :
+ "test should have taken 0-60 ms, actually took [expr $end - $start]"}
+} {ok}
+test clock-33.6 {clock clicks, milli with too much abbreviation} {
+ list [catch { clock clicks ? } msg] $msg
+} {1 {bad switch "?": must be -milliseconds or -microseconds}}
+test clock-33.7 {clock clicks, milli with too much abbreviation} {
+ list [catch { clock clicks - } msg] $msg
+} {1 {ambiguous switch "-": must be -milliseconds or -microseconds}}
+
+test clock-33.8 {clock clicks test, microsecond timing test} {
+ # This test can fail on a system that is so heavily loaded that
+ # the test takes >60 ms to run.
+ set start [clock clicks -micro]
+ after 10
+ set end [clock clicks -micro]
+ expr {($end > $start) && (($end - $start) <= 60000)}
+} {1}
+test clock-33.8a {clock test, microsecond timing test} {
+ # This test can fail on a system that is so heavily loaded that
+ # the test takes >60 ms to run.
+ set start [clock microseconds]
+ after 10
+ set end [clock microseconds]
+ expr {($end > $start) && (($end - $start) <= 60000)}
+} {1}
+
+test clock-33.9 {clock clicks test, millis align with seconds} {
+ set t1 [clock seconds]
+ while { 1 } {
+ set t2 [clock clicks -millis]
+ set t3 [clock seconds]
+ if { $t3 == $t1 } break
+ set t1 $t3
+ }
+ expr { $t2 / 1000 == $t3 }
+} {1}
+test clock-33.9a {clock test, millis align with seconds} {
+ set t1 [clock seconds]
+ while { 1 } {
+ set t2 [clock milliseconds]
+ set t3 [clock seconds]
+ if { $t3 == $t1 } break
+ set t1 $t3
+ }
+ expr { $t2 / 1000 == $t3 }
+} {1}
+
+test clock-33.10 {clock clicks test, micros align with seconds} {
+ set t1 [clock seconds]
+ while { 1 } {
+ set t2 [clock clicks -micros]
+ set t3 [clock seconds]
+ if { $t3 == $t1 } break
+ set t1 $t3
+ }
+ expr { $t2 / 1000000 == $t3 }
+} {1}
+test clock-33.10a {clock test, micros align with seconds} {
+ set t1 [clock seconds]
+ while { 1 } {
+ set t2 [clock microseconds]
+ set t3 [clock seconds]
+ if { $t3 == $t1 } break
+ set t1 $t3
+ }
+ expr { $t2 / 1000000 == $t3 }
+} {1}
+
+test clock-33.11 {clock clicks test, millis align with micros} {
+ set t1 [clock clicks -millis]
+ while { 1 } {
+ set t2 [clock clicks -micros]
+ set t3 [clock clicks -millis]
+ if { $t3 == $t1 } break
+ set t1 $t3
+ }
+ expr { $t2 / 1000 == $t3 }
+} {1}
+test clock-33.11a {clock test, millis align with micros} {
+ set t1 [clock milliseconds]
+ while { 1 } {
+ set t2 [clock microseconds]
+ set t3 [clock milliseconds]
+ if { $t3 == $t1 } break
+ set t1 $t3
+ }
+ expr { $t2 / 1000 == $t3 }
+} {1}
+
+# clock scan
+test clock-34.1 {clock scan tests} {
+ list [catch {clock scan} msg] $msg
+} {1 {wrong # args: should be "clock scan string ?-base seconds? ?-format string? ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?"}}
+test clock-34.2 {clock scan tests} {*}{
+ -body {clock scan "bad-string"}
+ -returnCodes error
+ -match glob
+ -result {unable to convert date-time string "bad-string"*}
+}
+test clock-34.3 {clock scan tests} {
+ clock format [clock scan "14 Feb 92" -gmt true] \
+ -format {%m/%d/%y %I:%M:%S %p} -gmt true
+} {02/14/92 12:00:00 AM}
+test clock-34.4 {clock scan tests} {
+ clock format [clock scan "Feb 14, 1992 12:20 PM" -gmt true] \
+ -format {%m/%d/%y %I:%M:%S %p} -gmt true
+} {02/14/92 12:20:00 PM}
+test clock-34.5 {clock scan tests} {
+ clock format \
+ [clock scan "Feb 14, 1992 12:20 PM" -base 319363200 -gmt true] \
+ -format {%m/%d/%y %I:%M:%S %p} -gmt true
+} {02/14/92 12:20:00 PM}
+test clock-34.6 {clock scan tests} {
+ set time [clock scan "Oct 23,1992 15:00"]
+ clock format $time -format {%b %d,%Y %H:%M}
+} {Oct 23,1992 15:00}
+test clock-34.7 {clock scan tests} {
+ set time [clock scan "Oct 23,1992 15:00 GMT"]
+ clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
+} {Oct 23,1992 15:00 GMT}
+test clock-34.8 {clock scan tests} {
+ set time [clock scan "Oct 23,1992 15:00" -gmt true]
+ clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
+} {Oct 23,1992 15:00 GMT}
+test clock-34.9 {clock scan tests} {
+ list [catch {clock scan "Jan 12" -bad arg} msg] $msg
+} {1 {bad switch "-bad", must be -base, -format, -gmt, -locale or -timezone}}
+# The following two two tests test the two year date policy
+test clock-34.10 {clock scan tests} {
+ set time [clock scan "1/1/71" -gmt true]
+ clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
+} {Jan 01,1971 00:00 GMT}
+test clock-34.11 {clock scan tests} {
+ set time [clock scan "1/1/37" -gmt true]
+ clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
+} {Jan 01,2037 00:00 GMT}
+
+test clock-34.12 {clock scan, relative times} {
+ set time [clock scan "Oct 23, 1992 -1 day"]
+ clock format $time -format {%b %d, %Y}
+} "Oct 22, 1992"
+test clock-34.13 {clock scan, ISO 8601 base date format} {
+ set time [clock scan "19921023"]
+ clock format $time -format {%b %d, %Y}
+} "Oct 23, 1992"
+test clock-34.14 {clock scan, ISO 8601 expanded date format} {
+ set time [clock scan "1992-10-23"]
+ clock format $time -format {%b %d, %Y}
+} "Oct 23, 1992"
+test clock-34.15 {clock scan, DD-Mon-YYYY format} {
+ set time [clock scan "23-Oct-1992"]
+ clock format $time -format {%b %d, %Y}
+} "Oct 23, 1992"
+test clock-34.16 {clock scan, ISO 8601 point in time format} {
+ set time [clock scan "19921023T235959"]
+ clock format $time -format {%b %d, %Y %H:%M:%S}
+} "Oct 23, 1992 23:59:59"
+test clock-34.17 {clock scan, ISO 8601 point in time format} {
+ set time [clock scan "19921023 235959"]
+ clock format $time -format {%b %d, %Y %H:%M:%S}
+} "Oct 23, 1992 23:59:59"
+test clock-34.18 {clock scan, ISO 8601 point in time format} {
+ set time [clock scan "19921023T000000"]
+ clock format $time -format {%b %d, %Y %H:%M:%S}
+} "Oct 23, 1992 00:00:00"
+
+# CLOCK SCAN REAL TESTS
+# We use 5am PST, 31-12-1999 as the base for these scans because irrespective
+# of your local timezone it should always give us times on December 31, 1999
+set 5amPST 946645200
+test clock-34.19 {clock scan, number meridian} {
+ set t1 [clock scan "5 am" -base $5amPST -gmt true]
+ set t2 [clock scan "5 pm" -base $5amPST -gmt true]
+ set t3 [clock scan "5 a.m." -base $5amPST -gmt true]
+ set t4 [clock scan "5 p.m." -base $5amPST -gmt true]
+ list \
+ [clock format $t1 -format {%b %d, %Y %H:%M:%S} -gmt true] \
+ [clock format $t2 -format {%b %d, %Y %H:%M:%S} -gmt true] \
+ [clock format $t3 -format {%b %d, %Y %H:%M:%S} -gmt true] \
+ [clock format $t4 -format {%b %d, %Y %H:%M:%S} -gmt true]
+} [list "Dec 31, 1999 05:00:00" "Dec 31, 1999 17:00:00" \
+ "Dec 31, 1999 05:00:00" "Dec 31, 1999 17:00:00"]
+test clock-34.20 {clock scan, number:number meridian} {
+ clock format [clock scan "5:30 pm" -base $5amPST -gmt true] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 17:30:00"
+test clock-34.21 {clock scan, number:number-timezone} {
+ clock format [clock scan "00:00-0800" -gmt true -base $5amPST] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 08:00:00"
+test clock-34.22 {clock scan, number:number:number o_merid} {
+ clock format [clock scan "8:00:00" -gmt true -base $5amPST] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 08:00:00"
+test clock-34.23 {clock scan, number:number:number o_merid} {
+ clock format [clock scan "8:00:00 am" -gmt true -base $5amPST] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 08:00:00"
+test clock-34.24 {clock scan, number:number:number o_merid} {
+ clock format [clock scan "8:00:00 pm" -gmt true -base $5amPST] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 20:00:00"
+test clock-34.25 {clock scan, number:number:number-timezone} {
+ clock format [clock scan "00:00:30-0800" -gmt true -base $5amPST] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 08:00:30"
+test clock-34.26 {clock scan, DST for days} {
+ clock scan "tomorrow" -base [clock scan "19991031 00:00:00"]
+} [clock scan "19991101 00:00:00"]
+test clock-34.27 {clock scan, DST for days} {
+ clock scan "yesterday" -base [clock scan "19991101 00:00:00"]
+} [clock scan "19991031 00:00:00"]
+test clock-34.28 {clock scan, day} {
+ clock format [clock scan "Monday" -gmt true -base 946627200] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Jan 03, 2000 00:00:00"
+test clock-34.29 {clock scan, number/number} {
+ clock format [clock scan "1/1" -gmt true -base 946627200] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Jan 01, 1999 00:00:00"
+test clock-34.30 {clock scan, number/number} {
+ clock format [clock scan "1/1/1999" -gmt true -base 946627200] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Jan 01, 1999 00:00:00"
+test clock-34.31 {clock scan, number/number} {
+ clock format [clock scan "19990101" -gmt true -base 946627200] \
+ -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Jan 01, 1999 00:00:00"
+test clock-34.32 {clock scan, relative minutes} {
+ clock scan "now + 1 minute" -base 946627200
+} 946627260
+test clock-34.33 {clock scan, relative minutes} {
+ clock scan "now +1 minute" -base 946627200
+} 946627260
+test clock-34.34 {clock scan, relative minutes} {
+ clock scan "now 1 minute" -base 946627200
+} 946627260
+test clock-34.35 {clock scan, relative minutes} {
+ clock scan "now - 1 minute" -base 946627200
+} 946627140
+test clock-34.36 {clock scan, relative minutes} {
+ clock scan "now -1 minute" -base 946627200
+} 946627140
+test clock-34.37 {clock scan, day of week} {
+ clock format [clock scan "wednesday" -base [clock scan 20000112]] \
+ -format {%b %d, %Y}
+} "Jan 12, 2000"
+test clock-34.38 {clock scan, next day of week} {
+ clock format [clock scan "next wednesday" -base [clock scan 20000112]] \
+ -format {%b %d, %Y}
+} "Jan 19, 2000"
+test clock-34.39 {clock scan, day of week} {
+ clock format [clock scan "thursday" -base [clock scan 20000112]] \
+ -format {%b %d, %Y}
+} "Jan 13, 2000"
+test clock-34.40 {clock scan, next day of week} {
+ clock format [clock scan "next thursday" -base [clock scan 20000112]] \
+ -format {%b %d, %Y}
+} "Jan 20, 2000"
+
+# weekday specification and base.
+test clock-34.41 {2nd monday in november} {
+ set res {}
+ foreach i {91 92 93 94 95 96} {
+ set nov8th [clock scan 11/8/$i]
+ set monday [clock scan monday -base $nov8th]
+ lappend res [clock format $monday -format %Y-%m-%d]
+ }
+ set res
+} {1991-11-11 1992-11-09 1993-11-08 1994-11-14 1995-11-13 1996-11-11}
+test clock-34.42 {2nd monday in november (2nd try)} {
+ set res {}
+ foreach i {91 92 93 94 95 96} {
+ set nov1th [clock scan 11/1/$i]
+ set monday [clock scan "2 monday" -base $nov1th]
+ lappend res [clock format $monday -format %Y-%m-%d]
+ }
+ set res
+} {1991-11-11 1992-11-09 1993-11-08 1994-11-14 1995-11-13 1996-11-11}
+test clock-34.43 {last monday in november} {
+ set res {}
+ foreach i {91 92 93 94 95 96} {
+ set dec1th [clock scan 12/1/$i]
+ set monday [clock scan "monday 1 week ago" -base $dec1th]
+ lappend res [clock format $monday -format %Y-%m-%d]
+ }
+ set res
+} {1991-11-25 1992-11-30 1993-11-29 1994-11-28 1995-11-27 1996-11-25}
+
+test clock-34.44 {2nd monday in november} {
+ set res {}
+ foreach i {91 92 93 94 95 96} {
+ set nov8th [clock scan 11/8/$i -gmt 1]
+ set monday [clock scan monday -base $nov8th -gmt 1]
+ lappend res [clock format $monday -format %Y-%m-%d -gmt 1]
+ }
+ set res
+} {1991-11-11 1992-11-09 1993-11-08 1994-11-14 1995-11-13 1996-11-11}
+test clock-34.45 {2nd monday in november (2nd try)} {
+ set res {}
+ foreach i {91 92 93 94 95 96} {
+ set nov1th [clock scan 11/1/$i -gmt 1]
+ set monday [clock scan "2 monday" -base $nov1th -gmt 1]
+ lappend res [clock format $monday -format %Y-%m-%d -gmt 1]
+ }
+ set res
+} {1991-11-11 1992-11-09 1993-11-08 1994-11-14 1995-11-13 1996-11-11}
+test clock-34.46 {last monday in november} {
+ set res {}
+ foreach i {91 92 93 94 95 96} {
+ set dec1th [clock scan 12/1/$i -gmt 1]
+ set monday [clock scan "monday 1 week ago" -base $dec1th -gmt 1]
+ lappend res [clock format $monday -format %Y-%m-%d -gmt 1]
+ }
+ set res
+} {1991-11-25 1992-11-30 1993-11-29 1994-11-28 1995-11-27 1996-11-25}
+test clock-34.47 {ago with multiple relative units} {
+ set base [clock scan "12/31/1999 00:00:00"]
+ set res [clock scan "2 days 2 hours ago" -base $base]
+ expr {$base - $res}
+} 180000
+
+test clock-34.48 {more than one ToD} {*}{
+ -body {clock scan {10:00 11:00}}
+ -returnCodes error
+ -result {unable to convert date-time string "10:00 11:00": more than one time of day in string}
+}
+
+test clock-34.49 {more than one date} {*}{
+ -body {clock scan {1/1/2001 2/2/2002}}
+ -returnCodes error
+ -result {unable to convert date-time string "1/1/2001 2/2/2002": more than one date in string}
+}
+
+test clock-34.50 {more than one time zone} {*}{
+ -body {clock scan {10:00 EST CST}}
+ -returnCodes error
+ -result {unable to convert date-time string "10:00 EST CST": more than one time zone in string}
+}
+
+test clock-34.51 {more than one weekday} {*}{
+ -body {clock scan {Monday Tuesday}}
+ -returnCodes error
+ -result {unable to convert date-time string "Monday Tuesday": more than one weekday in string}
+}
+
+test clock-34.52 {more than one ordinal month} {*}{
+ -body {clock scan {next January next March}}
+ -returnCodes error
+ -result {unable to convert date-time string "next January next March": more than one ordinal month in string}
+}
+
+
+
+# clock seconds
+test clock-35.1 {clock seconds tests} {
+ expr [clock seconds]+1
+ concat {}
+} {}
+test clock-35.2 {clock seconds tests} {
+ list [catch {clock seconds foo} msg] $msg
+} {1 {wrong # args: should be "clock seconds"}}
+test clock-35.3 {clock seconds tests} {
+ set start [clock seconds]
+ after 2000
+ set end [clock seconds]
+ expr "$end > $start"
+} {1}
+
+
+test clock-36.1 {clock scan next monthname} {
+ clock format [clock scan "next june" -base [clock scan "june 1, 2000"]] \
+ -format %m.%Y
+} "06.2001"
+test clock-36.2 {clock scan next monthname} {
+ clock format [clock scan "next july" -base [clock scan "june 1, 2000"]] \
+ -format %m.%Y
+} "07.2000"
+test clock-36.3 {clock scan next monthname} {
+ clock format [clock scan "next may" -base [clock scan "june 1, 2000"]] \
+ -format %m.%Y
+} "05.2001"
+
+test clock-37.1 {%s gmt testing} {
+ set s [clock seconds]
+ set a [clock format $s -format %s -gmt 0]
+ set b [clock format $s -format %s -gmt 1]
+ # %s, being the difference between local and Greenwich, does not
+ # depend on the time zone.
+ set c [expr {$b-$a}]
+} {0}
+
+test clock-38.1 {regression - convertUTCToLocalViaC - east of Greenwich} \
+ -setup {
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ }
+ set env(TZ) CET-01:00CEST-02:00,M3.5.0/02:00,M10.5.0/03:00
+ } \
+ -body {
+ clock format 0 -format %H:%M:%S -timezone :localtime
+ } \
+ -cleanup {
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ unset oldTZ
+ } else {
+ unset env(TZ)
+ }
+ } \
+ -result {01:00:00}
+
+test clock-38.2 {make sure TZ is not cached after unset} \
+ -setup {
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ unset env(TZ)
+ }
+ if { [info exists env(TCL_TZ)] } {
+ set oldTCLTZ $env(TCL_TZ)
+ unset env(TCL_TZ)
+ }
+ } \
+ -body {
+ set t1 [clock format 0]
+ # a time zone that is unlikely to anywhere
+ set env(TZ) "+04:20"
+ set t2 [clock format 0]
+ unset env(TZ)
+ set t3 [clock format 0]
+ expr {$t1 eq $t3 && $t1 ne $t2}
+ } \
+ -cleanup {
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ unset oldTZ
+ }
+ if { [info exists oldTclTZ] } {
+ set env(TCL_TZ) $oldTclTZ
+ unset oldTclTZ
+ }
+ } \
+ -result 1
+
+
+test clock-39.1 {regression - synonym timezones} {
+ clock format 0 -format {%H:%M:%S} -timezone :US/Eastern
+} {19:00:00}
+
+test clock-40.1 {regression - bad month with -timezone :localtime} \
+ -setup {
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ }
+ set env(TZ) UTC0
+ } \
+ -body {
+ clock scan 2000-01-01T00:00:00 -timezone :localtime \
+ -format %Y-%m-%dT%H:%M:%S
+ } \
+ -cleanup {
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ unset oldTZ
+ } else {
+ unset env(TZ)
+ }
+ } \
+ -result 946684800
+
+test clock-41.1 {regression test - format group %k when hour is 0 } {
+ clock format 0 -format %k -gmt true
+} { 0}
+
+test clock-42.1 {regression test - %z in :localtime when west of Greenwich } \
+ -setup {
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ }
+ set env(TZ) EST5
+ } \
+ -body {
+ clock format 0 -format %z -timezone :localtime
+ } \
+ -cleanup {
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ unset oldTZ
+ } else {
+ unset env(TZ)
+ }
+ } \
+ -result {-0500}
+
+# 43.1 was a bad test - mktime returning -1 is an error according to posix.
+
+test clock-44.1 {regression test - time zone name containing hyphen } \
+ -setup {
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ }
+ set env(TZ) US/East-Indiana
+ } \
+ -body {
+ clock format 1098466496 -format %H:%M:%S%z -timezone US/East-Indiana
+ } \
+ -cleanup {
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ unset oldTZ
+ } else {
+ unset env(TZ)
+ }
+ } \
+ -result {12:34:56-0500}
+
+test clock-45.1 {regression test - time zone containing only two digits} \
+ -body {
+ clock scan 1985-04-12T10:15:30+04 -format %Y-%m-%dT%H:%M:%S%Z
+ } \
+ -result 482134530
+
+test clock-46.1 {regression test - month zero} \
+ -body {
+ clock scan 2004-00-00 -format %Y-%m-%d
+ } -result [clock scan 2003-11-30 -format %Y-%m-%d]
+test clock-46.2 {regression test - month zero} \
+ -body {
+ clock scan 20040000
+ } -result [clock scan 2003-11-30 -format %Y-%m-%d]
+test clock-46.3 {regression test - month thirteen} \
+ -body {
+ clock scan 2004-13-01 -format %Y-%m-%d
+ } -result [clock scan 2005-01-01 -format %Y-%m-%d]
+test clock-46.4 {regression test - month thirteen} \
+ -body {
+ clock scan 20041301
+ } -result [clock scan 2005-01-01 -format %Y-%m-%d]
+
+test clock-47.1 {regression test - four-digit time} {
+ clock scan 0012
+} [clock scan 0012 -format %H%M]
+test clock-47.2 {regression test - four digit time} {
+ clock scan 0039
+} [clock scan 0039 -format %H%M]
+
+test clock-48.1 {Bug 1185933: 'i' destroyed by clock init} -setup {
+ interp create child
+} -body {
+ interp eval child {
+ set i 12345
+ clock format 0
+ list [catch { set i } result] $result
+ }
+} -cleanup {
+ interp delete child
+} -result {0 12345}
+
+test clock-49.1 {regression test - localtime with negative arg (Bug 1237907)} \
+ -body {
+ list [catch {
+ clock format -86400 -timezone :localtime -format %Y
+ } result] $result
+ } \
+ -match regexp \
+ -result {0 1969|1 {localtime failed \(clock value may be too large/small to represent\)}}
+
+test clock-49.2 {regression test - missing time zone file (Bug 1237907)} \
+ -constraints win \
+ -setup {
+ # override the registry so that the test takes place in New York time
+ namespace eval ::tcl::clock {
+ namespace import -force ::testClock::registry
+ }
+ set noreg [info exists ::tcl::clock::NoRegistry]
+ if {$noreg} {unset ::tcl::clock::NoRegistry}
+ if { [info exists env(TZ)] } {
+ set oldTZ $env(TZ)
+ unset env(TZ)
+ }
+ if { [info exists env(TCL_TZ)] } {
+ set oldTclTZ $env(TCL_TZ)
+ unset env(TCL_TZ)
+ }
+ # make it so New York time is a missing file
+ dict set ::tcl::clock::WinZoneInfo \
+ {-18000 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} \
+ :No/Such/File
+ ::tcl::clock::ClearCaches
+ } \
+ -body {
+ list [::tcl::clock::GuessWindowsTimeZone] \
+ [clock format 0 -locale system -format "%H:%M:%S %Z"] \
+ [clock format -86400 -format "%Y"]
+ } \
+ -cleanup {
+ # restore the registry and environment
+ namespace eval ::tcl::clock {
+ rename registry {}
+ }
+ if {$noreg} {set ::tcl::clock::NoRegistry {}}
+ if { [info exists oldTclTZ] } {
+ set env(TCL_TZ) $oldTclTZ
+ }
+ if { [info exists oldTZ] } {
+ set env(TZ) $oldTZ
+ }
+ # put New York back on the map
+ dict set ::tcl::clock::WinZoneInfo \
+ {-18000 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} \
+ :America/New_York
+ ::tcl::clock::ClearCaches
+ } \
+ -result {<-0500>+05:00:00<-0400>+04:00:00,M3.2.0/02:00:00,M11.1.0/02:00:00 {19:00:00 -0500} 1969}
+
+test clock-50.1 {format / scan -1 as a local time} {
+ if {[catch {
+ clock scan \
+ [clock format -1 -format %Y%m%d%H%M%S -timezone :localtime] \
+ -format %Y%m%d%H%M%S -timezone :localtime
+ } result]} {
+ if { [regexp " too large" $result] } {
+ set result -1
+ }
+ }
+ set result
+} -1
+test clock-50.2 {format / scan -2 as a local time} {
+ if {[catch {
+ clock scan \
+ [clock format -2 -format %Y%m%d%H%M%S -timezone :localtime] \
+ -format %Y%m%d%H%M%S -timezone :localtime
+ } result]} {
+ if { [regexp " too large" $result] } {
+ set result -2
+ }
+ }
+ set result
+} -2
+
+test clock-51.1 {correct conversion of times in Sydney} {
+ # Paul Mackerras reported a bug where DST rollover in New South Wales
+ # was miscalculated. The problem was that tclZIC.tcl had a
+ # typo in the switch case where DST begins/ends at a given time
+ # Standard Time (that is, winter time).
+ set result {}
+ foreach t {1130601599 1130601600 1130637599 1130637600} {
+ lappend result [clock format $t -format %H:%M:%S \
+ -timezone :Australia/Sydney]
+ }
+ set result
+} {01:59:59 03:00:00 12:59:59 13:00:00}
+
+test clock-52.1 {Posix timezone and conversion on last Sunday} {
+ # Martin Lemburg reported a bug where if tzdata is missing, then
+ # times are converted incorrectly in locales where DST conversion
+ # happens in the last (nominal 5th) week of a month.
+ set result {}
+ set timezone <MEZ>-01:00:00<MESZ>-02:00:00,M3.5.0/02:00:00,M10.5.0/01:00:00
+ foreach t {1143334799 1143334800} {
+ lappend result [clock format $t -format %H:%M:%S -timezone $timezone] \
+ [clock format $t -format %H:%M:%S -timezone :Europe/Berlin]
+ }
+ set result
+} {01:59:59 01:59:59 03:00:00 03:00:00}
+
+test clock-52.2 {correct conversion of times in Europe} {
+ # [Bug 2207436]
+ set result {}
+ foreach t [list 1206838799 1206838800 1224982799 1224982800] {
+ lappend result [clock format $t -format %H:%M:%S \
+ -timezone MET-1METDST]
+ lappend result [clock format $t -format %H:%M:%S \
+ -timezone MET0METDST]
+ }
+ set result
+} {01:59:59 00:59:59 03:00:00 02:00:00 02:59:59 01:59:59 02:00:00 01:00:00}
+
+test clock-52.3 {correct conversion of times in Russia} {
+ # [Bug 2207436]
+ set result {}
+ foreach t [list 1206799199 1206799200 1224943199 1224943200] {
+ lappend result [clock format $t -format %H:%M:%S \
+ -timezone WST-12WSTDST]
+ }
+ set result
+} {01:59:59 03:00:00 02:59:59 02:00:00}
+
+test clock-52.4 {correct conversion of times in USA} {
+ # [Bug 2207436]
+ set result {}
+ foreach t [list 1268549999 1268550000 1257055199 1257055200] {
+ lappend result [clock format $t -format %H:%M:%S \
+ -timezone EST5EDT]
+ }
+ set result
+} {01:59:59 03:00:00 01:59:59 01:00:00}
+
+# Regression test for Bug # 1505383
+
+test clock-53.1 {%EC %Ey} {
+ clock format 0 -gmt true -locale en_US_roman -format %EC%Ey
+} mcmlxx
+
+# Test that glob-special characters can be handled in [clock]
+
+test clock-54.1 {glob specials in [clock format]} \
+ -setup {
+ clock format 0 -gmt 1 -format %Y
+ } \
+ -body {
+ clock format 0 -gmt 1 -format {*[%Y%m%d]*}
+ } \
+ -result {*[19700101]*}
+test clock-54.2 {glob specials in [clock scan]} \
+ -setup {
+ clock scan 1970 -gmt 1 -format %Y
+ } \
+ -body {
+ clock scan {*[19700101]*} -format {*[%Y%m%d]*} -gmt 1
+ } \
+ -result 0
+
+test clock-55.1 {Common Era} {
+ clock format -62135769600 -gmt 1 -format {%d %m %Y %EE}
+} {01 01 0001 C.E.}
+test clock-55.2 {Common Era} {
+ clock format -62135769600 -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} {01 01 0001 Anno Domini}
+test clock-55.3 {Before the Common Era} {
+ clock format -62135769601 -gmt 1 -format {%d %m %Y %EE}
+} {31 12 0001 B.C.E.}
+test clock-55.4 {Before the Common Era} {
+ clock format -62135769601 -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} {31 12 0001 Before Christ}
+test clock-55.5 {Common Era} {
+ clock scan {01 01 0001 C.E.} \
+ -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135769600
+test clock-55.6 {Common Era} {
+ clock scan {01 01 0001 A.D.} \
+ -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135769600
+test clock-55.7 {Common Era} {
+ clock scan {01 01 0001 Anno Domini} \
+ -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135769600
+test clock-55.8 {Before the Common Era} {
+ clock scan {31 12 0001 B.C.E.} \
+ -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135856000
+test clock-55.9 {Common Era} {
+ clock scan {31 12 0001 B.C.} \
+ -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135856000
+test clock-55.10 {Common Era} {
+ clock scan {31 12 0001 Before Christ} \
+ -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135856000
+
+test clock-56.1 {use of zoneinfo, version 1} {*}{
+ -setup {
+ clock format [clock seconds]
+ set tzdir [makeDirectory zoneinfo]
+ set tzdir2 [makeDirectory Test $tzdir]
+ set tzfile [makeFile {} PhoenixOne $tzdir2]
+ set f [open $tzfile wb]
+ puts -nonewline $f [binary format c* {
+ 0x54 0x5a 0x69 0x66 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x03
+ 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0a
+ 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x0c 0x9e 0xa6 0x3a 0x90
+ 0x9f 0xbb 0x07 0x80 0xa0 0x86 0x1c 0x90 0xa1 0x9a 0xe9 0x80
+ 0xcb 0x89 0x0c 0x90 0xcf 0x17 0xdf 0x1c 0xcf 0x8f 0xe5 0xac
+ 0xd0 0x81 0x1a 0x1c 0xfa 0xf8 0x75 0x10 0xfb 0xe8 0x58 0x00
+ 0x00 0x01 0x00 0x01 0x02 0x01 0x02 0x01 0x00 0x01 0xff 0xff
+ 0xab 0xa0 0x01 0x00 0xff 0xff 0x9d 0x90 0x00 0x04 0xff 0xff
+ 0xab 0xa0 0x01 0x08 0x4d 0x44 0x54 0x00 0x4d 0x53 0x54 0x00
+ 0x4d 0x57 0x54 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ }]
+ close $f
+ set ::tcl::clock::ZoneinfoPaths \
+ [linsert $::tcl::clock::ZoneinfoPaths 0 $tzdir]
+ ::tcl::clock::ClearCaches
+ }
+ -cleanup {
+ set ::tcl::clock::ZoneinfoPaths \
+ [lrange $::tcl::clock::ZoneinfoPaths 1 end]
+ ::tcl::clock::ClearCaches
+ removeFile PhoenixOne $tzdir2
+ removeDirectory Test $tzdir
+ removeDirectory zoneinfo
+ }
+ -body {
+ clock format 1072940400 -timezone :Test/PhoenixOne \
+ -format {%Y-%m-%d %H:%M:%S %Z}
+ }
+ -result {2004-01-01 00:00:00 MST}
+}
+
+test clock-56.2 {use of zoneinfo, version 2} {*}{
+ -setup {
+ clock format [clock seconds]
+ set tzdir [makeDirectory zoneinfo]
+ set tzdir2 [makeDirectory Test $tzdir]
+ set tzfile [makeFile {} PhoenixTwo $tzdir2]
+ set f [open $tzfile wb]
+ puts -nonewline $f [binary format c* {
+ 0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x03
+ 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0a
+ 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x0c 0x9e 0xa6 0x3a 0x90
+ 0x9f 0xbb 0x07 0x80 0xa0 0x86 0x1c 0x90 0xa1 0x9a 0xe9 0x80
+ 0xcb 0x89 0x0c 0x90 0xcf 0x17 0xdf 0x1c 0xcf 0x8f 0xe5 0xac
+ 0xd0 0x81 0x1a 0x1c 0xfa 0xf8 0x75 0x10 0xfb 0xe8 0x58 0x00
+ 0x00 0x01 0x00 0x01 0x02 0x01 0x02 0x01 0x00 0x01 0xff 0xff
+ 0xab 0xa0 0x01 0x00 0xff 0xff 0x9d 0x90 0x00 0x04 0xff 0xff
+ 0xab 0xa0 0x01 0x08 0x4d 0x44 0x54 0x00 0x4d 0x53 0x54 0x00
+ 0x4d 0x57 0x54 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x54 0x5a
+ 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x04 0x00 0x00
+ 0x00 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0b 0x00 0x00
+ 0x00 0x04 0x00 0x00 0x00 0x10 0xff 0xff 0xff 0xff 0x5e 0x04
+ 0x0c 0xb0 0xff 0xff 0xff 0xff 0x9e 0xa6 0x3a 0x90 0xff 0xff
+ 0xff 0xff 0x9f 0xbb 0x07 0x80 0xff 0xff 0xff 0xff 0xa0 0x86
+ 0x1c 0x90 0xff 0xff 0xff 0xff 0xa1 0x9a 0xe9 0x80 0xff 0xff
+ 0xff 0xff 0xcb 0x89 0x0c 0x90 0xff 0xff 0xff 0xff 0xcf 0x17
+ 0xdf 0x1c 0xff 0xff 0xff 0xff 0xcf 0x8f 0xe5 0xac 0xff 0xff
+ 0xff 0xff 0xd0 0x81 0x1a 0x1c 0xff 0xff 0xff 0xff 0xfa 0xf8
+ 0x75 0x10 0xff 0xff 0xff 0xff 0xfb 0xe8 0x58 0x00 0x02 0x01
+ 0x02 0x01 0x02 0x03 0x02 0x03 0x02 0x01 0x02 0xff 0xff 0x96
+ 0xee 0x00 0x00 0xff 0xff 0xab 0xa0 0x01 0x04 0xff 0xff 0x9d
+ 0x90 0x00 0x08 0xff 0xff 0xab 0xa0 0x01 0x0c 0x4c 0x4d 0x54
+ 0x00 0x4d 0x44 0x54 0x00 0x4d 0x53 0x54 0x00 0x4d 0x57 0x54
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0a 0x4d 0x53
+ 0x54 0x37 0x0a
+ }]
+ close $f
+ set ::tcl::clock::ZoneinfoPaths \
+ [linsert $::tcl::clock::ZoneinfoPaths 0 $tzdir]
+ ::tcl::clock::ClearCaches
+ }
+ -cleanup {
+ set ::tcl::clock::ZoneinfoPaths \
+ [lrange $::tcl::clock::ZoneinfoPaths 1 end]
+ ::tcl::clock::ClearCaches
+ removeFile PhoenixTwo $tzdir2
+ removeDirectory Test $tzdir
+ removeDirectory zoneinfo
+ }
+ -body {
+ clock format 1072940400 -timezone :Test/PhoenixTwo \
+ -format {%Y-%m-%d %H:%M:%S %Z}
+ }
+ -result {2004-01-01 00:00:00 MST}
+}
+
+test clock-56.3 {use of zoneinfo, version 2, Y2038 compliance} {*}{
+ -setup {
+ clock format [clock seconds]
+ set tzdir [makeDirectory zoneinfo]
+ set tzdir2 [makeDirectory Test $tzdir]
+ set tzfile [makeFile {} TijuanaTwo $tzdir2]
+ set f [open $tzfile wb]
+ puts -nonewline $f [binary format c* {
+ 0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x06 0x00 0x00
+ 0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x95 0x00 0x00 0x00
+ 0x06 0x00 0x00 0x00 0x18 0xa5 0xb6 0xf6 0x80 0xa9 0x79 0x4f 0x70
+ 0xaf 0xf2 0x7c 0xf0 0xb6 0x66 0x64 0x70 0xb7 0x1b 0x10 0x00 0xb8
+ 0x0a 0xf2 0xf0 0xcb 0xea 0x8d 0x80 0xd2 0x23 0xf4 0x70 0xd2 0x99
+ 0xba 0x70 0xd7 0x1b 0x59 0x00 0xd8 0x91 0xb4 0xf0 0xe2 0x7e 0x59
+ 0xa0 0xe3 0x49 0x52 0x90 0xe4 0x5e 0x3b 0xa0 0xe5 0x29 0x34 0x90
+ 0xe6 0x47 0x58 0x20 0xe7 0x12 0x51 0x10 0xe8 0x27 0x3a 0x20 0xe8
+ 0xf2 0x33 0x10 0xea 0x07 0x1c 0x20 0xea 0xd2 0x15 0x10 0xeb 0xe6
+ 0xfe 0x20 0xec 0xb1 0xf7 0x10 0xed 0xc6 0xe0 0x20 0xee 0x91 0xd9
+ 0x10 0x0b 0xe0 0xaf 0xa0 0x0c 0xd9 0xcd 0x10 0x0d 0xc0 0x91 0xa0
+ 0x0e 0xb9 0xaf 0x10 0x0f 0xa9 0xae 0x20 0x10 0x99 0x91 0x10 0x11
+ 0x89 0x90 0x20 0x12 0x79 0x73 0x10 0x13 0x69 0x72 0x20 0x14 0x59
+ 0x55 0x10 0x15 0x49 0x54 0x20 0x16 0x39 0x37 0x10 0x17 0x29 0x36
+ 0x20 0x18 0x22 0x53 0x90 0x19 0x09 0x18 0x20 0x1a 0x02 0x35 0x90
+ 0x1a 0xf2 0x34 0xa0 0x1b 0xe2 0x17 0x90 0x1c 0xd2 0x16 0xa0 0x1d
+ 0xc1 0xf9 0x90 0x1e 0xb1 0xf8 0xa0 0x1f 0xa1 0xdb 0x90 0x20 0x76
+ 0x2b 0x20 0x21 0x81 0xbd 0x90 0x22 0x56 0x0d 0x20 0x23 0x6a 0xda
+ 0x10 0x24 0x35 0xef 0x20 0x25 0x4a 0xbc 0x10 0x26 0x15 0xd1 0x20
+ 0x27 0x2a 0x9e 0x10 0x27 0xfe 0xed 0xa0 0x29 0x0a 0x80 0x10 0x29
+ 0xde 0xcf 0xa0 0x2a 0xea 0x62 0x10 0x2b 0xbe 0xb1 0xa0 0x2c 0xd3
+ 0x7e 0x90 0x2d 0x9e 0x93 0xa0 0x2e 0xb3 0x60 0x90 0x2f 0x7e 0x75
+ 0xa0 0x30 0x93 0x42 0x90 0x31 0x67 0x92 0x20 0x32 0x73 0x24 0x90
+ 0x33 0x47 0x74 0x20 0x34 0x53 0x06 0x90 0x35 0x27 0x56 0x20 0x36
+ 0x32 0xe8 0x90 0x37 0x07 0x38 0x20 0x38 0x1c 0x05 0x10 0x38 0xe7
+ 0x1a 0x20 0x39 0xfb 0xe7 0x10 0x3a 0xc6 0xfc 0x20 0x3b 0xdb 0xc9
+ 0x10 0x3c 0xb0 0x18 0xa0 0x3d 0xbb 0xab 0x10 0x3e 0x8f 0xfa 0xa0
+ 0x3f 0x9b 0x8d 0x10 0x40 0x6f 0xdc 0xa0 0x41 0x84 0xa9 0x90 0x42
+ 0x4f 0xbe 0xa0 0x43 0x64 0x8b 0x90 0x44 0x2f 0xa0 0xa0 0x45 0x44
+ 0x6d 0x90 0x46 0x0f 0x82 0xa0 0x47 0x24 0x4f 0x90 0x47 0xf8 0x9f
+ 0x20 0x49 0x04 0x31 0x90 0x49 0xd8 0x81 0x20 0x4a 0xe4 0x13 0x90
+ 0x4b 0xb8 0x63 0x20 0x4c 0xcd 0x30 0x10 0x4d 0x98 0x45 0x20 0x4e
+ 0xad 0x12 0x10 0x4f 0x78 0x27 0x20 0x50 0x8c 0xf4 0x10 0x51 0x61
+ 0x43 0xa0 0x52 0x6c 0xd6 0x10 0x53 0x41 0x25 0xa0 0x54 0x4c 0xb8
+ 0x10 0x55 0x21 0x07 0xa0 0x56 0x2c 0x9a 0x10 0x57 0x00 0xe9 0xa0
+ 0x58 0x15 0xb6 0x90 0x58 0xe0 0xcb 0xa0 0x59 0xf5 0x98 0x90 0x5a
+ 0xc0 0xad 0xa0 0x5b 0xd5 0x7a 0x90 0x5c 0xa9 0xca 0x20 0x5d 0xb5
+ 0x5c 0x90 0x5e 0x89 0xac 0x20 0x5f 0x95 0x3e 0x90 0x60 0x69 0x8e
+ 0x20 0x61 0x7e 0x5b 0x10 0x62 0x49 0x70 0x20 0x63 0x5e 0x3d 0x10
+ 0x64 0x29 0x52 0x20 0x65 0x3e 0x1f 0x10 0x66 0x12 0x6e 0xa0 0x67
+ 0x1e 0x01 0x10 0x67 0xf2 0x50 0xa0 0x68 0xfd 0xe3 0x10 0x69 0xd2
+ 0x32 0xa0 0x6a 0xdd 0xc5 0x10 0x6b 0xb2 0x14 0xa0 0x6c 0xc6 0xe1
+ 0x90 0x6d 0x91 0xf6 0xa0 0x6e 0xa6 0xc3 0x90 0x6f 0x71 0xd8 0xa0
+ 0x70 0x86 0xa5 0x90 0x71 0x5a 0xf5 0x20 0x72 0x66 0x87 0x90 0x73
+ 0x3a 0xd7 0x20 0x74 0x46 0x69 0x90 0x75 0x1a 0xb9 0x20 0x76 0x2f
+ 0x86 0x10 0x76 0xfa 0x9b 0x20 0x78 0x0f 0x68 0x10 0x78 0xda 0x7d
+ 0x20 0x79 0xef 0x4a 0x10 0x7a 0xba 0x5f 0x20 0x7b 0xcf 0x2c 0x10
+ 0x7c 0xa3 0x7b 0xa0 0x7d 0xaf 0x0e 0x10 0x7e 0x83 0x5d 0xa0 0x7f
+ 0x8e 0xf0 0x10 0x01 0x02 0x01 0x02 0x03 0x02 0x04 0x05 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0xff 0xff 0x92 0x4c
+ 0x00 0x00 0xff 0xff 0x9d 0x90 0x00 0x04 0xff 0xff 0x8f 0x80 0x00
+ 0x08 0xff 0xff 0x9d 0x90 0x01 0x0c 0xff 0xff 0x9d 0x90 0x01 0x10
+ 0xff 0xff 0x9d 0x90 0x01 0x14 0x4c 0x4d 0x54 0x00 0x4d 0x53 0x54
+ 0x00 0x50 0x53 0x54 0x00 0x50 0x44 0x54 0x00 0x50 0x57 0x54 0x00
+ 0x50 0x50 0x54 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00
+ 0x00 0x00 0x01 0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x06 0x00 0x00 0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x95
+ 0x00 0x00 0x00 0x06 0x00 0x00 0x00 0x18 0xff 0xff 0xff 0xff 0xa5
+ 0xb6 0xf6 0x80 0xff 0xff 0xff 0xff 0xa9 0x79 0x4f 0x70 0xff 0xff
+ 0xff 0xff 0xaf 0xf2 0x7c 0xf0 0xff 0xff 0xff 0xff 0xb6 0x66 0x64
+ 0x70 0xff 0xff 0xff 0xff 0xb7 0x1b 0x10 0x00 0xff 0xff 0xff 0xff
+ 0xb8 0x0a 0xf2 0xf0 0xff 0xff 0xff 0xff 0xcb 0xea 0x8d 0x80 0xff
+ 0xff 0xff 0xff 0xd2 0x23 0xf4 0x70 0xff 0xff 0xff 0xff 0xd2 0x99
+ 0xba 0x70 0xff 0xff 0xff 0xff 0xd7 0x1b 0x59 0x00 0xff 0xff 0xff
+ 0xff 0xd8 0x91 0xb4 0xf0 0xff 0xff 0xff 0xff 0xe2 0x7e 0x59 0xa0
+ 0xff 0xff 0xff 0xff 0xe3 0x49 0x52 0x90 0xff 0xff 0xff 0xff 0xe4
+ 0x5e 0x3b 0xa0 0xff 0xff 0xff 0xff 0xe5 0x29 0x34 0x90 0xff 0xff
+ 0xff 0xff 0xe6 0x47 0x58 0x20 0xff 0xff 0xff 0xff 0xe7 0x12 0x51
+ 0x10 0xff 0xff 0xff 0xff 0xe8 0x27 0x3a 0x20 0xff 0xff 0xff 0xff
+ 0xe8 0xf2 0x33 0x10 0xff 0xff 0xff 0xff 0xea 0x07 0x1c 0x20 0xff
+ 0xff 0xff 0xff 0xea 0xd2 0x15 0x10 0xff 0xff 0xff 0xff 0xeb 0xe6
+ 0xfe 0x20 0xff 0xff 0xff 0xff 0xec 0xb1 0xf7 0x10 0xff 0xff 0xff
+ 0xff 0xed 0xc6 0xe0 0x20 0xff 0xff 0xff 0xff 0xee 0x91 0xd9 0x10
+ 0x00 0x00 0x00 0x00 0x0b 0xe0 0xaf 0xa0 0x00 0x00 0x00 0x00 0x0c
+ 0xd9 0xcd 0x10 0x00 0x00 0x00 0x00 0x0d 0xc0 0x91 0xa0 0x00 0x00
+ 0x00 0x00 0x0e 0xb9 0xaf 0x10 0x00 0x00 0x00 0x00 0x0f 0xa9 0xae
+ 0x20 0x00 0x00 0x00 0x00 0x10 0x99 0x91 0x10 0x00 0x00 0x00 0x00
+ 0x11 0x89 0x90 0x20 0x00 0x00 0x00 0x00 0x12 0x79 0x73 0x10 0x00
+ 0x00 0x00 0x00 0x13 0x69 0x72 0x20 0x00 0x00 0x00 0x00 0x14 0x59
+ 0x55 0x10 0x00 0x00 0x00 0x00 0x15 0x49 0x54 0x20 0x00 0x00 0x00
+ 0x00 0x16 0x39 0x37 0x10 0x00 0x00 0x00 0x00 0x17 0x29 0x36 0x20
+ 0x00 0x00 0x00 0x00 0x18 0x22 0x53 0x90 0x00 0x00 0x00 0x00 0x19
+ 0x09 0x18 0x20 0x00 0x00 0x00 0x00 0x1a 0x02 0x35 0x90 0x00 0x00
+ 0x00 0x00 0x1a 0xf2 0x34 0xa0 0x00 0x00 0x00 0x00 0x1b 0xe2 0x17
+ 0x90 0x00 0x00 0x00 0x00 0x1c 0xd2 0x16 0xa0 0x00 0x00 0x00 0x00
+ 0x1d 0xc1 0xf9 0x90 0x00 0x00 0x00 0x00 0x1e 0xb1 0xf8 0xa0 0x00
+ 0x00 0x00 0x00 0x1f 0xa1 0xdb 0x90 0x00 0x00 0x00 0x00 0x20 0x76
+ 0x2b 0x20 0x00 0x00 0x00 0x00 0x21 0x81 0xbd 0x90 0x00 0x00 0x00
+ 0x00 0x22 0x56 0x0d 0x20 0x00 0x00 0x00 0x00 0x23 0x6a 0xda 0x10
+ 0x00 0x00 0x00 0x00 0x24 0x35 0xef 0x20 0x00 0x00 0x00 0x00 0x25
+ 0x4a 0xbc 0x10 0x00 0x00 0x00 0x00 0x26 0x15 0xd1 0x20 0x00 0x00
+ 0x00 0x00 0x27 0x2a 0x9e 0x10 0x00 0x00 0x00 0x00 0x27 0xfe 0xed
+ 0xa0 0x00 0x00 0x00 0x00 0x29 0x0a 0x80 0x10 0x00 0x00 0x00 0x00
+ 0x29 0xde 0xcf 0xa0 0x00 0x00 0x00 0x00 0x2a 0xea 0x62 0x10 0x00
+ 0x00 0x00 0x00 0x2b 0xbe 0xb1 0xa0 0x00 0x00 0x00 0x00 0x2c 0xd3
+ 0x7e 0x90 0x00 0x00 0x00 0x00 0x2d 0x9e 0x93 0xa0 0x00 0x00 0x00
+ 0x00 0x2e 0xb3 0x60 0x90 0x00 0x00 0x00 0x00 0x2f 0x7e 0x75 0xa0
+ 0x00 0x00 0x00 0x00 0x30 0x93 0x42 0x90 0x00 0x00 0x00 0x00 0x31
+ 0x67 0x92 0x20 0x00 0x00 0x00 0x00 0x32 0x73 0x24 0x90 0x00 0x00
+ 0x00 0x00 0x33 0x47 0x74 0x20 0x00 0x00 0x00 0x00 0x34 0x53 0x06
+ 0x90 0x00 0x00 0x00 0x00 0x35 0x27 0x56 0x20 0x00 0x00 0x00 0x00
+ 0x36 0x32 0xe8 0x90 0x00 0x00 0x00 0x00 0x37 0x07 0x38 0x20 0x00
+ 0x00 0x00 0x00 0x38 0x1c 0x05 0x10 0x00 0x00 0x00 0x00 0x38 0xe7
+ 0x1a 0x20 0x00 0x00 0x00 0x00 0x39 0xfb 0xe7 0x10 0x00 0x00 0x00
+ 0x00 0x3a 0xc6 0xfc 0x20 0x00 0x00 0x00 0x00 0x3b 0xdb 0xc9 0x10
+ 0x00 0x00 0x00 0x00 0x3c 0xb0 0x18 0xa0 0x00 0x00 0x00 0x00 0x3d
+ 0xbb 0xab 0x10 0x00 0x00 0x00 0x00 0x3e 0x8f 0xfa 0xa0 0x00 0x00
+ 0x00 0x00 0x3f 0x9b 0x8d 0x10 0x00 0x00 0x00 0x00 0x40 0x6f 0xdc
+ 0xa0 0x00 0x00 0x00 0x00 0x41 0x84 0xa9 0x90 0x00 0x00 0x00 0x00
+ 0x42 0x4f 0xbe 0xa0 0x00 0x00 0x00 0x00 0x43 0x64 0x8b 0x90 0x00
+ 0x00 0x00 0x00 0x44 0x2f 0xa0 0xa0 0x00 0x00 0x00 0x00 0x45 0x44
+ 0x6d 0x90 0x00 0x00 0x00 0x00 0x46 0x0f 0x82 0xa0 0x00 0x00 0x00
+ 0x00 0x47 0x24 0x4f 0x90 0x00 0x00 0x00 0x00 0x47 0xf8 0x9f 0x20
+ 0x00 0x00 0x00 0x00 0x49 0x04 0x31 0x90 0x00 0x00 0x00 0x00 0x49
+ 0xd8 0x81 0x20 0x00 0x00 0x00 0x00 0x4a 0xe4 0x13 0x90 0x00 0x00
+ 0x00 0x00 0x4b 0xb8 0x63 0x20 0x00 0x00 0x00 0x00 0x4c 0xcd 0x30
+ 0x10 0x00 0x00 0x00 0x00 0x4d 0x98 0x45 0x20 0x00 0x00 0x00 0x00
+ 0x4e 0xad 0x12 0x10 0x00 0x00 0x00 0x00 0x4f 0x78 0x27 0x20 0x00
+ 0x00 0x00 0x00 0x50 0x8c 0xf4 0x10 0x00 0x00 0x00 0x00 0x51 0x61
+ 0x43 0xa0 0x00 0x00 0x00 0x00 0x52 0x6c 0xd6 0x10 0x00 0x00 0x00
+ 0x00 0x53 0x41 0x25 0xa0 0x00 0x00 0x00 0x00 0x54 0x4c 0xb8 0x10
+ 0x00 0x00 0x00 0x00 0x55 0x21 0x07 0xa0 0x00 0x00 0x00 0x00 0x56
+ 0x2c 0x9a 0x10 0x00 0x00 0x00 0x00 0x57 0x00 0xe9 0xa0 0x00 0x00
+ 0x00 0x00 0x58 0x15 0xb6 0x90 0x00 0x00 0x00 0x00 0x58 0xe0 0xcb
+ 0xa0 0x00 0x00 0x00 0x00 0x59 0xf5 0x98 0x90 0x00 0x00 0x00 0x00
+ 0x5a 0xc0 0xad 0xa0 0x00 0x00 0x00 0x00 0x5b 0xd5 0x7a 0x90 0x00
+ 0x00 0x00 0x00 0x5c 0xa9 0xca 0x20 0x00 0x00 0x00 0x00 0x5d 0xb5
+ 0x5c 0x90 0x00 0x00 0x00 0x00 0x5e 0x89 0xac 0x20 0x00 0x00 0x00
+ 0x00 0x5f 0x95 0x3e 0x90 0x00 0x00 0x00 0x00 0x60 0x69 0x8e 0x20
+ 0x00 0x00 0x00 0x00 0x61 0x7e 0x5b 0x10 0x00 0x00 0x00 0x00 0x62
+ 0x49 0x70 0x20 0x00 0x00 0x00 0x00 0x63 0x5e 0x3d 0x10 0x00 0x00
+ 0x00 0x00 0x64 0x29 0x52 0x20 0x00 0x00 0x00 0x00 0x65 0x3e 0x1f
+ 0x10 0x00 0x00 0x00 0x00 0x66 0x12 0x6e 0xa0 0x00 0x00 0x00 0x00
+ 0x67 0x1e 0x01 0x10 0x00 0x00 0x00 0x00 0x67 0xf2 0x50 0xa0 0x00
+ 0x00 0x00 0x00 0x68 0xfd 0xe3 0x10 0x00 0x00 0x00 0x00 0x69 0xd2
+ 0x32 0xa0 0x00 0x00 0x00 0x00 0x6a 0xdd 0xc5 0x10 0x00 0x00 0x00
+ 0x00 0x6b 0xb2 0x14 0xa0 0x00 0x00 0x00 0x00 0x6c 0xc6 0xe1 0x90
+ 0x00 0x00 0x00 0x00 0x6d 0x91 0xf6 0xa0 0x00 0x00 0x00 0x00 0x6e
+ 0xa6 0xc3 0x90 0x00 0x00 0x00 0x00 0x6f 0x71 0xd8 0xa0 0x00 0x00
+ 0x00 0x00 0x70 0x86 0xa5 0x90 0x00 0x00 0x00 0x00 0x71 0x5a 0xf5
+ 0x20 0x00 0x00 0x00 0x00 0x72 0x66 0x87 0x90 0x00 0x00 0x00 0x00
+ 0x73 0x3a 0xd7 0x20 0x00 0x00 0x00 0x00 0x74 0x46 0x69 0x90 0x00
+ 0x00 0x00 0x00 0x75 0x1a 0xb9 0x20 0x00 0x00 0x00 0x00 0x76 0x2f
+ 0x86 0x10 0x00 0x00 0x00 0x00 0x76 0xfa 0x9b 0x20 0x00 0x00 0x00
+ 0x00 0x78 0x0f 0x68 0x10 0x00 0x00 0x00 0x00 0x78 0xda 0x7d 0x20
+ 0x00 0x00 0x00 0x00 0x79 0xef 0x4a 0x10 0x00 0x00 0x00 0x00 0x7a
+ 0xba 0x5f 0x20 0x00 0x00 0x00 0x00 0x7b 0xcf 0x2c 0x10 0x00 0x00
+ 0x00 0x00 0x7c 0xa3 0x7b 0xa0 0x00 0x00 0x00 0x00 0x7d 0xaf 0x0e
+ 0x10 0x00 0x00 0x00 0x00 0x7e 0x83 0x5d 0xa0 0x00 0x00 0x00 0x00
+ 0x7f 0x8e 0xf0 0x10 0x01 0x02 0x01 0x02 0x03 0x02 0x04 0x05 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+ 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+ 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0xff 0xff 0x92
+ 0x4c 0x00 0x00 0xff 0xff 0x9d 0x90 0x00 0x04 0xff 0xff 0x8f 0x80
+ 0x00 0x08 0xff 0xff 0x9d 0x90 0x01 0x0c 0xff 0xff 0x9d 0x90 0x01
+ 0x10 0xff 0xff 0x9d 0x90 0x01 0x14 0x4c 0x4d 0x54 0x00 0x4d 0x53
+ 0x54 0x00 0x50 0x53 0x54 0x00 0x50 0x44 0x54 0x00 0x50 0x57 0x54
+ 0x00 0x50 0x50 0x54 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x00 0x00
+ 0x00 0x00 0x00 0x01 0x0a 0x50 0x53 0x54 0x38 0x50 0x44 0x54 0x2c
+ 0x4d 0x34 0x2e 0x31 0x2e 0x30 0x2c 0x4d 0x31 0x30 0x2e 0x35 0x2e
+ 0x30 0x0a
+ }]
+ close $f
+ set ::tcl::clock::ZoneinfoPaths \
+ [linsert $::tcl::clock::ZoneinfoPaths 0 $tzdir]
+ ::tcl::clock::ClearCaches
+ }
+ -cleanup {
+ set ::tcl::clock::ZoneinfoPaths \
+ [lrange $::tcl::clock::ZoneinfoPaths 1 end]
+ ::tcl::clock::ClearCaches
+ removeFile TijuanaTwo $tzdir2
+ removeDirectory Test $tzdir
+ removeDirectory zoneinfo
+ }
+ -body {
+ clock format 2224738800 -timezone :Test/TijuanaTwo \
+ -format {%Y-%m-%d %H:%M:%S %Z}
+ }
+ -result {2040-07-01 00:00:00 PDT}
+}
+
+test clock-56.4 {Bug 3470928} {*}{
+ -setup {
+ clock format [clock seconds]
+ set tzdir [makeDirectory zoneinfo]
+ set tzdir2 [makeDirectory Test $tzdir]
+ set tzfile [makeFile {} Windhoek $tzdir2]
+ set f [open $tzfile wb]
+ puts -nonewline $f [binary format c* {
+ 0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x06 0x00 0x00
+ 0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x5c 0x00 0x00 0x00
+ 0x06 0x00 0x00 0x00 0x13 0x82 0x46 0xcf 0x68 0xcc 0xae 0x8c 0x80
+ 0xcd 0x9e 0x6f 0x70 0x26 0x06 0xa7 0xe0 0x2d 0x9d 0xea 0xe0 0x2e
+ 0x69 0x1c 0x10 0x2f 0x7d 0xe9 0x00 0x30 0x48 0xfe 0x10 0x31 0x67
+ 0x05 0x80 0x32 0x28 0xe0 0x10 0x33 0x46 0xe7 0x80 0x34 0x11 0xfc
+ 0x90 0x35 0x26 0xc9 0x80 0x35 0xf1 0xde 0x90 0x37 0x06 0xab 0x80
+ 0x37 0xd1 0xc0 0x90 0x38 0xe6 0x8d 0x80 0x39 0xb1 0xa2 0x90 0x3a
+ 0xc6 0x6f 0x80 0x3b 0x91 0x84 0x90 0x3c 0xaf 0x8c 0x00 0x3d 0x71
+ 0x66 0x90 0x3e 0x8f 0x6e 0x00 0x3f 0x5a 0x83 0x10 0x40 0x6f 0x50
+ 0x00 0x41 0x3a 0x65 0x10 0x42 0x4f 0x32 0x00 0x43 0x1a 0x47 0x10
+ 0x44 0x2f 0x14 0x00 0x44 0xfa 0x29 0x10 0x46 0x0e 0xf6 0x00 0x46
+ 0xda 0x0b 0x10 0x47 0xf8 0x12 0x80 0x48 0xc3 0x27 0x90 0x49 0xd7
+ 0xf4 0x80 0x4a 0xa3 0x09 0x90 0x4b 0xb7 0xd6 0x80 0x4c 0x82 0xeb
+ 0x90 0x4d 0x97 0xb8 0x80 0x4e 0x62 0xcd 0x90 0x4f 0x77 0x9a 0x80
+ 0x50 0x42 0xaf 0x90 0x51 0x60 0xb7 0x00 0x52 0x22 0x91 0x90 0x53
+ 0x40 0x99 0x00 0x54 0x0b 0xae 0x10 0x55 0x20 0x7b 0x00 0x55 0xeb
+ 0x90 0x10 0x57 0x00 0x5d 0x00 0x57 0xcb 0x72 0x10 0x58 0xe0 0x3f
+ 0x00 0x59 0xab 0x54 0x10 0x5a 0xc0 0x21 0x00 0x5b 0x8b 0x36 0x10
+ 0x5c 0xa9 0x3d 0x80 0x5d 0x6b 0x18 0x10 0x5e 0x89 0x1f 0x80 0x5f
+ 0x54 0x34 0x90 0x60 0x69 0x01 0x80 0x61 0x34 0x16 0x90 0x62 0x48
+ 0xe3 0x80 0x63 0x13 0xf8 0x90 0x64 0x28 0xc5 0x80 0x64 0xf3 0xda
+ 0x90 0x66 0x11 0xe2 0x00 0x66 0xd3 0xbc 0x90 0x67 0xf1 0xc4 0x00
+ 0x68 0xbc 0xd9 0x10 0x69 0xd1 0xa6 0x00 0x6a 0x9c 0xbb 0x10 0x6b
+ 0xb1 0x88 0x00 0x6c 0x7c 0x9d 0x10 0x6d 0x91 0x6a 0x00 0x6e 0x5c
+ 0x7f 0x10 0x6f 0x71 0x4c 0x00 0x70 0x3c 0x61 0x10 0x71 0x5a 0x68
+ 0x80 0x72 0x1c 0x43 0x10 0x73 0x3a 0x4a 0x80 0x74 0x05 0x5f 0x90
+ 0x75 0x1a 0x2c 0x80 0x75 0xe5 0x41 0x90 0x76 0xfa 0x0e 0x80 0x77
+ 0xc5 0x23 0x90 0x78 0xd9 0xf0 0x80 0x79 0xa5 0x05 0x90 0x7a 0xb9
+ 0xd2 0x80 0x7b 0x84 0xe7 0x90 0x7c 0xa2 0xef 0x00 0x7d 0x6e 0x04
+ 0x10 0x7e 0x82 0xd1 0x00 0x7f 0x4d 0xe6 0x10 0x01 0x02 0x01 0x03
+ 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
+ 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
+ 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
+ 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
+ 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
+ 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
+ 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x00 0x00 0x15
+ 0x18 0x00 0x00 0x00 0x00 0x1c 0x20 0x00 0x05 0x00 0x00 0x2a 0x30
+ 0x01 0x05 0x00 0x00 0x1c 0x20 0x00 0x0a 0x00 0x00 0x1c 0x20 0x01
+ 0x0e 0x00 0x00 0x0e 0x10 0x00 0x01 0x53 0x57 0x41 0x54 0x00 0x53
+ 0x41 0x53 0x54 0x00 0x43 0x41 0x54 0x00 0x57 0x41 0x53 0x54 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x54
+ 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x07 0x00 0x00 0x00
+ 0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x5d 0x00 0x00 0x00 0x07
+ 0x00 0x00 0x00 0x17 0xff 0xff 0xff 0xff 0x6d 0x7b 0x4b 0x78 0xff
+ 0xff 0xff 0xff 0x82 0x46 0xcf 0x68 0xff 0xff 0xff 0xff 0xcc 0xae
+ 0x8c 0x80 0xff 0xff 0xff 0xff 0xcd 0x9e 0x6f 0x70 0x00 0x00 0x00
+ 0x00 0x26 0x06 0xa7 0xe0 0x00 0x00 0x00 0x00 0x2d 0x9d 0xea 0xe0
+ 0x00 0x00 0x00 0x00 0x2e 0x69 0x1c 0x10 0x00 0x00 0x00 0x00 0x2f
+ 0x7d 0xe9 0x00 0x00 0x00 0x00 0x00 0x30 0x48 0xfe 0x10 0x00 0x00
+ 0x00 0x00 0x31 0x67 0x05 0x80 0x00 0x00 0x00 0x00 0x32 0x28 0xe0
+ 0x10 0x00 0x00 0x00 0x00 0x33 0x46 0xe7 0x80 0x00 0x00 0x00 0x00
+ 0x34 0x11 0xfc 0x90 0x00 0x00 0x00 0x00 0x35 0x26 0xc9 0x80 0x00
+ 0x00 0x00 0x00 0x35 0xf1 0xde 0x90 0x00 0x00 0x00 0x00 0x37 0x06
+ 0xab 0x80 0x00 0x00 0x00 0x00 0x37 0xd1 0xc0 0x90 0x00 0x00 0x00
+ 0x00 0x38 0xe6 0x8d 0x80 0x00 0x00 0x00 0x00 0x39 0xb1 0xa2 0x90
+ 0x00 0x00 0x00 0x00 0x3a 0xc6 0x6f 0x80 0x00 0x00 0x00 0x00 0x3b
+ 0x91 0x84 0x90 0x00 0x00 0x00 0x00 0x3c 0xaf 0x8c 0x00 0x00 0x00
+ 0x00 0x00 0x3d 0x71 0x66 0x90 0x00 0x00 0x00 0x00 0x3e 0x8f 0x6e
+ 0x00 0x00 0x00 0x00 0x00 0x3f 0x5a 0x83 0x10 0x00 0x00 0x00 0x00
+ 0x40 0x6f 0x50 0x00 0x00 0x00 0x00 0x00 0x41 0x3a 0x65 0x10 0x00
+ 0x00 0x00 0x00 0x42 0x4f 0x32 0x00 0x00 0x00 0x00 0x00 0x43 0x1a
+ 0x47 0x10 0x00 0x00 0x00 0x00 0x44 0x2f 0x14 0x00 0x00 0x00 0x00
+ 0x00 0x44 0xfa 0x29 0x10 0x00 0x00 0x00 0x00 0x46 0x0e 0xf6 0x00
+ 0x00 0x00 0x00 0x00 0x46 0xda 0x0b 0x10 0x00 0x00 0x00 0x00 0x47
+ 0xf8 0x12 0x80 0x00 0x00 0x00 0x00 0x48 0xc3 0x27 0x90 0x00 0x00
+ 0x00 0x00 0x49 0xd7 0xf4 0x80 0x00 0x00 0x00 0x00 0x4a 0xa3 0x09
+ 0x90 0x00 0x00 0x00 0x00 0x4b 0xb7 0xd6 0x80 0x00 0x00 0x00 0x00
+ 0x4c 0x82 0xeb 0x90 0x00 0x00 0x00 0x00 0x4d 0x97 0xb8 0x80 0x00
+ 0x00 0x00 0x00 0x4e 0x62 0xcd 0x90 0x00 0x00 0x00 0x00 0x4f 0x77
+ 0x9a 0x80 0x00 0x00 0x00 0x00 0x50 0x42 0xaf 0x90 0x00 0x00 0x00
+ 0x00 0x51 0x60 0xb7 0x00 0x00 0x00 0x00 0x00 0x52 0x22 0x91 0x90
+ 0x00 0x00 0x00 0x00 0x53 0x40 0x99 0x00 0x00 0x00 0x00 0x00 0x54
+ 0x0b 0xae 0x10 0x00 0x00 0x00 0x00 0x55 0x20 0x7b 0x00 0x00 0x00
+ 0x00 0x00 0x55 0xeb 0x90 0x10 0x00 0x00 0x00 0x00 0x57 0x00 0x5d
+ 0x00 0x00 0x00 0x00 0x00 0x57 0xcb 0x72 0x10 0x00 0x00 0x00 0x00
+ 0x58 0xe0 0x3f 0x00 0x00 0x00 0x00 0x00 0x59 0xab 0x54 0x10 0x00
+ 0x00 0x00 0x00 0x5a 0xc0 0x21 0x00 0x00 0x00 0x00 0x00 0x5b 0x8b
+ 0x36 0x10 0x00 0x00 0x00 0x00 0x5c 0xa9 0x3d 0x80 0x00 0x00 0x00
+ 0x00 0x5d 0x6b 0x18 0x10 0x00 0x00 0x00 0x00 0x5e 0x89 0x1f 0x80
+ 0x00 0x00 0x00 0x00 0x5f 0x54 0x34 0x90 0x00 0x00 0x00 0x00 0x60
+ 0x69 0x01 0x80 0x00 0x00 0x00 0x00 0x61 0x34 0x16 0x90 0x00 0x00
+ 0x00 0x00 0x62 0x48 0xe3 0x80 0x00 0x00 0x00 0x00 0x63 0x13 0xf8
+ 0x90 0x00 0x00 0x00 0x00 0x64 0x28 0xc5 0x80 0x00 0x00 0x00 0x00
+ 0x64 0xf3 0xda 0x90 0x00 0x00 0x00 0x00 0x66 0x11 0xe2 0x00 0x00
+ 0x00 0x00 0x00 0x66 0xd3 0xbc 0x90 0x00 0x00 0x00 0x00 0x67 0xf1
+ 0xc4 0x00 0x00 0x00 0x00 0x00 0x68 0xbc 0xd9 0x10 0x00 0x00 0x00
+ 0x00 0x69 0xd1 0xa6 0x00 0x00 0x00 0x00 0x00 0x6a 0x9c 0xbb 0x10
+ 0x00 0x00 0x00 0x00 0x6b 0xb1 0x88 0x00 0x00 0x00 0x00 0x00 0x6c
+ 0x7c 0x9d 0x10 0x00 0x00 0x00 0x00 0x6d 0x91 0x6a 0x00 0x00 0x00
+ 0x00 0x00 0x6e 0x5c 0x7f 0x10 0x00 0x00 0x00 0x00 0x6f 0x71 0x4c
+ 0x00 0x00 0x00 0x00 0x00 0x70 0x3c 0x61 0x10 0x00 0x00 0x00 0x00
+ 0x71 0x5a 0x68 0x80 0x00 0x00 0x00 0x00 0x72 0x1c 0x43 0x10 0x00
+ 0x00 0x00 0x00 0x73 0x3a 0x4a 0x80 0x00 0x00 0x00 0x00 0x74 0x05
+ 0x5f 0x90 0x00 0x00 0x00 0x00 0x75 0x1a 0x2c 0x80 0x00 0x00 0x00
+ 0x00 0x75 0xe5 0x41 0x90 0x00 0x00 0x00 0x00 0x76 0xfa 0x0e 0x80
+ 0x00 0x00 0x00 0x00 0x77 0xc5 0x23 0x90 0x00 0x00 0x00 0x00 0x78
+ 0xd9 0xf0 0x80 0x00 0x00 0x00 0x00 0x79 0xa5 0x05 0x90 0x00 0x00
+ 0x00 0x00 0x7a 0xb9 0xd2 0x80 0x00 0x00 0x00 0x00 0x7b 0x84 0xe7
+ 0x90 0x00 0x00 0x00 0x00 0x7c 0xa2 0xef 0x00 0x00 0x00 0x00 0x00
+ 0x7d 0x6e 0x04 0x10 0x00 0x00 0x00 0x00 0x7e 0x82 0xd1 0x00 0x00
+ 0x00 0x00 0x00 0x7f 0x4d 0xe6 0x10 0x01 0x02 0x03 0x02 0x04 0x06
+ 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
+ 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
+ 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
+ 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
+ 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
+ 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
+ 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x00 0x00 0x10 0x08
+ 0x00 0x00 0x00 0x00 0x15 0x18 0x00 0x04 0x00 0x00 0x1c 0x20 0x00
+ 0x09 0x00 0x00 0x2a 0x30 0x01 0x09 0x00 0x00 0x1c 0x20 0x00 0x0e
+ 0x00 0x00 0x1c 0x20 0x01 0x12 0x00 0x00 0x0e 0x10 0x00 0x05 0x4c
+ 0x4d 0x54 0x00 0x53 0x57 0x41 0x54 0x00 0x53 0x41 0x53 0x54 0x00
+ 0x43 0x41 0x54 0x00 0x57 0x41 0x53 0x54 0x00 0x00 0x00 0x00 0x00
+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0a 0x57 0x41
+ 0x54 0x2d 0x31 0x57 0x41 0x53 0x54 0x2c 0x4d 0x39 0x2e 0x31 0x2e
+ 0x30 0x2c 0x4d 0x34 0x2e 0x31 0x2e 0x30 0x0a
+ }]
+ close $f
+ set ::tcl::clock::ZoneinfoPaths \
+ [linsert $::tcl::clock::ZoneinfoPaths 0 $tzdir]
+ ::tcl::clock::ClearCaches
+ }
+ -body {
+ clock format 1326054606 -timezone :Test/Windhoek
+ }
+ -cleanup {
+ set ::tcl::clock::ZoneinfoPaths \
+ [lrange $::tcl::clock::ZoneinfoPaths 1 end]
+ ::tcl::clock::ClearCaches
+ removeFile Windhoek $tzdir2
+ removeDirectory Test $tzdir
+ removeDirectory zoneinfo
+ }
+ -result {Sun Jan 08 22:30:06 WAST 2012}
+}
+
+test clock-57.1 {clock scan - abbreviated options} {
+ clock scan 1970-01-01 -f %Y-%m-%d -g true
+} 0
+
+test clock-58.1 {clock l10n - Japanese localisation} {*}{
+ -setup {
+ proc backslashify { string } {
+
+ set retval {}
+ foreach char [split $string {}] {
+ scan $char %c ccode
+ if { $ccode >= 0x0020 && $ccode < 0x007f
+ && $char ne "\{" && $char ne "\}" && $char ne "\["
+ && $char ne "\]" && $char ne "\\" && $char ne "\$" } {
+ append retval $char
+ } else {
+ append retval \\u [format %04x $ccode]
+ }
+ }
+ return $retval
+ }
+ }
+ -body {
+ set trouble {}
+ foreach {date jdate} [list \
+ 1872-12-31 \u897f\u66a61872\u5e7412\u670831\u65e5 \
+ 1873-01-01 \u660e\u6cbb06\u5e7401\u670801\u65e5 \
+ 1912-07-29 \u660e\u6cbb45\u5e7407\u670829\u65e5 \
+ 1912-07-30 \u5927\u6b6301\u5e7407\u670830\u65e5 \
+ 1926-12-24 \u5927\u6b6315\u5e7412\u670824\u65e5 \
+ 1926-12-25 \u662d\u548c01\u5e7412\u670825\u65e5 \
+ 1989-01-07 \u662d\u548c64\u5e7401\u670807\u65e5 \
+ 1989-01-08 \u5e73\u621001\u5e7401\u670808\u65e5 \
+ ] {
+ set status [catch {
+ set secs [clock scan $date \
+ -timezone +0900 \
+ -locale ja_JP \
+ -format %Y-%m-%d]
+ set jda [clock format $secs \
+ -timezone +0900 \
+ -locale ja_JP \
+ -format %Ex]
+ } result]
+ if {$status != 0} {
+ append trouble \n $date " gives error " $result
+ } elseif {$jda ne $jdate} {
+ append trouble \n $date " converts to " \
+ [backslashify $jda] " and should be " \
+ [backslashify $jdate]
+ }
+ # There is no code for scanning dates on the locale's
+ # alternative calendar.
+ continue
+ set status [catch {
+ set secs [clock scan $jdate \
+ -timezone +0900 \
+ -locale ja_JP \
+ -format %Ex]
+ set da [clock format $secs \
+ -timezone +0900 \
+ -locale ja_JP \
+ -format %Y-%m-%d]
+ } result]
+ if {$status != 0} {
+ append trouble \n [backslashify $jdate] " gives error " $result
+ } elseif {$da ne $date} {
+ append trouble \n [backslashify $jdate] " converts to " \
+ $da " and should be " $date
+ }
+ }
+ set trouble
+ }
+ -cleanup {
+ rename backslashify {}
+ }
+ -result {}
+}
+
+test clock-59.1 {military time zones} {
+ set hour 0
+ set base [clock scan "20000101 000000" -format "%Y%m%d %H%M%S" -gmt 1]
+ set trouble {}
+ foreach {pzone mzone} {
+ Z Z A N B O C P D Q E R F S G T H U I V K W L X M Y
+ } {
+ catch {clock scan "20000101 000000 $pzone" \
+ -format "%Y%m%d %H%M%S %Z"} ps1
+ catch {clock scan "20000101 000000 $pzone"} ps2
+ catch {clock scan "20000101 000000 $mzone" \
+ -format "%Y%m%d %H%M%S %Z"} ms1
+ catch {clock scan "20000101 000000 $mzone"} ms2
+ if {$ps1 != $base - 3600 * $hour} {
+ lappend trouble [list pzone $pzone hour $hour ps1 is $ps1]
+ }
+ if {$ps2 != $base - 3600 * $hour} {
+ lappend trouble [list pzone $pzone ps2 is $ps2]
+ }
+ if {$ms1 != $base + 3600 * $hour} {
+ lappend trouble [list mzone $mzone ms1 is $ms1]
+ }
+ if {$ms2 != $base + 3600 * $hour} {
+ lappend trouble [list mzone $mzone ms2 is $ms2]
+ }
+ incr hour
+ }
+ join $trouble \n
+} {}
+
+# case-insensitive matching of weekday and month names [Bug 1781282]
+
+test clock-60.1 {case insensitive weekday names} {
+ clock scan "2000-W01 monday" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-1" -gmt true -format "%G-W%V-%u"]
+test clock-60.2 {case insensitive weekday names} {
+ clock scan "2000-W01 Monday" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-1" -gmt true -format "%G-W%V-%u"]
+test clock-60.3 {case insensitive weekday names} {
+ clock scan "2000-W01 MONDAY" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-1" -gmt true -format "%G-W%V-%u"]
+test clock-60.4 {case insensitive weekday names} {
+ clock scan "2000-W01 friday" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-5" -gmt true -format "%G-W%V-%u"]
+test clock-60.5 {case insensitive weekday names} {
+ clock scan "2000-W01 Friday" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-5" -gmt true -format "%G-W%V-%u"]
+test clock-60.6 {case insensitive weekday names} {
+ clock scan "2000-W01 FRIDAY" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-5" -gmt true -format "%G-W%V-%u"]
+test clock-60.7 {case insensitive month names} {
+ clock scan "1 january 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-01-01" -gmt true -format "%Y-%m-%d"]
+test clock-60.8 {case insensitive month names} {
+ clock scan "1 January 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-01-01" -gmt true -format "%Y-%m-%d"]
+test clock-60.9 {case insensitive month names} {
+ clock scan "1 JANUARY 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-01-01" -gmt true -format "%Y-%m-%d"]
+test clock-60.10 {case insensitive month names} {
+ clock scan "1 december 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-12-01" -gmt true -format "%Y-%m-%d"]
+test clock-60.11 {case insensitive month names} {
+ clock scan "1 December 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-12-01" -gmt true -format "%Y-%m-%d"]
+test clock-60.12 {case insensitive month names} {
+ clock scan "1 DECEMBER 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-12-01" -gmt true -format "%Y-%m-%d"]
+
+test clock-61.1 {overflow of a wide integer on output} {*}{
+ -body {
+ clock format 0x8000000000000000 -format %s -gmt true
+ }
+ -result {integer value too large to represent}
+ -returnCodes error
+}
+test clock-61.2 {overflow of a wide integer on output} {*}{
+ -body {
+ clock format -0x8000000000000001 -format %s -gmt true
+ }
+ -result {integer value too large to represent}
+ -returnCodes error
+}
+test clock-61.3 {near-miss overflow of a wide integer on output} {
+ clock format 0x7fffffffffffffff -format %s -gmt true
+} [expr 0x7fffffffffffffff]
+test clock-61.4 {near-miss overflow of a wide integer on output} {
+ clock format -0x8000000000000000 -format %s -gmt true
+} [expr -0x8000000000000000]
+
+test clock-62.1 {Bug 1902423} {*}{
+ -setup {::tcl::clock::ClearCaches}
+ -body {
+ set s 1204049747
+ set f1 [clock format $s -format {%Y-%m-%d %T} -locale C]
+ set f2 [clock format $s -format {%Y-%m-%d %H:%M:%S} -locale C]
+ if {$f1 ne $f2} {
+ subst "$f2 is not $f1"
+ } else {
+ subst "ok"
+ }
+ }
+ -result ok
+}
+
+test clock-63.1 {Incorrect use of internal ConvertLocalToUTC command} {*}{
+ -body {
+ ::tcl::clock::ConvertLocalToUTC {immaterial stuff} {} 12345
+ }
+ -returnCodes error
+ -result {key "localseconds" not found in dictionary}
+}
+
+test clock-64.1 {:: in format string [Bug 2362156]} {*}{
+ -body {
+ clock scan 2001-02-03::04:05:06 -gmt 1 -format %Y-%m-%d::%H:%M:%S
+ }
+ -result 981173106
+}
+test clock-64.2 {:: in format string [Bug 2362156]} {*}{
+ -body {
+ clock format 981173106 -gmt 1 -format %Y-%m-%d::%H:%M:%S
+ }
+ -result 2001-02-03::04:05:06
+}
+
+test clock-65.1 {clock add, bad option [Bug 2481670]} {*}{
+ -body {
+ clock add 0 1 year -foo bar
+ }
+ -match glob
+ -returnCodes error
+ -result {bad switch "-foo"*}
+}
+
+test clock-66.1 {clock scan, no date, never-before-seen timezone} {*}{
+ -setup {
+ ::tcl::clock::ClearCaches
+ }
+ -body {
+ clock scan 1200 \
+ -timezone {<EST>+05:00:00<EDT>+04:00:00,M3.2.0/02:00:00,M11.1.0/02:00:00} \
+ -base 1256529600 \
+ -format %H%M
+ }
+ -result 1256572800
+}
+
+test clock-67.1 {clock format, %% with a letter following [Bug 2819334]} {
+ clock format [clock seconds] -format %%r
+} %r
+
+# cleanup
+
+namespace delete ::testClock
+::tcl::clock::ClearCaches
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/cmdAH.test b/pkgs/msgcat/tests/cmdAH.test
new file mode 100644
index 0000000..291df8d
--- /dev/null
+++ b/pkgs/msgcat/tests/cmdAH.test
@@ -0,0 +1,1578 @@
+# The file tests the tclCmdAH.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1996-1998 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2.1
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testchmod [llength [info commands testchmod]]
+testConstraint testsetplatform [llength [info commands testsetplatform]]
+testConstraint testvolumetype [llength [info commands testvolumetype]]
+testConstraint linkDirectory [expr {
+ ![testConstraint win] ||
+ ([string index $tcl_platform(osVersion) 0] >= 5
+ && [lindex [file system [temporaryDirectory]] 1] eq "NTFS")
+}]
+
+global env
+set cmdAHwd [pwd]
+catch {set platform [testgetplatform]}
+
+proc waitForEvenSecondForFAT {} {
+ # Windows 9x uses filesystems (the FAT* family of FSes) without enough
+ # data in its timestamps for even per-second-accurate timings. :^(
+ # This procedure based on work by Helmut Giese
+ if {
+ [testConstraint win] &&
+ [lindex [file system [temporaryDirectory]] 1] ne "NTFS"
+ } then {
+ # Assume non-NTFS means FAT{12,16,32} and hence in need of special
+ # help...
+ set start [clock seconds]
+ while {1} {
+ set now [clock seconds]
+ if {$now!=$start && !($now & 1)} {
+ break
+ }
+ after 50
+ }
+ }
+}
+
+test cmdAH-0.1 {Tcl_BreakObjCmd, errors} -body {
+ break foo
+} -returnCodes error -result {wrong # args: should be "break"}
+test cmdAH-0.2 {Tcl_BreakObjCmd, success} {
+ list [catch {break} msg] $msg
+} {3 {}}
+
+# Tcl_CaseObjCmd is tested in case.test
+
+test cmdAH-1.1 {Tcl_CatchObjCmd, errors} -returnCodes error -body {
+ catch
+} -result {wrong # args: should be "catch script ?resultVarName? ?optionVarName?"}
+test cmdAH-1.2 {Tcl_CatchObjCmd, errors} {
+ list [catch {catch foo bar baz} msg] $msg
+} {0 1}
+test cmdAH-1.3 {Tcl_CatchObjCmd, errors} -returnCodes error -body {
+ catch foo bar baz spaz
+} -result {wrong # args: should be "catch script ?resultVarName? ?optionVarName?"}
+
+test cmdAH-2.1 {Tcl_CdObjCmd} -returnCodes error -body {
+ cd foo bar
+} -result {wrong # args: should be "cd ?dirName?"}
+set foodir [file join [temporaryDirectory] foo]
+test cmdAH-2.2 {Tcl_CdObjCmd} -setup {
+ file delete -force $foodir
+ set oldpwd [pwd]
+} -body {
+ file mkdir $foodir
+ cd $foodir
+ file tail [pwd]
+} -cleanup {
+ cd $oldpwd
+ file delete $foodir
+} -result foo
+test cmdAH-2.3 {Tcl_CdObjCmd} -setup {
+ global env
+ set oldpwd [pwd]
+ set temp $env(HOME)
+ file delete -force $foodir
+} -body {
+ set env(HOME) $oldpwd
+ file mkdir $foodir
+ cd $foodir
+ cd ~
+ string equal [pwd] $oldpwd
+} -cleanup {
+ cd $oldpwd
+ file delete $foodir
+ set env(HOME) $temp
+} -result 1
+test cmdAH-2.4 {Tcl_CdObjCmd} -setup {
+ global env
+ set oldpwd [pwd]
+ set temp $env(HOME)
+ file delete -force $foodir
+} -body {
+ set env(HOME) $oldpwd
+ file mkdir $foodir
+ cd $foodir
+ cd
+ string equal [pwd] $oldpwd
+} -cleanup {
+ cd $oldpwd
+ file delete $foodir
+ set env(HOME) $temp
+} -result 1
+test cmdAH-2.5 {Tcl_CdObjCmd} -returnCodes error -body {
+ cd ~~
+} -result {user "~" doesn't exist}
+test cmdAH-2.6 {Tcl_CdObjCmd} -returnCodes error -body {
+ cd _foobar
+} -result {couldn't change working directory to "_foobar": no such file or directory}
+test cmdAH-2.6.1 {Tcl_CdObjCmd} -returnCodes error -body {
+ cd ""
+} -result {couldn't change working directory to "": no such file or directory}
+test cmdAH-2.6.2 {cd} -constraints {unix nonPortable} -setup {
+ set dir [pwd]
+} -body {
+ cd /
+ pwd
+} -cleanup {
+ cd $dir
+} -result {/}
+test cmdAH-2.7 {Tcl_ConcatObjCmd} {
+ concat
+} {}
+test cmdAH-2.8 {Tcl_ConcatObjCmd} {
+ concat a
+} a
+test cmdAH-2.9 {Tcl_ConcatObjCmd} {
+ concat a {b c}
+} {a b c}
+
+test cmdAH-3.1 {Tcl_ContinueObjCmd, errors} -returnCodes error -body {
+ continue foo
+} -result {wrong # args: should be "continue"}
+test cmdAH-3.2 {Tcl_ContinueObjCmd, success} {
+ list [catch {continue} msg] $msg
+} {4 {}}
+
+test cmdAH-4.1 {Tcl_EncodingObjCmd} -returnCodes error -body {
+ encoding
+} -result {wrong # args: should be "encoding option ?arg ...?"}
+test cmdAH-4.2 {Tcl_EncodingObjCmd} -returnCodes error -body {
+ encoding foo
+} -result {bad option "foo": must be convertfrom, convertto, dirs, names, or system}
+test cmdAH-4.3 {Tcl_EncodingObjCmd} -returnCodes error -body {
+ encoding convertto
+} -result {wrong # args: should be "encoding convertto ?encoding? data"}
+test cmdAH-4.4 {Tcl_EncodingObjCmd} -returnCodes error -body {
+ encoding convertto foo bar
+} -result {unknown encoding "foo"}
+test cmdAH-4.5 {Tcl_EncodingObjCmd} -setup {
+ set system [encoding system]
+} -body {
+ encoding system jis0208
+ encoding convertto \u4e4e
+} -cleanup {
+ encoding system $system
+} -result 8C
+test cmdAH-4.6 {Tcl_EncodingObjCmd} -setup {
+ set system [encoding system]
+} -body {
+ encoding system identity
+ encoding convertto jis0208 \u4e4e
+} -cleanup {
+ encoding system $system
+} -result 8C
+test cmdAH-4.7 {Tcl_EncodingObjCmd} -returnCodes error -body {
+ encoding convertfrom
+} -result {wrong # args: should be "encoding convertfrom ?encoding? data"}
+test cmdAH-4.8 {Tcl_EncodingObjCmd} -returnCodes error -body {
+ encoding convertfrom foo bar
+} -result {unknown encoding "foo"}
+test cmdAH-4.9 {Tcl_EncodingObjCmd} -setup {
+ set system [encoding system]
+} -body {
+ encoding system jis0208
+ encoding convertfrom 8C
+} -cleanup {
+ encoding system $system
+} -result \u4e4e
+test cmdAH-4.10 {Tcl_EncodingObjCmd} -setup {
+ set system [encoding system]
+} -body {
+ encoding system identity
+ encoding convertfrom jis0208 8C
+} -cleanup {
+ encoding system $system
+} -result \u4e4e
+test cmdAH-4.11 {Tcl_EncodingObjCmd} -returnCodes error -body {
+ encoding names foo
+} -result {wrong # args: should be "encoding names"}
+test cmdAH-4.12 {Tcl_EncodingObjCmd} -returnCodes error -body {
+ encoding system foo bar
+} -result {wrong # args: should be "encoding system ?encoding?"}
+test cmdAH-4.13 {Tcl_EncodingObjCmd} -setup {
+ set system [encoding system]
+} -body {
+ encoding system identity
+ encoding system
+} -cleanup {
+ encoding system $system
+} -result identity
+
+test cmdAH-5.1 {Tcl_FileObjCmd} -returnCodes error -body {
+ file
+} -result {wrong # args: should be "file subcommand ?arg ...?"}
+test cmdAH-5.2 {Tcl_FileObjCmd} -returnCodes error -body {
+ file x
+} -result {unknown or ambiguous subcommand "x": must be atime, attributes, channels, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, link, lstat, mkdir, mtime, nativename, normalize, owned, pathtype, readable, readlink, rename, rootname, separator, size, split, stat, system, tail, tempfile, type, volumes, or writable}
+test cmdAH-5.3 {Tcl_FileObjCmd} -returnCodes error -body {
+ file exists
+} -result {wrong # args: should be "file exists name"}
+test cmdAH-5.4 {Tcl_FileObjCmd} {
+ file exists ""
+} 0
+
+# volume
+test cmdAH-6.1 {Tcl_FileObjCmd: volumes} -returnCodes error -body {
+ file volumes x
+} -result {wrong # args: should be "file volumes"}
+test cmdAH-6.2 {Tcl_FileObjCmd: volumes} -body {
+ lindex [file volumes] 0
+} -match glob -result ?*
+test cmdAH-6.3 {Tcl_FileObjCmd: volumes} -constraints unix -body {
+ set volumeList [file volumes]
+ glob -nocomplain [lindex $volumeList 0]*
+} -match glob -result *
+test cmdAH-6.4 {Tcl_FileObjCmd: volumes} -constraints win -body {
+ set volumeList [string tolower [file volumes]]
+ set element [lsearch -exact $volumeList "c:/"]
+ list [expr {$element>-1}] [glob -nocomplain [lindex $volumeList $element]*]
+} -match glob -result {1 *}
+
+# attributes
+test cmdAH-7.1 {Tcl_FileObjCmd - file attrs} -setup {
+ set foofile [makeFile abcde foo.file]
+ catch {file delete -force $foofile}
+} -body {
+ close [open $foofile w]
+ file attributes $foofile
+} -cleanup {
+ # We used [makeFile] so we undo with [removeFile]
+ removeFile $foofile
+} -match glob -result *
+
+# dirname
+test cmdAH-8.1 {Tcl_FileObjCmd: dirname} -returnCodes error -body {
+ file dirname a b
+} -result {wrong # args: should be "file dirname name"}
+test cmdAH-8.2 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname /a/b
+} /a
+test cmdAH-8.3 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname {}
+} .
+test cmdAH-8.5 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform win
+ file dirname {}
+} .
+test cmdAH-8.6 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname .def
+} .
+test cmdAH-8.8 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform win
+ file dirname a
+} .
+test cmdAH-8.9 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname a/b/c.d
+} a/b
+test cmdAH-8.10 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname a/b.c/d
+} a/b.c
+test cmdAH-8.11 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname /.
+} /
+test cmdAH-8.12 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname /
+} /
+test cmdAH-8.13 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname /foo
+} /
+test cmdAH-8.14 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname //foo
+} /
+test cmdAH-8.15 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname //foo/bar
+} /foo
+test cmdAH-8.16 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname {//foo\/bar/baz}
+} {/foo\/bar}
+test cmdAH-8.17 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname {//foo\/bar/baz/blat}
+} {/foo\/bar/baz}
+test cmdAH-8.18 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname /foo//
+} /
+test cmdAH-8.19 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname ./a
+} .
+test cmdAH-8.20 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname a/.a
+} a
+test cmdAH-8.21 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform windows
+ file dirname c:foo
+} c:
+test cmdAH-8.22 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform windows
+ file dirname c:
+} c:
+test cmdAH-8.23 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform windows
+ file dirname c:/
+} c:/
+test cmdAH-8.24 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform windows
+ file dirname {c:\foo}
+} c:/
+test cmdAH-8.25 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform windows
+ file dirname {//foo/bar/baz}
+} //foo/bar
+test cmdAH-8.26 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform windows
+ file dirname {//foo/bar}
+} //foo/bar
+test cmdAH-8.38 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname ~/foo
+} ~
+test cmdAH-8.39 {Tcl_FileObjCmd: dirname} testsetplatform {
+ testsetplatform unix
+ file dirname ~bar/foo
+} ~bar
+test cmdAH-8.43 {Tcl_FileObjCmd: dirname} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints testsetplatform -body {
+ set env(HOME) "/homewontexist/test"
+ testsetplatform unix
+ file dirname ~
+} -cleanup {
+ set env(HOME) $temp
+} -result /homewontexist
+test cmdAH-8.44 {Tcl_FileObjCmd: dirname} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints testsetplatform -body {
+ set env(HOME) "~"
+ testsetplatform unix
+ file dirname ~
+} -cleanup {
+ set env(HOME) $temp
+} -result ~
+test cmdAH-8.45 {Tcl_FileObjCmd: dirname} -setup {
+ set temp $::env(HOME)
+} -constraints {win testsetplatform} -match regexp -body {
+ set ::env(HOME) "/homewontexist/test"
+ testsetplatform windows
+ file dirname ~
+} -cleanup {
+ set ::env(HOME) $temp
+} -result {([a-zA-Z]:?)/homewontexist}
+test cmdAH-8.46 {Tcl_FileObjCmd: dirname} {
+ set f [file normalize [info nameof]]
+ file exists $f
+ set res1 [file dirname [file join $f foo/bar]]
+ set res2 [file dirname "${f}/foo/bar"]
+ if {$res1 eq $res2} {
+ return "ok"
+ }
+ return "file dirname problem, $res1, $res2 not equal"
+} {ok}
+
+# tail
+test cmdAH-9.1 {Tcl_FileObjCmd: tail} -returnCodes error -body {
+ file tail a b
+} -result {wrong # args: should be "file tail name"}
+test cmdAH-9.2 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail /a/b
+} b
+test cmdAH-9.3 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail {}
+} {}
+test cmdAH-9.5 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform win
+ file tail {}
+} {}
+test cmdAH-9.6 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail .def
+} .def
+test cmdAH-9.8 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform win
+ file tail a
+} a
+test cmdAH-9.9 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file ta a/b/c.d
+} c.d
+test cmdAH-9.10 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail a/b.c/d
+} d
+test cmdAH-9.11 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail /.
+} .
+test cmdAH-9.12 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail /
+} {}
+test cmdAH-9.13 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail /foo
+} foo
+test cmdAH-9.14 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail //foo
+} foo
+test cmdAH-9.15 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail //foo/bar
+} bar
+test cmdAH-9.16 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail {//foo\/bar/baz}
+} baz
+test cmdAH-9.17 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail {//foo\/bar/baz/blat}
+} blat
+test cmdAH-9.18 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail /foo//
+} foo
+test cmdAH-9.19 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail ./a
+} a
+test cmdAH-9.20 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail a/.a
+} .a
+test cmdAH-9.21 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail c:foo
+} foo
+test cmdAH-9.22 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail c:
+} {}
+test cmdAH-9.23 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail c:/
+} {}
+test cmdAH-9.24 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail {c:\foo}
+} foo
+test cmdAH-9.25 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail {//foo/bar/baz}
+} baz
+test cmdAH-9.26 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail {//foo/bar}
+} {}
+test cmdAH-9.42 {Tcl_FileObjCmd: tail} -constraints testsetplatform -setup {
+ global env
+ set temp $env(HOME)
+} -body {
+ set env(HOME) "/home/test"
+ testsetplatform unix
+ file tail ~
+} -cleanup {
+ set env(HOME) $temp
+} -result test
+test cmdAH-9.43 {Tcl_FileObjCmd: tail} -constraints testsetplatform -setup {
+ global env
+ set temp $env(HOME)
+} -body {
+ set env(HOME) "~"
+ testsetplatform unix
+ file tail ~
+} -cleanup {
+ set env(HOME) $temp
+} -result {}
+test cmdAH-9.44 {Tcl_FileObjCmd: tail} -constraints testsetplatform -setup {
+ global env
+ set temp $env(HOME)
+} -body {
+ set env(HOME) "/home/test"
+ testsetplatform windows
+ file tail ~
+} -cleanup {
+ set env(HOME) $temp
+} -result test
+test cmdAH-9.46 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform unix
+ file tail {f.oo\bar/baz.bat}
+} baz.bat
+test cmdAH-9.47 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail c:foo
+} foo
+test cmdAH-9.48 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail c:
+} {}
+test cmdAH-9.49 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail c:/foo
+} foo
+test cmdAH-9.50 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail {c:/foo\bar}
+} bar
+test cmdAH-9.51 {Tcl_FileObjCmd: tail} testsetplatform {
+ testsetplatform windows
+ file tail {foo\bar}
+} bar
+
+# rootname
+test cmdAH-10.1 {Tcl_FileObjCmd: rootname} -returnCodes error -body {
+ file rootname a b
+} -result {wrong # args: should be "file rootname name"}
+test cmdAH-10.2 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file rootname {}
+} {}
+test cmdAH-10.3 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file ro foo
+} foo
+test cmdAH-10.4 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file rootname foo.
+} foo
+test cmdAH-10.5 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file rootname .foo
+} {}
+test cmdAH-10.6 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file rootname abc.def
+} abc
+test cmdAH-10.7 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file rootname abc.def.ghi
+} abc.def
+test cmdAH-10.8 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file rootname a/b/c.d
+} a/b/c
+test cmdAH-10.9 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file rootname a/b.c/d
+} a/b.c/d
+test cmdAH-10.10 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform unix
+ file rootname a/b.c/
+} a/b.c/
+test cmdAH-10.23 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname {}
+} {}
+test cmdAH-10.24 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file ro foo
+} foo
+test cmdAH-10.25 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname foo.
+} foo
+test cmdAH-10.26 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname .foo
+} {}
+test cmdAH-10.27 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname abc.def
+} abc
+test cmdAH-10.28 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname abc.def.ghi
+} abc.def
+test cmdAH-10.29 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname a/b/c.d
+} a/b/c
+test cmdAH-10.30 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname a/b.c/d
+} a/b.c/d
+test cmdAH-10.31 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname a\\b.c\\
+} a\\b.c\\
+test cmdAH-10.32 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname a\\b\\c.d
+} a\\b\\c
+test cmdAH-10.33 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname a\\b.c\\d
+} a\\b.c\\d
+test cmdAH-10.34 {Tcl_FileObjCmd: rootname} testsetplatform {
+ testsetplatform windows
+ file rootname a\\b.c\\
+} a\\b.c\\
+set num 35
+foreach outer { {} a .a a. a.a } {
+ foreach inner { {} a .a a. a.a } {
+ set thing [format %s/%s $outer $inner]
+ ;test cmdAH-10.$num {Tcl_FileObjCmd: rootname and extension options} testsetplatform "
+ testsetplatform unix
+ [list format %s%s [file rootname $thing] [file ext $thing]]
+ " $thing
+ incr num
+ }
+}
+
+# extension
+test cmdAH-11.1 {Tcl_FileObjCmd: extension} -returnCodes error -body {
+ file extension a b
+} -result {wrong # args: should be "file extension name"}
+test cmdAH-11.2 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file extension {}
+} {}
+test cmdAH-11.3 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file ext foo
+} {}
+test cmdAH-11.4 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file extension foo.
+} .
+test cmdAH-11.5 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file extension .foo
+} .foo
+test cmdAH-11.6 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file extension abc.def
+} .def
+test cmdAH-11.7 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file extension abc.def.ghi
+} .ghi
+test cmdAH-11.8 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file extension a/b/c.d
+} .d
+test cmdAH-11.9 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file extension a/b.c/d
+} {}
+test cmdAH-11.10 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform unix
+ file extension a/b.c/
+} {}
+test cmdAH-11.23 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension {}
+} {}
+test cmdAH-11.24 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file ext foo
+} {}
+test cmdAH-11.25 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension foo.
+} .
+test cmdAH-11.26 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension .foo
+} .foo
+test cmdAH-11.27 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension abc.def
+} .def
+test cmdAH-11.28 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension abc.def.ghi
+} .ghi
+test cmdAH-11.29 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension a/b/c.d
+} .d
+test cmdAH-11.30 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension a/b.c/d
+} {}
+test cmdAH-11.31 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension a\\b.c\\
+} {}
+test cmdAH-11.32 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension a\\b\\c.d
+} .d
+test cmdAH-11.33 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension a\\b.c\\d
+} {}
+test cmdAH-11.34 {Tcl_FileObjCmd: extension} testsetplatform {
+ testsetplatform windows
+ file extension a\\b.c\\
+} {}
+foreach {test onPlatform value result} {
+ cmdAH-11.35 unix a..b .b
+ cmdAH-11.36 windows a..b .b
+ cmdAH-11.37 unix a...b .b
+ cmdAH-11.38 windows a...b .b
+ cmdAH-11.39 unix a.c..b .b
+ cmdAH-11.40 windows a.c..b .b
+ cmdAH-11.41 unix ..b .b
+ cmdAH-11.42 windows ..b .b
+} {
+ test $test {Tcl_FileObjCmd: extension} testsetplatform "
+ testsetplatform $onPlatform
+ file extension $value
+ " $result
+}
+
+# pathtype
+test cmdAH-12.1 {Tcl_FileObjCmd: pathtype} -returnCodes error -body {
+ file pathtype a b
+} -result {wrong # args: should be "file pathtype name"}
+test cmdAH-12.2 {Tcl_FileObjCmd: pathtype} testsetplatform {
+ testsetplatform unix
+ file pathtype /a
+} absolute
+test cmdAH-12.3 {Tcl_FileObjCmd: pathtype} testsetplatform {
+ testsetplatform unix
+ file p a
+} relative
+test cmdAH-12.4 {Tcl_FileObjCmd: pathtype} testsetplatform {
+ testsetplatform windows
+ file pathtype c:a
+} volumerelative
+
+# split
+test cmdAH-13.1 {Tcl_FileObjCmd: split} -returnCodes error -body {
+ file split a b
+} -result {wrong # args: should be "file split name"}
+test cmdAH-13.2 {Tcl_FileObjCmd: split} testsetplatform {
+ testsetplatform unix
+ file split a
+} a
+test cmdAH-13.3 {Tcl_FileObjCmd: split} testsetplatform {
+ testsetplatform unix
+ file split a/b
+} {a b}
+
+# join
+test cmdAH-14.1 {Tcl_FileObjCmd: join} testsetplatform {
+ testsetplatform unix
+ file join a
+} a
+test cmdAH-14.2 {Tcl_FileObjCmd: join} testsetplatform {
+ testsetplatform unix
+ file join a b
+} a/b
+test cmdAH-14.3 {Tcl_FileObjCmd: join} testsetplatform {
+ testsetplatform unix
+ file join a b c d
+} a/b/c/d
+
+# error handling of Tcl_TranslateFileName
+test cmdAH-15.1 {Tcl_FileObjCmd} -constraints testsetplatform -body {
+ testsetplatform unix
+ file atime ~_bad_user
+} -returnCodes error -result {user "_bad_user" doesn't exist}
+
+catch {testsetplatform $platform}
+
+# readable
+set gorpfile [makeFile abcde gorp.file]
+set dirfile [makeDirectory dir.file]
+test cmdAH-16.1 {Tcl_FileObjCmd: readable} {
+ -returnCodes error
+ -body {file readable a b}
+ -result {wrong # args: should be "file readable name"}
+}
+test cmdAH-16.2 {Tcl_FileObjCmd: readable} {
+ -constraints testchmod
+ -setup {testchmod 0444 $gorpfile}
+ -body {file readable $gorpfile}
+ -result 1
+}
+test cmdAH-16.3 {Tcl_FileObjCmd: readable} {
+ -constraints {unix notRoot testchmod}
+ -setup {testchmod 0333 $gorpfile}
+ -body {file readable $gorpfile}
+ -result 0
+}
+
+# writable
+test cmdAH-17.1 {Tcl_FileObjCmd: writable} {
+ -returnCodes error
+ -body {file writable a b}
+ -result {wrong # args: should be "file writable name"}
+}
+test cmdAH-17.2 {Tcl_FileObjCmd: writable} {
+ -constraints {notRoot testchmod}
+ -setup {testchmod 0555 $gorpfile}
+ -body {file writable $gorpfile}
+ -result 0
+}
+test cmdAH-17.3 {Tcl_FileObjCmd: writable} {
+ -constraints testchmod
+ -setup {testchmod 0222 $gorpfile}
+ -body {file writable $gorpfile}
+ -result 1
+}
+
+# executable
+removeFile $gorpfile
+removeDirectory $dirfile
+set dirfile [makeDirectory dir.file]
+set gorpfile [makeFile abcde gorp.file]
+test cmdAH-18.1 {Tcl_FileObjCmd: executable} -returnCodes error -body {
+ file executable a b
+} -result {wrong # args: should be "file executable name"}
+test cmdAH-18.2 {Tcl_FileObjCmd: executable} {notRoot} {
+ file executable $gorpfile
+} 0
+test cmdAH-18.3 {Tcl_FileObjCmd: executable} {unix testchmod} {
+ # Only on unix will setting the execute bit on a regular file cause that
+ # file to be executable.
+ testchmod 0775 $gorpfile
+ file exe $gorpfile
+} 1
+test cmdAH-18.5 {Tcl_FileObjCmd: executable} -constraints {win} -body {
+ # On pc, must be a .exe, .com, etc.
+ set x [file exe $gorpfile]
+ set gorpexe [makeFile foo gorp.exe]
+ lappend x [file exe $gorpexe]
+} -cleanup {
+ removeFile $gorpexe
+} -result {0 1}
+test cmdAH-18.5.1 {Tcl_FileObjCmd: executable} -constraints {win} -body {
+ # On pc, must be a .exe, .com, etc.
+ set x [file exe $gorpfile]
+ set gorpexe [makeFile foo gorp.exe]
+ lappend x [file exe [string toupper $gorpexe]]
+} -cleanup {
+ removeFile $gorpexe
+} -result {0 1}
+test cmdAH-18.6 {Tcl_FileObjCmd: executable} {} {
+ # Directories are always executable.
+ file exe $dirfile
+} 1
+
+removeDirectory $dirfile
+removeFile $gorpfile
+set linkfile [file join [temporaryDirectory] link.file]
+file delete $linkfile
+
+# exists
+test cmdAH-19.1 {Tcl_FileObjCmd: exists} -returnCodes error -body {
+ file exists a b
+} -result {wrong # args: should be "file exists name"}
+test cmdAH-19.2 {Tcl_FileObjCmd: exists} {file exists $gorpfile} 0
+test cmdAH-19.3 {Tcl_FileObjCmd: exists} {
+ file exists [file join [temporaryDirectory] dir.file gorp.file]
+} 0
+catch {
+ set gorpfile [makeFile abcde gorp.file]
+ set dirfile [makeDirectory dir.file]
+ set subgorp [makeFile 12345 [file join $dirfile gorp.file]]
+}
+test cmdAH-19.4 {Tcl_FileObjCmd: exists} {
+ file exists $gorpfile
+} 1
+test cmdAH-19.5 {Tcl_FileObjCmd: exists} {
+ file exists $subgorp
+} 1
+# nativename
+test cmdAH-19.6 {Tcl_FileObjCmd: nativename} -body {
+ testsetplatform unix
+ file nativename a/b
+} -constraints testsetplatform -cleanup {
+ testsetplatform $platform
+} -result a/b
+test cmdAH-19.7 {Tcl_FileObjCmd: nativename} -body {
+ testsetplatform windows
+ file nativename a/b
+} -constraints testsetplatform -cleanup {
+ testsetplatform $platform
+} -result {a\b}
+test cmdAH-19.9 {Tcl_FileObjCmd: ~ : exists} {
+ file exists ~nOsUcHuSeR
+} 0
+test cmdAH-19.10 {Tcl_FileObjCmd: ~ : nativename} -body {
+ # should probably be a non-error in fact...
+ file nativename ~nOsUcHuSeR
+} -returnCodes error -match glob -result *
+# The test below has to be done in /tmp rather than the current directory in
+# order to guarantee (?) a local file system: some NFS file systems won't do
+# the stuff below correctly.
+test cmdAH-19.11 {Tcl_FileObjCmd: exists} -constraints {unix notRoot} -setup {
+ file delete -force /tmp/tcl.foo.dir/file
+ file delete -force /tmp/tcl.foo.dir
+} -body {
+ makeDirectory /tmp/tcl.foo.dir
+ makeFile 12345 /tmp/tcl.foo.dir/file
+ file attributes /tmp/tcl.foo.dir -permissions 0000
+ file exists /tmp/tcl.foo.dir/file
+} -cleanup {
+ file attributes /tmp/tcl.foo.dir -permissions 0775
+ removeFile /tmp/tcl.foo.dir/file
+ removeDirectory /tmp/tcl.foo.dir
+} -result 0
+
+# Stat related commands
+
+catch {testsetplatform $platform}
+removeFile $gorpfile
+set gorpfile [makeFile "Test string" gorp.file]
+catch {file attributes $gorpfile -permissions 0765}
+
+# avoid problems with non-local filesystems
+if {[testConstraint unix] && [file exists /tmp]} {
+ set file [makeFile "data" touch.me /tmp]
+} else {
+ set file [makeFile "data" touch.me]
+}
+
+# atime
+test cmdAH-20.1 {Tcl_FileObjCmd: atime} -returnCodes error -body {
+ file atime a b c
+} -result {wrong # args: should be "file atime name ?time?"}
+test cmdAH-20.2 {Tcl_FileObjCmd: atime} -setup {
+ unset -nocomplain stat
+} -body {
+ file stat $gorpfile stat
+ list [expr {[file mtime $gorpfile] == $stat(mtime)}] \
+ [expr {[file atime $gorpfile] == $stat(atime)}]
+} -result {1 1}
+test cmdAH-20.3 {Tcl_FileObjCmd: atime} {
+ list [catch {file atime _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-20.4 {Tcl_FileObjCmd: atime} -returnCodes error -body {
+ file atime $file notint
+} -result {expected integer but got "notint"}
+test cmdAH-20.5 {Tcl_FileObjCmd: atime touch} {unix} {
+ set atime [file atime $file]
+ after 1100; # pause a sec to notice change in atime
+ set newatime [clock seconds]
+ set modatime [file atime $file $newatime]
+ expr {$newatime == $modatime ? 1 : "$newatime != $modatime"}
+} 1
+test cmdAH-20.6 {Tcl_FileObjCmd: atime touch} -setup {
+ set old [pwd]
+ cd $::tcltest::temporaryDirectory
+ set volumetype [testvolumetype]
+ cd $old
+} -constraints {win testvolumetype} -body {
+ if {"NTFS" ne $volumetype} {
+ # Windows FAT doesn't understand atime, but NTFS does. May also fail
+ # for Windows on NFS mounted disks.
+ return 1
+ }
+ cd $old
+ set atime [file atime $file]
+ after 1100; # pause a sec to notice change in atime
+ set newatime [clock seconds]
+ set modatime [file atime $file $newatime]
+ expr {$newatime == $modatime ? 1 : "$newatime != $modatime"}
+} -result 1
+
+if {[testConstraint unix] && [file exists /tmp]} {
+ removeFile touch.me /tmp
+} else {
+ removeFile touch.me
+}
+
+# isdirectory
+test cmdAH-21.1 {Tcl_FileObjCmd: isdirectory} -returnCodes error -body {
+ file isdirectory a b
+} -result {wrong # args: should be "file isdirectory name"}
+test cmdAH-21.2 {Tcl_FileObjCmd: isdirectory} {file isdirectory $gorpfile} 0
+test cmdAH-21.3 {Tcl_FileObjCmd: isdirectory} {file isdirectory $dirfile} 1
+
+# isfile
+test cmdAH-22.1 {Tcl_FileObjCmd: isfile} -returnCodes error -body {
+ file isfile a b
+} -result {wrong # args: should be "file isfile name"}
+test cmdAH-22.2 {Tcl_FileObjCmd: isfile} {file isfile $gorpfile} 1
+test cmdAH-22.3 {Tcl_FileObjCmd: isfile} {file isfile $dirfile} 0
+
+# lstat and readlink: don't run these tests everywhere, since not all sites
+# will have symbolic links
+catch {file link -symbolic $linkfile $gorpfile}
+test cmdAH-23.1 {Tcl_FileObjCmd: lstat} -returnCodes error -body {
+ file lstat a
+} -result {wrong # args: should be "file lstat name varName"}
+test cmdAH-23.2 {Tcl_FileObjCmd: lstat} -returnCodes error -body {
+ file lstat a b c
+} -result {wrong # args: should be "file lstat name varName"}
+test cmdAH-23.3 {Tcl_FileObjCmd: lstat} -setup {
+ unset -nocomplain stat
+} -constraints {unix nonPortable} -body {
+ file lstat $linkfile stat
+ lsort [array names stat]
+} -result {atime ctime dev gid ino mode mtime nlink size type uid}
+test cmdAH-23.4 {Tcl_FileObjCmd: lstat} -setup {
+ unset -nocomplain stat
+} -constraints {unix nonPortable} -body {
+ file lstat $linkfile stat
+ list $stat(nlink) [expr $stat(mode)&0777] $stat(type)
+} -result {1 511 link}
+test cmdAH-23.5 {Tcl_FileObjCmd: lstat errors} {nonPortable} {
+ list [catch {file lstat _bogus_ stat} msg] [string tolower $msg] \
+ $errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-23.6 {Tcl_FileObjCmd: lstat errors} -setup {
+ unset -nocomplain x
+} -body {
+ set x 44
+ list [catch {file lstat $gorpfile x} msg] $msg $errorCode
+} -result {1 {can't set "x(dev)": variable isn't array} {TCL LOOKUP VARNAME x}}
+unset -nocomplain stat
+# mkdir
+set dirA [file join [temporaryDirectory] a]
+set dirB [file join [temporaryDirectory] a]
+test cmdAH-23.7 {Tcl_FileObjCmd: mkdir} -setup {
+ catch {file delete -force $dirA}
+} -body {
+ file mkdir $dirA
+ file isdirectory $dirA
+} -cleanup {
+ file delete $dirA
+} -result {1}
+test cmdAH-23.8 {Tcl_FileObjCmd: mkdir} -setup {
+ catch {file delete -force $dirA}
+} -body {
+ file mkdir $dirA/b
+ file isdirectory $dirA/b
+} -cleanup {
+ file delete -force $dirA
+} -result {1}
+test cmdAH-23.9 {Tcl_FileObjCmd: mkdir} -setup {
+ catch {file delete -force $dirA}
+} -body {
+ file mkdir $dirA/b/c
+ file isdirectory $dirA/b/c
+} -cleanup {
+ file delete -force $dirA
+} -result {1}
+test cmdAH-23.10 {Tcl_FileObjCmd: mkdir} -setup {
+ catch {file delete -force $dirA}
+ catch {file delete -force $dirB}
+} -body {
+ file mkdir $dirA/b $dirB/a/c
+ list [file isdirectory $dirA/b] [file isdirectory $dirB/a/c]
+} -cleanup {
+ file delete -force $dirA
+ file delete -force $dirB
+} -result {1 1}
+test cmdAH-23.11 {Tcl_FileObjCmd: mkdir} {
+ # Allow zero arguments (TIP 323)
+ file mkdir
+} {}
+
+set file [makeFile "data" touch.me]
+# mtime
+test cmdAH-24.1 {Tcl_FileObjCmd: mtime} -returnCodes error -body {
+ file mtime a b c
+} -result {wrong # args: should be "file mtime name ?time?"}
+test cmdAH-24.2 {Tcl_FileObjCmd: mtime} -setup {
+ # Check (allowing for clock-skew and OS interrupts as best we can) that
+ # the change in mtime on a file being written is the time elapsed between
+ # writes. Note that this can still fail on very busy systems if there are
+ # long preemptions between the writes and the reading of the clock, but
+ # there's not much you can do about that other than the completely
+ # horrible "keep on trying to write until you managed to do it all in less
+ # than a second." - DKF
+ waitForEvenSecondForFAT
+} -body {
+ set f [open $gorpfile w]
+ puts $f "More text"
+ close $f
+ set clockOld [clock seconds]
+ set fileOld [file mtime $gorpfile]
+ after 2000
+ set f [open $gorpfile w]
+ puts $f "More text"
+ close $f
+ set clockNew [clock seconds]
+ set fileNew [file mtime $gorpfile]
+ expr {
+ (($fileNew > $fileOld) && ($clockNew > $clockOld) &&
+ (abs(($fileNew-$fileOld) - ($clockNew-$clockOld)) <= 1)) ? "1" :
+ "file:($fileOld=>$fileNew) clock:($clockOld=>$clockNew)"
+ }
+} -result {1}
+test cmdAH-24.3 {Tcl_FileObjCmd: mtime} -setup {
+ unset -nocomplain stat
+} -body {
+ file stat $gorpfile stat
+ list [expr {[file mtime $gorpfile] == $stat(mtime)}] \
+ [expr {[file atime $gorpfile] == $stat(atime)}]
+} -result {1 1}
+test cmdAH-24.4 {Tcl_FileObjCmd: mtime} {
+ list [catch {file mtime _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-24.5 {Tcl_FileObjCmd: mtime} -setup {
+ # Under Unix, use a file in /tmp to avoid clock skew due to NFS. On other
+ # platforms, just use a file in the local directory.
+ if {[testConstraint unix]} {
+ set name /tmp/tcl.test.[pid]
+ } else {
+ set name [file join [temporaryDirectory] tf]
+ }
+} -body {
+ # Make sure that a new file's time is correct. 10 seconds variance is
+ # allowed used due to slow networks or clock skew on a network drive.
+ file delete -force $name
+ close [open $name w]
+ expr {abs([clock seconds]-[file mtime $name])<10}
+} -cleanup {
+ file delete $name
+} -result {1}
+test cmdAH-24.7 {Tcl_FileObjCmd: mtime} -returnCodes error -body {
+ file mtime $file notint
+} -result {expected integer but got "notint"}
+test cmdAH-24.8 {Tcl_FileObjCmd: mtime touch} unix {
+ set mtime [file mtime $file]
+ after 1100; # pause a sec to notice change in mtime
+ set newmtime [clock seconds]
+ set modmtime [file mtime $file $newmtime]
+ expr {$newmtime == $modmtime ? 1 : "$newmtime != $modmtime"}
+} 1
+test cmdAH-24.9 {Tcl_FileObjCmd: mtime touch with non-ascii chars} -setup {
+ set oldfile $file
+} -constraints unix -body {
+ # introduce some non-ascii characters.
+ append file \u2022
+ file delete -force $file
+ file rename $oldfile $file
+ set mtime [file mtime $file]
+ after 1100; # pause a sec to notice change in mtime
+ set newmtime [clock seconds]
+ set modmtime [file mtime $file $newmtime]
+ expr {$newmtime == $modmtime ? 1 : "$newmtime != $modmtime"}
+} -cleanup {
+ file rename $file $oldfile
+} -result 1
+test cmdAH-24.10 {Tcl_FileObjCmd: mtime touch} -constraints win -setup {
+ waitForEvenSecondForFAT
+} -body {
+ set mtime [file mtime $file]
+ after 2100; # pause two secs to notice change in mtime on FAT fs'es
+ set newmtime [clock seconds]
+ set modmtime [file mtime $file $newmtime]
+ expr {$newmtime == $modmtime ? 1 : "$newmtime != $modmtime"}
+} -result 1
+test cmdAH-24.11 {Tcl_FileObjCmd: mtime touch with non-ascii chars} -setup {
+ waitForEvenSecondForFAT
+ set oldfile $file
+} -constraints win -body {
+ # introduce some non-ascii characters.
+ append file \u2022
+ file delete -force $file
+ file rename $oldfile $file
+ set mtime [file mtime $file]
+ after 2100; # pause two secs to notice change in mtime on FAT fs'es
+ set newmtime [clock seconds]
+ set modmtime [file mtime $file $newmtime]
+ expr {$newmtime == $modmtime ? 1 : "$newmtime != $modmtime"}
+} -cleanup {
+ file rename $file $oldfile
+} -result 1
+removeFile touch.me
+rename waitForEvenSecondForFAT {}
+test cmdAH-24.12 {Tcl_FileObjCmd: mtime and daylight savings} -setup {
+ set name [file join [temporaryDirectory] clockchange]
+ file delete -force $name
+ close [open $name w]
+} -body {
+ set time [clock scan "21:00:00 October 30 2004 GMT"]
+ file mtime $name $time
+ set newmtime [file mtime $name]
+ expr {$newmtime == $time ? 1 : "$newmtime != $time"}
+} -cleanup {
+ file delete $name
+} -result {1}
+# bug 1420432: setting mtime fails for directories on windows.
+test cmdAH-24.13 {Tcl_FileObjCmd: directory mtime} -setup {
+ set dirname [file join [temporaryDirectory] tmp[pid]]
+ file delete -force $dirname
+} -constraints tempNotWin -body {
+ file mkdir $dirname
+ set old [file mtime $dirname]
+ file mtime $dirname 0
+ set new [file mtime $dirname]
+ list $new [expr {$old != $new}]
+} -cleanup {
+ file delete -force $dirname
+} -result {0 1}
+
+# owned
+test cmdAH-25.1 {Tcl_FileObjCmd: owned} -returnCodes error -body {
+ file owned a b
+} -result {wrong # args: should be "file owned name"}
+test cmdAH-25.2 {Tcl_FileObjCmd: owned} -constraints win -body {
+ file owned $gorpfile
+} -result 1
+test cmdAH-25.2.1 {Tcl_FileObjCmd: owned} -constraints unix -setup {
+ # Avoid problems with AFS
+ set tmpfile [makeFile "data" touch.me /tmp]
+} -body {
+ file owned $tmpfile
+} -cleanup {
+ removeFile touch.me /tmp
+} -result 1
+test cmdAH-25.3 {Tcl_FileObjCmd: owned} {unix notRoot} {
+ file owned /
+} 0
+
+# readlink
+test cmdAH-26.1 {Tcl_FileObjCmd: readlink} -returnCodes error -body {
+ file readlink a b
+} -result {wrong # args: should be "file readlink name"}
+test cmdAH-26.2 {Tcl_FileObjCmd: readlink} {unix nonPortable} {
+ file readlink $linkfile
+} $gorpfile
+test cmdAH-26.3 {Tcl_FileObjCmd: readlink errors} {unix nonPortable} {
+ list [catch {file readlink _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not readlink "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-26.5 {Tcl_FileObjCmd: readlink errors} {win nonPortable} {
+ list [catch {file readlink _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not readlink "_bogus_": invalid argument} {POSIX EINVAL {invalid argument}}}
+
+# size
+test cmdAH-27.1 {Tcl_FileObjCmd: size} -returnCodes error -body {
+ file size a b
+} -result {wrong # args: should be "file size name"}
+test cmdAH-27.2 {Tcl_FileObjCmd: size} {
+ set oldsize [file size $gorpfile]
+ set f [open $gorpfile a]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f "More text"
+ close $f
+ expr {[file size $gorpfile] - $oldsize}
+} {10}
+test cmdAH-27.3 {Tcl_FileObjCmd: size} {
+ list [catch {file size _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+
+catch {testsetplatform $platform}
+removeFile $gorpfile
+set gorpfile [makeFile "Test string" gorp.file]
+catch {file attributes $gorpfile -permissions 0765}
+
+# stat
+test cmdAH-28.1 {Tcl_FileObjCmd: stat} -returnCodes error -body {
+ file stat _bogus_
+} -result {wrong # args: should be "file stat name varName"}
+test cmdAH-28.2 {Tcl_FileObjCmd: stat} -returnCodes error -body {
+ file stat _bogus_ a b
+} -result {wrong # args: should be "file stat name varName"}
+test cmdAH-28.3 {Tcl_FileObjCmd: stat} -setup {
+ unset -nocomplain stat
+ set stat(blocks) [set stat(blksize) {}]
+} -body {
+ file stat $gorpfile stat
+ unset stat(blocks) stat(blksize); # Ignore these fields; not always set
+ lsort [array names stat]
+} -result {atime ctime dev gid ino mode mtime nlink size type uid}
+test cmdAH-28.4 {Tcl_FileObjCmd: stat} -setup {
+ unset -nocomplain stat
+} -body {
+ file stat $gorpfile stat
+ list $stat(nlink) $stat(size) $stat(type)
+} -result {1 12 file}
+test cmdAH-28.5 {Tcl_FileObjCmd: stat} -constraints {unix} -setup {
+ unset -nocomplain stat
+} -body {
+ file stat $gorpfile stat
+ expr {$stat(mode) & 0o777}
+} -result {501}
+test cmdAH-28.6 {Tcl_FileObjCmd: stat} {
+ list [catch {file stat _bogus_ stat} msg] [string tolower $msg] $errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-28.7 {Tcl_FileObjCmd: stat} -setup {
+ unset -nocomplain x
+} -returnCodes error -body {
+ set x 44
+ file stat $gorpfile x
+} -result {can't set "x(dev)": variable isn't array}
+test cmdAH-28.8 {Tcl_FileObjCmd: stat} -setup {
+ set filename [makeFile "" foo.text]
+} -body {
+ # Sign extension of purported unsigned short to int.
+ file stat $filename stat
+ expr {$stat(mode) > 0}
+} -cleanup {
+ removeFile $filename
+} -result 1
+test cmdAH-28.9 {Tcl_FileObjCmd: stat} win {
+ # stat of root directory was failing. Don't care about answer, just that
+ # test runs. Relative paths that resolve to root
+ set old [pwd]
+ cd c:/
+ file stat c: stat
+ file stat c:. stat
+ file stat . stat
+ cd $old
+ file stat / stat
+ file stat c:/ stat
+ file stat c:/. stat
+} {}
+test cmdAH-28.10 {Tcl_FileObjCmd: stat} {win nonPortable} {
+ # stat of root directory was failing. Don't care about answer, just that
+ # test runs.
+ file stat //pop/$env(USERNAME) stat
+ file stat //pop/$env(USERNAME)/ stat
+ file stat //pop/$env(USERNAME)/. stat
+} {}
+test cmdAH-28.11 {Tcl_FileObjCmd: stat} -setup {
+ set old [pwd]
+} -constraints {win nonPortable} -body {
+ # stat of network directory was returning id of current local drive.
+ cd c:/
+ file stat //pop/$env(USERNAME) stat
+ expr {$stat(dev) == 2}
+} -cleanup {
+ cd $old
+} -result 0
+test cmdAH-28.12 {Tcl_FileObjCmd: stat} -setup {
+ set filename [makeFile "" foo.test]
+} -body {
+ # stat(mode) with S_IFREG flag was returned as a negative number if mode_t
+ # was a short instead of an unsigned short.
+ file stat $filename stat
+ expr {$stat(mode) > 0}
+} -cleanup {
+ removeFile $filename
+} -result 1
+unset -nocomplain stat
+
+# type
+test cmdAH-29.1 {Tcl_FileObjCmd: type} -returnCodes error -body {
+ file size a b
+} -result {wrong # args: should be "file size name"}
+test cmdAH-29.2 {Tcl_FileObjCmd: type} {
+ file type $dirfile
+} directory
+test cmdAH-29.3.0 {Tcl_FileObjCmd: delete removes link not file} {unix nonPortable} {
+ set exists [list [file exists $linkfile] [file exists $gorpfile]]
+ file delete $linkfile
+ set exists2 [list [file exists $linkfile] [file exists $gorpfile]]
+ list $exists $exists2
+} {{1 1} {0 1}}
+test cmdAH-29.3 {Tcl_FileObjCmd: type} {
+ file type $gorpfile
+} file
+test cmdAH-29.4 {Tcl_FileObjCmd: type} -constraints {unix} -setup {
+ catch {file delete $linkfile}
+} -body {
+ # Unlike [exec ln -s], [file link] requires an existing target
+ file link -symbolic $linkfile $gorpfile
+ file type $linkfile
+} -cleanup {
+ file delete $linkfile
+} -result link
+test cmdAH-29.4.1 {Tcl_FileObjCmd: type} -constraints {linkDirectory} -setup {
+ set tempdir [makeDirectory temp]
+} -body {
+ set linkdir [file join [temporaryDirectory] link.dir]
+ file link -symbolic $linkdir $tempdir
+ file type $linkdir
+} -cleanup {
+ file delete $linkdir
+ removeDirectory $tempdir
+} -result link
+test cmdAH-29.5 {Tcl_FileObjCmd: type} {
+ list [catch {file type _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+
+# Error conditions
+test cmdAH-30.1 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+ file gorp x
+} -result {unknown or ambiguous subcommand "gorp": must be atime, attributes, channels, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, link, lstat, mkdir, mtime, nativename, normalize, owned, pathtype, readable, readlink, rename, rootname, separator, size, split, stat, system, tail, tempfile, type, volumes, or writable}
+test cmdAH-30.2 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+ file ex x
+} -match glob -result {unknown or ambiguous subcommand "ex": must be *}
+test cmdAH-30.3 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+ file is x
+} -match glob -result {unknown or ambiguous subcommand "is": must be *}
+test cmdAH-30.4 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+ file z x
+} -match glob -result {unknown or ambiguous subcommand "z": must be *}
+test cmdAH-30.5 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+ file read x
+} -match glob -result {unknown or ambiguous subcommand "read": must be *}
+test cmdAH-30.6 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+ file s x
+} -match glob -result {unknown or ambiguous subcommand "s": must be *}
+test cmdAH-30.7 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+ file t x
+} -match glob -result {unknown or ambiguous subcommand "t": must be *}
+test cmdAH-30.8 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+ file dirname ~woohgy
+} -result {user "woohgy" doesn't exist}
+
+# channels
+# In testing 'file channels', we need to make sure that a channel created in
+# one interp isn't visible in another.
+
+interp create simpleInterp
+interp create -safe safeInterp
+interp create
+catch {safeInterp expose file file}
+
+test cmdAH-31.1 {Tcl_FileObjCmd: channels, too many args} -body {
+ file channels a b
+} -returnCodes error -result {wrong # args: should be "file channels ?pattern?"}
+test cmdAH-31.2 {Tcl_FileObjCmd: channels, too many args} {
+ # Normal interps start out with only the standard channels
+ lsort [simpleInterp eval [list file chan]]
+} {stderr stdin stdout}
+test cmdAH-31.3 {Tcl_FileObjCmd: channels, globbing} {
+ string equal [file channels] [file channels *]
+} {1}
+test cmdAH-31.4 {Tcl_FileObjCmd: channels, globbing} {
+ lsort [file channels std*]
+} {stderr stdin stdout}
+set newFileId [open $gorpfile w]
+test cmdAH-31.5 {Tcl_FileObjCmd: channels} {
+ set res [file channels $newFileId]
+ string equal $newFileId $res
+} {1}
+test cmdAH-31.6 {Tcl_FileObjCmd: channels in other interp} {
+ # Safe interps start out with no channels
+ safeInterp eval [list file channels]
+} {}
+test cmdAH-31.7 {Tcl_FileObjCmd: channels in other interp} -body {
+ safeInterp eval [list puts $newFileId "hello"]
+} -returnCodes error -result "can not find channel named \"$newFileId\""
+interp share {} $newFileId safeInterp
+interp share {} stdout safeInterp
+test cmdAH-31.8 {Tcl_FileObjCmd: channels in other interp} {
+ # $newFileId should now be visible in both interps
+ list [file channels $newFileId] \
+ [safeInterp eval [list file channels $newFileId]]
+} [list $newFileId $newFileId]
+test cmdAH-31.9 {Tcl_FileObjCmd: channels in other interp} {
+ lsort [safeInterp eval [list file channels]]
+} [lsort [list stdout $newFileId]]
+test cmdAH-31.10 {Tcl_FileObjCmd: channels in other interp} {
+ # we can now write to $newFileId from slave
+ safeInterp eval [list puts $newFileId "hello"]
+} {}
+interp transfer {} $newFileId safeInterp
+test cmdAH-31.11 {Tcl_FileObjCmd: channels in other interp} {
+ # $newFileId should now be visible only in safeInterp
+ list [file channels $newFileId] \
+ [safeInterp eval [list file channels $newFileId]]
+} [list {} $newFileId]
+test cmdAH-31.12 {Tcl_FileObjCmd: channels in other interp} {
+ lsort [safeInterp eval [list file channels]]
+} [lsort [list stdout $newFileId]]
+test cmdAH-31.13 {Tcl_FileObjCmd: channels in other interp} {
+ safeInterp eval [list close $newFileId]
+ safeInterp eval [list file channels]
+} {stdout}
+
+# Temp files (TIP#210)
+test cmdAH-32.1 {file tempfile - usage} -returnCodes error -body {
+ file tempfile a b c
+} -result {wrong # args: should be "file tempfile ?nameVar? ?template?"}
+test cmdAH-32.2 {file tempfile - returns a read/write channel} -body {
+ set f [file tempfile]
+ puts $f ok
+ seek $f 0
+ gets $f
+} -cleanup {
+ catch {close $f}
+} -result ok
+test cmdAH-32.3 {file tempfile - makes filenames} -setup {
+ unset -nocomplain name
+} -body {
+ set result [info exists name]
+ set f [file tempfile name]
+ lappend result [info exists name] [file exists $name]
+ close $f
+ lappend result [file exists $name]
+} -cleanup {
+ catch {close $f}
+ catch {file delete $name}
+} -result {0 1 1 1}
+# We try to obey the template on Unix, but don't (currently) bother on Win
+test cmdAH-32.4 {file tempfile - templates} -constraints unix -body {
+ close [file tempfile name foo]
+ expr {[string match foo* [file tail $name]] ? "ok" : "foo produced $name"}
+} -cleanup {
+ catch {file delete $name}
+} -result ok
+test cmdAH-32.5 {file tempfile - templates} -constraints unix -body {
+ set template [file join $dirfile foo]
+ close [file tempfile name $template]
+ expr {[string match $template* $name] ? "ok" : "$template produced $name"}
+} -cleanup {
+ catch {file delete $name}
+} -result ok
+# Not portable; not all unix systems have mkstemps()
+test cmdAH-32.6 {file tempfile - templates} -body {
+ set template [file join $dirfile foo]
+ close [file tempfile name $template.bar]
+ expr {[string match $template*.bar $name] ? "ok" :
+ "$template.bar produced $name"}
+} -constraints {unix nonPortable} -cleanup {
+ catch {file delete $name}
+} -result ok
+
+# This shouldn't work, but just in case a test above failed...
+catch {close $newFileId}
+
+interp delete safeInterp
+interp delete simpleInterp
+
+# cleanup
+catch {testsetplatform $platform}
+unset -nocomplain platform
+
+# Tcl_ForObjCmd is tested in for.test
+
+catch {file attributes $dirfile -permissions 0777}
+removeDirectory $dirfile
+removeFile $gorpfile
+# No idea how well [removeFile] copes with links...
+file delete $linkfile
+
+cd $cmdAHwd
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/cmdIL.test b/pkgs/msgcat/tests/cmdIL.test
new file mode 100644
index 0000000..4b1002a
--- /dev/null
+++ b/pkgs/msgcat/tests/cmdIL.test
@@ -0,0 +1,723 @@
+# This file contains a collection of tests for the procedures in the file
+# tclCmdIL.c. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Used for constraining memory leak tests
+testConstraint memory [llength [info commands memory]]
+testConstraint testobj [llength [info commands testobj]]
+
+test cmdIL-1.1 {Tcl_LsortObjCmd procedure} -returnCodes error -body {
+ lsort
+} -result {wrong # args: should be "lsort ?-option value ...? list"}
+test cmdIL-1.2 {Tcl_LsortObjCmd procedure} -returnCodes error -body {
+ lsort -foo {1 3 2 5}
+} -result {bad option "-foo": must be -ascii, -command, -decreasing, -dictionary, -increasing, -index, -indices, -integer, -nocase, -real, -stride, or -unique}
+test cmdIL-1.3 {Tcl_LsortObjCmd procedure, default options} {
+ lsort {d e c b a \{ d35 d300}
+} {a b c d d300 d35 e \{}
+test cmdIL-1.4 {Tcl_LsortObjCmd procedure, -ascii option} {
+ lsort -integer -ascii {d e c b a d35 d300}
+} {a b c d d300 d35 e}
+test cmdIL-1.5 {Tcl_LsortObjCmd procedure, -command option} -body {
+ lsort -command {1 3 2 5}
+} -returnCodes error -result {"-command" option must be followed by comparison command}
+test cmdIL-1.6 {Tcl_LsortObjCmd procedure, -command option} -setup {
+ proc cmp {a b} {
+ expr {[string match x* $b] - [string match x* $a]}
+ }
+} -body {
+ lsort -command cmp {x1 abc x2 def x3 x4}
+} -result {x1 x2 x3 x4 abc def} -cleanup {
+ rename cmp ""
+}
+test cmdIL-1.7 {Tcl_LsortObjCmd procedure, -decreasing option} {
+ lsort -decreasing {d e c b a d35 d300}
+} {e d35 d300 d c b a}
+test cmdIL-1.8 {Tcl_LsortObjCmd procedure, -dictionary option} {
+ lsort -dictionary {d e c b a d35 d300}
+} {a b c d d35 d300 e}
+test cmdIL-1.9 {Tcl_LsortObjCmd procedure, -dictionary option} {
+ lsort -dictionary {1k 0k 10k}
+} {0k 1k 10k}
+test cmdIL-1.10 {Tcl_LsortObjCmd procedure, -increasing option} {
+ lsort -decreasing -increasing {d e c b a d35 d300}
+} {a b c d d300 d35 e}
+test cmdIL-1.11 {Tcl_LsortObjCmd procedure, -index option} -body {
+ lsort -index {1 3 2 5}
+} -returnCodes error -result {"-index" option must be followed by list index}
+test cmdIL-1.12 {Tcl_LsortObjCmd procedure, -index option} -body {
+ lsort -index foo {1 3 2 5}
+} -returnCodes error -result {bad index "foo": must be integer?[+-]integer? or end?[+-]integer?}
+test cmdIL-1.13 {Tcl_LsortObjCmd procedure, -index option} {
+ lsort -index end -integer {{2 25} {10 20 50 100} {3 16 42} 1}
+} {1 {2 25} {3 16 42} {10 20 50 100}}
+test cmdIL-1.14 {Tcl_LsortObjCmd procedure, -index option} {
+ lsort -index 1 -integer {{1 25 100} {3 16 42} {10 20 50}}
+} {{3 16 42} {10 20 50} {1 25 100}}
+test cmdIL-1.15 {Tcl_LsortObjCmd procedure, -integer option} {
+ lsort -integer {24 6 300 18}
+} {6 18 24 300}
+test cmdIL-1.16 {Tcl_LsortObjCmd procedure, -integer option} -body {
+ lsort -integer {1 3 2.4}
+} -returnCodes error -result {expected integer but got "2.4"}
+test cmdIL-1.17 {Tcl_LsortObjCmd procedure, -real option} {
+ lsort -real {24.2 6e3 150e-1}
+} {150e-1 24.2 6e3}
+test cmdIL-1.18 {Tcl_LsortObjCmd procedure, bogus list} -body {
+ lsort "1 2 3 \{ 4"
+} -returnCodes error -result {unmatched open brace in list}
+test cmdIL-1.19 {Tcl_LsortObjCmd procedure, empty list} {
+ lsort {}
+} {}
+test cmdIL-1.22 {Tcl_LsortObjCmd procedure, unique sort} {
+ lsort -integer -unique {3 1 2 3 1 4 3}
+} {1 2 3 4}
+test cmdIL-1.23 {Tcl_LsortObjCmd procedure, unique sort with index} {
+ # lsort -unique should return the last unique item
+ lsort -unique -index 0 {{a b} {c b} {a c} {d a}}
+} {{a c} {c b} {d a}}
+test cmdIL-1.24 {Tcl_LsortObjCmd procedure, order of -index and -command} -setup {
+ catch {rename 1 ""}
+ proc testcmp {a b} {return [string compare $a $b]}
+} -body {
+ set l [list [list a b] [list c d]]
+ lsort -command testcmp -index 1 $l
+} -cleanup {
+ rename testcmp ""
+} -result [list [list a b] [list c d]]
+test cmdIL-1.25 {Tcl_LsortObjCmd procedure, order of -index and -command} -setup {
+ catch {rename 1 ""}
+ proc testcmp {a b} {return [string compare $a $b]}
+} -body {
+ set l [list [list a b] [list c d]]
+ lsort -index 1 -command testcmp $l
+} -cleanup {
+ rename testcmp ""
+} -result [list [list a b] [list c d]]
+# Note that the required order only exists in the end-1'th element; indexing
+# using the end element or any fixed offset from the start will not work...
+test cmdIL-1.26 {Tcl_LsortObjCmd procedure, offset indexing from end} {
+ lsort -index end-1 {{a 1 e i} {b 2 3 f g} {c 4 5 6 d h}}
+} {{c 4 5 6 d h} {a 1 e i} {b 2 3 f g}}
+test cmdIL-1.27 {Tcl_LsortObjCmd procedure, returning indices} {
+ lsort -indices {a c b}
+} {0 2 1}
+test cmdIL-1.28 {Tcl_LsortObjCmd procedure, returning indices} {
+ lsort -indices -unique -decreasing -real {1.2 34.5 34.5 5.6}
+} {2 3 0}
+test cmdIL-1.29 {Tcl_LsortObjCmd procedure, loss of list rep during sorting} {
+ set l {1 2 3}
+ string length [lsort -command {apply {args {string length $::l}}} $l]
+} 5
+test cmdIL-1.30 {Tcl_LsortObjCmd procedure, -stride option} {
+ lsort -stride 2 {f e d c b a}
+} {b a d c f e}
+test cmdIL-1.31 {Tcl_LsortObjCmd procedure, -stride option} {
+ lsort -stride 3 {f e d c b a}
+} {c b a f e d}
+test cmdIL-1.32 {lsort -stride errors} -returnCodes error -body {
+ lsort -stride foo bar
+} -result {expected integer but got "foo"}
+test cmdIL-1.33 {lsort -stride errors} -returnCodes error -body {
+ lsort -stride 1 bar
+} -result {stride length must be at least 2}
+test cmdIL-1.34 {lsort -stride errors} -returnCodes error -body {
+ lsort -stride 2 {a b c}
+} -result {list size must be a multiple of the stride length}
+test cmdIL-1.35 {lsort -stride errors} -returnCodes error -body {
+ lsort -stride 2 -index 3 {a b c d}
+} -result {when used with "-stride", the leading "-index" value must be within the group}
+test cmdIL-1.36 {lsort -stride and -index: Bug 2918962} {
+ lsort -stride 2 -index {0 1} {
+ {{c o d e} 54321} {{b l a h} 94729}
+ {{b i g} 12345} {{d e m o} 34512}
+ }
+} {{{b i g} 12345} {{d e m o} 34512} {{c o d e} 54321} {{b l a h} 94729}}
+
+# Can't think of any good tests for the MergeSort and MergeLists procedures,
+# except a bunch of random lists to sort.
+
+test cmdIL-2.1 {MergeSort and MergeLists procedures} -setup {
+ set result {}
+ set r 1435753299
+ proc rand {} {
+ global r
+ set r [expr {(16807 * $r) % (0x7fffffff)}]
+ }
+} -body {
+ for {set i 0} {$i < 150} {incr i} {
+ set x {}
+ for {set j 0} {$j < $i} {incr j} {
+ lappend x [expr {[rand] & 0xfff}]
+ }
+ set y [lsort -integer $x]
+ set old -1
+ foreach el $y {
+ if {$el < $old} {
+ append result "list {$x} sorted to {$y}, element $el out of order\n"
+ break
+ }
+ set old $el
+ }
+ }
+ string trim $result
+} -cleanup {
+ rename rand ""
+} -result {}
+
+test cmdIL-3.1 {SortCompare procedure, skip comparisons after error} -body {
+ set ::x 0
+ list [catch {
+ lsort -integer -command {apply {{a b} {
+ incr ::x
+ error "error #$::x"
+ }}} {48 6 28 190 16 2 3 6 1}
+ } msg] $msg $::x
+} -result {1 {error #1} 1}
+test cmdIL-3.2 {SortCompare procedure, -index option} -body {
+ lsort -integer -index 2 "\\\{ {30 40 50}"
+} -returnCodes error -result {unmatched open brace in list}
+test cmdIL-3.3 {SortCompare procedure, -index option} -body {
+ lsort -integer -index 2 {{20 10} {15 30 40}}
+} -returnCodes error -result {element 2 missing from sublist "20 10"}
+test cmdIL-3.4 {SortCompare procedure, -index option} -body {
+ lsort -integer -index 2 "{a b c} \\\{"
+} -returnCodes error -result {expected integer but got "c"}
+test cmdIL-3.4.1 {SortCompare procedure, -index option} -body {
+ lsort -integer -index 2 "{1 2 3} \\\{"
+} -returnCodes error -result {unmatched open brace in list}
+test cmdIL-3.5 {SortCompare procedure, -index option} -body {
+ lsort -integer -index 2 {{20 10 13} {15}}
+} -returnCodes error -result {element 2 missing from sublist "15"}
+test cmdIL-3.6 {SortCompare procedure, -index option} {
+ lsort -integer -index 2 {{1 15 30} {2 5 25} {3 25 20}}
+} {{3 25 20} {2 5 25} {1 15 30}}
+test cmdIL-3.7 {SortCompare procedure, -ascii option} {
+ lsort -ascii {d e c b a d35 d300 100 20}
+} {100 20 a b c d d300 d35 e}
+test cmdIL-3.8 {SortCompare procedure, -dictionary option} {
+ lsort -dictionary {d e c b a d35 d300 100 20}
+} {20 100 a b c d d35 d300 e}
+test cmdIL-3.9 {SortCompare procedure, -integer option} -body {
+ lsort -integer {x 3}
+} -returnCodes error -result {expected integer but got "x"}
+test cmdIL-3.10 {SortCompare procedure, -integer option} -body {
+ lsort -integer {3 q}
+} -returnCodes error -result {expected integer but got "q"}
+test cmdIL-3.11 {SortCompare procedure, -integer option} {
+ lsort -integer {35 21 0x20 30 0o23 100 8}
+} {8 0o23 21 30 0x20 35 100}
+test cmdIL-3.12 {SortCompare procedure, -real option} -body {
+ lsort -real {6...4 3}
+} -returnCodes error -result {expected floating-point number but got "6...4"}
+test cmdIL-3.13 {SortCompare procedure, -real option} -body {
+ lsort -real {3 1x7}
+} -returnCodes error -result {expected floating-point number but got "1x7"}
+test cmdIL-3.14 {SortCompare procedure, -real option} {
+ lsort -real {24 2.5e01 16.7 85e-1 10.004}
+} {85e-1 10.004 16.7 24 2.5e01}
+test cmdIL-3.15 {SortCompare procedure, -command option} -body {
+ proc cmp {a b} {
+ error "comparison error"
+ }
+ list [catch {lsort -command cmp {48 6}} msg] $msg $::errorInfo
+} -cleanup {
+ rename cmp ""
+} -result {1 {comparison error} {comparison error
+ while executing
+"error "comparison error""
+ (procedure "cmp" line 2)
+ invoked from within
+"cmp 48 6"
+ (-compare command)
+ invoked from within
+"lsort -command cmp {48 6}"}}
+test cmdIL-3.16 {SortCompare procedure, -command option, long command} -body {
+ proc cmp {dummy a b} {
+ string compare $a $b
+ }
+ lsort -command {cmp {this argument is very very long in order to make the dstring overflow its statically allocated space}} {{this first element is also long in order to help expand the dstring} {the second element, last but not least, is quite long also, in order to make absolutely sure that space is allocated dynamically for the dstring}}
+} -cleanup {
+ rename cmp ""
+} -result {{the second element, last but not least, is quite long also, in order to make absolutely sure that space is allocated dynamically for the dstring} {this first element is also long in order to help expand the dstring}}
+test cmdIL-3.17 {SortCompare procedure, -command option, non-integer result} -body {
+ proc cmp {a b} {
+ return foow
+ }
+ lsort -command cmp {48 6}
+} -returnCodes error -cleanup {
+ rename cmp ""
+} -result {-compare command returned non-integer result}
+test cmdIL-3.18 {SortCompare procedure, -command option} -body {
+ proc cmp {a b} {
+ expr {$b - $a}
+ }
+ lsort -command cmp {48 6 18 22 21 35 36}
+} -cleanup {
+ rename cmp ""
+} -result {48 36 35 22 21 18 6}
+test cmdIL-3.19 {SortCompare procedure, -decreasing option} {
+ lsort -decreasing -integer {35 21 0x20 30 0o23 100 8}
+} {100 35 0x20 30 21 0o23 8}
+
+test cmdIL-4.1 {DictionaryCompare procedure, numerics, leading zeros} {
+ lsort -dictionary {a003b a03b}
+} {a03b a003b}
+test cmdIL-4.2 {DictionaryCompare procedure, numerics, leading zeros} {
+ lsort -dictionary {a3b a03b}
+} {a3b a03b}
+test cmdIL-4.3 {DictionaryCompare procedure, numerics, leading zeros} {
+ lsort -dictionary {a3b A03b}
+} {A03b a3b}
+test cmdIL-4.4 {DictionaryCompare procedure, numerics, leading zeros} {
+ lsort -dictionary {a3b a03B}
+} {a3b a03B}
+test cmdIL-4.5 {DictionaryCompare procedure, numerics, leading zeros} {
+ lsort -dictionary {00000 000}
+} {000 00000}
+test cmdIL-4.6 {DictionaryCompare procedure, numerics, different lengths} {
+ lsort -dictionary {a321b a03210b}
+} {a321b a03210b}
+test cmdIL-4.7 {DictionaryCompare procedure, numerics, different lengths} {
+ lsort -dictionary {a03210b a321b}
+} {a321b a03210b}
+test cmdIL-4.8 {DictionaryCompare procedure, numerics} {
+ lsort -dictionary {48 6a 18b 22a 21aa 35 36}
+} {6a 18b 21aa 22a 35 36 48}
+test cmdIL-4.9 {DictionaryCompare procedure, numerics} {
+ lsort -dictionary {a123x a123b}
+} {a123b a123x}
+test cmdIL-4.10 {DictionaryCompare procedure, numerics} {
+ lsort -dictionary {a123b a123x}
+} {a123b a123x}
+test cmdIL-4.11 {DictionaryCompare procedure, numerics} {
+ lsort -dictionary {a1b aab}
+} {a1b aab}
+test cmdIL-4.12 {DictionaryCompare procedure, numerics} {
+ lsort -dictionary {a1b a!b}
+} {a!b a1b}
+test cmdIL-4.13 {DictionaryCompare procedure, numerics} {
+ lsort -dictionary {a1b2c a1b1c}
+} {a1b1c a1b2c}
+test cmdIL-4.14 {DictionaryCompare procedure, numerics} {
+ lsort -dictionary {a1b2c a1b3c}
+} {a1b2c a1b3c}
+test cmdIL-4.15 {DictionaryCompare procedure, long numbers} {
+ lsort -dictionary {a7654884321988762b a7654884321988761b}
+} {a7654884321988761b a7654884321988762b}
+test cmdIL-4.16 {DictionaryCompare procedure, long numbers} {
+ lsort -dictionary {a8765488432198876b a7654884321988761b}
+} {a7654884321988761b a8765488432198876b}
+test cmdIL-4.17 {DictionaryCompare procedure, case} {
+ lsort -dictionary {aBCd abcc}
+} {abcc aBCd}
+test cmdIL-4.18 {DictionaryCompare procedure, case} {
+ lsort -dictionary {aBCd abce}
+} {aBCd abce}
+test cmdIL-4.19 {DictionaryCompare procedure, case} {
+ lsort -dictionary {abcd ABcc}
+} {ABcc abcd}
+test cmdIL-4.20 {DictionaryCompare procedure, case} {
+ lsort -dictionary {abcd ABce}
+} {abcd ABce}
+test cmdIL-4.21 {DictionaryCompare procedure, case} {
+ lsort -dictionary {abCD ABcd}
+} {ABcd abCD}
+test cmdIL-4.22 {DictionaryCompare procedure, case} {
+ lsort -dictionary {ABcd aBCd}
+} {ABcd aBCd}
+test cmdIL-4.23 {DictionaryCompare procedure, case} {
+ lsort -dictionary {ABcd AbCd}
+} {ABcd AbCd}
+test cmdIL-4.24 {DictionaryCompare procedure, international characters} {hasIsoLocale} {
+ ::tcltest::set_iso8859_1_locale
+ set result [lsort -dictionary "a b c A B C \xe3 \xc4"]
+ ::tcltest::restore_locale
+ set result
+} "A a B b C c \xe3 \xc4"
+test cmdIL-4.25 {DictionaryCompare procedure, international characters} {hasIsoLocale} {
+ ::tcltest::set_iso8859_1_locale
+ set result [lsort -dictionary "a23\xe3 a23\xc5 a23\xe4"]
+ ::tcltest::restore_locale
+ set result
+} "a23\xe3 a23\xe4 a23\xc5"
+test cmdIL-4.26 {DefaultCompare procedure, signed characters} {
+ set l [lsort [list "abc\200" "abc"]]
+ set viewlist {}
+ foreach s $l {
+ set viewelem ""
+ set len [string length $s]
+ for {set i 0} {$i < $len} {incr i} {
+ set c [string index $s $i]
+ scan $c %c d
+ if {$d > 0 && $d < 128} {
+ append viewelem $c
+ } else {
+ append viewelem "\\[format %03o $d]"
+ }
+ }
+ lappend viewlist $viewelem
+ }
+ set viewlist
+} [list "abc" "abc\\200"]
+test cmdIL-4.27 {DictionaryCompare procedure, signed characters} {
+ set l [lsort -dictionary [list "abc\200" "abc"]]
+ set viewlist {}
+ foreach s $l {
+ set viewelem ""
+ set len [string length $s]
+ for {set i 0} {$i < $len} {incr i} {
+ set c [string index $s $i]
+ scan $c %c d
+ if {$d > 0 && $d < 128} {
+ append viewelem $c
+ } else {
+ append viewelem "\\[format %03o $d]"
+ }
+ }
+ lappend viewlist $viewelem
+ }
+ set viewlist
+} [list "abc" "abc\\200"]
+test cmdIL-4.28 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+ lsort -dictionary [list AA ` c CC]
+} [list ` AA c CC]
+test cmdIL-4.29 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+ lsort -dictionary [list AA ` c ^ \\ CC \[ \]]
+} [list \[ \\ \] ^ ` AA c CC]
+test cmdIL-4.30 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+ lsort -dictionary [list AA ` c ^ _ \\ CC \[ dude \] funky]
+} [list \[ \\ \] ^ _ ` AA c CC dude funky]
+test cmdIL-4.31 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+ lsort -dictionary [list AA c ` CC]
+} [list ` AA c CC]
+test cmdIL-4.32 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+ lsort -dictionary [list AA c CC `]
+} [list ` AA c CC]
+test cmdIL-4.33 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+ lsort -dictionary [list AA ! c CC `]
+} [list ! ` AA c CC]
+test cmdIL-4.34 {SortCompare procedure, -ascii option with -nocase option} {
+ lsort -ascii -nocase {d e c b a d35 d300 100 20}
+} {100 20 a b c d d300 d35 e}
+test cmdIL-4.35 {SortCompare procedure, -ascii option with -nocase option} {
+ lsort -ascii -nocase {d E c B a D35 d300 100 20}
+} {100 20 a B c d d300 D35 E}
+
+test cmdIL-5.1 {lsort with list style index} {
+ lsort -ascii -decreasing -index {0 1} {
+ {{Jim Alpha} 20000410}
+ {{Joe Bravo} 19990320}
+ {{Jacky Charlie} 19390911}
+ }
+} {{{Jacky Charlie} 19390911} {{Joe Bravo} 19990320} {{Jim Alpha} 20000410}}
+test cmdIL-5.2 {lsort with list style index} {
+ lsort -decreasing -index {0 1} {
+ {{Jim Alpha} 20000410}
+ {{Joe Bravo} 19990320}
+ {{Jacky Charlie} 19390911}
+ }
+} {{{Jacky Charlie} 19390911} {{Joe Bravo} 19990320} {{Jim Alpha} 20000410}}
+test cmdIL-5.3 {lsort with list style index} {
+ lsort -integer -increasing -index {1 end} {
+ {{Jim Alpha} 20000410}
+ {{Joe Bravo} 19990320}
+ {{Jacky Charlie} 19390911}
+ }
+} {{{Jacky Charlie} 19390911} {{Joe Bravo} 19990320} {{Jim Alpha} 20000410}}
+test cmdIL-5.4 {lsort with list style index} {
+ lsort -integer -index {1 end-1} {
+ {the {0 1 2 3 4 5} quick}
+ {brown {0 1 2 3 4} fox}
+ {jumps {30 31 2 33} over}
+ {the {0 1 2} lazy}
+ {dogs {0 1}}
+ }
+} {{dogs {0 1}} {the {0 1 2} lazy} {jumps {30 31 2 33} over} {brown {0 1 2 3 4} fox} {the {0 1 2 3 4 5} quick}}
+test cmdIL-5.5 {lsort with list style index and sharing} -body {
+ proc test_lsort {l} {
+ set n $l
+ foreach e $l {lappend n [list [expr {rand()}] $e]}
+ lindex [lsort -real -index $l $n] 1 1
+ }
+ expr srand(1)
+ test_lsort 0
+} -result 0 -cleanup {
+ rename test_lsort ""
+}
+test cmdIL-5.6 {lsort with multiple list-style index options} {
+ lsort -index {1 2 3} -index 0 {{a b} {c d} {b e}}
+} {{a b} {b e} {c d}}
+
+# Compiled version
+test cmdIL-6.1 {lassign command syntax} -returnCodes error -body {
+ apply {{} { lassign }}
+} -result {wrong # args: should be "lassign list ?varName ...?"}
+test cmdIL-6.2 {lassign command syntax} {
+ apply {{} { lassign x }}
+} x
+test cmdIL-6.3 {lassign command} -body {
+ apply {{} {
+ set x FAIL
+ list [lassign a x] $x
+ }}
+} -result {{} a}
+test cmdIL-6.4 {lassign command} -body {
+ apply {{} {
+ set x FAIL
+ set y FAIL
+ list [lassign a x y] $x $y
+ }}
+} -result {{} a {}}
+test cmdIL-6.5 {lassign command} -body {
+ apply {{} {
+ set x FAIL
+ set y FAIL
+ list [lassign {a b} x y] $x $y
+ }}
+} -result {{} a b}
+test cmdIL-6.6 {lassign command} -body {
+ apply {{} {
+ set x FAIL
+ set y FAIL
+ list [lassign {a b c} x y] $x $y
+ }}
+} -result {c a b}
+test cmdIL-6.7 {lassign command} -body {
+ apply {{} {
+ set x FAIL
+ set y FAIL
+ list [lassign {a b c d} x y] $x $y
+ }}
+} -result {{c d} a b}
+test cmdIL-6.8 {lassign command - list format error} -body {
+ apply {{} {
+ set x FAIL
+ set y FAIL
+ list [catch {lassign {a {b}c d} x y} msg] $msg $x $y
+ }}
+} -result {1 {list element in braces followed by "c" instead of space} FAIL FAIL}
+test cmdIL-6.9 {lassign command - assignment to arrays} -body {
+ apply {{} {
+ list [lassign {a b} x(x)] $x(x)
+ }}
+} -result {b a}
+test cmdIL-6.10 {lassign command - variable update error} -body {
+ apply {{} {
+ set x(x) {}
+ lassign a x
+ }}
+} -returnCodes error -result {can't set "x": variable is array}
+test cmdIL-6.11 {lassign command - variable update error} -body {
+ apply {{} {
+ set x(x) {}
+ set y FAIL
+ list [catch {lassign a y x} msg] $msg $y
+ }}
+} -result {1 {can't set "x": variable is array} a}
+test cmdIL-6.12 {lassign command - memory leak testing} -setup {
+ unset -nocomplain x y
+ set x(x) {}
+ set y FAIL
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex [lindex $lines 3] 3
+ }
+ proc stress {} {
+ global x y
+ lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y
+ catch {lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y x}
+ catch {lassign {} x}
+ }
+} -constraints memory -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ stress
+ set tmp $end
+ set end [getbytes]
+ }
+ expr {$end - $tmp}
+} -result 0 -cleanup {
+ unset -nocomplain x y i tmp end
+ rename getbytes {}
+ rename stress {}
+}
+# Force non-compiled version
+test cmdIL-6.13 {lassign command syntax} -returnCodes error -body {
+ apply {{} {
+ set lassign lassign
+ $lassign
+ }}
+} -result {wrong # args: should be "lassign list ?varName ...?"}
+test cmdIL-6.14 {lassign command syntax} {
+ apply {{} {
+ set lassign lassign
+ $lassign x
+ }}
+} x
+test cmdIL-6.15 {lassign command} -body {
+ apply {{} {
+ set lassign lassign
+ set x FAIL
+ list [$lassign a x] $x
+ }}
+} -result {{} a}
+test cmdIL-6.16 {lassign command} -body {
+ apply {{} {
+ set lassign lassign
+ set x FAIL
+ set y FAIL
+ list [$lassign a x y] $x $y
+ }}
+} -result {{} a {}}
+test cmdIL-6.17 {lassign command} -body {
+ apply {{} {
+ set lassign lassign
+ set x FAIL
+ set y FAIL
+ list [$lassign {a b} x y] $x $y
+ }}
+} -result {{} a b}
+test cmdIL-6.18 {lassign command} -body {
+ apply {{} {
+ set lassign lassign
+ set x FAIL
+ set y FAIL
+ list [$lassign {a b c} x y] $x $y
+ }}
+} -result {c a b}
+test cmdIL-6.19 {lassign command} -body {
+ apply {{} {
+ set lassign lassign
+ set x FAIL
+ set y FAIL
+ list [$lassign {a b c d} x y] $x $y
+ }}
+} -result {{c d} a b}
+test cmdIL-6.20 {lassign command - list format error} -body {
+ apply {{} {
+ set lassign lassign
+ set x FAIL
+ set y FAIL
+ list [catch {$lassign {a {b}c d} x y} msg] $msg $x $y
+ }}
+} -result {1 {list element in braces followed by "c" instead of space} FAIL FAIL}
+test cmdIL-6.21 {lassign command - assignment to arrays} -body {
+ apply {{} {
+ set lassign lassign
+ list [$lassign {a b} x(x)] $x(x)
+ }}
+} -result {b a}
+test cmdIL-6.22 {lassign command - variable update error} -body {
+ apply {{} {
+ set lassign lassign
+ set x(x) {}
+ $lassign a x
+ }}
+} -returnCodes 1 -result {can't set "x": variable is array}
+test cmdIL-6.23 {lassign command - variable update error} -body {
+ apply {{} {
+ set lassign lassign
+ set x(x) {}
+ set y FAIL
+ list [catch {$lassign a y x} msg] $msg $y
+ }}
+} -result {1 {can't set "x": variable is array} a}
+test cmdIL-6.24 {lassign command - memory leak testing} -setup {
+ set x(x) {}
+ set y FAIL
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex [lindex $lines 3] 3
+ }
+ proc stress {} {
+ global x y
+ set lassign lassign
+ $lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y
+ catch {$lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y x}
+ catch {$lassign {} x}
+ }
+} -constraints memory -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ stress
+ set tmp $end
+ set end [getbytes]
+ }
+ expr {$end - $tmp}
+} -result 0 -cleanup {
+ unset -nocomplain x y i tmp end
+ rename getbytes {}
+ rename stress {}
+}
+# Assorted shimmering problems
+test cmdIL-6.25 {lassign command - shimmering protection} -body {
+ apply {{} {
+ set x {a b c}
+ list [lassign $x $x y] $x [set $x] $y
+ }}
+} -result {c {a b c} a b}
+test cmdIL-6.26 {lassign command - shimmering protection} -body {
+ apply {{} {
+ set x {a b c}
+ set lassign lassign
+ list [$lassign $x $x y] $x [set $x] $y
+ }}
+} -result {c {a b c} a b}
+
+test cmdIL-7.1 {lreverse command} -body {
+ lreverse
+} -returnCodes error -result "wrong # args: should be \"lreverse list\""
+test cmdIL-7.2 {lreverse command} -body {
+ lreverse a b
+} -returnCodes error -result "wrong # args: should be \"lreverse list\""
+test cmdIL-7.3 {lreverse command} -body {
+ lreverse "not \{a list"
+} -returnCodes error -result {unmatched open brace in list}
+test cmdIL-7.4 {lreverse command - shared object} {
+ set x {a b {c d} e f}
+ lreverse $x
+} {f e {c d} b a}
+test cmdIL-7.5 {lreverse command - unshared object} {
+ lreverse [list a b {c d} e f]
+} {f e {c d} b a}
+test cmdIL-7.6 {lreverse command - unshared object [Bug 1672585]} {
+ lreverse [set x {1 2 3}][unset x]
+} {3 2 1}
+test cmdIL-7.7 {lreverse command - empty object [Bug 1876793]} {
+ lreverse [list]
+} {}
+test cmdIL-7.8 {lreverse command - shared intrep [Bug 1675044]} -setup {
+ teststringobj set 1 {1 2 3}
+ testobj convert 1 list
+ testobj duplicate 1 2
+ variable x [teststringobj get 1]
+ variable y [teststringobj get 2]
+ testobj freeallvars
+ proc K {a b} {return $a}
+} -constraints testobj -body {
+ lreverse [K $y [unset y]]
+ lindex $x 0
+} -cleanup {
+ unset -nocomplain x y
+ rename K {}
+} -result 1
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/cmdInfo.test b/pkgs/msgcat/tests/cmdInfo.test
new file mode 100644
index 0000000..86aa6e1
--- /dev/null
+++ b/pkgs/msgcat/tests/cmdInfo.test
@@ -0,0 +1,106 @@
+# Commands covered: none
+#
+# This file contains a collection of tests for Tcl_GetCommandInfo,
+# Tcl_SetCommandInfo, Tcl_CreateCommand, Tcl_DeleteCommand, and
+# Tcl_NameOfCommand. Sourcing this file into Tcl runs the tests
+# and generates output for errors. No output means no errors were
+# found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testcmdinfo [llength [info commands testcmdinfo]]
+testConstraint testcmdtoken [llength [info commands testcmdtoken]]
+
+test cmdinfo-1.1 {command procedure and clientData} {testcmdinfo} {
+ testcmdinfo create x1
+ testcmdinfo get x1
+} {CmdProc1 original CmdDelProc1 original :: stringProc}
+test cmdinfo-1.2 {command procedure and clientData} {testcmdinfo} {
+ testcmdinfo create x1
+ x1
+} {CmdProc1 original}
+test cmdinfo-1.3 {command procedure and clientData} {testcmdinfo} {
+ testcmdinfo create x1
+ testcmdinfo modify x1
+ testcmdinfo get x1
+} {CmdProc2 new_command_data CmdDelProc2 new_delete_data :: stringProc}
+test cmdinfo-1.4 {command procedure and clientData} {testcmdinfo} {
+ testcmdinfo create x1
+ testcmdinfo modify x1
+ x1
+} {CmdProc2 new_command_data}
+
+test cmdinfo-2.1 {command deletion callbacks} {testcmdinfo} {
+ testcmdinfo create x1
+ testcmdinfo delete x1
+} {CmdDelProc1 original}
+test cmdinfo-2.2 {command deletion callbacks} {testcmdinfo} {
+ testcmdinfo create x1
+ testcmdinfo modify x1
+ testcmdinfo delete x1
+} {CmdDelProc2 new_delete_data}
+
+test cmdinfo-3.1 {Tcl_Get/SetCommandInfo return values} {testcmdinfo} {
+ testcmdinfo get non_existent
+} {??}
+test cmdinfo-3.2 {Tcl_Get/SetCommandInfo return values} {testcmdinfo} {
+ testcmdinfo create x1
+ testcmdinfo modify x1
+} 1
+test cmdinfo-3.3 {Tcl_Get/SetCommandInfo return values} {testcmdinfo} {
+ testcmdinfo modify non_existent
+} 0
+
+test cmdinfo-4.1 {Tcl_GetCommandName/Tcl_GetCommandFullName procedures} \
+ {testcmdtoken} {
+ set x [testcmdtoken create x1]
+ rename x1 newName
+ set y [testcmdtoken name $x]
+ rename newName x1
+ lappend y {*}[testcmdtoken name $x]
+} {newName ::newName x1 ::x1}
+
+catch {rename newTestCmd {}}
+catch {rename newTestCmd2 {}}
+
+test cmdinfo-5.1 {Names for commands created when inside namespaces} \
+ {testcmdtoken} {
+ # create namespace cmdInfoNs1
+ namespace eval cmdInfoNs1 {} ;# creates namespace cmdInfoNs1
+ # create namespace cmdInfoNs1::cmdInfoNs2 and execute a script in it
+ set x [namespace eval cmdInfoNs1::cmdInfoNs2 {
+ # the following creates a cmd in the global namespace
+ testcmdtoken create testCmd
+ }]
+ set y [testcmdtoken name $x]
+ rename ::testCmd newTestCmd
+ lappend y {*}[testcmdtoken name $x]
+} {testCmd ::testCmd newTestCmd ::newTestCmd}
+
+test cmdinfo-6.1 {Names for commands created when outside namespaces} \
+ {testcmdtoken} {
+ set x [testcmdtoken create cmdInfoNs1::cmdInfoNs2::testCmd]
+ set y [testcmdtoken name $x]
+ rename cmdInfoNs1::cmdInfoNs2::testCmd newTestCmd2
+ lappend y {*}[testcmdtoken name $x]
+} {testCmd ::cmdInfoNs1::cmdInfoNs2::testCmd newTestCmd2 ::newTestCmd2}
+
+# cleanup
+catch {namespace delete cmdInfoNs1::cmdInfoNs2 cmdInfoNs1}
+catch {rename x1 ""}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/cmdMZ.test b/pkgs/msgcat/tests/cmdMZ.test
new file mode 100644
index 0000000..2d68138
--- /dev/null
+++ b/pkgs/msgcat/tests/cmdMZ.test
@@ -0,0 +1,355 @@
+# The tests in this file cover the procedures in tclCmdMZ.c.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[catch {package require tcltest 2.1}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2.1 required."
+ return
+}
+
+namespace eval ::tcl::test::cmdMZ {
+ namespace import ::tcltest::cleanupTests
+ namespace import ::tcltest::customMatch
+ namespace import ::tcltest::makeFile
+ namespace import ::tcltest::removeFile
+ namespace import ::tcltest::temporaryDirectory
+ namespace import ::tcltest::test
+
+ proc ListGlobMatch {expected actual} {
+ if {[llength $expected] != [llength $actual]} {
+ return 0
+ }
+ foreach e $expected a $actual {
+ if {![string match $e $a]} {
+ return 0
+ }
+ }
+ return 1
+ }
+ customMatch listGlob [namespace which ListGlobMatch]
+
+# Tcl_PwdObjCmd
+
+test cmdMZ-1.1 {Tcl_PwdObjCmd} -returnCodes error -body {
+ pwd a
+} -result {wrong # args: should be "pwd"}
+test cmdMZ-1.2 {Tcl_PwdObjCmd: simple pwd} {
+ catch pwd
+} 0
+test cmdMZ-1.3 {Tcl_PwdObjCmd: simple pwd} -body {
+ pwd
+} -match glob -result {?*}
+test cmdMZ-1.4 {Tcl_PwdObjCmd: failure} -setup {
+ set cwd [pwd]
+ set foodir [file join [temporaryDirectory] foo]
+ file delete -force $foodir
+ file mkdir $foodir
+ cd $foodir
+} -constraints {unix nonPortable} -body {
+ # This test fails on various unix platforms (eg Linux) where permissions
+ # caching causes this to fail. The caching is strictly incorrect, but we
+ # have no control over that.
+ file attr . -permissions 000
+ pwd
+} -returnCodes error -cleanup {
+ cd $cwd
+ file delete -force $foodir
+} -result {error getting working directory name: permission denied}
+
+# The tests for Tcl_RegexpObjCmd, Tcl_RegsubObjCmd are in regexp.test
+
+# Tcl_RenameObjCmd
+
+test cmdMZ-2.1 {Tcl_RenameObjCmd: error conditions} -returnCodes error -body {
+ rename r1
+} -result {wrong # args: should be "rename oldName newName"}
+test cmdMZ-2.2 {Tcl_RenameObjCmd: error conditions} -returnCodes error -body {
+ rename r1 r2 r3
+} -result {wrong # args: should be "rename oldName newName"}
+test cmdMZ-2.3 {Tcl_RenameObjCmd: success} -setup {
+ catch {rename r2 {}}
+} -body {
+ proc r1 {} {return "r1"}
+ rename r1 r2
+ r2
+} -result {r1}
+test cmdMZ-2.4 {Tcl_RenameObjCmd: success} {
+ proc r1 {} {return "r1"}
+ rename r1 {}
+ list [catch {r1} msg] $msg
+} {1 {invalid command name "r1"}}
+
+# Some tests for Tcl_ReturnObjCmd are in proc-old.test
+
+test cmdMZ-return-1.0 {return checks for bad option values} -body {
+ return -options foo
+} -returnCodes error -match glob -result {bad -options value:*}
+test cmdMZ-return-1.1 {return checks for bad option values} -body {
+ return -code err
+} -returnCodes error -match glob -result {bad completion code "err": must be ok, error, return, break, continue*, or an integer}
+test cmdMZ-return-1.2 {return checks for bad option values} -body {
+ return -code 0x100000000
+} -returnCodes error -match glob -result {bad completion code "0x100000000": must be ok, error, return, break, continue*, or an integer}
+test cmdMZ-return-1.3 {return checks for bad option values} -body {
+ return -level foo
+} -returnCodes error -match glob -result {bad -level value: *}
+test cmdMZ-return-1.4 {return checks for bad option values} -body {
+ return -level -1
+} -returnCodes error -match glob -result {bad -level value: *}
+test cmdMZ-return-1.5 {return checks for bad option values} -body {
+ return -level 3.1415926
+} -returnCodes error -match glob -result {bad -level value: *}
+
+proc dictSort {d} {
+ set result {}
+ foreach k [lsort [dict keys $d]] {
+ dict set result $k [dict get $d $k]
+ }
+ return $result
+}
+
+test cmdMZ-return-2.0 {return option handling} {
+ list [catch return -> foo] [dictSort $foo]
+} {2 {-code 0 -level 1}}
+test cmdMZ-return-2.1 {return option handling} {
+ list [catch {return -bar soom} -> foo] [dictSort $foo]
+} {2 {-bar soom -code 0 -level 1}}
+test cmdMZ-return-2.2 {return option handling} {
+ list [catch {return -code return} -> foo] [dictSort $foo]
+} {2 {-code 0 -level 2}}
+test cmdMZ-return-2.3 {return option handling} {
+ list [catch {return -code return -level 10} -> foo] [dictSort $foo]
+} {2 {-code 0 -level 11}}
+test cmdMZ-return-2.4 {return option handling} -body {
+ return -level 0 -code error
+} -returnCodes error -result {}
+test cmdMZ-return-2.5 {return option handling} -body {
+ return -level 0 -code return
+} -returnCodes return -result {}
+test cmdMZ-return-2.6 {return option handling} -body {
+ return -level 0 -code break
+} -returnCodes break -result {}
+test cmdMZ-return-2.7 {return option handling} -body {
+ return -level 0 -code continue
+} -returnCodes continue -result {}
+test cmdMZ-return-2.8 {return option handling} -body {
+ return -level 0 -code -1
+} -returnCodes -1 -result {}
+test cmdMZ-return-2.9 {return option handling} -body {
+ return -level 0 -code 10
+} -returnCodes 10 -result {}
+test cmdMZ-return-2.10 {return option handling} -body {
+ list [catch {return -level 0 -code error} -> foo] [dictSort $foo]
+} -match glob -result {1 {-code 1 -errorcode NONE -errorinfo {
+ while executing
+"return -level 0 -code error"} -errorline 1 -errorstack * -level 0}}
+test cmdMZ-return-2.11 {return option handling} {
+ list [catch {return -level 0 -code break} -> foo] [dictSort $foo]
+} {3 {-code 3 -level 0}}
+test cmdMZ-return-2.12 {return option handling} -body {
+ return -level 0 -code error -options {-code ok}
+} -returnCodes ok -result {}
+test cmdMZ-return-2.13 {return option handling} -body {
+ return -level 0 -code error -options {-code err}
+} -returnCodes error -match glob -result {bad completion code "err": must be ok, error, return, break, continue*, or an integer}
+test cmdMZ-return-2.14 {return option handling} -body {
+ return -level 0 -code error -options {-code foo -options {-code break}}
+} -returnCodes break -result {}
+test cmdMZ-return-2.15 {return opton handling} {
+ list [catch {
+ apply {{} {
+ return -code error -errorcode {a b} c
+ }}
+ } result] $result $::errorCode
+} {1 c {a b}}
+test cmdMZ-return-2.16 {return opton handling} {
+ list [catch {
+ apply {{} {
+ return -code error -errorcode [list a b] c
+ }}
+ } result] $result $::errorCode
+} {1 c {a b}}
+test cmdMZ-return-2.17 {return opton handling} {
+ list [catch {
+ apply {{} {
+ return -code error -errorcode a\ b c
+ }}
+ } result] $result $::errorCode
+} {1 c {a b}}
+test cmdMZ-return-2.18 {return option handling} {
+ list [catch {
+ return -code error -errorstack [list CALL a CALL b] yo
+ } -> foo] [dictSort $foo] [info errorstack]
+} {2 {-code 1 -errorcode NONE -errorstack {CALL a CALL b} -level 1} {CALL a CALL b}}
+
+# Check that the result of a [return -options $opts $result] is
+# indistinguishable from that of the originally caught script, no matter what
+# the script is/does. (TIP 90)
+foreach {testid script} {
+ cmdMZ-return-3.0 {}
+ cmdMZ-return-3.1 {format x}
+ cmdMZ-return-3.2 {set}
+ cmdMZ-return-3.3 {set a 1}
+ cmdMZ-return-3.4 {error}
+ cmdMZ-return-3.5 {error foo}
+ cmdMZ-return-3.6 {error foo bar}
+ cmdMZ-return-3.7 {error foo bar baz}
+ cmdMZ-return-3.8 {return -level 0}
+ cmdMZ-return-3.9 {return -code error}
+ cmdMZ-return-3.10 {return -code error -errorinfo foo}
+ cmdMZ-return-3.11 {return -code error -errorinfo foo -errorcode bar}
+ cmdMZ-return-3.12 {return -code error -errorinfo foo -errorcode bar -errorline 10}
+ cmdMZ-return-3.12.1 {return -code error -errorinfo foo -errorcode bar -errorline 10 -errorstack baz}
+ cmdMZ-return-3.13 {return -options {x y z 2}}
+ cmdMZ-return-3.14 {return -level 3 -code break sdf}
+} {
+ test $testid "check that return after a catch is same:\n$script" {
+ set one [list [catch $script foo bar] $foo [dictSort $bar] \
+ $::errorCode $::errorInfo]
+ set two [list [catch {return -options $bar $foo} foo2 bar2] \
+ $foo2 [dictSort $bar2] $::errorCode $::errorInfo]
+ string equal $one $two
+ } 1
+}
+
+# The tests for Tcl_ScanObjCmd are in scan.test
+
+# Tcl_SourceObjCmd
+# More tests of Tcl_SourceObjCmd are in source.test
+
+test cmdMZ-3.3 {Tcl_SourceObjCmd: error conditions} -constraints {
+ unixOrPc
+} -returnCodes error -body {
+ source
+} -match glob -result {wrong # args: should be "source*fileName"}
+test cmdMZ-3.4 {Tcl_SourceObjCmd: error conditions} -constraints {
+ unixOrPc
+} -returnCodes error -body {
+ source a b
+} -match glob -result {wrong # args: should be "source*fileName"}
+test cmdMZ-3.5 {Tcl_SourceObjCmd: error in script} -body {
+ set file [makeFile {
+ set x 146
+ error "error in sourced file"
+ set y $x
+ } source.file]
+ list [catch {source $file} msg] $msg $::errorInfo
+} -cleanup {
+ removeFile source.file
+} -match listGlob -result {1 {error in sourced file} {error in sourced file
+ while executing
+"error "error in sourced file""
+ (file "*" line 3)
+ invoked from within
+"source $file"}}
+test cmdMZ-3.6 {Tcl_SourceObjCmd: simple script} -body {
+ set file [makeFile {list ok} source.file]
+ source $file
+} -cleanup {
+ removeFile source.file
+} -result ok
+
+# Tcl_SplitObjCmd
+
+test cmdMZ-4.1 {Tcl_SplitObjCmd: split errors} -returnCodes error -body {
+ split
+} -result {wrong # args: should be "split string ?splitChars?"}
+test cmdMZ-4.2 {Tcl_SplitObjCmd: split errors} -returnCodes error -body {
+ split a b c
+} -result {wrong # args: should be "split string ?splitChars?"}
+test cmdMZ-4.3 {Tcl_SplitObjCmd: basic split commands} {
+ split "a\n b\t\r c\n "
+} {a {} b {} {} c {} {}}
+test cmdMZ-4.4 {Tcl_SplitObjCmd: basic split commands} {
+ split "word 1xyzword 2zword 3" xyz
+} {{word 1} {} {} {word 2} {word 3}}
+test cmdMZ-4.5 {Tcl_SplitObjCmd: basic split commands} {
+ split "12345" {}
+} {1 2 3 4 5}
+test cmdMZ-4.6 {Tcl_SplitObjCmd: basic split commands} {
+ split "a\}b\[c\{\]\$"
+} "a\\\}b\\\[c\\\{\\\]\\\$"
+test cmdMZ-4.7 {Tcl_SplitObjCmd: basic split commands} {
+ split {} {}
+} {}
+test cmdMZ-4.8 {Tcl_SplitObjCmd: basic split commands} {
+ split {}
+} {}
+test cmdMZ-4.9 {Tcl_SplitObjCmd: basic split commands} {
+ split { }
+} {{} {} {} {}}
+test cmdMZ-4.10 {Tcl_SplitObjCmd: basic split commands} {
+ apply {{} {
+ set x {}
+ foreach f [split {]\n} {}] {
+ append x $f
+ }
+ return $x
+ }}
+} {]\n}
+test cmdMZ-4.11 {Tcl_SplitObjCmd: basic split commands} {
+ apply {{} {
+ set x ab\000c
+ set y [split $x {}]
+ binary scan $y c* z
+ return $z
+ }}
+} {97 32 98 32 0 32 99}
+test cmdMZ-4.12 {Tcl_SplitObjCmd: basic split commands} {
+ split "a0ab1b2bbb3\000c4" ab\000c
+} {{} 0 {} 1 2 {} {} 3 {} 4}
+test cmdMZ-4.13 {Tcl_SplitObjCmd: basic split commands} {
+ # if not UTF-8 aware, result is "a {} {} b qw\xe5 {} N wq"
+ split "a\u4e4eb qw\u5e4e\x4e wq" " \u4e4e"
+} "a b qw\u5e4eN wq"
+
+# The tests for Tcl_StringObjCmd are in string.test
+# The tests for Tcl_SubstObjCmd are in subst.test
+# The tests for Tcl_SwitchObjCmd are in switch.test
+
+test cmdMZ-5.1 {Tcl_TimeObjCmd: basic format of command} -body {
+ time
+} -returnCodes error -result {wrong # args: should be "time command ?count?"}
+test cmdMZ-5.2 {Tcl_TimeObjCmd: basic format of command} -body {
+ time a b c
+} -returnCodes error -result {wrong # args: should be "time command ?count?"}
+test cmdMZ-5.3 {Tcl_TimeObjCmd: basic format of command} -body {
+ time a b
+} -returnCodes error -result {expected integer but got "b"}
+test cmdMZ-5.4 {Tcl_TimeObjCmd: nothing happens with negative iteration counts} {
+ time bogusCmd -12456
+} {0 microseconds per iteration}
+test cmdMZ-5.5 {Tcl_TimeObjCmd: result format} -body {
+ time {format 1}
+} -match regexp -result {^\d+ microseconds per iteration}
+test cmdMZ-5.6 {Tcl_TimeObjCmd: slower commands take longer} {
+ expr {[lindex [time {after 2}] 0] < [lindex [time {after 1000}] 0]}
+} 1
+test cmdMZ-5.7 {Tcl_TimeObjCmd: errors generate right trace} {
+ list [catch {time {error foo}} msg] $msg $::errorInfo
+} {1 foo {foo
+ while executing
+"error foo"
+ invoked from within
+"time {error foo}"}}
+
+# The tests for Tcl_WhileObjCmd are in while.test
+
+# cleanup
+cleanupTests
+}
+namespace delete ::tcl::test::cmdMZ
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/compExpr-old.test b/pkgs/msgcat/tests/compExpr-old.test
new file mode 100644
index 0000000..bb19151
--- /dev/null
+++ b/pkgs/msgcat/tests/compExpr-old.test
@@ -0,0 +1,674 @@
+# Commands covered: expr
+#
+# This file contains the original set of tests for the compilation (and
+# indirectly execution) of Tcl's expr command. A new set of tests covering
+# the new implementation are in the files "parseExpr.test" and
+# "compExpr.test". Sourcing this file into Tcl runs the tests and generates
+# output for errors. No output means no errors were found.
+#
+# Copyright (c) 1996-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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+if {[catch {expr T1()} msg] && $msg eq {invalid command name "tcl::mathfunc::T1"}} {
+ testConstraint testmathfunctions 0
+} else {
+ testConstraint testmathfunctions 1
+}
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+ variable ieeeValues
+ binary scan [binary format dd -1.0 1.0] c* c
+ switch -exact -- $c {
+ {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+ # little endian
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+ ieeeValues(-Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+ ieeeValues(-Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+ ieeeValues(-Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+ ieeeValues(+Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+ ieeeValues(+Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 1
+ return 1
+ }
+ {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+ binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Infinity)
+ binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Normal)
+ binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Subnormal)
+ binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Normal)
+ binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Infinity)
+ binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 0
+ return 1
+ }
+ default {
+ return 0
+ }
+ }
+}
+testConstraint ieeeFloatingPoint [testIEEE]
+
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}]
+
+# procedures used below
+
+proc put_hello_char {c} {
+ global a
+ append a [format %c $c]
+ return $c
+}
+proc hello_world {} {
+ global a
+ set a ""
+ set L1 [set l0 [set h_1 [set q 0]]]
+ for {put_hello_char [expr [put_hello_char [expr [set h 7]*10+2]]+29]} {$l0?[put_hello_char $l0]
+ :!$h_1} {put_hello_char $ll;expr {$L1==2?[set ll [expr 32+0-0+[set bar 0]]]:0}} {expr {[incr L1]==[expr 1+([string length "abc"]-[string length "abc"])]
+ ?[set ll [set l0 [expr 54<<1]]]:$ll==108&&$L1<3?
+ [incr ll [expr 1|1<<1]; set ll $ll; set ll $ll; set ll $ll; set ll $ll; set l0 [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]; set l0; set l0 $l0; set l0; set l0]:$L1==4&&$ll==32?[set ll [expr 19+$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+[set foo [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]]]]
+ :[set q [expr $q-$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]};expr {$L1==5?[incr ll -8; set ll $ll; set ll]:$q&&$h1&&1};expr {$L1==4+2
+ ?[incr ll 3]:[expr ([string length "abc"]-[string length "abc"])+1]};expr {$ll==($h<<4)+2+0&&$L1!=6?[incr ll -6]:[set h1 [expr 100+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]}
+ expr {$L1!=1<<3?[incr q [expr ([string length "abc"]-[string length "abc"])-1]]:[set h_1 [set ll $h1]]}
+ }
+ set a
+}
+
+proc 12days {a b c} {
+ global xxx
+ expr {1<$a?[expr {$a<3?[12days -79 -13 [string range $c [12days -87 \
+ [expr 1-$b] [string range $c [12days -86 0 [string range $c 1 end]] \
+ end]] end]]:1};expr {$a<$b?[12days [expr $a+1] $b $c]:3};expr {[12days \
+ -94 [expr $a-27] $c]&&$a==2?$b<13?[12days 2 [expr $b+1] "%s %d %d\n"]:9
+ :16}]:$a<0?$a<-72?[12days $b $a "@n'+,#'/*\{\}w+/w#cdnr/+,\{\}r/*de\}+,/*\{*+,/w\{%+,/w#q#n+,/#\{l+,/n\{n+,/+#n+,/#;#q#n+,/+k#;*+,/'r :'d*'3,\}\{w+K w'K:'+\}e#';dq#'l q#'+d'K#!/+k#;q#'r\}eKK#\}w'r\}eKK\{nl\]'/#;#q#n')\{)#\}w')\{)\{nl\]'/+#n';d\}rw' i;# )\{nl\]!/n\{n#'; r\{#w'r nc\{nl\]'/#\{l,+'K \{rw' iK\{;\[\{nl\]'/w#q#n'wk nw' iwk\{KK\{nl\]!/w\{%'l##w#' i; :\{nl\]'/*\{q#'ld;r'\}\{nlwb!/*de\}'c ;;\{nl'-\{\}rw\]'/+,\}##'*\}#nc,',#nw\]'/+kd'+e\}+;#'rdq#w! nr'/ ') \}+\}\{rl#'\{n' ')# \}'+\}##(!!/"]
+ :$a<-50?[string compare [format %c $b] [string index $c 0]]==0?[append \
+ xxx [string index $c 31];scan [string index $c 31] %c x;set x]
+ :[12days -65 $b [string range $c 1 end]]:[12days [expr ([string compare \
+ [string index $c 0] "/"]==0)+$a] $b [string range $c 1 end]]:0<$a
+ ?[12days 2 2 "%s"]:[string compare [string index $c 0] "/"]==0||
+ [12days 0 [12days -61 [scan [string index $c 0] %c x; set x] \
+ "!ek;dc i@bK'(q)-\[w\]*%n+r3#l,\{\}:\nuwloca-O;m .vpbks,fxntdCeghiry"] \
+ [string range $c 1 end]]}
+}
+proc do_twelve_days {} {
+ global xxx
+ set xxx ""
+ 12days 1 1 1
+ set result [string length $xxx]
+ unset xxx
+ return $result
+}
+
+# start of tests
+
+catch {unset a b i x}
+
+test compExpr-old-1.1 {TclCompileExprCmd: no expression} {
+ list [catch {expr } msg] $msg
+} {1 {wrong # args: should be "expr arg ?arg ...?"}}
+test compExpr-old-1.2 {TclCompileExprCmd: one expression word} {
+ expr -25
+} -25
+test compExpr-old-1.3 {TclCompileExprCmd: two expression words} {
+ expr -8.2 -6
+} -14.2
+test compExpr-old-1.4 {TclCompileExprCmd: five expression words} {
+ expr 20 - 5 +10 -7
+} 18
+test compExpr-old-1.5 {TclCompileExprCmd: quoted expression word} {
+ expr "0005"
+} 5
+test compExpr-old-1.6 {TclCompileExprCmd: quoted expression word} {
+ catch {expr "0005"zxy} msg
+ set msg
+} {extra characters after close-quote}
+test compExpr-old-1.7 {TclCompileExprCmd: expression word in braces} {
+ expr {-0005}
+} -5
+test compExpr-old-1.8 {TclCompileExprCmd: expression word in braces} {
+ expr {{-0x1234}}
+} -4660
+test compExpr-old-1.9 {TclCompileExprCmd: expression word in braces} {
+ catch {expr {-0005}foo} msg
+ set msg
+} {extra characters after close-brace}
+test compExpr-old-1.10 {TclCompileExprCmd: other expression word in braces} {
+ expr 4*[llength "6 2"]
+} 8
+test compExpr-old-1.11 {TclCompileExprCmd: expression word terminated by ;} {
+ expr 4*[llength "6 2"];
+} 8
+test compExpr-old-1.12 {TclCompileExprCmd: inlined expr (in "catch") inside other catch} {
+ set a xxx
+ catch {
+ # Might not be a number
+ set a [expr 10*$a]
+ }
+} 1
+test compExpr-old-1.13 {TclCompileExprCmd: second level of substitutions in expr not in braces with single var reference} {
+ set a xxx
+ set x 27; set bool {$x}; if $bool {set a foo}
+ set a
+} foo
+test compExpr-old-1.14 {TclCompileExprCmd: second level of substitutions in expr with comparison as top-level operator} {
+ set a xxx
+ set x 2; set b {$x}; set a [expr $b == 2]
+ set a
+} 1
+
+test compExpr-old-2.1 {TclCompileExpr: are builtin functions registered?} {
+ expr double(5*[llength "6 2"])
+} 10.0
+test compExpr-old-2.2 {TclCompileExpr: error in expr} -body {
+ expr 2***3
+} -returnCodes error -match glob -result *
+test compExpr-old-2.3 {TclCompileExpr: junk after legal expr} -body {
+ expr 7*[llength "a b"]foo
+} -returnCodes error -match glob -result *
+test compExpr-old-2.4 {TclCompileExpr: numeric expr string rep == formatted int rep} {
+ expr {0001}
+} 1
+
+test compExpr-old-3.1 {CompileCondExpr: just lor expr} {expr 3||0} 1
+test compExpr-old-3.2 {CompileCondExpr: error in lor expr} -body {
+ expr x||3
+} -returnCodes error -match glob -result *
+test compExpr-old-3.3 {CompileCondExpr: test true arm} {expr 3>2?44:66} 44
+test compExpr-old-3.4 {CompileCondExpr: error compiling true arm} -body {
+ expr 3>2?2***3:66
+} -returnCodes error -match glob -result *
+test compExpr-old-3.5 {CompileCondExpr: test false arm} {expr 2>3?44:66} 66
+test compExpr-old-3.6 {CompileCondExpr: error compiling false arm} -body {
+ expr 2>3?44:2***3
+} -returnCodes error -match glob -result *
+test compExpr-old-3.7 {CompileCondExpr: long arms & nested cond exprs} {
+ hello_world
+} {Hello world}
+test compExpr-old-3.8 {CompileCondExpr: long arms & nested cond exprs} unix {
+ # Fails with a stack overflow on threaded Windows builds
+ do_twelve_days
+} 2358
+
+test compExpr-old-4.1 {CompileLorExpr: just land expr} {expr 1.3&&3.3} 1
+test compExpr-old-4.2 {CompileLorExpr: error in land expr} -body {
+ expr x&&3
+} -returnCodes error -match glob -result *
+test compExpr-old-4.3 {CompileLorExpr: simple lor exprs} {expr 0||1.0} 1
+test compExpr-old-4.4 {CompileLorExpr: simple lor exprs} {expr 3.0||0.0} 1
+test compExpr-old-4.5 {CompileLorExpr: simple lor exprs} {expr 0||0||1} 1
+test compExpr-old-4.6 {CompileLorExpr: error compiling lor arm} -body {
+ expr 2***3||4.0
+} -returnCodes error -match glob -result *
+test compExpr-old-4.7 {CompileLorExpr: error compiling lor arm} -body {
+ expr 1.3||2***3
+} -returnCodes error -match glob -result *
+test compExpr-old-4.8 {CompileLorExpr: error compiling lor arms} {
+ list [catch {expr {"a"||"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test compExpr-old-4.9 {CompileLorExpr: long lor arm} {
+ set a "abcdefghijkl"
+ set i 7
+ expr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]}
+} 1
+
+test compExpr-old-5.1 {CompileLandExpr: just bitor expr} {expr 7|0x13} 23
+test compExpr-old-5.2 {CompileLandExpr: error in bitor expr} -body {
+ expr x|3
+} -returnCodes error -match glob -result *
+test compExpr-old-5.3 {CompileLandExpr: simple land exprs} {expr 0&&1.0} 0
+test compExpr-old-5.4 {CompileLandExpr: simple land exprs} {expr 0&&0} 0
+test compExpr-old-5.5 {CompileLandExpr: simple land exprs} {expr 3.0&&1.2} 1
+test compExpr-old-5.6 {CompileLandExpr: simple land exprs} {expr 1&&1&&2} 1
+test compExpr-old-5.7 {CompileLandExpr: error compiling land arm} -body {
+ expr 2***3&&4.0
+} -returnCodes error -match glob -result *
+test compExpr-old-5.8 {CompileLandExpr: error compiling land arm} -body {
+ expr 1.3&&2***3
+} -returnCodes error -match glob -result *
+test compExpr-old-5.9 {CompileLandExpr: error compiling land arm} {
+ list [catch {expr {"a"&&"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test compExpr-old-5.10 {CompileLandExpr: long land arms} {
+ set a "abcdefghijkl"
+ set i 7
+ expr {[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]}
+} 1
+
+test compExpr-old-6.1 {CompileBitXorExpr: just bitand expr} {expr 7&0x13} 3
+test compExpr-old-6.2 {CompileBitXorExpr: error in bitand expr} -body {
+ expr x|3
+} -returnCodes error -match glob -result *
+test compExpr-old-6.3 {CompileBitXorExpr: simple bitxor exprs} {expr 7^0x13} 20
+test compExpr-old-6.4 {CompileBitXorExpr: simple bitxor exprs} {expr 3^0x10} 19
+test compExpr-old-6.5 {CompileBitXorExpr: simple bitxor exprs} {expr 0^7} 7
+test compExpr-old-6.6 {CompileBitXorExpr: simple bitxor exprs} {expr -1^7} -8
+test compExpr-old-6.7 {CompileBitXorExpr: error compiling bitxor arm} -body {
+ expr 2***3|6
+} -returnCodes error -match glob -result *
+test compExpr-old-6.8 {CompileBitXorExpr: error compiling bitxor arm} -body {
+ expr 2^x
+} -returnCodes error -match glob -result *
+test compExpr-old-6.9 {CompileBitXorExpr: runtime error in bitxor arm} {
+ list [catch {expr {24.0^3}} msg] $msg
+} {1 {can't use floating-point value as operand of "^"}}
+test compExpr-old-6.10 {CompileBitXorExpr: runtime error in bitxor arm} {
+ list [catch {expr {"a"^"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "^"}}
+
+test compExpr-old-7.1 {CompileBitAndExpr: just equality expr} {expr 3==2} 0
+test compExpr-old-7.2 {CompileBitAndExpr: just equality expr} {expr 2.0==2} 1
+test compExpr-old-7.3 {CompileBitAndExpr: just equality expr} {expr 3.2!=2.2} 1
+test compExpr-old-7.4 {CompileBitAndExpr: just equality expr} {expr {"abc" == "abd"}} 0
+test compExpr-old-7.5 {CompileBitAndExpr: error in equality expr} -body {
+ expr x==3
+} -returnCodes error -match glob -result *
+test compExpr-old-7.6 {CompileBitAndExpr: simple bitand exprs} {expr 7&0x13} 3
+test compExpr-old-7.7 {CompileBitAndExpr: simple bitand exprs} {expr 0xf2&0x53} 82
+test compExpr-old-7.8 {CompileBitAndExpr: simple bitand exprs} {expr 3&6} 2
+test compExpr-old-7.9 {CompileBitAndExpr: simple bitand exprs} {expr -1&-7} -7
+test compExpr-old-7.10 {CompileBitAndExpr: error compiling bitand arm} -body {
+ expr 2***3&6
+} -returnCodes error -match glob -result *
+test compExpr-old-7.11 {CompileBitAndExpr: error compiling bitand arm} -body {
+ expr 2&x
+} -returnCodes error -match glob -result *
+test compExpr-old-7.12 {CompileBitAndExpr: runtime error in bitand arm} {
+ list [catch {expr {24.0&3}} msg] $msg
+} {1 {can't use floating-point value as operand of "&"}}
+test compExpr-old-7.13 {CompileBitAndExpr: runtime error in bitand arm} {
+ list [catch {expr {"a"&"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "&"}}
+
+test compExpr-old-8.1 {CompileEqualityExpr: just relational expr} {expr 3>=2} 1
+test compExpr-old-8.2 {CompileEqualityExpr: just relational expr} {expr 2<=2.1} 1
+test compExpr-old-8.3 {CompileEqualityExpr: just relational expr} {expr 3.2>"2.2"} 1
+test compExpr-old-8.4 {CompileEqualityExpr: just relational expr} {expr {"0y"<"0x12"}} 0
+test compExpr-old-8.5 {CompileEqualityExpr: error in relational expr} -body {
+ expr x>3
+} -returnCodes error -match glob -result *
+test compExpr-old-8.6 {CompileEqualityExpr: simple equality exprs} {expr 7==0x13} 0
+test compExpr-old-8.7 {CompileEqualityExpr: simple equality exprs} {expr -0xf2!=0x53} 1
+test compExpr-old-8.8 {CompileEqualityExpr: simple equality exprs} {expr {"12398712938788234-1298379" != ""}} 1
+test compExpr-old-8.9 {CompileEqualityExpr: simple equality exprs} {expr -1!="abc"} 1
+test compExpr-old-8.10 {CompileEqualityExpr: error compiling equality arm} -body {
+ expr 2***3==6
+} -returnCodes error -match glob -result *
+test compExpr-old-8.11 {CompileEqualityExpr: error compiling equality arm} -body {
+ expr 2!=x
+} -returnCodes error -match glob -result *
+
+
+test compExpr-old-9.1 {CompileRelationalExpr: just shift expr} {expr 3<<2} 12
+test compExpr-old-9.2 {CompileRelationalExpr: just shift expr} {expr 0xff>>2} 63
+test compExpr-old-9.3 {CompileRelationalExpr: just shift expr} {expr -1>>2} -1
+test compExpr-old-9.4 {CompileRelationalExpr: just shift expr} {expr {1<<3}} 8
+
+# The following test is different for 32-bit versus 64-bit
+# architectures because LONG_MIN is different
+
+test compExpr-old-9.5a {CompileRelationalExpr: shift expr producing LONG_MIN} longIs64bit {
+ expr {int(1<<63)}
+} -9223372036854775808
+test compExpr-old-9.5b {CompileRelationalExpr: shift expr producing LONG_MIN} longIs32bit {
+ expr {int(1<<31)}
+} -2147483648
+
+test compExpr-old-9.6 {CompileRelationalExpr: error in shift expr} -body {
+ expr x>>3
+} -returnCodes error -match glob -result *
+test compExpr-old-9.7 {CompileRelationalExpr: simple relational exprs} {expr 0xff>=+0x3} 1
+test compExpr-old-9.8 {CompileRelationalExpr: simple relational exprs} {expr -0xf2<0x3} 1
+test compExpr-old-9.9 {CompileRelationalExpr: error compiling relational arm} -body {
+ expr 2***3>6
+} -returnCodes error -match glob -result *
+test compExpr-old-9.10 {CompileRelationalExpr: error compiling relational arm} -body {
+ expr 2<x
+} -returnCodes error -match glob -result *
+
+test compExpr-old-10.1 {CompileShiftExpr: just add expr} {expr 4+-2} 2
+test compExpr-old-10.2 {CompileShiftExpr: just add expr} {expr 0xff-2} 253
+test compExpr-old-10.3 {CompileShiftExpr: just add expr} {expr -1--2} 1
+test compExpr-old-10.4 {CompileShiftExpr: just add expr} {expr 1-0o123} -82
+test compExpr-old-10.5 {CompileShiftExpr: error in add expr} -body {
+ expr x+3
+} -returnCodes error -match glob -result *
+test compExpr-old-10.6 {CompileShiftExpr: simple shift exprs} {expr 0xff>>0x3} 31
+test compExpr-old-10.7 {CompileShiftExpr: simple shift exprs} {expr -0xf2<<0x3} -1936
+test compExpr-old-10.8 {CompileShiftExpr: error compiling shift arm} -body {
+ expr 2***3>>6
+} -returnCodes error -match glob -result *
+test compExpr-old-10.9 {CompileShiftExpr: error compiling shift arm} -body {
+ expr 2<<x
+} -returnCodes error -match glob -result *
+test compExpr-old-10.10 {CompileShiftExpr: runtime error} {
+ list [catch {expr {24.0>>43}} msg] $msg
+} {1 {can't use floating-point value as operand of ">>"}}
+test compExpr-old-10.11 {CompileShiftExpr: runtime error} {
+ list [catch {expr {"a"<<"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "<<"}}
+
+test compExpr-old-11.1 {CompileAddExpr: just multiply expr} {expr 4*-2} -8
+test compExpr-old-11.2 {CompileAddExpr: just multiply expr} {expr 0xff%2} 1
+test compExpr-old-11.3 {CompileAddExpr: just multiply expr} {expr -1/2} -1
+test compExpr-old-11.4 {CompileAddExpr: just multiply expr} {expr 7891%0o123} 6
+test compExpr-old-11.5 {CompileAddExpr: error in multiply expr} -body {
+ expr x*3
+} -returnCodes error -match glob -result *
+test compExpr-old-11.6 {CompileAddExpr: simple add exprs} {expr 0xff++0x3} 258
+test compExpr-old-11.7 {CompileAddExpr: simple add exprs} {expr -0xf2--0x3} -239
+test compExpr-old-11.8 {CompileAddExpr: error compiling add arm} -body {
+ expr 2***3+6
+} -returnCodes error -match glob -result *
+test compExpr-old-11.9 {CompileAddExpr: error compiling add arm} -body {
+ expr 2-x
+} -returnCodes error -match glob -result *
+test compExpr-old-11.10 {CompileAddExpr: runtime error} {
+ list [catch {expr {24.0+"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test compExpr-old-11.11 {CompileAddExpr: runtime error} {
+ list [catch {expr {"a"-"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+test compExpr-old-11.12 {CompileAddExpr: runtime error} {
+ list [catch {expr {3/0}} msg] $msg
+} {1 {divide by zero}}
+test compExpr-old-11.13a {CompileAddExpr: runtime error} ieeeFloatingPoint {
+ list [catch {expr {2.3/0.0}} msg] $msg
+} {0 Inf}
+test compExpr-old-11.13b {CompileAddExpr: runtime error} !ieeeFloatingPoint {
+ list [catch {expr {2.3/0.0}} msg] $msg
+} {1 {divide by zero}}
+
+test compExpr-old-12.1 {CompileMultiplyExpr: just unary expr} {expr ~4} -5
+test compExpr-old-12.2 {CompileMultiplyExpr: just unary expr} {expr --5} 5
+test compExpr-old-12.3 {CompileMultiplyExpr: just unary expr} {expr !27} 0
+test compExpr-old-12.4 {CompileMultiplyExpr: just unary expr} {expr ~0xff00ff} -16711936
+test compExpr-old-12.5 {CompileMultiplyExpr: error in unary expr} -body {
+ expr ~x
+} -returnCodes error -match glob -result *
+test compExpr-old-12.6 {CompileMultiplyExpr: simple multiply exprs} {expr 0xff*0x3} 765
+test compExpr-old-12.7 {CompileMultiplyExpr: simple multiply exprs} {expr -0xf2%-0x3} -2
+test compExpr-old-12.8 {CompileMultiplyExpr: error compiling multiply arm} -body {
+ expr 2*3%%6
+} -returnCodes error -match glob -result *
+test compExpr-old-12.9 {CompileMultiplyExpr: error compiling multiply arm} -body {
+ expr 2*x
+} -returnCodes error -match glob -result *
+test compExpr-old-12.10 {CompileMultiplyExpr: runtime error} {
+ list [catch {expr {24.0*"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "*"}}
+test compExpr-old-12.11 {CompileMultiplyExpr: runtime error} {
+ list [catch {expr {"a"/"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+
+test compExpr-old-13.1 {CompileUnaryExpr: unary exprs} {expr -0xff} -255
+test compExpr-old-13.2 {CompileUnaryExpr: unary exprs} {expr +0o00123} 83
+test compExpr-old-13.3 {CompileUnaryExpr: unary exprs} {expr +--++36} 36
+test compExpr-old-13.4 {CompileUnaryExpr: unary exprs} {expr !2} 0
+test compExpr-old-13.5 {CompileUnaryExpr: unary exprs} {expr +--+-62.0} -62.0
+test compExpr-old-13.6 {CompileUnaryExpr: unary exprs} {expr !0.0} 1
+test compExpr-old-13.7 {CompileUnaryExpr: unary exprs} {expr !0xef} 0
+test compExpr-old-13.8 {CompileUnaryExpr: error compiling unary expr} -body {
+ expr ~x
+} -returnCodes error -match glob -result *
+test compExpr-old-13.9 {CompileUnaryExpr: error compiling unary expr} -body {
+ expr !1.x
+ set msg
+} -returnCodes error -match glob -result *
+test compExpr-old-13.10 {CompileUnaryExpr: runtime error} {
+ list [catch {expr {~"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "~"}}
+test compExpr-old-13.11 {CompileUnaryExpr: runtime error} {
+ list [catch {expr ~4.0} msg] $msg
+} {1 {can't use floating-point value as operand of "~"}}
+test compExpr-old-13.12 {CompileUnaryExpr: just primary expr} {expr 0x123} 291
+test compExpr-old-13.13 {CompileUnaryExpr: just primary expr} {
+ set a 27
+ expr $a
+} 27
+test compExpr-old-13.14 {CompileUnaryExpr: just primary expr} {
+ expr double(27)
+} 27.0
+test compExpr-old-13.15 {CompileUnaryExpr: just primary expr} {expr "123"} 123
+test compExpr-old-13.16 {CompileUnaryExpr: error in primary expr} {
+ catch {expr [set]} msg
+ set msg
+} {wrong # args: should be "set varName ?newValue?"}
+test compExpr-old-14.1 {CompilePrimaryExpr: literal primary} {expr 1} 1
+test compExpr-old-14.2 {CompilePrimaryExpr: literal primary} {expr 123} 123
+test compExpr-old-14.3 {CompilePrimaryExpr: literal primary} {expr 0xff} 255
+test compExpr-old-14.4 {CompilePrimaryExpr: literal primary} {expr 0o0010} 8
+test compExpr-old-14.5 {CompilePrimaryExpr: literal primary} {expr 62.0} 62.0
+test compExpr-old-14.6 {CompilePrimaryExpr: literal primary} {
+ expr 3.1400000
+} 3.14
+test compExpr-old-14.7 {CompilePrimaryExpr: literal primary} {expr {{abcde}<{abcdef}}} 1
+test compExpr-old-14.8 {CompilePrimaryExpr: literal primary} {expr {{abc\
+def} < {abcdef}}} 1
+test compExpr-old-14.9 {CompilePrimaryExpr: literal primary} {expr {{abc\tde} > {abc\tdef}}} 0
+test compExpr-old-14.10 {CompilePrimaryExpr: literal primary} {expr {{123}}} 123
+test compExpr-old-14.11 {CompilePrimaryExpr: var reference primary} {
+ set i 789
+ list [expr {$i}] [expr $i]
+} {789 789}
+test compExpr-old-14.12 {CompilePrimaryExpr: var reference primary} {
+ set i {789} ;# test expr's aggressive conversion to numeric semantics
+ list [expr {$i}] [expr $i]
+} {789 789}
+test compExpr-old-14.13 {CompilePrimaryExpr: var reference primary} {
+ catch {unset a}
+ set a(foo) foo
+ set a(bar) bar
+ set a(123) 123
+ set result ""
+ lappend result [expr $a(123)] [expr {$a(bar)<$a(foo)}]
+ catch {unset a}
+ set result
+} {123 1}
+test compExpr-old-14.14 {CompilePrimaryExpr: var reference primary} {
+ set i 123 ;# test "$var.0" floating point conversion hack
+ list [expr $i] [expr $i.0] [expr $i.0/12.0]
+} {123 123.0 10.25}
+test compExpr-old-14.15 {CompilePrimaryExpr: var reference primary} {
+ set i 123
+ catch {expr $i.2} msg
+ set msg
+} 123.2
+test compExpr-old-14.16 {CompilePrimaryExpr: error compiling var reference primary} -body {
+ expr {$a(foo}
+} -returnCodes error -match glob -result *
+test compExpr-old-14.17 {CompilePrimaryExpr: string primary that looks like var ref} -body {
+ expr $
+} -returnCodes error -match glob -result *
+test compExpr-old-14.18 {CompilePrimaryExpr: quoted string primary} {
+ expr "21"
+} 21
+test compExpr-old-14.19 {CompilePrimaryExpr: quoted string primary} {
+ set i 123
+ set x 456
+ expr "$i+$x"
+} 579
+test compExpr-old-14.20 {CompilePrimaryExpr: quoted string primary} {
+ set i 3
+ set x 6
+ expr 2+"$i.$x"
+} 5.6
+test compExpr-old-14.21 {CompilePrimaryExpr: error in quoted string primary} {
+ catch {expr "[set]"} msg
+ set msg
+} {wrong # args: should be "set varName ?newValue?"}
+test compExpr-old-14.22 {CompilePrimaryExpr: subcommand primary} {
+ expr {[set i 123; set i]}
+} 123
+test compExpr-old-14.23 {CompilePrimaryExpr: error in subcommand primary} -body {
+ catch {expr {[set]}} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test compExpr-old-14.24 {CompilePrimaryExpr: error in subcommand primary} -body {
+ expr {[set i}
+} -returnCodes error -match glob -result *
+test compExpr-old-14.25 {CompilePrimaryExpr: math function primary} {
+ format %.6g [expr exp(1.0)]
+} 2.71828
+test compExpr-old-14.26 {CompilePrimaryExpr: math function primary} {
+ format %.6g [expr pow(2.0+0.1,3.0+0.1)]
+} 9.97424
+test compExpr-old-14.27 {CompilePrimaryExpr: error in math function primary} -body {
+ expr sinh::(2.0)
+} -returnCodes error -match glob -result *
+test compExpr-old-14.28 {CompilePrimaryExpr: subexpression primary} {
+ expr 2+(3*4)
+} 14
+test compExpr-old-14.29 {CompilePrimaryExpr: error in subexpression primary} -body {
+ catch {expr 2+(3*[set])} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test compExpr-old-14.30 {CompilePrimaryExpr: missing paren in subexpression primary} -body {
+ expr 2+(3*(4+5)
+} -returnCodes error -match glob -result *
+test compExpr-old-14.31 {CompilePrimaryExpr: just var ref in subexpression primary} {
+ set i "5+10"
+ list "[expr $i] == 15" "[expr ($i)] == 15" "[eval expr ($i)] == 15"
+} {{15 == 15} {15 == 15} {15 == 15}}
+test compExpr-old-14.32 {CompilePrimaryExpr: unexpected token} -body {
+ expr @
+} -returnCodes error -match glob -result *
+
+test compExpr-old-15.1 {CompileMathFuncCall: missing parenthesis} -body {
+ expr sinh2.0)
+} -returnCodes error -match glob -result *
+test compExpr-old-15.2 {CompileMathFuncCall: unknown math function} -body {
+ catch {expr whazzathuh(1)} msg
+ set ::errorInfo
+} -match glob -result {* "*whazzathuh"
+ while *ing
+"expr whazzathuh(1)"}
+test compExpr-old-15.3 {CompileMathFuncCall: too many arguments} -body {
+ catch {expr sin(1,2,3)} msg
+ set ::errorInfo
+} -match glob -result {too many arguments for math function*
+ while *ing
+"expr sin(1,2,3)"}
+test compExpr-old-15.4 {CompileMathFuncCall: ')' found before last required arg} -body {
+ catch {expr sin()} msg
+ set ::errorInfo
+} -match glob -result {too few arguments for math function*
+ while *ing
+"expr sin()"}
+test compExpr-old-15.5 {CompileMathFuncCall: too few arguments} -body {
+ catch {expr pow(1)} msg
+ set ::errorInfo
+} -match glob -result {too few arguments for math function*
+ while *ing
+"expr pow(1)"}
+test compExpr-old-15.6 {CompileMathFuncCall: missing ')'} -body {
+ expr sin(1
+} -returnCodes error -match glob -result *
+test compExpr-old-15.7 {CompileMathFuncCall: call registered math function} testmathfunctions {
+ expr 2*T1()
+} 246
+test compExpr-old-15.8 {CompileMathFuncCall: call registered math function} testmathfunctions {
+ expr T2()*3
+} 1035
+test compExpr-old-15.9 {CompileMathFuncCall: call registered math function} testmathfunctions {
+ expr T3(21, 37)
+} 37
+test compExpr-old-15.10 {CompileMathFuncCall: call registered math function} testmathfunctions {
+ expr T3(21.2, 37)
+} 37.0
+test compExpr-old-15.11 {CompileMathFuncCall: call registered math function} testmathfunctions {
+ expr T3(-21.2, -17.5)
+} -17.5
+
+test compExpr-old-16.1 {GetToken: checks whether integer token starting with "0x" (e.g., "0x$") is invalid} {
+ catch {unset a}
+ set a(VALUE) ff15
+ set i 123
+ if {[expr 0x$a(VALUE)] & 16} {
+ set i {}
+ }
+ set i
+} {}
+test compExpr-old-16.2 {GetToken: check for string literal in braces} {
+ expr {{1}}
+} {1}
+
+# Check "expr" and computed command names.
+
+test compExpr-old-17.1 {expr and computed command names} {
+ set i 0
+ set z expr
+ $z 1+2
+} 3
+
+# Check correct conversion of operands to numbers: If the string looks like
+# an integer, convert to integer. Otherwise, if the string looks like a
+# double, convert to double.
+
+test compExpr-old-18.1 {expr and conversion of operands to numbers} {
+ set x [lindex 11 0]
+ catch {expr int($x)}
+ expr {$x}
+} 11
+
+# Check "expr" and interpreter result object resetting before appending
+# an error msg during evaluation of exprs not in {}s
+
+test compExpr-old-19.1 {expr and interpreter result object resetting} {
+ proc p {} {
+ set t 10.0
+ set x 2.0
+ set dx 0.2
+ set f {$dx-$x/10}
+ set g {-$x/5}
+ set center 1.0
+ set x [expr $x-$center]
+ set dx [expr $dx+$g]
+ set x [expr $x+$f+$center]
+ set x [expr $x+$f+$center]
+ set y [expr round($x)]
+ }
+ p
+} 3
+
+# cleanup
+if {[info exists a]} {
+ unset a
+}
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/compExpr.test b/pkgs/msgcat/tests/compExpr.test
new file mode 100644
index 0000000..8e27f1f
--- /dev/null
+++ b/pkgs/msgcat/tests/compExpr.test
@@ -0,0 +1,393 @@
+# This file contains a collection of tests for the procedures in the file
+# tclCompExpr.c. Sourcing this file into Tcl runs the tests and generates
+# output for errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+if {[catch {expr T1()} msg] && $msg eq {invalid command name "tcl::mathfunc::T1"}} {
+ testConstraint testmathfunctions 0
+} else {
+ testConstraint testmathfunctions 1
+}
+
+# Constrain memory leak tests
+testConstraint memory [llength [info commands memory]]
+
+catch {unset a}
+
+test compExpr-1.1 {TclCompileExpr procedure, successful expr parse and compile} {
+ expr 1+2
+} 3
+test compExpr-1.2 {TclCompileExpr procedure, error parsing expr} -body {
+ expr 1+2+
+} -returnCodes error -match glob -result *
+test compExpr-1.3 {TclCompileExpr procedure, error compiling expr} -body {
+ list [catch {expr "foo(123)"} msg] $msg
+} -match glob -result {1 {* "*foo"}}
+test compExpr-1.4 {TclCompileExpr procedure, expr has no operators} {
+ set a {0o00123}
+ expr {$a}
+} 83
+
+test compExpr-2.1 {CompileSubExpr procedure, TCL_TOKEN_WORD parse token} -setup {
+ unset -nocomplain a
+} -body {
+ set a 27
+ expr {"foo$a" < "bar"}
+} -result 0
+test compExpr-2.2 {CompileSubExpr procedure, error compiling TCL_TOKEN_WORD parse token} -body {
+ expr {"00[expr 1+]" + 17}
+} -returnCodes error -match glob -result *
+test compExpr-2.3 {CompileSubExpr procedure, TCL_TOKEN_TEXT parse token} {
+ expr {{12345}}
+} 12345
+test compExpr-2.4 {CompileSubExpr procedure, empty TCL_TOKEN_TEXT parse token} {
+ expr {{}}
+} {}
+test compExpr-2.5 {CompileSubExpr procedure, TCL_TOKEN_BS parse token} {
+ expr "\{ \\
+ +123 \}"
+} 123
+test compExpr-2.6 {CompileSubExpr procedure, TCL_TOKEN_COMMAND parse token} {
+ expr {[info tclversion] != ""}
+} 1
+test compExpr-2.7 {CompileSubExpr procedure, TCL_TOKEN_COMMAND parse token} {
+ expr {[]}
+} {}
+test compExpr-2.8 {CompileSubExpr procedure, error in TCL_TOKEN_COMMAND parse token} -body {
+ expr {[foo "bar"xxx] + 17}
+} -returnCodes error -match glob -result *
+test compExpr-2.9 {CompileSubExpr procedure, TCL_TOKEN_VARIABLE parse token} -setup {
+ unset -nocomplain a
+} -body {
+ set a 123
+ expr {$a*2}
+} -result 246
+test compExpr-2.10 {CompileSubExpr procedure, TCL_TOKEN_VARIABLE parse token} -setup {
+ unset -nocomplain a
+ unset -nocomplain b
+} -body {
+ set a(george) martha
+ set b geo
+ expr {$a(${b}rge)}
+} -result martha
+test compExpr-2.11 {CompileSubExpr procedure, error in TCL_TOKEN_VARIABLE parse token} -body {
+ unset -nocomplain a
+ expr {$a + 17}
+} -returnCodes error -result {can't read "a": no such variable}
+test compExpr-2.12 {CompileSubExpr procedure, TCL_TOKEN_SUB_EXPR parse token} {
+ expr {27||3? 3<<(1+4) : 4&&9}
+} 96
+test compExpr-2.13 {CompileSubExpr procedure, error in TCL_TOKEN_SUB_EXPR parse token} -setup {
+ unset -nocomplain a
+} -body {
+ set a 15
+ list [catch {expr {27 || "$a[expr 1+]00"}} msg] $msg
+} -result {0 1}
+test compExpr-2.14 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, op found} {
+ expr {5*6}
+} 30
+test compExpr-2.15 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, math function found} {
+ format %.6g [expr {sin(2.0)}]
+} 0.909297
+test compExpr-2.16 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, math function not found} -body {
+ list [catch {expr {fred(2.0)}} msg] $msg
+} -match glob -result {1 {* "*fred"}}
+test compExpr-2.17 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4*2}
+} 8
+test compExpr-2.18 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4/2}
+} 2
+test compExpr-2.19 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4%2}
+} 0
+test compExpr-2.20 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4<<2}
+} 16
+test compExpr-2.21 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4>>2}
+} 1
+test compExpr-2.22 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4<2}
+} 0
+test compExpr-2.23 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4>2}
+} 1
+test compExpr-2.24 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4<=2}
+} 0
+test compExpr-2.25 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4>=2}
+} 1
+test compExpr-2.26 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4==2}
+} 0
+test compExpr-2.27 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4!=2}
+} 1
+test compExpr-2.28 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4&2}
+} 0
+test compExpr-2.29 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4^2}
+} 6
+test compExpr-2.30 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+ expr {4|2}
+} 6
+test compExpr-2.31 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator, 1 operand} {
+ expr {!4}
+} 0
+test compExpr-2.32 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator, 1 operand} {
+ expr {~4}
+} -5
+test compExpr-2.33 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator, comparison} -setup {
+ unset -nocomplain a
+} -body {
+ set a 15
+ expr {$a==15} ;# compiled out-of-line to runtime call on Tcl_ExprObjCmd
+} -result 1
+test compExpr-2.34 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
+ expr {+2}
+} 2
+test compExpr-2.35 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, error in special operator} -body {
+ expr {+[expr 1+]}
+} -returnCodes error -match glob -result *
+test compExpr-2.36 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
+ expr {4+2}
+} 6
+test compExpr-2.37 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, error in special operator} -body {
+ expr {[expr 1+]+5}
+} -returnCodes error -match glob -result *
+test compExpr-2.38 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, error in special operator} -body {
+ expr {5+[expr 1+]}
+} -returnCodes error -match glob -result *
+test compExpr-2.39 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
+ expr {-2}
+} -2
+test compExpr-2.40 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
+ expr {4-2}
+} 2
+test compExpr-2.41 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} -setup {
+ unset -nocomplain a
+} -body {
+ set a true
+ expr {0||$a}
+} -result 1
+test compExpr-2.42 {CompileSubExpr procedure, error in TCL_TOKEN_SUB_EXPR parse token} -setup {
+ unset -nocomplain a
+} -body {
+ set a 15
+ list [catch {expr {27 || "$a[expr 1+]00"}} msg] $msg
+} -result {0 1}
+test compExpr-2.43 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} -setup {
+ unset -nocomplain a
+} -body {
+ set a false
+ expr {3&&$a}
+} -result 0
+test compExpr-2.44 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} -setup {
+ unset -nocomplain a
+} -body {
+ set a false
+ expr {$a||1? 1 : 0}
+} -result 1
+test compExpr-2.45 {CompileSubExpr procedure, error in TCL_TOKEN_SUB_EXPR parse token} -setup {
+ unset -nocomplain a
+} -body {
+ set a 15
+ list [catch {expr {1? 54 : "$a[expr 1+]00"}} msg] $msg
+} -result {0 54}
+
+test compExpr-3.1 {CompileLandOrLorExpr procedure, numeric 1st operand} -setup {
+ unset -nocomplain a
+} -body {
+ set a 2
+ expr {[set a]||0}
+} -result 1
+test compExpr-3.2 {CompileLandOrLorExpr procedure, nonnumeric 1st operand} -setup {
+ unset -nocomplain a
+} -body {
+ set a no
+ expr {$a&&1}
+} -result 0
+test compExpr-3.3 {CompileSubExpr procedure, error in 1st operand} -body {
+ expr {[expr *2]||0}
+} -returnCodes error -match glob -result *
+test compExpr-3.4 {CompileLandOrLorExpr procedure, result is 1 or 0} -setup {
+ unset -nocomplain a
+ unset -nocomplain b
+} -body {
+ set a no
+ set b true
+ expr {$a || $b}
+} -result 1
+test compExpr-3.5 {CompileLandOrLorExpr procedure, short-circuit semantics} -setup {
+ unset -nocomplain a
+} -body {
+ set a yes
+ expr {$a || [exit]}
+} -result 1
+test compExpr-3.6 {CompileLandOrLorExpr procedure, short-circuit semantics} -setup {
+ unset -nocomplain a
+} -body {
+ set a no
+ expr {$a && [exit]}
+} -result 0
+test compExpr-3.7 {CompileLandOrLorExpr procedure, numeric 2nd operand} -setup {
+ unset -nocomplain a
+} -body {
+ set a 2
+ expr {0||[set a]}
+} -result 1
+test compExpr-3.8 {CompileLandOrLorExpr procedure, nonnumeric 2nd operand} -setup {
+ unset -nocomplain a
+} -body {
+ set a no
+ expr {1&&$a}
+} -result 0
+test compExpr-3.9 {CompileLandOrLorExpr procedure, error in 2nd operand} -body {
+ expr {0||[expr %2]}
+} -returnCodes error -match glob -result *
+test compExpr-3.10 {CompileLandOrLorExpr procedure, long lor/land arm} {
+ set a "abcdefghijkl"
+ set i 7
+ expr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]}
+} 1
+
+test compExpr-4.1 {CompileCondExpr procedure, simple test} -setup {
+ unset -nocomplain a
+} -body {
+ set a 2
+ expr {($a > 1)? "ok" : "nope"}
+} -result ok
+test compExpr-4.2 {CompileCondExpr procedure, complex test, convert to numeric} -setup {
+ unset -nocomplain a
+} -body {
+ set a no
+ expr {[set a]? 27 : -54}
+} -result -54
+test compExpr-4.3 {CompileCondExpr procedure, error in test} -body {
+ expr {[expr *2]? +1 : -1}
+} -returnCodes error -match glob -result *
+test compExpr-4.4 {CompileCondExpr procedure, simple "true" clause} -setup {
+ unset -nocomplain a
+} -body {
+ set a no
+ expr {1? (27-2) : -54}
+} -result 25
+test compExpr-4.5 {CompileCondExpr procedure, convert "true" clause to numeric} -setup {
+ unset -nocomplain a
+} -body {
+ set a no
+ expr {1? $a : -54}
+} -result no
+test compExpr-4.6 {CompileCondExpr procedure, error in "true" clause} -body {
+ expr {1? [expr *2] : -127}
+} -returnCodes error -match glob -result *
+test compExpr-4.7 {CompileCondExpr procedure, simple "false" clause} -setup {
+ unset -nocomplain a
+} -body {
+ set a no
+ expr {(2-2)? -3.14159 : "nope"}
+} -result nope
+test compExpr-4.8 {CompileCondExpr procedure, convert "false" clause to numeric} -setup {
+ unset -nocomplain a
+} -body {
+ set a 0o0123
+ expr {0? 42 : $a}
+} -result 83
+test compExpr-4.9 {CompileCondExpr procedure, error in "false" clause} {
+ list [catch {expr {1? 15 : [expr *2]}} msg] $msg
+} {0 15}
+
+test compExpr-5.1 {CompileMathFuncCall procedure, math function found} {
+ format %.6g [expr atan2(1.0, 2.0)]
+} 0.463648
+test compExpr-5.2 {CompileMathFuncCall procedure, math function not found} -body {
+ expr {do_it()}
+} -returnCodes error -match glob -result {* "*do_it"}
+test compExpr-5.3 {CompileMathFuncCall: call registered math function} testmathfunctions {
+ expr 3*T1()-1
+} 368
+test compExpr-5.4 {CompileMathFuncCall: call registered math function} testmathfunctions {
+ expr T2()*3
+} 1035
+test compExpr-5.5 {CompileMathFuncCall procedure, too few arguments} -body {
+ expr {atan2(1.0)}
+} -returnCodes error -match glob -result {too few arguments for math function*}
+test compExpr-5.6 {CompileMathFuncCall procedure, complex argument} {
+ format %.6g [expr pow(2.1, 27.5-(24.4*(5%2)))]
+} 9.97424
+test compExpr-5.7 {CompileMathFuncCall procedure, error in argument} -body {
+ expr {sinh(2.*)}
+} -returnCodes error -match glob -result *
+test compExpr-5.8 {CompileMathFuncCall procedure, too many arguments} -body {
+ expr {sinh(2.0, 3.0)}
+} -returnCodes error -match glob -result {too many arguments for math function*}
+test compExpr-5.9 {CompileMathFuncCall procedure, too many arguments} -body {
+ expr {0 <= rand(5.2)}
+} -returnCodes error -match glob -result {too many arguments for math function*}
+
+test compExpr-6.1 {LogSyntaxError procedure, error in expr longer than 60 chars} -body {
+ expr {(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)/} -1 foo 3
+} -returnCodes error -match glob -result *
+
+test compExpr-7.1 {Memory Leak} -constraints memory -setup {
+ proc getbytes {} {
+ set lines [split [memory info] \n]
+ lindex $lines 3 3
+ }
+} -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ interp create slave
+ slave eval expr 1+2+3+4+5+6+7+8+9+10+11+12+13
+ interp delete slave
+ set tmp $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+ unset end i tmp
+ rename getbytes {}
+} -result 0
+
+test compExpr-7.2 {[Bug 1869989]: expr parser memleak} -constraints memory -setup {
+ proc getbytes {} {
+ set lines [split [memory info] \n]
+ lindex $lines 3 3
+ }
+} -body {
+ set i 5
+ set end [getbytes]
+ while {[incr i -1]} {
+ expr ${i}000
+ set tmp $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+ unset end i tmp
+ rename getbytes {}
+} -result 0
+
+# cleanup
+catch {unset a}
+catch {unset b}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/compile.test b/pkgs/msgcat/tests/compile.test
new file mode 100644
index 0000000..d6048be
--- /dev/null
+++ b/pkgs/msgcat/tests/compile.test
@@ -0,0 +1,721 @@
+# This file contains tests for the files tclCompile.c, tclCompCmds.c and
+# tclLiteral.c
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+testConstraint exec [llength [info commands exec]]
+testConstraint memory [llength [info commands memory]]
+testConstraint testevalex [llength [info commands testevalex]]
+
+# The following tests are very incomplete, although the rest of the
+# test suite covers this file fairly well.
+
+catch {rename p ""}
+catch {namespace delete test_ns_compile}
+catch {unset x}
+catch {unset y}
+catch {unset a}
+
+test compile-1.1 {TclCompileString: look up cmds in proc ns, not current ns} -setup {
+ catch {namespace delete test_ns_compile}
+ catch {unset x}
+} -body {
+ set x 123
+ namespace eval test_ns_compile {
+ proc set {args} {
+ global x
+ lappend x test_ns_compile::set
+ }
+ proc p {} {
+ set 0
+ }
+ }
+ list [test_ns_compile::p] [set x]
+} -result {{123 test_ns_compile::set} {123 test_ns_compile::set}}
+test compile-1.2 {TclCompileString, error result is reset if TclGetLong determines word isn't an integer} {
+ proc p {x} {info commands 3m}
+ list [catch {p} msg] $msg
+} {1 {wrong # args: should be "p x"}}
+
+test compile-2.1 {TclCompileDollarVar: global scalar name with ::s} -setup {
+ catch {unset x}
+} -body {
+ set x 123
+ list $::x [expr {"x" in [info globals]}]
+} -result {123 1}
+test compile-2.2 {TclCompileDollarVar: global scalar name with ::s} -setup {
+ catch {unset y}
+} -body {
+ proc p {} {
+ set ::y 789
+ return $::y
+ }
+ list [p] $::y [expr {"y" in [info globals]}]
+} -result {789 789 1}
+test compile-2.3 {TclCompileDollarVar: global array name with ::s} -setup {
+ catch {unset a}
+} -body {
+ set ::a(1) 2
+ list $::a(1) [set ::a($::a(1)) 3] $::a(2) [expr {"a" in [info globals]}]
+} -result {2 3 3 1}
+test compile-2.4 {TclCompileDollarVar: global scalar name with ::s} -setup {
+ catch {unset a}
+} -body {
+ proc p {} {
+ set ::a(1) 1
+ return $::a($::a(1))
+ }
+ list [p] $::a(1) [expr {"a" in [info globals]}]
+} -result {1 1 1}
+test compile-2.5 {TclCompileDollarVar: global array, called as ${arrName(0)}} -setup {
+ catch {unset a}
+} -body {
+ proc p {} {
+ global a
+ set a(1) 1
+ return ${a(1)}$::a(1)$a(1)
+ }
+ list [p] $::a(1) [expr {"a" in [info globals]}]
+} -result {111 1 1}
+
+test compile-3.1 {TclCompileCatchCmd: only catch cmds with scalar vars are compiled inline} -setup {
+ catch {unset a}
+} -body {
+ set a(1) xyzzyx
+ proc p {} {
+ global a
+ catch {set x 123} a(1)
+ }
+ list [p] $a(1)
+} -result {0 123}
+test compile-3.2 {TclCompileCatchCmd: non-local variables} {
+ set ::foo 1
+ proc catch-test {} {
+ catch {set x 3} ::foo
+ }
+ catch-test
+ return $::foo
+} 3
+test compile-3.3 {TclCompileCatchCmd: overagressive compiling [bug 219184]} {
+ proc catch-test {str} {
+ catch [eval $str GOOD]
+ error BAD
+ }
+ catch {catch-test error} ::foo
+ return $::foo
+} {GOOD}
+test compile-3.4 {TclCompileCatchCmd: bcc'ed [return] is caught} {
+ proc foo {} {
+ set fail [catch {
+ return 1
+ }] ; # {}
+ return 2
+ }
+ foo
+} {2}
+test compile-3.5 {TclCompileCatchCmd: recover from error, [Bug 705406]} {
+ proc foo {} {
+ catch {
+ if {[a]} {
+ if b {}
+ }
+ }
+ }
+ list [catch foo msg] $msg
+} {0 1}
+test compile-3.6 {TclCompileCatchCmd: error in storing result [Bug 3098302]} {*}{
+ -setup {
+ namespace eval catchtest {
+ variable result1 {}
+ }
+ trace add variable catchtest::result1 write catchtest::failtrace
+ proc catchtest::failtrace {n1 n2 op} {
+ return -code error "trace on $n1 fails by request"
+ }
+ }
+ -body {
+ proc catchtest::x {} {
+ variable result1
+ set count 0
+ for {set i 0} {$i < 10} {incr i} {
+ set status2 [catch {
+ set status1 [catch {
+ return -code error -level 0 "original failure"
+ } result1 options1]
+ } result2 options2]
+ incr count
+ }
+ list $count $result2
+ }
+ catchtest::x
+ }
+ -result {10 {can't set "result1": trace on result1 fails by request}}
+ -cleanup {namespace delete catchtest}
+}
+
+test compile-4.1 {TclCompileForCmd: command substituted test expression} {
+ set i 0
+ set j 0
+ # Should be "forever"
+ for {} [expr $i < 3] {} {
+ set j [incr i]
+ if {$j > 3} break
+ }
+ set j
+} {4}
+
+test compile-5.1 {TclCompileForeachCmd: exception stack} {
+ proc foreach-exception-test {} {
+ foreach array(index) [list 1 2 3] break
+ foreach array(index) [list 1 2 3] break
+ foreach scalar [list 1 2 3] break
+ }
+ list [catch foreach-exception-test result] $result
+} {0 {}}
+test compile-5.2 {TclCompileForeachCmd: non-local variables} {
+ set ::foo 1
+ proc foreach-test {} {
+ foreach ::foo {1 2 3} {}
+ }
+ foreach-test
+ set ::foo
+} 3
+
+test compile-6.1 {TclCompileSetCmd: global scalar names with ::s} -setup {
+ catch {unset x}
+ catch {unset y}
+} -body {
+ set x 123
+ proc p {} {
+ set ::y 789
+ return $::y
+ }
+ list $::x [expr {"x" in [info globals]}] \
+ [p] $::y [expr {"y" in [info globals]}]
+} -result {123 1 789 789 1}
+test compile-6.2 {TclCompileSetCmd: global array names with ::s} -setup {
+ catch {unset a}
+} -body {
+ set ::a(1) 2
+ proc p {} {
+ set ::a(1) 1
+ return $::a($::a(1))
+ }
+ list $::a(1) [p] [set ::a($::a(1)) 3] $::a(1) [expr {"a" in [info globals]}]
+} -result {2 1 3 3 1}
+test compile-6.3 {TclCompileSetCmd: namespace var names with ::s} -setup {
+ catch {namespace delete test_ns_compile}
+ catch {unset x}
+} -body {
+ namespace eval test_ns_compile {
+ variable v hello
+ variable arr
+ set ::x $::test_ns_compile::v
+ set ::test_ns_compile::arr(1) 123
+ }
+ list $::x $::test_ns_compile::arr(1)
+} -result {hello 123}
+
+test compile-7.1 {TclCompileWhileCmd: command substituted test expression} {
+ set i 0
+ set j 0
+ # Should be "forever"
+ while [expr $i < 3] {
+ set j [incr i]
+ if {$j > 3} break
+ }
+ set j
+} {4}
+
+test compile-8.1 {CollectArgInfo: binary data} {
+ list [catch "string length \000foo" msg] $msg
+} {0 4}
+test compile-8.2 {CollectArgInfo: binary data} {
+ list [catch "string length foo\000" msg] $msg
+} {0 4}
+test compile-8.3 {CollectArgInfo: handle "]" at end of command properly} {
+ set x ]
+} {]}
+
+test compile-9.1 {UpdateStringOfByteCode: called for duplicate of compiled empty object} {
+ proc p {} {
+ set x {}
+ eval $x
+ append x { }
+ eval $x
+ }
+ p
+} {}
+
+test compile-10.1 {BLACKBOX: exception stack overflow} {
+ set x {{0}}
+ set y 0
+ while {$y < 100} {
+ if !$x {incr y}
+ }
+} {}
+
+test compile-11.1 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} {
+ # shared object - Interp result && Var 'r'
+ set r [list foobar]
+ # command that will add error to result
+ lindex a bogus
+ }}
+} -returnCodes error -result {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}
+test compile-11.2 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} { set r [list foobar] ; string index a bogus }}
+} -returnCodes error -result {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}
+test compile-11.3 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} { set r [list foobar] ; string index a 0o9 }}
+} -returnCodes error -match glob -result {*invalid octal number*}
+test compile-11.4 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} { set r [list foobar] ; array set var {one two many} }}
+} -returnCodes error -result {list must have an even number of elements}
+test compile-11.5 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} { set r [list foobar] ; incr foo bar baz}}
+} -returnCodes error -result {wrong # args: should be "incr varName ?increment?"}
+test compile-11.6 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} { set r [list foobar] ; incr}}
+} -returnCodes error -result {wrong # args: should be "incr varName ?increment?"}
+test compile-11.7 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} { set r [list foobar] ; expr !a }}
+} -returnCodes error -match glob -result *
+test compile-11.8 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} { set r [list foobar] ; expr {!a} }}
+} -returnCodes error -match glob -result *
+test compile-11.9 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+ apply {{} { set r [list foobar] ; llength "\{" }}
+ list [catch {p} msg] $msg
+} -returnCodes error -result {unmatched open brace in list}
+
+#
+# Special section for tests of tclLiteral.c
+# The following tests check for incorrect memory handling in
+# TclReleaseLiteral. They are only effective when tcl is compiled with
+# TCL_MEM_DEBUG
+#
+# Special test for leak on interp delete [Bug 467523].
+test compile-12.1 {testing literal leak on interp delete} -setup {
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex $lines 3 3
+ }
+} -constraints memory -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ interp create foo
+ foo eval {
+ namespace eval bar {}
+ }
+ interp delete foo
+ set tmp $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+ rename getbytes {}
+ unset -nocomplain end i tmp leakedBytes
+} -result 0
+# Special test for a memory error in a preliminary fix of [Bug 467523]. It
+# requires executing a helpfile. Presumably the child process is used because
+# when this test fails, it crashes.
+test compile-12.2 {testing error on literal deletion} -constraints {memory exec} -body {
+ set sourceFile [makeFile {
+ for {set i 0} {$i < 5} {incr i} {
+ namespace eval bar {}
+ namespace delete bar
+ }
+ puts 0
+ } source.file]
+ exec [interpreter] $sourceFile
+} -cleanup {
+ catch {removeFile $sourceFile}
+} -result 0
+# Test to catch buffer overrun in TclCompileTokens from buf 530320
+test compile-12.3 {check for a buffer overrun} -body {
+ proc crash {} {
+ puts $array([expr {a+2}])
+ }
+ crash
+} -returnCodes error -cleanup {
+ rename crash {}
+} -match glob -result *
+test compile-12.4 {TclCleanupLiteralTable segfault} -body {
+ # Tcl Bug 1001997
+ # Here, we're trying to test a case that causes a crash in
+ # TclCleanupLiteralTable. The conditions that we're trying to establish
+ # are:
+ # - TclCleanupLiteralTable is attempting to clean up a bytecode object in
+ # the literal table.
+ # - The bytecode object in question contains the only reference to another
+ # literal.
+ # - The literal in question is in the same hash bucket as the bytecode
+ # object, and immediately follows it in the chain.
+ # Since newly registered literals are added at the FRONT of the bucket
+ # chains, and since the bytecode object is registered before its literals,
+ # this is difficult to achieve. What we do is:
+ # (a) do a [namespace eval] of a string that's calculated to hash into
+ # the same bucket as a literal that it contains. In this case, the
+ # script and the variable 'bugbug' land in the same bucket.
+ # (b) do a [namespace eval] of a string that contains enough literals to
+ # force TclRegisterLiteral to rebuild the global literal table. The
+ # newly created hash buckets will contain the literals, IN REVERSE
+ # ORDER, thus putting the bytecode immediately ahead of 'bugbug' and
+ # 'bug4345bug'. The bytecode object will contain the only references
+ # to those two literals.
+ # (c) Delete the interpreter to invoke TclCleanupLiteralTable and tickle
+ # the bug.
+ proc foo {} {
+ set i [interp create]
+ $i eval {
+ namespace eval ::w {concat 4649; variable bugbug}
+ namespace eval ::w {
+ concat x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 \
+ x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 \
+ x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 \
+ x31 x32 X33 X34 X35 X36 X37 X38 X39 X40 \
+ x41 x42 x43 x44 x45 x46 x47 x48 x49 x50 \
+ x51 x52 x53 x54 x55 x56 x57 x58 x59 x60 \
+ x61 x62 x63 x64
+ concat y1 y2 y3 y4 y5 y6 y7 y8 y9 y10 \
+ y11 y12 y13 y14 y15 y16 y17 y18 y19 y20 \
+ y21 y22 y23 y24 y25 y26 y27 y28 y29 y30 \
+ y31 y32 Y33 Y34 Y35 Y36 Y37 Y38 Y39 Y40 \
+ y41 y42 y43 y44 y45 y46 y47 y48 y49 y50 \
+ y51 y52 y53 y54 y55 y56 y57 y58 y59 y60 \
+ y61 y62 y63 y64
+ concat z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 \
+ z11 z12 z13 z14 z15 z16 z17 z18 z19 z20 \
+ z21 z22 z23 z24 z25 z26 z27 z28 z29 z30 \
+ z31 z32
+ }
+ }
+ interp delete $i; # must not crash
+ return ok
+ }
+ foo
+} -cleanup {
+ rename foo {}
+} -result ok
+
+# Special test for underestimating the maxStackSize required for a compiled
+# command. A failure will cause a segfault in the child process.
+test compile-13.1 {testing underestimate of maxStackSize in list cmd} {exec} {
+ set body {set x [list}
+ for {set i 0} {$i < 3000} {incr i} {
+ append body " $i"
+ }
+ append body {]; puts OK}
+ regsub BODY {proc crash {} {BODY}; crash} $body script
+ list [catch {exec [interpreter] << $script} msg] $msg
+} {0 OK}
+
+# Special test for compiling tokens from a copy of the source string. [Bug
+# 599788]
+test compile-14.1 {testing errors in element name; segfault?} {} {
+ catch {set a([error])} msg1
+ catch {set bubba([join $abba $jubba]) $vol} msg2
+ list $msg1 $msg2
+} {{wrong # args: should be "error message ?errorInfo? ?errorCode?"} {can't read "abba": no such variable}}
+
+# Tests compile-15.* cover Tcl Bug 633204
+test compile-15.1 {proper TCL_RETURN code from [return]} {
+ apply {{} {catch return}}
+} 2
+test compile-15.2 {proper TCL_RETURN code from [return]} {
+ apply {{} {catch {return foo}}}
+} 2
+test compile-15.3 {proper TCL_RETURN code from [return]} {
+ apply {{} {catch {return $::tcl_library}}}
+} 2
+test compile-15.4 {proper TCL_RETURN code from [return]} {
+ apply {{} {catch {return [info library]}}}
+} 2
+test compile-15.5 {proper TCL_RETURN code from [return]} {
+ apply {{} {catch {set a 1}; return}}
+} ""
+
+for {set noComp 0} {$noComp <= 1} {incr noComp} {
+
+if $noComp {
+ interp alias {} run {} testevalex
+ set constraints testevalex
+} else {
+ interp alias {} run {} if 1
+ set constraints {}
+}
+
+test compile-16.1.$noComp {TclCompileScript: word expansion} $constraints {
+ run "list [string repeat {{*}a } 255]"
+} [lrepeat 255 a]
+test compile-16.2.$noComp {TclCompileScript: word expansion} $constraints {
+ run "list [string repeat {{*}a } 256]"
+} [lrepeat 256 a]
+test compile-16.3.$noComp {TclCompileScript: word expansion} $constraints {
+ run "list [string repeat {{*}a } 257]"
+} [lrepeat 257 a]
+test compile-16.4.$noComp {TclCompileScript: word expansion} $constraints {
+ run {{*}list}
+} {}
+test compile-16.5.$noComp {TclCompileScript: word expansion} $constraints {
+ run {{*}list {*}{x y z}}
+} {x y z}
+test compile-16.6.$noComp {TclCompileScript: word expansion} $constraints {
+ run {{*}list {*}[list x y z]}
+} {x y z}
+test compile-16.7.$noComp {TclCompileScript: word expansion} $constraints {
+ run {{*}list {*}[list x y z][list x y z]}
+} {x y zx y z}
+test compile-16.8.$noComp {TclCompileScript: word expansion} -body {
+ set l {x y z}
+ run {{*}list {*}$l}
+} -constraints $constraints -cleanup {
+ unset l
+} -result {x y z}
+test compile-16.9.$noComp {TclCompileScript: word expansion} -body {
+ set l {x y z}
+ run {{*}list {*}$l$l}
+} -constraints $constraints -cleanup {
+ unset l
+} -result {x y zx y z}
+test compile-16.10.$noComp {TclCompileScript: word expansion} -body {
+ run {{*}\{}
+} -constraints $constraints -returnCodes error \
+-result {unmatched open brace in list}
+test compile-16.11.$noComp {TclCompileScript: word expansion} -body {
+ proc badList {} {return \{}
+ run {{*}[badList]}
+} -constraints $constraints -cleanup {
+ rename badList {}
+} -returnCodes error -result {unmatched open brace in list}
+test compile-16.12.$noComp {TclCompileScript: word expansion} $constraints {
+ run {{*}list x y z}
+} {x y z}
+test compile-16.13.$noComp {TclCompileScript: word expansion} $constraints {
+ run {{*}list x y {*}z}
+} {x y z}
+test compile-16.14.$noComp {TclCompileScript: word expansion} $constraints {
+ run {{*}list x {*}y z}
+} {x y z}
+test compile-16.15.$noComp {TclCompileScript: word expansion} $constraints {
+ run {list x y {*}z}
+} {x y z}
+test compile-16.16.$noComp {TclCompileScript: word expansion} $constraints {
+ run {list x {*}y z}
+} {x y z}
+test compile-16.17.$noComp {TclCompileScript: word expansion} $constraints {
+ run {list {*}x y z}
+} {x y z}
+
+# These tests note that expansion can in theory cause the number of arguments
+# to a command to exceed INT_MAX, which is as big as objc is allowed to get.
+#
+# In practice, it seems we will run out of memory before we confront this
+# issue. Note that compiled operations run out of memory at smaller objc
+# values than direct string evaluation.
+#
+# These tests are constrained as knownBug because they are likely to cause
+# memory allocation panics somewhere, and we don't want panics in the test
+# suite.
+#
+test compile-16.18.$noComp {TclCompileScript: word expansion} -body {
+ proc LongList {} {return [lrepeat [expr {1<<10}] x]}
+ llength [run "list [string repeat {{*}[LongList] } [expr {1<<10}]]"]
+} -constraints [linsert $constraints 0 knownBug] -cleanup {
+ rename LongList {}
+} -returnCodes ok -result [expr {1<<20}]
+test compile-16.19.$noComp {TclCompileScript: word expansion} -body {
+ proc LongList {} {return [lrepeat [expr {1<<11}] x]}
+ llength [run "list [string repeat {{*}[LongList] } [expr {1<<11}]]"]
+} -constraints [linsert $constraints 0 knownBug] -cleanup {
+ rename LongList {}
+} -returnCodes ok -result [expr {1<<22}]
+test compile-16.20.$noComp {TclCompileScript: word expansion} -body {
+ proc LongList {} {return [lrepeat [expr {1<<12}] x]}
+ llength [run "list [string repeat {{*}[LongList] } [expr {1<<12}]]"]
+} -constraints [linsert $constraints 0 knownBug] -cleanup {
+ rename LongList {}
+} -returnCodes ok -result [expr {1<<24}]
+# This is the one that should cause overflow
+test compile-16.21.$noComp {TclCompileScript: word expansion} -body {
+ proc LongList {} {return [lrepeat [expr {1<<16}] x]}
+ llength [run "list [string repeat {{*}[LongList] } [expr {1<<16}]]"]
+} -constraints [linsert $constraints 0 knownBug] -cleanup {
+ rename LongList {}
+} -returnCodes ok -result [expr {wide(1)<<32}]
+test compile-16.22.$noComp {
+ Bug 845412: TclCompileScript: word expansion not mandatory
+} -body {
+ # This test may crash and will fail unless Bug 845412 is fixed.
+ proc ReturnResults args {return $args}
+ run "ReturnResults [string repeat {x } 260]"
+} -constraints $constraints -cleanup {
+ rename ReturnResults {}
+} -returnCodes ok -result [string trim [string repeat {x } 260]]
+test compile-16.23.$noComp {
+ Bug 1032805: defer parse error until run time
+} -constraints $constraints -body {
+ namespace eval x {
+ run {
+ proc if {a b} {uplevel 1 [list set $a $b]}
+ if 1 {syntax {}{}}
+ }
+ }
+} -cleanup {
+ namespace delete x
+} -returnCodes ok -result {syntax {}{}}
+test compile-16.24.$noComp {
+ Bug 1638414: bad list constant as first expanded term
+} -constraints $constraints -body {
+ run "{*}\"\{foo bar\""
+} -returnCodes error -result {unmatched open brace in list}
+test compile-16.25.$noComp {TclCompileScript: word expansion, naked backslashes} $constraints {
+ run {list {*}{a \n b}}
+} {a {
+} b}
+test compile-16.26.$noComp {TclCompileScript: word expansion, protected backslashes} $constraints {
+ run {list {*}{a {\n} b}}
+} {a {\n} b}
+} ;# End of noComp loop
+
+# These tests are messy because it wrecks the interpreter it runs in! They
+# demonstrate issues arising from [FRQ 1101710]
+test compile-17.1 {Command interpretation binding for compiled code} -constraints knownBug -setup {
+ set i [interp create]
+} -body {
+ $i eval {
+ if 1 {
+ expr [
+ proc expr args {return substituted}
+ format {[subst compiled]}
+ ]
+ }
+ }
+} -cleanup {
+ interp delete $i
+} -result substituted
+test compile-17.2 {Command interpretation binding for non-compiled code} -setup {
+ set i [interp create]
+} -body {
+ $i eval {
+ if 1 {
+ [subst expr] [
+ proc expr args {return substituted}
+ format {[subst compiled]}
+ ]
+ }
+ }
+} -cleanup {
+ interp delete $i
+} -result substituted
+
+# This tests the supported parts of the unsupported [disassemble] command. It
+# does not check the format of disassembled bytecode though; that's liable to
+# change without warning.
+
+test compile-18.1 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble
+} -match glob -result {wrong # args: should be "*"}
+test compile-18.2 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble ?
+} -match glob -result {bad type "?": must be *}
+test compile-18.3 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble lambda
+} -match glob -result {wrong # args: should be "* lambda lambdaTerm"}
+test compile-18.4 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble lambda \{
+} -result "can't interpret \"\{\" as a lambda expression"
+test compile-18.5 {disassembler - basics} -body {
+ # Allow any string: the result format is not defined anywhere!
+ tcl::unsupported::disassemble lambda {{} {}}
+} -match glob -result *
+test compile-18.6 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble proc
+} -match glob -result {wrong # args: should be "* proc procName"}
+test compile-18.7 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble proc nosuchproc
+} -result {"nosuchproc" isn't a procedure}
+test compile-18.8 {disassembler - basics} -setup {
+ proc chewonthis {} {}
+} -body {
+ # Allow any string: the result format is not defined anywhere!
+ tcl::unsupported::disassemble proc chewonthis
+} -cleanup {
+ rename chewonthis {}
+} -match glob -result *
+test compile-18.9 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble script
+} -match glob -result {wrong # args: should be "* script script"}
+test compile-18.10 {disassembler - basics} -body {
+ # Allow any string: the result format is not defined anywhere!
+ tcl::unsupported::disassemble script {}
+} -match glob -result *
+test compile-18.11 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble method
+} -match glob -result {wrong # args: should be "* method className methodName"}
+test compile-18.12 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble method nosuchclass foo
+} -result {nosuchclass does not refer to an object}
+test compile-18.13 {disassembler - basics} -returnCodes error -setup {
+ oo::object create justanobject
+} -body {
+ tcl::unsupported::disassemble method justanobject foo
+} -cleanup {
+ justanobject destroy
+} -result {"justanobject" is not a class}
+test compile-18.14 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble method oo::object nosuchmethod
+} -result {unknown method "nosuchmethod"}
+test compile-18.15 {disassembler - basics} -setup {
+ oo::class create foo {method bar {} {}}
+} -body {
+ # Allow any string: the result format is not defined anywhere!
+ tcl::unsupported::disassemble method foo bar
+} -cleanup {
+ foo destroy
+} -match glob -result *
+test compile-18.16 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble objmethod
+} -match glob -result {wrong # args: should be "* objmethod objectName methodName"}
+test compile-18.17 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble objmethod nosuchobject foo
+} -result {nosuchobject does not refer to an object}
+test compile-18.18 {disassembler - basics} -returnCodes error -body {
+ tcl::unsupported::disassemble objmethod oo::object nosuchmethod
+} -result {unknown method "nosuchmethod"}
+test compile-18.19 {disassembler - basics} -setup {
+ oo::object create foo
+ oo::objdefine foo {method bar {} {}}
+} -body {
+ # Allow any string: the result format is not defined anywhere!
+ tcl::unsupported::disassemble objmethod foo bar
+} -cleanup {
+ foo destroy
+} -match glob -result *
+# TODO sometime - check that bytecode from tbcload is *not* disassembled.
+
+# cleanup
+catch {rename p ""}
+catch {namespace delete test_ns_compile}
+catch {unset x}
+catch {unset y}
+catch {unset a}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/concat.test b/pkgs/msgcat/tests/concat.test
new file mode 100644
index 0000000..eeb11ca
--- /dev/null
+++ b/pkgs/msgcat/tests/concat.test
@@ -0,0 +1,57 @@
+# Commands covered: concat
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test concat-1.1 {simple concatenation} {
+ concat a b c d e f g
+} {a b c d e f g}
+test concat-1.2 {merging lists together} {
+ concat a {b c d} {e f g h}
+} {a b c d e f g h}
+test concat-1.3 {merge lists, retain sub-lists} {
+ concat a {b {c d}} {{e f}} g h
+} {a b {c d} {e f} g h}
+test concat-1.4 {special characters} {
+ concat a\{ {b \{c d} \{d
+} "a{ b \\{c d {d"
+
+test concat-2.1 {error: one empty argument} {
+ concat {}
+} {}
+
+test concat-3.1 {error: no arguments} {
+ list [catch concat msg] $msg
+} {0 {}}
+
+test concat-4.1 {pruning off extra white space} {
+ concat {} {a b c}
+} {a b c}
+test concat-4.2 {pruning off extra white space} {
+ concat x y " a b c \n\t " " " " def "
+} {x y a b c def}
+test concat-4.3 {pruning off extra white space sets length correctly} {
+ llength [concat { {{a}} }]
+} 1
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/config.test b/pkgs/msgcat/tests/config.test
new file mode 100644
index 0000000..d14837e
--- /dev/null
+++ b/pkgs/msgcat/tests/config.test
@@ -0,0 +1,60 @@
+# -*- tcl -*-
+# Commands covered: pkgconfig
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test pkgconfig-1.1 {query keys} {
+ lsort [::tcl::pkgconfig list]
+} {64bit bindir,install bindir,runtime compile_debug compile_stats debug docdir,install docdir,runtime includedir,install includedir,runtime libdir,install libdir,runtime mem_debug optimized profiled scriptdir,install scriptdir,runtime threaded}
+test pkgconfig-1.2 {query keys multiple times} {
+ string compare [::tcl::pkgconfig list] [::tcl::pkgconfig list]
+} 0
+test pkgconfig-1.3 {query value multiple times} {
+ string compare \
+ [::tcl::pkgconfig get bindir,install] \
+ [::tcl::pkgconfig get bindir,install]
+} 0
+
+
+test pkgconfig-2.0 {error: missing subcommand} {
+ catch {::tcl::pkgconfig} msg
+ set msg
+} {wrong # args: should be "::tcl::pkgconfig subcommand ?arg?"}
+test pkgconfig-2.1 {error: illegal subcommand} {
+ catch {::tcl::pkgconfig foo} msg
+ set msg
+} {bad subcommand "foo": must be get or list}
+test pkgconfig-2.2 {error: list with arguments} {
+ catch {::tcl::pkgconfig list foo} msg
+ set msg
+} {wrong # args: should be "::tcl::pkgconfig list"}
+test pkgconfig-2.3 {error: get without arguments} {
+ catch {::tcl::pkgconfig get} msg
+ set msg
+} {wrong # args: should be "::tcl::pkgconfig get key"}
+test pkgconfig-2.4 {error: query unknown key} {
+ catch {::tcl::pkgconfig get foo} msg
+ set msg
+} {key not known}
+test pkgconfig-2.5 {error: query with to many arguments} {
+ catch {::tcl::pkgconfig get foo bar} msg
+ set msg
+} {wrong # args: should be "::tcl::pkgconfig subcommand ?arg?"}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/coroutine.test b/pkgs/msgcat/tests/coroutine.test
new file mode 100644
index 0000000..7f40a7b
--- /dev/null
+++ b/pkgs/msgcat/tests/coroutine.test
@@ -0,0 +1,618 @@
+# Commands covered: coroutine, yield, [info coroutine]
+#
+# This file contains a collection of tests for experimental commands that are
+# found in ::tcl::unsupported. The tests will migrate to normal test files
+# if/when the commands find their way into the core.
+#
+# Copyright (c) 2008 by Miguel Sofer.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testnrelevels [llength [info commands testnrelevels]]
+testConstraint memory [llength [info commands memory]]
+
+set lambda [list {{start 0} {stop 10}} {
+ # init
+ set i $start
+ set imax $stop
+ yield
+ while {$i < $imax} {
+ yield [expr {$i*$stop}]
+ incr i
+ }
+}]
+
+test coroutine-1.1 {coroutine basic} -setup {
+ coroutine foo ::apply $lambda
+ set res {}
+} -body {
+ for {set k 1} {$k < 4} {incr k} {
+ lappend res [foo]
+ }
+ set res
+} -cleanup {
+ rename foo {}
+ unset res
+} -result {0 10 20}
+test coroutine-1.2 {coroutine basic} -setup {
+ coroutine foo ::apply $lambda 2 8
+ set res {}
+} -body {
+ for {set k 1} {$k < 4} {incr k} {
+ lappend res [foo]
+ }
+ set res
+} -cleanup {
+ rename foo {}
+ unset res
+} -result {16 24 32}
+test coroutine-1.3 {yield returns new arg} -setup {
+ set body {
+ # init
+ set i $start
+ set imax $stop
+ yield
+ while {$i < $imax} {
+ set stop [yield [expr {$i*$stop}]]
+ incr i
+ }
+ }
+ coroutine foo ::apply [list {{start 2} {stop 10}} $body]
+ set res {}
+} -body {
+ for {set k 1} {$k < 4} {incr k} {
+ lappend res [foo $k]
+ }
+ set res
+} -cleanup {
+ rename foo {}
+ unset res
+} -result {20 6 12}
+test coroutine-1.4 {yield in nested proc} -setup {
+ proc moo {} {
+ upvar 1 i i stop stop
+ yield [expr {$i*$stop}]
+ }
+ set body {
+ # init
+ set i $start
+ set imax $stop
+ yield
+ while {$i < $imax} {
+ moo
+ incr i
+ }
+ }
+ coroutine foo ::apply [list {{start 0} {stop 10}} $body]
+ set res {}
+} -body {
+ for {set k 1} {$k < 4} {incr k} {
+ lappend res [foo $k]
+ }
+ set res
+} -cleanup {
+ rename foo {}
+ rename moo {}
+ unset body res
+} -result {0 10 20}
+test coroutine-1.5 {just yield} -body {
+ coroutine foo yield
+ list [foo] [catch foo msg] $msg
+} -cleanup {
+ unset msg
+} -result {{} 1 {invalid command name "foo"}}
+test coroutine-1.6 {just yield} -body {
+ coroutine foo [list yield]
+ list [foo] [catch foo msg] $msg
+} -cleanup {
+ unset msg
+} -result {{} 1 {invalid command name "foo"}}
+test coroutine-1.7 {yield in nested uplevel} -setup {
+ set body {
+ # init
+ set i $start
+ set imax $stop
+ yield
+ while {$i < $imax} {
+ uplevel 0 [list yield [expr {$i*$stop}]]
+ incr i
+ }
+ }
+ coroutine foo ::apply [list {{start 0} {stop 10}} $body]
+ set res {}
+} -body {
+ for {set k 1} {$k < 4} {incr k} {
+ lappend res [eval foo $k]
+ }
+ set res
+} -cleanup {
+ rename foo {}
+ unset body res
+} -result {0 10 20}
+test coroutine-1.8 {yield in nested uplevel} -setup {
+ set body {
+ # init
+ set i $start
+ set imax $stop
+ yield
+ while {$i < $imax} {
+ uplevel 0 yield [expr {$i*$stop}]
+ incr i
+ }
+ }
+ coroutine foo ::apply [list {{start 0} {stop 10}} $body]
+ set res {}
+} -body {
+ for {set k 1} {$k < 4} {incr k} {
+ lappend res [eval foo $k]
+ }
+ set res
+} -cleanup {
+ rename foo {}
+ unset body res
+} -result {0 10 20}
+test coroutine-1.9 {yield in nested eval} -setup {
+ proc moo {} {
+ upvar 1 i i stop stop
+ yield [expr {$i*$stop}]
+ }
+ set body {
+ # init
+ set i $start
+ set imax $stop
+ yield
+ while {$i < $imax} {
+ eval moo
+ incr i
+ }
+ }
+ coroutine foo ::apply [list {{start 0} {stop 10}} $body]
+ set res {}
+} -body {
+ for {set k 1} {$k < 4} {incr k} {
+ lappend res [foo $k]
+ }
+ set res
+} -cleanup {
+ rename moo {}
+ unset body res
+} -result {0 10 20}
+test coroutine-1.10 {yield in nested eval} -setup {
+ set body {
+ # init
+ set i $start
+ set imax $stop
+ yield
+ while {$i < $imax} {
+ eval yield [expr {$i*$stop}]
+ incr i
+ }
+ }
+ coroutine foo ::apply [list {{start 0} {stop 10}} $body]
+ set res {}
+} -body {
+ for {set k 1} {$k < 4} {incr k} {
+ lappend res [eval foo $k]
+ }
+ set res
+} -cleanup {
+ unset body res
+} -result {0 10 20}
+test coroutine-1.11 {yield outside coroutine} -setup {
+ proc moo {} {
+ upvar 1 i i stop stop
+ yield [expr {$i*$stop}]
+ }
+} -body {
+ variable i 5 stop 6
+ moo
+} -cleanup {
+ rename moo {}
+ unset i stop
+} -returnCodes error -result {yield can only be called in a coroutine}
+test coroutine-1.12 {proc as coroutine} -setup {
+ set body {
+ # init
+ set i $start
+ set imax $stop
+ yield
+ while {$i < $imax} {
+ uplevel 0 [list yield [expr {$i*$stop}]]
+ incr i
+ }
+ }
+ proc moo {{start 0} {stop 10}} $body
+ coroutine foo moo 2 8
+} -body {
+ list [foo] [foo]
+} -cleanup {
+ unset body
+ rename moo {}
+ rename foo {}
+} -result {16 24}
+test coroutine-1.13 {subst as coroutine: literal} {
+ list [coroutine foo eval {subst {>>[yield a],[yield b]<<}}] [foo x] [foo y]
+} {a b >>x,y<<}
+test coroutine-1.14 {subst as coroutine: in variable} {
+ set pattern {>>[yield c],[yield d]<<}
+ list [coroutine foo eval {subst $pattern}] [foo p] [foo q]
+} {c d >>p,q<<}
+
+test coroutine-2.1 {self deletion on return} -body {
+ coroutine foo set x 3
+ foo
+} -returnCodes error -result {invalid command name "foo"}
+test coroutine-2.2 {self deletion on return} -body {
+ coroutine foo ::apply [list {} {yield; yield 1; return 2}]
+ list [foo] [foo] [catch foo msg] $msg
+} -result {1 2 1 {invalid command name "foo"}}
+test coroutine-2.3 {self deletion on error return} -body {
+ coroutine foo ::apply [list {} {yield;yield 1; error ouch!}]
+ list [foo] [catch foo msg] $msg [catch foo msg] $msg
+} -result {1 1 ouch! 1 {invalid command name "foo"}}
+test coroutine-2.4 {self deletion on other return} -body {
+ coroutine foo ::apply [list {} {yield;yield 1; return -code 100 ouch!}]
+ list [foo] [catch foo msg] $msg [catch foo msg] $msg
+} -result {1 100 ouch! 1 {invalid command name "foo"}}
+test coroutine-2.5 {deletion of suspended coroutine} -body {
+ coroutine foo ::apply [list {} {yield; yield 1; return 2}]
+ list [foo] [rename foo {}] [catch foo msg] $msg
+} -result {1 {} 1 {invalid command name "foo"}}
+test coroutine-2.6 {deletion of running coroutine} -body {
+ coroutine foo ::apply [list {} {yield; rename foo {}; yield 1; return 2}]
+ list [foo] [catch foo msg] $msg
+} -result {1 1 {invalid command name "foo"}}
+
+test coroutine-3.1 {info level computation} -setup {
+ proc a {} {while 1 {yield [info level]}}
+ proc b {} foo
+} -body {
+ # note that coroutines execute in uplevel #0
+ set l0 [coroutine foo a]
+ set l1 [foo]
+ set l2 [b]
+ list $l0 $l1 $l2
+} -cleanup {
+ rename a {}
+ rename b {}
+} -result {1 1 1}
+test coroutine-3.2 {info frame computation} -setup {
+ proc a {} {while 1 {yield [info frame]}}
+ proc b {} foo
+} -body {
+ set l0 [coroutine foo a]
+ set l1 [foo]
+ set l2 [b]
+ expr {$l2 - $l1}
+} -cleanup {
+ rename a {}
+ rename b {}
+} -result 1
+test coroutine-3.3 {info coroutine} -setup {
+ proc a {} {info coroutine}
+ proc b {} a
+} -body {
+ b
+} -cleanup {
+ rename a {}
+ rename b {}
+} -result {}
+test coroutine-3.4 {info coroutine} -setup {
+ proc a {} {info coroutine}
+ proc b {} a
+} -body {
+ coroutine foo b
+} -cleanup {
+ rename a {}
+ rename b {}
+} -result ::foo
+test coroutine-3.5 {info coroutine} -setup {
+ proc a {} {info coroutine}
+ proc b {} {rename [info coroutine] {}; a}
+} -body {
+ coroutine foo b
+} -cleanup {
+ rename a {}
+ rename b {}
+} -result {}
+test coroutine-3.6 {info frame, bug #2910094} -setup {
+ proc stack {} {
+ set res [list "LEVEL:[set lev [info frame]]"]
+ for {set i 1} {$i < $lev} {incr i} {
+ lappend res [info frame $i]
+ }
+ set res
+ # the precise command depends on line numbers and such, is likely not
+ # to be stable: just check that the test completes!
+ return
+ }
+ proc a {} stack
+} -body {
+ coroutine aa a
+} -cleanup {
+ rename stack {}
+ rename a {}
+} -result {}
+
+test coroutine-4.1 {bug #2093188} -setup {
+ proc foo {} {
+ set v 1
+ trace add variable v {write unset} bar
+ yield
+ set v 2
+ yield
+ set v 3
+ }
+ proc bar args {lappend ::res $args}
+ coroutine a foo
+} -body {
+ list [a] [a] $::res
+} -cleanup {
+ rename foo {}
+ rename bar {}
+ unset ::res
+} -result {{} 3 {{v {} write} {v {} write} {v {} unset}}}
+test coroutine-4.2 {bug #2093188} -setup {
+ proc foo {} {
+ set v 1
+ trace add variable v {read unset} bar
+ yield
+ set v 2
+ set v
+ yield
+ set v 3
+ }
+ proc bar args {lappend ::res $args}
+ coroutine a foo
+} -body {
+ list [a] [a] $::res
+} -cleanup {
+ rename foo {}
+ rename bar {}
+ unset ::res
+} -result {{} 3 {{v {} read} {v {} unset}}}
+
+test coroutine-4.3 {bug #2093947} -setup {
+ proc foo {} {
+ set v 1
+ trace add variable v {write unset} bar
+ yield
+ set v 2
+ yield
+ set v 3
+ }
+ proc bar args {lappend ::res $args}
+} -body {
+ coroutine a foo
+ a
+ a
+ coroutine a foo
+ a
+ rename a {}
+ set ::res
+} -cleanup {
+ rename foo {}
+ rename bar {}
+ unset ::res
+} -result {{v {} write} {v {} write} {v {} unset} {v {} write} {v {} unset}}
+
+test coroutine-4.4 {bug #2917627: cmd resolution} -setup {
+ proc a {} {return global}
+ namespace eval b {proc a {} {return local}}
+} -body {
+ namespace eval b {coroutine foo a}
+} -cleanup {
+ rename a {}
+ namespace delete b
+} -result local
+
+test coroutine-4.5 {bug #2724403} -constraints {memory} \
+-setup {
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex $lines 3 3
+ }
+} -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ set ns ::y$i
+ namespace eval $ns {}
+ proc ${ns}::start {} {yield; puts hello}
+ coroutine ${ns}::run ${ns}::start
+ namespace delete $ns
+ set start $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $start}]
+} -cleanup {
+ rename getbytes {}
+ unset i ns start end
+} -result 0
+
+test coroutine-4.6 {compile context, bug #3282869} -setup {
+ unset ::x
+ proc f x {
+ coroutine D eval {yield X$x;yield Y}
+ }
+} -body {
+ f 12
+} -cleanup {
+ rename f {}
+} -returnCodes error -match glob -result {can't read *}
+
+test coroutine-4.7 {compile context, bug #3282869} -setup {
+ proc f x {
+ coroutine D eval {yield X$x;yield Y$x}
+ }
+} -body {
+ set ::x 15
+ set ::x [f 12]
+ D
+} -cleanup {
+ D
+ unset ::x
+ rename f {}
+} -result YX15
+
+test coroutine-5.1 {right numLevels on coro return} -constraints {testnrelevels} \
+-setup {
+ proc nestedYield {{val {}}} {
+ yield $val
+ }
+ proc getNumLevel {} {
+ # remove the level for this proc's call
+ expr {[lindex [testnrelevels] 1] - 1}
+ }
+ proc relativeLevel base {
+ # remove the level for this proc's call
+ expr {[getNumLevel] - $base - 1}
+ }
+ proc foo {} {
+ while 1 {
+ nestedYield
+ }
+ }
+ set res {}
+} -body {
+ set base [getNumLevel]
+ lappend res [relativeLevel $base]
+ eval {coroutine a foo}
+ # back to base level
+ lappend res [relativeLevel $base]
+ a
+ lappend res [relativeLevel $base]
+ eval a
+ lappend res [relativeLevel $base]
+ eval {eval a}
+ lappend res [relativeLevel $base]
+ rename a {}
+ lappend res [relativeLevel $base]
+ set res
+} -cleanup {
+ rename foo {}
+ rename nestedYield {}
+ rename getNumLevel {}
+ rename relativeLevel {}
+ unset res
+} -result {0 0 0 0 0 0}
+test coroutine-5.2 {right numLevels within coro} -constraints {testnrelevels} \
+-setup {
+ proc nestedYield {{val {}}} {
+ yield $val
+ }
+ proc getNumLevel {} {
+ # remove the level for this proc's call
+ expr {[lindex [testnrelevels] 1] - 1}
+ }
+ proc relativeLevel base {
+ # remove the level for this proc's call
+ expr {[getNumLevel] - $base - 1}
+ }
+ proc foo base {
+ while 1 {
+ set base [nestedYield [relativeLevel $base]]
+ }
+ }
+ set res {}
+} -body {
+ lappend res [eval {coroutine a foo [getNumLevel]}]
+ lappend res [a [getNumLevel]]
+ lappend res [eval {a [getNumLevel]}]
+ lappend res [eval {eval {a [getNumLevel]}}]
+ set base [lindex $res 0]
+ foreach x $res[set res {}] {
+ lappend res [expr {$x-$base}]
+ }
+ set res
+} -cleanup {
+ rename a {}
+ rename foo {}
+ rename nestedYield {}
+ rename getNumLevel {}
+ rename relativeLevel {}
+ unset res
+} -result {0 0 0 0}
+
+test coroutine-6.1 {coroutine nargs} -body {
+ coroutine a ::apply $lambda
+ a
+} -cleanup {
+ rename a {}
+} -result 0
+test coroutine-6.2 {coroutine nargs} -body {
+ coroutine a ::apply $lambda
+ a a
+} -cleanup {
+ rename a {}
+} -result 0
+test coroutine-6.3 {coroutine nargs} -body {
+ coroutine a ::apply $lambda
+ a a a
+} -cleanup {
+ rename a {}
+} -returnCodes error -result {wrong # args: should be "a ?arg?"}
+
+test coroutine-7.1 {yieldto} -body {
+ coroutine c apply {{} {
+ yield
+ yieldto return -level 0 -code 1 quux
+ return quuy
+ }}
+ set res [list [catch c msg] $msg]
+ lappend res [catch c msg] $msg
+ lappend res [catch c msg] $msg
+} -cleanup {
+ unset res
+} -result [list 1 quux 0 quuy 1 {invalid command name "c"}]
+test coroutine-7.2 {multi-argument yielding with yieldto} -body {
+ proc corobody {} {
+ set a 1
+ while 1 {
+ set a [yield $a]
+ set a [yieldto return -level 0 $a]
+ lappend a [llength $a]
+ }
+ }
+ coroutine a corobody
+ coroutine b corobody
+ list [a x] [a y z] [a \{p] [a \{q r] [a] [a] [rename a {}] \
+ [b ok] [rename b {}]
+} -cleanup {
+ rename corobody {}
+} -result {x {y z 2} \{p {\{q r 2} {} 0 {} ok {}}
+test coroutine-7.3 {yielding between coroutines} -body {
+ proc juggler {target {value ""}} {
+ if {$value eq ""} {
+ set value [yield [info coroutine]]
+ }
+ while {[llength $value]} {
+ lappend ::result $value [info coroutine]
+ set value [lrange $value 0 end-1]
+ lassign [yieldto $target $value] value
+ }
+ # Clear nested collection of coroutines
+ catch $target
+ }
+ set result ""
+ coroutine j1 juggler [coroutine j2 juggler [coroutine j3 juggler j1]]\
+ {a b c d e}
+ list $result [info command j1] [info command j2] [info command j3]
+} -cleanup {
+ catch {rename juggler ""}
+} -result {{{a b c d e} ::j1 {a b c d} ::j2 {a b c} ::j3 {a b} ::j1 a ::j2} {} {} {}}
+
+# cleanup
+unset lambda
+::tcltest::cleanupTests
+
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/dcall.test b/pkgs/msgcat/tests/dcall.test
new file mode 100644
index 0000000..8977c31
--- /dev/null
+++ b/pkgs/msgcat/tests/dcall.test
@@ -0,0 +1,42 @@
+# Commands covered: none
+#
+# This file contains a collection of tests for Tcl_CallWhenDeleted.
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testdcall [llength [info commands testdcall]]
+
+test dcall-1.1 {deletion callbacks} testdcall {
+ lsort -increasing [testdcall 1 2 3]
+} {1 2 3}
+test dcall-1.2 {deletion callbacks} testdcall {
+ testdcall
+} {}
+test dcall-1.3 {deletion callbacks} testdcall {
+ lsort -increasing [testdcall 20 21 22 -22]
+} {20 21}
+test dcall-1.4 {deletion callbacks} testdcall {
+ lsort -increasing [testdcall 20 21 22 -20]
+} {21 22}
+test dcall-1.5 {deletion callbacks} testdcall {
+ lsort -increasing [testdcall 20 21 22 -21]
+} {20 22}
+test dcall-1.6 {deletion callbacks} testdcall {
+ lsort -increasing [testdcall 20 21 22 -21 -22 -20]
+} {}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/dict.test b/pkgs/msgcat/tests/dict.test
new file mode 100644
index 0000000..77bacf6
--- /dev/null
+++ b/pkgs/msgcat/tests/dict.test
@@ -0,0 +1,1531 @@
+# This test file covers the dictionary object type and the dict command used
+# to work with values of that type.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 2003-2009 Donal K. Fellows
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Used for constraining memory leak tests
+testConstraint memory [llength [info commands memory]]
+if {[testConstraint memory]} {
+ proc memtest script {
+ set end [lindex [split [memory info] \n] 3 3]
+ for {set i 0} {$i < 5} {incr i} {
+ uplevel 1 $script
+ set tmp $end
+ set end [lindex [split [memory info] \n] 3 3]
+ }
+ expr {$end - $tmp}
+ }
+}
+
+test dict-1.1 {dict command basic syntax} -returnCodes error -body {
+ dict
+} -result {wrong # args: should be "dict subcommand ?arg ...?"}
+test dict-1.2 {dict command basic syntax} -returnCodes error -body {
+ dict ?
+} -match glob -result {unknown or ambiguous subcommand "?": must be *}
+
+test dict-2.1 {dict create command} {
+ dict create
+} {}
+test dict-2.2 {dict create command} {
+ dict create a b
+} {a b}
+test dict-2.3 {dict create command} -body {
+ set result {}
+ set dict [dict create a b c d]
+ # Can't compare directly as ordering of values is undefined
+ foreach key {a c} {
+ set idx [lsearch -exact $dict $key]
+ if {$idx & 1} {
+ error "found $key at odd index $idx in $dict"
+ }
+ lappend result [lindex $dict [expr {$idx+1}]]
+ }
+ return $result
+} -cleanup {
+ unset result dict key idx
+} -result {b d}
+test dict-2.4 {dict create command} -returnCodes error -body {
+ dict create a
+} -result {wrong # args: should be "dict create ?key value ...?"}
+test dict-2.5 {dict create command} -returnCodes error -body {
+ dict create a b c
+} -result {wrong # args: should be "dict create ?key value ...?"}
+test dict-2.6 {dict create command - initialse refcount field!} -body {
+ # Bug 715751 will show up in memory debuggers like purify
+ for {set i 0} {$i<10} {incr i} {
+ set dictv [dict create a 0]
+ set share [dict values $dictv]
+ list [dict incr dictv a]
+ }
+} -cleanup {
+ unset i dictv share
+} -result {}
+test dict-2.7 {dict create command - #-quoting in string rep} {
+ dict create # #comment
+} {{#} #comment}
+test dict-2.8 {dict create command - #-quoting in string rep} -body {
+ dict create #a x #b x
+} -match glob -result {{#?} x #? x}
+
+test dict-3.1 {dict get command} {dict get {a b} a} b
+test dict-3.2 {dict get command} {dict get {a b c d} a} b
+test dict-3.3 {dict get command} {dict get {a b c d} c} d
+test dict-3.4 {dict get command} -returnCodes error -body {
+ dict get {a b c d} b
+} -result {key "b" not known in dictionary}
+test dict-3.5 {dict get command} {dict get {a {p q r s} b {u v x y}} a p} q
+test dict-3.6 {dict get command} {dict get {a {p q r s} b {u v x y}} a r} s
+test dict-3.7 {dict get command} {dict get {a {p q r s} b {u v x y}} b u} v
+test dict-3.8 {dict get command} {dict get {a {p q r s} b {u v x y}} b x} y
+test dict-3.9 {dict get command} -returnCodes error -body {
+ dict get {a {p q r s} b {u v x y}} a z
+} -result {key "z" not known in dictionary}
+test dict-3.10 {dict get command} -returnCodes error -body {
+ dict get {a {p q r s} b {u v x y}} c z
+} -result {key "c" not known in dictionary}
+test dict-3.11 {dict get command} {dict get [dict create a b c d] a} b
+test dict-3.12 {dict get command} -returnCodes error -body {
+ dict get
+} -result {wrong # args: should be "dict get dictionary ?key ...?"}
+test dict-3.13 {dict get command} -body {
+ set dict [dict get {a b c d}]
+ if {$dict eq "a b c d"} {
+ return OK
+ } elseif {$dict eq "c d a b"} {
+ return reordered
+ } else {
+ return $dict
+ }
+} -cleanup {
+ unset dict
+} -result OK
+test dict-3.14 {dict get command} -returnCodes error -body {
+ dict get {a b c d} a c
+} -result {missing value to go with key}
+test dict-3.15 {compiled dict get error cleanliness - Bug 2431847} -body {
+ apply {{} {
+ dict set a(z) b c
+ dict get $a(z) d
+ }}
+} -returnCodes error -result {key "d" not known in dictionary}
+test dict-3.16 {dict/list shimmering - Bug 3004007} {set l [list p 1 p 2 q 3];dict get $l q;set l} {p 1 p 2 q 3}
+test dict-3.17 {dict/list shimmering - Bug 3004007} {set l [list p 1 p 2 q 3];dict get $l q;llength $l} 6
+
+test dict-4.1 {dict replace command} {
+ dict replace {a b c d}
+} {a b c d}
+test dict-4.2 {dict replace command} {
+ dict replace {a b c d} e f
+} {a b c d e f}
+test dict-4.3 {dict replace command} {
+ dict replace {a b c d} c f
+} {a b c f}
+test dict-4.4 {dict replace command} {
+ dict replace {a b c d} c x a y
+} {a y c x}
+test dict-4.5 {dict replace command} -returnCodes error -body {
+ dict replace
+} -result {wrong # args: should be "dict replace dictionary ?key value ...?"}
+test dict-4.6 {dict replace command} -returnCodes error -body {
+ dict replace {a a} a
+} -result {wrong # args: should be "dict replace dictionary ?key value ...?"}
+test dict-4.7 {dict replace command} -returnCodes error -body {
+ dict replace {a a a} a b
+} -result {missing value to go with key}
+test dict-4.8 {dict replace command} -returnCodes error -body {
+ dict replace [list a a a] a b
+} -result {missing value to go with key}
+test dict-4.9 {dict replace command} {dict replace [list a a] a b} {a b}
+test dict-4.10 {dict replace command} {dict replace [list a a] a b a c} {a c}
+
+test dict-5.1 {dict remove command} {dict remove {a b c d} a} {c d}
+test dict-5.2 {dict remove command} {dict remove {a b c d} c} {a b}
+test dict-5.3 {dict remove command} {dict remove {a b c d} a c} {}
+test dict-5.4 {dict remove command} {dict remove {a b c d} c a} {}
+test dict-5.5 {dict remove command} {
+ dict remove {a b c d}
+} {a b c d}
+test dict-5.6 {dict remove command} {dict remove {a b} c} {a b}
+test dict-5.7 {dict remove command} -returnCodes error -body {
+ dict remove
+} -result {wrong # args: should be "dict remove dictionary ?key ...?"}
+
+test dict-6.1 {dict keys command} {dict keys {a b}} a
+test dict-6.2 {dict keys command} {dict keys {c d}} c
+test dict-6.3 {dict keys command} {lsort [dict keys {a b c d}]} {a c}
+test dict-6.4 {dict keys command} {dict keys {a b c d} a} a
+test dict-6.5 {dict keys command} {dict keys {a b c d} c} c
+test dict-6.6 {dict keys command} {dict keys {a b c d} e} {}
+test dict-6.7 {dict keys command} {lsort [dict keys {a b c d ca da} c*]} {c ca}
+test dict-6.8 {dict keys command} -returnCodes error -body {
+ dict keys
+} -result {wrong # args: should be "dict keys dictionary ?pattern?"}
+test dict-6.9 {dict keys command} -returnCodes error -body {
+ dict keys {} a b
+} -result {wrong # args: should be "dict keys dictionary ?pattern?"}
+test dict-6.10 {dict keys command} -returnCodes error -body {
+ dict keys a
+} -result {missing value to go with key}
+
+test dict-7.1 {dict values command} {dict values {a b}} b
+test dict-7.2 {dict values command} {dict values {c d}} d
+test dict-7.3 {dict values command} {lsort [dict values {a b c d}]} {b d}
+test dict-7.4 {dict values command} {dict values {a b c d} b} b
+test dict-7.5 {dict values command} {dict values {a b c d} d} d
+test dict-7.6 {dict values command} {dict values {a b c d} e} {}
+test dict-7.7 {dict values command} {lsort [dict values {a b c d ca da} d*]} {d da}
+test dict-7.8 {dict values command} -returnCodes error -body {
+ dict values
+} -result {wrong # args: should be "dict values dictionary ?pattern?"}
+test dict-7.9 {dict values command} -returnCodes error -body {
+ dict values {} a b
+} -result {wrong # args: should be "dict values dictionary ?pattern?"}
+test dict-7.10 {dict values command} -returnCodes error -body {
+ dict values a
+} -result {missing value to go with key}
+
+test dict-8.1 {dict size command} {dict size {}} 0
+test dict-8.2 {dict size command} {dict size {a b}} 1
+test dict-8.3 {dict size command} {dict size {a b c d}} 2
+test dict-8.4 {dict size command} -returnCodes error -body {
+ dict size
+} -result {wrong # args: should be "dict size dictionary"}
+test dict-8.5 {dict size command} -returnCodes error -body {
+ dict size a b
+} -result {wrong # args: should be "dict size dictionary"}
+test dict-8.6 {dict size command} -returnCodes error -body {
+ dict size a
+} -result {missing value to go with key}
+
+test dict-9.1 {dict exists command} {dict exists {a b} a} 1
+test dict-9.2 {dict exists command} {dict exists {a b} b} 0
+test dict-9.3 {dict exists command} {dict exists {a {b c}} a b} 1
+test dict-9.4 {dict exists command} {dict exists {a {b c}} a c} 0
+test dict-9.5 {dict exists command} {dict exists {a {b c}} b c} 0
+test dict-9.6 {dict exists command} {dict exists {a {b c d}} a c} 0
+test dict-9.7 {dict exists command} -returnCodes error -body {
+ dict exists
+} -result {wrong # args: should be "dict exists dictionary key ?key ...?"}
+test dict-9.8 {dict exists command} -returnCodes error -body {
+ dict exists {}
+} -result {wrong # args: should be "dict exists dictionary key ?key ...?"}
+
+test dict-10.1 {dict info command} -body {
+ # Actual string returned by this command is undefined; it is
+ # intended for human consumption and not for use by scripts.
+ dict info {}
+} -match glob -result *
+test dict-10.2 {dict info command} -returnCodes error -body {
+ dict info
+} -result {wrong # args: should be "dict info dictionary"}
+test dict-10.3 {dict info command} -returnCodes error -body {
+ dict info {} x
+} -result {wrong # args: should be "dict info dictionary"}
+test dict-10.4 {dict info command} -returnCodes error -body {
+ dict info x
+} -result {missing value to go with key}
+
+test dict-11.1 {dict incr command: unshared value} -body {
+ set dictv [dict create \
+ a [string index "=0=" 1] \
+ b [expr {1+2}] \
+ c [expr {wide(0x80000000)+1}]]
+ dict incr dictv a
+} -cleanup {
+ unset dictv
+} -result {a 1 b 3 c 2147483649}
+test dict-11.2 {dict incr command: unshared value} -body {
+ set dictv [dict create \
+ a [string index "=0=" 1] \
+ b [expr {1+2}] \
+ c [expr {wide(0x80000000)+1}]]
+ dict incr dictv b
+} -cleanup {
+ unset dictv
+} -result {a 0 b 4 c 2147483649}
+test dict-11.3 {dict incr command: unshared value} -body {
+ set dictv [dict create \
+ a [string index "=0=" 1] \
+ b [expr {1+2}] \
+ c [expr {wide(0x80000000)+1}]]
+ dict incr dictv c
+} -cleanup {
+ unset dictv
+} -result {a 0 b 3 c 2147483650}
+test dict-11.4 {dict incr command: shared value} -body {
+ set dictv [dict create a 0 b [expr {1+2}] c [expr {wide(0x80000000)+1}]]
+ set sharing [dict values $dictv]
+ dict incr dictv a
+} -cleanup {
+ unset dictv sharing
+} -result {a 1 b 3 c 2147483649}
+test dict-11.5 {dict incr command: shared value} -body {
+ set dictv [dict create a 0 b [expr {1+2}] c [expr {wide(0x80000000)+1}]]
+ set sharing [dict values $dictv]
+ dict incr dictv b
+} -cleanup {
+ unset dictv sharing
+} -result {a 0 b 4 c 2147483649}
+test dict-11.6 {dict incr command: shared value} -body {
+ set dictv [dict create a 0 b [expr {1+2}] c [expr {wide(0x80000000)+1}]]
+ set sharing [dict values $dictv]
+ dict incr dictv c
+} -cleanup {
+ unset dictv sharing
+} -result {a 0 b 3 c 2147483650}
+test dict-11.7 {dict incr command: unknown values} -body {
+ set dictv [dict create a 0 b [expr {1+2}] c [expr {wide(0x80000000)+1}]]
+ dict incr dictv d
+} -cleanup {
+ unset dictv
+} -result {a 0 b 3 c 2147483649 d 1}
+test dict-11.8 {dict incr command} -body {
+ set dictv {a 1}
+ dict incr dictv a 2
+} -cleanup {
+ unset dictv
+} -result {a 3}
+test dict-11.9 {dict incr command} -returnCodes error -body {
+ set dictv {a dummy}
+ dict incr dictv a
+} -cleanup {
+ unset dictv
+} -result {expected integer but got "dummy"}
+test dict-11.10 {dict incr command} -returnCodes error -body {
+ set dictv {a 1}
+ dict incr dictv a dummy
+} -cleanup {
+ unset dictv
+} -result {expected integer but got "dummy"}
+test dict-11.11 {dict incr command} -setup {
+ unset -nocomplain dictv
+} -body {
+ dict incr dictv a
+} -cleanup {
+ unset dictv
+} -result {a 1}
+test dict-11.12 {dict incr command} -returnCodes error -body {
+ set dictv a
+ dict incr dictv a
+} -cleanup {
+ unset dictv
+} -result {missing value to go with key}
+test dict-11.13 {dict incr command} -returnCodes error -body {
+ set dictv a
+ dict incr dictv a a a
+} -cleanup {
+ unset dictv
+} -result {wrong # args: should be "dict incr varName key ?increment?"}
+test dict-11.14 {dict incr command} -returnCodes error -body {
+ set dictv a
+ dict incr dictv
+} -cleanup {
+ unset dictv
+} -result {wrong # args: should be "dict incr varName key ?increment?"}
+test dict-11.15 {dict incr command: write failure} -setup {
+ unset -nocomplain dictVar
+} -body {
+ set dictVar(block) {}
+ dict incr dictVar a
+} -returnCodes error -cleanup {
+ unset dictVar
+} -result {can't set "dictVar": variable is array}
+test dict-11.16 {dict incr command: compilation} {
+ apply {{} {
+ set v {a 0 b 0 c 0}
+ dict incr v a
+ dict incr v b 1
+ dict incr v c 2
+ dict incr v d 3
+ list [dict get $v a] [dict get $v b] [dict get $v c] [dict get $v d]
+ }}
+} {1 1 2 3}
+test dict-11.17 {dict incr command: compilation} {
+ apply {{} {
+ set dictv {a 1}
+ dict incr dictv a 2
+ }}
+} {a 3}
+
+test dict-12.1 {dict lappend command} -body {
+ set dictv {a a}
+ dict lappend dictv a
+} -cleanup {
+ unset dictv
+} -result {a a}
+test dict-12.2 {dict lappend command} -body {
+ set dictv {a a}
+ set sharing [dict values $dictv]
+ dict lappend dictv a b
+} -cleanup {
+ unset dictv sharing
+} -result {a {a b}}
+test dict-12.3 {dict lappend command} -body {
+ set dictv {a a}
+ dict lappend dictv a b c
+} -cleanup {
+ unset dictv
+} -result {a {a b c}}
+test dict-12.2.1 {dict lappend command} -body {
+ set dictv [dict create a [string index =a= 1]]
+ dict lappend dictv a b
+} -cleanup {
+ unset dictv
+} -result {a {a b}}
+test dict-12.4 {dict lappend command} -body {
+ set dictv {}
+ dict lappend dictv a x y z
+} -cleanup {
+ unset dictv
+} -result {a {x y z}}
+test dict-12.5 {dict lappend command} -body {
+ unset -nocomplain dictv
+ dict lappend dictv a b
+} -cleanup {
+ unset dictv
+} -result {a b}
+test dict-12.6 {dict lappend command} -returnCodes error -body {
+ set dictv a
+ dict lappend dictv a a
+} -cleanup {
+ unset dictv
+} -result {missing value to go with key}
+test dict-12.7 {dict lappend command} -returnCodes error -body {
+ dict lappend
+} -result {wrong # args: should be "dict lappend varName key ?value ...?"}
+test dict-12.8 {dict lappend command} -returnCodes error -body {
+ dict lappend dictv
+} -result {wrong # args: should be "dict lappend varName key ?value ...?"}
+test dict-12.9 {dict lappend command} -returnCodes error -body {
+ set dictv [dict create a "\{"]
+ dict lappend dictv a a
+} -cleanup {
+ unset dictv
+} -result {unmatched open brace in list}
+test dict-12.10 {dict lappend command: write failure} -setup {
+ unset -nocomplain dictVar
+} -body {
+ set dictVar(block) {}
+ dict lappend dictVar a x
+} -returnCodes error -cleanup {
+ unset dictVar
+} -result {can't set "dictVar": variable is array}
+test dict-12.11 {compiled dict append: invalidate string rep - Bug 3079830} {
+ apply {{} {set d {a 1 b 2 c 3}; dict lappend d b 22}}
+} {a 1 b {2 22} c 3}
+
+test dict-13.1 {dict append command} -body {
+ set dictv {a a}
+ dict append dictv a
+} -cleanup {
+ unset dictv
+} -result {a a}
+test dict-13.2 {dict append command} -body {
+ set dictv {a a}
+ set sharing [dict values $dictv]
+ dict append dictv a b
+} -cleanup {
+ unset dictv sharing
+} -result {a ab}
+test dict-13.3 {dict append command} -body {
+ set dictv {a a}
+ dict append dictv a b c
+} -cleanup {
+ unset dictv
+} -result {a abc}
+test dict-13.2.1 {dict append command} -body {
+ set dictv [dict create a [string index =a= 1]]
+ dict append dictv a b
+} -cleanup {
+ unset dictv
+} -result {a ab}
+test dict-13.4 {dict append command} -body {
+ set dictv {}
+ dict append dictv a x y z
+} -cleanup {
+ unset dictv
+} -result {a xyz}
+test dict-13.5 {dict append command} -body {
+ unset -nocomplain dictv
+ dict append dictv a b
+} -cleanup {
+ unset dictv
+} -result {a b}
+test dict-13.6 {dict append command} -returnCodes error -body {
+ set dictv a
+ dict append dictv a a
+} -cleanup {
+ unset dictv
+} -result {missing value to go with key}
+test dict-13.7 {dict append command} -returnCodes error -body {
+ dict append
+} -result {wrong # args: should be "dict append varName key ?value ...?"}
+test dict-13.8 {dict append command} -returnCodes error -body {
+ dict append dictv
+} -result {wrong # args: should be "dict append varName key ?value ...?"}
+test dict-13.9 {dict append command: write failure} -setup {
+ unset -nocomplain dictVar
+} -body {
+ set dictVar(block) {}
+ dict append dictVar a x
+} -returnCodes error -cleanup {
+ unset dictVar
+} -result {can't set "dictVar": variable is array}
+test dict-13.10 {compiled dict append: crash case} {
+ apply {{} {dict append dictVar a o k}}
+} {a ok}
+test dict-13.11 {compiled dict append: invalidate string rep - Bug 3079830} {
+ apply {{} {set d {a 1 b 2 c 3}; dict append d b 22}}
+} {a 1 b 222 c 3}
+
+test dict-14.1 {dict for command: syntax} -returnCodes error -body {
+ dict for
+} -result {wrong # args: should be "dict for {keyVar valueVar} dictionary script"}
+test dict-14.2 {dict for command: syntax} -returnCodes error -body {
+ dict for x
+} -result {wrong # args: should be "dict for {keyVar valueVar} dictionary script"}
+test dict-14.3 {dict for command: syntax} -returnCodes error -body {
+ dict for x x
+} -result {wrong # args: should be "dict for {keyVar valueVar} dictionary script"}
+test dict-14.4 {dict for command: syntax} -returnCodes error -body {
+ dict for x x x x
+} -result {wrong # args: should be "dict for {keyVar valueVar} dictionary script"}
+test dict-14.5 {dict for command: syntax} -returnCodes error -body {
+ dict for x x x
+} -result {must have exactly two variable names}
+test dict-14.6 {dict for command: syntax} -returnCodes error -body {
+ dict for {x x x} x x
+} -result {must have exactly two variable names}
+test dict-14.7 {dict for command: syntax} -returnCodes error -body {
+ dict for "\{x" x x
+} -result {unmatched open brace in list}
+test dict-14.8 {dict for command} -body {
+ # This test confirms that [dict keys], [dict values] and [dict for]
+ # all traverse a dictionary in the same order.
+ set dictv {a A b B c C}
+ set keys {}
+ set values {}
+ dict for {k v} $dictv {
+ lappend keys $k
+ lappend values $v
+ }
+ set result [expr {
+ $keys eq [dict keys $dictv] && $values eq [dict values $dictv]
+ }]
+ expr {$result ? "YES" : [list "NO" $dictv $keys $values]}
+} -cleanup {
+ unset result keys values k v dictv
+} -result YES
+test dict-14.9 {dict for command} {
+ dict for {k v} {} {
+ error "unexpected execution of 'dict for' body"
+ }
+} {}
+test dict-14.10 {dict for command: script results} -body {
+ set times 0
+ dict for {k v} {a a b b} {
+ incr times
+ continue
+ error "shouldn't get here"
+ }
+ return $times
+} -cleanup {
+ unset times k v
+} -result 2
+test dict-14.11 {dict for command: script results} -body {
+ set times 0
+ dict for {k v} {a a b b} {
+ incr times
+ break
+ error "shouldn't get here"
+ }
+ return $times
+} -cleanup {
+ unset times k v
+} -result 1
+test dict-14.12 {dict for command: script results} -body {
+ set times 0
+ list [catch {
+ dict for {k v} {a a b b} {
+ incr times
+ error test
+ }
+ } msg] $msg $times $::errorInfo
+} -cleanup {
+ unset times k v msg
+} -result {1 test 1 {test
+ while executing
+"error test"
+ ("dict for" body line 3)
+ invoked from within
+"dict for {k v} {a a b b} {
+ incr times
+ error test
+ }"}}
+test dict-14.13 {dict for command: script results} {
+ apply {{} {
+ dict for {k v} {a b} {
+ return ok,$k,$v
+ error "skipped return completely"
+ }
+ error "return didn't go far enough"
+ }}
+} ok,a,b
+test dict-14.14 {dict for command: handle representation loss} -body {
+ set dictVar {a b c d e f g h}
+ set keys {}
+ set values {}
+ dict for {k v} $dictVar {
+ if {[llength $dictVar]} {
+ lappend keys $k
+ lappend values $v
+ }
+ }
+ list [lsort $keys] [lsort $values]
+} -cleanup {
+ unset dictVar keys values k v
+} -result {{a c e g} {b d f h}}
+test dict-14.15 {dict for command: keys are unique and iterated over once only} -setup {
+ unset -nocomplain accum
+ array set accum {}
+} -body {
+ set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+ dict for {k v} $dictVar {
+ append accum($k) $v,
+ }
+ set result [lsort [array names accum]]
+ lappend result :
+ foreach k $result {
+ catch {lappend result $accum($k)}
+ }
+ return $result
+} -cleanup {
+ unset dictVar k v result accum
+} -result {a1 a2 b1 b2 bar foo : a, b, c, d, foo, bar,}
+test dict-14.16 {dict for command in compilation context} {
+ apply {{} {
+ set res {x x x x x x}
+ dict for {k v} {a 0 b 1 c 2 d 3 e 4 f 5} {
+ lset res $v $k
+ continue
+ }
+ return $res
+ }}
+} {a b c d e f}
+test dict-14.17 {dict for command in compilation context} {
+ # Bug 1379349
+ apply {{} {
+ set d [dict create a 1] ;# Dict must be unshared!
+ dict for {k v} $d {
+ dict set d $k 0 ;# Any modification will do
+ }
+ return $d
+ }}
+} {a 0}
+test dict-14.18 {dict for command in compilation context} {
+ # Bug 1382528
+ apply {{} {
+ dict for {k v} {} {} ;# Note empty dict
+ catch { error foo } ;# Note compiled [catch]
+ }}
+} 1
+test dict-14.19 {dict for and invalid dicts: bug 1531184} -body {
+ di[list]ct for {k v} x {}
+} -returnCodes 1 -result {missing value to go with key}
+test dict-14.20 {dict for stack space compilation: bug 1903325} {
+ apply {{x y args} {
+ dict for {a b} $x {}
+ concat "c=$y,$args"
+ }} {} 1 2 3
+} {c=1,2 3}
+# There's probably a lot more tests to add here. Really ought to use a
+# coverage tool for this job...
+
+test dict-15.1 {dict set command} -body {
+ set dictVar {}
+ dict set dictVar a x
+} -cleanup {
+ unset dictVar
+} -result {a x}
+test dict-15.2 {dict set command} -body {
+ set dictvar {a {}}
+ dict set dictvar a b x
+} -cleanup {
+ unset dictvar
+} -result {a {b x}}
+test dict-15.3 {dict set command} -body {
+ set dictvar {a {b {}}}
+ dict set dictvar a b c x
+} -cleanup {
+ unset dictvar
+} -result {a {b {c x}}}
+test dict-15.4 {dict set command} -body {
+ set dictVar {a y}
+ dict set dictVar a x
+} -cleanup {
+ unset dictVar
+} -result {a x}
+test dict-15.5 {dict set command} -body {
+ set dictVar {a {b y}}
+ dict set dictVar a b x
+} -cleanup {
+ unset dictVar
+} -result {a {b x}}
+test dict-15.6 {dict set command} -body {
+ set dictVar {a {b {c y}}}
+ dict set dictVar a b c x
+} -cleanup {
+ unset dictVar
+} -result {a {b {c x}}}
+test dict-15.7 {dict set command: path creation} -body {
+ set dictVar {}
+ dict set dictVar a b x
+} -cleanup {
+ unset dictVar
+} -result {a {b x}}
+test dict-15.8 {dict set command: creates variables} -setup {
+ unset -nocomplain dictVar
+} -body {
+ dict set dictVar a x
+ return $dictVar
+} -cleanup {
+ unset dictVar
+} -result {a x}
+test dict-15.9 {dict set command: write failure} -setup {
+ unset -nocomplain dictVar
+} -body {
+ set dictVar(block) {}
+ dict set dictVar a x
+} -returnCodes error -cleanup {
+ unset dictVar
+} -result {can't set "dictVar": variable is array}
+test dict-15.10 {dict set command: syntax} -returnCodes error -body {
+ dict set
+} -result {wrong # args: should be "dict set varName key ?key ...? value"}
+test dict-15.11 {dict set command: syntax} -returnCodes error -body {
+ dict set a
+} -result {wrong # args: should be "dict set varName key ?key ...? value"}
+test dict-15.12 {dict set command: syntax} -returnCodes error -body {
+ dict set a a
+} -result {wrong # args: should be "dict set varName key ?key ...? value"}
+test dict-15.13 {dict set command} -returnCodes error -body {
+ set dictVar a
+ dict set dictVar b c
+} -cleanup {
+ unset dictVar
+} -result {missing value to go with key}
+
+test dict-16.1 {dict unset command} -body {
+ set dictVar {a b c d}
+ dict unset dictVar a
+} -cleanup {
+ unset dictVar
+} -result {c d}
+test dict-16.2 {dict unset command} -body {
+ set dictVar {a b c d}
+ dict unset dictVar c
+} -cleanup {
+ unset dictVar
+} -result {a b}
+test dict-16.3 {dict unset command} -body {
+ set dictVar {a b}
+ dict unset dictVar c
+} -cleanup {
+ unset dictVar
+} -result {a b}
+test dict-16.4 {dict unset command} -body {
+ set dictVar {a {b c d e}}
+ dict unset dictVar a b
+} -cleanup {
+ unset dictVar
+} -result {a {d e}}
+test dict-16.5 {dict unset command} -returnCodes error -body {
+ set dictVar a
+ dict unset dictVar a
+} -cleanup {
+ unset dictVar
+} -result {missing value to go with key}
+test dict-16.6 {dict unset command} -returnCodes error -body {
+ set dictVar {a b}
+ dict unset dictVar c d
+} -cleanup {
+ unset dictVar
+} -result {key "c" not known in dictionary}
+test dict-16.7 {dict unset command} -setup {
+ unset -nocomplain dictVar
+} -body {
+ list [info exists dictVar] [dict unset dictVar a] [info exists dictVar]
+} -cleanup {
+ unset dictVar
+} -result {0 {} 1}
+test dict-16.8 {dict unset command} -returnCodes error -body {
+ dict unset dictVar
+} -result {wrong # args: should be "dict unset varName key ?key ...?"}
+test dict-16.9 {dict unset command: write failure} -setup {
+ unset -nocomplain dictVar
+} -body {
+ set dictVar(block) {}
+ dict unset dictVar a
+} -returnCodes error -cleanup {
+ unset dictVar
+} -result {can't set "dictVar": variable is array}
+
+test dict-17.1 {dict filter command: key} -body {
+ set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+ dict filter $dictVar key a2
+} -cleanup {
+ unset dictVar
+} -result {a2 b}
+test dict-17.2 {dict filter command: key} -body {
+ set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+ dict size [dict filter $dictVar key *]
+} -cleanup {
+ unset dictVar
+} -result 6
+test dict-17.3 {dict filter command: key} -body {
+ set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+ dict filter $dictVar key ???
+} -cleanup {
+ unset dictVar
+} -result {foo bar bar foo}
+test dict-17.4 {dict filter command: key - no patterns} {
+ dict filter {a b c d} key
+} {}
+test dict-17.4.1 {dict filter command: key - many patterns} {
+ dict filter {a1 a a2 b b1 c b2 d foo bar bar foo} key a? b?
+} {a1 a a2 b b1 c b2 d}
+test dict-17.5 {dict filter command: key - bad dict} -returnCodes error -body {
+ dict filter {a b c} key
+} -result {missing value to go with key}
+test dict-17.6 {dict filter command: value} -body {
+ set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+ dict filter $dictVar value c
+} -cleanup {
+ unset dictVar
+} -result {b1 c}
+test dict-17.7 {dict filter command: value} -body {
+ set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+ dict size [dict filter $dictVar value *]
+} -cleanup {
+ unset dictVar
+} -result 6
+test dict-17.8 {dict filter command: value} -body {
+ set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+ dict filter $dictVar value ???
+} -cleanup {
+ unset dictVar
+} -result {foo bar bar foo}
+test dict-17.9 {dict filter command: value - no patterns} {
+ dict filter {a b c d} value
+} {}
+test dict-17.9.1 {dict filter command: value - many patterns} {
+ dict filter {a a1 b a2 c b1 foo bar bar foo d b2} value a? b?
+} {a a1 b a2 c b1 d b2}
+test dict-17.10 {dict filter command: value - bad dict} -body {
+ dict filter {a b c} value a
+} -returnCodes error -result {missing value to go with key}
+test dict-17.11 {dict filter command: script} -body {
+ set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+ set n 0
+ list [dict filter $dictVar script {k v} {
+ incr n
+ expr {[string length $k] == [string length $v]}
+ }] $n
+} -cleanup {
+ unset dictVar n k v
+} -result {{foo bar bar foo} 6}
+test dict-17.12 {dict filter command: script} -returnCodes error -body {
+ dict filter {a b} script {k v} {
+ concat $k $v
+ }
+} -cleanup {
+ unset k v
+} -result {expected boolean value but got "a b"}
+test dict-17.13 {dict filter command: script} -body {
+ list [catch {dict filter {a b} script {k v} {error x}} msg] $msg \
+ $::errorInfo
+} -cleanup {
+ unset k v msg
+} -result {1 x {x
+ while executing
+"error x"
+ ("dict filter" script line 1)
+ invoked from within
+"dict filter {a b} script {k v} {error x}"}}
+test dict-17.14 {dict filter command: script} -setup {
+ set n 0
+} -body {
+ list [dict filter {a b c d} script {k v} {
+ incr n
+ break
+ error boom!
+ }] $n
+} -cleanup {
+ unset n k v
+} -result {{} 1}
+test dict-17.15 {dict filter command: script} -setup {
+ set n 0
+} -body {
+ list [dict filter {a b c d} script {k v} {
+ incr n
+ continue
+ error boom!
+ }] $n
+} -cleanup {
+ unset n k v
+} -result {{} 2}
+test dict-17.16 {dict filter command: script} {
+ apply {{} {
+ dict filter {a b} script {k v} {
+ return ok,$k,$v
+ error "skipped return completely"
+ }
+ error "return didn't go far enough"
+ }}
+} ok,a,b
+test dict-17.17 {dict filter command: script} -body {
+ dict filter {a b} script {k k} {continue}
+ return $k
+} -cleanup {
+ unset k
+} -result b
+test dict-17.18 {dict filter command: script} -returnCodes error -body {
+ dict filter {a b} script {k k}
+} -result {wrong # args: should be "dict filter dictionary script {keyVar valueVar} filterScript"}
+test dict-17.19 {dict filter command: script} -returnCodes error -body {
+ dict filter {a b} script k {continue}
+} -result {must have exactly two variable names}
+test dict-17.20 {dict filter command: script} -returnCodes error -body {
+ dict filter {a b} script "\{k v" {continue}
+} -result {unmatched open brace in list}
+test dict-17.21 {dict filter command} -returnCodes error -body {
+ dict filter {a b}
+} -result {wrong # args: should be "dict filter dictionary filterType ?arg ...?"}
+test dict-17.22 {dict filter command} -returnCodes error -body {
+ dict filter {a b} JUNK
+} -result {bad filterType "JUNK": must be key, script, or value}
+test dict-17.23 {dict filter command} -returnCodes error -body {
+ dict filter a key *
+} -result {missing value to go with key}
+
+test dict-18.1 {dict-list relationship} -body {
+ # Test that any internal conversion between list and dict does not change
+ # the object
+ set l [list 1 2 3 4 5 6 7 8 9 0 q w e r t y]
+ dict values $l
+ return $l
+} -cleanup {
+ unset l
+} -result {1 2 3 4 5 6 7 8 9 0 q w e r t y}
+test dict-18.2 {dict-list relationship} -body {
+ # Test that the dictionary is a valid list
+ set d [dict create "abc def" 0 "a\{b" 1 "c\}d" 2]
+ for {set t 0} {$t < 5} {incr t} {
+ llength $d
+ dict lappend d "abc def" "\}\{"
+ dict append d "a\{b" "\}"
+ dict incr d "c\}d" 1
+ }
+ llength $d
+} -cleanup {
+ unset d t
+} -result 6
+test dict-18.3 {dict-list relationship} -body {
+ set ld [list a b c d c e f g]
+ list [string length $ld] [dict size $ld] [llength $ld]
+} -cleanup {
+ unset ld
+} -result {15 3 8}
+test dict-18.4 {dict-list relationship} -body {
+ set ld [list a b c d c e f g]
+ list [llength $ld] [dict size $ld] [llength $ld]
+} -cleanup {
+ unset ld
+} -result {8 3 8}
+
+# This is a test for a specific bug.
+# It shows a bad ref counter when running with memdebug on.
+test dict-19.1 {memory bug} {
+ apply {{} {
+ set successors [dict create x {c d}]
+ dict set successors x a b
+ dict get $successors x
+ }}
+} [dict create c d a b]
+test dict-19.2 {dict: testing for leaks} -constraints memory -body {
+ # This test is made to stress object reference management
+ memtest {
+ apply {{} {
+ # A shared invalid dictinary
+ set apa {a {}b c d}
+ set bepa $apa
+ catch {dict replace $apa e f}
+ catch {dict remove $apa c d}
+ catch {dict incr apa a 5}
+ catch {dict lappend apa a 5}
+ catch {dict append apa a 5}
+ catch {dict set apa a 5}
+ catch {dict unset apa a}
+
+ # A shared valid dictionary, invalid incr
+ set apa {a b c d}
+ set bepa $apa
+ catch {dict incr bepa a 5}
+
+ # An error during write to an unshared object, incr
+ set apa {a 1 b 2}
+ set bepa [lrange $apa 0 end]
+ trace add variable bepa write {error hej}
+ catch {dict incr bepa a 5}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # An error during write to a shared object, incr
+ set apa {a 1 b 2}
+ set bepa $apa
+ trace add variable bepa write {error hej}
+ catch {dict incr bepa a 5}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # A shared valid dictionary, invalid lappend
+ set apa [list a {{}b} c d]
+ set bepa $apa
+ catch {dict lappend bepa a 5}
+
+ # An error during write to an unshared object, lappend
+ set apa {a 1 b 2}
+ set bepa [lrange $apa 0 end]
+ trace add variable bepa write {error hej}
+ catch {dict lappend bepa a 5}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # An error during write to a shared object, lappend
+ set apa {a 1 b 2}
+ set bepa $apa
+ trace add variable bepa write {error hej}
+ catch {dict lappend bepa a 5}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # An error during write to an unshared object, append
+ set apa {a 1 b 2}
+ set bepa [lrange $apa 0 end]
+ trace add variable bepa write {error hej}
+ catch {dict append bepa a 5}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # An error during write to a shared object, append
+ set apa {a 1 b 2}
+ set bepa $apa
+ trace add variable bepa write {error hej}
+ catch {dict append bepa a 5}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # An error during write to an unshared object, set
+ set apa {a 1 b 2}
+ set bepa [lrange $apa 0 end]
+ trace add variable bepa write {error hej}
+ catch {dict set bepa a 5}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # An error during write to a shared object, set
+ set apa {a 1 b 2}
+ set bepa $apa
+ trace add variable bepa write {error hej}
+ catch {dict set bepa a 5}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # An error during write to an unshared object, unset
+ set apa {a 1 b 2}
+ set bepa [lrange $apa 0 end]
+ trace add variable bepa write {error hej}
+ catch {dict unset bepa a}
+ trace remove variable bepa write {error hej}
+ unset bepa
+
+ # An error during write to a shared object, unset
+ set apa {a 1 b 2}
+ set bepa $apa
+ trace add variable bepa write {error hej}
+ catch {dict unset bepa a}
+ trace remove variable bepa write {error hej}
+ unset bepa
+ }}
+ }
+} -result 0
+test dict-19.3 {testing for leaks - Bug 2874678} -constraints memory -body {
+ set d aDictVar; # Force interpreted [dict incr]
+ memtest {
+ dict incr $d aKey 0
+ unset $d
+ }
+} -cleanup {
+ unset d
+} -result 0
+
+test dict-20.1 {dict merge command} {
+ dict merge
+} {}
+test dict-20.2 {dict merge command} {
+ dict merge {a b c d e f}
+} {a b c d e f}
+test dict-20.3 {dict merge command} -body {
+ dict merge {a b c d e}
+} -result {missing value to go with key} -returnCodes error
+test dict-20.4 {dict merge command} {
+ dict merge {a b c d} {e f g h}
+} {a b c d e f g h}
+test dict-20.5 {dict merge command} -body {
+ dict merge {a b c d e} {e f g h}
+} -result {missing value to go with key} -returnCodes error
+test dict-20.6 {dict merge command} -body {
+ dict merge {a b c d} {e f g h i}
+} -result {missing value to go with key} -returnCodes error
+test dict-20.7 {dict merge command} {
+ dict merge {a b c d e f} {e x g h}
+} {a b c d e x g h}
+test dict-20.8 {dict merge command} {
+ dict merge {a b c d} {a x c y}
+} {a x c y}
+test dict-20.9 {dict merge command} {
+ dict merge {a b c d} {c y a x}
+} {a x c y}
+test dict-20.10 {dict merge command} {
+ dict merge {a b c d e f} {a x 1 2 3 4} {a - 1 -}
+} {a - c d e f 1 - 3 4}
+
+test dict-21.1 {dict update command} -returnCodes 1 -body {
+ dict update
+} -result {wrong # args: should be "dict update varName key varName ?key varName ...? script"}
+test dict-21.2 {dict update command} -returnCodes 1 -body {
+ dict update v
+} -result {wrong # args: should be "dict update varName key varName ?key varName ...? script"}
+test dict-21.3 {dict update command} -returnCodes 1 -body {
+ dict update v k
+} -result {wrong # args: should be "dict update varName key varName ?key varName ...? script"}
+test dict-21.4 {dict update command} -returnCodes 1 -body {
+ dict update v k v
+} -result {wrong # args: should be "dict update varName key varName ?key varName ...? script"}
+test dict-21.5 {dict update command} -body {
+ set a {b c}
+ set result {}
+ set bb {}
+ dict update a b bb {
+ lappend result $a $bb
+ }
+ lappend result $a
+} -cleanup {
+ unset a result bb
+} -result {{b c} c {b c}}
+test dict-21.6 {dict update command} -body {
+ set a {b c}
+ set result {}
+ set bb {}
+ dict update a b bb {
+ lappend result $a $bb [set bb d]
+ }
+ lappend result $a
+} -cleanup {
+ unset a result bb
+} -result {{b c} c d {b d}}
+test dict-21.7 {dict update command} -body {
+ set a {b c}
+ set result {}
+ set bb {}
+ dict update a b bb {
+ lappend result $a $bb [unset bb]
+ }
+ lappend result $a
+} -cleanup {
+ unset a result
+} -result {{b c} c {} {}}
+test dict-21.8 {dict update command} -body {
+ set a {b c d e}
+ dict update a b v1 d v2 {
+ lassign "$v1 $v2" v2 v1
+ }
+ return $a
+} -cleanup {
+ unset a v1 v2
+} -result {b e d c}
+test dict-21.9 {dict update command} -body {
+ set a {b c d e}
+ dict update a b v1 d v2 {unset a}
+ info exist a
+} -cleanup {
+ unset v1 v2
+} -result 0
+test dict-21.10 {dict update command} -body {
+ set a {b {c d}}
+ dict update a b v1 {
+ dict update v1 c v2 {
+ set v2 foo
+ }
+ }
+ return $a
+} -cleanup {
+ unset a v1 v2
+} -result {b {c foo}}
+test dict-21.11 {dict update command} -body {
+ set a {b c d e}
+ dict update a b v1 d v2 {
+ dict set a f g
+ }
+ return $a
+} -cleanup {
+ unset a v1 v2
+} -result {b c d e f g}
+test dict-21.12 {dict update command} -body {
+ set a {b c d e}
+ dict update a b v1 d v2 f v3 {
+ set v3 g
+ }
+ return $a
+} -cleanup {
+ unset a v1 v2 v3
+} -result {b c d e f g}
+test dict-21.13 {dict update command: compilation} {
+ apply {d {
+ while 1 {
+ dict update d a alpha b beta {
+ set beta $alpha
+ unset alpha
+ break
+ }
+ }
+ return $d
+ }} {a 1 c 2}
+} {c 2 b 1}
+test dict-21.14 {dict update command: compilation} {
+ apply {x {
+ set indices {2 3}
+ trace add variable aa write "string length \$indices ;#"
+ dict update x k aa l bb {}
+ }} {k 1 l 2}
+} {}
+test dict-21.15 {dict update command: compilation} {
+ apply {x {
+ set indices {2 3}
+ trace add variable aa read "string length \$indices ;#"
+ dict update x k aa l bb {}
+ }} {k 1 l 2}
+} {}
+test dict-21.16 {dict update command: no recursive structures [Bug 1786481]} -body {
+ set foo {a {b {c {d {e 1}}}}}
+ dict update foo a t {
+ dict update t b t {
+ dict update t c t {
+ dict update t d t {
+ dict incr t e
+ }
+ }
+ }
+ }
+ string range [append foo OK] end-1 end
+} -cleanup {
+ unset foo t
+} -result OK
+test dict-21.17 {dict update command: no recursive structures [Bug 1786481]} {
+ apply {{} {
+ set foo {a {b {c {d {e 1}}}}}
+ dict update foo a t {
+ dict update t b t {
+ dict update t c t {
+ dict update t d t {
+ dict incr t e
+ }
+ }
+ }
+ }
+ string range [append foo OK] end-1 end
+ }}
+} OK
+
+test dict-22.1 {dict with command} -body {
+ dict with
+} -returnCodes 1 -result {wrong # args: should be "dict with dictVar ?key ...? script"}
+test dict-22.2 {dict with command} -body {
+ dict with v
+} -returnCodes 1 -result {wrong # args: should be "dict with dictVar ?key ...? script"}
+test dict-22.3 {dict with command} -body {
+ unset -nocomplain v
+ dict with v {error "in body"}
+} -returnCodes 1 -result {can't read "v": no such variable}
+test dict-22.4 {dict with command} -body {
+ set a {b c d e}
+ unset -nocomplain b d
+ set result [list [info exist b] [info exist d]]
+ dict with a {
+ lappend result [info exist b] [info exist d] $b $d
+ }
+ return $result
+} -cleanup {
+ unset a b d result
+} -result {0 0 1 1 c e}
+test dict-22.5 {dict with command} -body {
+ set a {b c d e}
+ dict with a {
+ lassign "$b $d" d b
+ }
+ return $a
+} -cleanup {
+ unset a b d
+} -result {b e d c}
+test dict-22.6 {dict with command} -body {
+ set a {b c d e}
+ dict with a {
+ unset b
+ # This *won't* go into the dict...
+ set f g
+ }
+ return $a
+} -cleanup {
+ unset a d f
+} -result {d e}
+test dict-22.7 {dict with command} -body {
+ set a {b c d e}
+ dict with a {
+ dict unset a b
+ }
+ return $a
+} -cleanup {
+ unset a
+} -result {d e b c}
+test dict-22.8 {dict with command} -body {
+ set a [dict create b c]
+ dict with a {
+ set b $a
+ }
+ return $a
+} -cleanup {
+ unset a b
+} -result {b {b c}}
+test dict-22.9 {dict with command} -body {
+ set a {b {c d}}
+ dict with a b {
+ set c $c$c
+ }
+ return $a
+} -cleanup {
+ unset a c
+} -result {b {c dd}}
+test dict-22.10 {dict with command: result handling tricky case} -body {
+ set a {b {c d}}
+ foreach i {0 1} {
+ if {$i} break
+ dict with a b {
+ set a {}
+ # We're checking to see if we lose this break
+ break
+ }
+ }
+ list $i $a
+} -cleanup {
+ unset a i c
+} -result {0 {}}
+test dict-22.11 {dict with command: no recursive structures [Bug 1786481]} -body {
+ set foo {t {t {t {inner 1}}}}
+ dict with foo {
+ dict with t {
+ dict with t {
+ dict with t {
+ incr inner
+ }
+ }
+ }
+ }
+ string range [append foo OK] end-1 end
+} -cleanup {
+ unset foo t inner
+} -result OK
+test dict-22.12 {dict with: compiled} {
+ apply {{} {
+ set d {a 1 b 2}
+ list [dict with d {
+ set a $b
+ unset b
+ dict set d c 3
+ list ok
+ }] $d
+ }}
+} {ok {a 2 c 3}}
+test dict-22.13 {dict with: compiled} {
+ apply {i {
+ set d($i) {a 1 b 2}
+ list [dict with d($i) {
+ set a $b
+ unset b
+ dict set d($i) c 3
+ list ok
+ }] [array get d]
+ }} e
+} {ok {e {a 2 c 3}}}
+test dict-22.14 {dict with: compiled} {
+ apply {{} {
+ set d {a 1 b 2}
+ foreach x {1 2 3} {
+ dict with d {
+ incr a $b
+ if {$x == 2} break
+ }
+ unset a b
+ }
+ list $a $b $x $d
+ }}
+} {5 2 2 {a 5 b 2}}
+test dict-22.15 {dict with: compiled} {
+ apply {i {
+ set d($i) {a 1 b 2}
+ foreach x {1 2 3} {
+ dict with d($i) {
+ incr a $b
+ if {$x == 2} break
+ }
+ unset a b
+ }
+ list $a $b $x [array get d]
+ }} e
+} {5 2 2 {e {a 5 b 2}}}
+test dict-22.16 {dict with: compiled} {
+ apply {{} {
+ set d {p {q {a 1 b 2}}}
+ dict with d p q {
+ set a $b.$a
+ }
+ return $d
+ }}
+} {p {q {a 2.1 b 2}}}
+test dict-22.17 {dict with: compiled} {
+ apply {i {
+ set d($i) {p {q {a 1 b 2}}}
+ dict with d($i) p q {
+ set a $b.$a
+ }
+ array get d
+ }} e
+} {e {p {q {a 2.1 b 2}}}}
+test dict-22.18 {dict with: compiled} {
+ set ::d {a 1 b 2}
+ apply {{} {
+ dict with ::d {
+ set a $b.$a
+ }
+ return $::d
+ }}
+} {a 2.1 b 2}
+test dict-22.19 {dict with: compiled} {
+ set ::d {p {q {r {a 1 b 2}}}}
+ apply {{} {
+ dict with ::d p q r {
+ set a $b.$a
+ }
+ return $::d
+ }}
+} {p {q {r {a 2.1 b 2}}}}
+test dict-22.20 {dict with: compiled} {
+ apply {d {
+ dict with d {
+ }
+ return $a,$b
+ }} {a 1 b 2}
+} 1,2
+test dict-22.21 {dict with: compiled} {
+ apply {d {
+ dict with d p q {
+ }
+ return $a,$b
+ }} {p {q {a 1 b 2}}}
+} 1,2
+test dict-22.22 {dict with: compiled} {
+ set ::d {a 1 b 2}
+ apply {{} {
+ dict with ::d {
+ }
+ return $a,$b
+ }}
+} 1,2
+test dict-22.23 {dict with: compiled} {
+ set ::d {p {q {a 1 b 2}}}
+ apply {{} {
+ dict with ::d p q {
+ }
+ return $a,$b
+ }}
+} 1,2
+
+proc linenumber {} {
+ dict get [info frame -1] line
+}
+test dict-23.1 {dict compilation crash: Bug 3487626} {
+ apply {{} {apply {n {
+ set e {}
+ set k {}
+ dict for {a b} {c {d {e {f g}}}} {
+ ::tcl::dict::for {h i} $b {
+ dict update i e j {
+ ::tcl::dict::update j f k {
+ return [expr {$n - [linenumber]}]
+ }
+ }
+ }
+ }
+ }} [linenumber]}}
+} 5
+test dict-23.2 {dict compilation crash: Bug 3487626} knownBug {
+ # Something isn't quite right in line number and continuation line
+ # tracking; at time of writing, this test produces 7, not 5, which
+ # indicates that the extra newlines in the non-script argument are
+ # confusing things.
+ apply {{} {apply {n {
+ set e {}
+ set k {}
+ dict for {a {
+b
+}} {c {d {e {f g}}}} {
+ ::tcl::dict::for {h {
+i
+}} ${
+b
+} {
+ dict update {
+i
+} e {
+j
+} {
+ ::tcl::dict::update {
+j
+} f k {
+ return [expr {$n - [linenumber]}]
+ }
+ }
+ }
+ }
+ }} [linenumber]}}
+} 5
+rename linenumber {}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/dstring.test b/pkgs/msgcat/tests/dstring.test
new file mode 100644
index 0000000..bcc304d
--- /dev/null
+++ b/pkgs/msgcat/tests/dstring.test
@@ -0,0 +1,436 @@
+# Commands covered: none
+#
+# This file contains a collection of tests for Tcl's dynamic string library
+# procedures. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testdstring [llength [info commands testdstring]]
+if {[testConstraint testdstring]} {
+ testdstring free
+}
+
+test dstring-1.1 {appending and retrieving} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append "abc" -1
+ list [testdstring get] [testdstring length]
+} -cleanup {
+ testdstring free
+} -result {abc 3}
+test dstring-1.2 {appending and retrieving} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append "abc" -1
+ testdstring append " xyzzy" 3
+ testdstring append " 12345" -1
+ list [testdstring get] [testdstring length]
+} -cleanup {
+ testdstring free
+} -result {{abc xy 12345} 12}
+test dstring-1.3 {appending and retrieving} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ foreach l {a b c d e f g h i j k l m n o p} {
+ testdstring append $l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l\n -1
+ }
+ list [testdstring get] [testdstring length]
+} -cleanup {
+ testdstring free
+} -result {{aaaaaaaaaaaaaaaaaaaaa
+bbbbbbbbbbbbbbbbbbbbb
+ccccccccccccccccccccc
+ddddddddddddddddddddd
+eeeeeeeeeeeeeeeeeeeee
+fffffffffffffffffffff
+ggggggggggggggggggggg
+hhhhhhhhhhhhhhhhhhhhh
+iiiiiiiiiiiiiiiiiiiii
+jjjjjjjjjjjjjjjjjjjjj
+kkkkkkkkkkkkkkkkkkkkk
+lllllllllllllllllllll
+mmmmmmmmmmmmmmmmmmmmm
+nnnnnnnnnnnnnnnnnnnnn
+ooooooooooooooooooooo
+ppppppppppppppppppppp
+} 352}
+
+test dstring-2.1 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring element "abc"
+ testdstring element "d e f"
+ list [testdstring get] [testdstring length]
+} -cleanup {
+ testdstring free
+} -result {{abc {d e f}} 11}
+test dstring-2.2 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring element "x"
+ testdstring element "\{"
+ testdstring element "ab\}"
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {x \{ ab\}}
+test dstring-2.3 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ foreach l {a b c d e f g h i j k l m n o p} {
+ testdstring element $l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l
+ }
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {aaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbb ccccccccccccccccccccc ddddddddddddddddddddd eeeeeeeeeeeeeeeeeeeee fffffffffffffffffffff ggggggggggggggggggggg hhhhhhhhhhhhhhhhhhhhh iiiiiiiiiiiiiiiiiiiii jjjjjjjjjjjjjjjjjjjjj kkkkkkkkkkkkkkkkkkkkk lllllllllllllllllllll mmmmmmmmmmmmmmmmmmmmm nnnnnnnnnnnnnnnnnnnnn ooooooooooooooooooooo ppppppppppppppppppppp}
+test dstring-2.4 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append "a\{" -1
+ testdstring element abc
+ testdstring append " \{" -1
+ testdstring element xyzzy
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result "a{ abc {xyzzy"
+test dstring-2.5 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append " \{" -1
+ testdstring element abc
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result " {abc"
+test dstring-2.6 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append " " -1
+ testdstring element abc
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result { abc}
+test dstring-2.7 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append "\\ " -1
+ testdstring element abc
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result "\\ abc"
+test dstring-2.8 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append "x " -1
+ testdstring element abc
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {x abc}
+test dstring-2.9 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring element #
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {{#}}
+test dstring-2.10 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append " " -1
+ testdstring element #
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result { {#}}
+test dstring-2.11 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append \t -1
+ testdstring element #
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result \t{#}
+test dstring-2.12 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append x -1
+ testdstring element #
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {x #}
+test dstring-2.13 {appending list elements} -constraints testdstring -body {
+ # This test shows lack of sophistication in Tcl_DStringAppendElement's
+ # decision about whether #-quoting can be disabled.
+ testdstring free
+ testdstring append "x " -1
+ testdstring element #
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {x {#}}
+
+test dstring-3.1 {nested sublists} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring start
+ testdstring element foo
+ testdstring element bar
+ testdstring end
+ testdstring element another
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {{foo bar} another}
+test dstring-3.2 {nested sublists} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring start
+ testdstring start
+ testdstring element abc
+ testdstring element def
+ testdstring end
+ testdstring end
+ testdstring element ghi
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {{{abc def}} ghi}
+test dstring-3.3 {nested sublists} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring start
+ testdstring start
+ testdstring start
+ testdstring element foo
+ testdstring element foo2
+ testdstring end
+ testdstring end
+ testdstring element foo3
+ testdstring end
+ testdstring element foo4
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {{{{foo foo2}} foo3} foo4}
+test dstring-3.4 {nested sublists} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring element before
+ testdstring start
+ testdstring element during
+ testdstring element more
+ testdstring end
+ testdstring element last
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {before {during more} last}
+test dstring-3.5 {nested sublists} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring element "\{"
+ testdstring start
+ testdstring element first
+ testdstring element second
+ testdstring end
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {\{ {first second}}
+test dstring-3.6 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append x -1
+ testdstring start
+ testdstring element #
+ testdstring end
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {x {{#}}}
+test dstring-3.7 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append x -1
+ testdstring start
+ testdstring append " " -1
+ testdstring element #
+ testdstring end
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {x { {#}}}
+test dstring-3.8 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append x -1
+ testdstring start
+ testdstring append \t -1
+ testdstring element #
+ testdstring end
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result "x {\t{#}}"
+test dstring-3.9 {appending list elements} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append x -1
+ testdstring start
+ testdstring append x -1
+ testdstring element #
+ testdstring end
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {x {x #}}
+test dstring-3.10 {appending list elements} -constraints testdstring -body {
+ # This test shows lack of sophistication in Tcl_DStringAppendElement's
+ # decision about whether #-quoting can be disabled.
+ testdstring free
+ testdstring append x -1
+ testdstring start
+ testdstring append "x " -1
+ testdstring element #
+ testdstring end
+ testdstring get
+} -cleanup {
+ testdstring free
+} -result {x {x {#}}}
+
+test dstring-4.1 {truncation} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append "abcdefg" -1
+ testdstring trunc 3
+ list [testdstring get] [testdstring length]
+} -cleanup {
+ testdstring free
+} -result {abc 3}
+test dstring-4.2 {truncation} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append "xyzzy" -1
+ testdstring trunc 0
+ list [testdstring get] [testdstring length]
+} -cleanup {
+ testdstring free
+} -result {{} 0}
+
+test dstring-5.1 {copying to result} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ testdstring append xyz -1
+ testdstring result
+} -cleanup {
+ testdstring free
+} -result xyz
+test dstring-5.2 {copying to result} -constraints testdstring -setup {
+ testdstring free
+ unset -nocomplain a
+} -body {
+ foreach l {a b c d e f g h i j k l m n o p} {
+ testdstring append $l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l\n -1
+ }
+ set a [testdstring result]
+ testdstring append abc -1
+ list $a [testdstring get]
+} -cleanup {
+ testdstring free
+} -result {{aaaaaaaaaaaaaaaaaaaaa
+bbbbbbbbbbbbbbbbbbbbb
+ccccccccccccccccccccc
+ddddddddddddddddddddd
+eeeeeeeeeeeeeeeeeeeee
+fffffffffffffffffffff
+ggggggggggggggggggggg
+hhhhhhhhhhhhhhhhhhhhh
+iiiiiiiiiiiiiiiiiiiii
+jjjjjjjjjjjjjjjjjjjjj
+kkkkkkkkkkkkkkkkkkkkk
+lllllllllllllllllllll
+mmmmmmmmmmmmmmmmmmmmm
+nnnnnnnnnnnnnnnnnnnnn
+ooooooooooooooooooooo
+ppppppppppppppppppppp
+} abc}
+
+test dstring-6.1 {Tcl_DStringGetResult} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ list [testdstring gresult staticsmall] [testdstring get]
+} -cleanup {
+ testdstring free
+} -result {{} short}
+test dstring-6.2 {Tcl_DStringGetResult} -constraints testdstring -setup {
+ testdstring free
+} -body {
+ foreach l {a b c d e f g h i j k l m n o p} {
+ testdstring append $l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l\n -1
+ }
+ list [testdstring gresult staticsmall] [testdstring get]
+} -cleanup {
+ testdstring free
+} -result {{} short}
+test dstring-6.3 {Tcl_DStringGetResult} -constraints testdstring -body {
+ set result {}
+ lappend result [testdstring gresult staticlarge]
+ testdstring append x 1
+ lappend result [testdstring get]
+} -cleanup {
+ testdstring free
+} -result {{} {first0 first1 first2 first3 first4 first5 first6 first7 first8 first9
+second0 second1 second2 second3 second4 second5 second6 second7 second8 second9
+third0 third1 third2 third3 third4 third5 third6 third7 third8 third9
+fourth0 fourth1 fourth2 fourth3 fourth4 fourth5 fourth6 fourth7 fourth8 fourth9
+fifth0 fifth1 fifth2 fifth3 fifth4 fifth5 fifth6 fifth7 fifth8 fifth9
+sixth0 sixth1 sixth2 sixth3 sixth4 sixth5 sixth6 sixth7 sixth8 sixth9
+seventh0 seventh1 seventh2 seventh3 seventh4 seventh5 seventh6 seventh7 seventh8 seventh9
+x}}
+test dstring-6.4 {Tcl_DStringGetResult} -constraints testdstring -body {
+ set result {}
+ lappend result [testdstring gresult free]
+ testdstring append y 1
+ lappend result [testdstring get]
+} -cleanup {
+ testdstring free
+} -result {{} {This is a malloc-ed stringy}}
+test dstring-6.5 {Tcl_DStringGetResult} -constraints testdstring -body {
+ set result {}
+ lappend result [testdstring gresult special]
+ testdstring append z 1
+ lappend result [testdstring get]
+} -cleanup {
+ testdstring free
+} -result {{} {This is a specially-allocated stringz}}
+
+# cleanup
+if {[testConstraint testdstring]} {
+ testdstring free
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/encoding.test b/pkgs/msgcat/tests/encoding.test
new file mode 100644
index 0000000..51b7aa1
--- /dev/null
+++ b/pkgs/msgcat/tests/encoding.test
@@ -0,0 +1,597 @@
+# This file contains a collection of tests for tclEncoding.c
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+
+namespace eval ::tcl::test::encoding {
+ variable x
+
+namespace import -force ::tcltest::*
+
+proc toutf {args} {
+ variable x
+ lappend x "toutf $args"
+}
+proc fromutf {args} {
+ variable x
+ lappend x "fromutf $args"
+}
+
+proc runtests {} {
+ variable x
+
+# Some tests require the testencoding command
+testConstraint testencoding [llength [info commands testencoding]]
+testConstraint exec [llength [info commands exec]]
+testConstraint testgetdefenc [llength [info commands testgetdefenc]]
+testConstraint testfinexit [llength [info commands testfinexit]]
+
+# TclInitEncodingSubsystem is tested by the rest of this file
+# TclFinalizeEncodingSubsystem is not currently tested
+
+test encoding-1.1 {Tcl_GetEncoding: system encoding} -setup {
+ set old [encoding system]
+} -constraints {testencoding} -body {
+ testencoding create foo [namespace origin toutf] [namespace origin fromutf]
+ encoding system foo
+ set x {}
+ encoding convertto abcd
+ return $x
+} -cleanup {
+ encoding system $old
+ testencoding delete foo
+} -result {{fromutf }}
+test encoding-1.2 {Tcl_GetEncoding: existing encoding} {testencoding} {
+ testencoding create foo [namespace origin toutf] [namespace origin fromutf]
+ set x {}
+ encoding convertto foo abcd
+ testencoding delete foo
+ return $x
+} {{fromutf }}
+test encoding-1.3 {Tcl_GetEncoding: load encoding} {
+ list [encoding convertto jis0208 \u4e4e] \
+ [encoding convertfrom jis0208 8C]
+} "8C \u4e4e"
+
+test encoding-2.1 {Tcl_FreeEncoding: refcount == 0} {
+ encoding convertto jis0208 \u4e4e
+} {8C}
+test encoding-2.2 {Tcl_FreeEncoding: refcount != 0} -setup {
+ set system [encoding system]
+ set path [encoding dirs]
+} -constraints {testencoding} -body {
+ encoding system shiftjis ;# incr ref count
+ encoding dirs [list [pwd]]
+ set x [encoding convertto shiftjis \u4e4e] ;# old one found
+ encoding system identity
+ llength shiftjis ;# Shimmer away any cache of Tcl_Encoding
+ lappend x [catch {encoding convertto shiftjis \u4e4e} msg] $msg
+} -cleanup {
+ encoding system identity
+ encoding dirs $path
+ encoding system $system
+} -result "\u008c\u00c1 1 {unknown encoding \"shiftjis\"}"
+
+test encoding-3.1 {Tcl_GetEncodingName, NULL} -setup {
+ set old [encoding system]
+} -body {
+ encoding system shiftjis
+ encoding system
+} -cleanup {
+ encoding system $old
+} -result {shiftjis}
+test encoding-3.2 {Tcl_GetEncodingName, non-null} -setup {
+ set old [fconfigure stdout -encoding]
+} -body {
+ fconfigure stdout -encoding jis0208
+ fconfigure stdout -encoding
+} -cleanup {
+ fconfigure stdout -encoding $old
+} -result {jis0208}
+
+test encoding-4.1 {Tcl_GetEncodingNames} -constraints {testencoding} -setup {
+ cd [makeDirectory tmp]
+ makeDirectory [file join tmp encoding]
+ set path [encoding dirs]
+ encoding dirs {}
+ catch {unset encodings}
+ catch {unset x}
+} -body {
+ foreach encoding [encoding names] {
+ set encodings($encoding) 1
+ }
+ makeFile {} [file join tmp encoding junk.enc]
+ makeFile {} [file join tmp encoding junk2.enc]
+ encoding dirs [list [file join [pwd] encoding]]
+ foreach encoding [encoding names] {
+ if {![info exists encodings($encoding)]} {
+ lappend x $encoding
+ }
+ }
+ lsort $x
+} -cleanup {
+ encoding dirs $path
+ cd [workingDirectory]
+ removeFile [file join tmp encoding junk2.enc]
+ removeFile [file join tmp encoding junk.enc]
+ removeDirectory [file join tmp encoding]
+ removeDirectory tmp
+} -result {junk junk2}
+
+test encoding-5.1 {Tcl_SetSystemEncoding} -setup {
+ set old [encoding system]
+} -body {
+ encoding system jis0208
+ encoding convertto \u4e4e
+} -cleanup {
+ encoding system identity
+ encoding system $old
+} -result {8C}
+test encoding-5.2 {Tcl_SetSystemEncoding: test ref count} {
+ set old [encoding system]
+ encoding system $old
+ string compare $old [encoding system]
+} {0}
+
+test encoding-6.1 {Tcl_CreateEncoding: new} {testencoding} {
+ testencoding create foo [namespace code {toutf 1}] \
+ [namespace code {fromutf 2}]
+ set x {}
+ encoding convertfrom foo abcd
+ encoding convertto foo abcd
+ testencoding delete foo
+ return $x
+} {{toutf 1} {fromutf 2}}
+test encoding-6.2 {Tcl_CreateEncoding: replace encoding} {testencoding} {
+ testencoding create foo [namespace code {toutf a}] \
+ [namespace code {fromutf b}]
+ set x {}
+ encoding convertfrom foo abcd
+ encoding convertto foo abcd
+ testencoding delete foo
+ return $x
+} {{toutf a} {fromutf b}}
+
+test encoding-7.1 {Tcl_ExternalToUtfDString: small buffer} {
+ encoding convertfrom jis0208 8c8c8c8c
+} "\u543e\u543e\u543e\u543e"
+test encoding-7.2 {Tcl_UtfToExternalDString: big buffer} {
+ set a 8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C
+ append a $a
+ append a $a
+ append a $a
+ append a $a
+ set x [encoding convertfrom jis0208 $a]
+ list [string length $x] [string index $x 0]
+} "512 \u4e4e"
+
+test encoding-8.1 {Tcl_ExternalToUtf} {
+ set f [open [file join [temporaryDirectory] dummy] w]
+ fconfigure $f -translation binary -encoding iso8859-1
+ puts -nonewline $f "ab\x8c\xc1g"
+ close $f
+ set f [open [file join [temporaryDirectory] dummy] r]
+ fconfigure $f -translation binary -encoding shiftjis
+ set x [read $f]
+ close $f
+ file delete [file join [temporaryDirectory] dummy]
+ return $x
+} "ab\u4e4eg"
+
+test encoding-9.1 {Tcl_UtfToExternalDString: small buffer} {
+ encoding convertto jis0208 "\u543e\u543e\u543e\u543e"
+} {8c8c8c8c}
+test encoding-9.2 {Tcl_UtfToExternalDString: big buffer} {
+ set a \u4e4e\u4e4e\u4e4e\u4e4e\u4e4e\u4e4e\u4e4e\u4e4e
+ append a $a
+ append a $a
+ append a $a
+ append a $a
+ append a $a
+ append a $a
+ set x [encoding convertto jis0208 $a]
+ list [string length $x] [string range $x 0 1]
+} "1024 8C"
+
+test encoding-10.1 {Tcl_UtfToExternal} {
+ set f [open [file join [temporaryDirectory] dummy] w]
+ fconfigure $f -translation binary -encoding shiftjis
+ puts -nonewline $f "ab\u4e4eg"
+ close $f
+ set f [open [file join [temporaryDirectory] dummy] r]
+ fconfigure $f -translation binary -encoding iso8859-1
+ set x [read $f]
+ close $f
+ file delete [file join [temporaryDirectory] dummy]
+ return $x
+} "ab\x8c\xc1g"
+
+proc viewable {str} {
+ set res ""
+ foreach c [split $str {}] {
+ if {[string is print $c] && [string is ascii $c]} {
+ append res $c
+ } else {
+ append res "\\u[format %4.4x [scan $c %c]]"
+ }
+ }
+ return "$str ($res)"
+}
+
+test encoding-11.1 {LoadEncodingFile: unknown encoding} {testencoding} {
+ set system [encoding system]
+ set path [encoding dirs]
+ encoding system iso8859-1
+ encoding dirs {}
+ llength jis0208 ;# Shimmer any cached Tcl_Encoding in shared literal
+ set x [list [catch {encoding convertto jis0208 \u4e4e} msg] $msg]
+ encoding dirs $path
+ encoding system $system
+ lappend x [encoding convertto jis0208 \u4e4e]
+} {1 {unknown encoding "jis0208"} 8C}
+test encoding-11.2 {LoadEncodingFile: single-byte} {
+ encoding convertfrom jis0201 \xa1
+} "\uff61"
+test encoding-11.3 {LoadEncodingFile: double-byte} {
+ encoding convertfrom jis0208 8C
+} "\u4e4e"
+test encoding-11.4 {LoadEncodingFile: multi-byte} {
+ encoding convertfrom shiftjis \x8c\xc1
+} "\u4e4e"
+test encoding-11.5 {LoadEncodingFile: escape file} {
+ viewable [encoding convertto iso2022 \u4e4e]
+} [viewable "\x1b\$B8C\x1b(B"]
+test encoding-11.5.1 {LoadEncodingFile: escape file} {
+ viewable [encoding convertto iso2022-jp \u4e4e]
+} [viewable "\x1b\$B8C\x1b(B"]
+test encoding-11.6 {LoadEncodingFile: invalid file} -constraints {testencoding} -setup {
+ set system [encoding system]
+ set path [encoding dirs]
+ encoding system identity
+} -body {
+ cd [temporaryDirectory]
+ encoding dirs [file join tmp encoding]
+ makeDirectory tmp
+ makeDirectory [file join tmp encoding]
+ set f [open [file join tmp encoding splat.enc] w]
+ fconfigure $f -translation binary
+ puts $f "abcdefghijklmnop"
+ close $f
+ encoding convertto splat \u4e4e
+} -returnCodes error -cleanup {
+ file delete [file join [temporaryDirectory] tmp encoding splat.enc]
+ removeDirectory [file join tmp encoding]
+ removeDirectory tmp
+ cd [workingDirectory]
+ encoding dirs $path
+ encoding system $system
+} -result {invalid encoding file "splat"}
+
+# OpenEncodingFile is fully tested by the rest of the tests in this file.
+
+test encoding-12.1 {LoadTableEncoding: normal encoding} {
+ set x [encoding convertto iso8859-3 \u120]
+ append x [encoding convertto iso8859-3 \ud5]
+ append x [encoding convertfrom iso8859-3 \xd5]
+} "\xd5?\u120"
+test encoding-12.2 {LoadTableEncoding: single-byte encoding} {
+ set x [encoding convertto iso8859-3 ab\u0120g]
+ append x [encoding convertfrom iso8859-3 ab\xd5g]
+} "ab\xd5gab\u120g"
+test encoding-12.3 {LoadTableEncoding: multi-byte encoding} {
+ set x [encoding convertto shiftjis ab\u4e4eg]
+ append x [encoding convertfrom shiftjis ab\x8c\xc1g]
+} "ab\x8c\xc1gab\u4e4eg"
+test encoding-12.4 {LoadTableEncoding: double-byte encoding} {
+ set x [encoding convertto jis0208 \u4e4e\u3b1]
+ append x [encoding convertfrom jis0208 8C&A]
+} "8C&A\u4e4e\u3b1"
+test encoding-12.5 {LoadTableEncoding: symbol encoding} {
+ set x [encoding convertto symbol \u3b3]
+ append x [encoding convertto symbol \u67]
+ append x [encoding convertfrom symbol \x67]
+} "\x67\x67\u3b3"
+
+test encoding-13.1 {LoadEscapeTable} {
+ viewable [set x [encoding convertto iso2022 ab\u4e4e\u68d9g]]
+} [viewable "ab\x1b\$B8C\x1b\$\(DD%\x1b(Bg"]
+
+test encoding-14.1 {BinaryProc} {
+ encoding convertto identity \x12\x34\x56\xff\x69
+} "\x12\x34\x56\xc3\xbf\x69"
+
+test encoding-15.1 {UtfToUtfProc} {
+ encoding convertto utf-8 \xa3
+} "\xc2\xa3"
+test encoding-15.2 {UtfToUtfProc null character output} {
+ set x \u0000
+ set y [encoding convertto utf-8 \u0000]
+ set y [encoding convertfrom identity $y]
+ binary scan $y H* z
+ list [string bytelength $x] [string bytelength $y] $z
+} {2 1 00}
+test encoding-15.3 {UtfToUtfProc null character input} {
+ set x [encoding convertfrom identity \x00]
+ set y [encoding convertfrom utf-8 $x]
+ binary scan [encoding convertto identity $y] H* z
+ list [string bytelength $x] [string bytelength $y] $z
+} {1 2 c080}
+
+test encoding-16.1 {UnicodeToUtfProc} {
+ set val [encoding convertfrom unicode NN]
+ list $val [format %x [scan $val %c]]
+} "\u4e4e 4e4e"
+
+test encoding-17.1 {UtfToUnicodeProc} {
+} {}
+
+test encoding-18.1 {TableToUtfProc} {
+} {}
+
+test encoding-19.1 {TableFromUtfProc} {
+} {}
+
+test encoding-20.1 {TableFreefProc} {
+} {}
+
+test encoding-21.1 {EscapeToUtfProc} {
+} {}
+
+test encoding-22.1 {EscapeFromUtfProc} {
+} {}
+
+set iso2022encData "\u001b\$B;d\$I\$b\$G\$O!\"%A%C%W\$49XF~;~\$K\$4EPO?\$\$\$?\$@\$\$\$?\$4=;=j\$r%-%c%C%7%e%\"%&%H\$N:]\$N\u001b(B
+\u001b\$B>.@Z<jAwIU@h\$H\$7\$F;HMQ\$7\$F\$*\$j\$^\$9!#62\$lF~\$j\$^\$9\$,!\"@5\$7\$\$=;=j\$r\$4EPO?\$7\$J\$*\u001b(B
+\u001b\$B\$*4j\$\$\$\$\$?\$7\$^\$9!#\$^\$?!\"BgJQ62=L\$G\$9\$,!\"=;=jJQ99\$N\$\"\$H!\"F|K\\8l%5!<%S%9It!J\u001b(B
+casino_japanese@___.com \u001b\$B!K\$^\$G\$4=;=jJQ99:Q\$NO\"Mm\$r\$\$\$?\$@\$1\$J\$\$\$G\u001b(B
+\u001b\$B\$7\$g\$&\$+!)\u001b(B"
+
+set iso2022uniData [encoding convertfrom iso2022-jp $iso2022encData]
+set iso2022uniData2 "\u79c1\u3069\u3082\u3067\u306f\u3001\u30c1\u30c3\u30d7\u3054\u8cfc\u5165\u6642\u306b\u3054\u767b\u9332\u3044\u305f\u3060\u3044\u305f\u3054\u4f4f\u6240\u3092\u30ad\u30e3\u30c3\u30b7\u30e5\u30a2\u30a6\u30c8\u306e\u969b\u306e
+\u5c0f\u5207\u624b\u9001\u4ed8\u5148\u3068\u3057\u3066\u4f7f\u7528\u3057\u3066\u304a\u308a\u307e\u3059\u3002\u6050\u308c\u5165\u308a\u307e\u3059\u304c\u3001\u6b63\u3057\u3044\u4f4f\u6240\u3092\u3054\u767b\u9332\u3057\u306a\u304a
+\u304a\u9858\u3044\u3044\u305f\u3057\u307e\u3059\u3002\u307e\u305f\u3001\u5927\u5909\u6050\u7e2e\u3067\u3059\u304c\u3001\u4f4f\u6240\u5909\u66f4\u306e\u3042\u3068\u3001\u65e5\u672c\u8a9e\u30b5\u30fc\u30d3\u30b9\u90e8\uff08
+\u0063\u0061\u0073\u0069\u006e\u006f\u005f\u006a\u0061\u0070\u0061\u006e\u0065\u0073\u0065\u0040\u005f\u005f\u005f\u002e\u0063\u006f\u006d\u0020\uff09\u307e\u3067\u3054\u4f4f\u6240\u5909\u66f4\u6e08\u306e\u9023\u7d61\u3092\u3044\u305f\u3060\u3051\u306a\u3044\u3067
+\u3057\u3087\u3046\u304b\uff1f"
+
+cd [temporaryDirectory]
+set fid [open iso2022.txt w]
+fconfigure $fid -encoding binary
+puts -nonewline $fid $iso2022encData
+close $fid
+
+test encoding-23.1 {iso2022-jp escape encoding test} {
+ string equal $iso2022uniData $iso2022uniData2
+} 1
+test encoding-23.2 {iso2022-jp escape encoding test} {
+ # This checks that 'gets' isn't resetting the encoding inappropriately.
+ # [Bug #523988]
+ set fid [open iso2022.txt r]
+ fconfigure $fid -encoding iso2022-jp
+ set out ""
+ set count 0
+ while {[set num [gets $fid line]] >= 0} {
+ if {$count} {
+ incr count 1 ; # account for newline
+ append out \n
+ }
+ append out $line
+ incr count $num
+ }
+ close $fid
+ if {[string compare $iso2022uniData $out]} {
+ return -code error "iso2022-jp read in doesn't match original"
+ }
+ list $count $out
+} [list [string length $iso2022uniData] $iso2022uniData]
+test encoding-23.3 {iso2022-jp escape encoding test} {
+ # read $fis <size> reads size in chars, not raw bytes.
+ set fid [open iso2022.txt r]
+ fconfigure $fid -encoding iso2022-jp
+ set data [read $fid 50]
+ close $fid
+ return $data
+} [string range $iso2022uniData 0 49] ; # 0 .. 49 inclusive == 50
+cd [workingDirectory]
+
+# Code to make the next few tests more intelligible; the code being tested
+# should be in the body of the test!
+proc runInSubprocess {contents {filename iso2022.tcl}} {
+ set theFile [makeFile $contents $filename]
+ try {
+ exec [interpreter] $theFile
+ } finally {
+ removeFile $theFile
+ }
+}
+
+test encoding-24.1 {EscapeFreeProc on open channels} exec {
+ runInSubprocess {
+ set f [open [file join [file dirname [info script]] iso2022.txt]]
+ fconfigure $f -encoding iso2022-jp
+ gets $f
+ }
+} {}
+test encoding-24.2 {EscapeFreeProc on open channels} {exec testfinexit} {
+ # Bug #524674 output
+ viewable [runInSubprocess {
+ encoding system cp1252; # Bug #2891556 crash revelator
+ fconfigure stdout -encoding iso2022-jp
+ puts ab\u4e4e\u68d9g
+ testfinexit
+ }]
+} "ab\x1b\$B8C\x1b\$(DD%\x1b(Bg (ab\\u001b\$B8C\\u001b\$(DD%\\u001b(Bg)"
+test encoding-24.3 {EscapeFreeProc on open channels} {stdio} {
+ # Bug #219314 - if we don't free escape encodings correctly on channel
+ # closure, we go boom
+ set file [makeFile {
+ encoding system iso2022-jp
+ set a "\u4e4e\u4e5e\u4e5f"; # 3 Japanese Kanji letters
+ puts $a
+ } iso2022.tcl]
+ set f [open "|[list [interpreter] $file]"]
+ fconfigure $f -encoding iso2022-jp
+ set count [gets $f line]
+ close $f
+ removeFile iso2022.tcl
+ list $count [viewable $line]
+} [list 3 "\u4e4e\u4e5e\u4e5f (\\u4e4e\\u4e5e\\u4e5f)"]
+
+file delete [file join [temporaryDirectory] iso2022.txt]
+
+#
+# Begin jajp encoding round-trip conformity tests
+#
+proc foreach-jisx0208 {varName command} {
+ upvar 1 $varName code
+ foreach range {
+ {2121 217E}
+ {2221 222E}
+ {223A 2241}
+ {224A 2250}
+ {225C 226A}
+ {2272 2279}
+ {227E 227E}
+ {2330 2339}
+ {2421 2473}
+ {2521 2576}
+ {2821 2821}
+ {282C 282C}
+ {2837 2837}
+
+ {30 21 4E 7E}
+ {4F21 4F53}
+
+ {50 21 73 7E}
+ {7421 7426}
+ } {
+ if {[llength $range] == 2} {
+ # for adhoc range. simple {first last}. inclusive.
+ scan $range %x%x first last
+ for {set i $first} {$i <= $last} {incr i} {
+ set code $i
+ uplevel 1 $command
+ }
+ } elseif {[llength $range] == 4} {
+ # for uniform range.
+ scan $range %x%x%x%x h0 l0 hend lend
+ for {set hi $h0} {$hi <= $hend} {incr hi} {
+ for {set lo $l0} {$lo <= $lend} {incr lo} {
+ set code [expr {$hi << 8 | ($lo & 0xff)}]
+ uplevel 1 $command
+ }
+ }
+ } else {
+ error "really?"
+ }
+ }
+}
+proc gen-jisx0208-euc-jp {code} {
+ binary format cc \
+ [expr {($code >> 8) | 0x80}] [expr {($code & 0xff) | 0x80}]
+}
+proc gen-jisx0208-iso2022-jp {code} {
+ binary format a3cca3 \
+ "\x1b\$B" [expr {$code >> 8}] [expr {$code & 0xff}] "\x1b(B"
+}
+proc gen-jisx0208-cp932 {code} {
+ set c1 [expr {($code >> 8) | 0x80}]
+ set c2 [expr {($code & 0xff)| 0x80}]
+ if {$c1 % 2} {
+ set c1 [expr {($c1 >> 1) + ($c1 < 0xdf ? 0x31 : 0x71)}]
+ incr c2 [expr {- (0x60 + ($c2 < 0xe0))}]
+ } else {
+ set c1 [expr {($c1 >> 1) + ($c1 < 0xdf ? 0x30 : 0x70)}]
+ incr c2 -2
+ }
+ binary format cc $c1 $c2
+}
+proc channel-diff {fa fb} {
+ set diff {}
+ while {[gets $fa la] >= 0 && [gets $fb lb] >= 0} {
+ if {[string compare $la $lb] == 0} continue
+ # lappend diff $la $lb
+
+ # For more readable (easy to analyze) output.
+ set code [lindex $la 0]
+ binary scan [lindex $la 1] H* expected
+ binary scan [lindex $lb 1] H* got
+ lappend diff [list $code $expected $got]
+ }
+ return $diff
+}
+
+# Create char tables.
+cd [temporaryDirectory]
+foreach enc {cp932 euc-jp iso2022-jp} {
+ set f [open $enc.chars w]
+ fconfigure $f -encoding binary
+ foreach-jisx0208 code {
+ puts $f [format "%04X %s" $code [gen-jisx0208-$enc $code]]
+ }
+ close $f
+}
+# shiftjis == cp932 for jisx0208.
+file copy -force cp932.chars shiftjis.chars
+
+set NUM 0
+foreach from {cp932 shiftjis euc-jp iso2022-jp} {
+ foreach to {cp932 shiftjis euc-jp iso2022-jp} {
+ test encoding-25.[incr NUM] "jisx0208 $from => $to" -setup {
+ cd [temporaryDirectory]
+ } -body {
+ set f [open $from.chars]
+ fconfigure $f -encoding $from
+ set out [open $from.$to.tcltestout w]
+ fconfigure $out -encoding $to
+ puts -nonewline $out [read $f]
+ close $out
+ close $f
+ # then compare $to.chars <=> $from.to.tcltestout as binary.
+ set fa [open $to.chars rb]
+ set fb [open $from.$to.tcltestout rb]
+ channel-diff $fa $fb
+ # Difference should be empty.
+ } -cleanup {
+ close $fa
+ close $fb
+ } -result {}
+ }
+}
+
+test encoding-26.0 {Tcl_GetDefaultEncodingDir} -constraints {
+ testgetdefenc
+} -setup {
+ set origDir [testgetdefenc]
+ testsetdefenc slappy
+} -body {
+ testgetdefenc
+} -cleanup {
+ testsetdefenc $origDir
+} -result slappy
+
+file delete {*}[glob -directory [temporaryDirectory] *.chars *.tcltestout]
+# ===> Cut here <===
+
+# EscapeFreeProc, GetTableEncoding, unilen are fully tested by the rest of
+# this file.
+
+}
+runtests
+
+}
+
+# cleanup
+namespace delete ::tcl::test::encoding
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/env.test b/pkgs/msgcat/tests/env.test
new file mode 100644
index 0000000..9010f52
--- /dev/null
+++ b/pkgs/msgcat/tests/env.test
@@ -0,0 +1,308 @@
+# Commands covered: none (tests environment variable implementation)
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Some tests require the "exec" command.
+# Skip them if exec is not defined.
+testConstraint exec [llength [info commands exec]]
+
+#
+# These tests will run on any platform (and indeed crashed on the Mac). So put
+# them before you test for the existance of exec.
+#
+test env-1.1 {propagation of env values to child interpreters} -setup {
+ catch {interp delete child}
+ catch {unset env(test)}
+} -body {
+ interp create child
+ set env(test) garbage
+ child eval {set env(test)}
+} -cleanup {
+ interp delete child
+ unset env(test)
+} -result {garbage}
+#
+# This one crashed on Solaris under Tcl8.0, so we only want to make sure it
+# runs.
+#
+test env-1.2 {lappend to env value} -setup {
+ catch {unset env(test)}
+} -body {
+ set env(test) aaaaaaaaaaaaaaaa
+ append env(test) bbbbbbbbbbbbbb
+ unset env(test)
+}
+test env-1.3 {reflection of env by "array names"} -setup {
+ catch {interp delete child}
+ catch {unset env(test)}
+} -body {
+ interp create child
+ child eval {set env(test) garbage}
+ expr {"test" in [array names env]}
+} -cleanup {
+ interp delete child
+ catch {unset env(test)}
+} -result {1}
+
+set printenvScript [makeFile {
+ encoding system iso8859-1
+ proc lrem {listname name} {
+ upvar $listname list
+ set i [lsearch -nocase $list $name]
+ if {$i >= 0} {
+ set list [lreplace $list $i $i]
+ }
+ return $list
+ }
+ proc mangle s {
+ regsub -all {\[|\\|\]} $s {\\&} s
+ regsub -all {[\u0000-\u001f\u007f-\uffff]} $s {[manglechar &]} s
+ return [subst -novariables $s]
+ }
+ proc manglechar c {
+ return [format {\u%04x} [scan $c %c]]
+ }
+
+ set names [lsort [array names env]]
+ if {$tcl_platform(platform) eq "windows"} {
+ lrem names HOME
+ lrem names COMSPEC
+ lrem names ComSpec
+ lrem names ""
+ }
+ foreach name {
+ TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH PURE_PROG_NAME DISPLAY
+ SHLIB_PATH SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH
+ DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING
+ __CF_USER_TEXT_ENCODING SECURITYSESSIONID LANG WINDIR TERM
+ CommonProgramFiles ProgramFiles
+ } {
+ lrem names $name
+ }
+ foreach p $names {
+ puts "[mangle $p]=[mangle $env($p)]"
+ }
+ exit
+} printenv]
+
+# [exec] is required here to see the actual environment received by child
+# processes.
+proc getenv {} {
+ global printenvScript tcltest
+ catch {exec [interpreter] $printenvScript} out
+ if {$out eq "child process exited abnormally"} {
+ set out {}
+ }
+ return $out
+}
+
+# Save the current environment variables at the start of the test.
+
+set env2 [array get env]
+foreach name [array names env] {
+ # Keep some environment variables that support operation of the tcltest
+ # package.
+ if {[string toupper $name] ni {
+ TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH DISPLAY SHLIB_PATH
+ SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH
+ DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING
+ SECURITYSESSIONID LANG WINDIR TERM
+ CommonProgramFiles ProgramFiles
+ }} {
+ unset env($name)
+ }
+}
+
+# Need to run 'getenv' in known encoding, so save the current one here...
+set sysenc [encoding system]
+
+test env-2.1 {adding environment variables} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ getenv
+} -cleanup {
+ encoding system $sysenc
+} -result {}
+test env-2.2 {adding environment variables} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ set env(NAME1) "test string"
+ getenv
+} -cleanup {
+ encoding system $sysenc
+} -result {NAME1=test string}
+test env-2.3 {adding environment variables} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ set env(NAME2) "more"
+ getenv
+} -cleanup {
+ encoding system $sysenc
+} -result {NAME1=test string
+NAME2=more}
+test env-2.4 {adding environment variables} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ set env(XYZZY) "garbage"
+ getenv
+} -cleanup {
+ encoding system $sysenc
+} -result {NAME1=test string
+NAME2=more
+XYZZY=garbage}
+
+set env(NAME2) "new value"
+test env-3.1 {changing environment variables} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ set result [getenv]
+ unset env(NAME2)
+ set result
+} -cleanup {
+ encoding system $sysenc
+} -result {NAME1=test string
+NAME2=new value
+XYZZY=garbage}
+
+test env-4.1 {unsetting environment variables: default} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ getenv
+} -cleanup {
+ encoding system $sysenc
+} -result {NAME1=test string
+XYZZY=garbage}
+test env-4.2 {unsetting environment variables} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ unset env(NAME1)
+ getenv
+} -cleanup {
+ unset env(XYZZY)
+ encoding system $sysenc
+} -result {XYZZY=garbage}
+test env-4.3 {setting international environment variables} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ set env(\ua7) \ub6
+ getenv
+} -cleanup {
+ encoding system $sysenc
+} -result {\u00a7=\u00b6}
+test env-4.4 {changing international environment variables} -setup {
+ encoding system iso8859-1
+} -constraints {exec} -body {
+ set env(\ua7) \ua7
+ getenv
+} -cleanup {
+ encoding system $sysenc
+} -result {\u00a7=\u00a7}
+test env-4.5 {unsetting international environment variables} -setup {
+ encoding system iso8859-1
+} -body {
+ set env(\ub6) \ua7
+ unset env(\ua7)
+ getenv
+} -constraints {exec} -cleanup {
+ encoding system $sysenc
+ unset env(\ub6)
+} -result {\u00b6=\u00a7}
+
+test env-5.0 {corner cases - set a value, it should exist} -body {
+ set env(temp) a
+ set env(temp)
+} -cleanup {
+ unset env(temp)
+} -result {a}
+test env-5.1 {corner cases - remove one elem at a time} -setup {
+ set x [array get env]
+} -body {
+ # When no environment variables exist, the env var will contain no
+ # entries. The "array names" call synchs up the C-level environ array with
+ # the Tcl level env array. Make sure an empty Tcl array is created.
+ foreach e [array names env] {
+ unset env($e)
+ }
+ array size env
+} -cleanup {
+ array set env $x
+} -result {0}
+test env-5.2 {corner cases - unset the env array} -setup {
+ interp create i
+} -body {
+ # Unsetting a variable in an interp detaches the C-level traces from the
+ # Tcl "env" variable.
+ i eval {
+ unset env
+ set env(THIS_SHOULDNT_EXIST) a
+ }
+ info exists env(THIS_SHOULDNT_EXIST)
+} -cleanup {
+ interp delete i
+} -result {0}
+test env-5.3 {corner cases: unset the env in master should unset child} -setup {
+ interp create i
+} -body {
+ # Variables deleted in a master interp should be deleted in child interp
+ # too.
+ i eval { set env(THIS_SHOULD_EXIST) a}
+ set result [set env(THIS_SHOULD_EXIST)]
+ unset env(THIS_SHOULD_EXIST)
+ lappend result [i eval {catch {set env(THIS_SHOULD_EXIST)}}]
+} -cleanup {
+ interp delete i
+} -result {a 1}
+test env-5.4 {corner cases - unset the env array} -setup {
+ interp create i
+} -body {
+ # The info exists command should be in synch with the env array.
+ # Know Bug: 1737
+ i eval { set env(THIS_SHOULD_EXIST) a}
+ set result [info exists env(THIS_SHOULD_EXIST)]
+ lappend result [set env(THIS_SHOULD_EXIST)]
+ lappend result [info exists env(THIS_SHOULD_EXIST)]
+} -cleanup {
+ interp delete i
+} -result {1 a 1}
+test env-5.5 {corner cases - cannot have null entries on Windows} {win} {
+ set env() a
+ catch {set env()}
+} {1}
+
+test env-6.1 {corner cases - add lots of env variables} {} {
+ set size [array size env]
+ for {set i 0} {$i < 100} {incr i} {
+ set env(BOGUS$i) $i
+ }
+ expr {[array size env] - $size}
+} 100
+
+# Restore the environment variables at the end of the test.
+
+foreach name [array names env] {
+ unset env($name)
+}
+array set env $env2
+
+# cleanup
+removeFile $printenvScript
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/error.test b/pkgs/msgcat/tests/error.test
new file mode 100644
index 0000000..97bcc0a
--- /dev/null
+++ b/pkgs/msgcat/tests/error.test
@@ -0,0 +1,1061 @@
+# Commands covered: error, catch, throw, try
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint memory [llength [info commands memory]]
+namespace eval ::tcl::test::error {
+if {[testConstraint memory]} {
+ proc getbytes {} {
+ set lines [split [memory info] \n]
+ return [lindex $lines 3 3]
+ }
+ proc leaktest {script {iterations 3}} {
+ set end [getbytes]
+ for {set i 0} {$i < $iterations} {incr i} {
+ uplevel 1 $script
+ set tmp $end
+ set end [getbytes]
+ }
+ return [expr {$end - $tmp}]
+ }
+}
+
+proc foo {} {
+ global errorInfo
+ set a [catch {format [error glorp2]} b]
+ error {Human-generated}
+}
+
+proc foo2 {} {
+ global errorInfo
+ set a [catch {format [error glorp2]} b]
+ error {Human-generated} $errorInfo
+}
+
+# Catch errors occurring in commands and errors from "error" command
+
+test error-1.1 {simple errors from commands} {
+ catch {format [string index]} b
+} 1
+test error-1.2 {simple errors from commands} {
+ catch {format [string index]} b
+ set b
+} {wrong # args: should be "string index string charIndex"}
+test error-1.3 {simple errors from commands} {
+ catch {format [string index]} b
+ set ::errorInfo
+ # This used to return '... while executing ...', but string index is fully
+ # compiled as of 8.4a3
+} {wrong # args: should be "string index string charIndex"
+ while executing
+"string index"}
+test error-1.4 {simple errors from commands} {
+ catch {error glorp} b
+} 1
+test error-1.5 {simple errors from commands} {
+ catch {error glorp} b
+ set b
+} glorp
+test error-1.6 {simple errors from commands} {
+ catch {catch a b c d} b
+} 1
+test error-1.7 {simple errors from commands} {
+ catch {catch a b c d} b
+ set b
+} {wrong # args: should be "catch script ?resultVarName? ?optionVarName?"}
+test error-1.8 {simple errors from commands} {
+ # This test is non-portable: it generates a memory fault on machines like
+ # DEC Alphas (infinite recursion overflows stack?)
+ #
+ # That claims sounds like a bug to be fixed rather than a portability
+ # problem. Anyhow, I believe it's out of date (bug's been fixed) so this
+ # test is re-enabled.
+ proc p {} {
+ uplevel 1 catch p error
+ }
+ p
+} 0
+
+# Check errors nested in procedures. Also check the optional argument to
+# "error" to generate a new error trace.
+
+test error-2.1 {errors in nested procedures} {
+ catch foo b
+} 1
+test error-2.2 {errors in nested procedures} {
+ catch foo b
+ set b
+} {Human-generated}
+test error-2.3 {errors in nested procedures} {
+ catch foo b
+ set ::errorInfo
+} {Human-generated
+ while executing
+"error {Human-generated}"
+ (procedure "foo" line 4)
+ invoked from within
+"foo"}
+test error-2.4 {errors in nested procedures} {
+ catch foo2 b
+} 1
+test error-2.5 {errors in nested procedures} {
+ catch foo2 b
+ set b
+} {Human-generated}
+test error-2.6 {errors in nested procedures} {
+ catch foo2 b
+ set ::errorInfo
+} {glorp2
+ while executing
+"error glorp2"
+ (procedure "foo2" line 3)
+ invoked from within
+"foo2"}
+
+# Error conditions related to "catch".
+
+test error-3.1 {errors in catch command} {
+ list [catch {catch} msg] $msg
+} {1 {wrong # args: should be "catch script ?resultVarName? ?optionVarName?"}}
+test error-3.2 {errors in catch command} {
+ list [catch {catch a b c} msg] $msg
+} {0 1}
+test error-3.3 {errors in catch command} {
+ catch {unset a}
+ set a(0) 22
+ list [catch {catch {format 44} a} msg] $msg
+} {1 {can't set "a": variable is array}}
+catch {unset a}
+
+# More tests related to errorInfo and errorCode
+
+test error-4.1 {errorInfo and errorCode variables} {
+ list [catch {error msg1 msg2 msg3} msg] $msg $::errorInfo $::errorCode
+} {1 msg1 msg2 msg3}
+test error-4.2 {errorInfo and errorCode variables} {
+ list [catch {error msg1 {} msg3} msg] $msg $::errorInfo $::errorCode
+} {1 msg1 {msg1
+ while executing
+"error msg1 {} msg3"} msg3}
+test error-4.3 {errorInfo and errorCode variables} {
+ list [catch {error msg1 {}} msg] $msg $::errorInfo $::errorCode
+} {1 msg1 {msg1
+ while executing
+"error msg1 {}"} NONE}
+test error-4.4 {errorInfo and errorCode variables} {
+ set ::errorCode bogus
+ list [catch {error msg1} msg] $msg $::errorInfo $::errorCode
+} {1 msg1 {msg1
+ while executing
+"error msg1"} NONE}
+test error-4.5 {errorInfo and errorCode variables} {
+ set ::errorCode bogus
+ list [catch {error msg1 msg2 {}} msg] $msg $::errorInfo $::errorCode
+} {1 msg1 msg2 {}}
+
+test error-4.6 {errorstack via info } -body {
+ proc f x {g $x$x}
+ proc g x {error G:$x}
+ catch {f 12}
+ info errorstack
+} -match glob -result {INNER * CALL {g 1212} CALL {f 12} UP 1}
+test error-4.7 {errorstack via options dict } -body {
+ proc f x {g $x$x}
+ proc g x {error G:$x}
+ catch {f 12} m d
+ dict get $d -errorstack
+} -match glob -result {INNER * CALL {g 1212} CALL {f 12} UP 1}
+
+# Errors in error command itself
+
+test error-5.1 {errors in error command} {
+ list [catch {error} msg] $msg
+} {1 {wrong # args: should be "error message ?errorInfo? ?errorCode?"}}
+test error-5.2 {errors in error command} {
+ list [catch {error a b c d} msg] $msg
+} {1 {wrong # args: should be "error message ?errorInfo? ?errorCode?"}}
+
+# Make sure that catch resets error information
+
+test error-6.1 {catch must reset error state} {
+ catch {error outer [catch {error inner inner.errorInfo inner.errorCode}]}
+ list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.2 {catch must reset error state} {
+ catch {error outer [catch {return -level 0 -code error -errorcode BUG}]}
+ list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.3 {catch must reset error state} {
+ set ::errorCode BUG
+ catch {error outer [catch set]}
+ list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.4 {catch must reset error state} {
+ catch {error [catch {error foo bar baz}] 1}
+ list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.5 {catch must reset error state} {
+ catch {error [catch {return -level 0 -code error -errorcode BUG}] 1}
+ list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.6 {catch must reset error state} {
+ catch {return -level 0 -code error -errorinfo [catch {error foo bar baz}]}
+ list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.7 {catch must reset error state} {
+ proc foo {} {
+ return -code error -errorinfo [catch {error foo bar baz}]
+ }
+ catch foo
+ list $::errorCode
+} {NONE}
+test error-6.8 {catch must reset error state} {
+ catch {return -level 0 -code error [catch {error foo bar baz}]}
+ list $::errorCode
+} {NONE}
+test error-6.9 {catch must reset error state} {
+ proc foo {} {
+ return -code error [catch {error foo bar baz}]
+ }
+ catch foo
+ list $::errorCode
+} {NONE}
+test error-6.10 {catch must reset errorstack} -body {
+ proc f x {g $x$x}
+ proc g x {error G:$x}
+ catch {f 12}
+ set e1 [info errorstack]
+ catch {f 13}
+ set e2 [info errorstack]
+ list $e1 $e2
+} -match glob -result {{INNER * CALL {g 1212} CALL {f 12} UP 1} {INNER * CALL {g 1313} CALL {f 13} UP 1}}
+
+test error-7.1 {Bug 1397843} -body {
+ variable cmds
+ proc EIWrite args {
+ variable cmds
+ lappend cmds [lindex [info level -2] 0]
+ }
+ proc BadProc {} {
+ set i a
+ incr i
+ }
+ trace add variable ::errorInfo write [namespace code EIWrite]
+ catch BadProc
+ trace remove variable ::errorInfo write [namespace code EIWrite]
+ set cmds
+} -match glob -result {*BadProc*}
+
+# throw tests
+
+test error-8.1 {throw produces error 1 at level 0} {
+ catch { throw FOO bar }
+} {1}
+test error-8.2 {throw behaves as error does at level 0} {
+ catch { throw FOO bar } em1 opts1
+ catch { error bar {} FOO } em2 opts2
+ dict set opts1 -result $em1
+ dict set opts2 -result $em2
+ foreach key {-code -level -result -errorcode} {
+ if { [dict get $opts1 $key] ne [dict get $opts2 $key] } {
+ error "error/throw outcome differs on '$key'"
+ }
+ }
+} {}
+test error-8.3 {throw produces error 1 at level > 0} {
+ proc throw_foo {} {
+ throw FOO bar
+ }
+ catch { throw_foo }
+} {1}
+test error-8.4 {throw behaves as error does at level > 0} {
+ proc throw_foo {} {
+ throw FOO bar
+ }
+ proc error_foo {} {
+ error bar {} FOO
+ }
+ catch { throw_foo } em1 opts1
+ catch { error_foo } em2 opts2
+ dict set opts1 -result $em1
+ dict set opts2 -result $em2
+ foreach key {-code -level -result -errorcode} {
+ if { [dict get $opts1 $key] ne [dict get $opts2 $key] } {
+ error "error/throw outcome differs on '$key'"
+ }
+ }
+} {}
+test error-8.5 {throw syntax checks} -returnCodes error -body {
+ throw
+} -result {wrong # args: should be "throw type message"}
+test error-8.6 {throw syntax checks} -returnCodes error -body {
+ throw a
+} -result {wrong # args: should be "throw type message"}
+test error-8.7 {throw syntax checks} -returnCodes error -body {
+ throw a b c
+} -result {wrong # args: should be "throw type message"}
+test error-8.8 {throw syntax checks} -returnCodes error -body {
+ throw "not a \{ list" foo
+} -result {unmatched open brace in list}
+test error-8.9 {throw syntax checks} -returnCodes error -body {
+ throw {} foo
+} -result {type must be non-empty list}
+
+# simple try tests: body completes with code ok
+
+test error-9.1 {try (ok, empty result) with no handlers} {
+ try list
+} {}
+test error-9.2 {try (ok, non-empty result) with no handlers} {
+ try { list a b c }
+} {a b c}
+test error-9.3 {try (ok, non-empty result) with trap handler} {
+ try { list a b c } trap {} {} { list d e f }
+} {a b c}
+test error-9.4 {try (ok, non-empty result) with on handler} {
+ try { list a b c } on break {} { list d e f }
+} {a b c}
+test error-9.5 {try (ok, non-empty result) with on ok handler} {
+ try { list a b c } on ok {} { list d e f }
+} {d e f}
+
+# simple try tests - "on" handler matching
+
+test error-10.1 {try with on ok} {
+ try { list a b c } on ok {} { list d e f }
+} {d e f}
+test error-10.2 {try with on 0} {
+ try { list a b c } on 0 {} { list d e f }
+} {d e f}
+test error-10.3 {try with on error (using error)} {
+ try { error a b c } on error {} { list d e f }
+} {d e f}
+test error-10.4 {try with on error (using return -code)} {
+ try { return -level 0 -code 1 a } on error {} { list d e f }
+} {d e f}
+test error-10.5 {try with on error (using throw)} {
+ try { throw c a } on error {} { list d e f }
+} {d e f}
+test error-10.6 {try with on 1 (using error)} {
+ try { error a b c } on 1 {} { list d e f }
+} {d e f}
+test error-10.7 {try with on return} {
+ try { return [list a b c] } on return {} { list d e f }
+} {d e f}
+test error-10.8 {try with on break} {
+ try { break } on break {} { list d e f }
+} {d e f}
+test error-10.9 {try with on continue} {
+ try { continue } on continue {} { list d e f }
+} {d e f}
+test error-10.10 {try with on for arbitrary (decimal) return code} {
+ try { return -level 0 -code 123456 } on 123456 {} { list d e f }
+} {d e f}
+test error-10.11 {try with on for arbitrary (hex) return code} {
+ try { return -level 0 -code 0x123456 } on 0x123456 {} { list d e f }
+} {d e f}
+test error-10.12 {try with on for arbitrary return code (mixed number representations)} {
+ try { return -level 0 -code 0x10 } on 16 {} { list d e f }
+} {d e f}
+
+# simple try tests - "trap" handler matching
+
+test error-11.1 {try with trap all} {
+ try { throw FOO bar } trap {} {} { list d e f }
+} {d e f}
+test error-11.2 {try with trap (exact)} {
+ try { throw FOO bar } trap {FOO} {} { list d e f }
+} {d e f}
+test error-11.3 {try with trap (prefix 1)} {
+ try { throw [list FOO A B C D] bar } trap {FOO} {} { list d e f }
+} {d e f}
+test error-11.4 {try with trap (prefix 2)} {
+ try { throw [list FOO A B C D] bar } trap {FOO A} {} { list d e f }
+} {d e f}
+test error-11.5 {try with trap (prefix 3)} {
+ try { throw [list FOO A B C D] bar } trap {FOO A B} {} { list d e f }
+} {d e f}
+test error-11.6 {try with trap (prefix 4)} {
+ try { throw [list FOO A B C D] bar } trap {FOO A B C} {} { list d e f }
+} {d e f}
+test error-11.7 {try with trap (exact, 5 elements)} {
+ try { throw [list FOO A B C D] bar } trap {FOO A B C D} {} { list d e f }
+} {d e f}
+
+# simple try tests - variable assignment and result handling
+
+test error-12.1 {try with no variable assignment in on handler} {
+ try { throw FOO bar } on error {} { list d e f }
+} {d e f}
+test error-12.2 {try with result variable assignment in on handler} {
+ try { throw FOO bar } on error {res} { set res }
+} {bar}
+test error-12.3 {try with result variable assignment in on handler, var remains in scope} {
+ try { throw FOO bar } on error {res} { list d e f }
+ set res
+} {bar}
+test error-12.4 {try with result/opts variable assignment in on handler} {
+ try {
+ throw FOO bar
+ } on error {res opts} {
+ set r "$res,[dict get $opts -errorcode]"
+ }
+} {bar,FOO}
+test error-12.5 {try with result/opts variable assignment in on handler, vars remain in scope} {
+ try { throw FOO bar } on error {res opts} { list d e f }
+ set r "$res,[dict get $opts -errorcode]"
+} {bar,FOO}
+test error-12.6 {try result is propagated if no matching handler} {
+ try { list a b c } on error {} { list d e f }
+} {a b c}
+test error-12.7 {handler result is propagated if handler executes} {
+ try { throw FOO bar } on error {} { list d e f }
+} {d e f}
+
+# negative case try tests - bad args to try
+
+test error-13.1 {try with no arguments} -body {
+ # warning: error message may change
+ try
+} -returnCodes error -match glob -result {wrong # args: *}
+test error-13.2 {try with body only (ok)} {
+ try list
+} {}
+test error-13.3 {try with missing finally body} -body {
+ # warning: error message may change
+ try list finally
+} -returnCodes error -match glob -result {wrong # args to finally clause: *}
+test error-13.4 {try with bad handler keyword} -body {
+ # warning: error message may change
+ try list then a b c
+} -returnCodes error -match glob -result {bad handler *}
+test error-13.5 {try with partial handler #1} -body {
+ # warning: error message may change
+ try list on
+} -returnCodes error -match glob -result {wrong # args to on clause: *}
+test error-13.6 {try with partial handler #2} -body {
+ # warning: error message may change
+ try list on error
+} -returnCodes error -match glob -result {wrong # args to on clause: *}
+test error-13.7 {try with partial handler #3} -body {
+ # warning: error message may change
+ try list on error {em opts}
+} -returnCodes error -match glob -result {wrong # args to on clause: *}
+test error-13.8 {try with multiple handlers and finally (ok)} {
+ try list on error {} {} trap {} {} {} finally {}
+} {}
+test error-13.9 {last handler body can't be a fallthrough #1} -body {
+ try list on error {} {} on break {} -
+} -returnCodes error -result {last non-finally clause must not have a body of "-"}
+test error-13.10 {last handler body can't be a fallthrough #2} -body {
+ try list on error {} {} on break {} - finally { list d e f }
+} -returnCodes error -result {last non-finally clause must not have a body of "-"}
+
+# try tests - multiple handlers (left-to-right matching, only one runs)
+
+test error-14.1 {try with multiple handlers (only one matches) #1} {
+ try { throw FOO bar } on ok {} { list a b c } trap FOO {} { list d e f }
+} {d e f}
+test error-14.2 {try with multiple handlers (only one matches) #2} {
+ try { throw FOO bar } trap FOO {} { list d e f } on ok {} { list a b c }
+} {d e f}
+test error-14.3 {try with multiple handlers (only one matches) #3} {
+ try {
+ throw FOO bar
+ } on break {} {
+ list x y z
+ } trap FOO {} {
+ list d e f
+ } on ok {} {
+ list a b c
+ }
+} {d e f}
+test error-14.4 {try with multiple matching handlers (only the first in left-to-right order runs) #1} {
+ try { throw FOO bar } on error {} { list a b c } trap FOO {} { list d e f }
+} {a b c}
+test error-14.5 {try with multiple matching handlers (only the first in left-to-right order runs) #2} {
+ try { throw FOO bar } trap FOO {} { list d e f } on error {} { list a b c }
+} {d e f}
+test error-14.6 {try with multiple matching handlers (only the first in left-to-right order runs) #3} {
+ try { throw FOO bar } trap {} {} { list d e f } on 1 {} { list a b c }
+} {d e f}
+test error-14.7 {try with multiple matching handlers (only the first in left-to-right order runs) #4} {
+ try { throw FOO bar } on 1 {} { list a b c } trap {} {} { list d e f }
+} {a b c}
+test error-14.8 {try with handler-of-last-resort "trap {}"} {
+ try { throw FOO bar } trap FOX {} { list a b c } trap {} {} { list d e f }
+} {d e f}
+test error-14.9 {try with handler-of-last-resort "on error"} {
+ try { foo } trap FOX {} { list a b c } on error {} { list d e f }
+} {d e f}
+
+# try tests - propagation (no matching handlers)
+
+test error-15.1 {try with no handler (ok result propagates)} {
+ try { list a b c }
+} {a b c}
+test error-15.2 {try with no matching handler (ok result propagates)} {
+ try { list a b c } on error {} { list d e f }
+} {a b c}
+test error-15.3 {try with no handler (error result propagates)} -body {
+ try { throw FOO bar }
+} -returnCodes error -result {bar}
+test error-15.4 {try with no matching handler (error result propagates)} -body {
+ try { throw FOO bar } trap FOX {} { list a b c }
+} -returnCodes error -result {bar}
+test error-15.5 {try with no handler (return result propagates)} -body {
+ try { return bar }
+} -returnCodes 2 -result {bar}
+test error-15.6 {try with no matching handler (break result propagates)} -body {
+ try { if {1} break } on error {} { list a b c }
+} -returnCodes 3 -result {}
+test error-15.7 {try with no matching handler (unknown integer result propagates)} -body {
+ try { return -level 0 -code 123456 } trap {} {} { list a b c }
+} -returnCodes 123456 -result {}
+
+foreach level {0 1 2 3} {
+ foreach code {0 1 2 3 4 5} {
+
+ # Following cases have different -errorinfo; avoid false alarms
+ # TODO: examine whether these difference are as they ought to be.
+ if {$level == 0 && $code == 1} continue
+
+ foreach extras {{} {-bar soom}} {
+
+test error-15.8.$level.$code.[llength $extras] {[try] coverage} {
+ set script {return -level $level -code $code {*}$extras foo}
+ catch $script m1 o1
+ catch {try $script} m2 o2
+ set o1 [lsort -stride 2 $o1]
+ set o2 [lsort -stride 2 $o2]
+ expr {$o1 eq $o2 ? "ok" : "$o1\n\tis not equal to\n$o2"}
+} ok
+
+test error-15.9.$level.$code.[llength $extras] {[try] coverage} {
+ set script {return -level $level -code $code {*}$extras foo}
+ catch $script m1 o1
+ catch {try $script finally {}} m2 o2
+ set o1 [lsort -stride 2 $o1]
+ set o2 [lsort -stride 2 $o2]
+ expr {$o1 eq $o2 ? "ok" : "$o1\n\tis not equal to\n$o2"}
+} ok
+
+test error-15.10.$level.$code.[llength $extras] {[try] coverage} {
+ set script {return -level $level -code $code {*}$extras foo}
+ catch $script m1 o1
+ catch {try $script on $code {x y} {return -options $y $x}} m2 o2
+ set o1 [lsort -stride 2 $o1]
+ set o2 [lsort -stride 2 $o2]
+ expr {$o1 eq $o2 ? "ok" : "$o1\n\tis not equal to\n$o2"}
+} ok
+
+ }
+ }
+}
+
+# try tests - propagation (exceptions in handlers, exception chaining)
+
+test error-16.1 {try with successfully executed handler} {
+ try { throw FOO bar } trap FOO {} { list a b c }
+} {a b c}
+test error-16.2 {try with exception (error) in handler} -body {
+ try { throw FOO bar } trap FOO {} { throw BAR foo }
+} -returnCodes error -result {foo}
+test error-16.3 {try with exception (return) in handler} -body {
+ try { throw FOO bar } trap FOO {} { return BAR }
+} -returnCodes 2 -result {BAR}
+test error-16.4 {try with exception (break) in handler #1} -body {
+ try { throw FOO bar } trap FOO {} { break }
+} -returnCodes 3 -result {}
+test error-16.5 {try with exception (break) in handler #2} {
+ for { set i 5 } { $i < 10 } { incr i } {
+ try { throw FOO bar } trap FOO {} { break }
+ }
+ set i
+} {5}
+test error-16.6 {try with variable assignment and propagation #1} {
+ # Ensure that the handler variables preserve the exception off the
+ # try-body, and are not modified by the exception off the handler
+ catch {
+ try { throw FOO bar } trap FOO {em} { throw BAR baz }
+ }
+ set em
+} {bar}
+test error-16.7 {try with variable assignment and propagation #2} {
+ catch {
+ try { throw FOO bar } trap FOO {em opts} { throw BAR baz }
+ }
+ list $em [dict get $opts -errorcode]
+} {bar FOO}
+test error-16.8 {exception chaining (try=ok, handler=error)} {
+ #FIXME is the intent of this test correct?
+ catch {
+ try { list a b c } on ok {em opts} { throw BAR baz }
+ } tryem tryopts
+ string equal $opts [dict get $tryopts -during]
+} {1}
+test error-16.9 {exception chaining (try=error, handler=error)} {
+ # The exception off the handler should chain to the exception off the
+ # try-body (using the -during option)
+ catch {
+ try { throw FOO bar } trap {} {em opts} { throw BAR baz }
+ } tryem tryopts
+ string equal $opts [dict get $tryopts -during]
+} {1}
+test error-16.10 {no exception chaining when handler is successful} {
+ catch {
+ try { throw FOO bar } trap {} {em opts} { list d e f }
+ } tryem tryopts
+ dict exists $tryopts -during
+} {0}
+test error-16.11 {no exception chaining when handler is a non-error exception} {
+ catch {
+ try { throw FOO bar } trap {} {em opts} { break }
+ } tryem tryopts
+ dict exists $tryopts -during
+} {0}
+
+# try tests - finally
+
+test error-17.1 {finally always runs (try with ok result)} {
+ set RES {}
+ try { list a b c } finally { set RES done }
+ set RES
+} {done}
+test error-17.2 {finally always runs (try with error result)} {
+ set RES {}
+ catch {
+ try { throw FOO bar } finally { set RES done }
+ }
+ set RES
+} {done}
+test error-17.3 {finally always runs (try with matching handler)} {
+ set RES {}
+ try { throw FOO bar } trap FOO {} { list a b c } finally { set RES done }
+ set RES
+} {done}
+test error-17.4 {finally always runs (try with exception in handler)} {
+ set RES {}
+ catch {
+ try {
+ throw FOO bar
+ } trap FOO {} {
+ throw BAR baz
+ } finally {
+ set RES done
+ }
+ }
+ set RES
+} {done}
+test error-17.5 {successful finally doesn't modify try outcome (try=ok)} {
+ try { list a b c } finally { list d e f }
+} {a b c}
+test error-17.6 {successful finally doesn't modify try outcome (try=return)} -body {
+ try { return c } finally { list d e f }
+} -returnCodes 2 -result {c}
+test error-17.7 {successful finally doesn't modify try outcome (try=error)} -body {
+ try { error bar } finally { list d e f }
+} -returnCodes 1 -result {bar}
+test error-17.8 {successful finally doesn't modify handler outcome (handler=ok)} {
+ try { throw FOO bar } trap FOO {} { list a b c } finally { list d e f }
+} {a b c}
+test error-17.9 {successful finally doesn't modify handler outcome (handler=error)} -body {
+ try { throw FOO bar } trap FOO {} { throw BAR baz } finally { list d e f }
+} -returnCodes error -result {baz}
+test error-17.10 {successful finally doesn't affect variable assignment} {
+ catch {
+ try { throw FOO bar } trap FOO {em opts} { list d e f } finally { list d e f }
+ } result
+ list $em $result
+} {bar {d e f}}
+test error-17.11 {successful finally doesn't affect variable assignment or propagation} {
+ catch {
+ try { throw FOO bar } trap FOO {em opts} { throw BAR baz } finally { list d e f }
+ }
+ list $em [dict get $opts -errorcode]
+} {bar FOO}
+
+# try tests - propagation (exceptions in finally, exception chaining)
+
+test error-18.1 {try (ok) with exception in finally (error)} -body {
+ try { list a b c } finally { throw BAR foo }
+} -returnCodes error -result {foo}
+test error-18.2 {try (error) with exception in finally (break)} -body {
+ try { throw FOO bar } finally { break }
+} -returnCodes 3 -result {}
+test error-18.3 {try (ok) with handler (ok) and exception in finally (error)} -body {
+ try { list a b c } on ok {} { list d e f } finally { throw BAR foo }
+} -returnCodes error -result {foo}
+test error-18.4 {try (error) with exception in handler (error) and in finally (arb code)} -body {
+ try { throw FOO bar } on error {} { throw BAR baz } finally { return -level 0 -code 99 zing }
+} -returnCodes 99 -result {zing}
+test error-18.5 {exception in finally doesn't affect variable assignment} {
+ catch {
+ try { throw FOO bar } trap FOO {em opts} { throw BAR baz } finally { throw BAZ zing }
+ }
+ list $em [dict get $opts -errorcode]
+} {bar FOO}
+test error-18.6 {exception chaining in finally (try=ok)} {
+ catch {
+ list a b c
+ } em expopts
+ catch {
+ try { list a b c } finally { throw BAR foo }
+ } em opts
+ string equal $expopts [dict get $opts -during]
+} {1}
+test error-18.7 {exception chaining in finally (try=error)} {
+ catch {
+ try { throw FOO bar } finally { throw BAR baz }
+ } em opts
+ dict get $opts -during -errorcode
+} {FOO}
+test error-18.8 {exception chaining in finally (try=ok, handler=ok)} {
+ catch {
+ try { list a b c } on ok {} { list d e f } finally { throw BAR baz }
+ } em opts
+ list [dict get $opts -during -code] [dict exists $opts -during -during]
+} {0 0}
+test error-18.9 {exception chaining in finally (try=error, handler=ok)} {
+ catch {
+ try {
+ throw FOO bar
+ } on error {} {
+ list d e f
+ } finally {
+ throw BAR baz
+ }
+ } em opts
+ list [dict get $opts -during -code] [dict exists $opts -during -during]
+} {0 0}
+test error-18.10 {exception chaining in finally (try=error, handler=error)} {
+ catch {
+ try {
+ throw FOO bar
+ } on error {} {
+ throw BAR baz
+ } finally {
+ throw BAR baz
+ }
+ } em opts
+ list [dict get $opts -during -errorcode] [dict get $opts -during -during -errorcode]
+} {BAR FOO}
+test error-18.11 {no exception chaining if finally produces a non-error exception} {
+ catch {
+ try { throw FOO bar } on error {} { throw BAR baz } finally { break }
+ } em opts
+ dict exists $opts -during
+} {0}
+test error-18.12 {variable assignment unaffected by exception in finally} {
+ catch {
+ try {
+ throw FOO bar
+ } on error {em opts} {
+ list a b c
+ } finally {
+ throw BAR baz
+ }
+ }
+ list $em [dict get $opts -errorcode]
+} {bar FOO}
+
+# try tests - fallthough body cases
+
+test error-19.1 {try with fallthrough body #1} {
+ set RES {}
+ try { list a b c } on ok { set RES 0 } - on error {} { set RES 1 }
+ set RES
+} {1}
+test error-19.2 {try with fallthrough body #2} {
+ set RES {}
+ try {
+ throw FOO bar
+ } trap BAR {} {
+ } trap FOO {} - trap {} {} {
+ set RES foo
+ } on error {} {
+ set RES err
+ }
+ set RES
+} {foo}
+test error-19.3 {try with cascade fallthrough} {
+ set RES {}
+ try {
+ throw FOO bar
+ } trap FOO {} - trap BAR {} - trap {} {} {
+ set RES trap
+ } on error {} { set RES err }
+ set RES
+} {trap}
+test error-19.4 {multiple unrelated fallthroughs #1} {
+ set RES {}
+ try {
+ throw FOO bar
+ } trap FOO {} - trap BAR {} {
+ set RES foo
+ } trap {} {} - on error {} {
+ set RES err
+ }
+ set RES
+} {foo}
+test error-19.5 {multiple unrelated fallthroughs #2} {
+ set RES {}
+ try {
+ throw BAZ zing
+ } trap FOO {} - trap BAR {} {
+ set RES foo
+ } trap {} {} - on error {} {
+ set RES err
+ }
+ set RES
+} {err}
+proc addmsg msg {
+ variable RES
+ lappend RES $msg
+}
+test error-19.6 {compiled try executes all clauses} -setup {
+ set RES {}
+} -body {
+ apply {{} {
+ try {
+ addmsg a
+ throw bar hello
+ } trap bar {res opt} {
+ addmsg b
+ } finally {
+ addmsg c
+ }
+ addmsg d
+ } ::tcl::test::error}
+} -cleanup {
+ unset RES
+} -result {a b c d}
+test error-19.7 {compiled try executes all clauses} -setup {
+ set RES {}
+} -body {
+ apply {{} {
+ try {
+ addmsg a
+ } on error {res opt} {
+ addmsg b
+ } on ok {} {
+ addmsg c
+ } finally {
+ addmsg d
+ }
+ addmsg e
+ } ::tcl::test::error}
+} -cleanup {
+ unset RES
+} -result {a c d e}
+test error-19.8 {compiled try executes all clauses} -setup {
+ set RES {}
+} -body {
+ apply {{} {
+ try {
+ addmsg a
+ throw bar hello
+ } trap bar {res opt} {
+ addmsg b
+ }
+ addmsg c
+ } ::tcl::test::error}
+} -cleanup {
+ unset RES
+} -result {a b c}
+test error-19.9 {compiled try executes all clauses} -setup {
+ set RES {}
+} -body {
+ apply {{} {
+ try {
+ addmsg a
+ } on error {res opt} {
+ addmsg b
+ } on ok {} {
+ addmsg c
+ }
+ addmsg d
+ } ::tcl::test::error}
+} -cleanup {
+ unset RES
+} -result {a c d}
+test error-19.10 {compiled try with chained clauses} -setup {
+ set RES {}
+} -body {
+ list [apply {{} {
+ try {
+ return good
+ } on return {res} - on ok {res} {
+ addmsg ok
+ addmsg $res
+ return handler
+ } finally {
+ addmsg finally
+ }
+ } ::tcl::test::error}] $RES
+} -cleanup {
+ unset RES
+} -result {handler {ok good finally}}
+test error-19.11 {compiled try and errors on variable write} -setup {
+ set RES {}
+} -body {
+ apply {{} {
+ array set foo {bar boo}
+ set bar unset
+ catch {
+ try {
+ addmsg body
+ return a
+ } on return {bar foo} {
+ addmsg handler
+ return b
+ } finally {
+ addmsg finally,$bar
+ }
+ } msg
+ addmsg $msg
+ } ::tcl::test::error}
+} -cleanup {
+ unset RES
+} -result {body finally,a {can't set "foo": variable is array}}
+test error-19.12 {interpreted try and errors on variable write} -setup {
+ set RES {}
+} -body {
+ apply {try {
+ array set foo {bar boo}
+ set bar unset
+ catch {
+ $try {
+ addmsg body
+ return a
+ } on return {bar foo} {
+ addmsg handler
+ return b
+ } finally {
+ addmsg finally,$bar
+ }
+ } msg
+ addmsg $msg
+ } ::tcl::test::error} try
+} -cleanup {
+ unset RES
+} -result {body finally,a {can't set "foo": variable is array}}
+test error-19.13 {compiled try and errors on variable write} -setup {
+ set RES {}
+} -body {
+ apply {{} {
+ array set foo {bar boo}
+ set bar unset
+ catch {
+ try {
+ addmsg body
+ return a
+ } on return {bar foo} - on error {bar foo} {
+ addmsg handler
+ return b
+ } finally {
+ addmsg finally,$bar
+ }
+ } msg
+ addmsg $msg
+ } ::tcl::test::error}
+} -cleanup {
+ unset RES
+} -result {body finally,a {can't set "foo": variable is array}}
+rename addmsg {}
+
+# FIXME test what vars get set on fallthough ... what is the correct behavior?
+# It would seem appropriate to set at least those for the matching handler and
+# the executed body; possibly for each handler we fall through as well?
+
+# negative case try tests - bad "on" handler
+
+test error-20.1 {bad code name in on handler} -body {
+ try { list a b c } on err {} {}
+} -returnCodes error -match glob -result {bad completion code "err": must be ok, error, return, break, continue*, or an integer}
+test error-20.2 {bad code value in on handler} -body {
+ try { list a b c } on 34985723094872345 {} {}
+} -returnCodes error -match glob -result {bad completion code "34985723094872345": must be ok, error, return, break, continue*, or an integer}
+
+test error-21.1 {memory leaks in try: Bug 2910044} memory {
+ leaktest {
+ try {string repeat x 10} on ok {} {}
+ }
+} 0
+test error-21.2 {memory leaks in try: Bug 2910044} memory {
+ leaktest {
+ try {error [string repeat x 10]} on error {} {}
+ }
+} 0
+test error-21.3 {memory leaks in try: Bug 2910044} memory {
+ leaktest {
+ try {throw FOO [string repeat x 10]} trap FOO {} {}
+ }
+} 0
+test error-21.4 {memory leaks in try: Bug 2910044} memory {
+ leaktest {
+ try {string repeat x 10}
+ }
+} 0
+test error-21.5 {memory leaks in try: Bug 2910044} memory {
+ leaktest {
+ try {string repeat x 10} on ok {} {} finally {string repeat y 10}
+ }
+} 0
+test error-21.6 {memory leaks in try: Bug 2910044} memory {
+ leaktest {
+ try {
+ error [string repeat x 10]
+ } on error {} {} finally {
+ string repeat y 10
+ }
+ }
+} 0
+test error-21.7 {memory leaks in try: Bug 2910044} memory {
+ leaktest {
+ try {
+ throw FOO [string repeat x 10]
+ } trap FOO {} {} finally {
+ string repeat y 10
+ }
+ }
+} 0
+test error-21.8 {memory leaks in try: Bug 2910044} memory {
+ leaktest {
+ try {string repeat x 10} finally {string repeat y 10}
+ }
+} 0
+
+# negative case try tests - bad "trap" handler
+# what is the effect if we attempt to trap an errorcode that is not a list?
+# nested try
+# catch inside try
+# no tests for bad varslist?
+# -errorcode but code!=1 doesn't trap
+# throw negative case tests (no args, too many args, etc)
+
+}
+namespace delete ::tcl::test::error
+
+# cleanup
+catch {rename p ""}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/eval.test b/pkgs/msgcat/tests/eval.test
new file mode 100644
index 0000000..70ceac8
--- /dev/null
+++ b/pkgs/msgcat/tests/eval.test
@@ -0,0 +1,89 @@
+# Commands covered: eval
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test eval-1.1 {single argument} {
+ eval {format 22}
+} 22
+test eval-1.2 {multiple arguments} {
+ set a {$b}
+ set b xyzzy
+ eval format $a
+} xyzzy
+test eval-1.3 {single argument} {
+ eval concat a b c d e f g
+} {a b c d e f g}
+
+test eval-2.1 {error: not enough arguments} {catch eval} 1
+test eval-2.2 {error: not enough arguments} {
+ catch eval msg
+ set msg
+} {wrong # args: should be "eval arg ?arg ...?"}
+test eval-2.3 {error in eval'ed command} {
+ catch {eval {error "test error"}}
+} 1
+test eval-2.4 {error in eval'ed command} {
+ catch {eval {error "test error"}} msg
+ set msg
+} {test error}
+test eval-2.5 {error in eval'ed command: setting errorInfo} {
+ catch {eval {
+ set a 1
+ error "test error"
+ }} msg
+ set ::errorInfo
+} "test error
+ while executing
+\"error \"test error\"\"
+ (\"eval\" body line 3)
+ invoked from within
+\"eval {
+ set a 1
+ error \"test error\"
+ }\""
+
+test eval-3.1 {eval and pure lists} {
+ eval [list list 1 2 3 4 5]
+} {1 2 3 4 5}
+test eval-3.2 {concatenating eval and pure lists} {
+ eval [list list 1] [list 2 3 4 5]
+} {1 2 3 4 5}
+test eval-3.3 {eval and canonical lists} {
+ set cmd [list list 1 2 3 4 5]
+ # Force existance of utf-8 rep
+ set dummy($cmd) $cmd
+ unset dummy
+ eval $cmd
+} {1 2 3 4 5}
+test eval-3.4 {concatenating eval and canonical lists} {
+ set cmd [list list 1]
+ set cmd2 [list 2 3 4 5]
+ # Force existance of utf-8 rep
+ set dummy($cmd) $cmd
+ set dummy($cmd2) $cmd2
+ unset dummy
+ eval $cmd $cmd2
+} {1 2 3 4 5}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/event.test b/pkgs/msgcat/tests/event.test
new file mode 100644
index 0000000..0ee7558
--- /dev/null
+++ b/pkgs/msgcat/tests/event.test
@@ -0,0 +1,921 @@
+# This file contains a collection of tests for the procedures in the file
+# tclEvent.c, which includes the "update", and "vwait" Tcl commands. Sourcing
+# this file into Tcl runs the tests and generates output for errors. No
+# output means no errors were found.
+#
+# Copyright (c) 1995-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+testConstraint testfilehandler [llength [info commands testfilehandler]]
+testConstraint testexithandler [llength [info commands testexithandler]]
+testConstraint testfilewait [llength [info commands testfilewait]]
+testConstraint exec [llength [info commands exec]]
+
+test event-1.1 {Tcl_CreateFileHandler, reading} -setup {
+ testfilehandler close
+ set result ""
+} -constraints {testfilehandler} -body {
+ testfilehandler create 0 readable off
+ testfilehandler clear 0
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+ testfilehandler fillpartial 0
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+} -cleanup {
+ testfilehandler close
+} -result {{0 0} {1 0} {2 0}}
+test event-1.2 {Tcl_CreateFileHandler, writing} -setup {
+ testfilehandler close
+ set result ""
+} -constraints {testfilehandler nonPortable} -body {
+ # This test is non-portable because on some systems (e.g., SunOS 4.1.3)
+ # pipes seem to be writable always.
+ testfilehandler create 0 off writable
+ testfilehandler clear 0
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+ testfilehandler fillpartial 0
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+ testfilehandler fill 0
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+} -cleanup {
+ testfilehandler close
+} -result {{0 1} {0 2} {0 2}}
+test event-1.3 {Tcl_DeleteFileHandler} -setup {
+ testfilehandler close
+ set result ""
+} -constraints {testfilehandler nonPortable} -body {
+ testfilehandler create 2 disabled disabled
+ testfilehandler create 1 readable writable
+ testfilehandler create 0 disabled disabled
+ testfilehandler fillpartial 1
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler create 1 off off
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+} -cleanup {
+ testfilehandler close
+} -result {{0 1} {1 1} {1 2} {0 0}}
+
+test event-2.1 {Tcl_DeleteFileHandler} -setup {
+ testfilehandler close
+ set result ""
+} -constraints {testfilehandler nonPortable} -body {
+ testfilehandler create 2 disabled disabled
+ testfilehandler create 1 readable writable
+ testfilehandler fillpartial 1
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler create 1 off off
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+} -cleanup {
+ testfilehandler close
+} -result {{0 1} {1 1} {1 2} {0 0}}
+test event-2.2 {Tcl_DeleteFileHandler, fd reused & events still pending} -setup {
+ testfilehandler close
+ set result ""
+} -constraints {testfilehandler nonPortable} -body {
+ testfilehandler create 0 readable writable
+ testfilehandler fillpartial 0
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+ testfilehandler close
+ testfilehandler create 0 readable writable
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+} -cleanup {
+ testfilehandler close
+} -result {{0 1} {0 0}}
+
+test event-3.1 {FileHandlerCheckProc, TCL_FILE_EVENTS off} -setup {
+ testfilehandler close
+} -constraints {testfilehandler} -body {
+ testfilehandler create 1 readable writable
+ testfilehandler fillpartial 1
+ testfilehandler windowevent
+ testfilehandler counts 1
+} -cleanup {
+ testfilehandler close
+} -result {0 0}
+
+test event-4.1 {FileHandlerEventProc, race between event and disabling} -setup {
+ update
+ testfilehandler close
+ set result ""
+} -constraints {testfilehandler nonPortable} -body {
+ testfilehandler create 2 disabled disabled
+ testfilehandler create 1 readable writable
+ testfilehandler fillpartial 1
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+ testfilehandler create 1 disabled disabled
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 1]
+} -cleanup {
+ testfilehandler close
+} -result {{0 1} {1 1} {1 2} {0 0}}
+test event-4.2 {FileHandlerEventProc, TCL_FILE_EVENTS off} -setup {
+ update
+ testfilehandler close
+} -constraints {testfilehandler nonPortable} -body {
+ testfilehandler create 1 readable writable
+ testfilehandler create 2 readable writable
+ testfilehandler fillpartial 1
+ testfilehandler fillpartial 2
+ testfilehandler oneevent
+ set result ""
+ lappend result [testfilehandler counts 1] [testfilehandler counts 2]
+ testfilehandler windowevent
+ lappend result [testfilehandler counts 1] [testfilehandler counts 2]
+} -cleanup {
+ testfilehandler close
+} -result {{0 0} {0 1} {0 0} {0 1}}
+update
+
+test event-5.1 {Tcl_BackgroundError, HandleBgErrors procedures} -setup {
+ catch {rename bgerror {}}
+} -body {
+ proc bgerror msg {
+ global errorInfo errorCode x
+ lappend x [list $msg $errorInfo $errorCode]
+ }
+ after idle {error "a simple error"}
+ after idle {open non_existent}
+ after idle {set errorInfo foobar; set errorCode xyzzy}
+ set x {}
+ update idletasks
+ regsub -all [file join {} non_existent] $x "non_existent"
+} -cleanup {
+ rename bgerror {}
+} -result {{{a simple error} {a simple error
+ while executing
+"error "a simple error""
+ ("after" script)} NONE} {{couldn't open "non_existent": no such file or directory} {couldn't open "non_existent": no such file or directory
+ while executing
+"open non_existent"
+ ("after" script)} {POSIX ENOENT {no such file or directory}}}}
+test event-5.2 {Tcl_BackgroundError, HandleBgErrors procedures} -setup {
+ catch {rename bgerror {}}
+} -body {
+ proc bgerror msg {
+ global x
+ lappend x $msg
+ return -code break
+ }
+ after idle {error "a simple error"}
+ after idle {open non_existent}
+ set x {}
+ update idletasks
+ return $x
+} -cleanup {
+ rename bgerror {}
+} -result {{a simple error}}
+test event-5.3 {HandleBgErrors: [Bug 1670155]} -setup {
+ variable x
+ proc demo args {variable x done}
+ variable target [list [namespace which demo] x]
+ proc trial args {variable target; string length $target}
+ trace add execution demo enter [namespace code trial]
+ variable save [interp bgerror {}]
+ interp bgerror {} $target
+} -body {
+ after 0 {error bar}
+ vwait [namespace which -variable x]
+} -cleanup {
+ interp bgerror {} $save
+ unset x target save
+ rename demo {}
+ rename trial {}
+} -result {}
+test event-5.3.1 {Default [interp bgerror] handler} -body {
+ ::tcl::Bgerror
+} -returnCodes error -match glob -result {*msg options*}
+test event-5.4 {Default [interp bgerror] handler} -body {
+ ::tcl::Bgerror {}
+} -returnCodes error -match glob -result {*msg options*}
+test event-5.5 {Default [interp bgerror] handler} -body {
+ ::tcl::Bgerror {} {} {}
+} -returnCodes error -match glob -result {*msg options*}
+test event-5.6 {Default [interp bgerror] handler} -body {
+ ::tcl::Bgerror {} {}
+} -returnCodes error -match glob -result {*-level*}
+test event-5.7 {Default [interp bgerror] handler} -body {
+ ::tcl::Bgerror {} {-level foo}
+} -returnCodes error -match glob -result {*expected integer*}
+test event-5.8 {Default [interp bgerror] handler} -body {
+ ::tcl::Bgerror {} {-level 0}
+} -returnCodes error -match glob -result {*-code*}
+test event-5.9 {Default [interp bgerror] handler} -body {
+ ::tcl::Bgerror {} {-level 0 -code ok}
+} -returnCodes error -match glob -result {*expected integer*}
+test event-5.10 {Default [interp bgerror] handler} -body {
+ proc bgerror {m} {append ::res $m}
+ set ::res {}
+ ::tcl::Bgerror {} {-level 0 -code 0}
+ return $::res
+} -cleanup {
+ rename bgerror {}
+} -result {}
+test event-5.11 {Default [interp bgerror] handler} -body {
+ proc bgerror {m} {append ::res $m}
+ set ::res {}
+ ::tcl::Bgerror msg {-level 0 -code 1}
+ return $::res
+} -cleanup {
+ rename bgerror {}
+} -result {msg}
+test event-5.12 {Default [interp bgerror] handler} -body {
+ proc bgerror {m} {append ::res $m}
+ set ::res {}
+ ::tcl::Bgerror msg {-level 0 -code 2}
+ return $::res
+} -cleanup {
+ rename bgerror {}
+} -result {command returned bad code: 2}
+test event-5.13 {Default [interp bgerror] handler} -body {
+ proc bgerror {m} {append ::res $m}
+ set ::res {}
+ ::tcl::Bgerror msg {-level 0 -code 3}
+ return $::res
+} -cleanup {
+ rename bgerror {}
+} -result {invoked "break" outside of a loop}
+test event-5.14 {Default [interp bgerror] handler} -body {
+ proc bgerror {m} {append ::res $m}
+ set ::res {}
+ ::tcl::Bgerror msg {-level 0 -code 4}
+ return $::res
+} -cleanup {
+ rename bgerror {}
+} -result {invoked "continue" outside of a loop}
+test event-5.15 {Default [interp bgerror] handler} -body {
+ proc bgerror {m} {append ::res $m}
+ set ::res {}
+ ::tcl::Bgerror msg {-level 0 -code 5}
+ return $::res
+} -cleanup {
+ rename bgerror {}
+} -result {command returned bad code: 5}
+
+test event-6.1 {BgErrorDeleteProc procedure} -setup {
+ catch {interp delete foo}
+ interp create foo
+ set erroutfile [makeFile Unmodified err.out]
+} -body {
+ foo eval [list set erroutfile $erroutfile]
+ foo eval {
+ proc bgerror args {
+ global errorInfo erroutfile
+ set f [open $erroutfile r+]
+ seek $f 0 end
+ puts $f "$args $errorInfo"
+ close $f
+ }
+ after 100 {error "first error"}
+ after 100 {error "second error"}
+ }
+ after 100 {interp delete foo}
+ after 200
+ update
+ set f [open $erroutfile r]
+ set result [read $f]
+ close $f
+ return $result
+} -cleanup {
+ removeFile $erroutfile
+} -result {Unmodified
+}
+
+test event-7.1 {bgerror / regular} {
+ set errRes {}
+ proc bgerror {err} {
+ global errRes
+ set errRes $err
+ }
+ after 0 {error err1}
+ vwait errRes
+ return $errRes
+} err1
+test event-7.2 {bgerror / accumulation} {
+ set errRes {}
+ proc bgerror {err} {
+ global errRes
+ lappend errRes $err
+ }
+ after 0 {error err1}
+ after 0 {error err2}
+ after 0 {error err3}
+ update
+ return $errRes
+} {err1 err2 err3}
+test event-7.3 {bgerror / accumulation / break} {
+ set errRes {}
+ proc bgerror {err} {
+ global errRes
+ lappend errRes $err
+ return -code break "skip!"
+ }
+ after 0 {error err1}
+ after 0 {error err2}
+ after 0 {error err3}
+ update
+ return $errRes
+} err1
+test event-7.4 {tkerror is nothing special anymore to tcl} -body {
+ set errRes {}
+ # we don't just rename bgerror to empty because it could then
+ # be autoloaded...
+ proc bgerror {err} {
+ global errRes
+ lappend errRes "bg:$err"
+ }
+ proc tkerror {err} {
+ global errRes
+ lappend errRes "tk:$err"
+ }
+ after 0 {error err1}
+ update
+ return $errRes
+} -cleanup {
+ rename tkerror {}
+} -result bg:err1
+test event-7.5 {correct behaviour when there is no bgerror [Bug 219142]} -body {
+ exec [interpreter] << {
+ after 1000 error hello
+ after 2000 set a 0
+ vwait a
+ }
+} -constraints {exec} -returnCodes error -result {hello
+ while executing
+"error hello"
+ ("after" script)}
+test event-7.6 {safe hidden bgerror fallback} -setup {
+ variable result {}
+ interp create -safe safe
+} -body {
+ safe alias puts puts
+ safe alias result ::append [namespace which -variable result]
+ safe eval {proc bgerror m {result $m\n$::errorCode\n$::errorInfo\n}}
+ safe hide bgerror
+ safe eval after 0 error foo
+ update
+ return $result
+} -cleanup {
+ interp delete safe
+} -result {foo
+NONE
+foo
+ while executing
+"error foo"
+ ("after" script)
+}
+test event-7.7 {safe hidden bgerror fallback} -setup {
+ variable result {}
+ interp create -safe safe
+} -body {
+ safe alias puts puts
+ safe alias result ::append [namespace which -variable result]
+ safe eval {proc bgerror m {result $m\n$::errorCode\n$::errorInfo\n}}
+ safe hide bgerror
+ safe eval {proc bgerror m {error bar soom baz}}
+ safe eval after 0 error foo
+ update
+ return $result
+} -cleanup {
+ interp delete safe
+} -result {foo
+NONE
+foo
+ while executing
+"error foo"
+ ("after" script)
+}
+
+# someday : add a test checking that when there is no bgerror, an error msg
+# goes to stderr ideally one would use sub interp and transfer a fake stderr
+# to it, unfortunatly the current interp tcl API does not allow that. The
+# other option would be to use fork a test but it then becomes more a
+# file/exec test than a bgerror test.
+
+# end of bgerror tests
+catch {rename bgerror {}}
+
+test event-8.1 {Tcl_CreateExitHandler procedure} {stdio testexithandler} {
+ set child [open |[list [interpreter]] r+]
+ puts $child "testexithandler create 41; testexithandler create 4"
+ puts $child "testexithandler create 6; exit"
+ flush $child
+ set result [read $child]
+ close $child
+ return $result
+} {even 6
+even 4
+odd 41
+}
+
+test event-9.1 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
+ set child [open |[list [interpreter]] r+]
+ puts $child "testexithandler create 41; testexithandler create 4"
+ puts $child "testexithandler create 6; testexithandler delete 41"
+ puts $child "testexithandler create 16; exit"
+ flush $child
+ set result [read $child]
+ close $child
+ return $result
+} {even 16
+even 6
+even 4
+}
+test event-9.2 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
+ set child [open |[list [interpreter]] r+]
+ puts $child "testexithandler create 41; testexithandler create 4"
+ puts $child "testexithandler create 6; testexithandler delete 4"
+ puts $child "testexithandler create 16; exit"
+ flush $child
+ set result [read $child]
+ close $child
+ return $result
+} {even 16
+even 6
+odd 41
+}
+test event-9.3 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
+ set child [open |[list [interpreter]] r+]
+ puts $child "testexithandler create 41; testexithandler create 4"
+ puts $child "testexithandler create 6; testexithandler delete 6"
+ puts $child "testexithandler create 16; exit"
+ flush $child
+ set result [read $child]
+ close $child
+ return $result
+} {even 16
+even 4
+odd 41
+}
+test event-9.4 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
+ set child [open |[list [interpreter]] r+]
+ puts $child "testexithandler create 41; testexithandler delete 41"
+ puts $child "testexithandler create 16; exit"
+ flush $child
+ set result [read $child]
+ close $child
+ return $result
+} {even 16
+}
+
+test event-10.1 {Tcl_Exit procedure} {stdio} {
+ set child [open |[list [interpreter]] r+]
+ puts $child "exit 3"
+ list [catch {close $child} msg] $msg [lindex $::errorCode 0] \
+ [lindex $::errorCode 2]
+} {1 {child process exited abnormally} CHILDSTATUS 3}
+
+test event-11.1 {Tcl_VwaitCmd procedure} -returnCodes error -body {
+ vwait
+} -result {wrong # args: should be "vwait name"}
+test event-11.2 {Tcl_VwaitCmd procedure} -returnCodes error -body {
+ vwait a b
+} -result {wrong # args: should be "vwait name"}
+test event-11.3 {Tcl_VwaitCmd procedure} -setup {
+ catch {unset x}
+} -body {
+ set x 1
+ vwait x(1)
+} -returnCodes error -result {can't trace "x(1)": variable isn't array}
+test event-11.4 {Tcl_VwaitCmd procedure} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+ after 10; update; # On Mac make sure update won't take long
+} -body {
+ after 100 {set x x-done}
+ after 200 {set y y-done}
+ after 300 {set z z-done}
+ after idle {set q q-done}
+ set x before
+ set y before
+ set z before
+ set q before
+ list [vwait y] $x $y $z $q
+} -cleanup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {{} x-done y-done before q-done}
+test event-11.5 {Tcl_VwaitCmd procedure: round robin scheduling, 2 sources} -setup {
+ set test1file [makeFile "" test1]
+} -constraints {socket} -body {
+ set f1 [open $test1file w]
+ proc accept {s args} {
+ puts $s foobar
+ close $s
+ }
+ set s1 [socket -server accept -myaddr 127.0.0.1 0]
+ after 1000
+ set s2 [socket 127.0.0.1 [lindex [fconfigure $s1 -sockname] 2]]
+ close $s1
+ set x 0
+ set y 0
+ set z 0
+ fileevent $s2 readable {incr z}
+ vwait z
+ fileevent $f1 writable {incr x; if {$y == 3} {set z done}}
+ fileevent $s2 readable {incr y; if {$x == 3} {set z done}}
+ vwait z
+ close $f1
+ close $s2
+ list $x $y $z
+} -cleanup {
+ removeFile $test1file
+} -result {3 3 done}
+test event-11.6 {Tcl_VwaitCmd procedure: round robin scheduling, same source} {
+ set test1file [makeFile "" test1]
+ set test2file [makeFile "" test2]
+ set f1 [open $test1file w]
+ set f2 [open $test2file w]
+ set x 0
+ set y 0
+ set z 0
+ update
+ fileevent $f1 writable {incr x; if {$y == 3} {set z done}}
+ fileevent $f2 writable {incr y; if {$x == 3} {set z done}}
+ vwait z
+ close $f1
+ close $f2
+ removeFile $test1file
+ removeFile $test2file
+ list $x $y $z
+} {3 3 done}
+
+test event-12.1 {Tcl_UpdateCmd procedure} -returnCodes error -body {
+ update a b
+} -result {wrong # args: should be "update ?idletasks?"}
+test event-12.2 {Tcl_UpdateCmd procedure} -returnCodes error -body {
+ update bogus
+} -result {bad option "bogus": must be idletasks}
+test event-12.3 {Tcl_UpdateCmd procedure} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ after 500 {set x after}
+ after idle {set y after}
+ after idle {set z "after, y = $y"}
+ set x before
+ set y before
+ set z before
+ update idletasks
+ list $x $y $z
+} -cleanup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {before after {after, y = after}}
+test event-12.4 {Tcl_UpdateCmd procedure} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ after 10; update; # On Mac make sure update won't take long
+ after 200 {set x x-done}
+ after 600 {set y y-done}
+ after idle {set z z-done}
+ set x before
+ set y before
+ set z before
+ after 300
+ update
+ list $x $y $z
+} -cleanup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {x-done before z-done}
+
+test event-13.1 {Tcl_WaitForFile procedure, readable} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+ testfilehandler close
+} -constraints {testfilehandler} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ set x "no timeout"
+ set result [testfilehandler wait 1 readable 0]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {{} {no timeout}}
+test event-13.2 {Tcl_WaitForFile procedure, readable} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+ testfilehandler close
+} -constraints testfilehandler -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ set x "no timeout"
+ set result [testfilehandler wait 1 readable 100]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {{} timeout}
+test event-13.3 {Tcl_WaitForFile procedure, readable} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+ testfilehandler close
+} -constraints testfilehandler -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ testfilehandler fillpartial 1
+ set x "no timeout"
+ set result [testfilehandler wait 1 readable 100]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {readable {no timeout}}
+test event-13.4 {Tcl_WaitForFile procedure, writable} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+ testfilehandler close
+} -constraints {testfilehandler nonPortable} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ testfilehandler fill 1
+ set x "no timeout"
+ set result [testfilehandler wait 1 writable 0]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {{} {no timeout}}
+test event-13.5 {Tcl_WaitForFile procedure, writable} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+ testfilehandler close
+} -constraints {testfilehandler nonPortable} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ testfilehandler fill 1
+ set x "no timeout"
+ set result [testfilehandler wait 1 writable 100]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {{} timeout}
+test event-13.6 {Tcl_WaitForFile procedure, writable} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+ testfilehandler close
+} -constraints testfilehandler -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ set x "no timeout"
+ set result [testfilehandler wait 1 writable 100]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {writable {no timeout}}
+test event-13.7 {Tcl_WaitForFile procedure, don't call other event handlers} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+ testfilehandler close
+} -constraints testfilehandler -body {
+ after 100 lappend x timeout
+ after idle lappend x idle
+ testfilehandler create 1 off off
+ set x ""
+ set result [list [testfilehandler wait 1 readable 200] $x]
+ update
+ lappend result $x
+} -cleanup {
+ testfilehandler close
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {{} {} {timeout idle}}
+test event-13.8 {Tcl_WaitForFile procedure, waiting indefinitely} testfilewait {
+ set f [open "|sleep 2" r]
+ set result ""
+ lappend result [testfilewait $f readable 100]
+ lappend result [testfilewait $f readable -1]
+ close $f
+ return $result
+} {{} readable}
+
+test event-14.1 {Tcl_WaitForFile procedure, readable, big fd} -setup {
+ set chanList {}
+ for {set i 0} {$i < 32} {incr i} {
+ lappend chanList [open /dev/null r]
+ }
+ foreach i [after info] {after cancel $i}
+ testfilehandler close
+} -constraints {testfilehandler unix} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ set x "no timeout"
+ set result [testfilehandler wait 1 readable 0]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach chan $chanList {close $chan}
+ foreach i [after info] {after cancel $i}
+} -result {{} {no timeout}}
+test event-14.2 {Tcl_WaitForFile procedure, readable, big fd} -setup {
+ set chanList {}
+ for {set i 0} {$i < 32} {incr i} {
+ lappend chanList [open /dev/null r]
+ }
+ foreach i [after info] {after cancel $i}
+ testfilehandler close
+} -constraints {testfilehandler unix} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ set x "no timeout"
+ set result [testfilehandler wait 1 readable 100]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach chan $chanList {close $chan}
+ foreach i [after info] {after cancel $i}
+} -result {{} timeout}
+test event-14.3 {Tcl_WaitForFile procedure, readable, big fd} -setup {
+ set chanList {}
+ for {set i 0} {$i < 32} {incr i} {
+ lappend chanList [open /dev/null r]
+ }
+ foreach i [after info] {after cancel $i}
+ testfilehandler close
+} -constraints {testfilehandler unix} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ testfilehandler fillpartial 1
+ set x "no timeout"
+ set result [testfilehandler wait 1 readable 100]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach chan $chanList {close $chan}
+ foreach i [after info] {after cancel $i}
+} -result {readable {no timeout}}
+test event-14.4 {Tcl_WaitForFile procedure, writable, big fd} -setup {
+ set chanList {}
+ for {set i 0} {$i < 32} {incr i} {
+ lappend chanList [open /dev/null r]
+ }
+ foreach i [after info] {after cancel $i}
+ testfilehandler close
+} -constraints {testfilehandler unix nonPortable} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ testfilehandler fill 1
+ set x "no timeout"
+ set result [testfilehandler wait 1 writable 0]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach chan $chanList {close $chan}
+ foreach i [after info] {after cancel $i}
+} -result {{} {no timeout}}
+test event-14.5 {Tcl_WaitForFile procedure, writable, big fd} -setup {
+ set chanList {}
+ for {set i 0} {$i < 32} {incr i} {
+ lappend chanList [open /dev/null r]
+ }
+ foreach i [after info] {after cancel $i}
+ testfilehandler close
+} -constraints {testfilehandler unix nonPortable} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ testfilehandler fill 1
+ set x "no timeout"
+ set result [testfilehandler wait 1 writable 100]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach chan $chanList {close $chan}
+ foreach i [after info] {after cancel $i}
+} -result {{} timeout}
+test event-14.6 {Tcl_WaitForFile procedure, writable, big fd} -setup {
+ set chanList {}
+ for {set i 0} {$i < 32} {incr i} {
+ lappend chanList [open /dev/null r]
+ }
+ foreach i [after info] {after cancel $i}
+ testfilehandler close
+} -constraints {testfilehandler unix} -body {
+ after 100 set x timeout
+ testfilehandler create 1 off off
+ set x "no timeout"
+ set result [testfilehandler wait 1 writable 100]
+ update
+ list $result $x
+} -cleanup {
+ testfilehandler close
+ foreach chan $chanList {close $chan}
+ foreach i [after info] {after cancel $i}
+} -result {writable {no timeout}}
+test event-14.7 {Tcl_WaitForFile, don't call other event handlers, big fd} -setup {
+ set chanList {}
+ for {set i 0} {$i < 32} {incr i} {
+ lappend chanList [open /dev/null r]
+ }
+ foreach i [after info] {after cancel $i}
+ testfilehandler close
+} -constraints {testfilehandler unix} -body {
+ after 100 lappend x timeout
+ after idle lappend x idle
+ testfilehandler create 1 off off
+ set x ""
+ set result [list [testfilehandler wait 1 readable 200] $x]
+ update
+ lappend result $x
+} -cleanup {
+ testfilehandler close
+ foreach chan $chanList {close $chan}
+ foreach i [after info] {after cancel $i}
+} -result {{} {} {timeout idle}}
+test event-14.8 {Tcl_WaitForFile procedure, waiting indefinitely, big fd} -setup {
+ set chanList {}
+ for {set i 0} {$i < 32} {incr i} {
+ lappend chanList [open /dev/null r]
+ }
+} -constraints {testfilewait unix} -body {
+ set f [open "|sleep 2" r]
+ set result ""
+ lappend result [testfilewait $f readable 100]
+ lappend result [testfilewait $f readable -1]
+ close $f
+ return $result
+} -cleanup {
+ foreach chan $chanList {close $chan}
+} -result {{} readable}
+
+# cleanup
+foreach i [after info] {
+ after cancel $i
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/exec.test b/pkgs/msgcat/tests/exec.test
new file mode 100644
index 0000000..64d3517
--- /dev/null
+++ b/pkgs/msgcat/tests/exec.test
@@ -0,0 +1,699 @@
+# Commands covered: exec
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+# All tests require the "exec" command.
+# Skip them if exec is not defined.
+testConstraint exec [llength [info commands exec]]
+unset -nocomplain path
+
+# Utilities that are like bourne shell stalwarts, but cross-platform.
+set path(echo) [makeFile {
+ puts -nonewline [lindex $argv 0]
+ foreach str [lrange $argv 1 end] {
+ puts -nonewline " $str"
+ }
+ puts {}
+ exit
+} echo]
+set path(echo2) [makeFile {
+ puts stdout [join $argv]
+ puts stderr [lindex $argv 1]
+ exit
+} echo2]
+set path(cat) [makeFile {
+ if {$argv eq ""} {
+ set argv -
+ }
+ fconfigure stdout -translation binary
+ foreach name $argv {
+ if {$name eq "-"} {
+ set f stdin
+ } elseif {[catch {open $name r} f] != 0} {
+ puts stderr $f
+ continue
+ }
+ fconfigure $f -translation binary
+ while {[eof $f] == 0} {
+ puts -nonewline [read $f]
+ }
+ if {$f ne "stdin"} {
+ close $f
+ }
+ }
+ exit
+} cat]
+set path(wc) [makeFile {
+ set data [read stdin]
+ set lines [regsub -all "\n" $data {} dummy]
+ set words [regsub -all "\[^ \t\n]+" $data {} dummy]
+ set chars [string length $data]
+ puts [format "%8.d%8.d%8.d" $lines $words $chars]
+ exit
+} wc]
+set path(sh) [makeFile {
+ if {[lindex $argv 0] ne "-c"} {
+ error "sh: unexpected arguments $argv"
+ }
+ set cmd [lindex $argv 1]
+ lappend cmd ";"
+ set newcmd {}
+ foreach arg $cmd {
+ if {$arg eq ";"} {
+ exec >@stdout 2>@stderr [info nameofexecutable] {*}$newcmd
+ set newcmd {}
+ continue
+ }
+ if {$arg eq "1>&2"} {
+ set arg >@stderr
+ }
+ lappend newcmd $arg
+ }
+ exit
+} sh]
+set path(sh2) [makeFile {
+ if {[lindex $argv 0] ne "-c"} {
+ error "sh: unexpected arguments $argv"
+ }
+ set cmd [lindex $argv 1]
+ lappend cmd ";"
+ set newcmd {}
+ foreach arg $cmd {
+ if {$arg eq ";"} {
+ exec -ignorestderr >@stdout [info nameofexecutable] {*}$newcmd
+ set newcmd {}
+ continue
+ }
+ lappend newcmd $arg
+ }
+ exit
+} sh2]
+set path(sleep) [makeFile {
+ after [expr $argv*1000]
+ exit
+} sleep]
+set path(exit) [makeFile {
+ exit $argv
+} exit]
+
+proc readfile filename {
+ set f [open $filename]
+ set d [read $f]
+ close $f
+ return [string trimright $d \n]
+}
+
+# ----------------------------------------------------------------------
+# Basic operations.
+
+test exec-1.1 {basic exec operation} {exec} {
+ exec [interpreter] $path(echo) a b c
+} "a b c"
+test exec-1.2 {pipelining} {exec stdio} {
+ exec [interpreter] $path(echo) a b c d | [interpreter] $path(cat) | [interpreter] $path(cat)
+} "a b c d"
+test exec-1.3 {pipelining} {exec stdio} {
+ set a [exec [interpreter] $path(echo) a b c d | [interpreter] $path(cat) | [interpreter] $path(wc)]
+ list [scan $a "%d %d %d" b c d] $b $c
+} {3 1 4}
+set arg {12345678901234567890123456789012345678901234567890}
+set arg "$arg$arg$arg$arg$arg$arg"
+test exec-1.4 {long command lines} {exec} {
+ exec [interpreter] $path(echo) $arg
+} $arg
+set arg {}
+
+# I/O redirection: input from Tcl command.
+
+test exec-2.1 {redirecting input from immediate source} {exec stdio} {
+ exec [interpreter] $path(cat) << "Sample text"
+} {Sample text}
+test exec-2.2 {redirecting input from immediate source} {exec stdio} {
+ exec << "Sample text" [interpreter] $path(cat) | [interpreter] $path(cat)
+} {Sample text}
+test exec-2.3 {redirecting input from immediate source} {exec stdio} {
+ exec [interpreter] $path(cat) << "Sample text" | [interpreter] $path(cat)
+} {Sample text}
+test exec-2.4 {redirecting input from immediate source} {exec stdio} {
+ exec [interpreter] $path(cat) | [interpreter] $path(cat) << "Sample text"
+} {Sample text}
+test exec-2.5 {redirecting input from immediate source} {exec} {
+ exec [interpreter] $path(cat) "<<Joined to arrows"
+} {Joined to arrows}
+test exec-2.6 {redirecting input from immediate source, with UTF} -setup {
+ set sysenc [encoding system]
+ encoding system iso8859-1
+ proc quotenonascii s {
+ regsub -all {\[|\\|\]} $s {\\&} s
+ regsub -all {[\u007f-\uffff]} $s \
+ {[apply {c {format {\u%04x} [scan $c %c]}} &]} s
+ return [subst -novariables $s]
+ }
+} -constraints {exec} -body {
+ # If this fails, it may give back: "\uC3\uA9\uC3\uA0\uC3\uBC\uC3\uB1"
+ # If it does, this means that the UTF -> external conversion did not occur
+ # before writing out the temp file.
+ quotenonascii [exec [interpreter] $path(cat) << "\uE9\uE0\uFC\uF1"]
+} -cleanup {
+ encoding system $sysenc
+ rename quotenonascii {}
+} -result {\u00e9\u00e0\u00fc\u00f1}
+
+# I/O redirection: output to file.
+
+set path(gorp.file) [makeFile {} gorp.file]
+file delete $path(gorp.file)
+
+test exec-3.1 {redirecting output to file} {exec} {
+ exec [interpreter] $path(echo) "Some simple words" > $path(gorp.file)
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "Some simple words"
+test exec-3.2 {redirecting output to file} {exec stdio} {
+ exec [interpreter] $path(echo) "More simple words" | >$path(gorp.file) [interpreter] $path(cat) | [interpreter] $path(cat)
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "More simple words"
+test exec-3.3 {redirecting output to file} {exec stdio} {
+ exec > $path(gorp.file) [interpreter] $path(echo) "Different simple words" | [interpreter] $path(cat) | [interpreter] $path(cat)
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "Different simple words"
+test exec-3.4 {redirecting output to file} {exec} {
+ exec [interpreter] $path(echo) "Some simple words" >$path(gorp.file)
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "Some simple words"
+test exec-3.5 {redirecting output to file} {exec} {
+ exec [interpreter] $path(echo) "First line" >$path(gorp.file)
+ exec [interpreter] $path(echo) "Second line" >> $path(gorp.file)
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "First line\nSecond line"
+test exec-3.6 {redirecting output to file} {exec} {
+ exec [interpreter] $path(echo) "First line" >$path(gorp.file)
+ exec [interpreter] $path(echo) "Second line" >>$path(gorp.file)
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "First line\nSecond line"
+test exec-3.7 {redirecting output to file} {exec} {
+ set f [open $path(gorp.file) w]
+ puts $f "Line 1"
+ flush $f
+ exec [interpreter] $path(echo) "More text" >@ $f
+ exec [interpreter] $path(echo) >@$f "Even more"
+ puts $f "Line 3"
+ close $f
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "Line 1\nMore text\nEven more\nLine 3"
+
+# I/O redirection: output and stderr to file.
+
+file delete $path(gorp.file)
+
+test exec-4.1 {redirecting output and stderr to file} {exec} {
+ exec [interpreter] $path(echo) "test output" >& $path(gorp.file)
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "test output"
+test exec-4.2 {redirecting output and stderr to file} {exec} {
+ list [exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" >&$path(gorp.file)] \
+ [exec [interpreter] $path(cat) $path(gorp.file)]
+} {{} {foo bar}}
+test exec-4.3 {redirecting output and stderr to file} {exec} {
+ exec [interpreter] $path(echo) "first line" > $path(gorp.file)
+ list [exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" >>&$path(gorp.file)] \
+ [exec [interpreter] $path(cat) $path(gorp.file)]
+} "{} {first line\nfoo bar}"
+test exec-4.4 {redirecting output and stderr to file} {exec} {
+ set f [open $path(gorp.file) w]
+ puts $f "Line 1"
+ flush $f
+ exec [interpreter] $path(echo) "More text" >&@ $f
+ exec [interpreter] $path(echo) >&@$f "Even more"
+ puts $f "Line 3"
+ close $f
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "Line 1\nMore text\nEven more\nLine 3"
+test exec-4.5 {redirecting output and stderr to file} {exec} {
+ set f [open $path(gorp.file) w]
+ puts $f "Line 1"
+ flush $f
+ exec >&@ $f [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2"
+ exec >&@$f [interpreter] $path(sh) -c "\"$path(echo)\" xyzzy 1>&2"
+ puts $f "Line 3"
+ close $f
+ exec [interpreter] $path(cat) $path(gorp.file)
+} "Line 1\nfoo bar\nxyzzy\nLine 3"
+
+# I/O redirection: input from file.
+
+if {[testConstraint exec]} {
+ exec [interpreter] $path(echo) "Just a few thoughts" > $path(gorp.file)
+}
+test exec-5.1 {redirecting input from file} {exec} {
+ exec [interpreter] $path(cat) < $path(gorp.file)
+} {Just a few thoughts}
+test exec-5.2 {redirecting input from file} {exec stdio} {
+ exec [interpreter] $path(cat) | [interpreter] $path(cat) < $path(gorp.file)
+} {Just a few thoughts}
+test exec-5.3 {redirecting input from file} {exec stdio} {
+ exec [interpreter] $path(cat) < $path(gorp.file) | [interpreter] $path(cat)
+} {Just a few thoughts}
+test exec-5.4 {redirecting input from file} {exec stdio} {
+ exec < $path(gorp.file) [interpreter] $path(cat) | [interpreter] $path(cat)
+} {Just a few thoughts}
+test exec-5.5 {redirecting input from file} {exec} {
+ exec [interpreter] $path(cat) <$path(gorp.file)
+} {Just a few thoughts}
+test exec-5.6 {redirecting input from file} -constraints {exec} -body {
+ set f [open $path(gorp.file) r]
+ exec [interpreter] $path(cat) <@ $f
+} -cleanup {
+ close $f
+} -result {Just a few thoughts}
+test exec-5.7 {redirecting input from file} -constraints {exec} -body {
+ set f [open $path(gorp.file) r]
+ exec <@$f [interpreter] $path(cat)
+} -cleanup {
+ close $f
+} -result {Just a few thoughts}
+
+# I/O redirection: standard error through a pipeline.
+
+test exec-6.1 {redirecting stderr through a pipeline} {exec stdio} {
+ exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar" |& [interpreter] $path(cat)
+} "foo bar"
+test exec-6.2 {redirecting stderr through a pipeline} {exec stdio} {
+ exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" |& [interpreter] $path(cat)
+} "foo bar"
+test exec-6.3 {redirecting stderr through a pipeline} {exec stdio} {
+ exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" \
+ |& [interpreter] $path(sh) -c "\"$path(echo)\" second msg 1>&2 ; \"$path(cat)\"" |& [interpreter] $path(cat)
+} "second msg\nfoo bar"
+
+# I/O redirection: combinations.
+
+set path(gorp.file2) [makeFile {} gorp.file2]
+file delete $path(gorp.file2)
+
+test exec-7.1 {multiple I/O redirections} {exec} {
+ exec << "command input" > $path(gorp.file2) [interpreter] $path(cat) < $path(gorp.file)
+ exec [interpreter] $path(cat) $path(gorp.file2)
+} {Just a few thoughts}
+test exec-7.2 {multiple I/O redirections} {exec} {
+ exec < $path(gorp.file) << "command input" [interpreter] $path(cat)
+} {command input}
+
+# Long input to command and output from command.
+set a "0123456789 xxxxxxxxx abcdefghi ABCDEFGHIJK\n"
+set a [concat $a $a $a $a]
+set a [concat $a $a $a $a]
+set a [concat $a $a $a $a]
+set a [concat $a $a $a $a]
+test exec-8.1 {long input and output} {exec} {
+ exec [interpreter] $path(cat) << $a
+} $a
+# More than 20 arguments to exec.
+test exec-8.2 {long input and output} {exec} {
+ exec [interpreter] $path(echo) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23}
+
+# Commands that return errors.
+
+test exec-9.1 {commands returning errors} {exec} {
+ set x [catch {exec gorp456} msg]
+ list $x [string tolower $msg] [string tolower $errorCode]
+} {1 {couldn't execute "gorp456": no such file or directory} {posix enoent {no such file or directory}}}
+test exec-9.2 {commands returning errors} {exec} {
+ string tolower [list [catch {exec [interpreter] echo foo | foo123} msg] $msg $errorCode]
+} {1 {couldn't execute "foo123": no such file or directory} {posix enoent {no such file or directory}}}
+test exec-9.3 {commands returning errors} -constraints {exec stdio} -body {
+ exec [interpreter] $path(sleep) 1 | [interpreter] $path(exit) 43 | [interpreter] $path(sleep) 1
+} -returnCodes error -result {child process exited abnormally}
+test exec-9.4 {commands returning errors} -constraints {exec stdio} -body {
+ exec [interpreter] $path(exit) 43 | [interpreter] $path(echo) "foo bar"
+} -returnCodes error -result {foo bar
+child process exited abnormally}
+test exec-9.5 {commands returning errors} -constraints {exec stdio} -body {
+ exec gorp456 | [interpreter] echo a b c
+} -returnCodes error -result {couldn't execute "gorp456": no such file or directory}
+test exec-9.6 {commands returning errors} -constraints {exec} -body {
+ exec [interpreter] $path(sh) -c "\"$path(echo)\" error msg 1>&2"
+} -returnCodes error -result {error msg}
+test exec-9.7 {commands returning errors} -constraints {exec stdio nonPortable} -body {
+ # This test can fail easily on multiprocessor machines
+ exec [interpreter] $path(sh) -c "\"$path(echo)\" error msg 1>&2 ; \"$path(sleep)\" 1" \
+ | [interpreter] $path(sh) -c "\"$path(echo)\" error msg 1>&2 ; \"$path(sleep)\" 1"
+} -returnCodes error -result {error msg
+error msg}
+set path(err) [makeFile {} err]
+test exec-9.8 {commands returning errors} -constraints {exec} -setup {
+ set f [open $path(err) w]
+ puts $f {
+ puts stdout out
+ puts stderr err
+ }
+ close $f
+} -body {
+ exec [interpreter] $path(err)
+} -returnCodes error -result {out
+err}
+
+# Errors in executing the Tcl command, as opposed to errors in the processes
+# that are invoked.
+
+test exec-10.1 {errors in exec invocation} -constraints {exec} -body {
+ exec
+} -returnCodes error -result {wrong # args: should be "exec ?-switch ...? arg ?arg ...?"}
+test exec-10.2 {errors in exec invocation} -constraints {exec} -body {
+ exec | cat
+} -returnCodes error -result {illegal use of | or |& in command}
+test exec-10.3 {errors in exec invocation} -constraints {exec} -body {
+ exec cat |
+} -returnCodes error -result {illegal use of | or |& in command}
+test exec-10.4 {errors in exec invocation} -constraints {exec} -body {
+ exec cat | | cat
+} -returnCodes error -result {illegal use of | or |& in command}
+test exec-10.5 {errors in exec invocation} -constraints {exec} -body {
+ exec cat | |& cat
+} -returnCodes error -result {illegal use of | or |& in command}
+test exec-10.6 {errors in exec invocation} -constraints {exec} -body {
+ exec cat |&
+} -returnCodes error -result {illegal use of | or |& in command}
+test exec-10.7 {errors in exec invocation} -constraints {exec} -body {
+ exec cat <
+} -returnCodes error -result {can't specify "<" as last word in command}
+test exec-10.8 {errors in exec invocation} -constraints {exec} -body {
+ exec cat >
+} -returnCodes error -result {can't specify ">" as last word in command}
+test exec-10.9 {errors in exec invocation} -constraints {exec} -body {
+ exec cat <<
+} -returnCodes error -result {can't specify "<<" as last word in command}
+test exec-10.10 {errors in exec invocation} -constraints {exec} -body {
+ exec cat >>
+} -returnCodes error -result {can't specify ">>" as last word in command}
+test exec-10.11 {errors in exec invocation} -constraints {exec} -body {
+ exec cat >&
+} -returnCodes error -result {can't specify ">&" as last word in command}
+test exec-10.12 {errors in exec invocation} -constraints {exec} -body {
+ exec cat >>&
+} -returnCodes error -result {can't specify ">>&" as last word in command}
+test exec-10.13 {errors in exec invocation} -constraints {exec} -body {
+ exec cat >@
+} -returnCodes error -result {can't specify ">@" as last word in command}
+test exec-10.14 {errors in exec invocation} -constraints {exec} -body {
+ exec cat <@
+} -returnCodes error -result {can't specify "<@" as last word in command}
+test exec-10.15 {errors in exec invocation} -constraints {exec} -body {
+ exec cat < a/b/c
+} -returnCodes error -result {couldn't read file "a/b/c": no such file or directory}
+test exec-10.16 {errors in exec invocation} -constraints {exec} -body {
+ exec cat << foo > a/b/c
+} -returnCodes error -result {couldn't write file "a/b/c": no such file or directory}
+test exec-10.17 {errors in exec invocation} -constraints {exec} -body {
+ exec cat << foo > a/b/c
+} -returnCodes error -result {couldn't write file "a/b/c": no such file or directory}
+set f [open $path(gorp.file) w]
+test exec-10.18 {errors in exec invocation} -constraints {exec} -body {
+ exec cat <@ $f
+} -returnCodes error -result "channel \"$f\" wasn't opened for reading"
+close $f
+set f [open $path(gorp.file) r]
+test exec-10.19 {errors in exec invocation} -constraints {exec} -body {
+ exec cat >@ $f
+} -returnCodes error -result "channel \"$f\" wasn't opened for writing"
+close $f
+test exec-10.20 {errors in exec invocation} -constraints {exec} -body {
+ exec ~non_existent_user/foo/bar
+} -returnCodes error -result {user "non_existent_user" doesn't exist}
+test exec-10.21 {errors in exec invocation} -constraints {exec} -body {
+ exec [interpreter] true | ~xyzzy_bad_user/x | false
+} -returnCodes error -result {user "xyzzy_bad_user" doesn't exist}
+test exec-10.22 {errors in exec invocation} -constraints exec -body {
+ exec echo test > ~non_existent_user/foo/bar
+} -returnCodes error -result {user "non_existent_user" doesn't exist}
+# Commands in background.
+
+test exec-11.1 {commands in background} {exec} {
+ set time [time {exec [interpreter] $path(sleep) 2 &}]
+ expr {[lindex $time 0] < 1000000}
+} 1
+test exec-11.2 {commands in background} -constraints {exec} -body {
+ exec [interpreter] $path(echo) a &b
+} -result {a &b}
+test exec-11.3 {commands in background} {exec} {
+ llength [exec [interpreter] $path(sleep) 1 &]
+} 1
+test exec-11.4 {commands in background} {exec stdio} {
+ llength [exec [interpreter] $path(sleep) 1 | [interpreter] $path(sleep) 1 | [interpreter] $path(sleep) 1 &]
+} 3
+test exec-11.5 {commands in background} {exec} {
+ set f [open $path(gorp.file) w]
+ puts $f [list catch [list exec [info nameofexecutable] $path(echo) foo &]]
+ close $f
+ exec [interpreter] $path(gorp.file)
+} foo
+
+# Make sure that background commands are properly reaped when they
+# eventually die.
+
+if {[testConstraint exec] && [testConstraint nonPortable]} {
+ after 1300
+ exec [interpreter] $path(sleep) 1
+}
+test exec-12.1 {reaping background processes} {exec unix nonPortable} {
+ for {set i 0} {$i < 20} {incr i} {
+ exec echo foo > /dev/null &
+ }
+ after 1000
+ catch {exec ps | fgrep "echo foo" | fgrep -v fgrep | wc} msg
+ lindex $msg 0
+} 0
+test exec-12.2 {reaping background processes} {exec unix nonPortable} {
+ exec sleep 2 | sleep 2 | sleep 2 &
+ catch {exec ps | fgrep -i "sleep" | fgrep -i -v fgrep | wc} msg
+ set x [lindex $msg 0]
+ after 3000
+ catch {exec ps | fgrep -i "sleep" | fgrep -i -v fgrep | wc} msg
+ list $x [lindex $msg 0]
+} {3 0}
+test exec-12.3 {reaping background processes} {exec unix nonPortable} {
+ exec sleep 1000 &
+ exec sleep 1000 &
+ set x [exec ps | fgrep "sleep" | fgrep -v fgrep]
+ set pids {}
+ foreach i [split $x \n] {
+ lappend pids [lindex $i 0]
+ }
+ foreach i $pids {
+ catch {exec kill -STOP $i}
+ }
+ catch {exec ps | fgrep "sleep" | fgrep -v fgrep | wc} msg
+ set x [lindex $msg 0]
+ foreach i $pids {
+ catch {exec kill -KILL $i}
+ }
+ catch {exec ps | fgrep "sleep" | fgrep -v fgrep | wc} msg
+ list $x [lindex $msg 0]
+} {2 0}
+
+# Make sure "errorCode" is set correctly.
+
+test exec-13.1 {setting errorCode variable} {exec} {
+ list [catch {exec [interpreter] $path(cat) < a/b/c} msg] [string tolower $errorCode]
+} {1 {posix enoent {no such file or directory}}}
+test exec-13.2 {setting errorCode variable} {exec} {
+ list [catch {exec [interpreter] $path(cat) > a/b/c} msg] [string tolower $errorCode]
+} {1 {posix enoent {no such file or directory}}}
+test exec-13.3 {setting errorCode variable} {exec} {
+ set x [catch {exec _weird_cmd_} msg]
+ list $x [string tolower $msg] [lindex $errorCode 0] \
+ [string tolower [lrange $errorCode 2 end]]
+} {1 {couldn't execute "_weird_cmd_": no such file or directory} POSIX {{no such file or directory}}}
+test exec-13.4 {extended exit result codes} -setup {
+ set tmp [makeFile {exit 0x00000101} tmpfile.exec-13.4]
+} -constraints {win} -body {
+ list [catch {exec [interpreter] $tmp} err] [lreplace $::errorCode 1 1 {}]
+} -cleanup {
+ removeFile $tmp
+} -result {1 {CHILDSTATUS {} 257}}
+test exec-13.5 {extended exit result codes: max value} -setup {
+ set tmp [makeFile {exit 0x3fffffff} tmpfile.exec-13.5]
+} -constraints {win} -body {
+ list [catch {exec [interpreter] $tmp} err] [lreplace $::errorCode 1 1 {}]
+} -cleanup {
+ removeFile $tmp
+} -result {1 {CHILDSTATUS {} 1073741823}}
+test exec-13.6 {extended exit result codes: signalled} -setup {
+ set tmp [makeFile {exit 0xC0000016} tmpfile.exec-13.6]
+} -constraints {win} -body {
+ list [catch {exec [interpreter] $tmp} err] [lreplace $::errorCode 1 1 {}]
+} -cleanup {
+ removeFile $tmp
+} -result {1 {CHILDKILLED {} SIGABRT SIGABRT}}
+
+# Switches before the first argument
+
+test exec-14.1 {-keepnewline switch} {exec} {
+ exec -keepnewline [interpreter] $path(echo) foo
+} "foo\n"
+test exec-14.2 {-keepnewline switch} -constraints {exec} -body {
+ exec -keepnewline
+} -returnCodes error -result {wrong # args: should be "exec ?-switch ...? arg ?arg ...?"}
+test exec-14.3 {unknown switch} -constraints {exec} -body {
+ exec -gorp
+} -returnCodes error -result {bad switch "-gorp": must be -ignorestderr, -keepnewline, or --}
+test exec-14.4 {-- switch} -constraints {exec} -body {
+ exec -- -gorp
+} -returnCodes error -result {couldn't execute "-gorp": no such file or directory}
+test exec-14.5 {-ignorestderr switch} {exec} {
+ # Alas, the use of -ignorestderr is buried here :-(
+ exec [interpreter] $path(sh2) -c [list $path(echo2) foo bar] 2>@1
+} "foo bar\nbar"
+
+# Redirecting standard error separately from standard output
+
+test exec-15.1 {standard error redirection} {exec} {
+ exec [interpreter] $path(echo) "First line" > $path(gorp.file)
+ list [exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" 2> $path(gorp.file)] \
+ [exec [interpreter] $path(cat) $path(gorp.file)]
+} {{} {foo bar}}
+test exec-15.2 {standard error redirection} {exec stdio} {
+ list [exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" \
+ | [interpreter] $path(echo) biz baz >$path(gorp.file) 2> $path(gorp.file2)] \
+ [exec [interpreter] $path(cat) $path(gorp.file)] \
+ [exec [interpreter] $path(cat) $path(gorp.file2)]
+} {{} {biz baz} {foo bar}}
+test exec-15.3 {standard error redirection} {exec stdio} {
+ list [exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" \
+ | [interpreter] $path(echo) biz baz 2>$path(gorp.file) > $path(gorp.file2)] \
+ [exec [interpreter] $path(cat) $path(gorp.file)] \
+ [exec [interpreter] $path(cat) $path(gorp.file2)]
+} {{} {foo bar} {biz baz}}
+test exec-15.4 {standard error redirection} {exec} {
+ set f [open $path(gorp.file) w]
+ puts $f "Line 1"
+ flush $f
+ exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" 2>@ $f
+ puts $f "Line 3"
+ close $f
+ readfile $path(gorp.file)
+} {Line 1
+foo bar
+Line 3}
+test exec-15.5 {standard error redirection} {exec} {
+ exec [interpreter] $path(echo) "First line" > "$path(gorp.file)"
+ exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" 2>> "$path(gorp.file)"
+ readfile $path(gorp.file)
+} {First line
+foo bar}
+test exec-15.6 {standard error redirection} {exec stdio} {
+ exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" > "$path(gorp.file2)" 2> "$path(gorp.file)" \
+ >& "$path(gorp.file)" 2> "$path(gorp.file2)" | [interpreter] $path(echo) biz baz
+ list [readfile $path(gorp.file)] [readfile $path(gorp.file2)]
+} {{biz baz} {foo bar}}
+test exec-15.7 {standard error redirection 2>@1} {exec stdio} {
+ # This redirects stderr output into normal result output from exec
+ exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" 2>@1
+} {foo bar}
+
+test exec-16.1 {flush output before exec} {exec} {
+ set f [open $path(gorp.file) w]
+ puts $f "First line"
+ exec [interpreter] $path(echo) "Second line" >@ $f
+ puts $f "Third line"
+ close $f
+ readfile $path(gorp.file)
+} {First line
+Second line
+Third line}
+test exec-16.2 {flush output before exec} {exec} {
+ set f [open $path(gorp.file) w]
+ puts $f "First line"
+ exec [interpreter] << {puts stderr {Second line}} >&@ $f > $path(gorp.file2)
+ puts $f "Third line"
+ close $f
+ readfile $path(gorp.file)
+} {First line
+Second line
+Third line}
+
+test exec-17.1 {inheriting standard I/O} -constraints {exec} -setup {
+ set path(script) [makeFile {} script]
+ set f [open $path(script) w]
+ puts $f [list lassign [list \
+ [info nameofexecutable] $path(gorp.file) $path(echo) $path(sleep) \
+ ] exe file echo sleep]
+ puts $f {
+ close stdout
+ set f [open $file w]
+ catch {exec $exe $echo foobar &}
+ exec $exe $sleep 2
+ close $f
+ }
+ close $f
+} -body {
+ catch {exec [interpreter] $path(script)} result
+ list $result [readfile $path(gorp.file)]
+} -cleanup {
+ removeFile $path(script)
+} -result {{} foobar}
+
+test exec-18.1 {exec deals with weird file names} -body {
+ set path(fooblah) [makeFile {contents} "foo\[\{blah"]
+ exec [interpreter] $path(cat) $path(fooblah)
+} -constraints {exec} -cleanup {
+ removeFile $path(fooblah)
+} -result contents
+test exec-18.2 {exec cat deals with weird file names} -body {
+ # This is cross-platform, but the cat isn't predictably correct on
+ # Windows.
+ set path(fooblah) [makeFile {contents} "foo\[\{blah"]
+ exec cat $path(fooblah)
+} -constraints {exec tempNotWin} -cleanup {
+ removeFile $path(fooblah)
+} -result contents
+
+# Note that this test cannot be adapted to work on Windows; that platform has
+# no kernel support for an analog of O_APPEND. OTOH, that means we can assume
+# that there is a POSIX shell...
+test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix} -setup {
+ set tmpfile [makeFile {0} tmpfile.exec-19.1]
+} -body {
+ # Note that we have to allow for the current contents of the temporary
+ # file, which is why the result is 14 and not 12
+ exec /bin/sh -c \
+ {for a in 1 2 3; do sleep 1; echo $a; done} >>$tmpfile &
+ exec /bin/sh -c \
+ {for a in a b c; do sleep 1; echo $a; done} >>$tmpfile &
+ # The above two shell invokations take about 3 seconds to finish, so allow
+ # 5s (in case the machine is busy)
+ after 5000
+ # Check that no bytes have got lost through mixups with overlapping
+ # appends, which is only guaranteed to work when we set O_APPEND on the
+ # file descriptor in the [exec >>...]
+ file size $tmpfile
+} -cleanup {
+ removeFile $tmpfile
+} -result 14
+
+# ----------------------------------------------------------------------
+# cleanup
+
+foreach file {gorp.file gorp.file2 echo echo2 cat wc sh sh2 sleep exit err} {
+ removeFile $file
+}
+unset -nocomplain path
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/execute.test b/pkgs/msgcat/tests/execute.test
new file mode 100644
index 0000000..012b3a7
--- /dev/null
+++ b/pkgs/msgcat/tests/execute.test
@@ -0,0 +1,1062 @@
+# This file contains tests for the tclExecute.c source file. Tests appear in
+# the same order as the C code that they test. The set of tests is currently
+# incomplete since it currently includes only new tests for code changed for
+# the addition of Tcl namespaces. Other execution-related tests appear in
+# several other test files including namespace.test, basic.test, eval.test,
+# for.test, etc.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+catch {rename foo ""}
+catch {unset x}
+catch {unset y}
+catch {unset msg}
+
+testConstraint testobj [expr {
+ [llength [info commands testobj]]
+ && [llength [info commands testdoubleobj]]
+ && [llength [info commands teststringobj]]
+}]
+
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+testConstraint testexprlongobj [llength [info commands testexprlongobj]]
+
+# Tests for the omnibus TclExecuteByteCode function:
+
+# INST_DONE not tested
+# INST_PUSH1 not tested
+# INST_PUSH4 not tested
+# INST_POP not tested
+# INST_DUP not tested
+# INST_INVOKE_STK4 not tested
+# INST_INVOKE_STK1 not tested
+# INST_EVAL_STK not tested
+# INST_EXPR_STK not tested
+
+# INST_LOAD_SCALAR1
+test execute-1.1 {TclExecuteByteCode, INST_LOAD_SCALAR1, small opnd} {
+ proc foo {} {
+ set x 1
+ return $x
+ }
+ foo
+} 1
+test execute-1.2 {TclExecuteByteCode, INST_LOAD_SCALAR1, large opnd} {
+ # Bug: 2243
+ set body {}
+ for {set i 0} {$i < 129} {incr i} {
+ append body "set x$i x\n"
+ }
+ append body {
+ set y 1
+ return $y
+ }
+ proc foo {} $body
+ foo
+} 1
+test execute-1.3 {TclExecuteByteCode, INST_LOAD_SCALAR1, error} {
+ proc foo {} {
+ set x 1
+ unset x
+ return $x
+ }
+ list [catch {foo} msg] $msg
+} {1 {can't read "x": no such variable}}
+
+# INST_LOAD_SCALAR4
+test execute-2.1 {TclExecuteByteCode, INST_LOAD_SCALAR4, simple case} {
+ set body {}
+ for {set i 0} {$i < 256} {incr i} {
+ append body "set x$i x\n"
+ }
+ append body {
+ set y 1
+ return $y
+ }
+ proc foo {} $body
+ foo
+} 1
+test execute-2.2 {TclExecuteByteCode, INST_LOAD_SCALAR4, error} {
+ set body {}
+ for {set i 0} {$i < 256} {incr i} {
+ append body "set x$i x\n"
+ }
+ append body {
+ set y 1
+ unset y
+ return $y
+ }
+ proc foo {} $body
+ list [catch {foo} msg] $msg
+} {1 {can't read "y": no such variable}}
+
+# INST_LOAD_SCALAR_STK not tested
+# INST_LOAD_ARRAY4 not tested
+# INST_LOAD_ARRAY1 not tested
+# INST_LOAD_ARRAY_STK not tested
+# INST_LOAD_STK not tested
+# INST_STORE_SCALAR4 not tested
+# INST_STORE_SCALAR1 not tested
+# INST_STORE_SCALAR_STK not tested
+# INST_STORE_ARRAY4 not tested
+# INST_STORE_ARRAY1 not tested
+# INST_STORE_ARRAY_STK not tested
+# INST_STORE_STK not tested
+# INST_INCR_SCALAR1 not tested
+# INST_INCR_SCALAR_STK not tested
+# INST_INCR_STK not tested
+# INST_INCR_ARRAY1 not tested
+# INST_INCR_ARRAY_STK not tested
+# INST_INCR_SCALAR1_IMM not tested
+# INST_INCR_SCALAR_STK_IMM not tested
+# INST_INCR_STK_IMM not tested
+# INST_INCR_ARRAY1_IMM not tested
+# INST_INCR_ARRAY_STK_IMM not tested
+# INST_JUMP1 not tested
+# INST_JUMP4 not tested
+# INST_JUMP_TRUE4 not tested
+# INST_JUMP_TRUE1 not tested
+# INST_JUMP_FALSE4 not tested
+# INST_JUMP_FALSE1 not tested
+# INST_LOR not tested
+# INST_LAND not tested
+# INST_EQ not tested
+# INST_NEQ not tested
+# INST_LT not tested
+# INST_GT not tested
+# INST_LE not tested
+# INST_GE not tested
+# INST_MOD not tested
+# INST_LSHIFT not tested
+# INST_RSHIFT not tested
+# INST_BITOR not tested
+# INST_BITXOR not tested
+# INST_BITAND not tested
+
+# INST_ADD is partially tested:
+test execute-3.1 {TclExecuteByteCode, INST_ADD, op1 is int} {testobj} {
+ set x [testintobj set 0 1]
+ expr {$x + 1}
+} 2
+test execute-3.2 {TclExecuteByteCode, INST_ADD, op1 is double} {testobj} {
+ set x [testdoubleobj set 0 1]
+ expr {$x + 1}
+} 2.0
+test execute-3.3 {TclExecuteByteCode, INST_ADD, op1 is double with string} {testobj} {
+ set x [testintobj set 0 1]
+ testobj convert 0 double
+ expr {$x + 1}
+} 2
+test execute-3.4 {TclExecuteByteCode, INST_ADD, op1 is string int} {testobj} {
+ set x [teststringobj set 0 1]
+ expr {$x + 1}
+} 2
+test execute-3.5 {TclExecuteByteCode, INST_ADD, op1 is string double} {testobj} {
+ set x [teststringobj set 0 1.0]
+ expr {$x + 1}
+} 2.0
+test execute-3.6 {TclExecuteByteCode, INST_ADD, op1 is non-numeric} {testobj} {
+ set x [teststringobj set 0 foo]
+ list [catch {expr {$x + 1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test execute-3.7 {TclExecuteByteCode, INST_ADD, op2 is int} {testobj} {
+ set x [testintobj set 0 1]
+ expr {1 + $x}
+} 2
+test execute-3.8 {TclExecuteByteCode, INST_ADD, op2 is double} {testobj} {
+ set x [testdoubleobj set 0 1]
+ expr {1 + $x}
+} 2.0
+test execute-3.9 {TclExecuteByteCode, INST_ADD, op2 is double with string} {testobj} {
+ set x [testintobj set 0 1]
+ testobj convert 0 double
+ expr {1 + $x}
+} 2
+test execute-3.10 {TclExecuteByteCode, INST_ADD, op2 is string int} {testobj} {
+ set x [teststringobj set 0 1]
+ expr {1 + $x}
+} 2
+test execute-3.11 {TclExecuteByteCode, INST_ADD, op2 is string double} {testobj} {
+ set x [teststringobj set 0 1.0]
+ expr {1 + $x}
+} 2.0
+test execute-3.12 {TclExecuteByteCode, INST_ADD, op2 is non-numeric} {testobj} {
+ set x [teststringobj set 0 foo]
+ list [catch {expr {1 + $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+
+# INST_SUB is partially tested:
+test execute-3.13 {TclExecuteByteCode, INST_SUB, op1 is int} {testobj} {
+ set x [testintobj set 0 1]
+ expr {$x - 1}
+} 0
+test execute-3.14 {TclExecuteByteCode, INST_SUB, op1 is double} {testobj} {
+ set x [testdoubleobj set 0 1]
+ expr {$x - 1}
+} 0.0
+test execute-3.15 {TclExecuteByteCode, INST_SUB, op1 is double with string} {testobj} {
+ set x [testintobj set 0 1]
+ testobj convert 0 double
+ expr {$x - 1}
+} 0
+test execute-3.16 {TclExecuteByteCode, INST_SUB, op1 is string int} {testobj} {
+ set x [teststringobj set 0 1]
+ expr {$x - 1}
+} 0
+test execute-3.17 {TclExecuteByteCode, INST_SUB, op1 is string double} {testobj} {
+ set x [teststringobj set 0 1.0]
+ expr {$x - 1}
+} 0.0
+test execute-3.18 {TclExecuteByteCode, INST_SUB, op1 is non-numeric} {testobj} {
+ set x [teststringobj set 0 foo]
+ list [catch {expr {$x - 1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+test execute-3.19 {TclExecuteByteCode, INST_SUB, op2 is int} {testobj} {
+ set x [testintobj set 0 1]
+ expr {1 - $x}
+} 0
+test execute-3.20 {TclExecuteByteCode, INST_SUB, op2 is double} {testobj} {
+ set x [testdoubleobj set 0 1]
+ expr {1 - $x}
+} 0.0
+test execute-3.21 {TclExecuteByteCode, INST_SUB, op2 is double with string} {testobj} {
+ set x [testintobj set 0 1]
+ testobj convert 0 double
+ expr {1 - $x}
+} 0
+test execute-3.22 {TclExecuteByteCode, INST_SUB, op2 is string int} {testobj} {
+ set x [teststringobj set 0 1]
+ expr {1 - $x}
+} 0
+test execute-3.23 {TclExecuteByteCode, INST_SUB, op2 is string double} {testobj} {
+ set x [teststringobj set 0 1.0]
+ expr {1 - $x}
+} 0.0
+test execute-3.24 {TclExecuteByteCode, INST_SUB, op2 is non-numeric} {testobj} {
+ set x [teststringobj set 0 foo]
+ list [catch {expr {1 - $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+
+# INST_MULT is partially tested:
+test execute-3.25 {TclExecuteByteCode, INST_MULT, op1 is int} {testobj} {
+ set x [testintobj set 1 1]
+ expr {$x * 1}
+} 1
+test execute-3.26 {TclExecuteByteCode, INST_MULT, op1 is double} {testobj} {
+ set x [testdoubleobj set 1 2.0]
+ expr {$x * 1}
+} 2.0
+test execute-3.27 {TclExecuteByteCode, INST_MULT, op1 is double with string} {testobj} {
+ set x [testintobj set 1 2]
+ testobj convert 1 double
+ expr {$x * 1}
+} 2
+test execute-3.28 {TclExecuteByteCode, INST_MULT, op1 is string int} {testobj} {
+ set x [teststringobj set 1 1]
+ expr {$x * 1}
+} 1
+test execute-3.29 {TclExecuteByteCode, INST_MULT, op1 is string double} {testobj} {
+ set x [teststringobj set 1 1.0]
+ expr {$x * 1}
+} 1.0
+test execute-3.30 {TclExecuteByteCode, INST_MULT, op1 is non-numeric} {testobj} {
+ set x [teststringobj set 1 foo]
+ list [catch {expr {$x * 1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "*"}}
+test execute-3.31 {TclExecuteByteCode, INST_MULT, op2 is int} {testobj} {
+ set x [testintobj set 1 1]
+ expr {1 * $x}
+} 1
+test execute-3.32 {TclExecuteByteCode, INST_MULT, op2 is double} {testobj} {
+ set x [testdoubleobj set 1 2.0]
+ expr {1 * $x}
+} 2.0
+test execute-3.33 {TclExecuteByteCode, INST_MULT, op2 is double with string} {testobj} {
+ set x [testintobj set 1 2]
+ testobj convert 1 double
+ expr {1 * $x}
+} 2
+test execute-3.34 {TclExecuteByteCode, INST_MULT, op2 is string int} {testobj} {
+ set x [teststringobj set 1 1]
+ expr {1 * $x}
+} 1
+test execute-3.35 {TclExecuteByteCode, INST_MULT, op2 is string double} {testobj} {
+ set x [teststringobj set 1 1.0]
+ expr {1 * $x}
+} 1.0
+test execute-3.36 {TclExecuteByteCode, INST_MULT, op2 is non-numeric} {testobj} {
+ set x [teststringobj set 1 foo]
+ list [catch {expr {1 * $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "*"}}
+
+# INST_DIV is partially tested:
+test execute-3.37 {TclExecuteByteCode, INST_DIV, op1 is int} {testobj} {
+ set x [testintobj set 1 1]
+ expr {$x / 1}
+} 1
+test execute-3.38 {TclExecuteByteCode, INST_DIV, op1 is double} {testobj} {
+ set x [testdoubleobj set 1 2.0]
+ expr {$x / 1}
+} 2.0
+test execute-3.39 {TclExecuteByteCode, INST_DIV, op1 is double with string} {testobj} {
+ set x [testintobj set 1 2]
+ testobj convert 1 double
+ expr {$x / 1}
+} 2
+test execute-3.40 {TclExecuteByteCode, INST_DIV, op1 is string int} {testobj} {
+ set x [teststringobj set 1 1]
+ expr {$x / 1}
+} 1
+test execute-3.41 {TclExecuteByteCode, INST_DIV, op1 is string double} {testobj} {
+ set x [teststringobj set 1 1.0]
+ expr {$x / 1}
+} 1.0
+test execute-3.42 {TclExecuteByteCode, INST_DIV, op1 is non-numeric} {testobj} {
+ set x [teststringobj set 1 foo]
+ list [catch {expr {$x / 1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+test execute-3.43 {TclExecuteByteCode, INST_DIV, op2 is int} {testobj} {
+ set x [testintobj set 1 1]
+ expr {2 / $x}
+} 2
+test execute-3.44 {TclExecuteByteCode, INST_DIV, op2 is double} {testobj} {
+ set x [testdoubleobj set 1 1.0]
+ expr {2 / $x}
+} 2.0
+test execute-3.45 {TclExecuteByteCode, INST_DIV, op2 is double with string} {testobj} {
+ set x [testintobj set 1 1]
+ testobj convert 1 double
+ expr {2 / $x}
+} 2
+test execute-3.46 {TclExecuteByteCode, INST_DIV, op2 is string int} {testobj} {
+ set x [teststringobj set 1 1]
+ expr {2 / $x}
+} 2
+test execute-3.47 {TclExecuteByteCode, INST_DIV, op2 is string double} {testobj} {
+ set x [teststringobj set 1 1.0]
+ expr {2 / $x}
+} 2.0
+test execute-3.48 {TclExecuteByteCode, INST_DIV, op2 is non-numeric} {testobj} {
+ set x [teststringobj set 1 foo]
+ list [catch {expr {1 / $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+
+# INST_UPLUS is partially tested:
+test execute-3.49 {TclExecuteByteCode, INST_UPLUS, op is int} {testobj} {
+ set x [testintobj set 1 1]
+ expr {+ $x}
+} 1
+test execute-3.50 {TclExecuteByteCode, INST_UPLUS, op is double} {testobj} {
+ set x [testdoubleobj set 1 1.0]
+ expr {+ $x}
+} 1.0
+test execute-3.51 {TclExecuteByteCode, INST_UPLUS, op is double with string} {testobj} {
+ set x [testintobj set 1 1]
+ testobj convert 1 double
+ expr {+ $x}
+} 1
+test execute-3.52 {TclExecuteByteCode, INST_UPLUS, op is string int} {testobj} {
+ set x [teststringobj set 1 1]
+ expr {+ $x}
+} 1
+test execute-3.53 {TclExecuteByteCode, INST_UPLUS, op is string double} {testobj} {
+ set x [teststringobj set 1 1.0]
+ expr {+ $x}
+} 1.0
+test execute-3.54 {TclExecuteByteCode, INST_UPLUS, op is non-numeric} {testobj} {
+ set x [teststringobj set 1 foo]
+ list [catch {expr {+ $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+
+# INST_UMINUS is partially tested:
+test execute-3.55 {TclExecuteByteCode, INST_UMINUS, op is int} {testobj} {
+ set x [testintobj set 1 1]
+ expr {- $x}
+} -1
+test execute-3.56 {TclExecuteByteCode, INST_UMINUS, op is double} {testobj} {
+ set x [testdoubleobj set 1 1.0]
+ expr {- $x}
+} -1.0
+test execute-3.57 {TclExecuteByteCode, INST_UMINUS, op is double with string} {testobj} {
+ set x [testintobj set 1 1]
+ testobj convert 1 double
+ expr {- $x}
+} -1
+test execute-3.58 {TclExecuteByteCode, INST_UMINUS, op is string int} {testobj} {
+ set x [teststringobj set 1 1]
+ expr {- $x}
+} -1
+test execute-3.59 {TclExecuteByteCode, INST_UMINUS, op is string double} {testobj} {
+ set x [teststringobj set 1 1.0]
+ expr {- $x}
+} -1.0
+test execute-3.60 {TclExecuteByteCode, INST_UMINUS, op is non-numeric} {testobj} {
+ set x [teststringobj set 1 foo]
+ list [catch {expr {- $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+
+# INST_LNOT is partially tested:
+test execute-3.61 {TclExecuteByteCode, INST_LNOT, op is int} {testobj} {
+ set x [testintobj set 1 2]
+ expr {! $x}
+} 0
+test execute-3.62 {TclExecuteByteCode, INST_LNOT, op is int} {testobj} {
+ set x [testintobj set 1 0]
+ expr {! $x}
+} 1
+test execute-3.63 {TclExecuteByteCode, INST_LNOT, op is double} {testobj} {
+ set x [testdoubleobj set 1 1.0]
+ expr {! $x}
+} 0
+test execute-3.64 {TclExecuteByteCode, INST_LNOT, op is double} {testobj} {
+ set x [testdoubleobj set 1 0.0]
+ expr {! $x}
+} 1
+test execute-3.65 {TclExecuteByteCode, INST_LNOT, op is double with string} {testobj} {
+ set x [testintobj set 1 1]
+ testobj convert 1 double
+ expr {! $x}
+} 0
+test execute-3.66 {TclExecuteByteCode, INST_LNOT, op is double with string} {testobj} {
+ set x [testintobj set 1 0]
+ testobj convert 1 double
+ expr {! $x}
+} 1
+test execute-3.67 {TclExecuteByteCode, INST_LNOT, op is string int} {testobj} {
+ set x [teststringobj set 1 1]
+ expr {! $x}
+} 0
+test execute-3.68 {TclExecuteByteCode, INST_LNOT, op is string int} {testobj} {
+ set x [teststringobj set 1 0]
+ expr {! $x}
+} 1
+test execute-3.69 {TclExecuteByteCode, INST_LNOT, op is string double} {testobj} {
+ set x [teststringobj set 1 1.0]
+ expr {! $x}
+} 0
+test execute-3.70 {TclExecuteByteCode, INST_LNOT, op is string double} {testobj} {
+ set x [teststringobj set 1 0.0]
+ expr {! $x}
+} 1
+test execute-3.71 {TclExecuteByteCode, INST_LNOT, op is non-numeric} {testobj} {
+ set x [teststringobj set 1 foo]
+ list [catch {expr {! $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "!"}}
+
+# INST_BITNOT not tested
+# INST_CALL_BUILTIN_FUNC1 not tested
+# INST_CALL_FUNC1 not tested
+
+# INST_TRY_CVT_TO_NUMERIC is partially tested:
+test execute-3.72 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is int} {testobj} {
+ set x [testintobj set 1 1]
+ expr {$x}
+} 1
+test execute-3.73 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is double} {testobj} {
+ set x [testdoubleobj set 1 1.0]
+ expr {$x}
+} 1.0
+test execute-3.74 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is double with string} {testobj} {
+ set x [testintobj set 1 1]
+ testobj convert 1 double
+ expr {$x}
+} 1
+test execute-3.75 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is string int} {testobj} {
+ set x [teststringobj set 1 1]
+ expr {$x}
+} 1
+test execute-3.76 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is string double} {testobj} {
+ set x [teststringobj set 1 1.0]
+ expr {$x}
+} 1.0
+test execute-3.77 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is non-numeric} {testobj} {
+ set x [teststringobj set 1 foo]
+ expr {$x}
+} foo
+
+# INST_BREAK not tested
+# INST_CONTINUE not tested
+# INST_FOREACH_START4 not tested
+# INST_FOREACH_STEP4 not tested
+# INST_BEGIN_CATCH4 not tested
+# INST_END_CATCH not tested
+# INST_PUSH_RESULT not tested
+# INST_PUSH_RETURN_CODE not tested
+
+test execute-4.1 {Tcl_GetCommandFromObj, convert to tclCmdNameType} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ unset -nocomplain x
+ unset -nocomplain y
+} -body {
+ namespace eval test_ns_1 {
+ namespace export cmd1
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ }
+ namespace eval test_ns_1::test_ns_2 {
+ namespace import ::test_ns_1::*
+ }
+ set x "test_ns_1::"
+ set y "test_ns_2::"
+ list [namespace which -command ${x}${y}cmd1] \
+ [catch {namespace which -command ${x}${y}cmd2} msg] $msg \
+ [catch {namespace which -command ${x}${y}:cmd2} msg] $msg
+} -result {::test_ns_1::test_ns_2::cmd1 0 {} 0 {}}
+test execute-4.2 {Tcl_GetCommandFromObj, check if cached tclCmdNameType is invalid} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename foo ""}
+ unset -nocomplain l
+} -body {
+ proc foo {} {
+ return "global foo"
+ }
+ namespace eval test_ns_1 {
+ proc whichFoo {} {
+ return [namespace which -command foo]
+ }
+ }
+ set l ""
+ lappend l [test_ns_1::whichFoo]
+ namespace eval test_ns_1 {
+ proc foo {} {
+ return "namespace foo"
+ }
+ }
+ lappend l [test_ns_1::whichFoo]
+} -result {::foo ::test_ns_1::foo}
+test execute-4.3 {Tcl_GetCommandFromObj, command never found} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename foo ""}
+} -body {
+ namespace eval test_ns_1 {
+ proc foo {} {
+ return "namespace foo"
+ }
+ }
+ namespace eval test_ns_1 {
+ proc foo {} {
+ return "namespace foo"
+ }
+ }
+ list [namespace eval test_ns_1 {namespace which -command foo}] \
+ [rename test_ns_1::foo ""] \
+ [catch {namespace eval test_ns_1 {namespace which -command foo}} msg] $msg
+} -result {::test_ns_1::foo {} 0 {}}
+
+test execute-5.1 {SetCmdNameFromAny, set cmd name to empty heap string if NULL} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ unset -nocomplain l
+} -body {
+ proc {} {} {return {}}
+ {}
+ set l {}
+ lindex {} 0
+ {}
+} -result {}
+
+test execute-6.1 {UpdateStringOfCmdName: called for duplicate of empty cmdName object} {
+ proc {} {} {}
+ proc { } {} {}
+ proc p {} {
+ set x {}
+ $x
+ append x { }
+ $x
+ }
+ p
+} {}
+test execute-6.2 {Evaluate an expression in a variable; compile the first time, do not the second} {
+ set w {3*5}
+ proc a {obj} {expr $obj}
+ set res "[a $w]:[a $w]"
+} {15:15}
+test execute-6.3 {Tcl_ExprObj: don't use cached script bytecode [Bug 1899164]} -setup {
+ proc 0+0 {} {return SCRIPT}
+} -body {
+ set e { 0+0 }
+ if 1 $e
+ if 1 {expr $e}
+} -cleanup {
+ rename 0+0 {}
+} -result 0
+test execute-6.4 {TclCompEvalObj: don't use cached expr bytecode [Bug 1899164]} -setup {
+ proc 0+0 {} {return SCRIPT}
+} -body {
+ set e { 0+0 }
+ if 1 {expr $e}
+ if 1 $e
+} -cleanup {
+ rename 0+0 {}
+} -result SCRIPT
+test execute-6.5 {TclCompEvalObj: bytecode epoch validation} -body {
+ set script { llength {} }
+ set result {}
+ lappend result [if 1 $script]
+ set origName [namespace which llength]
+ rename $origName llength.orig
+ proc $origName {args} {return AHA!}
+ lappend result [if 1 $script]
+} -cleanup {
+ rename $origName {}
+ rename llength.orig $origName
+} -result {0 AHA!}
+test execute-6.6 {TclCompEvalObj: proc-body bytecode invalid for script} -body {
+ proc foo {} {set a 1}
+ set a untouched
+ set result {}
+ lappend result [foo] $a
+ lappend result [if 1 [info body foo]] $a
+} -cleanup {
+ rename foo {}
+} -result {1 untouched 1 1}
+test execute-6.7 {TclCompEvalObj: bytecode context validation} -setup {
+ namespace eval foo {}
+} -body {
+ set script { llength {} }
+ namespace eval foo {
+ proc llength {args} {return AHA!}
+ }
+ set result {}
+ lappend result [if 1 $script]
+ lappend result [namespace eval foo $script]
+} -cleanup {
+ namespace delete foo
+} -result {0 AHA!}
+test execute-6.8 {TclCompEvalObj: bytecode name resolution epoch validation} -setup {
+ namespace eval foo {}
+} -body {
+ set script { llength {} }
+ set result {}
+ lappend result [namespace eval foo $script]
+ namespace eval foo {
+ proc llength {args} {return AHA!}
+ }
+ lappend result [namespace eval foo $script]
+} -cleanup {
+ namespace delete foo
+} -result {0 AHA!}
+test execute-6.9 {TclCompEvalObj: bytecode interp validation} -setup {
+ interp create slave
+} -body {
+ set script { llength {} }
+ slave eval {proc llength args {return AHA!}}
+ set result {}
+ lappend result [if 1 $script]
+ lappend result [slave eval $script]
+} -cleanup {
+ interp delete slave
+} -result {0 AHA!}
+test execute-6.10 {TclCompEvalObj: bytecode interp validation} -body {
+ set script { llength {} }
+ interp create slave
+ set result {}
+ lappend result [slave eval $script]
+ interp delete slave
+ interp create slave
+ lappend result [slave eval $script]
+} -cleanup {
+ catch {interp delete slave}
+} -result {0 0}
+test execute-6.11 {Tcl_ExprObj: exprcode interp validation} -setup {
+ interp create slave
+} -constraints testexprlongobj -body {
+ set e { [llength {}]+1 }
+ set result {}
+ load {} Tcltest slave
+ interp alias {} e slave testexprlongobj
+ lappend result [e $e]
+ interp delete slave
+ interp create slave
+ load {} Tcltest slave
+ interp alias {} e slave testexprlongobj
+ lappend result [e $e]
+} -cleanup {
+ interp delete slave
+} -result {{This is a result: 1} {This is a result: 1}}
+test execute-6.12 {Tcl_ExprObj: exprcode interp validation} -setup {
+ interp create slave
+} -body {
+ set e { [llength {}]+1 }
+ set result {}
+ interp alias {} e slave expr
+ lappend result [e $e]
+ interp delete slave
+ interp create slave
+ interp alias {} e slave expr
+ lappend result [e $e]
+} -cleanup {
+ interp delete slave
+} -result {1 1}
+test execute-6.13 {Tcl_ExprObj: exprcode epoch validation} -body {
+ set e { [llength {}]+1 }
+ set result {}
+ lappend result [expr $e]
+ set origName [namespace which llength]
+ rename $origName llength.orig
+ proc $origName {args} {return 1}
+ lappend result [expr $e]
+} -cleanup {
+ rename $origName {}
+ rename llength.orig $origName
+} -result {1 2}
+test execute-6.14 {Tcl_ExprObj: exprcode context validation} -setup {
+ namespace eval foo {}
+} -body {
+ set e { [llength {}]+1 }
+ namespace eval foo {
+ proc llength {args} {return 1}
+ }
+ set result {}
+ lappend result [expr $e]
+ lappend result [namespace eval foo {expr $e}]
+} -cleanup {
+ namespace delete foo
+} -result {1 2}
+test execute-6.15 {Tcl_ExprObj: exprcode name resolution epoch validation} -setup {
+ namespace eval foo {}
+} -body {
+ set e { [llength {}]+1 }
+ set result {}
+ lappend result [namespace eval foo {expr $e}]
+ namespace eval foo {
+ proc llength {args} {return 1}
+ }
+ lappend result [namespace eval foo {expr $e}]
+} -cleanup {
+ namespace delete foo
+} -result {1 2}
+test execute-6.16 {Tcl_ExprObj: exprcode interp validation} -setup {
+ interp create slave
+} -body {
+ set e { [llength {}]+1 }
+ interp alias {} e slave expr
+ slave eval {proc llength args {return 1}}
+ set result {}
+ lappend result [expr $e]
+ lappend result [e $e]
+} -cleanup {
+ interp delete slave
+} -result {1 2}
+test execute-6.17 {Tcl_ExprObj: exprcode context validation} -body {
+ proc foo e {set v 0; expr $e}
+ proc bar e {set v 1; expr $e}
+ set e { $v }
+ set result {}
+ lappend result [foo $e]
+ lappend result [bar $e]
+} -cleanup {
+ rename foo {}
+ rename bar {}
+} -result {0 1}
+test execute-6.18 {Tcl_ExprObj: exprcode context validation} -body {
+ proc foo e {set v {}; expr $e}
+ proc bar e {set v v; expr $e}
+ set e { [llength $v] }
+ set result {}
+ lappend result [foo $e]
+ lappend result [bar $e]
+} -cleanup {
+ rename foo {}
+ rename bar {}
+} -result {0 1}
+
+test execute-7.0 {Wide int handling in INST_JUMP_FALSE/LAND} {
+ set x 0x100000000
+ expr {$x && 1}
+} 1
+test execute-7.1 {Wide int handling in INST_JUMP_FALSE/LAND} {
+ expr {0x100000000 && 1}
+} 1
+test execute-7.2 {Wide int handling in INST_JUMP_FALSE/LAND} {
+ expr {1 && 0x100000000}
+} 1
+test execute-7.3 {Wide int handling in INST_JUMP_FALSE/LAND} {
+ expr {wide(0x100000000) && 1}
+} 1
+test execute-7.4 {Wide int handling in INST_JUMP_FALSE/LAND} {
+ expr {1 && wide(0x100000000)}
+} 1
+test execute-7.5 {Wide int handling in INST_EQ} {
+ expr {4 == (wide(1)+wide(3))}
+} 1
+test execute-7.6 {Wide int handling in INST_EQ and [incr]} {
+ set x 399999999999
+ expr {400000000000 == [incr x]}
+} 1
+# wide ints have more bits of precision than doubles, but we convert anyway
+test execute-7.7 {Wide int handling in INST_EQ and [incr]} {
+ set x [expr {wide(1)<<62}]
+ set y [expr {$x+1}]
+ expr {double($x) == double($y)}
+} 1
+test execute-7.8 {Wide int conversions can change sign} longIs32bit {
+ set x 0x80000000
+ expr {int($x) < wide($x)}
+} 1
+test execute-7.9 {Wide int handling in INST_MOD} {
+ expr {(wide(1)<<60) % ((wide(47)<<45)-1)}
+} 316659348800185
+test execute-7.10 {Wide int handling in INST_MOD} {
+ expr {((wide(1)<<60)-1) % 0x400000000}
+} 17179869183
+test execute-7.11 {Wide int handling in INST_LSHIFT} {
+ expr wide(42)<<30
+} 45097156608
+test execute-7.12 {Wide int handling in INST_LSHIFT} {
+ expr 12345678901<<3
+} 98765431208
+test execute-7.13 {Wide int handling in INST_RSHIFT} {
+ expr 0x543210febcda9876>>7
+} 47397893236700464
+test execute-7.14 {Wide int handling in INST_RSHIFT} {
+ expr wide(0x9876543210febcda)>>7
+} -58286587177206407
+test execute-7.15 {Wide int handling in INST_BITOR} {
+ expr wide(0x9876543210febcda) | 0x543210febcda9876
+} -2560765885044310786
+test execute-7.16 {Wide int handling in INST_BITXOR} {
+ expr wide(0x9876543210febcda) ^ 0x543210febcda9876
+} -3727778945703861076
+test execute-7.17 {Wide int handling in INST_BITAND} {
+ expr wide(0x9876543210febcda) & 0x543210febcda9876
+} 1167013060659550290
+test execute-7.18 {Wide int handling in INST_ADD} {
+ expr wide(0x7fffffff)+wide(0x7fffffff)
+} 4294967294
+test execute-7.19 {Wide int handling in INST_ADD} {
+ expr 0x7fffffff+wide(0x7fffffff)
+} 4294967294
+test execute-7.20 {Wide int handling in INST_ADD} {
+ expr wide(0x7fffffff)+0x7fffffff
+} 4294967294
+test execute-7.21 {Wide int handling in INST_ADD} {
+ expr double(0x7fffffff)+wide(0x7fffffff)
+} 4294967294.0
+test execute-7.22 {Wide int handling in INST_ADD} {
+ expr wide(0x7fffffff)+double(0x7fffffff)
+} 4294967294.0
+test execute-7.23 {Wide int handling in INST_SUB} {
+ expr 0x123456789a-0x20406080a
+} 69530054800
+test execute-7.24 {Wide int handling in INST_MULT} {
+ expr 0x123456789a*193
+} 15090186251290
+test execute-7.25 {Wide int handling in INST_DIV} {
+ expr 0x123456789a/193
+} 405116546
+test execute-7.26 {Wide int handling in INST_UPLUS} {
+ set x 0x123456871234568
+ expr {+ $x}
+} 81985533099853160
+test execute-7.27 {Wide int handling in INST_UMINUS} {
+ set x 0x123456871234568
+ expr {- $x}
+} -81985533099853160
+test execute-7.28 {Wide int handling in INST_LNOT} {
+ set x 0x123456871234568
+ expr {! $x}
+} 0
+test execute-7.29 {Wide int handling in INST_BITNOT} {
+ set x 0x123456871234568
+ expr {~ $x}
+} -81985533099853161
+test execute-7.30 {Wide int handling in function call} {
+ set x 0x12345687123456
+ incr x
+ expr {log($x) == log(double($x))}
+} 1
+test execute-7.31 {Wide int handling in abs()} {
+ set x 0xa23456871234568
+ incr x
+ set y 0x123456871234568
+ concat [expr {abs($x)}] [expr {abs($y)}]
+} {730503879441204585 81985533099853160}
+test execute-7.32 {Wide int handling} longIs32bit {
+ expr {int(1024 * 1024 * 1024 * 1024)}
+} 0
+test execute-7.33 {Wide int handling} longIs32bit {
+ expr {int(0x1 * 1024 * 1024 * 1024 * 1024)}
+} 0
+test execute-7.34 {Wide int handling} {
+ expr {wide(0x1) * 1024 * 1024 * 1024 * 1024}
+} 1099511627776
+
+test execute-8.1 {Stack protection} -setup {
+ # If [Bug #804681] has not been properly taken care of, this should
+ # segfault
+ proc whatever args {llength $args}
+ trace add variable ::errorInfo {write unset} whatever
+} -body {
+ expr {1+9/0}
+} -cleanup {
+ trace remove variable ::errorInfo {write unset} whatever
+ rename whatever {}
+} -returnCodes error -match glob -result *
+test execute-8.2 {Stack restoration} -setup {
+ # Avoid crashes when system stack size is limited (thread-enabled!)
+ set limit [interp recursionlimit {}]
+ interp recursionlimit {} 100
+} -body {
+ # Test for [Bug #816641], correct restoration of the stack top after the
+ # stack is grown
+ proc f {args} { f bee bop }
+ catch f msg
+ set msg
+} -cleanup {
+ interp recursionlimit {} $limit
+} -result {too many nested evaluations (infinite loop?)}
+test execute-8.3 {Stack restoration} -setup {
+ # Avoid crashes when system stack size is limited (thread-enabled!)
+ set limit [interp recursionlimit {}]
+ interp recursionlimit {} 100
+} -body {
+ # Test for [Bug #1055676], correct restoration of the stack top after the
+ # epoch is bumped and the stack is grown in a call from a nested
+ # evaluation
+ set arglst [string repeat "a " 1000]
+ proc f {args} "f $arglst"
+ proc run {} {
+ # bump the interp's epoch
+ rename ::set ::dummy
+ rename ::dummy ::set
+ catch f msg
+ set msg
+ }
+ run
+} -cleanup {
+ interp recursionlimit {} $limit
+} -result {too many nested evaluations (infinite loop?)}
+test execute-8.4 {Compile epoch bump effect on stack trace} -setup {
+ proc foo {} {
+ error bar
+ }
+ proc FOO {} {
+ catch {error bar} m o
+ rename ::set ::dummy
+ rename ::dummy ::set
+ return -options $o $m
+ }
+} -body {
+ catch foo m o
+ set stack1 [dict get $o -errorinfo]
+ catch FOO m o
+ set stack2 [string map {FOO foo} [dict get $o -errorinfo]]
+ expr {$stack1 eq $stack2 ? {} : "These differ:\n$stack1\n$stack2"}
+} -cleanup {
+ rename foo {}
+ rename FOO {}
+ unset -nocomplain m o stack1 stack2
+} -result {}
+test execute-8.5 {Bug 2038069} -setup {
+ proc demo {} {
+ catch [list error FOO] m o
+ return $o
+ }
+} -body {
+ demo
+} -cleanup {
+ rename demo {}
+} -match glob -result {-code 1 -level 0 -errorstack * -errorcode NONE -errorinfo {FOO
+ while executing
+"error FOO"
+ invoked from within
+"catch \[list error FOO\] m o"} -errorline 2}
+
+test execute-9.1 {Interp result resetting [Bug 1522803]} {
+ set c 0
+ catch {
+ catch {set foo}
+ expr {1/$c}
+ }
+ if {[string match *foo* $::errorInfo]} {
+ set result "Bad errorInfo: $::errorInfo"
+ } else {
+ set result SUCCESS
+ }
+ set result
+} SUCCESS
+
+test execute-10.1 {TclExecuteByteCode, INST_CONCAT1, bytearrays} {
+ apply {s {binary scan $s c x; list $x [scan $s$s %c%c]}} \u0130
+} {48 {304 304}}
+test execute-10.2 {Bug 2802881} -setup {
+ interp create slave
+} -body {
+ # If [Bug 2802881] is not fixed, this will segfault
+ slave eval {
+ trace add variable ::errorInfo write {expr {$foo} ;#}
+ proc demo {} {a {}{}}
+ demo
+ }
+} -cleanup {
+ interp delete slave
+} -returnCodes error -match glob -result *
+test execute-10.3 {Bug 3072640} -setup {
+ proc generate {n} {
+ for {set i 0} {$i < $n} {incr i} {
+ yield $i
+ }
+ }
+ proc t {args} {
+ incr ::foo
+ }
+ trace add execution ::generate enterstep ::t
+} -body {
+ coroutine coro generate 5
+ trace remove execution ::generate enterstep ::t
+ set ::foo
+} -cleanup {
+ unset ::foo
+ rename generate {}
+ rename t {}
+ rename coro {}
+} -result 4
+
+test execute-11.1 {Bug 3142026: GrowEvaluationStack off-by-one} -setup {
+ interp create slave
+} -body {
+ slave eval {
+ set x [lrepeat 1320 199]
+ for {set i 0} {$i < 20} {incr i} {
+ lappend x $i
+ lsort -integer $x
+ }
+ # Crashes on failure
+ return ok
+ }
+} -cleanup {
+ interp delete slave
+} -result ok
+
+# cleanup
+if {[info commands testobj] != {}} {
+ testobj freeallvars
+}
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+catch {rename foo ""}
+catch {rename p ""}
+catch {rename {} ""}
+catch {rename { } ""}
+catch {unset x}
+catch {unset y}
+catch {unset msg}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/expr-old.test b/pkgs/msgcat/tests/expr-old.test
new file mode 100644
index 0000000..c05a925
--- /dev/null
+++ b/pkgs/msgcat/tests/expr-old.test
@@ -0,0 +1,1207 @@
+# Commands covered: expr
+#
+# This file contains the original set of tests for Tcl's expr command.
+# Since the expr command is now compiled, a new set of tests covering
+# the new implementation are in the files "parseExpr.test" and
+# "compExpr.test". Sourcing this file into Tcl runs the tests and generates
+# output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2.1
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testexprlong [llength [info commands testexprlong]]
+testConstraint testexprdouble [llength [info commands testexprdouble]]
+testConstraint testexprstring [llength [info commands testexprstring]]
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+
+if {[catch {expr T1()} msg] && $msg eq {invalid command name "tcl::mathfunc::T1"}} {
+ testConstraint testmathfunctions 0
+} else {
+ testConstraint testmathfunctions 1
+}
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+ variable ieeeValues
+ binary scan [binary format dd -1.0 1.0] c* c
+ switch -exact -- $c {
+ {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+ # little endian
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+ ieeeValues(-Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+ ieeeValues(-Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+ ieeeValues(-Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+ ieeeValues(+Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+ ieeeValues(+Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 1
+ return 1
+ }
+ {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+ binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Infinity)
+ binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Normal)
+ binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Subnormal)
+ binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Normal)
+ binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Infinity)
+ binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 0
+ return 1
+ }
+ default {
+ return 0
+ }
+ }
+}
+testConstraint ieeeFloatingPoint [testIEEE]
+
+# First, test all of the integer operators individually.
+
+test expr-old-1.1 {integer operators} {expr -4} -4
+test expr-old-1.2 {integer operators} {expr -(1+4)} -5
+test expr-old-1.3 {integer operators} {expr ~3} -4
+test expr-old-1.4 {integer operators} {expr !2} 0
+test expr-old-1.5 {integer operators} {expr !0} 1
+test expr-old-1.6 {integer operators} {expr 4*6} 24
+test expr-old-1.7 {integer operators} {expr 36/12} 3
+test expr-old-1.8 {integer operators} {expr 27/4} 6
+test expr-old-1.9 {integer operators} {expr 27%4} 3
+test expr-old-1.10 {integer operators} {expr 2+2} 4
+test expr-old-1.11 {integer operators} {expr 2-6} -4
+test expr-old-1.12 {integer operators} {expr 1<<3} 8
+test expr-old-1.13 {integer operators} {expr 0xff>>2} 63
+test expr-old-1.14 {integer operators} {expr -1>>2} -1
+test expr-old-1.15 {integer operators} {expr 3>2} 1
+test expr-old-1.16 {integer operators} {expr 2>2} 0
+test expr-old-1.17 {integer operators} {expr 1>2} 0
+test expr-old-1.18 {integer operators} {expr 3<2} 0
+test expr-old-1.19 {integer operators} {expr 2<2} 0
+test expr-old-1.20 {integer operators} {expr 1<2} 1
+test expr-old-1.21 {integer operators} {expr 3>=2} 1
+test expr-old-1.22 {integer operators} {expr 2>=2} 1
+test expr-old-1.23 {integer operators} {expr 1>=2} 0
+test expr-old-1.24 {integer operators} {expr 3<=2} 0
+test expr-old-1.25 {integer operators} {expr 2<=2} 1
+test expr-old-1.26 {integer operators} {expr 1<=2} 1
+test expr-old-1.27 {integer operators} {expr 3==2} 0
+test expr-old-1.28 {integer operators} {expr 2==2} 1
+test expr-old-1.29 {integer operators} {expr 3!=2} 1
+test expr-old-1.30 {integer operators} {expr 2!=2} 0
+test expr-old-1.31 {integer operators} {expr 7&0x13} 3
+test expr-old-1.32 {integer operators} {expr 7^0x13} 20
+test expr-old-1.33 {integer operators} {expr 7|0x13} 23
+test expr-old-1.34 {integer operators} {expr 0&&1} 0
+test expr-old-1.35 {integer operators} {expr 0&&0} 0
+test expr-old-1.36 {integer operators} {expr 1&&3} 1
+test expr-old-1.37 {integer operators} {expr 0||1} 1
+test expr-old-1.38 {integer operators} {expr 3||0} 1
+test expr-old-1.39 {integer operators} {expr 0||0} 0
+test expr-old-1.40 {integer operators} {expr 3>2?44:66} 44
+test expr-old-1.41 {integer operators} {expr 2>3?44:66} 66
+test expr-old-1.42 {integer operators} {expr 36/5} 7
+test expr-old-1.43 {integer operators} {expr 36%5} 1
+test expr-old-1.44 {integer operators} {expr -36/5} -8
+test expr-old-1.45 {integer operators} {expr -36%5} 4
+test expr-old-1.46 {integer operators} {expr 36/-5} -8
+test expr-old-1.47 {integer operators} {expr 36%-5} -4
+test expr-old-1.48 {integer operators} {expr -36/-5} 7
+test expr-old-1.49 {integer operators} {expr -36%-5} -1
+test expr-old-1.50 {integer operators} {expr +36} 36
+test expr-old-1.51 {integer operators} {expr +--++36} 36
+test expr-old-1.52 {integer operators} {expr +36%+5} 1
+test expr-old-1.53 {integer operators} {
+ catch {unset x}
+ set x yes
+ list [expr {1 && $x}] [expr {$x && 1}] \
+ [expr {0 || $x}] [expr {$x || 0}]
+} {1 1 1 1}
+
+# Check the floating-point operators individually, along with
+# automatic conversion to integers where needed.
+
+test expr-old-2.1 {floating-point operators} {expr -4.2} -4.2
+test expr-old-2.2 {floating-point operators} {expr -(1.125+4.25)} -5.375
+test expr-old-2.3 {floating-point operators} {expr +5.7} 5.7
+test expr-old-2.4 {floating-point operators} {expr +--+-62.0} -62.0
+test expr-old-2.5 {floating-point operators} {expr !2.1} 0
+test expr-old-2.6 {floating-point operators} {expr !0.0} 1
+test expr-old-2.7 {floating-point operators} {expr 4.2*6.3} 26.46
+test expr-old-2.8 {floating-point operators} {expr 36.0/12.0} 3.0
+test expr-old-2.9 {floating-point operators} {expr 27/4.0} 6.75
+test expr-old-2.10 {floating-point operators} {expr 2.3+2.1} 4.4
+test expr-old-2.11 {floating-point operators} {expr 2.3-6.5} -4.2
+test expr-old-2.12 {floating-point operators} {expr 3.1>2.1} 1
+test expr-old-2.13 {floating-point operators} {expr {2.1 > 2.1}} 0
+test expr-old-2.14 {floating-point operators} {expr 1.23>2.34e+1} 0
+test expr-old-2.15 {floating-point operators} {expr 3.45<2.34} 0
+test expr-old-2.16 {floating-point operators} {expr 0.002e3<--200e-2} 0
+test expr-old-2.17 {floating-point operators} {expr 1.1<2.1} 1
+test expr-old-2.18 {floating-point operators} {expr 3.1>=2.2} 1
+test expr-old-2.19 {floating-point operators} {expr 2.345>=2.345} 1
+test expr-old-2.20 {floating-point operators} {expr 1.1>=2.2} 0
+test expr-old-2.21 {floating-point operators} {expr 3.0<=2.0} 0
+test expr-old-2.22 {floating-point operators} {expr 2.2<=2.2} 1
+test expr-old-2.23 {floating-point operators} {expr 2.2<=2.2001} 1
+test expr-old-2.24 {floating-point operators} {expr 3.2==2.2} 0
+test expr-old-2.25 {floating-point operators} {expr 2.2==2.2} 1
+test expr-old-2.26 {floating-point operators} {expr 3.2!=2.2} 1
+test expr-old-2.27 {floating-point operators} {expr 2.2!=2.2} 0
+test expr-old-2.28 {floating-point operators} {expr 0.0&&0.0} 0
+test expr-old-2.29 {floating-point operators} {expr 0.0&&1.3} 0
+test expr-old-2.30 {floating-point operators} {expr 1.3&&0.0} 0
+test expr-old-2.31 {floating-point operators} {expr 1.3&&3.3} 1
+test expr-old-2.32 {floating-point operators} {expr 0.0||0.0} 0
+test expr-old-2.33 {floating-point operators} {expr 0.0||1.3} 1
+test expr-old-2.34 {floating-point operators} {expr 1.3||0.0} 1
+test expr-old-2.35 {floating-point operators} {expr 3.3||0.0} 1
+test expr-old-2.36 {floating-point operators} {expr 3.3>2.3?44.3:66.3} 44.3
+test expr-old-2.37 {floating-point operators} {expr 2.3>3.3?44.3:66.3} 66.3
+test expr-old-2.38 {floating-point operators} {
+ list [catch {expr 028.1 + 09.2} msg] $msg
+} {0 37.3}
+
+# Operators that aren't legal on floating-point numbers
+
+test expr-old-3.1 {illegal floating-point operations} {
+ list [catch {expr ~4.0} msg] $msg
+} {1 {can't use floating-point value as operand of "~"}}
+test expr-old-3.2 {illegal floating-point operations} {
+ list [catch {expr 27%4.0} msg] $msg
+} {1 {can't use floating-point value as operand of "%"}}
+test expr-old-3.3 {illegal floating-point operations} {
+ list [catch {expr 27.0%4} msg] $msg
+} {1 {can't use floating-point value as operand of "%"}}
+test expr-old-3.4 {illegal floating-point operations} {
+ list [catch {expr 1.0<<3} msg] $msg
+} {1 {can't use floating-point value as operand of "<<"}}
+test expr-old-3.5 {illegal floating-point operations} {
+ list [catch {expr 3<<1.0} msg] $msg
+} {1 {can't use floating-point value as operand of "<<"}}
+test expr-old-3.6 {illegal floating-point operations} {
+ list [catch {expr 24.0>>3} msg] $msg
+} {1 {can't use floating-point value as operand of ">>"}}
+test expr-old-3.7 {illegal floating-point operations} {
+ list [catch {expr 24>>3.0} msg] $msg
+} {1 {can't use floating-point value as operand of ">>"}}
+test expr-old-3.8 {illegal floating-point operations} {
+ list [catch {expr 24&3.0} msg] $msg
+} {1 {can't use floating-point value as operand of "&"}}
+test expr-old-3.9 {illegal floating-point operations} {
+ list [catch {expr 24.0|3} msg] $msg
+} {1 {can't use floating-point value as operand of "|"}}
+test expr-old-3.10 {illegal floating-point operations} {
+ list [catch {expr 24.0^3} msg] $msg
+} {1 {can't use floating-point value as operand of "^"}}
+
+# Check the string operators individually.
+
+test expr-old-4.1 {string operators} {expr {"abc" > "def"}} 0
+test expr-old-4.2 {string operators} {expr {"def" > "def"}} 0
+test expr-old-4.3 {string operators} {expr {"g" > "def"}} 1
+test expr-old-4.4 {string operators} {expr {"abc" < "abd"}} 1
+test expr-old-4.5 {string operators} {expr {"abd" < "abd"}} 0
+test expr-old-4.6 {string operators} {expr {"abe" < "abd"}} 0
+test expr-old-4.7 {string operators} {expr {"abc" >= "def"}} 0
+test expr-old-4.8 {string operators} {expr {"def" >= "def"}} 1
+test expr-old-4.9 {string operators} {expr {"g" >= "def"}} 1
+test expr-old-4.10 {string operators} {expr {"abc" <= "abd"}} 1
+test expr-old-4.11 {string operators} {expr {"abd" <= "abd"}} 1
+test expr-old-4.12 {string operators} {expr {"abe" <= "abd"}} 0
+test expr-old-4.13 {string operators} {expr {"abc" == "abd"}} 0
+test expr-old-4.14 {string operators} {expr {"abd" == "abd"}} 1
+test expr-old-4.15 {string operators} {expr {"abc" != "abd"}} 1
+test expr-old-4.16 {string operators} {expr {"abd" != "abd"}} 0
+test expr-old-4.17 {string operators} {expr {"0y" < "0x12"}} 0
+test expr-old-4.18 {string operators} {expr {"." < " "}} 0
+test expr-old-4.19 {string operators} {expr {"abc" eq "abd"}} 0
+test expr-old-4.20 {string operators} {expr {"abd" eq "abd"}} 1
+test expr-old-4.21 {string operators} {expr {"abc" ne "abd"}} 1
+test expr-old-4.22 {string operators} {expr {"abd" ne "abd"}} 0
+test expr-old-4.23 {string operators} {expr {"" eq "abd"}} 0
+test expr-old-4.24 {string operators} {expr {"" eq ""}} 1
+test expr-old-4.25 {string operators} {expr {"abd" ne ""}} 1
+test expr-old-4.26 {string operators} {expr {"" ne ""}} 0
+test expr-old-4.27 {string operators} {expr {"longerstring" eq "shorter"}} 0
+test expr-old-4.28 {string operators} {expr {"longerstring" ne "shorter"}} 1
+test expr-old-4.29 {string operators} {expr {"0" == "+"}} 0
+test expr-old-4.30 {string operators} {expr {"0" == "-"}} 0
+test expr-old-4.31 {string operators} {expr {1?"foo":"bar"}} foo
+test expr-old-4.32 {string operators} {expr {0?"foo":"bar"}} bar
+
+# Operators that aren't legal on string operands.
+
+test expr-old-5.1 {illegal string operations} {
+ list [catch {expr {-"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+test expr-old-5.2 {illegal string operations} {
+ list [catch {expr {+"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-5.3 {illegal string operations} {
+ list [catch {expr {~"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "~"}}
+test expr-old-5.4 {illegal string operations} {
+ list [catch {expr {!"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-old-5.5 {illegal string operations} {
+ list [catch {expr {"a"*"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "*"}}
+test expr-old-5.6 {illegal string operations} {
+ list [catch {expr {"a"/"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+test expr-old-5.7 {illegal string operations} {
+ list [catch {expr {"a"%"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "%"}}
+test expr-old-5.8 {illegal string operations} {
+ list [catch {expr {"a"+"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-5.9 {illegal string operations} {
+ list [catch {expr {"a"-"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+test expr-old-5.10 {illegal string operations} {
+ list [catch {expr {"a"<<"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "<<"}}
+test expr-old-5.11 {illegal string operations} {
+ list [catch {expr {"a">>"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of ">>"}}
+test expr-old-5.12 {illegal string operations} {
+ list [catch {expr {"a"&"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "&"}}
+test expr-old-5.13 {illegal string operations} {
+ list [catch {expr {"a"^"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "^"}}
+test expr-old-5.14 {illegal string operations} {
+ list [catch {expr {"a"|"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "|"}}
+test expr-old-5.15 {illegal string operations} {
+ list [catch {expr {"a"&&"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test expr-old-5.16 {illegal string operations} {
+ list [catch {expr {"a"||"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test expr-old-5.17 {illegal string operations} {
+ list [catch {expr {"a"?4:2}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+
+# Check precedence pairwise.
+
+test expr-old-6.1 {precedence checks} {expr -~3} 4
+test expr-old-6.2 {precedence checks} {expr -!3} 0
+test expr-old-6.3 {precedence checks} {expr -~0} 1
+
+test expr-old-7.1 {precedence checks} {expr 2*4/6} 1
+test expr-old-7.2 {precedence checks} {expr 24/6*3} 12
+test expr-old-7.3 {precedence checks} {expr 24/6/2} 2
+
+test expr-old-8.1 {precedence checks} {expr -2+4} 2
+test expr-old-8.2 {precedence checks} {expr -2-4} -6
+test expr-old-8.3 {precedence checks} {expr +2-4} -2
+
+test expr-old-9.1 {precedence checks} {expr 2*3+4} 10
+test expr-old-9.2 {precedence checks} {expr 8/2+4} 8
+test expr-old-9.3 {precedence checks} {expr 8%3+4} 6
+test expr-old-9.4 {precedence checks} {expr 2*3-1} 5
+test expr-old-9.5 {precedence checks} {expr 8/2-1} 3
+test expr-old-9.6 {precedence checks} {expr 8%3-1} 1
+
+test expr-old-10.1 {precedence checks} {expr 6-3-2} 1
+
+test expr-old-11.1 {precedence checks} {expr 7+1>>2} 2
+test expr-old-11.2 {precedence checks} {expr 7+1<<2} 32
+test expr-old-11.3 {precedence checks} {expr 7>>3-2} 3
+test expr-old-11.4 {precedence checks} {expr 7<<3-2} 14
+
+test expr-old-12.1 {precedence checks} {expr 6>>1>4} 0
+test expr-old-12.2 {precedence checks} {expr 6>>1<2} 0
+test expr-old-12.3 {precedence checks} {expr 6>>1>=3} 1
+test expr-old-12.4 {precedence checks} {expr 6>>1<=2} 0
+test expr-old-12.5 {precedence checks} {expr 6<<1>5} 1
+test expr-old-12.6 {precedence checks} {expr 6<<1<5} 0
+test expr-old-12.7 {precedence checks} {expr 5<=6<<1} 1
+test expr-old-12.8 {precedence checks} {expr 5>=6<<1} 0
+
+test expr-old-13.1 {precedence checks} {expr 2<3<4} 1
+test expr-old-13.2 {precedence checks} {expr 0<4>2} 0
+test expr-old-13.3 {precedence checks} {expr 4>2<1} 0
+test expr-old-13.4 {precedence checks} {expr 4>3>2} 0
+test expr-old-13.5 {precedence checks} {expr 4>3>=2} 0
+test expr-old-13.6 {precedence checks} {expr 4>=3>2} 0
+test expr-old-13.7 {precedence checks} {expr 4>=3>=2} 0
+test expr-old-13.8 {precedence checks} {expr 0<=4>=2} 0
+test expr-old-13.9 {precedence checks} {expr 4>=2<=0} 0
+test expr-old-13.10 {precedence checks} {expr 2<=3<=4} 1
+
+test expr-old-14.1 {precedence checks} {expr 1==4>3} 1
+test expr-old-14.2 {precedence checks} {expr 0!=4>3} 1
+test expr-old-14.3 {precedence checks} {expr 1==3<4} 1
+test expr-old-14.4 {precedence checks} {expr 0!=3<4} 1
+test expr-old-14.5 {precedence checks} {expr 1==4>=3} 1
+test expr-old-14.6 {precedence checks} {expr 0!=4>=3} 1
+test expr-old-14.7 {precedence checks} {expr 1==3<=4} 1
+test expr-old-14.8 {precedence checks} {expr 0!=3<=4} 1
+test expr-old-14.9 {precedence checks} {expr 1eq4>3} 1
+test expr-old-14.10 {precedence checks} {expr 0ne4>3} 1
+test expr-old-14.11 {precedence checks} {expr 1eq3<4} 1
+test expr-old-14.12 {precedence checks} {expr 0ne3<4} 1
+test expr-old-14.13 {precedence checks} {expr 1eq4>=3} 1
+test expr-old-14.14 {precedence checks} {expr 0ne4>=3} 1
+test expr-old-14.15 {precedence checks} {expr 1eq3<=4} 1
+test expr-old-14.16 {precedence checks} {expr 0ne3<=4} 1
+
+test expr-old-15.1 {precedence checks} {expr 1==3==3} 0
+test expr-old-15.2 {precedence checks} {expr 3==3!=2} 1
+test expr-old-15.3 {precedence checks} {expr 2!=3==3} 0
+test expr-old-15.4 {precedence checks} {expr 2!=1!=1} 0
+test expr-old-15.5 {precedence checks} {expr 1eq3eq3} 0
+test expr-old-15.6 {precedence checks} {expr 3eq3ne2} 1
+test expr-old-15.7 {precedence checks} {expr 2ne3eq3} 0
+test expr-old-15.8 {precedence checks} {expr 2ne1ne1} 0
+
+test expr-old-16.1 {precedence checks} {expr 2&3eq2} 0
+test expr-old-16.2 {precedence checks} {expr 1&3ne3} 0
+test expr-old-16.3 {precedence checks} {expr 2&3eq2} 0
+test expr-old-16.4 {precedence checks} {expr 1&3ne3} 0
+
+test expr-old-17.1 {precedence checks} {expr 7&3^0x10} 19
+test expr-old-17.2 {precedence checks} {expr 7^0x10&3} 7
+
+test expr-old-18.1 {precedence checks} {expr 7^0x10|3} 23
+test expr-old-18.2 {precedence checks} {expr 7|0x10^3} 23
+
+test expr-old-19.1 {precedence checks} {expr 7|3&&1} 1
+test expr-old-19.2 {precedence checks} {expr 1&&3|7} 1
+test expr-old-19.3 {precedence checks} {expr 0&&1||1} 1
+test expr-old-19.4 {precedence checks} {expr 1||1&&0} 1
+
+test expr-old-20.1 {precedence checks} {expr 1||0?3:4} 3
+test expr-old-20.2 {precedence checks} {expr 1?0:4||1} 0
+test expr-old-20.3 {precedence checks} {expr 1?2:0?3:4} 2
+test expr-old-20.4 {precedence checks} {expr 0?2:0?3:4} 4
+test expr-old-20.5 {precedence checks} {expr 1?2?3:4:0} 3
+test expr-old-20.6 {precedence checks} {expr 0?2?3:4:0} 0
+
+# Parentheses.
+
+test expr-old-21.1 {parenthesization} {expr (2+4)*6} 36
+test expr-old-21.2 {parenthesization} {expr (1?0:4)||1} 1
+test expr-old-21.3 {parenthesization} {expr +(3-4)} -1
+
+# Embedded commands and variable names.
+
+set a 16
+test expr-old-22.1 {embedded variables} {expr {2*$a}} 32
+test expr-old-22.2 {embedded variables} {
+ set x -5
+ set y 10
+ expr {$x + $y}
+} {5}
+test expr-old-22.3 {embedded variables} {
+ set x " -5"
+ set y " +10"
+ expr {$x + $y}
+} {5}
+test expr-old-22.4 {embedded commands and variables} {expr {[set a] - 14}} 2
+test expr-old-22.5 {embedded commands and variables} {
+ list [catch {expr {12 - [bad_command_name]}} msg] $msg
+} {1 {invalid command name "bad_command_name"}}
+
+# Double-quotes and things inside them.
+
+test expr-old-23.1 {double quotes} {expr {"abc"}} abc
+test expr-old-23.2 {double quotes} {
+ set a 189
+ expr {"$a.bc"}
+} 189.bc
+test expr-old-23.3 {double quotes} {
+ set b2 xyx
+ expr {"$b2$b2$b2.[set b2].[set b2]"}
+} xyxxyxxyx.xyx.xyx
+test expr-old-23.4 {double quotes} {expr {"11\}\}22"}} 11}}22
+test expr-old-23.5 {double quotes} {expr {"\*bc"}} {*bc}
+test expr-old-23.6 {double quotes} {
+ catch {unset bogus__}
+ list [catch {expr {"$bogus__"}} msg] $msg
+} {1 {can't read "bogus__": no such variable}}
+test expr-old-23.7 {double quotes} {
+ list [catch {expr {"a[error Testing]bc"}} msg] $msg
+} {1 Testing}
+test expr-old-23.8 {double quotes} {
+ list [catch {expr {"12398712938788234-1298379" != ""}} msg] $msg
+} {0 1}
+
+# Numbers in various bases.
+
+test expr-old-24.1 {numbers in different bases} {expr 0x20} 32
+test expr-old-24.2 {numbers in different bases} {expr 0o15} 13
+
+# Conversions between various data types.
+
+test expr-old-25.1 {type conversions} {expr 2+2.5} 4.5
+test expr-old-25.2 {type conversions} {expr 2.5+2} 4.5
+test expr-old-25.3 {type conversions} {expr 2-2.5} -0.5
+test expr-old-25.4 {type conversions} {expr 2/2.5} 0.8
+test expr-old-25.5 {type conversions} {expr 2>2.5} 0
+test expr-old-25.6 {type conversions} {expr 2.5>2} 1
+test expr-old-25.7 {type conversions} {expr 2<2.5} 1
+test expr-old-25.8 {type conversions} {expr 2>=2.5} 0
+test expr-old-25.9 {type conversions} {expr 2<=2.5} 1
+test expr-old-25.10 {type conversions} {expr 2==2.5} 0
+test expr-old-25.11 {type conversions} {expr 2!=2.5} 1
+test expr-old-25.12 {type conversions} {expr 2>"ab"} 0
+test expr-old-25.13 {type conversions} {expr {2>" "}} 1
+test expr-old-25.14 {type conversions} {expr {"24.1a" > 24.1}} 1
+test expr-old-25.15 {type conversions} {expr {24.1 > "24.1a"}} 0
+test expr-old-25.16 {type conversions} {expr 2+2.5} 4.5
+test expr-old-25.17 {type conversions} {expr 2+2.5} 4.5
+test expr-old-25.18 {type conversions} {expr 2.0e2} 200.0
+test expr-old-25.19 {type conversions} {expr 2.0e15} 2000000000000000.0
+test expr-old-25.20 {type conversions} {expr 10.0} 10.0
+
+# Various error conditions.
+
+test expr-old-26.1 {error conditions} {
+ list [catch {expr 2+"a"} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-26.2 {error conditions} -body {
+ expr 2+4*
+} -returnCodes error -match glob -result *
+test expr-old-26.3 {error conditions} -body {
+ expr 2+4*(
+} -returnCodes error -match glob -result *
+catch {unset _non_existent_}
+test expr-old-26.4 {error conditions} {
+ list [catch {expr 2+$_non_existent_} msg] $msg
+} {1 {can't read "_non_existent_": no such variable}}
+set a xx
+test expr-old-26.5 {error conditions} {
+ list [catch {expr {2+$a}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-26.6 {error conditions} {
+ list [catch {expr {2+[set a]}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-26.7 {error conditions} -body {
+ expr {2+(4}
+} -returnCodes error -match glob -result *
+test expr-old-26.8 {error conditions} {
+ list [catch {expr 2/0} msg] $msg $errorCode
+} {1 {divide by zero} {ARITH DIVZERO {divide by zero}}}
+test expr-old-26.9 {error conditions} {
+ list [catch {expr 2%0} msg] $msg $errorCode
+} {1 {divide by zero} {ARITH DIVZERO {divide by zero}}}
+test expr-old-26.10a {error conditions} !ieeeFloatingPoint {
+ list [catch {expr 2.0/0.0} msg] $msg $errorCode
+} {1 {divide by zero} {ARITH DIVZERO {divide by zero}}}
+test expr-old-26.10b {error conditions} ieeeFloatingPoint {
+ list [catch {expr 2.0/0.0} msg] $msg
+} {0 Inf}
+test expr-old-26.11 {error conditions} -body {
+ expr 2#
+} -returnCodes error -match glob -result *
+test expr-old-26.12 {error conditions} -body {
+ expr a.b
+} -returnCodes error -match glob -result *
+test expr-old-26.13 {error conditions} {
+ list [catch {expr {"a"/"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+test expr-old-26.14 {error conditions} -body {
+ expr 2:3
+} -returnCodes error -match glob -result *
+test expr-old-26.15 {error conditions} -body {
+ expr a@b
+} -returnCodes error -match glob -result *
+test expr-old-26.16 {error conditions} {
+ list [catch {expr a[b} msg] $msg
+} {1 {missing close-bracket}}
+test expr-old-26.17 {error conditions} -body {
+ expr a`b
+} -returnCodes error -match glob -result *
+test expr-old-26.18 {error conditions} -body {
+ expr \"a\"\{b
+} -returnCodes error -match glob -result *
+test expr-old-26.19 {error conditions} -body {
+ expr a
+} -returnCodes error -match glob -result *
+test expr-old-26.20 {error conditions} {
+ list [catch expr msg] $msg
+} {1 {wrong # args: should be "expr arg ?arg ...?"}}
+
+# Cancelled evaluation.
+
+test expr-old-27.1 {cancelled evaluation} {
+ set a 1
+ expr {0&&[set a 2]}
+ set a
+} 1
+test expr-old-27.2 {cancelled evaluation} {
+ set a 1
+ expr {1||[set a 2]}
+ set a
+} 1
+test expr-old-27.3 {cancelled evaluation} {
+ set a 1
+ expr {0?[set a 2]:1}
+ set a
+} 1
+test expr-old-27.4 {cancelled evaluation} {
+ set a 1
+ expr {1?2:[set a 2]}
+ set a
+} 1
+catch {unset x}
+test expr-old-27.5 {cancelled evaluation} {
+ list [catch {expr {[info exists x] && $x}} msg] $msg
+} {0 0}
+test expr-old-27.6 {cancelled evaluation} {
+ list [catch {expr {0 && [concat $x]}} msg] $msg
+} {0 0}
+test expr-old-27.7 {cancelled evaluation} {
+ set one 1
+ list [catch {expr {1 || 1/$one}} msg] $msg
+} {0 1}
+test expr-old-27.8 {cancelled evaluation} {
+ list [catch {expr {1 || -"string"}} msg] $msg
+} {0 1}
+test expr-old-27.9 {cancelled evaluation} {
+ list [catch {expr {1 || ("string" * ("x" && "y"))}} msg] $msg
+} {0 1}
+test expr-old-27.10 {cancelled evaluation} {
+ set x -1.0
+ list [catch {expr {($x > 0) ? round(log($x)) : 0}} msg] $msg
+} {0 0}
+test expr-old-27.11 {cancelled evaluation} -body {
+ expr {0 && foo}
+} -returnCodes error -match glob -result *
+test expr-old-27.12 {cancelled evaluation} -body {
+ expr {0 ? 1 : foo}
+} -returnCodes error -match glob -result *
+
+# Tcl_ExprBool as used in "if" statements
+
+test expr-old-28.1 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {2} {set a 2}
+ set a
+} 2
+test expr-old-28.2 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {0} {set a 2}
+ set a
+} 1
+test expr-old-28.3 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {1.2} {set a 2}
+ set a
+} 2
+test expr-old-28.4 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {-1.1} {set a 2}
+ set a
+} 2
+test expr-old-28.5 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {0.0} {set a 2}
+ set a
+} 1
+test expr-old-28.6 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"YES"} {set a 2}
+ set a
+} 2
+test expr-old-28.7 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"no"} {set a 2}
+ set a
+} 1
+test expr-old-28.8 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"true"} {set a 2}
+ set a
+} 2
+test expr-old-28.9 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"fAlse"} {set a 2}
+ set a
+} 1
+test expr-old-28.10 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"on"} {set a 2}
+ set a
+} 2
+test expr-old-28.11 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"Off"} {set a 2}
+ set a
+} 1
+test expr-old-28.12 {Tcl_ExprBool usage} {
+ list [catch {if {"abc"} {}} msg] $msg
+} {1 {expected boolean value but got "abc"}}
+test expr-old-28.13 {Tcl_ExprBool usage} {
+ list [catch {if {"ogle"} {}} msg] $msg
+} {1 {expected boolean value but got "ogle"}}
+test expr-old-28.14 {Tcl_ExprBool usage} {
+ list [catch {if {"o"} {}} msg] $msg
+} {1 {expected boolean value but got "o"}}
+
+# Operands enclosed in braces
+
+test expr-old-29.1 {braces} {expr {{abc}}} abc
+test expr-old-29.2 {braces} {expr {{0o0010}}} 8
+test expr-old-29.3 {braces} {expr {{3.1200000}}} 3.12
+test expr-old-29.4 {braces} {expr {{a{b}{1 {2 3}}c}}} "a{b}{1 {2 3}}c"
+test expr-old-29.5 {braces} -body {
+ expr "\{abc"
+} -returnCodes error -match glob -result *
+
+# Very long values
+
+test expr-old-30.1 {long values} {
+ set a "0000 1111 2222 3333 4444"
+ set a "$a | $a | $a | $a | $a"
+ set a "$a || $a || $a || $a || $a"
+ expr {$a}
+} {0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 || 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 || 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 || 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 || 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444}
+test expr-old-30.2 {long values} {
+ set a "000000000000000000000000000000"
+ set a "$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a${a}5"
+ expr $a
+} 5
+
+# Expressions spanning multiple arguments
+
+test expr-old-31.1 {multiple arguments to expr command} {
+ expr 4 + ( 6 *12) -3
+} 73
+test expr-old-31.2 {multiple arguments to expr command} -body {
+ expr 2 + (3 + 4
+} -returnCodes error -match glob -result *
+test expr-old-31.3 {multiple arguments to expr command} -body {
+ expr 2 + 3 +
+} -returnCodes error -match glob -result *
+test expr-old-31.4 {multiple arguments to expr command} -body {
+ expr 2 + 3 )
+} -returnCodes error -match glob -result *
+
+# Math functions
+
+test expr-old-32.1 {math functions in expressions} {
+ format %.6g [expr acos(0.5)]
+} {1.0472}
+test expr-old-32.2 {math functions in expressions} {
+ format %.6g [expr asin(0.5)]
+} {0.523599}
+test expr-old-32.3 {math functions in expressions} {
+ format %.6g [expr atan(1.0)]
+} {0.785398}
+test expr-old-32.4 {math functions in expressions} {
+ format %.6g [expr atan2(2.0, 2.0)]
+} {0.785398}
+test expr-old-32.5 {math functions in expressions} {
+ format %.6g [expr ceil(1.999)]
+} {2}
+test expr-old-32.6 {math functions in expressions} {
+ format %.6g [expr cos(.1)]
+} {0.995004}
+test expr-old-32.7 {math functions in expressions} {
+ format %.6g [expr cosh(.1)]
+} {1.005}
+test expr-old-32.8 {math functions in expressions} {
+ format %.6g [expr exp(1.0)]
+} {2.71828}
+test expr-old-32.9 {math functions in expressions} {
+ format %.6g [expr floor(2.000)]
+} {2}
+test expr-old-32.10 {math functions in expressions} {
+ format %.6g [expr floor(2.001)]
+} {2}
+test expr-old-32.11 {math functions in expressions} {
+ format %.6g [expr fmod(7.3, 3.2)]
+} {0.9}
+test expr-old-32.12 {math functions in expressions} {
+ format %.6g [expr hypot(3.0, 4.0)]
+} {5}
+test expr-old-32.13 {math functions in expressions} {
+ format %.6g [expr log(2.8)]
+} {1.02962}
+test expr-old-32.14 {math functions in expressions} {
+ format %.6g [expr log10(2.8)]
+} {0.447158}
+test expr-old-32.15 {math functions in expressions} {
+ format %.6g [expr pow(2.1, 3.1)]
+} {9.97424}
+test expr-old-32.16 {math functions in expressions} {
+ format %.6g [expr sin(.1)]
+} {0.0998334}
+test expr-old-32.17 {math functions in expressions} {
+ format %.6g [expr sinh(.1)]
+} {0.100167}
+test expr-old-32.18 {math functions in expressions} {
+ format %.6g [expr sqrt(2.0)]
+} {1.41421}
+test expr-old-32.19 {math functions in expressions} {
+ format %.6g [expr tan(0.8)]
+} {1.02964}
+test expr-old-32.20 {math functions in expressions} {
+ format %.6g [expr tanh(0.8)]
+} {0.664037}
+test expr-old-32.21 {math functions in expressions} {
+ format %.6g [expr abs(-1.8)]
+} {1.8}
+test expr-old-32.22 {math functions in expressions} {
+ expr abs(10.0)
+} {10.0}
+test expr-old-32.23 {math functions in expressions} {
+ format %.6g [expr abs(-4)]
+} {4}
+test expr-old-32.24 {math functions in expressions} {
+ format %.6g [expr abs(66)]
+} {66}
+
+test expr-old-32.25a {math functions in expressions} {
+ expr abs(0x8000000000000000)
+} [expr 1<<63]
+
+test expr-old-32.25b {math functions in expressions} {
+ expr abs(0x80000000)
+} 2147483648
+
+test expr-old-32.26 {math functions in expressions} {
+ expr double(1)
+} {1.0}
+test expr-old-32.27 {math functions in expressions} {
+ expr double(1.1)
+} {1.1}
+test expr-old-32.28 {math functions in expressions} {
+ expr int(1)
+} {1}
+test expr-old-32.29 {math functions in expressions} {
+ expr int(1.4)
+} {1}
+test expr-old-32.30 {math functions in expressions} {
+ expr int(1.6)
+} {1}
+test expr-old-32.31 {math functions in expressions} {
+ expr int(-1.4)
+} {-1}
+test expr-old-32.32 {math functions in expressions} {
+ expr int(-1.6)
+} {-1}
+test expr-old-32.33 {math functions in expressions} {
+ expr int(1e60)
+} 0
+test expr-old-32.34 {math functions in expressions} {
+ expr int(-1e60)
+} 0
+test expr-old-32.35 {math functions in expressions} {
+ expr round(1.49)
+} {1}
+test expr-old-32.36 {math functions in expressions} {
+ expr round(1.51)
+} {2}
+test expr-old-32.37 {math functions in expressions} {
+ expr round(-1.49)
+} {-1}
+test expr-old-32.38 {math functions in expressions} {
+ expr round(-1.51)
+} {-2}
+test expr-old-32.39 {math functions in expressions} {
+ expr round(1e60)
+} 999999999999999949387135297074018866963645011013410073083904
+test expr-old-32.40 {math functions in expressions} {
+ expr round(-1e60)
+} -999999999999999949387135297074018866963645011013410073083904
+test expr-old-32.41 {math functions in expressions} {
+ list [catch {expr pow(1.0 + 3.0 - 2, .8 * 5)} msg] $msg
+} {0 16.0}
+test expr-old-32.42 {math functions in expressions} {
+ list [catch {expr hypot(5*.8,3)} msg] $msg
+} {0 5.0}
+test expr-old-32.43 {math functions in expressions} testmathfunctions {
+ expr 2*T1()
+} 246
+test expr-old-32.44 {math functions in expressions} testmathfunctions {
+ expr T2()*3
+} 1035
+test expr-old-32.45 {math functions in expressions} {
+ expr (0 <= rand()) && (rand() < 1)
+} {1}
+test expr-old-32.46 {math functions in expressions} -body {
+ list [catch {expr rand(24)} msg] $msg
+} -match glob -result {1 {too many arguments for math function*}}
+test expr-old-32.47 {math functions in expressions} -body {
+ list [catch {expr srand()} msg] $msg
+} -match glob -result {1 {too few arguments for math function*}}
+test expr-old-32.48 {math functions in expressions} -body {
+ expr srand(3.79)
+} -returnCodes error -match glob -result *
+test expr-old-32.49 {math functions in expressions} -body {
+ expr srand("")
+} -returnCodes error -match glob -result *
+test expr-old-32.50 {math functions in expressions} {
+ set result [expr round(srand(12345) * 1000)]
+ for {set i 0} {$i < 10} {incr i} {
+ lappend result [expr round(rand() * 1000)]
+ }
+ set result
+} {97 834 948 36 12 51 766 585 914 784 333}
+test expr-old-32.51 {math functions in expressions} -body {
+ expr {srand([lindex "6ty" 0])}
+} -returnCodes error -match glob -result *
+test expr-old-32.52 {math functions in expressions} {
+ expr {srand(int(1<<37)) < 1}
+} {1}
+test expr-old-32.53 {math functions in expressions} {
+ expr {srand((1<<31) - 1) > 0}
+} {1}
+
+test expr-old-33.1 {conversions and fancy args to math functions} {
+ expr hypot ( 3 , 4 )
+} 5.0
+test expr-old-33.2 {conversions and fancy args to math functions} {
+ expr hypot ( (2.0+1.0) , 4 )
+} 5.0
+test expr-old-33.3 {conversions and fancy args to math functions} {
+ expr hypot ( 3 , (3.0 + 1.0) )
+} 5.0
+test expr-old-33.4 {conversions and fancy args to math functions} {
+ format %.6g [expr cos(acos(0.1))]
+} 0.1
+
+test expr-old-34.1 {errors in math functions} -body {
+ list [catch {expr func_2(1.0)} msg] $msg
+} -match glob -result {1 {* "*func_2"}}
+test expr-old-34.2 {errors in math functions} -body {
+ expr func|(1.0)
+} -returnCodes error -match glob -result *
+test expr-old-34.3 {errors in math functions} {
+ list [catch {expr {hypot("a b", 2.0)}} msg] $msg
+} {1 {expected floating-point number but got "a b"}}
+test expr-old-34.4 {errors in math functions} -body {
+ expr hypot(1.0 2.0)
+} -returnCodes error -match glob -result *
+test expr-old-34.5 {errors in math functions} -body {
+ expr hypot(1.0, 2.0
+} -returnCodes error -match glob -result *
+test expr-old-34.6 {errors in math functions} -body {
+ expr hypot(1.0 ,
+} -returnCodes error -match glob -result *
+test expr-old-34.7 {errors in math functions} -body {
+ list [catch {expr hypot(1.0)} msg] $msg
+} -match glob -result {1 {too few arguments for math function*}}
+test expr-old-34.8 {errors in math functions} -body {
+ list [catch {expr hypot(1.0, 2.0, 3.0)} msg] $msg
+} -match glob -result {1 {too many arguments for math function*}}
+test expr-old-34.9 {errors in math functions} {
+ list [catch {expr acos(-2.0)} msg] $msg $errorCode
+} {1 {domain error: argument not in valid range} {ARITH DOMAIN {domain error: argument not in valid range}}}
+test expr-old-34.10 {errors in math functions} {
+ list [catch {expr pow(-3, 1000001)} msg] $msg
+} {0 -Inf}
+test expr-old-34.11a {errors in math functions} !ieeeFloatingPoint {
+ list [catch {expr pow(3, 1000001)} msg] $msg $errorCode
+} {1 {floating-point value too large to represent} {ARITH OVERFLOW {floating-point value too large to represent}}}
+test expr-old-34.11b {errors in math functions} ieeeFloatingPoint {
+ list [catch {expr pow(3, 1000001)} msg] $msg
+} {0 Inf}
+test expr-old-34.12a {errors in math functions} !ieeeFloatingPoint {
+ list [catch {expr -14.0*exp(100000)} msg] $msg $errorCode
+} {1 {floating-point value too large to represent} {ARITH OVERFLOW {floating-point value too large to represent}}}
+test expr-old-34.12b {errors in math functions} ieeeFloatingPoint {
+ list [catch {expr -14.0*exp(100000)} msg] $msg
+} {0 -Inf}
+test expr-old-34.13 {errors in math functions} {
+ expr wide(1.0e30)
+} 5076964154930102272
+test expr-old-34.14 {errors in math functions} {
+ expr wide(-1.0e30)
+} -5076964154930102272
+test expr-old-34.15 {errors in math functions} {
+ expr round(1.0e30)
+} 1000000000000000019884624838656
+test expr-old-34.16 {errors in math functions} {
+ expr round(-1.0e30)
+} -1000000000000000019884624838656
+test expr-old-34.17 {errors in math functions} -constraints testmathfunctions \
+ -body {
+ list [catch {expr T1(4)} msg] $msg
+ } -match glob -result {1 {too many arguments for math function*}}
+
+test expr-old-36.1 {ExprLooksLikeInt procedure} -body {
+ expr 0o289
+} -returnCodes error -match glob -result {*invalid octal number*}
+test expr-old-36.2 {ExprLooksLikeInt procedure} {
+ set x 0o289
+ list [catch {expr {$x+1}} msg] $msg
+} {1 {can't use invalid octal number as operand of "+"}}
+test expr-old-36.3 {ExprLooksLikeInt procedure} {
+ list [catch {expr 0289.1} msg] $msg
+} {0 289.1}
+test expr-old-36.4 {ExprLooksLikeInt procedure} {
+ set x 0289.1
+ list [catch {expr {$x+1}} msg] $msg
+} {0 290.1}
+test expr-old-36.5 {ExprLooksLikeInt procedure} {
+ set x { +22}
+ list [catch {expr {$x+1}} msg] $msg
+} {0 23}
+test expr-old-36.6 {ExprLooksLikeInt procedure} {
+ set x { -22}
+ list [catch {expr {$x+1}} msg] $msg
+} {0 -21}
+test expr-old-36.7 {ExprLooksLikeInt procedure} {
+ list [catch {expr nan} msg] $msg
+} {1 {domain error: argument not in valid range}}
+test expr-old-36.8 {ExprLooksLikeInt procedure} {
+ list [catch {expr 78e1} msg] $msg
+} {0 780.0}
+test expr-old-36.9 {ExprLooksLikeInt procedure} {
+ list [catch {expr 24E1} msg] $msg
+} {0 240.0}
+test expr-old-36.10 {ExprLooksLikeInt procedure} -body {
+ expr 78e
+} -returnCodes error -match glob -result *
+
+# test for [Bug #542588]
+test expr-old-36.11 {ExprLooksLikeInt procedure} {
+ # define a "too large integer"; this one works also for 64bit arith
+ set x 665802003400000000000000
+ expr {$x+1}
+} 665802003400000000000001
+
+# tests for [Bug #587140]
+test expr-old-36.12 {ExprLooksLikeInt procedure} {
+ set x "10;"
+ list [catch {expr {$x+1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-36.13 {ExprLooksLikeInt procedure} {
+ set x " +"
+ list [catch {expr {$x+1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-36.14 {ExprLooksLikeInt procedure} {
+ set x "123456789012345678901234567890 "
+ expr {$x+1}
+} 123456789012345678901234567891
+test expr-old-36.15 {ExprLooksLikeInt procedure} {
+ set x "0o99 "
+ list [catch {expr {$x+1}} msg] $msg
+} {1 {can't use invalid octal number as operand of "+"}}
+test expr-old-36.16 {ExprLooksLikeInt procedure} {
+ set x " 0xffffffffffffffffffffffffffffffffffffff "
+ expr {$x+1}
+} [expr 0x100000000000000000000000000000000000000]
+
+test expr-old-37.1 {Check that Tcl_ExprLong doesn't modify interpreter result if no error} testexprlong {
+ testexprlong 4+1
+} {This is a result: 5}
+#Check for [Bug 1109484]
+test expr-old-37.2 {Tcl_ExprLong handles wide ints gracefully} testexprlong {
+ testexprlong wide(1)+2
+} {This is a result: 3}
+
+test expr-old-37.3 {Tcl_ExprLong on the empty string} testexprlong {
+ testexprlong ""
+} {This is a result: 0}
+test expr-old-37.4 {Tcl_ExprLong coerces doubles} testexprlong {
+ testexprlong 3+.14159
+} {This is a result: 3}
+test expr-old-37.5 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit} {
+ testexprlong 0x80000000
+} {This is a result: -2147483648}
+test expr-old-37.6 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit} {
+ testexprlong 0xffffffff
+} {This is a result: -1}
+test expr-old-37.7 {Tcl_ExprLong handles overflows} \
+ -constraints {testexprlong longIs32bit} \
+ -match glob \
+ -body {
+ list [catch {testexprlong 0x100000000} result] $result
+ } \
+ -result {1 {integer value too large to represent*}}
+test expr-old-37.8 {Tcl_ExprLong handles overflows} testexprlong {
+ testexprlong -0x80000000
+} {This is a result: -2147483648}
+test expr-old-37.9 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit} {
+ testexprlong -0xffffffff
+} {This is a result: 1}
+test expr-old-37.10 {Tcl_ExprLong handles overflows} \
+ -constraints {testexprlong longIs32bit} \
+ -match glob \
+ -body {
+ list [catch {testexprlong -0x100000000} result] $result
+ } \
+ -result {1 {integer value too large to represent*}}
+test expr-old-37.11 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit} {
+ testexprlong 2147483648.
+} {This is a result: -2147483648}
+test expr-old-37.12 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit} {
+ testexprlong 4294967295.
+} {This is a result: -1}
+test expr-old-37.13 {Tcl_ExprLong handles overflows} \
+ -constraints {testexprlong longIs32bit} \
+ -match glob \
+ -body {
+ list [catch {testexprlong 4294967296.} result] $result
+ } \
+ -result {1 {integer value too large to represent*}}
+test expr-old-37.14 {Tcl_ExprLong handles overflows} testexprlong {
+ testexprlong -2147483648.
+} {This is a result: -2147483648}
+test expr-old-37.15 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit} {
+ testexprlong -4294967295.
+} {This is a result: 1}
+test expr-old-37.16 {Tcl_ExprLong handles overflows} \
+ -constraints {testexprlong longIs32bit} \
+ -match glob \
+ -body {
+ list [catch {testexprlong 4294967296.} result] $result
+ } \
+ -result {1 {integer value too large to represent*}}
+
+test expr-old-37.17 {Check that Tcl_ExprDouble doesn't modify interpreter result if no error} testexprdouble {
+ testexprdouble 4.+1.
+} {This is a result: 5.0}
+#Check for [Bug 1109484]
+test expr-old-37.18 {Tcl_ExprDouble on the empty string} testexprdouble {
+ testexprdouble ""
+} {This is a result: 0.0}
+test expr-old-37.19 {Tcl_ExprDouble coerces wides} testexprdouble {
+ testexprdouble 1[string repeat 0 17]
+} {This is a result: 1e+17}
+test expr-old-37.20 {Tcl_ExprDouble coerces bignums} testexprdouble {
+ testexprdouble 1[string repeat 0 38]
+} {This is a result: 1e+38}
+test expr-old-37.21 {Tcl_ExprDouble handles overflows} testexprdouble {
+ testexprdouble 17976931348623157[string repeat 0 292].
+} {This is a result: 1.7976931348623157e+308}
+test expr-old-37.22 {Tcl_ExprDouble handles overflows that look like int} \
+ testexprdouble {
+ testexprdouble 17976931348623157[string repeat 0 292]
+ } {This is a result: 1.7976931348623157e+308}
+test expr-old-37.23 {Tcl_ExprDouble handles overflows} \
+ ieeeFloatingPoint&&testexprdouble {
+ testexprdouble 17976931348623165[string repeat 0 292].
+ } {This is a result: Inf}
+test expr-old-37.24 {Tcl_ExprDouble handles overflows that look like int} \
+ ieeeFloatingPoint&&testexprdouble {
+ testexprdouble 17976931348623165[string repeat 0 292]
+ } {This is a result: Inf}
+test expr-old-37.25 {Tcl_ExprDouble and NaN} \
+ {ieeeFloatingPoint testexprdouble} {
+ list [catch {testexprdouble 0.0/0.0} result] $result
+ } {1 {domain error: argument not in valid range}}
+
+test expr-old-38.1 {Verify Tcl_ExprString's basic operation} -constraints {testexprstring} -body {
+ list [testexprstring "1+4"] [testexprstring "2*3+4.2"] \
+ [catch {testexprstring "1+"} msg] $msg
+} -match glob -result {5 10.2 1 *}
+test expr-old-38.2 {Tcl_ExprString} testexprstring {
+ # This one is "magical"
+ testexprstring {}
+} 0
+test expr-old-38.3 {Tcl_ExprString} -constraints testexprstring -body {
+ testexprstring { }
+} -returnCodes error -match glob -result *
+
+#
+# Test for bug #908375: rounding numbers that do not fit in a
+# long but do fit in a wide
+#
+
+test expr-old-39.1 {Rounding with wide result} {
+ set x 1.0e10
+ set y [expr $x + 0.1]
+ catch {
+ set x [list [expr {$x == round($y)}] [expr $x == -round(-$y)]]
+ }
+ set x
+} {1 1}
+unset -nocomplain x y
+
+#
+# TIP #255 min and max math functions
+#
+
+test expr-old-40.1 {min math function} -body {
+ expr {min(0)}
+} -result 0
+test expr-old-40.2 {min math function} -body {
+ expr {min(0.0)}
+} -result 0.0
+test expr-old-40.3 {min math function} -body {
+ list [catch {expr {min()}} msg] $msg
+} -result {1 {too few arguments to math function "min"}}
+test expr-old-40.4 {min math function} -body {
+ expr {min(wide(-1) << 30, 4.5, -10)}
+} -result [expr {wide(-1) << 30}]
+test expr-old-40.5 {min math function} -body {
+ expr {min("a", 0)}
+} -returnCodes error -match glob -result *
+test expr-old-40.6 {min math function} -body {
+ expr {min(300, "0xFF")}
+} -result 255
+
+test expr-old-41.1 {max math function} -body {
+ expr {max(0)}
+} -result 0
+test expr-old-41.2 {max math function} -body {
+ expr {max(0.0)}
+} -result 0.0
+test expr-old-41.3 {max math function} -body {
+ list [catch {expr {max()}} msg] $msg
+} -result {1 {too few arguments to math function "max"}}
+test expr-old-41.4 {max math function} -body {
+ expr {max(wide(1) << 30, 4.5, -10)}
+} -result [expr {wide(1) << 30}]
+test expr-old-41.5 {max math function} -body {
+ expr {max("a", 0)}
+} -returnCodes error -match glob -result *
+test expr-old-41.6 {max math function} -body {
+ expr {max(200, "0xFF")}
+} -result 255
+
+# Special test for Pentium arithmetic bug of 1994:
+
+if {(4195835.0 - (4195835.0/3145727.0)*3145727.0) == 256.0} {
+ puts "Warning: this machine contains a defective Pentium processor"
+ puts "that performs arithmetic incorrectly. I recommend that you"
+ puts "call Intel customer service immediately at 1-800-628-8686"
+ puts "to request a replacement processor."
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/expr.test b/pkgs/msgcat/tests/expr.test
new file mode 100644
index 0000000..6679569
--- /dev/null
+++ b/pkgs/msgcat/tests/expr.test
@@ -0,0 +1,7187 @@
+# Commands covered: expr
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1996-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2.1
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testmathfunctions [expr {
+ ([catch {expr T1()} msg] != 1) || ($msg ne {invalid command name "tcl::mathfunc::T1"})
+}]
+
+# Determine if "long int" type is a 32 bit number and if the wide
+# type is a 64 bit number on this machine.
+
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}]
+testConstraint wideIs64bit \
+ [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}]
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+ variable ieeeValues
+ binary scan [binary format dd -1.0 1.0] c* c
+ switch -exact -- $c {
+ {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+ # little endian
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+ ieeeValues(-Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+ ieeeValues(-Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+ ieeeValues(-Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+ ieeeValues(+Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+ ieeeValues(+Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+ ieeeValues(NaN)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\xff d \
+ ieeeValues(-NaN)
+ set ieeeValues(littleEndian) 1
+ return 1
+ }
+ {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+ binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Infinity)
+ binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Normal)
+ binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Subnormal)
+ binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Normal)
+ binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Infinity)
+ binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(NaN)
+ binary scan \xff\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-NaN)
+ set ieeeValues(littleEndian) 0
+ return 1
+ }
+ default {
+ return 0
+ }
+ }
+}
+
+testConstraint ieeeFloatingPoint [testIEEE]
+# procedures used below
+
+proc put_hello_char {c} {
+ global a
+ append a [format %c $c]
+ return $c
+}
+proc hello_world {} {
+ global a
+ set a ""
+ set L1 [set l0 [set h_1 [set q 0]]]
+ for {put_hello_char [expr [put_hello_char [expr [set h 7]*10+2]]+29]} {$l0?[put_hello_char $l0]
+ :!$h_1} {put_hello_char $ll;expr {$L1==2?[set ll [expr 32+0-0+[set bar 0]]]:0}} {expr {[incr L1]==[expr 1+([string length "abc"]-[string length "abc"])]
+ ?[set ll [set l0 [expr 54<<1]]]:$ll==108&&$L1<3?
+ [incr ll [expr 1|1<<1]; set ll $ll; set ll $ll; set ll $ll; set ll $ll; set l0 [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]; set l0; set l0 $l0; set l0; set l0]:$L1==4&&$ll==32?[set ll [expr 19+$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+[set foo [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]]]]
+ :[set q [expr $q-$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]};expr {$L1==5?[incr ll -8; set ll $ll; set ll]:$q&&$h1&&1};expr {$L1==4+2
+ ?[incr ll 3]:[expr ([string length "abc"]-[string length "abc"])+1]};expr {$ll==($h<<4)+2+0&&$L1!=6?[incr ll -6]:[set h1 [expr 100+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]}
+ expr {$L1!=1<<3?[incr q [expr ([string length "abc"]-[string length "abc"])-1]]:[set h_1 [set ll $h1]]}
+ }
+ set a
+}
+
+proc 12days {a b c} {
+ global xxx
+ expr {1<$a?[expr {$a<3?[12days -79 -13 [string range $c [12days -87 \
+ [expr 1-$b] [string range $c [12days -86 0 [string range $c 1 end]] \
+ end]] end]]:1};expr {$a<$b?[12days [expr $a+1] $b $c]:3};expr {[12days \
+ -94 [expr $a-27] $c]&&$a==2?$b<13?[12days 2 [expr $b+1] "%s %d %d\n"]:9
+ :16}]:$a<0?$a<-72?[12days $b $a "@n'+,#'/*\{\}w+/w#cdnr/+,\{\}r/*de\}+,/*\{*+,/w\{%+,/w#q#n+,/#\{l+,/n\{n+,/+#n+,/#;#q#n+,/+k#;*+,/'r :'d*'3,\}\{w+K w'K:'+\}e#';dq#'l q#'+d'K#!/+k#;q#'r\}eKK#\}w'r\}eKK\{nl\]'/#;#q#n')\{)#\}w')\{)\{nl\]'/+#n';d\}rw' i;# )\{nl\]!/n\{n#'; r\{#w'r nc\{nl\]'/#\{l,+'K \{rw' iK\{;\[\{nl\]'/w#q#n'wk nw' iwk\{KK\{nl\]!/w\{%'l##w#' i; :\{nl\]'/*\{q#'ld;r'\}\{nlwb!/*de\}'c ;;\{nl'-\{\}rw\]'/+,\}##'*\}#nc,',#nw\]'/+kd'+e\}+;#'rdq#w! nr'/ ') \}+\}\{rl#'\{n' ')# \}'+\}##(!!/"]
+ :$a<-50?[string compare [format %c $b] [string index $c 0]]==0?[append \
+ xxx [string index $c 31];scan [string index $c 31] %c x;set x]
+ :[12days -65 $b [string range $c 1 end]]:[12days [expr ([string compare \
+ [string index $c 0] "/"]==0)+$a] $b [string range $c 1 end]]:0<$a
+ ?[12days 2 2 "%s"]:[string compare [string index $c 0] "/"]==0||
+ [12days 0 [12days -61 [scan [string index $c 0] %c x; set x] \
+ "!ek;dc i@bK'(q)-\[w\]*%n+r3#l,\{\}:\nuwloca-O;m .vpbks,fxntdCeghiry"] \
+ [string range $c 1 end]]}
+}
+proc do_twelve_days {} {
+ global xxx
+ set xxx ""
+ 12days 1 1 1
+ set result [string length $xxx]
+ unset xxx
+ return $result
+}
+
+# start of tests
+
+catch {unset a b i x}
+
+test expr-1.1 {TclCompileExprCmd: no expression} {
+ list [catch {expr } msg] $msg
+} {1 {wrong # args: should be "expr arg ?arg ...?"}}
+test expr-1.2 {TclCompileExprCmd: one expression word} {
+ expr -25
+} -25
+test expr-1.3 {TclCompileExprCmd: two expression words} {
+ expr -8.2 -6
+} -14.2
+test expr-1.4 {TclCompileExprCmd: five expression words} {
+ expr 20 - 5 +10 -7
+} 18
+test expr-1.5 {TclCompileExprCmd: quoted expression word} {
+ expr "0005"
+} 5
+test expr-1.6 {TclCompileExprCmd: quoted expression word} {
+ catch {expr "0005"zxy} msg
+ set msg
+} {extra characters after close-quote}
+test expr-1.7 {TclCompileExprCmd: expression word in braces} {
+ expr {-0005}
+} -5
+test expr-1.8 {TclCompileExprCmd: expression word in braces} {
+ expr {{-0x1234}}
+} -4660
+test expr-1.9 {TclCompileExprCmd: expression word in braces} {
+ catch {expr {-0005}foo} msg
+ set msg
+} {extra characters after close-brace}
+test expr-1.10 {TclCompileExprCmd: other expression word in braces} {
+ expr 4*[llength "6 2"]
+} 8
+test expr-1.11 {TclCompileExprCmd: expression word terminated by ;} {
+ expr 4*[llength "6 2"];
+} 8
+test expr-1.12 {TclCompileExprCmd: inlined expr (in "catch") inside other catch} {
+ set a xxx
+ catch {
+ # Might not be a number
+ set a [expr 10*$a]
+ }
+} 1
+test expr-1.13 {TclCompileExprCmd: second level of substitutions in expr not in braces with single var reference} {
+ set a xxx
+ set x 27; set bool {$x}; if $bool {set a foo}
+ set a
+} foo
+test expr-1.14 {TclCompileExprCmd: second level of substitutions in expr with comparison as top-level operator} {
+ set a xxx
+ set x 2; set b {$x}; set a [expr $b == 2]
+ set a
+} 1
+test expr-1.15 {TclCompileExprCmd: second level of substitutions in expr with comparison as top-level operator} {
+ set a xxx
+ set x 2; set b {$x}; set a [expr $b eq 2]
+ set a
+} 1
+
+test expr-2.1 {TclCompileExpr: are builtin functions registered?} {
+ expr double(5*[llength "6 2"])
+} 10.0
+test expr-2.2 {TclCompileExpr: error in expr} -body {
+ expr 2***3
+} -returnCodes error -match glob -result *
+test expr-2.3 {TclCompileExpr: junk after legal expr} -body {
+ expr 7*[llength "a b"]foo
+} -returnCodes error -match glob -result *
+test expr-2.4 {TclCompileExpr: numeric expr string rep == formatted int rep} {
+ expr {0001}
+} 1
+
+test expr-3.1 {CompileCondExpr: just lor expr} {expr 3||0} 1
+test expr-3.2 {CompileCondExpr: error in lor expr} -body {
+ expr x||3
+} -returnCodes error -match glob -result *
+test expr-3.3 {CompileCondExpr: test true arm} {expr 3>2?44:66} 44
+test expr-3.4 {CompileCondExpr: error compiling true arm} -body {
+ expr 3>2?2***3:66
+} -returnCodes error -match glob -result *
+test expr-3.5 {CompileCondExpr: test false arm} {expr 2>3?44:66} 66
+test expr-3.6 {CompileCondExpr: error compiling false arm} -body {
+ expr 2>3?44:2***3
+} -returnCodes error -match glob -result *
+test expr-3.7 {CompileCondExpr: long arms & nested cond exprs} {
+ hello_world
+} {Hello world}
+test expr-3.8 {CompileCondExpr: long arms & nested cond exprs} unix {
+ # Fails with a stack overflow on threaded Windows builds
+ do_twelve_days
+} 2358
+
+test expr-4.1 {CompileLorExpr: just land expr} {expr 1.3&&3.3} 1
+test expr-4.2 {CompileLorExpr: error in land expr} -body {
+ expr x&&3
+} -returnCodes error -match glob -result *
+test expr-4.3 {CompileLorExpr: simple lor exprs} {expr 0||1.0} 1
+test expr-4.4 {CompileLorExpr: simple lor exprs} {expr 3.0||0.0} 1
+test expr-4.5 {CompileLorExpr: simple lor exprs} {expr 0||0||1} 1
+test expr-4.6 {CompileLorExpr: error compiling lor arm} -body {
+ expr 2***3||4.0
+} -returnCodes error -match glob -result *
+test expr-4.7 {CompileLorExpr: error compiling lor arm} -body {
+ expr 1.3||2***3
+} -returnCodes error -match glob -result *
+test expr-4.8 {CompileLorExpr: error compiling lor arms} {
+ list [catch {expr {"a"||"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test expr-4.9 {CompileLorExpr: long lor arm} {
+ set a "abcdefghijkl"
+ set i 7
+ expr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]}
+} 1
+test expr-4.10 {CompileLorExpr: error compiling ! operand} {
+ list [catch {expr {!"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-4.11 {CompileLorExpr: error compiling land arms} {
+ list [catch {expr {"a"||0}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test expr-4.12 {CompileLorExpr: error compiling land arms} {
+ list [catch {expr {0||"a"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+
+test expr-5.1 {CompileLandExpr: just bitor expr} {expr 7|0x13} 23
+test expr-5.2 {CompileLandExpr: error in bitor expr} -body {
+ expr x|3
+} -returnCodes error -match glob -result *
+test expr-5.3 {CompileLandExpr: simple land exprs} {expr 0&&1.0} 0
+test expr-5.4 {CompileLandExpr: simple land exprs} {expr 0&&0} 0
+test expr-5.5 {CompileLandExpr: simple land exprs} {expr 3.0&&1.2} 1
+test expr-5.6 {CompileLandExpr: simple land exprs} {expr 1&&1&&2} 1
+test expr-5.7 {CompileLandExpr: error compiling land arm} -body {
+ expr 2***3&&4.0
+} -returnCodes error -match glob -result *
+test expr-5.8 {CompileLandExpr: error compiling land arm} -body {
+ expr 1.3&&2***3
+} -returnCodes error -match glob -result *
+test expr-5.9 {CompileLandExpr: error compiling land arm} {
+ list [catch {expr {"a"&&"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test expr-5.10 {CompileLandExpr: long land arms} {
+ set a "abcdefghijkl"
+ set i 7
+ expr {[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]}
+} 1
+
+test expr-6.1 {CompileBitXorExpr: just bitand expr} {expr 7&0x13} 3
+test expr-6.2 {CompileBitXorExpr: error in bitand expr} -body {
+ expr x|3
+} -returnCodes error -match glob -result *
+test expr-6.3 {CompileBitXorExpr: simple bitxor exprs} {expr 7^0x13} 20
+test expr-6.4 {CompileBitXorExpr: simple bitxor exprs} {expr 3^0x10} 19
+test expr-6.5 {CompileBitXorExpr: simple bitxor exprs} {expr 0^7} 7
+test expr-6.6 {CompileBitXorExpr: simple bitxor exprs} {expr -1^7} -8
+test expr-6.7 {CompileBitXorExpr: error compiling bitxor arm} -body {
+ expr 2***3|6
+} -returnCodes error -match glob -result *
+test expr-6.8 {CompileBitXorExpr: error compiling bitxor arm} -body {
+ expr 2^x
+} -returnCodes error -match glob -result *
+test expr-6.9 {CompileBitXorExpr: runtime error in bitxor arm} {
+ list [catch {expr {24.0^3}} msg] $msg
+} {1 {can't use floating-point value as operand of "^"}}
+test expr-6.10 {CompileBitXorExpr: runtime error in bitxor arm} {
+ list [catch {expr {"a"^"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "^"}}
+
+test expr-7.1 {CompileBitAndExpr: just equality expr} {expr 3==2} 0
+test expr-7.2 {CompileBitAndExpr: just equality expr} {expr 2.0==2} 1
+test expr-7.3 {CompileBitAndExpr: just equality expr} {expr 3.2!=2.2} 1
+test expr-7.4 {CompileBitAndExpr: just equality expr} {expr {"abc" == "abd"}} 0
+test expr-7.5 {CompileBitAndExpr: error in equality expr} -body {
+ expr x==3
+} -returnCodes error -match glob -result *
+test expr-7.6 {CompileBitAndExpr: simple bitand exprs} {expr 7&0x13} 3
+test expr-7.7 {CompileBitAndExpr: simple bitand exprs} {expr 0xf2&0x53} 82
+test expr-7.8 {CompileBitAndExpr: simple bitand exprs} {expr 3&6} 2
+test expr-7.9 {CompileBitAndExpr: simple bitand exprs} {expr -1&-7} -7
+test expr-7.10 {CompileBitAndExpr: error compiling bitand arm} -body {
+ expr 2***3&6
+} -returnCodes error -match glob -result *
+test expr-7.11 {CompileBitAndExpr: error compiling bitand arm} -body {
+ expr 2&x
+} -returnCodes error -match glob -result *
+test expr-7.12 {CompileBitAndExpr: runtime error in bitand arm} {
+ list [catch {expr {24.0&3}} msg] $msg
+} {1 {can't use floating-point value as operand of "&"}}
+test expr-7.13 {CompileBitAndExpr: runtime error in bitand arm} {
+ list [catch {expr {"a"&"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "&"}}
+test expr-7.14 {CompileBitAndExpr: equality expr} {expr 3eq2} 0
+test expr-7.18 {CompileBitAndExpr: equality expr} {expr {"abc" eq "abd"}} 0
+test expr-7.20 {CompileBitAndExpr: error in equality expr} -body {
+ expr xne3
+} -returnCodes error -match glob -result *
+
+test expr-8.1 {CompileEqualityExpr: just relational expr} {expr 3>=2} 1
+test expr-8.2 {CompileEqualityExpr: just relational expr} {expr 2<=2.1} 1
+test expr-8.3 {CompileEqualityExpr: just relational expr} {expr 3.2>"2.2"} 1
+test expr-8.4 {CompileEqualityExpr: just relational expr} {expr {"0y"<"0x12"}} 0
+test expr-8.5 {CompileEqualityExpr: error in relational expr} -body {
+ expr x>3
+} -returnCodes error -match glob -result *
+test expr-8.6 {CompileEqualityExpr: simple equality exprs} {expr 7==0x13} 0
+test expr-8.7 {CompileEqualityExpr: simple equality exprs} {expr -0xf2!=0x53} 1
+test expr-8.8 {CompileEqualityExpr: simple equality exprs} {expr {"12398712938788234-1298379" != ""}} 1
+test expr-8.9 {CompileEqualityExpr: simple equality exprs} {expr -1!="abc"} 1
+test expr-8.10 {CompileEqualityExpr: error compiling equality arm} -body {
+ expr 2***3==6
+} -returnCodes error -match glob -result *
+test expr-8.11 {CompileEqualityExpr: error compiling equality arm} -body {
+ expr 2!=x
+} -returnCodes error -match glob -result *
+test expr-8.12 {CompileBitAndExpr: equality expr} {expr {"a"eq"a"}} 1
+test expr-8.13 {CompileBitAndExpr: equality expr} {expr {"\374" eq [set s \u00fc]}} 1
+test expr-8.14 {CompileBitAndExpr: equality expr} {expr 3eq2} 0
+test expr-8.15 {CompileBitAndExpr: equality expr} {expr 2.0eq2} 0
+test expr-8.16 {CompileBitAndExpr: equality expr} {expr 3.2ne2.2} 1
+test expr-8.17 {CompileBitAndExpr: equality expr} {expr 01eq1} 0
+test expr-8.18 {CompileBitAndExpr: equality expr} {expr {"abc" eq "abd"}} 0
+test expr-8.19 {CompileBitAndExpr: equality expr} {expr {"abc" ne "abd"}} 1
+test expr-8.20 {CompileBitAndExpr: error in equality expr} -body {
+ expr x ne3
+} -returnCodes error -match glob -result *
+test expr-8.21 {CompileBitAndExpr: error in equality expr} -body {
+ # These should be ""ed to avoid the error
+ expr a eq b
+} -returnCodes error -match glob -result *
+test expr-8.22 {CompileBitAndExpr: error in equality expr} -body {
+ expr {false eqfalse}
+} -returnCodes error -match glob -result *
+test expr-8.23 {CompileBitAndExpr: error in equality expr} -body {
+ expr {false nefalse}
+} -returnCodes error -match glob -result *
+test expr-8.24 {CompileEqualityExpr: simple equality exprs} {
+ set x 12398712938788234
+ expr {$x == 100}
+} 0
+test expr-8.25 {CompileEqualityExpr: simple equality exprs} {
+ expr {"0x12 " == "0x12"}
+} 1
+test expr-8.26 {CompileEqualityExpr: simple equality exprs} {
+ expr {"0x12 " eq "0x12"}
+} 0
+test expr-8.27 {CompileEqualityExpr: simple equality exprs} {
+ expr {"1.0e100000000" == "0.0"}
+} 0
+test expr-8.28 {CompileEqualityExpr: just relational expr} {
+ expr {"0y" == "0x0"}
+} 0
+test expr-8.29 {CompileEqualityExpr: just relational expr} {
+ # Compare original strings from variables.
+ set v1 "0y"
+ set v2 "0x12"
+ expr {$v1 < $v2}
+} 0
+test expr-8.30 {CompileEqualityExpr: simple equality exprs} {
+ expr {"fake" != "bob"}
+} 1
+test expr-8.31 {expr edge cases} -body {
+ expr {1e}
+} -returnCodes error -match glob -result *
+test expr-8.32 {expr edge cases} -body {
+ expr {1E}
+} -returnCodes error -match glob -result *
+test expr-8.33 {expr edge cases} -body {
+ expr {1e+}
+} -returnCodes error -match glob -result *
+test expr-8.34 {expr edge cases} -body {
+ expr {1E+}
+} -returnCodes error -match glob -result *
+test expr-8.35 {expr edge cases} -body {
+ expr {1ea}
+} -returnCodes error -match glob -result *
+
+test expr-9.1 {CompileRelationalExpr: just shift expr} {expr 3<<2} 12
+test expr-9.2 {CompileRelationalExpr: just shift expr} {expr 0xff>>2} 63
+test expr-9.3 {CompileRelationalExpr: just shift expr} {expr -1>>2} -1
+test expr-9.4 {CompileRelationalExpr: just shift expr} {expr {1<<3}} 8
+test expr-9.5a {CompileRelationalExpr: shift expr producing LONG_MIN} longIs64bit {
+ expr {int(1<<63)}
+} -9223372036854775808
+test expr-9.5b {CompileRelationalExpr: shift expr producing LONG_MIN} longIs32bit {
+ expr {int(1<<31)}
+} -2147483648
+test expr-9.6 {CompileRelationalExpr: error in shift expr} -body {
+ expr x>>3
+} -returnCodes error -match glob -result *
+test expr-9.7 {CompileRelationalExpr: simple relational exprs} {expr 0xff>=+0x3} 1
+test expr-9.8 {CompileRelationalExpr: simple relational exprs} {expr -0xf2<0x3} 1
+test expr-9.9 {CompileRelationalExpr: error compiling relational arm} -body {
+ expr 2***3>6
+} -returnCodes error -match glob -result *
+test expr-9.10 {CompileRelationalExpr: error compiling relational arm} -body {
+ expr 2<x
+} -returnCodes error -match glob -result *
+
+test expr-10.1 {CompileShiftExpr: just add expr} {expr 4+-2} 2
+test expr-10.2 {CompileShiftExpr: just add expr} {expr 0xff-2} 253
+test expr-10.3 {CompileShiftExpr: just add expr} {expr -1--2} 1
+test expr-10.4 {CompileShiftExpr: just add expr} {expr 1-0o123} -82
+test expr-10.5 {CompileShiftExpr: error in add expr} -body {
+ expr x+3
+} -returnCodes error -match glob -result *
+test expr-10.6 {CompileShiftExpr: simple shift exprs} {expr 0xff>>0x3} 31
+test expr-10.7 {CompileShiftExpr: simple shift exprs} {expr -0xf2<<0x3} -1936
+test expr-10.8 {CompileShiftExpr: error compiling shift arm} -body {
+ expr 2***3>>6
+} -returnCodes error -match glob -result *
+test expr-10.9 {CompileShiftExpr: error compiling shift arm} -body {
+ expr 2<<x
+} -returnCodes error -match glob -result *
+test expr-10.10 {CompileShiftExpr: runtime error} {
+ list [catch {expr {24.0>>43}} msg] $msg
+} {1 {can't use floating-point value as operand of ">>"}}
+test expr-10.11 {CompileShiftExpr: runtime error} {
+ list [catch {expr {"a"<<"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "<<"}}
+
+test expr-11.1 {CompileAddExpr: just multiply expr} {expr 4*-2} -8
+test expr-11.2 {CompileAddExpr: just multiply expr} {expr 0xff%2} 1
+test expr-11.3 {CompileAddExpr: just multiply expr} {expr -1/2} -1
+test expr-11.4 {CompileAddExpr: just multiply expr} {expr 7891%0o123} 6
+test expr-11.5 {CompileAddExpr: error in multiply expr} -body {
+ expr x*3
+} -returnCodes error -match glob -result *
+test expr-11.6 {CompileAddExpr: simple add exprs} {expr 0xff++0x3} 258
+test expr-11.7 {CompileAddExpr: simple add exprs} {expr -0xf2--0x3} -239
+test expr-11.8 {CompileAddExpr: error compiling add arm} -body {
+ expr 2***3+6
+} -returnCodes error -match glob -result *
+test expr-11.9 {CompileAddExpr: error compiling add arm} -body {
+ expr 2-x
+} -returnCodes error -match glob -result *
+test expr-11.10 {CompileAddExpr: runtime error} {
+ list [catch {expr {24.0+"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-11.11 {CompileAddExpr: runtime error} {
+ list [catch {expr {"a"-"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+test expr-11.12 {CompileAddExpr: runtime error} {
+ list [catch {expr {3/0}} msg] $msg
+} {1 {divide by zero}}
+test expr-11.13a {CompileAddExpr: runtime error} !ieeeFloatingPoint {
+ list [catch {expr {2.3/0.0}} msg] $msg
+} {1 {divide by zero}}
+test expr-11.13b {CompileAddExpr: runtime error} ieeeFloatingPoint {
+ list [catch {expr {2.3/0.0}} msg] $msg
+} {0 Inf}
+
+test expr-12.1 {CompileMultiplyExpr: just unary expr} {expr ~4} -5
+test expr-12.2 {CompileMultiplyExpr: just unary expr} {expr --5} 5
+test expr-12.3 {CompileMultiplyExpr: just unary expr} {expr !27} 0
+test expr-12.4 {CompileMultiplyExpr: just unary expr} {expr ~0xff00ff} -16711936
+test expr-12.5 {CompileMultiplyExpr: error in unary expr} -body {
+ expr ~x
+} -returnCodes error -match glob -result *
+test expr-12.6 {CompileMultiplyExpr: simple multiply exprs} {expr 0xff*0x3} 765
+test expr-12.7 {CompileMultiplyExpr: simple multiply exprs} {expr -0xf2%-0x3} -2
+test expr-12.8 {CompileMultiplyExpr: error compiling multiply arm} -body {
+ expr 2*3%%6
+} -returnCodes error -match glob -result *
+test expr-12.9 {CompileMultiplyExpr: error compiling multiply arm} -body {
+ expr 2*x
+} -returnCodes error -match glob -result *
+test expr-12.10 {CompileMultiplyExpr: runtime error} {
+ list [catch {expr {24.0*"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "*"}}
+test expr-12.11 {CompileMultiplyExpr: runtime error} {
+ list [catch {expr {"a"/"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+
+test expr-13.1 {CompileUnaryExpr: unary exprs} {expr -0xff} -255
+test expr-13.2 {CompileUnaryExpr: unary exprs} {expr +0o00123} 83
+test expr-13.3 {CompileUnaryExpr: unary exprs} {expr +--++36} 36
+test expr-13.4 {CompileUnaryExpr: unary exprs} {expr !2} 0
+test expr-13.5 {CompileUnaryExpr: unary exprs} {expr +--+-62.0} -62.0
+test expr-13.6 {CompileUnaryExpr: unary exprs} {expr !0.0} 1
+test expr-13.7 {CompileUnaryExpr: unary exprs} {expr !0xef} 0
+test expr-13.8 {CompileUnaryExpr: error compiling unary expr} -body {
+ expr ~x
+} -returnCodes error -match glob -result *
+test expr-13.9 {CompileUnaryExpr: error compiling unary expr} -body {
+ expr !1.x
+} -returnCodes error -match glob -result *
+test expr-13.10 {CompileUnaryExpr: runtime error} {
+ list [catch {expr {~"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "~"}}
+test expr-13.11 {CompileUnaryExpr: runtime error} {
+ list [catch {expr ~4.0} msg] $msg
+} {1 {can't use floating-point value as operand of "~"}}
+test expr-13.12 {CompileUnaryExpr: just primary expr} {expr 0x123} 291
+test expr-13.13 {CompileUnaryExpr: just primary expr} {
+ set a 27
+ expr $a
+} 27
+test expr-13.14 {CompileUnaryExpr: just primary expr} {
+ expr double(27)
+} 27.0
+test expr-13.15 {CompileUnaryExpr: just primary expr} {expr "123"} 123
+test expr-13.16 {CompileUnaryExpr: error in primary expr} {
+ catch {expr [set]} msg
+ set msg
+} {wrong # args: should be "set varName ?newValue?"}
+test expr-13.17 {CompileUnaryExpr: negating non-numeric boolean literals} {
+ set a1 yes; set a0 no; set b1 true; set b0 false
+ list [expr {!$a1}] [expr {!$a0}] [expr {!$b1}] [expr {!$b0}]
+} {0 1 0 1}
+
+test expr-14.1 {CompilePrimaryExpr: literal primary} {expr 1} 1
+test expr-14.2 {CompilePrimaryExpr: literal primary} {expr 123} 123
+test expr-14.3 {CompilePrimaryExpr: literal primary} {expr 0xff} 255
+test expr-14.4 {CompilePrimaryExpr: literal primary} {expr 0o0010} 8
+test expr-14.5 {CompilePrimaryExpr: literal primary} {expr 62.0} 62.0
+test expr-14.6 {CompilePrimaryExpr: literal primary} {
+ expr 3.1400000
+} 3.14
+test expr-14.7 {CompilePrimaryExpr: literal primary} {expr {{abcde}<{abcdef}}} 1
+test expr-14.8 {CompilePrimaryExpr: literal primary} {expr {{abc\
+def} < {abcdef}}} 1
+test expr-14.9 {CompilePrimaryExpr: literal primary} {expr {{abc\tde} > {abc\tdef}}} 0
+test expr-14.10 {CompilePrimaryExpr: literal primary} {expr {{123}}} 123
+test expr-14.11 {CompilePrimaryExpr: var reference primary} {
+ set i 789
+ list [expr {$i}] [expr $i]
+} {789 789}
+test expr-14.12 {CompilePrimaryExpr: var reference primary} {
+ set i {789} ;# test expr's aggressive conversion to numeric semantics
+ list [expr {$i}] [expr $i]
+} {789 789}
+test expr-14.13 {CompilePrimaryExpr: var reference primary} {
+ catch {unset a}
+ set a(foo) foo
+ set a(bar) bar
+ set a(123) 123
+ set result ""
+ lappend result [expr $a(123)] [expr {$a(bar)<$a(foo)}]
+ catch {unset a}
+ set result
+} {123 1}
+test expr-14.14 {CompilePrimaryExpr: var reference primary} {
+ set i 123 ;# test "$var.0" floating point conversion hack
+ list [expr $i] [expr $i.0] [expr $i.0/12.0]
+} {123 123.0 10.25}
+test expr-14.15 {CompilePrimaryExpr: var reference primary} {
+ set i 123
+ catch {expr $i.2} msg
+ set msg
+} 123.2
+test expr-14.16 {CompilePrimaryExpr: error compiling var reference primary} -body {
+ expr {$a(foo}
+} -returnCodes error -match glob -result *
+test expr-14.17 {CompilePrimaryExpr: string primary that looks like var ref} -body {
+ expr $
+} -returnCodes error -match glob -result *
+test expr-14.18 {CompilePrimaryExpr: quoted string primary} {
+ expr "21"
+} 21
+test expr-14.19 {CompilePrimaryExpr: quoted string primary} {
+ set i 123
+ set x 456
+ expr "$i+$x"
+} 579
+test expr-14.20 {CompilePrimaryExpr: quoted string primary} {
+ set i 3
+ set x 6
+ expr 2+"$i.$x"
+} 5.6
+test expr-14.21 {CompilePrimaryExpr: error in quoted string primary} {
+ catch {expr "[set]"} msg
+ set msg
+} {wrong # args: should be "set varName ?newValue?"}
+test expr-14.22 {CompilePrimaryExpr: subcommand primary} {
+ expr {[set i 123; set i]}
+} 123
+test expr-14.23 {CompilePrimaryExpr: error in subcommand primary} -body {
+ catch {expr {[set]}} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test expr-14.24 {CompilePrimaryExpr: error in subcommand primary} -body {
+ expr {[set i}
+} -returnCodes error -match glob -result *
+test expr-14.25 {CompilePrimaryExpr: math function primary} {
+ format %.6g [expr exp(1.0)]
+} 2.71828
+test expr-14.26 {CompilePrimaryExpr: math function primary} {
+ format %.6g [expr pow(2.0+0.1,3.0+0.1)]
+} 9.97424
+test expr-14.27 {CompilePrimaryExpr: error in math function primary} -body {
+ expr sinh::(2.0)
+} -returnCodes error -match glob -result *
+test expr-14.28 {CompilePrimaryExpr: subexpression primary} {
+ expr 2+(3*4)
+} 14
+test expr-14.29 {CompilePrimaryExpr: error in subexpression primary} -body {
+ catch {expr 2+(3*[set])} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test expr-14.30 {CompilePrimaryExpr: missing paren in subexpression primary} -body {
+ expr 2+(3*(4+5)
+} -returnCodes error -match glob -result *
+test expr-14.31 {CompilePrimaryExpr: just var ref in subexpression primary} {
+ set i "5+10"
+ list "[expr $i] == 15" "[expr ($i)] == 15" "[eval expr ($i)] == 15"
+} {{15 == 15} {15 == 15} {15 == 15}}
+test expr-14.32 {CompilePrimaryExpr: unexpected token} -body {
+ expr @
+} -returnCodes error -match glob -result *
+
+test expr-15.1 {CompileMathFuncCall: missing parenthesis} -body {
+ expr sinh2.0)
+} -returnCodes error -match glob -result *
+test expr-15.2 {CompileMathFuncCall: unknown math function} -body {
+ catch {expr whazzathuh(1)} msg
+ set ::errorInfo
+} -match glob -result {* "*whazzathuh"
+ while *ing
+"expr whazzathuh(1)"}
+test expr-15.3 {CompileMathFuncCall: too many arguments} -body {
+ catch {expr sin(1,2,3)} msg
+ set ::errorInfo
+} -match glob -result {too many arguments for math function*
+ while *ing
+"expr sin(1,2,3)"}
+test expr-15.4 {CompileMathFuncCall: ')' found before last required arg} -body {
+ catch {expr sin()} msg
+ set ::errorInfo
+} -match glob -result {too few arguments for math function*
+ while *ing
+"expr sin()"}
+test expr-15.5 {CompileMathFuncCall: too few arguments} -body {
+ catch {expr pow(1)} msg
+ set ::errorInfo
+} -match glob -result {too few arguments for math function*
+ while *ing
+"expr pow(1)"}
+test expr-15.6 {CompileMathFuncCall: missing ')'} -body {
+ expr sin(1
+} -returnCodes error -match glob -result *
+test expr-15.7 {CompileMathFuncCall: call registered math function} {testmathfunctions} {
+ expr 2*T1()
+} 246
+test expr-15.8 {CompileMathFuncCall: call registered math function} {testmathfunctions} {
+ expr T2()*3
+} 1035
+test expr-15.9 {CompileMathFuncCall: call registered math function} {testmathfunctions} {
+ expr T3(21, 37)
+} 37
+test expr-15.10 {CompileMathFuncCall: call registered math function} {testmathfunctions} {
+ expr T3(21.2, 37)
+} 37.0
+test expr-15.11 {CompileMathFuncCall: call registered math function} {testmathfunctions} {
+ expr T3(-21.2, -17.5)
+} -17.5
+test expr-15.12 {ExprCallMathFunc: call registered math function} {testmathfunctions} {
+ expr T3(21, wide(37))
+} 37
+test expr=15.13 {ExprCallMathFunc: call registered math function} {testmathfunctions} {
+ expr T3(wide(21), 37)
+} 37
+test expr=15.14 {ExprCallMathFunc: call registered math function} {testmathfunctions} {
+ expr T3(wide(21), wide(37))
+} 37
+test expr-15.15 {ExprCallMathFunc: call registered math function} {testmathfunctions} {
+ expr T3(21.0, wide(37))
+} 37.0
+test expr-15.16 {ExprCallMathFunc: call registered math function} {testmathfunctions} {
+ expr T3(wide(21), 37.0)
+} 37.0
+test expr-15.17 {ExprCallMathFunc: non-numeric arg} -constraints {
+ testmathfunctions
+} -body {
+ expr T3(0,"a")
+} -returnCodes error -result {argument to math function didn't have numeric value}
+
+
+test expr-16.1 {GetToken: checks whether integer token starting with "0x" (e.g., "0x$") is invalid} {
+ catch {unset a}
+ set a(VALUE) ff15
+ set i 123
+ if {[expr 0x$a(VALUE)] & 16} {
+ set i {}
+ }
+ set i
+} {}
+test expr-16.2 {GetToken: check for string literal in braces} {
+ expr {{1}}
+} {1}
+
+# Check "expr" and computed command names.
+
+test expr-17.1 {expr and computed command names} {
+ set i 0
+ set z expr
+ $z 1+2
+} 3
+
+# Check correct conversion of operands to numbers: If the string looks like
+# an integer, convert to integer. Otherwise, if the string looks like a
+# double, convert to double.
+
+test expr-18.1 {expr and conversion of operands to numbers} {
+ set x [lindex 11 0]
+ catch {expr int($x)}
+ expr {$x}
+} 11
+test expr-18.2 {whitespace strings should not be == 0 (buggy strtod)} {
+ expr {" "}
+} { }
+
+# Check "expr" and interpreter result object resetting before appending
+# an error msg during evaluation of exprs not in {}s
+
+test expr-19.1 {expr and interpreter result object resetting} {
+ proc p {} {
+ set t 10.0
+ set x 2.0
+ set dx 0.2
+ set f {$dx-$x/10}
+ set g {-$x/5}
+ set center 1.0
+ set x [expr $x-$center]
+ set dx [expr $dx+$g]
+ set x [expr $x+$f+$center]
+ set x [expr $x+$f+$center]
+ set y [expr round($x)]
+ }
+ p
+} 3
+
+# Test for incorrect "double evaluation" semantics
+
+test expr-20.1 {wrong brace matching} {
+ catch {unset l}
+ catch {unset r}
+ catch {unset q}
+ catch {unset cmd}
+ catch {unset a}
+ set l "\{"; set r "\}"; set q "\""
+ set cmd "expr $l$q|$q == $q$r$q$r"
+ list [catch $cmd a] $a
+} {1 {extra characters after close-brace}}
+test expr-20.2 {double invocation of variable traces} -body {
+ set exprtracecounter 0
+ proc exprtraceproc {args} {
+ upvar #0 exprtracecounter counter
+ set argc [llength $args]
+ set extraargs [lrange $args 0 [expr {$argc - 4}]]
+ set name [lindex $args [expr {$argc - 3}]]
+ upvar 1 $name var
+ if {[incr counter] % 2 == 1} {
+ set var "$counter oops [concat $extraargs]"
+ } else {
+ set var "$counter + [concat $extraargs]"
+ }
+ }
+ trace variable exprtracevar r [list exprtraceproc 10]
+ list [catch {expr "$exprtracevar + 20"} a] $a \
+ [catch {expr "$exprtracevar + 20"} b] $b \
+ [unset exprtracevar exprtracecounter]
+} -match glob -result {1 * 0 32 {}}
+test expr-20.3 {broken substitution of integer digits} {
+ # fails with 8.0.x, but not 8.1b2
+ list [set a 000; expr 0x1$a] [set a 1; expr ${a}000]
+} {4096 1000}
+test expr-20.4 {proper double evaluation compilation, error case} {
+ catch {unset a}; # make sure $a doesn't exist
+ list [catch {expr 1?{$a}:0} msg] $msg
+} {1 {can't read "a": no such variable}}
+test expr-20.5 {proper double evaluation compilation, working case} {
+ set a yellow
+ expr 1?{$a}:0
+} yellow
+test expr-20.6 {handling of compile error in trial compile} {
+ list [catch {expr + {[incr]}} msg] $msg
+} {1 {wrong # args: should be "incr varName ?increment?"}}
+test expr-20.7 {handling of compile error in runtime case} {
+ list [catch {expr + {[error foo]}} msg] $msg
+} {1 foo}
+
+# Test for non-numeric boolean literal handling
+test expr-21.1 {non-numeric boolean literals} {expr false } false
+test expr-21.2 {non-numeric boolean literals} {expr true } true
+test expr-21.3 {non-numeric boolean literals} {expr off } off
+test expr-21.4 {non-numeric boolean literals} {expr on } on
+test expr-21.5 {non-numeric boolean literals} {expr no } no
+test expr-21.6 {non-numeric boolean literals} {expr yes } yes
+test expr-21.7 {non-numeric boolean literals} {expr !false} 1
+test expr-21.8 {non-numeric boolean literals} {expr !true } 0
+test expr-21.9 {non-numeric boolean literals} {expr !off } 1
+test expr-21.10 {non-numeric boolean literals} {expr !on } 0
+test expr-21.11 {non-numeric boolean literals} {expr !no } 1
+test expr-21.12 {non-numeric boolean literals} {expr !yes } 0
+test expr-21.13 {non-numeric boolean literals} -body {
+ expr !truef
+} -returnCodes error -match glob -result *
+test expr-21.14 {non-numeric boolean literals} {
+ list [catch {expr !"truef"} err] $err
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-21.15 {non-numeric boolean variables} {
+ set v truef
+ list [catch {expr {!$v}} err] $err
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-21.16 {non-numeric boolean variables} {
+ set v "true "
+ list [catch {expr {!$v}} err] $err
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-21.17 {non-numeric boolean variables} {
+ set v "tru"
+ list [catch {expr {!$v}} err] $err
+} {0 0}
+test expr-21.18 {non-numeric boolean variables} {
+ set v "fal"
+ list [catch {expr {!$v}} err] $err
+} {0 1}
+test expr-21.19 {non-numeric boolean variables} {
+ set v "y"
+ list [catch {expr {!$v}} err] $err
+} {0 0}
+test expr-21.20 {non-numeric boolean variables} {
+ set v "of"
+ list [catch {expr {!$v}} err] $err
+} {0 1}
+test expr-21.21 {non-numeric boolean variables} {
+ set v "o"
+ list [catch {expr {!$v}} err] $err
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-21.22 {non-numeric boolean variables} {
+ set v ""
+ list [catch {expr {!$v}} err] $err
+} {1 {can't use empty string as operand of "!"}}
+
+# Test for non-numeric float handling.
+test expr-22.1 {non-numeric floats} {
+ list [catch {expr {NaN + 1}} msg] $msg
+} {1 {can't use non-numeric floating-point value as operand of "+"}}
+test expr-22.2 {non-numeric floats} !ieeeFloatingPoint {
+ list [catch {expr {Inf + 1}} msg] $msg
+} {1 {can't use infinite floating-point value as operand of "+"}}
+test expr-22.3 {non-numeric floats} {
+ set nan NaN
+ list [catch {expr {$nan + 1}} msg] $msg
+} {1 {can't use non-numeric floating-point value as operand of "+"}}
+test expr-22.4 {non-numeric floats} !ieeeFloatingPoint {
+ set inf Inf
+ list [catch {expr {$inf + 1}} msg] $msg
+} {1 {can't use infinite floating-point value as operand of "+"}}
+test expr-22.5 {non-numeric floats} {
+ list [catch {expr NaN} msg] $msg
+} {1 {domain error: argument not in valid range}}
+test expr-22.6 {non-numeric floats} !ieeeFloatingPoint {
+ list [catch {expr Inf} msg] $msg
+} {1 {floating-point value too large to represent}}
+test expr-22.7 {non-numeric floats} {
+ list [catch {expr {1 / NaN}} msg] $msg
+} {1 {can't use non-numeric floating-point value as operand of "/"}}
+test expr-22.8 {non-numeric floats} !ieeeFloatingPoint {
+ list [catch {expr {1 / Inf}} msg] $msg
+} {1 {can't use infinite floating-point value as operand of "/"}}
+# Make sure [Bug 761471] stays fixed.
+test expr-22.9 {non-numeric floats: shared object equality and NaN} {
+ set x NaN
+ expr {$x == $x}
+} 0
+
+# Tests for exponentiation handling
+test expr-23.1 {CompileExponentialExpr: just exponential expr} {expr 4**2} 16
+test expr-23.2 {CompileExponentialExpr: just exponential expr} {expr 0xff**2} 65025
+test expr-23.3 {CompileExponentialExpr: just exponential expr} {expr -1**2} 1
+test expr-23.4 {CompileExponentialExpr: just exponential expr} {expr 18**07} 612220032
+test expr-23.5 {CompileExponentialExpr: error in exponential expr} -body {
+ expr x**3
+} -returnCodes error -match glob -result *
+test expr-23.6 {CompileExponentialExpr: simple expo exprs} {expr 0xff**0x3} 16581375
+test expr-23.7 {CompileExponentialExpr: error compiling expo arm} -body {
+ expr (-3-)**6
+} -returnCodes error -match glob -result *
+test expr-23.8 {CompileExponentialExpr: error compiling expo arm} -body {
+ expr 2**x
+} -returnCodes error -match glob -result *
+test expr-23.9 {CompileExponentialExpr: runtime error} {
+ list [catch {expr {24.0**"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "**"}}
+test expr-23.10 {CompileExponentialExpr: runtime error} {
+ list [catch {expr {"a"**2}} msg] $msg
+} {1 {can't use non-numeric string as operand of "**"}}
+test expr-23.11 {CompileExponentialExpr: runtime error} {
+ list [catch {expr {0**-1}} msg] $msg
+} {1 {exponentiation of zero by negative power}}
+test expr-23.12 {CompileExponentialExpr: runtime error} {
+ list [catch {expr {0.0**-1.0}} msg] $msg
+} {1 {exponentiation of zero by negative power}}
+test expr-23.13 {CompileExponentialExpr: runtime error} {
+ list [catch {expr {wide(0)**wide(-1)}} msg] $msg
+} {1 {exponentiation of zero by negative power}}
+test expr-23.14 {INST_EXPON: special cases} {expr {0**1}} 0
+test expr-23.15 {INST_EXPON: special cases} {expr {0**0}} 1
+test expr-23.16 {INST_EXPON: special cases} {expr {-2**-1}} 0
+test expr-23.17 {INST_EXPON: special cases} {expr {-2**0}} 1
+test expr-23.18 {INST_EXPON: special cases} {expr {-1**1}} -1
+test expr-23.19 {INST_EXPON: special cases} {expr {-1**0}} 1
+test expr-23.20 {INST_EXPON: special cases} {expr {-1**2}} 1
+test expr-23.21 {INST_EXPON: special cases} {expr {-1**-1}} -1
+test expr-23.22 {INST_EXPON: special cases} {expr {1**1234567}} 1
+test expr-23.23 {INST_EXPON: special cases} {expr {2**-2}} 0
+test expr-23.24 {INST_EXPON: special cases} {expr {wide(0)**wide(1)}} 0
+test expr-23.25 {INST_EXPON: special cases} {expr {wide(0)**wide(0)}} 1
+test expr-23.26 {INST_EXPON: special cases} {expr {wide(-2)**wide(-1)}} 0
+test expr-23.27 {INST_EXPON: special cases} {expr {wide(-2)**wide(0)}} 1
+test expr-23.28 {INST_EXPON: special cases} {expr {wide(-1)**wide(1)}} -1
+test expr-23.29 {INST_EXPON: special cases} {expr {wide(-1)**wide(0)}} 1
+test expr-23.30 {INST_EXPON: special cases} {expr {wide(-1)**wide(2)}} 1
+test expr-23.31 {INST_EXPON: special cases} {expr {wide(-1)**wide(-1)}} -1
+test expr-23.32 {INST_EXPON: special cases} {expr {wide(1)**wide(1234567)}} 1
+test expr-23.33 {INST_EXPON: special cases} {expr {wide(2)**wide(-2)}} 0
+test expr-23.34 {INST_EXPON: special cases} {expr {2**0}} 1
+test expr-23.35 {INST_EXPON: special cases} {expr {wide(2)**0}} 1
+test expr-23.36 {INST_EXPON: big integer} {expr {10**17}} 1[string repeat 0 17]
+test expr-23.37 {INST_EXPON: big integer} {expr {10**18}} 1[string repeat 0 18]
+test expr-23.38 {INST_EXPON: big integer} {expr {10**19}} 1[string repeat 0 19]
+test expr-23.39 {INST_EXPON: big integer} {
+ expr 1[string repeat 0 30]**2
+} 1[string repeat 0 60]
+test expr-23.40 {INST_EXPON: overflow to big integer} {expr {(-10)**3}} -1000
+test expr-23.41 {INST_EXPON: overflow to big integer} {expr 2**64} [expr 1<<64]
+test expr-23.42 {INST_EXPON: overflow to big integer} {expr 4**32} [expr 1<<64]
+test expr-23.43 {INST_EXPON: overflow to big integer} {expr 16**16} [expr 1<<64]
+test expr-23.44 {INST_EXPON: overflow to big integer} {expr 256**8} [expr 1<<64]
+test expr-23.45 {INST_EXPON: Bug 1555371} {expr 2**1} 2
+test expr-23.46 {INST_EXPON: Bug 1561260} -body {
+ expr 5**28
+} -match glob -result *5
+test expr-23.47 {INST_EXPON: Bug 1561260} {
+ expr 2**32*5**32
+} 1[string repeat 0 32]
+test expr-23.48 {INST_EXPON: TIP 274: right assoc} {
+expr 2**3**4
+} 2417851639229258349412352
+test expr-23.49 {INST_EXPON: optimize powers of 2} {
+ set trouble {test powers of 2}
+ for {set tval 0} {$tval <= 66} {incr tval} {
+ set is [expr {2 ** $tval}]
+ set sb [expr {1 << $tval}]
+ if {$is != $sb} {
+ append trouble \n "2**" $tval " is " $is " should be " $sb
+ }
+ if {$tval >= 1} {
+ set is [expr {-2 ** $tval}]
+ set sb [expr {1 << $tval}]
+ if {$tval & 1} {
+ set sb [expr {-$sb}]
+ }
+ if {$is != $sb} {
+ append trouble \n "-2**" $tval " is " $is " should be " $sb
+ }
+ }
+ }
+ set trouble
+} {test powers of 2}
+test expr-23.50 {INST_EXPON: small powers of 32-bit integers} {
+ set trouble {test small powers of 32-bit ints}
+ for {set base 3} {$base <= 45} {incr base} {
+ set sb $base
+ set sbm [expr {-$base}]
+ for {set expt 2} {$expt <= 8} {incr expt} {
+ set sb [expr {$sb * $base}]
+ set is [expr {$base ** $expt}]
+ if {$sb != $is} {
+ append trouble \n $base ** $expt " is " $is " should be " $sb
+ }
+ set sbm [expr {-$sbm * $base}]
+ set ism [expr {(-$base) ** $expt}]
+ if {$sbm != $ism} {
+ append trouble \n - $base ** $expt " is " $ism \
+ " should be " $sbm
+ }
+ }
+ }
+ set trouble
+} {test small powers of 32-bit ints}
+test expr-23.51 {INST_EXPON: intermediate powers of 32-bit integers} {
+ set trouble {test intermediate powers of 32-bit ints}
+ for {set base 3} {$base <= 11} {incr base} {
+ set sb [expr {$base ** 8}]
+ set sbm $sb
+ for {set expt 9} {$expt <= 21} {incr expt} {
+ set sb [expr {$sb * $base}]
+ set sbm [expr {$sbm * -$base}]
+ set is [expr {$base ** $expt}]
+ set ism [expr {-$base ** $expt}]
+ if {$sb != $is} {
+ append trouble \n $base ** $expt " is " $is " should be " $sb
+ }
+ if {$sbm != $ism} {
+ append trouble \n - $base ** $expt " is " $ism \
+ " should be " $sbm
+ }
+ }
+ }
+ set trouble
+} {test intermediate powers of 32-bit ints}
+test expr-23.52 {INST_EXPON: small integer powers with 64-bit results} {
+ set trouble {test small int powers with 64-bit results}
+ for {set exp 2} {$exp <= 16} {incr exp} {
+ set base [expr {entier(pow(double(0x7fffffffffffffff),(1.0/$exp)))}]
+ set sb 1
+ set sbm 1
+ for {set i 0} {$i < $exp} {incr i} {
+ set sb [expr {$sb * $base}]
+ set sbm [expr {$sbm * -$base}]
+ }
+ set is [expr {$base ** $exp}]
+ set ism [expr {-$base ** $exp}]
+ if {$sb != $is} {
+ append trouble \n $base ** $exp " is " $is " should be " $sb
+ }
+ if {$sbm != $ism} {
+ append trouble \n - $base ** $exp " is " $ism " should be " $sbm
+ }
+ incr base
+ set sb 1
+ set sbm 1
+ for {set i 0} {$i < $exp} {incr i} {
+ set sb [expr {$sb * $base}]
+ set sbm [expr {$sbm * -$base}]
+ }
+ set is [expr {$base ** $exp}]
+ set ism [expr {-$base ** $exp}]
+ if {$sb != $is} {
+ append trouble \n $base ** $exp " is " $is " should be " $sb
+ }
+ if {$sbm != $ism} {
+ append trouble \n - $base ** $exp " is " $ism " should be " $sbm
+ }
+ }
+ set trouble
+} {test small int powers with 64-bit results}
+test expr-23.53 {INST_EXPON: intermediate powers of 64-bit integers} {
+ set trouble {test intermediate powers of 64-bit ints}
+ for {set base 3} {$base <= 13} {incr base} {
+ set sb [expr {$base ** 15}]
+ set sbm [expr {-$sb}]
+ for {set expt 16} {$expt <= 39} {incr expt} {
+ set sb [expr {$sb * $base}]
+ set sbm [expr {$sbm * -$base}]
+ set is [expr {$base ** $expt}]
+ set ism [expr {-$base ** $expt}]
+ if {$sb != $is} {
+ append trouble \n $base ** $expt " is " $is " should be " $sb
+ }
+ if {$sbm != $ism} {
+ append trouble \n - $base ** $expt " is " $ism \
+ " should be " $sbm
+ }
+ }
+ }
+ set trouble
+} {test intermediate powers of 64-bit ints}
+test expr-23.54.0 {INST_EXPON: Bug 2798543} {
+ expr {3**9 == 3**65545}
+} 0
+test expr-23.54.1 {INST_EXPON: Bug 2798543} {
+ expr {3**10 == 3**65546}
+} 0
+test expr-23.54.2 {INST_EXPON: Bug 2798543} {
+ expr {3**11 == 3**65547}
+} 0
+test expr-23.54.3 {INST_EXPON: Bug 2798543} {
+ expr {3**12 == 3**65548}
+} 0
+test expr-23.54.4 {INST_EXPON: Bug 2798543} {
+ expr {3**13 == 3**65549}
+} 0
+test expr-23.54.5 {INST_EXPON: Bug 2798543} {
+ expr {3**14 == 3**65550}
+} 0
+test expr-23.54.6 {INST_EXPON: Bug 2798543} {
+ expr {3**15 == 3**65551}
+} 0
+test expr-23.54.7 {INST_EXPON: Bug 2798543} {
+ expr {3**16 == 3**65552}
+} 0
+test expr-23.54.8 {INST_EXPON: Bug 2798543} {
+ expr {3**17 == 3**65553}
+} 0
+test expr-23.54.9 {INST_EXPON: Bug 2798543} {
+ expr {3**18 == 3**65554}
+} 0
+test expr-23.54.10 {INST_EXPON: Bug 2798543} {
+ expr {3**19 == 3**65555}
+} 0
+test expr-23.54.11 {INST_EXPON: Bug 2798543} {
+ expr {3**9 == 3**131081}
+} 0
+test expr-23.54.12 {INST_EXPON: Bug 2798543} -body {
+ expr {3**9 == 3**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.54.13 {INST_EXPON: Bug 2798543} {
+ expr {(-3)**9 == (-3)**65545}
+} 0
+test expr-23.55.0 {INST_EXPON: Bug 2798543} {
+ expr {4**9 == 4**65545}
+} 0
+test expr-23.55.1 {INST_EXPON: Bug 2798543} {
+ expr {4**15 == 4**65551}
+} 0
+test expr-23.55.2 {INST_EXPON: Bug 2798543} {
+ expr {4**9 == 4**131081}
+} 0
+test expr-23.55.3 {INST_EXPON: Bug 2798543} -body {
+ expr {4**9 == 4**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.55.4 {INST_EXPON: Bug 2798543} {
+ expr {(-4)**9 == (-4)**65545}
+} 0
+test expr-23.56.0 {INST_EXPON: Bug 2798543} {
+ expr {5**9 == 5**65545}
+} 0
+test expr-23.56.1 {INST_EXPON: Bug 2798543} {
+ expr {5**13 == 5**65549}
+} 0
+test expr-23.56.2 {INST_EXPON: Bug 2798543} {
+ expr {5**9 == 5**131081}
+} 0
+test expr-23.56.3 {INST_EXPON: Bug 2798543} -body {
+ expr {5**9 == 5**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.56.4 {INST_EXPON: Bug 2798543} {
+ expr {(-5)**9 == (-5)**65545}
+} 0
+test expr-23.57.0 {INST_EXPON: Bug 2798543} {
+ expr {6**9 == 6**65545}
+} 0
+test expr-23.57.1 {INST_EXPON: Bug 2798543} {
+ expr {6**11 == 6**65547}
+} 0
+test expr-23.57.2 {INST_EXPON: Bug 2798543} {
+ expr {6**9 == 6**131081}
+} 0
+test expr-23.57.3 {INST_EXPON: Bug 2798543} -body {
+ expr {6**9 == 6**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.57.4 {INST_EXPON: Bug 2798543} {
+ expr {(-6)**9 == (-6)**65545}
+} 0
+test expr-23.58.0 {INST_EXPON: Bug 2798543} {
+ expr {7**9 == 7**65545}
+} 0
+test expr-23.58.1 {INST_EXPON: Bug 2798543} {
+ expr {7**11 == 7**65547}
+} 0
+test expr-23.58.2 {INST_EXPON: Bug 2798543} {
+ expr {7**9 == 7**131081}
+} 0
+test expr-23.58.3 {INST_EXPON: Bug 2798543} -body {
+ expr {7**9 == 7**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.58.4 {INST_EXPON: Bug 2798543} {
+ expr {(-7)**9 == (-7)**65545}
+} 0
+test expr-23.59.0 {INST_EXPON: Bug 2798543} {
+ expr {8**9 == 8**65545}
+} 0
+test expr-23.59.1 {INST_EXPON: Bug 2798543} {
+ expr {8**10 == 8**65546}
+} 0
+test expr-23.59.2 {INST_EXPON: Bug 2798543} {
+ expr {8**9 == 8**131081}
+} 0
+test expr-23.59.3 {INST_EXPON: Bug 2798543} -body {
+ expr {8**9 == 8**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.59.4 {INST_EXPON: Bug 2798543} {
+ expr {(-8)**9 == (-8)**65545}
+} 0
+test expr-23.60.0 {INST_EXPON: Bug 2798543} {
+ expr {9**9 == 9**65545}
+} 0
+test expr-23.60.1 {INST_EXPON: Bug 2798543} {
+ expr {9**9 == 9**131081}
+} 0
+test expr-23.60.2 {INST_EXPON: Bug 2798543} -body {
+ expr {9**9 == 9**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.60.3 {INST_EXPON: Bug 2798543} {
+ expr {(-9)**9 == (-9)**65545}
+} 0
+test expr-23.61.0 {INST_EXPON: Bug 2798543} {
+ expr {10**9 == 10**65545}
+} 0
+test expr-23.61.1 {INST_EXPON: Bug 2798543} {
+ expr {10**9 == 10**131081}
+} 0
+test expr-23.61.2 {INST_EXPON: Bug 2798543} -body {
+ expr {10**9 == 10**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.61.3 {INST_EXPON: Bug 2798543} {
+ expr {(-10)**9 == (-10)**65545}
+} 0
+test expr-23.62.0 {INST_EXPON: Bug 2798543} {
+ expr {11**9 == 11**65545}
+} 0
+test expr-23.62.1 {INST_EXPON: Bug 2798543} {
+ expr {11**9 == 11**131081}
+} 0
+test expr-23.62.2 {INST_EXPON: Bug 2798543} -body {
+ expr {11**9 == 11**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.62.3 {INST_EXPON: Bug 2798543} {
+ expr {(-11)**9 == (-11)**65545}
+} 0
+test expr-23.63.0 {INST_EXPON: Bug 2798543} {
+ expr {3**20 == 3**65556}
+} 0
+test expr-23.63.1 {INST_EXPON: Bug 2798543} {
+ expr {3**39 == 3**65575}
+} 0
+test expr-23.63.2 {INST_EXPON: Bug 2798543} {
+ expr {3**20 == 3**131092}
+} 0
+test expr-23.63.3 {INST_EXPON: Bug 2798543} -body {
+ expr {3**20 == 3**268435476}
+} -returnCodes error -result {exponent too large}
+test expr-23.63.4 {INST_EXPON: Bug 2798543} {
+ expr {(-3)**20 == (-3)**65556}
+} 0
+test expr-23.64.0 {INST_EXPON: Bug 2798543} {
+ expr {4**17 == 4**65553}
+} 0
+test expr-23.64.1 {INST_EXPON: Bug 2798543} {
+ expr {4**31 == 4**65567}
+} 0
+test expr-23.64.2 {INST_EXPON: Bug 2798543} {
+ expr {4**17 == 4**131089}
+} 0
+test expr-23.64.3 {INST_EXPON: Bug 2798543} -body {
+ expr {4**17 == 4**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.64.4 {INST_EXPON: Bug 2798543} {
+ expr {(-4)**17 == (-4)**65553}
+} 0
+test expr-23.65.0 {INST_EXPON: Bug 2798543} {
+ expr {5**17 == 5**65553}
+} 0
+test expr-23.65.1 {INST_EXPON: Bug 2798543} {
+ expr {5**27 == 5**65563}
+} 0
+test expr-23.65.2 {INST_EXPON: Bug 2798543} {
+ expr {5**17 == 5**131089}
+} 0
+test expr-23.65.3 {INST_EXPON: Bug 2798543} -body {
+ expr {5**17 == 5**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.65.4 {INST_EXPON: Bug 2798543} {
+ expr {(-5)**17 == (-5)**65553}
+} 0
+test expr-23.66.0 {INST_EXPON: Bug 2798543} {
+ expr {6**17 == 6**65553}
+} 0
+test expr-23.66.1 {INST_EXPON: Bug 2798543} {
+ expr {6**24 == 6**65560}
+} 0
+test expr-23.66.2 {INST_EXPON: Bug 2798543} {
+ expr {6**17 == 6**131089}
+} 0
+test expr-23.66.3 {INST_EXPON: Bug 2798543} -body {
+ expr {6**17 == 6**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.66.4 {INST_EXPON: Bug 2798543} {
+ expr {(-6)**17 == (-6)**65553}
+} 0
+test expr-23.67.0 {INST_EXPON: Bug 2798543} {
+ expr {7**17 == 7**65553}
+} 0
+test expr-23.67.1 {INST_EXPON: Bug 2798543} {
+ expr {7**22 == 7**65558}
+} 0
+test expr-23.67.2 {INST_EXPON: Bug 2798543} {
+ expr {7**17 == 7**131089}
+} 0
+test expr-23.67.3 {INST_EXPON: Bug 2798543} -body {
+ expr {7**17 == 7**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.67.4 {INST_EXPON: Bug 2798543} {
+ expr {(-7)**17 == (-7)**65553}
+} 0
+test expr-23.68.0 {INST_EXPON: Bug 2798543} {
+ expr {8**17 == 8**65553}
+} 0
+test expr-23.68.1 {INST_EXPON: Bug 2798543} {
+ expr {8**20 == 8**65556}
+} 0
+test expr-23.68.2 {INST_EXPON: Bug 2798543} {
+ expr {8**17 == 8**131089}
+} 0
+test expr-23.68.3 {INST_EXPON: Bug 2798543} -body {
+ expr {8**17 == 8**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.68.4 {INST_EXPON: Bug 2798543} {
+ expr {(-8)**17 == (-8)**65553}
+} 0
+test expr-23.69.0 {INST_EXPON: Bug 2798543} {
+ expr {9**17 == 9**65553}
+} 0
+test expr-23.69.1 {INST_EXPON: Bug 2798543} {
+ expr {9**19 == 9**65555}
+} 0
+test expr-23.69.2 {INST_EXPON: Bug 2798543} {
+ expr {9**17 == 9**131089}
+} 0
+test expr-23.69.3 {INST_EXPON: Bug 2798543} -body {
+ expr {9**17 == 9**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.69.4 {INST_EXPON: Bug 2798543} {
+ expr {(-9)**17 == (-9)**65553}
+} 0
+test expr-23.70.0 {INST_EXPON: Bug 2798543} {
+ expr {10**17 == 10**65553}
+} 0
+test expr-23.70.1 {INST_EXPON: Bug 2798543} {
+ expr {10**18 == 10**65554}
+} 0
+test expr-23.70.2 {INST_EXPON: Bug 2798543} {
+ expr {10**17 == 10**131089}
+} 0
+test expr-23.70.3 {INST_EXPON: Bug 2798543} -body {
+ expr {10**17 == 10**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.70.4 {INST_EXPON: Bug 2798543} {
+ expr {(-10)**17 == (-10)**65553}
+} 0
+test expr-23.71.0 {INST_EXPON: Bug 2798543} {
+ expr {11**17 == 11**65553}
+} 0
+test expr-23.71.1 {INST_EXPON: Bug 2798543} {
+ expr {11**18 == 11**65554}
+} 0
+test expr-23.71.2 {INST_EXPON: Bug 2798543} {
+ expr {11**17 == 11**131089}
+} 0
+test expr-23.71.3 {INST_EXPON: Bug 2798543} -body {
+ expr {11**17 == 11**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.71.4 {INST_EXPON: Bug 2798543} {
+ expr {(-11)**17 == (-11)**65553}
+} 0
+test expr-23.72.0 {INST_EXPON: Bug 2798543} {
+ expr {12**17 == 12**65553}
+} 0
+test expr-23.72.1 {INST_EXPON: Bug 2798543} {
+ expr {12**17 == 12**131089}
+} 0
+test expr-23.72.2 {INST_EXPON: Bug 2798543} -body {
+ expr {12**17 == 12**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.72.3 {INST_EXPON: Bug 2798543} {
+ expr {(-12)**17 == (-12)**65553}
+} 0
+test expr-23.73.0 {INST_EXPON: Bug 2798543} {
+ expr {13**17 == 13**65553}
+} 0
+test expr-23.73.1 {INST_EXPON: Bug 2798543} {
+ expr {13**17 == 13**131089}
+} 0
+test expr-23.73.2 {INST_EXPON: Bug 2798543} -body {
+ expr {13**17 == 13**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.73.3 {INST_EXPON: Bug 2798543} {
+ expr {(-13)**17 == (-13)**65553}
+} 0
+test expr-23.74.0 {INST_EXPON: Bug 2798543} {
+ expr {14**17 == 14**65553}
+} 0
+test expr-23.74.1 {INST_EXPON: Bug 2798543} {
+ expr {14**17 == 14**131089}
+} 0
+test expr-23.74.2 {INST_EXPON: Bug 2798543} -body {
+ expr {14**17 == 14**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.74.3 {INST_EXPON: Bug 2798543} {
+ expr {(-14)**17 == (-14)**65553}
+} 0
+
+
+# Some compilers get this wrong; ensure that we work around it correctly
+test expr-24.1 {expr edge cases; shifting} {expr int(5)>>32} 0
+test expr-24.2 {expr edge cases; shifting} {expr int(5)>>63} 0
+test expr-24.3 {expr edge cases; shifting} {expr wide(5)>>32} 0
+test expr-24.4 {expr edge cases; shifting} {expr wide(5)>>63} 0
+test expr-24.5 {expr edge cases; shifting} longIs32bit {expr int(5<<32)} 0
+test expr-24.6 {expr edge cases; shifting} longIs32bit {expr int(5<<63)} 0
+test expr-24.7 {expr edge cases; shifting} {expr wide(5)<<32} 21474836480
+test expr-24.8 {expr edge cases; shifting} {expr wide(10<<63)} 0
+test expr-24.9 {expr edge cases; shifting} {expr 5>>32} 0
+
+test expr-24.10 {INST_LSHIFT: Bug 1567222} {expr 500000000000000<<28} 134217728000000000000000
+
+# List membership tests
+test expr-25.1 {'in' operator} {expr {"a" in "a b c"}} 1
+test expr-25.2 {'in' operator} {expr {"a" in "b a c"}} 1
+test expr-25.3 {'in' operator} {expr {"a" in "b c a"}} 1
+test expr-25.4 {'in' operator} {expr {"a" in ""}} 0
+test expr-25.5 {'in' operator} {expr {"" in {a b c ""}}} 1
+test expr-25.6 {'in' operator} {expr {"" in "a b c"}} 0
+test expr-25.7 {'in' operator} {expr {"" in ""}} 0
+
+test expr-26.1 {'ni' operator} {expr {"a" ni "a b c"}} 0
+test expr-26.2 {'ni' operator} {expr {"a" ni "b a c"}} 0
+test expr-26.3 {'ni' operator} {expr {"a" ni "b c a"}} 0
+test expr-26.4 {'ni' operator} {expr {"a" ni ""}} 1
+test expr-26.5 {'ni' operator} {expr {"" ni {a b c ""}}} 0
+test expr-26.6 {'ni' operator} {expr {"" ni "a b c"}} 1
+test expr-26.7 {'ni' operator} {expr {"" ni ""}} 1
+
+foreach op {< <= == != > >=} {
+ proc test$op {a b} [list expr "\$a $op \$b"]
+}
+
+test expr-27.1 {expr - correct ordering - not compiled} ieeeFloatingPoint {
+ set problems {}
+ # Ordering should be: -Infinity < -Normal < Subnormal < -0
+ # < +0 < +Subnormal < +Normal < +Infinity
+ # with equality within each class.
+ set names {
+ -Infinity -Normal -Subnormal -0 +0 +Subnormal +Normal +Infinity
+ }
+ set weights {
+ -3 -2 -1 0 0 1 2 3
+ }
+ foreach name1 $names weight1 $weights {
+ foreach name2 $names weight2 $weights {
+ foreach op {< <= == != >= >} {
+ set shouldBe [expr "$weight1 $op $weight2"]
+ set is [expr "\$ieeeValues($name1) $op \$ieeeValues($name2)"]
+ if { $is != $shouldBe } {
+ append problems $name1 { } $op { } $name2 \
+ ":result is " $is ", should be $shouldBe" \n
+ }
+ }
+ }
+ }
+ set problems
+} {}
+test expr-27.2 {expr - correct ordering - compiled} ieeeFloatingPoint {
+ set problems {}
+ # Ordering should be: -Infinity < -Normal < Subnormal < -0
+ # < +0 < +Subnormal < +Normal < +Infinity
+ # with equality within each class.
+ set names {
+ -Infinity -Normal -Subnormal -0 +0 +Subnormal +Normal +Infinity
+ }
+ set weights {
+ -3 -2 -1 0 0 1 2 3
+ }
+ foreach name1 $names weight1 $weights {
+ foreach name2 $names weight2 $weights {
+ foreach op {< <= == != >= >} {
+ set shouldBe [expr "$weight1 $op $weight2"]
+ set is [test$op $ieeeValues($name1) $ieeeValues($name2)]
+ if { $is != $shouldBe } {
+ append problems $name1 { } $op { } $name2 \
+ ":result is " $is ", should be $shouldBe" \n
+ }
+ }
+ }
+ }
+ set problems
+} {}
+test expr-27.3 {expr - NaN is unordered - not compiled} {
+ set problems {}
+ set names {
+ -Infinity -Normal -Subnormal -0 +0 +Subnormal +Normal +Infinity NaN
+ }
+ foreach name1 $names {
+ foreach op {< <= == != >= >} sb {0 0 0 1 0 0} {
+ if "(\$ieeeValues($name1) $op \$ieeeValues(NaN)) != $sb " {
+ append problems $name1 { } $op { } NaN \
+ ": result is 1, should be $sb" \n
+ }
+ if "(\$ieeeValues(NaN) $op \$ieeeValues($name1)) != $sb" {
+ append problems NaN { } $op { } $name1 \
+ ": result is 1, should be $sb" \n
+ }
+ }
+ }
+ set problems
+} {}
+test expr-27.4 {expr - NaN is unordered - compiled} {
+ set problems {}
+ set names {
+ -Infinity -Normal -Subnormal -0 +0 +Subnormal +Normal +Infinity NaN
+ }
+ foreach name1 $names {
+ foreach op {< <= == != >= >} sb {0 0 0 1 0 0} {
+ if { [test$op $ieeeValues($name1) $ieeeValues(NaN)] != $sb } {
+ append problems $ieeeValues($name1) { } $op { } $ieeeValues(NaN) \
+ ": result is 1, should be $sb" \n
+ }
+ if { [test$op $ieeeValues(NaN) $ieeeValues($name1)] != $sb } {
+ append problems NaN { } $op { } $ieeeValues($name1) \
+ ": result is 1, should be $sb" \n
+ }
+ }
+ }
+ set problems
+} {}
+
+proc convertToDouble { x } {
+ variable ieeeValues
+ binary scan [binary format d $x] c* bytes
+ set result 0x
+ if { $ieeeValues(littleEndian) } {
+ for { set i 7 } { $i >= 0 } { incr i -1 } {
+ append result [format %02x [expr { [lindex $bytes $i] & 0xff }]]
+ }
+ } else {
+ foreach byte $bytes {
+ append result [format %02x [expr { $byte & 0xff }]]
+ }
+ }
+ return $result
+}
+
+test expr-28.1 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 0 E0 OK 00000000000000 E-1023
+ convertToDouble 0E0
+} 0x0000000000000000
+test expr-28.2 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL -0 E0 OK -0000000000000 E-1023
+ convertToDouble -0E0
+} 0x8000000000000000
+test expr-28.3 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 1 E0 OK 10000000000000 E0
+ convertToDouble 1E0
+} 0x3ff0000000000000
+test expr-28.4 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 15 E-1 OK 18000000000000 E0
+ convertToDouble 15E-1
+} 0x3ff8000000000000
+test expr-28.5 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 125 E-2 OK 14000000000000 E0
+ convertToDouble 125E-2
+} 0x3ff4000000000000
+test expr-28.6 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 1125 E-3 OK 12000000000000 E0
+ convertToDouble 1125E-3
+} 0x3ff2000000000000
+test expr-28.7 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 10625 E-4 OK 11000000000000 E0
+ convertToDouble 10625E-4
+} 0x3ff1000000000000
+test expr-28.8 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 103125 E-5 OK 10800000000000 E0
+ convertToDouble 103125E-5
+} 0x3ff0800000000000
+test expr-28.9 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 1015625 E-6 OK 10400000000000 E0
+ convertToDouble 1015625E-6
+} 0x3ff0400000000000
+test expr-28.10 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 10078125 E-7 OK 10200000000000 E0
+ convertToDouble 10078125E-7
+} 0x3ff0200000000000
+test expr-28.11 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d ALL 100390625 E-8 OK 10100000000000 E0
+ convertToDouble 100390625E-8
+} 0x3ff0100000000000
+test expr-28.12 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee ALL 1001953125 E-9 OK 10080000000000 E0
+ convertToDouble 1001953125E-9
+} 0x3ff0080000000000
+test expr-28.13 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee ALL 10009765625 E-10 OK 10040000000000 E0
+ convertToDouble 10009765625E-10
+} 0x3ff0040000000000
+test expr-28.14 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee ALL 100048828125 E-11 OK 10020000000000 E0
+ convertToDouble 100048828125E-11
+} 0x3ff0020000000000
+test expr-28.15 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee ALL 1000244140625 E-12 OK 10010000000000 E0
+ convertToDouble 1000244140625E-12
+} 0x3ff0010000000000
+test expr-28.16 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee ALL 10001220703125 E-13 OK 10008000000000 E0
+ convertToDouble 10001220703125E-13
+} 0x3ff0008000000000
+test expr-28.17 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee ALL 100006103515625 E-14 OK 10004000000000 E0
+ convertToDouble 100006103515625E-14
+} 0x3ff0004000000000
+test expr-28.18 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee ALL 1000030517578125 E-15 OK 10002000000000 E0
+ convertToDouble 1000030517578125E-15
+} 0x3ff0002000000000
+test expr-28.19 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee ALL 10000152587890625 E-16 OK 10001000000000 E0
+ convertToDouble 10000152587890625E-16
+} 0x3ff0001000000000
+test expr-28.20 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8 E153 x 1317e5ef3ab327_0000000001& E511
+ convertToDouble +8E153
+} 0x5fe317e5ef3ab327
+test expr-28.21 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1 E153 x -1317e5ef3ab327_0000000001& E508
+ convertToDouble -1E153
+} 0xdfb317e5ef3ab327
+test expr-28.22 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9 E306 x 19a2028368022e_00000000001& E1019
+ convertToDouble +9E306
+} 0x7fa9a2028368022e
+test expr-28.23 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -2 E153 x -1317e5ef3ab327_0000000001& E509
+ convertToDouble -2E153
+} 0xdfc317e5ef3ab327
+test expr-28.24 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7 E-304 x 1eb8e84fa0b278_00000000001& E-1008
+ convertToDouble +7E-304
+} 0x00feb8e84fa0b278
+test expr-28.25 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3 E-49 x -1c0f92a6276c9d_000000001& E-162
+ convertToDouble -3E-49
+} 0xb5dc0f92a6276c9d
+test expr-28.26 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7 E-303 x 13339131c46f8b_00000000001& E-1004
+ convertToDouble +7E-303
+} 0x0133339131c46f8b
+test expr-28.27 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -6 E-49 x -1c0f92a6276c9d_000000001& E-161
+ convertToDouble -6E-49
+} 0xb5ec0f92a6276c9d
+test expr-28.28 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9 E43 x 102498ea6df0c3_11111111110& E146
+ convertToDouble +9E43
+} 0x49102498ea6df0c4
+test expr-28.29 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9 E44 x -142dbf25096cf4_1111111110& E149
+ convertToDouble -9E44
+} 0xc9442dbf25096cf5
+test expr-28.30 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8 E303 x 1754e31cd072d9_1111111110& E1009
+ convertToDouble +8E303
+} 0x7f0754e31cd072da
+test expr-28.31 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1 E303 x -1754e31cd072d9_1111111110& E1006
+ convertToDouble -1E303
+} 0xfed754e31cd072da
+test expr-28.32 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7 E-287 x 1551603777f798_111111110& E-951
+ convertToDouble +7E-287
+} 0x048551603777f799
+test expr-28.33 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -2 E-204 x -1410d9f9b2f7f2_11111110& E-677
+ convertToDouble -2E-204
+} 0x95a410d9f9b2f7f3
+test expr-28.34 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2 E-205 x 100d7b2e28c65b_11111110& E-680
+ convertToDouble +2E-205
+} 0x15700d7b2e28c65c
+test expr-28.35 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9 E-47 x -10711fed5b19a3_11111110& E-153
+ convertToDouble -9E-47
+} 0xb660711fed5b19a4
+test expr-28.36 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +34 E195 x 1d1c26db7d0dae_000000000001& E652
+ convertToDouble +34E195
+} 0x68bd1c26db7d0dae
+test expr-28.37 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -68 E195 x -1d1c26db7d0dae_000000000001& E653
+ convertToDouble -68E195
+} 0xe8cd1c26db7d0dae
+test expr-28.38 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +85 E194 x 1d1c26db7d0dae_000000000001& E650
+ convertToDouble +85E194
+} 0x689d1c26db7d0dae
+test expr-28.39 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -67 E97 x -139ac1ce2cc95f_000000000001& E328
+ convertToDouble -67E97
+} 0xd4739ac1ce2cc95f
+test expr-28.40 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +93 E-234 x 127b2e4f210075_0000000000000001& E-771
+ convertToDouble +93E-234
+} 0x0fc27b2e4f210075
+test expr-28.41 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -19 E-87 x -12e5f5dfa4fe9d_00000000000001& E-285
+ convertToDouble -19E-87
+} 0xae22e5f5dfa4fe9d
+test expr-28.42 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +38 E-87 x 12e5f5dfa4fe9d_00000000000001& E-284
+ convertToDouble +38E-87
+} 0x2e32e5f5dfa4fe9d
+test expr-28.43 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -38 E-88 x -1e3cbc9907fdc8_00000000000001& E-288
+ convertToDouble -38E-88
+} 0xadfe3cbc9907fdc8
+test expr-28.44 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -69 E220 x -1e8aa8823a5db3_11111111110& E736
+ convertToDouble -69E220
+} 0xedfe8aa8823a5db4
+test expr-28.45 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +18 E43 x 102498ea6df0c3_11111111110& E147
+ convertToDouble +18E43
+} 0x49202498ea6df0c4
+test expr-28.46 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -36 E43 x -102498ea6df0c3_11111111110& E148
+ convertToDouble -36E43
+} 0xc9302498ea6df0c4
+test expr-28.47 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +61 E-99 x 10ad836f269a16_11111111111110& E-323
+ convertToDouble +61E-99
+} 0x2bc0ad836f269a17
+test expr-28.48 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -43 E-92 x -1c0794d9d40e95_111111111111110& E-301
+ convertToDouble -43E-92
+} 0xad2c0794d9d40e96
+test expr-28.49 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +86 E-92 x 1c0794d9d40e95_111111111111110& E-300
+ convertToDouble +86E-92
+} 0x2d3c0794d9d40e96
+test expr-28.50 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -51 E-74 x -1cd5bee57763e5_1111111111111110& E-241
+ convertToDouble -51E-74
+} 0xb0ecd5bee57763e6
+test expr-28.51 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +283 E85 x 16c309024bab4b_00000000000000001& E290
+ convertToDouble +283E85
+} 0x5216c309024bab4b
+test expr-28.52 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -566 E85 x -16c309024bab4b_00000000000000001& E291
+ convertToDouble -566E85
+} 0xd226c309024bab4b
+test expr-28.53 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +589 E187 x 1526be9c22eb17_00000000000000001& E630
+ convertToDouble +589E187
+} 0x675526be9c22eb17
+test expr-28.54 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -839 E143 x -1ae03f245703e2_000000000000001& E484
+ convertToDouble -839E143
+} 0xde3ae03f245703e2
+test expr-28.55 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -744 E-234 x -127b2e4f210075_0000000000000001& E-768
+ convertToDouble -744E-234
+} 0x8ff27b2e4f210075
+test expr-28.56 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +930 E-235 x 127b2e4f210075_0000000000000001& E-771
+ convertToDouble +930E-235
+} 0x0fc27b2e4f210075
+test expr-28.57 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -186 E-234 x -127b2e4f210075_0000000000000001& E-770
+ convertToDouble -186E-234
+} 0x8fd27b2e4f210075
+test expr-28.58 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +604 E175 x 17d93193f78fc5_1111111111111111110& E590
+ convertToDouble +604E175
+} 0x64d7d93193f78fc6
+test expr-28.59 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -302 E175 x -17d93193f78fc5_1111111111111111110& E589
+ convertToDouble -302E175
+} 0xe4c7d93193f78fc6
+test expr-28.60 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +755 E174 x 17d93193f78fc5_1111111111111111110& E587
+ convertToDouble +755E174
+} 0x64a7d93193f78fc6
+test expr-28.61 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -151 E175 x -17d93193f78fc5_1111111111111111110& E588
+ convertToDouble -151E175
+} 0xe4b7d93193f78fc6
+test expr-28.62 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +662 E-213 x 1bdb90e62a8cbc_1111111111111110& E-699
+ convertToDouble +662E-213
+} 0x144bdb90e62a8cbd
+test expr-28.63 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -408 E-74 x -1cd5bee57763e5_1111111111111110& E-238
+ convertToDouble -408E-74
+} 0xb11cd5bee57763e6
+test expr-28.64 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +510 E-75 x 1cd5bee57763e5_1111111111111110& E-241
+ convertToDouble +510E-75
+} 0x30ecd5bee57763e6
+test expr-28.65 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6782 E55 x 159bd3ad46e346_0000000000000000001& E195
+ convertToDouble +6782E55
+} 0x4c259bd3ad46e346
+test expr-28.66 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -2309 E92 x -1bac6f7d64d119_000000000000000001& E316
+ convertToDouble -2309E92
+} 0xd3bbac6f7d64d119
+test expr-28.67 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7963 E34 x 1df4170f0fdecc_00000000000000000001& E125
+ convertToDouble +7963E34
+} 0x47cdf4170f0fdecc
+test expr-28.68 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3391 E55 x -159bd3ad46e346_0000000000000000001& E194
+ convertToDouble -3391E55
+} 0xcc159bd3ad46e346
+test expr-28.69 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7903 E-96 x 107c2d27a5b989_0000000000000000001& E-306
+ convertToDouble +7903E-96
+} 0x2cd07c2d27a5b989
+test expr-28.70 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7611 E-226 x -119b8744033457_0000000000000000001& E-738
+ convertToDouble -7611E-226
+} 0x91d19b8744033457
+test expr-28.71 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +4907 E-196 x 11e90a8711440f_000000000000000001& E-639
+ convertToDouble +4907E-196
+} 0x1801e90a8711440f
+test expr-28.72 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5547 E-311 x -13f190452a29f4_000000000000000001& E-1021
+ convertToDouble -5547E-311
+} 0x8023f190452a29f4
+test expr-28.73 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +5311 E241 x 1f1ce3c887c25f_11111111111111111110& E812
+ convertToDouble +5311E241
+} 0x72bf1ce3c887c260
+test expr-28.74 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5311 E243 x -184e91f4aa0fda_11111111111111111110& E819
+ convertToDouble -5311E243
+} 0xf3284e91f4aa0fdb
+test expr-28.75 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +5311 E242 x 13720e5d54d97b_11111111111111111110& E816
+ convertToDouble +5311E242
+} 0x72f3720e5d54d97c
+test expr-28.76 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9269 E-45 x 19d69455a53bd8_111111111111111111110& E-137
+ convertToDouble +9269E-45
+} 0x3769d69455a53bd9
+test expr-28.77 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8559 E-289 x -104a81d35952fe_11111111111111111110& E-947
+ convertToDouble -8559E-289
+} 0x84c04a81d35952ff
+test expr-28.78 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8699 E-276 x 12d2df246ecd2c_1111111111111111111110& E-904
+ convertToDouble +8699E-276
+} 0x0772d2df246ecd2d
+test expr-28.79 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8085 E-64 x -14c98fce16152d_1111111111111111110& E-200
+ convertToDouble -8085E-64
+} 0xb374c98fce16152e
+test expr-28.80 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +74819 E201 x 1dd455061eb3f1_0000000000000000000001& E683
+ convertToDouble +74819E201
+} 0x6aadd455061eb3f1
+test expr-28.81 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -82081 E41 x -170105df3d47cb_000000000000000000000000001& E152
+ convertToDouble -82081E41
+} 0xc9770105df3d47cb
+test expr-28.82 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +51881 E37 x 17d2950dc76da4_000000000000000000001& E138
+ convertToDouble +51881E37
+} 0x4897d2950dc76da4
+test expr-28.83 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -55061 E157 x -1394fc0f33536c_000000000000000000001& E537
+ convertToDouble -55061E157
+} 0xe18394fc0f33536c
+test expr-28.84 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +77402 E-215 x 10492a4a8a37fd_0000000000000000000000001& E-698
+ convertToDouble +77402E-215
+} 0x1450492a4a8a37fd
+test expr-28.85 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -33891 E-92 x -1592f9932c06bd_00000000000000000000001& E-291
+ convertToDouble -33891E-92
+} 0xadc592f9932c06bd
+test expr-28.86 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +38701 E-215 x 10492a4a8a37fd_0000000000000000000000001& E-699
+ convertToDouble +38701E-215
+} 0x1440492a4a8a37fd
+test expr-28.87 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -82139 E-76 x -1d0681489839d5_00000000000000000000001& E-237
+ convertToDouble -82139E-76
+} 0xb12d0681489839d5
+test expr-28.88 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +75859 E25 x 132645e1ba93ef_11111111111111111111110& E99
+ convertToDouble +75859E25
+} 0x46232645e1ba93f0
+test expr-28.89 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +89509 E140 x 16f02bee68670c_1111111111111111111110& E481
+ convertToDouble +89509E140
+} 0x5e06f02bee68670d
+test expr-28.90 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -57533 E287 x -1272ed2307f569_1111111111111111111110& E969
+ convertToDouble -57533E287
+} 0xfc8272ed2307f56a
+test expr-28.91 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +46073 E-32 x 12405b773fbdf2_11111111111111111111110& E-91
+ convertToDouble +46073E-32
+} 0x3a42405b773fbdf3
+test expr-28.92 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -92146 E-32 x -12405b773fbdf2_11111111111111111111110& E-90
+ convertToDouble -92146E-32
+} 0xba52405b773fbdf3
+test expr-28.93 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +83771 E-74 x 17206bfc4ccabd_11111111111111111111110& E-230
+ convertToDouble +83771E-74
+} 0x3197206bfc4ccabe
+test expr-28.94 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -34796 E-276 x -12d2df246ecd2c_1111111111111111111110& E-902
+ convertToDouble -34796E-276
+} 0x8792d2df246ecd2d
+test expr-28.95 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +584169 E229 x 1d657059dc79aa_00000000000000000000000000001& E779
+ convertToDouble +584169E229
+} 0x70ad657059dc79aa
+test expr-28.96 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +164162 E41 x 170105df3d47cb_000000000000000000000000001& E153
+ convertToDouble +164162E41
+} 0x49870105df3d47cb
+test expr-28.97 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -328324 E41 x -170105df3d47cb_000000000000000000000000001& E154
+ convertToDouble -328324E41
+} 0xc9970105df3d47cb
+test expr-28.98 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +209901 E-11 x 119b96f36ec68b_00000000000000000000000001& E-19
+ convertToDouble +209901E-11
+} 0x3ec19b96f36ec68b
+test expr-28.99 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -419802 E-11 x -119b96f36ec68b_00000000000000000000000001& E-18
+ convertToDouble -419802E-11
+} 0xbed19b96f36ec68b
+test expr-28.100 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +940189 E-112 x 1b99d6240c1a28_00000000000000000000000001& E-353
+ convertToDouble +940189E-112
+} 0x29eb99d6240c1a28
+test expr-28.101 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -892771 E-213 x -125818c7294f27_0000000000000000000000000001& E-688
+ convertToDouble -892771E-213
+} 0x94f25818c7294f27
+test expr-28.102 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +757803 E120 x 11e968b555bb80_11111111111111111111111111110& E418
+ convertToDouble +757803E120
+} 0x5a11e968b555bb81
+test expr-28.103 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -252601 E120 x -17e1e0f1c7a4ab_11111111111111111111111111110& E416
+ convertToDouble -252601E120
+} 0xd9f7e1e0f1c7a4ac
+test expr-28.104 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +252601 E121 x 1dda592e398dd6_1111111111111111111111111110& E419
+ convertToDouble +252601E121
+} 0x5a2dda592e398dd7
+test expr-28.105 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -505202 E120 x -17e1e0f1c7a4ab_11111111111111111111111111110& E417
+ convertToDouble -505202E120
+} 0xda07e1e0f1c7a4ac
+test expr-28.106 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +970811 E-264 x 1dda6b965c9629_11111111111111111111111110& E-858
+ convertToDouble +970811E-264
+} 0x0a5dda6b965c962a
+test expr-28.107 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -654839 E-60 x -100e7db3b3f241_111111111111111111111111110& E-180
+ convertToDouble -654839E-60
+} 0xb4b00e7db3b3f242
+test expr-28.108 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +289767 E-178 x 1caad28f23a100_11111111111111111111111110& E-574
+ convertToDouble +289767E-178
+} 0x1c1caad28f23a101
+test expr-28.109 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -579534 E-178 x -1caad28f23a100_11111111111111111111111110& E-573
+ convertToDouble -579534E-178
+} 0x9c2caad28f23a101
+test expr-28.110 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8823691 E130 x -1e597c0b94b7ae_00000000000000000000000000000001& E454
+ convertToDouble -8823691E130
+} 0xdc5e597c0b94b7ae
+test expr-28.111 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9346704 E229 x 1d657059dc79aa_00000000000000000000000000001& E783
+ convertToDouble +9346704E229
+} 0x70ed657059dc79aa
+test expr-28.112 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1168338 E229 x -1d657059dc79aa_00000000000000000000000000001& E780
+ convertToDouble -1168338E229
+} 0xf0bd657059dc79aa
+test expr-28.113 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -6063369 E-136 x -1ae6148e3902b3_000000000000000000000000000001& E-430
+ convertToDouble -6063369E-136
+} 0xa51ae6148e3902b3
+test expr-28.114 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3865421 E-225 x 15d4fe53afec65_00000000000000000000000000001& E-726
+ convertToDouble +3865421E-225
+} 0x1295d4fe53afec65
+test expr-28.115 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5783893 E-127 x -17e5902ce0e151_000000000000000000000000000000001& E-400
+ convertToDouble -5783893E-127
+} 0xa6f7e5902ce0e151
+test expr-28.116 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2572231 E223 x 10f73be1dff9ac_111111111111111111111111111110& E762
+ convertToDouble +2572231E223
+} 0x6f90f73be1dff9ad
+test expr-28.117 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5144462 E223 x -10f73be1dff9ac_111111111111111111111111111110& E763
+ convertToDouble -5144462E223
+} 0xefa0f73be1dff9ad
+test expr-28.118 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +1817623 E109 x 1d85f96f3fe659_11111111111111111111111111110& E382
+ convertToDouble +1817623E109
+} 0x57dd85f96f3fe65a
+test expr-28.119 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6431543 E-97 x 14f6493f34a0bc_11111111111111111111111111110& E-300
+ convertToDouble +6431543E-97
+} 0x2d34f6493f34a0bd
+test expr-28.120 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -5444097 E-21 x -18849dd33c95ae_11111111111111111111111111110& E-48
+ convertToDouble -5444097E-21
+} 0xbcf8849dd33c95af
+test expr-28.121 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8076999 E-121 x 1fd332f7e2e3b2_11111111111111111111111111110& E-380
+ convertToDouble +8076999E-121
+} 0x283fd332f7e2e3b3
+test expr-28.122 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9997649 E-270 x -1425e9d29e558d_1111111111111111111111111110& E-874
+ convertToDouble -9997649E-270
+} 0x895425e9d29e558e
+test expr-28.123 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +50609263 E157 x 1193aff1f1c8e3_000000000000000000000000000000001& E547
+ convertToDouble +50609263E157
+} 0x622193aff1f1c8e3
+test expr-28.124 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +70589528 E130 x 1e597c0b94b7ae_00000000000000000000000000000001& E457
+ convertToDouble +70589528E130
+} 0x5c8e597c0b94b7ae
+test expr-28.125 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -88236910 E129 x -1e597c0b94b7ae_00000000000000000000000000000001& E454
+ convertToDouble -88236910E129
+} 0xdc5e597c0b94b7ae
+test expr-28.126 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +87575437 E-310 x 1805c19e680456_0000000000000000000000000000000000001& E-1004
+ convertToDouble +87575437E-310
+} 0x013805c19e680456
+test expr-28.127 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -23135572 E-127 x -17e5902ce0e151_000000000000000000000000000000001& E-398
+ convertToDouble -23135572E-127
+} 0xa717e5902ce0e151
+test expr-28.128 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +85900881 E177 x 14375b2214e1b4_111111111111111111111111111111110& E614
+ convertToDouble +85900881E177
+} 0x6654375b2214e1b5
+test expr-28.129 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -84863171 E113 x -1a4a8e56474b8b_111111111111111111111111111111110& E401
+ convertToDouble -84863171E113
+} 0xd90a4a8e56474b8c
+test expr-28.130 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +68761586 E232 x 1a662c350f37f2_1111111111111111111111111111110& E796
+ convertToDouble +68761586E232
+} 0x71ba662c350f37f3
+test expr-28.131 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -50464069 E286 x -1948dd06de561e_1111111111111111111111111111110& E975
+ convertToDouble -50464069E286
+} 0xfce948dd06de561f
+test expr-28.132 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +27869147 E-248 x 1dbbac6f83a820_111111111111111111111111111111111110& E-800
+ convertToDouble +27869147E-248
+} 0x0dfdbbac6f83a821
+test expr-28.133 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -55738294 E-248 x -1dbbac6f83a820_111111111111111111111111111111111110& E-799
+ convertToDouble -55738294E-248
+} 0x8e0dbbac6f83a821
+test expr-28.134 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +70176353 E-53 x 100683a21de854_1111111111111111111111111111111110& E-150
+ convertToDouble +70176353E-53
+} 0x36900683a21de855
+test expr-28.135 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -80555086 E-32 x -1f29ca0ff893b0_111111111111111111111111111111110& E-81
+ convertToDouble -80555086E-32
+} 0xbaef29ca0ff893b1
+test expr-28.136 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -491080654 E121 x -1c569e968e0944_00000000000000000000000000000000000000001& E430
+ convertToDouble -491080654E121
+} 0xdadc569e968e0944
+test expr-28.137 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +526250918 E287 x 14997a298b2f2e_0000000000000000000000000000000000001& E982
+ convertToDouble +526250918E287
+} 0x7d54997a298b2f2e
+test expr-28.138 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -245540327 E121 x -1c569e968e0944_00000000000000000000000000000000000000001& E429
+ convertToDouble -245540327E121
+} 0xdacc569e968e0944
+test expr-28.139 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -175150874 E-310 x -1805c19e680456_0000000000000000000000000000000000001& E-1003
+ convertToDouble -175150874E-310
+} 0x814805c19e680456
+test expr-28.140 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +350301748 E-310 x 1805c19e680456_0000000000000000000000000000000000001& E-1002
+ convertToDouble +350301748E-310
+} 0x015805c19e680456
+test expr-28.141 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -437877185 E-311 x -1805c19e680456_0000000000000000000000000000000000001& E-1005
+ convertToDouble -437877185E-311
+} 0x812805c19e680456
+test expr-28.142 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +458117166 E52 x 16ce94febdc7a4_1111111111111111111111111111111111110& E201
+ convertToDouble +458117166E52
+} 0x4c86ce94febdc7a5
+test expr-28.143 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -916234332 E52 x -16ce94febdc7a4_1111111111111111111111111111111111110& E202
+ convertToDouble -916234332E52
+} 0xcc96ce94febdc7a5
+test expr-28.144 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +229058583 E52 x 16ce94febdc7a4_1111111111111111111111111111111111110& E200
+ convertToDouble +229058583E52
+} 0x4c76ce94febdc7a5
+test expr-28.145 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -525789935 E98 x -16ecdc2a58fc64_11111111111111111111111111111111110& E354
+ convertToDouble -525789935E98
+} 0xd616ecdc2a58fc65
+test expr-28.146 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +282926897 E-227 x 1ff5a70d3d2fee_1111111111111111111111111111111111110& E-727
+ convertToDouble +282926897E-227
+} 0x128ff5a70d3d2fef
+test expr-28.147 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -565853794 E-227 x -1ff5a70d3d2fee_1111111111111111111111111111111111110& E-726
+ convertToDouble -565853794E-227
+} 0x929ff5a70d3d2fef
+test expr-28.148 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +667284113 E-240 x 109355f8050c01_111111111111111111111111111111111110& E-768
+ convertToDouble +667284113E-240
+} 0x0ff09355f8050c02
+test expr-28.149 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -971212611 E-126 x -1397d3c9745d2e_111111111111111111111111111111111111110& E-389
+ convertToDouble -971212611E-126
+} 0xa7a397d3c9745d2f
+test expr-28.150 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9981396317 E-182 x 18afe10a2a66aa_0000000000000000000000000000000000000001& E-572
+ convertToDouble +9981396317E-182
+} 0x1c38afe10a2a66aa
+test expr-28.151 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5035231965 E-156 x -101891fc4717fd_00000000000000000000000000000000000001& E-486
+ convertToDouble -5035231965E-156
+} 0xa1901891fc4717fd
+test expr-28.152 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8336960483 E-153 x 1a06a1024b95e1_000000000000000000000000000000000000001& E-476
+ convertToDouble +8336960483E-153
+} 0x223a06a1024b95e1
+test expr-28.153 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8056371144 E-155 x -101891fc4717fd_00000000000000000000000000000000000001& E-482
+ convertToDouble -8056371144E-155
+} 0xa1d01891fc4717fd
+test expr-28.154 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6418488827 E79 x 1021f14ed7b3f9_11111111111111111111111111111111111111110& E295
+ convertToDouble +6418488827E79
+} 0x526021f14ed7b3fa
+test expr-28.155 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3981006983 E252 x -102ebaf189d5f1_1111111111111111111111111111111111111110& E869
+ convertToDouble -3981006983E252
+} 0xf6402ebaf189d5f2
+test expr-28.156 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7962013966 E252 x 102ebaf189d5f1_1111111111111111111111111111111111111110& E870
+ convertToDouble +7962013966E252
+} 0x76502ebaf189d5f2
+test expr-28.157 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -4713898551 E261 x -11d8813536e0df_11111111111111111111111111111111111110& E899
+ convertToDouble -4713898551E261
+} 0xf821d8813536e0e0
+test expr-28.158 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8715380633 E-58 x 14614c3219891e_11111111111111111111111111111111111111110& E-160
+ convertToDouble +8715380633E-58
+} 0x35f4614c3219891f
+test expr-28.159 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9078555839 E-109 x -1fc575867314ed_111111111111111111111111111111111111111111110& E-330
+ convertToDouble -9078555839E-109
+} 0xab5fc575867314ee
+test expr-28.160 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9712126110 E-127 x 1397d3c9745d2e_111111111111111111111111111111111111110& E-389
+ convertToDouble +9712126110E-127
+} 0x27a397d3c9745d2f
+test expr-28.161 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +42333842451 E201 x 10189a26df575f_000000000000000000000000000000000000000000001& E703
+ convertToDouble +42333842451E201
+} 0x6be0189a26df575f
+test expr-28.162 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -84667684902 E201 x -10189a26df575f_000000000000000000000000000000000000000000001& E704
+ convertToDouble -84667684902E201
+} 0xebf0189a26df575f
+test expr-28.163 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +23792120709 E-315 x 10b517dc5d3212_00000000000000000000000000000000000000001& E-1012
+ convertToDouble +23792120709E-315
+} 0x00b0b517dc5d3212
+test expr-28.164 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -78564021519 E-227 x -1155515fd37265_00000000000000000000000000000000000000000001& E-718
+ convertToDouble -78564021519E-227
+} 0x931155515fd37265
+test expr-28.165 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +71812054883 E-188 x 1747b46d78c6fe_00000000000000000000000000000000000000001& E-589
+ convertToDouble +71812054883E-188
+} 0x1b2747b46d78c6fe
+test expr-28.166 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -30311163631 E-116 x -163ef6f560afe7_00000000000000000000000000000000000000001& E-351
+ convertToDouble -30311163631E-116
+} 0xaa063ef6f560afe7
+test expr-28.167 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +71803914657 E292 x 10c0c44cdc2c05_11111111111111111111111111111111111111111110& E1006
+ convertToDouble +71803914657E292
+} 0x7ed0c0c44cdc2c06
+test expr-28.168 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +36314223356 E-109 x 1fc575867314ed_111111111111111111111111111111111111111111110& E-328
+ convertToDouble +36314223356E-109
+} 0x2b7fc575867314ee
+test expr-28.169 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +18157111678 E-109 x 1fc575867314ed_111111111111111111111111111111111111111111110& E-329
+ convertToDouble +18157111678E-109
+} 0x2b6fc575867314ee
+test expr-28.170 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -45392779195 E-110 x -1fc575867314ed_111111111111111111111111111111111111111111110& E-331
+ convertToDouble -45392779195E-110
+} 0xab4fc575867314ee
+test expr-28.171 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +778380362293 E218 x 19ab8261990292_0000000000000000000000000000000000000000000000000001& E763
+ convertToDouble +778380362293E218
+} 0x6fa9ab8261990292
+test expr-28.172 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -685763015669 E280 x -15fd7aa44d9477_000000000000000000000000000000000000000000000001& E969
+ convertToDouble -685763015669E280
+} 0xfc85fd7aa44d9477
+test expr-28.173 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +952918668151 E70 x 14177a9915fbf8_00000000000000000000000000000000000000000000001& E272
+ convertToDouble +952918668151E70
+} 0x50f4177a9915fbf8
+test expr-28.174 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -548357443505 E32 x -13abde2775e9b5_0000000000000000000000000000000000000000000001& E145
+ convertToDouble -548357443505E32
+} 0xc903abde2775e9b5
+test expr-28.175 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +384865004907 E-285 x 1aa65b58639e69_00000000000000000000000000000000000000000000001& E-909
+ convertToDouble +384865004907E-285
+} 0x072aa65b58639e69
+test expr-28.176 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -769730009814 E-285 x -1aa65b58639e69_00000000000000000000000000000000000000000000001& E-908
+ convertToDouble -769730009814E-285
+} 0x873aa65b58639e69
+test expr-28.177 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +697015418417 E-93 x 152847dad80453_0000000000000000000000000000000000000000000001& E-270
+ convertToDouble +697015418417E-93
+} 0x2f152847dad80453
+test expr-28.178 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -915654049301 E-28 x -1a645598d05989_0000000000000000000000000000000000000000000001& E-54
+ convertToDouble -915654049301E-28
+} 0xbc9a645598d05989
+test expr-28.179 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +178548656339 E169 x 1b89d67c5b6d24_111111111111111111111111111111111111111111110& E598
+ convertToDouble +178548656339E169
+} 0x655b89d67c5b6d25
+test expr-28.180 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -742522891517 E259 x -1c1c352fc3c308_11111111111111111111111111111111111111111111110& E899
+ convertToDouble -742522891517E259
+} 0xf82c1c352fc3c309
+test expr-28.181 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +742522891517 E258 x 167cf7596968d3_11111111111111111111111111111111111111111111110& E896
+ convertToDouble +742522891517E258
+} 0x77f67cf7596968d4
+test expr-28.182 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -357097312678 E169 x -1b89d67c5b6d24_111111111111111111111111111111111111111111110& E599
+ convertToDouble -357097312678E169
+} 0xe56b89d67c5b6d25
+test expr-28.183 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3113521449172 E218 x -19ab8261990292_0000000000000000000000000000000000000000000000000001& E765
+ convertToDouble -3113521449172E218
+} 0xefc9ab8261990292
+test expr-28.184 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3891901811465 E217 x 19ab8261990292_0000000000000000000000000000000000000000000000000001& E762
+ convertToDouble +3891901811465E217
+} 0x6f99ab8261990292
+test expr-28.185 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1556760724586 E218 x -19ab8261990292_0000000000000000000000000000000000000000000000000001& E764
+ convertToDouble -1556760724586E218
+} 0xefb9ab8261990292
+test expr-28.186 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9997878507563 E-195 x 153db2fea1ea31_0000000000000000000000000000000000000000000000001& E-605
+ convertToDouble +9997878507563E-195
+} 0x1a253db2fea1ea31
+test expr-28.187 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7247563029154 E-319 x -10493f056e9ef3_0000000000000000000000000000000000000000000000001& E-1017
+ convertToDouble -7247563029154E-319
+} 0x8060493f056e9ef3
+test expr-28.188 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3623781514577 E-319 x 10493f056e9ef3_0000000000000000000000000000000000000000000000001& E-1018
+ convertToDouble +3623781514577E-319
+} 0x0050493f056e9ef3
+test expr-28.189 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3092446298323 E-200 x -113918353bbc47_0000000000000000000000000000000000000000000000001& E-623
+ convertToDouble -3092446298323E-200
+} 0x99013918353bbc47
+test expr-28.190 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6363857920591 E145 x 128a61cf9483b6_1111111111111111111111111111111111111111111111111110& E524
+ convertToDouble +6363857920591E145
+} 0x60b28a61cf9483b7
+test expr-28.191 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8233559360849 E94 x -11f324d11d4861_1111111111111111111111111111111111111111111111110& E355
+ convertToDouble -8233559360849E94
+} 0xd621f324d11d4862
+test expr-28.192 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2689845954547 E49 x 10bd2bfd34f98a_1111111111111111111111111111111111111111111111110& E204
+ convertToDouble +2689845954547E49
+} 0x4cb0bd2bfd34f98b
+test expr-28.193 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5379691909094 E49 x -10bd2bfd34f98a_1111111111111111111111111111111111111111111111110& E205
+ convertToDouble -5379691909094E49
+} 0xccc0bd2bfd34f98b
+test expr-28.194 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +5560322501926 E-301 x 15acc2053064c1_11111111111111111111111111111111111111111111111110& E-958
+ convertToDouble +5560322501926E-301
+} 0x0415acc2053064c2
+test expr-28.195 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7812878489261 E-179 x -126dae7bbeda74_11111111111111111111111111111111111111111111111111110& E-552
+ convertToDouble -7812878489261E-179
+} 0x9d726dae7bbeda75
+test expr-28.196 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8439398533053 E-256 x 170cc285f2d209_1111111111111111111111111111111111111111111111110& E-808
+ convertToDouble +8439398533053E-256
+} 0x0d770cc285f2d20a
+test expr-28.197 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -2780161250963 E-301 x -15acc2053064c1_11111111111111111111111111111111111111111111111110& E-959
+ convertToDouble -2780161250963E-301
+} 0x8405acc2053064c2
+test expr-28.198 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -87605699161665 E155 x -12920f96e7f9ef_00000000000000000000000000000000000000000000000000001& E561
+ convertToDouble -87605699161665E155
+} 0xe302920f96e7f9ef
+test expr-28.199 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -17521139832333 E156 x -12920f96e7f9ef_00000000000000000000000000000000000000000000000000001& E562
+ convertToDouble -17521139832333E156
+} 0xe312920f96e7f9ef
+test expr-28.200 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -88218101363513 E-170 x -18395688592faf_0000000000000000000000000000000000000000000000000001& E-519
+ convertToDouble -88218101363513E-170
+} 0x9f88395688592faf
+test expr-28.201 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +38639244311627 E-115 x 114ef3e205c817_0000000000000000000000000000000000000000000000000001& E-337
+ convertToDouble +38639244311627E-115
+} 0x2ae14ef3e205c817
+test expr-28.202 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +35593959807306 E261 x 1072f3819c1320_11111111111111111111111111111111111111111111111111110& E912
+ convertToDouble +35593959807306E261
+} 0x78f072f3819c1321
+test expr-28.203 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -53390939710959 E260 x -13bd243521b08d_11111111111111111111111111111111111111111111111111110& E909
+ convertToDouble -53390939710959E260
+} 0xf8c3bd243521b08e
+test expr-28.204 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +71187919614612 E261 x 1072f3819c1320_11111111111111111111111111111111111111111111111111110& E913
+ convertToDouble +71187919614612E261
+} 0x790072f3819c1321
+test expr-28.205 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -88984899518265 E260 x -1072f3819c1320_11111111111111111111111111111111111111111111111111110& E910
+ convertToDouble -88984899518265E260
+} 0xf8d072f3819c1321
+test expr-28.206 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +77003665618895 E-73 x 18bf7e7fa6f029_111111111111111111111111111111111111111111111111111111110& E-197
+ convertToDouble +77003665618895E-73
+} 0x33a8bf7e7fa6f02a
+test expr-28.207 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -15400733123779 E-72 x -18bf7e7fa6f029_111111111111111111111111111111111111111111111111111111110& E-196
+ convertToDouble -15400733123779E-72
+} 0xb3b8bf7e7fa6f02a
+test expr-28.208 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +61602932495116 E-72 x 18bf7e7fa6f029_111111111111111111111111111111111111111111111111111111110& E-194
+ convertToDouble +61602932495116E-72
+} 0x33d8bf7e7fa6f02a
+test expr-28.209 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -30801466247558 E-72 x -18bf7e7fa6f029_111111111111111111111111111111111111111111111111111111110& E-195
+ convertToDouble -30801466247558E-72
+} 0xb3c8bf7e7fa6f02a
+test expr-28.210 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +834735494917063 E-300 x 1fc6c26f899dd1_0000000000000000000000000000000000000000000000000000000001& E-948
+ convertToDouble +834735494917063E-300
+} 0x04bfc6c26f899dd1
+test expr-28.211 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -589795149206434 E-151 x -15f2df5e675a0f_0000000000000000000000000000000000000000000000000000000001& E-453
+ convertToDouble -589795149206434E-151
+} 0xa3a5f2df5e675a0f
+test expr-28.212 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +475603213226859 E-42 x 12d73088f4050a_000000000000000000000000000000000000000000000000000000001& E-91
+ convertToDouble +475603213226859E-42
+} 0x3a42d73088f4050a
+test expr-28.213 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -294897574603217 E-151 x -15f2df5e675a0f_0000000000000000000000000000000000000000000000000000000001& E-454
+ convertToDouble -294897574603217E-151
+} 0xa395f2df5e675a0f
+test expr-28.214 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +850813008001913 E93 x 172f7a1831ad70_11111111111111111111111111111111111111111111111111111110& E358
+ convertToDouble +850813008001913E93
+} 0x56572f7a1831ad71
+test expr-28.215 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -203449172043339 E185 x -1102b47e4af987_11111111111111111111111111111111111111111111111111111110& E662
+ convertToDouble -203449172043339E185
+} 0xe95102b47e4af988
+test expr-28.216 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +406898344086678 E185 x 1102b47e4af987_11111111111111111111111111111111111111111111111111111110& E663
+ convertToDouble +406898344086678E185
+} 0x696102b47e4af988
+test expr-28.217 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -813796688173356 E185 x -1102b47e4af987_11111111111111111111111111111111111111111111111111111110& E664
+ convertToDouble -813796688173356E185
+} 0xe97102b47e4af988
+test expr-28.218 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6045338514609393 E244 x 1f746182e6cd5d_00000000000000000000000000000000000000000000000000000000001& E862
+ convertToDouble +6045338514609393E244
+} 0x75df746182e6cd5d
+test expr-28.219 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5145963778954906 E142 x -1dfc11fbf46087_00000000000000000000000000000000000000000000000000000000001& E523
+ convertToDouble -5145963778954906E142
+} 0xe0adfc11fbf46087
+test expr-28.220 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2572981889477453 E142 x 1dfc11fbf46087_00000000000000000000000000000000000000000000000000000000001& E522
+ convertToDouble +2572981889477453E142
+} 0x609dfc11fbf46087
+test expr-28.221 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -6965949469487146 E74 x -15e2c10ad970b0_0000000000000000000000000000000000000000000000000000000001& E298
+ convertToDouble -6965949469487146E74
+} 0xd295e2c10ad970b0
+test expr-28.222 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6182410494241627 E-119 x 11b96458445d07_0000000000000000000000000000000000000000000000000000000000001& E-343
+ convertToDouble +6182410494241627E-119
+} 0x2a81b96458445d07
+test expr-28.223 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8510309498186985 E-277 x -1acc46749dccfe_000000000000000000000000000000000000000000000000000000000001& E-868
+ convertToDouble -8510309498186985E-277
+} 0x89bacc46749dccfe
+test expr-28.224 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6647704637273331 E-212 x 13e07d2c0cb1e9_0000000000000000000000000000000000000000000000000000000000001& E-652
+ convertToDouble +6647704637273331E-212
+} 0x1733e07d2c0cb1e9
+test expr-28.225 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -2215901545757777 E-212 x -1a80a6e566428c_000000000000000000000000000000000000000000000000000000000001& E-654
+ convertToDouble -2215901545757777E-212
+} 0x971a80a6e566428c
+test expr-28.226 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3771476185376383 E276 x 183010aba78a53_111111111111111111111111111111111111111111111111111111111110& E968
+ convertToDouble +3771476185376383E276
+} 0x7c783010aba78a54
+test expr-28.227 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3729901848043846 E212 x -1f7d6721f7f143_111111111111111111111111111111111111111111111111111111111110& E755
+ convertToDouble -3729901848043846E212
+} 0xef2f7d6721f7f144
+test expr-28.228 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3771476185376383 E277 x 1e3c14d6916ce8_111111111111111111111111111111111111111111111111111111111110& E971
+ convertToDouble +3771476185376383E277
+} 0x7cae3c14d6916ce9
+test expr-28.229 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9977830465649166 E119 x -15f6de9d5d6b5a_111111111111111111111111111111111111111111111111111111111110& E448
+ convertToDouble -9977830465649166E119
+} 0xdbf5f6de9d5d6b5b
+test expr-28.230 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8439928496349319 E-142 x 12483a0f125699_111111111111111111111111111111111111111111111111111111111110& E-419
+ convertToDouble +8439928496349319E-142
+} 0x25c2483a0f12569a
+test expr-28.231 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8204230082070882 E-59 x -1d460f4fca1d36_1111111111111111111111111111111111111111111111111111111110& E-144
+ convertToDouble -8204230082070882E-59
+} 0xb6fd460f4fca1d37
+test expr-28.232 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8853686434843997 E-244 x 157a340eb5d4f0_11111111111111111111111111111111111111111111111111111111110& E-758
+ convertToDouble +8853686434843997E-244
+} 0x10957a340eb5d4f1
+test expr-28.233 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5553274272288559 E-104 x -1c47d20a19d1ed_1111111111111111111111111111111111111111111111111111111110& E-294
+ convertToDouble -5553274272288559E-104
+} 0xad9c47d20a19d1ee
+test expr-28.234 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +36149023611096162 E144 x 1491daad0ba280_0000000000000000000000000000000000000000000000000000000000000001& E533
+ convertToDouble +36149023611096162E144
+} 0x614491daad0ba280
+test expr-28.235 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -36149023611096162 E147 x -14166f8cfd5cb1_0000000000000000000000000000000000000000000000000000000000000001& E543
+ convertToDouble -36149023611096162E147
+} 0xe1e4166f8cfd5cb1
+test expr-28.236 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +18074511805548081 E146 x 1011f2d73116f4_0000000000000000000000000000000000000000000000000000000000000001& E539
+ convertToDouble +18074511805548081E146
+} 0x61a011f2d73116f4
+test expr-28.237 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -18074511805548081 E147 x -14166f8cfd5cb1_0000000000000000000000000000000000000000000000000000000000000001& E542
+ convertToDouble -18074511805548081E147
+} 0xe1d4166f8cfd5cb1
+test expr-28.238 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +97338774138954421 E-290 x 10d9b828199006_0000000000000000000000000000000000000000000000000000000000000001& E-907
+ convertToDouble +97338774138954421E-290
+} 0x0740d9b828199006
+test expr-28.239 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -88133809804950961 E-308 x -119710dc581911_000000000000000000000000000000000000000000000000000000000000001& E-967
+ convertToDouble -88133809804950961E-308
+} 0x83819710dc581911
+test expr-28.240 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +94080055902682397 E-243 x 11d467e94b856e_0000000000000000000000000000000000000000000000000000000000000001& E-751
+ convertToDouble +94080055902682397E-243
+} 0x1101d467e94b856e
+test expr-28.241 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -24691002732654881 E-115 x -159a2783ce70ab_000000000000000000000000000000000000000000000000000000000000001& E-328
+ convertToDouble -24691002732654881E-115
+} 0xab759a2783ce70ab
+test expr-28.242 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +52306490527514614 E49 x 13de005bd620de_111111111111111111111111111111111111111111111111111111111111111110& E218
+ convertToDouble +52306490527514614E49
+} 0x4d93de005bd620df
+test expr-28.243 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -26153245263757307 E49 x -13de005bd620de_111111111111111111111111111111111111111111111111111111111111111110& E217
+ convertToDouble -26153245263757307E49
+} 0xcd83de005bd620df
+test expr-28.244 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +55188692254193604 E165 x 1a999ddec72ac9_11111111111111111111111111111111111111111111111111111111111110& E603
+ convertToDouble +55188692254193604E165
+} 0x65aa999ddec72aca
+test expr-28.245 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -68985865317742005 E164 x -1a999ddec72ac9_11111111111111111111111111111111111111111111111111111111111110& E600
+ convertToDouble -68985865317742005E164
+} 0xe57a999ddec72aca
+test expr-28.246 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +27176258005319167 E-261 x 17c0747bd76fa0_11111111111111111111111111111111111111111111111111111111111111110& E-813
+ convertToDouble +27176258005319167E-261
+} 0x0d27c0747bd76fa1
+test expr-28.247 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -73169230107256116 E-248 x -122cea327fa99c_1111111111111111111111111111111111111111111111111111111111110& E-768
+ convertToDouble -73169230107256116E-248
+} 0x8ff22cea327fa99d
+test expr-28.248 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +91461537634070145 E-249 x 122cea327fa99c_1111111111111111111111111111111111111111111111111111111111110& E-771
+ convertToDouble +91461537634070145E-249
+} 0x0fc22cea327fa99d
+test expr-28.249 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -54352516010638334 E-261 x -17c0747bd76fa0_11111111111111111111111111111111111111111111111111111111111111110& E-812
+ convertToDouble -54352516010638334E-261
+} 0x8d37c0747bd76fa1
+test expr-28.250 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +586144289638535878 E280 x 11eccbd6f62709_0000000000000000000000000000000000000000000000000000000000000000001& E989
+ convertToDouble +586144289638535878E280
+} 0x7dc1eccbd6f62709
+test expr-28.251 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -601117006785295431 E245 x -1e8b3525b3737e_000000000000000000000000000000000000000000000000000000000000000001& E872
+ convertToDouble -601117006785295431E245
+} 0xf67e8b3525b3737e
+test expr-28.252 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +293072144819267939 E280 x 11eccbd6f62709_0000000000000000000000000000000000000000000000000000000000000000001& E988
+ convertToDouble +293072144819267939E280
+} 0x7db1eccbd6f62709
+test expr-28.253 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -953184713238516652 E272 x -138fd93f1f5342_00000000000000000000000000000000000000000000000000000000000000001& E963
+ convertToDouble -953184713238516652E272
+} 0xfc238fd93f1f5342
+test expr-28.254 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +902042358290366539 E-281 x 122dc01ca1cb8c_0000000000000000000000000000000000000000000000000000000000000000001& E-874
+ convertToDouble +902042358290366539E-281
+} 0x09522dc01ca1cb8c
+test expr-28.255 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -557035730189854663 E-294 x -13bfac6bc4767b_00000000000000000000000000000000000000000000000000000000000000000001& E-918
+ convertToDouble -557035730189854663E-294
+} 0x8693bfac6bc4767b
+test expr-28.256 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +902042358290366539 E-280 x 16b93023ca3e6f_0000000000000000000000000000000000000000000000000000000000000000001& E-871
+ convertToDouble +902042358290366539E-280
+} 0x0986b93023ca3e6f
+test expr-28.257 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -354944100507554393 E-238 x -19a91cece6ad07_000000000000000000000000000000000000000000000000000000000000000001& E-733
+ convertToDouble -354944100507554393E-238
+} 0x9229a91cece6ad07
+test expr-28.258 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +272104041512242479 E199 x 1f92bacb3cb40b_11111111111111111111111111111111111111111111111111111111111111111111110& E718
+ convertToDouble +272104041512242479E199
+} 0x6cdf92bacb3cb40c
+test expr-28.259 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -816312124536727437 E199 x -17ae0c186d8708_11111111111111111111111111111111111111111111111111111111111111111111110& E720
+ convertToDouble -816312124536727437E199
+} 0xecf7ae0c186d8709
+test expr-28.260 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +544208083024484958 E199 x 1f92bacb3cb40b_11111111111111111111111111111111111111111111111111111111111111111111110& E719
+ convertToDouble +544208083024484958E199
+} 0x6cef92bacb3cb40c
+test expr-28.261 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -792644927852378159 E78 x -17bff336d8ff05_111111111111111111111111111111111111111111111111111111111111111111110& E318
+ convertToDouble -792644927852378159E78
+} 0xd3d7bff336d8ff06
+test expr-28.262 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -679406450132979175 E-263 x -17c0747bd76fa0_11111111111111111111111111111111111111111111111111111111111111110& E-815
+ convertToDouble -679406450132979175E-263
+} 0x8d07c0747bd76fa1
+test expr-28.263 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +543525160106383340 E-262 x 17c0747bd76fa0_11111111111111111111111111111111111111111111111111111111111111110& E-812
+ convertToDouble +543525160106383340E-262
+} 0x0d37c0747bd76fa1
+test expr-28.264 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7400253695682920196 E215 x 1dca94e3990085_00000000000000000000000000000000000000000000000000000000000000000000001& E776
+ convertToDouble +7400253695682920196E215
+} 0x707dca94e3990085
+test expr-28.265 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1850063423920730049 E215 x -1dca94e3990085_00000000000000000000000000000000000000000000000000000000000000000000001& E774
+ convertToDouble -1850063423920730049E215
+} 0xf05dca94e3990085
+test expr-28.266 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3700126847841460098 E215 x 1dca94e3990085_00000000000000000000000000000000000000000000000000000000000000000000001& E775
+ convertToDouble +3700126847841460098E215
+} 0x706dca94e3990085
+test expr-28.267 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9250317119603650245 E214 x -1dca94e3990085_00000000000000000000000000000000000000000000000000000000000000000000001& E773
+ convertToDouble -9250317119603650245E214
+} 0xf04dca94e3990085
+test expr-28.268 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8396094300569779681 E-252 x 1ab223efcee35a_0000000000000000000000000000000000000000000000000000000000000000000000001& E-775
+ convertToDouble +8396094300569779681E-252
+} 0x0f8ab223efcee35a
+test expr-28.269 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3507665085003296281 E-75 x -160499b881ea50_00000000000000000000000000000000000000000000000000000000000000000000001& E-188
+ convertToDouble -3507665085003296281E-75
+} 0xb4360499b881ea50
+test expr-28.270 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7015330170006592562 E-75 x 160499b881ea50_00000000000000000000000000000000000000000000000000000000000000000000001& E-187
+ convertToDouble +7015330170006592562E-75
+} 0x34460499b881ea50
+test expr-28.271 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7015330170006592562 E-74 x -1b85c026a264e4_00000000000000000000000000000000000000000000000000000000000000000000001& E-184
+ convertToDouble -7015330170006592562E-74
+} 0xb47b85c026a264e4
+test expr-28.272 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7185620434951919351 E205 x 18d92d2bcc7a80_1111111111111111111111111111111111111111111111111111111111111111111111110& E743
+ convertToDouble +7185620434951919351E205
+} 0x6e68d92d2bcc7a81
+test expr-28.273 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1360520207561212395 E198 x -1f92bacb3cb40b_11111111111111111111111111111111111111111111111111111111111111111111110& E717
+ convertToDouble -1360520207561212395E198
+} 0xeccf92bacb3cb40c
+test expr-28.274 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2178999185345151731 E-184 x 19b2c4d2a82335_1111111111111111111111111111111111111111111111111111111111111111111110& E-551
+ convertToDouble +2178999185345151731E-184
+} 0x1d89b2c4d2a82336
+test expr-28.275 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8691089486201567102 E-218 x -1a9c42e5b6d89e_1111111111111111111111111111111111111111111111111111111111111111111110& E-662
+ convertToDouble -8691089486201567102E-218
+} 0x969a9c42e5b6d89f
+test expr-28.276 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +4345544743100783551 E-218 x 1a9c42e5b6d89e_1111111111111111111111111111111111111111111111111111111111111111111110& E-663
+ convertToDouble +4345544743100783551E-218
+} 0x168a9c42e5b6d89f
+test expr-28.277 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -4357998370690303462 E-184 x -19b2c4d2a82335_1111111111111111111111111111111111111111111111111111111111111111111110& E-550
+ convertToDouble -4357998370690303462E-184
+} 0x9d99b2c4d2a82336
+test expr-28.278 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +59825267349106892461 E177 x 199c476d7868df_000000000000000000000000000000000000000000000000000000000000000000000001& E653
+ convertToDouble +59825267349106892461E177
+} 0x68c99c476d7868df
+test expr-28.279 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -62259110684423957791 E47 x -1d8f2cfc20d6e8_0000000000000000000000000000000000000000000000000000000000000000000000001& E221
+ convertToDouble -62259110684423957791E47
+} 0xcdcd8f2cfc20d6e8
+test expr-28.280 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +58380168477038565599 E265 x 1f686e9efbe48d_00000000000000000000000000000000000000000000000000000000000000000000000001& E945
+ convertToDouble +58380168477038565599E265
+} 0x7b0f686e9efbe48d
+test expr-28.281 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -62259110684423957791 E48 x -12797c1d948651_0000000000000000000000000000000000000000000000000000000000000000000000001& E225
+ convertToDouble -62259110684423957791E48
+} 0xce02797c1d948651
+test expr-28.282 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -33584377202279118724 E-252 x -1ab223efcee35a_0000000000000000000000000000000000000000000000000000000000000000000000001& E-773
+ convertToDouble -33584377202279118724E-252
+} 0x8faab223efcee35a
+test expr-28.283 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -57484963479615354808 E205 x -18d92d2bcc7a80_1111111111111111111111111111111111111111111111111111111111111111111111110& E746
+ convertToDouble -57484963479615354808E205
+} 0xee98d92d2bcc7a81
+test expr-28.284 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +71856204349519193510 E204 x 18d92d2bcc7a80_1111111111111111111111111111111111111111111111111111111111111111111111110& E743
+ convertToDouble +71856204349519193510E204
+} 0x6e68d92d2bcc7a81
+test expr-28.285 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -14371240869903838702 E205 x -18d92d2bcc7a80_1111111111111111111111111111111111111111111111111111111111111111111111110& E744
+ convertToDouble -14371240869903838702E205
+} 0xee78d92d2bcc7a81
+test expr-28.286 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +36992084760177624177 E-318 x 18c5f9551c2f99_111111111111111111111111111111111111111111111111111111111111111111111110& E-992
+ convertToDouble +36992084760177624177E-318
+} 0x01f8c5f9551c2f9a
+test expr-28.287 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -73984169520355248354 E-318 x -18c5f9551c2f99_111111111111111111111111111111111111111111111111111111111111111111111110& E-991
+ convertToDouble -73984169520355248354E-318
+} 0x8208c5f9551c2f9a
+test expr-28.288 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +99257763227713890244 E-115 x 15338a554b9ce0_11111111111111111111111111111111111111111111111111111111111111111111110& E-316
+ convertToDouble +99257763227713890244E-115
+} 0x2c35338a554b9ce1
+test expr-28.289 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -87336362425182547697 E-280 x -1130304e7d9c32_11111111111111111111111111111111111111111111111111111111111111111111110& E-864
+ convertToDouble -87336362425182547697E-280
+} 0x89f130304e7d9c33
+test expr-28.290 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7 E289 x 1cbb547777a284_10000000001& E962
+ convertToDouble +7E289
+} 0x7c1cbb547777a285
+test expr-28.291 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3 E153 x -1ca3d8e6d80cba_100000001& E509
+ convertToDouble -3E153
+} 0xdfcca3d8e6d80cbb
+test expr-28.292 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6 E153 x 1ca3d8e6d80cba_100000001& E510
+ convertToDouble +6E153
+} 0x5fdca3d8e6d80cbb
+test expr-28.293 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5 E243 x -176ec98994f488_10000001& E809
+ convertToDouble -5E243
+} 0xf2876ec98994f489
+test expr-28.294 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7 E-161 x 1f7e0db3799aa2_10000000001& E-533
+ convertToDouble +7E-161
+} 0x1eaf7e0db3799aa3
+test expr-28.295 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7 E-172 x -15a4337446ef2a_1000000001& E-569
+ convertToDouble -7E-172
+} 0x9c65a4337446ef2b
+test expr-28.296 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8 E-63 x 1a53fc9631d10c_10000001& E-207
+ convertToDouble +8E-63
+} 0x330a53fc9631d10d
+test expr-28.297 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7 E-113 x -158c47e6eea282_10000001& E-373
+ convertToDouble -7E-113
+} 0xa8a58c47e6eea283
+test expr-28.298 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8 E126 x 17a2ecc414a03f_0111111111110& E421
+ convertToDouble +8E126
+} 0x5a47a2ecc414a03f
+test expr-28.299 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -4 E126 x -17a2ecc414a03f_0111111111110& E420
+ convertToDouble -4E126
+} 0xda37a2ecc414a03f
+test expr-28.300 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +5 E125 x 17a2ecc414a03f_0111111111110& E417
+ convertToDouble +5E125
+} 0x5a07a2ecc414a03f
+test expr-28.301 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1 E126 x -17a2ecc414a03f_0111111111110& E418
+ convertToDouble -1E126
+} 0xda17a2ecc414a03f
+test expr-28.302 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8 E-163 x 1708d0f84d3de7_011111110& E-539
+ convertToDouble +8E-163
+} 0x1e4708d0f84d3de7
+test expr-28.303 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1 E-163 x -1708d0f84d3de7_011111110& E-542
+ convertToDouble -1E-163
+} 0x9e1708d0f84d3de7
+test expr-28.304 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2 E-163 x 1708d0f84d3de7_011111110& E-541
+ convertToDouble +2E-163
+} 0x1e2708d0f84d3de7
+test expr-28.305 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -4 E-163 x -1708d0f84d3de7_011111110& E-540
+ convertToDouble -4E-163
+} 0x9e3708d0f84d3de7
+test expr-28.306 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +51 E195 x 15d51d249dca42_1000000000001& E653
+ convertToDouble +51E195
+} 0x68c5d51d249dca43
+test expr-28.307 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -37 E46 x -1033d7eca0adee_100000000000001& E158
+ convertToDouble -37E46
+} 0xc9d033d7eca0adef
+test expr-28.308 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +74 E46 x 1033d7eca0adee_100000000000001& E159
+ convertToDouble +74E46
+} 0x49e033d7eca0adef
+test expr-28.309 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -56 E289 x -1cbb547777a284_10000000001& E965
+ convertToDouble -56E289
+} 0xfc4cbb547777a285
+test expr-28.310 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +69 E-145 x 158a41b31c9a9a_100000000001& E-476
+ convertToDouble +69E-145
+} 0x22358a41b31c9a9b
+test expr-28.311 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -70 E-162 x -1f7e0db3799aa2_10000000001& E-533
+ convertToDouble -70E-162
+} 0x9eaf7e0db3799aa3
+test expr-28.312 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +56 E-161 x 1f7e0db3799aa2_10000000001& E-530
+ convertToDouble +56E-161
+} 0x1edf7e0db3799aa3
+test expr-28.313 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -21 E-303 x -1ccd59caa6a750_10000000001& E-1003
+ convertToDouble -21E-303
+} 0x814ccd59caa6a751
+test expr-28.314 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +34 E-276 x 12d5a4350d30ff_011111111110& E-912
+ convertToDouble +34E-276
+} 0x06f2d5a4350d30ff
+test expr-28.315 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -68 E-276 x -12d5a4350d30ff_011111111110& E-911
+ convertToDouble -68E-276
+} 0x8702d5a4350d30ff
+test expr-28.316 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +85 E-277 x 12d5a4350d30ff_011111111110& E-914
+ convertToDouble +85E-277
+} 0x06d2d5a4350d30ff
+test expr-28.317 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -87 E-274 x -12d36cf48e7abd_011111111111110& E-904
+ convertToDouble -87E-274
+} 0x8772d36cf48e7abd
+test expr-28.318 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +829 E102 x 17221a79cdd1d8_1000000000000001& E348
+ convertToDouble +829E102
+} 0x55b7221a79cdd1d9
+test expr-28.319 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -623 E100 x -1640a62f3a83de_10000000000000000001& E341
+ convertToDouble -623E100
+} 0xd54640a62f3a83df
+test expr-28.320 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +723 E-162 x 145457ee24abd2_1000000000000001& E-529
+ convertToDouble +723E-162
+} 0x1ee45457ee24abd3
+test expr-28.321 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -457 E-102 x -1ffc81bc29f02a_100000000000000001& E-331
+ convertToDouble -457E-102
+} 0xab4ffc81bc29f02b
+test expr-28.322 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +914 E-102 x 1ffc81bc29f02a_100000000000000001& E-330
+ convertToDouble +914E-102
+} 0x2b5ffc81bc29f02b
+test expr-28.323 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -323 E-135 x -1d589ae4d70218_10000000000001& E-441
+ convertToDouble -323E-135
+} 0xa46d589ae4d70219
+test expr-28.324 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +151 E176 x 1dcf7df8f573b7_0111111111111111110& E591
+ convertToDouble +151E176
+} 0x64edcf7df8f573b7
+test expr-28.325 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -302 E176 x -1dcf7df8f573b7_0111111111111111110& E592
+ convertToDouble -302E176
+} 0xe4fdcf7df8f573b7
+test expr-28.326 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +921 E90 x 1c420a45fd70ff_0111111111111110& E308
+ convertToDouble +921E90
+} 0x533c420a45fd70ff
+test expr-28.327 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -604 E176 x -1dcf7df8f573b7_0111111111111111110& E593
+ convertToDouble -604E176
+} 0xe50dcf7df8f573b7
+test expr-28.328 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +823 E-206 x 14a48933c208ad_0111111111111110& E-675
+ convertToDouble +823E-206
+} 0x15c4a48933c208ad
+test expr-28.329 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -463 E-114 x -11d0c83f6378a5_011111111111110& E-370
+ convertToDouble -463E-114
+} 0xa8d1d0c83f6378a5
+test expr-28.330 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +348 E-274 x 12d36cf48e7abd_011111111111110& E-902
+ convertToDouble +348E-274
+} 0x0792d36cf48e7abd
+test expr-28.331 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9968 E100 x 1640a62f3a83de_10000000000000000001& E345
+ convertToDouble +9968E100
+} 0x558640a62f3a83df
+test expr-28.332 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -6230 E99 x -1640a62f3a83de_10000000000000000001& E341
+ convertToDouble -6230E99
+} 0xd54640a62f3a83df
+test expr-28.333 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +1246 E100 x 1640a62f3a83de_10000000000000000001& E342
+ convertToDouble +1246E100
+} 0x555640a62f3a83df
+test expr-28.334 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6676 E-296 x 15519ac5142aaa_1000000000000000000001& E-971
+ convertToDouble +6676E-296
+} 0x0345519ac5142aab
+test expr-28.335 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8345 E-297 x -15519ac5142aaa_1000000000000000000001& E-974
+ convertToDouble -8345E-297
+} 0x8315519ac5142aab
+test expr-28.336 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +1669 E-296 x 15519ac5142aaa_1000000000000000000001& E-973
+ convertToDouble +1669E-296
+} 0x0325519ac5142aab
+test expr-28.337 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3338 E-296 x -15519ac5142aaa_1000000000000000000001& E-972
+ convertToDouble -3338E-296
+} 0x8335519ac5142aab
+test expr-28.338 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3257 E58 x 1444b34a6fb3eb_01111111111111111110& E204
+ convertToDouble +3257E58
+} 0x4cb444b34a6fb3eb
+test expr-28.339 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -6514 E58 x -1444b34a6fb3eb_01111111111111111110& E205
+ convertToDouble -6514E58
+} 0xccc444b34a6fb3eb
+test expr-28.340 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2416 E176 x 1dcf7df8f573b7_0111111111111111110& E595
+ convertToDouble +2416E176
+} 0x652dcf7df8f573b7
+test expr-28.341 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8085 E-63 x 19fbf3c19b9a79_0111111111111111110& E-197
+ convertToDouble +8085E-63
+} 0x33a9fbf3c19b9a79
+test expr-28.342 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3234 E-62 x -19fbf3c19b9a79_0111111111111111110& E-195
+ convertToDouble -3234E-62
+} 0xb3c9fbf3c19b9a79
+test expr-28.343 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +1617 E-62 x 19fbf3c19b9a79_0111111111111111110& E-196
+ convertToDouble +1617E-62
+} 0x33b9fbf3c19b9a79
+test expr-28.344 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -6468 E-62 x -19fbf3c19b9a79_0111111111111111110& E-194
+ convertToDouble -6468E-62
+} 0xb3d9fbf3c19b9a79
+test expr-28.345 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +53418 E111 x 15b1051df943a8_1000000000000000000001& E384
+ convertToDouble +53418E111
+} 0x57f5b1051df943a9
+test expr-28.346 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -60513 E160 x -15043b64e56c72_1000000000000000000001& E547
+ convertToDouble -60513E160
+} 0xe225043b64e56c73
+test expr-28.347 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +26709 E111 x 15b1051df943a8_1000000000000000000001& E383
+ convertToDouble +26709E111
+} 0x57e5b1051df943a9
+test expr-28.348 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -99447 E166 x -10782189b336ae_1000000000000000000001& E568
+ convertToDouble -99447E166
+} 0xe370782189b336af
+test expr-28.349 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +12549 E48 x 10c52fe6dc6a1b_011111111111111111111110& E173
+ convertToDouble +12549E48
+} 0x4ac0c52fe6dc6a1b
+test expr-28.350 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -25098 E48 x -10c52fe6dc6a1b_011111111111111111111110& E174
+ convertToDouble -25098E48
+} 0xcad0c52fe6dc6a1b
+test expr-28.351 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +50196 E48 x 10c52fe6dc6a1b_011111111111111111111110& E175
+ convertToDouble +50196E48
+} 0x4ae0c52fe6dc6a1b
+test expr-28.352 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -62745 E47 x -10c52fe6dc6a1b_011111111111111111111110& E172
+ convertToDouble -62745E47
+} 0xcab0c52fe6dc6a1b
+test expr-28.353 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +83771 E-73 x 1ce886fb5ffd6d_0111111111111111111110& E-227
+ convertToDouble +83771E-73
+} 0x31cce886fb5ffd6d
+test expr-28.354 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -97451 E-167 x -1c0f220fb1c70d_01111111111111111111110& E-539
+ convertToDouble -97451E-167
+} 0x9e4c0f220fb1c70d
+test expr-28.355 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +86637 E-203 x 10943edb4e81db_0111111111111111111110& E-658
+ convertToDouble +86637E-203
+} 0x16d0943edb4e81db
+test expr-28.356 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -75569 E-254 x -15a462d91c6ab3_0111111111111111111111111110& E-828
+ convertToDouble -75569E-254
+} 0x8c35a462d91c6ab3
+test expr-28.357 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +473806 E83 x 17d15bf3186080_1000000000000000000000001& E294
+ convertToDouble +473806E83
+} 0x5257d15bf3186081
+test expr-28.358 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -947612 E83 x -17d15bf3186080_1000000000000000000000001& E295
+ convertToDouble -947612E83
+} 0xd267d15bf3186081
+test expr-28.359 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +292369 E76 x 18a85eb277e644_100000000000000000000000001& E270
+ convertToDouble +292369E76
+} 0x50d8a85eb277e645
+test expr-28.360 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -584738 E76 x -18a85eb277e644_100000000000000000000000001& E271
+ convertToDouble -584738E76
+} 0xd0e8a85eb277e645
+test expr-28.361 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +933587 E-140 x 1b248728b9c116_100000000000000000000000001& E-446
+ convertToDouble +933587E-140
+} 0x241b248728b9c117
+test expr-28.362 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -720919 E-14 x -1ef696965cbf04_10000000000000000000000001& E-28
+ convertToDouble -720919E-14
+} 0xbe3ef696965cbf05
+test expr-28.363 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +535001 E-149 x 10b38e07c745ae_1000000000000000000000001& E-476
+ convertToDouble +535001E-149
+} 0x2230b38e07c745af
+test expr-28.364 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -890521 E-235 x -114828ee39c852_1000000000000000000000001& E-761
+ convertToDouble -890521E-235
+} 0x90614828ee39c853
+test expr-28.365 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +548057 E81 x 11a1d9135cca53_0111111111111111111111110& E288
+ convertToDouble +548057E81
+} 0x51f1a1d9135cca53
+test expr-28.366 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -706181 E88 x -1b156ac4c2d1e5_0111111111111111111111110& E311
+ convertToDouble -706181E88
+} 0xd36b156ac4c2d1e5
+test expr-28.367 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +820997 E106 x 1b4f8b64fa125d_0111111111111111111111110& E371
+ convertToDouble +820997E106
+} 0x572b4f8b64fa125d
+test expr-28.368 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -320681 E63 x -17ca18a876c5ef_0111111111111111111111110& E227
+ convertToDouble -320681E63
+} 0xce27ca18a876c5ef
+test expr-28.369 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +928609 E-261 x 1be2dd66200bef_011111111111111111111111111110& E-848
+ convertToDouble +928609E-261
+} 0x0afbe2dd66200bef
+test expr-28.370 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -302276 E-254 x -15a462d91c6ab3_0111111111111111111111111110& E-826
+ convertToDouble -302276E-254
+} 0x8c55a462d91c6ab3
+test expr-28.371 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +151138 E-254 x 15a462d91c6ab3_0111111111111111111111111110& E-827
+ convertToDouble +151138E-254
+} 0x0c45a462d91c6ab3
+test expr-28.372 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +4691773 E45 x 19147b9330eaae_1000000000000000000000000001& E171
+ convertToDouble +4691773E45
+} 0x4aa9147b9330eaaf
+test expr-28.373 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9383546 E45 x -19147b9330eaae_1000000000000000000000000001& E172
+ convertToDouble -9383546E45
+} 0xcab9147b9330eaaf
+test expr-28.374 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3059949 E-243 x 13ecf22ea07862_10000000000000000000000000001& E-786
+ convertToDouble +3059949E-243
+} 0x0ed3ecf22ea07863
+test expr-28.375 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -6119898 E-243 x -13ecf22ea07862_10000000000000000000000000001& E-785
+ convertToDouble -6119898E-243
+} 0x8ee3ecf22ea07863
+test expr-28.376 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +5356626 E-213 x 1b84252abdf6ba_100000000000000000000000001& E-686
+ convertToDouble +5356626E-213
+} 0x151b84252abdf6bb
+test expr-28.377 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -4877378 E-199 x -11cd5cd90cb200_100000000000000000000000001& E-639
+ convertToDouble -4877378E-199
+} 0x9801cd5cd90cb201
+test expr-28.378 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7716693 E223 x 1972d9d2cff683_01111111111111111111111111110& E763
+ convertToDouble +7716693E223
+} 0x6fa972d9d2cff683
+test expr-28.379 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5452869 E109 x -16247b136fecc3_01111111111111111111111111110& E384
+ convertToDouble -5452869E109
+} 0xd7f6247b136fecc3
+test expr-28.380 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +4590831 E156 x 14689b4a5fa201_011111111111111111111111111110& E540
+ convertToDouble +4590831E156
+} 0x61b4689b4a5fa201
+test expr-28.381 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9181662 E156 x -14689b4a5fa201_011111111111111111111111111110& E541
+ convertToDouble -9181662E156
+} 0xe1c4689b4a5fa201
+test expr-28.382 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3714436 E-261 x -1be2dd66200bef_011111111111111111111111111110& E-846
+ convertToDouble -3714436E-261
+} 0x8b1be2dd66200bef
+test expr-28.383 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +4643045 E-262 x 1be2dd66200bef_011111111111111111111111111110& E-849
+ convertToDouble +4643045E-262
+} 0x0aebe2dd66200bef
+test expr-28.384 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7428872 E-261 x -1be2dd66200bef_011111111111111111111111111110& E-845
+ convertToDouble -7428872E-261
+} 0x8b2be2dd66200bef
+test expr-28.385 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +52942146 E130 x 16c31d08af89c2_10000000000000000000000000000001& E457
+ convertToDouble +52942146E130
+} 0x5c86c31d08af89c3
+test expr-28.386 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -27966061 E145 x -155bcf72fd10f8_1000000000000000000000000000000001& E506
+ convertToDouble -27966061E145
+} 0xdf955bcf72fd10f9
+test expr-28.387 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +26471073 E130 x 16c31d08af89c2_10000000000000000000000000000001& E456
+ convertToDouble +26471073E130
+} 0x5c76c31d08af89c3
+test expr-28.388 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -55932122 E145 x -155bcf72fd10f8_1000000000000000000000000000000001& E507
+ convertToDouble -55932122E145
+} 0xdfa55bcf72fd10f9
+test expr-28.389 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +95412548 E-99 x 18e0bfb98864c8_100000000000000000000000000000001& E-303
+ convertToDouble +95412548E-99
+} 0x2d08e0bfb98864c9
+test expr-28.390 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -47706274 E-99 x -18e0bfb98864c8_100000000000000000000000000000001& E-304
+ convertToDouble -47706274E-99
+} 0xacf8e0bfb98864c9
+test expr-28.391 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +23853137 E-99 x 18e0bfb98864c8_100000000000000000000000000000001& E-305
+ convertToDouble +23853137E-99
+} 0x2ce8e0bfb98864c9
+test expr-28.392 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -78493654 E-301 x -140d76077b648e_10000000000000000000000000000001& E-974
+ convertToDouble -78493654E-301
+} 0x83140d76077b648f
+test expr-28.393 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +65346417 E29 x 13aa1ad778f23b_0111111111111111111111111111110& E122
+ convertToDouble +65346417E29
+} 0x4793aa1ad778f23b
+test expr-28.394 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -51083099 E167 x -14a75eb58df47b_0111111111111111111111111111110& E580
+ convertToDouble -51083099E167
+} 0xe434a75eb58df47b
+test expr-28.395 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +89396333 E264 x 1526f061ca9053_0111111111111111111111111111111110& E903
+ convertToDouble +89396333E264
+} 0x786526f061ca9053
+test expr-28.396 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -84863171 E114 x -106e98f5ec8f37_0111111111111111111111111111111110& E405
+ convertToDouble -84863171E114
+} 0xd9406e98f5ec8f37
+test expr-28.397 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +59540836 E-251 x 10430c2d075c07_011111111111111111111111111111110& E-808
+ convertToDouble +59540836E-251
+} 0x0d70430c2d075c07
+test expr-28.398 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -74426045 E-252 x -10430c2d075c07_011111111111111111111111111111110& E-811
+ convertToDouble -74426045E-252
+} 0x8d40430c2d075c07
+test expr-28.399 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +14885209 E-251 x 10430c2d075c07_011111111111111111111111111111110& E-810
+ convertToDouble +14885209E-251
+} 0x0d50430c2d075c07
+test expr-28.400 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -29770418 E-251 x -10430c2d075c07_011111111111111111111111111111110& E-809
+ convertToDouble -29770418E-251
+} 0x8d60430c2d075c07
+test expr-28.401 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +982161308 E122 x 11b6231e18c5ca_100000000000000000000000000000000000000001& E435
+ convertToDouble +982161308E122
+} 0x5b21b6231e18c5cb
+test expr-28.402 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -245540327 E122 x -11b6231e18c5ca_100000000000000000000000000000000000000001& E433
+ convertToDouble -245540327E122
+} 0xdb01b6231e18c5cb
+test expr-28.403 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +491080654 E122 x 11b6231e18c5ca_100000000000000000000000000000000000000001& E434
+ convertToDouble +491080654E122
+} 0x5b11b6231e18c5cb
+test expr-28.404 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +525452622 E-310 x 12045136ce0340_1000000000000000000000000000000000001& E-1001
+ convertToDouble +525452622E-310
+} 0x0162045136ce0341
+test expr-28.405 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -771837113 E-134 x -14e61f991c4ed0_100000000000000000000000000000000001& E-416
+ convertToDouble -771837113E-134
+} 0xa5f4e61f991c4ed1
+test expr-28.406 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +820858081 E-150 x 14050669985a86_10000000000000000000000000000000001& E-469
+ convertToDouble +820858081E-150
+} 0x22a4050669985a87
+test expr-28.407 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -262726311 E-310 x -12045136ce0340_1000000000000000000000000000000000001& E-1002
+ convertToDouble -262726311E-310
+} 0x8152045136ce0341
+test expr-28.408 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +923091487 E209 x 10bc60e6896717_011111111111111111111111111111111110& E724
+ convertToDouble +923091487E209
+} 0x6d30bc60e6896717
+test expr-28.409 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -653777767 E273 x -120223f2b3a881_0111111111111111111111111111111111111110& E936
+ convertToDouble -653777767E273
+} 0xfa720223f2b3a881
+test expr-28.410 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +842116236 E-53 x 1809c5732cdc7f_0111111111111111111111111111111110& E-147
+ convertToDouble +842116236E-53
+} 0x36c809c5732cdc7f
+test expr-28.411 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -741111169 E-202 x -15a3e1d1b73099_01111111111111111111111111111111110& E-642
+ convertToDouble -741111169E-202
+} 0x97d5a3e1d1b73099
+test expr-28.412 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +839507247 E-284 x 129a1effc50859_0111111111111111111111111111111110& E-914
+ convertToDouble +839507247E-284
+} 0x06d29a1effc50859
+test expr-28.413 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -951487269 E-264 x -1c92befccb5f59_0111111111111111111111111111111110& E-848
+ convertToDouble -951487269E-264
+} 0x8afc92befccb5f59
+test expr-28.414 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9821613080 E121 x -11b6231e18c5ca_100000000000000000000000000000000000000001& E435
+ convertToDouble -9821613080E121
+} 0xdb21b6231e18c5cb
+test expr-28.415 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6677856011 E-31 x 193a6d11077292_100000000000000000000000000000000000001& E-71
+ convertToDouble +6677856011E-31
+} 0x3b893a6d11077293
+test expr-28.416 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3573796826 E-266 x -112be2041a79fc_100000000000000000000000000000000000001& E-852
+ convertToDouble -3573796826E-266
+} 0x8ab12be2041a79fd
+test expr-28.417 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7147593652 E-266 x 112be2041a79fc_100000000000000000000000000000000000001& E-851
+ convertToDouble +7147593652E-266
+} 0x0ac12be2041a79fd
+test expr-28.418 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9981396317 E-181 x -1edbd94cb50054_100000000000000000000000000000000000001& E-569
+ convertToDouble -9981396317E-181
+} 0x9c6edbd94cb50055
+test expr-28.419 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3268888835 E272 x 120223f2b3a881_0111111111111111111111111111111111111110& E935
+ convertToDouble +3268888835E272
+} 0x7a620223f2b3a881
+test expr-28.420 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -2615111068 E273 x -120223f2b3a881_0111111111111111111111111111111111111110& E938
+ convertToDouble -2615111068E273
+} 0xfa920223f2b3a881
+test expr-28.421 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +1307555534 E273 x 120223f2b3a881_0111111111111111111111111111111111111110& E937
+ convertToDouble +1307555534E273
+} 0x7a820223f2b3a881
+test expr-28.422 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2990671154 E-190 x 13db11ac608107_01111111111111111111111111111111111111110& E-600
+ convertToDouble +2990671154E-190
+} 0x1a73db11ac608107
+test expr-28.423 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1495335577 E-190 x -13db11ac608107_01111111111111111111111111111111111111110& E-601
+ convertToDouble -1495335577E-190
+} 0x9a63db11ac608107
+test expr-28.424 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +5981342308 E-190 x 13db11ac608107_01111111111111111111111111111111111111110& E-599
+ convertToDouble +5981342308E-190
+} 0x1a83db11ac608107
+test expr-28.425 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7476677885 E-191 x -13db11ac608107_01111111111111111111111111111111111111110& E-602
+ convertToDouble -7476677885E-191
+} 0x9a53db11ac608107
+test expr-28.426 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +82259684194 E-202 x 12c3e72d179606_1000000000000000000000000000000000000000001& E-635
+ convertToDouble +82259684194E-202
+} 0x1842c3e72d179607
+test expr-28.427 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -93227267727 E-49 x -1960fe08d5847e_100000000000000000000000000000000000000001& E-127
+ convertToDouble -93227267727E-49
+} 0xb80960fe08d5847f
+test expr-28.428 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +41129842097 E-202 x 12c3e72d179606_1000000000000000000000000000000000000000001& E-636
+ convertToDouble +41129842097E-202
+} 0x1832c3e72d179607
+test expr-28.429 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -47584241418 E-314 x -14e25dd3747e96_10000000000000000000000000000000000000001& E-1008
+ convertToDouble -47584241418E-314
+} 0x80f4e25dd3747e97
+test expr-28.430 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -79360293406 E92 x -1c58a00bb31863_01111111111111111111111111111111111111110& E341
+ convertToDouble -79360293406E92
+} 0xd54c58a00bb31863
+test expr-28.431 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +57332259349 E225 x 120811f528378b_01111111111111111111111111111111111111110& E783
+ convertToDouble +57332259349E225
+} 0x70e20811f528378b
+test expr-28.432 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -57202326162 E111 x -1626f1c480545b_01111111111111111111111111111111111111110& E404
+ convertToDouble -57202326162E111
+} 0xd93626f1c480545b
+test expr-28.433 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +86860597053 E-206 x 103b77d2b969d9_0111111111111111111111111111111111111111110& E-648
+ convertToDouble +86860597053E-206
+} 0x17703b77d2b969d9
+test expr-28.434 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -53827010643 E-200 x -132fa69a69bd6d_0111111111111111111111111111111111111111110& E-629
+ convertToDouble -53827010643E-200
+} 0x98a32fa69a69bd6d
+test expr-28.435 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +53587107423 E-61 x 100a19a3ffd981_011111111111111111111111111111111111111111110& E-167
+ convertToDouble +53587107423E-61
+} 0x35800a19a3ffd981
+test expr-28.436 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +635007636765 E200 x 1824e73a4f030e_100000000000000000000000000000000000000000001& E703
+ convertToDouble +635007636765E200
+} 0x6be824e73a4f030f
+test expr-28.437 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +508006109412 E201 x 1824e73a4f030e_100000000000000000000000000000000000000000001& E706
+ convertToDouble +508006109412E201
+} 0x6c1824e73a4f030f
+test expr-28.438 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -254003054706 E201 x -1824e73a4f030e_100000000000000000000000000000000000000000001& E705
+ convertToDouble -254003054706E201
+} 0xec0824e73a4f030f
+test expr-28.439 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +561029718715 E-72 x 1cd96a6972a14a_100000000000000000000000000000000000000000001& E-201
+ convertToDouble +561029718715E-72
+} 0x336cd96a6972a14b
+test expr-28.440 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -897647549944 E-71 x -1cd96a6972a14a_100000000000000000000000000000000000000000001& E-197
+ convertToDouble -897647549944E-71
+} 0xb3acd96a6972a14b
+test expr-28.441 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +112205943743 E-71 x 1cd96a6972a14a_100000000000000000000000000000000000000000001& E-200
+ convertToDouble +112205943743E-71
+} 0x337cd96a6972a14b
+test expr-28.442 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -873947086081 E-236 x -19e117541d04e6_1000000000000000000000000000000000000000000001& E-745
+ convertToDouble -873947086081E-236
+} 0x9169e117541d04e7
+test expr-28.443 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +809184709177 E116 x 1de27e59fb0679_011111111111111111111111111111111111111111110& E424
+ convertToDouble +809184709177E116
+} 0x5a7de27e59fb0679
+test expr-28.444 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -573112917422 E81 x -11958b36c5102b_01111111111111111111111111111111111111111111110& E308
+ convertToDouble -573112917422E81
+} 0xd331958b36c5102b
+test expr-28.445 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +286556458711 E81 x 11958b36c5102b_01111111111111111111111111111111111111111111110& E307
+ convertToDouble +286556458711E81
+} 0x5321958b36c5102b
+test expr-28.446 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +952805821491 E-259 x 1551767ef8a9a3_011111111111111111111111111111111111111111110& E-821
+ convertToDouble +952805821491E-259
+} 0x0ca551767ef8a9a3
+test expr-28.447 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -132189992873 E-44 x -1b746cf242410b_011111111111111111111111111111111111111111110& E-110
+ convertToDouble -132189992873E-44
+} 0xb91b746cf242410b
+test expr-28.448 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -173696038493 E-144 x -1f8fefbb3249d3_011111111111111111111111111111111111111111110& E-442
+ convertToDouble -173696038493E-144
+} 0xa45f8fefbb3249d3
+test expr-28.449 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +1831132757599 E-107 x 138e6edd48f2a2_1000000000000000000000000000000000000000000000001& E-315
+ convertToDouble +1831132757599E-107
+} 0x2c438e6edd48f2a3
+test expr-28.450 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9155663787995 E-108 x -138e6edd48f2a2_1000000000000000000000000000000000000000000000001& E-316
+ convertToDouble -9155663787995E-108
+} 0xac338e6edd48f2a3
+test expr-28.451 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7324531030396 E-107 x 138e6edd48f2a2_1000000000000000000000000000000000000000000000001& E-313
+ convertToDouble +7324531030396E-107
+} 0x2c638e6edd48f2a3
+test expr-28.452 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9277338894969 E-200 x -19d5a44fd99a6a_1000000000000000000000000000000000000000000000001& E-622
+ convertToDouble -9277338894969E-200
+} 0x9919d5a44fd99a6b
+test expr-28.453 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8188292423973 E287 x 1390273bf8f983_0111111111111111111111111111111111111111111111110& E996
+ convertToDouble +8188292423973E287
+} 0x7e3390273bf8f983
+test expr-28.454 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5672557437938 E59 x -148c2bd60a1523_011111111111111111111111111111111111111111111110& E238
+ convertToDouble -5672557437938E59
+} 0xced48c2bd60a1523
+test expr-28.455 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2836278718969 E59 x 148c2bd60a1523_011111111111111111111111111111111111111111111110& E237
+ convertToDouble +2836278718969E59
+} 0x4ec48c2bd60a1523
+test expr-28.456 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -9995153153494 E54 x -17ba37c4fbe993_01111111111111111111111111111111111111111111110& E222
+ convertToDouble -9995153153494E54
+} 0xcdd7ba37c4fbe993
+test expr-28.457 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9224786422069 E-291 x 14ee5d56b32957_011111111111111111111111111111111111111111111111110& E-924
+ convertToDouble +9224786422069E-291
+} 0x0634ee5d56b32957
+test expr-28.458 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3142213164987 E-294 x -1d3409dfbca26f_011111111111111111111111111111111111111111111111110& E-936
+ convertToDouble -3142213164987E-294
+} 0x857d3409dfbca26f
+test expr-28.459 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +6284426329974 E-294 x 1d3409dfbca26f_011111111111111111111111111111111111111111111111110& E-935
+ convertToDouble +6284426329974E-294
+} 0x058d3409dfbca26f
+test expr-28.460 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8340483752889 E-301 x -10419183e44b91_01111111111111111111111111111111111111111111111110& E-957
+ convertToDouble -8340483752889E-301
+} 0x8420419183e44b91
+test expr-28.461 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +67039371486466 E89 x 17f203339c9628_10000000000000000000000000000000000000000000000000001& E341
+ convertToDouble +67039371486466E89
+} 0x5547f203339c9629
+test expr-28.462 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -62150786615239 E197 x -12e79a035b9714_1000000000000000000000000000000000000000000000000001& E700
+ convertToDouble -62150786615239E197
+} 0xebb2e79a035b9715
+test expr-28.463 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +33519685743233 E89 x 17f203339c9628_10000000000000000000000000000000000000000000000000001& E340
+ convertToDouble +33519685743233E89
+} 0x5537f203339c9629
+test expr-28.464 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -52563419496999 E156 x -1bdb17625bf6e6_1000000000000000000000000000000000000000000000000001& E563
+ convertToDouble -52563419496999E156
+} 0xe32bdb17625bf6e7
+test expr-28.465 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +32599460466991 E-65 x 1f395d4c779d8e_1000000000000000000000000000000000000000000000000001& E-172
+ convertToDouble +32599460466991E-65
+} 0x353f395d4c779d8f
+test expr-28.466 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -41010988798007 E-133 x -152e1c9e04ee06_100000000000000000000000000000000000000000000000001& E-397
+ convertToDouble -41010988798007E-133
+} 0xa7252e1c9e04ee07
+test expr-28.467 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +65198920933982 E-65 x 1f395d4c779d8e_1000000000000000000000000000000000000000000000000001& E-171
+ convertToDouble +65198920933982E-65
+} 0x354f395d4c779d8f
+test expr-28.468 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -82021977596014 E-133 x -152e1c9e04ee06_100000000000000000000000000000000000000000000000001& E-396
+ convertToDouble -82021977596014E-133
+} 0xa7352e1c9e04ee07
+test expr-28.469 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +80527976643809 E61 x 1c7c5aea080a49_0111111111111111111111111111111111111111111111111110& E248
+ convertToDouble +80527976643809E61
+} 0x4f7c7c5aea080a49
+test expr-28.470 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -74712611505209 E158 x -1eeebe9ea010f3_011111111111111111111111111111111111111111111111110& E570
+ convertToDouble -74712611505209E158
+} 0xe39eeebe9ea010f3
+test expr-28.471 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +53390939710959 E261 x 18ac6d426a1cb1_0111111111111111111111111111111111111111111111111110& E912
+ convertToDouble +53390939710959E261
+} 0x78f8ac6d426a1cb1
+test expr-28.472 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -69277302659155 E225 x -1547166a3a2b0f_011111111111111111111111111111111111111111111111110& E793
+ convertToDouble -69277302659155E225
+} 0xf18547166a3a2b0f
+test expr-28.473 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +46202199371337 E-72 x 128f9edfbd341f_0111111111111111111111111111111111111111111111111111111110& E-194
+ convertToDouble +46202199371337E-72
+} 0x33d28f9edfbd341f
+test expr-28.474 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -23438635467783 E-179 x -1ba485b99e47af_0111111111111111111111111111111111111111111111111110& E-551
+ convertToDouble -23438635467783E-179
+} 0x9d8ba485b99e47af
+test expr-28.475 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +41921560615349 E-67 x 19b2a5c4041e4b_0111111111111111111111111111111111111111111111111110& E-178
+ convertToDouble +41921560615349E-67
+} 0x34d9b2a5c4041e4b
+test expr-28.476 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -92404398742674 E-72 x -128f9edfbd341f_0111111111111111111111111111111111111111111111111111111110& E-193
+ convertToDouble -92404398742674E-72
+} 0xb3e28f9edfbd341f
+test expr-28.477 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +738545606647197 E124 x 13d8886a766a20_100000000000000000000000000000000000000000000000000001& E461
+ convertToDouble +738545606647197E124
+} 0x5cc3d8886a766a21
+test expr-28.478 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -972708181182949 E117 x -15ed1f039cebfe_1000000000000000000000000000000000000000000000000000001& E438
+ convertToDouble -972708181182949E117
+} 0xdb55ed1f039cebff
+test expr-28.479 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -837992143580825 E87 x -17f203339c9628_10000000000000000000000000000000000000000000000000001& E338
+ convertToDouble -837992143580825E87
+} 0xd517f203339c9629
+test expr-28.480 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +609610927149051 E-255 x 104273b18918b0_100000000000000000000000000000000000000000000000000000001& E-798
+ convertToDouble +609610927149051E-255
+} 0x0e104273b18918b1
+test expr-28.481 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -475603213226859 E-41 x -178cfcab31064c_10000000000000000000000000000000000000000000000000000001& E-88
+ convertToDouble -475603213226859E-41
+} 0xba778cfcab31064d
+test expr-28.482 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +563002800671023 E-177 x 1035e7b5183922_10000000000000000000000000000000000000000000000000000001& E-539
+ convertToDouble +563002800671023E-177
+} 0x1e4035e7b5183923
+test expr-28.483 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -951206426453718 E-41 x -178cfcab31064c_10000000000000000000000000000000000000000000000000000001& E-87
+ convertToDouble -951206426453718E-41
+} 0xba878cfcab31064d
+test expr-28.484 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +805416432656519 E202 x 175d226331d039_01111111111111111111111111111111111111111111111111111110& E720
+ convertToDouble +805416432656519E202
+} 0x6cf75d226331d039
+test expr-28.485 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -530658674694337 E159 x -112a13daa46fe3_0111111111111111111111111111111111111111111111111111110& E577
+ convertToDouble -530658674694337E159
+} 0xe4012a13daa46fe3
+test expr-28.486 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +946574173863918 E208 x 1a2fbffdb7580b_011111111111111111111111111111111111111111111111111110& E740
+ convertToDouble +946574173863918E208
+} 0x6e3a2fbffdb7580b
+test expr-28.487 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -318329953318553 E113 x -178358811cbc95_011111111111111111111111111111111111111111111111111110& E423
+ convertToDouble -318329953318553E113
+} 0xda678358811cbc95
+test expr-28.488 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -462021993713370 E-73 x -128f9edfbd341f_0111111111111111111111111111111111111111111111111111111110& E-194
+ convertToDouble -462021993713370E-73
+} 0xb3d28f9edfbd341f
+test expr-28.489 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +369617594970696 E-72 x 128f9edfbd341f_0111111111111111111111111111111111111111111111111111111110& E-191
+ convertToDouble +369617594970696E-72
+} 0x34028f9edfbd341f
+test expr-28.490 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3666156212014994 E233 x 1a37935f3b71c8_100000000000000000000000000000000000000000000000000000001& E825
+ convertToDouble +3666156212014994E233
+} 0x738a37935f3b71c9
+test expr-28.491 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1833078106007497 E233 x -1a37935f3b71c8_100000000000000000000000000000000000000000000000000000001& E824
+ convertToDouble -1833078106007497E233
+} 0xf37a37935f3b71c9
+test expr-28.492 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +8301790508624232 E174 x 1dcfee6690ffc6_100000000000000000000000000000000000000000000000000000001& E630
+ convertToDouble +8301790508624232E174
+} 0x675dcfee6690ffc7
+test expr-28.493 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1037723813578029 E174 x -1dcfee6690ffc6_100000000000000000000000000000000000000000000000000000001& E627
+ convertToDouble -1037723813578029E174
+} 0xe72dcfee6690ffc7
+test expr-28.494 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7297662880581139 E-286 x 18ac8c79e1ff18_1000000000000000000000000000000000000000000000000000000000001& E-898
+ convertToDouble +7297662880581139E-286
+} 0x07d8ac8c79e1ff19
+test expr-28.495 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -5106185698912191 E-276 x -141934d77659be_1000000000000000000000000000000000000000000000000000000000001& E-865
+ convertToDouble -5106185698912191E-276
+} 0x89e41934d77659bf
+test expr-28.496 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7487252720986826 E-165 x 18823a57adbef8_100000000000000000000000000000000000000000000000000000000000001& E-496
+ convertToDouble +7487252720986826E-165
+} 0x20f8823a57adbef9
+test expr-28.497 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3743626360493413 E-165 x -18823a57adbef8_100000000000000000000000000000000000000000000000000000000000001& E-497
+ convertToDouble -3743626360493413E-165
+} 0xa0e8823a57adbef9
+test expr-28.498 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3773057430100257 E230 x 1ba10d818fdafd_0111111111111111111111111111111111111111111111111111111110& E815
+ convertToDouble +3773057430100257E230
+} 0x72eba10d818fdafd
+test expr-28.499 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7546114860200514 E230 x -1ba10d818fdafd_0111111111111111111111111111111111111111111111111111111110& E816
+ convertToDouble -7546114860200514E230
+} 0xf2fba10d818fdafd
+test expr-28.500 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +4321222892463822 E58 x 18750ea732fdad_011111111111111111111111111111111111111111111111111111110& E244
+ convertToDouble +4321222892463822E58
+} 0x4f38750ea732fdad
+test expr-28.501 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7793560217139653 E51 x -1280461b856ec5_0111111111111111111111111111111111111111111111111111111110& E222
+ convertToDouble -7793560217139653E51
+} 0xcdd280461b856ec5
+test expr-28.502 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +26525993941010681 E112 x 187dcbf6ad5cf8_10000000000000000000000000000000000000000000000000000000000001& E426
+ convertToDouble +26525993941010681E112
+} 0x5a987dcbf6ad5cf9
+test expr-28.503 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -53051987882021362 E112 x -187dcbf6ad5cf8_10000000000000000000000000000000000000000000000000000000000001& E427
+ convertToDouble -53051987882021362E112
+} 0xdaa87dcbf6ad5cf9
+test expr-28.504 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +72844871414247907 E77 x 1bf00baf60b70c_100000000000000000000000000000000000000000000000000000000001& E311
+ convertToDouble +72844871414247907E77
+} 0x536bf00baf60b70d
+test expr-28.505 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -88839359596763261 E105 x -1133b1a33a1108_100000000000000000000000000000000000000000000000000000000001& E405
+ convertToDouble -88839359596763261E105
+} 0xd94133b1a33a1109
+test expr-28.506 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +18718131802467065 E-166 x 18823a57adbef8_100000000000000000000000000000000000000000000000000000000000001& E-498
+ convertToDouble +18718131802467065E-166
+} 0x20d8823a57adbef9
+test expr-28.507 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -14974505441973652 E-165 x -18823a57adbef8_100000000000000000000000000000000000000000000000000000000000001& E-495
+ convertToDouble -14974505441973652E-165
+} 0xa108823a57adbef9
+test expr-28.508 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +73429396004640239 E106 x 11c5cb19ef3451_01111111111111111111111111111111111111111111111111111111111110& E408
+ convertToDouble +73429396004640239E106
+} 0x5971c5cb19ef3451
+test expr-28.509 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -58483921078398283 E57 x -108ce499519ce3_0111111111111111111111111111111111111111111111111111111111111110& E245
+ convertToDouble -58483921078398283E57
+} 0xcf408ce499519ce3
+test expr-28.510 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +41391519190645203 E165 x 13f33667156017_011111111111111111111111111111111111111111111111111111111111110& E603
+ convertToDouble +41391519190645203E165
+} 0x65a3f33667156017
+test expr-28.511 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -82783038381290406 E165 x -13f33667156017_011111111111111111111111111111111111111111111111111111111111110& E604
+ convertToDouble -82783038381290406E165
+} 0xe5b3f33667156017
+test expr-28.512 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +58767043776702677 E-163 x 12c92fee3a3867_0111111111111111111111111111111111111111111111111111111111110& E-486
+ convertToDouble +58767043776702677E-163
+} 0x2192c92fee3a3867
+test expr-28.513 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -90506231831231999 E-129 x -1bdc4114397ff3_01111111111111111111111111111111111111111111111111111111111110& E-373
+ convertToDouble -90506231831231999E-129
+} 0xa8abdc4114397ff3
+test expr-28.514 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +64409240769861689 E-159 x 192238f7987779_011111111111111111111111111111111111111111111111111111111111110& E-473
+ convertToDouble +64409240769861689E-159
+} 0x22692238f7987779
+test expr-28.515 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -77305427432277771 E-190 x -1e978b7780b613_0111111111111111111111111111111111111111111111111111111111110& E-576
+ convertToDouble -77305427432277771E-190
+} 0x9bfe978b7780b613
+test expr-28.516 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +476592356619258326 E273 x 1873cf8ee72812_10000000000000000000000000000000000000000000000000000000000000001& E965
+ convertToDouble +476592356619258326E273
+} 0x7c4873cf8ee72813
+test expr-28.517 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -953184713238516652 E273 x -1873cf8ee72812_10000000000000000000000000000000000000000000000000000000000000001& E966
+ convertToDouble -953184713238516652E273
+} 0xfc5873cf8ee72813
+test expr-28.518 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +899810892172646163 E283 x 1adf51fa055e02_100000000000000000000000000000000000000000000000000000000000000000001& E999
+ convertToDouble +899810892172646163E283
+} 0x7e6adf51fa055e03
+test expr-28.519 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -929167076892018333 E187 x -1da2c42fce2bc4_10000000000000000000000000000000000000000000000000000000000000000001& E680
+ convertToDouble -929167076892018333E187
+} 0xea7da2c42fce2bc5
+test expr-28.520 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +647761278967534239 E-312 x 1a7a2476ec0b3e_10000000000000000000000000000000000000000000000000000000000000001& E-978
+ convertToDouble +647761278967534239E-312
+} 0x02da7a2476ec0b3f
+test expr-28.521 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -644290479820542942 E-180 x -128d1407dfa832_10000000000000000000000000000000000000000000000000000000000000001& E-539
+ convertToDouble -644290479820542942E-180
+} 0x9e428d1407dfa833
+test expr-28.522 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +926145344610700019 E-225 x 1307a67f1f69fe_10000000000000000000000000000000000000000000000000000000000000000001& E-688
+ convertToDouble +926145344610700019E-225
+} 0x14f307a67f1f69ff
+test expr-28.523 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -958507931896511964 E-246 x -17406753df2f0c_10000000000000000000000000000000000000000000000000000000000000001& E-758
+ convertToDouble -958507931896511964E-246
+} 0x9097406753df2f0d
+test expr-28.524 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +272104041512242479 E200 x 13bbb4bf05f087_011111111111111111111111111111111111111111111111111111111111111111111110& E722
+ convertToDouble +272104041512242479E200
+} 0x6d13bbb4bf05f087
+test expr-28.525 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -792644927852378159 E79 x -1daff0048f3ec7_011111111111111111111111111111111111111111111111111111111111111111110& E321
+ convertToDouble -792644927852378159E79
+} 0xd40daff0048f3ec7
+test expr-28.526 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +544208083024484958 E200 x 13bbb4bf05f087_011111111111111111111111111111111111111111111111111111111111111111111110& E723
+ convertToDouble +544208083024484958E200
+} 0x6d23bbb4bf05f087
+test expr-28.527 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -929963218616126365 E290 x -108dcc0c505461_01111111111111111111111111111111111111111111111111111111111111110& E1023
+ convertToDouble -929963218616126365E290
+} 0xffe08dcc0c505461
+test expr-28.528 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +305574339166810102 E-219 x 17f399fe02c4b9_011111111111111111111111111111111111111111111111111111111111111110& E-670
+ convertToDouble +305574339166810102E-219
+} 0x1617f399fe02c4b9
+test expr-28.529 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -152787169583405051 E-219 x -17f399fe02c4b9_011111111111111111111111111111111111111111111111111111111111111110& E-671
+ convertToDouble -152787169583405051E-219
+} 0x9607f399fe02c4b9
+test expr-28.530 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +611148678333620204 E-219 x 17f399fe02c4b9_011111111111111111111111111111111111111111111111111111111111111110& E-669
+ convertToDouble +611148678333620204E-219
+} 0x1627f399fe02c4b9
+test expr-28.531 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -763935847917025255 E-220 x -17f399fe02c4b9_011111111111111111111111111111111111111111111111111111111111111110& E-672
+ convertToDouble -763935847917025255E-220
+} 0x95f7f399fe02c4b9
+test expr-28.532 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +7439550220920798612 E158 x 177fe14f40159a_10000000000000000000000000000000000000000000000000000000000000000000001& E587
+ convertToDouble +7439550220920798612E158
+} 0x64a77fe14f40159b
+test expr-28.533 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -3719775110460399306 E158 x -177fe14f40159a_10000000000000000000000000000000000000000000000000000000000000000000001& E586
+ convertToDouble -3719775110460399306E158
+} 0xe4977fe14f40159b
+test expr-28.534 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +9299437776150998265 E157 x 177fe14f40159a_10000000000000000000000000000000000000000000000000000000000000000000001& E584
+ convertToDouble +9299437776150998265E157
+} 0x64777fe14f40159b
+test expr-28.535 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7120190517612959703 E120 x -13220dcd5899fc_1000000000000000000000000000000000000000000000000000000000000000000000001& E461
+ convertToDouble -7120190517612959703E120
+} 0xdcc3220dcd5899fd
+test expr-28.536 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +3507665085003296281 E-73 x 11339818257f0e_100000000000000000000000000000000000000000000000000000000000000000000001& E-181
+ convertToDouble +3507665085003296281E-73
+} 0x34a1339818257f0f
+test expr-28.537 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -7015330170006592562 E-73 x -11339818257f0e_100000000000000000000000000000000000000000000000000000000000000000000001& E-180
+ convertToDouble -7015330170006592562E-73
+} 0xb4b1339818257f0f
+test expr-28.538 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -6684428762278255956 E-294 x -1d9f82a1a6b1b8_10000000000000000000000000000000000000000000000000000000000000000001& E-915
+ convertToDouble -6684428762278255956E-294
+} 0x86cd9f82a1a6b1b9
+test expr-28.539 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -1088416166048969916 E200 x -13bbb4bf05f087_011111111111111111111111111111111111111111111111111111111111111111111110& E724
+ convertToDouble -1088416166048969916E200
+} 0xed33bbb4bf05f087
+test expr-28.540 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8707329328391759328 E200 x -13bbb4bf05f087_011111111111111111111111111111111111111111111111111111111111111111111110& E727
+ convertToDouble -8707329328391759328E200
+} 0xed63bbb4bf05f087
+test expr-28.541 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +4439021781608558002 E-65 x 1038168b71e2c9_01111111111111111111111111111111111111111111111111111111111111111110& E-154
+ convertToDouble +4439021781608558002E-65
+} 0x365038168b71e2c9
+test expr-28.542 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -8878043563217116004 E-65 x -1038168b71e2c9_01111111111111111111111111111111111111111111111111111111111111111110& E-153
+ convertToDouble -8878043563217116004E-65
+} 0xb66038168b71e2c9
+test expr-28.543 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +2219510890804279001 E-65 x 1038168b71e2c9_01111111111111111111111111111111111111111111111111111111111111111110& E-155
+ convertToDouble +2219510890804279001E-65
+} 0x364038168b71e2c9
+test expr-28.544 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +33051223951904955802 E55 x 1762068a24fd54_1000000000000000000000000000000000000000000000000000000000000000000000001& E247
+ convertToDouble +33051223951904955802E55
+} 0x4f6762068a24fd55
+test expr-28.545 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -56961524140903677624 E120 x -13220dcd5899fc_1000000000000000000000000000000000000000000000000000000000000000000000001& E464
+ convertToDouble -56961524140903677624E120
+} 0xdcf3220dcd5899fd
+test expr-28.546 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +71201905176129597030 E119 x 13220dcd5899fc_1000000000000000000000000000000000000000000000000000000000000000000000001& E461
+ convertToDouble +71201905176129597030E119
+} 0x5cc3220dcd5899fd
+test expr-28.547 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +14030660340013185124 E-73 x 11339818257f0e_100000000000000000000000000000000000000000000000000000000000000000000001& E-179
+ convertToDouble +14030660340013185124E-73
+} 0x34c1339818257f0f
+test expr-28.548 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -17538325425016481405 E-74 x -11339818257f0e_100000000000000000000000000000000000000000000000000000000000000000000001& E-182
+ convertToDouble -17538325425016481405E-74
+} 0xb491339818257f0f
+test expr-28.549 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +67536228609141569109 E-133 x 10a1b35cf2a635_01111111111111111111111111111111111111111111111111111111111111111111110& E-376
+ convertToDouble +67536228609141569109E-133
+} 0x2870a1b35cf2a635
+test expr-28.550 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -35620497849450218807 E-306 x -15b22082529425_0111111111111111111111111111111111111111111111111111111111111111111111110& E-952
+ convertToDouble -35620497849450218807E-306
+} 0x8475b22082529425
+test expr-28.551 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN +66550376797582521751 E-126 x 13897c0ede6c69_01111111111111111111111111111111111111111111111111111111111111111111110& E-353
+ convertToDouble +66550376797582521751E-126
+} 0x29e3897c0ede6c69
+test expr-28.552 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b d UN -71240995698900437614 E-306 x -15b22082529425_0111111111111111111111111111111111111111111111111111111111111111111111110& E-951
+ convertToDouble -71240995698900437614E-306
+} 0x8485b22082529425
+test expr-28.553 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +3 E24 x 13da329b633647_0001& E81
+ convertToDouble +3E24
+} 0x4503da329b633647
+test expr-28.554 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -6 E24 x -13da329b633647_0001& E82
+ convertToDouble -6E24
+} 0xc513da329b633647
+test expr-28.555 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6 E26 x 1f04ef12cb04cf_0001& E88
+ convertToDouble +6E26
+} 0x457f04ef12cb04cf
+test expr-28.556 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -7 E25 x -1cf389cd46047d_0000001& E85
+ convertToDouble -7E25
+} 0xc54cf389cd46047d
+test expr-28.557 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +1 E-14 x 16849b86a12b9b_00000001& E-47
+ convertToDouble +1E-14
+} 0x3d06849b86a12b9b
+test expr-28.558 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2 E-14 x -16849b86a12b9b_00000001& E-46
+ convertToDouble -2E-14
+} 0xbd16849b86a12b9b
+test expr-28.559 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4 E-14 x 16849b86a12b9b_00000001& E-45
+ convertToDouble +4E-14
+} 0x3d26849b86a12b9b
+test expr-28.560 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8 E-14 x -16849b86a12b9b_00000001& E-44
+ convertToDouble -8E-14
+} 0xbd36849b86a12b9b
+test expr-28.561 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +5 E26 x 19d971e4fe8401_1110& E88
+ convertToDouble +5E26
+} 0x4579d971e4fe8402
+test expr-28.562 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8 E27 x -19d971e4fe8401_1110& E92
+ convertToDouble -8E27
+} 0xc5b9d971e4fe8402
+test expr-28.563 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +1 E27 x 19d971e4fe8401_1110& E89
+ convertToDouble +1E27
+} 0x4589d971e4fe8402
+test expr-28.564 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4 E27 x -19d971e4fe8401_1110& E91
+ convertToDouble -4E27
+} 0xc5a9d971e4fe8402
+test expr-28.565 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9 E-13 x 1faa7ab552a551_111110& E-41
+ convertToDouble +9E-13
+} 0x3d6faa7ab552a552
+test expr-28.566 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -7 E-20 x -14a90ceafff9de_11110& E-64
+ convertToDouble -7E-20
+} 0xbbf4a90ceafff9df
+test expr-28.567 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +56 E25 x 1cf389cd46047d_0000001& E88
+ convertToDouble +56E25
+} 0x457cf389cd46047d
+test expr-28.568 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -70 E24 x -1cf389cd46047d_0000001& E85
+ convertToDouble -70E24
+} 0xc54cf389cd46047d
+test expr-28.569 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +51 E26 x 107a9f01fbda8e_0000001& E92
+ convertToDouble +51E26
+} 0x45b07a9f01fbda8e
+test expr-28.570 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +71 E-17 x 19949819f693d7_00000000001& E-51
+ convertToDouble +71E-17
+} 0x3cc9949819f693d7
+test expr-28.571 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -31 E-5 x -1450efdc9c4da9_00000000001& E-12
+ convertToDouble -31E-5
+} 0xbf3450efdc9c4da9
+test expr-28.572 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +62 E-5 x 1450efdc9c4da9_00000000001& E-11
+ convertToDouble +62E-5
+} 0x3f4450efdc9c4da9
+test expr-28.573 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -94 E-8 x -1f8a89dc374df5_0000000001& E-21
+ convertToDouble -94E-8
+} 0xbeaf8a89dc374df5
+test expr-28.574 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +67 E27 x 1b0fa33bba7231_11111110& E95
+ convertToDouble +67E27
+} 0x45eb0fa33bba7232
+test expr-28.575 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -81 E24 x -10c01ab31bb5cb_1111110& E86
+ convertToDouble -81E24
+} 0xc550c01ab31bb5cc
+test expr-28.576 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +54 E23 x 11ddfa58a6173f_111110& E82
+ convertToDouble +54E23
+} 0x4511ddfa58a61740
+test expr-28.577 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -54 E25 x -1bead72a838453_111110& E88
+ convertToDouble -54E25
+} 0xc57bead72a838454
+test expr-28.578 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +63 E-22 x 1dc03b8fd70169_11111111110& E-68
+ convertToDouble +63E-22
+} 0x3bbdc03b8fd7016a
+test expr-28.579 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -63 E-23 x -17ccfc73126787_11111111110& E-71
+ convertToDouble -63E-23
+} 0xbb87ccfc73126788
+test expr-28.580 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +43 E-4 x 119ce075f6fd21_111111110& E-8
+ convertToDouble +43E-4
+} 0x3f719ce075f6fd22
+test expr-28.581 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -86 E-4 x -119ce075f6fd21_111111110& E-7
+ convertToDouble -86E-4
+} 0xbf819ce075f6fd22
+test expr-28.582 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +942 E26 x 1306069e8681f3_00000000001& E96
+ convertToDouble +942E26
+} 0x45f306069e8681f3
+test expr-28.583 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -471 E25 x -1e700a973d9cb8_0000000001& E91
+ convertToDouble -471E25
+} 0xc5ae700a973d9cb8
+test expr-28.584 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +803 E24 x 14c1cee9cd666b_000000000001& E89
+ convertToDouble +803E24
+} 0x4584c1cee9cd666b
+test expr-28.585 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -471 E26 x -1306069e8681f3_00000000001& E95
+ convertToDouble -471E26
+} 0xc5e306069e8681f3
+test expr-28.586 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -409 E-21 x -1e2dcaa4115622_000000000001& E-62
+ convertToDouble -409E-21
+} 0xbc1e2dcaa4115622
+test expr-28.587 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +818 E-21 x 1e2dcaa4115622_000000000001& E-61
+ convertToDouble +818E-21
+} 0x3c2e2dcaa4115622
+test expr-28.588 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -867 E-8 x -122eabba029aba_000000000001& E-17
+ convertToDouble -867E-8
+} 0xbee22eabba029aba
+test expr-28.589 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +538 E27 x 1b297cad9f70b5_1111111111111110& E98
+ convertToDouble +538E27
+} 0x461b297cad9f70b6
+test expr-28.590 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -857 E24 x -16272678ba603b_11111111110& E89
+ convertToDouble -857E24
+} 0xc586272678ba603c
+test expr-28.591 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +269 E27 x 1b297cad9f70b5_1111111111111110& E97
+ convertToDouble +269E27
+} 0x460b297cad9f70b6
+test expr-28.592 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -403 E26 x -1046ec1e31dd85_1111111110& E95
+ convertToDouble -403E26
+} 0xc5e046ec1e31dd86
+test expr-28.593 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +959 E-7 x 1923bd746a3527_11111111111110& E-14
+ convertToDouble +959E-7
+} 0x3f1923bd746a3528
+test expr-28.594 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -959 E-6 x -1f6cacd184c271_1111111111110& E-11
+ convertToDouble -959E-6
+} 0xbf4f6cacd184c272
+test expr-28.595 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +373 E-27 x 1cdc06b20ef182_1111111111110& E-82
+ convertToDouble +373E-27
+} 0x3adcdc06b20ef183
+test expr-28.596 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -746 E-27 x -1cdc06b20ef182_1111111111110& E-81
+ convertToDouble -746E-27
+} 0xbaecdc06b20ef183
+test expr-28.597 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4069 E24 x 1a4b9887fbfe7a_0000000000001& E91
+ convertToDouble +4069E24
+} 0x45aa4b9887fbfe7a
+test expr-28.598 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4069 E23 x -150946d32ffec8_0000000000001& E88
+ convertToDouble -4069E23
+} 0xc5750946d32ffec8
+test expr-28.599 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8138 E24 x -1a4b9887fbfe7a_0000000000001& E92
+ convertToDouble -8138E24
+} 0xc5ba4b9887fbfe7a
+test expr-28.600 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8294 E-15 x 123d1b5eb1d778_000000000000000001& E-37
+ convertToDouble +8294E-15
+} 0x3da23d1b5eb1d778
+test expr-28.601 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4147 E-14 x -16cc62365e4d56_00000000000000001& E-35
+ convertToDouble -4147E-14
+} 0xbdc6cc62365e4d56
+test expr-28.602 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4147 E-15 x 123d1b5eb1d778_000000000000000001& E-38
+ convertToDouble +4147E-15
+} 0x3d923d1b5eb1d778
+test expr-28.603 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8294 E-14 x -16cc62365e4d56_00000000000000001& E-34
+ convertToDouble -8294E-14
+} 0xbdd6cc62365e4d56
+test expr-28.604 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +538 E27 x 1b297cad9f70b5_1111111111111110& E98
+ convertToDouble +538E27
+} 0x461b297cad9f70b6
+test expr-28.605 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2690 E26 x -1b297cad9f70b5_1111111111111110& E97
+ convertToDouble -2690E26
+} 0xc60b297cad9f70b6
+test expr-28.606 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +269 E27 x 1b297cad9f70b5_1111111111111110& E97
+ convertToDouble +269E27
+} 0x460b297cad9f70b6
+test expr-28.607 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2152 E27 x -1b297cad9f70b5_1111111111111110& E100
+ convertToDouble -2152E27
+} 0xc63b297cad9f70b6
+test expr-28.608 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +1721 E-17 x 136071dcae4564_111111111111110& E-46
+ convertToDouble +1721E-17
+} 0x3d136071dcae4565
+test expr-28.609 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -7979 E-27 x -134ac304747faf_111111111111110& E-77
+ convertToDouble -7979E-27
+} 0xbb234ac304747fb0
+test expr-28.610 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6884 E-17 x 136071dcae4564_111111111111110& E-44
+ convertToDouble +6884E-17
+} 0x3d336071dcae4565
+test expr-28.611 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8605 E-18 x -136071dcae4564_111111111111110& E-47
+ convertToDouble -8605E-18
+} 0xbd036071dcae4565
+test expr-28.612 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +82854 E27 x 10570ed9e3cecc_00000000000000001& E106
+ convertToDouble +82854E27
+} 0x4690570ed9e3cecc
+test expr-28.613 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -55684 E24 x -167d9735144ae3_00000000000000001& E95
+ convertToDouble -55684E24
+} 0xc5e67d9735144ae3
+test expr-28.614 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +27842 E24 x 167d9735144ae3_00000000000000001& E94
+ convertToDouble +27842E24
+} 0x45d67d9735144ae3
+test expr-28.615 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -48959 E25 x -18b7cd6ca56f85_00000000000000001& E98
+ convertToDouble -48959E25
+} 0xc618b7cd6ca56f85
+test expr-28.616 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +81921 E-17 x 1cd2c9a6cdd003_000000000000000000001& E-41
+ convertToDouble +81921E-17
+} 0x3d6cd2c9a6cdd003
+test expr-28.617 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -76207 E-8 x -18f8b4dd16f1df_0000000000000000001& E-11
+ convertToDouble -76207E-8
+} 0xbf48f8b4dd16f1df
+test expr-28.618 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4147 E-15 x 123d1b5eb1d778_000000000000000001& E-38
+ convertToDouble +4147E-15
+} 0x3d923d1b5eb1d778
+test expr-28.619 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -41470 E-16 x -123d1b5eb1d778_000000000000000001& E-38
+ convertToDouble -41470E-16
+} 0xbd923d1b5eb1d778
+test expr-28.620 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +89309 E24 x 12092ac5f2019e_1111111111111111110& E96
+ convertToDouble +89309E24
+} 0x45f2092ac5f2019f
+test expr-28.621 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +75859 E26 x 17efd75a2938eb_1111111111111111111110& E102
+ convertToDouble +75859E26
+} 0x4657efd75a2938ec
+test expr-28.622 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -75859 E25 x -132645e1ba93ef_1111111111111111111110& E99
+ convertToDouble -75859E25
+} 0xc6232645e1ba93f0
+test expr-28.623 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +14257 E-23 x 150a246ecd44f2_1111111111111111110& E-63
+ convertToDouble +14257E-23
+} 0x3c050a246ecd44f3
+test expr-28.624 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -28514 E-23 x -150a246ecd44f2_1111111111111111110& E-62
+ convertToDouble -28514E-23
+} 0xbc150a246ecd44f3
+test expr-28.625 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +57028 E-23 x 150a246ecd44f2_1111111111111111110& E-61
+ convertToDouble +57028E-23
+} 0x3c250a246ecd44f3
+test expr-28.626 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -71285 E-24 x -150a246ecd44f2_1111111111111111110& E-64
+ convertToDouble -71285E-24
+} 0xbbf50a246ecd44f3
+test expr-28.627 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +344863 E27 x 1100c873963d6d_00000000000000000001& E108
+ convertToDouble +344863E27
+} 0x46b100c873963d6d
+test expr-28.628 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -951735 E27 x -17764ad224e24a_000000000000000000001& E109
+ convertToDouble -951735E27
+} 0xc6c7764ad224e24a
+test expr-28.629 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +200677 E23 x 1035e73135b834_0000000000000000001& E94
+ convertToDouble +200677E23
+} 0x45d035e73135b834
+test expr-28.630 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -401354 E24 x -144360fd832641_0000000000000000001& E98
+ convertToDouble -401354E24
+} 0xc6144360fd832641
+test expr-28.631 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +839604 E-11 x 119b96f36ec68b_00000000000000000000000001& E-17
+ convertToDouble +839604E-11
+} 0x3ee19b96f36ec68b
+test expr-28.632 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -209901 E-11 x -119b96f36ec68b_00000000000000000000000001& E-19
+ convertToDouble -209901E-11
+} 0xbec19b96f36ec68b
+test expr-28.633 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +419802 E-11 x 119b96f36ec68b_00000000000000000000000001& E-18
+ convertToDouble +419802E-11
+} 0x3ed19b96f36ec68b
+test expr-28.634 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -537734 E-24 x -13d6c1088ae40e_0000000000000000000001& E-61
+ convertToDouble -537734E-24
+} 0xbc23d6c1088ae40e
+test expr-28.635 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +910308 E26 x 11f3e1839eeab0_11111111111111111111110& E106
+ convertToDouble +910308E26
+} 0x4691f3e1839eeab1
+test expr-28.636 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -227577 E26 x -11f3e1839eeab0_11111111111111111111110& E104
+ convertToDouble -227577E26
+} 0xc671f3e1839eeab1
+test expr-28.637 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +455154 E26 x 11f3e1839eeab0_11111111111111111111110& E105
+ convertToDouble +455154E26
+} 0x4681f3e1839eeab1
+test expr-28.638 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -531013 E25 x -10c17d25834171_11111111111111111111110& E102
+ convertToDouble -531013E25
+} 0xc650c17d25834172
+test expr-28.639 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +963019 E-21 x 11592429784914_11111111111111111111110& E-50
+ convertToDouble +963019E-21
+} 0x3cd1592429784915
+test expr-28.640 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -519827 E-13 x -1be872a8b30d7c_11111111111111111111110& E-25
+ convertToDouble -519827E-13
+} 0xbe6be872a8b30d7d
+test expr-28.641 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +623402 E-27 x 178d2c97bde2a0_11111111111111111111110& E-71
+ convertToDouble +623402E-27
+} 0x3b878d2c97bde2a1
+test expr-28.642 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -311701 E-27 x -178d2c97bde2a0_11111111111111111111110& E-72
+ convertToDouble -311701E-27
+} 0xbb778d2c97bde2a1
+test expr-28.643 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9613651 E26 x 17b31116270d9b_000000000000000000000001& E109
+ convertToDouble +9613651E26
+} 0x46c7b31116270d9b
+test expr-28.644 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -9191316 E23 x -1733bfae0801fd_0000000000000000000001& E99
+ convertToDouble -9191316E23
+} 0xc62733bfae0801fd
+test expr-28.645 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4595658 E23 x 1733bfae0801fd_0000000000000000000001& E98
+ convertToDouble +4595658E23
+} 0x461733bfae0801fd
+test expr-28.646 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2297829 E23 x -1733bfae0801fd_0000000000000000000001& E97
+ convertToDouble -2297829E23
+} 0xc60733bfae0801fd
+test expr-28.647 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -1679208 E-11 x -119b96f36ec68b_00000000000000000000000001& E-16
+ convertToDouble -1679208E-11
+} 0xbef19b96f36ec68b
+test expr-28.648 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +3379223 E27 x 14d3794ce2fc25_1111111111111111111111110& E111
+ convertToDouble +3379223E27
+} 0x46e4d3794ce2fc26
+test expr-28.649 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -6758446 E27 x -14d3794ce2fc25_1111111111111111111111110& E112
+ convertToDouble -6758446E27
+} 0xc6f4d3794ce2fc26
+test expr-28.650 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +5444097 E-21 x 18849dd33c95ae_11111111111111111111111111110& E-48
+ convertToDouble +5444097E-21
+} 0x3cf8849dd33c95af
+test expr-28.651 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8399969 E-27 x -13d5783e85fcf7_1111111111111111111111110& E-67
+ convertToDouble -8399969E-27
+} 0xbbc3d5783e85fcf8
+test expr-28.652 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8366487 E-16 x 1cbf3d630403af_1111111111111111111111110& E-31
+ convertToDouble +8366487E-16
+} 0x3e0cbf3d630403b0
+test expr-28.653 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8366487 E-15 x -11f7865de2824d_11111111111111111111111110& E-27
+ convertToDouble -8366487E-15
+} 0xbe41f7865de2824e
+test expr-28.654 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +65060671 E25 x 1009e7d474572a_0000000000000000000000000001& E109
+ convertToDouble +65060671E25
+} 0x46c009e7d474572a
+test expr-28.655 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +65212389 E23 x 1493d098d37657_000000000000000000000000001& E102
+ convertToDouble +65212389E23
+} 0x465493d098d37657
+test expr-28.656 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +55544957 E-13 x 174c1826f3010c_00000000000000000000000000001& E-18
+ convertToDouble +55544957E-13
+} 0x3ed74c1826f3010c
+test expr-28.657 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -51040905 E-20 x -11f55b23c8bf2d_0000000000000000000000000001& E-41
+ convertToDouble -51040905E-20
+} 0xbd61f55b23c8bf2d
+test expr-28.658 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +99585767 E-22 x 166cba8699f0f2_0000000000000000000000000001& E-47
+ convertToDouble +99585767E-22
+} 0x3d066cba8699f0f2
+test expr-28.659 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -99585767 E-23 x -11f095387b2728_0000000000000000000000000001& E-50
+ convertToDouble -99585767E-23
+} 0xbcd1f095387b2728
+test expr-28.660 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +40978393 E26 x 1941401cca2bfd_1111111111111111111111111110& E111
+ convertToDouble +40978393E26
+} 0x46e941401cca2bfe
+test expr-28.661 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -67488159 E24 x -1a9e90059d12db_11111111111111111111111111110& E105
+ convertToDouble -67488159E24
+} 0xc68a9e90059d12dc
+test expr-28.662 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +69005339 E23 x 15c634f6ef1f95_111111111111111111111111110& E102
+ convertToDouble +69005339E23
+} 0x4655c634f6ef1f96
+test expr-28.663 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -81956786 E26 x -1941401cca2bfd_1111111111111111111111111110& E112
+ convertToDouble -81956786E26
+} 0xc6f941401cca2bfe
+test expr-28.664 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -87105552 E-21 x -18849dd33c95ae_11111111111111111111111111110& E-44
+ convertToDouble -87105552E-21
+} 0xbd38849dd33c95af
+test expr-28.665 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +10888194 E-21 x 18849dd33c95ae_11111111111111111111111111110& E-47
+ convertToDouble +10888194E-21
+} 0x3d08849dd33c95af
+test expr-28.666 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -21776388 E-21 x -18849dd33c95ae_11111111111111111111111111110& E-46
+ convertToDouble -21776388E-21
+} 0xbd18849dd33c95af
+test expr-28.667 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +635806667 E27 x 1e9cec176c96f8_000000000000000000000000000000001& E118
+ convertToDouble +635806667E27
+} 0x475e9cec176c96f8
+test expr-28.668 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -670026614 E25 x -14a593f89f4194_00000000000000000000000000000001& E112
+ convertToDouble -670026614E25
+} 0xc6f4a593f89f4194
+test expr-28.669 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +335013307 E26 x 19cef8f6c711f9_0000000000000000000000000000001& E114
+ convertToDouble +335013307E26
+} 0x4719cef8f6c711f9
+test expr-28.670 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -335013307 E25 x -14a593f89f4194_00000000000000000000000000000001& E111
+ convertToDouble -335013307E25
+} 0xc6e4a593f89f4194
+test expr-28.671 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +371790617 E-24 x 1aca538c61ba9c_000000000000000000000000000000001& E-52
+ convertToDouble +371790617E-24
+} 0x3cbaca538c61ba9c
+test expr-28.672 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -371790617 E-25 x -156ea93d1afbb0_0000000000000000000000000000000001& E-55
+ convertToDouble -371790617E-25
+} 0xbc856ea93d1afbb0
+test expr-28.673 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +743581234 E-24 x 1aca538c61ba9c_000000000000000000000000000000001& E-51
+ convertToDouble +743581234E-24
+} 0x3ccaca538c61ba9c
+test expr-28.674 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -743581234 E-25 x -156ea93d1afbb0_0000000000000000000000000000000001& E-54
+ convertToDouble -743581234E-25
+} 0xbc956ea93d1afbb0
+test expr-28.675 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +202464477 E24 x 13f6ec0435ce24_111111111111111111111111111110& E107
+ convertToDouble +202464477E24
+} 0x46a3f6ec0435ce25
+test expr-28.676 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -404928954 E24 x -13f6ec0435ce24_111111111111111111111111111110& E108
+ convertToDouble -404928954E24
+} 0xc6b3f6ec0435ce25
+test expr-28.677 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +997853758 E27 x 1805bfa33b98fa_111111111111111111111111111110& E119
+ convertToDouble +997853758E27
+} 0x476805bfa33b98fb
+test expr-28.678 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -997853758 E26 x -1337cc829613fb_111111111111111111111111111110& E116
+ convertToDouble -997853758E26
+} 0xc73337cc829613fc
+test expr-28.679 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +405498418 E-17 x 116a8093df66a6_111111111111111111111111111111110& E-28
+ convertToDouble +405498418E-17
+} 0x3e316a8093df66a7
+test expr-28.680 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -582579084 E-14 x -186f653140a658_111111111111111111111111111111110& E-18
+ convertToDouble -582579084E-14
+} 0xbed86f653140a659
+test expr-28.681 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +608247627 E-18 x 14e633e4a5ae61_111111111111111111111111111111110& E-31
+ convertToDouble +608247627E-18
+} 0x3e04e633e4a5ae62
+test expr-28.682 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -291289542 E-14 x -186f653140a658_111111111111111111111111111111110& E-19
+ convertToDouble -291289542E-14
+} 0xbec86f653140a659
+test expr-28.683 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -9537100005 E26 x -16f5b11191713a_000000000000000000000000000000001& E119
+ convertToDouble -9537100005E26
+} 0xc766f5b11191713a
+test expr-28.684 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6358066670 E27 x 1322138ea3de5b_000000000000000000000000000000001& E122
+ convertToDouble +6358066670E27
+} 0x479322138ea3de5b
+test expr-28.685 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -1271613334 E27 x -1e9cec176c96f8_000000000000000000000000000000001& E119
+ convertToDouble -1271613334E27
+} 0xc76e9cec176c96f8
+test expr-28.686 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +5229646999 E-16 x 118c3b89731f3d_000000000000000000000000000000000001& E-21
+ convertToDouble +5229646999E-16
+} 0x3ea18c3b89731f3d
+test expr-28.687 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +5229646999 E-17 x 1c13927584fec8_00000000000000000000000000000000001& E-25
+ convertToDouble +5229646999E-17
+} 0x3e6c13927584fec8
+test expr-28.688 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4429943614 E24 x 1b4d37fa06864a_1111111111111111111111111111111110& E111
+ convertToDouble +4429943614E24
+} 0x46eb4d37fa06864b
+test expr-28.689 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8859887228 E24 x -1b4d37fa06864a_1111111111111111111111111111111110& E112
+ convertToDouble -8859887228E24
+} 0xc6fb4d37fa06864b
+test expr-28.690 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +2214971807 E24 x 1b4d37fa06864a_1111111111111111111111111111111110& E110
+ convertToDouble +2214971807E24
+} 0x46db4d37fa06864b
+test expr-28.691 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4176887093 E26 x -141c692c5bd07a_111111111111111111111111111111110& E118
+ convertToDouble -4176887093E26
+} 0xc7541c692c5bd07b
+test expr-28.692 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4003495257 E-20 x 16026b2e07ec06_111111111111111111111111111111111110& E-35
+ convertToDouble +4003495257E-20
+} 0x3dc6026b2e07ec07
+test expr-28.693 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4361901637 E-23 x -188e29a9d7c5b8_11111111111111111111111111111111110& E-45
+ convertToDouble -4361901637E-23
+} 0xbd288e29a9d7c5b9
+test expr-28.694 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8723803274 E-23 x 188e29a9d7c5b8_11111111111111111111111111111111110& E-44
+ convertToDouble +8723803274E-23
+} 0x3d388e29a9d7c5b9
+test expr-28.695 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8006990514 E-20 x -16026b2e07ec06_111111111111111111111111111111111110& E-34
+ convertToDouble -8006990514E-20
+} 0xbdd6026b2e07ec07
+test expr-28.696 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +72835110098 E27 x 1b65c41711fb6d_0000000000000000000000000000000000001& E125
+ convertToDouble +72835110098E27
+} 0x47cb65c41711fb6d
+test expr-28.697 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -36417555049 E27 x -1b65c41711fb6d_0000000000000000000000000000000000001& E124
+ convertToDouble -36417555049E27
+} 0xc7bb65c41711fb6d
+test expr-28.698 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +84279630104 E25 x 144a221b1cf62e_000000000000000000000000000000000001& E119
+ convertToDouble +84279630104E25
+} 0x47644a221b1cf62e
+test expr-28.699 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -84279630104 E24 x -103b4e7c172b58_000000000000000000000000000000000001& E116
+ convertToDouble -84279630104E24
+} 0xc7303b4e7c172b58
+test expr-28.700 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +21206176437 E-27 x 1872f563ae0cc9_0000000000000000000000000000000000001& E-56
+ convertToDouble +21206176437E-27
+} 0x3c7872f563ae0cc9
+test expr-28.701 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -66461566917 E-22 x -1d3ae83e4322b3_00000000000000000000000000000000000001& E-38
+ convertToDouble -66461566917E-22
+} 0xbd9d3ae83e4322b3
+test expr-28.702 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +64808355539 E-16 x 1b2ebe83265fbf_00000000000000000000000000000000000001& E-18
+ convertToDouble +64808355539E-16
+} 0x3edb2ebe83265fbf
+test expr-28.703 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -84932679673 E-19 x -123d39339f1bf6_00000000000000000000000000000000000001& E-27
+ convertToDouble -84932679673E-19
+} 0xbe423d39339f1bf6
+test expr-28.704 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +65205430094 E26 x 139f3e5d7fd76a_1111111111111111111111111111111111110& E122
+ convertToDouble +65205430094E26
+} 0x47939f3e5d7fd76b
+test expr-28.705 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -68384463429 E25 x -107684982f634e_1111111111111111111111111111111111111110& E119
+ convertToDouble -68384463429E25
+} 0xc7607684982f634f
+test expr-28.706 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +32602715047 E26 x 139f3e5d7fd76a_1111111111111111111111111111111111110& E121
+ convertToDouble +32602715047E26
+} 0x47839f3e5d7fd76b
+test expr-28.707 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -62662203426 E27 x -1792269424688d_111111111111111111111111111111111110& E125
+ convertToDouble -62662203426E27
+} 0xc7c792269424688e
+test expr-28.708 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +58784444678 E-18 x 1f8f45c64b4682_111111111111111111111111111111111111110& E-25
+ convertToDouble +58784444678E-18
+} 0x3e6f8f45c64b4683
+test expr-28.709 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -50980203373 E-21 x -1c06d366394440_11111111111111111111111111111111111111111110& E-35
+ convertToDouble -50980203373E-21
+} 0xbdcc06d366394441
+test expr-28.710 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +29392222339 E-18 x 1f8f45c64b4682_111111111111111111111111111111111111110& E-26
+ convertToDouble +29392222339E-18
+} 0x3e5f8f45c64b4683
+test expr-28.711 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -75529940323 E-27 x -15c5203c0aad52_1111111111111111111111111111111111111110& E-54
+ convertToDouble -75529940323E-27
+} 0xbc95c5203c0aad53
+test expr-28.712 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -937495906299 E26 x -11a1e0ebb6af11_000000000000000000000000000000000000000001& E126
+ convertToDouble -937495906299E26
+} 0xc7d1a1e0ebb6af11
+test expr-28.713 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +842642485799 E-20 x 121879decdd7cb_000000000000000000000000000000000000000001& E-27
+ convertToDouble +842642485799E-20
+} 0x3e421879decdd7cb
+test expr-28.714 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -387824150699 E-23 x -110e8302245571_00000000000000000000000000000000000000001& E-38
+ convertToDouble -387824150699E-23
+} 0xbd910e8302245571
+test expr-28.715 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +924948814726 E-27 x 10a992d1fc6ded_00000000000000000000000000000000000000001& E-50
+ convertToDouble +924948814726E-27
+} 0x3cd0a992d1fc6ded
+test expr-28.716 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -775648301398 E-23 x -110e8302245571_00000000000000000000000000000000000000001& E-37
+ convertToDouble -775648301398E-23
+} 0xbda10e8302245571
+test expr-28.717 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +547075707432 E25 x 107684982f634e_1111111111111111111111111111111111111110& E122
+ convertToDouble +547075707432E25
+} 0x47907684982f634f
+test expr-28.718 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +683844634290 E24 x 107684982f634e_1111111111111111111111111111111111111110& E119
+ convertToDouble +683844634290E24
+} 0x47607684982f634f
+test expr-28.719 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -136768926858 E25 x -107684982f634e_1111111111111111111111111111111111111110& E120
+ convertToDouble -136768926858E25
+} 0xc7707684982f634f
+test expr-28.720 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +509802033730 E-22 x 1c06d366394440_11111111111111111111111111111111111111111110& E-35
+ convertToDouble +509802033730E-22
+} 0x3dcc06d366394441
+test expr-28.721 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +101960406746 E-21 x 1c06d366394440_11111111111111111111111111111111111111111110& E-34
+ convertToDouble +101960406746E-21
+} 0x3ddc06d366394441
+test expr-28.722 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -815683253968 E-21 x -1c06d366394440_11111111111111111111111111111111111111111110& E-31
+ convertToDouble -815683253968E-21
+} 0xbe0c06d366394441
+test expr-28.723 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +7344124123524 E24 x 1619b519dd6833_00000000000000000000000000000000000000000001& E122
+ convertToDouble +7344124123524E24
+} 0x479619b519dd6833
+test expr-28.724 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -9180155154405 E23 x -1619b519dd6833_00000000000000000000000000000000000000000001& E119
+ convertToDouble -9180155154405E23
+} 0xc76619b519dd6833
+test expr-28.725 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6479463327323 E27 x 130a9b3e9bd05e_00000000000000000000000000000000000000000001& E132
+ convertToDouble +6479463327323E27
+} 0x48330a9b3e9bd05e
+test expr-28.726 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -1836031030881 E24 x -1619b519dd6833_00000000000000000000000000000000000000000001& E120
+ convertToDouble -1836031030881E24
+} 0xc77619b519dd6833
+test expr-28.727 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4337269293039 E-19 x 1d1b5f354c63d6_00000000000000000000000000000000000000000001& E-22
+ convertToDouble +4337269293039E-19
+} 0x3e9d1b5f354c63d6
+test expr-28.728 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4599163554373 E-23 x -1948bf4d34088d_00000000000000000000000000000000000000000001& E-35
+ convertToDouble -4599163554373E-23
+} 0xbdc948bf4d34088d
+test expr-28.729 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9198327108746 E-23 x 1948bf4d34088d_00000000000000000000000000000000000000000001& E-34
+ convertToDouble +9198327108746E-23
+} 0x3dd948bf4d34088d
+test expr-28.730 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4812803938347 E27 x 1c4980a4ee94ce_111111111111111111111111111111111111111111110& E131
+ convertToDouble +4812803938347E27
+} 0x482c4980a4ee94cf
+test expr-28.731 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8412030890011 E23 x -14405075e52db9_11111111111111111111111111111111111111111110& E119
+ convertToDouble -8412030890011E23
+} 0xc764405075e52dba
+test expr-28.732 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9625607876694 E27 x 1c4980a4ee94ce_111111111111111111111111111111111111111111110& E132
+ convertToDouble +9625607876694E27
+} 0x483c4980a4ee94cf
+test expr-28.733 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4739968828249 E24 x -1c87140cdf8a1d_1111111111111111111111111111111111111111110& E121
+ convertToDouble -4739968828249E24
+} 0xc78c87140cdf8a1e
+test expr-28.734 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9697183891673 E-23 x 1aa7c959b6a666_11111111111111111111111111111111111111111111110& E-34
+ convertToDouble +9697183891673E-23
+} 0x3ddaa7c959b6a667
+test expr-28.735 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -7368108517543 E-20 x -13c7535bbd85a1_1111111111111111111111111111111111111111111110& E-24
+ convertToDouble -7368108517543E-20
+} 0xbe73c7535bbd85a2
+test expr-28.736 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +51461358161422 E25 x 18326f87d4cae0_0000000000000000000000000000000000000000000000001& E128
+ convertToDouble +51461358161422E25
+} 0x47f8326f87d4cae0
+test expr-28.737 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -77192037242133 E26 x -16af488f577e32_0000000000000000000000000000000000000000000000001& E132
+ convertToDouble -77192037242133E26
+} 0xc836af488f577e32
+test expr-28.738 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +77192037242133 E25 x 1225d3a5df9828_0000000000000000000000000000000000000000000000001& E129
+ convertToDouble +77192037242133E25
+} 0x480225d3a5df9828
+test expr-28.739 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -51461358161422 E27 x -12e767221e3e7f_0000000000000000000000000000000000000000000000001& E135
+ convertToDouble -51461358161422E27
+} 0xc862e767221e3e7f
+test expr-28.740 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +43999661561541 E-21 x 179f4476d372a3_0000000000000000000000000000000000000000000000001& E-25
+ convertToDouble +43999661561541E-21
+} 0x3e679f4476d372a3
+test expr-28.741 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -87999323123082 E-21 x -179f4476d372a3_0000000000000000000000000000000000000000000000001& E-24
+ convertToDouble -87999323123082E-21
+} 0xbe779f4476d372a3
+test expr-28.742 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +48374886826137 E-26 x 110538f23350d5_00000000000000000000000000000000000000000000001& E-41
+ convertToDouble +48374886826137E-26
+} 0x3d610538f23350d5
+test expr-28.743 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -57684246567111 E-23 x -13d1f5c1b8a912_00000000000000000000000000000000000000000000001& E-31
+ convertToDouble -57684246567111E-23
+} 0xbe03d1f5c1b8a912
+test expr-28.744 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +87192805957686 E23 x 1a3d16e55a9664_1111111111111111111111111111111111111111111110& E122
+ convertToDouble +87192805957686E23
+} 0x479a3d16e55a9665
+test expr-28.745 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -75108713005913 E24 x -1c40b4baa79655_11111111111111111111111111111111111111111111110& E125
+ convertToDouble -75108713005913E24
+} 0xc7cc40b4baa79656
+test expr-28.746 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +64233110587487 E27 x 179873e38669a6_1111111111111111111111111111111111111111111110& E135
+ convertToDouble +64233110587487E27
+} 0x48679873e38669a7
+test expr-28.747 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -77577471133384 E-23 x -1aa7c959b6a666_11111111111111111111111111111111111111111111110& E-31
+ convertToDouble -77577471133384E-23
+} 0xbe0aa7c959b6a667
+test expr-28.748 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +48485919458365 E-24 x 1aa7c959b6a666_11111111111111111111111111111111111111111111110& E-35
+ convertToDouble +48485919458365E-24
+} 0x3dcaa7c959b6a667
+test expr-28.749 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -56908598265713 E-26 x -1405deef4bdef5_111111111111111111111111111111111111111111111110& E-41
+ convertToDouble -56908598265713E-26
+} 0xbd6405deef4bdef6
+test expr-28.750 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +589722294620133 E23 x 162ed1b287caef_00000000000000000000000000000000000000000000000001& E125
+ convertToDouble +589722294620133E23
+} 0x47c62ed1b287caef
+test expr-28.751 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +652835804449289 E-22 x 118640e490b087_0000000000000000000000000000000000000000000000000001& E-24
+ convertToDouble +652835804449289E-22
+} 0x3e718640e490b087
+test expr-28.752 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -656415363936202 E-23 x -1c315cfe25d201_00000000000000000000000000000000000000000000000001& E-28
+ convertToDouble -656415363936202E-23
+} 0xbe3c315cfe25d201
+test expr-28.753 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +579336749585745 E-25 x 1fd9709d9aeb19_00000000000000000000000000000000000000000000000001& E-35
+ convertToDouble +579336749585745E-25
+} 0x3dcfd9709d9aeb19
+test expr-28.754 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -381292764980839 E-26 x -10c4f9921c3f8f_00000000000000000000000000000000000000000000000001& E-38
+ convertToDouble -381292764980839E-26
+} 0xbd90c4f9921c3f8f
+test expr-28.755 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +965265859649698 E23 x 12279607edcb0c_1111111111111111111111111111111111111111111111110& E126
+ convertToDouble +965265859649698E23
+} 0x47d2279607edcb0d
+test expr-28.756 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -848925235434882 E27 x -137d88ba4b43e3_1111111111111111111111111111111111111111111111111110& E139
+ convertToDouble -848925235434882E27
+} 0xc8a37d88ba4b43e4
+test expr-28.757 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +536177612222491 E23 x 142b33dd3acafd_11111111111111111111111111111111111111111111111110& E125
+ convertToDouble +536177612222491E23
+} 0x47c42b33dd3acafe
+test expr-28.758 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -424462617717441 E27 x -137d88ba4b43e3_1111111111111111111111111111111111111111111111111110& E138
+ convertToDouble -424462617717441E27
+} 0xc8937d88ba4b43e4
+test expr-28.759 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +276009279888989 E-27 x 136c242313c288_111111111111111111111111111111111111111111111111110& E-42
+ convertToDouble +276009279888989E-27
+} 0x3d536c242313c289
+test expr-28.760 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -608927158043691 E-26 x -1ac7e909c22f09_11111111111111111111111111111111111111111111111110& E-38
+ convertToDouble -608927158043691E-26
+} 0xbd9ac7e909c22f0a
+test expr-28.761 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +552018559777978 E-27 x 136c242313c288_111111111111111111111111111111111111111111111111110& E-41
+ convertToDouble +552018559777978E-27
+} 0x3d636c242313c289
+test expr-28.762 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -425678377667758 E-22 x -16da7aa49bdcd5_1111111111111111111111111111111111111111111111110& E-25
+ convertToDouble -425678377667758E-22
+} 0xbe66da7aa49bdcd6
+test expr-28.763 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8013702726927119 E26 x 126607f8f1b29e_00000000000000000000000000000000000000000000000000001& E139
+ convertToDouble +8013702726927119E26
+} 0x48a26607f8f1b29e
+test expr-28.764 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8862627962362001 E27 x 196f3b0e7787c2_00000000000000000000000000000000000000000000000000001& E142
+ convertToDouble +8862627962362001E27
+} 0x48d96f3b0e7787c2
+test expr-28.765 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -5068007907757162 E26 x -17456a27848397_00000000000000000000000000000000000000000000000000001& E138
+ convertToDouble -5068007907757162E26
+} 0xc897456a27848397
+test expr-28.766 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -7379714799828406 E-23 x -13cf4d2839e036_00000000000000000000000000000000000000000000000000001& E-24
+ convertToDouble -7379714799828406E-23
+} 0xbe73cf4d2839e036
+test expr-28.767 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4114538064016107 E-27 x 12188eda98010c_0000000000000000000000000000000000000000000000000001& E-38
+ convertToDouble +4114538064016107E-27
+} 0x3d92188eda98010c
+test expr-28.768 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -3689857399914203 E-23 x -13cf4d2839e036_00000000000000000000000000000000000000000000000000001& E-25
+ convertToDouble -3689857399914203E-23
+} 0xbe63cf4d2839e036
+test expr-28.769 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +5575954851815478 E23 x 1a37cfbf2ffdb5_1111111111111111111111111111111111111111111111111110& E128
+ convertToDouble +5575954851815478E23
+} 0x47fa37cfbf2ffdb6
+test expr-28.770 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +3395700941739528 E27 x 137d88ba4b43e3_1111111111111111111111111111111111111111111111111110& E141
+ convertToDouble +3395700941739528E27
+} 0x48c37d88ba4b43e4
+test expr-28.771 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4115535777581961 E-23 x 1618596be30fe4_111111111111111111111111111111111111111111111111111110& E-25
+ convertToDouble +4115535777581961E-23
+} 0x3e6618596be30fe5
+test expr-28.772 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8231071555163922 E-23 x -1618596be30fe4_111111111111111111111111111111111111111111111111111110& E-24
+ convertToDouble -8231071555163922E-23
+} 0xbe7618596be30fe5
+test expr-28.773 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6550246696190871 E-26 x 1201538b0f8c69_111111111111111111111111111111111111111111111111111110& E-34
+ convertToDouble +6550246696190871E-26
+} 0x3dd201538b0f8c6a
+test expr-28.774 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -68083046403986701 E27 x -186c70ba8ba28d_000000000000000000000000000000000000000000000000000000001& E145
+ convertToDouble -68083046403986701E27
+} 0xc9086c70ba8ba28d
+test expr-28.775 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +43566388595783643 E27 x 1f41e1bf48b03f_111111111111111111111111111111111111111111111111111111110& E144
+ convertToDouble +43566388595783643E27
+} 0x48ff41e1bf48b040
+test expr-28.776 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -87132777191567286 E27 x -1f41e1bf48b03f_111111111111111111111111111111111111111111111111111111110& E145
+ convertToDouble -87132777191567286E27
+} 0xc90f41e1bf48b040
+test expr-28.777 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +59644881059342141 E25 x 1b6338d9d8ae38_11111111111111111111111111111111111111111111111111111110& E138
+ convertToDouble +59644881059342141E25
+} 0x489b6338d9d8ae39
+test expr-28.778 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -83852770718576667 E23 x -18a4619ed6f442_111111111111111111111111111111111111111111111111111111110& E132
+ convertToDouble -83852770718576667E23
+} 0xc838a4619ed6f443
+test expr-28.779 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +99482967418206961 E-25 x 155d224bfed7ac_11111111111111111111111111111111111111111111111111111111110& E-27
+ convertToDouble +99482967418206961E-25
+} 0x3e455d224bfed7ad
+test expr-28.780 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -99482967418206961 E-26 x -11174ea3324623_11111111111111111111111111111111111111111111111111111111110& E-30
+ convertToDouble -99482967418206961E-26
+} 0xbe11174ea3324624
+test expr-28.781 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +87446669969994614 E-27 x 1809832942376d_11111111111111111111111111111111111111111111111111111110& E-34
+ convertToDouble +87446669969994614E-27
+} 0x3dd809832942376e
+test expr-28.782 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -43723334984997307 E-27 x -1809832942376d_11111111111111111111111111111111111111111111111111111110& E-35
+ convertToDouble -43723334984997307E-27
+} 0xbdc809832942376e
+test expr-28.783 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +5 E24 x 108b2a2c280290_1001& E82
+ convertToDouble +5E24
+} 0x45108b2a2c280291
+test expr-28.784 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8 E25 x -108b2a2c280290_1001& E86
+ convertToDouble -8E25
+} 0xc5508b2a2c280291
+test expr-28.785 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +1 E25 x 108b2a2c280290_1001& E83
+ convertToDouble +1E25
+} 0x45208b2a2c280291
+test expr-28.786 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4 E25 x -108b2a2c280290_1001& E85
+ convertToDouble -4E25
+} 0xc5408b2a2c280291
+test expr-28.787 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +2 E-5 x 14f8b588e368f0_100001& E-16
+ convertToDouble +2E-5
+} 0x3ef4f8b588e368f1
+test expr-28.788 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -5 E-6 x -14f8b588e368f0_100001& E-18
+ convertToDouble -5E-6
+} 0xbed4f8b588e368f1
+test expr-28.789 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4 E-5 x 14f8b588e368f0_100001& E-15
+ convertToDouble +4E-5
+} 0x3f04f8b588e368f1
+test expr-28.790 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -3 E-20 x -11b578c96db19a_100001& E-65
+ convertToDouble -3E-20
+} 0xbbe1b578c96db19b
+test expr-28.791 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +3 E27 x 1363156bbee301_0110& E91
+ convertToDouble +3E27
+} 0x45a363156bbee301
+test expr-28.792 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -9 E26 x -1743b34e18439b_010& E89
+ convertToDouble -9E26
+} 0xc58743b34e18439b
+test expr-28.793 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +7 E25 x 1cf389cd46047d_00& E85
+ convertToDouble +7E25
+} 0x454cf389cd46047d
+test expr-28.794 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -6 E27 x -1363156bbee301_0110& E92
+ convertToDouble -6E27
+} 0xc5b363156bbee301
+test expr-28.795 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +2 E-21 x 12e3b40a0e9b4f_0111110& E-69
+ convertToDouble +2E-21
+} 0x3ba2e3b40a0e9b4f
+test expr-28.796 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -5 E-22 x -12e3b40a0e9b4f_0111110& E-71
+ convertToDouble -5E-22
+} 0xbb82e3b40a0e9b4f
+test expr-28.797 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4 E-21 x -12e3b40a0e9b4f_0111110& E-68
+ convertToDouble -4E-21
+} 0xbbb2e3b40a0e9b4f
+test expr-28.798 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +87 E25 x 167d2d5406637c_10001& E89
+ convertToDouble +87E25
+} 0x45867d2d5406637d
+test expr-28.799 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -97 E24 x -140f232256e982_1000000001& E86
+ convertToDouble -97E24
+} 0xc5540f232256e983
+test expr-28.800 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +82 E-24 x 18c87154dff6c6_1000000001& E-74
+ convertToDouble +82E-24
+} 0x3b58c87154dff6c7
+test expr-28.801 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -41 E-24 x -18c87154dff6c6_1000000001& E-75
+ convertToDouble -41E-24
+} 0xbb48c87154dff6c7
+test expr-28.802 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +76 E-23 x 1cb644dc1633c0_10000001& E-71
+ convertToDouble +76E-23
+} 0x3b8cb644dc1633c1
+test expr-28.803 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +83 E25 x 15747ab143e353_011111111110& E89
+ convertToDouble +83E25
+} 0x4585747ab143e353
+test expr-28.804 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -50 E27 x -1431e0fae6d721_0111110& E95
+ convertToDouble -50E27
+} 0xc5e431e0fae6d721
+test expr-28.805 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +25 E27 x 1431e0fae6d721_0111110& E94
+ convertToDouble +25E27
+} 0x45d431e0fae6d721
+test expr-28.806 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -99 E27 x -13fe2e171cda19_011110& E96
+ convertToDouble -99E27
+} 0xc5f3fe2e171cda19
+test expr-28.807 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +97 E-10 x 14d4a1a3157dc7_011111110& E-27
+ convertToDouble +97E-10
+} 0x3e44d4a1a3157dc7
+test expr-28.808 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -57 E-20 x -15077f6f3242e7_011111110& E-61
+ convertToDouble -57E-20
+} 0xbc25077f6f3242e7
+test expr-28.809 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +997 E23 x 149e12f51c1a3c_10000000001& E86
+ convertToDouble +997E23
+} 0x45549e12f51c1a3d
+test expr-28.810 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +776 E24 x 140f232256e982_1000000001& E89
+ convertToDouble +776E24
+} 0x45840f232256e983
+test expr-28.811 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -388 E24 x -140f232256e982_1000000001& E88
+ convertToDouble -388E24
+} 0xc5740f232256e983
+test expr-28.812 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +521 E-10 x 1bf891c92c0890_100000000001& E-25
+ convertToDouble +521E-10
+} 0x3e6bf891c92c0891
+test expr-28.813 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -506 E-26 x -1877fa0260beb2_10000000001& E-78
+ convertToDouble -506E-26
+} 0xbb1877fa0260beb3
+test expr-28.814 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +739 E-10 x 13d65e8c76722c_10000000001& E-24
+ convertToDouble +739E-10
+} 0x3e73d65e8c76722d
+test expr-28.815 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -867 E-7 x -16ba56a8834168_100000000001& E-14
+ convertToDouble -867E-7
+} 0xbf16ba56a8834169
+test expr-28.816 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -415 E24 x -15747ab143e353_011111111110& E88
+ convertToDouble -415E24
+} 0xc575747ab143e353
+test expr-28.817 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +332 E25 x 15747ab143e353_011111111110& E91
+ convertToDouble +332E25
+} 0x45a5747ab143e353
+test expr-28.818 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -664 E25 x -15747ab143e353_011111111110& E92
+ convertToDouble -664E25
+} 0xc5b5747ab143e353
+test expr-28.819 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +291 E-13 x 1ffeebfc8b81b5_01111111111110& E-36
+ convertToDouble +291E-13
+} 0x3dbffeebfc8b81b5
+test expr-28.820 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -982 E-8 x -14981285e98e79_0111111111110& E-17
+ convertToDouble -982E-8
+} 0xbee4981285e98e79
+test expr-28.821 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +582 E-13 x 1ffeebfc8b81b5_01111111111110& E-35
+ convertToDouble +582E-13
+} 0x3dcffeebfc8b81b5
+test expr-28.822 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -491 E-8 x -14981285e98e79_0111111111110& E-18
+ convertToDouble -491E-8
+} 0xbed4981285e98e79
+test expr-28.823 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4574 E26 x 1717c1a612f954_100000000001& E98
+ convertToDouble +4574E26
+} 0x461717c1a612f955
+test expr-28.824 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8609 E26 x -15bb6f942546ee_1000000000001& E99
+ convertToDouble -8609E26
+} 0xc625bb6f942546ef
+test expr-28.825 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +2287 E26 x 1717c1a612f954_100000000001& E97
+ convertToDouble +2287E26
+} 0x460717c1a612f955
+test expr-28.826 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4818 E24 x -1f22b65eb419a0_10000000001& E91
+ convertToDouble -4818E24
+} 0xc5af22b65eb419a1
+test expr-28.827 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6529 E-8 x 111d89a8b5c142_100000000000001& E-14
+ convertToDouble +6529E-8
+} 0x3f111d89a8b5c143
+test expr-28.828 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8151 E-21 x -12cb804b61b898_1000000000000001& E-57
+ convertToDouble -8151E-21
+} 0xbc62cb804b61b899
+test expr-28.829 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +1557 E-12 x 1abfc227ab1026_10000000000001& E-30
+ convertToDouble +1557E-12
+} 0x3e1abfc227ab1027
+test expr-28.830 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2573 E-18 x -172cef1ebbca44_10000000000001& E-49
+ convertToDouble -2573E-18
+} 0xbce72cef1ebbca45
+test expr-28.831 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4929 E-16 x 1157a604ed019f_0111111111111110& E-41
+ convertToDouble +4929E-16
+} 0x3d6157a604ed019f
+test expr-28.832 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -3053 E-22 x -1686f435fe6b6b_011111111111110& E-62
+ convertToDouble -3053E-22
+} 0xbc1686f435fe6b6b
+test expr-28.833 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9858 E-16 x 1157a604ed019f_0111111111111110& E-40
+ convertToDouble +9858E-16
+} 0x3d7157a604ed019f
+test expr-28.834 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -7767 E-11 x -14d971170ed055_011111111111110& E-24
+ convertToDouble -7767E-11
+} 0xbe74d971170ed055
+test expr-28.835 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +54339 E26 x 1125782ec15cbe_100000000000000001& E102
+ convertToDouble +54339E26
+} 0x465125782ec15cbf
+test expr-28.836 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -62409 E25 x -1f822c980d4bb2_100000000000000001& E98
+ convertToDouble -62409E25
+} 0xc61f822c980d4bb3
+test expr-28.837 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +32819 E27 x 19e3be885fc16a_100000000000001& E104
+ convertToDouble +32819E27
+} 0x4679e3be885fc16b
+test expr-28.838 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -89849 E27 x -11b8371b6dda04_1000000000000001& E106
+ convertToDouble -89849E27
+} 0xc691b8371b6dda05
+test expr-28.839 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +63876 E-20 x 1703856844bdbe_1000000000000000000001& E-51
+ convertToDouble +63876E-20
+} 0x3cc703856844bdbf
+test expr-28.840 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -15969 E-20 x -1703856844bdbe_1000000000000000000001& E-53
+ convertToDouble -15969E-20
+} 0xbca703856844bdbf
+test expr-28.841 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +31938 E-20 x 1703856844bdbe_1000000000000000000001& E-52
+ convertToDouble +31938E-20
+} 0x3cb703856844bdbf
+test expr-28.842 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -79845 E-21 x -1703856844bdbe_1000000000000000000001& E-54
+ convertToDouble -79845E-21
+} 0xbc9703856844bdbf
+test expr-28.843 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +89306 E27 x 119cccff237e17_011111111111110& E106
+ convertToDouble +89306E27
+} 0x46919cccff237e17
+test expr-28.844 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -25487 E24 x -1496968ba07117_01111111111110& E94
+ convertToDouble -25487E24
+} 0xc5d496968ba07117
+test expr-28.845 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +79889 E24 x 10222a1c7e27d3_01111111111110& E96
+ convertToDouble +79889E24
+} 0x45f0222a1c7e27d3
+test expr-28.846 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -97379 E26 x -1eba3685911519_011111111111111110& E102
+ convertToDouble -97379E26
+} 0xc65eba3685911519
+test expr-28.847 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +81002 E-8 x 1a8af0b45d9531_0111111111111111110& E-11
+ convertToDouble +81002E-8
+} 0x3f4a8af0b45d9531
+test expr-28.848 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -43149 E-25 x -146064de6ecbed_011111111111111110& E-68
+ convertToDouble -43149E-25
+} 0xbbb46064de6ecbed
+test expr-28.849 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +40501 E-8 x 1a8af0b45d9531_0111111111111111110& E-12
+ convertToDouble +40501E-8
+} 0x3f3a8af0b45d9531
+test expr-28.850 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -60318 E-10 x -194c988f217e51_011111111111111110& E-18
+ convertToDouble -60318E-10
+} 0xbed94c988f217e51
+test expr-28.851 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -648299 E27 x -1ff6af0bf00100_10000000000000000001& E108
+ convertToDouble -648299E27
+} 0xc6bff6af0bf00101
+test expr-28.852 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +780649 E24 x 13b4d36f9edd18_10000000000000000001& E99
+ convertToDouble +780649E24
+} 0x4623b4d36f9edd19
+test expr-28.853 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +720919 E-14 x 1ef696965cbf04_10000000000000000000000001& E-28
+ convertToDouble +720919E-14
+} 0x3e3ef696965cbf05
+test expr-28.854 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -629703 E-11 x -1a69626d2629d0_1000000000000000000000001& E-18
+ convertToDouble -629703E-11
+} 0xbeda69626d2629d1
+test expr-28.855 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +557913 E24 x 1c2adb44b394bf_01111111111111111110& E98
+ convertToDouble +557913E24
+} 0x461c2adb44b394bf
+test expr-28.856 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -847899 E23 x -111f88fb93dce9_011111111111111111110& E96
+ convertToDouble -847899E23
+} 0xc5f11f88fb93dce9
+test expr-28.857 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +565445 E27 x 1be0eb55770d4d_0111111111111111110& E108
+ convertToDouble +565445E27
+} 0x46bbe0eb55770d4d
+test expr-28.858 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -736531 E24 x -1297b853d64ac7_01111111111111111110& E99
+ convertToDouble -736531E24
+} 0xc62297b853d64ac7
+test expr-28.859 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +680013 E-19 x 13240293e95c3b_01111111111111111111110& E-44
+ convertToDouble +680013E-19
+} 0x3d33240293e95c3b
+test expr-28.860 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -529981 E-10 x -1bc948d999ac11_011111111111111111110& E-15
+ convertToDouble -529981E-10
+} 0xbf0bc948d999ac11
+test expr-28.861 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +382923 E-23 x 11a8c1c10a1fc5_011111111111111111110& E-58
+ convertToDouble +382923E-23
+} 0x3c51a8c1c10a1fc5
+test expr-28.862 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -633614 E-18 x -164b166995a9b7_011111111111111111110& E-41
+ convertToDouble -633614E-18
+} 0xbd664b166995a9b7
+test expr-28.863 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +2165479 E27 x 1ab10c016c34b8_100000000000000000000001& E110
+ convertToDouble +2165479E27
+} 0x46dab10c016c34b9
+test expr-28.864 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8661916 E27 x -1ab10c016c34b8_100000000000000000000001& E112
+ convertToDouble -8661916E27
+} 0xc6fab10c016c34b9
+test expr-28.865 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4330958 E27 x 1ab10c016c34b8_100000000000000000000001& E111
+ convertToDouble +4330958E27
+} 0x46eab10c016c34b9
+test expr-28.866 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -9391993 E22 x -12f78bec748c98_1000000000000000000001& E96
+ convertToDouble -9391993E22
+} 0xc5f2f78bec748c99
+test expr-28.867 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -5767352 E-14 x -1ef696965cbf04_10000000000000000000000001& E-25
+ convertToDouble -5767352E-14
+} 0xbe6ef696965cbf05
+test expr-28.868 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +7209190 E-15 x 1ef696965cbf04_10000000000000000000000001& E-28
+ convertToDouble +7209190E-15
+} 0x3e3ef696965cbf05
+test expr-28.869 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -1441838 E-14 x -1ef696965cbf04_10000000000000000000000001& E-27
+ convertToDouble -1441838E-14
+} 0xbe4ef696965cbf05
+test expr-28.870 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8478990 E22 x 111f88fb93dce9_011111111111111111110& E96
+ convertToDouble +8478990E22
+} 0x45f11f88fb93dce9
+test expr-28.871 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +1473062 E24 x 1297b853d64ac7_01111111111111111110& E100
+ convertToDouble +1473062E24
+} 0x463297b853d64ac7
+test expr-28.872 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8366487 E-14 x 167567f55b22e1_0111111111111111111111110& E-24
+ convertToDouble +8366487E-14
+} 0x3e767567f55b22e1
+test expr-28.873 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8399969 E-25 x -1efd8be1b15b43_011111111111111111111110& E-61
+ convertToDouble -8399969E-25
+} 0xbc2efd8be1b15b43
+test expr-28.874 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9366737 E-12 x 13a4ba87ddc13f_011111111111111111111110& E-17
+ convertToDouble +9366737E-12
+} 0x3ee3a4ba87ddc13f
+test expr-28.875 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -9406141 E-13 x -1f8fd047c84d49_0111111111111111111111110& E-21
+ convertToDouble -9406141E-13
+} 0xbeaf8fd047c84d49
+test expr-28.876 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +65970979 E24 x 1a055dd68f3e3c_1000000000000000000000000001& E105
+ convertToDouble +65970979E24
+} 0x468a055dd68f3e3d
+test expr-28.877 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -65060671 E26 x -140c61c9916cf4_100000000000000000000000001& E112
+ convertToDouble -65060671E26
+} 0xc6f40c61c9916cf5
+test expr-28.878 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +54923002 E27 x 1527d37d8b38ea_10000000000000000000000001& E115
+ convertToDouble +54923002E27
+} 0x472527d37d8b38eb
+test expr-28.879 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -63846927 E25 x -1f7a9d79dad9b4_10000000000000000000000001& E108
+ convertToDouble -63846927E25
+} 0xc6bf7a9d79dad9b5
+test expr-28.880 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +99585767 E-21 x 1c07e928406d2e_100000000000000000000000001& E-44
+ convertToDouble +99585767E-21
+} 0x3d3c07e928406d2f
+test expr-28.881 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +67488159 E25 x 10a31a03822bc9_011111111111111111111111111110& E109
+ convertToDouble +67488159E25
+} 0x46c0a31a03822bc9
+test expr-28.882 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -69005339 E24 x -1b37c234aae77b_011111111111111111111111110& E105
+ convertToDouble -69005339E24
+} 0xc68b37c234aae77b
+test expr-28.883 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +81956786 E27 x 1f919023fcb6fd_0111111111111111111111111110& E115
+ convertToDouble +81956786E27
+} 0x472f919023fcb6fd
+test expr-28.884 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -40978393 E27 x -1f919023fcb6fd_0111111111111111111111111110& E114
+ convertToDouble -40978393E27
+} 0xc71f919023fcb6fd
+test expr-28.885 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +77505754 E-12 x 145152b6f85e09_0111111111111111111111111110& E-14
+ convertToDouble +77505754E-12
+} 0x3f145152b6f85e09
+test expr-28.886 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -38752877 E-12 x -145152b6f85e09_0111111111111111111111111110& E-15
+ convertToDouble -38752877E-12
+} 0xbf045152b6f85e09
+test expr-28.887 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +82772981 E-15 x 16381dae63505f_0111111111111111111111111111110& E-24
+ convertToDouble +82772981E-15
+} 0x3e76381dae63505f
+test expr-28.888 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -95593517 E-25 x -160ad862d8537d_0111111111111111111111111110& E-57
+ convertToDouble -95593517E-25
+} 0xbc660ad862d8537d
+test expr-28.889 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +200036989 E25 x 18a80dedbc575e_10000000000000000000000000001& E110
+ convertToDouble +200036989E25
+} 0x46d8a80dedbc575f
+test expr-28.890 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -772686455 E27 x -129a0c45ceca7a_1000000000000000000000000000001& E119
+ convertToDouble -772686455E27
+} 0xc7629a0c45ceca7b
+test expr-28.891 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +859139907 E23 x 10f18c4dd0ffe2_10000000000000000000000000001& E106
+ convertToDouble +859139907E23
+} 0x4690f18c4dd0ffe3
+test expr-28.892 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -400073978 E25 x -18a80dedbc575e_10000000000000000000000000001& E111
+ convertToDouble -400073978E25
+} 0xc6e8a80dedbc575f
+test expr-28.893 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +569014327 E-14 x 17ddbeac19d3b2_100000000000000000000000000001& E-18
+ convertToDouble +569014327E-14
+} 0x3ed7ddbeac19d3b3
+test expr-28.894 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -794263862 E-15 x -1aa6acb41dfc52_1000000000000000000000000000001& E-21
+ convertToDouble -794263862E-15
+} 0xbeaaa6acb41dfc53
+test expr-28.895 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +397131931 E-15 x 1aa6acb41dfc52_1000000000000000000000000000001& E-22
+ convertToDouble +397131931E-15
+} 0x3e9aa6acb41dfc53
+test expr-28.896 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -380398957 E-16 x -146c29d8331024_100000000000000000000000000001& E-25
+ convertToDouble -380398957E-16
+} 0xbe646c29d8331025
+test expr-28.897 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +567366773 E27 x 1b5155dd5417f9_0111111111111111111111111111110& E118
+ convertToDouble +567366773E27
+} 0x475b5155dd5417f9
+test expr-28.898 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -337440795 E24 x -10a31a03822bc9_011111111111111111111111111110& E108
+ convertToDouble -337440795E24
+} 0xc6b0a31a03822bc9
+test expr-28.899 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +134976318 E25 x 10a31a03822bc9_011111111111111111111111111110& E110
+ convertToDouble +134976318E25
+} 0x46d0a31a03822bc9
+test expr-28.900 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -269952636 E25 x -10a31a03822bc9_011111111111111111111111111110& E111
+ convertToDouble -269952636E25
+} 0xc6e0a31a03822bc9
+test expr-28.901 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +932080597 E-20 x 147f25b4941e5b_0111111111111111111111111111110& E-37
+ convertToDouble +932080597E-20
+} 0x3da47f25b4941e5b
+test expr-28.902 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -331091924 E-15 x -16381dae63505f_0111111111111111111111111111110& E-22
+ convertToDouble -331091924E-15
+} 0xbe96381dae63505f
+test expr-28.903 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -413864905 E-16 x -16381dae63505f_0111111111111111111111111111110& E-25
+ convertToDouble -413864905E-16
+} 0xbe66381dae63505f
+test expr-28.904 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8539246247 E26 x 148eb7813eaeba_10000000000000000000000000000001& E119
+ convertToDouble +8539246247E26
+} 0x47648eb7813eaebb
+test expr-28.905 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -5859139791 E26 x -1c35f28719d478_10000000000000000000000000000001& E118
+ convertToDouble -5859139791E26
+} 0xc75c35f28719d479
+test expr-28.906 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6105010149 E24 x 12d000fb2b138a_1000000000000000000000000000000001& E112
+ convertToDouble +6105010149E24
+} 0x46f2d000fb2b138b
+test expr-28.907 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -3090745820 E27 x -129a0c45ceca7a_1000000000000000000000000000001& E121
+ convertToDouble -3090745820E27
+} 0xc7829a0c45ceca7b
+test expr-28.908 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +3470877773 E-20 x 1314d381f2c31e_1000000000000000000000000000000001& E-35
+ convertToDouble +3470877773E-20
+} 0x3dc314d381f2c31f
+test expr-28.909 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -6136309089 E-27 x -1c4c799fab4328_1000000000000000000000000000000001& E-58
+ convertToDouble -6136309089E-27
+} 0xbc5c4c799fab4329
+test expr-28.910 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8917758713 E-19 x 1ea424bda7d7f4_100000000000000000000000000000001& E-31
+ convertToDouble +8917758713E-19
+} 0x3e0ea424bda7d7f5
+test expr-28.911 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -6941755546 E-20 x -1314d381f2c31e_1000000000000000000000000000000001& E-34
+ convertToDouble -6941755546E-20
+} 0xbdd314d381f2c31f
+test expr-28.912 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9194900535 E25 x 11b56f9c090dfb_011111111111111111111111111111111110& E116
+ convertToDouble +9194900535E25
+} 0x4731b56f9c090dfb
+test expr-28.913 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -1838980107 E26 x -11b56f9c090dfb_011111111111111111111111111111111110& E117
+ convertToDouble -1838980107E26
+} 0xc741b56f9c090dfb
+test expr-28.914 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +7355920428 E26 x 11b56f9c090dfb_011111111111111111111111111111111110& E119
+ convertToDouble +7355920428E26
+} 0x4761b56f9c090dfb
+test expr-28.915 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -3677960214 E26 x -11b56f9c090dfb_011111111111111111111111111111111110& E118
+ convertToDouble -3677960214E26
+} 0xc751b56f9c090dfb
+test expr-28.916 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8473634343 E-17 x 16bf0984b232b7_0111111111111111111111111111111110& E-24
+ convertToDouble +8473634343E-17
+} 0x3e76bf0984b232b7
+test expr-28.917 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8870766274 E-16 x -1dc3ee22137269_0111111111111111111111111111111110& E-21
+ convertToDouble -8870766274E-16
+} 0xbeadc3ee22137269
+test expr-28.918 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +4435383137 E-16 x 1dc3ee22137269_0111111111111111111111111111111110& E-22
+ convertToDouble +4435383137E-16
+} 0x3e9dc3ee22137269
+test expr-28.919 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -9598990129 E-15 x -14216b286031e7_01111111111111111111111111111111110& E-17
+ convertToDouble -9598990129E-15
+} 0xbee4216b286031e7
+test expr-28.920 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +71563496764 E26 x 15890d1ef6a0da_10000000000000000000000000000000000001& E122
+ convertToDouble +71563496764E26
+} 0x4795890d1ef6a0db
+test expr-28.921 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -89454370955 E25 x -15890d1ef6a0da_10000000000000000000000000000000000001& E119
+ convertToDouble -89454370955E25
+} 0xc765890d1ef6a0db
+test expr-28.922 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +17890874191 E26 x 15890d1ef6a0da_10000000000000000000000000000000000001& E120
+ convertToDouble +17890874191E26
+} 0x4775890d1ef6a0db
+test expr-28.923 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -35781748382 E26 x -15890d1ef6a0da_10000000000000000000000000000000000001& E121
+ convertToDouble -35781748382E26
+} 0xc785890d1ef6a0db
+test expr-28.924 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +57973447842 E-19 x 18e63f7cf5313c_1000000000000000000000000000000000000001& E-28
+ convertToDouble +57973447842E-19
+} 0x3e38e63f7cf5313d
+test expr-28.925 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -28986723921 E-19 x -18e63f7cf5313c_1000000000000000000000000000000000000001& E-29
+ convertToDouble -28986723921E-19
+} 0xbe28e63f7cf5313d
+test expr-28.926 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +76822711313 E-19 x 107f5f8b3bf818_100000000000000000000000000000000001& E-27
+ convertToDouble +76822711313E-19
+} 0x3e407f5f8b3bf819
+test expr-28.927 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -97699466874 E-20 x -10c8de34de806e_10000000000000000000000000000000001& E-30
+ convertToDouble -97699466874E-20
+} 0xbe10c8de34de806f
+test expr-28.928 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +67748656762 E27 x 197bf5559b31fd_01111111111111111111111111111111111110& E125
+ convertToDouble +67748656762E27
+} 0x47c97bf5559b31fd
+test expr-28.929 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -19394840991 E24 x -1de1ea791a6e7d_0111111111111111111111111111111111110& E113
+ convertToDouble -19394840991E24
+} 0xc70de1ea791a6e7d
+test expr-28.930 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +38789681982 E24 x 1de1ea791a6e7d_0111111111111111111111111111111111110& E114
+ convertToDouble +38789681982E24
+} 0x471de1ea791a6e7d
+test expr-28.931 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -33874328381 E27 x -197bf5559b31fd_01111111111111111111111111111111111110& E124
+ convertToDouble -33874328381E27
+} 0xc7b97bf5559b31fd
+test expr-28.932 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +54323763886 E-27 x 1f50c5c63e5441_0111111111111111111111111111111111110& E-55
+ convertToDouble +54323763886E-27
+} 0x3c8f50c5c63e5441
+test expr-28.933 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -58987193887 E-20 x -14449185a4c829_011111111111111111111111111111111111110& E-31
+ convertToDouble -58987193887E-20
+} 0xbe04449185a4c829
+test expr-28.934 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +27161881943 E-27 x 1f50c5c63e5441_0111111111111111111111111111111111110& E-56
+ convertToDouble +27161881943E-27
+} 0x3c7f50c5c63e5441
+test expr-28.935 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -93042648033 E-19 x -13fb12dc023fd3_0111111111111111111111111111111111110& E-27
+ convertToDouble -93042648033E-19
+} 0xbe43fb12dc023fd3
+test expr-28.936 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +520831059055 E27 x 187d469cb69dd0_10000000000000000000000000000000000000001& E128
+ convertToDouble +520831059055E27
+} 0x47f87d469cb69dd1
+test expr-28.937 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -768124264394 E25 x -171d6a019edae8_1000000000000000000000000000000000000001& E122
+ convertToDouble -768124264394E25
+} 0xc7971d6a019edae9
+test expr-28.938 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +384062132197 E25 x 171d6a019edae8_1000000000000000000000000000000000000001& E121
+ convertToDouble +384062132197E25
+} 0x47871d6a019edae9
+test expr-28.939 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +765337749889 E-25 x 158ad6f5d0a854_100000000000000000000000000000000000000001& E-44
+ convertToDouble +765337749889E-25
+} 0x3d358ad6f5d0a855
+test expr-28.940 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +794368912771 E25 x 17e79872f2f7ef_01111111111111111111111111111111111111110& E122
+ convertToDouble +794368912771E25
+} 0x4797e79872f2f7ef
+test expr-28.941 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -994162090146 E23 x -132598f85e658b_011111111111111111111111111111111111110& E116
+ convertToDouble -994162090146E23
+} 0xc7332598f85e658b
+test expr-28.942 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +781652779431 E26 x 1d670adf52038f_01111111111111111111111111111111111110& E125
+ convertToDouble +781652779431E26
+} 0x47cd670adf52038f
+test expr-28.943 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +910077190046 E-26 x 147e3ce1871d79_01111111111111111111111111111111111111110& E-47
+ convertToDouble +910077190046E-26
+} 0x3d047e3ce1871d79
+test expr-28.944 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -455038595023 E-26 x -147e3ce1871d79_01111111111111111111111111111111111111110& E-48
+ convertToDouble -455038595023E-26
+} 0xbcf47e3ce1871d79
+test expr-28.945 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +471897551096 E-20 x 14449185a4c829_011111111111111111111111111111111111110& E-28
+ convertToDouble +471897551096E-20
+} 0x3e34449185a4c829
+test expr-28.946 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -906698409911 E-21 x -1f27674f7d5745_0111111111111111111111111111111111111110& E-31
+ convertToDouble -906698409911E-21
+} 0xbe0f27674f7d5745
+test expr-28.947 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8854128003935 E25 x 10a71b8948faac_100000000000000000000000000000000000000001& E126
+ convertToDouble +8854128003935E25
+} 0x47d0a71b8948faad
+test expr-28.948 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8146122716299 E27 x -17f0762ac05654_1000000000000000000000000000000000000000001& E132
+ convertToDouble -8146122716299E27
+} 0xc837f0762ac05655
+test expr-28.949 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +7083302403148 E26 x 10a71b8948faac_100000000000000000000000000000000000000001& E129
+ convertToDouble +7083302403148E26
+} 0x4800a71b8948faad
+test expr-28.950 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -3541651201574 E26 x -10a71b8948faac_100000000000000000000000000000000000000001& E128
+ convertToDouble -3541651201574E26
+} 0xc7f0a71b8948faad
+test expr-28.951 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8394920649291 E-25 x 1d8978e8c1cc78_100000000000000000000000000000000000000000001& E-41
+ convertToDouble +8394920649291E-25
+} 0x3d6d8978e8c1cc79
+test expr-28.952 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -7657975756753 E-22 x -1a5006d695fef0_1000000000000000000000000000000000000000000001& E-31
+ convertToDouble -7657975756753E-22
+} 0xbe0a5006d695fef1
+test expr-28.953 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +5473834002228 E-20 x 1d632e1f745624_100000000000000000000000000000000000000000001& E-25
+ convertToDouble +5473834002228E-20
+} 0x3e6d632e1f745625
+test expr-28.954 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -6842292502785 E-21 x -1d632e1f745624_100000000000000000000000000000000000000000001& E-28
+ convertToDouble -6842292502785E-21
+} 0xbe3d632e1f745625
+test expr-28.955 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2109568884597 E25 x -1fbdc386609b13_011111111111111111111111111111111111111110& E123
+ convertToDouble -2109568884597E25
+} 0xc7afbdc386609b13
+test expr-28.956 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +8438275538388 E25 x 1fbdc386609b13_011111111111111111111111111111111111111110& E125
+ convertToDouble +8438275538388E25
+} 0x47cfbdc386609b13
+test expr-28.957 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -4219137769194 E25 x -1fbdc386609b13_011111111111111111111111111111111111111110& E124
+ convertToDouble -4219137769194E25
+} 0xc7bfbdc386609b13
+test expr-28.958 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +3200141789841 E-25 x 1684dcea3829f7_0111111111111111111111111111111111111111110& E-42
+ convertToDouble +3200141789841E-25
+} 0x3d5684dcea3829f7
+test expr-28.959 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8655689322607 E-22 x -1dbd9ff5dc8991_011111111111111111111111111111111111111110& E-31
+ convertToDouble -8655689322607E-22
+} 0xbe0dbd9ff5dc8991
+test expr-28.960 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6400283579682 E-25 x 1684dcea3829f7_0111111111111111111111111111111111111111110& E-41
+ convertToDouble +6400283579682E-25
+} 0x3d6684dcea3829f7
+test expr-28.961 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -8837719634493 E-21 x -12fa9676d2585b_011111111111111111111111111111111111111110& E-27
+ convertToDouble -8837719634493E-21
+} 0xbe42fa9676d2585b
+test expr-28.962 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +19428217075297 E24 x 1d3b7a1d154aba_10000000000000000000000000000000000000000000001& E123
+ convertToDouble +19428217075297E24
+} 0x47ad3b7a1d154abb
+test expr-28.963 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -38856434150594 E24 x -1d3b7a1d154aba_10000000000000000000000000000000000000000000001& E124
+ convertToDouble -38856434150594E24
+} 0xc7bd3b7a1d154abb
+test expr-28.964 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +77712868301188 E24 x 1d3b7a1d154aba_10000000000000000000000000000000000000000000001& E125
+ convertToDouble +77712868301188E24
+} 0x47cd3b7a1d154abb
+test expr-28.965 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -77192037242133 E27 x -1c5b1ab32d5dbe_1000000000000000000000000000000000000000000000001& E135
+ convertToDouble -77192037242133E27
+} 0xc86c5b1ab32d5dbf
+test expr-28.966 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +76579757567530 E-23 x 1a5006d695fef0_1000000000000000000000000000000000000000000001& E-31
+ convertToDouble +76579757567530E-23
+} 0x3e0a5006d695fef1
+test expr-28.967 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +15315951513506 E-22 x 1a5006d695fef0_1000000000000000000000000000000000000000000001& E-30
+ convertToDouble +15315951513506E-22
+} 0x3e1a5006d695fef1
+test expr-28.968 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -38289878783765 E-23 x -1a5006d695fef0_1000000000000000000000000000000000000000000001& E-32
+ convertToDouble -38289878783765E-23
+} 0xbdfa5006d695fef1
+test expr-28.969 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +49378033925202 E25 x 1737aa2567167b_0111111111111111111111111111111111111111111110& E128
+ convertToDouble +49378033925202E25
+} 0x47f737aa2567167b
+test expr-28.970 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -50940527102367 E24 x -132964f2944b05_0111111111111111111111111111111111111111111111110& E125
+ convertToDouble -50940527102367E24
+} 0xc7c32964f2944b05
+test expr-28.971 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +98756067850404 E25 x 1737aa2567167b_0111111111111111111111111111111111111111111110& E129
+ convertToDouble +98756067850404E25
+} 0x480737aa2567167b
+test expr-28.972 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -99589397544892 E26 x -1d4446075c4933_0111111111111111111111111111111111111111111110& E132
+ convertToDouble -99589397544892E26
+} 0xc83d4446075c4933
+test expr-28.973 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -56908598265713 E-25 x -190756ab1ed6b3_011111111111111111111111111111111111111111111110& E-38
+ convertToDouble -56908598265713E-25
+} 0xbd990756ab1ed6b3
+test expr-28.974 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +97470695699657 E-22 x 14ee821710e655_01111111111111111111111111111111111111111111110& E-27
+ convertToDouble +97470695699657E-22
+} 0x3e44ee821710e655
+test expr-28.975 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -35851901247343 E-25 x -1f8921657e1581_0111111111111111111111111111111111111111111110& E-39
+ convertToDouble -35851901247343E-25
+} 0xbd8f8921657e1581
+test expr-28.976 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +154384074484266 E27 x 1c5b1ab32d5dbe_1000000000000000000000000000000000000000000000001& E136
+ convertToDouble +154384074484266E27
+} 0x487c5b1ab32d5dbf
+test expr-28.977 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -308768148968532 E27 x -1c5b1ab32d5dbe_1000000000000000000000000000000000000000000000001& E137
+ convertToDouble -308768148968532E27
+} 0xc88c5b1ab32d5dbf
+test expr-28.978 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +910990389005985 E23 x 112242592ae54a_100000000000000000000000000000000000000000000001& E126
+ convertToDouble +910990389005985E23
+} 0x47d12242592ae54b
+test expr-28.979 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +271742424169201 E-27 x 131f46bcf7b452_10000000000000000000000000000000000000000000000001& E-42
+ convertToDouble +271742424169201E-27
+} 0x3d531f46bcf7b453
+test expr-28.980 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -543484848338402 E-27 x -131f46bcf7b452_10000000000000000000000000000000000000000000000001& E-41
+ convertToDouble -543484848338402E-27
+} 0xbd631f46bcf7b453
+test expr-28.981 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +162192083357563 E-26 x 1c887b68658760_1000000000000000000000000000000000000000000000001& E-40
+ convertToDouble +162192083357563E-26
+} 0x3d7c887b68658761
+test expr-28.982 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -869254552770081 E-23 x -12aac70665485e_1000000000000000000000000000000000000000000000000001& E-27
+ convertToDouble -869254552770081E-23
+} 0xbe42aac70665485f
+test expr-28.983 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +664831007626046 E24 x 1f429cb67eb075_011111111111111111111111111111111111111111111111110& E128
+ convertToDouble +664831007626046E24
+} 0x47ff429cb67eb075
+test expr-28.984 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -332415503813023 E24 x -1f429cb67eb075_011111111111111111111111111111111111111111111111110& E127
+ convertToDouble -332415503813023E24
+} 0xc7ef429cb67eb075
+test expr-28.985 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +943701829041427 E24 x 162fb2e38ee461_01111111111111111111111111111111111111111111111110& E129
+ convertToDouble +943701829041427E24
+} 0x48062fb2e38ee461
+test expr-28.986 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -101881054204734 E24 x -132964f2944b05_0111111111111111111111111111111111111111111111110& E126
+ convertToDouble -101881054204734E24
+} 0xc7d32964f2944b05
+test expr-28.987 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +828027839666967 E-27 x 1d2236349da3cd_011111111111111111111111111111111111111111111111110& E-41
+ convertToDouble +828027839666967E-27
+} 0x3d6d2236349da3cd
+test expr-28.988 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -280276135608777 E-27 x -13b901892fd0bf_0111111111111111111111111111111111111111111111110& E-42
+ convertToDouble -280276135608777E-27
+} 0xbd53b901892fd0bf
+test expr-28.989 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +212839188833879 E-21 x 1c91194dc2d40b_0111111111111111111111111111111111111111111111110& E-23
+ convertToDouble +212839188833879E-21
+} 0x3e8c91194dc2d40b
+test expr-28.990 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -113817196531426 E-25 x -190756ab1ed6b3_011111111111111111111111111111111111111111111110& E-37
+ convertToDouble -113817196531426E-25
+} 0xbda90756ab1ed6b3
+test expr-28.991 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +9711553197796883 E27 x 1bdeec25c0f03e_10000000000000000000000000000000000000000000000000001& E142
+ convertToDouble +9711553197796883E27
+} 0x48dbdeec25c0f03f
+test expr-28.992 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2739849386524269 E26 x -19295ade212370_1000000000000000000000000000000000000000000000000001& E137
+ convertToDouble -2739849386524269E26
+} 0xc889295ade212371
+test expr-28.993 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +5479698773048538 E26 x 19295ade212370_1000000000000000000000000000000000000000000000000001& E138
+ convertToDouble +5479698773048538E26
+} 0x4899295ade212371
+test expr-28.994 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6124568318523113 E-25 x 150b3a2e0aff14_1000000000000000000000000000000000000000000000000000001& E-31
+ convertToDouble +6124568318523113E-25
+} 0x3e050b3a2e0aff15
+test expr-28.995 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -1139777988171071 E-24 x -1394cbee428ea4_10000000000000000000000000000000000000000000000000001& E-30
+ convertToDouble -1139777988171071E-24
+} 0xbe1394cbee428ea5
+test expr-28.996 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +6322612303128019 E-27 x 1bcea0ec21e250_1000000000000000000000000000000000000000000000000000001& E-38
+ convertToDouble +6322612303128019E-27
+} 0x3d9bcea0ec21e251
+test expr-28.997 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2955864564844617 E-25 x -1450030e26c6dc_10000000000000000000000000000000000000000000000000001& E-32
+ convertToDouble -2955864564844617E-25
+} 0xbdf450030e26c6dd
+test expr-28.998 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -9994029144998961 E25 x -125b2b7fed4a61_0111111111111111111111111111111111111111111111111110& E136
+ convertToDouble -9994029144998961E25
+} 0xc8725b2b7fed4a61
+test expr-28.999 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -2971238324022087 E27 x -110dd7a301db67_0111111111111111111111111111111111111111111111111110& E141
+ convertToDouble -2971238324022087E27
+} 0xc8c10dd7a301db67
+test expr-28.1000 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -1656055679333934 E-27 x -1d2236349da3cd_011111111111111111111111111111111111111111111111110& E-40
+ convertToDouble -1656055679333934E-27
+} 0xbd7d2236349da3cd
+test expr-28.1001 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -1445488709150234 E-26 x -1fc960c59526c7_0111111111111111111111111111111111111111111111110& E-37
+ convertToDouble -1445488709150234E-26
+} 0xbdafc960c59526c7
+test expr-28.1002 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +55824717499885172 E27 x 1406b0cd17fd56_1000000000000000000000000000000000000000000000000000000001& E145
+ convertToDouble +55824717499885172E27
+} 0x490406b0cd17fd57
+test expr-28.1003 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -69780896874856465 E26 x -1406b0cd17fd56_1000000000000000000000000000000000000000000000000000000001& E142
+ convertToDouble -69780896874856465E26
+} 0xc8d406b0cd17fd57
+test expr-28.1004 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +84161538867545199 E25 x 13529217bdce6c_10000000000000000000000000000000000000000000000000000000001& E139
+ convertToDouble +84161538867545199E25
+} 0x48a3529217bdce6d
+test expr-28.1005 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -27912358749942586 E27 x -1406b0cd17fd56_1000000000000000000000000000000000000000000000000000000001& E144
+ convertToDouble -27912358749942586E27
+} 0xc8f406b0cd17fd57
+test expr-28.1006 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +24711112462926331 E-25 x 153a07f6040d22_100000000000000000000000000000000000000000000000000000001& E-29
+ convertToDouble +24711112462926331E-25
+} 0x3e253a07f6040d23
+test expr-28.1007 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -12645224606256038 E-27 x -1bcea0ec21e250_1000000000000000000000000000000000000000000000000000001& E-37
+ convertToDouble -12645224606256038E-27
+} 0xbdabcea0ec21e251
+test expr-28.1008 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -12249136637046226 E-25 x -150b3a2e0aff14_1000000000000000000000000000000000000000000000000000001& E-30
+ convertToDouble -12249136637046226E-25
+} 0xbe150b3a2e0aff15
+test expr-28.1009 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +74874448287465757 E27 x 1adc21d1d50b09_01111111111111111111111111111111111111111111111111111110& E145
+ convertToDouble +74874448287465757E27
+} 0x490adc21d1d50b09
+test expr-28.1010 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -35642836832753303 E24 x -1a2fac2b421f53_0111111111111111111111111111111111111111111111111111110& E134
+ convertToDouble -35642836832753303E24
+} 0xc85a2fac2b421f53
+test expr-28.1011 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -71285673665506606 E24 x -1a2fac2b421f53_0111111111111111111111111111111111111111111111111111110& E135
+ convertToDouble -71285673665506606E24
+} 0xc86a2fac2b421f53
+test expr-28.1012 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +43723334984997307 E-26 x 1e0be3f392c549_01111111111111111111111111111111111111111111111111111110& E-32
+ convertToDouble +43723334984997307E-26
+} 0x3dfe0be3f392c549
+test expr-28.1013 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN +10182419849537963 E-24 x 15ddd831ebbe53_011111111111111111111111111111111111111111111111111110& E-27
+ convertToDouble +10182419849537963E-24
+} 0x3e45ddd831ebbe53
+test expr-28.1014 {input floating-point conversion} {ieeeFloatingPoint} {
+ # Ad2b dieee UN -93501703572661982 E-26 x -10103f97ea6e13_0111111111111111111111111111111111111111111111111110& E-30
+ convertToDouble -93501703572661982E-26
+} 0xbe10103f97ea6e13
+
+test expr-29.1 {smallest representible number} {ieeeFloatingPoint} {
+ list [catch {convertToDouble 4.9406564584124654e-324} result] \
+ $result \
+ [catch {convertToDouble 2.4703282292062327e-324} result] \
+ $result \
+ [catch {convertToDouble 2.47032822920623e-324} result] \
+ $result
+} {0 0x0000000000000001 0 0x0000000000000001 0 0x0000000000000000}
+test expr-29.2 {smallest representible number} {ieeeFloatingPoint} {
+ list [catch {convertToDouble -4.9406564584124654e-324} result] \
+ $result \
+ [catch {convertToDouble -2.4703282292062327e-324} result] \
+ $result \
+ [catch {convertToDouble -2.47032822920623e-324} result] \
+ $result
+} {0 0x8000000000000001 0 0x8000000000000001 0 0x8000000000000000}
+test expr-29.3 {silent underflow on input conversion} {ieeeFloatingPoint} {
+ set v ?
+ list [scan 2.47032822920623e-324 %g v] $v
+} {1 0.0}
+test expr-29.4 {silent underflow on input conversion} {ieeeFloatingPoint} {
+ set v ?
+ list [scan -2.47032822920623e-324 %g v] $v
+} {1 -0.0}
+
+test expr-30.1 {largest representible number} {ieeeFloatingPoint} {
+ list [catch {convertToDouble 1.7976931348623155e+308} result] \
+ $result \
+ [catch {convertToDouble 1.7976931348623157e+308} result] \
+ $result \
+ [catch {convertToDouble 1.7976931348623159e+308} result] \
+ $result
+} {0 0x7feffffffffffffe 0 0x7fefffffffffffff 0 0x7ff0000000000000}
+test expr-30.2 {largest representible number} {ieeeFloatingPoint} {
+ list [catch {convertToDouble -1.7976931348623155e+308} result] \
+ $result \
+ [catch {convertToDouble -1.7976931348623157e+308} result] \
+ $result \
+ [catch {convertToDouble -1.7976931348623159e+308} result] \
+ $result
+} {0 0xffeffffffffffffe 0 0xffefffffffffffff 0 0xfff0000000000000}
+test expr-30.3 {silent overflow on input conversion} {ieeeFloatingPoint} {
+ set v ?
+ list [scan 1.7976931348623159e+308 %f v] $v
+} {1 Inf}
+test expr-30.4 {silent overflow on input conversion} {ieeeFloatingPoint} {
+ set v ?
+ list [scan -1.7976931348623159e+308 %f v] $v
+} {1 -Inf}
+
+# bool() tests (TIP #182)
+set i 0
+foreach s {yes true on} {
+ test expr-31.$i.0 {boolean conversion} {expr bool($s)} 1
+ test expr-31.$i.1 {boolean conversion} {expr bool(!$s)} 0
+ test expr-31.$i.2 {boolean conversion} {expr bool("$s")} 1
+ test expr-31.$i.3 {boolean conversion} {expr bool(!"$s")} 0
+ set j 1
+ while {$j < [string length $s]-1} {
+ test expr-31.$i.4.$j {boolean conversion} {
+ expr bool([string range $s 0 $j])
+ } 1
+ test expr-31.$i.5.$j {boolean conversion} {
+ expr bool("[string range $s 0 $j]")
+ } 1
+ incr j
+ }
+ incr i
+}
+test expr-31.0.4.0 {boolean conversion} {expr bool(y)} 1
+test expr-31.0.5.0 {boolean conversion} {expr bool("y")} 1
+test expr-31.1.4.0 {boolean conversion} {expr bool(t)} 1
+test expr-31.1.5.0 {boolean conversion} {expr bool("t")} 1
+test expr-31.2.4.0 {boolean conversion} -body {
+ expr bool(o)
+} -returnCodes error -match glob -result *
+test expr-31.2.5.0 {boolean conversion} -body {
+ expr bool("o")
+} -returnCodes error -match glob -result *
+foreach s {no false off} {
+ test expr-31.$i.0 {boolean conversion} {expr bool($s)} 0
+ test expr-31.$i.1 {boolean conversion} {expr bool(!$s)} 1
+ test expr-31.$i.2 {boolean conversion} {expr bool("$s")} 0
+ test expr-31.$i.3 {boolean conversion} {expr bool(!"$s")} 1
+ set j 1
+ while {$j < [string length $s]-1} {
+ test expr-31.$i.4.$j {boolean conversion} {
+ expr bool([string range $s 0 $j])
+ } 0
+ test expr-31.$i.5.$j {boolean conversion} {
+ expr bool("[string range $s 0 $j]")
+ } 0
+ incr j
+ }
+ incr i
+}
+test expr-31.3.4.0 {boolean conversion} {expr bool(n)} 0
+test expr-31.3.5.0 {boolean conversion} {expr bool("n")} 0
+test expr-31.4.4.0 {boolean conversion} {expr bool(f)} 0
+test expr-31.4.5.0 {boolean conversion} {expr bool("f")} 0
+test expr-31.6 {boolean conversion} {expr bool(-1 + 1)} 0
+test expr-31.7 {boolean conversion} {expr bool(0 + 1)} 1
+test expr-31.8 {boolean conversion} {expr bool(0.0)} 0
+test expr-31.9 {boolean conversion} {expr bool(0x0)} 0
+test expr-31.10 {boolean conversion} {expr bool(wide(0))} 0
+test expr-31.11 {boolean conversion} {expr bool(5.0)} 1
+test expr-31.12 {boolean conversion} {expr bool(5)} 1
+test expr-31.13 {boolean conversion} {expr bool(0x5)} 1
+test expr-31.14 {boolean conversion} {expr bool(wide(5))} 1
+test expr-31.15 {boolean conversion} -body {
+ expr bool("fred")
+} -returnCodes error -match glob -result *
+
+test expr-32.1 {expr mod basics} {
+ set mod_nums [list \
+ {-3 1} {-3 2} {-3 3} {-3 4} {-3 5} \
+ {-3 -1} {-3 -2} {-3 -3} {-3 -4} {-3 -5} \
+ {-2 1} {-2 2} {-2 3} {-2 4} {-2 5} \
+ {-2 -1} {-2 -2} {-2 -3} {-2 -4} {-2 -5} \
+ {-1 1} {-1 2} {-1 3} {-1 4} {-1 5} \
+ {-1 -1} {-1 -2} {-1 -3} {-1 -4} {-1 -5} \
+ {0 -100} {0 -1} {0 1} {0 100} \
+ {1 1} {1 2} {1 3} {1 4} {1 5} \
+ {1 -1} {1 -2} {1 -3} {1 -4} {1 -5} \
+ {2 1} {2 2} {2 3} {2 4} {2 5} \
+ {2 -1} {2 -2} {2 -3} {2 -4} {2 -5} \
+ {3 1} {3 2} {3 3} {3 4} {3 5} \
+ {3 -1} {3 -2} {3 -3} {3 -4} {3 -5} \
+ ]
+ set results [list]
+ foreach pair $mod_nums {
+ set dividend [lindex $pair 0]
+ set divisor [lindex $pair 1]
+ lappend results [expr {$dividend % $divisor}]
+ }
+ set results
+} [list \
+ 0 1 0 1 2 \
+ 0 -1 0 -3 -3 \
+ 0 0 1 2 3 \
+ 0 0 -2 -2 -2 \
+ 0 1 2 3 4 \
+ 0 -1 -1 -1 -1 \
+ 0 0 0 0 \
+ 0 1 1 1 1 \
+ 0 -1 -2 -3 -4 \
+ 0 0 2 2 2 \
+ 0 0 -1 -2 -3 \
+ 0 1 0 3 3 \
+ 0 -1 0 -1 -2 \
+ ]
+
+test expr-32.2 {expr div basics} {
+ set mod_nums [list \
+ {-3 1} {-3 2} {-3 3} {-3 4} {-3 5} \
+ {-3 -1} {-3 -2} {-3 -3} {-3 -4} {-3 -5} \
+ {-2 1} {-2 2} {-2 3} {-2 4} {-2 5} \
+ {-2 -1} {-2 -2} {-2 -3} {-2 -4} {-2 -5} \
+ {-1 1} {-1 2} {-1 3} {-1 4} {-1 5} \
+ {-1 -1} {-1 -2} {-1 -3} {-1 -4} {-1 -5} \
+ {0 -100} {0 -1} {0 1} {0 100} \
+ {1 1} {1 2} {1 3} {1 4} {1 5} \
+ {1 -1} {1 -2} {1 -3} {1 -4} {1 -5} \
+ {2 1} {2 2} {2 3} {2 4} {2 5} \
+ {2 -1} {2 -2} {2 -3} {2 -4} {2 -5} \
+ {3 1} {3 2} {3 3} {3 4} {3 5} \
+ {3 -1} {3 -2} {3 -3} {3 -4} {3 -5} \
+ ]
+ set results [list]
+ foreach pair $mod_nums {
+ set dividend [lindex $pair 0]
+ set divisor [lindex $pair 1]
+ lappend results [expr {$dividend / $divisor}]
+ }
+ set results
+} [list \
+ -3 -2 -1 -1 -1 \
+ 3 1 1 0 0 \
+ -2 -1 -1 -1 -1 \
+ 2 1 0 0 0 \
+ -1 -1 -1 -1 -1 \
+ 1 0 0 0 0 \
+ 0 0 0 0 \
+ 1 0 0 0 0 \
+ -1 -1 -1 -1 -1 \
+ 2 1 0 0 0 \
+ -2 -1 -1 -1 -1 \
+ 3 1 1 0 0 \
+ -3 -2 -1 -1 -1 \
+ ]
+
+test expr-32.3 {Bug 1585704} {
+ expr 1%(1<<63)
+} 1
+test expr-32.4 {Bug 1585704} {
+ expr -1%(1<<63)
+} [expr (1<<63)-1]
+test expr-32.5 {Bug 1585704} {
+ expr (1<<32)%(1<<63)
+} [expr 1<<32]
+test expr-32.6 {Bug 1585704} {
+ expr -(1<<32)%(1<<63)
+} [expr (1<<63)-(1<<32)]
+
+test expr-33.1 {parse largest long value} longIs32bit {
+ set max_long_str 2147483647
+ set max_long_hex "0x7FFFFFFF "
+
+ # Convert to integer (long, not wide) internal rep
+ set max_long 2147483647
+ string is integer $max_long
+
+ list \
+ [expr {" $max_long_str "}] \
+ [expr {$max_long_str + 0}] \
+ [expr {$max_long + 0}] \
+ [expr {2147483647 + 0}] \
+ [expr {$max_long == $max_long_hex}] \
+ [expr {int(2147483647 + 1) < 0}] \
+
+} {2147483647 2147483647 2147483647 2147483647 1 1}
+test expr-33.2 {parse smallest long value} longIs32bit {
+ set min_long_str -2147483648
+ set min_long_hex "-0x80000000 "
+
+ set min_long -2147483648
+ # This will convert to integer (not wide) internal rep
+ string is integer $min_long
+
+ # Note: If the final expression returns 0 then the
+ # expression literal is being promoted to a wide type
+ # when it should be parsed as a long type.
+ list \
+ [expr {" $min_long_str "}] \
+ [expr {$min_long_str + 0}] \
+ [expr {$min_long + 0}] \
+ [expr {-2147483648 + 0}] \
+ [expr {$min_long == $min_long_hex}] \
+ [expr {int(-2147483648 - 1) == 0x7FFFFFFF}] \
+
+} {-2147483648 -2147483648 -2147483648 -2147483648 1 1}
+test expr-33.3 {parse largest wide value} wideIs64bit {
+ set max_wide_str 9223372036854775807
+ set max_wide_hex "0x7FFFFFFFFFFFFFFF "
+
+ # Convert to wide integer
+ set max_wide 9223372036854775807
+ string is integer $max_wide
+
+ list \
+ [expr {" $max_wide_str "}] \
+ [expr {$max_wide_str + 0}] \
+ [expr {$max_wide + 0}] \
+ [expr {9223372036854775807 + 0}] \
+ [expr {$max_wide == $max_wide_hex}] \
+ [expr {wide(9223372036854775807 + 1) < 0}] \
+
+} {9223372036854775807 9223372036854775807 9223372036854775807 9223372036854775807 1 1}
+test expr-33.4 {parse smallest wide value} wideIs64bit {
+ set min_wide_str -9223372036854775808
+ set min_wide_hex "-0x8000000000000000 "
+
+ set min_wide -9223372036854775808
+ # Convert to wide integer
+ string is integer $min_wide
+
+ # Note: If the final expression returns 0 then the
+ # wide integer is not being parsed correctly with
+ # the leading - sign.
+ list \
+ [expr {" $min_wide_str "}] \
+ [expr {$min_wide_str + 0}] \
+ [expr {$min_wide + 0}] \
+ [expr {-9223372036854775808 + 0}] \
+ [expr {$min_wide == $min_wide_hex}] \
+ [expr {wide(-9223372036854775808 - 1) == 0x7FFFFFFFFFFFFFFF}] \
+
+} {-9223372036854775808 -9223372036854775808 -9223372036854775808 -9223372036854775808 1 1}
+
+set min -2147483648
+set max 2147483647
+
+test expr-34.1 {expr edge cases} {
+ expr {$min / $min}
+} {1}
+test expr-34.2 {expr edge cases} {
+ expr {$min % $min}
+} {0}
+test expr-34.3 {expr edge cases} {
+ expr {$min / ($min + 1)}
+} {1}
+test expr-34.4 {expr edge cases} {
+ expr {$min % ($min + 1)}
+} {-1}
+test expr-34.5 {expr edge cases} {
+ expr {$min / ($min + 2)}
+} {1}
+test expr-34.6 {expr edge cases} {
+ expr {$min % ($min + 2)}
+} {-2}
+test expr-34.7 {expr edge cases} {
+ expr {$min / ($min + 3)}
+} {1}
+test expr-34.8 {expr edge cases} {
+ expr {$min % ($min + 3)}
+} {-3}
+test expr-34.9 {expr edge cases} {
+ expr {$min / -3}
+} {715827882}
+test expr-34.10 {expr edge cases} {
+ expr {$min % -3}
+} {-2}
+test expr-34.11 {expr edge cases} {
+ expr {$min / -2}
+} {1073741824}
+test expr-34.12 {expr edge cases} {
+ expr {$min % -2}
+} {0}
+test expr-34.13 {expr edge cases} longIs32bit {
+ expr {int($min / -1)}
+} {-2147483648}
+test expr-34.14 {expr edge cases} {
+ expr {$min % -1}
+} {0}
+test expr-34.15 {expr edge cases} longIs32bit {
+ expr {int($min * -1)}
+} $min
+test expr-34.16 {expr edge cases} longIs32bit {
+ expr {int(-$min)}
+} $min
+test expr-34.17 {expr edge cases} {
+ expr {$min / 1}
+} $min
+test expr-34.18 {expr edge cases} {
+ expr {$min % 1}
+} {0}
+test expr-34.19 {expr edge cases} {
+ expr {$min / 2}
+} {-1073741824}
+test expr-34.20 {expr edge cases} {
+ expr {$min % 2}
+} {0}
+test expr-34.21 {expr edge cases} {
+ expr {$min / 3}
+} {-715827883}
+test expr-34.22 {expr edge cases} {
+ expr {$min % 3}
+} {1}
+test expr-34.23 {expr edge cases} {
+ expr {$min / ($max - 3)}
+} {-2}
+test expr-34.24 {expr edge cases} {
+ expr {$min % ($max - 3)}
+} {2147483640}
+test expr-34.25 {expr edge cases} {
+ expr {$min / ($max - 2)}
+} {-2}
+test expr-34.26 {expr edge cases} {
+ expr {$min % ($max - 2)}
+} {2147483642}
+test expr-34.27 {expr edge cases} {
+ expr {$min / ($max - 1)}
+} {-2}
+test expr-34.28 {expr edge cases} {
+ expr {$min % ($max - 1)}
+} {2147483644}
+test expr-34.29 {expr edge cases} {
+ expr {$min / $max}
+} {-2}
+test expr-34.30 {expr edge cases} {
+ expr {$min % $max}
+} {2147483646}
+test expr-34.31 {expr edge cases} {
+ expr {$max / $max}
+} {1}
+test expr-34.32 {expr edge cases} {
+ expr {$max % $max}
+} {0}
+test expr-34.33 {expr edge cases} {
+ expr {$max / ($max - 1)}
+} {1}
+test expr-34.34 {expr edge cases} {
+ expr {$max % ($max - 1)}
+} {1}
+test expr-34.35 {expr edge cases} {
+ expr {$max / ($max - 2)}
+} {1}
+test expr-34.36 {expr edge cases} {
+ expr {$max % ($max - 2)}
+} {2}
+test expr-34.37 {expr edge cases} {
+ expr {$max / ($max - 3)}
+} {1}
+test expr-34.38 {expr edge cases} {
+ expr {$max % ($max - 3)}
+} {3}
+test expr-34.39 {expr edge cases} {
+ expr {$max / 3}
+} {715827882}
+test expr-34.40 {expr edge cases} {
+ expr {$max % 3}
+} {1}
+test expr-34.41 {expr edge cases} {
+ expr {$max / 2}
+} {1073741823}
+test expr-34.42 {expr edge cases} {
+ expr {$max % 2}
+} {1}
+test expr-34.43 {expr edge cases} {
+ expr {$max / 1}
+} $max
+test expr-34.44 {expr edge cases} {
+ expr {$max % 1}
+} {0}
+test expr-34.45 {expr edge cases} {
+ expr {$max / -1}
+} "-$max"
+test expr-34.46 {expr edge cases} {
+ expr {$max % -1}
+} {0}
+test expr-34.47 {expr edge cases} {
+ expr {$max / -2}
+} {-1073741824}
+test expr-34.48 {expr edge cases} {
+ expr {$max % -2}
+} {-1}
+test expr-34.49 {expr edge cases} {
+ expr {$max / -3}
+} {-715827883}
+test expr-34.50 {expr edge cases} {
+ expr {$max % -3}
+} {-2}
+test expr-34.51 {expr edge cases} {
+ expr {$max / ($min + 3)}
+} {-2}
+test expr-34.52 {expr edge cases} {
+ expr {$max % ($min + 3)}
+} {-2147483643}
+test expr-34.53 {expr edge cases} {
+ expr {$max / ($min + 2)}
+} {-2}
+test expr-34.54 {expr edge cases} {
+ expr {$max % ($min + 2)}
+} {-2147483645}
+test expr-34.55 {expr edge cases} {
+ expr {$max / ($min + 1)}
+} {-1}
+test expr-34.56 {expr edge cases} {
+ expr {$max % ($min + 1)}
+} {0}
+test expr-34.57 {expr edge cases} {
+ expr {$max / $min}
+} {-1}
+test expr-34.58 {expr edge cases} {
+ expr {$max % $min}
+} {-1}
+test expr-34.59 {expr edge cases} {
+ expr {($min + 1) / ($max - 1)}
+} {-2}
+test expr-34.60 {expr edge cases} {
+ expr {($min + 1) % ($max - 1)}
+} {2147483645}
+test expr-34.61 {expr edge cases} {
+ expr {($max - 1) / ($min + 1)}
+} {-1}
+test expr-34.62 {expr edge cases} {
+ expr {($max - 1) % ($min + 1)}
+} {-1}
+test expr-34.63 {expr edge cases} {
+ expr {($max - 1) / $min}
+} {-1}
+test expr-34.64 {expr edge cases} {
+ expr {($max - 1) % $min}
+} {-2}
+test expr-34.65 {expr edge cases} {
+ expr {($max - 2) / $min}
+} {-1}
+test expr-34.66 {expr edge cases} {
+ expr {($max - 2) % $min}
+} {-3}
+test expr-34.67 {expr edge cases} {
+ expr {($max - 3) / $min}
+} {-1}
+test expr-34.68 {expr edge cases} {
+ expr {($max - 3) % $min}
+} {-4}
+test expr-34.69 {expr edge cases} {
+ expr {-3 / $min}
+} {0}
+test expr-34.70 {expr edge cases} {
+ expr {-3 % $min}
+} {-3}
+test expr-34.71 {expr edge cases} {
+ expr {-2 / $min}
+} {0}
+test expr-34.72 {expr edge cases} {
+ expr {-2 % $min}
+} {-2}
+test expr-34.73 {expr edge cases} {
+ expr {-1 / $min}
+} {0}
+test expr-34.74 {expr edge cases} {
+ expr {-1 % $min}
+} {-1}
+test expr-34.75 {expr edge cases} {
+ expr {0 / $min}
+} {0}
+test expr-34.76 {expr edge cases} {
+ expr {0 % $min}
+} {0}
+test expr-34.77 {expr edge cases} {
+ expr {0 / ($min + 1)}
+} {0}
+test expr-34.78 {expr edge cases} {
+ expr {0 % ($min + 1)}
+} {0}
+test expr-34.79 {expr edge cases} {
+ expr {1 / $min}
+} {-1}
+test expr-34.80 {expr edge cases} {
+ expr {1 % $min}
+} {-2147483647}
+test expr-34.81 {expr edge cases} {
+ expr {1 / ($min + 1)}
+} {-1}
+test expr-34.82 {expr edge cases} {
+ expr {1 % ($min + 1)}
+} {-2147483646}
+test expr-34.83 {expr edge cases} {
+ expr {2 / $min}
+} {-1}
+test expr-34.84 {expr edge cases} {
+ expr {2 % $min}
+} {-2147483646}
+test expr-34.85 {expr edge cases} {
+ expr {2 / ($min + 1)}
+} {-1}
+test expr-34.86 {expr edge cases} {
+ expr {2 % ($min + 1)}
+} {-2147483645}
+test expr-34.87 {expr edge cases} {
+ expr {3 / $min}
+} {-1}
+test expr-34.88 {expr edge cases} {
+ expr {3 % $min}
+} {-2147483645}
+test expr-34.89 {expr edge cases} {
+ expr {3 / ($min + 1)}
+} {-1}
+test expr-34.90 {expr edge cases} {
+ expr {3 % ($min + 1)}
+} {-2147483644}
+
+# Euclidean property:
+# quotient * divisor + remainder = dividend
+
+test expr-35.1 {expr edge cases} {
+ set dividend $max
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($divisor * $q) + $r}]
+} {1073741823 * 2 + 1 = 2147483647}
+test expr-35.2 {expr edge cases} {
+ set dividend [expr {$max - 1}]
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1073741823 * 2 + 0 = 2147483646}
+test expr-35.3 {expr edge cases} {
+ set dividend [expr {$max - 2}]
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1073741822 * 2 + 1 = 2147483645}
+test expr-35.4 {expr edge cases} {
+ set dividend $max
+ set divisor 3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {715827882 * 3 + 1 = 2147483647}
+test expr-35.5 {expr edge cases} {
+ set dividend [expr {$max - 1}]
+ set divisor 3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {715827882 * 3 + 0 = 2147483646}
+test expr-35.6 {expr edge cases} {
+ set dividend [expr {$max - 2}]
+ set divisor 3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {715827881 * 3 + 2 = 2147483645}
+test expr-35.7 {expr edge cases} {
+ set dividend $min
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-1073741824 * 2 + 0 = -2147483648}
+test expr-35.8 {expr edge cases} {
+ set dividend [expr {$min + 1}]
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-1073741824 * 2 + 1 = -2147483647}
+test expr-35.9 {expr edge cases} {
+ set dividend [expr {$min + 2}]
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-1073741823 * 2 + 0 = -2147483646}
+test expr-35.10 {expr edge cases} {
+ # Two things could happen here. The multiplication
+ # could overflow a 32 bit type, so that when
+ # 1 is added it overflows again back to min.
+ # The multiplication could also use a wide type
+ # to hold ($min - 1) until 1 is added and
+ # the number becomes $min again.
+ set dividend $min
+ set divisor 3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-715827883 * 3 + 1 = -2147483648}
+test expr-35.11 {expr edge cases} {
+ set dividend $min
+ set divisor -3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {715827882 * -3 + -2 = -2147483648}
+test expr-35.12 {expr edge cases} {
+ set dividend $min
+ set divisor $min
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -2147483648 + 0 = -2147483648}
+test expr-35.13 {expr edge cases} {
+ set dividend $min
+ set divisor [expr {$min + 1}]
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -2147483647 + -1 = -2147483648}
+test expr-35.14 {expr edge cases} {
+ set dividend $min
+ set divisor [expr {$min + 2}]
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -2147483646 + -2 = -2147483648}
+
+# 64bit wide integer checks
+
+set min -9223372036854775808
+set max 9223372036854775807
+
+test expr-36.1 {expr edge cases} {wideIs64bit} {
+ expr {$min / $min}
+} {1}
+test expr-36.2 {expr edge cases} {wideIs64bit} {
+ expr {$min % $min}
+} {0}
+test expr-36.3 {expr edge cases} {wideIs64bit} {
+ expr {$min / ($min + 1)}
+} {1}
+test expr-36.4 {expr edge cases} {wideIs64bit} {
+ expr {$min % ($min + 1)}
+} {-1}
+test expr-36.5 {expr edge cases} {wideIs64bit} {
+ expr {$min / ($min + 2)}
+} {1}
+test expr-36.6 {expr edge cases} {wideIs64bit} {
+ expr {$min % ($min + 2)}
+} {-2}
+test expr-36.7 {expr edge cases} {wideIs64bit} {
+ expr {$min / ($min + 3)}
+} {1}
+test expr-36.8 {expr edge cases} {wideIs64bit} {
+ expr {$min % ($min + 3)}
+} {-3}
+test expr-36.9 {expr edge cases} {wideIs64bit} {
+ expr {$min / -3}
+} {3074457345618258602}
+test expr-36.10 {expr edge cases} {wideIs64bit} {
+ expr {$min % -3}
+} {-2}
+test expr-36.11 {expr edge cases} {wideIs64bit} {
+ expr {$min / -2}
+} {4611686018427387904}
+test expr-36.12 {expr edge cases} {wideIs64bit} {
+ expr {$min % -2}
+} {0}
+test expr-36.13 {expr edge cases} wideIs64bit {
+ expr {wide($min / -1)}
+} $min
+test expr-36.14 {expr edge cases} {wideIs64bit} {
+ expr {$min % -1}
+} {0}
+test expr-36.15 {expr edge cases} wideIs64bit {
+ expr {wide($min * -1)}
+} $min
+test expr-36.16 {expr edge cases} wideIs64bit {
+ expr {wide(-$min)}
+} $min
+test expr-36.17 {expr edge cases} {wideIs64bit} {
+ expr {$min / 1}
+} $min
+test expr-36.18 {expr edge cases} {wideIs64bit} {
+ expr {$min % 1}
+} {0}
+test expr-36.19 {expr edge cases} {wideIs64bit} {
+ expr {$min / 2}
+} {-4611686018427387904}
+test expr-36.20 {expr edge cases} {wideIs64bit} {
+ expr {$min % 2}
+} {0}
+test expr-36.21 {expr edge cases} {wideIs64bit} {
+ expr {$min / 3}
+} {-3074457345618258603}
+test expr-36.22 {expr edge cases} {wideIs64bit} {
+ expr {$min % 3}
+} {1}
+test expr-36.23 {expr edge cases} {wideIs64bit} {
+ expr {$min / ($max - 3)}
+} {-2}
+test expr-36.24 {expr edge cases} {wideIs64bit} {
+ expr {$min % ($max - 3)}
+} {9223372036854775800}
+test expr-36.25 {expr edge cases} {wideIs64bit} {
+ expr {$min / ($max - 2)}
+} {-2}
+test expr-36.26 {expr edge cases} {wideIs64bit} {
+ expr {$min % ($max - 2)}
+} {9223372036854775802}
+test expr-36.27 {expr edge cases} {wideIs64bit} {
+ expr {$min / ($max - 1)}
+} {-2}
+test expr-36.28 {expr edge cases} {wideIs64bit} {
+ expr {$min % ($max - 1)}
+} {9223372036854775804}
+test expr-36.29 {expr edge cases} {wideIs64bit} {
+ expr {$min / $max}
+} {-2}
+test expr-36.30 {expr edge cases} {wideIs64bit} {
+ expr {$min % $max}
+} {9223372036854775806}
+test expr-36.31 {expr edge cases} {wideIs64bit} {
+ expr {$max / $max}
+} {1}
+test expr-36.32 {expr edge cases} {wideIs64bit} {
+ expr {$max % $max}
+} {0}
+test expr-36.33 {expr edge cases} {wideIs64bit} {
+ expr {$max / ($max - 1)}
+} {1}
+test expr-36.34 {expr edge cases} {wideIs64bit} {
+ expr {$max % ($max - 1)}
+} {1}
+test expr-36.35 {expr edge cases} {wideIs64bit} {
+ expr {$max / ($max - 2)}
+} {1}
+test expr-36.36 {expr edge cases} {wideIs64bit} {
+ expr {$max % ($max - 2)}
+} {2}
+test expr-36.37 {expr edge cases} {wideIs64bit} {
+ expr {$max / ($max - 3)}
+} {1}
+test expr-36.38 {expr edge cases} {wideIs64bit} {
+ expr {$max % ($max - 3)}
+} {3}
+test expr-36.39 {expr edge cases} {wideIs64bit} {
+ expr {$max / 3}
+} {3074457345618258602}
+test expr-36.40 {expr edge cases} {wideIs64bit} {
+ expr {$max % 3}
+} {1}
+test expr-36.41 {expr edge cases} {wideIs64bit} {
+ expr {$max / 2}
+} {4611686018427387903}
+test expr-36.42 {expr edge cases} {wideIs64bit} {
+ expr {$max % 2}
+} {1}
+test expr-36.43 {expr edge cases} {wideIs64bit} {
+ expr {$max / 1}
+} $max
+test expr-36.44 {expr edge cases} {wideIs64bit} {
+ expr {$max % 1}
+} {0}
+test expr-36.45 {expr edge cases} {wideIs64bit} {
+ expr {$max / -1}
+} "-$max"
+test expr-36.46 {expr edge cases} {wideIs64bit} {
+ expr {$max % -1}
+} {0}
+test expr-36.47 {expr edge cases} {wideIs64bit} {
+ expr {$max / -2}
+} {-4611686018427387904}
+test expr-36.48 {expr edge cases} {wideIs64bit} {
+ expr {$max % -2}
+} {-1}
+test expr-36.49 {expr edge cases} {wideIs64bit} {
+ expr {$max / -3}
+} {-3074457345618258603}
+test expr-36.50 {expr edge cases} {wideIs64bit} {
+ expr {$max % -3}
+} {-2}
+test expr-36.51 {expr edge cases} {wideIs64bit} {
+ expr {$max / ($min + 3)}
+} {-2}
+test expr-36.52 {expr edge cases} {wideIs64bit} {
+ expr {$max % ($min + 3)}
+} {-9223372036854775803}
+test expr-36.53 {expr edge cases} {wideIs64bit} {
+ expr {$max / ($min + 2)}
+} {-2}
+test expr-36.54 {expr edge cases} {wideIs64bit} {
+ expr {$max % ($min + 2)}
+} {-9223372036854775805}
+test expr-36.55 {expr edge cases} {wideIs64bit} {
+ expr {$max / ($min + 1)}
+} {-1}
+test expr-36.56 {expr edge cases} {wideIs64bit} {
+ expr {$max % ($min + 1)}
+} {0}
+test expr-36.57 {expr edge cases} {wideIs64bit} {
+ expr {$max / $min}
+} {-1}
+test expr-36.58 {expr edge cases} {wideIs64bit} {
+ expr {$max % $min}
+} {-1}
+test expr-36.59 {expr edge cases} {wideIs64bit} {
+ expr {($min + 1) / ($max - 1)}
+} {-2}
+test expr-36.60 {expr edge cases} {wideIs64bit} {
+ expr {($min + 1) % ($max - 1)}
+} {9223372036854775805}
+test expr-36.61 {expr edge cases} {wideIs64bit} {
+ expr {($max - 1) / ($min + 1)}
+} {-1}
+test expr-36.62 {expr edge cases} {wideIs64bit} {
+ expr {($max - 1) % ($min + 1)}
+} {-1}
+test expr-36.63 {expr edge cases} {wideIs64bit} {
+ expr {($max - 1) / $min}
+} {-1}
+test expr-36.64 {expr edge cases} {wideIs64bit} {
+ expr {($max - 1) % $min}
+} {-2}
+test expr-36.65 {expr edge cases} {wideIs64bit} {
+ expr {($max - 2) / $min}
+} {-1}
+test expr-36.66 {expr edge cases} {wideIs64bit} {
+ expr {($max - 2) % $min}
+} {-3}
+test expr-36.67 {expr edge cases} {wideIs64bit} {
+ expr {($max - 3) / $min}
+} {-1}
+test expr-36.68 {expr edge cases} {wideIs64bit} {
+ expr {($max - 3) % $min}
+} {-4}
+test expr-36.69 {expr edge cases} {wideIs64bit} {
+ expr {-3 / $min}
+} {0}
+test expr-36.70 {expr edge cases} {wideIs64bit} {
+ expr {-3 % $min}
+} {-3}
+test expr-36.71 {expr edge cases} {wideIs64bit} {
+ expr {-2 / $min}
+} {0}
+test expr-36.72 {expr edge cases} {wideIs64bit} {
+ expr {-2 % $min}
+} {-2}
+test expr-36.73 {expr edge cases} {wideIs64bit} {
+ expr {-1 / $min}
+} {0}
+test expr-36.74 {expr edge cases} {wideIs64bit} {
+ expr {-1 % $min}
+} {-1}
+test expr-36.75 {expr edge cases} {wideIs64bit} {
+ expr {0 / $min}
+} {0}
+test expr-36.76 {expr edge cases} {wideIs64bit} {
+ expr {0 % $min}
+} {0}
+test expr-36.77 {expr edge cases} {wideIs64bit} {
+ expr {0 / ($min + 1)}
+} {0}
+test expr-36.78 {expr edge cases} {wideIs64bit} {
+ expr {0 % ($min + 1)}
+} {0}
+test expr-36.79 {expr edge cases} {wideIs64bit} {
+ expr {1 / $min}
+} {-1}
+test expr-36.80 {expr edge cases} {wideIs64bit} {
+ expr {1 % $min}
+} {-9223372036854775807}
+test expr-36.81 {expr edge cases} {wideIs64bit} {
+ expr {1 / ($min + 1)}
+} {-1}
+test expr-36.82 {expr edge cases} {wideIs64bit} {
+ expr {1 % ($min + 1)}
+} {-9223372036854775806}
+test expr-36.83 {expr edge cases} {wideIs64bit} {
+ expr {2 / $min}
+} {-1}
+test expr-36.84 {expr edge cases} {wideIs64bit} {
+ expr {2 % $min}
+} {-9223372036854775806}
+test expr-36.85 {expr edge cases} {wideIs64bit} {
+ expr {2 / ($min + 1)}
+} {-1}
+test expr-36.86 {expr edge cases} {wideIs64bit} {
+ expr {2 % ($min + 1)}
+} {-9223372036854775805}
+test expr-36.87 {expr edge cases} {wideIs64bit} {
+ expr {3 / $min}
+} {-1}
+test expr-36.88 {expr edge cases} {wideIs64bit} {
+ expr {3 % $min}
+} {-9223372036854775805}
+test expr-36.89 {expr edge cases} {wideIs64bit} {
+ expr {3 / ($min + 1)}
+} {-1}
+test expr-36.90 {expr edge cases} {wideIs64bit} {
+ expr {3 % ($min + 1)}
+} {-9223372036854775804}
+
+test expr-37.1 {expr edge cases} {wideIs64bit} {
+ set dividend $max
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($divisor * $q) + $r}]
+} {4611686018427387903 * 2 + 1 = 9223372036854775807}
+test expr-37.2 {expr edge cases} {wideIs64bit} {
+ set dividend [expr {$max - 1}]
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {4611686018427387903 * 2 + 0 = 9223372036854775806}
+test expr-37.3 {expr edge cases} {wideIs64bit} {
+ set dividend [expr {$max - 2}]
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {4611686018427387902 * 2 + 1 = 9223372036854775805}
+test expr-37.4 {expr edge cases} {wideIs64bit} {
+ set dividend $max
+ set divisor 3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {3074457345618258602 * 3 + 1 = 9223372036854775807}
+test expr-37.5 {expr edge cases} {wideIs64bit} {
+ set dividend [expr {$max - 1}]
+ set divisor 3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {3074457345618258602 * 3 + 0 = 9223372036854775806}
+test expr-37.6 {expr edge cases} {wideIs64bit} {
+ set dividend [expr {$max - 2}]
+ set divisor 3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {3074457345618258601 * 3 + 2 = 9223372036854775805}
+test expr-37.7 {expr edge cases} {wideIs64bit} {
+ set dividend $min
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-4611686018427387904 * 2 + 0 = -9223372036854775808}
+test expr-37.8 {expr edge cases} {wideIs64bit} {
+ set dividend [expr {$min + 1}]
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-4611686018427387904 * 2 + 1 = -9223372036854775807}
+test expr-37.9 {expr edge cases} {wideIs64bit} {
+ set dividend [expr {$min + 2}]
+ set divisor 2
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-4611686018427387903 * 2 + 0 = -9223372036854775806}
+test expr-37.10 {expr edge cases} {wideIs64bit} {
+ # Multiplication overflows 64 bit type here,
+ # so when the 1 is added it overflows
+ # again and we end up back at min.
+ set dividend $min
+ set divisor 3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-3074457345618258603 * 3 + 1 = -9223372036854775808}
+test expr-37.11 {expr edge cases} {wideIs64bit} {
+ set dividend $min
+ set divisor -3
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {3074457345618258602 * -3 + -2 = -9223372036854775808}
+test expr-37.12 {expr edge cases} {wideIs64bit} {
+ set dividend $min
+ set divisor $min
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -9223372036854775808 + 0 = -9223372036854775808}
+test expr-37.13 {expr edge cases} {wideIs64bit} {
+ set dividend $min
+ set divisor [expr {$min + 1}]
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -9223372036854775807 + -1 = -9223372036854775808}
+test expr-37.14 {expr edge cases} {wideIs64bit} {
+ set dividend $min
+ set divisor [expr {$min + 2}]
+ set q [expr {$dividend / $divisor}]
+ set r [expr {$dividend % $divisor}]
+ list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -9223372036854775806 + -2 = -9223372036854775808}
+
+test expr-38.1 {abs of smallest 32-bit integer [Bug 1241572]} {wideIs64bit} {
+ expr {abs(-2147483648)}
+} 2147483648
+test expr-38.2 {abs and -0 [Bug 1893815]} {
+ expr {abs(-0)}
+} 0
+test expr-38.3 {abs and -0 [Bug 1893815]} {
+ expr {abs(-0.0)}
+} 0.0
+test expr-38.4 {abs and -0 [Bug 1893815]} {
+ expr {abs(-1e-324)}
+} 0.0
+test expr-38.5 {abs and -0 [Bug 1893815]} {
+ ::tcl::mathfunc::abs -0
+} 0
+test expr-38.6 {abs and -0 [Bug 1893815]} {
+ ::tcl::mathfunc::abs -0.0
+} 0.0
+test expr-38.7 {abs and -0 [Bug 1893815]} {
+ ::tcl::mathfunc::abs -1e-324
+} 0.0
+test expr-38.8 {abs and 0.0 [Bug 2954959]} {
+ ::tcl::mathfunc::abs 0.0
+} 0.0
+test expr-38.9 {abs and 0.0 [Bug 2954959]} {
+ expr {abs(0.0)}
+} 0.0
+test expr-38.10 {abs and -0x0 [Bug 2954959]} {
+ expr {abs(-0x0)}
+} 0
+test expr-38.11 {abs and 0x0 [Bug 2954959]} {
+ ::tcl::mathfunc::abs { 0x0}
+} { 0x0}
+test expr-38.12 {abs and -0x0 [Bug 2954959]} {
+ ::tcl::mathfunc::abs { -0x0}
+} 0
+test expr-38.13 {abs and 0.0 [Bug 2954959]} {
+ ::tcl::mathfunc::abs 1e-324
+} 1e-324
+
+testConstraint testexprlongobj [llength [info commands testexprlongobj]]
+testConstraint testexprdoubleobj [llength [info commands testexprdoubleobj]]
+
+test expr-39.1 {Check that Tcl_ExprLongObj doesn't modify interpreter result if no error} testexprlongobj {
+ testexprlongobj 4+1
+} {This is a result: 5}
+#Check for [Bug 1109484]
+test expr-39.2 {Tcl_ExprLongObj handles wide ints gracefully} testexprlongobj {
+ testexprlongobj wide(1)+2
+} {This is a result: 3}
+
+test expr-39.3 {Tcl_ExprLongObj on the empty string} \
+ -constraints {testexprlongobj}\
+ -body {testexprlongobj ""} \
+ -match glob \
+ -returnCodes error -result *
+test expr-39.4 {Tcl_ExprLongObj coerces doubles} testexprlongobj {
+ testexprlongobj 3+.14159
+} {This is a result: 3}
+test expr-39.5 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+ testexprlongobj 0x80000000
+} {This is a result: -2147483648}
+test expr-39.6 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+ testexprlongobj 0xffffffff
+} {This is a result: -1}
+test expr-39.7 {Tcl_ExprLongObj handles overflows} \
+ -constraints {testexprlongobj longIs32bit} \
+ -match glob \
+ -body {
+ list [catch {testexprlongobj 0x100000000} result] $result
+ } \
+ -result {1 {integer value too large to represent*}}
+test expr-39.8 {Tcl_ExprLongObj handles overflows} testexprlongobj {
+ testexprlongobj -0x80000000
+} {This is a result: -2147483648}
+test expr-39.9 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+ testexprlongobj -0xffffffff
+} {This is a result: 1}
+test expr-39.10 {Tcl_ExprLongObj handles overflows} \
+ -constraints {testexprlongobj longIs32bit} \
+ -match glob \
+ -body {
+ list [catch {testexprlongobj -0x100000000} result] $result
+ } \
+ -result {1 {integer value too large to represent*}}
+test expr-39.11 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+ testexprlongobj 2147483648.
+} {This is a result: -2147483648}
+test expr-39.12 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+ testexprlongobj 4294967295.
+} {This is a result: -1}
+test expr-39.13 {Tcl_ExprLongObj handles overflows} \
+ -constraints {testexprlongobj longIs32bit} \
+ -match glob \
+ -body {
+ list [catch {testexprlongobj 4294967296.} result] $result
+ } \
+ -result {1 {integer value too large to represent*}}
+test expr-39.14 {Tcl_ExprLongObj handles overflows} testexprlongobj {
+ testexprlongobj -2147483648.
+} {This is a result: -2147483648}
+test expr-39.15 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+ testexprlongobj -4294967295.
+} {This is a result: 1}
+test expr-39.16 {Tcl_ExprLongObj handles overflows} \
+ -constraints {testexprlongobj longIs32bit} \
+ -match glob \
+ -body {
+ list [catch {testexprlongobj 4294967296.} result] $result
+ } \
+ -result {1 {integer value too large to represent*}}
+
+test expr-39.17 {Check that Tcl_ExprDoubleObj doesn't modify interpreter result if no error} testexprdoubleobj {
+ testexprdoubleobj 4.+1.
+} {This is a result: 5.0}
+#Check for [Bug 1109484]
+test expr-39.18 {Tcl_ExprDoubleObj on the empty string} \
+ -constraints {testexprdoubleobj} \
+ -match glob \
+ -body {testexprdoubleobj ""} \
+ -returnCodes error -result *
+test expr-39.19 {Tcl_ExprDoubleObj coerces wides} testexprdoubleobj {
+ testexprdoubleobj 1[string repeat 0 17]
+} {This is a result: 1e+17}
+test expr-39.20 {Tcl_ExprDoubleObj coerces bignums} testexprdoubleobj {
+ testexprdoubleobj 1[string repeat 0 38]
+} {This is a result: 1e+38}
+test expr-39.21 {Tcl_ExprDoubleObj handles overflows} \
+ testexprdoubleobj&&ieeeFloatingPoint {
+ testexprdoubleobj 17976931348623157[string repeat 0 292].
+ } {This is a result: 1.7976931348623157e+308}
+test expr-39.22 {Tcl_ExprDoubleObj handles overflows that look like int} \
+ testexprdoubleobj&&ieeeFloatingPoint {
+ testexprdoubleobj 17976931348623157[string repeat 0 292]
+ } {This is a result: 1.7976931348623157e+308}
+test expr-39.23 {Tcl_ExprDoubleObj handles overflows} \
+ testexprdoubleobj&&ieeeFloatingPoint {
+ testexprdoubleobj 17976931348623165[string repeat 0 292].
+ } {This is a result: Inf}
+test expr-39.24 {Tcl_ExprDoubleObj handles overflows that look like int} \
+ testexprdoubleobj&&ieeeFloatingPoint {
+ testexprdoubleobj 17976931348623165[string repeat 0 292]
+ } {This is a result: Inf}
+test expr-39.25 {Tcl_ExprDoubleObj and NaN} \
+ {testexprdoubleobj ieeeFloatingPoint} {
+ list [catch {testexprdoubleobj 0.0/0.0} result] $result
+ } {1 {domain error: argument not in valid range}}
+
+test expr-40.1 {large octal shift} {
+ expr 0o100000000000000000000000000000000
+} [expr 0x1000000000000000000000000]
+test expr-40.2 {large octal shift} {
+ expr 0o100000000000000000000000000000001
+} [expr 0x1000000000000000000000001]
+
+test expr-41.1 {exponent overflow} {
+ expr 1.0e2147483630
+} Inf
+test expr-41.2 {exponent underflow} {
+ expr 1.0e-2147483630
+} 0.0
+
+test expr-42.1 {denormals} ieeeFloatingPoint {
+ expr 7e-324
+} 5e-324
+
+# TIP 114
+
+test expr-43.1 {0b notation} {
+ expr 0b0
+} 0
+test expr-43.2 {0b notation} {
+ expr 0b1
+} 1
+test expr-43.3 {0b notation} {
+ expr 0b10
+} 2
+test expr-43.4 {0b notation} {
+ expr 0b11
+} 3
+test expr-43.5 {0b notation} {
+ expr 0b100
+} 4
+test expr-43.6 {0b notation} {
+ expr 0b101
+} 5
+test expr-43.7 {0b notation} {
+ expr 0b1000
+} 8
+test expr-43.8 {0b notation} {
+ expr 0b1001
+} 9
+test expr-43.9 {0b notation} {
+ expr 0b1[string repeat 0 31]
+} 2147483648
+test expr-43.10 {0b notation} {
+ expr 0b1[string repeat 0 30]1
+} 2147483649
+test expr-43.11 {0b notation} {
+ expr 0b[string repeat 1 64]
+} 18446744073709551615
+test expr-43.12 {0b notation} {
+ expr 0b1[string repeat 0 64]
+} 18446744073709551616
+test expr-43.13 {0b notation} {
+ expr 0b1[string repeat 0 63]1
+} 18446744073709551617
+
+test expr-44.1 {0o notation} {
+ expr 0o0
+} 0
+test expr-44.2 {0o notation} {
+ expr 0o1
+} 1
+test expr-44.3 {0o notation} {
+ expr 0o7
+} 7
+test expr-44.4 {0o notation} {
+ expr 0o10
+} 8
+test expr-44.5 {0o notation} {
+ expr 0o11
+} 9
+test expr-44.6 {0o notation} {
+ expr 0o100
+} 64
+test expr-44.7 {0o notation} {
+ expr 0o101
+} 65
+test expr-44.8 {0o notation} {
+ expr 0o1000
+} 512
+test expr-44.9 {0o notation} {
+ expr 0o1001
+} 513
+test expr-44.10 {0o notation} {
+ expr 0o1[string repeat 7 21]
+} 18446744073709551615
+test expr-44.11 {0o notation} {
+ expr 0o2[string repeat 0 21]
+} 18446744073709551616
+test expr-44.12 {0o notation} {
+ expr 0o2[string repeat 0 20]1
+} 18446744073709551617
+
+# TIP 237 again
+
+test expr-45.1 {entier} {
+ expr entier(0)
+} 0
+test expr-45.2 {entier} {
+ expr entier(0.5)
+} 0
+test expr-45.3 {entier} {
+ expr entier(1.0)
+} 1
+test expr-45.4 {entier} {
+ expr entier(1.5)
+} 1
+test expr-45.5 {entier} {
+ expr entier(2.0)
+} 2
+test expr-45.6 {entier} {
+ expr entier(1e+22)
+} 10000000000000000000000
+test expr-45.7 {entier} {
+ list [catch {expr entier(Inf)} result] $result
+} {1 {integer value too large to represent}}
+test expr-45.8 {entier} ieeeFloatingPoint {
+ list [catch {expr {entier($ieeeValues(NaN))}} result] $result
+} {1 {floating point value is Not a Number}}
+test expr-45.9 {entier} ieeeFloatingPoint {
+ list [catch {expr {entier($ieeeValues(-NaN))}} result] $result
+} {1 {floating point value is Not a Number}}
+
+test expr-46.1 {round() rounds to +-infinity} {
+ expr round(0.5)
+} 1
+test expr-46.2 {round() rounds to +-infinity} {
+ expr round(1.5)
+} 2
+test expr-46.3 {round() rounds to +-infinity} {
+ expr round(-0.5)
+} -1
+test expr-46.4 {round() rounds to +-infinity} {
+ expr round(-1.5)
+} -2
+test expr-46.5 {round() overflow} {
+ expr round(9.2233720368547758e+018)
+} 9223372036854775808
+test expr-46.6 {round() overflow} {
+ expr round(-9.2233720368547758e+018)
+} -9223372036854775808
+test expr-46.7 {round() bad value} -body {
+ set x trash
+ expr {round($x)}
+} -returnCodes error -match glob -result *
+test expr-46.8 {round() already an integer} {
+ set x 123456789012
+ incr x
+ expr round($x)
+} 123456789013
+test expr-46.9 {round() boundary case - 1/2 - 1 ulp} {
+ set x 0.25
+ set bit 0.125
+ while 1 {
+ set newx [expr {$x + $bit}]
+ if { $newx == $x || $newx == 0.5 } break
+ set x $newx
+ set bit [expr { $bit / 2.0 }]
+ }
+ expr {round($x)}
+} 0
+test expr-46.10 {round() boundary case - 1/2 + 1 ulp} {
+ set x 0.75
+ set bit 0.125
+ while 1 {
+ set newx [expr {$x - $bit}]
+ if { $newx == $x || $newx == 0.5 } break
+ set x $newx
+ set bit [expr { $bit / 2.0 }]
+ }
+ expr {round($x)}
+} 1
+test expr-46.11 {round() boundary case - -1/2 - 1 ulp} {
+ set x -0.75
+ set bit 0.125
+ while 1 {
+ set newx [expr {$x + $bit}]
+ if { $newx == $x || $newx == -0.5 } break
+ set x $newx
+ set bit [expr { $bit / 2.0 }]
+ }
+ expr {round($x)}
+} -1
+test expr-46.12 {round() boundary case - -1/2 + 1 ulp} {
+ set x -0.25
+ set bit 0.125
+ while 1 {
+ set newx [expr {$x - $bit}]
+ if { $newx == $x || $newx == -0.5 } break
+ set x $newx
+ set bit [expr { $bit / 2.0 }]
+ }
+ expr {round($x)}
+} 0
+test expr-46.13 {round() boundary case - round down} {
+ expr {round(2147483647 - 0.51)}
+} 2147483646
+
+test expr-46.14 {round() boundary case - round up} {
+ expr {round(2147483647 - 0.50)}
+} 2147483647
+
+test expr-46.15 {round() boundary case - round up to wide} {
+ expr {round(2147483647 + 0.50)}
+} [expr {wide(2147483647) + 1}]
+
+test expr-46.16 {round() boundary case - round up} {
+ expr {round(-2147483648 + 0.51)}
+} -2147483647
+
+test expr-46.17 {round() boundary case - round down} {
+ expr {round(-2147483648 + 0.50)}
+} -2147483648
+test expr-46.18 {round() boundary case - round down to wide} {
+ expr {round(-2147483648 - 0.50)}
+} [expr {wide(-2147483648) - 1}]
+
+test expr-46.19 {round() handling of long/bignum boundary} {
+ expr {round(double(0x7fffffffffffffff))}
+} 9223372036854775808
+
+test expr-47.1 {isqrt() - arg count} {
+ list [catch {expr {isqrt(1,2)}} result] $result
+} {1 {too many arguments for math function "isqrt"}}
+
+test expr-47.2 {isqrt() - non-number} {
+ list [catch {expr {isqrt({rubbish})}} result] $result
+} {1 {expected number but got "rubbish"}}
+
+test expr-47.3 {isqrt() - NaN} ieeeFloatingPoint {
+ list [catch {expr {isqrt(NaN)}} result] $result
+} {1 {floating point value is Not a Number}}
+
+test expr-47.4 {isqrt() of negative floating point number} {
+ list [catch {expr {isqrt(-1.0)}} result] $result
+} {1 {square root of negative argument}}
+
+test expr-47.5 {isqrt() of floating point zero} {
+ expr isqrt(0.0)
+} 0
+
+test expr-47.6 {isqrt() of exact floating point numbers} {
+ set trouble {}
+ for {set i 0} {$i < 16} {incr i} {
+ set root [expr {1 << $i}]
+ set rm1 [expr {$root - 1}]
+ set arg [expr {pow(2., (2 * $i))}]
+ if {isqrt($arg-1) != $rm1} {
+ append trouble "i = " $i ": isqrt( " $arg "-1) != " $rm1 "\n"
+ }
+ if {isqrt($arg) != $root} {
+ append trouble "i = " $i ": isqrt( " $arg ") != " $root "\n"
+ }
+ if {isqrt($arg+1) != $root} {
+ append trouble "i = " $i ": isqrt( " $arg "+1) != " $root "\n"
+ }
+ }
+ set trouble
+} {}
+
+test expr-47.7 {isqrt() of exact floating point numbers} ieeeFloatingPoint {
+ set trouble {}
+ for {set i 17} {$i < 27} {incr i} {
+ set root [expr {1 << $i}]
+ set rm1 [expr {$root - 1}]
+ set arg [expr {pow(2., (2 * $i))}]
+ if {isqrt($arg-1.0) != $rm1} {
+ append trouble "i = " $i ": isqrt( " $arg "-1) != " $rm1 "\n"
+ }
+ if {isqrt($arg) != $root} {
+ append trouble "i = " $i ": isqrt( " $arg ") != " $root "\n"
+ }
+ if {isqrt($arg+1.0) != $root} {
+ append trouble "i = " $i ": isqrt( " $arg "+1) != " $root "\n"
+ }
+ }
+ set trouble
+} {}
+
+test expr-47.8 {isqrt of inexact floating point number} ieeeFloatingPoint {
+ expr isqrt(2[string repeat 0 34])
+} 141421356237309504
+
+test expr-47.9 {isqrt of negative int} {
+ list [catch {expr isqrt(-1)} result] $result
+} {1 {square root of negative argument}}
+
+test expr-47.10 {isqrt of negative bignum} {
+ list [catch {expr isqrt(-1[string repeat 0 1000])} result] $result
+} {1 {square root of negative argument}}
+
+test expr-47.11 {isqrt of zero} {
+ expr {isqrt(0)}
+} 0
+
+test expr-47.12 {isqrt of various sizes of integer} {
+ set faults 0
+ set trouble {}
+ for {set i 0} {$faults < 10 && $i <= 1024} {incr i} {
+ set root [expr {1 << $i}]
+ set rm1 [expr {$root - 1}]
+ set arg [expr {1 << (2 * $i)}]
+ set tval [expr {isqrt($arg-1)}]
+ if {$tval != $rm1} {
+ append trouble "i = " $i ": isqrt(" $arg "-1) == " $tval \
+ " != " $rm1 "\n"
+ incr faults
+ }
+ set tval [expr {isqrt($arg)}]
+ if {$tval != $root} {
+ append trouble "i = " $i ": isqrt(" $arg ") == " $tval \
+ " != " $root "\n"
+ incr faults
+ }
+ set tval [expr {isqrt($arg+1)}]
+ if {$tval != $root} {
+ append trouble "i = " $i ": isqrt(" $arg "+1) == " $tval \
+ " != " $root "\n"
+ incr faults
+ }
+ }
+ set trouble
+} {}
+
+test expr-47.13 {isqrt and floating point rounding (Bug 2143288)} {
+ set trouble {}
+ set faults 0
+ for {set i 0} {$i < 29 && $faults < 10} {incr i} {
+ for {set j 0} {$j <= $i} {incr j} {
+ set k [expr {isqrt((1<<56)+(1<<$i)+(1<<$j))}]
+ if {$k != (1<<28)} {
+ append trouble "i = $i, j = $j, k = $k\n"
+ incr faults
+ }
+ }
+ set k [expr {isqrt((1<<56)+(1<<29)+(1<<$i))}]
+ if {$k != (1<<28)+1} {
+ append trouble "i = $i, k = $k\n"
+ incr faults
+ }
+ }
+ set trouble
+} {}
+
+test expr-48.1 {Bug 1770224} {
+ expr {-0x8000000000000001 >> 0x8000000000000000}
+} -1
+
+test expr-49.1 {Bug 2823282} {
+ coroutine foo apply {{} {set expr expr; $expr {[yield]}}}
+ foo 1
+} 1
+
+test expr-50.1 {test sqrt() of bignums with non-Inf answer} {
+ expr {sqrt("1[string repeat 0 616]") == 1e308}
+} 1
+
+
+
+# cleanup
+if {[info exists a]} {
+ unset a
+}
+catch {unset min}
+catch {unset max}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/fCmd.test b/pkgs/msgcat/tests/fCmd.test
new file mode 100644
index 0000000..72b7da9
--- /dev/null
+++ b/pkgs/msgcat/tests/fCmd.test
@@ -0,0 +1,2601 @@
+# This file tests the tclFCmd.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1996-1997 Sun Microsystems, Inc.
+# Copyright (c) 1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+cd [temporaryDirectory]
+
+testConstraint testsetplatform [llength [info commands testsetplatform]]
+testConstraint testchmod [llength [info commands testchmod]]
+testConstraint winVista 0
+testConstraint win2000orXP 0
+# Don't know how to determine this constraint correctly
+testConstraint notNetworkFilesystem 0
+testConstraint reg 0
+if {[testConstraint win]} {
+ catch {
+ # Is the registry extension already static to this shell?
+ try {
+ load {} Registry
+ set ::reglib {}
+ } on error {} {
+ # try the location given to use on the commandline to tcltest
+ ::tcltest::loadTestedCommands
+ load $::reglib Registry
+ }
+ testConstraint reg 1
+ }
+}
+
+set tmpspace /tmp;# default value
+# Find a group that exists on this Unix system, or else skip tests that
+# require Unix groups.
+testConstraint foundGroup [expr {![testConstraint unix]}]
+if {[testConstraint unix]} {
+ catch {
+ set groupList [exec groups]
+ set group [lindex $groupList 0]
+ testConstraint foundGroup 1
+ }
+
+ proc dev dir {
+ file stat $dir stat
+ return $stat(dev)
+ }
+
+ if {[catch {makeDirectory tcl[pid] /tmp} tmpspace] == 0} {
+ testConstraint xdev [expr {([dev .] != [dev $tmpspace])}]
+ }
+}
+
+# Also used in winFCmd...
+if {[testConstraint win]} {
+ set major [string index $tcl_platform(osVersion) 0]
+ if {[testConstraint nt] && $major > 4} {
+ if {$major > 5} {
+ testConstraint winVista 1
+ } elseif {$major == 5} {
+ testConstraint win2000orXP 1
+ }
+ }
+}
+
+testConstraint darwin9 [expr {
+ [testConstraint unix]
+ && $tcl_platform(os) eq "Darwin"
+ && [package vsatisfies 1.$tcl_platform(osVersion) 1.9]
+}]
+testConstraint notDarwin9 [expr {![testConstraint darwin9]}]
+
+testConstraint fileSharing 0
+testConstraint notFileSharing 1
+testConstraint linkFile 1
+testConstraint linkDirectory 1
+
+# Several tests require need to match results against the unix username
+set user {}
+if {[testConstraint unix]} {
+ catch {
+ set user [exec whoami]
+ }
+ if {$user eq ""} {
+ catch {
+ regexp {^[^(]*\(([^)]*)\)} [exec id] -> user
+ }
+ }
+ if {$user eq ""} {
+ set user "root"
+ }
+}
+
+proc createfile {file {string a}} {
+ set f [open $file w]
+ puts -nonewline $f $string
+ close $f
+ return $string
+}
+
+#
+# checkcontent --
+#
+# Ensures that file "file" contains only the string "matchString" returns 0
+# if the file does not exist, or has a different content
+#
+proc checkcontent {file matchString} {
+ try {
+ set f [open $file]
+ set fileString [read $f]
+ close $f
+ } on error {} {
+ return 0
+ }
+ return [string match $matchString $fileString]
+}
+
+proc openup {path} {
+ testchmod 777 $path
+ if {[file isdirectory $path]} {
+ catch {
+ foreach p [glob -directory $path *] {
+ openup $p
+ }
+ }
+ }
+}
+
+proc cleanup {args} {
+ set wd [list .]
+ foreach p [concat $wd $args] {
+ set x ""
+ catch {
+ set x [glob -directory $p tf* td*]
+ }
+ foreach file $x {
+ if {
+ [catch {file delete -force -- $file}]
+ && [testConstraint testchmod]
+ } then {
+ catch {openup $file}
+ catch {file delete -force -- $file}
+ }
+ }
+ }
+}
+
+proc contents {file} {
+ set f [open $file]
+ set r [read $f]
+ close $f
+ return $r
+}
+
+
+set root [lindex [file split [pwd]] 0]
+
+# A really long file name.
+# Length of long is 1216 chars, which should be greater than any static buffer
+# or allowable filename.
+
+set long "abcdefghihjllmnopqrstuvwxyz01234567890"
+append long $long
+append long $long
+append long $long
+append long $long
+append long $long
+
+test fCmd-1.1 {TclFileRenameCmd} -constraints {notRoot} -setup {
+ cleanup
+} -body {
+ createfile tf1
+ file rename tf1 tf2
+ glob tf*
+} -result {tf2}
+
+test fCmd-2.1 {TclFileCopyCmd} -constraints {notRoot} -setup {
+ cleanup
+} -body {
+ createfile tf1
+ file copy tf1 tf2
+ lsort [glob tf*]
+} -result {tf1 tf2}
+
+test fCmd-3.1 {FileCopyRename: FileForceOption fails} -constraints {notRoot} -body {
+ file rename -xyz
+} -returnCodes error -result {bad option "-xyz": must be -force or --}
+test fCmd-3.2 {FileCopyRename: not enough args} -constraints {notRoot} -body {
+ file rename xyz
+} -returnCodes error -result {wrong # args: should be "file rename ?-option value ...? source ?source ...? target"}
+test fCmd-3.3 {FileCopyRename: Tcl_TranslateFileName fails} -constraints {notRoot} -body {
+ file rename xyz ~_totally_bogus_user
+} -returnCodes error -result {user "_totally_bogus_user" doesn't exist}
+test fCmd-3.4 {FileCopyRename: Tcl_TranslateFileName passes} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file copy tf1 ~
+} -result {error copying "tf1": no such file or directory}
+test fCmd-3.5 {FileCopyRename: target doesn't exist: stat(target) != 0} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file rename tf1 tf2 tf3
+} -result {error renaming: target "tf3" is not a directory}
+test fCmd-3.6 {FileCopyRename: target tf3 is not a dir: !S_ISDIR(target)} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ createfile tf3
+ file rename tf1 tf2 tf3
+} -result {error renaming: target "tf3" is not a directory}
+test fCmd-3.7 {FileCopyRename: target exists & is directory} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir td1
+ createfile tf1 tf1
+ file rename tf1 td1
+ contents [file join td1 tf1]
+} -result {tf1}
+test fCmd-3.8 {FileCopyRename: too many arguments: argc - i > 2} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file rename tf1 tf2 tf3
+} -result {error renaming: target "tf3" is not a directory}
+test fCmd-3.9 {FileCopyRename: too many arguments: argc - i > 2} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file copy -force -- tf1 tf2 tf3
+} -result {error copying: target "tf3" is not a directory}
+test fCmd-3.10 {FileCopyRename: just 2 arguments} -constraints notRoot -setup {
+ cleanup
+} -body {
+ createfile tf1 tf1
+ file rename tf1 tf2
+ contents tf2
+} -result {tf1}
+test fCmd-3.11 {FileCopyRename: just 2 arguments} -constraints notRoot -setup {
+ cleanup
+} -body {
+ createfile tf1 tf1
+ file rename -force -force -- tf1 tf2
+ contents tf2
+} -result {tf1}
+test fCmd-3.12 {FileCopyRename: move each source: 1 source} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ createfile tf1 tf1
+ file mkdir td1
+ file rename tf1 td1
+ contents [file join td1 tf1]
+} -result {tf1}
+test fCmd-3.13 {FileCopyRename: move each source: multiple sources} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ createfile tf1 tf1
+ createfile tf2 tf2
+ createfile tf3 tf3
+ createfile tf4 tf4
+ file mkdir td1
+ file rename tf1 tf2 tf3 tf4 td1
+ list [contents [file join td1 tf1]] [contents [file join td1 tf2]] \
+ [contents [file join td1 tf3]] [contents [file join td1 tf4]]
+} -result {tf1 tf2 tf3 tf4}
+test fCmd-3.14 {FileCopyRename: FileBasename fails} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir td1
+ file rename ~_totally_bogus_user td1
+} -result {user "_totally_bogus_user" doesn't exist}
+test fCmd-3.15 {FileCopyRename: source[0] == '\0'} -setup {
+ cleanup
+} -constraints {notRoot unixOrPc} -returnCodes error -body {
+ file mkdir td1
+ file rename / td1
+} -result {error renaming "/" to "td1": file already exists}
+test fCmd-3.16 {FileCopyRename: break on first error} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ createfile tf1
+ createfile tf2
+ createfile tf3
+ createfile tf4
+ file mkdir td1
+ createfile [file join td1 tf3]
+ file rename tf1 tf2 tf3 tf4 td1
+} -result [subst {error renaming "tf3" to "[file join td1 tf3]": file already exists}]
+
+test fCmd-4.1 {TclFileMakeDirsCmd: make each dir: 1 dir} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir td1
+ glob td*
+} -result {td1}
+test fCmd-4.2 {TclFileMakeDirsCmd: make each dir: multiple dirs} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir td1 td2 td3
+ lsort [glob td*]
+} -result {td1 td2 td3}
+test fCmd-4.3 {TclFileMakeDirsCmd: stops on first error} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ createfile tf1
+ catch {file mkdir td1 td2 tf1 td3 td4}
+ glob td1 td2 tf1 td3 td4
+} -result {td1 td2 tf1}
+test fCmd-4.4 {TclFileMakeDirsCmd: Tcl_TranslateFileName fails} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir ~_totally_bogus_user
+} -result {user "_totally_bogus_user" doesn't exist}
+test fCmd-4.5 {TclFileMakeDirsCmd: Tcl_SplitPath returns 0: *name == '\0'} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir ""
+} -result {can't create directory "": no such file or directory}
+test fCmd-4.6 {TclFileMakeDirsCmd: one level deep} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir td1
+ glob td1
+} -result {td1}
+test fCmd-4.7 {TclFileMakeDirsCmd: multi levels deep} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir [file join td1 td2 td3 td4]
+ glob td1 [file join td1 td2]
+} -result "td1 [file join td1 td2]"
+test fCmd-4.8 {TclFileMakeDirsCmd: already exist: lstat(target) == 0} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir td1
+ set x [file exists td1]
+ file mkdir td1
+ list $x [file exists td1]
+} -result {1 1}
+test fCmd-4.9 {TclFileMakeDirsCmd: exists, not dir} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ createfile tf1
+ file mkdir tf1
+} -result [subst {can't create directory "[file join tf1]": file already exists}]
+test fCmd-4.10 {TclFileMakeDirsCmd: exists, is dir} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir td1
+ set x [file exists td1]
+ file mkdir td1
+ list $x [file exists td1]
+} -result {1 1}
+test fCmd-4.11 {TclFileMakeDirsCmd: doesn't exist: errno != ENOENT} -setup {
+ cleanup
+} -constraints {unix notRoot testchmod} -returnCodes error -body {
+ file mkdir td1/td2/td3
+ testchmod 000 td1/td2
+ file mkdir td1/td2/td3/td4
+} -cleanup {
+ testchmod 755 td1/td2
+ cleanup
+} -result {can't create directory "td1/td2/td3": permission denied}
+test fCmd-4.13 {TclFileMakeDirsCmd: doesn't exist: errno == ENOENT} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ set x [file exists td1]
+ file mkdir td1
+ list $x [file exists td1]
+} -result {0 1}
+test fCmd-4.14 {TclFileMakeDirsCmd: TclpCreateDirectory fails} -setup {
+ cleanup
+ file delete -force foo
+} -constraints {unix notRoot} -body {
+ file mkdir foo
+ file attr foo -perm 040000
+ file mkdir foo/tf1
+} -returnCodes error -cleanup {
+ file delete -force foo
+} -result {can't create directory "foo/tf1": permission denied}
+test fCmd-4.16 {TclFileMakeDirsCmd: TclpCreateDirectory succeeds} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir tf1
+ file exists tf1
+} -result {1}
+
+test fCmd-5.1 {TclFileDeleteCmd: FileForceOption fails} -constraints {notRoot} -body {
+ file delete -xyz
+} -returnCodes error -result {bad option "-xyz": must be -force or --}
+test fCmd-5.2 {TclFileDeleteCmd: accept 0 files (TIP 323)} -body {
+ file delete -force -force
+} -result {}
+test fCmd-5.3 {TclFileDeleteCmd: 1 file} -constraints {notRoot} -setup {
+ cleanup
+} -body {
+ createfile tf1
+ createfile tf2
+ file mkdir td1
+ file delete tf2
+ glob tf* td*
+} -result {tf1 td1}
+test fCmd-5.4 {TclFileDeleteCmd: multiple files} -constraints notRoot -setup {
+ cleanup
+} -body {
+ createfile tf1
+ createfile tf2
+ file mkdir td1
+ set x [list [file exists tf1] [file exists tf2] [file exists td1]]
+ file delete tf1 td1 tf2
+ lappend x [file exists tf1] [file exists tf2] [file exists tf3]
+} -cleanup {cleanup} -result {1 1 1 0 0 0}
+test fCmd-5.5 {TclFileDeleteCmd: stop at first error} -setup {
+ cleanup
+} -constraints {notRoot unixOrPc} -body {
+ createfile tf1
+ createfile tf2
+ file mkdir td1
+ catch {file delete tf1 td1 $root tf2}
+ list [file exists tf1] [file exists tf2] [file exists td1]
+} -cleanup {cleanup} -result {0 1 0}
+test fCmd-5.6 {TclFileDeleteCmd: Tcl_TranslateFileName fails} -constraints {notRoot} -body {
+ file delete ~_totally_bogus_user
+} -returnCodes error -result {user "_totally_bogus_user" doesn't exist}
+test fCmd-5.7 {TclFileDeleteCmd: Tcl_TranslateFileName succeeds} -setup {
+ catch {file delete ~/tf1}
+} -constraints {notRoot} -body {
+ createfile ~/tf1
+ file delete ~/tf1
+} -result {}
+test fCmd-5.8 {TclFileDeleteCmd: file doesn't exist: lstat(name) != 0} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ set x [file exists tf1]
+ file delete tf1
+ list $x [file exists tf1]
+} -result {0 0}
+test fCmd-5.9 {TclFileDeleteCmd: is directory} -constraints {notRoot} -setup {
+ cleanup
+} -body {
+ file mkdir td1
+ file delete td1
+ file exists td1
+} -result {0}
+test fCmd-5.10 {TclFileDeleteCmd: TclpRemoveDirectory fails} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir [file join td1 td2]
+ file delete td1
+} -result {error deleting "td1": directory not empty}
+test fCmd-5.11 {TclFileDeleteCmd: TclpRemoveDirectory with cwd inside} -setup {
+ cleanup
+ set dir [pwd]
+} -constraints {notRoot} -body {
+ file mkdir [file join td1 td2]
+ cd [file join td1 td2]
+ set res [list [catch {file delete -force [file dirname [pwd]]} msg]]
+ cd $dir
+ lappend res [file exists td1] $msg
+} -cleanup {
+ cd $dir
+} -result {0 0 {}}
+test fCmd-5.12 {TclFileDeleteCmd: TclpRemoveDirectory with bad perms} -setup {
+ cleanup
+} -constraints {unix} -body {
+ file mkdir [file join td1 td2]
+ file attributes [file join td1 td2] -permissions u+rwx
+ set res [list [catch {file delete -force td1} msg]]
+ lappend res [file exists td1] $msg
+} -result {0 0 {}}
+
+test fCmd-6.1 {CopyRenameOneFile: bad source} {notRoot emptyTest} {
+ # can't test this, because it's caught by FileCopyRename
+} {}
+test fCmd-6.2 {CopyRenameOneFile: bad target} {notRoot emptyTest} {
+ # can't test this, because it's caught by FileCopyRename
+} {}
+test fCmd-6.3 {CopyRenameOneFile: lstat(source) != 0} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file rename tf1 tf2
+} -result {error renaming "tf1": no such file or directory}
+test fCmd-6.4 {CopyRenameOneFile: lstat(source) == 0} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ createfile tf1
+ file rename tf1 tf2
+ glob tf*
+} -result {tf2}
+test fCmd-6.5 {CopyRenameOneFile: lstat(target) != 0} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ createfile tf1
+ file rename tf1 tf2
+ glob tf*
+} -result {tf2}
+test fCmd-6.6 {CopyRenameOneFile: errno != ENOENT} -setup {
+ cleanup
+} -constraints {unix notRoot testchmod} -body {
+ file mkdir td1
+ testchmod 000 td1
+ createfile tf1
+ file rename tf1 td1
+} -returnCodes error -cleanup {
+ testchmod 755 td1
+} -result {error renaming "tf1" to "td1/tf1": permission denied}
+test fCmd-6.7 {CopyRenameOneFile: errno != ENOENT} -setup {
+ cleanup
+} -constraints {win 95} -returnCodes error -body {
+ createfile tf1
+ file rename tf1 $long
+} -result [subst {error renaming "tf1" to "$long": file name too long}]
+test fCmd-6.9 {CopyRenameOneFile: errno == ENOENT} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ createfile tf1
+ file rename tf1 tf2
+ glob tf*
+} -result {tf2}
+test fCmd-6.10 {CopyRenameOneFile: lstat(target) == 0} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ createfile tf1
+ createfile tf2
+ file rename tf1 tf2
+} -result {error renaming "tf1" to "tf2": file already exists}
+test fCmd-6.11 {CopyRenameOneFile: force == 0} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ createfile tf1
+ createfile tf2
+ file rename tf1 tf2
+} -result {error renaming "tf1" to "tf2": file already exists}
+test fCmd-6.12 {CopyRenameOneFile: force != 0} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ createfile tf1
+ createfile tf2
+ file rename -force tf1 tf2
+ glob tf*
+} -result {tf2}
+test fCmd-6.13 {CopyRenameOneFile: source is dir, target is file} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir td1
+ file mkdir td2
+ createfile [file join td2 td1]
+ file rename -force td1 td2
+} -result [subst {can't overwrite file "[file join td2 td1]" with directory "td1"}]
+test fCmd-6.14 {CopyRenameOneFile: source is file, target is dir} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ createfile tf1
+ file mkdir [file join td1 tf1]
+ file rename -force tf1 td1
+} -result [subst {can't overwrite directory "[file join td1 tf1]" with file "tf1"}]
+test fCmd-6.15 {CopyRenameOneFile: TclpRenameFile succeeds} -setup {
+ cleanup
+} -constraints {notRoot notNetworkFilesystem} -body {
+ file mkdir [file join td1 td2]
+ file mkdir td2
+ createfile [file join td2 tf1]
+ file rename -force td2 td1
+ file exists [file join td1 td2 tf1]
+} -result 1
+test fCmd-6.16 {CopyRenameOneFile: TclpCopyRenameOneFile fails} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir [file join td1 td2]
+ createfile [file join td1 td2 tf1]
+ file mkdir td2
+ file rename -force td2 td1
+} -returnCodes error -match glob -result \
+ [subst {error renaming "td2" to "[file join td1 td2]": file *}]
+test fCmd-6.17 {CopyRenameOneFile: errno == EINVAL} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file rename -force $root tf1
+} -result [subst {error renaming "$root" to "tf1": trying to rename a volume or move a directory into itself}]
+test fCmd-6.18 {CopyRenameOneFile: errno != EXDEV} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir [file join td1 td2]
+ createfile [file join td1 td2 tf1]
+ file mkdir td2
+ file rename -force td2 td1
+} -returnCodes error -match glob -result \
+ [subst {error renaming "td2" to "[file join td1 td2]": file *}]
+test fCmd-6.19 {CopyRenameOneFile: errno == EXDEV} -setup {
+ cleanup $tmpspace
+} -constraints {unix notRoot} -body {
+ createfile tf1
+ file rename tf1 $tmpspace
+ glob -nocomplain tf* [file join $tmpspace tf1]
+} -result [file join $tmpspace tf1]
+test fCmd-6.20 {CopyRenameOneFile: errno == EXDEV} -constraints {win} -setup {
+ catch {file delete -force c:/tcl8975@ d:/tcl8975@}
+} -body {
+ file mkdir c:/tcl8975@
+ if {[catch {file rename c:/tcl8975@ d:/}]} {
+ return d:/tcl8975@
+ }
+ glob c:/tcl8975@ d:/tcl8975@
+} -cleanup {
+ file delete -force c:/tcl8975@
+ catch {file delete -force d:/tcl8975@}
+} -result {d:/tcl8975@}
+test fCmd-6.21 {CopyRenameOneFile: copy/rename: S_ISDIR(source)} -setup {
+ cleanup $tmpspace
+} -constraints {unix notRoot} -body {
+ file mkdir td1
+ file rename td1 $tmpspace
+ glob -nocomplain td* [file join $tmpspace td*]
+} -result [file join $tmpspace td1]
+test fCmd-6.22 {CopyRenameOneFile: copy/rename: !S_ISDIR(source)} -setup {
+ cleanup $tmpspace
+} -constraints {unix notRoot} -body {
+ createfile tf1
+ file rename tf1 $tmpspace
+ glob -nocomplain tf* [file join $tmpspace tf*]
+} -result [file join $tmpspace tf1]
+test fCmd-6.23 {CopyRenameOneFile: TclpCopyDirectory failed} -setup {
+ cleanup $tmpspace
+} -constraints {xdev notRoot} -body {
+ file mkdir td1/td2/td3
+ file attributes td1 -permissions 0000
+ file rename td1 $tmpspace
+} -returnCodes error -cleanup {
+ file attributes td1 -permissions 0755
+ cleanup
+} -match regexp -result {^error renaming "td1"( to "/tmp/tcl\d+/td1")?: permission denied$}
+test fCmd-6.24 {CopyRenameOneFile: error uses original name} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir ~/td1/td2
+ set td1name [file join [file dirname ~] [file tail ~] td1]
+ file attributes $td1name -permissions 0000
+ file copy ~/td1 td1
+} -returnCodes error -cleanup {
+ file attributes $td1name -permissions 0755
+ file delete -force ~/td1
+} -result {error copying "~/td1": permission denied}
+test fCmd-6.25 {CopyRenameOneFile: error uses original name} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir td2
+ file mkdir ~/td1
+ set td1name [file join [file dirname ~] [file tail ~] td1]
+ file attributes $td1name -permissions 0000
+ file copy td2 ~/td1
+} -returnCodes error -cleanup {
+ file attributes $td1name -permissions 0755
+ file delete -force ~/td1
+} -result {error copying "td2" to "~/td1/td2": permission denied}
+test fCmd-6.26 {CopyRenameOneFile: doesn't use original name} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir ~/td1/td2
+ set td2name [file join [file dirname ~] [file tail ~] td1 td2]
+ file attributes $td2name -permissions 0000
+ file copy ~/td1 td1
+} -returnCodes error -cleanup {
+ file attributes $td2name -permissions 0755
+ file delete -force ~/td1
+} -result "error copying \"~/td1\" to \"td1\": \"[file join $::env(HOME) td1 td2]\": permission denied"
+test fCmd-6.27 {CopyRenameOneFile: TclpCopyDirectory failed} -setup {
+ cleanup $tmpspace
+} -constraints {notRoot xdev} -returnCodes error -body {
+ file mkdir td1/td2/td3
+ file mkdir [file join $tmpspace td1]
+ createfile [file join $tmpspace td1 tf1]
+ file rename -force td1 $tmpspace
+} -match glob -result {error renaming "td1" to "/tmp/tcl*/td1": file already exists}
+test fCmd-6.28 {CopyRenameOneFile: TclpCopyDirectory failed} -setup {
+ cleanup $tmpspace
+} -constraints {notRoot xdev} -body {
+ file mkdir td1/td2/td3
+ file attributes td1/td2/td3 -permissions 0000
+ file rename td1 $tmpspace
+} -returnCodes error -cleanup {
+ file attributes td1/td2/td3 -permissions 0755
+ cleanup $tmpspace
+} -match glob -result {error renaming "td1" to "/tmp/tcl*/td1": "td1/td2/td3": permission denied}
+test fCmd-6.29 {CopyRenameOneFile: TclpCopyDirectory passed} -setup {
+ cleanup $tmpspace
+} -constraints {notRoot xdev} -body {
+ file mkdir td1/td2/td3
+ file rename td1 $tmpspace
+ glob td* [file join $tmpspace td1 t*]
+} -result [file join $tmpspace td1 td2]
+test fCmd-6.30 {CopyRenameOneFile: TclpRemoveDirectory failed} -setup {
+ cleanup $tmpspace
+} -constraints {unix notRoot} -body {
+ file mkdir foo/bar
+ file attr foo -perm 040555
+ file rename foo/bar $tmpspace
+} -returnCodes error -cleanup {
+ catch {file delete [file join $tmpspace bar]}
+ catch {file attr foo -perm 040777}
+ catch {file delete -force foo}
+} -match glob -result {*: permission denied}
+test fCmd-6.31 {CopyRenameOneFile: TclpDeleteFile passed} -setup {
+ cleanup $tmpspace
+} -constraints {notRoot xdev} -body {
+ file mkdir [file join $tmpspace td1]
+ createfile [file join $tmpspace td1 tf1]
+ file rename [file join $tmpspace td1 tf1] tf1
+ list [file exists [file join $tmpspace td1 tf1]] [file exists tf1]
+} -result {0 1}
+test fCmd-6.32 {CopyRenameOneFile: copy} -constraints {notRoot} -setup {
+ cleanup
+} -returnCodes error -body {
+ file copy tf1 tf2
+} -result {error copying "tf1": no such file or directory}
+
+test fCmd-7.1 {FileForceOption: none} -constraints {notRoot} -setup {
+ cleanup
+} -returnCodes error -body {
+ file mkdir [file join tf1 tf2]
+ file delete tf1
+} -result {error deleting "tf1": directory not empty}
+test fCmd-7.2 {FileForceOption: -force} -constraints {notRoot} -setup {
+ cleanup
+} -body {
+ file mkdir [file join tf1 tf2]
+ file delete -force tf1
+} -result {}
+test fCmd-7.3 {FileForceOption: --} -constraints {notRoot} -body {
+ createfile -tf1
+ file delete -- -tf1
+} -result {}
+test fCmd-7.4 {FileForceOption: bad option} -constraints {notRoot} -setup {
+ createfile -tf1
+} -body {
+ file delete -tf1
+} -returnCodes error -cleanup {
+ file delete -- -tf1
+} -result {bad option "-tf1": must be -force or --}
+test fCmd-7.5 {FileForceOption: multiple times through loop} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ createfile --
+ createfile -force
+ file delete -force -force -- -- -force
+ glob -- -- -force
+} -result {no files matched glob patterns "-- -force"}
+
+test fCmd-8.1 {FileBasename: basename of ~user: argc == 1 && *path == ~} \
+ -constraints {unix notRoot knownBug} -body {
+ # Labelled knownBug because it is dangerous [Bug: 3881]
+ file mkdir td1
+ file attr td1 -perm 040000
+ file rename ~$user td1
+} -returnCodes error -cleanup {
+ file delete -force td1
+} -result "error renaming \"~$user\" to \"td1/[file tail ~$user]\": permission denied"
+test fCmd-8.2 {FileBasename: basename of ~user: argc == 1 && *path == ~} \
+ -constraints {unix notRoot} -body {
+ string equal [file tail ~$user] ~$user
+} -result 0
+test fCmd-8.3 {file copy and path translation: ensure correct error} -body {
+ file copy ~ [file join this file doesnt exist]
+} -returnCodes error -result [subst \
+ {error copying "~" to "[file join this file doesnt exist]": no such file or directory}]
+
+test fCmd-9.1 {file rename: comprehensive: EACCES} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir td1
+ file mkdir td2
+ file attr td2 -perm 040000
+ file rename td1 td2/
+} -returnCodes error -cleanup {
+ file delete -force td2
+ file delete -force td1
+} -result {error renaming "td1" to "td2/td1": permission denied}
+test fCmd-9.2 {file rename: comprehensive: source doesn't exist} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file rename tf1 tf2
+} -result {error renaming "tf1": no such file or directory}
+test fCmd-9.3 {file rename: comprehensive: file to new name} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ createfile tf1
+ createfile tf2
+ testchmod 444 tf2
+ file rename tf1 tf3
+ file rename tf2 tf4
+ list [lsort [glob tf*]] [file writable tf3] [file writable tf4]
+} -result {{tf3 tf4} 1 0}
+test fCmd-9.4.a {file rename: comprehensive: dir to new name} -setup {
+ cleanup
+} -constraints {win win2000orXP testchmod} -body {
+ file mkdir td1 td2
+ testchmod 555 td2
+ file rename td1 td3
+ file rename td2 td4
+ list [lsort [glob td*]] [file writable td3] [file writable td4]
+} -cleanup {
+ cleanup
+} -result {{td3 td4} 1 0}
+test fCmd-9.4.b {file rename: comprehensive: dir to new name} -setup {
+ cleanup
+} -constraints {unix notRoot testchmod notDarwin9} -body {
+ file mkdir td1 td2
+ testchmod 555 td2
+ file rename td1 td3
+ file rename td2 td4
+ list [lsort [glob td*]] [file writable td3] [file writable td4]
+} -cleanup {
+ cleanup
+} -result {{td3 td4} 1 0}
+test fCmd-9.5 {file rename: comprehensive: file to self} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ createfile tf1 tf1
+ createfile tf2 tf2
+ testchmod 444 tf2
+ file rename -force tf1 tf1
+ file rename -force tf2 tf2
+ list [contents tf1] [contents tf2] [file writable tf1] [file writable tf2]
+} -result {tf1 tf2 1 0}
+test fCmd-9.6.a {file rename: comprehensive: dir to self} -setup {
+ cleanup
+} -constraints {win win2000orXP testchmod} -body {
+ file mkdir td1
+ file mkdir td2
+ testchmod 555 td2
+ file rename -force td1 .
+ file rename -force td2 .
+ list [lsort [glob td*]] [file writable td1] [file writable td2]
+} -result {{td1 td2} 1 0}
+test fCmd-9.6.b {file rename: comprehensive: dir to self} -setup {
+ cleanup
+} -constraints {unix notRoot testchmod} -body {
+ file mkdir td1
+ file mkdir td2
+ testchmod 555 td2
+ file rename -force td1 .
+ file rename -force td2 .
+ list [lsort [glob td*]] [file writable td1] [file writable td2]
+} -result {{td1 td2} 1 0}
+test fCmd-9.7 {file rename: comprehensive: file to existing file} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ createfile tf1
+ createfile tf2
+ createfile tfs1
+ createfile tfs2
+ createfile tfs3
+ createfile tfs4
+ createfile tfd1
+ createfile tfd2
+ createfile tfd3
+ createfile tfd4
+ testchmod 444 tfs3
+ testchmod 444 tfs4
+ testchmod 444 tfd2
+ testchmod 444 tfd4
+ set msg [list [catch {file rename tf1 tf2} msg] $msg]
+ file rename -force tfs1 tfd1
+ file rename -force tfs2 tfd2
+ file rename -force tfs3 tfd3
+ file rename -force tfs4 tfd4
+ list [lsort [glob tf*]] $msg [file writable tfd1] [file writable tfd2] [file writable tfd3] [file writable tfd4]
+} -result {{tf1 tf2 tfd1 tfd2 tfd3 tfd4} {1 {error renaming "tf1" to "tf2": file already exists}} 1 1 0 0}
+test fCmd-9.8 {file rename: comprehensive: dir to empty dir} -setup {
+ cleanup
+} -constraints {notRoot testchmod notNetworkFilesystem} -body {
+ # Under unix, you can rename a read-only directory, but you can't move it
+ # into another directory.
+ file mkdir td1
+ file mkdir [file join td2 td1]
+ file mkdir tds1
+ file mkdir tds2
+ file mkdir tds3
+ file mkdir tds4
+ file mkdir [file join tdd1 tds1]
+ file mkdir [file join tdd2 tds2]
+ file mkdir [file join tdd3 tds3]
+ file mkdir [file join tdd4 tds4]
+ if {![testConstraint unix]} {
+ testchmod 555 tds3
+ testchmod 555 tds4
+ }
+ testchmod 555 [file join tdd2 tds2]
+ testchmod 555 [file join tdd4 tds4]
+ set msg [list [catch {file rename td1 td2} msg] $msg]
+ file rename -force tds1 tdd1
+ file rename -force tds2 tdd2
+ file rename -force tds3 tdd3
+ file rename -force tds4 tdd4
+ if {[testConstraint unix]} {
+ set w3 0
+ set w4 0
+ } else {
+ set w3 [file writable [file join tdd3 tds3]]
+ set w4 [file writable [file join tdd4 tds4]]
+ }
+ list [lsort [glob td*]] $msg [file writable [file join tdd1 tds1]] \
+ [file writable [file join tdd2 tds2]] $w3 $w4
+} -result [subst {{td1 td2 tdd1 tdd2 tdd3 tdd4} {1 {error renaming "td1" to "[file join td2 td1]": file already exists}} 1 1 0 0}]
+# Test can hit EEXIST or EBUSY, depending on underlying filesystem
+test fCmd-9.9 {file rename: comprehensive: dir to non-empty dir} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ file mkdir tds1
+ file mkdir tds2
+ file mkdir [file join tdd1 tds1 xxx]
+ file mkdir [file join tdd2 tds2 xxx]
+ if {!([testConstraint unix] || [testConstraint winVista])} {
+ testchmod 555 tds2
+ }
+ set a1 [list [catch {file rename -force tds1 tdd1} msg] $msg]
+ set a2 [list [catch {file rename -force tds2 tdd2} msg] $msg]
+ if {[testConstraint unix] || [testConstraint winVista]} {
+ set w2 0
+ } else {
+ set w2 [file writable tds2]
+ }
+ list [lsort [glob td*]] $a1 $a2 [file writable tds1] $w2
+} -match glob -result \
+ [subst {{tdd1 tdd2 tds1 tds2} {1 {error renaming "tds1" to "[file join tdd1 tds1]": file *}} {1 {error renaming "tds2" to "[file join tdd2 tds2]": file *}} 1 0}]
+test fCmd-9.10 {file rename: comprehensive: file to new name and dir} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ createfile tf1
+ createfile tf2
+ file mkdir td1
+ testchmod 444 tf2
+ file rename tf1 [file join td1 tf3]
+ file rename tf2 [file join td1 tf4]
+ list [catch {glob tf*}] [lsort [glob -directory td1 t*]] \
+ [file writable [file join td1 tf3]] [file writable [file join td1 tf4]]
+} -result [subst {1 {[file join td1 tf3] [file join td1 tf4]} 1 0}]
+test fCmd-9.11 {file rename: comprehensive: dir to new name and dir} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ file mkdir td1
+ file mkdir td2
+ file mkdir td3
+ if {!([testConstraint unix] || [testConstraint winVista])} {
+ testchmod 555 td2
+ }
+ file rename td1 [file join td3 td3]
+ file rename td2 [file join td3 td4]
+ if {[testConstraint unix] || [testConstraint winVista]} {
+ set w4 0
+ } else {
+ set w4 [file writable [file join td3 td4]]
+ }
+ list [lsort [glob td*]] [lsort [glob -directory td3 t*]] \
+ [file writable [file join td3 td3]] $w4
+} -result [subst {td3 {[file join td3 td3] [file join td3 td4]} 1 0}]
+test fCmd-9.12 {file rename: comprehensive: target exists} -setup {
+ cleanup
+} -constraints {notRoot testchmod notNetworkFilesystem} -body {
+ file mkdir [file join td1 td2] [file join td2 td1]
+ testchmod 555 [file join td2 td1]
+ file mkdir [file join td3 td4] [file join td4 td3]
+ file rename -force td3 td4
+ list [file exists td3] [file exists [file join td4 td3 td4]] \
+ [catch {file rename td1 td2} msg] $msg
+} -cleanup {
+ testchmod 755 [file join td2 td1]
+} -result [subst {0 1 1 {error renaming "td1" to "[file join td2 td1]": file already exists}}]
+# Test can hit EEXIST or EBUSY, depending on underlying filesystem
+test fCmd-9.13 {file rename: comprehensive: can't overwrite target} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir [file join td1 td2] [file join td2 td1 td4]
+ file rename -force td1 td2
+} -returnCodes error -match glob -result \
+ [subst {error renaming "td1" to "[file join td2 td1]": file *}]
+test fCmd-9.14 {file rename: comprehensive: dir into self} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir td1
+ list [glob td*] [list [catch {file rename td1 td1} msg] $msg]
+} -result [subst {td1 {1 {error renaming "td1" to "[file join td1 td1]": trying to rename a volume or move a directory into itself}}}]
+test fCmd-9.14.1 {file rename: comprehensive: dir into self} -setup {
+ cleanup
+} -constraints {notRoot} -body {
+ file mkdir td1
+ file rename td1 td1x
+ file rename td1x td1
+ set msg "ok"
+} -result {ok}
+test fCmd-9.14.2 {file rename: comprehensive: dir into self} -setup {
+ cleanup
+ set dir [pwd]
+} -constraints {nonPortable notRoot} -body {
+ file mkdir td1
+ cd td1
+ file rename [file join .. td1] [file join .. td1x]
+} -returnCodes error -cleanup {
+ cd $dir
+} -result [subst {error renaming "[file join .. td1]" to "[file join .. td1x]": permission denied}]
+test fCmd-9.14.3 {file rename: comprehensive: dir into self} -setup {
+ cleanup
+ set dir [pwd]
+} -constraints {notRoot} -body {
+ file mkdir td1
+ cd td1
+ file rename [file join .. td1] [file join .. td1 foo]
+} -returnCodes error -cleanup {
+ cd $dir
+} -result [subst {error renaming "[file join .. td1]" to "[file join .. td1 foo]": trying to rename a volume or move a directory into itself}]
+test fCmd-9.15 {file rename: comprehensive: source and target incompatible} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir td1
+ createfile tf1
+ file rename -force td1 tf1
+} -cleanup {
+ cleanup
+} -result {can't overwrite file "tf1" with directory "td1"}
+test fCmd-9.16 {file rename: comprehensive: source and target incompatible} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir td1/tf1
+ createfile tf1
+ file rename -force tf1 td1
+} -result [subst {can't overwrite directory "[file join td1 tf1]" with file "tf1"}]
+
+test fCmd-10.1 {file copy: comprehensive: source doesn't exist} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file copy tf1 tf2
+} -result {error copying "tf1": no such file or directory}
+test fCmd-10.2 {file copy: comprehensive: file to new name} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ createfile tf1 tf1
+ createfile tf2 tf2
+ testchmod 444 tf2
+ file copy tf1 tf3
+ file copy tf2 tf4
+ list [lsort [glob tf*]] [contents tf3] [contents tf4] [file writable tf3] [file writable tf4]
+} -result {{tf1 tf2 tf3 tf4} tf1 tf2 1 0}
+test fCmd-10.3 {file copy: comprehensive: dir to new name} -setup {
+ cleanup
+} -constraints {unix notRoot testchmod} -body {
+ file mkdir [file join td1 tdx]
+ file mkdir [file join td2 tdy]
+ testchmod 555 td2
+ file copy td1 td3
+ file copy td2 td4
+ list [lsort [glob td*]] [glob -directory td3 t*] \
+ [glob -directory td4 t*] [file writable td3] [file writable td4]
+} -cleanup {
+ testchmod 755 td2
+ testchmod 755 td4
+} -result [list {td1 td2 td3 td4} [file join td3 tdx] [file join td4 tdy] 1 0]
+test fCmd-10.3.1 {file copy: comprehensive: dir to new name} -setup {
+ cleanup
+} -constraints {win notRoot testchmod} -body {
+ # On Windows with ACLs, copying a directory is defined like this
+ file mkdir [file join td1 tdx]
+ file mkdir [file join td2 tdy]
+ testchmod 555 td2
+ file copy td1 td3
+ file copy td2 td4
+ list [lsort [glob td*]] [glob -directory td3 t*] \
+ [glob -directory td4 t*] [file writable td3] [file writable td4]
+} -cleanup {
+ testchmod 755 td2
+ testchmod 755 td4
+} -result [list {td1 td2 td3 td4} [file join td3 tdx] [file join td4 tdy] 1 1]
+test fCmd-10.4 {file copy: comprehensive: file to existing file} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ createfile tf1
+ createfile tf2
+ createfile tfs1
+ createfile tfs2
+ createfile tfs3
+ createfile tfs4
+ createfile tfd1
+ createfile tfd2
+ createfile tfd3
+ createfile tfd4
+ testchmod 444 tfs3
+ testchmod 444 tfs4
+ testchmod 444 tfd2
+ testchmod 444 tfd4
+ set msg [list [catch {file copy tf1 tf2} msg] $msg]
+ file copy -force tfs1 tfd1
+ file copy -force tfs2 tfd2
+ file copy -force tfs3 tfd3
+ file copy -force tfs4 tfd4
+ list [lsort [glob tf*]] $msg [file writable tfd1] [file writable tfd2] [file writable tfd3] [file writable tfd4]
+} -result {{tf1 tf2 tfd1 tfd2 tfd3 tfd4 tfs1 tfs2 tfs3 tfs4} {1 {error copying "tf1" to "tf2": file already exists}} 1 1 0 0}
+test fCmd-10.5 {file copy: comprehensive: dir to empty dir} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ file mkdir td1
+ file mkdir [file join td2 td1]
+ file mkdir tds1
+ file mkdir tds2
+ file mkdir tds3
+ file mkdir tds4
+ file mkdir [file join tdd1 tds1]
+ file mkdir [file join tdd2 tds2]
+ file mkdir [file join tdd3 tds3]
+ file mkdir [file join tdd4 tds4]
+ testchmod 555 tds3
+ testchmod 555 tds4
+ testchmod 555 [file join tdd2 tds2]
+ testchmod 555 [file join tdd4 tds4]
+ set a1 [list [catch {file copy td1 td2} msg] $msg]
+ set a2 [list [catch {file copy -force tds1 tdd1} msg] $msg]
+ set a3 [catch {file copy -force tds2 tdd2}]
+ set a4 [catch {file copy -force tds3 tdd3}]
+ set a5 [catch {file copy -force tds4 tdd4}]
+ list [lsort [glob td*]] $a1 $a2 $a3 $a4 $a5
+} -result [subst {{td1 td2 tdd1 tdd2 tdd3 tdd4 tds1 tds2 tds3 tds4} {1 {error copying "td1" to "[file join td2 td1]": file already exists}} {1 {error copying "tds1" to "[file join tdd1 tds1]": file already exists}} 1 1 1}]
+test fCmd-10.6 {file copy: comprehensive: dir to non-empty dir} -setup {
+ cleanup
+} -constraints {notRoot unixOrPc testchmod} -body {
+ file mkdir tds1
+ file mkdir tds2
+ file mkdir [file join tdd1 tds1 xxx]
+ file mkdir [file join tdd2 tds2 xxx]
+ testchmod 555 tds2
+ set a1 [list [catch {file copy -force tds1 tdd1} msg] $msg]
+ set a2 [list [catch {file copy -force tds2 tdd2} msg] $msg]
+ list [lsort [glob td*]] $a1 $a2 [file writable tds1] [file writable tds2]
+} -result [subst {{tdd1 tdd2 tds1 tds2} {1 {error copying "tds1" to "[file join tdd1 tds1]": file already exists}} {1 {error copying "tds2" to "[file join tdd2 tds2]": file already exists}} 1 0}]
+test fCmd-10.7 {file rename: comprehensive: file to new name and dir} -setup {
+ cleanup
+} -constraints {notRoot testchmod} -body {
+ createfile tf1
+ createfile tf2
+ file mkdir td1
+ testchmod 444 tf2
+ file copy tf1 [file join td1 tf3]
+ file copy tf2 [file join td1 tf4]
+ list [lsort [glob tf*]] [lsort [glob -directory td1 t*]] \
+ [file writable [file join td1 tf3]] [file writable [file join td1 tf4]]
+} -result [subst {{tf1 tf2} {[file join td1 tf3] [file join td1 tf4]} 1 0}]
+test fCmd-10.8 {file rename: comprehensive: dir to new name and dir} -setup {
+ cleanup
+} -constraints {unix notRoot testchmod} -body {
+ file mkdir td1
+ file mkdir td2
+ file mkdir td3
+ testchmod 555 td2
+ file copy td1 [file join td3 td3]
+ file copy td2 [file join td3 td4]
+ list [lsort [glob td*]] [lsort [glob -directory td3 t*]] \
+ [file writable [file join td3 td3]] [file writable [file join td3 td4]]
+} -result [subst {{td1 td2 td3} {[file join td3 td3] [file join td3 td4]} 1 0}]
+test fCmd-10.8.1 {file rename: comprehensive: dir to new name and dir} -setup {
+ cleanup
+} -constraints {win notRoot testchmod} -body {
+ # On Windows with ACLs, copying a directory is defined like this
+ file mkdir td1
+ file mkdir td2
+ file mkdir td3
+ testchmod 555 td2
+ file copy td1 [file join td3 td3]
+ file copy td2 [file join td3 td4]
+ list [lsort [glob td*]] [lsort [glob -directory td3 t*]] \
+ [file writable [file join td3 td3]] [file writable [file join td3 td4]]
+} -result [subst {{td1 td2 td3} {[file join td3 td3] [file join td3 td4]} 1 1}]
+test fCmd-10.9 {file copy: comprehensive: source and target incompatible} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir td1
+ createfile tf1
+ file copy -force td1 tf1
+} -result {can't overwrite file "tf1" with directory "td1"}
+test fCmd-10.10 {file copy: comprehensive: source and target incompatible} -setup {
+ cleanup
+} -constraints {notRoot} -returnCodes error -body {
+ file mkdir [file join td1 tf1]
+ createfile tf1
+ file copy -force tf1 td1
+} -result [subst {can't overwrite directory "[file join td1 tf1]" with file "tf1"}]
+test fCmd-10.11 {file copy: copy to empty file name} -setup {
+ cleanup
+} -returnCodes error -body {
+ createfile tf1
+ file copy tf1 ""
+} -result {error copying "tf1" to "": no such file or directory}
+test fCmd-10.12 {file rename: rename to empty file name} -setup {
+ cleanup
+} -returnCodes error -body {
+ createfile tf1
+ file rename tf1 ""
+} -result {error renaming "tf1" to "": no such file or directory}
+cleanup
+
+# old tests
+
+test fCmd-11.1 {TclFileRenameCmd: -- option} -constraints notRoot -setup {
+ catch {file delete -force -- -tfa1}
+} -body {
+ set s [createfile -tfa1]
+ file rename -- -tfa1 tfa2
+ list [checkcontent tfa2 $s] [file exists -tfa1]
+} -cleanup {
+ file delete tfa2
+} -result {1 0}
+test fCmd-11.2 {TclFileRenameCmd: bad option} -constraints notRoot -setup {
+ catch {file delete -force -- tfa1}
+} -body {
+ set s [createfile tfa1]
+ list [catch {file rename -x tfa1 tfa2}] \
+ [checkcontent tfa1 $s] [file exists tfa2]
+} -cleanup {
+ file delete tfa1
+} -result {1 1 0}
+test fCmd-11.3 {TclFileRenameCmd: bad \# args} -returnCodes error -body {
+ file rename --
+} -match glob -result *
+test fCmd-11.4 {TclFileRenameCmd: target filename translation failing} -setup {
+ set temp $::env(HOME)
+} -constraints notRoot -body {
+ global env
+ unset env(HOME)
+ catch { file rename tfa ~/foobar }
+} -cleanup {
+ set ::env(HOME) $temp
+} -result 1
+test fCmd-11.5 {TclFileRenameCmd: > 1 source & target is not a dir} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {notRoot} -body {
+ createfile tfa1
+ createfile tfa2
+ createfile tfa3
+ catch {file rename tfa1 tfa2 tfa3}
+} -cleanup {
+ file delete tfa1 tfa2 tfa3
+} -result {1}
+test fCmd-11.6 {TclFileRenameCmd: : single file into directory} -setup {
+ catch {file delete -force -- tfa1 tfad}
+} -constraints {notRoot} -body {
+ set s [createfile tfa1]
+ file mkdir tfad
+ file rename tfa1 tfad
+ list [checkcontent tfad/tfa1 $s] [file exists tfa1]
+} -cleanup {
+ file delete -force tfad
+} -result {1 0}
+test fCmd-11.7 {TclFileRenameCmd: : multiple files into directory} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfad}
+} -constraints {notRoot} -body {
+ set s1 [createfile tfa1]
+ set s2 [createfile tfa2]
+ file mkdir tfad
+ file rename tfa1 tfa2 tfad
+ list [checkcontent tfad/tfa1 $s1] [checkcontent tfad/tfa2 $s2] \
+ [file exists tfa1] [file exists tfa2]
+} -cleanup {
+ file delete -force tfad
+} -result {1 1 0 0}
+test fCmd-11.8 {TclFileRenameCmd: error renaming file to directory} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ set s [createfile tfa]
+ file mkdir tfad
+ file mkdir tfad/tfa
+ list [catch {file rename tfa tfad}] [checkcontent tfa $s] [file isdir tfad]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1}
+
+#
+# Coverage tests for renamefile() ;
+#
+test fCmd-12.1 {renamefile: source filename translation failing} -setup {
+ set temp $::env(HOME)
+} -constraints {notRoot} -body {
+ global env
+ unset env(HOME)
+ catch {file rename ~/tfa1 tfa2}
+} -cleanup {
+ set ::env(HOME) $temp
+} -result {1}
+test fCmd-12.2 {renamefile: src filename translation failing} -setup {
+ set temp $::env(HOME)
+} -constraints {notRoot} -body {
+ global env
+ unset env(HOME)
+ set s [createfile tfa1]
+ file mkdir tfad
+ catch {file rename tfa1 ~/tfa2 tfad}
+} -cleanup {
+ set ::env(HOME) $temp
+ file delete -force tfad
+} -result {1}
+test fCmd-12.3 {renamefile: stat failing on source} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ list [catch {file rename tfa1 tfa2}] [file exists tfa1] [file exists tfa2]
+} -result {1 0 0}
+test fCmd-12.4 {renamefile: error renaming file to directory} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ set s1 [createfile tfa]
+ file mkdir tfad
+ file mkdir tfad/tfa
+ list [catch {file rename tfa tfad}] [checkcontent tfa $s1] \
+ [file isdir tfad/tfa]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1}
+test fCmd-12.5 {renamefile: error renaming directory to file} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ file mkdir tfa
+ file mkdir tfad
+ set s [createfile tfad/tfa]
+ list [catch {file rename tfa tfad}] [checkcontent tfad/tfa $s] \
+ [file isdir tfad] [file isdir tfa]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1 1}
+test fCmd-12.6 {renamefile: TclRenameFile succeeding} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ set s [createfile tfa1]
+ file rename tfa1 tfa2
+ list [checkcontent tfa2 $s] [file exists tfa1]
+} -cleanup {
+ file delete tfa2
+} -result {1 0}
+test fCmd-12.7 {renamefile: renaming directory into offspring} -setup {
+ catch {file delete -force -- tfad}
+} -constraints {notRoot} -body {
+ file mkdir tfad
+ file mkdir tfad/dir
+ catch {file rename tfad tfad/dir}
+} -cleanup {
+ file delete -force tfad
+} -result {1}
+test fCmd-12.8 {renamefile: generic error} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa
+ file mkdir tfa/dir
+ file attributes tfa -permissions 0555
+ catch {file rename tfa/dir tfa2}
+} -cleanup {
+ catch {file attributes tfa -permissions 0777}
+ file delete -force tfa
+} -result {1}
+test fCmd-12.9 {renamefile: moving a file across volumes} -setup {
+ cleanup $tmpspace
+} -constraints {unix notRoot} -body {
+ set s [createfile tfa]
+ file rename tfa $tmpspace
+ list [checkcontent [file join $tmpspace tfa] $s] [file exists tfa]
+} -cleanup {
+ cleanup $tmpspace
+} -result {1 0}
+test fCmd-12.10 {renamefile: moving a directory across volumes} -setup {
+ cleanup $tmpspace
+} -constraints {xdev notRoot} -body {
+ file mkdir tfad
+ set s [createfile tfad/a]
+ file rename tfad $tmpspace
+ list [checkcontent [file join $tmpspace tfad a] $s] [file exists tfad]
+} -cleanup {
+ cleanup $tmpspace
+} -result {1 0}
+
+#
+# Coverage tests for TclCopyFilesCmd()
+#
+test fCmd-13.1 {TclCopyFilesCmd: -force option} -constraints notRoot -setup {
+ catch {file delete -force -- tfa1}
+} -body {
+ set s [createfile tfa1]
+ file copy -force tfa1 tfa2
+ list [checkcontent tfa2 $s] [checkcontent tfa1 $s]
+} -cleanup {
+ file delete tfa1 tfa2
+} -result {1 1}
+test fCmd-13.2 {TclCopyFilesCmd: -- option} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa1}
+} -body {
+ set s [createfile -tfa1]
+ file copy -- -tfa1 tfa2
+ list [checkcontent tfa2 $s] [checkcontent -tfa1 $s]
+} -cleanup {
+ file delete -- -tfa1 tfa2
+} -result {1 1}
+test fCmd-13.3 {TclCopyFilesCmd: bad option} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa1}
+} -body {
+ set s [createfile tfa1]
+ list [catch {file copy -x tfa1 tfa2}] \
+ [checkcontent tfa1 $s] [file exists tfa2]
+} -cleanup {
+ file delete tfa1
+} -result {1 1 0}
+test fCmd-13.4 {TclCopyFilesCmd: bad \# args} -constraints {notRoot} -body {
+ file copy --
+} -returnCodes error -match glob -result *
+test fCmd-13.5 {TclCopyFilesCmd: target filename translation failing} -setup {
+ set temp $::env(HOME)
+} -body {
+ global env
+ unset env(HOME)
+ catch { file copy tfa ~/foobar }
+} -cleanup {
+ set ::env(HOME) $temp
+} -result {1}
+test fCmd-13.6 {TclCopyFilesCmd: > 1 source & target is not a dir} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {notRoot} -body {
+ createfile tfa1
+ createfile tfa2
+ createfile tfa3
+ catch {file copy tfa1 tfa2 tfa3}
+} -cleanup {
+ file delete tfa1 tfa2 tfa3
+} -result {1}
+test fCmd-13.7 {TclCopyFilesCmd: single file into directory} -setup {
+ catch {file delete -force -- tfa1 tfad}
+} -constraints {notRoot} -body {
+ set s [createfile tfa1]
+ file mkdir tfad
+ file copy tfa1 tfad
+ list [checkcontent tfad/tfa1 $s] [checkcontent tfa1 $s]
+} -cleanup {
+ file delete -force tfad tfa1
+} -result {1 1}
+test fCmd-13.8 {TclCopyFilesCmd: multiple files into directory} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfad}
+} -constraints {notRoot} -body {
+ set s1 [createfile tfa1]
+ set s2 [createfile tfa2]
+ file mkdir tfad
+ file copy tfa1 tfa2 tfad
+ list [checkcontent tfad/tfa1 $s1] [checkcontent tfad/tfa2 $s2] \
+ [checkcontent tfa1 $s1] [checkcontent tfa2 $s2]
+} -cleanup {
+ file delete -force tfad tfa1 tfa2
+} -result {1 1 1 1}
+test fCmd-13.9 {TclCopyFilesCmd: error copying file to directory} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ set s [createfile tfa]
+ file mkdir tfad
+ file mkdir tfad/tfa
+ list [catch {file copy tfa tfad}] [checkcontent tfa $s] \
+ [file isdir tfad/tfa] [file isdir tfad]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1 1}
+
+#
+# Coverage tests for copyfile()
+#
+test fCmd-14.1 {copyfile: source filename translation failing} -setup {
+ set temp $::env(HOME)
+} -constraints {notRoot} -body {
+ global env
+ unset env(HOME)
+ catch {file copy ~/tfa1 tfa2}
+} -cleanup {
+ set ::env(HOME) $temp
+} -result {1}
+test fCmd-14.2 {copyfile: dst filename translation failing} -setup {
+ set temp $::env(HOME)
+} -constraints {notRoot} -body {
+ global env
+ unset env(HOME)
+ set s [createfile tfa1]
+ file mkdir tfad
+ list [catch {file copy tfa1 ~/tfa2 tfad}] [checkcontent tfad/tfa1 $s]
+} -cleanup {
+ set ::env(HOME) $temp
+ file delete -force tfa1 tfad
+} -result {1 1}
+test fCmd-14.3 {copyfile: stat failing on source} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints notRoot -body {
+ list [catch {file copy tfa1 tfa2}] [file exists tfa1] [file exists tfa2]
+} -result {1 0 0}
+test fCmd-14.4 {copyfile: error copying file to directory} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ set s1 [createfile tfa]
+ file mkdir tfad
+ file mkdir tfad/tfa
+ list [catch {file copy tfa tfad}] [checkcontent tfa $s1] \
+ [file isdir tfad] [file isdir tfad/tfa]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1 1}
+test fCmd-14.5 {copyfile: error copying directory to file} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ file mkdir tfa
+ file mkdir tfad
+ set s [createfile tfad/tfa]
+ list [catch {file copy tfa tfad}] [checkcontent tfad/tfa $s] \
+ [file isdir tfad] [file isdir tfa]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1 1}
+test fCmd-14.6 {copyfile: copy file succeeding} -constraints notRoot -setup {
+ catch {file delete -force -- tfa tfa2}
+} -body {
+ set s [createfile tfa]
+ file copy tfa tfa2
+ list [checkcontent tfa $s] [checkcontent tfa2 $s]
+} -cleanup {
+ file delete tfa tfa2
+} -result {1 1}
+test fCmd-14.7 {copyfile: copy directory succeeding} -setup {
+ catch {file delete -force -- tfa tfa2}
+} -constraints {notRoot} -body {
+ file mkdir tfa
+ set s [createfile tfa/file]
+ file copy tfa tfa2
+ list [checkcontent tfa/file $s] [checkcontent tfa2/file $s]
+} -cleanup {
+ file delete -force tfa tfa2
+} -result {1 1}
+test fCmd-14.8 {copyfile: copy directory failing} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa/dir/a/b/c
+ file attributes tfa/dir -permissions 0000
+ catch {file copy tfa tfa2}
+} -cleanup {
+ file attributes tfa/dir -permissions 0777
+ file delete -force tfa tfa2
+} -result {1}
+
+#
+# Coverage tests for TclMkdirCmd()
+#
+test fCmd-15.1 {TclMakeDirsCmd: target filename translation failing} -setup {
+ set temp $::env(HOME)
+} -constraints {notRoot} -body {
+ global env
+ unset env(HOME)
+ catch {file mkdir ~/tfa}
+} -cleanup {
+ set ::env(HOME) $temp
+} -result {1}
+#
+# Can Tcl_SplitPath return argc == 0? If so them we need a test for that code.
+#
+test fCmd-15.2 {TclMakeDirsCmd - one directory} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+ file mkdir tfa
+ file isdirectory tfa
+} -cleanup {
+ file delete tfa
+} -result {1}
+test fCmd-15.3 {TclMakeDirsCmd: - two directories} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ file mkdir tfa1 tfa2
+ list [file isdirectory tfa1] [file isdirectory tfa2]
+} -cleanup {
+ file delete tfa1 tfa2
+} -result {1 1}
+test fCmd-15.4 {TclMakeDirsCmd - stat failing} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa
+ createfile tfa/file
+ file attributes tfa -permissions 0000
+ catch {file mkdir tfa/file}
+} -cleanup {
+ file attributes tfa -permissions 0777
+ file delete -force tfa
+} -result {1}
+test fCmd-15.5 {TclMakeDirsCmd: - making a directory several levels deep} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+ file mkdir tfa/a/b/c
+ file isdir tfa/a/b/c
+} -cleanup {
+ file delete -force tfa
+} -result {1}
+test fCmd-15.6 {TclMakeDirsCmd: - trying to overwrite a file} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+ set s [createfile tfa]
+ list [catch {file mkdir tfa}] [file isdir tfa] [file exists tfa] \
+ [checkcontent tfa $s]
+} -cleanup {
+ file delete tfa
+} -result {1 0 1 1}
+test fCmd-15.7 {TclMakeDirsCmd - making several directories} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ file mkdir tfa1 tfa2/a/b/c
+ list [file isdir tfa1] [file isdir tfa2/a/b/c]
+} -cleanup {
+ file delete -force tfa1 tfa2
+} -result {1 1}
+test fCmd-15.8 {TclFileMakeDirsCmd: trying to create an existing dir} -body {
+ file mkdir tfa
+ file mkdir tfa
+ file isdir tfa
+} -constraints {notRoot} -cleanup {
+ file delete tfa
+} -result {1}
+
+# Coverage tests for TclDeleteFilesCommand()
+test fCmd-16.1 {test the -- argument} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa}
+} -body {
+ createfile tfa
+ file delete -- tfa
+ file exists tfa
+} -result 0
+test fCmd-16.2 {test the -force and -- arguments} -constraints notRoot -setup {
+ catch {file delete -force -- tfa}
+} -body {
+ createfile tfa
+ file delete -force -- tfa
+ file exists tfa
+} -result 0
+test fCmd-16.3 {test bad option} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa}
+} -body {
+ createfile tfa
+ catch {file delete -dog tfa}
+} -cleanup {
+ file delete tfa
+} -result {1}
+test fCmd-16.4 {accept zero files (TIP 323)} -body {
+ file delete
+} -result {}
+test fCmd-16.5 {accept zero files (TIP 323)} -body {
+ file delete --
+} -result {}
+test fCmd-16.6 {delete: source filename translation failing} -setup {
+ set temp $::env(HOME)
+} -constraints {notRoot} -body {
+ global env
+ unset env(HOME)
+ catch {file delete ~/tfa}
+} -cleanup {
+ set ::env(HOME) $temp
+} -result {1}
+test fCmd-16.7 {remove a non-empty directory without -force} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+ file mkdir tfa
+ createfile tfa/a
+ catch {file delete tfa}
+} -cleanup {
+ file delete -force tfa
+} -result {1}
+test fCmd-16.8 {remove a normal file} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa}
+} -body {
+ file mkdir tfa
+ createfile tfa/a
+ catch {file delete tfa}
+} -cleanup {
+ file delete -force tfa
+} -result {1}
+test fCmd-16.9 {error while deleting file} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa
+ createfile tfa/a
+ file attributes tfa -permissions 0555
+ catch {file delete tfa/a}
+ #######
+ ####### If any directory in a tree that is being removed does not have
+ ####### write permission, the process will fail! This is also the case
+ ####### with "rm -rf"
+ #######
+} -cleanup {
+ file attributes tfa -permissions 0777
+ file delete -force tfa
+} -result {1}
+test fCmd-16.10 {deleting multiple files} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -body {
+ createfile tfa1
+ createfile tfa2
+ file delete tfa1 tfa2
+ list [file exists tfa1] [file exists tfa2]
+} -result {0 0}
+test fCmd-16.11 {TclFileDeleteCmd: removing a nonexistant file} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+ file delete tfa
+} -result {}
+
+# More coverage tests for mkpath()
+test fCmd-17.1 {mkdir stat failing on target but not ENOENT} -setup {
+ catch {file delete -force -- tfa1}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa1
+ file attributes tfa1 -permissions 0555
+ catch {file mkdir tfa1/tfa2}
+} -cleanup {
+ file attributes tfa1 -permissions 0777
+ file delete -force tfa1
+} -result {1}
+test fCmd-17.2 {mkdir several levels deep - relative} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+ file mkdir tfa/a/b
+ file isdir tfa/a/b
+} -cleanup {
+ file delete tfa/a/b tfa/a tfa
+} -result 1
+test fCmd-17.3 {mkdir several levels deep - absolute} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+ set f [file join [pwd] tfa a]
+ file mkdir $f
+ file isdir $f
+} -cleanup {
+ file delete $f [file join [pwd] tfa]
+} -result {1}
+
+#
+# Functionality tests for TclFileRenameCmd()
+#
+test fCmd-18.1 {TclFileRenameCmd: rename (first form) in the same directory} \
+ -setup {
+ catch {file delete -force -- tfad}
+ set savedDir [pwd]
+} -constraints {notRoot} -body {
+ file mkdir tfad/dir
+ cd tfad/dir
+ set s [createfile foo]
+ file rename foo bar
+ file rename bar ./foo
+ file rename ./foo bar
+ file rename ./bar ./foo
+ file rename foo ../dir/bar
+ file rename ../dir/bar ./foo
+ file rename ../../tfad/dir/foo ../../tfad/dir/bar
+ file rename [file join [pwd] bar] foo
+ file rename foo [file join [pwd] bar]
+ list [checkcontent bar $s] [file exists foo]
+} -cleanup {
+ cd $savedDir
+ file delete -force tfad
+} -result {1 0}
+test fCmd-18.2 {TclFileRenameCmd: single dir to nonexistant} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ file mkdir tfa1
+ file rename tfa1 tfa2
+ list [file exists tfa2] [file exists tfa1]
+} -cleanup {
+ file delete tfa2
+} -result {1 0}
+test fCmd-18.3 {TclFileRenameCmd: mixed dirs and files into directory} -setup {
+ catch {file delete -force -- tfa1 tfad1 tfad2}
+} -constraints {notRoot} -body {
+ set s [createfile tfa1]
+ file mkdir tfad1 tfad2
+ file rename tfa1 tfad1 tfad2
+ list [checkcontent tfad2/tfa1 $s] [file isdir tfad2/tfad1] \
+ [file exists tfa1] [file exists tfad1]
+} -cleanup {
+ file delete tfad2/tfa1
+ file delete -force tfad2
+} -result {1 1 0 0}
+test fCmd-18.4 {TclFileRenameCmd: attempt to replace non-dir with dir} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ set s [createfile tfa]
+ file mkdir tfad
+ list [catch {file rename tfad tfa}] [checkcontent tfa $s] [file isdir tfad]
+} -cleanup {
+ file delete tfa tfad
+} -result {1 1 1}
+test fCmd-18.5 {TclFileRenameCmd: attempt to replace dir with non-dir} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ set s [createfile tfa]
+ file mkdir tfad/tfa
+ list [catch {file rename tfa tfad}] [checkcontent tfa $s] \
+ [file isdir tfad/tfa]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1}
+#
+# On Windows there is no easy way to determine if two files are the same
+#
+test fCmd-18.6 {TclFileRenameCmd: rename a file to itself} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+ set s [createfile tfa]
+ list [catch {file rename tfa tfa}] [checkcontent tfa $s]
+} -cleanup {
+ file delete tfa
+} -result {1 1}
+test fCmd-18.7 {TclFileRenameCmd: rename dir on top of another empty dir w/o -force} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ file mkdir tfa tfad/tfa
+ list [catch {file rename tfa tfad}] [file isdir tfa]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1}
+test fCmd-18.8 {TclFileRenameCmd: rename dir on top of another empty dir w/ -force} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot notNetworkFilesystem} -body {
+ file mkdir tfa tfad/tfa
+ file rename -force tfa tfad
+ file isdir tfa
+} -cleanup {
+ file delete -force tfad
+} -result 0
+test fCmd-18.9 {TclFileRenameCmd: rename dir on top of a non-empty dir w/o -force} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ file mkdir tfa tfad/tfa/file
+ list [catch {file rename tfa tfad}] [file isdir tfa] \
+ [file isdir tfad/tfa/file]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1}
+test fCmd-18.10 {TclFileRenameCmd: rename dir on top of a non-empty dir w/ -force} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot notNetworkFilesystem} -body {
+ file mkdir tfa tfad/tfa/file
+ list [catch {file rename -force tfa tfad}] [file isdir tfa] \
+ [file isdir tfad/tfa/file]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1}
+test fCmd-18.11 {TclFileRenameCmd: rename a non-existant file} -setup {
+ catch {file delete -force -- tfa1}
+} -constraints {notRoot} -body {
+ list [catch {file rename tfa1 tfa2}] [file exists tfa1] [file exists tfa2]
+} -result {1 0 0}
+test fCmd-18.12 {TclFileRenameCmd : rename a symbolic link to file} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {unix notRoot} -body {
+ set s [createfile tfa1]
+ file link -symbolic tfa2 tfa1
+ file rename tfa2 tfa3
+ file type tfa3
+} -cleanup {
+ file delete tfa1 tfa3
+} -result link
+test fCmd-18.13 {TclFileRenameCmd : rename a symbolic link to dir} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa1
+ file link -symbolic tfa2 tfa1
+ file rename tfa2 tfa3
+ file type tfa3
+} -cleanup {
+ file delete tfa1 tfa3
+} -result link
+test fCmd-18.14 {TclFileRenameCmd : rename a path with sym link} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa1/a/b/c/d
+ file mkdir tfa2
+ set f [file join [pwd] tfa1/a/b]
+ set f2 [file join [pwd] {tfa2/b alias}]
+ file link -symbolic $f2 $f
+ file rename {tfa2/b alias/c} tfa3
+ list [file isdir tfa3] [file exists tfa1/a/b/c]
+} -cleanup {
+ file delete -force tfa1 tfa2 tfa3
+} -result {1 0}
+test fCmd-18.15 {TclFileRenameCmd : rename a file to a symlink dir} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfalink}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa1
+ set s [createfile tfa2]
+ file link -symbolic tfalink tfa1
+ file rename tfa2 tfalink
+ checkcontent tfa1/tfa2 $s
+} -cleanup {
+ file delete -force tfa1 tfalink
+} -result {1}
+test fCmd-18.16 {TclFileRenameCmd: rename a dangling symlink} -setup {
+ catch {file delete -force -- tfa1 tfalink}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa1
+ file link -symbolic tfalink tfa1
+ file delete tfa1
+ file rename tfalink tfa2
+ file type tfa2
+} -cleanup {
+ file delete tfa2
+} -result link
+
+#
+# Coverage tests for TclUnixRmdir
+#
+test fCmd-19.1 {remove empty directory} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa}
+} -body {
+ file mkdir tfa
+ file delete tfa
+ file exists tfa
+} -result {0}
+test fCmd-19.2 {rmdir error besides EEXIST} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa
+ file mkdir tfa/a
+ file attributes tfa -permissions 0555
+ catch {file delete tfa/a}
+} -cleanup {
+ file attributes tfa -permissions 0777
+ file delete -force tfa
+} -result {1}
+test fCmd-19.3 {recursive remove} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa}
+} -body {
+ file mkdir tfa
+ file mkdir tfa/a
+ file delete -force tfa
+ file exists tfa
+} -result {0}
+
+#
+# TclUnixDeleteFile and TraversalDelete are covered by tests from the
+# TclDeleteFilesCmd suite
+#
+
+#
+# Coverage tests for TraverseUnixTree(), called from TclDeleteFilesCmd
+#
+test fCmd-20.1 {TraverseUnixTree : failure opening a subdirectory directory} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa
+ file mkdir tfa/a
+ file attributes tfa/a -permissions 0000
+ catch {file delete -force tfa}
+} -cleanup {
+ file attributes tfa/a -permissions 0777
+ file delete -force tfa
+} -result {1}
+test fCmd-20.2 {TraverseUnixTree : recursive delete of large directory: Bug 1034337} -setup {
+ catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+ file mkdir tfa
+ for {set i 1} {$i <= 300} {incr i} {
+ createfile tfa/testfile_$i
+ }
+ file delete -force tfa
+} -cleanup {
+ while {[catch {file delete -force tfa}]} {}
+} -result {}
+
+#
+# Feature testing for TclCopyFilesCmd
+#
+test fCmd-21.1 {copy : single file to nonexistant} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ set s [createfile tfa1]
+ file copy tfa1 tfa2
+ list [checkcontent tfa2 $s] [checkcontent tfa1 $s]
+} -cleanup {
+ file delete tfa1 tfa2
+} -result {1 1}
+test fCmd-21.2 {copy : single dir to nonexistant} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ file mkdir tfa1
+ file copy tfa1 tfa2
+ list [file isdir tfa2] [file isdir tfa1]
+} -cleanup {
+ file delete tfa1 tfa2
+} -result {1 1}
+test fCmd-21.3 {copy : single file into directory} -setup {
+ catch {file delete -force -- tfa1 tfad}
+} -constraints {notRoot} -body {
+ set s [createfile tfa1]
+ file mkdir tfad
+ file copy tfa1 tfad
+ list [checkcontent tfad/tfa1 $s] [checkcontent tfa1 $s]
+} -cleanup {
+ file delete -force tfa1 tfad
+} -result {1 1}
+test fCmd-21.4 {copy : more than one source and target is not a directory} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {notRoot} -body {
+ createfile tfa1
+ createfile tfa2
+ createfile tfa3
+ catch {file copy tfa1 tfa2 tfa3}
+} -cleanup {
+ file delete tfa1 tfa2 tfa3
+} -result {1}
+test fCmd-21.5 {copy : multiple files into directory} -constraints {notRoot} -setup {
+ catch {file delete -force -- tfa1 tfa2 tfad}
+} -body {
+ set s1 [createfile tfa1]
+ set s2 [createfile tfa2]
+ file mkdir tfad
+ file copy tfa1 tfa2 tfad
+ list [checkcontent tfad/tfa1 $s1] [checkcontent tfad/tfa2 $s2] \
+ [checkcontent tfa1 $s1] [checkcontent tfa2 $s2]
+} -cleanup {
+ file delete -force tfa1 tfa2 tfad
+} -result {1 1 1 1}
+test fCmd-21.6 {copy: mixed dirs and files into directory} -setup {
+ catch {file delete -force -- tfa1 tfad1 tfad2}
+} -constraints {notRoot notFileSharing} -body {
+ set s [createfile tfa1]
+ file mkdir tfad1 tfad2
+ file copy tfa1 tfad1 tfad2
+ list [checkcontent [file join tfad2 tfa1] $s] \
+ [file isdir [file join tfad2 tfad1]] \
+ [checkcontent tfa1 $s] [file isdir tfad1]
+} -cleanup {
+ file delete -force tfa1 tfad1 tfad2
+} -result {1 1 1 1}
+test fCmd-21.7.1 {TclCopyFilesCmd: copy a dangling link} -setup {
+ catch {file delete -force tfad1 tfalink tfalink2}
+} -constraints {unix notRoot dontCopyLinks} -body {
+ file mkdir tfad1
+ file link -symbolic tfalink tfad1
+ file delete tfad1
+ file copy tfalink tfalink2
+} -returnCodes error -cleanup {
+ file delete -force tfalink tfalink2
+} -result {error copying "tfalink": the target of this link doesn't exist}
+test fCmd-21.7.2 {TclCopyFilesCmd: copy a dangling link} -setup {
+ catch {file delete -force tfad1 tfalink tfalink2}
+} -constraints {unix notRoot} -body {
+ file mkdir tfad1
+ file link -symbolic tfalink tfad1
+ file delete tfad1
+ file copy tfalink tfalink2
+ file type tfalink2
+} -cleanup {
+ file delete tfalink tfalink2
+} -result link
+test fCmd-21.8.1 {TclCopyFilesCmd: copy a link} -setup {
+ catch {file delete -force tfad1 tfalink tfalink2}
+} -constraints {unix notRoot dontCopyLinks} -body {
+ file mkdir tfad1
+ file link -symbolic tfalink tfad1
+ file copy tfalink tfalink2
+ list [file type tfalink] [file type tfalink2] [file isdir tfad1]
+} -cleanup {
+ file delete -force tfad1 tfalink tfalink2
+} -result {link directory 1}
+test fCmd-21.8.2 {TclCopyFilesCmd: copy a link} -setup {
+ catch {file delete -force tfad1 tfalink tfalink2}
+} -constraints {unix notRoot} -body {
+ file mkdir tfad1
+ file link -symbolic tfalink tfad1
+ file copy tfalink tfalink2
+ list [file type tfalink] [file type tfalink2] [file isdir tfad1]
+} -cleanup {
+ file delete -force tfad1 tfalink tfalink2
+} -result {link link 1}
+test fCmd-21.9 {TclCopyFilesCmd: copy dir with a link in it} -setup {
+ catch {file delete -force tfad1 tfad2}
+} -constraints {unix notRoot} -body {
+ file mkdir tfad1
+ file link -symbolic tfad1/tfalink "[pwd]/tfad1"
+ file copy tfad1 tfad2
+ file type tfad2/tfalink
+} -cleanup {
+ file delete -force tfad1 tfad2
+} -result link
+test fCmd-21.10 {TclFileCopyCmd: copy dir on top of another empty dir w/o -force} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ file mkdir tfa [file join tfad tfa]
+ list [catch {file copy tfa tfad}] [file isdir tfa]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1}
+test fCmd-21.11 {TclFileCopyCmd: copy dir on top of a dir w/o -force} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ file mkdir tfa [file join tfad tfa file]
+ list [catch {file copy tfa tfad}] [file isdir tfa] \
+ [file isdir [file join tfad tfa file]]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1}
+test fCmd-21.12 {TclFileCopyCmd: copy dir on top of a non-empty dir w/ -force} -setup {
+ catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+ file mkdir tfa [file join tfad tfa file]
+ list [catch {file copy -force tfa tfad}] [file isdir tfa] \
+ [file isdir [file join tfad tfa file]]
+} -cleanup {
+ file delete -force tfa tfad
+} -result {1 1 1}
+
+#
+# Coverage testing for TclpRenameFile
+#
+test fCmd-22.1 {TclpRenameFile: rename and overwrite in a single dir} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ set s [createfile tfa1]
+ set s2 [createfile tfa2 q]
+ set result [catch {file rename tfa1 tfa2}]
+ file rename -force tfa1 tfa2
+ lappend result [checkcontent tfa2 $s]
+} -cleanup {
+ file delete [glob tfa1 tfa2]
+} -result {1 1}
+test fCmd-22.2 {TclpRenameFile: attempt to overwrite itself} -setup {
+ catch {file delete -force -- tfa1}
+} -constraints {unix notRoot} -body {
+ set s [createfile tfa1]
+ file rename -force tfa1 tfa1
+ checkcontent tfa1 $s
+} -cleanup {
+ file delete tfa1
+} -result {1}
+test fCmd-22.3 {TclpRenameFile: rename dir to existing dir} -setup {
+ catch {file delete -force -- d1 tfad}
+} -constraints {notRoot} -body {
+ file mkdir d1 [file join tfad d1]
+ list [catch {file rename d1 tfad}] [file isdir d1] \
+ [file isdir [file join tfad d1]]
+} -cleanup {
+ file delete -force d1 tfad
+} -result {1 1 1}
+test fCmd-22.4 {TclpRenameFile: rename dir to dir several levels deep} -setup {
+ catch {file delete -force -- d1 tfad}
+} -constraints {notRoot} -body {
+ file mkdir d1 [file join tfad a b c]
+ file rename d1 [file join tfad a b c d1]
+ list [file isdir d1] [file isdir [file join tfad a b c d1]]
+} -cleanup {
+ file delete -force [glob d1 tfad]
+} -result {0 1}
+#
+# TclMacCopyFile needs to be redone.
+#
+test fCmd-22.5 {TclMacCopyFile: copy and overwrite in a single dir} -setup {
+ catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+ set s [createfile tfa1]
+ set s2 [createfile tfa2 q]
+ set result [catch {file copy tfa1 tfa2}]
+ file copy -force tfa1 tfa2
+ lappend result [checkcontent tfa2 $s] [checkcontent tfa1 $s]
+} -cleanup {
+ file delete tfa1 tfa2
+} -result {1 1 1}
+
+#
+# TclMacMkdir - basic cases are covered elsewhere.
+# Error cases are not covered.
+#
+
+#
+# TclMacRmdir
+# Error cases are not covered.
+#
+test fCmd-23.1 {TclMacRmdir: trying to remove a nonempty directory} -setup {
+ catch {file delete -force -- tfad}
+} -constraints {notRoot} -body {
+ file mkdir [file join tfad dir]
+ list [catch {file delete tfad}] [file delete -force tfad]
+} -cleanup {
+ catch {file delete -force tfad}
+} -result {1 {}}
+
+#
+# TclMacDeleteFile
+# Error cases are not covered.
+#
+test fCmd-24.1 {TclMacDeleteFile: deleting a normal file} -setup {
+ catch {file delete -force -- tfa1}
+} -constraints {notRoot} -body {
+ createfile tfa1
+ file delete tfa1
+ file exists tfa1
+} -cleanup {
+ catch {file delete -force tfa1}
+} -result {0}
+
+#
+# TclMacCopyDirectory
+# Error cases are not covered.
+#
+test fCmd-25.1 {TclMacCopyDirectory: copying a normal directory} -setup {
+ catch {file delete -force -- tfad1 tfad2}
+} -constraints {notRoot notFileSharing} -body {
+ file mkdir [file join tfad1 a b c]
+ file copy tfad1 tfad2
+ list [file isdir [file join tfad1 a b c]] \
+ [file isdir [file join tfad2 a b c]]
+} -cleanup {
+ file delete -force tfad1 tfad2
+} -result {1 1}
+test fCmd-25.2 {TclMacCopyDirectory: copying a short path normal directory} -setup {
+ catch {file delete -force -- tfad1 tfad2}
+} -constraints {notRoot notFileSharing} -body {
+ file mkdir tfad1
+ file copy tfad1 tfad2
+ list [file isdir tfad1] [file isdir tfad2]
+} -cleanup {
+ file delete tfad1 tfad2
+} -result {1 1}
+test fCmd-25.3 {TclMacCopyDirectory: copying dirs between different dirs} -setup {
+ catch {file delete -force -- tfad1 tfad2}
+} -constraints {notRoot notFileSharing} -body {
+ file mkdir [file join tfad1 x y z]
+ file mkdir [file join tfad2 dir]
+ file copy tfad1 [file join tfad2 dir]
+ list [file isdir [file join tfad1 x y z]] \
+ [file isdir [file join tfad2 dir tfad1 x y z]]
+} -cleanup {
+ file delete -force tfad1 tfad2
+} -result {1 1}
+
+#
+# Functionality tests for TclDeleteFilesCmd
+#
+test fCmd-26.1 {TclDeleteFilesCmd: delete symlink} -setup {
+ catch {file delete -force -- tfad1 tfad2}
+} -constraints {unix notRoot} -body {
+ file mkdir tfad1
+ file link -symbolic tfalink tfad1
+ file delete tfalink
+ list [file isdir tfad1] [file exists tfalink]
+} -cleanup {
+ file delete tfad1
+ catch {file delete tfalink}
+} -result {1 0}
+test fCmd-26.2 {TclDeleteFilesCmd: delete dir with symlink} -setup {
+ catch {file delete -force -- tfad1 tfad2}
+} -constraints {unix notRoot} -body {
+ file mkdir tfad1
+ file mkdir tfad2
+ file link -symbolic [file join tfad2 link] [file join .. tfad1]
+ file delete -force tfad2
+ list [file isdir tfad1] [file exists tfad2]
+} -cleanup {
+ file delete tfad1
+} -result {1 0}
+test fCmd-26.3 {TclDeleteFilesCmd: delete dangling symlink} -setup {
+ catch {file delete -force -- tfad1 tfad2}
+} -constraints {unix notRoot} -body {
+ file mkdir tfad1
+ file link -symbolic tfad2 tfad1
+ file delete tfad1
+ file delete tfad2
+ list [file exists tfad1] [file exists tfad2]
+} -result {0 0}
+
+# There is no fCmd-27.1
+test fCmd-27.2 {TclFileAttrsCmd - Tcl_TranslateFileName fails} -setup {
+ set platform [testgetplatform]
+} -constraints {testsetplatform} -body {
+ testsetplatform unix
+ file attributes ~_totally_bogus_user
+} -returnCodes error -cleanup {
+ testsetplatform $platform
+} -result {user "_totally_bogus_user" doesn't exist}
+test fCmd-27.3 {TclFileAttrsCmd - all attributes} -setup {
+ catch {file delete -force -- foo.tmp}
+} -body {
+ createfile foo.tmp
+ file attributes foo.tmp
+ # Must be non-empty result
+} -cleanup {
+ file delete -force -- foo.tmp
+} -match glob -result {?*}
+test fCmd-27.4 {TclFileAttrsCmd - getting one option} -setup {
+ catch {file delete -force -- foo.tmp}
+} -body {
+ createfile foo.tmp
+ set attrs [file attributes foo.tmp]
+ file attributes foo.tmp {*}[lindex $attrs 0]
+ # Any successful result will do
+} -cleanup {
+ file delete -force -- foo.tmp
+} -match glob -result *
+test fCmd-27.5 {TclFileAttrsCmd - setting one option} -setup {
+ catch {file delete -force -- foo.tmp}
+} -constraints {foundGroup} -body {
+ createfile foo.tmp
+ set attrs [file attributes foo.tmp]
+ file attributes foo.tmp {*}[lrange $attrs 0 1]
+} -cleanup {
+ file delete -force -- foo.tmp
+} -result {}
+test fCmd-27.6 {TclFileAttrsCmd - setting more than one option} -setup {
+ catch {file delete -force -- foo.tmp}
+} -constraints {foundGroup} -body {
+ createfile foo.tmp
+ set attrs [file attributes foo.tmp]
+ file attributes foo.tmp {*}[lrange $attrs 0 3]
+} -cleanup {
+ file delete -force -- foo.tmp
+} -result {}
+
+if {
+ [testConstraint win] &&
+ ([string index $tcl_platform(osVersion) 0] < 5
+ || [lindex [file system [temporaryDirectory]] 1] ne "NTFS")
+} then {
+ testConstraint linkDirectory 0
+ testConstraint linkFile 0
+}
+
+test fCmd-28.1 {file link} -returnCodes error -body {
+ file link
+} -result {wrong # args: should be "file link ?-linktype? linkname ?target?"}
+test fCmd-28.2 {file link} -returnCodes error -body {
+ file link a b c d
+} -result {wrong # args: should be "file link ?-linktype? linkname ?target?"}
+test fCmd-28.3 {file link} -returnCodes error -body {
+ file link abc b c
+} -result {bad switch "abc": must be -symbolic or -hard}
+test fCmd-28.4 {file link} -returnCodes error -body {
+ file link -abc b c
+} -result {bad switch "-abc": must be -symbolic or -hard}
+cd [workingDirectory]
+makeDirectory abc.dir
+makeDirectory abc2.dir
+makeFile contents abc.file
+makeFile contents abc2.file
+cd [temporaryDirectory]
+test fCmd-28.5 {file link: source already exists} -setup {
+ cd [temporaryDirectory]
+} -constraints {linkDirectory} -body {
+ file link abc.dir abc2.dir
+} -returnCodes error -cleanup {
+ cd [workingDirectory]
+} -result {could not create new link "abc.dir": that path already exists}
+test fCmd-28.6 {file link: unsupported operation} -setup {
+ cd [temporaryDirectory]
+} -constraints {linkDirectory win} -body {
+ file link -hard abc.link abc.dir
+} -returnCodes error -cleanup {
+ cd [workingDirectory]
+} -result {could not create new link "abc.link" pointing to "abc.dir": illegal operation on a directory}
+test fCmd-28.7 {file link: source already exists} -setup {
+ cd [temporaryDirectory]
+} -constraints {linkFile} -body {
+ file link abc.file abc2.file
+} -returnCodes error -cleanup {
+ cd [workingDirectory]
+} -result {could not create new link "abc.file": that path already exists}
+test fCmd-28.8 {file link} -constraints {linkFile win} -setup {
+ cd [temporaryDirectory]
+} -body {
+ file link -symbolic abc.link abc.file
+} -returnCodes error -cleanup {
+ cd [workingDirectory]
+} -result {could not create new link "abc.link" pointing to "abc.file": not a directory}
+test fCmd-28.9 {file link: success with file} -constraints {linkFile} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -body {
+ file link abc.link abc.file
+} -cleanup {
+ cd [workingDirectory]
+} -result abc.file
+test fCmd-28.9.1 {file link: success with file} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -constraints {linkFile win} -body {
+ file stat abc.file arr
+ set res $arr(nlink)
+ lappend res [catch {file link abc.link abc.file} msg] $msg
+ file stat abc.file arr
+ lappend res $arr(nlink)
+} -cleanup {
+ cd [workingDirectory]
+} -result {1 0 abc.file 2}
+cd [temporaryDirectory]
+catch {file delete -force abc.link}
+cd [workingDirectory]
+test fCmd-28.10 {file link: linking to nonexistent path} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -constraints {linkDirectory} -body {
+ file link abc.link abc2.doesnt
+} -returnCodes error -cleanup {
+ cd [workingDirectory]
+} -result {could not create new link "abc.link": target "abc2.doesnt" doesn't exist}
+test fCmd-28.10.1 {file link: linking to nonexistent path} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -constraints {linkDirectory} -body {
+ file link doesnt/abc.link abc.dir
+} -returnCodes error -cleanup {
+ cd [workingDirectory]
+} -result {could not create new link "doesnt/abc.link": no such file or directory}
+test fCmd-28.11 {file link: success with directory} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -constraints {linkDirectory} -body {
+ file link abc.link abc.dir
+} -cleanup {
+ cd [workingDirectory]
+} -result abc.dir
+test fCmd-28.12 {file link: cd into a link} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -constraints {linkDirectory} -body {
+ file link abc.link abc.dir
+ set orig [pwd]
+ cd abc.link
+ set dir [pwd]
+ cd ..
+ set up [pwd]
+ cd $orig
+ # Now '$up' should be either $orig or [file dirname abc.dir], depending on
+ # whether 'cd' actually moves to the destination of a link, or simply
+ # treats the link as a directory. (On windows the former, on unix the
+ # latter, I believe)
+ if {
+ ([file normalize $up] ne [file normalize $orig]) &&
+ ([file normalize $up] ne [file normalize [file dirname abc.dir]])
+ } then {
+ return "wrong directory with 'cd abc.link ; cd ..': \
+ \"[file normalize $up]\" should be \"[file normalize $orig]\"\
+ or \"[file normalize [file dirname abc.dir]]\""
+ } else {
+ return "ok"
+ }
+} -cleanup {
+ cd [workingDirectory]
+} -result ok
+test fCmd-28.13 {file link} -constraints {linkDirectory} -setup {
+ cd [temporaryDirectory]
+} -body {
+ # duplicate link throws error
+ file link abc.link abc.dir
+} -returnCodes error -cleanup {
+ cd [workingDirectory]
+} -result {could not create new link "abc.link": that path already exists}
+test fCmd-28.14 {file link: deletes link not dir} -setup {
+ cd [temporaryDirectory]
+} -constraints {linkDirectory} -body {
+ file delete -force abc.link
+ list [file exists abc.link] [file exists abc.dir]
+} -cleanup {
+ cd [workingDirectory]
+} -result {0 1}
+test fCmd-28.15.1 {file link: copies link not dir} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -constraints {linkDirectory dontCopyLinks} -body {
+ file link abc.link abc.dir
+ file copy abc.link abc2.link
+ # abc2.linkdir was a copy of a link to a dir, so it should end up as a
+ # directory, not a link (links trace to endpoint).
+ list [file type abc2.link] [file tail [file link abc.link]]
+} -cleanup {
+ cd [workingDirectory]
+} -result {directory abc.dir}
+test fCmd-28.15.2 {file link: copies link not dir} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -constraints {linkDirectory} -body {
+ file link abc.link abc.dir
+ file copy abc.link abc2.link
+ list [file type abc2.link] [file tail [file link abc2.link]]
+} -cleanup {
+ cd [workingDirectory]
+} -result {link abc.dir}
+cd [temporaryDirectory]
+file delete -force abc.link
+file delete -force abc2.link
+cd abc.dir
+file delete -force abc.file
+file delete -force abc2.file
+cd ..
+file copy abc.file abc.dir
+file copy abc2.file abc.dir
+cd [workingDirectory]
+test fCmd-28.16 {file link: glob inside link} -setup {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+} -constraints {linkDirectory} -body {
+ file link abc.link abc.dir
+ lsort [glob -dir abc.link -tails *]
+} -cleanup {
+ cd [workingDirectory]
+} -result {abc.file abc2.file}
+test fCmd-28.17 {file link: glob -type l} -setup {
+ cd [temporaryDirectory]
+} -constraints {linkDirectory} -body {
+ glob -dir [pwd] -type l -tails abc*
+} -cleanup {
+ cd [workingDirectory]
+} -result {abc.link}
+test fCmd-28.18 {file link: glob -type d} -constraints linkDirectory -setup {
+ cd [temporaryDirectory]
+} -body {
+ lsort [glob -dir [pwd] -type d -tails abc*]
+} -cleanup {
+ cd [workingDirectory]
+} -result [lsort [list abc.link abc.dir abc2.dir]]
+test fCmd-28.19 {file link: relative paths} -setup {
+ cd [temporaryDirectory]
+} -constraints {win linkDirectory} -body {
+ file mkdir d1/d2/d3
+ file link d1/l2 d1/d2
+} -cleanup {
+ catch {file delete -force d1}
+ cd [workingDirectory]
+} -result d1/d2
+test fCmd-28.20 {file link: relative paths} -setup {
+ cd [temporaryDirectory]
+} -constraints {unix linkDirectory} -body {
+ file mkdir d1/d2/d3
+ file link d1/l2 d1/d2
+} -returnCodes error -cleanup {
+ catch {file delete -force d1}
+ cd [workingDirectory]
+} -result {could not create new link "d1/l2": target "d1/d2" doesn't exist}
+test fCmd-28.21 {file link: relative paths} -setup {
+ cd [temporaryDirectory]
+} -constraints {unix linkDirectory} -body {
+ file mkdir d1/d2/d3
+ file link d1/l2 d2
+} -cleanup {
+ catch {file delete -force d1}
+ cd [workingDirectory]
+} -result d2
+test fCmd-28.22 {file link: relative paths} -setup {
+ cd [temporaryDirectory]
+} -constraints {unix linkDirectory} -body {
+ file mkdir d1/d2/d3
+ catch {file delete -force d1/l2}
+ file link d1/l2 d2/d3
+} -cleanup {
+ catch {file delete -force d1}
+ cd [workingDirectory]
+} -result d2/d3
+try {
+ cd [temporaryDirectory]
+ file delete -force abc.link
+ file delete -force d1/d2
+ file delete -force d1
+} finally {
+ cd [workingDirectory]
+}
+removeFile abc2.file
+removeFile abc.file
+removeDirectory abc2.dir
+removeDirectory abc.dir
+
+test fCmd-29.1 {weird memory corruption fault} -body {
+ open [file join ~a_totally_bogus_user_id/foo bar]
+} -returnCodes error -match glob -result *
+
+test fCmd-30.1 {file writable on 'My Documents'} -setup {
+ # Get the localized version of the folder name by looking in the registry.
+ set mydocsname [registry get {HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders} Personal]
+} -constraints {win reg} -body {
+ file writable $mydocsname
+} -result 1
+test fCmd-30.2 {file readable on 'NTUSER.DAT'} -constraints {win} -body {
+ expr {[info exists env(USERPROFILE)]
+ && [file exists $env(USERPROFILE)/NTUSER.DAT]
+ && [file readable $env(USERPROFILE)/NTUSER.DAT]}
+} -result {1}
+test fCmd-30.3 {file readable on 'pagefile.sys'} -constraints {win} -body {
+ set r {}
+ if {[info exists env(SystemDrive)]} {
+ set path $env(SystemDrive)/pagefile.sys
+ lappend r exists [file exists $path]
+ lappend r readable [file readable $path]
+ lappend r stat [catch {file stat $path a} e] $e
+ }
+ return $r
+} -result {exists 1 readable 0 stat 0 {}}
+
+# cleanup
+cleanup
+if {[testConstraint unix]} {
+ removeDirectory tcl[pid] /tmp
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/fileName.test b/pkgs/msgcat/tests/fileName.test
new file mode 100644
index 0000000..affacff
--- /dev/null
+++ b/pkgs/msgcat/tests/fileName.test
@@ -0,0 +1,1627 @@
+# This file tests the filename manipulation routines.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testsetplatform [llength [info commands testsetplatform]]
+testConstraint testtranslatefilename [llength [info commands testtranslatefilename]]
+testConstraint linkDirectory 1
+testConstraint symbolicLinkFile 1
+if {[testConstraint win]} {
+ if {[string index $tcl_platform(osVersion) 0] < 5 \
+ || [lindex [file system [temporaryDirectory]] 1] ne "NTFS"} {
+ testConstraint linkDirectory 0
+ }
+ testConstraint symbolicLinkFile 0
+ testConstraint sharedCdrive [expr {![catch {cd //[info hostname]/c}]}]
+}
+# This match compares the first two words of the result. If the wanted result
+# is "equal", then this is successful if the words are equal. If the wanted
+# result is "not equal", then this is successful if the words are different.
+customMatch compareWords {apply {{a b} {
+ lassign $b w1 w2
+ expr {$a eq "equal" ? $w1 eq $w2 : $w1 ne $w2}
+}}}
+
+proc touch filename {catch {close [open $filename w]}}
+global env
+if {[testConstraint testsetplatform]} {
+ set platform [testgetplatform]
+}
+
+# Caution: when using 'testsetplatform' to test different file name platform
+# descriptions in this file, one must be very careful not to combine such
+# platform manipulation with commands like 'cd', 'pwd'. That is because the
+# latter commands operate on the real filesystem but will potentially have
+# their logic routed through the wrong generic code paths if we've used
+# 'testsetplatform'. This can lead to serious problems, even crashes.
+test filename-1.1 {Tcl_GetPathType: unix} {testsetplatform} {
+ testsetplatform unix
+ file pathtype /
+} absolute
+test filename-1.2 {Tcl_GetPathType: unix} {testsetplatform} {
+ testsetplatform unix
+ file pathtype /foo
+} absolute
+test filename-1.3 {Tcl_GetPathType: unix} {testsetplatform} {
+ testsetplatform unix
+ file pathtype foo
+} relative
+test filename-1.4 {Tcl_GetPathType: unix} {testsetplatform} {
+ testsetplatform unix
+ file pathtype c:/foo
+} relative
+test filename-1.5 {Tcl_GetPathType: unix} {testsetplatform} {
+ testsetplatform unix
+ file pathtype ~
+} absolute
+test filename-1.6 {Tcl_GetPathType: unix} {testsetplatform} {
+ testsetplatform unix
+ file pathtype ~/foo
+} absolute
+test filename-1.7 {Tcl_GetPathType: unix} {testsetplatform} {
+ testsetplatform unix
+ file pathtype ~foo
+} absolute
+test filename-1.8 {Tcl_GetPathType: unix} {testsetplatform} {
+ testsetplatform unix
+ file pathtype ./~foo
+} relative
+
+test filename-3.1 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype /
+} volumerelative
+test filename-3.2 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype \\
+} volumerelative
+test filename-3.3 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype /foo
+} volumerelative
+test filename-3.4 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype \\foo
+} volumerelative
+test filename-3.5 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype c:/
+} absolute
+test filename-3.6 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype c:\\
+} absolute
+test filename-3.7 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype c:/foo
+} absolute
+test filename-3.8 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype c:\\foo
+} absolute
+test filename-3.9 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype c:
+} volumerelative
+test filename-3.10 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype c:foo
+} volumerelative
+test filename-3.11 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype foo
+} relative
+test filename-3.12 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype //foo/bar
+} absolute
+test filename-3.13 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype ~foo
+} absolute
+test filename-3.14 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype ~
+} absolute
+test filename-3.15 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype ~/foo
+} absolute
+test filename-3.16 {Tcl_GetPathType: windows} {testsetplatform} {
+ testsetplatform windows
+ file pathtype ./~foo
+} relative
+
+test filename-4.1 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split /
+} {/}
+test filename-4.2 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split /foo
+} {/ foo}
+test filename-4.3 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split /foo/bar
+} {/ foo bar}
+test filename-4.4 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split /foo/bar/baz
+} {/ foo bar baz}
+test filename-4.5 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split foo/bar
+} {foo bar}
+test filename-4.6 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split ./foo/bar
+} {. foo bar}
+test filename-4.7 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split /foo/../././foo/bar
+} {/ foo .. . . foo bar}
+test filename-4.8 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split ../foo/bar
+} {.. foo bar}
+test filename-4.9 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split {}
+} {}
+test filename-4.10 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split .
+} {.}
+test filename-4.11 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split ../
+} {..}
+test filename-4.12 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split ../..
+} {.. ..}
+test filename-4.13 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split //foo
+} {/ foo}
+test filename-4.14 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split foo//bar
+} {foo bar}
+test filename-4.15 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split ~foo
+} {~foo}
+test filename-4.16 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split ~foo/~bar
+} {~foo ./~bar}
+test filename-4.17 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split ~foo/~bar/~baz
+} {~foo ./~bar ./~baz}
+test filename-4.18 {Tcl_SplitPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file split foo/bar~/baz
+} {foo bar~ baz}
+if {[testConstraint testsetplatform]} {
+ testsetplatform $platform
+}
+test filename-4.19 {Tcl_SplitPath} -setup {
+ set oldDir [pwd]
+ cd [temporaryDirectory]
+} -body {
+ file mkdir tildetmp
+ set nastydir [file join tildetmp ./~tilde]
+ file mkdir $nastydir
+ set norm [file normalize $nastydir]
+ cd tildetmp
+ cd ./~tilde
+ glob -nocomplain *
+ set idx [string first tildetmp $norm]
+ set norm [string range $norm $idx end]
+ # fix path away so all platforms are the same
+ regsub {(.*):$} $norm {\1} norm
+ regsub -all ":" $norm "/" norm
+ # make sure we can delete the directory we created
+ cd $oldDir
+ file delete -force $nastydir
+ return $norm
+} -cleanup {
+ cd $oldDir
+ catch {file delete -force [file join [temporaryDirectory] tildetmp]}
+} -result {tildetmp/~tilde}
+
+test filename-6.1 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split /
+} {/}
+test filename-6.2 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split /foo
+} {/ foo}
+test filename-6.3 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split /foo/bar
+} {/ foo bar}
+test filename-6.4 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split /foo/bar/baz
+} {/ foo bar baz}
+test filename-6.5 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split foo/bar
+} {foo bar}
+test filename-6.6 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split ./foo/bar
+} {. foo bar}
+test filename-6.7 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split /foo/../././foo/bar
+} {/ foo .. . . foo bar}
+test filename-6.8 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split ../foo/bar
+} {.. foo bar}
+test filename-6.9 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split {}
+} {}
+test filename-6.10 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split .
+} {.}
+test filename-6.11 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split ../
+} {..}
+test filename-6.12 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split ../..
+} {.. ..}
+test filename-6.13 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split //foo
+} {/ foo}
+test filename-6.14 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split foo//bar
+} {foo bar}
+test filename-6.15 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split /\\/foo//bar
+} {//foo/bar}
+test filename-6.16 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split /\\/foo//bar
+} {//foo/bar}
+test filename-6.17 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split /\\/foo//bar
+} {//foo/bar}
+test filename-6.18 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split \\\\foo\\bar
+} {//foo/bar}
+test filename-6.19 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split \\\\foo\\bar/baz
+} {//foo/bar baz}
+test filename-6.20 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split c:/foo
+} {c:/ foo}
+test filename-6.21 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split c:foo
+} {c: foo}
+test filename-6.22 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split c:
+} {c:}
+test filename-6.23 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split c:\\
+} {c:/}
+test filename-6.24 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split c:/
+} {c:/}
+test filename-6.25 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split c:/./..
+} {c:/ . ..}
+test filename-6.26 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split ~foo
+} {~foo}
+test filename-6.27 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split ~foo/~bar
+} {~foo ./~bar}
+test filename-6.28 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split ~foo/~bar/~baz
+} {~foo ./~bar ./~baz}
+test filename-6.29 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split foo/bar~/baz
+} {foo bar~ baz}
+test filename-6.30 {Tcl_SplitPath: win} {testsetplatform} {
+ testsetplatform win
+ file split c:~foo
+} {c: ./~foo}
+
+test filename-7.1 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join / a
+} {/a}
+test filename-7.2 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join a b
+} {a/b}
+test filename-7.3 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join /a c /b d
+} {/b/d}
+test filename-7.4 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join /
+} {/}
+test filename-7.5 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join a
+} {a}
+test filename-7.6 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join {}
+} {}
+test filename-7.7 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join /a/ b
+} {/a/b}
+test filename-7.8 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join /a// b
+} {/a/b}
+test filename-7.9 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join /a/./../. b
+} {/a/./.././b}
+test filename-7.10 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join ~ a
+} {~/a}
+test filename-7.11 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join ~a ~b
+} {~b}
+test filename-7.12 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join ./~a b
+} {./~a/b}
+test filename-7.13 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join ./~a ~b
+} {~b}
+test filename-7.14 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join ./~a ./~b
+} {./~a/~b}
+test filename-7.15 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join a . b
+} {a/./b}
+test filename-7.16 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join a . ./~b
+} {a/./~b}
+test filename-7.17 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join //a b
+} {/a/b}
+test filename-7.18 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ file join /// a b
+} {/a/b}
+
+test filename-9.1 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join a b
+} {a/b}
+test filename-9.2 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join /a b
+} {/a/b}
+test filename-9.3 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join /a /b
+} {/b}
+test filename-9.4 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join c: foo
+} {c:foo}
+test filename-9.5 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join c:/ foo
+} {c:/foo}
+test filename-9.6 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join c:\\bar foo
+} {c:/bar/foo}
+test filename-9.7 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join /foo c:bar
+} {c:bar}
+test filename-9.8 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join ///host//share dir
+} {//host/share/dir}
+test filename-9.9 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join ~ foo
+} {~/foo}
+test filename-9.10 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join ~/~foo
+} {~/~foo}
+test filename-9.11 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join ~ ./~foo
+} {~/~foo}
+test filename-9.12 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join / ~foo
+} {~foo}
+test filename-9.13 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join ./a/ b c
+} {./a/b/c}
+test filename-9.14 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join ./~a/ b c
+} {./~a/b/c}
+test filename-9.15 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join // host share path
+} {/host/share/path}
+test filename-9.16 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join foo . bar
+} {foo/./bar}
+test filename-9.17 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join foo .. bar
+} {foo/../bar}
+test filename-9.18 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ file join foo/./bar
+} {foo/./bar}
+test filename-9.19 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ set res {}
+ lappend res \
+ [file join {C:\foo\bar}] \
+ [file join C:/blah {C:\foo\bar}] \
+ [file join C:/blah C:/blah {C:\foo\bar}]
+} {C:/foo/bar C:/foo/bar C:/foo/bar}
+test filename-9.19.1 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ set res {}
+ lappend res \
+ [file join {foo\bar}] \
+ [file join C:/blah {foo\bar}] \
+ [file join C:/blah C:/blah {foo\bar}]
+} {foo/bar C:/blah/foo/bar C:/blah/foo/bar}
+test filename-9.19.2 {Tcl_JoinPath: win} {testsetplatform win} {
+ testsetplatform win
+ set res {}
+ lappend res \
+ [file join {foo\bar}] \
+ [file join [pwd] {foo\bar}] \
+ [file join [pwd] [pwd] {foo\bar}]
+ set nres {}
+ foreach elt $res {
+ lappend nres [string map [list [pwd] pwd] $elt]
+ }
+ set nres
+} {foo/bar pwd/foo/bar pwd/foo/bar}
+test filename-9.20 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ set res {}
+ lappend res \
+ [file join {/foo/bar}] \
+ [file join /x {/foo/bar}] \
+ [file join /x /x {/foo/bar}]
+} {/foo/bar /foo/bar /foo/bar}
+test filename-9.23 {Tcl_JoinPath: win} {testsetplatform} {
+ testsetplatform win
+ set res {}
+ lappend res \
+ [file join {foo\bar}] \
+ [file join C:/blah {foo\bar}] \
+ [file join C:/blah C:/blah {foo\bar}]
+ string map [list C:/blah ""] $res
+} {foo/bar /foo/bar /foo/bar}
+test filename-9.24 {Tcl_JoinPath: unix} {testsetplatform} {
+ testsetplatform unix
+ set res {}
+ lappend res \
+ [file join {foo/bar}] \
+ [file join /x {foo/bar}] \
+ [file join /x /x {foo/bar}]
+ string map [list /x ""] $res
+} {foo/bar /foo/bar /foo/bar}
+
+test filename-10.1 {Tcl_TranslateFileName} -body {
+ testsetplatform unix
+ testtranslatefilename foo
+} -result {foo} -constraints {testsetplatform testtranslatefilename}
+test filename-10.2 {Tcl_TranslateFileName} -body {
+ testsetplatform windows
+ testtranslatefilename {c:/foo}
+} -result {c:\foo} -constraints {testsetplatform testtranslatefilename}
+test filename-10.3 {Tcl_TranslateFileName} -body {
+ testsetplatform windows
+ testtranslatefilename {c:/\\foo/}
+} -result {c:\foo} -constraints {testsetplatform testtranslatefilename}
+test filename-10.3.1 {Tcl_TranslateFileName} -body {
+ testsetplatform windows
+ testtranslatefilename {c://///}
+} -result c:\\ -constraints {testsetplatform testtranslatefilename}
+test filename-10.6 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ set env(HOME) "/home/test"
+ testsetplatform unix
+ testtranslatefilename ~/foo
+} -cleanup {
+ set env(HOME) $temp
+} -result {/home/test/foo}
+test filename-10.7 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ unset env(HOME)
+ testsetplatform unix
+ testtranslatefilename ~/foo
+} -returnCodes error -cleanup {
+ set env(HOME) $temp
+} -result {couldn't find HOME environment variable to expand path}
+test filename-10.8 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ set env(HOME) "/home/test"
+ testsetplatform unix
+ testtranslatefilename ~
+} -cleanup {
+ set env(HOME) $temp
+} -result {/home/test}
+test filename-10.9 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ set env(HOME) "/home/test/"
+ testsetplatform unix
+ testtranslatefilename ~
+} -cleanup {
+ set env(HOME) $temp
+} -result {/home/test}
+test filename-10.10 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ set env(HOME) "/home/test/"
+ testsetplatform unix
+ testtranslatefilename ~/foo
+} -cleanup {
+ set env(HOME) $temp
+} -result {/home/test/foo}
+test filename-10.17 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ set env(HOME) "\\home\\"
+ testsetplatform windows
+ testtranslatefilename ~/foo
+} -cleanup {
+ set env(HOME) $temp
+} -result {\home\foo}
+test filename-10.18 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ set env(HOME) "\\home\\"
+ testsetplatform windows
+ testtranslatefilename ~/foo\\bar
+} -cleanup {
+ set env(HOME) $temp
+} -result {\home\foo\bar}
+test filename-10.19 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ set env(HOME) "c:"
+ testsetplatform windows
+ testtranslatefilename ~/foo
+} -cleanup {
+ set env(HOME) $temp
+} -result {c:foo}
+test filename-10.20 {Tcl_TranslateFileName} -returnCodes error -body {
+ testtranslatefilename ~blorp/foo
+} -constraints {testtranslatefilename testtranslatefilename} \
+ -result {user "blorp" doesn't exist}
+test filename-10.21 {Tcl_TranslateFileName} -setup {
+ global env
+ set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+ set env(HOME) "c:\\"
+ testsetplatform windows
+ testtranslatefilename ~/foo
+} -cleanup {
+ set env(HOME) $temp
+} -result {c:\foo}
+test filename-10.22 {Tcl_TranslateFileName} -body {
+ testsetplatform windows
+ testtranslatefilename foo//bar
+} -constraints {testsetplatform testtranslatefilename} -result {foo\bar}
+if {[testConstraint testsetplatform]} {
+ testsetplatform $platform
+}
+test filename-10.23 {Tcl_TranslateFileName} -body {
+ # this test fails if ~ouster is not /home/ouster
+ testtranslatefilename ~ouster
+} -constraints {nonPortable testtranslatefilename} -result {/home/ouster}
+test filename-10.24 {Tcl_TranslateFileName} -body {
+ # this test fails if ~ouster is not /home/ouster
+ testtranslatefilename ~ouster/foo
+} -result {/home/ouster/foo} -constraints {nonPortable testtranslatefilename}
+
+test filename-11.1 {Tcl_GlobCmd} -returnCodes error -body {
+ glob
+} -result {no files matched glob patterns ""}
+test filename-11.2 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -gorp
+} -result {bad option "-gorp": must be -directory, -join, -nocomplain, -path, -tails, -types, or --}
+test filename-11.3 {Tcl_GlobCmd} -body {
+ glob -nocomplai
+} -result {}
+test filename-11.4 {Tcl_GlobCmd} -body {
+ glob -nocomplain
+} -result {}
+test filename-11.5 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -nocomplain * ~xyqrszzz
+} -result {user "xyqrszzz" doesn't exist}
+test filename-11.6 {Tcl_GlobCmd} -returnCodes error -body {
+ glob ~xyqrszzz
+} -result {user "xyqrszzz" doesn't exist}
+test filename-11.7 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -- -nocomplain
+} -result {no files matched glob pattern "-nocomplain"}
+test filename-11.8 {Tcl_GlobCmd} -body {
+ glob -nocomplain -- -nocomplain
+} -result {}
+test filename-11.9 {Tcl_GlobCmd} -constraints {testsetplatform} -body {
+ testsetplatform unix
+ glob ~\\xyqrszzz/bar
+} -returnCodes error -result {user "\xyqrszzz" doesn't exist}
+test filename-11.10 {Tcl_GlobCmd} -constraints {testsetplatform} -body {
+ testsetplatform unix
+ glob -nocomplain ~\\xyqrszzz/bar
+} -returnCodes error -result {user "\xyqrszzz" doesn't exist}
+test filename-11.11 {Tcl_GlobCmd} -constraints {testsetplatform} -body {
+ testsetplatform unix
+ glob ~xyqrszzz\\/\\bar
+} -returnCodes error -result {user "xyqrszzz" doesn't exist}
+test filename-11.12 {Tcl_GlobCmd} -constraints {testsetplatform} -setup {
+ testsetplatform unix
+ set home $env(HOME)
+} -body {
+ unset env(HOME)
+ glob ~/*
+} -returnCodes error -cleanup {
+ set env(HOME) $home
+} -result {couldn't find HOME environment variable to expand path}
+if {[testConstraint testsetplatform]} {
+ testsetplatform $platform
+}
+test filename-11.13 {Tcl_GlobCmd} {
+ file join [lindex [glob ~] 0]
+} [file join $env(HOME)]
+set oldpwd [pwd]
+set oldhome $env(HOME)
+cd [temporaryDirectory]
+set env(HOME) [pwd]
+file delete -force globTest
+file mkdir globTest/a1/b1
+file mkdir globTest/a1/b2
+file mkdir globTest/a2/b3
+file mkdir globTest/a3
+touch globTest/x1.c
+touch globTest/y1.c
+touch globTest/z1.c
+touch "globTest/weird name.c"
+touch globTest/a1/b1/x2.c
+touch globTest/a1/b2/y2.c
+touch globTest/.1
+touch globTest/x,z1.c
+test filename-11.14 {Tcl_GlobCmd} {
+ glob ~/globTest
+} [list [file join $env(HOME) globTest]]
+test filename-11.15 {Tcl_GlobCmd} {
+ glob ~\\/globTest
+} [list [file join $env(HOME) globTest]]
+test filename-11.16 {Tcl_GlobCmd} {
+ glob globTest
+} {globTest}
+set globname "globTest"
+set horribleglobname "glob\[\{Test"
+test filename-11.17 {Tcl_GlobCmd} {unix} {
+ lsort [glob -directory $globname *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.17.1 {Tcl_GlobCmd} {win} {
+ lsort [glob -directory $globname *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname .1]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.17.2 {Tcl_GlobCmd} -setup {
+ set dir [pwd]
+} -constraints {notRoot linkDirectory} -body {
+ cd $globname
+ file link -symbolic link a1
+ cd $dir
+ lsort [glob -directory $globname -join * b1]
+} -cleanup {
+ cd $dir
+ file delete [file join $globname link]
+} -result [list [file join $globname a1 b1] \
+ [file join $globname link b1]]
+# Simpler version of the above test to illustrate a given bug.
+test filename-11.17.3 {Tcl_GlobCmd} -setup {
+ set dir [pwd]
+} -constraints {notRoot linkDirectory} -body {
+ cd $globname
+ file link -symbolic link a1
+ cd $dir
+ lsort [glob -directory $globname -type d *]
+} -cleanup {
+ cd $dir
+ file delete [file join $globname link]
+} -result [list [file join $globname a1] \
+ [file join $globname a2] \
+ [file join $globname a3] \
+ [file join $globname link]]
+# Make sure the bugfix isn't too simple. We don't want to break 'glob -type l'
+test filename-11.17.4 {Tcl_GlobCmd} -setup {
+ set dir [pwd]
+} -constraints {notRoot linkDirectory} -body {
+ cd $globname
+ file link -symbolic link a1
+ cd $dir
+ lsort [glob -directory $globname -type l *]
+} -cleanup {
+ cd $dir
+ file delete [file join $globname link]
+} -result [list [file join $globname link]]
+test filename-11.17.5 {Tcl_GlobCmd} {
+ lsort [glob -directory $globname -tails *.c]
+} [lsort [list "weird name.c" x,z1.c x1.c y1.c z1.c]]
+test filename-11.17.6 {Tcl_GlobCmd} {
+ lsort [glob -directory $globname -tails *.c *.c]
+} [lsort [concat [list "weird name.c" x,z1.c x1.c y1.c z1.c] \
+ [list "weird name.c" x,z1.c x1.c y1.c z1.c]]]
+test filename-11.17.7 {Tcl_GlobCmd: broken link and glob -l} -setup {
+ set dir [pwd]
+} -constraints {linkDirectory} -body {
+ cd $globname
+ file mkdir nonexistent
+ file link -symbolic link nonexistent
+ file delete nonexistent
+ cd $dir
+ lsort [glob -nocomplain -directory $globname -type l *]
+} -cleanup {
+ cd $dir
+ file delete [file join $globname link]
+} -result [list [file join $globname link]]
+test filename-11.17.8 {Tcl_GlobCmd: broken link and glob -l} -setup {
+ set dir [pwd]
+} -constraints {symbolicLinkFile} -body {
+ cd $globname
+ touch "nonexistent"
+ file link -symbolic link nonexistent
+ file delete nonexistent
+ cd $dir
+ lsort [glob -nocomplain -directory $globname -type l *]
+} -cleanup {
+ cd $dir
+ file delete [file join $globname link]
+} -result [list [file join $globname link]]
+test filename-11.18 {Tcl_GlobCmd} {unix} {
+ lsort [glob -path $globname/ *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.18.1 {Tcl_GlobCmd} {win} {
+ lsort [glob -path $globname/ *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname .1]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.19 {Tcl_GlobCmd} {unix} {
+ lsort [glob -join -path [string range $globname 0 5] * *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.19.1 {Tcl_GlobCmd} {win} {
+ lsort [glob -join -path [string range $globname 0 5] * *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname .1]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.20 {Tcl_GlobCmd} {
+ lsort [glob -type d -dir $globname *]
+} [lsort [list [file join $globname a1]\
+ [file join $globname a2]\
+ [file join $globname a3]]]
+test filename-11.21 {Tcl_GlobCmd} {
+ lsort [glob -type d -path $globname *]
+} [list $globname]
+test filename-11.21.1 {Tcl_GlobCmd} -body {
+ touch {[tcl].testremains}
+ lsort [glob -path {[tcl]} *]
+} -cleanup {
+ file delete -force {[tcl].testremains}
+} -result {{[tcl].testremains}}
+# Get rid of file/dir if it exists, since it will have been left behind by a
+# previous failed run.
+if {[file exists $horribleglobname]} {
+ file delete -force $horribleglobname
+}
+file rename globTest $horribleglobname
+set globname $horribleglobname
+test filename-11.22 {Tcl_GlobCmd} {unix} {
+ lsort [glob -dir $globname *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.22.1 {Tcl_GlobCmd} {win} {
+ lsort [glob -dir $globname *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname .1]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.23 {Tcl_GlobCmd} {unix} {
+ lsort [glob -path $globname/ *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.23.1 {Tcl_GlobCmd} {win} {
+ lsort [glob -path $globname/ *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname .1]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.24 {Tcl_GlobCmd} {unix} {
+ lsort [glob -join -path [string range $globname 0 5] * *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.24.1 {Tcl_GlobCmd} {win} {
+ lsort [glob -join -path [string range $globname 0 5] * *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+ [file join $globname .1]\
+ [file join $globname a3]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.25 {Tcl_GlobCmd} {
+ lsort [glob -type d -dir $globname *]
+} [lsort [list [file join $globname a1]\
+ [file join $globname a2]\
+ [file join $globname a3]]]
+test filename-11.25.1 {Tcl_GlobCmd} {
+ lsort [glob -type {d r} -dir $globname *]
+} [lsort [list [file join $globname a1]\
+ [file join $globname a2]\
+ [file join $globname a3]]]
+test filename-11.25.2 {Tcl_GlobCmd} {
+ lsort [glob -type {d r w} -dir $globname *]
+} [lsort [list [file join $globname a1]\
+ [file join $globname a2]\
+ [file join $globname a3]]]
+test filename-11.26 {Tcl_GlobCmd} {
+ glob -type d -path $globname *
+} [list $globname]
+test filename-11.27 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types abcde *
+} -result {bad argument to "-types": abcde}
+test filename-11.28 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types z *
+} -result {bad argument to "-types": z}
+test filename-11.29 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types {abcd efgh} *
+} -result {only one MacOS type or creator argument to "-types" allowed}
+test filename-11.30 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types {{macintosh type TEXT} {macintosh creator ALFA} efgh} *
+} -result {only one MacOS type or creator argument to "-types" allowed}
+test filename-11.31 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types
+} -result {missing argument to "-types"}
+test filename-11.32 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -path hello -dir hello *
+} -result {"-directory" cannot be used with "-path"}
+test filename-11.33 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -path
+} -result {missing argument to "-path"}
+test filename-11.34 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -direct
+} -result {missing argument to "-directory"}
+test filename-11.35 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -paths *
+} -result {bad option "-paths": must be -directory, -join, -nocomplain, -path, -tails, -types, or --}
+# Test '-tails' flag to glob.
+test filename-11.36 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -tails *
+} -result {"-tails" must be used with either "-directory" or "-path"}
+test filename-11.37 {Tcl_GlobCmd} {
+ glob -type d -tails -path $globname *
+} [list $globname]
+test filename-11.38 {Tcl_GlobCmd} {
+ glob -tails -path $globname *
+} [list $globname]
+test filename-11.39 {Tcl_GlobCmd} {
+ glob -tails -join -path $globname *
+} [list $globname]
+test filename-11.40 {Tcl_GlobCmd} -body {
+ list [glob -dir [pwd] -tails *] [glob *]
+} -match compareWords -result equal
+test filename-11.41 {Tcl_GlobCmd} -body {
+ list [glob -dir [pwd] -tails *] [glob -dir [pwd] *]
+} -match compareWords -result "not equal"
+test filename-11.42 {Tcl_GlobCmd} -body {
+ set res [list]
+ foreach f [glob -dir [pwd] *] {
+ lappend res [file tail $f]
+ }
+ list $res [glob *]
+} -match compareWords -result equal
+test filename-11.43 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -t *
+} -result {ambiguous option "-t": must be -directory, -join, -nocomplain, -path, -tails, -types, or --}
+test filename-11.44 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -tails -path hello -directory hello *
+} -result {"-directory" cannot be used with "-path"}
+test filename-11.45 {Tcl_GlobCmd on root volume} -setup {
+ set res1 ""
+ set res2 ""
+ set tmpd [pwd]
+} -body {
+ catch {
+ set res1 [glob -dir [lindex [file volumes] 0] -tails *]
+ }
+ catch {
+ cd [lindex [file volumes] 0]
+ set res2 [glob *]
+ }
+ list $res1 $res2
+} -cleanup {
+ cd $tmpd
+} -match compareWords -result equal
+test filename-11.46 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types abcde -dir foo *
+} -result {bad argument to "-types": abcde}
+test filename-11.47 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types abcde -path foo *
+} -result {bad argument to "-types": abcde}
+test filename-11.48 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types abcde -dir foo -join * *
+} -result {bad argument to "-types": abcde}
+test filename-11.49 {Tcl_GlobCmd} -returnCodes error -body {
+ glob -types abcde -path foo -join * *
+} -result {bad argument to "-types": abcde}
+
+file rename $horribleglobname globTest
+set globname globTest
+unset horribleglobname
+
+test filename-12.1 {simple globbing} {unixOrPc} {
+ glob {}
+} {.}
+test filename-12.1.1 {simple globbing} -constraints {unixOrPc} -body {
+ glob -types f {}
+} -returnCodes error -result {no files matched glob pattern ""}
+test filename-12.1.2 {simple globbing} {unixOrPc} {
+ glob -types d {}
+} {.}
+test filename-12.1.3 {simple globbing} {unix} {
+ glob -types hidden {}
+} {.}
+test filename-12.1.4 {simple globbing} -constraints {win} -body {
+ glob -types hidden {}
+} -returnCodes error -result {no files matched glob pattern ""}
+test filename-12.1.5 {simple globbing} -constraints {win} -body {
+ glob -types hidden c:/
+} -returnCodes error -result {no files matched glob pattern "c:/"}
+test filename-12.1.6 {simple globbing} {win} {
+ glob c:/
+} {c:/}
+test filename-12.3 {simple globbing} {
+ glob -nocomplain \{a1,a2\}
+} {}
+set globPreResult globTest/
+set x1 x1.c
+set y1 y1.c
+test filename-12.4 {simple globbing} {unixOrPc} {
+ lsort [glob globTest/x1.c globTest/y1.c globTest/foo]
+} "$globPreResult$x1 $globPreResult$y1"
+test filename-12.5 {simple globbing} {
+ glob globTest\\/x1.c
+} "$globPreResult$x1"
+test filename-12.6 {simple globbing} {
+ glob globTest\\/\\x1.c
+} "$globPreResult$x1"
+test filename-12.7 {globbing at filesystem root} -constraints {unix} -body {
+ list [glob -nocomplain /*] [glob -path / *]
+} -match compareWords -result equal
+test filename-12.8 {globbing at filesystem root} -constraints {unix} -body {
+ set first [string range [lindex [glob -type d /*] 0] 0 1]
+ list [glob -nocomplain ${first}*] [glob -path $first *]
+} -match compareWords -result equal
+test filename-12.9 {globbing at filesystem root} -constraints {win} -body {
+ # Can't grab just anything from 'file volumes' because we need a dir that
+ # has subdirs - assume that C:/ exists across Windows machines.
+ set first [string range [lindex [glob -type d C:/*] 0] 0 3]
+ list [glob -nocomplain ${first}*] [glob -path $first *]
+} -match compareWords -result equal
+test filename-12.10 {globbing with volume relative paths} -setup {
+ set pwd [pwd]
+} -body {
+ set dir [lindex [glob -type d C:/*] 0]
+ cd C:/
+ list [glob -nocomplain [string range $dir 2 end]] [list $dir]
+} -cleanup {
+ cd $pwd
+} -constraints {win} -match compareWords -result equal
+
+test filename-13.1 {globbing with brace substitution} {
+ glob globTest/\{\}
+} "$globPreResult"
+test filename-13.2 {globbing with brace substitution} -body {
+ glob globTest/\{
+} -returnCodes error -result {unmatched open-brace in file name}
+test filename-13.3 {globbing with brace substitution} -body {
+ glob globTest/\{\\\}
+} -returnCodes error -result {unmatched open-brace in file name}
+test filename-13.4 {globbing with brace substitution} -body {
+ glob globTest/\{\\
+} -returnCodes error -result {unmatched open-brace in file name}
+test filename-13.5 {globbing with brace substitution} -body {
+ glob globTest/\}
+} -returnCodes error -result {unmatched close-brace in file name}
+test filename-13.6 {globbing with brace substitution} {
+ glob globTest/\{\}x1.c
+} "$globPreResult$x1"
+test filename-13.7 {globbing with brace substitution} {
+ glob globTest/\{x\}1.c
+} "$globPreResult$x1"
+test filename-13.8 {globbing with brace substitution} {
+ glob globTest/\{x\{\}\}1.c
+} "$globPreResult$x1"
+test filename-13.9 {globbing with brace substitution} {
+ lsort [glob globTest/\{x,y\}1.c]
+} [list $globPreResult$x1 $globPreResult$y1]
+test filename-13.10 {globbing with brace substitution} {
+ lsort [glob globTest/\{x,,y\}1.c]
+} [list $globPreResult$x1 $globPreResult$y1]
+test filename-13.11 {globbing with brace substitution} {unixOrPc} {
+ lsort [glob globTest/\{x,x\\,z,z\}1.c]
+} [lsort {globTest/x1.c globTest/x,z1.c globTest/z1.c}]
+test filename-13.13 {globbing with brace substitution} {
+ lsort [glob globTest/{a,b,x,y}1.c]
+} [list $globPreResult$x1 $globPreResult$y1]
+test filename-13.14 {globbing with brace substitution} {unixOrPc} {
+ lsort [glob {globTest/{x1,y2,weird name}.c}]
+} {{globTest/weird name.c} globTest/x1.c}
+test filename-13.16 {globbing with brace substitution} {unixOrPc} {
+ lsort [glob globTest/{x1.c,a1/*}]
+} {globTest/a1/b1 globTest/a1/b2 globTest/x1.c}
+test filename-13.18 {globbing with brace substitution} {unixOrPc} {
+ lsort [glob globTest/{x1.c,{a},a1/*}]
+} {globTest/a1/b1 globTest/a1/b2 globTest/x1.c}
+test filename-13.20 {globbing with brace substitution} {unixOrPc} {
+ lsort [glob globTest/{a,x}1/*/{x,y}*]
+} {globTest/a1/b1/x2.c globTest/a1/b2/y2.c}
+test filename-13.22 {globbing with brace substitution} -body {
+ glob globTest/\{a,x\}1/*/\{
+} -returnCodes error -result {unmatched open-brace in file name}
+
+test filename-14.1 {asterisks, question marks, and brackets} {unixOrPc} {
+ lsort [glob glo*/*.c]
+} {{globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}
+test filename-14.3 {asterisks, question marks, and brackets} {unixOrPc} {
+ lsort [glob globTest/?1.c]
+} {globTest/x1.c globTest/y1.c globTest/z1.c}
+test filename-14.5 {asterisks, question marks, and brackets} -setup {
+ # The current directory could be anywhere; do this to stop spurious
+ # matches
+ file mkdir globTestContext
+ file rename globTest [file join globTestContext globTest]
+ set savepwd [pwd]
+ cd globTestContext
+} -constraints {unixOrPc} -body {
+ lsort [glob */*/*/*.c]
+} -cleanup {
+ # Reset to where we were
+ cd $savepwd
+ file rename [file join globTestContext globTest] globTest
+ file delete globTestContext
+} -result {globTest/a1/b1/x2.c globTest/a1/b2/y2.c}
+test filename-14.7 {asterisks, question marks, and brackets} {unix} {
+ lsort [glob globTest/*]
+} {globTest/a1 globTest/a2 globTest/a3 {globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}
+test filename-14.7.1 {asterisks, question marks, and brackets} {win} {
+ lsort [glob globTest/*]
+} {globTest/.1 globTest/a1 globTest/a2 globTest/a3 {globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}
+test filename-14.9 {asterisks, question marks, and brackets} {unixOrPc} {
+ lsort [glob globTest/.*]
+} {globTest/. globTest/.. globTest/.1}
+test filename-14.11 {asterisks, question marks, and brackets} {unixOrPc} {
+ lsort [glob globTest/*/*]
+} {globTest/a1/b1 globTest/a1/b2 globTest/a2/b3}
+test filename-14.13 {asterisks, question marks, and brackets} {unixOrPc} {
+ lsort [glob {globTest/[xyab]1.*}]
+} {globTest/x1.c globTest/y1.c}
+test filename-14.15 {asterisks, question marks, and brackets} {unixOrPc} {
+ lsort [glob globTest/*/]
+} {globTest/a1/ globTest/a2/ globTest/a3/}
+test filename-14.17 {asterisks, question marks, and brackets} -setup {
+ global env
+ set temp $env(HOME)
+} -body {
+ set env(HOME) [file join $env(HOME) globTest]
+ glob ~/z*
+} -cleanup {
+ set env(HOME) $temp
+} -result [list [file join $env(HOME) globTest z1.c]]
+test filename-14.18 {asterisks, question marks, and brackets} {unixOrPc} {
+ lsort [glob globTest/*.c goo/*]
+} {{globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}
+test filename-14.20 {asterisks, question marks, and brackets} {
+ glob -nocomplain goo/*
+} {}
+test filename-14.21 {asterisks, question marks, and brackets} -body {
+ glob globTest/*/gorp
+} -returnCodes error -result {no files matched glob pattern "globTest/*/gorp"}
+test filename-14.22 {asterisks, question marks, and brackets} -body {
+ glob goo/* x*z foo?q
+} -returnCodes error -result {no files matched glob patterns "goo/* x*z foo?q"}
+test filename-14.23 {slash globbing} {unix} {
+ glob /
+} /
+test filename-14.23.2 {slash globbing} {win} {
+ glob /
+} [file norm /]
+test filename-14.24 {slash globbing} {win} {
+ glob {\\}
+} [file norm /]
+test filename-14.25 {type specific globbing} {unix} {
+ lsort [glob -dir globTest -types f *]
+} [lsort [list \
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-14.25.1 {type specific globbing} {win} {
+ lsort [glob -dir globTest -types f *]
+} [lsort [list \
+ [file join $globname .1]\
+ [file join $globname "weird name.c"]\
+ [file join $globname x,z1.c]\
+ [file join $globname x1.c]\
+ [file join $globname y1.c] [file join $globname z1.c]]]
+test filename-14.26 {type specific globbing} {
+ glob -nocomplain -dir globTest -types {readonly} *
+} {}
+test filename-14.27 {Bug 2710920} {unixOrPc} {
+ file tail [lindex [lsort [glob globTest/*/]] 0]
+} a1
+test filename-14.28 {Bug 2710920} {unixOrPc} {
+ file dirname [lindex [lsort [glob globTest/*/]] 0]
+} globTest
+test filename-14.29 {Bug 2710920} {unixOrPc} {
+ file extension [lindex [lsort [glob globTest/*/]] 0]
+} {}
+test filename-14.30 {Bug 2710920} {unixOrPc} {
+ file rootname [lindex [lsort [glob globTest/*/]] 0]
+} globTest/a1/
+
+test filename-14.31 {Bug 2918610} -setup {
+ set d [makeDirectory foo]
+ makeFile {} bar.soom $d
+} -body {
+ foreach fn [glob $d/bar.soom] {
+ set root [file rootname $fn]
+ close [open $root {WRONLY CREAT}]
+ }
+ llength [glob -directory $d *]
+} -cleanup {
+ file delete -force $d/bar
+ removeFile bar.soom $d
+ removeDirectory foo
+} -result 2
+
+unset globname
+
+# The following tests are only valid for Unix systems. On some systems, like
+# AFS, "000" protection doesn't prevent access by owner, so the following test
+# is not portable.
+
+catch {file attributes globTest/a1 -permissions 0000}
+test filename-15.1 {unix specific globbing} {unix nonPortable} {
+ string tolower [list [catch {glob globTest/a1/*} msg] $msg $errorCode]
+} {1 {couldn't read directory "globtest/a1": permission denied} {posix eacces {permission denied}}}
+test filename-15.2 {unix specific no complain: no errors} {unix nonPortable} {
+ glob -nocomplain globTest/a1/*
+} {}
+test filename-15.3 {unix specific no complain: no errors, good result} \
+ {unix nonPortable} {
+ # test fails because if an error occurs, the interp's result is reset...
+ glob -nocomplain globTest/a2 globTest/a1/* globTest/a3
+} {globTest/a2 globTest/a3}
+catch {file attributes globTest/a1 -permissions 0755}
+test filename-15.4 {unix specific no complain: no errors, good result} \
+ {unix nonPortable} {
+ # test fails because if an error occurs, the interp's result is reset...
+ # or you don't run at scriptics where the outser and welch users exists
+ glob -nocomplain ~ouster ~foo ~welch
+} {/home/ouster /home/welch}
+test filename-15.4.1 {no complain: errors, sequencing} {
+ # test used to fail because if an error occurs, the interp's result is
+ # reset... But, the sequence means we throw a different error first.
+ list [catch {glob -nocomplain ~wontexist ~blahxyz ~} res1] $res1 \
+ [catch {glob -nocomplain ~ ~blahxyz ~wontexist} res2] $res2
+} {1 {user "wontexist" doesn't exist} 1 {user "blahxyz" doesn't exist}}
+test filename-15.4.2 {no complain: errors, sequencing} -body {
+ # test used to fail because if an error occurs, the interp's result is
+ # reset...
+ list [list [catch {glob -nocomplain ~wontexist *} res1] $res1] \
+ [list [catch {glob -nocomplain * ~wontexist} res2] $res2]
+} -match compareWords -result equal
+test filename-15.5 {unix specific globbing} {unix nonPortable} {
+ glob ~ouster/.csh*
+} "/home/ouster/.cshrc"
+touch globTest/odd\\\[\]*?\{\}name
+test filename-15.6 {unix specific globbing} -constraints {unix} -setup {
+ global env
+ set temp $env(HOME)
+} -body {
+ set env(HOME) $env(HOME)/globTest/odd\\\[\]*?\{\}name
+ glob ~
+} -cleanup {
+ set env(HOME) $temp
+} -result [list [lindex [glob ~] 0]/globTest/odd\\\[\]*?\{\}name]
+catch {file delete -force globTest/odd\\\[\]*?\{\}name}
+test filename-15.7 {win specific globbing} -constraints {win} -body {
+ glob ~
+} -match regexp -result {[^/]$}
+test filename-15.8 {win and unix specific globbing} -constraints {unixOrWin} -setup {
+ global env
+ set temp $env(HOME)
+} -body {
+ touch $env(HOME)/globTest/anyname
+ set env(HOME) $env(HOME)/globTest/anyname
+ glob ~
+} -cleanup {
+ set env(HOME) $temp
+ catch {file delete -force $env(HOME)/globTest/anyname}
+} -result [list [lindex [glob ~] 0]/globTest/anyname]
+
+# The following tests are only valid for Windows systems.
+set oldDir [pwd]
+if {[testConstraint win]} {
+ cd c:/
+ file delete -force globTest
+ file mkdir globTest
+ touch globTest/x1.BAT
+ touch globTest/y1.Bat
+ touch globTest/z1.bat
+}
+
+test filename-16.1 {windows specific globbing} {win} {
+ lsort [glob globTest/*.bat]
+} {globTest/x1.BAT globTest/y1.Bat globTest/z1.bat}
+test filename-16.2 {windows specific globbing} {win} {
+ glob c:
+} c:
+test filename-16.2.1 {windows specific globbing} -constraints {win} -setup {
+ set dir [pwd]
+} -body {
+ cd C:/
+ glob c:
+} -cleanup {
+ cd $dir
+} -result c:
+test filename-16.3 {windows specific globbing} {win} {
+ glob -nocomplain c:\\\\
+} c:/
+test filename-16.4 {windows specific globbing} {win} {
+ glob -nocomplain c:/
+} c:/
+test filename-16.5 {windows specific globbing} {win} {
+ glob -nocomplain c:*bTest
+} c:globTest
+test filename-16.6 {windows specific globbing} {win} {
+ glob -nocomplain c:\\\\*bTest
+} c:/globTest
+test filename-16.7 {windows specific globbing} {win} {
+ glob -nocomplain c:/*bTest
+} c:/globTest
+test filename-16.8 {windows specific globbing} {win} {
+ lsort [glob -nocomplain c:globTest/*.bat]
+} {c:globTest/x1.BAT c:globTest/y1.Bat c:globTest/z1.bat}
+test filename-16.9 {windows specific globbing} {win} {
+ lsort [glob -nocomplain c:/globTest/*.bat]
+} {c:/globTest/x1.BAT c:/globTest/y1.Bat c:/globTest/z1.bat}
+test filename-16.10 {windows specific globbing} {win} {
+ lsort [glob -nocomplain c:globTest\\\\*.bat]
+} {c:globTest/x1.BAT c:globTest/y1.Bat c:globTest/z1.bat}
+test filename-16.11 {windows specific globbing} {win} {
+ lsort [glob -nocomplain c:\\\\globTest\\\\*.bat]
+} {c:/globTest/x1.BAT c:/globTest/y1.Bat c:/globTest/z1.bat}
+# some tests require a shared C drive
+test filename-16.12 {windows specific globbing} {win sharedCdrive} {
+ cd //[info hostname]/c
+ glob //[info hostname]/c/*Test
+} //[info hostname]/c/globTest
+test filename-16.13 {windows specific globbing} {win sharedCdrive} {
+ cd //[info hostname]/c
+ glob "\\\\\\\\[info hostname]\\\\c\\\\*Test"
+} //[info hostname]/c/globTest
+test filename-16.14 {windows specific globbing} {win} {
+ cd [lindex [glob -types d -dir C:/ *] 0]
+ expr {".." in [glob {{.,*}*}]}
+} {1}
+test filename-16.15 {windows specific globbing} {win} {
+ cd [lindex [glob -types d -dir C:/ *] 0]
+ glob ..
+} {..}
+test filename-16.16 {windows specific globbing} {win} {
+ file tail [lindex [glob -nocomplain "[lindex [glob -types d -dir C:/ *] 0]/.."] 0]
+} {..}
+test filename-16.17 {windows specific globbing} -constraints {win} -body {
+ cd C:/
+ # Ensure correct trimming of tails with absolute and volume relative
+ # globbing.
+ list [glob -nocomplain -tails -dir C:/ *] \
+ [glob -nocomplain -tails -dir C: *]
+} -match compareWords -result equal
+
+# Put the working directory back now that we're done with globbing in C:/
+if {[testConstraint win]} {
+ cd $oldDir
+}
+
+test filename-17.1 {windows specific special files} {testsetplatform} {
+ testsetplatform win
+ list [file pathtype com1] [file pathtype con] [file pathtype lpt3] \
+ [file pathtype prn] [file pathtype nul] [file pathtype aux] \
+ [file pathtype foo]
+} {absolute absolute absolute absolute absolute absolute relative}
+if {[testConstraint testsetplatform]} {
+ testsetplatform $platform
+}
+test filename-17.2 {windows specific glob with executable} -body {
+ makeDirectory execglob
+ makeFile contents execglob/abc.exe
+ makeFile contents execglob/abc.notexecutable
+ glob -nocomplain -dir [temporaryDirectory]/execglob -tails -types x *
+} -constraints {win} -cleanup {
+ removeFile execglob/abc.exe
+ removeFile execglob/abc.notexecutable
+ removeDirectory execglob
+} -result {abc.exe}
+test filename-17.3 {Bug 2571597} win {
+ set p /a
+ file pathtype $p
+ file normalize $p
+ file pathtype $p
+} volumerelative
+
+test fileName-18.1 {windows - split ADS name correctly} {win} {
+ # bug 1194458
+ set x [file split c:/c:d]
+ list $x [file join {*}$x]
+} {{c:/ ./c:d} c:/c:d}
+
+test fileName-19.1 {ensure that [Bug 1325099] stays fixed} {
+ # Any non-crashing result is OK
+ list [file exists ~//.nonexistant_file] [file exists ~///.nonexistant_file]
+} {0 0}
+
+test fileName-20.1 {Bug 1750300} -setup {
+ set d [makeDirectory foo]
+ makeFile {} TAGS $d
+} -body {
+ llength [glob -nocomplain -directory $d -- TAGS one two]
+} -cleanup {
+ removeFile TAGS $d
+ removeDirectory foo
+} -result 1
+test fileName-20.2 {Bug 1750300} -setup {
+ set d [makeDirectory foo]
+ makeFile {} TAGS $d
+} -body {
+ llength [glob -nocomplain -directory $d -types {} -- TAGS one two]
+} -cleanup {
+ removeFile TAGS $d
+ removeDirectory foo
+} -result 1
+test fileName-20.3 {Bug 1750300} -setup {
+ set d [makeDirectory foo]
+ makeFile {} TAGS $d
+} -body {
+ llength [glob -nocomplain -directory $d -types {} -- *U*]
+} -cleanup {
+ removeFile TAGS $d
+ removeDirectory foo
+} -result 0
+test fileName-20.4 {Bug 1750300} -setup {
+ set d [makeDirectory foo]
+ makeFile {} TAGS $d
+} -body {
+ llength [glob -nocomplain -directory $d -types {} -- URGENT Urkle]
+} -cleanup {
+ removeFile TAGS $d
+ removeDirectory foo
+} -result 0
+test fileName-20.5 {Bug 2837800} -setup {
+ set dd [makeDirectory isolate]
+ set d [makeDirectory ./~foo $dd]
+ makeFile {} test $d
+ set savewd [pwd]
+ cd $dd
+} -body {
+ glob -nocomplain */test
+} -cleanup {
+ cd $savewd
+ removeFile test $d
+ removeDirectory ./~foo $dd
+ removeDirectory isolate
+} -result ~foo/test
+test fileName-20.6 {Bug 2837800} -setup {
+ # Recall that we have $env(HOME) set so that references
+ # to ~ point to [temporaryDirectory]
+ makeFile {} test ~
+ set dd [makeDirectory isolate]
+ set d [makeDirectory ./~ $dd]
+ set savewd [pwd]
+ cd $dd
+} -body {
+ glob -nocomplain */test
+} -cleanup {
+ cd $savewd
+ removeDirectory ./~ $dd
+ removeDirectory isolate
+ removeFile test ~
+} -result {}
+test fileName-20.7 {Bug 2806250} -setup {
+ set savewd [pwd]
+ cd [temporaryDirectory]
+ set d [makeDirectory isolate]
+ makeFile {} ./~test $d
+} -body {
+ file exists [lindex [glob -nocomplain isolate/*] 0]
+} -cleanup {
+ removeFile ./~test $d
+ removeDirectory isolate
+ cd $savewd
+} -result 1
+test fileName-20.8 {Bug 2806250} -setup {
+ set savewd [pwd]
+ cd [temporaryDirectory]
+ set d [makeDirectory isolate]
+ makeFile {} ./~test $d
+} -body {
+ file tail [lindex [glob -nocomplain isolate/*] 0]
+} -cleanup {
+ removeFile ./~test $d
+ removeDirectory isolate
+ cd $savewd
+} -result ./~test
+test fileName-20.9 {globbing for special chars} -setup {
+ makeFile {} test ~
+ set d [makeDirectory isolate]
+ set savewd [pwd]
+ cd $d
+} -body {
+ glob -nocomplain -directory ~ test
+} -cleanup {
+ cd $savewd
+ removeDirectory isolate
+ removeFile test ~
+} -result ~/test
+test fileName-20.10 {globbing for special chars} -setup {
+ set s [makeDirectory sub ~]
+ makeFile {} fileName-20.10 $s
+ set d [makeDirectory isolate]
+ set savewd [pwd]
+ cd $d
+} -body {
+ glob -nocomplain -directory ~ -join * fileName-20.10
+} -cleanup {
+ cd $savewd
+ removeDirectory isolate
+ removeFile fileName-20.10 $s
+ removeDirectory sub ~
+} -result ~/sub/fileName-20.10
+
+# cleanup
+catch {file delete -force C:/globTest}
+cd [temporaryDirectory]
+file delete -force globTest
+cd $oldpwd
+set env(HOME) $oldhome
+if {[testConstraint testsetplatform]} {
+ testsetplatform $platform
+ catch {unset platform}
+}
+catch {unset oldhome temp result globPreResult}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/fileSystem.test b/pkgs/msgcat/tests/fileSystem.test
new file mode 100644
index 0000000..9950dde
--- /dev/null
+++ b/pkgs/msgcat/tests/fileSystem.test
@@ -0,0 +1,935 @@
+# This file tests the filesystem and vfs internals.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 2002 Vincent Darley.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace eval ::tcl::test::fileSystem {
+ namespace import ::tcltest::*
+
+ catch {
+ file delete -force link.file
+ file delete -force dir.link
+ file delete -force [file join dir.dir linkinside.file]
+ }
+
+# Test for commands defined in Tcltest executable
+testConstraint testfilesystem [llength [info commands ::testfilesystem]]
+testConstraint testsetplatform [llength [info commands ::testsetplatform]]
+testConstraint testsimplefilesystem [llength [info commands ::testsimplefilesystem]]
+
+cd [tcltest::temporaryDirectory]
+makeFile "test file" gorp.file
+makeDirectory dir.dir
+makeDirectory [file join dir.dir dirinside.dir]
+makeFile "test file in directory" [file join dir.dir inside.file]
+
+testConstraint unusedDrive 0
+testConstraint moreThanOneDrive 0
+apply {{} {
+ # The variables 'drive' and 'drives' will be used below.
+ variable drive {} drives {}
+ if {[testConstraint win]} {
+ set vols [string map [list :/ {}] [file volumes]]
+ for {set i 0} {$i < 26} {incr i} {
+ set drive [format %c [expr {$i + 65}]]
+ if {$drive ni $vols} {
+ testConstraint unusedDrive 1
+ break
+ }
+ }
+
+ set dir [pwd]
+ try {
+ foreach vol [file volumes] {
+ if {![catch {cd $vol}]} {
+ lappend drives $vol
+ }
+ }
+ testConstraint moreThanOneDrive [llength $drives]
+ } finally {
+ cd $dir
+ }
+ }
+} ::tcl::test::fileSystem}
+
+proc testPathEqual {one two} {
+ if {$one eq $two} {
+ return "ok"
+ }
+ return "not equal: $one $two"
+}
+
+testConstraint hasLinks [expr {![catch {
+ file link link.file gorp.file
+ cd dir.dir
+ file link \
+ [file join linkinside.file] \
+ [file join inside.file]
+ cd ..
+ file link dir.link dir.dir
+ cd dir.dir
+ file link [file join dirinside.link] \
+ [file join dirinside.dir]
+ cd ..
+}]}]
+
+if {[testConstraint testsetplatform]} {
+ set platform [testgetplatform]
+}
+
+# ----------------------------------------------------------------------
+
+test filesystem-1.0 {link normalisation} {hasLinks} {
+ string equal [file normalize gorp.file] [file normalize link.file]
+} {0}
+test filesystem-1.1 {link normalisation} {hasLinks} {
+ string equal [file normalize dir.dir] [file normalize dir.link]
+} {0}
+test filesystem-1.2 {link normalisation} {hasLinks unix} {
+ testPathEqual [file normalize [file join gorp.file foo]] \
+ [file normalize [file join link.file foo]]
+} ok
+test filesystem-1.3 {link normalisation} {hasLinks} {
+ testPathEqual [file normalize [file join dir.dir foo]] \
+ [file normalize [file join dir.link foo]]
+} ok
+test filesystem-1.4 {link normalisation} {hasLinks} {
+ testPathEqual [file normalize [file join dir.dir inside.file]] \
+ [file normalize [file join dir.link inside.file]]
+} ok
+test filesystem-1.5 {link normalisation} {hasLinks} {
+ testPathEqual [file normalize [file join dir.dir linkinside.file]] \
+ [file normalize [file join dir.dir linkinside.file]]
+} ok
+test filesystem-1.6 {link normalisation} {hasLinks} {
+ string equal [file normalize [file join dir.dir linkinside.file]] \
+ [file normalize [file join dir.link inside.file]]
+} {0}
+test filesystem-1.7 {link normalisation} {hasLinks unix} {
+ testPathEqual [file normalize [file join dir.link linkinside.file foo]] \
+ [file normalize [file join dir.dir inside.file foo]]
+} ok
+test filesystem-1.8 {link normalisation} {hasLinks} {
+ string equal [file normalize [file join dir.dir linkinside.filefoo]] \
+ [file normalize [file join dir.link inside.filefoo]]
+} {0}
+test filesystem-1.9 {link normalisation} -setup {
+ file delete -force dir.link
+} -constraints {unix hasLinks} -body {
+ file link dir.link [file nativename dir.dir]
+ testPathEqual [file normalize [file join dir.dir linkinside.file foo]] \
+ [file normalize [file join dir.link inside.file foo]]
+} -result ok
+test filesystem-1.10 {link normalisation: double link} {unix hasLinks} {
+ file link dir2.link dir.link
+ testPathEqual [file normalize [file join dir.dir linkinside.file foo]] \
+ [file normalize [file join dir2.link inside.file foo]]
+} ok
+makeDirectory dir2.file
+test filesystem-1.11 {link normalisation: double link, back in tree} {unix hasLinks} {
+ file link [file join dir2.file dir2.link] [file join .. dir2.link]
+ testPathEqual [file normalize [file join dir.dir linkinside.file foo]] \
+ [file normalize [file join dir2.file dir2.link inside.file foo]]
+} ok
+test filesystem-1.12 {file new native path} {} {
+ for {set i 0} {$i < 10} {incr i} {
+ foreach f [lsort [glob -nocomplain -type l *]] {
+ catch {file readlink $f}
+ }
+ }
+ # If we reach here we've succeeded. We used to crash above.
+ expr 1
+} {1}
+test filesystem-1.13 {file normalisation} {win} {
+ # This used to be broken
+ file normalize C:/thislongnamedoesntexist
+} {C:/thislongnamedoesntexist}
+test filesystem-1.14 {file normalisation} {win} {
+ # This used to be broken
+ file normalize c:/
+} {C:/}
+test filesystem-1.15 {file normalisation} {win} {
+ file normalize c:/../
+} {C:/}
+test filesystem-1.16 {file normalisation} {win} {
+ file normalize c:/.
+} {C:/}
+test filesystem-1.17 {file normalisation} {win} {
+ file normalize c:/..
+} {C:/}
+test filesystem-1.17.1 {file normalisation} {win} {
+ file normalize c:\\..
+} {C:/}
+test filesystem-1.18 {file normalisation} {win} {
+ file normalize c:/./
+} {C:/}
+test filesystem-1.19 {file normalisation} {win unusedDrive} {
+ file normalize ${drive}:/./../../..
+} "${drive}:/"
+test filesystem-1.20 {file normalisation} {win} {
+ file normalize //name/foo/../
+} {//name/foo}
+test filesystem-1.21 {file normalisation} {win} {
+ file normalize C:///foo/./
+} {C:/foo}
+test filesystem-1.22 {file normalisation} {win} {
+ file normalize //name/foo/.
+} {//name/foo}
+test filesystem-1.23 {file normalisation} {win} {
+ file normalize c:/./foo
+} {C:/foo}
+test filesystem-1.24 {file normalisation} {win unusedDrive} {
+ file normalize ${drive}:/./../../../a
+} "${drive}:/a"
+test filesystem-1.25 {file normalisation} {win unusedDrive} {
+ file normalize ${drive}:/./.././../../a
+} "${drive}:/a"
+test filesystem-1.25.1 {file normalisation} {win unusedDrive} {
+ file normalize ${drive}:/./.././..\\..\\a\\bb
+} "${drive}:/a/bb"
+test filesystem-1.26 {link normalisation: link and ..} -setup {
+ file delete -force dir2.link
+} -constraints {hasLinks} -body {
+ set dir [file join dir2 foo bar]
+ file mkdir $dir
+ file link dir2.link [file join dir2 foo bar]
+ testPathEqual [file normalize [file join dir2 foo x]] \
+ [file normalize [file join dir2.link .. x]]
+} -result ok
+test filesystem-1.27 {file normalisation: up and down with ..} {
+ set dir [file join dir2 foo bar]
+ file mkdir $dir
+ set dir2 [file join dir2 .. dir2 foo .. foo bar]
+ list [testPathEqual [file normalize $dir] [file normalize $dir2]] \
+ [file exists $dir] [file exists $dir2]
+} {ok 1 1}
+test filesystem-1.28 {link normalisation: link with .. and ..} -setup {
+ file delete -force dir2.link
+} -constraints {hasLinks} -body {
+ set dir [file join dir2 foo bar]
+ file mkdir $dir
+ set to [file join dir2 .. dir2 foo .. foo bar]
+ file link dir2.link $to
+ testPathEqual [file normalize [file join dir2 foo x]] \
+ [file normalize [file join dir2.link .. x]]
+} -result ok
+test filesystem-1.29 {link normalisation: link with ..} -setup {
+ file delete -force dir2.link
+} -constraints {hasLinks} -body {
+ set dir [file join dir2 foo bar]
+ file mkdir $dir
+ set to [file join dir2 .. dir2 foo .. foo bar]
+ file link dir2.link $to
+ set res [file normalize [file join dir2.link x yyy z]]
+ if {[string match *..* $res]} {
+ return "$res must not contain '..'"
+ }
+ return "ok"
+} -result {ok}
+test filesystem-1.29.1 {link normalisation with two consecutive links} {hasLinks} {
+ testPathEqual [file normalize [file join dir.link dirinside.link abc]] \
+ [file normalize [file join dir.dir dirinside.dir abc]]
+} ok
+file delete -force dir2.file
+file delete -force dir2.link
+file delete -force link.file dir.link
+file delete -force dir2
+file delete -force [file join dir.dir dirinside.link]
+removeFile [file join dir.dir inside.file]
+removeDirectory [file join dir.dir dirinside.dir]
+removeDirectory dir.dir
+test filesystem-1.30 {normalisation of nonexistent user} -body {
+ file normalize ~noonewiththisname
+} -returnCodes error -result {user "noonewiththisname" doesn't exist}
+test filesystem-1.31 {link normalisation: link near filesystem root} {testsetplatform} {
+ testsetplatform unix
+ file normalize /foo/../bar
+} {/bar}
+test filesystem-1.32 {link normalisation: link near filesystem root} {testsetplatform} {
+ testsetplatform unix
+ file normalize /../bar
+} {/bar}
+test filesystem-1.33 {link normalisation: link near filesystem root} {testsetplatform} {
+ testsetplatform windows
+ set res [file normalize C:/../bar]
+ if {[testConstraint unix]} {
+ # Some unices go further in normalizing this -- not really a problem
+ # since this is a Windows test.
+ regexp {C:/bar$} $res res
+ }
+ set res
+} {C:/bar}
+if {[testConstraint testsetplatform]} {
+ testsetplatform $platform
+}
+test filesystem-1.34 {file normalisation with '/./'} -body {
+ file normalize /foo/bar/anc/./.tml
+} -match regexp -result {^(?:(?!/\./).)*$}
+test filesystem-1.35a {file normalisation with '/./'} -body {
+ file normalize /ffo/bar/anc/./foo/.tml
+} -match regexp -result {^(?:(?!/\./).)*$}
+test filesystem-1.35b {file normalisation with '/./'} {
+ llength [regexp -all foo [file normalize /ffo/bar/anc/./foo/.tml]]
+} 1
+test filesystem-1.36a {file normalisation with '/./'} -body {
+ file normalize /foo/bar/anc/././asdasd/.tml
+} -match regexp -result {^(?:(?!/\./).)*$}
+test filesystem-1.36b {file normalisation with '/./'} {
+ llength [regexp -all asdasd [file normalize /foo/bar/anc/././asdasd/.tml]]
+} 1
+test filesystem-1.37 {file normalisation with '/./'} -body {
+ set fname "/abc/./def/./ghi/./asda/.././.././asd/x/../../../../....."
+ file norm $fname
+} -match regexp -result {^(?:[^/]|/(?:[^/]|$))+$}
+test filesystem-1.38 {file normalisation with volume relative} -setup {
+ set dir [pwd]
+} -constraints {win moreThanOneDrive} -body {
+ set path "[string range [lindex $drives 0] 0 1]foo"
+ cd [lindex $drives 1]
+ file norm $path
+} -cleanup {
+ cd $dir
+} -result "[lindex $drives 0]foo"
+test filesystem-1.39 {file normalisation with volume relative} -setup {
+ set old [pwd]
+} -constraints {win} -body {
+ set drv C:/
+ cd [lindex [glob -type d -dir $drv *] 0]
+ file norm [string range $drv 0 1]
+} -cleanup {
+ cd $old
+} -match glob -result {*[^/]}
+test filesystem-1.40 {file normalisation with repeated separators} {
+ testPathEqual [file norm foo////bar] [file norm foo/bar]
+} ok
+test filesystem-1.41 {file normalisation with repeated separators} {win} {
+ testPathEqual [file norm foo\\\\\\bar] [file norm foo/bar]
+} ok
+test filesystem-1.42 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /xxx/..] [file norm /]
+} ok
+test filesystem-1.42.1 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /xxx/../] [file norm /]
+} ok
+test filesystem-1.43 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /xxx/foo/../..] [file norm /]
+} ok
+test filesystem-1.43.1 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /xxx/foo/../../] [file norm /]
+} ok
+test filesystem-1.44 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /xxx/foo/../../bar] [file norm /bar]
+} ok
+test filesystem-1.45 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /xxx/../../bar] [file norm /bar]
+} ok
+test filesystem-1.46 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /xxx/../bar] [file norm /bar]
+} ok
+test filesystem-1.47 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /..] [file norm /]
+} ok
+test filesystem-1.48 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /../] [file norm /]
+} ok
+test filesystem-1.49 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /.] [file norm /]
+} ok
+test filesystem-1.50 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /./] [file norm /]
+} ok
+test filesystem-1.51 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /../..] [file norm /]
+} ok
+test filesystem-1.51.1 {file normalisation .. beyond root (Bug 1379287)} {
+ testPathEqual [file norm /../../] [file norm /]
+} ok
+
+test filesystem-2.0 {new native path} {unix} {
+ foreach f [lsort [glob -nocomplain /usr/bin/c*]] {
+ catch {file readlink $f}
+ }
+ # If we reach here we've succeeded. We used to crash above.
+ return ok
+} ok
+
+# Make sure the testfilesystem hasn't been registered.
+if {[testConstraint testfilesystem]} {
+ while {![catch {testfilesystem 0}]} {}
+}
+
+test filesystem-3.1 {Tcl_FSRegister & Tcl_FSUnregister} testfilesystem {
+ set result {}
+ lappend result [testfilesystem 1]
+ lappend result [testfilesystem 0]
+ lappend result [catch {testfilesystem 0} msg] $msg
+} {registered unregistered 1 failed}
+test filesystem-3.3 {Tcl_FSRegister} testfilesystem {
+ testfilesystem 1
+ testfilesystem 1
+ testfilesystem 0
+ testfilesystem 0
+} {unregistered}
+test filesystem-3.4 {Tcl_FSRegister} testfilesystem {
+ testfilesystem 1
+ file system bar
+} {reporting}
+test filesystem-3.5 {Tcl_FSUnregister} testfilesystem {
+ testfilesystem 0
+ lindex [file system bar] 0
+} {native}
+
+test filesystem-4.0 {testfilesystem} -constraints testfilesystem -body {
+ testfilesystem 1
+ set filesystemReport {}
+ file exists foo
+ testfilesystem 0
+ return $filesystemReport
+} -match glob -result {*{access foo}}
+test filesystem-4.1 {testfilesystem} -constraints testfilesystem -body {
+ testfilesystem 1
+ set filesystemReport {}
+ catch {file stat foo bar}
+ testfilesystem 0
+ return $filesystemReport
+} -match glob -result {*{stat foo}}
+test filesystem-4.2 {testfilesystem} -constraints testfilesystem -body {
+ testfilesystem 1
+ set filesystemReport {}
+ catch {file lstat foo bar}
+ testfilesystem 0
+ return $filesystemReport
+} -match glob -result {*{lstat foo}}
+test filesystem-4.3 {testfilesystem} -constraints testfilesystem -body {
+ testfilesystem 1
+ set filesystemReport {}
+ catch {glob *}
+ testfilesystem 0
+ return $filesystemReport
+} -match glob -result {*{matchindirectory *}*}
+
+test filesystem-5.1 {cache and ~} -constraints testfilesystem -setup {
+ set orig $::env(HOME)
+} -body {
+ set ::env(HOME) /foo/bar/blah
+ set testdir ~
+ set res1 "Parent of ~ (/foo/bar/blah) is [file dirname $testdir]"
+ set ::env(HOME) /a/b/c
+ set res2 "Parent of ~ (/a/b/c) is [file dirname $testdir]"
+ list $res1 $res2
+} -cleanup {
+ set ::env(HOME) $orig
+} -match regexp -result {{Parent of ~ \(/foo/bar/blah\) is ([a-zA-Z]:)?(/cygwin)?(/foo/bar|foo:bar)} {Parent of ~ \(/a/b/c\) is ([a-zA-Z]:)?(/cygwin)?(/a/b|a:b)}}
+
+test filesystem-6.1 {empty file name} -returnCodes error -body {
+ open ""
+} -result {couldn't open "": no such file or directory}
+test filesystem-6.2 {empty file name} -returnCodes error -body {
+ file stat "" arr
+} -result {could not read "": no such file or directory}
+test filesystem-6.3 {empty file name} -returnCodes error -body {
+ file atime ""
+} -result {could not read "": no such file or directory}
+test filesystem-6.4 {empty file name} -returnCodes error -body {
+ file attributes ""
+} -result {could not read "": no such file or directory}
+test filesystem-6.5 {empty file name} -returnCodes error -body {
+ file copy "" ""
+} -result {error copying "": no such file or directory}
+test filesystem-6.6 {empty file name} {file delete ""} {}
+test filesystem-6.7 {empty file name} {file dirname ""} .
+test filesystem-6.8 {empty file name} {file executable ""} 0
+test filesystem-6.9 {empty file name} {file exists ""} 0
+test filesystem-6.10 {empty file name} {file extension ""} {}
+test filesystem-6.11 {empty file name} {file isdirectory ""} 0
+test filesystem-6.12 {empty file name} {file isfile ""} 0
+test filesystem-6.13 {empty file name} {file join ""} {}
+test filesystem-6.14 {empty file name} -returnCodes error -body {
+ file link ""
+} -result {could not read link "": no such file or directory}
+test filesystem-6.15 {empty file name} -returnCodes error -body {
+ file lstat "" arr
+} -result {could not read "": no such file or directory}
+test filesystem-6.16 {empty file name} -returnCodes error -body {
+ file mtime ""
+} -result {could not read "": no such file or directory}
+test filesystem-6.17 {empty file name} -returnCodes error -body {
+ file mtime "" 0
+} -result {could not read "": no such file or directory}
+test filesystem-6.18 {empty file name} -returnCodes error -body {
+ file mkdir ""
+} -result {can't create directory "": no such file or directory}
+test filesystem-6.19 {empty file name} {file nativename ""} {}
+test filesystem-6.20 {empty file name} {file normalize ""} {}
+test filesystem-6.21 {empty file name} {file owned ""} 0
+test filesystem-6.22 {empty file name} {file pathtype ""} relative
+test filesystem-6.23 {empty file name} {file readable ""} 0
+test filesystem-6.24 {empty file name} -returnCodes error -body {
+ file readlink ""
+} -result {could not readlink "": no such file or directory}
+test filesystem-6.25 {empty file name} -returnCodes error -body {
+ file rename "" ""
+} -result {error renaming "": no such file or directory}
+test filesystem-6.26 {empty file name} {file rootname ""} {}
+test filesystem-6.27 {empty file name} -returnCodes error -body {
+ file separator ""
+} -result {unrecognised path}
+test filesystem-6.28 {empty file name} -returnCodes error -body {
+ file size ""
+} -result {could not read "": no such file or directory}
+test filesystem-6.29 {empty file name} {file split ""} {}
+test filesystem-6.30 {empty file name} -returnCodes error -body {
+ file system ""
+} -result {unrecognised path}
+test filesystem-6.31 {empty file name} {file tail ""} {}
+test filesystem-6.32 {empty file name} -returnCodes error -body {
+ file type ""
+} -result {could not read "": no such file or directory}
+test filesystem-6.33 {empty file name} {file writable ""} 0
+
+# Make sure the testfilesystem hasn't been registered.
+if {[testConstraint testfilesystem]} {
+ while {![catch {testfilesystem 0}]} {}
+}
+
+test filesystem-7.1.1 {load from vfs} -setup {
+ set dir [pwd]
+} -constraints {win testsimplefilesystem} -body {
+ # This may cause a crash on exit
+ cd [file dirname [info nameof]]
+ set dde [lindex [glob *dde*[info sharedlib]] 0]
+ testsimplefilesystem 1
+ # This loads dde via a complex copy-to-temp operation
+ load simplefs:/$dde dde
+ testsimplefilesystem 0
+ return ok
+ # The real result of this test is what happens when Tcl exits.
+} -cleanup {
+ cd $dir
+} -result ok
+test filesystem-7.1.2 {load from vfs, and then unload again} -setup {
+ set dir [pwd]
+} -constraints {win testsimplefilesystem} -body {
+ # This may cause a crash on exit
+ cd [file dirname [info nameof]]
+ set reg [lindex [glob tclreg*[info sharedlib]] 0]
+ testsimplefilesystem 1
+ # This loads reg via a complex copy-to-temp operation
+ load simplefs:/$reg Registry
+ unload simplefs:/$reg
+ testsimplefilesystem 0
+ return ok
+ # The real result of this test is what happens when Tcl exits.
+} -cleanup {
+ cd $dir
+} -result ok
+test filesystem-7.2 {cross-filesystem copy from vfs maintains mtime} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -constraints testsimplefilesystem -body {
+ # We created this file several tests ago.
+ set origtime [file mtime gorp.file]
+ set res [file exists gorp.file]
+ testsimplefilesystem 1
+ file delete -force theCopy
+ file copy simplefs:/gorp.file theCopy
+ testsimplefilesystem 0
+ set newtime [file mtime theCopy]
+ lappend res [expr {$origtime == $newtime ? 1 : "$origtime != $newtime"}]
+} -cleanup {
+ catch {file delete theCopy}
+ cd $dir
+} -result {1 1}
+test filesystem-7.3 {glob in simplefs} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -constraints testsimplefilesystem -body {
+ file mkdir simpledir
+ close [open [file join simpledir simplefile] w]
+ testsimplefilesystem 1
+ glob -nocomplain -dir simplefs:/simpledir *
+} -cleanup {
+ catch {testsimplefilesystem 0}
+ file delete -force simpledir
+ cd $dir
+} -result {simplefs:/simpledir/simplefile}
+test filesystem-7.3.1 {glob in simplefs: no path/dir} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -constraints testsimplefilesystem -body {
+ file mkdir simpledir
+ close [open [file join simpledir simplefile] w]
+ testsimplefilesystem 1
+ set res [glob -nocomplain simplefs:/simpledir/*]
+ lappend res {*}[glob -nocomplain simplefs:/simpledir]
+} -cleanup {
+ catch {testsimplefilesystem 0}
+ file delete -force simpledir
+ cd $dir
+} -result {simplefs:/simpledir/simplefile simplefs:/simpledir}
+test filesystem-7.3.2 {glob in simplefs: no path/dir, no subdirectory} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -constraints testsimplefilesystem -body {
+ file mkdir simpledir
+ close [open [file join simpledir simplefile] w]
+ testsimplefilesystem 1
+ glob -nocomplain simplefs:/s*
+} -cleanup {
+ catch {testsimplefilesystem 0}
+ file delete -force simpledir
+ cd $dir
+} -match glob -result ?*
+test filesystem-7.3.3 {glob in simplefs: pattern is a volume} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -constraints testsimplefilesystem -body {
+ file mkdir simpledir
+ close [open [file join simpledir simplefile] w]
+ testsimplefilesystem 1
+ glob -nocomplain simplefs:/*
+} -cleanup {
+ testsimplefilesystem 0
+ file delete -force simpledir
+ cd $dir
+} -match glob -result ?*
+test filesystem-7.4 {cross-filesystem file copy with -force} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+ set fout [open [file join simplefile] w]
+ puts -nonewline $fout "1234567890"
+ close $fout
+ testsimplefilesystem 1
+} -constraints testsimplefilesystem -body {
+ # First copy should succeed
+ set res [catch {file copy simplefs:/simplefile file2} err]
+ lappend res $err
+ # Second copy should fail (no -force)
+ lappend res [catch {file copy simplefs:/simplefile file2} err]
+ lappend res $err
+ # Third copy should succeed (-force)
+ lappend res [catch {file copy -force simplefs:/simplefile file2} err]
+ lappend res $err
+ lappend res [file exists file2]
+} -cleanup {
+ catch {testsimplefilesystem 0}
+ file delete -force simplefile
+ file delete -force file2
+ cd $dir
+} -result {0 10 1 {error copying "simplefs:/simplefile" to "file2": file already exists} 0 10 1}
+test filesystem-7.5 {cross-filesystem file copy with -force} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+ set fout [open [file join simplefile] w]
+ puts -nonewline $fout "1234567890"
+ close $fout
+ testsimplefilesystem 1
+} -constraints {testsimplefilesystem unix} -body {
+ # First copy should succeed
+ set res [catch {file copy simplefs:/simplefile file2} err]
+ lappend res $err
+ file attributes file2 -permissions 0000
+ # Second copy should fail (no -force)
+ lappend res [catch {file copy simplefs:/simplefile file2} err]
+ lappend res $err
+ # Third copy should succeed (-force)
+ lappend res [catch {file copy -force simplefs:/simplefile file2} err]
+ lappend res $err
+ lappend res [file exists file2]
+} -cleanup {
+ testsimplefilesystem 0
+ file delete -force simplefile
+ file delete -force file2
+ cd $dir
+} -result {0 10 1 {error copying "simplefs:/simplefile" to "file2": file already exists} 0 10 1}
+test filesystem-7.6 {cross-filesystem dir copy with -force} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+ file delete -force simpledir
+ file mkdir simpledir
+ file mkdir dir2
+ set fout [open [file join simpledir simplefile] w]
+ puts -nonewline $fout "1234567890"
+ close $fout
+ testsimplefilesystem 1
+} -constraints testsimplefilesystem -body {
+ # First copy should succeed
+ set res [catch {file copy simplefs:/simpledir dir2} err]
+ lappend res $err
+ # Second copy should fail (no -force)
+ lappend res [catch {file copy simplefs:/simpledir dir2} err]
+ lappend res $err
+ # Third copy should succeed (-force)
+ lappend res [catch {file copy -force simplefs:/simpledir dir2} err]
+ lappend res $err
+ lappend res [file exists [file join dir2 simpledir]] \
+ [file exists [file join dir2 simpledir simplefile]]
+} -cleanup {
+ testsimplefilesystem 0
+ file delete -force simpledir
+ file delete -force dir2
+ cd $dir
+} -result {0 {} 1 {error copying "simplefs:/simpledir" to "dir2/simpledir": file already exists} 0 {} 1 1}
+test filesystem-7.7 {cross-filesystem dir copy with -force} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+ file delete -force simpledir
+ file mkdir simpledir
+ file mkdir dir2
+ set fout [open [file join simpledir simplefile] w]
+ puts -nonewline $fout "1234567890"
+ close $fout
+ testsimplefilesystem 1
+} -constraints {testsimplefilesystem unix} -body {
+ # First copy should succeed
+ set res [catch {file copy simplefs:/simpledir dir2} err]
+ lappend res $err
+ # Second copy should fail (no -force)
+ lappend res [catch {file copy simplefs:/simpledir dir2} err]
+ lappend res $err
+ # Third copy should succeed (-force)
+ # I've noticed on some Unices that this only succeeds intermittently (some
+ # runs work, some fail). This needs examining further.
+ lappend res [catch {file copy -force simplefs:/simpledir dir2} err]
+ lappend res $err
+ lappend res [file exists [file join dir2 simpledir]] \
+ [file exists [file join dir2 simpledir simplefile]]
+} -cleanup {
+ testsimplefilesystem 0
+ file delete -force simpledir
+ file delete -force dir2
+ cd $dir
+} -result {0 {} 1 {error copying "simplefs:/simpledir" to "dir2/simpledir": file already exists} 0 {} 1 1}
+removeFile gorp.file
+test filesystem-7.8 {vfs cd} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+ file delete -force simpledir
+ file mkdir simpledir
+ testsimplefilesystem 1
+} -constraints testsimplefilesystem -body {
+ # This can variously cause an infinite loop or simply have no effect at
+ # all (before certain bugs were fixed, of course).
+ cd simplefs:/simpledir
+ pwd
+} -cleanup {
+ cd [tcltest::temporaryDirectory]
+ testsimplefilesystem 0
+ file delete -force simpledir
+ cd $dir
+} -result {simplefs:/simpledir}
+
+test filesystem-8.1 {relative path objects and caching of pwd} -setup {
+ set dir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ makeDirectory abc
+ makeDirectory def
+ makeFile "contents" [file join abc foo]
+ cd abc
+ set f "foo"
+ set res {}
+ lappend res [file exists $f]
+ lappend res [file exists $f]
+ cd ..
+ cd def
+ # If we haven't cleared the object's cwd cache, Tcl will think it still
+ # exists.
+ lappend res [file exists $f]
+ lappend res [file exists $f]
+} -cleanup {
+ removeFile [file join abc foo]
+ removeDirectory abc
+ removeDirectory def
+ cd $dir
+} -result {1 1 0 0}
+test filesystem-8.2 {relative path objects and use of pwd} -setup {
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ set dir "abc"
+ makeDirectory $dir
+ makeFile "contents" [file join abc foo]
+ cd $dir
+ file exists [lindex [glob *] 0]
+} -cleanup {
+ cd [tcltest::temporaryDirectory]
+ removeFile [file join abc foo]
+ removeDirectory abc
+ cd $origdir
+} -result 1
+test filesystem-8.3 {path objects and empty string} {
+ set anchor ""
+ set dst foo
+ set res $dst
+ set yyy [file split $anchor]
+ set dst [file join $anchor $dst]
+ lappend res $dst $yyy
+} {foo foo {}}
+
+proc TestFind1 {d f} {
+ set r1 [file exists [file join $d $f]]
+ lappend res "[file join $d $f] found: $r1"
+ lappend res "is dir a dir? [file isdirectory $d]"
+ set r2 [file exists [file join $d $f]]
+ lappend res "[file join $d $f] found: $r2"
+ return $res
+}
+proc TestFind2 {d f} {
+ set r1 [file exists [file join $d $f]]
+ lappend res "[file join $d $f] found: $r1"
+ lappend res "is dir a dir? [file isdirectory [file join $d]]"
+ set r2 [file exists [file join $d $f]]
+ lappend res "[file join $d $f] found: $r2"
+ return $res
+}
+
+test filesystem-9.1 {path objects and join and object rep} -setup {
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir [file join a b c]
+ TestFind1 a [file join b . c]
+} -cleanup {
+ file delete -force a
+ cd $origdir
+} -result {{a/b/./c found: 1} {is dir a dir? 1} {a/b/./c found: 1}}
+test filesystem-9.2 {path objects and join and object rep} -setup {
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir [file join a b c]
+ TestFind2 a [file join b . c]
+} -cleanup {
+ file delete -force a
+ cd $origdir
+} -result {{a/b/./c found: 1} {is dir a dir? 1} {a/b/./c found: 1}}
+test filesystem-9.2.1 {path objects and join and object rep} -setup {
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir [file join a b c]
+ TestFind2 a [file join b .]
+} -cleanup {
+ file delete -force a
+ cd $origdir
+} -result {{a/b/. found: 1} {is dir a dir? 1} {a/b/. found: 1}}
+test filesystem-9.3 {path objects and join and object rep} -setup {
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir [file join a b c]
+ TestFind1 a [file join b .. b c]
+} -cleanup {
+ file delete -force a
+ cd $origdir
+} -result {{a/b/../b/c found: 1} {is dir a dir? 1} {a/b/../b/c found: 1}}
+test filesystem-9.4 {path objects and join and object rep} -setup {
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir [file join a b c]
+ TestFind2 a [file join b .. b c]
+} -cleanup {
+ file delete -force a
+ cd $origdir
+} -result {{a/b/../b/c found: 1} {is dir a dir? 1} {a/b/../b/c found: 1}}
+test filesystem-9.5 {path objects and file tail and object rep} -setup {
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir dgp
+ close [open dgp/test w]
+ foreach relative [glob -nocomplain [file join * test]] {
+ set absolute [file join [pwd] $relative]
+ set res [list [file tail $absolute] "test"]
+ }
+ return $res
+} -cleanup {
+ file delete -force dgp
+ cd $origdir
+} -result {test test}
+test filesystem-9.6 {path objects and file tail and object rep} win {
+ set res {}
+ set p "C:\\toto"
+ lappend res [file join $p toto]
+ file isdirectory $p
+ lappend res [file join $p toto]
+} {C:/toto/toto C:/toto/toto}
+test filesystem-9.7 {path objects and glob and file tail and tilde} -setup {
+ set res {}
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir tilde
+ close [open tilde/~testNotExist w]
+ cd tilde
+ set file [lindex [glob *test*] 0]
+ lappend res [file exists $file] [catch {file tail $file} r] $r
+ lappend res $file
+ lappend res [file exists $file] [catch {file tail $file} r] $r
+ lappend res [catch {file tail $file} r] $r
+} -cleanup {
+ cd [tcltest::temporaryDirectory]
+ file delete -force tilde
+ cd $origdir
+} -result {0 1 {user "testNotExist" doesn't exist} ~testNotExist 0 1 {user "testNotExist" doesn't exist} 1 {user "testNotExist" doesn't exist}}
+test filesystem-9.8 {path objects and glob and file tail and tilde} -setup {
+ set res {}
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir tilde
+ close [open tilde/~testNotExist w]
+ cd tilde
+ set file1 [lindex [glob *test*] 0]
+ set file2 "~testNotExist"
+ lappend res $file1 $file2
+ lappend res [catch {file tail $file1} r] $r
+ lappend res [catch {file tail $file2} r] $r
+} -cleanup {
+ cd [tcltest::temporaryDirectory]
+ file delete -force tilde
+ cd $origdir
+} -result {~testNotExist ~testNotExist 1 {user "testNotExist" doesn't exist} 1 {user "testNotExist" doesn't exist}}
+test filesystem-9.9 {path objects and glob and file tail and tilde} -setup {
+ set res {}
+ set origdir [pwd]
+ cd [tcltest::temporaryDirectory]
+} -body {
+ file mkdir tilde
+ close [open tilde/~testNotExist w]
+ cd tilde
+ set file1 [lindex [glob *test*] 0]
+ set file2 "~testNotExist"
+ lappend res [catch {file exists $file1} r] $r
+ lappend res [catch {file exists $file2} r] $r
+ lappend res [string equal $file1 $file2]
+} -cleanup {
+ cd [tcltest::temporaryDirectory]
+ file delete -force tilde
+ cd $origdir
+} -result {0 0 0 0 1}
+
+# ----------------------------------------------------------------------
+
+test filesystem-10.1 {Bug 3414754} {
+ string match */ [file join [pwd] foo/]
+} 0
+
+cleanupTests
+unset -nocomplain drive drives
+}
+namespace delete ::tcl::test::fileSystem
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/for-old.test b/pkgs/msgcat/tests/for-old.test
new file mode 100644
index 0000000..a11a791
--- /dev/null
+++ b/pkgs/msgcat/tests/for-old.test
@@ -0,0 +1,71 @@
+# Commands covered: for, continue, break
+#
+# This file contains the original set of tests for Tcl's for command.
+# Since the for command is now compiled, a new set of tests covering
+# the new implementation is in the file "for.test". Sourcing this file
+# into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# Check "for" and its use of continue and break.
+
+catch {unset a i}
+test for-old-1.1 {for tests} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} {
+ set a [concat $a $i]
+ }
+ set a
+} {1 2 3 4 5}
+test for-old-1.2 {for tests} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} {
+ if $i==4 continue
+ set a [concat $a $i]
+ }
+ set a
+} {1 2 3 5}
+test for-old-1.3 {for tests} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} {
+ if $i==4 break
+ set a [concat $a $i]
+ }
+ set a
+} {1 2 3}
+test for-old-1.4 {for tests} {catch {for 1 2 3} msg} 1
+test for-old-1.5 {for tests} {
+ catch {for 1 2 3} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-old-1.6 {for tests} {catch {for 1 2 3 4 5} msg} 1
+test for-old-1.7 {for tests} {
+ catch {for 1 2 3 4 5} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-old-1.8 {for tests} {
+ set a {xyz}
+ for {set i 1} {$i<6} {set i [expr $i+1]} {}
+ set a
+} xyz
+test for-old-1.9 {for tests} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]; if $i==4 break} {
+ set a [concat $a $i]
+ }
+ set a
+} {1 2 3}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/for.test b/pkgs/msgcat/tests/for.test
new file mode 100644
index 0000000..ff4dc0e
--- /dev/null
+++ b/pkgs/msgcat/tests/for.test
@@ -0,0 +1,830 @@
+# Commands covered: for, continue, break
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Basic "for" operation.
+
+test for-1.1 {TclCompileForCmd: missing initial command} {
+ list [catch {for} msg] $msg
+} {1 {wrong # args: should be "for start test next command"}}
+test for-1.2 {TclCompileForCmd: error in initial command} -body {
+ list [catch {for {set}} msg] $msg $::errorInfo
+} -match glob -result {1 {wrong # args: should be "for start test next command"} {wrong # args: should be "for start test next command"
+ while *ing
+"for {set}"}}
+catch {unset i}
+test for-1.3 {TclCompileForCmd: missing test expression} {
+ catch {for {set i 0}} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-1.4 {TclCompileForCmd: error in test expression} -body {
+ catch {for {set i 0} {$i<}} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "for start test next command"
+ while *ing
+"for {set i 0} {$i<}"}
+test for-1.5 {TclCompileForCmd: test expression is enclosed in quotes} {
+ set i 0
+ for {} "$i > 5" {incr i} {}
+} {}
+test for-1.6 {TclCompileForCmd: missing "next" command} {
+ catch {for {set i 0} {$i < 5}} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-1.7 {TclCompileForCmd: missing command body} {
+ catch {for {set i 0} {$i < 5} {incr i}} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-1.8 {TclCompileForCmd: error compiling command body} -body {
+ catch {for {set i 0} {$i < 5} {incr i} {set}} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+catch {unset a}
+test for-1.9 {TclCompileForCmd: simple command body} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} {
+ if $i==4 break
+ set a [concat $a $i]
+ }
+ set a
+} {1 2 3}
+test for-1.10 {TclCompileForCmd: command body in quotes} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} "append a x"
+ set a
+} {xxxxx}
+test for-1.11 {TclCompileForCmd: computed command body} {
+ catch {unset x1}
+ catch {unset bb}
+ catch {unset x2}
+ set x1 {append a x1; }
+ set bb {break}
+ set x2 {; append a x2}
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} $x1$bb$x2
+ set a
+} {x1}
+test for-1.12 {TclCompileForCmd: error in "next" command} -body {
+ catch {for {set i 0} {$i < 5} {set} {format $i}} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test for-1.13 {TclCompileForCmd: long command body} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} {
+ if $i==4 break
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ }
+ set a
+} {1 2 3}
+test for-1.14 {TclCompileForCmd: for command result} {
+ set a [for {set i 0} {$i < 5} {incr i} {}]
+ set a
+} {}
+test for-1.15 {TclCompileForCmd: for command result} {
+ set a [for {set i 0} {$i < 5} {incr i} {if $i==3 break}]
+ set a
+} {}
+
+# Check "for" and "continue".
+
+test for-2.1 {TclCompileContinueCmd: arguments after "continue"} {
+ catch {continue foo} msg
+ set msg
+} {wrong # args: should be "continue"}
+test for-2.2 {TclCompileContinueCmd: continue result} {
+ catch continue
+} 4
+test for-2.3 {continue tests} {
+ set a {}
+ for {set i 1} {$i <= 4} {set i [expr $i+1]} {
+ if {$i == 2} continue
+ set a [concat $a $i]
+ }
+ set a
+} {1 3 4}
+test for-2.4 {continue tests} {
+ set a {}
+ for {set i 1} {$i <= 4} {set i [expr $i+1]} {
+ if {$i != 2} continue
+ set a [concat $a $i]
+ }
+ set a
+} {2}
+test for-2.5 {continue tests, nested loops} {
+ set msg {}
+ for {set i 1} {$i <= 4} {incr i} {
+ for {set a 1} {$a <= 2} {incr a} {
+ if {$i>=2 && $a>=2} continue
+ set msg [concat $msg "$i.$a"]
+ }
+ }
+ set msg
+} {1.1 1.2 2.1 3.1 4.1}
+test for-2.6 {continue tests, long command body} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} {
+ if $i==2 continue
+ if $i==4 break
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ }
+ set a
+} {1 3}
+test for-2.7 {continue tests, uncompiled [for]} -body {
+ set file [makeFile {
+ set guard 0
+ for {set i 20} {$i > 0} {incr i -1} {
+ if {[incr guard]>30} {return BAD}
+ continue
+ }
+ return GOOD
+ } source.file]
+ source $file
+} -cleanup {
+ removeFile source.file
+} -result GOOD
+
+# Check "for" and "break".
+
+test for-3.1 {TclCompileBreakCmd: arguments after "break"} {
+ catch {break foo} msg
+ set msg
+} {wrong # args: should be "break"}
+test for-3.2 {TclCompileBreakCmd: break result} {
+ catch break
+} 3
+test for-3.3 {break tests} {
+ set a {}
+ for {set i 1} {$i <= 4} {incr i} {
+ if {$i == 3} break
+ set a [concat $a $i]
+ }
+ set a
+} {1 2}
+test for-3.4 {break tests, nested loops} {
+ set msg {}
+ for {set i 1} {$i <= 4} {incr i} {
+ for {set a 1} {$a <= 2} {incr a} {
+ if {$i>=2 && $a>=2} break
+ set msg [concat $msg "$i.$a"]
+ }
+ }
+ set msg
+} {1.1 1.2 2.1 3.1 4.1}
+test for-3.5 {break tests, long command body} {
+ set a {}
+ for {set i 1} {$i<6} {set i [expr $i+1]} {
+ if $i==2 continue
+ if $i==5 break
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if $i==4 break
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ }
+ set a
+} {1 3}
+# A simplified version of exmh's mail formatting routine to stress "for",
+# "break", "while", and "if".
+proc formatMail {} {
+ array set lines {
+ 0 {Return-path: george@tcl} \
+ 1 {Return-path: <george@tcl>} \
+ 2 {Received: from tcl by tcl.Somewhere.COM (SMI-8.6/SMI-SVR4)} \
+ 3 { id LAA10027; Wed, 11 Sep 1996 11:14:53 -0700} \
+ 4 {Message-id: <199609111814.LAA10027@tcl.Somewhere.COM>} \
+ 5 {X-mailer: exmh version 1.6.9 8/22/96} \
+ 6 {Mime-version: 1.0} \
+ 7 {Content-type: text/plain; charset=iso-8859-1} \
+ 8 {Content-transfer-encoding: quoted-printable} \
+ 9 {Content-length: 2162} \
+ 10 {To: fred} \
+ 11 {Subject: tcl7.6} \
+ 12 {Date: Wed, 11 Sep 1996 11:14:53 -0700} \
+ 13 {From: George <george@tcl>} \
+ 14 {The Tcl 7.6 and Tk 4.2 releases} \
+ 15 {} \
+ 16 {This page contains information about Tcl 7.6 and Tk4.2, which are the most recent} \
+ 17 {releases of the Tcl scripting language and the Tk toolkit. The first beta versions of these} \
+ 18 {releases were released on August 30, 1996. These releases contain only minor changes,} \
+ 19 {so we hope to have only a single beta release and to go final in early October, 1996. } \
+ 20 {} \
+ 21 {} \
+ 22 {What's new } \
+ 23 {} \
+ 24 {The most important changes in the releases are summarized below. See the README} \
+ 25 {and changes files in the distributions for more complete information on what has} \
+ 26 {changed, including both feature changes and bug fixes. } \
+ 27 {} \
+ 28 { There are new options to the file command for copying files (file copy),} \
+ 29 { deleting files and directories (file delete), creating directories (file} \
+ 30 { mkdir), and renaming files (file rename). } \
+ 31 { The implementation of exec has been improved greatly for Windows 95 and} \
+ 32 { Windows NT. } \
+ 33 { There is a new memory allocator for the Macintosh version, which should be} \
+ 34 { more efficient than the old one. } \
+ 35 { Tk's grid geometry manager has been completely rewritten. The layout} \
+ 36 { algorithm produces much better layouts than before, especially where rows or} \
+ 37 { columns were stretchable. } \
+ 38 { There are new commands for creating common dialog boxes:} \
+ 39 { tk_chooseColor, tk_getOpenFile, tk_getSaveFile and} \
+ 40 { tk_messageBox. These use native dialog boxes if they are available. } \
+ 41 { There is a new virtual event mechanism for handling events in a more portable} \
+ 42 { way. See the new command event. It also allows events (both physical and} \
+ 43 { virtual) to be generated dynamically. } \
+ 44 {} \
+ 45 {Tcl 7.6 and Tk 4.2 are backwards-compatible with Tcl 7.5 and Tk 4.1 except for} \
+ 46 {changes in the C APIs for custom channel drivers. Scripts written for earlier releases} \
+ 47 {should work on these new releases as well. } \
+ 48 {} \
+ 49 {Obtaining The Releases} \
+ 50 {} \
+ 51 {Binary Releases} \
+ 52 {} \
+ 53 {Pre-compiled releases are available for the following platforms: } \
+ 54 {} \
+ 55 { Windows 3.1, Windows 95, and Windows NT: Fetch} \
+ 56 { ftp://ftp.sunlabs.com/pub/tcl/win42b1.exe, then execute it. The file is a} \
+ 57 { self-extracting executable. It will install the Tcl and Tk libraries, the wish and} \
+ 58 { tclsh programs, and documentation. } \
+ 59 { Macintosh (both 68K and PowerPC): Fetch} \
+ 60 { ftp://ftp.sunlabs.com/pub/tcl/mactk4.2b1.sea.hqx. The file is in binhex format,} \
+ 61 { which is understood by Fetch, StuffIt, and many other Mac utilities. The} \
+ 62 { unpacked file is a self-installing executable: double-click on it and it will create a} \
+ 63 { folder containing all that you need to run Tcl and Tk. } \
+ 64 { UNIX (Solaris 2.* and SunOS, other systems soon to follow). Easy to install} \
+ 65 { binary packages are now for sale at the Sun Labs Tcl/Tk Shop. Check it out!} \
+ }
+
+ set result ""
+ set NL "
+"
+ set tag {level= type=text/plain part=0 sel Charset}
+ set ix [lsearch -regexp $tag text/enriched]
+ if {$ix < 0} {
+ set ranges {}
+ set quote 0
+ }
+ set breakrange {6.42 78.0}
+ set F1 [lindex $breakrange 0]
+ set F2 [lindex $breakrange 1]
+ set breakrange [lrange $breakrange 2 end]
+ if {[string length $F1] == 0} {
+ set F1 -1
+ set break 0
+ } else {
+ set break 1
+ }
+
+ set xmailer 0
+ set inheaders 1
+ set last [array size lines]
+ set plen 2
+ for {set L 1} {$L < $last} {incr L} {
+ set line $lines($L)
+ if {$inheaders} {
+ # Blank or empty line terminates headers
+ # Leading --- terminates headers
+ if {[regexp {^[ ]*$} $line] || [regexp {^--+} $line]} {
+ set inheaders 0
+ }
+ if {[regexp -nocase {^x-mailer:} $line]} {
+ continue
+ }
+ }
+ if $inheaders {
+ set limit 55
+ } else {
+ set limit 55
+
+ # Decide whether or not to break the body line
+
+ if {$plen > 0} {
+ if {[string first {> } $line] == 0} {
+ # This is quoted text from previous message, don't reformat
+ append result $line $NL
+ if {$quote && !$inheaders} {
+ # Fix from <sarr@umich.edu> to handle text/enriched
+ if {$L > $L1 && $L < $L2 && $line != {}} {
+ # enriched requires two newlines for each one.
+ append result $NL
+ } elseif {$L > $L2} {
+ set L1 [lindex $ranges 0]
+ set L2 [lindex $ranges 1]
+ set ranges [lrange $ranges 2 end]
+ set quote [llength $L1]
+ }
+ }
+ continue
+ }
+ }
+ if {$F1 < 0} {
+ # Nothing left to format
+ append result $line $NL
+ continue
+ } elseif {$L < $F1} {
+ # Not yet to formatted block
+ append result $line $NL
+ continue
+ } elseif {$L > $F2} {
+ # Past formatted block
+ set F1 [lindex $breakrange 0]
+ set F2 [lindex $breakrange 1]
+ set breakrange [lrange $breakrange 2 end]
+ append result $line $NL
+ if {[string length $F1] == 0} {
+ set F1 -1
+ }
+ continue
+ }
+ }
+ set climit [expr $limit-1]
+ set cutoff 50
+ set continuation 0
+
+ while {[string length $line] > $limit} {
+ for {set c [expr $limit-1]} {$c >= $cutoff} {incr c -1} {
+ set char [string index $line $c]
+ if {$char == " " || $char == "\t"} {
+ break
+ }
+ if {$char == ">"} { ;# Hack for enriched formatting
+ break
+ }
+ }
+ if {$c < $cutoff} {
+ if {! $inheaders} {
+ set c [expr $limit-1]
+ } else {
+ set c [string length $line]
+ }
+ }
+ set newline [string range $line 0 $c]
+ if {! $continuation} {
+ append result $newline $NL
+ } else {
+ append result \ $newline $NL
+ }
+ incr c
+ set line [string trimright [string range $line $c end]]
+ if {$inheaders} {
+ set continuation 1
+ set limit $climit
+ }
+ }
+ if {$continuation} {
+ if {[string length $line] != 0} {
+ append result \ $line $NL
+ }
+ } else {
+ append result $line $NL
+ if {$quote && !$inheaders} {
+ if {$L > $L1 && $L < $L2 && $line != {}} {
+ # enriched requires two newlines for each one.
+ append result "" $NL
+ } elseif {$L > $L2} {
+ set L1 [lindex $ranges 0]
+ set L2 [lindex $ranges 1]
+ set ranges [lrange $ranges 2 end]
+ set quote [llength $L1]
+ }
+ }
+ }
+ }
+ return $result
+}
+test for-3.6 {break tests} {
+ formatMail
+} {Return-path: <george@tcl>
+Received: from tcl by tcl.Somewhere.COM (SMI-8.6/SMI-SVR4)
+ id LAA10027; Wed, 11 Sep 1996 11:14:53 -0700
+Message-id: <199609111814.LAA10027@tcl.Somewhere.COM>
+Mime-version: 1.0
+Content-type: text/plain; charset=iso-8859-1
+Content-transfer-encoding: quoted-printable
+Content-length: 2162
+To: fred
+Subject: tcl7.6
+Date: Wed, 11 Sep 1996 11:14:53 -0700
+From: George <george@tcl>
+The Tcl 7.6 and Tk 4.2 releases
+
+This page contains information about Tcl 7.6 and Tk4.2,
+ which are the most recent
+releases of the Tcl scripting language and the Tk toolk
+it. The first beta versions of these
+releases were released on August 30, 1996. These releas
+es contain only minor changes,
+so we hope to have only a single beta release and to
+go final in early October, 1996.
+
+
+What's new
+
+The most important changes in the releases are summariz
+ed below. See the README
+and changes files in the distributions for more complet
+e information on what has
+changed, including both feature changes and bug fixes.
+
+ There are new options to the file command for
+copying files (file copy),
+ deleting files and directories (file delete),
+creating directories (file
+ mkdir), and renaming files (file rename).
+ The implementation of exec has been improved great
+ly for Windows 95 and
+ Windows NT.
+ There is a new memory allocator for the Macintosh
+version, which should be
+ more efficient than the old one.
+ Tk's grid geometry manager has been completely
+rewritten. The layout
+ algorithm produces much better layouts than before
+, especially where rows or
+ columns were stretchable.
+ There are new commands for creating common dialog
+boxes:
+ tk_chooseColor, tk_getOpenFile, tk_getSaveFile and
+ tk_messageBox. These use native dialog boxes if
+they are available.
+ There is a new virtual event mechanism for handlin
+g events in a more portable
+ way. See the new command event. It also allows
+events (both physical and
+ virtual) to be generated dynamically.
+
+Tcl 7.6 and Tk 4.2 are backwards-compatible with Tcl
+7.5 and Tk 4.1 except for
+changes in the C APIs for custom channel drivers. Scrip
+ts written for earlier releases
+should work on these new releases as well.
+
+Obtaining The Releases
+
+Binary Releases
+
+Pre-compiled releases are available for the following
+platforms:
+
+ Windows 3.1, Windows 95, and Windows NT: Fetch
+ ftp://ftp.sunlabs.com/pub/tcl/win42b1.exe, then
+execute it. The file is a
+ self-extracting executable. It will install the
+Tcl and Tk libraries, the wish and
+ tclsh programs, and documentation.
+ Macintosh (both 68K and PowerPC): Fetch
+ ftp://ftp.sunlabs.com/pub/tcl/mactk4.2b1.sea.hqx.
+The file is in binhex format,
+ which is understood by Fetch, StuffIt, and many
+other Mac utilities. The
+ unpacked file is a self-installing executable:
+double-click on it and it will create a
+ folder containing all that you need to run Tcl
+and Tk.
+ UNIX (Solaris 2.* and SunOS, other systems
+soon to follow). Easy to install
+ binary packages are now for sale at the Sun Labs
+Tcl/Tk Shop. Check it out!
+}
+
+# Check that "break" resets the interpreter's result
+
+test for-4.1 {break must reset the interp result} {
+ catch {
+ set z GLOBTESTDIR/dir2/file2.c
+ if [string match GLOBTESTDIR/dir2/* $z] {
+ break
+ }
+ } j
+ set j
+} {}
+
+# Test for incorrect "double evaluation" semantics
+
+test for-5.1 {possible delayed substitution of increment command} {
+ # Increment should be 5, and lappend should always append $a
+ catch {unset a}
+ catch {unset i}
+ set a 5
+ set i {}
+ for {set a 1} {$a < 12} "incr a $a" {lappend i $a}
+ set i
+} {1 6 11}
+
+test for-5.2 {possible delayed substitution of increment command} {
+ # Increment should be 5, and lappend should always append $a
+ catch {rename p ""}
+ proc p {} {
+ set a 5
+ set i {}
+ for {set a 1} {$a < 12} "incr a $a" {lappend i $a}
+ set i
+ }
+ p
+} {1 6 11}
+test for-5.3 {possible delayed substitution of body command} {
+ # Increment should be $a, and lappend should always append 5
+ set a 5
+ set i {}
+ for {set a 1} {$a < 12} {incr a $a} "lappend i $a"
+ set i
+} {5 5 5 5}
+test for-5.4 {possible delayed substitution of body command} {
+ # Increment should be $a, and lappend should always append 5
+ catch {rename p ""}
+ proc p {} {
+ set a 5
+ set i {}
+ for {set a 1} {$a < 12} {incr a $a} "lappend i $a"
+ set i
+ }
+ p
+} {5 5 5 5}
+
+# In the following tests we need to bypass the bytecode compiler by
+# substituting the command from a variable. This ensures that command
+# procedure is invoked directly.
+
+test for-6.1 {Tcl_ForObjCmd: number of args} {
+ set z for
+ catch {$z} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-6.2 {Tcl_ForObjCmd: number of args} {
+ set z for
+ catch {$z {set i 0}} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-6.3 {Tcl_ForObjCmd: number of args} {
+ set z for
+ catch {$z {set i 0} {$i < 5}} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-6.4 {Tcl_ForObjCmd: number of args} {
+ set z for
+ catch {$z {set i 0} {$i < 5} {incr i}} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-6.5 {Tcl_ForObjCmd: number of args} {
+ set z for
+ catch {$z {set i 0} {$i < 5} {incr i} {body} extra} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-6.6 {Tcl_ForObjCmd: error in initial command} -body {
+ set z for
+ list [catch {$z {set} {$i < 5} {incr i} {body}} msg] $msg $::errorInfo
+} -match glob -result {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"
+ ("for" initial command)
+ invoked from within
+"$z {set} {$i < 5} {incr i} {body}"}}
+test for-6.7 {Tcl_ForObjCmd: error in test expression} -body {
+ set z for
+ catch {$z {set i 0} {i < 5} {incr i} {body}}
+ set ::errorInfo
+} -match glob -result {*"$z {set i 0} {i < 5} {incr i} {body}"}
+test for-6.8 {Tcl_ForObjCmd: test expression is enclosed in quotes} {
+ set z for
+ set i 0
+ $z {set i 6} "$i > 5" {incr i} {set y $i}
+ set i
+} 6
+test for-6.9 {Tcl_ForObjCmd: error executing command body} -body {
+ set z for
+ catch {$z {set i 0} {$i < 5} {incr i} {set}} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"
+ ("for" body line 1)
+ invoked from within
+"$z {set i 0} {$i < 5} {incr i} {set}"}
+test for-6.10 {Tcl_ForObjCmd: simple command body} {
+ set z for
+ set a {}
+ $z {set i 1} {$i<6} {set i [expr $i+1]} {
+ if $i==4 break
+ set a [concat $a $i]
+ }
+ set a
+} {1 2 3}
+test for-6.11 {Tcl_ForObjCmd: command body in quotes} {
+ set z for
+ set a {}
+ $z {set i 1} {$i<6} {set i [expr $i+1]} "append a x"
+ set a
+} {xxxxx}
+test for-6.12 {Tcl_ForObjCmd: computed command body} {
+ set z for
+ catch {unset x1}
+ catch {unset bb}
+ catch {unset x2}
+ set x1 {append a x1; }
+ set bb {break}
+ set x2 {; append a x2}
+ set a {}
+ $z {set i 1} {$i<6} {set i [expr $i+1]} $x1$bb$x2
+ set a
+} {x1}
+test for-6.13 {Tcl_ForObjCmd: error in "next" command} -body {
+ set z for
+ catch {$z {set i 0} {$i < 5} {set} {set j 4}} msg
+ set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"
+ ("for" loop-end command)
+ invoked from within
+"$z {set i 0} {$i < 5} {set} {set j 4}"}
+test for-6.14 {Tcl_ForObjCmd: long command body} {
+ set z for
+ set a {}
+ $z {set i 1} {$i<6} {set i [expr $i+1]} {
+ if $i==4 break
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ }
+ set a
+} {1 2 3}
+test for-6.15 {Tcl_ForObjCmd: for command result} {
+ set z for
+ set a [$z {set i 0} {$i < 5} {incr i} {}]
+ set a
+} {}
+test for-6.16 {Tcl_ForObjCmd: for command result} {
+ set z for
+ set a [$z {set i 0} {$i < 5} {incr i} {if $i==3 break}]
+ set a
+} {}
+test for-6.17 {Tcl_ForObjCmd: for command result} {
+ list \
+ [catch {for {break} {1} {} {}} err] $err \
+ [catch {for {continue} {1} {} {}} err] $err \
+ [catch {for {} {[break]} {} {}} err] $err \
+ [catch {for {} {[continue]} {} {}} err] $err \
+ [catch {for {} {1} {break} {}} err] $err \
+ [catch {for {} {1} {continue} {}} err] $err \
+} [list \
+ 3 {} \
+ 4 {} \
+ 3 {} \
+ 4 {} \
+ 0 {} \
+ 4 {} \
+ ]
+test for-6.18 {Tcl_ForObjCmd: for command result} {
+ proc p6181 {} {
+ for {break} {1} {} {}
+ }
+ proc p6182 {} {
+ for {continue} {1} {} {}
+ }
+ proc p6183 {} {
+ for {} {[break]} {} {}
+ }
+ proc p6184 {} {
+ for {} {[continue]} {} {}
+ }
+ proc p6185 {} {
+ for {} {1} {break} {}
+ }
+ proc p6186 {} {
+ for {} {1} {continue} {}
+ }
+ list \
+ [catch {p6181} err] $err \
+ [catch {p6182} err] $err \
+ [catch {p6183} err] $err \
+ [catch {p6184} err] $err \
+ [catch {p6185} err] $err \
+ [catch {p6186} err] $err
+} [list \
+ 1 {invoked "break" outside of a loop} \
+ 1 {invoked "continue" outside of a loop} \
+ 1 {invoked "break" outside of a loop} \
+ 1 {invoked "continue" outside of a loop} \
+ 0 {} \
+ 1 {invoked "continue" outside of a loop} \
+ ]
+
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/foreach.test b/pkgs/msgcat/tests/foreach.test
new file mode 100644
index 0000000..a4b652a
--- /dev/null
+++ b/pkgs/msgcat/tests/foreach.test
@@ -0,0 +1,274 @@
+# Commands covered: foreach, continue, break
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+catch {unset a}
+catch {unset x}
+
+# Basic "foreach" operation.
+
+test foreach-1.1 {basic foreach tests} {
+ set a {}
+ foreach i {a b c d} {
+ set a [concat $a $i]
+ }
+ set a
+} {a b c d}
+test foreach-1.2 {basic foreach tests} {
+ set a {}
+ foreach i {a b {{c d} e} {123 {{x}}}} {
+ set a [concat $a $i]
+ }
+ set a
+} {a b {c d} e 123 {{x}}}
+test foreach-1.3 {basic foreach tests} {catch {foreach} msg} 1
+test foreach-1.4 {basic foreach tests} {
+ catch {foreach} msg
+ set msg
+} {wrong # args: should be "foreach varList list ?varList list ...? command"}
+test foreach-1.5 {basic foreach tests} {catch {foreach i} msg} 1
+test foreach-1.6 {basic foreach tests} {
+ catch {foreach i} msg
+ set msg
+} {wrong # args: should be "foreach varList list ?varList list ...? command"}
+test foreach-1.7 {basic foreach tests} {catch {foreach i j} msg} 1
+test foreach-1.8 {basic foreach tests} {
+ catch {foreach i j} msg
+ set msg
+} {wrong # args: should be "foreach varList list ?varList list ...? command"}
+test foreach-1.9 {basic foreach tests} {catch {foreach i j k l} msg} 1
+test foreach-1.10 {basic foreach tests} {
+ catch {foreach i j k l} msg
+ set msg
+} {wrong # args: should be "foreach varList list ?varList list ...? command"}
+test foreach-1.11 {basic foreach tests} {
+ set a {}
+ foreach i {} {
+ set a [concat $a $i]
+ }
+ set a
+} {}
+test foreach-1.12 {foreach errors} {
+ list [catch {foreach {{a}{b}} {1 2 3} {}} msg] $msg
+} {1 {list element in braces followed by "{b}" instead of space}}
+test foreach-1.13 {foreach errors} {
+ list [catch {foreach a {{1 2}3} {}} msg] $msg
+} {1 {list element in braces followed by "3" instead of space}}
+catch {unset a}
+test foreach-1.14 {foreach errors} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {foreach a {1 2 3} {}} msg o] $msg $::errorInfo
+} {1 {can't set "a": variable is array} {can't set "a": variable is array
+ (setting foreach loop variable "a")
+ invoked from within
+"foreach a {1 2 3} {}"}}
+test foreach-1.15 {foreach errors} {
+ list [catch {foreach {} {} {}} msg] $msg
+} {1 {foreach varlist is empty}}
+catch {unset a}
+
+test foreach-2.1 {parallel foreach tests} {
+ set x {}
+ foreach {a b} {1 2 3 4} {
+ append x $b $a
+ }
+ set x
+} {2143}
+test foreach-2.2 {parallel foreach tests} {
+ set x {}
+ foreach {a b} {1 2 3 4 5} {
+ append x $b $a
+ }
+ set x
+} {21435}
+test foreach-2.3 {parallel foreach tests} {
+ set x {}
+ foreach a {1 2 3} b {4 5 6} {
+ append x $b $a
+ }
+ set x
+} {415263}
+test foreach-2.4 {parallel foreach tests} {
+ set x {}
+ foreach a {1 2 3} b {4 5 6 7 8} {
+ append x $b $a
+ }
+ set x
+} {41526378}
+test foreach-2.5 {parallel foreach tests} {
+ set x {}
+ foreach {a b} {a b A B aa bb} c {c C cc CC} {
+ append x $a $b $c
+ }
+ set x
+} {abcABCaabbccCC}
+test foreach-2.6 {parallel foreach tests} {
+ set x {}
+ foreach a {1 2 3} b {1 2 3} c {1 2 3} d {1 2 3} e {1 2 3} {
+ append x $a $b $c $d $e
+ }
+ set x
+} {111112222233333}
+test foreach-2.7 {parallel foreach tests} {
+ set x {}
+ foreach a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
+ append x $a $b $c $d $e
+ }
+ set x
+} {1111 2222334}
+test foreach-2.8 {foreach only sets vars if repeating loop} {
+ proc foo {} {
+ set rgb {65535 0 0}
+ foreach {r g b} [set rgb] {}
+ return "r=$r, g=$g, b=$b"
+ }
+ foo
+} {r=65535, g=0, b=0}
+test foreach-2.9 {foreach only supports local scalar variables} {
+ proc foo {} {
+ set x {}
+ foreach {a(3)} {1 2 3 4} {lappend x [set {a(3)}]}
+ set x
+ }
+ foo
+} {1 2 3 4}
+
+test foreach-3.1 {compiled foreach backward jump works correctly} {
+ catch {unset x}
+ proc foo {arrayName} {
+ upvar 1 $arrayName a
+ set l {}
+ foreach member [array names a] {
+ lappend l [list $member [set a($member)]]
+ }
+ return $l
+ }
+ array set x {0 zero 1 one 2 two 3 three}
+ lsort [foo x]
+} [lsort {{0 zero} {1 one} {2 two} {3 three}}]
+
+test foreach-4.1 {noncompiled foreach and shared variable or value list objects that are converted to another type} {
+ catch {unset x}
+ foreach {12.0} {a b c} {
+ set x 12.0
+ set x [expr $x + 1]
+ }
+ set x
+} 13.0
+
+# Check "continue".
+
+test foreach-5.1 {continue tests} {catch continue} 4
+test foreach-5.2 {continue tests} {
+ set a {}
+ foreach i {a b c d} {
+ if {[string compare $i "b"] == 0} continue
+ set a [concat $a $i]
+ }
+ set a
+} {a c d}
+test foreach-5.3 {continue tests} {
+ set a {}
+ foreach i {a b c d} {
+ if {[string compare $i "b"] != 0} continue
+ set a [concat $a $i]
+ }
+ set a
+} {b}
+test foreach-5.4 {continue tests} {catch {continue foo} msg} 1
+test foreach-5.5 {continue tests} {
+ catch {continue foo} msg
+ set msg
+} {wrong # args: should be "continue"}
+
+# Check "break".
+
+test foreach-6.1 {break tests} {catch break} 3
+test foreach-6.2 {break tests} {
+ set a {}
+ foreach i {a b c d} {
+ if {[string compare $i "c"] == 0} break
+ set a [concat $a $i]
+ }
+ set a
+} {a b}
+test foreach-6.3 {break tests} {catch {break foo} msg} 1
+test foreach-6.4 {break tests} {
+ catch {break foo} msg
+ set msg
+} {wrong # args: should be "break"}
+# Check for bug #406709
+test foreach-6.5 {break tests} {
+ proc a {} {
+ set a 1
+ foreach b b {list [concat a; break]; incr a}
+ incr a
+ }
+ a
+} {2}
+
+# Test for incorrect "double evaluation" semantics
+test foreach-7.1 {delayed substitution of body} {
+ proc foo {} {
+ set a 0
+ foreach a [list 1 2 3] "
+ set x $a
+ "
+ set x
+ }
+ foo
+} {0}
+
+# Test for [Bug 1189274]; crash on failure
+test foreach-8.1 {empty list handling} {
+ proc crash {} {
+ rename crash {}
+ set a "x y z"
+ set b ""
+ foreach aa $a bb $b { set x "aa = $aa bb = $bb" }
+ }
+ crash
+} {}
+
+# [Bug 1671138]; infinite loop with empty var list in bytecompiled version
+test foreach-9.1 {compiled empty var list} {
+ proc foo {} {
+ foreach {} x {
+ error "reached body"
+ }
+ }
+ list [catch { foo } msg] $msg
+} {1 {foreach varlist is empty}}
+
+test foreach-10.1 {foreach: [Bug 1671087]} -setup {
+ proc demo {} {
+ set vals {1 2 3 4}
+ trace add variable x write {string length $vals ;# }
+ foreach {x y} $vals {format $y}
+ }
+} -body {
+ demo
+} -cleanup {
+ rename demo {}
+} -result {}
+
+# cleanup
+catch {unset a}
+catch {unset x}
+catch {rename foo {}}
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/format.test b/pkgs/msgcat/tests/format.test
new file mode 100644
index 0000000..2d53eba
--- /dev/null
+++ b/pkgs/msgcat/tests/format.test
@@ -0,0 +1,584 @@
+# Commands covered: format
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# %u output depends on word length, so this test is not portable.
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}]
+testConstraint wideIs64bit \
+ [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}]
+testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}]
+
+test format-1.1 {integer formatting} {
+ format "%*d %d %d %d" 6 34 16923 -12 -1
+} { 34 16923 -12 -1}
+test format-1.2 {integer formatting} {
+ format "%4d %4d %4d %4d %d %#x %#X" 6 34 16923 -12 -1 14 12
+} { 6 34 16923 -12 -1 0xe 0XC}
+test format-1.3 {integer formatting} longIs32bit {
+ format "%4u %4u %4u %4u %d %#o" 6 34 16923 -12 -1 0
+} { 6 34 16923 4294967284 -1 0}
+test format-1.3.1 {integer formatting} longIs64bit {
+ format "%4u %4u %4u %4u %d %#o" 6 34 16923 -12 -1 0
+} { 6 34 16923 18446744073709551604 -1 0}
+test format-1.4 {integer formatting} {
+ format "%-4d %-4i %-4d %-4ld" 6 34 16923 -12 -1
+} {6 34 16923 -12 }
+test format-1.5 {integer formatting} {
+ format "%04d %04d %04d %04i" 6 34 16923 -12 -1
+} {0006 0034 16923 -012}
+test format-1.6 {integer formatting} {
+ format "%00*d" 6 34
+} {000034}
+# Printing negative numbers in hex or octal format depends on word
+# length, so these tests are not portable.
+test format-1.7 {integer formatting} longIs32bit {
+ format "%4x %4x %4x %4x" 6 34 16923 -12 -1
+} { 6 22 421b fffffff4}
+test format-1.7.1 {integer formatting} longIs64bit {
+ format "%4x %4x %4x %4x" 6 34 16923 -12 -1
+} { 6 22 421b fffffffffffffff4}
+test format-1.8 {integer formatting} longIs32bit {
+ format "%#x %#X %#X %#x" 6 34 16923 -12 -1
+} {0x6 0X22 0X421B 0xfffffff4}
+test format-1.8.1 {integer formatting} longIs64bit {
+ format "%#x %#X %#X %#x" 6 34 16923 -12 -1
+} {0x6 0X22 0X421B 0xfffffffffffffff4}
+test format-1.9 {integer formatting} longIs32bit {
+ format "%#20x %#20x %#20x %#20x" 6 34 16923 -12 -1
+} { 0x6 0x22 0x421b 0xfffffff4}
+test format-1.9.1 {integer formatting} longIs64bit {
+ format "%#20x %#20x %#20x %#20x" 6 34 16923 -12 -1
+} { 0x6 0x22 0x421b 0xfffffffffffffff4}
+test format-1.10 {integer formatting} longIs32bit {
+ format "%-#20x %-#20x %-#20x %-#20x" 6 34 16923 -12 -1
+} {0x6 0x22 0x421b 0xfffffff4 }
+test format-1.10.1 {integer formatting} longIs64bit {
+ format "%-#20x %-#20x %-#20x %-#20x" 6 34 16923 -12 -1
+} {0x6 0x22 0x421b 0xfffffffffffffff4 }
+test format-1.11 {integer formatting} longIs32bit {
+ format "%-#20o %#-20o %#-20o %#-20o" 6 34 16923 -12 -1
+} {06 042 041033 037777777764 }
+test format-1.11.1 {integer formatting} longIs64bit {
+ format "%-#20o %#-20o %#-20o %#-20o" 6 34 16923 -12 -1
+} {06 042 041033 01777777777777777777764}
+test format-1.12 {integer formatting} {
+ format "%b %#b %llb" 5 5 [expr {2**100}]
+} {101 0b101 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000}
+
+test format-2.1 {string formatting} {
+ format "%s %s %c %s" abcd {This is a very long test string.} 120 x
+} {abcd This is a very long test string. x x}
+test format-2.2 {string formatting} {
+ format "%20s %20s %20c %20s" abcd {This is a very long test string.} 120 x
+} { abcd This is a very long test string. x x}
+test format-2.3 {string formatting} {
+ format "%.10s %.10s %c %.10s" abcd {This is a very long test string.} 120 x
+} {abcd This is a x x}
+test format-2.4 {string formatting} {
+ format "%s %s %% %c %s" abcd {This is a very long test string.} 120 x
+} {abcd This is a very long test string. % x x}
+test format-2.5 {string formatting, embedded nulls} {
+ format "%10s" abc\0def
+} " abc\0def"
+test format-2.6 {string formatting, international chars} {
+ format "%10s" abc\ufeffdef
+} " abc\ufeffdef"
+test format-2.7 {string formatting, international chars} {
+ format "%.5s" abc\ufeffdef
+} "abc\ufeffd"
+test format-2.8 {string formatting, international chars} {
+ format "foo\ufeffbar%s" baz
+} "foo\ufeffbarbaz"
+test format-2.9 {string formatting, width} {
+ format "a%5sa" f
+} "a fa"
+test format-2.10 {string formatting, width} {
+ format "a%-5sa" f
+} "af a"
+test format-2.11 {string formatting, width} {
+ format "a%2sa" foo
+} "afooa"
+test format-2.12 {string formatting, width} {
+ format "a%0sa" foo
+} "afooa"
+test format-2.13 {string formatting, precision} {
+ format "a%.2sa" foobarbaz
+} "afoa"
+test format-2.14 {string formatting, precision} {
+ format "a%.sa" foobarbaz
+} "aa"
+test format-2.15 {string formatting, precision} {
+ list [catch {format "a%.-2sa" foobarbaz} msg] $msg
+} {1 {bad field specifier "-"}}
+test format-2.16 {string formatting, width and precision} {
+ format "a%5.2sa" foobarbaz
+} "a foa"
+test format-2.17 {string formatting, width and precision} {
+ format "a%5.7sa" foobarbaz
+} "afoobarba"
+
+test format-3.1 {Tcl_FormatObjCmd: character formatting} {
+ format "|%c|%0c|%-1c|%1c|%-6c|%6c|%*c|%*c|" 65 65 65 65 65 65 3 65 -4 65
+} "|A|A|A|A|A | A| A|A |"
+test format-3.2 {Tcl_FormatObjCmd: international character formatting} {
+ format "|%c|%0c|%-1c|%1c|%-6c|%6c|%*c|%*c|" 0xa2 0x4e4e 0x25a 0xc3 0xff08 0 3 0x6575 -4 0x4e4f
+} "|\ua2|\u4e4e|\u25a|\uc3|\uff08 | \0| \u6575|\u4e4f |"
+
+test format-4.1 {e and f formats} {eformat} {
+ format "%e %e %e %e" 34.2e12 68.514 -.125 -16000. .000053
+} {3.420000e+13 6.851400e+01 -1.250000e-01 -1.600000e+04}
+test format-4.2 {e and f formats} {eformat} {
+ format "%20e %20e %20e %20e" 34.2e12 68.514 -.125 -16000. .000053
+} { 3.420000e+13 6.851400e+01 -1.250000e-01 -1.600000e+04}
+test format-4.3 {e and f formats} {eformat} {
+ format "%.1e %.1e %.1e %.1e" 34.2e12 68.514 -.126 -16000. .000053
+} {3.4e+13 6.9e+01 -1.3e-01 -1.6e+04}
+test format-4.4 {e and f formats} {eformat} {
+ format "%020e %020e %020e %020e" 34.2e12 68.514 -.126 -16000. .000053
+} {000000003.420000e+13 000000006.851400e+01 -00000001.260000e-01 -00000001.600000e+04}
+test format-4.5 {e and f formats} {eformat} {
+ format "%7.1e %7.1e %7.1e %7.1e" 34.2e12 68.514 -.126 -16000. .000053
+} {3.4e+13 6.9e+01 -1.3e-01 -1.6e+04}
+test format-4.6 {e and f formats} {
+ format "%f %f %f %f" 34.2e12 68.514 -.125 -16000. .000053
+} {34200000000000.000000 68.514000 -0.125000 -16000.000000}
+test format-4.7 {e and f formats} {
+ format "%.4f %.4f %.4f %.4f %.4f" 34.2e12 68.514 -.125 -16000. .000053
+} {34200000000000.0000 68.5140 -0.1250 -16000.0000 0.0001}
+test format-4.8 {e and f formats} {eformat} {
+ format "%.4e %.5e %.6e" -9.99996 -9.99996 9.99996
+} {-1.0000e+01 -9.99996e+00 9.999960e+00}
+test format-4.9 {e and f formats} {
+ format "%.4f %.5f %.6f" -9.99996 -9.99996 9.99996
+} {-10.0000 -9.99996 9.999960}
+test format-4.10 {e and f formats} {
+ format "%20f %-20f %020f" -9.99996 -9.99996 9.99996
+} { -9.999960 -9.999960 0000000000009.999960}
+test format-4.11 {e and f formats} {
+ format "%-020f %020f" -9.99996 -9.99996 9.99996
+} {-9.999960 -000000000009.999960}
+test format-4.12 {e and f formats} {eformat} {
+ format "%.0e %#.0e" -9.99996 -9.99996 9.99996
+} {-1e+01 -1.e+01}
+test format-4.13 {e and f formats} {
+ format "%.0f %#.0f" -9.99996 -9.99996 9.99996
+} {-10 -10.}
+test format-4.14 {e and f formats} {
+ format "%.4f %.5f %.6f" -9.99996 -9.99996 9.99996
+} {-10.0000 -9.99996 9.999960}
+test format-4.15 {e and f formats} {
+ format "%3.0f %3.0f %3.0f %3.0f" 1.0 1.1 1.01 1.001
+} { 1 1 1 1}
+test format-4.16 {e and f formats} {
+ format "%3.1f %3.1f %3.1f %3.1f" 0.0 0.1 0.01 0.001
+} {0.0 0.1 0.0 0.0}
+
+test format-5.1 {g-format} {eformat} {
+ format "%.3g" 12341.0
+} {1.23e+04}
+test format-5.2 {g-format} {eformat} {
+ format "%.3G" 1234.12345
+} {1.23E+03}
+test format-5.3 {g-format} {
+ format "%.3g" 123.412345
+} {123}
+test format-5.4 {g-format} {
+ format "%.3g" 12.3412345
+} {12.3}
+test format-5.5 {g-format} {
+ format "%.3g" 1.23412345
+} {1.23}
+test format-5.6 {g-format} {
+ format "%.3g" 1.23412345
+} {1.23}
+test format-5.7 {g-format} {
+ format "%.3g" .123412345
+} {0.123}
+test format-5.8 {g-format} {
+ format "%.3g" .012341
+} {0.0123}
+test format-5.9 {g-format} {
+ format "%.3g" .0012341
+} {0.00123}
+test format-5.10 {g-format} {
+ format "%.3g" .00012341
+} {0.000123}
+test format-5.11 {g-format} {eformat} {
+ format "%.3g" .00001234
+} {1.23e-05}
+test format-5.12 {g-format} {eformat} {
+ format "%.4g" 9999.6
+} {1e+04}
+test format-5.13 {g-format} {
+ format "%.4g" 999.96
+} {1000}
+test format-5.14 {g-format} {
+ format "%.3g" 1.0
+} {1}
+test format-5.15 {g-format} {
+ format "%.3g" .1
+} {0.1}
+test format-5.16 {g-format} {
+ format "%.3g" .01
+} {0.01}
+test format-5.17 {g-format} {
+ format "%.3g" .001
+} {0.001}
+test format-5.18 {g-format} {eformat} {
+ format "%.3g" .00001
+} {1e-05}
+test format-5.19 {g-format} {eformat} {
+ format "%#.3g" 1234.0
+} {1.23e+03}
+test format-5.20 {g-format} {eformat} {
+ format "%#.3G" 9999.5
+} {1.00E+04}
+
+test format-6.1 {floating-point zeroes} {eformat} {
+ format "%e %f %g" 0.0 0.0 0.0 0.0
+} {0.000000e+00 0.000000 0}
+test format-6.2 {floating-point zeroes} {eformat} {
+ format "%.4e %.4f %.4g" 0.0 0.0 0.0 0.0
+} {0.0000e+00 0.0000 0}
+test format-6.3 {floating-point zeroes} {eformat} {
+ format "%#.4e %#.4f %#.4g" 0.0 0.0 0.0 0.0
+} {0.0000e+00 0.0000 0.000}
+test format-6.4 {floating-point zeroes} {eformat} {
+ format "%.0e %.0f %.0g" 0.0 0.0 0.0 0.0
+} {0e+00 0 0}
+test format-6.5 {floating-point zeroes} {eformat} {
+ format "%#.0e %#.0f %#.0g" 0.0 0.0 0.0 0.0
+} {0.e+00 0. 0.}
+test format-6.6 {floating-point zeroes} {
+ format "%3.0f %3.0f %3.0f %3.0f" 0.0 0.0 0.0 0.0
+} { 0 0 0 0}
+test format-6.7 {floating-point zeroes} {
+ format "%3.0f %3.0f %3.0f %3.0f" 1.0 1.1 1.01 1.001
+} { 1 1 1 1}
+test format-6.8 {floating-point zeroes} {
+ format "%3.1f %3.1f %3.1f %3.1f" 0.0 0.1 0.01 0.001
+} {0.0 0.1 0.0 0.0}
+
+test format-7.1 {various syntax features} {
+ format "%*.*f" 12 3 12.345678901
+} { 12.346}
+test format-7.2 {various syntax features} {
+ format "%0*.*f" 12 3 12.345678901
+} {00000012.346}
+test format-7.3 {various syntax features} {
+ format "\*\t\\n"
+} {* \n}
+
+test format-8.1 {error conditions} {
+ catch format
+} 1
+test format-8.2 {error conditions} {
+ catch format msg
+ set msg
+} {wrong # args: should be "format formatString ?arg ...?"}
+test format-8.3 {error conditions} {
+ catch {format %*d}
+} 1
+test format-8.4 {error conditions} {
+ catch {format %*d} msg
+ set msg
+} {not enough arguments for all format specifiers}
+test format-8.5 {error conditions} {
+ catch {format %*.*f 12}
+} 1
+test format-8.6 {error conditions} {
+ catch {format %*.*f 12} msg
+ set msg
+} {not enough arguments for all format specifiers}
+test format-8.7 {error conditions} {
+ catch {format %*.*f 12 3}
+} 1
+test format-8.8 {error conditions} {
+ catch {format %*.*f 12 3} msg
+ set msg
+} {not enough arguments for all format specifiers}
+test format-8.9 {error conditions} {
+ list [catch {format %*d x 3} msg] $msg
+} {1 {expected integer but got "x"}}
+test format-8.10 {error conditions} {
+ list [catch {format %*.*f 2 xyz 3} msg] $msg
+} {1 {expected integer but got "xyz"}}
+test format-8.11 {error conditions} {
+ catch {format %d 2a}
+} 1
+test format-8.12 {error conditions} {
+ catch {format %d 2a} msg
+ set msg
+} {expected integer but got "2a"}
+test format-8.13 {error conditions} {
+ catch {format %c 2x}
+} 1
+test format-8.14 {error conditions} {
+ catch {format %c 2x} msg
+ set msg
+} {expected integer but got "2x"}
+test format-8.15 {error conditions} {
+ catch {format %f 2.1z}
+} 1
+test format-8.16 {error conditions} {
+ catch {format %f 2.1z} msg
+ set msg
+} {expected floating-point number but got "2.1z"}
+test format-8.17 {error conditions} {
+ catch {format ab%}
+} 1
+test format-8.18 {error conditions} {
+ catch {format ab% 12} msg
+ set msg
+} {format string ended in middle of field specifier}
+test format-8.19 {error conditions} {
+ catch {format %q x}
+} 1
+test format-8.20 {error conditions} {
+ catch {format %q x} msg
+ set msg
+} {bad field specifier "q"}
+test format-8.21 {error conditions} {
+ catch {format %d}
+} 1
+test format-8.22 {error conditions} {
+ catch {format %d} msg
+ set msg
+} {not enough arguments for all format specifiers}
+test format-8.23 {error conditions} {
+ catch {format "%d %d" 24 xyz} msg
+ set msg
+} {expected integer but got "xyz"}
+
+test format-9.1 {long result} {
+ set a {1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z}
+ format {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG %s %s} $a $a
+} {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z}
+
+test format-10.1 {"h" format specifier} {
+ format %hd 0xffff
+} -1
+test format-10.2 {"h" format specifier} {
+ format %hx 0x10fff
+} fff
+test format-10.3 {"h" format specifier} {
+ format %hd 0x10000
+} 0
+test format-10.4 {"h" format specifier} {
+ # Bug 1154163: This is minimal behaviour for %hx specifier!
+ format %hx 1
+} 1
+test format-10.5 {"h" format specifier} {
+ # Bug 1284178: Highly out-of-range values shouldn't cause errors
+ format %hu 0x100000000
+} 0
+
+test format-11.1 {XPG3 %$n specifiers} {
+ format {%2$d %1$d} 4 5
+} {5 4}
+test format-11.2 {XPG3 %$n specifiers} {
+ format {%2$d %1$d %1$d %3$d} 4 5 6
+} {5 4 4 6}
+test format-11.3 {XPG3 %$n specifiers} {
+ list [catch {format {%2$d %3$d} 4 5} msg] $msg
+} {1 {"%n$" argument index out of range}}
+test format-11.4 {XPG3 %$n specifiers} {
+ list [catch {format {%2$d %0$d} 4 5 6} msg] $msg
+} {1 {"%n$" argument index out of range}}
+test format-11.5 {XPG3 %$n specifiers} {
+ list [catch {format {%d %1$d} 4 5 6} msg] $msg
+} {1 {cannot mix "%" and "%n$" conversion specifiers}}
+test format-11.6 {XPG3 %$n specifiers} {
+ list [catch {format {%2$d %d} 4 5 6} msg] $msg
+} {1 {cannot mix "%" and "%n$" conversion specifiers}}
+test format-11.7 {XPG3 %$n specifiers} {
+ list [catch {format {%2$d %3d} 4 5 6} msg] $msg
+} {1 {cannot mix "%" and "%n$" conversion specifiers}}
+test format-11.8 {XPG3 %$n specifiers} {
+ format {%2$*d %3$d} 1 10 4
+} { 4 4}
+test format-11.9 {XPG3 %$n specifiers} {
+ format {%2$.*s %4$d} 1 5 abcdefghijklmnop 44
+} {abcde 44}
+test format-11.10 {XPG3 %$n specifiers} {
+ list [catch {format {%2$*d} 4} msg] $msg
+} {1 {"%n$" argument index out of range}}
+test format-11.11 {XPG3 %$n specifiers} {
+ list [catch {format {%2$*d} 4 5} msg] $msg
+} {1 {"%n$" argument index out of range}}
+test format-11.12 {XPG3 %$n specifiers} {
+ list [catch {format {%2$*d} 4 5 6} msg] $msg
+} {0 { 6}}
+
+test format-12.1 {negative width specifiers} {
+ format "%*d" -47 25
+} {25 }
+
+test format-13.1 {tcl_precision fuzzy comparison} {
+ catch {unset a}
+ catch {unset b}
+ catch {unset c}
+ catch {unset d}
+ set a 0.0000000000001
+ set b 0.00000000000001
+ set c 0.00000000000000001
+ set d [expr $a + $b + $c]
+ format {%0.10f %0.12f %0.15f %0.17f} $d $d $d $d
+} {0.0000000000 0.000000000000 0.000000000000110 0.00000000000011001}
+test format-13.2 {tcl_precision fuzzy comparison} {
+ catch {unset a}
+ catch {unset b}
+ catch {unset c}
+ catch {unset d}
+ set a 0.000000000001
+ set b 0.000000000000005
+ set c 0.0000000000000008
+ set d [expr $a + $b + $c]
+ format {%0.10f %0.12f %0.15f %0.17f} $d $d $d $d
+} {0.0000000000 0.000000000001 0.000000000001006 0.00000000000100580}
+test format-13.3 {tcl_precision fuzzy comparison} {
+ catch {unset a}
+ catch {unset b}
+ catch {unset c}
+ set a 0.00000000000099
+ set b 0.000000000000011
+ set c [expr $a + $b]
+ format {%0.10f %0.12f %0.15f %0.17f} $c $c $c $c
+} {0.0000000000 0.000000000001 0.000000000001001 0.00000000000100100}
+test format-13.4 {tcl_precision fuzzy comparison} {
+ catch {unset a}
+ catch {unset b}
+ catch {unset c}
+ set a 0.444444444444
+ set b 0.33333333333333
+ set c [expr $a + $b]
+ format {%0.10f %0.12f %0.15f %0.16f} $c $c $c $c
+} {0.7777777778 0.777777777777 0.777777777777330 0.7777777777773300}
+test format-13.5 {tcl_precision fuzzy comparison} {
+ catch {unset a}
+ catch {unset b}
+ catch {unset c}
+ set a 0.444444444444
+ set b 0.99999999999999
+ set c [expr $a + $b]
+ format {%0.10f %0.12f %0.15f} $c $c $c
+} {1.4444444444 1.444444444444 1.444444444443990}
+
+test format-14.1 {testing MAX_FLOAT_SIZE for 0 and 1} {
+ format {%s} ""
+} {}
+test format-14.2 {testing MAX_FLOAT_SIZE for 0 and 1} {
+ format {%s} "a"
+} {a}
+
+test format-15.1 {testing %0..s 0 padding for chars/strings} {
+ format %05s a
+} {0000a}
+test format-15.2 {testing %0..s 0 padding for chars/strings} {
+ format "% 5s" a
+} { a}
+test format-15.3 {testing %0..s 0 padding for chars/strings} {
+ format %5s a
+} { a}
+test format-15.4 {testing %0..s 0 padding for chars/strings} {
+ format %05c 61
+} {0000=}
+test format-15.5 {testing %d space padding for integers} {
+ format "(% 1d) (% 1d)" 10 -10
+} {( 10) (-10)}
+test format-15.6 {testing %d plus padding for integers} {
+ format "(%+1d) (%+1d)" 10 -10
+} {(+10) (-10)}
+
+set a "0123456789"
+set b ""
+for {set i 0} {$i < 290} {incr i} {
+ append b $a
+}
+for {set i 290} {$i < 400} {incr i} {
+ test format-16.[expr $i -289] {testing MAX_FLOAT_SIZE} {
+ format {%s} $b
+ } $b
+ append b "x"
+}
+
+test format-17.1 {testing %d with wide} {wideIs64bit wideBiggerThanInt} {
+ format %d 7810179016327718216
+} 1819043144
+test format-17.2 {testing %ld with wide} {wideIs64bit} {
+ format %ld 7810179016327718216
+} 7810179016327718216
+test format-17.3 {testing %ld with non-wide} {wideIs64bit} {
+ format %ld 42
+} 42
+test format-17.4 {testing %l with non-integer} {
+ format %lf 1
+} 1.000000
+
+test format-18.1 {do not demote existing numeric values} {
+ set a 0xaaaaaaaa
+ # Ensure $a and $b are separate objects
+ set b 0xaaaa
+ append b aaaa
+ set result [expr {$a == $b}]
+ format %08lx $b
+ lappend result [expr {$a == $b}]
+ set b 0xaaaa
+ append b aaaa
+ lappend result [expr {$a == $b}]
+ format %08x $b
+ lappend result [expr {$a == $b}]
+} {1 1 1 1}
+test format-18.2 {do not demote existing numeric values} {wideBiggerThanInt} {
+ set a [expr {0xaaaaaaaaaa + 1}]
+ set b 0xaaaaaaaaab
+ list [format %08x $a] [expr {$a == $b}]
+} {aaaaaaab 1}
+
+test format-19.1 {
+ regression test - tcl-core message by Brian Griffin on
+ 26 0ctober 2004
+} -body {
+ set x 0x8fedc654
+ list [expr { ~ $x }] [format %08x [expr { ~$x }]]
+} -match regexp -result {-2414724693 f*701239ab}
+test format-19.2 {Bug 1867855} {
+ format %llx 0
+} 0
+test format-19.3 {Bug 2830354} {
+ string length [format %340f 0]
+} 340
+
+# Note that this test may fail in future versions
+test format-20.1 {Bug 2932421: plain %s caused intrep change of args} -body {
+ set x [dict create a b c d]
+ format %s $x
+ # After this, obj in $x should be a dict with a non-NULL bytes field
+ tcl::unsupported::representation $x
+} -match glob -result {value is a dict with *, string representation "*".}
+
+# cleanup
+catch {unset a}
+catch {unset b}
+catch {unset c}
+catch {unset d}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/get.test b/pkgs/msgcat/tests/get.test
new file mode 100644
index 0000000..40ec98f
--- /dev/null
+++ b/pkgs/msgcat/tests/get.test
@@ -0,0 +1,98 @@
+# Commands covered: none
+#
+# This file contains a collection of tests for the procedures in the
+# file tclGet.c. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1995-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testgetint [llength [info commands testgetint]]
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}]
+
+test get-1.1 {Tcl_GetInt procedure} testgetint {
+ testgetint 44 { 22}
+} {66}
+test get-1.2 {Tcl_GetInt procedure} testgetint {
+ testgetint 44 -3
+} {41}
+test get-1.3 {Tcl_GetInt procedure} testgetint {
+ testgetint 44 +8
+} {52}
+test get-1.4 {Tcl_GetInt procedure} testgetint {
+ list [catch {testgetint 44 foo} msg] $msg
+} {1 {expected integer but got "foo"}}
+test get-1.5 {Tcl_GetInt procedure} testgetint {
+ list [catch {testgetint 44 {16 }} msg] $msg
+} {0 60}
+test get-1.6 {Tcl_GetInt procedure} testgetint {
+ list [catch {testgetint 44 {16 x}} msg] $msg
+} {1 {expected integer but got "16 x"}}
+test get-1.7 {Tcl_GetInt procedure} {testgetint longIs64bit} {
+ list [catch {testgetint 44 18446744073709551616} msg] $msg $errorCode
+} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
+test get-1.8 {Tcl_GetInt procedure} {testgetint longIs64bit} {
+ list [catch {testgetint 18446744073709551614} msg] $msg
+} {0 -2}
+test get-1.9 {Tcl_GetInt procedure} {testgetint longIs64bit} {
+ list [catch {testgetint +18446744073709551614} msg] $msg
+} {0 -2}
+test get-1.10 {Tcl_GetInt procedure} {testgetint longIs64bit} {
+ list [catch {testgetint -18446744073709551614} msg] $msg
+} {0 2}
+test get-1.11 {Tcl_GetInt procedure} {testgetint longIs32bit} {
+ list [catch {testgetint 44 4294967296} msg] $msg $errorCode
+} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
+test get-1.12 {Tcl_GetInt procedure} {testgetint longIs32bit} {
+ list [catch {testgetint 4294967294} msg] $msg
+} {0 -2}
+test get-1.13 {Tcl_GetInt procedure} {testgetint longIs32bit} {
+ list [catch {testgetint +4294967294} msg] $msg
+} {0 -2}
+test get-1.14 {Tcl_GetInt procedure} {testgetint longIs32bit} {
+ list [catch {testgetint -4294967294} msg] $msg
+} {0 2}
+
+test get-2.1 {Tcl_GetInt procedure} {
+ format %g 1.23
+} {1.23}
+test get-2.2 {Tcl_GetInt procedure} {
+ format %g { 1.23 }
+} {1.23}
+test get-2.3 {Tcl_GetInt procedure} {
+ list [catch {format %g clip} msg] $msg
+} {1 {expected floating-point number but got "clip"}}
+test get-2.4 {Tcl_GetInt procedure} {
+ format %g .000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
+} 0
+
+test get-3.1 {Tcl_GetInt(FromObj), bad numbers} {
+ # SF bug #634856
+ set result ""
+ set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1" "+12345678987654321" "++12345678987654321"]
+ foreach num $numbers {
+ lappend result [catch {format %ld $num} msg] $msg
+ }
+ set result
+} {0 1 0 1 1 {expected integer but got "++1"} 1 {expected integer but got "+-1"} 1 {expected integer but got "-+1"} 0 -1 1 {expected integer but got "--1"} 1 {expected integer but got "- +1"} 0 12345678987654321 1 {expected integer but got "++12345678987654321"}}
+test get-3.2 {Tcl_GetDouble(FromObj), bad numbers} {
+ set result ""
+ set numbers [list 1.0 +1.0 ++1.0 +-1.0 -+1.0 -1.0 --1.0 "- +1.0"]
+ foreach num $numbers {
+ lappend result [catch {format %g $num} msg] $msg
+ }
+ set result
+} {0 1 0 1 1 {expected floating-point number but got "++1.0"} 1 {expected floating-point number but got "+-1.0"} 1 {expected floating-point number but got "-+1.0"} 0 -1 1 {expected floating-point number but got "--1.0"} 1 {expected floating-point number but got "- +1.0"}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/history.test b/pkgs/msgcat/tests/history.test
new file mode 100644
index 0000000..c562796
--- /dev/null
+++ b/pkgs/msgcat/tests/history.test
@@ -0,0 +1,250 @@
+# Commands covered: history
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# The history command might be autoloaded...
+if {[catch {history}]} {
+ testConstraint history 0
+} else {
+ testConstraint history 1
+}
+
+if {[testConstraint history]} {
+ set num [history nextid]
+ history keep 3
+ history add {set a 12345}
+ history add {set b [format {A test %s} string]}
+ history add {Another test}
+} else {
+ # Dummy value, must be numeric
+ set num 0
+}
+
+# "history event"
+
+test history-1.1 {event option} history {history event -1} \
+ {set b [format {A test %s} string]}
+test history-1.2 {event option} history {history event $num} \
+ {set a 12345}
+test history-1.3 {event option} history {history event [expr $num+2]} \
+ {Another test}
+test history-1.4 {event option} history {history event set} \
+ {set b [format {A test %s} string]}
+test history-1.5 {event option} history {history e "* a*"} \
+ {set a 12345}
+test history-1.6 {event option} history {catch {history event *gorp} msg} 1
+test history-1.7 {event option} history {
+ catch {history event *gorp} msg
+ set msg
+} {no event matches "*gorp"}
+test history-1.8 {event option} history {history event} \
+ {set b [format {A test %s} string]}
+test history-1.9 {event option} history {catch {history event 123 456} msg} 1
+test history-1.10 {event option} history {
+ catch {history event 123 456} msg
+ set msg
+} {wrong # args: should be "history event ?event?"}
+
+# "history redo"
+
+if {[testConstraint history]} {
+ set a 0
+ history redo -2
+}
+test history-2.1 {redo option} history {set a} 12345
+if {[testConstraint history]} {
+ set b 0
+ history redo
+}
+test history-2.2 {redo option} history {set b} {A test string}
+test history-2.3 {redo option} history {catch {history redo -3 -4}} 1
+test history-2.4 {redo option} history {
+ catch {history redo -3 -4} msg
+ set msg
+} {wrong # args: should be "history redo ?event?"}
+
+# "history add"
+
+if {[testConstraint history]} {
+ history add "set a 444" exec
+}
+test history-3.1 {add option} history {set a} 444
+test history-3.2 {add option} history {catch {history add "set a 444" execGorp}} 1
+test history-3.3 {add option} history {
+ catch {history add "set a 444" execGorp} msg
+ set msg
+} {bad argument "execGorp": should be "exec"}
+test history-3.4 {add option} history {catch {history add "set a 444" a} msg} 1
+test history-3.5 {add option} history {
+ catch {history add "set a 444" a} msg
+ set msg
+} {bad argument "a": should be "exec"}
+if {[testConstraint history]} {
+ history add "set a 555" e
+}
+test history-3.6 {add option} history {set a} 555
+if {[testConstraint history]} {
+ history add "set a 666"
+}
+test history-3.7 {add option} history {set a} 555
+test history-3.8 {add option} history {catch {history add "set a 666" e f} msg} 1
+test history-3.9 {add option} history {
+ catch {history add "set a 666" e f} msg
+ set msg
+} {wrong # args: should be "history add event ?exec?"}
+
+# "history change"
+
+if {[testConstraint history]} {
+ history change "A test value"
+}
+test history-4.1 {change option} history {history event [expr {[history n]-1}]} \
+ "A test value"
+if {[testConstraint history]} {
+ history ch "Another test" -1
+}
+test history-4.2 {change option} history {history e} "Another test"
+test history-4.3 {change option} history {history event [expr {[history n]-1}]} \
+ "A test value"
+test history-4.4 {change option} history {catch {history change Foo 4 10}} 1
+test history-4.5 {change option} history {
+ catch {history change Foo 4 10} msg
+ set msg
+} {wrong # args: should be "history change newValue ?event?"}
+test history-4.6 {change option} history {
+ catch {history change Foo [expr {[history n]-4}]}
+} 1
+if {[testConstraint history]} {
+ set num [expr {[history n]-4}]
+}
+test history-4.7 {change option} history {
+ catch {history change Foo $num} msg
+ set msg
+} "event \"$num\" is too far in the past"
+
+# "history info"
+
+if {[testConstraint history]} {
+ set num [history n]
+ history add set\ a\ {b\nc\ d\ e}
+ history add {set b 1234}
+ history add set\ c\ {a\nb\nc}
+}
+test history-5.1 {info option} history {history info} [format {%6d set a {b
+ c d e}
+%6d set b 1234
+%6d set c {a
+ b
+ c}} $num [expr $num+1] [expr $num+2]]
+test history-5.2 {info option} history {history i 2} [format {%6d set b 1234
+%6d set c {a
+ b
+ c}} [expr $num+1] [expr $num+2]]
+test history-5.3 {info option} history {catch {history i 2 3}} 1
+test history-5.4 {info option} history {
+ catch {history i 2 3} msg
+ set msg
+} {wrong # args: should be "history info ?count?"}
+test history-5.5 {info option} history {history} [format {%6d set a {b
+ c d e}
+%6d set b 1234
+%6d set c {a
+ b
+ c}} $num [expr $num+1] [expr $num+2]]
+
+# "history keep"
+
+if {[testConstraint history]} {
+ history add "foo1"
+ history add "foo2"
+ history add "foo3"
+ history keep 2
+}
+test history-6.1 {keep option} history {history event [expr [history n]-1]} foo3
+test history-6.2 {keep option} history {history event -1} foo2
+test history-6.3 {keep option} history {catch {history event -3}} 1
+test history-6.4 {keep option} history {
+ catch {history event -3} msg
+ set msg
+} {event "-3" is too far in the past}
+if {[testConstraint history]} {
+ history k 5
+}
+test history-6.5 {keep option} history {history event -1} foo2
+test history-6.6 {keep option} history {history event -2} {}
+test history-6.7 {keep option} history {history event -3} {}
+test history-6.8 {keep option} history {history event -4} {}
+test history-6.9 {keep option} history {catch {history event -5}} 1
+test history-6.10 {keep option} history {catch {history keep 4 6}} 1
+test history-6.11 {keep option} history {
+ catch {history keep 4 6} msg
+ set msg
+} {wrong # args: should be "history keep ?count?"}
+test history-6.12 {keep option} history {catch {history keep}} 0
+test history-6.13 {keep option} history {
+ history keep
+} {5}
+test history-6.14 {keep option} history {catch {history keep -3}} 1
+test history-6.15 {keep option} history {
+ catch {history keep -3} msg
+ set msg
+} {illegal keep count "-3"}
+test history-6.16 {keep option} history {
+ catch {history keep butter} msg
+ set msg
+} {illegal keep count "butter"}
+
+# "history nextid"
+
+if {[testConstraint history]} {
+ set num [history n]
+ history add "Testing"
+ history add "Testing2"
+}
+test history-7.1 {nextid option} history {history event} "Testing"
+test history-7.2 {nextid option} history {history next} [expr $num+2]
+test history-7.3 {nextid option} history {catch {history nextid garbage}} 1
+test history-7.4 {nextid option} history {
+ catch {history nextid garbage} msg
+ set msg
+} {wrong # args: should be "history nextid"}
+
+# "history clear"
+
+if {[testConstraint history]} {
+ set num [history n]
+ history add "Testing"
+ history add "Testing2"
+}
+test history-8.1 {clear option} history {catch {history clear junk}} 1
+test history-8.2 {clear option} history {history clear} {}
+if {[testConstraint history]} {
+ history add "Testing"
+}
+test history-8.3 {clear option} history {history} { 1 Testing}
+
+# miscellaneous
+
+test history-9.1 {miscellaneous} history {catch {history gorp} msg} 1
+test history-9.2 {miscellaneous} history {
+ catch {history gorp} msg
+ set msg
+} {unknown or ambiguous subcommand "gorp": must be add, change, clear, event, info, keep, nextid, or redo}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/http.test b/pkgs/msgcat/tests/http.test
new file mode 100644
index 0000000..37d4a05
--- /dev/null
+++ b/pkgs/msgcat/tests/http.test
@@ -0,0 +1,632 @@
+# Commands covered: http::config, http::geturl, http::wait, http::reset
+#
+# This file contains a collection of tests for the http script library.
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 by Ajuba Solutions.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+if {[catch {package require http 2} version]} {
+ if {[info exists http2]} {
+ catch {puts "Cannot load http 2.* package"}
+ return
+ } else {
+ catch {puts "Running http 2.* tests in slave interp"}
+ set interp [interp create http2]
+ $interp eval [list set http2 "running"]
+ $interp eval [list set argv $argv]
+ $interp eval [list source [info script]]
+ interp delete $interp
+ return
+ }
+}
+
+proc bgerror {args} {
+ global errorInfo
+ puts stderr "http.test bgerror"
+ puts stderr [join $args]
+ puts stderr $errorInfo
+}
+
+set port 8010
+set bindata "This is binary data\x0d\x0amore\x0dmore\x0amore\x00null"
+catch {unset data}
+
+# Ensure httpd file exists
+
+set origFile [file join [pwd] [file dirname [info script]] httpd]
+set httpdFile [file join [temporaryDirectory] httpd_[pid]]
+if {![file exists $httpdFile]} {
+ makeFile "" $httpdFile
+ file delete $httpdFile
+ file copy $origFile $httpdFile
+ set removeHttpd 1
+}
+
+catch {package require Thread 2.6}
+if {[catch {package present Thread}] == 0 && [file exists $httpdFile]} {
+ set httpthread [thread::create -preserved]
+ thread::send $httpthread [list source $httpdFile]
+ thread::send $httpthread [list set port $port]
+ thread::send $httpthread [list set bindata $bindata]
+ thread::send $httpthread {httpd_init $port}
+ puts "Running httpd in thread $httpthread"
+} else {
+ if {![file exists $httpdFile]} {
+ puts "Cannot read $httpdFile script, http test skipped"
+ unset port
+ return
+ }
+ source $httpdFile
+ # Let the OS pick the port; that's much more flexible
+ if {[catch {httpd_init 0} listen]} {
+ puts "Cannot start http server, http test skipped"
+ unset port
+ return
+ } else {
+ set port [lindex [fconfigure $listen -sockname] 2]
+ }
+}
+
+test http-1.1 {http::config} {
+ http::config -useragent UserAgent
+ http::config
+} [list -accept */* -proxyfilter http::ProxyRequired -proxyhost {} -proxyport {} -urlencoding utf-8 -useragent "UserAgent"]
+test http-1.2 {http::config} {
+ http::config -proxyfilter
+} http::ProxyRequired
+test http-1.3 {http::config} {
+ catch {http::config -junk}
+} 1
+test http-1.4 {http::config} {
+ set savedconf [http::config]
+ http::config -proxyhost nowhere.come -proxyport 8080 \
+ -proxyfilter myFilter -useragent "Tcl Test Suite" \
+ -urlencoding iso8859-1
+ set x [http::config]
+ http::config {*}$savedconf
+ set x
+} {-accept */* -proxyfilter myFilter -proxyhost nowhere.come -proxyport 8080 -urlencoding iso8859-1 -useragent {Tcl Test Suite}}
+test http-1.5 {http::config} -returnCodes error -body {
+ http::config -proxyhost {} -junk 8080
+} -result {Unknown option -junk, must be: -accept, -proxyfilter, -proxyhost, -proxyport, -urlencoding, -useragent}
+test http-1.6 {http::config} -setup {
+ set oldenc [http::config -urlencoding]
+} -body {
+ set enc [list [http::config -urlencoding]]
+ http::config -urlencoding iso8859-1
+ lappend enc [http::config -urlencoding]
+} -cleanup {
+ http::config -urlencoding $oldenc
+} -result {utf-8 iso8859-1}
+
+test http-2.1 {http::reset} {
+ catch {http::reset http#1}
+} 0
+
+test http-3.1 {http::geturl} -returnCodes error -body {
+ http::geturl -bogus flag
+} -result {Unknown option flag, can be: -binary, -blocksize, -channel, -command, -handler, -headers, -keepalive, -method, -myaddr, -progress, -protocol, -query, -queryblocksize, -querychannel, -queryprogress, -strict, -timeout, -type, -validate}
+test http-3.2 {http::geturl} -returnCodes error -body {
+ http::geturl http:junk
+} -result {Unsupported URL: http:junk}
+set url //[info hostname]:$port
+set badurl //[info hostname]:6666
+test http-3.3 {http::geturl} -body {
+ set token [http::geturl $url]
+ http::data $token
+} -cleanup {
+ http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET /</h2>
+</body></html>"
+set tail /a/b/c
+set url //[info hostname]:$port/a/b/c
+set fullurl http://user:pass@[info hostname]:$port/a/b/c
+set binurl //[info hostname]:$port/binary
+set posturl //[info hostname]:$port/post
+set badposturl //[info hostname]:$port/droppost
+test http-3.4 {http::geturl} -body {
+ set token [http::geturl $url]
+ http::data $token
+} -cleanup {
+ http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+proc selfproxy {host} {
+ global port
+ return [list [info hostname] $port]
+}
+test http-3.5 {http::geturl} -body {
+ http::config -proxyfilter selfproxy
+ set token [http::geturl $url]
+ http::data $token
+} -cleanup {
+ http::config -proxyfilter http::ProxyRequired
+ http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET http:$url</h2>
+</body></html>"
+test http-3.6 {http::geturl} -body {
+ http::config -proxyfilter bogus
+ set token [http::geturl $url]
+ http::data $token
+} -cleanup {
+ http::config -proxyfilter http::ProxyRequired
+ http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+test http-3.7 {http::geturl} -body {
+ set token [http::geturl $url -headers {Pragma no-cache}]
+ http::data $token
+} -cleanup {
+ http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+test http-3.8 {http::geturl} -body {
+ set token [http::geturl $url -query Name=Value&Foo=Bar -timeout 2000]
+ http::data $token
+} -cleanup {
+ http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>POST $tail</h2>
+<h2>Query</h2>
+<dl>
+<dt>Name<dd>Value
+<dt>Foo<dd>Bar
+</dl>
+</body></html>"
+test http-3.9 {http::geturl} -body {
+ set token [http::geturl $url -validate 1]
+ http::code $token
+} -cleanup {
+ http::cleanup $token
+} -result "HTTP/1.0 200 OK"
+test http-3.10 {http::geturl queryprogress} -setup {
+ set query foo=bar
+ set sep ""
+ set i 0
+ # Create about 120K of query data
+ while {$i < 14} {
+ incr i
+ append query $sep$query
+ set sep &
+ }
+} -body {
+ proc postProgress {token x y} {
+ global postProgress
+ lappend postProgress $y
+ }
+ set postProgress {}
+ set t [http::geturl $posturl -keepalive 0 -query $query \
+ -queryprogress postProgress -queryblocksize 16384]
+ http::wait $t
+ list [http::status $t] [string length $query] $postProgress [http::data $t]
+} -cleanup {
+ http::cleanup $t
+} -result {ok 122879 {16384 32768 49152 65536 81920 98304 114688 122879} {Got 122879 bytes}}
+test http-3.11 {http::geturl querychannel with -command} -setup {
+ set query foo=bar
+ set sep ""
+ set i 0
+ # Create about 120K of query data
+ while {$i < 14} {
+ incr i
+ append query $sep$query
+ set sep &
+ }
+ set file [makeFile $query outdata]
+} -body {
+ set fp [open $file]
+ proc asyncCB {token} {
+ global postResult
+ lappend postResult [http::data $token]
+ }
+ set postResult [list ]
+ set t [http::geturl $posturl -querychannel $fp]
+ http::wait $t
+ set testRes [list [http::status $t] [string length $query] [http::data $t]]
+ # Now do async
+ http::cleanup $t
+ close $fp
+ set fp [open $file]
+ set t [http::geturl $posturl -querychannel $fp -command asyncCB]
+ set postResult [list PostStart]
+ http::wait $t
+ close $fp
+ lappend testRes [http::status $t] $postResult
+} -cleanup {
+ removeFile outdata
+ http::cleanup $t
+} -result {ok 122879 {Got 122880 bytes} ok {PostStart {Got 122880 bytes}}}
+# On Linux platforms when the client and server are on the same host, the
+# client is unable to read the server's response one it hits the write error.
+# The status is "eof".
+# On Windows, the http::wait procedure gets a "connection reset by peer" error
+# while reading the reply.
+test http-3.12 {http::geturl querychannel with aborted request} -setup {
+ set query foo=bar
+ set sep ""
+ set i 0
+ # Create about 120K of query data
+ while {$i < 14} {
+ incr i
+ append query $sep$query
+ set sep &
+ }
+ set file [makeFile $query outdata]
+} -constraints {nonPortable} -body {
+ set fp [open $file]
+ proc asyncCB {token} {
+ global postResult
+ lappend postResult [http::data $token]
+ }
+ proc postProgress {token x y} {
+ global postProgress
+ lappend postProgress $y
+ }
+ set postProgress {}
+ # Now do async
+ set postResult [list PostStart]
+ if {[catch {
+ set t [http::geturl $badposturl -querychannel $fp -command asyncCB \
+ -queryprogress postProgress]
+ http::wait $t
+ upvar #0 $t state
+ } err]} {
+ puts $::errorInfo
+ error $err
+ }
+ list [http::status $t] [http::code $t]
+} -cleanup {
+ removeFile outdata
+ http::cleanup $t
+} -result {ok {HTTP/1.0 200 Data follows}}
+test http-3.13 {http::geturl socket leak test} {
+ set chanCount [llength [file channels]]
+ for {set i 0} {$i < 3} {incr i} {
+ catch {http::geturl $badurl -timeout 5000}
+ }
+
+ # No extra channels should be taken
+ expr {[llength [file channels]] == $chanCount}
+} 1
+test http-3.14 "http::geturl $fullurl" -body {
+ set token [http::geturl $fullurl -validate 1]
+ http::code $token
+} -cleanup {
+ http::cleanup $token
+} -result "HTTP/1.0 200 OK"
+test http-3.15 {http::geturl parse failures} -body {
+ http::geturl "{invalid}:url"
+} -returnCodes error -result {Unsupported URL: {invalid}:url}
+test http-3.16 {http::geturl parse failures} -body {
+ http::geturl http:relative/url
+} -returnCodes error -result {Unsupported URL: http:relative/url}
+test http-3.17 {http::geturl parse failures} -body {
+ http::geturl /absolute/url
+} -returnCodes error -result {Missing host part: /absolute/url}
+test http-3.18 {http::geturl parse failures} -body {
+ http::geturl http://somewhere:123456789/
+} -returnCodes error -result {Invalid port number: 123456789}
+test http-3.19 {http::geturl parse failures} -body {
+ http::geturl http://{user}@somewhere
+} -returnCodes error -result {Illegal characters in URL user}
+test http-3.20 {http::geturl parse failures} -body {
+ http::geturl http://%user@somewhere
+} -returnCodes error -result {Illegal encoding character usage "%us" in URL user}
+test http-3.21 {http::geturl parse failures} -body {
+ http::geturl http://somewhere/{path}
+} -returnCodes error -result {Illegal characters in URL path}
+test http-3.22 {http::geturl parse failures} -body {
+ http::geturl http://somewhere/%path
+} -returnCodes error -result {Illegal encoding character usage "%pa" in URL path}
+test http-3.23 {http::geturl parse failures} -body {
+ http::geturl http://somewhere/path?{query}?
+} -returnCodes error -result {Illegal characters in URL path}
+test http-3.24 {http::geturl parse failures} -body {
+ http::geturl http://somewhere/path?%query
+} -returnCodes error -result {Illegal encoding character usage "%qu" in URL path}
+test http-3.25 {http::meta} -setup {
+ unset -nocomplain m token
+} -body {
+ set token [http::geturl $url -timeout 2000]
+ array set m [http::meta $token]
+ lsort [array names m]
+} -cleanup {
+ http::cleanup $token
+ unset -nocomplain m token
+} -result {Content-Length Content-Type Date}
+test http-3.26 {http::meta} -setup {
+ unset -nocomplain m token
+} -body {
+ set token [http::geturl $url -headers {X-Check 1} -timeout 2000]
+ array set m [http::meta $token]
+ lsort [array names m]
+} -cleanup {
+ http::cleanup $token
+ unset -nocomplain m token
+} -result {Content-Length Content-Type Date X-Check}
+test http-3.27 {http::geturl: -headers override -type} -body {
+ set token [http::geturl $url/headers -type "text/plain" -query dummy \
+ -headers [list "Content-Type" "text/plain;charset=utf-8"]]
+ http::data $token
+} -cleanup {
+ http::cleanup $token
+} -match regexp -result {(?n)Accept \*/\*
+Host .*
+User-Agent .*
+Connection close
+Content-Type {text/plain;charset=utf-8}
+Accept-Encoding .*
+Content-Length 5}
+test http-3.28 {http::geturl: -headers override -type default} -body {
+ set token [http::geturl $url/headers -query dummy \
+ -headers [list "Content-Type" "text/plain;charset=utf-8"]]
+ http::data $token
+} -cleanup {
+ http::cleanup $token
+} -match regexp -result {(?n)Accept \*/\*
+Host .*
+User-Agent .*
+Connection close
+Content-Type {text/plain;charset=utf-8}
+Accept-Encoding .*
+Content-Length 5}
+
+test http-4.1 {http::Event} -body {
+ set token [http::geturl $url -keepalive 0]
+ upvar #0 $token data
+ array set meta $data(meta)
+ expr {($data(totalsize) == $meta(Content-Length))}
+} -cleanup {
+ http::cleanup $token
+} -result 1
+test http-4.2 {http::Event} -body {
+ set token [http::geturl $url]
+ upvar #0 $token data
+ array set meta $data(meta)
+ string compare $data(type) [string trim $meta(Content-Type)]
+} -cleanup {
+ http::cleanup $token
+} -result 0
+test http-4.3 {http::Event} -body {
+ set token [http::geturl $url]
+ http::code $token
+} -cleanup {
+ http::cleanup $token
+} -result {HTTP/1.0 200 Data follows}
+test http-4.4 {http::Event} -setup {
+ set testfile [makeFile "" testfile]
+} -body {
+ set out [open $testfile w]
+ set token [http::geturl $url -channel $out]
+ close $out
+ set in [open $testfile]
+ set x [read $in]
+} -cleanup {
+ catch {close $in}
+ catch {close $out}
+ removeFile $testfile
+ http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+test http-4.5 {http::Event} -setup {
+ set testfile [makeFile "" testfile]
+} -body {
+ set out [open $testfile w]
+ fconfigure $out -translation lf
+ set token [http::geturl $url -channel $out]
+ close $out
+ upvar #0 $token data
+ expr {$data(currentsize) == $data(totalsize)}
+} -cleanup {
+ removeFile $testfile
+ http::cleanup $token
+} -result 1
+test http-4.6 {http::Event} -setup {
+ set testfile [makeFile "" testfile]
+} -body {
+ set out [open $testfile w]
+ set token [http::geturl $binurl -channel $out]
+ close $out
+ set in [open $testfile]
+ fconfigure $in -translation binary
+ read $in
+} -cleanup {
+ catch {close $in}
+ catch {close $out}
+ removeFile $testfile
+ http::cleanup $token
+} -result "$bindata[string trimleft $binurl /]"
+proc myProgress {token total current} {
+ global progress httpLog
+ if {[info exists httpLog] && $httpLog} {
+ puts "progress $total $current"
+ }
+ set progress [list $total $current]
+}
+if 0 {
+ # This test hangs on Windows95 because the client never gets EOF
+ set httpLog 1
+ test http-4.6.1 {http::Event} knownBug {
+ set token [http::geturl $url -blocksize 50 -progress myProgress]
+ return $progress
+ } {111 111}
+}
+test http-4.7 {http::Event} -body {
+ set token [http::geturl $url -keepalive 0 -progress myProgress]
+ return $progress
+} -cleanup {
+ http::cleanup $token
+} -result {111 111}
+test http-4.8 {http::Event} -body {
+ set token [http::geturl $url]
+ http::status $token
+} -cleanup {
+ http::cleanup $token
+} -result {ok}
+test http-4.9 {http::Event} -body {
+ set token [http::geturl $url -progress myProgress]
+ http::code $token
+} -cleanup {
+ http::cleanup $token
+} -result {HTTP/1.0 200 Data follows}
+test http-4.10 {http::Event} -body {
+ set token [http::geturl $url -progress myProgress]
+ http::size $token
+} -cleanup {
+ http::cleanup $token
+} -result {111}
+# Timeout cases
+# Short timeout to working server (the test server). This lets us try a
+# reset during the connection.
+test http-4.11 {http::Event} -body {
+ set token [http::geturl $url -timeout 1 -keepalive 0 -command \#]
+ http::reset $token
+ http::status $token
+} -cleanup {
+ http::cleanup $token
+} -result {reset}
+# Longer timeout with reset.
+test http-4.12 {http::Event} -body {
+ set token [http::geturl $url/?timeout=10 -keepalive 0 -command \#]
+ http::reset $token
+ http::status $token
+} -cleanup {
+ http::cleanup $token
+} -result {reset}
+# Medium timeout to working server that waits even longer. The timeout
+# hits while waiting for a reply.
+test http-4.13 {http::Event} -body {
+ set token [http::geturl $url?timeout=30 -keepalive 0 -timeout 10 -command \#]
+ http::wait $token
+ http::status $token
+} -cleanup {
+ http::cleanup $token
+} -result {timeout}
+# Longer timeout to good host, bad port, gets an error after the
+# connection "completes" but the socket is bad.
+test http-4.14 {http::Event} -body {
+ set token [http::geturl $badurl/?timeout=10 -timeout 10000 -command \#]
+ if {$token eq ""} {
+ error "bogus return from http::geturl"
+ }
+ http::wait $token
+ http::status $token
+ # error code varies among platforms.
+} -returnCodes 1 -match regexp -cleanup {
+ catch {http::cleanup $token}
+} -result {(connect failed|couldn't open socket)}
+# Bogus host
+test http-4.15 {http::Event} -body {
+ # This test may fail if you use a proxy server. That is to be
+ # expected and is not a problem with Tcl.
+ set token [http::geturl //not_a_host.tcl.tk -timeout 1000 -command \#]
+ http::wait $token
+ http::status $token
+ # error codes vary among platforms.
+} -cleanup {
+ catch {http::cleanup $token}
+} -returnCodes 1 -match glob -result "couldn't open socket*"
+
+test http-5.1 {http::formatQuery} {
+ http::formatQuery name1 value1 name2 "value two"
+} {name1=value1&name2=value%20two}
+# test http-5.2 obsoleted by 5.4 and 5.5 with http 2.5
+test http-5.3 {http::formatQuery} {
+ http::formatQuery lines "line1\nline2\nline3"
+} {lines=line1%0D%0Aline2%0D%0Aline3}
+test http-5.4 {http::formatQuery} {
+ http::formatQuery name1 ~bwelch name2 \xa1\xa2\xa2
+} {name1=~bwelch&name2=%C2%A1%C2%A2%C2%A2}
+test http-5.5 {http::formatQuery} {
+ set enc [http::config -urlencoding]
+ http::config -urlencoding iso8859-1
+ set res [http::formatQuery name1 ~bwelch name2 \xa1\xa2\xa2]
+ http::config -urlencoding $enc
+ set res
+} {name1=~bwelch&name2=%A1%A2%A2}
+
+test http-6.1 {http::ProxyRequired} -body {
+ http::config -proxyhost [info hostname] -proxyport $port
+ set token [http::geturl $url]
+ http::wait $token
+ upvar #0 $token data
+ set data(body)
+} -cleanup {
+ http::config -proxyhost {} -proxyport {}
+ http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET http:$url</h2>
+</body></html>"
+
+test http-7.1 {http::mapReply} {
+ http::mapReply "abc\$\[\]\"\\()\}\{"
+} {abc%24%5B%5D%22%5C%28%29%7D%7B}
+test http-7.2 {http::mapReply} {
+ # RFC 2718 specifies that we pass urlencoding on utf-8 chars by default,
+ # so make sure this gets converted to utf-8 then urlencoded.
+ http::mapReply "\u2208"
+} {%E2%88%88}
+test http-7.3 {http::formatQuery} -setup {
+ set enc [http::config -urlencoding]
+} -returnCodes error -body {
+ # this would be reverting to http <=2.4 behavior
+ http::config -urlencoding ""
+ http::mapReply "\u2208"
+} -cleanup {
+ http::config -urlencoding $enc
+} -result "can't read \"formMap(\u2208)\": no such element in array"
+test http-7.4 {http::formatQuery} -setup {
+ set enc [http::config -urlencoding]
+} -body {
+ # this would be reverting to http <=2.4 behavior w/o errors
+ # (unknown chars become '?')
+ http::config -urlencoding "iso8859-1"
+ http::mapReply "\u2208"
+} -cleanup {
+ http::config -urlencoding $enc
+} -result {%3F}
+
+# cleanup
+catch {unset url}
+catch {unset badurl}
+catch {unset port}
+catch {unset data}
+if {[info exists httpthread]} {
+ thread::release $httpthread
+} else {
+ close $listen
+}
+
+if {[info exists removeHttpd]} {
+ removeFile $httpdFile
+}
+
+rename bgerror {}
+::tcltest::cleanupTests
+
+# Local variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/http11.test b/pkgs/msgcat/tests/http11.test
new file mode 100644
index 0000000..230ce5a
--- /dev/null
+++ b/pkgs/msgcat/tests/http11.test
@@ -0,0 +1,656 @@
+# http11.test -- -*- tcl-*-
+#
+# Test HTTP/1.1 features.
+#
+# Copyright (C) 2009 Pat Thoyts <patthoyts@users.sourceforge.net>
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+package require http 2.8
+
+# start the server
+variable httpd_output
+proc create_httpd {} {
+ proc httpd_read {chan} {
+ variable httpd_output
+ if {[gets $chan line] != -1} {
+ #puts stderr "read '$line'"
+ set httpd_output $line
+ }
+ if {[eof $chan]} {
+ puts stderr "eof from httpd"
+ fileevent $chan readable {}
+ close $chan
+ }
+ }
+ variable httpd_output
+ set httpd_script [file join [pwd] [file dirname [info script]] httpd11.tcl]
+ set httpd [open "|[list [interpreter] -encoding utf-8 $httpd_script]" r+]
+ fconfigure $httpd -buffering line -blocking 0
+ fileevent $httpd readable [list httpd_read $httpd]
+ vwait httpd_output
+ variable httpd_port [lindex $httpd_output 2]
+ return $httpd
+}
+
+proc halt_httpd {} {
+ variable httpd_output
+ variable httpd
+ if {[info exists httpd]} {
+ puts $httpd "quit"
+ vwait httpd_output
+ close $httpd
+ }
+ unset -nocomplain httpd_output httpd
+}
+
+proc meta {tok {key ""}} {
+ set meta [http::meta $tok]
+ if {$key ne ""} {
+ if {[dict exists $meta $key]} {
+ return [dict get $meta $key]
+ } else {
+ return ""
+ }
+ }
+ return $meta
+}
+
+proc check_crc {tok args} {
+ set crc [meta $tok x-crc32]
+ set data [expr {[llength $args] ? [lindex $args 0] : [http::data $tok]}]
+ set chk [format %x [zlib crc32 $data]]
+ if {$crc ne $chk} {
+ return "crc32 mismatch: $crc ne $chk"
+ }
+ return "ok"
+}
+
+makeFile "<html><head><title>test</title></head>\
+<body><p>this is a test</p>\n\
+[string repeat {<p>This is a tcl test file.</p>} 4192]\n\
+</body></html>" testdoc.html
+
+# -------------------------------------------------------------------------
+
+test http11-1.0 "normal request for document " -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html -timeout 10000]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] [meta $tok connection]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close}
+
+test http11-1.1 "normal,gzip,non-chunked" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 10000 -headers {accept-encoding gzip}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok gzip {}}
+
+test http11-1.2 "normal,deflated,non-chunked" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 10000 -headers {accept-encoding deflate}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok deflate {}}
+
+test http11-1.3 "normal,compressed,non-chunked" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 10000 -headers {accept-encoding compress}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok compress {}}
+
+test http11-1.4 "normal,identity,non-chunked" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 10000 -headers {accept-encoding identity}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {} {}}
+
+test http11-1.5 "normal request for document, unsupported coding" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 10000 -headers {accept-encoding unsupported}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {}}
+
+test http11-1.6 "normal, specify 1.1 " -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -protocol 1.1 -timeout 10000]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok connection] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close chunked}
+
+test http11-1.7 "normal, 1.1 and keepalive " -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -protocol 1.1 -keepalive 1 -timeout 10000]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok connection] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {} chunked}
+
+test http11-1.8 "normal, 1.1 and keepalive, server close" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -protocol 1.1 -keepalive 1 -timeout 10000]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok connection] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close {}}
+
+test http11-1.9 "normal,gzip,chunked" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 10000 -headers {accept-encoding gzip}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok gzip chunked}
+
+test http11-1.10 "normal,deflate,chunked" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 10000 -headers {accept-encoding deflate}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok deflate chunked}
+
+test http11-1.11 "normal,compress,chunked" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 10000 -headers {accept-encoding compress}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok compress chunked}
+
+test http11-1.12 "normal,identity,chunked" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 10000 -headers {accept-encoding identity}]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok] \
+ [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {} chunked}
+
+# -------------------------------------------------------------------------
+
+test http11-2.0 "-channel" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 5000 -channel $chan]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close chunked}
+
+test http11-2.1 "-channel, encoding gzip" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 5000 -channel $chan -headers {accept-encoding gzip}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close gzip chunked}
+
+test http11-2.2 "-channel, encoding deflate" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 5000 -channel $chan -headers {accept-encoding deflate}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close deflate chunked}
+
+test http11-2.3 "-channel,encoding compress" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 5000 -channel $chan \
+ -headers {accept-encoding compress}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close compress chunked}
+
+test http11-2.4 "-channel,encoding identity" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 5000 -channel $chan \
+ -headers {accept-encoding identity}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close {} chunked}
+
+test http11-2.5 "-channel,encoding unsupported" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 5000 -channel $chan \
+ -headers {accept-encoding unsupported}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close {} chunked}
+
+test http11-2.6 "-channel,encoding gzip,non-chunked" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 5000 -channel $chan -headers {accept-encoding gzip}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]\
+ [expr {[file size testdoc.html]-[file size testfile.tmp]}]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close gzip {} 0}
+
+test http11-2.7 "-channel,encoding deflate,non-chunked" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 5000 -channel $chan -headers {accept-encoding deflate}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]\
+ [expr {[file size testdoc.html]-[file size testfile.tmp]}]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close deflate {} 0}
+
+test http11-2.8 "-channel,encoding compress,non-chunked" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 5000 -channel $chan -headers {accept-encoding compress}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]\
+ [expr {[file size testdoc.html]-[file size testfile.tmp]}]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close compress {} 0}
+
+test http11-2.9 "-channel,encoding identity,non-chunked" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 5000 -channel $chan -headers {accept-encoding identity}]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]\
+ [expr {[file size testdoc.html]-[file size testfile.tmp]}]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close {} {} 0}
+
+test http11-2.10 "-channel,deflate,keepalive" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 5000 -channel $chan -keepalive 1]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]\
+ [expr {[file size testdoc.html]-[file size testfile.tmp]}]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {} deflate chunked 0}
+
+test http11-2.11 "-channel,identity,keepalive" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -headers {accept-encoding identity} \
+ -timeout 5000 -channel $chan -keepalive 1]
+ http::wait $tok
+ seek $chan 0
+ set data [read $chan]
+ list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+ [meta $tok connection] [meta $tok content-encoding]\
+ [meta $tok transfer-encoding]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {} {} chunked}
+
+# -------------------------------------------------------------------------
+#
+# The following tests for the -handler option will require changes in
+# the future. At the moment we cannot handler chunked data with this
+# option. Therefore we currently force HTTP/1.0 protocol version.
+#
+# Once this is solved, these tests should be fixed to assume chunked
+# returns in 3.2 and 3.3 and HTTP/1.1 in all but test 3.1
+
+proc handler {var sock token} {
+ upvar #0 $var data
+ set chunk [read $sock]
+ append data $chunk
+ #::http::Log "handler read [string length $chunk] ([chan configure $sock -buffersize])"
+ if {[eof $sock]} {
+ #::http::Log "handler eof $sock"
+ chan event $sock readable {}
+ }
+}
+
+test http11-3.0 "-handler,close,identity" -setup {
+ variable httpd [create_httpd]
+ set testdata ""
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 10000 -handler [namespace code [list handler testdata]]]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
+ [meta $tok connection] [meta $tok content-encoding] \
+ [meta $tok transfer-encoding] \
+ [expr {[file size testdoc.html]-[string length $testdata]}]
+} -cleanup {
+ http::cleanup $tok
+ unset -nocomplain testdata
+ halt_httpd
+} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}
+
+test http11-3.1 "-handler,protocol1.0" -setup {
+ variable httpd [create_httpd]
+ set testdata ""
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+ -timeout 10000 -protocol 1.0 \
+ -handler [namespace code [list handler testdata]]]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
+ [meta $tok connection] [meta $tok content-encoding] \
+ [meta $tok transfer-encoding] \
+ [expr {[file size testdoc.html]-[string length $testdata]}]
+} -cleanup {
+ http::cleanup $tok
+ unset -nocomplain testdata
+ halt_httpd
+} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}
+
+test http11-3.2 "-handler,close,chunked" -setup {
+ variable httpd [create_httpd]
+ set testdata ""
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 10000 -keepalive 0 -binary 1\
+ -handler [namespace code [list handler testdata]]]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
+ [meta $tok connection] [meta $tok content-encoding] \
+ [meta $tok transfer-encoding] \
+ [expr {[file size testdoc.html]-[string length $testdata]}]
+} -cleanup {
+ http::cleanup $tok
+ unset -nocomplain testdata
+ halt_httpd
+} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}
+
+test http11-3.3 "-handler,keepalive,chunked" -setup {
+ variable httpd [create_httpd]
+ set testdata ""
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -timeout 10000 -keepalive 1 -binary 1\
+ -handler [namespace code [list handler testdata]]]
+ http::wait $tok
+ list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
+ [meta $tok connection] [meta $tok content-encoding] \
+ [meta $tok transfer-encoding] \
+ [expr {[file size testdoc.html]-[string length $testdata]}]
+} -cleanup {
+ http::cleanup $tok
+ unset -nocomplain testdata
+ halt_httpd
+} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}
+
+test http11-4.0 "normal post request" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set query [http::formatQuery q 1 z 2]
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -query $query -timeout 10000]
+ http::wait $tok
+ list status [http::status $tok] code [http::code $tok]\
+ crc [check_crc $tok]\
+ connection [meta $tok connection]\
+ query-length [meta $tok x-query-length]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 7}
+
+test http11-4.1 "normal post request, check query length" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set query [http::formatQuery q 1 z 2]
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+ -headers [list x-check-query yes] \
+ -query $query -timeout 10000]
+ http::wait $tok
+ list status [http::status $tok] code [http::code $tok]\
+ crc [check_crc $tok]\
+ connection [meta $tok connection]\
+ query-length [meta $tok x-query-length]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 7}
+
+test http11-4.2 "normal post request, check long query length" -setup {
+ variable httpd [create_httpd]
+} -body {
+ set query [string repeat a 24576]
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html\
+ -headers [list x-check-query yes]\
+ -query $query -timeout 10000]
+ http::wait $tok
+ list status [http::status $tok] code [http::code $tok]\
+ crc [check_crc $tok]\
+ connection [meta $tok connection]\
+ query-length [meta $tok x-query-length]
+} -cleanup {
+ http::cleanup $tok
+ halt_httpd
+} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 24576}
+
+test http11-4.3 "normal post request, check channel query length" -setup {
+ variable httpd [create_httpd]
+ set chan [open [makeFile {} testfile.tmp] wb+]
+ puts -nonewline $chan [string repeat [encoding convertto utf-8 "This is a test\n"] 8192]
+ flush $chan
+ seek $chan 0
+} -body {
+ set tok [http::geturl http://localhost:$httpd_port/testdoc.html\
+ -headers [list x-check-query yes]\
+ -querychannel $chan -timeout 10000]
+ http::wait $tok
+ list status [http::status $tok] code [http::code $tok]\
+ crc [check_crc $tok]\
+ connection [meta $tok connection]\
+ query-length [meta $tok x-query-length]
+} -cleanup {
+ http::cleanup $tok
+ close $chan
+ removeFile testfile.tmp
+ halt_httpd
+} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 122880}
+
+# -------------------------------------------------------------------------
+
+foreach p {create_httpd httpd_read halt_httpd meta check_crc} {
+ if {[llength [info proc $p]]} {rename $p {}}
+}
+removeFile testdoc.html
+unset -nocomplain httpd_port httpd p
+
+::tcltest::cleanupTests
diff --git a/pkgs/msgcat/tests/httpd b/pkgs/msgcat/tests/httpd
new file mode 100644
index 0000000..f810797
--- /dev/null
+++ b/pkgs/msgcat/tests/httpd
@@ -0,0 +1,236 @@
+# -*- tcl -*-
+#
+# The httpd_ procedures implement a stub http server.
+#
+# Copyright (c) 1997-1998 Sun Microsystems, Inc.
+# Copyright (c) 1999-2000 Scriptics Corporation
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+#set httpLog 1
+
+proc httpd_init {{port 8015}} {
+ socket -server httpdAccept $port
+}
+proc httpd_log {args} {
+ global httpLog
+ if {[info exists httpLog] && $httpLog} {
+ puts stderr "httpd: [join $args { }]"
+ }
+}
+array set httpdErrors {
+ 204 {No Content}
+ 400 {Bad Request}
+ 401 {Authorization Required}
+ 404 {Not Found}
+ 503 {Service Unavailable}
+ 504 {Service Temporarily Unavailable}
+}
+
+proc httpdError {sock code args} {
+ global httpdErrors
+ puts $sock "$code $httpdErrors($code)"
+ httpd_log "error: [join $args { }]"
+}
+proc httpdAccept {newsock ipaddr port} {
+ global httpd
+ upvar #0 httpd$newsock data
+
+ fconfigure $newsock -blocking 0 -translation {auto crlf}
+ httpd_log $newsock Connect $ipaddr $port
+ set data(ipaddr) $ipaddr
+ fileevent $newsock readable [list httpdRead $newsock]
+}
+
+# read data from a client request
+
+proc httpdRead { sock } {
+ upvar #0 httpd$sock data
+
+ if {[eof $sock]} {
+ set readCount -1
+ } elseif {![info exists data(state)]} {
+
+ # Read the protocol line and parse out the URL and query
+
+ set readCount [gets $sock line]
+ if {[regexp {(POST|GET|HEAD) ([^?]+)\??([^ ]*) HTTP/(1.[01])} $line \
+ -> data(proto) data(url) data(query) data(httpversion)]} {
+ set data(state) mime
+ httpd_log $sock Query $line
+ } else {
+ httpdError $sock 400
+ httpd_log $sock Error "bad first line:$line"
+ httpdSockDone $sock
+ }
+ return
+ } elseif {$data(state) == "mime"} {
+
+ # Read the HTTP headers
+
+ set readCount [gets $sock line]
+ if {[regexp {^([^:]+):(.*)$} $line -> key val]} {
+ lappend data(meta) $key [string trim $val]
+ }
+
+ } elseif {$data(state) == "query"} {
+
+ # Read the query data
+
+ if {![info exists data(length_orig)]} {
+ set data(length_orig) $data(length)
+ }
+ set line [read $sock $data(length)]
+ set readCount [string length $line]
+ incr data(length) -$readCount
+ }
+
+ # string compare $readCount 0 maps -1 to -1, 0 to 0, and > 0 to 1
+
+ set state [string compare $readCount 0],$data(state),$data(proto)
+ httpd_log $sock $state
+ switch -- $state {
+ -1,mime,HEAD -
+ -1,mime,GET -
+ -1,mime,POST {
+ # gets would block
+ return
+ }
+ 0,mime,HEAD -
+ 0,mime,GET -
+ 0,query,POST {
+ # Empty line at end of headers,
+ # or eof after query data
+ httpdRespond $sock
+ }
+ 0,mime,POST {
+ # Empty line between headers and query data
+ if {![info exists data(mime,content-length)]} {
+ httpd_log $sock Error "No Content-Length for POST"
+ httpdError $sock 400
+ httpdSockDone $sock
+ } else {
+ set data(state) query
+ set data(length) $data(mime,content-length)
+
+ # Special case to simulate servers that respond
+ # without reading the post data.
+
+ if {[string match *droppost* $data(url)]} {
+ fileevent $sock readable {}
+ httpdRespond $sock
+ }
+ }
+ }
+ 1,mime,HEAD -
+ 1,mime,POST -
+ 1,mime,GET {
+ # A line of HTTP headers
+ if {[regexp {([^:]+):[ ]*(.*)} $line dummy key value]} {
+ set data(mime,[string tolower $key]) $value
+ }
+ }
+ -1,query,POST {
+ httpd_log $sock Error "unexpected eof on <$data(url)> request"
+ httpdError $sock 400
+ httpdSockDone $sock
+ }
+ 1,query,POST {
+ append data(query) $line
+ if {$data(length) <= 0} {
+ set data(length) $data(length_orig)
+ httpdRespond $sock
+ }
+ }
+ default {
+ if {[eof $sock]} {
+ httpd_log $sock Error "unexpected eof on <$data(url)> request"
+ } else {
+ httpd_log $sock Error "unhandled state <$state> fetching <$data(url)>"
+ }
+ httpdError $sock 404
+ httpdSockDone $sock
+ }
+ }
+}
+proc httpdSockDone { sock } {
+ upvar #0 httpd$sock data
+ unset data
+ catch {close $sock}
+}
+
+# Respond to the query.
+
+proc httpdRespond { sock } {
+ global httpd bindata port
+ upvar #0 httpd$sock data
+
+ switch -glob -- $data(url) {
+ *binary* {
+ set html "$bindata[info hostname]:$port$data(url)"
+ set type application/octet-stream
+ }
+ *post* {
+ set html "Got [string length $data(query)] bytes"
+ set type text/plain
+ }
+ *headers* {
+ set html ""
+ set type text/plain
+ foreach {key value} $data(meta) {
+ append html [list $key $value] "\n"
+ }
+ set html [string trim $html]
+ }
+ default {
+ set type text/html
+
+ set html "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>$data(proto) $data(url)</h2>
+"
+ if {[info exists data(query)] && [string length $data(query)]} {
+ append html "<h2>Query</h2>\n<dl>\n"
+ foreach {key value} [split $data(query) &=] {
+ append html "<dt>$key<dd>$value\n"
+ if {$key == "timeout"} {
+ after $value ;# pause
+ }
+ }
+ append html </dl>\n
+ }
+ append html </body></html>
+ }
+ }
+
+ # Catch errors from premature client closes
+
+ catch {
+ if {$data(proto) == "HEAD"} {
+ puts $sock "HTTP/1.0 200 OK"
+ } else {
+ # Split the response to test for [Bug 26245326]
+ puts -nonewline $sock "HT"
+ flush $sock
+ puts $sock "TP/1.0 200 Data follows"
+ }
+ puts $sock "Date: [clock format [clock seconds] \
+ -format {%a, %d %b %Y %H:%M:%S %Z}]"
+ puts $sock "Content-Type: $type"
+ puts $sock "Content-Length: [string length $html]"
+ foreach {key val} $data(meta) {
+ if {[string match "X-*" $key]} {
+ puts $sock "$key: $val"
+ }
+ }
+ puts $sock ""
+ flush $sock
+ if {$data(proto) != "HEAD"} {
+ fconfigure $sock -translation binary
+ puts -nonewline $sock $html
+ }
+ }
+ httpd_log $sock Done ""
+ httpdSockDone $sock
+}
diff --git a/pkgs/msgcat/tests/httpd11.tcl b/pkgs/msgcat/tests/httpd11.tcl
new file mode 100644
index 0000000..9c543dc
--- /dev/null
+++ b/pkgs/msgcat/tests/httpd11.tcl
@@ -0,0 +1,254 @@
+# httpd11.tcl -- -*- tcl -*-
+#
+# A simple httpd for testing HTTP/1.1 client features.
+# Not suitable for use on a internet connected port.
+#
+# Copyright (C) 2009 Pat Thoyts <patthoyts@users.sourceforge.net>
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require Tcl 8.6
+
+proc ::tcl::dict::get? {dict key} {
+ if {[dict exists $dict $key]} {
+ return [dict get $dict $key]
+ }
+ return
+}
+namespace ensemble configure dict \
+ -map [linsert [namespace ensemble configure dict -map] end get? ::tcl::dict::get?]
+
+proc make-chunk-generator {data {size 4096}} {
+ variable _chunk_gen_uid
+ if {![info exists _chunk_gen_uid]} {set _chunk_gen_uid 0}
+ set lambda {{data size} {
+ set pos 0
+ yield
+ while {1} {
+ set payload [string range $data $pos [expr {$pos + $size - 1}]]
+ incr pos $size
+ set chunk [format %x [string length $payload]]\r\n$payload\r\n
+ yield $chunk
+ if {![string length $payload]} {return}
+ }
+ }}
+ set name chunker[incr _chunk_gen_uid]
+ coroutine $name ::apply $lambda $data $size
+ return $name
+}
+
+proc get-chunks {data {compression gzip}} {
+ switch -exact -- $compression {
+ gzip { set data [zlib gzip $data] }
+ deflate { set data [zlib deflate $data] }
+ compress { set data [zlib compress $data] }
+ }
+
+ set data ""
+ set chunker [make-chunk-generator $data 512]
+ while {[string length [set chunk [$chunker]]]} {
+ append data $chunk
+ }
+ return $data
+}
+
+proc blow-chunks {data {ochan stdout} {compression gzip}} {
+ switch -exact -- $compression {
+ gzip { set data [zlib gzip $data] }
+ deflate { set data [zlib deflate $data] }
+ compress { set data [zlib compress $data] }
+ }
+
+ set chunker [make-chunk-generator $data 512]
+ while {[string length [set chunk [$chunker]]]} {
+ puts -nonewline $ochan $chunk
+ }
+ return
+}
+
+proc mime-type {filename} {
+ switch -exact -- [file extension $filename] {
+ .htm - .html { return {text text/html}}
+ .png { return {binary image/png} }
+ .jpg { return {binary image/jpeg} }
+ .gif { return {binary image/gif} }
+ .css { return {text text/css} }
+ .xml { return {text text/xml} }
+ .xhtml {return {text application/xml+html} }
+ .svg { return {text image/svg+xml} }
+ .txt - .tcl - .c - .h { return {text text/plain}}
+ }
+ return {binary text/plain}
+}
+
+proc Puts {chan s} {puts $chan $s; puts $s}
+
+proc Service {chan addr port} {
+ chan event $chan readable [info coroutine]
+ while {1} {
+ set meta {}
+ chan configure $chan -buffering line -encoding iso8859-1 -translation crlf
+ chan configure $chan -blocking 0
+ yield
+ while {[gets $chan line] < 0} {
+ if {[eof $chan]} {chan event $chan readable {}; close $chan; return}
+ yield
+ }
+ if {[eof $chan]} {chan event $chan readable {}; close $chan; return}
+ foreach {req url protocol} {GET {} HTTP/1.1} break
+ regexp {^(\S+)\s+(.*)\s(\S+)?$} $line -> req url protocol
+
+ puts $line
+ while {[gets $chan line] > 0} {
+ if {[regexp {^([^:]+):(.*)$} $line -> key val]} {
+ puts [list $key [string trim $val]]
+ lappend meta [string tolower $key] [string trim $val]
+ }
+ yield
+ }
+
+ set encoding identity
+ set transfer ""
+ set close 1
+ set type text/html
+ set code "404 Not Found"
+ set data "<html><head><title>Error 404</title></head>"
+ append data "<body><h1>Not Found</h1><p>Try again.</p></body></html>"
+
+ if {[scan $url {%[^?]?%s} path query] < 2} {
+ set query ""
+ }
+
+ switch -exact -- $req {
+ GET - HEAD {
+ }
+ POST {
+ # Read the query.
+ set qlen [dict get? $meta content-length]
+ if {[string is integer -strict $qlen]} {
+ chan configure $chan -buffering none -translation binary
+ while {[string length $query] < $qlen} {
+ append query [read $chan $qlen]
+ if {[string length $query] < $qlen} {yield}
+ }
+ # Check for excess query bytes [Bug 2715421]
+ if {[dict get? $meta x-check-query] eq "yes"} {
+ chan configure $chan -blocking 0
+ append query [read $chan]
+ }
+ }
+ }
+ default {
+ # invalid request error 5??
+ }
+ }
+ if {$query ne ""} {puts $query}
+
+ set path [string trimleft $path /]
+ set path [file join [pwd] $path]
+ if {[file exists $path] && [file isfile $path]} {
+ foreach {what type} [mime-type $path] break
+ set f [open $path r]
+ if {$what eq "binary"} {chan configure $f -translation binary}
+ set data [read $f]
+ close $f
+ set code "200 OK"
+ set close [expr {[dict get? $meta connection] eq "close"}]
+ }
+
+ if {$protocol eq "HTTP/1.1"} {
+ if {[string match "*deflate*" [dict get? $meta accept-encoding]]} {
+ set encoding deflate
+ } elseif {[string match "*gzip*" [dict get? $meta accept-encoding]]} {
+ set encoding gzip
+ } elseif {[string match "*compress*" [dict get? $meta accept-encoding]]} {
+ set encoding compress
+ }
+ set transfer chunked
+ } else {
+ set close 1
+ }
+
+ foreach pair [split $query &] {
+ if {[scan $pair {%[^=]=%s} key val] != 2} {set val ""}
+ switch -exact -- $key {
+ close {set close 1 ; set transfer 0}
+ transfer {set transfer $val}
+ content-type {set type $val}
+ }
+ }
+
+ chan configure $chan -buffering line -encoding iso8859-1 -translation crlf
+ Puts $chan "$protocol $code"
+ Puts $chan "content-type: $type"
+ Puts $chan [format "x-crc32: %08x" [zlib crc32 $data]]
+ if {$req eq "POST"} {
+ Puts $chan [format "x-query-length: %d" [string length $query]]
+ }
+ if {$close} {
+ Puts $chan "connection: close"
+ }
+ if {$encoding eq "identity"} {
+ Puts $chan "content-length: [string length $data]"
+ } else {
+ Puts $chan "content-encoding: $encoding"
+ }
+ if {$transfer eq "chunked"} {
+ Puts $chan "transfer-encoding: chunked"
+ }
+ puts $chan ""
+ flush $chan
+
+ chan configure $chan -buffering full -translation binary
+ if {$transfer eq "chunked"} {
+ blow-chunks $data $chan $encoding
+ } elseif {$encoding ne "identity"} {
+ puts -nonewline $chan [zlib $encoding $data]
+ } else {
+ puts -nonewline $chan $data
+ }
+
+ if {$close} {
+ chan event $chan readable {}
+ close $chan
+ puts "close $chan"
+ return
+ } else {
+ flush $chan
+ }
+ puts "pipeline $chan"
+ }
+}
+
+proc Accept {chan addr port} {
+ coroutine client$chan Service $chan $addr $port
+ return
+}
+
+proc Control {chan} {
+ if {[gets $chan line] != -1} {
+ if {[string trim $line] eq "quit"} {
+ set ::forever 1
+ }
+ }
+ if {[eof $chan]} {
+ chan event $chan readable {}
+ }
+}
+
+proc Main {{port 0}} {
+ set server [socket -server Accept -myaddr localhost $port]
+ puts [chan configure $server -sockname]
+ flush stdout
+ chan event stdin readable [list Control stdin]
+ vwait ::forever
+ close $server
+ return "done"
+}
+
+if {!$tcl_interactive} {
+ set r [catch [linsert $argv 0 Main] err]
+ if {$r} {puts stderr $errorInfo} elseif {[string length $err]} {puts $err}
+ exit $r
+}
diff --git a/pkgs/msgcat/tests/httpold.test b/pkgs/msgcat/tests/httpold.test
new file mode 100644
index 0000000..aeba311
--- /dev/null
+++ b/pkgs/msgcat/tests/httpold.test
@@ -0,0 +1,293 @@
+# Commands covered: http_config, http_get, http_wait, http_reset
+#
+# This file contains a collection of tests for the http script library.
+# Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+if {[catch {package require http 1.0}]} {
+ if {[info exists httpold]} {
+ catch {puts "Cannot load http 1.0 package"}
+ ::tcltest::cleanupTests
+ return
+ } else {
+ catch {puts "Running http 1.0 tests in slave interp"}
+ set interp [interp create httpold]
+ $interp eval [list set httpold "running"]
+ $interp eval [list set argv $argv]
+ $interp eval [list source [info script]]
+ interp delete $interp
+ ::tcltest::cleanupTests
+ return
+ }
+}
+
+set bindata "This is binary data\x0d\x0amore\x0dmore\x0amore\x00null"
+catch {unset data}
+
+##
+## The httpd script implement a stub http server
+##
+source [file join [file dirname [info script]] httpd]
+
+set port 8010
+if [catch {httpd_init $port} listen] {
+ puts "Cannot start http server, http test skipped"
+ unset port
+ ::tcltest::cleanupTests
+ return
+}
+
+test httpold-1.1 {http_config} {
+ http_config
+} {-accept */* -proxyfilter httpProxyRequired -proxyhost {} -proxyport {} -useragent {Tcl http client package 1.0}}
+
+test httpold-1.2 {http_config} {
+ http_config -proxyfilter
+} httpProxyRequired
+
+test httpold-1.3 {http_config} {
+ catch {http_config -junk}
+} 1
+
+test httpold-1.4 {http_config} {
+ http_config -proxyhost nowhere.come -proxyport 8080 -proxyfilter myFilter -useragent "Tcl Test Suite"
+ set x [http_config]
+ http_config -proxyhost {} -proxyport {} -proxyfilter httpProxyRequired \
+ -useragent "Tcl http client package 1.0"
+ set x
+} {-accept */* -proxyfilter myFilter -proxyhost nowhere.come -proxyport 8080 -useragent {Tcl Test Suite}}
+
+test httpold-1.5 {http_config} {
+ catch {http_config -proxyhost {} -junk 8080}
+} 1
+
+test httpold-2.1 {http_reset} {
+ catch {http_reset http#1}
+} 0
+
+test httpold-3.1 {http_get} {
+ catch {http_get -bogus flag}
+} 1
+test httpold-3.2 {http_get} {
+ catch {http_get http:junk} err
+ set err
+} {Unsupported URL: http:junk}
+
+set url [info hostname]:$port
+test httpold-3.3 {http_get} {
+ set token [http_get $url]
+ http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET /</h2>
+</body></html>"
+
+set tail /a/b/c
+set url [info hostname]:$port/a/b/c
+set binurl [info hostname]:$port/binary
+
+test httpold-3.4 {http_get} {
+ set token [http_get $url]
+ http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+
+proc selfproxy {host} {
+ global port
+ return [list [info hostname] $port]
+}
+test httpold-3.5 {http_get} {
+ http_config -proxyfilter selfproxy
+ set token [http_get $url]
+ http_config -proxyfilter httpProxyRequired
+ http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET http://$url</h2>
+</body></html>"
+
+test httpold-3.6 {http_get} {
+ http_config -proxyfilter bogus
+ set token [http_get $url]
+ http_config -proxyfilter httpProxyRequired
+ http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+
+test httpold-3.7 {http_get} {
+ set token [http_get $url -headers {Pragma no-cache}]
+ http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+
+test httpold-3.8 {http_get} {
+ set token [http_get $url -query Name=Value&Foo=Bar]
+ http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>POST $tail</h2>
+<h2>Query</h2>
+<dl>
+<dt>Name<dd>Value
+<dt>Foo<dd>Bar
+</dl>
+</body></html>"
+
+test httpold-3.9 {http_get} {
+ set token [http_get $url -validate 1]
+ http_code $token
+} "HTTP/1.0 200 OK"
+
+
+test httpold-4.1 {httpEvent} {
+ set token [http_get $url]
+ upvar #0 $token data
+ array set meta $data(meta)
+ expr ($data(totalsize) == $meta(Content-Length))
+} 1
+
+test httpold-4.2 {httpEvent} {
+ set token [http_get $url]
+ upvar #0 $token data
+ array set meta $data(meta)
+ string compare $data(type) [string trim $meta(Content-Type)]
+} 0
+
+test httpold-4.3 {httpEvent} {
+ set token [http_get $url]
+ http_code $token
+} {HTTP/1.0 200 Data follows}
+
+test httpold-4.4 {httpEvent} {
+ set testfile [makeFile "" testfile]
+ set out [open $testfile w]
+ set token [http_get $url -channel $out]
+ close $out
+ set in [open $testfile]
+ set x [read $in]
+ close $in
+ removeFile $testfile
+ set x
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+
+test httpold-4.5 {httpEvent} {
+ set testfile [makeFile "" testfile]
+ set out [open $testfile w]
+ set token [http_get $url -channel $out]
+ close $out
+ upvar #0 $token data
+ removeFile $testfile
+ expr $data(currentsize) == $data(totalsize)
+} 1
+
+test httpold-4.6 {httpEvent} {
+ set testfile [makeFile "" testfile]
+ set out [open $testfile w]
+ set token [http_get $binurl -channel $out]
+ close $out
+ set in [open $testfile]
+ fconfigure $in -translation binary
+ set x [read $in]
+ close $in
+ removeFile $testfile
+ set x
+} "$bindata$binurl"
+
+proc myProgress {token total current} {
+ global progress httpLog
+ if {[info exists httpLog] && $httpLog} {
+ puts "progress $total $current"
+ }
+ set progress [list $total $current]
+}
+if 0 {
+ # This test hangs on Windows95 because the client never gets EOF
+ set httpLog 1
+ test httpold-4.6 {httpEvent} {
+ set token [http_get $url -blocksize 50 -progress myProgress]
+ set progress
+ } {111 111}
+}
+test httpold-4.7 {httpEvent} {
+ set token [http_get $url -progress myProgress]
+ set progress
+} {111 111}
+test httpold-4.8 {httpEvent} {
+ set token [http_get $url]
+ http_status $token
+} {ok}
+test httpold-4.9 {httpEvent} {
+ set token [http_get $url -progress myProgress]
+ http_code $token
+} {HTTP/1.0 200 Data follows}
+test httpold-4.10 {httpEvent} {
+ set token [http_get $url -progress myProgress]
+ http_size $token
+} {111}
+test httpold-4.11 {httpEvent} {
+ set token [http_get $url -timeout 1 -command {#}]
+ http_reset $token
+ http_status $token
+} {reset}
+test httpold-4.12 {httpEvent} {
+ update
+ set x {}
+ after 500 {lappend x ok}
+ set token [http_get $url -timeout 1 -command {lappend x fail}]
+ vwait x
+ list [http_status $token] $x
+} {timeout ok}
+
+test httpold-5.1 {http_formatQuery} {
+ http_formatQuery name1 value1 name2 "value two"
+} {name1=value1&name2=value+two}
+
+test httpold-5.2 {http_formatQuery} {
+ http_formatQuery name1 ~bwelch name2 \xa1\xa2\xa2
+} {name1=%7ebwelch&name2=%a1%a2%a2}
+
+test httpold-5.3 {http_formatQuery} {
+ http_formatQuery lines "line1\nline2\nline3"
+} {lines=line1%0d%0aline2%0d%0aline3}
+
+test httpold-6.1 {httpProxyRequired} {
+ update
+ http_config -proxyhost [info hostname] -proxyport $port
+ set token [http_get $url]
+ http_wait $token
+ http_config -proxyhost {} -proxyport {}
+ upvar #0 $token data
+ set data(body)
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET http://$url</h2>
+</body></html>"
+
+# cleanup
+catch {unset url}
+catch {unset port}
+catch {unset data}
+close $listen
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/if-old.test b/pkgs/msgcat/tests/if-old.test
new file mode 100644
index 0000000..fbcf56c
--- /dev/null
+++ b/pkgs/msgcat/tests/if-old.test
@@ -0,0 +1,162 @@
+# Commands covered: if
+#
+# This file contains the original set of tests for Tcl's if command.
+# Since the if command is now compiled, a new set of tests covering
+# the new implementation is in the file "if.test". Sourcing this file
+# into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test if-old-1.1 {taking proper branch} {
+ set a {}
+ if 0 {set a 1} else {set a 2}
+ set a
+} 2
+test if-old-1.2 {taking proper branch} {
+ set a {}
+ if 1 {set a 1} else {set a 2}
+ set a
+} 1
+test if-old-1.3 {taking proper branch} {
+ set a {}
+ if 1<2 {set a 1}
+ set a
+} 1
+test if-old-1.4 {taking proper branch} {
+ set a {}
+ if 1>2 {set a 1}
+ set a
+} {}
+test if-old-1.5 {taking proper branch} {
+ set a {}
+ if 0 {set a 1} else {}
+ set a
+} {}
+test if-old-1.6 {taking proper branch} {
+ set a {}
+ if 0 {set a 1} elseif 1 {set a 2} elseif 1 {set a 3} else {set a 4}
+ set a
+} {2}
+test if-old-1.7 {taking proper branch} {
+ set a {}
+ if 0 {set a 1} elseif 0 {set a 2} elseif 1 {set a 3} else {set a 4}
+ set a
+} {3}
+test if-old-1.8 {taking proper branch} {
+ set a {}
+ if 0 {set a 1} elseif 0 {set a 2} elseif 0 {set a 3} else {set a 4}
+ set a
+} {4}
+test if-old-1.9 {taking proper branch, multiline test expr} {
+ set a {}
+ if {($tcl_platform(platform) != "foobar1") && \
+ ($tcl_platform(platform) != "foobar2")} {set a 3} else {set a 4}
+ set a
+} {3}
+
+
+test if-old-2.1 {optional then-else args} {
+ set a 44
+ if 0 then {set a 1} elseif 0 then {set a 3} else {set a 2}
+ set a
+} 2
+test if-old-2.2 {optional then-else args} {
+ set a 44
+ if 1 then {set a 1} else {set a 2}
+ set a
+} 1
+test if-old-2.3 {optional then-else args} {
+ set a 44
+ if 0 {set a 1} else {set a 2}
+ set a
+} 2
+test if-old-2.4 {optional then-else args} {
+ set a 44
+ if 1 {set a 1} else {set a 2}
+ set a
+} 1
+test if-old-2.5 {optional then-else args} {
+ set a 44
+ if 0 then {set a 1} {set a 2}
+ set a
+} 2
+test if-old-2.6 {optional then-else args} {
+ set a 44
+ if 1 then {set a 1} {set a 2}
+ set a
+} 1
+test if-old-2.7 {optional then-else args} {
+ set a 44
+ if 0 then {set a 1} else {set a 2}
+ set a
+} 2
+test if-old-2.8 {optional then-else args} {
+ set a 44
+ if 0 then {set a 1} elseif 0 {set a 2} elseif 0 {set a 3} {set a 4}
+ set a
+} 4
+
+test if-old-3.1 {return value} {
+ if 1 then {set a 22; concat abc}
+} abc
+test if-old-3.2 {return value} {
+ if 0 then {set a 22; concat abc} elseif 1 {concat def} {concat ghi}
+} def
+test if-old-3.3 {return value} {
+ if 0 then {set a 22; concat abc} else {concat def}
+} def
+test if-old-3.4 {return value} {
+ if 0 then {set a 22; concat abc}
+} {}
+test if-old-3.5 {return value} {
+ if 0 then {set a 22; concat abc} elseif 0 {concat def}
+} {}
+
+test if-old-4.1 {error conditions} {
+ list [catch {if} msg] $msg
+} {1 {wrong # args: no expression after "if" argument}}
+test if-old-4.2 {error conditions} {
+ list [catch {if {[error "error in condition"]} foo} msg] $msg
+} {1 {error in condition}}
+test if-old-4.3 {error conditions} {
+ list [catch {if 2} msg] $msg
+} {1 {wrong # args: no script following "2" argument}}
+test if-old-4.4 {error conditions} {
+ list [catch {if 2 then} msg] $msg
+} {1 {wrong # args: no script following "then" argument}}
+test if-old-4.5 {error conditions} {
+ list [catch {if 2 the} msg] $msg
+} {1 {invalid command name "the"}}
+test if-old-4.6 {error conditions} {
+ list [catch {if 2 then {[error "error in then clause"]}} msg] $msg
+} {1 {error in then clause}}
+test if-old-4.7 {error conditions} {
+ list [catch {if 0 then foo elseif} msg] $msg
+} {1 {wrong # args: no expression after "elseif" argument}}
+test if-old-4.8 {error conditions} {
+ list [catch {if 0 then foo elsei} msg] $msg
+} {1 {invalid command name "elsei"}}
+test if-old-4.9 {error conditions} {
+ list [catch {if 0 then foo elseif 0 bar else} msg] $msg
+} {1 {wrong # args: no script following "else" argument}}
+test if-old-4.10 {error conditions} {
+ list [catch {if 0 then foo elseif 0 bar els} msg] $msg
+} {1 {invalid command name "els"}}
+test if-old-4.11 {error conditions} {
+ list [catch {if 0 then foo elseif 0 bar else {[error "error in else clause"]}} msg] $msg
+} {1 {error in else clause}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/if.test b/pkgs/msgcat/tests/if.test
new file mode 100644
index 0000000..040364a
--- /dev/null
+++ b/pkgs/msgcat/tests/if.test
@@ -0,0 +1,1282 @@
+# Commands covered: if
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Basic "if" operation.
+
+catch {unset a}
+test if-1.1 {TclCompileIfCmd: missing if/elseif test} -body {
+ if
+} -returnCodes error -result {wrong # args: no expression after "if" argument}
+test if-1.2 {TclCompileIfCmd: error in if/elseif test} -body {
+ if {[error "error in condition"]} foo
+} -returnCodes error -result {error in condition}
+test if-1.3 {TclCompileIfCmd: error in if/elseif test} -body {
+ list [catch {if {1+}} msg] $msg $::errorInfo
+} -match glob -cleanup {
+ unset msg
+} -result {1 * {*"if {1+}"}}
+test if-1.4 {TclCompileIfCmd: if/elseif test in braces} -body {
+ set a {}
+ if {1<2} {set a 1}
+ return $a
+} -cleanup {
+ unset a
+} -result {1}
+test if-1.5 {TclCompileIfCmd: if/elseif test not in braces} -body {
+ set a {}
+ if 1<2 {set a 1}
+ return $a
+} -cleanup {
+ unset a
+} -result {1}
+test if-1.6 {TclCompileIfCmd: multiline test expr} -setup {
+ set a {}
+} -body {
+ if {($tcl_platform(platform) != "foobar1") && \
+ ($tcl_platform(platform) != "foobar2")} {set a 3} else {set a 4}
+ return $a
+} -cleanup {
+ unset a
+} -result 3
+test if-1.7 {TclCompileIfCmd: "then" after if/elseif test} -body {
+ set a {}
+ if 4>3 then {set a 1}
+ return $a
+} -cleanup {
+ unset a
+} -result {1}
+test if-1.8 {TclCompileIfCmd: keyword other than "then" after if/elseif test} -setup {
+ set a {}
+} -body {
+ if 1<2 therefore {set a 1}
+} -cleanup {
+ unset a
+} -returnCodes error -result {invalid command name "therefore"}
+test if-1.9 {TclCompileIfCmd: missing "then" body} -setup {
+ set a {}
+} -body {
+ if 1<2 then
+} -cleanup {
+ unset a
+} -returnCodes error -result {wrong # args: no script following "then" argument}
+test if-1.10 {TclCompileIfCmd: error in "then" body} -body {
+ set a {}
+ list [catch {if {$a!="xxx"} then {set}} msg] $msg $::errorInfo
+} -match glob -cleanup {
+ unset a msg
+} -result {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}}
+test if-1.11 {TclCompileIfCmd: error in "then" body} -body {
+ if 2 then {[error "error in then clause"]}
+} -returnCodes error -result {error in then clause}
+test if-1.12 {TclCompileIfCmd: "then" body in quotes} -body {
+ set a {}
+ if 27>17 "append a x"
+ return $a
+} -cleanup {
+ unset a
+} -result {x}
+test if-1.13 {TclCompileIfCmd: computed "then" body} -setup {
+ catch {unset x1}
+ catch {unset x2}
+} -body {
+ set x1 {append a x1}
+ set x2 {; append a x2}
+ set a {}
+ if 1 $x1$x2
+ return $a
+} -cleanup {
+ unset a x1 x2
+} -result {x1x2}
+test if-1.14 {TclCompileIfCmd: taking proper branch} -body {
+ set a {}
+ if 1<2 {set a 1}
+ return $a
+} -cleanup {
+ unset a
+} -result 1
+test if-1.15 {TclCompileIfCmd: taking proper branch} -body {
+ set a {}
+ if 1>2 {set a 1}
+ return $a
+} -cleanup {
+ unset a
+} -result {}
+test if-1.16 {TclCompileIfCmd: test jumpFalse instruction replacement after long "then" body} -setup {
+ catch {unset i}
+ set a {}
+} -body {
+ if 1<2 {
+ set a 1
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 2
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 3
+ }
+ return $a
+} -cleanup {
+ unset a
+ unset -nocomplain i
+} -result 3
+test if-1.17 {TclCompileIfCmd: if/elseif test in quotes} -setup {
+ set a {}
+} -body {
+ if {"0 < 3"} {set a 1}
+} -returnCodes error -cleanup {
+ unset a
+} -result {expected boolean value but got "0 < 3"}
+
+test if-2.1 {TclCompileIfCmd: "elseif" after if/elseif test} -setup {
+ set a {}
+} -body {
+ if 3>4 {set a 1} elseif 1 {set a 2}
+ return $a
+} -cleanup {
+ unset a
+} -result {2}
+# Since "else" is optional, the "elwood" below is treated as a command.
+# But then there shouldn't be any additional argument words for the "if".
+test if-2.2 {TclCompileIfCmd: keyword other than "elseif"} -setup {
+ set a {}
+} -body {
+ if 1<2 {set a 1} elwood {set a 2}
+} -returnCodes error -cleanup {
+ unset a
+} -result {wrong # args: extra words after "else" clause in "if" command}
+test if-2.3 {TclCompileIfCmd: missing expression after "elseif"} -setup {
+ set a {}
+} -body {
+ if 1<2 {set a 1} elseif
+} -returnCodes error -cleanup {
+ unset a
+} -result {wrong # args: no expression after "elseif" argument}
+test if-2.4 {TclCompileIfCmd: error in expression after "elseif"} -setup {
+ set a {}
+} -body {
+ list [catch {if 3>4 {set a 1} elseif {1>}} msg] $msg $::errorInfo
+} -match glob -cleanup {
+ unset a msg
+} -result {1 * {*"if 3>4 {set a 1} elseif {1>}"}}
+test if-2.5 {TclCompileIfCmd: test jumpFalse instruction replacement after long "elseif" body} -setup {
+ catch {unset i}
+ set a {}
+} -body {
+ if 1>2 {
+ set a 1
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 2
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 3
+ } elseif 1<2 then { #; this if arm should be taken
+ set a 4
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 5
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 6
+ }
+ return $a
+} -cleanup {
+ unset a
+ unset -nocomplain i
+} -result 6
+
+test if-3.1 {TclCompileIfCmd: "else" clause} -body {
+ set a {}
+ if 3>4 {set a 1} elseif {$a == "foo"} {set a 2} else {set a 3}
+ return $a
+} -cleanup {
+ unset a
+} -result 3
+# Since "else" is optional, the "elsex" below is treated as a command.
+# But then there shouldn't be any additional argument words for the "if".
+test if-3.2 {TclCompileIfCmd: keyword other than "else"} -setup {
+ set a {}
+} -body {
+ if 1<2 then {set a 1} elsex {set a 2}
+} -returnCodes error -cleanup {
+ unset a
+} -result {wrong # args: extra words after "else" clause in "if" command}
+test if-3.3 {TclCompileIfCmd: missing body after "else"} -setup {
+ set a {}
+} -body {
+ if 2<1 {set a 1} else
+} -returnCodes error -cleanup {
+ unset a
+} -result {wrong # args: no script following "else" argument}
+test if-3.4 {TclCompileIfCmd: error compiling body after "else"} -setup {
+ set a {}
+} -body {
+ catch {if 2<1 {set a 1} else {set}}
+ set ::errorInfo
+} -match glob -cleanup {
+ unset a
+} -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test if-3.5 {TclCompileIfCmd: extra arguments after "else" argument} -setup {
+ set a {}
+} -body {
+ if 2<1 {set a 1} else {set a 2} or something
+} -returnCodes error -cleanup {
+ unset a
+} -result {wrong # args: extra words after "else" clause in "if" command}
+# The following test also checks whether contained loops and other
+# commands are properly relocated because a short jump must be replaced
+# by a "long distance" one.
+test if-3.6 {TclCompileIfCmd: test jumpFalse instruction replacement after long "else" clause} -setup {
+ catch {unset i}
+ set a {}
+} -body {
+ if 1>2 {
+ set a 1
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 2
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 3
+ } elseif 1==2 then { #; this if arm should be taken
+ set a 4
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 5
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 6
+ } else {
+ set a 7
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 8
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ if {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 9
+ }
+ return $a
+} -cleanup {
+ unset a
+ unset -nocomplain i
+} -result 9
+
+test if-4.1 {TclCompileIfCmd: "if" command result} -setup {
+ set a {}
+} -body {
+ set a [if 3<4 {set i 27}]
+ return $a
+} -cleanup {
+ unset a
+ unset -nocomplain i
+} -result 27
+test if-4.2 {TclCompileIfCmd: "if" command result} -setup {
+ set a {}
+} -body {
+ set a [if 3>4 {set i 27}]
+ return $a
+} -cleanup {
+ unset a
+ unset -nocomplain i
+} -result {}
+test if-4.3 {TclCompileIfCmd: "if" command result} -setup {
+ set a {}
+} -body {
+ set a [if 0 {set i 1} elseif 1 {set i 2}]
+ return $a
+} -cleanup {
+ unset a
+ unset -nocomplain i
+} -result 2
+test if-4.4 {TclCompileIfCmd: "if" command result} -setup {
+ set a {}
+} -body {
+ set a [if 0 {set i 1} elseif 0 {set i 2} elseif 2>5 {set i 3} else {set i 4}]
+ return $a
+} -cleanup {
+ unset a i
+} -result 4
+test if-4.5 {TclCompileIfCmd: return value} -body {
+ if 0 then {set a 22; concat abc} elseif 1 {concat def} {concat ghi}
+} -cleanup {
+ unset -nocomplain a
+} -result def
+
+# Check "if" and computed command names.
+
+test if-5.1 {if cmd with computed command names: missing if/elseif test} -body {
+ set z if
+ $z
+} -returnCodes error -cleanup {
+ unset z
+} -result {wrong # args: no expression after "if" argument}
+test if-5.2 {if cmd with computed command names: error in if/elseif test} -body {
+ set z if
+ $z {[error "error in condition"]} foo
+} -returnCodes error -cleanup {
+ unset z
+} -result {error in condition}
+test if-5.3 {if cmd with computed command names: error in if/elseif test} -body {
+ set z if
+ list [catch {$z {1+}}] $::errorInfo
+} -match glob -cleanup {
+ unset z
+} -result {1 {*"$z {1+}"}}
+test if-5.4 {if cmd with computed command names: if/elseif test in braces} -setup {
+ set a {}
+} -body {
+ set z if
+ $z {1<2} {set a 1}
+ return $a
+} -cleanup {
+ unset a z
+} -result {1}
+test if-5.5 {if cmd with computed command names: if/elseif test not in braces} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 1<2 {set a 1}
+ return $a
+} -cleanup {
+ unset a z
+} -result {1}
+test if-5.6 {if cmd with computed command names: multiline test expr} -body {
+ set z if
+ $z {($tcl_platform(platform) != "foobar1") && \
+ ($tcl_platform(platform) != "foobar2")} {set a 3} else {set a 4}
+ return $a
+} -cleanup {
+ unset a z
+} -result 3
+test if-5.7 {if cmd with computed command names: "then" after if/elseif test} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 4>3 then {set a 1}
+ return $a
+} -cleanup {
+ unset a z
+} -result {1}
+test if-5.8 {if cmd with computed command names: keyword other than "then" after if/elseif test} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 1<2 therefore {set a 1}
+} -returnCodes error -cleanup {
+ unset a z
+} -result {invalid command name "therefore"}
+test if-5.9 {if cmd with computed command names: missing "then" body} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 1<2 then
+} -returnCodes error -cleanup {
+ unset a z
+} -result {wrong # args: no script following "then" argument}
+test if-5.10 {if cmd with computed command names: error in "then" body} -body {
+ set z if
+ set a {}
+ list [catch {$z {$a!="xxx"} then {set}} msg] $msg $::errorInfo
+} -match glob -cleanup {
+ unset a z msg
+} -result {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"
+ invoked from within
+"$z {$a!="xxx"} then {set}"}}
+test if-5.11 {if cmd with computed command names: error in "then" body} -body {
+ set z if
+ $z 2 then {[error "error in then clause"]}
+} -returnCodes error -cleanup {
+ unset z
+} -result {error in then clause}
+test if-5.12 {if cmd with computed command names: "then" body in quotes} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 27>17 "append a x"
+ return $a
+} -cleanup {
+ unset a z
+} -result {x}
+test if-5.13 {if cmd with computed command names: computed "then" body} -setup {
+ catch {unset x1}
+ catch {unset x2}
+} -body {
+ set z if
+ set x1 {append a x1}
+ set x2 {; append a x2}
+ set a {}
+ $z 1 $x1$x2
+ return $a
+} -cleanup {
+ unset a z x1 x2
+} -result {x1x2}
+test if-5.14 {if cmd with computed command names: taking proper branch} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 1<2 {set a 1}
+ return $a
+} -cleanup {
+ unset a z
+} -result 1
+test if-5.15 {if cmd with computed command names: taking proper branch} -body {
+ set a {}
+ set z if
+ $z 1>2 {set a 1}
+ return $a
+} -cleanup {
+ unset a z
+} -result {}
+test if-5.16 {if cmd with computed command names: test jumpFalse instruction replacement after long "then" body} -setup {
+ catch {unset i}
+ set a {}
+} -body {
+ set z if
+ $z 1<2 {
+ set a 1
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 2
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 3
+ }
+ return $a
+} -cleanup {
+ unset a z
+ unset -nocomplain i
+} -result 3
+test if-5.17 {if cmd with computed command names: if/elseif test in quotes} -setup {
+ set a {}
+} -body {
+ set z if
+ $z {"0 < 3"} {set a 1}
+} -returnCodes error -cleanup {
+ unset a z
+} -result {expected boolean value but got "0 < 3"}
+
+test if-6.1 {if cmd with computed command names: "elseif" after if/elseif test} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 3>4 {set a 1} elseif 1 {set a 2}
+ return $a
+} -cleanup {
+ unset a z
+} -result {2}
+# Since "else" is optional, the "elwood" below is treated as a command.
+# But then there shouldn't be any additional argument words for the "if".
+test if-6.2 {if cmd with computed command names: keyword other than "elseif"} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 1<2 {set a 1} elwood {set a 2}
+} -returnCodes error -cleanup {
+ unset a z
+} -result {wrong # args: extra words after "else" clause in "if" command}
+test if-6.3 {if cmd with computed command names: missing expression after "elseif"} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 1<2 {set a 1} elseif
+} -returnCodes error -cleanup {
+ unset a z
+} -result {wrong # args: no expression after "elseif" argument}
+test if-6.4 {if cmd with computed command names: error in expression after "elseif"} -setup {
+ set a {}
+} -body {
+ set z if
+ list [catch {$z 3>4 {set a 1} elseif {1>}}] $::errorInfo
+} -match glob -cleanup {
+ unset a z
+} -result {1 {*"$z 3>4 {set a 1} elseif {1>}"}}
+test if-6.5 {if cmd with computed command names: test jumpFalse instruction replacement after long "elseif" body} -setup {
+ catch {unset i}
+ set a {}
+} -body {
+ set z if
+ $z 1>2 {
+ set a 1
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 2
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 3
+ } elseif 1<2 then { #; this if arm should be taken
+ set a 4
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 5
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 6
+ }
+ return $a
+} -cleanup {
+ unset a z
+ unset -nocomplain i
+} -result 6
+
+test if-7.1 {if cmd with computed command names: "else" clause} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 3>4 {set a 1} elseif {$a == "foo"} {set a 2} else {set a 3}
+ return $a
+} -cleanup {
+ unset a z
+} -result 3
+# Since "else" is optional, the "elsex" below is treated as a command.
+# But then there shouldn't be any additional argument words for the "if".
+test if-7.2 {if cmd with computed command names: keyword other than "else"} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 1<2 then {set a 1} elsex {set a 2}
+} -returnCodes error -cleanup {
+ unset a z
+} -result {wrong # args: extra words after "else" clause in "if" command}
+test if-7.3 {if cmd with computed command names: missing body after "else"} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 2<1 {set a 1} else
+} -returnCodes error -cleanup {
+ unset a z
+} -result {wrong # args: no script following "else" argument}
+test if-7.4 {if cmd with computed command names: error compiling body after "else"} -setup {
+ set a {}
+} -body {
+ set z if
+ catch {$z 2<1 {set a 1} else {set}}
+ return $::errorInfo
+} -match glob -cleanup {
+ unset a z
+} -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"
+ invoked from within
+"$z 2<1 {set a 1} else {set}"}
+test if-7.5 {if cmd with computed command names: extra arguments after "else" argument} -setup {
+ set a {}
+} -body {
+ set z if
+ $z 2<1 {set a 1} else {set a 2} or something
+} -returnCodes error -cleanup {
+ unset a z
+} -result {wrong # args: extra words after "else" clause in "if" command}
+# The following test also checks whether contained loops and other
+# commands are properly relocated because a short jump must be replaced
+# by a "long distance" one.
+test if-7.6 {if cmd with computed command names: test jumpFalse instruction replacement after long "else" clause} -setup {
+ catch {unset i}
+ set a {}
+} -body {
+ set z if
+ $z 1>2 {
+ set a 1
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 2
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 3
+ } elseif 1==2 then { #; this if arm should be taken
+ set a 4
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 5
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 6
+ } else {
+ set a 7
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 8
+ while {$a != "xxx"} {
+ break;
+ while {$i >= 0} {
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ $z {[string compare $a "bar"] < 0} {
+ set i $i
+ set i [lindex $s $i]
+ }
+ set i [expr $i-1]
+ }
+ }
+ set a 9
+ }
+ return $a
+} -cleanup {
+ unset a z
+ unset -nocomplain i
+} -result 9
+
+test if-8.1 {if cmd with computed command names: "if" command result} -setup {
+ set a {}
+} -body {
+ set z if
+ set a [$z 3<4 {set i 27}]
+ return $a
+} -cleanup {
+ unset a z
+ unset -nocomplain i
+} -result 27
+test if-8.2 {if cmd with computed command names: "if" command result} -setup {
+ set a {}
+} -body {
+ set z if
+ set a [$z 3>4 {set i 27}]
+ return $a
+} -cleanup {
+ unset a z
+ unset -nocomplain i
+} -result {}
+test if-8.3 {if cmd with computed command names: "if" command result} -setup {
+ set a {}
+} -body {
+ set z if
+ set a [$z 0 {set i 1} elseif 1 {set i 2}]
+ return $a
+} -cleanup {
+ unset a z
+ unset -nocomplain i
+} -result 2
+test if-8.4 {if cmd with computed command names: "if" command result} -setup {
+ set a {}
+} -body {
+ set z if
+ set a [$z 0 {set i 1} elseif 0 {set i 2} elseif 2>5 {set i 3} else {set i 4}]
+ return $a
+} -cleanup {
+ unset a z
+ unset -nocomplain i
+} -result 4
+test if-8.5 {if cmd with computed command names: return value} -body {
+ set z if
+ $z 0 then {set a 22; concat abc} elseif 1 {concat def} {concat ghi}
+} -cleanup {
+ unset z
+ unset -nocomplain a
+} -result def
+
+test if-9.1 {if cmd with namespace qualifiers} -body {
+ ::if {1} {set x 4}
+} -cleanup {
+ unset x
+} -result 4
+
+# Test for incorrect "double evaluation semantics"
+
+test if-10.1 {delayed substitution of then body} -body {
+ set j 0
+ set if if
+ # this is not compiled
+ $if {[incr j] == 1} "
+ set result $j
+ "
+ # this will be compiled
+ proc p {} {
+ set j 0
+ if {[incr j]} "
+ set result $j
+ "
+ set result
+ }
+ append result [p]
+} -cleanup {
+ unset j if result
+ rename p {}
+} -result {00}
+test if-10.2 {delayed substitution of elseif expression} -body {
+ set j 0
+ set if if
+ # this is not compiled
+ $if {[incr j] == 0} {
+ set result badthen
+ } elseif "$j == 1" {
+ set result badelseif
+ } else {
+ set result 0
+ }
+ # this will be compiled
+ proc p {} {
+ set j 0
+ if {[incr j] == 0} {
+ set result badthen
+ } elseif "$j == 1" {
+ set result badelseif
+ } else {
+ set result 0
+ }
+ set result
+ }
+ append result [p]
+} -cleanup {
+ unset j if result
+ rename p {}
+} -result {00}
+test if-10.3 {delayed substitution of elseif body} -body {
+ set j 0
+ set if if
+ # this is not compiled
+ $if {[incr j] == 0} {
+ set result badthen
+ } elseif {1} "
+ set result $j
+ "
+ # this will be compiled
+ proc p {} {
+ set j 0
+ if {[incr j] == 0} {
+ set result badthen
+ } elseif {1} "
+ set result $j
+ "
+ }
+ append result [p]
+} -cleanup {
+ unset j if result
+ rename p {}
+} -result {00}
+test if-10.4 {delayed substitution of else body} -body {
+ set j 0
+ if {[incr j] == 0} {
+ set result badthen
+ } else "
+ set result $j
+ "
+ return $result
+} -cleanup {
+ unset j result
+} -result {0}
+test if-10.5 {substituted control words} -body {
+ set then then; proc then {} {return badthen}
+ set else else; proc else {} {return badelse}
+ set elseif elseif; proc elseif {} {return badelseif}
+ list [catch {if 1 $then {if 0 {} $elseif 1 {if 0 {} $else {list ok}}}} a] $a
+} -cleanup {
+ unset then else elseif a
+} -result {0 ok}
+test if-10.6 {double invocation of variable traces} -body {
+ set iftracecounter 0
+ proc iftraceproc {args} {
+ upvar #0 iftracecounter counter
+ set argc [llength $args]
+ set extraargs [lrange $args 0 [expr {$argc - 4}]]
+ set name [lindex $args [expr {$argc - 3}]]
+ upvar 1 $name var
+ if {[incr counter] % 2 == 1} {
+ set var "$counter oops [concat $extraargs]"
+ } else {
+ set var "$counter + [concat $extraargs]"
+ }
+ }
+ trace variable iftracevar r [list iftraceproc 10]
+ list [catch {if "$iftracevar + 20" {}} a] $a \
+ [catch {if "$iftracevar + 20" {}} b] $b
+} -cleanup {
+ unset iftracevar iftracecounter a b
+} -match glob -result {1 {*} 0 {}}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/incr-old.test b/pkgs/msgcat/tests/incr-old.test
new file mode 100644
index 0000000..ed457cf
--- /dev/null
+++ b/pkgs/msgcat/tests/incr-old.test
@@ -0,0 +1,92 @@
+# Commands covered: incr
+#
+# This file contains the original set of tests for Tcl's incr command.
+# Since the incr command is now compiled, a new set of tests covering
+# the new implementation is in the file "incr.test". Sourcing this file
+# into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+catch {unset x}
+
+test incr-old-1.1 {basic incr operation} {
+ set x 23
+ list [incr x] $x
+} {24 24}
+test incr-old-1.2 {basic incr operation} {
+ set x 106
+ list [incr x -5] $x
+} {101 101}
+test incr-old-1.3 {basic incr operation} {
+ set x " -106"
+ list [incr x 1] $x
+} {-105 -105}
+test incr-old-1.4 {basic incr operation} {
+ set x " +106"
+ list [incr x 1] $x
+} {107 107}
+
+test incr-old-2.1 {incr errors} {
+ list [catch incr msg] $msg
+} {1 {wrong # args: should be "incr varName ?increment?"}}
+test incr-old-2.2 {incr errors} {
+ list [catch {incr a b c} msg] $msg
+} {1 {wrong # args: should be "incr varName ?increment?"}}
+test incr-old-2.3 {incr errors} {
+ catch {unset x}
+ incr x
+} 1
+test incr-old-2.4 {incr errors} {
+ set x abc
+ list [catch {incr x} msg] $msg $::errorInfo
+} {1 {expected integer but got "abc"} {expected integer but got "abc"
+ while executing
+"incr x"}}
+test incr-old-2.5 {incr errors} {
+ set x 123
+ list [catch {incr x 1a} msg] $msg $::errorInfo
+} {1 {expected integer but got "1a"} {expected integer but got "1a"
+ (reading increment)
+ invoked from within
+"incr x 1a"}}
+test incr-old-2.6 {incr errors} -body {
+ proc readonly args {error "variable is read-only"}
+ set x 123
+ trace var x w readonly
+ list [catch {incr x 1} msg] $msg $::errorInfo
+} -match glob -result {1 {can't set "x": variable is read-only} {*variable is read-only
+ while executing
+*
+"incr x 1"}}
+catch {unset x}
+test incr-old-2.7 {incr errors} {
+ set x -
+ list [catch {incr x 1} msg] $msg
+} {1 {expected integer but got "-"}}
+test incr-old-2.8 {incr errors} {
+ set x { - }
+ list [catch {incr x 1} msg] $msg
+} {1 {expected integer but got " - "}}
+test incr-old-2.9 {incr errors} {
+ set x +
+ list [catch {incr x 1} msg] $msg
+} {1 {expected integer but got "+"}}
+test incr-old-2.10 {incr errors} {
+ set x {20 x}
+ list [catch {incr x 1} msg] $msg
+} {1 {expected integer but got "20 x"}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/incr.test b/pkgs/msgcat/tests/incr.test
new file mode 100644
index 0000000..9243be0
--- /dev/null
+++ b/pkgs/msgcat/tests/incr.test
@@ -0,0 +1,522 @@
+# Commands covered: incr
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+unset -nocomplain x i
+proc readonly varName {
+ upvar 1 $varName var
+ trace add variable var write \
+ {apply {{args} {error "variable is read-only"}}}
+}
+
+# Basic "incr" operation.
+
+test incr-1.1 {TclCompileIncrCmd: missing variable name} -returnCodes error -body {
+ incr
+} -result {wrong # args: should be "incr varName ?increment?"}
+test incr-1.2 {TclCompileIncrCmd: simple variable name} {
+ set i 10
+ list [incr i] $i
+} {11 11}
+test incr-1.3 {TclCompileIncrCmd: error compiling variable name} -body {
+ set i 10
+ incr "i"xxx
+} -returnCodes error -result {extra characters after close-quote}
+test incr-1.4 {TclCompileIncrCmd: simple variable name in quotes} {
+ set i 17
+ list [incr "i"] $i
+} {18 18}
+test incr-1.5 {TclCompileIncrCmd: simple variable name in braces} -setup {
+ unset -nocomplain {a simple var}
+} -body {
+ set {a simple var} 27
+ list [incr {a simple var}] ${a simple var}
+} -result {28 28}
+test incr-1.6 {TclCompileIncrCmd: simple array variable name} -setup {
+ unset -nocomplain a
+} -body {
+ set a(foo) 37
+ list [incr a(foo)] $a(foo)
+} -result {38 38}
+test incr-1.7 {TclCompileIncrCmd: non-simple (computed) variable name} {
+ set x "i"
+ set i 77
+ list [incr $x 2] $i
+} {79 79}
+test incr-1.8 {TclCompileIncrCmd: non-simple (computed) variable name} {
+ set x "i"
+ set i 77
+ list [incr [set x] +2] $i
+} {79 79}
+test incr-1.9 {TclCompileIncrCmd: increment given} {
+ set i 10
+ list [incr i +07] $i
+} {17 17}
+test incr-1.10 {TclCompileIncrCmd: no increment given} {
+ set i 10
+ list [incr i] $i
+} {11 11}
+test incr-1.11 {TclCompileIncrCmd: simple global name} {
+ proc p {} {
+ global i
+ set i 54
+ incr i
+ }
+ p
+} {55}
+test incr-1.12 {TclCompileIncrCmd: simple local name} {
+ proc p {} {
+ set foo 100
+ incr foo
+ }
+ p
+} {101}
+test incr-1.13 {TclCompileIncrCmd: simple but new (unknown) local name} {
+ proc p {} {
+ incr bar
+ }
+ p
+} 1
+test incr-1.14 {TclCompileIncrCmd: simple local name, >255 locals} {
+ proc 260locals {} {
+ # create 260 locals
+ set a0 0; set a1 0; set a2 0; set a3 0; set a4 0
+ set a5 0; set a6 0; set a7 0; set a8 0; set a9 0
+ set b0 0; set b1 0; set b2 0; set b3 0; set b4 0
+ set b5 0; set b6 0; set b7 0; set b8 0; set b9 0
+ set c0 0; set c1 0; set c2 0; set c3 0; set c4 0
+ set c5 0; set c6 0; set c7 0; set c8 0; set c9 0
+ set d0 0; set d1 0; set d2 0; set d3 0; set d4 0
+ set d5 0; set d6 0; set d7 0; set d8 0; set d9 0
+ set e0 0; set e1 0; set e2 0; set e3 0; set e4 0
+ set e5 0; set e6 0; set e7 0; set e8 0; set e9 0
+ set f0 0; set f1 0; set f2 0; set f3 0; set f4 0
+ set f5 0; set f6 0; set f7 0; set f8 0; set f9 0
+ set g0 0; set g1 0; set g2 0; set g3 0; set g4 0
+ set g5 0; set g6 0; set g7 0; set g8 0; set g9 0
+ set h0 0; set h1 0; set h2 0; set h3 0; set h4 0
+ set h5 0; set h6 0; set h7 0; set h8 0; set h9 0
+ set i0 0; set i1 0; set i2 0; set i3 0; set i4 0
+ set i5 0; set i6 0; set i7 0; set i8 0; set i9 0
+ set j0 0; set j1 0; set j2 0; set j3 0; set j4 0
+ set j5 0; set j6 0; set j7 0; set j8 0; set j9 0
+ set k0 0; set k1 0; set k2 0; set k3 0; set k4 0
+ set k5 0; set k6 0; set k7 0; set k8 0; set k9 0
+ set l0 0; set l1 0; set l2 0; set l3 0; set l4 0
+ set l5 0; set l6 0; set l7 0; set l8 0; set l9 0
+ set m0 0; set m1 0; set m2 0; set m3 0; set m4 0
+ set m5 0; set m6 0; set m7 0; set m8 0; set m9 0
+ set n0 0; set n1 0; set n2 0; set n3 0; set n4 0
+ set n5 0; set n6 0; set n7 0; set n8 0; set n9 0
+ set o0 0; set o1 0; set o2 0; set o3 0; set o4 0
+ set o5 0; set o6 0; set o7 0; set o8 0; set o9 0
+ set p0 0; set p1 0; set p2 0; set p3 0; set p4 0
+ set p5 0; set p6 0; set p7 0; set p8 0; set p9 0
+ set q0 0; set q1 0; set q2 0; set q3 0; set q4 0
+ set q5 0; set q6 0; set q7 0; set q8 0; set q9 0
+ set r0 0; set r1 0; set r2 0; set r3 0; set r4 0
+ set r5 0; set r6 0; set r7 0; set r8 0; set r9 0
+ set s0 0; set s1 0; set s2 0; set s3 0; set s4 0
+ set s5 0; set s6 0; set s7 0; set s8 0; set s9 0
+ set t0 0; set t1 0; set t2 0; set t3 0; set t4 0
+ set t5 0; set t6 0; set t7 0; set t8 0; set t9 0
+ set u0 0; set u1 0; set u2 0; set u3 0; set u4 0
+ set u5 0; set u6 0; set u7 0; set u8 0; set u9 0
+ set v0 0; set v1 0; set v2 0; set v3 0; set v4 0
+ set v5 0; set v6 0; set v7 0; set v8 0; set v9 0
+ set w0 0; set w1 0; set w2 0; set w3 0; set w4 0
+ set w5 0; set w6 0; set w7 0; set w8 0; set w9 0
+ set x0 0; set x1 0; set x2 0; set x3 0; set x4 0
+ set x5 0; set x6 0; set x7 0; set x8 0; set x9 0
+ set y0 0; set y1 0; set y2 0; set y3 0; set y4 0
+ set y5 0; set y6 0; set y7 0; set y8 0; set y9 0
+ set z0 0; set z1 0; set z2 0; set z3 0; set z4 0
+ set z5 0; set z6 0; set z7 0; set z8 0; set z9 0
+ # now increment the last one (local var index > 255)
+ incr z9
+ }
+ 260locals
+} {1}
+test incr-1.15 {TclCompileIncrCmd: variable is array} -setup {
+ unset -nocomplain a
+} -body {
+ set a(foo) 27
+ incr a(foo) 11
+} -cleanup {
+ unset -nocomplain a
+} -result 38
+test incr-1.16 {TclCompileIncrCmd: variable is array, elem substitutions} -setup {
+ unset -nocomplain a
+} -body {
+ set i 5
+ set a(foo5) 27
+ incr a(foo$i) 11
+} -cleanup {
+ unset -nocomplain a
+} -result 38
+test incr-1.17 {TclCompileIncrCmd: increment given, simple int} {
+ set i 5
+ incr i 123
+} 128
+test incr-1.18 {TclCompileIncrCmd: increment given, simple int} {
+ set i 5
+ incr i -100
+} -95
+test incr-1.19 {TclCompileIncrCmd: increment given, but erroneous} -body {
+ set i 5
+ catch {incr i [set]} -> opts
+ dict get $opts -errorinfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test incr-1.20 {TclCompileIncrCmd: increment given, in quotes} {
+ set i 25
+ incr i "-100"
+} -75
+test incr-1.21 {TclCompileIncrCmd: increment given, in braces} {
+ set i 24
+ incr i {126}
+} 150
+test incr-1.22 {TclCompileIncrCmd: increment given, large int} {
+ set i 5
+ incr i 200000
+} 200005
+test incr-1.23 {TclCompileIncrCmd: increment given, formatted int != int} {
+ set i 25
+ incr i 0o00012345 ;# an octal literal
+} 5374
+test incr-1.24 {TclCompileIncrCmd: increment given, formatted int != int} -body {
+ set i 25
+ incr i 1a
+} -returnCodes error -result {expected integer but got "1a"}
+test incr-1.25 {TclCompileIncrCmd: too many arguments} -body {
+ set i 10
+ incr i 10 20
+} -returnCodes error -result {wrong # args: should be "incr varName ?increment?"}
+test incr-1.26 {TclCompileIncrCmd: runtime error, bad variable name} {
+ unset -nocomplain {"foo}
+ incr {"foo}
+} 1
+test incr-1.27 {TclCompileIncrCmd: runtime error, bad variable name} -body {
+ list [catch {incr [set]} msg] $msg $::errorInfo
+} -match glob -result {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}}
+test incr-1.28 {TclCompileIncrCmd: runtime error, readonly variable} -body {
+ set x 123
+ readonly x
+ list [catch {incr x 1} msg] $msg $::errorInfo
+} -match glob -cleanup {
+ unset -nocomplain x
+} -result {1 {can't set "x": variable is read-only} {*variable is read-only
+ while executing
+*
+"incr x 1"}}
+test incr-1.29 {TclCompileIncrCmd: runtime error, bad variable value} -body {
+ set x " - "
+ incr x 1
+} -returnCodes error -result {expected integer but got " - "}
+test incr-1.30 {TclCompileIncrCmd: array var, braced (no subs)} -setup {
+ catch {unset array}
+} -body {
+ set array(\$foo) 4
+ incr {array($foo)}
+} -result 5
+
+# Check "incr" and computed command names.
+
+unset -nocomplain x i
+test incr-2.0 {incr and computed command names} {
+ set i 5
+ set z incr
+ $z i -1
+ return $i
+} 4
+test incr-2.1 {incr command (not compiled): missing variable name} -body {
+ set z incr
+ $z
+} -returnCodes error -result {wrong # args: should be "incr varName ?increment?"}
+test incr-2.2 {incr command (not compiled): simple variable name} {
+ set z incr
+ set i 10
+ list [$z i] $i
+} {11 11}
+test incr-2.3 {incr command (not compiled): error compiling variable name} -body {
+ set z incr
+ set i 10
+ $z "i"xxx
+} -returnCodes error -result {extra characters after close-quote}
+test incr-2.4 {incr command (not compiled): simple variable name in quotes} {
+ set z incr
+ set i 17
+ list [$z "i"] $i
+} {18 18}
+test incr-2.5 {incr command (not compiled): simple variable name in braces} -setup {
+ unset -nocomplain {a simple var}
+} -body {
+ set z incr
+ set {a simple var} 27
+ list [$z {a simple var}] ${a simple var}
+} -result {28 28}
+test incr-2.6 {incr command (not compiled): simple array variable name} -setup {
+ unset -nocomplain a
+} -body {
+ set z incr
+ set a(foo) 37
+ list [$z a(foo)] $a(foo)
+} -result {38 38}
+test incr-2.7 {incr command (not compiled): non-simple (computed) variable name} {
+ set z incr
+ set x "i"
+ set i 77
+ list [$z $x 2] $i
+} {79 79}
+test incr-2.8 {incr command (not compiled): non-simple (computed) variable name} {
+ set z incr
+ set x "i"
+ set i 77
+ list [$z [set x] +2] $i
+} {79 79}
+test incr-2.9 {incr command (not compiled): increment given} {
+ set z incr
+ set i 10
+ list [$z i +07] $i
+} {17 17}
+test incr-2.10 {incr command (not compiled): no increment given} {
+ set z incr
+ set i 10
+ list [$z i] $i
+} {11 11}
+test incr-2.11 {incr command (not compiled): simple global name} {
+ proc p {} {
+ set z incr
+ global i
+ set i 54
+ $z i
+ }
+ p
+} {55}
+test incr-2.12 {incr command (not compiled): simple local name} {
+ proc p {} {
+ set z incr
+ set foo 100
+ $z foo
+ }
+ p
+} {101}
+test incr-2.13 {incr command (not compiled): simple but new (unknown) local name} {
+ proc p {} {
+ set z incr
+ $z bar
+ }
+ p
+} 1
+test incr-2.14 {incr command (not compiled): simple local name, >255 locals} {
+ proc 260locals {} {
+ set z incr
+ # create 260 locals
+ set a0 0; set a1 0; set a2 0; set a3 0; set a4 0
+ set a5 0; set a6 0; set a7 0; set a8 0; set a9 0
+ set b0 0; set b1 0; set b2 0; set b3 0; set b4 0
+ set b5 0; set b6 0; set b7 0; set b8 0; set b9 0
+ set c0 0; set c1 0; set c2 0; set c3 0; set c4 0
+ set c5 0; set c6 0; set c7 0; set c8 0; set c9 0
+ set d0 0; set d1 0; set d2 0; set d3 0; set d4 0
+ set d5 0; set d6 0; set d7 0; set d8 0; set d9 0
+ set e0 0; set e1 0; set e2 0; set e3 0; set e4 0
+ set e5 0; set e6 0; set e7 0; set e8 0; set e9 0
+ set f0 0; set f1 0; set f2 0; set f3 0; set f4 0
+ set f5 0; set f6 0; set f7 0; set f8 0; set f9 0
+ set g0 0; set g1 0; set g2 0; set g3 0; set g4 0
+ set g5 0; set g6 0; set g7 0; set g8 0; set g9 0
+ set h0 0; set h1 0; set h2 0; set h3 0; set h4 0
+ set h5 0; set h6 0; set h7 0; set h8 0; set h9 0
+ set i0 0; set i1 0; set i2 0; set i3 0; set i4 0
+ set i5 0; set i6 0; set i7 0; set i8 0; set i9 0
+ set j0 0; set j1 0; set j2 0; set j3 0; set j4 0
+ set j5 0; set j6 0; set j7 0; set j8 0; set j9 0
+ set k0 0; set k1 0; set k2 0; set k3 0; set k4 0
+ set k5 0; set k6 0; set k7 0; set k8 0; set k9 0
+ set l0 0; set l1 0; set l2 0; set l3 0; set l4 0
+ set l5 0; set l6 0; set l7 0; set l8 0; set l9 0
+ set m0 0; set m1 0; set m2 0; set m3 0; set m4 0
+ set m5 0; set m6 0; set m7 0; set m8 0; set m9 0
+ set n0 0; set n1 0; set n2 0; set n3 0; set n4 0
+ set n5 0; set n6 0; set n7 0; set n8 0; set n9 0
+ set o0 0; set o1 0; set o2 0; set o3 0; set o4 0
+ set o5 0; set o6 0; set o7 0; set o8 0; set o9 0
+ set p0 0; set p1 0; set p2 0; set p3 0; set p4 0
+ set p5 0; set p6 0; set p7 0; set p8 0; set p9 0
+ set q0 0; set q1 0; set q2 0; set q3 0; set q4 0
+ set q5 0; set q6 0; set q7 0; set q8 0; set q9 0
+ set r0 0; set r1 0; set r2 0; set r3 0; set r4 0
+ set r5 0; set r6 0; set r7 0; set r8 0; set r9 0
+ set s0 0; set s1 0; set s2 0; set s3 0; set s4 0
+ set s5 0; set s6 0; set s7 0; set s8 0; set s9 0
+ set t0 0; set t1 0; set t2 0; set t3 0; set t4 0
+ set t5 0; set t6 0; set t7 0; set t8 0; set t9 0
+ set u0 0; set u1 0; set u2 0; set u3 0; set u4 0
+ set u5 0; set u6 0; set u7 0; set u8 0; set u9 0
+ set v0 0; set v1 0; set v2 0; set v3 0; set v4 0
+ set v5 0; set v6 0; set v7 0; set v8 0; set v9 0
+ set w0 0; set w1 0; set w2 0; set w3 0; set w4 0
+ set w5 0; set w6 0; set w7 0; set w8 0; set w9 0
+ set x0 0; set x1 0; set x2 0; set x3 0; set x4 0
+ set x5 0; set x6 0; set x7 0; set x8 0; set x9 0
+ set y0 0; set y1 0; set y2 0; set y3 0; set y4 0
+ set y5 0; set y6 0; set y7 0; set y8 0; set y9 0
+ set z0 0; set z1 0; set z2 0; set z3 0; set z4 0
+ set z5 0; set z6 0; set z7 0; set z8 0; set z9 0
+ # now increment the last one (local var index > 255)
+ $z z9
+ }
+ 260locals
+} {1}
+test incr-2.15 {incr command (not compiled): variable is array} -setup {
+ unset -nocomplain a
+} -body {
+ set z incr
+ set a(foo) 27
+ $z a(foo) 11
+} -cleanup {
+ unset -nocomplain a
+} -result 38
+test incr-2.16 {incr command (not compiled): variable is array, elem substitutions} -setup {
+ unset -nocomplain a
+} -body {
+ set z incr
+ set i 5
+ set a(foo5) 27
+ $z a(foo$i) 11
+} -cleanup {
+ unset -nocomplain a
+} -result 38
+test incr-2.17 {incr command (not compiled): increment given, simple int} {
+ set z incr
+ set i 5
+ $z i 123
+} 128
+test incr-2.18 {incr command (not compiled): increment given, simple int} {
+ set z incr
+ set i 5
+ $z i -100
+} -95
+test incr-2.19 {incr command (not compiled): increment given, but erroneous} -body {
+ set z incr
+ set i 5
+ catch {$z i [set]} -> opts
+ dict get $opts -errorinfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test incr-2.20 {incr command (not compiled): increment given, in quotes} {
+ set z incr
+ set i 25
+ $z i "-100"
+} -75
+test incr-2.21 {incr command (not compiled): increment given, in braces} {
+ set z incr
+ set i 24
+ $z i {126}
+} 150
+test incr-2.22 {incr command (not compiled): increment given, large int} {
+ set z incr
+ set i 5
+ $z i 200000
+} 200005
+test incr-2.23 {incr command (not compiled): increment given, formatted int != int} {
+ set z incr
+ set i 25
+ $z i 0o00012345 ;# an octal literal
+} 5374
+test incr-2.24 {incr command (not compiled): increment given, formatted int != int} -body {
+ set z incr
+ set i 25
+ $z i 1a
+} -returnCodes error -result {expected integer but got "1a"}
+test incr-2.25 {incr command (not compiled): too many arguments} -body {
+ set z incr
+ set i 10
+ $z i 10 20
+} -returnCodes error -result {wrong # args: should be "incr varName ?increment?"}
+test incr-2.26 {incr command (not compiled): runtime error, bad variable name} -setup {
+ unset -nocomplain {"foo}
+} -body {
+ set z incr
+ $z {"foo}
+} -result 1
+test incr-2.27 {incr command (not compiled): runtime error, bad variable name} -body {
+ set z incr
+ list [catch {$z [set]} msg] $msg $::errorInfo
+} -match glob -result {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}}
+test incr-2.28 {incr command (not compiled): runtime error, readonly variable} -body {
+ set z incr
+ set x 123
+ readonly x
+ list [catch {$z x 1} msg] $msg $::errorInfo
+} -match glob -cleanup {
+ unset -nocomplain x
+} -result {1 {can't set "x": variable is read-only} {*variable is read-only
+ while executing
+*
+"$z x 1"}}
+test incr-2.29 {incr command (not compiled): runtime error, bad variable value} -body {
+ set z incr
+ set x " - "
+ $z x 1
+} -returnCodes error -result {expected integer but got " - "}
+test incr-2.30 {incr command (not compiled): bad increment} {
+ set z incr
+ set x 0
+ list [catch {$z x 1a} msg] $msg $::errorInfo
+} {1 {expected integer but got "1a"} {expected integer but got "1a"
+ (reading increment)
+ invoked from within
+"$z x 1a"}}
+test incr-2.31 {incr command (compiled): bad increment} {
+ list [catch {incr x 1a} msg] $msg $::errorInfo
+} {1 {expected integer but got "1a"} {expected integer but got "1a"
+ (reading increment)
+ invoked from within
+"incr x 1a"}}
+
+test incr-3.1 {increment by wide amount: bytecode route} {
+ set x 0
+ incr x 123123123123
+} 123123123123
+test incr-3.2 {increment by wide amount: command route} {
+ set z incr
+ set x 0
+ $z x 123123123123
+} 123123123123
+
+test incr-4.1 {increment non-existing array element [Bug 1445454]} -body {
+ proc x {} {incr a(1)}
+ x
+} -cleanup {
+ rename x {}
+} -result 1
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/indexObj.test b/pkgs/msgcat/tests/indexObj.test
new file mode 100644
index 0000000..479cc3b
--- /dev/null
+++ b/pkgs/msgcat/tests/indexObj.test
@@ -0,0 +1,163 @@
+# This file is a Tcl script to test out the the procedures in file
+# tkIndexObj.c, which implement indexed table lookups. The tests here are
+# organized in the standard fashion for Tcl tests.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testindexobj [llength [info commands testindexobj]]
+testConstraint testparseargs [llength [info commands testparseargs]]
+
+test indexObj-1.1 {exact match} testindexobj {
+ testindexobj 1 1 xyz abc def xyz alm
+} {2}
+test indexObj-1.2 {exact match} testindexobj {
+ testindexobj 1 1 abc abc def xyz alm
+} {0}
+test indexObj-1.3 {exact match} testindexobj {
+ testindexobj 1 1 alm abc def xyz alm
+} {3}
+test indexObj-1.4 {unique abbreviation} testindexobj {
+ testindexobj 1 1 xy abc def xalb xyz alm
+} {3}
+test indexObj-1.5 {multiple abbreviations and exact match} testindexobj {
+ testindexobj 1 1 x abc def xalb xyz alm x
+} {5}
+test indexObj-1.6 {forced exact match} testindexobj {
+ testindexobj 1 0 xy abc def xalb xy alm
+} {3}
+test indexObj-1.7 {forced exact match} testindexobj {
+ testindexobj 1 0 x abc def xalb xyz alm x
+} {5}
+test indexObj-1.8 {exact match of empty values} testindexobj {
+ testindexobj 1 1 {} a aa aaa {} b bb bbb
+} 3
+test indexObj-1.9 {exact match of empty values} testindexobj {
+ testindexobj 1 0 {} a aa aaa {} b bb bbb
+} 3
+
+test indexObj-2.1 {no match} testindexobj {
+ list [catch {testindexobj 1 1 dddd abc def xalb xyz alm x} msg] $msg
+} {1 {bad token "dddd": must be abc, def, xalb, xyz, alm, or x}}
+test indexObj-2.2 {no match} testindexobj {
+ list [catch {testindexobj 1 1 dddd abc} msg] $msg
+} {1 {bad token "dddd": must be abc}}
+test indexObj-2.3 {no match: no abbreviations} testindexobj {
+ list [catch {testindexobj 1 0 xy abc def xalb xyz alm} msg] $msg
+} {1 {bad token "xy": must be abc, def, xalb, xyz, or alm}}
+test indexObj-2.4 {ambiguous value} testindexobj {
+ list [catch {testindexobj 1 1 d dumb daughter a c} msg] $msg
+} {1 {ambiguous token "d": must be dumb, daughter, a, or c}}
+test indexObj-2.5 {omit error message} testindexobj {
+ list [catch {testindexobj 0 1 d x} msg] $msg
+} {1 {}}
+test indexObj-2.6 {TCL_EXACT => no "ambiguous" error message} testindexobj {
+ list [catch {testindexobj 1 0 d dumb daughter a c} msg] $msg
+} {1 {bad token "d": must be dumb, daughter, a, or c}}
+test indexObj-2.7 {exact match of empty values} testindexobj {
+ list [catch {testindexobj 1 1 {} a b c} msg] $msg
+} {1 {ambiguous token "": must be a, b, or c}}
+test indexObj-2.8 {exact match of empty values: singleton case} testindexobj {
+ list [catch {testindexobj 1 0 {} a} msg] $msg
+} {1 {bad token "": must be a}}
+test indexObj-2.9 {non-exact match of empty values: singleton case} testindexobj {
+ # NOTE this is a special case. Although the empty string is a
+ # unique prefix, we have an established history of rejecting
+ # empty lookup keys, requiring any unique prefix match to have
+ # at least one character.
+ list [catch {testindexobj 1 1 {} a} msg] $msg
+} {1 {bad token "": must be a}}
+
+test indexObj-3.1 {cache result to skip next lookup} testindexobj {
+ testindexobj check 42
+} {42}
+
+test indexObj-4.1 {free old internal representation} testindexobj {
+ set x {a b}
+ lindex $x 1
+ testindexobj 1 1 $x abc def {a b} zzz
+} {2}
+
+test indexObj-5.1 {Tcl_WrongNumArgs} testindexobj {
+ testwrongnumargs 1 "?-switch?" mycmd
+} "wrong # args: should be \"mycmd ?-switch?\""
+test indexObj-5.2 {Tcl_WrongNumArgs} testindexobj {
+ testwrongnumargs 2 "bar" mycmd foo
+} "wrong # args: should be \"mycmd foo bar\""
+test indexObj-5.3 {Tcl_WrongNumArgs} testindexobj {
+ testwrongnumargs 0 "bar" mycmd foo
+} "wrong # args: should be \"bar\""
+test indexObj-5.4 {Tcl_WrongNumArgs} testindexobj {
+ testwrongnumargs 0 "" mycmd foo
+} "wrong # args: should be \"\""
+test indexObj-5.5 {Tcl_WrongNumArgs} testindexobj {
+ testwrongnumargs 1 "" mycmd foo
+} "wrong # args: should be \"mycmd\""
+test indexObj-5.6 {Tcl_WrongNumArgs} testindexobj {
+ testwrongnumargs 2 "" mycmd foo
+} "wrong # args: should be \"mycmd foo\""
+# Contrast this with test proc-3.6; they have to be like this because
+# of [Bug 1066837] so Itcl won't break.
+test indexObj-5.7 {Tcl_WrongNumArgs} testindexobj {
+ testwrongnumargs 2 "fee fi" "fo fum" foo bar
+} "wrong # args: should be \"fo fum foo fee fi\""
+
+test indexObj-6.1 {Tcl_GetIndexFromObjStruct} testindexobj {
+ set x a
+ testgetindexfromobjstruct $x 0
+} "wrong # args: should be \"testgetindexfromobjstruct a 0\""
+test indexObj-6.2 {Tcl_GetIndexFromObjStruct} testindexobj {
+ set x a
+ testgetindexfromobjstruct $x 0
+ testgetindexfromobjstruct $x 0
+} "wrong # args: should be \"testgetindexfromobjstruct a 0\""
+test indexObj-6.3 {Tcl_GetIndexFromObjStruct} testindexobj {
+ set x c
+ testgetindexfromobjstruct $x 1
+} "wrong # args: should be \"testgetindexfromobjstruct c 1\""
+test indexObj-6.4 {Tcl_GetIndexFromObjStruct} testindexobj {
+ set x c
+ testgetindexfromobjstruct $x 1
+ testgetindexfromobjstruct $x 1
+} "wrong # args: should be \"testgetindexfromobjstruct c 1\""
+
+test indexObj-7.1 {Tcl_ParseArgsObjv} testparseargs {
+ testparseargs
+} {0 1 testparseargs}
+test indexObj-7.2 {Tcl_ParseArgsObjv} testparseargs {
+ testparseargs -bool
+} {1 1 testparseargs}
+test indexObj-7.3 {Tcl_ParseArgsObjv} testparseargs {
+ testparseargs -bool bar
+} {1 2 {testparseargs bar}}
+test indexObj-7.4 {Tcl_ParseArgsObjv} testparseargs {
+ testparseargs bar
+} {0 2 {testparseargs bar}}
+test indexObj-7.5 {Tcl_ParseArgsObjv} -constraints testparseargs -body {
+ testparseargs -help
+} -returnCodes error -result {Command-specific options:
+ -bool: booltest
+ --: Marks the end of the options
+ -help: Print summary of command-line options and abort}
+test indexObj-7.6 {Tcl_ParseArgsObjv} testparseargs {
+ testparseargs -- -bool -help
+} {0 3 {testparseargs -bool -help}}
+test indexObj-7.7 {Tcl_ParseArgsObjv memory management} testparseargs {
+ testparseargs 1 2 3 4 5 6 7 8 9 0 -bool 1 2 3 4 5 6 7 8 9 0
+} {1 21 {testparseargs 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0}}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/info.test b/pkgs/msgcat/tests/info.test
new file mode 100644
index 0000000..3323281
--- /dev/null
+++ b/pkgs/msgcat/tests/info.test
@@ -0,0 +1,1964 @@
+# -*- tcl -*-
+# Commands covered: info
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2006 ActiveState
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# DO NOT DELETE THIS LINE
+
+if {{::tcltest} ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Set up namespaces needed to test operation of "info args", "info body",
+# "info default", and "info procs" with imported procedures.
+
+catch {namespace delete test_ns_info1 test_ns_info2}
+
+namespace eval test_ns_info1 {
+ namespace export *
+ proc p {x} {return "x=$x"}
+ proc q {{y 27} {z {}}} {return "y=$y"}
+}
+
+test info-1.1 {info args option} {
+ proc t1 {a bbb c} {return foo}
+ info args t1
+} {a bbb c}
+test info-1.2 {info args option} {
+ proc t1 {{a default1} {bbb default2} {c default3} args} {return foo}
+ info a t1
+} {a bbb c args}
+test info-1.3 {info args option} {
+ proc t1 "" {return foo}
+ info args t1
+} {}
+test info-1.4 {info args option} -body {
+ catch {rename t1 {}}
+ info args t1
+} -returnCodes error -result {"t1" isn't a procedure}
+test info-1.5 {info args option} -body {
+ info args set
+} -returnCodes error -result {"set" isn't a procedure}
+test info-1.6 {info args option} {
+ proc t1 {a b} {set c 123; set d $c}
+ t1 1 2
+ info args t1
+} {a b}
+test info-1.7 {info args option} {
+ catch {namespace delete test_ns_info2}
+ namespace eval test_ns_info2 {
+ namespace import ::test_ns_info1::*
+ list [info args p] [info args q]
+ }
+} {x {y z}}
+
+test info-2.1 {info body option} {
+ proc t1 {} {body of t1}
+ info body t1
+} {body of t1}
+test info-2.2 {info body option} -body {
+ info body set
+} -returnCodes error -result {"set" isn't a procedure}
+test info-2.3 {info body option} -body {
+ info args set 1
+} -returnCodes error -result {wrong # args: should be "info args procname"}
+test info-2.4 {info body option} {
+ catch {namespace delete test_ns_info2}
+ namespace eval test_ns_info2 {
+ namespace import ::test_ns_info1::*
+ list [info body p] [info body q]
+ }
+} {{return "x=$x"} {return "y=$y"}}
+# Prior to 8.3.0 this would cause a crash because [info body]
+# would return the bytecompiled version of foo, which the catch
+# would then try and eval out of the foo context, accessing
+# compiled local indices
+test info-2.5 {info body option, returning bytecompiled bodies} -body {
+ catch {unset args}
+ proc foo {args} {
+ foreach v $args {
+ upvar $v var
+ return "variable $v existence: [info exists var]"
+ }
+ }
+ foo a
+ eval [info body foo]
+} -returnCodes error -result {can't read "args": no such variable}
+# Fix for problem tested for in info-2.5 caused problems when
+# procedure body had no string rep (i.e. was not yet bytecode)
+# causing an empty string to be returned [Bug #545644]
+test info-2.6 {info body option, returning list bodies} {
+ proc foo args [list subst bar]
+ list [string bytelength [info body foo]] \
+ [foo; string bytelength [info body foo]]
+} {9 9}
+
+proc testinfocmdcount {} {
+ set x [info cmdcount]
+ set y 12345
+ set z [info cm]
+ expr {$z-$x}
+}
+test info-3.1 {info cmdcount compiled} {
+ testinfocmdcount
+} 4
+test info-3.2 {info cmdcount evaled} -body {
+ set x [info cmdcount]
+ set y 12345
+ set z [info cm]
+ expr {$z-$x}
+} -cleanup {unset x y z} -result 4
+test info-3.3 {info cmdcount evaled} -body [info body testinfocmdcount] -cleanup {unset x y z} -result 4
+test info-3.4 {info cmdcount option} -body {
+ info cmdcount 1
+} -returnCodes error -result {wrong # args: should be "info cmdcount"}
+
+test info-4.1 {info commands option} -body {
+ proc t1 {} {}
+ proc t2 {} {}
+ set x " [info commands] "
+ list [string match {* t1 *} $x] [string match {* t2 *} $x] \
+ [string match {* set *} $x] [string match {* list *} $x]
+} -cleanup {unset x} -result {1 1 1 1}
+test info-4.2 {info commands option} -body {
+ proc t1 {} {}
+ rename t1 {}
+ string match {* t1 *} \
+ [info comm]
+} -result 0
+test info-4.3 {info commands option} {
+ proc _t1_ {} {}
+ proc _t2_ {} {}
+ info commands _t1_
+} _t1_
+test info-4.4 {info commands option} {
+ proc _t1_ {} {}
+ proc _t2_ {} {}
+ lsort [info commands _t*]
+} {_t1_ _t2_}
+catch {rename _t1_ {}}
+catch {rename _t2_ {}}
+test info-4.5 {info commands option} -returnCodes error -body {
+ info commands a b
+} -result {wrong # args: should be "info commands ?pattern?"}
+# Also some tests in namespace.test
+
+test info-5.1 {info complete option} -body {
+ info complete
+} -returnCodes error -result {wrong # args: should be "info complete command"}
+test info-5.2 {info complete option} {
+ info complete abc
+} 1
+test info-5.3 {info complete option} {
+ info complete "\{abcd "
+} 0
+test info-5.4 {info complete option} {
+ info complete {# Comment should be complete command}
+} 1
+test info-5.5 {info complete option} {
+ info complete {[a [b] }
+} 0
+test info-5.6 {info complete option} {
+ info complete {[a [b]}
+} 0
+
+test info-6.1 {info default option} {
+ proc t1 {a b {c d} {e "long default value"}} {}
+ info default t1 a value
+} 0
+test info-6.2 {info default option} -body {
+ proc t1 {a b {c d} {e "long default value"}} {}
+ set value 12345
+ info d t1 a value
+ return $value
+} -cleanup {unset value} -result {}
+test info-6.3 {info default option} -body {
+ proc t1 {a b {c d} {e "long default value"}} {}
+ info default t1 c value
+} -cleanup {unset value} -result 1
+test info-6.4 {info default option} -body {
+ proc t1 {a b {c d} {e "long default value"}} {}
+ set value 12345
+ info default t1 c value
+ return $value
+} -cleanup {unset value} -result d
+test info-6.5 {info default option} -body {
+ proc t1 {a b {c d} {e "long default value"}} {}
+ set value 12345
+ set x [info default t1 e value]
+ list $x $value
+} -cleanup {unset x value} -result {1 {long default value}}
+test info-6.6 {info default option} -returnCodes error -body {
+ info default a b
+} -result {wrong # args: should be "info default procname arg varname"}
+test info-6.7 {info default option} -returnCodes error -body {
+ info default _nonexistent_ a b
+} -result {"_nonexistent_" isn't a procedure}
+test info-6.8 {info default option} -returnCodes error -body {
+ proc t1 {a b} {}
+ info default t1 x value
+} -result {procedure "t1" doesn't have an argument "x"}
+test info-6.9 {info default option} -returnCodes error -setup {
+ catch {unset a}
+} -cleanup {unset a} -body {
+ set a(0) 88
+ proc t1 {a b} {}
+ info default t1 a a
+} -returnCodes error -result {can't set "a": variable is array}
+test info-6.10 {info default option} -setup {
+ catch {unset a}
+} -cleanup {unset a} -body {
+ set a(0) 88
+ proc t1 {{a 18} b} {}
+ info default t1 a a
+} -returnCodes error -result {can't set "a": variable is array}
+test info-6.11 {info default option} {
+ catch {namespace delete test_ns_info2}
+ namespace eval test_ns_info2 {
+ namespace import ::test_ns_info1::*
+ list [info default p x foo] $foo [info default q y bar] $bar
+ }
+} {0 {} 1 27}
+
+
+test info-7.1 {info exists option} -body {
+ set value foo
+ info exists value
+} -cleanup {unset value} -result 1
+
+test info-7.2 {info exists option} -setup {catch {unset _nonexistent_}} -body {
+ info exists _nonexistent_
+} -result 0
+test info-7.3 {info exists option} {
+ proc t1 {x} {return [info exists x]}
+ t1 2
+} 1
+test info-7.4 {info exists option} -body {
+ proc t1 {x} {
+ global _nonexistent_
+ return [info exists _nonexistent_]
+ }
+ t1 2
+} -setup {unset -nocomplain _nonexistent_} -result 0
+test info-7.5 {info exists option} {
+ proc t1 {x} {
+ set y 47
+ return [info exists y]
+ }
+ t1 2
+} 1
+test info-7.6 {info exists option} {
+ proc t1 {x} {return [info exists value]}
+ t1 2
+} 0
+test info-7.7 {info exists option} -setup {
+ catch {unset x}
+} -body {
+ set x(2) 44
+ list [info exists x] [info exists x(1)] [info exists x(2)]
+} -result {1 0 1}
+catch {unset x}
+test info-7.8 {info exists option} -body {
+ info exists
+} -returnCodes error -result {wrong # args: should be "info exists varName"}
+test info-7.9 {info exists option} -body {
+ info exists 1 2
+} -returnCodes error -result {wrong # args: should be "info exists varName"}
+
+test info-8.1 {info globals option} -body {
+ set x 1
+ set y 2
+ set value 23
+ set a " [info globals] "
+ list [string match {* x *} $a] [string match {* y *} $a] \
+ [string match {* value *} $a] [string match {* _foobar_ *} $a]
+} -cleanup {unset x y value a} -result {1 1 1 0}
+test info-8.2 {info globals option} -body {
+ set _xxx1 1
+ set _xxx2 2
+ lsort [info g _xxx*]
+} -cleanup {unset _xxx1 _xxx2} -result {_xxx1 _xxx2}
+test info-8.3 {info globals option} -returnCodes error -body {
+ info globals 1 2
+} -result {wrong # args: should be "info globals ?pattern?"}
+test info-8.4 {info globals option: may have leading namespace qualifiers} -body {
+ set x 0
+ list [info globals x] [info globals :x] [info globals ::x] [info globals :::x] [info globals ::::x]
+} -cleanup {unset x} -result {x {} x x x}
+test info-8.5 {info globals option: only return existing global variables} {
+ -setup {
+ unset -nocomplain ::NO_SUCH_VAR
+ proc evalInProc script {eval $script}
+ }
+ -body {
+ evalInProc {global NO_SUCH_VAR; info globals NO_SUCH_VAR}
+ }
+ -cleanup {
+ rename evalInProc {}
+ }
+ -result {}
+}
+
+test info-9.1 {info level option} {
+ info level
+} 0
+test info-9.2 {info level option} {
+ proc t1 {a b} {
+ set x [info le]
+ set y [info level 1]
+ list $x $y
+ }
+ t1 146 testString
+} {1 {t1 146 testString}}
+test info-9.3 {info level option} {
+ proc t1 {a b} {
+ t2 [expr $a*2] $b
+ }
+ proc t2 {x y} {
+ list [info level] [info level 1] [info level 2] [info level -1] \
+ [info level 0]
+ }
+ t1 146 {a {b c} {{{c}}}}
+} {2 {t1 146 {a {b c} {{{c}}}}} {t2 292 {a {b c} {{{c}}}}} {t1 146 {a {b c} {{{c}}}}} {t2 292 {a {b c} {{{c}}}}}}
+test info-9.4 {info level option} {
+ proc t1 {} {
+ set x [info level]
+ set y [info level 1]
+ list $x $y
+ }
+ t1
+} {1 t1}
+test info-9.5 {info level option} -body {
+ info level 1 2
+} -returnCodes error -result {wrong # args: should be "info level ?number?"}
+test info-9.6 {info level option} -body {
+ info level 123a
+} -returnCodes error -result {expected integer but got "123a"}
+test info-9.7 {info level option} -body {
+ info level 0
+} -returnCodes error -result {bad level "0"}
+test info-9.8 {info level option} -body {
+ proc t1 {} {info level -1}
+ t1
+} -returnCodes error -result {bad level "-1"}
+test info-9.9 {info level option} -body {
+ proc t1 {x} {info level $x}
+ t1 -3
+} -returnCodes error -result {bad level "-3"}
+test info-9.10 {info level option, namespaces} -body {
+ namespace eval t {info level 0}
+} -cleanup {
+ namespace delete t
+} -result {namespace eval t {info level 0}}
+test info-9.11 {info level option, aliases} -constraints knownBug -setup {
+ proc w {x y z} {info level 0}
+ interp alias {} a {} w a b
+} -body {
+ a c
+} -cleanup {
+ rename a {}
+ rename w {}
+} -result {a c}
+test info-9.12 {info level option, ensembles} -constraints knownBug -setup {
+ proc w {x y z} {info level 0}
+ namespace ensemble create -command a -map {foo ::w}
+} -body {
+ a foo 1 2 3
+} -cleanup {
+ rename a {}
+ rename w {}
+} -result {a foo 1 2 3}
+
+set savedLibrary $tcl_library
+test info-10.1 {info library option} -body {
+ info library x
+} -returnCodes error -result {wrong # args: should be "info library"}
+test info-10.2 {info library option} {
+ set tcl_library 12345
+ info library
+} {12345}
+test info-10.3 {info library option} -body {
+ unset tcl_library
+ info library
+} -returnCodes error -result {no library has been specified for Tcl}
+set tcl_library $savedLibrary; unset savedLibrary
+
+test info-11.1 {info loaded option} -body {
+ info loaded a b
+} -returnCodes error -result {wrong # args: should be "info loaded ?interp?"}
+test info-11.2 {info loaded option} -body {
+ info loaded {}; info loaded gorp
+} -returnCodes error -result {could not find interpreter "gorp"}
+
+test info-12.1 {info locals option} -body {
+ set a 22
+ proc t1 {x y} {
+ set b 13
+ set c testing
+ global a
+ global aa
+ set aa 23
+ return [info locals]
+ }
+ lsort [t1 23 24]
+} -cleanup {unset a aa} -result {b c x y}
+test info-12.2 {info locals option} {
+ proc t1 {x y} {
+ set xx1 2
+ set xx2 3
+ set y 4
+ return [info loc x*]
+ }
+ lsort [t1 2 3]
+} {x xx1 xx2}
+test info-12.3 {info locals option} -body {
+ info locals 1 2
+} -returnCodes error -result {wrong # args: should be "info locals ?pattern?"}
+test info-12.4 {info locals option} {
+ info locals
+} {}
+test info-12.5 {info locals option} {
+ proc t1 {} {return [info locals]}
+ t1
+} {}
+test info-12.6 {info locals vs unset compiled locals} {
+ proc t1 {lst} {
+ foreach $lst $lst {}
+ unset lst
+ return [info locals]
+ }
+ lsort [t1 {a b c c d e f}]
+} {a b c d e f}
+test info-12.7 {info locals with temporary variables} {
+ proc t1 {} {
+ foreach a {b c} {}
+ info locals
+ }
+ t1
+} {a}
+
+test info-13.1 {info nameofexecutable option} -returnCodes error -body {
+ info nameofexecutable foo
+} -result {wrong # args: should be "info nameofexecutable"}
+
+test info-14.1 {info patchlevel option} -body {
+ set a [info patchlevel]
+ regexp {[0-9]+\.[0-9]+([p[0-9]+)?} $a
+} -cleanup {unset a} -result 1
+test info-14.2 {info patchlevel option} -returnCodes error -body {
+ info patchlevel a
+} -result {wrong # args: should be "info patchlevel"}
+test info-14.3 {info patchlevel option} -setup {
+ set t $tcl_patchLevel
+} -body {
+ unset tcl_patchLevel
+ info patchlevel
+} -cleanup {
+ set tcl_patchLevel $t; unset t
+} -returnCodes error -result {can't read "tcl_patchLevel": no such variable}
+
+test info-15.1 {info procs option} -body {
+ proc t1 {} {}
+ proc t2 {} {}
+ set x " [info procs] "
+ list [string match {* t1 *} $x] [string match {* t2 *} $x] \
+ [string match {* _undefined_ *} $x]
+} -cleanup {unset x} -result {1 1 0}
+test info-15.2 {info procs option} {
+ proc _tt1 {} {}
+ proc _tt2 {} {}
+ lsort [info pr _tt*]
+} {_tt1 _tt2}
+catch {rename _tt1 {}}
+catch {rename _tt2 {}}
+test info-15.3 {info procs option} -body {
+ info procs 2 3
+} -returnCodes error -result {wrong # args: should be "info procs ?pattern?"}
+test info-15.4 {info procs option} -setup {
+ catch {namespace delete test_ns_info2}
+} -body {
+ namespace eval test_ns_info2 {
+ namespace import ::test_ns_info1::*
+ proc r {} {}
+ list [lsort [info procs]] [info procs p*]
+ }
+} -result {{p q r} p}
+test info-15.5 {info procs option with a proc in a namespace} -setup {
+ catch {namespace delete test_ns_info2}
+} -body {
+ namespace eval test_ns_info2 {
+ proc p1 { arg } {
+ puts cmd
+ }
+ proc p2 { arg } {
+ puts cmd
+ }
+ }
+ info procs ::test_ns_info2::p1
+} -result {::test_ns_info2::p1}
+test info-15.6 {info procs option with a pattern in a namespace} -setup {
+ catch {namespace delete test_ns_info2}
+} -body {
+ namespace eval test_ns_info2 {
+ proc p1 { arg } {
+ puts cmd
+ }
+ proc p2 { arg } {
+ puts cmd
+ }
+ }
+ lsort [info procs ::test_ns_info2::p*]
+} -result [lsort [list ::test_ns_info2::p1 ::test_ns_info2::p2]]
+test info-15.7 {info procs option with a global shadowing proc} -setup {
+ catch {namespace delete test_ns_info2}
+} -body {
+ proc string_cmd { arg } {
+ puts cmd
+ }
+ namespace eval test_ns_info2 {
+ proc string_cmd { arg } {
+ puts cmd
+ }
+ }
+ info procs test_ns_info2::string*
+} -result {::test_ns_info2::string_cmd}
+# This regression test is currently commented out because it requires
+# that the implementation of "info procs" looks into the global namespace,
+# which it does not (in contrast to "info commands")
+test info-15.8 {info procs option with a global shadowing proc} -setup {
+ catch {namespace delete test_ns_info2}
+} -constraints knownBug -body {
+ proc string_cmd { arg } {
+ puts cmd
+ }
+ proc string_cmd2 { arg } {
+ puts cmd
+ }
+ namespace eval test_ns_info2 {
+ proc string_cmd { arg } {
+ puts cmd
+ }
+ }
+ namespace eval test_ns_info2 {
+ lsort [info procs string*]
+ }
+} -result [lsort [list string_cmd string_cmd2]]
+
+test info-16.1 {info script option} -returnCodes error -body {
+ info script x x
+} -result {wrong # args: should be "info script ?filename?"}
+test info-16.2 {info script option} {
+ file tail [info sc]
+} "info.test"
+set gorpfile [makeFile "info script\n" gorp.info]
+test info-16.3 {info script option} {
+ list [source $gorpfile] [file tail [info script]]
+} [list $gorpfile info.test]
+test info-16.4 {resetting "info script" after errors} {
+ catch {source ~_nobody_/foo}
+ file tail [info script]
+} "info.test"
+test info-16.5 {resetting "info script" after errors} {
+ catch {source _nonexistent_}
+ file tail [info script]
+} "info.test"
+test info-16.6 {info script option} -body {
+ set script [info script]
+ list [file tail [info script]] \
+ [info script newname.txt] \
+ [file tail [info script $script]]
+} -result [list info.test newname.txt info.test] -cleanup {unset script}
+test info-16.7 {info script option} -body {
+ set script [info script]
+ info script newname.txt
+ list [source $gorpfile] [file tail [info script]] \
+ [file tail [info script $script]]
+} -result [list $gorpfile newname.txt info.test] -cleanup {unset script}
+removeFile gorp.info
+set gorpfile [makeFile {list [info script] [info script foo.bar]} gorp.info]
+test info-16.8 {info script option} {
+ list [source $gorpfile] [file tail [info script]]
+} [list [list $gorpfile foo.bar] info.test]
+removeFile gorp.info; unset gorpfile
+
+test info-17.1 {info sharedlibextension option} -returnCodes error -body {
+ info sharedlibextension foo
+} -result {wrong # args: should be "info sharedlibextension"}
+
+test info-18.1 {info tclversion option} -body {
+ scan [info tclversion] "%d.%d%c" a b c
+} -cleanup {unset -nocomplain a b c} -result 2
+test info-18.2 {info tclversion option} -body {
+ info t 2
+} -returnCodes error -result {wrong # args: should be "info tclversion"}
+test info-18.3 {info tclversion option} -body {
+ unset tcl_version
+ info tclversion
+} -returnCodes error -setup {
+ set t $tcl_version
+} -cleanup {
+ set tcl_version $t; unset t
+} -result {can't read "tcl_version": no such variable}
+
+test info-19.1 {info vars option} -body {
+ set a 1
+ set b 2
+ proc t1 {x y} {
+ global a b
+ set c 33
+ return [info vars]
+ }
+ lsort [t1 18 19]
+} -cleanup {unset a b} -result {a b c x y}
+test info-19.2 {info vars option} -body {
+ set xxx1 1
+ set xxx2 2
+ proc t1 {xxa y} {
+ global xxx1 xxx2
+ set c 33
+ return [info vars x*]
+ }
+ lsort [t1 18 19]
+} -cleanup {unset xxx1 xxx2} -result {xxa xxx1 xxx2}
+test info-19.3 {info vars option} {
+ lsort [info vars]
+} [lsort [info globals]]
+test info-19.4 {info vars option} -returnCodes error -body {
+ info vars a b
+} -result {wrong # args: should be "info vars ?pattern?"}
+test info-19.5 {info vars with temporary variables} {
+ proc t1 {} {
+ foreach a {b c} {}
+ info vars
+ }
+ t1
+} {a}
+test info-19.6 {info vars: Bug 1072654} -setup {
+ namespace eval :: unset -nocomplain foo
+ catch {namespace delete x}
+} -body {
+ namespace eval x info vars foo
+} -cleanup {
+ namespace delete x
+} -result {}
+
+set functions {abs acos asin atan atan2 bool ceil cos cosh double entier exp floor fmod hypot int isqrt log log10 max min pow rand round sin sinh sqrt srand tan tanh wide}
+# Check whether the extra testing functions are defined...
+if {!([catch {expr T1()} msg] && ($msg eq {invalid command name "tcl::mathfunc::T1"}))} {
+ set functions "T1 T2 T3 $functions" ;# A lazy way of prepending!
+}
+test info-20.1 {info functions option} {info functions sin} sin
+test info-20.2 {info functions option} {lsort [info functions]} $functions
+test info-20.3 {info functions option} {
+ lsort [info functions a*]
+} {abs acos asin atan atan2}
+test info-20.4 {info functions option} {
+ lsort [info functions *tan*]
+} {atan atan2 tan tanh}
+test info-20.5 {info functions option} -returnCodes error -body {
+ info functions raise an error
+} -result {wrong # args: should be "info functions ?pattern?"}
+unset functions msg
+
+test info-21.1 {miscellaneous error conditions} -returnCodes error -body {
+ info
+} -result {wrong # args: should be "info subcommand ?arg ...?"}
+test info-21.2 {miscellaneous error conditions} -returnCodes error -body {
+ info gorp
+} -result {unknown or ambiguous subcommand "gorp": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars}
+test info-21.3 {miscellaneous error conditions} -returnCodes error -body {
+ info c
+} -result {unknown or ambiguous subcommand "c": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars}
+test info-21.4 {miscellaneous error conditions} -returnCodes error -body {
+ info l
+} -result {unknown or ambiguous subcommand "l": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars}
+test info-21.5 {miscellaneous error conditions} -returnCodes error -body {
+ info s
+} -result {unknown or ambiguous subcommand "s": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars}
+
+##
+# ### ### ### ######### ######### #########
+## info frame
+## Helper
+# For the more complex results we cut the file name down to remove path
+# dependencies, and we use only part of the first line of the reported
+# command. The latter is required because otherwise the whole test case may
+# appear in some results, but the result is part of the testcase. An infinite
+# string would be required to describe that. The cutting-down breaks this.
+proc reduce {frame} {
+ set pos [lsearch -exact $frame cmd]
+ incr pos
+ set cmd [lindex $frame $pos]
+ if {[regexp \n $cmd]} {
+ set first [string range [lindex [split $cmd \n] 0] 0 end-4]
+ set frame [lreplace $frame $pos $pos $first]
+ }
+ set pos [lsearch -exact $frame file]
+ if {$pos >=0} {
+ incr pos
+ set tail [file tail [lindex $frame $pos]]
+ set frame [lreplace $frame $pos $pos $tail]
+ }
+ set frame
+}
+proc subinterp {} { interp create sub ; interp debug sub -frame 1;
+ interp eval sub [list proc reduce [info args reduce] [info body reduce]]
+}
+## Helper
+# Generate a stacktrace from the current location to top. This code
+# not only depends on the exact location of things, but also on the
+# implementation of tcltest. Any changes and these tests will have to
+# be updated.
+
+proc etrace {} {
+ set res {}
+ set level [info frame]
+ while {$level} {
+ lappend res [list $level [reduce [info frame $level]]]
+ incr level -1
+ }
+ return $res
+}
+
+##
+
+test info-22.0 {info frame, levels} {!singleTestInterp} {
+ info frame
+} 7
+test info-22.1 {info frame, bad level relative} {!singleTestInterp} {
+ # catch is another level!, i.e. we have 8, not 7
+ catch {info frame -8} msg
+ set msg
+} {bad level "-8"}
+test info-22.2 {info frame, bad level absolute} {!singleTestInterp} {
+ # catch is another level!, i.e. we have 8, not 7
+ catch {info frame 9} msg
+ set msg
+} {bad level "9"}
+test info-22.3 {info frame, current, relative} -match glob -body {
+ info frame 0
+} -result {type source line 750 file */info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-22.4 {info frame, current, relative, nested} -match glob -body {
+ set res [info frame 0]
+} -result {type source line 753 file */info.test cmd {info frame 0} proc ::tcltest::RunTest} -cleanup {unset res}
+test info-22.5 {info frame, current, absolute} -constraints {!singleTestInterp} -match glob -body {
+ reduce [info frame 7]
+} -result {type source line 756 file info.test cmd {info frame 7} proc ::tcltest::RunTest}
+test info-22.6 {info frame, global, relative} {!singleTestInterp} {
+ reduce [info frame -6]
+} {type source line 758 file info.test cmd test\ info-22.6\ \{info\ frame,\ global,\ relative\}\ \{!singleTestInter level 0}
+test info-22.7 {info frame, global, absolute} {!singleTestInterp} {
+ reduce [info frame 1]
+} {type source line 761 file info.test cmd test\ info-22.7\ \{info\ frame,\ global,\ absolute\}\ \{!singleTestInter level 0}
+test info-22.8 {info frame, basic trace} -match glob -body {
+ join [lrange [etrace] 0 2] \n
+} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type source line 765 file info.test cmd etrace proc ::tcltest::RunTest}
+* {type source line * file tcltest* cmd {uplevel 1 $script} proc ::tcltest::RunTest}}
+unset -nocomplain msg
+
+test info-23.0.0 {eval'd info frame} {!singleTestInterp} {
+ eval {info frame}
+} 8
+test info-23.0.1 {eval'd info frame} -constraints {singleTestInterp} -match glob -body {
+ eval {info frame}
+} -result {1[12]} ;# SingleTestInterp results changes depending on running the whole suite, or info.test alone.
+test info-23.1.0 {eval'd info frame, semi-dynamic} {!singleTestInterp} {
+ eval info frame
+} 8
+test info-23.1.1 {eval'd info frame, semi-dynamic} -constraints {singleTestInterp} -match glob -body {
+ eval info frame
+} -result {1[12]}
+test info-23.2.0 {eval'd info frame, dynamic} -constraints {!singleTestInterp} -body {
+ set script {info frame}
+ eval $script
+} -cleanup {unset script} -result 8
+test info-23.2.1 {eval'd info frame, dynamic} -constraints {singleTestInterp} -match glob -body {
+ set script {info frame}
+ eval $script
+} -cleanup {unset script} -result {1[12]}
+test info-23.3 {eval'd info frame, literal} -match glob -body {
+ eval {
+ info frame 0
+ }
+} -result {type source line 793 file * cmd {info frame 0} proc ::tcltest::RunTest}
+test info-23.4 {eval'd info frame, semi-dynamic} {
+ eval info frame 0
+} {type eval line 1 cmd {info frame 0} proc ::tcltest::RunTest}
+test info-23.5 {eval'd info frame, dynamic} -cleanup {unset script} -body {
+ set script {info frame 0}
+ eval $script
+} -result {type eval line 1 cmd {info frame 0} proc ::tcltest::RunTest}
+test info-23.6 {eval'd info frame, trace} -match glob -cleanup {unset script} -body {
+ set script {etrace}
+ join [lrange [eval $script] 0 2] \n
+} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type eval line 1 cmd etrace proc ::tcltest::RunTest}
+* {type source line 805 file info.test cmd {eval $script} proc ::tcltest::RunTest}}
+
+# -------------------------------------------------------------------------
+
+# Procedures defined in scripts which are arguments to control
+# structures (like 'namespace eval', 'interp eval', 'if', 'while',
+# 'switch', 'catch', 'for', 'foreach', etc.) have no absolute
+# location. The command implementations execute such scripts through
+# Tcl_EvalObjEx. Flag 0 causes it to use the bytecode compiler. This
+# causes the connection to the context to be lost. Currently only
+# procedure bodies are able to remember their context.
+
+# NOTE THAT THESE DO NOT USE THE -setup OPTION TO [test]
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {
+ proc bar {} {info frame 0}
+}
+
+test info-24.0 {info frame, interaction, namespace eval} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 825 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+set flag 1
+if {$flag} {
+ namespace eval foo {}
+ proc ::foo::bar {} {info frame 0}
+}
+
+test info-24.1 {info frame, interaction, if} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 839 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+set flag 1
+while {$flag} {
+ namespace eval foo {}
+ proc ::foo::bar {} {info frame 0}
+ set flag 0
+};unset flag
+
+test info-24.2 {info frame, interaction, while} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 853 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+catch {
+ namespace eval foo {}
+ proc ::foo::bar {} {info frame 0}
+}
+
+test info-24.3 {info frame, interaction, catch} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 867 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+foreach var val {
+ namespace eval foo {}
+ proc ::foo::bar {} {info frame 0}
+ break
+}; unset var
+
+test info-24.4 {info frame, interaction, foreach} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 880 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+for {} {1} {} {
+ namespace eval foo {}
+ proc ::foo::bar {} {info frame 0}
+ break
+}
+
+test info-24.5 {info frame, interaction, for} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 894 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+set x foo
+switch -exact -- $x {
+ foo {
+ proc ::foo::bar {} {info frame 0}
+ }
+}
+
+test info-24.6.0 {info frame, interaction, switch, list body} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+ unset x
+} -result {type source line 910 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+set x foo
+switch -exact -- $x foo {
+ proc ::foo::bar {} {info frame 0}
+}
+
+test info-24.6.1 {info frame, interaction, switch, multi-body} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+ unset x
+} -result {type source line 926 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+set x foo
+switch -exact -- $x [list foo {
+ proc ::foo::bar {} {info frame 0}
+}]
+
+test info-24.6.2 {info frame, interaction, switch, list body, dynamic} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+ unset x
+} -result {type proc line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+dict for {k v} {foo bar} {
+ proc ::foo::bar {} {info frame 0}
+}
+
+test info-24.7 {info frame, interaction, dict for} {
+ reduce [foo::bar]
+} {type source line 955 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo; unset k v
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+set thedict {foo bar}
+dict with thedict {
+ proc ::foo::bar {} {info frame 0}
+}
+
+test info-24.8 {info frame, interaction, dict with} {
+ reduce [foo::bar]
+} {type source line 969 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+unset thedict foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+dict filter {foo bar} script {k v} {
+ proc ::foo::bar {} {info frame 0}
+ set x 1
+}; unset k v x
+
+test info-24.9 {info frame, interaction, dict filter} {
+ reduce [foo::bar]
+} {type source line 983 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+#unset x
+
+# -------------------------------------------------------------------------
+
+eval {
+ proc bar {} {info frame 0}
+}
+
+test info-25.0 {info frame, proc in eval} {
+ reduce [bar]
+} {type source line 997 file info.test cmd {info frame 0} proc ::bar level 0}
+# Don't need to clean up yet...
+
+proc bar {} {info frame 0}
+
+test info-25.1 {info frame, regular proc} {
+ reduce [bar]
+} {type source line 1005 file info.test cmd {info frame 0} proc ::bar level 0}
+
+rename bar {}
+
+# -------------------------------------------------------------------------
+# More info-30.x test cases at the end of the file.
+test info-30.0 {bs+nl in literal words} -cleanup {unset res} -body {
+ if {1} {
+ set res \
+ [reduce [info frame 0]];#1018
+ }
+ return $res
+ # This was reporting line 3 instead of the correct 4 because the
+ # bs+nl combination is subst by the parser before the 'if'
+ # command, and the bcc, see the word. Fixed by recording the
+ # offsets of all bs+nl sequences in literal words, then using the
+ # information in the bcc and other places to bump line numbers when
+ # parsing over the location. Also affected: testcases 22.8 and 23.6.
+} -result {type source line 1018 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+# -------------------------------------------------------------------------
+# See 24.0 - 24.5 for similar situations, using literal scripts.
+
+set body {set flag 0
+ set a c
+ set res [info frame 0]} ;# line 3!
+
+test info-31.0 {ns eval, script in variable} -body {namespace eval foo {variable res {}}
+ namespace eval foo $body
+ return $foo::res
+} -result {type eval line 3 cmd {info frame 0} level 0} -cleanup {
+ catch {namespace delete foo}
+}
+test info-31.1 {if, script in variable} -cleanup {unset res a flag} -body {
+ if 1 $body
+ return $res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-31.1a {if, script in variable} -cleanup {unset res a flag} -body {
+ if 1 then $body
+ return $res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-31.2 {while, script in variable} -cleanup {unset flag res a} -body {
+ set flag 1
+ while {$flag} $body
+ return $res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+# .3 - proc - scoping prevent return of result ...
+
+test info-31.4 {foreach, script in variable} -cleanup {unset var res a flag} -body {
+ foreach var val $body
+ set res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-31.5 {for, script in variable} -cleanup {unset flag res a} -body {
+ set flag 1
+ for {} {$flag} {} $body
+ return $res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-31.6 {eval, script in variable} -cleanup {unset res a flag} -body {
+ eval $body
+ return $res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+# -------------------------------------------------------------------------
+
+set body {
+ foo {
+ proc ::foo::bar {} {info frame 0}
+ }
+}
+
+namespace eval foo {}
+set x foo
+switch -exact -- $x $body; unset body
+
+test info-31.7 {info frame, interaction, switch, dynamic} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+ unset x
+} -result {type proc line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+set body {
+ proc ::foo::bar {} {info frame 0}
+}
+
+namespace eval foo {}
+eval $body
+
+test info-32.0 {info frame, dynamic procedure} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type proc line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace {*}{
+ eval
+ foo
+ {proc bar {} {info frame 0}}
+}
+test info-33.0 {{*}, literal, direct} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 1115 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+ set flag 1
+ if {*}{
+ {$flag}
+ {info frame 0}
+ }
+}
+test info-33.1 {{*}, literal, simple, bytecompiled} -body {
+ reduce [foo::bar]
+} -cleanup {
+ namespace delete foo
+} -result {type source line 1130 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace {*}"
+ eval
+ foo
+ {proc bar {} {info frame 0}}
+"
+test info-33.2 {{*}, literal, direct} {
+ reduce [foo::bar]
+} {type source line 1144 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace {*}"eval\nfoo\n{proc bar {} {info frame 0}}\n"
+
+test info-33.2a {{*}, literal, not simple, direct} {
+ reduce [foo::bar]
+} {type proc line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+ set flag 1
+ if {*}"
+ {1}
+ {info frame 0}
+ "
+}
+test info-33.3 {{*}, literal, simple, bytecompiled} {
+ reduce [foo::bar]
+} {type source line 1169 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+ set flag 1
+ if {*}"\n{1}\n{info frame 0}"
+}
+test info-33.3a {{*}, literal, not simple, bytecompiled} {
+ reduce [foo::bar]
+} {type eval line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+set body {
+ eval
+ foo
+ {proc bar {} {
+ info frame 0
+ }}
+}
+namespace {*}$body
+test info-34.0 {{*}, dynamic, direct} {
+ reduce [foo::bar]
+} {type proc line 2 cmd {info frame 0} proc ::foo::bar level 0}
+
+unset body
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+set body {
+ {$flag}
+ {info frame 0}
+}
+proc foo::bar {} {
+ global body ; set flag 1
+ if {*}$body
+}
+test info-34.1 {{*}, literal, bytecompiled} {
+ reduce [foo::bar]
+} {type eval line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+unset body
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+proc foo {} {
+ apply {
+ {x y}
+ {info frame 0}
+ } 0 0
+}
+test info-35.0 {apply, literal} {
+ reduce [foo]
+} {type source line 1231 file info.test cmd {info frame 0} lambda {
+ {x y}
+ {info frame 0}
+ } level 0}
+rename foo {}
+
+set lambda {
+ {x y}
+ {info frame 0}
+}
+test info-35.1 {apply, dynamic} {
+ reduce [apply $lambda 0 0]
+} {type proc line 1 cmd {info frame 0} lambda {
+ {x y}
+ {info frame 0}
+} level 0}
+unset lambda
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+ dict for {k v} {foo bar} {
+ set x [info frame 0]
+ }
+ set x
+}
+test info-36.0 {info frame, dict for, bcc} -body {
+ reduce [foo::bar]
+} -result {type source line 1259 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+ set x foo
+ switch -exact -- $x {
+ foo {set y [info frame 0]}
+ }
+ set y
+}
+
+test info-36.1.0 {switch, list literal, bcc} -body {
+ reduce [foo::bar]
+} -result {type source line 1275 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+ set x foo
+ switch -exact -- $x foo {set y [info frame 0]}
+ set y
+}
+
+test info-36.1.1 {switch, multi-body literals, bcc} -body {
+ reduce [foo::bar]
+} -result {type source line 1291 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+test info-37.0 {eval pure list, single line} -match glob -body {
+ # Basically, counting the newline in the word seen through $foo
+ # doesn't really make sense. It makes a bit of sense if the word
+ # would have been a string literal in the command list.
+ #
+ # Problem: At the point where we see the list elements we cannot
+ # distinguish the two cases, thus we cannot switch between
+ # count/not-count, it is has to be one or the other for all
+ # cases. Of the two possibilities miguel convinced me that 'not
+ # counting' is the more proper.
+ set foo {b
+ c}
+ set cmd [list foreach $foo {x y} {
+ set res [join [lrange [etrace] 0 2] \n]
+ break
+ }]
+ eval $cmd
+ return $res
+} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type eval line 2 cmd etrace proc ::tcltest::RunTest}
+* {type eval line 1 cmd foreac proc ::tcltest::RunTest}} -cleanup {unset foo cmd res b c}
+
+# -------------------------------------------------------------------------
+
+# 6 cases.
+## DV. direct-var - unchanged
+## DPV direct-proc-var - ditto
+## PPV proc-proc-var - ditto
+## DL. direct-literal - now tracking absolute location
+## DPL direct-proc-literal - ditto
+## PPL proc-proc-literal - ditto
+## ### ### ### ######### ######### #########"
+
+proc control {vv script} {
+ upvar 1 $vv var
+ return [uplevel 1 $script]
+}
+
+proc datal {} {
+ control y {
+ set y PPL
+ etrace
+ }
+}
+
+proc datav {} {
+ set script {
+ set y PPV
+ etrace
+ }
+ control y $script
+}
+
+test info-38.1 {location information for uplevel, dv, direct-var} -match glob -body {
+ set script {
+ set y DV.
+ etrace
+ }
+ join [lrange [uplevel \#0 $script] 0 2] \n
+} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type eval line 3 cmd etrace proc ::tcltest::RunTest}
+* {type source line 1361 file info.test cmd {uplevel \\#0 $script} proc ::tcltest::RunTest}} -cleanup {unset script y}
+
+# 38.2 moved to bottom to not disturb other tests with the necessary changes to this one.
+
+
+
+
+
+
+
+
+test info-38.3 {location information for uplevel, dpv, direct-proc-var} -match glob -body {
+ set script {
+ set y DPV
+ etrace
+ }
+ join [lrange [control y $script] 0 3] \n
+} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type eval line 3 cmd etrace proc ::control}
+* {type source line 1338 file info.test cmd {uplevel 1 $script} proc ::control}
+* {type source line 1380 file info.test cmd {control y $script} proc ::tcltest::RunTest}} -cleanup {unset script y}
+
+# 38.4 moved to bottom to not disturb other tests with the necessary changes to this one.
+
+
+
+
+
+
+
+
+
+test info-38.5 {location information for uplevel, ppv, proc-proc-var} -match glob -body {
+ join [lrange [datav] 0 4] \n
+} -result {* {type source line 728 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type eval line 3 cmd etrace proc ::control}
+* {type source line 1338 file info.test cmd {uplevel 1 $script} proc ::control}
+* {type source line 1353 file info.test cmd {control y $script} proc ::datav level 1}
+* {type source line 1397 file info.test cmd datav proc ::tcltest::RunTest}}
+
+# 38.6 moved to bottom to not disturb other tests with the necessary changes to this one.
+
+
+
+
+
+
+
+testConstraint testevalex [llength [info commands testevalex]]
+test info-38.7 {location information for arg substitution} -constraints testevalex -match glob -body {
+ join [lrange [testevalex {return -level 0 [etrace]}] 0 3] \n
+} -result {* {type source line 728 file info.test cmd {info frame \$level} proc ::etrace level 0}
+* {type eval line 1 cmd etrace proc ::tcltest::RunTest}
+* {type source line 1414 file info.test cmd {testevalex {return -level 0 \[etrace]}} proc ::tcltest::RunTest}
+* {type source line * file tcltest* cmd {uplevel 1 $script} proc ::tcltest::RunTest}}
+
+# -------------------------------------------------------------------------
+# literal sharing
+
+test info-39.0 {location information not confused by literal sharing} -body {
+ namespace eval ::foo {}
+ proc ::foo::bar {} {
+ lappend res {}
+ lappend res [reduce [eval {info frame 0}]]
+ lappend res [reduce [eval {info frame 0}]]
+ return $res
+ }
+ set res [::foo::bar]
+ namespace delete ::foo
+ join $res \n
+} -cleanup {unset res} -result {
+type source line 1427 file info.test cmd {info frame 0} proc ::foo::bar level 0
+type source line 1428 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+# Additional tests for info-30.*, handling of continuation lines (bs+nl sequences).
+
+test info-30.1 {bs+nl in literal words, procedure body, compiled} -body {
+ proc abra {} {
+ if {1} \
+ {
+ return \
+ [reduce [info frame 0]];# line 1446
+ }
+ }
+ abra
+} -cleanup {
+ rename abra {}
+} -result {type source line 1446 file info.test cmd {info frame 0} proc ::abra level 0}
+
+test info-30.2 {bs+nl in literal words, namespace script} {
+ namespace eval xxx {
+ variable res \
+ [reduce [info frame 0]];# line 1457
+ }
+ return $xxx::res
+} {type source line 1457 file info.test cmd {info frame 0} level 0}
+
+test info-30.3 {bs+nl in literal words, namespace multi-word script} {
+ namespace eval xxx variable res \
+ [list [reduce [info frame 0]]];# line 1464
+ return $xxx::res
+} {type source line 1464 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.4 {bs+nl in literal words, eval script} -cleanup {unset res} -body {
+ eval {
+ set ::res \
+ [reduce [info frame 0]];# line 1471
+ }
+ return $res
+} -result {type source line 1471 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.5 {bs+nl in literal words, eval script, with nested words} -body {
+ eval {
+ if {1} \
+ {
+ set ::res \
+ [reduce [info frame 0]];# line 1481
+ }
+ }
+ return $res
+} -cleanup {unset res} -result {type source line 1481 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.6 {bs+nl in computed word} -cleanup {unset res} -body {
+ set res "\
+[reduce [info frame 0]]";# line 1489
+} -result { type source line 1489 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.7 {bs+nl in computed word, in proc} -body {
+ proc abra {} {
+ return "\
+[reduce [info frame 0]]";# line 1495
+ }
+ abra
+} -cleanup {
+ rename abra {}
+} -result { type source line 1495 file info.test cmd {info frame 0} proc ::abra level 0}
+
+test info-30.8 {bs+nl in computed word, nested eval} -body {
+ eval {
+ set \
+ res "\
+[reduce [info frame 0]]";# line 1506
+}
+} -cleanup {unset res} -result { type source line 1506 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.9 {bs+nl in computed word, nested eval} -body {
+ eval {
+ set \
+ res "\
+[reduce \
+ [info frame 0]]";# line 1515
+}
+} -cleanup {unset res} -result { type source line 1515 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.10 {bs+nl in computed word, key to array} -body {
+ set tmp([set \
+ res "\
+[reduce \
+ [info frame 0]]"]) x ; #1523
+ unset tmp
+ set res
+} -cleanup {unset res} -result { type source line 1523 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.11 {bs+nl in subst arguments} -body {
+ subst {[set \
+ res "\
+[reduce \
+ [info frame 0]]"]} ; #1532
+} -cleanup {unset res} -result { type source line 1532 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.12 {bs+nl in computed word, nested eval} -body {
+ eval {
+ set \
+ res "\
+[set x {}] \
+[reduce \
+ [info frame 0]]";# line 1541
+}
+} -cleanup {unset res x} -result { type source line 1541 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.13 {bs+nl in literal words, uplevel script, with nested words} -body {
+ subinterp ; set res [interp eval sub { uplevel #0 {
+ if {1} \
+ {
+ set ::res \
+ [reduce [info frame 0]];# line 1550
+ }
+ }
+ set res }] ; interp delete sub ; set res
+} -cleanup {unset res} -result {type source line 1550 file info.test cmd {info frame 0} level 0}
+
+test info-30.14 {bs+nl, literal word, uplevel through proc} {
+ subinterp ; set res [interp eval sub { proc abra {script} {
+ uplevel 1 $script
+ }
+ set res [abra {
+ return "\
+[reduce [info frame 0]]";# line 1562
+ }]
+ rename abra {}
+ set res }] ; interp delete sub ; set res
+} { type source line 1562 file info.test cmd {info frame 0} proc ::abra}
+
+test info-30.15 {bs+nl in literal words, nested proc body, compiled} {
+ proc a {} {
+ proc b {} {
+ if {1} \
+ {
+ return \
+ [reduce [info frame 0]];# line 1574
+ }
+ }
+ }
+ a ; set res [b]
+ rename a {}
+ rename b {}
+ set res
+} {type source line 1574 file info.test cmd {info frame 0} proc ::b level 0}
+
+test info-30.16 {bs+nl in multi-body switch, compiled} {
+ proc a {value} {
+ switch -regexp -- $value \
+ ^key { info frame 0; # 1587 } \
+ \t### { info frame 0; # 1588 } \
+ {[0-9]*} { info frame 0; # 1589 }
+ }
+ set res {}
+ lappend res [reduce [a {key }]]
+ lappend res [reduce [a {1alpha}]]
+ set res "\n[join $res \n]"
+} {
+type source line 1587 file info.test cmd {info frame 0} proc ::a level 0
+type source line 1589 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.17 {bs+nl in multi-body switch, direct} {
+ switch -regexp -- {key } \
+ ^key { reduce [info frame 0] ;# 1601 } \
+ \t### { } \
+ {[0-9]*} { }
+} {type source line 1601 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.18 {bs+nl, literal word, uplevel through proc, appended, loss of primary tracking data} {
+ proc abra {script} {
+ append script "\n# end of script"
+ uplevel 1 $script
+ }
+ set res [abra {
+ return "\
+[reduce [info frame 0]]";# line 1613, still line of 3 appended script
+ }]
+ rename abra {}
+ set res
+} { type eval line 3 cmd {info frame 0} proc ::abra}
+# { type source line 1606 file info.test cmd {info frame 0} proc ::abra}
+
+test info-30.19 {bs+nl in single-body switch, compiled} {
+ proc a {value} {
+ switch -regexp -- $value {
+ ^key { reduce \
+ [info frame 0] }
+ \t { reduce \
+ [info frame 0] }
+ {[0-9]*} { reduce \
+ [info frame 0] }
+ }
+ }
+ set res {}
+ lappend res [a {key }]
+ lappend res [a {1alpha}]
+ set res "\n[join $res \n]"
+} {
+type source line 1624 file info.test cmd {info frame 0} proc ::a level 0
+type source line 1628 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.20 {bs+nl in single-body switch, direct} {
+ switch -regexp -- {key } { \
+
+ ^key { reduce \
+ [info frame 0] }
+ \t### { }
+ {[0-9]*} { }
+ }
+} {type source line 1643 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.21 {bs+nl in if, full compiled} {
+ proc a {value} {
+ if {$value} \
+ {info frame 0} \
+ {info frame 0} ; # 1653
+ }
+ set res {}
+ lappend res [reduce [a 1]]
+ lappend res [reduce [a 0]]
+ set res "\n[join $res \n]"
+} {
+type source line 1652 file info.test cmd {info frame 0} proc ::a level 0
+type source line 1653 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.22 {bs+nl in computed word, key to array, compiled} {
+ proc a {} {
+ set tmp([set \
+ res "\
+[reduce \
+ [info frame 0]]"]) x ; #1668
+ unset tmp
+ set res
+ }
+ set res [a]
+ rename a {}
+ set res
+} { type source line 1668 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.23 {bs+nl in multi-body switch, full compiled} {
+ proc a {value} {
+ switch -exact -- $value \
+ key { info frame 0; # 1680 } \
+ xxx { info frame 0; # 1681 } \
+ 000 { info frame 0; # 1682 }
+ }
+ set res {}
+ lappend res [reduce [a key]]
+ lappend res [reduce [a 000]]
+ set res "\n[join $res \n]"
+} {
+type source line 1680 file info.test cmd {info frame 0} proc ::a level 0
+type source line 1682 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.24 {bs+nl in single-body switch, full compiled} {
+ proc a {value} {
+ switch -exact -- $value {
+ key { reduce \
+ [info frame 0] }
+ xxx { reduce \
+ [info frame 0] }
+ 000 { reduce \
+ [info frame 0] }
+ }
+ }
+ set res {}
+ lappend res [a key]
+ lappend res [a 000]
+ set res "\n[join $res \n]"
+} {
+type source line 1696 file info.test cmd {info frame 0} proc ::a level 0
+type source line 1700 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.25 {TIP 280 for compiled [subst]} {
+ subst {[reduce [info frame 0]]} ; # 1712
+} {type source line 1712 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.26 {TIP 280 for compiled [subst]} {
+ subst \
+ {[reduce [info frame 0]]} ; # 1716
+} {type source line 1716 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.27 {TIP 280 for compiled [subst]} {
+ subst {
+[reduce [info frame 0]]} ; # 1720
+} {
+type source line 1720 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.28 {TIP 280 for compiled [subst]} {
+ subst {\
+[reduce [info frame 0]]} ; # 1725
+} { type source line 1725 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.29 {TIP 280 for compiled [subst]} {
+ subst {foo\
+[reduce [info frame 0]]} ; # 1729
+} {foo type source line 1729 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.30 {TIP 280 for compiled [subst]} {
+ subst {foo
+[reduce [info frame 0]]} ; # 1733
+} {foo
+type source line 1733 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.31 {TIP 280 for compiled [subst]} {
+ subst {[][reduce [info frame 0]]} ; # 1737
+} {type source line 1737 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.32 {TIP 280 for compiled [subst]} {
+ subst {[\
+][reduce [info frame 0]]} ; # 1741
+} {type source line 1741 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.33 {TIP 280 for compiled [subst]} {
+ subst {[
+][reduce [info frame 0]]} ; # 1745
+} {type source line 1745 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.34 {TIP 280 for compiled [subst]} {
+ subst {[format %s {}
+][reduce [info frame 0]]} ; # 1749
+} {type source line 1749 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.35 {TIP 280 for compiled [subst]} {
+ subst {[format %s {}
+]
+[reduce [info frame 0]]} ; # 1754
+} {
+type source line 1754 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.36 {TIP 280 for compiled [subst]} {
+ subst {
+[format %s {}][reduce [info frame 0]]} ; # 1759
+} {
+type source line 1759 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.37 {TIP 280 for compiled [subst]} {
+ subst {
+[format %s {}]
+[reduce [info frame 0]]} ; # 1765
+} {
+
+type source line 1765 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.38 {TIP 280 for compiled [subst]} {
+ subst {\
+[format %s {}][reduce [info frame 0]]} ; # 1771
+} { type source line 1771 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.39 {TIP 280 for compiled [subst]} {
+ subst {\
+[format %s {}]\
+[reduce [info frame 0]]} ; # 1776
+} { type source line 1776 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.40 {TIP 280 for compiled [subst]} -setup {
+ unset -nocomplain empty
+} -body {
+ set empty {}
+ subst {$empty[reduce [info frame 0]]} ; # 1782
+} -cleanup {
+ unset empty
+} -result {type source line 1782 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.41 {TIP 280 for compiled [subst]} -setup {
+ unset -nocomplain empty
+} -body {
+ set empty {}
+ subst {$empty
+[reduce [info frame 0]]} ; # 1791
+} -cleanup {
+ unset empty
+} -result {
+type source line 1791 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.42 {TIP 280 for compiled [subst]} -setup {
+ unset -nocomplain empty
+} -body {
+ set empty {}; subst {$empty\
+[reduce [info frame 0]]} ; # 1800
+} -cleanup {
+ unset empty
+} -result { type source line 1800 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.43 {TIP 280 for compiled [subst]} -body {
+ unset -nocomplain a\nb
+ set a\nb {}
+ subst {${a
+b}[reduce [info frame 0]]} ; # 1808
+} -cleanup {unset a\nb} -result {type source line 1808 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.44 {TIP 280 for compiled [subst]} {
+ unset -nocomplain a
+ set a(\n) {}
+ subst {$a(
+)[reduce [info frame 0]]} ; # 1814
+} {type source line 1814 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.45 {TIP 280 for compiled [subst]} {
+ unset -nocomplain a
+ set a() {}
+ subst {$a([
+return -level 0])[reduce [info frame 0]]} ; # 1820
+} {type source line 1820 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.46 {TIP 280 for compiled [subst]} {
+ unset -nocomplain a
+ set a(1825) YES; set a(1824) 1824; set a(1826) 1826
+ subst {$a([dict get [info frame 0] line])} ; # 1825
+} YES
+test info-30.47 {TIP 280 for compiled [subst]} {
+ unset -nocomplain a
+ set a(\n1831) YES; set a(\n1830) 1830; set a(\n1832) 1832
+ subst {$a(
+[dict get [info frame 0] line])} ; # 1831
+} YES
+unset -nocomplain a
+
+test info-30.48 {Bug 2850901} testevalex {
+ testevalex {return -level 0 [format %s {}
+][reduce [info frame 0]]} ; # line 2 of the eval
+} {type eval line 2 cmd {info frame 0} proc ::tcltest::RunTest}
+
+
+# -------------------------------------------------------------------------
+# literal sharing 2, bug 2933089
+
+test info-39.1 {location information not confused by literal sharing, bug 2933089} -setup {
+ set result {}
+
+ proc print_one {} {}
+ proc test_info_frame {} {
+ set x 1
+ set y x
+
+ if "$x != 1" {
+ } else {
+ print_one
+ } ;#line 1854^
+
+ if "$$y != 1" {
+ } else {
+ print_one
+ } ;#line 1859^
+ # Do not put the comments listing the line numbers into the
+ # branches. We need shared literals, and the comments would
+ # make them different, thus unshared.
+ }
+
+ proc get_frame_info { cmd_str op } {
+ lappend ::result [reduce [eval {info frame -3}]]
+ }
+ trace add execution print_one enter get_frame_info
+} -body {
+ test_info_frame;
+ join $result \n
+} -cleanup {
+ trace remove execution print_one enter get_frame_info
+ rename get_frame_info {}
+ rename test_info_frame {}
+ rename print_one {}
+} -result {type source line 1854 file info.test cmd print_one proc ::test_info_frame level 1
+type source line 1859 file info.test cmd print_one proc ::test_info_frame level 1}
+
+# -------------------------------------------------------------------------
+# Tests moved to the end to not disturb other tests and their locations.
+
+test info-38.6 {location information for uplevel, ppl, proc-proc-literal} -match glob -setup {subinterp} -body {
+ interp eval sub {
+ proc etrace {} {
+ set res {}
+ set level [info frame]
+ while {$level} {
+ lappend res [list $level [reduce [info frame $level]]]
+ incr level -1
+ }
+ return $res
+ }
+ proc control {vv script} {
+ upvar 1 $vv var
+ return [uplevel 1 $script]
+ }
+ proc datal {} {
+ control y {
+ set y PPL
+ etrace
+ }
+ }
+ join [lrange [datal] 0 4] \n
+ }
+} -result {* {type source line 1890 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type source line 1902 file info.test cmd etrace proc ::control}
+* {type source line 1897 file info.test cmd {uplevel 1 $script} proc ::control}
+* {type source line 1900 file info.test cmd control proc ::datal level 1}
+* {type source line 1905 file info.test cmd datal level 2}} -cleanup {interp delete sub}
+
+test info-38.4 {location information for uplevel, dpv, direct-proc-literal} -match glob -setup {subinterp} -body {
+ interp eval sub {
+ proc etrace {} {
+ set res {}
+ set level [info frame]
+ while {$level} {
+ lappend res [list $level [reduce [info frame $level]]]
+ incr level -1
+ }
+ return $res
+ }
+ proc control {vv script} {
+ upvar 1 $vv var
+ return [uplevel 1 $script]
+ }
+ join [lrange [control y {
+ set y DPL
+ etrace
+ }] 0 3] \n
+ }
+} -result {* {type source line 1919 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type source line 1930 file info.test cmd etrace proc ::control}
+* {type source line 1926 file info.test cmd {uplevel 1 $script} proc ::control}
+* {type source line 1928 file info.test cmd control level 1}} -cleanup {interp delete sub}
+
+test info-38.2 {location information for uplevel, dl, direct-literal} -match glob -setup {subinterp} -body {
+ interp eval sub {
+ proc etrace {} {
+ set res {}
+ set level [info frame]
+ while {$level} {
+ lappend res [list $level [reduce [info frame $level]]]
+ incr level -1
+ }
+ return $res
+ }
+ join [lrange [uplevel \#0 {
+ set y DL.
+ etrace
+ }] 0 2] \n
+ }
+} -result {* {type source line 1944 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type source line 1951 file info.test cmd etrace level 1}
+* {type source line 1949 file info.test cmd uplevel\\ \\\\ level 1}} -cleanup {interp delete sub}
+
+# -------------------------------------------------------------------------
+unset -nocomplain res
+
+# cleanup
+catch {namespace delete test_ns_info1 test_ns_info2}
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/init.test b/pkgs/msgcat/tests/init.test
new file mode 100644
index 0000000..41b8624
--- /dev/null
+++ b/pkgs/msgcat/tests/init.test
@@ -0,0 +1,195 @@
+# Functionality covered: this file contains a collection of tests for the auto
+# loading and namespaces.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2.3.4
+ namespace import -force ::tcltest::*
+}
+
+# Clear out any namespaces called test_ns_*
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+
+# Six cases - white box testing
+
+test init-1.1 {auto_qualify - absolute cmd - namespace} {
+ auto_qualify ::foo::bar ::blue
+} ::foo::bar
+test init-1.2 {auto_qualify - absolute cmd - global} {
+ auto_qualify ::global ::sub
+} global
+test init-1.3 {auto_qualify - no colons cmd - global} {
+ auto_qualify nocolons ::
+} nocolons
+test init-1.4 {auto_qualify - no colons cmd - namespace} {
+ auto_qualify nocolons ::sub
+} {::sub::nocolons nocolons}
+test init-1.5 {auto_qualify - colons in cmd - global} {
+ auto_qualify foo::bar ::
+} ::foo::bar
+test init-1.6 {auto_qualify - colons in cmd - namespace} {
+ auto_qualify foo::bar ::sub
+} {::sub::foo::bar ::foo::bar}
+# Some additional tests
+test init-1.7 {auto_qualify - multiples colons 1} {
+ auto_qualify :::foo::::bar ::blue
+} ::foo::bar
+test init-1.8 {auto_qualify - multiple colons 2} {
+ auto_qualify :::foo ::bar
+} foo
+
+# We use a sub-interp and auto_reset and double the tests because there is 2
+# places where auto_loading occur (before loading the indexes files and after)
+
+set testInterp [interp create]
+tcltest::loadIntoSlaveInterpreter $testInterp {*}$argv
+interp eval $testInterp {
+ namespace import -force ::tcltest::*
+ customMatch pairwise {apply {{mode pair} {
+ if {[llength $pair] != 2} {error "need a pair of values to check"}
+ string $mode [lindex $pair 0] [lindex $pair 1]
+ }}}
+
+ auto_reset
+ catch {rename parray {}}
+
+test init-2.0 {load parray - stage 1} -body {
+ parray
+} -returnCodes error -cleanup {
+ rename parray {} ;# remove it, for the next test - that should not fail.
+} -result {wrong # args: should be "parray a ?pattern?"}
+test init-2.1 {load parray - stage 2} -body {
+ parray
+} -returnCodes error -result {wrong # args: should be "parray a ?pattern?"}
+auto_reset
+catch {rename ::safe::setLogCmd {}}
+#unset -nocomplain auto_index(::safe::setLogCmd) auto_oldpath
+test init-2.2 {load ::safe::setLogCmd - stage 1} {
+ ::safe::setLogCmd
+ rename ::safe::setLogCmd {} ;# should not fail
+} {}
+test init-2.3 {load ::safe::setLogCmd - stage 2} {
+ ::safe::setLogCmd
+ rename ::safe::setLogCmd {} ;# should not fail
+} {}
+auto_reset
+catch {rename ::safe::setLogCmd {}}
+test init-2.4 {load safe:::setLogCmd - stage 1} {
+ safe:::setLogCmd ;# intentionally 3 :
+ rename ::safe::setLogCmd {} ;# should not fail
+} {}
+test init-2.5 {load safe:::setLogCmd - stage 2} {
+ safe:::setLogCmd ;# intentionally 3 :
+ rename ::safe::setLogCmd {} ;# should not fail
+} {}
+auto_reset
+catch {rename ::safe::setLogCmd {}}
+test init-2.6 {load setLogCmd from safe:: - stage 1} {
+ namespace eval safe setLogCmd
+ rename ::safe::setLogCmd {} ;# should not fail
+} {}
+test init-2.7 {oad setLogCmd from safe:: - stage 2} {
+ namespace eval safe setLogCmd
+ rename ::safe::setLogCmd {} ;# should not fail
+} {}
+test init-2.8 {load tcl::HistAdd} -setup {
+ auto_reset
+ catch {rename ::tcl::HistAdd {}}
+} -body {
+ # 3 ':' on purpose
+ tcl:::HistAdd
+} -returnCodes error -cleanup {
+ rename ::tcl::HistAdd {}
+} -result {wrong # args: should be "tcl:::HistAdd event ?exec?"}
+
+test init-3.0 {random stuff in the auto_index, should still work} {
+ set auto_index(foo:::bar::blah) {
+ namespace eval foo {namespace eval bar {proc blah {} {return 1}}}
+ }
+ foo:::bar::blah
+} 1
+
+# Tests that compare the error stack trace generated when autoloading with
+# that generated when no autoloading is necessary. Ideally they should be the
+# same.
+
+set count 0
+foreach arg [subst -nocommands -novariables {
+ c
+ {argument
+ which spans
+ multiple lines}
+ {argument which is all on one line but which is of such great length that the Tcl C library will truncate it when appending it onto the global error stack}
+ {argument which spans multiple lines
+ and is long enough to be truncated and
+" <- includes a false lead in the prune point search
+ and must be longer still to force truncation}
+ {contrived example: rare circumstance
+ where the point at which to prune the
+ error stack cannot be uniquely determined.
+ foo bar foo
+"}
+ {contrived example: rare circumstance
+ where the point at which to prune the
+ error stack cannot be uniquely determined.
+ foo bar
+"}
+ {argument that contains non-ASCII character, \u20ac, and which is of such great length that it will be longer than 150 bytes so it will be truncated by the Tcl C library}
+ }] { ;# emacs needs -> "
+
+ test init-4.$count.0 {::errorInfo produced by [unknown]} -setup {
+ auto_reset
+ } -body {
+ catch {parray a b $arg}
+ set first $::errorInfo
+ catch {parray a b $arg}
+ list $first $::errorInfo
+ } -match pairwise -result equal
+ test init-4.$count.1 {::errorInfo produced by [unknown]} -setup {
+ auto_reset
+ } -body {
+ namespace eval junk [list array set $arg [list 1 2 3 4]]
+ trace variable ::junk::$arg r \
+ "[list error [subst {Variable \"$arg\" is write-only}]] ;# "
+ catch {parray ::junk::$arg}
+ set first $::errorInfo
+ catch {parray ::junk::$arg}
+ list $first $::errorInfo
+ } -match pairwise -result equal
+
+ incr count
+}
+
+test init-5.0 {return options passed through ::unknown} -setup {
+ catch {rename xxx {}}
+ set ::auto_index(::xxx) {proc ::xxx {} {
+ return -code error -level 2 xxx
+ }}
+} -body {
+ set code [catch {::xxx} foo bar]
+ set code2 [catch {::xxx} foo2 bar2]
+ list $code $foo $bar $code2 $foo2 $bar2
+} -cleanup {
+ unset ::auto_index(::xxx)
+} -match glob -result {2 xxx {-errorcode NONE -code 1 -level 1} 2 xxx {-code 1 -level 1 -errorcode NONE}}
+
+cleanupTests
+} ;# End of [interp eval $testInterp]
+
+# cleanup
+interp delete $testInterp
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/interp.test b/pkgs/msgcat/tests/interp.test
new file mode 100644
index 0000000..ab91f77
--- /dev/null
+++ b/pkgs/msgcat/tests/interp.test
@@ -0,0 +1,3630 @@
+# This file tests the multiple interpreter facility of Tcl
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1995-1996 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2.1
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testinterpdelete [llength [info commands testinterpdelete]]
+
+set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempfile tcl:file:type tcl:file:volumes tcl:file:writable unload}
+
+foreach i [interp slaves] {
+ interp delete $i
+}
+
+# Part 0: Check out options for interp command
+test interp-1.1 {options for interp command} -returnCodes error -body {
+ interp
+} -result {wrong # args: should be "interp cmd ?arg ...?"}
+test interp-1.2 {options for interp command} -returnCodes error -body {
+ interp frobox
+} -result {bad option "frobox": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
+test interp-1.3 {options for interp command} {
+ interp delete
+} ""
+test interp-1.4 {options for interp command} -returnCodes error -body {
+ interp delete foo bar
+} -result {could not find interpreter "foo"}
+test interp-1.5 {options for interp command} -returnCodes error -body {
+ interp exists foo bar
+} -result {wrong # args: should be "interp exists ?path?"}
+#
+# test interp-0.6 was removed
+#
+test interp-1.6 {options for interp command} -returnCodes error -body {
+ interp slaves foo bar zop
+} -result {wrong # args: should be "interp slaves ?path?"}
+test interp-1.7 {options for interp command} -returnCodes error -body {
+ interp hello
+} -result {bad option "hello": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
+test interp-1.8 {options for interp command} -returnCodes error -body {
+ interp -froboz
+} -result {bad option "-froboz": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
+test interp-1.9 {options for interp command} -returnCodes error -body {
+ interp -froboz -safe
+} -result {bad option "-froboz": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
+test interp-1.10 {options for interp command} -returnCodes error -body {
+ interp target
+} -result {wrong # args: should be "interp target path alias"}
+
+# Part 1: Basic interpreter creation tests:
+test interp-2.1 {basic interpreter creation} {
+ interp create a
+} a
+test interp-2.2 {basic interpreter creation} {
+ catch {interp create}
+} 0
+test interp-2.3 {basic interpreter creation} {
+ catch {interp create -safe}
+} 0
+test interp-2.4 {basic interpreter creation} {
+ list [catch {interp create a} msg] $msg
+} {1 {interpreter named "a" already exists, cannot create}}
+test interp-2.5 {basic interpreter creation} {
+ interp create b -safe
+} b
+test interp-2.6 {basic interpreter creation} {
+ interp create d -safe
+} d
+test interp-2.7 {basic interpreter creation} {
+ list [catch {interp create -froboz} msg] $msg
+} {1 {bad option "-froboz": must be -safe or --}}
+test interp-2.8 {basic interpreter creation} {
+ interp create -- -froboz
+} -froboz
+test interp-2.9 {basic interpreter creation} {
+ interp create -safe -- -froboz1
+} -froboz1
+test interp-2.10 {basic interpreter creation} {
+ interp create {a x1}
+ interp create {a x2}
+ interp create {a x3} -safe
+} {a x3}
+test interp-2.11 {anonymous interps vs existing procs} {
+ set x [interp create]
+ regexp "interp(\[0-9]+)" $x dummy thenum
+ interp delete $x
+ proc interp$thenum {} {}
+ set x [interp create]
+ regexp "interp(\[0-9]+)" $x dummy anothernum
+ expr $anothernum > $thenum
+} 1
+test interp-2.12 {anonymous interps vs existing procs} {
+ set x [interp create -safe]
+ regexp "interp(\[0-9]+)" $x dummy thenum
+ interp delete $x
+ proc interp$thenum {} {}
+ set x [interp create -safe]
+ regexp "interp(\[0-9]+)" $x dummy anothernum
+ expr $anothernum - $thenum
+} 1
+test interp-2.13 {correct default when no $path arg is given} -body {
+ interp create --
+} -match regexp -result {interp[0-9]+}
+
+foreach i [interp slaves] {
+ interp delete $i
+}
+
+# Part 2: Testing "interp slaves" and "interp exists"
+test interp-3.1 {testing interp exists and interp slaves} {
+ interp slaves
+} ""
+test interp-3.2 {testing interp exists and interp slaves} {
+ interp create a
+ interp exists a
+} 1
+test interp-3.3 {testing interp exists and interp slaves} {
+ interp exists nonexistent
+} 0
+test interp-3.4 {testing interp exists and interp slaves} -body {
+ interp slaves a b c
+} -returnCodes error -result {wrong # args: should be "interp slaves ?path?"}
+test interp-3.5 {testing interp exists and interp slaves} -body {
+ interp exists a b c
+} -returnCodes error -result {wrong # args: should be "interp exists ?path?"}
+test interp-3.6 {testing interp exists and interp slaves} {
+ interp exists
+} 1
+test interp-3.7 {testing interp exists and interp slaves} {
+ interp slaves
+} a
+test interp-3.8 {testing interp exists and interp slaves} -body {
+ interp slaves a b c
+} -returnCodes error -result {wrong # args: should be "interp slaves ?path?"}
+test interp-3.9 {testing interp exists and interp slaves} {
+ interp create {a a2} -safe
+ expr {"a2" in [interp slaves a]}
+} 1
+test interp-3.10 {testing interp exists and interp slaves} {
+ interp exists {a a2}
+} 1
+
+# Part 3: Testing "interp delete"
+test interp-3.11 {testing interp delete} {
+ interp delete
+} ""
+test interp-4.1 {testing interp delete} {
+ catch {interp create a}
+ interp delete a
+} ""
+test interp-4.2 {testing interp delete} -returnCodes error -body {
+ interp delete nonexistent
+} -result {could not find interpreter "nonexistent"}
+test interp-4.3 {testing interp delete} -returnCodes error -body {
+ interp delete x y z
+} -result {could not find interpreter "x"}
+test interp-4.4 {testing interp delete} {
+ interp delete
+} ""
+test interp-4.5 {testing interp delete} {
+ interp create a
+ interp create {a x1}
+ interp delete {a x1}
+ expr {"x1" in [interp slaves a]}
+} 0
+test interp-4.6 {testing interp delete} {
+ interp create c1
+ interp create c2
+ interp create c3
+ interp delete c1 c2 c3
+} ""
+test interp-4.7 {testing interp delete} -returnCodes error -body {
+ interp create c1
+ interp create c2
+ interp delete c1 c2 c3
+} -result {could not find interpreter "c3"}
+test interp-4.8 {testing interp delete} -returnCodes error -body {
+ interp delete {}
+} -result {cannot delete the current interpreter}
+
+foreach i [interp slaves] {
+ interp delete $i
+}
+
+# Part 4: Consistency checking - all nondeleted interpreters should be
+# there:
+test interp-5.1 {testing consistency} {
+ interp slaves
+} ""
+test interp-5.2 {testing consistency} {
+ interp exists a
+} 0
+test interp-5.3 {testing consistency} {
+ interp exists nonexistent
+} 0
+
+# Recreate interpreter "a"
+interp create a
+
+# Part 5: Testing eval in interpreter object command and with interp command
+test interp-6.1 {testing eval} {
+ a eval expr 3 + 5
+} 8
+test interp-6.2 {testing eval} -returnCodes error -body {
+ a eval foo
+} -result {invalid command name "foo"}
+test interp-6.3 {testing eval} {
+ a eval {proc foo {} {expr 3 + 5}}
+ a eval foo
+} 8
+test interp-6.4 {testing eval} {
+ interp eval a foo
+} 8
+test interp-6.5 {testing eval} {
+ interp create {a x2}
+ interp eval {a x2} {proc frob {} {expr 4 * 9}}
+ interp eval {a x2} frob
+} 36
+test interp-6.6 {testing eval} -returnCodes error -body {
+ interp eval {a x2} foo
+} -result {invalid command name "foo"}
+
+# UTILITY PROCEDURE RUNNING IN MASTER INTERPRETER:
+proc in_master {args} {
+ return [list seen in master: $args]
+}
+
+# Part 6: Testing basic alias creation
+test interp-7.1 {testing basic alias creation} {
+ a alias foo in_master
+} foo
+test interp-7.2 {testing basic alias creation} {
+ a alias bar in_master a1 a2 a3
+} bar
+# Test 6.3 has been deleted.
+test interp-7.3 {testing basic alias creation} {
+ a alias foo
+} in_master
+test interp-7.4 {testing basic alias creation} {
+ a alias bar
+} {in_master a1 a2 a3}
+test interp-7.5 {testing basic alias creation} {
+ lsort [a aliases]
+} {bar foo}
+test interp-7.6 {testing basic aliases arg checking} -returnCodes error -body {
+ a aliases too many args
+} -result {wrong # args: should be "a aliases"}
+
+# Part 7: testing basic alias invocation
+test interp-8.1 {testing basic alias invocation} {
+ catch {interp create a}
+ a alias foo in_master
+ a eval foo s1 s2 s3
+} {seen in master: {s1 s2 s3}}
+test interp-8.2 {testing basic alias invocation} {
+ catch {interp create a}
+ a alias bar in_master a1 a2 a3
+ a eval bar s1 s2 s3
+} {seen in master: {a1 a2 a3 s1 s2 s3}}
+test interp-8.3 {testing basic alias invocation} -returnCodes error -body {
+ catch {interp create a}
+ a alias
+} -result {wrong # args: should be "a alias aliasName ?targetName? ?arg ...?"}
+
+# Part 8: Testing aliases for non-existent or hidden targets
+test interp-9.1 {testing aliases for non-existent targets} {
+ catch {interp create a}
+ a alias zop nonexistent-command-in-master
+ list [catch {a eval zop} msg] $msg
+} {1 {invalid command name "nonexistent-command-in-master"}}
+test interp-9.2 {testing aliases for non-existent targets} {
+ catch {interp create a}
+ a alias zop nonexistent-command-in-master
+ proc nonexistent-command-in-master {} {return i_exist!}
+ a eval zop
+} i_exist!
+test interp-9.3 {testing aliases for hidden commands} {
+ catch {interp create a}
+ a eval {proc p {} {return ENTER_A}}
+ interp alias {} p a p
+ set res {}
+ lappend res [list [catch p msg] $msg]
+ interp hide a p
+ lappend res [list [catch p msg] $msg]
+ rename p {}
+ interp delete a
+ set res
+ } {{0 ENTER_A} {1 {invalid command name "p"}}}
+test interp-9.4 {testing aliases and namespace commands} {
+ proc p {} {return GLOBAL}
+ namespace eval tst {
+ proc p {} {return NAMESPACE}
+ }
+ interp alias {} a {} p
+ set res [a]
+ lappend res [namespace eval tst a]
+ rename p {}
+ rename a {}
+ namespace delete tst
+ set res
+ } {GLOBAL GLOBAL}
+
+if {[info command nonexistent-command-in-master] != ""} {
+ rename nonexistent-command-in-master {}
+}
+
+# Part 9: Aliasing between interpreters
+test interp-10.1 {testing aliasing between interpreters} {
+ catch {interp delete a}
+ catch {interp delete b}
+ interp create a
+ interp create b
+ interp alias a a_alias b b_alias 1 2 3
+} a_alias
+test interp-10.2 {testing aliasing between interpreters} {
+ catch {interp delete a}
+ catch {interp delete b}
+ interp create a
+ interp create b
+ b eval {proc b_alias {args} {return [list got $args]}}
+ interp alias a a_alias b b_alias 1 2 3
+ a eval a_alias a b c
+} {got {1 2 3 a b c}}
+test interp-10.3 {testing aliasing between interpreters} {
+ catch {interp delete a}
+ catch {interp delete b}
+ interp create a
+ interp create b
+ interp alias a a_alias b b_alias 1 2 3
+ list [catch {a eval a_alias a b c} msg] $msg
+} {1 {invalid command name "b_alias"}}
+test interp-10.4 {testing aliasing between interpreters} {
+ catch {interp delete a}
+ interp create a
+ a alias a_alias puts
+ a aliases
+} a_alias
+test interp-10.5 {testing aliasing between interpreters} {
+ catch {interp delete a}
+ catch {interp delete b}
+ interp create a
+ interp create b
+ a alias a_alias puts
+ interp alias a a_del b b_del
+ interp delete b
+ a aliases
+} a_alias
+test interp-10.6 {testing aliasing between interpreters} {
+ catch {interp delete a}
+ catch {interp delete b}
+ interp create a
+ interp create b
+ interp alias a a_command b b_command a1 a2 a3
+ b alias b_command in_master b1 b2 b3
+ a eval a_command m1 m2 m3
+} {seen in master: {b1 b2 b3 a1 a2 a3 m1 m2 m3}}
+test interp-10.7 {testing aliases between interpreters} {
+ catch {interp delete a}
+ interp create a
+ interp alias "" foo a zoppo
+ a eval {proc zoppo {x} {list $x $x $x}}
+ set x [foo 33]
+ a eval {rename zoppo {}}
+ interp alias "" foo a {}
+ return $x
+} {33 33 33}
+
+# Part 10: Testing "interp target"
+test interp-11.1 {testing interp target} {
+ list [catch {interp target} msg] $msg
+} {1 {wrong # args: should be "interp target path alias"}}
+test interp-11.2 {testing interp target} {
+ list [catch {interp target nosuchinterpreter foo} msg] $msg
+} {1 {could not find interpreter "nosuchinterpreter"}}
+test interp-11.3 {testing interp target} {
+ catch {interp delete a}
+ interp create a
+ a alias boo no_command
+ interp target a boo
+} ""
+test interp-11.4 {testing interp target} {
+ catch {interp delete x1}
+ interp create x1
+ x1 eval interp create x2
+ x1 eval x2 eval interp create x3
+ catch {interp delete y1}
+ interp create y1
+ y1 eval interp create y2
+ y1 eval y2 eval interp create y3
+ interp alias {x1 x2 x3} xcommand {y1 y2 y3} ycommand
+ interp target {x1 x2 x3} xcommand
+} {y1 y2 y3}
+test interp-11.5 {testing interp target} {
+ catch {interp delete x1}
+ interp create x1
+ interp create {x1 x2}
+ interp create {x1 x2 x3}
+ catch {interp delete y1}
+ interp create y1
+ interp create {y1 y2}
+ interp create {y1 y2 y3}
+ interp alias {x1 x2 x3} xcommand {y1 y2 y3} ycommand
+ list [catch {x1 eval {interp target {x2 x3} xcommand}} msg] $msg
+} {1 {target interpreter for alias "xcommand" in path "x2 x3" is not my descendant}}
+test interp-11.6 {testing interp target} {
+ foreach a [interp aliases] {
+ rename $a {}
+ }
+ list [catch {interp target {} foo} msg] $msg
+} {1 {alias "foo" in path "" not found}}
+test interp-11.7 {testing interp target} {
+ catch {interp delete a}
+ interp create a
+ list [catch {interp target a foo} msg] $msg
+} {1 {alias "foo" in path "a" not found}}
+
+# Part 11: testing "interp issafe"
+test interp-12.1 {testing interp issafe} {
+ interp issafe
+} 0
+test interp-12.2 {testing interp issafe} {
+ catch {interp delete a}
+ interp create a
+ interp issafe a
+} 0
+test interp-12.3 {testing interp issafe} {
+ catch {interp delete a}
+ interp create a
+ interp create {a x3} -safe
+ interp issafe {a x3}
+} 1
+test interp-12.4 {testing interp issafe} {
+ catch {interp delete a}
+ interp create a
+ interp create {a x3} -safe
+ interp create {a x3 foo}
+ interp issafe {a x3 foo}
+} 1
+
+# Part 12: testing interpreter object command "issafe" sub-command
+test interp-13.1 {testing foo issafe} {
+ catch {interp delete a}
+ interp create a
+ a issafe
+} 0
+test interp-13.2 {testing foo issafe} {
+ catch {interp delete a}
+ interp create a
+ interp create {a x3} -safe
+ a eval x3 issafe
+} 1
+test interp-13.3 {testing foo issafe} {
+ catch {interp delete a}
+ interp create a
+ interp create {a x3} -safe
+ interp create {a x3 foo}
+ a eval x3 eval foo issafe
+} 1
+test interp-13.4 {testing issafe arg checking} {
+ catch {interp create a}
+ list [catch {a issafe too many args} msg] $msg
+} {1 {wrong # args: should be "a issafe"}}
+
+# part 14: testing interp aliases
+test interp-14.1 {testing interp aliases} {
+ interp aliases
+} ""
+test interp-14.2 {testing interp aliases} {
+ catch {interp delete a}
+ interp create a
+ a alias a1 puts
+ a alias a2 puts
+ a alias a3 puts
+ lsort [interp aliases a]
+} {a1 a2 a3}
+test interp-14.3 {testing interp aliases} {
+ catch {interp delete a}
+ interp create a
+ interp create {a x3}
+ interp alias {a x3} froboz "" puts
+ interp aliases {a x3}
+} froboz
+test interp-14.4 {testing interp alias - alias over master} {
+ # SF Bug 641195
+ catch {interp delete a}
+ interp create a
+ list [catch {interp alias "" a a eval} msg] $msg [info commands a]
+} {1 {cannot define or rename alias "a": interpreter deleted} {}}
+test interp-14.5 {testing interp-alias: wrong # args} -body {
+ proc setx x {set x}
+ interp alias {} a {} setx
+ catch {a 1 2}
+ set ::errorInfo
+} -cleanup {
+ rename setx {}
+ rename a {}
+} -result {wrong # args: should be "a x"
+ while executing
+"a 1 2"}
+test interp-14.6 {testing interp-alias: wrong # args} -setup {
+ proc setx x {set x}
+ catch {interp delete a}
+ interp create a
+} -body {
+ interp alias a a {} setx
+ catch {a eval a 1 2}
+ set ::errorInfo
+} -cleanup {
+ rename setx {}
+ interp delete a
+} -result {wrong # args: should be "a x"
+ invoked from within
+"a 1 2"
+ invoked from within
+"a eval a 1 2"}
+test interp-14.7 {testing interp-alias: wrong # args} -setup {
+ proc setx x {set x}
+ catch {interp delete a}
+ interp create a
+} -body {
+ interp alias a a {} setx
+ a eval {
+ catch {a 1 2}
+ set ::errorInfo
+ }
+} -cleanup {
+ rename setx {}
+ interp delete a
+} -result {wrong # args: should be "a x"
+ invoked from within
+"a 1 2"}
+test interp-14.8 {testing interp-alias: error messages} -body {
+ proc setx x {return -code error x}
+ interp alias {} a {} setx
+ catch {a 1}
+ set ::errorInfo
+} -cleanup {
+ rename setx {}
+ rename a {}
+} -result {x
+ while executing
+"a 1"}
+test interp-14.9 {testing interp-alias: error messages} -setup {
+ proc setx x {return -code error x}
+ catch {interp delete a}
+ interp create a
+} -body {
+ interp alias a a {} setx
+ catch {a eval a 1}
+ set ::errorInfo
+} -cleanup {
+ rename setx {}
+ interp delete a
+} -result {x
+ invoked from within
+"a 1"
+ invoked from within
+"a eval a 1"}
+test interp-14.10 {testing interp-alias: error messages} -setup {
+ proc setx x {return -code error x}
+ catch {interp delete a}
+ interp create a
+} -body {
+ interp alias a a {} setx
+ a eval {
+ catch {a 1}
+ set ::errorInfo
+ }
+} -cleanup {
+ rename setx {}
+ interp delete a
+} -result {x
+ invoked from within
+"a 1"}
+
+# part 15: testing file sharing
+test interp-15.1 {testing file sharing} {
+ catch {interp delete z}
+ interp create z
+ z eval close stdout
+ list [catch {z eval puts hello} msg] $msg
+} {1 {can not find channel named "stdout"}}
+test interp-15.2 {testing file sharing} -body {
+ catch {interp delete z}
+ interp create z
+ set f [open [makeFile {} file-15.2] w]
+ interp share "" $f z
+ z eval puts $f hello
+ z eval close $f
+ close $f
+} -cleanup {
+ removeFile file-15.2
+} -result ""
+test interp-15.3 {testing file sharing} {
+ catch {interp delete xsafe}
+ interp create xsafe -safe
+ list [catch {xsafe eval puts hello} msg] $msg
+} {1 {can not find channel named "stdout"}}
+test interp-15.4 {testing file sharing} -body {
+ catch {interp delete xsafe}
+ interp create xsafe -safe
+ set f [open [makeFile {} file-15.4] w]
+ interp share "" $f xsafe
+ xsafe eval puts $f hello
+ xsafe eval close $f
+ close $f
+} -cleanup {
+ removeFile file-15.4
+} -result ""
+test interp-15.5 {testing file sharing} {
+ catch {interp delete xsafe}
+ interp create xsafe -safe
+ interp share "" stdout xsafe
+ list [catch {xsafe eval gets stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test interp-15.6 {testing file sharing} -body {
+ catch {interp delete xsafe}
+ interp create xsafe -safe
+ set f [open [makeFile {} file-15.6] w]
+ interp share "" $f xsafe
+ set x [list [catch [list xsafe eval gets $f] msg] $msg]
+ xsafe eval close $f
+ close $f
+ string compare [string tolower $x] \
+ [list 1 [format "channel \"%s\" wasn't opened for reading" $f]]
+} -cleanup {
+ removeFile file-15.6
+} -result 0
+test interp-15.7 {testing file transferring} -body {
+ catch {interp delete xsafe}
+ interp create xsafe -safe
+ set f [open [makeFile {} file-15.7] w]
+ interp transfer "" $f xsafe
+ xsafe eval puts $f hello
+ xsafe eval close $f
+} -cleanup {
+ removeFile file-15.7
+} -result ""
+test interp-15.8 {testing file transferring} -body {
+ catch {interp delete xsafe}
+ interp create xsafe -safe
+ set f [open [makeFile {} file-15.8] w]
+ interp transfer "" $f xsafe
+ xsafe eval close $f
+ set x [list [catch {close $f} msg] $msg]
+ string compare [string tolower $x] \
+ [list 1 [format "can not find channel named \"%s\"" $f]]
+} -cleanup {
+ removeFile file-15.8
+} -result 0
+
+#
+# Torture tests for interpreter deletion order
+#
+proc kill {} {interp delete xxx}
+test interp-16.0 {testing deletion order} {
+ catch {interp delete xxx}
+ interp create xxx
+ xxx alias kill kill
+ list [catch {xxx eval kill} msg] $msg
+} {0 {}}
+test interp-16.1 {testing deletion order} {
+ catch {interp delete xxx}
+ interp create xxx
+ interp create {xxx yyy}
+ interp alias {xxx yyy} kill "" kill
+ list [catch {interp eval {xxx yyy} kill} msg] $msg
+} {0 {}}
+test interp-16.2 {testing deletion order} {
+ catch {interp delete xxx}
+ interp create xxx
+ interp create {xxx yyy}
+ interp alias {xxx yyy} kill "" kill
+ list [catch {xxx eval yyy eval kill} msg] $msg
+} {0 {}}
+test interp-16.3 {testing deletion order} {
+ catch {interp delete xxx}
+ interp create xxx
+ interp create ddd
+ xxx alias kill kill
+ interp alias ddd kill xxx kill
+ set x [ddd eval kill]
+ interp delete ddd
+ set x
+} ""
+test interp-16.4 {testing deletion order} {
+ catch {interp delete xxx}
+ interp create xxx
+ interp create {xxx yyy}
+ interp alias {xxx yyy} kill "" kill
+ interp create ddd
+ interp alias ddd kill {xxx yyy} kill
+ set x [ddd eval kill]
+ interp delete ddd
+ set x
+} ""
+test interp-16.5 {testing deletion order, bgerror} {
+ catch {interp delete xxx}
+ interp create xxx
+ xxx eval {proc bgerror {args} {exit}}
+ xxx alias exit kill xxx
+ proc kill {i} {interp delete $i}
+ xxx eval after 100 expr a + b
+ after 200
+ update
+ interp exists xxx
+} 0
+
+#
+# Alias loop prevention testing.
+#
+
+test interp-17.1 {alias loop prevention} {
+ list [catch {interp alias {} a {} a} msg] $msg
+} {1 {cannot define or rename alias "a": would create a loop}}
+test interp-17.2 {alias loop prevention} {
+ catch {interp delete x}
+ interp create x
+ x alias a loop
+ list [catch {interp alias {} loop x a} msg] $msg
+} {1 {cannot define or rename alias "loop": would create a loop}}
+test interp-17.3 {alias loop prevention} {
+ catch {interp delete x}
+ interp create x
+ interp alias x a x b
+ list [catch {interp alias x b x a} msg] $msg
+} {1 {cannot define or rename alias "b": would create a loop}}
+test interp-17.4 {alias loop prevention} {
+ catch {interp delete x}
+ interp create x
+ interp alias x b x a
+ list [catch {x eval rename b a} msg] $msg
+} {1 {cannot define or rename alias "a": would create a loop}}
+test interp-17.5 {alias loop prevention} {
+ catch {interp delete x}
+ interp create x
+ x alias z l1
+ interp alias {} l2 x z
+ list [catch {rename l2 l1} msg] $msg
+} {1 {cannot define or rename alias "l1": would create a loop}}
+test interp-17.6 {alias loop prevention} {
+ catch {interp delete x}
+ interp create x
+ interp alias x a x b
+ x eval rename a c
+ list [catch {x eval rename c b} msg] $msg
+} {1 {cannot define or rename alias "b": would create a loop}}
+
+#
+# Test robustness of Tcl_DeleteInterp when applied to a slave interpreter.
+# If there are bugs in the implementation these tests are likely to expose
+# the bugs as a core dump.
+#
+
+test interp-18.1 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+ list [catch {testinterpdelete} msg] $msg
+} {1 {wrong # args: should be "testinterpdelete path"}}
+test interp-18.2 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+ catch {interp delete a}
+ interp create a
+ testinterpdelete a
+} ""
+test interp-18.3 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+ catch {interp delete a}
+ interp create a
+ interp create {a b}
+ testinterpdelete {a b}
+} ""
+test interp-18.4 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+ catch {interp delete a}
+ interp create a
+ interp create {a b}
+ testinterpdelete a
+} ""
+test interp-18.5 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+ catch {interp delete a}
+ interp create a
+ interp create {a b}
+ interp alias {a b} dodel {} dodel
+ proc dodel {x} {testinterpdelete $x}
+ list [catch {interp eval {a b} {dodel {a b}}} msg] $msg
+} {0 {}}
+test interp-18.6 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+ catch {interp delete a}
+ interp create a
+ interp create {a b}
+ interp alias {a b} dodel {} dodel
+ proc dodel {x} {testinterpdelete $x}
+ list [catch {interp eval {a b} {dodel a}} msg] $msg
+} {0 {}}
+test interp-18.7 {eval in deleted interp} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ proc dodel {} {
+ delme
+ dosomething else
+ }
+ proc dosomething args {
+ puts "I should not have been called!!"
+ }
+ }
+ a alias delme dela
+ proc dela {} {interp delete a}
+ list [catch {a eval dodel} msg] $msg
+} {1 {attempt to call eval in deleted interpreter}}
+test interp-18.8 {eval in deleted interp} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ interp create b
+ b eval {
+ proc dodel {} {
+ dela
+ }
+ }
+ proc foo {} {
+ b eval dela
+ dosomething else
+ }
+ proc dosomething args {
+ puts "I should not have been called!!"
+ }
+ }
+ interp alias {a b} dela {} dela
+ proc dela {} {interp delete a}
+ list [catch {a eval foo} msg] $msg
+} {1 {attempt to call eval in deleted interpreter}}
+test interp-18.9 {eval in deleted interp, bug 495830} {
+ interp create tst
+ interp alias tst suicide {} interp delete tst
+ list [catch {tst eval {suicide; set a 5}} msg] $msg
+} {1 {attempt to call eval in deleted interpreter}}
+test interp-18.10 {eval in deleted interp, bug 495830} {
+ interp create tst
+ interp alias tst suicide {} interp delete tst
+ list [catch {tst eval {set set set; suicide; $set a 5}} msg] $msg
+} {1 {attempt to call eval in deleted interpreter}}
+
+# Test alias deletion
+
+test interp-19.1 {alias deletion} {
+ catch {interp delete a}
+ interp create a
+ interp alias a foo a bar
+ set s [interp alias a foo {}]
+ interp delete a
+ set s
+} {}
+test interp-19.2 {alias deletion} {
+ catch {interp delete a}
+ interp create a
+ catch {interp alias a foo {}} msg
+ interp delete a
+ set msg
+} {alias "foo" not found}
+test interp-19.3 {alias deletion} {
+ catch {interp delete a}
+ interp create a
+ interp alias a foo a bar
+ interp eval a {rename foo zop}
+ interp alias a foo a zop
+ catch {interp eval a foo} msg
+ interp delete a
+ set msg
+} {invalid command name "bar"}
+test interp-19.4 {alias deletion} {
+ catch {interp delete a}
+ interp create a
+ interp alias a foo a bar
+ interp eval a {rename foo zop}
+ catch {interp eval a foo} msg
+ interp delete a
+ set msg
+} {invalid command name "foo"}
+test interp-19.5 {alias deletion} {
+ catch {interp delete a}
+ interp create a
+ interp eval a {proc bar {} {return 1}}
+ interp alias a foo a bar
+ interp eval a {rename foo zop}
+ catch {interp eval a zop} msg
+ interp delete a
+ set msg
+} 1
+test interp-19.6 {alias deletion} {
+ catch {interp delete a}
+ interp create a
+ interp alias a foo a bar
+ interp eval a {rename foo zop}
+ interp alias a foo a zop
+ set s [interp aliases a]
+ interp delete a
+ set s
+} {::foo foo}
+test interp-19.7 {alias deletion, renaming} {
+ catch {interp delete a}
+ interp create a
+ interp alias a foo a bar
+ interp eval a rename foo blotz
+ interp alias a foo {}
+ set s [interp aliases a]
+ interp delete a
+ set s
+} {}
+test interp-19.8 {alias deletion, renaming} {
+ catch {interp delete a}
+ interp create a
+ interp alias a foo a bar
+ interp eval a rename foo blotz
+ set l ""
+ lappend l [interp aliases a]
+ interp alias a foo {}
+ lappend l [interp aliases a]
+ interp delete a
+ set l
+} {foo {}}
+test interp-19.9 {alias deletion, renaming} {
+ catch {interp delete a}
+ interp create a
+ interp alias a foo a bar
+ interp eval a rename foo blotz
+ interp eval a {proc foo {} {expr 34 * 34}}
+ interp alias a foo {}
+ set l [interp eval a foo]
+ interp delete a
+ set l
+} 1156
+
+test interp-20.1 {interp hide, interp expose and interp invokehidden} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ $a eval {proc foo {} {}}
+ $a hide foo
+ catch {$a eval foo something} msg
+ interp delete $a
+ set msg
+} {invalid command name "foo"}
+test interp-20.2 {interp hide, interp expose and interp invokehidden} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ $a hide list
+ set l ""
+ lappend l [catch {$a eval {list 1 2 3}} msg] $msg
+ $a expose list
+ lappend l [catch {$a eval {list 1 2 3}} msg] $msg
+ interp delete $a
+ set l
+} {1 {invalid command name "list"} 0 {1 2 3}}
+test interp-20.3 {interp hide, interp expose and interp invokehidden} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ $a hide list
+ set l ""
+ lappend l [catch { $a eval {list 1 2 3} } msg] $msg
+ lappend l [catch { $a invokehidden list 1 2 3 } msg] $msg
+ $a expose list
+ lappend l [catch { $a eval {list 1 2 3} } msg] $msg
+ interp delete $a
+ set l
+} {1 {invalid command name "list"} 0 {1 2 3} 0 {1 2 3}}
+test interp-20.4 {interp hide, interp expose and interp invokehidden -- passing {}} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ $a hide list
+ set l ""
+ lappend l [catch { $a eval {list 1 2 3} } msg] $msg
+ lappend l [catch { $a invokehidden list {"" 1 2 3} } msg] $msg
+ $a expose list
+ lappend l [catch { $a eval {list 1 2 3} } msg] $msg
+ interp delete $a
+ set l
+} {1 {invalid command name "list"} 0 {{"" 1 2 3}} 0 {1 2 3}}
+test interp-20.5 {interp hide, interp expose and interp invokehidden -- passing {}} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ $a hide list
+ set l ""
+ lappend l [catch { $a eval {list 1 2 3} } msg] $msg
+ lappend l [catch { $a invokehidden list {{} 1 2 3} } msg] $msg
+ $a expose list
+ lappend l [catch { $a eval {list 1 2 3} } msg] $msg
+ interp delete $a
+ set l
+} {1 {invalid command name "list"} 0 {{{} 1 2 3}} 0 {1 2 3}}
+test interp-20.6 {interp invokehidden -- eval args} {
+ set a [interp create]
+ $a hide list
+ set l ""
+ set z 45
+ lappend l [catch { $a invokehidden list $z 1 2 3 } msg] $msg
+ $a expose list
+ lappend l [catch { $a eval list $z 1 2 3 } msg] $msg
+ interp delete $a
+ set l
+} {0 {45 1 2 3} 0 {45 1 2 3}}
+test interp-20.7 {interp invokehidden vs variable eval} {
+ set a [interp create]
+ $a hide list
+ set z 45
+ set l [list [catch {$a invokehidden list {$z a b c}} msg] $msg]
+ interp delete $a
+ set l
+} {0 {{$z a b c}}}
+test interp-20.8 {interp invokehidden vs variable eval} {
+ set a [interp create]
+ $a hide list
+ $a eval set z 89
+ set z 45
+ set l [list [catch {$a invokehidden list {$z a b c}} msg] $msg]
+ interp delete $a
+ set l
+} {0 {{$z a b c}}}
+test interp-20.9 {interp invokehidden vs variable eval} {
+ set a [interp create]
+ $a hide list
+ $a eval set z 89
+ set z 45
+ set l ""
+ lappend l [catch {$a invokehidden list $z {$z a b c}} msg] $msg
+ interp delete $a
+ set l
+} {0 {45 {$z a b c}}}
+test interp-20.10 {interp hide, interp expose and interp invokehidden} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ $a eval {proc foo {} {}}
+ interp hide $a foo
+ catch {interp eval $a foo something} msg
+ interp delete $a
+ set msg
+} {invalid command name "foo"}
+test interp-20.11 {interp hide, interp expose and interp invokehidden} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ interp hide $a list
+ set l ""
+ lappend l [catch {interp eval $a {list 1 2 3}} msg] $msg
+ interp expose $a list
+ lappend l [catch {interp eval $a {list 1 2 3}} msg] $msg
+ interp delete $a
+ set l
+} {1 {invalid command name "list"} 0 {1 2 3}}
+test interp-20.12 {interp hide, interp expose and interp invokehidden} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ interp hide $a list
+ set l ""
+ lappend l [catch {interp eval $a {list 1 2 3} } msg] $msg
+ lappend l [catch {interp invokehidden $a list 1 2 3} msg] $msg
+ interp expose $a list
+ lappend l [catch {interp eval $a {list 1 2 3} } msg] $msg
+ interp delete $a
+ set l
+} {1 {invalid command name "list"} 0 {1 2 3} 0 {1 2 3}}
+test interp-20.13 {interp hide, interp expose, interp invokehidden -- passing {}} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ interp hide $a list
+ set l ""
+ lappend l [catch {interp eval $a {list 1 2 3} } msg] $msg
+ lappend l [catch {interp invokehidden $a list {"" 1 2 3}} msg] $msg
+ interp expose $a list
+ lappend l [catch {interp eval $a {list 1 2 3} } msg] $msg
+ interp delete $a
+ set l
+} {1 {invalid command name "list"} 0 {{"" 1 2 3}} 0 {1 2 3}}
+test interp-20.14 {interp hide, interp expose, interp invokehidden -- passing {}} {
+ set a [interp create]
+ $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+ interp hide $a list
+ set l ""
+ lappend l [catch {interp eval $a {list 1 2 3} } msg] $msg
+ lappend l [catch {interp invokehidden $a list {{} 1 2 3}} msg] $msg
+ interp expose $a list
+ lappend l [catch {$a eval {list 1 2 3} } msg] $msg
+ interp delete $a
+ set l
+} {1 {invalid command name "list"} 0 {{{} 1 2 3}} 0 {1 2 3}}
+test interp-20.15 {interp invokehidden -- eval args} {
+ catch {interp delete a}
+ interp create a
+ interp hide a list
+ set l ""
+ set z 45
+ lappend l [catch {interp invokehidden a list $z 1 2 3} msg]
+ lappend l $msg
+ a expose list
+ lappend l [catch {interp eval a list $z 1 2 3} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {45 1 2 3} 0 {45 1 2 3}}
+test interp-20.16 {interp invokehidden vs variable eval} {
+ catch {interp delete a}
+ interp create a
+ interp hide a list
+ set z 45
+ set l ""
+ lappend l [catch {interp invokehidden a list {$z a b c}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {{$z a b c}}}
+test interp-20.17 {interp invokehidden vs variable eval} {
+ catch {interp delete a}
+ interp create a
+ interp hide a list
+ a eval set z 89
+ set z 45
+ set l ""
+ lappend l [catch {interp invokehidden a list {$z a b c}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {{$z a b c}}}
+test interp-20.18 {interp invokehidden vs variable eval} {
+ catch {interp delete a}
+ interp create a
+ interp hide a list
+ a eval set z 89
+ set z 45
+ set l ""
+ lappend l [catch {interp invokehidden a list $z {$z a b c}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {45 {$z a b c}}}
+test interp-20.19 {interp invokehidden vs nested commands} {
+ catch {interp delete a}
+ interp create a
+ a hide list
+ set l [a invokehidden list {[list x y z] f g h} z]
+ interp delete a
+ set l
+} {{[list x y z] f g h} z}
+test interp-20.20 {interp invokehidden vs nested commands} {
+ catch {interp delete a}
+ interp create a
+ a hide list
+ set l [interp invokehidden a list {[list x y z] f g h} z]
+ interp delete a
+ set l
+} {{[list x y z] f g h} z}
+test interp-20.21 {interp hide vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [catch {a hide list} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {}}
+test interp-20.22 {interp hide vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [catch {interp hide a list} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {}}
+test interp-20.23 {interp hide vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [catch {a eval {interp hide {} list}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {1 {permission denied: safe interpreter cannot hide commands}}
+test interp-20.24 {interp hide vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ interp create {a b}
+ set l ""
+ lappend l [catch {a eval {interp hide b list}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {1 {permission denied: safe interpreter cannot hide commands}}
+test interp-20.25 {interp hide vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ interp create {a b}
+ set l ""
+ lappend l [catch {interp hide {a b} list} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {}}
+test interp-20.26 {interp expoose vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [catch {a hide list} msg]
+ lappend l $msg
+ lappend l [catch {a expose list} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {} 0 {}}
+test interp-20.27 {interp expose vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [catch {interp hide a list} msg]
+ lappend l $msg
+ lappend l [catch {interp expose a list} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {} 0 {}}
+test interp-20.28 {interp expose vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [catch {a hide list} msg]
+ lappend l $msg
+ lappend l [catch {a eval {interp expose {} list}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {} 1 {permission denied: safe interpreter cannot expose commands}}
+test interp-20.29 {interp expose vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [catch {interp hide a list} msg]
+ lappend l $msg
+ lappend l [catch {a eval {interp expose {} list}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {} 1 {permission denied: safe interpreter cannot expose commands}}
+test interp-20.30 {interp expose vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ interp create {a b}
+ set l ""
+ lappend l [catch {interp hide {a b} list} msg]
+ lappend l $msg
+ lappend l [catch {a eval {interp expose b list}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {} 1 {permission denied: safe interpreter cannot expose commands}}
+test interp-20.31 {interp expose vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ interp create {a b}
+ set l ""
+ lappend l [catch {interp hide {a b} list} msg]
+ lappend l $msg
+ lappend l [catch {interp expose {a b} list} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {0 {} 0 {}}
+test interp-20.32 {interp invokehidden vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ interp hide a list
+ set l ""
+ lappend l [catch {a eval {interp invokehidden {} list a b c}} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {1 {not allowed to invoke hidden commands from safe interpreter}}
+test interp-20.33 {interp invokehidden vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ interp hide a list
+ set l ""
+ lappend l [catch {a eval {interp invokehidden {} list a b c}} msg]
+ lappend l $msg
+ lappend l [catch {a invokehidden list a b c} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {1 {not allowed to invoke hidden commands from safe interpreter}\
+0 {a b c}}
+test interp-20.34 {interp invokehidden vs safety} {
+ catch {interp delete a}
+ interp create a -safe
+ interp create {a b}
+ interp hide {a b} list
+ set l ""
+ lappend l [catch {a eval {interp invokehidden b list a b c}} msg]
+ lappend l $msg
+ lappend l [catch {interp invokehidden {a b} list a b c} msg]
+ lappend l $msg
+ interp delete a
+ set l
+} {1 {not allowed to invoke hidden commands from safe interpreter}\
+0 {a b c}}
+test interp-20.35 {invokehidden at local level} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ proc p1 {} {
+ set z 90
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a h1
+ }
+ set r [interp eval a p1]
+ interp delete a
+ set r
+} 91
+test interp-20.36 {invokehidden at local level} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ set z 90
+ proc p1 {} {
+ global z
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a h1
+ }
+ set r [interp eval a p1]
+ interp delete a
+ set r
+} 91
+test interp-20.37 {invokehidden at local level} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ proc p1 {} {
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a h1
+ }
+ set r [interp eval a p1]
+ interp delete a
+ set r
+} 91
+test interp-20.38 {invokehidden at global level} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ proc p1 {} {
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a -global h1
+ }
+ set r [catch {interp eval a p1} msg]
+ interp delete a
+ list $r $msg
+} {1 {can't read "z": no such variable}}
+test interp-20.39 {invokehidden at global level} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ proc p1 {} {
+ global z
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a -global h1
+ }
+ set r [catch {interp eval a p1} msg]
+ interp delete a
+ list $r $msg
+} {0 91}
+test interp-20.40 {safe, invokehidden at local level} {
+ catch {interp delete a}
+ interp create a -safe
+ a eval {
+ proc p1 {} {
+ set z 90
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a h1
+ }
+ set r [interp eval a p1]
+ interp delete a
+ set r
+} 91
+test interp-20.41 {safe, invokehidden at local level} {
+ catch {interp delete a}
+ interp create a -safe
+ a eval {
+ set z 90
+ proc p1 {} {
+ global z
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a h1
+ }
+ set r [interp eval a p1]
+ interp delete a
+ set r
+} 91
+test interp-20.42 {safe, invokehidden at local level} {
+ catch {interp delete a}
+ interp create a -safe
+ a eval {
+ proc p1 {} {
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a h1
+ }
+ set r [interp eval a p1]
+ interp delete a
+ set r
+} 91
+test interp-20.43 {invokehidden at global level} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ proc p1 {} {
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a -global h1
+ }
+ set r [catch {interp eval a p1} msg]
+ interp delete a
+ list $r $msg
+} {1 {can't read "z": no such variable}}
+test interp-20.44 {invokehidden at global level} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ proc p1 {} {
+ global z
+ a1
+ set z
+ }
+ proc h1 {} {
+ upvar z z
+ set z 91
+ }
+ }
+ a hide h1
+ a alias a1 a1
+ proc a1 {} {
+ interp invokehidden a -global h1
+ }
+ set r [catch {interp eval a p1} msg]
+ interp delete a
+ list $r $msg
+} {0 91}
+test interp-20.45 {interp hide vs namespaces} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ namespace eval foo {}
+ proc foo::x {} {}
+ }
+ set l [list [catch {interp hide a foo::x} msg] $msg]
+ interp delete a
+ set l
+} {1 {cannot use namespace qualifiers in hidden command token (rename)}}
+test interp-20.46 {interp hide vs namespaces} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ namespace eval foo {}
+ proc foo::x {} {}
+ }
+ set l [list [catch {interp hide a foo::x x} msg] $msg]
+ interp delete a
+ set l
+} {1 {can only hide global namespace commands (use rename then hide)}}
+test interp-20.47 {interp hide vs namespaces} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ proc x {} {}
+ }
+ set l [list [catch {interp hide a x foo::x} msg] $msg]
+ interp delete a
+ set l
+} {1 {cannot use namespace qualifiers in hidden command token (rename)}}
+test interp-20.48 {interp hide vs namespaces} {
+ catch {interp delete a}
+ interp create a
+ a eval {
+ namespace eval foo {}
+ proc foo::x {} {}
+ }
+ set l [list [catch {interp hide a foo::x bar::x} msg] $msg]
+ interp delete a
+ set l
+} {1 {cannot use namespace qualifiers in hidden command token (rename)}}
+test interp-20.49 {interp invokehidden -namespace} -setup {
+ set script [makeFile {
+ set x [namespace current]
+ } script]
+ interp create -safe slave
+} -body {
+ slave invokehidden -namespace ::foo source $script
+ slave eval {set ::foo::x}
+} -cleanup {
+ interp delete slave
+ removeFile script
+} -result ::foo
+test interp-20.50 {Bug 2486550} -setup {
+ interp create slave
+} -body {
+ slave hide coroutine
+ slave invokehidden coroutine
+} -cleanup {
+ interp delete slave
+} -returnCodes error -match glob -result *
+
+test interp-21.1 {interp hidden} {
+ interp hidden {}
+} ""
+test interp-21.2 {interp hidden} {
+ interp hidden
+} ""
+test interp-21.3 {interp hidden vs interp hide, interp expose} -setup {
+ set l ""
+} -body {
+ lappend l [interp hidden]
+ interp hide {} pwd
+ lappend l [interp hidden]
+ interp expose {} pwd
+ lappend l [interp hidden]
+} -result {{} pwd {}}
+test interp-21.4 {interp hidden} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a
+ interp hidden a
+} -cleanup {
+ interp delete a
+} -result ""
+test interp-21.5 {interp hidden} -setup {
+ catch {interp delete a}
+} -body {
+ interp create -safe a
+ lsort [interp hidden a]
+} -cleanup {
+ interp delete a
+} -result $hidden_cmds
+test interp-21.6 {interp hidden vs interp hide, interp expose} -setup {
+ catch {interp delete a}
+ set l ""
+} -body {
+ interp create a
+ lappend l [interp hidden a]
+ interp hide a pwd
+ lappend l [interp hidden a]
+ interp expose a pwd
+ lappend l [interp hidden a]
+} -cleanup {
+ interp delete a
+} -result {{} pwd {}}
+test interp-21.7 {interp hidden} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a
+ a hidden
+} -cleanup {
+ interp delete a
+} -result ""
+test interp-21.8 {interp hidden} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a -safe
+ lsort [a hidden]
+} -cleanup {
+ interp delete a
+} -result $hidden_cmds
+test interp-21.9 {interp hidden vs interp hide, interp expose} -setup {
+ catch {interp delete a}
+ set l ""
+} -body {
+ interp create a
+ lappend l [a hidden]
+ a hide pwd
+ lappend l [a hidden]
+ a expose pwd
+ lappend l [a hidden]
+} -cleanup {
+ interp delete a
+} -result {{} pwd {}}
+
+test interp-22.1 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a
+ set l ""
+ lappend l [a issafe]
+ lappend l [a marktrusted]
+ lappend l [a issafe]
+ interp delete a
+ set l
+} {0 {} 0}
+test interp-22.2 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a
+ set l ""
+ lappend l [interp issafe a]
+ lappend l [interp marktrusted a]
+ lappend l [interp issafe a]
+ interp delete a
+ set l
+} {0 {} 0}
+test interp-22.3 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [a issafe]
+ lappend l [a marktrusted]
+ lappend l [a issafe]
+ interp delete a
+ set l
+} {1 {} 0}
+test interp-22.4 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [interp issafe a]
+ lappend l [interp marktrusted a]
+ lappend l [interp issafe a]
+ interp delete a
+ set l
+} {1 {} 0}
+test interp-22.5 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a -safe
+ interp create {a b}
+ catch {a eval {interp marktrusted b}} msg
+ interp delete a
+ set msg
+} {permission denied: safe interpreter cannot mark trusted}
+test interp-22.6 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a -safe
+ interp create {a b}
+ catch {a eval {b marktrusted}} msg
+ interp delete a
+ set msg
+} {permission denied: safe interpreter cannot mark trusted}
+test interp-22.7 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [interp issafe a]
+ interp marktrusted a
+ interp create {a b}
+ lappend l [interp issafe a]
+ lappend l [interp issafe {a b}]
+ interp delete a
+ set l
+} {1 0 0}
+test interp-22.8 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [interp issafe a]
+ interp create {a b}
+ lappend l [interp issafe {a b}]
+ interp marktrusted a
+ interp create {a c}
+ lappend l [interp issafe a]
+ lappend l [interp issafe {a c}]
+ interp delete a
+ set l
+} {1 1 0 0}
+test interp-22.9 {testing interp marktrusted} {
+ catch {interp delete a}
+ interp create a -safe
+ set l ""
+ lappend l [interp issafe a]
+ interp create {a b}
+ lappend l [interp issafe {a b}]
+ interp marktrusted {a b}
+ lappend l [interp issafe a]
+ lappend l [interp issafe {a b}]
+ interp create {a b c}
+ lappend l [interp issafe {a b c}]
+ interp delete a
+ set l
+} {1 1 1 0 0}
+
+test interp-23.1 {testing hiding vs aliases: unsafe interp} -setup {
+ catch {interp delete a}
+ set l ""
+} -body {
+ interp create a
+ lappend l [interp hidden a]
+ a alias bar bar
+ lappend l [interp aliases a] [interp hidden a]
+ a hide bar
+ lappend l [interp aliases a] [interp hidden a]
+ a alias bar {}
+ lappend l [interp aliases a] [interp hidden a]
+} -cleanup {
+ interp delete a
+} -result {{} bar {} bar bar {} {}}
+test interp-23.2 {testing hiding vs aliases: safe interp} -setup {
+ catch {interp delete a}
+ set l ""
+} -constraints {unixOrPc} -body {
+ interp create a -safe
+ lappend l [lsort [interp hidden a]]
+ a alias bar bar
+ lappend l [lsort [interp aliases a]] [lsort [interp hidden a]]
+ a hide bar
+ lappend l [lsort [interp aliases a]] [lsort [interp hidden a]]
+ a alias bar {}
+ lappend l [lsort [interp aliases a]] [lsort [interp hidden a]]
+} -cleanup {
+ interp delete a
+} -result [list $hidden_cmds {::tcl::mathfunc::max ::tcl::mathfunc::min bar clock} $hidden_cmds {::tcl::mathfunc::max ::tcl::mathfunc::min bar clock} [lsort [concat $hidden_cmds bar]] {::tcl::mathfunc::max ::tcl::mathfunc::min clock} $hidden_cmds]
+
+test interp-24.1 {result resetting on error} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a
+ interp alias a foo {} apply {args {error $args}}
+ interp eval a {
+ lappend l [catch {foo 1 2 3} msg] $msg
+ lappend l [catch {foo 3 4 5} msg] $msg
+ }
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.2 {result resetting on error} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a -safe
+ interp alias a foo {} apply {args {error $args}}
+ interp eval a {
+ lappend l [catch {foo 1 2 3} msg] $msg
+ lappend l [catch {foo 3 4 5} msg] $msg
+ }
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.3 {result resetting on error} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a
+ interp create {a b}
+ interp eval a {
+ proc foo args {error $args}
+ }
+ interp alias {a b} foo a foo
+ interp eval {a b} {
+ lappend l [catch {foo 1 2 3} msg] $msg
+ lappend l [catch {foo 3 4 5} msg] $msg
+ }
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.4 {result resetting on error} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a -safe
+ interp create {a b}
+ interp eval a {
+ proc foo args {error $args}
+ }
+ interp alias {a b} foo a foo
+ interp eval {a b} {
+ lappend l [catch {foo 1 2 3} msg]
+ lappend l $msg
+ lappend l [catch {foo 3 4 5} msg]
+ lappend l $msg
+ }
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.5 {result resetting on error} -setup {
+ catch {interp delete a}
+ catch {interp delete b}
+} -body {
+ interp create a
+ interp create b
+ interp eval a {
+ proc foo args {error $args}
+ }
+ interp alias b foo a foo
+ interp eval b {
+ lappend l [catch {foo 1 2 3} msg] $msg
+ lappend l [catch {foo 3 4 5} msg] $msg
+ }
+} -cleanup {
+ interp delete a
+ interp delete b
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.6 {result resetting on error} -setup {
+ catch {interp delete a}
+ catch {interp delete b}
+} -body {
+ interp create a -safe
+ interp create b -safe
+ interp eval a {
+ proc foo args {error $args}
+ }
+ interp alias b foo a foo
+ interp eval b {
+ lappend l [catch {foo 1 2 3} msg] $msg
+ lappend l [catch {foo 3 4 5} msg] $msg
+ }
+} -cleanup {
+ interp delete a
+ interp delete b
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.7 {result resetting on error} -setup {
+ catch {interp delete a}
+ set l {}
+} -body {
+ interp create a
+ interp eval a {
+ proc foo args {error $args}
+ }
+ lappend l [catch {interp eval a foo 1 2 3} msg] $msg
+ lappend l [catch {interp eval a foo 3 4 5} msg] $msg
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.8 {result resetting on error} -setup {
+ catch {interp delete a}
+ set l {}
+} -body {
+ interp create a -safe
+ interp eval a {
+ proc foo args {error $args}
+ }
+ lappend l [catch {interp eval a foo 1 2 3} msg] $msg
+ lappend l [catch {interp eval a foo 3 4 5} msg] $msg
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.9 {result resetting on error} -setup {
+ catch {interp delete a}
+ set l {}
+} -body {
+ interp create a
+ interp create {a b}
+ interp eval {a b} {
+ proc foo args {error $args}
+ }
+ interp eval a {
+ proc foo args {
+ eval interp eval b foo $args
+ }
+ }
+ lappend l [catch {interp eval a foo 1 2 3} msg] $msg
+ lappend l [catch {interp eval a foo 3 4 5} msg] $msg
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.10 {result resetting on error} -setup {
+ catch {interp delete a}
+ set l {}
+} -body {
+ interp create a -safe
+ interp create {a b}
+ interp eval {a b} {
+ proc foo args {error $args}
+ }
+ interp eval a {
+ proc foo args {
+ eval interp eval b foo $args
+ }
+ }
+ lappend l [catch {interp eval a foo 1 2 3} msg] $msg
+ lappend l [catch {interp eval a foo 3 4 5} msg] $msg
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.11 {result resetting on error} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a
+ interp create {a b}
+ interp eval {a b} {
+ proc foo args {error $args}
+ }
+ interp eval a {
+ proc foo args {
+ lappend l [catch {eval interp eval b foo $args} msg] $msg
+ lappend l [catch {eval interp eval b foo $args} msg] $msg
+ }
+ }
+ interp eval a foo 1 2 3
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {1 2 3}}
+test interp-24.12 {result resetting on error} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a -safe
+ interp create {a b}
+ interp eval {a b} {
+ proc foo args {error $args}
+ }
+ interp eval a {
+ proc foo args {
+ lappend l [catch {eval interp eval b foo $args} msg] $msg
+ lappend l [catch {eval interp eval b foo $args} msg] $msg
+ }
+ }
+ interp eval a foo 1 2 3
+} -cleanup {
+ interp delete a
+} -result {1 {1 2 3} 1 {1 2 3}}
+
+test interp-25.1 {testing aliasing of string commands} -setup {
+ catch {interp delete a}
+} -body {
+ interp create a
+ a alias exec foo ;# Relies on exec being a string command!
+ interp delete a
+} -result ""
+
+#
+# Interps result transmission
+#
+
+test interp-26.1 {result code transmission : interp eval direct} {
+ # Test that all the possibles error codes from Tcl get passed up
+ # from the slave interp's context to the master, even though the
+ # slave nominally thinks the command is running at the root level.
+ catch {interp delete a}
+ interp create a
+ set res {}
+ # use a for so if a return -code break 'escapes' we would notice
+ for {set code -1} {$code<=5} {incr code} {
+ lappend res [catch {interp eval a return -code $code} msg]
+ }
+ interp delete a
+ set res
+} {-1 0 1 2 3 4 5}
+test interp-26.2 {result code transmission : interp eval indirect} {
+ # retcode == 2 == return is special
+ catch {interp delete a}
+ interp create a
+ interp eval a {proc retcode {code} {return -code $code ret$code}}
+ set res {}
+ # use a for so if a return -code break 'escapes' we would notice
+ for {set code -1} {$code<=5} {incr code} {
+ lappend res [catch {interp eval a retcode $code} msg] $msg
+ }
+ interp delete a
+ set res
+} {-1 ret-1 0 ret0 1 ret1 0 ret2 3 ret3 4 ret4 5 ret5}
+test interp-26.3 {result code transmission : aliases} {
+ # Test that all the possibles error codes from Tcl get passed up from the
+ # slave interp's context to the master, even though the slave nominally
+ # thinks the command is running at the root level.
+ catch {interp delete a}
+ interp create a
+ set res {}
+ proc MyTestAlias {code} {
+ return -code $code ret$code
+ }
+ interp alias a Test {} MyTestAlias
+ for {set code -1} {$code<=5} {incr code} {
+ lappend res [interp eval a [list catch [list Test $code] msg]]
+ }
+ interp delete a
+ set res
+} {-1 0 1 2 3 4 5}
+test interp-26.4 {result code transmission: invoke hidden direct--bug 1637} \
+ {knownBug} {
+ # The known bug is that code 2 is returned, not the -code argument
+ catch {interp delete a}
+ interp create a
+ set res {}
+ interp hide a return
+ for {set code -1} {$code<=5} {incr code} {
+ lappend res [catch {interp invokehidden a return -code $code ret$code}]
+ }
+ interp delete a
+ set res
+} {-1 0 1 2 3 4 5}
+test interp-26.5 {result code transmission: invoke hidden indirect--bug 1637} -setup {
+ catch {interp delete a}
+ interp create a
+} -body {
+ # The known bug is that the break and continue should raise errors that
+ # they are used outside a loop.
+ set res {}
+ interp eval a {proc retcode {code} {return -code $code ret$code}}
+ interp hide a retcode
+ for {set code -1} {$code<=5} {incr code} {
+ lappend res [catch {interp invokehidden a retcode $code} msg] $msg
+ }
+ return $res
+} -cleanup {
+ interp delete a
+} -result {-1 ret-1 0 ret0 1 ret1 2 ret2 3 ret3 4 ret4 5 ret5}
+test interp-26.6 {result code transmission: all combined--bug 1637} -setup {
+ set interp [interp create]
+} -constraints knownBug -body {
+ # Test that all the possibles error codes from Tcl get passed in both
+ # directions. This doesn't work.
+ proc MyTestAlias {interp args} {
+ global aliasTrace
+ lappend aliasTrace $args
+ interp invokehidden $interp {*}$args
+ }
+ foreach c {return} {
+ interp hide $interp $c
+ interp alias $interp $c {} MyTestAlias $interp $c
+ }
+ interp eval $interp {proc ret {code} {return -code $code ret$code}}
+ set res {}
+ set aliasTrace {}
+ for {set code -1} {$code<=5} {incr code} {
+ lappend res [catch {interp eval $interp ret $code} msg] $msg
+ }
+ return $res
+} -cleanup {
+ interp delete $interp
+} -result {-1 ret-1 0 ret0 1 ret1 0 ret2 3 ret3 4 ret4 5 ret5}
+# Some tests might need to be added to check for difference between toplevel
+# and non-toplevel evals.
+# End of return code transmission section
+test interp-26.7 {errorInfo transmission: regular interps} -setup {
+ set interp [interp create]
+} -body {
+ proc MyError {secret} {
+ return -code error "msg"
+ }
+ proc MyTestAlias {interp args} {
+ MyError "some secret"
+ }
+ interp alias $interp test {} MyTestAlias $interp
+ interp eval $interp {catch test;set ::errorInfo}
+} -cleanup {
+ interp delete $interp
+} -result {msg
+ while executing
+"MyError "some secret""
+ (procedure "MyTestAlias" line 2)
+ invoked from within
+"test"}
+test interp-26.8 {errorInfo transmission: safe interps--bug 1637} -setup {
+ set interp [interp create -safe]
+} -constraints knownBug -body {
+ # this test fails because the errorInfo is fully transmitted whether the
+ # interp is safe or not. The errorInfo should never report data from the
+ # master interpreter because it could contain sensitive information.
+ proc MyError {secret} {
+ return -code error "msg"
+ }
+ proc MyTestAlias {interp args} {
+ MyError "some secret"
+ }
+ interp alias $interp test {} MyTestAlias $interp
+ interp eval $interp {catch test;set ::errorInfo}
+} -cleanup {
+ interp delete $interp
+} -result {msg
+ while executing
+"test"}
+
+# Interps & Namespaces
+test interp-27.1 {interp aliases & namespaces} -setup {
+ set i [interp create]
+} -body {
+ set aliasTrace {}
+ proc tstAlias {args} {
+ global aliasTrace
+ lappend aliasTrace [list [namespace current] $args]
+ }
+ $i alias foo::bar tstAlias foo::bar
+ $i eval foo::bar test
+ return $aliasTrace
+} -cleanup {
+ interp delete $i
+} -result {{:: {foo::bar test}}}
+test interp-27.2 {interp aliases & namespaces} -setup {
+ set i [interp create]
+} -body {
+ set aliasTrace {}
+ proc tstAlias {args} {
+ global aliasTrace
+ lappend aliasTrace [list [namespace current] $args]
+ }
+ $i alias foo::bar tstAlias foo::bar
+ $i eval namespace eval foo {bar test}
+ return $aliasTrace
+} -cleanup {
+ interp delete $i
+} -result {{:: {foo::bar test}}}
+test interp-27.3 {interp aliases & namespaces} -setup {
+ set i [interp create]
+} -body {
+ set aliasTrace {}
+ proc tstAlias {args} {
+ global aliasTrace
+ lappend aliasTrace [list [namespace current] $args]
+ }
+ interp eval $i {namespace eval foo {proc bar {} {error "bar called"}}}
+ interp alias $i foo::bar {} tstAlias foo::bar
+ interp eval $i {namespace eval foo {bar test}}
+ return $aliasTrace
+} -cleanup {
+ interp delete $i
+} -result {{:: {foo::bar test}}}
+test interp-27.4 {interp aliases & namespaces} -setup {
+ set i [interp create]
+} -body {
+ namespace eval foo2 {
+ variable aliasTrace {}
+ proc bar {args} {
+ variable aliasTrace
+ lappend aliasTrace [list [namespace current] $args]
+ }
+ }
+ $i alias foo::bar foo2::bar foo::bar
+ $i eval namespace eval foo {bar test}
+ return $foo2::aliasTrace
+} -cleanup {
+ namespace delete foo2
+ interp delete $i
+} -result {{::foo2 {foo::bar test}}}
+test interp-27.5 {interp hidden & namespaces} -setup {
+ set i [interp create]
+} -constraints knownBug -body {
+ interp eval $i {
+ namespace eval foo {
+ proc bar {args} {
+ return "bar called ([namespace current]) ($args)"
+ }
+ }
+ }
+ set res [list [interp eval $i {namespace eval foo {bar test1}}]]
+ interp hide $i foo::bar
+ lappend res [list [catch {interp eval $i {namespace eval foo {bar test2}}} msg] $msg]
+} -cleanup {
+ interp delete $i
+} -result {{bar called (::foo) (test1)} {1 {invalid command name "bar"}}}
+test interp-27.6 {interp hidden & aliases & namespaces} -setup {
+ set i [interp create]
+} -constraints knownBug -body {
+ set v root-master
+ namespace eval foo {
+ variable v foo-master
+ proc bar {interp args} {
+ variable v
+ list "master bar called ($v) ([namespace current]) ($args)"\
+ [interp invokehidden $interp foo::bar $args]
+ }
+ }
+ interp eval $i {
+ namespace eval foo {
+ namespace export *
+ variable v foo-slave
+ proc bar {args} {
+ variable v
+ return "slave bar called ($v) ([namespace current]) ($args)"
+ }
+ }
+ }
+ set res [list [interp eval $i {namespace eval foo {bar test1}}]]
+ $i hide foo::bar
+ $i alias foo::bar foo::bar $i
+ set res [concat $res [interp eval $i {
+ set v root-slave
+ namespace eval test {
+ variable v foo-test
+ namespace import ::foo::*
+ bar test2
+ }
+ }]]
+} -cleanup {
+ namespace delete foo
+ interp delete $i
+} -result {{slave bar called (foo-slave) (::foo) (test1)} {master bar called (foo-master) (::foo) (test2)} {slave bar called (foo-slave) (::foo) (test2)}}
+test interp-27.7 {interp hidden & aliases & imports & namespaces} -setup {
+ set i [interp create]
+} -constraints knownBug -body {
+ set v root-master
+ namespace eval mfoo {
+ variable v foo-master
+ proc bar {interp args} {
+ variable v
+ list "master bar called ($v) ([namespace current]) ($args)"\
+ [interp invokehidden $interp test::bar $args]
+ }
+ }
+ interp eval $i {
+ namespace eval foo {
+ namespace export *
+ variable v foo-slave
+ proc bar {args} {
+ variable v
+ return "slave bar called ($v) ([info level 0]) ([uplevel namespace current]) ([namespace current]) ($args)"
+ }
+ }
+ set v root-slave
+ namespace eval test {
+ variable v foo-test
+ namespace import ::foo::*
+ }
+ }
+ set res [list [interp eval $i {namespace eval test {bar test1}}]]
+ $i hide test::bar
+ $i alias test::bar mfoo::bar $i
+ set res [concat $res [interp eval $i {test::bar test2}]]
+} -cleanup {
+ namespace delete mfoo
+ interp delete $i
+} -result {{slave bar called (foo-slave) (bar test1) (::tcltest) (::foo) (test1)} {master bar called (foo-master) (::mfoo) (test2)} {slave bar called (foo-slave) (test::bar test2) (::) (::foo) (test2)}}
+test interp-27.8 {hiding, namespaces and integrity} knownBug {
+ namespace eval foo {
+ variable v 3
+ proc bar {} {variable v; set v}
+ # next command would currently generate an unknown command "bar" error.
+ interp hide {} bar
+ }
+ namespace delete foo
+ list [catch {interp invokehidden {} foo::bar} msg] $msg
+} {1 {invalid hidden command name "foo"}}
+
+test interp-28.1 {getting fooled by slave's namespace ?} -setup {
+ set i [interp create -safe]
+ proc master {interp args} {interp hide $interp list}
+} -body {
+ $i alias master master $i
+ set r [interp eval $i {
+ namespace eval foo {
+ proc list {args} {
+ return "dummy foo::list"
+ }
+ master
+ }
+ info commands list
+ }]
+} -cleanup {
+ rename master {}
+ interp delete $i
+} -result {}
+test interp-28.2 {master's nsName cache should not cross} -setup {
+ set i [interp create]
+ $i eval {proc filter lst {lsearch -all -inline -not $lst "::tcl"}}
+} -body {
+ $i eval {
+ set x {namespace children ::}
+ set y [list namespace children ::]
+ namespace delete {*}[filter [{*}$y]]
+ set j [interp create]
+ $j alias filter filter
+ $j eval {namespace delete {*}[filter [namespace children ::]]}
+ namespace eval foo {}
+ list [filter [eval $x]] [filter [eval $y]] [filter [$j eval $x]] [filter [$j eval $y]]
+ }
+} -cleanup {
+ interp delete $i
+} -result {::foo ::foo {} {}}
+
+# Part 29: recursion limit
+# 29.1.* Argument checking
+# 29.2.* Reading and setting the recursion limit
+# 29.3.* Does the recursion limit work?
+# 29.4.* Recursion limit inheritance by sub-interpreters
+# 29.5.* Confirming the recursionlimit command does not affect the parent
+# 29.6.* Safe interpreter restriction
+
+test interp-29.1.1 {interp recursionlimit argument checking} {
+ list [catch {interp recursionlimit} msg] $msg
+} {1 {wrong # args: should be "interp recursionlimit path ?newlimit?"}}
+test interp-29.1.2 {interp recursionlimit argument checking} {
+ list [catch {interp recursionlimit foo bar} msg] $msg
+} {1 {could not find interpreter "foo"}}
+test interp-29.1.3 {interp recursionlimit argument checking} {
+ list [catch {interp recursionlimit foo bar baz} msg] $msg
+} {1 {wrong # args: should be "interp recursionlimit path ?newlimit?"}}
+test interp-29.1.4 {interp recursionlimit argument checking} {
+ interp create moo
+ set result [catch {interp recursionlimit moo bar} msg]
+ interp delete moo
+ list $result $msg
+} {1 {expected integer but got "bar"}}
+test interp-29.1.5 {interp recursionlimit argument checking} {
+ interp create moo
+ set result [catch {interp recursionlimit moo 0} msg]
+ interp delete moo
+ list $result $msg
+} {1 {recursion limit must be > 0}}
+test interp-29.1.6 {interp recursionlimit argument checking} {
+ interp create moo
+ set result [catch {interp recursionlimit moo -1} msg]
+ interp delete moo
+ list $result $msg
+} {1 {recursion limit must be > 0}}
+test interp-29.1.7 {interp recursionlimit argument checking} {
+ interp create moo
+ set result [catch {interp recursionlimit moo [expr {wide(1)<<32}]} msg]
+ interp delete moo
+ list $result [string range $msg 0 35]
+} {1 {integer value too large to represent}}
+test interp-29.1.8 {slave recursionlimit argument checking} {
+ interp create moo
+ set result [catch {moo recursionlimit foo bar} msg]
+ interp delete moo
+ list $result $msg
+} {1 {wrong # args: should be "moo recursionlimit ?newlimit?"}}
+test interp-29.1.9 {slave recursionlimit argument checking} {
+ interp create moo
+ set result [catch {moo recursionlimit foo} msg]
+ interp delete moo
+ list $result $msg
+} {1 {expected integer but got "foo"}}
+test interp-29.1.10 {slave recursionlimit argument checking} {
+ interp create moo
+ set result [catch {moo recursionlimit 0} msg]
+ interp delete moo
+ list $result $msg
+} {1 {recursion limit must be > 0}}
+test interp-29.1.11 {slave recursionlimit argument checking} {
+ interp create moo
+ set result [catch {moo recursionlimit -1} msg]
+ interp delete moo
+ list $result $msg
+} {1 {recursion limit must be > 0}}
+test interp-29.1.12 {slave recursionlimit argument checking} {
+ interp create moo
+ set result [catch {moo recursionlimit [expr {wide(1)<<32}]} msg]
+ interp delete moo
+ list $result [string range $msg 0 35]
+} {1 {integer value too large to represent}}
+test interp-29.2.1 {query recursion limit} {
+ interp recursionlimit {}
+} 1000
+test interp-29.2.2 {query recursion limit} {
+ set i [interp create]
+ set n [interp recursionlimit $i]
+ interp delete $i
+ set n
+} 1000
+test interp-29.2.3 {query recursion limit} {
+ set i [interp create]
+ set n [$i recursionlimit]
+ interp delete $i
+ set n
+} 1000
+test interp-29.2.4 {query recursion limit} {
+ set i [interp create]
+ set r [$i eval {
+ set n1 [interp recursionlimit {} 42]
+ set n2 [interp recursionlimit {}]
+ list $n1 $n2
+ }]
+ interp delete $i
+ set r
+} {42 42}
+test interp-29.2.5 {query recursion limit} {
+ set i [interp create]
+ set n1 [interp recursionlimit $i 42]
+ set n2 [interp recursionlimit $i]
+ interp delete $i
+ list $n1 $n2
+} {42 42}
+test interp-29.2.6 {query recursion limit} {
+ set i [interp create]
+ set n1 [interp recursionlimit $i 42]
+ set n2 [$i recursionlimit]
+ interp delete $i
+ list $n1 $n2
+} {42 42}
+test interp-29.2.7 {query recursion limit} {
+ set i [interp create]
+ set n1 [$i recursionlimit 42]
+ set n2 [interp recursionlimit $i]
+ interp delete $i
+ list $n1 $n2
+} {42 42}
+test interp-29.2.8 {query recursion limit} {
+ set i [interp create]
+ set n1 [$i recursionlimit 42]
+ set n2 [$i recursionlimit]
+ interp delete $i
+ list $n1 $n2
+} {42 42}
+test interp-29.3.1 {recursion limit} {
+ set i [interp create]
+ set r [interp eval $i {
+ interp recursionlimit {} 50
+ proc p {} {incr ::i; p}
+ set i 0
+ list [catch p msg] $msg $i
+ }]
+ interp delete $i
+ set r
+} {1 {too many nested evaluations (infinite loop?)} 49}
+test interp-29.3.2 {recursion limit} {
+ set i [interp create]
+ interp recursionlimit $i 50
+ set r [interp eval $i {
+ proc p {} {incr ::i; p}
+ set i 0
+ list [catch p msg] $msg $i
+ }]
+ interp delete $i
+ set r
+} {1 {too many nested evaluations (infinite loop?)} 49}
+test interp-29.3.3 {recursion limit} {
+ set i [interp create]
+ $i recursionlimit 50
+ set r [interp eval $i {
+ proc p {} {incr ::i; p}
+ set i 0
+ list [catch p msg] $msg $i
+ }]
+ interp delete $i
+ set r
+} {1 {too many nested evaluations (infinite loop?)} 49}
+test interp-29.3.4 {recursion limit error reporting} {
+ interp create slave
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ interp recursionlimit {} 5
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {1 {falling back due to new recursion limit}}
+test interp-29.3.5 {recursion limit error reporting} {
+ interp create slave
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ interp recursionlimit {} 4
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {1 {falling back due to new recursion limit}}
+test interp-29.3.6 {recursion limit error reporting} {
+ interp create slave
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ interp recursionlimit {} 6
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+#
+# Note that TEBC does not verify the interp's nesting level itself; the nesting
+# level will only be verified when it invokes a non-bcc'd command.
+#
+test interp-29.3.7a {recursion limit error reporting} {
+ interp create slave
+ after 0 {interp recursionlimit slave 5}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.3.7b {recursion limit error reporting} {
+ interp create slave
+ after 0 {interp recursionlimit slave 5}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ update
+ eval { # 5
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.3.7c {recursion limit error reporting} {
+ interp create slave
+ after 0 {interp recursionlimit slave 5}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set set set
+ $set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {1 {too many nested evaluations (infinite loop?)}}
+test interp-29.3.8a {recursion limit error reporting} {
+ interp create slave
+ after 0 {interp recursionlimit slave 4}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.3.8b {recursion limit error reporting} {
+ interp create slave
+ after 0 {interp recursionlimit slave 4}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ update
+ eval { # 5
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {1 {too many nested evaluations (infinite loop?)}}
+test interp-29.3.9a {recursion limit error reporting} {
+ interp create slave
+ after 0 {interp recursionlimit slave 6}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.3.9b {recursion limit error reporting} {
+ interp create slave
+ after 0 {interp recursionlimit slave 6}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ set set set
+ $set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.3.10a {recursion limit error reporting} {
+ interp create slave
+ after 0 {slave recursionlimit 4}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.3.10b {recursion limit error reporting} {
+ interp create slave
+ after 0 {slave recursionlimit 4}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ update
+ eval { # 5
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {1 {too many nested evaluations (infinite loop?)}}
+test interp-29.3.11a {recursion limit error reporting} {
+ interp create slave
+ after 0 {slave recursionlimit 5}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.3.11b {recursion limit error reporting} {
+ interp create slave
+ after 0 {slave recursionlimit 5}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set set set
+ $set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {1 {too many nested evaluations (infinite loop?)}}
+test interp-29.3.12a {recursion limit error reporting} {
+ interp create slave
+ after 0 {slave recursionlimit 6}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.3.12b {recursion limit error reporting} {
+ interp create slave
+ after 0 {slave recursionlimit 6}
+ set r1 [slave eval {
+ catch { # nesting level 1
+ eval { # 2
+ eval { # 3
+ eval { # 4
+ eval { # 5
+ update
+ set set set
+ $set x ok
+ }
+ }
+ }
+ }
+ } msg
+ }]
+ set r2 [slave eval { set msg }]
+ interp delete slave
+ list $r1 $r2
+} {0 ok}
+test interp-29.4.1 {recursion limit inheritance} {
+ set i [interp create]
+ set ii [interp eval $i {
+ interp recursionlimit {} 50
+ interp create
+ }]
+ set r [interp eval [list $i $ii] {
+ proc p {} {incr ::i; p}
+ set i 0
+ catch p
+ set i
+ }]
+ interp delete $i
+ set r
+} 50
+test interp-29.4.2 {recursion limit inheritance} {
+ set i [interp create]
+ $i recursionlimit 50
+ set ii [interp eval $i {interp create}]
+ set r [interp eval [list $i $ii] {
+ proc p {} {incr ::i; p}
+ set i 0
+ catch p
+ set i
+ }]
+ interp delete $i
+ set r
+} 50
+test interp-29.5.1 {does slave recursion limit affect master?} {
+ set before [interp recursionlimit {}]
+ set i [interp create]
+ interp recursionlimit $i 20000
+ set after [interp recursionlimit {}]
+ set slavelimit [interp recursionlimit $i]
+ interp delete $i
+ list [expr {$before == $after}] $slavelimit
+} {1 20000}
+test interp-29.5.2 {does slave recursion limit affect master?} {
+ set before [interp recursionlimit {}]
+ set i [interp create]
+ interp recursionlimit $i 20000
+ set after [interp recursionlimit {}]
+ set slavelimit [$i recursionlimit]
+ interp delete $i
+ list [expr {$before == $after}] $slavelimit
+} {1 20000}
+test interp-29.5.3 {does slave recursion limit affect master?} {
+ set before [interp recursionlimit {}]
+ set i [interp create]
+ $i recursionlimit 20000
+ set after [interp recursionlimit {}]
+ set slavelimit [interp recursionlimit $i]
+ interp delete $i
+ list [expr {$before == $after}] $slavelimit
+} {1 20000}
+test interp-29.5.4 {does slave recursion limit affect master?} {
+ set before [interp recursionlimit {}]
+ set i [interp create]
+ $i recursionlimit 20000
+ set after [interp recursionlimit {}]
+ set slavelimit [$i recursionlimit]
+ interp delete $i
+ list [expr {$before == $after}] $slavelimit
+} {1 20000}
+test interp-29.6.1 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set n [interp recursionlimit slave]
+ interp delete slave
+ set n
+} 1000
+test interp-29.6.2 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set n [slave recursionlimit]
+ interp delete slave
+ set n
+} 1000
+test interp-29.6.3 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set n1 [interp recursionlimit slave 42]
+ set n2 [interp recursionlimit slave]
+ interp delete slave
+ list $n1 $n2
+} {42 42}
+test interp-29.6.4 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set n1 [slave recursionlimit 42]
+ set n2 [interp recursionlimit slave]
+ interp delete slave
+ list $n1 $n2
+} {42 42}
+test interp-29.6.5 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set n1 [interp recursionlimit slave 42]
+ set n2 [slave recursionlimit]
+ interp delete slave
+ list $n1 $n2
+} {42 42}
+test interp-29.6.6 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set n1 [slave recursionlimit 42]
+ set n2 [slave recursionlimit]
+ interp delete slave
+ list $n1 $n2
+} {42 42}
+test interp-29.6.7 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set n1 [slave recursionlimit 42]
+ set n2 [slave recursionlimit]
+ interp delete slave
+ list $n1 $n2
+} {42 42}
+test interp-29.6.8 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set n [catch {slave eval {interp recursionlimit {} 42}} msg]
+ interp delete slave
+ list $n $msg
+} {1 {permission denied: safe interpreters cannot change recursion limit}}
+test interp-29.6.9 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set result [
+ slave eval {
+ interp create slave2 -safe
+ set n [catch {
+ interp recursionlimit slave2 42
+ } msg]
+ list $n $msg
+ }
+ ]
+ interp delete slave
+ set result
+} {1 {permission denied: safe interpreters cannot change recursion limit}}
+test interp-29.6.10 {safe interpreter recursion limit} {
+ interp create slave -safe
+ set result [
+ slave eval {
+ interp create slave2 -safe
+ set n [catch {
+ slave2 recursionlimit 42
+ } msg]
+ list $n $msg
+ }
+ ]
+ interp delete slave
+ set result
+} {1 {permission denied: safe interpreters cannot change recursion limit}}
+
+
+# # Deep recursion (into interps when the regular one fails):
+# # still crashes...
+# proc p {} {
+# if {[catch p ret]} {
+# catch {
+# set i [interp create]
+# interp eval $i [list proc p {} [info body p]]
+# interp eval $i p
+# }
+# interp delete $i
+# return ok
+# }
+# return $ret
+# }
+# p
+
+# more tests needed...
+
+# Interp & stack
+#test interp-29.1 {interp and stack (info level)} {
+#} {}
+
+# End of stack-recursion tests
+
+# This test dumps core in Tcl 8.0.3!
+test interp-30.1 {deletion of aliases inside namespaces} {
+ set i [interp create]
+ $i alias ns::cmd list
+ $i alias ns::cmd {}
+} {}
+
+test interp-31.1 {alias invocation scope} {
+ proc mySet {varName value} {
+ upvar 1 $varName localVar
+ set localVar $value
+ }
+ interp alias {} myNewSet {} mySet
+ proc testMyNewSet {value} {
+ myNewSet a $value
+ return $a
+ }
+ unset -nocomplain a
+ set result [testMyNewSet "ok"]
+ rename testMyNewSet {}
+ rename mySet {}
+ rename myNewSet {}
+ set result
+} ok
+
+test interp-32.1 {parent's working directory should be inherited by a child interp} -setup {
+ cd [temporaryDirectory]
+} -body {
+ set parent [pwd]
+ set i [interp create]
+ set child [$i eval pwd]
+ interp delete $i
+ file mkdir cwd_test
+ cd cwd_test
+ lappend parent [pwd]
+ set i [interp create]
+ lappend child [$i eval pwd]
+ cd ..
+ file delete cwd_test
+ interp delete $i
+ expr {[string equal $parent $child] ? 1 :
+ "\{$parent\} != \{$child\}"}
+} -cleanup {
+ cd [workingDirectory]
+} -result 1
+
+test interp-33.1 {refCounting for target words of alias [Bug 730244]} {
+ # This test will panic if Bug 730244 is not fixed.
+ set i [interp create]
+ proc testHelper args {rename testHelper {}; return $args}
+ # Note: interp names are simple words by default
+ trace add execution testHelper enter "interp alias $i alias {} ;#"
+ interp alias $i alias {} testHelper this
+ $i eval alias
+} this
+
+test interp-34.1 {basic test of limits - calling commands} -body {
+ set i [interp create]
+ $i eval {
+ proc foobar {} {
+ for {set x 0} {$x<1000000} {incr x} {
+ # Calls to this are not bytecoded away
+ pid
+ }
+ }
+ }
+ $i limit command -value 1000
+ $i eval foobar
+} -returnCodes error -result {command count limit exceeded} -cleanup {
+ interp delete $i
+}
+test interp-34.2 {basic test of limits - bytecoded commands} -body {
+ set i [interp create]
+ $i eval {
+ proc foobar {} {
+ for {set x 0} {$x<1000000} {incr x} {
+ # Calls to this *are* bytecoded away
+ expr {1+2+3}
+ }
+ }
+ }
+ $i limit command -value 1000
+ $i eval foobar
+} -returnCodes error -result {command count limit exceeded} -cleanup {
+ interp delete $i
+}
+test interp-34.3 {basic test of limits - pure bytecode loop} -body {
+ set i [interp create]
+ $i eval {
+ proc foobar {} {
+ while {1} {
+ # No bytecode at all here...
+ }
+ }
+ }
+ # We use a time limit here; command limits don't trap this case
+ $i limit time -seconds [expr {[clock seconds]+2}]
+ $i eval foobar
+} -returnCodes error -result {time limit exceeded} -cleanup {
+ interp delete $i
+}
+test interp-34.3.1 {basic test of limits - pure inside-command loop} -body {
+ set i [interp create]
+ $i eval {
+ proc foobar {} {
+ set while while
+ $while {1} {
+ # No bytecode at all here...
+ }
+ }
+ }
+ # We use a time limit here; command limits don't trap this case
+ $i limit time -seconds [expr {[clock seconds]+2}]
+ $i eval foobar
+} -returnCodes error -result {time limit exceeded} -cleanup {
+ interp delete $i
+}
+test interp-34.4 {limits with callbacks: extending limits} -setup {
+ set i [interp create]
+ set a 0
+ set b 0
+ set c a
+ proc cb1 {} {
+ global c
+ incr ::$c
+ }
+ proc cb2 {newlimit args} {
+ global c i
+ set c b
+ $i limit command -value $newlimit
+ }
+} -body {
+ interp alias $i foo {} cb1
+ set curlim [$i eval info cmdcount]
+ $i limit command -command "cb2 [expr $curlim+100]" \
+ -value [expr {$curlim+10}]
+ $i eval {for {set i 0} {$i<10} {incr i} {foo}}
+ list $a $b $c
+} -result {6 4 b} -cleanup {
+ interp delete $i
+ rename cb1 {}
+ rename cb2 {}
+}
+# The next three tests exercise all the three ways that limit handlers
+# can be deleted. Fully verifying this requires additional source
+# code instrumentation.
+test interp-34.5 {limits with callbacks: removing limits} -setup {
+ set i [interp create]
+ set a 0
+ set b 0
+ set c a
+ proc cb1 {} {
+ global c
+ incr ::$c
+ }
+ proc cb2 {newlimit args} {
+ global c i
+ set c b
+ $i limit command -value $newlimit
+ }
+} -body {
+ interp alias $i foo {} cb1
+ set curlim [$i eval info cmdcount]
+ $i limit command -command "cb2 {}" -value [expr {$curlim+10}]
+ $i eval {for {set i 0} {$i<10} {incr i} {foo}}
+ list $a $b $c
+} -result {6 4 b} -cleanup {
+ interp delete $i
+ rename cb1 {}
+ rename cb2 {}
+}
+test interp-34.6 {limits with callbacks: removing limits and handlers} -setup {
+ set i [interp create]
+ set a 0
+ set b 0
+ set c a
+ proc cb1 {} {
+ global c
+ incr ::$c
+ }
+ proc cb2 {args} {
+ global c i
+ set c b
+ $i limit command -value {} -command {}
+ }
+} -body {
+ interp alias $i foo {} cb1
+ set curlim [$i eval info cmdcount]
+ $i limit command -command cb2 -value [expr {$curlim+10}]
+ $i eval {for {set i 0} {$i<10} {incr i} {foo}}
+ list $a $b $c
+} -result {6 4 b} -cleanup {
+ interp delete $i
+ rename cb1 {}
+ rename cb2 {}
+}
+test interp-34.7 {limits with callbacks: deleting the handler interp} -setup {
+ set i [interp create]
+ $i eval {
+ set i [interp create]
+ proc cb1 {} {
+ global c
+ incr ::$c
+ }
+ proc cb2 {args} {
+ global c i curlim
+ set c b
+ $i limit command -value [expr {$curlim+1000}]
+ trapToParent
+ }
+ }
+ proc cb3 {} {
+ global i subi
+ interp alias [list $i $subi] foo {} cb4
+ interp delete $i
+ }
+ proc cb4 {} {
+ global n
+ incr n
+ }
+} -body {
+ set subi [$i eval set i]
+ interp alias $i trapToParent {} cb3
+ set n 0
+ $i eval {
+ set a 0
+ set b 0
+ set c a
+ interp alias $i foo {} cb1
+ set curlim [$i eval info cmdcount]
+ $i limit command -command cb2 -value [expr {$curlim+10}]
+ }
+ $i eval {
+ $i eval {
+ for {set i 0} {$i<10} {incr i} {foo}
+ }
+ }
+ list $n [interp exists $i]
+} -result {4 0} -cleanup {
+ rename cb3 {}
+ rename cb4 {}
+}
+# Bug 1085023
+test interp-34.8 {time limits trigger in vwaits} -body {
+ set i [interp create]
+ interp limit $i time -seconds [expr {[clock seconds]+1}] -granularity 1
+ $i eval {
+ set x {}
+ vwait x
+ }
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {limit exceeded}
+test interp-34.9 {time limits trigger in blocking after} {
+ set i [interp create]
+ set t0 [clock seconds]
+ interp limit $i time -seconds [expr {$t0 + 1}] -granularity 1
+ set code [catch {
+ $i eval {after 10000}
+ } msg]
+ set t1 [clock seconds]
+ interp delete $i
+ list $code $msg [expr {($t1-$t0) < 3 ? "OK" : $t1-$t0}]
+} {1 {time limit exceeded} OK}
+test interp-34.10 {time limits trigger in vwaits: Bug 1221395} -body {
+ set i [interp create]
+ # Assume someone hasn't set the clock to early 1970!
+ $i limit time -seconds 1 -granularity 4
+ interp alias $i log {} lappend result
+ set result {}
+ catch {
+ $i eval {
+ log 1
+ after 100
+ log 2
+ }
+ } msg
+ interp delete $i
+ lappend result $msg
+} -result {1 {time limit exceeded}}
+test interp-34.11 {time limit extension in callbacks} -setup {
+ proc cb1 {i t} {
+ global result
+ lappend result cb1
+ $i limit time -seconds $t -command cb2
+ }
+ proc cb2 {} {
+ global result
+ lappend result cb2
+ }
+} -body {
+ set i [interp create]
+ set t0 [clock seconds]
+ $i limit time -seconds [expr {$t0+1}] -granularity 1 \
+ -command "cb1 $i [expr {$t0+2}]"
+ set ::result {}
+ lappend ::result [catch {
+ $i eval {
+ for {set i 0} {$i<30} {incr i} {
+ after 100
+ }
+ }
+ } msg] $msg
+ set t1 [clock seconds]
+ lappend ::result [expr {$t1-$t0>=2 ? "ok" : "$t0,$t1"}]
+ interp delete $i
+ return $::result
+} -result {cb1 cb2 1 {time limit exceeded} ok} -cleanup {
+ rename cb1 {}
+ rename cb2 {}
+}
+test interp-34.12 {time limit extension in callbacks} -setup {
+ proc cb1 {i} {
+ global result times
+ lappend result cb1
+ set times [lassign $times t]
+ $i limit time -seconds $t
+ }
+} -body {
+ set i [interp create]
+ set t0 [clock seconds]
+ set ::times "[expr {$t0+2}] [expr {$t0+100}]"
+ $i limit time -seconds [expr {$t0+1}] -granularity 1 -command "cb1 $i"
+ set ::result {}
+ lappend ::result [catch {
+ $i eval {
+ for {set i 0} {$i<30} {incr i} {
+ after 100
+ }
+ }
+ } msg] $msg
+ set t1 [clock seconds]
+ lappend ::result [expr {$t1-$t0>=2 ? "ok" : "$t0,$t1"}]
+ interp delete $i
+ return $::result
+} -result {cb1 cb1 0 {} ok} -cleanup {
+ rename cb1 {}
+}
+test interp-34.13 {time limit granularity and vwait: Bug 2891362} -setup {
+ set i [interp create -safe]
+} -body {
+ $i limit time -seconds [clock add [clock seconds] 1 second]
+ $i eval {
+ after 2000 set x timeout
+ vwait x
+ return $x
+ }
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {limit exceeded}
+
+test interp-35.1 {interp limit syntax} -body {
+ interp limit
+} -returnCodes error -result {wrong # args: should be "interp limit path limitType ?-option value ...?"}
+test interp-35.2 {interp limit syntax} -body {
+ interp limit {}
+} -returnCodes error -result {wrong # args: should be "interp limit path limitType ?-option value ...?"}
+test interp-35.3 {interp limit syntax} -body {
+ interp limit {} foo
+} -returnCodes error -result {bad limit type "foo": must be commands or time}
+test interp-35.4 {interp limit syntax} -body {
+ set i [interp create]
+ set dict [interp limit $i commands]
+ set result {}
+ foreach key [lsort [dict keys $dict]] {
+ lappend result $key [dict get $dict $key]
+ }
+ set result
+} -cleanup {
+ interp delete $i
+} -result {-command {} -granularity 1 -value {}}
+test interp-35.5 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i commands -granularity
+} -cleanup {
+ interp delete $i
+} -result 1
+test interp-35.6 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i commands -granularity 2
+} -cleanup {
+ interp delete $i
+} -result {}
+test interp-35.7 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i commands -foobar
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {bad option "-foobar": must be -command, -granularity, or -value}
+test interp-35.8 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i commands -granularity foobar
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {expected integer but got "foobar"}
+test interp-35.9 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i commands -granularity 0
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {granularity must be at least 1}
+test interp-35.10 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i commands -value foobar
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {expected integer but got "foobar"}
+test interp-35.11 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i commands -value -1
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {command limit value must be at least 0}
+test interp-35.12 {interp limit syntax} -body {
+ set i [interp create]
+ set dict [interp limit $i time]
+ set result {}
+ foreach key [lsort [dict keys $dict]] {
+ lappend result $key [dict get $dict $key]
+ }
+ set result
+} -cleanup {
+ interp delete $i
+} -result {-command {} -granularity 10 -milliseconds {} -seconds {}}
+test interp-35.13 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -granularity
+} -cleanup {
+ interp delete $i
+} -result 10
+test interp-35.14 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -granularity 2
+} -cleanup {
+ interp delete $i
+} -result {}
+test interp-35.15 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -foobar
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {bad option "-foobar": must be -command, -granularity, -milliseconds, or -seconds}
+test interp-35.16 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -granularity foobar
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {expected integer but got "foobar"}
+test interp-35.17 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -granularity 0
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {granularity must be at least 1}
+test interp-35.18 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -seconds foobar
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {expected integer but got "foobar"}
+test interp-35.19 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -seconds -1
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {seconds must be at least 0}
+test interp-35.20 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -millis foobar
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {expected integer but got "foobar"}
+test interp-35.21 {interp limit syntax} -body {
+ set i [interp create]
+ interp limit $i time -millis -1
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {milliseconds must be at least 0}
+test interp-35.22 {interp time limits normalize milliseconds} -body {
+ set i [interp create]
+ interp limit $i time -seconds 1 -millis 1500
+ list [$i limit time -seconds] [$i limit time -millis]
+} -cleanup {
+ interp delete $i
+} -result {2 500}
+# Bug 3398794
+test interp-35.23 {interp command limits can't touch current interp} -body {
+ interp limit {} commands -value 10
+} -returnCodes error -result {limits on current interpreter inaccessible}
+test interp-35.24 {interp time limits can't touch current interp} -body {
+ interp limit {} time -seconds 2
+} -returnCodes error -result {limits on current interpreter inaccessible}
+
+test interp-36.1 {interp bgerror syntax} -body {
+ interp bgerror
+} -returnCodes error -result {wrong # args: should be "interp bgerror path ?cmdPrefix?"}
+test interp-36.2 {interp bgerror syntax} -body {
+ interp bgerror x y z
+} -returnCodes error -result {wrong # args: should be "interp bgerror path ?cmdPrefix?"}
+test interp-36.3 {interp bgerror syntax} -setup {
+ interp create slave
+} -body {
+ slave bgerror x y
+} -cleanup {
+ interp delete slave
+} -returnCodes error -result {wrong # args: should be "slave bgerror ?cmdPrefix?"}
+test interp-36.4 {SlaveBgerror syntax} -setup {
+ interp create slave
+} -body {
+ slave bgerror \{
+} -cleanup {
+ interp delete slave
+} -returnCodes error -result {cmdPrefix must be list of length >= 1}
+test interp-36.5 {SlaveBgerror syntax} -setup {
+ interp create slave
+} -body {
+ slave bgerror {}
+} -cleanup {
+ interp delete slave
+} -returnCodes error -result {cmdPrefix must be list of length >= 1}
+test interp-36.6 {SlaveBgerror returns handler} -setup {
+ interp create slave
+} -body {
+ slave bgerror {foo bar soom}
+} -cleanup {
+ interp delete slave
+} -result {foo bar soom}
+test interp-36.7 {SlaveBgerror sets error handler of slave [1999035]} -setup {
+ interp create slave
+ slave alias handler handler
+ slave bgerror handler
+ variable result {untouched}
+ proc handler {args} {
+ variable result
+ set result [lindex $args 0]
+ }
+} -body {
+ slave eval {
+ variable done {}
+ after 0 error foo
+ after 10 [list ::set [namespace which -variable done] {}]
+ vwait [namespace which -variable done]
+ }
+ set result
+} -cleanup {
+ variable result {}
+ unset -nocomplain result
+ interp delete slave
+} -result foo
+
+test interp-37.1 {safe interps and min() and max(): Bug 2895741} -setup {
+ catch {interp delete a}
+ interp create a
+ set result {}
+} -body {
+ interp create {a b} -safe
+ lappend result [interp eval a {expr min(5,2,3)*max(7,13,11)}]
+ lappend result [interp eval {a b} {expr min(5,2,3)*max(7,13,11)}]
+} -cleanup {
+ unset -nocomplain result
+ interp delete a
+} -result {26 26}
+
+test interp-38.1 {interp debug one-way switch} -setup {
+ catch {interp delete a}
+ interp create a
+ interp debug a -frame 1
+} -body {
+ # TIP #3xx interp debug frame is a one-way switch
+ interp debug a -frame 0
+} -cleanup {
+ interp delete a
+} -result {1}
+test interp-38.2 {interp debug env var} -setup {
+ catch {interp delete a}
+ set ::env(TCL_INTERP_DEBUG_FRAME) 1
+ interp create a
+} -body {
+ interp debug a
+} -cleanup {
+ unset -nocomplain ::env(TCL_INTERP_DEBUG_FRAME)
+ interp delete a
+} -result {-frame 1}
+test interp-38.3 {interp debug wrong args} -body {
+ interp debug
+} -returnCodes {
+ error
+} -result {wrong # args: should be "interp debug path ?-frame ?bool??"}
+test interp-38.4 {interp debug basic setup} -body {
+ interp debug {}
+} -result {-frame 0}
+test interp-38.5 {interp debug basic setup} -body {
+ interp debug {} -f
+} -result {0}
+test interp-38.6 {interp debug basic setup} -body {
+ interp debug -frames
+} -returnCodes error -result {could not find interpreter "-frames"}
+test interp-38.7 {interp debug basic setup} -body {
+ interp debug {} -frames
+} -returnCodes error -result {bad debug option "-frames": must be -frame}
+test interp-38.8 {interp debug basic setup} -body {
+ interp debug {} -frame 0 bogus
+} -returnCodes {
+ error
+} -result {wrong # args: should be "interp debug path ?-frame ?bool??"}
+
+# cleanup
+unset -nocomplain hidden_cmds
+foreach i [interp slaves] {
+ interp delete $i
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/io.test b/pkgs/msgcat/tests/io.test
new file mode 100644
index 0000000..f3c39f4
--- /dev/null
+++ b/pkgs/msgcat/tests/io.test
@@ -0,0 +1,7797 @@
+# -*- tcl -*-
+# Functionality covered: operation of all IO commands, and all procedures
+# defined in generic/tclIO.c.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# 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.
+
+if {[catch {package require tcltest 2}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2 required."
+ return
+}
+namespace eval ::tcl::test::io {
+ namespace import ::tcltest::*
+
+ variable umaskValue
+ variable path
+ variable f
+ variable i
+ variable n
+ variable v
+ variable msg
+ variable expected
+
+testConstraint testchannel [llength [info commands testchannel]]
+testConstraint exec [llength [info commands exec]]
+testConstraint openpipe 1
+testConstraint fileevent [llength [info commands fileevent]]
+testConstraint fcopy [llength [info commands fcopy]]
+testConstraint testfevent [llength [info commands testfevent]]
+testConstraint testchannelevent [llength [info commands testchannelevent]]
+testConstraint testmainthread [llength [info commands testmainthread]]
+testConstraint thread [expr {0 == [catch {package require Thread 2.6}]}]
+
+# You need a *very* special environment to do some tests. In
+# particular, many file systems do not support large-files...
+testConstraint largefileSupport 0
+
+# some tests can only be run is umask is 2
+# if "umask" cannot be run, the tests will be skipped.
+set umaskValue 0
+testConstraint umask [expr {![catch {set umaskValue [scan [exec /bin/sh -c umask] %o]}]}]
+
+testConstraint makeFileInHome [expr {![file exists ~/_test_] && [file writable ~]}]
+
+# set up a long data file for some of the following tests
+
+set path(longfile) [makeFile {} longfile]
+set f [open $path(longfile) w]
+fconfigure $f -eofchar {} -translation lf
+for { set i 0 } { $i < 100 } { incr i} {
+ puts $f "#123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
+\#123456789abcdef01
+\#"
+ }
+close $f
+
+set path(cat) [makeFile {
+ set f stdin
+ if {$argv != ""} {
+ set f [open [lindex $argv 0]]
+ }
+ fconfigure $f -encoding binary -translation lf -blocking 0 -eofchar \x1a
+ fconfigure stdout -encoding binary -translation lf -buffering none
+ fileevent $f readable "foo $f"
+ proc foo {f} {
+ set x [read $f]
+ catch {puts -nonewline $x}
+ if {[eof $f]} {
+ close $f
+ exit 0
+ }
+ }
+ vwait forever
+} cat]
+
+set thisScript [file join [pwd] [info script]]
+
+proc contents {file} {
+ set f [open $file]
+ fconfigure $f -translation binary
+ set a [read $f]
+ close $f
+ return $a
+}
+
+test io-1.5 {Tcl_WriteChars: CheckChannelErrors} {emptyTest} {
+ # no test, need to cause an async error.
+} {}
+set path(test1) [makeFile {} test1]
+test io-1.6 {Tcl_WriteChars: WriteBytes} {
+ set f [open $path(test1) w]
+ fconfigure $f -encoding binary
+ puts -nonewline $f "a\u4e4d\0"
+ close $f
+ contents $path(test1)
+} "a\x4d\x00"
+test io-1.7 {Tcl_WriteChars: WriteChars} {
+ set f [open $path(test1) w]
+ fconfigure $f -encoding shiftjis
+ puts -nonewline $f "a\u4e4d\0"
+ close $f
+ contents $path(test1)
+} "a\x93\xe1\x00"
+set path(test2) [makeFile {} test2]
+test io-1.8 {Tcl_WriteChars: WriteChars} {
+ # This test written for SF bug #506297.
+ #
+ # Executing this test without the fix for the referenced bug
+ # applied to tcl will cause tcl, more specifically WriteChars, to
+ # go into an infinite loop.
+
+ set f [open $path(test2) w]
+ fconfigure $f -encoding iso2022-jp
+ puts -nonewline $f [format %s%c [string repeat " " 4] 12399]
+ close $f
+ contents $path(test2)
+} " \x1b\$B\$O\x1b(B"
+
+test io-1.9 {Tcl_WriteChars: WriteChars} {
+ # When closing a channel with an encoding that appends
+ # escape bytes, check for the case where the escape
+ # bytes overflow the current IO buffer. The bytes
+ # should be moved into a new buffer.
+
+ set data "1234567890 [format %c 12399]"
+
+ set sizes [list]
+
+ # With default buffer size
+ set f [open $path(test2) w]
+ fconfigure $f -encoding iso2022-jp
+ puts -nonewline $f $data
+ close $f
+ lappend sizes [file size $path(test2)]
+
+ # With buffer size equal to the length
+ # of the data, the escape bytes would
+ # go into the next buffer.
+
+ set f [open $path(test2) w]
+ fconfigure $f -encoding iso2022-jp -buffersize 16
+ puts -nonewline $f $data
+ close $f
+ lappend sizes [file size $path(test2)]
+
+ # With buffer size that is large enough
+ # to hold 1 byte of escaped data, but
+ # not all 3. This should not write
+ # the escape bytes to the first buffer
+ # and then again to the second buffer.
+
+ set f [open $path(test2) w]
+ fconfigure $f -encoding iso2022-jp -buffersize 17
+ puts -nonewline $f $data
+ close $f
+ lappend sizes [file size $path(test2)]
+
+ # With buffer size that can hold 2 out of
+ # 3 bytes of escaped data.
+
+ set f [open $path(test2) w]
+ fconfigure $f -encoding iso2022-jp -buffersize 18
+ puts -nonewline $f $data
+ close $f
+ lappend sizes [file size $path(test2)]
+
+ # With buffer size that can hold all the
+ # data and escape bytes.
+
+ set f [open $path(test2) w]
+ fconfigure $f -encoding iso2022-jp -buffersize 19
+ puts -nonewline $f $data
+ close $f
+ lappend sizes [file size $path(test2)]
+
+ set sizes
+} {19 19 19 19 19}
+
+test io-2.1 {WriteBytes} {
+ # loop until all bytes are written
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding binary -buffersize 16 -translation crlf
+ puts $f "abcdefghijklmnopqrstuvwxyz"
+ close $f
+ contents $path(test1)
+} "abcdefghijklmnopqrstuvwxyz\r\n"
+test io-2.2 {WriteBytes: savedLF > 0} {
+ # After flushing buffer, there was a \n left over from the last
+ # \n -> \r\n expansion. It gets stuck at beginning of this buffer.
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding binary -buffersize 16 -translation crlf
+ puts -nonewline $f "123456789012345\n12"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "123456789012345\r" "123456789012345\r\n12"]
+test io-2.3 {WriteBytes: flush on line} {
+ # Tcl "line" buffering has weird behavior: if current buffer contains
+ # a \n, entire buffer gets flushed. Logical behavior would be to flush
+ # only up to the \n.
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding binary -buffering line -translation crlf
+ puts -nonewline $f "\n12"
+ set x [contents $path(test1)]
+ close $f
+ set x
+} "\r\n12"
+test io-2.4 {WriteBytes: reset sawLF after each buffer} {
+ set f [open $path(test1) w]
+ fconfigure $f -encoding binary -buffering line -translation lf \
+ -buffersize 16
+ puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]
+
+test io-3.1 {WriteChars: compatibility with WriteBytes} {
+ # loop until all bytes are written
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding ascii -buffersize 16 -translation crlf
+ puts $f "abcdefghijklmnopqrstuvwxyz"
+ close $f
+ contents $path(test1)
+} "abcdefghijklmnopqrstuvwxyz\r\n"
+test io-3.2 {WriteChars: compatibility with WriteBytes: savedLF > 0} {
+ # After flushing buffer, there was a \n left over from the last
+ # \n -> \r\n expansion. It gets stuck at beginning of this buffer.
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding ascii -buffersize 16 -translation crlf
+ puts -nonewline $f "123456789012345\n12"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "123456789012345\r" "123456789012345\r\n12"]
+test io-3.3 {WriteChars: compatibility with WriteBytes: flush on line} {
+ # Tcl "line" buffering has weird behavior: if current buffer contains
+ # a \n, entire buffer gets flushed. Logical behavior would be to flush
+ # only up to the \n.
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding ascii -buffering line -translation crlf
+ puts -nonewline $f "\n12"
+ set x [contents $path(test1)]
+ close $f
+ set x
+} "\r\n12"
+test io-3.4 {WriteChars: loop over stage buffer} {
+ # stage buffer maps to more than can be queued at once.
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding jis0208 -buffersize 16
+ puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test io-3.5 {WriteChars: saved != 0} {
+ # Bytes produced by UtfToExternal from end of last channel buffer
+ # had to be moved to beginning of next channel buffer to preserve
+ # requested buffersize.
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding jis0208 -buffersize 17
+ puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test io-3.6 {WriteChars: (stageRead + dstWrote == 0)} {
+ # One incomplete UTF-8 character at end of staging buffer. Backup
+ # in src to the beginning of that UTF-8 character and try again.
+ #
+ # Translate the first 16 bytes, produce 14 bytes of output, 2 left over
+ # (first two bytes of \uff21 in UTF-8). Given those two bytes try
+ # translating them again, find that no bytes are read produced, and break
+ # to outer loop where those two bytes will have the remaining 4 bytes
+ # (the last byte of \uff21 plus the all of \uff22) appended.
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding shiftjis -buffersize 16
+ puts -nonewline $f "12345678901234\uff21\uff22"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "12345678901234\x82\x60" "12345678901234\x82\x60\x82\x61"]
+test io-3.7 {WriteChars: (bufPtr->nextAdded > bufPtr->length)} {
+ # When translating UTF-8 to external, the produced bytes went past end
+ # of the channel buffer. This is done purpose -- we then truncate the
+ # bytes at the end of the partial character to preserve the requested
+ # blocksize on flush. The truncated bytes are moved to the beginning
+ # of the next channel buffer.
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding jis0208 -buffersize 17
+ puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test io-3.8 {WriteChars: reset sawLF after each buffer} {
+ set f [open $path(test1) w]
+ fconfigure $f -encoding ascii -buffering line -translation lf \
+ -buffersize 16
+ puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]
+
+test io-4.1 {TranslateOutputEOL: lf} {
+ # search for \n
+
+ set f [open $path(test1) w]
+ fconfigure $f -buffering line -translation lf
+ puts $f "abcde"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "abcde\n" "abcde\n"]
+test io-4.2 {TranslateOutputEOL: cr} {
+ # search for \n, replace with \r
+
+ set f [open $path(test1) w]
+ fconfigure $f -buffering line -translation cr
+ puts $f "abcde"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "abcde\r" "abcde\r"]
+test io-4.3 {TranslateOutputEOL: crlf} {
+ # simple case: search for \n, replace with \r
+
+ set f [open $path(test1) w]
+ fconfigure $f -buffering line -translation crlf
+ puts $f "abcde"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "abcde\r\n" "abcde\r\n"]
+test io-4.4 {TranslateOutputEOL: crlf} {
+ # keep storing more bytes in output buffer until output buffer is full.
+ # We have 13 bytes initially that would turn into 18 bytes. Fill
+ # dest buffer while (dstEnd < dstMax).
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -buffersize 16
+ puts -nonewline $f "1234567\n\n\n\n\nA"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "1234567\r\n\r\n\r\n\r\n\r" "1234567\r\n\r\n\r\n\r\n\r\nA"]
+test io-4.5 {TranslateOutputEOL: crlf} {
+ # Check for overflow of the destination buffer
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -buffersize 12
+ puts -nonewline $f "12345678901\n456789012345678901234"
+ close $f
+ set x [contents $path(test1)]
+} "12345678901\r\n456789012345678901234"
+
+test io-5.1 {CheckFlush: not full} {
+ set f [open $path(test1) w]
+ fconfigure $f
+ puts -nonewline $f "12345678901234567890"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "" "12345678901234567890"]
+test io-5.2 {CheckFlush: full} {
+ set f [open $path(test1) w]
+ fconfigure $f -buffersize 16
+ puts -nonewline $f "12345678901234567890"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "1234567890123456" "12345678901234567890"]
+test io-5.3 {CheckFlush: not line} {
+ set f [open $path(test1) w]
+ fconfigure $f -buffering line
+ puts -nonewline $f "12345678901234567890"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "" "12345678901234567890"]
+test io-5.4 {CheckFlush: line} {
+ set f [open $path(test1) w]
+ fconfigure $f -buffering line -translation lf -encoding ascii
+ puts -nonewline $f "1234567890\n1234567890"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "1234567890\n1234567890" "1234567890\n1234567890"]
+test io-5.5 {CheckFlush: none} {
+ set f [open $path(test1) w]
+ fconfigure $f -buffering none
+ puts -nonewline $f "1234567890"
+ set x [list [contents $path(test1)]]
+ close $f
+ lappend x [contents $path(test1)]
+} [list "1234567890" "1234567890"]
+
+test io-6.1 {Tcl_GetsObj: working} {
+ set f [open $path(test1) w]
+ puts $f "foo\nboo"
+ close $f
+ set f [open $path(test1)]
+ set x [gets $f]
+ close $f
+ set x
+} {foo}
+test io-6.2 {Tcl_GetsObj: CheckChannelErrors() != 0} emptyTest {
+ # no test, need to cause an async error.
+} {}
+test io-6.3 {Tcl_GetsObj: how many have we used?} {
+ # if (bufPtr != NULL) {oldRemoved = bufPtr->nextRemoved}
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f "abc\ndefg"
+ close $f
+ set f [open $path(test1)]
+ set x [list [tell $f] [gets $f line] [tell $f] [gets $f line] $line]
+ close $f
+ set x
+} {0 3 5 4 defg}
+test io-6.4 {Tcl_GetsObj: encoding == NULL} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation binary
+ puts $f "\x81\u1234\0"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation binary
+ set x [list [gets $f line] $line]
+ close $f
+ set x
+} [list 3 "\x81\x34\x00"]
+test io-6.5 {Tcl_GetsObj: encoding != NULL} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation binary
+ puts $f "\x88\xea\x92\x9a"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding shiftjis
+ set x [list [gets $f line] $line]
+ close $f
+ set x
+} [list 2 "\u4e00\u4e01"]
+set a "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
+append a $a
+append a $a
+test io-6.6 {Tcl_GetsObj: loop test} {
+ # if (dst >= dstEnd)
+
+ set f [open $path(test1) w]
+ puts $f $a
+ puts $f hi
+ close $f
+ set f [open $path(test1)]
+ set x [list [gets $f line] $line]
+ close $f
+ set x
+} [list 256 $a]
+test io-6.7 {Tcl_GetsObj: error in input} {stdio openpipe} {
+ # if (FilterInputBytes(chanPtr, &gs) != 0)
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ puts -nonewline $f "hi\nwould"
+ flush $f
+ gets $f
+ fconfigure $f -blocking 0
+ set x [gets $f line]
+ close $f
+ set x
+} {-1}
+test io-6.8 {Tcl_GetsObj: remember if EOF is seen} {
+ set f [open $path(test1) w]
+ puts $f "abcdef\x1aghijk\nwombat"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -eofchar \x1a
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {6 abcdef -1 {}}
+test io-6.9 {Tcl_GetsObj: remember if EOF is seen} {
+ set f [open $path(test1) w]
+ puts $f "abcdefghijk\nwom\u001abat"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -eofchar \x1a
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {11 abcdefghijk 3 wom}
+# Comprehensive tests
+test io-6.10 {Tcl_GetsObj: lf mode: no chars} {
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation lf
+ set x [list [gets $f line] $line]
+ close $f
+ set x
+} {-1 {}}
+test io-6.11 {Tcl_GetsObj: lf mode: lone \n} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation lf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {0 {} -1 {}}
+test io-6.12 {Tcl_GetsObj: lf mode: lone \r} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation lf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 1 "\r" -1 ""]
+test io-6.13 {Tcl_GetsObj: lf mode: 1 char} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f a
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation lf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {1 a -1 {}}
+test io-6.14 {Tcl_GetsObj: lf mode: 1 char followed by EOL} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation lf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {1 a -1 {}}
+test io-6.15 {Tcl_GetsObj: lf mode: several chars} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation lf
+ set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 4 "abcd" 10 "efgh\rijkl\r" 4 "mnop" -1 ""]
+test io-6.16 {Tcl_GetsObj: cr mode: no chars} {
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation cr
+ set x [list [gets $f line] $line]
+ close $f
+ set x
+} {-1 {}}
+test io-6.17 {Tcl_GetsObj: cr mode: lone \n} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation cr
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 1 "\n" -1 ""]
+test io-6.18 {Tcl_GetsObj: cr mode: lone \r} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation cr
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {0 {} -1 {}}
+test io-6.19 {Tcl_GetsObj: cr mode: 1 char} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f a
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation cr
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {1 a -1 {}}
+test io-6.20 {Tcl_GetsObj: cr mode: 1 char followed by EOL} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation cr
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {1 a -1 {}}
+test io-6.21 {Tcl_GetsObj: cr mode: several chars} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation cr
+ set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 9 "abcd\nefgh" 4 "ijkl" 5 "\nmnop" -1 ""]
+test io-6.22 {Tcl_GetsObj: crlf mode: no chars} {
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [list [gets $f line] $line]
+ close $f
+ set x
+} {-1 {}}
+test io-6.23 {Tcl_GetsObj: crlf mode: lone \n} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 1 "\n" -1 ""]
+test io-6.24 {Tcl_GetsObj: crlf mode: lone \r} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 1 "\r" -1 ""]
+test io-6.25 {Tcl_GetsObj: crlf mode: \r\r} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 2 "\r\r" -1 ""]
+test io-6.26 {Tcl_GetsObj: crlf mode: \r\n} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 0 "" -1 ""]
+test io-6.27 {Tcl_GetsObj: crlf mode: 1 char} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f a
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {1 a -1 {}}
+test io-6.28 {Tcl_GetsObj: crlf mode: 1 char followed by EOL} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\r\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {1 a -1 {}}
+test io-6.29 {Tcl_GetsObj: crlf mode: several chars} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 14 "abcd\nefgh\rijkl" 4 "mnop" -1 ""]
+test io-6.30 {Tcl_GetsObj: crlf mode: buffer exhausted} {testchannel} {
+ # if (eol >= dstEnd)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456789012345\r\nabcdefghijklmnoprstuvwxyz"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf -buffersize 16
+ set x [list [gets $f line] $line [testchannel inputbuffered $f]]
+ close $f
+ set x
+} [list 15 "123456789012345" 15]
+test io-6.31 {Tcl_GetsObj: crlf mode: buffer exhausted, blocked} {stdio testchannel openpipe fileevent} {
+ # (FilterInputBytes() != 0)
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {crlf lf} -buffering none
+ puts -nonewline $f "bbbbbbbbbbbbbb\r\n123456789012345\r"
+ fconfigure $f -buffersize 16
+ set x [gets $f]
+ fconfigure $f -blocking 0
+ lappend x [gets $f line] $line [fblocked $f] [testchannel inputbuffered $f]
+ close $f
+ set x
+} [list "bbbbbbbbbbbbbb" -1 "" 1 16]
+test io-6.32 {Tcl_GetsObj: crlf mode: buffer exhausted, more data} {testchannel} {
+ # not (FilterInputBytes() != 0)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456789012345\r\n123"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf -buffersize 16
+ set x [list [gets $f line] $line [tell $f] [testchannel inputbuffered $f]]
+ close $f
+ set x
+} [list 15 "123456789012345" 17 3]
+test io-6.33 {Tcl_GetsObj: crlf mode: buffer exhausted, at eof} {
+ # eol still equals dstEnd
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456789012345\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf -buffersize 16
+ set x [list [gets $f line] $line [eof $f]]
+ close $f
+ set x
+} [list 16 "123456789012345\r" 1]
+test io-6.34 {Tcl_GetsObj: crlf mode: buffer exhausted, not followed by \n} {
+ # not (*eol == '\n')
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456789012345\rabcd\r\nefg"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf -buffersize 16
+ set x [list [gets $f line] $line [tell $f]]
+ close $f
+ set x
+} [list 20 "123456789012345\rabcd" 22]
+test io-6.35 {Tcl_GetsObj: auto mode: no chars} {
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [gets $f line] $line]
+ close $f
+ set x
+} {-1 {}}
+test io-6.36 {Tcl_GetsObj: auto mode: lone \n} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 0 "" -1 ""]
+test io-6.37 {Tcl_GetsObj: auto mode: lone \r} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 0 "" -1 ""]
+test io-6.38 {Tcl_GetsObj: auto mode: \r\r} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 0 "" 0 "" -1 ""]
+test io-6.39 {Tcl_GetsObj: auto mode: \r\n} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 0 "" -1 ""]
+test io-6.40 {Tcl_GetsObj: auto mode: 1 char} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f a
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {1 a -1 {}}
+test io-6.41 {Tcl_GetsObj: auto mode: 1 char followed by EOL} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\r\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} {1 a -1 {}}
+test io-6.42 {Tcl_GetsObj: auto mode: several chars} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [gets $f line] $line [gets $f line] $line]
+ lappend x [gets $f line] $line [gets $f line] $line [gets $f line] $line
+ close $f
+ set x
+} [list 4 "abcd" 4 "efgh" 4 "ijkl" 4 "mnop" -1 ""]
+test io-6.43 {Tcl_GetsObj: input saw cr} {stdio testchannel openpipe fileevent} {
+ # if (chanPtr->flags & INPUT_SAW_CR)
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {auto lf} -buffering none
+ puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+ fconfigure $f -buffersize 16
+ set x [list [gets $f]]
+ fconfigure $f -blocking 0
+ lappend x [gets $f line] $line [testchannel queuedcr $f]
+ fconfigure $f -blocking 1
+ puts -nonewline $f "\nabcd\refg\x1a"
+ lappend x [gets $f line] $line [testchannel queuedcr $f]
+ lappend x [gets $f line] $line
+ close $f
+ set x
+} [list "bbbbbbbbbbbbbbb" 15 "123456789abcdef" 1 4 "abcd" 0 3 "efg"]
+test io-6.44 {Tcl_GetsObj: input saw cr, not followed by cr} {stdio testchannel openpipe fileevent} {
+ # not (*eol == '\n')
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {auto lf} -buffering none
+ puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+ fconfigure $f -buffersize 16
+ set x [list [gets $f]]
+ fconfigure $f -blocking 0
+ lappend x [gets $f line] $line [testchannel queuedcr $f]
+ fconfigure $f -blocking 1
+ puts -nonewline $f "abcd\refg\x1a"
+ lappend x [gets $f line] $line [testchannel queuedcr $f]
+ lappend x [gets $f line] $line
+ close $f
+ set x
+} [list "bbbbbbbbbbbbbbb" 15 "123456789abcdef" 1 4 "abcd" 0 3 "efg"]
+test io-6.45 {Tcl_GetsObj: input saw cr, skip right number of bytes} {stdio testchannel openpipe fileevent} {
+ # Tcl_ExternalToUtf()
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {auto lf} -buffering none
+ fconfigure $f -encoding unicode
+ puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+ fconfigure $f -buffersize 16
+ gets $f
+ fconfigure $f -blocking 0
+ set x [list [gets $f line] $line [testchannel queuedcr $f]]
+ fconfigure $f -blocking 1
+ puts -nonewline $f "\nabcd\refg"
+ lappend x [gets $f line] $line [testchannel queuedcr $f]
+ close $f
+ set x
+} [list 15 "123456789abcdef" 1 4 "abcd" 0]
+test io-6.46 {Tcl_GetsObj: input saw cr, followed by just \n should give eof} {stdio testchannel openpipe fileevent} {
+ # memmove()
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {auto lf} -buffering none
+ puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+ fconfigure $f -buffersize 16
+ gets $f
+ fconfigure $f -blocking 0
+ set x [list [gets $f line] $line [testchannel queuedcr $f]]
+ fconfigure $f -blocking 1
+ puts -nonewline $f "\n\x1a"
+ lappend x [gets $f line] $line [testchannel queuedcr $f]
+ close $f
+ set x
+} [list 15 "123456789abcdef" 1 -1 "" 0]
+test io-6.47 {Tcl_GetsObj: auto mode: \r at end of buffer, peek for \n} {testchannel} {
+ # (eol == dstEnd)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456789012345\r\nabcdefghijklmnopq"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto -buffersize 16
+ set x [list [gets $f] [testchannel inputbuffered $f]]
+ close $f
+ set x
+} [list "123456789012345" 15]
+test io-6.48 {Tcl_GetsObj: auto mode: \r at end of buffer, no more avail} {testchannel} {
+ # PeekAhead() did not get any, so (eol >= dstEnd)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456789012345\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto -buffersize 16
+ set x [list [gets $f] [testchannel queuedcr $f]]
+ close $f
+ set x
+} [list "123456789012345" 1]
+test io-6.49 {Tcl_GetsObj: auto mode: \r followed by \n} {testchannel} {
+ # if (*eol == '\n') {skip++}
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456\r\n78901"
+ close $f
+ set f [open $path(test1)]
+ set x [list [gets $f] [testchannel queuedcr $f] [tell $f] [gets $f]]
+ close $f
+ set x
+} [list "123456" 0 8 "78901"]
+test io-6.50 {Tcl_GetsObj: auto mode: \r not followed by \n} {testchannel} {
+ # not (*eol == '\n')
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456\r78901"
+ close $f
+ set f [open $path(test1)]
+ set x [list [gets $f] [testchannel queuedcr $f] [tell $f] [gets $f]]
+ close $f
+ set x
+} [list "123456" 0 7 "78901"]
+test io-6.51 {Tcl_GetsObj: auto mode: \n} {
+ # else if (*eol == '\n') {goto gotoeol;}
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456\n78901"
+ close $f
+ set f [open $path(test1)]
+ set x [list [gets $f] [tell $f] [gets $f]]
+ close $f
+ set x
+} [list "123456" 7 "78901"]
+test io-6.52 {Tcl_GetsObj: saw EOF character} {testchannel} {
+ # if (eof != NULL)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "123456\x1ak9012345\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -eofchar \x1a
+ set x [list [gets $f] [testchannel queuedcr $f] [tell $f] [gets $f]]
+ close $f
+ set x
+} [list "123456" 0 6 ""]
+test io-6.53 {Tcl_GetsObj: device EOF} {
+ # didn't produce any bytes
+
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1)]
+ set x [list [gets $f line] $line [eof $f]]
+ close $f
+ set x
+} {-1 {} 1}
+test io-6.54 {Tcl_GetsObj: device EOF} {
+ # got some bytes before EOF.
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abc
+ close $f
+ set f [open $path(test1)]
+ set x [list [gets $f line] $line [eof $f]]
+ close $f
+ set x
+} {3 abc 1}
+test io-6.55 {Tcl_GetsObj: overconverted} {
+ # Tcl_ExternalToUtf(), make sure state updated
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding iso2022-jp
+ puts $f "there\u4e00ok\n\u4e01more bytes\nhere"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding iso2022-jp
+ set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line]
+ close $f
+ set x
+} [list 8 "there\u4e00ok" 11 "\u4e01more bytes" 4 "here"]
+test io-6.56 {Tcl_GetsObj: incomplete lines should disable file events} {stdio openpipe fileevent} {
+ update
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -buffering none
+ puts -nonewline $f "foobar"
+ fconfigure $f -blocking 0
+ variable x {}
+ after 500 [namespace code { lappend x timeout }]
+ fileevent $f readable [namespace code { lappend x [gets $f] }]
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ fconfigure $f -blocking 1
+ puts -nonewline $f "baz\n"
+ after 500 [namespace code { lappend x timeout }]
+ fconfigure $f -blocking 0
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ close $f
+ set x
+} {{} timeout foobarbaz timeout}
+
+test io-7.1 {FilterInputBytes: split up character at end of buffer} {
+ # (result == TCL_CONVERT_MULTIBYTE)
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding shiftjis
+ puts $f "1234567890123\uff10\uff11\uff12\uff13\uff14\nend"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding shiftjis -buffersize 16
+ set x [gets $f]
+ close $f
+ set x
+} "1234567890123\uff10\uff11\uff12\uff13\uff14"
+test io-7.2 {FilterInputBytes: split up character in middle of buffer} {
+ # (bufPtr->nextAdded < bufPtr->bufLength)
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding binary
+ puts -nonewline $f "1234567890\n123\x82\x4f\x82\x50\x82"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding shiftjis
+ set x [list [gets $f line] $line [eof $f]]
+ close $f
+ set x
+} [list 10 "1234567890" 0]
+test io-7.3 {FilterInputBytes: split up character at EOF} {testchannel} {
+ set f [open $path(test1) w]
+ fconfigure $f -encoding binary
+ puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding shiftjis
+ set x [list [gets $f line] $line]
+ lappend x [tell $f] [testchannel inputbuffered $f] [eof $f]
+ lappend x [gets $f line] $line
+ close $f
+ set x
+} [list 15 "1234567890123\uff10\uff11" 18 0 1 -1 ""]
+test io-7.4 {FilterInputBytes: recover from split up character} {stdio openpipe fileevent} {
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -encoding binary -buffering none
+ puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
+ fconfigure $f -encoding shiftjis -blocking 0
+ fileevent $f read [namespace code "ready $f"]
+ variable x {}
+ proc ready {f} {
+ variable x
+ lappend x [gets $f line] $line [fblocked $f]
+ }
+ vwait [namespace which -variable x]
+ fconfigure $f -encoding binary -blocking 1
+ puts $f "\x51\x82\x52"
+ fconfigure $f -encoding shiftjis
+ vwait [namespace which -variable x]
+ close $f
+ set x
+} [list -1 "" 1 17 "1234567890123\uff10\uff11\uff12\uff13" 0]
+
+test io-8.1 {PeekAhead: only go to device if no more cached data} {testchannel} {
+ # (bufPtr->nextPtr == NULL)
+
+ set f [open $path(test1) w]
+ fconfigure $f -encoding ascii -translation lf
+ puts -nonewline $f "123456789012345\r\n2345678"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding ascii -translation auto -buffersize 16
+ # here
+ gets $f
+ set x [testchannel inputbuffered $f]
+ close $f
+ set x
+} "7"
+test io-8.2 {PeekAhead: only go to device if no more cached data} {stdio testchannel openpipe fileevent} {
+ # not (bufPtr->nextPtr == NULL)
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation lf -encoding ascii -buffering none
+ puts -nonewline $f "123456789012345\r\nbcdefghijklmnopqrstuvwxyz"
+ variable x {}
+ fileevent $f read [namespace code "ready $f"]
+ proc ready {f} {
+ variable x
+ lappend x [gets $f line] $line [testchannel inputbuffered $f]
+ }
+ fconfigure $f -encoding unicode -buffersize 16 -blocking 0
+ vwait [namespace which -variable x]
+ fconfigure $f -translation auto -encoding ascii -blocking 1
+ # here
+ vwait [namespace which -variable x]
+ close $f
+ set x
+} [list -1 "" 42 15 "123456789012345" 25]
+test io-8.3 {PeekAhead: no cached data available} {stdio testchannel openpipe fileevent} {
+ # (bytesLeft == 0)
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {auto binary}
+ puts -nonewline $f "abcdefghijklmno\r"
+ flush $f
+ set x [list [gets $f line] $line [testchannel queuedcr $f]]
+ close $f
+ set x
+} [list 15 "abcdefghijklmno" 1]
+set a "123456789012345678901234567890"
+append a "123456789012345678901234567890"
+append a "1234567890123456789012345678901"
+test io-8.4 {PeekAhead: cached data available in this buffer} {
+ # not (bytesLeft == 0)
+
+ set f [open $path(test1) w+]
+ fconfigure $f -translation binary
+ puts $f "${a}\r\nabcdef"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding binary -translation auto
+
+ # "${a}\r" was converted in one operation (because ENCODING_LINESIZE
+ # is 30). To check if "\n" follows, calls PeekAhead and determines
+ # that cached data is available in buffer w/o having to call driver.
+
+ set x [gets $f]
+ close $f
+ set x
+} $a
+unset a
+test io-8.5 {PeekAhead: don't peek if last read was short} {stdio testchannel openpipe fileevent} {
+ # (bufPtr->nextAdded < bufPtr->length)
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {auto binary}
+ puts -nonewline $f "abcdefghijklmno\r"
+ flush $f
+ # here
+ set x [list [gets $f line] $line [testchannel queuedcr $f]]
+ close $f
+ set x
+} {15 abcdefghijklmno 1}
+test io-8.6 {PeekAhead: change to non-blocking mode} {stdio testchannel openpipe fileevent} {
+ # ((chanPtr->flags & CHANNEL_NONBLOCKING) == 0)
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {auto binary} -buffersize 16
+ puts -nonewline $f "abcdefghijklmno\r"
+ flush $f
+ # here
+ set x [list [gets $f line] $line [testchannel queuedcr $f]]
+ close $f
+ set x
+} {15 abcdefghijklmno 1}
+test io-8.7 {PeekAhead: cleanup} {stdio testchannel openpipe fileevent} {
+ # Make sure bytes are removed from buffer.
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -translation {auto binary} -buffering none
+ puts -nonewline $f "abcdefghijklmno\r"
+ # here
+ set x [list [gets $f line] $line [testchannel queuedcr $f]]
+ puts -nonewline $f "\x1a"
+ lappend x [gets $f line] $line
+ close $f
+ set x
+} {15 abcdefghijklmno 1 -1 {}}
+
+test io-9.1 {CommonGetsCleanup} emptyTest {
+} {}
+
+test io-10.1 {Tcl_ReadChars: CheckChannelErrors} emptyTest {
+ # no test, need to cause an async error.
+} {}
+test io-10.2 {Tcl_ReadChars: loop until enough copied} {
+ # one time
+ # for (copied = 0; (unsigned) toRead > 0; )
+
+ set f [open $path(test1) w]
+ puts $f abcdefghijklmnop
+ close $f
+
+ set f [open $path(test1)]
+ set x [read $f 5]
+ close $f
+ set x
+} {abcde}
+test io-10.3 {Tcl_ReadChars: loop until enough copied} {
+ # multiple times
+ # for (copied = 0; (unsigned) toRead > 0; )
+
+ set f [open $path(test1) w]
+ puts $f abcdefghijklmnopqrstuvwxyz
+ close $f
+
+ set f [open $path(test1)]
+ fconfigure $f -buffersize 16
+ # here
+ set x [read $f 19]
+ close $f
+ set x
+} {abcdefghijklmnopqrs}
+test io-10.4 {Tcl_ReadChars: no more in channel buffer} {
+ # (copiedNow < 0)
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abcdefghijkl
+ close $f
+
+ set f [open $path(test1)]
+ # here
+ set x [read $f 1000]
+ close $f
+ set x
+} {abcdefghijkl}
+test io-10.5 {Tcl_ReadChars: stop on EOF} {
+ # (chanPtr->flags & CHANNEL_EOF)
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abcdefghijkl
+ close $f
+
+ set f [open $path(test1)]
+ # here
+ set x [read $f 1000]
+ close $f
+ set x
+} {abcdefghijkl}
+
+test io-11.1 {ReadBytes: want to read a lot} {
+ # ((unsigned) toRead > (unsigned) srcLen)
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abcdefghijkl
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding binary
+ # here
+ set x [read $f 1000]
+ close $f
+ set x
+} {abcdefghijkl}
+test io-11.2 {ReadBytes: want to read all} {
+ # ((unsigned) toRead > (unsigned) srcLen)
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abcdefghijkl
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -encoding binary
+ # here
+ set x [read $f]
+ close $f
+ set x
+} {abcdefghijkl}
+test io-11.3 {ReadBytes: allocate more space} {
+ # (toRead > length - offset - 1)
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abcdefghijklmnopqrstuvwxyz
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -buffersize 16 -encoding binary
+ # here
+ set x [read $f]
+ close $f
+ set x
+} {abcdefghijklmnopqrstuvwxyz}
+test io-11.4 {ReadBytes: EOF char found} {
+ # (TranslateInputEOL() != 0)
+
+ set f [open $path(test1) w]
+ puts $f abcdefghijklmnopqrstuvwxyz
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -eofchar m -encoding binary
+ # here
+ set x [list [read $f] [eof $f] [read $f] [eof $f]]
+ close $f
+ set x
+} [list "abcdefghijkl" 1 "" 1]
+
+test io-12.1 {ReadChars: want to read a lot} {
+ # ((unsigned) toRead > (unsigned) srcLen)
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abcdefghijkl
+ close $f
+ set f [open $path(test1)]
+ # here
+ set x [read $f 1000]
+ close $f
+ set x
+} {abcdefghijkl}
+test io-12.2 {ReadChars: want to read all} {
+ # ((unsigned) toRead > (unsigned) srcLen)
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abcdefghijkl
+ close $f
+ set f [open $path(test1)]
+ # here
+ set x [read $f]
+ close $f
+ set x
+} {abcdefghijkl}
+test io-12.3 {ReadChars: allocate more space} {
+ # (toRead > length - offset - 1)
+
+ set f [open $path(test1) w]
+ puts -nonewline $f abcdefghijklmnopqrstuvwxyz
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -buffersize 16
+ # here
+ set x [read $f]
+ close $f
+ set x
+} {abcdefghijklmnopqrstuvwxyz}
+test io-12.4 {ReadChars: split-up char} {stdio testchannel openpipe fileevent} {
+ # (srcRead == 0)
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -encoding binary -buffering none -buffersize 16
+ puts -nonewline $f "123456789012345\x96"
+ fconfigure $f -encoding shiftjis -blocking 0
+
+ fileevent $f read [namespace code "ready $f"]
+ proc ready {f} {
+ variable x
+ lappend x [read $f] [testchannel inputbuffered $f]
+ }
+ variable x {}
+
+ fconfigure $f -encoding shiftjis
+ vwait [namespace which -variable x]
+ fconfigure $f -encoding binary -blocking 1
+ puts -nonewline $f "\x7b"
+ after 500 ;# Give the cat process time to catch up
+ fconfigure $f -encoding shiftjis -blocking 0
+ vwait [namespace which -variable x]
+ close $f
+ set x
+} [list "123456789012345" 1 "\u672c" 0]
+test io-12.5 {ReadChars: fileevents on partial characters} {stdio openpipe fileevent} {
+ set path(test1) [makeFile {
+ fconfigure stdout -encoding binary -buffering none
+ gets stdin; puts -nonewline "\xe7"
+ gets stdin; puts -nonewline "\x89"
+ gets stdin; puts -nonewline "\xa6"
+ } test1]
+ set f [open "|[list [interpreter] $path(test1)]" r+]
+ fileevent $f readable [namespace code {
+ lappend x [read $f]
+ if {[eof $f]} {
+ lappend x eof
+ }
+ }]
+ puts $f "go1"
+ flush $f
+ fconfigure $f -blocking 0 -encoding utf-8
+ variable x {}
+ vwait [namespace which -variable x]
+ after 500 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ puts $f "go2"
+ flush $f
+ vwait [namespace which -variable x]
+ after 500 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ puts $f "go3"
+ flush $f
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ lappend x [catch {close $f} msg] $msg
+ set x
+} "{} timeout {} timeout \u7266 {} eof 0 {}"
+
+test io-13.1 {TranslateInputEOL: cr mode} {} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\rdef\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation cr
+ set x [read $f]
+ close $f
+ set x
+} "abcd\ndef\n"
+test io-13.2 {TranslateInputEOL: crlf mode} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\r\ndef\r\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [read $f]
+ close $f
+ set x
+} "abcd\ndef\n"
+test io-13.3 {TranslateInputEOL: crlf mode: naked cr} {
+ # (src >= srcMax)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\r\ndef\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [read $f]
+ close $f
+ set x
+} "abcd\ndef\r"
+test io-13.4 {TranslateInputEOL: crlf mode: cr followed by not \n} {
+ # (src >= srcMax)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\r\ndef\rfgh"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [read $f]
+ close $f
+ set x
+} "abcd\ndef\rfgh"
+test io-13.5 {TranslateInputEOL: crlf mode: naked lf} {
+ # (src >= srcMax)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\r\ndef\nfgh"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation crlf
+ set x [read $f]
+ close $f
+ set x
+} "abcd\ndef\nfgh"
+test io-13.6 {TranslateInputEOL: auto mode: saw cr in last segment} {stdio testchannel openpipe fileevent} {
+ # (chanPtr->flags & INPUT_SAW_CR)
+ # This test may fail on slower machines.
+
+ set f [open "|[list [interpreter] $path(cat)]" w+]
+ fconfigure $f -blocking 0 -buffering none -translation {auto lf}
+
+ fileevent $f read [namespace code "ready $f"]
+ proc ready {f} {
+ variable x
+ lappend x [read $f] [testchannel queuedcr $f]
+ }
+ variable x {}
+ variable y {}
+
+ puts -nonewline $f "abcdefghj\r"
+ after 500 [namespace code {set y ok}]
+ vwait [namespace which -variable y]
+
+ puts -nonewline $f "\n01234"
+ after 500 [namespace code {set y ok}]
+ vwait [namespace which -variable y]
+
+ close $f
+ set x
+} [list "abcdefghj\n" 1 "01234" 0]
+test io-13.7 {TranslateInputEOL: auto mode: naked \r} {testchannel openpipe} {
+ # (src >= srcMax)
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\r"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [list [read $f] [testchannel queuedcr $f]]
+ close $f
+ set x
+} [list "abcd\n" 1]
+test io-13.8 {TranslateInputEOL: auto mode: \r\n} {
+ # (*src == '\n')
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\r\ndef"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [read $f]
+ close $f
+ set x
+} "abcd\ndef"
+test io-13.9 {TranslateInputEOL: auto mode: \r followed by not \n} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\rdef"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [read $f]
+ close $f
+ set x
+} "abcd\ndef"
+test io-13.10 {TranslateInputEOL: auto mode: \n} {
+ # not (*src == '\r')
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\ndef"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto
+ set x [read $f]
+ close $f
+ set x
+} "abcd\ndef"
+test io-13.11 {TranslateInputEOL: EOF char} {
+ # (*chanPtr->inEofChar != '\0')
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "abcd\ndefgh"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto -eofchar e
+ set x [read $f]
+ close $f
+ set x
+} "abcd\nd"
+test io-13.12 {TranslateInputEOL: find EOF char in src} {
+ # (*chanPtr->inEofChar != '\0')
+
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "\r\n\r\n\r\nab\r\n\r\ndef\r\n\r\n\r\n"
+ close $f
+ set f [open $path(test1)]
+ fconfigure $f -translation auto -eofchar e
+ set x [read $f]
+ close $f
+ set x
+} "\n\n\nab\n\nd"
+
+# Test standard handle management. The functions tested are
+# Tcl_SetStdChannel and Tcl_GetStdChannel. Incidentally we are
+# also testing channel table management.
+
+if {[info commands testchannel] != ""} {
+ set consoleFileNames [lsort [testchannel open]]
+} else {
+ # just to avoid an error
+ set consoleFileNames [list]
+}
+
+test io-14.1 {Tcl_SetStdChannel and Tcl_GetStdChannel} {testchannel} {
+ set l ""
+ lappend l [fconfigure stdin -buffering]
+ lappend l [fconfigure stdout -buffering]
+ lappend l [fconfigure stderr -buffering]
+ lappend l [lsort [testchannel open]]
+ set l
+} [list line line none $consoleFileNames]
+test io-14.2 {Tcl_SetStdChannel and Tcl_GetStdChannel} {
+ interp create x
+ set l ""
+ lappend l [x eval {fconfigure stdin -buffering}]
+ lappend l [x eval {fconfigure stdout -buffering}]
+ lappend l [x eval {fconfigure stderr -buffering}]
+ interp delete x
+ set l
+} {line line none}
+set path(test3) [makeFile {} test3]
+test io-14.3 {Tcl_SetStdChannel & Tcl_GetStdChannel} {exec openpipe} {
+ set f [open $path(test1) w]
+ puts -nonewline $f {
+ close stdin
+ close stdout
+ close stderr
+ set f [}
+ puts $f [list open $path(test1) r]]
+ puts $f "set f2 \[[list open $path(test2) w]]"
+ puts $f "set f3 \[[list open $path(test3) w]]"
+ puts $f { puts stdout [gets stdin]
+ puts stdout out
+ puts stderr err
+ close $f
+ close $f2
+ close $f3
+ }
+ close $f
+ set result [exec [interpreter] $path(test1)]
+ set f [open $path(test2) r]
+ set f2 [open $path(test3) r]
+ lappend result [read $f] [read $f2]
+ close $f
+ close $f2
+ set result
+} {{
+out
+} {err
+}}
+# This test relies on the fact that stdout is used before stderr
+test io-14.4 {Tcl_SetStdChannel & Tcl_GetStdChannel} {exec} {
+ set f [open $path(test1) w]
+ puts -nonewline $f { close stdin
+ close stdout
+ close stderr
+ set f [}
+ puts $f [list open $path(test1) r]]
+ puts $f "set f2 \[[list open $path(test2) w]]"
+ puts $f "set f3 \[[list open $path(test3) w]]"
+ puts $f { puts stdout [gets stdin]
+ puts stdout $f2
+ puts stderr $f3
+ close $f
+ close $f2
+ close $f3
+ }
+ close $f
+ set result [exec [interpreter] $path(test1)]
+ set f [open $path(test2) r]
+ set f2 [open $path(test3) r]
+ lappend result [read $f] [read $f2]
+ close $f
+ close $f2
+ set result
+} {{ close stdin
+stdout
+} {stderr
+}}
+catch {interp delete z}
+test io-14.5 {Tcl_GetChannel: stdio name translation} {
+ interp create z
+ eof stdin
+ catch {z eval flush stdin} msg1
+ catch {z eval close stdin} msg2
+ catch {z eval flush stdin} msg3
+ set result [list $msg1 $msg2 $msg3]
+ interp delete z
+ set result
+} {{channel "stdin" wasn't opened for writing} {} {can not find channel named "stdin"}}
+test io-14.6 {Tcl_GetChannel: stdio name translation} {
+ interp create z
+ eof stdout
+ catch {z eval flush stdout} msg1
+ catch {z eval close stdout} msg2
+ catch {z eval flush stdout} msg3
+ set result [list $msg1 $msg2 $msg3]
+ interp delete z
+ set result
+} {{} {} {can not find channel named "stdout"}}
+test io-14.7 {Tcl_GetChannel: stdio name translation} {
+ interp create z
+ eof stderr
+ catch {z eval flush stderr} msg1
+ catch {z eval close stderr} msg2
+ catch {z eval flush stderr} msg3
+ set result [list $msg1 $msg2 $msg3]
+ interp delete z
+ set result
+} {{} {} {can not find channel named "stderr"}}
+set path(script) [makeFile {} script]
+test io-14.8 {reuse of stdio special channels} {stdio openpipe} {
+ file delete $path(script)
+ file delete $path(test1)
+ set f [open $path(script) w]
+ puts -nonewline $f {
+ close stderr
+ set f [}
+ puts $f [list open $path(test1) w]]
+ puts -nonewline $f {
+ puts stderr hello
+ close $f
+ set f [}
+ puts $f [list open $path(test1) r]]
+ puts $f {
+ puts [gets $f]
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ set c [gets $f]
+ close $f
+ set c
+} hello
+test io-14.9 {reuse of stdio special channels} {stdio openpipe fileevent} {
+ file delete $path(script)
+ file delete $path(test1)
+ set f [open $path(script) w]
+ puts $f {
+ array set path [lindex $argv 0]
+ set f [open $path(test1) w]
+ puts $f hello
+ close $f
+ close stderr
+ set f [open "|[list [info nameofexecutable] $path(cat) $path(test1)]" r]
+ puts [gets $f]
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script) [array get path]]" r]
+ set c [gets $f]
+ close $f
+ # Added delay to give Windows time to stop the spawned process and clean
+ # up its grip on the file test1. Added delete as proper test cleanup.
+ # The failing tests were 18.1 and 18.2 as first re-users of file "test1".
+ after 10000
+ file delete $path(script)
+ file delete $path(test1)
+ set c
+} hello
+
+test io-15.1 {Tcl_CreateCloseHandler} emptyTest {
+} {}
+
+test io-16.1 {Tcl_DeleteCloseHandler} emptyTest {
+} {}
+
+# Test channel table management. The functions tested are
+# GetChannelTable, DeleteChannelTable, Tcl_RegisterChannel,
+# Tcl_UnregisterChannel, Tcl_GetChannel and Tcl_CreateChannel.
+#
+# These functions use "eof stdin" to ensure that the standard
+# channels are added to the channel table of the interpreter.
+
+test io-17.1 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} {
+ set l1 [testchannel refcount stdin]
+ eof stdin
+ interp create x
+ set l ""
+ lappend l [expr [testchannel refcount stdin] - $l1]
+ x eval {eof stdin}
+ lappend l [expr [testchannel refcount stdin] - $l1]
+ interp delete x
+ lappend l [expr [testchannel refcount stdin] - $l1]
+ set l
+} {0 1 0}
+test io-17.2 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} {
+ set l1 [testchannel refcount stdout]
+ eof stdin
+ interp create x
+ set l ""
+ lappend l [expr [testchannel refcount stdout] - $l1]
+ x eval {eof stdout}
+ lappend l [expr [testchannel refcount stdout] - $l1]
+ interp delete x
+ lappend l [expr [testchannel refcount stdout] - $l1]
+ set l
+} {0 1 0}
+test io-17.3 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} {
+ set l1 [testchannel refcount stderr]
+ eof stdin
+ interp create x
+ set l ""
+ lappend l [expr [testchannel refcount stderr] - $l1]
+ x eval {eof stderr}
+ lappend l [expr [testchannel refcount stderr] - $l1]
+ interp delete x
+ lappend l [expr [testchannel refcount stderr] - $l1]
+ set l
+} {0 1 0}
+
+test io-18.1 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {testchannel} {
+ file delete -force $path(test1)
+ set l ""
+ set f [open $path(test1) w]
+ lappend l [lindex [testchannel info $f] 15]
+ close $f
+ if {[catch {lindex [testchannel info $f] 15} msg]} {
+ lappend l $msg
+ } else {
+ lappend l "very broken: $f found after being closed"
+ }
+ string compare [string tolower $l] \
+ [list 1 [format "can not find channel named \"%s\"" $f]]
+} 0
+test io-18.2 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {testchannel} {
+ file delete -force $path(test1)
+ set l ""
+ set f [open $path(test1) w]
+ lappend l [lindex [testchannel info $f] 15]
+ interp create x
+ interp share "" $f x
+ lappend l [lindex [testchannel info $f] 15]
+ x eval close $f
+ lappend l [lindex [testchannel info $f] 15]
+ interp delete x
+ lappend l [lindex [testchannel info $f] 15]
+ close $f
+ if {[catch {lindex [testchannel info $f] 15} msg]} {
+ lappend l $msg
+ } else {
+ lappend l "very broken: $f found after being closed"
+ }
+ string compare [string tolower $l] \
+ [list 1 2 1 1 [format "can not find channel named \"%s\"" $f]]
+} 0
+test io-18.3 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {testchannel} {
+ file delete $path(test1)
+ set l ""
+ set f [open $path(test1) w]
+ lappend l [lindex [testchannel info $f] 15]
+ interp create x
+ interp share "" $f x
+ lappend l [lindex [testchannel info $f] 15]
+ interp delete x
+ lappend l [lindex [testchannel info $f] 15]
+ close $f
+ if {[catch {lindex [testchannel info $f] 15} msg]} {
+ lappend l $msg
+ } else {
+ lappend l "very broken: $f found after being closed"
+ }
+ string compare [string tolower $l] \
+ [list 1 2 1 [format "can not find channel named \"%s\"" $f]]
+} 0
+
+test io-19.1 {Tcl_GetChannel->Tcl_GetStdChannel, standard handles} {
+ eof stdin
+} 0
+test io-19.2 {testing Tcl_GetChannel, user opened handle} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ set x [eof $f]
+ close $f
+ set x
+} 0
+test io-19.3 {Tcl_GetChannel, channel not found} {
+ list [catch {eof file34} msg] $msg
+} {1 {can not find channel named "file34"}}
+test io-19.4 {Tcl_CreateChannel, insertion into channel table} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ set l ""
+ lappend l [eof $f]
+ close $f
+ if {[catch {lindex [testchannel info $f] 15} msg]} {
+ lappend l $msg
+ } else {
+ lappend l "very broken: $f found after being closed"
+ }
+ string compare [string tolower $l] \
+ [list 0 [format "can not find channel named \"%s\"" $f]]
+} 0
+
+test io-20.1 {Tcl_CreateChannel: initial settings} {
+ set a [open $path(test2) w]
+ set old [encoding system]
+ encoding system ascii
+ set f [open $path(test1) w]
+ set x [fconfigure $f -encoding]
+ close $f
+ encoding system $old
+ close $a
+ set x
+} {ascii}
+test io-20.2 {Tcl_CreateChannel: initial settings} {win} {
+ set f [open $path(test1) w+]
+ set x [list [fconfigure $f -eofchar] [fconfigure $f -translation]]
+ close $f
+ set x
+} [list [list \x1a ""] {auto crlf}]
+test io-20.3 {Tcl_CreateChannel: initial settings} {unix} {
+ set f [open $path(test1) w+]
+ set x [list [fconfigure $f -eofchar] [fconfigure $f -translation]]
+ close $f
+ set x
+} {{{} {}} {auto lf}}
+set path(stdout) [makeFile {} stdout]
+test io-20.5 {Tcl_CreateChannel: install channel in empty slot} {stdio openpipe} {
+ set f [open $path(script) w]
+ puts -nonewline $f {
+ close stdout
+ set f1 [}
+ puts $f [list open $path(stdout) w]]
+ puts $f {
+ fconfigure $f1 -buffersize 777
+ puts stderr [fconfigure stdout -buffersize]
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]"]
+ catch {close $f} msg
+ set msg
+} {777}
+
+test io-21.1 {CloseChannelsOnExit} emptyTest {
+} {}
+
+# Test management of attributes associated with a channel, such as
+# its default translation, its name and type, etc. The functions
+# tested in this group are Tcl_GetChannelName,
+# Tcl_GetChannelType and Tcl_GetChannelFile. Tcl_GetChannelInstanceData
+# not tested because files do not use the instance data.
+
+test io-22.1 {Tcl_GetChannelMode} emptyTest {
+ # Not used anywhere in Tcl.
+} {}
+
+test io-23.1 {Tcl_GetChannelName} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ set n [testchannel name $f]
+ close $f
+ string compare $n $f
+} 0
+
+test io-24.1 {Tcl_GetChannelType} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ set t [testchannel type $f]
+ close $f
+ string compare $t file
+} 0
+
+test io-25.1 {Tcl_GetChannelHandle, input} {testchannel} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f "1234567890\n098765432"
+ close $f
+ set f [open $path(test1) r]
+ gets $f
+ set l ""
+ lappend l [testchannel inputbuffered $f]
+ lappend l [tell $f]
+ close $f
+ set l
+} {10 11}
+test io-25.2 {Tcl_GetChannelHandle, output} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello
+ set l ""
+ lappend l [testchannel outputbuffered $f]
+ lappend l [tell $f]
+ flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [tell $f]
+ close $f
+ file delete $path(test1)
+ set l
+} {6 6 0 6}
+
+test io-26.1 {Tcl_GetChannelInstanceData} {stdio openpipe} {
+ # "pid" command uses Tcl_GetChannelInstanceData
+ # Don't care what pid is (but must be a number), just want to exercise it.
+
+ set f [open "|[list [interpreter] << exit]"]
+ expr [pid $f]
+ close $f
+} {}
+
+# Test flushing. The functions tested here are FlushChannel.
+
+test io-27.1 {FlushChannel, no output buffered} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ flush $f
+ set s [file size $path(test1)]
+ close $f
+ set s
+} 0
+test io-27.2 {FlushChannel, some output buffered} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ set l ""
+ puts $f hello
+ lappend l [file size $path(test1)]
+ flush $f
+ lappend l [file size $path(test1)]
+ close $f
+ lappend l [file size $path(test1)]
+ set l
+} {0 6 6}
+test io-27.3 {FlushChannel, implicit flush on close} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ set l ""
+ puts $f hello
+ lappend l [file size $path(test1)]
+ close $f
+ lappend l [file size $path(test1)]
+ set l
+} {0 6}
+test io-27.4 {FlushChannel, implicit flush when buffer fills} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ fconfigure $f -buffersize 60
+ set l ""
+ lappend l [file size $path(test1)]
+ for {set i 0} {$i < 12} {incr i} {
+ puts $f hello
+ }
+ lappend l [file size $path(test1)]
+ flush $f
+ lappend l [file size $path(test1)]
+ close $f
+ set l
+} {0 60 72}
+test io-27.5 {FlushChannel, implicit flush when buffer fills and on close} \
+ {unixOrPc} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -buffersize 60 -eofchar {}
+ set l ""
+ lappend l [file size $path(test1)]
+ for {set i 0} {$i < 12} {incr i} {
+ puts $f hello
+ }
+ lappend l [file size $path(test1)]
+ close $f
+ lappend l [file size $path(test1)]
+ set l
+} {0 60 72}
+set path(pipe) [makeFile {} pipe]
+set path(output) [makeFile {} output]
+test io-27.6 {FlushChannel, async flushing, async close} \
+ {stdio asyncPipeClose openpipe} {
+ # This test may fail on old Unix systems (seen on IRIX64 6.5) with
+ # obsolete gettimeofday() calls. See Tcl Bugs 3530533, 1942197.
+ file delete $path(pipe)
+ file delete $path(output)
+ set f [open $path(pipe) w]
+ puts $f "set f \[[list open $path(output) w]]"
+ puts $f {
+ fconfigure $f -translation lf -buffering none -eofchar {}
+ while {![eof stdin]} {
+ after 20
+ puts -nonewline $f [read stdin 1024]
+ }
+ close $f
+ }
+ close $f
+ set x 01234567890123456789012345678901
+ for {set i 0} {$i < 11} {incr i} {
+ set x "$x$x"
+ }
+ set f [open $path(output) w]
+ close $f
+ set f [open "|[list [interpreter] $path(pipe)]" w]
+ fconfigure $f -blocking off
+ puts -nonewline $f $x
+ close $f
+ set counter 0
+ while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+ after 20 [list incr [namespace which -variable counter]]
+ vwait [namespace which -variable counter]
+ }
+ if {$counter == 1000} {
+ set result "file size only [file size $path(output)]"
+ } else {
+ set result ok
+ }
+} ok
+
+# Tests closing a channel. The functions tested are CloseChannel and Tcl_Close.
+
+test io-28.1 {CloseChannel called when all references are dropped} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ interp create x
+ interp share "" $f x
+ set l ""
+ lappend l [testchannel refcount $f]
+ x eval close $f
+ interp delete x
+ lappend l [testchannel refcount $f]
+ close $f
+ set l
+} {2 1}
+test io-28.2 {CloseChannel called when all references are dropped} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ interp create x
+ interp share "" $f x
+ puts -nonewline $f abc
+ close $f
+ x eval puts $f def
+ x eval close $f
+ interp delete x
+ set f [open $path(test1) r]
+ set l [gets $f]
+ close $f
+ set l
+} abcdef
+test io-28.3 {CloseChannel, not called before output queue is empty} \
+ {stdio asyncPipeClose nonPortable openpipe} {
+ file delete $path(pipe)
+ file delete $path(output)
+ set f [open $path(pipe) w]
+ puts $f {
+
+ # Need to not have eof char appended on close, because the other
+ # side of the pipe already closed, so that writing would cause an
+ # error "invalid file".
+
+ fconfigure stdout -eofchar {}
+ fconfigure stderr -eofchar {}
+
+ set f [open $path(output) w]
+ fconfigure $f -translation lf -buffering none
+ for {set x 0} {$x < 20} {incr x} {
+ after 20
+ puts -nonewline $f [read stdin 1024]
+ }
+ close $f
+ }
+ close $f
+ set x 01234567890123456789012345678901
+ for {set i 0} {$i < 11} {incr i} {
+ set x "$x$x"
+ }
+ set f [open $path(output) w]
+ close $f
+ set f [open "|[list [interpreter] pipe]" r+]
+ fconfigure $f -blocking off -eofchar {}
+
+ puts -nonewline $f $x
+ close $f
+ set counter 0
+ while {([file size $path(output)] < 20480) && ($counter < 1000)} {
+ after 20 [list incr [namespace which -variable counter]]
+ vwait [namespace which -variable counter]
+ }
+ if {$counter == 1000} {
+ set result probably_broken
+ } else {
+ set result ok
+ }
+} ok
+test io-28.4 {Tcl_Close} {testchannel} {
+ file delete $path(test1)
+ set l ""
+ lappend l [lsort [testchannel open]]
+ set f [open $path(test1) w]
+ lappend l [lsort [testchannel open]]
+ close $f
+ lappend l [lsort [testchannel open]]
+ set x [list $consoleFileNames \
+ [lsort [list {*}$consoleFileNames $f]] \
+ $consoleFileNames]
+ string compare $l $x
+} 0
+test io-28.5 {Tcl_Close vs standard handles} {stdio unix testchannel openpipe} {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f {
+ close stdin
+ puts [testchannel open]
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ set l [gets $f]
+ close $f
+ lsort $l
+} {file1 file2}
+
+test io-29.1 {Tcl_WriteChars, channel not writable} {
+ list [catch {puts stdin hello} msg] $msg
+} {1 {channel "stdin" wasn't opened for writing}}
+test io-29.2 {Tcl_WriteChars, empty string} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -eofchar {}
+ puts -nonewline $f ""
+ close $f
+ file size $path(test1)
+} 0
+test io-29.3 {Tcl_WriteChars, nonempty string} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -eofchar {}
+ puts -nonewline $f hello
+ close $f
+ file size $path(test1)
+} 5
+test io-29.4 {Tcl_WriteChars, buffering in full buffering mode} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -buffering full -eofchar {}
+ puts $f hello
+ set l ""
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ close $f
+ set l
+} {6 0 0 6}
+test io-29.5 {Tcl_WriteChars, buffering in line buffering mode} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -buffering line -eofchar {}
+ puts -nonewline $f hello
+ set l ""
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ close $f
+ set l
+} {5 0 0 11}
+test io-29.6 {Tcl_WriteChars, buffering in no buffering mode} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -buffering none -eofchar {}
+ puts -nonewline $f hello
+ set l ""
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ close $f
+ set l
+} {0 5 0 11}
+test io-29.7 {Tcl_Flush, full buffering} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -buffering full -eofchar {}
+ puts -nonewline $f hello
+ set l ""
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ close $f
+ set l
+} {5 0 11 0 0 11}
+test io-29.8 {Tcl_Flush, full buffering} {testchannel} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -buffering line
+ puts -nonewline $f hello
+ set l ""
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size $path(test1)]
+ close $f
+ set l
+} {5 0 0 5 0 11 0 11}
+test io-29.9 {Tcl_Flush, channel not writable} {
+ list [catch {flush stdin} msg] $msg
+} {1 {channel "stdin" wasn't opened for writing}}
+test io-29.10 {Tcl_WriteChars, looping and buffering} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ set f2 [open $path(longfile) r]
+ for {set x 0} {$x < 10} {incr x} {
+ puts $f1 [gets $f2]
+ }
+ close $f2
+ close $f1
+ file size $path(test1)
+} 387
+test io-29.11 {Tcl_WriteChars, no newline, implicit flush} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -eofchar {}
+ set f2 [open $path(longfile) r]
+ for {set x 0} {$x < 10} {incr x} {
+ puts -nonewline $f1 [gets $f2]
+ }
+ close $f1
+ close $f2
+ file size $path(test1)
+} 377
+test io-29.12 {Tcl_WriteChars on a pipe} {stdio openpipe} {
+ file delete $path(test1)
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 "set f1 \[[list open $path(longfile) r]]"
+ puts $f1 {
+ for {set x 0} {$x < 10} {incr x} {
+ puts [gets $f1]
+ }
+ }
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r]
+ set f2 [open $path(longfile) r]
+ set y ok
+ for {set x 0} {$x < 10} {incr x} {
+ set l1 [gets $f1]
+ set l2 [gets $f2]
+ if {"$l1" != "$l2"} {
+ set y broken
+ }
+ }
+ close $f1
+ close $f2
+ set y
+} ok
+test io-29.13 {Tcl_WriteChars to a pipe, line buffered} {stdio openpipe} {
+ file delete $path(test1)
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {
+ puts [gets stdin]
+ puts [gets stdin]
+ }
+ close $f1
+ set y ok
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ fconfigure $f1 -buffering line
+ set f2 [open $path(longfile) r]
+ set line [gets $f2]
+ puts $f1 $line
+ set backline [gets $f1]
+ if {"$line" != "$backline"} {
+ set y broken
+ }
+ set line [gets $f2]
+ puts $f1 $line
+ set backline [gets $f1]
+ if {"$line" != "$backline"} {
+ set y broken
+ }
+ close $f1
+ close $f2
+ set y
+} ok
+test io-29.14 {Tcl_WriteChars, buffering and implicit flush at close} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ puts -nonewline $f "Text1"
+ puts -nonewline $f " Text 2"
+ puts $f " Text 3"
+ close $f
+ set f [open $path(test3) r]
+ set x [gets $f]
+ close $f
+ set x
+} {Text1 Text 2 Text 3}
+test io-29.15 {Tcl_Flush, channel not open for writing} {
+ file delete $path(test1)
+ set fd [open $path(test1) w]
+ close $fd
+ set fd [open $path(test1) r]
+ set x [list [catch {flush $fd} msg] $msg]
+ close $fd
+ string compare $x \
+ [list 1 "channel \"$fd\" wasn't opened for writing"]
+} 0
+test io-29.16 {Tcl_Flush on pipe opened only for reading} {stdio openpipe} {
+ set fd [open "|[list [interpreter] cat longfile]" r]
+ set x [list [catch {flush $fd} msg] $msg]
+ catch {close $fd}
+ string compare $x \
+ [list 1 "channel \"$fd\" wasn't opened for writing"]
+} 0
+test io-29.17 {Tcl_WriteChars buffers, then Tcl_Flush flushes} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf
+ puts $f1 hello
+ puts $f1 hello
+ puts $f1 hello
+ flush $f1
+ set x [file size $path(test1)]
+ close $f1
+ set x
+} 18
+test io-29.18 {Tcl_WriteChars and Tcl_Flush intermixed} {
+ file delete $path(test1)
+ set x ""
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf
+ puts $f1 hello
+ puts $f1 hello
+ puts $f1 hello
+ flush $f1
+ lappend x [file size $path(test1)]
+ puts $f1 hello
+ flush $f1
+ lappend x [file size $path(test1)]
+ puts $f1 hello
+ flush $f1
+ lappend x [file size $path(test1)]
+ close $f1
+ set x
+} {18 24 30}
+test io-29.19 {Explicit and implicit flushes} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ set x ""
+ puts $f1 hello
+ puts $f1 hello
+ puts $f1 hello
+ flush $f1
+ lappend x [file size $path(test1)]
+ puts $f1 hello
+ flush $f1
+ lappend x [file size $path(test1)]
+ puts $f1 hello
+ close $f1
+ lappend x [file size $path(test1)]
+ set x
+} {18 24 30}
+test io-29.20 {Implicit flush when buffer is full} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ set line "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+ for {set x 0} {$x < 100} {incr x} {
+ puts $f1 $line
+ }
+ set z ""
+ lappend z [file size $path(test1)]
+ for {set x 0} {$x < 100} {incr x} {
+ puts $f1 $line
+ }
+ lappend z [file size $path(test1)]
+ close $f1
+ lappend z [file size $path(test1)]
+ set z
+} {4096 12288 12600}
+test io-29.21 {Tcl_Flush to pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {set x [read stdin 6]}
+ puts $f1 {set cnt [string length $x]}
+ puts $f1 {puts "read $cnt characters"}
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ puts $f1 hello
+ flush $f1
+ set x [gets $f1]
+ catch {close $f1}
+ set x
+} "read 6 characters"
+test io-29.22 {Tcl_Flush called at other end of pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {
+ fconfigure stdout -buffering full
+ puts hello
+ puts hello
+ flush stdout
+ gets stdin
+ puts bye
+ flush stdout
+ }
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ set x ""
+ lappend x [gets $f1]
+ lappend x [gets $f1]
+ puts $f1 hello
+ flush $f1
+ lappend x [gets $f1]
+ close $f1
+ set x
+} {hello hello bye}
+test io-29.23 {Tcl_Flush and line buffering at end of pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {
+ puts hello
+ puts hello
+ gets stdin
+ puts bye
+ }
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ set x ""
+ lappend x [gets $f1]
+ lappend x [gets $f1]
+ puts $f1 hello
+ flush $f1
+ lappend x [gets $f1]
+ close $f1
+ set x
+} {hello hello bye}
+test io-29.24 {Tcl_WriteChars and Tcl_Flush move end of file} {
+ set f [open $path(test3) w]
+ puts $f "Line 1"
+ puts $f "Line 2"
+ set f2 [open $path(test3)]
+ set x {}
+ lappend x [read -nonewline $f2]
+ close $f2
+ flush $f
+ set f2 [open $path(test3)]
+ lappend x [read -nonewline $f2]
+ close $f2
+ close $f
+ set x
+} "{} {Line 1\nLine 2}"
+test io-29.25 {Implicit flush with Tcl_Flush to command pipelines} {stdio openpipe fileevent} {
+ file delete $path(test3)
+ set f [open "|[list [interpreter] $path(cat) | [interpreter] $path(cat) > $path(test3)]" w]
+ puts $f "Line 1"
+ puts $f "Line 2"
+ close $f
+ after 100
+ set f [open $path(test3) r]
+ set x [read $f]
+ close $f
+ set x
+} "Line 1\nLine 2\n"
+test io-29.26 {Tcl_Flush, Tcl_Write on bidirectional pipelines} {stdio unixExecs openpipe} {
+ set f [open "|[list cat -u]" r+]
+ puts $f "Line1"
+ flush $f
+ set x [gets $f]
+ close $f
+ set x
+} {Line1}
+test io-29.27 {Tcl_Flush on closed pipeline} {stdio openpipe} {
+ file delete $path(pipe)
+ set f [open $path(pipe) w]
+ puts $f {exit}
+ close $f
+ set f [open "|[list [interpreter] $path(pipe)]" r+]
+ gets $f
+ puts $f output
+ after 50
+ #
+ # The flush below will get a SIGPIPE. This is an expected part of
+ # test and indicates that the test operates correctly. If you run
+ # this test under a debugger, the signal will by intercepted unless
+ # you disable the debugger's signal interception.
+ #
+ if {[catch {flush $f} msg]} {
+ set x [list 1 $msg $::errorCode]
+ catch {close $f}
+ } else {
+ if {[catch {close $f} msg]} {
+ set x [list 1 $msg $::errorCode]
+ } else {
+ set x {this was supposed to fail and did not}
+ }
+ }
+ regsub {".*":} $x {"":} x
+ string tolower $x
+} {1 {error flushing "": broken pipe} {posix epipe {broken pipe}}}
+test io-29.28 {Tcl_WriteChars, lf mode} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f hello\nthere\nand\nhere
+ flush $f
+ set s [file size $path(test1)]
+ close $f
+ set s
+} 21
+test io-29.29 {Tcl_WriteChars, cr mode} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar {}
+ puts $f hello\nthere\nand\nhere
+ close $f
+ file size $path(test1)
+} 21
+test io-29.30 {Tcl_WriteChars, crlf mode} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -eofchar {}
+ puts $f hello\nthere\nand\nhere
+ close $f
+ file size $path(test1)
+} 25
+test io-29.31 {Tcl_WriteChars, background flush} {stdio openpipe} {
+ # This test may fail on old Unix systems (seen on IRIX64 6.5) with
+ # obsolete gettimeofday() calls. See Tcl Bugs 3530533, 1942197.
+ file delete $path(pipe)
+ file delete $path(output)
+ set f [open $path(pipe) w]
+ puts $f "set f \[[list open $path(output) w]]"
+ puts $f {fconfigure $f -translation lf}
+ set x [list while {![eof stdin]}]
+ set x "$x {"
+ puts $f $x
+ puts $f { puts -nonewline $f [read stdin 4096]}
+ puts $f { flush $f}
+ puts $f "}"
+ puts $f {close $f}
+ close $f
+ set x 01234567890123456789012345678901
+ for {set i 0} {$i < 11} {incr i} {
+ set x "$x$x"
+ }
+ set f [open $path(output) w]
+ close $f
+ set f [open "|[list [interpreter] $path(pipe)]" r+]
+ fconfigure $f -blocking off
+ puts -nonewline $f $x
+ close $f
+ set counter 0
+ while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+ after 10 [list incr [namespace which -variable counter]]
+ vwait [namespace which -variable counter]
+ }
+ if {$counter == 1000} {
+ set result "file size only [file size $path(output)]"
+ } else {
+ set result ok
+ }
+ # allow a little time for the background process to close.
+ # otherwise, the following test fails on the [file delete $path(output)
+ # on Windows because a process still has the file open.
+ after 100 set v 1; vwait v
+ set result
+} ok
+test io-29.32 {Tcl_WriteChars, background flush to slow reader} \
+ {stdio asyncPipeClose openpipe} {
+ # This test may fail on old Unix systems (seen on IRIX64 6.5) with
+ # obsolete gettimeofday() calls. See Tcl Bugs 3530533, 1942197.
+ file delete $path(pipe)
+ file delete $path(output)
+ set f [open $path(pipe) w]
+ puts $f "set f \[[list open $path(output) w]]"
+ puts $f {fconfigure $f -translation lf}
+ set x [list while {![eof stdin]}]
+ set x "$x \{"
+ puts $f $x
+ puts $f { after 20}
+ puts $f { puts -nonewline $f [read stdin 1024]}
+ puts $f { flush $f}
+ puts $f "\}"
+ puts $f {close $f}
+ close $f
+ set x 01234567890123456789012345678901
+ for {set i 0} {$i < 11} {incr i} {
+ set x "$x$x"
+ }
+ set f [open $path(output) w]
+ close $f
+ set f [open "|[list [interpreter] $path(pipe)]" r+]
+ fconfigure $f -blocking off
+ puts -nonewline $f $x
+ close $f
+ set counter 0
+ while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+ after 20 [list incr [namespace which -variable counter]]
+ vwait [namespace which -variable counter]
+ }
+ if {$counter == 1000} {
+ set result "file size only [file size $path(output)]"
+ } else {
+ set result ok
+ }
+} ok
+test io-29.33 {Tcl_Flush, implicit flush on exit} {exec} {
+ set f [open $path(script) w]
+ puts $f "set f \[[list open $path(test1) w]]"
+ puts $f {fconfigure $f -translation lf
+ puts $f hello
+ puts $f bye
+ puts $f strange
+ }
+ close $f
+ exec [interpreter] $path(script)
+ set f [open $path(test1) r]
+ set r [read $f]
+ close $f
+ set r
+} "hello\nbye\nstrange\n"
+set path(script2) [makeFile {} script2]
+test io-29.33b {TIP#398, no implicit flush of nonblocking on exit} {exec} {
+ set f [open $path(script) w]
+ puts $f {
+ fconfigure stdout -blocking 0
+ puts -nonewline stdout [string repeat A 655360]
+ flush stdout
+ }
+ close $f
+ set f [open $path(script2) w]
+ puts $f {after 2000}
+ close $f
+ set t1 [clock milliseconds]
+ set ff [open "|[list [interpreter] $path(script2)]" w]
+ catch {unset ::env(TCL_FLUSH_NONBLOCKING_ON_EXIT)}
+ exec [interpreter] $path(script) >@ $ff
+ set t2 [clock milliseconds]
+ close $ff
+ expr {($t2-$t1)/2000 ? $t2-$t1 : 0}
+} 0
+test io-29.34 {Tcl_Close, async flush on close, using sockets} {socket tempNotMac fileevent} {
+ variable c 0
+ variable x running
+ set l abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
+ proc writelots {s l} {
+ for {set i 0} {$i < 2000} {incr i} {
+ puts $s $l
+ }
+ }
+ proc accept {s a p} {
+ variable x
+ fileevent $s readable [namespace code [list readit $s]]
+ fconfigure $s -blocking off
+ set x accepted
+ }
+ proc readit {s} {
+ variable c
+ variable x
+ set l [gets $s]
+
+ if {[eof $s]} {
+ close $s
+ set x done
+ } elseif {([string length $l] > 0) || ![fblocked $s]} {
+ incr c
+ }
+ }
+ set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set cs [socket 127.0.0.1 [lindex [fconfigure $ss -sockname] 2]]
+ vwait [namespace which -variable x]
+ fconfigure $cs -blocking off
+ writelots $cs $l
+ close $cs
+ close $ss
+ vwait [namespace which -variable x]
+ set c
+} 2000
+test io-29.35 {Tcl_Close vs fileevent vs multiple interpreters} {socket tempNotMac fileevent} {
+ # On Mac, this test screws up sockets such that subsequent tests using port 2828
+ # either cause errors or panic().
+
+ catch {interp delete x}
+ catch {interp delete y}
+ interp create x
+ interp create y
+ set s [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ proc accept {s a p} {
+ puts $s hello
+ close $s
+ }
+ set c [socket 127.0.0.1 [lindex [fconfigure $s -sockname] 2]]
+ interp share {} $c x
+ interp share {} $c y
+ close $c
+ x eval {
+ proc readit {s} {
+ gets $s
+ if {[eof $s]} {
+ close $s
+ }
+ }
+ }
+ y eval {
+ proc readit {s} {
+ gets $s
+ if {[eof $s]} {
+ close $s
+ }
+ }
+ }
+ x eval "fileevent $c readable \{readit $c\}"
+ y eval "fileevent $c readable \{readit $c\}"
+ y eval [list close $c]
+ update
+ close $s
+ interp delete x
+ interp delete y
+} ""
+
+# Test end of line translations. Procedures tested are Tcl_Write, Tcl_Read.
+
+test io-30.1 {Tcl_Write lf, Tcl_Read lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf
+ set x [read $f]
+ close $f
+ set x
+} "hello\nthere\nand\nhere\n"
+test io-30.2 {Tcl_Write lf, Tcl_Read cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr
+ set x [read $f]
+ close $f
+ set x
+} "hello\nthere\nand\nhere\n"
+test io-30.3 {Tcl_Write lf, Tcl_Read crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set x [read $f]
+ close $f
+ set x
+} "hello\nthere\nand\nhere\n"
+test io-30.4 {Tcl_Write cr, Tcl_Read cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr
+ set x [read $f]
+ close $f
+ set x
+} "hello\nthere\nand\nhere\n"
+test io-30.5 {Tcl_Write cr, Tcl_Read lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf
+ set x [read $f]
+ close $f
+ set x
+} "hello\rthere\rand\rhere\r"
+test io-30.6 {Tcl_Write cr, Tcl_Read crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set x [read $f]
+ close $f
+ set x
+} "hello\rthere\rand\rhere\r"
+test io-30.7 {Tcl_Write crlf, Tcl_Read crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set x [read $f]
+ close $f
+ set x
+} "hello\nthere\nand\nhere\n"
+test io-30.8 {Tcl_Write crlf, Tcl_Read lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf
+ set x [read $f]
+ close $f
+ set x
+} "hello\r\nthere\r\nand\r\nhere\r\n"
+test io-30.9 {Tcl_Write crlf, Tcl_Read cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr
+ set x [read $f]
+ close $f
+ set x
+} "hello\n\nthere\n\nand\n\nhere\n\n"
+test io-30.10 {Tcl_Write lf, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ set c [read $f]
+ set x [fconfigure $f -translation]
+ close $f
+ list $c $x
+} {{hello
+there
+and
+here
+} auto}
+test io-30.11 {Tcl_Write cr, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ set c [read $f]
+ set x [fconfigure $f -translation]
+ close $f
+ list $c $x
+} {{hello
+there
+and
+here
+} auto}
+test io-30.12 {Tcl_Write crlf, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ set c [read $f]
+ set x [fconfigure $f -translation]
+ close $f
+ list $c $x
+} {{hello
+there
+and
+here
+} auto}
+test io-30.13 {Tcl_Write crlf on block boundary, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set line "123456789ABCDE" ;# 14 char plus crlf
+ puts -nonewline $f x ;# shift crlf across block boundary
+ for {set i 0} {$i < 700} {incr i} {
+ puts $f $line
+ }
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto
+ set c [read $f]
+ close $f
+ string length $c
+} [expr 700*15+1]
+test io-30.14 {Tcl_Write crlf on block boundary, Tcl_Read crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set line "123456789ABCDE" ;# 14 char plus crlf
+ puts -nonewline $f x ;# shift crlf across block boundary
+ for {set i 0} {$i < 700} {incr i} {
+ puts $f $line
+ }
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set c [read $f]
+ close $f
+ string length $c
+} [expr 700*15+1]
+test io-30.15 {Tcl_Write mixed, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\rhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto
+ set c [read $f]
+ close $f
+ set c
+} {hello
+there
+and
+here
+}
+test io-30.16 {Tcl_Write ^Z at end, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f hello\nthere\nand\rhere\n\x1a
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ set c [read $f]
+ close $f
+ set c
+} {hello
+there
+and
+here
+}
+test io-30.17 {Tcl_Write, implicit ^Z at end, Tcl_Read auto} {win} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -eofchar \x1a -translation lf
+ puts $f hello\nthere\nand\rhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ set c [read $f]
+ close $f
+ set c
+} {hello
+there
+and
+here
+}
+test io-30.18 {Tcl_Write, ^Z in middle, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1 {} 1}
+test io-30.19 {Tcl_Write, ^Z no newline in middle, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1 {} 1}
+test io-30.20 {Tcl_Write, ^Z in middle ignored, Tcl_Read lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf -eofchar {}
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} "abc def 0 \x1aghi 0 qrs 0 {} 1"
+test io-30.21 {Tcl_Write, ^Z in middle ignored, Tcl_Read cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr -eofchar {}
+ set l ""
+ set x [gets $f]
+ lappend l [string compare $x "abc\ndef\n\x1aghi\nqrs\n"]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {0 1 {} 1}
+test io-30.22 {Tcl_Write, ^Z in middle ignored, Tcl_Read crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf -eofchar {}
+ set l ""
+ set x [gets $f]
+ lappend l [string compare $x "abc\ndef\n\x1aghi\nqrs\n"]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {0 1 {} 1}
+test io-30.23 {Tcl_Write lf, ^Z in middle, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set c [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $e
+} {8 1}
+test io-30.24 {Tcl_Write lf, ^Z in middle, Tcl_Read lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf -eofchar \x1a
+ set c [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $e
+} {8 1}
+test io-30.25 {Tcl_Write cr, ^Z in middle, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set c [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $e
+} {8 1}
+test io-30.26 {Tcl_Write cr, ^Z in middle, Tcl_Read cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr -eofchar \x1a
+ set c [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $e
+} {8 1}
+test io-30.27 {Tcl_Write crlf, ^Z in middle, Tcl_Read auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set c [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $e
+} {8 1}
+test io-30.28 {Tcl_Write crlf, ^Z in middle, Tcl_Read crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf -eofchar \x1a
+ set c [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $e
+} {8 1}
+
+# Test end of line translations. Functions tested are Tcl_Write and Tcl_Gets.
+
+test io-31.1 {Tcl_Write lf, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ close $f
+ set l
+} {hello 6 auto there 12 auto}
+test io-31.2 {Tcl_Write cr, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ close $f
+ set l
+} {hello 6 auto there 12 auto}
+test io-31.3 {Tcl_Write crlf, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ close $f
+ set l
+} {hello 7 auto there 14 auto}
+test io-31.4 {Tcl_Write lf, Tcl_Gets lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf
+ set l ""
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ close $f
+ set l
+} {hello 6 lf there 12 lf}
+test io-31.5 {Tcl_Write lf, Tcl_Gets cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr
+ set l ""
+ lappend l [string length [gets $f]]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ close $f
+ set l
+} {21 21 cr 1 {} 21 cr 1}
+test io-31.6 {Tcl_Write lf, Tcl_Gets crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set l ""
+ lappend l [string length [gets $f]]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ close $f
+ set l
+} {21 21 crlf 1 {} 21 crlf 1}
+test io-31.7 {Tcl_Write cr, Tcl_Gets cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr
+ set l ""
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello 6 cr 0 there 12 cr 0}
+test io-31.8 {Tcl_Write cr, Tcl_Gets lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf
+ set l ""
+ lappend l [string length [gets $f]]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ close $f
+ set l
+} {21 21 lf 1 {} 21 lf 1}
+test io-31.9 {Tcl_Write cr, Tcl_Gets crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set l ""
+ lappend l [string length [gets $f]]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ close $f
+ set l
+} {21 21 crlf 1 {} 21 crlf 1}
+test io-31.10 {Tcl_Write crlf, Tcl_Gets crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set l ""
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello 7 crlf 0 there 14 crlf 0}
+test io-31.11 {Tcl_Write crlf, Tcl_Gets cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr
+ set l ""
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ lappend l [string length [gets $f]]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello 6 cr 0 6 13 cr 0}
+test io-31.12 {Tcl_Write crlf, Tcl_Gets lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf
+ set l ""
+ lappend l [string length [gets $f]]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ lappend l [string length [gets $f]]
+ lappend l [tell $f]
+ lappend l [fconfigure $f -translation]
+ lappend l [eof $f]
+ close $f
+ set l
+} {6 7 lf 0 6 14 lf 0}
+test io-31.13 {binary mode is synonym of lf mode} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation binary
+ set x [fconfigure $f -translation]
+ close $f
+ set x
+} lf
+#
+# Test io-9.14 has been removed because "auto" output translation mode is
+# not supoprted.
+#
+test io-31.14 {Tcl_Write mixed, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\rand\r\nhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello there and here 0 {} 1}
+test io-31.15 {Tcl_Write mixed, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f hello\nthere\rand\r\nhere\r
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello there and here 0 {} 1}
+test io-31.16 {Tcl_Write mixed, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f hello\nthere\rand\r\nhere\n
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello there and here 0 {} 1}
+test io-31.17 {Tcl_Write mixed, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f hello\nthere\rand\r\nhere\r\n
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello there and here 0 {} 1}
+test io-31.18 {Tcl_Write ^Z at end, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set s [format "hello\nthere\nand\rhere\n\%c" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello there and here 0 {} 1}
+test io-31.19 {Tcl_Write, implicit ^Z at end, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -eofchar \x1a -translation lf
+ puts $f hello\nthere\nand\rhere
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {hello there and here 0 {} 1}
+test io-31.20 {Tcl_Write, ^Z in middle, Tcl_Gets auto, eofChar} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a
+ fconfigure $f -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1}
+test io-31.21 {Tcl_Write, no newline ^Z in middle, Tcl_Gets auto, eofChar} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1}
+test io-31.22 {Tcl_Write, ^Z in middle ignored, Tcl_Gets lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf -eofchar {}
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test io-31.23 {Tcl_Write, ^Z in middle ignored, Tcl_Gets cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr -eofchar {}
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test io-31.24 {Tcl_Write, ^Z in middle ignored, Tcl_Gets crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf -eofchar {}
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test io-31.25 {Tcl_Write lf, ^Z in middle, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1}
+test io-31.26 {Tcl_Write lf, ^Z in middle, Tcl_Gets lf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf -eofchar \x1a
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1}
+test io-31.27 {Tcl_Write cr, ^Z in middle, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1}
+test io-31.28 {Tcl_Write cr, ^Z in middle, Tcl_Gets cr} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr -eofchar \x1a
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1}
+test io-31.29 {Tcl_Write crlf, ^Z in middle, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1}
+test io-31.30 {Tcl_Write crlf, ^Z in middle, Tcl_Gets crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf -eofchar \x1a
+ set l ""
+ lappend l [gets $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {abc def 0 {} 1}
+test io-31.31 {Tcl_Write crlf on block boundary, Tcl_Gets crlf} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set line "123456789ABCDE" ;# 14 char plus crlf
+ puts -nonewline $f x ;# shift crlf across block boundary
+ for {set i 0} {$i < 700} {incr i} {
+ puts $f $line
+ }
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf
+ set c ""
+ while {[gets $f line] >= 0} {
+ append c $line\n
+ }
+ close $f
+ string length $c
+} [expr 700*15+1]
+test io-31.32 {Tcl_Write crlf on block boundary, Tcl_Gets auto} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set line "123456789ABCDE" ;# 14 char plus crlf
+ puts -nonewline $f x ;# shift crlf across block boundary
+ for {set i 0} {$i < 700} {incr i} {
+ puts $f $line
+ }
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto
+ set c ""
+ while {[gets $f line] >= 0} {
+ append c $line\n
+ }
+ close $f
+ string length $c
+} [expr 700*15+1]
+
+# Test Tcl_Read and buffering.
+
+test io-32.1 {Tcl_Read, channel not readable} {
+ list [catch {read stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test io-32.2 {Tcl_Read, zero byte count} {
+ read stdin 0
+} ""
+test io-32.3 {Tcl_Read, negative byte count} {
+ set f [open $path(longfile) r]
+ set l [list [catch {read $f -1} msg] $msg]
+ close $f
+ set l
+} {1 {expected non-negative integer but got "-1"}}
+test io-32.4 {Tcl_Read, positive byte count} {
+ set f [open $path(longfile) r]
+ set x [read $f 1024]
+ set s [string length $x]
+ unset x
+ close $f
+ set s
+} 1024
+test io-32.5 {Tcl_Read, multiple buffers} {
+ set f [open $path(longfile) r]
+ fconfigure $f -buffersize 100
+ set x [read $f 1024]
+ set s [string length $x]
+ unset x
+ close $f
+ set s
+} 1024
+test io-32.6 {Tcl_Read, very large read} {
+ set f1 [open $path(longfile) r]
+ set z [read $f1 1000000]
+ close $f1
+ set l [string length $z]
+ set x ok
+ set z [file size $path(longfile)]
+ if {$z != $l} {
+ set x broken
+ }
+ set x
+} ok
+test io-32.7 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
+ set f1 [open $path(longfile) r]
+ fconfigure $f1 -blocking off
+ set z [read $f1 20]
+ close $f1
+ set l [string length $z]
+ set x ok
+ if {$l != 20} {
+ set x broken
+ }
+ set x
+} ok
+test io-32.8 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
+ set f1 [open $path(longfile) r]
+ fconfigure $f1 -blocking off
+ set z [read $f1 1000000]
+ close $f1
+ set x ok
+ set l [string length $z]
+ set z [file size $path(longfile)]
+ if {$z != $l} {
+ set x broken
+ }
+ set x
+} ok
+test io-32.9 {Tcl_Read, read to end of file} {
+ set f1 [open $path(longfile) r]
+ set z [read $f1]
+ close $f1
+ set l [string length $z]
+ set x ok
+ set z [file size $path(longfile)]
+ if {$z != $l} {
+ set x broken
+ }
+ set x
+} ok
+test io-32.10 {Tcl_Read from a pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {puts [gets stdin]}
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ puts $f1 hello
+ flush $f1
+ set x [read $f1]
+ close $f1
+ set x
+} "hello\n"
+test io-32.11 {Tcl_Read from a pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {puts [gets stdin]}
+ puts $f1 {puts [gets stdin]}
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ puts $f1 hello
+ flush $f1
+ set x ""
+ lappend x [read $f1 6]
+ puts $f1 hello
+ flush $f1
+ lappend x [read $f1]
+ close $f1
+ set x
+} {{hello
+} {hello
+}}
+test io-32.12 {Tcl_Read, -nonewline} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ puts $f1 hello
+ puts $f1 bye
+ close $f1
+ set f1 [open $path(test1) r]
+ set c [read -nonewline $f1]
+ close $f1
+ set c
+} {hello
+bye}
+test io-32.13 {Tcl_Read, -nonewline} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ puts $f1 hello
+ puts $f1 bye
+ close $f1
+ set f1 [open $path(test1) r]
+ set c [read -nonewline $f1]
+ close $f1
+ list [string length $c] $c
+} {9 {hello
+bye}}
+test io-32.14 {Tcl_Read, reading in small chunks} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f "Two lines: this one"
+ puts $f "and this one"
+ close $f
+ set f [open $path(test1)]
+ set x [list [read $f 1] [read $f 2] [read $f]]
+ close $f
+ set x
+} {T wo { lines: this one
+and this one
+}}
+test io-32.15 {Tcl_Read, asking for more input than available} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f "Two lines: this one"
+ puts $f "and this one"
+ close $f
+ set f [open $path(test1)]
+ set x [read $f 100]
+ close $f
+ set x
+} {Two lines: this one
+and this one
+}
+test io-32.16 {Tcl_Read, read to end of file with -nonewline} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f "Two lines: this one"
+ puts $f "and this one"
+ close $f
+ set f [open $path(test1)]
+ set x [read -nonewline $f]
+ close $f
+ set x
+} {Two lines: this one
+and this one}
+
+# Test Tcl_Gets.
+
+test io-33.1 {Tcl_Gets, reading what was written} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ set y "first line"
+ puts $f1 $y
+ close $f1
+ set f1 [open $path(test1) r]
+ set x [gets $f1]
+ set z ok
+ if {"$x" != "$y"} {
+ set z broken
+ }
+ close $f1
+ set z
+} ok
+test io-33.2 {Tcl_Gets into variable} {
+ set f1 [open $path(longfile) r]
+ set c [gets $f1 x]
+ set l [string length x]
+ set z ok
+ if {$l != $l} {
+ set z broken
+ }
+ close $f1
+ set z
+} ok
+test io-33.3 {Tcl_Gets from pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {puts [gets stdin]}
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ puts $f1 hello
+ flush $f1
+ set x [gets $f1]
+ close $f1
+ set z ok
+ if {"$x" != "hello"} {
+ set z broken
+ }
+ set z
+} ok
+test io-33.4 {Tcl_Gets with long line} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ puts $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ close $f
+ set f [open $path(test3)]
+ set x [gets $f]
+ close $f
+ set x
+} {abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
+test io-33.5 {Tcl_Gets with long line} {
+ set f [open $path(test3)]
+ set x [gets $f y]
+ close $f
+ list $x $y
+} {260 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
+test io-33.6 {Tcl_Gets and end of file} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ puts -nonewline $f "Test1\nTest2"
+ close $f
+ set f [open $path(test3)]
+ set x {}
+ set y {}
+ lappend x [gets $f y] $y
+ set y {}
+ lappend x [gets $f y] $y
+ set y {}
+ lappend x [gets $f y] $y
+ close $f
+ set x
+} {5 Test1 5 Test2 -1 {}}
+test io-33.7 {Tcl_Gets and bad variable} {
+ set f [open $path(test3) w]
+ puts $f "Line 1"
+ puts $f "Line 2"
+ close $f
+ catch {unset x}
+ set x 24
+ set f [open $path(test3) r]
+ set result [list [catch {gets $f x(0)} msg] $msg]
+ close $f
+ set result
+} {1 {can't set "x(0)": variable isn't array}}
+test io-33.8 {Tcl_Gets, exercising double buffering} {
+ set f [open $path(test3) w]
+ fconfigure $f -translation lf -eofchar {}
+ set x ""
+ for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+ for {set y 0} {$y < 100} {incr y} {puts $f $x}
+ close $f
+ set f [open $path(test3) r]
+ fconfigure $f -translation lf
+ for {set y 0} {$y < 100} {incr y} {gets $f}
+ close $f
+ set y
+} 100
+test io-33.9 {Tcl_Gets, exercising double buffering} {
+ set f [open $path(test3) w]
+ fconfigure $f -translation lf -eofchar {}
+ set x ""
+ for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+ for {set y 0} {$y < 200} {incr y} {puts $f $x}
+ close $f
+ set f [open $path(test3) r]
+ fconfigure $f -translation lf
+ for {set y 0} {$y < 200} {incr y} {gets $f}
+ close $f
+ set y
+} 200
+test io-33.10 {Tcl_Gets, exercising double buffering} {
+ set f [open $path(test3) w]
+ fconfigure $f -translation lf -eofchar {}
+ set x ""
+ for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+ for {set y 0} {$y < 300} {incr y} {puts $f $x}
+ close $f
+ set f [open $path(test3) r]
+ fconfigure $f -translation lf
+ for {set y 0} {$y < 300} {incr y} {gets $f}
+ close $f
+ set y
+} 300
+
+# Test Tcl_Seek and Tcl_Tell.
+
+test io-34.1 {Tcl_Seek to current position at start of file} {
+ set f1 [open $path(longfile) r]
+ seek $f1 0 current
+ set c [tell $f1]
+ close $f1
+ set c
+} 0
+test io-34.2 {Tcl_Seek to offset from start} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open $path(test1) r]
+ seek $f1 10 start
+ set c [tell $f1]
+ close $f1
+ set c
+} 10
+test io-34.3 {Tcl_Seek to end of file} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open $path(test1) r]
+ seek $f1 0 end
+ set c [tell $f1]
+ close $f1
+ set c
+} 54
+test io-34.4 {Tcl_Seek to offset from end of file} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open $path(test1) r]
+ seek $f1 -10 end
+ set c [tell $f1]
+ close $f1
+ set c
+} 44
+test io-34.5 {Tcl_Seek to offset from current position} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open $path(test1) r]
+ seek $f1 10 current
+ seek $f1 10 current
+ set c [tell $f1]
+ close $f1
+ set c
+} 20
+test io-34.6 {Tcl_Seek to offset from end of file} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open $path(test1) r]
+ seek $f1 -10 end
+ set c [tell $f1]
+ set r [read $f1]
+ close $f1
+ list $c $r
+} {44 {rstuvwxyz
+}}
+test io-34.7 {Tcl_Seek to offset from end of file, then to current position} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open $path(test1) r]
+ seek $f1 -10 end
+ set c1 [tell $f1]
+ set r1 [read $f1 5]
+ seek $f1 0 current
+ set c2 [tell $f1]
+ close $f1
+ list $c1 $r1 $c2
+} {44 rstuv 49}
+test io-34.8 {Tcl_Seek on pipes: not supported} {stdio openpipe} {
+ set f1 [open "|[list [interpreter]]" r+]
+ set x [list [catch {seek $f1 0 current} msg] $msg]
+ close $f1
+ regsub {".*":} $x {"":} x
+ string tolower $x
+} {1 {error during seek on "": invalid argument}}
+test io-34.9 {Tcl_Seek, testing buffered input flushing} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ fconfigure $f -eofchar {}
+ puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ close $f
+ set f [open $path(test3) RDWR]
+ set x [read $f 1]
+ seek $f 3
+ lappend x [read $f 1]
+ seek $f 0 start
+ lappend x [read $f 1]
+ seek $f 10 current
+ lappend x [read $f 1]
+ seek $f -2 end
+ lappend x [read $f 1]
+ seek $f 50 end
+ lappend x [read $f 1]
+ seek $f 1
+ lappend x [read $f 1]
+ close $f
+ set x
+} {a d a l Y {} b}
+set path(test3) [makeFile {} test3]
+test io-34.10 {Tcl_Seek testing flushing of buffered input} {
+ set f [open $path(test3) w]
+ fconfigure $f -translation lf
+ puts $f xyz\n123
+ close $f
+ set f [open $path(test3) r+]
+ fconfigure $f -translation lf
+ set x [gets $f]
+ seek $f 0 current
+ puts $f 456
+ close $f
+ list $x [viewFile test3]
+} "xyz {xyz
+456}"
+test io-34.11 {Tcl_Seek testing flushing of buffered output} {
+ set f [open $path(test3) w]
+ puts $f xyz\n123
+ close $f
+ set f [open $path(test3) w+]
+ puts $f xyzzy
+ seek $f 2
+ set x [gets $f]
+ close $f
+ list $x [viewFile test3]
+} "zzy xyzzy"
+test io-34.12 {Tcl_Seek testing combination of write, seek back and read} {
+ set f [open $path(test3) w]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f xyz\n123
+ close $f
+ set f [open $path(test3) a+]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f xyzzy
+ flush $f
+ set x [tell $f]
+ seek $f -4 cur
+ set y [gets $f]
+ close $f
+ list $x [viewFile test3] $y
+} {14 {xyz
+123
+xyzzy} zzy}
+test io-34.13 {Tcl_Tell at start of file} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ set p [tell $f1]
+ close $f1
+ set p
+} 0
+test io-34.14 {Tcl_Tell after seek to end of file} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open $path(test1) r]
+ seek $f1 0 end
+ set c1 [tell $f1]
+ close $f1
+ set c1
+} 54
+test io-34.15 {Tcl_Tell combined with seeking} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open $path(test1) r]
+ seek $f1 10 start
+ set c1 [tell $f1]
+ seek $f1 10 current
+ set c2 [tell $f1]
+ close $f1
+ list $c1 $c2
+} {10 20}
+test io-34.16 {Tcl_Tell on pipe: always -1} {stdio openpipe} {
+ set f1 [open "|[list [interpreter]]" r+]
+ set c [tell $f1]
+ close $f1
+ set c
+} -1
+test io-34.17 {Tcl_Tell on pipe: always -1} {stdio openpipe} {
+ set f1 [open "|[list [interpreter]]" r+]
+ puts $f1 {puts hello}
+ flush $f1
+ set c [tell $f1]
+ gets $f1
+ close $f1
+ set c
+} -1
+test io-34.18 {Tcl_Tell combined with seeking and reading} {
+ file delete $path(test2)
+ set f [open $path(test2) w]
+ fconfigure $f -translation lf -eofchar {}
+ puts -nonewline $f "line1\nline2\nline3\nline4\nline5\n"
+ close $f
+ set f [open $path(test2)]
+ fconfigure $f -translation lf
+ set x [tell $f]
+ read $f 3
+ lappend x [tell $f]
+ seek $f 2
+ lappend x [tell $f]
+ seek $f 10 current
+ lappend x [tell $f]
+ seek $f 0 end
+ lappend x [tell $f]
+ close $f
+ set x
+} {0 3 2 12 30}
+test io-34.19 {Tcl_Tell combined with opening in append mode} {
+ set f [open $path(test3) w]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f "abcdefghijklmnopqrstuvwxyz"
+ puts $f "abcdefghijklmnopqrstuvwxyz"
+ close $f
+ set f [open $path(test3) a]
+ set c [tell $f]
+ close $f
+ set c
+} 54
+test io-34.20 {Tcl_Tell combined with writing} {
+ set f [open $path(test3) w]
+ set l ""
+ seek $f 29 start
+ lappend l [tell $f]
+ puts -nonewline $f a
+ seek $f 39 start
+ lappend l [tell $f]
+ puts -nonewline $f a
+ lappend l [tell $f]
+ seek $f 407 end
+ lappend l [tell $f]
+ close $f
+ set l
+} {29 39 40 447}
+test io-34.21 {Tcl_Seek and Tcl_Tell on large files} {largefileSupport} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ fconfigure $f -encoding binary
+ set l ""
+ lappend l [tell $f]
+ puts -nonewline $f abcdef
+ lappend l [tell $f]
+ flush $f
+ lappend l [tell $f]
+ # 4GB offset!
+ seek $f 0x100000000
+ lappend l [tell $f]
+ puts -nonewline $f abcdef
+ lappend l [tell $f]
+ close $f
+ lappend l [file size $f]
+ # truncate...
+ close [open $path(test3) w]
+ lappend l [file size $f]
+ set l
+} {0 6 6 4294967296 4294967302 4294967302 0}
+
+# Test Tcl_Eof
+
+test io-35.1 {Tcl_Eof} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f hello
+ puts $f hello
+ close $f
+ set f [open $path(test1)]
+ set x [eof $f]
+ lappend x [eof $f]
+ gets $f
+ lappend x [eof $f]
+ gets $f
+ lappend x [eof $f]
+ gets $f
+ lappend x [eof $f]
+ lappend x [eof $f]
+ close $f
+ set x
+} {0 0 0 0 1 1}
+test io-35.2 {Tcl_Eof with pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {gets stdin}
+ puts $f1 {puts hello}
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ puts $f1 hello
+ set x [eof $f1]
+ flush $f1
+ lappend x [eof $f1]
+ gets $f1
+ lappend x [eof $f1]
+ gets $f1
+ lappend x [eof $f1]
+ close $f1
+ set x
+} {0 0 0 1}
+test io-35.3 {Tcl_Eof with pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {gets stdin}
+ puts $f1 {puts hello}
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ puts $f1 hello
+ set x [eof $f1]
+ flush $f1
+ lappend x [eof $f1]
+ gets $f1
+ lappend x [eof $f1]
+ gets $f1
+ lappend x [eof $f1]
+ gets $f1
+ lappend x [eof $f1]
+ gets $f1
+ lappend x [eof $f1]
+ close $f1
+ set x
+} {0 0 0 1 1 1}
+test io-35.4 {Tcl_Eof, eof detection on nonblocking file} {nonBlockFiles} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -blocking off
+ set l ""
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {{} 1}
+test io-35.5 {Tcl_Eof, eof detection on nonblocking pipe} {stdio openpipe} {
+ file delete $path(pipe)
+ set f [open $path(pipe) w]
+ puts $f {
+ exit
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(pipe)]" r]
+ set l ""
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {{} 1}
+test io-35.6 {Tcl_Eof, eof char, lf write, auto read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $s $l $e
+} {9 8 1}
+test io-35.7 {Tcl_Eof, eof char, lf write, lf read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $s $l $e
+} {9 8 1}
+test io-35.8 {Tcl_Eof, eof char, cr write, auto read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $s $l $e
+} {9 8 1}
+test io-35.9 {Tcl_Eof, eof char, cr write, cr read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $s $l $e
+} {9 8 1}
+test io-35.10 {Tcl_Eof, eof char, crlf write, auto read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $s $l $e
+} {11 8 1}
+test io-35.11 {Tcl_Eof, eof char, crlf write, crlf read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $s $l $e
+} {11 8 1}
+test io-35.12 {Tcl_Eof, eof char in middle, lf write, auto read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ set i [format abc\ndef\n%cqrs\nuvw 26]
+ puts $f $i
+ close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $l $e
+} {17 8 1}
+test io-35.13 {Tcl_Eof, eof char in middle, lf write, lf read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ set i [format abc\ndef\n%cqrs\nuvw 26]
+ puts $f $i
+ close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $l $e
+} {17 8 1}
+test io-35.14 {Tcl_Eof, eof char in middle, cr write, auto read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar {}
+ set i [format abc\ndef\n%cqrs\nuvw 26]
+ puts $f $i
+ close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $l $e
+} {17 8 1}
+test io-35.15 {Tcl_Eof, eof char in middle, cr write, cr read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr -eofchar {}
+ set i [format abc\ndef\n%cqrs\nuvw 26]
+ puts $f $i
+ close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $l $e
+} {17 8 1}
+test io-35.16 {Tcl_Eof, eof char in middle, crlf write, auto read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -eofchar {}
+ set i [format abc\ndef\n%cqrs\nuvw 26]
+ puts $f $i
+ close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $l $e
+} {21 8 1}
+test io-35.17 {Tcl_Eof, eof char in middle, crlf write, crlf read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf -eofchar {}
+ set i [format abc\ndef\n%cqrs\nuvw 26]
+ puts $f $i
+ close $f
+ set c [file size $path(test1)]
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf -eofchar \x1a
+ set l [string length [read $f]]
+ set e [eof $f]
+ close $f
+ list $c $l $e
+} {21 8 1}
+
+# Test Tcl_InputBlocked
+
+test io-36.1 {Tcl_InputBlocked on nonblocking pipe} {stdio openpipe} {
+ set f1 [open "|[list [interpreter]]" r+]
+ puts $f1 {puts hello_from_pipe}
+ flush $f1
+ gets $f1
+ fconfigure $f1 -blocking off -buffering full
+ puts $f1 {puts hello}
+ set x ""
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ flush $f1
+ after 200
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ close $f1
+ set x
+} {{} 1 hello 0 {} 1}
+test io-36.2 {Tcl_InputBlocked on blocking pipe} {stdio openpipe} {
+ set f1 [open "|[list [interpreter]]" r+]
+ fconfigure $f1 -buffering line
+ puts $f1 {puts hello_from_pipe}
+ set x ""
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ puts $f1 {exit}
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ lappend x [eof $f1]
+ close $f1
+ set x
+} {hello_from_pipe 0 {} 0 1}
+test io-36.3 {Tcl_InputBlocked vs files, short read} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f abcdefghijklmnop
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [fblocked $f]
+ lappend l [read $f 3]
+ lappend l [fblocked $f]
+ lappend l [read -nonewline $f]
+ lappend l [fblocked $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {0 abc 0 defghijklmnop 0 1}
+test io-36.4 {Tcl_InputBlocked vs files, event driven read} {fileevent} {
+ proc in {f} {
+ variable l
+ variable x
+ lappend l [read $f 3]
+ if {[eof $f]} {lappend l eof; close $f; set x done}
+ }
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f abcdefghijklmnop
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ fileevent $f readable [namespace code [list in $f]]
+ variable x
+ vwait [namespace which -variable x]
+ set l
+} {abc def ghi jkl mno {p
+} eof}
+test io-36.5 {Tcl_InputBlocked vs files, short read, nonblocking} {nonBlockFiles} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f abcdefghijklmnop
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -blocking off
+ set l ""
+ lappend l [fblocked $f]
+ lappend l [read $f 3]
+ lappend l [fblocked $f]
+ lappend l [read -nonewline $f]
+ lappend l [fblocked $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {0 abc 0 defghijklmnop 0 1}
+test io-36.6 {Tcl_InputBlocked vs files, event driven read} {nonBlockFiles fileevent} {
+ proc in {f} {
+ variable l
+ variable x
+ lappend l [read $f 3]
+ if {[eof $f]} {lappend l eof; close $f; set x done}
+ }
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f abcdefghijklmnop
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -blocking off
+ set l ""
+ fileevent $f readable [namespace code [list in $f]]
+ variable x
+ vwait [namespace which -variable x]
+ set l
+} {abc def ghi jkl mno {p
+} eof}
+
+# Test Tcl_InputBuffered
+
+test io-37.1 {Tcl_InputBuffered} {testchannel} {
+ set f [open $path(longfile) r]
+ fconfigure $f -buffersize 4096
+ read $f 3
+ set l ""
+ lappend l [testchannel inputbuffered $f]
+ lappend l [tell $f]
+ close $f
+ set l
+} {4093 3}
+test io-37.2 {Tcl_InputBuffered, test input flushing on seek} {testchannel} {
+ set f [open $path(longfile) r]
+ fconfigure $f -buffersize 4096
+ read $f 3
+ set l ""
+ lappend l [testchannel inputbuffered $f]
+ lappend l [tell $f]
+ seek $f 0 current
+ lappend l [testchannel inputbuffered $f]
+ lappend l [tell $f]
+ close $f
+ set l
+} {4093 3 0 3}
+
+# Test Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize
+
+test io-38.1 {Tcl_GetChannelBufferSize, default buffer size} {
+ set f [open $path(longfile) r]
+ set s [fconfigure $f -buffersize]
+ close $f
+ set s
+} 4096
+test io-38.2 {Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize} {
+ set f [open $path(longfile) r]
+ set l ""
+ lappend l [fconfigure $f -buffersize]
+ fconfigure $f -buffersize 10000
+ lappend l [fconfigure $f -buffersize]
+ fconfigure $f -buffersize 1
+ lappend l [fconfigure $f -buffersize]
+ fconfigure $f -buffersize -1
+ lappend l [fconfigure $f -buffersize]
+ fconfigure $f -buffersize 0
+ lappend l [fconfigure $f -buffersize]
+ fconfigure $f -buffersize 100000
+ lappend l [fconfigure $f -buffersize]
+ fconfigure $f -buffersize 10000000
+ lappend l [fconfigure $f -buffersize]
+ close $f
+ set l
+} {4096 10000 1 1 1 100000 1048576}
+test io-38.3 {Tcl_SetChannelBufferSize, changing buffersize between reads} {
+ # This test crashes the interp if Bug #427196 is not fixed
+
+ set chan [open [info script] r]
+ fconfigure $chan -buffersize 10
+ set var [read $chan 2]
+ fconfigure $chan -buffersize 32
+ append var [read $chan]
+ close $chan
+} {}
+
+# Test Tcl_SetChannelOption, Tcl_GetChannelOption
+
+test io-39.1 {Tcl_GetChannelOption} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ set x [fconfigure $f1 -blocking]
+ close $f1
+ set x
+} 1
+#
+# Test 17.2 was removed.
+#
+test io-39.2 {Tcl_GetChannelOption} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ set x [fconfigure $f1 -buffering]
+ close $f1
+ set x
+} full
+test io-39.3 {Tcl_GetChannelOption} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -buffering line
+ set x [fconfigure $f1 -buffering]
+ close $f1
+ set x
+} line
+test io-39.4 {Tcl_GetChannelOption, Tcl_SetChannelOption} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ set l ""
+ lappend l [fconfigure $f1 -buffering]
+ fconfigure $f1 -buffering line
+ lappend l [fconfigure $f1 -buffering]
+ fconfigure $f1 -buffering none
+ lappend l [fconfigure $f1 -buffering]
+ fconfigure $f1 -buffering line
+ lappend l [fconfigure $f1 -buffering]
+ fconfigure $f1 -buffering full
+ lappend l [fconfigure $f1 -buffering]
+ close $f1
+ set l
+} {full line none line full}
+test io-39.5 {Tcl_GetChannelOption, invariance} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ set l ""
+ lappend l [fconfigure $f1 -buffering]
+ lappend l [list [catch {fconfigure $f1 -buffering green} msg] $msg]
+ lappend l [fconfigure $f1 -buffering]
+ close $f1
+ set l
+} {full {1 {bad value for -buffering: must be one of full, line, or none}} full}
+test io-39.6 {Tcl_SetChannelOption, multiple options} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -buffering line
+ puts $f1 hello
+ puts $f1 bye
+ set x [file size $path(test1)]
+ close $f1
+ set x
+} 10
+test io-39.7 {Tcl_SetChannelOption, buffering, translation} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf
+ puts $f1 hello
+ puts $f1 bye
+ set x ""
+ fconfigure $f1 -buffering line
+ lappend x [file size $path(test1)]
+ puts $f1 really_bye
+ lappend x [file size $path(test1)]
+ close $f1
+ set x
+} {0 21}
+test io-39.8 {Tcl_SetChannelOption, different buffering options} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ set l ""
+ fconfigure $f1 -translation lf -buffering none -eofchar {}
+ puts -nonewline $f1 hello
+ lappend l [file size $path(test1)]
+ puts -nonewline $f1 hello
+ lappend l [file size $path(test1)]
+ fconfigure $f1 -buffering full
+ puts -nonewline $f1 hello
+ lappend l [file size $path(test1)]
+ fconfigure $f1 -buffering none
+ lappend l [file size $path(test1)]
+ puts -nonewline $f1 hello
+ lappend l [file size $path(test1)]
+ close $f1
+ lappend l [file size $path(test1)]
+ set l
+} {5 10 10 10 20 20}
+test io-39.9 {Tcl_SetChannelOption, blocking mode} {nonBlockFiles} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ close $f1
+ set f1 [open $path(test1) r]
+ set x ""
+ lappend x [fconfigure $f1 -blocking]
+ fconfigure $f1 -blocking off
+ lappend x [fconfigure $f1 -blocking]
+ lappend x [gets $f1]
+ lappend x [read $f1 1000]
+ lappend x [fblocked $f1]
+ lappend x [eof $f1]
+ close $f1
+ set x
+} {1 0 {} {} 0 1}
+test io-39.10 {Tcl_SetChannelOption, blocking mode} {stdio openpipe} {
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {
+ gets stdin
+ after 100
+ puts hi
+ gets stdin
+ }
+ close $f1
+ set x ""
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ fconfigure $f1 -blocking off -buffering line
+ lappend x [fconfigure $f1 -blocking]
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ fconfigure $f1 -blocking on
+ puts $f1 hello
+ fconfigure $f1 -blocking off
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ fconfigure $f1 -blocking on
+ puts $f1 bye
+ fconfigure $f1 -blocking off
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ fconfigure $f1 -blocking on
+ lappend x [fconfigure $f1 -blocking]
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ lappend x [eof $f1]
+ lappend x [gets $f1]
+ lappend x [eof $f1]
+ close $f1
+ set x
+} {0 {} 1 {} 1 {} 1 1 hi 0 0 {} 1}
+test io-39.11 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size clipped to lower bound} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -buffersize -10
+ set x [fconfigure $f -buffersize]
+ close $f
+ set x
+} 1
+test io-39.12 {Tcl_SetChannelOption, Tcl_GetChannelOption buffer size clipped to upper bound} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -buffersize 10000000
+ set x [fconfigure $f -buffersize]
+ close $f
+ set x
+} 1048576
+test io-39.13 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -buffersize 40000
+ set x [fconfigure $f -buffersize]
+ close $f
+ set x
+} 40000
+test io-39.14 {Tcl_SetChannelOption: -encoding, binary & utf-8} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -encoding {}
+ puts -nonewline $f \xe7\x89\xa6
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -encoding utf-8
+ set x [read $f]
+ close $f
+ set x
+} \u7266
+test io-39.15 {Tcl_SetChannelOption: -encoding, binary & utf-8} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -encoding binary
+ puts -nonewline $f \xe7\x89\xa6
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -encoding utf-8
+ set x [read $f]
+ close $f
+ set x
+} \u7266
+test io-39.16 {Tcl_SetChannelOption: -encoding, errors} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ set result [list [catch {fconfigure $f -encoding foobar} msg] $msg]
+ close $f
+ set result
+} {1 {unknown encoding "foobar"}}
+test io-39.17 {Tcl_SetChannelOption: -encoding, clearing CHANNEL_NEED_MORE_DATA} {stdio openpipe fileevent} {
+ set f [open "|[list [interpreter] $path(cat)]" r+]
+ fconfigure $f -encoding binary
+ puts -nonewline $f "\xe7"
+ flush $f
+ fconfigure $f -encoding utf-8 -blocking 0
+ variable x {}
+ fileevent $f readable [namespace code { lappend x [read $f] }]
+ vwait [namespace which -variable x]
+ after 300 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ fconfigure $f -encoding utf-8
+ vwait [namespace which -variable x]
+ after 300 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ fconfigure $f -encoding binary
+ vwait [namespace which -variable x]
+ after 300 [namespace code { lappend x timeout }]
+ vwait [namespace which -variable x]
+ close $f
+ set x
+} "{} timeout {} timeout \xe7 timeout"
+test io-39.18 {Tcl_SetChannelOption, setting read mode independently} \
+ {socket} {
+ proc accept {s a p} {close $s}
+ set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $s1 -sockname] 2]
+ set s2 [socket 127.0.0.1 $port]
+ update
+ fconfigure $s2 -translation {auto lf}
+ set modes [fconfigure $s2 -translation]
+ close $s1
+ close $s2
+ set modes
+} {auto lf}
+test io-39.19 {Tcl_SetChannelOption, setting read mode independently} \
+ {socket} {
+ proc accept {s a p} {close $s}
+ set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $s1 -sockname] 2]
+ set s2 [socket 127.0.0.1 $port]
+ update
+ fconfigure $s2 -translation {auto crlf}
+ set modes [fconfigure $s2 -translation]
+ close $s1
+ close $s2
+ set modes
+} {auto crlf}
+test io-39.20 {Tcl_SetChannelOption, setting read mode independently} \
+ {socket} {
+ proc accept {s a p} {close $s}
+ set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $s1 -sockname] 2]
+ set s2 [socket 127.0.0.1 $port]
+ update
+ fconfigure $s2 -translation {auto cr}
+ set modes [fconfigure $s2 -translation]
+ close $s1
+ close $s2
+ set modes
+} {auto cr}
+test io-39.21 {Tcl_SetChannelOption, setting read mode independently} \
+ {socket} {
+ proc accept {s a p} {close $s}
+ set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $s1 -sockname] 2]
+ set s2 [socket 127.0.0.1 $port]
+ update
+ fconfigure $s2 -translation {auto auto}
+ set modes [fconfigure $s2 -translation]
+ close $s1
+ close $s2
+ set modes
+} {auto crlf}
+test io-39.22 {Tcl_SetChannelOption, invariance} {unix} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w+]
+ set l ""
+ lappend l [fconfigure $f1 -eofchar]
+ fconfigure $f1 -eofchar {ON GO}
+ lappend l [fconfigure $f1 -eofchar]
+ fconfigure $f1 -eofchar D
+ lappend l [fconfigure $f1 -eofchar]
+ close $f1
+ set l
+} {{{} {}} {O G} {D D}}
+test io-39.22a {Tcl_SetChannelOption, invariance} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w+]
+ set l [list]
+ fconfigure $f1 -eofchar {ON GO}
+ lappend l [fconfigure $f1 -eofchar]
+ fconfigure $f1 -eofchar D
+ lappend l [fconfigure $f1 -eofchar]
+ lappend l [list [catch {fconfigure $f1 -eofchar {1 2 3}} msg] $msg]
+ close $f1
+ set l
+} {{O G} {D D} {1 {bad value for -eofchar: should be a list of zero, one, or two elements}}}
+test io-39.23 {Tcl_GetChannelOption, server socket is not readable or
+ writeable, it should still have valid -eofchar and -translation options } {
+ set l [list]
+ set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ lappend l [fconfigure $sock -eofchar] [fconfigure $sock -translation]
+ close $sock
+ set l
+} {{{}} auto}
+test io-39.24 {Tcl_SetChannelOption, server socket is not readable or
+ writable so we can't change -eofchar or -translation } {
+ set l [list]
+ set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ fconfigure $sock -eofchar D -translation lf
+ lappend l [fconfigure $sock -eofchar] [fconfigure $sock -translation]
+ close $sock
+ set l
+} {{{}} auto}
+
+test io-40.1 {POSIX open access modes: RDWR} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ puts $f xyzzy
+ close $f
+ set f [open $path(test3) RDWR]
+ puts -nonewline $f "ab"
+ seek $f 0 current
+ set x [gets $f]
+ close $f
+ set f [open $path(test3) r]
+ lappend x [gets $f]
+ close $f
+ set x
+} {zzy abzzy}
+test io-40.2 {POSIX open access modes: CREAT} {unix} {
+ file delete $path(test3)
+ set f [open $path(test3) {WRONLY CREAT} 0o600]
+ file stat $path(test3) stats
+ set x [format "0o%o" [expr $stats(mode)&0o777]]
+ puts $f "line 1"
+ close $f
+ set f [open $path(test3) r]
+ lappend x [gets $f]
+ close $f
+ set x
+} {0o600 {line 1}}
+test io-40.3 {POSIX open access modes: CREAT} {unix umask} {
+ # This test only works if your umask is 2, like ouster's.
+ file delete $path(test3)
+ set f [open $path(test3) {WRONLY CREAT}]
+ close $f
+ file stat $path(test3) stats
+ format "0%o" [expr $stats(mode)&0o777]
+} [format %04o [expr {0o666 & ~ $umaskValue}]]
+test io-40.4 {POSIX open access modes: CREAT} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ fconfigure $f -eofchar {}
+ puts $f xyzzy
+ close $f
+ set f [open $path(test3) {WRONLY CREAT}]
+ fconfigure $f -eofchar {}
+ puts -nonewline $f "ab"
+ close $f
+ set f [open $path(test3) r]
+ set x [gets $f]
+ close $f
+ set x
+} abzzy
+test io-40.5 {POSIX open access modes: APPEND} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f xyzzy
+ close $f
+ set f [open $path(test3) {WRONLY APPEND}]
+ fconfigure $f -translation lf
+ puts $f "new line"
+ seek $f 0
+ puts $f "abc"
+ close $f
+ set f [open $path(test3) r]
+ fconfigure $f -translation lf
+ set x ""
+ seek $f 6 current
+ lappend x [gets $f]
+ lappend x [gets $f]
+ close $f
+ set x
+} {{new line} abc}
+test io-40.6 {POSIX open access modes: EXCL} -match regexp -body {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ puts $f xyzzy
+ close $f
+ open $path(test3) {WRONLY CREAT EXCL}
+} -returnCodes error -result {(?i)couldn't open ".*test3": file (already )?exists}
+test io-40.7 {POSIX open access modes: EXCL} {
+ file delete $path(test3)
+ set f [open $path(test3) {WRONLY CREAT EXCL}]
+ fconfigure $f -eofchar {}
+ puts $f "A test line"
+ close $f
+ viewFile test3
+} {A test line}
+test io-40.8 {POSIX open access modes: TRUNC} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ puts $f xyzzy
+ close $f
+ set f [open $path(test3) {WRONLY TRUNC}]
+ puts $f abc
+ close $f
+ set f [open $path(test3) r]
+ set x [gets $f]
+ close $f
+ set x
+} abc
+test io-40.9 {POSIX open access modes: NONBLOCK} {nonPortable unix} {
+ file delete $path(test3)
+ set f [open $path(test3) {WRONLY NONBLOCK CREAT}]
+ puts $f "NONBLOCK test"
+ close $f
+ set f [open $path(test3) r]
+ set x [gets $f]
+ close $f
+ set x
+} {NONBLOCK test}
+test io-40.10 {POSIX open access modes: RDONLY} {
+ set f [open $path(test1) w]
+ puts $f "two lines: this one"
+ puts $f "and this"
+ close $f
+ set f [open $path(test1) RDONLY]
+ set x [list [gets $f] [catch {puts $f Test} msg] $msg]
+ close $f
+ string compare [string tolower $x] \
+ [list {two lines: this one} 1 \
+ [format "channel \"%s\" wasn't opened for writing" $f]]
+} 0
+test io-40.11 {POSIX open access modes: RDONLY} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) RDONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test io-40.12 {POSIX open access modes: WRONLY} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) WRONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test io-40.13 {POSIX open access modes: WRONLY} {
+ makeFile xyzzy test3
+ set f [open $path(test3) WRONLY]
+ fconfigure $f -eofchar {}
+ puts -nonewline $f "ab"
+ seek $f 0 current
+ set x [list [catch {gets $f} msg] $msg]
+ close $f
+ lappend x [viewFile test3]
+ string compare [string tolower $x] \
+ [list 1 "channel \"$f\" wasn't opened for reading" abzzy]
+} 0
+test io-40.14 {POSIX open access modes: RDWR} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) RDWR
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test io-40.15 {POSIX open access modes: RDWR} {
+ makeFile xyzzy test3
+ set f [open $path(test3) RDWR]
+ puts -nonewline $f "ab"
+ seek $f 0 current
+ set x [gets $f]
+ close $f
+ lappend x [viewFile test3]
+} {zzy abzzy}
+test io-40.16 {tilde substitution in open} -constraints makeFileInHome -setup {
+ makeFile {Some text} _test_ ~
+} -body {
+ file exists [file join $::env(HOME) _test_]
+} -cleanup {
+ removeFile _test_ ~
+} -result 1
+test io-40.17 {tilde substitution in open} {
+ set home $::env(HOME)
+ unset ::env(HOME)
+ set x [list [catch {open ~/foo} msg] $msg]
+ set ::env(HOME) $home
+ set x
+} {1 {couldn't find HOME environment variable to expand path}}
+
+test io-41.1 {Tcl_FileeventCmd: errors} {fileevent} {
+ list [catch {fileevent foo} msg] $msg
+} {1 {wrong # args: should be "fileevent channelId event ?script?"}}
+test io-41.2 {Tcl_FileeventCmd: errors} {fileevent} {
+ list [catch {fileevent foo bar baz q} msg] $msg
+} {1 {wrong # args: should be "fileevent channelId event ?script?"}}
+test io-41.3 {Tcl_FileeventCmd: errors} {fileevent} {
+ list [catch {fileevent gorp readable} msg] $msg
+} {1 {can not find channel named "gorp"}}
+test io-41.4 {Tcl_FileeventCmd: errors} {fileevent} {
+ list [catch {fileevent gorp writable} msg] $msg
+} {1 {can not find channel named "gorp"}}
+test io-41.5 {Tcl_FileeventCmd: errors} {fileevent} {
+ list [catch {fileevent gorp who-knows} msg] $msg
+} {1 {bad event name "who-knows": must be readable or writable}}
+
+#
+# Test fileevent on a file
+#
+
+set path(foo) [makeFile {} foo]
+set f [open $path(foo) w+]
+
+test io-42.1 {Tcl_FileeventCmd: creating, deleting, querying} {fileevent} {
+ list [fileevent $f readable] [fileevent $f writable]
+} {{} {}}
+test io-42.2 {Tcl_FileeventCmd: replacing} {fileevent} {
+ set result {}
+ fileevent $f r "first script"
+ lappend result [fileevent $f readable]
+ fileevent $f r "new script"
+ lappend result [fileevent $f readable]
+ fileevent $f r "yet another"
+ lappend result [fileevent $f readable]
+ fileevent $f r ""
+ lappend result [fileevent $f readable]
+} {{first script} {new script} {yet another} {}}
+test io-42.3 {Tcl_FileeventCmd: replacing, with NULL chars in script} {fileevent} {
+ set result {}
+ fileevent $f r "first scr\0ipt"
+ lappend result [string length [fileevent $f readable]]
+ fileevent $f r "new scr\0ipt"
+ lappend result [string length [fileevent $f readable]]
+ fileevent $f r "yet ano\0ther"
+ lappend result [string length [fileevent $f readable]]
+ fileevent $f r ""
+ lappend result [fileevent $f readable]
+} {13 11 12 {}}
+
+
+test io-43.1 {Tcl_FileeventCmd: creating, deleting, querying} {stdio unixExecs fileevent} {
+ set result {}
+ fileevent $f readable "script 1"
+ lappend result [fileevent $f readable] [fileevent $f writable]
+ fileevent $f writable "write script"
+ lappend result [fileevent $f readable] [fileevent $f writable]
+ fileevent $f readable {}
+ lappend result [fileevent $f readable] [fileevent $f writable]
+ fileevent $f writable {}
+ lappend result [fileevent $f readable] [fileevent $f writable]
+} {{script 1} {} {script 1} {write script} {} {write script} {} {}}
+test io-43.2 {Tcl_FileeventCmd: deleting when many present} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+ set result {}
+ lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
+ fileevent $f r "read f"
+ fileevent $f2 r "read f2"
+ fileevent $f3 r "read f3"
+ lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
+ fileevent $f2 r {}
+ lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
+ fileevent $f3 r {}
+ lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
+ fileevent $f r {}
+ lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
+} -cleanup {
+ catch {close $f2}
+ catch {close $f3}
+} -result {{} {} {} {read f} {read f2} {read f3} {read f} {} {read f3} {read f} {} {} {} {} {}}
+
+test io-44.1 {FileEventProc procedure: normal read event} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+ fileevent $f2 readable [namespace code {
+ set x [gets $f2]; fileevent $f2 readable {}
+ }]
+ puts $f2 text; flush $f2
+ variable x initial
+ vwait [namespace which -variable x]
+ set x
+} -cleanup {
+ catch {close $f2}
+ catch {close $f3}
+} -result {text}
+test io-44.2 {FileEventProc procedure: error in read event} -constraints {
+ stdio unixExecs fileevent openpipe
+} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+ proc myHandler {msg options} {
+ variable x $msg
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+} -body {
+ fileevent $f2 readable {error bogus}
+ puts $f2 text; flush $f2
+ variable x initial
+ vwait [namespace which -variable x]
+ list $x [fileevent $f2 readable]
+} -cleanup {
+ interp bgerror {} $handler
+ catch {close $f2}
+ catch {close $f3}
+} -result {bogus {}}
+test io-44.3 {FileEventProc procedure: normal write event} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+ fileevent $f2 writable [namespace code {
+ lappend x "triggered"
+ incr count -1
+ if {$count <= 0} {
+ fileevent $f2 writable {}
+ }
+ }]
+ variable x initial
+ set count 3
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ set x
+} -cleanup {
+ catch {close $f2}
+ catch {close $f3}
+} -result {initial triggered triggered triggered}
+test io-44.4 {FileEventProc procedure: eror in write event} -constraints {
+ stdio unixExecs fileevent openpipe
+} -setup {
+ set f2 [open "|[list cat -u]" r+]
+ set f3 [open "|[list cat -u]" r+]
+ proc myHandler {msg options} {
+ variable x $msg
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+} -body {
+ fileevent $f2 writable {error bad-write}
+ variable x initial
+ vwait [namespace which -variable x]
+ list $x [fileevent $f2 writable]
+} -cleanup {
+ interp bgerror {} $handler
+ catch {close $f2}
+ catch {close $f3}
+} -result {bad-write {}}
+test io-44.5 {FileEventProc procedure: end of file} {stdio unixExecs openpipe fileevent} {
+ set f4 [open "|[list [interpreter] $path(cat) << foo]" r]
+ fileevent $f4 readable [namespace code {
+ if {[gets $f4 line] < 0} {
+ lappend x eof
+ fileevent $f4 readable {}
+ } else {
+ lappend x $line
+ }
+ }]
+ variable x initial
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ close $f4
+ set x
+} {initial foo eof}
+
+close $f
+makeFile "foo bar" foo
+
+test io-45.1 {DeleteFileEvent, cleanup on close} {fileevent} {
+ set f [open $path(foo) r]
+ fileevent $f readable [namespace code {
+ lappend x "binding triggered: \"[gets $f]\""
+ fileevent $f readable {}
+ }]
+ close $f
+ set x initial
+ after 100 [namespace code { set y done }]
+ variable y
+ vwait [namespace which -variable y]
+ set x
+} {initial}
+test io-45.2 {DeleteFileEvent, cleanup on close} {fileevent} {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ fileevent $f readable [namespace code {
+ lappend x "f triggered: \"[gets $f]\""
+ fileevent $f readable {}
+ }]
+ fileevent $f2 readable [namespace code {
+ lappend x "f2 triggered: \"[gets $f2]\""
+ fileevent $f2 readable {}
+ }]
+ close $f
+ variable x initial
+ vwait [namespace which -variable x]
+ close $f2
+ set x
+} {initial {f2 triggered: "foo bar"}}
+test io-45.3 {DeleteFileEvent, cleanup on close} {fileevent} {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ set f3 [open $path(foo) r]
+ fileevent $f readable {f script}
+ fileevent $f2 readable {f2 script}
+ fileevent $f3 readable {f3 script}
+ set x {}
+ close $f2
+ lappend x [catch {fileevent $f readable} msg] $msg \
+ [catch {fileevent $f2 readable}] \
+ [catch {fileevent $f3 readable} msg] $msg
+ close $f3
+ lappend x [catch {fileevent $f readable} msg] $msg \
+ [catch {fileevent $f2 readable}] \
+ [catch {fileevent $f3 readable}]
+ close $f
+ lappend x [catch {fileevent $f readable}] \
+ [catch {fileevent $f2 readable}] \
+ [catch {fileevent $f3 readable}]
+} {0 {f script} 1 0 {f3 script} 0 {f script} 1 1 1 1 1}
+
+# Execute these tests only if the "testfevent" command is present.
+
+test io-46.1 {Tcl event loop vs multiple interpreters} {testfevent fileevent} {
+ testfevent create
+ set script "set f \[[list open $path(foo) r]]\n"
+ append script {
+ set x "no event"
+ fileevent $f readable [namespace code {
+ set x "f triggered: [gets $f]"
+ fileevent $f readable {}
+ }]
+ }
+ testfevent cmd $script
+ after 1 ;# We must delay because Windows takes a little time to notice
+ update
+ testfevent cmd {close $f}
+ list [testfevent cmd {set x}] [testfevent cmd {info commands after}]
+} {{f triggered: foo bar} after}
+test io-46.2 {Tcl event loop vs multiple interpreters} testfevent {
+ testfevent create
+ testfevent cmd {
+ variable x 0
+ after 100 {set x triggered}
+ vwait [namespace which -variable x]
+ set x
+ }
+} {triggered}
+test io-46.3 {Tcl event loop vs multiple interpreters} testfevent {
+ testfevent create
+ testfevent cmd {
+ set x 0
+ after 10 {lappend x timer}
+ after 30
+ set result $x
+ update idletasks
+ lappend result $x
+ update
+ lappend result $x
+ }
+} {0 0 {0 timer}}
+
+test io-47.1 {fileevent vs multiple interpreters} {testfevent fileevent} {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ set f3 [open $path(foo) r]
+ fileevent $f readable {script 1}
+ testfevent create
+ testfevent share $f2
+ testfevent cmd "fileevent $f2 readable {script 2}"
+ fileevent $f3 readable {sript 3}
+ set x {}
+ lappend x [fileevent $f2 readable]
+ testfevent delete
+ lappend x [fileevent $f readable] [fileevent $f2 readable] \
+ [fileevent $f3 readable]
+ close $f
+ close $f2
+ close $f3
+ set x
+} {{} {script 1} {} {sript 3}}
+test io-47.2 {deleting fileevent on interpreter delete} {testfevent fileevent} {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ set f3 [open $path(foo) r]
+ set f4 [open $path(foo) r]
+ fileevent $f readable {script 1}
+ testfevent create
+ testfevent share $f2
+ testfevent share $f3
+ testfevent cmd "fileevent $f2 readable {script 2}
+ fileevent $f3 readable {script 3}"
+ fileevent $f4 readable {script 4}
+ testfevent delete
+ set x [list [fileevent $f readable] [fileevent $f2 readable] \
+ [fileevent $f3 readable] [fileevent $f4 readable]]
+ close $f
+ close $f2
+ close $f3
+ close $f4
+ set x
+} {{script 1} {} {} {script 4}}
+test io-47.3 {deleting fileevent on interpreter delete} {testfevent fileevent} {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ set f3 [open $path(foo) r]
+ set f4 [open $path(foo) r]
+ testfevent create
+ testfevent share $f3
+ testfevent share $f4
+ fileevent $f readable {script 1}
+ fileevent $f2 readable {script 2}
+ testfevent cmd "fileevent $f3 readable {script 3}
+ fileevent $f4 readable {script 4}"
+ testfevent delete
+ set x [list [fileevent $f readable] [fileevent $f2 readable] \
+ [fileevent $f3 readable] [fileevent $f4 readable]]
+ close $f
+ close $f2
+ close $f3
+ close $f4
+ set x
+} {{script 1} {script 2} {} {}}
+test io-47.4 {file events on shared files and multiple interpreters} {testfevent fileevent} {
+ set f [open $path(foo) r]
+ set f2 [open $path(foo) r]
+ testfevent create
+ testfevent share $f
+ testfevent cmd "fileevent $f readable {script 1}"
+ fileevent $f readable {script 2}
+ fileevent $f2 readable {script 3}
+ set x [list [fileevent $f2 readable] \
+ [testfevent cmd "fileevent $f readable"] \
+ [fileevent $f readable]]
+ testfevent delete
+ close $f
+ close $f2
+ set x
+} {{script 3} {script 1} {script 2}}
+test io-47.5 {file events on shared files, deleting file events} {testfevent fileevent} {
+ set f [open $path(foo) r]
+ testfevent create
+ testfevent share $f
+ testfevent cmd "fileevent $f readable {script 1}"
+ fileevent $f readable {script 2}
+ testfevent cmd "fileevent $f readable {}"
+ set x [list [testfevent cmd "fileevent $f readable"] \
+ [fileevent $f readable]]
+ testfevent delete
+ close $f
+ set x
+} {{} {script 2}}
+test io-47.6 {file events on shared files, deleting file events} {testfevent fileevent} {
+ set f [open $path(foo) r]
+ testfevent create
+ testfevent share $f
+ testfevent cmd "fileevent $f readable {script 1}"
+ fileevent $f readable {script 2}
+ fileevent $f readable {}
+ set x [list [testfevent cmd "fileevent $f readable"] \
+ [fileevent $f readable]]
+ testfevent delete
+ close $f
+ set x
+} {{script 1} {}}
+
+set path(bar) [makeFile {} bar]
+
+test io-48.1 {testing readability conditions} {fileevent} {
+ set f [open $path(bar) w]
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ close $f
+ set f [open $path(bar) r]
+ fileevent $f readable [namespace code [list consume $f]]
+ proc consume {f} {
+ variable l
+ variable x
+ lappend l called
+ if {[eof $f]} {
+ close $f
+ set x done
+ } else {
+ gets $f
+ }
+ }
+ set l ""
+ variable x not_done
+ vwait [namespace which -variable x]
+ list $x $l
+} {done {called called called called called called called}}
+test io-48.2 {testing readability conditions} {nonBlockFiles fileevent} {
+ set f [open $path(bar) w]
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ close $f
+ set f [open $path(bar) r]
+ fileevent $f readable [namespace code [list consume $f]]
+ fconfigure $f -blocking off
+ proc consume {f} {
+ variable x
+ variable l
+ lappend l called
+ if {[eof $f]} {
+ close $f
+ set x done
+ } else {
+ gets $f
+ }
+ }
+ set l ""
+ variable x not_done
+ vwait [namespace which -variable x]
+ list $x $l
+} {done {called called called called called called called}}
+set path(my_script) [makeFile {} my_script]
+test io-48.3 {testing readability conditions} {stdio unix nonBlockFiles openpipe fileevent} {
+ set f [open $path(bar) w]
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ close $f
+ set f [open $path(my_script) w]
+ puts $f {
+ proc copy_slowly {f} {
+ while {![eof $f]} {
+ puts [gets $f]
+ after 200
+ }
+ close $f
+ }
+ }
+ close $f
+ set f [open "|[list [interpreter]]" r+]
+ fileevent $f readable [namespace code [list consume $f]]
+ fconfigure $f -buffering line
+ fconfigure $f -blocking off
+ proc consume {f} {
+ variable l
+ variable x
+ if {[eof $f]} {
+ set x done
+ } else {
+ gets $f
+ lappend l [fblocked $f]
+ gets $f
+ lappend l [fblocked $f]
+ }
+ }
+ set l ""
+ variable x not_done
+ puts $f [list source $path(my_script)]
+ puts $f "set f \[[list open $path(bar) r]]"
+ puts $f {copy_slowly $f}
+ puts $f {exit}
+ vwait [namespace which -variable x]
+ close $f
+ list $x $l
+} {done {0 1 0 1 0 1 0 1 0 1 0 1 0 0}}
+test io-48.4 {lf write, testing readability, ^Z termination, auto read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ variable c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable c
+ variable x
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.5 {lf write, testing readability, ^Z in middle, auto read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable x
+ variable c
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.6 {cr write, testing readability, ^Z termination, auto read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ set c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable x
+ variable c
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.7 {cr write, testing readability, ^Z in middle, auto read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable c
+ variable x
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.8 {crlf write, testing readability, ^Z termination, auto read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable x
+ variable c
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -translation auto -eofchar \x1a
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.9 {crlf write, testing readability, ^Z in middle, auto read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable c
+ variable x
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation auto
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.10 {lf write, testing readability, ^Z in middle, lf read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable c
+ variable x
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation lf
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.11 {lf write, testing readability, ^Z termination, lf read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ set c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable x
+ variable c
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -translation lf -eofchar \x1a
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.12 {cr write, testing readability, ^Z in middle, cr read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable l
+ variable x
+ variable c
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation cr
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.13 {cr write, testing readability, ^Z termination, cr read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation cr
+ set c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable c
+ variable x
+ variable l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -translation cr -eofchar \x1a
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.14 {crlf write, testing readability, ^Z in middle, crlf read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable c
+ variable x
+ variable l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -eofchar \x1a -translation crlf
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+test io-48.15 {crlf write, testing readability, ^Z termi, crlf read mode} {fileevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation crlf
+ set c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ variable c
+ variable x
+ variable l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open $path(test1) r]
+ fconfigure $f -translation crlf -eofchar \x1a
+ fileevent $f readable [namespace code [list consume $f]]
+ variable x
+ vwait [namespace which -variable x]
+ list $c $l
+} {3 {abc def {}}}
+
+test io-49.1 {testing crlf reading, leftover cr disgorgment} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\rb\rc\r\n"
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [file size $path(test1)]
+ fconfigure $f -translation crlf
+ lappend l [read $f 1]
+ lappend l [tell $f]
+ lappend l [read $f 1]
+ lappend l [tell $f]
+ lappend l [read $f 1]
+ lappend l [tell $f]
+ lappend l [read $f 1]
+ lappend l [tell $f]
+ lappend l [read $f 1]
+ lappend l [tell $f]
+ lappend l [read $f 1]
+ lappend l [tell $f]
+ lappend l [eof $f]
+ lappend l [read $f 1]
+ lappend l [eof $f]
+ close $f
+ set l
+} "7 a 1 [list \r] 2 b 3 [list \r] 4 c 5 {
+} 7 0 {} 1"
+test io-49.2 {testing crlf reading, leftover cr disgorgment} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\rb\rc\r\n"
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [file size $path(test1)]
+ fconfigure $f -translation crlf
+ lappend l [read $f 2]
+ lappend l [tell $f]
+ lappend l [read $f 2]
+ lappend l [tell $f]
+ lappend l [read $f 2]
+ lappend l [tell $f]
+ lappend l [eof $f]
+ lappend l [read $f 2]
+ lappend l [tell $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} "7 [list a\r] 2 [list b\r] 4 [list c\n] 7 0 {} 7 1"
+test io-49.3 {testing crlf reading, leftover cr disgorgment} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\rb\rc\r\n"
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [file size $path(test1)]
+ fconfigure $f -translation crlf
+ lappend l [read $f 3]
+ lappend l [tell $f]
+ lappend l [read $f 3]
+ lappend l [tell $f]
+ lappend l [eof $f]
+ lappend l [read $f 3]
+ lappend l [tell $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} "7 [list a\rb] 3 [list \rc\n] 7 0 {} 7 1"
+test io-49.4 {testing crlf reading, leftover cr disgorgment} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\rb\rc\r\n"
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [file size $path(test1)]
+ fconfigure $f -translation crlf
+ lappend l [read $f 3]
+ lappend l [tell $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} "7 [list a\rb] 3 [list \rc] 7 0 {} 7 1"
+test io-49.5 {testing crlf reading, leftover cr disgorgment} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts -nonewline $f "a\rb\rc\r\n"
+ close $f
+ set f [open $path(test1) r]
+ set l ""
+ lappend l [file size $path(test1)]
+ fconfigure $f -translation crlf
+ lappend l [set x [gets $f]]
+ lappend l [tell $f]
+ lappend l [gets $f]
+ lappend l [tell $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} [list 7 a\rb\rc 7 {} 7 1]
+
+test io-50.1 {testing handler deletion} {testchannelevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list delhandler $f]]
+ proc delhandler {f} {
+ variable z
+ set z called
+ testchannelevent $f delete 0
+ }
+ set z not_called
+ update
+ close $f
+ set z
+} called
+test io-50.2 {testing handler deletion with multiple handlers} {testchannelevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list delhandler $f 1]]
+ testchannelevent $f add readable [namespace code [list delhandler $f 0]]
+ proc delhandler {f i} {
+ variable z
+ lappend z "called delhandler $f $i"
+ testchannelevent $f delete 0
+ }
+ set z ""
+ update
+ close $f
+ string compare [string tolower $z] \
+ [list [list called delhandler $f 0] [list called delhandler $f 1]]
+} 0
+test io-50.3 {testing handler deletion with multiple handlers} {testchannelevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list notcalled $f 1]]
+ testchannelevent $f add readable [namespace code [list delhandler $f 0]]
+ set z ""
+ proc notcalled {f i} {
+ variable z
+ lappend z "notcalled was called!! $f $i"
+ }
+ proc delhandler {f i} {
+ variable z
+ testchannelevent $f delete 1
+ lappend z "delhandler $f $i called"
+ testchannelevent $f delete 0
+ lappend z "delhandler $f $i deleted myself"
+ }
+ set z ""
+ update
+ close $f
+ string compare [string tolower $z] \
+ [list [list delhandler $f 0 called] \
+ [list delhandler $f 0 deleted myself]]
+} 0
+test io-50.4 {testing handler deletion vs reentrant calls} {testchannelevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list delrecursive $f]]
+ proc delrecursive {f} {
+ variable z
+ variable u
+ if {"$u" == "recursive"} {
+ testchannelevent $f delete 0
+ lappend z "delrecursive deleting recursive"
+ } else {
+ lappend z "delrecursive calling recursive"
+ set u recursive
+ update
+ }
+ }
+ variable u toplevel
+ variable z ""
+ update
+ close $f
+ string compare [string tolower $z] \
+ {{delrecursive calling recursive} {delrecursive deleting recursive}}
+} 0
+test io-50.5 {testing handler deletion vs reentrant calls} {testchannelevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list notcalled $f]]
+ testchannelevent $f add readable [namespace code [list del $f]]
+ proc notcalled {f} {
+ variable z
+ lappend z "notcalled was called!! $f"
+ }
+ proc del {f} {
+ variable u
+ variable z
+ if {"$u" == "recursive"} {
+ testchannelevent $f delete 1
+ testchannelevent $f delete 0
+ lappend z "del deleted notcalled"
+ lappend z "del deleted myself"
+ } else {
+ set u recursive
+ lappend z "del calling recursive"
+ update
+ lappend z "del after update"
+ }
+ }
+ set z ""
+ set u toplevel
+ update
+ close $f
+ string compare [string tolower $z] \
+ [list {del calling recursive} {del deleted notcalled} \
+ {del deleted myself} {del after update}]
+} 0
+test io-50.6 {testing handler deletion vs reentrant calls} {testchannelevent} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ close $f
+ set f [open $path(test1) r]
+ testchannelevent $f add readable [namespace code [list second $f]]
+ testchannelevent $f add readable [namespace code [list first $f]]
+ proc first {f} {
+ variable u
+ variable z
+ if {"$u" == "toplevel"} {
+ lappend z "first called"
+ set u first
+ update
+ lappend z "first after update"
+ } else {
+ lappend z "first called not toplevel"
+ }
+ }
+ proc second {f} {
+ variable u
+ variable z
+ if {"$u" == "first"} {
+ lappend z "second called, first time"
+ set u second
+ testchannelevent $f delete 0
+ } elseif {"$u" == "second"} {
+ lappend z "second called, second time"
+ testchannelevent $f delete 0
+ } else {
+ lappend z "second called, cannot happen!"
+ testchannelevent $f removeall
+ }
+ }
+ set z ""
+ set u toplevel
+ update
+ close $f
+ string compare [string tolower $z] \
+ [list {first called} {first called not toplevel} \
+ {second called, first time} {second called, second time} \
+ {first after update}]
+} 0
+
+test io-51.1 {Test old socket deletion on Macintosh} {socket} {
+ set x 0
+ set result ""
+ proc accept {s a p} {
+ variable x
+ variable wait
+ fconfigure $s -blocking off
+ puts $s "sock[incr x]"
+ close $s
+ set wait done
+ }
+ set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $ss -sockname] 2]
+
+ variable wait ""
+ set cs [socket 127.0.0.1 $port]
+ vwait [namespace which -variable wait]
+ lappend result [gets $cs]
+ close $cs
+
+ set wait ""
+ set cs [socket 127.0.0.1 $port]
+ vwait [namespace which -variable wait]
+ lappend result [gets $cs]
+ close $cs
+
+ set wait ""
+ set cs [socket 127.0.0.1 $port]
+ vwait [namespace which -variable wait]
+ lappend result [gets $cs]
+ close $cs
+
+ set wait ""
+ set cs [socket 127.0.0.1 $port]
+ vwait [namespace which -variable wait]
+ lappend result [gets $cs]
+ close $cs
+ close $ss
+ set result
+} {sock1 sock2 sock3 sock4}
+
+test io-52.1 {TclCopyChannel} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fcopy $f1 $f2 -command { # }
+ catch { fcopy $f1 $f2 } msg
+ close $f1
+ close $f2
+ string compare $msg "channel \"$f1\" is busy"
+} {0}
+test io-52.2 {TclCopyChannel} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ set f3 [open $thisScript]
+ fcopy $f1 $f2 -command { # }
+ catch { fcopy $f3 $f2 } msg
+ close $f1
+ close $f2
+ close $f3
+ string compare $msg "channel \"$f2\" is busy"
+} {0}
+test io-52.3 {TclCopyChannel} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation cr -blocking 0
+ set s0 [fcopy $f1 $f2]
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ close $f1
+ close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {("$s1" == "$s2") && ($s0 == $s1)} {
+ lappend result ok
+ }
+ set result
+} {0 0 ok}
+test io-52.4 {TclCopyChannel} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation cr -blocking 0
+ fcopy $f1 $f2 -size 40
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ close $f1
+ close $f2
+ lappend result [file size $path(test1)]
+} {0 0 40}
+test io-52.5 {TclCopyChannel, all} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation lf -blocking 0
+ fcopy $f1 $f2 -size -1 ;# -1 means 'copy all', same as if no -size specified.
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ close $f1
+ close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {"$s1" == "$s2"} {
+ lappend result ok
+ }
+ set result
+} {0 0 ok}
+test io-52.5a {TclCopyChannel, all, other negative value} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation lf -blocking 0
+ fcopy $f1 $f2 -size -2 ;# < 0 behaves like -1, copy all
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ close $f1
+ close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {"$s1" == "$s2"} {
+ lappend result ok
+ }
+ set result
+} {0 0 ok}
+test io-52.5b {TclCopyChannel, all, wrap to negative value} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation lf -blocking 0
+ fcopy $f1 $f2 -size 3221176172 ;# Wrapped to < 0, behaves like -1, copy all
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ close $f1
+ close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {"$s1" == "$s2"} {
+ lappend result ok
+ }
+ set result
+} {0 0 ok}
+test io-52.6 {TclCopyChannel} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation lf -blocking 0
+ set s0 [fcopy $f1 $f2 -size [expr [file size $thisScript] + 5]]
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ close $f1
+ close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {("$s1" == "$s2") && ($s0 == $s1)} {
+ lappend result ok
+ }
+ set result
+} {0 0 ok}
+test io-52.7 {TclCopyChannel} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation lf -blocking 0
+ fcopy $f1 $f2
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ close $f1
+ close $f2
+ if {"$s1" == "$s2"} {
+ lappend result ok
+ }
+ set result
+} {0 0 ok}
+test io-52.8 {TclCopyChannel} {stdio openpipe fcopy} {
+ file delete $path(test1)
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ fconfigure $f1 -translation lf
+ puts $f1 "
+ puts ready
+ gets stdin
+ set f1 \[open [list $thisScript] r\]
+ fconfigure \$f1 -translation lf
+ puts \[read \$f1 100\]
+ close \$f1
+ "
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ fconfigure $f1 -translation lf
+ gets $f1
+ puts $f1 ready
+ flush $f1
+ set f2 [open $path(test1) w]
+ fconfigure $f2 -translation lf
+ set s0 [fcopy $f1 $f2 -size 40]
+ catch {close $f1}
+ close $f2
+ list $s0 [file size $path(test1)]
+} {40 40}
+# Empty files, to register them with the test facility
+set path(kyrillic.txt) [makeFile {} kyrillic.txt]
+set path(utf8-fcopy.txt) [makeFile {} utf8-fcopy.txt]
+set path(utf8-rp.txt) [makeFile {} utf8-rp.txt]
+# Create kyrillic file, use lf translation to avoid os eol issues
+set out [open $path(kyrillic.txt) w]
+fconfigure $out -encoding koi8-r -translation lf
+puts $out "\u0410\u0410"
+close $out
+test io-52.9 {TclCopyChannel & encodings} {fcopy} {
+ # Copy kyrillic to UTF-8, using fcopy.
+
+ set in [open $path(kyrillic.txt) r]
+ set out [open $path(utf8-fcopy.txt) w]
+
+ fconfigure $in -encoding koi8-r -translation lf
+ fconfigure $out -encoding utf-8 -translation lf
+
+ fcopy $in $out
+ close $in
+ close $out
+
+ # Do the same again, but differently (read/puts).
+
+ set in [open $path(kyrillic.txt) r]
+ set out [open $path(utf8-rp.txt) w]
+
+ fconfigure $in -encoding koi8-r -translation lf
+ fconfigure $out -encoding utf-8 -translation lf
+
+ puts -nonewline $out [read $in]
+
+ close $in
+ close $out
+
+ list [file size $path(kyrillic.txt)] \
+ [file size $path(utf8-fcopy.txt)] \
+ [file size $path(utf8-rp.txt)]
+} {3 5 5}
+test io-52.10 {TclCopyChannel & encodings} {fcopy} {
+ # encoding to binary (=> implies that the
+ # internal utf-8 is written)
+
+ set in [open $path(kyrillic.txt) r]
+ set out [open $path(utf8-fcopy.txt) w]
+
+ fconfigure $in -encoding koi8-r -translation lf
+ # -translation binary is also -encoding binary
+ fconfigure $out -translation binary
+
+ fcopy $in $out
+ close $in
+ close $out
+
+ file size $path(utf8-fcopy.txt)
+} 5
+test io-52.11 {TclCopyChannel & encodings} {fcopy} {
+ # binary to encoding => the input has to be
+ # in utf-8 to make sense to the encoder
+
+ set in [open $path(utf8-fcopy.txt) r]
+ set out [open $path(kyrillic.txt) w]
+
+ # -translation binary is also -encoding binary
+ fconfigure $in -translation binary
+ fconfigure $out -encoding koi8-r -translation lf
+
+ fcopy $in $out
+ close $in
+ close $out
+
+ file size $path(kyrillic.txt)
+} 3
+
+test io-53.1 {CopyData} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation cr -blocking 0
+ fcopy $f1 $f2 -size 0
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ close $f1
+ close $f2
+ lappend result [file size $path(test1)]
+} {0 0 0}
+test io-53.2 {CopyData} {fcopy} {
+ file delete $path(test1)
+ set f1 [open $thisScript]
+ set f2 [open $path(test1) w]
+ fconfigure $f1 -translation lf -blocking 0
+ fconfigure $f2 -translation cr -blocking 0
+ fcopy $f1 $f2 -command [namespace code {set s0}]
+ set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+ variable s0
+ vwait [namespace which -variable s0]
+ close $f1
+ close $f2
+ set s1 [file size $thisScript]
+ set s2 [file size $path(test1)]
+ if {("$s1" == "$s2") && ($s0 == $s1)} {
+ lappend result ok
+ }
+ set result
+} {0 0 ok}
+test io-53.3 {CopyData: background read underflow} {stdio unix openpipe fcopy} {
+ file delete $path(test1)
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts -nonewline $f1 {
+ puts ready
+ flush stdout ;# Don't assume line buffered!
+ fcopy stdin stdout -command { set x }
+ vwait x
+ set f [}
+ puts $f1 [list open $path(test1) w]]
+ puts $f1 {
+ fconfigure $f -translation lf
+ puts $f "done"
+ close $f
+ }
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ set result [gets $f1]
+ puts $f1 line1
+ flush $f1
+ lappend result [gets $f1]
+ puts $f1 line2
+ flush $f1
+ lappend result [gets $f1]
+ close $f1
+ after 500
+ set f [open $path(test1)]
+ lappend result [read $f]
+ close $f
+ set result
+} "ready line1 line2 {done\n}"
+test io-53.4 {CopyData: background write overflow} {stdio unix openpipe fileevent fcopy} {
+ set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n
+ variable x
+ for {set x 0} {$x < 12} {incr x} {
+ append big $big
+ }
+ file delete $path(test1)
+ file delete $path(pipe)
+ set f1 [open $path(pipe) w]
+ puts $f1 {
+ puts ready
+ fcopy stdin stdout -command { set x }
+ vwait x
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf
+ puts $f "done"
+ close $f
+ }
+ close $f1
+ set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+ set result [gets $f1]
+ fconfigure $f1 -blocking 0
+ puts $f1 $big
+ flush $f1
+ after 500
+ set result ""
+ fileevent $f1 read [namespace code {
+ append result [read $f1 1024]
+ if {[string length $result] >= [string length $big]} {
+ set x done
+ }
+ }]
+ vwait [namespace which -variable x]
+ close $f1
+ set big {}
+ set x
+} done
+set result {}
+proc FcopyTestAccept {sock args} {
+ after 1000 "close $sock"
+}
+proc FcopyTestDone {bytes {error {}}} {
+ variable fcopyTestDone
+ if {[string length $error]} {
+ set fcopyTestDone 1
+ } else {
+ set fcopyTestDone 0
+ }
+}
+test io-53.5 {CopyData: error during fcopy} {socket fcopy} {
+ variable fcopyTestDone
+ set listen [socket -server [namespace code FcopyTestAccept] -myaddr 127.0.0.1 0]
+ set in [open $thisScript] ;# 126 K
+ set out [socket 127.0.0.1 [lindex [fconfigure $listen -sockname] 2]]
+ catch {unset fcopyTestDone}
+ close $listen ;# This means the socket open never really succeeds
+ fcopy $in $out -command [namespace code FcopyTestDone]
+ variable fcopyTestDone
+ if ![info exists fcopyTestDone] {
+ vwait [namespace which -variable fcopyTestDone] ;# The error occurs here in the b.g.
+ }
+ close $in
+ close $out
+ set fcopyTestDone ;# 1 for error condition
+} 1
+test io-53.6 {CopyData: error during fcopy} {stdio openpipe fcopy} {
+ variable fcopyTestDone
+ file delete $path(pipe)
+ file delete $path(test1)
+ catch {unset fcopyTestDone}
+ set f1 [open $path(pipe) w]
+ puts $f1 "exit 1"
+ close $f1
+ set in [open "|[list [interpreter] $path(pipe)]" r+]
+ set out [open $path(test1) w]
+ fcopy $in $out -command [namespace code FcopyTestDone]
+ variable fcopyTestDone
+ if ![info exists fcopyTestDone] {
+ vwait [namespace which -variable fcopyTestDone]
+ }
+ catch {close $in}
+ close $out
+ set fcopyTestDone ;# 0 for plain end of file
+} {0}
+proc doFcopy {in out {bytes 0} {error {}}} {
+ variable fcopyTestDone
+ variable fcopyTestCount
+ incr fcopyTestCount $bytes
+ if {[string length $error]} {
+ set fcopyTestDone 1
+ } elseif {[eof $in]} {
+ set fcopyTestDone 0
+ } else {
+ # Delay next fcopy to wait for size>0 input bytes
+ after 100 [list fcopy $in $out -size 1000 \
+ -command [namespace code [list doFcopy $in $out]]]
+ }
+}
+test io-53.7 {CopyData: Flooding fcopy from pipe} {stdio openpipe fcopy} {
+ variable fcopyTestDone
+ file delete $path(pipe)
+ catch {unset fcopyTestDone}
+ set fcopyTestCount 0
+ set f1 [open $path(pipe) w]
+ puts $f1 {
+ # Write 10 bytes / 10 msec
+ proc Write {count} {
+ puts -nonewline "1234567890"
+ if {[incr count -1]} {
+ after 10 [list Write $count]
+ } else {
+ set ::ready 1
+ }
+ }
+ fconfigure stdout -buffering none
+ Write 345 ;# 3450 bytes ~3.45 sec
+ vwait ready
+ exit 0
+ }
+ close $f1
+ set in [open "|[list [interpreter] $path(pipe) &]" r+]
+ set out [open $path(test1) w]
+ doFcopy $in $out
+ variable fcopyTestDone
+ if ![info exists fcopyTestDone] {
+ vwait [namespace which -variable fcopyTestDone]
+ }
+ catch {close $in}
+ close $out
+ # -1=error 0=script error N=number of bytes
+ expr ($fcopyTestDone == 0) ? $fcopyTestCount : -1
+} {3450}
+test io-53.8 {CopyData: async callback and error handling, Bug 1932639} -setup {
+ # copy progress callback. errors out intentionally
+ proc ::cmd args {
+ lappend ::RES "CMD $args"
+ error !STOP
+ }
+ # capture callback error here
+ proc ::bgerror args {
+ lappend ::RES "bgerror/OK $args"
+ set ::forever has-been-reached
+ return
+ }
+ # Files we use for our channels
+ set foo [makeFile ashgdfashdgfasdhgfasdhgf foo]
+ set bar [makeFile {} bar]
+ # Channels to copy between
+ set f [open $foo r] ; fconfigure $f -translation binary
+ set g [open $bar w] ; fconfigure $g -translation binary -buffering none
+} -constraints {stdio openpipe fcopy} -body {
+ # Record input size, so that result is always defined
+ lappend ::RES [file size $bar]
+ # Run the copy. Should not invoke -command now.
+ fcopy $f $g -size 2 -command ::cmd
+ # Check that -command was not called synchronously
+ set sbs [file size $bar]
+ lappend ::RES [expr {($sbs > 0) ? "sync/FAIL" : "sync/OK"}] $sbs
+ # Now let the async part happen. Should capture the error in cmd
+ # via bgerror. If not break the event loop via timer.
+ set token [after 1000 {
+ lappend ::RES {bgerror/FAIL timeout}
+ set ::forever has-been-reached
+ }]
+ vwait ::forever
+ catch {after cancel $token}
+ # Report
+ set ::RES
+} -cleanup {
+ close $f
+ close $g
+ catch {unset ::RES}
+ catch {unset ::forever}
+ rename ::cmd {}
+ rename ::bgerror {}
+ removeFile foo
+ removeFile bar
+} -result {0 sync/OK 0 {CMD 2} {bgerror/OK !STOP}}
+test io-53.8a {CopyData: async callback and error handling, Bug 1932639, at eof} -setup {
+ # copy progress callback. errors out intentionally
+ proc ::cmd args {
+ lappend ::RES "CMD $args"
+ set ::forever has-been-reached
+ return
+ }
+ # Files we use for our channels
+ set foo [makeFile ashgdfashdgfasdhgfasdhgf foo]
+ set bar [makeFile {} bar]
+ # Channels to copy between
+ set f [open $foo r] ; fconfigure $f -translation binary
+ set g [open $bar w] ; fconfigure $g -translation binary -buffering none
+} -constraints {stdio openpipe fcopy} -body {
+ # Initialize and force eof on the input.
+ seek $f 0 end ; read $f 1
+ set ::RES [eof $f]
+ # Run the copy. Should not invoke -command now.
+ fcopy $f $g -size 2 -command ::cmd
+ # Check that -command was not called synchronously
+ lappend ::RES [expr {([llength $::RES] > 1) ? "sync/FAIL" : "sync/OK"}]
+ # Now let the async part happen. Should capture the eof in cmd
+ # If not break the event loop via timer.
+ set token [after 1000 {
+ lappend ::RES {cmd/FAIL timeout}
+ set ::forever has-been-reached
+ }]
+ vwait ::forever
+ catch {after cancel $token}
+ # Report
+ set ::RES
+} -cleanup {
+ close $f
+ close $g
+ catch {unset ::RES}
+ catch {unset ::forever}
+ rename ::cmd {}
+ removeFile foo
+ removeFile bar
+} -result {1 sync/OK {CMD 0}}
+test io-53.8b {CopyData: async callback and -size 0} -setup {
+ # copy progress callback. errors out intentionally
+ proc ::cmd args {
+ lappend ::RES "CMD $args"
+ set ::forever has-been-reached
+ return
+ }
+ # Files we use for our channels
+ set foo [makeFile ashgdfashdgfasdhgfasdhgf foo]
+ set bar [makeFile {} bar]
+ # Channels to copy between
+ set f [open $foo r] ; fconfigure $f -translation binary
+ set g [open $bar w] ; fconfigure $g -translation binary -buffering none
+} -constraints {stdio openpipe fcopy} -body {
+ set ::RES {}
+ # Run the copy. Should not invoke -command now.
+ fcopy $f $g -size 0 -command ::cmd
+ # Check that -command was not called synchronously
+ lappend ::RES [expr {([llength $::RES] > 1) ? "sync/FAIL" : "sync/OK"}]
+ # Now let the async part happen. Should capture the eof in cmd
+ # If not break the event loop via timer.
+ set token [after 1000 {
+ lappend ::RES {cmd/FAIL timeout}
+ set ::forever has-been-reached
+ }]
+ vwait ::forever
+ catch {after cancel $token}
+ # Report
+ set ::RES
+} -cleanup {
+ close $f
+ close $g
+ catch {unset ::RES}
+ catch {unset ::forever}
+ rename ::cmd {}
+ removeFile foo
+ removeFile bar
+} -result {sync/OK {CMD 0}}
+test io-53.9 {CopyData: -size and event interaction, Bug 780533} -setup {
+ set out [makeFile {} out]
+ set err [makeFile {} err]
+ set pipe [open "|[list [info nameofexecutable] 2> $err]" r+]
+ fconfigure $pipe -translation binary -buffering line
+ puts $pipe {
+ fconfigure stdout -translation binary -buffering line
+ puts stderr Waiting...
+ after 1000
+ foreach x {a b c} {
+ puts stderr Looping...
+ puts $x
+ after 500
+ }
+ proc bye args {
+ if {[gets stdin line]<0} {
+ puts stderr "CHILD: EOF detected, exiting"
+ exit
+ } else {
+ puts stderr "CHILD: ignoring line: $line"
+ }
+ }
+ puts stderr Now-sleeping-forever
+ fileevent stdin readable bye
+ vwait forever
+ }
+ proc ::done args {
+ set ::forever OK
+ return
+ }
+ set ::forever {}
+ set out [open $out w]
+} -constraints {stdio openpipe fcopy} -body {
+ fcopy $pipe $out -size 6 -command ::done
+ set token [after 5000 {
+ set ::forever {fcopy hangs}
+ }]
+ vwait ::forever
+ catch {after cancel $token}
+ set ::forever
+} -cleanup {
+ close $pipe
+ rename ::done {}
+ after 1000; # Give Windows time to kill the process
+ catch {close $out}
+ catch {removeFile out}
+ catch {removeFile err}
+ catch {unset ::forever}
+} -result OK
+test io-53.10 {Bug 1350564, multi-directional fcopy} -setup {
+ set err [makeFile {} err]
+ set pipe [open "|[list [info nameofexecutable] 2> $err]" r+]
+ fconfigure $pipe -translation binary -buffering line
+ puts $pipe {
+ fconfigure stderr -buffering line
+ # Kill server when pipe closed by invoker.
+ proc bye args {
+ if {![eof stdin]} { gets stdin ; return }
+ puts stderr BYE
+ exit
+ }
+ # Server code. Bi-directional copy between 2 sockets.
+ proc geof {sok} {
+ puts stderr DONE/$sok
+ close $sok
+ }
+ proc new {sok args} {
+ puts stderr NEW/$sok
+ global l srv
+ fconfigure $sok -translation binary -buffering none
+ lappend l $sok
+ if {[llength $l]==2} {
+ close $srv
+ foreach {a b} $l break
+ fcopy $a $b -command [list geof $a]
+ fcopy $b $a -command [list geof $b]
+ puts stderr 2COPY
+ }
+ puts stderr ...
+ }
+ puts stderr SRV
+ set l {}
+ set srv [socket -server new 9999]
+ puts stderr WAITING
+ fileevent stdin readable bye
+ puts OK
+ vwait forever
+ }
+ # wait for OK from server.
+ gets $pipe
+ # Now the two clients.
+ proc ::done {sock} {
+ if {[eof $sock]} { close $sock ; return }
+ lappend ::forever [gets $sock]
+ return
+ }
+ set a [socket 127.0.0.1 9999]
+ set b [socket 127.0.0.1 9999]
+ fconfigure $a -translation binary -buffering none
+ fconfigure $b -translation binary -buffering none
+ fileevent $a readable [list ::done $a]
+ fileevent $b readable [list ::done $b]
+} -constraints {stdio openpipe fcopy} -body {
+ # Now pass data through the server in both directions.
+ set ::forever {}
+ puts $a AB
+ vwait ::forever
+ puts $b BA
+ vwait ::forever
+ set ::forever
+} -cleanup {
+ catch {close $a}
+ catch {close $b}
+ close $pipe
+ rename ::done {}
+ after 1000 ;# Give Windows time to kill the process
+ removeFile err
+ catch {unset ::forever}
+} -result {AB BA}
+test io-53.11 {Bug 2895565} -setup {
+ set in [makeFile {} in]
+ set f [open $in w]
+ fconfigure $f -encoding utf-8 -translation binary
+ puts -nonewline $f [string repeat "Ho hum\n" 11]
+ close $f
+ set inChan [open $in r]
+ fconfigure $inChan -translation binary
+ set out [makeFile {} out]
+ set outChan [open $out w]
+ fconfigure $outChan -encoding cp1252 -translation crlf
+ proc CopyDone {bytes args} {
+ variable done
+ if {[llength $args]} {
+ set done "Error: '[lindex $args 0]' after $bytes bytes copied"
+ } else {
+ set done "$bytes bytes copied"
+ }
+ }
+} -body {
+ variable done
+ after 2000 [list set [namespace which -variable done] timeout]
+ fcopy $inChan $outChan -size 40 -command [namespace which CopyDone]
+ vwait [namespace which -variable done]
+ set done
+} -cleanup {
+ close $outChan
+ close $inChan
+ removeFile out
+ removeFile in
+} -result {40 bytes copied}
+
+test io-54.1 {Recursive channel events} {socket fileevent} {
+ # This test checks to see if file events are delivered during recursive
+ # event loops when there is buffered data on the channel.
+
+ proc accept {s a p} {
+ variable as
+ fconfigure $s -translation lf
+ puts $s "line 1\nline2\nline3"
+ flush $s
+ set as $s
+ }
+ proc readit {s next} {
+ variable x
+ variable result
+ lappend result $next
+ if {$next == 1} {
+ fileevent $s readable [namespace code [list readit $s 2]]
+ vwait [namespace which -variable x]
+ }
+ incr x
+ }
+ set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+
+ # We need to delay on some systems until the creation of the
+ # server socket completes.
+
+ set done 0
+ for {set i 0} {$i < 10} {incr i} {
+ if {![catch {set cs [socket 127.0.0.1 [lindex [fconfigure $ss -sockname] 2]]}]} {
+ set done 1
+ break
+ }
+ after 100
+ }
+ if {$done == 0} {
+ close $ss
+ error "failed to connect to server"
+ }
+ variable result {}
+ variable x 0
+ variable as
+ vwait [namespace which -variable as]
+ fconfigure $cs -translation lf
+ lappend result [gets $cs]
+ fconfigure $cs -blocking off
+ fileevent $cs readable [namespace code [list readit $cs 1]]
+ set a [after 2000 [namespace code { set x failure }]]
+ vwait [namespace which -variable x]
+ after cancel $a
+ close $as
+ close $ss
+ close $cs
+ list $result $x
+} {{{line 1} 1 2} 2}
+test io-54.2 {Testing for busy-wait in recursive channel events} {socket fileevent} {
+ set accept {}
+ set after {}
+ variable s [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ proc accept {s a p} {
+ variable counter
+ variable accept
+
+ set accept $s
+ set counter 0
+ fconfigure $s -blocking off -buffering line -translation lf
+ fileevent $s readable [namespace code "doit $s"]
+ }
+ proc doit {s} {
+ variable counter
+ variable after
+
+ incr counter
+ set l [gets $s]
+ if {"$l" == ""} {
+ fileevent $s readable [namespace code "doit1 $s"]
+ set after [after 1000 [namespace code newline]]
+ }
+ }
+ proc doit1 {s} {
+ variable counter
+ variable accept
+
+ incr counter
+ set l [gets $s]
+ close $s
+ set accept {}
+ }
+ proc producer {} {
+ variable s
+ variable writer
+
+ set writer [socket 127.0.0.1 [lindex [fconfigure $s -sockname] 2]]
+ fconfigure $writer -buffering line
+ puts -nonewline $writer hello
+ flush $writer
+ }
+ proc newline {} {
+ variable done
+ variable writer
+
+ puts $writer hello
+ flush $writer
+ set done 1
+ }
+ producer
+ variable done
+ vwait [namespace which -variable done]
+ close $writer
+ close $s
+ after cancel $after
+ if {$accept != {}} {close $accept}
+ set counter
+} 1
+
+set path(fooBar) [makeFile {} fooBar]
+
+test io-55.1 {ChannelEventScriptInvoker: deletion} -constraints {
+ fileevent
+} -setup {
+ variable x
+ proc eventScript {fd} {
+ variable x
+ close $fd
+ error "planned error"
+ set x whoops
+ }
+ proc myHandler args {
+ variable x got_error
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+} -body {
+ set f [open $path(fooBar) w]
+ fileevent $f writable [namespace code [list eventScript $f]]
+ variable x not_done
+ vwait [namespace which -variable x]
+ set x
+} -cleanup {
+ interp bgerror {} $handler
+} -result {got_error}
+
+test io-56.1 {ChannelTimerProc} {testchannelevent} {
+ set f [open $path(fooBar) w]
+ puts $f "this is a test"
+ close $f
+ set f [open $path(fooBar) r]
+ testchannelevent $f add readable [namespace code {
+ read $f 1
+ incr x
+ }]
+ variable x 0
+ vwait [namespace which -variable x]
+ vwait [namespace which -variable x]
+ set result $x
+ testchannelevent $f set 0 none
+ after idle [namespace code {set y done}]
+ variable y
+ vwait [namespace which -variable y]
+ close $f
+ lappend result $y
+} {2 done}
+
+test io-57.1 {buffered data and file events, gets} {fileevent} {
+ proc accept {sock args} {
+ variable s2
+ set s2 $sock
+ }
+ set server [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set s [socket 127.0.0.1 [lindex [fconfigure $server -sockname] 2]]
+ variable s2
+ vwait [namespace which -variable s2]
+ update
+ fileevent $s2 readable [namespace code {lappend result readable}]
+ puts $s "12\n34567890"
+ flush $s
+ variable result [gets $s2]
+ after 1000 [namespace code {lappend result timer}]
+ vwait [namespace which -variable result]
+ lappend result [gets $s2]
+ vwait [namespace which -variable result]
+ close $s
+ close $s2
+ close $server
+ set result
+} {12 readable 34567890 timer}
+test io-57.2 {buffered data and file events, read} {fileevent} {
+ proc accept {sock args} {
+ variable s2
+ set s2 $sock
+ }
+ set server [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+ set s [socket 127.0.0.1 [lindex [fconfigure $server -sockname] 2]]
+ variable s2
+ vwait [namespace which -variable s2]
+ update
+ fileevent $s2 readable [namespace code {lappend result readable}]
+ puts -nonewline $s "1234567890"
+ flush $s
+ variable result [read $s2 1]
+ after 1000 [namespace code {lappend result timer}]
+ vwait [namespace which -variable result]
+ lappend result [read $s2 9]
+ vwait [namespace which -variable result]
+ close $s
+ close $s2
+ close $server
+ set result
+} {1 readable 234567890 timer}
+
+test io-58.1 {Tcl_NotifyChannel and error when closing} {stdio unixOrPc openpipe fileevent} {
+ set out [open $path(script) w]
+ puts $out {
+ puts "normal message from pipe"
+ puts stderr "error message from pipe"
+ exit 1
+ }
+ proc readit {pipe} {
+ variable x
+ variable result
+ if {[eof $pipe]} {
+ set x [catch {close $pipe} line]
+ lappend result catch $line
+ } else {
+ gets $pipe line
+ lappend result gets $line
+ }
+ }
+ close $out
+ set pipe [open "|[list [interpreter] $path(script)]" r]
+ fileevent $pipe readable [namespace code [list readit $pipe]]
+ variable x ""
+ set result ""
+ vwait [namespace which -variable x]
+ list $x $result
+} {1 {gets {normal message from pipe} gets {} catch {error message from pipe}}}
+
+test io-59.1 {Thread reference of channels} {testmainthread testchannel} {
+ # TIP #10
+ # More complicated tests (like that the reference changes as a
+ # channel is moved from thread to thread) can be done only in the
+ # extension which fully implements the moving of channels between
+ # threads, i.e. 'Threads'.
+
+ set f [open $path(longfile) r]
+ set result [testchannel mthread $f]
+ close $f
+ string equal $result [testmainthread]
+} {1}
+
+test io-60.1 {writing illegal utf sequences} {openpipe fileevent} {
+ # This test will hang in older revisions of the core.
+
+ set out [open $path(script) w]
+ puts $out {
+ puts [encoding convertfrom identity \xe2]
+ exit 1
+ }
+ proc readit {pipe} {
+ variable x
+ variable result
+ if {[eof $pipe]} {
+ set x [catch {close $pipe} line]
+ lappend result catch $line
+ } else {
+ gets $pipe line
+ lappend result gets $line
+ }
+ }
+ close $out
+ set pipe [open "|[list [interpreter] $path(script)]" r]
+ fileevent $pipe readable [namespace code [list readit $pipe]]
+ variable x ""
+ set result ""
+ vwait [namespace which -variable x]
+
+ # cut of the remainder of the error stack, especially the filename
+ set result [lreplace $result 3 3 [lindex [split [lindex $result 3] \n] 0]]
+ list $x $result
+} {1 {gets {} catch {error writing "stdout": invalid argument}}}
+
+test io-61.1 {Reset eof state after changing the eof char} -setup {
+ set datafile [makeFile {} eofchar]
+ set f [open $datafile w]
+ fconfigure $f -translation binary
+ puts -nonewline $f [string repeat "Ho hum\n" 11]
+ puts $f =
+ set line [string repeat "Ge gla " 4]
+ puts -nonewline $f [string repeat [string trimright $line]\n 834]
+ close $f
+} -body {
+ set f [open $datafile r]
+ fconfigure $f -eofchar =
+ set res {}
+ lappend res [read $f; tell $f]
+ fconfigure $f -eofchar {}
+ lappend res [read $f 1]
+ lappend res [read $f; tell $f]
+ # Any seek zaps the internals into a good state.
+ #seek $f 0 start
+ #seek $f 0 current
+ #lappend res [read $f; tell $f]
+ close $f
+ set res
+} -cleanup {
+ removeFile eofchar
+} -result {77 = 23431}
+
+
+# Test the cutting and splicing of channels, this is incidentially the
+# attach/detach facility of package Thread, but __without any
+# safeguards__. It can also be used to emulate transfer of channels
+# between threads, and is used for that here.
+
+test io-70.0 {Cutting & Splicing channels} {testchannel} {
+ set f [makeFile {... dummy ...} cutsplice]
+ set c [open $f r]
+
+ set res {}
+ lappend res [catch {seek $c 0 start}]
+ testchannel cut $c
+
+ lappend res [catch {seek $c 0 start}]
+ testchannel splice $c
+
+ lappend res [catch {seek $c 0 start}]
+ close $c
+
+ removeFile cutsplice
+
+ set res
+} {0 1 0}
+
+
+test io-70.1 {Transfer channel} {testchannel thread} {
+ set f [makeFile {... dummy ...} cutsplice]
+ set c [open $f r]
+
+ set res {}
+ lappend res [catch {seek $c 0 start}]
+ testchannel cut $c
+ lappend res [catch {seek $c 0 start}]
+
+ set tid [thread::create -preserved]
+ thread::send $tid [list set c $c]
+ thread::send $tid {load {} Tcltest}
+ lappend res [thread::send $tid {
+ testchannel splice $c
+ set res [catch {seek $c 0 start}]
+ close $c
+ set res
+ }]
+
+ thread::release $tid
+ removeFile cutsplice
+
+ set res
+} {0 1 0}
+
+# ### ### ### ######### ######### #########
+
+foreach {n msg expected} {
+ 0 {} {}
+ 1 {{message only}} {{message only}}
+ 2 {-options x} {-options x}
+ 3 {-options {x y} {the message}} {-options {x y} {the message}}
+
+ 4 {-code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 5 {-code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 6 {-code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 7 {-code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 8 {-code error -level 0 -f ba snarf} {-code error -level 0 -f ba snarf}
+ 9 {-code ok -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 10 {-code error -level 5 -f ba snarf} {-code error -level 0 -f ba snarf}
+ 11 {-code ok -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 12 {-code boss -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 13 {-code boss -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 14 {-code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 15 {-code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 16 {-code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 17 {-code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 18 {-code error -level 0 -f ba} {-code error -level 0 -f ba}
+ 19 {-code ok -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 20 {-code error -level 5 -f ba} {-code error -level 0 -f ba}
+ 21 {-code ok -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 22 {-code boss -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 23 {-code boss -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 24 {-code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 25 {-code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 26 {-code error -level X -f ba snarf} {-code error -level 0 -f ba snarf}
+ 27 {-code ok -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 28 {-code boss -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 29 {-code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+ 30 {-code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ 31 {-code error -level X -f ba} {-code error -level 0 -f ba}
+ 32 {-code ok -level X -f ba} {-code 1 -level 0 -f ba}
+ 33 {-code boss -level X -f ba} {-code 1 -level 0 -f ba}
+
+ 34 {-code 1 -code 1 -level 0 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 35 {-code 1 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 36 {-code 1 -code 1 -level 5 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 37 {-code 1 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 38 {-code 1 -code error -level 0 -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+ 39 {-code 1 -code ok -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 40 {-code 1 -code error -level 5 -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+ 41 {-code 1 -code ok -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 42 {-code 1 -code boss -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 43 {-code 1 -code boss -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 44 {-code 1 -code 1 -level 0 -f ba} {-code 1 -code 1 -level 0 -f ba}
+ 45 {-code 1 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 46 {-code 1 -code 1 -level 5 -f ba} {-code 1 -code 1 -level 0 -f ba}
+ 47 {-code 1 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 48 {-code 1 -code error -level 0 -f ba} {-code 1 -code error -level 0 -f ba}
+ 49 {-code 1 -code ok -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 50 {-code 1 -code error -level 5 -f ba} {-code 1 -code error -level 0 -f ba}
+ 51 {-code 1 -code ok -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 52 {-code 1 -code boss -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 53 {-code 1 -code boss -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 54 {-code 1 -code 1 -level X -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 55 {-code 1 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 56 {-code 1 -code error -level X -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+ 57 {-code 1 -code ok -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 58 {-code 1 -code boss -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 59 {-code 1 -code 1 -level X -f ba} {-code 1 -code 1 -level 0 -f ba}
+ 60 {-code 1 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ 61 {-code 1 -code error -level X -f ba} {-code 1 -code error -level 0 -f ba}
+ 62 {-code 1 -code ok -level X -f ba} {-code 1 -level 0 -f ba}
+ 63 {-code 1 -code boss -level X -f ba} {-code 1 -level 0 -f ba}
+
+ 64 {-code 0 -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 65 {-code 0 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 66 {-code 0 -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 67 {-code 0 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 68 {-code 0 -code error -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 69 {-code 0 -code ok -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 70 {-code 0 -code error -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 71 {-code 0 -code ok -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 72 {-code 0 -code boss -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 73 {-code 0 -code boss -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 74 {-code 0 -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 75 {-code 0 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 76 {-code 0 -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 77 {-code 0 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 78 {-code 0 -code error -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 79 {-code 0 -code ok -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 80 {-code 0 -code error -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 81 {-code 0 -code ok -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 82 {-code 0 -code boss -level 0 -f ba} {-code 1 -level 0 -f ba}
+ 83 {-code 0 -code boss -level 5 -f ba} {-code 1 -level 0 -f ba}
+ 84 {-code 0 -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 85 {-code 0 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 86 {-code 0 -code error -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 87 {-code 0 -code ok -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 88 {-code 0 -code boss -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 89 {-code 0 -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+ 90 {-code 0 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ 91 {-code 0 -code error -level X -f ba} {-code 1 -level 0 -f ba}
+ 92 {-code 0 -code ok -level X -f ba} {-code 1 -level 0 -f ba}
+ 93 {-code 0 -code boss -level X -f ba} {-code 1 -level 0 -f ba}
+
+ 94 {-code 1 -code 1 -level 0 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 95 {-code 0 -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 96 {-code 1 -code 1 -level 5 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ 97 {-code 0 -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ 98 {-code error -code 1 -level 0 -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+ 99 {-code ok -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ a0 {-code error -code 1 -level 5 -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+ a1 {-code ok -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ a2 {-code boss -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ a3 {-code boss -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ a4 {-code 1 -code 1 -level 0 -f ba} {-code 1 -code 1 -level 0 -f ba}
+ a5 {-code 0 -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ a6 {-code 1 -code 1 -level 5 -f ba} {-code 1 -code 1 -level 0 -f ba}
+ a7 {-code 0 -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ a8 {-code error -code 1 -level 0 -f ba} {-code error -code 1 -level 0 -f ba}
+ a9 {-code ok -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ b0 {-code error -code 1 -level 5 -f ba} {-code error -code 1 -level 0 -f ba}
+ b1 {-code ok -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ b2 {-code boss -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ b3 {-code boss -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ b4 {-code 1 -code 1 -level X -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
+ b5 {-code 0 -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ b6 {-code error -code 1 -level X -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+ b7 {-code ok -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ b8 {-code boss -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ b9 {-code 1 -code 1 -level X -f ba} {-code 1 -code 1 -level 0 -f ba}
+ c0 {-code 0 -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+ c1 {-code error -code 1 -level X -f ba} {-code error -code 1 -level 0 -f ba}
+ c2 {-code ok -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+ c3 {-code boss -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
+
+ c4 {-code 1 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c5 {-code 0 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c6 {-code 1 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c7 {-code 0 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c8 {-code error -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ c9 {-code ok -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d0 {-code error -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d1 {-code ok -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d2 {-code boss -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d3 {-code boss -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ d4 {-code 1 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ d5 {-code 0 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ d6 {-code 1 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ d7 {-code 0 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ d8 {-code error -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ d9 {-code ok -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ e0 {-code error -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ e1 {-code ok -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ e2 {-code boss -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
+ e3 {-code boss -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
+ e4 {-code 1 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e5 {-code 0 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e6 {-code error -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e7 {-code ok -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e8 {-code boss -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+ e9 {-code 1 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ f0 {-code 0 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ f1 {-code error -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ f2 {-code ok -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+ f3 {-code boss -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
+} {
+ test io-71.$n {Tcl_SetChannelError} {testchannel} {
+
+ set f [makeFile {... dummy ...} cutsplice]
+ set c [open $f r]
+
+ set res [testchannel setchannelerror $c [lrange $msg 0 end]]
+ close $c
+ removeFile cutsplice
+
+ set res
+ } [lrange $expected 0 end]
+
+ test io-72.$n {Tcl_SetChannelErrorInterp} {testchannel} {
+
+ set f [makeFile {... dummy ...} cutsplice]
+ set c [open $f r]
+
+ set res [testchannel setchannelerrorinterp $c [lrange $msg 0 end]]
+ close $c
+ removeFile cutsplice
+
+ set res
+ } [lrange $expected 0 end]
+}
+
+test io-73.1 {channel Tcl_Obj SetChannelFromAny} {} {
+ # Test for Bug 1847044 - don't spoil type unless we have a valid channel
+ catch {close [lreplace [list a] 0 end]}
+} {1}
+
+test io-73.2 {channel Tcl_Obj SetChannelFromAny, bug 2407783} -setup {
+ # Invalidate intrep of 'channel' Tcl_Obj when transiting between interpreters.
+ set f [open [info script] r]
+} -body {
+ interp create foo
+ seek $f 0
+ set code [catch {interp eval foo [list seek $f 0]} msg]
+ # The string map converts the changing channel handle to a fixed string
+ list $code [string map [list $f @@] $msg]
+} -cleanup {
+ close $f
+} -result {1 {can not find channel named "@@"}}
+
+# ### ### ### ######### ######### #########
+
+# cleanup
+foreach file [list fooBar longfile script script2 output test1 pipe my_script \
+ test2 test3 cat stdout kyrillic.txt utf8-fcopy.txt utf8-rp.txt] {
+ removeFile $file
+}
+cleanupTests
+}
+namespace delete ::tcl::test::io
+return
diff --git a/pkgs/msgcat/tests/ioCmd.test b/pkgs/msgcat/tests/ioCmd.test
new file mode 100644
index 0000000..cf913ff
--- /dev/null
+++ b/pkgs/msgcat/tests/ioCmd.test
@@ -0,0 +1,3741 @@
+# -*- tcl -*-
+# Commands covered: open, close, gets, read, puts, seek, tell, eof, flush,
+# fblocked, fconfigure, open, channel, fcopy
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Custom constraints used in this file
+testConstraint fcopy [llength [info commands fcopy]]
+testConstraint testchannel [llength [info commands testchannel]]
+testConstraint thread [expr {0 == [catch {package require Thread 2.6}]}]
+
+#----------------------------------------------------------------------
+
+test iocmd-1.1 {puts command} {
+ list [catch {puts} msg] $msg
+} {1 {wrong # args: should be "puts ?-nonewline? ?channelId? string"}}
+test iocmd-1.2 {puts command} {
+ list [catch {puts a b c d e f g} msg] $msg
+} {1 {wrong # args: should be "puts ?-nonewline? ?channelId? string"}}
+test iocmd-1.3 {puts command} {
+ list [catch {puts froboz -nonewline kablooie} msg] $msg
+} {1 {wrong # args: should be "puts ?-nonewline? ?channelId? string"}}
+test iocmd-1.4 {puts command} {
+ list [catch {puts froboz hello} msg] $msg
+} {1 {can not find channel named "froboz"}}
+test iocmd-1.5 {puts command} {
+ list [catch {puts stdin hello} msg] $msg
+} {1 {channel "stdin" wasn't opened for writing}}
+
+set path(test1) [makeFile {} test1]
+
+test iocmd-1.6 {puts command} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ puts -nonewline $f foobar
+ close $f
+ file size $path(test1)
+} 6
+test iocmd-1.7 {puts command} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f foobar
+ close $f
+ file size $path(test1)
+} 7
+test iocmd-1.8 {puts command} {
+ set f [open $path(test1) w]
+ fconfigure $f -translation lf -eofchar {} -encoding iso8859-1
+ puts -nonewline $f [binary format a4a5 foo bar]
+ close $f
+ file size $path(test1)
+} 9
+
+test iocmd-2.1 {flush command} {
+ list [catch {flush} msg] $msg
+} {1 {wrong # args: should be "flush channelId"}}
+test iocmd-2.2 {flush command} {
+ list [catch {flush a b c d e} msg] $msg
+} {1 {wrong # args: should be "flush channelId"}}
+test iocmd-2.3 {flush command} {
+ list [catch {flush foo} msg] $msg
+} {1 {can not find channel named "foo"}}
+test iocmd-2.4 {flush command} {
+ list [catch {flush stdin} msg] $msg
+} {1 {channel "stdin" wasn't opened for writing}}
+
+test iocmd-3.1 {gets command} {
+ list [catch {gets} msg] $msg
+} {1 {wrong # args: should be "gets channelId ?varName?"}}
+test iocmd-3.2 {gets command} {
+ list [catch {gets a b c d e f g} msg] $msg
+} {1 {wrong # args: should be "gets channelId ?varName?"}}
+test iocmd-3.3 {gets command} {
+ list [catch {gets aaa} msg] $msg
+} {1 {can not find channel named "aaa"}}
+test iocmd-3.4 {gets command} {
+ list [catch {gets stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test iocmd-3.5 {gets command} {
+ set f [open $path(test1) w]
+ puts $f [binary format a4a5 foo bar]
+ close $f
+ set f [open $path(test1) r]
+ set result [gets $f]
+ close $f
+ set x foo\x00
+ set x "${x}bar\x00\x00"
+ string compare $x $result
+} 0
+
+test iocmd-4.1 {read command} {
+ list [catch {read} msg] $msg
+} {1 {wrong # args: should be "read channelId ?numChars?" or "read ?-nonewline? channelId"}}
+test iocmd-4.2 {read command} {
+ list [catch {read a b c d e f g h} msg] $msg
+} {1 {wrong # args: should be "read channelId ?numChars?" or "read ?-nonewline? channelId"}}
+test iocmd-4.3 {read command} {
+ list [catch {read aaa} msg] $msg
+} {1 {can not find channel named "aaa"}}
+test iocmd-4.4 {read command} {
+ list [catch {read -nonewline} msg] $msg
+} {1 {wrong # args: should be "read channelId ?numChars?" or "read ?-nonewline? channelId"}}
+test iocmd-4.5 {read command} {
+ list [catch {read -nonew file4} msg] $msg $::errorCode
+} {1 {can not find channel named "-nonew"} {TCL LOOKUP CHANNEL -nonew}}
+test iocmd-4.6 {read command} {
+ list [catch {read stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test iocmd-4.7 {read command} {
+ list [catch {read -nonewline stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test iocmd-4.8 {read command with incorrect combination of arguments} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f "Two lines: this one"
+ puts $f "and this one"
+ close $f
+ set f [open $path(test1)]
+ set x [list [catch {read -nonewline $f 20 z} msg] $msg $::errorCode]
+ close $f
+ set x
+} {1 {wrong # args: should be "read channelId ?numChars?" or "read ?-nonewline? channelId"} {TCL WRONGARGS}}
+test iocmd-4.9 {read command} {
+ list [catch {read stdin foo} msg] $msg $::errorCode
+} {1 {expected non-negative integer but got "foo"} {TCL VALUE NUMBER}}
+test iocmd-4.10 {read command} {
+ list [catch {read file107} msg] $msg $::errorCode
+} {1 {can not find channel named "file107"} {TCL LOOKUP CHANNEL file107}}
+set path(test3) [makeFile {} test3]
+test iocmd-4.11 {read command} {
+ set f [open $path(test3) w]
+ set x [list [catch {read $f} msg] $msg $::errorCode]
+ close $f
+ string compare [string tolower $x] \
+ [list 1 [format "channel \"%s\" wasn't opened for reading" $f] none]
+} 0
+test iocmd-4.12 {read command} -setup {
+ set f [open $path(test1)]
+} -body {
+ list [catch {read $f 12z} msg] $msg $::errorCode
+} -cleanup {
+ close $f
+} -result {1 {expected non-negative integer but got "12z"} {TCL VALUE NUMBER}}
+
+test iocmd-5.1 {seek command} -returnCodes error -body {
+ seek
+} -result {wrong # args: should be "seek channelId offset ?origin?"}
+test iocmd-5.2 {seek command} -returnCodes error -body {
+ seek a b c d e f g
+} -result {wrong # args: should be "seek channelId offset ?origin?"}
+test iocmd-5.3 {seek command} -returnCodes error -body {
+ seek stdin gugu
+} -result {expected integer but got "gugu"}
+test iocmd-5.4 {seek command} -returnCodes error -body {
+ seek stdin 100 gugu
+} -result {bad origin "gugu": must be start, current, or end}
+
+test iocmd-6.1 {tell command} {
+ list [catch {tell} msg] $msg
+} {1 {wrong # args: should be "tell channelId"}}
+test iocmd-6.2 {tell command} {
+ list [catch {tell a b c d e} msg] $msg
+} {1 {wrong # args: should be "tell channelId"}}
+test iocmd-6.3 {tell command} {
+ list [catch {tell aaa} msg] $msg
+} {1 {can not find channel named "aaa"}}
+
+test iocmd-7.1 {close command} {
+ list [catch {close} msg] $msg
+} {1 {wrong # args: should be "close channelId ?direction?"}}
+test iocmd-7.2 {close command} {
+ list [catch {close a b c d e} msg] $msg
+} {1 {wrong # args: should be "close channelId ?direction?"}}
+test iocmd-7.3 {close command} {
+ list [catch {close aaa} msg] $msg
+} {1 {can not find channel named "aaa"}}
+test iocmd-7.4 {close command} -setup {
+ set chan [open [info script] r]
+} -body {
+ chan close $chan bar
+} -cleanup {
+ close $chan
+} -returnCodes error -result "bad direction \"bar\": must be read or write"
+test iocmd-7.5 {close command} -setup {
+ set chan [open [info script] r]
+} -body {
+ chan close $chan write
+} -cleanup {
+ close $chan
+} -returnCodes error -result "Half-close of write-side not possible, side not opened or already closed"
+
+test iocmd-8.1 {fconfigure command} {
+ list [catch {fconfigure} msg] $msg
+} {1 {wrong # args: should be "fconfigure channelId ?-option value ...?"}}
+test iocmd-8.2 {fconfigure command} {
+ list [catch {fconfigure a b c d e f} msg] $msg
+} {1 {wrong # args: should be "fconfigure channelId ?-option value ...?"}}
+test iocmd-8.3 {fconfigure command} {
+ list [catch {fconfigure a b} msg] $msg
+} {1 {can not find channel named "a"}}
+test iocmd-8.4 {fconfigure command} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ set x [list [catch {fconfigure $f1 froboz} msg] $msg]
+ close $f1
+ set x
+} {1 {bad option "froboz": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, or -translation}}
+test iocmd-8.5 {fconfigure command} {
+ list [catch {fconfigure stdin -buffering froboz} msg] $msg
+} {1 {bad value for -buffering: must be one of full, line, or none}}
+test iocmd-8.6 {fconfigure command} {
+ list [catch {fconfigure stdin -translation froboz} msg] $msg
+} {1 {bad value for -translation: must be one of auto, binary, cr, lf, crlf, or platform}}
+test iocmd-8.7 {fconfigure command} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -eofchar {} -encoding unicode
+ set x [fconfigure $f1]
+ close $f1
+ set x
+} {-blocking 1 -buffering full -buffersize 4096 -encoding unicode -eofchar {} -translation lf}
+test iocmd-8.8 {fconfigure command} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation lf -buffering line -buffersize 3030 \
+ -eofchar {} -encoding unicode
+ set x ""
+ lappend x [fconfigure $f1 -buffering]
+ lappend x [fconfigure $f1]
+ close $f1
+ set x
+} {line {-blocking 1 -buffering line -buffersize 3030 -encoding unicode -eofchar {} -translation lf}}
+test iocmd-8.9 {fconfigure command} {
+ file delete $path(test1)
+ set f1 [open $path(test1) w]
+ fconfigure $f1 -translation binary -buffering none -buffersize 4040 \
+ -eofchar {} -encoding binary
+ set x [fconfigure $f1]
+ close $f1
+ set x
+} {-blocking 1 -buffering none -buffersize 4040 -encoding binary -eofchar {} -translation lf}
+test iocmd-8.10 {fconfigure command} {
+ list [catch {fconfigure a b} msg] $msg
+} {1 {can not find channel named "a"}}
+set path(fconfigure.dummy) [makeFile {} fconfigure.dummy]
+test iocmd-8.11 {fconfigure command} {
+ set chan [open $path(fconfigure.dummy) r]
+ set res [list [catch {fconfigure $chan -froboz blarfo} msg] $msg]
+ close $chan
+ set res
+} {1 {bad option "-froboz": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, or -translation}}
+test iocmd-8.12 {fconfigure command} {
+ set chan [open $path(fconfigure.dummy) r]
+ set res [list [catch {fconfigure $chan -b blarfo} msg] $msg]
+ close $chan
+ set res
+} {1 {bad option "-b": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, or -translation}}
+test iocmd-8.13 {fconfigure command} {
+ set chan [open $path(fconfigure.dummy) r]
+ set res [list [catch {fconfigure $chan -buffer blarfo} msg] $msg]
+ close $chan
+ set res
+} {1 {bad option "-buffer": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, or -translation}}
+removeFile fconfigure.dummy
+test iocmd-8.14 {fconfigure command} {
+ fconfigure stdin -buffers
+} 4096
+test iocmd-8.15.1 {fconfigure command / tcp channel} -constraints {socket unixOrPc} -setup {
+ set srv [socket -server iocmdSRV -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $srv -sockname] 2]
+ proc iocmdSRV {sock ip port} {close $sock}
+ set cli [socket 127.0.0.1 $port]
+} -body {
+ fconfigure $cli -blah
+} -cleanup {
+ close $cli
+ close $srv
+ unset cli srv port
+ rename iocmdSRV {}
+} -returnCodes error -result {bad option "-blah": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -translation, -peername, or -sockname}
+test iocmd-8.16 {fconfigure command / tcp channel} -constraints socket -setup {
+ set srv [socket -server iocmdSRV -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $srv -sockname] 2]
+ proc iocmdSRV {sock ip port} {close $sock}
+ set cli [socket 127.0.0.1 $port]
+} -body {
+ expr {[lindex [fconfigure $cli -peername] 2] == $port}
+} -cleanup {
+ close $cli
+ close $srv
+ unset cli srv port
+ rename iocmdSRV {}
+} -result 1
+test iocmd-8.17 {fconfigure command / tcp channel} -constraints nonPortable -setup {
+ set srv [socket -server iocmdSRV -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $srv -sockname] 2]
+ proc iocmdSRV {sock ip port} {close $sock}
+ set cli [socket 127.0.0.1 $port]
+} -body {
+ # It is possible that you don't get the connection reset by peer
+ # error but rather a valid answer. Depends on the tcp implementation
+ update
+ puts $cli "blah"
+ flush $cli; # that flush could/should fail too
+ update
+ regsub -all {can([^:])+: } [catch {fconfigure $cli -peername} msg] {}
+} -cleanup {
+ close $cli
+ close $srv
+ unset cli srv port
+ rename iocmdSRV {}
+} -result 1
+test iocmd-8.18 {fconfigure command / unix tty channel} -constraints {nonPortable unix} -setup {
+ set tty ""
+} -body {
+ # might fail if /dev/ttya is unavailable
+ set tty [open /dev/ttya]
+ fconfigure $tty -blah blih
+} -cleanup {
+ if {$tty ne ""} {
+ close $tty
+ }
+} -returnCodes error -result {bad option "-blah": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -translation, or -mode}
+test iocmd-8.19 {fconfigure command / win tty channel} -constraints {nonPortable win} -setup {
+ set tty ""
+} -body {
+ # might fail early if com1 is unavailable
+ set tty [open com1]
+ fconfigure $tty -blah blih
+} -cleanup {
+ if {$tty ne ""} {
+ close $tty
+ }
+} -returnCodes error -result {bad option "-blah": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -translation, -mode, -handshake, -pollinterval, -sysbuffer, -timeout, -ttycontrol, or -xchar}
+# TODO: Test parsing of serial channel options (nonportable, since requires an
+# open channel to work with).
+
+test iocmd-9.1 {eof command} {
+ list [catch {eof} msg] $msg $::errorCode
+} {1 {wrong # args: should be "eof channelId"} {TCL WRONGARGS}}
+test iocmd-9.2 {eof command} {
+ list [catch {eof a b} msg] $msg $::errorCode
+} {1 {wrong # args: should be "eof channelId"} {TCL WRONGARGS}}
+test iocmd-9.3 {eof command} {
+ catch {close file100}
+ list [catch {eof file100} msg] $msg $::errorCode
+} {1 {can not find channel named "file100"} {TCL LOOKUP CHANNEL file100}}
+
+# The tests for Tcl_ExecObjCmd are in exec.test
+
+test iocmd-10.1 {fblocked command} {
+ list [catch {fblocked} msg] $msg
+} {1 {wrong # args: should be "fblocked channelId"}}
+test iocmd-10.2 {fblocked command} {
+ list [catch {fblocked a b c d e f g} msg] $msg
+} {1 {wrong # args: should be "fblocked channelId"}}
+test iocmd-10.3 {fblocked command} {
+ list [catch {fblocked file1000} msg] $msg
+} {1 {can not find channel named "file1000"}}
+test iocmd-10.4 {fblocked command} {
+ list [catch {fblocked stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test iocmd-10.5 {fblocked command} {
+ fblocked stdin
+} 0
+
+set path(test4) [makeFile {} test4]
+set path(test5) [makeFile {} test5]
+
+file delete $path(test5)
+test iocmd-11.1 {I/O to command pipelines} {unixOrPc unixExecs} {
+ set f [open $path(test4) w]
+ close $f
+ list [catch {open "| cat < \"$path(test4)\" > \"$path(test5)\"" w} msg] $msg $::errorCode
+} {1 {can't write input to command: standard input was redirected} {TCL OPERATION EXEC BADREDIRECT}}
+test iocmd-11.2 {I/O to command pipelines} {unixOrPc unixExecs} {
+ list [catch {open "| echo > \"$path(test5)\"" r} msg] $msg $::errorCode
+} {1 {can't read output from command: standard output was redirected} {TCL OPERATION EXEC BADREDIRECT}}
+test iocmd-11.3 {I/O to command pipelines} {unixOrPc unixExecs} {
+ list [catch {open "| echo > \"$path(test5)\"" r+} msg] $msg $::errorCode
+} {1 {can't read output from command: standard output was redirected} {TCL OPERATION EXEC BADREDIRECT}}
+test iocmd-11.4 {I/O to command pipelines} unixOrPc {
+ list [catch {open "| no_such_command_exists" rb} msg] $msg $::errorCode
+} {1 {couldn't execute "no_such_command_exists": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+
+test iocmd-12.1 {POSIX open access modes: RDONLY} {
+ file delete $path(test1)
+ set f [open $path(test1) w]
+ puts $f "Two lines: this one"
+ puts $f "and this one"
+ close $f
+ set f [open $path(test1) RDONLY]
+ set x [list [gets $f] [catch {puts $f Test} msg] $msg]
+ close $f
+ string compare $x \
+ "{Two lines: this one} 1 [list [format "channel \"%s\" wasn't opened for writing" $f]]"
+} 0
+test iocmd-12.2 {POSIX open access modes: RDONLY} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) RDONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test iocmd-12.3 {POSIX open access modes: WRONLY} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) WRONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+#
+# Test 13.4 relies on assigning the same channel name twice.
+#
+test iocmd-12.4 {POSIX open access modes: WRONLY} {unix} {
+ file delete $path(test3)
+ set f [open $path(test3) w]
+ fconfigure $f -eofchar {}
+ puts $f xyzzy
+ close $f
+ set f [open $path(test3) WRONLY]
+ fconfigure $f -eofchar {}
+ puts -nonewline $f "ab"
+ seek $f 0 current
+ set x [list [catch {gets $f} msg] $msg]
+ close $f
+ set f [open $path(test3) r]
+ fconfigure $f -eofchar {}
+ lappend x [gets $f]
+ close $f
+ set y [list 1 [format "channel \"%s\" wasn't opened for reading" $f] abzzy]
+ string compare $x $y
+} 0
+test iocmd-12.5 {POSIX open access modes: RDWR} -match regexp -body {
+ file delete $path(test3)
+ open $path(test3) RDWR
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test iocmd-12.6 {POSIX open access modes: errors} {
+ concat [catch {open $path(test3) "FOO \{BAR BAZ"} msg] $msg\n$::errorInfo
+} "1 unmatched open brace in list
+unmatched open brace in list
+ while processing open access modes \"FOO {BAR BAZ\"
+ invoked from within
+\"open \$path(test3) \"FOO \\{BAR BAZ\"\""
+test iocmd-12.7 {POSIX open access modes: errors} {
+ list [catch {open $path(test3) {FOO BAR BAZ}} msg] $msg
+} {1 {invalid access mode "FOO": must be RDONLY, WRONLY, RDWR, APPEND, BINARY, CREAT, EXCL, NOCTTY, NONBLOCK, or TRUNC}}
+test iocmd-12.8 {POSIX open access modes: errors} {
+ list [catch {open $path(test3) {TRUNC CREAT}} msg] $msg
+} {1 {access mode must include either RDONLY, WRONLY, or RDWR}}
+close [open $path(test3) w]
+test iocmd-12.9 {POSIX open access modes: BINARY} {
+ list [catch {open $path(test1) BINARY} msg] $msg
+} {1 {access mode must include either RDONLY, WRONLY, or RDWR}}
+test iocmd-12.10 {POSIX open access modes: BINARY} {
+ set f [open $path(test1) {WRONLY BINARY TRUNC}]
+ puts $f a
+ puts $f b
+ puts -nonewline $f c ;# contents are now 5 bytes: a\nb\nc
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation binary
+ set result [string length [read $f]]
+ close $f
+ set result
+} 5
+test iocmd-12.11 {POSIX open access modes: BINARY} {
+ set f [open $path(test1) {WRONLY BINARY TRUNC}]
+ puts $f \u0248 ;# gets truncated to \u0048
+ close $f
+ set f [open $path(test1) r]
+ fconfigure $f -translation binary
+ set result [read -nonewline $f]
+ close $f
+ set result
+} \u0048
+
+test iocmd-13.1 {errors in open command} {
+ list [catch {open} msg] $msg
+} {1 {wrong # args: should be "open fileName ?access? ?permissions?"}}
+test iocmd-13.2 {errors in open command} {
+ list [catch {open a b c d} msg] $msg
+} {1 {wrong # args: should be "open fileName ?access? ?permissions?"}}
+test iocmd-13.3 {errors in open command} {
+ list [catch {open $path(test1) x} msg] $msg
+} {1 {illegal access mode "x"}}
+test iocmd-13.4 {errors in open command} {
+ list [catch {open $path(test1) rw} msg] $msg
+} {1 {illegal access mode "rw"}}
+test iocmd-13.5 {errors in open command} {
+ list [catch {open $path(test1) r+1} msg] $msg
+} {1 {illegal access mode "r+1"}}
+test iocmd-13.6 {errors in open command} {
+ set msg [list [catch {open _non_existent_} msg] $msg $::errorCode]
+ regsub [file join {} _non_existent_] $msg "_non_existent_" msg
+ string tolower $msg
+} {1 {couldn't open "_non_existent_": no such file or directory} {posix enoent {no such file or directory}}}
+test iocmd-13.7 {errors in open command} {
+ list [catch {open $path(test1) b} msg] $msg
+} {1 {illegal access mode "b"}}
+test iocmd-13.8 {errors in open command} {
+ list [catch {open $path(test1) rbb} msg] $msg
+} {1 {illegal access mode "rbb"}}
+test iocmd-13.9 {errors in open command} {
+ list [catch {open $path(test1) r++} msg] $msg
+} {1 {illegal access mode "r++"}}
+test iocmd-13.10.1 {open for append, a mode} -setup {
+ set log [makeFile {} out]
+ set chans {}
+} -body {
+ foreach i { 0 1 2 3 4 5 6 7 8 9 } {
+ puts [set ch [open $log a]] $i
+ lappend chans $ch
+ }
+ foreach ch $chans {catch {close $ch}}
+ lsort [split [string trim [viewFile out]] \n]
+} -cleanup {
+ removeFile out
+ # Ensure that channels are gone, even if body failed to do so
+ foreach ch $chans {catch {close $ch}}
+} -result {0 1 2 3 4 5 6 7 8 9}
+test iocmd-13.10.2 {open for append, O_APPEND} -setup {
+ set log [makeFile {} out]
+ set chans {}
+} -body {
+ foreach i { 0 1 2 3 4 5 6 7 8 9 } {
+ puts [set ch [open $log {WRONLY CREAT APPEND}]] $i
+ lappend chans $ch
+ }
+ foreach ch $chans {catch {close $ch}}
+ lsort [split [string trim [viewFile out]] \n]
+} -cleanup {
+ removeFile out
+ # Ensure that channels are gone, even if body failed to do so
+ foreach ch $chans {catch {close $ch}}
+} -result {0 1 2 3 4 5 6 7 8 9}
+test ioCmd-13.11 {open ... a+ must not use O_APPEND: Bug 1773127} -setup {
+ set f [makeFile {} ioutil41.tmp]
+ set fid [open $f wb]
+ puts -nonewline $fid 123
+ close $fid
+} -body {
+ set fid [open $f ab+]
+ puts -nonewline $fid 456
+ seek $fid 2
+ set d [read $fid 2]
+ seek $fid 4
+ puts -nonewline $fid x
+ close $fid
+ set fid [open $f rb]
+ append d [read $fid]
+ close $fid
+ return $d
+} -cleanup {
+ removeFile $f
+} -result 341234x6
+
+
+test iocmd-14.1 {file id parsing errors} {
+ list [catch {eof gorp} msg] $msg $::errorCode
+} {1 {can not find channel named "gorp"} {TCL LOOKUP CHANNEL gorp}}
+test iocmd-14.2 {file id parsing errors} {
+ list [catch {eof filex} msg] $msg
+} {1 {can not find channel named "filex"}}
+test iocmd-14.3 {file id parsing errors} {
+ list [catch {eof file12a} msg] $msg
+} {1 {can not find channel named "file12a"}}
+test iocmd-14.4 {file id parsing errors} {
+ list [catch {eof file123} msg] $msg
+} {1 {can not find channel named "file123"}}
+test iocmd-14.5 {file id parsing errors} {
+ list [catch {eof stdout} msg] $msg
+} {0 0}
+test iocmd-14.6 {file id parsing errors} {
+ list [catch {eof stdin} msg] $msg
+} {0 0}
+test iocmd-14.7 {file id parsing errors} {
+ list [catch {eof stdout} msg] $msg
+} {0 0}
+test iocmd-14.8 {file id parsing errors} {
+ list [catch {eof stderr} msg] $msg
+} {0 0}
+test iocmd-14.9 {file id parsing errors} {
+ list [catch {eof stderr1} msg] $msg
+} {1 {can not find channel named "stderr1"}}
+
+set f [open $path(test1) w]
+close $f
+
+set expect "1 {can not find channel named \"$f\"}"
+test iocmd-14.10 {file id parsing errors} {
+ list [catch {eof $f} msg] $msg
+} $expect
+
+test iocmd-15.1 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy} msg] $msg
+} {1 {wrong # args: should be "fcopy input output ?-size size? ?-command callback?"}}
+test iocmd-15.2 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy 1} msg] $msg
+} {1 {wrong # args: should be "fcopy input output ?-size size? ?-command callback?"}}
+test iocmd-15.3 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy 1 2 3 4 5 6 7} msg] $msg
+} {1 {wrong # args: should be "fcopy input output ?-size size? ?-command callback?"}}
+test iocmd-15.4 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy 1 2 3} msg] $msg
+} {1 {wrong # args: should be "fcopy input output ?-size size? ?-command callback?"}}
+test iocmd-15.5 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy 1 2 3 4 5} msg] $msg
+} {1 {wrong # args: should be "fcopy input output ?-size size? ?-command callback?"}}
+
+set path(test2) [makeFile {} test2]
+set f [open $path(test1) w]
+close $f
+set rfile [open $path(test1) r]
+set wfile [open $path(test2) w]
+
+test iocmd-15.6 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy foo $wfile} msg] $msg
+} {1 {can not find channel named "foo"}}
+test iocmd-15.7 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy $rfile foo} msg] $msg
+} {1 {can not find channel named "foo"}}
+test iocmd-15.8 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy $wfile $wfile} msg] $msg
+} "1 {channel \"$wfile\" wasn't opened for reading}"
+test iocmd-15.9 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy $rfile $rfile} msg] $msg
+} "1 {channel \"$rfile\" wasn't opened for writing}"
+test iocmd-15.10 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy $rfile $wfile foo bar} msg] $msg
+} {1 {bad switch "foo": must be -size or -command}}
+test iocmd-15.11 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy $rfile $wfile -size foo} msg] $msg
+} {1 {expected integer but got "foo"}}
+test iocmd-15.12 {Tcl_FcopyObjCmd} {fcopy} {
+ list [catch {fcopy $rfile $wfile -command bar -size foo} msg] $msg
+} {1 {expected integer but got "foo"}}
+
+close $rfile
+close $wfile
+
+# ### ### ### ######### ######### #########
+## Testing the reflected channel.
+
+test iocmd-20.0 {chan, wrong#args} {
+ catch {chan} msg
+ set msg
+} {wrong # args: should be "chan subcommand ?arg ...?"}
+test iocmd-20.1 {chan, unknown method} -body {
+ chan foo
+} -returnCodes error -match glob -result {unknown or ambiguous subcommand "foo": must be *}
+
+# --- --- --- --------- --------- ---------
+# chan create, and method "initalize"
+
+test iocmd-21.0 {chan create, wrong#args, not enough} {
+ catch {chan create} msg
+ set msg
+} {wrong # args: should be "chan create mode cmdprefix"}
+test iocmd-21.1 {chan create, wrong#args, too many} {
+ catch {chan create a b c} msg
+ set msg
+} {wrong # args: should be "chan create mode cmdprefix"}
+test iocmd-21.2 {chan create, invalid r/w mode, empty} {
+ proc foo {} {}
+ catch {chan create {} foo} msg
+ rename foo {}
+ set msg
+} {bad mode list: is empty}
+test iocmd-21.3 {chan create, invalid r/w mode, bad string} {
+ proc foo {} {}
+ catch {chan create {c} foo} msg
+ rename foo {}
+ set msg
+} {bad mode "c": must be read or write}
+test iocmd-21.4 {chan create, bad handler, not a list} {
+ catch {chan create {r w} "foo \{"} msg
+ set msg
+} {unmatched open brace in list}
+test iocmd-21.5 {chan create, bad handler, not a command} {
+ catch {chan create {r w} foo} msg
+ set msg
+} {invalid command name "foo"}
+test iocmd-21.6 {chan create, initialize failed, bad signature} {
+ proc foo {} {}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} {wrong # args: should be "foo"}
+test iocmd-21.7 {chan create, initialize failed, bad signature} {
+ proc foo {} {}
+ catch {chan create {r w} ::foo} msg
+ rename foo {}
+ set msg
+} {wrong # args: should be "::foo"}
+test iocmd-21.8 {chan create, initialize failed, bad result, not a list} -body {
+ proc foo {args} {return "\{"}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set ::errorInfo
+} -match glob -result {chan handler "foo initialize" returned non-list: *}
+test iocmd-21.9 {chan create, initialize failed, bad result, not a list} -body {
+ proc foo {args} {return \{\{\}}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {chan handler "foo initialize" returned non-list: *}
+test iocmd-21.10 {chan create, initialize failed, bad result, empty list} -body {
+ proc foo {args} {}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {*all required methods*}
+test iocmd-21.11 {chan create, initialize failed, bad result, bogus method name} -body {
+ proc foo {args} {return 1}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {*bad method "1": must be *}
+test iocmd-21.12 {chan create, initialize failed, bad result, bogus method name} -body {
+ proc foo {args} {return {a b c}}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {*bad method "c": must be *}
+test iocmd-21.13 {chan create, initialize failed, bad result, required methods missing} -body {
+ proc foo {args} {return {initialize finalize}}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {*all required methods*}
+test iocmd-21.14 {chan create, initialize failed, bad result, mode/handler mismatch} -body {
+ proc foo {args} {return {initialize finalize watch read}}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {*lacks a "write" method}
+test iocmd-21.15 {chan create, initialize failed, bad result, mode/handler mismatch} -body {
+ proc foo {args} {return {initialize finalize watch write}}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {*lacks a "read" method}
+test iocmd-21.16 {chan create, initialize failed, bad result, cget(all) mismatch} -body {
+ proc foo {args} {return {initialize finalize watch cget write read}}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {*supports "cget" but not "cgetall"}
+test iocmd-21.17 {chan create, initialize failed, bad result, cget(all) mismatch} -body {
+ proc foo {args} {return {initialize finalize watch cgetall read write}}
+ catch {chan create {r w} foo} msg
+ rename foo {}
+ set msg
+} -match glob -result {*supports "cgetall" but not "cget"}
+test iocmd-21.18 {chan create, initialize ok, creates channel} -match glob -body {
+ proc foo {args} {
+ global res
+ lappend res $args
+ if {[lindex $args 0] ne "initialize"} {return}
+ return {initialize finalize watch read write}
+ }
+ set res {}
+ lappend res [file channel rc*]
+ lappend res [chan create {r w} foo]
+ lappend res [close [lindex $res end]]
+ lappend res [file channel rc*]
+ rename foo {}
+ set res
+} -result {{} {initialize rc* {read write}} rc* {finalize rc*} {} {}}
+test iocmd-21.19 {chan create, init failure -> no channel, no finalize} -match glob -body {
+ proc foo {args} {
+ global res
+ lappend res $args
+ return {}
+ }
+ set res {}
+ lappend res [file channel rc*]
+ lappend res [catch {chan create {r w} foo} msg]
+ lappend res $msg
+ lappend res [file channel rc*]
+ rename foo {}
+ set res
+} -result {{} {initialize rc* {read write}} 1 {*all required methods*} {}}
+
+# --- --- --- --------- --------- ---------
+# Helper commands to record the arguments to handler methods.
+
+# Stored in a script so that the threads and interpreters needing this
+# code do not need their own copy but can access this variable.
+
+set helperscript {
+
+proc note {item} {global res; lappend res $item; return}
+proc track {} {upvar args item; note $item; return}
+proc notes {items} {foreach i $items {note $i}}
+# This forces the return options to be in the order that the test expects!
+proc noteOpts opts {global res; lappend res [dict merge {
+ -code !?! -level !?! -errorcode !?! -errorline !?! -errorinfo !?!
+} $opts]; return}
+
+# Helper command, canned result for 'initialize' method.
+# Gets the optional methods as arguments. Use return features
+# to post the result higher up.
+
+proc init {args} {
+ lappend args initialize finalize watch read write
+ return -code return $args
+}
+proc oninit {args} {
+ upvar args hargs
+ if {[lindex $hargs 0] ne "initialize"} {return}
+ lappend args initialize finalize watch read write
+ return -code return $args
+}
+proc onfinal {} {
+ upvar args hargs
+ if {[lindex $hargs 0] ne "finalize"} {return}
+ return -code return ""
+}
+}
+
+# Set everything up in the main thread.
+eval $helperscript
+
+# --- --- --- --------- --------- ---------
+# method finalize
+
+test iocmd-22.1 {chan finalize, handler destruction has no effect on channel} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return}
+ note [set c [chan create {r w} foo]]
+ rename foo {}
+ note [file channels rc*]
+ note [catch {close $c} msg]; note $msg
+ note [file channels rc*]
+ set res
+} -result {{initialize rc* {read write}} rc* rc* 1 {invalid command name "foo"} {}}
+test iocmd-22.2 {chan finalize, for close} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return {}}
+ note [set c [chan create {r w} foo]]
+ close $c
+ # Close deleted the channel.
+ note [file channels rc*]
+ # Channel destruction does not kill handler command!
+ note [info command foo]
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} {} foo}
+test iocmd-22.3 {chan finalize, for close, error, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -code error 5}
+ note [set c [chan create {r w} foo]]
+ note [catch {close $c} msg]; note $msg
+ # Channel is gone despite error.
+ note [file channels rc*]
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 5 {}}
+test iocmd-22.4 {chan finalize, for close, error, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; error FOO}
+ note [set c [chan create {r w} foo]]
+ note [catch {close $c} msg]; note $msg; note $::errorInfo
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 FOO {FOO
+*"close $c"}}
+test iocmd-22.5 {chan finalize, for close, arbitrary result, ignored} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return SOMETHING}
+ note [set c [chan create {r w} foo]]
+ note [catch {close $c} msg]; note $msg
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 0 {}}
+test iocmd-22.6 {chan finalize, for close, break, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -code 3}
+ note [set c [chan create {r w} foo]]
+ note [catch {close $c} msg]; note $msg
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*}
+test iocmd-22.7 {chan finalize, for close, continue, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -code 4}
+ note [set c [chan create {r w} foo]]
+ note [catch {close $c} msg]; note $msg
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*}
+test iocmd-22.8 {chan finalize, for close, custom code, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -code 777 BANG}
+ note [set c [chan create {r w} foo]]
+ note [catch {close $c} msg]; note $msg
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*}
+test iocmd-22.9 {chan finalize, for close, ignore level, close error} -match glob -setup {
+ set res {}
+} -body {
+ proc foo {args} {track; oninit; return -level 5 -code 777 BANG}
+ note [set c [chan create {r w} foo]]
+ note [catch {close $c} msg opt]; note $msg; noteOpts $opt
+ return $res
+} -cleanup {
+ rename foo {}
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "finalize"*}}
+
+# --- === *** ###########################
+# method read
+
+test iocmd-23.1 {chan read, regular data return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return snarf
+ }
+ set c [chan create {r w} foo]
+ note [read $c 10]
+ close $c
+ rename foo {}
+ set res
+} -result {{read rc* 4096} {read rc* 4096} snarfsnarf}
+test iocmd-23.2 {chan read, bad data return, to much} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return [string repeat snarf 1000]
+ }
+ set c [chan create {r w} foo]
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 {read delivered more than requested}}
+test iocmd-23.3 {chan read, for non-readable channel} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track; note MUST_NOT_HAPPEN
+ }
+ set c [chan create {w} foo]
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {1 {channel "rc*" wasn't opened for reading}}
+test iocmd-23.4 {chan read, error return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 BOOM!}
+test iocmd-23.5 {chan read, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -code break BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 *bad code*}
+test iocmd-23.6 {chan read, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -code continue BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 *bad code*}
+test iocmd-23.7 {chan read, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -code 777 BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 *bad code*}
+test iocmd-23.8 {chan read, level is squashed} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -level 55 -code 777 BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {read $c 2} msg opt]; note $msg; noteOpts $opt
+ close $c
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}}
+test iocmd-23.9 {chan read, no data means eof} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return ""
+ }
+ set c [chan create {r w} foo]
+} -body {
+ note [read $c 2]
+ note [eof $c]
+ set res
+} -cleanup {
+ close $c
+ rename foo {}
+ unset res
+} -result {{read rc* 4096} {} 1}
+test iocmd-23.10 {chan read, EAGAIN means no data, yet no eof either} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ error EAGAIN
+ }
+ set c [chan create {r w} foo]
+} -body {
+ note [read $c 2]
+ note [eof $c]
+ set res
+} -cleanup {
+ close $c
+ rename foo {}
+ unset res
+} -result {{read rc* 4096} {} 0}
+
+# --- === *** ###########################
+# method write
+
+test iocmd-24.1 {chan write, regular write} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ set written [string length [lindex $args 2]]
+ note $written
+ return $written
+ }
+ set c [chan create {r w} foo]
+ puts -nonewline $c snarf; flush $c
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarf} 5}
+test iocmd-24.2 {chan write, partial write is ok} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ set written [string length [lindex $args 2]]
+ if {$written > 10} {set written [expr {$written / 2}]}
+ note $written
+ return $written
+ }
+ set c [chan create {r w} foo]
+ puts -nonewline $c snarfsnarfsnarf; flush $c
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 7 {write rc* arfsnarf} 8}
+test iocmd-24.3 {chan write, failed write} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note -1; return -1}
+ set c [chan create {r w} foo]
+ puts -nonewline $c snarfsnarfsnarf; flush $c
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} -1}
+test iocmd-24.4 {chan write, non-writable channel} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r} foo]
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {1 {channel "rc*" wasn't opened for writing}}
+test iocmd-24.5 {chan write, bad result, more written than data} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return 10000}
+ set c [chan create {r w} foo]
+ note [catch {puts -nonewline $c snarf; flush $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarf} 1 {write wrote more than requested}}
+test iocmd-24.6 {chan write, bad result, zero-length write} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return 0}
+ set c [chan create {r w} foo]
+ note [catch {puts -nonewline $c snarf; flush $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarf} 1 {write wrote nothing}}
+test iocmd-24.7 {chan write, failed write, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code error BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 BOOM!}
+test iocmd-24.8 {chan write, failed write, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; error BOOM!}
+ set c [chan create {r w} foo]
+ notes [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 BOOM!}
+test iocmd-24.9 {chan write, failed write, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code break BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*}
+test iocmd-24.10 {chan write, failed write, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code continue BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*}
+test iocmd-24.11 {chan write, failed write, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code 777 BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*}
+test iocmd-24.12 {chan write, failed write, non-numeric return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return BANG}
+ set c [chan create {r w} foo]
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 {expected integer but got "BANG"}}
+test iocmd-24.13 {chan write, failed write, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -level 55 -code 777 BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg opt]
+ note $msg
+ noteOpts $opt
+ close $c
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "write"*}}
+test iocmd-24.14 {chan write, no EAGAIN means that writing is allowed at this time, bug 2936225} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return 3
+ }
+ set c [chan create {r w} foo]
+} -body {
+ note [puts -nonewline $c ABC ; flush $c]
+ set res
+} -cleanup {
+ close $c
+ rename foo {}
+ unset res
+} -result {{write rc* ABC} {}}
+test iocmd-24.15 {chan write, EAGAIN means that writing is not allowed at this time, bug 2936225} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ # Note: The EAGAIN signals that the channel cannot accept
+ # write requests right now, this in turn causes the IO core to
+ # request the generation of writable events (see expected
+ # result below, and compare to case 24.14 above).
+ error EAGAIN
+ }
+ set c [chan create {r w} foo]
+} -body {
+ note [puts -nonewline $c ABC ; flush $c]
+ set res
+} -cleanup {
+ close $c
+ rename foo {}
+ unset res
+} -result {{write rc* ABC} {watch rc* write} {}}
+
+# --- === *** ###########################
+# method cgetall
+
+test iocmd-25.1 {chan configure, cgetall, standard options} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ note [fconfigure $c]
+ close $c
+ rename foo {}
+ set res
+} -result {{-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *}}}
+test iocmd-25.2 {chan configure, cgetall, no options} -match glob -body {
+ set res {}
+ proc foo {args} {oninit cget cgetall; onfinal; track; return ""}
+ set c [chan create {r w} foo]
+ note [fconfigure $c]
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *}}}
+test iocmd-25.3 {chan configure, cgetall, regular result} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return "-bar foo -snarf x"
+ }
+ set c [chan create {r w} foo]
+ note [fconfigure $c]
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *} -bar foo -snarf x}}
+test iocmd-25.4 {chan configure, cgetall, bad result, list of uneven length} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return "-bar"
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 {Expected list with even number of elements, got 1 element instead}}
+test iocmd-25.5 {chan configure, cgetall, bad result, not a list} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return "\{"
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 {unmatched open brace in list}}
+test iocmd-25.6 {chan configure, cgetall, error return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 BOOM!}
+test iocmd-25.7 {chan configure, cgetall, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code break BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 *bad code*}
+test iocmd-25.8 {chan configure, cgetall, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code continue BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 *bad code*}
+test iocmd-25.9 {chan configure, cgetall, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code 777 BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 *bad code*}
+test iocmd-25.10 {chan configure, cgetall, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -level 55 -code 777 BANG
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c} msg opt]; note $msg; noteOpts $opt
+ close $c
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cgetall"*}}
+
+# --- === *** ###########################
+# method configure
+
+test iocmd-26.1 {chan configure, set standard option} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track; note MUST_NOT_HAPPEN; return
+ }
+ set c [chan create {r w} foo]
+ note [fconfigure $c -translation lf]
+ close $c
+ rename foo {}
+ set res
+} -result {{}}
+test iocmd-26.2 {chan configure, set option, error return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo bar} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 BOOM!}
+test iocmd-26.3 {chan configure, set option, ok return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit configure; onfinal; track; return}
+ set c [chan create {r w} foo]
+ note [fconfigure $c -rc-foo bar]
+ close $c
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} {}}
+test iocmd-26.4 {chan configure, set option, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -code break BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo bar} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*}
+test iocmd-26.5 {chan configure, set option, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -code continue BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo bar} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*}
+test iocmd-26.6 {chan configure, set option, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -code 444 BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo bar} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*}
+test iocmd-26.7 {chan configure, set option, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -level 55 -code 444 BANG
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo bar} msg opt]; note $msg; noteOpts $opt
+ close $c
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "configure"*}}
+
+# --- === *** ###########################
+# method cget
+
+test iocmd-27.1 {chan configure, get option, ok return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit cget cgetall; onfinal; track; return foo}
+ set c [chan create {r w} foo]
+ note [fconfigure $c -rc-foo]
+ close $c
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} foo}
+test iocmd-27.2 {chan configure, get option, error return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 BOOM!}
+test iocmd-27.3 {chan configure, get option, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 BOOM!}
+test iocmd-27.4 {chan configure, get option, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code continue BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 *bad code*}
+test iocmd-27.5 {chan configure, get option, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code 333 BOOM!
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 *bad code*}
+test iocmd-27.6 {chan configure, get option, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -level 77 -code 333 BANG
+ }
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -rc-foo} msg opt]; note $msg; noteOpts $opt
+ close $c
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cget"*}}
+
+# --- === *** ###########################
+# method seek
+
+test iocmd-28.1 {chan tell, not supported by handler} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ note [tell $c]
+ close $c
+ rename foo {}
+ set res
+} -result {-1}
+test iocmd-28.2 {chan tell, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code error BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {tell $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 BOOM!}
+test iocmd-28.3 {chan tell, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code break BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {tell $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 *bad code*}
+test iocmd-28.4 {chan tell, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code continue BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {tell $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 *bad code*}
+test iocmd-28.5 {chan tell, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code 222 BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {tell $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 *bad code*}
+test iocmd-28.6 {chan tell, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -level 11 -code 222 BANG}
+ set c [chan create {r w} foo]
+ note [catch {tell $c} msg opt]; note $msg; noteOpts $opt
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}}
+test iocmd-28.7 {chan tell, regular return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return 88}
+ set c [chan create {r w} foo]
+ note [tell $c]
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 88}
+test iocmd-28.8 {chan tell, negative return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -1}
+ set c [chan create {r w} foo]
+ note [catch {tell $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 {Tried to seek before origin}}
+test iocmd-28.9 {chan tell, string return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return BOGUS}
+ set c [chan create {r w} foo]
+ note [catch {tell $c} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 {expected integer but got "BOGUS"}}
+test iocmd-28.10 {chan seek, not supported by handler} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ note [catch {seek $c 0 start} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {1 {error during seek on "rc*": invalid argument}}
+test iocmd-28.11 {chan seek, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code error BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {seek $c 0 start} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 BOOM!}
+test iocmd-28.12 {chan seek, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code break BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {seek $c 0 start} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 *bad code*}
+test iocmd-28.13 {chan seek, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code continue BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {seek $c 0 start} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 *bad code*}
+test iocmd-28.14 {chan seek, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code 99 BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {seek $c 0 start} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 *bad code*}
+test iocmd-28.15 {chan seek, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -level 33 -code 99 BANG}
+ set c [chan create {r w} foo]
+ note [catch {seek $c 0 start} msg opt]; note $msg; noteOpts $opt
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}}
+test iocmd-28.16 {chan seek, bogus return, negative location} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -45}
+ set c [chan create {r w} foo]
+ note [catch {seek $c 0 start} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 {Tried to seek before origin}}
+test iocmd-28.17 {chan seek, bogus return, string return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return BOGUS}
+ set c [chan create {r w} foo]
+ note [catch {seek $c 0 start} msg]; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 {expected integer but got "BOGUS"}}
+test iocmd-28.18 {chan seek, ok result} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return 23}
+ set c [chan create {r w} foo]
+ note [seek $c 0 current]
+ close $c
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} {}}
+foreach {testname code} {
+ iocmd-28.19.0 start
+ iocmd-28.19.1 current
+ iocmd-28.19.2 end
+} {
+ test $testname "chan seek, base conversion, $code" -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return 0}
+ set c [chan create {r w} foo]
+ note [seek $c 0 $code]
+ close $c
+ rename foo {}
+ set res
+ } -result [list [list seek rc* 0 $code] {}]
+}
+
+# --- === *** ###########################
+# method blocking
+
+test iocmd-29.1 {chan blocking, no handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ note [fconfigure $c -blocking]
+ close $c
+ rename foo {}
+ set res
+} -result {1}
+test iocmd-29.2 {chan blocking, no handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ note [fconfigure $c -blocking 0]
+ note [fconfigure $c -blocking]
+ close $c
+ rename foo {}
+ set res
+} -result {{} 0}
+test iocmd-29.3 {chan blocking, retrieval, handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ note [fconfigure $c -blocking]
+ close $c
+ rename foo {}
+ set res
+} -result {1}
+test iocmd-29.4 {chan blocking, resetting, handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return}
+ set c [chan create {r w} foo]
+ note [fconfigure $c -blocking 0]
+ note [fconfigure $c -blocking]
+ close $c
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} {} 0}
+test iocmd-29.5 {chan blocking, setting, handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return}
+ set c [chan create {r w} foo]
+ note [fconfigure $c -blocking 1]
+ note [fconfigure $c -blocking]
+ close $c
+ rename foo {}
+ set res
+} -result {{blocking rc* 1} {} 1}
+test iocmd-29.6 {chan blocking, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; error BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -blocking 0} msg]; note $msg
+ # Catch the close. It changes blocking mode internally, and runs into the error result.
+ catch {close $c}
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 BOOM!}
+test iocmd-29.7 {chan blocking, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return -code break BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -blocking 0} msg]; note $msg
+ catch {close $c}
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 *bad code*}
+test iocmd-29.8 {chan blocking, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return -code continue BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -blocking 0} msg]; note $msg
+ catch {close $c}
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 *bad code*}
+test iocmd-29.9 {chan blocking, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return -code 44 BOOM!}
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -blocking 0} msg]; note $msg
+ catch {close $c}
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 *bad code*}
+test iocmd-29.10 {chan blocking, level is ignored} -match glob -setup {
+ set res {}
+} -body {
+ proc foo {args} {oninit blocking; onfinal; track; return -level 99 -code 44 BANG}
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -blocking 0} msg opt]; note $msg; noteOpts $opt
+ catch {close $c}
+ return $res
+} -cleanup {
+ rename foo {}
+} -result {{blocking rc* 0} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "blocking"*}}
+test iocmd-29.11 {chan blocking, regular return ok, value ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return BOGUS}
+ set c [chan create {r w} foo]
+ note [catch {fconfigure $c -blocking 0} msg]; note $msg
+ catch {close $c}
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 0 {}}
+
+# --- === *** ###########################
+# method watch
+
+test iocmd-30.1 {chan watch, read interest, some return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return IGNORED}
+ set c [chan create {r w} foo]
+ note [fileevent $c readable {set tick $tick}]
+ close $c ;# 2nd watch, interest zero.
+ rename foo {}
+ set res
+} -result {{watch rc* read} {} {watch rc* {}}}
+test iocmd-30.2 {chan watch, write interest, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code error BOOM!_IGNORED}
+ set c [chan create {r w} foo]
+ note [fileevent $c writable {set tick $tick}]
+ note [fileevent $c writable {}]
+ close $c
+ rename foo {}
+ set res
+} -result {{watch rc* write} {} {watch rc* {}} {}}
+test iocmd-30.3 {chan watch, accumulated interests} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ note [fileevent $c writable {set tick $tick}]
+ note [fileevent $c readable {set tick $tick}]
+ note [fileevent $c writable {}]
+ note [fileevent $c readable {}]
+ close $c
+ rename foo {}
+ set res
+} -result {{watch rc* write} {} {watch rc* {read write}} {} {watch rc* read} {} {watch rc* {}} {}}
+test iocmd-30.4 {chan watch, unchanged interest not forwarded} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ note [fileevent $c writable {set tick $tick}]
+ note [fileevent $c readable {set tick $tick}] ;# Script is changing,
+ note [fileevent $c readable {set tock $tock}] ;# interest does not.
+ close $c ;# 3rd and 4th watch, removing the event handlers.
+ rename foo {}
+ set res
+} -result {{watch rc* write} {} {watch rc* {read write}} {} {} {watch rc* write} {watch rc* {}}}
+
+# --- === *** ###########################
+# chan postevent
+
+test iocmd-31.1 {chan postevent, restricted to reflected channels} -match glob -body {
+ set c [open [makeFile {} goo] r]
+ catch {chan postevent $c {r w}} msg
+ close $c
+ removeFile goo
+ set msg
+} -result {can not find reflected channel named "file*"}
+test iocmd-31.2 {chan postevent, unwanted events} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ catch {chan postevent $c {r w}} msg; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{tried to post events channel "rc*" is not interested in}}
+test iocmd-31.3 {chan postevent, bad input, empty list} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ catch {chan postevent $c {}} msg; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{bad event list: is empty}}
+test iocmd-31.4 {chan postevent, bad input, illlegal keyword} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ catch {chan postevent $c goo} msg; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{bad event "goo": must be read or write}}
+test iocmd-31.5 {chan postevent, bad input, not a list} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ catch {chan postevent $c "\{"} msg; note $msg
+ close $c
+ rename foo {}
+ set res
+} -result {{unmatched open brace in list}}
+test iocmd-31.6 {chan postevent, posted events do happen} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ note [fileevent $c readable {note TOCK}]
+ set stop [after 10000 {note TIMEOUT}]
+ after 1000 {note [chan postevent $c r]}
+ vwait ::res
+ catch {after cancel $stop}
+ close $c
+ rename foo {}
+ set res
+} -result {{watch rc* read} {} TOCK {} {watch rc* {}}}
+test iocmd-31.7 {chan postevent, posted events do happen} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ note [fileevent $c writable {note TOCK}]
+ set stop [after 10000 {note TIMEOUT}]
+ after 1000 {note [chan postevent $c w]}
+ vwait ::res
+ catch {after cancel $stop}
+ close $c
+ rename foo {}
+ set res
+} -result {{watch rc* write} {} TOCK {} {watch rc* {}}}
+test iocmd-31.8 {chan postevent after close throws error} -match glob -setup {
+ proc foo {args} {oninit; onfinal; track; return}
+ proc dummy args { return }
+ set c [chan create {r w} foo]
+ fileevent $c readable dummy
+} -body {
+ close $c
+ chan postevent $c read
+} -cleanup {
+ rename foo {}
+ rename dummy {}
+} -returnCodes error -result {can not find reflected channel named "rc*"}
+
+# --- === *** ###########################
+# 'Pull the rug' tests. Create channel in a interpreter A, move to
+# other interpreter B, destroy the origin interpreter (A) before or
+# during access from B. Must not crash, must return proper errors.
+
+test iocmd-32.0 {origin interpreter of moved channel gone} -match glob -body {
+
+ set ida [interp create];#puts <<$ida>>
+ set idb [interp create];#puts <<$idb>>
+
+ # Magic to get the test* commands in the slaves
+ load {} Tcltest $ida
+ load {} Tcltest $idb
+
+ # Set up channel in interpreter
+ interp eval $ida $helperscript
+ set chan [interp eval $ida {
+ proc foo {args} {oninit seek; onfinal; track; return}
+ set chan [chan create {r w} foo]
+ fconfigure $chan -buffering none
+ set chan
+ }]
+
+ # Move channel to 2nd interpreter.
+ interp eval $ida [list testchannel cut $chan]
+ interp eval $idb [list testchannel splice $chan]
+
+ # Kill origin interpreter, then access channel from 2nd interpreter.
+ interp delete $ida
+
+ set res {}
+ lappend res [catch {interp eval $idb [list puts $chan shoo]} msg] $msg
+ lappend res [catch {interp eval $idb [list tell $chan]} msg] $msg
+ lappend res [catch {interp eval $idb [list seek $chan 1]} msg] $msg
+ lappend res [catch {interp eval $idb [list gets $chan]} msg] $msg
+ lappend res [catch {interp eval $idb [list close $chan]} msg] $msg
+ set res
+
+} -constraints {testchannel} \
+ -result {1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}}
+
+test iocmd-32.1 {origin interpreter of moved channel destroyed during access} -match glob -body {
+
+ set ida [interp create];#puts <<$ida>>
+ set idb [interp create];#puts <<$idb>>
+
+ # Magic to get the test* commands in the slaves
+ load {} Tcltest $ida
+ load {} Tcltest $idb
+
+ # Set up channel in thread
+ set chan [interp eval $ida $helperscript]
+ set chan [interp eval $ida {
+ proc foo {args} {
+ oninit; onfinal; track;
+ # destroy interpreter during channel access
+ # Actually not possible for an interp to destroy itself.
+ interp delete {}
+ return}
+ set chan [chan create {r w} foo]
+ fconfigure $chan -buffering none
+ set chan
+ }]
+
+ # Move channel to 2nd thread.
+ interp eval $ida [list testchannel cut $chan]
+ interp eval $idb [list testchannel splice $chan]
+
+ # Run access from interpreter B, this will give us a synchronous
+ # response.
+
+ interp eval $idb [list set chan $chan]
+ set res [interp eval $idb {
+ # wait a bit, give the main thread the time to start its event
+ # loop to wait for the response from B
+ after 2000
+ catch { puts $chan shoo } res
+ set res
+ }]
+ set res
+} -constraints {testchannel impossible} \
+ -result {Owner lost}
+
+test iocmd-32.2 {delete interp of reflected chan} {
+ # Bug 3034840
+ # Run this test in an interp with memory debugging to panic
+ # on the double free
+ interp create slave
+ slave eval {
+ proc no-op args {}
+ proc driver {sub args} {return {initialize finalize watch read}}
+ chan event [chan create read driver] readable no-op
+ }
+ interp delete slave
+} {}
+
+# ### ### ### ######### ######### #########
+## Same tests as above, but exercising the code forwarding and
+## receiving driver operations to the originator thread.
+
+# -*- tcl -*-
+# ### ### ### ######### ######### #########
+## Testing the reflected channel (Thread forwarding).
+#
+## The id numbers refer to the original test without thread
+## forwarding, and gaps due to tests not applicable to forwarding are
+## left to keep this asociation.
+
+# ### ### ### ######### ######### #########
+## Helper command. Runs a script in a separate thread and returns the
+## result. A channel is transfered into the thread as well, and list of
+## configuation variables
+
+proc inthread {chan script args} {
+ # Test thread.
+
+ set tid [thread::create -preserved]
+ thread::send $tid {load {} Tcltest}
+
+ # Init thread configuration.
+ # - Listed variables
+ # - Id of main thread
+ # - A number of helper commands
+
+ foreach v $args {
+ upvar 1 $v x
+ thread::send $tid [list set $v $x]
+
+ }
+ thread::send $tid [list set mid [thread::id]]
+ thread::send $tid {
+ proc note {item} {global notes; lappend notes $item}
+ proc notes {} {global notes; return $notes}
+ proc noteOpts opts {global notes; lappend notes [dict merge {
+ -code !?! -level !?! -errorcode !?! -errorline !?! -errorinfo !?!
+ } $opts]}
+ }
+ thread::send $tid [list proc s {} [list uplevel 1 $script]]; # (*)
+
+ # Transfer channel (cut/splice aka detach/attach)
+
+ testchannel cut $chan
+ thread::send $tid [list testchannel splice $chan]
+
+ # Run test script, also run local event loop!
+ # The local event loop waits for the result to come back.
+ # It is also necessary for the execution of forwarded channel
+ # operations.
+
+ set ::tres ""
+ thread::send -async $tid {
+ after 500
+ catch {s} res; # This runs the script, 's' was defined at (*)
+ thread::send -async $mid [list set ::tres $res]
+ }
+ vwait ::tres
+ # Remove test thread, and return the captured result.
+
+ thread::release $tid
+ return $::tres
+}
+
+# ### ### ### ######### ######### #########
+
+# ### ### ### ######### ######### #########
+
+test iocmd.tf-22.2 {chan finalize, for close} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return {}}
+ note [set c [chan create {r w} foo]]
+ note [inthread $c {
+ close $c
+ # Close the deleted the channel.
+ file channels rc*
+ } c]
+ # Channel destruction does not kill handler command!
+ note [info command foo]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{initialize rc* {read write}} rc* {finalize rc*} {} foo}
+test iocmd.tf-22.3 {chan finalize, for close, error, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -code error 5}
+ note [set c [chan create {r w} foo]]
+ notes [inthread $c {
+ note [catch {close $c} msg]; note $msg
+ # Channel is gone despite error.
+ note [file channels rc*]
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 5 {}}
+test iocmd.tf-22.4 {chan finalize, for close, error, close errror} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; error FOO}
+ note [set c [chan create {r w} foo]]
+ notes [inthread $c {
+ note [catch {close $c} msg]; note $msg
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 FOO}
+test iocmd.tf-22.5 {chan finalize, for close, arbitrary result} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return SOMETHING}
+ note [set c [chan create {r w} foo]]
+ notes [inthread $c {
+ note [catch {close $c} msg]; note $msg
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{initialize rc* {read write}} rc* {finalize rc*} 0 {}}
+test iocmd.tf-22.6 {chan finalize, for close, break, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -code 3}
+ note [set c [chan create {r w} foo]]
+ notes [inthread $c {
+ note [catch {close $c} msg]; note $msg
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-22.7 {chan finalize, for close, continue, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -code 4}
+ note [set c [chan create {r w} foo]]
+ notes [inthread $c {
+ note [catch {close $c} msg]; note $msg
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-22.8 {chan finalize, for close, custom code, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -code 777 BANG}
+ note [set c [chan create {r w} foo]]
+ notes [inthread $c {
+ note [catch {close $c} msg]; note $msg
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-22.9 {chan finalize, for close, ignore level, close error} -match glob -body {
+ set res {}
+ proc foo {args} {track; oninit; return -level 5 -code 777 BANG}
+ note [set c [chan create {r w} foo]]
+ notes [inthread $c {
+ note [catch {close $c} msg opt]; note $msg; noteOpts $opt
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "finalize"*}} \
+ -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method read
+
+test iocmd.tf-23.1 {chan read, regular data return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return snarf
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [read $c 10]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{read rc* 4096} {read rc* 4096} snarfsnarf}
+test iocmd.tf-23.2 {chan read, bad data return, to much} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return [string repeat snarf 1000]
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {[read $c 2]} msg]; note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{read rc* 4096} 1 {read delivered more than requested}}
+test iocmd.tf-23.3 {chan read, for non-readable channel} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track; note MUST_NOT_HAPPEN
+ }
+ set c [chan create {w} foo]
+ notes [inthread $c {
+ note [catch {[read $c 2]} msg]; note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {1 {channel "rc*" wasn't opened for reading}}
+test iocmd.tf-23.4 {chan read, error return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 BOOM!} \
+ -constraints {testchannel thread}
+test iocmd.tf-23.5 {chan read, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -code break BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-23.6 {chan read, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -code continue BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-23.7 {chan read, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -code 777 BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {read $c 2} msg]; note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-23.8 {chan read, level is squashed} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return -level 55 -code 777 BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {read $c 2} msg opt]; note $msg; noteOpts $opt
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{read rc* 4096} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}} \
+ -constraints {testchannel thread}
+test iocmd.tf-23.9 {chan read, no data means eof} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return ""
+ }
+ set c [chan create {r w} foo]
+} -body {
+ notes [inthread $c {
+ note [read $c 2]
+ note [eof $c]
+ close $c
+ notes
+ } c]
+ set res
+} -cleanup {
+ rename foo {}
+ unset res
+} -result {{read rc* 4096} {} 1} \
+ -constraints {testchannel thread}
+test iocmd.tf-23.10 {chan read, EAGAIN means no data, yet no eof either} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ error EAGAIN
+ }
+ set c [chan create {r w} foo]
+} -body {
+ notes [inthread $c {
+ note [read $c 2]
+ note [eof $c]
+ close $c
+ notes
+ } c]
+ set res
+} -cleanup {
+ rename foo {}
+ unset res
+} -result {{read rc* 4096} {} 0} \
+ -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method write
+
+test iocmd.tf-24.1 {chan write, regular write} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ set written [string length [lindex $args 2]]
+ note $written
+ return $written
+ }
+ set c [chan create {r w} foo]
+ inthread $c {
+ puts -nonewline $c snarf; flush $c
+ close $c
+ } c
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{write rc* snarf} 5}
+test iocmd.tf-24.2 {chan write, ack partial writes} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ set written [string length [lindex $args 2]]
+ if {$written > 10} {set written [expr {$written / 2}]}
+ note $written
+ return $written
+ }
+ set c [chan create {r w} foo]
+ inthread $c {
+ puts -nonewline $c snarfsnarfsnarf; flush $c
+ close $c
+ } c
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{write rc* snarfsnarfsnarf} 7 {write rc* arfsnarf} 8}
+test iocmd.tf-24.3 {chan write, failed write} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note -1; return -1}
+ set c [chan create {r w} foo]
+ inthread $c {
+ puts -nonewline $c snarfsnarfsnarf; flush $c
+ close $c
+ } c
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{write rc* snarfsnarfsnarf} -1}
+test iocmd.tf-24.4 {chan write, non-writable channel} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {1 {channel "rc*" wasn't opened for writing}}
+test iocmd.tf-24.5 {chan write, bad result, more written than data} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return 10000}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{write rc* snarf} 1 {write wrote more than requested}}
+test iocmd.tf-24.6 {chan write, zero writes} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return 0}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{write rc* snarf} 1 {write wrote more than requested}}
+test iocmd.tf-24.7 {chan write, failed write, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code error BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 BOOM!} \
+ -constraints {testchannel thread}
+test iocmd.tf-24.8 {chan write, failed write, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; error BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 BOOM!} \
+ -constraints {testchannel thread}
+test iocmd.tf-24.9 {chan write, failed write, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code break BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-24.10 {chan write, failed write, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code continue BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-24.11 {chan write, failed write, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code 777 BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-24.12 {chan write, failed write, non-numeric return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return BANG}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 {expected integer but got "BANG"}} \
+ -constraints {testchannel thread}
+test iocmd.tf-24.13 {chan write, failed write, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -level 55 -code 777 BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg opt]
+ note $msg
+ noteOpts $opt
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "write"*}} \
+ -constraints {testchannel thread}
+test iocmd.tf-24.14 {chan write, no EAGAIN means that writing is allowed at this time, bug 2936225} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ return 3
+ }
+ set c [chan create {r w} foo]
+} -body {
+ notes [inthread $c {
+ note [puts -nonewline $c ABC ; flush $c]
+ close $c
+ notes
+ } c]
+ set res
+} -cleanup {
+ rename foo {}
+ unset res
+} -result {{write rc* ABC} {}} \
+ -constraints {testchannel thread}
+test iocmd.tf-24.15 {chan write, EAGAIN means that writing is not allowed at this time, bug 2936225} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ # Note: The EAGAIN signals that the channel cannot accept
+ # write requests right now, this in turn causes the IO core to
+ # request the generation of writable events (see expected
+ # result below, and compare to case 24.14 above).
+ error EAGAIN
+ }
+ set c [chan create {r w} foo]
+} -body {
+ notes [inthread $c {
+ note [puts -nonewline $c ABC ; flush $c]
+ close $c
+ notes
+ } c]
+ set res
+} -cleanup {
+ proc foo {args} {onfinal; set ::done-24.15 1; return 3}
+ after 1000 {set ::done-24.15 2}
+ vwait done-24.15
+ rename foo {}
+ unset res
+} -result {{write rc* ABC} {watch rc* write} {}} \
+ -constraints {testchannel thread}
+
+test iocmd.tf-24.16 {chan write, note the background flush setup by close due to the EAGAIN leaving data in buffers.} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ # Note: The EAGAIN signals that the channel cannot accept
+ # write requests right now, this in turn causes the IO core to
+ # request the generation of writable events (see expected
+ # result below, and compare to case 24.14 above).
+ error EAGAIN
+ }
+ set c [chan create {r w} foo]
+} -body {
+ notes [inthread $c {
+ note [puts -nonewline $c ABC ; flush $c]
+ close $c
+ notes
+ } c]
+ # Replace handler with all-tracking one which doesn't error.
+ # This will tell us if a write-due-flush is there.
+ proc foo {args} { onfinal; note BG ; track ; set ::endbody-24.16 1}
+ # Flush (sic!) the event-queue to capture the write from a
+ # BG-flush.
+ after 1000 {set ::endbody-24.16 2}
+ vwait endbody-24.16
+ set res
+} -cleanup {
+ proc foo {args} {onfinal; set ::done-24.16 1; return 3}
+ after 1000 {set ::done-24.16 2}
+ vwait done-24.16
+ rename foo {}
+ unset res
+} -result {{write rc* ABC} {watch rc* write} {} BG {write rc* ABC}} \
+ -constraints {testchannel thread}
+
+test iocmd.tf-24.17.bug3522560 {postevent for transfered channel} \
+ -constraints {testchannel thread} -setup {
+ # This test exposes how the execution of postevent in the handler thread causes
+ # a crash if we are not properly injecting the events into the owning thread instead.
+ # With the injection the test will simply complete without crash.
+
+ set beat 10000
+ set drive 999
+ set data ...---...
+
+ proc LOG {text} {
+ #puts stderr "[thread::id]: $text"
+ return
+ }
+
+ proc POST {hi} {
+ LOG "-> [info level 0]"
+ chan postevent $hi read
+ LOG "<- [info level 0]"
+
+ set ::timer [after $::drive [info level 0]]
+ return
+ }
+
+ proc HANDLER {op ch args} {
+ lappend ::res [lrange [info level 0] 1 end]
+ LOG "-> [info level 0]"
+ set ret {}
+ switch -glob -- $op {
+ init* {set ret {initialize finalize watch read}}
+ watch {
+ set l [lindex $args 0]
+ if {[llength $l]} {
+ set ::timer [after $::drive [list POST $ch]]
+ } else {
+ after cancel $::timer
+ }
+ }
+ finalize {
+ catch { after cancel $::timer }
+ after 500 {set ::forever now}
+ }
+ read {
+ set ret $::data
+ set ::data {} ; # Next is EOF.
+ }
+ }
+ LOG "<- [info level 0] : $ret"
+ return $ret
+ }
+} -body {
+ LOG BEGIN
+ set ch [chan create {read} HANDLER]
+
+ set tid [thread::create {
+ proc LOG {text} {
+ #puts stderr "\t\t\t\t\t\t[thread::id]: $text"
+ return
+ }
+ LOG THREAD-STARTED
+ load {} Tcltest
+ proc bgerror s {
+ LOG BGERROR:$s
+ }
+ vwait forever
+ LOG THREAD-DONE
+ }]
+
+ testchannel cut $ch
+ thread::send $tid [list set thech $ch]
+ thread::send $tid [list set beat $beat]
+ thread::send -async $tid {
+ LOG SPLICE-BEG
+ testchannel splice $thech
+ LOG SPLICE-END
+ proc PROCESS {ch} {
+ LOG "-> [info level 0]"
+ if {[eof $ch]} {
+ close $ch
+ set ::done 1
+ set c <<EOF>>
+ } else {
+ set c [read $ch 1]
+ }
+ LOG "GOTCHAR: $c"
+ LOG "<- [info level 0]"
+ }
+ LOG THREAD-FILEEVENT
+ fconfigure $thech -translation binary -blocking 0
+ fileevent $thech readable [list PROCESS $thech]
+ LOG THREAD-NOEVENT-LOOP
+ set done 0
+ while {!$done} {
+ after $beat
+ LOG THREAD-HEARTBEAT
+ update
+ }
+ LOG THREAD-LOOP-DONE
+ thread::exit
+ }
+
+ LOG MAIN_WAITING
+ vwait forever
+ LOG MAIN_DONE
+
+ set res
+} -cleanup {
+ rename LOG {}
+ rename POST {}
+ rename HANDLER {}
+ unset beat drive data forever res tid ch
+} -match glob \
+ -result {{initialize rc* read} {watch rc* read} {read rc* 4096} {watch rc* {}} {watch rc* read} {read rc* 4096} {watch rc* {}} {finalize rc*}}
+
+# --- === *** ###########################
+# method cgetall
+
+test iocmd.tf-25.1 {chan configure, cgetall, standard options} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} \
+ -result {{-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *}}}
+test iocmd.tf-25.2 {chan configure, cgetall, no options} -match glob -body {
+ set res {}
+ proc foo {args} {oninit cget cgetall; onfinal; track; return ""}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} \
+ -result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *}}}
+test iocmd.tf-25.3 {chan configure, cgetall, regular result} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return "-bar foo -snarf x"
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} \
+ -result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *} -bar foo -snarf x}}
+test iocmd.tf-25.4 {chan configure, cgetall, bad result, list of uneven length} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return "-bar"
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{cgetall rc*} 1 {Expected list with even number of elements, got 1 element instead}}
+test iocmd.tf-25.5 {chan configure, cgetall, bad result, not a list} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return "\{"
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{cgetall rc*} 1 {unmatched open brace in list}}
+test iocmd.tf-25.6 {chan configure, cgetall, error return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{cgetall rc*} 1 BOOM!}
+test iocmd.tf-25.7 {chan configure, cgetall, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code break BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-25.8 {chan configure, cgetall, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code continue BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-25.9 {chan configure, cgetall, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code 777 BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-25.10 {chan configure, cgetall, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -level 55 -code 777 BANG
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c} msg opt]
+ note $msg
+ noteOpts $opt
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{cgetall rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cgetall"*}} \
+ -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method configure
+
+test iocmd.tf-26.1 {chan configure, set standard option} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track; note MUST_NOT_HAPPEN; return
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c -translation lf]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{}}
+test iocmd.tf-26.2 {chan configure, set option, error return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo bar} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{configure rc* -rc-foo bar} 1 BOOM!}
+test iocmd.tf-26.3 {chan configure, set option, ok return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit configure; onfinal; track; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c -rc-foo bar]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{configure rc* -rc-foo bar} {}}
+test iocmd.tf-26.4 {chan configure, set option, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -code break BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo bar} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-26.5 {chan configure, set option, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -code continue BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo bar} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-26.6 {chan configure, set option, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -code 444 BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo bar} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-26.7 {chan configure, set option, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit configure; onfinal; track
+ return -level 55 -code 444 BANG
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo bar} msg opt]
+ note $msg
+ noteOpts $opt
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "configure"*}} \
+ -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method cget
+
+test iocmd.tf-27.1 {chan configure, get option, ok return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit cget cgetall; onfinal; track; return foo}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c -rc-foo]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{cget rc* -rc-foo} foo}
+test iocmd.tf-27.2 {chan configure, get option, error return} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{cget rc* -rc-foo} 1 BOOM!}
+test iocmd.tf-27.3 {chan configure, get option, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code error BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 BOOM!} \
+ -constraints {testchannel thread}
+test iocmd.tf-27.4 {chan configure, get option, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code continue BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-27.5 {chan configure, get option, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -code 333 BOOM!
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-27.6 {chan configure, get option, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {
+ oninit cget cgetall; onfinal; track
+ return -level 77 -code 333 BANG
+ }
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -rc-foo} msg opt]
+ note $msg
+ noteOpts $opt
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{cget rc* -rc-foo} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cget"*}} \
+ -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method seek
+
+test iocmd.tf-28.1 {chan tell, not supported by handler} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [tell $c]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {-1} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.2 {chan tell, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code error BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {tell $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 BOOM!} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.3 {chan tell, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code break BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {tell $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.4 {chan tell, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code continue BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {tell $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.5 {chan tell, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code 222 BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {tell $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.6 {chan tell, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -level 11 -code 222 BANG}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {tell $c} msg opt]
+ note $msg
+ noteOpts $opt
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.7 {chan tell, regular return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return 88}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [tell $c]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 88} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.8 {chan tell, negative return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -1}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {tell $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 {Tried to seek before origin}} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.9 {chan tell, string return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return BOGUS}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {tell $c} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} 1 {expected integer but got "BOGUS"}} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.10 {chan seek, not supported by handler} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {seek $c 0 start} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {1 {error during seek on "rc*": invalid argument}} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.11 {chan seek, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code error BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {seek $c 0 start} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 BOOM!} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.12 {chan seek, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code break BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {seek $c 0 start} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.13 {chan seek, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code continue BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {seek $c 0 start} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.14 {chan seek, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -code 99 BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {seek $c 0 start} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.15 {chan seek, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -level 33 -code 99 BANG}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {seek $c 0 start} msg opt]
+ note $msg
+ noteOpts $opt
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.16 {chan seek, bogus return, negative location} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return -45}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {seek $c 0 start} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 {Tried to seek before origin}} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.17 {chan seek, bogus return, string return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return BOGUS}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {seek $c 0 start} msg]
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 start} 1 {expected integer but got "BOGUS"}} \
+ -constraints {testchannel thread}
+test iocmd.tf-28.18 {chan seek, ok result} -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return 23}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [seek $c 0 current]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{seek rc* 0 current} {}} \
+ -constraints {testchannel thread}
+foreach {testname code} {
+ iocmd.tf-28.19.0 start
+ iocmd.tf-28.19.1 current
+ iocmd.tf-28.19.2 end
+} {
+ test $testname "chan seek, base conversion, $code" -match glob -body {
+ set res {}
+ proc foo {args} {oninit seek; onfinal; track; return 0}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [seek $c 0 $code]
+ close $c
+ notes
+ } c code]
+ rename foo {}
+ set res
+ } -result [list [list seek rc* 0 $code] {}] \
+ -constraints {testchannel thread}
+}
+
+# --- === *** ###########################
+# method blocking
+
+test iocmd.tf-29.1 {chan blocking, no handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c -blocking]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {1} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.2 {chan blocking, no handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c -blocking 0]
+ note [fconfigure $c -blocking]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{} 0} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.3 {chan blocking, retrieval, handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; note MUST_NOT_HAPPEN; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c -blocking]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {1} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.4 {chan blocking, resetting, handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c -blocking 0]
+ note [fconfigure $c -blocking]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} {} 0} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.5 {chan blocking, setting, handler support} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fconfigure $c -blocking 1]
+ note [fconfigure $c -blocking]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{blocking rc* 1} {} 1} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.6 {chan blocking, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; error BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -blocking 0} msg]
+ note $msg
+ # Catch the close. It changes blocking mode internally, and runs into the error result.
+ catch {close $c}
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 BOOM!} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.7 {chan blocking, break return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return -code break BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -blocking 0} msg]
+ note $msg
+ catch {close $c}
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.8 {chan blocking, continue return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return -code continue BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -blocking 0} msg]
+ note $msg
+ catch {close $c}
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.9 {chan blocking, custom return is error} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return -code 44 BOOM!}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -blocking 0} msg]
+ note $msg
+ catch {close $c}
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 *bad code*} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.10 {chan blocking, level is ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return -level 99 -code 44 BANG}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -blocking 0} msg opt]
+ note $msg
+ noteOpts $opt
+ catch {close $c}
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "blocking"*}} \
+ -constraints {testchannel thread}
+test iocmd.tf-29.11 {chan blocking, regular return ok, value ignored} -match glob -body {
+ set res {}
+ proc foo {args} {oninit blocking; onfinal; track; return BOGUS}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [catch {fconfigure $c -blocking 0} msg]
+ note $msg
+ catch {close $c}
+ notes
+ } c]
+ rename foo {}
+ set res
+} -result {{blocking rc* 0} 0 {}} \
+ -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method watch
+
+test iocmd.tf-30.1 {chan watch, read interest, some return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return IGNORED}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fileevent $c readable {set tick $tick}]
+ close $c ;# 2nd watch, interest zero.
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{watch rc* read} {watch rc* {}} {}}
+test iocmd.tf-30.2 {chan watch, write interest, error return} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return -code error BOOM!_IGNORED}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fileevent $c writable {set tick $tick}]
+ note [fileevent $c writable {}]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} -result {{watch rc* write} {watch rc* {}} {} {}}
+test iocmd.tf-30.3 {chan watch, accumulated interests} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fileevent $c writable {set tick $tick}]
+ note [fileevent $c readable {set tick $tick}]
+ note [fileevent $c writable {}]
+ note [fileevent $c readable {}]
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} \
+ -result {{watch rc* write} {watch rc* {read write}} {watch rc* read} {watch rc* {}} {} {} {} {}}
+test iocmd.tf-30.4 {chan watch, unchanged interest not forwarded} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ note [fileevent $c writable {set tick $tick}]
+ note [fileevent $c readable {set tick $tick}] ;# Script is changing,
+ note [fileevent $c readable {set tock $tock}] ;# interest does not.
+ close $c ;# 3rd and 4th watch, removing the event handlers.
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} \
+ -result {{watch rc* write} {watch rc* {read write}} {watch rc* write} {watch rc* {}} {} {} {}}
+
+# --- === *** ###########################
+# postevent
+# Not possible from a thread not containing the command handler.
+# Check that this is rejected.
+
+test iocmd.tf-31.8 {chan postevent, bad input} -match glob -body {
+ set res {}
+ proc foo {args} {oninit; onfinal; track; return}
+ set c [chan create {r w} foo]
+ notes [inthread $c {
+ catch {chan postevent $c r} msg
+ note $msg
+ close $c
+ notes
+ } c]
+ rename foo {}
+ set res
+} -constraints {testchannel thread} \
+ -result {{can not find reflected channel named "rc*"}}
+
+# --- === *** ###########################
+# 'Pull the rug' tests. Create channel in a thread A, move to other
+# thread B, destroy the origin thread (A) before or during access from
+# B. Must not crash, must return proper errors.
+
+test iocmd.tf-32.0 {origin thread of moved channel gone} -match glob -body {
+
+ #puts <<$tcltest::mainThread>>main
+ set tida [thread::create -preserved];#puts <<$tida>>
+ thread::send $tida {load {} Tcltest}
+
+ set tidb [thread::create -preserved];#puts <<$tidb>>
+ thread::send $tidb {load {} Tcltest}
+
+ # Set up channel in thread
+ thread::send $tida $helperscript
+ set chan [thread::send $tida {
+ proc foo {args} {oninit seek; onfinal; track; return}
+ set chan [chan create {r w} foo]
+ fconfigure $chan -buffering none
+ set chan
+ }]
+
+ # Move channel to 2nd thread.
+ thread::send $tida [list testchannel cut $chan]
+ thread::send $tidb [list testchannel splice $chan]
+
+ # Kill origin thread, then access channel from 2nd thread.
+ thread::release $tida
+
+ set res {}
+ lappend res [catch {thread::send $tidb [list puts $chan shoo]} msg] $msg
+
+ lappend res [catch {thread::send $tidb [list tell $chan]} msg] $msg
+ lappend res [catch {thread::send $tidb [list seek $chan 1]} msg] $msg
+ lappend res [catch {thread::send $tidb [list gets $chan]} msg] $msg
+ lappend res [catch {thread::send $tidb [list close $chan]} msg] $msg
+ thread::release $tidb
+ set res
+
+} -constraints {testchannel thread} \
+ -result {1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}}
+
+
+# The test iocmd.tf-32.1 unavoidably exhibits a memory leak. We are testing
+# the ability of the reflected channel system to react to the situation where
+# the thread in which the driver routines runs exits during driver operations.
+# In this case, thread exit handlers signal back to the owner thread so that the
+# channel operation does not hang. There's no way to test this without actually
+# exiting a thread in mid-operation, and that action is unavoidably leaky (which
+# is why [thread::exit] is advised against).
+#
+# Use constraints to skip this test while valgrinding so this expected leak
+# doesn't prevent a finding of "leak-free".
+#
+testConstraint notValgrind [expr {![testConstraint valgrind]}]
+test iocmd.tf-32.1 {origin thread of moved channel destroyed during access} -match glob -body {
+
+ #puts <<$tcltest::mainThread>>main
+ set tida [thread::create -preserved];#puts <<$tida>>
+ thread::send $tida {load {} Tcltest}
+ set tidb [thread::create -preserved];#puts <<$tidb>>
+ thread::send $tidb {load {} Tcltest}
+
+ # Set up channel in thread
+ thread::send $tida $helperscript
+ set chan [thread::send $tida {
+ proc foo {args} {
+ oninit; onfinal; track;
+ # destroy thread during channel access
+ thread::exit
+ }
+ set chan [chan create {r w} foo]
+ fconfigure $chan -buffering none
+ set chan
+ }]
+
+ # Move channel to 2nd thread.
+ thread::send $tida [list testchannel cut $chan]
+ thread::send $tidb [list testchannel splice $chan]
+
+ # Run access from thread B, wait for response from A (A is not
+ # using event loop at this point, so the event pile up in the
+ # queue.
+
+ thread::send $tidb [list set chan $chan]
+ thread::send $tidb [list set mid [thread::id]]
+ thread::send -async $tidb {
+ # wait a bit, give the main thread the time to start its event
+ # loop to wait for the response from B
+ after 2000
+ catch { puts $chan shoo } res
+ thread::send -async $mid [list set ::res $res]
+ }
+ vwait ::res
+
+ catch {thread::release $tida}
+ thread::release $tidb
+ set res
+} -constraints {testchannel thread notValgrind} \
+ -result {Owner lost}
+
+# ### ### ### ######### ######### #########
+
+# ### ### ### ######### ######### #########
+
+rename track {}
+# cleanup
+foreach file [list test1 test2 test3 test4] {
+ removeFile $file
+}
+# delay long enough for background processes to finish
+after 500
+foreach file [list test5] {
+ removeFile $file
+}
+cleanupTests
+return
diff --git a/pkgs/msgcat/tests/ioTrans.test b/pkgs/msgcat/tests/ioTrans.test
new file mode 100644
index 0000000..7da4329
--- /dev/null
+++ b/pkgs/msgcat/tests/ioTrans.test
@@ -0,0 +1,1864 @@
+# -*- tcl -*-
+# Functionality covered: operation of the reflected transformation
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 2007 Andreas Kupries <andreask@activestate.com>
+# <akupries@shaw.ca>
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Custom constraints used in this file
+testConstraint testchannel [llength [info commands testchannel]]
+testConstraint thread [expr {0 == [catch {package require Thread 2.6}]}]
+
+# testchannel cut|splice Both needed to test the reflection in threads.
+# thread::send
+
+#----------------------------------------------------------------------
+
+# ### ### ### ######### ######### #########
+## Testing the reflected transformation.
+
+# Helper commands to record the arguments to handler methods. Stored in a
+# script so that the tests needing this code do not need their own copy but
+# can access this variable.
+
+set helperscript {
+ if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+ }
+
+ # This forces the return options to be in the order that the test expects!
+ variable optorder {
+ -code !?! -level !?! -errorcode !?! -errorline !?! -errorinfo !?!
+ -errorstack !?!
+ }
+ proc noteOpts opts {
+ variable optorder
+ lappend ::res [dict merge $optorder $opts]
+ }
+
+ # Helper command, canned result for 'initialize' method. Gets the
+ # optional methods as arguments. Use return features to post the result
+ # higher up.
+
+ proc handle.initialize {args} {
+ upvar args hargs
+ if {[lindex $hargs 0] eq "initialize"} {
+ return -code return [list {*}$args initialize finalize read write]
+ }
+ }
+ proc handle.finalize {} {
+ upvar args hargs
+ if {[lindex $hargs 0] eq "finalize"} {
+ return -code return ""
+ }
+ }
+ proc handle.read {} {
+ upvar args hargs
+ if {[lindex $hargs 0] eq "read"} {
+ return -code return "@"
+ }
+ }
+ proc handle.drain {} {
+ upvar args hargs
+ if {[lindex $hargs 0] eq "drain"} {
+ return -code return "<>"
+ }
+ }
+ proc handle.clear {} {
+ upvar args hargs
+ if {[lindex $hargs 0] eq "clear"} {
+ return -code return ""
+ }
+ }
+
+ proc tempchan {{mode r+}} {
+ global tempchan
+ return [set tempchan [open [makeFile {test data} tempchanfile] $mode]]
+ }
+ proc tempdone {} {
+ global tempchan
+ catch {close $tempchan}
+ removeFile tempchanfile
+ return
+ }
+ proc tempview {} { viewFile tempchanfile }
+}
+
+# Set everything up in the main thread.
+eval $helperscript
+
+#puts <<[file channels]>>
+
+# ### ### ### ######### ######### #########
+
+test iortrans-1.0 {chan, wrong#args} -returnCodes error -body {
+ chan
+} -result {wrong # args: should be "chan subcommand ?arg ...?"}
+test iortrans-1.1 {chan, unknown method} -returnCodes error -body {
+ chan foo
+} -match glob -result {unknown or ambiguous subcommand "foo": must be*}
+
+# --- --- --- --------- --------- ---------
+# chan push, and method "initalize"
+
+test iortrans-2.0 {chan push, wrong#args, not enough} -returnCodes error -body {
+ chan push
+} -result {wrong # args: should be "chan push channel cmdprefix"}
+test iortrans-2.1 {chan push, wrong#args, too many} -returnCodes error -body {
+ chan push a b c
+} -result {wrong # args: should be "chan push channel cmdprefix"}
+test iortrans-2.2 {chan push, invalid channel} -setup {
+ proc foo {} {}
+} -returnCodes error -body {
+ chan push {} foo
+} -cleanup {
+ rename foo {}
+} -result {can not find channel named ""}
+test iortrans-2.3 {chan push, bad handler, not a list} -body {
+ chan push [tempchan] "foo \{"
+} -returnCodes error -cleanup {
+ tempdone
+} -result {unmatched open brace in list}
+test iortrans-2.4 {chan push, bad handler, not a command} -body {
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+} -result {invalid command name "foo"}
+test iortrans-2.5 {chan push, initialize failed, bad signature} -body {
+ proc foo {} {}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -result {wrong # args: should be "foo"}
+test iortrans-2.6 {chan push, initialize failed, bad signature} -body {
+ proc foo {} {}
+ chan push [tempchan] ::foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -result {wrong # args: should be "::foo"}
+test iortrans-2.7 {chan push, initialize failed, bad result, not a list} -body {
+ proc foo {args} {return "\{"}
+ catch {chan push [tempchan] foo}
+ return $::errorInfo
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {chan handler "foo initialize" returned non-list: *}
+test iortrans-2.8 {chan push, initialize failed, bad result, not a list} -body {
+ proc foo {args} {return \{\{\}}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {chan handler "foo initialize" returned non-list: *}
+test iortrans-2.9 {chan push, initialize failed, bad result, empty list} -body {
+ proc foo {args} {}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {*all required methods*}
+test iortrans-2.10 {chan push, initialize failed, bad result, bogus method name} -body {
+ proc foo {args} {return 1}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {*bad method "1": must be *}
+test iortrans-2.11 {chan push, initialize failed, bad result, bogus method name} -body {
+ proc foo {args} {return {a b c}}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {*bad method "c": must be *}
+test iortrans-2.12 {chan push, initialize failed, bad result, required methods missing} -body {
+ # Required: initialize, and finalize.
+ proc foo {args} {return {initialize}}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {*all required methods*}
+test iortrans-2.13 {chan push, initialize failed, bad result, illegal method name} -body {
+ proc foo {args} {return {initialize finalize BOGUS}}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {*returned bad method "BOGUS": must be clear, drain, finalize, flush, initialize, limit?, read, or write}
+test iortrans-2.14 {chan push, initialize failed, bad result, mode/handler mismatch} -body {
+ proc foo {args} {return {initialize finalize}}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {*makes the channel inaccessible}
+# iortrans-2.15 event/watch methods elimimated, removed these tests.
+# iortrans-2.16
+test iortrans-2.17 {chan push, initialize failed, bad result, drain/read mismatch} -body {
+ proc foo {args} {return {initialize finalize drain write}}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {*supports "drain" but not "read"}
+test iortrans-2.18 {chan push, initialize failed, bad result, flush/write mismatch} -body {
+ proc foo {args} {return {initialize finalize flush read}}
+ chan push [tempchan] foo
+} -returnCodes error -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {*supports "flush" but not "write"}
+test iortrans-2.19 {chan push, initialize ok, creates channel} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ global res
+ lappend res $args
+ if {[lindex $args 0] ne "initialize"} {return}
+ return {initialize finalize drain flush read write}
+ }
+ lappend res [file channel rt*]
+ lappend res [chan push [tempchan] foo]
+ lappend res [close [lindex $res end]]
+ lappend res [file channel rt*]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{} {initialize rt* {read write}} file* {drain rt*} {flush rt*} {finalize rt*} {} {}}
+test iortrans-2.20 {chan push, init failure -> no channel, no finalize} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ global res
+ lappend res $args
+ return
+ }
+ lappend res [file channel rt*]
+ lappend res [catch {chan push [tempchan] foo} msg] $msg
+ lappend res [file channel rt*]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{} {initialize rt* {read write}} 1 {*all required methods*} {}}
+
+# --- --- --- --------- --------- ---------
+# method finalize (via close)
+
+# General note: file channels rt* finds the transform channel, however the
+# name reported will be that of the underlying base driver, fileXX here. This
+# actually allows us to see if the whole channel is gone, or only the
+# transformation, but not the base.
+
+test iortrans-3.1 {chan finalize, handler destruction has no effect on channel} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ rename foo {}
+ lappend res [file channels file*]
+ lappend res [file channels rt*]
+ lappend res [catch {close $c} msg] $msg
+ lappend res [file channels file*]
+ lappend res [file channels rt*]
+} -result {{initialize rt* {read write}} file* file* {} 1 {invalid command name "foo"} {} {}}
+test iortrans-3.2 {chan finalize, for close} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ close $c
+ # Close deleted the channel.
+ lappend res [file channels rt*]
+ # Channel destruction does not kill handler command!
+ lappend res [info command foo]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} {} foo}
+test iortrans-3.3 {chan finalize, for close, error, close error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -code error 5
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res [catch {close $c} msg] $msg
+ # Channel is gone despite error.
+ lappend res [file channels rt*]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 5 {}}
+test iortrans-3.4 {chan finalize, for close, error, close error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ error FOO
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res [catch {close $c} msg] $msg $::errorInfo
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 FOO {FOO
+*"close $c"}}
+test iortrans-3.5 {chan finalize, for close, arbitrary result, ignored} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return SOMETHING
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res [catch {close $c} msg] $msg
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 0 {}}
+test iortrans-3.6 {chan finalize, for close, break, close error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -code 3
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res [catch {close $c} msg] $msg
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans-3.7 {chan finalize, for close, continue, close error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -code 4
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res [catch {close $c} msg] $msg
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans-3.8 {chan finalize, for close, custom code, close error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -code 777 BANG
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res [catch {close $c} msg] $msg
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans-3.9 {chan finalize, for close, ignore level, close error} -setup {
+ set res {}
+} -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -level 5 -code 777 BANG
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res [catch {close $c} msg opt] $msg
+ noteOpts $opt
+} -match glob -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "finalize"*}}
+
+# --- === *** ###########################
+# method read (via read)
+
+test iortrans-4.1 {chan read, transform call and return} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return snarf
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [read $c 10]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} snarf}
+test iortrans-4.2 {chan read, for non-readable channel} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args MUST_NOT_HAPPEN
+ }
+ set c [chan push [tempchan w] foo]
+ lappend res [catch {read $c 2} msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {1 {channel "file*" wasn't opened for reading}}
+test iortrans-4.3 {chan read, error return} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code error BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {read $c 2} msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} 1 BOOM!}
+test iortrans-4.4 {chan read, break return is error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code break BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {read $c 2} msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans-4.5 {chan read, continue return is error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code continue BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {read $c 2} msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans-4.6 {chan read, custom return is error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code 777 BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {read $c 2} msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans-4.7 {chan read, level is squashed} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -level 55 -code 777 BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {read $c 2} msg opt] $msg
+ noteOpts $opt
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}}
+test iortrans-4.8 {chan read, read, bug 2921116} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {fd args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ # Kill and recreate transform while it is operating
+ chan pop $fd
+ chan push $fd [list foo $fd]
+ }
+ set c [chan push [set c [tempchan]] [list foo $c]]
+ lappend res [read $c]
+ #lappend res [gets $c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} file*}
+test iortrans-4.9 {chan read, gets, bug 2921116} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {fd args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ # Kill and recreate transform while it is operating
+ chan pop $fd
+ chan push $fd [list foo $fd]
+ }
+ set c [chan push [set c [tempchan]] [list foo $c]]
+ lappend res [gets $c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} file*}
+
+# --- === *** ###########################
+# method write (via puts)
+
+test iortrans-5.1 {chan write, regular write} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return transformresult
+ }
+ set c [chan push [tempchan] foo]
+ puts -nonewline $c snarf
+ flush $c
+ close $c
+ lappend res [tempview]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarf} transformresult}
+test iortrans-5.2 {chan write, no write is ok, no change to file} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return
+ }
+ set c [chan push [tempchan] foo]
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ close $c
+ lappend res [tempview]; # This has to show the original data, as nothing was written
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} {test data}}
+test iortrans-5.3 {chan write, failed write} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code error FAIL!
+ }
+ set c [chan push [tempchan] foo]
+ puts -nonewline $c snarfsnarfsnarf
+ lappend res [catch {flush $c} msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 FAIL!}
+test iortrans-5.4 {chan write, non-writable channel} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args MUST_NOT_HAPPEN
+ return
+ }
+ set c [chan push [tempchan r] foo]
+ lappend res [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+} -cleanup {
+ close $c
+ tempdone
+ rename foo {}
+} -result {1 {channel "file*" wasn't opened for writing}}
+test iortrans-5.5 {chan write, failed write, error return} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code error BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 BOOM!}
+test iortrans-5.6 {chan write, failed write, error return} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ error BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 BOOM!}
+test iortrans-5.7 {chan write, failed write, break return is error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code break BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans-5.8 {chan write, failed write, continue return is error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code continue BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans-5.9 {chan write, failed write, custom return is error} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code 777 BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans-5.10 {chan write, failed write, level is ignored} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -level 55 -code 777 BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg opt] $msg
+ noteOpts $opt
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline * -errorinfo *bad code*subcommand "write"*}}
+test iortrans-5.11 {chan write, bug 2921116} -match glob -setup {
+ set res {}
+ set level 0
+} -body {
+ proc foo {fd args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ # pop - invokes flush - invokes 'foo write' - infinite recursion - stop it
+ global level
+ if {$level} {
+ return
+ }
+ incr level
+ # Kill and recreate transform while it is operating
+ chan pop $fd
+ chan push $fd [list foo $fd]
+ }
+ set c [chan push [set c [tempchan]] [list foo $c]]
+ lappend res [puts -nonewline $c abcdef]
+ lappend res [flush $c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{} {write rt* abcdef} {write rt* abcdef} {}}
+
+# --- === *** ###########################
+# method limit?, drain (via read)
+
+test iortrans-6.1 {chan read, read limits} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize limit?
+ handle.finalize
+ lappend ::res $args
+ handle.read
+ return 6
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [read $c 10]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{limit? rt*} {read rt* {test d}} {limit? rt*} {read rt* {ata
+}} {limit? rt*} @@}
+test iortrans-6.2 {chan read, read transform drain on eof} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize drain
+ handle.finalize
+ lappend ::res $args
+ handle.read
+ handle.drain
+ return
+ }
+ set c [chan push [tempchan] foo]
+ lappend res [read $c]
+ lappend res [close $c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} {drain rt*} @<> {}}
+
+# --- === *** ###########################
+# method clear (via puts, seek)
+
+test iortrans-7.1 {chan write, write clears read buffers} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize clear
+ handle.finalize
+ lappend ::res $args
+ handle.clear
+ return transformresult
+ }
+ set c [chan push [tempchan] foo]
+ puts -nonewline $c snarf
+ flush $c
+ return $res
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{clear rt*} {write rt* snarf}}
+test iortrans-7.2 {seek clears read buffers} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize clear
+ handle.finalize
+ lappend ::res $args
+ return
+ }
+ set c [chan push [tempchan] foo]
+ seek $c 2
+ return $res
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{clear rt*}}
+test iortrans-7.3 {clear, any result is ignored} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize clear
+ handle.finalize
+ lappend ::res $args
+ return -code error "X"
+ }
+ set c [chan push [tempchan] foo]
+ seek $c 2
+ return $res
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{clear rt*}}
+test iortrans-7.4 {chan clear, bug 2921116} -match glob -setup {
+ set res {}
+} -body {
+ proc foo {fd args} {
+ handle.initialize clear
+ handle.finalize
+ lappend ::res $args
+ # Kill and recreate transform while it is operating
+ chan pop $fd
+ chan push $fd [list foo $fd]
+ }
+ set c [chan push [set c [tempchan]] [list foo $c]]
+ seek $c 2
+ return $res
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{clear rt*}}
+
+# --- === *** ###########################
+# method flush (via seek, close)
+
+test iortrans-8.1 {seek flushes write buffers, ignores data} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize flush
+ handle.finalize
+ lappend ::res $args
+ return X
+ }
+ set c [chan push [tempchan] foo]
+ # Flush, no writing
+ seek $c 2
+ # The close flushes again, this modifies the file!
+ lappend res |
+ lappend res [close $c] | [tempview]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{flush rt*} | {flush rt*} {} | {teXt data}}
+test iortrans-8.2 {close flushes write buffers, writes data} -setup {
+ set res {}
+} -match glob -body {
+ proc foo {args} {
+ handle.initialize flush
+ lappend ::res $args
+ handle.finalize
+ return .flushed.
+ }
+ set c [chan push [tempchan] foo]
+ close $c
+ lappend res [tempview]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{flush rt*} {finalize rt*} .flushed.}
+test iortrans-8.3 {chan flush, bug 2921116} -match glob -setup {
+ set res {}
+} -body {
+ proc foo {fd args} {
+ handle.initialize flush
+ handle.finalize
+ lappend ::res $args
+ # Kill and recreate transform while it is operating
+ chan pop $fd
+ chan push $fd [list foo $fd]
+ }
+ set c [chan push [set c [tempchan]] [list foo $c]]
+ seek $c 2
+ set res
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{flush rt*}}
+
+# --- === *** ###########################
+# method watch - removed from TIP (rev 1.12+)
+
+# --- === *** ###########################
+# method event - removed from TIP (rev 1.12+)
+
+# --- === *** ###########################
+# 'Pull the rug' tests. Create channel in a interpreter A, move to other
+# interpreter B, destroy the origin interpreter (A) before or during access
+# from B. Must not crash, must return proper errors.
+test iortrans-11.0 {origin interpreter of moved transform gone} -setup {
+ set ida [interp create]; #puts <<$ida>>
+ set idb [interp create]; #puts <<$idb>>
+ # Magic to get the test* commands in the slaves
+ load {} Tcltest $ida
+ load {} Tcltest $idb
+} -constraints {testchannel} -match glob -body {
+ # Set up channel and transform in interpreter
+ interp eval $ida $helperscript
+ interp eval $ida [list ::variable tempchan [tempchan]]
+ interp transfer {} $::tempchan $ida
+ set chan [interp eval $ida {
+ variable tempchan
+ proc foo {args} {
+ handle.initialize clear drain flush limit? read write
+ handle.finalize
+ lappend ::res $args
+ return
+ }
+ set chan [chan push $tempchan foo]
+ fconfigure $chan -buffering none
+ set chan
+ }]
+ # Move channel to 2nd interpreter, transform goes with it.
+ interp eval $ida [list testchannel cut $chan]
+ interp eval $idb [list testchannel splice $chan]
+ # Kill origin interpreter, then access channel from 2nd interpreter.
+ interp delete $ida
+ set res {}
+ lappend res \
+ [catch {interp eval $idb [list puts $chan shoo]} msg] $msg \
+ [catch {interp eval $idb [list tell $chan]} msg] $msg \
+ [catch {interp eval $idb [list seek $chan 1]} msg] $msg \
+ [catch {interp eval $idb [list gets $chan]} msg] $msg \
+ [catch {interp eval $idb [list close $chan]} msg] $msg
+ #lappend res [interp eval $ida {set res}]
+ # actions: clear|write|clear|write|clear|flush|limit?|drain|flush
+ # The 'tell' is ok, as it passed through the transform to the base channel
+ # without invoking the transform handler.
+} -cleanup {
+ tempdone
+} -result {1 {Owner lost} 0 0 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}}
+test iortrans-11.1 {origin interpreter of moved transform destroyed during access} -setup {
+ set ida [interp create]; #puts <<$ida>>
+ set idb [interp create]; #puts <<$idb>>
+ # Magic to get the test* commands in the slaves
+ load {} Tcltest $ida
+ load {} Tcltest $idb
+} -constraints {testchannel impossible} -match glob -body {
+ # Set up channel in thread
+ set chan [interp eval $ida $helperscript]
+ set chan [interp eval $ida {
+ proc foo {args} {
+ handle.initialize clear drain flush limit? read write
+ handle.finalize
+ lappend ::res $args
+ # Destroy interpreter during channel access. Actually not
+ # possible for an interp to destroy itself.
+ interp delete {}
+ return}
+ set chan [chan push [tempchan] foo]
+ fconfigure $chan -buffering none
+ set chan
+ }]
+ # Move channel to 2nd thread, transform goes with it.
+ interp eval $ida [list testchannel cut $chan]
+ interp eval $idb [list testchannel splice $chan]
+ # Run access from interpreter B, this will give us a synchronous response.
+ interp eval $idb [list set chan $chan]
+ interp eval $idb [list set mid $tcltest::mainThread]
+ set res [interp eval $idb {
+ # Wait a bit, give the main thread the time to start its event loop to
+ # wait for the response from B
+ after 50
+ catch { puts $chan shoo } res
+ set res
+ }]
+} -cleanup {
+ tempdone
+} -result {Owner lost}
+test iortrans-11.2 {delete interp of reflected transform} -setup {
+ interp create slave
+ # Magic to get the test* commands into the slave
+ load {} Tcltest slave
+} -constraints {testchannel} -body {
+ # Get base channel into the slave
+ set c [tempchan]
+ testchannel cut $c
+ interp eval slave [list testchannel splice $c]
+ interp eval slave [list set c $c]
+ slave eval {
+ proc no-op args {}
+ proc driver {c sub args} {
+ return {initialize finalize read write}
+ }
+ set t [chan push $c [list driver $c]]
+ chan event $c readable no-op
+ }
+ interp delete slave
+} -result {}
+
+# ### ### ### ######### ######### #########
+## Same tests as above, but exercising the code forwarding and receiving
+## driver operations to the originator thread.
+
+# ### ### ### ######### ######### #########
+## Testing the reflected channel (Thread forwarding).
+#
+## The id numbers refer to the original test without thread forwarding, and
+## gaps due to tests not applicable to forwarding are left to keep this
+## association.
+
+# ### ### ### ######### ######### #########
+## Helper command. Runs a script in a separate thread and returns the result.
+## A channel is transfered into the thread as well, and a list of configuation
+## variables
+
+proc inthread {chan script args} {
+ # Test thread.
+ set tid [thread::create -preserved]
+ thread::send $tid {load {} Tcltest}
+
+ # Init thread configuration.
+ # - Listed variables
+ # - Id of main thread
+ # - A number of helper commands
+
+ foreach v $args {
+ upvar 1 $v x
+ thread::send $tid [list set $v $x]
+ }
+ thread::send $tid [list set mid [thread::id]]
+ thread::send $tid {
+ proc notes {} {
+ return $::notes
+ }
+ proc noteOpts opts {
+ lappend ::notes [dict merge {
+ -code !?! -level !?! -errorcode !?! -errorline !?!
+ -errorinfo !?! -errorstack !?!
+ } $opts]
+ }
+ }
+ thread::send $tid [list proc s {} [list uplevel 1 $script]]; # (*)
+
+ # Transfer channel (cut/splice aka detach/attach)
+
+ testchannel cut $chan
+ thread::send $tid [list testchannel splice $chan]
+
+ # Run test script, also run local event loop! The local event loop waits
+ # for the result to come back. It is also necessary for the execution of
+ # forwarded channel operations.
+
+ set ::tres ""
+ thread::send -async $tid {
+ after 50
+ catch {s} res; # This runs the script, 's' was defined at (*)
+ thread::send -async $mid [list set ::tres $res]
+ }
+ vwait ::tres
+ # Remove test thread, and return the captured result.
+
+ thread::release $tid
+ return $::tres
+}
+
+# ### ### ### ######### ######### #########
+
+test iortrans.tf-3.2 {chan finalize, for close} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return {}
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res [inthread $c {
+ close $c
+ # Close the deleted the channel.
+ file channels rt*
+ } c]
+ # Channel destruction does not kill handler command!
+ lappend res [info command foo]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} {} foo}
+test iortrans.tf-3.3 {chan finalize, for close, error, close error} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -code error 5
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {close $c} msg] $msg
+ # Channel is gone despite error.
+ lappend notes [file channels rt*]
+ notes
+ } c]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 5 {}}
+test iortrans.tf-3.4 {chan finalize, for close, error, close errror} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ error FOO
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {close $c} msg] $msg
+ notes
+ } c]
+} -match glob -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 FOO}
+test iortrans.tf-3.5 {chan finalize, for close, arbitrary result} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return SOMETHING
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {close $c} msg] $msg
+ notes
+ } c]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 0 {}}
+test iortrans.tf-3.6 {chan finalize, for close, break, close error} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -code 3
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {close $c} msg] $msg
+ notes
+ } c]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans.tf-3.7 {chan finalize, for close, continue, close error} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -code 4
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {close $c} msg] $msg
+ notes
+ } c]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans.tf-3.8 {chan finalize, for close, custom code, close error} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -code 777 BANG
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {close $c} msg] $msg
+ notes
+ } c]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans.tf-3.9 {chan finalize, for close, ignore level, close error} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ lappend ::res $args
+ handle.initialize
+ return -level 5 -code 777 BANG
+ }
+ lappend res [set c [chan push [tempchan] foo]]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {close $c} msg opt] $msg
+ noteOpts $opt
+ notes
+ } c]
+} -cleanup {
+ rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "finalize"*}}
+
+# --- === *** ###########################
+# method read
+
+test iortrans.tf-4.1 {chan read, transform call and return} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return snarf
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [read $c 10]
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {{read rt* {test data
+}} snarf}
+test iortrans.tf-4.2 {chan read, for non-readable channel} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args MUST_NOT_HAPPEN
+ }
+ set c [chan push [tempchan w] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {[read $c 2]} msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {1 {channel "file*" wasn't opened for reading}}
+test iortrans.tf-4.3 {chan read, error return} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code error BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {read $c 2} msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {{read rt* {test data
+}} 1 BOOM!}
+test iortrans.tf-4.4 {chan read, break return is error} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code break BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {read $c 2} msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans.tf-4.5 {chan read, continue return is error} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code continue BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {read $c 2} msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans.tf-4.6 {chan read, custom return is error} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code 777 BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {read $c 2} msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans.tf-4.7 {chan read, level is squashed} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -level 55 -code 777 BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {read $c 2} msg opt] $msg
+ noteOpts $opt
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {{read rt* {test data
+}} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}}
+
+# --- === *** ###########################
+# method write
+
+test iortrans.tf-5.1 {chan write, regular write} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return transformresult
+ }
+ set c [chan push [tempchan] foo]
+ inthread $c {
+ puts -nonewline $c snarf
+ flush $c
+ close $c
+ } c
+ lappend res [tempview]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarf} transformresult}
+test iortrans.tf-5.2 {chan write, no write is ok, no change to file} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return
+ }
+ set c [chan push [tempchan] foo]
+ inthread $c {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ close $c
+ } c
+ lappend res [tempview]; # This has to show the original data, as nothing was written
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} {test data}}
+test iortrans.tf-5.3 {chan write, failed write} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code error FAIL!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ puts -nonewline $c snarfsnarfsnarf
+ lappend notes [catch {flush $c} msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 FAIL!}
+test iortrans.tf-5.4 {chan write, non-writable channel} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args MUST_NOT_HAPPEN
+ return
+ }
+ set c [chan push [tempchan r] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {1 {channel "file*" wasn't opened for writing}}
+test iortrans.tf-5.5 {chan write, failed write, error return} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code error BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 BOOM!}
+test iortrans.tf-5.6 {chan write, failed write, error return} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ error BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 BOOM!}
+test iortrans.tf-5.7 {chan write, failed write, break return is error} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code break BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans.tf-5.8 {chan write, failed write, continue return is error} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code continue BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans.tf-5.9 {chan write, failed write, custom return is error} -setup {
+ set res {}
+} -constraints {testchannel thread} -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -code 777 BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg] $msg
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -match glob -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans.tf-5.10 {chan write, failed write, level is ignored} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize
+ handle.finalize
+ lappend ::res $args
+ return -level 55 -code 777 BOOM!
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [catch {
+ puts -nonewline $c snarfsnarfsnarf
+ flush $c
+ } msg opt] $msg
+ noteOpts $opt
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline * -errorinfo *bad code*subcommand "write"*}}
+
+# --- === *** ###########################
+# method limit?, drain (via read)
+
+test iortrans.tf-6.1 {chan read, read limits} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize limit?
+ handle.finalize
+ lappend ::res $args
+ handle.read
+ return 6
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [read $c 10]
+ close $c
+ notes
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{limit? rt*} {read rt* {test d}} {limit? rt*} {read rt* {ata
+}} {limit? rt*} @@}
+test iortrans.tf-6.2 {chan read, read transform drain on eof} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize drain
+ handle.finalize
+ lappend ::res $args
+ handle.read
+ handle.drain
+ return
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ lappend notes [read $c]
+ lappend notes [close $c]
+ } c]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{read rt* {test data
+}} {drain rt*} @<> {}}
+
+# --- === *** ###########################
+# method clear (via puts, seek)
+
+test iortrans.tf-7.1 {chan write, write clears read buffers} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize clear
+ handle.finalize
+ lappend ::res $args
+ handle.clear
+ return transformresult
+ }
+ set c [chan push [tempchan] foo]
+ inthread $c {
+ puts -nonewline $c snarf
+ flush $c
+ close $c
+ } c
+ return $res
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{clear rt*} {write rt* snarf}}
+test iortrans.tf-7.2 {seek clears read buffers} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize clear
+ handle.finalize
+ lappend ::res $args
+ return
+ }
+ set c [chan push [tempchan] foo]
+ inthread $c {
+ seek $c 2
+ close $c
+ } c
+ return $res
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{clear rt*}}
+test iortrans.tf-7.3 {clear, any result is ignored} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize clear
+ handle.finalize
+ lappend ::res $args
+ return -code error "X"
+ }
+ set c [chan push [tempchan] foo]
+ inthread $c {
+ seek $c 2
+ close $c
+ } c
+ return $res
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{clear rt*}}
+
+# --- === *** ###########################
+# method flush (via seek, close)
+
+test iortrans.tf-8.1 {seek flushes write buffers, ignores data} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize flush
+ handle.finalize
+ lappend ::res $args
+ return X
+ }
+ set c [chan push [tempchan] foo]
+ lappend res {*}[inthread $c {
+ # Flush, no writing
+ seek $c 2
+ # The close flushes again, this modifies the file!
+ lappend notes | [close $c] |
+ # NOTE: The flush generated by the close is recorded immediately, the
+ # other note's here are defered until after the thread is done. This
+ # changes the order of the result a bit from the non-threaded case
+ # (The first | moves one to the right). This is an artifact of the
+ # 'inthread' framework, not of the transformation itself.
+ notes
+ } c]
+ lappend res [tempview]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{flush rt*} {flush rt*} | {} | {teXt data}}
+test iortrans.tf-8.2 {close flushes write buffers, writes data} -setup {
+ set res {}
+} -constraints {testchannel thread} -match glob -body {
+ proc foo {args} {
+ handle.initialize flush
+ lappend ::res $args
+ handle.finalize
+ return .flushed.
+ }
+ set c [chan push [tempchan] foo]
+ inthread $c {
+ close $c
+ } c
+ lappend res [tempview]
+} -cleanup {
+ tempdone
+ rename foo {}
+} -result {{flush rt*} {finalize rt*} .flushed.}
+
+# --- === *** ###########################
+# method watch - removed from TIP (rev 1.12+)
+
+# --- === *** ###########################
+# method event - removed from TIP (rev 1.12+)
+
+# --- === *** ###########################
+# 'Pull the rug' tests. Create channel in a thread A, move to other thread B,
+# destroy the origin thread (A) before or during access from B. Must not
+# crash, must return proper errors.
+
+test iortrans.tf-11.0 {origin thread of moved transform gone} -setup {
+ #puts <<$tcltest::mainThread>>main
+ set tida [thread::create -preserved]; #puts <<$tida>>
+ thread::send $tida {load {} Tcltest}
+ set tidb [thread::create -preserved]; #puts <<$tida>>
+ thread::send $tidb {load {} Tcltest}
+} -constraints {testchannel thread} -match glob -body {
+ # Set up channel in thread
+ thread::send $tida $helperscript
+ thread::send $tidb $helperscript
+ set chan [thread::send $tida {
+ proc foo {args} {
+ handle.initialize clear drain flush limit? read write
+ handle.finalize
+ lappend ::res $args
+ return
+ }
+ set chan [chan push [tempchan] foo]
+ fconfigure $chan -buffering none
+ set chan
+ }]
+
+ # Move channel to 2nd thread, transform goes with it.
+ thread::send $tida [list testchannel cut $chan]
+ thread::send $tidb [list testchannel splice $chan]
+
+ # Kill origin thread, then access channel from 2nd thread.
+ thread::release -wait $tida
+
+ set res {}
+ lappend res [catch {thread::send $tidb [list puts $chan shoo]} msg] $msg
+ lappend res [catch {thread::send $tidb [list tell $chan]} msg] $msg
+ lappend res [catch {thread::send $tidb [list seek $chan 1]} msg] $msg
+ lappend res [catch {thread::send $tidb [list gets $chan]} msg] $msg
+ lappend res [catch {thread::send $tidb [list close $chan]} msg] $msg
+ # The 'tell' is ok, as it passed through the transform to the base
+ # channel without invoking the transform handler.
+} -cleanup {
+ thread::send $tidb tempdone
+ thread::release $tidb
+} -result {1 {Owner lost} 0 0 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}}
+
+testConstraint notValgrind [expr {![testConstraint valgrind]}]
+
+test iortrans.tf-11.1 {origin thread of moved transform destroyed during access} -setup {
+ #puts <<$tcltest::mainThread>>main
+ set tida [thread::create -preserved]; #puts <<$tida>>
+ thread::send $tida {load {} Tcltest}
+ set tidb [thread::create -preserved]; #puts <<$tidb>>
+ thread::send $tidb {load {} Tcltest}
+} -constraints {testchannel thread notValgrind} -match glob -body {
+ # Set up channel in thread
+ thread::send $tida $helperscript
+ thread::send $tidb $helperscript
+ set chan [thread::send $tida {
+ proc foo {args} {
+ handle.initialize clear drain flush limit? read write
+ handle.finalize
+ lappend ::res $args
+ # destroy thread during channel access
+ thread::exit
+ }
+ set chan [chan push [tempchan] foo]
+ fconfigure $chan -buffering none
+ set chan
+ }]
+
+ # Move channel to 2nd thread, transform goes with it.
+ thread::send $tida [list testchannel cut $chan]
+ thread::send $tidb [list testchannel splice $chan]
+
+ # Run access from thread B, wait for response from A (A is not using event
+ # loop at this point, so the event pile up in the queue.
+ thread::send $tidb [list set chan $chan]
+ thread::send $tidb [list set mid [thread::id]]
+ thread::send -async $tidb {
+ # Wait a bit, give the main thread the time to start its event loop to
+ # wait for the response from B
+ after 50
+ catch { puts $chan shoo } res
+ catch { close $chan }
+ thread::send -async $mid [list set ::res $res]
+ }
+ vwait ::res
+ set res
+} -cleanup {
+ thread::send $tidb tempdone
+ thread::release $tidb
+} -result {Owner lost}
+
+# ### ### ### ######### ######### #########
+
+cleanupTests
+return
diff --git a/pkgs/msgcat/tests/iogt.test b/pkgs/msgcat/tests/iogt.test
new file mode 100644
index 0000000..60d7ab8
--- /dev/null
+++ b/pkgs/msgcat/tests/iogt.test
@@ -0,0 +1,802 @@
+# -*- tcl -*-
+# Commands covered: transform, and stacking in general
+#
+# This file contains a collection of tests for Giot
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# Copyright (c) 2000 Ajuba Solutions.
+# Copyright (c) 2000 Andreas Kupries.
+# All rights reserved.
+
+if {[catch {package require tcltest 2.1}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2.1 required."
+ return
+}
+namespace eval ::tcl::test::iogt {
+ namespace import ::tcltest::*
+
+testConstraint testchannel [llength [info commands testchannel]]
+
+set path(dummy) [makeFile {abcdefghijklmnopqrstuvwxyz0123456789,./?><;'\|":[]\}\{`~!@#$%^&*()_+-=
+} dummy]
+
+# " capture coloring of quotes
+
+set path(dummyout) [makeFile {} dummyout]
+
+set path(__echo_srv__.tcl) [makeFile {
+#!/usr/local/bin/tclsh
+# -*- tcl -*-
+# echo server
+#
+# arguments, options: port to listen on for connections.
+# delay till echo of first block
+# delay between blocks
+# blocksize ...
+
+set port [lindex $argv 0]
+set fdelay [lindex $argv 1]
+set idelay [lindex $argv 2]
+set bsizes [lrange $argv 3 end]
+set c 0
+
+proc newconn {sock rhost rport} {
+ variable fdelay
+ variable c
+ incr c
+ namespace upvar [namespace current] c$c conn
+
+ #puts stdout "C $sock $rhost $rport / $fdelay" ; flush stdout
+
+ set conn(after) {}
+ set conn(state) 0
+ set conn(size) 0
+ set conn(data) ""
+ set conn(delay) $fdelay
+
+ fileevent $sock readable [list echoGet $c $sock]
+ fconfigure $sock -translation binary -buffering none -blocking 0
+}
+
+proc echoGet {c sock} {
+ variable fdelay
+ namespace upvar [namespace current] c$c conn
+
+ if {[eof $sock]} {
+ # one-shot echo
+ exit
+ }
+ append conn(data) [read $sock]
+
+ #puts stdout "G $c $sock $conn(data) <<$conn(data)>>" ; flush stdout
+
+ if {$conn(after) == {}} {
+ set conn(after) [after $conn(delay) [list echoPut $c $sock]]
+ }
+}
+
+proc echoPut {c sock} {
+ variable idelay
+ variable fdelay
+ variable bsizes
+ namespace upvar [namespace current] c$c conn
+
+ if {[string length $conn(data)] == 0} {
+ #puts stdout "C $c $sock" ; flush stdout
+ # auto terminate
+ close $sock
+ exit
+ #set conn(delay) $fdelay
+ return
+ }
+
+ set conn(delay) $idelay
+ set n [lindex $bsizes $conn(size)]
+
+ #puts stdout "P $c $sock $n >>" ; flush stdout
+
+ #puts __________________________________________
+ #parray conn
+ #puts n=<$n>
+
+ if {[string length $conn(data)] >= $n} {
+ puts -nonewline $sock [string range $conn(data) 0 $n]
+ set conn(data) [string range $conn(data) [incr n] end]
+ }
+
+ incr conn(size)
+ if {$conn(size) >= [llength $bsizes]} {
+ set conn(size) [expr {[llength $bsizes]-1}]
+ }
+
+ set conn(after) [after $conn(delay) [list echoPut $c $sock]]
+}
+
+#fileevent stdin readable {exit ;#cut}
+
+# main
+socket -server newconn -myaddr 127.0.0.1 $port
+vwait forever
+} __echo_srv__.tcl]
+
+########################################################################
+
+proc fevent {fdelay idelay blocks script data} {
+ # Start and initialize an echo server, prepare data transmission, then
+ # hand over to the test script. This has to start real transmission via
+ # 'flush'. The server is stopped after completion of the test.
+
+ upvar 1 sock sk
+
+ # Fixed port, not so good. Lets hope for the best, for now.
+ set port 4000
+
+ exec tclsh __echo_srv__.tcl $port $fdelay $idelay {*}$blocks >@stdout &
+ after 500
+
+ #puts stdout "> $port"; flush stdout
+
+ set sk [socket localhost $port]
+ fconfigure $sk -blocking 0 -buffering full \
+ -buffersize [expr {10+[llength $data]}]
+ puts -nonewline $sk $data
+
+ # The channel is prepared to go off.
+
+ #puts stdout ">>>>>"; flush stdout
+
+ set res [uplevel 1 $script]
+ catch {close $sk}
+ return $res
+}
+
+# --------------------------------------------------------------
+# utility transformations ...
+
+proc id {op data} {
+ switch -- $op {
+ create/write - create/read - delete/write - delete/read - clear_read {
+ #ignore
+ }
+ flush/write - flush/read - write - read {
+ return $data
+ }
+ query/maxRead {
+ return -1
+ }
+ }
+}
+
+proc id_optrail {var op data} {
+ variable $var
+ upvar 0 $var trail
+
+ lappend trail $op
+ switch -- $op {
+ create/write - create/read - delete/write - delete/read -
+ flush/read - clear/read {
+ #ignore
+ }
+ flush/write - write - read {
+ return $data
+ }
+ query/maxRead {
+ return -1
+ }
+ default {
+ lappend trail "error $op"
+ error $op
+ }
+ }
+}
+
+proc id_fulltrail {var op data} {
+ namespace upvar [namespace current] $var trail
+
+ #puts stdout ">> $var $op $data" ; flush stdout
+
+ switch -- $op {
+ create/write - create/read - delete/write - delete/read - clear_read {
+ set res *ignored*
+ }
+ flush/write - flush/read - write - read {
+ set res $data
+ }
+ query/maxRead {
+ set res -1
+ }
+ }
+
+ #catch {puts stdout "\t>* $res" ; flush stdout}
+ #catch {puts stdout "x$res"} msg
+
+ lappend trail [list $op $data $res]
+ return $res
+}
+
+proc counter {var op data} {
+ namespace upvar [namespace current] $var n
+
+ switch -- $op {
+ create/write - create/read - delete/write - delete/read - clear_read {
+ #ignore
+ }
+ flush/write - flush/read {
+ return {}
+ }
+ write {
+ return $data
+ }
+ read {
+ if {$n > 0} {
+ incr n -[string length $data]
+ if {$n < 0} {
+ set n 0
+ }
+ }
+ return $data
+ }
+ query/maxRead {
+ return $n
+ }
+ }
+}
+
+proc counter_audit {var vtrail op data} {
+ namespace upvar [namespace current] $var n $vtrail trail
+
+ switch -- $op {
+ create/write - create/read - delete/write - delete/read - clear_read {
+ set res {}
+ }
+ flush/write - flush/read {
+ set res {}
+ }
+ write {
+ set res $data
+ }
+ read {
+ if {$n > 0} {
+ incr n -[string length $data]
+ if {$n < 0} {
+ set n 0
+ }
+ }
+ set res $data
+ }
+ query/maxRead {
+ set res $n
+ }
+ }
+
+ lappend trail [list counter:$op $data $res]
+ return $res
+}
+
+proc rblocks {var vtrail n op data} {
+ namespace upvar [namespace current] $var n $vtrail trail
+
+ set res {}
+
+ switch -- $op {
+ create/write - create/read - delete/write - delete/read - clear_read {
+ set buf {}
+ }
+ flush/write {
+ }
+ flush/read {
+ set res $buf
+ set buf {}
+ }
+ write {
+ set data
+ }
+ read {
+ append buf $data
+ set b [expr {$n * ([string length $buf] / $n)}]
+ append op " $n [string length $buf] :- $b"
+ set res [string range $buf 0 [incr b -1]]
+ set buf [string range $buf [incr b] end]
+ #return $res
+ }
+ query/maxRead {
+ set res -1
+ }
+ }
+
+ lappend trail [list rblock | $op $data $res | $buf]
+ return $res
+}
+
+# --------------------------------------------------------------
+# ... and convenience procedures to stack them
+
+proc identity {-attach channel} {
+ testchannel transform $channel -command [namespace code id]
+}
+proc audit_ops {var -attach channel} {
+ testchannel transform $channel -command [namespace code [list id_optrail $var]]
+}
+proc audit_flow {var -attach channel} {
+ testchannel transform $channel -command [namespace code [list id_fulltrail $var]]
+}
+proc stopafter {var n -attach channel} {
+ namespace upvar [namespace current] $var vn
+ set vn $n
+ testchannel transform $channel -command [namespace code [list counter $var]]
+}
+proc stopafter_audit {var trail n -attach channel} {
+ namespace upvar [namespace current] $var vn
+ set vn $n
+ testchannel transform $channel -command [namespace code [list counter_audit $var $trail]]
+}
+proc rblocks_t {var trail n -attach channel} {
+ testchannel transform $channel -command [namespace code [list rblocks $var $trail $n]]
+}
+
+# --------------------------------------------------------------
+# serialize an array, with keys in sorted order.
+
+proc array_sget {v} {
+ upvar $v a
+ set res [list]
+ foreach n [lsort [array names a]] {
+ lappend res $n $a($n)
+ }
+ set res
+}
+proc asort {alist} {
+ # sort a list of key/value pairs by key, removes duplicates too.
+ array set a $alist
+ array_sget a
+}
+
+########################################################################
+
+test iogt-1.1 {stack/unstack} testchannel {
+ set fh [open $path(dummy) r]
+ identity -attach $fh
+ testchannel unstack $fh
+ close $fh
+} {}
+test iogt-1.2 {stack/close} testchannel {
+ set fh [open $path(dummy) r]
+ identity -attach $fh
+ close $fh
+} {}
+test iogt-1.3 {stack/unstack, configuration, options} testchannel {
+ set fh [open $path(dummy) r]
+ set ca [asort [fconfigure $fh]]
+ identity -attach $fh
+ set cb [asort [fconfigure $fh]]
+ testchannel unstack $fh
+ set cc [asort [fconfigure $fh]]
+ close $fh
+ # With this system none of the buffering, translation and encoding option
+ # may change their values with channels stacked upon each other or not.
+ # cb == ca == cc
+ list [string equal $ca $cb] [string equal $cb $cc] [string equal $ca $cc]
+} {1 1 1}
+test iogt-1.4 {stack/unstack, configuration} -setup {
+ set fh [open $path(dummy) r]
+} -constraints testchannel -body {
+ set ca [asort [fconfigure $fh]]
+ identity -attach $fh
+ fconfigure $fh -buffering line -translation cr -encoding shiftjis
+ testchannel unstack $fh
+ set cc [asort [fconfigure $fh]]
+ list [string equal $ca $cc] [fconfigure $fh -buffering] \
+ [fconfigure $fh -translation] [fconfigure $fh -encoding]
+} -cleanup {
+ close $fh
+} -result {0 line cr shiftjis}
+
+test iogt-2.0 {basic I/O going through transform} -setup {
+ set fin [open $path(dummy) r]
+ set fout [open $path(dummyout) w]
+} -constraints testchannel -body {
+ identity -attach $fin
+ identity -attach $fout
+ fcopy $fin $fout
+ close $fin
+ close $fout
+ set fin [open $path(dummy) r]
+ set fout [open $path(dummyout) r]
+ list [string equal [set in [read $fin]] [set out [read $fout]]] \
+ [string length $in] [string length $out]
+} -cleanup {
+ close $fin
+ close $fout
+} -result {1 71 71}
+test iogt-2.1 {basic I/O, operation trail} {testchannel unix} {
+ set fin [open $path(dummy) r]
+ set fout [open $path(dummyout) w]
+ set ain [list]; set aout [list]
+ audit_ops ain -attach $fin
+ audit_ops aout -attach $fout
+ fconfigure $fin -buffersize 10
+ fconfigure $fout -buffersize 10
+ fcopy $fin $fout
+ close $fin
+ close $fout
+ set res "[join $ain \n]\n--------\n[join $aout \n]"
+} {create/read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+flush/read
+delete/read
+--------
+create/write
+write
+write
+write
+write
+write
+write
+write
+write
+flush/write
+delete/write}
+test iogt-2.2 {basic I/O, data trail} {testchannel unix} {
+ set fin [open $path(dummy) r]
+ set fout [open $path(dummyout) w]
+ set ain [list]; set aout [list]
+ audit_flow ain -attach $fin
+ audit_flow aout -attach $fout
+ fconfigure $fin -buffersize 10
+ fconfigure $fout -buffersize 10
+ fcopy $fin $fout
+ close $fin
+ close $fout
+ set res "[join $ain \n]\n--------\n[join $aout \n]"
+} {create/read {} *ignored*
+query/maxRead {} -1
+read abcdefghij abcdefghij
+query/maxRead {} -1
+read klmnopqrst klmnopqrst
+query/maxRead {} -1
+read uvwxyz0123 uvwxyz0123
+query/maxRead {} -1
+read 456789,./? 456789,./?
+query/maxRead {} -1
+read {><;'\|":[]} {><;'\|":[]}
+query/maxRead {} -1
+read {\}\{`~!@#$} {\}\{`~!@#$}
+query/maxRead {} -1
+read %^&*()_+-= %^&*()_+-=
+query/maxRead {} -1
+read {
+} {
+}
+query/maxRead {} -1
+flush/read {} {}
+delete/read {} *ignored*
+--------
+create/write {} *ignored*
+write abcdefghij abcdefghij
+write klmnopqrst klmnopqrst
+write uvwxyz0123 uvwxyz0123
+write 456789,./? 456789,./?
+write {><;'\|":[]} {><;'\|":[]}
+write {\}\{`~!@#$} {\}\{`~!@#$}
+write %^&*()_+-= %^&*()_+-=
+write {
+} {
+}
+flush/write {} {}
+delete/write {} *ignored*}
+test iogt-2.3 {basic I/O, mixed trail} {testchannel unix} {
+ set fin [open $path(dummy) r]
+ set fout [open $path(dummyout) w]
+ set trail [list]
+ audit_flow trail -attach $fin
+ audit_flow trail -attach $fout
+ fconfigure $fin -buffersize 20
+ fconfigure $fout -buffersize 10
+ fcopy $fin $fout
+ close $fin
+ close $fout
+ join $trail \n
+} {create/read {} *ignored*
+create/write {} *ignored*
+query/maxRead {} -1
+read abcdefghijklmnopqrst abcdefghijklmnopqrst
+write abcdefghij abcdefghij
+write klmnopqrst klmnopqrst
+query/maxRead {} -1
+read uvwxyz0123456789,./? uvwxyz0123456789,./?
+write uvwxyz0123 uvwxyz0123
+write 456789,./? 456789,./?
+query/maxRead {} -1
+read {><;'\|":[]\}\{`~!@#$} {><;'\|":[]\}\{`~!@#$}
+write {><;'\|":[]} {><;'\|":[]}
+write {\}\{`~!@#$} {\}\{`~!@#$}
+query/maxRead {} -1
+read {%^&*()_+-=
+} {%^&*()_+-=
+}
+query/maxRead {} -1
+flush/read {} {}
+write %^&*()_+-= %^&*()_+-=
+write {
+} {
+}
+delete/read {} *ignored*
+flush/write {} {}
+delete/write {} *ignored*}
+
+test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} -setup {
+ proc DoneCopy {n {err {}}} {
+ variable copy 1
+ }
+} -constraints {testchannel hangs} -body {
+ # This test to check the validity of aquired Tcl_Channel references is not
+ # possible because even a backgrounded fcopy will immediately start to
+ # copy data, without waiting for the event loop. This is done only in case
+ # of an underflow on the read size!. So stacking transforms after the
+ # fcopy will miss information, or are not used at all.
+ #
+ # I was able to circumvent this by using the echo.tcl server with a big
+ # delay, causing the fcopy to underflow immediately.
+ set fin [open $path(dummy) r]
+ fevent 1000 500 {20 20 20 10 1 1} {
+ close $fin
+ set fout [open dummyout w]
+ flush $sock; # now, or fcopy will error us out
+ # But the 1 second delay should be enough to initialize everything
+ # else here.
+ fcopy $sock $fout -command [namespace code DoneCopy]
+ # Transform after fcopy got its handles! They should be still valid
+ # for fcopy.
+ set trail [list]
+ audit_ops trail -attach $fout
+ vwait [namespace which -variable copy]
+ } [read $fin]; # {}
+ close $fout
+ # Check result of copy.
+ set fin [open $path(dummy) r]
+ set fout [open $path(dummyout) r]
+ set res [string equal [read $fin] [read $fout]]
+ close $fin
+ close $fout
+ list $res $trail
+} -cleanup {
+ rename DoneCopy {}
+} -result {1 {create/write create/read write flush/write flush/read delete/write delete/read}}
+
+test iogt-4.0 {fileevent readable, after transform} -setup {
+ set fin [open $path(dummy) r]
+ set data [read $fin]
+ close $fin
+ set trail [list]
+ set got [list]
+ proc Done {args} {
+ variable stop 1
+ }
+} -constraints {testchannel hangs} -body {
+ fevent 1000 500 {20 20 20 10 1} {
+ audit_flow trail -attach $sock
+ rblocks_t rbuf trail 23 -attach $sock
+ fileevent $sock readable [namespace code {
+ if {[eof $sock]} {
+ Done
+ lappend trail "xxxxxxxxxxxxx"
+ close $sock
+ } else {
+ lappend trail "vvvvvvvvvvvvv"
+ lappend trail "\tgot: [lappend got "\[\[[read $sock]\]\]"]"
+ lappend trail "============="
+ #puts stdout $__; flush stdout
+ #read $sock
+ }
+ }]
+ flush $sock; # Now, or fcopy will error us out
+ # But the 1 second delay should be enough to initialize everything
+ # else here.
+ vwait [namespace which -variable stop]
+ } $data
+ join [list [join $got \n] ~~~~~~~~ [join $trail \n]] \n
+} -cleanup {
+ rename Done {}
+} -result {[[]]
+[[abcdefghijklmnopqrstuvw]]
+[[xyz0123456789,./?><;'\|]]
+[[]]
+[[]]
+[[":[]\}\{`~!@#$%^&*()]]
+[[]]
+~~~~~~~~
+create/write {} *ignored*
+create/read {} *ignored*
+rblock | create/write {} {} | {}
+rblock | create/read {} {} | {}
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | {}
+query/maxRead {} -1
+read abcdefghijklmnopqrstu abcdefghijklmnopqrstu
+query/maxRead {} -1
+rblock | {read 23 21 :- 0} abcdefghijklmnopqrstu {} | abcdefghijklmnopqrstu
+rblock | query/maxRead {} -1 | abcdefghijklmnopqrstu
+query/maxRead {} -1
+ got: {[[]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | abcdefghijklmnopqrstu
+query/maxRead {} -1
+read vwxyz0123456789,./?>< vwxyz0123456789,./?><
+query/maxRead {} -1
+rblock | {read 23 42 :- 23} vwxyz0123456789,./?>< abcdefghijklmnopqrstuvw | xyz0123456789,./?><
+rblock | query/maxRead {} -1 | xyz0123456789,./?><
+query/maxRead {} -1
+ got: {[[]]} {[[abcdefghijklmnopqrstuvw]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | xyz0123456789,./?><
+query/maxRead {} -1
+read {;'\|":[]\}\{`~!@#$%^&} {;'\|":[]\}\{`~!@#$%^&}
+query/maxRead {} -1
+rblock | {read 23 40 :- 23} {;'\|":[]\}\{`~!@#$%^&} {xyz0123456789,./?><;'\|} | {":[]\}\{`~!@#$%^&}
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&}
+query/maxRead {} -1
+ got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&}
+query/maxRead {} -1
+read *( *(
+query/maxRead {} -1
+rblock | {read 23 19 :- 0} *( {} | {":[]\}\{`~!@#$%^&*(}
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*(}
+query/maxRead {} -1
+ got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*(}
+query/maxRead {} -1
+read ) )
+query/maxRead {} -1
+rblock | {read 23 20 :- 0} ) {} | {":[]\}\{`~!@#$%^&*()}
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*()}
+query/maxRead {} -1
+ got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]} {[[]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*()}
+query/maxRead {} -1
+flush/read {} {}
+rblock | flush/read {} {":[]\}\{`~!@#$%^&*()} | {}
+rblock | query/maxRead {} -1 | {}
+query/maxRead {} -1
+ got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]} {[[]]} {[[":[]\}\{`~!@#$%^&*()]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | {}
+query/maxRead {} -1
+ got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]} {[[]]} {[[":[]\}\{`~!@#$%^&*()]]} {[[]]}
+xxxxxxxxxxxxx
+rblock | flush/write {} {} | {}
+rblock | delete/write {} {} | {}
+rblock | delete/read {} {} | {}
+flush/write {} {}
+delete/write {} *ignored*
+delete/read {} *ignored*}; # catch unescaped quote "
+
+test iogt-5.0 {EOF simulation} -setup {
+ set fin [open $path(dummy) r]
+ set fout [open $path(dummyout) w]
+ set trail [list]
+} -constraints {testchannel unknownFailure} -result {
+ audit_flow trail -attach $fin
+ stopafter_audit d trail 20 -attach $fin
+ audit_flow trail -attach $fout
+ fconfigure $fin -buffersize 20
+ fconfigure $fout -buffersize 10
+ fcopy $fin $fout
+ testchannel unstack $fin
+ # now copy the rest in the channel
+ lappend trail {**after unstack**}
+ fcopy $fin $fout
+ close $fin
+ close $fout
+ join $trail \n
+} -result {create/read {} *ignored*
+counter:create/read {} {}
+create/write {} *ignored*
+counter:query/maxRead {} 20
+query/maxRead {} -1
+read {abcdefghijklmnopqrstuvwxyz0123456789,./?><;'\|":[]\}\{`~!@#$%^&*()_+-=
+} {abcdefghijklmnopqrstuvwxyz0123456789,./?><;'\|":[]\}\{`~!@#$%^&*()_+-=
+}
+query/maxRead {} -1
+flush/read {} {}
+counter:read abcdefghijklmnopqrst abcdefghijklmnopqrst
+write abcdefghij abcdefghij
+write klmnopqrst klmnopqrst
+counter:query/maxRead {} 0
+counter:flush/read {} {}
+counter:delete/read {} {}
+**after unstack**
+query/maxRead {} -1
+write uvwxyz0123 uvwxyz0123
+write 456789,./? 456789,./?
+write {><;'\|":[]} {><;'\|":[]}
+write {\}\{`~!@#$} {\}\{`~!@#$}
+write %^&*()_+-= %^&*()_+-=
+write {
+} {
+}
+query/maxRead {} -1
+delete/read {} *ignored*
+flush/write {} {}
+delete/write {} *ignored*}
+
+proc constX {op data} {
+ # replace anything coming in with a same-length string of x'es.
+ switch -- $op {
+ create/write - create/read - delete/write - delete/read - clear_read {
+ #ignore
+ }
+ flush/write - flush/read - write - read {
+ return [string repeat x [string length $data]]
+ }
+ query/maxRead {
+ return -1
+ }
+ }
+}
+proc constx {-attach channel} {
+ testchannel transform $channel -command [namespace code constX]
+}
+
+test iogt-6.0 {Push back} -constraints testchannel -body {
+ set f [open $path(dummy) r]
+ # contents of dummy = "abcdefghi..."
+ read $f 3; # skip behind "abc"
+ constx -attach $f
+ # expect to get "xxx" from the transform because of unread "def" input to
+ # transform which returns "xxx".
+ #
+ # Actually the IO layer pre-read the whole file and will read "def"
+ # directly from the buffer without bothering to consult the newly stacked
+ # transformation. This is wrong.
+ read $f 3
+} -cleanup {
+ close $f
+} -result {xxx}
+test iogt-6.1 {Push back and up} -constraints {testchannel knownBug} -body {
+ set f [open $path(dummy) r]
+ # contents of dummy = "abcdefghi..."
+ read $f 3; # skip behind "abc"
+ constx -attach $f
+ set res [read $f 3]
+ testchannel unstack $f
+ append res [read $f 3]
+} -cleanup {
+ close $f
+} -result {xxxghi}
+
+# cleanup
+foreach file [list dummy dummyout __echo_srv__.tcl] {
+ removeFile $file
+}
+cleanupTests
+}
+namespace delete ::tcl::test::iogt
+return
diff --git a/pkgs/msgcat/tests/join.test b/pkgs/msgcat/tests/join.test
new file mode 100644
index 0000000..4abe233
--- /dev/null
+++ b/pkgs/msgcat/tests/join.test
@@ -0,0 +1,55 @@
+# Commands covered: join
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test join-1.1 {basic join commands} {
+ join {a b c} xyz
+} axyzbxyzc
+test join-1.2 {basic join commands} {
+ join {a b c} {}
+} abc
+test join-1.3 {basic join commands} {
+ join {} xyz
+} {}
+test join-1.4 {basic join commands} {
+ join {12 34 56}
+} {12 34 56}
+
+test join-2.1 {join errors} {
+ list [catch join msg] $msg $errorCode
+} {1 {wrong # args: should be "join list ?joinString?"} {TCL WRONGARGS}}
+test join-2.2 {join errors} {
+ list [catch {join a b c} msg] $msg $errorCode
+} {1 {wrong # args: should be "join list ?joinString?"} {TCL WRONGARGS}}
+test join-2.3 {join errors} {
+ list [catch {join "a \{ c" 111} msg] $msg $errorCode
+} {1 {unmatched open brace in list} {TCL VALUE LIST BRACE}}
+
+test join-3.1 {joinString is binary ok} {
+ string length [join {a b c} a\0b]
+} 9
+test join-3.2 {join is binary ok} {
+ string length [join "a\0b a\0b a\0b"]
+} 11
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/lindex.test b/pkgs/msgcat/tests/lindex.test
new file mode 100644
index 0000000..07abff8
--- /dev/null
+++ b/pkgs/msgcat/tests/lindex.test
@@ -0,0 +1,455 @@
+# Commands covered: lindex
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2001 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2.2
+ namespace import -force ::tcltest::*
+}
+
+set minus -
+testConstraint testevalex [llength [info commands testevalex]]
+
+# Tests of Tcl_LindexObjCmd, NOT COMPILED
+
+test lindex-1.1 {wrong # args} testevalex {
+ list [catch {testevalex lindex} result] $result
+} "1 {wrong # args: should be \"lindex list ?index ...?\"}"
+
+# Indices that are lists or convertible to lists
+
+test lindex-2.1 {empty index list} testevalex {
+ set x {}
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {{a b c} {a b c}}
+test lindex-2.2 {singleton index list} testevalex {
+ set x { 1 }
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {b b}
+test lindex-2.3 {multiple indices in list} testevalex {
+ set x {1 2}
+ list [testevalex {lindex {{a b c} {d e f}} $x}] \
+ [testevalex {lindex {{a b c} {d e f}} $x}]
+} {f f}
+test lindex-2.4 {malformed index list} testevalex {
+ set x \{
+ list [catch { testevalex {lindex {a b c} $x} } result] $result
+} {1 bad\ index\ \"\{\":\ must\ be\ integer?\[+-\]integer?\ or\ end?\[+-\]integer?}
+
+# Indices that are integers or convertible to integers
+
+test lindex-3.1 {integer -1} testevalex {
+ set x ${minus}1
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {{} {}}
+test lindex-3.2 {integer 0} testevalex {
+ set x [string range 00 0 0]
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {a a}
+test lindex-3.3 {integer 2} testevalex {
+ set x [string range 22 0 0]
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {c c}
+test lindex-3.4 {integer 3} testevalex {
+ set x [string range 33 0 0]
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {{} {}}
+test lindex-3.5 {bad octal} -constraints testevalex -body {
+ set x 0o8
+ list [catch { testevalex {lindex {a b c} $x} } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-3.6 {bad octal} -constraints testevalex -body {
+ set x -0o9
+ list [catch { testevalex {lindex {a b c} $x} } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-3.7 {indexes don't shimmer wide ints} {
+ set x [expr {(wide(1)<<31) - 2}]
+ list $x [lindex {1 2 3} $x] [incr x] [incr x]
+} {2147483646 {} 2147483647 2147483648}
+
+# Indices relative to end
+
+test lindex-4.1 {index = end} testevalex {
+ set x end
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {c c}
+test lindex-4.2 {index = end--1} testevalex {
+ set x end--1
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {{} {}}
+test lindex-4.3 {index = end-0} testevalex {
+ set x end-0
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {c c}
+test lindex-4.4 {index = end-2} testevalex {
+ set x end-2
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {a a}
+test lindex-4.5 {index = end-3} testevalex {
+ set x end-3
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {{} {}}
+test lindex-4.6 {bad octal} -constraints testevalex -body {
+ set x end-0o8
+ list [catch { testevalex {lindex {a b c} $x} } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-4.7 {bad octal} -constraints testevalex -body {
+ set x end--0o9
+ list [catch { testevalex {lindex {a b c} $x} } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-4.8 {bad integer, not octal} testevalex {
+ set x end-0a2
+ list [catch { testevalex {lindex {a b c} $x} } result] $result
+} {1 {bad index "end-0a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lindex-4.9 {obsolete test} testevalex {
+ set x end
+ list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {c c}
+test lindex-4.10 {incomplete end-} testevalex {
+ set x end-
+ list [catch { testevalex {lindex {a b c} $x} } result] $result
+} {1 {bad index "end-": must be integer?[+-]integer? or end?[+-]integer?}}
+
+test lindex-5.1 {bad second index} testevalex {
+ list [catch { testevalex {lindex {a b c} 0 0a2} } result] $result
+} {1 {bad index "0a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lindex-5.2 {good second index} testevalex {
+ testevalex {lindex {{a b c} {d e f} {g h i}} 1 2}
+} f
+test lindex-5.3 {three indices} testevalex {
+ testevalex {lindex {{{a b} {c d}} {{e f} {g h}}} 1 0 1}
+} f
+
+test lindex-6.1 {error conditions in parsing list} testevalex {
+ list [catch {testevalex {lindex "a \{" 2}} msg] $msg
+} {1 {unmatched open brace in list}}
+test lindex-6.2 {error conditions in parsing list} testevalex {
+ list [catch {testevalex {lindex {a {b c}d e} 2}} msg] $msg
+} {1 {list element in braces followed by "d" instead of space}}
+test lindex-6.3 {error conditions in parsing list} testevalex {
+ list [catch {testevalex {lindex {a "b c"def ghi} 2}} msg] $msg
+} {1 {list element in quotes followed by "def" instead of space}}
+
+test lindex-7.1 {quoted elements} testevalex {
+ testevalex {lindex {a "b c" d} 1}
+} {b c}
+test lindex-7.2 {quoted elements} testevalex {
+ testevalex {lindex {"{}" b c} 0}
+} {{}}
+test lindex-7.3 {quoted elements} testevalex {
+ testevalex {lindex {ab "c d \" x" y} 1}
+} {c d " x}
+test lindex-7.4 {quoted elements} {
+ lindex {a b {c d "e} {f g"}} 2
+} {c d "e}
+
+test lindex-8.1 {data reuse} testevalex {
+ set x 0
+ testevalex {lindex $x $x}
+} {0}
+test lindex-8.2 {data reuse} testevalex {
+ set a 0
+ testevalex {lindex $a $a $a}
+} 0
+test lindex-8.3 {data reuse} testevalex {
+ set a 1
+ testevalex {lindex $a $a $a}
+} {}
+test lindex-8.4 {data reuse} testevalex {
+ set x [list 0 0]
+ testevalex {lindex $x $x}
+} {0}
+test lindex-8.5 {data reuse} testevalex {
+ set x 0
+ testevalex {lindex $x [list $x $x]}
+} {0}
+test lindex-8.6 {data reuse} testevalex {
+ set x [list 1 1]
+ testevalex {lindex $x $x}
+} {}
+test lindex-8.7 {data reuse} testevalex {
+ set x 1
+ testevalex {lindex $x [list $x $x]}
+} {}
+
+#----------------------------------------------------------------------
+
+# Compilation tests for lindex
+
+test lindex-9.1 {wrong # args} {
+ list [catch {lindex} result] $result
+} "1 {wrong # args: should be \"lindex list ?index ...?\"}"
+test lindex-9.2 {ensure that compilation works in the right order} {
+ proc foo {} {
+ rename foo {}
+ lindex 1 0
+ }
+ foo
+} 1
+
+# Indices that are lists or convertible to lists
+
+test lindex-10.1 {empty index list} {
+ set x {}
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {{a b c} {a b c}}
+test lindex-10.2 {singleton index list} {
+ set x { 1 }
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {b b}
+test lindex-10.3 {multiple indices in list} {
+ set x {1 2}
+ catch {
+ list [lindex {{a b c} {d e f}} $x] [lindex {{a b c} {d e f}} $x]
+ } result
+ set result
+} {f f}
+test lindex-10.4 {malformed index list} {
+ set x \{
+ list [catch { lindex {a b c} $x } result] $result
+} {1 bad\ index\ \"\{\":\ must\ be\ integer?\[+-\]integer?\ or\ end?\[+-\]integer?}
+
+# Indices that are integers or convertible to integers
+
+test lindex-11.1 {integer -1} {
+ set x ${minus}1
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {{} {}}
+test lindex-11.2 {integer 0} {
+ set x [string range 00 0 0]
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {a a}
+test lindex-11.3 {integer 2} {
+ set x [string range 22 0 0]
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {c c}
+test lindex-11.4 {integer 3} {
+ set x [string range 33 0 0]
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {{} {}}
+test lindex-11.5 {bad octal} -body {
+ set x 0o8
+ list [catch { lindex {a b c} $x } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-11.6 {bad octal} -body {
+ set x -0o9
+ list [catch { lindex {a b c} $x } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+
+# Indices relative to end
+
+test lindex-12.1 {index = end} {
+ set x end
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {c c}
+test lindex-12.2 {index = end--1} {
+ set x end--1
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {{} {}}
+test lindex-12.3 {index = end-0} {
+ set x end-0
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {c c}
+test lindex-12.4 {index = end-2} {
+ set x end-2
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {a a}
+test lindex-12.5 {index = end-3} {
+ set x end-3
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {{} {}}
+test lindex-12.6 {bad octal} -body {
+ set x end-0o8
+ list [catch { lindex {a b c} $x } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-12.7 {bad octal} -body {
+ set x end--0o9
+ list [catch { lindex {a b c} $x } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-12.8 {bad integer, not octal} {
+ set x end-0a2
+ list [catch { lindex {a b c} $x } result] $result
+} {1 {bad index "end-0a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lindex-12.9 {obsolete test} {
+ set x end
+ catch {
+ list [lindex {a b c} $x] [lindex {a b c} $x]
+ } result
+ set result
+} {c c}
+test lindex-12.10 {incomplete end-} {
+ set x end-
+ list [catch { lindex {a b c} $x } result] $result
+} {1 {bad index "end-": must be integer?[+-]integer? or end?[+-]integer?}}
+
+test lindex-13.1 {bad second index} {
+ list [catch { lindex {a b c} 0 0a2 } result] $result
+} {1 {bad index "0a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lindex-13.2 {good second index} {
+ catch {
+ lindex {{a b c} {d e f} {g h i}} 1 2
+ } result
+ set result
+} f
+test lindex-13.3 {three indices} {
+ catch {
+ lindex {{{a b} {c d}} {{e f} {g h}}} 1 0 1
+ } result
+ set result
+} f
+
+test lindex-14.1 {error conditions in parsing list} {
+ list [catch { lindex "a \{" 2 } msg] $msg
+} {1 {unmatched open brace in list}}
+test lindex-14.2 {error conditions in parsing list} {
+ list [catch { lindex {a {b c}d e} 2 } msg] $msg
+} {1 {list element in braces followed by "d" instead of space}}
+test lindex-14.3 {error conditions in parsing list} {
+ list [catch { lindex {a "b c"def ghi} 2 } msg] $msg
+} {1 {list element in quotes followed by "def" instead of space}}
+
+test lindex-15.1 {quoted elements} {
+ catch {
+ lindex {a "b c" d} 1
+ } result
+ set result
+} {b c}
+test lindex-15.2 {quoted elements} {
+ catch {
+ lindex {"{}" b c} 0
+ } result
+ set result
+} {{}}
+test lindex-15.3 {quoted elements} {
+ catch {
+ lindex {ab "c d \" x" y} 1
+ } result
+ set result
+} {c d " x}
+test lindex-15.4 {quoted elements} {
+ catch {
+ lindex {a b {c d "e} {f g"}} 2
+ } result
+ set result
+} {c d "e}
+
+test lindex-16.1 {data reuse} {
+ set x 0
+ catch {
+ lindex $x $x
+ } result
+ set result
+} {0}
+test lindex-16.2 {data reuse} {
+ set a 0
+ catch {
+ lindex $a $a $a
+ } result
+ set result
+} 0
+test lindex-16.3 {data reuse} {
+ set a 1
+ catch {
+ lindex $a $a $a
+ } result
+ set result
+} {}
+test lindex-16.4 {data reuse} {
+ set x [list 0 0]
+ catch {
+ lindex $x $x
+ } result
+ set result
+} {0}
+test lindex-16.5 {data reuse} {
+ set x 0
+ catch {
+ lindex $x [list $x $x]
+ } result
+ set result
+} {0}
+test lindex-16.6 {data reuse} {
+ set x [list 1 1]
+ catch {
+ lindex $x $x
+ } result
+ set result
+} {}
+test lindex-16.7 {data reuse} {
+ set x 1
+ catch {
+ lindex $x [list $x $x]
+ } result
+ set result
+} {}
+
+test lindex-17.0 {Bug 1718580} {*}{
+ -body {
+ lindex {} end foo
+ }
+ -match glob
+ -result {bad index "foo"*}
+ -returnCodes 1
+}
+
+test lindex-17.1 {Bug 1718580} {*}{
+ -body {
+ lindex a end foo
+ }
+ -match glob
+ -result {bad index "foo"*}
+ -returnCodes 1
+}
+
+catch { unset minus }
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/link.test b/pkgs/msgcat/tests/link.test
new file mode 100644
index 0000000..60d0799
--- /dev/null
+++ b/pkgs/msgcat/tests/link.test
@@ -0,0 +1,307 @@
+# Commands covered: none
+#
+# This file contains a collection of tests for Tcl_LinkVar and related library
+# procedures. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testlink [llength [info commands testlink]]
+
+foreach i {int real bool string} {
+ unset -nocomplain $i
+}
+
+test link-1.1 {reading C variables from Tcl} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink set 43 1.23 4 - 12341234 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ list $int $real $bool $string $wide
+} -result {43 1.23 1 NULL 12341234}
+test link-1.2 {reading C variables from Tcl} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ testlink set -3 2 0 "A long string with spaces" 43214321 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ list $int $real $bool $string $wide $int $real $bool $string $wide
+} -result {-3 2.0 0 {A long string with spaces} 43214321 -3 2.0 0 {A long string with spaces} 43214321}
+
+test link-2.1 {writing C variables from Tcl} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink set 43 1.21 4 - 56785678 64 250 30000 60000 0xbaadbeef 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ set int "0o0721"
+ set real -10.5
+ set bool true
+ set string abcdef
+ set wide 135135
+ set char 79
+ set uchar 161
+ set short 8000
+ set ushort 40000
+ set uint 0xc001babe
+ set long 34543
+ set ulong 567890
+ set float 1.0987654321
+ set uwide 357357357357
+ concat [testlink get] | $int $real $bool $string $wide $char $uchar $short $ushort $uint $long $ulong $float $uwide
+} -result {465 -10.5 1 abcdef 135135 79 161 8000 40000 -1073628482 34543 567890 1.0987653732299805 357357357357 | 0o0721 -10.5 true abcdef 135135 79 161 8000 40000 0xc001babe 34543 567890 1.0987654321 357357357357}
+test link-2.2 {writing bad values into variables} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ list [catch {set int 09a} msg] $msg $int
+} -result {1 {can't set "int": variable must have integer value} 43}
+test link-2.3 {writing bad values into variables} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ list [catch {set real 1.x3} msg] $msg $real
+} -result {1 {can't set "real": variable must have real value} 1.23}
+test link-2.4 {writing bad values into variables} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ list [catch {set bool gorp} msg] $msg $bool
+} -result {1 {can't set "bool": variable must have boolean value} 1}
+test link-2.5 {writing bad values into variables} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ list [catch {set wide gorp} msg] $msg $bool
+} -result {1 {can't set "wide": variable must have integer value} 1}
+
+test link-3.1 {read-only variables} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 0 1 1 0 0 0 0 0 0 0 0 0 0 0
+ list [catch {set int 4} msg] $msg $int \
+ [catch {set real 10.6} msg] $msg $real \
+ [catch {set bool no} msg] $msg $bool \
+ [catch {set string "new value"} msg] $msg $string \
+ [catch {set wide 12341234} msg] $msg $wide
+} -result {1 {can't set "int": linked variable is read-only} 43 0 10.6 10.6 0 no no 1 {can't set "string": linked variable is read-only} NULL 1 {can't set "wide": linked variable is read-only} 56785678}
+test link-3.2 {read-only variables} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 0 0 1 1 0 0 0 0 0 0 0 0 0
+ list [catch {set int 4} msg] $msg $int \
+ [catch {set real 10.6} msg] $msg $real \
+ [catch {set bool no} msg] $msg $bool \
+ [catch {set string "new value"} msg] $msg $string\
+ [catch {set wide 12341234} msg] $msg $wide
+} -result {0 4 4 1 {can't set "real": linked variable is read-only} 1.23 1 {can't set "bool": linked variable is read-only} 1 0 {new value} {new value} 0 12341234 12341234}
+
+test link-4.1 {unsetting linked variables} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink set -6 -2.5 0 stringValue 13579 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ unset int real bool string wide
+ list [catch {set int} msg] $msg [catch {set real} msg] $msg \
+ [catch {set bool} msg] $msg [catch {set string} msg] $msg \
+ [catch {set wide} msg] $msg
+} -result {0 -6 0 -2.5 0 0 0 stringValue 0 13579}
+test link-4.2 {unsetting linked variables} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink set -6 -2.1 0 stringValue 97531 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ unset int real bool string wide
+ set int 102
+ set real 16
+ set bool true
+ set string newValue
+ set wide 333555
+ lrange [testlink get] 0 4
+} -result {102 16.0 1 newValue 333555}
+
+test link-5.1 {unlinking variables} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink set -6 -2.25 0 stringValue 13579 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink delete
+ set int xx1
+ set real qrst
+ set bool bogus
+ set string 12345
+ set wide 875421
+ set char skjdf
+ set uchar dslfjk
+ set short slkf
+ set ushort skrh
+ set uint sfdkfkh
+ set long srkjh
+ set ulong sjkg
+ set float dskjfbjfd
+ set uwide isdfsngs
+ testlink get
+} -result {-6 -2.25 0 stringValue 13579 64 250 30000 60000 -1091585346 12321 32123 3.25 1231231234}
+test link-5.2 {unlinking variables} -constraints {testlink} -setup {
+ testlink delete
+} -body {
+ testlink set -6 -2.25 0 stringValue 97531 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ testlink delete
+ testlink set 25 14.7 7 - 999999 65 251 30001 60001 0xbabebeef 12322 32124 3.125 12312312340
+ list $int $real $bool $string $wide $char $uchar $short $ushort $uint $long $ulong $float $uwide
+} -result {-6 -2.25 0 stringValue 97531 64 250 30000 60000 3203381950 12321 32123 3.25 1231231234}
+
+test link-6.1 {errors in setting up link} -setup {
+ testlink delete
+ unset -nocomplain int
+} -constraints {testlink} -body {
+ set int(44) 1
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+} -cleanup {
+ unset -nocomplain int
+} -returnCodes error -result {can't set "int": variable is array}
+
+test link-7.1 {access to linked variables via upvar} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ proc x {} {
+ upvar int y
+ unset y
+ }
+ testlink create 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ testlink set 14 {} {} {} {} {} {} {} {} {} {} {} {} {}
+ x
+ list [catch {set int} msg] $msg
+} -result {0 14}
+test link-7.2 {access to linked variables via upvar} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ proc x {} {
+ upvar int y
+ return [set y]
+ }
+ testlink create 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ testlink set 0 {} {} {} {} {} {} {} {} {} {} {} {} {}
+ set int
+ testlink set 23 {} {} {} {} {} {} {} {} {} {} {} {} {}
+ x
+ list [x] $int
+} -result {23 23}
+test link-7.3 {access to linked variables via upvar} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ proc x {} {
+ upvar int y
+ set y 44
+ }
+ testlink create 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ testlink set 11 {} {} {} {} {} {} {} {} {} {} {} {} {}
+ list [catch x msg] $msg $int
+} -result {1 {can't set "y": linked variable is read-only} 11}
+test link-7.4 {access to linked variables via upvar} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ proc x {} {
+ upvar int y
+ set y abc
+ }
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ testlink set -4 {} {} {} {} {} {} {} {} {} {} {} {} {}
+ list [catch x msg] $msg $int
+} -result {1 {can't set "y": variable must have integer value} -4}
+test link-7.5 {access to linked variables via upvar} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ proc x {} {
+ upvar real y
+ set y abc
+ }
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ testlink set -4 16.75 {} {} {} {} {} {} {} {} {} {} {} {}
+ list [catch x msg] $msg $real
+} -result {1 {can't set "y": variable must have real value} 16.75}
+test link-7.6 {access to linked variables via upvar} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ proc x {} {
+ upvar bool y
+ set y abc
+ }
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ testlink set -4 16.3 1 {} {} {} {} {} {} {} {} {} {} {}
+ list [catch x msg] $msg $bool
+} -result {1 {can't set "y": variable must have boolean value} 1}
+test link-7.7 {access to linked variables via upvar} -setup {
+ testlink delete
+} -constraints {testlink} -body {
+ proc x {} {
+ upvar wide y
+ set y abc
+ }
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ testlink set -4 16.3 1 {} 778899 {} {} {} {} {} {} {} {} {}
+ list [catch x msg] $msg $wide
+} -result {1 {can't set "y": variable must have integer value} 778899}
+
+test link-8.1 {Tcl_UpdateLinkedVar procedure} {testlink} {
+ proc x args {
+ global x int real bool string wide
+ lappend x $args $int $real $bool $string $wide
+ }
+ set x {}
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ testlink set 14 -2.0 0 xyzzy 995511 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ trace var int w x
+ testlink update 32 4.0 3 abcd 113355 65 251 30001 60001 0xbabebeef 12322 32124 3.125 12312312340
+ trace vdelete int w x
+ return $x
+} {{int {} w} 32 -2.0 0 xyzzy 995511}
+test link-8.2 {Tcl_UpdateLinkedVar procedure} {testlink} {
+ proc x args {
+ global x int real bool string wide
+ lappend x $args $int $real $bool $string $wide
+ }
+ set x {}
+ testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ testlink set 14 -2.0 0 xyzzy 995511 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+ testlink delete
+ trace var int w x
+ testlink update 32 4.0 6 abcd 113355 65 251 30001 60001 0xbabebeef 12322 32124 3.125 12312312340
+ trace vdelete int w x
+ return $x
+} {}
+test link-8.3 {Tcl_UpdateLinkedVar procedure, read-only variable} {testlink} {
+ testlink create 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ list [catch {
+ testlink update 47 {} {} {} {} {} {} {} {} {} {} {} {} {}
+ } msg] $msg $int
+} {0 {} 47}
+
+catch {testlink set 0 0 0 - 0 0 0 0 0 0 0 0 0 0}
+catch {testlink delete}
+foreach i {int real bool string wide} {
+ unset -nocomplain $i
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/linsert.test b/pkgs/msgcat/tests/linsert.test
new file mode 100644
index 0000000..4939e5c
--- /dev/null
+++ b/pkgs/msgcat/tests/linsert.test
@@ -0,0 +1,119 @@
+# Commands covered: linsert
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+catch {unset lis}
+catch {rename p ""}
+
+test linsert-1.1 {linsert command} {
+ linsert {1 2 3 4 5} 0 a
+} {a 1 2 3 4 5}
+test linsert-1.2 {linsert command} {
+ linsert {1 2 3 4 5} 1 a
+} {1 a 2 3 4 5}
+test linsert-1.3 {linsert command} {
+ linsert {1 2 3 4 5} 2 a
+} {1 2 a 3 4 5}
+test linsert-1.4 {linsert command} {
+ linsert {1 2 3 4 5} 3 a
+} {1 2 3 a 4 5}
+test linsert-1.5 {linsert command} {
+ linsert {1 2 3 4 5} 4 a
+} {1 2 3 4 a 5}
+test linsert-1.6 {linsert command} {
+ linsert {1 2 3 4 5} 5 a
+} {1 2 3 4 5 a}
+test linsert-1.7 {linsert command} {
+ linsert {1 2 3 4 5} 2 one two \{three \$four
+} {1 2 one two \{three {$four} 3 4 5}
+test linsert-1.8 {linsert command} {
+ linsert {\{one \$two \{three \ four \ five} 2 a b c
+} {\{one {$two} a b c \{three { four} { five}}
+test linsert-1.9 {linsert command} {
+ linsert {{1 2} {3 4} {5 6} {7 8}} 2 {x y} {a b}
+} {{1 2} {3 4} {x y} {a b} {5 6} {7 8}}
+test linsert-1.10 {linsert command} {
+ linsert {} 2 a b c
+} {a b c}
+test linsert-1.11 {linsert command} {
+ linsert {} 2 {}
+} {{}}
+test linsert-1.12 {linsert command} {
+ linsert {a b "c c" d e} 3 1
+} {a b {c c} 1 d e}
+test linsert-1.13 {linsert command} {
+ linsert { a b c d} 0 1 2
+} {1 2 a b c d}
+test linsert-1.14 {linsert command} {
+ linsert {a b c {d e f}} 4 1 2
+} {a b c {d e f} 1 2}
+test linsert-1.15 {linsert command} {
+ linsert {a b c \{\ abc} 4 q r
+} {a b c \{\ q r abc}
+test linsert-1.16 {linsert command} {
+ linsert {a b c \{ abc} 4 q r
+} {a b c \{ q r abc}
+test linsert-1.17 {linsert command} {
+ linsert {a b c} end q r
+} {a b c q r}
+test linsert-1.18 {linsert command} {
+ linsert {a} end q r
+} {a q r}
+test linsert-1.19 {linsert command} {
+ linsert {} end q r
+} {q r}
+test linsert-1.20 {linsert command, use of end-int index} {
+ linsert {a b c d} end-2 e f
+} {a b e f c d}
+
+test linsert-2.1 {linsert errors} {
+ list [catch linsert msg] $msg
+} {1 {wrong # args: should be "linsert list index ?element ...?"}}
+test linsert-2.2 {linsert errors} {
+ list [catch {linsert a b} msg] $msg
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
+test linsert-2.3 {linsert errors} {
+ list [catch {linsert a 12x 2} msg] $msg
+} {1 {bad index "12x": must be integer?[+-]integer? or end?[+-]integer?}}
+test linsert-2.4 {linsert errors} {
+ list [catch {linsert \{ 12 2} msg] $msg
+} {1 {unmatched open brace in list}}
+test linsert-2.5 {syntax (TIP 323)} {
+ linsert {a b c} 0
+} [list a b c]
+test linsert-2.6 {syntax (TIP 323)} {
+ linsert "a\nb\nc" 0
+} [list a b c]
+
+test linsert-3.1 {linsert won't modify shared argument objects} {
+ proc p {} {
+ linsert "a b c" 1 "x y"
+ return "a b c"
+ }
+ p
+} "a b c"
+test linsert-3.2 {linsert won't modify shared argument objects} {
+ catch {unset lis}
+ set lis [format "a \"%s\" c" "b"]
+ linsert $lis 0 [string length $lis]
+} "7 a b c"
+
+# cleanup
+catch {unset lis}
+catch {rename p ""}
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/list.test b/pkgs/msgcat/tests/list.test
new file mode 100644
index 0000000..dff5d50
--- /dev/null
+++ b/pkgs/msgcat/tests/list.test
@@ -0,0 +1,134 @@
+# Commands covered: list
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# First, a bunch of individual tests
+
+test list-1.1 {basic tests} {list a b c} {a b c}
+test list-1.2 {basic tests} {list {a b} c} {{a b} c}
+test list-1.3 {basic tests} {list \{a b c} {\{a b c}
+test list-1.4 {basic tests} "list a{}} b{} c}" "a\\{\\}\\} b{} c\\}"
+test list-1.5 {basic tests} {list a\[ b\] } "{a\[} b\\]"
+test list-1.6 {basic tests} {list c\ d\t } "{c } {d\t}"
+test list-1.7 {basic tests} {list e\n f\$ } "{e\n} {f\$}"
+test list-1.8 {basic tests} {list g\; h\\} {{g;} h\\}
+test list-1.9 {basic tests} "list a\\\[} b\\\]} " "a\\\[\\\} b\\\]\\\}"
+test list-1.10 {basic tests} "list c\\\} d\\t} " "c\\} d\\t\\}"
+test list-1.11 {basic tests} "list e\\n} f\\$} " "e\\n\\} f\\$\\}"
+test list-1.12 {basic tests} "list g\\;} h\\\\} " "g\\;\\} {h\\}}"
+test list-1.13 {basic tests} {list a {{}} b} {a {{}} b}
+test list-1.14 {basic tests} {list a b xy\\} "a b xy\\\\"
+test list-1.15 {basic tests} "list a b\} e\\" "a b\\} e\\\\"
+test list-1.16 {basic tests} "list a b\}\\\$ e\\\$\\" "a b\\}\\\$ e\\\$\\\\"
+test list-1.17 {basic tests} {list a\f \{\f} "{a\f} \\\{\\f"
+test list-1.18 {basic tests} {list a\r \{\r} "{a\r} \\\{\\r"
+test list-1.19 {basic tests} {list a\v \{\v} "{a\v} \\\{\\v"
+test list-1.20 {basic tests} {list \"\}\{} "\\\"\\}\\{"
+test list-1.21 {basic tests} {list a b c\\\nd} "a b c\\\\\\nd"
+test list-1.22 {basic tests} {list "{ab}\\"} \\{ab\\}\\\\
+test list-1.23 {basic tests} {list \{} "\\{"
+test list-1.24 {basic tests} {list} {}
+test list-1.25 {basic tests} {list # #} {{#} #}
+test list-1.26 {basic tests} {list #\{ #\{} {\#\{ #\{}
+test list-1.27 {basic null treatment} {
+ set l [list "" "\0" "\0\0"]
+ set e "{} \0 \0\0"
+ string equal $l $e
+} 1
+test list-1.28 {basic null treatment} {
+ set result "\0a\0b"
+ list $result [string length $result]
+} "\0a\0b 4"
+test list-1.29 {basic null treatment} {
+ set result "\0a\0b"
+ set srep "$result 4"
+ set lrep [list $result [string length $result]]
+ string equal $srep $lrep
+} 1
+test list-1.30 {basic null treatment} {
+ set l [list "\0abc" "xyz"]
+ set e "\0abc xyz"
+ string equal $l $e
+} 1
+
+# For the next round of tests create a list and then pick it apart
+# with "index" to make sure that we get back exactly what went in.
+
+set num 0
+proc lcheck {testid a b c} {
+ global num d
+ set d [list $a $b $c]
+ test ${testid}-0 {what goes in must come out} {lindex $d 0} $a
+ test ${testid}-1 {what goes in must come out} {lindex $d 1} $b
+ test ${testid}-2 {what goes in must come out} {lindex $d 2} $c
+}
+lcheck list-2.1 a b c
+lcheck list-2.2 "a b" c\td e\nf
+lcheck list-2.3 {{a b}} {} { }
+lcheck list-2.4 \$ \$ab ab\$
+lcheck list-2.5 \; \;ab ab\;
+lcheck list-2.6 \[ \[ab ab\[
+lcheck list-2.7 \\ \\ab ab\\
+lcheck list-2.8 {"} {"ab} {ab"} ;#" Stupid emacs highlighting!
+lcheck list-2.9 {a b} { ab} {ab }
+lcheck list-2.10 a{ a{b \{ab
+lcheck list-2.11 a} a}b }ab
+lcheck list-2.12 a\\} {a \}b} {a \{c}
+lcheck list-2.13 xyz \\ 1\\\n2
+lcheck list-2.14 "{ab}\\" "{ab}xy" abc
+
+concat {}
+
+# Check that tclListObj.c's SetListFromAny handles possible overlarge
+# string rep lengths in the source object.
+
+proc slowsort list {
+ set result {}
+ set last [expr [llength $list] - 1]
+ while {$last > 0} {
+ set minIndex [expr [llength $list] - 1]
+ set min [lindex $list $last]
+ set i [expr $minIndex-1]
+ while {$i >= 0} {
+ if {[string compare [lindex $list $i] $min] < 0} {
+ set minIndex $i
+ set min [lindex $list $i]
+ }
+ set i [expr $i-1]
+ }
+ set result [concat $result [list $min]]
+ if {$minIndex == 0} {
+ set list [lrange $list 1 end]
+ } else {
+ set list [concat [lrange $list 0 [expr $minIndex-1]] \
+ [lrange $list [expr $minIndex+1] end]]
+ }
+ set last [expr $last-1]
+ }
+ return [concat $result $list]
+}
+test list-3.1 {SetListFromAny and lrange/concat results} {
+ slowsort {fred julie alex carol bill annie}
+} {alex annie bill carol fred julie}
+
+test list-4.1 {Bug 3173086} {
+ string is list "{[list \\\\\}]}"
+} 1
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/listObj.test b/pkgs/msgcat/tests/listObj.test
new file mode 100644
index 0000000..53017b1
--- /dev/null
+++ b/pkgs/msgcat/tests/listObj.test
@@ -0,0 +1,202 @@
+# Functionality covered: operation of the procedures in tclListObj.c that
+# implement the Tcl type manager for the list object type.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1995-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testobj [llength [info commands testobj]]
+
+catch {unset x}
+test listobj-1.1 {Tcl_GetListObjType} emptyTest {
+ # Test removed; tested an internal detail
+ # that's no longer correct, and duplicated test obj-1.1
+} {}
+
+test listobj-2.1 {Tcl_SetListObj, use in lappend} {
+ catch {unset x}
+ list [lappend x 1 abc def] [lappend x 1 ghi jkl] $x
+} {{1 abc def} {1 abc def 1 ghi jkl} {1 abc def 1 ghi jkl}}
+test listobj-2.2 {Tcl_SetListObj, use in ObjInterpProc} {
+ proc return_args {args} {
+ return $args
+ }
+ list [return_args] [return_args x] [return_args x y]
+} {{} x {x y}}
+test listobj-2.3 {Tcl_SetListObj, zero element count} {
+ list
+} {}
+
+test listobj-3.1 {Tcl_ListObjAppend, list conversion} {
+ catch {unset x}
+ list [lappend x 1 2 abc "long string"] $x
+} {{1 2 abc {long string}} {1 2 abc {long string}}}
+test listobj-3.2 {Tcl_ListObjAppend, list conversion} {
+ set x ""
+ list [lappend x first second] [lappend x third fourth] $x
+} {{first second} {first second third fourth} {first second third fourth}}
+test listobj-3.3 {Tcl_ListObjAppend, list conversion} {
+ set x "abc def"
+ list [lappend x first second] $x
+} {{abc def first second} {abc def first second}}
+test listobj-3.4 {Tcl_ListObjAppend, error in conversion} {
+ set x " \{"
+ list [catch {lappend x abc def} msg] $msg
+} {1 {unmatched open brace in list}}
+test listobj-3.5 {Tcl_ListObjAppend, force internal rep array to grow} {
+ set x ""
+ list [lappend x 1 1] [lappend x 2 2] [lappend x 3 3] [lappend x 4 4] \
+ [lappend x 5 5] [lappend x 6 6] [lappend x 7 7] [lappend x 8 8] $x
+} {{1 1} {1 1 2 2} {1 1 2 2 3 3} {1 1 2 2 3 3 4 4} {1 1 2 2 3 3 4 4 5 5} {1 1 2 2 3 3 4 4 5 5 6 6} {1 1 2 2 3 3 4 4 5 5 6 6 7 7} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8}}
+
+test listobj-4.1 {Tcl_ListObjAppendElement, list conversion} {
+ catch {unset x}
+ list [lappend x 1] $x
+} {1 1}
+test listobj-4.2 {Tcl_ListObjAppendElement, list conversion} {
+ set x ""
+ list [lappend x first] [lappend x second] $x
+} {first {first second} {first second}}
+test listobj-4.3 {Tcl_ListObjAppendElement, list conversion} {
+ set x "abc def"
+ list [lappend x first] $x
+} {{abc def first} {abc def first}}
+test listobj-4.4 {Tcl_ListObjAppendElement, error in conversion} {
+ set x " \{"
+ list [catch {lappend x abc} msg] $msg
+} {1 {unmatched open brace in list}}
+test listobj-4.5 {Tcl_ListObjAppendElement, force internal rep array to grow} {
+ set x ""
+ list [lappend x 1] [lappend x 2] [lappend x 3] [lappend x 4] \
+ [lappend x 5] [lappend x 6] [lappend x 7] [lappend x 8] $x
+} {1 {1 2} {1 2 3} {1 2 3 4} {1 2 3 4 5} {1 2 3 4 5 6} {1 2 3 4 5 6 7} {1 2 3 4 5 6 7 8} {1 2 3 4 5 6 7 8}}
+
+test listobj-5.1 {Tcl_ListObjIndex, basic tests} {
+ lindex {a b c} 0
+} a
+test listobj-5.2 {Tcl_ListObjIndex, basic tests} {
+ lindex a 0
+} a
+test listobj-5.3 {Tcl_ListObjIndex, basic tests} {
+ lindex {a {b c d} x} 1
+} {b c d}
+test listobj-5.4 {Tcl_ListObjIndex, basic tests} {
+ lindex {a b c} 3
+} {}
+test listobj-5.5 {Tcl_ListObjIndex, basic tests} {
+ lindex {a b c} 100
+} {}
+test listobj-5.6 {Tcl_ListObjIndex, basic tests} {
+ lindex a 100
+} {}
+test listobj-5.7 {Tcl_ListObjIndex, basic tests} {
+ lindex {} -1
+} {}
+test listobj-5.8 {Tcl_ListObjIndex, error in conversion} {
+ set x " \{"
+ list [catch {lindex $x 0} msg] $msg
+} {1 {unmatched open brace in list}}
+
+test listobj-6.1 {Tcl_ListObjLength} {
+ llength {a b c d}
+} 4
+test listobj-6.2 {Tcl_ListObjLength} {
+ llength {a b c {a b {c d}} d}
+} 5
+test listobj-6.3 {Tcl_ListObjLength} {
+ llength {}
+} 0
+test listobj-6.4 {Tcl_ListObjLength, convert from non-list} {
+ llength 123
+} 1
+test listobj-6.5 {Tcl_ListObjLength, error converting from non-list} {
+ list [catch {llength "a b c \{"} msg] $msg
+} {1 {unmatched open brace in list}}
+test listobj-6.6 {Tcl_ListObjLength, error converting from non-list} {
+ list [catch {llength "a {b}c"} msg] $msg
+} {1 {list element in braces followed by "c" instead of space}}
+
+test listobj-7.1 {Tcl_ListObjReplace, conversion from non-list} {
+ lreplace 123 0 0 x
+} {x}
+test listobj-7.2 {Tcl_ListObjReplace, error converting from non-list} {
+ list [catch {lreplace "a b c \{" 1 1 x} msg] $msg
+} {1 {unmatched open brace in list}}
+test listobj-7.3 {Tcl_ListObjReplace, error converting from non-list} {
+ list [catch {lreplace "a {b}c" 1 2 x} msg] $msg
+} {1 {list element in braces followed by "c" instead of space}}
+test listobj-7.4 {Tcl_ListObjReplace, negative first element index} {
+ lreplace {1 2 3 4 5} -1 1 a
+} {a 3 4 5}
+test listobj-7.5 {Tcl_ListObjReplace, last element index >= num elems} {
+ lreplace {1 2 3 4 5} 3 7 a b c
+} {1 2 3 a b c}
+test listobj-7.6 {Tcl_ListObjReplace, first element index > last index} {
+ lreplace {1 2 3 4 5} 3 1 a b c
+} {1 2 3 a b c 4 5}
+test listobj-7.7 {Tcl_ListObjReplace, no new elements} {
+ lreplace {1 2 3 4 5} 1 1
+} {1 3 4 5}
+test listobj-7.8 {Tcl_ListObjReplace, shrink array in place} {
+ lreplace {1 2 3 4 5 6 7} 4 5
+} {1 2 3 4 7}
+test listobj-7.9 {Tcl_ListObjReplace, grow array in place} {
+ lreplace {1 2 3 4 5 6 7} 1 3 a b c d e
+} {1 a b c d e 5 6 7}
+test listobj-7.10 {Tcl_ListObjReplace, replace tail of array} {
+ lreplace {1 2 3 4 5 6 7} 3 6 a
+} {1 2 3 a}
+test listobj-7.11 {Tcl_ListObjReplace, must grow internal array} {
+ lreplace {1 2 3 4 5} 2 3 a b c d e f g h i j k l
+} {1 2 a b c d e f g h i j k l 5}
+test listobj-7.12 {Tcl_ListObjReplace, grow array, insert at start} {
+ lreplace {1 2 3 4 5} -1 -1 a b c d e f g h i j k l
+} {a b c d e f g h i j k l 1 2 3 4 5}
+test listobj-7.13 {Tcl_ListObjReplace, grow array, insert at end} {
+ lreplace {1 2 3 4 5} 4 1 a b c d e f g h i j k l
+} {1 2 3 4 a b c d e f g h i j k l 5}
+
+test listobj-8.1 {SetListFromAny} {
+ lindex {0 foo\x00help 2} 1
+} "foo\x00help"
+
+test listobj-9.1 {UpdateStringOfList} {
+ string length [list foo\x00help]
+} 8
+
+test listobj-10.1 {Bug [2971669]} {*}{
+ -constraints testobj
+ -setup {
+ testobj freeallvars
+ }
+ -body {
+ set result {}
+ lappend result \
+ [testlistobj set 1 a b c d e] \
+ [testlistobj replace 1 0x7fffffff 0x7fffffff f] \
+ [testlistobj get 1]
+ }
+ -cleanup {
+ testobj freeallvars
+ }
+ -result {{a b c d e} {} {a b c d e f}}
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/llength.test b/pkgs/msgcat/tests/llength.test
new file mode 100644
index 0000000..169c7ca
--- /dev/null
+++ b/pkgs/msgcat/tests/llength.test
@@ -0,0 +1,41 @@
+# Commands covered: llength
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test llength-1.1 {length of list} {
+ llength {a b c d}
+} 4
+test llength-1.2 {length of list} {
+ llength {a b c {a b {c d}} d}
+} 5
+test llength-1.3 {length of list} {
+ llength {}
+} 0
+
+test llength-2.1 {error conditions} {
+ list [catch {llength} msg] $msg
+} {1 {wrong # args: should be "llength list"}}
+test llength-2.2 {error conditions} {
+ list [catch {llength 123 2} msg] $msg
+} {1 {wrong # args: should be "llength list"}}
+test llength-2.3 {error conditions} {
+ list [catch {llength "a b c \{"} msg] $msg
+} {1 {unmatched open brace in list}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/load.test b/pkgs/msgcat/tests/load.test
new file mode 100644
index 0000000..b7c1a59
--- /dev/null
+++ b/pkgs/msgcat/tests/load.test
@@ -0,0 +1,217 @@
+# Commands covered: load
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1995 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Figure out what extension is used for shared libraries on this
+# platform.
+if {![info exists ext]} {
+ set ext [info sharedlibextension]
+}
+# Tests require the existence of one of the DLLs in the dltest directory.
+set testDir [file join [file dirname [info nameofexecutable]] dltest]
+set x [file join $testDir pkga$ext]
+set dll "[file tail $x]Required"
+testConstraint $dll [file readable $x]
+
+# Tests also require that this DLL has not already been loaded.
+set loaded "[file tail $x]Loaded"
+set alreadyLoaded [info loaded]
+testConstraint $loaded [expr {![string match *pkga* $alreadyLoaded]}]
+
+set alreadyTotalLoaded [info loaded]
+
+# Certain tests require the 'teststaticpkg' command from tcltest
+
+testConstraint teststaticpkg [llength [info commands teststaticpkg]]
+
+# Test load-10.1 requires the 'testsimplefilesystem' command from tcltest
+
+testConstraint testsimplefilesystem \
+ [llength [info commands testsimplefilesystem]]
+
+test load-1.1 {basic errors} {} {
+ list [catch {load} msg] $msg
+} "1 {wrong \# args: should be \"load fileName ?packageName? ?interp?\"}"
+test load-1.2 {basic errors} {} {
+ list [catch {load a b c d} msg] $msg
+} "1 {wrong \# args: should be \"load fileName ?packageName? ?interp?\"}"
+test load-1.3 {basic errors} {} {
+ list [catch {load a b foobar} msg] $msg
+} {1 {could not find interpreter "foobar"}}
+test load-1.4 {basic errors} {} {
+ list [catch {load {}} msg] $msg
+} {1 {must specify either file name or package name}}
+test load-1.5 {basic errors} {} {
+ list [catch {load {} {}} msg] $msg
+} {1 {must specify either file name or package name}}
+test load-1.6 {basic errors} {} {
+ list [catch {load {} Unknown} msg] $msg
+} {1 {package "Unknown" isn't loaded statically}}
+
+test load-2.1 {basic loading, with guess for package name} \
+ [list $dll $loaded] {
+ load [file join $testDir pkga$ext]
+ list [pkga_eq abc def] [lsort [info commands pkga_*]]
+} {0 {pkga_eq pkga_quote}}
+interp create -safe child
+test load-2.2 {loading into a safe interpreter, with package name conversion} \
+ [list $dll $loaded] {
+ load [file join $testDir pkgb$ext] pKgB child
+ list [child eval pkgb_sub 44 13] [catch {child eval pkgb_unsafe} msg] $msg \
+ [catch {pkgb_sub 12 10} msg2] $msg2
+} {31 1 {invalid command name "pkgb_unsafe"} 1 {invalid command name "pkgb_sub"}}
+test load-2.3 {loading with no _Init procedure} -constraints [list $dll $loaded] \
+-body {
+ list [catch {load [file join $testDir pkgc$ext] foo} msg] $msg $errorCode
+} -match glob \
+ -result [list 1 {cannot find symbol "Foo_Init"*} \
+ {TCL LOOKUP LOAD_SYMBOL *Foo_Init}]
+test load-2.4 {loading with no _SafeInit procedure} [list $dll $loaded] {
+ list [catch {load [file join $testDir pkga$ext] {} child} msg] $msg
+} {1 {can't use package in a safe interpreter: no Pkga_SafeInit procedure}}
+
+test load-3.1 {error in _Init procedure, same interpreter} \
+ [list $dll $loaded] {
+ list [catch {load [file join $testDir pkge$ext] pkge} msg] \
+ $msg $::errorInfo $::errorCode
+} {1 {couldn't open "non_existent": no such file or directory} {couldn't open "non_existent": no such file or directory
+ while executing
+"open non_existent"
+ invoked from within
+"if 44 {open non_existent}"
+ invoked from within
+"load [file join $testDir pkge$ext] pkge"} {POSIX ENOENT {no such file or directory}}}
+test load-3.2 {error in _Init procedure, slave interpreter} \
+ [list $dll $loaded] {
+ catch {interp delete x}
+ interp create x
+ set ::errorCode foo
+ set ::errorInfo bar
+ set result [list [catch {load [file join $testDir pkge$ext] pkge x} msg] \
+ $msg $::errorInfo $::errorCode]
+ interp delete x
+ set result
+} {1 {couldn't open "non_existent": no such file or directory} {couldn't open "non_existent": no such file or directory
+ while executing
+"open non_existent"
+ invoked from within
+"if 44 {open non_existent}"
+ invoked from within
+"load [file join $testDir pkge$ext] pkge x"} {POSIX ENOENT {no such file or directory}}}
+
+test load-4.1 {reloading package into same interpreter} [list $dll $loaded] {
+ list [catch {load [file join $testDir pkga$ext] pkga} msg] $msg
+} {0 {}}
+test load-4.2 {reloading package into same interpreter} [list $dll $loaded] {
+ list [catch {load [file join $testDir pkga$ext] pkgb} msg] $msg
+} [list 1 "file \"[file join $testDir pkga$ext]\" is already loaded for package \"Pkga\""]
+
+test load-5.1 {file name not specified and no static package: pick default} \
+ [list $dll $loaded] {
+ catch {interp delete x}
+ interp create x
+ load [file join $testDir pkga$ext] pkga
+ load {} pkga x
+ set result [info loaded x]
+ interp delete x
+ set result
+} [list [list [file join $testDir pkga$ext] Pkga]]
+
+# On some platforms, like SunOS 4.1.3, these tests can't be run because
+# they cause the process to exit.
+#
+# As of 2005, such ancient broken systems no longer matter.
+
+test load-6.1 {errors loading file} [list $dll $loaded] {
+ catch {load foo foo}
+} {1}
+
+test load-7.1 {Tcl_StaticPackage procedure} [list teststaticpkg] {
+ set x "not loaded"
+ teststaticpkg Test 1 0
+ load {} Test
+ load {} Test child
+ list [set x] [child eval set x]
+} {loaded loaded}
+test load-7.2 {Tcl_StaticPackage procedure} [list teststaticpkg] {
+ set x "not loaded"
+ teststaticpkg Another 0 0
+ load {} Another
+ child eval {set x "not loaded"}
+ list [catch {load {} Another child} msg] $msg \
+ [child eval set x] [set x]
+} {1 {can't use package in a safe interpreter: no Another_SafeInit procedure} {not loaded} loaded}
+test load-7.3 {Tcl_StaticPackage procedure} [list teststaticpkg] {
+ set x "not loaded"
+ teststaticpkg More 0 1
+ load {} More
+ set x
+} {not loaded}
+test load-7.4 {Tcl_StaticPackage procedure, redundant calls} \
+ [list teststaticpkg $dll $loaded] {
+ teststaticpkg Double 0 1
+ teststaticpkg Double 0 1
+ info loaded
+ } [concat [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkge$ext] Pkge] [list [file join $testDir pkgb$ext] Pkgb] [list [file join $testDir pkga$ext] Pkga]] $alreadyTotalLoaded]
+
+test load-8.1 {TclGetLoadedPackages procedure} [list teststaticpkg $dll $loaded] {
+ info loaded
+} [concat [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkge$ext] Pkge] [list [file join $testDir pkgb$ext] Pkgb] [list [file join $testDir pkga$ext] Pkga]] $alreadyTotalLoaded]
+test load-8.2 {TclGetLoadedPackages procedure} [list teststaticpkg] {
+ list [catch {info loaded gorp} msg] $msg
+} {1 {could not find interpreter "gorp"}}
+test load-8.3 {TclGetLoadedPackages procedure} [list teststaticpkg $dll $loaded] {
+ list [info loaded {}] [info loaded child]
+} [list [concat [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga]] $alreadyLoaded] [list {{} Test} [list [file join $testDir pkgb$ext] Pkgb]]]
+test load-8.4 {TclGetLoadedPackages procedure} [list $dll $loaded teststaticpkg] {
+ load [file join $testDir pkgb$ext] pkgb
+ list [info loaded {}] [lsort [info commands pkgb_*]]
+} [list [concat [list [list [file join $testDir pkgb$ext] Pkgb] {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga]] $alreadyLoaded] {pkgb_sub pkgb_unsafe}]
+interp delete child
+
+test load-9.1 {Tcl_StaticPackage, load already-loaded package into another interp} \
+ -constraints {teststaticpkg} \
+ -setup {
+ interp create child1
+ interp create child2
+ load {} Tcltest child1
+ load {} Tcltest child2
+ } \
+ -body {
+ child1 eval { teststaticpkg Loadninepointone 0 1 }
+ child2 eval { teststaticpkg Loadninepointone 0 1 }
+ list \
+ [child1 eval { info loaded {} }] \
+ [child2 eval { info loaded {} }]
+ } \
+ -result {{{{} Loadninepointone} {{} Tcltest}} {{{} Loadninepointone} {{} Tcltest}}} \
+ -cleanup { interp delete child1 ; interp delete child2 }
+
+test load-10.1 {load from vfs} \
+ -constraints [list $dll $loaded testsimplefilesystem] \
+ -setup {set dir [pwd]; cd $testDir; testsimplefilesystem 1} \
+ -body {list [catch {load simplefs:/pkgd$ext pkgd} msg] $msg} \
+ -result {0 {}} \
+ -cleanup {testsimplefilesystem 0; cd $dir; unset dir}
+
+# cleanup
+unset ext
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/lrange.test b/pkgs/msgcat/tests/lrange.test
new file mode 100644
index 0000000..6c81872
--- /dev/null
+++ b/pkgs/msgcat/tests/lrange.test
@@ -0,0 +1,88 @@
+# Commands covered: lrange
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test lrange-1.1 {range of list elements} {
+ lrange {a b c d} 1 2
+} {b c}
+test lrange-1.2 {range of list elements} {
+ lrange {a {bcd e {f g {}}} l14 l15 d} 1 1
+} {{bcd e {f g {}}}}
+test lrange-1.3 {range of list elements} {
+ lrange {a {bcd e {f g {}}} l14 l15 d} 3 end
+} {l15 d}
+test lrange-1.4 {range of list elements} {
+ lrange {a {bcd e {f g {}}} l14 l15 d} 4 10000
+} {d}
+test lrange-1.5 {range of list elements} {
+ lrange {a {bcd e {f g {}}} l14 l15 d} 4 3
+} {}
+test lrange-1.6 {range of list elements} {
+ lrange {a {bcd e {f g {}}} l14 l15 d} 10 11
+} {}
+test lrange-1.7 {range of list elements} {
+ lrange {a b c d e} -1 2
+} {a b c}
+test lrange-1.8 {range of list elements} {
+ lrange {a b c d e} -2 -1
+} {}
+test lrange-1.9 {range of list elements} {
+ lrange {a b c d e} -2 end
+} {a b c d e}
+test lrange-1.10 {range of list elements} {
+ lrange "a b\{c d" 1 2
+} "b\\{c d"
+test lrange-1.11 {range of list elements} {
+ lrange "a b c d" end end
+} d
+test lrange-1.12 {range of list elements} {
+ lrange "a b c d" end 100000
+} d
+test lrange-1.13 {range of list elements} {
+ lrange "a b c d" end 3
+} d
+test lrange-1.14 {range of list elements} {
+ lrange "a b c d" end 2
+} {}
+test lrange-1.15 {range of list elements} {
+ concat \"[lrange {a b \{\ } 0 2]"
+} {"a b \{\ "}
+test lrange-1.16 {list element quoting} {
+ lrange {[append a .b]} 0 end
+} {{[append} a .b\]}
+test lrange-2.1 {error conditions} {
+ list [catch {lrange a b} msg] $msg
+} {1 {wrong # args: should be "lrange list first last"}}
+test lrange-2.2 {error conditions} {
+ list [catch {lrange a b 6 7} msg] $msg
+} {1 {wrong # args: should be "lrange list first last"}}
+test lrange-2.3 {error conditions} {
+ list [catch {lrange a b 6} msg] $msg
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
+test lrange-2.4 {error conditions} {
+ list [catch {lrange a 0 enigma} msg] $msg
+} {1 {bad index "enigma": must be integer?[+-]integer? or end?[+-]integer?}}
+test lrange-2.5 {error conditions} {
+ list [catch {lrange "a \{b c" 3 4} msg] $msg
+} {1 {unmatched open brace in list}}
+test lrange-2.6 {error conditions} {
+ list [catch {lrange "a b c \{ d e" 1 4} msg] $msg
+} {1 {unmatched open brace in list}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/lrepeat.test b/pkgs/msgcat/tests/lrepeat.test
new file mode 100644
index 0000000..788bb9b
--- /dev/null
+++ b/pkgs/msgcat/tests/lrepeat.test
@@ -0,0 +1,84 @@
+# Commands covered: lrepeat
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 2003 by Simon Geard.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+## Arg errors
+test lrepeat-1.1 {error cases} {
+ -body {
+ lrepeat
+ }
+ -returnCodes 1
+ -result {wrong # args: should be "lrepeat count ?value ...?"}
+}
+test lrepeat-1.2 {Accept zero elements(TIP 323)} {
+ -body {
+ lrepeat 1
+ }
+ -result {}
+}
+test lrepeat-1.3 {error cases} {
+ -body {
+ lrepeat a 1
+ }
+ -returnCodes 1
+ -result {expected integer but got "a"}
+}
+test lrepeat-1.4 {error cases} {
+ -body {
+ lrepeat -3 1
+ }
+ -returnCodes 1
+ -result {bad count "-3": must be integer >= 0}
+}
+test lrepeat-1.5 {Accept zero repetitions (TIP 323)} {
+ -body {
+ lrepeat 0
+ }
+ -result {}
+}
+test lrepeat-1.6 {error cases} {
+ -body {
+ lrepeat 3.5 1
+ }
+ -returnCodes 1
+ -result {expected integer but got "3.5"}
+}
+test lrepeat-1.7 {Accept zero repetitions (TIP 323)} {
+ -body {
+ lrepeat 0 a b c
+ }
+ -result {}
+}
+test lrepeat-1.8 {Do not build enormous lists - Bug 2130992} -body {
+ lrepeat 0x10000000 a b c d e f g h
+} -returnCodes error -match glob -result *
+
+## Okay
+test lrepeat-2.1 {normal cases} {
+ lrepeat 10 a
+} {a a a a a a a a a a}
+test lrepeat-2.2 {normal cases} {
+ lrepeat 3 [lrepeat 3 0]
+} {{0 0 0} {0 0 0} {0 0 0}}
+test lrepeat-2.3 {normal cases} {
+ lrepeat 3 a b c
+} {a b c a b c a b c}
+test lrepeat-2.4 {normal cases} {
+ lrepeat 3 [lrepeat 2 a] b c
+} {{a a} b c {a a} b c {a a} b c}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/lreplace.test b/pkgs/msgcat/tests/lreplace.test
new file mode 100644
index 0000000..5f675bc
--- /dev/null
+++ b/pkgs/msgcat/tests/lreplace.test
@@ -0,0 +1,136 @@
+# Commands covered: lreplace
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test lreplace-1.1 {lreplace command} {
+ lreplace {1 2 3 4 5} 0 0 a
+} {a 2 3 4 5}
+test lreplace-1.2 {lreplace command} {
+ lreplace {1 2 3 4 5} 1 1 a
+} {1 a 3 4 5}
+test lreplace-1.3 {lreplace command} {
+ lreplace {1 2 3 4 5} 2 2 a
+} {1 2 a 4 5}
+test lreplace-1.4 {lreplace command} {
+ lreplace {1 2 3 4 5} 3 3 a
+} {1 2 3 a 5}
+test lreplace-1.5 {lreplace command} {
+ lreplace {1 2 3 4 5} 4 4 a
+} {1 2 3 4 a}
+test lreplace-1.6 {lreplace command} {
+ lreplace {1 2 3 4 5} 4 5 a
+} {1 2 3 4 a}
+test lreplace-1.7 {lreplace command} {
+ lreplace {1 2 3 4 5} -1 -1 a
+} {a 1 2 3 4 5}
+test lreplace-1.8 {lreplace command} {
+ lreplace {1 2 3 4 5} 2 end a b c d
+} {1 2 a b c d}
+test lreplace-1.9 {lreplace command} {
+ lreplace {1 2 3 4 5} 0 3
+} {5}
+test lreplace-1.10 {lreplace command} {
+ lreplace {1 2 3 4 5} 0 4
+} {}
+test lreplace-1.11 {lreplace command} {
+ lreplace {1 2 3 4 5} 0 1
+} {3 4 5}
+test lreplace-1.12 {lreplace command} {
+ lreplace {1 2 3 4 5} 2 3
+} {1 2 5}
+test lreplace-1.13 {lreplace command} {
+ lreplace {1 2 3 4 5} 3 end
+} {1 2 3}
+test lreplace-1.14 {lreplace command} {
+ lreplace {1 2 3 4 5} -1 4 a b c
+} {a b c}
+test lreplace-1.15 {lreplace command} {
+ lreplace {a b "c c" d e f} 3 3
+} {a b {c c} e f}
+test lreplace-1.16 {lreplace command} {
+ lreplace { 1 2 3 4 5} 0 0 a
+} {a 2 3 4 5}
+test lreplace-1.17 {lreplace command} {
+ lreplace {1 2 3 4 "5 6"} 4 4 a
+} {1 2 3 4 a}
+test lreplace-1.18 {lreplace command} {
+ lreplace {1 2 3 4 {5 6}} 4 4 a
+} {1 2 3 4 a}
+test lreplace-1.19 {lreplace command} {
+ lreplace {1 2 3 4} 2 end x y z
+} {1 2 x y z}
+test lreplace-1.20 {lreplace command} {
+ lreplace {1 2 3 4} end end a
+} {1 2 3 a}
+test lreplace-1.21 {lreplace command} {
+ lreplace {1 2 3 4} end 3 a
+} {1 2 3 a}
+test lreplace-1.22 {lreplace command} {
+ lreplace {1 2 3 4} end end
+} {1 2 3}
+test lreplace-1.23 {lreplace command} {
+ lreplace {1 2 3 4} 2 -1 xy
+} {1 2 xy 3 4}
+test lreplace-1.24 {lreplace command} {
+ lreplace {1 2 3 4} end -1 z
+} {1 2 3 z 4}
+test lreplace-1.25 {lreplace command} {
+ concat \"[lreplace {\}\ hello} end end]\"
+} {"\}\ "}
+test lreplace-1.26 {lreplace command} {
+ catch {unset foo}
+ set foo {a b}
+ list [set foo [lreplace $foo end end]] \
+ [set foo [lreplace $foo end end]] \
+ [set foo [lreplace $foo end end]]
+} {a {} {}}
+
+
+test lreplace-2.1 {lreplace errors} {
+ list [catch lreplace msg] $msg
+} {1 {wrong # args: should be "lreplace list first last ?element ...?"}}
+test lreplace-2.2 {lreplace errors} {
+ list [catch {lreplace a b} msg] $msg
+} {1 {wrong # args: should be "lreplace list first last ?element ...?"}}
+test lreplace-2.3 {lreplace errors} {
+ list [catch {lreplace x a 10} msg] $msg
+} {1 {bad index "a": must be integer?[+-]integer? or end?[+-]integer?}}
+test lreplace-2.4 {lreplace errors} {
+ list [catch {lreplace x 10 x} msg] $msg
+} {1 {bad index "x": must be integer?[+-]integer? or end?[+-]integer?}}
+test lreplace-2.5 {lreplace errors} {
+ list [catch {lreplace x 10 1x} msg] $msg
+} {1 {bad index "1x": must be integer?[+-]integer? or end?[+-]integer?}}
+test lreplace-2.6 {lreplace errors} {
+ list [catch {lreplace x 3 2} msg] $msg
+} {1 {list doesn't contain element 3}}
+test lreplace-2.7 {lreplace errors} {
+ list [catch {lreplace x 1 1} msg] $msg
+} {1 {list doesn't contain element 1}}
+
+test lreplace-3.1 {lreplace won't modify shared argument objects} {
+ proc p {} {
+ lreplace "a b c" 1 1 "x y"
+ return "a b c"
+ }
+ p
+} "a b c"
+
+# cleanup
+catch {unset foo}
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/lsearch.test b/pkgs/msgcat/tests/lsearch.test
new file mode 100644
index 0000000..f36e987
--- /dev/null
+++ b/pkgs/msgcat/tests/lsearch.test
@@ -0,0 +1,528 @@
+# Commands covered: lsearch
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+set x {abcd bbcd 123 234 345}
+test lsearch-1.1 {lsearch command} {
+ lsearch $x 123
+} 2
+test lsearch-1.2 {lsearch command} {
+ lsearch $x 3456
+} -1
+test lsearch-1.3 {lsearch command} {
+ lsearch $x *5
+} 4
+test lsearch-1.4 {lsearch command} {
+ lsearch $x *bc*
+} 0
+
+test lsearch-2.1 {search modes} {
+ lsearch -exact {xyz bbcc *bc*} *bc*
+} 2
+test lsearch-2.2 {search modes} {
+ lsearch -exact {b.x ^bc xy bcx} ^bc
+} 1
+test lsearch-2.3 {search modes} {
+ lsearch -exact {foo bar cat} ba
+} -1
+test lsearch-2.4 {search modes} {
+ lsearch -exact {foo bar cat} bart
+} -1
+test lsearch-2.5 {search modes} {
+ lsearch -exact {foo bar cat} bar
+} 1
+test lsearch-2.6 {search modes} -returnCodes error -body {
+ lsearch -regexp {xyz bbcc *bc*} *bc*
+} -result {couldn't compile regular expression pattern: quantifier operand invalid}
+test lsearch-2.7 {search modes} {
+ lsearch -regexp {b.x ^bc xy bcx} ^bc
+} 3
+test lsearch-2.8 {search modes} {
+ lsearch -glob {xyz bbcc *bc*} *bc*
+} 1
+test lsearch-2.9 {search modes} {
+ lsearch -glob {b.x ^bc xy bcx} ^bc
+} 1
+test lsearch-2.10 {search modes} -returnCodes error -body {
+ lsearch -glib {b.x bx xy bcx} b.x
+} -result {bad option "-glib": must be -all, -ascii, -bisect, -decreasing, -dictionary, -exact, -glob, -increasing, -index, -inline, -integer, -nocase, -not, -real, -regexp, -sorted, -start, or -subindices}
+test lsearch-2.11 {search modes with -nocase} {
+ lsearch -exact -nocase {a b c A B C} A
+} 0
+test lsearch-2.12 {search modes with -nocase} {
+ lsearch -glob -nocase {a b c A B C} A*
+} 0
+test lsearch-2.13 {search modes with -nocase} {
+ lsearch -regexp -nocase {a b c A B C} ^A\$
+} 0
+test lsearch-2.14 {search modes without -nocase} {
+ lsearch -exact {a b c A B C} A
+} 3
+test lsearch-2.15 {search modes without -nocase} {
+ lsearch -glob {a b c A B C} A*
+} 3
+test lsearch-2.16 {search modes without -nocase} {
+ lsearch -regexp {a b c A B C} ^A\$
+} 3
+
+test lsearch-3.1 {lsearch errors} -returnCodes error -body {
+ lsearch
+} -result {wrong # args: should be "lsearch ?-option value ...? list pattern"}
+test lsearch-3.2 {lsearch errors} -returnCodes error -body {
+ lsearch a
+} -result {wrong # args: should be "lsearch ?-option value ...? list pattern"}
+test lsearch-3.3 {lsearch errors} -returnCodes error -body {
+ lsearch a b c
+} -result {bad option "a": must be -all, -ascii, -bisect, -decreasing, -dictionary, -exact, -glob, -increasing, -index, -inline, -integer, -nocase, -not, -real, -regexp, -sorted, -start, or -subindices}
+test lsearch-3.4 {lsearch errors} -returnCodes error -body {
+ lsearch a b c d
+} -result {bad option "a": must be -all, -ascii, -bisect, -decreasing, -dictionary, -exact, -glob, -increasing, -index, -inline, -integer, -nocase, -not, -real, -regexp, -sorted, -start, or -subindices}
+test lsearch-3.5 {lsearch errors} -returnCodes error -body {
+ lsearch "\{" b
+} -result {unmatched open brace in list}
+test lsearch-3.6 {lsearch errors} -returnCodes error -body {
+ lsearch -index a b
+} -result {"-index" option must be followed by list index}
+test lsearch-3.7 {lsearch errors} -returnCodes error -body {
+ lsearch -subindices -exact a b
+} -result {-subindices cannot be used without -index option}
+
+test lsearch-4.1 {binary data} {
+ lsearch -exact [list foo one\000two bar] bar
+} 2
+test lsearch-4.2 {binary data} {
+ set x one
+ append x \x00
+ append x two
+ lsearch -exact [list foo one\000two bar] $x
+} 1
+
+# Make a sorted list
+set l {}
+set l2 {}
+for {set i 0} {$i < 100} {incr i} {
+ lappend l $i
+ lappend l2 [expr {double($i)/2}]
+}
+set increasingIntegers [lsort -integer $l]
+set decreasingIntegers [lsort -decreasing -integer $l]
+set increasingDoubles [lsort -real $l2]
+set decreasingDoubles [lsort -decreasing -real $l2]
+set increasingStrings [lsort {48 6a 18b 22a 21aa 35 36}]
+set decreasingStrings [lsort -decreasing {48 6a 18b 22a 21aa 35 36}]
+set increasingDictionary [lsort -dictionary {48 6a 18b 22a 21aa 35 36}]
+set decreasingDictionary [lsort -dictionary -decreasing $increasingDictionary]
+
+set l {}
+for {set i 0} {$i < 10} {incr i} {
+ lappend l $i $i $i $i $i
+}
+set repeatingIncreasingIntegers [lsort -integer $l]
+set repeatingDecreasingIntegers [lsort -integer -decreasing $l]
+
+test lsearch-5.1 {binary search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -integer -sorted $increasingIntegers $i]
+ }
+ set res
+} $increasingIntegers
+test lsearch-5.2 {binary search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -integer -decreasing -sorted \
+ $decreasingIntegers $i]
+ }
+ set res
+} $decreasingIntegers
+test lsearch-5.3 {binary search finds leftmost occurances} {
+ set res {}
+ for {set i 0} {$i < 10} {incr i} {
+ lappend res [lsearch -integer -sorted $repeatingIncreasingIntegers $i]
+ }
+ set res
+} [list 0 5 10 15 20 25 30 35 40 45]
+test lsearch-5.4 {binary search -decreasing finds leftmost occurances} {
+ set res {}
+ for {set i 9} {$i >= 0} {incr i -1} {
+ lappend res [lsearch -sorted -integer -decreasing \
+ $repeatingDecreasingIntegers $i]
+ }
+ set res
+} [list 0 5 10 15 20 25 30 35 40 45]
+
+test lsearch-6.1 {integer search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -exact -integer $increasingIntegers $i]
+ }
+ set res
+} [lrange $increasingIntegers 0 99]
+test lsearch-6.2 {decreasing integer search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -exact -integer -decreasing \
+ $decreasingIntegers $i]
+ }
+ set res
+} [lrange $decreasingIntegers 0 99]
+test lsearch-6.3 {sorted integer search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -sorted -integer $increasingIntegers $i]
+ }
+ set res
+} [lrange $increasingIntegers 0 99]
+test lsearch-6.4 {sorted decreasing integer search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -integer -sorted -decreasing \
+ $decreasingIntegers $i]
+ }
+ set res
+} [lrange $decreasingIntegers 0 99]
+
+test lsearch-7.1 {double search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -exact -real $increasingDoubles \
+ [expr {double($i)/2}]]
+ }
+ set res
+} [lrange $increasingIntegers 0 99]
+test lsearch-7.2 {decreasing double search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -exact -real -decreasing \
+ $decreasingDoubles [expr {double($i)/2}]]
+ }
+ set res
+} [lrange $decreasingIntegers 0 99]
+test lsearch-7.3 {sorted double search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -sorted -real \
+ $increasingDoubles [expr {double($i)/2}]]
+ }
+ set res
+} [lrange $increasingIntegers 0 99]
+test lsearch-7.4 {sorted decreasing double search} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -sorted -real -decreasing \
+ $decreasingDoubles [expr {double($i)/2}]]
+ }
+ set res
+} [lrange $decreasingIntegers 0 99]
+
+test lsearch-8.1 {dictionary search} {
+ set res {}
+ foreach val {6a 18b 21aa 22a 35 36 48} {
+ lappend res [lsearch -exact -dictionary $increasingDictionary $val]
+ }
+ set res
+} [list 0 1 2 3 4 5 6]
+test lsearch-8.2 {decreasing dictionary search} {
+ set res {}
+ foreach val {6a 18b 21aa 22a 35 36 48} {
+ lappend res [lsearch -exact -dictionary $decreasingDictionary $val]
+ }
+ set res
+} [list 6 5 4 3 2 1 0]
+test lsearch-8.3 {sorted dictionary search} {
+ set res {}
+ foreach val {6a 18b 21aa 22a 35 36 48} {
+ lappend res [lsearch -sorted -dictionary $increasingDictionary $val]
+ }
+ set res
+} [list 0 1 2 3 4 5 6]
+test lsearch-8.4 {decreasing sorted dictionary search} {
+ set res {}
+ foreach val {6a 18b 21aa 22a 35 36 48} {
+ lappend res [lsearch -decreasing -sorted -dictionary \
+ $decreasingDictionary $val]
+ }
+ set res
+} [list 6 5 4 3 2 1 0]
+
+test lsearch-9.1 {ascii search} {
+ set res {}
+ foreach val {18b 21aa 22a 35 36 48 6a} {
+ lappend res [lsearch -exact -ascii $increasingStrings $val]
+ }
+ set res
+} [list 0 1 2 3 4 5 6]
+test lsearch-9.2 {decreasing ascii search} {
+ set res {}
+ foreach val {18b 21aa 22a 35 36 48 6a} {
+ lappend res [lsearch -exact -ascii $decreasingStrings $val]
+ }
+ set res
+} [list 6 5 4 3 2 1 0]
+test lsearch-9.3 {sorted ascii search} {
+ set res {}
+ foreach val {18b 21aa 22a 35 36 48 6a} {
+ lappend res [lsearch -sorted -ascii $increasingStrings $val]
+ }
+ set res
+} [list 0 1 2 3 4 5 6]
+test lsearch-9.4 {decreasing sorted ascii search} {
+ set res {}
+ foreach val {18b 21aa 22a 35 36 48 6a} {
+ lappend res [lsearch -decreasing -sorted -ascii \
+ $decreasingStrings $val]
+ }
+ set res
+} [list 6 5 4 3 2 1 0]
+
+test lsearch-10.1 {offset searching} {
+ lsearch -start 2 {a b c a b c} a
+} 3
+test lsearch-10.2 {offset searching} {
+ lsearch -start 2 {a b c d e f} a
+} -1
+test lsearch-10.3 {offset searching} {
+ lsearch -start end-4 {a b c a b c} a
+} 3
+test lsearch-10.4 {offset searching} -returnCodes error -body {
+ lsearch -start foobar {a b c a b c} a
+} -result {bad index "foobar": must be integer?[+-]integer? or end?[+-]integer?}
+test lsearch-10.5 {offset searching} -returnCodes error -body {
+ lsearch -start 1 2
+} -result {missing starting index}
+test lsearch-10.6 {binary search with offset} {
+ set res {}
+ for {set i 0} {$i < 100} {incr i} {
+ lappend res [lsearch -integer -start 2 -sorted $increasingIntegers $i]
+ }
+ set res
+} [concat -1 -1 [lrange $increasingIntegers 2 end]]
+test lsearch-10.7 {offset searching with an empty list} {
+ # Stop bug #694232 from reocurring
+ lsearch -start 0 {} x
+} -1
+test lsearch-10.8 {offset searching past the end of the list} {
+ # Stop [Bug 1374778] from reoccurring
+ lsearch -start 10 {a b c} c
+} -1
+test lsearch-10.9 {offset searching past the end of the list} {
+ # Stop [Bug 1374778] from reoccurring
+ lsearch -start 10 -all {a b c} c
+} {}
+test lsearch-10.10 {offset searching past the end of the list} {
+ # Stop [Bug 1374778] from reoccurring
+ lsearch -start 10 -inline {a b c} c
+} {}
+
+test lsearch-11.1 {negated searches} {
+ lsearch -not {a a a b a a a} a
+} 3
+test lsearch-11.2 {negated searches} {
+ lsearch -not {a a a a a a a} a
+} -1
+
+test lsearch-12.1 {return values instead of indices} {
+ lsearch -glob -inline {a1 b2 c3 d4} c*
+} c3
+test lsearch-12.2 {return values instead of indices} {
+ lsearch -glob -inline {a1 b2 c3 d4} e*
+} {}
+
+test lsearch-13.1 {search for all matches} {
+ lsearch -all {a b a c a d} 1
+} {}
+test lsearch-13.2 {search for all matches} {
+ lsearch -all {a b a c a d} a
+} {0 2 4}
+test lsearch-13.3 {search for all matches with -nocase} {
+ lsearch -all -exact -nocase {a b c A B C} A
+} {0 3}
+test lsearch-13.4 {search for all matches with -nocase} {
+ lsearch -all -glob -nocase {a b c A B C} A*
+} {0 3}
+test lsearch-13.5 {search for all matches with -nocase} {
+ lsearch -all -regexp -nocase {a b c A B C} ^A\$
+} {0 3}
+
+test lsearch-14.1 {combinations: -all and -inline} {
+ lsearch -all -inline -glob {a1 b2 a3 c4 a5 d6} a*
+} {a1 a3 a5}
+test lsearch-14.2 {combinations: -all, -inline and -not} {
+ lsearch -all -inline -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {b2 c4 d6}
+test lsearch-14.3 {combinations: -all and -not} {
+ lsearch -all -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {1 3 5}
+test lsearch-14.4 {combinations: -inline and -not} {
+ lsearch -inline -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {b2}
+test lsearch-14.5 {combinations: -start, -all and -inline} {
+ lsearch -start 2 -all -inline -glob {a1 b2 a3 c4 a5 d6} a*
+} {a3 a5}
+test lsearch-14.6 {combinations: -start, -all, -inline and -not} {
+ lsearch -start 2 -all -inline -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {c4 d6}
+test lsearch-14.7 {combinations: -start, -all and -not} {
+ lsearch -start 2 -all -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {3 5}
+test lsearch-14.8 {combinations: -start, -inline and -not} {
+ lsearch -start 2 -inline -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {c4}
+
+test lsearch-15.1 {make sure no shimmering occurs} {
+ set x [expr int(sin(0))]
+ lsearch -start $x $x $x
+} 0
+
+test lsearch-16.1 {lsearch -regexp shared object} {
+ set str a
+ lsearch -regexp $str $str
+} 0
+# Bug 1366683
+test lsearch-16.2 {lsearch -regexp allows internal backrefs} {
+ lsearch -regexp {a aa b} {(.)\1}
+} 1
+
+test lsearch-17.1 {lsearch -index option, basic functionality} {
+ lsearch -index 1 {{a c} {a b} {a a}} a
+} 2
+test lsearch-17.2 {lsearch -index option, basic functionality} {
+ lsearch -index 1 -exact {{a c} {a b} {a a}} a
+} 2
+test lsearch-17.3 {lsearch -index option, basic functionality} {
+ lsearch -index 1 -glob {{ab cb} {ab bb} {ab ab}} b*
+} 1
+test lsearch-17.4 {lsearch -index option, basic functionality} {
+ lsearch -index 1 -regexp {{ab cb} {ab bb} {ab ab}} {[cb]b}
+} 0
+test lsearch-17.5 {lsearch -index option, basic functionality} {
+ lsearch -all -index 0 -exact {{a c} {a b} {d a}} a
+} {0 1}
+test lsearch-17.6 {lsearch -index option, basic functionality} {
+ lsearch -all -index 1 -glob {{ab cb} {ab bb} {db bx}} b*
+} {1 2}
+test lsearch-17.7 {lsearch -index option, basic functionality} {
+ lsearch -all -index 1 -regexp {{ab cb} {ab bb} {ab ab}} {[cb]b}
+} {0 1}
+
+test lsearch-18.1 {lsearch -index option, list as index basic functionality} {
+ lsearch -index {0 0} {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a
+} 1
+test lsearch-18.2 {lsearch -index option, list as index basic functionality} {
+ lsearch -index {2 0} -exact {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a
+} 0
+test lsearch-18.3 {lsearch -index option, list as index basic functionality} {
+ lsearch -index {1 1} -glob {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} b*
+} 0
+test lsearch-18.4 {lsearch -index option, list as index basic functionality} {
+ lsearch -index {0 1} -regexp {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} {[cb]b}
+} 0
+test lsearch-18.5 {lsearch -index option, list as index basic functionality} {
+ lsearch -all -index {0 0} -exact {{{a c} {a b} {d a}} {{a c} {a b} {d a}}} a
+} {0 1}
+
+test lsearch-19.1 {lsearch -sunindices option} {
+ lsearch -subindices -index {0 0} {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a
+} {1 0 0}
+test lsearch-19.2 {lsearch -sunindices option} {
+ lsearch -subindices -index {2 0} -exact {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a
+} {0 2 0}
+test lsearch-19.3 {lsearch -sunindices option} {
+ lsearch -subindices -index {1 1} -glob {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} b*
+} {0 1 1}
+test lsearch-19.4 {lsearch -sunindices option} {
+ lsearch -subindices -index {0 1} -regexp {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} {[cb]b}
+} {0 0 1}
+test lsearch-19.5 {lsearch -sunindices option} {
+ lsearch -subindices -all -index {0 0} -exact {{{a c} {a b} {d a}} {{a c} {a b} {d a}}} a
+} {{0 0 0} {1 0 0}}
+
+test lsearch-20.1 {lsearch -index option, index larger than sublists} -body {
+ lsearch -index 2 {{a c} {a b} {a a}} a
+} -returnCodes error -result {element 2 missing from sublist "a c"}
+test lsearch-20.2 {lsearch -index option, malformed index} -body {
+ lsearch -index foo {{a c} {a b} {a a}} a
+} -returnCodes error -result {bad index "foo": must be integer?[+-]integer? or end?[+-]integer?}
+test lsearch-20.3 {lsearch -index option, malformed index} -body {
+ lsearch -index \{ {{a c} {a b} {a a}} a
+} -returnCodes error -result {unmatched open brace in list}
+
+test lsearch-21.1 {lsearch shimmering crash} {
+ set x 0
+ lsearch -exact -integer $x $x
+} 0
+test lsearch-21.2 {lsearch shimmering crash} {
+ set x 0.5
+ lsearch -exact -real $x $x
+} 0
+
+test lsearch-22.1 {lsearch -bisect} -setup {
+ set res {}
+} -body {
+ foreach i {0 1 5 6 7 8 15 16} {
+ lappend res [lsearch -bisect -integer {1 4 5 7 9 15} $i]
+ }
+ return $res
+} -result {-1 0 2 2 3 3 5 5}
+test lsearch-22.2 {lsearch -bisect, last of equals} -setup {
+ set res {}
+} -body {
+ foreach i {0 1 2 3} {
+ lappend res [lsearch -bisect -integer {0 0 1 1 1 2 2 2 3 3 3} $i]
+ }
+ return $res
+} -result {1 4 7 10}
+test lsearch-22.3 {lsearch -bisect decreasing order} -setup {
+ set res {}
+} -body {
+ foreach i {0 1 5 6 7 8 15 16} {
+ lappend res [lsearch -bisect -integer -decreasing {15 9 7 5 4 1} $i]
+ }
+ return $res
+} -result {5 5 3 2 2 1 0 -1}
+test lsearch-22.4 {lsearch -bisect, last of equals, decreasing} -setup {
+ set res {}
+} -body {
+ foreach i {0 1 2 3} {
+ lappend res [lsearch -bisect -integer -decreasing \
+ {3 3 3 2 2 2 1 1 1 0 0} $i]
+ }
+ return $res
+} -result {10 8 5 2}
+test lsearch-22.5 {lsearch -bisect, all equal} {
+ lsearch -bisect -integer {5 5 5 5} 5
+} {3}
+test lsearch-22.6 {lsearch -sorted, all equal} {
+ lsearch -sorted -integer {5 5 5 5} 5
+} {0}
+
+# cleanup
+catch {unset res}
+catch {unset increasingIntegers}
+catch {unset decreasingIntegers}
+catch {unset increasingDoubles}
+catch {unset decreasingDoubles}
+catch {unset increasingStrings}
+catch {unset decreasingStrings}
+catch {unset increasingDictionary}
+catch {unset decreasingDictionary}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/lset.test b/pkgs/msgcat/tests/lset.test
new file mode 100644
index 0000000..3f4914d
--- /dev/null
+++ b/pkgs/msgcat/tests/lset.test
@@ -0,0 +1,478 @@
+# This file is a -*- tcl -*- test script
+
+# Commands covered: lset
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 2001 by 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+proc failTrace {name1 name2 op} {
+ error "trace failed"
+}
+
+testConstraint testevalex [llength [info commands testevalex]]
+
+set noRead {}
+trace add variable noRead read failTrace
+set noWrite {a b c}
+trace add variable noWrite write failTrace
+
+test lset-1.1 {lset, not compiled, arg count} testevalex {
+ list [catch {testevalex lset} msg] $msg
+} "1 {wrong \# args: should be \"lset listVar ?index? ?index ...? value\"}"
+test lset-1.2 {lset, not compiled, no such var} testevalex {
+ list [catch {testevalex {lset noSuchVar 0 {}}} msg] $msg
+} "1 {can't read \"noSuchVar\": no such variable}"
+test lset-1.3 {lset, not compiled, var not readable} testevalex {
+ list [catch {testevalex {lset noRead 0 {}}} msg] $msg
+} "1 {can't read \"noRead\": trace failed}"
+
+test lset-2.1 {lset, not compiled, 3 args, second arg a plain index} testevalex {
+ set x {0 1 2}
+ list [testevalex {lset x 0 3}] $x
+} {{3 1 2} {3 1 2}}
+test lset-2.2 {lset, not compiled, 3 args, second arg neither index nor list} testevalex {
+ set x {0 1 2}
+ list [catch {
+ testevalex {lset x {{bad}1} 3}
+ } msg] $msg
+} {1 {bad index "{bad}1": must be integer?[+-]integer? or end?[+-]integer?}}
+
+test lset-3.1 {lset, not compiled, 3 args, data duplicated} testevalex {
+ set x {0 1 2}
+ list [testevalex {lset x 0 $x}] $x
+} {{{0 1 2} 1 2} {{0 1 2} 1 2}}
+test lset-3.2 {lset, not compiled, 3 args, data duplicated} testevalex {
+ set x {0 1}
+ set y $x
+ list [testevalex {lset x 0 2}] $x $y
+} {{2 1} {2 1} {0 1}}
+test lset-3.3 {lset, not compiled, 3 args, data duplicated} testevalex {
+ set x {0 1}
+ set y $x
+ list [testevalex {lset x 0 $x}] $x $y
+} {{{0 1} 1} {{0 1} 1} {0 1}}
+test lset-3.4 {lset, not compiled, 3 args, data duplicated} testevalex {
+ set x {0 1 2}
+ list [testevalex {lset x [list 0] $x}] $x
+} {{{0 1 2} 1 2} {{0 1 2} 1 2}}
+test lset-3.5 {lset, not compiled, 3 args, data duplicated} testevalex {
+ set x {0 1}
+ set y $x
+ list [testevalex {lset x [list 0] 2}] $x $y
+} {{2 1} {2 1} {0 1}}
+test lset-3.6 {lset, not compiled, 3 args, data duplicated} testevalex {
+ set x {0 1}
+ set y $x
+ list [testevalex {lset x [list 0] $x}] $x $y
+} {{{0 1} 1} {{0 1} 1} {0 1}}
+
+test lset-4.1 {lset, not compiled, 3 args, not a list} testevalex {
+ set a "x \{"
+ list [catch {
+ testevalex {lset a [list 0] y}
+ } msg] $msg
+} {1 {unmatched open brace in list}}
+test lset-4.2 {lset, not compiled, 3 args, bad index} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a [list 2a2] w}
+ } msg] $msg
+} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lset-4.3 {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a [list -1] w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.4 {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a [list 4] w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.5a {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a [list end--2] w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.5b {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a [list end+2] w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.6 {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a [list end-3] w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.7 {lset, not compiled, 3 args, not a list} testevalex {
+ set a "x \{"
+ list [catch {
+ testevalex {lset a 0 y}
+ } msg] $msg
+} {1 {unmatched open brace in list}}
+test lset-4.8 {lset, not compiled, 3 args, bad index} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a 2a2 w}
+ } msg] $msg
+} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lset-4.9 {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a -1 w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.10 {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a 4 w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.11a {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a end--2 w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.11 {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a end+2 w}
+ } msg] $msg
+} {1 {list index out of range}}
+test lset-4.12 {lset, not compiled, 3 args, index out of range} testevalex {
+ set a {x y z}
+ list [catch {
+ testevalex {lset a end-3 w}
+ } msg] $msg
+} {1 {list index out of range}}
+
+test lset-5.1 {lset, not compiled, 3 args, can't set variable} testevalex {
+ list [catch {
+ testevalex {lset noWrite 0 d}
+ } msg] $msg $noWrite
+} {1 {can't set "noWrite": trace failed} {d b c}}
+test lset-5.2 {lset, not compiled, 3 args, can't set variable} testevalex {
+ list [catch {
+ testevalex {lset noWrite [list 0] d}
+ } msg] $msg $noWrite
+} {1 {can't set "noWrite": trace failed} {d b c}}
+
+test lset-6.1 {lset, not compiled, 3 args, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a 0 a}] $a
+} {{a y z} {a y z}}
+test lset-6.2 {lset, not compiled, 3 args, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a [list 0] a}] $a
+} {{a y z} {a y z}}
+test lset-6.3 {lset, not compiled, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a 2 a}] $a
+} {{x y a} {x y a}}
+test lset-6.4 {lset, not compiled, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a [list 2] a}] $a
+} {{x y a} {x y a}}
+test lset-6.5 {lset, not compiled, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a end a}] $a
+} {{x y a} {x y a}}
+test lset-6.6 {lset, not compiled, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a [list end] a}] $a
+} {{x y a} {x y a}}
+test lset-6.7 {lset, not compiled, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a end-0 a}] $a
+} {{x y a} {x y a}}
+test lset-6.8 {lset, not compiled, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a [list end-0] a}] $a
+} {{x y a} {x y a}}
+test lset-6.9 {lset, not compiled, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a end-2 a}] $a
+} {{a y z} {a y z}}
+test lset-6.10 {lset, not compiled, 1-d list basics} testevalex {
+ set a {x y z}
+ list [testevalex {lset a [list end-2] a}] $a
+} {{a y z} {a y z}}
+
+test lset-7.1 {lset, not compiled, data sharing} testevalex {
+ set a 0
+ list [testevalex {lset a $a {gag me}}] $a
+} {{{gag me}} {{gag me}}}
+test lset-7.2 {lset, not compiled, data sharing} testevalex {
+ set a [list 0]
+ list [testevalex {lset a $a {gag me}}] $a
+} {{{gag me}} {{gag me}}}
+test lset-7.3 {lset, not compiled, data sharing} testevalex {
+ set a {x y}
+ list [testevalex {lset a 0 $a}] $a
+} {{{x y} y} {{x y} y}}
+test lset-7.4 {lset, not compiled, data sharing} testevalex {
+ set a {x y}
+ list [testevalex {lset a [list 0] $a}] $a
+} {{{x y} y} {{x y} y}}
+test lset-7.5 {lset, not compiled, data sharing} testevalex {
+ set n 0
+ set a {x y}
+ list [testevalex {lset a $n $n}] $a $n
+} {{0 y} {0 y} 0}
+test lset-7.6 {lset, not compiled, data sharing} testevalex {
+ set n [list 0]
+ set a {x y}
+ list [testevalex {lset a $n $n}] $a $n
+} {{0 y} {0 y} 0}
+test lset-7.7 {lset, not compiled, data sharing} testevalex {
+ set n 0
+ set a [list $n $n]
+ list [testevalex {lset a $n 1}] $a $n
+} {{1 0} {1 0} 0}
+test lset-7.8 {lset, not compiled, data sharing} testevalex {
+ set n [list 0]
+ set a [list $n $n]
+ list [testevalex {lset a $n 1}] $a $n
+} {{1 0} {1 0} 0}
+test lset-7.9 {lset, not compiled, data sharing} testevalex {
+ set a 0
+ list [testevalex {lset a $a $a}] $a
+} {0 0}
+test lset-7.10 {lset, not compiled, data sharing} testevalex {
+ set a [list 0]
+ list [testevalex {lset a $a $a}] $a
+} {0 0}
+
+test lset-8.1 {lset, not compiled, malformed sublist} testevalex {
+ set a [list "a \{" b]
+ list [catch {testevalex {lset a 0 1 c}} msg] $msg
+} {1 {unmatched open brace in list}}
+test lset-8.2 {lset, not compiled, malformed sublist} testevalex {
+ set a [list "a \{" b]
+ list [catch {testevalex {lset a {0 1} c}} msg] $msg
+} {1 {unmatched open brace in list}}
+test lset-8.3 {lset, not compiled, bad second index} testevalex {
+ set a {{b c} {d e}}
+ list [catch {testevalex {lset a 0 2a2 f}} msg] $msg
+} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lset-8.4 {lset, not compiled, bad second index} testevalex {
+ set a {{b c} {d e}}
+ list [catch {testevalex {lset a {0 2a2} f}} msg] $msg
+} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lset-8.5 {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a 2 -1 h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.6 {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a {2 -1} h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.7 {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a 2 3 h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.8 {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a {2 3} h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.9a {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a 2 end--2 h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.9b {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a 2 end+2 h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.10a {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a {2 end--2} h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.10b {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a {2 end+2} h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.11 {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a 2 end-2 h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.12 {lset, not compiled, second index out of range} testevalex {
+ set a {{b c} {d e} {f g}}
+ list [catch {testevalex {lset a {2 end-2} h}} msg] $msg
+} {1 {list index out of range}}
+
+test lset-9.1 {lset, not compiled, entire variable} testevalex {
+ set a x
+ list [testevalex {lset a y}] $a
+} {y y}
+test lset-9.2 {lset, not compiled, entire variable} testevalex {
+ set a x
+ list [testevalex {lset a {} y}] $a
+} {y y}
+
+test lset-10.1 {lset, not compiled, shared data} testevalex {
+ set row {p q}
+ set a [list $row $row]
+ list [testevalex {lset a 0 0 x}] $a
+} {{{x q} {p q}} {{x q} {p q}}}
+test lset-10.2 {lset, not compiled, shared data} testevalex {
+ set row {p q}
+ set a [list $row $row]
+ list [testevalex {lset a {0 0} x}] $a
+} {{{x q} {p q}} {{x q} {p q}}}
+test lset-10.3 {lset, not compiled, shared data, [Bug 1333036]} testevalex {
+ set a [list [list p q] [list r s]]
+ set b $a
+ list [testevalex {lset b {0 0} x}] $a
+} {{{x q} {r s}} {{p q} {r s}}}
+
+test lset-11.1 {lset, not compiled, 2-d basics} testevalex {
+ set a {{b c} {d e}}
+ list [testevalex {lset a 0 0 f}] $a
+} {{{f c} {d e}} {{f c} {d e}}}
+test lset-11.2 {lset, not compiled, 2-d basics} testevalex {
+ set a {{b c} {d e}}
+ list [testevalex {lset a {0 0} f}] $a
+} {{{f c} {d e}} {{f c} {d e}}}
+test lset-11.3 {lset, not compiled, 2-d basics} testevalex {
+ set a {{b c} {d e}}
+ list [testevalex {lset a 0 1 f}] $a
+} {{{b f} {d e}} {{b f} {d e}}}
+test lset-11.4 {lset, not compiled, 2-d basics} testevalex {
+ set a {{b c} {d e}}
+ list [testevalex {lset a {0 1} f}] $a
+} {{{b f} {d e}} {{b f} {d e}}}
+test lset-11.5 {lset, not compiled, 2-d basics} testevalex {
+ set a {{b c} {d e}}
+ list [testevalex {lset a 1 0 f}] $a
+} {{{b c} {f e}} {{b c} {f e}}}
+test lset-11.6 {lset, not compiled, 2-d basics} testevalex {
+ set a {{b c} {d e}}
+ list [testevalex {lset a {1 0} f}] $a
+} {{{b c} {f e}} {{b c} {f e}}}
+test lset-11.7 {lset, not compiled, 2-d basics} testevalex {
+ set a {{b c} {d e}}
+ list [testevalex {lset a 1 1 f}] $a
+} {{{b c} {d f}} {{b c} {d f}}}
+test lset-11.8 {lset, not compiled, 2-d basics} testevalex {
+ set a {{b c} {d e}}
+ list [testevalex {lset a {1 1} f}] $a
+} {{{b c} {d f}} {{b c} {d f}}}
+
+test lset-12.0 {lset, not compiled, typical sharing pattern} testevalex {
+ set zero 0
+ set row [list $zero $zero $zero $zero]
+ set ident [list $row $row $row $row]
+ for { set i 0 } { $i < 4 } { incr i } {
+ testevalex {lset ident $i $i 1}
+ }
+ set ident
+} {{1 0 0 0} {0 1 0 0} {0 0 1 0} {0 0 0 1}}
+
+test lset-13.0 {lset, not compiled, shimmering hell} testevalex {
+ set a 0
+ list [testevalex {lset a $a $a $a $a {gag me}}] $a
+} {{{{{{gag me}}}}} {{{{{gag me}}}}}}
+test lset-13.1 {lset, not compiled, shimmering hell} testevalex {
+ set a [list 0]
+ list [testevalex {lset a $a $a $a $a {gag me}}] $a
+} {{{{{{gag me}}}}} {{{{{gag me}}}}}}
+test lset-13.2 {lset, not compiled, shimmering hell} testevalex {
+ set a [list 0 0 0 0]
+ list [testevalex {lset a $a {gag me}}] $a
+} {{{{{{gag me}}}} 0 0 0} {{{{{gag me}}}} 0 0 0}}
+
+test lset-14.1 {lset, not compiled, list args, is string rep preserved?} testevalex {
+ set a { { 1 2 } { 3 4 } }
+ catch { testevalex {lset a {1 5} 5} }
+ list $a [lindex $a 1]
+} "{ { 1 2 } { 3 4 } } { 3 4 }"
+test lset-14.2 {lset, not compiled, flat args, is string rep preserved?} testevalex {
+ set a { { 1 2 } { 3 4 } }
+ catch { testevalex {lset a 1 5 5} }
+ list $a [lindex $a 1]
+} "{ { 1 2 } { 3 4 } } { 3 4 }"
+
+testConstraint testobj [llength [info commands testobj]]
+test lset-15.1 {lset: shared intrep [Bug 1677512]} -setup {
+ teststringobj set 1 {{1 2} 3}
+ testobj convert 1 list
+ testobj duplicate 1 2
+ variable x [teststringobj get 1]
+ variable y [teststringobj get 2]
+ testobj freeallvars
+ set l [list $y z]
+ unset y
+} -constraints testobj -body {
+ lset l 0 0 0 5
+ lindex $x 0 0
+} -cleanup {
+ unset -nocomplain x l
+} -result 1
+
+test lset-16.1 {lset - grow a variable} testevalex {
+ set x {}
+ testevalex {lset x 0 {test 1}}
+ testevalex {lset x 1 {test 2}}
+ set x
+} {{test 1} {test 2}}
+test lset-16.2 {lset - multiple created sublists} testevalex {
+ set x {}
+ testevalex {lset x 0 0 {test 1}}
+} {{{test 1}}}
+test lset-16.3 {lset - sublists 3 deep} testevalex {
+ set x {}
+ testevalex {lset x 0 0 0 {test 1}}
+} {{{{test 1}}}}
+test lset-16.4 {lset - append to inner list} testevalex {
+ set x {test 1}
+ testevalex {lset x 1 1 2}
+ testevalex {lset x 1 2 3}
+ testevalex {lset x 1 2 1 4}
+} {test {1 2 {3 4}}}
+
+test lset-16.5 {lset - grow a variable} testevalex {
+ set x {}
+ testevalex {lset x end+1 {test 1}}
+ testevalex {lset x end+1 {test 2}}
+ set x
+} {{test 1} {test 2}}
+test lset-16.6 {lset - multiple created sublists} testevalex {
+ set x {}
+ testevalex {lset x end+1 end+1 {test 1}}
+} {{{test 1}}}
+test lset-16.7 {lset - sublists 3 deep} testevalex {
+ set x {}
+ testevalex {lset x end+1 end+1 end+1 {test 1}}
+} {{{{test 1}}}}
+test lset-16.8 {lset - append to inner list} testevalex {
+ set x {test 1}
+ testevalex {lset x end end+1 2}
+ testevalex {lset x end end+1 3}
+ testevalex {lset x end end end+1 4}
+} {test {1 2 {3 4}}}
+
+catch {unset noRead}
+catch {unset noWrite}
+catch {rename failTrace {}}
+catch {unset ::x}
+catch {unset ::y}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/lsetComp.test b/pkgs/msgcat/tests/lsetComp.test
new file mode 100755
index 0000000..6846cbf
--- /dev/null
+++ b/pkgs/msgcat/tests/lsetComp.test
@@ -0,0 +1,431 @@
+# This file is a -*- tcl -*- test script
+
+# Commands covered: lset
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 2001 by 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# Procedure to evaluate a script within a proc, to test compilation
+# functionality
+
+proc evalInProc { script } {
+ proc testProc {} $script
+ set status [catch {
+ testProc
+ } result]
+ rename testProc {}
+ return [list $status $result]
+}
+
+# Tests for the bytecode compilation of the 'lset' command
+
+test lsetComp-1.1 {lset, compiled, wrong \# args} {
+ evalInProc {
+ lset
+ }
+} "1 {wrong \# args: should be \"lset listVar ?index? ?index ...? value\"}"
+
+test lsetComp-2.1 {lset, compiled, list of args, not a simple var name} {
+ evalInProc {
+ set y x
+ set x {{1 2} {3 4}}
+ lset $y {1 1} 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.2 {lset, compiled, list of args, scalar on stack} {
+ evalInProc {
+ set ::x {{1 2} {3 4}}
+ lset ::x {1 1} 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.3 {lset, compiled, list of args, scalar, one-byte offset} {
+ evalInProc {
+ set x {{1 2} {3 4}}
+ lset x {1 1} 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.4 {lset, compiled, list of args, scalar, four-byte offset} {
+ evalInProc {
+ set x0 0; set x1 0; set x2 0; set x3 0;
+ set x4 0; set x5 0; set x6 0; set x7 0;
+ set x8 0; set x9 0; set x10 0; set x11 0;
+ set x12 0; set x13 0; set x14 0; set x15 0;
+ set x16 0; set x17 0; set x18 0; set x19 0;
+ set x20 0; set x21 0; set x22 0; set x23 0;
+ set x24 0; set x25 0; set x26 0; set x27 0;
+ set x28 0; set x29 0; set x30 0; set x31 0;
+ set x32 0; set x33 0; set x34 0; set x35 0;
+ set x36 0; set x37 0; set x38 0; set x39 0;
+ set x40 0; set x41 0; set x42 0; set x43 0;
+ set x44 0; set x45 0; set x46 0; set x47 0;
+ set x48 0; set x49 0; set x50 0; set x51 0;
+ set x52 0; set x53 0; set x54 0; set x55 0;
+ set x56 0; set x57 0; set x58 0; set x59 0;
+ set x60 0; set x61 0; set x62 0; set x63 0;
+ set x64 0; set x65 0; set x66 0; set x67 0;
+ set x68 0; set x69 0; set x70 0; set x71 0;
+ set x72 0; set x73 0; set x74 0; set x75 0;
+ set x76 0; set x77 0; set x78 0; set x79 0;
+ set x80 0; set x81 0; set x82 0; set x83 0;
+ set x84 0; set x85 0; set x86 0; set x87 0;
+ set x88 0; set x89 0; set x90 0; set x91 0;
+ set x92 0; set x93 0; set x94 0; set x95 0;
+ set x96 0; set x97 0; set x98 0; set x99 0;
+ set x100 0; set x101 0; set x102 0; set x103 0;
+ set x104 0; set x105 0; set x106 0; set x107 0;
+ set x108 0; set x109 0; set x110 0; set x111 0;
+ set x112 0; set x113 0; set x114 0; set x115 0;
+ set x116 0; set x117 0; set x118 0; set x119 0;
+ set x120 0; set x121 0; set x122 0; set x123 0;
+ set x124 0; set x125 0; set x126 0; set x127 0;
+ set x128 0; set x129 0; set x130 0; set x131 0;
+ set x132 0; set x133 0; set x134 0; set x135 0;
+ set x136 0; set x137 0; set x138 0; set x139 0;
+ set x140 0; set x141 0; set x142 0; set x143 0;
+ set x144 0; set x145 0; set x146 0; set x147 0;
+ set x148 0; set x149 0; set x150 0; set x151 0;
+ set x152 0; set x153 0; set x154 0; set x155 0;
+ set x156 0; set x157 0; set x158 0; set x159 0;
+ set x160 0; set x161 0; set x162 0; set x163 0;
+ set x164 0; set x165 0; set x166 0; set x167 0;
+ set x168 0; set x169 0; set x170 0; set x171 0;
+ set x172 0; set x173 0; set x174 0; set x175 0;
+ set x176 0; set x177 0; set x178 0; set x179 0;
+ set x180 0; set x181 0; set x182 0; set x183 0;
+ set x184 0; set x185 0; set x186 0; set x187 0;
+ set x188 0; set x189 0; set x190 0; set x191 0;
+ set x192 0; set x193 0; set x194 0; set x195 0;
+ set x196 0; set x197 0; set x198 0; set x199 0;
+ set x200 0; set x201 0; set x202 0; set x203 0;
+ set x204 0; set x205 0; set x206 0; set x207 0;
+ set x208 0; set x209 0; set x210 0; set x211 0;
+ set x212 0; set x213 0; set x214 0; set x215 0;
+ set x216 0; set x217 0; set x218 0; set x219 0;
+ set x220 0; set x221 0; set x222 0; set x223 0;
+ set x224 0; set x225 0; set x226 0; set x227 0;
+ set x228 0; set x229 0; set x230 0; set x231 0;
+ set x232 0; set x233 0; set x234 0; set x235 0;
+ set x236 0; set x237 0; set x238 0; set x239 0;
+ set x240 0; set x241 0; set x242 0; set x243 0;
+ set x244 0; set x245 0; set x246 0; set x247 0;
+ set x248 0; set x249 0; set x250 0; set x251 0;
+ set x252 0; set x253 0; set x254 0; set x255 0;
+ set x {{1 2} {3 4}}
+ lset x {1 1} 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.5 {lset, compiled, list of args, array on stack} {
+ evalInProc {
+ set ::y(0) {{1 2} {3 4}}
+ lset ::y(0) {1 1} 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.6 {lset, compiled, list of args, array, one-byte offset} {
+ evalInProc {
+ set y(0) {{1 2} {3 4}}
+ lset y(0) {1 1} 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.7 {lset, compiled, list of args, array, four-byte offset} {
+ evalInProc {
+ set x0 0; set x1 0; set x2 0; set x3 0;
+ set x4 0; set x5 0; set x6 0; set x7 0;
+ set x8 0; set x9 0; set x10 0; set x11 0;
+ set x12 0; set x13 0; set x14 0; set x15 0;
+ set x16 0; set x17 0; set x18 0; set x19 0;
+ set x20 0; set x21 0; set x22 0; set x23 0;
+ set x24 0; set x25 0; set x26 0; set x27 0;
+ set x28 0; set x29 0; set x30 0; set x31 0;
+ set x32 0; set x33 0; set x34 0; set x35 0;
+ set x36 0; set x37 0; set x38 0; set x39 0;
+ set x40 0; set x41 0; set x42 0; set x43 0;
+ set x44 0; set x45 0; set x46 0; set x47 0;
+ set x48 0; set x49 0; set x50 0; set x51 0;
+ set x52 0; set x53 0; set x54 0; set x55 0;
+ set x56 0; set x57 0; set x58 0; set x59 0;
+ set x60 0; set x61 0; set x62 0; set x63 0;
+ set x64 0; set x65 0; set x66 0; set x67 0;
+ set x68 0; set x69 0; set x70 0; set x71 0;
+ set x72 0; set x73 0; set x74 0; set x75 0;
+ set x76 0; set x77 0; set x78 0; set x79 0;
+ set x80 0; set x81 0; set x82 0; set x83 0;
+ set x84 0; set x85 0; set x86 0; set x87 0;
+ set x88 0; set x89 0; set x90 0; set x91 0;
+ set x92 0; set x93 0; set x94 0; set x95 0;
+ set x96 0; set x97 0; set x98 0; set x99 0;
+ set x100 0; set x101 0; set x102 0; set x103 0;
+ set x104 0; set x105 0; set x106 0; set x107 0;
+ set x108 0; set x109 0; set x110 0; set x111 0;
+ set x112 0; set x113 0; set x114 0; set x115 0;
+ set x116 0; set x117 0; set x118 0; set x119 0;
+ set x120 0; set x121 0; set x122 0; set x123 0;
+ set x124 0; set x125 0; set x126 0; set x127 0;
+ set x128 0; set x129 0; set x130 0; set x131 0;
+ set x132 0; set x133 0; set x134 0; set x135 0;
+ set x136 0; set x137 0; set x138 0; set x139 0;
+ set x140 0; set x141 0; set x142 0; set x143 0;
+ set x144 0; set x145 0; set x146 0; set x147 0;
+ set x148 0; set x149 0; set x150 0; set x151 0;
+ set x152 0; set x153 0; set x154 0; set x155 0;
+ set x156 0; set x157 0; set x158 0; set x159 0;
+ set x160 0; set x161 0; set x162 0; set x163 0;
+ set x164 0; set x165 0; set x166 0; set x167 0;
+ set x168 0; set x169 0; set x170 0; set x171 0;
+ set x172 0; set x173 0; set x174 0; set x175 0;
+ set x176 0; set x177 0; set x178 0; set x179 0;
+ set x180 0; set x181 0; set x182 0; set x183 0;
+ set x184 0; set x185 0; set x186 0; set x187 0;
+ set x188 0; set x189 0; set x190 0; set x191 0;
+ set x192 0; set x193 0; set x194 0; set x195 0;
+ set x196 0; set x197 0; set x198 0; set x199 0;
+ set x200 0; set x201 0; set x202 0; set x203 0;
+ set x204 0; set x205 0; set x206 0; set x207 0;
+ set x208 0; set x209 0; set x210 0; set x211 0;
+ set x212 0; set x213 0; set x214 0; set x215 0;
+ set x216 0; set x217 0; set x218 0; set x219 0;
+ set x220 0; set x221 0; set x222 0; set x223 0;
+ set x224 0; set x225 0; set x226 0; set x227 0;
+ set x228 0; set x229 0; set x230 0; set x231 0;
+ set x232 0; set x233 0; set x234 0; set x235 0;
+ set x236 0; set x237 0; set x238 0; set x239 0;
+ set x240 0; set x241 0; set x242 0; set x243 0;
+ set x244 0; set x245 0; set x246 0; set x247 0;
+ set x248 0; set x249 0; set x250 0; set x251 0;
+ set x252 0; set x253 0; set x254 0; set x255 0;
+ set y(0) {{1 2} {3 4}}
+ lset y(0) {1 1} 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.8 {lset, compiled, list of args, error } {
+ evalInProc {
+ set x { {1 2} {3 4} }
+ lset x {1 5} 5
+ }
+} "1 {list index out of range}"
+
+test lsetComp-2.9 {lset, compiled, list of args, error - is string preserved} {
+ set ::x { { 1 2 } { 3 4 } }
+ evalInProc {
+ lset ::x { 1 5 } 5
+ }
+ list $::x [lindex $::x 1]
+} "{ { 1 2 } { 3 4 } } { 3 4 }"
+
+test lsetComp-3.1 {lset, compiled, flat args, not a simple var name} {
+ evalInProc {
+ set y x
+ set x {{1 2} {3 4}}
+ lset $y 1 1 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.2 {lset, compiled, flat args, scalar on stack} {
+ evalInProc {
+ set ::x {{1 2} {3 4}}
+ lset ::x 1 1 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.3 {lset, compiled, flat args, scalar, one-byte offset} {
+ evalInProc {
+ set x {{1 2} {3 4}}
+ lset x 1 1 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.4 {lset, compiled, scalar, four-byte offset} {
+ evalInProc {
+ set x0 0; set x1 0; set x2 0; set x3 0;
+ set x4 0; set x5 0; set x6 0; set x7 0;
+ set x8 0; set x9 0; set x10 0; set x11 0;
+ set x12 0; set x13 0; set x14 0; set x15 0;
+ set x16 0; set x17 0; set x18 0; set x19 0;
+ set x20 0; set x21 0; set x22 0; set x23 0;
+ set x24 0; set x25 0; set x26 0; set x27 0;
+ set x28 0; set x29 0; set x30 0; set x31 0;
+ set x32 0; set x33 0; set x34 0; set x35 0;
+ set x36 0; set x37 0; set x38 0; set x39 0;
+ set x40 0; set x41 0; set x42 0; set x43 0;
+ set x44 0; set x45 0; set x46 0; set x47 0;
+ set x48 0; set x49 0; set x50 0; set x51 0;
+ set x52 0; set x53 0; set x54 0; set x55 0;
+ set x56 0; set x57 0; set x58 0; set x59 0;
+ set x60 0; set x61 0; set x62 0; set x63 0;
+ set x64 0; set x65 0; set x66 0; set x67 0;
+ set x68 0; set x69 0; set x70 0; set x71 0;
+ set x72 0; set x73 0; set x74 0; set x75 0;
+ set x76 0; set x77 0; set x78 0; set x79 0;
+ set x80 0; set x81 0; set x82 0; set x83 0;
+ set x84 0; set x85 0; set x86 0; set x87 0;
+ set x88 0; set x89 0; set x90 0; set x91 0;
+ set x92 0; set x93 0; set x94 0; set x95 0;
+ set x96 0; set x97 0; set x98 0; set x99 0;
+ set x100 0; set x101 0; set x102 0; set x103 0;
+ set x104 0; set x105 0; set x106 0; set x107 0;
+ set x108 0; set x109 0; set x110 0; set x111 0;
+ set x112 0; set x113 0; set x114 0; set x115 0;
+ set x116 0; set x117 0; set x118 0; set x119 0;
+ set x120 0; set x121 0; set x122 0; set x123 0;
+ set x124 0; set x125 0; set x126 0; set x127 0;
+ set x128 0; set x129 0; set x130 0; set x131 0;
+ set x132 0; set x133 0; set x134 0; set x135 0;
+ set x136 0; set x137 0; set x138 0; set x139 0;
+ set x140 0; set x141 0; set x142 0; set x143 0;
+ set x144 0; set x145 0; set x146 0; set x147 0;
+ set x148 0; set x149 0; set x150 0; set x151 0;
+ set x152 0; set x153 0; set x154 0; set x155 0;
+ set x156 0; set x157 0; set x158 0; set x159 0;
+ set x160 0; set x161 0; set x162 0; set x163 0;
+ set x164 0; set x165 0; set x166 0; set x167 0;
+ set x168 0; set x169 0; set x170 0; set x171 0;
+ set x172 0; set x173 0; set x174 0; set x175 0;
+ set x176 0; set x177 0; set x178 0; set x179 0;
+ set x180 0; set x181 0; set x182 0; set x183 0;
+ set x184 0; set x185 0; set x186 0; set x187 0;
+ set x188 0; set x189 0; set x190 0; set x191 0;
+ set x192 0; set x193 0; set x194 0; set x195 0;
+ set x196 0; set x197 0; set x198 0; set x199 0;
+ set x200 0; set x201 0; set x202 0; set x203 0;
+ set x204 0; set x205 0; set x206 0; set x207 0;
+ set x208 0; set x209 0; set x210 0; set x211 0;
+ set x212 0; set x213 0; set x214 0; set x215 0;
+ set x216 0; set x217 0; set x218 0; set x219 0;
+ set x220 0; set x221 0; set x222 0; set x223 0;
+ set x224 0; set x225 0; set x226 0; set x227 0;
+ set x228 0; set x229 0; set x230 0; set x231 0;
+ set x232 0; set x233 0; set x234 0; set x235 0;
+ set x236 0; set x237 0; set x238 0; set x239 0;
+ set x240 0; set x241 0; set x242 0; set x243 0;
+ set x244 0; set x245 0; set x246 0; set x247 0;
+ set x248 0; set x249 0; set x250 0; set x251 0;
+ set x252 0; set x253 0; set x254 0; set x255 0;
+ set x {{1 2} {3 4}}
+ lset x 1 1 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.5 {lset, compiled, flat args, array on stack} {
+ evalInProc {
+ set ::y(0) {{1 2} {3 4}}
+ lset ::y(0) 1 1 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.6 {lset, compiled, flat args, array, one-byte offset} {
+ evalInProc {
+ set y(0) {{1 2} {3 4}}
+ lset y(0) 1 1 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.7 {lset, compiled, flat args, array, four-byte offset} {
+ evalInProc {
+ set x0 0; set x1 0; set x2 0; set x3 0;
+ set x4 0; set x5 0; set x6 0; set x7 0;
+ set x8 0; set x9 0; set x10 0; set x11 0;
+ set x12 0; set x13 0; set x14 0; set x15 0;
+ set x16 0; set x17 0; set x18 0; set x19 0;
+ set x20 0; set x21 0; set x22 0; set x23 0;
+ set x24 0; set x25 0; set x26 0; set x27 0;
+ set x28 0; set x29 0; set x30 0; set x31 0;
+ set x32 0; set x33 0; set x34 0; set x35 0;
+ set x36 0; set x37 0; set x38 0; set x39 0;
+ set x40 0; set x41 0; set x42 0; set x43 0;
+ set x44 0; set x45 0; set x46 0; set x47 0;
+ set x48 0; set x49 0; set x50 0; set x51 0;
+ set x52 0; set x53 0; set x54 0; set x55 0;
+ set x56 0; set x57 0; set x58 0; set x59 0;
+ set x60 0; set x61 0; set x62 0; set x63 0;
+ set x64 0; set x65 0; set x66 0; set x67 0;
+ set x68 0; set x69 0; set x70 0; set x71 0;
+ set x72 0; set x73 0; set x74 0; set x75 0;
+ set x76 0; set x77 0; set x78 0; set x79 0;
+ set x80 0; set x81 0; set x82 0; set x83 0;
+ set x84 0; set x85 0; set x86 0; set x87 0;
+ set x88 0; set x89 0; set x90 0; set x91 0;
+ set x92 0; set x93 0; set x94 0; set x95 0;
+ set x96 0; set x97 0; set x98 0; set x99 0;
+ set x100 0; set x101 0; set x102 0; set x103 0;
+ set x104 0; set x105 0; set x106 0; set x107 0;
+ set x108 0; set x109 0; set x110 0; set x111 0;
+ set x112 0; set x113 0; set x114 0; set x115 0;
+ set x116 0; set x117 0; set x118 0; set x119 0;
+ set x120 0; set x121 0; set x122 0; set x123 0;
+ set x124 0; set x125 0; set x126 0; set x127 0;
+ set x128 0; set x129 0; set x130 0; set x131 0;
+ set x132 0; set x133 0; set x134 0; set x135 0;
+ set x136 0; set x137 0; set x138 0; set x139 0;
+ set x140 0; set x141 0; set x142 0; set x143 0;
+ set x144 0; set x145 0; set x146 0; set x147 0;
+ set x148 0; set x149 0; set x150 0; set x151 0;
+ set x152 0; set x153 0; set x154 0; set x155 0;
+ set x156 0; set x157 0; set x158 0; set x159 0;
+ set x160 0; set x161 0; set x162 0; set x163 0;
+ set x164 0; set x165 0; set x166 0; set x167 0;
+ set x168 0; set x169 0; set x170 0; set x171 0;
+ set x172 0; set x173 0; set x174 0; set x175 0;
+ set x176 0; set x177 0; set x178 0; set x179 0;
+ set x180 0; set x181 0; set x182 0; set x183 0;
+ set x184 0; set x185 0; set x186 0; set x187 0;
+ set x188 0; set x189 0; set x190 0; set x191 0;
+ set x192 0; set x193 0; set x194 0; set x195 0;
+ set x196 0; set x197 0; set x198 0; set x199 0;
+ set x200 0; set x201 0; set x202 0; set x203 0;
+ set x204 0; set x205 0; set x206 0; set x207 0;
+ set x208 0; set x209 0; set x210 0; set x211 0;
+ set x212 0; set x213 0; set x214 0; set x215 0;
+ set x216 0; set x217 0; set x218 0; set x219 0;
+ set x220 0; set x221 0; set x222 0; set x223 0;
+ set x224 0; set x225 0; set x226 0; set x227 0;
+ set x228 0; set x229 0; set x230 0; set x231 0;
+ set x232 0; set x233 0; set x234 0; set x235 0;
+ set x236 0; set x237 0; set x238 0; set x239 0;
+ set x240 0; set x241 0; set x242 0; set x243 0;
+ set x244 0; set x245 0; set x246 0; set x247 0;
+ set x248 0; set x249 0; set x250 0; set x251 0;
+ set x252 0; set x253 0; set x254 0; set x255 0;
+ set y(0) {{1 2} {3 4}}
+ lset y(0) 1 1 5
+ }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.8 {lset, compiled, flat args, error } {
+ evalInProc {
+ set x { {1 2} {3 4} }
+ lset x 1 5 5
+ }
+} "1 {list index out of range}"
+
+test lsetComp-3.9 {lset, compiled, flat args, error - is string preserved} {
+ set ::x { { 1 2 } { 3 4 } }
+ evalInProc {
+ lset ::x 1 5 5
+ }
+ list $::x [lindex $::x 1]
+} "{ { 1 2 } { 3 4 } } { 3 4 }"
+
+catch { rename evalInProc {} }
+catch { unset ::x }
+catch { unset ::y }
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/macOSXFCmd.test b/pkgs/msgcat/tests/macOSXFCmd.test
new file mode 100644
index 0000000..071f11b
--- /dev/null
+++ b/pkgs/msgcat/tests/macOSXFCmd.test
@@ -0,0 +1,181 @@
+# This file tests the tclMacOSXFCmd.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 2003 Tcl Core Team.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# These tests really need to be run from a writable directory, which
+# it is assumed [temporaryDirectory] is.
+set oldcwd [pwd]
+cd [temporaryDirectory]
+
+# check whether macosx file attributes are supported
+testConstraint macosxFileAttr 0
+if {[testConstraint unix] && $tcl_platform(os) eq "Darwin"} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ catch {
+ file attributes foo.test -creator
+ testConstraint macosxFileAttr 1
+ }
+ file delete -force -- foo.test
+}
+
+test macOSXFCmd-1.1 {MacOSXGetFileAttribute - file not found} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ list [catch {file attributes foo.test -creator} msg] $msg
+} {1 {could not read "foo.test": no such file or directory}}
+test macOSXFCmd-1.2 {MacOSXGetFileAttribute - creator} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -creator} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 {} {}}
+test macOSXFCmd-1.3 {MacOSXGetFileAttribute - type} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -type} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 {} {}}
+test macOSXFCmd-1.4 {MacOSXGetFileAttribute - hidden} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -hidden} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 0 {}}
+test macOSXFCmd-1.5 {MacOSXGetFileAttribute - rsrclength} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -rsrclength} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 0 {}}
+
+test macOSXFCmd-2.1 {MacOSXSetFileAttribute - file not found} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ list [catch {file attributes foo.test -creator FOOC} msg] $msg
+} {1 {could not read "foo.test": no such file or directory}}
+test macOSXFCmd-2.2 {MacOSXSetFileAttribute - creator} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -creator FOOC} msg] $msg \
+ [catch {file attributes foo.test -creator} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 {} 0 FOOC {}}
+test macOSXFCmd-2.3 {MacOSXSetFileAttribute - empty creator} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -creator {}} msg] $msg \
+ [catch {file attributes foo.test -creator} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 {} 0 {} {}}
+test macOSXFCmd-2.4 {MacOSXSetFileAttribute - type} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -type FOOT} msg] $msg \
+ [catch {file attributes foo.test -type} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 {} 0 FOOT {}}
+test macOSXFCmd-2.5 {MacOSXSetFileAttribute - empty type} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -type {}} msg] $msg \
+ [catch {file attributes foo.test -type} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 {} 0 {} {}}
+test macOSXFCmd-2.6 {MacOSXSetFileAttribute - hidden} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ list [catch {file attributes foo.test -hidden 1} msg] $msg \
+ [catch {file attributes foo.test -hidden} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 {} 0 1 {}}
+test macOSXFCmd-2.7 {MacOSXSetFileAttribute - rsrclength} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ close [open foo.test w]
+ catch {
+ set f [open foo.test/..namedfork/rsrc w]
+ fconfigure $f -translation lf -eofchar {}
+ puts -nonewline $f "foo"
+ close $f
+ }
+ list [catch {file attributes foo.test -rsrclength} msg] $msg \
+ [catch {file attributes foo.test -rsrclength 0} msg] $msg \
+ [catch {file attributes foo.test -rsrclength} msg] $msg \
+ [file delete -force -- foo.test]
+} {0 3 0 {} 0 0 {}}
+
+test macOSXFCmd-3.1 {MacOSXCopyFileAttributes} {macosxFileAttr notRoot} {
+ catch {file delete -force -- foo.test}
+ catch {file delete -force -- bar.test}
+ close [open foo.test w]
+ catch {
+ file attributes foo.test -creator FOOC -type FOOT -hidden 1
+ set f [open foo.test/..namedfork/rsrc w]
+ fconfigure $f -translation lf -eofchar {}
+ puts -nonewline $f "foo"
+ close $f
+ file copy foo.test bar.test
+ }
+ list [catch {file attributes bar.test -creator} msg] $msg \
+ [catch {file attributes bar.test -type} msg] $msg \
+ [catch {file attributes bar.test -hidden} msg] $msg \
+ [catch {file attributes bar.test -rsrclength} msg] $msg \
+ [file delete -force -- foo.test bar.test]
+} {0 FOOC 0 FOOT 0 1 0 3 {}}
+
+test macOSXFCmd-4.1 {TclMacOSXMatchType} {macosxFileAttr notRoot} {
+ file mkdir globtest
+ cd globtest
+ foreach f {bar baz foo inv inw .nv reg} {
+ catch {file delete -force -- $f.test}
+ close [open $f.test w]
+ }
+ catch {file delete -force -- dir.test}
+ file mkdir dir.test
+ catch {
+ file attributes bar.test -type FOOT
+ file attributes baz.test -creator FOOC -type FOOT
+ file attributes foo.test -creator FOOC
+ file attributes inv.test -hidden 1
+ file attributes inw.test -hidden 1 -type FOOT
+ file attributes dir.test -hidden 1
+ }
+ set res [list \
+ [catch {glob *.test} msg] $msg \
+ [catch {glob -types FOOT *.test} msg] $msg \
+ [catch {glob -types {{macintosh type FOOT}} *.test} msg] $msg \
+ [catch {glob -types FOOTT *.test} msg] $msg \
+ [catch {glob -types {{macintosh type FOOTT}} *.test} msg] $msg \
+ [catch {glob -types {{macintosh type {}}} *.test} msg] $msg \
+ [catch {glob -types {{macintosh creator FOOC}} *.test} msg] $msg \
+ [catch {glob -types {{macintosh creator FOOC} {macintosh type FOOT}} *.test} msg] $msg \
+ [catch {glob -types hidden *.test} msg] $msg \
+ [catch {glob -types {hidden FOOT} *.test} msg] $msg \
+ ]
+ cd ..
+ file delete -force globtest
+ set res
+} [list \
+ 0 {bar.test baz.test dir.test foo.test inv.test inw.test reg.test} \
+ 0 {bar.test baz.test inw.test} 0 {bar.test baz.test inw.test} \
+ 1 {bad argument to "-types": FOOTT} \
+ 1 {expected Macintosh OS type but got "FOOTT": } \
+ 0 {foo.test inv.test reg.test} 0 {baz.test foo.test} \
+ 0 baz.test 0 {.nv.test dir.test inv.test inw.test} \
+ 0 inw.test
+]
+
+# cleanup
+cd $oldcwd
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/macOSXLoad.test b/pkgs/msgcat/tests/macOSXLoad.test
new file mode 100644
index 0000000..12c77e0
--- /dev/null
+++ b/pkgs/msgcat/tests/macOSXLoad.test
@@ -0,0 +1,33 @@
+# Commands covered: load unload
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1995 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+set oldTSF $::tcltest::testSingleFile
+set ::tcltest::testSingleFile false
+
+if {[testConstraint unix] && $tcl_platform(os) eq "Darwin" &&
+ ![string match *pkga* [info loaded]]} {
+ # On Darwin, test .bundle (un)loading in addition to .dylib
+ set ext .bundle
+ source [file join [file dirname [info script]] load.test]
+ set ext .bundle
+ source [file join [file dirname [info script]] unload.test]
+ unset -nocomplain ext
+}
+
+set ::tcltest::testSingleFile $oldTSF
+unset oldTSF
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/main.test b/pkgs/msgcat/tests/main.test
new file mode 100644
index 0000000..f1dc7fd
--- /dev/null
+++ b/pkgs/msgcat/tests/main.test
@@ -0,0 +1,1297 @@
+# This file contains a collection of tests for generic/tclMain.c.
+
+if {[catch {package require tcltest 2.0.2}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2.0.2 required."
+ return
+}
+
+namespace eval ::tcl::test::main {
+ namespace import ::tcltest::*
+
+ # Is [exec] defined?
+ testConstraint exec [llength [info commands exec]]
+
+ # Is the Tcltest package loaded?
+ # - that is, the special C-coded testing commands in tclTest.c
+ # - tests use testing commands introduced in Tcltest 8.4
+ testConstraint Tcltest [expr {
+ [llength [package provide Tcltest]]
+ && [package vsatisfies [package provide Tcltest] 8.4]}]
+
+ # Procedure to simulate interactive typing of commands, line by line
+ proc type {chan script} {
+ foreach line [split $script \n] {
+ if {[catch {
+ puts $chan $line
+ flush $chan
+ }]} {
+ return
+ }
+ # Grrr... Behavior depends on this value.
+ after 1000
+ }
+ }
+
+ cd [temporaryDirectory]
+ # Tests Tcl_Main-1.*: variable initializations
+
+ test Tcl_Main-1.1 {
+ Tcl_Main: startup script - normal
+ } -constraints {
+ stdio
+ } -setup {
+ makeFile {puts [list $argv0 $argv $tcl_interactive]} script
+ catch {set f [open "|[list [interpreter] script]" r]}
+ } -body {
+ read $f
+ } -cleanup {
+ close $f
+ removeFile script
+ } -result [list script {} 0]\n
+
+ test Tcl_Main-1.2 {
+ Tcl_Main: startup script - can't begin with '-'
+ } -constraints {
+ stdio
+ } -setup {
+ makeFile {puts [list $argv0 $argv $tcl_interactive]} -script
+ catch {set f [open "|[list [interpreter] -script]" w+]}
+ } -body {
+ puts $f {puts [list $argv0 $argv $tcl_interactive]; exit}
+ flush $f
+ read $f
+ } -cleanup {
+ close $f
+ removeFile -script
+ } -result [list [interpreter] -script 0]\n
+
+ test Tcl_Main-1.3 {
+ } -constraints {
+ stdio
+ } -setup {
+ makeFile {puts [list $argv0 $argv $tcl_interactive]} script
+ catch {set f [open "|[list [interpreter] script \u00c0]" r]}
+ } -body {
+ read $f
+ } -cleanup {
+ close $f
+ removeFile script
+ } -result [list script [list [encoding convertfrom [encoding system] \
+ [encoding convertto [encoding system] \u00c0]]] 0]\n
+
+ test Tcl_Main-1.4 {
+ } -constraints {
+ stdio
+ } -setup {
+ makeFile {puts [list $argv0 $argv $tcl_interactive]} script
+ catch {set f [open "|[list [interpreter] script \u20ac]" r]}
+ } -body {
+ read $f
+ } -cleanup {
+ close $f
+ removeFile script
+ } -result [list script [list [encoding convertfrom [encoding system] \
+ [encoding convertto [encoding system] \u20ac]]] 0]\n
+
+ test Tcl_Main-1.5 {
+ } -constraints {
+ stdio
+ } -setup {
+ makeFile {puts [list $argv0 $argv $tcl_interactive]} \u00c0
+ catch {set f [open "|[list [interpreter] \u00c0]" r]}
+ } -body {
+ read $f
+ } -cleanup {
+ close $f
+ removeFile \u00c0
+ } -result [list [list [encoding convertfrom [encoding system] \
+ [encoding convertto [encoding system] \u00c0]]] {} 0]\n
+
+ test Tcl_Main-1.6 {
+ } -constraints {
+ stdio
+ } -setup {
+ makeFile {puts [list $argv0 $argv $tcl_interactive]} \u20ac
+ catch {set f [open "|[list [interpreter] \u20ac]" r]}
+ } -body {
+ read $f
+ } -cleanup {
+ close $f
+ removeFile \u20ac
+ } -result [list [list [encoding convertfrom [encoding system] \
+ [encoding convertto [encoding system] \u20ac]]] {} 0]\n
+
+ test Tcl_Main-1.7 {
+ Tcl_Main: startup script - -encoding option
+ } -constraints {
+ stdio
+ } -setup {
+ set script [makeFile {} script]
+ file delete $script
+ set f [open $script w]
+ fconfigure $f -encoding utf-8
+ puts $f {puts [list $argv0 $argv $tcl_interactive]}
+ puts -nonewline $f {puts [string equal \u20ac }
+ puts $f "\u20ac]"
+ close $f
+ catch {set f [open "|[list [interpreter] -encoding utf-8 script]" r]}
+ } -body {
+ read $f
+ } -cleanup {
+ close $f
+ removeFile script
+ } -result [list script {} 0]\n1\n
+
+ test Tcl_Main-1.8 {
+ Tcl_Main: startup script - -encoding option - mismatched encodings
+ } -constraints {
+ stdio
+ } -setup {
+ set script [makeFile {} script]
+ file delete $script
+ set f [open $script w]
+ fconfigure $f -encoding utf-8
+ puts $f {puts [list $argv0 $argv $tcl_interactive]}
+ puts -nonewline $f {puts [string equal \u20ac }
+ puts $f "\u20ac]"
+ close $f
+ catch {set f [open "|[list [interpreter] -encoding ascii script]" r]}
+ } -body {
+ read $f
+ } -cleanup {
+ close $f
+ removeFile script
+ } -result [list script {} 0]\n0\n
+
+ test Tcl_Main-1.9 {
+ Tcl_Main: startup script - -encoding option - no abbrevation
+ } -constraints {
+ stdio
+ } -setup {
+ set script [makeFile {} script]
+ file delete $script
+ set f [open $script w]
+ fconfigure $f -encoding utf-8
+ puts $f {puts [list $argv0 $argv $tcl_interactive]}
+ puts -nonewline $f {puts [string equal \u20ac }
+ puts $f "\u20ac]"
+ close $f
+ catch {set f [open "|[list [interpreter] -enc utf-8 script]" r+]}
+ } -body {
+ type $f {
+ puts $argv
+ }
+ list [catch {gets $f} line] $line
+ } -cleanup {
+ close $f
+ removeFile script
+ } -result {0 {-enc utf-8 script}}
+
+ # Tests Tcl_Main-2.*: application-initialization procedure
+
+ test Tcl_Main-2.1 {
+ Tcl_Main: appInitProc returns error
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ makeFile {puts "In script"} script
+ } -body {
+ exec [interpreter] script -appinitprocerror >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -result "application-specific initialization failed: \nIn script\n"
+
+ test Tcl_Main-2.2 {
+ Tcl_Main: appInitProc returns error
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {puts "In script"} -appinitprocerror >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "application-specific initialization failed: \nIn script\n"
+
+ test Tcl_Main-2.3 {
+ Tcl_Main: appInitProc deletes interp
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ makeFile {puts "In script"} script
+ } -body {
+ exec [interpreter] script -appinitprocdeleteinterp >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -result "application-specific initialization failed: \n"
+
+ test Tcl_Main-2.4 {
+ Tcl_Main: appInitProc deletes interp
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {puts "In script"} \
+ -appinitprocdeleteinterp >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "application-specific initialization failed: \n"
+
+ test Tcl_Main-2.5 {
+ Tcl_Main: appInitProc closes stderr
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {puts "In script"} \
+ -appinitprocclosestderr >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "In script\n"
+
+ # Tests Tcl_Main-3.*: startup script evaluation
+
+ test Tcl_Main-3.1 {
+ Tcl_Main: startup script does not exist
+ } -constraints {
+ exec
+ } -setup {
+ if {[file exists no-such-file]} {
+ error "Can't run test Tcl_Main-3.1\
+ where a file named \"no-such-file\" exists"
+ }
+ } -body {
+ set code [catch {exec [interpreter] no-such-file >& result} result]
+ set f [open result]
+ list $code $result [read $f]
+ } -cleanup {
+ close $f
+ file delete result
+ } -match glob -result [list 1 {child process exited abnormally} \
+ {couldn't read file "no-such-file":*}]
+
+ test Tcl_Main-3.2 {
+ Tcl_Main: startup script raises error
+ } -constraints {
+ exec
+ } -setup {
+ makeFile {error ERROR} script
+ } -body {
+ set code [catch {exec [interpreter] script >& result} result]
+ set f [open result]
+ list $code $result [read $f]
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -match glob -result [list 1 {child process exited abnormally} \
+ "ERROR\n while executing*"]
+
+ test Tcl_Main-3.3 {
+ Tcl_Main: startup script closes stderr
+ } -constraints {
+ exec
+ } -setup {
+ makeFile {close stderr; error ERROR} script
+ } -body {
+ set code [catch {exec [interpreter] script >& result} result]
+ set f [open result]
+ list $code $result [read $f]
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -result [list 1 {child process exited abnormally} {}]
+
+ test Tcl_Main-3.4 {
+ Tcl_Main: startup script holds incomplete script
+ } -constraints {
+ exec
+ } -setup {
+ makeFile "if 1 \{" script
+ } -body {
+ set code [catch {exec [interpreter] script >& result} result]
+ set f [open result]
+ join [list $code $result [read $f]] \n
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -match glob -result [join [list 1 {child process exited abnormally}\
+ "missing close-brace\n while executing*"] \n]
+
+ test Tcl_Main-3.5 {
+ Tcl_Main: startup script sets main loop
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ makeFile {
+ rename exit _exit
+ proc exit {code} {
+ puts "In exit"
+ _exit $code
+ }
+ after 0 {
+ puts event
+ testexitmainloop
+ }
+ testexithandler create 0
+ testsetmainloop
+ } script
+ } -body {
+ exec [interpreter] script >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -result "event\nExit MainLoop\nIn exit\neven 0\n"
+
+ test Tcl_Main-3.6 {
+ Tcl_Main: startup script sets main loop and closes stdin
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ makeFile {
+ close stdin
+ testsetmainloop
+ rename exit _exit
+ proc exit {code} {
+ puts "In exit"
+ _exit $code
+ }
+ after 0 {
+ puts event
+ testexitmainloop
+ }
+ testexithandler create 0
+ } script
+ } -body {
+ exec [interpreter] script >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -result "event\nExit MainLoop\nIn exit\neven 0\n"
+
+ test Tcl_Main-3.7 {
+ Tcl_Main: startup script deletes interp
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ makeFile {
+ rename exit _exit
+ proc exit {code} {
+ puts "In exit"
+ _exit $code
+ }
+ testexithandler create 0
+ testinterpdelete {}
+ } script
+ } -body {
+ exec [interpreter] script >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -result "even 0\n"
+
+ test Tcl_Main-3.8 {
+ Tcl_Main: startup script deletes interp and sets mainloop
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ makeFile {
+ testsetmainloop
+ rename exit _exit
+ proc exit {code} {
+ puts "In exit"
+ _exit $code
+ }
+ testexitmainloop
+ testexithandler create 0
+ testinterpdelete {}
+ } script
+ } -body {
+ exec [interpreter] script >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -result "Exit MainLoop\neven 0\n"
+
+ test Tcl_Main-3.9 {
+ Tcl_Main: startup script can set tcl_interactive without limit
+ } -constraints {
+ exec
+ } -setup {
+ makeFile {set tcl_interactive foo} script
+ } -body {
+ exec [interpreter] script >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile script
+ } -result {}
+
+ # Tests Tcl_Main-4.*: rc file evaluation
+
+ test Tcl_Main-4.1 {
+ Tcl_Main: rcFile evaluation deletes interp
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ set rc [makeFile {testinterpdelete {}} rc]
+ } -body {
+ exec [interpreter] << {puts "In script"} \
+ -appinitprocsetrcfile $rc >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile rc
+ } -result "application-specific initialization failed: \n"
+
+ test Tcl_Main-4.2 {
+ Tcl_Main: rcFile evaluation closes stdin
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ set rc [makeFile {close stdin} rc]
+ } -body {
+ exec [interpreter] << {puts "In script"} \
+ -appinitprocsetrcfile $rc >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile rc
+ } -result "application-specific initialization failed: \n"
+
+ test Tcl_Main-4.3 {
+ Tcl_Main: rcFile evaluation closes stdin and sets main loop
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ set rc [makeFile {
+ close stdin
+ testsetmainloop
+ after 0 testexitmainloop
+ testexithandler create 0
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ } rc]
+ } -body {
+ exec [interpreter] << {puts "In script"} \
+ -appinitprocsetrcfile $rc >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile rc
+ } -result "application-specific initialization failed:\
+ \nExit MainLoop\nIn exit\neven 0\n"
+
+ test Tcl_Main-4.4 {
+ Tcl_Main: rcFile evaluation sets main loop
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ set rc [makeFile {
+ testsetmainloop
+ after 0 testexitmainloop
+ testexithandler create 0
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ } rc]
+ } -body {
+ exec [interpreter] << {} \
+ -appinitprocsetrcfile $rc >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ removeFile rc
+ } -result "application-specific initialization failed:\
+ \nExit MainLoop\nIn exit\neven 0\n"
+
+ test Tcl_Main-4.5 {
+ Tcl_Main: Bug 1481986
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ set rc [makeFile {
+ testsetmainloop
+ after 0 {puts "Event callback"}
+ } rc]
+ } -body {
+ set f [open "|[list [interpreter] -appinitprocsetrcfile $rc]" w+]
+ after 1000
+ type $f {puts {Interactive output}
+ exit
+ }
+ read $f
+ } -cleanup {
+ catch {close $f}
+ removeFile rc
+ } -result "Event callback\nInteractive output\n"
+
+ # Tests Tcl_Main-5.*: interactive operations
+
+ test Tcl_Main-5.1 {
+ Tcl_Main: tcl_interactive must be boolean
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {set tcl_interactive foo} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "can't set \"tcl_interactive\":\
+ variable must have boolean value\n"
+
+ test Tcl_Main-5.2 {
+ Tcl_Main able to handle non-blocking stdin
+ } -constraints {
+ exec
+ } -setup {
+ catch {set f [open "|[list [interpreter]]" w+]}
+ } -body {
+ type $f {
+ fconfigure stdin -blocking 0
+ puts SUCCESS
+ }
+ list [catch {gets $f} line] $line
+ } -cleanup {
+ close $f
+ } -result [list 0 SUCCESS]
+
+ test Tcl_Main-5.3 {
+ Tcl_Main handles stdin EOF in mid-command
+ } -constraints {
+ exec
+ } -setup {
+ catch {set f [open "|[list [interpreter]]" w+]}
+ catch {fconfigure $f -blocking 0}
+ } -body {
+ type $f "fconfigure stdin -eofchar \\032
+ if 1 \{\n\032"
+ variable wait
+ fileevent $f readable \
+ [list set [namespace which -variable wait] "child exit"]
+ set id [after 2000 [list set [namespace which -variable wait] timeout]]
+ vwait [namespace which -variable wait]
+ after cancel $id
+ set wait
+ } -cleanup {
+ if {[string equal timeout $wait] && [testConstraint unix]} {
+ exec kill [pid $f]
+ }
+ close $f
+ } -result {child exit}
+
+ test Tcl_Main-5.4 {
+ Tcl_Main handles stdin EOF in mid-command
+ } -constraints {
+ exec
+ } -setup {
+ set cmd {makeFile "if 1 \{" script}
+ catch {set f [open "|[list [interpreter]] < [list [eval $cmd]]" r]}
+ catch {fconfigure $f -blocking 0}
+ } -body {
+ variable wait
+ fileevent $f readable \
+ [list set [namespace which -variable wait] "child exit"]
+ set id [after 2000 [list set [namespace which -variable wait] timeout]]
+ vwait [namespace which -variable wait]
+ after cancel $id
+ set wait
+ } -cleanup {
+ if {[string equal timeout $wait] && [testConstraint unix]} {
+ exec kill [pid $f]
+ }
+ close $f
+ removeFile script
+ } -result {child exit}
+
+ test Tcl_Main-5.5 {
+ Tcl_Main: error raised in interactive mode
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {error foo} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "foo\n"
+
+ test Tcl_Main-5.6 {
+ Tcl_Main: interactive mode: errors don't stop command loop
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ error foo
+ puts bar
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "foo\nbar\n"
+
+ test Tcl_Main-5.7 {
+ Tcl_Main: interactive mode: closed stderr
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ close stderr
+ error foo
+ puts bar
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "bar\n"
+
+ test Tcl_Main-5.8 {
+ Tcl_Main: interactive mode: close stdin
+ -> main loop & [exit] & exit handlers
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ testsetmainloop
+ testexitmainloop
+ testexithandler create 0
+ close stdin
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "Exit MainLoop\nIn exit\neven 0\n"
+
+ test Tcl_Main-5.9 {
+ Tcl_Main: interactive mode: delete interp
+ -> main loop & exit handlers, but no [exit]
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ testsetmainloop
+ testexitmainloop
+ testexithandler create 0
+ testinterpdelete {}
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "Exit MainLoop\neven 0\n"
+
+ test Tcl_Main-5.10 {
+ Tcl_Main: exit main loop in mid-interactive command
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ catch {set f [open "|[list [interpreter]]" w+]}
+ catch {fconfigure $f -blocking 0}
+ } -body {
+ type $f "testsetmainloop
+ after 2000 testexitmainloop
+ puts \{1 2"
+ after 4000
+ type $f "3 4\}"
+ set code1 [catch {gets $f} line1]
+ set code2 [catch {gets $f} line2]
+ set code3 [catch {gets $f} line3]
+ list $code1 $line1 $code2 $line2 $code3 $line3
+ } -cleanup {
+ close $f
+ } -result [list 0 {Exit MainLoop} 0 {1 2} 0 {3 4}]
+
+ test Tcl_Main-5.11 {
+ Tcl_Main: EOF in interactive main loop
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ testexithandler create 0
+ after 0 testexitmainloop
+ testsetmainloop
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "Exit MainLoop\nIn exit\neven 0\n"
+
+ test Tcl_Main-5.12 {
+ Tcl_Main: close stdin in interactive main loop
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ testexithandler create 0
+ after 100 testexitmainloop
+ testsetmainloop
+ close stdin
+ puts "don't reach this"
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "Exit MainLoop\nIn exit\neven 0\n"
+
+ test Tcl_Main-5.13 {
+ Bug 1775878
+ } -constraints {
+ exec
+ } -setup {
+ catch {set f [open "|[list [interpreter]]" w+]}
+ } -body {
+ type $f "puts \\"
+ type $f return
+ list [catch {gets $f} line] $line
+ } -cleanup {
+ close $f
+ } -result [list 0 return]
+
+ # Tests Tcl_Main-6.*: interactive operations with prompts
+
+ test Tcl_Main-6.1 {
+ Tcl_Main: enable prompts with tcl_interactive
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {set tcl_interactive 1} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% "
+
+ test Tcl_Main-6.2 {
+ Tcl_Main: prompt deletes interp
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ set tcl_prompt1 {testinterpdelete {}}
+ set tcl_interactive 1
+ puts "not reached"
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n"
+
+ test Tcl_Main-6.3 {
+ Tcl_Main: prompt closes stdin
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ set tcl_prompt1 {close stdin}
+ set tcl_interactive 1
+ puts "not reached"
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n"
+
+ test Tcl_Main-6.4 {
+ Tcl_Main: interactive output, closed stdout
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ set tcl_interactive 1
+ close stdout
+ set a NO
+ puts stderr YES
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% YES\n"
+
+ test Tcl_Main-6.5 {
+ Tcl_Main: interactive entry to main loop
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ set tcl_interactive 1
+ testsetmainloop
+ testexitmainloop} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% % % Exit MainLoop\n"
+
+ test Tcl_Main-6.6 {
+ Tcl_Main: number of prompts during stdin close exit
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ set tcl_interactive 1
+ close stdin} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% "
+
+ test Tcl_Main-6.7 {
+ [unknown]: interactive auto-completion.
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ proc foo\{ x {}
+ set ::auto_noexec xxx
+ set tcl_interactive 1
+ foo y} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% % "
+
+ # Tests Tcl_Main-7.*: exiting
+
+ test Tcl_Main-7.1 {
+ Tcl_Main: [exit] defined as no-op -> still have exithandlers
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ proc exit args {}
+ testexithandler create 0
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "even 0\n"
+
+ test Tcl_Main-7.2 {
+ Tcl_Main: [exit] defined as no-op -> still have exithandlers
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ proc exit args {}
+ testexithandler create 0
+ after 0 testexitmainloop
+ testsetmainloop
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "Exit MainLoop\neven 0\n"
+
+ # Tests Tcl_Main-8.*: StdinProc operations
+
+ test Tcl_Main-8.1 {
+ StdinProc: handles non-blocking stdin
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ fconfigure stdin -blocking 0
+ testexitmainloop
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "Exit MainLoop\n"
+
+ test Tcl_Main-8.2 {
+ StdinProc: handles stdin EOF
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ testexithandler create 0
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ after 100 testexitmainloop
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "Exit MainLoop\nIn exit\neven 0\n"
+
+ test Tcl_Main-8.3 {
+ StdinProc: handles interactive stdin EOF
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ testexithandler create 0
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ set tcl_interactive 1} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% even 0\n"
+
+ test Tcl_Main-8.4 {
+ StdinProc: handles stdin close
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ after 100 testexitmainloop
+ after 0 puts 1
+ close stdin
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\nExit MainLoop\nIn exit\n"
+
+ test Tcl_Main-8.5 {
+ StdinProc: handles interactive stdin close
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ set tcl_interactive 1
+ rename exit _exit
+ proc exit code {
+ puts "In exit"
+ _exit $code
+ }
+ after 100 testexitmainloop
+ after 0 puts 1
+ close stdin
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% % % after#0\n% after#1\n% 1\nExit MainLoop\nIn exit\n"
+
+ test Tcl_Main-8.6 {
+ StdinProc: handles event loop re-entry
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ after 100 {puts 1; set delay 1}
+ vwait delay
+ puts 2
+ testexitmainloop
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n2\nExit MainLoop\n"
+
+ test Tcl_Main-8.7 {
+ StdinProc: handling of errors
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ error foo
+ testexitmainloop
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "foo\nExit MainLoop\n"
+
+ test Tcl_Main-8.8 {
+ StdinProc: handling of errors, closed stderr
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ close stderr
+ error foo
+ testexitmainloop
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "Exit MainLoop\n"
+
+ test Tcl_Main-8.9 {
+ StdinProc: interactive output
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ set tcl_interactive 1
+ testexitmainloop} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% % Exit MainLoop\n"
+
+ test Tcl_Main-8.10 {
+ StdinProc: interactive output, closed stdout
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ close stdout
+ set tcl_interactive 1
+ testexitmainloop
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result {}
+
+ test Tcl_Main-8.11 {
+ StdinProc: prompt deletes interp
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ set tcl_prompt1 {testinterpdelete {}}
+ set tcl_interactive 1} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n"
+
+ test Tcl_Main-8.12 {
+ StdinProc: prompt closes stdin
+ } -constraints {
+ exec Tcltest
+ } -body {
+ exec [interpreter] << {
+ testsetmainloop
+ set tcl_prompt1 {close stdin}
+ after 100 testexitmainloop
+ set tcl_interactive 1
+ puts "not reached"
+ } >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\nExit MainLoop\n"
+
+ test Tcl_Main-8.13 {
+ Bug 1775878
+ } -constraints {
+ exec Tcltest
+ } -setup {
+ catch {set f [open "|[list [interpreter]]" w+]}
+ } -body {
+ exec [interpreter] << "testsetmainloop\nputs \\\npwd\ntestexitmainloop" >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "pwd\nExit MainLoop\n"
+
+ # Tests Tcl_Main-9.*: Prompt operations
+
+ test Tcl_Main-9.1 {
+ Prompt: custom prompt variables
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ set tcl_prompt1 {puts -nonewline stdout "one "}
+ set tcl_prompt2 {puts -nonewline stdout "two "}
+ set tcl_interactive 1
+ puts {This is
+ a test}} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\none two This is\n\t\ta test\none "
+
+ test Tcl_Main-9.2 {
+ Prompt: error in custom prompt variables
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ set tcl_prompt1 {error foo}
+ set tcl_interactive 1
+ set errorInfo} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\nfoo\n% foo\n while executing\n\"error foo\"\n (script\
+ that generates prompt)\nfoo\n% "
+
+ test Tcl_Main-9.3 {
+ Prompt: error in custom prompt variables, closed stderr
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ set tcl_prompt1 {close stderr; error foo}
+ set tcl_interactive 1} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\n% "
+
+ test Tcl_Main-9.4 {
+ Prompt: error in custom prompt variables, closed stdout
+ } -constraints {
+ exec
+ } -body {
+ exec [interpreter] << {
+ set tcl_prompt1 {close stdout; error foo}
+ set tcl_interactive 1} >& result
+ set f [open result]
+ read $f
+ } -cleanup {
+ close $f
+ file delete result
+ } -result "1\nfoo\n"
+
+ cd [workingDirectory]
+
+ cleanupTests
+}
+
+namespace delete ::tcl::test::main
+return
diff --git a/pkgs/msgcat/tests/mathop.test b/pkgs/msgcat/tests/mathop.test
new file mode 100644
index 0000000..f122b7b
--- /dev/null
+++ b/pkgs/msgcat/tests/mathop.test
@@ -0,0 +1,1340 @@
+# Commands covered: ::tcl::mathop::...
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 2006 Donal K. Fellows
+# Copyright (c) 2006 Peter Spjuth
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2.1
+ namespace import -force ::tcltest::*
+}
+
+# A namespace to test that operators are exported and that they
+# work when imported
+namespace eval ::testmathop2 {
+ namespace import ::tcl::mathop::*
+}
+
+# Helper to test math ops.
+# Test different invokation variants and see that they do the same thing.
+# Byte compiled / non byte compiled version
+# Shared / unshared arguments
+# Original / imported
+proc TestOp {op args} {
+ set results {}
+
+ # Non byte compiled version, shared args
+ if {[catch {::tcl::mathop::$op {*}$args} res]} {
+ append res " $::errorCode"
+ }
+ lappend results $res
+
+ # Non byte compiled version, unshared args
+ set cmd ::tcl::mathop::\$op
+ foreach arg $args {
+ append cmd " \[format %s [list $arg]\]"
+ }
+ if {[catch $cmd res]} {
+ append res " $::errorCode"
+ }
+ lappend results $res
+
+ # Non byte compiled imported
+ if {[catch {::testmathop2::$op {*}$args} res]} {
+ append res " $::errorCode"
+ }
+ lappend results [string map {testmathop2 tcl::mathop} $res]
+
+ # BC version
+ set argList1 {}
+ set argList2 {}
+ set argList3 {}
+ for {set t 0} {$t < [llength $args]} {incr t} {
+ lappend argList1 a$t
+ lappend argList2 \$a$t
+ lappend argList3 "\[format %s \$a$t\]"
+ }
+ # Shared args
+ proc _TestOp $argList1 "::tcl::mathop::$op [join $argList2]"
+ # Unshared args
+ proc _TestOp2 $argList1 "::tcl::mathop::$op [join $argList3]"
+ # Imported
+ proc _TestOp3 $argList1 "::testmathop2::$op [join $argList2]"
+
+ set ::tcl_traceCompile 0 ;# Set to 2 to help with debug
+ if {[catch {_TestOp {*}$args} res]} {
+ append res " $::errorCode"
+ }
+ set ::tcl_traceCompile 0
+ lappend results $res
+
+ if {[catch {_TestOp2 {*}$args} res]} {
+ append res " $::errorCode"
+ }
+ lappend results $res
+
+ if {[catch {_TestOp3 {*}$args} res]} {
+ append res " $::errorCode"
+ }
+ lappend results [string map {testmathop2 tcl::mathop} $res]
+
+ # Check that they do the same
+ set len [llength $results]
+ for {set i 0} {$i < ($len - 1)} {incr i} {
+ set res1 [lindex $results $i]
+ set res2 [lindex $results $i+1]
+ if {$res1 ne $res2} {
+ return "$i:($res1 != $res2)"
+ }
+ }
+ return [lindex $results 0]
+}
+
+# start of tests
+
+namespace eval ::testmathop {
+ namespace path ::tcl::mathop
+ variable op ;# stop surprises!
+
+ test mathop-1.1 {compiled +} { + } 0
+ test mathop-1.2 {compiled +} { + 1 } 1
+ test mathop-1.3 {compiled +} { + 1 2 } 3
+ test mathop-1.4 {compiled +} { + 1 2 3 } 6
+ test mathop-1.5 {compiled +} { + 1.0 2 3 } 6.0
+ test mathop-1.6 {compiled +} { + 1 2 3.0 } 6.0
+ test mathop-1.7 {compiled +} { + 100000000000 2 3 } 100000000005
+ test mathop-1.8 {compiled +} { + 1 2 300000000000 } 300000000003
+ test mathop-1.9 {compiled +} { + 1000000000000000000000 2 3 } 1000000000000000000005
+ test mathop-1.10 {compiled +} { + 1 2 3000000000000000000000 } 3000000000000000000003
+ test mathop-1.11 {compiled +: errors} -returnCodes error -body {
+ + x 0
+ } -result {can't use non-numeric string as operand of "+"}
+ test mathop-1.12 {compiled +: errors} -returnCodes error -body {
+ + nan 0
+ } -result {can't use non-numeric floating-point value as operand of "+"}
+ test mathop-1.13 {compiled +: errors} -returnCodes error -body {
+ + 0 x
+ } -result {can't use non-numeric string as operand of "+"}
+ test mathop-1.14 {compiled +: errors} -returnCodes error -body {
+ + 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "+"}
+ test mathop-1.15 {compiled +: errors} -returnCodes error -body {
+ + 0o8 0
+ } -result {can't use invalid octal number as operand of "+"}
+ test mathop-1.16 {compiled +: errors} -returnCodes error -body {
+ + 0 0o8
+ } -result {can't use invalid octal number as operand of "+"}
+ test mathop-1.17 {compiled +: errors} -returnCodes error -body {
+ + 0 [error expectedError]
+ } -result expectedError
+ test mathop-1.18 {compiled +: argument processing order} -body {
+ # Bytecode compilation known hard for 3+ arguments
+ list [catch {
+ + [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+ set op +
+ test mathop-1.19 {interpreted +} { $op } 0
+ test mathop-1.20 {interpreted +} { $op 1 } 1
+ test mathop-1.21 {interpreted +} { $op 1 2 } 3
+ test mathop-1.22 {interpreted +} { $op 1 2 3 } 6
+ test mathop-1.23 {interpreted +} { $op 1.0 2 3 } 6.0
+ test mathop-1.24 {interpreted +} { $op 1 2 3.0 } 6.0
+ test mathop-1.25 {interpreted +} { $op 100000000000 2 3 } 100000000005
+ test mathop-1.26 {interpreted +} { $op 1 2 300000000000 } 300000000003
+ test mathop-1.27 {interpreted +} { $op 1000000000000000000000 2 3 } 1000000000000000000005
+ test mathop-1.28 {interpreted +} { $op 1 2 3000000000000000000000 } 3000000000000000000003
+ test mathop-1.29 {interpreted +: errors} -returnCodes error -body {
+ $op x 0
+ } -result {can't use non-numeric string as operand of "+"}
+ test mathop-1.30 {interpreted +: errors} -returnCodes error -body {
+ $op nan 0
+ } -result {can't use non-numeric floating-point value as operand of "+"}
+ test mathop-1.31 {interpreted +: errors} -returnCodes error -body {
+ $op 0 x
+ } -result {can't use non-numeric string as operand of "+"}
+ test mathop-1.32 {interpreted +: errors} -returnCodes error -body {
+ $op 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "+"}
+ test mathop-1.33 {interpreted +: errors} -returnCodes error -body {
+ $op 0o8 0
+ } -result {can't use invalid octal number as operand of "+"}
+ test mathop-1.34 {interpreted +: errors} -returnCodes error -body {
+ $op 0 0o8
+ } -result {can't use invalid octal number as operand of "+"}
+ test mathop-1.35 {interpreted +: errors} -returnCodes error -body {
+ $op 0 [error expectedError]
+ } -result expectedError
+ test mathop-1.36 {interpreted +: argument processing order} -body {
+ list [catch {
+ $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+
+ test mathop-2.1 {compiled *} { * } 1
+ test mathop-2.2 {compiled *} { * 2 } 2
+ test mathop-2.3 {compiled *} { * 2 3 } 6
+ test mathop-2.4 {compiled *} { * 2 3 4 } 24
+ test mathop-2.5 {compiled *} { * 1.0 2 3 } 6.0
+ test mathop-2.6 {compiled *} { * 1 2 3.0 } 6.0
+ test mathop-2.7 {compiled *} { * 100000000000 2 3 } 600000000000
+ test mathop-2.8 {compiled *} { * 1 2 300000000000 } 600000000000
+ test mathop-2.9 {compiled *} { * 1000000000000000000000 2 3 } 6000000000000000000000
+ test mathop-2.10 {compiled *} { * 1 2 3000000000000000000000 } 6000000000000000000000
+ test mathop-2.11 {compiled *: errors} -returnCodes error -body {
+ * x 0
+ } -result {can't use non-numeric string as operand of "*"}
+ test mathop-2.12 {compiled *: errors} -returnCodes error -body {
+ * nan 0
+ } -result {can't use non-numeric floating-point value as operand of "*"}
+ test mathop-2.13 {compiled *: errors} -returnCodes error -body {
+ * 0 x
+ } -result {can't use non-numeric string as operand of "*"}
+ test mathop-2.14 {compiled *: errors} -returnCodes error -body {
+ * 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "*"}
+ test mathop-2.15 {compiled *: errors} -returnCodes error -body {
+ * 0o8 0
+ } -result {can't use invalid octal number as operand of "*"}
+ test mathop-2.16 {compiled *: errors} -returnCodes error -body {
+ * 0 0o8
+ } -result {can't use invalid octal number as operand of "*"}
+ test mathop-2.17 {compiled *: errors} -returnCodes error -body {
+ * 0 [error expectedError]
+ } -result expectedError
+ test mathop-2.18 {compiled *: argument processing order} -body {
+ # Bytecode compilation known hard for 3+ arguments
+ list [catch {
+ * [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+ set op *
+ test mathop-2.19 {interpreted *} { $op } 1
+ test mathop-2.20 {interpreted *} { $op 2 } 2
+ test mathop-2.21 {interpreted *} { $op 2 3 } 6
+ test mathop-2.22 {interpreted *} { $op 2 3 4 } 24
+ test mathop-2.23 {interpreted *} { $op 1.0 2 3 } 6.0
+ test mathop-2.24 {interpreted *} { $op 1 2 3.0 } 6.0
+ test mathop-2.25 {interpreted *} { $op 100000000000 2 3 } 600000000000
+ test mathop-2.26 {interpreted *} { $op 1 2 300000000000 } 600000000000
+ test mathop-2.27 {interpreted *} { $op 1000000000000000000000 2 3 } 6000000000000000000000
+ test mathop-2.28 {interpreted *} { $op 1 2 3000000000000000000000 } 6000000000000000000000
+ test mathop-2.29 {interpreted *: errors} -returnCodes error -body {
+ $op x 0
+ } -result {can't use non-numeric string as operand of "*"}
+ test mathop-2.30 {interpreted *: errors} -returnCodes error -body {
+ $op nan 0
+ } -result {can't use non-numeric floating-point value as operand of "*"}
+ test mathop-2.31 {interpreted *: errors} -returnCodes error -body {
+ $op 0 x
+ } -result {can't use non-numeric string as operand of "*"}
+ test mathop-2.32 {interpreted *: errors} -returnCodes error -body {
+ $op 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "*"}
+ test mathop-2.33 {interpreted *: errors} -returnCodes error -body {
+ $op 0o8 0
+ } -result {can't use invalid octal number as operand of "*"}
+ test mathop-2.34 {interpreted *: errors} -returnCodes error -body {
+ $op 0 0o8
+ } -result {can't use invalid octal number as operand of "*"}
+ test mathop-2.35 {interpreted *: errors} -returnCodes error -body {
+ $op 0 [error expectedError]
+ } -result expectedError
+ test mathop-2.36 {interpreted *: argument processing order} -body {
+ list [catch {
+ $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+
+ test mathop-3.1 {compiled !} {! 0} 1
+ test mathop-3.2 {compiled !} {! 1} 0
+ test mathop-3.3 {compiled !} {! false} 1
+ test mathop-3.4 {compiled !} {! true} 0
+ test mathop-3.5 {compiled !} {! 0.0} 1
+ test mathop-3.6 {compiled !} {! 10000000000} 0
+ test mathop-3.7 {compiled !} {! 10000000000000000000000000} 0
+ test mathop-3.8 {compiled !: errors} -body {
+ ! foobar
+ } -returnCodes error -result {can't use non-numeric string as operand of "!"}
+ test mathop-3.9 {compiled !: errors} -body {
+ ! 0 0
+ } -returnCodes error -result "wrong # args: should be \"! boolean\""
+ test mathop-3.10 {compiled !: errors} -body {
+ !
+ } -returnCodes error -result "wrong # args: should be \"! boolean\""
+ set op !
+ test mathop-3.11 {interpreted !} {$op 0} 1
+ test mathop-3.12 {interpreted !} {$op 1} 0
+ test mathop-3.13 {interpreted !} {$op false} 1
+ test mathop-3.14 {interpreted !} {$op true} 0
+ test mathop-3.15 {interpreted !} {$op 0.0} 1
+ test mathop-3.16 {interpreted !} {$op 10000000000} 0
+ test mathop-3.17 {interpreted !} {$op 10000000000000000000000000} 0
+ test mathop-3.18 {interpreted !: errors} -body {
+ $op foobar
+ } -returnCodes error -result {can't use non-numeric string as operand of "!"}
+ test mathop-3.19 {interpreted !: errors} -body {
+ $op 0 0
+ } -returnCodes error -result "wrong # args: should be \"! boolean\""
+ test mathop-3.20 {interpreted !: errors} -body {
+ $op
+ } -returnCodes error -result "wrong # args: should be \"! boolean\""
+ test mathop-3.21 {compiled !: error} -returnCodes error -body {
+ ! NaN
+ } -result {can't use non-numeric floating-point value as operand of "!"}
+ test mathop-3.22 {interpreted !: error} -returnCodes error -body {
+ $op NaN
+ } -result {can't use non-numeric floating-point value as operand of "!"}
+
+ test mathop-4.1 {compiled ~} {~ 0} -1
+ test mathop-4.2 {compiled ~} {~ 1} -2
+ test mathop-4.3 {compiled ~} {~ 31} -32
+ test mathop-4.4 {compiled ~} {~ -127} 126
+ test mathop-4.5 {compiled ~} {~ -0} -1
+ test mathop-4.6 {compiled ~} {~ 10000000000} -10000000001
+ test mathop-4.7 {compiled ~} {~ 10000000000000000000000000} -10000000000000000000000001
+ test mathop-4.8 {compiled ~: errors} -body {
+ ~ foobar
+ } -returnCodes error -result {can't use non-numeric string as operand of "~"}
+ test mathop-4.9 {compiled ~: errors} -body {
+ ~ 0 0
+ } -returnCodes error -result "wrong # args: should be \"~ integer\""
+ test mathop-4.10 {compiled ~: errors} -body {
+ ~
+ } -returnCodes error -result "wrong # args: should be \"~ integer\""
+ test mathop-4.11 {compiled ~: errors} -returnCodes error -body {
+ ~ 0.0
+ } -result {can't use floating-point value as operand of "~"}
+ test mathop-4.12 {compiled ~: errors} -returnCodes error -body {
+ ~ NaN
+ } -result {can't use non-numeric floating-point value as operand of "~"}
+ set op ~
+ test mathop-4.13 {interpreted ~} {$op 0} -1
+ test mathop-4.14 {interpreted ~} {$op 1} -2
+ test mathop-4.15 {interpreted ~} {$op 31} -32
+ test mathop-4.16 {interpreted ~} {$op -127} 126
+ test mathop-4.17 {interpreted ~} {$op -0} -1
+ test mathop-4.18 {interpreted ~} {$op 10000000000} -10000000001
+ test mathop-4.19 {interpreted ~} {$op 10000000000000000000000000} -10000000000000000000000001
+ test mathop-4.20 {interpreted ~: errors} -body {
+ $op foobar
+ } -returnCodes error -result {can't use non-numeric string as operand of "~"}
+ test mathop-4.21 {interpreted ~: errors} -body {
+ $op 0 0
+ } -returnCodes error -result "wrong # args: should be \"~ integer\""
+ test mathop-4.22 {interpreted ~: errors} -body {
+ $op
+ } -returnCodes error -result "wrong # args: should be \"~ integer\""
+ test mathop-4.23 {interpreted ~: errors} -returnCodes error -body {
+ $op 0.0
+ } -result {can't use floating-point value as operand of "~"}
+ test mathop-4.24 {interpreted ~: errors} -returnCodes error -body {
+ $op NaN
+ } -result {can't use non-numeric floating-point value as operand of "~"}
+
+ test mathop-5.1 {compiled eq} {eq {} a} 0
+ test mathop-5.2 {compiled eq} {eq a a} 1
+ test mathop-5.3 {compiled eq} {eq a {}} 0
+ test mathop-5.4 {compiled eq} {eq a b} 0
+ test mathop-5.5 {compiled eq} { eq } 1
+ test mathop-5.6 {compiled eq} {eq a} 1
+ test mathop-5.7 {compiled eq} {eq a a a} 1
+ test mathop-5.8 {compiled eq} {eq a a b} 0
+ test mathop-5.9 {compiled eq} -body {
+ eq a b [error foobar]
+ } -returnCodes error -result foobar
+ test mathop-5.10 {compiled eq} {eq NaN Na NaN} 0
+ set op eq
+ test mathop-5.11 {interpreted eq} {$op {} a} 0
+ test mathop-5.12 {interpreted eq} {$op a a} 1
+ test mathop-5.13 {interpreted eq} {$op a {}} 0
+ test mathop-5.14 {interpreted eq} {$op a b} 0
+ test mathop-5.15 {interpreted eq} { $op } 1
+ test mathop-5.16 {interpreted eq} {$op a} 1
+ test mathop-5.17 {interpreted eq} {$op a a a} 1
+ test mathop-5.18 {interpreted eq} {$op a a b} 0
+ test mathop-5.19 {interpreted eq} -body {
+ $op a b [error foobar]
+ } -returnCodes error -result foobar
+ test mathop-5.20 {interpreted eq} {$op NaN Na NaN} 0
+
+ variable big1 12135435435354435435342423948763867876
+ variable big2 2746237174783836746262564892918327847
+ variable wide1 12345678912345
+ variable wide2 87321847232215
+ variable small1 87345
+ variable small2 16753
+
+ test mathop-6.1 {compiled &} { & } -1
+ test mathop-6.2 {compiled &} { & 1 } 1
+ test mathop-6.3 {compiled &} { & 1 2 } 0
+ test mathop-6.4 {compiled &} { & 3 7 6 } 2
+ test mathop-6.5 {compiled &} -returnCodes error -body {
+ & 1.0 2 3
+ } -result {can't use floating-point value as operand of "&"}
+ test mathop-6.6 {compiled &} -returnCodes error -body {
+ & 1 2 3.0
+ } -result {can't use floating-point value as operand of "&"}
+ test mathop-6.7 {compiled &} { & 100000000002 18 -126 } 2
+ test mathop-6.8 {compiled &} { & 0xff 0o377 333333333333 } 85
+ test mathop-6.9 {compiled &} { & 1000000000000000000002 18 -126 } 2
+ test mathop-6.10 {compiled &} { & 0xff 0o377 3333333333333333333333 } 85
+ test mathop-6.11 {compiled &: errors} -returnCodes error -body {
+ & x 0
+ } -result {can't use non-numeric string as operand of "&"}
+ test mathop-6.12 {compiled &: errors} -returnCodes error -body {
+ & nan 0
+ } -result {can't use non-numeric floating-point value as operand of "&"}
+ test mathop-6.13 {compiled &: errors} -returnCodes error -body {
+ & 0 x
+ } -result {can't use non-numeric string as operand of "&"}
+ test mathop-6.14 {compiled &: errors} -returnCodes error -body {
+ & 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "&"}
+ test mathop-6.15 {compiled &: errors} -returnCodes error -body {
+ & 0o8 0
+ } -result {can't use invalid octal number as operand of "&"}
+ test mathop-6.16 {compiled &: errors} -returnCodes error -body {
+ & 0 0o8
+ } -result {can't use invalid octal number as operand of "&"}
+ test mathop-6.17 {compiled &: errors} -returnCodes error -body {
+ & 0 [error expectedError]
+ } -result expectedError
+ test mathop-6.18 {compiled &: argument processing order} -body {
+ # Bytecode compilation known hard for 3+ arguments
+ list [catch {
+ & [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+ set op &
+ test mathop-6.19 {interpreted &} { $op } -1
+ test mathop-6.20 {interpreted &} { $op 1 } 1
+ test mathop-6.21 {interpreted &} { $op 1 2 } 0
+ test mathop-6.22 {interpreted &} { $op 3 7 6 } 2
+ test mathop-6.23 {interpreted &} -returnCodes error -body {
+ $op 1.0 2 3
+ } -result {can't use floating-point value as operand of "&"}
+ test mathop-6.24 {interpreted &} -returnCodes error -body {
+ $op 1 2 3.0
+ } -result {can't use floating-point value as operand of "&"}
+ test mathop-6.25 {interpreted &} { $op 100000000002 18 -126 } 2
+ test mathop-6.26 {interpreted &} { $op 0xff 0o377 333333333333 } 85
+ test mathop-6.27 {interpreted &} { $op 1000000000000000000002 18 -126 } 2
+ test mathop-6.28 {interpreted &} { $op 0xff 0o377 3333333333333333333333 } 85
+ test mathop-6.29 {interpreted &: errors} -returnCodes error -body {
+ $op x 0
+ } -result {can't use non-numeric string as operand of "&"}
+ test mathop-6.30 {interpreted &: errors} -returnCodes error -body {
+ $op nan 0
+ } -result {can't use non-numeric floating-point value as operand of "&"}
+ test mathop-6.31 {interpreted &: errors} -returnCodes error -body {
+ $op 0 x
+ } -result {can't use non-numeric string as operand of "&"}
+ test mathop-6.32 {interpreted &: errors} -returnCodes error -body {
+ $op 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "&"}
+ test mathop-6.33 {interpreted &: errors} -returnCodes error -body {
+ $op 0o8 0
+ } -result {can't use invalid octal number as operand of "&"}
+ test mathop-6.34 {interpreted &: errors} -returnCodes error -body {
+ $op 0 0o8
+ } -result {can't use invalid octal number as operand of "&"}
+ test mathop-6.35 {interpreted &: errors} -returnCodes error -body {
+ $op 0 [error expectedError]
+ } -result expectedError
+ test mathop-6.36 {interpreted &: argument processing order} -body {
+ list [catch {
+ $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+ test mathop-6.37 {& and bignums} {
+ list [& $big1 $big2] [$op $big1 $big2]
+ } {712439449294653815890598856501796 712439449294653815890598856501796}
+ test mathop-6.38 {& and bignums} {
+ list [& $big1 $wide2] [$op $big1 $wide2]
+ } {78521450111684 78521450111684}
+ test mathop-6.39 {& and bignums} {
+ list [& $big1 $small2] [$op $big1 $small2]
+ } {96 96}
+ test mathop-6.40 {& and bignums} {
+ list [& $wide1 $big2] [$op $wide1 $big2]
+ } {2371422390785 2371422390785}
+ test mathop-6.41 {& and bignums} {
+ list [& $wide1 $wide2] [$op $wide1 $wide2]
+ } {12275881497169 12275881497169}
+ test mathop-6.42 {& and bignums} {
+ list [& $wide1 $small2] [$op $wide1 $small2]
+ } {16721 16721}
+ test mathop-6.43 {& and bignums} {
+ list [& $small1 $big2] [$op $small1 $big2]
+ } {33 33}
+ test mathop-6.44 {& and bignums} {
+ list [& $small1 $wide2] [$op $small1 $wide2]
+ } {87057 87057}
+ test mathop-6.45 {& and bignums} {
+ list [& $small1 $small2] [$op $small1 $small2]
+ } {16689 16689}
+
+ test mathop-7.1 {compiled |} { | } 0
+ test mathop-7.2 {compiled |} { | 1 } 1
+ test mathop-7.3 {compiled |} { | 1 2 } 3
+ test mathop-7.4 {compiled |} { | 3 7 6 } 7
+ test mathop-7.5 {compiled |} -returnCodes error -body {
+ | 1.0 2 3
+ } -result {can't use floating-point value as operand of "|"}
+ test mathop-7.6 {compiled |} -returnCodes error -body {
+ | 1 2 3.0
+ } -result {can't use floating-point value as operand of "|"}
+ test mathop-7.7 {compiled |} { | 100000000002 18 -126 } -110
+ test mathop-7.8 {compiled |} { | 0xff 0o377 333333333333 } 333333333503
+ test mathop-7.9 {compiled |} { | 1000000000000000000002 18 -126 } -110
+ test mathop-7.10 {compiled |} { | 0xff 0o377 3333333333333333333333 } 3333333333333333333503
+ test mathop-7.11 {compiled |: errors} -returnCodes error -body {
+ | x 0
+ } -result {can't use non-numeric string as operand of "|"}
+ test mathop-7.12 {compiled |: errors} -returnCodes error -body {
+ | nan 0
+ } -result {can't use non-numeric floating-point value as operand of "|"}
+ test mathop-7.13 {compiled |: errors} -returnCodes error -body {
+ | 0 x
+ } -result {can't use non-numeric string as operand of "|"}
+ test mathop-7.14 {compiled |: errors} -returnCodes error -body {
+ | 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "|"}
+ test mathop-7.15 {compiled |: errors} -returnCodes error -body {
+ | 0o8 0
+ } -result {can't use invalid octal number as operand of "|"}
+ test mathop-7.16 {compiled |: errors} -returnCodes error -body {
+ | 0 0o8
+ } -result {can't use invalid octal number as operand of "|"}
+ test mathop-7.17 {compiled |: errors} -returnCodes error -body {
+ | 0 [error expectedError]
+ } -result expectedError
+ test mathop-7.18 {compiled |: argument processing order} -body {
+ # Bytecode compilation known hard for 3+ arguments
+ list [catch {
+ | [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+ set op |
+ test mathop-7.19 {interpreted |} { $op } 0
+ test mathop-7.20 {interpreted |} { $op 1 } 1
+ test mathop-7.21 {interpreted |} { $op 1 2 } 3
+ test mathop-7.22 {interpreted |} { $op 3 7 6 } 7
+ test mathop-7.23 {interpreted |} -returnCodes error -body {
+ $op 1.0 2 3
+ } -result {can't use floating-point value as operand of "|"}
+ test mathop-7.24 {interpreted |} -returnCodes error -body {
+ $op 1 2 3.0
+ } -result {can't use floating-point value as operand of "|"}
+ test mathop-7.25 {interpreted |} { $op 100000000002 18 -126 } -110
+ test mathop-7.26 {interpreted |} { $op 0xff 0o377 333333333333 } 333333333503
+ test mathop-7.27 {interpreted |} { $op 1000000000000000000002 18 -126 } -110
+ test mathop-7.28 {interpreted |} { $op 0xff 0o377 3333333333333333333333 } 3333333333333333333503
+ test mathop-7.29 {interpreted |: errors} -returnCodes error -body {
+ $op x 0
+ } -result {can't use non-numeric string as operand of "|"}
+ test mathop-7.30 {interpreted |: errors} -returnCodes error -body {
+ $op nan 0
+ } -result {can't use non-numeric floating-point value as operand of "|"}
+ test mathop-7.31 {interpreted |: errors} -returnCodes error -body {
+ $op 0 x
+ } -result {can't use non-numeric string as operand of "|"}
+ test mathop-7.32 {interpreted |: errors} -returnCodes error -body {
+ $op 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "|"}
+ test mathop-7.33 {interpreted |: errors} -returnCodes error -body {
+ $op 0o8 0
+ } -result {can't use invalid octal number as operand of "|"}
+ test mathop-7.34 {interpreted |: errors} -returnCodes error -body {
+ $op 0 0o8
+ } -result {can't use invalid octal number as operand of "|"}
+ test mathop-7.35 {interpreted |: errors} -returnCodes error -body {
+ $op 0 [error expectedError]
+ } -result expectedError
+ test mathop-7.36 {interpreted |: argument processing order} -body {
+ list [catch {
+ $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+ test mathop-7.37 {| and bignums} {
+ list [| $big1 $big2] [$op $big1 $big2]
+ } {14880960170688977527789098242825693927 14880960170688977527789098242825693927}
+ test mathop-7.38 {| and bignums} {
+ list [| $big1 $wide2] [$op $big1 $wide2]
+ } {12135435435354435435342432749160988407 12135435435354435435342432749160988407}
+ test mathop-7.39 {| and bignums} {
+ list [| $big1 $small2] [$op $big1 $small2]
+ } {12135435435354435435342423948763884533 12135435435354435435342423948763884533}
+ test mathop-7.40 {| and bignums} {
+ list [| $wide1 $big2] [$op $wide1 $big2]
+ } {2746237174783836746262574867174849407 2746237174783836746262574867174849407}
+ test mathop-7.41 {| and bignums} {
+ list [| $wide1 $wide2] [$op $wide1 $wide2]
+ } {87391644647391 87391644647391}
+ test mathop-7.42 {| and bignums} {
+ list [| $wide1 $small2] [$op $wide1 $small2]
+ } {12345678912377 12345678912377}
+ test mathop-7.43 {| and bignums} {
+ list [| $small1 $big2] [$op $small1 $big2]
+ } {2746237174783836746262564892918415159 2746237174783836746262564892918415159}
+ test mathop-7.44 {| and bignums} {
+ list [| $small1 $wide2] [$op $small1 $wide2]
+ } {87321847232503 87321847232503}
+ test mathop-7.45 {| and bignums} {
+ list [| $small1 $small2] [$op $small1 $small2]
+ } {87409 87409}
+
+ test mathop-8.1 {compiled ^} { ^ } 0
+ test mathop-8.2 {compiled ^} { ^ 1 } 1
+ test mathop-8.3 {compiled ^} { ^ 1 2 } 3
+ test mathop-8.4 {compiled ^} { ^ 3 7 6 } 2
+ test mathop-8.5 {compiled ^} -returnCodes error -body {
+ ^ 1.0 2 3
+ } -result {can't use floating-point value as operand of "^"}
+ test mathop-8.6 {compiled ^} -returnCodes error -body {
+ ^ 1 2 3.0
+ } -result {can't use floating-point value as operand of "^"}
+ test mathop-8.7 {compiled ^} { ^ 100000000002 18 -126 } -100000000110
+ test mathop-8.8 {compiled ^} { ^ 0xff 0o377 333333333333 } 333333333333
+ test mathop-8.9 {compiled ^} { ^ 1000000000000000000002 18 -126 } -1000000000000000000110
+ test mathop-8.10 {compiled ^} { ^ 0xff 0o377 3333333333333333333333 } 3333333333333333333333
+ test mathop-8.11 {compiled ^: errors} -returnCodes error -body {
+ ^ x 0
+ } -result {can't use non-numeric string as operand of "^"}
+ test mathop-8.12 {compiled ^: errors} -returnCodes error -body {
+ ^ nan 0
+ } -result {can't use non-numeric floating-point value as operand of "^"}
+ test mathop-8.13 {compiled ^: errors} -returnCodes error -body {
+ ^ 0 x
+ } -result {can't use non-numeric string as operand of "^"}
+ test mathop-8.14 {compiled ^: errors} -returnCodes error -body {
+ ^ 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "^"}
+ test mathop-8.15 {compiled ^: errors} -returnCodes error -body {
+ ^ 0o8 0
+ } -result {can't use invalid octal number as operand of "^"}
+ test mathop-8.16 {compiled ^: errors} -returnCodes error -body {
+ ^ 0 0o8
+ } -result {can't use invalid octal number as operand of "^"}
+ test mathop-8.17 {compiled ^: errors} -returnCodes error -body {
+ ^ 0 [error expectedError]
+ } -result expectedError
+ test mathop-8.18 {compiled ^: argument processing order} -body {
+ # Bytecode compilation known hard for 3+ arguments
+ list [catch {
+ ^ [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+ set op ^
+ test mathop-8.19 {interpreted ^} { $op } 0
+ test mathop-8.20 {interpreted ^} { $op 1 } 1
+ test mathop-8.21 {interpreted ^} { $op 1 2 } 3
+ test mathop-8.22 {interpreted ^} { $op 3 7 6 } 2
+ test mathop-8.23 {interpreted ^} -returnCodes error -body {
+ $op 1.0 2 3
+ } -result {can't use floating-point value as operand of "^"}
+ test mathop-8.24 {interpreted ^} -returnCodes error -body {
+ $op 1 2 3.0
+ } -result {can't use floating-point value as operand of "^"}
+ test mathop-8.25 {interpreted ^} { $op 100000000002 18 -126 } -100000000110
+ test mathop-8.26 {interpreted ^} { $op 0xff 0o377 333333333333 } 333333333333
+ test mathop-8.27 {interpreted ^} { $op 1000000000000000000002 18 -126 } -1000000000000000000110
+ test mathop-8.28 {interpreted ^} { $op 0xff 0o377 3333333333333333333333 } 3333333333333333333333
+ test mathop-8.29 {interpreted ^: errors} -returnCodes error -body {
+ $op x 0
+ } -result {can't use non-numeric string as operand of "^"}
+ test mathop-8.30 {interpreted ^: errors} -returnCodes error -body {
+ $op nan 0
+ } -result {can't use non-numeric floating-point value as operand of "^"}
+ test mathop-8.31 {interpreted ^: errors} -returnCodes error -body {
+ $op 0 x
+ } -result {can't use non-numeric string as operand of "^"}
+ test mathop-8.32 {interpreted ^: errors} -returnCodes error -body {
+ $op 0 nan
+ } -result {can't use non-numeric floating-point value as operand of "^"}
+ test mathop-8.33 {interpreted ^: errors} -returnCodes error -body {
+ $op 0o8 0
+ } -result {can't use invalid octal number as operand of "^"}
+ test mathop-8.34 {interpreted ^: errors} -returnCodes error -body {
+ $op 0 0o8
+ } -result {can't use invalid octal number as operand of "^"}
+ test mathop-8.35 {interpreted ^: errors} -returnCodes error -body {
+ $op 0 [error expectedError]
+ } -result expectedError
+ test mathop-8.36 {interpreted ^: argument processing order} -body {
+ list [catch {
+ $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+ test mathop-8.37 {^ and bignums} {
+ list [^ $big1 $big2] [$op $big1 $big2]
+ } {14880247731239682873973207643969192131 14880247731239682873973207643969192131}
+ test mathop-8.38 {^ and bignums} {
+ list [^ $big1 $wide2] [$op $big1 $wide2]
+ } {12135435435354435435342354227710876723 12135435435354435435342354227710876723}
+ test mathop-8.39 {^ and bignums} {
+ list [^ $big1 $small2] [$op $big1 $small2]
+ } {12135435435354435435342423948763884437 12135435435354435435342423948763884437}
+ test mathop-8.40 {^ and bignums} {
+ list [^ $wide1 $big2] [$op $wide1 $big2]
+ } {2746237174783836746262572495752458622 2746237174783836746262572495752458622}
+ test mathop-8.41 {^ and bignums} {
+ list [^ $wide1 $wide2] [$op $wide1 $wide2]
+ } {75115763150222 75115763150222}
+ test mathop-8.42 {^ and bignums} {
+ list [^ $wide1 $small2] [$op $wide1 $small2]
+ } {12345678895656 12345678895656}
+ test mathop-8.43 {^ and bignums} {
+ list [^ $small1 $big2] [$op $small1 $big2]
+ } {2746237174783836746262564892918415126 2746237174783836746262564892918415126}
+ test mathop-8.44 {^ and bignums} {
+ list [^ $small1 $wide2] [$op $small1 $wide2]
+ } {87321847145446 87321847145446}
+ test mathop-8.45 {^ and bignums} {
+ list [^ $small1 $small2] [$op $small1 $small2]
+ } {70720 70720}
+
+ # TODO: % ** << >> - / == != < <= > >= ne in ni
+
+ test mathop-13.100 {compiled -: argument processing order} -body {
+ # Bytecode compilation known hard for 3+ arguments
+ list [catch {
+ - [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+
+ test mathop-14.100 {compiled /: argument processing order} -body {
+ # Bytecode compilation known hard for 3+ arguments
+ list [catch {
+ / [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+ } msg] $msg $x
+ } -result {1 expected 2}
+}
+
+test mathop-20.1 { zero args, return unit } {
+ set res {}
+ foreach op {+ * & ^ | ** < <= > >= == eq} {
+ lappend res [TestOp $op]
+ }
+ set res
+} {0 1 -1 0 0 1 1 1 1 1 1 1}
+test mathop-20.2 { zero args, not allowed } {
+ set exp {}
+ foreach op {~ ! << >> % != ne in ni - /} {
+ set res [TestOp $op]
+ if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
+ lappend exp 0
+ } else {
+ lappend exp $res
+ }
+ }
+ set exp
+} {0 0 0 0 0 0 0 0 0 0 0}
+test mathop-20.3 { one arg } {
+ set res {}
+ foreach val {7 8.3} {
+ foreach op {+ ** - * / < <= > >= == eq !} {
+ lappend res [TestOp $op $val]
+ }
+ }
+ set res
+} [list 7 7 -7 7 [expr {1.0/7.0}] 1 1 1 1 1 1 0 \
+ 8.3 8.3 -8.3 8.3 [expr {1.0/8.3}] 1 1 1 1 1 1 0]
+test mathop-20.4 { one arg, integer only ops } {
+ set res {}
+ foreach val {23} {
+ foreach op {& | ^ ~} {
+ lappend res [TestOp $op $val]
+ }
+ }
+ set res
+} [list 23 23 23 -24]
+test mathop-20.5 { one arg, not allowed } {
+ set exp {}
+ foreach op {% != ne in ni << >>} {
+ set res [TestOp $op 1]
+ if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
+ lappend exp 0
+ } else {
+ lappend exp $res
+ }
+ }
+ set exp
+} {0 0 0 0 0 0 0}
+test mathop-20.6 { one arg, error } {
+ set res {}
+ set exp {}
+ foreach vals {x {1 x} {1 1 x} {1 x 1}} {
+ # skipping - for now, knownbug...
+ foreach op {+ * / & | ^ **} {
+ lappend res [TestOp $op {*}$vals]
+ lappend exp "can't use non-numeric string as operand of \"$op\"\
+ ARITH DOMAIN {non-numeric string}"
+ }
+ }
+ foreach op {+ * / & | ^ **} {
+ lappend res [TestOp $op NaN 1]
+ lappend exp "can't use non-numeric floating-point value as operand of \"$op\"\
+ ARITH DOMAIN {non-numeric floating-point value}"
+ }
+ expr {$res eq $exp ? 0 : $res}
+} 0
+test mathop-20.7 { multi arg } {
+ set res {}
+ foreach vals {{1 2} {3 4 5} {4 3 2 1}} {
+ foreach op {+ - * /} {
+ lappend res [TestOp $op {*}$vals]
+ }
+ }
+ set res
+} [list 3 -1 2 0 12 -6 60 0 10 -2 24 0]
+test mathop-20.8 { multi arg, double } {
+ set res {}
+ foreach vals {{1.0 2} {3.0 4 5} {4 3.0 2 1}
+ {1.0 -1.0 1e-18} {1.0 1.0 1e-18}} {
+ foreach op {+ - * /} {
+ lappend res [TestOp $op {*}$vals]
+ }
+ }
+ set res
+} [list 3.0 -1.0 2.0 0.5 12.0 -6.0 60.0 0.15 10.0 -2.0 24.0 [expr {2.0/3}] 1e-18 2.0 -1e-18 [expr {-1.0/1e-18}] 2.0 -1e-18 1e-18 [expr {1.0/1e-18}]]
+
+test mathop-21.1 { unary ops, bitnot } {
+ set res {}
+ lappend res [TestOp ~ 7]
+ lappend res [TestOp ~ -5]
+ lappend res [TestOp ~ 354657483923456]
+ lappend res [TestOp ~ 123456789123456789123456789]
+ set res
+} [list -8 4 -354657483923457 -123456789123456789123456790]
+test mathop-21.2 { unary ops, logical not } {
+ set res {}
+ lappend res [TestOp ! 0]
+ lappend res [TestOp ! 1]
+ lappend res [TestOp ! true]
+ lappend res [TestOp ! false]
+ lappend res [TestOp ! 37]
+ lappend res [TestOp ! 8.5]
+ set res
+} [list 1 0 0 1 0 0]
+test mathop-21.3 { unary ops, negation } {
+ set res {}
+ lappend res [TestOp - 7.2]
+ lappend res [TestOp - -5]
+ lappend res [TestOp - -2147483648] ;# -2**31
+ lappend res [TestOp - -9223372036854775808] ;# -2**63
+ lappend res [TestOp - 354657483923456] ;# wide
+ lappend res [TestOp - 123456789123456789123456789] ;# big
+ set res
+} [list -7.2 5 2147483648 9223372036854775808 -354657483923456 \
+ -123456789123456789123456789]
+test mathop-21.4 { unary ops, inversion } {
+ set res {}
+ lappend res [TestOp / 1]
+ lappend res [TestOp / 5]
+ lappend res [TestOp / 5.6]
+ lappend res [TestOp / -8]
+ lappend res [TestOp / 354657483923456] ;# wide
+ lappend res [TestOp / 123456789123456789123456789] ;# big
+ set res
+} [list 1.0 0.2 0.17857142857142858 -0.125 \
+ 2.8196218755553604e-15 8.10000006561e-27]
+test mathop-21.5 { unary ops, bad values } {
+ set res {}
+ set exp {}
+ lappend res [TestOp / x]
+ lappend exp "can't use non-numeric string as operand of \"/\" ARITH DOMAIN {non-numeric string}"
+ lappend res [TestOp - x]
+ lappend exp "can't use non-numeric string as operand of \"-\" ARITH DOMAIN {non-numeric string}"
+ lappend res [TestOp ~ x]
+ lappend exp "can't use non-numeric string as operand of \"~\" ARITH DOMAIN {non-numeric string}"
+ lappend res [TestOp ! x]
+ lappend exp "can't use non-numeric string as operand of \"!\" ARITH DOMAIN {non-numeric string}"
+ lappend res [TestOp ~ 5.0]
+ lappend exp "can't use floating-point value as operand of \"~\" ARITH DOMAIN {floating-point value}"
+ expr {$res eq $exp ? 0 : $res}
+} 0
+test mathop-21.6 { unary ops, too many } {
+ set exp {}
+ foreach op {~ !} {
+ set res [TestOp $op 7 8]
+ if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
+ lappend exp 0
+ } else {
+ lappend exp $res
+ }
+ }
+ set exp
+} {0 0}
+
+test mathop-22.1 { bitwise ops } {
+ set res {}
+ foreach vals {5 {1 6} {1 2 3} {1 2 3 4}} {
+ foreach op {& | ^} {
+ lappend res [TestOp $op {*}$vals]
+ }
+ }
+ set res
+} [list 5 5 5 0 7 7 0 3 0 0 7 4]
+test mathop-22.2 { bitwise ops on bignums } {
+ set dig 50
+ set a 0x[string repeat 5 $dig]
+ set b 0x[string repeat 7 $dig]
+ set c 0x[string repeat 9 $dig]
+ set bn [expr {~$b}]
+ set cn [expr {~$c}]
+
+ set res {}
+ foreach vals [list [list $a $b] [list $a $c] [list $b $c] \
+ [list $a $bn] [list $bn $c] [list $bn $cn]] {
+ foreach op {& | ^} {
+ lappend res [TestOp $op {*}$vals]
+ }
+ }
+ set exp {}
+ foreach d {5 7 2 1 D C 1 F E 0 -D -D 8 -9 -1 -0 -E E} {
+ if {[string match "-*" $d]} {
+ set d [format %X [expr 15-0x[string range $d 1 end]]]
+ set val [expr -0x[string repeat $d $dig]-1]
+ } else {
+ set val [expr 0x[string repeat $d $dig]]
+ }
+ lappend exp $val
+ }
+ expr {$exp eq $res ? 1 : "($res != $exp"}
+} 1
+test mathop-22.3 { bitwise ops } {
+ set big1 12135435435354435435342423948763867876
+ set big2 2746237174783836746262564892918327847
+ set wide1 12345678912345
+ set wide2 87321847232215
+ set small1 87345
+ set small2 16753
+
+ set res {}
+ foreach op {& | ^} {
+ lappend res [TestOp $op $big1 $big2]
+ lappend res [TestOp $op $big1 $wide2]
+ lappend res [TestOp $op $big1 $small2]
+ lappend res [TestOp $op $wide1 $big2]
+ lappend res [TestOp $op $wide1 $wide2]
+ lappend res [TestOp $op $wide1 $small2]
+ lappend res [TestOp $op $small1 $big2]
+ lappend res [TestOp $op $small1 $wide2]
+ lappend res [TestOp $op $small1 $small2]
+ }
+ set res
+} [list \
+ 712439449294653815890598856501796 \
+ 78521450111684 \
+ 96 \
+ 2371422390785 \
+ 12275881497169 \
+ 16721 \
+ 33 \
+ 87057 \
+ 16689 \
+ 14880960170688977527789098242825693927 \
+ 12135435435354435435342432749160988407 \
+ 12135435435354435435342423948763884533 \
+ 2746237174783836746262574867174849407 \
+ 87391644647391 \
+ 12345678912377 \
+ 2746237174783836746262564892918415159 \
+ 87321847232503 \
+ 87409 \
+ 14880247731239682873973207643969192131 \
+ 12135435435354435435342354227710876723 \
+ 12135435435354435435342423948763884437 \
+ 2746237174783836746262572495752458622 \
+ 75115763150222 \
+ 12345678895656 \
+ 2746237174783836746262564892918415126 \
+ 87321847145446 \
+ 70720 \
+ ]
+test mathop-22.4 { unary ops, bad values } {
+ set res {}
+ set exp {}
+ foreach op {& | ^} {
+ lappend res [TestOp $op x 5]
+ lappend exp "can't use non-numeric string as operand of \"$op\" ARITH DOMAIN {non-numeric string}"
+ lappend res [TestOp $op 5 x]
+ lappend exp "can't use non-numeric string as operand of \"$op\" ARITH DOMAIN {non-numeric string}"
+ }
+ expr {$res eq $exp ? 0 : $res}
+} 0
+
+test mathop-23.1 { comparison ops, numerical } {
+ set res {}
+ set todo {5 {1 6} {1 2 2 3} {4 3 2 1} {5.0 5.0} {6 3 3 1} {5.0 5}}
+ lappend todo [list 2342476234762482734623842342 234827463876473 3434]
+ lappend todo [list 2653 453735910264536 453735910264537 2384762472634982746239847637]
+ lappend todo [list 2653 2384762472634982746239847637]
+ lappend todo [list 2653 -2384762472634982746239847637]
+ lappend todo [list 3789253678212653 -2384762472634982746239847637]
+ lappend todo [list 5.0 6 7.0 8 1e13 1945628567352654 1.1e20 \
+ 6734253647589123456784564378 2.3e50]
+ set a 7
+ lappend todo [list $a $a] ;# Same object
+ foreach vals $todo {
+ foreach op {< <= > >= == eq} {
+ lappend res [TestOp $op {*}$vals]
+ }
+ }
+ set res
+} [list 1 1 1 1 1 1 \
+ 1 1 0 0 0 0 \
+ 0 1 0 0 0 0 \
+ 0 0 1 1 0 0 \
+ 0 1 0 1 1 1 \
+ 0 0 0 1 0 0 \
+ 0 1 0 1 1 0 \
+ 0 0 1 1 0 0 \
+ 1 1 0 0 0 0 \
+ 1 1 0 0 0 0 \
+ 0 0 1 1 0 0 \
+ 0 0 1 1 0 0 \
+ 1 1 0 0 0 0 \
+ 0 1 0 1 1 1 \
+ ]
+test mathop-23.2 { comparison ops, string } {
+ set res {}
+ set todo {a {a b} {5 b b c} {d c b a} {xy xy} {gy ef ef ab}}
+ set a x
+ lappend todo [list $a $a]
+ foreach vals $todo {
+ foreach op {< <= > >= == eq} {
+ lappend res [TestOp $op {*}$vals]
+ }
+ }
+ set res
+} [list 1 1 1 1 1 1 \
+ 1 1 0 0 0 0 \
+ 0 1 0 0 0 0 \
+ 0 0 1 1 0 0 \
+ 0 1 0 1 1 1 \
+ 0 0 0 1 0 0 \
+ 0 1 0 1 1 1 \
+ ]
+test mathop-23.3 { comparison ops, nonequal} {
+ set res {}
+ foreach vals {{a b} {17.0 0x11} {foo foo} {10 10}} {
+ foreach op {!= ne} {
+ lappend res [TestOp $op {*}$vals]
+ }
+ }
+ set res
+} [list 1 1 0 1 0 0 0 0 ]
+
+test mathop-24.1 { binary ops } {
+ set res {}
+ foreach vals {{3 5} {17 7} {199 5} {293234675763434238476239486 17} \
+ {5 1} {0 7}} {
+ foreach op {% << >> in ni} {
+ lappend res [TestOp $op {*}$vals]
+ }
+ }
+ set res
+} [list 3 96 0 0 1 3 2176 0 0 1 4 6368 6 0 1 \
+ 14 38434855421664852505557661908992 2237203031642412097749 0 1 \
+ 0 10 2 0 1 0 0 0 0 1]
+test mathop-24.2 { binary ops, modulo } {
+ # Test different combinations to get all code paths
+ set res {}
+
+ set bigbig 14372423674564535234543545248972634923869
+ set big 12135435435354435435342423948763867876
+ set wide 12345678912345
+ set negwide -12345678912345
+ set small 5
+ set neg -5
+
+ lappend res [TestOp % $bigbig $big]
+ lappend res [TestOp % $wide $big]
+ lappend res [TestOp % $negwide $big]
+ lappend res [TestOp % $small $big]
+ lappend res [TestOp % $neg $big]
+ lappend res [TestOp % $small $wide]
+ lappend res [TestOp % $neg $wide]
+ lappend res [TestOp % $wide $small]
+ set res
+} [list 4068119104883679098115293636215358685 \
+ 12345678912345 \
+ 12135435435354435435342411603084955531 \
+ 5 \
+ 12135435435354435435342423948763867871 \
+ 5 \
+ 12345678912340 \
+ 0 \
+ ]
+test mathop-24.3 { binary ops, bad values } {
+ set res {}
+ set exp {}
+ foreach op {% << >>} {
+ lappend res [TestOp $op x 1]
+ lappend exp "can't use non-numeric string as operand of \"$op\" ARITH DOMAIN {non-numeric string}"
+ lappend res [TestOp $op 1 x]
+ lappend exp "can't use non-numeric string as operand of \"$op\" ARITH DOMAIN {non-numeric string}"
+ }
+ foreach op {% << >>} {
+ lappend res [TestOp $op 5.0 1]
+ lappend exp "can't use floating-point value as operand of \"$op\" ARITH DOMAIN {floating-point value}"
+ lappend res [TestOp $op 1 5.0]
+ lappend exp "can't use floating-point value as operand of \"$op\" ARITH DOMAIN {floating-point value}"
+ }
+ foreach op {in ni} {
+ lappend res [TestOp $op 5 "a b \{ c"]
+ lappend exp "unmatched open brace in list TCL VALUE LIST BRACE"
+ }
+ lappend res [TestOp % 5 0]
+ lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
+ lappend res [TestOp % 9838923468297346238478737647637375 0]
+ lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
+ lappend res [TestOp / 5 0]
+ lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
+ lappend res [TestOp / 9838923468297346238478737647637375 0]
+ lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
+ expr {$res eq $exp ? 0 : $res}
+} 0
+test mathop-24.4 { binary ops, negative shift } {
+ set res {}
+
+ set big -12135435435354435435342423948763867876
+ set wide -12345678912345
+ set small -1
+
+ lappend res [TestOp << 10 $big]
+ lappend res [TestOp << 10 $wide]
+ lappend res [TestOp << 10 $small]
+ lappend res [TestOp >> 10 $big]
+ lappend res [TestOp >> 10 $wide]
+ lappend res [TestOp >> 10 $small]
+
+ set exp [lrepeat 6 "negative shift argument NONE"]
+ expr {$res eq $exp ? 0 : $res}
+} 0
+test mathop-24.5 { binary ops, large shift } {
+ set res {}
+ set exp {}
+
+ set big 12135435435354435435342423948763867876
+ set wide 12345678912345
+ set small 1
+
+ lappend res [TestOp << 1 2147483648]
+ lappend exp "integer value too large to represent NONE"
+ lappend res [TestOp << 1 4294967296]
+ lappend exp "integer value too large to represent NONE"
+ lappend res [TestOp << $small $wide]
+ lappend exp "integer value too large to represent NONE"
+ lappend res [TestOp << $small $big]
+ lappend exp "integer value too large to represent NONE"
+ lappend res [TestOp >> $big $wide]
+ lappend exp 0
+ lappend res [TestOp >> $big $big]
+ lappend exp 0
+ lappend res [TestOp >> $small 70]
+ lappend exp 0
+ lappend res [TestOp >> $wide 70]
+ lappend exp 0
+ lappend res [TestOp >> -$big $wide]
+ lappend exp -1
+ lappend res [TestOp >> -$wide $wide]
+ lappend exp -1
+ lappend res [TestOp >> -$small $wide]
+ lappend exp -1
+ lappend res [TestOp >> -$small 70]
+ lappend exp -1
+ lappend res [TestOp >> -$wide 70]
+ lappend exp -1
+
+ expr {$res eq $exp ? 0 : $res}
+} 0
+test mathop-24.6 { binary ops, shift } {
+ # Test different combinations to get all code paths
+ set res {}
+
+ set bigbig 14372423674564535234543545248972634923869
+ set big 12135435435354435435342423948763867876
+ set wide 12345678912345
+ set negwide -12345678912345
+ set small 5
+ set neg -5
+
+ lappend res [TestOp << $wide $small]
+ lappend res [TestOp >> $wide $small]
+ set res
+} [list 395061725195040 \
+ 385802466010 \
+ ]
+test mathop-24.7 { binary ops, list search } {
+ set res {}
+
+ foreach op {in ni} {
+ lappend res [TestOp $op 5 {7 5 8}]
+ lappend res [TestOp $op hej {foo bar hej}]
+ lappend res [TestOp $op 5 {7 0x5 8}]
+ }
+ set res
+} [list 1 1 0 0 0 1]
+test mathop-24.8 { binary ops, too many } {
+ set exp {}
+ foreach op {<< >> % != ne in ni ~ !} {
+ set res [TestOp $op 7 8 9]
+ if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
+ lappend exp 0
+ } else {
+ lappend exp $res
+ }
+ }
+ set exp
+} {0 0 0 0 0 0 0 0 0}
+
+test mathop-25.1 { exp operator } {TestOp ** } 1
+test mathop-25.2 { exp operator } {TestOp ** 0 } 0
+test mathop-25.3 { exp operator } {TestOp ** 0 5} 0
+test mathop-25.4 { exp operator } {TestOp ** 7.5 } 7.5
+test mathop-25.5 { exp operator } {TestOp ** 1 5} 1
+test mathop-25.6 { exp operator } {TestOp ** 5 1} 5
+test mathop-25.7 { exp operator } {TestOp ** 4 3 2 1} 262144
+test mathop-25.8 { exp operator } {TestOp ** 5.5 4} 915.0625
+test mathop-25.9 { exp operator } {TestOp ** 16 3.5} 16384.0
+test mathop-25.10 { exp operator } {TestOp ** 3.5 0} 1.0
+test mathop-25.11 { exp operator } {TestOp ** 378 0} 1
+test mathop-25.12 { exp operator } {TestOp ** 7.8 1} 7.8
+test mathop-25.13 { exp operator } {TestOp ** 748 1} 748
+test mathop-25.14 { exp operator } {TestOp ** 1.6 -1} 0.625
+test mathop-25.15 { exp operator } {TestOp ** 683 -1} 0
+test mathop-25.16 { exp operator } {TestOp ** 1 -1} 1
+test mathop-25.17 { exp operator } {TestOp ** -1 -1} -1
+test mathop-25.18 { exp operator } {TestOp ** -1 -2} 1
+test mathop-25.19 { exp operator } {TestOp ** -1 3} -1
+test mathop-25.20 { exp operator } {TestOp ** -1 4} 1
+test mathop-25.21 { exp operator } {TestOp ** 2 63} 9223372036854775808
+test mathop-25.22 { exp operator } {TestOp ** 83756485763458746358734658473567847567473 2} 7015148907444467657897585474493757781161998914521537835809623408157343003287605729
+test mathop-25.23 { exp operator errors } {
+ set res {}
+ set exp {}
+
+ set huge [string repeat 145782 1000]
+ set big 12135435435354435435342423948763867876
+ set wide 12345678912345
+ set small 2
+
+ lappend res [TestOp ** 0 -5]
+ lappend exp "exponentiation of zero by negative power ARITH DOMAIN {exponentiation of zero by negative power}"
+ lappend res [TestOp ** 0.0 -5.0]
+ lappend exp "exponentiation of zero by negative power ARITH DOMAIN {exponentiation of zero by negative power}"
+ lappend res [TestOp ** $small $wide]
+ lappend exp "exponent too large NONE"
+ lappend res [TestOp ** 2 $big]
+ lappend exp "exponent too large NONE"
+ lappend res [TestOp ** $huge 2.1]
+ lappend exp "Inf"
+ lappend res [TestOp ** 2 foo]
+ lappend exp "can't use non-numeric string as operand of \"**\" ARITH DOMAIN {non-numeric string}"
+ lappend res [TestOp ** foo 2]
+ lappend exp "can't use non-numeric string as operand of \"**\" ARITH DOMAIN {non-numeric string}"
+
+ expr {$res eq $exp ? 0 : $res}
+} 0
+
+test mathop-26.1 { misc ops, size combinations } {
+ set big1 12135435435354435435342423948763867876
+ set big2 2746237174783836746262564892918327847
+ set wide1 87321847232215
+ set wide2 12345678912345
+ set small1 87345
+ set small2 16753
+
+ set res {}
+ foreach op {+ * - /} {
+ lappend res [TestOp $op $big1 $big2]
+ lappend res [TestOp $op $big1 $wide2]
+ lappend res [TestOp $op $big1 $small2]
+ lappend res [TestOp $op $wide1 $big2]
+ lappend res [TestOp $op $wide1 $wide2]
+ lappend res [TestOp $op $wide1 $small2]
+ lappend res [TestOp $op $small1 $big2]
+ lappend res [TestOp $op $small1 $wide2]
+ lappend res [TestOp $op $small1 $small2]
+ }
+ set res
+} [list \
+ 14881672610138272181604988841682195723 \
+ 12135435435354435435342436294442780221 \
+ 12135435435354435435342423948763884629 \
+ 2746237174783836746262652214765560062 \
+ 99667526144560 \
+ 87321847248968 \
+ 2746237174783836746262564892918415192 \
+ 12345678999690 \
+ 104098 \
+ 33326783924759424684447891401270222910405366244661685890993770489959542972 \
+ 149820189346379518024969783068410988366610965329220 \
+ 203304949848492856848291628413641078526628 \
+ 239806503039903915972546163440347114360602909991105 \
+ 1078047487961768329845194175 \
+ 1462902906681297895 \
+ 239870086031494220602303730571951345796215 \
+ 1078333324598774025 \
+ 1463290785 \
+ 9389198260570598689079859055845540029 \
+ 12135435435354435435342411603084955531 \
+ 12135435435354435435342423948763851123 \
+ -2746237174783836746262477571071095632 \
+ 74976168319870 \
+ 87321847215462 \
+ -2746237174783836746262564892918240502 \
+ -12345678825000 \
+ 70592 \
+ 4 \
+ 982970278225822587257201 \
+ 724373869477373332259441529801460 \
+ 0 \
+ 7 \
+ 5212311062 \
+ 0 \
+ 0 \
+ 5 \
+ ]
+test mathop-26.2 { misc ops, corner cases } {
+ set res {}
+ lappend res [TestOp - 0 -2147483648] ;# -2**31
+ lappend res [TestOp - 0 -9223372036854775808] ;# -2**63
+ lappend res [TestOp / -9223372036854775808 -1]
+ lappend res [TestOp * 2147483648 2]
+ lappend res [TestOp * 9223372036854775808 2]
+ set res
+} [list 2147483648 9223372036854775808 9223372036854775808 4294967296 18446744073709551616]
+
+if 0 {
+ # Compare ops to expr bytecodes
+ namespace import ::tcl::mathop::*
+ proc _X {a b c} {
+ set x [+ $a [- $b $c]]
+ set y [expr {$a + ($b - $c)}]
+ set z [< $a $b $c]
+ }
+ set ::tcl_traceCompile 2
+ _X 3 4 5
+ set ::tcl_traceCompile 0
+}
+
+# cleanup
+namespace delete ::testmathop
+namespace delete ::testmathop2
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/misc.test b/pkgs/msgcat/tests/misc.test
new file mode 100644
index 0000000..fe19ebe
--- /dev/null
+++ b/pkgs/msgcat/tests/misc.test
@@ -0,0 +1,76 @@
+# Commands covered: various
+#
+# This file contains a collection of miscellaneous Tcl tests that
+# don't fit naturally in any of the other test files. Many of these
+# tests are pathological cases that caused bugs in earlier Tcl
+# releases.
+#
+# Copyright (c) 1992-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testhashsystemhash [llength [info commands testhashsystemhash]]
+
+test misc-1.1 {error in variable ref. in command in array reference} {
+ proc tstProc {} {
+ global a
+
+ set tst $a([winfo name $zz])
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ }
+ set msg {}
+ list [catch tstProc msg] $msg
+} {1 {can't read "zz": no such variable}}
+test misc-1.2 {error in variable ref. in command in array reference} {
+ proc tstProc {} "
+ global a
+
+ set tst \$a(\[winfo name \$\{zz)
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ "
+ set msg {}
+ join [list [catch tstProc msg] $msg $::errorInfo] \n
+} [subst -novariables -nocommands {1
+missing close-brace for variable name
+missing close-brace for variable name
+ while executing
+"set tst $a([winfo name $\{zz)
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a ..."
+ (procedure "tstProc" line 4)
+ invoked from within
+"tstProc"}]
+
+for {set i 1} {$i<300} {incr i} {
+ test misc-2.$i {hash table with sys-alloc} testhashsystemhash \
+ "testhashsystemhash $i" OK
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/msgcat.test b/pkgs/msgcat/tests/msgcat.test
new file mode 100644
index 0000000..0669810
--- /dev/null
+++ b/pkgs/msgcat/tests/msgcat.test
@@ -0,0 +1,618 @@
+# This file contains a collection of tests for the msgcat package.
+# Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1998 Mark Harrison.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Contributions from Don Porter, NIST, 2002. (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.
+#
+# Note that after running these tests, entries will be left behind in the
+# message catalogs for locales foo, foo_BAR, and foo_BAR_baz.
+
+package require Tcl 8.2
+if {[catch {package require tcltest 2}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2 required."
+ return
+}
+if {[catch {package require msgcat 1.4.2}]} {
+ puts stderr "Skipping tests in [info script]. No msgcat 1.4.2 found to test."
+ return
+}
+
+namespace eval ::msgcat::test {
+ namespace import ::msgcat::*
+ namespace import ::tcltest::test
+ namespace import ::tcltest::cleanupTests
+ namespace import ::tcltest::temporaryDirectory
+ namespace import ::tcltest::make*
+ namespace import ::tcltest::remove*
+
+ # Tests msgcat-0.*: locale initialization
+
+ proc PowerSet {l} {
+ if {[llength $l] == 0} {return [list [list]]}
+ set element [lindex $l 0]
+ set rest [lrange $l 1 end]
+ set result [list]
+ foreach x [PowerSet $rest] {
+ lappend result [linsert $x 0 $element]
+ lappend result $x
+ }
+ return $result
+ }
+
+ variable envVars {LC_ALL LC_MESSAGES LANG}
+ variable count 0
+ variable body
+ variable result
+ variable setVars
+ foreach setVars [PowerSet $envVars] {
+ set result [string tolower [lindex $setVars 0]]
+ if {[string length $result] == 0} {
+ if {[info exists ::tcl::mac::locale]} {
+ set result [string tolower \
+ [msgcat::ConvertLocale $::tcl::mac::locale]]
+ } else {
+ set result c
+ }
+ }
+ test msgcat-0.$count [list \
+ locale initialization from environment variables $setVars \
+ ] -setup {
+ variable var
+ foreach var $envVars {
+ catch {variable $var $::env($var)}
+ catch {unset ::env($var)}
+ }
+ foreach var $setVars {
+ set ::env($var) $var
+ }
+ interp create [namespace current]::i
+ i eval [list package ifneeded msgcat [package provide msgcat] \
+ [package ifneeded msgcat [package provide msgcat]]]
+ i eval package require msgcat
+ } -cleanup {
+ interp delete [namespace current]::i
+ foreach var $envVars {
+ catch {unset ::env($var)}
+ catch {set ::env($var) [set [namespace current]::$var]}
+ }
+ } -body {i eval msgcat::mclocale} -result $result
+ incr count
+ }
+ catch {unset result}
+
+ # Could add tests of initialization from Windows registry here.
+ # Use a fake registry package.
+
+ # Tests msgcat-1.*: [mclocale], [mcpreferences]
+
+ test msgcat-1.3 {mclocale set, single element} -setup {
+ variable locale [mclocale]
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mclocale en
+ } -result en
+
+ test msgcat-1.4 {mclocale get, single element} -setup {
+ variable locale [mclocale]
+ mclocale en
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mclocale
+ } -result en
+
+ test msgcat-1.5 {mcpreferences, single element} -setup {
+ variable locale [mclocale]
+ mclocale en
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mcpreferences
+ } -result {en {}}
+
+ test msgcat-1.6 {mclocale set, two elements} -setup {
+ variable locale [mclocale]
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mclocale en_US
+ } -result en_us
+
+ test msgcat-1.7 {mclocale get, two elements} -setup {
+ variable locale [mclocale]
+ mclocale en_US
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mclocale
+ } -result en_us
+
+ test msgcat-1.8 {mcpreferences, two elements} -setup {
+ variable locale [mclocale]
+ mclocale en_US
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mcpreferences
+ } -result {en_us en {}}
+
+ test msgcat-1.9 {mclocale set, three elements} -setup {
+ variable locale [mclocale]
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mclocale en_US_funky
+ } -result en_us_funky
+
+ test msgcat-1.10 {mclocale get, three elements} -setup {
+ variable locale [mclocale]
+ mclocale en_US_funky
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mclocale
+ } -result en_us_funky
+
+ test msgcat-1.11 {mcpreferences, three elements} -setup {
+ variable locale [mclocale]
+ mclocale en_US_funky
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mcpreferences
+ } -result {en_us_funky en_us en {}}
+
+ test msgcat-1.12 {mclocale set, reject evil input} -setup {
+ variable locale [mclocale]
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mclocale /path/to/evil/code
+ } -returnCodes error -match glob -result {invalid newLocale value *}
+
+ test msgcat-1.13 {mclocale set, reject evil input} -setup {
+ variable locale [mclocale]
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mclocale looks/ok/../../../../but/is/path/to/evil/code
+ } -returnCodes error -match glob -result {invalid newLocale value *}
+
+ # Tests msgcat-2.*: [mcset], [mcmset], namespace partitioning
+
+ test msgcat-2.1 {mcset, global scope} {
+ namespace eval :: ::msgcat::mcset foo_BAR text1 text2
+ } {text2}
+
+ test msgcat-2.2 {mcset, global scope, default} {
+ namespace eval :: ::msgcat::mcset foo_BAR text3
+ } {text3}
+
+ test msgcat-2.2.1 {mcset, namespace overlap} {
+ namespace eval baz {::msgcat::mcset foo_BAR con1 con1baz}
+ } {con1baz}
+
+ test msgcat-2.3 {mcset, namespace overlap} -setup {
+ namespace eval bar {::msgcat::mcset foo_BAR con1 con1bar}
+ namespace eval baz {::msgcat::mcset foo_BAR con1 con1baz}
+ variable locale [mclocale]
+ mclocale foo_BAR
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ namespace eval bar {::msgcat::mc con1}
+ } -result con1bar
+
+ test msgcat-2.4 {mcset, namespace overlap} -setup {
+ namespace eval bar {::msgcat::mcset foo_BAR con1 con1bar}
+ namespace eval baz {::msgcat::mcset foo_BAR con1 con1baz}
+ variable locale [mclocale]
+ mclocale foo_BAR
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ namespace eval baz {::msgcat::mc con1}
+ } -result con1baz
+
+ test msgcat-2.5 {mcmset, global scope} -setup {
+ namespace eval :: {
+ ::msgcat::mcmset foo_BAR {
+ src1 trans1
+ src2 trans2
+ }
+ }
+ variable locale [mclocale]
+ mclocale foo_BAR
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ namespace eval :: {
+ ::msgcat::mc src1
+ }
+ } -result trans1
+
+ test msgcat-2.6 {mcmset, namespace overlap} -setup {
+ namespace eval bar {::msgcat::mcmset foo_BAR {con2 con2bar}}
+ namespace eval baz {::msgcat::mcmset foo_BAR {con2 con2baz}}
+ variable locale [mclocale]
+ mclocale foo_BAR
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ namespace eval bar {::msgcat::mc con2}
+ } -result con2bar
+
+ test msgcat-2.7 {mcmset, namespace overlap} -setup {
+ namespace eval bar {::msgcat::mcmset foo_BAR {con2 con2bar}}
+ namespace eval baz {::msgcat::mcmset foo_BAR {con2 con2baz}}
+ variable locale [mclocale]
+ mclocale foo_BAR
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ namespace eval baz {::msgcat::mc con2}
+ } -result con2baz
+
+ # Tests msgcat-3.*: [mcset], [mc], catalog "inheritance"
+ #
+ # Test mcset and mc, ensuring that more specific locales
+ # (e.g. en_UK) will search less specific locales
+ # (e.g. en) for translation strings.
+ #
+ # Do this for the 15 permutations of
+ # locales: {foo foo_BAR foo_BAR_baz}
+ # strings: {ov0 ov1 ov2 ov3 ov4}
+ # locale ROOT defines ov0, ov1, ov2, ov3
+ # locale foo defines ov1, ov2, ov3
+ # locale foo_BAR defines ov2, ov3
+ # locale foo_BAR_BAZ defines ov3
+ # (ov4 is defined in none)
+ # So,
+ # ov3 should be resolved in foo, foo_BAR, foo_BAR_baz
+ # ov2 should be resolved in foo, foo_BAR
+ # ov2 should resolve to foo_BAR in foo_BAR_baz
+ # ov1 should be resolved in foo
+ # ov1 should resolve to foo in foo_BAR, foo_BAR_baz
+ # ov4 should be resolved in none, and call mcunknown
+ #
+ variable count 2
+ variable result
+ array set result {
+ foo,ov0 ov0_ROOT foo,ov1 ov1_foo foo,ov2 ov2_foo
+ foo,ov3 ov3_foo foo,ov4 ov4
+ foo_BAR,ov0 ov0_ROOT foo_BAR,ov1 ov1_foo foo_BAR,ov2 ov2_foo_BAR
+ foo_BAR,ov3 ov3_foo_BAR foo_BAR,ov4 ov4
+ foo_BAR_baz,ov0 ov0_ROOT foo_BAR_baz,ov1 ov1_foo
+ foo_BAR_baz,ov2 ov2_foo_BAR
+ foo_BAR_baz,ov3 ov3_foo_BAR_baz foo_BAR_baz,ov4 ov4
+ }
+ variable loc
+ variable string
+ foreach loc {foo foo_BAR foo_BAR_baz} {
+ foreach string {ov0 ov1 ov2 ov3 ov4} {
+ test msgcat-3.$count {mcset, overlap} -setup {
+ mcset {} ov0 ov0_ROOT
+ mcset {} ov1 ov1_ROOT
+ mcset {} ov2 ov2_ROOT
+ mcset {} ov3 ov3_ROOT
+ mcset foo ov1 ov1_foo
+ mcset foo ov2 ov2_foo
+ mcset foo ov3 ov3_foo
+ mcset foo_BAR ov2 ov2_foo_BAR
+ mcset foo_BAR ov3 ov3_foo_BAR
+ mcset foo_BAR_baz ov3 ov3_foo_BAR_baz
+ variable locale [mclocale]
+ mclocale $loc
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc $string
+ } -result $result($loc,$string)
+ incr count
+ }
+ }
+ catch {unset result}
+
+ # Tests msgcat-4.*: [mcunknown]
+
+ test msgcat-4.2 {mcunknown, default} -setup {
+ mcset foo unk1 "unknown 1"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc unk1
+ } -result {unknown 1}
+
+ test msgcat-4.3 {mcunknown, default} -setup {
+ mcset foo unk1 "unknown 1"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc unk2
+ } -result unk2
+
+ test msgcat-4.4 {mcunknown, overridden} -setup {
+ rename ::msgcat::mcunknown SavedMcunknown
+ proc ::msgcat::mcunknown {dom s} {
+ return unknown:$dom:$s
+ }
+ mcset foo unk1 "unknown 1"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ rename ::msgcat::mcunknown {}
+ rename SavedMcunknown ::msgcat::mcunknown
+ } -body {
+ mc unk1
+ } -result {unknown 1}
+
+ test msgcat-4.5 {mcunknown, overridden} -setup {
+ rename ::msgcat::mcunknown SavedMcunknown
+ proc ::msgcat::mcunknown {dom s} {
+ return unknown:$dom:$s
+ }
+ mcset foo unk1 "unknown 1"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ rename ::msgcat::mcunknown {}
+ rename SavedMcunknown ::msgcat::mcunknown
+ } -body {
+ mc unk2
+ } -result {unknown:foo:unk2}
+
+ test msgcat-4.6 {mcunknown, uplevel context} -setup {
+ rename ::msgcat::mcunknown SavedMcunknown
+ proc ::msgcat::mcunknown {dom s} {
+ return "unknown:$dom:$s:[expr {[info level] - 1}]"
+ }
+ mcset foo unk1 "unknown 1"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ rename ::msgcat::mcunknown {}
+ rename SavedMcunknown ::msgcat::mcunknown
+ } -body {
+ mc unk2
+ } -result unknown:foo:unk2:[info level]
+
+ # Tests msgcat-5.*: [mcload]
+
+ variable locales {{} foo foo_BAR foo_BAR_baz}
+ set msgdir [makeDirectory msgdir]
+ foreach loc $locales {
+ if { $loc eq {} } {
+ set msg ROOT
+ } else {
+ set msg [string tolower $loc]
+ }
+ makeFile [list ::msgcat::mcset $loc abc abc-$loc] $msg.msg $msgdir
+ }
+ variable count 1
+ foreach loc {foo foo_BAR foo_BAR_baz} {
+ test msgcat-5.$count {mcload} -setup {
+ variable locale [mclocale]
+ mclocale $loc
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mcload $msgdir
+ } -result [expr { $count+1 }]
+ incr count
+ }
+
+ # Even though foo_BAR_notexist does not exist,
+ # foo_BAR, foo and the root should be loaded.
+ test msgcat-5.4 {mcload} -setup {
+ variable locale [mclocale]
+ mclocale foo_BAR_notexist
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mcload $msgdir
+ } -result 3
+
+ test msgcat-5.5 {mcload} -setup {
+ variable locale [mclocale]
+ mclocale no_FI_notexist
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mcload $msgdir
+ } -result 1
+
+ test msgcat-5.6 {mcload} -setup {
+ variable locale [mclocale]
+ mclocale foo
+ mcload $msgdir
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc abc
+ } -result abc-foo
+
+ test msgcat-5.7 {mcload} -setup {
+ variable locale [mclocale]
+ mclocale foo_BAR
+ mcload $msgdir
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc abc
+ } -result abc-foo_BAR
+
+ test msgcat-5.8 {mcload} -setup {
+ variable locale [mclocale]
+ mclocale foo_BAR_baz
+ mcload $msgdir
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc abc
+ } -result abc-foo_BAR_baz
+
+ test msgcat-5.9 {mcload} -setup {
+ variable locale [mclocale]
+ mclocale no_FI_notexist
+ mcload $msgdir
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc abc
+ } -result abc-
+
+ test msgcat-5.10 {mcload} -setup {
+ rename ::msgcat::mcunknown SavedMcunknown
+ proc ::msgcat::mcunknown {dom s} {
+ return unknown:$dom:$s
+ }
+ variable locale [mclocale]
+ mclocale no_FI_notexist
+ mcload $msgdir
+ } -cleanup {
+ mclocale $locale
+ rename ::msgcat::mcunknown {}
+ rename SavedMcunknown ::msgcat::mcunknown
+ } -body {
+ mc def
+ } -result unknown:no_fi_notexist:def
+
+ foreach loc $locales {
+ if { $loc eq {} } {
+ set msg ROOT
+ } else {
+ set msg [string tolower $loc]
+ }
+ removeFile $msg.msg $msgdir
+ }
+ removeDirectory msgdir
+
+ # Tests msgcat-6.*: [mcset], [mc] namespace inheritance
+#
+# Test mcset and mc, ensuring that resolution for messages
+# proceeds from the current ns to its parent and so on to the
+# global ns.
+#
+# Do this for the 12 permutations of
+# locales: foo
+# namespaces: foo foo::bar foo::bar::baz
+# strings: {ov1 ov2 ov3 ov4}
+# namespace ::foo defines ov1, ov2, ov3
+# namespace ::foo::bar defines ov2, ov3
+# namespace ::foo::bar::baz defines ov3
+#
+# ov4 is not defined in any namespace.
+#
+# So,
+# ov3 should be resolved in ::foo::bar::baz, ::foo::bar, ::foo;
+# ov2 should be resolved in ::foo, ::foo::bar
+# ov1 should be resolved in ::foo
+# ov4 should be resolved in none, and call mcunknown
+#
+
+ variable result
+ array set result {
+ foo,ov1 ov1_foo foo,ov2 ov2_foo foo,ov3 ov3_foo foo,ov4 ov4
+ foo::bar,ov1 ov1_foo foo::bar,ov2 ov2_foo_bar
+ foo::bar,ov3 ov3_foo_bar foo::bar,ov4 ov4 foo::bar::baz,ov1 ov1_foo
+ foo::bar::baz,ov2 ov2_foo_bar foo::bar::baz,ov3 ov3_foo_bar_baz
+ foo::bar::baz,ov4 ov4
+ }
+ variable count 1
+ variable ns
+ foreach ns {foo foo::bar foo::bar::baz} {
+ foreach string {ov1 ov2 ov3 ov4} {
+ test msgcat-6.$count {mcset, overlap} -setup {
+ namespace eval foo {
+ ::msgcat::mcset foo ov1 ov1_foo
+ ::msgcat::mcset foo ov2 ov2_foo
+ ::msgcat::mcset foo ov3 ov3_foo
+ namespace eval bar {
+ ::msgcat::mcset foo ov2 ov2_foo_bar
+ ::msgcat::mcset foo ov3 ov3_foo_bar
+ namespace eval baz {
+ ::msgcat::mcset foo ov3 "ov3_foo_bar_baz"
+ }
+ }
+
+ }
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ namespace delete foo
+ } -body {
+ namespace eval $ns [list ::msgcat::mc $string]
+ } -result $result($ns,$string)
+ incr count
+ }
+ }
+
+ # Tests msgcat-7.*: [mc] extra args processed by [format]
+
+ test msgcat-7.1 {mc extra args go through to format} -setup {
+ mcset foo format1 "this is a test"
+ mcset foo format2 "this is a %s"
+ mcset foo format3 "this is a %s %s"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc format1 "good test"
+ } -result "this is a test"
+
+ test msgcat-7.2 {mc extra args go through to format} -setup {
+ mcset foo format1 "this is a test"
+ mcset foo format2 "this is a %s"
+ mcset foo format3 "this is a %s %s"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc format2 "good test"
+ } -result "this is a good test"
+
+ test msgcat-7.3 {mc errors from format are propagated} -setup {
+ mcset foo format1 "this is a test"
+ mcset foo format2 "this is a %s"
+ mcset foo format3 "this is a %s %s"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ catch {mc format3 "good test"}
+ } -result 1
+
+ test msgcat-7.4 {mc, extra args are given to unknown} -setup {
+ mcset foo format1 "this is a test"
+ mcset foo format2 "this is a %s"
+ mcset foo format3 "this is a %s %s"
+ variable locale [mclocale]
+ mclocale foo
+ } -cleanup {
+ mclocale $locale
+ } -body {
+ mc "this is a %s" "good test"
+ } -result "this is a good test"
+
+ cleanupTests
+}
+namespace delete ::msgcat::test
+return
+
diff --git a/pkgs/msgcat/tests/namespace-old.test b/pkgs/msgcat/tests/namespace-old.test
new file mode 100644
index 0000000..1d8ba31
--- /dev/null
+++ b/pkgs/msgcat/tests/namespace-old.test
@@ -0,0 +1,750 @@
+# Functionality covered: this file contains slightly modified versions of
+# the original tests written by Mike McLennan of Lucent Technologies for
+# the procedures in tclNamesp.c that implement Tcl's basic support for
+# namespaces. Other namespace-related tests appear in namespace.test
+# and variable.test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1997 Lucent Technologies
+# 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2.2
+ namespace import -force ::tcltest::*
+}
+
+# Clear out any namespaces called test_ns_*
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+
+test namespace-old-1.1 {usage for "namespace" command} {
+ list [catch {namespace} msg] $msg
+} {1 {wrong # args: should be "namespace subcommand ?arg ...?"}}
+test namespace-old-1.2 {global namespace's name is "::" or {}} {
+ list [namespace current] [namespace eval {} {namespace current}]
+} {:: ::}
+test namespace-old-1.3 {usage for "namespace eval"} {
+ list [catch {namespace eval} msg] $msg
+} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
+test namespace-old-1.4 {create new namespaces} {
+ list [lsort [namespace children :: test_ns_simple*]] \
+ [namespace eval test_ns_simple {}] \
+ [namespace eval test_ns_simple2 {}] \
+ [lsort [namespace children :: test_ns_simple*]]
+} {{} {} {} {::test_ns_simple ::test_ns_simple2}}
+test namespace-old-1.5 {access a new namespace} {
+ namespace eval test_ns_simple { namespace current }
+} {::test_ns_simple}
+test namespace-old-1.6 {usage for "namespace eval"} {
+ list [catch {namespace eval} msg] $msg
+} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
+test namespace-old-1.7 {usage for "namespace eval"} {
+ list [catch {namespace eval test_ns_xyzzy} msg] $msg
+} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
+test namespace-old-1.8 {command "namespace eval" concatenates args} {
+ namespace eval test_ns_simple namespace current
+} {::test_ns_simple}
+test namespace-old-1.9 {add elements to a namespace} {
+ namespace eval test_ns_simple {
+ variable test_ns_x 0
+ proc test {test_ns_x} {
+ return "test: $test_ns_x"
+ }
+ }
+} {}
+test namespace-old-1.10 {commands in a namespace} {
+ namespace eval test_ns_simple { info commands [namespace current]::*}
+} {::test_ns_simple::test}
+test namespace-old-1.11 {variables in a namespace} {
+ namespace eval test_ns_simple { info vars [namespace current]::* }
+} {::test_ns_simple::test_ns_x}
+test namespace-old-1.12 {global vars are separate from locals vars} {
+ list [test_ns_simple::test 123] [set test_ns_simple::test_ns_x]
+} {{test: 123} 0}
+test namespace-old-1.13 {add to an existing namespace} {
+ namespace eval test_ns_simple {
+ variable test_ns_y 123
+ proc _backdoor {cmd} {
+ eval $cmd
+ }
+ }
+} ""
+test namespace-old-1.14 {commands in a namespace} {
+ lsort [namespace eval test_ns_simple {info commands [namespace current]::*}]
+} {::test_ns_simple::_backdoor ::test_ns_simple::test}
+test namespace-old-1.15 {variables in a namespace} {
+ lsort [namespace eval test_ns_simple {info vars [namespace current]::*}]
+} {::test_ns_simple::test_ns_x ::test_ns_simple::test_ns_y}
+test namespace-old-1.16 {variables in a namespace} {
+ lsort [info vars test_ns_simple::*]
+} {::test_ns_simple::test_ns_x ::test_ns_simple::test_ns_y}
+test namespace-old-1.17 {commands in a namespace are hidden} {
+ list [catch "_backdoor {return yes!}" msg] $msg
+} {1 {invalid command name "_backdoor"}}
+test namespace-old-1.18 {using namespace qualifiers} {
+ list [catch "test_ns_simple::_backdoor {return yes!}" msg] $msg
+} {0 yes!}
+test namespace-old-1.19 {using absolute namespace qualifiers} {
+ list [catch "::test_ns_simple::_backdoor {return yes!}" msg] $msg
+} {0 yes!}
+test namespace-old-1.20 {variables in a namespace are hidden} {
+ list [catch "set test_ns_x" msg] $msg [catch "set test_ns_y" msg] $msg
+} {1 {can't read "test_ns_x": no such variable} 1 {can't read "test_ns_y": no such variable}}
+test namespace-old-1.21 {using namespace qualifiers} {
+ list [catch "set test_ns_simple::test_ns_x" msg] $msg \
+ [catch "set test_ns_simple::test_ns_y" msg] $msg
+} {0 0 0 123}
+test namespace-old-1.22 {using absolute namespace qualifiers} {
+ list [catch "set ::test_ns_simple::test_ns_x" msg] $msg \
+ [catch "set ::test_ns_simple::test_ns_y" msg] $msg
+} {0 0 0 123}
+test namespace-old-1.23 {variables can be accessed within a namespace} {
+ test_ns_simple::_backdoor {
+ variable test_ns_x
+ variable test_ns_y
+ return "$test_ns_x $test_ns_y"
+ }
+} {0 123}
+test namespace-old-1.24 {setting global variables} {
+ test_ns_simple::_backdoor {variable test_ns_x; set test_ns_x "new val"}
+ namespace eval test_ns_simple {set test_ns_x}
+} {new val}
+test namespace-old-1.25 {qualified variables don't need a global declaration} {
+ namespace eval test_ns_another { variable test_ns_x 456 }
+ set cmd {set ::test_ns_another::test_ns_x}
+ list [catch {test_ns_simple::_backdoor "$cmd some-value"} msg] $msg \
+ [eval $cmd]
+} {0 some-value some-value}
+test namespace-old-1.26 {namespace qualifiers are okay after $'s} {
+ namespace eval test_ns_simple { set test_ns_x 12; set test_ns_y 34 }
+ set cmd {list $::test_ns_simple::test_ns_x $::test_ns_simple::test_ns_y}
+ list [test_ns_simple::_backdoor $cmd] [eval $cmd]
+} {{12 34} {12 34}}
+test namespace-old-1.27 {can create commands with null names} {
+ proc test_ns_simple:: {args} {return $args}
+} {}
+
+# -----------------------------------------------------------------------
+# TEST: using "info" in namespace contexts
+# -----------------------------------------------------------------------
+test namespace-old-2.1 {querying: info commands} {
+ lsort [test_ns_simple::_backdoor {info commands [namespace current]::*}]
+} {::test_ns_simple:: ::test_ns_simple::_backdoor ::test_ns_simple::test}
+test namespace-old-2.2 {querying: info procs} {
+ lsort [test_ns_simple::_backdoor {info procs}]
+} {{} _backdoor test}
+test namespace-old-2.3 {querying: info vars} {
+ lsort [info vars test_ns_simple::*]
+} {::test_ns_simple::test_ns_x ::test_ns_simple::test_ns_y}
+test namespace-old-2.4 {querying: info vars} {
+ lsort [test_ns_simple::_backdoor {info vars [namespace current]::*}]
+} {::test_ns_simple::test_ns_x ::test_ns_simple::test_ns_y}
+test namespace-old-2.5 {querying: info locals} {
+ lsort [test_ns_simple::_backdoor {info locals}]
+} {cmd}
+test namespace-old-2.6 {querying: info exists} {
+ test_ns_simple::_backdoor {info exists test_ns_x}
+} {0}
+test namespace-old-2.7 {querying: info exists} {
+ test_ns_simple::_backdoor {info exists cmd}
+} {1}
+test namespace-old-2.8 {querying: info args} {
+ info args test_ns_simple::_backdoor
+} {cmd}
+test namespace-old-2.9 {querying: info body} {
+ string trim [info body test_ns_simple::test]
+} {return "test: $test_ns_x"}
+
+# -----------------------------------------------------------------------
+# TEST: namespace qualifiers, namespace tail
+# -----------------------------------------------------------------------
+test namespace-old-3.1 {usage for "namespace qualifiers"} {
+ list [catch "namespace qualifiers" msg] $msg
+} {1 {wrong # args: should be "namespace qualifiers string"}}
+test namespace-old-3.2 {querying: namespace qualifiers} {
+ list [namespace qualifiers ""] \
+ [namespace qualifiers ::] \
+ [namespace qualifiers x] \
+ [namespace qualifiers ::x] \
+ [namespace qualifiers foo::x] \
+ [namespace qualifiers ::foo::bar::xyz]
+} {{} {} {} {} foo ::foo::bar}
+test namespace-old-3.3 {usage for "namespace tail"} {
+ list [catch "namespace tail" msg] $msg
+} {1 {wrong # args: should be "namespace tail string"}}
+test namespace-old-3.4 {querying: namespace tail} {
+ list [namespace tail ""] \
+ [namespace tail ::] \
+ [namespace tail x] \
+ [namespace tail ::x] \
+ [namespace tail foo::x] \
+ [namespace tail ::foo::bar::xyz]
+} {{} {} x x x xyz}
+
+# -----------------------------------------------------------------------
+# TEST: delete commands and namespaces
+# -----------------------------------------------------------------------
+test namespace-old-4.1 {define test namespaces} {
+ namespace eval test_ns_delete {
+ namespace eval ns1 {
+ variable var1 1
+ proc cmd1 {} {return "cmd1"}
+ }
+ namespace eval ns2 {
+ variable var2 2
+ proc cmd2 {} {return "cmd2"}
+ }
+ namespace eval another {}
+ lsort [namespace children]
+ }
+} {::test_ns_delete::another ::test_ns_delete::ns1 ::test_ns_delete::ns2}
+test namespace-old-4.2 {it's okay to invoke "namespace delete" with no args} {
+ list [catch {namespace delete} msg] $msg
+} {0 {}}
+test namespace-old-4.3 {command "namespace delete" doesn't support patterns} {
+ set cmd {
+ namespace eval test_ns_delete {namespace delete ns*}
+ }
+ list [catch $cmd msg] $msg
+} {1 {unknown namespace "ns*" in namespace delete command}}
+test namespace-old-4.4 {command "namespace delete" handles multiple args} {
+ set cmd {
+ namespace eval test_ns_delete {
+ namespace delete \
+ {*}[namespace children [namespace current] ns?]
+ }
+ }
+ list [catch $cmd msg] $msg [namespace children test_ns_delete]
+} {0 {} ::test_ns_delete::another}
+
+# -----------------------------------------------------------------------
+# TEST: namespace hierarchy
+# -----------------------------------------------------------------------
+test namespace-old-5.1 {define nested namespaces} {
+ set test_ns_var_global "var in ::"
+ proc test_ns_cmd_global {} {return "cmd in ::"}
+ namespace eval test_ns_hier1 {
+ set test_ns_var_hier1 "particular to hier1"
+ proc test_ns_cmd_hier1 {} {return "particular to hier1"}
+ set test_ns_level 1
+ proc test_ns_show {} {return "[namespace current]: 1"}
+ namespace eval test_ns_hier2 {
+ set test_ns_var_hier2 "particular to hier2"
+ proc test_ns_cmd_hier2 {} {return "particular to hier2"}
+ set test_ns_level 2
+ proc test_ns_show {} {return "[namespace current]: 2"}
+ namespace eval test_ns_hier3a {}
+ namespace eval test_ns_hier3b {}
+ }
+ namespace eval test_ns_hier2a {}
+ namespace eval test_ns_hier2b {}
+ }
+} {}
+test namespace-old-5.2 {namespaces can be nested} {
+ list [namespace eval test_ns_hier1 {namespace current}] \
+ [namespace eval test_ns_hier1 {
+ namespace eval test_ns_hier2 {namespace current}
+ }]
+} {::test_ns_hier1 ::test_ns_hier1::test_ns_hier2}
+test namespace-old-5.3 {namespace qualifiers work in namespace command} {
+ list [namespace eval ::test_ns_hier1 {namespace current}] \
+ [namespace eval test_ns_hier1::test_ns_hier2 {namespace current}] \
+ [namespace eval ::test_ns_hier1::test_ns_hier2 {namespace current}]
+} {::test_ns_hier1 ::test_ns_hier1::test_ns_hier2 ::test_ns_hier1::test_ns_hier2}
+test namespace-old-5.4 {nested namespaces can access global namespace} {
+ list [namespace eval test_ns_hier1 {set test_ns_var_global}] \
+ [namespace eval test_ns_hier1 {test_ns_cmd_global}] \
+ [namespace eval test_ns_hier1::test_ns_hier2 {set test_ns_var_global}] \
+ [namespace eval test_ns_hier1::test_ns_hier2 {test_ns_cmd_global}]
+} {{var in ::} {cmd in ::} {var in ::} {cmd in ::}}
+test namespace-old-5.5 {variables in different namespaces don't conflict} {
+ list [set test_ns_hier1::test_ns_level] \
+ [set test_ns_hier1::test_ns_hier2::test_ns_level]
+} {1 2}
+test namespace-old-5.6 {commands in different namespaces don't conflict} {
+ list [test_ns_hier1::test_ns_show] \
+ [test_ns_hier1::test_ns_hier2::test_ns_show]
+} {{::test_ns_hier1: 1} {::test_ns_hier1::test_ns_hier2: 2}}
+test namespace-old-5.7 {nested namespaces don't see variables in parent} {
+ set cmd {
+ namespace eval test_ns_hier1::test_ns_hier2 {set test_ns_var_hier1}
+ }
+ list [catch $cmd msg] $msg
+} {1 {can't read "test_ns_var_hier1": no such variable}}
+test namespace-old-5.8 {nested namespaces don't see commands in parent} {
+ set cmd {
+ namespace eval test_ns_hier1::test_ns_hier2 {test_ns_cmd_hier1}
+ }
+ list [catch $cmd msg] $msg
+} {1 {invalid command name "test_ns_cmd_hier1"}}
+test namespace-old-5.9 {usage for "namespace children"} {
+ list [catch {namespace children test_ns_hier1 y z} msg] $msg
+} {1 {wrong # args: should be "namespace children ?name? ?pattern?"}}
+test namespace-old-5.10 {command "namespace children" must get valid namespace} -body {
+ namespace children xyzzy
+} -returnCodes error -result {namespace "xyzzy" not found in "::"}
+test namespace-old-5.11 {querying namespace children} {
+ lsort [namespace children :: test_ns_hier*]
+} {::test_ns_hier1}
+test namespace-old-5.12 {querying namespace children} {
+ lsort [namespace children test_ns_hier1]
+} {::test_ns_hier1::test_ns_hier2 ::test_ns_hier1::test_ns_hier2a ::test_ns_hier1::test_ns_hier2b}
+test namespace-old-5.13 {querying namespace children} {
+ lsort [namespace eval test_ns_hier1 {namespace children}]
+} {::test_ns_hier1::test_ns_hier2 ::test_ns_hier1::test_ns_hier2a ::test_ns_hier1::test_ns_hier2b}
+test namespace-old-5.14 {querying namespace children} {
+ lsort [namespace children test_ns_hier1::test_ns_hier2]
+} {::test_ns_hier1::test_ns_hier2::test_ns_hier3a ::test_ns_hier1::test_ns_hier2::test_ns_hier3b}
+test namespace-old-5.15 {querying namespace children} {
+ lsort [namespace eval test_ns_hier1::test_ns_hier2 {namespace children}]
+} {::test_ns_hier1::test_ns_hier2::test_ns_hier3a ::test_ns_hier1::test_ns_hier2::test_ns_hier3b}
+test namespace-old-5.16 {querying namespace children with patterns} {
+ lsort [namespace children test_ns_hier1::test_ns_hier2 test_ns_*]
+} {::test_ns_hier1::test_ns_hier2::test_ns_hier3a ::test_ns_hier1::test_ns_hier2::test_ns_hier3b}
+test namespace-old-5.17 {querying namespace children with patterns} {
+ lsort [namespace children test_ns_hier1::test_ns_hier2 *b]
+} {::test_ns_hier1::test_ns_hier2::test_ns_hier3b}
+test namespace-old-5.18 {usage for "namespace parent"} {
+ list [catch {namespace parent x y} msg] $msg
+} {1 {wrong # args: should be "namespace parent ?name?"}}
+test namespace-old-5.19 {command "namespace parent" must get valid namespace} -body {
+ namespace parent xyzzy
+} -returnCodes error -result {namespace "xyzzy" not found in "::"}
+test namespace-old-5.20 {querying namespace parent} {
+ list [namespace eval :: {namespace parent}] \
+ [namespace eval test_ns_hier1 {namespace parent}] \
+ [namespace eval test_ns_hier1::test_ns_hier2 {namespace parent}] \
+ [namespace eval test_ns_hier1::test_ns_hier2::test_ns_hier3a {namespace parent}] \
+} {{} :: ::test_ns_hier1 ::test_ns_hier1::test_ns_hier2}
+test namespace-old-5.21 {querying namespace parent for explicit namespace} {
+ list [namespace parent ::] \
+ [namespace parent test_ns_hier1] \
+ [namespace parent test_ns_hier1::test_ns_hier2] \
+ [namespace parent test_ns_hier1::test_ns_hier2::test_ns_hier3a]
+} {{} :: ::test_ns_hier1 ::test_ns_hier1::test_ns_hier2}
+
+# -----------------------------------------------------------------------
+# TEST: name resolution and caching
+# -----------------------------------------------------------------------
+test namespace-old-6.1 {relative ns names only looked up in current ns} {
+ namespace eval test_ns_cache1 {}
+ namespace eval test_ns_cache2 {}
+ namespace eval test_ns_cache2::test_ns_cache3 {}
+ set trigger {
+ namespace eval test_ns_cache2 {namespace current}
+ }
+ set trigger2 {
+ namespace eval test_ns_cache2::test_ns_cache3 {namespace current}
+ }
+ list [namespace eval test_ns_cache1 $trigger] \
+ [namespace eval test_ns_cache1 $trigger2]
+} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
+test namespace-old-6.2 {relative ns names only looked up in current ns} {
+ namespace eval test_ns_cache1::test_ns_cache2 {}
+ list [namespace eval test_ns_cache1 $trigger] \
+ [namespace eval test_ns_cache1 $trigger2]
+} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
+test namespace-old-6.3 {relative ns names only looked up in current ns} {
+ namespace eval test_ns_cache1::test_ns_cache2::test_ns_cache3 {}
+ list [namespace eval test_ns_cache1 $trigger] \
+ [namespace eval test_ns_cache1 $trigger2]
+} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
+test namespace-old-6.4 {relative ns names only looked up in current ns} {
+ namespace delete test_ns_cache1::test_ns_cache2
+ list [namespace eval test_ns_cache1 $trigger] \
+ [namespace eval test_ns_cache1 $trigger2]
+} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
+test namespace-old-6.5 {define test commands} {
+ proc test_ns_cache_cmd {} {
+ return "global version"
+ }
+ namespace eval test_ns_cache1 {
+ proc trigger {} {
+ test_ns_cache_cmd
+ }
+ }
+ test_ns_cache1::trigger
+} {global version}
+test namespace-old-6.6 {one-level check for command shadowing} {
+ proc test_ns_cache1::test_ns_cache_cmd {} {
+ return "cache1 version"
+ }
+ test_ns_cache1::trigger
+} {cache1 version}
+test namespace-old-6.7 {renaming commands changes command epoch} {
+ namespace eval test_ns_cache1 {
+ rename test_ns_cache_cmd test_ns_new
+ }
+ test_ns_cache1::trigger
+} {global version}
+test namespace-old-6.8 {renaming back handles shadowing} {
+ namespace eval test_ns_cache1 {
+ rename test_ns_new test_ns_cache_cmd
+ }
+ test_ns_cache1::trigger
+} {cache1 version}
+test namespace-old-6.9 {deleting commands changes command epoch} {
+ namespace eval test_ns_cache1 {
+ rename test_ns_cache_cmd ""
+ }
+ test_ns_cache1::trigger
+} {global version}
+test namespace-old-6.10 {define test namespaces} {
+ namespace eval test_ns_cache2 {
+ proc test_ns_cache_cmd {} {
+ return "global cache2 version"
+ }
+ }
+ namespace eval test_ns_cache1 {
+ proc trigger {} {
+ test_ns_cache2::test_ns_cache_cmd
+ }
+ }
+ namespace eval test_ns_cache1::test_ns_cache2 {
+ proc trigger {} {
+ test_ns_cache_cmd
+ }
+ }
+ list [test_ns_cache1::trigger] [test_ns_cache1::test_ns_cache2::trigger]
+} {{global cache2 version} {global version}}
+test namespace-old-6.11 {commands affect all parent namespaces} {
+ proc test_ns_cache1::test_ns_cache2::test_ns_cache_cmd {} {
+ return "cache2 version"
+ }
+ list [test_ns_cache1::trigger] [test_ns_cache1::test_ns_cache2::trigger]
+} {{cache2 version} {cache2 version}}
+test namespace-old-6.12 {define test variables} {
+ variable test_ns_cache_var "global version"
+ set trigger {set test_ns_cache_var}
+ namespace eval test_ns_cache1 $trigger
+} {global version}
+test namespace-old-6.13 {one-level check for variable shadowing} {
+ namespace eval test_ns_cache1 {
+ variable test_ns_cache_var "cache1 version"
+ }
+ namespace eval test_ns_cache1 $trigger
+} {cache1 version}
+test namespace-old-6.14 {deleting variables changes variable epoch} {
+ namespace eval test_ns_cache1 {
+ unset test_ns_cache_var
+ }
+ namespace eval test_ns_cache1 $trigger
+} {global version}
+test namespace-old-6.15 {define test namespaces} {
+ namespace eval test_ns_cache2 {
+ variable test_ns_cache_var "global cache2 version"
+ }
+ set trigger2 {set test_ns_cache2::test_ns_cache_var}
+ list [namespace eval test_ns_cache1 $trigger2] \
+ [namespace eval test_ns_cache1::test_ns_cache2 $trigger]
+} {{global cache2 version} {global version}}
+test namespace-old-6.16 {public variables affect all parent namespaces} {
+ variable test_ns_cache1::test_ns_cache2::test_ns_cache_var "cache2 version"
+ list [namespace eval test_ns_cache1 $trigger2] \
+ [namespace eval test_ns_cache1::test_ns_cache2 $trigger]
+} {{cache2 version} {cache2 version}}
+test namespace-old-6.17 {usage for "namespace which"} {
+ list [catch "namespace which -baz x" msg] $msg
+} {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
+test namespace-old-6.18 {usage for "namespace which"} {
+ # Presume no imported command called -command ;^)
+ namespace which -command
+} {}
+test namespace-old-6.19 {querying: namespace which -command} {
+ proc test_ns_cache1::test_ns_cache_cmd {} {
+ return "cache1 version"
+ }
+ list [namespace eval :: {namespace which test_ns_cache_cmd}] \
+ [namespace eval test_ns_cache1 {namespace which test_ns_cache_cmd}] \
+ [namespace eval :: {namespace which -command test_ns_cache_cmd}] \
+ [namespace eval test_ns_cache1 {namespace which -command test_ns_cache_cmd}]
+} {::test_ns_cache_cmd ::test_ns_cache1::test_ns_cache_cmd ::test_ns_cache_cmd ::test_ns_cache1::test_ns_cache_cmd}
+test namespace-old-6.20 {command "namespace which" may not find commands} {
+ namespace eval test_ns_cache1 {namespace which -command xyzzy}
+} {}
+test namespace-old-6.21 {querying: namespace which -variable} {
+ namespace eval test_ns_cache1::test_ns_cache2 {
+ namespace which -variable test_ns_cache_var
+ }
+} {::test_ns_cache1::test_ns_cache2::test_ns_cache_var}
+test namespace-old-6.22 {command "namespace which" may not find variables} {
+ namespace eval test_ns_cache1 {namespace which -variable xyzzy}
+} {}
+
+# -----------------------------------------------------------------------
+# TEST: uplevel/upvar across namespace boundaries
+# -----------------------------------------------------------------------
+test namespace-old-7.1 {define test namespace} {
+ namespace eval test_ns_uplevel {
+ variable x 0
+ variable y 1
+ proc show_vars {num} {
+ return [uplevel $num {info vars}]
+ }
+ proc test_uplevel {num} {
+ set a 0
+ set b 1
+ namespace eval ::test_ns_uplevel " return \[show_vars $num\] "
+ }
+ }
+} {}
+test namespace-old-7.2 {uplevel can access namespace call frame} {
+ list [expr {"x" in [test_ns_uplevel::test_uplevel 1]}] \
+ [expr {"y" in [test_ns_uplevel::test_uplevel 1]}]
+} {1 1}
+test namespace-old-7.3 {uplevel can go beyond namespace call frame} {
+ lsort [test_ns_uplevel::test_uplevel 2]
+} {a b num}
+test namespace-old-7.4 {uplevel can go up to global context} {
+ expr {[test_ns_uplevel::test_uplevel 3] == [info globals]}
+} {1}
+test namespace-old-7.5 {absolute call frame references work too} {
+ list [expr {"x" in [test_ns_uplevel::test_uplevel #2]}] \
+ [expr {"y" in [test_ns_uplevel::test_uplevel #2]}]
+} {1 1}
+test namespace-old-7.6 {absolute call frame references work too} {
+ lsort [test_ns_uplevel::test_uplevel #1]
+} {a b num}
+test namespace-old-7.7 {absolute call frame references work too} {
+ expr {[test_ns_uplevel::test_uplevel #0] == [info globals]}
+} {1}
+test namespace-old-7.8 {namespaces are included in the call stack} {
+ namespace eval test_ns_upvar {
+ variable scope "test_ns_upvar"
+ proc show_val {var num} {
+ upvar $num $var x
+ return $x
+ }
+ proc test_upvar {num} {
+ set scope "test_ns_upvar::test_upvar"
+ namespace eval ::test_ns_upvar " return \[show_val scope $num\] "
+ }
+ }
+} {}
+test namespace-old-7.9 {upvar can access namespace call frame} {
+ test_ns_upvar::test_upvar 1
+} {test_ns_upvar}
+test namespace-old-7.10 {upvar can go beyond namespace call frame} {
+ test_ns_upvar::test_upvar 2
+} {test_ns_upvar::test_upvar}
+test namespace-old-7.11 {absolute call frame references work too} {
+ test_ns_upvar::test_upvar #2
+} {test_ns_upvar}
+test namespace-old-7.12 {absolute call frame references work too} {
+ test_ns_upvar::test_upvar #1
+} {test_ns_upvar::test_upvar}
+
+# -----------------------------------------------------------------------
+# TEST: variable traces across namespace boundaries
+# -----------------------------------------------------------------------
+test namespace-old-8.1 {traces work across namespace boundaries} {
+ namespace eval test_ns_trace {
+ namespace eval foo {
+ variable x ""
+ }
+ variable status ""
+ proc monitor {name1 name2 op} {
+ variable status
+ lappend status "$op: $name1"
+ }
+ trace variable foo::x rwu [namespace code monitor]
+ }
+ set test_ns_trace::foo::x "yes!"
+ set test_ns_trace::foo::x
+ unset test_ns_trace::foo::x
+ namespace eval test_ns_trace { set status }
+} {{w: test_ns_trace::foo::x} {r: test_ns_trace::foo::x} {u: test_ns_trace::foo::x}}
+
+# -----------------------------------------------------------------------
+# TEST: imported commands
+# -----------------------------------------------------------------------
+test namespace-old-9.1 {empty "namespace export" list} {
+ list [catch "namespace export" msg] $msg
+} {0 {}}
+test namespace-old-9.2 {usage for "namespace export" command} {
+ list [catch "namespace export test_ns_trace::zzz" msg] $msg
+} {1 {invalid export pattern "test_ns_trace::zzz": pattern can't specify a namespace}}
+test namespace-old-9.3 {define test namespaces for import} {
+ namespace eval test_ns_export {
+ namespace export cmd1 cmd2 cmd3
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ proc cmd3 {args} {return "cmd3: $args"}
+ proc cmd4 {args} {return "cmd4: $args"}
+ proc cmd5 {args} {return "cmd5: $args"}
+ proc cmd6 {args} {return "cmd6: $args"}
+ }
+ lsort [info commands test_ns_export::*]
+} {::test_ns_export::cmd1 ::test_ns_export::cmd2 ::test_ns_export::cmd3 ::test_ns_export::cmd4 ::test_ns_export::cmd5 ::test_ns_export::cmd6}
+test namespace-old-9.4 {check export status} {
+ set x ""
+ namespace eval test_ns_import {
+ namespace export cmd1 cmd2
+ namespace import ::test_ns_export::*
+ }
+ foreach cmd [lsort [info commands test_ns_import::*]] {
+ lappend x $cmd
+ }
+ set x
+} {::test_ns_import::cmd1 ::test_ns_import::cmd2 ::test_ns_import::cmd3}
+test namespace-old-9.5 {empty import list in "namespace import" command} {
+ namespace eval test_ns_import_empty {
+ namespace import ::test_ns_export::*
+ try {
+ lsort [namespace import]
+ } finally {
+ namespace delete [namespace current]
+ }
+ }
+} {cmd1 cmd2 cmd3}
+# there is no namespace-old-9.6
+test namespace-old-9.7 {empty forget list for "namespace forget" command} {
+ namespace forget
+} {}
+catch {rename cmd1 {}}
+catch {rename cmd2 {}}
+catch {rename ncmd {}}
+catch {rename ncmd1 {}}
+catch {rename ncmd2 {}}
+test namespace-old-9.8 {only exported commands are imported} {
+ namespace import test_ns_import::cmd*
+ set x [lsort [info commands cmd*]]
+} {cmd1 cmd2}
+test namespace-old-9.9 {imported commands work just the same as original} {
+ list [cmd1 test 1 2 3] [test_ns_import::cmd1 test 4 5 6]
+} {{cmd1: test 1 2 3} {cmd1: test 4 5 6}}
+test namespace-old-9.10 {commands can be imported from many namespaces} {
+ namespace eval test_ns_import2 {
+ namespace export ncmd ncmd1 ncmd2
+ proc ncmd {args} {return "ncmd: $args"}
+ proc ncmd1 {args} {return "ncmd1: $args"}
+ proc ncmd2 {args} {return "ncmd2: $args"}
+ proc ncmd3 {args} {return "ncmd3: $args"}
+ }
+ namespace import test_ns_import2::*
+ lsort [concat [info commands cmd*] [info commands ncmd*]]
+} {cmd1 cmd2 ncmd ncmd1 ncmd2}
+test namespace-old-9.11 {imported commands can be removed by deleting them} {
+ rename cmd1 ""
+ lsort [concat [info commands cmd*] [info commands ncmd*]]
+} {cmd2 ncmd ncmd1 ncmd2}
+test namespace-old-9.12 {command "namespace forget" checks for valid namespaces} {
+ list [catch {namespace forget xyzzy::*} msg] $msg
+} {1 {unknown namespace in namespace forget pattern "xyzzy::*"}}
+test namespace-old-9.13 {command "namespace forget" ignores patterns that don't match} {
+ list [catch {namespace forget test_ns_import::xy*zzy} msg] $msg \
+ [lsort [info commands cmd?]]
+} {0 {} cmd2}
+test namespace-old-9.14 {imported commands can be removed} {
+ namespace forget test_ns_import::cmd?
+ list [lsort [info commands cmd?]] \
+ [catch {cmd1 another test} msg] $msg
+} {{} 1 {invalid command name "cmd1"}}
+test namespace-old-9.15 {existing commands can't be overwritten} {
+ proc cmd1 {x y} {
+ return [expr $x+$y]
+ }
+ list [catch {namespace import test_ns_import::cmd?} msg] $msg \
+ [cmd1 3 5]
+} {1 {can't import command "cmd1": already exists} 8}
+test namespace-old-9.16 {use "-force" option to override existing commands} {
+ list [cmd1 3 5] \
+ [namespace import -force test_ns_import::cmd?] \
+ [cmd1 3 5]
+} {8 {} {cmd1: 3 5}}
+test namespace-old-9.17 {commands can be imported into many namespaces} {
+ namespace eval test_ns_import_use {
+ namespace import ::test_ns_import::* ::test_ns_import2::ncmd?
+ lsort [concat [info commands ::test_ns_import_use::cmd*] \
+ [info commands ::test_ns_import_use::ncmd*]]
+ }
+} {::test_ns_import_use::cmd1 ::test_ns_import_use::cmd2 ::test_ns_import_use::ncmd1 ::test_ns_import_use::ncmd2}
+test namespace-old-9.18 {when command is deleted, imported commands go away} {
+ namespace eval test_ns_import { rename cmd1 "" }
+ list [info commands cmd1] \
+ [namespace eval test_ns_import_use {info commands cmd1}]
+} {{} {}}
+test namespace-old-9.19 {when namesp is deleted, all imported commands go away} {
+ namespace delete test_ns_import test_ns_import2
+ list [info commands cmd*] \
+ [info commands ncmd*] \
+ [namespace eval test_ns_import_use {info commands cmd*}] \
+ [namespace eval test_ns_import_use {info commands ncmd*}] \
+} {{} {} {} {}}
+
+# -----------------------------------------------------------------------
+# TEST: scoped values
+# -----------------------------------------------------------------------
+test namespace-old-10.1 {define namespace for scope test} {
+ namespace eval test_ns_inscope {
+ variable x "x-value"
+ proc show {args} {
+ return "show: $args"
+ }
+ proc do {args} {
+ return [eval $args]
+ }
+ list [set x] [show test]
+ }
+} {x-value {show: test}}
+test namespace-old-10.2 {command "namespace code" requires one argument} {
+ list [catch {namespace code} msg] $msg
+} {1 {wrong # args: should be "namespace code arg"}}
+test namespace-old-10.3 {command "namespace code" requires one argument} {
+ list [catch {namespace code first "second arg" third} msg] $msg
+} {1 {wrong # args: should be "namespace code arg"}}
+test namespace-old-10.4 {command "namespace code" gets current namesp context} {
+ namespace eval test_ns_inscope {
+ namespace code {"1 2 3" "4 5" 6}
+ }
+} {::namespace inscope ::test_ns_inscope {"1 2 3" "4 5" 6}}
+test namespace-old-10.5 {with one arg, first "scope" sticks} {
+ set sval [namespace eval test_ns_inscope {namespace code {one two}}]
+ namespace code $sval
+} {::namespace inscope ::test_ns_inscope {one two}}
+test namespace-old-10.6 {with many args, each "scope" adds new args} {
+ set sval [namespace eval test_ns_inscope {namespace code {one two}}]
+ namespace code "$sval three"
+} {::namespace inscope ::test_ns_inscope {one two} three}
+test namespace-old-10.7 {scoped commands work with eval} {
+ set cref [namespace eval test_ns_inscope {namespace code show}]
+ list [eval $cref "a" "b c" "d e f"]
+} {{show: a b c d e f}}
+test namespace-old-10.8 {scoped commands execute in namespace context} {
+ set cref [namespace eval test_ns_inscope {
+ namespace code {set x "some new value"}
+ }]
+ list [set test_ns_inscope::x] [eval $cref] [set test_ns_inscope::x]
+} {x-value {some new value} {some new value}}
+
+foreach cmd [info commands test_ns_*] {
+ rename $cmd ""
+}
+catch {rename cmd {}}
+catch {rename cmd1 {}}
+catch {rename cmd2 {}}
+catch {rename ncmd {}}
+catch {rename ncmd1 {}}
+catch {rename ncmd2 {}}
+catch {unset cref}
+catch {unset trigger}
+catch {unset trigger2}
+catch {unset sval}
+catch {unset msg}
+catch {unset x}
+catch {unset test_ns_var_global}
+catch {unset cmd}
+eval namespace delete [namespace children :: test_ns_*]
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/namespace.test b/pkgs/msgcat/tests/namespace.test
new file mode 100644
index 0000000..f07d8cf
--- /dev/null
+++ b/pkgs/msgcat/tests/namespace.test
@@ -0,0 +1,2944 @@
+# Functionality covered: this file contains a collection of tests for the
+# procedures in tclNamesp.c and tclEnsemble.c that implement Tcl's basic
+# support for namespaces. Other namespace-related tests appear in
+# variable.test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+testConstraint memory [llength [info commands memory]]
+
+#
+# REMARK: the tests for 'namespace upvar' are not done here. They are to be
+# found in the file 'upvar.test'.
+#
+
+# Clear out any namespaces called test_ns_*
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+
+proc fq {ns} {
+ if {[string match ::* $ns]} {return $ns}
+ set current [uplevel 1 {namespace current}]
+ return [string trimright $current :]::[string trimleft $ns :]
+}
+
+test namespace-1.1 {TclInitNamespaces, GetNamespaceFromObj, NamespaceChildrenCmd} {
+ namespace children :: test_ns_*
+} {}
+
+catch {unset l}
+test namespace-2.1 {Tcl_GetCurrentNamespace} {
+ list [namespace current] [namespace eval {} {namespace current}] \
+ [namespace eval {} {namespace current}]
+} {:: :: ::}
+test namespace-2.2 {Tcl_GetCurrentNamespace} {
+ set l {}
+ lappend l [namespace current]
+ namespace eval test_ns_1 {
+ lappend l [namespace current]
+ namespace eval foo {
+ lappend l [namespace current]
+ }
+ }
+ lappend l [namespace current]
+} {:: ::test_ns_1 ::test_ns_1::foo ::}
+
+test namespace-3.1 {Tcl_GetGlobalNamespace} {
+ namespace eval test_ns_1 {namespace eval foo {namespace eval bar {} } }
+ # namespace children uses Tcl_GetGlobalNamespace
+ namespace eval test_ns_1 {namespace children foo b*}
+} {::test_ns_1::foo::bar}
+
+test namespace-4.1 {Tcl_PushCallFrame with isProcCallFrame=1} {
+ namespace eval test_ns_1 {
+ variable v 123
+ proc p {} {
+ variable v
+ return $v
+ }
+ }
+ test_ns_1::p ;# does Tcl_PushCallFrame to push p's namespace
+} {123}
+test namespace-4.2 {Tcl_PushCallFrame with isProcCallFrame=0} {
+ namespace eval test_ns_1::baz {} ;# does Tcl_PushCallFrame to create baz
+ proc test_ns_1::baz::p {} {
+ variable v
+ set v 789
+ set v}
+ test_ns_1::baz::p
+} {789}
+
+test namespace-5.1 {Tcl_PopCallFrame, no vars} {
+ namespace eval test_ns_1::blodge {} ;# pushes then pops frame
+} {}
+test namespace-5.2 {Tcl_PopCallFrame, local vars must be deleted} {
+ proc test_ns_1::r {} {
+ set a 123
+ }
+ test_ns_1::r ;# pushes then pop's r's frame
+} {123}
+
+test namespace-6.1 {Tcl_CreateNamespace} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [lsort [namespace children :: test_ns_*]] \
+ [namespace eval test_ns_1 {namespace current}] \
+ [namespace eval test_ns_2 {namespace current}] \
+ [namespace eval ::test_ns_3 {namespace current}] \
+ [namespace eval ::test_ns_4 \
+ {namespace eval foo {namespace current}}] \
+ [namespace eval ::test_ns_5 \
+ {namespace eval ::test_ns_6 {namespace current}}] \
+ [lsort [namespace children :: test_ns_*]]
+} {{} ::test_ns_1 ::test_ns_2 ::test_ns_3 ::test_ns_4::foo ::test_ns_6 {::test_ns_1 ::test_ns_2 ::test_ns_3 ::test_ns_4 ::test_ns_5 ::test_ns_6}}
+test namespace-6.2 {Tcl_CreateNamespace, odd number of :'s in name is okay} {
+ list [namespace eval :::test_ns_1::::foo {namespace current}] \
+ [namespace eval test_ns_2:::::foo {namespace current}]
+} {::test_ns_1::foo ::test_ns_2::foo}
+test namespace-6.3 {Tcl_CreateNamespace, trailing ::s in ns name are ignored} {
+ list [catch {namespace eval test_ns_7::: {namespace current}} msg] $msg
+} {0 ::test_ns_7}
+test namespace-6.4 {Tcl_CreateNamespace, trailing ::s in ns name are ignored} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1:: {
+ namespace eval test_ns_2:: {}
+ namespace eval test_ns_3:: {}
+ }
+ lsort [namespace children ::test_ns_1]
+} [lsort {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_3}]
+test namespace-6.5 {Tcl_CreateNamespace, relative ns names now only looked up in current ns} {
+ set trigger {
+ namespace eval test_ns_2 {namespace current}
+ }
+ set l {}
+ lappend l [namespace eval test_ns_1 $trigger]
+ namespace eval test_ns_1::test_ns_2 {}
+ lappend l [namespace eval test_ns_1 $trigger]
+} {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_2}
+
+test namespace-7.1 {Tcl_DeleteNamespace, active call frames in ns} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1 {
+ proc p {} {
+ namespace delete [namespace current]
+ return [namespace current]
+ }
+ }
+ list [test_ns_1::p] [catch {test_ns_1::p} msg] $msg
+} {::test_ns_1 1 {invalid command name "test_ns_1::p"}}
+test namespace-7.2 {Tcl_DeleteNamespace, no active call frames in ns} {
+ namespace eval test_ns_2 {
+ proc p {} {
+ return [namespace current]
+ }
+ }
+ list [test_ns_2::p] [namespace delete test_ns_2]
+} {::test_ns_2 {}}
+test namespace-7.3 {recursive Tcl_DeleteNamespace, active call frames in ns} {
+ # [Bug 1355942]
+ namespace eval test_ns_2 {
+ set x 1
+ trace add variable x unset "namespace delete [namespace current];#"
+ namespace delete [namespace current]
+ }
+} {}
+test namespace-7.4 {recursive Tcl_DeleteNamespace, active call frames in ns} {
+ # [Bug 1355942]
+ namespace eval test_ns_2 {
+ proc x {} {}
+ trace add command x delete "namespace delete [namespace current];#"
+ namespace delete [namespace current]
+ }
+} {}
+test namespace-7.5 {recursive Tcl_DeleteNamespace, no active call frames in ns} {
+ # [Bug 1355942]
+ namespace eval test_ns_2 {
+ set x 1
+ trace add variable x unset "namespace delete [namespace current];#"
+ }
+ namespace delete test_ns_2
+} {}
+test namespace-7.6 {recursive Tcl_DeleteNamespace, no active call frames in ns} {
+ # [Bug 1355942]
+ namespace eval test_ns_2 {
+ proc x {} {}
+ trace add command x delete "namespace delete [namespace current];#"
+ }
+ namespace delete test_ns_2
+} {}
+test namespace-7.7 {Bug 1655305} -setup {
+ interp create slave
+ # Can't invoke through the ensemble, since deleting the global namespace
+ # (indirectly, via deleting ::tcl) deletes the ensemble.
+ slave eval {rename ::tcl::info::commands ::infocommands}
+ slave hide infocommands
+ slave eval {
+ proc foo {} {
+ namespace delete ::
+ }
+ }
+} -body {
+ slave eval foo
+ slave invokehidden infocommands
+} -cleanup {
+ interp delete slave
+} -result {}
+
+
+test namespace-8.1 {TclTeardownNamespace, delete global namespace} {
+ catch {interp delete test_interp}
+ interp create test_interp
+ interp eval test_interp {
+ namespace eval test_ns_1 {
+ namespace export p
+ proc p {} {
+ return [namespace current]
+ }
+ }
+ namespace eval test_ns_2 {
+ namespace import ::test_ns_1::p
+ variable v 27
+ proc q {} {
+ variable v
+ return "[p] $v"
+ }
+ }
+ set x [test_ns_2::q]
+ catch {set xxxx}
+ }
+ list [interp eval test_interp {test_ns_2::q}] \
+ [interp eval test_interp {namespace delete ::}] \
+ [catch {interp eval test_interp {set a 123}} msg] $msg \
+ [interp delete test_interp]
+} {{::test_ns_1 27} {} 1 {invalid command name "set"} {}}
+test namespace-8.2 {TclTeardownNamespace, remove deleted ns from parent} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1::test_ns_2::test_ns_3a {proc p {} {}}
+ namespace eval test_ns_1::test_ns_2::test_ns_3b {proc q {} {}}
+ list [namespace children test_ns_1] \
+ [namespace delete test_ns_1::test_ns_2] \
+ [namespace children test_ns_1]
+} {::test_ns_1::test_ns_2 {} {}}
+test namespace-8.3 {TclTeardownNamespace, delete child namespaces} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1::test_ns_2::test_ns_3a {proc p {} {}}
+ namespace eval test_ns_1::test_ns_2::test_ns_3b {proc q {} {}}
+ list [namespace children test_ns_1] \
+ [namespace delete test_ns_1::test_ns_2] \
+ [namespace children test_ns_1] \
+ [catch {namespace children test_ns_1::test_ns_2} msg] $msg \
+ [info commands test_ns_1::test_ns_2::test_ns_3a::*]
+} {::test_ns_1::test_ns_2 {} {} 1 {namespace "test_ns_1::test_ns_2" not found in "::"} {}}
+test namespace-8.4 {TclTeardownNamespace, cmds imported from deleted ns go away} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_export {
+ namespace export cmd1 cmd2
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ }
+ namespace eval test_ns_import {
+ namespace import ::test_ns_export::*
+ proc p {} {return foo}
+ }
+ list [lsort [info commands test_ns_import::*]] \
+ [namespace delete test_ns_export] \
+ [info commands test_ns_import::*]
+} [list [lsort {::test_ns_import::p ::test_ns_import::cmd1 ::test_ns_import::cmd2}] {} ::test_ns_import::p]
+test namespace-8.5 {TclTeardownNamespace: preserve errorInfo; errorCode values} {
+ interp create slave
+ slave eval {trace add execution error leave {namespace delete :: ;#}}
+ catch {slave eval error foo bar baz}
+ interp delete slave
+ set ::errorInfo
+} {bar
+ invoked from within
+"slave eval error foo bar baz"}
+test namespace-8.6 {TclTeardownNamespace: preserve errorInfo; errorCode values} {
+ interp create slave
+ slave eval {trace add variable errorCode write {namespace delete :: ;#}}
+ catch {slave eval error foo bar baz}
+ interp delete slave
+ set ::errorInfo
+} {bar
+ invoked from within
+"slave eval error foo bar baz"}
+test namespace-8.7 {TclTeardownNamespace: preserve errorInfo; errorCode values} {
+ interp create slave
+ slave eval {trace add execution error leave {namespace delete :: ;#}}
+ catch {slave eval error foo bar baz}
+ interp delete slave
+ set ::errorCode
+} baz
+
+test namespace-9.1 {Tcl_Import, empty import pattern} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace eval test_ns_import {namespace import {}}} msg] $msg
+} {1 {empty import pattern}}
+test namespace-9.2 {Tcl_Import, unknown namespace in import pattern} {
+ list [catch {namespace eval test_ns_import {namespace import fred::x}} msg] $msg
+} {1 {unknown namespace in import pattern "fred::x"}}
+test namespace-9.3 {Tcl_Import, import ns == export ns} {
+ list [catch {namespace eval test_ns_import {namespace import ::test_ns_import::puts}} msg] $msg
+} {1 {import pattern "::test_ns_import::puts" tries to import from namespace "test_ns_import" into itself}}
+test namespace-9.4 {Tcl_Import, simple import} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_export {
+ namespace export cmd1
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ }
+ namespace eval test_ns_import {
+ namespace import ::test_ns_export::*
+ proc p {} {return [cmd1 123]}
+ }
+ test_ns_import::p
+} {cmd1: 123}
+test namespace-9.5 {Tcl_Import, can't redefine cmd unless allowOverwrite!=0} {
+ list [catch {namespace eval test_ns_import {namespace import ::test_ns_export::*}} msg] $msg
+} {0 {}}
+test namespace-9.6 {Tcl_Import, cmd redefinition ok if allowOverwrite!=0} {
+ namespace eval test_ns_import {
+ namespace import -force ::test_ns_export::*
+ cmd1 555
+ }
+} {cmd1: 555}
+test namespace-9.7 {Tcl_Import, links are preserved if cmd is redefined} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_export {
+ namespace export cmd1
+ proc cmd1 {args} {return "cmd1: $args"}
+ }
+ namespace eval test_ns_import {
+ namespace import -force ::test_ns_export::*
+ }
+ list [test_ns_import::cmd1 a b c] \
+ [test_ns_export::cmd1 d e f] \
+ [proc test_ns_export::cmd1 {args} {return "new1: $args"}] \
+ [namespace origin test_ns_import::cmd1] \
+ [namespace origin test_ns_export::cmd1] \
+ [test_ns_import::cmd1 g h i] \
+ [test_ns_export::cmd1 j k l]
+} {{cmd1: a b c} {cmd1: d e f} {} ::test_ns_export::cmd1 ::test_ns_export::cmd1 {new1: g h i} {new1: j k l}}
+
+test namespace-9.8 {Tcl_Import: Bug 1017299} -setup {
+ namespace eval one {
+ namespace export cmd
+ proc cmd {} {}
+ }
+ namespace eval two {
+ namespace export cmd
+ proc other args {}
+ }
+ namespace eval two \
+ [list namespace import [namespace current]::one::cmd]
+ namespace eval three \
+ [list namespace import [namespace current]::two::cmd]
+ namespace eval three {
+ rename cmd other
+ namespace export other
+ }
+} -body {
+ namespace eval two [list namespace import -force \
+ [namespace current]::three::other]
+ namespace origin two::other
+} -cleanup {
+ namespace delete one two three
+} -match glob -result *::one::cmd
+
+test namespace-9.9 {Tcl_Import: Bug 1017299} -setup {
+ namespace eval one {
+ namespace export cmd
+ proc cmd {} {}
+ }
+ namespace eval two namespace export cmd
+ namespace eval two \
+ [list namespace import [namespace current]::one::cmd]
+ namespace eval three namespace export cmd
+ namespace eval three \
+ [list namespace import [namespace current]::two::cmd]
+} -body {
+ namespace eval two [list namespace import -force \
+ [namespace current]::three::cmd]
+ namespace origin two::cmd
+} -cleanup {
+ namespace delete one two three
+} -returnCodes error -match glob -result {import pattern * would create a loop*}
+
+test namespace-10.1 {Tcl_ForgetImport, check for valid namespaces} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace forget xyzzy::*} msg] $msg
+} {1 {unknown namespace in namespace forget pattern "xyzzy::*"}}
+test namespace-10.2 {Tcl_ForgetImport, ignores patterns that don't match} {
+ namespace eval test_ns_export {
+ namespace export cmd1
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ }
+ namespace eval test_ns_import {
+ namespace forget ::test_ns_export::wombat
+ }
+} {}
+test namespace-10.3 {Tcl_ForgetImport, deletes matching imported cmds} {
+ namespace eval test_ns_import {
+ namespace import ::test_ns_export::*
+ proc p {} {return [cmd1 123]}
+ set l {}
+ lappend l [lsort [info commands ::test_ns_import::*]]
+ namespace forget ::test_ns_export::cmd1
+ lappend l [info commands ::test_ns_import::*]
+ lappend l [catch {cmd1 777} msg] $msg
+ }
+} [list [lsort {::test_ns_import::p ::test_ns_import::cmd1}] ::test_ns_import::p 1 {invalid command name "cmd1"}]
+
+test namespace-10.4 {Tcl_ForgetImport: Bug 560297} -setup {
+ namespace eval origin {
+ namespace export cmd
+ proc cmd {} {}
+ }
+ namespace eval unrelated {
+ proc cmd {} {}
+ }
+ namespace eval my \
+ [list namespace import [namespace current]::origin::cmd]
+} -body {
+ namespace eval my \
+ [list namespace forget [namespace current]::unrelated::cmd]
+ my::cmd
+} -cleanup {
+ namespace delete origin unrelated my
+}
+
+test namespace-10.5 {Tcl_ForgetImport: Bug 560297} -setup {
+ namespace eval origin {
+ namespace export cmd
+ proc cmd {} {}
+ }
+ namespace eval my \
+ [list namespace import [namespace current]::origin::cmd]
+ namespace eval my rename cmd newname
+} -body {
+ namespace eval my \
+ [list namespace forget [namespace current]::origin::cmd]
+ my::newname
+} -cleanup {
+ namespace delete origin my
+} -returnCodes error -match glob -result *
+
+test namespace-10.6 {Tcl_ForgetImport: Bug 560297} -setup {
+ namespace eval origin {
+ namespace export cmd
+ proc cmd {} {}
+ }
+ namespace eval my \
+ [list namespace import [namespace current]::origin::cmd]
+ namespace eval your {}
+ namespace eval my \
+ [list rename cmd [namespace current]::your::newname]
+} -body {
+ namespace eval your namespace forget newname
+ your::newname
+} -cleanup {
+ namespace delete origin my your
+} -returnCodes error -match glob -result *
+
+test namespace-10.7 {Tcl_ForgetImport: Bug 560297} -setup {
+ namespace eval origin {
+ namespace export cmd
+ proc cmd {} {}
+ }
+ namespace eval link namespace export cmd
+ namespace eval link \
+ [list namespace import [namespace current]::origin::cmd]
+ namespace eval link2 namespace export cmd
+ namespace eval link2 \
+ [list namespace import [namespace current]::link::cmd]
+ namespace eval my \
+ [list namespace import [namespace current]::link2::cmd]
+} -body {
+ namespace eval my \
+ [list namespace forget [namespace current]::origin::cmd]
+ my::cmd
+} -cleanup {
+ namespace delete origin link link2 my
+} -returnCodes error -match glob -result *
+
+test namespace-10.8 {Tcl_ForgetImport: Bug 560297} -setup {
+ namespace eval origin {
+ namespace export cmd
+ proc cmd {} {}
+ }
+ namespace eval link namespace export cmd
+ namespace eval link \
+ [list namespace import [namespace current]::origin::cmd]
+ namespace eval link2 namespace export cmd
+ namespace eval link2 \
+ [list namespace import [namespace current]::link::cmd]
+ namespace eval my \
+ [list namespace import [namespace current]::link2::cmd]
+} -body {
+ namespace eval my \
+ [list namespace forget [namespace current]::link::cmd]
+ my::cmd
+} -cleanup {
+ namespace delete origin link link2 my
+}
+
+test namespace-10.9 {Tcl_ForgetImport: Bug 560297} -setup {
+ namespace eval origin {
+ namespace export cmd
+ proc cmd {} {}
+ }
+ namespace eval link namespace export cmd
+ namespace eval link \
+ [list namespace import [namespace current]::origin::cmd]
+ namespace eval link2 namespace export cmd
+ namespace eval link2 \
+ [list namespace import [namespace current]::link::cmd]
+ namespace eval my \
+ [list namespace import [namespace current]::link2::cmd]
+} -body {
+ namespace eval my \
+ [list namespace forget [namespace current]::link2::cmd]
+ my::cmd
+} -cleanup {
+ namespace delete origin link link2 my
+} -returnCodes error -match glob -result *
+
+test namespace-11.1 {TclGetOriginalCommand, check if not imported cmd} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_export {
+ namespace export cmd1
+ proc cmd1 {args} {return "cmd1: $args"}
+ }
+ list [namespace origin set] [namespace origin test_ns_export::cmd1]
+} {::set ::test_ns_export::cmd1}
+test namespace-11.2 {TclGetOriginalCommand, directly imported cmd} {
+ namespace eval test_ns_import1 {
+ namespace import ::test_ns_export::*
+ namespace export *
+ proc p {} {namespace origin cmd1}
+ }
+ list [test_ns_import1::p] [namespace origin test_ns_import1::cmd1]
+} {::test_ns_export::cmd1 ::test_ns_export::cmd1}
+test namespace-11.3 {TclGetOriginalCommand, indirectly imported cmd} {
+ namespace eval test_ns_import2 {
+ namespace import ::test_ns_import1::*
+ proc q {} {return [cmd1 123]}
+ }
+ list [test_ns_import2::q] [namespace origin test_ns_import2::cmd1]
+} {{cmd1: 123} ::test_ns_export::cmd1}
+
+test namespace-12.1 {InvokeImportedCmd} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_export {
+ namespace export cmd1
+ proc cmd1 {args} {namespace current}
+ }
+ namespace eval test_ns_import {
+ namespace import ::test_ns_export::*
+ }
+ list [test_ns_import::cmd1]
+} {::test_ns_export}
+
+test namespace-13.1 {DeleteImportedCmd, deletes imported cmds} {
+ namespace eval test_ns_import {
+ set l {}
+ lappend l [info commands ::test_ns_import::*]
+ namespace forget ::test_ns_export::cmd1
+ lappend l [info commands ::test_ns_import::*]
+ }
+} {::test_ns_import::cmd1 {}}
+
+test namespace-14.1 {TclGetNamespaceForQualName, absolute names} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ variable v 10
+ namespace eval test_ns_1::test_ns_2 {
+ variable v 20
+ }
+ namespace eval test_ns_2 {
+ variable v 30
+ }
+ namespace eval test_ns_1 {
+ list $::v $::test_ns_2::v $::test_ns_1::test_ns_2::v \
+ [lsort [namespace children :: test_ns_*]]
+ }
+} [list 10 30 20 [lsort {::test_ns_1 ::test_ns_2}]]
+test namespace-14.2 {TclGetNamespaceForQualName, invalid absolute names} {
+ namespace eval test_ns_1 {
+ list [catch {set ::test_ns_777::v} msg] $msg \
+ [catch {namespace children test_ns_777} msg] $msg
+ }
+} {1 {can't read "::test_ns_777::v": no such variable} 1 {namespace "test_ns_777" not found in "::test_ns_1"}}
+test namespace-14.3 {TclGetNamespaceForQualName, relative names} {
+ namespace eval test_ns_1 {
+ list $v $test_ns_2::v
+ }
+} {10 20}
+test namespace-14.4 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
+ namespace eval test_ns_1::test_ns_2 {
+ namespace eval foo {}
+ }
+ namespace eval test_ns_1 {
+ list [namespace children test_ns_2] \
+ [catch {namespace children test_ns_1} msg] $msg
+ }
+} {::test_ns_1::test_ns_2::foo 1 {namespace "test_ns_1" not found in "::test_ns_1"}}
+test namespace-14.5 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
+ namespace eval ::test_ns_2 {
+ namespace eval bar {}
+ }
+ namespace eval test_ns_1 {
+ list [catch {namespace delete test_ns_2::bar} msg] $msg
+ }
+} {1 {unknown namespace "test_ns_2::bar" in namespace delete command}}
+test namespace-14.6 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
+ namespace eval test_ns_1::test_ns_2 {
+ namespace eval foo {}
+ }
+ namespace eval test_ns_1 {
+ list [namespace children test_ns_2] \
+ [catch {namespace children test_ns_1} msg] $msg
+ }
+} {::test_ns_1::test_ns_2::foo 1 {namespace "test_ns_1" not found in "::test_ns_1"}}
+test namespace-14.7 {TclGetNamespaceForQualName, ignore extra :s if ns} {
+ namespace children test_ns_1:::
+} {::test_ns_1::test_ns_2}
+test namespace-14.8 {TclGetNamespaceForQualName, ignore extra :s if ns} {
+ namespace children :::test_ns_1:::::test_ns_2:::
+} {::test_ns_1::test_ns_2::foo}
+test namespace-14.9 {TclGetNamespaceForQualName, extra ::s are significant for vars} {
+ set l {}
+ lappend l [catch {set test_ns_1::test_ns_2::} msg] $msg
+ namespace eval test_ns_1::test_ns_2 {variable {} 2525}
+ lappend l [set test_ns_1::test_ns_2::]
+} {1 {can't read "test_ns_1::test_ns_2::": no such variable} 2525}
+test namespace-14.10 {TclGetNamespaceForQualName, extra ::s are significant for vars} {
+ catch {unset test_ns_1::test_ns_2::}
+ set l {}
+ lappend l [catch {set test_ns_1::test_ns_2::} msg] $msg
+ set test_ns_1::test_ns_2:: 314159
+ lappend l [set test_ns_1::test_ns_2::]
+} {1 {can't read "test_ns_1::test_ns_2::": no such variable} 314159}
+test namespace-14.11 {TclGetNamespaceForQualName, extra ::s are significant for commands} {
+ catch {rename test_ns_1::test_ns_2:: {}}
+ set l {}
+ lappend l [catch {test_ns_1::test_ns_2:: hello} msg] $msg
+ proc test_ns_1::test_ns_2:: {args} {return "\{\}: $args"}
+ lappend l [test_ns_1::test_ns_2:: hello]
+} {1 {invalid command name "test_ns_1::test_ns_2::"} {{}: hello}}
+test namespace-14.12 {TclGetNamespaceForQualName, extra ::s are significant for vars} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1 {
+ variable {}
+ set test_ns_1::(x) y
+ }
+ set test_ns_1::(x)
+} y
+test namespace-14.13 {TclGetNamespaceForQualName, namespace other than global ns can't have empty name} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace eval test_ns_1 {proc {} {} {}; namespace eval {} {}; {}}} msg] $msg
+} {1 {can't create namespace "": only global namespace can have empty name}}
+
+test namespace-15.1 {Tcl_FindNamespace, absolute name found} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_delete {
+ namespace eval test_ns_delete2 {}
+ proc cmd {args} {namespace current}
+ }
+ list [namespace delete ::test_ns_delete::test_ns_delete2] \
+ [namespace children ::test_ns_delete]
+} {{} {}}
+test namespace-15.2 {Tcl_FindNamespace, absolute name not found} {
+ list [catch {namespace delete ::test_ns_delete::test_ns_delete2} msg] $msg
+} {1 {unknown namespace "::test_ns_delete::test_ns_delete2" in namespace delete command}}
+test namespace-15.3 {Tcl_FindNamespace, relative name found} {
+ namespace eval test_ns_delete {
+ namespace eval test_ns_delete2 {}
+ namespace eval test_ns_delete3 {}
+ list [namespace delete test_ns_delete2] \
+ [namespace children [namespace current]]
+ }
+} {{} ::test_ns_delete::test_ns_delete3}
+test namespace-15.4 {Tcl_FindNamespace, relative name not found} {
+ namespace eval test_ns_delete2 {}
+ namespace eval test_ns_delete {
+ list [catch {namespace delete test_ns_delete2} msg] $msg
+ }
+} {1 {unknown namespace "test_ns_delete2" in namespace delete command}}
+
+test namespace-16.1 {Tcl_FindCommand, absolute name found} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1 {
+ proc cmd {args} {return "[namespace current]::cmd: $args"}
+ variable v "::test_ns_1::cmd"
+ eval $v one
+ }
+} {::test_ns_1::cmd: one}
+test namespace-16.2 {Tcl_FindCommand, absolute name found} {
+ eval $test_ns_1::v two
+} {::test_ns_1::cmd: two}
+test namespace-16.3 {Tcl_FindCommand, absolute name not found} {
+ namespace eval test_ns_1 {
+ variable v2 "::test_ns_1::ladidah"
+ list [catch {eval $v2} msg] $msg
+ }
+} {1 {invalid command name "::test_ns_1::ladidah"}}
+
+# save the "unknown" proc, which is redefined by the following two tests
+catch {rename unknown unknown.old}
+proc unknown {args} {
+ return "unknown: $args"
+}
+test namespace-16.4 {Tcl_FindCommand, absolute name and TCL_GLOBAL_ONLY} {
+ ::test_ns_1::foobar x y z
+} {unknown: ::test_ns_1::foobar x y z}
+test namespace-16.5 {Tcl_FindCommand, absolute name and TCL_GLOBAL_ONLY} {
+ ::foobar 1 2 3 4 5
+} {unknown: ::foobar 1 2 3 4 5}
+test namespace-16.6 {Tcl_FindCommand, relative name and TCL_GLOBAL_ONLY} {
+ test_ns_1::foobar x y z
+} {unknown: test_ns_1::foobar x y z}
+test namespace-16.7 {Tcl_FindCommand, relative name and TCL_GLOBAL_ONLY} {
+ foobar 1 2 3 4 5
+} {unknown: foobar 1 2 3 4 5}
+# restore the "unknown" proc saved previously
+catch {rename unknown {}}
+catch {rename unknown.old unknown}
+
+test namespace-16.8 {Tcl_FindCommand, relative name found} {
+ namespace eval test_ns_1 {
+ cmd a b c
+ }
+} {::test_ns_1::cmd: a b c}
+test namespace-16.9 {Tcl_FindCommand, relative name found} -body {
+ proc cmd2 {args} {return "[namespace current]::cmd2: $args"}
+ namespace eval test_ns_1 {
+ cmd2 a b c
+ }
+} -cleanup {
+ catch {rename cmd2 {}}
+} -result {::::cmd2: a b c}
+test namespace-16.10 {Tcl_FindCommand, relative name found, only look in current then global ns} -body {
+ proc cmd2 {args} {return "[namespace current]::cmd2: $args"}
+ namespace eval test_ns_1 {
+ proc cmd2 {args} {
+ return "[namespace current]::cmd2 in test_ns_1: $args"
+ }
+ namespace eval test_ns_12 {
+ cmd2 a b c
+ }
+ }
+} -cleanup {
+ catch {rename cmd2 {}}
+} -result {::::cmd2: a b c}
+test namespace-16.11 {Tcl_FindCommand, relative name not found} {
+ namespace eval test_ns_1 {
+ list [catch {cmd3 a b c} msg] $msg
+ }
+} {1 {invalid command name "cmd3"}}
+
+catch {unset x}
+test namespace-17.1 {Tcl_FindNamespaceVar, absolute name found} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ set x 314159
+ namespace eval test_ns_1 {
+ set ::x
+ }
+} {314159}
+test namespace-17.2 {Tcl_FindNamespaceVar, absolute name found} {
+ namespace eval test_ns_1 {
+ variable x 777
+ set ::test_ns_1::x
+ }
+} {777}
+test namespace-17.3 {Tcl_FindNamespaceVar, absolute name found} {
+ namespace eval test_ns_1 {
+ namespace eval test_ns_2 {
+ variable x 1111
+ }
+ set ::test_ns_1::test_ns_2::x
+ }
+} {1111}
+test namespace-17.4 {Tcl_FindNamespaceVar, absolute name not found} {
+ namespace eval test_ns_1 {
+ namespace eval test_ns_2 {
+ variable x 1111
+ }
+ list [catch {set ::test_ns_1::test_ns_2::y} msg] $msg
+ }
+} {1 {can't read "::test_ns_1::test_ns_2::y": no such variable}}
+test namespace-17.5 {Tcl_FindNamespaceVar, absolute name and TCL_GLOBAL_ONLY} {
+ namespace eval test_ns_1 {
+ namespace eval test_ns_3 {
+ variable ::test_ns_1::test_ns_2::x 2222
+ }
+ }
+ set ::test_ns_1::test_ns_2::x
+} {2222}
+test namespace-17.6 {Tcl_FindNamespaceVar, relative name found} {
+ namespace eval test_ns_1 {
+ set x
+ }
+} {777}
+test namespace-17.7 {Tcl_FindNamespaceVar, relative name found} {
+ namespace eval test_ns_1 {
+ unset x
+ set x ;# must be global x now
+ }
+} {314159}
+test namespace-17.8 {Tcl_FindNamespaceVar, relative name not found} {
+ namespace eval test_ns_1 {
+ list [catch {set wuzzat} msg] $msg
+ }
+} {1 {can't read "wuzzat": no such variable}}
+test namespace-17.9 {Tcl_FindNamespaceVar, relative name and TCL_GLOBAL_ONLY} {
+ namespace eval test_ns_1 {
+ variable a hello
+ }
+ set test_ns_1::a
+} {hello}
+test namespace-17.10 {Tcl_FindNamespaceVar, interference with cached varNames} {
+ namespace eval test_ns_1 {}
+ proc test_ns {} {
+ set ::test_ns_1::a 0
+ }
+ test_ns
+ rename test_ns {}
+ namespace eval test_ns_1 unset a
+ set a 0
+ namespace eval test_ns_1 set a 1
+ namespace delete test_ns_1
+ return $a
+} 1
+catch {unset a}
+catch {unset x}
+
+catch {unset l}
+catch {rename foo {}}
+test namespace-18.1 {TclResetShadowedCmdRefs, one-level check for command shadowing} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ proc foo {} {return "global foo"}
+ namespace eval test_ns_1 {
+ proc trigger {} {
+ return [foo]
+ }
+ }
+ set l ""
+ lappend l [test_ns_1::trigger]
+ namespace eval test_ns_1 {
+ # force invalidation of cached ref to "foo" in proc trigger
+ proc foo {} {return "foo in test_ns_1"}
+ }
+ lappend l [test_ns_1::trigger]
+} {{global foo} {foo in test_ns_1}}
+test namespace-18.2 {TclResetShadowedCmdRefs, multilevel check for command shadowing} {
+ namespace eval test_ns_2 {
+ proc foo {} {return "foo in ::test_ns_2"}
+ }
+ namespace eval test_ns_1 {
+ namespace eval test_ns_2 {}
+ proc trigger {} {
+ return [test_ns_2::foo]
+ }
+ }
+ set l ""
+ lappend l [test_ns_1::trigger]
+ namespace eval test_ns_1 {
+ namespace eval test_ns_2 {
+ # force invalidation of cached ref to "foo" in proc trigger
+ proc foo {} {return "foo in ::test_ns_1::test_ns_2"}
+ }
+ }
+ lappend l [test_ns_1::trigger]
+} {{foo in ::test_ns_2} {foo in ::test_ns_1::test_ns_2}}
+catch {unset l}
+catch {rename foo {}}
+
+test namespace-19.1 {GetNamespaceFromObj, global name found} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1::test_ns_2 {}
+ namespace children ::test_ns_1
+} {::test_ns_1::test_ns_2}
+test namespace-19.2 {GetNamespaceFromObj, relative name found} {
+ namespace eval test_ns_1 {
+ namespace children test_ns_2
+ }
+} {}
+test namespace-19.3 {GetNamespaceFromObj, name not found} -body {
+ namespace eval test_ns_1 {
+ namespace children test_ns_99
+ }
+} -returnCodes error -result {namespace "test_ns_99" not found in "::test_ns_1"}
+test namespace-19.4 {GetNamespaceFromObj, invalidation of cached ns refs} {
+ namespace eval test_ns_1 {
+ proc foo {} {
+ return [namespace children test_ns_2]
+ }
+ list [catch {namespace children test_ns_99} msg] $msg
+ }
+ set l {}
+ lappend l [test_ns_1::foo]
+ namespace delete test_ns_1::test_ns_2
+ namespace eval test_ns_1::test_ns_2::test_ns_3 {}
+ lappend l [test_ns_1::foo]
+} {{} ::test_ns_1::test_ns_2::test_ns_3}
+
+test namespace-20.1 {Tcl_NamespaceObjCmd, bad subcommand} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace} msg] $msg
+} {1 {wrong # args: should be "namespace subcommand ?arg ...?"}}
+test namespace-20.2 {Tcl_NamespaceObjCmd, bad subcommand} -body {
+ namespace wombat {}
+} -returnCodes error -match glob -result {unknown or ambiguous subcommand "wombat": must be *}
+test namespace-20.3 {Tcl_NamespaceObjCmd, abbreviations are okay} {
+ namespace ch :: test_ns_*
+} {}
+
+test namespace-21.1 {NamespaceChildrenCmd, no args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1::test_ns_2 {}
+ expr {[string first ::test_ns_1 [namespace children]] != -1}
+} {1}
+test namespace-21.2 {NamespaceChildrenCmd, no args} {
+ namespace eval test_ns_1 {
+ namespace children
+ }
+} {::test_ns_1::test_ns_2}
+test namespace-21.3 {NamespaceChildrenCmd, ns name given} {
+ namespace children ::test_ns_1
+} {::test_ns_1::test_ns_2}
+test namespace-21.4 {NamespaceChildrenCmd, ns name given} {
+ namespace eval test_ns_1 {
+ namespace children test_ns_2
+ }
+} {}
+test namespace-21.5 {NamespaceChildrenCmd, too many args} {
+ namespace eval test_ns_1 {
+ list [catch {namespace children test_ns_2 xxx yyy} msg] $msg
+ }
+} {1 {wrong # args: should be "namespace children ?name? ?pattern?"}}
+test namespace-21.6 {NamespaceChildrenCmd, glob-style pattern given} {
+ namespace eval test_ns_1::test_ns_foo {}
+ namespace children test_ns_1 *f*
+} {::test_ns_1::test_ns_foo}
+test namespace-21.7 {NamespaceChildrenCmd, glob-style pattern given} {
+ namespace eval test_ns_1::test_ns_foo {}
+ lsort [namespace children test_ns_1 test*]
+} [lsort {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_foo}]
+test namespace-21.8 {NamespaceChildrenCmd, trivial pattern starting with ::} {
+ namespace eval test_ns_1 {}
+ namespace children [namespace current] [fq test_ns_1]
+} [fq test_ns_1]
+
+test namespace-22.1 {NamespaceCodeCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace code} msg] $msg \
+ [catch {namespace code xxx yyy} msg] $msg
+} {1 {wrong # args: should be "namespace code arg"} 1 {wrong # args: should be "namespace code arg"}}
+test namespace-22.2 {NamespaceCodeCmd, arg is already scoped value} {
+ namespace eval test_ns_1 {
+ proc cmd {} {return "test_ns_1::cmd"}
+ }
+ namespace code {::namespace inscope ::test_ns_1 cmd}
+} {::namespace inscope ::test_ns_1 cmd}
+test namespace-22.3 {NamespaceCodeCmd, arg is already scoped value} {
+ namespace code {namespace inscope ::test_ns_1 cmd}
+} {::namespace inscope :: {namespace inscope ::test_ns_1 cmd}}
+test namespace-22.4 {NamespaceCodeCmd, in :: namespace} {
+ namespace code unknown
+} {::namespace inscope :: unknown}
+test namespace-22.5 {NamespaceCodeCmd, in other namespace} {
+ namespace eval test_ns_1 {
+ namespace code cmd
+ }
+} {::namespace inscope ::test_ns_1 cmd}
+test namespace-22.6 {NamespaceCodeCmd, in other namespace} {
+ namespace eval test_ns_1 {
+ variable v 42
+ }
+ namespace eval test_ns_2 {
+ proc namespace args {}
+ }
+ namespace eval test_ns_2 [namespace eval test_ns_1 {
+ namespace code {set v}
+ }]
+} {42}
+test namespace-22.7 {NamespaceCodeCmd, Bug 3202171} {
+ namespace eval demo {
+ proc namespace args {puts $args}
+ ::namespace code {namespace inscope foo}
+ }
+} [list ::namespace inscope [fq demo] {namespace inscope foo}]
+
+test namespace-23.1 {NamespaceCurrentCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace current xxx} msg] $msg \
+ [catch {namespace current xxx yyy} msg] $msg
+} {1 {wrong # args: should be "namespace current"} 1 {wrong # args: should be "namespace current"}}
+test namespace-23.2 {NamespaceCurrentCmd, at global level} {
+ namespace current
+} {::}
+test namespace-23.3 {NamespaceCurrentCmd, in nested ns} {
+ namespace eval test_ns_1::test_ns_2 {
+ namespace current
+ }
+} {::test_ns_1::test_ns_2}
+
+test namespace-24.1 {NamespaceDeleteCmd, no args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace delete
+} {}
+test namespace-24.2 {NamespaceDeleteCmd, one arg} {
+ namespace eval test_ns_1::test_ns_2 {}
+ namespace delete ::test_ns_1
+} {}
+test namespace-24.3 {NamespaceDeleteCmd, two args} {
+ namespace eval test_ns_1::test_ns_2 {}
+ list [namespace delete ::test_ns_1::test_ns_2] [namespace delete ::test_ns_1]
+} {{} {}}
+test namespace-24.4 {NamespaceDeleteCmd, unknown ns} {
+ list [catch {namespace delete ::test_ns_foo} msg] $msg
+} {1 {unknown namespace "::test_ns_foo" in namespace delete command}}
+
+test namespace-25.1 {NamespaceEvalCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace eval} msg] $msg
+} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
+test namespace-25.2 {NamespaceEvalCmd, bad args} -body {
+ namespace test_ns_1
+} -returnCodes error -match glob -result {unknown or ambiguous subcommand "test_ns_1": must be *}
+catch {unset v}
+test namespace-25.3 {NamespaceEvalCmd, new namespace} {
+ set v 123
+ namespace eval test_ns_1 {
+ variable v 314159
+ proc p {} {
+ variable v
+ return $v
+ }
+ }
+ test_ns_1::p
+} {314159}
+test namespace-25.4 {NamespaceEvalCmd, existing namespace} {
+ namespace eval test_ns_1 {
+ proc q {} {return [expr {[p]+1}]}
+ }
+ test_ns_1::q
+} {314160}
+test namespace-25.5 {NamespaceEvalCmd, multiple args} {
+ namespace eval test_ns_1 "set" "v"
+} {314159}
+test namespace-25.6 {NamespaceEvalCmd, error in eval'd script} {
+ list [catch {namespace eval test_ns_1 {xxxx}} msg] $msg $::errorInfo
+} {1 {invalid command name "xxxx"} {invalid command name "xxxx"
+ while executing
+"xxxx"
+ (in namespace eval "::test_ns_1" script line 1)
+ invoked from within
+"namespace eval test_ns_1 {xxxx}"}}
+test namespace-25.7 {NamespaceEvalCmd, error in eval'd script} {
+ list [catch {namespace eval test_ns_1 {error foo bar baz}} msg] $msg $::errorInfo
+} {1 foo {bar
+ (in namespace eval "::test_ns_1" script line 1)
+ invoked from within
+"namespace eval test_ns_1 {error foo bar baz}"}}
+test namespace-25.8 {NamespaceEvalCmd, error in eval'd script} {
+ list [catch {namespace eval test_ns_1 error foo bar baz} msg] $msg $::errorInfo
+} {1 foo {bar
+ (in namespace eval "::test_ns_1" script line 1)
+ invoked from within
+"namespace eval test_ns_1 error foo bar baz"}}
+catch {unset v}
+test namespace-25.9 {NamespaceEvalCmd, 545325} {
+ namespace eval test_ns_1 info level 0
+} {namespace eval test_ns_1 info level 0}
+
+test namespace-26.1 {NamespaceExportCmd, no args and new ns} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace export
+} {}
+test namespace-26.2 {NamespaceExportCmd, just -clear arg} {
+ namespace export -clear
+} {}
+test namespace-26.3 {NamespaceExportCmd, pattern can't specify a namespace} {
+ namespace eval test_ns_1 {
+ list [catch {namespace export ::zzz} msg] $msg
+ }
+} {1 {invalid export pattern "::zzz": pattern can't specify a namespace}}
+test namespace-26.4 {NamespaceExportCmd, one pattern} {
+ namespace eval test_ns_1 {
+ namespace export cmd1
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ proc cmd3 {args} {return "cmd3: $args"}
+ proc cmd4 {args} {return "cmd4: $args"}
+ }
+ namespace eval test_ns_2 {
+ namespace import ::test_ns_1::*
+ }
+ list [info commands test_ns_2::*] [test_ns_2::cmd1 hello]
+} {::test_ns_2::cmd1 {cmd1: hello}}
+test namespace-26.5 {NamespaceExportCmd, sequence of patterns, patterns accumulate} {
+ namespace eval test_ns_1 {
+ namespace export cmd1 cmd3
+ }
+ namespace eval test_ns_2 {
+ namespace import -force ::test_ns_1::*
+ }
+ list [lsort [info commands test_ns_2::*]] [test_ns_2::cmd3 hello]
+} [list [lsort {::test_ns_2::cmd1 ::test_ns_2::cmd3}] {cmd3: hello}]
+test namespace-26.6 {NamespaceExportCmd, no patterns means return uniq'ed export list} {
+ namespace eval test_ns_1 {
+ namespace export
+ }
+} {cmd1 cmd3}
+test namespace-26.7 {NamespaceExportCmd, -clear resets export list} {
+ namespace eval test_ns_1 {
+ namespace export -clear cmd4
+ }
+ namespace eval test_ns_2 {
+ namespace import ::test_ns_1::*
+ }
+ list [lsort [info commands test_ns_2::*]] [test_ns_2::cmd4 hello]
+} [list [lsort {::test_ns_2::cmd4 ::test_ns_2::cmd1 ::test_ns_2::cmd3}] {cmd4: hello}]
+
+test namespace-27.1 {NamespaceForgetCmd, no args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace forget
+} {}
+test namespace-27.2 {NamespaceForgetCmd, args must be valid namespaces} {
+ list [catch {namespace forget ::test_ns_1::xxx} msg] $msg
+} {1 {unknown namespace in namespace forget pattern "::test_ns_1::xxx"}}
+test namespace-27.3 {NamespaceForgetCmd, arg is forgotten} {
+ namespace eval test_ns_1 {
+ namespace export cmd*
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ }
+ namespace eval test_ns_2 {
+ namespace import ::test_ns_1::*
+ namespace forget ::test_ns_1::cmd1
+ }
+ info commands ::test_ns_2::*
+} {::test_ns_2::cmd2}
+
+test namespace-28.1 {NamespaceImportCmd, no args} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ namespace eval ::test_ns_1 {
+ proc foo {} {}
+ proc bar {} {}
+ proc boo {} {}
+ proc glorp {} {}
+ namespace export foo b*
+ }
+ namespace eval ::test_ns_2 {
+ namespace import ::test_ns_1::*
+ lsort [namespace import]
+ }
+} -cleanup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -result {bar boo foo}
+test namespace-28.2 {NamespaceImportCmd, no args and just "-force"} {
+ namespace import -force
+} {}
+test namespace-28.3 {NamespaceImportCmd, arg is imported} {
+ namespace eval test_ns_1 {
+ namespace export cmd2
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ }
+ namespace eval test_ns_2 {
+ namespace import ::test_ns_1::*
+ namespace forget ::test_ns_1::cmd1
+ }
+ info commands test_ns_2::*
+} {::test_ns_2::cmd2}
+
+test namespace-29.1 {NamespaceInscopeCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace inscope} msg] $msg
+} {1 {wrong # args: should be "namespace inscope name arg ?arg...?"}}
+test namespace-29.2 {NamespaceInscopeCmd, bad args} {
+ list [catch {namespace inscope ::} msg] $msg
+} {1 {wrong # args: should be "namespace inscope name arg ?arg...?"}}
+test namespace-29.3 {NamespaceInscopeCmd, specified ns must exist} -body {
+ namespace inscope test_ns_1 {set v}
+} -returnCodes error -result {namespace "test_ns_1" not found in "::"}
+test namespace-29.4 {NamespaceInscopeCmd, simple case} {
+ namespace eval test_ns_1 {
+ variable v 747
+ proc cmd {args} {
+ variable v
+ return "[namespace current]::cmd: v=$v, args=$args"
+ }
+ }
+ namespace inscope test_ns_1 cmd
+} {::test_ns_1::cmd: v=747, args=}
+test namespace-29.5 {NamespaceInscopeCmd, has lappend semantics} {
+ list [namespace inscope test_ns_1 cmd x y z] \
+ [namespace eval test_ns_1 [concat cmd [list x y z]]]
+} {{::test_ns_1::cmd: v=747, args=x y z} {::test_ns_1::cmd: v=747, args=x y z}}
+test namespace-29.6 {NamespaceInscopeCmd, 1400572} {
+ namespace inscope test_ns_1 {info level 0}
+} {namespace inscope test_ns_1 {info level 0}}
+
+
+test namespace-30.1 {NamespaceOriginCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace origin} msg] $msg
+} {1 {wrong # args: should be "namespace origin name"}}
+test namespace-30.2 {NamespaceOriginCmd, bad args} {
+ list [catch {namespace origin x y} msg] $msg
+} {1 {wrong # args: should be "namespace origin name"}}
+test namespace-30.3 {NamespaceOriginCmd, command not found} {
+ list [catch {namespace origin fred} msg] $msg
+} {1 {invalid command name "fred"}}
+test namespace-30.4 {NamespaceOriginCmd, command isn't imported} {
+ namespace origin set
+} {::set}
+test namespace-30.5 {NamespaceOriginCmd, imported command} {
+ namespace eval test_ns_1 {
+ namespace export cmd*
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ }
+ namespace eval test_ns_2 {
+ namespace export *
+ namespace import ::test_ns_1::*
+ proc p {} {}
+ }
+ namespace eval test_ns_3 {
+ namespace import ::test_ns_2::*
+ list [namespace origin foreach] \
+ [namespace origin p] \
+ [namespace origin cmd1] \
+ [namespace origin ::test_ns_2::cmd2]
+ }
+} {::foreach ::test_ns_2::p ::test_ns_1::cmd1 ::test_ns_1::cmd2}
+
+test namespace-31.1 {NamespaceParentCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace parent a b} msg] $msg
+} {1 {wrong # args: should be "namespace parent ?name?"}}
+test namespace-31.2 {NamespaceParentCmd, no args} {
+ namespace parent
+} {}
+test namespace-31.3 {NamespaceParentCmd, namespace specified} {
+ namespace eval test_ns_1 {
+ namespace eval test_ns_2 {
+ namespace eval test_ns_3 {}
+ }
+ }
+ list [namespace parent ::] \
+ [namespace parent test_ns_1::test_ns_2] \
+ [namespace eval test_ns_1::test_ns_2::test_ns_3 {namespace parent ::test_ns_1::test_ns_2}]
+} {{} ::test_ns_1 ::test_ns_1}
+test namespace-31.4 {NamespaceParentCmd, bad namespace specified} -body {
+ namespace parent test_ns_1::test_ns_foo
+} -returnCodes error -result {namespace "test_ns_1::test_ns_foo" not found in "::"}
+
+test namespace-32.1 {NamespaceQualifiersCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace qualifiers} msg] $msg
+} {1 {wrong # args: should be "namespace qualifiers string"}}
+test namespace-32.2 {NamespaceQualifiersCmd, bad args} {
+ list [catch {namespace qualifiers x y} msg] $msg
+} {1 {wrong # args: should be "namespace qualifiers string"}}
+test namespace-32.3 {NamespaceQualifiersCmd, simple name} {
+ namespace qualifiers foo
+} {}
+test namespace-32.4 {NamespaceQualifiersCmd, leading ::} {
+ namespace qualifiers ::x::y::z
+} {::x::y}
+test namespace-32.5 {NamespaceQualifiersCmd, no leading ::} {
+ namespace qualifiers a::b
+} {a}
+test namespace-32.6 {NamespaceQualifiersCmd, :: argument} {
+ namespace qualifiers ::
+} {}
+test namespace-32.7 {NamespaceQualifiersCmd, odd number of :s} {
+ namespace qualifiers :::::
+} {}
+test namespace-32.8 {NamespaceQualifiersCmd, odd number of :s} {
+ namespace qualifiers foo:::
+} {foo}
+
+test namespace-33.1 {NamespaceTailCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace tail} msg] $msg
+} {1 {wrong # args: should be "namespace tail string"}}
+test namespace-33.2 {NamespaceTailCmd, bad args} {
+ list [catch {namespace tail x y} msg] $msg
+} {1 {wrong # args: should be "namespace tail string"}}
+test namespace-33.3 {NamespaceTailCmd, simple name} {
+ namespace tail foo
+} {foo}
+test namespace-33.4 {NamespaceTailCmd, leading ::} {
+ namespace tail ::x::y::z
+} {z}
+test namespace-33.5 {NamespaceTailCmd, no leading ::} {
+ namespace tail a::b
+} {b}
+test namespace-33.6 {NamespaceTailCmd, :: argument} {
+ namespace tail ::
+} {}
+test namespace-33.7 {NamespaceTailCmd, odd number of :s} {
+ namespace tail :::::
+} {}
+test namespace-33.8 {NamespaceTailCmd, odd number of :s} {
+ namespace tail foo:::
+} {}
+
+test namespace-34.1 {NamespaceWhichCmd, bad args} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ list [catch {namespace which} msg] $msg
+} {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
+test namespace-34.2 {NamespaceWhichCmd, bad args} {
+ list [catch {namespace which -fred x} msg] $msg
+} {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
+test namespace-34.3 {NamespaceWhichCmd, single arg is always command name} {
+ namespace which -command
+} {}
+test namespace-34.4 {NamespaceWhichCmd, bad args} {
+ list [catch {namespace which a b} msg] $msg
+} {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
+test namespace-34.5 {NamespaceWhichCmd, command lookup} {
+ namespace eval test_ns_1 {
+ namespace export cmd*
+ variable v1 111
+ proc cmd1 {args} {return "cmd1: $args"}
+ proc cmd2 {args} {return "cmd2: $args"}
+ }
+ namespace eval test_ns_2 {
+ namespace export *
+ namespace import ::test_ns_1::*
+ variable v2 222
+ proc p {} {}
+ }
+ namespace eval test_ns_3 {
+ namespace import ::test_ns_2::*
+ variable v3 333
+ list [namespace which -command foreach] \
+ [namespace which -command p] \
+ [namespace which -command cmd1] \
+ [namespace which -command ::test_ns_2::cmd2] \
+ [catch {namespace which -command ::test_ns_2::noSuchCmd} msg] $msg
+ }
+} {::foreach ::test_ns_3::p ::test_ns_3::cmd1 ::test_ns_2::cmd2 0 {}}
+test namespace-34.6 {NamespaceWhichCmd, -command is default} {
+ namespace eval test_ns_3 {
+ list [namespace which foreach] \
+ [namespace which p] \
+ [namespace which cmd1] \
+ [namespace which ::test_ns_2::cmd2]
+ }
+} {::foreach ::test_ns_3::p ::test_ns_3::cmd1 ::test_ns_2::cmd2}
+test namespace-34.7 {NamespaceWhichCmd, variable lookup} {
+ namespace eval test_ns_3 {
+ list [namespace which -variable env] \
+ [namespace which -variable v3] \
+ [namespace which -variable ::test_ns_2::v2] \
+ [catch {namespace which -variable ::test_ns_2::noSuchVar} msg] $msg
+ }
+} {::env ::test_ns_3::v3 ::test_ns_2::v2 0 {}}
+
+test namespace-35.1 {FreeNsNameInternalRep, resulting ref count > 0} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1 {
+ proc p {} {
+ namespace delete [namespace current]
+ return [namespace current]
+ }
+ }
+ test_ns_1::p
+} {::test_ns_1}
+test namespace-35.2 {FreeNsNameInternalRep, resulting ref count == 0} {
+ namespace eval test_ns_1 {
+ proc q {} {
+ return [namespace current]
+ }
+ }
+ list [test_ns_1::q] \
+ [namespace delete test_ns_1] \
+ [catch {test_ns_1::q} msg] $msg
+} {::test_ns_1 {} 1 {invalid command name "test_ns_1::q"}}
+
+catch {unset x}
+catch {unset y}
+test namespace-36.1 {DupNsNameInternalRep} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1 {}
+ set x "::test_ns_1"
+ list [namespace parent $x] [set y $x] [namespace parent $y]
+} {:: ::test_ns_1 ::}
+catch {unset x}
+catch {unset y}
+
+test namespace-37.1 {SetNsNameFromAny, ns name found} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval test_ns_1::test_ns_2 {}
+ namespace eval test_ns_1 {
+ namespace children ::test_ns_1
+ }
+} {::test_ns_1::test_ns_2}
+test namespace-37.2 {SetNsNameFromAny, ns name not found} -body {
+ namespace eval test_ns_1 {
+ namespace children ::test_ns_1::test_ns_foo
+ }
+} -returnCodes error -result {namespace "::test_ns_1::test_ns_foo" not found}
+
+test namespace-38.1 {UpdateStringOfNsName} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ ;# Tcl_NamespaceObjCmd calls UpdateStringOfNsName to get subcmd name
+ list [namespace eval {} {namespace current}] \
+ [namespace eval {} {namespace current}]
+} {:: ::}
+
+test namespace-39.1 {NamespaceExistsCmd} {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ namespace eval ::test_ns_z::test_me { variable foo }
+ list [namespace exists ::] \
+ [namespace exists ::bogus_namespace] \
+ [namespace exists ::test_ns_z] \
+ [namespace exists test_ns_z] \
+ [namespace exists ::test_ns_z::foo] \
+ [namespace exists ::test_ns_z::test_me] \
+ [namespace eval ::test_ns_z { namespace exists ::test_me }] \
+ [namespace eval ::test_ns_z { namespace exists test_me }] \
+ [namespace exists :::::test_ns_z]
+} {1 0 1 1 0 1 0 1 1}
+test namespace-39.2 {NamespaceExistsCmd error} {
+ list [catch {namespace exists} msg] $msg
+} {1 {wrong # args: should be "namespace exists name"}}
+test namespace-39.3 {NamespaceExistsCmd error} {
+ list [catch {namespace exists a b} msg] $msg
+} {1 {wrong # args: should be "namespace exists name"}}
+
+test namespace-40.1 {Ignoring namespace proc "unknown"} -setup {
+ rename unknown _unknown
+} -body {
+ proc unknown args {return global}
+ namespace eval ns {proc unknown args {return local}}
+ list [namespace eval ns aaa bbb] [namespace eval ns aaa]
+} -cleanup {
+ rename unknown {}
+ rename _unknown unknown
+ namespace delete ns
+} -result {global global}
+
+test namespace-41.1 {Shadowing byte-compiled commands, Bug: 231259} {
+ set res {}
+ namespace eval ns {
+ set res {}
+ proc test {} {
+ set ::g 0
+ }
+ lappend ::res [test]
+ proc set {a b} {
+ ::set a [incr b]
+ }
+ lappend ::res [test]
+ }
+ namespace delete ns
+ set res
+} {0 1}
+test namespace-41.2 {Shadowing byte-compiled commands, Bug: 231259} {
+ set res {}
+ namespace eval ns {}
+ proc ns::a {i} {
+ variable b
+ proc set args {return "New proc is called"}
+ return [set b $i]
+ }
+ ns::a 1
+ set res [ns::a 2]
+ namespace delete ns
+ set res
+} {New proc is called}
+test namespace-41.3 {Shadowing byte-compiled commands, Bugs: 231259, 729692} {
+ set res {}
+ namespace eval ns {
+ variable b 0
+ }
+ proc ns::a {i} {
+ variable b
+ proc set args {return "New proc is called"}
+ return [set b $i]
+ }
+ set res [list [ns::a 1] $ns::b]
+ namespace delete ns
+ set res
+} {{New proc is called} 0}
+
+# Ensembles (TIP#112)
+
+test namespace-42.1 {ensembles: basic} {
+ namespace eval ns {
+ namespace export x
+ proc x {} {format 1}
+ namespace ensemble create
+ }
+ list [info command ns] [ns x] [namespace delete ns] [info command ns]
+} {ns 1 {} {}}
+test namespace-42.2 {ensembles: basic} {
+ namespace eval ns {
+ namespace export x
+ proc x {} {format 1}
+ namespace ensemble create
+ }
+ rename ns foo
+ list [info command foo] [foo x] [namespace delete ns] [info command foo]
+} {foo 1 {} {}}
+test namespace-42.3 {ensembles: basic} {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {} {format 1}
+ proc x2 {} {format 2}
+ namespace ensemble create
+ }
+ set result [list [ns x1] [ns x2]]
+ lappend result [catch {ns x} msg] $msg
+ rename ns {}
+ lappend result [info command ns::x1]
+ namespace delete ns
+ lappend result [info command ns::x1]
+} {1 2 1 {unknown or ambiguous subcommand "x": must be x1, or x2} ::ns::x1 {}}
+test namespace-42.4 {ensembles: basic} -body {
+ namespace eval ns {
+ namespace export y*
+ proc x1 {} {format 1}
+ proc x2 {} {format 2}
+ namespace ensemble create
+ }
+ list [catch {ns x} msg] $msg
+} -cleanup {
+ namespace delete ns
+} -result {1 {unknown subcommand "x": namespace ::ns does not export any commands}}
+test namespace-42.5 {ensembles: basic} -body {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {} {format 1}
+ proc x2 {} {format 2}
+ proc x3 {} {format 3}
+ namespace ensemble create
+ }
+ list [catch {ns x} msg] $msg
+} -cleanup {
+ namespace delete ns
+} -result {1 {unknown or ambiguous subcommand "x": must be x1, x2, or x3}}
+test namespace-42.6 {ensembles: nested} -body {
+ namespace eval ns {
+ namespace export x*
+ namespace eval x0 {
+ proc z {} {format 0}
+ namespace export z
+ namespace ensemble create
+ }
+ proc x1 {} {format 1}
+ proc x2 {} {format 2}
+ proc x3 {} {format 3}
+ namespace ensemble create
+ }
+ list [ns x0 z] [ns x1] [ns x2] [ns x3]
+} -cleanup {
+ namespace delete ns
+} -result {0 1 2 3}
+test namespace-42.7 {ensembles: nested} -body {
+ namespace eval ns {
+ namespace export x*
+ namespace eval x0 {
+ proc z {} {list [info level] [info level 1]}
+ namespace export z
+ namespace ensemble create
+ }
+ proc x1 {} {format 1}
+ proc x2 {} {format 2}
+ proc x3 {} {format 3}
+ namespace ensemble create
+ }
+ list [ns x0 z] [ns x1] [ns x2] [ns x3]
+} -cleanup {
+ namespace delete ns
+} -result {{1 ::ns::x0::z} 1 2 3}
+test namespace-42.8 {ensembles: [Bug 1670091]} -setup {
+ proc demo args {}
+ variable target [list [namespace which demo] x]
+ proc trial args {variable target; string length $target}
+ trace add execution demo enter [namespace code trial]
+ namespace ensemble create -command foo -map [list bar $target]
+} -body {
+ foo bar
+} -cleanup {
+ unset target
+ rename demo {}
+ rename trial {}
+ rename foo {}
+} -result {}
+
+test namespace-43.1 {ensembles: dict-driven} {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {} {format 1}
+ proc x2 {} {format 2}
+ namespace ensemble create -map {a x1 b x2}
+ }
+ set result [list [catch {ns c} msg] $msg [namespace ensemble exists ns]]
+ rename ns {}
+ lappend result [namespace ensemble exists ns]
+} {1 {unknown or ambiguous subcommand "c": must be a, or b} 1 0}
+test namespace-43.2 {ensembles: dict-driven} -body {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {args} {list 1 $args}
+ proc x2 {args} {list 2 [llength $args]}
+ namespace ensemble create -map {
+ a ::ns::x1 b ::ns::x2 c {::ns::x1 .} d {::ns::x2 .}
+ }
+ }
+ list [ns a] [ns b] [ns c] [ns c foo] [ns d] [ns d foo]
+} -cleanup {
+ namespace delete ns
+} -result {{1 {}} {2 0} {1 .} {1 {. foo}} {2 1} {2 2}}
+set SETUP {
+ namespace eval ns {
+ namespace export a b
+ proc a args {format 1,[llength $args]}
+ proc b args {format 2,[llength $args]}
+ proc c args {format 3,[llength $args]}
+ proc d args {format 4,[llength $args]}
+ namespace ensemble create -subcommands {b c}
+ }
+}
+test namespace-43.3 {ensembles: list-driven} -setup $SETUP -body {
+ namespace delete ns
+} -result {}
+test namespace-43.4 {ensembles: list-driven} -setup $SETUP -body {
+ ns a foo bar boo spong wibble
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown or ambiguous subcommand "a": must be b, or c}
+test namespace-43.5 {ensembles: list-driven} -setup $SETUP -body {
+ ns b foo bar boo spong wibble
+} -cleanup {namespace delete ns} -result 2,5
+test namespace-43.6 {ensembles: list-driven} -setup $SETUP -body {
+ ns c foo bar boo spong wibble
+} -cleanup {namespace delete ns} -result 3,5
+test namespace-43.7 {ensembles: list-driven} -setup $SETUP -body {
+ ns d foo bar boo spong wibble
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown or ambiguous subcommand "d": must be b, or c}
+set SETUP {
+ namespace eval ns {
+ namespace export a b
+ proc a args {format 1,[llength $args]}
+ proc b args {format 2,[llength $args]}
+ proc c args {format 3,[llength $args]}
+ proc d args {format 4,[llength $args]}
+ namespace ensemble create -subcommands {b c} -map {c ::ns::d}
+ }
+}
+test namespace-43.8 {ensembles: list-and-map-driven} -setup $SETUP -body {
+ namespace delete ns
+} -result {}
+test namespace-43.9 {ensembles: list-and-map-driven} -setup $SETUP -body {
+ ns a foo bar boo spong wibble
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown or ambiguous subcommand "a": must be b, or c}
+test namespace-43.10 {ensembles: list-and-map-driven} -setup $SETUP -body {
+ ns b foo bar boo spong wibble
+} -cleanup {namespace delete ns} -result 2,5
+test namespace-43.11 {ensembles: list-and-map-driven} -setup $SETUP -body {
+ ns c foo bar boo spong wibble
+} -cleanup {namespace delete ns} -result 4,5
+test namespace-43.12 {ensembles: list-and-map-driven} -setup $SETUP -body {
+ ns d foo bar boo spong wibble
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown or ambiguous subcommand "d": must be b, or c}
+set SETUP {
+ namespace eval ns {
+ namespace export *
+ proc foo args {format bar}
+ proc spong args {format wibble}
+ namespace ensemble create -prefixes off
+ }
+}
+test namespace-43.13 {ensembles: turn off prefixes} -setup $SETUP -body {
+ namespace delete ns
+} -result {}
+test namespace-43.14 {ensembles: turn off prefixes} -setup $SETUP -body {
+ ns fo
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown subcommand "fo": must be foo, or spong}
+test namespace-43.15 {ensembles: turn off prefixes} -setup $SETUP -body {
+ ns foo
+} -cleanup {namespace delete ns} -result bar
+test namespace-43.16 {ensembles: turn off prefixes} -setup $SETUP -body {
+ ns s
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown subcommand "s": must be foo, or spong}
+test namespace-43.17 {ensembles: turn off prefixes} -setup $SETUP -body {
+ ns spong
+} -cleanup {namespace delete ns} -result wibble
+
+test namespace-44.1 {ensemble: errors} {
+ list [catch {namespace ensemble} msg] $msg
+} {1 {wrong # args: should be "namespace ensemble subcommand ?arg ...?"}}
+test namespace-44.2 {ensemble: errors} {
+ list [catch {namespace ensemble ?} msg] $msg
+} {1 {bad subcommand "?": must be configure, create, or exists}}
+test namespace-44.3 {ensemble: errors} {
+ namespace eval ns {
+ list [catch {namespace ensemble create -map x} msg] $msg
+ }
+} {1 {missing value to go with key}}
+test namespace-44.4 {ensemble: errors} {
+ namespace eval ns {
+ list [catch {namespace ensemble create -map {x {}}} msg] $msg
+ }
+} {1 {ensemble subcommand implementations must be non-empty lists}}
+test namespace-44.5 {ensemble: errors} -setup {
+ namespace ensemble create -command foobar -subcommands {foobarcget foobarconfigure}
+} -body {
+ foobar foobarcon
+} -cleanup {
+ rename foobar {}
+} -returnCodes error -result {invalid command name "::foobarconfigure"}
+test namespace-44.6 {ensemble: errors} -returnCodes error -body {
+ namespace ensemble create gorp
+} -result {wrong # args: should be "namespace ensemble create ?option value ...?"}
+
+test namespace-45.1 {ensemble: introspection} {
+ namespace eval ns {
+ namespace export x
+ proc x {} {}
+ namespace ensemble create
+ set ::result [namespace ensemble configure ::ns]
+ }
+ namespace delete ns
+ set result
+} {-map {} -namespace ::ns -parameters {} -prefixes 1 -subcommands {} -unknown {}}
+test namespace-45.2 {ensemble: introspection} {
+ namespace eval ns {
+ namespace export x
+ proc x {} {}
+ namespace ensemble create -map {A x}
+ set ::result [namespace ensemble configure ::ns -map]
+ }
+ namespace delete ns
+ set result
+} {A ::ns::x}
+
+test namespace-46.1 {ensemble: modification} {
+ namespace eval ns {
+ namespace export x
+ proc x {} {format 123}
+ # Ensemble maps A->x
+ namespace ensemble create -command ns -map {A ::ns::x}
+ set ::result [list [namespace ensemble configure ns -map] [ns A]]
+ # Ensemble maps B->x
+ namespace ensemble configure ns -map {B ::ns::x}
+ lappend ::result [namespace ensemble configure ns -map] [ns B]
+ # Ensemble maps x->x
+ namespace ensemble configure ns -map {}
+ lappend ::result [namespace ensemble configure ns -map] [ns x]
+ }
+ namespace delete ns
+ set result
+} {{A ::ns::x} 123 {B ::ns::x} 123 {} 123}
+test namespace-46.2 {ensemble: ensembles really use current export list} {
+ namespace eval ns {
+ namespace export x1
+ proc x1 {} {format 1}
+ proc x2 {} {format 1}
+ namespace ensemble create
+ }
+ catch {ns ?} msg; set result [list $msg]
+ namespace eval ns {namespace export x*}
+ catch {ns ?} msg; lappend result $msg
+ rename ns::x1 {}
+ catch {ns ?} msg; lappend result $msg
+ namespace delete ns
+ set result
+} {{unknown or ambiguous subcommand "?": must be x1} {unknown or ambiguous subcommand "?": must be x1, or x2} {unknown or ambiguous subcommand "?": must be x2}}
+test namespace-46.3 {ensemble: implementation errors} {
+ namespace eval ns {
+ variable count 0
+ namespace ensemble create -map {
+ a {::lappend ::result}
+ b {::incr ::ns::count}
+ }
+ }
+ set result {}
+ lappend result [catch { ns } msg] $msg
+ ns a [ns b 10]
+ catch {rename p {}}
+ rename ns p
+ p a [p b 3000]
+ lappend result $ns::count
+ namespace delete ns
+ lappend result [info command p]
+} {1 {wrong # args: should be "ns subcommand ?arg ...?"} 10 3010 3010 {}}
+test namespace-46.4 {ensemble: implementation errors} {
+ namespace eval ns {
+ namespace ensemble create
+ }
+ set result [info command ns]
+ lappend result [catch {ns ?} msg] $msg
+ namespace delete ns
+ set result
+} {ns 1 {unknown subcommand "?": namespace ::ns does not export any commands}}
+test namespace-46.5 {ensemble: implementation errors} {
+ namespace eval ns {
+ namespace ensemble create -map {makeError ::error}
+ }
+ list [catch {ns makeError "an error happened"} msg] $msg $::errorInfo [namespace delete ns]
+} {1 {an error happened} {an error happened
+ while executing
+"ns makeError "an error happened""} {}}
+test namespace-46.6 {ensemble: implementation renames/deletes itself} {
+ namespace eval ns {
+ namespace ensemble create -map {to ::rename}
+ }
+ ns to ns foo
+ foo to foo bar
+ bar to bar spong
+ spong to spong {}
+ namespace delete ns
+} {}
+test namespace-46.7 {ensemble: implementation deletes its namespace} {
+ namespace eval ns {
+ namespace ensemble create -map {kill {::namespace delete}}
+ }
+ ns kill ns
+} {}
+test namespace-46.8 {ensemble: implementation deletes its namespace} {
+ namespace eval ns {
+ namespace export *
+ proc foo {} {
+ variable x 1
+ bar
+ # Tricky; what is the correct return value anyway?
+ info exist x
+ }
+ proc bar {} {
+ namespace delete [namespace current]
+ }
+ namespace ensemble create
+ }
+ list [ns foo] [info exist ns::x]
+} {1 0}
+test namespace-46.9 {ensemble: configuring really configures things} {
+ namespace eval ns {
+ namespace ensemble create -map {a a} -prefixes 0
+ }
+ set result [list [catch {ns x} msg] $msg]
+ namespace ensemble configure ns -map {b b}
+ lappend result [catch {ns x} msg] $msg
+ namespace delete ns
+ set result
+} {1 {unknown subcommand "x": must be a} 1 {unknown subcommand "x": must be b}}
+
+test namespace-47.1 {ensemble: unknown handler} {
+ set log {}
+ namespace eval ns {
+ namespace export {[a-z]*}
+ proc Magic {ensemble subcmd args} {
+ global log
+ if {[string match {[a-z]*} $subcmd]} {
+ lappend log "making $subcmd"
+ proc $subcmd args {
+ global log
+ lappend log "running [info level 0]"
+ llength $args
+ }
+ } else {
+ lappend log "unknown $subcmd - args = $args"
+ return -code error \
+ "unknown or protected subcommand \"$subcmd\""
+ }
+ }
+ namespace ensemble create -unknown ::ns::Magic
+ }
+ set result {}
+ lappend result [catch {ns a b c} msg] $msg
+ lappend result [catch {ns a b c} msg] $msg
+ lappend result [catch {ns b c d} msg] $msg
+ lappend result [catch {ns c d e} msg] $msg
+ lappend result [catch {ns Magic foo bar spong wibble} msg] $msg
+ list $result [lsort [info commands ::ns::*]] $log [namespace delete ns]
+} {{0 2 0 2 0 2 0 2 1 {unknown or protected subcommand "Magic"}} {::ns::Magic ::ns::a ::ns::b ::ns::c} {{making a} {running ::ns::a b c} {running ::ns::a b c} {making b} {running ::ns::b c d} {making c} {running ::ns::c d e} {unknown Magic - args = foo bar spong wibble}} {}}
+test namespace-47.2 {ensemble: unknown handler} {
+ namespace eval ns {
+ namespace export {[a-z]*}
+ proc Magic {ensemble subcmd args} {
+ error foobar
+ }
+ namespace ensemble create -unknown ::ns::Magic
+ }
+ list [catch {ns spong} msg] $msg $::errorInfo [namespace delete ns]
+} {1 foobar {foobar
+ while executing
+"error foobar"
+ (procedure "::ns::Magic" line 2)
+ invoked from within
+"::ns::Magic ::ns spong"
+ (ensemble unknown subcommand handler)
+ invoked from within
+"ns spong"} {}}
+test namespace-47.3 {ensemble: unknown handler} {
+ namespace eval ns {
+ variable count 0
+ namespace export {[a-z]*}
+ proc a {} {}
+ proc c {} {}
+ proc Magic {ensemble subcmd args} {
+ variable count
+ incr count
+ proc b {} {}
+ }
+ namespace ensemble create -unknown ::ns::Magic
+ }
+ list [catch {ns spong} msg] $msg $ns::count [namespace delete ns]
+} {1 {unknown or ambiguous subcommand "spong": must be a, b, or c} 1 {}}
+test namespace-47.4 {ensemble: unknown handler} {
+ namespace eval ns {
+ namespace export {[a-z]*}
+ proc Magic {ensemble subcmd args} {
+ return -code break
+ }
+ namespace ensemble create -unknown ::ns::Magic
+ }
+ list [catch {ns spong} msg] $msg $::errorInfo [namespace delete ns]
+} {1 {unknown subcommand handler returned bad code: break} {unknown subcommand handler returned bad code: break
+ result of ensemble unknown subcommand handler: ::ns::Magic ::ns spong
+ invoked from within
+"ns spong"} {}}
+test namespace-47.5 {ensemble: unknown handler} {
+ namespace ensemble create -command foo -unknown bar
+ proc bar {args} {
+ global result target
+ lappend result "LOG $args"
+ return $target
+ }
+ set result {}
+ set target {}
+ lappend result [catch {foo bar} msg] $msg
+ set target {lappend result boo hoo}
+ lappend result [catch {foo bar} msg] $msg [namespace ensemble config foo]
+ rename foo {}
+ set result
+} {{LOG ::foo bar} 1 {unknown subcommand "bar": namespace :: does not export any commands} {LOG ::foo bar} boo hoo 0 {{LOG ::foo bar} 1 {unknown subcommand "bar": namespace :: does not export any commands} {LOG ::foo bar} boo hoo} {-map {} -namespace :: -parameters {} -prefixes 1 -subcommands {} -unknown bar}}
+test namespace-47.6 {ensemble: unknown handler} {
+ namespace ensemble create -command foo -unknown bar
+ proc bar {args} {
+ return "\{"
+ }
+ set result [list [catch {foo bar} msg] $msg $::errorInfo]
+ rename foo {}
+ set result
+} {1 {unmatched open brace in list} {unmatched open brace in list
+ while parsing result of ensemble unknown subcommand handler
+ invoked from within
+"foo bar"}}
+test namespace-47.7 {ensemble: unknown handler, commands with spaces} {
+ namespace ensemble create -command foo -unknown bar
+ proc bar {args} {
+ list ::set ::x [join $args |]
+ }
+ set result [foo {one two three}]
+ rename foo {}
+ set result
+} {::foo|one two three}
+test namespace-47.8 {ensemble: unknown handler, commands with spaces} {
+ namespace ensemble create -command foo -unknown {bar boo}
+ proc bar {args} {
+ list ::set ::x [join $args |]
+ }
+ set result [foo {one two three}]
+ rename foo {}
+ set result
+} {boo|::foo|one two three}
+
+test namespace-48.1 {ensembles and namespace import: unknown handler} {
+ namespace eval foo {
+ namespace export bar
+ namespace ensemble create -command bar -unknown ::foo::u -subcomm x
+ proc u {ens args} {
+ global result
+ lappend result $ens $args
+ namespace ensemble config $ens -subcommand {x y}
+ }
+ proc u2 {ens args} {
+ global result
+ lappend result $ens $args
+ namespace ensemble config ::bar -subcommand {x y z}
+ }
+ proc x args {
+ global result
+ lappend result XXX $args
+ }
+ proc y args {
+ global result
+ lappend result YYY $args
+ }
+ proc z args {
+ global result
+ lappend result ZZZ $args
+ }
+ }
+ namespace import -force foo::bar
+ set result [list [namespace ensemble config bar]]
+ bar x 123
+ bar y 456
+ namespace ensemble config bar -unknown ::foo::u2
+ bar z 789
+ namespace delete foo
+ set result
+} {{-map {} -namespace ::foo -parameters {} -prefixes 1 -subcommands x -unknown ::foo::u} XXX 123 ::foo::bar {y 456} YYY 456 ::foo::bar {z 789} ZZZ 789}
+test namespace-48.2 {ensembles and namespace import: exists} {
+ namespace eval foo {
+ namespace ensemble create -command ::foo::bar
+ namespace export bar
+ }
+ set result [namespace ensemble exist foo::bar]
+ lappend result [namespace ensemble exist bar]
+ namespace import foo::bar
+ lappend result [namespace ensemble exist bar]
+ rename foo::bar foo::bar2
+ lappend result [namespace ensemble exist bar] \
+ [namespace ensemble exist spong]
+ rename bar spong
+ lappend result [namespace ensemble exist bar] \
+ [namespace ensemble exist spong]
+ rename foo::bar2 {}
+ lappend result [namespace ensemble exist spong]
+ namespace delete foo
+ set result
+} {1 0 1 1 0 0 1 0}
+test namespace-48.3 {ensembles and namespace import: config} {
+ catch {rename spong {}}
+ namespace eval foo {
+ namespace ensemble create -command ::foo::bar
+ namespace export bar boo
+ proc boo {} {}
+ }
+ namespace import foo::bar foo::boo
+ set result [namespace ensemble config bar -namespace]
+ lappend result [catch {namespace ensemble config boo} msg] $msg
+ lappend result [catch {namespace ensemble config spong} msg] $msg
+ namespace delete foo
+ set result
+} {::foo 1 {"boo" is not an ensemble command} 1 {unknown command "spong"}}
+
+test namespace-49.1 {ensemble subcommand caching} -body {
+ namespace ens cre -command a -map {b {lappend result 1}}
+ namespace ens cre -command c -map {b {lappend result 2}}
+ proc x {} {a b; c b; a b; c b}
+ x
+} -result {1 2 1 2} -cleanup {
+ rename a {}
+ rename c {}
+ rename x {}
+}
+test namespace-49.2 {strange delete crash} -body {
+ namespace eval foo {namespace ensemble create -command ::bar}
+ trace add command ::bar delete DeleteTrace
+ proc DeleteTrace {old new op} {
+ trace remove command ::bar delete DeleteTrace
+ rename $old ""
+ # This next line caused a bus error in [Bug 1220058]
+ namespace delete foo
+ }
+ rename ::bar ""
+} -result "" -cleanup {
+ rename DeleteTrace ""
+}
+
+test namespace-50.1 {ensembles affect proc arguments error messages} -body {
+ namespace ens cre -command a -map {b {bb foo}}
+ proc bb {c d {e f} args} {list $c $args}
+ a b
+} -returnCodes error -result "wrong # args: should be \"a b d ?e? ?arg ...?\"" -cleanup {
+ rename a {}
+ rename bb {}
+}
+test namespace-50.2 {ensembles affect WrongNumArgs error messages} -body {
+ namespace ens cre -command a -map {b {string is}}
+ a b boolean
+} -returnCodes error -result "wrong # args: should be \"a b class ?-strict? ?-failindex var? str\"" -cleanup {
+ rename a {}
+}
+test namespace-50.3 {chained ensembles affect error messages} -body {
+ namespace ens cre -command a -map {b c}
+ namespace ens cre -command c -map {d e}
+ proc e f {}
+ a b d
+} -returnCodes error -result "wrong # args: should be \"a b d f\"" -cleanup {
+ rename a {}
+ rename c {}
+}
+test namespace-50.4 {chained ensembles affect error messages} -body {
+ namespace ens cre -command a -map {b {c d}}
+ namespace ens cre -command c -map {d {e f}}
+ proc e f {}
+ a b d
+} -returnCodes error -result "wrong # args: should be \"a b\"" -cleanup {
+ rename a {}
+ rename c {}
+}
+
+test namespace-51.1 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ namespace eval test_ns_2 {
+ proc pathtestA {} {
+ ::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+ }
+ proc pathtestC {} {
+ ::return 2
+ }
+ }
+ proc pathtestB {} {
+ return 1
+ }
+ proc pathtestC {} {
+ return 1
+ }
+ namespace path ::test_ns_1
+ }
+ proc ::pathtestB {} {
+ return global
+ }
+ proc ::pathtestD {} {
+ return global
+ }
+ test_ns_1::test_ns_2::pathtestA
+} -result "global,2,global," -cleanup {
+ namespace delete ::test_ns_1
+ catch {rename ::pathtestB {}}
+ catch {rename ::pathtestD {}}
+}
+test namespace-51.2 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ namespace eval test_ns_2 {
+ namespace path ::test_ns_1
+ proc pathtestA {} {
+ ::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+ }
+ proc pathtestC {} {
+ ::return 2
+ }
+ }
+ proc pathtestB {} {
+ return 1
+ }
+ proc pathtestC {} {
+ return 1
+ }
+ }
+ proc ::pathtestB {} {
+ return global
+ }
+ proc ::pathtestD {} {
+ return global
+ }
+ ::test_ns_1::test_ns_2::pathtestA
+} -result "1,2,global,::test_ns_1" -cleanup {
+ namespace delete ::test_ns_1
+ catch {rename ::pathtestB {}}
+ catch {rename ::pathtestD {}}
+}
+test namespace-51.3 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ namespace eval test_ns_2 {
+ proc pathtestA {} {
+ ::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+ }
+ proc pathtestC {} {
+ ::return 2
+ }
+ }
+ proc pathtestB {} {
+ return 1
+ }
+ proc pathtestC {} {
+ return 1
+ }
+ }
+ proc ::pathtestB {} {
+ return global
+ }
+ proc ::pathtestD {} {
+ return global
+ }
+ set result [::test_ns_1::test_ns_2::pathtestA]
+ namespace eval ::test_ns_1::test_ns_2 {
+ namespace path ::test_ns_1
+ }
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+ rename ::test_ns_1::pathtestB {}
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+} -result "global,2,global, 1,2,global,::test_ns_1 global,2,global,::test_ns_1" -cleanup {
+ namespace delete ::test_ns_1
+ catch {rename ::pathtestB {}}
+ catch {rename ::pathtestD {}}
+}
+test namespace-51.4 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ namespace eval test_ns_2 {
+ proc pathtestA {} {
+ ::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+ }
+ proc pathtestC {} {
+ ::return 2
+ }
+ }
+ proc pathtestB {} {
+ return 1
+ }
+ proc pathtestC {} {
+ return 1
+ }
+ }
+ proc ::pathtestB {} {
+ return global
+ }
+ proc ::pathtestD {} {
+ return global
+ }
+ set result [::test_ns_1::test_ns_2::pathtestA]
+ namespace eval ::test_ns_1::test_ns_2 {
+ namespace path ::test_ns_1
+ }
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+ namespace eval ::test_ns_1::test_ns_2 {
+ namespace path {}
+ }
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+} -result "global,2,global, 1,2,global,::test_ns_1 global,2,global," -cleanup {
+ namespace delete ::test_ns_1
+ catch {rename ::pathtestB {}}
+ catch {rename ::pathtestD {}}
+}
+test namespace-51.5 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ namespace eval test_ns_2 {
+ proc pathtestA {} {
+ ::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+ }
+ proc pathtestC {} {
+ ::return 2
+ }
+ namespace path ::test_ns_1
+ }
+ proc pathtestB {} {
+ return 1
+ }
+ proc pathtestC {} {
+ return 1
+ }
+ proc pathtestD {} {
+ return 1
+ }
+ }
+ proc ::pathtestB {} {
+ return global
+ }
+ proc ::pathtestD {} {
+ return global
+ }
+ set result [::test_ns_1::test_ns_2::pathtestA]
+ namespace eval ::test_ns_1::test_ns_2 {
+ namespace path {:: ::test_ns_1}
+ }
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+ rename ::test_ns_1::test_ns_2::pathtestC {}
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+} -result "1,2,1,::test_ns_1 {global,2,global,:: ::test_ns_1} {global,1,global,:: ::test_ns_1}" -cleanup {
+ namespace delete ::test_ns_1
+ catch {rename ::pathtestB {}}
+ catch {rename ::pathtestD {}}
+}
+test namespace-51.6 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ namespace eval test_ns_2 {
+ proc pathtestA {} {
+ ::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+ }
+ proc pathtestC {} {
+ ::return 2
+ }
+ namespace path ::test_ns_1
+ }
+ proc pathtestB {} {
+ return 1
+ }
+ proc pathtestC {} {
+ return 1
+ }
+ proc pathtestD {} {
+ return 1
+ }
+ }
+ proc ::pathtestB {} {
+ return global
+ }
+ proc ::pathtestD {} {
+ return global
+ }
+ set result [::test_ns_1::test_ns_2::pathtestA]
+ namespace eval ::test_ns_1::test_ns_2 {
+ namespace path {:: ::test_ns_1}
+ }
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+ rename ::test_ns_1::test_ns_2::pathtestC {}
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+ proc ::pathtestC {} {
+ return global
+ }
+ lappend result [::test_ns_1::test_ns_2::pathtestA]
+} -result "1,2,1,::test_ns_1 {global,2,global,:: ::test_ns_1} {global,1,global,:: ::test_ns_1} {global,global,global,:: ::test_ns_1}" -cleanup {
+ namespace delete ::test_ns_1
+ catch {rename ::pathtestB {}}
+ catch {rename ::pathtestD {}}
+}
+test namespace-51.7 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ }
+ namespace eval ::test_ns_2 {
+ namespace path ::test_ns_1
+ proc getpath {} {namespace path}
+ }
+ list [::test_ns_2::getpath] [namespace delete ::test_ns_1] [::test_ns_2::getpath]
+} -result {::test_ns_1 {} {}} -cleanup {
+ catch {namespace delete ::test_ns_1}
+ namespace delete ::test_ns_2
+}
+test namespace-51.8 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ }
+ namespace eval ::test_ns_2 {
+ }
+ namespace eval ::test_ns_3 {
+ }
+ namespace eval ::test_ns_4 {
+ namespace path {::test_ns_1 ::test_ns_2 ::test_ns_3}
+ proc getpath {} {namespace path}
+ }
+ list [::test_ns_4::getpath] [namespace delete ::test_ns_2] [::test_ns_4::getpath]
+} -result {{::test_ns_1 ::test_ns_2 ::test_ns_3} {} {::test_ns_1 ::test_ns_3}} -cleanup {
+ catch {namespace delete ::test_ns_1}
+ catch {namespace delete ::test_ns_2}
+ catch {namespace delete ::test_ns_3}
+ catch {namespace delete ::test_ns_4}
+}
+test namespace-51.9 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ }
+ namespace eval ::test_ns_2 {
+ }
+ namespace eval ::test_ns_3 {
+ }
+ namespace eval ::test_ns_4 {
+ namespace path {::test_ns_1 ::test_ns_2 ::test_ns_3}
+ proc getpath {} {namespace path}
+ }
+ list [::test_ns_4::getpath] [namespace delete ::test_ns_2] [namespace eval ::test_ns_2 {}] [::test_ns_4::getpath]
+} -result {{::test_ns_1 ::test_ns_2 ::test_ns_3} {} {} {::test_ns_1 ::test_ns_3}} -cleanup {
+ catch {namespace delete ::test_ns_1}
+ catch {namespace delete ::test_ns_2}
+ catch {namespace delete ::test_ns_3}
+ catch {namespace delete ::test_ns_4}
+}
+test namespace-51.10 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ namespace path does::not::exist
+ }
+} -returnCodes error -result {namespace "does::not::exist" not found in "::test_ns_1"} -cleanup {
+ catch {namespace delete ::test_ns_1}
+}
+test namespace-51.11 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ proc foo {} {return 1}
+ }
+ namespace eval ::test_ns_2 {
+ proc foo {} {return 2}
+ }
+ namespace eval ::test_ns_3 {
+ namespace path ::test_ns_1
+ }
+ namespace eval ::test_ns_4 {
+ namespace path {::test_ns_3 ::test_ns_2}
+ foo
+ }
+} -result 2 -cleanup {
+ catch {namespace delete ::test_ns_1}
+ catch {namespace delete ::test_ns_2}
+ catch {namespace delete ::test_ns_3}
+ catch {namespace delete ::test_ns_4}
+}
+test namespace-51.12 {name resolution path control} -body {
+ namespace eval ::test_ns_1 {
+ proc foo {} {return 1}
+ }
+ namespace eval ::test_ns_2 {
+ proc foo {} {return 2}
+ }
+ namespace eval ::test_ns_3 {
+ namespace path ::test_ns_1
+ }
+ namespace eval ::test_ns_4 {
+ namespace path {::test_ns_3 ::test_ns_2}
+ list [foo] [namespace delete ::test_ns_3] [foo]
+ }
+} -result {2 {} 2} -cleanup {
+ catch {namespace delete ::test_ns_1}
+ catch {namespace delete ::test_ns_2}
+ catch {namespace delete ::test_ns_3}
+ catch {namespace delete ::test_ns_4}
+}
+test namespace-51.13 {name resolution path control} -body {
+ set ::result {}
+ namespace eval ::test_ns_1 {
+ proc foo {} {lappend ::result 1}
+ }
+ namespace eval ::test_ns_2 {
+ proc foo {} {lappend ::result 2}
+ trace add command foo delete "namespace eval ::test_ns_3 foo;#"
+ }
+ namespace eval ::test_ns_3 {
+ proc foo {} {
+ lappend ::result 3
+ namespace delete [namespace current]
+ ::test_ns_4::bar
+ }
+ }
+ namespace eval ::test_ns_4 {
+ namespace path {::test_ns_2 ::test_ns_3 ::test_ns_1}
+ proc bar {} {
+ list [foo] [namespace delete ::test_ns_2] [foo]
+ }
+ bar
+ }
+ # Should the result be "2 {} {2 3 2 1}" instead?
+} -result {2 {} {2 3 1 1}} -cleanup {
+ catch {namespace delete ::test_ns_1}
+ catch {namespace delete ::test_ns_2}
+ catch {namespace delete ::test_ns_3}
+ catch {namespace delete ::test_ns_4}
+}
+test namespace-51.14 {name resolution path control} -setup {
+ foreach cmd [info commands foo*] {
+ rename $cmd {}
+ }
+ namespace eval ::test_ns_1 {}
+ namespace eval ::test_ns_2 {}
+ namespace eval ::test_ns_3 {}
+} -body {
+ proc foo0 {} {}
+ proc ::test_ns_1::foo1 {} {}
+ proc ::test_ns_2::foo2 {} {}
+ namespace eval ::test_ns_3 {
+ variable result {}
+ lappend result [info commands foo*]
+ namespace path {::test_ns_1 ::test_ns_2}
+ lappend result [info commands foo*]
+ proc foo2 {} {}
+ lappend result [info commands foo*]
+ rename foo2 {}
+ lappend result [info commands foo*]
+ namespace delete ::test_ns_1
+ lappend result [info commands foo*]
+ }
+} -cleanup {
+ catch {namespace delete ::test_ns_1}
+ catch {namespace delete ::test_ns_2}
+ catch {namespace delete ::test_ns_3}
+} -result {foo0 {foo1 foo2 foo0} {foo2 foo1 foo0} {foo1 foo2 foo0} {foo2 foo0}}
+test namespace-51.15 {namespace resolution path control} -body {
+ namespace eval ::test_ns_2 {
+ proc foo {} {return 2}
+ }
+ namespace eval ::test_ns_1 {
+ namespace eval test_ns_2 {
+ proc foo {} {return 1_2}
+ }
+ namespace eval test_ns_3 {
+ namespace path ::test_ns_1
+ test_ns_2::foo
+ }
+ }
+} -result 1_2 -cleanup {
+ namespace delete ::test_ns_1
+ namespace delete ::test_ns_2
+}
+test namespace-51.16 {Bug 1566526} {
+ interp create slave
+ slave eval namespace eval demo namespace path ::
+ interp delete slave
+} {}
+test namespace-51.17 {resolution epoch handling: Bug 2898722} -setup {
+ set result {}
+ catch {namespace delete ::a}
+} -body {
+ namespace eval ::a {
+ proc c {} {lappend ::result A}
+ c
+ namespace eval b {
+ variable d c
+ lappend ::result [catch { $d }]
+ }
+ lappend ::result .
+ namespace eval b {
+ namespace path [namespace parent]
+ $d;[format %c 99]
+ }
+ lappend ::result .
+ namespace eval b {
+ proc c {} {lappend ::result B}
+ $d;[format %c 99]
+ }
+ lappend ::result .
+ }
+ namespace eval ::a::b {
+ $d;[format %c 99]
+ lappend ::result .
+ proc ::c {} {lappend ::result G}
+ $d;[format %c 99]
+ lappend ::result .
+ rename ::a::c {}
+ $d;[format %c 99]
+ lappend ::result .
+ rename ::a::b::c {}
+ $d;[format %c 99]
+ }
+} -cleanup {
+ namespace delete ::a
+ catch {rename ::c {}}
+ unset result
+} -result {A 1 . A A . B B . B B . B B . B B . G G}
+test namespace-51.18 {Bug 3185407} -setup {
+ namespace eval ::test_ns_1 {}
+} -body {
+ namespace eval ::test_ns_1 {
+ variable result {}
+ namespace eval ns {proc foo {} {}}
+ namespace eval ns2 {proc foo {} {}}
+ namespace path {ns ns2}
+ variable x foo
+ lappend result [namespace which $x]
+ proc foo {} {}
+ lappend result [namespace which $x]
+ }
+} -cleanup {
+ namespace delete ::test_ns_1
+} -result {::test_ns_1::ns::foo ::test_ns_1::foo}
+
+# TIP 181 - namespace unknown tests
+test namespace-52.1 {unknown: default handler ::unknown} {
+ set result [list [namespace eval foobar { namespace unknown }]]
+ lappend result [namespace eval :: { namespace unknown }]
+ namespace delete foobar
+ set result
+} {{} ::unknown}
+test namespace-52.2 {unknown: default resolution global} {
+ proc ::foo {} { return "GLOBAL" }
+ namespace eval ::bar { proc foo {} { return "NAMESPACE" } }
+ namespace eval ::bar::jim { proc test {} { foo } }
+ set result [::bar::jim::test]
+ namespace delete ::bar
+ rename ::foo {}
+ set result
+} {GLOBAL}
+test namespace-52.3 {unknown: default resolution local} {
+ proc ::foo {} { return "GLOBAL" }
+ namespace eval ::bar {
+ proc foo {} { return "NAMESPACE" }
+ proc test {} { foo }
+ }
+ set result [::bar::test]
+ namespace delete ::bar
+ rename ::foo {}
+ set result
+} {NAMESPACE}
+test namespace-52.4 {unknown: set handler} {
+ namespace eval foo {
+ namespace unknown [list dispatch]
+ proc dispatch {args} { return $args }
+ proc test {} {
+ UnknownCmd a b c
+ }
+ }
+ set result [foo::test]
+ namespace delete foo
+ set result
+} {UnknownCmd a b c}
+test namespace-52.5 {unknown: search path before unknown is unaltered} {
+ proc ::test2 {args} { return "TEST2: $args" }
+ namespace eval foo {
+ namespace unknown [list dispatch]
+ proc dispatch {args} { return "UNKNOWN: $args" }
+ proc test1 {args} { return "TEST1: $args" }
+ proc test {} {
+ set result [list [test1 a b c]]
+ lappend result [test2 a b c]
+ lappend result [test3 a b c]
+ return $result
+ }
+ }
+ set result [foo::test]
+ namespace delete foo
+ rename ::test2 {}
+ set result
+} {{TEST1: a b c} {TEST2: a b c} {UNKNOWN: test3 a b c}}
+test namespace-52.6 {unknown: deleting handler restores default} {
+ rename ::unknown ::_unknown_orig
+ proc ::unknown {args} { return "DEFAULT: $args" }
+ namespace eval foo {
+ namespace unknown dummy
+ namespace unknown {}
+ }
+ set result [namespace eval foo { dummy a b c }]
+ rename ::unknown {}
+ rename ::_unknown_orig ::unknown
+ namespace delete foo
+ set result
+} {DEFAULT: dummy a b c}
+test namespace-52.7 {unknown: setting global unknown handler} {
+ proc ::myunknown {args} { return "MYUNKNOWN: $args" }
+ namespace eval :: { namespace unknown ::myunknown }
+ set result [namespace eval foo { dummy a b c }]
+ namespace eval :: { namespace unknown {} }
+ rename ::myunknown {}
+ namespace delete foo
+ set result
+} {MYUNKNOWN: dummy a b c}
+test namespace-52.8 {unknown: destroying and redefining global namespace} {
+ set i [interp create]
+ $i hide proc
+ $i hide namespace
+ $i hide return
+ $i invokehidden namespace delete ::
+ $i expose return
+ $i invokehidden proc unknown args { return "FINE" }
+ $i eval { foo bar bob }
+} {FINE}
+test namespace-52.9 {unknown: refcounting} -setup {
+ proc this args {
+ unset args ;# stop sharing
+ set copy [namespace unknown]
+ string length $copy ;# shimmer away list rep
+ info level 0
+ }
+ set handler [namespace unknown]
+ namespace unknown {this is a test}
+ catch {rename noSuchCommand {}}
+} -body {
+ noSuchCommand
+} -cleanup {
+ namespace unknown $handler
+ rename this {}
+} -result {this is a test noSuchCommand}
+testConstraint testevalobjv [llength [info commands testevalobjv]]
+test namespace-52.10 {unknown: with TCL_EVAL_GLOBAL} -constraints {
+ testevalobjv
+} -setup {
+ rename ::unknown unknown.save
+ proc ::unknown args {
+ set caller [uplevel 1 {namespace current}]
+ namespace eval $caller {
+ variable foo
+ return $foo
+ }
+ }
+ catch {rename ::noSuchCommand {}}
+} -body {
+ namespace eval :: {
+ variable foo SUCCESS
+ }
+ namespace eval test_ns_1 {
+ variable foo FAIL
+ testevalobjv 1 noSuchCommand
+ }
+} -cleanup {
+ unset -nocomplain ::foo
+ namespace delete test_ns_1
+ rename ::unknown {}
+ rename unknown.save ::unknown
+} -result SUCCESS
+test namespace-52.11 {unknown: with TCL_EVAL_INVOKE} -setup {
+ set handler [namespace eval :: {namespace unknown}]
+ namespace eval :: {namespace unknown unknown}
+ rename ::unknown unknown.save
+ namespace eval :: {
+ proc unknown args {
+ return SUCCESS
+ }
+ }
+ catch {rename ::noSuchCommand {}}
+ set ::slave [interp create]
+} -body {
+ $::slave alias bar noSuchCommand
+ namespace eval test_ns_1 {
+ namespace unknown unknown
+ proc unknown args {
+ return FAIL
+ }
+ $::slave eval bar
+ }
+} -cleanup {
+ interp delete $::slave
+ unset ::slave
+ namespace delete test_ns_1
+ rename ::unknown {}
+ rename unknown.save ::unknown
+ namespace eval :: [list namespace unknown $handler]
+} -result SUCCESS
+test namespace-52.12 {unknown: error case must not reset handler} -body {
+ namespace eval foo {
+ namespace unknown ok
+ catch {namespace unknown {{}{}{}}}
+ namespace unknown
+ }
+} -cleanup {
+ namespace delete foo
+} -result ok
+
+# TIP 314 - ensembles with parameters
+test namespace-53.1 {ensembles: parameters} {
+ namespace eval ns {
+ namespace export x
+ proc x {para} {list 1 $para}
+ namespace ensemble create -parameters {para1}
+ }
+ list [info command ns] [ns bar x] [namespace delete ns] [info command ns]
+} {ns {1 bar} {} {}}
+test namespace-53.2 {ensembles: parameters} -setup {
+ namespace eval ns {
+ namespace export x
+ proc x {para} {list 1 $para}
+ namespace ensemble create
+ }
+} -body {
+ namespace ensemble configure ns -parameters {para1}
+ rename ns foo
+ list [info command foo] [foo bar x] [namespace delete ns] [info command foo]
+} -result {foo {1 bar} {} {}}
+test namespace-53.3 {ensembles: parameters} -setup {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {para} {list 1 $para}
+ proc x2 {para} {list 2 $para}
+ namespace ensemble create -parameters param1
+ }
+} -body {
+ set result [list [ns x2 x1] [ns x1 x2]]
+ lappend result [catch {ns x} msg] $msg
+ lappend result [catch {ns x x} msg] $msg
+ rename ns {}
+ lappend result [info command ns::x1]
+ namespace delete ns
+ lappend result [info command ns::x1]
+} -result\
+ {{1 x2} {2 x1}\
+ 1 {wrong # args: should be "ns param1 subcommand ?arg ...?"}\
+ 1 {unknown or ambiguous subcommand "x": must be x1, or x2}\
+ ::ns::x1 {}}
+test namespace-53.4 {ensembles: parameters} -setup {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {a1 a2} {list 1 $a1 $a2}
+ proc x2 {a1 a2} {list 2 $a1 $a2}
+ proc x3 {a1 a2} {list 3 $a1 $a2}
+ namespace ensemble create
+ }
+} -body {
+ set result {}
+ lappend result [ns x1 x2 x3]
+ namespace ensemble configure ns -parameters p1
+ lappend result [ns x1 x2 x3]
+ namespace ensemble configure ns -parameters {p1 p2}
+ lappend result [ns x1 x2 x3]
+} -cleanup {
+ namespace delete ns
+} -result {{1 x2 x3} {2 x1 x3} {3 x1 x2}}
+test namespace-53.5 {ensembles: parameters} -setup {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {para} {list 1 $para}
+ proc x2 {para} {list 2 $para}
+ proc x3 {para} {list 3 $para}
+ namespace ensemble create
+ }
+} -body {
+ set result [list [catch {ns x x1} msg] $msg]
+ lappend result [catch {ns x1 x} msg] $msg
+ namespace ensemble configure ns -parameters p1
+ lappend result [catch {ns x1 x} msg] $msg
+ lappend result [catch {ns x x1} msg] $msg
+} -cleanup {
+ namespace delete ns
+} -result\
+ {1 {unknown or ambiguous subcommand "x": must be x1, x2, or x3}\
+ 0 {1 x}\
+ 1 {unknown or ambiguous subcommand "x": must be x1, x2, or x3}\
+ 0 {1 x}}
+test namespace-53.6 {ensembles: nested} -setup {
+ namespace eval ns {
+ namespace export x*
+ namespace eval x0 {
+ proc z {args} {list 0 $args}
+ namespace export z
+ namespace ensemble create
+ }
+ proc x1 {args} {list 1 $args}
+ proc x2 {args} {list 2 $args}
+ proc x3 {args} {list 3 $args}
+ namespace ensemble create -parameters p
+ }
+} -body {
+ list [ns z x0] [ns z x1] [ns z x2] [ns z x3]
+} -cleanup {
+ namespace delete ns
+} -result {{0 {}} {1 z} {2 z} {3 z}}
+test namespace-53.7 {ensembles: parameters & wrong # args} -setup {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {a1 a2 a3 a4} {list x1 $a1 $a2 $a3 $a4}
+ namespace ensemble create -parameters p1
+ }
+} -body {
+ set result {}
+ lappend result [catch {ns} msg] $msg
+ lappend result [catch {ns x1} msg] $msg
+ lappend result [catch {ns x1 x1} msg] $msg
+ lappend result [catch {ns x1 x1 x1} msg] $msg
+ lappend result [catch {ns x1 x1 x1 x1} msg] $msg
+ lappend result [catch {ns x1 x1 x1 x1 x1} msg] $msg
+} -cleanup {
+ namespace delete ns
+} -result\
+ {1 {wrong # args: should be "ns p1 subcommand ?arg ...?"}\
+ 1 {wrong # args: should be "ns p1 subcommand ?arg ...?"}\
+ 1 {wrong # args: should be "ns x1 x1 a2 a3 a4"}\
+ 1 {wrong # args: should be "ns x1 x1 a2 a3 a4"}\
+ 1 {wrong # args: should be "ns x1 x1 a2 a3 a4"}\
+ 0 {x1 x1 x1 x1 x1}}
+test namespace-53.8 {ensemble: unknown handler changing -parameters} -setup {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {a1} {list 1 $a1}
+ proc Magic {ensemble subcmd args} {
+ namespace ensemble configure $ensemble\
+ -parameters [lrange p1 [llength [
+ namespace ensemble configure $ensemble -parameters
+ ]] 0]
+ list
+ }
+ namespace ensemble create -unknown ::ns::Magic
+ }
+} -body {
+ set result {}
+ lappend result [catch {ns x1 x2} msg] $msg [namespace ensemble configure ns -parameters]
+ lappend result [catch {ns x2 x1} msg] $msg [namespace ensemble configure ns -parameters]
+ lappend result [catch {ns x2 x3} msg] $msg [namespace ensemble configure ns -parameters]
+} -cleanup {
+ namespace delete ns
+} -result\
+ {0 {1 x2} {}\
+ 0 {1 x2} p1\
+ 1 {unknown or ambiguous subcommand "x2": must be x1} {}}
+test namespace-53.9 {ensemble: unknown handler changing -parameters,\
+ thereby eating all args} -setup {
+ namespace eval ns {
+ namespace export x*
+ proc x1 {args} {list 1 $args}
+ proc Magic {ensemble subcmd args} {
+ namespace ensemble configure $ensemble\
+ -parameters {p1 p2 p3 p4 p5}
+ list
+ }
+ namespace ensemble create -unknown ::ns::Magic
+ }
+} -body {
+ set result {}
+ lappend result [catch {ns x1 x2} msg] $msg [namespace ensemble configure ns -parameters]
+ lappend result [catch {ns x2 x1} msg] $msg [namespace ensemble configure ns -parameters]
+ lappend result [catch {ns a1 a2 a3 a4 a5 x1} msg] $msg [namespace ensemble configure ns -parameters]
+} -cleanup {
+ namespace delete ns
+} -result\
+ {0 {1 x2} {}\
+ 1 {wrong # args: should be "ns p1 p2 p3 p4 p5 subcommand ?arg ...?"} {p1 p2 p3 p4 p5}\
+ 0 {1 {a1 a2 a3 a4 a5}} {p1 p2 p3 p4 p5}}
+test namespace-53.10 {ensembles: nested rewrite} -setup {
+ namespace eval ns {
+ namespace export x
+ namespace eval x {
+ proc z0 {} {list 0}
+ proc z1 {a1} {list 1 $a1}
+ proc z2 {a1 a2} {list 2 $a1 $a2}
+ proc z3 {a1 a2 a3} {list 3 $a1 $a2 $a3}
+ namespace export z*
+ namespace ensemble create
+ }
+ namespace ensemble create -parameters p
+ }
+} -body {
+ set result {}
+ # In these cases, parsing the subensemble does not grab a new word.
+ lappend result [catch {ns z0 x} msg] $msg
+ lappend result [catch {ns z1 x} msg] $msg
+ lappend result [catch {ns z2 x} msg] $msg
+ lappend result [catch {ns z2 x v} msg] $msg
+ namespace ensemble configure ns::x -parameters q1
+ # In these cases, parsing the subensemble grabs a new word.
+ lappend result [catch {ns v x z0} msg] $msg
+ lappend result [catch {ns v x z1} msg] $msg
+ lappend result [catch {ns v x z2} msg] $msg
+ lappend result [catch {ns v x z2 v2} msg] $msg
+} -cleanup {
+ namespace delete ns
+} -result\
+ {0 0\
+ 1 {wrong # args: should be "ns z1 x a1"}\
+ 1 {wrong # args: should be "ns z2 x a1 a2"}\
+ 1 {wrong # args: should be "ns z2 x a1 a2"}\
+ 1 {wrong # args: should be "::ns::x::z0"}\
+ 0 {1 v}\
+ 1 {wrong # args: should be "ns v x z2 a2"}\
+ 0 {2 v v2}}
+
+test namespace-54.1 {leak on namespace deletion} -constraints {memory} \
+-setup {
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex $lines 3 3
+ }
+} -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ set ns ::y$i
+ namespace eval $ns {}
+ namespace delete $ns
+ set start $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $start}]
+} -cleanup {
+ rename getbytes {}
+ unset i ns start end
+} -result 0
+
+# cleanup
+catch {rename cmd1 {}}
+catch {unset l}
+catch {unset msg}
+catch {unset trigger}
+namespace delete {*}[namespace children :: test_ns_*]
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/notify.test b/pkgs/msgcat/tests/notify.test
new file mode 100755
index 0000000..ba52c50
--- /dev/null
+++ b/pkgs/msgcat/tests/notify.test
@@ -0,0 +1,324 @@
+# -*- tcl -*-
+#
+# notify.test --
+#
+# This file tests several functions in the file, 'generic/tclNotify.c'.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 2003 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testevent [llength [info commands testevent]]
+
+test notify-1.1 {Tcl_QueueEvent and delivery of a single event} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result {one}
+
+test notify-1.2 {Tcl_QueueEvent and delivery of events in order} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent queue two tail {lappend delivered two; expr 1}
+ testevent queue three tail {lappend delivered three; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result {one two three}
+
+test notify-1.3 {Tcl_QueueEvent at head} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one head {lappend delivered one; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result one
+
+test notify-1.4 {Tcl_QueueEvent multiple events at head} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one head {lappend delivered one; expr 1}
+ testevent queue two head {lappend delivered two; expr 1}
+ testevent queue three head {lappend delivered three; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result {three two one}
+
+test notify-1.5 {Tcl_QueueEvent marker event into an empty queue} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result one
+
+test notify-1.6 {Tcl_QueueEvent first marker event in a nonempty queue} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent queue two mark {lappend delivered two; expr 1}
+ testevent queue three head {lappend delivered three; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result {three two one}
+
+test notify-1.7 {Tcl_QueueEvent second marker event} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent queue two mark {lappend delivered two; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result {one two}
+
+test notify-1.8 {Tcl_QueueEvent preexisting event following second marker} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent queue two tail {lappend delivered two; expr 1}
+ testevent queue three mark {lappend delivered three; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result {one three two}
+
+test notify-2.1 {remove sole element, don't replace } \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent delete one
+ vwait done
+ set delivered
+ } \
+ -result {}
+
+test notify-2.2 {remove and replace sole element} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent delete one
+ testevent queue two tail {lappend delivered two; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result two
+
+test notify-2.3 {remove first element} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent queue two tail {lappend delivered two; expr 1}
+ testevent delete one
+ vwait done
+ set delivered
+ } \
+ -result {two}
+
+test notify-2.4 {remove and replace first element} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent queue two tail {lappend delivered two; expr 1}
+ testevent delete one
+ testevent queue three head {lappend delivered three; expr 1};
+ vwait done
+ set delivered
+ } \
+ -result {three two}
+
+test notify-2.5 {remove last element} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent queue two tail {lappend delivered two; expr 1}
+ testevent delete two
+ vwait done
+ set delivered
+ } \
+ -result {one}
+
+
+test notify-2.6 {remove and replace last element} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent queue two tail {lappend delivered two; expr 1}
+ testevent delete two
+ testevent queue three tail {lappend delivered three; expr 1};
+ vwait done
+ set delivered
+ } \
+ -result {one three}
+
+test notify-2.7 {remove a middle element} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one tail {lappend delivered one; expr 1}
+ testevent queue two tail {lappend delivered two; expr 1}
+ testevent queue three tail {lappend delivered three; expr 1}
+ testevent delete two
+ vwait done
+ set delivered
+ } \
+ -result {one three}
+
+test notify-2.8 {remove a marker event that's the sole event in the queue} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent delete one
+ vwait done
+ set delivered
+ } \
+ -result {}
+
+test notify-2.9 {remove and replace a marker event that's the sole event} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent delete one
+ testevent queue two mark {lappend delivered two; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result two
+
+test notify-2.10 {remove marker event from head} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent queue two mark {lappend delivered two; expr 1}
+ testevent delete one
+ vwait done
+ set delivered
+ } \
+ -result two
+
+test notify-2.11 {remove and replace marker event at head} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent queue two tail {lappend delivered two; expr 1}
+ testevent delete one
+ testevent queue three mark {lappend delivered three; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result {three two}
+
+test notify-2.12 {remove marker event at tail} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent queue two mark {lappend delivered two; expr 1}
+ testevent delete two
+ vwait done
+ set delivered
+ } \
+ -result {one}
+
+test notify-2.13 {remove and replace marker event at tail} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent queue two mark {lappend delivered two; expr 1}
+ testevent delete two
+ testevent queue three mark {lappend delivered three; expr 1}
+ vwait done
+ set delivered
+ } \
+ -result {one three}
+
+test notify-2.14 {remove marker event from middle} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent queue two mark {lappend delivered two; expr 1}
+ testevent queue three mark {lappend delivered three; expr 1}
+ testevent delete two
+ vwait done
+ set delivered
+ } \
+ -result {one three}
+
+test notify-2.15 {remove and replace marker event at middle} \
+ -constraints {testevent} \
+ -body {
+ set delivered {}
+ after 10 set done 1
+ testevent queue one mark {lappend delivered one; expr 1}
+ testevent queue two mark {lappend delivered two; expr 1}
+ testevent queue three tail {lappend delivered three; expr 1}
+ testevent delete two
+ testevent queue four mark {lappend delivered four; expr 1};
+ vwait done
+ set delivered
+ } \
+ -result {one four three}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/nre.test b/pkgs/msgcat/tests/nre.test
new file mode 100644
index 0000000..295f02e
--- /dev/null
+++ b/pkgs/msgcat/tests/nre.test
@@ -0,0 +1,445 @@
+# Commands covered: proc, apply, [interp alias], [namespce import]
+#
+# This file contains a collection of tests for the non-recursive executor that
+# avoids recursive calls to TEBC. Only the NRE behaviour is tested here, the
+# actual command functionality is tested in the specific test file.
+#
+# Copyright (c) 2008 by Miguel Sofer.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testnrelevels [llength [info commands testnrelevels]]
+
+#
+# The tests that risked blowing the C stack on failure have been removed: we
+# can now actually measure using testnrelevels.
+#
+
+if {[testConstraint testnrelevels]} {
+ namespace eval testnre {
+ namespace path ::tcl::mathop
+ #
+ # [testnrelevels] returns a 6-list with: C-stack depth, iPtr->numlevels,
+ # cmdFrame level, callFrame level, tosPtr and callback depth
+ #
+ variable last [testnrelevels]
+ proc depthDiff {} {
+ variable last
+ set depth [testnrelevels]
+ set res {}
+ foreach t $depth l $last {
+ lappend res [expr {$t-$l}]
+ }
+ set last $depth
+ return $res
+ }
+ proc setabs {} {
+ variable abs [- [lindex [testnrelevels] 0]]
+ }
+
+ variable body0 {
+ set x [depthDiff]
+ if {[incr i] > 10} {
+ namespace upvar [namespace qualifiers \
+ [namespace origin depthDiff]] abs abs
+ incr abs [lindex [testnrelevels] 0]
+ return [list [lrange $x 0 3] $abs]
+ }
+ }
+ proc makebody txt {
+ variable body0
+ return "$body0; $txt"
+ }
+ namespace export *
+ }
+ namespace import testnre::*
+}
+
+test nre-1.1 {self-recursive procs} -setup {
+ proc a i [makebody {a $i}]
+} -body {
+ setabs
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 1 1 1} 0}
+
+test nre-1.2 {self-recursive lambdas} -setup {
+ set a [list i [makebody {apply $::a $i}]]
+} -body {
+ setabs
+ apply $a 0
+} -cleanup {
+ unset a
+} -constraints {
+ testnrelevels
+} -result {{0 1 1 1} 0}
+
+test nre-1.3 {mutually recursive procs and lambdas} -setup {
+ proc a i {
+ apply $::b [incr i]
+ }
+ set b [list i [makebody {a $i}]]
+} -body {
+ setabs
+ a 0
+} -cleanup {
+ rename a {}
+ unset b
+} -constraints {
+ testnrelevels
+} -result {{0 2 2 2} 0}
+
+#
+# Test that aliases are non-recursive
+#
+
+test nre-2.1 {alias is not recursive} -setup {
+ proc a i [makebody {b $i}]
+ interp alias {} b {} a
+} -body {
+ setabs
+ a 0
+} -cleanup {
+ rename a {}
+ rename b {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 1 1} 0}
+
+#
+# Test that imports are non-recursive
+#
+
+test nre-3.1 {imports are not recursive} -setup {
+ namespace eval foo {
+ setabs
+ namespace export a
+ }
+ proc foo::a i [makebody {::a $i}]
+ namespace import foo::a
+} -body {
+ a 0
+} -cleanup {
+ rename a {}
+ namespace delete ::foo
+} -constraints {
+ testnrelevels
+} -result {{0 2 1 1} 0}
+
+test nre-4.1 {ensembles are not recursive} -setup {
+ proc a i [makebody {b foo $i}]
+ namespace ensemble create \
+ -command b \
+ -map [list foo a]
+} -body {
+ setabs
+ a 0
+} -cleanup {
+ rename a {}
+ rename b {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 1 1} 0}
+
+test nre-5.1 {[namespace eval] is not recursive} -setup {
+ namespace eval ::foo {
+ setabs
+ }
+ proc foo::a i [makebody {namespace eval ::foo [list a $i]}]
+} -body {
+ ::foo::a 0
+} -cleanup {
+ namespace delete ::foo
+} -constraints {
+ testnrelevels
+} -result {{0 3 2 2} 0}
+
+test nre-5.2 {[namespace eval] is not recursive} -setup {
+ namespace eval ::foo {
+ setabs
+ }
+ proc foo::a i [makebody {namespace eval ::foo "set x $i; a $i"}]
+} -body {
+ foo::a 0
+} -cleanup {
+ namespace delete ::foo
+} -constraints {
+ testnrelevels
+} -result {{0 3 2 2} 0}
+
+test nre-6.1 {[uplevel] is not recursive} -setup {
+ proc a i [makebody {uplevel 1 [list a $i]}]
+} -body {
+ setabs
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 2 0} 0}
+
+test nre-6.2 {[uplevel] is not recursive} -setup {
+ setabs
+ proc a i [makebody {uplevel 1 "set x $i; a $i"}]
+} -body {
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 2 0} 0}
+
+test nre-7.1 {[catch] is not recursive} -setup {
+ setabs
+ proc a i [makebody {uplevel 1 "catch {a $i} msg; set msg"}]
+} -body {
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 3 3 0} 0}
+
+test nre-7.2 {[if] is not recursive} -setup {
+ setabs
+ proc a i [makebody {uplevel 1 "if 1 {a $i}"}]
+} -body {
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 2 0} 0}
+
+test nre-7.3 {[while] is not recursive} -setup {
+ setabs
+ proc a i [makebody {uplevel 1 "while 1 {set res \[a $i\]; break}; set res"}]
+} -body {
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 2 0} 0}
+
+test nre-7.4 {[for] is not recursive} -setup {
+ setabs
+ proc a i [makebody {uplevel 1 "for {set j 0} {\$j < 10} {incr j} {set res \[a $i\]; break}; set res"}]
+} -body {
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 2 0} 0}
+
+test nre-7.5 {[foreach] is not recursive} -setup {
+ #
+ # Enable once [foreach] is NR-enabled
+ #
+ setabs
+ proc a i [makebody {uplevel 1 "foreach j {1 2 3 4 5 6} {set res \[a $i\]; break}; set res"}]
+} -body {
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 3 3 0} 0}
+
+test nre-7.6 {[eval] is not recursive} -setup {
+ proc a i [makebody {eval [list a $i]}]
+} -body {
+ setabs
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 2 1} 0}
+
+test nre-7.7 {[eval] is not recursive} -setup {
+ proc a i [makebody {eval "a $i"}]
+} -body {
+ setabs
+ a 0
+} -cleanup {
+ rename a {}
+} -constraints {
+ testnrelevels
+} -result {{0 2 2 1} 0}
+
+test nre-7.8 {bug #2910748: switch out of stale BC is not nre-aware} -setup {
+ proc foo args {}
+ foo
+ coroutine bar apply {{} {
+ yield
+ proc foo args {return ok}
+ while 1 {
+ yield [incr i]
+ foo
+ }
+ }}
+} -body {
+ # if switching to plain eval is not nre aware, this will cause a "cannot
+ # yield" error
+
+ list [bar] [bar] [bar]
+} -cleanup {
+ rename bar {}
+ rename foo {}
+} -result {1 2 3}
+
+
+test nre-8.1 {nre and {*}} -body {
+ # force an expansion that grows the evaluation stack, check that nre
+ # adapts the TEBCdataPtr. This crashes on failure.
+
+ proc inner {} {
+ set long [lrepeat 1000000 1]
+ list {*}$long
+ }
+ proc outer {} inner
+ lrange [outer] 0 2
+} -cleanup {
+ rename inner {}
+ rename outer {}
+} -result {1 1 1}
+test nre-8.2 {nre and {*}, [Bug 2415422]} -body {
+ # force an expansion that grows the evaluation stack, check that nre
+ # adapts the bcFramePtr. This causes an NRE assertion to fail if it is not
+ # done properly.
+
+ proc nop {} {}
+ proc crash {} {
+ foreach val [list {*}[lrepeat 100000 x]] {
+ nop
+ }
+ }
+
+ crash
+} -cleanup {
+ rename nop {}
+ rename crash {}
+}
+
+
+#
+# Basic TclOO tests
+#
+
+test nre-oo.1 {really deep calls in oo - direct} -setup {
+ oo::object create foo
+ oo::objdefine foo method bar i [makebody {foo bar $i}]
+} -body {
+ setabs
+ foo bar 0
+} -cleanup {
+ foo destroy
+} -constraints {
+ testnrelevels
+} -result {{0 1 1 1} 0}
+
+test nre-oo.2 {really deep calls in oo - call via [self]} -setup {
+ oo::object create foo
+ oo::objdefine foo method bar i [makebody {[self] bar $i}]
+} -body {
+ setabs
+ foo bar 0
+} -cleanup {
+ foo destroy
+} -constraints {
+ testnrelevels
+} -result {{0 1 1 1} 0}
+
+test nre-oo.3 {really deep calls in oo - private calls} -setup {
+ oo::object create foo
+ oo::objdefine foo method bar i [makebody {my bar $i}]
+} -body {
+ setabs
+ foo bar 0
+} -cleanup {
+ foo destroy
+} -constraints {
+ testnrelevels
+} -result {{0 1 1 1} 0}
+
+test nre-oo.4 {really deep calls in oo - overriding} -setup {
+ oo::class create foo {
+ method bar i [makebody {my bar $i}]
+ }
+ oo::class create boo {
+ superclass foo
+ method bar i [makebody {next $i}]
+ }
+} -body {
+ setabs
+ [boo new] bar 0
+} -cleanup {
+ foo destroy
+} -constraints {
+ testnrelevels
+} -result {{0 1 1 1} 0}
+
+test nre-oo.5 {really deep calls in oo - forwards} -setup {
+ oo::object create foo
+ set body [makebody {my boo $i}]
+ oo::objdefine foo "
+ method bar i {$body}
+ forward boo ::foo bar
+ "
+} -body {
+ setabs
+ foo bar 0
+} -cleanup {
+ foo destroy
+} -constraints {
+ testnrelevels
+} -result {{0 2 1 1} 0}
+
+
+#
+# NASTY BUG found by tcllib's interp package
+#
+
+test nre-X.1 {eval in wrong interp} -setup {
+ set i [interp create]
+ $i eval {proc filter lst {lsearch -all -inline -not $lst "::tcl"}}
+} -body {
+ $i eval {
+ set x {namespace children ::}
+ set y [list namespace children ::]
+ namespace delete {*}[filter [{*}$y]]
+ set j [interp create]
+ $j alias filter filter
+ $j eval {namespace delete {*}[filter [namespace children ::]]}
+ namespace eval foo {}
+ list [filter [eval $x]] [filter [eval $y]] [filter [$j eval $x]] [filter [$j eval $y]]
+ }
+} -cleanup {
+ interp delete $i
+} -result {::foo ::foo {} {}}
+
+# cleanup
+::tcltest::cleanupTests
+
+if {[testConstraint testnrelevels]} {
+ namespace forget testnre::*
+ namespace delete testnre
+}
+
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/obj.test b/pkgs/msgcat/tests/obj.test
new file mode 100644
index 0000000..126d5ca
--- /dev/null
+++ b/pkgs/msgcat/tests/obj.test
@@ -0,0 +1,632 @@
+# Functionality covered: this file contains a collection of tests for the
+# procedures in tclObj.c that implement Tcl's basic type support and the
+# type managers for the types boolean, double, and integer.
+#
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 1995-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testobj [llength [info commands testobj]]
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}]
+
+test obj-1.1 {Tcl_AppendAllObjTypes, and InitTypeTable, Tcl_RegisterObjType} testobj {
+ set r 1
+ foreach {t} {
+ {array search}
+ bytearray
+ bytecode
+ cmdName
+ dict
+ end-offset
+ regexp
+ string
+ } {
+ set first [string first $t [testobj types]]
+ set r [expr {$r && ($first != -1)}]
+ }
+ set result $r
+} {1}
+
+test obj-2.1 {Tcl_GetObjType error} testobj {
+ list [testintobj set 1 0] [catch {testobj convert 1 foo} msg] $msg
+} {0 1 {no type foo found}}
+test obj-2.2 {Tcl_GetObjType and Tcl_ConvertToType} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testintobj set 1 12]
+ lappend result [testobj convert 1 bytearray]
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 12 12 bytearray 3}
+
+test obj-3.1 {Tcl_ConvertToType error} testobj {
+ list [testdoubleobj set 1 12.34] \
+ [catch {testobj convert 1 end-offset} msg] \
+ $msg
+} {12.34 1 {bad index "12.34": must be end?[+-]integer?}}
+test obj-3.2 {Tcl_ConvertToType error, "empty string" object} testobj {
+ list [testobj newobj 1] [catch {testobj convert 1 end-offset} msg] $msg
+} {{} 1 {bad index "": must be end?[+-]integer?}}
+
+test obj-4.1 {Tcl_NewObj and AllocateFreeObjects} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testobj newobj 1]
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} {} string 2}
+
+test obj-5.1 {Tcl_FreeObj} testobj {
+ set result ""
+ lappend result [testintobj set 1 12345]
+ lappend result [testobj freeallvars]
+ lappend result [catch {testintobj get 1} msg]
+ lappend result $msg
+} {12345 {} 1 {variable 1 is unset (NULL)}}
+
+test obj-6.1 {Tcl_DuplicateObj, object has internal rep} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testintobj set 1 47]
+ lappend result [testobj duplicate 1 2]
+ lappend result [testintobj get 2]
+ lappend result [testobj refcount 1]
+ lappend result [testobj refcount 2]
+} {{} 47 47 47 2 3}
+test obj-6.2 {Tcl_DuplicateObj, "empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testobj newobj 1]
+ lappend result [testobj duplicate 1 2]
+ lappend result [testintobj get 2]
+ lappend result [testobj refcount 1]
+ lappend result [testobj refcount 2]
+} {{} {} {} {} 2 3}
+
+# We assume that testobj is an indicator for test*obj as well
+
+test obj-7.1 {Tcl_GetString, return existing string rep} testobj {
+ set result ""
+ lappend result [testintobj set 1 47]
+ lappend result [testintobj get2 1]
+} {47 47}
+test obj-7.2 {Tcl_GetString, "empty string" object} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [teststringobj append 1 abc -1]
+ lappend result [teststringobj get2 1]
+} {{} abc abc}
+test obj-7.3 {Tcl_GetString, returns string internal rep (DString)} testobj {
+ set result ""
+ lappend result [teststringobj set 1 xyz]
+ lappend result [teststringobj append 1 abc -1]
+ lappend result [teststringobj get2 1]
+} {xyz xyzabc xyzabc}
+test obj-7.4 {Tcl_GetString, recompute string rep from internal rep} testobj {
+ set result ""
+ lappend result [testintobj set 1 77]
+ lappend result [testintobj mult10 1]
+ lappend result [teststringobj get2 1]
+} {77 770 770}
+
+test obj-8.1 {Tcl_GetStringFromObj, return existing string rep} testobj {
+ set result ""
+ lappend result [testintobj set 1 47]
+ lappend result [testintobj get 1]
+} {47 47}
+test obj-8.2 {Tcl_GetStringFromObj, "empty string" object} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [teststringobj append 1 abc -1]
+ lappend result [teststringobj get 1]
+} {{} abc abc}
+test obj-8.3 {Tcl_GetStringFromObj, returns string internal rep (DString)} testobj {
+ set result ""
+ lappend result [teststringobj set 1 xyz]
+ lappend result [teststringobj append 1 abc -1]
+ lappend result [teststringobj get 1]
+} {xyz xyzabc xyzabc}
+test obj-8.4 {Tcl_GetStringFromObj, recompute string rep from internal rep} testobj {
+ set result ""
+ lappend result [testintobj set 1 77]
+ lappend result [testintobj mult10 1]
+ lappend result [teststringobj get 1]
+} {77 770 770}
+
+test obj-9.1 {Tcl_NewBooleanObj} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testbooleanobj set 1 0]
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 0 int 2}
+
+test obj-10.1 {Tcl_SetBooleanObj, existing "empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testobj newobj 1]
+ lappend result [testbooleanobj set 1 0] ;# makes existing obj boolean
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} {} 0 int 2}
+test obj-10.2 {Tcl_SetBooleanObj, existing non-"empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testintobj set 1 98765]
+ lappend result [testbooleanobj set 1 1] ;# makes existing obj boolean
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 98765 1 int 2}
+
+test obj-11.1 {Tcl_GetBooleanFromObj, existing boolean object} testobj {
+ set result ""
+ lappend result [testbooleanobj set 1 1]
+ lappend result [testbooleanobj not 1] ;# gets existing boolean rep
+} {1 0}
+test obj-11.2 {Tcl_GetBooleanFromObj, convert to boolean} testobj {
+ set result ""
+ lappend result [testintobj set 1 47]
+ lappend result [testbooleanobj not 1] ;# must convert to bool
+ lappend result [testobj type 1]
+} {47 0 int}
+test obj-11.3 {Tcl_GetBooleanFromObj, error converting to boolean} testobj {
+ set result ""
+ lappend result [teststringobj set 1 abc]
+ lappend result [catch {testbooleanobj not 1} msg]
+ lappend result $msg
+} {abc 1 {expected boolean value but got "abc"}}
+test obj-11.4 {Tcl_GetBooleanFromObj, error converting from "empty string"} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [catch {testbooleanobj not 1} msg]
+ lappend result $msg
+} {{} 1 {expected boolean value but got ""}}
+test obj-11.5 {Tcl_GetBooleanFromObj, convert hex to boolean} testobj {
+ set result ""
+ lappend result [teststringobj set 1 0xac]
+ lappend result [testbooleanobj not 1]
+ lappend result [testobj type 1]
+} {0xac 0 int}
+test obj-11.6 {Tcl_GetBooleanFromObj, convert float to boolean} testobj {
+ set result ""
+ lappend result [teststringobj set 1 5.42]
+ lappend result [testbooleanobj not 1]
+ lappend result [testobj type 1]
+} {5.42 0 int}
+
+test obj-12.1 {DupBooleanInternalRep} testobj {
+ set result ""
+ lappend result [testbooleanobj set 1 1]
+ lappend result [testobj duplicate 1 2] ;# uses DupBooleanInternalRep
+ lappend result [testbooleanobj get 2]
+} {1 1 1}
+
+test obj-13.1 {SetBooleanFromAny, int to boolean special case} testobj {
+ set result ""
+ lappend result [testintobj set 1 1234]
+ lappend result [testbooleanobj not 1] ;# converts with SetBooleanFromAny
+ lappend result [testobj type 1]
+} {1234 0 int}
+test obj-13.2 {SetBooleanFromAny, double to boolean special case} testobj {
+ set result ""
+ lappend result [testdoubleobj set 1 3.14159]
+ lappend result [testbooleanobj not 1] ;# converts with SetBooleanFromAny
+ lappend result [testobj type 1]
+} {3.14159 0 int}
+test obj-13.3 {SetBooleanFromAny, special case strings representing booleans} testobj {
+ set result ""
+ foreach s {yes no true false on off} {
+ teststringobj set 1 $s
+ lappend result [testbooleanobj not 1]
+ }
+ lappend result [testobj type 1]
+} {0 1 0 1 0 1 int}
+test obj-13.4 {SetBooleanFromAny, recompute string rep then parse it} testobj {
+ set result ""
+ lappend result [testintobj set 1 456]
+ lappend result [testintobj div10 1]
+ lappend result [testbooleanobj not 1] ;# converts with SetBooleanFromAny
+ lappend result [testobj type 1]
+} {456 45 0 int}
+test obj-13.5 {SetBooleanFromAny, error parsing string} testobj {
+ set result ""
+ lappend result [teststringobj set 1 abc]
+ lappend result [catch {testbooleanobj not 1} msg]
+ lappend result $msg
+} {abc 1 {expected boolean value but got "abc"}}
+test obj-13.6 {SetBooleanFromAny, error parsing string} testobj {
+ set result ""
+ lappend result [teststringobj set 1 x1.0]
+ lappend result [catch {testbooleanobj not 1} msg]
+ lappend result $msg
+} {x1.0 1 {expected boolean value but got "x1.0"}}
+test obj-13.7 {SetBooleanFromAny, error converting from "empty string"} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [catch {testbooleanobj not 1} msg]
+ lappend result $msg
+} {{} 1 {expected boolean value but got ""}}
+test obj-13.8 {SetBooleanFromAny, unicode strings} testobj {
+ set result ""
+ lappend result [teststringobj set 1 1\u7777]
+ lappend result [catch {testbooleanobj not 1} msg]
+ lappend result $msg
+} "1\u7777 1 {expected boolean value but got \"1\u7777\"}"
+
+test obj-14.1 {UpdateStringOfBoolean} testobj {
+ set result ""
+ lappend result [testbooleanobj set 1 0]
+ lappend result [testbooleanobj not 1]
+ lappend result [testbooleanobj get 1] ;# must update string rep
+} {0 1 1}
+
+test obj-15.1 {Tcl_NewDoubleObj} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testdoubleobj set 1 3.1459]
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 3.1459 double 2}
+
+test obj-16.1 {Tcl_SetDoubleObj, existing "empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testobj newobj 1]
+ lappend result [testdoubleobj set 1 0.123] ;# makes existing obj boolean
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} {} 0.123 double 2}
+test obj-16.2 {Tcl_SetDoubleObj, existing non-"empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testintobj set 1 98765]
+ lappend result [testdoubleobj set 1 27.56] ;# makes existing obj double
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 98765 27.56 double 2}
+
+test obj-17.1 {Tcl_GetDoubleFromObj, existing double object} testobj {
+ set result ""
+ lappend result [testdoubleobj set 1 16.1]
+ lappend result [testdoubleobj mult10 1] ;# gets existing double rep
+} {16.1 161.0}
+test obj-17.2 {Tcl_GetDoubleFromObj, convert to double} testobj {
+ set result ""
+ lappend result [testintobj set 1 477]
+ lappend result [testdoubleobj div10 1] ;# must convert to bool
+ lappend result [testobj type 1]
+} {477 47.7 double}
+test obj-17.3 {Tcl_GetDoubleFromObj, error converting to double} testobj {
+ set result ""
+ lappend result [teststringobj set 1 abc]
+ lappend result [catch {testdoubleobj mult10 1} msg]
+ lappend result $msg
+} {abc 1 {expected floating-point number but got "abc"}}
+test obj-17.4 {Tcl_GetDoubleFromObj, error converting from "empty string"} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [catch {testdoubleobj div10 1} msg]
+ lappend result $msg
+} {{} 1 {expected floating-point number but got ""}}
+
+test obj-18.1 {DupDoubleInternalRep} testobj {
+ set result ""
+ lappend result [testdoubleobj set 1 17.1]
+ lappend result [testobj duplicate 1 2] ;# uses DupDoubleInternalRep
+ lappend result [testdoubleobj get 2]
+} {17.1 17.1 17.1}
+
+test obj-19.1 {SetDoubleFromAny, int to double special case} testobj {
+ set result ""
+ lappend result [testintobj set 1 1234]
+ lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
+ lappend result [testobj type 1]
+} {1234 12340.0 double}
+test obj-19.2 {SetDoubleFromAny, boolean to double special case} testobj {
+ set result ""
+ lappend result [testbooleanobj set 1 1]
+ lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
+ lappend result [testobj type 1]
+} {1 10.0 double}
+test obj-19.3 {SetDoubleFromAny, recompute string rep then parse it} testobj {
+ set result ""
+ lappend result [testintobj set 1 456]
+ lappend result [testintobj div10 1]
+ lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
+ lappend result [testobj type 1]
+} {456 45 450.0 double}
+test obj-19.4 {SetDoubleFromAny, error parsing string} testobj {
+ set result ""
+ lappend result [teststringobj set 1 abc]
+ lappend result [catch {testdoubleobj mult10 1} msg]
+ lappend result $msg
+} {abc 1 {expected floating-point number but got "abc"}}
+test obj-19.5 {SetDoubleFromAny, error parsing string} testobj {
+ set result ""
+ lappend result [teststringobj set 1 x1.0]
+ lappend result [catch {testdoubleobj mult10 1} msg]
+ lappend result $msg
+} {x1.0 1 {expected floating-point number but got "x1.0"}}
+test obj-19.6 {SetDoubleFromAny, error converting from "empty string"} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [catch {testdoubleobj div10 1} msg]
+ lappend result $msg
+} {{} 1 {expected floating-point number but got ""}}
+
+test obj-20.1 {UpdateStringOfDouble} testobj {
+ set result ""
+ lappend result [testdoubleobj set 1 3.14159]
+ lappend result [testdoubleobj mult10 1]
+ lappend result [testdoubleobj get 1] ;# must update string rep
+} {3.14159 31.4159 31.4159}
+
+test obj-21.1 {Tcl_NewIntObj} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testintobj set 1 55]
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 55 int 2}
+
+test obj-22.1 {Tcl_SetIntObj, existing "empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testobj newobj 1]
+ lappend result [testintobj set 1 77] ;# makes existing obj int
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} {} 77 int 2}
+test obj-22.2 {Tcl_SetIntObj, existing non-"empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testdoubleobj set 1 12.34]
+ lappend result [testintobj set 1 77] ;# makes existing obj int
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 12.34 77 int 2}
+
+test obj-23.1 {Tcl_GetIntFromObj, existing int object} testobj {
+ set result ""
+ lappend result [testintobj set 1 22]
+ lappend result [testintobj mult10 1] ;# gets existing int rep
+} {22 220}
+test obj-23.2 {Tcl_GetIntFromObj, convert to int} testobj {
+ set result ""
+ lappend result [testintobj set 1 477]
+ lappend result [testintobj div10 1] ;# must convert to bool
+ lappend result [testobj type 1]
+} {477 47 int}
+test obj-23.3 {Tcl_GetIntFromObj, error converting to int} testobj {
+ set result ""
+ lappend result [teststringobj set 1 abc]
+ lappend result [catch {testintobj mult10 1} msg]
+ lappend result $msg
+} {abc 1 {expected integer but got "abc"}}
+test obj-23.4 {Tcl_GetIntFromObj, error converting from "empty string"} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [catch {testintobj div10 1} msg]
+ lappend result $msg
+} {{} 1 {expected integer but got ""}}
+test obj-23.5 {Tcl_GetIntFromObj, integer too large to represent as non-long error} {testobj} {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [testintobj inttoobigtest 1]
+} {{} 1}
+
+test obj-24.1 {DupIntInternalRep} testobj {
+ set result ""
+ lappend result [testintobj set 1 23]
+ lappend result [testobj duplicate 1 2] ;# uses DupIntInternalRep
+ lappend result [testintobj get 2]
+} {23 23 23}
+
+test obj-25.1 {SetIntFromAny, int to int special case} testobj {
+ set result ""
+ lappend result [testintobj set 1 1234]
+ lappend result [testintobj mult10 1] ;# converts with SetIntFromAny
+ lappend result [testobj type 1]
+} {1234 12340 int}
+test obj-25.2 {SetIntFromAny, boolean to int special case} testobj {
+ set result ""
+ lappend result [testbooleanobj set 1 1]
+ lappend result [testintobj mult10 1] ;# converts with SetIntFromAny
+ lappend result [testobj type 1]
+} {1 10 int}
+test obj-25.3 {SetIntFromAny, recompute string rep then parse it} testobj {
+ set result ""
+ lappend result [testintobj set 1 456]
+ lappend result [testintobj div10 1]
+ lappend result [testintobj mult10 1] ;# converts with SetIntFromAny
+ lappend result [testobj type 1]
+} {456 45 450 int}
+test obj-25.4 {SetIntFromAny, error parsing string} testobj {
+ set result ""
+ lappend result [teststringobj set 1 abc]
+ lappend result [catch {testintobj mult10 1} msg]
+ lappend result $msg
+} {abc 1 {expected integer but got "abc"}}
+test obj-25.5 {SetIntFromAny, error parsing string} testobj {
+ set result ""
+ lappend result [teststringobj set 1 x17]
+ lappend result [catch {testintobj mult10 1} msg]
+ lappend result $msg
+} {x17 1 {expected integer but got "x17"}}
+test obj-25.6 {SetIntFromAny, integer too large} {testobj} {
+ set result ""
+ lappend result [teststringobj set 1 123456789012345678901]
+ lappend result [catch {testintobj mult10 1} msg]
+ lappend result $msg
+} {123456789012345678901 1 {integer value too large to represent}}
+test obj-25.7 {SetIntFromAny, error converting from "empty string"} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [catch {testintobj div10 1} msg]
+ lappend result $msg
+} {{} 1 {expected integer but got ""}}
+
+test obj-26.1 {UpdateStringOfInt} testobj {
+ set result ""
+ lappend result [testintobj set 1 512]
+ lappend result [testintobj mult10 1]
+ lappend result [testintobj get 1] ;# must update string rep
+} {512 5120 5120}
+
+test obj-27.1 {Tcl_NewLongObj} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ testintobj setmaxlong 1
+ lappend result [testintobj ismaxlong 1]
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 1 int 1}
+
+test obj-28.1 {Tcl_SetLongObj, existing "empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testobj newobj 1]
+ lappend result [testintobj setlong 1 77] ;# makes existing obj long int
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} {} 77 int 2}
+test obj-28.2 {Tcl_SetLongObj, existing non-"empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testdoubleobj set 1 12.34]
+ lappend result [testintobj setlong 1 77] ;# makes existing obj long int
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 12.34 77 int 2}
+
+test obj-29.1 {Tcl_GetLongFromObj, existing long integer object} testobj {
+ set result ""
+ lappend result [testintobj setlong 1 22]
+ lappend result [testintobj mult10 1] ;# gets existing long int rep
+} {22 220}
+test obj-29.2 {Tcl_GetLongFromObj, convert to long} testobj {
+ set result ""
+ lappend result [testintobj setlong 1 477]
+ lappend result [testintobj div10 1] ;# must convert to bool
+ lappend result [testobj type 1]
+} {477 47 int}
+test obj-29.3 {Tcl_GetLongFromObj, error converting to long integer} testobj {
+ set result ""
+ lappend result [teststringobj set 1 abc]
+ lappend result [catch {testintobj ismaxlong 1} msg] ;# cvts to long int
+ lappend result $msg
+} {abc 1 {expected integer but got "abc"}}
+test obj-29.4 {Tcl_GetLongFromObj, error converting from "empty string"} testobj {
+ set result ""
+ lappend result [testobj newobj 1]
+ lappend result [catch {testintobj ismaxlong 1} msg] ;# cvts to long int
+ lappend result $msg
+} {{} 1 {expected integer but got ""}}
+
+test obj-30.1 {Ref counting and object deletion, simple types} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testintobj set 1 1024]
+ lappend result [testobj assign 1 2] ;# vars 1 and 2 share the int obj
+ lappend result [testobj type 2]
+ lappend result [testobj refcount 1]
+ lappend result [testobj refcount 2]
+ lappend result [testbooleanobj set 2 0] ;# must copy on write, now 2 objs
+ lappend result [testobj type 2]
+ lappend result [testobj refcount 1]
+ lappend result [testobj refcount 2]
+} {{} 1024 1024 int 4 4 0 int 3 2}
+
+
+test obj-31.1 {regenerate string rep of "end"} testobj {
+ testobj freeallvars
+ teststringobj set 1 end
+ testobj convert 1 end-offset
+ testobj invalidateStringRep 1
+} end
+test obj-31.2 {regenerate string rep of "end-1"} testobj {
+ testobj freeallvars
+ teststringobj set 1 end-0x1
+ testobj convert 1 end-offset
+ testobj invalidateStringRep 1
+} end-1
+test obj-31.3 {regenerate string rep of "end--1"} testobj {
+ testobj freeallvars
+ teststringobj set 1 end--0x1
+ testobj convert 1 end-offset
+ testobj invalidateStringRep 1
+} end--1
+test obj-31.4 {regenerate string rep of "end-bigInteger"} testobj {
+ testobj freeallvars
+ teststringobj set 1 end-0x7fffffff
+ testobj convert 1 end-offset
+ testobj invalidateStringRep 1
+} end-2147483647
+test obj-31.5 {regenerate string rep of "end--bigInteger"} testobj {
+ testobj freeallvars
+ teststringobj set 1 end--0x7fffffff
+ testobj convert 1 end-offset
+ testobj invalidateStringRep 1
+} end--2147483647
+test obj-31.6 {regenerate string rep of "end--bigInteger"} {testobj longIs32bit} {
+ testobj freeallvars
+ teststringobj set 1 end--0x80000000
+ testobj convert 1 end-offset
+ testobj invalidateStringRep 1
+} end--2147483648
+
+test obj-32.1 {freeing very large object trees} {
+ set x {}
+ for {set i 0} {$i<100000} {incr i} {
+ set x [list $x {}]
+ }
+ unset x
+} {}
+
+test obj-33.1 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+ set x 0x8000; append x 0000
+ list [string is integer $x] [expr { wide($x) }]
+} {1 2147483648}
+test obj-33.2 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+ set x 0xffff; append x ffff
+ list [string is integer $x] [expr { wide($x) }]
+} {1 4294967295}
+test obj-33.3 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+ set x 0x10000; append x 0000
+ list [string is integer $x] [expr { wide($x) }]
+} {0 4294967296}
+test obj-33.4 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+ set x -0x8000; append x 0000
+ list [string is integer $x] [expr { wide($x) }]
+} {1 -2147483648}
+test obj-33.5 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+ set x -0x8000; append x 0001
+ list [string is integer $x] [expr { wide($x) }]
+} {1 -2147483649}
+test obj-33.6 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+ set x -0xffff; append x ffff
+ list [string is integer $x] [expr { wide($x) }]
+} {1 -4294967295}
+test obj-33.7 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+ set x -0x10000; append x 0000
+ list [string is integer $x] [expr { wide($x) }]
+} {0 -4294967296}
+
+if {[testConstraint testobj]} {
+ testobj freeallvars
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/oo.test b/pkgs/msgcat/tests/oo.test
new file mode 100644
index 0000000..00663e9
--- /dev/null
+++ b/pkgs/msgcat/tests/oo.test
@@ -0,0 +1,3364 @@
+# This file contains a collection of tests for Tcl's built-in object system.
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 2006-2011 Donal K. Fellows
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require -exact TclOO 0.6.3 ;# Must match value in generic/tclOO.h
+package require tcltest 2
+if {"::tcltest" in [namespace children]} {
+ namespace import -force ::tcltest::*
+}
+
+testConstraint memory [llength [info commands memory]]
+if {[testConstraint memory]} {
+ proc getbytes {} {
+ set lines [split [memory info] \n]
+ return [lindex $lines 3 3]
+ }
+ proc leaktest {script {iterations 3}} {
+ set end [getbytes]
+ for {set i 0} {$i < $iterations} {incr i} {
+ uplevel 1 $script
+ set tmp $end
+ set end [getbytes]
+ }
+ return [expr {$end - $tmp}]
+ }
+}
+
+test oo-0.1 {basic test of OO's ability to clean up its initial state} {
+ interp create t
+ t eval {
+ package require TclOO
+ }
+ interp delete t
+} {}
+test oo-0.2 {basic test of OO's ability to clean up its initial state} {
+ set i [interp create]
+ interp eval $i {
+ package require TclOO
+ namespace delete ::
+ }
+ interp delete $i
+} {}
+test oo-0.3 {basic test of OO's ability to clean up its initial state} -body {
+ leaktest {
+ [oo::object new] destroy
+ }
+} -constraints memory -result 0
+test oo-0.4 {basic test of OO's ability to clean up its initial state} -body {
+ leaktest {
+ oo::class create foo
+ foo new
+ foo destroy
+ }
+} -constraints memory -result 0
+test oo-0.5 {testing literal leak on interp delete} memory {
+ leaktest {
+ interp create foo
+ foo eval {oo::object new}
+ interp delete foo
+ }
+} 0
+test oo-0.6 {cleaning the core class pair; way #1} -setup {
+ interp create t
+} -body {
+ t eval {
+ package require TclOO
+ namespace path oo
+ list [catch {class destroy} m] $m [catch {object destroy} m] $m
+ }
+} -cleanup {
+ interp delete t
+} -result {0 {} 1 {invalid command name "object"}}
+test oo-0.7 {cleaning the core class pair; way #2} -setup {
+ interp create t
+} -body {
+ t eval {
+ package require TclOO
+ namespace path oo
+ list [catch {object destroy} m] $m [catch {class destroy} m] $m
+ }
+} -cleanup {
+ interp delete t
+} -result {0 {} 1 {invalid command name "class"}}
+test oo-0.8 {leak in variable management} -setup {
+ oo::class create foo
+} -constraints memory -body {
+ oo::define foo {
+ constructor {} {
+ variable v 0
+ }
+ }
+ leaktest {[foo new] destroy}
+} -cleanup {
+ foo destroy
+} -result 0
+test oo-0.9 {various types of presence of the TclOO package} {
+ list [lsearch -nocase -all -inline [package names] tcloo] \
+ [package present TclOO] [package versions TclOO]
+} [list TclOO $::oo::version $::oo::version]
+
+test oo-1.1 {basic test of OO functionality: no classes} {
+ set result {}
+ lappend result [oo::object create foo]
+ lappend result [oo::objdefine foo {
+ method bar args {
+ global result
+ lappend result {*}$args
+ return [llength $args]
+ }
+ }]
+ lappend result [foo bar a b c]
+ lappend result [foo destroy] [info commands foo]
+} {::foo {} a b c 3 {} {}}
+test oo-1.2 {basic test of OO functionality: no classes} -body {
+ oo::define oo::object method missingArgs
+} -returnCodes 1 -result "wrong # args: should be \"oo::define oo::object method name args body\""
+test oo-1.3 {basic test of OO functionality: no classes} {
+ catch {oo::define oo::object method missingArgs}
+ set errorInfo
+} "wrong # args: should be \"oo::define oo::object method name args body\"
+ while executing
+\"oo::define oo::object method missingArgs\""
+test oo-1.4 {basic test of OO functionality} -body {
+ oo::object create {}
+} -returnCodes 1 -result {object name must not be empty}
+test oo-1.5 {basic test of OO functionality} -body {
+ oo::object doesnotexist
+} -returnCodes 1 -result {unknown method "doesnotexist": must be create, destroy or new}
+test oo-1.5.1 {basic test of OO functionality} -setup {
+ oo::object create aninstance
+} -returnCodes error -body {
+ aninstance
+} -cleanup {
+ rename aninstance {}
+} -result {wrong # args: should be "aninstance method ?arg ...?"}
+test oo-1.6 {basic test of OO functionality} -setup {
+ oo::object create aninstance
+} -body {
+ oo::objdefine aninstance unexport destroy
+ aninstance doesnotexist
+} -cleanup {
+ rename aninstance {}
+} -returnCodes 1 -result {object "::aninstance" has no visible methods}
+test oo-1.7 {basic test of OO functionality} -setup {
+ oo::object create aninstance
+} -body {
+ oo::objdefine aninstance {
+ # Do not do this in real code! Ever! This is *not* supported!
+ ::oo::define::method ha ha ha
+ }
+} -returnCodes error -cleanup {
+ aninstance destroy
+} -result {attempt to misuse API}
+test oo-1.8 {basic test of OO functionality} -setup {
+ oo::object create obj
+ set result {}
+} -cleanup {
+ obj destroy
+} -body {
+ oo::objdefine obj method foo {} {return bar}
+ lappend result [obj foo]
+ oo::objdefine obj method foo {} {}
+ lappend result [obj foo]
+} -result {bar {}}
+test oo-1.9 {basic test of OO functionality} -setup {
+ oo::object create a
+ oo::object create b
+} -cleanup {
+ catch {a destroy}
+ b destroy
+} -body {
+ oo::objdefine a method foo {} { return A }
+ oo::objdefine b method foo {} { return B }
+ apply {{} {
+ set m foo
+ return [a $m],[a destroy],[b $m]
+ }}
+} -result A,,B
+test oo-1.10 {basic test of OO functionality} -body {
+ namespace eval foo {
+ namespace eval bar {
+ oo::object create o
+ namespace export o
+ }
+ namespace import bar::o
+ }
+ list [info object isa object foo::bar::o] [info object isa object foo::o]
+} -cleanup {
+ namespace delete foo
+} -result {1 1}
+test oo-1.11 {basic test of OO functionality: abbreviating} -setup {
+ oo::class create c
+} -cleanup {
+ c destroy
+} -body {
+ oo::define c super oo::class
+ info class super c
+} -result ::oo::class
+test oo-1.12 {basic test of OO functionality: abbreviating} -setup {
+ oo::class create c
+} -cleanup {
+ c destroy
+} -body {
+ oo::define c {super oo::class}
+ info class super c
+} -result ::oo::class
+test oo-1.13 {basic test of OO functionality: abbreviating} -setup {
+ oo::class create c
+} -cleanup {
+ c destroy
+} -body {
+ oo::define c self {forw a b}
+ info object forw c a
+} -result b
+test oo-1.14 {basic test of OO functionality: abbreviating} -setup {
+ oo::class create c
+} -cleanup {
+ c destroy
+} -body {
+ oo::define c self forw a b
+ info object forw c a
+} -result b
+test oo-1.15 {basic test of OO functionality: abbreviating} -setup {
+ oo::object create o
+} -cleanup {
+ o destroy
+} -body {
+ oo::objdefine o {forw a b}
+ info object forw o a
+} -result b
+test oo-1.16 {basic test of OO functionality: abbreviating} -setup {
+ oo::object create o
+} -cleanup {
+ o destroy
+} -body {
+ oo::objdefine o forw a b
+ info object forw o a
+} -result b
+test oo-1.17 {basic test of OO functionality: Bug 2481109} -body {
+ namespace eval ::foo {oo::object create lreplace}
+} -cleanup {
+ namespace delete ::foo
+} -result ::foo::lreplace
+# Check for Bug 2519474; problem in tclNamesp.c, but tested here...
+test oo-1.18 {OO: create object in NS with same name as global cmd} -setup {
+ proc test-oo-1.18 {} return
+ oo::class create A
+ oo::class create B {superclass A}
+} -body {
+ oo::define B constructor {} {A create test-oo-1.18}
+ B create C
+} -cleanup {
+ rename test-oo-1.18 {}
+ A destroy
+} -result ::C
+test oo-1.19 {basic test of OO functionality: teardown order} -body {
+ oo::object create o
+ namespace delete [info object namespace o]
+ o destroy
+ # Crashes on error
+} -returnCodes error -result {invalid command name "o"}
+test oo-1.20 {basic test of OO functionality: my teardown post rename} -body {
+ oo::object create obj
+ rename [info object namespace obj]::my ::AGlobalName
+ obj destroy
+ info commands ::AGlobalName
+} -result {}
+
+test oo-2.1 {basic test of OO functionality: constructor} -setup {
+ # This is a bit complex because it needs to run in a sub-interp as
+ # we're modifying the root object class's constructor
+ interp create subinterp
+ subinterp eval {
+ package require TclOO
+ }
+} -body {
+ subinterp eval {
+ oo::define oo::object constructor {} {
+ lappend ::result [info level 0]
+ }
+ lappend result 1
+ lappend result 2 [oo::object create foo]
+ }
+} -cleanup {
+ interp delete subinterp
+} -result {1 {oo::object create foo} 2 ::foo}
+test oo-2.2 {basic test of OO functionality: constructor} {
+ oo::class create testClass {
+ constructor {} {
+ global result
+ lappend result "[self]->construct"
+ }
+ method bar {} {
+ global result
+ lappend result "[self]->bar"
+ }
+ }
+ set result {}
+ [testClass create foo] bar
+ testClass destroy
+ return $result
+} {::foo->construct ::foo->bar}
+test oo-2.4 {OO constructor - Bug 2531577} -setup {
+ oo::class create foo
+} -body {
+ oo::define foo constructor {} return
+ [foo new] destroy
+ oo::define foo constructor {} {}
+ llength [info command [foo new]]
+} -cleanup {
+ foo destroy
+} -result 1
+test oo-2.5 {OO constructor - Bug 2531577} -setup {
+ oo::class create foo
+ set result {}
+} -body {
+ oo::define foo constructor {} {error x}
+ lappend result [catch {foo new}]
+ oo::define foo constructor {} {}
+ lappend result [llength [info command [foo new]]]
+} -cleanup {
+ foo destroy
+} -result {1 1}
+test oo-2.6 {OO constructor and tailcall - Bug 2414858} -setup {
+ oo::class create foo
+} -body {
+ oo::define foo {
+ constructor {} { tailcall my bar }
+ method bar {} { return bad }
+ }
+ namespace tail [foo create good]
+} -cleanup {
+ foo destroy
+} -result good
+test oo-2.7 {construction, method calls and ensembles - Bug 3514761} -setup {
+ namespace eval k {}
+} -body {
+ namespace eval k {
+ oo::class create s {
+ constructor {j} {
+ # nothing
+ }
+ }
+ namespace export s
+ namespace ensemble create
+ }
+ k s create X
+} -returnCodes error -cleanup {
+ namespace delete k
+} -result {wrong # args: should be "k s create X j"}
+test oo-2.8 {construction, method calls and ensembles - Bug 3514761} -setup {
+ namespace eval k {}
+} -body {
+ namespace eval k {
+ oo::class create s {
+ constructor {j} {
+ # nothing
+ }
+ }
+ oo::class create t {
+ superclass s
+ constructor args {
+ k next {*}$args
+ }
+ }
+ interp alias {} ::k::next {} ::oo::Helpers::next
+ namespace export t next
+ namespace ensemble create
+ }
+ k t create X
+} -returnCodes error -cleanup {
+ namespace delete k
+} -result {wrong # args: should be "k next j"}
+
+test oo-3.1 {basic test of OO functionality: destructor} -setup {
+ # This is a bit complex because it needs to run in a sub-interp as we're
+ # modifying the root object class's constructor
+ interp create subinterp
+ subinterp eval {
+ package require TclOO
+ }
+} -body {
+ subinterp eval {
+ oo::define oo::object destructor {
+ lappend ::result died
+ }
+ lappend result 1 [oo::object create foo]
+ lappend result 2 [rename foo {}]
+ oo::define oo::object destructor {}
+ return $result
+ }
+} -cleanup {
+ interp delete subinterp
+} -result {1 ::foo died 2 {}}
+test oo-3.2 {basic test of OO functionality: destructor} -setup {
+ # This is a bit complex because it needs to run in a sub-interp as
+ # we're modifying the root object class's constructor
+ interp create subinterp
+ subinterp eval {
+ package require TclOO
+ }
+} -body {
+ subinterp eval {
+ oo::define oo::object destructor {
+ lappend ::result died
+ }
+ lappend result 1 [oo::object create foo]
+ lappend result 2 [rename foo {}]
+ }
+} -cleanup {
+ interp delete subinterp
+} -result {1 ::foo died 2 {}}
+test oo-3.3 {basic test of OO functionality: destructor} -setup {
+ oo::class create foo
+ set result {}
+} -cleanup {
+ foo destroy
+} -body {
+ oo::define foo {
+ constructor {} {lappend ::result made}
+ destructor {lappend ::result died}
+ }
+ namespace delete [info object namespace [foo new]]
+ return $result
+} -result {made died}
+test oo-3.4 {basic test of OO functionality: my exists in destructor} -setup {
+ oo::class create cls
+ set result {}
+} -cleanup {
+ cls destroy
+} -body {
+ oo::define cls {
+ variable state
+ constructor {} {
+ proc localcmdexists {} {}
+ set state ok
+ }
+ forward Report lappend ::result
+ destructor {
+ objmy Report [catch {set state} msg] $msg
+ objmy Report [namespace which -var state]
+ objmy Report [info commands localcmdexists]
+ }
+ }
+ cls create obj
+ rename [info object namespace obj]::my ::objmy
+ obj destroy
+ lappend result [info commands ::objmy]
+} -match glob -result {0 ok *::state localcmdexists {}}
+test oo-3.4a {basic test of OO functionality: my exists in destructor} -setup {
+ oo::class create cls
+ set result {}
+} -cleanup {
+ cls destroy
+} -body {
+ oo::define cls {
+ variable state
+ constructor {} {
+ proc localcmdexists {} {}
+ set state ok
+ }
+ forward Report lappend ::result
+ destructor {
+ objmy Report [catch {set state} msg] $msg
+ objmy Report [namespace which -var state]
+ objmy Report [info commands localcmdexists]
+ }
+ }
+ cls create obj
+ rename [info object namespace obj]::my ::objmy
+ rename obj {}
+ lappend result [info commands ::objmy]
+} -match glob -result {0 ok *::state localcmdexists {}}
+test oo-3.5 {basic test of OO functionality: destructor: evil case for Itcl} -setup {
+ oo::class create cls
+ set result {}
+} -cleanup {
+ cls destroy
+} -body {
+ oo::define cls {
+ variable state
+ constructor {} {
+ proc localcmdexists {} {}
+ set state ok
+ }
+ forward Report lappend ::result
+ destructor {
+ objmy Report [catch {set state} msg] $msg
+ objmy Report [namespace which -var state]
+ objmy Report [info commands localcmdexists]
+ }
+ }
+ cls create obj
+ rename [info object namespace obj]::my ::objmy
+ namespace delete [info object namespace obj]
+ lappend result [info commands ::objmy]
+} -match glob -result {0 ok *::state localcmdexists {}}
+test oo-3.5a {basic test of OO functionality: destructor: evil case for Itcl} -setup {
+ oo::class create cls
+ set result {}
+} -cleanup {
+ cls destroy
+} -body {
+ oo::define cls {
+ variable state result
+ constructor {} {
+ proc localcmdexists {} {}
+ set state ok
+ my eval {upvar 0 ::result result}
+ }
+ method nuke {} {
+ namespace delete [namespace current]
+ return $result
+ }
+ destructor {
+ lappend result [self] $state [info commands localcmdexists]
+ }
+ }
+ cls create obj
+ namespace delete [info object namespace obj]
+ [cls create obj2] nuke
+} -match glob -result {::obj ok localcmdexists ::obj2 ok localcmdexists}
+test oo-3.6 {basic test of OO functionality: errors in destructor} -setup {
+ oo::class create cls
+} -cleanup {
+ cls destroy
+} -body {
+ oo::define cls destructor {error foo}
+ list [catch {[cls create obj] destroy} msg] $msg [info commands obj]
+} -result {1 foo {}}
+test oo-3.7 {basic test of OO functionality: errors in destructor} -setup {
+ oo::class create cls
+ set result {}
+ proc bgerror msg {lappend ::result $msg}
+} -cleanup {
+ cls destroy
+ rename bgerror {}
+} -body {
+ oo::define cls destructor {error foo}
+ list [rename [cls create obj] {}] \
+ [update idletasks] $result [info commands obj]
+} -result {{} {} foo {}}
+test oo-3.8 {basic test of OO functionality: errors in destructor} -setup {
+ oo::class create cls
+ set result {}
+ proc bgerror msg {lappend ::result $msg}
+} -cleanup {
+ cls destroy
+ rename bgerror {}
+} -body {
+ oo::define cls destructor {error foo}
+ list [namespace delete [info object namespace [cls create obj]]] \
+ [update idletasks] $result [info commands obj]
+} -result {{} {} foo {}}
+test oo-3.9 {Bug 2944404: deleting the object in the destructor} -setup {
+ oo::class create cls
+ set result {}
+} -body {
+ oo::define cls {
+ destructor {
+ lappend ::result in destructor
+ [self] destroy
+ }
+ }
+ # This used to crash
+ [cls new] destroy
+ return $result
+} -cleanup {
+ cls destroy
+} -result {in destructor}
+
+test oo-4.1 {basic test of OO functionality: export} {
+ set o [oo::object new]
+ set result {}
+ oo::objdefine $o method Foo {} {lappend ::result Foo; return}
+ lappend result [catch {$o Foo} msg] $msg
+ oo::objdefine $o export Foo
+ lappend result [$o Foo] [$o destroy]
+} {1 {unknown method "Foo": must be destroy} Foo {} {}}
+test oo-4.2 {basic test of OO functionality: unexport} {
+ set o [oo::object new]
+ set result {}
+ oo::objdefine $o method foo {} {lappend ::result foo; return}
+ lappend result [$o foo]
+ oo::objdefine $o unexport foo
+ lappend result [catch {$o foo} msg] $msg [$o destroy]
+} {foo {} 1 {unknown method "foo": must be destroy} {}}
+test oo-4.3 {exporting and error messages, Bug 1824958} -setup {
+ oo::class create testClass
+} -cleanup {
+ testClass destroy
+} -body {
+ oo::define testClass self export Bad
+ testClass Bad
+} -returnCodes 1 -result {unknown method "Bad": must be create, destroy or new}
+test oo-4.4 {exporting a class method from an object} -setup {
+ oo::class create testClass
+ testClass create testObject
+} -cleanup {
+ testClass destroy
+} -body {
+ oo::define testClass method Good {} { return ok }
+ oo::objdefine testObject export Good
+ testObject Good
+} -result ok
+test oo-4.5 {export creates proper method entries} -setup {
+ oo::class create testClass
+} -body {
+ oo::define testClass {
+ export foo
+ method foo {} {return ok}
+ }
+ [testClass new] foo
+} -cleanup {
+ testClass destroy
+} -result ok
+test oo-4.6 {export creates proper method entries} -setup {
+ oo::class create testClass
+} -body {
+ oo::define testClass {
+ unexport foo
+ method foo {} {return ok}
+ }
+ [testClass new] foo
+} -cleanup {
+ testClass destroy
+} -result ok
+
+test oo-5.1 {OO: manipulation of classes as objects} -setup {
+ set obj [oo::object new]
+} -body {
+ oo::objdefine oo::object method foo {} { return "in object" }
+ catch {$obj foo} result
+ list [catch {$obj foo} result] $result [oo::object foo]
+} -cleanup {
+ oo::objdefine oo::object deletemethod foo
+ $obj destroy
+} -result {1 {unknown method "foo": must be destroy} {in object}}
+test oo-5.2 {OO: manipulation of classes as objects} -setup {
+ set obj [oo::object new]
+} -body {
+ oo::define oo::object self method foo {} { return "in object" }
+ catch {$obj foo} result
+ list [catch {$obj foo} result] $result [oo::object foo]
+} -cleanup {
+ oo::objdefine oo::object deletemethod foo
+ $obj destroy
+} -result {1 {unknown method "foo": must be destroy} {in object}}
+test oo-5.3 {OO: manipulation of classes as objects} -setup {
+ set obj [oo::object new]
+} -body {
+ oo::objdefine oo::object {
+ method foo {} { return "in object" }
+ }
+ catch {$obj foo} result
+ list [catch {$obj foo} result] $result [oo::object foo]
+} -cleanup {
+ oo::objdefine oo::object deletemethod foo
+ $obj destroy
+} -result {1 {unknown method "foo": must be destroy} {in object}}
+test oo-5.4 {OO: manipulation of classes as objects} -setup {
+ set obj [oo::object new]
+} -body {
+ oo::define oo::object {
+ self method foo {} { return "in object" }
+ }
+ catch {$obj foo} result
+ list [catch {$obj foo} result] $result [oo::object foo]
+} -cleanup {
+ oo::objdefine oo::object deletemethod foo
+ $obj destroy
+} -result {1 {unknown method "foo": must be destroy} {in object}}
+test oo-5.5 {OO: manipulation of classes as objects} -setup {
+ set obj [oo::object new]
+} -body {
+ oo::define oo::object {
+ self {
+ method foo {} { return "in object" }
+ }
+ }
+ catch {$obj foo} result
+ list [catch {$obj foo} result] $result [oo::object foo]
+} -cleanup {
+ oo::objdefine oo::object deletemethod foo
+ $obj destroy
+} -result {1 {unknown method "foo": must be destroy} {in object}}
+
+test oo-6.1 {OO: forward} {
+ oo::object create foo
+ oo::objdefine foo {
+ forward a lappend
+ forward b lappend result
+ }
+ set result {}
+ foo a result 1
+ foo b 2
+ foo destroy
+ return $result
+} {1 2}
+test oo-6.2 {OO: forward resolution scope} -setup {
+ oo::class create fooClass
+} -body {
+ proc foo {} {return bad}
+ oo::define fooClass {
+ constructor {} {
+ proc foo {} {return good}
+ }
+ forward bar foo
+ }
+ [fooClass new] bar
+} -cleanup {
+ fooClass destroy
+ rename foo {}
+} -result good
+test oo-6.3 {OO: forward resolution scope} -setup {
+ oo::class create fooClass
+} -body {
+ proc foo {} {return bad}
+ oo::define fooClass {
+ constructor {} {
+ proc foo {} {return good}
+ }
+ }
+ oo::define fooClass forward bar foo
+ [fooClass new] bar
+} -cleanup {
+ fooClass destroy
+ rename foo {}
+} -result good
+test oo-6.4 {OO: forward resolution scope} -setup {
+ oo::class create fooClass
+} -body {
+ proc foo {} {return good}
+ oo::define fooClass {
+ constructor {} {
+ proc foo {} {return bad}
+ }
+ forward bar ::foo
+ }
+ [fooClass new] bar
+} -cleanup {
+ fooClass destroy
+ rename foo {}
+} -result good
+test oo-6.5 {OO: forward resolution scope} -setup {
+ oo::class create fooClass
+ namespace eval foo {}
+} -body {
+ proc foo::foo {} {return good}
+ oo::define fooClass {
+ constructor {} {
+ proc foo {} {return bad}
+ }
+ forward bar foo::foo
+ }
+ [fooClass new] bar
+} -cleanup {
+ fooClass destroy
+ namespace delete foo
+} -result good
+test oo-6.6 {OO: forward resolution scope} -setup {
+ oo::class create fooClass
+ namespace eval foo {}
+} -body {
+ proc foo::foo {} {return bad}
+ oo::define fooClass {
+ constructor {} {
+ namespace eval foo {
+ proc foo {} {return good}
+ }
+ }
+ forward bar foo::foo
+ }
+ [fooClass new] bar
+} -cleanup {
+ fooClass destroy
+ namespace delete foo
+} -result good
+test oo-6.7 {OO: forward resolution scope is per-object} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ constructor {} {
+ proc curns {} {namespace current}
+ }
+ forward ns curns
+ }
+ expr {[[fooClass new] ns] ne [[fooClass new] ns]}
+} -cleanup {
+ fooClass destroy
+} -result 1
+test oo-6.8 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test my handler
+ method handler {a b c} {}
+ }
+ fooClass create ::foo
+ foo test
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "foo test a b c"}
+test oo-6.9 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test my handler
+ method handler {a b c} {list $a,$b,$c}
+ }
+ fooClass create ::foo
+ foo test 1 2 3
+} -cleanup {
+ fooClass destroy
+} -result 1,2,3
+test oo-6.10 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test my handler
+ method handler {a b c} {list $a,$b,$c}
+ }
+ fooClass create ::foo
+ foo test 1 2
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "foo test a b c"}
+test oo-6.11 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo {
+ forward test my handler
+ method handler {a b c} {}
+ }
+ foo test
+} -returnCodes error -cleanup {
+ foo destroy
+} -result {wrong # args: should be "foo test a b c"}
+test oo-6.12 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo {
+ forward test my handler
+ method handler {a b c} {list $a,$b,$c}
+ }
+ foo test 1 2 3
+} -cleanup {
+ foo destroy
+} -result 1,2,3
+test oo-6.13 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo {
+ forward test my handler
+ method handler {a b c} {list $a,$b,$c}
+ }
+ foo test 1 2
+} -returnCodes error -cleanup {
+ foo destroy
+} -result {wrong # args: should be "foo test a b c"}
+test oo-6.14 {Bug 3400658: forwarding and wrongargs rewriting - multistep} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test my handler1 p
+ forward handler1 my handler q
+ method handler {a b c} {}
+ }
+ fooClass create ::foo
+ foo test
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "foo test c"}
+test oo-6.15 {Bug 3400658: forwarding and wrongargs rewriting - multistep} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test my handler1 p
+ forward handler1 my handler q
+ method handler {a b c} {list $a,$b,$c}
+ }
+ fooClass create ::foo
+ foo test 1
+} -cleanup {
+ fooClass destroy
+} -result q,p,1
+test oo-6.16 {Bug 3400658: forwarding and wrongargs rewriting - via alias} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test handler1 foo bar
+ forward handler2 my handler x
+ method handler {a b c d} {list $a,$b,$c,$d}
+ export eval
+ }
+ fooClass create ::foo
+ foo eval {
+ interp alias {} [namespace current]::handler1 \
+ {} [namespace current]::my handler2
+ }
+ foo test 1 2 3
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "foo test d"}
+test oo-6.17 {Bug 3400658: forwarding and wrongargs rewriting - via ensemble} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward test handler1 foo bar boo
+ forward handler2 my handler
+ method handler {a b c d} {list $a,$b,$c,$d}
+ export eval
+ }
+ fooClass create ::foo
+ foo eval {
+ namespace ensemble create \
+ -command [namespace current]::handler1 -parameters {p q} \
+ -map [list boo [list [namespace current]::my handler2]]
+ }
+ foo test 1 2 3
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "foo test c d"}
+test oo-6.18 {Bug 3408830: more forwarding cases} -setup {
+ oo::class create fooClass
+} -body {
+ oo::define fooClass {
+ forward len string length
+ }
+ [fooClass create foo] len a b
+} -returnCodes error -cleanup {
+ fooClass destroy
+} -result {wrong # args: should be "::foo len string"}
+
+test oo-7.1 {OO: inheritance 101} -setup {
+ oo::class create superClass
+ oo::class create subClass
+ subClass create instance
+} -body {
+ oo::define superClass method doit x {lappend ::result $x}
+ oo::define subClass superclass superClass
+ set result [list [catch {subClass doit bad} msg] $msg]
+ instance doit ok
+ return $result
+} -cleanup {
+ subClass destroy
+ superClass destroy
+} -result {1 {unknown method "doit": must be create, destroy or new} ok}
+test oo-7.2 {OO: inheritance 101} -setup {
+ oo::class create superClass
+ oo::class create subClass
+ subClass create instance
+} -body {
+ oo::define superClass method doit x {
+ lappend ::result |$x|
+ }
+ oo::define subClass superclass superClass
+ oo::objdefine instance method doit x {
+ lappend ::result =$x=
+ next [incr x]
+ }
+ set result {}
+ instance doit 1
+ return $result
+} -cleanup {
+ subClass destroy
+ superClass destroy
+} -result {=1= |2|}
+test oo-7.3 {OO: inheritance 101} -setup {
+ oo::class create superClass
+ oo::class create subClass
+ subClass create instance
+} -body {
+ oo::define superClass method doit x {
+ lappend ::result |$x|
+ }
+ oo::define subClass {
+ superclass superClass
+ method doit x {lappend ::result -$x-; next [incr x]}
+ }
+ oo::objdefine instance method doit x {
+ lappend ::result =$x=;
+ next [incr x]
+ }
+ set result {}
+ instance doit 1
+ return $result
+} -cleanup {
+ subClass destroy
+ superClass destroy
+} -result {=1= -2- |3|}
+test oo-7.4 {OO: inheritance from oo::class} -body {
+ oo::class create meta {
+ superclass oo::class
+ self {
+ unexport create new
+ method make {x {definitions {}}} {
+ if {![string match ::* $x]} {
+ set ns [uplevel 1 {::namespace current}]
+ set x ${ns}::$x
+ }
+ set o [my create $x]
+ lappend ::result "made $o"
+ oo::define $o $definitions
+ return $o
+ }
+ }
+ }
+ set result [list [catch {meta create foo} msg] $msg]
+ lappend result [meta make classinstance {
+ lappend ::result "in definition script in [namespace current]"
+ }]
+ lappend result [classinstance create instance]
+} -cleanup {
+ catch {classinstance destroy}
+ catch {meta destroy}
+} -result {1 {unknown method "create": must be destroy or make} {made ::classinstance} {in definition script in ::oo::define} ::classinstance ::instance}
+test oo-7.5 {OO: inheritance from oo::class in the secondary chain} -body {
+ oo::class create other
+ oo::class create meta {
+ superclass other oo::class
+ self {
+ unexport create new
+ method make {x {definitions {}}} {
+ if {![string match ::* $x]} {
+ set ns [uplevel 1 {::namespace current}]
+ set x ${ns}::$x
+ }
+ set o [my create $x]
+ lappend ::result "made $o"
+ oo::define $o $definitions
+ return $o
+ }
+ }
+ }
+ set result [list [catch {meta create foo} msg] $msg]
+ lappend result [meta make classinstance {
+ lappend ::result "in definition script in [namespace current]"
+ }]
+ lappend result [classinstance create instance]
+} -cleanup {
+ catch {classinstance destroy}
+ catch {meta destroy}
+ catch {other destroy}
+} -result {1 {unknown method "create": must be destroy or make} {made ::classinstance} {in definition script in ::oo::define} ::classinstance ::instance}
+test oo-7.6 {OO: inheritance 101 - overridden methods should be oblivious} -setup {
+ oo::class create Aclass
+ oo::class create Bclass
+ Bclass create Binstance
+} -body {
+ oo::define Aclass {
+ method incr {var step} {
+ upvar 1 $var v
+ ::incr v $step
+ }
+ }
+ oo::define Bclass {
+ superclass Aclass
+ method incr {var {step 1}} {
+ global result
+ lappend result $var $step
+ set r [next $var $step]
+ lappend result returning:$r
+ return $r
+ }
+ }
+ set result {}
+ set x 10
+ lappend result x=$x
+ lappend result [Binstance incr x]
+ lappend result x=$x
+} -result {x=10 x 1 returning:11 11 x=11} -cleanup {
+ unset -nocomplain x
+ Aclass destroy
+}
+test oo-7.7 {OO: inheritance and errorInfo} -setup {
+ oo::class create A
+ oo::class create B
+ B create c
+} -body {
+ oo::define A method foo {} {error foo!}
+ oo::define B {
+ superclass A
+ method foo {} { next }
+ }
+ oo::objdefine c method foo {} { next }
+ catch {c ?} msg
+ set result [list $msg]
+ catch {c foo} msg
+ lappend result $msg $errorInfo
+} -cleanup {
+ A destroy
+} -result {{unknown method "?": must be destroy or foo} foo! {foo!
+ while executing
+"error foo!"
+ (class "::A" method "foo" line 1)
+ invoked from within
+"next "
+ (class "::B" method "foo" line 1)
+ invoked from within
+"next "
+ (object "::c" method "foo" line 1)
+ invoked from within
+"c foo"}}
+test oo-7.8 {OO: next at the end of the method chain} -setup {
+ set ::result ""
+} -cleanup {
+ foo destroy
+} -body {
+ oo::class create foo {
+ method bar {} {lappend ::result foo; lappend ::result [next] foo}
+ }
+ oo::class create foo2 {
+ superclass foo
+ method bar {} {lappend ::result foo2; lappend ::result [next] foo2}
+ }
+ lappend result [catch {[foo2 new] bar} msg] $msg
+} -result {foo2 foo 1 {no next method implementation}}
+test oo-7.9 {OO: defining inheritance in namespaces} -setup {
+ set ::result {}
+ oo::class create ::master
+ namespace eval ::foo {
+ oo::class create mixin {superclass ::master}
+ }
+} -cleanup {
+ ::master destroy
+ namespace delete ::foo
+} -body {
+ namespace eval ::foo {
+ oo::class create bar {superclass master}
+ oo::class create boo
+ oo::define boo {superclass bar}
+ oo::define boo {mixin mixin}
+ oo::class create spong {superclass boo}
+ return
+ }
+} -result {}
+
+test oo-8.1 {OO: global must work in methods} {
+ oo::object create foo
+ oo::objdefine foo method bar x {global result; lappend result $x}
+ set result {}
+ foo bar this
+ foo bar is
+ lappend result a
+ foo bar test
+ foo destroy
+ return $result
+} {this is a test}
+
+test oo-9.1 {OO: multiple inheritance} -setup {
+ oo::class create A
+ oo::class create B
+ oo::class create C
+ oo::class create D
+ D create foo
+} -body {
+ oo::define A method test {} {lappend ::result A; return ok}
+ oo::define B {
+ superclass A
+ method test {} {lappend ::result B; next}
+ }
+ oo::define C {
+ superclass A
+ method test {} {lappend ::result C; next}
+ }
+ oo::define D {
+ superclass B C
+ method test {} {lappend ::result D; next}
+ }
+ set result {}
+ lappend result [foo test]
+} -cleanup {
+ D destroy
+ C destroy
+ B destroy
+ A destroy
+} -result {D B C A ok}
+test oo-9.2 {OO: multiple inheritance} -setup {
+ oo::class create A
+ oo::class create B
+ oo::class create C
+ oo::class create D
+ D create foo
+} -body {
+ oo::define A method test {} {lappend ::result A; return ok}
+ oo::define B {
+ superclass A
+ method test {} {lappend ::result B; next}
+ }
+ oo::define C {
+ superclass A
+ method test {} {lappend ::result C; next}
+ }
+ oo::define D {
+ superclass B C
+ method test {} {lappend ::result D; next}
+ }
+ set result {}
+ lappend result [foo test]
+} -cleanup {
+ A destroy
+} -result {D B C A ok}
+
+test oo-10.1 {OO: recursive invoke and modify} -setup {
+ [oo::class create C] create O
+} -cleanup {
+ C destroy
+} -body {
+ oo::define C method foo x {
+ lappend ::result $x
+ if {$x} {
+ [self object] foo [incr x -1]
+ }
+ }
+ oo::objdefine O method foo x {
+ lappend ::result -$x-
+ if {$x == 1} {
+ oo::objdefine O deletemethod foo
+ }
+ next $x
+ }
+ set result {}
+ O foo 2
+ return $result
+} -result {-2- 2 -1- 1 0}
+test oo-10.2 {OO: recursive invoke and modify} -setup {
+ oo::object create O
+} -cleanup {
+ O destroy
+} -body {
+ oo::objdefine O method foo {} {
+ oo::objdefine [self] method foo {} {
+ error "not called"
+ }
+ return [format %s%s call ed]
+ }
+ O foo
+} -result called
+test oo-10.3 {OO: invoke and modify} -setup {
+ oo::class create A {
+ method a {} {return A.a}
+ method b {} {return A.b}
+ method c {} {return A.c}
+ }
+ oo::class create B {
+ superclass A
+ method a {} {return [next],B.a}
+ method b {} {return [next],B.b}
+ method c {} {return [next],B.c}
+ }
+ B create C
+ set result {}
+} -cleanup {
+ A destroy
+} -body {
+ lappend result [C a] [C b] [C c] -
+ oo::define B deletemethod b
+ lappend result [C a] [C b] [C c] -
+ oo::define B renamemethod a b
+ lappend result [C a] [C b] [C c] -
+ oo::define B deletemethod b c
+ lappend result [C a] [C b] [C c]
+} -result {A.a,B.a A.b,B.b A.c,B.c - A.a,B.a A.b A.c,B.c - A.a A.b,B.a A.c,B.c - A.a A.b A.c}
+
+test oo-11.1 {OO: cleanup} {
+ oo::object create foo
+ set result [list [catch {oo::object create foo} msg] $msg]
+ lappend result [foo destroy] [oo::object create foo] [foo destroy]
+} {1 {can't create object "foo": command already exists with that name} {} ::foo {}}
+test oo-11.2 {OO: cleanup} {
+ oo::class create bar
+ bar create foo
+ set result [list [catch {bar create foo} msg] $msg]
+ lappend result [bar destroy] [oo::object create foo] [foo destroy]
+} {1 {can't create object "foo": command already exists with that name} {} ::foo {}}
+test oo-11.3 {OO: cleanup} {
+ oo::class create bar0
+ oo::class create bar
+ oo::define bar superclass bar0
+ bar create foo
+ set result [list [catch {bar create foo} msg] $msg]
+ lappend result [bar0 destroy] [oo::object create foo] [foo destroy]
+} {1 {can't create object "foo": command already exists with that name} {} ::foo {}}
+test oo-11.4 {OO: cleanup} {
+ oo::class create bar0
+ oo::class create bar1
+ oo::define bar1 superclass bar0
+ oo::class create bar2
+ oo::define bar2 {
+ superclass bar0
+ destructor {lappend ::result destroyed}
+ }
+ oo::class create bar
+ oo::define bar superclass bar1 bar2
+ bar create foo
+ set result [list [catch {bar create foo} msg] $msg]
+ lappend result [bar0 destroy] [oo::object create foo] [foo destroy] \
+ [oo::object create bar2] [bar2 destroy]
+} {1 {can't create object "foo": command already exists with that name} destroyed {} ::foo {} ::bar2 {}}
+
+test oo-12.1 {OO: filters} {
+ oo::class create Aclass
+ Aclass create Aobject
+ oo::define Aclass {
+ method concatenate args {
+ global result
+ lappend result {*}$args
+ join $args {}
+ }
+ method logFilter args {
+ global result
+ lappend result "calling [self object]->[self method] $args"
+ set r [next {*}$args]
+ lappend result "result=$r"
+ return $r
+ }
+ }
+ oo::objdefine Aobject filter logFilter
+ set result {}
+ lappend result [Aobject concatenate 1 2 3 4 5]
+ Aclass destroy
+ return $result
+} {{calling ::Aobject->logFilter 1 2 3 4 5} 1 2 3 4 5 result=12345 12345}
+test oo-12.2 {OO: filters} -setup {
+ oo::class create Aclass
+ Aclass create Aobject
+} -body {
+ oo::define Aclass {
+ method concatenate args {
+ global result
+ lappend result {*}$args
+ join $args {}
+ }
+ method logFilter args {
+ global result
+ lappend result "calling [self object]->[self method] $args"
+ set r [next {*}$args]
+ lappend result "result=$r"
+ return $r
+ }
+ }
+ oo::objdefine Aobject filter logFilter
+ set result {}
+ lappend result [Aobject concatenate 1 2 3 4 5] [Aobject destroy]
+} -cleanup {
+ Aclass destroy
+} -result {{calling ::Aobject->logFilter 1 2 3 4 5} 1 2 3 4 5 result=12345 {calling ::Aobject->logFilter } result= 12345 {}}
+test oo-12.3 {OO: filters} -setup {
+ oo::class create Aclass
+ Aclass create Aobject
+} -body {
+ oo::define Aclass {
+ method concatenate args {
+ global result
+ lappend result {*}$args
+ join $args {}
+ }
+ method logFilter args {
+ global result
+ lappend result "calling [self object]->[self method] $args"
+ set r [next {*}$args]
+ lappend result "result=$r"
+ return $r
+ }
+ filter logFilter
+ }
+ set result {}
+ lappend result [Aobject concatenate 1 2 3 4 5] [Aobject destroy]
+} -cleanup {
+ Aclass destroy
+} -result {{calling ::Aobject->logFilter 1 2 3 4 5} 1 2 3 4 5 result=12345 {calling ::Aobject->logFilter } result= 12345 {}}
+test oo-12.4 {OO: filters} -setup {
+ oo::class create Aclass
+ Aclass create Aobject
+} -body {
+ oo::define Aclass {
+ method foo {} { return foo }
+ method Bar {} { return 1 }
+ method boo {} { if {[my Bar]} { next } { error forbidden } }
+ filter boo
+ }
+ Aobject foo
+} -cleanup {
+ Aclass destroy
+} -result foo
+test oo-12.5 {OO: filters} -setup {
+ oo::class create Aclass
+ Aclass create Aobject
+} -body {
+ oo::define Aclass {
+ method foo {} { return foo }
+ method Bar {} { return [my Bar2] }
+ method Bar2 {} { return 1 }
+ method boo {} { if {[my Bar]} { next } { error forbidden } }
+ filter boo
+ }
+ Aobject foo
+} -cleanup {
+ Aclass destroy
+} -result foo
+test oo-12.6 {OO: filters} -setup {
+ oo::class create Aclass
+ Aclass create Aobject
+} -body {
+ oo::define Aclass {
+ method foo {} { return foo }
+ method Bar {} { return [my Bar2] }
+ method Bar2 {} { return [my Bar3] }
+ method Bar3 {} { return 1 }
+ method boo {} { if {[my Bar]} { next } { error forbidden } }
+ filter boo
+ }
+ Aobject foo
+} -cleanup {
+ Aclass destroy
+} -result foo
+test oo-12.7 {OO: filters} -setup {
+ oo::class create Aclass
+ Aclass create Aobject
+} -body {
+ oo::define Aclass {
+ method outerfoo {} { return [my InnerFoo] }
+ method InnerFoo {} { return foo }
+ method Bar {} { return [my Bar2] }
+ method Bar2 {} { return [my Bar3] }
+ method Bar3 {} { return 1 }
+ method boo {} {
+ lappend ::log [self target]
+ if {[my Bar]} { next } else { error forbidden }
+ }
+ filter boo
+ }
+ set log {}
+ list [Aobject outerfoo] $log
+} -cleanup {
+ Aclass destroy
+} -result {foo {{::Aclass outerfoo} {::Aclass InnerFoo}}}
+
+test oo-13.1 {OO: changing an object's class} {
+ oo::class create Aclass
+ oo::define Aclass {method bar {} {lappend ::result "in A [self object]"}}
+ oo::class create Bclass
+ oo::define Bclass {method bar {} {lappend ::result "in B [self object]"}}
+ set result [Aclass create foo]
+ foo bar
+ oo::objdefine foo class Bclass
+ foo bar
+ Aclass destroy
+ lappend result [info command foo]
+ Bclass destroy
+ return $result
+} {::foo {in A ::foo} {in B ::foo} foo}
+test oo-13.2 {OO: changing an object's class} -body {
+ oo::object create foo
+ oo::objdefine foo class oo::class
+} -cleanup {
+ foo destroy
+} -returnCodes 1 -result {may not change a non-class object into a class object}
+test oo-13.3 {OO: changing an object's class} -body {
+ oo::class create foo
+ oo::objdefine foo class oo::object
+} -cleanup {
+ foo destroy
+} -returnCodes 1 -result {may not change a class object into a non-class object}
+test oo-13.4 {OO: changing an object's class} -body {
+ oo::class create foo {
+ method m {} {
+ set result [list [self class] [info object class [self]]]
+ oo::objdefine [self] class ::bar
+ lappend result [self class] [info object class [self]]
+ }
+ }
+ oo::class create bar
+ [foo new] m
+} -cleanup {
+ foo destroy
+ bar destroy
+} -result {::foo ::foo ::foo ::bar}
+# todo: changing a class subtype (metaclass) to another class subtype
+
+test oo-14.1 {OO: mixins} {
+ oo::class create Aclass
+ oo::define Aclass method bar {} {lappend ::result "[self object] in bar"}
+ oo::class create Bclass
+ oo::define Bclass method boo {} {lappend ::result "[self object] in boo"}
+ oo::objdefine [Aclass create fooTest] mixin Bclass
+ oo::objdefine [Aclass create fooTest2] mixin Bclass
+ set result [list [catch {fooTest ?} msg] $msg]
+ fooTest bar
+ fooTest boo
+ fooTest2 bar
+ fooTest2 boo
+ oo::objdefine fooTest2 mixin
+ lappend result [Bclass destroy] [info command fooTest*] [Aclass destroy]
+} {1 {unknown method "?": must be bar, boo or destroy} {::fooTest in bar} {::fooTest in boo} {::fooTest2 in bar} {::fooTest2 in boo} {} fooTest2 {}}
+test oo-14.2 {OO: mixins} {
+ oo::class create Aclass {
+ method bar {} {return "[self object] in bar"}
+ }
+ oo::class create Bclass {
+ method boo {} {return "[self object] in boo"}
+ }
+ oo::define Aclass mixin Bclass
+ Aclass create fooTest
+ set result [list [catch {fooTest ?} msg] $msg]
+ lappend result [catch {fooTest bar} msg] $msg
+ lappend result [catch {fooTest boo} msg] $msg
+ lappend result [Bclass destroy] [info commands Aclass]
+} {1 {unknown method "?": must be bar, boo or destroy} 0 {::fooTest in bar} 0 {::fooTest in boo} {} {}}
+test oo-14.3 {OO and mixins and filters - advanced case} -setup {
+ oo::class create mix
+ oo::class create c {
+ mixin mix
+ }
+ c create i
+} -body {
+ oo::define mix {
+ method foo {} {return >>[next]<<}
+ filter foo
+ }
+ oo::objdefine i method bar {} {return foobar}
+ i bar
+} -cleanup {
+ mix destroy
+ if {[info object isa object i]} {
+ error "mixin deletion failed to destroy dependent instance"
+ }
+} -result >>foobar<<
+test oo-14.4 {OO: mixin error case} -setup {
+ oo::class create c
+} -body {
+ oo::define c mixin c
+} -returnCodes error -cleanup {
+ c destroy
+} -result {may not mix a class into itself}
+test oo-14.5 {OO and mixins and filters - advanced case} -setup {
+ oo::class create mix
+ oo::class create c {
+ mixin mix
+ }
+ c create i
+} -body {
+ oo::define mix {
+ method foo {} {return >>[next]<<}
+ filter foo
+ }
+ oo::objdefine i method bar {} {return foobar}
+ i bar
+} -cleanup {
+ c destroy
+ mix destroy
+} -result >>foobar<<
+test oo-14.6 {OO and mixins of mixins - Bug 1960703} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create A {
+ superclass master
+ method egg {} {
+ return chicken
+ }
+ }
+ oo::class create B {
+ superclass master
+ mixin A
+ method bar {} {
+ # mixin from A
+ my egg
+ }
+ }
+ oo::class create C {
+ superclass master
+ mixin B
+ method foo {} {
+ # mixin from B
+ my bar
+ }
+ }
+ [C new] foo
+} -result chicken
+test oo-14.7 {OO and filters from mixins of mixins} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create A {
+ superclass master
+ method egg {} {
+ return chicken
+ }
+ filter f
+ method f args {
+ set m [lindex [self target] 1]
+ return "($m) [next {*}$args] ($m)"
+ }
+ }
+ oo::class create B {
+ superclass master
+ mixin A
+ filter f
+ method bar {} {
+ # mixin from A
+ my egg
+ }
+ }
+ oo::class create C {
+ superclass master
+ mixin B
+ filter f
+ method foo {} {
+ # mixin from B
+ my bar
+ }
+ }
+ [C new] foo
+} -result {(foo) (bar) (egg) chicken (egg) (bar) (foo)}
+test oo-14.8 {OO: class mixin order - Bug 1998221} -setup {
+ set ::result {}
+ oo::class create master {
+ method test {} {}
+ }
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create mix {
+ superclass master
+ method test {} {lappend ::result mix; next; return $::result}
+ }
+ oo::class create cls {
+ superclass master
+ mixin mix
+ method test {} {lappend ::result cls; next; return $::result}
+ }
+ [cls new] test
+} -result {mix cls}
+
+test oo-15.1 {OO: object cloning} {
+ oo::class create Aclass
+ oo::define Aclass method test {} {lappend ::result [self object]->test}
+ Aclass create Ainstance
+ set result {}
+ Ainstance test
+ oo::copy Ainstance Binstance
+ Binstance test
+ Ainstance test
+ Ainstance destroy
+ namespace eval foo {
+ oo::copy Binstance Cinstance
+ Cinstance test
+ }
+ Aclass destroy
+ namespace delete foo
+ lappend result [info commands Binstance]
+} {::Ainstance->test ::Binstance->test ::Ainstance->test ::foo::Cinstance->test {}}
+test oo-15.2 {OO: object cloning} {
+ oo::object create foo
+ oo::objdefine foo {
+ method m x {lappend ::result [self object] >$x<}
+ forward f ::lappend ::result fwd
+ }
+ set result {}
+ foo m 1
+ foo f 2
+ lappend result [oo::copy foo bar]
+ foo m 3
+ foo f 4
+ bar m 5
+ bar f 6
+ lappend result [foo destroy]
+ bar m 7
+ bar f 8
+ lappend result [bar destroy]
+} {::foo >1< fwd 2 ::bar ::foo >3< fwd 4 ::bar >5< fwd 6 {} ::bar >7< fwd 8 {}}
+catch {foo destroy}
+catch {bar destroy}
+test oo-15.3 {OO: class cloning} {
+ oo::class create foo {
+ method testme {} {lappend ::result [self class]->[self object]}
+ }
+ set result {}
+ foo create baseline
+ baseline testme
+ oo::copy foo bar
+ baseline testme
+ bar create tester
+ tester testme
+ foo destroy
+ tester testme
+ bar destroy
+ return $result
+} {::foo->::baseline ::foo->::baseline ::bar->::tester ::bar->::tester}
+test oo-15.4 {OO: object cloning - Bug 3474460} -setup {
+ oo::class create ArbitraryClass
+} -body {
+ ArbitraryClass create foo
+ oo::objdefine foo variable a b c
+ oo::copy foo bar
+ info object variable bar
+} -cleanup {
+ ArbitraryClass destroy
+} -result {a b c}
+test oo-15.5 {OO: class cloning - Bug 3474460} -setup {
+ oo::class create ArbitraryClass
+} -body {
+ oo::class create Foo {
+ superclass ArbitraryClass
+ variable a b c
+ }
+ oo::copy Foo Bar
+ info class variable Bar
+} -cleanup {
+ ArbitraryClass destroy
+} -result {a b c}
+test oo-15.6 {OO: object cloning copies namespace contents} -setup {
+ oo::class create ArbitraryClass {export eval}
+} -body {
+ ArbitraryClass create a
+ a eval {proc foo x {
+ variable y
+ return [string repeat $x [incr y]]
+ }}
+ set result [list [a eval {foo 2}] [a eval {foo 3}]]
+ oo::copy a b
+ a eval {rename foo bar}
+ lappend result [b eval {foo 2}] [b eval {foo 3}] [a eval {bar 4}]
+} -cleanup {
+ ArbitraryClass destroy
+} -result {2 33 222 3333 444}
+test oo-15.7 {OO: classes can be cloned anonymously} -setup {
+ oo::class create ArbitraryClassA
+ oo::class create ArbitraryClassB {superclass ArbitraryClassA}
+} -body {
+ info object isa class [oo::copy ArbitraryClassB]
+} -cleanup {
+ ArbitraryClassA destroy
+} -result 1
+test oo-15.8 {OO: intercept object cloning} -setup {
+ oo::class create Foo
+ set result {}
+} -body {
+ oo::define Foo {
+ constructor {msg} {
+ variable v $msg
+ }
+ method <cloned> {from} {
+ next $from
+ lappend ::result cloned $from [self]
+ }
+ method check {} {
+ variable v
+ lappend ::result check [self] $v
+ }
+ }
+ Foo create foo ok
+ oo::copy foo bar
+ foo check
+ bar check
+} -cleanup {
+ Foo destroy
+} -result {cloned ::foo ::bar check ::foo ok check ::bar ok}
+test oo-15.9 {ensemble rewriting must not bleed through oo::copy} -setup {
+ oo::class create Foo
+} -body {
+ oo::define Foo {
+ method <cloned> {a b} {}
+ }
+ interp alias {} Bar {} oo::copy [Foo create foo]
+ Bar bar
+} -returnCodes error -cleanup {
+ Foo destroy
+} -result {wrong # args: should be "::bar <cloned> a b"}
+
+test oo-16.1 {OO: object introspection} -body {
+ info object
+} -returnCodes 1 -result "wrong \# args: should be \"info object subcommand ?arg ...?\""
+test oo-16.2 {OO: object introspection} -body {
+ info object class NOTANOBJECT
+} -returnCodes 1 -result {NOTANOBJECT does not refer to an object}
+test oo-16.3 {OO: object introspection} -body {
+ info object gorp oo::object
+} -returnCodes 1 -result {unknown or ambiguous subcommand "gorp": must be call, class, definition, filters, forward, isa, methods, methodtype, mixins, namespace, variables, or vars}
+test oo-16.4 {OO: object introspection} -setup {
+ oo::class create meta { superclass oo::class }
+ [meta create instance1] create instance2
+} -body {
+ list [list [info object class oo::object] \
+ [info object class oo::class] \
+ [info object class meta] \
+ [info object class instance1] \
+ [info object class instance2]] \
+ [list [info object isa class oo::object] \
+ [info object isa class meta] \
+ [info object isa class instance1] \
+ [info object isa class instance2]] \
+ [list [info object isa metaclass oo::object] \
+ [info object isa metaclass oo::class] \
+ [info object isa metaclass meta] \
+ [info object isa metaclass instance1] \
+ [info object isa metaclass instance2]] \
+ [list [info object isa object oo::object] \
+ [info object isa object oo::class] \
+ [info object isa object meta] \
+ [info object isa object instance1] \
+ [info object isa object instance2] \
+ [info object isa object oo::define] \
+ [info object isa object NOTANOBJECT]]
+} -cleanup {
+ meta destroy
+} -result {{::oo::class ::oo::class ::oo::class ::meta ::instance1} {1 1 1 0} {0 1 1 0 0} {1 1 1 1 1 0 0}}
+test oo-16.5 {OO: object introspection} {info object methods oo::object} {}
+test oo-16.6 {OO: object introspection} {
+ oo::object create foo
+ set result [list [info object methods foo]]
+ oo::objdefine foo method bar {} {...}
+ lappend result [info object methods foo] [foo destroy]
+} {{} bar {}}
+test oo-16.7 {OO: object introspection} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo method bar {a {b c} args} {the body}
+ set result [info object methods foo]
+ lappend result [info object methodtype foo bar] \
+ [info object definition foo bar]
+} -cleanup {
+ foo destroy
+} -result {bar method {{a {b c} args} {the body}}}
+test oo-16.8 {OO: object introspection} {
+ oo::object create foo
+ oo::class create bar
+ oo::objdefine foo mixin bar
+ set result [list [info object mixins foo] \
+ [info object isa mixin foo bar] \
+ [info object isa mixin foo oo::class]]
+ foo destroy
+ bar destroy
+ return $result
+} {::bar 1 0}
+test oo-16.9 {OO: object introspection} -body {
+ oo::class create Ac
+ oo::class create Bc; oo::define Bc superclass Ac
+ oo::class create Cc; oo::define Cc superclass Bc
+ oo::class create Dc; oo::define Dc mixin Cc
+ Cc create E
+ Dc create F
+ list [info object isa typeof E oo::class] \
+ [info object isa typeof E Ac] \
+ [info object isa typeof F Bc] \
+ [info object isa typeof F Cc]
+} -cleanup {
+ catch {Ac destroy}
+} -result {0 1 1 1}
+test oo-16.10 {OO: object introspection} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo export eval
+ foo eval {variable c 3 a 1 b 2 ddd 4 e}
+ lsort [info object vars foo ?]
+} -cleanup {
+ foo destroy
+} -result {a b c}
+test oo-16.11 {OO: object introspection} -setup {
+ oo::class create foo
+ foo create bar
+} -body {
+ oo::define foo method spong {} {...}
+ oo::objdefine bar method boo {a {b c} args} {the body}
+ list [lsort [info object methods bar -all]] [lsort [info object methods bar -all -private]]
+} -cleanup {
+ foo destroy
+} -result {{boo destroy spong} {<cloned> boo destroy eval spong unknown variable varname}}
+test oo-16.12 {OO: object introspection} -setup {
+ oo::object create foo
+} -cleanup {
+ rename foo {}
+} -body {
+ oo::objdefine foo unexport {*}[info object methods foo -all]
+ info object methods foo -all
+} -result {}
+test oo-16.13 {OO: object introspection} -setup {
+ oo::object create foo
+} -cleanup {
+ rename foo {}
+} -body {
+ oo::objdefine foo method Bar {} {return "ok in foo"}
+ [info object namespace foo]::my Bar
+} -result "ok in foo"
+
+test oo-17.1 {OO: class introspection} -body {
+ info class
+} -returnCodes 1 -result "wrong \# args: should be \"info class subcommand ?arg ...?\""
+test oo-17.2 {OO: class introspection} -body {
+ info class superclass NOTANOBJECT
+} -returnCodes 1 -result {NOTANOBJECT does not refer to an object}
+test oo-17.3 {OO: class introspection} -setup {
+ oo::object create foo
+} -body {
+ info class superclass foo
+} -returnCodes 1 -cleanup {
+ foo destroy
+} -result {"foo" is not a class}
+test oo-17.4 {OO: class introspection} -body {
+ info class gorp oo::object
+} -returnCodes 1 -result {unknown or ambiguous subcommand "gorp": must be call, constructor, definition, destructor, filters, forward, instances, methods, methodtype, mixins, subclasses, superclasses, or variables}
+test oo-17.5 {OO: class introspection} -setup {
+ oo::class create testClass
+} -body {
+ testClass create foo
+ testClass create bar
+ testClass create spong
+ lsort [info class instances testClass]
+} -cleanup {
+ testClass destroy
+} -result {::bar ::foo ::spong}
+test oo-17.6 {OO: class introspection} -setup {
+ oo::class create foo
+} -body {
+ oo::define foo method bar {a {b c} args} {the body}
+ set result [info class methods foo]
+ lappend result [info class methodtype foo bar] \
+ [info class definition foo bar]
+} -cleanup {
+ foo destroy
+} -result {bar method {{a {b c} args} {the body}}}
+test oo-17.7 {OO: class introspection} {
+ info class superclasses oo::class
+} ::oo::object
+test oo-17.8 {OO: class introspection} -setup {
+ oo::class create testClass
+ oo::class create superClass1
+ oo::class create superClass2
+} -body {
+ oo::define testClass superclass superClass1 superClass2
+ list [info class superclasses testClass] \
+ [lsort [info class subclass oo::object ::superClass?]]
+} -cleanup {
+ testClass destroy
+ superClass1 destroy
+ superClass2 destroy
+} -result {{::superClass1 ::superClass2} {::superClass1 ::superClass2}}
+test oo-17.9 {OO: class introspection} -setup {
+ oo::class create foo
+ oo::class create subfoo {superclass foo}
+} -body {
+ oo::define foo {
+ method bar {a {b c} args} {the body}
+ self {
+ method bad {} {...}
+ }
+ }
+ oo::define subfoo method boo {a {b c} args} {the body}
+ list [lsort [info class methods subfoo -all]] \
+ [lsort [info class methods subfoo -all -private]]
+} -cleanup {
+ foo destroy
+} -result {{bar boo destroy} {<cloned> bar boo destroy eval unknown variable varname}}
+test oo-17.10 {OO: class introspection} -setup {
+ oo::class create foo
+} -cleanup {
+ rename foo {}
+} -body {
+ oo::define foo unexport {*}[info class methods foo -all]
+ info class methods foo -all
+} -result {}
+
+test oo-18.1 {OO: define command support} {
+ list [catch {oo::define oo::object {error foo}} msg] $msg $errorInfo
+} {1 foo {foo
+ while executing
+"error foo"
+ (in definition script for class "::oo::object" line 1)
+ invoked from within
+"oo::define oo::object {error foo}"}}
+test oo-18.2 {OO: define command support} {
+ list [catch {oo::define oo::object error foo} msg] $msg $errorInfo
+} {1 foo {foo
+ while executing
+"oo::define oo::object error foo"}}
+test oo-18.3 {OO: define command support} {
+ list [catch {oo::class create foo {error bar}} msg] $msg $errorInfo
+} {1 bar {bar
+ while executing
+"error bar"
+ (in definition script for class "::foo" line 1)
+ invoked from within
+"oo::class create foo {error bar}"}}
+test oo-18.3a {OO: define command support} {
+ list [catch {oo::class create foo {
+ error bar
+}} msg] $msg $errorInfo
+} {1 bar {bar
+ while executing
+"error bar"
+ (in definition script for class "::foo" line 2)
+ invoked from within
+"oo::class create foo {
+ error bar
+}"}}
+test oo-18.3b {OO: define command support} {
+ list [catch {oo::class create foo {
+ eval eval error bar
+}} msg] $msg $errorInfo
+} {1 bar {bar
+ while executing
+"error bar"
+ ("eval" body line 1)
+ invoked from within
+"eval error bar"
+ ("eval" body line 1)
+ invoked from within
+"eval eval error bar"
+ (in definition script for class "::foo" line 2)
+ invoked from within
+"oo::class create foo {
+ eval eval error bar
+}"}}
+test oo-18.4 {OO: more error traces from the guts} -setup {
+ oo::object create obj
+} -body {
+ oo::objdefine obj method bar {} {my eval {error foo}}
+ list [catch {obj bar} msg] $msg $errorInfo
+} -cleanup {
+ obj destroy
+} -result {1 foo {foo
+ while executing
+"error foo"
+ (in "my eval" script line 1)
+ invoked from within
+"my eval {error foo}"
+ (object "::obj" method "bar" line 1)
+ invoked from within
+"obj bar"}}
+test oo-18.5 {OO: more error traces from the guts} -setup {
+ [oo::class create cls] create obj
+ set errorInfo {}
+} -body {
+ oo::define cls {
+ method eval script {next $script}
+ export eval
+ }
+ oo::objdefine obj method bar {} {my eval {error foo}}
+ set result {}
+ lappend result [catch {obj bar} msg] $msg $errorInfo
+ lappend result [catch {obj eval {error bar}} msg] $msg $errorInfo
+} -cleanup {
+ cls destroy
+} -result {1 foo {foo
+ while executing
+"error foo"
+ (in "my eval" script line 1)
+ invoked from within
+"next $script"
+ (class "::cls" method "eval" line 1)
+ invoked from within
+"my eval {error foo}"
+ (object "::obj" method "bar" line 1)
+ invoked from within
+"obj bar"} 1 bar {bar
+ while executing
+"error bar"
+ (in "::obj eval" script line 1)
+ invoked from within
+"next $script"
+ (class "::cls" method "eval" line 1)
+ invoked from within
+"obj eval {error bar}"}}
+test oo-18.6 {class construction reference management and errors} -setup {
+ oo::class create super_abc
+} -body {
+ catch {
+oo::class create abc {
+ superclass super_abc
+ ::rename abc ::def
+ ::error foo
+}
+ } msg opt
+ dict get $opt -errorinfo
+} -cleanup {
+ super_abc destroy
+} -result {foo
+ while executing
+"::error foo"
+ (in definition script for class "::def" line 4)
+ invoked from within
+"oo::class create abc {
+ superclass super_abc
+ ::rename abc ::def
+ ::error foo
+}"}
+test oo-18.7 {OO: objdefine command support} -setup {
+ oo::object create ::inst
+} -body {
+ list [catch {oo::objdefine inst {rename ::inst ::INST;error foo}} msg] $msg $errorInfo
+} -cleanup {
+ catch {::inst destroy}
+ catch {::INST destroy}
+} -result {1 foo {foo
+ while executing
+"error foo"
+ (in definition script for object "::INST" line 1)
+ invoked from within
+"oo::objdefine inst {rename ::inst ::INST;error foo}"}}
+test oo-18.8 {OO: define/self command support} -setup {
+ oo::class create master
+ oo::class create ::foo {superclass master}
+} -body {
+ catch {oo::define foo {rename ::foo ::bar; self {error foobar}}} msg opt
+ dict get $opt -errorinfo
+} -cleanup {
+ master destroy
+} -result {foobar
+ while executing
+"error foobar"
+ (in definition script for class object "::bar" line 1)
+ invoked from within
+"self {error foobar}"
+ (in definition script for class "::bar" line 1)
+ invoked from within
+"oo::define foo {rename ::foo ::bar; self {error foobar}}"}
+test oo-18.9 {OO: define/self command support} -setup {
+ oo::class create master
+ set c [oo::class create now_this_is_a_very_very_long_class_name_indeed {
+ superclass master
+ }]
+} -body {
+ catch {oo::define $c {error err}} msg opt
+ dict get $opt -errorinfo
+} -cleanup {
+ master destroy
+} -result {err
+ while executing
+"error err"
+ (in definition script for class "::now_this_is_a_very_very_long..." line 1)
+ invoked from within
+"oo::define $c {error err}"}
+test oo-18.10 {OO: define/self command support} -setup {
+ oo::class create master
+ oo::class create ::foo {superclass master}
+} -body {
+ catch {oo::define foo {self {rename ::foo {}; error foobar}}} msg opt
+ dict get $opt -errorinfo
+} -cleanup {
+ master destroy
+} -result {foobar
+ while executing
+"error foobar"
+ (in definition script for class object "::foo" line 1)
+ invoked from within
+"self {rename ::foo {}; error foobar}"
+ (in definition script for class "::foo" line 1)
+ invoked from within
+"oo::define foo {self {rename ::foo {}; error foobar}}"}
+test oo-18.11 {OO: define/self command support} -setup {
+ oo::class create master
+ oo::class create ::foo {superclass master}
+} -body {
+ catch {oo::define foo {rename ::foo {}; self {error foobar}}} msg opt
+ dict get $opt -errorinfo
+} -cleanup {
+ master destroy
+} -result {this command cannot be called when the object has been deleted
+ while executing
+"self {error foobar}"
+ (in definition script for class "::foo" line 1)
+ invoked from within
+"oo::define foo {rename ::foo {}; self {error foobar}}"}
+
+test oo-19.1 {OO: varname method} -setup {
+ oo::object create inst
+ oo::objdefine inst export eval
+ set result {}
+ inst eval { variable x }
+} -body {
+ inst eval {trace add variable x write foo}
+ set ns [inst eval namespace current]
+ proc foo args {
+ global ns result
+ set context [uplevel 1 namespace current]
+ lappend result $args [expr {
+ $ns eq $context ? "ok" : [list $ns ne $context]
+ }] [expr {
+ "${ns}::x" eq [uplevel 1 my varname x] ? "ok" : [list ${ns}::x ne [uplevel 1 my varname x]]
+ }]
+ }
+ lappend result [inst eval set x 0]
+} -cleanup {
+ inst destroy
+ rename foo {}
+} -result {{x {} write} ok ok 0}
+test oo-19.2 {OO: varname method: Bug 2883857} -setup {
+ oo::class create SpecialClass
+ oo::objdefine SpecialClass export createWithNamespace
+ SpecialClass createWithNamespace inst ::oo_test
+ oo::objdefine inst export varname eval
+} -body {
+ inst eval { variable x; array set x {y z} }
+ inst varname x(y)
+} -cleanup {
+ SpecialClass destroy
+} -result ::oo_test::x(y)
+
+test oo-20.1 {OO: variable method} -body {
+ oo::class create testClass {
+ constructor {} {
+ my variable ok
+ set ok {}
+ }
+ }
+ lsort [info object vars [testClass new]]
+} -cleanup {
+ catch {testClass destroy}
+} -result ok
+test oo-20.2 {OO: variable method} -body {
+ oo::class create testClass {
+ constructor {} {
+ my variable a b c
+ set a [set b [set c {}]]
+ }
+ }
+ lsort [info object vars [testClass new]]
+} -cleanup {
+ catch {testClass destroy}
+} -result {a b c}
+test oo-20.3 {OO: variable method} -body {
+ oo::class create testClass {
+ export varname
+ method bar {} {
+ my variable a(b)
+ }
+ }
+ testClass create foo
+ array set [foo varname a] {b c}
+ foo bar
+} -returnCodes 1 -cleanup {
+ catch {testClass destroy}
+} -result {can't define "a(b)": name refers to an element in an array}
+test oo-20.4 {OO: variable method} -body {
+ oo::class create testClass {
+ export varname
+ method bar {} {
+ my variable a(b)
+ }
+ }
+ testClass create foo
+ set [foo varname a] b
+ foo bar
+} -returnCodes 1 -cleanup {
+ catch {testClass destroy}
+} -result {can't define "a(b)": name refers to an element in an array}
+test oo-20.5 {OO: variable method} -body {
+ oo::class create testClass {
+ method bar {} {
+ my variable a::b
+ }
+ }
+ testClass create foo
+ foo bar
+} -returnCodes 1 -cleanup {
+ catch {testClass destroy}
+} -result {variable name "a::b" illegal: must not contain namespace separator}
+test oo-20.6 {OO: variable method} -setup {
+ oo::class create testClass {
+ export varname
+ self export eval
+ }
+} -body {
+ testClass eval variable a 0
+ oo::objdefine [testClass create foo] method bar {other} {
+ $other variable a
+ set a 3
+ }
+ oo::objdefine [testClass create boo] export variable
+ set [foo varname a] 1
+ set [boo varname a] 2
+ foo bar boo
+ list [testClass eval set a] [set [foo varname a]] [set [boo varname a]]
+} -cleanup {
+ testClass destroy
+} -result {0 1 3}
+test oo-20.7 {OO: variable method} -setup {
+ oo::class create cls
+} -body {
+ oo::define cls {
+ method a {} {
+ my variable d b
+ lappend b $d
+ }
+ method e {} {
+ my variable b d
+ return [list $b $d]
+ }
+ method f {x y} {
+ my variable b d
+ set b $x
+ set d $y
+ }
+ }
+ cls create obj
+ obj f p q
+ obj a
+ obj a
+ obj e
+} -cleanup {
+ cls destroy
+} -result {{p q q} q}
+# oo-20.8 tested explicitly for functionality removed due to [Bug 1959457]
+test oo-20.9 {OO: variable method} -setup {
+ oo::object create obj
+} -body {
+ oo::objdefine obj {
+ method a {} {
+ my variable ::b
+ }
+ }
+ obj a
+} -returnCodes 1 -cleanup {
+ obj destroy
+} -result {variable name "::b" illegal: must not contain namespace separator}
+test oo-20.10 {OO: variable and varname methods refer to same things} -setup {
+ oo::object create obj
+} -body {
+ oo::objdefine obj {
+ method a {} {
+ my variable b
+ set b [self]
+ return [my varname b]
+ }
+ }
+ list [set [obj a]] [namespace tail [obj a]]
+} -cleanup {
+ obj destroy
+} -result {::obj b}
+test oo-20.11 {OO: variable mustn't crash when recursing} -body {
+ oo::class create A {
+ constructor {name} {
+ my variable np_name
+ set np_name $name
+ }
+ method copy {nm} {
+ set cpy [[info object class [self]] new $nm]
+ foreach var [info object vars [self]] {
+ my variable $var
+ set val [set $var]
+ if {[string match o_* $var]} {
+ set objs {}
+ foreach ref $val {
+ # call to "copy" crashes
+ lappend objs [$ref copy {}]
+ }
+ $cpy prop $var $objs
+ } else {
+ $cpy prop $var $val
+ }
+ }
+ return $cpy
+ }
+ method prop {name val} {
+ my variable $name
+ set $name $val
+ }
+ }
+ set o1 [A new {}]
+ set o2 [A new {}]
+ $o1 prop o_object $o2
+ $o1 copy aa
+} -cleanup {
+ catch {A destroy}
+} -match glob -result *
+test oo-20.12 {OO: variable method accept zero args (TIP 323)} -setup {
+ oo::object create foo
+} -cleanup {
+ foo destroy
+} -body {
+ oo::objdefine foo method demo {} {
+ my variable
+ }
+ foo demo
+} -result {}
+test oo-20.13 {OO: variable method use in non-methods [Bug 2903811]} -setup {
+ oo::object create fooObj
+ oo::objdefine fooObj export variable
+} -cleanup {
+ fooObj destroy
+} -body {
+ apply {{} {fooObj variable x; set x ok; return}}
+ apply {{} {fooObj variable x; return $x}}
+} -result ok
+test oo-20.14 {OO: variable method use in non-methods [Bug 2903811]} -setup {
+ oo::object create fooObj
+ oo::objdefine fooObj export variable
+ namespace eval ns1 {}
+ namespace eval ns2 {}
+ set x bad
+} -cleanup {
+ fooObj destroy
+ namespace delete ns1 ns2
+ unset x
+} -body {
+ namespace eval ns1 {fooObj variable x; set x ok; subst ""}
+ set x bad
+ namespace eval ns2 {fooObj variable x; return $x}
+} -result ok
+test oo-20.15 {OO: variable method use in non-methods [Bug 2903811]} -setup {
+ oo::object create fooObj
+ oo::objdefine fooObj export variable varname
+} -cleanup {
+ fooObj destroy
+} -body {
+ apply {{} {fooObj variable x; set x ok; return}}
+ return [set [fooObj varname x]]
+} -result ok
+test oo-20.16 {variable method: leak per instance} -setup {
+ oo::class create foo
+} -constraints memory -body {
+ oo::define foo {
+ constructor {} {
+ set [my variable v] 0
+ }
+ }
+ leaktest {[foo new] destroy}
+} -cleanup {
+ foo destroy
+} -result 0
+
+test oo-21.1 {OO: inheritance ordering} -setup {
+ oo::class create A
+} -body {
+ oo::define A method m {} {lappend ::result A}
+ oo::class create B {
+ superclass A
+ method m {} {lappend ::result B;next}
+ }
+ oo::class create C {
+ superclass A
+ method m {} {lappend ::result C;next}
+ }
+ oo::class create D {
+ superclass B C
+ method m {} {lappend ::result D;next}
+ }
+ D create o
+ oo::objdefine o method m {} {lappend ::result o;next}
+ set result {}
+ o m
+ return $result
+} -cleanup {
+ A destroy
+} -result {o D B C A}
+test oo-21.2 {OO: inheritance ordering} -setup {
+ oo::class create A
+} -body {
+ oo::define A method m {} {lappend ::result A}
+ oo::class create B {
+ superclass A
+ method m {} {lappend ::result B;next}
+ }
+ oo::class create C {
+ superclass A
+ method m {} {lappend ::result C;next}
+ }
+ oo::class create D {
+ superclass B C
+ method m {} {lappend ::result D;next}
+ }
+ oo::class create Emix {
+ superclass C
+ method m {} {lappend ::result Emix;next}
+ }
+ oo::class create Fmix {
+ superclass Emix
+ method m {} {lappend ::result Fmix;next}
+ }
+ D create o
+ oo::objdefine o {
+ method m {} {lappend ::result o;next}
+ mixin Fmix
+ }
+ set result {}
+ o m
+ return $result
+} -cleanup {
+ A destroy
+} -result {Fmix Emix o D B C A}
+test oo-21.3 {OO: inheritance ordering} -setup {
+ oo::class create A
+} -body {
+ oo::define A method m {} {lappend ::result A}
+ oo::class create B {
+ superclass A
+ method m {} {lappend ::result B;next}
+ method f {} {lappend ::result B-filt;next}
+ }
+ oo::class create C {
+ superclass A
+ method m {} {lappend ::result C;next}
+ }
+ oo::class create D {
+ superclass B C
+ method m {} {lappend ::result D;next}
+ }
+ oo::class create Emix {
+ superclass C
+ method m {} {lappend ::result Emix;next}
+ method f {} {lappend ::result Emix-filt;next}
+ }
+ oo::class create Fmix {
+ superclass Emix
+ method m {} {lappend ::result Fmix;next}
+ }
+ D create o
+ oo::objdefine o {
+ method m {} {lappend ::result o;next}
+ mixin Fmix
+ filter f
+ }
+ set result {}
+ o m
+ return $result
+} -cleanup {
+ A destroy
+} -result {Emix-filt B-filt Fmix Emix o D B C A}
+test oo-21.4 {OO: inheritance ordering} -setup {
+ oo::class create A
+} -body {
+ oo::define A method m {} {lappend ::result A}
+ oo::class create B {
+ superclass A
+ method m {} {lappend ::result B;next}
+ method f {} {lappend ::result B-filt;next}
+ method g {} {lappend ::result B-cfilt;next}
+ }
+ oo::class create C {
+ superclass A
+ method m {} {lappend ::result C;next}
+ }
+ oo::class create D {
+ superclass B C
+ method m {} {lappend ::result D;next}
+ method g {} {lappend ::result D-cfilt;next}
+ filter g
+ }
+ oo::class create Emix {
+ superclass C
+ method m {} {lappend ::result Emix;next}
+ method f {} {lappend ::result Emix-filt;next}
+ }
+ oo::class create Fmix {
+ superclass Emix
+ method m {} {lappend ::result Fmix;next}
+ }
+ D create o
+ oo::objdefine o {
+ method m {} {lappend ::result o;next}
+ mixin Fmix
+ filter f
+ }
+ set result {}
+ o m
+ return $result
+} -cleanup {
+ A destroy
+} -result {Emix-filt B-filt D-cfilt B-cfilt Fmix Emix o D B C A}
+
+test oo-22.1 {OO and info frame} -setup {
+ oo::class create c
+ c create i
+} -match glob -body {
+ oo::define c self method frame {} {
+ info frame 0
+ }
+ oo::define c {
+ method frames {} {
+ info frame 0
+ }
+ method level {} {
+ info frame
+ }
+ }
+ oo::objdefine i {
+ method frames {} {
+ list [next] [info frame 0]
+ }
+ method level {} {
+ expr {[next] - [info frame]}
+ }
+ }
+ list [i level] [i frames] [dict get [c frame] object]
+} -cleanup {
+ c destroy
+} -result {1 {{* cmd {info frame 0} method frames class ::c level 0} {* cmd {info frame 0} method frames object ::i level 0}} ::c}
+test oo-22.2 {OO and info frame: Bug 3001438} -setup {
+ oo::class create c
+} -body {
+ oo::define c method test {{x 1}} {
+ if {$x} {my test 0}
+ lsort {q w e r t y u i o p}; # Overwrite the Tcl stack
+ info frame 0
+ }
+ [c new] test
+} -match glob -cleanup {
+ c destroy
+} -result {* cmd {info frame 0} method test class ::c level 0}
+
+# Prove that the issue in [Bug 1865054] isn't an issue any more
+test oo-23.1 {Self-like derivation; complex case!} -setup {
+ oo::class create SELF {
+ superclass oo::class
+ unexport create new
+ # Next is just a convenience
+ method method args {oo::define [self] method {*}$args}
+ method derive {name} {
+ set o [my new [list superclass [self]]]
+ oo::objdefine $o mixin $o
+ uplevel 1 [list rename $o $name]\;[list namespace which $name]
+ }
+ self mixin SELF
+ }
+ set result {}
+} -body {
+ [SELF derive foo1] method bar1 {} {return 1}
+ lappend result [foo1 bar1]
+ [foo1 derive foo2] method bar2 {} {return [my bar1],2}
+ lappend result [foo2 bar2]
+ [foo2 derive foo3] method bar3 {} {return [my bar2],3}
+ lappend result [foo3 bar3]
+ [foo3 derive foo4] method bar4 {} {return [my bar3],4}
+ lappend result [foo4 bar4]
+ foo2 method bar2 {} {return [my bar1],x}
+ lappend result [foo4 bar4]
+} -cleanup {
+ SELF destroy
+} -result {1 1,2 1,2,3 1,2,3,4 1,x,3,4}
+
+test oo-24.1 {unknown method method - Bug 1965063} -setup {
+ oo::class create cls
+} -cleanup {
+ cls destroy
+} -returnCodes error -body {
+ oo::define cls {
+ method dummy {} {}
+ method unknown args {next {*}$args}
+ }
+ [cls new] foo bar
+} -result {unknown method "foo": must be destroy, dummy or unknown}
+test oo-24.2 {unknown method method - Bug 1965063} -setup {
+ oo::class create cls
+} -cleanup {
+ cls destroy
+} -returnCodes error -body {
+ oo::define cls {
+ method dummy {} {}
+ method unknown args {next {*}$args}
+ }
+ cls create obj
+ oo::objdefine obj {
+ method dummy2 {} {}
+ method unknown args {next {*}$args}
+ }
+ obj foo bar
+} -result {unknown method "foo": must be destroy, dummy, dummy2 or unknown}
+test oo-24.3 {unknown method method - absent method name} -setup {
+ set o [oo::object new]
+} -cleanup {
+ $o destroy
+} -body {
+ oo::objdefine $o method unknown args {
+ return "unknown: >>$args<<"
+ }
+ list [$o] [$o foobar] [$o foo bar]
+} -result {{unknown: >><<} {unknown: >>foobar<<} {unknown: >>foo bar<<}}
+
+# Probably need a better set of tests, but this is quite difficult to devise
+test oo-25.1 {call chain caching} -setup {
+ oo::class create cls {
+ method ab {} {return ok}
+ }
+ set result {}
+} -cleanup {
+ cls destroy
+} -body {
+ cls create foo
+ cls create bar
+ set m1 ab
+ set m2 a; append m2 b ;# different object!
+ lappend result [foo $m1] [foo $m1] [bar $m1] [foo $m1]
+ lappend result [foo $m2] [bar $m2]
+ oo::objdefine foo method ab {} {return good}
+ lappend result [foo $m1] [bar $m2]
+} -result {ok ok ok ok ok ok good ok}
+test oo-25.2 {call chain caching - Bug #2120903} -setup {
+ set c [oo::class create MyClass]
+ set o [$c new]
+} -body {
+ oo::define MyClass {
+ method name {} {return ok}
+ method isa o {MyClass name $o}
+ self method name o {$o name}
+ }
+ list [$o name] [$c name $o] [$o isa $o]
+} -cleanup {
+ $c destroy
+} -result {ok ok ok}
+
+test oo-26.1 {Bug 2037727} -setup {
+ proc succeed args {}
+ oo::object create example
+} -body {
+ oo::objdefine example method foo {} {succeed}
+ example foo
+ proc succeed {} {return succeed}
+ example foo
+} -cleanup {
+ example destroy
+ rename succeed {}
+} -result succeed
+test oo-26.2 {Bug 2037727} -setup {
+ oo::class create example {
+ method localProc {args body} {proc called $args $body}
+ method run {} { called }
+ }
+ example create i1
+ example create i2
+} -body {
+ i1 localProc args {}
+ i2 localProc args {return nonempty}
+ list [i1 run] [i2 run]
+} -cleanup {
+ example destroy
+} -result {{} nonempty}
+test oo-26.3 {Bug 2037727} -setup {
+ oo::class create example {
+ method subProc {args body} {
+ namespace eval subns [list proc called $args $body]
+ }
+ method run {} { subns::called }
+ }
+ example create i1
+ example create i2
+} -body {
+ i1 subProc args {}
+ i2 subProc args {return nonempty}
+ list [i1 run] [i2 run]
+} -cleanup {
+ example destroy
+} -result {{} nonempty}
+
+test oo-27.1 {variables declaration - class introspection} -setup {
+ oo::class create foo
+} -cleanup {
+ foo destroy
+} -body {
+ oo::define foo variable a b c
+ info class variables foo
+} -result {a b c}
+test oo-27.2 {variables declaration - object introspection} -setup {
+ oo::object create foo
+} -cleanup {
+ foo destroy
+} -body {
+ oo::objdefine foo variable a b c
+ info object variables foo
+} -result {a b c}
+test oo-27.3 {variables declaration - basic behaviour} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x!
+ constructor {} {set x! 1}
+ method y {} {incr x!}
+ }
+ foo create bar
+ bar y
+ bar y
+} -result 3
+test oo-27.4 {variables declaration - destructors too} -setup {
+ oo::class create master
+ set result bad!
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x!
+ constructor {} {set x! 1}
+ method y {} {incr x!}
+ destructor {set ::result ${x!}}
+ }
+ foo create bar
+ bar y
+ bar y
+ bar destroy
+ return $result
+} -result 3
+test oo-27.5 {variables declaration - object-bound variables} -setup {
+ oo::object create foo
+} -cleanup {
+ foo destroy
+} -body {
+ oo::objdefine foo {
+ variable x!
+ method y {} {incr x!}
+ }
+ foo y
+ foo y
+} -result 2
+test oo-27.6 {variables declaration - non-interference of levels} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x!
+ constructor {} {set x! 1}
+ method y {} {incr x!}
+ }
+ foo create bar
+ oo::objdefine bar {
+ variable y!
+ method y {} {list [next] [incr y!] [info var] [info local]}
+ export eval
+ }
+ bar y
+ list [bar y] [lsort [info object vars bar]] [bar eval {info vars *!}]
+} -result {{3 2 y! {}} {x! y!} {x! y!}}
+test oo-27.7 {variables declaration - one underlying variable space} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x!
+ constructor {} {set x! 1}
+ method y {} {incr x!}
+ }
+ oo::class create foo2 {
+ superclass foo
+ variable y!
+ constructor {} {set y! 42; next}
+ method x {} {incr y! -1}
+ }
+ foo2 create bar
+ oo::objdefine bar {
+ variable x! y!
+ method z {} {list ${x!} ${y!}}
+ }
+ bar y
+ bar x
+ list [bar y] [bar x] [bar z]
+} -result {3 40 {3 40}}
+test oo-27.8 {variables declaration - error cases - ns separators} -body {
+ oo::define oo::object variable bad::var
+} -returnCodes error -result {invalid declared variable name "bad::var": must not contain namespace separators}
+test oo-27.9 {variables declaration - error cases - arrays} -body {
+ oo::define oo::object variable bad(var)
+} -returnCodes error -result {invalid declared variable name "bad(var)": must not refer to an array element}
+test oo-27.10 {variables declaration - no instance var leaks with class resolvers} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable clsvar
+ constructor {} {
+ set clsvar 0
+ }
+ method step {} {
+ incr clsvar
+ return
+ }
+ method value {} {
+ return $clsvar
+ }
+ }
+ foo create inst1
+ inst1 step
+ foo create inst2
+ inst2 step
+ inst1 step
+ inst2 step
+ inst1 step
+ list [inst1 value] [inst2 value]
+} -result {3 2}
+test oo-27.11 {variables declaration - no instance var leaks with class resolvers} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable clsvar
+ constructor {} {
+ set clsvar 0
+ }
+ method step {} {
+ incr clsvar
+ return
+ }
+ method value {} {
+ return $clsvar
+ }
+ }
+ foo create inst1
+ oo::objdefine inst1 {
+ variable clsvar
+ method reinit {} {
+ set clsvar 0
+ }
+ }
+ foo create inst2
+ oo::objdefine inst2 {
+ variable clsvar
+ method reinit {} {
+ set clsvar 0
+ }
+ }
+ inst1 step
+ inst2 step
+ inst1 reinit
+ inst2 reinit
+ inst1 step
+ inst2 step
+ inst1 step
+ inst2 step
+ inst1 step
+ list [inst1 value] [inst2 value]
+} -result {3 2}
+test oo-27.12 {variables declaration: leak per instance} -setup {
+ oo::class create foo
+} -constraints memory -body {
+ oo::define foo {
+ variable v
+ constructor {} {
+ set v 0
+ }
+ }
+ leaktest {[foo new] destroy}
+} -cleanup {
+ foo destroy
+} -result 0
+# This test will actually (normally) crash if it fails!
+test oo-27.13 {variables declaration: Bug 3185009: require refcount management} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo {
+ variable x
+ method set v {set x $v}
+ method unset {} {unset x}
+ method exists {} {info exists x}
+ method get {} {return $x}
+ }
+ list [foo exists] [foo set 7] [foo exists] [foo get] [foo unset] \
+ [foo exists] [catch {foo get} msg] $msg
+} -cleanup {
+ foo destroy
+} -result {0 7 1 7 {} 0 1 {can't read "x": no such variable}}
+test oo-27.14 {variables declaration - multiple use} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x
+ variable y
+ method boo {} {
+ return [incr x],[incr y]
+ }
+ }
+ foo create bar
+ list [bar boo] [bar boo]
+} -result {1,1 2,2}
+test oo-27.15 {variables declaration - multiple use} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable
+ variable x y
+ method boo {} {
+ return [incr x],[incr y]
+ }
+ }
+ foo create bar
+ list [bar boo] [bar boo]
+} -result {1,1 2,2}
+test oo-27.16 {variables declaration - multiple use} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x
+ variable -clear
+ variable y
+ method boo {} {
+ return [incr x],[incr y]
+ }
+ }
+ foo create bar
+ list [bar boo] [bar boo]
+} -result {1,1 1,2}
+test oo-27.17 {variables declaration - multiple use} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x
+ variable -set y
+ method boo {} {
+ return [incr x],[incr y]
+ }
+ }
+ foo create bar
+ list [bar boo] [bar boo]
+} -result {1,1 1,2}
+test oo-27.18 {variables declaration - multiple use} -setup {
+ oo::class create master
+} -cleanup {
+ master destroy
+} -body {
+ oo::class create foo {
+ superclass master
+ variable x
+ variable -? y
+ method boo {} {
+ return [incr x],[incr y]
+ }
+ }
+ foo create bar
+ list [bar boo] [bar boo]
+} -returnCodes error -match glob -result {unknown method "-?": must be *}
+test oo-27.19 {variables declaration and [info vars]: Bug 2712377} -setup {
+ oo::class create Foo
+ set result {}
+} -body {
+ # This is really a test of problems to do with Tcl's introspection when a
+ # variable resolver is present...
+ oo::define Foo {
+ variable foo bar
+ method setvars {f b} {
+ set foo $f
+ set bar $b
+ }
+ method dump1 {} {
+ lappend ::result <1>
+ foreach v [lsort [info vars *]] {
+ lappend ::result $v=[set $v]
+ }
+ lappend ::result [info locals] [info locals *]
+ }
+ method dump2 {} {
+ lappend ::result <2>
+ foreach v [lsort [info vars *]] {
+ lappend ::result $v=[set $v]
+ }
+ lappend ::result | foo=$foo [info locals] [info locals *]
+ }
+ }
+ Foo create stuff
+ stuff setvars what ever
+ stuff dump1
+ stuff dump2
+ return $result
+} -cleanup {
+ Foo destroy
+} -result {<1> bar=ever foo=what v v <2> bar=ever foo=what | foo=what v v}
+test oo-27.20 {variables declaration and [info vars]: Bug 2712377} -setup {
+ oo::class create Foo
+ set result {}
+} -body {
+ # This is really a test of problems to do with Tcl's introspection when a
+ # variable resolver is present...
+ oo::define Foo {
+ variable foo bar
+ method setvars {f b} {
+ set foo $f
+ set bar $b
+ }
+ method dump1 {} {
+ lappend ::result <1>
+ foreach v [lsort [info vars *o]] {
+ lappend ::result $v=[set $v]
+ }
+ lappend ::result [info locals] [info locals *]
+ }
+ method dump2 {} {
+ lappend ::result <2>
+ foreach v [lsort [info vars *o]] {
+ lappend ::result $v=[set $v]
+ }
+ lappend ::result | foo=$foo [info locals] [info locals *]
+ }
+ }
+ Foo create stuff
+ stuff setvars what ever
+ stuff dump1
+ stuff dump2
+ return $result
+} -cleanup {
+ Foo destroy
+} -result {<1> foo=what v v <2> foo=what | foo=what v v}
+test oo-27.21 {variables declaration uniqueifies: Bug 3396896} -setup {
+ oo::class create Foo
+} -body {
+ oo::define Foo variable v v v t t v t
+ info class variable Foo
+} -cleanup {
+ Foo destroy
+} -result {v t}
+test oo-27.22 {variables declaration uniqueifies: Bug 3396896} -setup {
+ oo::object create foo
+} -body {
+ oo::objdefine foo variable v v v t t v t
+ info object variable foo
+} -cleanup {
+ foo destroy
+} -result {v t}
+
+# A feature that's not supported because the mechanism may change without
+# warning, but is supposed to work...
+test oo-28.1 {scripted extensions to oo::define} -setup {
+ interp create foo
+ foo eval {oo::class create cls {export eval}}
+} -cleanup {
+ interp delete foo
+} -body {
+ foo eval {
+ proc oo::define::privateMethod {name arguments body} {
+ uplevel 1 [list method $name $arguments $body]
+ uplevel 1 [list unexport $name]
+ }
+ oo::define cls privateMethod m {x y} {return $x,$y}
+ cls create obj
+ list [catch {obj m 1 2}] [obj eval my m 3 4]
+ }
+} -result {1 3,4}
+
+test oo-29.1 {self class with object-defined methods} -setup {
+ oo::object create obj
+} -body {
+ oo::objdefine obj method demo {} {
+ self class
+ }
+ obj demo
+} -returnCodes error -cleanup {
+ obj destroy
+} -result {method not defined by a class}
+
+test oo-30.1 {Bug 2903011: deleting an object in a constructor} -setup {
+ oo::class create cls
+} -body {
+ oo::define cls {constructor {} {[self] destroy}}
+ cls new
+} -returnCodes error -cleanup {
+ cls destroy
+} -result {object deleted in constructor}
+test oo-30.2 {Bug 2903011: deleting an object in a constructor} -setup {
+ oo::class create cls
+} -body {
+ oo::define cls {constructor {} {my destroy}}
+ cls new
+} -returnCodes error -cleanup {
+ cls destroy
+} -result {object deleted in constructor}
+
+test oo-31.1 {Bug 3111059: when objects and coroutines entangle} -setup {
+ oo::class create cls
+} -constraints memory -body {
+ oo::define cls {
+ method justyield {} {
+ yield
+ }
+ constructor {} {
+ coroutine coro my justyield
+ }
+ }
+ list [leaktest {[cls new] destroy}] [info class instances cls]
+} -cleanup {
+ cls destroy
+} -result {0 {}}
+test oo-31.2 {Bug 3111059: when objects and coroutines entangle} -setup {
+ oo::class create cls
+} -constraints memory -body {
+ oo::define cls {
+ method justyield {} {
+ yield
+ }
+ constructor {} {
+ coroutine coro my justyield
+ }
+ destructor {
+ rename coro {}
+ }
+ }
+ list [leaktest {[cls new] destroy}] [info class instances cls]
+} -cleanup {
+ cls destroy
+} -result {0 {}}
+
+oo::class create SampleSlot {
+ superclass oo::Slot
+ constructor {} {
+ variable contents {a b c} ops {}
+ }
+ method contents {} {variable contents; return $contents}
+ method ops {} {variable ops; return $ops}
+ method Get {} {
+ variable contents
+ variable ops
+ lappend ops [info level] Get
+ return $contents
+ }
+ method Set {lst} {
+ variable contents $lst
+ variable ops
+ lappend ops [info level] Set $lst
+ return
+ }
+}
+
+test oo-32.1 {TIP 380: slots - class test} -setup {
+ SampleSlot create sampleSlot
+} -body {
+ list [info level] [sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+ rename sampleSlot {}
+} -result {0 {a b c} {}}
+test oo-32.2 {TIP 380: slots - class test} -setup {
+ SampleSlot create sampleSlot
+} -body {
+ list [info level] [sampleSlot -clear] \
+ [sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+ rename sampleSlot {}
+} -result {0 {} {} {1 Set {}}}
+test oo-32.3 {TIP 380: slots - class test} -setup {
+ SampleSlot create sampleSlot
+} -body {
+ list [info level] [sampleSlot -append g h i] \
+ [sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+ rename sampleSlot {}
+} -result {0 {} {a b c g h i} {1 Get 1 Set {a b c g h i}}}
+test oo-32.4 {TIP 380: slots - class test} -setup {
+ SampleSlot create sampleSlot
+} -body {
+ list [info level] [sampleSlot -set d e f] \
+ [sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+ rename sampleSlot {}
+} -result {0 {} {d e f} {1 Set {d e f}}}
+test oo-32.5 {TIP 380: slots - class test} -setup {
+ SampleSlot create sampleSlot
+} -body {
+ list [info level] [sampleSlot -set d e f] [sampleSlot -append g h i] \
+ [sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+ rename sampleSlot {}
+} -result {0 {} {} {d e f g h i} {1 Set {d e f} 1 Get 1 Set {d e f g h i}}}
+
+test oo-33.1 {TIP 380: slots - defaulting} -setup {
+ set s [SampleSlot new]
+} -body {
+ list [$s x y] [$s contents]
+} -cleanup {
+ rename $s {}
+} -result {{} {a b c x y}}
+test oo-33.2 {TIP 380: slots - defaulting} -setup {
+ set s [SampleSlot new]
+} -body {
+ list [$s destroy; $s unknown] [$s contents]
+} -cleanup {
+ rename $s {}
+} -result {{} {a b c destroy unknown}}
+test oo-33.3 {TIP 380: slots - defaulting} -setup {
+ set s [SampleSlot new]
+} -body {
+ oo::objdefine $s forward --default-operation my -set
+ list [$s destroy; $s unknown] [$s contents] [$s ops]
+} -cleanup {
+ rename $s {}
+} -result {{} unknown {1 Set destroy 1 Set unknown}}
+test oo-33.4 {TIP 380: slots - errors} -setup {
+ set s [SampleSlot new]
+} -body {
+ # Method names beginning with "-" are special to slots
+ $s -grill q
+} -returnCodes error -cleanup {
+ rename $s {}
+} -result {unknown method "-grill": must be -append, -clear, -set, contents or ops}
+
+SampleSlot destroy
+
+test oo-34.1 {TIP 380: slots - presence} -setup {
+ set obj [oo::object new]
+ set result {}
+} -body {
+ oo::define oo::object {
+ ::lappend ::result [::info object class filter]
+ ::lappend ::result [::info object class mixin]
+ ::lappend ::result [::info object class superclass]
+ ::lappend ::result [::info object class variable]
+ }
+ oo::objdefine $obj {
+ ::lappend ::result [::info object class filter]
+ ::lappend ::result [::info object class mixin]
+ ::lappend ::result [::info object class variable]
+ }
+ return $result
+} -cleanup {
+ $obj destroy
+} -result {::oo::Slot ::oo::Slot ::oo::Slot ::oo::Slot ::oo::Slot ::oo::Slot ::oo::Slot}
+test oo-34.2 {TIP 380: slots - presence} {
+ lsort [info class instances oo::Slot]
+} {::oo::define::filter ::oo::define::mixin ::oo::define::superclass ::oo::define::variable ::oo::objdefine::filter ::oo::objdefine::mixin ::oo::objdefine::variable}
+proc getMethods obj {
+ list [lsort [info object methods $obj -all]] \
+ [lsort [info object methods $obj -private]]
+}
+test oo-34.3 {TIP 380: slots - presence} {
+ getMethods oo::define::filter
+} {{-append -clear -set} {Get Set}}
+test oo-34.4 {TIP 380: slots - presence} {
+ getMethods oo::define::mixin
+} {{-append -clear -set} {--default-operation Get Set}}
+test oo-34.5 {TIP 380: slots - presence} {
+ getMethods oo::define::superclass
+} {{-append -clear -set} {--default-operation Get Set}}
+test oo-34.6 {TIP 380: slots - presence} {
+ getMethods oo::define::variable
+} {{-append -clear -set} {Get Set}}
+test oo-34.7 {TIP 380: slots - presence} {
+ getMethods oo::objdefine::filter
+} {{-append -clear -set} {Get Set}}
+test oo-34.8 {TIP 380: slots - presence} {
+ getMethods oo::objdefine::mixin
+} {{-append -clear -set} {--default-operation Get Set}}
+test oo-34.9 {TIP 380: slots - presence} {
+ getMethods oo::objdefine::variable
+} {{-append -clear -set} {Get Set}}
+
+cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/ooNext2.test b/pkgs/msgcat/tests/ooNext2.test
new file mode 100644
index 0000000..eeade11
--- /dev/null
+++ b/pkgs/msgcat/tests/ooNext2.test
@@ -0,0 +1,790 @@
+# This file contains a collection of tests for Tcl's built-in object system.
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 2006-2008 Donal K. Fellows
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: oo.test,v 1.59 2011/01/18 16:10:48 dkf Exp $
+
+package require -exact TclOO 0.6.3 ;# Must match value in configure.in
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint memory [llength [info commands memory]]
+if {[testConstraint memory]} {
+ proc getbytes {} {
+ set lines [split [memory info] \n]
+ return [lindex $lines 3 3]
+ }
+ proc leaktest {script {iterations 3}} {
+ set end [getbytes]
+ for {set i 0} {$i < $iterations} {incr i} {
+ uplevel 1 $script
+ set tmp $end
+ set end [getbytes]
+ }
+ return [expr {$end - $tmp}]
+ }
+}
+
+test oo-nextto-1.1 {basic nextto functionality} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x args {
+ lappend ::result ==A== $args
+ }
+ }
+ oo::class create B {
+ superclass A
+ method x args {
+ lappend ::result ==B== $args
+ nextto A B -> A {*}$args
+ }
+ }
+ oo::class create C {
+ superclass A
+ method x args {
+ lappend ::result ==C== $args
+ nextto A C -> A {*}$args
+ }
+ }
+ oo::class create D {
+ superclass B C
+ method x args {
+ lappend ::result ==D== $args
+ next foo
+ nextto C bar
+ }
+ }
+ set ::result {}
+ [D new] x
+ return $::result
+} -cleanup {
+ root destroy
+} -result {==D== {} ==B== foo ==A== {B -> A foo} ==C== bar ==A== {C -> A bar}}
+test oo-nextto-1.2 {basic nextto functionality} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x args {
+ lappend ::result ==A== $args
+ }
+ }
+ oo::class create B {
+ superclass A
+ method x args {
+ lappend ::result ==B== $args
+ nextto A B -> A {*}$args
+ }
+ }
+ oo::class create C {
+ superclass A
+ method x args {
+ lappend ::result ==C== $args
+ nextto A C -> A {*}$args
+ }
+ }
+ oo::class create D {
+ superclass B C
+ method x args {
+ lappend ::result ==D== $args
+ nextto B foo {*}$args
+ nextto C bar {*}$args
+ }
+ }
+ set ::result {}
+ [D new] x 123
+ return $::result
+} -cleanup {
+ root destroy
+} -result {==D== 123 ==B== {foo 123} ==A== {B -> A foo 123} ==C== {bar 123} ==A== {C -> A bar 123}}
+test oo-nextto-1.3 {basic nextto functionality: constructors} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ variable result
+ constructor {a c} {
+ lappend result ==A== a=$a,c=$c
+ }
+ }
+ oo::class create B {
+ superclass root
+ variable result
+ constructor {b} {
+ lappend result ==B== b=$b
+ }
+ }
+ oo::class create C {
+ superclass A B
+ variable result
+ constructor {p q r} {
+ lappend result ==C== p=$p,q=$q,r=$r
+ # Route arguments to superclasses, in non-trival pattern
+ nextto B $q
+ nextto A $p $r
+ }
+ method result {} {return $result}
+ }
+ [C new x y z] result
+} -cleanup {
+ root destroy
+} -result {==C== p=x,q=y,r=z ==B== b=y ==A== a=x,c=z}
+test oo-nextto-1.4 {basic nextto functionality: destructors} -setup {
+ oo::class create root {destructor return}
+} -body {
+ oo::class create A {
+ superclass root
+ destructor {
+ lappend ::result ==A==
+ next
+ }
+ }
+ oo::class create B {
+ superclass root
+ destructor {
+ lappend ::result ==B==
+ next
+ }
+ }
+ oo::class create C {
+ superclass A B
+ destructor {
+ lappend ::result ==C==
+ lappend ::result |
+ nextto B
+ lappend ::result |
+ nextto A
+ lappend ::result |
+ next
+ }
+ }
+ set ::result ""
+ [C new] destroy
+ return $::result
+} -cleanup {
+ root destroy
+} -result {==C== | ==B== | ==A== ==B== | ==A== ==B==}
+
+test oo-nextto-2.1 {errors in nextto} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x y {error $y}
+ }
+ oo::class create B {
+ superclass A
+ method x y {nextto A $y}
+ }
+ [B new] x boom
+} -cleanup {
+ root destroy
+} -result boom -returnCodes error
+test oo-nextto-2.2 {errors in nextto} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x y {error $y}
+ }
+ oo::class create B {
+ superclass root
+ method x y {nextto A $y}
+ }
+ [B new] x boom
+} -returnCodes error -cleanup {
+ root destroy
+} -result {method has no non-filter implementation by "A"}
+test oo-nextto-2.3 {errors in nextto} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x y {nextto $y}
+ }
+ oo::class create B {
+ superclass A
+ method x y {nextto A $y}
+ }
+ [B new] x B
+} -returnCodes error -cleanup {
+ root destroy
+} -result {method implementation by "B" not reachable from here}
+test oo-nextto-2.4 {errors in nextto} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x y {nextto $y}
+ }
+ oo::class create B {
+ superclass A
+ method x y {nextto}
+ }
+ [B new] x B
+} -returnCodes error -cleanup {
+ root destroy
+} -result {wrong # args: should be "nextto class ?arg...?"}
+test oo-nextto-2.5 {errors in nextto} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x y {nextto $y}
+ }
+ oo::class create B {
+ superclass A
+ method x y {nextto $y $y $y}
+ }
+ [B new] x A
+} -cleanup {
+ root destroy
+} -result {wrong # args: should be "nextto A y"} -returnCodes error
+test oo-nextto-2.6 {errors in nextto} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x y {nextto $y}
+ }
+ oo::class create B {
+ superclass A
+ method x y {nextto $y $y $y}
+ }
+ [B new] x [root create notAClass]
+} -cleanup {
+ root destroy
+} -result {"::notAClass" is not a class} -returnCodes error
+test oo-nextto-2.7 {errors in nextto} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x y {nextto $y}
+ }
+ oo::class create B {
+ superclass A
+ filter Y
+ method Y args {next {*}$args}
+ }
+ oo::class create C {
+ superclass B
+ method x y {nextto $y $y $y}
+ }
+ [C new] x B
+} -returnCodes error -cleanup {
+ root destroy
+} -result {method has no non-filter implementation by "B"}
+
+test oo-call-1.1 {object call introspection} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ A create y
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{method x ::A method}}
+test oo-call-1.2 {object call introspection} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ }
+ B create y
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{method x ::B method} {method x ::A method}}
+test oo-call-1.3 {object call introspection} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ A create y
+ oo::objdefine y method x {} {}
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{method x object method} {method x ::A method}}
+test oo-call-1.4 {object object call introspection - unknown} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ A create y
+ info object call y z
+} -cleanup {
+ root destroy
+} -result {{unknown unknown ::oo::object {core method: "unknown"}}}
+test oo-call-1.5 {object call introspection - filters} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ method y {} {}
+ filter y
+ }
+ A create y
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{filter y ::A method} {method x ::A method}}
+test oo-call-1.6 {object call introspection - filters} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ method y {} {}
+ filter y
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ }
+ B create y
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{filter y ::A method} {method x ::B method} {method x ::A method}}
+test oo-call-1.7 {object call introspection - filters} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ method y {} {}
+ filter y
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ method y {} {}
+ }
+ B create y
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{filter y ::B method} {filter y ::A method} {method x ::B method} {method x ::A method}}
+test oo-call-1.8 {object call introspection - filters} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ method y {} {}
+ filter y
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ method y {} {}
+ method z {} {}
+ filter z
+ }
+ B create y
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{filter z ::B method} {filter y ::B method} {filter y ::A method} {method x ::B method} {method x ::A method}}
+test oo-call-1.9 {object call introspection - filters} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ method y {} {}
+ filter y
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ method y {} {}
+ method z {} {}
+ filter z
+ }
+ B create y
+ info object call y y
+} -cleanup {
+ root destroy
+} -result {{filter z ::B method} {filter y ::B method} {filter y ::A method} {method y ::B method} {method y ::A method}}
+test oo-call-1.10 {object call introspection - filters + unknown} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method y {} {}
+ filter y
+ }
+ oo::class create ::B {
+ superclass A
+ method y {} {}
+ method unknown {} {}
+ }
+ B create y
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{filter y ::B method} {filter y ::A method} {unknown unknown ::B method} {unknown unknown ::oo::object {core method: "unknown"}}}
+test oo-call-1.11 {object call introspection - filters + unknown} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method y {} {}
+ filter y
+ }
+ A create y
+ oo::objdefine y method unknown {} {}
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{filter y ::A method} {unknown unknown object method} {unknown unknown ::oo::object {core method: "unknown"}}}
+test oo-call-1.12 {object call introspection - filters + unknown} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method y {} {}
+ }
+ A create y
+ oo::objdefine y {
+ method unknown {} {}
+ filter y
+ }
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{filter y ::A method} {unknown unknown object method} {unknown unknown ::oo::object {core method: "unknown"}}}
+test oo-call-1.13 {object call introspection - filters + unknown} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method y {} {}
+ }
+ A create y
+ oo::objdefine y {
+ method unknown {} {}
+ method x {} {}
+ filter y
+ }
+ info object call y x
+} -cleanup {
+ root destroy
+} -result {{filter y ::A method} {method x object method}}
+test oo-call-1.14 {object call introspection - errors} -body {
+ info object call
+} -returnCodes error -result {wrong # args: should be "info object call objName methodName"}
+test oo-call-1.15 {object call introspection - errors} -body {
+ info object call a
+} -returnCodes error -result {wrong # args: should be "info object call objName methodName"}
+test oo-call-1.16 {object call introspection - errors} -body {
+ info object call a b c
+} -returnCodes error -result {wrong # args: should be "info object call objName methodName"}
+test oo-call-1.17 {object call introspection - errors} -body {
+ info object call notanobject x
+} -returnCodes error -result {notanobject does not refer to an object}
+test oo-call-1.18 {object call introspection - memory leaks} -body {
+ leaktest {
+ info object call oo::object destroy
+ }
+} -constraints memory -result 0
+test oo-call-1.19 {object call introspection - memory leaks} -setup {
+ oo::class create leaktester { method foo {} {dummy} }
+} -body {
+ leaktest {
+ set lt [leaktester new]
+ oo::objdefine $lt method foobar {} {dummy}
+ list [info object call $lt destroy] \
+ [info object call $lt foo] \
+ [info object call $lt bar] \
+ [info object call $lt foobar] \
+ [$lt destroy]
+ }
+} -cleanup {
+ leaktester destroy
+} -constraints memory -result 0
+
+test oo-call-2.1 {class call introspection} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ info class call A x
+} -cleanup {
+ root destroy
+} -result {{method x ::A method}}
+test oo-call-2.2 {class call introspection} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ }
+ list [info class call A x] [info class call B x]
+} -cleanup {
+ root destroy
+} -result {{{method x ::A method}} {{method x ::B method} {method x ::A method}}}
+test oo-call-2.3 {class call introspection} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ }
+ oo::class create ::C {
+ superclass A
+ method x {} {}
+ }
+ oo::class create ::D {
+ superclass C B
+ method x {} {}
+ }
+ info class call D x
+} -cleanup {
+ root destroy
+} -result {{method x ::D method} {method x ::C method} {method x ::B method} {method x ::A method}}
+test oo-call-2.4 {class call introspection - mixin} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ }
+ oo::class create ::C {
+ superclass A
+ method x {} {}
+ }
+ oo::class create ::D {
+ superclass C
+ mixin B
+ method x {} {}
+ }
+ info class call D x
+} -cleanup {
+ root destroy
+} -result {{method x ::B method} {method x ::D method} {method x ::C method} {method x ::A method}}
+test oo-call-2.5 {class call introspection - mixin + filter} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ method y {} {}
+ filter y
+ }
+ oo::class create ::C {
+ superclass A
+ method x {} {}
+ method y {} {}
+ }
+ oo::class create ::D {
+ superclass C
+ mixin B
+ method x {} {}
+ }
+ info class call D x
+} -cleanup {
+ root destroy
+} -result {{filter y ::B method} {filter y ::C method} {method x ::B method} {method x ::D method} {method x ::C method} {method x ::A method}}
+test oo-call-2.6 {class call introspection - mixin + filter + unknown} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ method unknown {} {}
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ method y {} {}
+ filter y
+ }
+ oo::class create ::C {
+ superclass A
+ method x {} {}
+ method y {} {}
+ }
+ oo::class create ::D {
+ superclass C
+ mixin B
+ method x {} {}
+ method unknown {} {}
+ }
+ info class call D z
+} -cleanup {
+ root destroy
+} -result {{filter y ::B method} {filter y ::C method} {unknown unknown ::D method} {unknown unknown ::A method} {unknown unknown ::oo::object {core method: "unknown"}}}
+test oo-call-2.7 {class call introspection - mixin + filter + unknown} -setup {
+ oo::class create root
+} -body {
+ oo::class create ::A {
+ superclass root
+ method x {} {}
+ }
+ oo::class create ::B {
+ superclass A
+ method x {} {}
+ filter x
+ }
+ info class call B x
+} -cleanup {
+ root destroy
+} -result {{filter x ::B method} {filter x ::A method} {method x ::B method} {method x ::A method}}
+test oo-call-2.8 {class call introspection - errors} -body {
+ info class call
+} -returnCodes error -result {wrong # args: should be "info class call className methodName"}
+test oo-call-2.9 {class call introspection - errors} -body {
+ info class call a
+} -returnCodes error -result {wrong # args: should be "info class call className methodName"}
+test oo-call-2.10 {class call introspection - errors} -body {
+ info class call a b c
+} -returnCodes error -result {wrong # args: should be "info class call className methodName"}
+test oo-call-2.11 {class call introspection - errors} -body {
+ info class call notaclass x
+} -returnCodes error -result {notaclass does not refer to an object}
+test oo-call-2.12 {class call introspection - errors} -setup {
+ oo::class create root
+} -body {
+ root create notaclass
+ info class call notaclass x
+} -returnCodes error -cleanup {
+ root destroy
+} -result {"notaclass" is not a class}
+test oo-call-2.13 {class call introspection - memory leaks} -body {
+ leaktest {
+ info class call oo::class destroy
+ }
+} -constraints memory -result 0
+test oo-call-2.14 {class call introspection - memory leaks} -body {
+ leaktest {
+ oo::class create leaktester { method foo {} {dummy} }
+ [leaktester new] destroy
+ list [info class call leaktester destroy] \
+ [info class call leaktester foo] \
+ [info class call leaktester bar] \
+ [leaktester destroy]
+ }
+} -constraints memory -result 0
+
+test oo-call-3.1 {current call introspection} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ method x {} {lappend ::result [self call]}
+ }
+ oo::class create B {
+ superclass A
+ method x {} {lappend ::result [self call];next}
+ }
+ B create y
+ oo::objdefine y method x {} {lappend ::result [self call];next}
+ set ::result {}
+ y x
+} -cleanup {
+ root destroy
+} -result {{{{method x object method} {method x ::B method} {method x ::A method}} 0} {{{method x object method} {method x ::B method} {method x ::A method}} 1} {{{method x object method} {method x ::B method} {method x ::A method}} 2}}
+test oo-call-3.2 {current call introspection} -setup {
+ oo::class create root
+} -constraints memory -body {
+ oo::class create A {
+ superclass root
+ method x {} {self call}
+ }
+ oo::class create B {
+ superclass A
+ method x {} {self call;next}
+ }
+ B create y
+ oo::objdefine y method x {} {self call;next}
+ leaktest {
+ y x
+ }
+} -cleanup {
+ root destroy
+} -result 0
+test oo-call-3.3 {current call introspection: in constructors} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ constructor {} {lappend ::result [self call]}
+ }
+ oo::class create B {
+ superclass A
+ constructor {} {lappend ::result [self call]; next}
+ }
+ set ::result {}
+ [B new] destroy
+ return $::result
+} -cleanup {
+ root destroy
+} -result {{{{method <constructor> ::B method} {method <constructor> ::A method}} 0} {{{method <constructor> ::B method} {method <constructor> ::A method}} 1}}
+test oo-call-3.4 {current call introspection: in destructors} -setup {
+ oo::class create root
+} -body {
+ oo::class create A {
+ superclass root
+ destructor {lappend ::result [self call]}
+ }
+ oo::class create B {
+ superclass A
+ destructor {lappend ::result [self call]; next}
+ }
+ set ::result {}
+ [B new] destroy
+ return $::result
+} -cleanup {
+ root destroy
+} -result {{{{method <destructor> ::B method} {method <destructor> ::A method}} 0} {{{method <destructor> ::B method} {method <destructor> ::A method}} 1}}
+
+cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/opt.test b/pkgs/msgcat/tests/opt.test
new file mode 100644
index 0000000..2732d40
--- /dev/null
+++ b/pkgs/msgcat/tests/opt.test
@@ -0,0 +1,245 @@
+# Package covered: opt1.0/optparse.tcl
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# the package we are going to test
+package require opt 0.4.6
+
+# we are using implementation specifics to test the package
+
+
+#### functions tests #####
+
+set n $::tcl::OptDescN
+
+test opt-1.1 {OptKeyRegister / check that auto allocation is skipping existing keys} {
+ list [::tcl::OptKeyRegister {} $n] [::tcl::OptKeyRegister {} [expr $n+1]] [::tcl::OptKeyRegister {}]
+} "$n [expr $n+1] [expr $n+2]"
+
+test opt-2.1 {OptKeyDelete} {
+ list [::tcl::OptKeyRegister {} testkey] \
+ [info exists ::tcl::OptDesc(testkey)] \
+ [::tcl::OptKeyDelete testkey] \
+ [info exists ::tcl::OptDesc(testkey)]
+} {testkey 1 {} 0}
+
+test opt-3.1 {OptParse / temp key is removed} {
+ set n $::tcl::OptDescN
+ set prev [array names ::tcl::OptDesc]
+ ::tcl::OptKeyRegister {} $n
+ list [info exists ::tcl::OptDesc($n)]\
+ [::tcl::OptKeyDelete $n]\
+ [::tcl::OptParse {{-foo}} {}]\
+ [info exists ::tcl::OptDesc($n)]\
+ [expr {"[lsort $prev]"=="[lsort [array names ::tcl::OptDesc]]"}]
+} {1 {} {} 0 1}
+test opt-3.2 {OptParse / temp key is removed even on errors} {
+ set n $::tcl::OptDescN
+ catch {::tcl::OptKeyDelete $n}
+ list [catch {::tcl::OptParse {{-foo}} {-blah}}] \
+ [info exists ::tcl::OptDesc($n)]
+} {1 0}
+
+test opt-4.1 {OptProc} {
+ ::tcl::OptProc optTest {} {}
+ optTest
+ ::tcl::OptKeyDelete optTest
+} {}
+
+test opt-5.1 {OptProcArgGiven} {
+ ::tcl::OptProc optTest {{-foo}} {
+ if {[::tcl::OptProcArgGiven "-foo"]} {
+ return 1
+ } else {
+ return 0
+ }
+ }
+ list [optTest] [optTest -f] [optTest -F] [optTest -fOO]
+} {0 1 1 1}
+
+test opt-6.1 {OptKeyParse} {
+ ::tcl::OptKeyRegister {} test
+ list [catch {::tcl::OptKeyParse test {-help}} msg] $msg
+} {1 {Usage information:
+ Var/FlagName Type Value Help
+ ------------ ---- ----- ----
+ (-help gives this help)}}
+
+test opt-7.1 {OptCheckType} {
+ list \
+ [::tcl::OptCheckType 23 int] \
+ [::tcl::OptCheckType 23 float] \
+ [::tcl::OptCheckType true boolean] \
+ [::tcl::OptCheckType "-blah" any] \
+ [::tcl::OptCheckType {a b c} list] \
+ [::tcl::OptCheckType maYbe choice {yes maYbe no}] \
+ [catch {::tcl::OptCheckType "-blah" string}] \
+ [catch {::tcl::OptCheckType 6 boolean}] \
+ [catch {::tcl::OptCheckType x float}] \
+ [catch {::tcl::OptCheckType "a \{ c" list}] \
+ [catch {::tcl::OptCheckType 2.3 int}] \
+ [catch {::tcl::OptCheckType foo choice {x y Foo z}}]
+} {23 23.0 1 -blah {a b c} maYbe 1 1 1 1 1 1}
+
+test opt-8.1 {List utilities} {
+ ::tcl::Lempty {}
+} 1
+test opt-8.2 {List utilities} {
+ ::tcl::Lempty {a b c}
+} 0
+test opt-8.3 {List utilities} {
+ ::tcl::Lget {a {b c d} e} {1 2}
+} d
+test opt-8.4 {List utilities} {
+ set l {a {b c d e} f}
+ ::tcl::Lvarset l {1 2} D
+ set l
+} {a {b c D e} f}
+test opt-8.5 {List utilities} {
+ set l {a b c}
+ ::tcl::Lvarset1 l 6 X
+ set l
+} {a b c {} {} {} X}
+test opt-8.6 {List utilities} {
+ set l {a {b c 7 e} f}
+ ::tcl::Lvarincr l {1 2}
+ set l
+} {a {b c 8 e} f}
+test opt-8.7 {List utilities} {
+ set l {a {b c 7 e} f}
+ ::tcl::Lvarincr l {1 2} -9
+ set l
+} {a {b c -2 e} f}
+# 8.8 and 8.9 missing?
+test opt-8.10 {List utilities} {
+ set l {a {b c 7 e} f}
+ ::tcl::Lvarpop l
+ set l
+} {{b c 7 e} f}
+test opt-8.11 {List utilities} {
+ catch {unset x}
+ set l {a {b c 7 e} f}
+ list [::tcl::Lassign $l u v w x] \
+ $u $v $w [info exists x]
+} {3 a {b c 7 e} f 0}
+
+test opt-9.1 {Misc utilities} {
+ catch {unset v}
+ ::tcl::SetMax v 3
+ ::tcl::SetMax v 7
+ ::tcl::SetMax v 6
+ set v
+} 7
+test opt-9.2 {Misc utilities} {
+ catch {unset v}
+ ::tcl::SetMin v 3
+ ::tcl::SetMin v -7
+ ::tcl::SetMin v 1
+ set v
+} -7
+
+#### behaviour tests #####
+
+test opt-10.1 {ambigous flags} {
+ ::tcl::OptProc optTest {{-fla} {-other} {-flag2xyz} {-flag3xyz}} {}
+ catch {optTest -fL} msg
+ set msg
+} {ambigous option "-fL", choose from:
+ -fla boolflag (false)
+ -flag2xyz boolflag (false)
+ -flag3xyz boolflag (false)}
+test opt-10.2 {non ambigous flags} {
+ ::tcl::OptProc optTest {{-flag1xyz} {-other} {-flag2xyz} {-flag3xyz}} {
+ return $flag2xyz
+ }
+ optTest -fLaG2
+} 1
+test opt-10.3 {non ambigous flags because of exact match} {
+ ::tcl::OptProc optTest {{-flag1x} {-other} {-flag1} {-flag1xy}} {
+ return $flag1
+ }
+ optTest -flAg1
+} 1
+test opt-10.4 {ambigous flags, not exact match} {
+ ::tcl::OptProc optTest {{-flag1xy} {-other} {-flag1} {-flag1xyz}} {
+ return $flag1
+ }
+ catch {optTest -fLag1X} msg
+ set msg
+} {ambigous option "-fLag1X", choose from:
+ -flag1xy boolflag (false)
+ -flag1xyz boolflag (false)}
+
+# medium size overall test example: (defined once)
+::tcl::OptProc optTest {
+ {cmd -choice {print save delete} "sub command to choose"}
+ {-allowBoing -boolean true}
+ {arg2 -string "this is help"}
+ {?arg3? 7 "optional number"}
+ {-moreflags}
+} {
+ list $cmd $allowBoing $arg2 $arg3 $moreflags
+}
+
+test opt-10.5 {medium size overall test} {
+ list [catch {optTest} msg] $msg
+} {1 {no value given for parameter "cmd" (use -help for full usage) :
+ cmd choice (print save delete) sub command to choose}}
+test opt-10.6 {medium size overall test} {
+ list [catch {optTest -help} msg] $msg
+} {1 {Usage information:
+ Var/FlagName Type Value Help
+ ------------ ---- ----- ----
+ (-help gives this help)
+ cmd choice (print save delete) sub command to choose
+ -allowBoing boolean (true)
+ arg2 string () this is help
+ ?arg3? int (7) optional number
+ -moreflags boolflag (false)}}
+test opt-10.7 {medium size overall test} {
+ optTest save tst
+} {save 1 tst 7 0}
+test opt-10.8 {medium size overall test} {
+ optTest save -allowBoing false -- 8
+} {save 0 8 7 0}
+test opt-10.9 {medium size overall test} {
+ optTest save tst -m --
+} {save 1 tst 7 1}
+test opt-10.10 {medium size overall test} {
+ list [catch {optTest save tst foo} msg] [lindex [split $msg "\n"] 0]
+} {1 {too many arguments (unexpected argument(s): foo), usage:}}
+
+test opt-11.1 {too many args test 2} {
+ set key [::tcl::OptKeyRegister {-foo}]
+ list [catch {::tcl::OptKeyParse $key {-foo blah}} msg] $msg\
+ [::tcl::OptKeyDelete $key]
+} {1 {too many arguments (unexpected argument(s): blah), usage:
+ Var/FlagName Type Value Help
+ ------------ ---- ----- ----
+ (-help gives this help)
+ -foo boolflag (false)} {}}
+test opt-11.2 {default value for args} {
+ set args {}
+ set key [::tcl::OptKeyRegister {{args -list {a b c} "args..."}}]
+ ::tcl::OptKeyParse $key {}
+ ::tcl::OptKeyDelete $key
+ set args
+} {a b c}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/package.test b/pkgs/msgcat/tests/package.test
new file mode 100644
index 0000000..da778f1
--- /dev/null
+++ b/pkgs/msgcat/tests/package.test
@@ -0,0 +1,1279 @@
+# This file contains tests for the package and ::pkg::* commands.
+# Note that the tests are limited to Tcl scripts only, there are no shared
+# libraries against which to test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2011 Donal K. Fellows
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2.3.3
+ namespace import -force ::tcltest::*
+}
+
+# Do all this in a slave interp to avoid garbaging the package list
+set i [interp create]
+tcltest::loadIntoSlaveInterpreter $i {*}$argv
+interp eval $i {
+namespace import -force ::tcltest::*
+package forget {*}[package names]
+set oldPkgUnknown [package unknown]
+package unknown {}
+set oldPath $auto_path
+set auto_path ""
+
+test package-1.1 {pkg::create gives error on insufficient args} -body {
+ ::pkg::create
+} -returnCodes error -match glob -result {wrong # args: should be "*"}
+test package-1.2 {pkg::create gives error on bad args} -body {
+ ::pkg::create -foo bar -bar baz -baz boo
+} -returnCodes error -match glob -result {unknown option "bar": *}
+test package-1.3 {pkg::create gives error on no value given} -body {
+ ::pkg::create -name foo -version 1.0 -source test.tcl -load
+} -returnCodes error -match glob -result {value for "-load" missing: *}
+test package-1.4 {pkg::create gives error on no name given} -body {
+ ::pkg::create -version 1.0 -source test.tcl -load foo.so
+} -returnCodes error -match glob -result {value for "-name" missing: *}
+test package-1.5 {pkg::create gives error on no version given} -body {
+ ::pkg::create -name foo -source test.tcl -load foo.so
+} -returnCodes error -match glob -result {value for "-version" missing: *}
+test package-1.6 {pkg::create gives error on no source or load options} -body {
+ ::pkg::create -name foo -version 1.0 -version 2.0
+} -returnCodes error -result {at least one of -load and -source must be given}
+test package-1.7 {pkg::create gives correct output for 1 direct source} {
+ ::pkg::create -name foo -version 1.0 -source test.tcl
+} {package ifneeded foo 1.0 [list source [file join $dir test.tcl]]}
+test package-1.8 {pkg::create gives correct output for 2 direct sources} {
+ ::pkg::create -name foo -version 1.0 -source test.tcl -source test2.tcl
+} {package ifneeded foo 1.0 [list source [file join $dir test.tcl]]\n[list source [file join $dir test2.tcl]]}
+test package-1.9 {pkg::create gives correct output for 1 direct load} {
+ ::pkg::create -name foo -version 1.0 -load test.so
+} {package ifneeded foo 1.0 [list load [file join $dir test.so]]}
+test package-1.10 {pkg::create gives correct output for 2 direct loads} {
+ ::pkg::create -name foo -version 1.0 -load test.so -load test2.so
+} {package ifneeded foo 1.0 [list load [file join $dir test.so]]\n[list load [file join $dir test2.so]]}
+test package-1.11 {pkg::create gives correct output for 1 lazy source} {
+ ::pkg::create -name foo -version 1.0 -source {test.tcl {foo bar}}
+} {package ifneeded foo 1.0 [list tclPkgSetup $dir foo 1.0 {{test.tcl source {foo bar}}}]}
+test package-1.12 {pkg::create gives correct output for 2 lazy sources} {
+ ::pkg::create -name foo -version 1.0 -source {test.tcl {foo bar}} \
+ -source {test2.tcl {baz boo}}
+} {package ifneeded foo 1.0 [list tclPkgSetup $dir foo 1.0 {{test.tcl source {foo bar}} {test2.tcl source {baz boo}}}]}
+test package-1.13 {pkg::create gives correct output for 1 lazy load} {
+ ::pkg::create -name foo -version 1.0 -load {test.so {foo bar}}
+} {package ifneeded foo 1.0 [list tclPkgSetup $dir foo 1.0 {{test.so load {foo bar}}}]}
+test package-1.14 {pkg::create gives correct output for 2 lazy loads} {
+ ::pkg::create -name foo -version 1.0 -load {test.so {foo bar}} \
+ -load {test2.so {baz boo}}
+} {package ifneeded foo 1.0 [list tclPkgSetup $dir foo 1.0 {{test.so load {foo bar}} {test2.so load {baz boo}}}]}
+test package-1.15 {pkg::create gives correct output for 1 each, direct} {
+ ::pkg::create -name foo -version 1.0 -source test.tcl -load test2.so
+} {package ifneeded foo 1.0 [list load [file join $dir test2.so]]\n[list source [file join $dir test.tcl]]}
+test package-1.16 {pkg::create gives correct output for 1 direct, 1 lazy} {
+ ::pkg::create -name foo -version 1.0 -source test.tcl \
+ -source {test2.tcl {foo bar}}
+} {package ifneeded foo 1.0 [list source [file join $dir test.tcl]]\n[list tclPkgSetup $dir foo 1.0 {{test2.tcl source {foo bar}}}]}
+
+test package-2.1 {Tcl_PkgProvide procedure} {
+ package forget t
+ package provide t 2.3
+} {}
+test package-2.2 {Tcl_PkgProvide procedure} -returnCodes error -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package provide t 2.2
+} -result {conflicting versions provided for package "t": 2.3, then 2.2}
+test package-2.3 {Tcl_PkgProvide procedure} -returnCodes error -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package provide t 2.4
+} -result {conflicting versions provided for package "t": 2.3, then 2.4}
+test package-2.4 {Tcl_PkgProvide procedure} -returnCodes error -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package provide t 3.3
+} -result {conflicting versions provided for package "t": 2.3, then 3.3}
+test package-2.5 {Tcl_PkgProvide procedure} -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package provide t 2.3
+} -result {}
+test package-2.6 {Tcl_PkgProvide procedure} {
+ package forget t
+ package provide t 2.3a1
+} {}
+
+set n 0
+foreach v {
+ 2.3k1 2a3a2 2ab3 2.a4 2.b4 2b.4 2a.4 2ba4 2a4b1
+ 2b4a1 2b3b2
+} {
+ test package-2.7.$n {Tcl_PkgProvide procedure} -setup {
+ package forget t
+ } -returnCodes error -body "
+ package provide t $v
+ " -result "expected version number but got \"$v\""
+ incr n
+}
+
+test package-3.1 {Tcl_PkgRequire procedure, picking best version} -setup {
+ package forget t
+ set x xxx
+} -body {
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ package require t
+ return $x
+} -result {3.4}
+test package-3.2 {Tcl_PkgRequire procedure, picking best version} -setup {
+ package forget t
+ set x xxx
+} -body {
+ foreach i {1.4 3.4 2.3 2.4 2.2 3.5 3.2} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ package require t
+ return $x
+} -result {3.5}
+test package-3.3 {Tcl_PkgRequire procedure, picking best version} -setup {
+ package forget t
+ set x xxx
+} -body {
+ foreach i {3.5 2.1 2.3} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ package require t 2.2
+ return $x
+} -result {2.3}
+test package-3.4 {Tcl_PkgRequire procedure, picking best version} -setup {
+ package forget t
+ set x xxx
+} -body {
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ package require -exact t 2.3
+ return $x
+} -result {2.3}
+test package-3.5 {Tcl_PkgRequire procedure, picking best version} -setup {
+ package forget t
+ set x xxx
+} -body {
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ package require t 2.1
+ return $x
+} -result {2.4}
+test package-3.6 {Tcl_PkgRequire procedure, can't find suitable version} -setup {
+ package forget t
+} -returnCodes error -body {
+ package unknown {}
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i"
+ }
+ package require t 2.5
+} -result {can't find package t 2.5}
+test package-3.7 {Tcl_PkgRequire procedure, can't find suitable version} -setup {
+ package forget t
+} -returnCodes error -body {
+ package unknown {}
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i"
+ }
+ package require t 4.1
+} -result {can't find package t 4.1}
+test package-3.8 {Tcl_PkgRequire procedure, can't find suitable version} -setup {
+ package forget t
+} -returnCodes error -body {
+ package unknown {}
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i"
+ }
+ package require -exact t 1.3
+} -result {can't find package t exactly 1.3}
+test package-3.9 {Tcl_PkgRequire procedure, can't find suitable version} -setup {
+ package forget t
+} -returnCodes error -body {
+ package unknown {}
+ package require t
+} -result {can't find package t}
+test package-3.10 {Tcl_PkgRequire procedure, error in ifneeded script} -setup {
+ package forget t
+} -body {
+ package ifneeded t 2.1 {package provide t 2.1; error "ifneeded test"}
+ list [catch {package require t 2.1} msg] $msg $::errorInfo
+} -match glob -result {1 {ifneeded test} {ifneeded test
+ while executing
+"error "ifneeded test""
+ ("package ifneeded*" script)
+ invoked from within
+"package require t 2.1"}}
+test package-3.11 {Tcl_PkgRequire procedure, ifneeded script doesn't provide package} -setup {
+ package forget t
+ set x xxx
+} -body {
+ package ifneeded t 2.1 "set x invoked"
+ list [catch {package require t 2.1} msg] $msg $x
+} -match glob -result {1 * invoked}
+test package-3.12 {Tcl_PkgRequire procedure, self-deleting script} -setup {
+ package forget t
+ set x xxx
+} -body {
+ package ifneeded t 1.2 "package forget t; set x 1.2; package provide t 1.2"
+ package require t 1.2
+ return $x
+} -result {1.2}
+test package-3.13 {Tcl_PkgRequire procedure, "package unknown" support} -setup {
+ package forget t
+ set x xxx
+} -body {
+ proc pkgUnknown args {
+ # args = name requirement
+ # requirement = v-v (for exact version)
+ global x
+ set x $args
+ package provide [lindex $args 0] [lindex [split [lindex $args 1] -] 0]
+ }
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i"
+ }
+ package unknown pkgUnknown
+ package require -exact t 1.5
+ return $x
+} -cleanup {
+ package unknown {}
+} -result {t 1.5-1.5}
+test package-3.14 {Tcl_PkgRequire procedure, "package unknown" support} -setup {
+ package forget t
+ set x xxx
+} -body {
+ proc pkgUnknown args {
+ package ifneeded t 1.2 "set x loaded; package provide t 1.2"
+ }
+ package unknown pkgUnknown
+ list [package require t] $x
+} -cleanup {
+ package unknown {}
+} -result {1.2 loaded}
+test package-3.15 {Tcl_PkgRequire procedure, "package unknown" support} -setup {
+ package forget {a b}
+ package unknown pkgUnknown
+ set x xxx
+} -body {
+ proc pkgUnknown args {
+ global x
+ set x $args
+ package provide [lindex $args 0] 2.0
+ }
+ package require {a b}
+ return $x
+} -cleanup {
+ package unknown {}
+} -result {{a b} 0-}
+test package-3.16 {Tcl_PkgRequire procedure, "package unknown" error} -setup {
+ package forget t
+} -body {
+ proc pkgUnknown args {
+ error "testing package unknown"
+ }
+ package unknown pkgUnknown
+ list [catch {package require t} msg] $msg $::errorInfo
+} -cleanup {
+ package unknown {}
+} -result {1 {testing package unknown} {testing package unknown
+ while executing
+"error "testing package unknown""
+ (procedure "pkgUnknown" line 2)
+ invoked from within
+"pkgUnknown t 0-"
+ ("package unknown" script)
+ invoked from within
+"package require t"}}
+test package-3.17 {Tcl_PkgRequire procedure, "package unknown" doesn't load package} -setup {
+ package forget t
+ set x xxx
+} -body {
+ proc pkgUnknown args {
+ global x
+ set x $args
+ }
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i"
+ }
+ package unknown pkgUnknown
+ list [catch {package require -exact t 1.5} msg] $msg $x
+} -cleanup {
+ package unknown {}
+} -result {1 {can't find package t exactly 1.5} {t 1.5-1.5}}
+test package-3.18 {Tcl_PkgRequire procedure, version checks} -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package require t
+} -result {2.3}
+test package-3.19 {Tcl_PkgRequire procedure, version checks} -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package require t 2.1
+} -result {2.3}
+test package-3.20 {Tcl_PkgRequire procedure, version checks} -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package require t 2.3
+} -result {2.3}
+test package-3.21 {Tcl_PkgRequire procedure, version checks} -setup {
+ package forget t
+} -returnCodes error -body {
+ package provide t 2.3
+ package require t 2.4
+} -result {version conflict for package "t": have 2.3, need 2.4}
+test package-3.22 {Tcl_PkgRequire procedure, version checks} -setup {
+ package forget t
+} -returnCodes error -body {
+ package provide t 2.3
+ package require t 1.2
+} -result {version conflict for package "t": have 2.3, need 1.2}
+test package-3.23 {Tcl_PkgRequire procedure, version checks} -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package require -exact t 2.3
+} -result {2.3}
+test package-3.24 {Tcl_PkgRequire procedure, version checks} -setup {
+ package forget t
+} -returnCodes error -body {
+ package provide t 2.3
+ package require -exact t 2.2
+} -result {version conflict for package "t": have 2.3, need exactly 2.2}
+test package-3.25 {Tcl_PkgRequire procedure, error in ifneeded script} -setup {
+ package forget t
+} -body {
+ package ifneeded t 2.1 {package provide t 2.1; error "ifneeded test" EI}
+ list [catch {package require t 2.1} msg] $msg $::errorInfo
+} -match glob -result {1 {ifneeded test} {EI
+ ("package ifneeded*" script)
+ invoked from within
+"package require t 2.1"}}
+test package-3.26 {Tcl_PkgRequire procedure, error in ifneeded script} -setup {
+ package forget t
+} -body {
+ package ifneeded t 2.1 {package provide t 2.1; foreach x 1 {error "ifneeded test" EI}}
+ list [catch {package require t 2.1} msg] $msg $::errorInfo
+} -match glob -result {1 {ifneeded test} {EI
+ ("foreach" body line 1)
+ invoked from within
+"foreach x 1 {error "ifneeded test" EI}"
+ ("package ifneeded*" script)
+ invoked from within
+"package require t 2.1"}}
+test package-3.27 {Tcl_PkgRequire: circular dependency} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {package require foo 1}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob -result {circular package dependency:*}
+test package-3.28 {Tcl_PkgRequire: circular dependency} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {package require foo 2}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob -result {circular package dependency:*}
+test package-3.29 {Tcl_PkgRequire: circular dependency} -setup {
+ package forget foo
+ package forget bar
+} -body {
+ package ifneeded foo 1 {package require bar 1; package provide foo 1}
+ package ifneeded bar 1 {package require foo 1; package provide bar 1}
+ package require foo 1
+} -cleanup {
+ package forget foo
+ package forget bar
+} -returnCodes error -match glob -result {circular package dependency:*}
+test package-3.30 {Tcl_PkgRequire: circular dependency} -setup {
+ package forget foo
+ package forget bar
+} -body {
+ package ifneeded foo 1 {package require bar 1; package provide foo 1}
+ package ifneeded foo 2 {package provide foo 2}
+ package ifneeded bar 1 {package require foo 2; package provide bar 1}
+ package require foo 1
+} -cleanup {
+ package forget foo
+ package forget bar
+} -returnCodes error -match glob -result {circular package dependency:*}
+test package-3.31 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {package provide foo 1; error foo}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob -result foo
+test package-3.32 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {package provide foo 1; error foo}
+ catch {package require foo 1}
+ package provide foo
+} -cleanup {
+ package forget foo
+} -result {}
+test package-3.33 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {package provide foo 2}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob -result {attempt to provide package * failed:*}
+test package-3.34 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {package provide foo 1.1}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob -result {attempt to provide package * failed:*}
+test package-3.34.1 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1.1 {package provide foo 1}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob -result {attempt to provide package * failed:*}
+test package-3.34.2 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1.1 {package provide foo 1}
+ package require foo 1.1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob -result {attempt to provide package * failed:*}
+test package-3.35 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob -result {attempt to provide package * failed:*}
+test package-3.35.1 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {break}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob \
+-result {attempt to provide package * failed: bad return code:*}
+test package-3.36 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {continue}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob \
+-result {attempt to provide package * failed: bad return code:*}
+test package-3.37 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {return}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob \
+-result {attempt to provide package * failed: bad return code:*}
+test package-3.38 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+} -body {
+ package ifneeded foo 1 {return -level 0 -code 10}
+ package require foo 1
+} -cleanup {
+ package forget foo
+} -returnCodes error -match glob \
+-result {attempt to provide package * failed: bad return code:*}
+test package-3.39 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+ set saveUnknown [package unknown]
+ package unknown {package provide foo 2 ;#}
+} -body {
+ package require foo 1
+} -cleanup {
+ package forget foo
+ package unknown $saveUnknown
+} -returnCodes error -match glob -result *
+test package-3.40 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+ set saveUnknown [package unknown]
+ package unknown {break ;#}
+} -body {
+ package require foo 1
+} -cleanup {
+ package forget foo
+ package unknown $saveUnknown
+} -returnCodes error -match glob -result {bad return code:*}
+test package-3.41 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+ set saveUnknown [package unknown]
+ package unknown {continue ;#}
+} -body {
+ package require foo 1
+} -cleanup {
+ package forget foo
+ package unknown $saveUnknown
+} -returnCodes error -match glob -result {bad return code:*}
+test package-3.42 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+ set saveUnknown [package unknown]
+ package unknown {return ;#}
+} -body {
+ package require foo 1
+} -cleanup {
+ package forget foo
+ package unknown $saveUnknown
+} -returnCodes error -match glob -result {bad return code:*}
+test package-3.43 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+ package forget foo
+ set saveUnknown [package unknown]
+ package unknown {return -level 0 -code 10 ;#}
+} -body {
+ package require foo 1
+} -cleanup {
+ package forget foo
+ package unknown $saveUnknown
+} -returnCodes error -match glob -result {bad return code:*}
+test package-3.44 {Tcl_PkgRequire: exact version matching (1578344)} -setup {
+ package provide demo 1.2.3
+} -body {
+ package require -exact demo 1.2
+} -returnCodes error -cleanup {
+ package forget demo
+} -result {version conflict for package "demo": have 1.2.3, need exactly 1.2}
+test package-3.50 {Tcl_PkgRequire procedure, picking best stable version} -setup {
+ package forget t
+ set x xxx
+} -body {
+ foreach i {1.4 3.4 4.0a1 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ package require t
+ return $x
+} -result {3.4}
+test package-3.51 {Tcl_PkgRequire procedure, picking best stable version} -setup {
+ package forget t
+ set x xxx
+} -body {
+ foreach i {1.2b1 1.2 1.3a2 1.3} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ package require t
+ return $x
+} -result {1.3}
+test package-3.52 {Tcl_PkgRequire procedure, picking best stable version} -setup {
+ package forget t
+ set x xxx
+} -body {
+ foreach i {1.2b1 1.2 1.3 1.3a2} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ package require t
+ return $x
+} -result {1.3}
+
+test package-4.1 {Tcl_PackageCmd procedure} -returnCodes error -body {
+ package
+} -result {wrong # args: should be "package option ?arg ...?"}
+test package-4.2 {Tcl_PackageCmd procedure, "forget" option} {
+ package forget {*}[package names]
+ package names
+} {}
+test package-4.3 {Tcl_PackageCmd procedure, "forget" option} {
+ package forget {*}[package names]
+ package forget foo
+} {}
+test package-4.4 {Tcl_PackageCmd procedure, "forget" option} -setup {
+ package forget {*}[package names]
+ set result {}
+} -body {
+ package ifneeded t 1.1 {first script}
+ package ifneeded t 2.3 {second script}
+ package ifneeded x 1.4 {x's script}
+ lappend result [lsort [package names]] [package versions t]
+ package forget t
+ lappend result [lsort [package names]] [package versions t]
+} -result {{t x} {1.1 2.3} x {}}
+test package-4.5 {Tcl_PackageCmd procedure, "forget" option} -setup {
+ package forget {*}[package names]
+} -body {
+ package ifneeded a 1.1 {first script}
+ package ifneeded b 2.3 {second script}
+ package ifneeded c 1.4 {third script}
+ package forget
+ set result [list [lsort [package names]]]
+ package forget a c
+ lappend result [lsort [package names]]
+} -result {{a b c} b}
+test package-4.5.1 {Tcl_PackageCmd procedure, "forget" option} -body {
+ # Test for Bug 415273
+ package ifneeded a 1 "I should have been forgotten"
+ package forget no-such-package a
+ package ifneeded a 1
+} -cleanup {
+ package forget a
+} -result {}
+test package-4.6 {Tcl_PackageCmd procedure, "ifneeded" option} -body {
+ package ifneeded a
+} -returnCodes error -result {wrong # args: should be "package ifneeded package version ?script?"}
+test package-4.7 {Tcl_PackageCmd procedure, "ifneeded" option} -body {
+ package ifneeded a b c d
+} -returnCodes error -result {wrong # args: should be "package ifneeded package version ?script?"}
+test package-4.8 {Tcl_PackageCmd procedure, "ifneeded" option} -body {
+ package ifneeded t xyz
+} -returnCodes error -result {expected version number but got "xyz"}
+test package-4.9 {Tcl_PackageCmd procedure, "ifneeded" option} {
+ package forget {*}[package names]
+ list [package ifneeded foo 1.1] [package names]
+} {{} {}}
+test package-4.10 {Tcl_PackageCmd procedure, "ifneeded" option} -setup {
+ package forget t
+} -body {
+ package ifneeded t 1.4 "script for t 1.4"
+ list [package names] [package ifneeded t 1.4] [package versions t]
+} -result {t {script for t 1.4} 1.4}
+test package-4.11 {Tcl_PackageCmd procedure, "ifneeded" option} -setup {
+ package forget t
+} -body {
+ package ifneeded t 1.4 "script for t 1.4"
+ list [package ifneeded t 1.5] [package names] [package versions t]
+} -result {{} t 1.4}
+test package-4.12 {Tcl_PackageCmd procedure, "ifneeded" option} -setup {
+ package forget t
+} -body {
+ package ifneeded t 1.4 "script for t 1.4"
+ package ifneeded t 1.4 "second script for t 1.4"
+ list [package ifneeded t 1.4] [package names] [package versions t]
+} -result {{second script for t 1.4} t 1.4}
+test package-4.13 {Tcl_PackageCmd procedure, "ifneeded" option} -setup {
+ package forget t
+} -body {
+ package ifneeded t 1.4 "script for t 1.4"
+ package ifneeded t 1.2 "second script"
+ package ifneeded t 3.1 "last script"
+ list [package ifneeded t 1.2] [package versions t]
+} -result {{second script} {1.4 1.2 3.1}}
+test package-4.14 {Tcl_PackageCmd procedure, "names" option} -body {
+ package names a
+} -returnCodes error -result {wrong # args: should be "package names"}
+test package-4.15 {Tcl_PackageCmd procedure, "names" option} {
+ package forget {*}[package names]
+ package names
+} {}
+test package-4.16 {Tcl_PackageCmd procedure, "names" option} -setup {
+ package forget {*}[package names]
+} -body {
+ package ifneeded x 1.2 {dummy}
+ package provide x 1.3
+ package provide y 2.4
+ catch {package require z 47.16}
+ lsort [package names]
+} -result {x y}
+test package-4.17 {Tcl_PackageCmd procedure, "provide" option} -body {
+ package provide
+} -returnCodes error -result {wrong # args: should be "package provide package ?version?"}
+test package-4.18 {Tcl_PackageCmd procedure, "provide" option} -body {
+ package provide a b c
+} -returnCodes error -result {wrong # args: should be "package provide package ?version?"}
+test package-4.19 {Tcl_PackageCmd procedure, "provide" option} -setup {
+ package forget t
+} -body {
+ package provide t
+} -result {}
+test package-4.20 {Tcl_PackageCmd procedure, "provide" option} -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package provide t
+} -result {2.3}
+test package-4.21 {Tcl_PackageCmd procedure, "provide" option} -setup {
+ package forget t
+} -returnCodes error -body {
+ package provide t a.b
+} -result {expected version number but got "a.b"}
+test package-4.22 {Tcl_PackageCmd procedure, "require" option} -returnCodes error -body {
+ package require
+} -result {wrong # args: should be "package require ?-exact? package ?requirement ...?"}
+test package-4.24 {Tcl_PackageCmd procedure, "require" option} -body {
+ package require -exact a b c
+ # Exact syntax: -exact name version
+ # name ?requirement ...?
+} -returnCodes error -result {wrong # args: should be "package require ?-exact? package ?requirement ...?"}
+test package-4.26 {Tcl_PackageCmd procedure, "require" option} -body {
+ package require x a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-4.27 {Tcl_PackageCmd procedure, "require" option} -body {
+ package require -exact x a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-4.28 {Tcl_PackageCmd procedure, "require" option} -body {
+ package require -exact x
+} -returnCodes error -result {wrong # args: should be "package require ?-exact? package ?requirement ...?"}
+test package-4.29 {Tcl_PackageCmd procedure, "require" option} -body {
+ package require -exact
+} -returnCodes error -result {wrong # args: should be "package require ?-exact? package ?requirement ...?"}
+test package-4.30 {Tcl_PackageCmd procedure, "require" option} -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package require t 2.1
+} -result {2.3}
+test package-4.31 {Tcl_PackageCmd procedure, "require" option} -setup {
+ package forget t
+} -body {
+ package require t
+} -returnCodes error -result {can't find package t}
+test package-4.32 {Tcl_PackageCmd procedure, "require" option} -setup {
+ package forget t
+} -body {
+ package ifneeded t 2.3 "error {synthetic error}"
+ package require t 2.3
+} -returnCodes error -result {synthetic error}
+test package-4.33 {Tcl_PackageCmd procedure, "unknown" option} -body {
+ package unknown a b
+} -returnCodes error -result {wrong # args: should be "package unknown ?command?"}
+test package-4.34 {Tcl_PackageCmd procedure, "unknown" option} {
+ package unknown "test script"
+ package unknown
+} {test script}
+test package-4.35 {Tcl_PackageCmd procedure, "unknown" option} {
+ package unknown "test script"
+ package unknown {}
+ package unknown
+} {}
+test package-4.36 {Tcl_PackageCmd procedure, "vcompare" option} -body {
+ package vcompare a
+} -returnCodes error -result {wrong # args: should be "package vcompare version1 version2"}
+test package-4.37 {Tcl_PackageCmd procedure, "vcompare" option} -body {
+ package vcompare a b c
+} -returnCodes error -result {wrong # args: should be "package vcompare version1 version2"}
+test package-4.38 {Tcl_PackageCmd procedure, "vcompare" option} -body {
+ package vcompare x.y 3.4
+} -returnCodes error -result {expected version number but got "x.y"}
+test package-4.39 {Tcl_PackageCmd procedure, "vcompare" option} -body {
+ package vcompare 2.1 a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-4.40 {Tcl_PackageCmd procedure, "vcompare" option} {
+ package vc 2.1 2.3
+} {-1}
+test package-4.41 {Tcl_PackageCmd procedure, "vcompare" option} {
+ package vc 2.2.4 2.2.4
+} {0}
+test package-4.42 {Tcl_PackageCmd procedure, "versions" option} -body {
+ package versions
+} -returnCodes error -result {wrong # args: should be "package versions package"}
+test package-4.43 {Tcl_PackageCmd procedure, "versions" option} -body {
+ package versions a b
+} -returnCodes error -result {wrong # args: should be "package versions package"}
+test package-4.44 {Tcl_PackageCmd procedure, "versions" option} -body {
+ package forget t
+ package versions t
+} -result {}
+test package-4.45 {Tcl_PackageCmd procedure, "versions" option} -setup {
+ package forget t
+} -body {
+ package provide t 2.3
+ package versions t
+} -result {}
+test package-4.46 {Tcl_PackageCmd procedure, "versions" option} -setup {
+ package forget t
+} -body {
+ package ifneeded t 2.3 x
+ package ifneeded t 2.4 y
+ package versions t
+} -result {2.3 2.4}
+test package-4.47 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+ package vsatisfies a
+} -returnCodes error -result {wrong # args: should be "package vsatisfies version ?requirement ...?"}
+test package-4.49 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+ package vsatisfies x.y 3.4
+} -returnCodes error -result {expected version number but got "x.y"}
+test package-4.50 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+ package vcompare 2.1 a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-4.51 {Tcl_PackageCmd procedure, "vsatisfies" option} {
+ package vs 2.3 2.1
+} {1}
+test package-4.52 {Tcl_PackageCmd procedure, "vsatisfies" option} {
+ package vs 2.3 1.2
+} {0}
+test package-4.53 {Tcl_PackageCmd procedure, "versions" option} -body {
+ package foo
+} -returnCodes error -result {bad option "foo": must be forget, ifneeded, names, prefer, present, provide, require, unknown, vcompare, versions, or vsatisfies}
+test package-4.54 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+ package vsatisfies 2.1 2.1-3.2-4.5
+} -returnCodes error -result {expected versionMin-versionMax but got "2.1-3.2-4.5"}
+test package-4.55 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+ package vsatisfies 2.1 3.2-x.y
+} -returnCodes error -result {expected version number but got "x.y"}
+test package-4.56 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+ package vsatisfies 2.1 x.y-3.2
+} -returnCodes error -result {expected version number but got "x.y"}
+
+# No tests for FindPackage; can't think up anything detectable errors.
+
+test package-5.1 {TclFreePackageInfo procedure} {
+ interp create slave
+ slave eval {
+ package ifneeded t 2.3 x
+ package ifneeded t 2.4 y
+ package ifneeded x 3.1 z
+ package provide q 4.3
+ package unknown "will this get freed?"
+ }
+ interp delete slave
+} {}
+test package-5.2 {TclFreePackageInfo procedure} -body {
+ interp create foo
+ foo eval {
+ package ifneeded t 2.3 x
+ package ifneeded t 2.4 y
+ package ifneeded x 3.1 z
+ package provide q 4.3
+ }
+ foo alias z kill
+ proc kill {} {
+ interp delete foo
+ }
+ foo eval package require x 3.1
+} -returnCodes error -match glob -result *
+
+test package-6.1 {CheckVersion procedure} {
+ package vcompare 1 2.1
+} -1
+test package-6.2 {CheckVersion procedure} -body {
+ package vcompare .1 2.1
+} -returnCodes error -result {expected version number but got ".1"}
+test package-6.3 {CheckVersion procedure} -body {
+ package vcompare 111.2a.3 2.1
+} -returnCodes error -result {expected version number but got "111.2a.3"}
+test package-6.4 {CheckVersion procedure} -body {
+ package vcompare 1.2.3. 2.1
+} -returnCodes error -result {expected version number but got "1.2.3."}
+test package-6.5 {CheckVersion procedure} -body {
+ package vcompare 1.2..3 2.1
+} -returnCodes error -result {expected version number but got "1.2..3"}
+
+test package-7.1 {ComparePkgVersions procedure} {
+ package vcompare 1.23 1.22
+} {1}
+test package-7.2 {ComparePkgVersions procedure} {
+ package vcompare 1.22.1.2.3 1.22.1.2.3
+} {0}
+test package-7.3 {ComparePkgVersions procedure} {
+ package vcompare 1.21 1.22
+} {-1}
+test package-7.4 {ComparePkgVersions procedure} {
+ package vcompare 1.21 1.21.2
+} {-1}
+test package-7.5 {ComparePkgVersions procedure} {
+ package vcompare 1.21.1 1.21
+} {1}
+test package-7.6 {ComparePkgVersions procedure} {
+ package vsatisfies 1.21.1 1.21
+} {1}
+test package-7.7 {ComparePkgVersions procedure} {
+ package vsatisfies 2.22.3 1.21
+} {0}
+test package-7.8 {ComparePkgVersions procedure} {
+ package vsatisfies 1 1
+} {1}
+test package-7.9 {ComparePkgVersions procedure} {
+ package vsatisfies 2 1
+} {0}
+
+test package-8.1 {Tcl_PkgPresent procedure, any version} -setup {
+ package forget t
+} -body {
+ package provide t 2.4
+ package present t
+} -result {2.4}
+test package-8.2 {Tcl_PkgPresent procedure, correct version} -setup {
+ package forget t
+} -body {
+ package provide t 2.4
+ package present t 2.4
+} -result {2.4}
+test package-8.3 {Tcl_PkgPresent procedure, satisfying version} -setup {
+ package forget t
+} -body {
+ package provide t 2.4
+ package present t 2.0
+} -result {2.4}
+test package-8.4 {Tcl_PkgPresent procedure, not satisfying version} -setup {
+ package forget t
+} -returnCodes error -body {
+ package provide t 2.4
+ package present t 2.6
+} -result {version conflict for package "t": have 2.4, need 2.6}
+test package-8.5 {Tcl_PkgPresent procedure, not satisfying version} -setup {
+ package forget t
+} -returnCodes error -body {
+ package provide t 2.4
+ package present t 1.0
+} -result {version conflict for package "t": have 2.4, need 1.0}
+test package-8.6 {Tcl_PkgPresent procedure, exact version} -setup {
+ package forget t
+} -body {
+ package provide t 2.4
+ package present -exact t 2.4
+} -result {2.4}
+test package-8.7 {Tcl_PkgPresent procedure, not exact version} -setup {
+ package forget t
+} -returnCodes error -body {
+ package provide t 2.4
+ package present -exact t 2.3
+} -result {version conflict for package "t": have 2.4, need exactly 2.3}
+test package-8.8 {Tcl_PkgPresent procedure, unknown package} -body {
+ package forget t
+ package present t
+} -returnCodes error -result {package t is not present}
+test package-8.9 {Tcl_PkgPresent procedure, unknown package} -body {
+ package forget t
+ package present t 2.4
+} -returnCodes error -result {package t 2.4 is not present}
+test package-8.10 {Tcl_PkgPresent procedure, unknown package} -body {
+ package forget t
+ package present -exact t 2.4
+} -returnCodes error -result {package t 2.4 is not present}
+test package-8.11 {Tcl_PackageCmd procedure, "present" option} -body {
+ package present
+} -returnCodes error -result {wrong # args: should be "package present ?-exact? package ?requirement ...?"}
+test package-8.12 {Tcl_PackageCmd procedure, "present" option} -body {
+ package present a b c
+} -returnCodes error -result {expected version number but got "b"}
+test package-8.13 {Tcl_PackageCmd procedure, "present" option} -body {
+ package present -exact a b c
+} -returnCodes error -result {wrong # args: should be "package present ?-exact? package ?requirement ...?"}
+test package-8.14 {Tcl_PackageCmd procedure, "present" option} -body {
+ package present -bs a b
+} -returnCodes error -result {expected version number but got "a"}
+test package-8.15 {Tcl_PackageCmd procedure, "present" option} -body {
+ package present x a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-8.16 {Tcl_PackageCmd procedure, "present" option} -body {
+ package present -exact x a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-8.17 {Tcl_PackageCmd procedure, "present" option} -body {
+ package present -exact x
+} -returnCodes error -result {wrong # args: should be "package present ?-exact? package ?requirement ...?"}
+test package-8.18 {Tcl_PackageCmd procedure, "present" option} -body {
+ package present -exact
+} -returnCodes error -result {wrong # args: should be "package present ?-exact? package ?requirement ...?"}
+
+set n 0
+foreach {r p vs vc} {
+ 8.5a0 8.5a5 1 -1
+ 8.5a0 8.5b1 1 -1
+ 8.5a0 8.5.1 1 -1
+ 8.5a0 8.6a0 1 -1
+ 8.5a0 8.6b0 1 -1
+ 8.5a0 8.6.0 1 -1
+ 8.5a6 8.5a5 0 1
+ 8.5a6 8.5b1 1 -1
+ 8.5a6 8.5.1 1 -1
+ 8.5a6 8.6a0 1 -1
+ 8.5a6 8.6b0 1 -1
+ 8.5a6 8.6.0 1 -1
+ 8.5b0 8.5a5 0 1
+ 8.5b0 8.5b1 1 -1
+ 8.5b0 8.5.1 1 -1
+ 8.5b0 8.6a0 1 -1
+ 8.5b0 8.6b0 1 -1
+ 8.5b0 8.6.0 1 -1
+ 8.5b2 8.5a5 0 1
+ 8.5b2 8.5b1 0 1
+ 8.5b2 8.5.1 1 -1
+ 8.5b2 8.6a0 1 -1
+ 8.5b2 8.6b0 1 -1
+ 8.5b2 8.6.0 1 -1
+ 8.5 8.5a5 1 1
+ 8.5 8.5b1 1 1
+ 8.5 8.5.1 1 -1
+ 8.5 8.6a0 1 -1
+ 8.5 8.6b0 1 -1
+ 8.5 8.6.0 1 -1
+ 8.5.0 8.5a5 0 1
+ 8.5.0 8.5b1 0 1
+ 8.5.0 8.5.1 1 -1
+ 8.5.0 8.6a0 1 -1
+ 8.5.0 8.6b0 1 -1
+ 8.5.0 8.6.0 1 -1
+ 10 8 0 1
+ 8 10 0 -1
+ 0.0.1.2 0.1.2 1 -1
+} {
+ test package-9.$n {package vsatisfies} {
+ package vsatisfies $p $r
+ } $vs
+ test package-10.$n {package vcompare} {
+ package vcompare $r $p
+ } $vc
+ incr n
+}
+
+test package-11.0.0 {package vcompare at 32bit boundary} {
+ package vcompare [expr {1<<31}] [expr {(1<<31)-1}]
+} 1
+
+# Note: It is correct that the result of the very first test, i.e. "5.0 5.0a0"
+# is 1, i.e. that version 5.0a0 satisfies a 5.0 requirement.
+
+# The requirement "5.0" internally translates first to "5.0-6", and then to
+# its final form of "5.0a0-6a0". These translations are explicitly specified
+# by the TIP (Search for "padded/extended internally with 'a0'"). This was
+# done intentionally for exactly the tested case, that an alpha package can
+# satisfy a requirement for the regular package. An example would be a package
+# FOO requiring Tcl 8.X for its operation. It can be used with Tcl 8.Xa0.
+# Without our translation that would not be possible.
+
+set n 0
+foreach {required provided satisfied} {
+ 5.0 5.0a0 1
+ 5.0a0 5.0 1
+
+ 8.5a0- 8.5a5 1
+ 8.5a0- 8.5b1 1
+ 8.5a0- 8.5.1 1
+ 8.5a0- 8.6a0 1
+ 8.5a0- 8.6b0 1
+ 8.5a0- 8.6.0 1
+ 8.5a6- 8.5a5 0
+ 8.5a6- 8.5b1 1
+ 8.5a6- 8.5.1 1
+ 8.5a6- 8.6a0 1
+ 8.5a6- 8.6b0 1
+ 8.5a6- 8.6.0 1
+ 8.5b0- 8.5a5 0
+ 8.5b0- 8.5b1 1
+ 8.5b0- 8.5.1 1
+ 8.5b0- 8.6a0 1
+ 8.5b0- 8.6b0 1
+ 8.5b0- 8.6.0 1
+ 8.5b2- 8.5a5 0
+ 8.5b2- 8.5b1 0
+ 8.5b2- 8.5.1 1
+ 8.5b2- 8.6a0 1
+ 8.5b2- 8.6b0 1
+ 8.5b2- 8.6.0 1
+ 8.5- 8.5a5 1
+ 8.5- 8.5b1 1
+ 8.5- 8.5.1 1
+ 8.5- 8.6a0 1
+ 8.5- 8.6b0 1
+ 8.5- 8.6.0 1
+ 8.5.0- 8.5a5 0
+ 8.5.0- 8.5b1 0
+ 8.5.0- 8.5.1 1
+ 8.5.0- 8.6a0 1
+ 8.5.0- 8.6b0 1
+ 8.5.0- 8.6.0 1
+ 8.5a0-7 8.5a5 0
+ 8.5a0-7 8.5b1 0
+ 8.5a0-7 8.5.1 0
+ 8.5a0-7 8.6a0 0
+ 8.5a0-7 8.6b0 0
+ 8.5a0-7 8.6.0 0
+ 8.5a6-7 8.5a5 0
+ 8.5a6-7 8.5b1 0
+ 8.5a6-7 8.5.1 0
+ 8.5a6-7 8.6a0 0
+ 8.5a6-7 8.6b0 0
+ 8.5a6-7 8.6.0 0
+ 8.5b0-7 8.5a5 0
+ 8.5b0-7 8.5b1 0
+ 8.5b0-7 8.5.1 0
+ 8.5b0-7 8.6a0 0
+ 8.5b0-7 8.6b0 0
+ 8.5b0-7 8.6.0 0
+ 8.5b2-7 8.5a5 0
+ 8.5b2-7 8.5b1 0
+ 8.5b2-7 8.5.1 0
+ 8.5b2-7 8.6a0 0
+ 8.5b2-7 8.6b0 0
+ 8.5b2-7 8.6.0 0
+ 8.5-7 8.5a5 0
+ 8.5-7 8.5b1 0
+ 8.5-7 8.5.1 0
+ 8.5-7 8.6a0 0
+ 8.5-7 8.6b0 0
+ 8.5-7 8.6.0 0
+ 8.5.0-7 8.5a5 0
+ 8.5.0-7 8.5b1 0
+ 8.5.0-7 8.5.1 0
+ 8.5.0-7 8.6a0 0
+ 8.5.0-7 8.6b0 0
+ 8.5.0-7 8.6.0 0
+ 8.5a0-8.6.1 8.5a5 1
+ 8.5a0-8.6.1 8.5b1 1
+ 8.5a0-8.6.1 8.5.1 1
+ 8.5a0-8.6.1 8.6a0 1
+ 8.5a0-8.6.1 8.6b0 1
+ 8.5a0-8.6.1 8.6.0 1
+ 8.5a6-8.6.1 8.5a5 0
+ 8.5a6-8.6.1 8.5b1 1
+ 8.5a6-8.6.1 8.5.1 1
+ 8.5a6-8.6.1 8.6a0 1
+ 8.5a6-8.6.1 8.6b0 1
+ 8.5a6-8.6.1 8.6.0 1
+ 8.5b0-8.6.1 8.5a5 0
+ 8.5b0-8.6.1 8.5b1 1
+ 8.5b0-8.6.1 8.5.1 1
+ 8.5b0-8.6.1 8.6a0 1
+ 8.5b0-8.6.1 8.6b0 1
+ 8.5b0-8.6.1 8.6.0 1
+ 8.5b2-8.6.1 8.5a5 0
+ 8.5b2-8.6.1 8.5b1 0
+ 8.5b2-8.6.1 8.5.1 1
+ 8.5b2-8.6.1 8.6a0 1
+ 8.5b2-8.6.1 8.6b0 1
+ 8.5b2-8.6.1 8.6.0 1
+ 8.5-8.6.1 8.5a5 1
+ 8.5-8.6.1 8.5b1 1
+ 8.5-8.6.1 8.5.1 1
+ 8.5-8.6.1 8.6a0 1
+ 8.5-8.6.1 8.6b0 1
+ 8.5-8.6.1 8.6.0 1
+ 8.5.0-8.6.1 8.5a5 0
+ 8.5.0-8.6.1 8.5b1 0
+ 8.5.0-8.6.1 8.5.1 1
+ 8.5.0-8.6.1 8.6a0 1
+ 8.5.0-8.6.1 8.6b0 1
+ 8.5.0-8.6.1 8.6.0 1
+ 8.5a0-8.5a0 8.5a0 1
+ 8.5a0-8.5a0 8.5b1 0
+ 8.5a0-8.5a0 8.4 0
+ 8.5b0-8.5b0 8.5a5 0
+ 8.5b0-8.5b0 8.5b0 1
+ 8.5b0-8.5b0 8.5.1 0
+ 8.5-8.5 8.5a5 0
+ 8.5-8.5 8.5b1 0
+ 8.5-8.5 8.5 1
+ 8.5-8.5 8.5.1 0
+ 8.5.0-8.5.0 8.5a5 0
+ 8.5.0-8.5.0 8.5b1 0
+ 8.5.0-8.5.0 8.5.0 1
+ 8.5.0-8.5.0 8.5.1 0
+ 8.5.0-8.5.0 8.6a0 0
+ 8.5.0-8.5.0 8.6b0 0
+ 8.5.0-8.5.0 8.6.0 0
+ 8.2 9 0
+ 8.2- 9 1
+ 8.2-8.5 9 0
+ 8.2-9.1 9 1
+
+ 8.5-8.5 8.5b1 0
+ 8.5a0-8.5 8.5b1 0
+ 8.5a0-8.5.1 8.5b1 1
+
+ 8.5-8.5 8.5 1
+ 8.5.0-8.5.0 8.5 1
+ 8.5a0-8.5.0 8.5 0
+} {
+ test package-11.$n "package vsatisfies $provided $required" {
+ package vsatisfies $provided $required
+ } $satisfied
+ incr n
+}
+
+test package-12.0 "package vsatisfies multiple" {
+ # yes no
+ package vsatisfies 8.4 8.4 7.3
+} 1
+test package-12.1 "package vsatisfies multiple" {
+ # no yes
+ package vsatisfies 8.4 7.3 8.4
+} 1
+test package-12.2 "package vsatisfies multiple" {
+ # yes yes
+ package vsatisfies 8.4.2 8.4 8.4.1
+} 1
+test package-12.3 "package vsatisfies multiple" {
+ # no no
+ package vsatisfies 8.4 7.3 6.1
+} 0
+
+proc prefer {args} {
+ set ip [interp create]
+ try {
+ lappend res [$ip eval {package prefer}]
+ foreach mode $args {
+ lappend res [$ip eval [list package prefer $mode]]
+ }
+ return $res
+ } finally {
+ interp delete $ip
+ }
+}
+
+test package-13.0 {package prefer defaults} {
+ prefer
+} stable
+test package-13.1 {package prefer defaults} -body {
+ set ::env(TCL_PKG_PREFER_LATEST) stable ;# value not relevant!
+ prefer
+} -cleanup {
+ unset -nocomplain ::env(TCL_PKG_PREFER_LATEST)
+} -result latest
+
+test package-14.0 {wrong\#args} -returnCodes error -body {
+ package prefer foo bar
+} -result {wrong # args: should be "package prefer ?latest|stable?"}
+test package-14.1 {bogus argument} -returnCodes error -body {
+ package prefer foo
+} -result {bad preference "foo": must be latest or stable}
+
+test package-15.0 {set, keep} {package prefer stable} stable
+test package-15.1 {set stable, keep} {prefer stable} {stable stable}
+test package-15.2 {set latest, change} {prefer latest} {stable latest}
+test package-15.3 {set latest, keep} {
+ prefer latest latest
+} {stable latest latest}
+test package-15.4 {set stable, rejected} {
+ prefer latest stable
+} {stable latest latest}
+
+rename prefer {}
+
+set auto_path $oldPath
+package unknown $oldPkgUnknown
+
+cleanupTests
+}
+
+# cleanup
+interp delete $i
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/parse.test b/pkgs/msgcat/tests/parse.test
new file mode 100644
index 0000000..3523975
--- /dev/null
+++ b/pkgs/msgcat/tests/parse.test
@@ -0,0 +1,1094 @@
+# This file contains a collection of tests for the procedures in the
+# file tclParse.c. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[catch {package require tcltest 2.0.2}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2.0.2 required."
+ return
+}
+
+namespace eval ::tcl::test::parse {
+ namespace import ::tcltest::*
+
+testConstraint testparser [llength [info commands testparser]]
+testConstraint testevalobjv [llength [info commands testevalobjv]]
+testConstraint testevalex [llength [info commands testevalex]]
+testConstraint testparsevarname [llength [info commands testparsevarname]]
+testConstraint testparsevar [llength [info commands testparsevar]]
+testConstraint testasync [llength [info commands testasync]]
+testConstraint testcmdtrace [llength [info commands testcmdtrace]]
+
+test parse-1.1 {Tcl_ParseCommand procedure, computing string length} testparser {
+ testparser [bytestring "foo\0 bar"] -1
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-1.2 {Tcl_ParseCommand procedure, computing string length} testparser {
+ testparser "foo bar" -1
+} {- {foo bar} 2 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
+test parse-1.3 {Tcl_ParseCommand procedure, leading space} testparser {
+ testparser " \n\t foo" 0
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-1.4 {Tcl_ParseCommand procedure, leading space} testparser {
+ testparser "\f\r\vfoo" 0
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-1.5 {Tcl_ParseCommand procedure, backslash-newline in leading space} testparser {
+ testparser " \\\n foo" 0
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-1.6 {Tcl_ParseCommand procedure, backslash-newline in leading space} testparser {
+ testparser { \a foo} 0
+} {- {\a foo} 2 word {\a} 1 backslash {\a} 0 simple foo 1 text foo 0 {}}
+test parse-1.7 {Tcl_ParseCommand procedure, missing continuation line in leading space} testparser {
+ testparser " \\\n" 0
+} {- {} 0 {}}
+test parse-1.8 {Tcl_ParseCommand procedure, eof in leading space} testparser {
+ testparser " foo" 3
+} {- {} 0 { foo}}
+test parse-1.9 {Tcl_ParseCommand procedure, backslash newline + newline} testparser {
+ testparser "cmd1\\\n\ncmd2" 0
+} {- cmd1\\\n\n 1 simple cmd1 1 text cmd1 0 cmd2}
+test parse-1.10 {Tcl_ParseCommand procedure, backslash newline + newline} testparser {
+ testparser "list \\\nA B\\\n\nlist C D" 0
+} {- list\ \\\nA\ B\\\n\n 3 simple list 1 text list 0 simple A 1 text A 0 simple B 1 text B 0 {list C D}}
+
+test parse-2.1 {Tcl_ParseCommand procedure, comments} testparser {
+ testparser "# foo bar\n foo" 0
+} {{# foo bar
+} foo 1 simple foo 1 text foo 0 {}}
+test parse-2.2 {Tcl_ParseCommand procedure, several comments} testparser {
+ testparser " # foo bar\n # another comment\n\n foo" 0
+} {{# foo bar
+ # another comment
+} foo 1 simple foo 1 text foo 0 {}}
+test parse-2.3 {Tcl_ParseCommand procedure, backslash-newline in comments} testparser {
+ testparser " # foo bar\\\ncomment on continuation line\nfoo" 0
+} {\#\ foo\ bar\\\ncomment\ on\ continuation\ line\n foo 1 simple foo 1 text foo 0 {}}
+test parse-2.4 {Tcl_ParseCommand procedure, missing continuation line in comment} testparser {
+ testparser "# \\\n" 0
+} {\#\ \ \ \\\n {} 0 {}}
+test parse-2.5 {Tcl_ParseCommand procedure, eof in comment} testparser {
+ testparser " # foo bar\nfoo" 8
+} {{# foo b} {} 0 {ar
+foo}}
+
+test parse-3.1 {Tcl_ParseCommand procedure, parsing words, skipping space} testparser {
+ testparser "foo bar\t\tx" 0
+} {- {foo bar x} 3 simple foo 1 text foo 0 simple bar 1 text bar 0 simple x 1 text x 0 {}}
+test parse-3.2 {Tcl_ParseCommand procedure, missing continuation line in leading space} testparser {
+ testparser "abc \\\n" 0
+} {- abc\ \ \\\n 1 simple abc 1 text abc 0 {}}
+test parse-3.3 {Tcl_ParseCommand procedure, parsing words, command ends in space} testparser {
+ testparser "foo ; bar x" 0
+} {- {foo ;} 1 simple foo 1 text foo 0 { bar x}}
+test parse-3.4 {Tcl_ParseCommand procedure, parsing words, command ends in space} testparser {
+ testparser "foo " 5
+} {- {foo } 1 simple foo 1 text foo 0 { }}
+test parse-3.5 {Tcl_ParseCommand procedure, quoted words} testparser {
+ testparser {foo "a b c" d "efg";} 0
+} {- {foo "a b c" d "efg";} 4 simple foo 1 text foo 0 simple {"a b c"} 1 text {a b c} 0 simple d 1 text d 0 simple {"efg"} 1 text efg 0 {}}
+test parse-3.6 {Tcl_ParseCommand procedure, words in braces} testparser {
+ testparser {foo {a $b [concat foo]} {c d}} 0
+} {- {foo {a $b [concat foo]} {c d}} 3 simple foo 1 text foo 0 simple {{a $b [concat foo]}} 1 text {a $b [concat foo]} 0 simple {{c d}} 1 text {c d} 0 {}}
+test parse-3.7 {Tcl_ParseCommand procedure, error in unquoted word} testparser {
+ list [catch {testparser "foo \$\{abc" 0} msg] $msg $::errorInfo
+} {1 {missing close-brace for variable name} missing\ close-brace\ for\ variable\ name\n\ \ \ \ (remainder\ of\ script:\ \"\{abc\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"foo\ \\\$\\\{abc\"\ 0\"}
+
+test parse-4.1 {Tcl_ParseCommand procedure, simple words} testparser {
+ testparser {foo} 0
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-4.2 {Tcl_ParseCommand procedure, simple words} testparser {
+ testparser {{abc}} 0
+} {- {{abc}} 1 simple {{abc}} 1 text abc 0 {}}
+test parse-4.3 {Tcl_ParseCommand procedure, simple words} testparser {
+ testparser {"c d"} 0
+} {- {"c d"} 1 simple {"c d"} 1 text {c d} 0 {}}
+test parse-4.4 {Tcl_ParseCommand procedure, simple words} testparser {
+ testparser {x$d} 0
+} {- {x$d} 1 word {x$d} 3 text x 0 variable {$d} 1 text d 0 {}}
+test parse-4.5 {Tcl_ParseCommand procedure, simple words} testparser {
+ testparser {"a [foo] b"} 0
+} {- {"a [foo] b"} 1 word {"a [foo] b"} 3 text {a } 0 command {[foo]} 0 text { b} 0 {}}
+test parse-4.6 {Tcl_ParseCommand procedure, simple words} testparser {
+ testparser {$x} 0
+} {- {$x} 1 word {$x} 2 variable {$x} 1 text x 0 {}}
+
+test parse-5.1 {Tcl_ParseCommand procedure, backslash-newline terminates word} testparser {
+ testparser "{abc}\\\n" 0
+} {- \{abc\}\\\n 1 simple {{abc}} 1 text abc 0 {}}
+test parse-5.2 {Tcl_ParseCommand procedure, backslash-newline terminates word} testparser {
+ testparser "foo\\\nbar" 0
+} {- foo\\\nbar 2 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
+test parse-5.3 {Tcl_ParseCommand procedure, word terminator is command terminator} testparser {
+ testparser "foo\n bar" 0
+} {- {foo
+} 1 simple foo 1 text foo 0 { bar}}
+test parse-5.4 {Tcl_ParseCommand procedure, word terminator is command terminator} testparser {
+ testparser "foo; bar" 0
+} {- {foo;} 1 simple foo 1 text foo 0 { bar}}
+test parse-5.5 {Tcl_ParseCommand procedure, word terminator is end of string} testparser {
+ testparser "\"foo\" bar" 5
+} {- {"foo"} 1 simple {"foo"} 1 text foo 0 { bar}}
+test parse-5.6 {Tcl_ParseCommand procedure, junk after close quote} testparser {
+ list [catch {testparser {foo "bar"x} 0} msg] $msg $::errorInfo
+} {1 {extra characters after close-quote} {extra characters after close-quote
+ (remainder of script: "x")
+ invoked from within
+"testparser {foo "bar"x} 0"}}
+test parse-5.7 {Tcl_ParseCommand procedure, backslash-newline after close quote} testparser {
+ testparser "foo \"bar\"\\\nx" 0
+} {- foo\ \"bar\"\\\nx 3 simple foo 1 text foo 0 simple {"bar"} 1 text bar 0 simple x 1 text x 0 {}}
+test parse-5.8 {Tcl_ParseCommand procedure, junk after close brace} testparser {
+ list [catch {testparser {foo {bar}x} 0} msg] $msg $::errorInfo
+} {1 {extra characters after close-brace} {extra characters after close-brace
+ (remainder of script: "x")
+ invoked from within
+"testparser {foo {bar}x} 0"}}
+test parse-5.9 {Tcl_ParseCommand procedure, backslash-newline after close brace} testparser {
+ testparser "foo {bar}\\\nx" 0
+} {- foo\ \{bar\}\\\nx 3 simple foo 1 text foo 0 simple {{bar}} 1 text bar 0 simple x 1 text x 0 {}}
+test parse-5.10 {Tcl_ParseCommand procedure, multiple deletion of non-static buffer} testparser {
+ # This test is designed to catch bug 1681.
+ list [catch {testparser "a \"\\1\\2\\3\\4\\5\\6\\7\\8\\9\\1\\2\\3\\4\\5\\6\\7\\8" 0} msg] $msg $::errorInfo
+} "1 {missing \"} {missing \"
+ (remainder of script: \"\"\\1\\2\\3\\4\\5\\6\\7\\8\\9\\1\\2\\3\\4\\5\\6\\7\\8\")
+ invoked from within
+\"testparser \"a \\\"\\\\1\\\\2\\\\3\\\\4\\\\5\\\\6\\\\7\\\\8\\\\9\\\\1\\\\2\\\\3\\\\4\\\\5\\\\6\\\\7\\\\8\" 0\"}"
+
+test parse-5.11 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{expan}} 0
+} {- {{expan}} 1 simple {{expan}} 1 text expan 0 {}}
+test parse-5.12 {Tcl_ParseCommand: {*} parsing} -constraints {
+ testparser
+} -body {
+ testparser {{expan}x} 0
+} -returnCodes error -result {extra characters after close-brace}
+test parse-5.13 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{**}} 0
+} {- {{**}} 1 simple {{**}} 1 text ** 0 {}}
+test parse-5.14 {Tcl_ParseCommand: {*} parsing} -constraints {
+ testparser
+} -body {
+ testparser {{**}x} 0
+} -returnCodes error -result {extra characters after close-brace}
+test parse-5.15 {Tcl_ParseCommand: {*} parsing} -constraints {
+ testparser
+} -body {
+ testparser {{*}{123456}x} 0
+} -returnCodes error -result {extra characters after close-brace}
+test parse-5.16 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{123456\
+ }} 0
+} {- {{123456 }} 1 simple {{123456 }} 1 text {123456 } 0 {}}
+test parse-5.17 {Tcl_ParseCommand: {*} parsing} -constraints {
+ testparser
+} -body {
+ testparser {{123456\
+ }x} 0
+} -returnCodes error -result {extra characters after close-brace}
+test parse-5.18 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{*\
+ }} 0
+} {- {{* }} 1 simple {{* }} 1 text {* } 0 {}}
+test parse-5.19 {Tcl_ParseCommand: {*} parsing} -constraints {
+ testparser
+} -body {
+ testparser {{*\
+ }x} 0
+} -returnCodes error -result {extra characters after close-brace}
+test parse-5.20 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{123456}} 0
+} {- {{123456}} 1 simple {{123456}} 1 text 123456 0 {}}
+test parse-5.21 {Tcl_ParseCommand: {*} parsing} -constraints {
+ testparser
+} -body {
+ testparser {{123456}x} 0
+} -returnCodes error -result {extra characters after close-brace}
+test parse-5.22 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{*}} 0
+} {- {{*}} 1 simple {{*}} 1 text * 0 {}}
+test parse-5.23 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{*} } 0
+} {- {{*} } 1 simple {{*}} 1 text * 0 {}}
+test parse-5.24 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{*}x} 0
+} {- {{*}x} 1 simple x 1 text x 0 {}}
+test parse-5.25 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{*}
+} 0
+} {- {{*}
+} 1 simple {{*}} 1 text * 0 {}}
+test parse-5.26 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser {{*};} 0
+} {- {{*};} 1 simple {{*}} 1 text * 0 {}}
+test parse-5.27 {Tcl_ParseCommand: {*} parsing} testparser {
+ testparser "{*}\\\n foo bar" 0
+} {- \{*\}\\\n\ foo\ bar 3 simple {{*}} 1 text * 0 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
+test parse-5.28 {Tcl_ParseCommand: {*} parsing, expanded literals} testparser {
+ testparser {{*}{a b}} 0
+} {- {{*}{a b}} 2 simple a 1 text a 0 simple b 1 text b 0 {}}
+test parse-5.29 {Tcl_ParseCommand: {*} parsing, expanded literals, naked backslashes} testparser {
+ testparser {{*}{a \n b}} 0
+} {- {{*}{a \n b}} 1 expand {{*}{a \n b}} 1 text {a \n b} 0 {}}
+test parse-5.30 {Tcl_ParseCommand: {*} parsing, expanded literals} testparser {
+ testparser {{*}"a b"} 0
+} {- {{*}"a b"} 2 simple a 1 text a 0 simple b 1 text b 0 {}}
+test parse-5.31 {Tcl_ParseCommand: {*} parsing, expanded literals, naked backslashes} testparser {
+ testparser {{*}"a \n b"} 0
+} {- {{*}"a \n b"} 1 expand {{*}"a \n b"} 3 text {a } 0 backslash {\n} 0 text { b} 0 {}}
+
+test parse-6.1 {ParseTokens procedure, empty word} testparser {
+ testparser {""} 0
+} {- {""} 1 simple {""} 1 text {} 0 {}}
+test parse-6.2 {ParseTokens procedure, simple range} testparser {
+ testparser {"abc$x.e"} 0
+} {- {"abc$x.e"} 1 word {"abc$x.e"} 4 text abc 0 variable {$x} 1 text x 0 text .e 0 {}}
+test parse-6.3 {ParseTokens procedure, variable reference} testparser {
+ testparser {abc$x.e $y(z)} 0
+} {- {abc$x.e $y(z)} 2 word {abc$x.e} 4 text abc 0 variable {$x} 1 text x 0 text .e 0 word {$y(z)} 3 variable {$y(z)} 2 text y 0 text z 0 {}}
+test parse-6.4 {ParseTokens procedure, variable reference} testparser {
+ list [catch {testparser {$x([a )} 0} msg] $msg
+} {1 {missing close-bracket}}
+test parse-6.5 {ParseTokens procedure, command substitution} testparser {
+ testparser {[foo $x bar]z} 0
+} {- {[foo $x bar]z} 1 word {[foo $x bar]z} 2 command {[foo $x bar]} 0 text z 0 {}}
+test parse-6.6 {ParseTokens procedure, command substitution} testparser {
+ testparser {[foo \] [a b]]} 0
+} {- {[foo \] [a b]]} 1 word {[foo \] [a b]]} 1 command {[foo \] [a b]]} 0 {}}
+test parse-6.7 {ParseTokens procedure, error in command substitution} testparser {
+ list [catch {testparser {a [b {}c d] e} 0} msg] $msg $::errorInfo
+} {1 {extra characters after close-brace} {extra characters after close-brace
+ (remainder of script: "c d] e")
+ invoked from within
+"testparser {a [b {}c d] e} 0"}}
+test parse-6.8 {ParseTokens procedure, error in command substitution} {
+ info complete {a [b {}c d]}
+} {1}
+test parse-6.9 {ParseTokens procedure, error in command substitution} {
+ info complete {a [b "c d}
+} {0}
+test parse-6.10 {ParseTokens procedure, incomplete sub-command} {
+ info complete {puts [
+ expr 1+1
+ #this is a comment ]}
+} {0}
+test parse-6.11 {ParseTokens procedure, memory allocation for big nested command} testparser {
+ testparser {[$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b)]} 0
+} {- {[$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b)]} 1 word {[$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b)]} 1 command {[$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b)]} 0 {}}
+test parse-6.12 {ParseTokens procedure, missing close bracket} testparser {
+ list [catch {testparser {[foo $x bar} 0} msg] $msg $::errorInfo
+} {1 {missing close-bracket} {missing close-bracket
+ (remainder of script: "[foo $x bar")
+ invoked from within
+"testparser {[foo $x bar} 0"}}
+test parse-6.13 {ParseTokens procedure, backslash-newline without continuation line} testparser {
+ list [catch {testparser "\"a b\\\n" 0} msg] $msg $::errorInfo
+} {1 {missing "} missing\ \"\n\ \ \ \ (remainder\ of\ script:\ \"\"a\ b\\\n\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"\\\"a\ b\\\\\\n\"\ 0\"}
+test parse-6.14 {ParseTokens procedure, backslash-newline} testparser {
+ testparser "b\\\nc" 0
+} {- b\\\nc 2 simple b 1 text b 0 simple c 1 text c 0 {}}
+test parse-6.15 {ParseTokens procedure, backslash-newline} testparser {
+ testparser "\"b\\\nc\"" 0
+} {- \"b\\\nc\" 1 word \"b\\\nc\" 3 text b 0 backslash \\\n 0 text c 0 {}}
+test parse-6.16 {ParseTokens procedure, backslash substitution} testparser {
+ testparser {\n\a\x7f} 0
+} {- {\n\a\x7f} 1 word {\n\a\x7f} 3 backslash {\n} 0 backslash {\a} 0 backslash {\x7f} 0 {}}
+test parse-6.17 {ParseTokens procedure, null characters} testparser {
+ testparser [bytestring "foo\0zz"] 0
+} "- [bytestring foo\0zz] 1 word [bytestring foo\0zz] 3 text foo 0 text [bytestring \0] 0 text zz 0 {}"
+test parse-6.18 {ParseTokens procedure, seek past numBytes for close-bracket} testparser {
+ # Test for Bug 681841
+ list [catch {testparser {[a]} 2} msg] $msg
+} {1 {missing close-bracket}}
+
+test parse-7.1 {Tcl_FreeParse and ExpandTokenArray procedures} testparser {
+ testparser {$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) } 0
+} {- {$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) } 16 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 {}}
+
+test parse-8.1 {Tcl_EvalObjv procedure} testevalobjv {
+ testevalobjv 0 concat this is a test
+} {this is a test}
+test parse-8.2 {Tcl_EvalObjv procedure, unknown commands} testevalobjv {
+ rename ::unknown unknown.old
+ set x [catch {testevalobjv 10 asdf poiu} msg]
+ rename unknown.old ::unknown
+ list $x $msg
+} {1 {invalid command name "asdf"}}
+test parse-8.3 {Tcl_EvalObjv procedure, unknown commands} testevalobjv {
+ rename ::unknown unknown.old
+ proc ::unknown args {
+ return "unknown $args"
+ }
+ set x [catch {testevalobjv 0 asdf poiu} msg]
+ rename ::unknown {}
+ rename unknown.old ::unknown
+ list $x $msg
+} {0 {unknown asdf poiu}}
+test parse-8.4 {Tcl_EvalObjv procedure, unknown commands} testevalobjv {
+ rename ::unknown unknown.old
+ proc ::unknown args {
+ error "I don't like that command"
+ }
+ set x [catch {testevalobjv 0 asdf poiu} msg]
+ rename ::unknown {}
+ rename unknown.old ::unknown
+ list $x $msg
+} {1 {I don't like that command}}
+test parse-8.5 {Tcl_EvalObjv procedure, command traces} {testevalobjv testcmdtrace} {
+ testevalobjv 0 set x 123
+ testcmdtrace tracetest {testevalobjv 0 set x $x}
+} {{testevalobjv 0 set x $x} {testevalobjv 0 set x 123} {set x 123} {set x 123}}
+test parse-8.7 {Tcl_EvalObjv procedure, TCL_EVAL_GLOBAL flag} -constraints {
+ testevalobjv
+} -setup {
+ proc x {} {
+ set y 23
+ set z [testevalobjv 1 set y]
+ return [list $z $y]
+ }
+ set ::y 16
+} -cleanup {
+ unset ::y
+} -body {
+ x
+} -result {16 23}
+test parse-8.8 {Tcl_EvalObjv procedure, async handlers} -constraints {
+ testevalobjv testasync
+} -setup {
+ variable ::aresult
+ variable ::acode
+ proc async1 {result code} {
+ variable ::aresult
+ variable ::acode
+ set aresult $result
+ set acode $code
+ return "new result"
+ }
+ set handler1 [testasync create async1]
+ set aresult xxx
+ set acode yyy
+} -cleanup {
+ testasync delete
+} -body {
+ list [testevalobjv 0 testasync mark $handler1 original 0] $acode $aresult
+} -result {{new result} 0 original}
+test parse-8.9 {Tcl_EvalObjv procedure, exceptional return} testevalobjv {
+ list [catch {testevalobjv 0 error message} msg] $msg
+} {1 message}
+test parse-8.10 {Tcl_EvalObjv procedure, TCL_EVAL_GLOBAL} testevalobjv {
+ rename ::unknown unknown.save
+ proc ::unknown args {lappend ::info [info level]}
+ catch {rename ::noSuchCommand {}}
+ set ::info {}
+ namespace eval test_ns_1 {
+ testevalobjv 1 noSuchCommand
+ uplevel #0 noSuchCommand
+ }
+ namespace delete test_ns_1
+ rename ::unknown {}
+ rename unknown.save ::unknown
+ set ::info
+} {1 1}
+test parse-8.11 {Tcl_EvalObjv procedure, TCL_EVAL_INVOKE} testevalobjv {
+ rename ::unknown unknown.save
+ proc ::unknown args {lappend ::info [info level]; uplevel 1 foo}
+ proc ::foo args {lappend ::info global}
+ catch {rename ::noSuchCommand {}}
+ set ::slave [interp create]
+ $::slave alias bar noSuchCommand
+ set ::info {}
+ namespace eval test_ns_1 {
+ proc foo args {lappend ::info namespace}
+ $::slave eval bar
+ testevalobjv 1 [list $::slave eval bar]
+ uplevel #0 [list $::slave eval bar]
+ }
+ namespace delete test_ns_1
+ rename ::foo {}
+ rename ::unknown {}
+ rename unknown.save ::unknown
+ set ::info
+} [subst {[set level 2; incr level [info level]] global 1 global 1 global}]
+test parse-8.12 {Tcl_EvalObjv procedure, TCL_EVAL_INVOKE} {
+ set ::auto_index(noSuchCommand) {
+ proc noSuchCommand {} {lappend ::info global}
+ }
+ set ::auto_index(::[string trimleft [namespace current]::test_ns_1::noSuchCommand :]) [list \
+ proc [namespace current]::test_ns_1::noSuchCommand {} {
+ lappend ::info ns
+ }]
+ catch {rename ::noSuchCommand {}}
+ set ::slave [interp create]
+ $::slave alias bar noSuchCommand
+ set ::info {}
+ namespace eval test_ns_1 {
+ $::slave eval bar
+ }
+ namespace delete test_ns_1
+ interp delete $::slave
+ catch {rename ::noSuchCommand {}}
+ set ::info
+} global
+
+
+test parse-9.1 {Tcl_LogCommandInfo, line numbers} testevalex {
+ catch {unset x}
+ list [catch {testevalex {for {} 1 {} {
+
+
+ # asdf
+ set x
+ }}}] $::errorInfo
+} {1 {can't read "x": no such variable
+ while executing
+"set x"
+ ("for" body line 5)
+ invoked from within
+"for {} 1 {} {
+
+
+ # asdf
+ set x
+ }"
+ invoked from within
+"testevalex {for {} 1 {} {
+
+
+ # asdf
+ set x
+ }}"}}
+test parse-9.2 {Tcl_LogCommandInfo, truncating long commands} {
+ list [catch {set a b 111111111 222222222 333333333 444444444 555555555 666666666 777777777 888888888 999999999 000000000 aaaaaaaaa bbbbbbbbb ccccccccc ddddddddd eeeeeeeee fffffffff ggggggggg}] $::errorInfo
+} {1 {wrong # args: should be "set varName ?newValue?"
+ while executing
+"set a b 111111111 222222222 333333333 444444444 555555555 666666666 777777777 888888888 999999999 000000000 aaaaaaaaa bbbbbbbbb ccccccccc ddddddddd ee..."}}
+
+test parse-10.1 {Tcl_EvalTokens, simple text} testevalex {
+ testevalex {concat test}
+} {test}
+test parse-10.2 {Tcl_EvalTokens, backslash sequences} testevalex {
+ testevalex {concat test\063\062test}
+} {test32test}
+test parse-10.3 {Tcl_EvalTokens, nested commands} testevalex {
+ testevalex {concat [expr 2 + 6]}
+} {8}
+test parse-10.4 {Tcl_EvalTokens, nested commands} testevalex {
+ catch {unset a}
+ list [catch {testevalex {concat xxx[expr $a]}} msg] $msg
+} {1 {can't read "a": no such variable}}
+test parse-10.5 {Tcl_EvalTokens, simple variables} testevalex {
+ set a hello
+ testevalex {concat $a}
+} {hello}
+test parse-10.6 {Tcl_EvalTokens, array variables} testevalex {
+ catch {unset a}
+ set a(12) 46
+ testevalex {concat $a(12)}
+} {46}
+test parse-10.7 {Tcl_EvalTokens, array variables} testevalex {
+ catch {unset a}
+ set a(12) 46
+ testevalex {concat $a(1[expr 3 - 1])}
+} {46}
+test parse-10.8 {Tcl_EvalTokens, array variables} testevalex {
+ catch {unset a}
+ list [catch {testevalex {concat $x($a)}} msg] $msg
+} {1 {can't read "a": no such variable}}
+test parse-10.9 {Tcl_EvalTokens, array variables} testevalex {
+ catch {unset a}
+ list [catch {testevalex {concat xyz$a(1)}} msg] $msg
+} {1 {can't read "a(1)": no such variable}}
+test parse-10.10 {Tcl_EvalTokens, object values} testevalex {
+ set a 123
+ testevalex {concat $a}
+} {123}
+test parse-10.11 {Tcl_EvalTokens, object values} testevalex {
+ set a 123
+ testevalex {concat $a$a$a}
+} {123123123}
+test parse-10.12 {Tcl_EvalTokens, object values} testevalex {
+ testevalex {concat [expr 2][expr 4][expr 6]}
+} {246}
+test parse-10.13 {Tcl_EvalTokens, string values} testevalex {
+ testevalex {concat {a" b"}}
+} {a" b"}
+test parse-10.14 {Tcl_EvalTokens, string values} testevalex {
+ set a 111
+ testevalex {concat x$a.$a.$a}
+} {x111.111.111}
+
+test parse-11.1 {Tcl_EvalEx, TCL_EVAL_GLOBAL flag} -constraints {
+ testevalex
+} -setup {
+ proc x {} {
+ set y 777
+ set z [testevalex "set y" global]
+ return [list $z $y]
+ }
+ set ::y 321
+} -cleanup {
+ unset ::y
+} -body {
+ x
+} -result {321 777}
+test parse-11.2 {Tcl_EvalEx, error while parsing} testevalex {
+ list [catch {testevalex {concat "abc}} msg] $msg
+} {1 {missing "}}
+test parse-11.3 {Tcl_EvalEx, error while collecting words} testevalex {
+ catch {unset a}
+ list [catch {testevalex {concat xyz $a}} msg] $msg
+} {1 {can't read "a": no such variable}}
+test parse-11.4 {Tcl_EvalEx, error in Tcl_EvalObjv call} testevalex {
+ catch {unset a}
+ list [catch {testevalex {_bogus_ a b c d}} msg] $msg
+} {1 {invalid command name "_bogus_"}}
+test parse-11.5 {Tcl_EvalEx, exceptional return} testevalex {
+ list [catch {testevalex {break}} msg] $msg
+} {3 {}}
+test parse-11.6 {Tcl_EvalEx, freeing memory} testevalex {
+ testevalex {concat a b c d e f g h i j k l m n o p q r s t u v w x y z}
+} {a b c d e f g h i j k l m n o p q r s t u v w x y z}
+test parse-11.7 {Tcl_EvalEx, multiple commands in script} testevalex {
+ list [testevalex {set a b; set c d}] $a $c
+} {d b d}
+test parse-11.8 {Tcl_EvalEx, multiple commands in script} testevalex {
+ list [testevalex {
+ set a b
+ set c d
+ }] $a $c
+} {d b d}
+test parse-11.9 {Tcl_EvalEx, freeing memory after error} testevalex {
+ catch {unset a}
+ list [catch {testevalex {concat a b c d e f g h i j k l m n o p q r s t u v w x y z $a}} msg] $msg
+} {1 {can't read "a": no such variable}}
+test parse-11.10 {Tcl_EvalTokens, empty commands} testevalex {
+ testevalex {concat xyz; }
+} {xyz}
+test parse-11.11 {Tcl_EvalTokens, empty commands} testevalex {
+ testevalex "concat abc; ; # this is a comment\n"
+} {abc}
+test parse-11.12 {Tcl_EvalTokens, empty commands} testevalex {
+ testevalex {}
+} {}
+
+test parse-12.1 {Tcl_ParseVarName procedure, initialization} testparsevarname {
+ list [catch {testparsevarname {$a([first second])} 8 0} msg] $msg
+} {1 {missing close-bracket}}
+test parse-12.2 {Tcl_ParseVarName procedure, initialization} testparsevarname {
+ testparsevarname {$a([first second])} 0 0
+} {- {} 0 variable {$a([first second])} 2 text a 0 command {[first second]} 0 {}}
+test parse-12.3 {Tcl_ParseVarName procedure, initialization} testparsevarname {
+ list [catch {testparsevarname {$abcd} 3 0} msg] $msg
+} {0 {- {} 0 variable {$ab} 1 text ab 0 cd}}
+test parse-12.4 {Tcl_ParseVarName procedure, initialization} testparsevarname {
+ testparsevarname {$abcd} 0 0
+} {- {} 0 variable {$abcd} 1 text abcd 0 {}}
+test parse-12.5 {Tcl_ParseVarName procedure, just a dollar sign} testparsevarname {
+ testparsevarname {$abcd} 1 0
+} {- {} 0 text {$} 0 abcd}
+test parse-12.6 {Tcl_ParseVarName procedure, braced variable name} testparser {
+ testparser {${..[]b}cd} 0
+} {- {${..[]b}cd} 1 word {${..[]b}cd} 3 variable {${..[]b}} 1 text {..[]b} 0 text cd 0 {}}
+test parse-12.7 {Tcl_ParseVarName procedure, braced variable name} testparser {
+ testparser "\$\{\{\} " 0
+} {- \$\{\{\}\ 1 word \$\{\{\} 2 variable \$\{\{\} 1 text \{ 0 {}}
+test parse-12.8 {Tcl_ParseVarName procedure, missing close brace} testparser {
+ list [catch {testparser "$\{abc" 0} msg] $msg $::errorInfo
+} {1 {missing close-brace for variable name} missing\ close-brace\ for\ variable\ name\n\ \ \ \ (remainder\ of\ script:\ \"\{abc\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"\$\\\{abc\"\ 0\"}
+test parse-12.9 {Tcl_ParseVarName procedure, missing close brace} testparsevarname {
+ list [catch {testparsevarname {${bcd}} 4 0} msg] $msg
+} {1 {missing close-brace for variable name}}
+test parse-12.10 {Tcl_ParseVarName procedure, missing close brace} testparsevarname {
+ list [catch {testparsevarname {${bc}} 4 0} msg] $msg
+} {1 {missing close-brace for variable name}}
+test parse-12.11 {Tcl_ParseVarName procedure, simple variable name} testparser {
+ testparser {$az_AZ.} 0
+} {- {$az_AZ.} 1 word {$az_AZ.} 3 variable {$az_AZ} 1 text az_AZ 0 text . 0 {}}
+test parse-12.12 {Tcl_ParseVarName procedure, simple variable name} testparser {
+ testparser {$abcdefg} 4
+} {- {$abc} 1 word {$abc} 2 variable {$abc} 1 text abc 0 defg}
+test parse-12.13 {Tcl_ParseVarName procedure, simple variable name with ::} testparser {
+ testparser {$xyz::ab:c} 0
+} {- {$xyz::ab:c} 1 word {$xyz::ab:c} 3 variable {$xyz::ab} 1 text xyz::ab 0 text :c 0 {}}
+test parse-12.14 {Tcl_ParseVarName procedure, variable names with many colons} testparser {
+ testparser {$xyz:::::c} 0
+} {- {$xyz:::::c} 1 word {$xyz:::::c} 2 variable {$xyz:::::c} 1 text xyz:::::c 0 {}}
+test parse-12.15 {Tcl_ParseVarName procedure, : vs. ::} testparsevarname {
+ testparsevarname {$ab:cd} 0 0
+} {- {} 0 variable {$ab} 1 text ab 0 :cd}
+test parse-12.16 {Tcl_ParseVarName procedure, eof in ::} testparsevarname {
+ testparsevarname {$ab::cd} 4 0
+} {- {} 0 variable {$ab} 1 text ab 0 ::cd}
+test parse-12.17 {Tcl_ParseVarName procedure, eof in ::} testparsevarname {
+ testparsevarname {$ab:::cd} 5 0
+} {- {} 0 variable {$ab::} 1 text ab:: 0 :cd}
+test parse-12.18 {Tcl_ParseVarName procedure, no variable name} testparser {
+ testparser {$$ $.} 0
+} {- {$$ $.} 2 word {$$} 2 text {$} 0 text {$} 0 word {$.} 2 text {$} 0 text . 0 {}}
+test parse-12.19 {Tcl_ParseVarName procedure, EOF before (} testparsevarname {
+ testparsevarname {$ab(cd)} 3 0
+} {- {} 0 variable {$ab} 1 text ab 0 (cd)}
+test parse-12.20 {Tcl_ParseVarName procedure, array reference} testparser {
+ testparser {$x(abc)} 0
+} {- {$x(abc)} 1 word {$x(abc)} 3 variable {$x(abc)} 2 text x 0 text abc 0 {}}
+test parse-12.21 {Tcl_ParseVarName procedure, array reference} testparser {
+ testparser {$x(ab$cde[foo bar])} 0
+} {- {$x(ab$cde[foo bar])} 1 word {$x(ab$cde[foo bar])} 6 variable {$x(ab$cde[foo bar])} 5 text x 0 text ab 0 variable {$cde} 1 text cde 0 command {[foo bar]} 0 {}}
+test parse-12.22 {Tcl_ParseVarName procedure, array reference} testparser {
+ testparser {$x([cmd arg]zz)} 0
+} {- {$x([cmd arg]zz)} 1 word {$x([cmd arg]zz)} 4 variable {$x([cmd arg]zz)} 3 text x 0 command {[cmd arg]} 0 text zz 0 {}}
+test parse-12.23 {Tcl_ParseVarName procedure, missing close paren in array reference} testparser {
+ list [catch {testparser {$x(poiu} 0} msg] $msg $::errorInfo
+} {1 {missing )} {missing )
+ (remainder of script: "(poiu")
+ invoked from within
+"testparser {$x(poiu} 0"}}
+test parse-12.24 {Tcl_ParseVarName procedure, missing close paren in array reference} testparsevarname {
+ list [catch {testparsevarname {$ab(cd)} 6 0} msg] $msg $::errorInfo
+} {1 {missing )} {missing )
+ (remainder of script: "(cd)")
+ invoked from within
+"testparsevarname {$ab(cd)} 6 0"}}
+test parse-12.25 {Tcl_ParseVarName procedure, nested array reference} testparser {
+ testparser {$x(a$y(b$z))} 0
+} {- {$x(a$y(b$z))} 1 word {$x(a$y(b$z))} 8 variable {$x(a$y(b$z))} 7 text x 0 text a 0 variable {$y(b$z)} 4 text y 0 text b 0 variable {$z} 1 text z 0 {}}
+
+test parse-13.1 {Tcl_ParseVar procedure} testparsevar {
+ set abc 24
+ testparsevar {$abc.fg}
+} {24 .fg}
+test parse-13.2 {Tcl_ParseVar procedure, no variable name} testparsevar {
+ testparsevar {$}
+} {{$} {}}
+test parse-13.3 {Tcl_ParseVar procedure, no variable name} testparsevar {
+ testparsevar {$.123}
+} {{$} .123}
+test parse-13.4 {Tcl_ParseVar procedure, error looking up variable} testparsevar {
+ catch {unset abc}
+ list [catch {testparsevar {$abc}} msg] $msg
+} {1 {can't read "abc": no such variable}}
+test parse-13.5 {Tcl_ParseVar procedure, error looking up variable} testparsevar {
+ catch {unset abc}
+ list [catch {testparsevar {$abc([bogus x y z])}} msg] $msg
+} {1 {invalid command name "bogus"}}
+
+test parse-14.1 {Tcl_ParseBraces procedure, computing string length} testparser {
+ testparser [bytestring "foo\0 bar"] -1
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-14.2 {Tcl_ParseBraces procedure, computing string length} testparser {
+ testparser "foo bar" -1
+} {- {foo bar} 2 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
+test parse-14.3 {Tcl_ParseBraces procedure, words in braces} testparser {
+ testparser {foo {a $b [concat foo]} {c d}} 0
+} {- {foo {a $b [concat foo]} {c d}} 3 simple foo 1 text foo 0 simple {{a $b [concat foo]}} 1 text {a $b [concat foo]} 0 simple {{c d}} 1 text {c d} 0 {}}
+test parse-14.4 {Tcl_ParseBraces procedure, empty nested braces} testparser {
+ testparser {foo {{}}} 0
+} {- {foo {{}}} 2 simple foo 1 text foo 0 simple {{{}}} 1 text {{}} 0 {}}
+test parse-14.5 {Tcl_ParseBraces procedure, nested braces} testparser {
+ testparser {foo {{a {b} c} {} {d e}}} 0
+} {- {foo {{a {b} c} {} {d e}}} 2 simple foo 1 text foo 0 simple {{{a {b} c} {} {d e}}} 1 text {{a {b} c} {} {d e}} 0 {}}
+test parse-14.6 {Tcl_ParseBraces procedure, backslashes in words in braces} testparser {
+ testparser "foo {a \\n\\\{}" 0
+} {- {foo {a \n\{}} 2 simple foo 1 text foo 0 simple {{a \n\{}} 1 text {a \n\{} 0 {}}
+test parse-14.7 {Tcl_ParseBraces procedure, missing continuation line in braces} testparser {
+ list [catch {testparser "\{abc\\\n" 0} msg] $msg $::errorInfo
+} {1 {missing close-brace} missing\ close-brace\n\ \ \ \ (remainder\ of\ script:\ \"\{abc\\\n\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"\\\{abc\\\\\\n\"\ 0\"}
+test parse-14.8 {Tcl_ParseBraces procedure, backslash-newline in braces} testparser {
+ testparser "foo {\\\nx}" 0
+} {- foo\ \{\\\nx\} 2 simple foo 1 text foo 0 word \{\\\nx\} 2 backslash \\\n 0 text x 0 {}}
+test parse-14.9 {Tcl_ParseBraces procedure, backslash-newline in braces} testparser {
+ testparser "foo {a \\\n b}" 0
+} {- foo\ \{a\ \\\n\ \ \ b\} 2 simple foo 1 text foo 0 word \{a\ \\\n\ \ \ b\} 3 text {a } 0 backslash \\\n\ \ \ 0 text b 0 {}}
+test parse-14.10 {Tcl_ParseBraces procedure, backslash-newline in braces} testparser {
+ testparser "foo {xyz\\\n }" 0
+} {- foo\ \{xyz\\\n\ \} 2 simple foo 1 text foo 0 word \{xyz\\\n\ \} 2 text xyz 0 backslash \\\n\ 0 {}}
+test parse-14.11 {Tcl_ParseBraces procedure, empty braced string} testparser {
+ testparser {foo {}} 0
+} {- {foo {}} 2 simple foo 1 text foo 0 simple {{}} 1 text {} 0 {}}
+test parse-14.12 {Tcl_ParseBraces procedure, missing close brace} testparser {
+ list [catch {testparser "foo \{xy\\\nz" 0} msg] $msg $::errorInfo
+} {1 {missing close-brace} missing\ close-brace\n\ \ \ \ (remainder\ of\ script:\ \"\{xy\\\nz\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"foo\ \\\{xy\\\\\\nz\"\ 0\"}
+
+test parse-15.1 {Tcl_ParseQuotedString procedure, computing string length} testparser {
+ testparser [bytestring "foo\0 bar"] -1
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-15.2 {Tcl_ParseQuotedString procedure, computing string length} testparser {
+ testparser "foo bar" -1
+} {- {foo bar} 2 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
+test parse-15.3 {Tcl_ParseQuotedString procedure, word is quoted string} testparser {
+ testparser {foo "a b c" d "efg";} 0
+} {- {foo "a b c" d "efg";} 4 simple foo 1 text foo 0 simple {"a b c"} 1 text {a b c} 0 simple d 1 text d 0 simple {"efg"} 1 text efg 0 {}}
+test parse-15.4 {Tcl_ParseQuotedString procedure, garbage after quoted string} testparser {
+ list [catch {testparser {foo "a b c"d} 0} msg] $msg $::errorInfo
+} {1 {extra characters after close-quote} {extra characters after close-quote
+ (remainder of script: "d")
+ invoked from within
+"testparser {foo "a b c"d} 0"}}
+
+test parse-15.5 {CommandComplete procedure} {
+ info complete ""
+} 1
+test parse-15.6 {CommandComplete procedure} {
+ info complete " \n"
+} 1
+test parse-15.7 {CommandComplete procedure} {
+ info complete "abc def"
+} 1
+test parse-15.8 {CommandComplete procedure} {
+ info complete "a b c d e f \t\n"
+} 1
+test parse-15.9 {CommandComplete procedure} {
+ info complete {a b c"d}
+} 1
+test parse-15.10 {CommandComplete procedure} {
+ info complete {a b "c d" e}
+} 1
+test parse-15.11 {CommandComplete procedure} {
+ info complete {a b "c d"}
+} 1
+test parse-15.12 {CommandComplete procedure} {
+ info complete {a b "c d"}
+} 1
+test parse-15.13 {CommandComplete procedure} {
+ info complete {a b "c d}
+} 0
+test parse-15.14 {CommandComplete procedure} {
+ info complete {a b "}
+} 0
+test parse-15.15 {CommandComplete procedure} {
+ info complete {a b "cd"xyz}
+} 1
+test parse-15.16 {CommandComplete procedure} {
+ info complete {a b "c $d() d"}
+} 1
+test parse-15.17 {CommandComplete procedure} {
+ info complete {a b "c $dd("}
+} 0
+test parse-15.18 {CommandComplete procedure} {
+ info complete {a b "c \"}
+} 0
+test parse-15.19 {CommandComplete procedure} {
+ info complete {a b "c [d e f]"}
+} 1
+test parse-15.20 {CommandComplete procedure} {
+ info complete {a b "c [d e f] g"}
+} 1
+test parse-15.21 {CommandComplete procedure} {
+ info complete {a b "c [d e f"}
+} 0
+test parse-15.22 {CommandComplete procedure} {
+ info complete {a {b c d} e}
+} 1
+test parse-15.23 {CommandComplete procedure} {
+ info complete {a {b c d}}
+} 1
+test parse-15.24 {CommandComplete procedure} {
+ info complete "a b\{c d"
+} 1
+test parse-15.25 {CommandComplete procedure} {
+ info complete "a b \{c"
+} 0
+test parse-15.26 {CommandComplete procedure} {
+ info complete "a b \{c{ }"
+} 0
+test parse-15.27 {CommandComplete procedure} {
+ info complete "a b {c d e}xxx"
+} 1
+test parse-15.28 {CommandComplete procedure} {
+ info complete "a b {c \\\{d e}xxx"
+} 1
+test parse-15.29 {CommandComplete procedure} {
+ info complete {a b [ab cd ef]}
+} 1
+test parse-15.30 {CommandComplete procedure} {
+ info complete {a b x[ab][cd][ef] gh}
+} 1
+test parse-15.31 {CommandComplete procedure} {
+ info complete {a b x[ab][cd[ef] gh}
+} 0
+test parse-15.32 {CommandComplete procedure} {
+ info complete {a b x[ gh}
+} 0
+test parse-15.33 {CommandComplete procedure} {
+ info complete {[]]]}
+} 1
+test parse-15.34 {CommandComplete procedure} {
+ info complete {abc x$yyy}
+} 1
+test parse-15.35 {CommandComplete procedure} {
+ info complete "abc x\${abc\[\\d} xyz"
+} 1
+test parse-15.36 {CommandComplete procedure} {
+ info complete "abc x\$\{ xyz"
+} 0
+test parse-15.37 {CommandComplete procedure} {
+ info complete {word $a(xyz)}
+} 1
+test parse-15.38 {CommandComplete procedure} {
+ info complete {word $a(}
+} 0
+test parse-15.39 {CommandComplete procedure} {
+ info complete "set a \\\n"
+} 0
+test parse-15.40 {CommandComplete procedure} {
+ info complete "set a \\\\\n"
+} 1
+test parse-15.41 {CommandComplete procedure} {
+ info complete "set a \\n "
+} 1
+test parse-15.42 {CommandComplete procedure} {
+ info complete "set a \\"
+} 1
+test parse-15.43 {CommandComplete procedure} {
+ info complete "foo \\\n\{"
+} 0
+test parse-15.44 {CommandComplete procedure} {
+ info complete "a\nb\n# \{\n# \{\nc\n"
+} 1
+test parse-15.45 {CommandComplete procedure} {
+ info complete "#Incomplete comment\\\n"
+} 0
+test parse-15.46 {CommandComplete procedure} {
+ info complete "#Incomplete comment\\\nBut now it's complete.\n"
+} 1
+test parse-15.47 {CommandComplete procedure} {
+ info complete "# Complete comment\\\\\n"
+} 1
+test parse-15.48 {CommandComplete procedure} {
+ info complete "abc\\\n def"
+} 1
+test parse-15.49 {CommandComplete procedure} {
+ info complete "abc\\\n "
+} 1
+test parse-15.50 {CommandComplete procedure} {
+ info complete "abc\\\n"
+} 0
+test parse-15.51 {CommandComplete procedure} "
+ info complete \"\\\{abc\\\}\\\{\"
+" 1
+test parse-15.52 {CommandComplete procedure} {
+ info complete "\"abc\"("
+} 1
+test parse-15.53 {CommandComplete procedure} "
+ info complete \" # \{\"
+" 1
+test parse-15.54 {CommandComplete procedure} "
+ info complete \"foo bar;# \{\"
+" 1
+test parse-15.55 {CommandComplete procedure} {
+ info complete "set x [bytestring \0]; puts hi"
+} 1
+test parse-15.56 {CommandComplete procedure} {
+ info complete "set x [bytestring \0]; \{"
+} 0
+test parse-15.57 {CommandComplete procedure} {
+ info complete "# Comment should be complete command"
+} 1
+test parse-15.58 {CommandComplete procedure, memory leaks} {
+ info complete "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22"
+} 1
+test parse-15.59 {CommandComplete procedure} {
+ # Test for Tcl Bug 684744
+ info complete [encoding convertfrom identity "\x00;if 1 \{"]
+} 0
+test parse-15.60 {CommandComplete procedure} {
+ # Test for Tcl Bug 1968882
+ info complete \\\n
+} 0
+
+test parse-16.1 {Bug 218885 (Scriptics bug 2535)} {
+ subst {[eval {return foo}]bar}
+} foobar
+
+test parse-17.1 {Correct return codes from errors during substitution} {
+ catch {eval {w[continue]}}
+} 4
+
+test parse-18.1 {Tcl_SubstObj, ParseTokens flags} {
+ subst {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo $::tcl_library $::tcl_library"
+test parse-18.2 {Tcl_SubstObj, ParseTokens flags} {
+ subst -nocommands {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo $::tcl_library \[set ::tcl_library]"
+test parse-18.3 {Tcl_SubstObj, ParseTokens flags} {
+ subst -novariables {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo \$::tcl_library $::tcl_library"
+test parse-18.4 {Tcl_SubstObj, ParseTokens flags} {
+ subst -nobackslashes {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo\\t$::tcl_library\\t$::tcl_library"
+test parse-18.5 {Tcl_SubstObj, ParseTokens flags} {
+ subst -novariables -nobackslashes {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo\\t\$::tcl_library\\t$::tcl_library"
+test parse-18.6 {Tcl_SubstObj, ParseTokens flags} {
+ subst -nocommands -nobackslashes {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo\\t$::tcl_library\\t\[set ::tcl_library]"
+test parse-18.7 {Tcl_SubstObj, ParseTokens flags} {
+ subst -nocommands -novariables {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo \$::tcl_library \[set ::tcl_library]"
+test parse-18.8 {Tcl_SubstObj, ParseTokens flags} {
+ subst -nocommands -novariables -nobackslashes \
+ {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo\\t\$::tcl_library\\t\[set ::tcl_library]"
+
+test parse-18.9 {Tcl_SubstObj, parse errors} {
+ list [catch "subst foo\$\{foo" msg] $msg
+} [list 1 "missing close-brace for variable name"]
+test parse-18.10 {Tcl_SubstObj, parse errors} {
+ list [catch "subst foo\[set \$\{foo]" msg] $msg
+} [list 1 "missing close-brace for variable name"]
+test parse-18.11 {Tcl_SubstObj, parse errors} {
+ list [catch "subst foo\$array(\$\{foo)" msg] $msg
+} [list 1 "missing close-brace for variable name"]
+test parse-18.12 {Tcl_SubstObj, parse errors} {
+ list [catch "subst foo\$(\$\{foo)" msg] $msg
+} [list 1 "missing close-brace for variable name"]
+test parse-18.13 {Tcl_SubstObj, parse errors} {
+ list [catch "subst \[" msg] $msg
+} [list 1 "missing close-bracket"]
+
+test parse-18.14 {Tcl_SubstObj, exception handling} {
+ subst {abc,[break],def}
+} {abc,}
+test parse-18.15 {Tcl_SubstObj, exception handling} {
+ subst {abc,[continue; expr 1+2],def}
+} {abc,,def}
+test parse-18.16 {Tcl_SubstObj, exception handling} {
+ subst {abc,[return foo; expr 1+2],def}
+} {abc,foo,def}
+test parse-18.17 {Tcl_SubstObj, exception handling} {
+ subst {abc,[return -code 10 foo; expr 1+2],def}
+} {abc,foo,def}
+test parse-18.18 {Tcl_SubstObj, exception handling} {
+ subst {abc,[break; set {} {}{}],def}
+} {abc,}
+test parse-18.19 {Tcl_SubstObj, exception handling} {
+ list [catch {subst {abc,[continue; expr 1+2; set {} {}{}],def}} msg] $msg
+} [list 1 "extra characters after close-brace"]
+test parse-18.20 {Tcl_SubstObj, exception handling} {
+ list [catch {subst {abc,[return foo; expr 1+2; set {} {}{}],def}} msg] $msg
+} [list 1 "extra characters after close-brace"]
+test parse-18.21 {Tcl_SubstObj, exception handling} {
+ list [catch {
+ subst {abc,[return -code 10 foo; expr 1+2; set {} {}{}],def}
+ } msg] $msg
+} [list 1 "extra characters after close-brace"]
+
+test parse-18.22 {Tcl_SubstObj, side effects} {
+ set a 0
+ list [subst {foo[incr a]bar}] $a
+} [list foo1bar 1]
+test parse-18.23 {Tcl_SubstObj, side effects} {
+ set a 0
+ list [subst {foo[incr a; incr a]bar}] $a
+} [list foo2bar 2]
+test parse-18.24 {Tcl_SubstObj, side effects} {
+ set a 0
+ list [subst {foo[incr a; break; incr a]bar}] $a
+} [list foo 1]
+test parse-18.25 {Tcl_SubstObj, side effects} {
+ set a 0
+ list [subst {foo[incr a; continue; incr a]bar}] $a
+} [list foobar 1]
+test parse-18.26 {Tcl_SubstObj, side effects} {
+ set a 0
+ list [subst {foo[incr a; return; incr a]bar}] $a
+} [list foobar 1]
+test parse-18.27 {Tcl_SubstObj, side effects} {
+ set a 0
+ list [subst {foo[incr a; return -code 10; incr a]bar}] $a
+} [list foobar 1]
+test parse-18.28 {Tcl_SubstObj, side effects} {
+ set a 0
+ catch {subst {foo[incr a; parse error {}{}; incr a]bar}}
+ set a
+} 1
+test parse-18.29 {Tcl_SubstObj, side effects} {
+ set a 0
+ catch {subst {foo[incr a; incr a; parse error {}{}]bar}}
+ set a
+} 2
+test parse-18.30 {Tcl_SubstObj, side effects} {
+ set a 0
+ catch {subst {foo[incr a; incr a parse error {}{}]bar}}
+ set a
+} 1
+
+test parse-19.1 {Bug 1115904: recursion limit in Tcl_EvalEx} -constraints {
+ testevalex
+} -setup {
+ interp create i
+ load {} Tcltest i
+ i eval {proc {} args {}}
+ interp recursionlimit i 3
+} -body {
+ i eval {testevalex {[]}}
+} -cleanup {
+ interp delete i
+}
+
+test parse-19.2 {Bug 1115904: recursion limit in Tcl_EvalEx} -constraints {
+ testevalex
+} -setup {
+ interp create i
+ load {} Tcltest i
+ i eval {proc {} args {}}
+ interp recursionlimit i 2
+} -body {
+ i eval {testevalex {[[]]}}
+} -cleanup {
+ interp delete i
+} -returnCodes error -match glob -result {too many nested*}
+
+test parse-19.3 {Bug 1115904: recursion limit in Tcl_EvalEx} emptyTest {
+ # Test no longer valid in Tcl 8.6
+} {}
+test parse-19.4 {Bug 1115904: recursion limit in Tcl_EvalEx} emptyTest {
+ # Test no longer valid in Tcl 8.6
+} {}
+
+test parse-20.1 {TclParseBackslash: truncated escape} testparser {
+ testparser {\u12345} 1
+} {- \\ 1 simple \\ 1 text \\ 0 u12345}
+test parse-20.2 {TclParseBackslash: truncated escape} testparser {
+ testparser {\u12345} 2
+} {- {\u} 1 word {\u} 1 backslash {\u} 0 12345}
+test parse-20.3 {TclParseBackslash: truncated escape} testparser {
+ testparser {\u12345} 3
+} {- {\u1} 1 word {\u1} 1 backslash {\u1} 0 2345}
+test parse-20.4 {TclParseBackslash: truncated escape} testparser {
+ testparser {\u12345} 4
+} {- {\u12} 1 word {\u12} 1 backslash {\u12} 0 345}
+test parse-20.5 {TclParseBackslash: truncated escape} testparser {
+ testparser {\u12345} 5
+} {- {\u123} 1 word {\u123} 1 backslash {\u123} 0 45}
+test parse-20.6 {TclParseBackslash: truncated escape} testparser {
+ testparser {\u12345} 6
+} {- {\u1234} 1 word {\u1234} 1 backslash {\u1234} 0 5}
+test parse-20.7 {TclParseBackslash: truncated escape} testparser {
+ testparser {\u12345} 7
+} {- {\u12345} 1 word {\u12345} 2 backslash {\u1234} 0 text 5 0 {}}
+
+test parse-20.8 {TclParseBackslash: truncated escape} testparser {
+ testparser {\x12X} 1
+} {- \\ 1 simple \\ 1 text \\ 0 x12X}
+test parse-20.9 {TclParseBackslash: truncated escape} testparser {
+ testparser {\x12X} 2
+} {- {\x} 1 word {\x} 1 backslash {\x} 0 12X}
+test parse-20.10 {TclParseBackslash: truncated escape} testparser {
+ testparser {\x12X} 3
+} {- {\x1} 1 word {\x1} 1 backslash {\x1} 0 2X}
+test parse-20.11 {TclParseBackslash: truncated escape} testparser {
+ testparser {\x12X} 4
+} {- {\x12} 1 word {\x12} 1 backslash {\x12} 0 X}
+test parse-20.12 {TclParseBackslash: truncated escape} testparser {
+ testparser {\x12X} 5
+} {- {\x12X} 1 word {\x12X} 2 backslash {\x12} 0 text X 0 {}}
+
+cleanupTests
+}
+
+namespace delete ::tcl::test::parse
+return
diff --git a/pkgs/msgcat/tests/parseExpr.test b/pkgs/msgcat/tests/parseExpr.test
new file mode 100644
index 0000000..cd0342a
--- /dev/null
+++ b/pkgs/msgcat/tests/parseExpr.test
@@ -0,0 +1,1068 @@
+# This file contains a collection of tests for the procedures in the
+# file tclCompExpr.c. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Note that the Tcl expression parser (tclCompExpr.c) does not check
+# the semantic validity of the expressions it parses. It does not check,
+# for example, that a math function actually exists, or that the operands
+# of "<<" are integers.
+
+testConstraint testexprparser [llength [info commands testexprparser]]
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+ variable ieeeValues
+ binary scan [binary format dd -1.0 1.0] c* c
+ switch -exact -- $c {
+ {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+ # little endian
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+ ieeeValues(-Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+ ieeeValues(-Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+ ieeeValues(-Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+ ieeeValues(+Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+ ieeeValues(+Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 1
+ return 1
+ }
+ {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+ binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Infinity)
+ binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Normal)
+ binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Subnormal)
+ binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Normal)
+ binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Infinity)
+ binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 0
+ return 1
+ }
+ default {
+ return 0
+ }
+ }
+}
+testConstraint ieeeFloatingPoint [testIEEE]
+
+######################################################################
+
+test parseExpr-1.1 {Tcl_ParseExpr procedure, computing string length} testexprparser {
+ testexprparser [bytestring "1+2\0 +3"] -1
+} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-1.2 {Tcl_ParseExpr procedure, computing string length} testexprparser {
+ testexprparser "1 + 2" -1
+} {- {} 0 subexpr {1 + 2} 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-1.3 {Tcl_ParseExpr procedure, error getting initial lexeme} testexprparser {
+ testexprparser 12345678901234567890 -1
+} {- {} 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-1.4 {Tcl_ParseExpr procedure, error in conditional expression} \
+ -constraints testexprparser -body {
+ testexprparser {foo+} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-1.5 {Tcl_ParseExpr procedure, lexemes after the expression} -constraints testexprparser -body {
+ testexprparser {1+2 345} -1
+} -returnCodes error -match glob -result *
+
+test parseExpr-2.1 {ParseCondExpr procedure, valid test subexpr} testexprparser {
+ testexprparser {2>3? 1 : 0} -1
+} {- {} 0 subexpr {2>3? 1 : 0} 11 operator ? 0 subexpr 2>3 5 operator > 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-2.2 {ParseCondExpr procedure, error in test subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {0 || foo} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-2.3 {ParseCondExpr procedure, next lexeme isn't "?"} testexprparser {
+ testexprparser {1+2} -1
+} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-2.4 {ParseCondExpr procedure, next lexeme is "?"} testexprparser {
+ testexprparser {1+2 ? 3 : 4} -1
+} {- {} 0 subexpr {1+2 ? 3 : 4} 11 operator ? 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-2.5 {ParseCondExpr procedure, bad lexeme after "?"} testexprparser {
+ testexprparser {1+2 ? 12345678901234567890 : 0} -1
+} {- {} 0 subexpr {1+2 ? 12345678901234567890 : 0} 11 operator ? 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-2.6 {ParseCondExpr procedure, valid "then" subexpression} testexprparser {
+ testexprparser {1? 3 : 4} -1
+} {- {} 0 subexpr {1? 3 : 4} 7 operator ? 0 subexpr 1 1 text 1 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-2.7 {ParseCondExpr procedure, error in "then" subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1? fred : martha} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-2.8 {ParseCondExpr procedure, lexeme after "then" subexpr isn't ":"} -constraints testexprparser -body {
+ testexprparser {1? 2 martha 3} -1
+} -returnCodes error -match glob -result *
+test parseExpr-2.9 {ParseCondExpr procedure, valid "else" subexpression} testexprparser {
+ testexprparser {27||3? 3 : 4&&9} -1
+} {- {} 0 subexpr {27||3? 3 : 4&&9} 15 operator ? 0 subexpr 27||3 5 operator || 0 subexpr 27 1 text 27 0 subexpr 3 1 text 3 0 subexpr 3 1 text 3 0 subexpr 4&&9 5 operator && 0 subexpr 4 1 text 4 0 subexpr 9 1 text 9 0 {}}
+test parseExpr-2.10 {ParseCondExpr procedure, error in "else" subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1? 2 : martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-3.1 {ParseLorExpr procedure, valid logical and subexpr} testexprparser {
+ testexprparser {1&&2 || 3} -1
+} {- {} 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-3.2 {ParseLorExpr procedure, error in logical and subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1&&foo || 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-3.3 {ParseLorExpr procedure, next lexeme isn't "||"} testexprparser {
+ testexprparser {1&&2? 1 : 0} -1
+} {- {} 0 subexpr {1&&2? 1 : 0} 11 operator ? 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-3.4 {ParseLorExpr procedure, next lexeme is "||"} testexprparser {
+ testexprparser {1&&2 || 3} -1
+} {- {} 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-3.5 {ParseLorExpr procedure, bad lexeme after "||"} testexprparser {
+ testexprparser {1&&2 || 12345678901234567890} -1
+} {- {} 0 subexpr {1&&2 || 12345678901234567890} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-3.6 {ParseLorExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1&&2 || 3 || 4} -1
+} {- {} 0 subexpr {1&&2 || 3 || 4} 13 operator || 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-3.7 {ParseLorExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1&&2 || 3 || martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-4.1 {ParseLandExpr procedure, valid LHS "|" subexpr} testexprparser {
+ testexprparser {1|2 && 3} -1
+} {- {} 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-4.2 {ParseLandExpr procedure, error in LHS "|" subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1&&foo && 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-4.3 {ParseLandExpr procedure, next lexeme isn't "&&"} testexprparser {
+ testexprparser {1|2? 1 : 0} -1
+} {- {} 0 subexpr {1|2? 1 : 0} 11 operator ? 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-4.4 {ParseLandExpr procedure, next lexeme is "&&"} testexprparser {
+ testexprparser {1|2 && 3} -1
+} {- {} 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-4.5 {ParseLandExpr procedure, bad lexeme after "&&"} testexprparser {
+ testexprparser {1|2 && 12345678901234567890} -1
+} {- {} 0 subexpr {1|2 && 12345678901234567890} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-4.6 {ParseLandExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1|2 && 3 && 4} -1
+} {- {} 0 subexpr {1|2 && 3 && 4} 13 operator && 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-4.7 {ParseLandExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1|2 && 3 && martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-5.1 {ParseBitOrExpr procedure, valid LHS "^" subexpr} testexprparser {
+ testexprparser {1^2 | 3} -1
+} {- {} 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-5.2 {ParseBitOrExpr procedure, error in LHS "^" subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1|foo | 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-5.3 {ParseBitOrExpr procedure, next lexeme isn't "|"} testexprparser {
+ testexprparser {1^2? 1 : 0} -1
+} {- {} 0 subexpr {1^2? 1 : 0} 11 operator ? 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-5.4 {ParseBitOrExpr procedure, next lexeme is "|"} testexprparser {
+ testexprparser {1^2 | 3} -1
+} {- {} 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-5.5 {ParseBitOrExpr procedure, bad lexeme after "|"} testexprparser {
+ testexprparser {1^2 | 12345678901234567890} -1
+} {- {} 0 subexpr {1^2 | 12345678901234567890} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-5.6 {ParseBitOrExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1^2 | 3 | 4} -1
+} {- {} 0 subexpr {1^2 | 3 | 4} 13 operator | 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-5.7 {ParseBitOrExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1^2 | 3 | martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-6.1 {ParseBitXorExpr procedure, valid LHS "&" subexpr} testexprparser {
+ testexprparser {1&2 ^ 3} -1
+} {- {} 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-6.2 {ParseBitXorExpr procedure, error in LHS "&" subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1^foo ^ 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-6.3 {ParseBitXorExpr procedure, next lexeme isn't "^"} testexprparser {
+ testexprparser {1&2? 1 : 0} -1
+} {- {} 0 subexpr {1&2? 1 : 0} 11 operator ? 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-6.4 {ParseBitXorExpr procedure, next lexeme is "^"} testexprparser {
+ testexprparser {1&2 ^ 3} -1
+} {- {} 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-6.5 {ParseBitXorExpr procedure, bad lexeme after "^"} testexprparser {
+ testexprparser {1&2 ^ 12345678901234567890} -1
+} {- {} 0 subexpr {1&2 ^ 12345678901234567890} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-6.6 {ParseBitXorExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1&2 ^ 3 ^ 4} -1
+} {- {} 0 subexpr {1&2 ^ 3 ^ 4} 13 operator ^ 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-6.7 {ParseBitXorExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1&2 ^ 3 ^ martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-7.1 {ParseBitAndExpr procedure, valid LHS equality subexpr} testexprparser {
+ testexprparser {1==2 & 3} -1
+} {- {} 0 subexpr {1==2 & 3} 9 operator & 0 subexpr 1==2 5 operator == 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-7.2 {ParseBitAndExpr procedure, error in LHS equality subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1!=foo & 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-7.3 {ParseBitAndExpr procedure, next lexeme isn't "&"} testexprparser {
+ testexprparser {1==2? 1 : 0} -1
+} {- {} 0 subexpr {1==2? 1 : 0} 11 operator ? 0 subexpr 1==2 5 operator == 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-7.4 {ParseBitAndExpr procedure, next lexeme is "&"} testexprparser {
+ testexprparser {1>2 & 3} -1
+} {- {} 0 subexpr {1>2 & 3} 9 operator & 0 subexpr 1>2 5 operator > 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-7.5 {ParseBitAndExpr procedure, bad lexeme after "&"} {testexprparser} {
+ testexprparser {1==2 & 12345678901234567890} -1
+} {- {} 0 subexpr {1==2 & 12345678901234567890} 9 operator & 0 subexpr 1==2 5 operator == 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-7.6 {ParseBitAndExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1<2 & 3 & 4} -1
+} {- {} 0 subexpr {1<2 & 3 & 4} 13 operator & 0 subexpr {1<2 & 3} 9 operator & 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-7.7 {ParseBitAndExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1==2 & 3>2 & martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-8.1 {ParseEqualityExpr procedure, valid LHS relational subexpr} testexprparser {
+ testexprparser {1<2 == 3} -1
+} {- {} 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-8.2 {ParseEqualityExpr procedure, error in LHS relational subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1>=foo == 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-8.3 {ParseEqualityExpr procedure, next lexeme isn't "==" or "!="} testexprparser {
+ testexprparser {1<2? 1 : 0} -1
+} {- {} 0 subexpr {1<2? 1 : 0} 11 operator ? 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-8.4 {ParseEqualityExpr procedure, next lexeme is "==" or "!="} testexprparser {
+ testexprparser {1<2 == 3} -1
+} {- {} 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-8.5 {ParseEqualityExpr procedure, next lexeme is "==" or "!="} testexprparser {
+ testexprparser {1<2 != 3} -1
+} {- {} 0 subexpr {1<2 != 3} 9 operator != 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-8.6 {ParseEqualityExpr procedure, bad lexeme after "==" or "!="} testexprparser {
+ testexprparser {1<2 == 12345678901234567890} -1
+} {- {} 0 subexpr {1<2 == 12345678901234567890} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-8.7 {ParseEqualityExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1<2 == 3 == 4} -1
+} {- {} 0 subexpr {1<2 == 3 == 4} 13 operator == 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-8.8 {ParseEqualityExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1<2 == 3 != martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-9.1 {ParseRelationalExpr procedure, valid LHS shift subexpr} testexprparser {
+ testexprparser {1<<2 < 3} -1
+} {- {} 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-9.2 {ParseRelationalExpr procedure, error in LHS shift subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1>=foo < 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-9.3 {ParseRelationalExpr procedure, next lexeme isn't relational op} testexprparser {
+ testexprparser {1<<2? 1 : 0} -1
+} {- {} 0 subexpr {1<<2? 1 : 0} 11 operator ? 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-9.4 {ParseRelationalExpr procedure, next lexeme is relational op} testexprparser {
+ testexprparser {1<<2 < 3} -1
+} {- {} 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-9.5 {ParseRelationalExpr procedure, next lexeme is relational op} testexprparser {
+ testexprparser {1>>2 > 3} -1
+} {- {} 0 subexpr {1>>2 > 3} 9 operator > 0 subexpr 1>>2 5 operator >> 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-9.6 {ParseRelationalExpr procedure, next lexeme is relational op} testexprparser {
+ testexprparser {1<<2 <= 3} -1
+} {- {} 0 subexpr {1<<2 <= 3} 9 operator <= 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-9.7 {ParseRelationalExpr procedure, next lexeme is relational op} testexprparser {
+ testexprparser {1<<2 >= 3} -1
+} {- {} 0 subexpr {1<<2 >= 3} 9 operator >= 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-9.8 {ParseRelationalExpr procedure, bad lexeme after relational op} testexprparser {
+ testexprparser {1<<2 < 12345678901234567890} -1
+} {- {} 0 subexpr {1<<2 < 12345678901234567890} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-9.9 {ParseRelationalExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1<<2 < 3 < 4} -1
+} {- {} 0 subexpr {1<<2 < 3 < 4} 13 operator < 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-9.10 {ParseRelationalExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1<<2 < 3 > martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-10.1 {ParseShiftExpr procedure, valid LHS add subexpr} testexprparser {
+ testexprparser {1+2 << 3} -1
+} {- {} 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-10.2 {ParseShiftExpr procedure, error in LHS add subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1-foo << 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-10.3 {ParseShiftExpr procedure, next lexeme isn't "<<" or ">>"} testexprparser {
+ testexprparser {1+2? 1 : 0} -1
+} {- {} 0 subexpr {1+2? 1 : 0} 11 operator ? 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-10.4 {ParseShiftExpr procedure, next lexeme is "<<" or ">>"} testexprparser {
+ testexprparser {1+2 << 3} -1
+} {- {} 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-10.5 {ParseShiftExpr procedure, next lexeme is "<<" or ">>"} testexprparser {
+ testexprparser {1+2 >> 3} -1
+} {- {} 0 subexpr {1+2 >> 3} 9 operator >> 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-10.6 {ParseShiftExpr procedure, bad lexeme after "<<" or ">>"} testexprparser {
+ testexprparser {1+2 << 12345678901234567890} -1
+} {- {} 0 subexpr {1+2 << 12345678901234567890} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-10.7 {ParseShiftExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1+2 << 3 << 4} -1
+} {- {} 0 subexpr {1+2 << 3 << 4} 13 operator << 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-10.8 {ParseShiftExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1+2 << 3 >> martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-11.1 {ParseAddExpr procedure, valid LHS multiply subexpr} testexprparser {
+ testexprparser {1*2 + 3} -1
+} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-11.2 {ParseAddExpr procedure, error in LHS multiply subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1/foo + 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-11.3 {ParseAddExpr procedure, next lexeme isn't "+" or "-"} testexprparser {
+ testexprparser {1*2? 1 : 0} -1
+} {- {} 0 subexpr {1*2? 1 : 0} 11 operator ? 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-11.4 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
+ testexprparser {1*2 + 3} -1
+} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-11.5 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
+ testexprparser {1*2 - 3} -1
+} {- {} 0 subexpr {1*2 - 3} 9 operator - 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-11.6 {ParseAddExpr procedure, bad lexeme after "+" or "-"} testexprparser {
+ testexprparser {1*2 + 12345678901234567890} -1
+} {- {} 0 subexpr {1*2 + 12345678901234567890} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-11.7 {ParseAddExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1*2 + 3 + 4} -1
+} {- {} 0 subexpr {1*2 + 3 + 4} 13 operator + 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-11.8 {ParseAddExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1*2 + 3 - martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-12.1 {ParseAddExpr procedure, valid LHS multiply subexpr} testexprparser {
+ testexprparser {1*2 + 3} -1
+} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-12.2 {ParseAddExpr procedure, error in LHS multiply subexpr} \
+ -constraints testexprparser -body {
+ testexprparser {1/foo + 3} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-12.3 {ParseAddExpr procedure, next lexeme isn't "+" or "-"} testexprparser {
+ testexprparser {1*2? 1 : 0} -1
+} {- {} 0 subexpr {1*2? 1 : 0} 11 operator ? 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-12.4 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
+ testexprparser {1*2 + 3} -1
+} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-12.5 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
+ testexprparser {1*2 - 3} -1
+} {- {} 0 subexpr {1*2 - 3} 9 operator - 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-12.6 {ParseAddExpr procedure, bad lexeme after "+" or "-"} testexprparser {
+ testexprparser {1*2 + 12345678901234567890} -1
+} {- {} 0 subexpr {1*2 + 12345678901234567890} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-12.7 {ParseAddExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {1*2 + 3 + 4} -1
+} {- {} 0 subexpr {1*2 + 3 + 4} 13 operator + 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-12.8 {ParseAddExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {1*2 + 3 - martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-13.1 {ParseMultiplyExpr procedure, valid LHS unary subexpr} testexprparser {
+ testexprparser {+2 * 3} -1
+} {- {} 0 subexpr {+2 * 3} 7 operator * 0 subexpr +2 3 operator + 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-13.2 {ParseMultiplyExpr procedure, error in LHS unary subexpr} testexprparser {
+ testexprparser {-12345678901234567890 * 3} -1
+} {- {} 0 subexpr {-12345678901234567890 * 3} 7 operator * 0 subexpr -12345678901234567890 3 operator - 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-13.3 {ParseMultiplyExpr procedure, next lexeme isn't "*", "/", or "%"} testexprparser {
+ testexprparser {+2? 1 : 0} -1
+} {- {} 0 subexpr {+2? 1 : 0} 9 operator ? 0 subexpr +2 3 operator + 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-13.4 {ParseMultiplyExpr procedure, next lexeme is "*", "/", or "%"} testexprparser {
+ testexprparser {-123 * 3} -1
+} {- {} 0 subexpr {-123 * 3} 7 operator * 0 subexpr -123 3 operator - 0 subexpr 123 1 text 123 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-13.5 {ParseMultiplyExpr procedure, next lexeme is "*", "/", or "%"} testexprparser {
+ testexprparser {+-456 / 3} -1
+} {- {} 0 subexpr {+-456 / 3} 9 operator / 0 subexpr +-456 5 operator + 0 subexpr -456 3 operator - 0 subexpr 456 1 text 456 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-13.6 {ParseMultiplyExpr procedure, next lexeme is "*", "/", or "%"} testexprparser {
+ testexprparser {+-456 % 3} -1
+} {- {} 0 subexpr {+-456 % 3} 9 operator % 0 subexpr +-456 5 operator + 0 subexpr -456 3 operator - 0 subexpr 456 1 text 456 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-13.7 {ParseMultiplyExpr procedure, bad lexeme after "*", "/", or "%"} testexprparser {
+ testexprparser {--++5 / 12345678901234567890} -1
+} {- {} 0 subexpr {--++5 / 12345678901234567890} 13 operator / 0 subexpr --++5 9 operator - 0 subexpr -++5 7 operator - 0 subexpr ++5 5 operator + 0 subexpr +5 3 operator + 0 subexpr 5 1 text 5 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-13.8 {ParseMultiplyExpr procedure, valid RHS subexpression} testexprparser {
+ testexprparser {-2 / 3 % 4} -1
+} {- {} 0 subexpr {-2 / 3 % 4} 11 operator % 0 subexpr {-2 / 3} 7 operator / 0 subexpr -2 3 operator - 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-13.9 {ParseMultiplyExpr procedure, error in RHS subexpression} \
+ -constraints testexprparser -body {
+ testexprparser {++2 / 3 * martha} -1
+ } -match glob -returnCodes error -result *
+
+test parseExpr-14.1 {ParseUnaryExpr procedure, first token is unary operator} testexprparser {
+ testexprparser {+2} -1
+} {- {} 0 subexpr +2 3 operator + 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-14.2 {ParseUnaryExpr procedure, first token is unary operator} testexprparser {
+ testexprparser {-2} -1
+} {- {} 0 subexpr -2 3 operator - 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-14.3 {ParseUnaryExpr procedure, first token is unary operator} testexprparser {
+ testexprparser {~2} -1
+} {- {} 0 subexpr ~2 3 operator ~ 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-14.4 {ParseUnaryExpr procedure, first token is unary operator} testexprparser {
+ testexprparser {!2} -1
+} {- {} 0 subexpr !2 3 operator ! 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-14.5 {ParseUnaryExpr procedure, error in lexeme after unary op} testexprparser {
+ testexprparser {-12345678901234567890} -1
+} {- {} 0 subexpr -12345678901234567890 3 operator - 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-14.6 {ParseUnaryExpr procedure, simple unary expr after unary op} testexprparser {
+ testexprparser {+"1234"} -1
+} {- {} 0 subexpr +\"1234\" 3 operator + 0 subexpr {"1234"} 1 text 1234 0 {}}
+test parseExpr-14.7 {ParseUnaryExpr procedure, another unary expr after unary op} testexprparser {
+ testexprparser {~!{fred}} -1
+} {- {} 0 subexpr ~!{fred} 5 operator ~ 0 subexpr !{fred} 3 operator ! 0 subexpr {{fred}} 1 text fred 0 {}}
+test parseExpr-14.8 {ParseUnaryExpr procedure, error in unary expr after unary op} -constraints testexprparser -body {
+ testexprparser {+-||27} -1
+} -returnCodes error -match glob -result *
+test parseExpr-14.9 {ParseUnaryExpr procedure, error in unary expr after unary op} -constraints testexprparser -body {
+ testexprparser {+-||27} -1
+} -returnCodes error -match glob -result *
+test parseExpr-14.10 {ParseUnaryExpr procedure, first token is not unary op} testexprparser {
+ testexprparser {123} -1
+} {- {} 0 subexpr 123 1 text 123 0 {}}
+test parseExpr-14.11 {ParseUnaryExpr procedure, not unary expr, complex primary expr} testexprparser {
+ testexprparser {(1+2)} -1
+} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-14.12 {ParseUnaryExpr procedure, not unary expr, error in primary expr} testexprparser {
+ testexprparser {(12345678901234567890)} -1
+} {- {} 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+
+test parseExpr-15.1 {ParsePrimaryExpr procedure, just parenthesized subexpr} testexprparser {
+ testexprparser {({abc}/{def})} -1
+} {- {} 0 subexpr {{abc}/{def}} 5 operator / 0 subexpr {{abc}} 1 text abc 0 subexpr {{def}} 1 text def 0 {}}
+test parseExpr-15.2 {ParsePrimaryExpr procedure, bad lexeme after "("} {testexprparser} {
+ testexprparser {(12345678901234567890)} -1
+} {- {} 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-15.3 {ParsePrimaryExpr procedure, valid parenthesized subexpr} testexprparser {
+ testexprparser {({abc}? 2*4 : -6)} -1
+} {- {} 0 subexpr {{abc}? 2*4 : -6} 13 operator ? 0 subexpr {{abc}} 1 text abc 0 subexpr 2*4 5 operator * 0 subexpr 2 1 text 2 0 subexpr 4 1 text 4 0 subexpr -6 3 operator - 0 subexpr 6 1 text 6 0 {}}
+test parseExpr-15.4 {ParsePrimaryExpr procedure, error in parenthesized subexpr} -constraints testexprparser -body {
+ testexprparser {(? 123 : 456)} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.5 {ParsePrimaryExpr procedure, missing ")" after in parenthesized subexpr} -constraints testexprparser -body {
+ testexprparser {({abc}/{def}} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.6 {ParsePrimaryExpr procedure, primary is literal} testexprparser {
+ testexprparser {12345} -1
+} {- {} 0 subexpr 12345 1 text 12345 0 {}}
+test parseExpr-15.7 {ParsePrimaryExpr procedure, primary is literal} testexprparser {
+ testexprparser {12345.6789} -1
+} {- {} 0 subexpr 12345.6789 1 text 12345.6789 0 {}}
+test parseExpr-15.8 {ParsePrimaryExpr procedure, primary is var reference} testexprparser {
+ testexprparser {$a} -1
+} {- {} 0 subexpr {$a} 2 variable {$a} 1 text a 0 {}}
+test parseExpr-15.9 {ParsePrimaryExpr procedure, primary is var reference} testexprparser {
+ testexprparser {$a(hello$there)} -1
+} {- {} 0 subexpr {$a(hello$there)} 5 variable {$a(hello$there)} 4 text a 0 text hello 0 variable {$there} 1 text there 0 {}}
+test parseExpr-15.10 {ParsePrimaryExpr procedure, primary is var reference} testexprparser {
+ testexprparser {$a()} -1
+} {- {} 0 subexpr {$a()} 3 variable {$a()} 2 text a 0 text {} 0 {}}
+test parseExpr-15.11 {ParsePrimaryExpr procedure, error in var reference} -constraints testexprparser -body {
+ testexprparser {$a(} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.12 {ParsePrimaryExpr procedure, primary is quoted string} testexprparser {
+ testexprparser {"abc $xyz def"} -1
+} {- {} 0 subexpr {"abc $xyz def"} 5 word {"abc $xyz def"} 4 text {abc } 0 variable {$xyz} 1 text xyz 0 text { def} 0 {}}
+test parseExpr-15.13 {ParsePrimaryExpr procedure, error in quoted string} -constraints testexprparser -body {
+ testexprparser {"$a(12"} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.14 {ParsePrimaryExpr procedure, quoted string has multiple tokens} testexprparser {
+ testexprparser {"abc [xyz] $def"} -1
+} {- {} 0 subexpr {"abc [xyz] $def"} 6 word {"abc [xyz] $def"} 5 text {abc } 0 command {[xyz]} 0 text { } 0 variable {$def} 1 text def 0 {}}
+test parseExpr-15.15 {ParsePrimaryExpr procedure, primary is command} testexprparser {
+ testexprparser {[def]} -1
+} {- {} 0 subexpr {[def]} 1 command {[def]} 0 {}}
+test parseExpr-15.16 {ParsePrimaryExpr procedure, primary is multiple commands} testexprparser {
+ testexprparser {[one; two; three; four;]} -1
+} {- {} 0 subexpr {[one; two; three; four;]} 1 command {[one; two; three; four;]} 0 {}}
+test parseExpr-15.17 {ParsePrimaryExpr procedure, primary is multiple commands} testexprparser {
+ testexprparser {[one; two; three; four;]} -1
+} {- {} 0 subexpr {[one; two; three; four;]} 1 command {[one; two; three; four;]} 0 {}}
+test parseExpr-15.18 {ParsePrimaryExpr procedure, missing close bracket} -constraints testexprparser -body {
+ testexprparser {[one} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.19 {ParsePrimaryExpr procedure, primary is braced string} testexprparser {
+ testexprparser {{hello world}} -1
+} {- {} 0 subexpr {{hello world}} 1 text {hello world} 0 {}}
+test parseExpr-15.20 {ParsePrimaryExpr procedure, error in primary, which is braced string} -constraints testexprparser -body {
+ testexprparser "\{abc\\\n" -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.21 {ParsePrimaryExpr procedure, primary is braced string with multiple tokens} testexprparser {
+ testexprparser "\{ \\
+ +123 \}" -1
+} {- {} 0 subexpr \{\ \ \\\n\ +123\ \} 4 word \{\ \ \\\n\ +123\ \} 3 text { } 0 backslash \\\n\ 0 text {+123 } 0 {}}
+test parseExpr-15.22 {ParsePrimaryExpr procedure, primary is function call} testexprparser {
+ testexprparser {foo(123)} -1
+} {- {} 0 subexpr foo(123) 3 operator foo 0 subexpr 123 1 text 123 0 {}}
+test parseExpr-15.23 {ParsePrimaryExpr procedure, bad lexeme after function name} -constraints testexprparser -body {
+ testexprparser {foo 12345678901234567890 123)} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.24 {ParsePrimaryExpr procedure, lexeme after function name isn't "("} \
+ -constraints testexprparser -body {
+ testexprparser {foo 27.4 123)} -1
+ } -match glob -returnCodes error -result *
+test parseExpr-15.25 {ParsePrimaryExpr procedure, bad lexeme after "("} testexprparser {
+ testexprparser {foo(12345678901234567890)} -1
+} {- {} 0 subexpr foo(12345678901234567890) 3 operator foo 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-15.26 {ParsePrimaryExpr procedure, function call, one arg} testexprparser {
+ testexprparser {foo(27*4)} -1
+} {- {} 0 subexpr foo(27*4) 7 operator foo 0 subexpr 27*4 5 operator * 0 subexpr 27 1 text 27 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-15.27 {ParsePrimaryExpr procedure, error in function arg} -constraints testexprparser -body {
+ testexprparser {foo(*1-2)} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.28 {ParsePrimaryExpr procedure, error in function arg} -constraints testexprparser -body {
+ testexprparser {foo(*1-2)} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.29 {ParsePrimaryExpr procedure, function call, comma after arg} testexprparser {
+ testexprparser {foo(27-2, (-2*[foo]))} -1
+} {- {} 0 subexpr {foo(27-2, (-2*[foo]))} 15 operator foo 0 subexpr 27-2 5 operator - 0 subexpr 27 1 text 27 0 subexpr 2 1 text 2 0 subexpr {-2*[foo]} 7 operator * 0 subexpr -2 3 operator - 0 subexpr 2 1 text 2 0 subexpr {[foo]} 1 command {[foo]} 0 {}}
+test parseExpr-15.30 {ParsePrimaryExpr procedure, bad lexeme after comma} testexprparser {
+ testexprparser {foo(123, 12345678901234567890)} -1
+} {- {} 0 subexpr {foo(123, 12345678901234567890)} 5 operator foo 0 subexpr 123 1 text 123 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-15.31 {ParsePrimaryExpr procedure, lexeme not "," or ")" after arg} -constraints testexprparser -body {
+ testexprparser {foo(123 [foo])} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.32 {ParsePrimaryExpr procedure, bad lexeme after primary} -constraints testexprparser -body {
+ testexprparser {123 12345678901234567890} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.33 {ParsePrimaryExpr procedure, comma-specific message} -constraints testexprparser -body {
+ testexprparser {123+,456} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.34 {ParsePrimaryExpr procedure, single equal-specific message} -constraints testexprparser -body {
+ testexprparser {123+=456} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.35 {ParsePrimaryExpr procedure, error in parenthesized subexpr} -constraints testexprparser -body {
+ testexprparser {(: 123 : 456)} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.36 {ParsePrimaryExpr procedure, missing close-bracket} -constraints testexprparser -body {
+ # Test for Bug 681841
+ testexprparser {[set a [format bc]} -1
+} -returnCodes error -match glob -result *
+
+test parseExpr-16.1 {GetLexeme procedure, whitespace before lexeme} testexprparser {
+ testexprparser { 123} -1
+} {- {} 0 subexpr 123 1 text 123 0 {}}
+test parseExpr-16.2 {GetLexeme procedure, whitespace before lexeme} testexprparser {
+ testexprparser { \
+456} -1
+} {- {} 0 subexpr 456 1 text 456 0 {}}
+test parseExpr-16.3 {GetLexeme procedure, no lexeme after whitespace} testexprparser {
+ testexprparser { 123 \
+ } -1
+} {- {} 0 subexpr 123 1 text 123 0 {}}
+test parseExpr-16.4 {GetLexeme procedure, integer lexeme} testexprparser {
+ testexprparser {000} -1
+} {- {} 0 subexpr 000 1 text 000 0 {}}
+test parseExpr-16.5 {GetLexeme procedure, integer lexeme too big} testexprparser {
+ testexprparser {12345678901234567890} -1
+} {- {} 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-16.6 {GetLexeme procedure, bad integer lexeme} -constraints testexprparser -body {
+ testexprparser {0o999} -1
+} -returnCodes error -match glob -result {*invalid octal number*}
+test parseExpr-16.7 {GetLexeme procedure, double lexeme} testexprparser {
+ testexprparser {0.999} -1
+} {- {} 0 subexpr 0.999 1 text 0.999 0 {}}
+test parseExpr-16.8 {GetLexeme procedure, double lexeme} testexprparser {
+ testexprparser {.123} -1
+} {- {} 0 subexpr .123 1 text .123 0 {}}
+test parseExpr-16.9 {GetLexeme procedure, double lexeme} {testexprparser unix} {
+ testexprparser {nan} -1
+} {- {} 0 subexpr nan 1 text nan 0 {}}
+test parseExpr-16.10 {GetLexeme procedure, double lexeme} {testexprparser unix} {
+ testexprparser {NaN} -1
+} {- {} 0 subexpr NaN 1 text NaN 0 {}}
+test parseExpr-16.11a {GetLexeme procedure, bad double lexeme too big} {testexprparser && !ieeeFloatingPoint} {
+ list [catch {testexprparser {123.e+99999999999999} -1} msg] $msg
+} {1 {floating-point value too large to represent}}
+test parseExpr-16.11b {GetLexeme procedure, bad double lexeme too big} {testexprparser && ieeeFloatingPoint} {
+ list [catch {testexprparser {123.e+99999999999999} -1} msg] $msg
+} {0 {- {} 0 subexpr 123.e+99999999999999 1 text 123.e+99999999999999 0 {}}}
+test parseExpr-16.12 {GetLexeme procedure, bad double lexeme} -constraints testexprparser -body {
+ testexprparser {123.4x56} -1
+} -returnCodes error -match glob -result *
+test parseExpr-16.13 {GetLexeme procedure, lexeme is "["} testexprparser {
+ testexprparser {[foo]} -1
+} {- {} 0 subexpr {[foo]} 1 command {[foo]} 0 {}}
+test parseExpr-16.14 {GetLexeme procedure, lexeme is open brace} testexprparser {
+ testexprparser {{bar}} -1
+} {- {} 0 subexpr {{bar}} 1 text bar 0 {}}
+test parseExpr-16.15 {GetLexeme procedure, lexeme is "("} testexprparser {
+ testexprparser {(123)} -1
+} {- {} 0 subexpr 123 1 text 123 0 {}}
+test parseExpr-16.16 {GetLexeme procedure, lexeme is ")"} testexprparser {
+ testexprparser {(2*3)} -1
+} {- {} 0 subexpr 2*3 5 operator * 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.17 {GetLexeme procedure, lexeme is "$"} testexprparser {
+ testexprparser {$wombat} -1
+} {- {} 0 subexpr {$wombat} 2 variable {$wombat} 1 text wombat 0 {}}
+test parseExpr-16.18 "GetLexeme procedure, lexeme is '\"'" testexprparser {
+ testexprparser {"fred"} -1
+} {- {} 0 subexpr {"fred"} 1 text fred 0 {}}
+test parseExpr-16.19 {GetLexeme procedure, lexeme is ","} testexprparser {
+ testexprparser {foo(1,2)} -1
+} {- {} 0 subexpr foo(1,2) 5 operator foo 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.20 {GetLexeme procedure, lexeme is "*"} testexprparser {
+ testexprparser {$a*$b} -1
+} {- {} 0 subexpr {$a*$b} 7 operator * 0 subexpr {$a} 2 variable {$a} 1 text a 0 subexpr {$b} 2 variable {$b} 1 text b 0 {}}
+test parseExpr-16.21 {GetLexeme procedure, lexeme is "/"} testexprparser {
+ testexprparser {5/6} -1
+} {- {} 0 subexpr 5/6 5 operator / 0 subexpr 5 1 text 5 0 subexpr 6 1 text 6 0 {}}
+test parseExpr-16.22 {GetLexeme procedure, lexeme is "%"} testexprparser {
+ testexprparser {5%[xxx]} -1
+} {- {} 0 subexpr {5%[xxx]} 5 operator % 0 subexpr 5 1 text 5 0 subexpr {[xxx]} 1 command {[xxx]} 0 {}}
+test parseExpr-16.23 {GetLexeme procedure, lexeme is "+"} testexprparser {
+ testexprparser {1+2} -1
+} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.24 {GetLexeme procedure, lexeme is "-"} testexprparser {
+ testexprparser {.12-0e27} -1
+} {- {} 0 subexpr .12-0e27 5 operator - 0 subexpr .12 1 text .12 0 subexpr 0e27 1 text 0e27 0 {}}
+test parseExpr-16.25 {GetLexeme procedure, lexeme is "?" or ":"} testexprparser {
+ testexprparser {$b? 1 : 0} -1
+} {- {} 0 subexpr {$b? 1 : 0} 8 operator ? 0 subexpr {$b} 2 variable {$b} 1 text b 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-16.26 {GetLexeme procedure, lexeme is "<"} testexprparser {
+ testexprparser {2<3} -1
+} {- {} 0 subexpr 2<3 5 operator < 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.27 {GetLexeme procedure, lexeme is "<<"} testexprparser {
+ testexprparser {2<<3} -1
+} {- {} 0 subexpr 2<<3 5 operator << 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.28 {GetLexeme procedure, lexeme is "<="} testexprparser {
+ testexprparser {2<=3} -1
+} {- {} 0 subexpr 2<=3 5 operator <= 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.29 {GetLexeme procedure, lexeme is ">"} testexprparser {
+ testexprparser {2>3} -1
+} {- {} 0 subexpr 2>3 5 operator > 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.30 {GetLexeme procedure, lexeme is ">>"} testexprparser {
+ testexprparser {2>>3} -1
+} {- {} 0 subexpr 2>>3 5 operator >> 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.31 {GetLexeme procedure, lexeme is ">="} testexprparser {
+ testexprparser {2>=3} -1
+} {- {} 0 subexpr 2>=3 5 operator >= 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.32 {GetLexeme procedure, lexeme is "=="} testexprparser {
+ testexprparser {2==3} -1
+} {- {} 0 subexpr 2==3 5 operator == 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.33 {GetLexeme procedure, bad lexeme starting with "="} -constraints testexprparser -body {
+ testexprparser {2=+3} -1
+} -returnCodes error -match glob -result *
+test parseExpr-16.34 {GetLexeme procedure, lexeme is "!="} testexprparser {
+ testexprparser {2!=3} -1
+} {- {} 0 subexpr 2!=3 5 operator != 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.35 {GetLexeme procedure, lexeme is "!"} testexprparser {
+ testexprparser {!2} -1
+} {- {} 0 subexpr !2 3 operator ! 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.36 {GetLexeme procedure, lexeme is "&&"} testexprparser {
+ testexprparser {2&&3} -1
+} {- {} 0 subexpr 2&&3 5 operator && 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.37 {GetLexeme procedure, lexeme is "&"} testexprparser {
+ testexprparser {1&2} -1
+} {- {} 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.38 {GetLexeme procedure, lexeme is "^"} testexprparser {
+ testexprparser {1^2} -1
+} {- {} 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.39 {GetLexeme procedure, lexeme is "||"} testexprparser {
+ testexprparser {2||3} -1
+} {- {} 0 subexpr 2||3 5 operator || 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.40 {GetLexeme procedure, lexeme is "|"} testexprparser {
+ testexprparser {1|2} -1
+} {- {} 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.41 {GetLexeme procedure, lexeme is "~"} testexprparser {
+ testexprparser {~2} -1
+} {- {} 0 subexpr ~2 3 operator ~ 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.42 {GetLexeme procedure, lexeme is func name} testexprparser {
+ testexprparser {george()} -1
+} {- {} 0 subexpr george() 1 operator george 0 {}}
+test parseExpr-16.43 {GetLexeme procedure, lexeme is func name} testexprparser {
+ testexprparser {harmonic_ratio(2,3)} -1
+} {- {} 0 subexpr harmonic_ratio(2,3) 5 operator harmonic_ratio 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.44 {GetLexeme procedure, unknown lexeme} -constraints testexprparser -body {
+ testexprparser {@27} -1
+} -returnCodes error -match glob -result *
+
+test parseExpr-17.1 {PrependSubExprTokens procedure, expand token array} testexprparser {
+ testexprparser {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]} -1
+} {- {} 0 subexpr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]} 13 operator && 0 subexpr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]} 9 operator && 0 subexpr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]} 5 operator && 0 subexpr {[string compare [format %c $i] [string index $a $i]]} 1 command {[string compare [format %c $i] [string index $a $i]]} 0 subexpr {[string compare [format %c $i] [string index $a $i]]} 1 command {[string compare [format %c $i] [string index $a $i]]} 0 subexpr {[string compare [format %c $i] [string index $a $i]]} 1 command {[string compare [format %c $i] [string index $a $i]]} 0 subexpr {[string compare [format %c $i] [string index $a $i]]} 1 command {[string compare [format %c $i] [string index $a $i]]} 0 {}}
+
+test parseExpr-18.1 {LogSyntaxError procedure, error in expr longer than 60 chars} -constraints testexprparser -body {
+ testexprparser {(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)/} -1
+} -returnCodes error -match glob -result *
+
+test parseExpr-19.1 {TclParseInteger: [Bug 648441]} -body {
+ # Should see this as integer "0" followed by incomplete function "x"
+ # Thus, syntax error.
+ # If Bug 648441 is not fixed, "0x" will be seen as floating point 0.0
+ expr 0x
+} -returnCodes error -match glob -result *
+
+test parseExpr-20.1 {Bug 1451233} {
+ expr 1000000000000000000042
+} 1000000000000000000042
+test parseExpr-20.2 {Bug 1451233} {
+ expr 10000000000000000000420000000042
+} 10000000000000000000420000000042
+test parseExpr-20.3 {Bug 1451233} {
+ expr 10000000000000000000020000000002
+} 10000000000000000000020000000002
+
+test parseExpr-21.1 {error messages} -body {
+ expr @
+} -returnCodes error -result {invalid character "@"
+in expression "@"}
+test parseExpr-21.2 {error messages} -body {
+ expr =
+} -returnCodes error -result {incomplete operator "="
+in expression "="}
+test parseExpr-21.3 {error messages} -body {
+ expr x
+} -returnCodes error -result {invalid bareword "x"
+in expression "x";
+should be "$x" or "{x}" or "x(...)" or ...}
+test parseExpr-21.4 {error messages} -body {
+ expr abcdefghijklmnopqrstuvwxyz
+} -returnCodes error -result {invalid bareword "abcdefghijklmnopqrstuv..."
+in expression "abcdefghijklmnopqrstuv...";
+should be "$abcdefghijklmnopqrstuv..." or "{abcdefghijklmnopqrstuv...}" or "abcdefghijklmnopqrstuv...(...)" or ...}
+test parseExpr-21.5 {error messages} -body {
+ expr {[][]}
+} -returnCodes error -result {missing operator at _@_
+in expression "[]_@_[]"}
+test parseExpr-21.6 {error messages} -body {
+ expr {0 0}
+} -returnCodes error -result {missing operator at _@_
+in expression "0 _@_0"}
+test parseExpr-21.7 {error messages} -body {
+ expr {0o8}
+} -returnCodes error -match glob -result {*invalid octal number*}
+test parseExpr-21.8 {error messages} -body {
+ expr {0o8x}
+} -returnCodes error -match glob -result {*invalid octal number*}
+test parseExpr-21.9 {error messages} -body {
+ expr {"}
+} -returnCodes error -result {missing "
+in expression """}
+test parseExpr-21.10 {error messages} -body {
+ expr \{
+} -returnCodes error -result "missing close-brace
+in expression \"\{\""
+test parseExpr-21.11 {error messages} -body {
+ expr $
+} -returnCodes error -result {invalid character "$"
+in expression "$"}
+test parseExpr-21.12 {error messages} -body {
+ expr {$(}
+} -returnCodes error -result {missing )
+in expression "$("}
+test parseExpr-21.13 {error messages} -body {
+ expr {[""x]}
+} -returnCodes error -result {extra characters after close-quote
+in expression "[""x]"}
+test parseExpr-21.14 {error messages} -body {
+ expr {[}
+} -returnCodes error -result {missing close-bracket
+in expression "["}
+test parseExpr-21.15 {error messages} -body {
+ expr 0~0
+} -returnCodes error -result {missing operator at _@_
+in expression "0_@_~0"}
+test parseExpr-21.16 {error messages} -body {
+ expr ()
+} -returnCodes error -result {empty subexpression at _@_
+in expression "(_@_)"}
+test parseExpr-21.17 {error messages} -body {
+ expr (
+} -returnCodes error -result {unbalanced open paren
+in expression "("}
+test parseExpr-21.18 {error messages} -body {
+ expr a(0,)
+} -returnCodes error -result {missing function argument at _@_
+in expression "a(0,_@_)"}
+test parseExpr-21.19 {error messages} -body {
+ expr {}
+} -returnCodes error -result {empty expression
+in expression ""}
+test parseExpr-21.20 {error messages} -body {
+ expr )
+} -returnCodes error -result {unbalanced close paren
+in expression ")"}
+test parseExpr-21.21 {error messages} -body {
+ expr a(,0)
+} -returnCodes error -result {missing function argument at _@_
+in expression "a(_@_,0)"}
+test parseExpr-21.22 {error messages} -body {
+ expr 0&|0
+} -returnCodes error -result {missing operand at _@_
+in expression "0&_@_|0"}
+test parseExpr-21.23 {error messages} -body {
+ expr 0^^0
+} -returnCodes error -result {missing operand at _@_
+in expression "0^_@_^0"}
+test parseExpr-21.24 {error messages} -body {
+ expr 0|&0
+} -returnCodes error -result {missing operand at _@_
+in expression "0|_@_&0"}
+test parseExpr-21.25 {error messages} -body {
+ expr a(1+,0)
+} -returnCodes error -result {missing operand at _@_
+in expression "a(1+_@_,0)"}
+test parseExpr-21.26 {error messages} -body {
+ expr (0
+} -returnCodes error -result {unbalanced open paren
+in expression "(0"}
+test parseExpr-21.27 {error messages} -body {
+ expr 0?0
+} -returnCodes error -result {missing operator ":" at _@_
+in expression "0?0_@_"}
+test parseExpr-21.28 {error messages} -body {
+ expr 0:0
+} -returnCodes error -result {unexpected operator ":" without preceding "?"
+in expression "0:0"}
+test parseExpr-21.29 {error messages} -body {
+ expr 0)
+} -returnCodes error -result {unbalanced close paren
+in expression "0)"}
+test parseExpr-21.30 {error messages} -body {
+ expr 0,
+} -returnCodes error -result {unexpected "," outside function argument list
+in expression "0,"}
+test parseExpr-21.31 {error messages} -body {
+ expr 0,0
+} -returnCodes error -result {unexpected "," outside function argument list
+in expression "0,0"}
+test parseExpr-21.32 {error messages} -body {
+ expr (0,0)
+} -returnCodes error -result {unexpected "," outside function argument list
+in expression "(0,0)"}
+test parseExpr-21.33 {error messages} -body {
+ expr a(0:0,0)
+} -returnCodes error -result {unexpected operator ":" without preceding "?"
+in expression "a(0:0,0)"}
+test parseExpr-21.34 {error messages} -body {
+ expr {"abcdefghijklmnopqrstuvwxyz"@0}
+} -returnCodes error -result {invalid character "@"
+in expression "...fghijklmnopqrstuvwxyz"@0"}
+test parseExpr-21.35 {error messages} -body {
+ expr {0@"abcdefghijklmnopqrstuvwxyz"}
+} -returnCodes error -result {invalid character "@"
+in expression "0@"abcdefghijklmnopqrstu..."}
+test parseExpr-21.36 {error messages} -body {
+ expr {"abcdefghijklmnopqrstuvwxyz"@"abcdefghijklmnopqrstuvwxyz"}
+} -returnCodes error -result {invalid character "@"
+in expression "...fghijklmnopqrstuvwxyz"@"abcdefghijklmnopqrstu..."}
+test parseExpr-21.37 {error messages} -body {
+ expr [format {"%s" @ 0} [string repeat \u00a7 25]]
+} -returnCodes error -result [format {invalid character "@"
+in expression "...%s" @ 0"} [string repeat \u00a7 10]]
+test parseExpr-21.38 {error messages} -body {
+ expr [format {0 @ "%s"} [string repeat \u00a7 25]]
+} -returnCodes error -result [format {invalid character "@"
+in expression "0 @ "%s..."} [string repeat \u00a7 10]]
+test parseExpr-21.39 {error messages} -body {
+ expr [format {"%s" @ "%s"} [string repeat \u00a7 25] [string repeat \u00a7 25]]
+} -returnCodes error -result [format {invalid character "@"
+in expression "...%s" @ "%s..."} [string repeat \u00a7 10] [string repeat \u00a7 10]]
+test parseExpr-21.40 {error messages} -body {
+ catch {expr {"abcdefghijklmnopqrstuvwxyz"@0}} m o
+ dict get $o -errorinfo
+} -result {invalid character "@"
+in expression "...fghijklmnopqrstuvwxyz"@0"
+ (parsing expression ""abcdefghijklmnopqrstu...")
+ invoked from within
+"expr {"abcdefghijklmnopqrstuvwxyz"@0}"}
+test parseExpr-21.41 {error messages} -body {
+ catch {expr [format {"%s" @ 0} [string repeat \u00a7 25]]} m o
+ dict get $o -errorinfo
+} -result [format {invalid character "@"
+in expression "...%s" @ 0"
+ (parsing expression ""%s...")
+ invoked from within
+"expr [format {"%%s" @ 0} [string repeat \u00a7 25]]"} [string repeat \u00a7 10] [string repeat \u00a7 10]]
+test parseExpr-21.42 {error message} -body {
+ expr {123456789012345678901234567890*"abcdefghijklmnopqrstuvwxyz}
+} -returnCodes error -result {missing "
+in expression "...012345678901234567890*"abcdefghijklmnopqrstuv..."}
+test parseExpr-21.43 {error message} -body {
+ expr "123456789012345678901234567890*\"foobar\$\{abcdefghijklmnopqrstuvwxyz\""
+} -returnCodes error -result "missing close-brace for variable name
+in expression \"...8901234567890*\"foobar\$\{abcdefghijklmnopqrstuv...\""
+test parseExpr-21.44 {error message} -body {
+ expr {123456789012345678901234567890*"foo$bar(abcdefghijklmnopqrstuvwxyz"}
+} -returnCodes error -result {missing )
+in expression "...8901234567890*"foo$bar(abcdefghijklmnopqrstuv..."}
+test parseExpr-21.45 {error message} -body {
+ expr {123456789012345678901234567890*"foo$bar([{}abcdefghijklmnopqrstuvwxyz])"}
+} -returnCodes error -result {extra characters after close-brace
+in expression "...234567890*"foo$bar([{}abcdefghijklmnopqrstuv..."}
+test parseExpr-21.46 {error message} -body {
+ expr {123456789012345678901234567890*"foo$bar([""abcdefghijklmnopqrstuvwxyz])"}
+} -returnCodes error -result {extra characters after close-quote
+in expression "...234567890*"foo$bar([""abcdefghijklmnopqrstuv..."}
+test parseExpr-21.47 {error message} -body {
+ expr {123456789012345678901234567890*"foo$bar([abcdefghijklmnopqrstuvwxyz)"}
+} -returnCodes error -result {missing close-bracket
+in expression "...901234567890*"foo$bar([abcdefghijklmnopqrstuv..."}
+test parseExpr-21.48 {error message} -body {
+ expr "123456789012345678901234567890*\"foo\$bar(\[\{abcdefghijklmnopqrstuvwxyz])\""
+} -returnCodes error -result "missing close-brace
+in expression \"...01234567890*\"foo\$bar(\[\{abcdefghijklmnopqrstuv...\""
+
+test parseExpr-21.49 {error message} -body {
+ expr "123456789012345678901234567890*\{abcdefghijklmnopqrstuvwxyz"
+} -returnCodes error -result "missing close-brace
+in expression \"...012345678901234567890*\{abcdefghijklmnopqrstuv...\""
+
+test parseExpr-21.50 {error message} -body {
+ expr {123456789012345678901234567890*$foo(["abcdefghijklmnopqrstuvwxyz])}
+} -returnCodes error -result {missing "
+in expression "...678901234567890*$foo(["abcdefghijklmnopqrstuv..."}
+test parseExpr-21.51 {error message} -body {
+ expr "123456789012345678901234567890*\$\{abcdefghijklmnopqrstuvwxyz"
+} -returnCodes error -result "missing close-brace for variable name
+in expression \"...12345678901234567890*\$\{abcdefghijklmnopqrstuv...\""
+test parseExpr-21.52 {error message} -body {
+ expr {123456789012345678901234567890*$bar(abcdefghijklmnopqrstuvwxyz}
+} -returnCodes error -result {missing )
+in expression "...45678901234567890*$bar(abcdefghijklmnopqrstuv..."}
+test parseExpr-21.53 {error message} -body {
+ expr {123456789012345678901234567890*$bar([{}abcdefghijklmnopqrstuvwxyz])"}
+} -returnCodes error -result {extra characters after close-brace
+in expression "...8901234567890*$bar([{}abcdefghijklmnopqrstuv..."}
+test parseExpr-21.54 {error message} -body {
+ expr {123456789012345678901234567890*$bar([""abcdefghijklmnopqrstuvwxyz])"}
+} -returnCodes error -result {extra characters after close-quote
+in expression "...8901234567890*$bar([""abcdefghijklmnopqrstuv..."}
+test parseExpr-21.55 {error message} -body {
+ expr {123456789012345678901234567890*$bar([abcdefghijklmnopqrstuvwxyz)"}
+} -returnCodes error -result {missing close-bracket
+in expression "...5678901234567890*$bar([abcdefghijklmnopqrstuv..."}
+test parseExpr-21.56 {error message} -body {
+ expr "123456789012345678901234567890*\$bar(\[\{abcdefghijklmnopqrstuvwxyz])"
+} -returnCodes error -result "missing close-brace
+in expression \"...678901234567890*\$bar(\[\{abcdefghijklmnopqrstuv...\""
+
+test parseExpr-21.57 {error message} -body {
+ expr {123456789012345678901234567890*["abcdefghijklmnopqrstuvwxyz]}
+} -returnCodes error -result {missing "
+in expression "...12345678901234567890*["abcdefghijklmnopqrstuv..."}
+test parseExpr-21.58 {error message} -body {
+ expr "123456789012345678901234567890*\[\$\{abcdefghijklmnopqrstuvwxyz]"
+} -returnCodes error -result "missing close-brace for variable name
+in expression \"...2345678901234567890*\[\$\{abcdefghijklmnopqrstuv...\""
+test parseExpr-21.59 {error message} -body {
+ expr {123456789012345678901234567890*[$bar(abcdefghijklmnopqrstuvwxyz]}
+} -returnCodes error -result {missing )
+in expression "...5678901234567890*[$bar(abcdefghijklmnopqrstuv..."}
+test parseExpr-21.60 {error message} -body {
+ expr {123456789012345678901234567890*[{}abcdefghijklmnopqrstuvwxyz]"}
+} -returnCodes error -result {extra characters after close-brace
+in expression "...345678901234567890*[{}abcdefghijklmnopqrstuv..."}
+test parseExpr-21.61 {error message} -body {
+ expr {123456789012345678901234567890*[""abcdefghijklmnopqrstuvwxyz]"}
+} -returnCodes error -result {extra characters after close-quote
+in expression "...345678901234567890*[""abcdefghijklmnopqrstuv..."}
+test parseExpr-21.62 {error message} -body {
+ expr {123456789012345678901234567890*[abcdefghijklmnopqrstuvwxyz"}
+} -returnCodes error -result {missing close-bracket
+in expression "...012345678901234567890*[abcdefghijklmnopqrstuv..."}
+test parseExpr-21.63 {error message} -body {
+ expr "123456789012345678901234567890*\[\{abcdefghijklmnopqrstuvwxyz]"
+} -returnCodes error -result "missing close-brace
+in expression \"...12345678901234567890*\[\{abcdefghijklmnopqrstuv...\""
+
+test parseExpr-22.1 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser 2a() 1
+} -result {- {} 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-22.2 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser nana() 3
+} -result {- {} 0 subexpr nan 1 text nan 0 {}}
+test parseExpr-22.3 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser 2a() -1
+} -result {- {} 0 subexpr 2a() 1 operator 2a 0 {}}
+test parseExpr-22.4 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser nana() -1
+} -result {- {} 0 subexpr nana() 1 operator nana 0 {}}
+test parseExpr-22.5 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser nan9() -1
+} -result {- {} 0 subexpr nan9() 1 operator nan9 0 {}}
+test parseExpr-22.6 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser 2_() -1
+} -result {- {} 0 subexpr 2_() 1 operator 2_ 0 {}}
+test parseExpr-22.7 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser nan_() -1
+} -result {- {} 0 subexpr nan_() 1 operator nan_ 0 {}}
+test parseExpr-22.8 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser nan!() -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR MISSING}
+test parseExpr-22.9 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser 1e3_() -1
+} -result {- {} 0 subexpr 1e3_() 1 operator 1e3_ 0 {}}
+test parseExpr-22.10 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 1.3_() -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADCHAR}
+test parseExpr-22.11 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 1e-3_() -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADCHAR}
+test parseExpr-22.12 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser naneq() -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR EMPTY}
+test parseExpr-22.13 {Bug 3401704} -constraints testexprparser -body {
+ testexprparser naner() -1
+} -result {- {} 0 subexpr naner() 1 operator naner 0 {}}
+
+test parseExpr-22.14 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 08 -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER OCTAL}
+test parseExpr-22.15 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 0o8 -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER OCTAL}
+test parseExpr-22.16 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 0o08 -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER OCTAL}
+test parseExpr-22.17 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 0b2 -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER BINARY}
+test parseExpr-22.18 {Bug 3401704} -constraints testexprparser -body {
+ catch {testexprparser 0b02 -1} m o
+ dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER BINARY}
+
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/parseOld.test b/pkgs/msgcat/tests/parseOld.test
new file mode 100644
index 0000000..132481c
--- /dev/null
+++ b/pkgs/msgcat/tests/parseOld.test
@@ -0,0 +1,543 @@
+# Commands covered: set (plus basic command syntax). Also tests the
+# procedures in the file tclOldParse.c. This set of tests is an old
+# one that predates the new parser in Tcl 8.1.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testwordend [llength [info commands testwordend]]
+
+# Save the argv value for restoration later
+set savedArgv $argv
+
+proc fourArgs {a b c d} {
+ global arg1 arg2 arg3 arg4
+ set arg1 $a
+ set arg2 $b
+ set arg3 $c
+ set arg4 $d
+}
+
+proc getArgs args {
+ global argv
+ set argv $args
+}
+
+# Basic argument parsing.
+
+test parseOld-1.1 {basic argument parsing} {
+ set arg1 {}
+ fourArgs a b c d
+ list $arg1 $arg2 $arg3 $arg4
+} {a b c d}
+test parseOld-1.2 {basic argument parsing} {
+ set arg1 {}
+ eval "fourArgs 123\v4\f56\r7890"
+ list $arg1 $arg2 $arg3 $arg4
+} {123 4 56 7890}
+
+# Quotes.
+
+test parseOld-2.1 {quotes and variable-substitution} {
+ getArgs "a b c" d
+ set argv
+} {{a b c} d}
+test parseOld-2.2 {quotes and variable-substitution} {
+ set a 101
+ getArgs "a$a b c"
+ set argv
+} {{a101 b c}}
+test parseOld-2.3 {quotes and variable-substitution} {
+ set argv "xy[format xabc]"
+ set argv
+} {xyxabc}
+test parseOld-2.4 {quotes and variable-substitution} {
+ set argv "xy\t"
+ set argv
+} xy\t
+test parseOld-2.5 {quotes and variable-substitution} {
+ set argv "a b c
+d e f"
+ set argv
+} a\ b\tc\nd\ e\ f
+test parseOld-2.6 {quotes and variable-substitution} {
+ set argv a"bcd"e
+ set argv
+} {a"bcd"e}
+
+# Braces.
+
+test parseOld-3.1 {braces} {
+ getArgs {a b c} d
+ set argv
+} "{a b c} d"
+test parseOld-3.2 {braces} {
+ set a 101
+ set argv {a$a b c}
+ set b [string index $argv 1]
+ set b
+} {$}
+test parseOld-3.3 {braces} {
+ set argv {a[format xyz] b}
+ string length $argv
+} 15
+test parseOld-3.4 {braces} {
+ set argv {a\nb\}}
+ string length $argv
+} 6
+test parseOld-3.5 {braces} {
+ set argv {{{{}}}}
+ set argv
+} "{{{}}}"
+test parseOld-3.6 {braces} {
+ set argv a{{}}b
+ set argv
+} "a{{}}b"
+test parseOld-3.7 {braces} {
+ set a [format "last]"]
+ set a
+} {last]}
+
+# Command substitution.
+
+test parseOld-4.1 {command substitution} {
+ set a [format xyz]
+ set a
+} xyz
+test parseOld-4.2 {command substitution} {
+ set a a[format xyz]b[format q]
+ set a
+} axyzbq
+test parseOld-4.3 {command substitution} {
+ set a a[
+set b 22;
+format %s $b
+
+]b
+ set a
+} a22b
+test parseOld-4.4 {command substitution} {
+ set a 7.7
+ if [catch {expr int($a)}] {set a foo}
+ set a
+} 7.7
+
+# Variable substitution.
+
+test parseOld-5.1 {variable substitution} {
+ set a 123
+ set b $a
+ set b
+} 123
+test parseOld-5.2 {variable substitution} {
+ set a 345
+ set b x$a.b
+ set b
+} x345.b
+test parseOld-5.3 {variable substitution} {
+ set _123z xx
+ set b $_123z^
+ set b
+} xx^
+test parseOld-5.4 {variable substitution} {
+ set a 78
+ set b a${a}b
+ set b
+} a78b
+test parseOld-5.5 {variable substitution} {catch {$_non_existent_} msg} 1
+test parseOld-5.6 {variable substitution} {
+ catch {$_non_existent_} msg
+ set msg
+} {can't read "_non_existent_": no such variable}
+test parseOld-5.7 {array variable substitution} {
+ catch {unset a}
+ set a(xyz) 123
+ set b $a(xyz)foo
+ set b
+} 123foo
+test parseOld-5.8 {array variable substitution} {
+ catch {unset a}
+ set "a(x y z)" 123
+ set b $a(x y z)foo
+ set b
+} 123foo
+test parseOld-5.9 {array variable substitution} {
+ catch {unset a}; catch {unset qqq}
+ set "a(x y z)" qqq
+ set $a([format x]\ y [format z]) foo
+ set qqq
+} foo
+test parseOld-5.10 {array variable substitution} {
+ catch {unset a}
+ list [catch {set b $a(22)} msg] $msg
+} {1 {can't read "a(22)": no such variable}}
+test parseOld-5.11 {array variable substitution} {
+ set b a$!
+ set b
+} {a$!}
+test parseOld-5.12 {empty array name support} {
+ list [catch {set b a$()} msg] $msg
+} {1 {can't read "()": no such variable}}
+catch {unset a}
+test parseOld-5.13 {array variable substitution} {
+ catch {unset a}
+ set long {This is a very long variable, long enough to cause storage \
+ allocation to occur in Tcl_ParseVar. If that storage isn't getting \
+ freed up correctly, then a core leak will occur when this test is \
+ run. This text is probably beginning to sound like drivel, but I've \
+ run out of things to say and I need more characters still.}
+ set a($long) 777
+ set b $a($long)
+ list $b [array names a]
+} {777 {{This is a very long variable, long enough to cause storage \
+ allocation to occur in Tcl_ParseVar. If that storage isn't getting \
+ freed up correctly, then a core leak will occur when this test is \
+ run. This text is probably beginning to sound like drivel, but I've \
+ run out of things to say and I need more characters still.}}}
+test parseOld-5.14 {array variable substitution} {
+ catch {unset a}; catch {unset b}; catch {unset a1}
+ set a1(22) foo
+ set a(foo) bar
+ set b $a($a1(22))
+ set b
+} bar
+catch {unset a}; catch {unset a1}
+
+test parseOld-7.1 {backslash substitution} {
+ set a "\a\c\n\]\}"
+ string length $a
+} 5
+test parseOld-7.2 {backslash substitution} {
+ set a {\a\c\n\]\}}
+ string length $a
+} 10
+test parseOld-7.3 {backslash substitution} {
+ set a "abc\
+def"
+ set a
+} {abc def}
+test parseOld-7.4 {backslash substitution} {
+ set a {abc\
+def}
+ set a
+} {abc def}
+test parseOld-7.5 {backslash substitution} {
+ set msg {}
+ set a xxx
+ set error [catch {if {24 < \
+ 35} {set a 22} {set \
+ a 33}} msg]
+ list $error $msg $a
+} {0 22 22}
+test parseOld-7.6 {backslash substitution} {
+ eval "concat abc\\"
+} "abc\\"
+test parseOld-7.7 {backslash substitution} {
+ eval "concat \\\na"
+} "a"
+test parseOld-7.8 {backslash substitution} {
+ eval "concat x\\\n a"
+} "x a"
+test parseOld-7.9 {backslash substitution} {
+ eval "concat \\x"
+} "x"
+test parseOld-7.10 {backslash substitution} {
+ eval "list a b\\\nc d"
+} {a b c d}
+test parseOld-7.11 {backslash substitution} {
+ eval "list a \"b c\"\\\nd e"
+} {a {b c} d e}
+test parseOld-7.12 {backslash substitution} {
+ list \ua2
+} [bytestring "\xc2\xa2"]
+test parseOld-7.13 {backslash substitution} {
+ list \u4e21
+} [bytestring "\xe4\xb8\xa1"]
+test parseOld-7.14 {backslash substitution} {
+ list \u4e2k
+} [bytestring "\xd3\xa2k"]
+
+# Semi-colon.
+
+test parseOld-8.1 {semi-colons} {
+ set b 0
+ getArgs a;set b 2
+ set argv
+} a
+test parseOld-8.2 {semi-colons} {
+ set b 0
+ getArgs a;set b 2
+ set b
+} 2
+test parseOld-8.3 {semi-colons} {
+ getArgs a b ; set b 1
+ set argv
+} {a b}
+test parseOld-8.4 {semi-colons} {
+ getArgs a b ; set b 1
+ set b
+} 1
+
+# The following checks are to ensure that the interpreter's result
+# gets re-initialized by Tcl_Eval in all the right places.
+
+test parseOld-9.1 {result initialization} {concat abc} abc
+test parseOld-9.2 {result initialization} {concat abc; proc foo {} {}} {}
+test parseOld-9.3 {result initialization} {concat abc; proc foo {} $a} {}
+test parseOld-9.4 {result initialization} {proc foo {} [concat abc]} {}
+test parseOld-9.5 {result initialization} {concat abc; } abc
+test parseOld-9.6 {result initialization} {
+ eval {
+ concat abc
+}} abc
+test parseOld-9.7 {result initialization} {} {}
+test parseOld-9.8 {result initialization} {concat abc; ; ;} abc
+
+# Syntax errors.
+
+test parseOld-10.1 {syntax errors} {catch "set a \{bcd" msg} 1
+test parseOld-10.2 {syntax errors} {
+ catch "set a \{bcd" msg
+ set msg
+} {missing close-brace}
+test parseOld-10.3 {syntax errors} {catch {set a "bcd} msg} 1
+test parseOld-10.4 {syntax errors} {
+ catch {set a "bcd} msg
+ set msg
+} {missing "}
+#" Emacs formatting >:^(
+test parseOld-10.5 {syntax errors} {catch {set a "bcd"xy} msg} 1
+test parseOld-10.6 {syntax errors} {
+ catch {set a "bcd"xy} msg
+ set msg
+} {extra characters after close-quote}
+test parseOld-10.7 {syntax errors} {catch "set a {bcd}xy" msg} 1
+test parseOld-10.8 {syntax errors} {
+ catch "set a {bcd}xy" msg
+ set msg
+} {extra characters after close-brace}
+test parseOld-10.9 {syntax errors} {catch {set a [format abc} msg} 1
+test parseOld-10.10 {syntax errors} {
+ catch {set a [format abc} msg
+ set msg
+} {missing close-bracket}
+test parseOld-10.11 {syntax errors} {catch gorp-a-lot msg} 1
+test parseOld-10.12 {syntax errors} {
+ catch gorp-a-lot msg
+ set msg
+} {invalid command name "gorp-a-lot"}
+test parseOld-10.13 {syntax errors} {
+ set a [concat {a}\
+ {b}]
+ set a
+} {a b}
+
+# The next test will fail on the Mac, 'cause the MSL uses a fixed sized
+# buffer for %d conversions (LAME!). I won't leave the test out, however,
+# since MetroWerks may some day fix this.
+
+test parseOld-10.14 {syntax errors} {
+ list [catch {eval \$x[format "%01000d" 0](} msg] $msg $::errorInfo
+} {1 {missing )} {missing )
+ while executing
+"$x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000..."
+ ("eval" body line 1)
+ invoked from within
+"eval \$x[format "%01000d" 0]("}}
+test parseOld-10.15 {syntax errors, missplaced braces} {
+ catch {
+ proc misplaced_end_brace {} {
+ set what foo
+ set when [expr ${what}size - [set off$what]}]
+ } msg
+ set msg
+} {extra characters after close-brace}
+test parseOld-10.16 {syntax errors, missplaced braces} {
+ catch {
+ set a {
+ set what foo
+ set when [expr ${what}size - [set off$what]}]
+ } msg
+ set msg
+} {extra characters after close-brace}
+test parseOld-10.17 {syntax errors, unusual spacing} {
+ list [catch {return [ [1]]} msg] $msg
+} {1 {invalid command name "1"}}
+# Long values (stressing storage management)
+
+set a {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH}
+
+test parseOld-11.1 {long values} {
+ string length $a
+} 214
+test parseOld-11.2 {long values} {
+ llength $a
+} 43
+test parseOld-11.3 {long values} {
+ set b "1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH"
+ set b
+} $a
+test parseOld-11.4 {long values} {
+ set b "$a"
+ set b
+} $a
+test parseOld-11.5 {long values} {
+ set b [set a]
+ set b
+} $a
+test parseOld-11.6 {long values} {
+ set b [concat 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH]
+ string length $b
+} 214
+test parseOld-11.7 {long values} {
+ set b [concat 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH]
+ llength $b
+} 43
+test parseOld-11.8 {long values} {
+ set b
+} $a
+test parseOld-11.9 {long values} {
+ set a [concat 0000 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH IIII JJJJ KKKK LLLL MMMM NNNN OOOO PPPP QQQQ RRRR SSSS TTTT UUUU VVVV WWWW XXXX YYYY ZZZZ]
+ llength $a
+} 62
+set i 0
+foreach j [concat 0000 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH IIII JJJJ KKKK LLLL MMMM NNNN OOOO PPPP QQQQ RRRR SSSS TTTT UUUU VVVV WWWW XXXX YYYY ZZZZ] {
+ set test [string index 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ $i]
+ set test $test$test$test$test
+ test parseOld-11.10-[incr i] {long values} {
+ set j
+ } $test
+}
+test parseOld-11.11 {test buffer overflow in backslashes in braces} {
+ expr {"a" == {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101}}
+} 0
+
+test parseOld-12.1 {comments} {
+ set a old
+ eval { # set a new}
+ set a
+} {old}
+test parseOld-12.2 {comments} {
+ set a old
+ eval " # set a new\nset a new"
+ set a
+} {new}
+test parseOld-12.3 {comments} {
+ set a old
+ eval " # set a new\\\nset a new"
+ set a
+} {old}
+test parseOld-12.4 {comments} {
+ set a old
+ eval " # set a new\\\\\nset a new"
+ set a
+} {new}
+
+test parseOld-13.1 {comments at the end of a bracketed script} {
+ set x "[
+expr 1+1
+# skip this!
+]"
+} {2}
+
+test parseOld-14.1 {TclWordEnd procedure} {testwordend} {
+ testwordend " \n abc"
+} {c}
+test parseOld-14.2 {TclWordEnd procedure} {testwordend} {
+ testwordend " \\\n"
+} {}
+test parseOld-14.3 {TclWordEnd procedure} {testwordend} {
+ testwordend " \\\n "
+} { }
+test parseOld-14.4 {TclWordEnd procedure} {testwordend} {
+ testwordend {"abc"}
+} {"}
+#" Emacs formatting :^(
+test parseOld-14.5 {TclWordEnd procedure} {testwordend} {
+ testwordend {{xyz}}
+} \}
+test parseOld-14.6 {TclWordEnd procedure} {testwordend} {
+ testwordend {{a{}b{}\}} xyz}
+} "\} xyz"
+test parseOld-14.7 {TclWordEnd procedure} {testwordend} {
+ testwordend {abc[this is a]def ghi}
+} {f ghi}
+test parseOld-14.8 {TclWordEnd procedure} {testwordend} {
+ testwordend "puts\\\n\n "
+} "s\\\n\n "
+test parseOld-14.9 {TclWordEnd procedure} {testwordend} {
+ testwordend "puts\\\n "
+} "s\\\n "
+test parseOld-14.10 {TclWordEnd procedure} {testwordend} {
+ testwordend "puts\\\n xyz"
+} "s\\\n xyz"
+test parseOld-14.11 {TclWordEnd procedure} {testwordend} {
+ testwordend {a$x.$y(a long index) foo}
+} ") foo"
+test parseOld-14.12 {TclWordEnd procedure} {testwordend} {
+ testwordend {abc; def}
+} {; def}
+test parseOld-14.13 {TclWordEnd procedure} {testwordend} {
+ testwordend {abc def}
+} {c def}
+test parseOld-14.14 {TclWordEnd procedure} {testwordend} {
+ testwordend {abc def}
+} {c def}
+test parseOld-14.15 {TclWordEnd procedure} {testwordend} {
+ testwordend "abc\ndef"
+} "c\ndef"
+test parseOld-14.16 {TclWordEnd procedure} {testwordend} {
+ testwordend "abc"
+} {c}
+test parseOld-14.17 {TclWordEnd procedure} {testwordend} {
+ testwordend "a\000bc"
+} {c}
+test parseOld-14.18 {TclWordEnd procedure} {testwordend} {
+ testwordend \[a\000\]
+} {]}
+test parseOld-14.19 {TclWordEnd procedure} {testwordend} {
+ testwordend \"a\000\"
+} {"}
+#" Emacs formatting :^(
+test parseOld-14.20 {TclWordEnd procedure} {testwordend} {
+ testwordend a{\000}b
+} {b}
+test parseOld-14.21 {TclWordEnd procedure} {testwordend} {
+ testwordend " \000b"
+} {b}
+
+test parseOld-15.1 {TclScriptEnd procedure} {
+ info complete {puts [
+ expr 1+1
+ #this is a comment ]}
+} {0}
+test parseOld-15.2 {TclScriptEnd procedure} {
+ info complete "abc\\\n"
+} {0}
+test parseOld-15.3 {TclScriptEnd procedure} {
+ info complete "abc\\\\\n"
+} {1}
+test parseOld-15.4 {TclScriptEnd procedure} {
+ info complete "xyz \[abc \{abc\]"
+} {0}
+test parseOld-15.5 {TclScriptEnd procedure} {
+ info complete "xyz \[abc"
+} {0}
+
+# cleanup
+set argv $savedArgv
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/pid.test b/pkgs/msgcat/tests/pid.test
new file mode 100644
index 0000000..d21dbaa
--- /dev/null
+++ b/pkgs/msgcat/tests/pid.test
@@ -0,0 +1,57 @@
+# Commands covered: pid
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1995 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint pidDefined [llength [info commands pid]]
+
+test pid-1.1 {pid command} pidDefined {
+ regexp {(^[0-9]+$)|(^0x[0-9a-fA-F]+$)} [pid]
+} 1
+test pid-1.2 {pid command} -constraints {unixOrPc unixExecs pidDefined} -setup {
+ set path(test1) [makeFile {} test1]
+ file delete $path(test1)
+} -body {
+ set f [open |[list echo foo | cat >$path(test1)] w]
+ set pids [pid $f]
+ close $f
+ list [llength $pids] [regexp {^[0-9]+$} [lindex $pids 0]] \
+ [regexp {^[0-9]+$} [lindex $pids 1]] \
+ [expr {[lindex $pids 0] == [lindex $pids 1]}]
+} -cleanup {
+ removeFile test1
+} -result {2 1 1 0}
+test pid-1.3 {pid command} -constraints pidDefined -setup {
+ set path(test1) [makeFile {} test1]
+ file delete $path(test1)
+} -body {
+ set f [open $path(test1) w]
+ set pids [pid $f]
+ close $f
+ set pids
+} -cleanup {
+ removeFile test1
+} -result {}
+test pid-1.4 {pid command} pidDefined {
+ list [catch {pid a b} msg] $msg
+} {1 {wrong # args: should be "pid ?channelId?"}}
+test pid-1.5 {pid command} pidDefined {
+ list [catch {pid gorp} msg] $msg
+} {1 {can not find channel named "gorp"}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/pkgMkIndex.test b/pkgs/msgcat/tests/pkgMkIndex.test
new file mode 100644
index 0000000..0fe394e
--- /dev/null
+++ b/pkgs/msgcat/tests/pkgMkIndex.test
@@ -0,0 +1,700 @@
+# This file contains tests for the pkg_mkIndex command.
+# Note that the tests are limited to Tcl scripts only, there are no shared
+# libraries against which to test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# All rights reserved.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+set fullPkgPath [makeDirectory pkg]
+
+namespace eval pkgtest {
+ # Namespace for procs we can discard
+}
+
+# pkgtest::parseArgs --
+#
+# Parse an argument list.
+#
+# Arguments:
+# <flags> (optional) arguments starting with a dash are collected as
+# options to pkg_mkIndex and passed to pkg_mkIndex.
+# dirPath the directory to index
+# pattern0 pattern to index
+# ... pattern to index
+# patternN pattern to index
+#
+# Results:
+# Returns a three element list:
+# 0: the options
+# 1: the directory to index
+# 2: the patterns list
+
+proc pkgtest::parseArgs { args } {
+ set options ""
+
+ set argc [llength $args]
+ for {set iarg 0} {$iarg < $argc} {incr iarg} {
+ set a [lindex $args $iarg]
+ if {[regexp {^-} $a]} {
+ lappend options $a
+ if {[string compare -load $a] == 0} {
+ incr iarg
+ lappend options [lindex $args $iarg]
+ }
+ } else {
+ break
+ }
+ }
+
+ set dirPath [lindex $args $iarg]
+ incr iarg
+ set patternList [lrange $args $iarg end]
+
+ return [list $options $dirPath $patternList]
+}
+
+# pkgtest::parseIndex --
+#
+# Loads a pkgIndex.tcl file, records all the calls to "package ifneeded".
+#
+# Arguments:
+# filePath path to the pkgIndex.tcl file.
+#
+# Results:
+# Returns a list, in "array set/get" format, where the keys are the package
+# name and version (in the form "$name:$version"), and the values the rest
+# of the command line.
+
+proc pkgtest::parseIndex { filePath } {
+ # create a slave interpreter, where we override "package ifneeded"
+
+ set slave [interp create]
+ if {[catch {
+ $slave eval {
+ rename package package_original
+ proc package { args } {
+ if {[string compare [lindex $args 0] ifneeded] == 0} {
+ set pkg [lindex $args 1]
+ set ver [lindex $args 2]
+ set ::PKGS($pkg:$ver) [lindex $args 3]
+ } else {
+ return [package_original {*}$args]
+ }
+ }
+ array set ::PKGS {}
+ }
+
+ set dir [file dirname $filePath]
+ $slave eval {set curdir [pwd]}
+ $slave eval [list cd $dir]
+ $slave eval [list set dir $dir]
+ $slave eval [list source [file tail $filePath]]
+ $slave eval {cd $curdir}
+
+ # Create the list in sorted order, so that we don't get spurious
+ # errors because the order has changed.
+
+ array set P {}
+ foreach {k v} [$slave eval {array get ::PKGS}] {
+ set P($k) $v
+ }
+
+ set PKGS ""
+ foreach k [lsort [array names P]] {
+ lappend PKGS $k $P($k)
+ }
+ } err]} {
+ set ei $::errorInfo
+ set ec $::errorCode
+
+ catch {interp delete $slave}
+
+ error $ei $ec
+ }
+
+ interp delete $slave
+
+ return $PKGS
+}
+
+# pkgtest::createIndex --
+#
+# Runs pkg_mkIndex for the given directory and set of patterns. This
+# procedure deletes any pkgIndex.tcl file in the target directory, then runs
+# pkg_mkIndex.
+#
+# Arguments:
+# <flags> (optional) arguments starting with a dash are collected as
+# options to pkg_mkIndex and passed to pkg_mkIndex.
+# dirPath the directory to index
+# pattern0 pattern to index
+# ... pattern to index
+# patternN pattern to index
+#
+# Results:
+# Returns a two element list:
+# 0: 1 if the procedure encountered an error, 0 otherwise.
+# 1: the error result if element 0 was 1
+
+proc pkgtest::createIndex { args } {
+ set parsed [parseArgs {*}$args]
+ set options [lindex $parsed 0]
+ set dirPath [lindex $parsed 1]
+ set patternList [lindex $parsed 2]
+
+ file mkdir $dirPath
+
+ if {[catch {
+ file delete [file join $dirPath pkgIndex.tcl]
+ pkg_mkIndex {*}$options $dirPath {*}$patternList
+ } err]} {
+ return [list 1 $err]
+ }
+
+ return [list 0 {}]
+}
+
+# makePkgList --
+#
+# Takes the output of a pkgtest::parseIndex call, filters it and returns a
+# cleaned up list of packages and their actions.
+#
+# Arguments:
+# inList output from a pkgtest::parseIndex.
+#
+# Results:
+# Returns a list of two element lists:
+# 0: the name:version
+# 1: a list describing the package.
+# For tclPkgSetup packages it consists of:
+# 0: the keyword tclPkgSetup
+# 1: the first file to source, with its exported procedures
+# 2: the second file ...
+# N: the N-1st file ...
+
+proc makePkgList { inList } {
+ set pkgList ""
+
+ foreach {k v} $inList {
+ switch [lindex $v 0] {
+ tclPkgSetup {
+ set l tclPkgSetup
+ foreach s [lindex $v 4] {
+ lappend l $s
+ }
+ }
+ source {
+ set l $v
+ }
+ default {
+ error "can't handle $k $v"
+ }
+ }
+
+ lappend pkgList [list $k $l]
+ }
+
+ return $pkgList
+}
+
+# pkgtest::runIndex --
+#
+# Runs pkg_mkIndex, parses the generated index file.
+#
+# Arguments:
+# <flags> (optional) arguments starting with a dash are collected as
+# options to pkg_mkIndex and passed to pkg_mkIndex.
+# dirPath the directory to index
+# pattern0 pattern to index
+# ... pattern to index
+# patternN pattern to index
+#
+# Results:
+# Returns a two element list:
+# 0: 1 if the procedure encountered an error, 0 otherwise.
+# 1: if no error, this is the parsed generated index file, in the format
+# returned by pkgtest::parseIndex. If error, this is the error result.
+
+proc pkgtest::runCreatedIndex {rv args} {
+ if {[lindex $rv 0] == 0} {
+ set parsed [parseArgs {*}$args]
+ set dirPath [lindex $parsed 1]
+ set idxFile [file join $dirPath pkgIndex.tcl]
+
+ if {[catch {
+ set result [list 0 [makePkgList [parseIndex $idxFile]]]
+ } err]} {
+ set result [list 1 $err]
+ }
+ file delete $idxFile
+ } else {
+ set result $rv
+ }
+
+ return $result
+}
+proc pkgtest::runIndex { args } {
+ set rv [createIndex {*}$args]
+ return [runCreatedIndex $rv {*}$args]
+}
+
+# If there is no match to the patterns, make sure the directory hasn't changed
+# on us
+
+test pkgMkIndex-1.1 {nothing matches pattern - current dir is the same} {
+ list [pkgtest::runIndex -lazy $fullPkgPath nomatch.tcl] [pwd]
+} [list {1 {no files matched glob pattern "nomatch.tcl"}} [pwd]]
+
+makeFile {
+# This is a simple package, just to check basic functionality.
+package provide simple 1.0
+namespace eval simple {
+ namespace export lower upper
+}
+proc simple::lower { stg } {
+ return [string tolower $stg]
+}
+proc simple::upper { stg } {
+ return [string toupper $stg]
+}
+} [file join pkg simple.tcl]
+
+test pkgMkIndex-2.1 {simple package} {
+ pkgtest::runIndex -lazy $fullPkgPath simple.tcl
+} {0 {{simple:1.0 {tclPkgSetup {simple.tcl source {::simple::lower ::simple::upper}}}}}}
+
+test pkgMkIndex-2.2 {simple package - use -direct} {
+ pkgtest::runIndex -direct $fullPkgPath simple.tcl
+} "0 {{simple:1.0 {[list source [file join $fullPkgPath simple.tcl]]}}}"
+
+test pkgMkIndex-2.3 {simple package - direct loading is default} {
+ pkgtest::runIndex $fullPkgPath simple.tcl
+} "0 {{simple:1.0 {[list source [file join $fullPkgPath simple.tcl]]}}}"
+
+test pkgMkIndex-2.4 {simple package - use -verbose} -body {
+ pkgtest::runIndex -verbose $fullPkgPath simple.tcl
+} -result "0 {{simple:1.0 {[list source [file join $fullPkgPath simple.tcl]]}}}" \
+ -errorOutput {successful sourcing of simple.tcl
+packages provided were {simple 1.0}
+processed simple.tcl
+}
+
+removeFile [file join pkg simple.tcl]
+
+makeFile {
+# Contains global symbols, used to check that they don't have a leading ::
+package provide global 1.0
+proc global_lower { stg } {
+ return [string tolower $stg]
+}
+proc global_upper { stg } {
+ return [string toupper $stg]
+}
+} [file join pkg global.tcl]
+
+test pkgMkIndex-3.1 {simple package with global symbols} {
+ pkgtest::runIndex -lazy $fullPkgPath global.tcl
+} {0 {{global:1.0 {tclPkgSetup {global.tcl source {global_lower global_upper}}}}}}
+
+removeFile [file join pkg global.tcl]
+
+makeFile {
+# This package is required by pkg1.
+# This package is split into two files, to test packages that are split over
+# multiple files.
+package provide pkg2 1.0
+namespace eval pkg2 {
+ namespace export p2-1
+}
+proc pkg2::p2-1 { num } {
+ return [expr $num * 2]
+}
+} [file join pkg pkg2_a.tcl]
+
+makeFile {
+# This package is required by pkg1.
+# This package is split into two files, to test packages that are split over
+# multiple files.
+package provide pkg2 1.0
+namespace eval pkg2 {
+ namespace export p2-2
+}
+proc pkg2::p2-2 { num } {
+ return [expr $num * 3]
+}
+} [file join pkg pkg2_b.tcl]
+
+test pkgMkIndex-4.1 {split package} {
+ pkgtest::runIndex -lazy $fullPkgPath pkg2_a.tcl pkg2_b.tcl
+} {0 {{pkg2:1.0 {tclPkgSetup {pkg2_a.tcl source ::pkg2::p2-1} {pkg2_b.tcl source ::pkg2::p2-2}}}}}
+
+test pkgMkIndex-4.2 {split package - direct loading} {
+ pkgtest::runIndex -direct $fullPkgPath pkg2_a.tcl pkg2_b.tcl
+} "0 {{pkg2:1.0 {[list source [file join $fullPkgPath pkg2_a.tcl]]
+[list source [file join $fullPkgPath pkg2_b.tcl]]}}}"
+
+# Add the direct1 directory to auto_path, so that the direct1 package can be
+# found.
+set direct1 [makeDirectory direct1]
+lappend auto_path $direct1
+makeFile {
+# This is referenced by pkgIndex.tcl as a -direct script.
+package provide direct1 1.0
+namespace eval direct1 {
+ namespace export pd1 pd2
+}
+proc direct1::pd1 { stg } {
+ return [string tolower $stg]
+}
+proc direct1::pd2 { stg } {
+ return [string toupper $stg]
+}
+} [file join direct1 direct1.tcl]
+pkg_mkIndex -direct $direct1 direct1.tcl
+
+makeFile {
+# Does a package require of direct1, whose pkgIndex.tcl entry is created
+# above with option -direct. This tests that pkg_mkIndex can handle code
+# that is sourced in pkgIndex.tcl files.
+package require direct1
+package provide std 1.0
+namespace eval std {
+ namespace export p1 p2
+}
+proc std::p1 { stg } {
+ return [string tolower $stg]
+}
+proc std::p2 { stg } {
+ return [string toupper $stg]
+}
+} [file join pkg std.tcl]
+
+test pkgMkIndex-5.1 {requires -direct package} {
+ pkgtest::runIndex -lazy $fullPkgPath std.tcl
+} {0 {{std:1.0 {tclPkgSetup {std.tcl source {::std::p1 ::std::p2}}}}}}
+
+removeFile [file join direct1 direct1.tcl]
+file delete [file join $direct1 pkgIndex.tcl]
+removeDirectory direct1
+removeFile [file join pkg std.tcl]
+
+makeFile {
+# This package requires pkg3, but it does not use any of pkg3's procs in the
+# code that is executed by the file (i.e. references to pkg3's procs are in
+# the proc bodies only).
+package require pkg3 1.0
+package provide pkg1 1.0
+namespace eval pkg1 {
+ namespace export p1-1 p1-2
+}
+proc pkg1::p1-1 { num } {
+ return [pkg3::p3-1 $num]
+}
+proc pkg1::p1-2 { num } {
+ return [pkg3::p3-2 $num]
+}
+} [file join pkg pkg1.tcl]
+
+makeFile {
+package provide pkg3 1.0
+namespace eval pkg3 {
+ namespace export p3-1 p3-2
+}
+proc pkg3::p3-1 { num } {
+ return {[expr $num * 2]}
+}
+proc pkg3::p3-2 { num } {
+ return {[expr $num * 3]}
+}
+} [file join pkg pkg3.tcl]
+
+test pkgMkIndex-6.1 {pkg1 requires pkg3} {
+ pkgtest::runIndex -lazy $fullPkgPath pkg1.tcl pkg3.tcl
+} {0 {{pkg1:1.0 {tclPkgSetup {pkg1.tcl source {::pkg1::p1-1 ::pkg1::p1-2}}}} {pkg3:1.0 {tclPkgSetup {pkg3.tcl source {::pkg3::p3-1 ::pkg3::p3-2}}}}}}
+
+test pkgMkIndex-6.2 {pkg1 requires pkg3 - use -direct} {
+ pkgtest::runIndex -direct $fullPkgPath pkg1.tcl pkg3.tcl
+} "0 {{pkg1:1.0 {[list source [file join $fullPkgPath pkg1.tcl]]}} {pkg3:1.0 {[list source [file join $fullPkgPath pkg3.tcl]]}}}"
+
+removeFile [file join pkg pkg1.tcl]
+
+makeFile {
+# This package requires pkg3, and it calls a pkg3 proc in the code that is
+# executed by the file
+package require pkg3 1.0
+package provide pkg4 1.0
+namespace eval pkg4 {
+ namespace export p4-1 p4-2
+ variable m2 [pkg3::p3-1 10]
+}
+proc pkg4::p4-1 { num } {
+ variable m2
+ return [expr {$m2 * $num}]
+}
+proc pkg4::p4-2 { num } {
+ return [pkg3::p3-2 $num]
+}
+} [file join pkg pkg4.tcl]
+
+test pkgMkIndex-7.1 {pkg4 uses pkg3} {
+ pkgtest::runIndex -lazy $fullPkgPath pkg4.tcl pkg3.tcl
+} {0 {{pkg3:1.0 {tclPkgSetup {pkg3.tcl source {::pkg3::p3-1 ::pkg3::p3-2}}}} {pkg4:1.0 {tclPkgSetup {pkg4.tcl source {::pkg4::p4-1 ::pkg4::p4-2}}}}}}
+
+test pkgMkIndex-7.2 {pkg4 uses pkg3 - use -direct} {
+ pkgtest::runIndex -direct $fullPkgPath pkg4.tcl pkg3.tcl
+} "0 {{pkg3:1.0 {[list source [file join $fullPkgPath pkg3.tcl]]}} {pkg4:1.0 {[list source [file join $fullPkgPath pkg4.tcl]]}}}"
+
+removeFile [file join pkg pkg4.tcl]
+removeFile [file join pkg pkg3.tcl]
+
+makeFile {
+# This package requires pkg2, and it calls a pkg2 proc in the code that is
+# executed by the file. Pkg2 is a split package.
+package require pkg2 1.0
+package provide pkg5 1.0
+namespace eval pkg5 {
+ namespace export p5-1 p5-2
+ variable m2 [pkg2::p2-1 10]
+ variable m3 [pkg2::p2-2 10]
+}
+proc pkg5::p5-1 { num } {
+ variable m2
+ return [expr {$m2 * $num}]
+}
+proc pkg5::p5-2 { num } {
+ variable m2
+ return [expr {$m2 * $num}]
+}
+} [file join pkg pkg5.tcl]
+
+test pkgMkIndex-8.1 {pkg5 uses pkg2} {
+ pkgtest::runIndex -lazy $fullPkgPath pkg5.tcl pkg2_a.tcl pkg2_b.tcl
+} {0 {{pkg2:1.0 {tclPkgSetup {pkg2_a.tcl source ::pkg2::p2-1} {pkg2_b.tcl source ::pkg2::p2-2}}} {pkg5:1.0 {tclPkgSetup {pkg5.tcl source {::pkg5::p5-1 ::pkg5::p5-2}}}}}}
+
+test pkgMkIndex-8.2 {pkg5 uses pkg2 - use -direct} {
+ pkgtest::runIndex -direct $fullPkgPath pkg5.tcl pkg2_a.tcl pkg2_b.tcl
+} "0 {{pkg2:1.0 {[list source [file join $fullPkgPath pkg2_a.tcl]]
+[list source [file join $fullPkgPath pkg2_b.tcl]]}} {pkg5:1.0 {[list source [file join $fullPkgPath pkg5.tcl]]}}}"
+
+removeFile [file join pkg pkg5.tcl]
+removeFile [file join pkg pkg2_a.tcl]
+removeFile [file join pkg pkg2_b.tcl]
+
+makeFile {
+# This package requires circ2, and circ2 requires circ3, which in turn
+# requires circ1. In case of cirularities, pkg_mkIndex should give up when
+# it gets stuck.
+package require circ2 1.0
+package provide circ1 1.0
+namespace eval circ1 {
+ namespace export c1-1 c1-2 c1-3 c1-4
+}
+proc circ1::c1-1 { num } {
+ return [circ2::c2-1 $num]
+}
+proc circ1::c1-2 { num } {
+ return [circ2::c2-2 $num]
+}
+proc circ1::c1-3 {} {
+ return 10
+}
+proc circ1::c1-4 {} {
+ return 20
+}
+} [file join pkg circ1.tcl]
+
+makeFile {
+# This package is required by circ1, and requires circ3. Circ3, in turn,
+# requires circ1 to give us a circularity.
+package require circ3 1.0
+package provide circ2 1.0
+namespace eval circ2 {
+ namespace export c2-1 c2-2
+}
+proc circ2::c2-1 { num } {
+ return [expr $num * [circ3::c3-1]]
+}
+proc circ2::c2-2 { num } {
+ return [expr $num * [circ3::c3-2]]
+}
+} [file join pkg circ2.tcl]
+
+makeFile {
+# This package is required by circ2, and in turn requires circ1. This closes
+# the circularity.
+package require circ1 1.0
+package provide circ3 1.0
+namespace eval circ3 {
+ namespace export c3-1 c3-4
+}
+proc circ3::c3-1 {} {
+ return [circ1::c1-3]
+}
+proc circ3::c3-2 {} {
+ return [circ1::c1-4]
+}
+} [file join pkg circ3.tcl]
+
+test pkgMkIndex-9.1 {circular packages} {
+ pkgtest::runIndex -lazy $fullPkgPath circ1.tcl circ2.tcl circ3.tcl
+} {0 {{circ1:1.0 {tclPkgSetup {circ1.tcl source {::circ1::c1-1 ::circ1::c1-2 ::circ1::c1-3 ::circ1::c1-4}}}} {circ2:1.0 {tclPkgSetup {circ2.tcl source {::circ2::c2-1 ::circ2::c2-2}}}} {circ3:1.0 {tclPkgSetup {circ3.tcl source ::circ3::c3-1}}}}}
+
+removeFile [file join pkg circ1.tcl]
+removeFile [file join pkg circ2.tcl]
+removeFile [file join pkg circ3.tcl]
+
+# Some tests require the existence of one of the DLLs in the dltest directory
+set x [file join [file dirname [info nameofexecutable]] dltest \
+ pkga[info sharedlibextension]]
+set dll "[file tail $x]Required"
+testConstraint $dll [file exists $x]
+
+if {[testConstraint $dll]} {
+ makeFile {
+# This package provides Pkga, which is also provided by a DLL.
+package provide Pkga 1.0
+proc pkga_neq { x } {
+ return [expr {! [pkgq_eq $x]}]
+}
+} [file join pkg pkga.tcl]
+ file copy -force $x $fullPkgPath
+}
+testConstraint exec [llength [info commands ::exec]]
+
+test pkgMkIndex-10.1 {package in DLL and script} [list exec $dll] {
+ # Do all [load]ing of shared libraries in another process, so we can
+ # delete the file and not get stuck because we're holding a reference to
+ # it.
+ set cmd [list pkg_mkIndex -lazy $fullPkgPath [file tail $x] pkga.tcl]
+ exec [interpreter] << $cmd
+ pkgtest::runCreatedIndex {0 {}} -lazy $fullPkgPath pkga[info sharedlibextension] pkga.tcl
+} "0 {{Pkga:1.0 {tclPkgSetup {pkga[info sharedlibextension] load {pkga_eq pkga_quote}} {pkga.tcl source pkga_neq}}}}"
+test pkgMkIndex-10.2 {package in DLL hidden by -load} [list exec $dll] {
+ # Do all [load]ing of shared libraries in another process, so we can
+ # delete the file and not get stuck because we're holding a reference to
+ # it.
+ #
+ # This test depends on context from prior test, so repeat it.
+ set script \
+ "[list pkg_mkIndex -lazy $fullPkgPath [file tail $x] pkga.tcl]"
+ append script \n \
+ "[list pkg_mkIndex -lazy -load Pkg* $fullPkgPath [file tail $x]]"
+ exec [interpreter] << $script
+ pkgtest::runCreatedIndex {0 {}} -lazy -load Pkg* -- $fullPkgPath pkga[info sharedlibextension]
+} {0 {}}
+
+if {[testConstraint $dll]} {
+ file delete -force [file join $fullPkgPath [file tail $x]]
+ removeFile [file join pkg pkga.tcl]
+}
+
+# Tolerate "namespace import" at the global scope
+
+makeFile {
+package provide fubar 1.0
+namespace eval ::fubar:: {
+ #
+ # export only public functions.
+ #
+ namespace export {[a-z]*}
+}
+proc ::fubar::foo {bar} {
+ puts "$bar"
+ return true
+}
+namespace import ::fubar::foo
+} [file join pkg import.tcl]
+
+test pkgMkIndex-11.1 {conflicting namespace imports} {
+ pkgtest::runIndex -lazy $fullPkgPath import.tcl
+} {0 {{fubar:1.0 {tclPkgSetup {import.tcl source ::fubar::foo}}}}}
+
+removeFile [file join pkg import.tcl]
+
+# Verify that the auto load list generated is correct even when there is a
+# proc name conflict between two namespaces (ie, ::foo::baz and ::bar::baz)
+
+makeFile {
+package provide football 1.0
+namespace eval ::pro:: {
+ #
+ # export only public functions.
+ #
+ namespace export {[a-z]*}
+}
+namespace eval ::college:: {
+ #
+ # export only public functions.
+ #
+ namespace export {[a-z]*}
+}
+proc ::pro::team {} {
+ puts "go packers!"
+ return true
+}
+proc ::college::team {} {
+ puts "go badgers!"
+ return true
+}
+} [file join pkg samename.tcl]
+
+test pkgMkIndex-12.1 {same name procs in different namespace} {
+ pkgtest::runIndex -lazy $fullPkgPath samename.tcl
+} {0 {{football:1.0 {tclPkgSetup {samename.tcl source {::college::team ::pro::team}}}}}}
+
+removeFile [file join pkg samename.tcl]
+
+# Proc names with embedded spaces are properly listed (ie, correct number of
+# braces) in result
+makeFile {
+package provide spacename 1.0
+proc {a b} {} {}
+proc {c d} {} {}
+} [file join pkg spacename.tcl]
+
+test pkgMkIndex-13.1 {proc names with embedded spaces} {
+ pkgtest::runIndex -lazy $fullPkgPath spacename.tcl
+} {0 {{spacename:1.0 {tclPkgSetup {spacename.tcl source {{a b} {c d}}}}}}}
+
+removeFile [file join pkg spacename.tcl]
+
+# Test the tcl::Pkg::CompareExtension helper function
+test pkgMkIndex-14.1 {tcl::Pkg::CompareExtension} {unix} {
+ tcl::Pkg::CompareExtension foo.so .so
+} 1
+test pkgMkIndex-14.2 {tcl::Pkg::CompareExtension} {unix} {
+ tcl::Pkg::CompareExtension foo.so.bar .so
+} 0
+test pkgMkIndex-14.3 {tcl::Pkg::CompareExtension} {unix} {
+ tcl::Pkg::CompareExtension foo.so.1 .so
+} 1
+test pkgMkIndex-14.4 {tcl::Pkg::CompareExtension} {unix} {
+ tcl::Pkg::CompareExtension foo.so.1.2 .so
+} 1
+test pkgMkIndex-14.5 {tcl::Pkg::CompareExtension} {unix} {
+ tcl::Pkg::CompareExtension foo .so
+} 0
+test pkgMkIndex-14.6 {tcl::Pkg::CompareExtension} {unix} {
+ tcl::Pkg::CompareExtension foo.so.1.2.bar .so
+} 0
+
+# cleanup
+
+removeDirectory pkg
+
+namespace delete pkgtest
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/platform.test b/pkgs/msgcat/tests/platform.test
new file mode 100644
index 0000000..92ca7ab
--- /dev/null
+++ b/pkgs/msgcat/tests/platform.test
@@ -0,0 +1,59 @@
+# The file tests the tcl_platform variable
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testCPUID [llength [info commands testcpuid]]
+
+test platform-1.1 {TclpSetVariables: tcl_platform} {
+ interp create i
+ i eval {catch {unset tcl_platform(debug)}}
+ i eval {catch {unset tcl_platform(threaded)}}
+ set result [i eval {lsort [array names tcl_platform]}]
+ interp delete i
+ set result
+} {byteOrder machine os osVersion pathSeparator platform pointerSize user wordSize}
+
+# Test assumes twos-complement arithmetic, which is true of virtually
+# everything these days. Note that this does *not* use wide(), and
+# this is intentional since that could make Tcl's numbers wider than
+# the machine-integer on some platforms...
+test platform-2.1 {tcl_platform(wordSize) indicates size of native word} {
+ set result [expr {int(1 << (8 * $tcl_platform(wordSize) - 1))}]
+ # Result must be the largest bit in a machine word, which this checks
+ # without assuming how wide the word really is
+ list [expr {$result < 0}] [expr {$result ^ int($result - 1)}]
+} {1 -1}
+
+# On Windows/UNIX, test that the CPU ID works
+
+test platform-3.1 {CPU ID on Windows/UNIX} \
+ -constraints testCPUID \
+ -body {
+ set cpudata [testcpuid 0]
+ binary format iii \
+ [lindex $cpudata 1] \
+ [lindex $cpudata 3] \
+ [lindex $cpudata 2]
+ } \
+ -match regexp \
+ -result {^(?:AuthenticAMD|CentaurHauls|CyrixInstead|GenuineIntel)$}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/proc-old.test b/pkgs/msgcat/tests/proc-old.test
new file mode 100644
index 0000000..e45cf5c
--- /dev/null
+++ b/pkgs/msgcat/tests/proc-old.test
@@ -0,0 +1,517 @@
+# Commands covered: proc, return, global
+#
+# This file, proc-old.test, includes the original set of tests for Tcl's
+# proc, return, and global commands. There is now a new file proc.test
+# that contains tests for the tclProc.c source file.
+#
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+catch {rename t1 ""}
+catch {rename foo ""}
+
+proc tproc {} {return a; return b}
+test proc-old-1.1 {simple procedure call and return} {tproc} a
+proc tproc x {
+ set x [expr $x+1]
+ return $x
+}
+test proc-old-1.2 {simple procedure call and return} {tproc 2} 3
+test proc-old-1.3 {simple procedure call and return} {
+ proc tproc {} {return foo}
+} {}
+test proc-old-1.4 {simple procedure call and return} {
+ proc tproc {} {return}
+ tproc
+} {}
+proc tproc1 {a} {incr a; return $a}
+proc tproc2 {a b} {incr a; return $a}
+test proc-old-1.5 {simple procedure call and return (2 procs with same body but different parameters)} {
+ list [tproc1 123] [tproc2 456 789]
+} {124 457}
+test proc-old-1.6 {simple procedure call and return (shared proc body string)} {
+ set x {}
+ proc tproc {} {} ;# body is shared with x
+ list [tproc] [append x foo]
+} {{} foo}
+
+test proc-old-2.1 {local and global variables} {
+ proc tproc x {
+ set x [expr $x+1]
+ return $x
+ }
+ set x 42
+ list [tproc 6] $x
+} {7 42}
+test proc-old-2.2 {local and global variables} {
+ proc tproc x {
+ set y [expr $x+1]
+ return $y
+ }
+ set y 18
+ list [tproc 6] $y
+} {7 18}
+test proc-old-2.3 {local and global variables} {
+ proc tproc x {
+ global y
+ set y [expr $x+1]
+ return $y
+ }
+ set y 189
+ list [tproc 6] $y
+} {7 7}
+test proc-old-2.4 {local and global variables} {
+ proc tproc x {
+ global y
+ return [expr $x+$y]
+ }
+ set y 189
+ list [tproc 6] $y
+} {195 189}
+catch {unset _undefined_}
+test proc-old-2.5 {local and global variables} {
+ proc tproc x {
+ global _undefined_
+ return $_undefined_
+ }
+ list [catch {tproc xxx} msg] $msg
+} {1 {can't read "_undefined_": no such variable}}
+test proc-old-2.6 {local and global variables} {
+ set a 114
+ set b 115
+ global a b
+ list $a $b
+} {114 115}
+
+proc do {cmd} {eval $cmd}
+test proc-old-3.1 {local and global arrays} {
+ catch {unset a}
+ set a(0) 22
+ list [catch {do {global a; set a(0)}} msg] $msg
+} {0 22}
+test proc-old-3.2 {local and global arrays} {
+ catch {unset a}
+ set a(x) 22
+ list [catch {do {global a; set a(x) newValue}} msg] $msg $a(x)
+} {0 newValue newValue}
+test proc-old-3.3 {local and global arrays} {
+ catch {unset a}
+ set a(x) 22
+ set a(y) 33
+ list [catch {do {global a; unset a(y)}; array names a} msg] $msg
+} {0 x}
+test proc-old-3.4 {local and global arrays} {
+ catch {unset a}
+ set a(x) 22
+ set a(y) 33
+ list [catch {do {global a; unset a; info exists a}} msg] $msg \
+ [info exists a]
+} {0 0 0}
+test proc-old-3.5 {local and global arrays} {
+ catch {unset a}
+ set a(x) 22
+ set a(y) 33
+ list [catch {do {global a; unset a(y); array names a}} msg] $msg
+} {0 x}
+catch {unset a}
+test proc-old-3.6 {local and global arrays} {
+ catch {unset a}
+ set a(x) 22
+ set a(y) 33
+ do {global a; do {global a; unset a}; set a(z) 22}
+ list [catch {array names a} msg] $msg
+} {0 z}
+test proc-old-3.7 {local and global arrays} {
+ proc t1 {args} {global info; set info 1}
+ catch {unset a}
+ set info {}
+ do {global a; trace var a(1) w t1}
+ set a(1) 44
+ set info
+} 1
+test proc-old-3.8 {local and global arrays} {
+ proc t1 {args} {global info; set info 1}
+ catch {unset a}
+ trace var a(1) w t1
+ set info {}
+ do {global a; trace vdelete a(1) w t1}
+ set a(1) 44
+ set info
+} {}
+test proc-old-3.9 {local and global arrays} {
+ proc t1 {args} {global info; set info 1}
+ catch {unset a}
+ trace var a(1) w t1
+ do {global a; trace vinfo a(1)}
+} {{w t1}}
+catch {unset a}
+
+test proc-old-30.1 {arguments and defaults} {
+ proc tproc {x y z} {
+ return [list $x $y $z]
+ }
+ tproc 11 12 13
+} {11 12 13}
+test proc-old-30.2 {arguments and defaults} {
+ proc tproc {x y z} {
+ return [list $x $y $z]
+ }
+ list [catch {tproc 11 12} msg] $msg
+} {1 {wrong # args: should be "tproc x y z"}}
+test proc-old-30.3 {arguments and defaults} {
+ proc tproc {x y z} {
+ return [list $x $y $z]
+ }
+ list [catch {tproc 11 12 13 14} msg] $msg
+} {1 {wrong # args: should be "tproc x y z"}}
+test proc-old-30.4 {arguments and defaults} {
+ proc tproc {x {y y-default} {z z-default}} {
+ return [list $x $y $z]
+ }
+ tproc 11 12 13
+} {11 12 13}
+test proc-old-30.5 {arguments and defaults} {
+ proc tproc {x {y y-default} {z z-default}} {
+ return [list $x $y $z]
+ }
+ tproc 11 12
+} {11 12 z-default}
+test proc-old-30.6 {arguments and defaults} {
+ proc tproc {x {y y-default} {z z-default}} {
+ return [list $x $y $z]
+ }
+ tproc 11
+} {11 y-default z-default}
+test proc-old-30.7 {arguments and defaults} {
+ proc tproc {x {y y-default} {z z-default}} {
+ return [list $x $y $z]
+ }
+ list [catch {tproc} msg] $msg
+} {1 {wrong # args: should be "tproc x ?y? ?z?"}}
+test proc-old-30.8 {arguments and defaults} {
+ list [catch {
+ proc tproc {x {y y-default} z} {
+ return [list $x $y $z]
+ }
+ tproc 2 3
+ } msg] $msg
+} {1 {wrong # args: should be "tproc x ?y? z"}}
+test proc-old-30.9 {arguments and defaults} {
+ proc tproc {x {y y-default} args} {
+ return [list $x $y $args]
+ }
+ tproc 2 3 4 5
+} {2 3 {4 5}}
+test proc-old-30.10 {arguments and defaults} {
+ proc tproc {x {y y-default} args} {
+ return [list $x $y $args]
+ }
+ tproc 2 3
+} {2 3 {}}
+test proc-old-30.11 {arguments and defaults} {
+ proc tproc {x {y y-default} args} {
+ return [list $x $y $args]
+ }
+ tproc 2
+} {2 y-default {}}
+test proc-old-30.12 {arguments and defaults} {
+ proc tproc {x {y y-default} args} {
+ return [list $x $y $args]
+ }
+ list [catch {tproc} msg] $msg
+} {1 {wrong # args: should be "tproc x ?y? ?arg ...?"}}
+
+test proc-old-4.1 {variable numbers of arguments} {
+ proc tproc args {return $args}
+ tproc
+} {}
+test proc-old-4.2 {variable numbers of arguments} {
+ proc tproc args {return $args}
+ tproc 1 2 3 4 5 6 7 8
+} {1 2 3 4 5 6 7 8}
+test proc-old-4.3 {variable numbers of arguments} {
+ proc tproc args {return $args}
+ tproc 1 {2 3} {4 {5 6} {{{7}}}} 8
+} {1 {2 3} {4 {5 6} {{{7}}}} 8}
+test proc-old-4.4 {variable numbers of arguments} {
+ proc tproc {x y args} {return $args}
+ tproc 1 2 3 4 5 6 7
+} {3 4 5 6 7}
+test proc-old-4.5 {variable numbers of arguments} {
+ proc tproc {x y args} {return $args}
+ tproc 1 2
+} {}
+test proc-old-4.6 {variable numbers of arguments} {
+ proc tproc {x missing args} {return $args}
+ list [catch {tproc 1} msg] $msg
+} {1 {wrong # args: should be "tproc x missing ?arg ...?"}}
+
+test proc-old-5.1 {error conditions} {
+ list [catch {proc} msg] $msg
+} {1 {wrong # args: should be "proc name args body"}}
+test proc-old-5.2 {error conditions} {
+ list [catch {proc tproc b} msg] $msg
+} {1 {wrong # args: should be "proc name args body"}}
+test proc-old-5.3 {error conditions} {
+ list [catch {proc tproc b c d e} msg] $msg
+} {1 {wrong # args: should be "proc name args body"}}
+test proc-old-5.4 {error conditions} {
+ list [catch {proc tproc \{xyz {return foo}} msg] $msg
+} {1 {unmatched open brace in list}}
+test proc-old-5.5 {error conditions} {
+ list [catch {proc tproc {{} y} {return foo}} msg] $msg
+} {1 {argument with no name}}
+test proc-old-5.6 {error conditions} {
+ list [catch {proc tproc {{} y} {return foo}} msg] $msg
+} {1 {argument with no name}}
+test proc-old-5.7 {error conditions} {
+ list [catch {proc tproc {{x 1 2} y} {return foo}} msg] $msg
+} {1 {too many fields in argument specifier "x 1 2"}}
+test proc-old-5.8 {error conditions} {
+ catch {return}
+} 2
+proc tproc {} {
+ set a 22
+ global a
+}
+test proc-old-5.10 {error conditions} {
+ list [catch {tproc} msg] $msg
+} {1 {variable "a" already exists}}
+test proc-old-5.11 {error conditions} {
+ catch {rename tproc {}}
+ catch {
+ proc tproc {x {} z} {return foo}
+ }
+ list [catch {tproc 1} msg] $msg
+} {1 {invalid command name "tproc"}}
+test proc-old-5.12 {error conditions} {
+ proc tproc {} {
+ set a 22
+ error "error in procedure"
+ return
+ }
+ list [catch tproc msg] $msg
+} {1 {error in procedure}}
+test proc-old-5.13 {error conditions} {
+ proc tproc {} {
+ set a 22
+ error "error in procedure"
+ return
+ }
+ catch tproc msg
+ set ::errorInfo
+} {error in procedure
+ while executing
+"error "error in procedure""
+ (procedure "tproc" line 3)
+ invoked from within
+"tproc"}
+test proc-old-5.14 {error conditions} {
+ proc tproc {} {
+ set a 22
+ break
+ return
+ }
+ catch tproc msg
+ set ::errorInfo
+} {invoked "break" outside of a loop
+ (procedure "tproc" line 1)
+ invoked from within
+"tproc"}
+test proc-old-5.15 {error conditions} {
+ proc tproc {} {
+ set a 22
+ continue
+ return
+ }
+ catch tproc msg
+ set ::errorInfo
+} {invoked "continue" outside of a loop
+ (procedure "tproc" line 1)
+ invoked from within
+"tproc"}
+test proc-old-5.16 {error conditions} {
+ proc foo args {
+ global fooMsg
+ set fooMsg "foo was called: $args"
+ }
+ proc tproc {} {
+ set x 44
+ trace var x u foo
+ while {$x < 100} {
+ error "Nested error"
+ }
+ }
+ set fooMsg "foo not called"
+ list [catch tproc msg] $msg $::errorInfo $fooMsg
+} {1 {Nested error} {Nested error
+ while executing
+"error "Nested error""
+ (procedure "tproc" line 5)
+ invoked from within
+"tproc"} {foo was called: x {} u}}
+
+# The tests below will really only be useful when run under Purify or
+# some other system that can detect accesses to freed memory...
+
+test proc-old-6.1 {procedure that redefines itself} {
+ proc tproc {} {
+ proc tproc {} {
+ return 44
+ }
+ return 45
+ }
+ tproc
+} 45
+test proc-old-6.2 {procedure that deletes itself} {
+ proc tproc {} {
+ rename tproc {}
+ return 45
+ }
+ tproc
+} 45
+
+proc tproc code {
+ return -code $code abc
+}
+test proc-old-7.1 {return with special completion code} {
+ list [catch {tproc ok} msg] $msg
+} {0 abc}
+test proc-old-7.2 {return with special completion code} {
+ list [catch {tproc error} msg] $msg $::errorInfo $::errorCode
+} {1 abc {abc
+ while executing
+"tproc error"} NONE}
+test proc-old-7.3 {return with special completion code} {
+ list [catch {tproc return} msg] $msg
+} {2 abc}
+test proc-old-7.4 {return with special completion code} {
+ list [catch {tproc break} msg] $msg
+} {3 abc}
+test proc-old-7.5 {return with special completion code} {
+ list [catch {tproc continue} msg] $msg
+} {4 abc}
+test proc-old-7.6 {return with special completion code} {
+ list [catch {tproc -14} msg] $msg
+} {-14 abc}
+test proc-old-7.7 {return with special completion code} -body {
+ tproc err
+} -returnCodes error -match glob -result {bad completion code "err": must be ok, error, return, break, continue*, or an integer}
+test proc-old-7.8 {return with special completion code} -body {
+ tproc 10b
+} -returnCodes error -match glob -result {bad completion code "10b": must be ok, error, return, break, continue*, or an integer}
+test proc-old-7.9 {return with special completion code} {
+ proc tproc2 {} {
+ tproc return
+ }
+ list [catch tproc2 msg] $msg
+} {0 abc}
+test proc-old-7.10 {return with special completion code} {
+ proc tproc2 {} {
+ return -code error
+ }
+ list [catch tproc2 msg] $msg
+} {1 {}}
+test proc-old-7.11 {return with special completion code} {
+ proc tproc2 {} {
+ global errorCode errorInfo
+ catch {open _bad_file_name r} msg
+ return -code error -errorinfo $errorInfo -errorcode $errorCode $msg
+ }
+ set msg [list [catch tproc2 msg] $msg $::errorInfo $::errorCode]
+ regsub -all [file join {} _bad_file_name] $msg "_bad_file_name" msg
+ normalizeMsg $msg
+} {1 {couldn't open "_bad_file_name": no such file or directory} {couldn't open "_bad_file_name": no such file or directory
+ while executing
+"open _bad_file_name r"
+ invoked from within
+"tproc2"} {posix enoent {no such file or directory}}}
+test proc-old-7.12 {return with special completion code} {
+ proc tproc2 {} {
+ global errorCode errorInfo
+ catch {open _bad_file_name r} msg
+ return -code error -errorcode $errorCode $msg
+ }
+ set msg [list [catch tproc2 msg] $msg $::errorInfo $::errorCode]
+ regsub -all [file join {} _bad_file_name] $msg "_bad_file_name" msg
+ normalizeMsg $msg
+} {1 {couldn't open "_bad_file_name": no such file or directory} {couldn't open "_bad_file_name": no such file or directory
+ while executing
+"tproc2"} {posix enoent {no such file or directory}}}
+test proc-old-7.13 {return with special completion code} {
+ proc tproc2 {} {
+ global errorCode errorInfo
+ catch {open _bad_file_name r} msg
+ return -code error -errorinfo $errorInfo $msg
+ }
+ set msg [list [catch tproc2 msg] $msg $::errorInfo $::errorCode]
+ regsub -all [file join {} _bad_file_name] $msg "_bad_file_name" msg
+ normalizeMsg $msg
+} {1 {couldn't open "_bad_file_name": no such file or directory} {couldn't open "_bad_file_name": no such file or directory
+ while executing
+"open _bad_file_name r"
+ invoked from within
+"tproc2"} none}
+test proc-old-7.14 {return with special completion code} {
+ proc tproc2 {} {
+ global errorCode errorInfo
+ catch {open _bad_file_name r} msg
+ return -code error $msg
+ }
+ set msg [list [catch tproc2 msg] $msg $::errorInfo $::errorCode]
+ regsub -all [file join {} _bad_file_name] $msg "_bad_file_name" msg
+ normalizeMsg $msg
+} {1 {couldn't open "_bad_file_name": no such file or directory} {couldn't open "_bad_file_name": no such file or directory
+ while executing
+"tproc2"} none}
+test proc-old-7.15 {return with special completion code} {
+ list [catch {return -badOption foo message} msg] $msg
+} {2 message}
+
+test proc-old-8.1 {unset and undefined local arrays} {
+ proc t1 {} {
+ foreach v {xxx, yyy} {
+ catch {unset $v}
+ }
+ set yyy(foo) bar
+ }
+ t1
+} bar
+
+test proc-old-9.1 {empty command name} {
+ catch {rename {} ""}
+ proc t1 {args} {
+ return
+ }
+ set v [t1]
+ catch {$v}
+} 1
+
+test proc-old-10.1 {ByteCode epoch change during recursive proc execution} {
+ proc t1 x {
+ set y 20
+ rename expr expr.old
+ rename expr.old expr
+ if $x then {t1 0} ;# recursive call after foo's code is invalidated
+ return 20
+ }
+ t1 1
+} 20
+
+# cleanup
+catch {rename t1 ""}
+catch {rename foo ""}
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/proc.test b/pkgs/msgcat/tests/proc.test
new file mode 100644
index 0000000..e06720e
--- /dev/null
+++ b/pkgs/msgcat/tests/proc.test
@@ -0,0 +1,396 @@
+# This file contains tests for the tclProc.c source file. Tests appear in the
+# same order as the C code that they test. The set of tests is currently
+# incomplete since it includes only new tests, in particular tests for code
+# changed for the addition of Tcl namespaces. Other procedure-related tests
+# appear in other test files such as proc-old.test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint procbodytest [expr {![catch {package require procbodytest}]}]
+testConstraint memory [llength [info commands memory]]
+
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+catch {rename p ""}
+catch {rename {} ""}
+catch {unset msg}
+
+test proc-1.1 {Tcl_ProcObjCmd, put proc in namespace specified in name, if any} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ namespace eval test_ns_1 {
+ namespace eval baz {}
+ }
+ proc test_ns_1::baz::p {} {
+ return "p in [namespace current]"
+ }
+ list [test_ns_1::baz::p] \
+ [namespace eval test_ns_1 {baz::p}] \
+ [info commands test_ns_1::baz::*]
+} -result {{p in ::test_ns_1::baz} {p in ::test_ns_1::baz} ::test_ns_1::baz::p}
+test proc-1.2 {Tcl_ProcObjCmd, namespace specified in proc name must exist} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -returnCodes error -body {
+ proc test_ns_1::baz::p {} {}
+} -result {can't create procedure "test_ns_1::baz::p": unknown namespace}
+test proc-1.3 {Tcl_ProcObjCmd, empty proc name} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ proc :: {} {
+ return "empty called"
+ }
+ list [::] \
+ [info body {}]
+} -result {{empty called} {
+ return "empty called"
+ }}
+test proc-1.4 {Tcl_ProcObjCmd, simple proc name and proc defined in namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ namespace eval test_ns_1 {
+ namespace eval baz {
+ proc p {} {
+ return "p in [namespace current]"
+ }
+ }
+ }
+ list [test_ns_1::baz::p] \
+ [info commands test_ns_1::baz::*]
+} -result {{p in ::test_ns_1::baz} ::test_ns_1::baz::p}
+test proc-1.5 {Tcl_ProcObjCmd, qualified proc name and proc defined in namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ namespace eval test_ns_1::baz {}
+ namespace eval test_ns_1 {
+ proc baz::p {} {
+ return "p in [namespace current]"
+ }
+ }
+ list [test_ns_1::baz::p] \
+ [info commands test_ns_1::baz::*] \
+ [namespace eval test_ns_1::baz {namespace which p}]
+} -result {{p in ::test_ns_1::baz} ::test_ns_1::baz::p ::test_ns_1::baz::p}
+test proc-1.6 {Tcl_ProcObjCmd, namespace code ignores single ":"s in middle or end of command names} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ namespace eval test_ns_1 {
+ proc q: {} {return "q:"}
+ proc value:at: {} {return "value:at:"}
+ }
+ list [namespace eval test_ns_1 {q:}] \
+ [namespace eval test_ns_1 {value:at:}] \
+ [test_ns_1::q:] \
+ [test_ns_1::value:at:] \
+ [lsort [info commands test_ns_1::*]] \
+ [namespace eval test_ns_1 {namespace which q:}] \
+ [namespace eval test_ns_1 {namespace which value:at:}]
+} -result {q: value:at: q: value:at: {::test_ns_1::q: ::test_ns_1::value:at:} ::test_ns_1::q: ::test_ns_1::value:at:}
+test proc-1.7 {Tcl_ProcObjCmd, check that formal parameter names are not array elements} -setup {
+ catch {rename p ""}
+} -returnCodes error -body {
+ proc p {a(1) a(2)} {
+ set z [expr $a(1)+$a(2)]
+ puts "$z=z, $a(1)=$a(1)"
+ }
+} -result {formal parameter "a(1)" is an array element}
+test proc-1.8 {Tcl_ProcObjCmd, check that formal parameter names are simple names} -setup {
+ catch {rename p ""}
+} -body {
+ proc p {b:a b::a} {
+ }
+} -returnCodes error -result {formal parameter "b::a" is not a simple name}
+
+test proc-2.1 {TclFindProc, simple proc name and proc not in namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename p ""}
+} -body {
+ proc p {} {return "p in [namespace current]"}
+ info body p
+} -result {return "p in [namespace current]"}
+test proc-2.2 {TclFindProc, simple proc name and proc defined in namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ namespace eval test_ns_1 {
+ namespace eval baz {
+ proc p {} {return "p in [namespace current]"}
+ }
+ }
+ namespace eval test_ns_1::baz {info body p}
+} -result {return "p in [namespace current]"}
+test proc-2.3 {TclFindProc, qualified proc name and proc defined in namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ namespace eval test_ns_1::baz {}
+ namespace eval test_ns_1 {
+ proc baz::p {} {return "p in [namespace current]"}
+ }
+ namespace eval test_ns_1 {info body baz::p}
+} -result {return "p in [namespace current]"}
+test proc-2.4 {TclFindProc, global proc and executing in namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename p ""}
+} -body {
+ proc p {} {return "global p"}
+ namespace eval test_ns_1::baz {info body p}
+} -result {return "global p"}
+
+test proc-3.1 {TclObjInterpProc, proc defined and executing in same namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ proc p {} {return "p in [namespace current]"}
+ p
+} -result {p in ::}
+test proc-3.2 {TclObjInterpProc, proc defined and executing in same namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+ namespace eval test_ns_1::baz {
+ proc p {} {return "p in [namespace current]"}
+ p
+ }
+} -result {p in ::test_ns_1::baz}
+test proc-3.3 {TclObjInterpProc, proc defined and executing in different namespaces} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename p ""}
+} -body {
+ proc p {} {return "p in [namespace current]"}
+ namespace eval test_ns_1::baz {
+ p
+ }
+} -result {p in ::}
+test proc-3.4 {TclObjInterpProc, procs execute in the namespace in which they were defined unless renamed into new namespace} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename p ""}
+} -body {
+ namespace eval test_ns_1::baz {
+ proc p {} {return "p in [namespace current]"}
+ rename ::test_ns_1::baz::p ::p
+ list [p] [namespace which p]
+ }
+} -result {{p in ::} ::p}
+test proc-3.5 {TclObjInterpProc, any old result is reset before appending error msg about missing arguments} -body {
+ proc p {x} {info commands 3m}
+ p
+} -returnCodes error -result {wrong # args: should be "p x"}
+test proc-3.6 {TclObjInterpProc, proper quoting of proc name, Bug 942757} -body {
+ proc {a b c} {x} {info commands 3m}
+ {a b c}
+} -returnCodes error -result {wrong # args: should be "{a b c} x"}
+
+test proc-3.7 {TclObjInterpProc, wrong num args, Bug 3366265} {
+ proc {} {x} {}
+ list [catch {{}} msg] $msg
+} {1 {wrong # args: should be "{} x"}}
+
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+catch {rename p ""}
+catch {rename {} ""}
+catch {rename {a b c} {}}
+catch {unset msg}
+
+catch {rename p ""}
+catch {rename t ""}
+
+# Note that the test require that procedures whose body is used to create
+# procbody objects must be executed before the procbodytest::proc command is
+# executed, so that the Proc struct is populated correctly (CompiledLocals are
+# added at compile time).
+
+test proc-4.1 {TclCreateProc, procbody obj} -constraints procbodytest -body {
+ proc p x {return "$x:$x"}
+ set rv [p P]
+ procbodytest::proc t x p
+ lappend rv [t T]
+} -cleanup {
+ catch {rename p ""}
+ catch {rename t ""}
+} -result {P:P T:T}
+test proc-4.2 {TclCreateProc, procbody obj, use compiled locals} -body {
+ proc p x {
+ set y [string tolower $x]
+ return "$x:$y"
+ }
+ set rv [p P]
+ procbodytest::proc t x p
+ lappend rv [t T]
+} -constraints procbodytest -cleanup {
+ catch {rename p ""}
+ catch {rename t ""}
+} -result {P:p T:t}
+test proc-4.3 {TclCreateProc, procbody obj, too many args} -body {
+ proc p x {
+ set y [string tolower $x]
+ return "$x:$y"
+ }
+ set rv [p P]
+ procbodytest::proc t {x x1 x2} p
+ lappend rv [t T]
+} -constraints procbodytest -returnCodes error -cleanup {
+ catch {rename p ""}
+ catch {rename t ""}
+} -result {procedure "t": arg list contains 3 entries, precompiled header expects 1}
+test proc-4.4 {TclCreateProc, procbody obj, inconsistent arg name} -body {
+ proc p {x y z} {
+ set v [join [list $x $y $z]]
+ set w [string tolower $v]
+ return "$v:$w"
+ }
+ set rv [p P Q R]
+ procbodytest::proc t {x x1 z} p
+ lappend rv [t S T U]
+} -constraints procbodytest -returnCodes error -cleanup {
+ catch {rename p ""}
+ catch {rename t ""}
+} -result {procedure "t": formal parameter 1 is inconsistent with precompiled body}
+test proc-4.5 {TclCreateProc, procbody obj, inconsistent arg default type} -body {
+ proc p {x y {z Z}} {
+ set v [join [list $x $y $z]]
+ set w [string tolower $v]
+ return "$v:$w"
+ }
+ set rv [p P Q R]
+ procbodytest::proc t {x y z} p
+ lappend rv [t S T U]
+} -constraints procbodytest -returnCodes error -cleanup {
+ catch {rename p ""}
+ catch {rename t ""}
+} -result {procedure "t": formal parameter 2 is inconsistent with precompiled body}
+test proc-4.6 {TclCreateProc, procbody obj, inconsistent arg default type} -body {
+ proc p {x y z} {
+ set v [join [list $x $y $z]]
+ set w [string tolower $v]
+ return "$v:$w"
+ }
+ set rv [p P Q R]
+ procbodytest::proc t {x y {z Z}} p
+ lappend rv [t S T U]
+} -returnCodes error -constraints procbodytest -cleanup {
+ catch {rename p ""}
+ catch {rename t ""}
+} -result {procedure "t": formal parameter 2 is inconsistent with precompiled body}
+test proc-4.7 {TclCreateProc, procbody obj, inconsistent arg default value} -body {
+ proc p {x y {z Z}} {
+ set v [join [list $x $y $z]]
+ set w [string tolower $v]
+ return "$v:$w"
+ }
+ set rv [p P Q R]
+ procbodytest::proc t {x y {z ZZ}} p
+ lappend rv [t S T U]
+} -constraints procbodytest -returnCodes error -cleanup {
+ catch {rename p ""}
+ catch {rename t ""}
+} -result {procedure "t": formal parameter "z" has default value inconsistent with precompiled body}
+test proc-4.8 {TclCreateProc, procbody obj, no leak on multiple iterations} -setup {
+ proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex $lines 3 3
+ }
+ proc px x {
+ set y [string tolower $x]
+ return "$x:$y"
+ }
+ px x
+} -constraints {procbodytest memory} -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ procbodytest::proc tx x px
+ set tmp $end
+ set end [getbytes]
+ }
+ set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+ rename getbytes {}
+ unset -nocomplain end i tmp leakedBytes
+} -result 0
+
+test proc-5.1 {Bytecompiling noop; test for correct argument substitution} -body {
+ proc p args {} ; # this will be bytecompiled into t
+ proc t {} {
+ set res {}
+ set a 0
+ set b 0
+ trace add variable a read {append res a ;#}
+ trace add variable b write {append res b ;#}
+ p $a ccccccw {bfe} {$a} [incr b] [incr a] {[incr b]} {$a} hello
+ set res
+ }
+ t
+} -cleanup {
+ catch {rename p ""}
+ catch {rename t ""}
+} -result {aba}
+
+test proc-6.1 {ProcessProcResultCode: Bug 647307 (negative return code)} -body {
+ proc a {} {return -code -5}
+ proc b {} a
+ catch b
+} -cleanup {
+ rename a {}
+ rename b {}
+} -result -5
+
+test proc-7.1 {Redefining a compiled cmd: Bug 729692} {
+ proc bar args {}
+ proc foo {} {
+ proc bar args {return bar}
+ bar
+ }
+ foo
+} bar
+test proc-7.2 {Shadowing a compiled cmd: Bug 729692} -body {
+ namespace eval ugly {}
+ proc ugly::foo {} {
+ proc set args {return bar}
+ set x 1
+ }
+ ugly::foo
+} -cleanup {
+ namespace delete ugly
+} -result bar
+test proc-7.3 {Returning loop exception from redefined cmd: Bug 729692} -body {
+ namespace eval ugly {}
+ proc ugly::foo {} {
+ set i 0
+ while { 1 } {
+ if { [incr i] > 3 } {
+ proc continue {} {return -code break}
+ }
+ continue
+ }
+ return $i
+ }
+ ugly::foo
+} -cleanup {
+ namespace delete ugly
+} -result 4
+
+test proc-7.4 {Proc struct outlives its interp: Bug 3532959} {
+ set lambda x
+ lappend lambda {set a 1}
+ interp create slave
+ slave eval [list apply $lambda foo]
+ interp delete slave
+ unset lambda
+} {}
+
+# cleanup
+catch {rename p ""}
+catch {rename t ""}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/pwd.test b/pkgs/msgcat/tests/pwd.test
new file mode 100644
index 0000000..175c852
--- /dev/null
+++ b/pkgs/msgcat/tests/pwd.test
@@ -0,0 +1,31 @@
+# Commands covered: pwd
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+test pwd-1.1 {simple pwd} {
+ catch pwd
+} 0
+test pwd-1.2 {simple pwd} {
+ expr [string length pwd]>0
+} 1
+test pwd-1.3 {pwd takes no args} -body {
+ pwd foobar
+} -returnCodes error -result "wrong \# args: should be \"pwd\""
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/reg.test b/pkgs/msgcat/tests/reg.test
new file mode 100644
index 0000000..abfc9ca
--- /dev/null
+++ b/pkgs/msgcat/tests/reg.test
@@ -0,0 +1,1087 @@
+# reg.test --
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+# (Don't panic if you are seeing this as part of the reg distribution
+# and aren't using Tcl -- reg's own regression tester also knows how
+# to read this file, ignoring the Tcl-isms.)
+#
+# Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+}
+
+# All tests require the testregexp command, return if this
+# command doesn't exist
+
+::tcltest::testConstraint testregexp [llength [info commands testregexp]]
+::tcltest::testConstraint localeRegexp 0
+
+# This file uses some custom procedures, defined below, for regexp regression
+# testing. The name of the procedure indicates the general nature of the
+# test:
+# expectError compile error expected
+# expectNomatch match failure expected
+# expectMatch successful match
+# expectIndices successful match with -indices (used in checking things
+# like nonparticipating subexpressions)
+# expectPartial unsuccessful match with -indices (!!) (used in checking
+# partial-match reporting)
+# There is also "doing" which sets up title and major test number for each
+# block of tests.
+
+# The first 3 arguments are constant: a minor number (which often gets
+# a letter or two suffixed to it internally), some flags, and the RE
+# itself. For expectError, the remaining argument is the name of the
+# compile error expected, less the leading "REG_". For the rest, the
+# next argument is the string to try the match against. Remaining
+# arguments are the substring expected to be matched, and any
+# substrings expected to be matched by subexpressions. (For
+# expectNomatch, these arguments are optional, and if present are
+# ignored except that they indicate how many subexpressions should be
+# present in the RE.) It is an error for the number of subexpression
+# arguments to be wrong. Cases involving nonparticipating
+# subexpressions, checking where empty substrings are located,
+# etc. should be done using expectIndices and expectPartial.
+
+# The flag characters are complex and a bit eclectic. Generally speaking,
+# lowercase letters are compile options, uppercase are expected re_info
+# bits, and nonalphabetics are match options, controls for how the test is
+# run, or testing options. The one small surprise is that AREs are the
+# default, and you must explicitly request lesser flavors of RE. The flags
+# are as follows. It is admitted that some are not very mnemonic.
+# There are some others which are purely debugging tools and are not
+# useful in this file.
+#
+# - no-op (placeholder)
+# + provide fake xy equivalence class and ch collating element
+# % force small state-set cache in matcher (to test cache replace)
+# ^ beginning of string is not beginning of line
+# $ end of string is not end of line
+# * test is Unicode-specific, needs big character set
+#
+# & test as both ARE and BRE
+# b BRE
+# e ERE
+# a turn advanced-features bit on (error unless ERE already)
+# q literal string, no metacharacters at all
+#
+# i case-independent matching
+# o ("opaque") no subexpression capture
+# p newlines are half-magic, excluded from . and [^ only
+# w newlines are half-magic, significant to ^ and $ only
+# n newlines are fully magic, both effects
+# x expanded RE syntax
+# t incomplete-match reporting
+#
+# A backslash-_a_lphanumeric seen
+# B ERE/ARE literal-_b_race heuristic used
+# E backslash (_e_scape) seen within []
+# H looka_h_ead constraint seen
+# I _i_mpossible to match
+# L _l_ocale-specific construct seen
+# M unportable (_m_achine-specific) construct seen
+# N RE can match empty (_n_ull) string
+# P non-_P_OSIX construct seen
+# Q {} _q_uantifier seen
+# R back _r_eference seen
+# S POSIX-un_s_pecified syntax seen
+# T prefers shortest (_t_iny)
+# U saw original-POSIX botch: unmatched right paren in ERE (_u_gh)
+
+# The one area we can't easily test is memory-allocation failures (which
+# are hard to provoke on command). Embedded NULs also are not tested at
+# the moment, but this is a historical accident which should be fixed.
+
+
+# test procedures and related
+namespace eval RETest {
+ namespace export doing expect* knownBug
+
+ variable regBug 0
+
+ # re_info abbreviation mapping table
+ variable infonames
+ array set infonames {
+ A REG_UBSALNUM
+ B REG_UBRACES
+ E REG_UBBS
+ H REG_ULOOKAHEAD
+ I REG_UIMPOSSIBLE
+ L REG_ULOCALE
+ M REG_UUNPORT
+ N REG_UEMPTYMATCH
+ P REG_UNONPOSIX
+ Q REG_UBOUNDS
+ R REG_UBACKREF
+ S REG_UUNSPEC
+ T REG_USHORTEST
+ U REG_UPBOTCH
+ }
+ variable infonameorder "RHQBAUEPSMLNIT" ;# must match bit order, lsb first
+
+ # build test number (internal)
+ proc TestNum {args} {
+ return reg-[join [concat $args] .]
+ }
+
+ # build description, with possible modifiers (internal)
+ proc TestDesc {args} {
+ variable description
+
+ set testid [concat $args]
+ set d $description
+ if {[llength $testid] > 1} {
+ set d "$d ([lrange $testid 1 end])"
+ }
+ return $d
+ }
+
+ # build trailing options and flags argument from a flags string (internal)
+ proc TestFlags {fl} {
+ set args [list]
+ set flags ""
+ foreach f [split $fl ""] {
+ switch -exact -- $f {
+ "i" { lappend args "-nocase" }
+ "x" { lappend args "-expanded" }
+ "n" { lappend args "-line" }
+ "p" { lappend args "-linestop" }
+ "w" { lappend args "-lineanchor" }
+ "-" { }
+ default { append flags $f }
+ }
+ }
+ if {$flags ne ""} {
+ lappend args -xflags $flags
+ }
+ return $args
+ }
+
+ # build info-flags list from a flags string (internal)
+ proc TestInfoFlags {fl} {
+ variable infonames
+ variable infonameorder
+
+ set ret [list]
+ foreach f [split $infonameorder ""] {
+ if {[string match *$f* $fl]} {
+ lappend ret $infonames($f)
+ }
+ }
+ return $ret
+ }
+
+ # Share the generation of the list of test constraints so it is
+ # done the same on all routes.
+ proc TestConstraints {flags} {
+ set constraints [list testregexp]
+
+ variable regBug
+ if {$regBug} {
+ # This will trigger registration as a skipped test
+ lappend constraints knownBug
+ }
+
+ # Tcl locale stuff doesn't do the ch/xy test fakery yet
+ if {[string match *+* $flags]} {
+ # This will trigger registration as a skipped test
+ lappend constraints localeRegexp
+ }
+
+ return $constraints
+ }
+
+ # match expected, internal routine that does the work
+ # parameters like the "real" routines except they don't have "opts",
+ # which is a possibly-empty list of switches for the regexp match attempt
+ # The ! flag is used to indicate expected match failure (for REG_EXPECT,
+ # which wants argument testing even in the event of failure).
+ proc MatchExpected {opts testid flags re target args} {
+ # if &, test as both BRE and ARE
+ if {[string match *&* $flags]} {
+ set f [string map {& {}} $flags]
+ MatchExpected $opts "$testid ARE" ${f} $re $target {*}$args
+ MatchExpected $opts "$testid BRE" ${f}b $re $target {*}$args
+ return
+ }
+
+ set constraints [TestConstraints $flags]
+
+ set f [TestFlags $flags]
+ set infoflags [TestInfoFlags $flags]
+ set ccmd [list testregexp -about {*}$f $re]
+ set ecmd [list testregexp {*}$opts {*}$f $re $target]
+
+ set nsub [expr {[llength $args] - 1}]
+ set names [list]
+ set refs ""
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ if {$i == 0} {
+ set name match
+ } else {
+ set name sub$i
+ }
+ lappend names $name
+ append refs " \$$name"
+ set $name ""
+ }
+ if {[string match *o* $flags]} { ;# REG_NOSUB kludge
+ set nsub 0 ;# unsigned value cannot be -1
+ }
+ if {[string match *t* $flags]} { ;# REG_EXPECT
+ incr nsub -1 ;# the extra does not count
+ }
+ set erun "list \[[concat $ecmd $names]\] $refs"
+ set result [list [expr {![string match *!* $flags]}] {*}$args]
+ set info [list $nsub $infoflags]
+
+ ::tcltest::test [TestNum $testid compile] [TestDesc $testid compile] \
+ -constraints $constraints -body $ccmd -result $info
+ ::tcltest::test [TestNum $testid execute] [TestDesc $testid execute] \
+ -constraints $constraints -body $erun -result $result
+ }
+
+ # set major test number and description
+ proc doing {major desc} {
+ variable description "RE engine $desc"
+ }
+
+ # compilation error expected
+ proc expectError {testid flags re err} {
+ # if &, test as both ARE and BRE
+ if {[string match *&* $flags]} {
+ set f [string map {& {}} $flags]
+ expectError "$testid ARE" ${f} $re $err
+ expectError "$testid BRE" ${f}b $re $err
+ return
+ }
+
+ set constraints [TestConstraints $flags]
+
+ set cmd [list testregexp -about {*}[TestFlags $flags] $re]
+ ::tcltest::test [TestNum $testid error] [TestDesc $testid error] \
+ -constraints $constraints -result [list 1 REG_$err] -body \
+ "list \[catch \{$cmd\}\] \[lindex \$::errorCode 1\]"
+ }
+
+ # match failure expected
+ proc expectNomatch {testid flags re target args} {
+ variable regBug
+ # if &, test as both ARE and BRE
+ if {[string match *&* $flags]} {
+ set f [string map {& {}} $flags]
+ expectNomatch "$testid ARE" ${f} $re $target {*}$args
+ expectNomatch "$testid BRE" ${f}b $re $target {*}$args
+ return
+ }
+
+ set constraints [TestConstraints $flags]
+
+ set f [TestFlags $flags]
+ set infoflags [TestInfoFlags $flags]
+ set ccmd [list testregexp -about {*}$f $re]
+ set nsub [expr {[llength $args] - 1}]
+ if {$nsub == -1} {
+ # didn't tell us number of subexps
+ set ccmd "lreplace \[$ccmd\] 0 0"
+ set info [list $infoflags]
+ } else {
+ set info [list $nsub $infoflags]
+ }
+ set ecmd [list testregexp {*}$f $re $target]
+
+ ::tcltest::test [TestNum $testid compile] [TestDesc $testid compile] \
+ -constraints $constraints -body $ccmd -result $info
+ ::tcltest::test [TestNum $testid execute] [TestDesc $testid execute] \
+ -constraints $constraints -body $ecmd -result 0
+ }
+
+ # match expected (no missing, empty, or ambiguous submatches)
+ # expectMatch testno flags re target mat submat ...
+ proc expectMatch {args} {
+ MatchExpected {} {*}$args
+ }
+
+ # match expected (full fanciness)
+ # expectIndices testno flags re target mat submat ...
+ proc expectIndices {args} {
+ MatchExpected -indices {*}$args
+ }
+
+ # partial match expected
+ # expectPartial testno flags re target mat "" ...
+ # Quirk: number of ""s must be one more than number of subREs.
+ proc expectPartial {args} {
+ lset args 1 ![lindex $args 1] ;# add ! flag
+ MatchExpected -indices {*}$args
+ }
+
+ # test is a knownBug
+ proc knownBug {args} {
+ variable regBug 1
+ uplevel \#0 $args
+ set regBug 0
+ }
+}
+namespace import RETest::*
+
+######## the tests themselves ########
+
+# support functions and preliminary misc.
+# This is sensitive to changes in message wording, but we really have to
+# test the code->message expansion at least once.
+::tcltest::test reg-0.1 "regexp error reporting" {
+ list [catch {regexp (*) ign} msg] $msg
+} {1 {couldn't compile regular expression pattern: quantifier operand invalid}}
+
+
+doing 1 "basic sanity checks"
+expectMatch 1.1 & abc abc abc
+expectNomatch 1.2 & abc def
+expectMatch 1.3 & abc xyabxabce abc
+
+
+doing 2 "invalid option combinations"
+expectError 2.1 qe a INVARG
+expectError 2.2 qa a INVARG
+expectError 2.3 qx a INVARG
+expectError 2.4 qn a INVARG
+expectError 2.5 ba a INVARG
+
+
+doing 3 "basic syntax"
+expectIndices 3.1 &NS "" a {0 -1}
+expectMatch 3.2 NS a| a a
+expectMatch 3.3 - a|b a a
+expectMatch 3.4 - a|b b b
+expectMatch 3.5 NS a||b b b
+expectMatch 3.6 & ab ab ab
+
+
+doing 4 "parentheses"
+expectMatch 4.1 - (a)e ae ae a
+expectMatch 4.2 o (a)e ae
+expectMatch 4.3 b {\(a\)b} ab ab a
+expectMatch 4.4 - a((b)c) abc abc bc b
+expectMatch 4.5 - a(b)(c) abc abc b c
+expectError 4.6 - a(b EPAREN
+expectError 4.7 b {a\(b} EPAREN
+# sigh, we blew it on the specs here... someday this will be fixed in POSIX,
+# but meanwhile, it's fixed in AREs
+expectMatch 4.8 eU a)b a)b a)b
+expectError 4.9 - a)b EPAREN
+expectError 4.10 b {a\)b} EPAREN
+expectMatch 4.11 P a(?:b)c abc abc
+expectError 4.12 e a(?:b)c BADRPT
+expectIndices 4.13 S a()b ab {0 1} {1 0}
+expectMatch 4.14 SP a(?:)b ab ab
+expectIndices 4.15 S a(|b)c ac {0 1} {1 0}
+expectMatch 4.16 S a(b|)c abc abc b
+
+
+doing 5 "simple one-char matching"
+# general case of brackets done later
+expectMatch 5.1 & a.b axb axb
+expectNomatch 5.2 &n "a.b" "a\nb"
+expectMatch 5.3 & {a[bc]d} abd abd
+expectMatch 5.4 & {a[bc]d} acd acd
+expectNomatch 5.5 & {a[bc]d} aed
+expectNomatch 5.6 & {a[^bc]d} abd
+expectMatch 5.7 & {a[^bc]d} aed aed
+expectNomatch 5.8 &p "a\[^bc]d" "a\nd"
+
+
+doing 6 "context-dependent syntax"
+# plus odds and ends
+expectError 6.1 - * BADRPT
+expectMatch 6.2 b * * *
+expectMatch 6.3 b {\(*\)} * * *
+expectError 6.4 - (*) BADRPT
+expectMatch 6.5 b ^* * *
+expectError 6.6 - ^* BADRPT
+expectNomatch 6.7 & ^b ^b
+expectMatch 6.8 b x^ x^ x^
+expectNomatch 6.9 I x^ x
+expectMatch 6.10 n "\n^" "x\nb" "\n"
+expectNomatch 6.11 bS {\(^b\)} ^b
+expectMatch 6.12 - (^b) b b b
+expectMatch 6.13 & {x$} x x
+expectMatch 6.14 bS {\(x$\)} x x x
+expectMatch 6.15 - {(x$)} x x x
+expectMatch 6.16 b {x$y} "x\$y" "x\$y"
+expectNomatch 6.17 I {x$y} xy
+expectMatch 6.18 n "x\$\n" "x\n" "x\n"
+expectError 6.19 - + BADRPT
+expectError 6.20 - ? BADRPT
+
+
+doing 7 "simple quantifiers"
+expectMatch 7.1 &N a* aa aa
+expectIndices 7.2 &N a* b {0 -1}
+expectMatch 7.3 - a+ aa aa
+expectMatch 7.4 - a?b ab ab
+expectMatch 7.5 - a?b b b
+expectError 7.6 - ** BADRPT
+expectMatch 7.7 bN ** *** ***
+expectError 7.8 & a** BADRPT
+expectError 7.9 & a**b BADRPT
+expectError 7.10 & *** BADRPT
+expectError 7.11 - a++ BADRPT
+expectError 7.12 - a?+ BADRPT
+expectError 7.13 - a?* BADRPT
+expectError 7.14 - a+* BADRPT
+expectError 7.15 - a*+ BADRPT
+
+
+doing 8 "braces"
+expectMatch 8.1 NQ "a{0,1}" "" ""
+expectMatch 8.2 NQ "a{0,1}" ac a
+expectError 8.3 - "a{1,0}" BADBR
+expectError 8.4 - "a{1,2,3}" BADBR
+expectError 8.5 - "a{257}" BADBR
+expectError 8.6 - "a{1000}" BADBR
+expectError 8.7 - "a{1" EBRACE
+expectError 8.8 - "a{1n}" BADBR
+expectMatch 8.9 BS "a{b" "a\{b" "a\{b"
+expectMatch 8.10 BS "a{" "a\{" "a\{"
+expectMatch 8.11 bQ "a\\{0,1\\}b" cb b
+expectError 8.12 b "a\\{0,1" EBRACE
+expectError 8.13 - "a{0,1\\" BADBR
+expectMatch 8.14 Q "a{0}b" ab b
+expectMatch 8.15 Q "a{0,0}b" ab b
+expectMatch 8.16 Q "a{0,1}b" ab ab
+expectMatch 8.17 Q "a{0,2}b" b b
+expectMatch 8.18 Q "a{0,2}b" aab aab
+expectMatch 8.19 Q "a{0,}b" aab aab
+expectMatch 8.20 Q "a{1,1}b" aab ab
+expectMatch 8.21 Q "a{1,3}b" aaaab aaab
+expectNomatch 8.22 Q "a{1,3}b" b
+expectMatch 8.23 Q "a{1,}b" aab aab
+expectNomatch 8.24 Q "a{2,3}b" ab
+expectMatch 8.25 Q "a{2,3}b" aaaab aaab
+expectNomatch 8.26 Q "a{2,}b" ab
+expectMatch 8.27 Q "a{2,}b" aaaab aaaab
+
+
+doing 9 "brackets"
+expectMatch 9.1 & {a[bc]} ac ac
+expectMatch 9.2 & {a[-]} a- a-
+expectMatch 9.3 & {a[[.-.]]} a- a-
+expectMatch 9.4 &L {a[[.zero.]]} a0 a0
+expectMatch 9.5 &LM {a[[.zero.]-9]} a2 a2
+expectMatch 9.6 &M {a[0-[.9.]]} a2 a2
+expectMatch 9.7 &+L {a[[=x=]]} ax ax
+expectMatch 9.8 &+L {a[[=x=]]} ay ay
+expectNomatch 9.9 &+L {a[[=x=]]} az
+expectError 9.10 & {a[0-[=x=]]} ERANGE
+expectMatch 9.11 &L {a[[:digit:]]} a0 a0
+expectError 9.12 & {a[[:woopsie:]]} ECTYPE
+expectNomatch 9.13 &L {a[[:digit:]]} ab
+expectError 9.14 & {a[0-[:digit:]]} ERANGE
+expectMatch 9.15 &LP {[[:<:]]a} a a
+expectMatch 9.16 &LP {a[[:>:]]} a a
+expectError 9.17 & {a[[..]]b} ECOLLATE
+expectError 9.18 & {a[[==]]b} ECOLLATE
+expectError 9.19 & {a[[::]]b} ECTYPE
+expectError 9.20 & {a[[.a} EBRACK
+expectError 9.21 & {a[[=a} EBRACK
+expectError 9.22 & {a[[:a} EBRACK
+expectError 9.23 & {a[} EBRACK
+expectError 9.24 & {a[b} EBRACK
+expectError 9.25 & {a[b-} EBRACK
+expectError 9.26 & {a[b-c} EBRACK
+expectMatch 9.27 &M {a[b-c]} ab ab
+expectMatch 9.28 & {a[b-b]} ab ab
+expectMatch 9.29 &M {a[1-2]} a2 a2
+expectError 9.30 & {a[c-b]} ERANGE
+expectError 9.31 & {a[a-b-c]} ERANGE
+expectMatch 9.32 &M {a[--?]b} a?b a?b
+expectMatch 9.33 & {a[---]b} a-b a-b
+expectMatch 9.34 & {a[]b]c} a]c a]c
+expectMatch 9.35 EP {a[\]]b} a]b a]b
+expectNomatch 9.36 bE {a[\]]b} a]b
+expectMatch 9.37 bE {a[\]]b} "a\\]b" "a\\]b"
+expectMatch 9.38 eE {a[\]]b} "a\\]b" "a\\]b"
+expectMatch 9.39 EP {a[\\]b} "a\\b" "a\\b"
+expectMatch 9.40 eE {a[\\]b} "a\\b" "a\\b"
+expectMatch 9.41 bE {a[\\]b} "a\\b" "a\\b"
+expectError 9.42 - {a[\Z]b} EESCAPE
+expectMatch 9.43 & {a[[b]c} "a\[c" "a\[c"
+expectMatch 9.44 EMP* {a[\u00fe-\u0507][\u00ff-\u0300]b} \
+ "a\u0102\u02ffb" "a\u0102\u02ffb"
+
+
+doing 10 "anchors and newlines"
+expectMatch 10.1 & ^a a a
+expectNomatch 10.2 &^ ^a a
+expectIndices 10.3 &N ^ a {0 -1}
+expectIndices 10.4 & {a$} aba {2 2}
+expectNomatch 10.5 {&$} {a$} a
+expectIndices 10.6 &N {$} ab {2 1}
+expectMatch 10.7 &n ^a a a
+expectMatch 10.8 &n "^a" "b\na" "a"
+expectIndices 10.9 &w "^a" "a\na" {0 0}
+expectIndices 10.10 &n^ "^a" "a\na" {2 2}
+expectMatch 10.11 &n {a$} a a
+expectMatch 10.12 &n "a\$" "a\nb" "a"
+expectIndices 10.13 &n "a\$" "a\na" {0 0}
+expectIndices 10.14 N ^^ a {0 -1}
+expectMatch 10.15 b ^^ ^ ^
+expectIndices 10.16 N {$$} a {1 0}
+expectMatch 10.17 b {$$} "\$" "\$"
+expectMatch 10.18 &N {^$} "" ""
+expectNomatch 10.19 &N {^$} a
+expectIndices 10.20 &nN "^\$" a\n\nb {2 1}
+expectMatch 10.21 N {$^} "" ""
+expectMatch 10.22 b {$^} "\$^" "\$^"
+expectMatch 10.23 P {\Aa} a a
+expectMatch 10.24 ^P {\Aa} a a
+expectNomatch 10.25 ^nP {\Aa} "b\na"
+expectMatch 10.26 P {a\Z} a a
+expectMatch 10.27 \$P {a\Z} a a
+expectNomatch 10.28 \$nP {a\Z} "a\nb"
+expectError 10.29 - ^* BADRPT
+expectError 10.30 - {$*} BADRPT
+expectError 10.31 - {\A*} BADRPT
+expectError 10.32 - {\Z*} BADRPT
+
+
+doing 11 "boundary constraints"
+expectMatch 11.1 &LP {[[:<:]]a} a a
+expectMatch 11.2 &LP {[[:<:]]a} -a a
+expectNomatch 11.3 &LP {[[:<:]]a} ba
+expectMatch 11.4 &LP {a[[:>:]]} a a
+expectMatch 11.5 &LP {a[[:>:]]} a- a
+expectNomatch 11.6 &LP {a[[:>:]]} ab
+expectMatch 11.7 bLP {\<a} a a
+expectNomatch 11.8 bLP {\<a} ba
+expectMatch 11.9 bLP {a\>} a a
+expectNomatch 11.10 bLP {a\>} ab
+expectMatch 11.11 LP {\ya} a a
+expectNomatch 11.12 LP {\ya} ba
+expectMatch 11.13 LP {a\y} a a
+expectNomatch 11.14 LP {a\y} ab
+expectMatch 11.15 LP {a\Y} ab a
+expectNomatch 11.16 LP {a\Y} a-
+expectNomatch 11.17 LP {a\Y} a
+expectNomatch 11.18 LP {-\Y} -a
+expectMatch 11.19 LP {-\Y} -% -
+expectNomatch 11.20 LP {\Y-} a-
+expectError 11.21 - {[[:<:]]*} BADRPT
+expectError 11.22 - {[[:>:]]*} BADRPT
+expectError 11.23 b {\<*} BADRPT
+expectError 11.24 b {\>*} BADRPT
+expectError 11.25 - {\y*} BADRPT
+expectError 11.26 - {\Y*} BADRPT
+expectMatch 11.27 LP {\ma} a a
+expectNomatch 11.28 LP {\ma} ba
+expectMatch 11.29 LP {a\M} a a
+expectNomatch 11.30 LP {a\M} ab
+expectNomatch 11.31 ILP {\Ma} a
+expectNomatch 11.32 ILP {a\m} a
+
+
+doing 12 "character classes"
+expectMatch 12.1 LP {a\db} a0b a0b
+expectNomatch 12.2 LP {a\db} axb
+expectNomatch 12.3 LP {a\Db} a0b
+expectMatch 12.4 LP {a\Db} axb axb
+expectMatch 12.5 LP "a\\sb" "a b" "a b"
+expectMatch 12.6 LP "a\\sb" "a\tb" "a\tb"
+expectMatch 12.7 LP "a\\sb" "a\nb" "a\nb"
+expectNomatch 12.8 LP {a\sb} axb
+expectMatch 12.9 LP {a\Sb} axb axb
+expectNomatch 12.10 LP "a\\Sb" "a b"
+expectMatch 12.11 LP {a\wb} axb axb
+expectNomatch 12.12 LP {a\wb} a-b
+expectNomatch 12.13 LP {a\Wb} axb
+expectMatch 12.14 LP {a\Wb} a-b a-b
+expectMatch 12.15 LP {\y\w+z\y} adze-guz guz
+expectMatch 12.16 LPE {a[\d]b} a1b a1b
+expectMatch 12.17 LPE "a\[\\s]b" "a b" "a b"
+expectMatch 12.18 LPE {a[\w]b} axb axb
+
+
+doing 13 "escapes"
+expectError 13.1 & "a\\" EESCAPE
+expectMatch 13.2 - {a\<b} a<b a<b
+expectMatch 13.3 e {a\<b} a<b a<b
+expectMatch 13.4 bAS {a\wb} awb awb
+expectMatch 13.5 eAS {a\wb} awb awb
+expectMatch 13.6 PL "a\\ab" "a\007b" "a\007b"
+expectMatch 13.7 P "a\\bb" "a\bb" "a\bb"
+expectMatch 13.8 P {a\Bb} "a\\b" "a\\b"
+expectMatch 13.9 MP "a\\chb" "a\bb" "a\bb"
+expectMatch 13.10 MP "a\\cHb" "a\bb" "a\bb"
+expectMatch 13.11 LMP "a\\e" "a\033" "a\033"
+expectMatch 13.12 P "a\\fb" "a\fb" "a\fb"
+expectMatch 13.13 P "a\\nb" "a\nb" "a\nb"
+expectMatch 13.14 P "a\\rb" "a\rb" "a\rb"
+expectMatch 13.15 P "a\\tb" "a\tb" "a\tb"
+expectMatch 13.16 P "a\\u0008x" "a\bx" "a\bx"
+expectMatch 13.17 P {a\u008x} "a\bx" "a\bx"
+expectMatch 13.18 P "a\\u00088x" "a\b8x" "a\b8x"
+expectMatch 13.19 P "a\\U00000008x" "a\bx" "a\bx"
+expectMatch 13.20 P {a\U0000008x} "a\bx" "a\bx"
+expectMatch 13.21 P "a\\vb" "a\vb" "a\vb"
+expectMatch 13.22 MP "a\\x08x" "a\bx" "a\bx"
+expectError 13.23 - {a\xq} EESCAPE
+expectMatch 13.24 MP "a\\x08x" "a\bx" "a\bx"
+expectError 13.25 - {a\z} EESCAPE
+expectMatch 13.26 MP "a\\010b" "a\bb" "a\bb"
+expectMatch 13.27 P "a\\U00001234x" "a\u1234x" "a\u1234x"
+expectMatch 13.28 P {a\U00001234x} "a\u1234x" "a\u1234x"
+expectMatch 13.29 P "a\\U0001234x" "a\u1234x" "a\u1234x"
+expectMatch 13.30 P {a\U0001234x} "a\u1234x" "a\u1234x"
+expectMatch 13.31 P "a\\U000012345x" "a\u12345x" "a\u12345x"
+expectMatch 13.32 P {a\U000012345x} "a\u12345x" "a\u12345x"
+expectMatch 13.33 P "a\\U1000000x" "a\ufffd0x" "a\ufffd0x"
+expectMatch 13.34 P {a\U1000000x} "a\ufffd0x" "a\ufffd0x"
+
+
+doing 14 "back references"
+# ugh
+expectMatch 14.1 RP {a(b*)c\1} abbcbb abbcbb bb
+expectMatch 14.2 RP {a(b*)c\1} ac ac ""
+expectNomatch 14.3 RP {a(b*)c\1} abbcb
+expectMatch 14.4 RP {a(b*)\1} abbcbb abb b
+expectMatch 14.5 RP {a(b|bb)\1} abbcbb abb b
+expectMatch 14.6 RP {a([bc])\1} abb abb b
+expectNomatch 14.7 RP {a([bc])\1} abc
+expectMatch 14.8 RP {a([bc])\1} abcabb abb b
+expectNomatch 14.9 RP {a([bc])*\1} abc
+expectNomatch 14.10 RP {a([bc])\1} abB
+expectMatch 14.11 iRP {a([bc])\1} abB abB b
+expectMatch 14.12 RP {a([bc])\1+} abbb abbb b
+expectMatch 14.13 QRP "a(\[bc])\\1{3,4}" abbbb abbbb b
+expectNomatch 14.14 QRP "a(\[bc])\\1{3,4}" abbb
+expectMatch 14.15 RP {a([bc])\1*} abbb abbb b
+expectMatch 14.16 RP {a([bc])\1*} ab ab b
+expectMatch 14.17 RP {a([bc])(\1*)} ab ab b ""
+expectError 14.18 - {a((b)\1)} ESUBREG
+expectError 14.19 - {a(b)c\2} ESUBREG
+expectMatch 14.20 bR {a\(b*\)c\1} abbcbb abbcbb bb
+expectMatch 14.21 RP {^([bc])\1*$} bbb bbb b
+expectMatch 14.22 RP {^([bc])\1*$} ccc ccc c
+knownBug expectNomatch 14.23 R {^([bc])\1*$} bcb
+
+
+doing 15 "octal escapes vs back references"
+# initial zero is always octal
+expectMatch 15.1 MP "a\\010b" "a\bb" "a\bb"
+expectMatch 15.2 MP "a\\0070b" "a\0070b" "a\0070b"
+expectMatch 15.3 MP "a\\07b" "a\007b" "a\007b"
+expectMatch 15.4 MP "a(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)\\07c" \
+ "abbbbbbbbbb\007c" abbbbbbbbbb\007c b b b b b b b b b b
+# a single digit is always a backref
+expectError 15.5 - {a\7b} ESUBREG
+# otherwise it's a backref only if within range (barf!)
+expectMatch 15.6 MP "a\\10b" "a\bb" "a\bb"
+expectMatch 15.7 MP {a\101b} aAb aAb
+expectMatch 15.8 RP {a(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)\10c} \
+ "abbbbbbbbbbbc" abbbbbbbbbbbc b b b b b b b b b b
+# but we're fussy about border cases -- guys who want octal should use the zero
+expectError 15.9 - {a((((((((((b\10))))))))))c} ESUBREG
+# BREs don't have octal, EREs don't have backrefs
+expectMatch 15.10 MP "a\\12b" "a\nb" "a\nb"
+expectError 15.11 b {a\12b} ESUBREG
+expectMatch 15.12 eAS {a\12b} a12b a12b
+expectMatch 15.13 MP {a\701b} a\u00381b a\u00381b
+
+
+doing 16 "expanded syntax"
+expectMatch 16.1 xP "a b c" "abc" "abc"
+expectMatch 16.2 xP "a b #oops\nc\td" "abcd" "abcd"
+expectMatch 16.3 x "a\\ b\\\tc" "a b\tc" "a b\tc"
+expectMatch 16.4 xP "a b\\#c" "ab#c" "ab#c"
+expectMatch 16.5 xP "a b\[c d]e" "ab e" "ab e"
+expectMatch 16.6 xP "a b\[c#d]e" "ab#e" "ab#e"
+expectMatch 16.7 xP "a b\[c#d]e" "abde" "abde"
+expectMatch 16.8 xSPB "ab{ d" "ab\{d" "ab\{d"
+expectMatch 16.9 xPQ "ab{ 1 , 2 }c" "abc" "abc"
+
+
+doing 17 "misc syntax"
+expectMatch 17.1 P a(?#comment)b ab ab
+
+
+doing 18 "unmatchable REs"
+expectNomatch 18.1 I a^b ab
+
+
+doing 19 "case independence"
+expectMatch 19.1 &i ab Ab Ab
+expectMatch 19.2 &i {a[bc]} aC aC
+expectNomatch 19.3 &i {a[^bc]} aB
+expectMatch 19.4 &iM {a[b-d]} aC aC
+expectNomatch 19.5 &iM {a[^b-d]} aC
+
+
+doing 20 "directors and embedded options"
+expectError 20.1 & ***? BADPAT
+expectMatch 20.2 q ***? ***? ***?
+expectMatch 20.3 &P ***=a*b a*b a*b
+expectMatch 20.4 q ***=a*b ***=a*b ***=a*b
+expectMatch 20.5 bLP {***:\w+} ab ab
+expectMatch 20.6 eLP {***:\w+} ab ab
+expectError 20.7 & ***:***=a*b BADRPT
+expectMatch 20.8 &P ***:(?b)a+b a+b a+b
+expectMatch 20.9 P (?b)a+b a+b a+b
+expectError 20.10 e {(?b)\w+} BADRPT
+expectMatch 20.11 bAS {(?b)\w+} (?b)w+ (?b)w+
+expectMatch 20.12 iP (?c)a a a
+expectNomatch 20.13 iP (?c)a A
+expectMatch 20.14 APS {(?e)\W+} WW WW
+expectMatch 20.15 P (?i)a+ Aa Aa
+expectNomatch 20.16 P "(?m)a.b" "a\nb"
+expectMatch 20.17 P "(?m)^b" "a\nb" "b"
+expectNomatch 20.18 P "(?n)a.b" "a\nb"
+expectMatch 20.19 P "(?n)^b" "a\nb" "b"
+expectNomatch 20.20 P "(?p)a.b" "a\nb"
+expectNomatch 20.21 P "(?p)^b" "a\nb"
+expectMatch 20.22 P (?q)a+b a+b a+b
+expectMatch 20.23 nP "(?s)a.b" "a\nb" "a\nb"
+expectMatch 20.24 xP "(?t)a b" "a b" "a b"
+expectMatch 20.25 P "(?w)a.b" "a\nb" "a\nb"
+expectMatch 20.26 P "(?w)^b" "a\nb" "b"
+expectMatch 20.27 P "(?x)a b" "ab" "ab"
+expectError 20.28 - (?z)ab BADOPT
+expectMatch 20.29 P (?ici)a+ Aa Aa
+expectError 20.30 P (?i)(?q)a+ BADRPT
+expectMatch 20.31 P (?q)(?i)a+ (?i)a+ (?i)a+
+expectMatch 20.32 P (?qe)a+ a a
+expectMatch 20.33 xP "(?q)a b" "a b" "a b"
+expectMatch 20.34 P "(?qx)a b" "a b" "a b"
+expectMatch 20.35 P (?qi)ab Ab Ab
+
+
+doing 21 "capturing"
+expectMatch 21.1 - a(b)c abc abc b
+expectMatch 21.2 P a(?:b)c xabc abc
+expectMatch 21.3 - a((b))c xabcy abc b b
+expectMatch 21.4 P a(?:(b))c abcy abc b
+expectMatch 21.5 P a((?:b))c abc abc b
+expectMatch 21.6 P a(?:(?:b))c abc abc
+expectIndices 21.7 Q "a(b){0}c" ac {0 1} {-1 -1}
+expectMatch 21.8 - a(b)c(d)e abcde abcde b d
+expectMatch 21.9 - (b)c(d)e bcde bcde b d
+expectMatch 21.10 - a(b)(d)e abde abde b d
+expectMatch 21.11 - a(b)c(d) abcd abcd b d
+expectMatch 21.12 - (ab)(cd) xabcdy abcd ab cd
+expectMatch 21.13 - a(b)?c xabcy abc b
+expectIndices 21.14 - a(b)?c xacy {1 2} {-1 -1}
+expectMatch 21.15 - a(b)?c(d)?e xabcdey abcde b d
+expectIndices 21.16 - a(b)?c(d)?e xacdey {1 4} {-1 -1} {3 3}
+expectIndices 21.17 - a(b)?c(d)?e xabcey {1 4} {2 2} {-1 -1}
+expectIndices 21.18 - a(b)?c(d)?e xacey {1 3} {-1 -1} {-1 -1}
+expectMatch 21.19 - a(b)*c xabcy abc b
+expectIndices 21.20 - a(b)*c xabbbcy {1 5} {4 4}
+expectIndices 21.21 - a(b)*c xacy {1 2} {-1 -1}
+expectMatch 21.22 - a(b*)c xabbbcy abbbc bbb
+expectMatch 21.23 - a(b*)c xacy ac ""
+expectNomatch 21.24 - a(b)+c xacy
+expectMatch 21.25 - a(b)+c xabcy abc b
+expectIndices 21.26 - a(b)+c xabbbcy {1 5} {4 4}
+expectMatch 21.27 - a(b+)c xabbbcy abbbc bbb
+expectIndices 21.28 Q "a(b){2,3}c" xabbbcy {1 5} {4 4}
+expectIndices 21.29 Q "a(b){2,3}c" xabbcy {1 4} {3 3}
+expectNomatch 21.30 Q "a(b){2,3}c" xabcy
+expectMatch 21.31 LP "\\y(\\w+)\\y" "-- abc-" "abc" "abc"
+expectMatch 21.32 - a((b|c)d+)+ abacdbd acdbd bd b
+expectMatch 21.33 N (.*).* abc abc abc
+expectMatch 21.34 N (a*)* bc "" ""
+
+
+doing 22 "multicharacter collating elements"
+# again ugh
+expectMatch 22.1 &+L {a[c]e} ace ace
+expectNomatch 22.2 &+IL {a[c]h} ach
+expectMatch 22.3 &+L {a[[.ch.]]} ach ach
+expectNomatch 22.4 &+L {a[[.ch.]]} ace
+expectMatch 22.5 &+L {a[c[.ch.]]} ac ac
+expectMatch 22.6 &+L {a[c[.ch.]]} ace ac
+expectMatch 22.7 &+L {a[c[.ch.]]} ache ach
+expectNomatch 22.8 &+L {a[^c]e} ace
+expectMatch 22.9 &+L {a[^c]e} abe abe
+expectMatch 22.10 &+L {a[^c]e} ache ache
+expectNomatch 22.11 &+L {a[^[.ch.]]} ach
+expectMatch 22.12 &+L {a[^[.ch.]]} ace ac
+expectMatch 22.13 &+L {a[^[.ch.]]} ac ac
+expectMatch 22.14 &+L {a[^[.ch.]]} abe ab
+expectNomatch 22.15 &+L {a[^c[.ch.]]} ach
+expectNomatch 22.16 &+L {a[^c[.ch.]]} ace
+expectNomatch 22.17 &+L {a[^c[.ch.]]} ac
+expectMatch 22.18 &+L {a[^c[.ch.]]} abe ab
+expectMatch 22.19 &+L {a[^b]} ac ac
+expectMatch 22.20 &+L {a[^b]} ace ac
+expectMatch 22.21 &+L {a[^b]} ach ach
+expectNomatch 22.22 &+L {a[^b]} abe
+
+
+doing 23 "lookahead constraints"
+expectMatch 23.1 HP a(?=b)b* ab ab
+expectNomatch 23.2 HP a(?=b)b* a
+expectMatch 23.3 HP a(?=b)b*(?=c)c* abc abc
+expectNomatch 23.4 HP a(?=b)b*(?=c)c* ab
+expectNomatch 23.5 HP a(?!b)b* ab
+expectMatch 23.6 HP a(?!b)b* a a
+expectMatch 23.7 HP (?=b)b b b
+expectNomatch 23.8 HP (?=b)b a
+
+
+doing 24 "non-greedy quantifiers"
+expectMatch 24.1 PT ab+? abb ab
+expectMatch 24.2 PT ab+?c abbc abbc
+expectMatch 24.3 PT ab*? abb a
+expectMatch 24.4 PT ab*?c abbc abbc
+expectMatch 24.5 PT ab?? ab a
+expectMatch 24.6 PT ab??c abc abc
+expectMatch 24.7 PQT "ab{2,4}?" abbbb abb
+expectMatch 24.8 PQT "ab{2,4}?c" abbbbc abbbbc
+expectMatch 24.9 - 3z* 123zzzz456 3zzzz
+expectMatch 24.10 PT 3z*? 123zzzz456 3
+expectMatch 24.11 - z*4 123zzzz456 zzzz4
+expectMatch 24.12 PT z*?4 123zzzz456 zzzz4
+
+
+doing 25 "mixed quantifiers"
+# this is very incomplete as yet
+# should include |
+expectMatch 25.1 PNT {^(.*?)(a*)$} "xyza" xyza xyz a
+expectMatch 25.2 PNT {^(.*?)(a*)$} "xyzaa" xyzaa xyz aa
+expectMatch 25.3 PNT {^(.*?)(a*)$} "xyz" xyz xyz ""
+
+
+doing 26 "tricky cases"
+# attempts to trick the matcher into accepting a short match
+expectMatch 26.1 - (week|wee)(night|knights) \
+ "weeknights" weeknights wee knights
+expectMatch 26.2 RP {a(bc*).*\1} abccbccb abccbccb b
+expectMatch 26.3 - {a(b.[bc]*)+} abcbd abcbd bd
+
+
+doing 27 "implementation misc."
+# duplicate arcs are suppressed
+expectMatch 27.1 P a(?:b|b)c abc abc
+# make color/subcolor relationship go back and forth
+expectMatch 27.2 & {[ab][ab][ab]} aba aba
+expectMatch 27.3 & {[ab][ab][ab][ab][ab][ab][ab]} \
+ "abababa" abababa
+
+
+doing 28 "boundary busters etc."
+# color-descriptor allocation changes at 10
+expectMatch 28.1 & abcdefghijkl "abcdefghijkl" abcdefghijkl
+# so does arc allocation
+expectMatch 28.2 P a(?:b|c|d|e|f|g|h|i|j|k|l|m)n "agn" agn
+# subexpression tracking also at 10
+expectMatch 28.3 - a(((((((((((((b)))))))))))))c \
+ "abc" abc b b b b b b b b b b b b b
+# state-set handling changes slightly at unsigned size (might be 64...)
+# (also stresses arc allocation)
+expectMatch 28.4 Q "ab{1,100}c" abbc abbc
+expectMatch 28.5 Q "ab{1,100}c" \
+ "abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc" \
+ abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc
+expectMatch 28.6 Q "ab{1,100}c" \
+ "abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc"\
+ abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc
+# force small cache and bust it, several ways
+expectMatch 28.7 LP {\w+abcdefgh} xyzabcdefgh xyzabcdefgh
+expectMatch 28.8 %LP {\w+abcdefgh} xyzabcdefgh xyzabcdefgh
+expectMatch 28.9 %LP {\w+abcdefghijklmnopqrst} \
+ "xyzabcdefghijklmnopqrst" xyzabcdefghijklmnopqrst
+expectIndices 28.10 %LP {\w+(abcdefgh)?} xyz {0 2} {-1 -1}
+expectIndices 28.11 %LP {\w+(abcdefgh)?} xyzabcdefg {0 9} {-1 -1}
+expectIndices 28.12 %LP {\w+(abcdefghijklmnopqrst)?} \
+ "xyzabcdefghijklmnopqrs" {0 21} {-1 -1}
+
+
+doing 29 "incomplete matches"
+expectPartial 29.1 t def abc {3 2} ""
+expectPartial 29.2 t bcd abc {1 2} ""
+expectPartial 29.3 t abc abab {0 3} ""
+expectPartial 29.4 t abc abdab {3 4} ""
+expectIndices 29.5 t abc abc {0 2} {0 2}
+expectIndices 29.6 t abc xyabc {2 4} {2 4}
+expectPartial 29.7 t abc+ xyab {2 3} ""
+expectIndices 29.8 t abc+ xyabc {2 4} {2 4}
+knownBug expectIndices 29.9 t abc+ xyabcd {2 4} {6 5}
+expectIndices 29.10 t abc+ xyabcdd {2 4} {7 6}
+expectPartial 29.11 tPT abc+? xyab {2 3} ""
+# the retain numbers in these two may look wrong, but they aren't
+expectIndices 29.12 tPT abc+? xyabc {2 4} {5 4}
+expectIndices 29.13 tPT abc+? xyabcc {2 4} {6 5}
+expectIndices 29.14 tPT abc+? xyabcd {2 4} {6 5}
+expectIndices 29.15 tPT abc+? xyabcdd {2 4} {7 6}
+expectIndices 29.16 t abcd|bc xyabc {3 4} {2 4}
+expectPartial 29.17 tn .*k "xx\nyyy" {3 5} ""
+
+
+doing 30 "misc. oddities and old bugs"
+expectError 30.1 & *** BADRPT
+expectMatch 30.2 N a?b* abb abb
+expectMatch 30.3 N a?b* bb bb
+expectMatch 30.4 & a*b aab aab
+expectMatch 30.5 & ^a*b aaaab aaaab
+expectMatch 30.6 &M {[0-6][1-2][0-3][0-6][1-6][0-6]} \
+ "010010" 010010
+# temporary REG_BOSONLY kludge
+expectMatch 30.7 s abc abcd abc
+expectNomatch 30.8 s abc xabcd
+# back to normal stuff
+expectMatch 30.9 HLP {(?n)^(?![t#])\S+} \
+ "tk\n\n#\n#\nit0" it0
+
+
+# Now for tests *not* written by Henry Spencer
+
+namespace import -force ::tcltest::test
+
+# Tests resulting from bugs reported by users
+test reg-31.1 {[[:xdigit:]] behaves correctly when followed by [[:space:]]} {
+ set str {2:::DebugWin32}
+ set re {([[:xdigit:]])([[:space:]]*)}
+ list [regexp $re $str match xdigit spaces] $match $xdigit $spaces
+ # Code used to produce {1 2:::DebugWin32 2 :::DebugWin32} !!!
+} {1 2 2 {}}
+
+test reg-32.1 {canmatch functionality -- at end} testregexp {
+ set pat {blah}
+ set line "asd asd"
+ # can match at the final d, if '%' follows
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 7}
+test reg-32.2 {canmatch functionality -- at end} testregexp {
+ set pat {s%$}
+ set line "asd asd"
+ # can only match after the end of the string
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 7}
+test reg-32.3 {canmatch functionality -- not last char} testregexp {
+ set pat {[^d]%$}
+ set line "asd asd"
+ # can only match after the end of the string
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 7}
+test reg-32.3.1 {canmatch functionality -- no match} testregexp {
+ set pat {\Zx}
+ set line "asd asd"
+ # can match the last char, if followed by x
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 -1}
+test reg-32.4 {canmatch functionality -- last char} {knownBug testregexp} {
+ set pat {.x}
+ set line "asd asd"
+ # can match the last char, if followed by x
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+test reg-32.4.1 {canmatch functionality -- last char} {knownBug testregexp} {
+ set pat {.x$}
+ set line "asd asd"
+ # can match the last char, if followed by x
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+test reg-32.5 {canmatch functionality -- last char} {knownBug testregexp} {
+ set pat {.[^d]x$}
+ set line "asd asd"
+ # can match the last char, if followed by not-d and x.
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+test reg-32.6 {canmatch functionality -- last char} {knownBug testregexp} {
+ set pat {[^a]%[^\r\n]*$}
+ set line "asd asd"
+ # can match at the final d, if '%' follows
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+test reg-32.7 {canmatch functionality -- last char} {knownBug testregexp} {
+ set pat {[^a]%$}
+ set line "asd asd"
+ # can match at the final d, if '%' follows
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+test reg-32.8 {canmatch functionality -- last char} {knownBug testregexp} {
+ set pat {[^x]%$}
+ set line "asd asd"
+ # can match at the final d, if '%' follows
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+test reg-32.9 {canmatch functionality -- more complex case} {knownBug testregexp} {
+ set pat {((\B\B|\Bh+line)[ \t]*|[^\B]%[^\r\n]*)$}
+ set line "asd asd"
+ # can match at the final d, if '%' follows
+ set res [testregexp -xflags -- c $pat $line resvar]
+ lappend res $resvar
+} {0 6}
+
+# Tests reg-33.*: Checks for bug fixes
+
+test reg-33.1 {Bug 230589} {
+ regexp {[ ]*(^|[^%])%V} "*%V2" m s
+} 1
+test reg-33.2 {Bug 504785} {
+ regexp -inline {([^_.]*)([^.]*)\.(..)(.).*} bbcos_001_c01.q1la
+} {bbcos_001_c01.q1la bbcos _001_c01 q1 l}
+test reg-33.3 {Bug 505048} {
+ regexp {\A\s*[^<]*\s*<([^>]+)>} a<a>
+} 1
+test reg-33.4 {Bug 505048} {
+ regexp {\A\s*([^b]*)b} ab
+} 1
+test reg-33.5 {Bug 505048} {
+ regexp {\A\s*[^b]*(b)} ab
+} 1
+test reg-33.6 {Bug 505048} {
+ regexp {\A(\s*)[^b]*(b)} ab
+} 1
+test reg-33.7 {Bug 505048} {
+ regexp {\A\s*[^b]*b} ab
+} 1
+test reg-33.8 {Bug 505048} {
+ regexp -inline {\A\s*[^b]*b} ab
+} ab
+test reg-33.9 {Bug 505048} {
+ regexp -indices -inline {\A\s*[^b]*b} ab
+} {{0 1}}
+test reg-33.10 {Bug 840258} -body {
+ regsub {(^|\n)+\.*b} \n.b {} tmp
+} -cleanup {
+ unset tmp
+} -result 1
+test reg-33.11 {Bug 840258} -body {
+ regsub {(^|[\n\r]+)\.*\?<.*?(\n|\r)+} \
+ "TQ\r\n.?<5000267>Test already stopped\r\n" {} tmp
+} -cleanup {
+ unset tmp
+} -result 1
+test reg-33.12 {Bug 1810264 - bad read} {
+ regexp {\3161573148} {\3161573148}
+} 0
+test reg-33.13 {Bug 1810264 - infinite loop} {
+ regexp {($|^)*} {x}
+} 1
+# Some environments have small default stack sizes. [Bug 1905562]
+test reg-33.14 {Bug 1810264 - super-expensive expression} nonPortable {
+ regexp {(x{200}){200}$y} {x}
+} 0
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/regexp.test b/pkgs/msgcat/tests/regexp.test
new file mode 100644
index 0000000..7cafd1b
--- /dev/null
+++ b/pkgs/msgcat/tests/regexp.test
@@ -0,0 +1,1072 @@
+# Commands covered: regexp, regsub
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1998 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+unset -nocomplain foo
+
+testConstraint exec [llength [info commands exec]]
+
+test regexp-1.1 {basic regexp operation} {
+ regexp ab*c abbbc
+} 1
+test regexp-1.2 {basic regexp operation} {
+ regexp ab*c ac
+} 1
+test regexp-1.3 {basic regexp operation} {
+ regexp ab*c ab
+} 0
+test regexp-1.4 {basic regexp operation} {
+ regexp -- -gorp abc-gorpxxx
+} 1
+test regexp-1.5 {basic regexp operation} {
+ regexp {^([^ ]*)[ ]*([^ ]*)} "" a
+} 1
+test regexp-1.6 {basic regexp operation} {
+ list [catch {regexp {} abc} msg] $msg
+} {0 1}
+test regexp-1.7 {regexp utf compliance} {
+ # if not UTF-8 aware, result is "0 1"
+ set foo "\u4e4eb q"
+ regexp "\u4e4eb q" "a\u4e4eb qw\u5e4e\x4e wq" bar
+ list [string compare $foo $bar] [regexp 4 $bar]
+} {0 0}
+test regexp-1.8 {regexp ***= metasyntax} {
+ regexp -- "***=o" "aeiou"
+} 1
+test regexp-1.9 {regexp ***= metasyntax} {
+ set string "aeiou"
+ regexp -- "***=o" $string
+} 1
+test regexp-1.10 {regexp ***= metasyntax} {
+ set string "aeiou"
+ set re "***=o"
+ regexp -- $re $string
+} 1
+test regexp-1.11 {regexp ***= metasyntax} {
+ regexp -- "***=y" "aeiou"
+} 0
+test regexp-1.12 {regexp ***= metasyntax} {
+ set string "aeiou"
+ regexp -- "***=y" $string
+} 0
+test regexp-1.13 {regexp ***= metasyntax} {
+ set string "aeiou"
+ set re "***=y"
+ regexp -- $re $string
+} 0
+
+test regexp-2.1 {getting substrings back from regexp} {
+ set foo {}
+ list [regexp ab*c abbbbc foo] $foo
+} {1 abbbbc}
+test regexp-2.2 {getting substrings back from regexp} {
+ set foo {}
+ set f2 {}
+ list [regexp a(b*)c abbbbc foo f2] $foo $f2
+} {1 abbbbc bbbb}
+test regexp-2.3 {getting substrings back from regexp} {
+ set foo {}
+ set f2 {}
+ list [regexp a(b*)(c) abbbbc foo f2] $foo $f2
+} {1 abbbbc bbbb}
+test regexp-2.4 {getting substrings back from regexp} {
+ set foo {}
+ set f2 {}
+ set f3 {}
+ list [regexp a(b*)(c) abbbbc foo f2 f3] $foo $f2 $f3
+} {1 abbbbc bbbb c}
+test regexp-2.5 {getting substrings back from regexp} {
+ set foo {}; set f1 {}; set f2 {}; set f3 {}; set f4 {}; set f5 {};
+ set f6 {}; set f7 {}; set f8 {}; set f9 {}; set fa {}; set fb {};
+ list [regexp (1*)(2*)(3*)(4*)(5*)(6*)(7*)(8*)(9*)(a*)(b*) \
+ 12223345556789999aabbb \
+ foo f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb] $foo $f1 $f2 $f3 $f4 $f5 \
+ $f6 $f7 $f8 $f9 $fa $fb
+} {1 12223345556789999aabbb 1 222 33 4 555 6 7 8 9999 aa bbb}
+test regexp-2.6 {getting substrings back from regexp} {
+ set foo 2; set f2 2; set f3 2; set f4 2
+ list [regexp (a)(b)? xay foo f2 f3 f4] $foo $f2 $f3 $f4
+} {1 a a {} {}}
+test regexp-2.7 {getting substrings back from regexp} {
+ set foo 1; set f2 1; set f3 1; set f4 1
+ list [regexp (a)(b)?(c) xacy foo f2 f3 f4] $foo $f2 $f3 $f4
+} {1 ac a {} c}
+test regexp-2.8 {getting substrings back from regexp} {
+ set match {}
+ list [regexp {^a*b} aaaab match] $match
+} {1 aaaab}
+test regexp-2.9 {getting substrings back from regexp} {
+ set foo {}
+ set f2 {}
+ list [regexp f\352te(b*)c f\352tebbbbc foo f2] $foo $f2
+} [list 1 f\352tebbbbc bbbb]
+test regexp-2.10 {getting substrings back from regexp} {
+ set foo {}
+ set f2 {}
+ list [regexp f\352te(b*)c eff\352tebbbbc foo f2] $foo $f2
+} [list 1 f\352tebbbbc bbbb]
+test regexp-2.11 {non-capturing subgroup} {
+ set foo {}
+ set f2 {}
+ list [regexp {str(?:a+)} straa foo f2] $foo $f2
+} [list 1 straa {}]
+test regexp-2.12 {non-capturing subgroup with -inline} {
+ regexp -inline {str(?:a+)} straa
+} {straa}
+test regexp-2.13 {non-capturing and capturing subgroups} {
+ set foo {}
+ set f2 {}
+ set f3 {}
+ list [regexp {str(?:a+)(c+)} straacc foo f2 f3] $foo $f2 $f3
+} [list 1 straacc cc {}]
+test regexp-2.14 {non-capturing and capturing subgroups} {
+ regexp -inline {str(?:a+)(c+)} straacc
+} {straacc cc}
+test regexp-2.15 {getting substrings back from regexp} {
+ set foo NA
+ set f2 NA
+ list [regexp {str(?:a+)} straa foo f2] $foo $f2
+} [list 1 straa {}]
+
+test regexp-3.1 {-indices option to regexp} {
+ set foo {}
+ list [regexp -indices ab*c abbbbc foo] $foo
+} {1 {0 5}}
+test regexp-3.2 {-indices option to regexp} {
+ set foo {}
+ set f2 {}
+ list [regexp -indices a(b*)c abbbbc foo f2] $foo $f2
+} {1 {0 5} {1 4}}
+test regexp-3.3 {-indices option to regexp} {
+ set foo {}
+ set f2 {}
+ list [regexp -indices a(b*)(c) abbbbc foo f2] $foo $f2
+} {1 {0 5} {1 4}}
+test regexp-3.4 {-indices option to regexp} {
+ set foo {}
+ set f2 {}
+ set f3 {}
+ list [regexp -indices a(b*)(c) abbbbc foo f2 f3] $foo $f2 $f3
+} {1 {0 5} {1 4} {5 5}}
+test regexp-3.5 {-indices option to regexp} {
+ set foo {}; set f1 {}; set f2 {}; set f3 {}; set f4 {}; set f5 {};
+ set f6 {}; set f7 {}; set f8 {}; set f9 {}
+ list [regexp -indices (1*)(2*)(3*)(4*)(5*)(6*)(7*)(8*)(9*) \
+ 12223345556789999 \
+ foo f1 f2 f3 f4 f5 f6 f7 f8 f9] $foo $f1 $f2 $f3 $f4 $f5 \
+ $f6 $f7 $f8 $f9
+} {1 {0 16} {0 0} {1 3} {4 5} {6 6} {7 9} {10 10} {11 11} {12 12} {13 16}}
+test regexp-3.6 {getting substrings back from regexp} {
+ set foo 2; set f2 2; set f3 2; set f4 2
+ list [regexp -indices (a)(b)? xay foo f2 f3 f4] $foo $f2 $f3 $f4
+} {1 {1 1} {1 1} {-1 -1} {-1 -1}}
+test regexp-3.7 {getting substrings back from regexp} {
+ set foo 1; set f2 1; set f3 1; set f4 1
+ list [regexp -indices (a)(b)?(c) xacy foo f2 f3 f4] $foo $f2 $f3 $f4
+} {1 {1 2} {1 1} {-1 -1} {2 2}}
+
+test regexp-4.1 {-nocase option to regexp} {
+ regexp -nocase foo abcFOo
+} 1
+test regexp-4.2 {-nocase option to regexp} {
+ set f1 22
+ set f2 33
+ set f3 44
+ list [regexp -nocase {a(b*)([xy]*)z} aBbbxYXxxZ22 f1 f2 f3] $f1 $f2 $f3
+} {1 aBbbxYXxxZ Bbb xYXxx}
+test regexp-4.3 {-nocase option to regexp} {
+ regexp -nocase FOo abcFOo
+} 1
+set x abcdefghijklmnopqrstuvwxyz1234567890
+set x $x$x$x$x$x$x$x$x$x$x$x$x
+test regexp-4.4 {case conversion in regexp} {
+ list [regexp -nocase $x $x foo] $foo
+} "1 $x"
+unset -nocomplain x
+
+test regexp-5.1 {exercise cache of compiled expressions} {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*a bbba
+} 1
+test regexp-5.2 {exercise cache of compiled expressions} {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*b xxxb
+} 1
+test regexp-5.3 {exercise cache of compiled expressions} {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*c yyyc
+} 1
+test regexp-5.4 {exercise cache of compiled expressions} {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*d 1d
+} 1
+test regexp-5.5 {exercise cache of compiled expressions} {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*e xe
+} 1
+
+test regexp-6.1 {regexp errors} {
+ list [catch {regexp a} msg] $msg
+} {1 {wrong # args: should be "regexp ?-switch ...? exp string ?matchVar? ?subMatchVar ...?"}}
+test regexp-6.2 {regexp errors} {
+ list [catch {regexp -nocase a} msg] $msg
+} {1 {wrong # args: should be "regexp ?-switch ...? exp string ?matchVar? ?subMatchVar ...?"}}
+test regexp-6.3 {regexp errors} {
+ list [catch {regexp -gorp a} msg] $msg
+} {1 {bad switch "-gorp": must be -all, -about, -indices, -inline, -expanded, -line, -linestop, -lineanchor, -nocase, -start, or --}}
+test regexp-6.4 {regexp errors} {
+ list [catch {regexp a( b} msg] $msg
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexp-6.5 {regexp errors} {
+ list [catch {regexp a( b} msg] $msg
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexp-6.6 {regexp errors} {
+ list [catch {regexp a a f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1} msg] $msg
+} {0 1}
+test regexp-6.7 {regexp errors} {
+ list [catch {regexp (x)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.) xyzzy} msg] $msg
+} {0 0}
+test regexp-6.8 {regexp errors} -setup {
+ unset -nocomplain f1
+} -body {
+ set f1 44
+ regexp abc abc f1(f2)
+} -returnCodes error -result {can't set "f1(f2)": variable isn't array}
+test regexp-6.9 {regexp errors, -start bad int check} {
+ list [catch {regexp -start bogus {^$} {}} msg] $msg
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
+test regexp-6.10 {regexp errors} {
+ list [catch {regexp {a[} b} msg] $msg
+} {1 {couldn't compile regular expression pattern: brackets [] not balanced}}
+
+test regexp-7.1 {basic regsub operation} {
+ list [regsub aa+ xaxaaaxaa 111&222 foo] $foo
+} {1 xax111aaa222xaa}
+test regexp-7.2 {basic regsub operation} {
+ list [regsub aa+ aaaxaa &111 foo] $foo
+} {1 aaa111xaa}
+test regexp-7.3 {basic regsub operation} {
+ list [regsub aa+ xaxaaa 111& foo] $foo
+} {1 xax111aaa}
+test regexp-7.4 {basic regsub operation} {
+ list [regsub aa+ aaa 11&2&333 foo] $foo
+} {1 11aaa2aaa333}
+test regexp-7.5 {basic regsub operation} {
+ list [regsub aa+ xaxaaaxaa &2&333 foo] $foo
+} {1 xaxaaa2aaa333xaa}
+test regexp-7.6 {basic regsub operation} {
+ list [regsub aa+ xaxaaaxaa 1&22& foo] $foo
+} {1 xax1aaa22aaaxaa}
+test regexp-7.7 {basic regsub operation} {
+ list [regsub a(a+) xaxaaaxaa {1\122\1} foo] $foo
+} {1 xax1aa22aaxaa}
+test regexp-7.8 {basic regsub operation} {
+ list [regsub a(a+) xaxaaaxaa {1\\\122\1} foo] $foo
+} "1 {xax1\\aa22aaxaa}"
+test regexp-7.9 {basic regsub operation} {
+ list [regsub a(a+) xaxaaaxaa {1\\122\1} foo] $foo
+} "1 {xax1\\122aaxaa}"
+test regexp-7.10 {basic regsub operation} {
+ list [regsub a(a+) xaxaaaxaa {1\\&\1} foo] $foo
+} "1 {xax1\\aaaaaxaa}"
+test regexp-7.11 {basic regsub operation} {
+ list [regsub a(a+) xaxaaaxaa {1\&\1} foo] $foo
+} {1 xax1&aaxaa}
+test regexp-7.12 {basic regsub operation} {
+ list [regsub a(a+) xaxaaaxaa {\1\1\1\1&&} foo] $foo
+} {1 xaxaaaaaaaaaaaaaaxaa}
+test regexp-7.13 {basic regsub operation} {
+ set foo xxx
+ list [regsub abc xyz 111 foo] $foo
+} {0 xyz}
+test regexp-7.14 {basic regsub operation} {
+ set foo xxx
+ list [regsub ^ xyz "111 " foo] $foo
+} {1 {111 xyz}}
+test regexp-7.15 {basic regsub operation} {
+ set foo xxx
+ list [regsub -- -foo abc-foodef "111 " foo] $foo
+} {1 {abc111 def}}
+test regexp-7.16 {basic regsub operation} {
+ set foo xxx
+ list [regsub x "" y foo] $foo
+} {0 {}}
+test regexp-7.17 {regsub utf compliance} {
+ # if not UTF-8 aware, result is "0 1"
+ set foo "xyz555ijka\u4e4ebpqr"
+ regsub a\u4e4eb xyza\u4e4ebijka\u4e4ebpqr 555 bar
+ list [string compare $foo $bar] [regexp 4 $bar]
+} {0 0}
+test regexp-7.18 {basic regsub replacement} {
+ list [regsub a+ aaa {&} foo] $foo
+} {1 aaa}
+test regexp-7.19 {basic regsub replacement} {
+ list [regsub a+ aaa {\&} foo] $foo
+} {1 &}
+test regexp-7.20 {basic regsub replacement} {
+ list [regsub a+ aaa {\\&} foo] $foo
+} {1 {\aaa}}
+test regexp-7.21 {basic regsub replacement} {
+ list [regsub a+ aaa {\\\&} foo] $foo
+} {1 {\&}}
+test regexp-7.22 {basic regsub replacement} {
+ list [regsub a+ aaa {\0} foo] $foo
+} {1 aaa}
+test regexp-7.23 {basic regsub replacement} {
+ list [regsub a+ aaa {\\0} foo] $foo
+} {1 {\0}}
+test regexp-7.24 {basic regsub replacement} {
+ list [regsub a+ aaa {\\\0} foo] $foo
+} {1 {\aaa}}
+test regexp-7.25 {basic regsub replacement} {
+ list [regsub a+ aaa {\\\\0} foo] $foo
+} {1 {\\0}}
+test regexp-7.26 {dollar zero is not a backslash replacement} {
+ list [regsub a+ aaa {$0} foo] $foo
+} {1 {$0}}
+test regexp-7.27 {dollar zero is not a backslash replacement} {
+ list [regsub a+ aaa {\0$0} foo] $foo
+} {1 {aaa$0}}
+test regexp-7.28 {dollar zero is not a backslash replacement} {
+ list [regsub a+ aaa {\$0} foo] $foo
+} {1 {\$0}}
+test regexp-7.29 {dollar zero is not a backslash replacement} {
+ list [regsub a+ aaa {\\} foo] $foo
+} {1 \\}
+
+test regexp-8.1 {case conversion in regsub} {
+ list [regsub -nocase a(a+) xaAAaAAay & foo] $foo
+} {1 xaAAaAAay}
+test regexp-8.2 {case conversion in regsub} {
+ list [regsub -nocase a(a+) xaAAaAAay & foo] $foo
+} {1 xaAAaAAay}
+test regexp-8.3 {case conversion in regsub} {
+ set foo 123
+ list [regsub a(a+) xaAAaAAay & foo] $foo
+} {0 xaAAaAAay}
+test regexp-8.4 {case conversion in regsub} {
+ set foo 123
+ list [regsub -nocase a CaDE b foo] $foo
+} {1 CbDE}
+test regexp-8.5 {case conversion in regsub} {
+ set foo 123
+ list [regsub -nocase XYZ CxYzD b foo] $foo
+} {1 CbD}
+test regexp-8.6 {case conversion in regsub} {
+ set x abcdefghijklmnopqrstuvwxyz1234567890
+ set x $x$x$x$x$x$x$x$x$x$x$x$x
+ set foo 123
+ list [regsub -nocase $x $x b foo] $foo
+} {1 b}
+
+test regexp-9.1 {-all option to regsub} {
+ set foo 86
+ list [regsub -all x+ axxxbxxcxdx |&| foo] $foo
+} {4 a|xxx|b|xx|c|x|d|x|}
+test regexp-9.2 {-all option to regsub} {
+ set foo 86
+ list [regsub -nocase -all x+ aXxXbxxcXdx |&| foo] $foo
+} {4 a|XxX|b|xx|c|X|d|x|}
+test regexp-9.3 {-all option to regsub} {
+ set foo 86
+ list [regsub x+ axxxbxxcxdx |&| foo] $foo
+} {1 a|xxx|bxxcxdx}
+test regexp-9.4 {-all option to regsub} {
+ set foo 86
+ list [regsub -all bc axxxbxxcxdx |&| foo] $foo
+} {0 axxxbxxcxdx}
+test regexp-9.5 {-all option to regsub} {
+ set foo xxx
+ list [regsub -all node "node node more" yy foo] $foo
+} {2 {yy yy more}}
+test regexp-9.6 {-all option to regsub} {
+ set foo xxx
+ list [regsub -all ^ xxx 123 foo] $foo
+} {1 123xxx}
+
+test regexp-10.1 {expanded syntax in regsub} {
+ set foo xxx
+ list [regsub -expanded ". \#comment\n . \#comment2" abc def foo] $foo
+} {1 defc}
+test regexp-10.2 {newline sensitivity in regsub} {
+ set foo xxx
+ list [regsub -line {^a.*b$} "dabc\naxyb\n" 123 foo] $foo
+} "1 {dabc\n123\n}"
+test regexp-10.3 {newline sensitivity in regsub} {
+ set foo xxx
+ list [regsub -line {^a.*b$} "dabc\naxyb\nxb" 123 foo] $foo
+} "1 {dabc\n123\nxb}"
+test regexp-10.4 {partial newline sensitivity in regsub} {
+ set foo xxx
+ list [regsub -lineanchor {^a.*b$} "da\naxyb\nxb" 123 foo] $foo
+} "1 {da\n123}"
+test regexp-10.5 {inverse partial newline sensitivity in regsub} {
+ set foo xxx
+ list [regsub -linestop {a.*b} "da\nbaxyb\nxb" 123 foo] $foo
+} "1 {da\nb123\nxb}"
+
+test regexp-11.1 {regsub errors} {
+ list [catch {regsub a b} msg] $msg
+} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}}
+test regexp-11.2 {regsub errors} {
+ list [catch {regsub -nocase a b} msg] $msg
+} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}}
+test regexp-11.3 {regsub errors} {
+ list [catch {regsub -nocase -all a b} msg] $msg
+} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}}
+test regexp-11.4 {regsub errors} {
+ list [catch {regsub a b c d e f} msg] $msg
+} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}}
+test regexp-11.5 {regsub errors} {
+ list [catch {regsub -gorp a b c} msg] $msg
+} {1 {bad switch "-gorp": must be -all, -nocase, -expanded, -line, -linestop, -lineanchor, -start, or --}}
+test regexp-11.6 {regsub errors} {
+ list [catch {regsub -nocase a( b c d} msg] $msg
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexp-11.7 {regsub errors} -setup {
+ unset -nocomplain f1
+} -body {
+ set f1 44
+ regsub -nocase aaa aaa xxx f1(f2)
+} -returnCodes error -result {can't set "f1(f2)": variable isn't array}
+test regexp-11.8 {regsub errors, -start bad int check} {
+ list [catch {regsub -start bogus pattern string rep var} msg] $msg
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
+test regexp-11.9 {regsub without final variable name returns value} {
+ regsub b abaca X
+} {aXaca}
+test regexp-11.10 {regsub without final variable name returns value} {
+ regsub -all a abaca X
+} {XbXcX}
+test regexp-11.11 {regsub without final variable name returns value} {
+ regsub b(.*?)d abcdeabcfde {,&,\1,}
+} {a,bcd,c,eabcfde}
+test regexp-11.12 {regsub without final variable name returns value} {
+ regsub -all b(.*?)d abcdeabcfde {,&,\1,}
+} {a,bcd,c,ea,bcfd,cf,e}
+
+# This test crashes on the Mac unless you increase the Stack Space to about 1
+# Meg. This is probably bigger than most users want...
+# 8.2.3 regexp reduced stack space requirements, but this should be
+# tested again
+test regexp-12.1 {Tcl_RegExpExec: large number of subexpressions} {macCrash} {
+ list [regexp (.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.) abcdefghijklmnopqrstuvwxyz all a b c d e f g h i j k l m n o p q r s t u v w x y z] $all $a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z
+} {1 abcdefghijklmnopqrstuvwxyz a b c d e f g h i j k l m n o p q r s t u v w x y z}
+
+test regexp-13.1 {regsub of a very large string} {
+ # This test is designed to stress the memory subsystem in order to catch
+ # Bug #933. It only fails if the Tcl memory allocator is in use.
+ set line {BEGIN_TABLE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; END_TABLE}
+ set filedata [string repeat $line 200]
+ for {set i 1} {$i<10} {incr i} {
+ regsub -all "BEGIN_TABLE " $filedata "" newfiledata
+ }
+ set x done
+} {done}
+
+test regexp-14.1 {CompileRegexp: regexp cache} {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ set x .
+ append x *a
+ regexp $x bbba
+} 1
+test regexp-14.2 {CompileRegexp: regexp cache, different flags} {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ set x .
+ append x *a
+ regexp -nocase $x bbba
+} 1
+test regexp-14.3 {CompileRegexp: regexp cache, empty regexp and empty cache} -constraints {
+ exec
+} -setup {
+ set junk [makeFile {puts [regexp {} foo]} junk.tcl]
+} -body {
+ exec [interpreter] $junk
+} -cleanup {
+ removeFile junk.tcl
+} -result 1
+
+test regexp-15.1 {regexp -start} {
+ unset -nocomplain x
+ list [regexp -start -10 {\d} 1abc2de3 x] $x
+} {1 1}
+test regexp-15.2 {regexp -start} {
+ unset -nocomplain x
+ list [regexp -start 2 {\d} 1abc2de3 x] $x
+} {1 2}
+test regexp-15.3 {regexp -start} {
+ unset -nocomplain x
+ list [regexp -start 4 {\d} 1abc2de3 x] $x
+} {1 2}
+test regexp-15.4 {regexp -start} {
+ unset -nocomplain x
+ list [regexp -start 5 {\d} 1abc2de3 x] $x
+} {1 3}
+test regexp-15.5 {regexp -start, over end of string} {
+ unset -nocomplain x
+ list [regexp -start [string length 1abc2de3] {\d} 1abc2de3 x] [info exists x]
+} {0 0}
+test regexp-15.6 {regexp -start, loss of ^$ behavior} {
+ list [regexp -start 2 {^$} {}]
+} {0}
+test regexp-15.7 {regexp -start, double option} {
+ regexp -start 2 -start 0 a abc
+} 1
+test regexp-15.8 {regexp -start, double option} {
+ regexp -start 0 -start 2 a abc
+} 0
+test regexp-15.9 {regexp -start, end relative index} {
+ unset -nocomplain x
+ list [regexp -start end {\d} 1abc2de3 x] [info exists x]
+} {0 0}
+test regexp-15.10 {regexp -start, end relative index} {
+ unset -nocomplain x
+ list [regexp -start end-1 {\d} 1abc2de3 x] [info exists x] $x
+} {1 1 3}
+test regexp-15.11 {regexp -start, over end of string} {
+ set x NA
+ list [regexp -start 2 {.*} ab x] $x
+} {1 {}}
+
+test regexp-16.1 {regsub -start} {
+ unset -nocomplain x
+ list [regsub -all -start 2 {\d} a1b2c3d4e5 {/&} x] $x
+} {4 a1b/2c/3d/4e/5}
+test regexp-16.2 {regsub -start} {
+ unset -nocomplain x
+ list [regsub -all -start -25 {z} hello {/&} x] $x
+} {0 hello}
+test regexp-16.3 {regsub -start} {
+ unset -nocomplain x
+ list [regsub -all -start 3 {z} hello {/&} x] $x
+} {0 hello}
+test regexp-16.4 {regsub -start, \A behavior} {
+ set out {}
+ lappend out [regsub -start 0 -all {\A(\w)} {abcde} {/\1} x] $x
+ lappend out [regsub -start 2 -all {\A(\w)} {abcde} {/\1} x] $x
+} {5 /a/b/c/d/e 3 ab/c/d/e}
+test regexp-16.5 {regsub -start, double option} {
+ list [regsub -start 2 -start 0 a abc c x] $x
+} {1 cbc}
+test regexp-16.6 {regsub -start, double option} {
+ list [regsub -start 0 -start 2 a abc c x] $x
+} {0 abc}
+test regexp-16.7 {regexp -start, end relative index} {
+ list [regsub -start end a aaa b x] $x
+} {0 aaa}
+test regexp-16.8 {regexp -start, end relative index} {
+ list [regsub -start end-1 a aaa b x] $x
+} {1 aab}
+test regexp-16.9 {regsub -start and -all} {
+ set foo {}
+ list [regsub -start 0 -all x+ axxxbxx |&| foo] $foo
+} {2 a|xxx|b|xx|}
+test regexp-16.10 {regsub -start and -all} {
+ set foo {}
+ list [regsub -start 1 -all x+ axxxbxx |&| foo] $foo
+} {2 a|xxx|b|xx|}
+test regexp-16.11 {regsub -start and -all} {
+ set foo {}
+ list [regsub -start 4 -all x+ axxxbxx |&| foo] $foo
+} {1 axxxb|xx|}
+test regexp-16.12 {regsub -start} {
+ set foo {}
+ list [regsub -start 4 x+ axxxbxx |&| foo] $foo
+} {1 axxxb|xx|}
+test regexp-16.13 {regsub -start and -all} {
+ set foo {}
+ list [regsub -start 1 -all a+ "" & foo] $foo
+} {0 {}}
+test regexp-16.14 {regsub -start} {
+ set foo {}
+ list [regsub -start 1 a+ "" & foo] $foo
+} {0 {}}
+test regexp-16.15 {regsub -start and -all} {
+ set foo {}
+ list [regsub -start 2 -all a+ "xy" & foo] $foo
+} {0 xy}
+test regexp-16.16 {regsub -start} {
+ set foo {}
+ list [regsub -start 2 a+ "xy" & foo] $foo
+} {0 xy}
+test regexp-16.17 {regsub -start and -all} {
+ set foo {}
+ list [regsub -start 1 -all y+ "xy" & foo] $foo
+} {1 xy}
+test regexp-16.18 {regsub -start} {
+ set foo {}
+ list [regsub -start 1 y+ "xy" & foo] $foo
+} {1 xy}
+test regexp-16.19 {regsub -start} {
+ set foo {}
+ list [regsub -start -1 a+ "" & foo] $foo
+} {0 {}}
+test regexp-16.20 {regsub -start, loss of ^$ behavior} {
+ set foo NA
+ list [regsub -start 1 {^$} {} & foo] $foo
+} {0 {}}
+test regexp-16.21 {regsub -start, loss of ^$ behavior} {
+ set foo NA
+ list [regsub -start 1 {^.*$} abc & foo] $foo
+} {0 abc}
+test regexp-16.22 {regsub -start, loss of ^$ behavior} {
+ set foo NA
+ list [regsub -all -start 1 {^.*$} abc & foo] $foo
+} {0 abc}
+
+test regexp-17.1 {regexp -inline} {
+ regexp -inline b ababa
+} {b}
+test regexp-17.2 {regexp -inline} {
+ regexp -inline (b) ababa
+} {b b}
+test regexp-17.3 {regexp -inline -indices} {
+ regexp -inline -indices (b) ababa
+} {{1 1} {1 1}}
+test regexp-17.4 {regexp -inline} {
+ regexp -inline {\w(\d+)\w} " hello 23 there456def "
+} {e456d 456}
+test regexp-17.5 {regexp -inline no matches} {
+ regexp -inline {\w(\d+)\w} ""
+} {}
+test regexp-17.6 {regexp -inline no matches} {
+ regexp -inline hello goodbye
+} {}
+test regexp-17.7 {regexp -inline, no matchvars allowed} {
+ list [catch {regexp -inline b abc match} msg] $msg
+} {1 {regexp match variables not allowed when using -inline}}
+
+test regexp-18.1 {regexp -all} {
+ regexp -all b bbbbb
+} {5}
+test regexp-18.2 {regexp -all} {
+ regexp -all b abababbabaaaaaaaaaab
+} {6}
+test regexp-18.3 {regexp -all -inline} {
+ regexp -all -inline b abababbabaaaaaaaaaab
+} {b b b b b b}
+test regexp-18.4 {regexp -all -inline} {
+ regexp -all -inline {\w(\w)} abcdefg
+} {ab b cd d ef f}
+test regexp-18.5 {regexp -all -inline} {
+ regexp -all -inline {\w(\w)$} abcdefg
+} {fg g}
+test regexp-18.6 {regexp -all -inline} {
+ regexp -all -inline {\d+} 10:20:30:40
+} {10 20 30 40}
+test regexp-18.7 {regexp -all -inline} {
+ list [catch {regexp -all -inline b abc match} msg] $msg
+} {1 {regexp match variables not allowed when using -inline}}
+test regexp-18.8 {regexp -all} {
+ # This should not cause an infinite loop
+ regexp -all -inline {a*} a
+} {a}
+test regexp-18.9 {regexp -all} {
+ # Yes, the expected result is {a {}}. Here's why:
+ # Start at index 0; a* matches the "a" there then stops.
+ # Go to index 1; a* matches the lambda (or {}) there then stops. Recall
+ # that a* matches zero or more "a"'s; thus it matches the string "b", as
+ # there are zero or more "a"'s there.
+ # Go to index 2; this is past the end of the string, so stop.
+ regexp -all -inline {a*} ab
+} {a {}}
+test regexp-18.10 {regexp -all} {
+ # Yes, the expected result is {a {} a}. Here's why:
+ # Start at index 0; a* matches the "a" there then stops.
+ # Go to index 1; a* matches the lambda (or {}) there then stops. Recall
+ # that a* matches zero or more "a"'s; thus it matches the string "b", as
+ # there are zero or more "a"'s there.
+ # Go to index 2; a* matches the "a" there then stops.
+ # Go to index 3; this is past the end of the string, so stop.
+ regexp -all -inline {a*} aba
+} {a {} a}
+test regexp-18.11 {regexp -all} {
+ regexp -all -inline {^a} aaaa
+} {a}
+test regexp-18.12 {regexp -all -inline -indices} {
+ regexp -all -inline -indices a(b(c)d|e(f)g)h abcdhaefgh
+} {{0 4} {1 3} {2 2} {-1 -1} {5 9} {6 8} {-1 -1} {7 7}}
+
+test regexp-19.1 {regsub null replacement} {
+ regsub -all {@} {@hel@lo@} "\0a\0" result
+ list $result [string length $result]
+} "\0a\0hel\0a\0lo\0a\0 14"
+
+test regexp-19.2 {regsub null replacement} {
+ regsub -all {@} {@hel@lo@} "\0a\0" result
+ set expected "\0a\0hel\0a\0lo\0a\0"
+ string equal $result $expected
+} 1
+
+test regexp-20.1 {regsub shared object shimmering} {
+ # Bug #461322
+ set a abcdefghijklmnopqurstuvwxyz
+ set b $a
+ set c abcdefghijklmnopqurstuvwxyz0123456789
+ regsub $a $c $b d
+ list $d [string length $d] [string bytelength $d]
+} [list abcdefghijklmnopqurstuvwxyz0123456789 37 37]
+test regexp-20.2 {regsub shared object shimmering with -about} {
+ eval regexp -about abc
+} {0 {}}
+
+test regexp-21.1 {regsub works with empty string} {
+ regsub -- ^ {} foo
+} {foo}
+test regexp-21.2 {regsub works with empty string} {
+ regsub -- \$ {} foo
+} {foo}
+test regexp-21.3 {regsub works with empty string offset} {
+ regsub -start 0 -- ^ {} foo
+} {foo}
+test regexp-21.4 {regsub works with empty string offset} {
+ regsub -start 0 -- \$ {} foo
+} {foo}
+test regexp-21.5 {regsub works with empty string offset} {
+ regsub -start 3 -- \$ {123} foo
+} {123foo}
+test regexp-21.6 {regexp works with empty string} {
+ regexp -- ^ {}
+} {1}
+test regexp-21.7 {regexp works with empty string} {
+ regexp -start 0 -- ^ {}
+} {1}
+test regexp-21.8 {regexp works with empty string offset} {
+ regexp -start 3 -- ^ {123}
+} {0}
+test regexp-21.9 {regexp works with empty string offset} {
+ regexp -start 3 -- \$ {123}
+} {1}
+test regexp-21.10 {multiple matches handle newlines} {
+ regsub -all -lineanchor -- {^#[^\n]*\n} "#one\n#two\n#three\n" foo\n
+} "foo\nfoo\nfoo\n"
+test regexp-21.11 {multiple matches handle newlines} {
+ regsub -all -line -- ^ "a\nb\nc" \#
+} "\#a\n\#b\n\#c"
+test regexp-21.12 {multiple matches handle newlines} {
+ regsub -all -line -- ^ "\n\n" \#
+} "\#\n\#\n\#"
+test regexp-21.13 {multiple matches handle newlines} {
+ regexp -all -inline -indices -line -- ^ "a\nb\nc"
+} {{0 -1} {2 1} {4 3}}
+test regexp-21.14 {regsub works with empty string} {
+ regsub -- ^ {} &
+} {}
+test regexp-21.15 {regsub works with empty string} {
+ regsub -- ^ {} foo&
+} {foo}
+test regexp-21.16 {regsub works with empty string} {
+ regsub -all -- ^ {} foo&
+} {foo}
+test regexp-21.17 {regsub works with empty string} {
+ regsub -- ^ {} {foo\0}
+} {foo}
+test regexp-21.18 {regsub works with empty string} {
+ regsub -- ^.* {} {foo$0}
+} {foo$0}
+test regexp-21.19 {regsub works with empty string} {
+ regsub -- ^ {input} {}
+} {input}
+test regexp-21.20 {regsub works with empty string} {
+ regsub -- x {} {foo}
+} {}
+
+test regexp-22.1 {Bug 1810038} {
+ regexp ($|^X)* {}
+} 1
+test regexp-22.2 {regexp compile and backrefs, Bug 1857126} {
+ regexp -- {([bc])\1} bb
+} 1
+
+test regexp-23.1 {regexp -all and -line} {
+ set string ""
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1}} {{0 -1}} {{0 -1}}}
+test regexp-23.2 {regexp -all and -line} {
+ set string "\n"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1}} {{0 -1}} {{0 -1}}}
+test regexp-23.3 {regexp -all and -line} {
+ set string "\n\n"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {1 0}} {{0 -1} {1 0}} {{0 -1} {1 0}}}
+test regexp-23.4 {regexp -all and -line} {
+ set string "a"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^.*$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1}} {{0 0}} {{1 0}}}
+test regexp-23.5 {regexp -all and -line} {knownBug} {
+ set string "a\n"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^.*$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {2 1}} {{0 0} {2 1}} {{1 0} {2 1}}}
+test regexp-23.6 {regexp -all and -line} {
+ set string "\na"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^.*$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {1 0}} {{0 -1} {1 1}} {{0 -1} {2 1}}}
+test regexp-23.7 {regexp -all and -line} {knownBug} {
+ set string "ab\n"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^.*$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {3 2}} {{0 1} {3 2}} {{2 1} {3 2}}}
+test regexp-23.8 {regexp -all and -line} {
+ set string "a\nb"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^.*$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {2 1}} {{0 0} {2 2}} {{1 0} {3 2}}}
+test regexp-23.9 {regexp -all and -line} {knownBug} {
+ set string "a\nb\n"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^.*$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {2 1} {4 3}} {{0 0} {2 2} {4 3}} {{1 0} {3 2} {4 3}}}
+test regexp-23.10 {regexp -all and -line} {
+ set string "a\nb\nc"
+ list \
+ [regexp -all -inline -indices -line -- {^} $string] \
+ [regexp -all -inline -indices -line -- {^.*$} $string] \
+ [regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {2 1} {4 3}} {{0 0} {2 2} {4 4}} {{1 0} {3 2} {5 4}}}
+test regexp-23.11 {regexp -all and -line} {
+ regexp -all -inline -indices -line -- {b} "abb\nb"
+} {{1 1} {2 2} {4 4}}
+
+test regexp-24.1 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string ""
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} {1 <> 1 <> 1 <>}
+test regexp-24.2 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "\n"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 2 "<>\n<>" 2 "<>\n<>" 2 "<>\n<>"]
+test regexp-24.3 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "\n\n"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 3 "<>\n<>\n<>" 3 "<>\n<>\n<>" 3 "<>\n<>\n<>"]
+test regexp-24.4 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "a"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 1 "<>a" 1 "<a>" 1 "a<>"]
+test regexp-24.5 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "a\n"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 2 "<>a\n<>" 2 "<a>\n<>" 2 "a<>\n<>"]
+test regexp-24.6 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "\na"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 2 "<>\n<>a" 2 "<>\n<a>" 2 "<>\na<>"]
+test regexp-24.7 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "ab\n"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 2 "<>ab\n<>" 2 "<ab>\n<>" 2 "ab<>\n<>"]
+test regexp-24.8 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "a\nb"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 2 "<>a\n<>b" 2 "<a>\n<b>" 2 "a<>\nb<>"]
+test regexp-24.9 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "a\nb\n"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 3 "<>a\n<>b\n<>" 3 "<a>\n<b>\n<>" 3 "a<>\nb<>\n<>"]
+test regexp-24.10 {regsub -all and -line} {
+ foreach {v1 v2 v3} {{} {} {}} {}
+ set string "a\nb\nc"
+ list \
+ [regsub -line -all {^} $string {<&>} v1] $v1 \
+ [regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+ [regsub -line -all {$} $string {<&>} v3] $v3
+} [list 3 "<>a\n<>b\n<>c" 3 "<a>\n<b>\n<c>" 3 "a<>\nb<>\nc<>"]
+test regexp-24.11 {regsub -all and -line} {
+ regsub -line -all {b} "abb\nb" {<&>}
+} "a<b><b>\n<b>"
+
+test regexp-25.1 {regexp without -line option} {
+ set foo ""
+ list [regexp {a.*b} "dabc\naxyb\n" foo] $foo
+} [list 1 abc\naxyb]
+test regexp-25.2 {regexp without -line option} {
+ set foo ""
+ list [regexp {^a.*b$} "dabc\naxyb\n" foo] $foo
+} {0 {}}
+test regexp-25.3 {regexp with -line option} {
+ set foo ""
+ list [regexp -line {^a.*b$} "dabc\naxyb\n" foo] $foo
+} {1 axyb}
+test regexp-25.4 {regexp with -line option} {
+ set foo ""
+ list [regexp -line {^a.*b$} "dabc\naxyb\nxb" foo] $foo
+} {1 axyb}
+test regexp-25.5 {regexp without -line option} {
+ set foo ""
+ list [regexp {^a.*b$} "dabc\naxyb\nxb" foo] $foo
+} {0 {}}
+test regexp-25.6 {regexp without -line option} {
+ set foo ""
+ list [regexp {a.*b$} "dabc\naxyb\nxb" foo] $foo
+} "1 {abc\naxyb\nxb}"
+test regexp-25.7 {regexp with -lineanchor option} {
+ set foo ""
+ list [regexp -lineanchor {^a.*b$} "dabc\naxyb\nxb" foo] $foo
+} "1 {axyb\nxb}"
+test regexp-25.8 {regexp with -lineanchor and -linestop option} {
+ set foo ""
+ list [regexp -lineanchor -linestop {^a.*b$} "dabc\naxyb\nxb" foo] $foo
+} {1 axyb}
+test regexp-25.9 {regexp with -linestop option} {
+ set foo ""
+ list [regexp -linestop {a.*b} "ab\naxyb\nxb" foo] $foo
+} {1 ab}
+
+test regexp-26.1 {matches start of line 1 time} {
+ regexp -all -inline -- {^a+} "aab\naaa"
+} {aa}
+test regexp-26.2 {matches start of line(s) 2 times} {
+ regexp -all -inline -line -- {^a+} "aab\naaa"
+} {aa aaa}
+test regexp-26.3 {effect of -line -all and -start} {
+ list \
+ [regexp -all -inline -line -start 0 -- {^a+} "aab\naaa"] \
+ [regexp -all -inline -line -start 1 -- {^a+} "aab\naaa"] \
+ [regexp -all -inline -line -start 3 -- {^a+} "aab\naaa"] \
+ [regexp -all -inline -line -start 4 -- {^a+} "aab\naaa"] \
+} {{aa aaa} aaa aaa aaa}
+# No regexp-26.4
+test regexp-26.5 {match length 0, match length 1} {
+ regexp -all -inline -line -- {^b*} "a\nb"
+} {{} b}
+test regexp-26.6 {non reporting capture group} {
+ regexp -all -inline -line -- {^(?:a+|b)} "aab\naaa"
+} {aa aaa}
+test regexp-26.7 {Tcl bug 2826551: -line sensitive regexp and -start} {
+ set match1 {}
+ set match2 {}
+ list \
+ [regexp -start 0 -indices -line {^a} "\nab" match1] $match1 \
+ [regexp -start 1 -indices -line {^a} "\nab" match2] $match2
+} {1 {1 1} 1 {1 1}}
+test regexp-26.8 {Tcl bug 2826551: diff regexp with -line option} {
+ set data "@1\n2\n+3\n@4\n-5\n+6\n7\n@8\n9\n"
+ regexp -all -inline -line {^@.*\n(?:[^@].*\n?)*} $data
+} [list "@1\n2\n+3\n" "@4\n-5\n+6\n7\n" "@8\n9\n"]
+test regexp-26.9 {Tcl bug 2826551: diff regexp with embedded -line option} {
+ set data "@1\n2\n+3\n@4\n-5\n+6\n7\n@8\n9\n"
+ regexp -all -inline {(?n)^@.*\n(?:[^@].*\n?)*} $data
+} [list "@1\n2\n+3\n" "@4\n-5\n+6\n7\n" "@8\n9\n"]
+test regexp-26.10 {regexp with -line option} {
+ regexp -all -inline -line -- {a*} "a\n"
+} {a {}}
+test regexp-26.11 {regexp without -line option} {
+ regexp -all -inline -- {a*} "a\n"
+} {a {}}
+test regexp-26.12 {regexp with -line option} {
+ regexp -all -inline -line -- {a*} "b\n"
+} {{} {}}
+test regexp-26.13 {regexp without -line option} {
+ regexp -all -inline -- {a*} "b\n"
+} {{} {}}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/regexpComp.test b/pkgs/msgcat/tests/regexpComp.test
new file mode 100644
index 0000000..94fb90e
--- /dev/null
+++ b/pkgs/msgcat/tests/regexpComp.test
@@ -0,0 +1,992 @@
+# Commands covered: regexp, regsub
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1998 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Procedure to evaluate a script within a proc, to test compilation
+# functionality
+
+proc evalInProc { script } {
+ proc testProc {} $script
+ set status [catch {
+ testProc
+ } result]
+ rename testProc {}
+ return $result
+ #return [list $status $result]
+}
+
+unset -nocomplain foo
+
+test regexpComp-1.1 {basic regexp operation} {
+ evalInProc {
+ regexp ab*c abbbc
+ }
+} 1
+test regexpComp-1.2 {basic regexp operation} {
+ evalInProc {
+ regexp ab*c ac
+ }
+} 1
+test regexpComp-1.3 {basic regexp operation} {
+ evalInProc {
+ regexp ab*c ab
+ }
+} 0
+test regexpComp-1.4 {basic regexp operation} {
+ evalInProc {
+ regexp -- -gorp abc-gorpxxx
+ }
+} 1
+test regexpComp-1.5 {basic regexp operation} {
+ evalInProc {
+ regexp {^([^ ]*)[ ]*([^ ]*)} "" a
+ }
+} 1
+test regexpComp-1.6 {basic regexp operation} {
+ list [catch {regexp {} abc} msg] $msg
+} {0 1}
+test regexpComp-1.7 {regexp utf compliance} {
+ # if not UTF-8 aware, result is "0 1"
+ evalInProc {
+ set foo "\u4e4eb q"
+ regexp "\u4e4eb q" "a\u4e4eb qw\u5e4e\x4e wq" bar
+ list [string compare $foo $bar] [regexp 4 $bar]
+ }
+} {0 0}
+
+test regexpComp-1.8 {regexp ***= metasyntax} {
+ evalInProc {
+ regexp -- "***=o" "aeiou"
+ }
+} 1
+test regexpComp-1.9 {regexp ***= metasyntax} {
+ evalInProc {
+ set string "aeiou"
+ regexp -- "***=o" $string
+ }
+} 1
+test regexpComp-1.10 {regexp ***= metasyntax} {
+ evalInProc {
+ set string "aeiou"
+ set re "***=o"
+ regexp -- $re $string
+ }
+} 1
+test regexpComp-1.11 {regexp ***= metasyntax} {
+ evalInProc {
+ regexp -- "***=y" "aeiou"
+ }
+} 0
+test regexpComp-1.12 {regexp ***= metasyntax} {
+ evalInProc {
+ set string "aeiou"
+ regexp -- "***=y" $string
+ }
+} 0
+test regexpComp-1.13 {regexp ***= metasyntax} {
+ evalInProc {
+ set string "aeiou"
+ set re "***=y"
+ regexp -- $re $string
+ }
+} 0
+test regexpComp-1.14 {regexp ***= metasyntax} {
+ evalInProc {
+ set string "aeiou"
+ set re "***=e*o"
+ regexp -- $re $string
+ }
+} 0
+test regexpComp-1.15 {regexp ***= metasyntax} {
+ evalInProc {
+ set string "ae*ou"
+ set re "***=e*o"
+ regexp -- $re $string
+ }
+} 1
+test regexpComp-1.16 {regexp ***= metasyntax} {
+ evalInProc {
+ set string {ae*[o]?ua}
+ set re {***=e*[o]?u}
+ regexp -- $re $string
+ }
+} 1
+
+test regexpComp-2.1 {getting substrings back from regexp} {
+ evalInProc {
+ set foo {}
+ list [regexp ab*c abbbbc foo] $foo
+ }
+} {1 abbbbc}
+test regexpComp-2.2 {getting substrings back from regexp} {
+ evalInProc {
+ set foo {}
+ set f2 {}
+ list [regexp a(b*)c abbbbc foo f2] $foo $f2
+ }
+} {1 abbbbc bbbb}
+test regexpComp-2.3 {getting substrings back from regexp} {
+ evalInProc {
+ set foo {}
+ set f2 {}
+ list [regexp a(b*)(c) abbbbc foo f2] $foo $f2
+ }
+} {1 abbbbc bbbb}
+test regexpComp-2.4 {getting substrings back from regexp} {
+ evalInProc {
+ set foo {}
+ set f2 {}
+ set f3 {}
+ list [regexp a(b*)(c) abbbbc foo f2 f3] $foo $f2 $f3
+ }
+} {1 abbbbc bbbb c}
+test regexpComp-2.5 {getting substrings back from regexp} {
+ evalInProc {
+ set foo {}; set f1 {}; set f2 {}; set f3 {}; set f4 {}; set f5 {};
+ set f6 {}; set f7 {}; set f8 {}; set f9 {}; set fa {}; set fb {};
+ list [regexp (1*)(2*)(3*)(4*)(5*)(6*)(7*)(8*)(9*)(a*)(b*) \
+ 12223345556789999aabbb \
+ foo f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb] $foo $f1 $f2 $f3 $f4 $f5 \
+ $f6 $f7 $f8 $f9 $fa $fb
+ }
+} {1 12223345556789999aabbb 1 222 33 4 555 6 7 8 9999 aa bbb}
+test regexpComp-2.6 {getting substrings back from regexp} {
+ evalInProc {
+ set foo 2; set f2 2; set f3 2; set f4 2
+ list [regexp (a)(b)? xay foo f2 f3 f4] $foo $f2 $f3 $f4
+ }
+} {1 a a {} {}}
+test regexpComp-2.7 {getting substrings back from regexp} {
+ evalInProc {
+ set foo 1; set f2 1; set f3 1; set f4 1
+ list [regexp (a)(b)?(c) xacy foo f2 f3 f4] $foo $f2 $f3 $f4
+ }
+} {1 ac a {} c}
+test regexpComp-2.8 {getting substrings back from regexp} {
+ evalInProc {
+ set match {}
+ list [regexp {^a*b} aaaab match] $match
+ }
+} {1 aaaab}
+
+test regexpComp-3.1 {-indices option to regexp} {
+ evalInProc {
+ set foo {}
+ list [regexp -indices ab*c abbbbc foo] $foo
+ }
+} {1 {0 5}}
+test regexpComp-3.2 {-indices option to regexp} {
+ evalInProc {
+ set foo {}
+ set f2 {}
+ list [regexp -indices a(b*)c abbbbc foo f2] $foo $f2
+ }
+} {1 {0 5} {1 4}}
+test regexpComp-3.3 {-indices option to regexp} {
+ evalInProc {
+ set foo {}
+ set f2 {}
+ list [regexp -indices a(b*)(c) abbbbc foo f2] $foo $f2
+ }
+} {1 {0 5} {1 4}}
+test regexpComp-3.4 {-indices option to regexp} {
+ evalInProc {
+ set foo {}
+ set f2 {}
+ set f3 {}
+ list [regexp -indices a(b*)(c) abbbbc foo f2 f3] $foo $f2 $f3
+ }
+} {1 {0 5} {1 4} {5 5}}
+test regexpComp-3.5 {-indices option to regexp} {
+ evalInProc {
+ set foo {}; set f1 {}; set f2 {}; set f3 {}; set f4 {}; set f5 {};
+ set f6 {}; set f7 {}; set f8 {}; set f9 {}
+ list [regexp -indices (1*)(2*)(3*)(4*)(5*)(6*)(7*)(8*)(9*) \
+ 12223345556789999 \
+ foo f1 f2 f3 f4 f5 f6 f7 f8 f9] $foo $f1 $f2 $f3 $f4 $f5 \
+ $f6 $f7 $f8 $f9
+ }
+} {1 {0 16} {0 0} {1 3} {4 5} {6 6} {7 9} {10 10} {11 11} {12 12} {13 16}}
+test regexpComp-3.6 {getting substrings back from regexp} {
+ evalInProc {
+ set foo 2; set f2 2; set f3 2; set f4 2
+ list [regexp -indices (a)(b)? xay foo f2 f3 f4] $foo $f2 $f3 $f4
+ }
+} {1 {1 1} {1 1} {-1 -1} {-1 -1}}
+test regexpComp-3.7 {getting substrings back from regexp} {
+ evalInProc {
+ set foo 1; set f2 1; set f3 1; set f4 1
+ list [regexp -indices (a)(b)?(c) xacy foo f2 f3 f4] $foo $f2 $f3 $f4
+ }
+} {1 {1 2} {1 1} {-1 -1} {2 2}}
+
+test regexpComp-4.1 {-nocase option to regexp} {
+ evalInProc {
+ regexp -nocase foo abcFOo
+ }
+} 1
+test regexpComp-4.2 {-nocase option to regexp} {
+ evalInProc {
+ set f1 22
+ set f2 33
+ set f3 44
+ list [regexp -nocase {a(b*)([xy]*)z} aBbbxYXxxZ22 f1 f2 f3] $f1 $f2 $f3
+ }
+} {1 aBbbxYXxxZ Bbb xYXxx}
+test regexpComp-4.3 {-nocase option to regexp} {
+ evalInProc {
+ regexp -nocase FOo abcFOo
+ }
+} 1
+set ::x abcdefghijklmnopqrstuvwxyz1234567890
+set ::x $x$x$x$x$x$x$x$x$x$x$x$x
+test regexpComp-4.4 {case conversion in regexp} {
+ evalInProc {
+ list [regexp -nocase $::x $::x foo] $foo
+ }
+} "1 $x"
+unset -nocomplain ::x
+
+test regexpComp-5.1 {exercise cache of compiled expressions} {
+ evalInProc {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*a bbba
+ }
+} 1
+test regexpComp-5.2 {exercise cache of compiled expressions} {
+ evalInProc {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*b xxxb
+ }
+} 1
+test regexpComp-5.3 {exercise cache of compiled expressions} {
+ evalInProc {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*c yyyc
+ }
+} 1
+test regexpComp-5.4 {exercise cache of compiled expressions} {
+ evalInProc {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*d 1d
+ }
+} 1
+test regexpComp-5.5 {exercise cache of compiled expressions} {
+ evalInProc {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ regexp .*e xe
+ }
+} 1
+
+test regexpComp-6.1 {regexp errors} {
+ evalInProc {
+ list [catch {regexp a} msg] $msg
+ }
+} {1 {wrong # args: should be "regexp ?-switch ...? exp string ?matchVar? ?subMatchVar ...?"}}
+test regexpComp-6.2 {regexp errors} {
+ evalInProc {
+ list [catch {regexp -nocase a} msg] $msg
+ }
+} {1 {wrong # args: should be "regexp ?-switch ...? exp string ?matchVar? ?subMatchVar ...?"}}
+test regexpComp-6.3 {regexp errors} {
+ evalInProc {
+ list [catch {regexp -gorp a} msg] $msg
+ }
+} {1 {bad switch "-gorp": must be -all, -about, -indices, -inline, -expanded, -line, -linestop, -lineanchor, -nocase, -start, or --}}
+test regexpComp-6.4 {regexp errors} {
+ evalInProc {
+ list [catch {regexp a( b} msg] $msg
+ }
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexpComp-6.5 {regexp errors} {
+ evalInProc {
+ list [catch {regexp a( b} msg] $msg
+ }
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexpComp-6.6 {regexp errors} {
+ evalInProc {
+ list [catch {regexp a a f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1} msg] $msg
+ }
+} {0 1}
+test regexpComp-6.7 {regexp errors} {
+ evalInProc {
+ list [catch {regexp (x)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.) xyzzy} msg] $msg
+ }
+} {0 0}
+test regexpComp-6.8 {regexp errors} {
+ evalInProc {
+ unset -nocomplain f1
+ set f1 44
+ list [catch {regexp abc abc f1(f2)} msg] $msg
+ }
+} {1 {can't set "f1(f2)": variable isn't array}}
+test regexpComp-6.9 {regexp errors, -start bad int check} {
+ evalInProc {
+ list [catch {regexp -start bogus {^$} {}} msg] $msg
+ }
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
+
+test regexpComp-7.1 {basic regsub operation} {
+ evalInProc {
+ list [regsub aa+ xaxaaaxaa 111&222 foo] $foo
+ }
+} {1 xax111aaa222xaa}
+test regexpComp-7.2 {basic regsub operation} {
+ evalInProc {
+ list [regsub aa+ aaaxaa &111 foo] $foo
+ }
+} {1 aaa111xaa}
+test regexpComp-7.3 {basic regsub operation} {
+ evalInProc {
+ list [regsub aa+ xaxaaa 111& foo] $foo
+ }
+} {1 xax111aaa}
+test regexpComp-7.4 {basic regsub operation} {
+ evalInProc {
+ list [regsub aa+ aaa 11&2&333 foo] $foo
+ }
+} {1 11aaa2aaa333}
+test regexpComp-7.5 {basic regsub operation} {
+ evalInProc {
+ list [regsub aa+ xaxaaaxaa &2&333 foo] $foo
+ }
+} {1 xaxaaa2aaa333xaa}
+test regexpComp-7.6 {basic regsub operation} {
+ evalInProc {
+ list [regsub aa+ xaxaaaxaa 1&22& foo] $foo
+ }
+} {1 xax1aaa22aaaxaa}
+test regexpComp-7.7 {basic regsub operation} {
+ evalInProc {
+ list [regsub a(a+) xaxaaaxaa {1\122\1} foo] $foo
+ }
+} {1 xax1aa22aaxaa}
+test regexpComp-7.8 {basic regsub operation} {
+ evalInProc {
+ list [regsub a(a+) xaxaaaxaa {1\\\122\1} foo] $foo
+ }
+} "1 {xax1\\aa22aaxaa}"
+test regexpComp-7.9 {basic regsub operation} {
+ evalInProc {
+ list [regsub a(a+) xaxaaaxaa {1\\122\1} foo] $foo
+ }
+} "1 {xax1\\122aaxaa}"
+test regexpComp-7.10 {basic regsub operation} {
+ evalInProc {
+ list [regsub a(a+) xaxaaaxaa {1\\&\1} foo] $foo
+ }
+} "1 {xax1\\aaaaaxaa}"
+test regexpComp-7.11 {basic regsub operation} {
+ evalInProc {
+ list [regsub a(a+) xaxaaaxaa {1\&\1} foo] $foo
+ }
+} {1 xax1&aaxaa}
+test regexpComp-7.12 {basic regsub operation} {
+ evalInProc {
+ list [regsub a(a+) xaxaaaxaa {\1\1\1\1&&} foo] $foo
+ }
+} {1 xaxaaaaaaaaaaaaaaxaa}
+test regexpComp-7.13 {basic regsub operation} {
+ evalInProc {
+ set foo xxx
+ list [regsub abc xyz 111 foo] $foo
+ }
+} {0 xyz}
+test regexpComp-7.14 {basic regsub operation} {
+ evalInProc {
+ set foo xxx
+ list [regsub ^ xyz "111 " foo] $foo
+ }
+} {1 {111 xyz}}
+test regexpComp-7.15 {basic regsub operation} {
+ evalInProc {
+ set foo xxx
+ list [regsub -- -foo abc-foodef "111 " foo] $foo
+ }
+} {1 {abc111 def}}
+test regexpComp-7.16 {basic regsub operation} {
+ evalInProc {
+ set foo xxx
+ list [regsub x "" y foo] $foo
+ }
+} {0 {}}
+test regexpComp-7.17 {regsub utf compliance} {
+ evalInProc {
+ # if not UTF-8 aware, result is "0 1"
+ set foo "xyz555ijka\u4e4ebpqr"
+ regsub a\u4e4eb xyza\u4e4ebijka\u4e4ebpqr 555 bar
+ list [string compare $foo $bar] [regexp 4 $bar]
+ }
+} {0 0}
+
+test regexpComp-8.1 {case conversion in regsub} {
+ evalInProc {
+ list [regsub -nocase a(a+) xaAAaAAay & foo] $foo
+ }
+} {1 xaAAaAAay}
+test regexpComp-8.2 {case conversion in regsub} {
+ evalInProc {
+ list [regsub -nocase a(a+) xaAAaAAay & foo] $foo
+ }
+} {1 xaAAaAAay}
+test regexpComp-8.3 {case conversion in regsub} {
+ evalInProc {
+ set foo 123
+ list [regsub a(a+) xaAAaAAay & foo] $foo
+ }
+} {0 xaAAaAAay}
+test regexpComp-8.4 {case conversion in regsub} {
+ evalInProc {
+ set foo 123
+ list [regsub -nocase a CaDE b foo] $foo
+ }
+} {1 CbDE}
+test regexpComp-8.5 {case conversion in regsub} {
+ evalInProc {
+ set foo 123
+ list [regsub -nocase XYZ CxYzD b foo] $foo
+ }
+} {1 CbD}
+test regexpComp-8.6 {case conversion in regsub} {
+ evalInProc {
+ set x abcdefghijklmnopqrstuvwxyz1234567890
+ set x $x$x$x$x$x$x$x$x$x$x$x$x
+ set foo 123
+ list [regsub -nocase $x $x b foo] $foo
+ }
+} {1 b}
+
+test regexpComp-9.1 {-all option to regsub} {
+ evalInProc {
+ set foo 86
+ list [regsub -all x+ axxxbxxcxdx |&| foo] $foo
+ }
+} {4 a|xxx|b|xx|c|x|d|x|}
+test regexpComp-9.2 {-all option to regsub} {
+ evalInProc {
+ set foo 86
+ list [regsub -nocase -all x+ aXxXbxxcXdx |&| foo] $foo
+ }
+} {4 a|XxX|b|xx|c|X|d|x|}
+test regexpComp-9.3 {-all option to regsub} {
+ evalInProc {
+ set foo 86
+ list [regsub x+ axxxbxxcxdx |&| foo] $foo
+ }
+} {1 a|xxx|bxxcxdx}
+test regexpComp-9.4 {-all option to regsub} {
+ evalInProc {
+ set foo 86
+ list [regsub -all bc axxxbxxcxdx |&| foo] $foo
+ }
+} {0 axxxbxxcxdx}
+test regexpComp-9.5 {-all option to regsub} {
+ evalInProc {
+ set foo xxx
+ list [regsub -all node "node node more" yy foo] $foo
+ }
+} {2 {yy yy more}}
+test regexpComp-9.6 {-all option to regsub} {
+ evalInProc {
+ set foo xxx
+ list [regsub -all ^ xxx 123 foo] $foo
+ }
+} {1 123xxx}
+
+test regexpComp-10.1 {expanded syntax in regsub} {
+ evalInProc {
+ set foo xxx
+ list [regsub -expanded ". \#comment\n . \#comment2" abc def foo] $foo
+ }
+} {1 defc}
+test regexpComp-10.2 {newline sensitivity in regsub} {
+ evalInProc {
+ set foo xxx
+ list [regsub -line {^a.*b$} "dabc\naxyb\n" 123 foo] $foo
+ }
+} "1 {dabc\n123\n}"
+test regexpComp-10.3 {newline sensitivity in regsub} {
+ evalInProc {
+ set foo xxx
+ list [regsub -line {^a.*b$} "dabc\naxyb\nxb" 123 foo] $foo
+ }
+} "1 {dabc\n123\nxb}"
+test regexpComp-10.4 {partial newline sensitivity in regsub} {
+ evalInProc {
+ set foo xxx
+ list [regsub -lineanchor {^a.*b$} "da\naxyb\nxb" 123 foo] $foo
+ }
+} "1 {da\n123}"
+test regexpComp-10.5 {inverse partial newline sensitivity in regsub} {
+ evalInProc {
+ set foo xxx
+ list [regsub -linestop {a.*b} "da\nbaxyb\nxb" 123 foo] $foo
+ }
+} "1 {da\nb123\nxb}"
+
+test regexpComp-11.1 {regsub errors} {
+ evalInProc {
+ list [catch {regsub a b} msg] $msg
+ }
+} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}}
+test regexpComp-11.2 {regsub errors} {
+ evalInProc {
+ list [catch {regsub -nocase a b} msg] $msg
+ }
+} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}}
+test regexpComp-11.3 {regsub errors} {
+ evalInProc {
+ list [catch {regsub -nocase -all a b} msg] $msg
+ }
+} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}}
+test regexpComp-11.4 {regsub errors} {
+ evalInProc {
+ list [catch {regsub a b c d e f} msg] $msg
+ }
+} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}}
+test regexpComp-11.5 {regsub errors} {
+ evalInProc {
+ list [catch {regsub -gorp a b c} msg] $msg
+ }
+} {1 {bad switch "-gorp": must be -all, -nocase, -expanded, -line, -linestop, -lineanchor, -start, or --}}
+test regexpComp-11.6 {regsub errors} {
+ evalInProc {
+ list [catch {regsub -nocase a( b c d} msg] $msg
+ }
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexpComp-11.7 {regsub errors} {
+ evalInProc {
+ unset -nocomplain f1
+ set f1 44
+ list [catch {regsub -nocase aaa aaa xxx f1(f2)} msg] $msg
+ }
+} {1 {can't set "f1(f2)": variable isn't array}}
+test regexpComp-11.8 {regsub errors, -start bad int check} {
+ evalInProc {
+ list [catch {regsub -start bogus pattern string rep var} msg] $msg
+ }
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
+
+# This test crashes on the Mac unless you increase the Stack Space to about 1
+# Meg. This is probably bigger than most users want...
+# 8.2.3 regexp reduced stack space requirements, but this should be
+# tested again
+test regexpComp-12.1 {Tcl_RegExpExec: large number of subexpressions} {macCrash} {
+ evalInProc {
+ list [regexp (.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.) abcdefghijklmnopqrstuvwxyz all a b c d e f g h i j k l m n o p q r s t u v w x y z] $all $a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z
+ }
+} {1 abcdefghijklmnopqrstuvwxyz a b c d e f g h i j k l m n o p q r s t u v w x y z}
+
+test regexpComp-13.1 {regsub of a very large string} {
+ # This test is designed to stress the memory subsystem in order
+ # to catch Bug #933. It only fails if the Tcl memory allocator
+ # is in use.
+
+ set line {BEGIN_TABLE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; END_TABLE}
+ set filedata [string repeat $line 200]
+ for {set i 1} {$i<10} {incr i} {
+ regsub -all "BEGIN_TABLE " $filedata "" newfiledata
+ }
+ set x done
+} {done}
+
+test regexpComp-14.1 {CompileRegexp: regexp cache} {
+ evalInProc {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ set x .
+ append x *a
+ regexp $x bbba
+ }
+} 1
+test regexpComp-14.2 {CompileRegexp: regexp cache, different flags} {
+ evalInProc {
+ regexp .*a b
+ regexp .*b c
+ regexp .*c d
+ regexp .*d e
+ regexp .*e f
+ set x .
+ append x *a
+ regexp -nocase $x bbba
+ }
+} 1
+
+testConstraint exec [llength [info commands exec]]
+test regexpComp-14.3 {CompileRegexp: regexp cache, empty regexp and empty cache} -constraints {
+ exec
+} -setup {
+ set junk [makeFile {puts [regexp {} foo]} junk.tcl]
+} -body {
+ exec [interpreter] $junk
+} -cleanup {
+ removeFile junk.tcl
+} -result 1
+
+test regexpComp-15.1 {regexp -start} {
+ unset -nocomplain x
+ list [regexp -start -10 {\d} 1abc2de3 x] $x
+} {1 1}
+test regexpComp-15.2 {regexp -start} {
+ unset -nocomplain x
+ list [regexp -start 2 {\d} 1abc2de3 x] $x
+} {1 2}
+test regexpComp-15.3 {regexp -start} {
+ unset -nocomplain x
+ list [regexp -start 4 {\d} 1abc2de3 x] $x
+} {1 2}
+test regexpComp-15.4 {regexp -start} {
+ unset -nocomplain x
+ list [regexp -start 5 {\d} 1abc2de3 x] $x
+} {1 3}
+test regexpComp-15.5 {regexp -start, over end of string} {
+ unset -nocomplain x
+ list [regexp -start [string length 1abc2de3] {\d} 1abc2de3 x] [info exists x]
+} {0 0}
+test regexpComp-15.6 {regexp -start, loss of ^$ behavior} {
+ list [regexp -start 2 {^$} {}]
+} {0}
+
+test regexpComp-16.1 {regsub -start} {
+ unset -nocomplain x
+ list [regsub -all -start 2 {\d} a1b2c3d4e5 {/&} x] $x
+} {4 a1b/2c/3d/4e/5}
+test regexpComp-16.2 {regsub -start} {
+ unset -nocomplain x
+ list [regsub -all -start -25 {z} hello {/&} x] $x
+} {0 hello}
+test regexpComp-16.3 {regsub -start} {
+ unset -nocomplain x
+ list [regsub -all -start 3 {z} hello {/&} x] $x
+} {0 hello}
+test regexpComp-16.4 {regsub -start, \A behavior} {
+ set out {}
+ lappend out [regsub -start 0 -all {\A(\w)} {abcde} {/\1} x] $x
+ lappend out [regsub -start 2 -all {\A(\w)} {abcde} {/\1} x] $x
+} {5 /a/b/c/d/e 3 ab/c/d/e}
+
+test regexpComp-17.1 {regexp -inline} {
+ regexp -inline b ababa
+} {b}
+test regexpComp-17.2 {regexp -inline} {
+ regexp -inline (b) ababa
+} {b b}
+test regexpComp-17.3 {regexp -inline -indices} {
+ regexp -inline -indices (b) ababa
+} {{1 1} {1 1}}
+test regexpComp-17.4 {regexp -inline} {
+ regexp -inline {\w(\d+)\w} " hello 23 there456def "
+} {e456d 456}
+test regexpComp-17.5 {regexp -inline no matches} {
+ regexp -inline {\w(\d+)\w} ""
+} {}
+test regexpComp-17.6 {regexp -inline no matches} {
+ regexp -inline hello goodbye
+} {}
+test regexpComp-17.7 {regexp -inline, no matchvars allowed} {
+ list [catch {regexp -inline b abc match} msg] $msg
+} {1 {regexp match variables not allowed when using -inline}}
+
+test regexpComp-18.1 {regexp -all} {
+ regexp -all b bbbbb
+} {5}
+test regexpComp-18.2 {regexp -all} {
+ regexp -all b abababbabaaaaaaaaaab
+} {6}
+test regexpComp-18.3 {regexp -all -inline} {
+ regexp -all -inline b abababbabaaaaaaaaaab
+} {b b b b b b}
+test regexpComp-18.4 {regexp -all -inline} {
+ regexp -all -inline {\w(\w)} abcdefg
+} {ab b cd d ef f}
+test regexpComp-18.5 {regexp -all -inline} {
+ regexp -all -inline {\w(\w)$} abcdefg
+} {fg g}
+test regexpComp-18.6 {regexp -all -inline} {
+ regexp -all -inline {\d+} 10:20:30:40
+} {10 20 30 40}
+test regexpComp-18.7 {regexp -all -inline} {
+ list [catch {regexp -all -inline b abc match} msg] $msg
+} {1 {regexp match variables not allowed when using -inline}}
+test regexpComp-18.8 {regexp -all} {
+ # This should not cause an infinite loop
+ regexp -all -inline {a*} a
+} {a}
+test regexpComp-18.9 {regexp -all} {
+ # Yes, the expected result is {a {}}. Here's why:
+ # Start at index 0; a* matches the "a" there then stops.
+ # Go to index 1; a* matches the lambda (or {}) there then stops. Recall
+ # that a* matches zero or more "a"'s; thus it matches the string "b", as
+ # there are zero or more "a"'s there.
+ # Go to index 2; this is past the end of the string, so stop.
+ regexp -all -inline {a*} ab
+} {a {}}
+test regexpComp-18.10 {regexp -all} {
+ # Yes, the expected result is {a {} a}. Here's why:
+ # Start at index 0; a* matches the "a" there then stops.
+ # Go to index 1; a* matches the lambda (or {}) there then stops. Recall
+ # that a* matches zero or more "a"'s; thus it matches the string "b", as
+ # there are zero or more "a"'s there.
+ # Go to index 2; a* matches the "a" there then stops.
+ # Go to index 3; this is past the end of the string, so stop.
+ regexp -all -inline {a*} aba
+} {a {} a}
+test regexpComp-18.11 {regexp -all} {
+ evalInProc {
+ regexp -all -inline {^a} aaaa
+ }
+} {a}
+test regexpComp-18.12 {regexp -all -inline -indices} {
+ evalInProc {
+ regexp -all -inline -indices a(b(c)d|e(f)g)h abcdhaefgh
+ }
+} {{0 4} {1 3} {2 2} {-1 -1} {5 9} {6 8} {-1 -1} {7 7}}
+
+test regexpComp-19.1 {regsub null replacement} {
+ evalInProc {
+ regsub -all {@} {@hel@lo@} "\0a\0" result
+ list $result [string length $result]
+ }
+} "\0a\0hel\0a\0lo\0a\0 14"
+
+test regexpComp-20.1 {regsub shared object shimmering} {
+ evalInProc {
+ # Bug #461322
+ set a abcdefghijklmnopqurstuvwxyz
+ set b $a
+ set c abcdefghijklmnopqurstuvwxyz0123456789
+ regsub $a $c $b d
+ list $d [string length $d] [string bytelength $d]
+ }
+} [list abcdefghijklmnopqurstuvwxyz0123456789 37 37]
+test regexpComp-20.2 {regsub shared object shimmering with -about} {
+ evalInProc {
+ eval regexp -about abc
+ }
+} {0 {}}
+
+test regexpComp-21.1 {regexp command compiling tests} {
+ evalInProc {
+ regexp foo bar
+ }
+} 0
+test regexpComp-21.2 {regexp command compiling tests} {
+ evalInProc {
+ regexp {^foo$} dogfood
+ }
+} 0
+test regexpComp-21.3 {regexp command compiling tests} {
+ evalInProc {
+ set a foo
+ regexp {^foo$} $a
+ }
+} 1
+test regexpComp-21.4 {regexp command compiling tests} {
+ evalInProc {
+ regexp foo dogfood
+ }
+} 1
+test regexpComp-21.5 {regexp command compiling tests} {
+ evalInProc {
+ regexp -nocase FOO dogfod
+ }
+} 0
+test regexpComp-21.6 {regexp command compiling tests} {
+ evalInProc {
+ regexp -n foo dogfoOd
+ }
+} 1
+test regexpComp-21.7 {regexp command compiling tests} {
+ evalInProc {
+ regexp -no -- FoO dogfood
+ }
+} 1
+test regexpComp-21.8 {regexp command compiling tests} {
+ evalInProc {
+ regexp -- foo dogfod
+ }
+} 0
+test regexpComp-21.9 {regexp command compiling tests} {
+ evalInProc {
+ list [catch {regexp -- -nocase foo dogfod} msg] $msg
+ }
+} {0 0}
+test regexpComp-21.10 {regexp command compiling tests} {
+ evalInProc {
+ list [regsub -all "" foo bar str] $str
+ }
+} {3 barfbarobaro}
+test regexpComp-21.11 {regexp command compiling tests} {
+ evalInProc {
+ list [regsub -all "" "" bar str] $str
+ }
+} {0 {}}
+
+test regexpComp-22.0.1 {Bug 1810038} {
+ evalInProc {
+ regexp ($|^X)* {}
+ }
+} 1
+
+test regexpComp-22.0.2 {regexp compile and backrefs, Bug 1857126} {
+ evalInProc {
+ regexp -- {([bc])\1} bb
+ }
+} 1
+
+set i 0
+foreach {str exp result} {
+ foo ^foo 1
+ foobar ^foobar$ 1
+ foobar bar$ 1
+ foobar ^$ 0
+ "" ^$ 1
+ anything $ 1
+ anything ^.*$ 1
+ anything ^.*a$ 0
+ anything ^.*a.*$ 1
+ anything ^.*.*$ 1
+ anything ^.*..*$ 1
+ anything ^.*b$ 0
+ anything ^a.*$ 1
+} {
+ test regexpComp-22.[incr i] {regexp command compiling tests} \
+ [subst {evalInProc {set a "$str"; regexp {$exp} \$a}}] $result
+}
+
+set i 0
+foreach {str exp result} {
+ foo ^foo 1
+ foobar ^foobar$ 1
+ foobar bar$ 1
+ foobar ^$ 0
+ "" ^$ 1
+ anything $ 1
+ anything ^.*$ 1
+ anything ^.*a$ 0
+ anything ^.*a.*$ 1
+ anything ^.*.*$ 1
+ anything ^.*..*$ 1
+ anything ^.*b$ 0
+ anything ^a.*$ 1
+} {
+ test regexpComp-23.[incr i] {regexp command compiling tests INST_REGEXP} \
+ [subst {evalInProc {set a "$str"; set re "$exp"; regexp \$re \$a}}] $result
+}
+
+test regexpComp-24.1 {regexp command compiling tests} {
+ evalInProc {
+ set re foo
+ regexp -nocase $re bar
+ }
+} 0
+test regexpComp-24.2 {regexp command compiling tests} {
+ evalInProc {
+ set re {^foo$}
+ regexp $re dogfood
+ }
+} 0
+test regexpComp-24.3 {regexp command compiling tests} {
+ evalInProc {
+ set a foo
+ set re {^foo$}
+ regexp $re $a
+ }
+} 1
+test regexpComp-24.4 {regexp command compiling tests} {
+ evalInProc {
+ set re foo
+ regexp $re dogfood
+ }
+} 1
+test regexpComp-24.5 {regexp command compiling tests} {
+ evalInProc {
+ set re FOO
+ regexp -nocase $re dogfod
+ }
+} 0
+test regexpComp-24.6 {regexp command compiling tests} {
+ evalInProc {
+ set re foo
+ regexp -n $re dogfoOd
+ }
+} 1
+test regexpComp-24.7 {regexp command compiling tests} {
+ evalInProc {
+ set re FoO
+ regexp -no -- $re dogfood
+ }
+} 1
+test regexpComp-24.8 {regexp command compiling tests} {
+ evalInProc {
+ set re foo
+ regexp -- $re dogfod
+ }
+} 0
+test regexpComp-24.9 {regexp command compiling tests} {
+ evalInProc {
+ set re "("
+ list [catch {regexp -- $re dogfod} msg] $msg
+ }
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexpComp-24.10 {regexp command compiling tests} {
+ # Bug 1902436 - last * escaped
+ evalInProc {
+ set text {this is *bold* !}
+ set re {\*bold\*}
+ regexp -- $re $text
+ }
+} 1
+test regexpComp-24.11 {regexp command compiling tests} {
+ # Bug 1902436 - last * escaped
+ evalInProc {
+ set text {this is *bold* !}
+ set re {\*bold\*.*!}
+ regexp -- $re $text
+ }
+} 1
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/registry.test b/pkgs/msgcat/tests/registry.test
new file mode 100644
index 0000000..400277f
--- /dev/null
+++ b/pkgs/msgcat/tests/registry.test
@@ -0,0 +1,691 @@
+# registry.test --
+#
+# This file contains a collection of tests for the registry command.
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# In order for these tests to run, the registry package must be on the
+# auto_path or the registry package must have been loaded already.
+#
+# Copyright (c) 1997 by Sun Microsystems, Inc. All rights reserved.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint reg 0
+if {[testConstraint win]} {
+ catch {
+ # Is the registry extension already static to this shell?
+ if [catch {load {} Registry; set ::reglib {}}] {
+ # try the location given to use on the commandline to tcltest
+ ::tcltest::loadTestedCommands
+ load $::reglib Registry
+ }
+ testConstraint reg 1
+ }
+}
+
+# determine the current locale
+testConstraint english [expr {
+ [llength [info commands testlocale]]
+ && [string match "English*" [testlocale all ""]]
+}]
+
+test registry-1.1 {argument parsing for registry command} {win reg} {
+ list [catch {registry} msg] $msg
+} {1 {wrong # args: should be "registry ?-32bit|-64bit? option ?arg ...?"}}
+test registry-1.1a {argument parsing for registry command} {win reg} {
+ list [catch {registry -32bit} msg] $msg
+} {1 {wrong # args: should be "registry ?-32bit|-64bit? option ?arg ...?"}}
+test registry-1.1b {argument parsing for registry command} {win reg} {
+ list [catch {registry -64bit} msg] $msg
+} {1 {wrong # args: should be "registry ?-32bit|-64bit? option ?arg ...?"}}
+test registry-1.2 {argument parsing for registry command} {win reg} {
+ list [catch {registry foo} msg] $msg
+} {1 {bad option "foo": must be broadcast, delete, get, keys, set, type, or values}}
+test registry-1.2a {argument parsing for registry command} {win reg} {
+ list [catch {registry -33bit foo} msg] $msg
+} {1 {bad mode "-33bit": must be -32bit or -64bit}}
+
+test registry-1.3 {argument parsing for registry command} {win reg} {
+ list [catch {registry d} msg] $msg
+} {1 {wrong # args: should be "registry delete keyName ?valueName?"}}
+test registry-1.3a {argument parsing for registry command} {win reg} {
+ list [catch {registry -32bit d} msg] $msg
+} {1 {wrong # args: should be "registry -32bit delete keyName ?valueName?"}}
+test registry-1.3b {argument parsing for registry command} {win reg} {
+ list [catch {registry -64bit d} msg] $msg
+} {1 {wrong # args: should be "registry -64bit delete keyName ?valueName?"}}
+test registry-1.4 {argument parsing for registry command} {win reg} {
+ list [catch {registry delete} msg] $msg
+} {1 {wrong # args: should be "registry delete keyName ?valueName?"}}
+test registry-1.5 {argument parsing for registry command} {win reg} {
+ list [catch {registry delete foo bar baz} msg] $msg
+} {1 {wrong # args: should be "registry delete keyName ?valueName?"}}
+
+test registry-1.6 {argument parsing for registry command} {win reg} {
+ list [catch {registry g} msg] $msg
+} {1 {wrong # args: should be "registry get keyName valueName"}}
+test registry-1.6a {argument parsing for registry command} {win reg} {
+ list [catch {registry -32bit g} msg] $msg
+} {1 {wrong # args: should be "registry -32bit get keyName valueName"}}
+test registry-1.6b {argument parsing for registry command} {win reg} {
+ list [catch {registry -64bit g} msg] $msg
+} {1 {wrong # args: should be "registry -64bit get keyName valueName"}}
+test registry-1.7 {argument parsing for registry command} {win reg} {
+ list [catch {registry get} msg] $msg
+} {1 {wrong # args: should be "registry get keyName valueName"}}
+test registry-1.8 {argument parsing for registry command} {win reg} {
+ list [catch {registry get foo} msg] $msg
+} {1 {wrong # args: should be "registry get keyName valueName"}}
+test registry-1.9 {argument parsing for registry command} {win reg} {
+ list [catch {registry get foo bar baz} msg] $msg
+} {1 {wrong # args: should be "registry get keyName valueName"}}
+
+test registry-1.10 {argument parsing for registry command} {win reg} {
+ list [catch {registry k} msg] $msg
+} {1 {wrong # args: should be "registry keys keyName ?pattern?"}}
+test registry-1.10a {argument parsing for registry command} {win reg} {
+ list [catch {registry -32bit k} msg] $msg
+} {1 {wrong # args: should be "registry -32bit keys keyName ?pattern?"}}
+test registry-1.10b {argument parsing for registry command} {win reg} {
+ list [catch {registry -64bit k} msg] $msg
+} {1 {wrong # args: should be "registry -64bit keys keyName ?pattern?"}}
+test registry-1.11 {argument parsing for registry command} {win reg} {
+ list [catch {registry keys} msg] $msg
+} {1 {wrong # args: should be "registry keys keyName ?pattern?"}}
+test registry-1.12 {argument parsing for registry command} {win reg} {
+ list [catch {registry keys foo bar baz} msg] $msg
+} {1 {wrong # args: should be "registry keys keyName ?pattern?"}}
+
+test registry-1.13 {argument parsing for registry command} {win reg} {
+ list [catch {registry s} msg] $msg
+} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
+test registry-1.13a {argument parsing for registry command} {win reg} {
+ list [catch {registry -32bit s} msg] $msg
+} {1 {wrong # args: should be "registry -32bit set keyName ?valueName data ?type??"}}
+test registry-1.13b {argument parsing for registry command} {win reg} {
+ list [catch {registry -64bit s} msg] $msg
+} {1 {wrong # args: should be "registry -64bit set keyName ?valueName data ?type??"}}
+test registry-1.14 {argument parsing for registry command} {win reg} {
+ list [catch {registry set} msg] $msg
+} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
+test registry-1.15 {argument parsing for registry command} {win reg} {
+ list [catch {registry set foo bar} msg] $msg
+} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
+test registry-1.16 {argument parsing for registry command} {win reg} {
+ list [catch {registry set foo bar baz blat gorp} msg] $msg
+} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
+
+test registry-1.17 {argument parsing for registry command} {win reg} {
+ list [catch {registry t} msg] $msg
+} {1 {wrong # args: should be "registry type keyName valueName"}}
+test registry-1.17a {argument parsing for registry command} {win reg} {
+ list [catch {registry -32bit t} msg] $msg
+} {1 {wrong # args: should be "registry -32bit type keyName valueName"}}
+test registry-1.17b {argument parsing for registry command} {win reg} {
+ list [catch {registry -64bit t} msg] $msg
+} {1 {wrong # args: should be "registry -64bit type keyName valueName"}}
+test registry-1.18 {argument parsing for registry command} {win reg} {
+ list [catch {registry type} msg] $msg
+} {1 {wrong # args: should be "registry type keyName valueName"}}
+test registry-1.19 {argument parsing for registry command} {win reg} {
+ list [catch {registry type foo} msg] $msg
+} {1 {wrong # args: should be "registry type keyName valueName"}}
+test registry-1.20 {argument parsing for registry command} {win reg} {
+ list [catch {registry type foo bar baz} msg] $msg
+} {1 {wrong # args: should be "registry type keyName valueName"}}
+
+test registry-1.21 {argument parsing for registry command} {win reg} {
+ list [catch {registry v} msg] $msg
+} {1 {wrong # args: should be "registry values keyName ?pattern?"}}
+test registry-1.21a {argument parsing for registry command} {win reg} {
+ list [catch {registry -32bit v} msg] $msg
+} {1 {wrong # args: should be "registry -32bit values keyName ?pattern?"}}
+test registry-1.21b {argument parsing for registry command} {win reg} {
+ list [catch {registry -64bit v} msg] $msg
+} {1 {wrong # args: should be "registry -64bit values keyName ?pattern?"}}
+test registry-1.22 {argument parsing for registry command} {win reg} {
+ list [catch {registry values} msg] $msg
+} {1 {wrong # args: should be "registry values keyName ?pattern?"}}
+test registry-1.23 {argument parsing for registry command} {win reg} {
+ list [catch {registry values foo bar baz} msg] $msg
+} {1 {wrong # args: should be "registry values keyName ?pattern?"}}
+
+test registry-2.1 {DeleteKey: bad key} {win reg} {
+ list [catch {registry delete foo} msg] $msg
+} {1 {bad root name "foo": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}}
+test registry-2.2 {DeleteKey: bad key} {win reg} {
+ list [catch {registry delete HKEY_CLASSES_ROOT} msg] $msg
+} {1 {bad key: cannot delete root keys}}
+test registry-2.3 {DeleteKey: bad key} {win reg} {
+ list [catch {registry delete HKEY_CLASSES_ROOT\\} msg] $msg
+} {1 {bad key: cannot delete root keys}}
+test registry-2.4 {DeleteKey: subkey at root level} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry keys HKEY_CURRENT_USER TclFoobar
+} {}
+test registry-2.5 {DeleteKey: subkey below root level} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test
+ registry delete HKEY_CURRENT_USER\\TclFoobar\\test
+ set result [registry keys HKEY_CURRENT_USER TclFoobar\\test]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {}
+test registry-2.6 {DeleteKey: recursive delete} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test1
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test2\\test3
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result [registry keys HKEY_CURRENT_USER TclFoobar]
+ set result
+} {}
+test registry-2.7 {DeleteKey: trailing backslashes} {win reg english} {
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz
+ list [catch {registry delete HKEY_CURRENT_USER\\TclFoobar\\} msg] $msg
+} {1 {unable to delete key: The configuration registry key is invalid.}}
+test registry-2.8 {DeleteKey: failure} {win reg} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} {}
+test registry-2.9 {DeleteKey: unicode} {win reg} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test\u00c7bar\\a
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test\u00c7bar\\b
+ registry delete HKEY_CURRENT_USER\\TclFoobar\\test\u00c7bar
+ set result [registry keys HKEY_CURRENT_USER\\TclFoobar]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {}
+
+test registry-3.1 {DeleteValue} {win reg} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz test1 blort
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz test2 blat
+ registry delete HKEY_CURRENT_USER\\TclFoobar\\baz test1
+ set result [registry values HKEY_CURRENT_USER\\TclFoobar\\baz]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} test2
+test registry-3.2 {DeleteValue: bad key} {win reg english} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ list [catch {registry delete HKEY_CURRENT_USER\\TclFoobar test} msg] $msg
+} {1 {unable to open key: The system cannot find the file specified.}}
+test registry-3.3 {DeleteValue: bad value} {win reg english} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz test2 blort
+ set result [list [catch {registry delete HKEY_CURRENT_USER\\TclFoobar test1} msg] $msg]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {1 {unable to delete value "test1" from key "HKEY_CURRENT_USER\TclFoobar": The system cannot find the file specified.}}
+test registry-3.4 {DeleteValue: Unicode} {win reg} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\\u00c7baz \u00c7test1 blort
+ registry set HKEY_CURRENT_USER\\TclFoobar\\\u00c7baz test2 blat
+ registry delete HKEY_CURRENT_USER\\TclFoobar\\\u00c7baz \u00c7test1
+ set result [registry values HKEY_CURRENT_USER\\TclFoobar\\\u00c7baz]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} test2
+
+test registry-4.1 {GetKeyNames: bad key} {win reg english} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ list [catch {registry keys HKEY_CURRENT_USER\\TclFoobar} msg] $msg
+} {1 {unable to open key: The system cannot find the file specified.}}
+test registry-4.2 {GetKeyNames} {win reg} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz
+ set result [registry keys HKEY_CURRENT_USER\\TclFoobar]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {baz}
+test registry-4.3 {GetKeyNames: remote key} {win reg nonPortable english} {
+ set hostname [info hostname]
+ registry set \\\\$hostname\\HKEY_CURRENT_USER\\TclFoobar\\baz
+ set result [registry keys \\\\gaspode\\HKEY_CURRENT_USER\\TclFoobar]
+ registry delete \\\\$hostname\\HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {baz}
+test registry-4.4 {GetKeyNames: empty key} {win reg} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar
+ set result [registry keys HKEY_CURRENT_USER\\TclFoobar]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {}
+test registry-4.5 {GetKeyNames: patterns} {win reg} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz
+ registry set HKEY_CURRENT_USER\\TclFoobar\\blat
+ registry set HKEY_CURRENT_USER\\TclFoobar\\foo
+ set result [lsort [registry keys HKEY_CURRENT_USER\\TclFoobar b*]]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {baz blat}
+test registry-4.6 {GetKeyNames: names with spaces} {win reg} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz\ bar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\blat
+ registry set HKEY_CURRENT_USER\\TclFoobar\\foo
+ set result [lsort [registry keys HKEY_CURRENT_USER\\TclFoobar b*]]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {{baz bar} blat}
+test registry-4.7 {GetKeyNames: Unicode} {win reg english} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz\u00c7bar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\blat
+ registry set HKEY_CURRENT_USER\\TclFoobar\\foo
+ set result [lsort [registry keys HKEY_CURRENT_USER\\TclFoobar b*]]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} "baz\u00c7bar blat"
+test registry-4.8 {GetKeyNames: Unicode} {win reg nt} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz\u30b7bar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\blat
+ registry set HKEY_CURRENT_USER\\TclFoobar\\foo
+ set result [lsort [registry keys HKEY_CURRENT_USER\\TclFoobar b*]]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} "baz\u30b7bar blat"
+test registry-4.9 {GetKeyNames: very long key [Bug 1682211]} {*}{
+ -constraints {win reg}
+ -setup {
+ registry set HKEY_CURRENT_USER\\TclFoobar\\a
+ registry set HKEY_CURRENT_USER\\TclFoobar\\b[string repeat x 254]
+ registry set HKEY_CURRENT_USER\\TclFoobar\\c
+ }
+ -body {
+ lsort [registry keys HKEY_CURRENT_USER\\TclFoobar]
+ }
+ -cleanup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ }} \
+ -result [list a b[string repeat x 254] c]
+
+test registry-5.1 {GetType} {win reg english} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ list [catch {registry type HKEY_CURRENT_USER\\TclFoobar val1} msg] $msg
+} {1 {unable to open key: The system cannot find the file specified.}}
+test registry-5.2 {GetType} {win reg english} {
+ registry set HKEY_CURRENT_USER\\TclFoobar
+ list [catch {registry type HKEY_CURRENT_USER\\TclFoobar val1} msg] $msg
+} {1 {unable to get type of value "val1" from key "HKEY_CURRENT_USER\TclFoobar": The system cannot find the file specified.}}
+test registry-5.3 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar none
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} none
+test registry-5.4 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} sz
+test registry-5.5 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar sz
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} sz
+test registry-5.6 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar expand_sz
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} expand_sz
+test registry-5.7 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 binary
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} binary
+test registry-5.8 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 dword
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} dword
+test registry-5.9 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 dword_big_endian
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} dword_big_endian
+test registry-5.10 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 link
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} link
+test registry-5.11 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar multi_sz
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} multi_sz
+test registry-5.12 {GetType} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 resource_list
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} resource_list
+test registry-5.13 {GetType: unknown types} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 24
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} 24
+test registry-5.14 {GetType: Unicode} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar va\u00c7l1 1 24
+ set result [registry type HKEY_CURRENT_USER\\TclFoobar va\u00c7l1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} 24
+
+test registry-6.1 {GetValue} {win reg english} {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ list [catch {registry get HKEY_CURRENT_USER\\TclFoobar val1} msg] $msg
+} {1 {unable to open key: The system cannot find the file specified.}}
+test registry-6.2 {GetValue} {win reg english} {
+ registry set HKEY_CURRENT_USER\\TclFoobar
+ list [catch {registry get HKEY_CURRENT_USER\\TclFoobar val1} msg] $msg
+} {1 {unable to get value "val1" from key "HKEY_CURRENT_USER\TclFoobar": The system cannot find the file specified.}}
+test registry-6.3 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar none
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} foobar
+test registry-6.4 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} foobar
+test registry-6.5 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} foobar
+test registry-6.6 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar expand_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} foobar
+test registry-6.7 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 binary
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} 1
+test registry-6.8 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 0x20 dword
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} 32
+test registry-6.9 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 0x20 dword_big_endian
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} 32
+test registry-6.10 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 link
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} 1
+test registry-6.11 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} foobar
+test registry-6.12 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 {foo\ bar baz} multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {{foo bar} baz}
+test registry-6.13 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 {} multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} {}
+test registry-6.14 {GetValue: truncation of multivalues with null elements} \
+ {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 {a {} b} multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} a
+test registry-6.15 {GetValue} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 resource_list
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} 1
+test registry-6.16 {GetValue: unknown types} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 1 24
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} 1
+test registry-6.17 {GetValue: Unicode value names} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val\u00c71 foobar multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val\u00c71]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} foobar
+test registry-6.18 {GetValue: values with Unicode strings} {win reg nt} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 {foo ba\u30b7r baz} multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} "foo ba\u30b7r baz"
+test registry-6.19 {GetValue: values with Unicode strings} {win reg english} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 {foo ba\u00c7r baz} multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} "foo ba\u00c7r baz"
+test registry-6.20 {GetValue: values with Unicode strings with embedded nulls} {win reg} {
+ registry set HKEY_CURRENT_USER\\TclFoobar val1 {foo ba\u0000r baz} multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} "foo ba r baz"
+test registry-6.21 {GetValue: very long value names and values} {pcOnly} {
+ registry set HKEY_CURRENT_USER\\TclFoobar [string repeat k 16383] [string repeat x 16383] multi_sz
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar [string repeat k 16383]]
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result
+} [string repeat x 16383]
+
+test registry-7.1 {GetValueNames: bad key} -constraints {win reg english} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -body {
+ registry values HKEY_CURRENT_USER\\TclFoobar
+} -returnCodes error -result {unable to open key: The system cannot find the file specified.}
+test registry-7.2 {GetValueNames} -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar baz foobar
+} -body {
+ registry values HKEY_CURRENT_USER\\TclFoobar
+} -cleanup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result baz
+test registry-7.3 {GetValueNames} -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar baz foobar1
+ registry set HKEY_CURRENT_USER\\TclFoobar blat foobar2
+ registry set HKEY_CURRENT_USER\\TclFoobar {} foobar3
+} -body {
+ lsort [registry values HKEY_CURRENT_USER\\TclFoobar]
+} -cleanup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {{} baz blat}
+test registry-7.4 {GetValueNames: remote key} -constraints {win reg nonPortable english} -body {
+ set hostname [info hostname]
+ registry set \\\\$hostname\\HKEY_CURRENT_USER\\TclFoobar baz blat
+ set result [registry values \\\\$hostname\\HKEY_CURRENT_USER\\TclFoobar]
+ registry delete \\\\$hostname\\HKEY_CURRENT_USER\\TclFoobar
+ set result
+} -result baz
+test registry-7.5 {GetValueNames: empty key} -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar
+} -body {
+ registry values HKEY_CURRENT_USER\\TclFoobar
+} -cleanup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {}
+test registry-7.6 {GetValueNames: patterns} -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar baz foobar1
+ registry set HKEY_CURRENT_USER\\TclFoobar blat foobar2
+ registry set HKEY_CURRENT_USER\\TclFoobar foo foobar3
+} -body {
+ lsort [registry values HKEY_CURRENT_USER\\TclFoobar b*]
+} -cleanup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {baz blat}
+test registry-7.7 {GetValueNames: names with spaces} -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar baz\ bar foobar1
+ registry set HKEY_CURRENT_USER\\TclFoobar blat foobar2
+ registry set HKEY_CURRENT_USER\\TclFoobar foo foobar3
+} -body {
+ lsort [registry values HKEY_CURRENT_USER\\TclFoobar b*]
+} -cleanup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {{baz bar} blat}
+
+test registry-8.1 {OpenSubKey} -constraints {win reg nonPortable english} \
+ -body {
+ # This test will only succeed if the current user does not have
+ # registry access on the specified machine.
+ registry keys {\\mom\HKEY_LOCAL_MACHINE}
+ } -returnCodes error -result "unable to open key: Access is denied."
+test registry-8.2 {OpenSubKey} -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar
+} -body {
+ registry keys HKEY_CURRENT_USER TclFoobar
+} -cleanup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {TclFoobar}
+test registry-8.3 {OpenSubKey} -constraints {win reg english} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -body {
+ registry keys HKEY_CURRENT_USER\\TclFoobar
+} -returnCodes error \
+ -result "unable to open key: The system cannot find the file specified."
+
+test registry-9.1 {ParseKeyName: bad keys} -constraints {win reg} -body {
+ registry values \\
+} -returnCodes error -result "bad key \"\\\": must start with a valid root"
+test registry-9.2 {ParseKeyName: bad keys} -constraints {win reg} -body {
+ registry values \\foobar
+} -returnCodes error -result {bad key "\foobar": must start with a valid root}
+test registry-9.3 {ParseKeyName: bad keys} -constraints {win reg} -body {
+ registry values \\\\
+} -returnCodes error -result {bad root name "": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}
+test registry-9.4 {ParseKeyName: bad keys} -constraints {win reg} -body {
+ registry values \\\\\\
+} -returnCodes error -result {bad root name "": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}
+test registry-9.5 {ParseKeyName: bad keys} -constraints {win reg english nt} -body {
+ registry values \\\\\\HKEY_CLASSES_ROOT
+} -returnCodes error -result {unable to open key: The network address is invalid.}
+test registry-9.6 {ParseKeyName: bad keys} -constraints {win reg} -body {
+ registry values \\\\gaspode
+} -returnCodes error -result {bad root name "": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}
+test registry-9.7 {ParseKeyName: bad keys} -constraints {win reg} -body {
+ registry values foobar
+} -returnCodes error -result {bad root name "foobar": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}
+test registry-9.8 {ParseKeyName: null keys} -constraints {win reg} -body {
+ registry delete HKEY_CLASSES_ROOT\\
+} -returnCodes error -result {bad key: cannot delete root keys}
+test registry-9.9 {ParseKeyName: null keys} \
+ -constraints {win reg english} \
+ -body {registry keys HKEY_CLASSES_ROOT\\TclFoobar\\baz} \
+ -returnCodes error \
+ -result {unable to open key: The system cannot find the file specified.}
+
+test registry-10.1 {RecursiveDeleteKey} -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -body {
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test1
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test2\\test3
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ set result [registry keys HKEY_CURRENT_USER TclFoobar]
+ set result
+} -result {}
+test registry-10.2 {RecursiveDeleteKey} -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test1
+ registry set HKEY_CURRENT_USER\\TclFoobar\\test2\\test3
+} -body {
+ registry delete HKEY_CURRENT_USER\\TclFoobar\\test2\\test4
+} -cleanup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {}
+
+test registry-11.1 {SetValue: recursive creation} \
+ -constraints {win reg} -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ } -body {
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz blat foobar
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar\\baz blat]
+ } -result {foobar}
+test registry-11.2 {SetValue: modification} -constraints {win reg} \
+ -setup {
+ registry delete HKEY_CURRENT_USER\\TclFoobar
+ } -body {
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz blat foobar
+ registry set HKEY_CURRENT_USER\\TclFoobar\\baz blat frob
+ set result [registry get HKEY_CURRENT_USER\\TclFoobar\\baz blat]
+ } -result {frob}
+test registry-11.3 {SetValue: failure} \
+ -constraints {win reg nonPortable english} \
+ -body {
+ # This test will only succeed if the current user does not have
+ # registry access on the specified machine.
+ registry set {\\mom\HKEY_CURRENT_USER\TclFoobar} bar foobar
+ } -returnCodes error -result {unable to open key: Access is denied.}
+
+test registry-12.1 {BroadcastValue} -constraints {win reg} -body {
+ registry broadcast
+} -returnCodes error -result "wrong # args: should be \"registry broadcast keyName ?-timeout milliseconds?\""
+test registry-12.2 {BroadcastValue} -constraints {win reg} -body {
+ registry broadcast "" -time
+} -returnCodes error -result "wrong # args: should be \"registry broadcast keyName ?-timeout milliseconds?\""
+test registry-12.3 {BroadcastValue} -constraints {win reg} -body {
+ registry broadcast "" - 500
+} -returnCodes error -result "wrong # args: should be \"registry broadcast keyName ?-timeout milliseconds?\""
+test registry-12.4 {BroadcastValue} -constraints {win reg} -body {
+ registry broadcast {Environment}
+} -result {1 0}
+test registry-12.5 {BroadcastValue} -constraints {win reg} -body {
+ registry b {}
+} -result {1 0}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# tcl-indent-level: 4
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/remote.tcl b/pkgs/msgcat/tests/remote.tcl
new file mode 100644
index 0000000..097e41f
--- /dev/null
+++ b/pkgs/msgcat/tests/remote.tcl
@@ -0,0 +1,159 @@
+# This file contains Tcl code to implement a remote server that can be
+# used during testing of Tcl socket code. This server is used by some
+# of the tests in socket.test.
+#
+# Source this file in the remote server you are using to test Tcl against.
+#
+# 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.
+
+# Initialize message delimitor
+
+# Initialize command array
+catch {unset command}
+set command(0) ""
+set callerSocket ""
+
+# Detect whether we should print out connection messages etc.
+if {![info exists VERBOSE]} {
+ set VERBOSE 0
+}
+
+proc __doCommands__ {l s} {
+ global callerSocket VERBOSE
+
+ if {$VERBOSE} {
+ puts "--- Server executing the following for socket $s:"
+ puts $l
+ puts "---"
+ }
+ set callerSocket $s
+ set ::errorInfo ""
+ set code [catch {uplevel "#0" $l} msg]
+ return [list $code $::errorInfo $msg]
+}
+
+proc __readAndExecute__ {s} {
+ global command VERBOSE
+
+ set l [gets $s]
+ if {[string compare $l "--Marker--Marker--Marker--"] == 0} {
+ puts $s [__doCommands__ $command($s) $s]
+ puts $s "--Marker--Marker--Marker--"
+ set command($s) ""
+ return
+ }
+ if {[string compare $l ""] == 0} {
+ if {[eof $s]} {
+ if {$VERBOSE} {
+ puts "Server closing $s, eof from client"
+ }
+ close $s
+ }
+ return
+ }
+ if {[eof $s]} {
+ if {$VERBOSE} {
+ puts "Server closing $s, eof from client"
+ }
+ close $s
+ unset command($s)
+ return
+ }
+ append command($s) $l "\n"
+}
+
+proc __accept__ {s a p} {
+ global command VERBOSE
+
+ if {$VERBOSE} {
+ puts "Server accepts new connection from $a:$p on $s"
+ }
+ set command($s) ""
+ fconfigure $s -buffering line -translation crlf
+ fileevent $s readable [list __readAndExecute__ $s]
+}
+
+set serverIsSilent 0
+for {set i 0} {$i < $argc} {incr i} {
+ if {[string compare -serverIsSilent [lindex $argv $i]] == 0} {
+ set serverIsSilent 1
+ break
+ }
+}
+if {![info exists serverPort]} {
+ if {[info exists env(serverPort)]} {
+ set serverPort $env(serverPort)
+ }
+}
+if {![info exists serverPort]} {
+ for {set i 0} {$i < $argc} {incr i} {
+ if {[string compare -port [lindex $argv $i]] == 0} {
+ if {$i < [expr $argc - 1]} {
+ set serverPort [lindex $argv [expr $i + 1]]
+ }
+ break
+ }
+ }
+}
+if {![info exists serverPort]} {
+ set serverPort 2048
+}
+
+if {![info exists serverAddress]} {
+ if {[info exists env(serverAddress)]} {
+ set serverAddress $env(serverAddress)
+ }
+}
+if {![info exists serverAddress]} {
+ for {set i 0} {$i < $argc} {incr i} {
+ if {[string compare -address [lindex $argv $i]] == 0} {
+ if {$i < [expr $argc - 1]} {
+ set serverAddress [lindex $argv [expr $i + 1]]
+ }
+ break
+ }
+ }
+}
+if {![info exists serverAddress]} {
+ set serverAddress 0.0.0.0
+}
+
+if {$serverIsSilent == 0} {
+ set l "Remote server listening on port $serverPort, IP $serverAddress."
+ puts ""
+ puts $l
+ for {set c [string length $l]} {$c > 0} {incr c -1} {puts -nonewline "-"}
+ puts ""
+ puts ""
+ puts "You have set the Tcl variables serverAddress to $serverAddress and"
+ puts "serverPort to $serverPort. You can set these with the -address and"
+ puts "-port command line options, or as environment variables in your"
+ puts "shell."
+ puts ""
+ puts "NOTE: The tests will not work properly if serverAddress is set to"
+ puts "\"localhost\" or 127.0.0.1."
+ puts ""
+ puts "When you invoke tcltest to run the tests, set the variables"
+ puts "remoteServerPort to $serverPort and remoteServerIP to"
+ puts "[info hostname]. You can set these as environment variables"
+ puts "from the shell. The tests will not work properly if you set"
+ puts "remoteServerIP to \"localhost\" or 127.0.0.1."
+ puts ""
+ puts -nonewline "Type Ctrl-C to terminate--> "
+ flush stdout
+}
+
+proc getPort sock {
+ lindex [fconfigure $sock -sockname] 2
+}
+
+if {[catch {set serverSocket \
+ [socket -myaddr $serverAddress -server __accept__ $serverPort]} msg]} {
+ puts "Server on $serverAddress:$serverPort cannot start: $msg"
+} else {
+ puts ready
+ vwait __server_wait_variable__
+}
diff --git a/pkgs/msgcat/tests/rename.test b/pkgs/msgcat/tests/rename.test
new file mode 100644
index 0000000..9ac49b4
--- /dev/null
+++ b/pkgs/msgcat/tests/rename.test
@@ -0,0 +1,182 @@
+# Commands covered: rename
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testdel [llength [info commands testdel]]
+
+# Must eliminate the "unknown" command while the test is running, especially
+# if the test is being run in a program with its own special-purpose unknown
+# command.
+catch {rename unknown unknown.old}
+
+catch {rename r2 {}}
+proc r1 {} {return "procedure r1"}
+rename r1 r2
+
+test rename-1.1 {simple renaming} {
+ r2
+} {procedure r1}
+test rename-1.2 {simple renaming} {
+ list [catch r1 msg] $msg
+} {1 {invalid command name "r1"}}
+rename r2 {}
+test rename-1.3 {simple renaming} {
+ list [catch r2 msg] $msg
+} {1 {invalid command name "r2"}}
+
+# The test below is tricky because it renames a built-in command. It's
+# possible that the test procedure uses this command, so must restore the
+# command before calling test again.
+rename list l.new
+set a [catch list msg1]
+set b [l.new a b c]
+rename l.new list
+set c [catch l.new msg2]
+set d [list 111 222]
+test rename-2.1 {renaming built-in command} {
+ list $a $msg1 $b $c $msg2 $d
+} {1 {invalid command name "list"} {a b c} 1 {invalid command name "l.new"} {111 222}}
+
+test rename-3.1 {error conditions} {
+ list [catch {rename r1} msg] $msg $errorCode
+} {1 {wrong # args: should be "rename oldName newName"} {TCL WRONGARGS}}
+test rename-3.2 {error conditions} {
+ list [catch {rename r1 r2 r3} msg] $msg $errorCode
+} {1 {wrong # args: should be "rename oldName newName"} {TCL WRONGARGS}}
+test rename-3.3 {error conditions} -setup {
+ proc r1 {} {}
+ proc r2 {} {}
+} -returnCodes error -body {
+ rename r1 r2
+} -result {can't rename to "r2": command already exists}
+test rename-3.4 {error conditions} -setup {
+ catch {rename r1 {}}
+ catch {rename r2 {}}
+} -returnCodes error -body {
+ rename r1 r2
+} -result {can't rename "r1": command doesn't exist}
+test rename-3.5 {error conditions} -setup {
+ catch {rename _non_existent_command {}}
+} -returnCodes error -body {
+ rename _non_existent_command {}
+} -result {can't delete "_non_existent_command": command doesn't exist}
+
+catch {rename unknown {}}
+catch {rename unknown.old unknown}
+catch {rename bar {}}
+
+test rename-4.1 {reentrancy issues with command deletion and renaming} testdel {
+ set x {}
+ testdel {} foo {lappend x deleted; rename bar {}; lappend x [info command bar]}
+ rename foo bar
+ lappend x |
+ rename bar {}
+ set x
+} {| deleted {}}
+test rename-4.2 {reentrancy issues with command deletion and renaming} testdel {
+ set x {}
+ testdel {} foo {lappend x deleted; rename foo bar}
+ rename foo {}
+ set x
+} {deleted}
+test rename-4.3 {reentrancy issues with command deletion and renaming} testdel {
+ set x {}
+ testdel {} foo {lappend x deleted; testdel {} foo {lappend x deleted2}}
+ rename foo {}
+ lappend x |
+ rename foo {}
+ set x
+} {deleted | deleted2}
+test rename-4.4 {reentrancy issues with command deletion and renaming} testdel {
+ set x {}
+ testdel {} foo {lappend x deleted; rename foo bar}
+ rename foo {}
+ lappend x | [info command bar]
+} {deleted | {}}
+test rename-4.5 {reentrancy issues with command deletion and renaming} testdel {
+ set env(value) before
+ interp create foo
+ testdel foo cmd {set env(value) deleted}
+ interp delete foo
+ set env(value)
+} {deleted}
+test rename-4.6 {reentrancy issues with command deletion and renaming} testdel {
+ proc kill args {
+ interp delete foo
+ }
+ set env(value) before
+ interp create foo
+ foo alias kill kill
+ testdel foo cmd {set env(value) deleted; kill}
+ list [catch {foo eval {rename cmd {}}} msg] $msg $env(value)
+} {0 {} deleted}
+test rename-4.7 {reentrancy issues with command deletion and renaming} testdel {
+ proc kill args {
+ interp delete foo
+ }
+ set env(value) before
+ interp create foo
+ foo alias kill kill
+ testdel foo cmd {set env(value) deleted; kill}
+ list [catch {interp delete foo} msg] $msg $env(value)
+} {0 {} deleted}
+if {[info exists env(value)]} {
+ unset env(value)
+}
+
+# Save the unknown procedure which is modified by the following test.
+
+catch {rename unknown unknown.old}
+
+set SAVED_UNKNOWN "proc unknown "
+append SAVED_UNKNOWN [list [info args unknown.old] [info body unknown.old]]
+test rename-5.1 {repeated rename deletion and redefinition of same command} {
+ for {set i 0} {$i < 10} {incr i} {
+ eval $SAVED_UNKNOWN
+ tcl_wordBreakBefore "" 0
+ rename tcl_wordBreakBefore {}
+ rename unknown {}
+ }
+} {}
+
+catch {rename unknown {}}
+catch {rename unknown.old unknown}
+
+test rename-6.1 {old code invalidated (epoch incremented) when cmd with compile proc is renamed} -body {
+ proc x {} {
+ set a 123
+ set b [incr a]
+ }
+ x
+ rename incr incr.old
+ proc incr {} {puts "new incr called!"}
+ x
+} -cleanup {
+ rename incr {}
+ rename incr.old incr
+} -returnCodes error -result {wrong # args: should be "incr"}
+
+if {[info commands incr.old] != {}} {
+ catch {rename incr {}}
+ catch {rename incr.old incr}
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/resolver.test b/pkgs/msgcat/tests/resolver.test
new file mode 100644
index 0000000..bb9f59d
--- /dev/null
+++ b/pkgs/msgcat/tests/resolver.test
@@ -0,0 +1,200 @@
+# This test collection covers some unwanted interactions between command
+# literal sharing and the use of command resolvers (per-interp) which cause
+# command literals to be re-used with their command references being invalid
+# in the reusing context. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 2011 Gustaf Neumann <gustaf.neumann@wu.ac.at>
+# Copyright (c) 2011 Stefan Sobernig <stefan.sobernig@wu.ac.at>
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+if {"::tcltest" in [namespace children]} {
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testinterpresolver [llength [info commands testinterpresolver]]
+
+test resolver-1.1 {cmdNameObj sharing vs. cmd resolver: namespace import} -setup {
+ testinterpresolver up
+ namespace eval ::ns1 {
+ proc z {} { return Z }
+ namespace export z
+ }
+ proc ::y {} { return Y }
+ proc ::x {} {
+ z
+ }
+} -constraints testinterpresolver -body {
+ # 1) Have the proc body compiled: During compilation or, alternatively,
+ # the first evaluation of the compiled body, the InterpCmdResolver (see
+ # tclTest.c) maps the cmd token "z" to "::y"; this mapping is saved in the
+ # resulting CmdName Tcl_Obj with the print string "z". The CmdName Tcl_Obj
+ # is turned into a command literal shared for a given (here: the global)
+ # namespace.
+ set r0 [x]; # --> The result of [x] is "Y"
+ # 2) After having requested cmd resolution above, we can now use the
+ # globally shared CmdName Tcl_Obj "z", now bound to cmd ::y. This is
+ # certainly questionable, but defensible
+ set r1 [z]; # --> The result of [z] is "Y"
+ # 3) We import from the namespace ns1 another z. [namespace import] takes
+ # care "shadowed" cmd references, however, till now cmd literals have not
+ # been touched. This is, however, necessary since the BC compiler (used in
+ # the [namespace eval]) seems to be eager to reuse CmdName Tcl_Objs as cmd
+ # literals for a given NS scope. We expect, that r2 is "Z", the result of
+ # the namespace imported cmd.
+ namespace eval :: {
+ namespace import ::ns1::z
+ set r2 [z]
+ }
+ list $r0 $r1 $::r2
+} -cleanup {
+ testinterpresolver down
+ rename ::x ""
+ rename ::y ""
+ namespace delete ::ns1
+} -result {Y Y Z}
+test resolver-1.2 {cmdNameObj sharing vs. cmd resolver: proc creation} -setup {
+ testinterpresolver up
+ proc ::y {} { return Y }
+ proc ::x {} {
+ z
+ }
+} -constraints testinterpresolver -body {
+ set r0 [x]
+ set r1 [z]
+ proc ::foo {} {
+ proc ::z {} { return Z }
+ return [z]
+ }
+ list $r0 $r1 [::foo]
+} -cleanup {
+ testinterpresolver down
+ rename ::x ""
+ rename ::y ""
+ rename ::foo ""
+ rename ::z ""
+} -result {Y Y Z}
+test resolver-1.3 {cmdNameObj sharing vs. cmd resolver: rename} -setup {
+ testinterpresolver up
+ proc ::Z {} { return Z }
+ proc ::y {} { return Y }
+ proc ::x {} {
+ z
+ }
+} -constraints testinterpresolver -body {
+ set r0 [x]
+ set r1 [z]
+ namespace eval :: {
+ rename ::Z ::z
+ set r2 [z]
+ }
+ list $r0 $r1 $r2
+} -cleanup {
+ testinterpresolver down
+ rename ::x ""
+ rename ::y ""
+ rename ::z ""
+} -result {Y Y Z}
+test resolver-1.4 {cmdNameObj sharing vs. cmd resolver: interp expose} -setup {
+ testinterpresolver up
+ proc ::Z {} { return Z }
+ interp hide {} Z
+ proc ::y {} { return Y }
+ proc ::x {} {
+ z
+ }
+} -constraints testinterpresolver -body {
+ set r0 [x]
+ set r1 [z]
+ interp expose {} Z z
+ namespace eval :: {
+ set r2 [z]
+ }
+ list $r0 $r1 $r2
+} -cleanup {
+ testinterpresolver down
+ rename ::x ""
+ rename ::y ""
+ rename ::z ""
+} -result {Y Y Z}
+test resolver-1.5 {cmdNameObj sharing vs. cmd resolver: other than global NS} -setup {
+ testinterpresolver up
+ namespace eval ::ns1 {
+ proc z {} { return Z }
+ namespace export z
+ }
+ proc ::y {} { return Y }
+ namespace eval ::ns2 {
+ proc x {} {
+ z
+ }
+ }
+} -constraints testinterpresolver -body {
+ set r0 [namespace eval ::ns2 {x}]
+ set r1 [namespace eval ::ns2 {z}]
+ namespace eval ::ns2 {
+ namespace import ::ns1::z
+ set r2 [z]
+ }
+ list $r0 $r1 $r2
+} -cleanup {
+ testinterpresolver down
+ namespace delete ::ns2
+ namespace delete ::ns1
+} -result {Y Y Z}
+test resolver-1.6 {cmdNameObj sharing vs. cmd resolver: interp alias} -setup {
+ testinterpresolver up
+ proc ::Z {} { return Z }
+ proc ::y {} { return Y }
+ proc ::x {} {
+ z
+ }
+} -constraints testinterpresolver -body {
+ set r0 [x]
+ set r1 [z]
+ namespace eval :: {
+ interp alias {} ::z {} ::Z
+ set r2 [z]
+ }
+ list $r0 $r1 $r2
+} -cleanup {
+ testinterpresolver down
+ rename ::x ""
+ rename ::y ""
+ rename ::Z ""
+} -result {Y Y Z}
+
+test resolver-2.1 {compiled var resolver: Bug #3383616} -setup {
+ testinterpresolver up
+ # The compiled var resolver fetches just variables starting with a capital
+ # "T" and stores some test information in the resolver-specific resolver
+ # var info.
+ proc ::x {} {
+ set T1 100
+ return $T1
+ }
+} -constraints testinterpresolver -body {
+ # Call "x" the first time, causing a byte code compilation of the body.
+ # During the compilation the compiled var resolver, the resolve-specific
+ # var info is allocated, during the execution of the body, the variable is
+ # fetched and cached.
+ x;
+ # During later calls, the cached variable is reused.
+ x
+ # When the proc is freed, the resolver-specific resolver var info is
+ # freed. This did not happen before fix #3383616.
+ rename ::x ""
+} -cleanup {
+ testinterpresolver down
+} -result {}
+
+cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/result.test b/pkgs/msgcat/tests/result.test
new file mode 100644
index 0000000..f080654
--- /dev/null
+++ b/pkgs/msgcat/tests/result.test
@@ -0,0 +1,146 @@
+# This file tests the routines in tclResult.c.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Some tests require the testsaveresult command
+
+testConstraint testsaveresult [llength [info commands testsaveresult]]
+testConstraint testsetobjerrorcode [llength [info commands testsetobjerrorcode]]
+testConstraint testseterrorcode [llength [info commands testseterrorcode]]
+testConstraint testreturn [llength [info commands testreturn]]
+
+test result-1.1 {Tcl_SaveInterpResult} {testsaveresult} {
+ testsaveresult small {set x 42} 0
+} {small result}
+test result-1.2 {Tcl_SaveInterpResult} {testsaveresult} {
+ testsaveresult append {set x 42} 0
+} {append result}
+test result-1.3 {Tcl_SaveInterpResult} {testsaveresult} {
+ testsaveresult dynamic {set x 42} 0
+} {dynamic result notCalled present}
+test result-1.4 {Tcl_SaveInterpResult} {testsaveresult} {
+ testsaveresult object {set x 42} 0
+} {object result same}
+test result-1.5 {Tcl_SaveInterpResult} {testsaveresult} {
+ testsaveresult small {set x 42} 1
+} {42}
+test result-1.6 {Tcl_SaveInterpResult} {testsaveresult} {
+ testsaveresult append {set x 42} 1
+} {42}
+test result-1.7 {Tcl_SaveInterpResult} {testsaveresult} {
+ testsaveresult dynamic {set x 42} 1
+} {42 called missing}
+test result-1.8 {Tcl_SaveInterpResult} {testsaveresult} {
+ testsaveresult object {set x 42} 1
+} {42 different}
+
+# Tcl_RestoreInterpResult is mostly tested by the previous tests except
+# for the following case
+
+test result-2.1 {Tcl_RestoreInterpResult} {testsaveresult} {
+ testsaveresult append {cd _foobar} 0
+} {append result}
+
+# Tcl_DiscardInterpResult is mostly tested by the previous tests except
+# for the following cases
+
+test result-3.1 {Tcl_DiscardInterpResult} -constraints testsaveresult -body {
+ testsaveresult append {cd _foobar} 1
+} -returnCodes error -result {couldn't change working directory to "_foobar": no such file or directory}
+test result-3.2 {Tcl_DiscardInterpResult} {testsaveresult} {
+ testsaveresult free {set x 42} 1
+} {42}
+
+test result-4.1 {Tcl_SetObjErrorCode - one arg} {testsetobjerrorcode} {
+ catch {testsetobjerrorcode 1}
+ list [set errorCode]
+} {1}
+test result-4.2 {Tcl_SetObjErrorCode - two args} {testsetobjerrorcode} {
+ catch {testsetobjerrorcode 1 2}
+ list [set errorCode]
+} {{1 2}}
+test result-4.3 {Tcl_SetObjErrorCode - three args} {testsetobjerrorcode} {
+ catch {testsetobjerrorcode 1 2 3}
+ list [set errorCode]
+} {{1 2 3}}
+test result-4.4 {Tcl_SetObjErrorCode - four args} {testsetobjerrorcode} {
+ catch {testsetobjerrorcode 1 2 3 4}
+ list [set errorCode]
+} {{1 2 3 4}}
+test result-4.5 {Tcl_SetObjErrorCode - five args} {testsetobjerrorcode} {
+ catch {testsetobjerrorcode 1 2 3 4 5}
+ list [set errorCode]
+} {{1 2 3 4 5}}
+
+test result-5.1 {Tcl_SetErrorCode - one arg} testseterrorcode {
+ catch {testseterrorcode 1}
+ set errorCode
+} 1
+test result-5.2 {Tcl_SetErrorCode - one arg, list quoting} testseterrorcode {
+ catch {testseterrorcode {a b}}
+ set errorCode
+} {{a b}}
+test result-5.3 {Tcl_SetErrorCode - one arg, list quoting} testseterrorcode {
+ catch {testseterrorcode \{}
+ llength $errorCode
+} 1
+test result-5.4 {Tcl_SetErrorCode - two args, list quoting} testseterrorcode {
+ catch {testseterrorcode {a b} c}
+ set errorCode
+} {{a b} c}
+
+test result-6.0 {Bug 1209759} -constraints testreturn -body {
+ # Might panic if bug is not fixed.
+ proc foo {} {testreturn}
+ foo
+} -returnCodes ok -result {}
+test result-6.1 {Bug 1209759} -constraints testreturn -body {
+ # Might panic if bug is not fixed.
+ proc foo {} {catch {return -level 2}; testreturn}
+ foo
+} -cleanup {
+ rename foo {}
+} -returnCodes ok -result {}
+test result-6.2 {Bug 1649062} -setup {
+ proc foo {} {
+ if {[catch {
+ return -code error -errorinfo custom -errorcode CUSTOM foo
+ } err]} {
+ return [list $err $::errorCode $::errorInfo]
+ }
+ }
+ set ::errorInfo {}
+ set ::errorCode {}
+} -body {
+ foo
+} -cleanup {
+ rename foo {}
+} -result {foo {} {}}
+test result-6.3 {Bug 2383005} {
+ catch {return -code error -errorcode {{}a} eek} m
+ set m
+} {bad -errorcode value: expected a list but got "{}a"}
+test result-6.4 {non-list -errorstack} -body {
+ catch {return -code error -errorstack {{}a} eek} m o
+ list $m [dict get $o -errorcode] [dict get $o -errorstack]
+} -match glob -result {{bad -errorstack value: expected a list but got "{}a"} {TCL RESULT NONLIST_ERRORSTACK} {INNER * UP 1}}
+test result-6.5 {odd-sized-list -errorstack} -body {
+ catch {return -code error -errorstack a eek} m o
+ list $m [dict get $o -errorcode] [dict get $o -errorstack]
+} -match glob -result {{forbidden odd-sized list for -errorstack: "a"} {TCL RESULT ODDSIZEDLIST_ERRORSTACK} {INNER * UP 1}}
+# cleanup
+cleanupTests
+return
diff --git a/pkgs/msgcat/tests/safe.test b/pkgs/msgcat/tests/safe.test
new file mode 100644
index 0000000..4a2792e
--- /dev/null
+++ b/pkgs/msgcat/tests/safe.test
@@ -0,0 +1,774 @@
+# safe.test --
+#
+# This file contains a collection of tests for safe Tcl, packages loading, and
+# using safe interpreters. Sourcing this file into tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require Tcl 8.5
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+foreach i [interp slaves] {
+ interp delete $i
+}
+
+set saveAutoPath $::auto_path
+set ::auto_path [info library]
+
+# Force actual loading of the safe package because we use un exported (and
+# thus un-autoindexed) APIs in this test result arguments:
+catch {safe::interpConfigure}
+
+# testing that nested and statics do what is advertised (we use a static
+# package - Tcltest - but it might be absent if we're in standard tclsh)
+
+testConstraint TcltestPackage [expr {![catch {package require Tcltest}]}]
+
+test safe-1.1 {safe::interpConfigure syntax} -returnCodes error -body {
+ safe::interpConfigure
+} -result {no value given for parameter "slave" (use -help for full usage) :
+ slave name () name of the slave}
+test safe-1.2 {safe::interpCreate syntax} -returnCodes error -body {
+ safe::interpCreate -help
+} -result {Usage information:
+ Var/FlagName Type Value Help
+ ------------ ---- ----- ----
+ (-help gives this help)
+ ?slave? name () name of the slave (optional)
+ -accessPath list () access path for the slave
+ -noStatics boolflag (false) prevent loading of statically linked pkgs
+ -statics boolean (true) loading of statically linked pkgs
+ -nestedLoadOk boolflag (false) allow nested loading
+ -nested boolean (false) nested loading
+ -deleteHook script () delete hook}
+test safe-1.3 {safe::interpInit syntax} -returnCodes error -body {
+ safe::interpInit -noStatics
+} -result {bad value "-noStatics" for parameter
+ slave name () name of the slave}
+
+test safe-2.1 {creating interpreters, should have no aliases} emptyTest {
+ # Disabled this test. It tests nothing sensible. [Bug 999612]
+ # interp aliases
+} ""
+test safe-2.2 {creating interpreters, should have no aliases} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ interp create a
+ a aliases
+} -cleanup {
+ safe::interpDelete a
+} -result ""
+test safe-2.3 {creating safe interpreters, should have no unexpected aliases} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ interp create a -safe
+ lsort [a aliases]
+} -cleanup {
+ interp delete a
+} -result {::tcl::mathfunc::max ::tcl::mathfunc::min clock}
+
+test safe-3.1 {calling safe::interpInit is safe} -setup {
+ catch {safe::interpDelete a}
+ interp create a -safe
+} -body {
+ safe::interpInit a
+ interp eval a exec ls
+} -returnCodes error -cleanup {
+ safe::interpDelete a
+} -result {invalid command name "exec"}
+test safe-3.2 {calling safe::interpCreate on trusted interp} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ safe::interpCreate a
+ lsort [a aliases]
+} -cleanup {
+ safe::interpDelete a
+} -result {::tcl::file::atime ::tcl::file::attributes ::tcl::file::copy ::tcl::file::delete ::tcl::file::dirname ::tcl::file::executable ::tcl::file::exists ::tcl::file::extension ::tcl::file::isdirectory ::tcl::file::isfile ::tcl::file::link ::tcl::file::lstat ::tcl::file::mkdir ::tcl::file::mtime ::tcl::file::nativename ::tcl::file::normalize ::tcl::file::owned ::tcl::file::readable ::tcl::file::readlink ::tcl::file::rename ::tcl::file::rootname ::tcl::file::size ::tcl::file::stat ::tcl::file::tail ::tcl::file::tempfile ::tcl::file::type ::tcl::file::volumes ::tcl::file::writable ::tcl::info::nameofexecutable clock encoding exit glob load source}
+test safe-3.3 {calling safe::interpCreate on trusted interp} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ safe::interpCreate a
+ interp eval a {source [file join $tcl_library init.tcl]}
+} -cleanup {
+ safe::interpDelete a
+} -result ""
+test safe-3.4 {calling safe::interpCreate on trusted interp} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ safe::interpCreate a
+ interp eval a {source [file join $tcl_library init.tcl]}
+} -cleanup {
+ safe::interpDelete a
+} -result {}
+
+test safe-4.1 {safe::interpDelete} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ interp create a
+ safe::interpDelete a
+} -result ""
+test safe-4.2 {safe::interpDelete, indirectly} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ interp create a
+ a alias exit safe::interpDelete a
+ a eval exit
+} -result ""
+test safe-4.5 {safe::interpDelete} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ safe::interpCreate a
+ safe::interpCreate a
+} -returnCodes error -cleanup {
+ safe::interpDelete a
+} -result {interpreter named "a" already exists, cannot create}
+test safe-4.6 {safe::interpDelete, indirectly} -setup {
+ catch {safe::interpDelete a}
+} -body {
+ safe::interpCreate a
+ a eval exit
+} -result ""
+
+# The following test checks whether the definition of tcl_endOfWord can be
+# obtained from auto_loading.
+
+test safe-5.1 {test auto-loading in safe interpreters} -setup {
+ catch {safe::interpDelete a}
+ safe::interpCreate a
+} -body {
+ interp eval a {tcl_endOfWord "" 0}
+} -cleanup {
+ safe::interpDelete a
+} -result -1
+
+# test safe interps 'information leak'
+proc SafeEval {script} {
+ # Helper procedure that ensures the safe interp is cleaned up even if
+ # there is a failure in the script.
+ set SafeInterp [interp create -safe]
+ catch {$SafeInterp eval $script} msg opts
+ interp delete $SafeInterp
+ return -options $opts $msg
+}
+
+test safe-6.1 {test safe interpreters knowledge of the world} {
+ lsort [SafeEval {info globals}]
+} {tcl_interactive tcl_patchLevel tcl_platform tcl_version}
+test safe-6.2 {test safe interpreters knowledge of the world} {
+ SafeEval {info script}
+} {}
+test safe-6.3 {test safe interpreters knowledge of the world} {
+ set r [SafeEval {array names tcl_platform}]
+ # If running a windows-debug shell, remove the "debug" element from r.
+ if {[testConstraint win]} {
+ set r [lsearch -all -inline -not -exact $r "debug"]
+ }
+ set r [lsearch -all -inline -not -exact $r "threaded"]
+ lsort $r
+} {byteOrder pathSeparator platform pointerSize wordSize}
+
+# More test should be added to check that hostname, nameofexecutable, aren't
+# leaking infos, but they still do...
+
+# high level general test
+test safe-7.1 {tests that everything works at high level} {
+ set i [safe::interpCreate]
+ # no error shall occur:
+ # (because the default access_path shall include 1st level sub dirs so
+ # package require in a slave works like in the master)
+ set v [interp eval $i {package require http 1}]
+ # no error shall occur:
+ interp eval $i {http_config}
+ safe::interpDelete $i
+ set v
+} 1.0
+test safe-7.2 {tests specific path and interpFind/AddToAccessPath} -body {
+ set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
+ # should not add anything (p0)
+ set token1 [safe::interpAddToAccessPath $i [info library]]
+ # should add as p1
+ set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
+ # an error shall occur (http is not anymore in the secure 0-level
+ # provided deep path)
+ list $token1 $token2 \
+ [catch {interp eval $i {package require http 1}} msg] $msg \
+ [safe::interpConfigure $i]\
+ [safe::interpDelete $i]
+} -match glob -result "{\$p(:0:)} {\$p(:*:)} 1 {can't find package http 1} {-accessPath {[list $tcl_library */dummy/unixlike/test/path]} -statics 0 -nested 1 -deleteHook {}} {}"
+test safe-7.3 {check that safe subinterpreters work} {
+ set i [safe::interpCreate]
+ set j [safe::interpCreate [list $i x]]
+ list [interp eval $j {join {o k} ""}] [safe::interpDelete $i] [interp exists $j]
+} {ok {} 0}
+
+# test source control on file name
+test safe-8.1 {safe source control on file} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+} -body {
+ safe::interpCreate $i
+ $i eval {source}
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {wrong # args: should be "source ?-encoding E? fileName"}
+test safe-8.2 {safe source control on file} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+} -body {
+ safe::interpCreate $i
+ $i eval {source a b c d e}
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {wrong # args: should be "source ?-encoding E? fileName"}
+test safe-8.3 {safe source control on file} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+ set log {}
+ proc safe-test-log {str} {lappend ::log $str}
+ set prevlog [safe::setLogCmd]
+} -body {
+ safe::interpCreate $i
+ safe::setLogCmd safe-test-log
+ list [catch {$i eval {source .}} msg] $msg $log
+} -cleanup {
+ safe::setLogCmd $prevlog
+ unset log
+ safe::interpDelete $i
+} -result {1 {permission denied} {{ERROR for slave a : ".": is a directory}}}
+test safe-8.4 {safe source control on file} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+ set log {}
+ proc safe-test-log {str} {global log; lappend log $str}
+ set prevlog [safe::setLogCmd]
+} -body {
+ safe::interpCreate $i
+ safe::setLogCmd safe-test-log
+ list [catch {$i eval {source /abc/def}} msg] $msg $log
+} -cleanup {
+ safe::setLogCmd $prevlog
+ unset log
+ safe::interpDelete $i
+} -result {1 {permission denied} {{ERROR for slave a : "/abc/def": not in access_path}}}
+test safe-8.5 {safe source control on file} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+ set log {}
+ proc safe-test-log {str} {global log; lappend log $str}
+ set prevlog [safe::setLogCmd]
+} -body {
+ # This tested filename == *.tcl or tclIndex, but that restriction was
+ # removed in 8.4a4 - hobbs
+ safe::interpCreate $i
+ safe::setLogCmd safe-test-log
+ list [catch {
+ $i eval {source [file join [info lib] blah]}
+ } msg] $msg $log
+} -cleanup {
+ safe::setLogCmd $prevlog
+ unset log
+ safe::interpDelete $i
+} -result [list 1 {no such file or directory} [list "ERROR for slave a : [file join [info library] blah]:no such file or directory"]]
+test safe-8.6 {safe source control on file} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+ set log {}
+ proc safe-test-log {str} {global log; lappend log $str}
+ set prevlog [safe::setLogCmd]
+} -body {
+ safe::interpCreate $i
+ safe::setLogCmd safe-test-log
+ list [catch {
+ $i eval {source [file join [info lib] blah.tcl]}
+ } msg] $msg $log
+} -cleanup {
+ safe::setLogCmd $prevlog
+ unset log
+ safe::interpDelete $i
+} -result [list 1 {no such file or directory} [list "ERROR for slave a : [file join [info library] blah.tcl]:no such file or directory"]]
+test safe-8.7 {safe source control on file} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+ set log {}
+ proc safe-test-log {str} {global log; lappend log $str}
+ set prevlog [safe::setLogCmd]
+} -body {
+ safe::interpCreate $i
+ # This tested length of filename, but that restriction was removed in
+ # 8.4a4 - hobbs
+ safe::setLogCmd safe-test-log
+ list [catch {
+ $i eval {source [file join [info lib] xxxxxxxxxxx.tcl]}
+ } msg] $msg $log
+} -cleanup {
+ safe::setLogCmd $prevlog
+ unset log
+ safe::interpDelete $i
+} -result [list 1 {no such file or directory} [list "ERROR for slave a : [file join [info library] xxxxxxxxxxx.tcl]:no such file or directory"]]
+test safe-8.8 {safe source forbids -rsrc} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+ safe::interpCreate $i
+} -body {
+ $i eval {source -rsrc Init}
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {wrong # args: should be "source ?-encoding E? fileName"}
+test safe-8.9 {safe source and return} -setup {
+ set returnScript [makeFile {return "ok"} return.tcl]
+ catch {safe::interpDelete $i}
+} -body {
+ safe::interpCreate $i
+ set token [safe::interpAddToAccessPath $i [file dirname $returnScript]]
+ $i eval [list source $token/[file tail $returnScript]]
+} -cleanup {
+ catch {safe::interpDelete $i}
+ removeFile $returnScript
+} -result ok
+test safe-8.10 {safe source and return} -setup {
+ set returnScript [makeFile {return -level 2 "ok"} return.tcl]
+ catch {safe::interpDelete $i}
+} -body {
+ safe::interpCreate $i
+ set token [safe::interpAddToAccessPath $i [file dirname $returnScript]]
+ $i eval [list apply {filename {
+ source $filename
+ error boom
+ }} $token/[file tail $returnScript]]
+} -cleanup {
+ catch {safe::interpDelete $i}
+ removeFile $returnScript
+} -result ok
+
+test safe-9.1 {safe interps' deleteHook} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+ set res {}
+} -body {
+ proc testDelHook {args} {
+ global res
+ # the interp still exists at that point
+ interp eval a {set delete 1}
+ # mark that we've been here (successfully)
+ set res $args
+ }
+ safe::interpCreate $i -deleteHook "testDelHook arg1 arg2"
+ list [interp eval $i exit] $res
+} -result {{} {arg1 arg2 a}}
+test safe-9.2 {safe interps' error in deleteHook} -setup {
+ set i "a"
+ catch {safe::interpDelete $i}
+ set res {}
+ set log {}
+ proc safe-test-log {str} {lappend ::log $str}
+ set prevlog [safe::setLogCmd]
+} -body {
+ proc testDelHook {args} {
+ global res
+ # the interp still exists at that point
+ interp eval a {set delete 1}
+ # mark that we've been here (successfully)
+ set res $args
+ # create an exception
+ error "being catched"
+ }
+ safe::interpCreate $i -deleteHook "testDelHook arg1 arg2"
+ safe::setLogCmd safe-test-log
+ list [safe::interpDelete $i] $res $log
+} -cleanup {
+ safe::setLogCmd $prevlog
+ unset log
+} -result {{} {arg1 arg2 a} {{NOTICE for slave a : About to delete} {ERROR for slave a : Delete hook error (being catched)} {NOTICE for slave a : Deleted}}}
+test safe-9.3 {dual specification of statics} -returnCodes error -body {
+ safe::interpCreate -stat true -nostat
+} -result {conflicting values given for -statics and -noStatics}
+test safe-9.4 {dual specification of statics} {
+ # no error shall occur
+ safe::interpDelete [safe::interpCreate -stat false -nostat]
+} {}
+test safe-9.5 {dual specification of nested} -returnCodes error -body {
+ safe::interpCreate -nested 0 -nestedload
+} -result {conflicting values given for -nested and -nestedLoadOk}
+test safe-9.6 {interpConfigure widget like behaviour} -body {
+ # this test shall work, don't try to "fix it" unless you *really* know what
+ # you are doing (ie you are me :p) -- dl
+ list [set i [safe::interpCreate \
+ -noStatics \
+ -nestedLoadOk \
+ -deleteHook {foo bar}]
+ safe::interpConfigure $i -accessPath /foo/bar
+ safe::interpConfigure $i]\
+ [safe::interpConfigure $i -aCCess]\
+ [safe::interpConfigure $i -nested]\
+ [safe::interpConfigure $i -statics]\
+ [safe::interpConfigure $i -DEL]\
+ [safe::interpConfigure $i -accessPath /blah -statics 1
+ safe::interpConfigure $i]\
+ [safe::interpConfigure $i -deleteHook toto -nosta -nested 0
+ safe::interpConfigure $i]
+} -match glob -result {{-accessPath * -statics 0 -nested 1 -deleteHook {foo bar}} {-accessPath *} {-nested 1} {-statics 0} {-deleteHook {foo bar}} {-accessPath * -statics 1 -nested 1 -deleteHook {foo bar}} {-accessPath * -statics 0 -nested 0 -deleteHook toto}}
+
+catch {teststaticpkg Safepkg1 0 0}
+test safe-10.1 {testing statics loading} -constraints TcltestPackage -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i {load {} Safepkg1}
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {can't use package in a safe interpreter: no Safepkg1_SafeInit procedure}
+test safe-10.2 {testing statics loading / -nostatics} -constraints TcltestPackage -body {
+ set i [safe::interpCreate -nostatics]
+ interp eval $i {load {} Safepkg1}
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {permission denied (static package)}
+test safe-10.3 {testing nested statics loading / no nested by default} -setup {
+ set i [safe::interpCreate]
+} -constraints TcltestPackage -body {
+ interp eval $i {interp create x; load {} Safepkg1 x}
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {permission denied (nested load)}
+test safe-10.4 {testing nested statics loading / -nestedloadok} -constraints TcltestPackage -body {
+ set i [safe::interpCreate -nestedloadok]
+ interp eval $i {interp create x; load {} Safepkg1 x}
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {can't use package in a safe interpreter: no Safepkg1_SafeInit procedure}
+
+test safe-11.1 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {wrong # args: should be "encoding option ?arg ...?"}
+test safe-11.1a {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding foobar
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -match glob -result {bad option "foobar": must be *}
+test safe-11.2 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding system cp775
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {wrong # args: should be "encoding system"}
+test safe-11.3 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding system
+} -cleanup {
+ safe::interpDelete $i
+} -result [encoding system]
+test safe-11.4 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding names
+} -cleanup {
+ safe::interpDelete $i
+} -result [encoding names]
+test safe-11.5 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding convertfrom cp1258 foobar
+} -cleanup {
+ safe::interpDelete $i
+} -result foobar
+test safe-11.6 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding convertto cp1258 foobar
+} -cleanup {
+ safe::interpDelete $i
+} -result foobar
+test safe-11.7 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding convertfrom
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {wrong # args: should be "encoding convertfrom ?encoding? data"}
+test safe-11.8 {testing safe encoding} -setup {
+ set i [safe::interpCreate]
+} -body {
+ interp eval $i encoding convertto
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {wrong # args: should be "encoding convertto ?encoding? data"}
+
+test safe-12.1 {glob is restricted [Bug 2906841]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ $i eval glob ../*
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result "permission denied"
+test safe-12.2 {glob is restricted [Bug 2906841]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ $i eval glob -directory .. *
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result "permission denied"
+test safe-12.3 {glob is restricted [Bug 2906841]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ $i eval glob -join .. *
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result "permission denied"
+test safe-12.4 {glob is restricted [Bug 2906841]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ $i eval glob -nocomplain ../*
+} -cleanup {
+ safe::interpDelete $i
+} -result {}
+test safe-12.5 {glob is restricted [Bug 2906841]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ $i eval glob -directory .. -nocomplain *
+} -cleanup {
+ safe::interpDelete $i
+} -result {}
+test safe-12.6 {glob is restricted [Bug 2906841]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ $i eval glob -nocomplain -join .. *
+} -cleanup {
+ safe::interpDelete $i
+} -result {}
+test safe-12.7 {glob is restricted} -setup {
+ set i [safe::interpCreate]
+} -body {
+ $i eval glob *
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {permission denied}
+
+proc buildEnvironment {filename} {
+ upvar 1 testdir testdir testdir2 testdir2 testfile testfile
+ set testdir [makeDirectory deletethisdir]
+ set testdir2 [makeDirectory deletemetoo $testdir]
+ set testfile [makeFile {} $filename $testdir2]
+}
+#### New tests for Safe base glob, with patches @ Bug 2964715
+test safe-13.1 {glob is restricted [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ $i eval glob *
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+} -result {permission denied}
+test safe-13.2 {mimic the valid glob call by ::tcl::tm::UnknownHandler [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment deleteme.tm
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir2
+ set result [$i eval glob -nocomplain -directory $testdir2 *.tm]
+ if {$result eq [list $testfile]} {
+ return "glob match"
+ } else {
+ return "no match: $result"
+ }
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {glob match}
+test safe-13.3 {cf 13.2 but test glob failure when -directory is outside access path [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment deleteme.tm
+} -body {
+ $i eval glob -directory $testdir2 *.tm
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {permission denied}
+test safe-13.4 {another valid glob call [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment deleteme.tm
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir
+ ::safe::interpAddToAccessPath $i $testdir2
+ set result [$i eval \
+ glob -nocomplain -directory $testdir [file join deletemetoo *.tm]]
+ if {$result eq [list $testfile]} {
+ return "glob match"
+ } else {
+ return "no match: $result"
+ }
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {glob match}
+test safe-13.5 {as 13.4 but test glob failure when -directory is outside access path [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment deleteme.tm
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir2
+ $i eval \
+ glob -directory $testdir [file join deletemetoo *.tm]
+} -returnCodes error -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {permission denied}
+test safe-13.6 {as 13.4 but test silent failure when result is outside access_path [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment deleteme.tm
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir
+ $i eval \
+ glob -nocomplain -directory $testdir [file join deletemetoo *.tm]
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {}
+test safe-13.7 {mimic the glob call by tclPkgUnknown which gives a deliberate error in a safe interpreter [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment pkgIndex.tcl
+} -body {
+ set safeTD [::safe::interpAddToAccessPath $i $testdir]
+ ::safe::interpAddToAccessPath $i $testdir2
+ string map [list $safeTD EXPECTED] [$i eval [list \
+ glob -directory $safeTD -join * pkgIndex.tcl]]
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {{EXPECTED/deletemetoo/pkgIndex.tcl}}
+# Note the extra {} around the result above; that's *expected* because of the
+# format of virtual path roots.
+test safe-13.8 {mimic the glob call by tclPkgUnknown without the deliberate error that is specific to pkgIndex.tcl [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment notIndex.tcl
+} -body {
+ set safeTD [::safe::interpAddToAccessPath $i $testdir]
+ ::safe::interpAddToAccessPath $i $testdir2
+ $i eval [list glob -directory $safeTD -join -nocomplain * notIndex.tcl]
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {}
+test safe-13.9 {as 13.8 but test glob failure when -directory is outside access path [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment notIndex.tcl
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir2
+ set result [$i eval \
+ glob -directory $testdir -join -nocomplain * notIndex.tcl]
+ if {$result eq [list $testfile]} {
+ return {glob match}
+ } else {
+ return "no match: $result"
+ }
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {no match: }
+test safe-13.10 {as 13.8 but test silent failure when result is outside access_path [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+ buildEnvironment notIndex.tcl
+} -body {
+ ::safe::interpAddToAccessPath $i $testdir
+ $i eval glob -directory $testdir -join -nocomplain * notIndex.tcl
+} -cleanup {
+ safe::interpDelete $i
+ removeDirectory $testdir
+} -result {}
+rename buildEnvironment {}
+
+#### Test for the module path
+test safe-14.1 {Check that module path is the same as in the master interpreter [Bug 2964715]} -setup {
+ set i [safe::interpCreate]
+} -body {
+ set tm {}
+ foreach token [$i eval ::tcl::tm::path list] {
+ lappend tm [dict get [set ::safe::S${i}(access_path,map)] $token]
+ }
+ return $tm
+} -cleanup {
+ safe::interpDelete $i
+} -result [::tcl::tm::path list]
+
+test safe-15.1 {safe file ensemble does not surprise code} -setup {
+ set i [interp create -safe]
+} -body {
+ set result [expr {"file" in [interp hidden $i]}]
+ lappend result [interp eval $i {tcl::file::split a/b/c}]
+ lappend result [catch {interp eval $i {tcl::file::isdirectory .}}]
+ lappend result [interp invokehidden $i file split a/b/c]
+ lappend result [catch {interp eval $i {file split a/b/c}} msg] $msg
+ lappend result [catch {interp invokehidden $i file isdirectory .}]
+ interp expose $i file
+ lappend result [catch {interp eval $i {file split a/b/c}} msg] $msg
+ lappend result [catch {interp eval $i {file isdirectory .}} msg] $msg
+} -cleanup {
+ interp delete $i
+} -result {1 {a b c} 1 {a b c} 1 {invalid command name "file"} 1 0 {a b c} 1 {not allowed to invoke subcommand isdirectory of file}}
+
+### ~ should have no special meaning in paths in safe interpreters
+test safe-16.1 {Bug 3529949: defang ~ in paths} -setup {
+ set savedHOME $env(HOME)
+ set env(HOME) /foo/bar
+ set i [safe::interpCreate]
+} -body {
+ $i eval {
+ set d [format %c 126]
+ list [file join [file dirname $d] [file tail $d]]
+ }
+} -cleanup {
+ safe::interpDelete $i
+ set env(HOME) $savedHOME
+} -result {./~}
+test safe-16.2 {Bug 3529949: defang ~user in paths} -setup {
+ set i [safe::interpCreate]
+ set user $tcl_platform(user)
+} -body {
+ string map [list $user USER] [$i eval \
+ "file join \[file dirname ~$user\] \[file tail ~$user\]"]
+} -cleanup {
+ safe::interpDelete $i
+} -result {./~USER}
+test safe-16.3 {Bug 3529949: defang ~ in globs} -setup {
+ set syntheticHOME [makeDirectory foo]
+ makeFile {} bar $syntheticHOME
+ set savedHOME $env(HOME)
+ set env(HOME) $syntheticHOME
+ set i [safe::interpCreate]
+} -body {
+ ::safe::interpAddToAccessPath $i $syntheticHOME
+ $i eval {glob -nocomplain ~/*}
+} -cleanup {
+ safe::interpDelete $i
+ set env(HOME) $savedHOME
+ removeDirectory $syntheticHOME
+} -result {}
+test safe-16.4 {Bug 3529949: defang ~user in globs} -setup {
+ set i [safe::interpCreate]
+} -body {
+ ::safe::interpAddToAccessPath $i $~$tcl_platform(user)
+ $i eval [list glob -nocomplain ~$tcl_platform(user)/*]
+} -cleanup {
+ safe::interpDelete $i
+} -result {}
+
+set ::auto_path $saveAutoPath
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/scan.test b/pkgs/msgcat/tests/scan.test
new file mode 100644
index 0000000..97ad5eb
--- /dev/null
+++ b/pkgs/msgcat/tests/scan.test
@@ -0,0 +1,773 @@
+# Commands covered: scan
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint wideIs64bit \
+ [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}]
+
+test scan-1.1 {BuildCharSet, CharInSet} {
+ list [scan foo {%[^o]} x] $x
+} {1 f}
+test scan-1.2 {BuildCharSet, CharInSet} {
+ list [scan \]foo {%[]f]} x] $x
+} {1 \]f}
+test scan-1.3 {BuildCharSet, CharInSet} {
+ list [scan abc-def {%[a-c]} x] $x
+} {1 abc}
+test scan-1.4 {BuildCharSet, CharInSet} {
+ list [scan abc-def {%[a-c]} x] $x
+} {1 abc}
+test scan-1.5 {BuildCharSet, CharInSet} {
+ list [scan -abc-def {%[-ac]} x] $x
+} {1 -a}
+test scan-1.6 {BuildCharSet, CharInSet} {
+ list [scan -abc-def {%[ac-]} x] $x
+} {1 -a}
+test scan-1.7 {BuildCharSet, CharInSet} {
+ list [scan abc-def {%[c-a]} x] $x
+} {1 abc}
+test scan-1.8 {BuildCharSet, CharInSet} {
+ list [scan def-abc {%[^c-a]} x] $x
+} {1 def-}
+test scan-1.9 {BuildCharSet, CharInSet no match} {
+ catch {unset x}
+ list [scan {= f} {= %[TF]} x] [info exists x]
+} {0 0}
+
+test scan-2.1 {ReleaseCharSet} {
+ list [scan abcde {%[abc]} x] $x
+} {1 abc}
+test scan-2.2 {ReleaseCharSet} {
+ list [scan abcde {%[a-c]} x] $x
+} {1 abc}
+
+test scan-3.1 {ValidateFormat} {
+ list [catch {scan {} {%d%1$d} x} msg] $msg
+} {1 {cannot mix "%" and "%n$" conversion specifiers}}
+test scan-3.2 {ValidateFormat} {
+ list [catch {scan {} {%d%1$d} x} msg] $msg
+} {1 {cannot mix "%" and "%n$" conversion specifiers}}
+test scan-3.3 {ValidateFormat} {
+ list [catch {scan {} {%2$d%d} x} msg] $msg
+} {1 {"%n$" argument index out of range}}
+test scan-3.4 {ValidateFormat} {
+ # degenerate case, before changed from 8.2 to 8.3
+ list [catch {scan {} %d} msg] $msg
+} {0 {}}
+test scan-3.5 {ValidateFormat} {
+ list [catch {scan {} {%10c} a} msg] $msg
+} {1 {field width may not be specified in %c conversion}}
+test scan-3.6 {ValidateFormat} {
+ list [catch {scan {} {%*1$d} a} msg] $msg
+} {1 {bad scan conversion character "$"}}
+test scan-3.7 {ValidateFormat} {
+ list [catch {scan {} {%1$d%1$d} a} msg] $msg
+} {1 {variable is assigned by multiple "%n$" conversion specifiers}}
+test scan-3.8 {ValidateFormat} {
+ list [catch {scan {} a x} msg] $msg
+} {1 {variable is not assigned by any conversion specifiers}}
+test scan-3.9 {ValidateFormat} {
+ list [catch {scan {} {%2$s} x y} msg] $msg
+} {1 {variable is not assigned by any conversion specifiers}}
+test scan-3.10 {ValidateFormat} {
+ list [catch {scan {} {%[a} x} msg] $msg
+} {1 {unmatched [ in format string}}
+test scan-3.11 {ValidateFormat} {
+ list [catch {scan {} {%[^a} x} msg] $msg
+} {1 {unmatched [ in format string}}
+test scan-3.12 {ValidateFormat} {
+ list [catch {scan {} {%[]a} x} msg] $msg
+} {1 {unmatched [ in format string}}
+test scan-3.13 {ValidateFormat} {
+ list [catch {scan {} {%[^]a} x} msg] $msg
+} {1 {unmatched [ in format string}}
+
+test scan-4.1 {Tcl_ScanObjCmd, argument checks} {
+ list [catch {scan} msg] $msg
+} {1 {wrong # args: should be "scan string format ?varName ...?"}}
+test scan-4.2 {Tcl_ScanObjCmd, argument checks} {
+ list [catch {scan string} msg] $msg
+} {1 {wrong # args: should be "scan string format ?varName ...?"}}
+test scan-4.3 {Tcl_ScanObjCmd, argument checks} {
+ # degenerate case, before changed from 8.2 to 8.3
+ list [catch {scan string format} msg] $msg
+} {0 {}}
+test scan-4.4 {Tcl_ScanObjCmd, whitespace} {
+ list [scan { abc def } {%s%s} x y] $x $y
+} {2 abc def}
+test scan-4.5 {Tcl_ScanObjCmd, whitespace} {
+ list [scan { abc def } { %s %s } x y] $x $y
+} {2 abc def}
+test scan-4.6 {Tcl_ScanObjCmd, whitespace} {
+ list [scan { abc def } { %s %s } x y] $x $y
+} {2 abc def}
+test scan-4.7 {Tcl_ScanObjCmd, literals} {
+ # degenerate case, before changed from 8.2 to 8.3
+ scan { abc def } { abc def }
+} {}
+test scan-4.8 {Tcl_ScanObjCmd, literals} {
+ set x {}
+ list [scan { abcg} { abc def %1s} x] $x
+} {0 {}}
+test scan-4.9 {Tcl_ScanObjCmd, literals} {
+ list [scan { abc%defghi} { abc %% def%n } x] $x
+} {1 10}
+test scan-4.10 {Tcl_ScanObjCmd, assignment suppression} {
+ list [scan { abc def } { %*c%s def } x] $x
+} {1 bc}
+test scan-4.11 {Tcl_ScanObjCmd, XPG3-style} {
+ list [scan { abc def } {%2$s %1$s} x y] $x $y
+} {2 def abc}
+test scan-4.12 {Tcl_ScanObjCmd, width specifiers} {
+ list [scan {abc123456789012} {%3s%3d%3f%3[0-9]%s} a b c d e] $a $b $c $d $e
+} {5 abc 123 456.0 789 012}
+test scan-4.13 {Tcl_ScanObjCmd, width specifiers} {
+ list [scan {abc123456789012} {%3s%3d%3f%3[0-9]%s} a b c d e] $a $b $c $d $e
+} {5 abc 123 456.0 789 012}
+test scan-4.14 {Tcl_ScanObjCmd, underflow} {
+ set x {}
+ list [scan {a} {a%d} x] $x
+} {-1 {}}
+test scan-4.15 {Tcl_ScanObjCmd, underflow} {
+ set x {}
+ list [scan {} {a%d} x] $x
+} {-1 {}}
+test scan-4.16 {Tcl_ScanObjCmd, underflow} {
+ set x {}
+ list [scan {ab} {a%d} x] $x
+} {0 {}}
+test scan-4.17 {Tcl_ScanObjCmd, underflow} {
+ set x {}
+ list [scan {a } {a%d} x] $x
+} {-1 {}}
+test scan-4.18 {Tcl_ScanObjCmd, skipping whitespace} {
+ list [scan { b} {%c%s} x y] $x $y
+} {2 32 b}
+test scan-4.19 {Tcl_ScanObjCmd, skipping whitespace} {
+ list [scan { b} {%[^b]%s} x y] $x $y
+} {2 { } b}
+test scan-4.20 {Tcl_ScanObjCmd, string scanning} {
+ list [scan {abc def} {%s} x] $x
+} {1 abc}
+test scan-4.21 {Tcl_ScanObjCmd, string scanning} {
+ list [scan {abc def} {%0s} x] $x
+} {1 abc}
+test scan-4.22 {Tcl_ScanObjCmd, string scanning} {
+ list [scan {abc def} {%2s} x] $x
+} {1 ab}
+test scan-4.23 {Tcl_ScanObjCmd, string scanning} {
+ list [scan {abc def} {%*s%n} x] $x
+} {1 3}
+test scan-4.24 {Tcl_ScanObjCmd, charset scanning} {
+ list [scan {abcdef} {%[a-c]} x] $x
+} {1 abc}
+test scan-4.25 {Tcl_ScanObjCmd, charset scanning} {
+ list [scan {abcdef} {%0[a-c]} x] $x
+} {1 abc}
+test scan-4.26 {Tcl_ScanObjCmd, charset scanning} {
+ list [scan {abcdef} {%2[a-c]} x] $x
+} {1 ab}
+test scan-4.27 {Tcl_ScanObjCmd, charset scanning} {
+ list [scan {abcdef} {%*[a-c]%n} x] $x
+} {1 3}
+test scan-4.28 {Tcl_ScanObjCmd, character scanning} {
+ list [scan {abcdef} {%c} x] $x
+} {1 97}
+test scan-4.29 {Tcl_ScanObjCmd, character scanning} {
+ list [scan {abcdef} {%*c%n} x] $x
+} {1 1}
+
+test scan-4.30 {Tcl_ScanObjCmd, base-10 integer scanning} {
+ set x {}
+ list [scan {1234567890a} {%3d} x] $x
+} {1 123}
+test scan-4.31 {Tcl_ScanObjCmd, base-10 integer scanning} {
+ set x {}
+ list [scan {1234567890a} {%d} x] $x
+} {1 1234567890}
+test scan-4.32 {Tcl_ScanObjCmd, base-10 integer scanning} {
+ set x {}
+ list [scan {01234567890a} {%d} x] $x
+} {1 1234567890}
+test scan-4.33 {Tcl_ScanObjCmd, base-10 integer scanning} {
+ set x {}
+ list [scan {+01234} {%d} x] $x
+} {1 1234}
+test scan-4.34 {Tcl_ScanObjCmd, base-10 integer scanning} {
+ set x {}
+ list [scan {-01234} {%d} x] $x
+} {1 -1234}
+test scan-4.35 {Tcl_ScanObjCmd, base-10 integer scanning} {
+ set x {}
+ list [scan {a01234} {%d} x] $x
+} {0 {}}
+test scan-4.36 {Tcl_ScanObjCmd, base-10 integer scanning} {
+ set x {}
+ list [scan {0x10} {%d} x] $x
+} {1 0}
+test scan-4.37 {Tcl_ScanObjCmd, base-8 integer scanning} {
+ set x {}
+ list [scan {012345678} {%o} x] $x
+} {1 342391}
+test scan-4.38 {Tcl_ScanObjCmd, base-8 integer scanning} {
+ set x {}
+ list [scan {+1238 -1239 123a} {%o%*s%o%*s%o} x y z] $x $y $z
+} {3 83 -83 83}
+test scan-4.39 {Tcl_ScanObjCmd, base-16 integer scanning} {
+ set x {}
+ list [scan {+1238 -123a 0123} {%x%x%x} x y z] $x $y $z
+} {3 4664 -4666 291}
+test scan-4.40 {Tcl_ScanObjCmd, base-16 integer scanning} {
+ # The behavior changed in 8.4a4/8.3.4cvs (6 Feb) to correctly
+ # return '1' for 0x1 scanned via %x, to comply with 8.0 and C scanf.
+ # Bug #495213
+ set x {}
+ list [scan {aBcDeF AbCdEf 0x1} {%x%x%x} x y z] $x $y $z
+} {3 11259375 11259375 1}
+test scan-4.40.1 {Tcl_ScanObjCmd, base-16 integer scanning} {
+ set x {}
+ list [scan {0xF 0x00A0B 0X0XF} {%x %x %x} x y z] $x $y $z
+} {3 15 2571 0}
+test scan-4.40.2 {Tcl_ScanObjCmd, base-16 integer scanning} {
+ catch {unset x}
+ list [scan {xF} {%x} x] [info exists x]
+} {0 0}
+test scan-4.40.3 {Tcl_ScanObjCmd, base-2 integer scanning} {
+ set x {}
+ list [scan {1001 0b101 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000} {%b %b %llb} x y z] $x $y $z
+} {3 9 5 340282366920938463463374607431768211456}
+test scan-4.41 {Tcl_ScanObjCmd, base-unknown integer scanning} {
+ set x {}
+ list [scan {10 010 0x10 0b10} {%i%i%i%i} x y z t] $x $y $z $t
+} {4 10 8 16 0}
+test scan-4.42 {Tcl_ScanObjCmd, base-unknown integer scanning} {
+ set x {}
+ list [scan {10 010 0X10} {%i%i%i} x y z] $x $y $z
+} {3 10 8 16}
+test scan-4.43 {Tcl_ScanObjCmd, integer scanning, odd cases} {
+ set x {}
+ list [scan {+ } {%i} x] $x
+} {0 {}}
+test scan-4.44 {Tcl_ScanObjCmd, integer scanning, odd cases} {
+ set x {}
+ list [scan {+} {%i} x] $x
+} {-1 {}}
+test scan-4.45 {Tcl_ScanObjCmd, integer scanning, odd cases} {
+ set x {}
+ list [scan {0x} {%i%s} x y] $x $y
+} {2 0 x}
+test scan-4.46 {Tcl_ScanObjCmd, integer scanning, odd cases} {
+ set x {}
+ list [scan {0X} {%i%s} x y] $x $y
+} {2 0 X}
+test scan-4.47 {Tcl_ScanObjCmd, integer scanning, suppressed} {
+ set x {}
+ list [scan {123def} {%*i%s} x] $x
+} {1 def}
+test scan-4.48 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {1 2 3} {%e %f %g} x y z] $x $y $z
+} {3 1.0 2.0 3.0}
+test scan-4.49 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {.1 0.2 3.} {%e %f %g} x y z] $x $y $z
+} {3 0.1 0.2 3.0}
+test scan-4.50 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {1234567890a} %f x] $x
+} {1 1234567890.0}
+test scan-4.51 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {+123+45} %f x] $x
+} {1 123.0}
+test scan-4.52 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {-123+45} %f x] $x
+} {1 -123.0}
+test scan-4.53 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {1.0e1} %f x] $x
+} {1 10.0}
+test scan-4.54 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {1.0e-1} %f x] $x
+} {1 0.1}
+test scan-4.55 {Tcl_ScanObjCmd, odd cases} {
+ set x {}
+ list [scan {+} %f x] $x
+} {-1 {}}
+test scan-4.56 {Tcl_ScanObjCmd, odd cases} {
+ set x {}
+ list [scan {1.0e} %f%s x y] $x $y
+} {2 1.0 e}
+test scan-4.57 {Tcl_ScanObjCmd, odd cases} {
+ set x {}
+ list [scan {1.0e+} %f%s x y] $x $y
+} {2 1.0 e+}
+test scan-4.58 {Tcl_ScanObjCmd, odd cases} {
+ set x {}
+ set y {}
+ list [scan {e1} %f%s x y] $x $y
+} {0 {} {}}
+test scan-4.59 {Tcl_ScanObjCmd, float scanning} {
+ list [scan {1.0e-1x} %*f%n x] $x
+} {1 6}
+
+test scan-4.60 {Tcl_ScanObjCmd, set errors} {
+ set x {}
+ set y {}
+ catch {unset z}; array set z {}
+ set result [list [catch {scan {abc def ghi} {%s%s%s} x z y} msg] \
+ $msg $x $y]
+ unset z
+ set result
+} {1 {can't set "z": variable is array} abc ghi}
+test scan-4.61 {Tcl_ScanObjCmd, set errors} {
+ set x {}
+ catch {unset y}; array set y {}
+ catch {unset z}; array set z {}
+ set result [list [catch {scan {abc def ghi} {%s%s%s} x z y} msg] \
+ $msg $x]
+ unset y
+ unset z
+ set result
+} {1 {can't set "z": variable is array} abc}
+
+# procedure that returns the range of integers
+
+proc int_range {} {
+ for { set MIN_INT 1 } { int($MIN_INT) > 0 } {} {
+ set MIN_INT [expr { $MIN_INT << 1 }]
+ }
+ set MIN_INT [expr {int($MIN_INT)}]
+ set MAX_INT [expr { ~ $MIN_INT }]
+ return [list $MIN_INT $MAX_INT]
+}
+
+test scan-4.62 {scanning of large and negative octal integers} {
+ foreach { MIN_INT MAX_INT } [int_range] {}
+ set scanstring [format {%o %o %o} -1 $MIN_INT $MAX_INT]
+ list [scan $scanstring {%o %o %o} a b c] \
+ [expr { $a == -1 }] [expr { $b == $MIN_INT }] [expr { $c == $MAX_INT }]
+} {3 1 1 1}
+test scan-4.63 {scanning of large and negative hex integers} {
+ foreach { MIN_INT MAX_INT } [int_range] {}
+ set scanstring [format {%x %x %x} -1 $MIN_INT $MAX_INT]
+ list [scan $scanstring {%x %x %x} a b c] \
+ [expr { $a == -1 }] [expr { $b == $MIN_INT }] [expr { $c == $MAX_INT }]
+} {3 1 1 1}
+
+# clean up from last two tests
+
+catch {
+ rename int_range {}
+}
+
+test scan-5.1 {integer scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "-20 1476 \n33 0" "%d %d %d %d" a b c d] $a $b $c $d
+} {4 -20 1476 33 0}
+test scan-5.2 {integer scanning} {
+ set a {}; set b {}; set c {}
+ list [scan "-45 16 7890 +10" "%2d %*d %10d %d" a b c] $a $b $c
+} {3 -4 16 7890}
+test scan-5.3 {integer scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "-45 16 +10 987" "%ld %d %ld %d" a b c d] $a $b $c $d
+} {4 -45 16 10 987}
+test scan-5.4 {integer scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "14 1ab 62 10" "%d %x %lo %x" a b c d] $a $b $c $d
+} {4 14 427 50 16}
+test scan-5.5 {integer scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "12345670 1234567890ab cdefg" "%o %o %x %lx" a b c d] \
+ $a $b $c $d
+} {4 2739128 342391 561323 52719}
+test scan-5.6 {integer scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "ab123-24642" "%2x %3x %3o %2o" a b c d] $a $b $c $d
+} {4 171 291 -20 52}
+test scan-5.7 {integer scanning} {
+ set a {}; set b {}
+ list [scan "1234567 234 567 " "%*3x %x %*o %4o" a b] $a $b
+} {2 17767 375}
+test scan-5.8 {integer scanning} {
+ set a {}; set b {}
+ list [scan "a 1234" "%d %d" a b] $a $b
+} {0 {} {}}
+test scan-5.9 {integer scanning} {
+ set a {}; set b {}; set c {}; set d {};
+ list [scan "12345678" "%2d %2d %2ld %2d" a b c d] $a $b $c $d
+} {4 12 34 56 78}
+test scan-5.10 {integer scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "1 2 " "%hd %d %d %d" a b c d] $a $b $c $d
+} {2 1 2 {} {}}
+#
+# The behavior for scaning intergers larger than MAX_INT is
+# not defined by the ANSI spec. Some implementations wrap the
+# input (-16) some return MAX_INT.
+#
+test scan-5.11 {integer scanning} {nonPortable} {
+ set a {}; set b {};
+ list [scan "4294967280 4294967280" "%u %d" a b] $a \
+ [expr {$b == -16 || $b == 0x7fffffff}]
+} {2 4294967280 1}
+test scan-5.12 {integer scanning} {wideIs64bit} {
+ set a {}; set b {}; set c {}
+ list [scan "7810179016327718216,6c63546f6c6c6548,661432506755433062510" \
+ %ld,%lx,%lo a b c] $a $b $c
+} {3 7810179016327718216 7810179016327718216 7810179016327718216}
+test scan-5.13 {integer scanning and overflow} {
+ # This test used to fail on some 64-bit systems. [Bug 1011860]
+ scan {300000000 3000000000 30000000000} {%ld %ld %ld}
+} {300000000 3000000000 30000000000}
+
+test scan-5.14 {integer scanning} {
+ scan 0xff %u
+} 0
+
+test scan-6.1 {floating-point scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "2.1 -3.0e8 .99962 a" "%f%g%e%f" a b c d] $a $b $c $d
+} {3 2.1 -300000000.0 0.99962 {}}
+test scan-6.2 {floating-point scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "-1.2345 +8.2 9" "%3e %3lf %f %f" a b c d] $a $b $c $d
+} {4 -1.0 234.0 5.0 8.2}
+test scan-6.3 {floating-point scanning} {
+ set a {}; set b {}; set c {}
+ list [scan "1e00004 332E-4 3e+4" "%Lf %*2e %f %f" a b c] $a $c
+} {3 10000.0 30000.0}
+#
+# Some libc implementations consider 3.e- bad input. The ANSI
+# spec states that digits must follow the - sign.
+#
+test scan-6.4 {floating-point scanning} {
+ set a {}; set b {}; set c {}
+ list [scan "1. 47.6 2.e2 3.e-" "%f %*f %f %f" a b c] $a $b $c
+} {3 1.0 200.0 3.0}
+test scan-6.5 {floating-point scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "4.6 99999.7 876.43e-1 118" "%f %f %f %e" a b c d] $a $b $c $d
+} {4 4.6 99999.7 87.643 118.0}
+test scan-6.6 {floating-point scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "1.2345 697.0e-3 124 .00005" "%f %e %f %e" a b c d] $a $b $c $d
+} {4 1.2345 0.697 124.0 5e-5}
+test scan-6.7 {floating-point scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "4.6abc" "%f %f %f %f" a b c d] $a $b $c $d
+} {1 4.6 {} {} {}}
+test scan-6.8 {floating-point scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "4.6 5.2" "%f %f %f %f" a b c d] $a $b $c $d
+} {2 4.6 5.2 {} {}}
+
+test scan-7.1 {string and character scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "abc defghijk dum " "%s %3s %20s %s" a b c d] $a $b $c $d
+} {4 abc def ghijk dum}
+test scan-7.2 {string and character scanning} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "a bcdef" "%c%c%1s %s" a b c d] $a $b $c $d
+} {4 97 32 b cdef}
+test scan-7.3 {string and character scanning} {
+ set a {}; set b {}; set c {}
+ list [scan "123456 test " "%*c%*s %s %s %s" a b c] $a $b $c
+} {1 test {} {}}
+test scan-7.4 {string and character scanning} {
+ set a {}; set b {}; set c {}; set d
+ list [scan "ababcd01234 f 123450" {%4[abcd] %4[abcd] %[^abcdef] %[^0]} a b c d] $a $b $c $d
+} {4 abab cd {01234 } {f 12345}}
+test scan-7.5 {string and character scanning} {
+ set a {}; set b {}; set c {}
+ list [scan "aaaaaabc aaabcdefg + + XYZQR" {%*4[a] %s %*4[a]%s%*4[ +]%c} a b c] $a $b $c
+} {3 aabc bcdefg 43}
+test scan-7.6 {string and character scanning, unicode} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "abc d\u00c7fghijk dum " "%s %3s %20s %s" a b c d] $a $b $c $d
+} "4 abc d\u00c7f ghijk dum"
+test scan-7.7 {string and character scanning, unicode} {
+ set a {}; set b {}
+ list [scan "ab\u00c7cdef" "ab%c%c" a b] $a $b
+} "2 199 99"
+test scan-7.8 {string and character scanning, unicode} {
+ set a {}; set b {}
+ list [scan "ab\ufeffdef" "%\[ab\ufeff\]" a] $a
+} "1 ab\ufeff"
+
+test scan-8.1 {error conditions} {
+ catch {scan a}
+} 1
+test scan-8.2 {error conditions} {
+ catch {scan a} msg
+ set msg
+} {wrong # args: should be "scan string format ?varName ...?"}
+test scan-8.3 {error conditions} {
+ list [catch {scan a %D x} msg] $msg
+} {1 {bad scan conversion character "D"}}
+test scan-8.4 {error conditions} {
+ list [catch {scan a %O x} msg] $msg
+} {1 {bad scan conversion character "O"}}
+test scan-8.5 {error conditions} {
+ list [catch {scan a %X x} msg] $msg
+} {1 {bad scan conversion character "X"}}
+test scan-8.6 {error conditions} {
+ list [catch {scan a %F x} msg] $msg
+} {1 {bad scan conversion character "F"}}
+test scan-8.7 {error conditions} {
+ list [catch {scan a %E x} msg] $msg
+} {1 {bad scan conversion character "E"}}
+test scan-8.8 {error conditions} {
+ list [catch {scan a "%d %d" a} msg] $msg
+} {1 {different numbers of variable names and field specifiers}}
+test scan-8.9 {error conditions} {
+ list [catch {scan a "%d %d" a b c} msg] $msg
+} {1 {variable is not assigned by any conversion specifiers}}
+test scan-8.10 {error conditions} {
+ set a {}; set b {}; set c {}; set d {}
+ list [expr {[scan " a" " a %d %d %d %d" a b c d] <= 0}] $a $b $c $d
+} {1 {} {} {} {}}
+test scan-8.11 {error conditions} {
+ set a {}; set b {}; set c {}; set d {}
+ list [scan "1 2" "%d %d %d %d" a b c d] $a $b $c $d
+} {2 1 2 {} {}}
+test scan-8.12 {error conditions} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {scan 44 %d a} msg] $msg
+} {1 {can't set "a": variable is array}}
+test scan-8.13 {error conditions} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {scan 44 %c a} msg] $msg
+} {1 {can't set "a": variable is array}}
+test scan-8.14 {error conditions} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {scan 44 %s a} msg] $msg
+} {1 {can't set "a": variable is array}}
+test scan-8.15 {error conditions} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {scan 44 %f a} msg] $msg
+} {1 {can't set "a": variable is array}}
+test scan-8.16 {error conditions} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {scan 44 %f a} msg] $msg
+} {1 {can't set "a": variable is array}}
+catch {unset a}
+test scan-8.17 {error conditions} {
+ list [catch {scan 44 %2c a} msg] $msg
+} {1 {field width may not be specified in %c conversion}}
+test scan-8.18 {error conditions} {
+ list [catch {scan abc {%[} x} msg] $msg
+} {1 {unmatched [ in format string}}
+test scan-8.19 {error conditions} {
+ list [catch {scan abc {%[^a} x} msg] $msg
+} {1 {unmatched [ in format string}}
+test scan-8.20 {error conditions} {
+ list [catch {scan abc {%[^]a} x} msg] $msg
+} {1 {unmatched [ in format string}}
+test scan-8.21 {error conditions} {
+ list [catch {scan abc {%[]a} x} msg] $msg
+} {1 {unmatched [ in format string}}
+
+test scan-9.1 {lots of arguments} {
+ scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200" "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20
+} 20
+test scan-9.2 {lots of arguments} {
+ scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200" "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20
+ set a20
+} 200
+
+test scan-10.1 {miscellaneous tests} {
+ set a {}
+ list [scan ab16c ab%dc a] $a
+} {1 16}
+test scan-10.2 {miscellaneous tests} {
+ set a {}
+ list [scan ax16c ab%dc a] $a
+} {0 {}}
+test scan-10.3 {miscellaneous tests} {
+ set a {}
+ list [catch {scan ab%c114 ab%%c%d a} msg] $msg $a
+} {0 1 114}
+test scan-10.4 {miscellaneous tests} {
+ set a {}
+ list [catch {scan ab%c14 ab%%c%d a} msg] $msg $a
+} {0 1 14}
+test scan-10.5 {miscellaneous tests} {
+ catch {unset arr}
+ set arr(2) {}
+ list [catch {scan ab%c14 ab%%c%d arr(2)} msg] $msg $arr(2)
+} {0 1 14}
+test scan-10.6 {miscellaneous tests} {
+ scan 5a {%i%[a]}
+} {5 a}
+test scan-10.7 {miscellaneous tests} {
+ scan {5 a} {%i%[a]}
+} {5 {}}
+
+test scan-11.1 {alignment in results array (TCL_ALIGN)} {
+ scan "123 13.6" "%s %f" a b
+ set b
+} 13.6
+test scan-11.2 {alignment in results array (TCL_ALIGN)} {
+ scan "1234567 13.6" "%s %f" a b
+ set b
+} 13.6
+test scan-11.3 {alignment in results array (TCL_ALIGN)} {
+ scan "12345678901 13.6" "%s %f" a b
+ set b
+} 13.6
+test scan-11.4 {alignment in results array (TCL_ALIGN)} {
+ scan "123456789012345 13.6" "%s %f" a b
+ set b
+} 13.6
+test scan-11.5 {alignment in results array (TCL_ALIGN)} {
+ scan "1234567890123456789 13.6" "%s %f" a b
+ set b
+} 13.6
+
+test scan-12.1 {Tcl_ScanObjCmd, inline case} {
+ scan a %c
+} 97
+test scan-12.2 {Tcl_ScanObjCmd, inline case} {
+ scan abc %c%c%c%c
+} {97 98 99 {}}
+test scan-12.3 {Tcl_ScanObjCmd, inline case} {
+ scan abc %s%c
+} {abc {}}
+test scan-12.4 {Tcl_ScanObjCmd, inline case, underflow} {
+ scan abc abc%c
+} {}
+test scan-12.5 {Tcl_ScanObjCmd, inline case} {
+ scan abc bogus%c%c%c
+} {{} {} {}}
+test scan-12.6 {Tcl_ScanObjCmd, inline case} {
+ # degenerate case, behavior changed from 8.2 to 8.3
+ list [catch {scan foo foobar} msg] $msg
+} {0 {}}
+test scan-12.7 {Tcl_ScanObjCmd, inline case lots of arguments} {
+ scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140\
+ 150 160 170 180 190 200" \
+ "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"
+} {10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200 {}}
+
+test scan-13.1 {Tcl_ScanObjCmd, inline XPG case} {
+ scan a {%1$c}
+} 97
+test scan-13.2 {Tcl_ScanObjCmd, inline XPG case} {
+ scan abc {%1$c%2$c%3$c%4$c}
+} {97 98 99 {}}
+test scan-13.3 {Tcl_ScanObjCmd, inline XPG case} {
+ list [catch {scan abc {%1$c%1$c}} msg] $msg
+} {1 {variable is assigned by multiple "%n$" conversion specifiers}}
+test scan-13.4 {Tcl_ScanObjCmd, inline XPG case} {
+ scan abc {%2$s%1$c}
+} {{} abc}
+test scan-13.5 {Tcl_ScanObjCmd, inline XPG case, underflow} {
+ scan abc {abc%5$c}
+} {}
+test scan-13.6 {Tcl_ScanObjCmd, inline XPG case} {
+ catch {scan abc {bogus%1$c%5$c%10$c}} msg
+ list [llength $msg] $msg
+} {10 {{} {} {} {} {} {} {} {} {} {}}}
+test scan-13.7 {Tcl_ScanObjCmd, inline XPG case lots of arguments} {
+ scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200" {%20$d %18$d %17$d %16$d %15$d %14$d %13$d %12$d %11$d %10$d %9$d %8$d %7$d %6$d %5$d %4$d %3$d %2$d %1$d}
+} {190 180 170 160 150 140 130 120 110 100 90 80 70 60 50 40 30 20 {} 10}
+test scan-13.8 {Tcl_ScanObjCmd, inline XPG case lots of arguments} {
+ set msg [scan "10 20 30" {%100$d %5$d %200$d}]
+ list [llength $msg] [lindex $msg 99] [lindex $msg 4] [lindex $msg 199]
+} {200 10 20 30}
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+ variable ieeeValues
+ binary scan [binary format dd -1.0 1.0] c* c
+ switch -exact -- $c {
+ {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+ # little endian
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+ ieeeValues(-Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+ ieeeValues(-Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+ ieeeValues(-Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+ ieeeValues(+Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+ ieeeValues(+Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 1
+ return 1
+ }
+ {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+ binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Infinity)
+ binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Normal)
+ binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Subnormal)
+ binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Normal)
+ binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Infinity)
+ binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(NaN)
+ set ieeeValues(littleEndian) 0
+ return 1
+ }
+ default {
+ return 0
+ }
+ }
+}
+
+testConstraint ieeeFloatingPoint [testIEEE]
+
+# scan infinities - not working
+
+test scan-14.1 {infinity} {
+ scan Inf %g d
+ set d
+} Inf
+test scan-14.2 {infinity} {
+ scan -Inf %g d
+ set d
+} -Inf
+
+# TODO - also need to scan NaN's
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/security.test b/pkgs/msgcat/tests/security.test
new file mode 100644
index 0000000..eeabc9c
--- /dev/null
+++ b/pkgs/msgcat/tests/security.test
@@ -0,0 +1,45 @@
+# security.test --
+#
+# Functionality covered: this file contains a collection of tests for the auto
+# loading and namespaces.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# All rights reserved.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# If this proc becomes invoked, then there is a bug
+
+proc BUG {args} {
+ set ::BUG 1
+}
+
+# Check and Clear the bug flag (to do before each test)
+set ::BUG 0
+
+proc CB {} {
+ set ret $::BUG
+ set ::BUG 0
+ return $ret
+}
+
+
+test security-1.1 {tcl_endOfPreviousWord} {
+ catch {tcl_startOfPreviousWord x {[BUG]}}
+ CB
+} 0
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/set-old.test b/pkgs/msgcat/tests/set-old.test
new file mode 100644
index 0000000..52dc0ff
--- /dev/null
+++ b/pkgs/msgcat/tests/set-old.test
@@ -0,0 +1,928 @@
+# Commands covered: set, unset, array
+#
+# This file includes the original set of tests for Tcl's set command.
+# Since the set command is now compiled, a new set of tests covering
+# the new implementation is in the file "set.test". Sourcing this file
+# into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+proc ignore args {}
+
+# Simple variable operations.
+
+catch {unset a}
+test set-old-1.1 {basic variable setting and unsetting} {
+ set a 22
+} 22
+test set-old-1.2 {basic variable setting and unsetting} {
+ set a 123
+ set a
+} 123
+test set-old-1.3 {basic variable setting and unsetting} {
+ set a xxx
+ format %s $a
+} xxx
+test set-old-1.4 {basic variable setting and unsetting} {
+ set a 44
+ unset a
+ list [catch {set a} msg] $msg
+} {1 {can't read "a": no such variable}}
+
+# Basic array operations.
+
+catch {unset a}
+set a(xyz) 2
+set a(44) 3
+set {a(a long name)} test
+test set-old-2.1 {basic array operations} {
+ lsort [array names a]
+} {44 {a long name} xyz}
+test set-old-2.2 {basic array operations} {
+ set a(44)
+} 3
+test set-old-2.3 {basic array operations} {
+ set a(xyz)
+} 2
+test set-old-2.4 {basic array operations} {
+ set "a(a long name)"
+} test
+test set-old-2.5 {basic array operations} {
+ list [catch {set a(other)} msg] $msg
+} {1 {can't read "a(other)": no such element in array}}
+test set-old-2.6 {basic array operations} {
+ list [catch {set a} msg] $msg
+} {1 {can't read "a": variable is array}}
+test set-old-2.7 {basic array operations} {
+ format %s $a(44)
+} 3
+test set-old-2.8 {basic array operations} {
+ format %s $a(a long name)
+} test
+unset a(44)
+test set-old-2.9 {basic array operations} {
+ lsort [array names a]
+} {{a long name} xyz}
+test set-old-2.10 {basic array operations} {
+ catch {unset b}
+ list [catch {set b(123)} msg] $msg
+} {1 {can't read "b(123)": no such variable}}
+test set-old-2.11 {basic array operations} {
+ catch {unset b}
+ set b 44
+ list [catch {set b(123)} msg] $msg
+} {1 {can't read "b(123)": variable isn't array}}
+test set-old-2.12 {basic array operations} {
+ list [catch {set a 14} msg] $msg
+} {1 {can't set "a": variable is array}}
+unset a
+test set-old-2.13 {basic array operations} {
+ list [catch {set a(xyz)} msg] $msg
+} {1 {can't read "a(xyz)": no such variable}}
+
+# Test the set commands, and exercise the corner cases of the code
+# that parses array references into two parts.
+
+test set-old-3.1 {set command} {
+ list [catch {set} msg] $msg
+} {1 {wrong # args: should be "set varName ?newValue?"}}
+test set-old-3.2 {set command} {
+ list [catch {set x y z} msg] $msg
+} {1 {wrong # args: should be "set varName ?newValue?"}}
+test set-old-3.3 {set command} {
+ catch {unset a}
+ list [catch {set a} msg] $msg
+} {1 {can't read "a": no such variable}}
+test set-old-3.4 {set command} {
+ catch {unset a}
+ set a(14) 83
+ list [catch {set a 22} msg] $msg
+} {1 {can't set "a": variable is array}}
+
+# Test the corner-cases of parsing array names, using set and unset.
+
+test set-old-4.1 {parsing array names} {
+ catch {unset a}
+ set a(()) 44
+ list [catch {array names a} msg] $msg
+} {0 ()}
+test set-old-4.2 {parsing array names} {
+ catch {unset a a(abcd}
+ set a(abcd 33
+ info exists a(abcd
+} 1
+test set-old-4.3 {parsing array names} {
+ catch {unset a a(abcd}
+ set a(abcd 33
+ list [catch {array names a} msg] $msg
+} {0 {}}
+test set-old-4.4 {parsing array names} {
+ catch {unset a abcd)}
+ set abcd) 33
+ info exists abcd)
+} 1
+test set-old-4.5 {parsing array names} {
+ set a(bcd yyy
+ catch {unset a}
+ list [catch {set a(bcd} msg] $msg
+} {0 yyy}
+test set-old-4.6 {parsing array names} {
+ catch {unset a}
+ set a 44
+ list [catch {set a(bcd test} msg] $msg
+} {0 test}
+
+# Errors in reading variables
+
+test set-old-5.1 {errors in reading variables} {
+ catch {unset a}
+ list [catch {set a} msg] $msg
+} {1 {can't read "a": no such variable}}
+test set-old-5.2 {errors in reading variables} {
+ catch {unset a}
+ set a 44
+ list [catch {set a(18)} msg] $msg
+} {1 {can't read "a(18)": variable isn't array}}
+test set-old-5.3 {errors in reading variables} {
+ catch {unset a}
+ set a(6) 44
+ list [catch {set a(18)} msg] $msg
+} {1 {can't read "a(18)": no such element in array}}
+test set-old-5.4 {errors in reading variables} {
+ catch {unset a}
+ set a(6) 44
+ list [catch {set a} msg] $msg
+} {1 {can't read "a": variable is array}}
+
+# Errors and other special cases in writing variables
+
+test set-old-6.1 {creating array during write} {
+ catch {unset a}
+ trace var a rwu ignore
+ list [catch {set a(14) 186} msg] $msg [array names a]
+} {0 186 14}
+test set-old-6.2 {errors in writing variables} {
+ catch {unset a}
+ set a xxx
+ list [catch {set a(14) 186} msg] $msg
+} {1 {can't set "a(14)": variable isn't array}}
+test set-old-6.3 {errors in writing variables} {
+ catch {unset a}
+ set a(100) yyy
+ list [catch {set a 2} msg] $msg
+} {1 {can't set "a": variable is array}}
+test set-old-6.4 {expanding variable size} {
+ catch {unset a}
+ list [set a short] [set a "longer name"] [set a "even longer name"] \
+ [set a "a much much truly longer name"]
+} {short {longer name} {even longer name} {a much much truly longer name}}
+
+# Unset command, Tcl_UnsetVar procedures
+
+test set-old-7.1 {unset command} {
+ catch {unset a}; catch {unset b}; catch {unset c}; catch {unset d}
+ set a 44
+ set b 55
+ set c 66
+ set d 77
+ unset a b c
+ list [catch {set a(0) 0}] [catch {set b(0) 0}] [catch {set c(0) 0}] \
+ [catch {set d(0) 0}]
+} {0 0 0 1}
+test set-old-7.2 {unset command} {
+ list [catch {unset} msg] $msg
+} {0 {}}
+# Used to return:
+#{1 {wrong # args: should be "unset ?-nocomplain? ?--? ?varName ...?"}}
+test set-old-7.3 {unset command} {
+ catch {unset a}
+ list [catch {unset a} msg] $msg
+} {1 {can't unset "a": no such variable}}
+test set-old-7.4 {unset command} {
+ catch {unset a}
+ set a 44
+ list [catch {unset a(14)} msg] $msg
+} {1 {can't unset "a(14)": variable isn't array}}
+test set-old-7.5 {unset command} {
+ catch {unset a}
+ set a(0) xx
+ list [catch {unset a(14)} msg] $msg
+} {1 {can't unset "a(14)": no such element in array}}
+test set-old-7.6 {unset command} {
+ catch {unset a}; catch {unset b}; catch {unset c}
+ set a foo
+ set c gorp
+ list [catch {unset a a a(14)} msg] $msg [info exists c]
+} {1 {can't unset "a": no such variable} 1}
+test set-old-7.7 {unsetting globals from within procedures} {
+ set y 0
+ proc p1 {} {
+ global y
+ set z [p2]
+ return [list $z [catch {set y} msg] $msg]
+ }
+ proc p2 {} {global y; unset y; list [catch {set y} msg] $msg}
+ p1
+} {{1 {can't read "y": no such variable}} 1 {can't read "y": no such variable}}
+test set-old-7.8 {unsetting globals from within procedures} {
+ set y 0
+ proc p1 {} {
+ global y
+ p2
+ return [list [catch {set y 44} msg] $msg]
+ }
+ proc p2 {} {global y; unset y}
+ concat [p1] [list [catch {set y} msg] $msg]
+} {0 44 0 44}
+test set-old-7.9 {unsetting globals from within procedures} {
+ set y 0
+ proc p1 {} {
+ global y
+ unset y
+ return [list [catch {set y 55} msg] $msg]
+ }
+ concat [p1] [list [catch {set y} msg] $msg]
+} {0 55 0 55}
+test set-old-7.10 {unset command} {
+ catch {unset a}
+ set a(14) 22
+ unset a(14)
+ list [catch {set a(14)} msg] $msg [catch {array names a} msg2] $msg2
+} {1 {can't read "a(14)": no such element in array} 0 {}}
+test set-old-7.11 {unset command} {
+ catch {unset a}
+ set a(14) 22
+ unset a
+ list [catch {set a(14)} msg] $msg [catch {array names a} msg2] $msg2
+} {1 {can't read "a(14)": no such variable} 0 {}}
+test set-old-7.12 {unset command, -nocomplain} {
+ catch {unset a}
+ list [info exists a] [catch {unset -nocomplain a}] [info exists a]
+} {0 0 0}
+test set-old-7.13 {unset command, -nocomplain} {
+ set -nocomplain abc
+ list [info exists -nocomplain] [catch {unset -nocomplain}] \
+ [info exists -nocomplain] [catch {unset -- -nocomplain}] \
+ [info exists -nocomplain]
+} {1 0 1 0 0}
+test set-old-7.14 {unset command, --} {
+ set -- abc
+ list [info exists --] [catch {unset --}] \
+ [info exists --] [catch {unset -- --}] \
+ [info exists --]
+} {1 0 1 0 0}
+test set-old-7.15 {unset command, -nocomplain} {
+ set -nocomplain abc
+ set -- abc
+ list [info exists -nocomplain] [catch {unset -- -nocomplain}] \
+ [info exists -nocomplain] [info exists --] \
+ [catch {unset -- -nocomplain}] [info exists --] \
+ [catch {unset -- --}] [info exists --]
+} {1 0 0 1 1 1 0 0}
+test set-old-7.16 {unset command, -nocomplain} {
+ set -nocomplain abc
+ set var abc
+ list [info exists bogus] [catch {unset -nocomplain bogus var bogus}] \
+ [info exists -nocomplain] [info exists var] \
+ [catch {unset -nocomplain -nocomplain}] [info exists -nocomplain]
+} {0 0 1 0 0 0}
+test set-old-7.17 {unset command, -nocomplain (no abbreviation)} {
+ set -nocomp abc
+ list [info exists -nocomp] [catch {unset -nocomp}] [info exists -nocomp]
+} {1 0 0}
+test set-old-7.18 {unset command, -nocomplain (no abbreviation)} {
+ catch {unset -nocomp}
+ list [info exists -nocomp] [catch {unset -nocomp}]
+} {0 1}
+
+# Array command.
+
+test set-old-8.1 {array command} {
+ list [catch {array} msg] $msg
+} {1 {wrong # args: should be "array subcommand ?arg ...?"}}
+test set-old-8.2 {array command} {
+ list [catch {array a} msg] $msg
+} {1 {wrong # args: should be "array anymore arrayName searchId"}}
+test set-old-8.3 {array command} {
+ catch {unset a}
+ list [catch {array anymore a b} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.4 {array command} {
+ catch {unset a}
+ set a 44
+ list [catch {array anymore a b} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.5 {array command} {
+ proc foo {} {
+ set a 44
+ upvar 0 a x
+ list [catch {array anymore x b} msg] $msg
+ }
+ foo
+} {1 {"x" isn't an array}}
+test set-old-8.6 {array command} {
+ catch {unset a}
+ set a(22) 3
+ list [catch {array gorp a} msg] $msg
+} {1 {unknown or ambiguous subcommand "gorp": must be anymore, donesearch, exists, get, names, nextelement, set, size, startsearch, statistics, or unset}}
+test set-old-8.7 {array command, anymore option} {
+ catch {unset a}
+ list [catch {array anymore a x} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.8 {array command, anymore option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ proc foo {x} {
+ if {$x==1} {
+ return [array anymore a x]
+ }
+ set a(x) 123
+ }
+ list [catch {foo 1} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.9 {array command, donesearch option} {
+ catch {unset a}
+ list [catch {array donesearch a x} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.10 {array command, donesearch option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ proc foo {x} {
+ if {$x==1} {
+ return [array donesearch a x]
+ }
+ set a(x) 123
+ }
+ list [catch {foo 1} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.11 {array command, exists option} {
+ list [catch {array exists a b} msg] $msg
+} {1 {wrong # args: should be "array exists arrayName"}}
+test set-old-8.12 {array command, exists option} {
+ catch {unset a}
+ array exists a
+} {0}
+test set-old-8.13 {array command, exists option} {
+ catch {unset a}
+ set a(0) 1
+ array exists a
+} {1}
+test set-old-8.14 {array command, exists option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ proc foo {x} {
+ if {$x==1} {
+ return [array exists a]
+ }
+ set a(x) 123
+ }
+ list [catch {foo 1} msg] $msg
+} {0 0}
+test set-old-8.15 {array command, get option} {
+ list [catch {array get} msg] $msg
+} {1 {wrong # args: should be "array get arrayName ?pattern?"}}
+test set-old-8.16 {array command, get option} {
+ list [catch {array get a b c} msg] $msg
+} {1 {wrong # args: should be "array get arrayName ?pattern?"}}
+test set-old-8.17 {array command, get option} {
+ catch {unset a}
+ array get a
+} {}
+test set-old-8.18 {array command, get option} {
+ catch {unset a}
+ set a(22) 3
+ set {a(long name)} {}
+ lsort [array get a]
+} {{} 22 3 {long name}}
+test set-old-8.19 {array command, get option (unset variable)} {
+ catch {unset a}
+ set a(x) 3
+ trace var a(y) w ignore
+ array get a
+} {x 3}
+test set-old-8.20 {array command, get option, with pattern} {
+ catch {unset a}
+ set a(x1) 3
+ set a(x2) 4
+ set a(x3) 5
+ set a(b1) 24
+ set a(b2) 25
+ lsort [array get a x*]
+} {3 4 5 x1 x2 x3}
+test set-old-8.21 {array command, get option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ proc foo {x} {
+ if {$x==1} {
+ return [array get a]
+ }
+ set a(x) 123
+ }
+ list [catch {foo 1} msg] $msg
+} {0 {}}
+test set-old-8.22 {array command, names option} {
+ catch {unset a}
+ set a(22) 3
+ list [catch {array names a 4 5} msg] $msg
+} {1 {bad option "4": must be -exact, -glob, or -regexp}}
+test set-old-8.23 {array command, names option} {
+ catch {unset a}
+ array names a
+} {}
+test set-old-8.24 {array command, names option} {
+ catch {unset a}
+ set a(22) 3; set a(Textual_name) 44; set "a(name with spaces)" xxx
+ list [catch {lsort [array names a]} msg] $msg
+} {0 {22 Textual_name {name with spaces}}}
+test set-old-8.25 {array command, names option} {
+ catch {unset a}
+ set a(22) 3; set a(33) 44;
+ trace var a(xxx) w ignore
+ list [catch {lsort [array names a]} msg] $msg
+} {0 {22 33}}
+test set-old-8.26 {array command, names option} {
+ catch {unset a}
+ set a(22) 3; set a(33) 44;
+ trace var a(xxx) w ignore
+ set a(xxx) value
+ list [catch {lsort [array names a]} msg] $msg
+} {0 {22 33 xxx}}
+test set-old-8.27 {array command, names option} {
+ catch {unset a}
+ set a(axy) 3
+ set a(bxy) 44
+ set a(no) yes
+ set a(xxx) value
+ list [lsort [array names a *xy]] [lsort [array names a]]
+} {{axy bxy} {axy bxy no xxx}}
+test set-old-8.28 {array command, names option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ proc foo {x} {
+ if {$x==1} {
+ return [array names a]
+ }
+ set a(x) 123
+ }
+ list [catch {foo 1} msg] $msg
+} {0 {}}
+test set-old-8.29 {array command, nextelement option} {
+ list [catch {array nextelement a} msg] $msg
+} {1 {wrong # args: should be "array nextelement arrayName searchId"}}
+test set-old-8.30 {array command, nextelement option} {
+ catch {unset a}
+ list [catch {array nextelement a b} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.31 {array command, nextelement option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ proc foo {x} {
+ if {$x==1} {
+ return [array nextelement a b]
+ }
+ set a(x) 123
+ }
+ list [catch {foo 1} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.32 {array command, set option} {
+ list [catch {array set a} msg] $msg
+} {1 {wrong # args: should be "array set arrayName list"}}
+test set-old-8.33 {array command, set option} {
+ list [catch {array set a 1 2} msg] $msg
+} {1 {wrong # args: should be "array set arrayName list"}}
+test set-old-8.34 {array command, set option} {
+ list [catch {array set a "a \{ c"} msg] $msg
+} {1 {unmatched open brace in list}}
+test set-old-8.35 {array command, set option} {
+ catch {unset a}
+ set a 44
+ list [catch {array set a {a b c d}} msg] $msg
+} {1 {can't set "a(a)": variable isn't array}}
+test set-old-8.36 {array command, set option} {
+ catch {unset a}
+ set a(xx) yy
+ array set a {b c d e}
+ lsort [array get a]
+} {b c d e xx yy}
+test set-old-8.37 {array command, set option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ proc foo {x} {
+ if {$x==1} {
+ return [array set a {x 0}]
+ }
+ set a(x)
+ }
+ list [catch {foo 1} msg] $msg
+} {0 {}}
+test set-old-8.38 {array command, set option} {
+ catch {unset aVaRnAmE}
+ array set aVaRnAmE {}
+ list [info exists aVaRnAmE] [catch {set aVaRnAmE} msg] $msg
+} {1 1 {can't read "aVaRnAmE": variable is array}}
+test set-old-8.38.1 {array command, set scalar} {
+ catch {unset aVaRnAmE}
+ set aVaRnAmE 1
+ list [catch {array set aVaRnAmE {}} msg] $msg
+} {1 {can't array set "aVaRnAmE": variable isn't array}}
+test set-old-8.38.2 {array command, set alias} {
+ catch {unset aVaRnAmE}
+ upvar 0 aVaRnAmE anAliAs
+ array set anAliAs {}
+ list [array exists aVaRnAmE] [catch {set anAliAs} msg] $msg
+} {1 1 {can't read "anAliAs": variable is array}}
+test set-old-8.38.3 {array command, set element alias} {
+ catch {unset aVaRnAmE}
+ list [catch {upvar 0 aVaRnAmE(elem) elemAliAs}] \
+ [catch {array set elemAliAs {}} msg] $msg
+} {0 1 {can't array set "elemAliAs": variable isn't array}}
+test set-old-8.38.4 {array command, empty set with populated array} {
+ catch {unset aVaRnAmE}
+ array set aVaRnAmE [list e1 v1 e2 v2]
+ array set aVaRnAmE {}
+ array set aVaRnAmE [list e3 v3]
+ list [lsort [array names aVaRnAmE]] [catch {set aVaRnAmE(e2)} msg] $msg
+} {{e1 e2 e3} 0 v2}
+test set-old-8.38.5 {array command, set with non-existent namespace} {
+ list [catch {array set bogusnamespace::var {}} msg] $msg
+} {1 {can't set "bogusnamespace::var": parent namespace doesn't exist}}
+test set-old-8.38.6 {array command, set with non-existent namespace} {
+ list [catch {array set bogusnamespace::var {a b}} msg] $msg
+} {1 {can't set "bogusnamespace::var": parent namespace doesn't exist}}
+test set-old-8.38.7 {array command, set with non-existent namespace} {
+ list [catch {array set bogusnamespace::var(0) {a b}} msg] $msg
+} {1 {can't set "bogusnamespace::var(0)": parent namespace doesn't exist}}
+test set-old-8.39 {array command, size option} {
+ catch {unset a}
+ array size a
+} {0}
+test set-old-8.40 {array command, size option} {
+ list [catch {array size a 4} msg] $msg
+} {1 {wrong # args: should be "array size arrayName"}}
+test set-old-8.41 {array command, size option} {
+ catch {unset a}
+ array size a
+} {0}
+test set-old-8.42 {array command, size option} {
+ catch {unset a}
+ set a(22) 3; set a(Textual_name) 44; set "a(name with spaces)" xxx
+ list [catch {array size a} msg] $msg
+} {0 3}
+test set-old-8.43 {array command, size option} {
+ catch {unset a}
+ set a(22) 3; set a(xx) 44; set a(y) xxx
+ unset a(22) a(y) a(xx)
+ list [catch {array size a} msg] $msg
+} {0 0}
+test set-old-8.44 {array command, size option} {
+ catch {unset a}
+ set a(22) 3;
+ trace var a(33) rwu ignore
+ list [catch {array size a} msg] $msg
+} {0 1}
+test set-old-8.45 {array command, size option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ proc foo {x} {
+ if {$x==1} {
+ return [array size a]
+ }
+ set a(x) 123
+ }
+ list [catch {foo 1} msg] $msg
+} {0 0}
+test set-old-8.46 {array command, startsearch option} {
+ list [catch {array startsearch a b} msg] $msg
+} {1 {wrong # args: should be "array startsearch arrayName"}}
+test set-old-8.47 {array command, startsearch option} {
+ catch {unset a}
+ list [catch {array startsearch a} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.48 {array command, startsearch option, array doesn't exist yet but has compiler-allocated procedure slot} {
+ catch {rename p ""}
+ proc p {x} {
+ if {$x==1} {
+ return [array startsearch a]
+ }
+ set a(x) 123
+ }
+ list [catch {p 1} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.49 {array command, statistics option} {
+ catch {unset a}
+ set a(abc) 1
+ set a(def) 2
+ set a(ghi) 3
+ set a(jkl) 4
+ set a(mno) 5
+ set a(pqr) 6
+ set a(stu) 7
+ set a(vwx) 8
+ set a(yz) 9
+ array statistics a
+} "9 entries in table, 4 buckets
+number of buckets with 0 entries: 0
+number of buckets with 1 entries: 0
+number of buckets with 2 entries: 3
+number of buckets with 3 entries: 1
+number of buckets with 4 entries: 0
+number of buckets with 5 entries: 0
+number of buckets with 6 entries: 0
+number of buckets with 7 entries: 0
+number of buckets with 8 entries: 0
+number of buckets with 9 entries: 0
+number of buckets with 10 or more entries: 0
+average search distance for entry: 1.7"
+test set-old-8.50 {array command, array names -exact on glob pattern} {
+ catch {unset a}
+ set a(1*2) 1
+ list [catch {array names a -exact 1*2} msg] $msg
+} {0 1*2}
+test set-old-8.51 {array command, array names -glob on glob pattern} {
+ catch {unset a}
+ set a(1*2) 1
+ set a(12) 1
+ set a(11) 1
+ list [catch {lsort [array names a -glob 1*2]} msg] $msg
+} {0 {1*2 12}}
+test set-old-8.52 {array command, array names -regexp on regexp pattern} {
+ catch {unset a}
+ set a(1*2) 1
+ set a(12) 1
+ set a(11) 1
+ list [catch {lsort [array names a -regexp ^1]} msg] $msg
+} {0 {1*2 11 12}}
+test set-old-8.53 {array command, array names -regexp} {
+ catch {unset a}
+ set a(-glob) 1
+ set a(-regexp) 1
+ set a(-exact) 1
+ list [catch {array names a -regexp} msg] $msg
+} {0 -regexp}
+test set-old-8.54 {array command, array names -exact} {
+ catch {unset a}
+ set a(-glob) 1
+ set a(-regexp) 1
+ set a(-exact) 1
+ list [catch {array names a -exact} msg] $msg
+} {0 -exact}
+test set-old-8.55 {array command, array names -glob} {
+ catch {unset a}
+ set a(-glob) 1
+ set a(-regexp) 1
+ set a(-exact) 1
+ list [catch {array names a -glob} msg] $msg
+} {0 -glob}
+test set-old-8.56 {array command, array statistics on a non-array} {
+ catch {unset a}
+ list [catch {array statistics a} msg] $msg
+} [list 1 "\"a\" isn't an array"]
+test set-old-8.57 {array command, array get with trivial pattern} {
+ catch {unset a}
+ set a(x) 1
+ set a(y) 2
+ array get a x
+} {x 1}
+
+test set-old-9.1 {ids for array enumeration} {
+ catch {unset a}
+ set a(a) 1
+ list [array star a] [array star a] [array done a s-1-a; array star a] \
+ [array done a s-2-a; array d a s-3-a; array start a]
+} {s-1-a s-2-a s-3-a s-1-a}
+test set-old-9.2 {array enumeration} {
+ catch {unset a}
+ set a(a) 1
+ set a(b) 1
+ set a(c) 1
+ set x [array startsearch a]
+ lsort [list [array nextelement a $x] [array ne a $x] [array next a $x] \
+ [array next a $x] [array next a $x]]
+} {{} {} a b c}
+test set-old-9.3 {array enumeration} {
+ catch {unset a}
+ set a(a) 1
+ set a(b) 1
+ set a(c) 1
+ set x [array startsearch a]
+ set y [array startsearch a]
+ set z [array startsearch a]
+ lsort [list [array nextelement a $x] [array ne a $x] \
+ [array next a $y] [array next a $z] [array next a $y] \
+ [array next a $z] [array next a $y] [array next a $z] \
+ [array next a $y] [array next a $z] [array next a $x] \
+ [array next a $x]]
+} {{} {} {} a a a b b b c c c}
+test set-old-9.4 {array enumeration: stopping searches} {
+ catch {unset a}
+ set a(a) 1
+ set a(b) 1
+ set a(c) 1
+ set x [array startsearch a]
+ set y [array startsearch a]
+ set z [array startsearch a]
+ lsort [list [array next a $x] [array next a $x] [array next a $y] \
+ [array done a $z; array next a $x] \
+ [array done a $x; array next a $y] [array next a $y]]
+} {a a b b c c}
+test set-old-9.5 {array enumeration: stopping searches} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ array done a $x
+ list [catch {array next a $x} msg] $msg
+} {1 {couldn't find search "s-1-a"}}
+test set-old-9.6 {array enumeration: searches automatically stopped} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ set y [array startsearch a]
+ set a(b) 1
+ list [catch {array next a $x} msg] $msg \
+ [catch {array next a $y} msg2] $msg2
+} {1 {couldn't find search "s-1-a"} 1 {couldn't find search "s-2-a"}}
+test set-old-9.7 {array enumeration: searches automatically stopped} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ set y [array startsearch a]
+ set a(a) 2
+ list [catch {array next a $x} msg] $msg \
+ [catch {array next a $y} msg2] $msg2
+} {0 a 0 a}
+test set-old-9.8 {array enumeration: searches automatically stopped} {
+ catch {unset a}
+ set a(a) 1
+ set a(c) 2
+ set x [array startsearch a]
+ set y [array startsearch a]
+ catch {unset a(c)}
+ list [catch {array next a $x} msg] $msg \
+ [catch {array next a $y} msg2] $msg2
+} {1 {couldn't find search "s-1-a"} 1 {couldn't find search "s-2-a"}}
+test set-old-9.9 {array enumeration: searches automatically stopped} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ set y [array startsearch a]
+ catch {unset a(c)}
+ list [catch {array next a $x} msg] $msg \
+ [catch {array next a $y} msg2] $msg2
+} {0 a 0 a}
+test set-old-9.10 {array enumeration: searches automatically stopped} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ set y [array startsearch a]
+ trace var a(b) r {}
+ list [catch {array next a $x} msg] $msg \
+ [catch {array next a $y} msg2] $msg2
+} {1 {couldn't find search "s-1-a"} 1 {couldn't find search "s-2-a"}}
+test set-old-9.11 {array enumeration: searches automatically stopped} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ set y [array startsearch a]
+ trace var a(a) r {}
+ list [catch {array next a $x} msg] $msg \
+ [catch {array next a $y} msg2] $msg2
+} {0 a 0 a}
+test set-old-9.12 {array enumeration with traced undefined elements} {
+ catch {unset a}
+ set a(a) 1
+ trace var a(b) r {}
+ set x [array startsearch a]
+ lsort [list [array next a $x] [array next a $x]]
+} {{} a}
+
+test set-old-10.1 {array enumeration errors} {
+ list [catch {array start} msg] $msg
+} {1 {wrong # args: should be "array startsearch arrayName"}}
+test set-old-10.2 {array enumeration errors} {
+ list [catch {array start a b} msg] $msg
+} {1 {wrong # args: should be "array startsearch arrayName"}}
+test set-old-10.3 {array enumeration errors} {
+ catch {unset a}
+ list [catch {array start a} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-10.4 {array enumeration errors} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ list [catch {array next a} msg] $msg
+} {1 {wrong # args: should be "array nextelement arrayName searchId"}}
+test set-old-10.5 {array enumeration errors} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ list [catch {array next a b c} msg] $msg
+} {1 {wrong # args: should be "array nextelement arrayName searchId"}}
+test set-old-10.6 {array enumeration errors} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ list [catch {array next a a-1-a} msg] $msg
+} {1 {illegal search identifier "a-1-a"}}
+test set-old-10.7 {array enumeration errors} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ list [catch {array next a sx1-a} msg] $msg
+} {1 {illegal search identifier "sx1-a"}}
+test set-old-10.8 {array enumeration errors} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ list [catch {array next a s--a} msg] $msg
+} {1 {illegal search identifier "s--a"}}
+test set-old-10.9 {array enumeration errors} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ list [catch {array next a s-1-b} msg] $msg
+} {1 {search identifier "s-1-b" isn't for variable "a"}}
+test set-old-10.10 {array enumeration errors} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ list [catch {array next a s-1ba} msg] $msg
+} {1 {illegal search identifier "s-1ba"}}
+test set-old-10.11 {array enumeration errors} {
+ catch {unset a}
+ set a(a) 1
+ set x [array startsearch a]
+ list [catch {array next a s-2-a} msg] $msg
+} {1 {couldn't find search "s-2-a"}}
+test set-old-10.12 {array enumeration errors} {
+ list [catch {array done a} msg] $msg
+} {1 {wrong # args: should be "array donesearch arrayName searchId"}}
+test set-old-10.13 {array enumeration errors} {
+ list [catch {array done a b c} msg] $msg
+} {1 {wrong # args: should be "array donesearch arrayName searchId"}}
+test set-old-10.14 {array enumeration errors} {
+ list [catch {array done a b} msg] $msg
+} {1 {illegal search identifier "b"}}
+test set-old-10.15 {array enumeration errors} {
+ list [catch {array anymore a} msg] $msg
+} {1 {wrong # args: should be "array anymore arrayName searchId"}}
+test set-old-10.16 {array enumeration errors} {
+ list [catch {array any a b c} msg] $msg
+} {1 {wrong # args: should be "array anymore arrayName searchId"}}
+test set-old-10.17 {array enumeration errors} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {array any a bogus} msg] $msg
+} {1 {illegal search identifier "bogus"}}
+
+# Array enumeration with "anymore" option
+
+test set-old-11.1 {array anymore option} {
+ catch {unset a}
+ set a(a) 1
+ set a(b) 2
+ set a(c) 3
+ array startsearch a
+ lsort [list [array anymore a s-1-a] [array next a s-1-a] \
+ [array anymore a s-1-a] [array next a s-1-a] \
+ [array anymore a s-1-a] [array next a s-1-a] \
+ [array anymore a s-1-a] [array next a s-1-a]]
+} {{} 0 1 1 1 a b c}
+test set-old-11.2 {array anymore option} {
+ catch {unset a}
+ set a(a) 1
+ set a(b) 2
+ set a(c) 3
+ array startsearch a
+ lsort [list [array next a s-1-a] [array next a s-1-a] \
+ [array anymore a s-1-a] [array next a s-1-a] \
+ [array next a s-1-a] [array anymore a s-1-a]]
+} {{} 0 1 a b c}
+
+# Special check to see that the value of a variable is handled correctly
+# if it is returned as the result of a procedure (must not free the variable
+# string while deleting the call frame). Errors will only be detected if
+# a memory consistency checker such as Purify is being used.
+
+test set-old-12.1 {cleanup on procedure return} {
+ proc foo {} {
+ set x 12345
+ }
+ foo
+} 12345
+test set-old-12.2 {cleanup on procedure return} {
+ proc foo {} {
+ set x(1) 23456
+ }
+ foo
+} 23456
+
+# Must delete variables when done, since these arrays get used as
+# scalars by other tests.
+catch {unset a}
+catch {unset b}
+catch {unset c}
+catch {unset aVaRnAmE}
+catch {rename foo {}}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/set.test b/pkgs/msgcat/tests/set.test
new file mode 100644
index 0000000..9e0ddc0
--- /dev/null
+++ b/pkgs/msgcat/tests/set.test
@@ -0,0 +1,531 @@
+# Commands covered: set
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testset2 [llength [info commands testset2]]
+
+catch {unset x}
+catch {unset i}
+
+test set-1.1 {TclCompileSetCmd: missing variable name} {
+ list [catch {set} msg] $msg
+} {1 {wrong # args: should be "set varName ?newValue?"}}
+test set-1.2 {TclCompileSetCmd: simple variable name} {
+ set i 10
+ list [set i] $i
+} {10 10}
+test set-1.3 {TclCompileSetCmd: error compiling variable name} {
+ set i 10
+ catch {set "i"xxx} msg
+ set msg
+} {extra characters after close-quote}
+test set-1.4 {TclCompileSetCmd: simple variable name in quotes} {
+ set i 17
+ list [set "i"] $i
+} {17 17}
+test set-1.5 {TclCompileSetCmd: simple variable name in braces} {
+ catch {unset {a simple var}}
+ set {a simple var} 27
+ list [set {a simple var}] ${a simple var}
+} {27 27}
+test set-1.6 {TclCompileSetCmd: simple array variable name} {
+ catch {unset a}
+ set a(foo) 37
+ list [set a(foo)] $a(foo)
+} {37 37}
+test set-1.7 {TclCompileSetCmd: non-simple (computed) variable name} {
+ set x "i"
+ set i 77
+ list [set $x] $i
+} {77 77}
+test set-1.8 {TclCompileSetCmd: non-simple (computed) variable name} {
+ set x "i"
+ set i 77
+ list [set [set x] 2] $i
+} {2 2}
+
+test set-1.9 {TclCompileSetCmd: 3rd arg => assignment} {
+ set i "abcdef"
+ list [set i] $i
+} {abcdef abcdef}
+test set-1.10 {TclCompileSetCmd: only two args => just getting value} {
+ set i {one two}
+ set i
+} {one two}
+
+test set-1.11 {TclCompileSetCmd: simple global name} {
+ proc p {} {
+ global i
+ set i 54
+ set i
+ }
+ p
+} {54}
+test set-1.12 {TclCompileSetCmd: simple local name} {
+ proc p {bar} {
+ set foo $bar
+ set foo
+ }
+ p 999
+} {999}
+test set-1.13 {TclCompileSetCmd: simple but new (unknown) local name} {
+ proc p {} {
+ set bar
+ }
+ catch {p} msg
+ set msg
+} {can't read "bar": no such variable}
+test set-1.14 {TclCompileSetCmd: simple local name, >255 locals} {
+ proc 260locals {} {
+ # create 260 locals (the last ones with index > 255)
+ set a0 0; set a1 0; set a2 0; set a3 0; set a4 0
+ set a5 0; set a6 0; set a7 0; set a8 0; set a9 0
+ set b0 0; set b1 0; set b2 0; set b3 0; set b4 0
+ set b5 0; set b6 0; set b7 0; set b8 0; set b9 0
+ set c0 0; set c1 0; set c2 0; set c3 0; set c4 0
+ set c5 0; set c6 0; set c7 0; set c8 0; set c9 0
+ set d0 0; set d1 0; set d2 0; set d3 0; set d4 0
+ set d5 0; set d6 0; set d7 0; set d8 0; set d9 0
+ set e0 0; set e1 0; set e2 0; set e3 0; set e4 0
+ set e5 0; set e6 0; set e7 0; set e8 0; set e9 0
+ set f0 0; set f1 0; set f2 0; set f3 0; set f4 0
+ set f5 0; set f6 0; set f7 0; set f8 0; set f9 0
+ set g0 0; set g1 0; set g2 0; set g3 0; set g4 0
+ set g5 0; set g6 0; set g7 0; set g8 0; set g9 0
+ set h0 0; set h1 0; set h2 0; set h3 0; set h4 0
+ set h5 0; set h6 0; set h7 0; set h8 0; set h9 0
+ set i0 0; set i1 0; set i2 0; set i3 0; set i4 0
+ set i5 0; set i6 0; set i7 0; set i8 0; set i9 0
+ set j0 0; set j1 0; set j2 0; set j3 0; set j4 0
+ set j5 0; set j6 0; set j7 0; set j8 0; set j9 0
+ set k0 0; set k1 0; set k2 0; set k3 0; set k4 0
+ set k5 0; set k6 0; set k7 0; set k8 0; set k9 0
+ set l0 0; set l1 0; set l2 0; set l3 0; set l4 0
+ set l5 0; set l6 0; set l7 0; set l8 0; set l9 0
+ set m0 0; set m1 0; set m2 0; set m3 0; set m4 0
+ set m5 0; set m6 0; set m7 0; set m8 0; set m9 0
+ set n0 0; set n1 0; set n2 0; set n3 0; set n4 0
+ set n5 0; set n6 0; set n7 0; set n8 0; set n9 0
+ set o0 0; set o1 0; set o2 0; set o3 0; set o4 0
+ set o5 0; set o6 0; set o7 0; set o8 0; set o9 0
+ set p0 0; set p1 0; set p2 0; set p3 0; set p4 0
+ set p5 0; set p6 0; set p7 0; set p8 0; set p9 0
+ set q0 0; set q1 0; set q2 0; set q3 0; set q4 0
+ set q5 0; set q6 0; set q7 0; set q8 0; set q9 0
+ set r0 0; set r1 0; set r2 0; set r3 0; set r4 0
+ set r5 0; set r6 0; set r7 0; set r8 0; set r9 0
+ set s0 0; set s1 0; set s2 0; set s3 0; set s4 0
+ set s5 0; set s6 0; set s7 0; set s8 0; set s9 0
+ set t0 0; set t1 0; set t2 0; set t3 0; set t4 0
+ set t5 0; set t6 0; set t7 0; set t8 0; set t9 0
+ set u0 0; set u1 0; set u2 0; set u3 0; set u4 0
+ set u5 0; set u6 0; set u7 0; set u8 0; set u9 0
+ set v0 0; set v1 0; set v2 0; set v3 0; set v4 0
+ set v5 0; set v6 0; set v7 0; set v8 0; set v9 0
+ set w0 0; set w1 0; set w2 0; set w3 0; set w4 0
+ set w5 0; set w6 0; set w7 0; set w8 0; set w9 0
+ set x0 0; set x1 0; set x2 0; set x3 0; set x4 0
+ set x5 0; set x6 0; set x7 0; set x8 0; set x9 0
+ set y0 0; set y1 0; set y2 0; set y3 0; set y4 0
+ set y5 0; set y6 0; set y7 0; set y8 0; set y9 0
+ set z0 0; set z1 0; set z2 0; set z3 0; set z4 0
+ set z5 0; set z6 0; set z7 0; set z8 0; set z9 1234
+ }
+ 260locals
+} {1234}
+test set-1.15 {TclCompileSetCmd: variable is array} {
+ catch {unset a}
+ set x 27
+ set x [set a(foo) 11]
+ catch {unset a}
+ set x
+} 11
+test set-1.16 {TclCompileSetCmd: variable is array, elem substitutions} {
+ catch {unset a}
+ set i 5
+ set x 789
+ set a(foo5) 27
+ set x [set a(foo$i)]
+ catch {unset a}
+ set x
+} 27
+
+test set-1.17 {TclCompileSetCmd: doing assignment, simple int} {
+ set i 5
+ set i 123
+} 123
+test set-1.18 {TclCompileSetCmd: doing assignment, simple int} {
+ set i 5
+ set i -100
+} -100
+test set-1.19 {TclCompileSetCmd: doing assignment, simple but not int} {
+ set i 5
+ set i 0x12MNOP
+ set i
+} {0x12MNOP}
+test set-1.20 {TclCompileSetCmd: doing assignment, in quotes} {
+ set i 25
+ set i "-100"
+} -100
+test set-1.21 {TclCompileSetCmd: doing assignment, in braces} {
+ set i 24
+ set i {126}
+} 126
+test set-1.22 {TclCompileSetCmd: doing assignment, large int} {
+ set i 5
+ set i 200000
+} 200000
+test set-1.23 {TclCompileSetCmd: doing assignment, formatted int != int} {
+ set i 25
+ set i 0o00012345 ;# an octal literal == 5349 decimal
+ list $i [incr i]
+} {0o00012345 5350}
+
+test set-1.24 {TclCompileSetCmd: too many arguments} {
+ set i 10
+ catch {set i 20 30} msg
+ set msg
+} {wrong # args: should be "set varName ?newValue?"}
+
+test set-1.25 {TclCompileSetCmd: var is array, braced (no subs)} {
+ # This was a known error in 8.1a* - 8.2.1
+ catch {unset array}
+ set {array($foo)} 5
+} 5
+test set-1.26 {TclCompileSetCmd: various array constructs} {
+ # Test all kinds of array constructs that TclCompileSetCmd
+ # may feel inclined to tamper with.
+ proc p {} {
+ set a x
+ set be(hej) 1 ; # hej
+ set be($a) 1 ; # x
+ set {be($a)} 1 ; # $a
+ set be($a,hej) 1 ; # x,hej
+ set be($a,$a) 5 ; # x,x
+ set be(c($a) 1 ; # c(x
+ set be(\w\w) 1 ; # ww
+ set be(a:$a) [set be(x,$a)] ; # a:x
+ set be(hej,$be($a,hej),hej) 1 ; # hej,1,hej
+ set be([string range hugge 0 2]) 1 ; # hug
+ set be(a\ a) 1 ; # a a
+ set be($a\ ,[string range hugge 1 3],hej) 1 ; # x ,ugg,hej
+ set be($a,h"ej) 1 ; # x,h"ej
+ set be([string range "a b c" 2 end]) 1 ; # b c
+ set [string range bet 0 1](foo) 1 ; # foo
+ set be([set be(a:$a)][set b\e($a)]) 1 ; # 51
+ return [lsort [array names be]]
+ }
+ p
+} [lsort {hej x $a x,hej x,x c(x ww a:x hej,1,hej hug {a a} {x ,ugg,hej} x,h"ej
+{b c} foo 51}]; # " just a matching end quote
+
+test set-2.1 {set command: runtime error, bad variable name} {
+ unset -nocomplain {"foo}
+ list [catch {set {"foo}} msg] $msg $::errorInfo
+} {1 {can't read ""foo": no such variable} {can't read ""foo": no such variable
+ while executing
+"set {"foo}"}}
+test set-2.2 {set command: runtime error, not array variable} {
+ catch {unset b}
+ set b 44
+ list [catch {set b(123)} msg] $msg
+} {1 {can't read "b(123)": variable isn't array}}
+test set-2.3 {set command: runtime error, errors in reading variables} {
+ catch {unset a}
+ set a(6) 44
+ list [catch {set a(18)} msg] $msg
+} {1 {can't read "a(18)": no such element in array}}
+test set-2.4 {set command: runtime error, readonly variable} -body {
+ proc readonly args {error "variable is read-only"}
+ set x 123
+ trace var x w readonly
+ list [catch {set x 1} msg] $msg $::errorInfo
+} -match glob -result {1 {can't set "x": variable is read-only} {*variable is read-only
+ while executing
+*
+"set x 1"}}
+test set-2.5 {set command: runtime error, basic array operations} {
+ list [catch {set a(other)} msg] $msg
+} {1 {can't read "a(other)": no such element in array}}
+test set-2.6 {set command: runtime error, basic array operations} {
+ list [catch {set a} msg] $msg
+} {1 {can't read "a": variable is array}}
+
+# Test the uncompiled version of set
+
+catch {unset a}
+catch {unset b}
+catch {unset i}
+catch {unset x}
+
+test set-3.1 {uncompiled set command: missing variable name} {
+ set z set
+ list [catch {$z} msg] $msg
+} {1 {wrong # args: should be "set varName ?newValue?"}}
+test set-3.2 {uncompiled set command: simple variable name} {
+ set z set
+ $z i 10
+ list [$z i] $i
+} {10 10}
+test set-3.3 {uncompiled set command: error compiling variable name} {
+ set z set
+ $z i 10
+ catch {$z "i"xxx} msg
+ $z msg
+} {extra characters after close-quote}
+test set-3.4 {uncompiled set command: simple variable name in quotes} {
+ set z set
+ $z i 17
+ list [$z "i"] $i
+} {17 17}
+test set-3.5 {uncompiled set command: simple variable name in braces} {
+ set z set
+ catch {unset {a simple var}}
+ $z {a simple var} 27
+ list [$z {a simple var}] ${a simple var}
+} {27 27}
+test set-3.6 {uncompiled set command: simple array variable name} {
+ set z set
+ catch {unset a}
+ $z a(foo) 37
+ list [$z a(foo)] $a(foo)
+} {37 37}
+test set-3.7 {uncompiled set command: non-simple (computed) variable name} {
+ set z set
+ $z x "i"
+ $z i 77
+ list [$z $x] $i
+} {77 77}
+test set-3.8 {uncompiled set command: non-simple (computed) variable name} {
+ set z set
+ $z x "i"
+ $z i 77
+ list [$z [$z x] 2] $i
+} {2 2}
+
+test set-3.9 {uncompiled set command: 3rd arg => assignment} {
+ set z set
+ $z i "abcdef"
+ list [$z i] $i
+} {abcdef abcdef}
+test set-3.10 {uncompiled set command: only two args => just getting value} {
+ set z set
+ $z i {one two}
+ $z i
+} {one two}
+
+test set-3.11 {uncompiled set command: simple global name} {
+ proc p {} {
+ set z set
+ global i
+ $z i 54
+ $z i
+ }
+ p
+} {54}
+test set-3.12 {uncompiled set command: simple local name} {
+ proc p {bar} {
+ set z set
+ $z foo $bar
+ $z foo
+ }
+ p 999
+} {999}
+test set-3.13 {uncompiled set command: simple but new (unknown) local name} {
+ set z set
+ proc p {} {
+ set z set
+ $z bar
+ }
+ catch {p} msg
+ $z msg
+} {can't read "bar": no such variable}
+test set-3.14 {uncompiled set command: simple local name, >255 locals} {
+ proc 260locals {} {
+ set z set
+ # create 260 locals (the last ones with index > 255)
+ $z a0 0; $z a1 0; $z a2 0; $z a3 0; $z a4 0
+ $z a5 0; $z a6 0; $z a7 0; $z a8 0; $z a9 0
+ $z b0 0; $z b1 0; $z b2 0; $z b3 0; $z b4 0
+ $z b5 0; $z b6 0; $z b7 0; $z b8 0; $z b9 0
+ $z c0 0; $z c1 0; $z c2 0; $z c3 0; $z c4 0
+ $z c5 0; $z c6 0; $z c7 0; $z c8 0; $z c9 0
+ $z d0 0; $z d1 0; $z d2 0; $z d3 0; $z d4 0
+ $z d5 0; $z d6 0; $z d7 0; $z d8 0; $z d9 0
+ $z e0 0; $z e1 0; $z e2 0; $z e3 0; $z e4 0
+ $z e5 0; $z e6 0; $z e7 0; $z e8 0; $z e9 0
+ $z f0 0; $z f1 0; $z f2 0; $z f3 0; $z f4 0
+ $z f5 0; $z f6 0; $z f7 0; $z f8 0; $z f9 0
+ $z g0 0; $z g1 0; $z g2 0; $z g3 0; $z g4 0
+ $z g5 0; $z g6 0; $z g7 0; $z g8 0; $z g9 0
+ $z h0 0; $z h1 0; $z h2 0; $z h3 0; $z h4 0
+ $z h5 0; $z h6 0; $z h7 0; $z h8 0; $z h9 0
+ $z i0 0; $z i1 0; $z i2 0; $z i3 0; $z i4 0
+ $z i5 0; $z i6 0; $z i7 0; $z i8 0; $z i9 0
+ $z j0 0; $z j1 0; $z j2 0; $z j3 0; $z j4 0
+ $z j5 0; $z j6 0; $z j7 0; $z j8 0; $z j9 0
+ $z k0 0; $z k1 0; $z k2 0; $z k3 0; $z k4 0
+ $z k5 0; $z k6 0; $z k7 0; $z k8 0; $z k9 0
+ $z l0 0; $z l1 0; $z l2 0; $z l3 0; $z l4 0
+ $z l5 0; $z l6 0; $z l7 0; $z l8 0; $z l9 0
+ $z m0 0; $z m1 0; $z m2 0; $z m3 0; $z m4 0
+ $z m5 0; $z m6 0; $z m7 0; $z m8 0; $z m9 0
+ $z n0 0; $z n1 0; $z n2 0; $z n3 0; $z n4 0
+ $z n5 0; $z n6 0; $z n7 0; $z n8 0; $z n9 0
+ $z o0 0; $z o1 0; $z o2 0; $z o3 0; $z o4 0
+ $z o5 0; $z o6 0; $z o7 0; $z o8 0; $z o9 0
+ $z p0 0; $z p1 0; $z p2 0; $z p3 0; $z p4 0
+ $z p5 0; $z p6 0; $z p7 0; $z p8 0; $z p9 0
+ $z q0 0; $z q1 0; $z q2 0; $z q3 0; $z q4 0
+ $z q5 0; $z q6 0; $z q7 0; $z q8 0; $z q9 0
+ $z r0 0; $z r1 0; $z r2 0; $z r3 0; $z r4 0
+ $z r5 0; $z r6 0; $z r7 0; $z r8 0; $z r9 0
+ $z s0 0; $z s1 0; $z s2 0; $z s3 0; $z s4 0
+ $z s5 0; $z s6 0; $z s7 0; $z s8 0; $z s9 0
+ $z t0 0; $z t1 0; $z t2 0; $z t3 0; $z t4 0
+ $z t5 0; $z t6 0; $z t7 0; $z t8 0; $z t9 0
+ $z u0 0; $z u1 0; $z u2 0; $z u3 0; $z u4 0
+ $z u5 0; $z u6 0; $z u7 0; $z u8 0; $z u9 0
+ $z v0 0; $z v1 0; $z v2 0; $z v3 0; $z v4 0
+ $z v5 0; $z v6 0; $z v7 0; $z v8 0; $z v9 0
+ $z w0 0; $z w1 0; $z w2 0; $z w3 0; $z w4 0
+ $z w5 0; $z w6 0; $z w7 0; $z w8 0; $z w9 0
+ $z x0 0; $z x1 0; $z x2 0; $z x3 0; $z x4 0
+ $z x5 0; $z x6 0; $z x7 0; $z x8 0; $z x9 0
+ $z y0 0; $z y1 0; $z y2 0; $z y3 0; $z y4 0
+ $z y5 0; $z y6 0; $z y7 0; $z y8 0; $z y9 0
+ $z z0 0; $z z1 0; $z z2 0; $z z3 0; $z z4 0
+ $z z5 0; $z z6 0; $z z7 0; $z z8 0; $z z9 1234
+ }
+ 260locals
+} {1234}
+test set-3.15 {uncompiled set command: variable is array} {
+ set z set
+ catch {unset a}
+ $z x 27
+ $z x [$z a(foo) 11]
+ catch {unset a}
+ $z x
+} 11
+test set-3.16 {uncompiled set command: variable is array, elem substitutions} {
+ set z set
+ catch {unset a}
+ $z i 5
+ $z x 789
+ $z a(foo5) 27
+ $z x [$z a(foo$i)]
+ catch {unset a}
+ $z x
+} 27
+
+test set-3.17 {uncompiled set command: doing assignment, simple int} {
+ set z set
+ $z i 5
+ $z i 123
+} 123
+test set-3.18 {uncompiled set command: doing assignment, simple int} {
+ set z set
+ $z i 5
+ $z i -100
+} -100
+test set-3.19 {uncompiled set command: doing assignment, simple but not int} {
+ set z set
+ $z i 5
+ $z i 0x12MNOP
+ $z i
+} {0x12MNOP}
+test set-3.20 {uncompiled set command: doing assignment, in quotes} {
+ set z set
+ $z i 25
+ $z i "-100"
+} -100
+test set-3.21 {uncompiled set command: doing assignment, in braces} {
+ set z set
+ $z i 24
+ $z i {126}
+} 126
+test set-3.22 {uncompiled set command: doing assignment, large int} {
+ set z set
+ $z i 5
+ $z i 200000
+} 200000
+test set-3.23 {uncompiled set command: doing assignment, formatted int != int} {
+ set z set
+ $z i 25
+ $z i 0o00012345 ;# an octal literal == 5349 decimal
+ list $i [incr i]
+} {0o00012345 5350}
+
+test set-3.24 {uncompiled set command: too many arguments} {
+ set z set
+ $z i 10
+ catch {$z i 20 30} msg
+ $z msg
+} {wrong # args: should be "set varName ?newValue?"}
+
+test set-4.1 {uncompiled set command: runtime error, bad variable name} {
+ unset -nocomplain {"foo}
+ set z set
+ list [catch {$z {"foo}} msg] $msg $::errorInfo
+} {1 {can't read ""foo": no such variable} {can't read ""foo": no such variable
+ while executing
+"$z {"foo}"}}
+test set-4.2 {uncompiled set command: runtime error, not array variable} {
+ set z set
+ catch {unset b}
+ $z b 44
+ list [catch {$z b(123)} msg] $msg
+} {1 {can't read "b(123)": variable isn't array}}
+test set-4.3 {uncompiled set command: runtime error, errors in reading variables} {
+ set z set
+ catch {unset a}
+ $z a(6) 44
+ list [catch {$z a(18)} msg] $msg
+} {1 {can't read "a(18)": no such element in array}}
+test set-4.4 {uncompiled set command: runtime error, readonly variable} -body {
+ set z set
+ proc readonly args {error "variable is read-only"}
+ $z x 123
+ trace var x w readonly
+ list [catch {$z x 1} msg] $msg $::errorInfo
+} -match glob -result {1 {can't set "x": variable is read-only} {*variable is read-only
+ while executing
+*
+"$z x 1"}}
+test set-4.5 {uncompiled set command: runtime error, basic array operations} {
+ set z set
+ list [catch {$z a(other)} msg] $msg
+} {1 {can't read "a(other)": no such element in array}}
+test set-4.6 {set command: runtime error, basic array operations} {
+ set z set
+ list [catch {$z a} msg] $msg
+} {1 {can't read "a": variable is array}}
+
+test set-5.1 {error on malformed array name} testset2 {
+ unset -nocomplain z
+ catch {testset2 z(a) b} msg
+ catch {testset2 z(b) a} msg1
+ list $msg $msg1
+} {{can't read "z(a)(b)": variable isn't array} {can't read "z(b)(a)": variable isn't array}}
+
+# cleanup
+catch {unset a}
+catch {unset b}
+catch {unset i}
+catch {unset x}
+catch {unset z}
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/socket.test b/pkgs/msgcat/tests/socket.test
new file mode 100644
index 0000000..9f1cc78
--- /dev/null
+++ b/pkgs/msgcat/tests/socket.test
@@ -0,0 +1,1860 @@
+# Commands tested in this file: socket.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 Ajuba Solutions.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+# Running socket tests with a remote server:
+# ------------------------------------------
+#
+# Some tests in socket.test depend on the existence of a remote server to
+# which they connect. The remote server must be an instance of tcltest and it
+# must run the script found in the file "remote.tcl" in this directory. You
+# can start the remote server on any machine reachable from the machine on
+# which you want to run the socket tests, by issuing:
+#
+# tcltest remote.tcl -port 2048 # Or choose another port number.
+#
+# If the machine you are running the remote server on has several IP
+# interfaces, you can choose which interface the server listens on for
+# connections by specifying the -address command line flag, so:
+#
+# tcltest remote.tcl -address your.machine.com
+#
+# These options can also be set by environment variables. On Unix, you can
+# type these commands to the shell from which the remote server is started:
+#
+# shell% setenv serverPort 2048
+# shell% setenv serverAddress your.machine.com
+#
+# and subsequently you can start the remote server with:
+#
+# tcltest remote.tcl
+#
+# to have it listen on port 2048 on the interface your.machine.com.
+#
+# When the server starts, it prints out a detailed message containing its
+# configuration information, and it will block until killed with a Ctrl-C.
+# Once the remote server exists, you can run the tests in socket.test with the
+# server by setting two Tcl variables:
+#
+# % set remoteServerIP <name or address of machine on which server runs>
+# % set remoteServerPort 2048
+#
+# These variables are also settable from the environment. On Unix, you can:
+#
+# shell% setenv remoteServerIP machine.where.server.runs
+# shell% senetv remoteServerPort 2048
+#
+# The preamble of the socket.test file checks to see if the variables are set
+# either in Tcl or in the environment; if they are, it attempts to connect to
+# the server. If the connection is successful, the tests using the remote
+# server will be performed; otherwise, it will attempt to start the remote
+# server (via exec) on platforms that support this, on the local host,
+# listening at port 2048. If all fails, a message is printed and the tests
+# using the remote server are not performed.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+# Some tests require the Thread package or exec command
+testConstraint thread [expr {0 == [catch {package require Thread 2.6.6}]}]
+testConstraint exec [llength [info commands exec]]
+
+# Produce a random port number in the Dynamic/Private range
+# from 49152 through 65535.
+proc randport {} { expr {int(rand()*16383+49152)} }
+
+# Test the latency of tcp connections over the loopback interface. Some OSes
+# (e.g. NetBSD) seem to use the Nagle algorithm and delayed ACKs, so it takes
+# up to 200ms for a packet sent to localhost to arrive. We're measuring this
+# here, so that OSes that don't have this problem can run the tests at full
+# speed.
+set server [socket -server {apply {{s a p} {set ::s1 $s}}} 0]
+set s2 [socket localhost [lindex [fconfigure $server -sockname] 2]]
+vwait s1; close $server
+fconfigure $s1 -buffering line
+fconfigure $s2 -buffering line
+set t1 [clock milliseconds]
+puts $s2 test1; gets $s1
+puts $s2 test2; gets $s1
+close $s1; close $s2
+set t2 [clock milliseconds]
+set latency [expr {($t2-$t1)*2}]; # doubled as a safety margin
+unset t1 t2 s1 s2 server
+
+# If remoteServerIP or remoteServerPort are not set, check in the environment
+# variables for externally set values.
+#
+
+if {![info exists remoteServerIP]} {
+ if {[info exists env(remoteServerIP)]} {
+ set remoteServerIP $env(remoteServerIP)
+ }
+}
+if {![info exists remoteServerPort]} {
+ if {[info exists env(remoteServerPort)]} {
+ set remoteServerPort $env(remoteServerPort)
+ } else {
+ if {[info exists remoteServerIP]} {
+ set remoteServerPort 2048
+ }
+ }
+}
+
+if 0 {
+ # activate this to time the tests
+ proc test {args} {
+ set name [lindex $args 0]
+ puts "[lindex [time {uplevel [linsert $args 0 tcltest::test]}] 0] @@@ $name"
+ }
+}
+
+foreach {af localhost} {
+ inet 127.0.0.1
+ inet6 ::1
+} {
+ # Check if the family is supported and set the constraint accordingly
+ testConstraint supported_$af [expr {![catch {socket -server foo -myaddr $localhost 0} sock]}]
+ catch {close $sock}
+}
+testConstraint supported_any [expr {[testConstraint supported_inet] || [testConstraint supported_inet6]}]
+
+set sock [socket -server foo -myaddr localhost 0]
+set sockname [fconfigure $sock -sockname]
+close $sock
+testConstraint localhost_v4 [expr {"127.0.0.1" in $sockname}]
+testConstraint localhost_v6 [expr {"::1" in $sockname}]
+
+
+foreach {af localhost} {
+ any 127.0.0.1
+ inet 127.0.0.1
+ inet6 ::1
+} {
+ set ::tcl::unsupported::socketAF $af
+#
+# Check if we're supposed to do tests against the remote server
+#
+
+set doTestsWithRemoteServer 1
+if {![info exists remoteServerIP]} {
+ set remoteServerIP $localhost
+}
+if {($doTestsWithRemoteServer == 1) && (![info exists remoteServerPort])} {
+ set remoteServerPort [randport]
+}
+
+# Attempt to connect to a remote server if one is already running. If it is
+# not running or for some other reason the connect fails, attempt to start the
+# remote server on the local host listening on port 2048. This is only done on
+# platforms that support exec (i.e. not on the Mac). On platforms that do not
+# support exec, the remote server must be started by the user before running
+# the tests.
+
+set remoteProcChan ""
+set commandSocket ""
+if {$doTestsWithRemoteServer} {
+ catch {close $commandSocket}
+ if {![catch {
+ set commandSocket [socket $remoteServerIP $remoteServerPort]
+ }]} then {
+ fconfigure $commandSocket -translation crlf -buffering line
+ } elseif {![testConstraint exec]} {
+ set noRemoteTestReason "can't exec"
+ set doTestsWithRemoteServer 0
+ } else {
+ set remoteServerIP $localhost
+ # Be *extra* careful in case this file is sourced from
+ # a directory other than the current one...
+ set remoteFile [file join [pwd] [file dirname [info script]] \
+ remote.tcl]
+ if {![catch {
+ set remoteProcChan [open "|[list \
+ [interpreter] $remoteFile -serverIsSilent \
+ -port $remoteServerPort -address $remoteServerIP]" w+]
+ } msg]} then {
+ gets $remoteProcChan
+ if {[catch {
+ set commandSocket [socket $remoteServerIP $remoteServerPort]
+ } msg] == 0} then {
+ fconfigure $commandSocket -translation crlf -buffering line
+ } else {
+ set noRemoteTestReason $msg
+ set doTestsWithRemoteServer 0
+ }
+ } else {
+ set noRemoteTestReason "$msg [interpreter]"
+ set doTestsWithRemoteServer 0
+ }
+ }
+}
+
+# Some tests are run only if we are doing testing against a remote server.
+testConstraint doTestsWithRemoteServer $doTestsWithRemoteServer
+if {!$doTestsWithRemoteServer} {
+ if {[string first s $::tcltest::verbose] != -1} {
+ puts "Skipping tests with remote server. See tests/socket.test for"
+ puts "information on how to run remote server."
+ puts "Reason for not doing remote tests: $noRemoteTestReason"
+ }
+}
+
+#
+# If we do the tests, define a command to send a command to the remote server.
+#
+
+if {[testConstraint doTestsWithRemoteServer]} {
+ proc sendCommand {c} {
+ global commandSocket
+
+ if {[eof $commandSocket]} {
+ error "remote server disappeared"
+ }
+ if {[catch {puts $commandSocket $c} msg]} {
+ error "remote server disappaered: $msg"
+ }
+ if {[catch {puts $commandSocket "--Marker--Marker--Marker--"} msg]} {
+ error "remote server disappeared: $msg"
+ }
+
+ while {1} {
+ set line [gets $commandSocket]
+ if {[eof $commandSocket]} {
+ error "remote server disappaered"
+ }
+ if {$line eq "--Marker--Marker--Marker--"} {
+ lassign $result code info value
+ return -code $code -errorinfo $info $value
+ }
+ append result $line "\n"
+ }
+ }
+}
+
+proc getPort sock {
+ lindex [fconfigure $sock -sockname] 2
+}
+
+
+# ----------------------------------------------------------------------
+
+test socket_$af-1.1 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -server
+} -returnCodes error -result {no argument given for -server option}
+test socket_$af-1.2 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -server foo
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
+test socket_$af-1.3 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -myaddr
+} -returnCodes error -result {no argument given for -myaddr option}
+test socket_$af-1.4 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -myaddr $localhost
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
+test socket_$af-1.5 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -myport
+} -returnCodes error -result {no argument given for -myport option}
+test socket_$af-1.6 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -myport xxxx
+} -returnCodes error -result {expected integer but got "xxxx"}
+test socket_$af-1.7 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -myport 2522
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
+test socket_$af-1.8 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -froboz
+} -returnCodes error -result {bad option "-froboz": must be -async, -myaddr, -myport, or -server}
+test socket_$af-1.9 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -server foo -myport 2521 3333
+} -returnCodes error -result {option -myport is not valid for servers}
+test socket_$af-1.10 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket host 2528 -junk
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
+test socket_$af-1.11 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -server callback 2520 --
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
+test socket_$af-1.12 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket foo badport
+} -returnCodes error -result {expected integer but got "badport"}
+test socket_$af-1.13 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -async -server
+} -returnCodes error -result {cannot set -async option for server sockets}
+test socket_$af-1.14 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+ socket -server foo -async
+} -returnCodes error -result {cannot set -async option for server sockets}
+
+set path(script) [makeFile {} script]
+
+test socket_$af-2.1 {tcp connection} -constraints [list socket supported_$af stdio] -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f {
+ set timer [after 10000 "set x timed_out"]
+ set f [socket -server accept 0]
+ proc accept {file addr port} {
+ global x
+ set x done
+ close $file
+ }
+ puts ready
+ puts [lindex [fconfigure $f -sockname] 2]
+ vwait x
+ after cancel $timer
+ close $f
+ puts $x
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f x
+ gets $f listen
+} -body {
+ # $x == "ready" at this point
+ set sock [socket $localhost $listen]
+ lappend x [gets $f]
+ close $sock
+ lappend x [gets $f]
+} -cleanup {
+ close $f
+} -result {ready done {}}
+test socket_$af-2.2 {tcp connection with client port specified} -setup {
+ set port [randport]
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f {
+ set timer [after 10000 "set x timeout"]
+ set f [socket -server accept 0]
+ proc accept {file addr port} {
+ global x
+ puts "[gets $file] $port"
+ close $file
+ set x done
+ }
+ puts ready
+ puts [lindex [fconfigure $f -sockname] 2]
+ vwait x
+ after cancel $timer
+ close $f
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f x
+ gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+ # $x == "ready" at this point
+ set sock [socket -myport $port $localhost $listen]
+ puts $sock hello
+ flush $sock
+ lappend x [expr {[gets $f] eq "hello $port"}]
+ close $sock
+ return $x
+} -cleanup {
+ catch {close [socket $localhost $listen]}
+ close $f
+} -result {ready 1}
+test socket_$af-2.3 {tcp connection with client interface specified} -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f {
+ set timer [after 2000 "set x done"]
+ set f [socket -server accept 0]
+ proc accept {file addr port} {
+ global x
+ puts "[gets $file] $addr"
+ close $file
+ set x done
+ }
+ puts [lindex [fconfigure $f -sockname] 2]
+ puts ready
+ vwait x
+ after cancel $timer
+ close $f
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f listen
+ gets $f x
+} -constraints [list socket supported_$af stdio] -body {
+ # $x == "ready" at this point
+ set sock [socket -myaddr $localhost $localhost $listen]
+ puts $sock hello
+ flush $sock
+ lappend x [gets $f]
+ close $sock
+ return $x
+} -cleanup {
+ close $f
+} -result [list ready [list hello $localhost]]
+test socket_$af-2.4 {tcp connection with server interface specified} -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f [list set localhost $localhost]
+ puts $f {
+ set timer [after 2000 "set x done"]
+ set f [socket -server accept -myaddr $localhost 0]
+ proc accept {file addr port} {
+ global x
+ puts "[gets $file]"
+ close $file
+ set x done
+ }
+ puts ready
+ puts [lindex [fconfigure $f -sockname] 2]
+ vwait x
+ after cancel $timer
+ close $f
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f x
+ gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+ # $x == "ready" at this point
+ set sock [socket $localhost $listen]
+ puts $sock hello
+ flush $sock
+ lappend x [gets $f]
+ close $sock
+ return $x
+} -cleanup {
+ close $f
+} -result {ready hello}
+test socket_$af-2.5 {tcp connection with redundant server port} -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f {
+ set timer [after 10000 "set x timeout"]
+ set f [socket -server accept 0]
+ proc accept {file addr port} {
+ global x
+ puts "[gets $file]"
+ close $file
+ set x done
+ }
+ puts ready
+ puts [lindex [fconfigure $f -sockname] 2]
+ vwait x
+ after cancel $timer
+ close $f
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f x
+ gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+ # $x == "ready" at this point
+ set sock [socket $localhost $listen]
+ puts $sock hello
+ flush $sock
+ lappend x [gets $f]
+ close $sock
+ return $x
+} -cleanup {
+ close $f
+} -result {ready hello}
+test socket_$af-2.6 {tcp connection} -constraints [list socket supported_$af] -body {
+ set status ok
+ if {![catch {set sock [socket $localhost [randport]]}]} {
+ if {![catch {gets $sock}]} {
+ set status broken
+ }
+ close $sock
+ }
+ set status
+} -result ok
+test socket_$af-2.7 {echo server, one line} -constraints [list socket supported_$af stdio] -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f {
+ set timer [after 10000 "set x timeout"]
+ set f [socket -server accept 0]
+ proc accept {s a p} {
+ fileevent $s readable [list echo $s]
+ fconfigure $s -translation lf -buffering line
+ }
+ proc echo {s} {
+ set l [gets $s]
+ if {[eof $s]} {
+ global x
+ close $s
+ set x done
+ } else {
+ puts $s $l
+ }
+ }
+ puts ready
+ puts [lindex [fconfigure $f -sockname] 2]
+ vwait x
+ after cancel $timer
+ close $f
+ puts $x
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f
+ gets $f listen
+} -body {
+ set s [socket $localhost $listen]
+ fconfigure $s -buffering line -translation lf
+ puts $s "hello abcdefghijklmnop"
+ set x [gets $s]
+ close $s
+ list $x [gets $f]
+} -cleanup {
+ close $f
+} -result {{hello abcdefghijklmnop} done}
+removeFile script
+test socket_$af-2.8 {echo server, loop 50 times, single connection} -setup {
+ set path(script) [makeFile {
+ set f [socket -server accept 0]
+ proc accept {s a p} {
+ fileevent $s readable [list echo $s]
+ fconfigure $s -buffering line
+ }
+ proc echo {s} {
+ global i
+ set l [gets $s]
+ if {[eof $s]} {
+ global x
+ close $s
+ set x done
+ } else {
+ incr i
+ puts $s $l
+ }
+ }
+ set i 0
+ puts ready
+ puts [lindex [fconfigure $f -sockname] 2]
+ set timer [after 20000 "set x done"]
+ vwait x
+ after cancel $timer
+ close $f
+ puts "done $i"
+ } script]
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f
+ gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+ set s [socket $localhost $listen]
+ fconfigure $s -buffering line
+ catch {
+ for {set x 0} {$x < 50} {incr x} {
+ puts $s "hello abcdefghijklmnop"
+ gets $s
+ }
+ }
+ close $s
+ catch {set x [gets $f]}
+ return $x
+} -cleanup {
+ close $f
+ removeFile script
+} -result {done 50}
+set path(script) [makeFile {} script]
+test socket_$af-2.9 {socket conflict} -constraints [list socket supported_$af stdio] -body {
+ set s [socket -server accept 0]
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f [list set ::tcl::unsupported::socketAF $::tcl::unsupported::socketAF]
+ puts $f "socket -server accept [lindex [fconfigure $s -sockname] 2]"
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f
+ after 100
+ close $f
+} -returnCodes error -cleanup {
+ close $s
+} -match glob -result {couldn't open socket: address already in use*}
+test socket_$af-2.10 {close on accept, accepted socket lives} -setup {
+ set done 0
+ set timer [after 20000 "set done timed_out"]
+} -constraints [list socket supported_$af] -body {
+ set ss [socket -server accept 0]
+ proc accept {s a p} {
+ global ss
+ close $ss
+ fileevent $s readable "readit $s"
+ fconfigure $s -trans lf
+ }
+ proc readit {s} {
+ global done
+ gets $s
+ close $s
+ set done 1
+ }
+ set cs [socket $localhost [lindex [fconfigure $ss -sockname] 2]]
+ puts $cs hello
+ close $cs
+ vwait done
+ return $done
+} -cleanup {
+ after cancel $timer
+} -result 1
+test socket_$af-2.11 {detecting new data} -constraints [list socket supported_$af] -setup {
+ proc accept {s a p} {
+ global sock
+ set sock $s
+ }
+ set s [socket -server accept 0]
+ set sock ""
+} -body {
+ set s2 [socket $localhost [lindex [fconfigure $s -sockname] 2]]
+ vwait sock
+ puts $s2 one
+ flush $s2
+ after idle {set x 1}
+ vwait x
+ fconfigure $sock -blocking 0
+ set result a:[gets $sock]
+ lappend result b:[gets $sock]
+ fconfigure $sock -blocking 1
+ puts $s2 two
+ flush $s2
+ after $latency {set x 1}; # NetBSD fails here if we do [after idle]
+ vwait x
+ fconfigure $sock -blocking 0
+ lappend result c:[gets $sock]
+} -cleanup {
+ fconfigure $sock -blocking 1
+ close $s2
+ close $s
+ close $sock
+} -result {a:one b: c:two}
+
+test socket_$af-3.1 {socket conflict} -constraints [list socket supported_$af stdio] -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f [list set localhost $localhost]
+ puts $f {
+ set f [socket -server accept -myaddr $localhost 0]
+ puts ready
+ puts [lindex [fconfigure $f -sockname] 2]
+ gets stdin
+ close $f
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r+]
+ gets $f
+ gets $f listen
+} -body {
+ socket -server accept -myaddr $localhost $listen
+} -cleanup {
+ puts $f bye
+ close $f
+} -returnCodes error -result {couldn't open socket: address already in use}
+test socket_$af-3.2 {server with several clients} -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f [list set localhost $localhost]
+ puts $f {
+ set t1 [after 30000 "set x timed_out"]
+ set t2 [after 31000 "set x timed_out"]
+ set t3 [after 32000 "set x timed_out"]
+ set counter 0
+ set s [socket -server accept -myaddr $localhost 0]
+ proc accept {s a p} {
+ fileevent $s readable [list echo $s]
+ fconfigure $s -buffering line
+ }
+ proc echo {s} {
+ global x
+ set l [gets $s]
+ if {[eof $s]} {
+ close $s
+ set x done
+ } else {
+ puts $s $l
+ }
+ }
+ puts ready
+ puts [lindex [fconfigure $s -sockname] 2]
+ vwait x
+ after cancel $t1
+ vwait x
+ after cancel $t2
+ vwait x
+ after cancel $t3
+ close $s
+ puts $x
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r+]
+ set x [gets $f]
+ gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+ # $x == "ready" here
+ set s1 [socket $localhost $listen]
+ fconfigure $s1 -buffering line
+ set s2 [socket $localhost $listen]
+ fconfigure $s2 -buffering line
+ set s3 [socket $localhost $listen]
+ fconfigure $s3 -buffering line
+ for {set i 0} {$i < 100} {incr i} {
+ puts $s1 hello,s1
+ gets $s1
+ puts $s2 hello,s2
+ gets $s2
+ puts $s3 hello,s3
+ gets $s3
+ }
+ close $s1
+ close $s2
+ close $s3
+ lappend x [gets $f]
+} -cleanup {
+ close $f
+} -result {ready done}
+
+test socket_$af-4.1 {server with several clients} -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f [list set localhost $localhost]
+ puts $f {
+ set port [gets stdin]
+ set s [socket $localhost $port]
+ fconfigure $s -buffering line
+ for {set i 0} {$i < 100} {incr i} {
+ puts $s hello
+ gets $s
+ }
+ close $s
+ puts bye
+ gets stdin
+ }
+ close $f
+ set p1 [open "|[list [interpreter] $path(script)]" r+]
+ fconfigure $p1 -buffering line
+ set p2 [open "|[list [interpreter] $path(script)]" r+]
+ fconfigure $p2 -buffering line
+ set p3 [open "|[list [interpreter] $path(script)]" r+]
+ fconfigure $p3 -buffering line
+} -constraints [list socket supported_$af stdio] -body {
+ proc accept {s a p} {
+ fconfigure $s -buffering line
+ fileevent $s readable [list echo $s]
+ }
+ proc echo {s} {
+ global x
+ set l [gets $s]
+ if {[eof $s]} {
+ close $s
+ set x done
+ } else {
+ puts $s $l
+ }
+ }
+ set t1 [after 30000 "set x timed_out"]
+ set t2 [after 31000 "set x timed_out"]
+ set t3 [after 32000 "set x timed_out"]
+ set s [socket -server accept -myaddr $localhost 0]
+ set listen [lindex [fconfigure $s -sockname] 2]
+ puts $p1 $listen
+ puts $p2 $listen
+ puts $p3 $listen
+ vwait x
+ vwait x
+ vwait x
+ after cancel $t1
+ after cancel $t2
+ after cancel $t3
+ close $s
+ set l ""
+ lappend l [list p1 [gets $p1] $x]
+ lappend l [list p2 [gets $p2] $x]
+ lappend l [list p3 [gets $p3] $x]
+} -cleanup {
+ puts $p1 bye
+ puts $p2 bye
+ puts $p3 bye
+ close $p1
+ close $p2
+ close $p3
+} -result {{p1 bye done} {p2 bye done} {p3 bye done}}
+test socket_$af-4.2 {byte order problems, socket numbers, htons} -body {
+ close [socket -server dodo -myaddr $localhost 0x3000]
+ return ok
+} -constraints [list socket supported_$af] -result ok
+
+test socket_$af-5.1 {byte order problems, socket numbers, htons} -body {
+ if {![catch {socket -server dodo 0x1} msg]} {
+ close $msg
+ return {htons problem, should be disallowed, are you running as SU?}
+ }
+ return {couldn't open socket: not owner}
+} -constraints [list socket supported_$af unix notRoot] -result {couldn't open socket: not owner}
+test socket_$af-5.2 {byte order problems, socket numbers, htons} -body {
+ if {![catch {socket -server dodo 0x10000} msg]} {
+ close $msg
+ return {port resolution problem, should be disallowed}
+ }
+ return {couldn't open socket: port number too high}
+} -constraints [list socket supported_$af] -result {couldn't open socket: port number too high}
+test socket_$af-5.3 {byte order problems, socket numbers, htons} -body {
+ if {![catch {socket -server dodo 21} msg]} {
+ close $msg
+ return {htons problem, should be disallowed, are you running as SU?}
+ }
+ return {couldn't open socket: not owner}
+} -constraints [list socket supported_$af unix notRoot] -result {couldn't open socket: not owner}
+
+test socket_$af-6.1 {accept callback error} -constraints [list socket supported_$af stdio] -setup {
+ proc myHandler {msg options} {
+ variable x $msg
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+ file delete $path(script)
+} -body {
+ set f [open $path(script) w]
+ puts $f [list set localhost $localhost]
+ puts $f {
+ gets stdin port
+ socket $localhost $port
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r+]
+ proc accept {s a p} {expr 10 / 0}
+ set s [socket -server accept -myaddr $localhost 0]
+ puts $f [lindex [fconfigure $s -sockname] 2]
+ close $f
+ set timer [after 10000 "set x timed_out"]
+ vwait x
+ after cancel $timer
+ close $s
+ return $x
+} -cleanup {
+ interp bgerror {} $handler
+} -result {divide by zero}
+
+test socket_$af-6.2 {
+ readable fileevent on server socket
+} -setup {
+ set sock [socket -server dummy 0]
+} -constraints [list socket supported_$af] -body {
+ fileevent $sock readable dummy
+} -cleanup {
+ close $sock
+} -returnCodes 1 -result "channel is not readable"
+
+test socket_$af-6.3 {writable fileevent on server socket} -setup {
+ set sock [socket -server dummy 0]
+} -constraints [list socket supported_$af] -body {
+ fileevent $sock writable dummy
+} -cleanup {
+ close $sock
+} -returnCodes 1 -result "channel is not writable"
+
+test socket_$af-7.1 {testing socket specific options} -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f {
+ set ss [socket -server accept 0]
+ proc accept args {
+ global x
+ set x done
+ }
+ puts ready
+ puts [lindex [fconfigure $ss -sockname] 2]
+ set timer [after 10000 "set x timed_out"]
+ vwait x
+ after cancel $timer
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f
+ gets $f listen
+ set l ""
+} -constraints [list socket supported_$af stdio] -body {
+ set s [socket $localhost $listen]
+ set p [fconfigure $s -peername]
+ close $s
+ lappend l [string compare [lindex $p 0] $localhost]
+ lappend l [string compare [lindex $p 2] $listen]
+ lappend l [llength $p]
+} -cleanup {
+ close $f
+} -result {0 0 3}
+test socket_$af-7.2 {testing socket specific options} -setup {
+ file delete $path(script)
+ set f [open $path(script) w]
+ puts $f [list set ::tcl::unsupported::socketAF $::tcl::unsupported::socketAF]
+ puts $f {
+ set ss [socket -server accept 0]
+ proc accept args {
+ global x
+ set x done
+ }
+ puts ready
+ puts [lindex [fconfigure $ss -sockname] 2]
+ set timer [after 10000 "set x timed_out"]
+ vwait x
+ after cancel $timer
+ }
+ close $f
+ set f [open "|[list [interpreter] $path(script)]" r]
+ gets $f
+ gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+ set s [socket $localhost $listen]
+ set p [fconfigure $s -sockname]
+ close $s
+ list [llength $p] \
+ [regexp {^(127\.0\.0\.1|0\.0\.0\.0|::1)$} [lindex $p 0]] \
+ [expr {[lindex $p 2] == $listen}]
+} -cleanup {
+ close $f
+} -result {3 1 0}
+test socket_$af-7.3 {testing socket specific options} -constraints [list socket supported_$af] -body {
+ set s [socket -server accept -myaddr $localhost 0]
+ set l [fconfigure $s]
+ close $s
+ update
+ llength $l
+} -result 14
+test socket_$af-7.4 {testing socket specific options} -constraints [list socket supported_$af] -setup {
+ set timer [after 10000 "set x timed_out"]
+ set l ""
+} -body {
+ set s [socket -server accept -myaddr $localhost 0]
+ proc accept {s a p} {
+ global x
+ set x [fconfigure $s -sockname]
+ close $s
+ }
+ set listen [lindex [fconfigure $s -sockname] 2]
+ set s1 [socket $localhost $listen]
+ vwait x
+ lappend l [expr {[lindex $x 2] == $listen}] [llength $x]
+} -cleanup {
+ after cancel $timer
+ close $s
+ close $s1
+} -result {1 3}
+test socket_$af-7.5 {testing socket specific options} -setup {
+ set timer [after 10000 "set x timed_out"]
+ set l ""
+} -constraints [list socket supported_$af unixOrPc] -body {
+ set s [socket -server accept 0]
+ proc accept {s a p} {
+ global x
+ set x [fconfigure $s -sockname]
+ close $s
+ }
+ set listen [lindex [fconfigure $s -sockname] 2]
+ set s1 [socket $localhost $listen]
+ vwait x
+ lappend l [lindex $x 0] [expr {[lindex $x 2] == $listen}] [llength $x]
+} -cleanup {
+ after cancel $timer
+ close $s
+ close $s1
+} -result [list $localhost 1 3]
+
+test socket_$af-8.1 {testing -async flag on sockets} -constraints [list socket supported_$af] -body {
+ # NOTE: This test may fail on some Solaris 2.4 systems. If it does, check
+ # that you have these patches installed (using showrev -p):
+ #
+ # 101907-05, 101925-02, 101945-14, 101959-03, 101969-05, 101973-03,
+ # 101977-03, 101981-02, 101985-01, 102001-03, 102003-01, 102007-01,
+ # 102011-02, 102024-01, 102039-01, 102044-01, 102048-01, 102062-03,
+ # 102066-04, 102070-01, 102105-01, 102153-03, 102216-01, 102232-01,
+ # 101878-03, 101879-01, 101880-03, 101933-01, 101950-01, 102030-01,
+ # 102057-08, 102140-01, 101920-02, 101921-09, 101922-07, 101923-03
+ #
+ # If after installing these patches you are still experiencing a problem,
+ # please email jyl@eng.sun.com. We have not observed this failure on
+ # Solaris 2.5, so another option (instead of installing these patches) is
+ # to upgrade to Solaris 2.5.
+ set s [socket -server accept -myaddr $localhost 0]
+ proc accept {s a p} {
+ global x
+ puts $s bye
+ close $s
+ set x done
+ }
+ set s1 [socket -async $localhost [lindex [fconfigure $s -sockname] 2]]
+ vwait x
+ gets $s1
+} -cleanup {
+ close $s
+ close $s1
+} -result bye
+
+test socket_$af-9.1 {testing spurious events} -constraints [list socket supported_$af] -setup {
+ set len 0
+ set spurious 0
+ set done 0
+ set timer [after 10000 "set done timed_out"]
+} -body {
+ proc readlittle {s} {
+ global spurious done len
+ set l [read $s 1]
+ if {[string length $l] == 0} {
+ if {![eof $s]} {
+ incr spurious
+ } else {
+ close $s
+ set done 1
+ }
+ } else {
+ incr len [string length $l]
+ }
+ }
+ proc accept {s a p} {
+ fconfigure $s -buffering none -blocking off
+ fileevent $s readable [list readlittle $s]
+ }
+ set s [socket -server accept -myaddr $localhost 0]
+ set c [socket $localhost [lindex [fconfigure $s -sockname] 2]]
+ puts -nonewline $c 01234567890123456789012345678901234567890123456789
+ close $c
+ vwait done
+ close $s
+ list $spurious $len
+} -cleanup {
+ after cancel $timer
+} -result {0 50}
+test socket_$af-9.2 {testing async write, fileevents, flush on close} -constraints [list socket supported_$af] -setup {
+ set firstblock ""
+ for {set i 0} {$i < 5} {incr i} {set firstblock "a$firstblock$firstblock"}
+ set secondblock ""
+ for {set i 0} {$i < 16} {incr i} {
+ set secondblock "b$secondblock$secondblock"
+ }
+ set timer [after 10000 "set done timed_out"]
+ set l [socket -server accept -myaddr $localhost 0]
+ proc accept {s a p} {
+ fconfigure $s -blocking 0 -translation lf -buffersize 16384 \
+ -buffering line
+ fileevent $s readable "readable $s"
+ }
+ proc readable {s} {
+ set l [gets $s]
+ fileevent $s readable {}
+ after idle respond $s
+ }
+ proc respond {s} {
+ global firstblock
+ puts -nonewline $s $firstblock
+ after idle writedata $s
+ }
+ proc writedata {s} {
+ global secondblock
+ puts -nonewline $s $secondblock
+ close $s
+ }
+} -body {
+ set s [socket $localhost [lindex [fconfigure $l -sockname] 2]]
+ fconfigure $s -blocking 0 -trans lf -buffering line
+ set count 0
+ puts $s hello
+ proc readit {s} {
+ global count done
+ set l [read $s]
+ incr count [string length $l]
+ if {[eof $s]} {
+ close $s
+ set done 1
+ }
+ }
+ fileevent $s readable "readit $s"
+ vwait done
+ return $count
+} -cleanup {
+ close $l
+ after cancel $timer
+} -result 65566
+test socket_$af-9.3 {testing EOF stickyness} -constraints [list socket supported_$af] -setup {
+ set count 0
+ set done false
+ proc write_then_close {s} {
+ puts $s bye
+ close $s
+ }
+ proc accept {s a p} {
+ fconfigure $s -buffering line -translation lf
+ fileevent $s writable "write_then_close $s"
+ }
+ set s [socket -server accept -myaddr $localhost 0]
+} -body {
+ proc count_to_eof {s} {
+ global count done
+ set l [gets $s]
+ if {[eof $s]} {
+ incr count
+ if {$count > 9} {
+ close $s
+ set done true
+ set count {eof is sticky}
+ }
+ }
+ }
+ proc timerproc {s} {
+ global done count
+ set done true
+ set count {timer went off, eof is not sticky}
+ close $s
+ }
+ set c [socket $localhost [lindex [fconfigure $s -sockname] 2]]
+ fconfigure $c -blocking off -buffering line -translation lf
+ fileevent $c readable "count_to_eof $c"
+ set timer [after 1000 timerproc $c]
+ vwait done
+ return $count
+} -cleanup {
+ close $s
+ after cancel $timer
+} -result {eof is sticky}
+
+removeFile script
+
+test socket_$af-10.1 {testing socket accept callback error handling} \
+ -constraints [list socket supported_$af] -setup {
+ variable goterror 0
+ proc myHandler {msg options} {
+ variable goterror 1
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+} -body {
+ set s [socket -server accept -myaddr $localhost 0]
+ proc accept {s a p} {close $s; error}
+ set c [socket $localhost [lindex [fconfigure $s -sockname] 2]]
+ vwait goterror
+ close $s
+ close $c
+ return $goterror
+} -cleanup {
+ interp bgerror {} $handler
+} -result 1
+
+test socket_$af-11.1 {tcp connection} -setup {
+ set port [sendCommand {
+ set server [socket -server accept 0]
+ proc accept {s a p} {
+ puts $s done
+ close $s
+ }
+ getPort $server
+ }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ set s [socket $remoteServerIP $port]
+ gets $s
+} -cleanup {
+ close $s
+ sendCommand {close $server}
+} -result done
+test socket_$af-11.2 {client specifies its port} -setup {
+ set lport [randport]
+ set rport [sendCommand {
+ set server [socket -server accept 0]
+ proc accept {s a p} {
+ puts $s $p
+ close $s
+ }
+ getPort $server
+ }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ set s [socket -myport $lport $remoteServerIP $rport]
+ set r [gets $s]
+ expr {$r==$lport ? "ok" : "broken: $r != $port"}
+} -cleanup {
+ close $s
+ sendCommand {close $server}
+} -result ok
+test socket_$af-11.3 {trying to connect, no server} -body {
+ set status ok
+ if {![catch {set s [socket $remoteServerIp [randport]]}]} {
+ if {![catch {gets $s}]} {
+ set status broken
+ }
+ close $s
+ }
+ return $status
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -result ok
+test socket_$af-11.4 {remote echo, one line} -setup {
+ set port [sendCommand {
+ set server [socket -server accept 0]
+ proc accept {s a p} {
+ fileevent $s readable [list echo $s]
+ fconfigure $s -buffering line -translation crlf
+ }
+ proc echo {s} {
+ set l [gets $s]
+ if {[eof $s]} {
+ close $s
+ } else {
+ puts $s $l
+ }
+ }
+ getPort $server
+ }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ set f [socket $remoteServerIP $port]
+ fconfigure $f -translation crlf -buffering line
+ puts $f hello
+ gets $f
+} -cleanup {
+ catch {close $f}
+ sendCommand {close $server}
+} -result hello
+test socket_$af-11.5 {remote echo, 50 lines} -setup {
+ set port [sendCommand {
+ set server [socket -server accept 0]
+ proc accept {s a p} {
+ fileevent $s readable [list echo $s]
+ fconfigure $s -buffering line -translation crlf
+ }
+ proc echo {s} {
+ set l [gets $s]
+ if {[eof $s]} {
+ close $s
+ } else {
+ puts $s $l
+ }
+ }
+ getPort $server
+ }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ set f [socket $remoteServerIP $port]
+ fconfigure $f -translation crlf -buffering line
+ for {set cnt 0} {$cnt < 50} {incr cnt} {
+ puts $f "hello, $cnt"
+ if {[gets $f] != "hello, $cnt"} {
+ break
+ }
+ }
+ return $cnt
+} -cleanup {
+ close $f
+ sendCommand {close $server}
+} -result 50
+test socket_$af-11.6 {socket conflict} -setup {
+ set s1 [socket -server accept -myaddr $localhost 0]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ set s2 [socket -server accept -myaddr $localhost [getPort $s1]]
+ list [getPort $s2] [close $s2]
+} -cleanup {
+ close $s1
+} -returnCodes error -result {couldn't open socket: address already in use}
+test socket_$af-11.7 {server with several clients} -setup {
+ set port [sendCommand {
+ set server [socket -server accept 0]
+ proc accept {s a p} {
+ fconfigure $s -buffering line
+ fileevent $s readable [list echo $s]
+ }
+ proc echo {s} {
+ set l [gets $s]
+ if {[eof $s]} {
+ close $s
+ } else {
+ puts $s $l
+ }
+ }
+ getPort $server
+ }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ set s1 [socket $remoteServerIP $port]
+ fconfigure $s1 -buffering line
+ set s2 [socket $remoteServerIP $port]
+ fconfigure $s2 -buffering line
+ set s3 [socket $remoteServerIP $port]
+ fconfigure $s3 -buffering line
+ for {set i 0} {$i < 100} {incr i} {
+ puts $s1 hello,s1
+ gets $s1
+ puts $s2 hello,s2
+ gets $s2
+ puts $s3 hello,s3
+ gets $s3
+ }
+ return $i
+} -cleanup {
+ close $s1
+ close $s2
+ close $s3
+ sendCommand {close $server}
+} -result 100
+test socket_$af-11.8 {client with several servers} -setup {
+ lassign [sendCommand {
+ set s1 [socket -server "accept server1" 0]
+ set s2 [socket -server "accept server2" 0]
+ set s3 [socket -server "accept server3" 0]
+ proc accept {mp s a p} {
+ puts $s $mp
+ close $s
+ }
+ list [getPort $s1] [getPort $s2] [getPort $s3]
+ }] p1 p2 p3
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ set s1 [socket $remoteServerIP $p1]
+ set s2 [socket $remoteServerIP $p2]
+ set s3 [socket $remoteServerIP $p3]
+ list [gets $s1] [gets $s1] [eof $s1] [gets $s2] [gets $s2] [eof $s2] \
+ [gets $s3] [gets $s3] [eof $s3]
+} -cleanup {
+ close $s1
+ close $s2
+ close $s3
+ sendCommand {
+ close $s1
+ close $s2
+ close $s3
+ }
+} -result {server1 {} 1 server2 {} 1 server3 {} 1}
+test socket_$af-11.9 {accept callback error} -constraints [list socket supported_$af doTestsWithRemoteServer] -setup {
+ proc myHandler {msg options} {
+ variable x $msg
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+ set timer [after 10000 "set x timed_out"]
+} -body {
+ set s [socket -server accept 0]
+ proc accept {s a p} {expr {10 / 0}}
+ sendCommand "set port [getPort $s]"
+ if {[catch {
+ sendCommand {
+ set peername [fconfigure $callerSocket -peername]
+ set s [socket [lindex $peername 0] $port]
+ close $s
+ }
+ } msg]} then {
+ close $s
+ error $msg
+ }
+ vwait x
+ return $x
+} -cleanup {
+ close $s
+ after cancel $timer
+ interp bgerror {} $handler
+} -result {divide by zero}
+test socket_$af-11.10 {testing socket specific options} -setup {
+ set port [sendCommand {
+ set server [socket -server accept 0]
+ proc accept {s a p} {close $s}
+ getPort $server
+ }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ set s [socket $remoteServerIP $port]
+ set p [fconfigure $s -peername]
+ set n [fconfigure $s -sockname]
+ list [expr {[lindex $p 2] == $port}] [llength $p] [llength $n]
+} -cleanup {
+ close $s
+ sendCommand {close $server}
+} -result {1 3 3}
+test socket_$af-11.11 {testing spurious events} -setup {
+ set port [sendCommand {
+ set server [socket -server accept 0]
+ proc accept {s a p} {
+ fconfigure $s -translation "auto lf"
+ after idle writesome $s
+ }
+ proc writesome {s} {
+ for {set i 0} {$i < 100} {incr i} {
+ puts $s "line $i from remote server"
+ }
+ close $s
+ }
+ getPort $server
+ }]
+ set len 0
+ set spurious 0
+ set done 0
+ set timer [after 40000 "set done timed_out"]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ proc readlittle {s} {
+ global spurious done len
+ set l [read $s 1]
+ if {[string length $l] == 0} {
+ if {![eof $s]} {
+ incr spurious
+ } else {
+ close $s
+ set done 1
+ }
+ } else {
+ incr len [string length $l]
+ }
+ }
+ set c [socket $remoteServerIP $port]
+ fileevent $c readable "readlittle $c"
+ vwait done
+ list $spurious $len $done
+} -cleanup {
+ after cancel $timer
+ sendCommand {close $server}
+} -result {0 2690 1}
+test socket_$af-11.12 {testing EOF stickyness} -constraints [list socket supported_$af doTestsWithRemoteServer] -setup {
+ set counter 0
+ set done 0
+ set port [sendCommand {
+ set server [socket -server accept 0]
+ proc accept {s a p} {
+ after idle close $s
+ }
+ getPort $server
+ }]
+ proc timed_out {} {
+ global c done
+ set done {timed_out, EOF is not sticky}
+ close $c
+ }
+ set after_id [after 1000 timed_out]
+} -body {
+ proc count_up {s} {
+ global counter done
+ set l [gets $s]
+ if {[eof $s]} {
+ incr counter
+ if {$counter > 9} {
+ set done {EOF is sticky}
+ close $s
+ }
+ }
+ }
+ set c [socket $remoteServerIP $port]
+ fileevent $c readable [list count_up $c]
+ vwait done
+ return $done
+} -cleanup {
+ after cancel $after_id
+ sendCommand {close $server}
+} -result {EOF is sticky}
+test socket_$af-11.13 {testing async write, async flush, async close} -setup {
+ set port [sendCommand {
+ set firstblock ""
+ for {set i 0} {$i < 5} {incr i} {
+ set firstblock "a$firstblock$firstblock"
+ }
+ set secondblock ""
+ for {set i 0} {$i < 16} {incr i} {
+ set secondblock "b$secondblock$secondblock"
+ }
+ set l [socket -server accept 0]
+ proc accept {s a p} {
+ fconfigure $s -blocking 0 -translation lf -buffersize 16384 \
+ -buffering line
+ fileevent $s readable "readable $s"
+ }
+ proc readable {s} {
+ set l [gets $s]
+ fileevent $s readable {}
+ after idle respond $s
+ }
+ proc respond {s} {
+ global firstblock
+ puts -nonewline $s $firstblock
+ after idle writedata $s
+ }
+ proc writedata {s} {
+ global secondblock
+ puts -nonewline $s $secondblock
+ close $s
+ }
+ getPort $l
+ }]
+ set timer [after 10000 "set done timed_out"]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+ proc readit {s} {
+ global count done
+ set l [read $s]
+ incr count [string length $l]
+ if {[eof $s]} {
+ close $s
+ set done 1
+ }
+ }
+ set s [socket $remoteServerIP $port]
+ fconfigure $s -blocking 0 -trans lf -buffering line
+ set count 0
+ puts $s hello
+ fileevent $s readable "readit $s"
+ vwait done
+ return $count
+} -cleanup {
+ after cancel $timer
+ sendCommand {close $l}
+} -result 65566
+
+set path(script1) [makeFile {} script1]
+set path(script2) [makeFile {} script2]
+
+test socket_$af-12.1 {testing inheritance of server sockets} -setup {
+ file delete $path(script1)
+ file delete $path(script2)
+ # Script1 is just a 10 second delay. If the server socket is inherited, it
+ # will be held open for 10 seconds
+ set f [open $path(script1) w]
+ puts $f {
+ fileevent stdin readable exit
+ after 10000 exit
+ vwait forever
+ }
+ close $f
+ # Script2 creates the server socket, launches script1, and exits.
+ # The server socket will now be closed unless script1 inherited it.
+ set f [open $path(script2) w]
+ puts $f [list set tcltest [interpreter]]
+ puts $f [list set delay $path(script1)]
+ puts $f [list set localhost $localhost]
+ puts $f {
+ set f [socket -server accept -myaddr $localhost 0]
+ proc accept { file addr port } {
+ close $file
+ }
+ exec $tcltest $delay &
+ puts [lindex [fconfigure $f -sockname] 2]
+ close $f
+ exit
+ }
+ close $f
+} -constraints [list socket supported_$af stdio exec] -body {
+ # Launch script2 and wait 5 seconds
+ ### exec [interpreter] script2 &
+ set p [open "|[list [interpreter] $path(script2)]" r]
+ # If we can still connect to the server, the socket got inherited.
+ if {[catch {close [socket $localhost $listen]}]} {
+ return {server socket was not inherited}
+ } else {
+ return {server socket was inherited}
+ }
+} -cleanup {
+ catch {close $p}
+} -result {server socket was not inherited}
+test socket_$af-12.2 {testing inheritance of client sockets} -setup {
+ file delete $path(script1)
+ file delete $path(script2)
+ # Script1 is just a 20 second delay. If the server socket is inherited, it
+ # will be held open for 20 seconds
+ set f [open $path(script1) w]
+ puts $f {
+ fileevent stdin readable exit
+ after 20000 exit
+ vwait forever
+ }
+ close $f
+ # Script2 opens the client socket and writes to it. It then launches
+ # script1 and exits. If the child process inherited the client socket, the
+ # socket will still be open.
+ set f [open $path(script2) w]
+ puts $f [list set tcltest [interpreter]]
+ puts $f [list set delay $path(script1)]
+ puts $f [list set localhost $localhost]
+ puts $f {
+ gets stdin port
+ set f [socket $localhost $port]
+ exec $tcltest $delay &
+ puts $f testing
+ flush $f
+ exit
+ }
+ close $f
+ # If the socket doesn't hit end-of-file in 10 seconds, the script1 process
+ # must have inherited the client.
+ set failed 0
+ set after [after 10000 [list set failed 1]]
+} -constraints [list socket supported_$af stdio exec] -body {
+ # Create the server socket
+ set server [socket -server accept -myaddr $localhost 0]
+ proc accept { file host port } {
+ # When the client connects, establish the read handler
+ global server
+ close $server
+ fileevent $file readable [list getdata $file]
+ fconfigure $file -buffering line -blocking 0
+ }
+ proc getdata { file } {
+ # Read handler on the accepted socket.
+ global x failed
+ set status [catch {read $file} data]
+ if {$status != 0} {
+ set x {read failed, error was $data}
+ catch { close $file }
+ } elseif {$data ne ""} {
+ } elseif {[fblocked $file]} {
+ } elseif {[eof $file]} {
+ if {$failed} {
+ set x {client socket was inherited}
+ } else {
+ set x {client socket was not inherited}
+ }
+ catch { close $file }
+ } else {
+ set x {impossible case}
+ catch { close $file }
+ }
+ }
+ # Launch the script2 process
+ ### exec [interpreter] script2 &
+ set p [open "|[list [interpreter] $path(script2)]" w]
+ puts $p [lindex [fconfigure $server -sockname] 2] ; flush $p
+ vwait x
+ return $x
+} -cleanup {
+ after cancel $after
+ close $p
+} -result {client socket was not inherited}
+test socket_$af-12.3 {testing inheritance of accepted sockets} -setup {
+ file delete $path(script1)
+ file delete $path(script2)
+ set f [open $path(script1) w]
+ puts $f {
+ fileevent stdin readable exit
+ after 10000 exit
+ vwait forever
+ }
+ close $f
+ set f [open $path(script2) w]
+ puts $f [list set tcltest [interpreter]]
+ puts $f [list set delay $path(script1)]
+ puts $f [list set localhost $localhost]
+ puts $f {
+ set server [socket -server accept -myaddr $localhost 0]
+ proc accept { file host port } {
+ global tcltest delay
+ puts $file {test data on socket}
+ exec $tcltest $delay &
+ after idle exit
+ }
+ puts stdout [lindex [fconfigure $server -sockname] 2]
+ vwait forever
+ }
+ close $f
+} -constraints [list socket supported_$af stdio exec] -body {
+ # Launch the script2 process and connect to it. See how long the socket
+ # stays open
+ ## exec [interpreter] script2 &
+ set p [open "|[list [interpreter] $path(script2)]" r]
+ gets $p listen
+ set f [socket $localhost $listen]
+ fconfigure $f -buffering full -blocking 0
+ fileevent $f readable [list getdata $f]
+ # If the socket is still open after 5 seconds, the script1 process must
+ # have inherited the accepted socket.
+ set failed 0
+ set after [after 5000 [list set failed 1]]
+ proc getdata { file } {
+ # Read handler on the client socket.
+ global x
+ global failed
+ set status [catch {read $file} data]
+ if {$status != 0} {
+ set x {read failed, error was $data}
+ catch { close $file }
+ } elseif {[string compare {} $data]} {
+ } elseif {[fblocked $file]} {
+ } elseif {[eof $file]} {
+ if {$failed} {
+ set x {accepted socket was inherited}
+ } else {
+ set x {accepted socket was not inherited}
+ }
+ catch { close $file }
+ } else {
+ set x {impossible case}
+ catch { close $file }
+ }
+ return
+ }
+ vwait x
+ return $x
+} -cleanup {
+ after cancel $after
+ catch {close $p}
+} -result {accepted socket was not inherited}
+
+test socket_$af-13.1 {Testing use of shared socket between two threads} -body {
+ # create a thread
+ set serverthread [thread::create -preserved [string map [list @localhost@ $localhost] {
+ set f [socket -server accept -myaddr @localhost@ 0]
+ set listen [lindex [fconfigure $f -sockname] 2]
+ proc accept {s a p} {
+ fileevent $s readable [list echo $s]
+ fconfigure $s -buffering line
+ }
+ proc echo {s} {
+ global i
+ set l [gets $s]
+ if {[eof $s]} {
+ global x
+ close $s
+ set x done
+ } else {
+ incr i
+ puts $s $l
+ }
+ }
+ set i 0
+ vwait x
+ close $f
+ thread::wait
+ }]]
+ set port [thread::send $serverthread {set listen}]
+ set s [socket $localhost $port]
+ fconfigure $s -buffering line
+ catch {
+ puts $s "hello"
+ gets $s result
+ }
+ close $s
+ thread::release $serverthread
+ append result " " [llength [thread::names]]
+} -result {hello 1} -constraints [list socket supported_$af thread]
+
+# ----------------------------------------------------------------------
+
+removeFile script1
+removeFile script2
+
+# cleanup
+if {$remoteProcChan ne ""} {
+ catch {sendCommand exit}
+}
+catch {close $commandSocket}
+catch {close $remoteProcChan}
+}
+unset ::tcl::unsupported::socketAF
+test socket-14.0 {[socket -async] when server only listens on IPv4} \
+ -constraints [list socket supported_any localhost_v4] \
+ -setup {
+ proc accept {s a p} {
+ global x
+ puts $s bye
+ close $s
+ set x ok
+ }
+ set server [socket -server accept -myaddr 127.0.0.1 0]
+ set port [lindex [fconfigure $server -sockname] 2]
+ } -body {
+ set client [socket -async localhost $port]
+ set after [after 1000 {set x [fconfigure $client -error]}]
+ vwait x
+ set x
+ } -cleanup {
+ after cancel $after
+ close $server
+ close $client
+ unset x
+ } -result ok
+test socket-14.1 {[socket -async] fileevent while still connecting} \
+ -constraints [list socket supported_any] \
+ -setup {
+ proc accept {s a p} {
+ global x
+ puts $s bye
+ close $s
+ lappend x ok
+ }
+ set server [socket -server accept -myaddr localhost 0]
+ set port [lindex [fconfigure $server -sockname] 2]
+ set x ""
+ } -body {
+ set client [socket -async localhost $port]
+ fileevent $client writable {
+ lappend x [fconfigure $client -error]
+ fileevent $client writable {}
+ }
+ set after [after 1000 {lappend x timeout}]
+ while {[llength $x] < 2 && "timeout" ni $x} {
+ vwait x
+ }
+ lsort $x; # we only want to see both events, the order doesn't matter
+ } -cleanup {
+ after cancel $after
+ close $server
+ close $client
+ unset x
+ } -result {{} ok}
+test socket-14.2 {[socket -async] fileevent connection refused} \
+ -constraints [list socket supported_any] \
+ -body {
+ if {[catch {socket -async localhost [randport]} client]} {
+ regexp {[^:]*: (.*)} $client -> x
+ } else {
+ fileevent $client writable {set x [fconfigure $client -error]}
+ set after [after 1000 {set x timeout}]
+ vwait x
+ after cancel $after
+ if {$x eq "timeout"} {
+ append x ": [fconfigure $client -error]"
+ }
+ close $client
+ }
+ set x
+ } -cleanup {
+ unset x
+ } -result "connection refused"
+test socket-14.3 {[socket -async] when server only listens on IPv6} \
+ -constraints [list socket supported_any localhost_v6] \
+ -setup {
+ proc accept {s a p} {
+ global x
+ puts $s bye
+ close $s
+ set x ok
+ }
+ set server [socket -server accept -myaddr ::1 0]
+ set port [lindex [fconfigure $server -sockname] 2]
+ } -body {
+ set client [socket -async localhost $port]
+ set after [after 1000 {set x [fconfigure $client -error]}]
+ vwait x
+ set x
+ } -cleanup {
+ after cancel $after
+ close $server
+ close $client
+ unset x
+ } -result ok
+test socket-14.4 {[socket -async] and both, readdable and writable fileevents} \
+ -constraints [list socket supported_any] \
+ -setup {
+ proc accept {s a p} {
+ puts $s bye
+ close $s
+ }
+ set server [socket -server accept -myaddr localhost 0]
+ set port [lindex [fconfigure $server -sockname] 2]
+ set x ""
+ } -body {
+ set client [socket -async localhost $port]
+ fileevent $client writable {
+ lappend x [fconfigure $client -error]
+ fileevent $client writable {}
+ }
+ fileevent $client readable {lappend x [gets $client]}
+ set after [after 1000 {lappend x timeout}]
+ while {[llength $x] < 2 && "timeout" ni $x} {
+ vwait x
+ }
+ lsort $x
+ } -cleanup {
+ after cancel $after
+ close $client
+ close $server
+ } -result {{} bye}
+test socket-14.5 {[socket -async] which fails before any connect() can be made} \
+ -constraints [list socket supported_any] \
+ -body {
+ # address from rfc5737
+ socket -async -myaddr 192.0.2.42 127.0.0.1 [randport]
+ } \
+ -returnCodes 1 \
+ -result {couldn't open socket: cannot assign requested address}
+::tcltest::cleanupTests
+flush stdout
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/source.test b/pkgs/msgcat/tests/source.test
new file mode 100644
index 0000000..d71212d
--- /dev/null
+++ b/pkgs/msgcat/tests/source.test
@@ -0,0 +1,302 @@
+# Commands covered: source
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 by Scriptics Corporation.
+# 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.
+
+if {[catch {package require tcltest 2.1}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2.1 required."
+ return
+}
+
+namespace eval ::tcl::test::source {
+ namespace import ::tcltest::*
+
+test source-1.1 {source command} -setup {
+ set x "old x value"
+ set y "old y value"
+ set z "old z value"
+ set sourcefile [makeFile {
+ set x 22
+ set y 33
+ set z 44
+ } source.file]
+} -body {
+ source $sourcefile
+ list $x $y $z
+} -cleanup {
+ removeFile source.file
+} -result {22 33 44}
+test source-1.2 {source command} -setup {
+ set sourcefile [makeFile {list result} source.file]
+} -body {
+ source $sourcefile
+} -cleanup {
+ removeFile source.file
+} -result result
+test source-1.3 {source command} -setup {
+ set sourcefile [makeFile {} source.file]
+ set fd [open $sourcefile w]
+ fconfigure $fd -translation lf
+ puts $fd "list a b c \\"
+ puts $fd "d e f"
+ close $fd
+} -body {
+ source $sourcefile
+} -cleanup {
+ removeFile source.file
+} -result {a b c d e f}
+
+proc ListGlobMatch {expected actual} {
+ if {[llength $expected] != [llength $actual]} {
+ return 0
+ }
+ foreach e $expected a $actual {
+ if {![string match $e $a]} {
+ return 0
+ }
+ }
+ return 1
+}
+customMatch listGlob [namespace which ListGlobMatch]
+
+test source-2.3 {source error conditions} -setup {
+ set sourcefile [makeFile {
+ set x 146
+ error "error in sourced file"
+ set y $x
+ } source.file]
+} -body {
+ list [catch {source $sourcefile} msg] $msg $::errorInfo
+} -cleanup {
+ removeFile source.file
+} -match listGlob -result [list 1 {error in sourced file} \
+ {error in sourced file
+ while executing
+"error "error in sourced file""
+ (file "*source.file" line 3)
+ invoked from within
+"source $sourcefile"}]
+test source-2.4 {source error conditions} -setup {
+ set sourcefile [makeFile {break} source.file]
+} -body {
+ source $sourcefile
+} -cleanup {
+ removeFile source.file
+} -returnCodes break
+test source-2.5 {source error conditions} -setup {
+ set sourcefile [makeFile {continue} source.file]
+} -body {
+ source $sourcefile
+} -cleanup {
+ removeFile source.file
+} -returnCodes continue
+test source-2.6 {source error conditions} -setup {
+ set sourcefile [makeFile {} _non_existent_]
+ removeFile _non_existent_
+} -body {
+ list [catch {source $sourcefile} msg] $msg $::errorCode
+} -match listGlob -result [list 1 \
+ {couldn't read file "*_non_existent_": no such file or directory} \
+ {POSIX ENOENT {no such file or directory}}]
+test source-2.7 {utf-8 with BOM} -setup {
+ set sourcefile [makeFile {} source.file]
+} -body {
+ set out [open $sourcefile w]
+ fconfigure $out -encoding utf-8
+ puts $out "\ufeffset y new-y"
+ close $out
+ set y old-y
+ source -encoding utf-8 $sourcefile
+ return $y
+} -cleanup {
+ removeFile $sourcefile
+} -result {new-y}
+
+test source-3.1 {return in middle of source file} -setup {
+ set sourcefile [makeFile {
+ set x new-x
+ return allDone
+ set y new-y
+ } source.file]
+} -body {
+ set x old-x
+ set y old-y
+ set z [source $sourcefile]
+ list $x $y $z
+} -cleanup {
+ removeFile source.file
+} -result {new-x old-y allDone}
+test source-3.2 {return with special code etc.} -setup {
+ set sourcefile [makeFile {
+ set x new-x
+ return -code break "Silly result"
+ set y new-y
+ } source.file]
+} -body {
+ source $sourcefile
+} -cleanup {
+ removeFile source.file
+} -returnCodes break -result {Silly result}
+test source-3.3 {return with special code etc.} -setup {
+ set sourcefile [makeFile {
+ set x new-x
+ return -code error "Simulated error"
+ set y new-y
+ } source.file]
+} -body {
+ list [catch {source $sourcefile} msg] $msg $::errorInfo $::errorCode
+} -cleanup {
+ removeFile source.file
+} -result {1 {Simulated error} {Simulated error
+ while executing
+"source $sourcefile"} NONE}
+test source-3.4 {return with special code etc.} -setup {
+ set sourcefile [makeFile {
+ set x new-x
+ return -code error -errorinfo "Simulated errorInfo stuff"
+ set y new-y
+ } source.file]
+} -body {
+ list [catch {source $sourcefile} msg] $msg $::errorInfo $::errorCode
+} -cleanup {
+ removeFile source.file
+} -result {1 {} {Simulated errorInfo stuff
+ invoked from within
+"source $sourcefile"} NONE}
+test source-3.5 {return with special code etc.} -setup {
+ set sourcefile [makeFile {
+ set x new-x
+ return -code error -errorinfo "Simulated errorInfo stuff" \
+ -errorcode {a b c}
+ set y new-y
+ } source.file]
+} -body {
+ list [catch {source $sourcefile} msg] $msg $::errorInfo $::errorCode
+} -cleanup {
+ removeFile source.file
+} -result {1 {} {Simulated errorInfo stuff
+ invoked from within
+"source $sourcefile"} {a b c}}
+
+test source-6.1 {source is binary ok} -setup {
+ # Note [makeFile] writes in the system encoding.
+ # [source] defaults to reading in the system encoding.
+ set sourcefile [makeFile [list set x "a b\0c"] source.file]
+} -body {
+ set x {}
+ source $sourcefile
+ string length $x
+} -cleanup {
+ removeFile source.file
+} -result 5
+test source-6.2 {source skips everything after Ctrl-Z: Bug 2040} -setup {
+ set sourcefile [makeFile "set x ab\32c" source.file]
+} -body {
+ set x {}
+ source $sourcefile
+ string length $x
+} -cleanup {
+ removeFile source.file
+} -result 2
+
+test source-7.1 {source -encoding test} -setup {
+ set sourcefile [makeFile {} source.file]
+ file delete $sourcefile
+ set f [open $sourcefile w]
+ fconfigure $f -encoding utf-8
+ puts $f "set symbol(square-root) \u221A; set x correct"
+ close $f
+} -body {
+ set x unset
+ source -encoding utf-8 $sourcefile
+ set x
+} -cleanup {
+ removeFile source.file
+} -result correct
+test source-7.2 {source -encoding test} -setup {
+ # This tests for bad interactions between [source -encoding]
+ # and use of the Control-Z character (\u001A) as a cross-platform
+ # EOF character by [source]. Here we write out and the [source] a
+ # file that contains the byte \x1A, although not the character \u001A in
+ # the indicated encoding.
+ set sourcefile [makeFile {} source.file]
+ file delete $sourcefile
+ set f [open $sourcefile w]
+ fconfigure $f -encoding unicode
+ puts $f "set symbol(square-root) \u221A; set x correct"
+ close $f
+} -body {
+ set x unset
+ source -encoding unicode $sourcefile
+ set x
+} -cleanup {
+ removeFile source.file
+} -result correct
+test source-7.3 {source -encoding: syntax} -body {
+ # Have to spell out the -encoding option
+ source -e utf-8 no_file
+} -returnCodes 1 -match glob -result {bad option*}
+test source-7.4 {source -encoding: syntax} -setup {
+ set sourcefile [makeFile {} source.file]
+} -body {
+ source -encoding no-such-encoding $sourcefile
+} -cleanup {
+ removeFile source.file
+} -returnCodes 1 -match glob -result {unknown encoding*}
+test source-7.5 {source -encoding: correct operation} -setup {
+ set sourcefile [makeFile {} source.file]
+ file delete $sourcefile
+ set f [open $sourcefile w]
+ fconfigure $f -encoding utf-8
+ puts $f "proc \u20ac {} {return foo}"
+ close $f
+} -body {
+ source -encoding utf-8 $sourcefile
+ \u20ac
+} -cleanup {
+ removeFile source.file
+ rename \u20ac {}
+} -result foo
+test source-7.6 {source -encoding: mismatch encoding error} -setup {
+ set sourcefile [makeFile {} source.file]
+ file delete $sourcefile
+ set f [open $sourcefile w]
+ fconfigure $f -encoding utf-8
+ puts $f "proc \u20ac {} {return foo}"
+ close $f
+} -body {
+ source -encoding ascii $sourcefile
+ \u20ac
+} -cleanup {
+ removeFile source.file
+} -returnCodes error -match glob -result {invalid command name*}
+
+test source-8.1 {source and coroutine/yield} -setup {
+ set sourcefile [makeFile {} source.file]
+ file delete $sourcefile
+} -body {
+ makeFile {yield 1; yield 2; return 3;} $sourcefile
+ coroutine coro apply {f {yield;source $f}} $sourcefile
+ list [coro] [coro] [coro] [info exist coro]
+} -cleanup {
+ catch {rename coro {}}
+ removeFile source.file
+} -result {1 2 3 0}
+
+cleanupTests
+}
+namespace delete ::tcl::test::source
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/split.test b/pkgs/msgcat/tests/split.test
new file mode 100644
index 0000000..778131f
--- /dev/null
+++ b/pkgs/msgcat/tests/split.test
@@ -0,0 +1,88 @@
+# Commands covered: split
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test split-1.1 {basic split commands} {
+ split "a\n b\t\r c\n "
+} {a {} b {} {} c {} {}}
+test split-1.2 {basic split commands} {
+ split "word 1xyzword 2zword 3" xyz
+} {{word 1} {} {} {word 2} {word 3}}
+test split-1.3 {basic split commands} {
+ split "12345" {}
+} {1 2 3 4 5}
+test split-1.4 {basic split commands} {
+ split "a\}b\[c\{\]\$"
+} "a\\}b\\\[c\\{\\\]\\\$"
+test split-1.5 {basic split commands} {
+ split {} {}
+} {}
+test split-1.6 {basic split commands} {
+ split {}
+} {}
+test split-1.7 {basic split commands} {
+ split { }
+} {{} {} {} {}}
+test split-1.8 {basic split commands} {
+ proc foo {} {
+ set x {}
+ foreach f [split {]\n} {}] {
+ append x $f
+ }
+ return $x
+ }
+ foo
+} {]\n}
+test split-1.9 {basic split commands} {
+ proc foo {} {
+ set x ab\000c
+ set y [split $x {}]
+ return $y
+ }
+ foo
+} "a b \000 c"
+test split-1.10 {basic split commands} {
+ split "a0ab1b2bbb3\000c4" ab\000c
+} {{} 0 {} 1 2 {} {} 3 {} 4}
+test split-1.11 {basic split commands} {
+ split "12,3,45" {,}
+} {12 3 45}
+test split-1.12 {basic split commands} {
+ split "\u0001ab\u0001cd\u0001\u0001ef\u0001" \1
+} {{} ab cd {} ef {}}
+test split-1.13 {basic split commands} {
+ split "12,34,56," {,}
+} {12 34 56 {}}
+test split-1.14 {basic split commands} {
+ split ",12,,,34,56," {,}
+} {{} 12 {} {} 34 56 {}}
+
+test split-2.1 {split errors} {
+ list [catch split msg] $msg $errorCode
+} {1 {wrong # args: should be "split string ?splitChars?"} {TCL WRONGARGS}}
+test split-2.2 {split errors} {
+ list [catch {split a b c} msg] $msg $errorCode
+} {1 {wrong # args: should be "split string ?splitChars?"} {TCL WRONGARGS}}
+
+# cleanup
+catch {rename foo {}}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/stack.test b/pkgs/msgcat/tests/stack.test
new file mode 100644
index 0000000..873cb08
--- /dev/null
+++ b/pkgs/msgcat/tests/stack.test
@@ -0,0 +1,64 @@
+# Tests that the stack size is big enough for the application.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1998-2000 Ajuba Solutions.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Note that a failure in this test may result in a crash of the executable.
+
+test stack-1.1 {maxNestingDepth reached on infinite recursion} -body {
+ # do this in a sub process in case it segfaults
+ exec [interpreter] << {
+ proc recurse {} { recurse }
+ catch { recurse } rv
+ puts $rv
+ }
+} -result {too many nested evaluations (infinite loop?)}
+
+test stack-2.1 {maxNestingDepth reached on infinite recursion} -body {
+ # do this in a sub process in case it segfaults
+ exec [interpreter] << {
+ interp alias {} unknown {} notaknownproc
+ catch { unknown } msg
+ puts $msg
+ }
+} -result {too many nested evaluations (infinite loop?)}
+
+# Make sure that there is enough stack to run regexp even if we're
+# close to the recursion limit. [Bug 947070] [Patch 746378]
+test stack-3.1 {enough room for regexp near recursion limit} -body {
+ # do this in a sub process in case it segfaults
+ exec [interpreter] << {
+ interp recursionlimit {} 10000
+ set depth 0
+ proc a { max } {
+ if { [info level] < $max } {
+ set ::depth [info level]
+ a $max
+ } else {
+ regexp {^ ?} x
+ }
+ }
+ catch { a 10001 }
+ set depth2 $depth
+ puts [list [a $depth] [expr { $depth2 - $depth }]]
+ }
+} -result {1 1}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/string.test b/pkgs/msgcat/tests/string.test
new file mode 100644
index 0000000..b3326ae
--- /dev/null
+++ b/pkgs/msgcat/tests/string.test
@@ -0,0 +1,1966 @@
+# Commands covered: string
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2001 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# Some tests require the testobj command
+
+testConstraint testobj [expr {[info commands testobj] != {}}]
+testConstraint testindexobj [expr {[info commands testindexobj] != {}}]
+
+# Used for constraining memory leak tests
+testConstraint memory [llength [info commands memory]]
+
+test string-1.1 {error conditions} {
+ list [catch {string gorp a b} msg] $msg
+} {1 {unknown or ambiguous subcommand "gorp": must be bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}}
+test string-1.2 {error conditions} {
+ list [catch {string} msg] $msg
+} {1 {wrong # args: should be "string subcommand ?arg ...?"}}
+
+test string-2.1 {string compare, too few args} {
+ list [catch {string compare a} msg] $msg
+} {1 {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"}}
+test string-2.2 {string compare, bad args} {
+ list [catch {string compare a b c} msg] $msg
+} {1 {bad option "a": must be -nocase or -length}}
+test string-2.3 {string compare, bad args} {
+ list [catch {string compare -length -nocase str1 str2} msg] $msg
+} {1 {expected integer but got "-nocase"}}
+test string-2.4 {string compare, too many args} {
+ list [catch {string compare -length 10 -nocase str1 str2 str3} msg] $msg
+} {1 {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"}}
+test string-2.5 {string compare with length unspecified} {
+ list [catch {string compare -length 10 10} msg] $msg
+} {1 {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"}}
+test string-2.6 {string compare} {
+ string compare abcde abdef
+} -1
+test string-2.7 {string compare, shortest method name} {
+ string c abcde ABCDE
+} 1
+test string-2.8 {string compare} {
+ string compare abcde abcde
+} 0
+test string-2.9 {string compare with length} {
+ string compare -length 2 abcde abxyz
+} 0
+test string-2.10 {string compare with special index} {
+ list [catch {string compare -length end-3 abcde abxyz} msg] $msg
+} {1 {expected integer but got "end-3"}}
+test string-2.11 {string compare, unicode} {
+ string compare ab\u7266 ab\u7267
+} -1
+test string-2.12 {string compare, high bit} {
+ # This test will fail if the underlying comparaison
+ # is using signed chars instead of unsigned chars.
+ # (like SunOS's default memcmp thus the compat/memcmp.c)
+ string compare "\x80" "@"
+ # Nb this tests works also in utf8 space because \x80 is
+ # translated into a 2 or more bytelength but whose first byte has
+ # the high bit set.
+} 1
+test string-2.13 {string compare -nocase} {
+ string compare -nocase abcde abdef
+} -1
+test string-2.14 {string compare -nocase} {
+ string c -nocase abcde ABCDE
+} 0
+test string-2.15 {string compare -nocase} {
+ string compare -nocase abcde abcde
+} 0
+test string-2.16 {string compare -nocase with length} {
+ string compare -length 2 -nocase abcde Abxyz
+} 0
+test string-2.17 {string compare -nocase with length} {
+ string compare -nocase -length 3 abcde Abxyz
+} -1
+test string-2.18 {string compare -nocase with length <= 0} {
+ string compare -nocase -length -1 abcde AbCdEf
+} -1
+test string-2.19 {string compare -nocase with excessive length} {
+ string compare -nocase -length 50 AbCdEf abcde
+} 1
+test string-2.20 {string compare -len unicode} {
+ # These are strings that are 6 BYTELENGTH long, but the length
+ # shouldn't make a different because there are actually 3 CHARS long
+ string compare -len 5 \334\334\334 \334\334\374
+} -1
+test string-2.21 {string compare -nocase with special index} {
+ list [catch {string compare -nocase -length end-3 Abcde abxyz} msg] $msg
+} {1 {expected integer but got "end-3"}}
+test string-2.22 {string compare, null strings} {
+ string compare "" ""
+} 0
+test string-2.23 {string compare, null strings} {
+ string compare "" foo
+} -1
+test string-2.24 {string compare, null strings} {
+ string compare foo ""
+} 1
+test string-2.25 {string compare -nocase, null strings} {
+ string compare -nocase "" ""
+} 0
+test string-2.26 {string compare -nocase, null strings} {
+ string compare -nocase "" foo
+} -1
+test string-2.27 {string compare -nocase, null strings} {
+ string compare -nocase foo ""
+} 1
+test string-2.28 {string compare with length, unequal strings} {
+ string compare -length 2 abc abde
+} 0
+test string-2.29 {string compare with length, unequal strings} {
+ string compare -length 2 ab abde
+} 0
+test string-2.30 {string compare with NUL character vs. other ASCII} {
+ # Be careful here, since UTF-8 rep comparison with memcmp() of
+ # these puts chars in the wrong order
+ string compare \x00 \x01
+} -1
+test string-2.31 {string compare, high bit} {
+ proc foo {} {string compare "a\x80" "a@"}
+ foo
+} 1
+test string-2.32 {string compare, high bit} {
+ proc foo {} {string compare "a\x00" "a\x01"}
+ foo
+} -1
+test string-2.33 {string compare, high bit} {
+ proc foo {} {string compare "\x00\x00" "\x00\x01"}
+ foo
+} -1
+
+# only need a few tests on equal, since it uses the same code as
+# string compare, but just modifies the return output
+test string-3.1 {string equal} {
+ string equal abcde abdef
+} 0
+test string-3.2 {string equal} {
+ string eq abcde ABCDE
+} 0
+test string-3.3 {string equal} {
+ string equal abcde abcde
+} 1
+test string-3.4 {string equal -nocase} {
+ string equal -nocase \334\334\334\334\374\374\374\374 \334\334\334\334\334\334\334\334
+} 1
+test string-3.5 {string equal -nocase} {
+ string equal -nocase abcde abdef
+} 0
+test string-3.6 {string equal -nocase} {
+ string eq -nocase abcde ABCDE
+} 1
+test string-3.7 {string equal -nocase} {
+ string equal -nocase abcde abcde
+} 1
+test string-3.8 {string equal with length, unequal strings} {
+ string equal -length 2 abc abde
+} 1
+
+test string-4.1 {string first, too few args} {
+ list [catch {string first a} msg] $msg
+} {1 {wrong # args: should be "string first needleString haystackString ?startIndex?"}}
+test string-4.2 {string first, bad args} {
+ list [catch {string first a b c} msg] $msg
+} {1 {bad index "c": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-4.3 {string first, too many args} {
+ list [catch {string first a b 5 d} msg] $msg
+} {1 {wrong # args: should be "string first needleString haystackString ?startIndex?"}}
+test string-4.4 {string first} {
+ string first bq abcdefgbcefgbqrs
+} 12
+test string-4.5 {string first} {
+ string fir bcd abcdefgbcefgbqrs
+} 1
+test string-4.6 {string first} {
+ string f b abcdefgbcefgbqrs
+} 1
+test string-4.7 {string first} {
+ string first xxx x123xx345xxx789xxx012
+} 9
+test string-4.8 {string first} {
+ string first "" x123xx345xxx789xxx012
+} -1
+test string-4.9 {string first, unicode} {
+ string first x abc\u7266x
+} 4
+test string-4.10 {string first, unicode} {
+ string first \u7266 abc\u7266x
+} 3
+test string-4.11 {string first, start index} {
+ string first \u7266 abc\u7266x 3
+} 3
+test string-4.12 {string first, start index} {
+ string first \u7266 abc\u7266x 4
+} -1
+test string-4.13 {string first, start index} {
+ string first \u7266 abc\u7266x end-2
+} 3
+test string-4.14 {string first, negative start index} {
+ string first b abc -1
+} 1
+test string-4.15 {string first, ability to two-byte encoded utf-8 chars} {
+ # Test for a bug in Tcl 8.3 where test for all-single-byte-encoded
+ # strings was incorrect, leading to an index returned by [string first]
+ # which pointed past the end of the string.
+ set uchar \u057e ;# character with two-byte encoding in utf-8
+ string first % %#$uchar$uchar#$uchar$uchar#% 3
+} 8
+
+test string-5.1 {string index} {
+ list [catch {string index} msg] $msg
+} {1 {wrong # args: should be "string index string charIndex"}}
+test string-5.2 {string index} {
+ list [catch {string index a b c} msg] $msg
+} {1 {wrong # args: should be "string index string charIndex"}}
+test string-5.3 {string index} {
+ string index abcde 0
+} a
+test string-5.4 {string index} {
+ string in abcde 4
+} e
+test string-5.5 {string index} {
+ string index abcde 5
+} {}
+test string-5.6 {string index} {
+ list [catch {string index abcde -10} msg] $msg
+} {0 {}}
+test string-5.7 {string index} {
+ list [catch {string index a xyz} msg] $msg
+} {1 {bad index "xyz": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-5.8 {string index} {
+ string index abc end
+} c
+test string-5.9 {string index} {
+ string index abc end-1
+} b
+test string-5.10 {string index, unicode} {
+ string index abc\u7266d 4
+} d
+test string-5.11 {string index, unicode} {
+ string index abc\u7266d 3
+} \u7266
+test string-5.12 {string index, unicode over char length, under byte length} {
+ string index \334\374\334\374 6
+} {}
+test string-5.13 {string index, bytearray object} {
+ string index [binary format a5 fuz] 0
+} f
+test string-5.14 {string index, bytearray object} {
+ string index [binary format I* {0x50515253 0x52}] 3
+} S
+test string-5.15 {string index, bytearray object} {
+ set b [binary format I* {0x50515253 0x52}]
+ set i1 [string index $b end-6]
+ set i2 [string index $b 1]
+ string compare $i1 $i2
+} 0
+test string-5.16 {string index, bytearray object with string obj shimmering} {
+ set str "0123456789\x00 abcdedfghi"
+ binary scan $str H* dump
+ string compare [string index $str 10] \x00
+} 0
+test string-5.17 {string index, bad integer} -body {
+ list [catch {string index "abc" 0o8} msg] $msg
+} -match glob -result {1 {*invalid octal number*}}
+test string-5.18 {string index, bad integer} -body {
+ list [catch {string index "abc" end-0o0289} msg] $msg
+} -match glob -result {1 {*invalid octal number*}}
+test string-5.19 {string index, bytearray object out of bounds} {
+ string index [binary format I* {0x50515253 0x52}] -1
+} {}
+test string-5.20 {string index, bytearray object out of bounds} {
+ string index [binary format I* {0x50515253 0x52}] 20
+} {}
+
+
+proc largest_int {} {
+ # This will give us what the largest valid int on this machine is,
+ # so we can test for overflow properly below on >32 bit systems
+ set int 1
+ set exp 7; # assume we get at least 8 bits
+ while {wide($int) > 0} { set int [expr {wide(1) << [incr exp]}] }
+ return [expr {$int-1}]
+}
+
+test string-6.1 {string is, too few args} {
+ list [catch {string is} msg] $msg
+} {1 {wrong # args: should be "string is class ?-strict? ?-failindex var? str"}}
+test string-6.2 {string is, too few args} {
+ list [catch {string is alpha} msg] $msg
+} {1 {wrong # args: should be "string is class ?-strict? ?-failindex var? str"}}
+test string-6.3 {string is, bad args} {
+ list [catch {string is alpha -failin str} msg] $msg
+} {1 {wrong # args: should be "string is alpha ?-strict? ?-failindex var? str"}}
+test string-6.4 {string is, too many args} {
+ list [catch {string is alpha -failin var -strict str more} msg] $msg
+} {1 {wrong # args: should be "string is class ?-strict? ?-failindex var? str"}}
+test string-6.5 {string is, class check} {
+ list [catch {string is bogus str} msg] $msg
+} {1 {bad class "bogus": must be alnum, alpha, ascii, control, boolean, digit, double, entier, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, or xdigit}}
+test string-6.6 {string is, ambiguous class} {
+ list [catch {string is al str} msg] $msg
+} {1 {ambiguous class "al": must be alnum, alpha, ascii, control, boolean, digit, double, entier, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, or xdigit}}
+test string-6.7 {string is alpha, all ok} {
+ string is alpha -strict -failindex var abc
+} 1
+test string-6.8 {string is, error in var} {
+ list [string is alpha -failindex var abc5def] $var
+} {0 3}
+test string-6.9 {string is, var shouldn't get set} {
+ catch {unset var}
+ list [catch {string is alpha -failindex var abc; set var} msg] $msg
+} {1 {can't read "var": no such variable}}
+test string-6.10 {string is, ok on empty} {
+ string is alpha {}
+} 1
+test string-6.11 {string is, -strict check against empty} {
+ string is alpha -strict {}
+} 0
+test string-6.12 {string is alnum, true} {
+ string is alnum abc123
+} 1
+test string-6.13 {string is alnum, false} {
+ list [string is alnum -failindex var abc1.23] $var
+} {0 4}
+test string-6.14 {string is alnum, unicode} "string is alnum abc\xfc" 1
+test string-6.15 {string is alpha, true} {
+ string is alpha abc
+} 1
+test string-6.16 {string is alpha, false} {
+ list [string is alpha -fail var a1bcde] $var
+} {0 1}
+test string-6.17 {string is alpha, unicode} {
+ string is alpha abc\374
+} 1
+test string-6.18 {string is ascii, true} {
+ string is ascii abc\u007Fend\u0000
+} 1
+test string-6.19 {string is ascii, false} {
+ list [string is ascii -fail var abc\u0000def\u0080more] $var
+} {0 7}
+test string-6.20 {string is boolean, true} {
+ string is boolean true
+} 1
+test string-6.21 {string is boolean, true} {
+ string is boolean f
+} 1
+test string-6.22 {string is boolean, true based on type} {
+ string is bool [string compare a a]
+} 1
+test string-6.23 {string is boolean, false} {
+ list [string is bool -fail var yada] $var
+} {0 0}
+test string-6.24 {string is digit, true} {
+ string is digit 0123456789
+} 1
+test string-6.25 {string is digit, false} {
+ list [string is digit -fail var 0123\u00dc567] $var
+} {0 4}
+test string-6.26 {string is digit, false} {
+ list [string is digit -fail var +123567] $var
+} {0 0}
+test string-6.27 {string is double, true} {
+ string is double 1
+} 1
+test string-6.28 {string is double, true} {
+ string is double [expr double(1)]
+} 1
+test string-6.29 {string is double, true} {
+ string is double 1.0
+} 1
+test string-6.30 {string is double, true} {
+ string is double [string compare a a]
+} 1
+test string-6.31 {string is double, true} {
+ string is double " +1.0e-1 "
+} 1
+test string-6.32 {string is double, true} {
+ string is double "\n1.0\v"
+} 1
+test string-6.33 {string is double, false} {
+ list [string is double -fail var 1abc] $var
+} {0 1}
+test string-6.34 {string is double, false} {
+ list [string is double -fail var abc] $var
+} {0 0}
+test string-6.35 {string is double, false} {
+ list [string is double -fail var " 1.0e4e4 "] $var
+} {0 8}
+test string-6.36 {string is double, false} {
+ list [string is double -fail var "\n"] $var
+} {0 0}
+test string-6.37 {string is double, false on int overflow} {
+ # Make it the largest int recognizable, with one more digit for overflow
+ # Since bignums arrived in Tcl 8.5, the sense of this test changed.
+ # Now integer values that exceed native limits become bignums, and
+ # bignums can convert to doubles without error.
+ list [string is double -fail var [largest_int]0] $var
+} {1 0}
+# string-6.38 removed, underflow on input is no longer an error.
+test string-6.39 {string is double, false} {
+ # This test is non-portable because IRIX thinks
+ # that .e1 is a valid double - this is really a bug
+ # on IRIX as .e1 should NOT be a valid double
+ #
+ # Portable now. Tcl 8.5 does its own double parsing.
+
+ list [string is double -fail var .e1] $var
+} {0 0}
+test string-6.40 {string is false, true} {
+ string is false false
+} 1
+test string-6.41 {string is false, true} {
+ string is false FaLsE
+} 1
+test string-6.42 {string is false, true} {
+ string is false N
+} 1
+test string-6.43 {string is false, true} {
+ string is false 0
+} 1
+test string-6.44 {string is false, true} {
+ string is false off
+} 1
+test string-6.45 {string is false, false} {
+ list [string is false -fail var abc] $var
+} {0 0}
+test string-6.46 {string is false, false} {
+ catch {unset var}
+ list [string is false -fail var Y] $var
+} {0 0}
+test string-6.47 {string is false, false} {
+ catch {unset var}
+ list [string is false -fail var offensive] $var
+} {0 0}
+test string-6.48 {string is integer, true} {
+ string is integer +1234567890
+} 1
+test string-6.49 {string is integer, true on type} {
+ string is integer [expr int(50.0)]
+} 1
+test string-6.50 {string is integer, true} {
+ string is integer [list -10]
+} 1
+test string-6.51 {string is integer, true as hex} {
+ string is integer 0xabcdef
+} 1
+test string-6.52 {string is integer, true as octal} {
+ string is integer 012345
+} 1
+test string-6.53 {string is integer, true with whitespace} {
+ string is integer " \n1234\v"
+} 1
+test string-6.54 {string is integer, false} {
+ list [string is integer -fail var 123abc] $var
+} {0 3}
+test string-6.55 {string is integer, false on overflow} {
+ list [string is integer -fail var +[largest_int]0] $var
+} {0 -1}
+test string-6.56 {string is integer, false} {
+ list [string is integer -fail var [expr double(1)]] $var
+} {0 1}
+test string-6.57 {string is integer, false} {
+ list [string is integer -fail var " "] $var
+} {0 0}
+test string-6.58 {string is integer, false on bad octal} {
+ list [string is integer -fail var 0o36963] $var
+} {0 4}
+test string-6.58.1 {string is integer, false on bad octal} {
+ list [string is integer -fail var 0o36963] $var
+} {0 4}
+test string-6.59 {string is integer, false on bad hex} {
+ list [string is integer -fail var 0X345XYZ] $var
+} {0 5}
+test string-6.60 {string is lower, true} {
+ string is lower abc
+} 1
+test string-6.61 {string is lower, unicode true} {
+ string is lower abc\u00fcue
+} 1
+test string-6.62 {string is lower, false} {
+ list [string is lower -fail var aBc] $var
+} {0 1}
+test string-6.63 {string is lower, false} {
+ list [string is lower -fail var abc1] $var
+} {0 3}
+test string-6.64 {string is lower, unicode false} {
+ list [string is lower -fail var ab\u00dcUE] $var
+} {0 2}
+test string-6.65 {string is space, true} {
+ string is space " \t\n\v\f"
+} 1
+test string-6.66 {string is space, false} {
+ list [string is space -fail var " \t\n\v1\f"] $var
+} {0 4}
+test string-6.67 {string is true, true} {
+ string is true true
+} 1
+test string-6.68 {string is true, true} {
+ string is true TrU
+} 1
+test string-6.69 {string is true, true} {
+ string is true ye
+} 1
+test string-6.70 {string is true, true} {
+ string is true 1
+} 1
+test string-6.71 {string is true, true} {
+ string is true on
+} 1
+test string-6.72 {string is true, false} {
+ list [string is true -fail var onto] $var
+} {0 0}
+test string-6.73 {string is true, false} {
+ catch {unset var}
+ list [string is true -fail var 25] $var
+} {0 0}
+test string-6.74 {string is true, false} {
+ catch {unset var}
+ list [string is true -fail var no] $var
+} {0 0}
+test string-6.75 {string is upper, true} {
+ string is upper ABC
+} 1
+test string-6.76 {string is upper, unicode true} {
+ string is upper ABC\u00dcUE
+} 1
+test string-6.77 {string is upper, false} {
+ list [string is upper -fail var AbC] $var
+} {0 1}
+test string-6.78 {string is upper, false} {
+ list [string is upper -fail var AB2C] $var
+} {0 2}
+test string-6.79 {string is upper, unicode false} {
+ list [string is upper -fail var ABC\u00fcue] $var
+} {0 3}
+test string-6.80 {string is wordchar, true} {
+ string is wordchar abc_123
+} 1
+test string-6.81 {string is wordchar, unicode true} {
+ string is wordchar abc\u00fcab\u00dcAB\u5001
+} 1
+test string-6.82 {string is wordchar, false} {
+ list [string is wordchar -fail var abcd.ef] $var
+} {0 4}
+test string-6.83 {string is wordchar, unicode false} {
+ list [string is wordchar -fail var abc\u0080def] $var
+} {0 3}
+test string-6.84 {string is control} {
+ ## Control chars are in the ranges
+ ## 00..1F && 7F..9F
+ list [string is control -fail var \x00\x01\x10\x1F\x7F\x80\x9F\x60] $var
+} {0 7}
+test string-6.85 {string is control} {
+ string is control \u0100
+} 0
+test string-6.86 {string is graph} {
+ ## graph is any print char, except space
+ list [string is gra -fail var "0123abc!@#\$\u0100 "] $var
+} {0 12}
+test string-6.87 {string is print} {
+ ## basically any printable char
+ list [string is print -fail var "0123abc!@#\$\u0100 \u0010"] $var
+} {0 13}
+test string-6.88 {string is punct} {
+ ## any graph char that isn't alnum
+ list [string is punct -fail var "_!@#\u00beq0"] $var
+} {0 4}
+test string-6.89 {string is xdigit} {
+ list [string is xdigit -fail var 0123456789\u0061bcdefABCDEFg] $var
+} {0 22}
+
+test string-6.90 {string is integer, bad integers} {
+ # SF bug #634856
+ set result ""
+ set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1"]
+ foreach num $numbers {
+ lappend result [string is int -strict $num]
+ }
+ return $result
+} {1 1 0 0 0 1 0 0}
+test string-6.91 {string is double, bad doubles} {
+ set result ""
+ set numbers [list 1.0 +1.0 ++1.0 +-1.0 -+1.0 -1.0 --1.0 "- +1.0"]
+ foreach num $numbers {
+ lappend result [string is double -strict $num]
+ }
+ return $result
+} {1 1 0 0 0 1 0 0}
+test string-6.92 {string is integer, 32-bit overflow} {
+ # Bug 718878
+ set x 0x100000000
+ list [string is integer -failindex var $x] $var
+} {0 -1}
+test string-6.93 {string is integer, 32-bit overflow} {
+ # Bug 718878
+ set x 0x100000000
+ append x ""
+ list [string is integer -failindex var $x] $var
+} {0 -1}
+test string-6.94 {string is integer, 32-bit overflow} {
+ # Bug 718878
+ set x 0x100000000
+ list [string is integer -failindex var [expr {$x}]] $var
+} {0 -1}
+test string-6.95 {string is wideinteger, true} {
+ string is wideinteger +1234567890
+} 1
+test string-6.96 {string is wideinteger, true on type} {
+ string is wideinteger [expr wide(50.0)]
+} 1
+test string-6.97 {string is wideinteger, true} {
+ string is wideinteger [list -10]
+} 1
+test string-6.98 {string is wideinteger, true as hex} {
+ string is wideinteger 0xabcdef
+} 1
+test string-6.99 {string is wideinteger, true as octal} {
+ string is wideinteger 0123456
+} 1
+test string-6.100 {string is wideinteger, true with whitespace} {
+ string is wideinteger " \n1234\v"
+} 1
+test string-6.101 {string is wideinteger, false} {
+ list [string is wideinteger -fail var 123abc] $var
+} {0 3}
+test string-6.102 {string is wideinteger, false on overflow} {
+ list [string is wideinteger -fail var +[largest_int]0] $var
+} {0 -1}
+test string-6.103 {string is wideinteger, false} {
+ list [string is wideinteger -fail var [expr double(1)]] $var
+} {0 1}
+test string-6.104 {string is wideinteger, false} {
+ list [string is wideinteger -fail var " "] $var
+} {0 0}
+test string-6.105 {string is wideinteger, false on bad octal} {
+ list [string is wideinteger -fail var 0o36963] $var
+} {0 4}
+test string-6.105.1 {string is wideinteger, false on bad octal} {
+ list [string is wideinteger -fail var 0o36963] $var
+} {0 4}
+test string-6.106 {string is wideinteger, false on bad hex} {
+ list [string is wideinteger -fail var 0X345XYZ] $var
+} {0 5}
+test string-6.107 {string is integer, bad integers} {
+ # SF bug #634856
+ set result ""
+ set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1"]
+ foreach num $numbers {
+ lappend result [string is wideinteger -strict $num]
+ }
+ return $result
+} {1 1 0 0 0 1 0 0}
+test string-6.108 {string is double, Bug 1382287} {
+ set x 2turtledoves
+ string is double $x
+ string is double $x
+} 0
+test string-6.109 {string is double, Bug 1360532} {
+ string is double 1\u00a0
+} 0
+test string-6.110 {string is entier, true} {
+ string is entier +1234567890
+} 1
+test string-6.111 {string is entier, true on type} {
+ string is entier [expr wide(50.0)]
+} 1
+test string-6.112 {string is entier, true} {
+ string is entier [list -10]
+} 1
+test string-6.113 {string is entier, true as hex} {
+ string is entier 0xabcdef
+} 1
+test string-6.114 {string is entier, true as octal} {
+ string is entier 0123456
+} 1
+test string-6.115 {string is entier, true with whitespace} {
+ string is entier " \n1234\v"
+} 1
+test string-6.116 {string is entier, false} {
+ list [string is entier -fail var 123abc] $var
+} {0 3}
+test string-6.117 {string is entier, false} {
+ list [string is entier -fail var 123123123123123123123123123123123123123123123123123123123123123123123123123123123123abc] $var
+} {0 84}
+test string-6.118 {string is entier, false} {
+ list [string is entier -fail var [expr double(1)]] $var
+} {0 1}
+test string-6.119 {string is entier, false} {
+ list [string is entier -fail var " "] $var
+} {0 0}
+test string-6.120 {string is entier, false on bad octal} {
+ list [string is entier -fail var 0o36963] $var
+} {0 4}
+test string-6.121.1 {string is entier, false on bad octal} {
+ list [string is entier -fail var 0o36963] $var
+} {0 4}
+test string-6.122 {string is entier, false on bad hex} {
+ list [string is entier -fail var 0X345XYZ] $var
+} {0 5}
+test string-6.123 {string is entier, bad integers} {
+ # SF bug #634856
+ set result ""
+ set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1"]
+ foreach num $numbers {
+ lappend result [string is entier -strict $num]
+ }
+ return $result
+} {1 1 0 0 0 1 0 0}
+test string-6.124 {string is entier, true} {
+ string is entier +1234567890123456789012345678901234567890
+} 1
+test string-6.125 {string is entier, true} {
+ string is entier [list -10000000000000000000000000000000000000000000000000000000000000000000000000000000000000]
+} 1
+test string-6.126 {string is entier, true as hex} {
+ string is entier 0xabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef
+} 1
+test string-6.127 {string is entier, true as octal} {
+ string is entier 0123456112341234561234565623456123456123456123456123456123456123456123456123456123456
+} 1
+test string-6.128 {string is entier, true with whitespace} {
+ string is entier " \n12340000000000000000000000000000000000000000000000000000000000000000000000000000000000000\v"
+} 1
+test string-6.129 {string is entier, false on bad octal} {
+ list [string is entier -fail var 0o1234561123412345612345656234561234561234561234561234561234561234561234561234561234536963] $var
+} {0 87}
+test string-6.130.1 {string is entier, false on bad octal} {
+ list [string is entier -fail var 0o1234561123412345612345656234561234561234561234561234561234561234561234561234561234536963] $var
+} {0 87}
+test string-6.131 {string is entier, false on bad hex} {
+ list [string is entier -fail var 0X12345611234123456123456562345612345612345612345612345612345612345612345612345612345345XYZ] $var
+} {0 88}
+
+catch {rename largest_int {}}
+
+test string-7.1 {string last, too few args} {
+ list [catch {string last a} msg] $msg
+} {1 {wrong # args: should be "string last needleString haystackString ?startIndex?"}}
+test string-7.2 {string last, bad args} {
+ list [catch {string last a b c} msg] $msg
+} {1 {bad index "c": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-7.3 {string last, too many args} {
+ list [catch {string last a b c d} msg] $msg
+} {1 {wrong # args: should be "string last needleString haystackString ?startIndex?"}}
+test string-7.4 {string last} {
+ string la xxx xxxx123xx345x678
+} 1
+test string-7.5 {string last} {
+ string last xx xxxx123xx345x678
+} 7
+test string-7.6 {string last} {
+ string las x xxxx123xx345x678
+} 12
+test string-7.7 {string last, unicode} {
+ string las x xxxx12\u7266xx345x678
+} 12
+test string-7.8 {string last, unicode} {
+ string las \u7266 xxxx12\u7266xx345x678
+} 6
+test string-7.9 {string last, stop index} {
+ string las \u7266 xxxx12\u7266xx345x678
+} 6
+test string-7.10 {string last, unicode} {
+ string las \u7266 xxxx12\u7266xx345x678
+} 6
+test string-7.11 {string last, start index} {
+ string last \u7266 abc\u7266x 3
+} 3
+test string-7.12 {string last, start index} {
+ string last \u7266 abc\u7266x 2
+} -1
+test string-7.13 {string last, start index} {
+ ## Constrain to last 'a' should work
+ string last ba badbad end-1
+} 3
+test string-7.14 {string last, start index} {
+ ## Constrain to last 'b' should skip last 'ba'
+ string last ba badbad end-2
+} 0
+test string-7.15 {string last, start index} {
+ string last \334a \334ad\334ad 0
+} -1
+test string-7.16 {string last, start index} {
+ string last \334a \334ad\334ad end-1
+} 3
+
+test string-8.1 {string bytelength} {
+ list [catch {string bytelength} msg] $msg
+} {1 {wrong # args: should be "string bytelength string"}}
+test string-8.2 {string bytelength} {
+ list [catch {string bytelength a b} msg] $msg
+} {1 {wrong # args: should be "string bytelength string"}}
+test string-8.3 {string bytelength} {
+ string bytelength "\u00c7"
+} 2
+test string-8.4 {string bytelength} {
+ string b ""
+} 0
+
+test string-9.1 {string length} {
+ list [catch {string length} msg] $msg
+} {1 {wrong # args: should be "string length string"}}
+test string-9.2 {string length} {
+ list [catch {string length a b} msg] $msg
+} {1 {wrong # args: should be "string length string"}}
+test string-9.3 {string length} {
+ string length "a little string"
+} 15
+test string-9.4 {string length} {
+ string le ""
+} 0
+test string-9.5 {string length, unicode} {
+ string le "abcd\u7266"
+} 5
+test string-9.6 {string length, bytearray object} {
+ string length [binary format a5 foo]
+} 5
+test string-9.7 {string length, bytearray object} {
+ string length [binary format I* {0x50515253 0x52}]
+} 8
+
+test string-10.1 {string map, too few args} {
+ list [catch {string map} msg] $msg
+} {1 {wrong # args: should be "string map ?-nocase? charMap string"}}
+test string-10.2 {string map, bad args} {
+ list [catch {string map {a b} abba oops} msg] $msg
+} {1 {bad option "a b": must be -nocase}}
+test string-10.3 {string map, too many args} {
+ list [catch {string map -nocase {a b} str1 str2} msg] $msg
+} {1 {wrong # args: should be "string map ?-nocase? charMap string"}}
+test string-10.4 {string map} {
+ string map {a b} abba
+} {bbbb}
+test string-10.5 {string map} {
+ string map {a b} a
+} {b}
+test string-10.6 {string map -nocase} {
+ string map -nocase {a b} Abba
+} {bbbb}
+test string-10.7 {string map} {
+ string map {abc 321 ab * a A} aabcabaababcab
+} {A321*A*321*}
+test string-10.8 {string map -nocase} {
+ string map -nocase {aBc 321 Ab * a A} aabcabaababcab
+} {A321*A*321*}
+test string-10.9 {string map -nocase} {
+ string map -no {abc 321 Ab * a A} aAbCaBaAbAbcAb
+} {A321*A*321*}
+test string-10.10 {string map} {
+ list [catch {string map {a b c} abba} msg] $msg
+} {1 {char map list unbalanced}}
+test string-10.11 {string map, nulls} {
+ string map {\x00 NULL blah \x00nix} {qwerty}
+} {qwerty}
+test string-10.12 {string map, unicode} {
+ string map [list \374 ue UE \334] "a\374ueUE\000EU"
+} aueue\334\0EU
+test string-10.13 {string map, -nocase unicode} {
+ string map -nocase [list \374 ue UE \334] "a\374ueUE\000EU"
+} aue\334\334\0EU
+test string-10.14 {string map, -nocase null arguments} {
+ string map -nocase {{} abc} foo
+} foo
+test string-10.15 {string map, one pair case} {
+ string map -nocase {abc 32} aAbCaBaAbAbcAb
+} {a32aBaAb32Ab}
+test string-10.16 {string map, one pair case} {
+ string map -nocase {ab 4321} aAbCaBaAbAbcAb
+} {a4321C4321a43214321c4321}
+test string-10.17 {string map, one pair case} {
+ string map {Ab 4321} aAbCaBaAbAbcAb
+} {a4321CaBa43214321c4321}
+test string-10.18 {string map, empty argument} {
+ string map -nocase {{} abc} foo
+} foo
+test string-10.19 {string map, empty arguments} {
+ string map -nocase {{} abc f bar {} def} foo
+} baroo
+test string-10.20 {string map, dictionaries don't alter map ordering} {
+ set map {aa X a Y}
+ list [string map [dict create aa X a Y] aaa] [string map $map aaa] [dict size $map] [string map $map aaa]
+} {XY XY 2 XY}
+test string-10.21 {string map, ABR checks} {
+ string map {longstring foob} long
+} long
+test string-10.22 {string map, ABR checks} {
+ string map {long foob} long
+} foob
+test string-10.23 {string map, ABR checks} {
+ string map {lon foob} long
+} foobg
+test string-10.24 {string map, ABR checks} {
+ string map {lon foob} longlo
+} foobglo
+test string-10.25 {string map, ABR checks} {
+ string map {lon foob} longlon
+} foobgfoob
+test string-10.26 {string map, ABR checks} {
+ string map {longstring foob longstring bar} long
+} long
+test string-10.27 {string map, ABR checks} {
+ string map {long foob longstring bar} long
+} foob
+test string-10.28 {string map, ABR checks} {
+ string map {lon foob longstring bar} long
+} foobg
+test string-10.29 {string map, ABR checks} {
+ string map {lon foob longstring bar} longlo
+} foobglo
+test string-10.30 {string map, ABR checks} {
+ string map {lon foob longstring bar} longlon
+} foobgfoob
+test string-10.31 {string map, nasty sharing crash from [Bug 1018562]} {
+ set a {a b}
+ string map $a $a
+} {b b}
+
+test string-11.1 {string match, too few args} {
+ list [catch {string match a} msg] $msg
+} {1 {wrong # args: should be "string match ?-nocase? pattern string"}}
+test string-11.2 {string match, too many args} {
+ list [catch {string match a b c d} msg] $msg
+} {1 {wrong # args: should be "string match ?-nocase? pattern string"}}
+test string-11.3 {string match} {
+ string match abc abc
+} 1
+test string-11.4 {string match} {
+ string mat abc abd
+} 0
+test string-11.5 {string match} {
+ string match ab*c abc
+} 1
+test string-11.6 {string match} {
+ string match ab**c abc
+} 1
+test string-11.7 {string match} {
+ string match ab* abcdef
+} 1
+test string-11.8 {string match} {
+ string match *c abc
+} 1
+test string-11.9 {string match} {
+ string match *3*6*9 0123456789
+} 1
+test string-11.9.1 {string match} {
+ string match *3*6*89 0123456789
+} 1
+test string-11.9.2 {string match} {
+ string match *3*456*89 0123456789
+} 1
+test string-11.9.3 {string match} {
+ string match *3*6* 0123456789
+} 1
+test string-11.9.4 {string match} {
+ string match *3*56* 0123456789
+} 1
+test string-11.9.5 {string match} {
+ string match *3*456*** 0123456789
+} 1
+test string-11.9.6 {string match} {
+ string match **3*456** 0123456789
+} 1
+test string-11.9.7 {string match} {
+ string match *3***456* 0123456789
+} 1
+test string-11.9.8 {string match} {
+ string match *3***\[456]* 0123456789
+} 1
+test string-11.9.9 {string match} {
+ string match *3***\[4-6]* 0123456789
+} 1
+test string-11.9.10 {string match} {
+ string match *3***\[4-6] 0123456789
+} 0
+test string-11.9.11 {string match} {
+ string match *3***\[4-6] 0123456
+} 1
+test string-11.10 {string match} {
+ string match *3*6*9 01234567890
+} 0
+test string-11.10.1 {string match} {
+ string match *3*6*89 01234567890
+} 0
+test string-11.10.2 {string match} {
+ string match *3*456*89 01234567890
+} 0
+test string-11.10.3 {string match} {
+ string match **3*456*89 01234567890
+} 0
+test string-11.10.4 {string match} {
+ string match *3*456***89 01234567890
+} 0
+test string-11.11 {string match} {
+ string match a?c abc
+} 1
+test string-11.12 {string match} {
+ string match a??c abc
+} 0
+test string-11.13 {string match} {
+ string match ?1??4???8? 0123456789
+} 1
+test string-11.14 {string match} {
+ string match {[abc]bc} abc
+} 1
+test string-11.15 {string match} {
+ string match {a[abc]c} abc
+} 1
+test string-11.16 {string match} {
+ string match {a[xyz]c} abc
+} 0
+test string-11.17 {string match} {
+ string match {12[2-7]45} 12345
+} 1
+test string-11.18 {string match} {
+ string match {12[ab2-4cd]45} 12345
+} 1
+test string-11.19 {string match} {
+ string match {12[ab2-4cd]45} 12b45
+} 1
+test string-11.20 {string match} {
+ string match {12[ab2-4cd]45} 12d45
+} 1
+test string-11.21 {string match} {
+ string match {12[ab2-4cd]45} 12145
+} 0
+test string-11.22 {string match} {
+ string match {12[ab2-4cd]45} 12545
+} 0
+test string-11.23 {string match} {
+ string match {a\*b} a*b
+} 1
+test string-11.24 {string match} {
+ string match {a\*b} ab
+} 0
+test string-11.25 {string match} {
+ string match {a\*\?\[\]\\\x} "a*?\[\]\\x"
+} 1
+test string-11.26 {string match} {
+ string match ** ""
+} 1
+test string-11.27 {string match} {
+ string match *. ""
+} 0
+test string-11.28 {string match} {
+ string match "" ""
+} 1
+test string-11.29 {string match} {
+ string match \[a a
+} 1
+test string-11.30 {string match, bad args} {
+ list [catch {string match - b c} msg] $msg
+} {1 {bad option "-": must be -nocase}}
+test string-11.31 {string match case} {
+ string match a A
+} 0
+test string-11.32 {string match nocase} {
+ string match -n a A
+} 1
+test string-11.33 {string match nocase} {
+ string match -nocase a\334 A\374
+} 1
+test string-11.34 {string match nocase} {
+ string match -nocase a*f ABCDEf
+} 1
+test string-11.35 {string match case, false hope} {
+ # This is true because '_' lies between the A-Z and a-z ranges
+ string match {[A-z]} _
+} 1
+test string-11.36 {string match nocase range} {
+ # This is false because although '_' lies between the A-Z and a-z ranges,
+ # we lower case the end points before checking the ranges.
+ string match -nocase {[A-z]} _
+} 0
+test string-11.37 {string match nocase} {
+ string match -nocase {[A-fh-Z]} g
+} 0
+test string-11.38 {string match case, reverse range} {
+ string match {[A-fh-Z]} g
+} 1
+test string-11.39 {string match, *\ case} {
+ string match {*\abc} abc
+} 1
+test string-11.39.1 {string match, *\ case} {
+ string match {*ab\c} abc
+} 1
+test string-11.39.2 {string match, *\ case} {
+ string match {*ab\*} ab*
+} 1
+test string-11.39.3 {string match, *\ case} {
+ string match {*ab\*} abc
+} 0
+test string-11.39.4 {string match, *\ case} {
+ string match {*ab\\*} {ab\c}
+} 1
+test string-11.39.5 {string match, *\ case} {
+ string match {*ab\\*} {ab\*}
+} 1
+test string-11.40 {string match, *special case} {
+ string match {*[ab]} abc
+} 0
+test string-11.41 {string match, *special case} {
+ string match {*[ab]*} abc
+} 1
+test string-11.42 {string match, *special case} {
+ string match "*\\" "\\"
+} 0
+test string-11.43 {string match, *special case} {
+ string match "*\\\\" "\\"
+} 1
+test string-11.44 {string match, *special case} {
+ string match "*???" "12345"
+} 1
+test string-11.45 {string match, *special case} {
+ string match "*???" "12"
+} 0
+test string-11.46 {string match, *special case} {
+ string match "*\\*" "abc*"
+} 1
+test string-11.47 {string match, *special case} {
+ string match "*\\*" "*"
+} 1
+test string-11.48 {string match, *special case} {
+ string match "*\\*" "*abc"
+} 0
+test string-11.49 {string match, *special case} {
+ string match "?\\*" "a*"
+} 1
+test string-11.50 {string match, *special case} {
+ string match "\\" "\\"
+} 0
+test string-11.51 {string match; *, -nocase and UTF-8} {
+ string match -nocase [binary format I 717316707] \
+ [binary format I 2028036707]
+} 1
+test string-11.52 {string match, null char in string} {
+ set out ""
+ set ptn "*abc*"
+ foreach elem [list "\u0000@abc" "@abc" "\u0000@abc\u0000" "blahabcblah"] {
+ lappend out [string match $ptn $elem]
+ }
+ set out
+} {1 1 1 1}
+test string-11.53 {string match, null char in pattern} {
+ set out ""
+ foreach {ptn elem} [list \
+ "*\u0000abc\u0000" "\u0000abc\u0000" \
+ "*\u0000abc\u0000" "\u0000abc\u0000ef" \
+ "*\u0000abc\u0000*" "\u0000abc\u0000ef" \
+ "*\u0000abc\u0000" "@\u0000abc\u0000ef" \
+ "*\u0000abc\u0000*" "@\u0000abc\u0000ef" \
+ ] {
+ lappend out [string match $ptn $elem]
+ }
+ set out
+} {1 0 1 0 1}
+test string-11.54 {string match, failure} {
+ set longString ""
+ for {set i 0} {$i < 10} {incr i} {
+ append longString "abcdefghijklmnopqrstuvwxy\u0000z01234567890123"
+ }
+ string first $longString 123
+ list [string match *cba* $longString] \
+ [string match *a*l*\u0000* $longString] \
+ [string match *a*l*\u0000*123 $longString] \
+ [string match *a*l*\u0000*123* $longString] \
+ [string match *a*l*\u0000*cba* $longString] \
+ [string match *===* $longString]
+} {0 1 1 1 0 0}
+
+test string-12.1 {string range} {
+ list [catch {string range} msg] $msg
+} {1 {wrong # args: should be "string range string first last"}}
+test string-12.2 {string range} {
+ list [catch {string range a 1} msg] $msg
+} {1 {wrong # args: should be "string range string first last"}}
+test string-12.3 {string range} {
+ list [catch {string range a 1 2 3} msg] $msg
+} {1 {wrong # args: should be "string range string first last"}}
+test string-12.4 {string range} {
+ string range abcdefghijklmnop 2 14
+} {cdefghijklmno}
+test string-12.5 {string range, last > length} {
+ string range abcdefghijklmnop 7 1000
+} {hijklmnop}
+test string-12.6 {string range} {
+ string range abcdefghijklmnop 10 end
+} {klmnop}
+test string-12.7 {string range, last < first} {
+ string range abcdefghijklmnop 10 9
+} {}
+test string-12.8 {string range, first < 0} {
+ string range abcdefghijklmnop -3 2
+} {abc}
+test string-12.9 {string range} {
+ string range abcdefghijklmnop -3 -2
+} {}
+test string-12.10 {string range} {
+ string range abcdefghijklmnop 1000 1010
+} {}
+test string-12.11 {string range} {
+ string range abcdefghijklmnop -100 end
+} {abcdefghijklmnop}
+test string-12.12 {string range} {
+ list [catch {string range abc abc 1} msg] $msg
+} {1 {bad index "abc": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-12.13 {string range} {
+ list [catch {string range abc 1 eof} msg] $msg
+} {1 {bad index "eof": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-12.14 {string range} {
+ string range abcdefghijklmnop end-1 end
+} {op}
+test string-12.15 {string range} {
+ string range abcdefghijklmnop end 1000
+} {p}
+test string-12.16 {string range} {
+ string range abcdefghijklmnop end end-1
+} {}
+test string-12.17 {string range, unicode} {
+ string range ab\u7266cdefghijklmnop 5 5
+} e
+test string-12.18 {string range, unicode} {
+ string range ab\u7266cdefghijklmnop 2 3
+} \u7266c
+test string-12.19 {string range, bytearray object} {
+ set b [binary format I* {0x50515253 0x52}]
+ set r1 [string range $b 1 end-1]
+ set r2 [string range $b 1 6]
+ string equal $r1 $r2
+} 1
+test string-12.20 {string range, out of bounds indices} {
+ string range \u00ff 0 1
+} \u00ff
+# Bug 1410553
+test string-12.21 {string range, regenerates correct reps, bug 1410553} {
+ set bytes "\x00 \x03 \x41"
+ set rxBuffer {}
+ foreach ch $bytes {
+ append rxBuffer $ch
+ if {$ch eq "\x03"} {
+ string length $rxBuffer
+ }
+ }
+ set rxCRC [string range $rxBuffer end-1 end]
+ binary scan [join $bytes {}] "H*" input_hex
+ binary scan $rxBuffer "H*" rxBuffer_hex
+ binary scan $rxCRC "H*" rxCRC_hex
+ list $input_hex $rxBuffer_hex $rxCRC_hex
+} {000341 000341 0341}
+test string-12.22 {string range, shimmering binary/index} {
+ set s 0000000001
+ binary scan $s a* x
+ string range $s $s end
+} 000000001
+
+test string-13.1 {string repeat} {
+ list [catch {string repeat} msg] $msg
+} {1 {wrong # args: should be "string repeat string count"}}
+test string-13.2 {string repeat} {
+ list [catch {string repeat abc 10 oops} msg] $msg
+} {1 {wrong # args: should be "string repeat string count"}}
+test string-13.3 {string repeat} {
+ string repeat {} 100
+} {}
+test string-13.4 {string repeat} {
+ string repeat { } 5
+} { }
+test string-13.5 {string repeat} {
+ string repeat abc 3
+} {abcabcabc}
+test string-13.6 {string repeat} {
+ string repeat abc -1
+} {}
+test string-13.7 {string repeat} {
+ list [catch {string repeat abc end} msg] $msg
+} {1 {expected integer but got "end"}}
+test string-13.8 {string repeat} {
+ string repeat {} -1000
+} {}
+test string-13.9 {string repeat} {
+ string repeat {} 0
+} {}
+test string-13.10 {string repeat} {
+ string repeat def 0
+} {}
+test string-13.11 {string repeat} {
+ string repeat def 1
+} def
+test string-13.12 {string repeat} {
+ string repeat ab\u7266cd 3
+} ab\u7266cdab\u7266cdab\u7266cd
+test string-13.13 {string repeat} {
+ string repeat \x00 3
+} \x00\x00\x00
+test string-13.14 {string repeat} {
+ # The string range will ensure us that string repeat gets a unicode string
+ string repeat [string range ab\u7266cd 2 3] 3
+} \u7266c\u7266c\u7266c
+
+test string-14.1 {string replace} {
+ list [catch {string replace} msg] $msg
+} {1 {wrong # args: should be "string replace string first last ?string?"}}
+test string-14.2 {string replace} {
+ list [catch {string replace a 1} msg] $msg
+} {1 {wrong # args: should be "string replace string first last ?string?"}}
+test string-14.3 {string replace} {
+ list [catch {string replace a 1 2 3 4} msg] $msg
+} {1 {wrong # args: should be "string replace string first last ?string?"}}
+test string-14.4 {string replace} {
+} {}
+test string-14.5 {string replace} {
+ string replace abcdefghijklmnop 2 14
+} {abp}
+test string-14.6 {string replace} {
+ string replace abcdefghijklmnop 7 1000
+} {abcdefg}
+test string-14.7 {string replace} {
+ string replace abcdefghijklmnop 10 end
+} {abcdefghij}
+test string-14.8 {string replace} {
+ string replace abcdefghijklmnop 10 9
+} {abcdefghijklmnop}
+test string-14.9 {string replace} {
+ string replace abcdefghijklmnop -3 2
+} {defghijklmnop}
+test string-14.10 {string replace} {
+ string replace abcdefghijklmnop -3 -2
+} {abcdefghijklmnop}
+test string-14.11 {string replace} {
+ string replace abcdefghijklmnop 1000 1010
+} {abcdefghijklmnop}
+test string-14.12 {string replace} {
+ string replace abcdefghijklmnop -100 end
+} {}
+test string-14.13 {string replace} {
+ list [catch {string replace abc abc 1} msg] $msg
+} {1 {bad index "abc": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-14.14 {string replace} {
+ list [catch {string replace abc 1 eof} msg] $msg
+} {1 {bad index "eof": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-14.15 {string replace} {
+ string replace abcdefghijklmnop end-10 end-2 NEW
+} {abcdeNEWop}
+test string-14.16 {string replace} {
+ string replace abcdefghijklmnop 0 end foo
+} {foo}
+test string-14.17 {string replace} {
+ string replace abcdefghijklmnop end end-1
+} {abcdefghijklmnop}
+
+test string-15.1 {string tolower too few args} {
+ list [catch {string tolower} msg] $msg
+} {1 {wrong # args: should be "string tolower string ?first? ?last?"}}
+test string-15.2 {string tolower bad args} {
+ list [catch {string tolower a b} msg] $msg
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-15.3 {string tolower too many args} {
+ list [catch {string tolower ABC 1 end oops} msg] $msg
+} {1 {wrong # args: should be "string tolower string ?first? ?last?"}}
+test string-15.4 {string tolower} {
+ string tolower ABCDeF
+} {abcdef}
+test string-15.5 {string tolower} {
+ string tolower "ABC XyZ"
+} {abc xyz}
+test string-15.6 {string tolower} {
+ string tolower {123#$&*()}
+} {123#$&*()}
+test string-15.7 {string tolower} {
+ string tolower ABC 1
+} AbC
+test string-15.8 {string tolower} {
+ string tolower ABC 1 end
+} Abc
+test string-15.9 {string tolower} {
+ string tolower ABC 0 end-1
+} abC
+test string-15.10 {string tolower, unicode} {
+ string tolower ABCabc\xc7\xe7
+} "abcabc\xe7\xe7"
+
+test string-16.1 {string toupper} {
+ list [catch {string toupper} msg] $msg
+} {1 {wrong # args: should be "string toupper string ?first? ?last?"}}
+test string-16.2 {string toupper} {
+ list [catch {string toupper a b} msg] $msg
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-16.3 {string toupper} {
+ list [catch {string toupper a 1 end oops} msg] $msg
+} {1 {wrong # args: should be "string toupper string ?first? ?last?"}}
+test string-16.4 {string toupper} {
+ string toupper abCDEf
+} {ABCDEF}
+test string-16.5 {string toupper} {
+ string toupper "abc xYz"
+} {ABC XYZ}
+test string-16.6 {string toupper} {
+ string toupper {123#$&*()}
+} {123#$&*()}
+test string-16.7 {string toupper} {
+ string toupper abc 1
+} aBc
+test string-16.8 {string toupper} {
+ string toupper abc 1 end
+} aBC
+test string-16.9 {string toupper} {
+ string toupper abc 0 end-1
+} ABc
+test string-16.10 {string toupper, unicode} {
+ string toupper ABCabc\xc7\xe7
+} "ABCABC\xc7\xc7"
+
+test string-17.1 {string totitle} {
+ list [catch {string totitle} msg] $msg
+} {1 {wrong # args: should be "string totitle string ?first? ?last?"}}
+test string-17.2 {string totitle} {
+ list [catch {string totitle a b} msg] $msg
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-17.3 {string totitle} {
+ string totitle abCDEf
+} {Abcdef}
+test string-17.4 {string totitle} {
+ string totitle "abc xYz"
+} {Abc xyz}
+test string-17.5 {string totitle} {
+ string totitle {123#$&*()}
+} {123#$&*()}
+test string-17.6 {string totitle, unicode} {
+ string totitle ABCabc\xc7\xe7
+} "Abcabc\xe7\xe7"
+test string-17.7 {string totitle, unicode} {
+ string totitle \u01f3BCabc\xc7\xe7
+} "\u01f2bcabc\xe7\xe7"
+
+test string-18.1 {string trim} {
+ list [catch {string trim} msg] $msg
+} {1 {wrong # args: should be "string trim string ?chars?"}}
+test string-18.2 {string trim} {
+ list [catch {string trim a b c} msg] $msg
+} {1 {wrong # args: should be "string trim string ?chars?"}}
+test string-18.3 {string trim} {
+ string trim " XYZ "
+} {XYZ}
+test string-18.4 {string trim} {
+ string trim "\t\nXYZ\t\n\r\n"
+} {XYZ}
+test string-18.5 {string trim} {
+ string trim " A XYZ A "
+} {A XYZ A}
+test string-18.6 {string trim} {
+ string trim "XXYYZZABC XXYYZZ" ZYX
+} {ABC }
+test string-18.7 {string trim} {
+ string trim " \t\r "
+} {}
+test string-18.8 {string trim} {
+ string trim {abcdefg} {}
+} {abcdefg}
+test string-18.9 {string trim} {
+ string trim {}
+} {}
+test string-18.10 {string trim} {
+ string trim ABC DEF
+} {ABC}
+test string-18.11 {string trim, unicode} {
+ string trim "\xe7\xe8 AB\xe7C \xe8\xe7" \xe7\xe8
+} " AB\xe7C "
+test string-18.12 {string trim, unicode default} {
+ string trim ABC\u1361\u1680\u3000
+} ABC
+
+test string-19.1 {string trimleft} {
+ list [catch {string trimleft} msg] $msg
+} {1 {wrong # args: should be "string trimleft string ?chars?"}}
+test string-19.2 {string trimleft} {
+ string trimleft " XYZ "
+} {XYZ }
+test string-19.3 {string trimleft, unicode default} {
+ string trimleft \u1361\u1680\u3000ABC
+} ABC
+
+test string-20.1 {string trimright errors} {
+ list [catch {string trimright} msg] $msg
+} {1 {wrong # args: should be "string trimright string ?chars?"}}
+test string-20.2 {string trimright errors} {
+ list [catch {string trimg a} msg] $msg
+} {1 {unknown or ambiguous subcommand "trimg": must be bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}}
+test string-20.3 {string trimright} {
+ string trimright " XYZ "
+} { XYZ}
+test string-20.4 {string trimright} {
+ string trimright " "
+} {}
+test string-20.5 {string trimright} {
+ string trimright ""
+} {}
+test string-20.6 {string trimright, unicode default} {
+ string trimright ABC\u1361\u1680\u3000
+} ABC
+
+test string-21.1 {string wordend} {
+ list [catch {string wordend a} msg] $msg
+} {1 {wrong # args: should be "string wordend string index"}}
+test string-21.2 {string wordend} {
+ list [catch {string wordend a b c} msg] $msg
+} {1 {wrong # args: should be "string wordend string index"}}
+test string-21.3 {string wordend} {
+ list [catch {string wordend a gorp} msg] $msg
+} {1 {bad index "gorp": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-21.4 {string wordend} {
+ string wordend abc. -1
+} 3
+test string-21.5 {string wordend} {
+ string wordend abc. 100
+} 4
+test string-21.6 {string wordend} {
+ string wordend "word_one two three" 2
+} 8
+test string-21.7 {string wordend} {
+ string wordend "one .&# three" 5
+} 6
+test string-21.8 {string wordend} {
+ string worde "x.y" 0
+} 1
+test string-21.9 {string wordend} {
+ string worde "x.y" end-1
+} 2
+test string-21.10 {string wordend, unicode} {
+ string wordend "xyz\u00c7de fg" 0
+} 6
+test string-21.11 {string wordend, unicode} {
+ string wordend "xyz\uc700de fg" 0
+} 6
+test string-21.12 {string wordend, unicode} {
+ string wordend "xyz\u203fde fg" 0
+} 6
+test string-21.13 {string wordend, unicode} {
+ string wordend "xyz\u2045de fg" 0
+} 3
+test string-21.14 {string wordend, unicode} {
+ string wordend "\uc700\uc700 abc" 8
+} 6
+
+test string-22.1 {string wordstart} {
+ list [catch {string word a} msg] $msg
+} {1 {unknown or ambiguous subcommand "word": must be bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}}
+test string-22.2 {string wordstart} {
+ list [catch {string wordstart a} msg] $msg
+} {1 {wrong # args: should be "string wordstart string index"}}
+test string-22.3 {string wordstart} {
+ list [catch {string wordstart a b c} msg] $msg
+} {1 {wrong # args: should be "string wordstart string index"}}
+test string-22.4 {string wordstart} {
+ list [catch {string wordstart a gorp} msg] $msg
+} {1 {bad index "gorp": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-22.5 {string wordstart} {
+ string wordstart "one two three_words" 400
+} 8
+test string-22.6 {string wordstart} {
+ string wordstart "one two three_words" 2
+} 0
+test string-22.7 {string wordstart} {
+ string wordstart "one two three_words" -2
+} 0
+test string-22.8 {string wordstart} {
+ string wordstart "one .*&^ three" 6
+} 6
+test string-22.9 {string wordstart} {
+ string wordstart "one two three" 4
+} 4
+test string-22.10 {string wordstart} {
+ string wordstart "one two three" end-5
+} 7
+test string-22.11 {string wordstart, unicode} {
+ string wordstart "one tw\u00c7o three" 7
+} 4
+test string-22.12 {string wordstart, unicode} {
+ string wordstart "ab\uc700\uc700 cdef ghi" 12
+} 10
+test string-22.13 {string wordstart, unicode} {
+ string wordstart "\uc700\uc700 abc" 8
+} 3
+
+test string-23.0 {string is boolean, Bug 1187123} testindexobj {
+ set x 5
+ catch {testindexobj $x foo bar soom}
+ string is boolean $x
+} 0
+test string-23.1 {string is command with empty string} {
+ set s ""
+ list \
+ [string is alnum $s] \
+ [string is alpha $s] \
+ [string is ascii $s] \
+ [string is control $s] \
+ [string is boolean $s] \
+ [string is digit $s] \
+ [string is double $s] \
+ [string is false $s] \
+ [string is graph $s] \
+ [string is integer $s] \
+ [string is lower $s] \
+ [string is print $s] \
+ [string is punct $s] \
+ [string is space $s] \
+ [string is true $s] \
+ [string is upper $s] \
+ [string is wordchar $s] \
+ [string is xdigit $s] \
+
+} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1}
+test string-23.2 {string is command with empty string} {
+ set s ""
+ list \
+ [string is alnum -strict $s] \
+ [string is alpha -strict $s] \
+ [string is ascii -strict $s] \
+ [string is control -strict $s] \
+ [string is boolean -strict $s] \
+ [string is digit -strict $s] \
+ [string is double -strict $s] \
+ [string is false -strict $s] \
+ [string is graph -strict $s] \
+ [string is integer -strict $s] \
+ [string is lower -strict $s] \
+ [string is print -strict $s] \
+ [string is punct -strict $s] \
+ [string is space -strict $s] \
+ [string is true -strict $s] \
+ [string is upper -strict $s] \
+ [string is wordchar -strict $s] \
+ [string is xdigit -strict $s] \
+
+} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}
+
+test string-24.1 {string reverse command} -body {
+ string reverse
+} -returnCodes error -result "wrong # args: should be \"string reverse string\""
+test string-24.2 {string reverse command} -body {
+ string reverse a b
+} -returnCodes error -result "wrong # args: should be \"string reverse string\""
+test string-24.3 {string reverse command - shared string} {
+ set x abcde
+ string reverse $x
+} edcba
+test string-24.4 {string reverse command - unshared string} {
+ set x abc
+ set y de
+ string reverse $x$y
+} edcba
+test string-24.5 {string reverse command - shared unicode string} {
+ set x abcde\udead
+ string reverse $x
+} \udeadedcba
+test string-24.6 {string reverse command - unshared string} {
+ set x abc
+ set y de\udead
+ string reverse $x$y
+} \udeadedcba
+test string-24.7 {string reverse command - simple case} {
+ string reverse a
+} a
+test string-24.8 {string reverse command - simple case} {
+ string reverse \udead
+} \udead
+test string-24.9 {string reverse command - simple case} {
+ string reverse {}
+} {}
+test string-24.10 {string reverse command - corner case} {
+ set x \ubeef\udead
+ string reverse $x
+} \udead\ubeef
+test string-24.11 {string reverse command - corner case} {
+ set x \ubeef
+ set y \udead
+ string reverse $x$y
+} \udead\ubeef
+test string-24.12 {string reverse command - corner case} {
+ set x \ubeef
+ set y \udead
+ string is ascii [string reverse $x$y]
+} 0
+test string-24.13 {string reverse command - pure Unicode string} {
+ string reverse [string range \ubeef\udead\ubeef\udead\ubeef\udead 1 5]
+} \udead\ubeef\udead\ubeef\udead
+test string-24.14 {string reverse command - pure bytearray} {
+ binary scan [string reverse [binary format H* 010203]] H* x
+ set x
+} 030201
+test string-24.15 {string reverse command - pure bytearray} {
+ binary scan [tcl::string::reverse [binary format H* 010203]] H* x
+ set x
+} 030201
+
+test string-25.1 {string is list} {
+ string is list {a b c}
+} 1
+test string-25.2 {string is list} {
+ string is list "a \{b c"
+} 0
+test string-25.3 {string is list} {
+ string is list {a {b c}d e}
+} 0
+test string-25.4 {string is list} {
+ string is list {}
+} 1
+test string-25.5 {string is list} {
+ string is list -strict {a b c}
+} 1
+test string-25.6 {string is list} {
+ string is list -strict "a \{b c"
+} 0
+test string-25.7 {string is list} {
+ string is list -strict {a {b c}d e}
+} 0
+test string-25.8 {string is list} {
+ string is list -strict {}
+} 1
+test string-25.9 {string is list} {
+ set x {}
+ list [string is list -failindex x {a b c}] $x
+} {1 {}}
+test string-25.10 {string is list} {
+ set x {}
+ list [string is list -failindex x "a \{b c"] $x
+} {0 2}
+test string-25.11 {string is list} {
+ set x {}
+ list [string is list -failindex x {a b {b c}d e}] $x
+} {0 4}
+test string-25.12 {string is list} {
+ set x {}
+ list [string is list -failindex x {}] $x
+} {1 {}}
+test string-25.13 {string is list} {
+ set x {}
+ list [string is list -failindex x { {b c}d e}] $x
+} {0 2}
+test string-25.14 {string is list} {
+ set x {}
+ list [string is list -failindex x "\uabcd {b c}d e"] $x
+} {0 2}
+
+test string-26.1 {tcl::prefix, too few args} -body {
+ tcl::prefix match a
+} -returnCodes 1 -result {wrong # args: should be "tcl::prefix match ?options? table string"}
+test string-26.2 {tcl::prefix, bad args} -body {
+ tcl::prefix match a b c
+} -returnCodes 1 -result {bad option "a": must be -error, -exact, or -message}
+test string-26.2.1 {tcl::prefix, empty table} -body {
+ tcl::prefix match {} foo
+} -returnCodes 1 -result {bad option "foo": no valid options}
+test string-26.3 {tcl::prefix, bad args} -body {
+ tcl::prefix match -error "{}x" -exact str1 str2
+} -returnCodes 1 -result {list element in braces followed by "x" instead of space}
+test string-26.3.1 {tcl::prefix, bad args} -body {
+ tcl::prefix match -error "x" -exact str1 str2
+} -returnCodes 1 -result {error options must have an even number of elements}
+test string-26.3.2 {tcl::prefix, bad args} -body {
+ tcl::prefix match -error str1 str2
+} -returnCodes 1 -result {missing error options}
+test string-26.4 {tcl::prefix, bad args} -body {
+ tcl::prefix match -message str1 str2
+} -returnCodes 1 -result {missing message}
+test string-26.5 {tcl::prefix} {
+ tcl::prefix match {apa bepa cepa depa} cepa
+} cepa
+test string-26.6 {tcl::prefix} {
+ tcl::prefix match {apa bepa cepa depa} be
+} bepa
+test string-26.7 {tcl::prefix} -body {
+ tcl::prefix match -exact {apa bepa cepa depa} be
+} -returnCodes 1 -result {bad option "be": must be apa, bepa, cepa, or depa}
+test string-26.8 {tcl::prefix} -body {
+ tcl::prefix match -message switch {apa bepa bear depa} be
+} -returnCodes 1 -result {ambiguous switch "be": must be apa, bepa, bear, or depa}
+test string-26.9 {tcl::prefix} -body {
+ tcl::prefix match -error {} {apa bepa bear depa} be
+} -returnCodes 0 -result {}
+test string-26.10 {tcl::prefix} -body {
+ tcl::prefix match -error {-level 1} {apa bepa bear depa} be
+} -returnCodes 2 -result {ambiguous option "be": must be apa, bepa, bear, or depa}
+test string-26.10.1 {tcl::prefix} -setup {
+ proc _testprefix {args} {
+ array set opts {-a x -b y -c y}
+ foreach {opt val} $args {
+ set opt [tcl::prefix match -error {-level 1} {-a -b -c} $opt]
+ set opts($opt) $val
+ }
+ array get opts
+ }
+} -body {
+ set a [catch {_testprefix -x u} result options]
+ dict get $options -errorinfo
+} -cleanup {
+ rename _testprefix {}
+} -result {bad option "-x": must be -a, -b, or -c
+ while executing
+"_testprefix -x u"}
+
+# Helper for memory stress tests
+# Repeat each body in a local space checking that memory does not increase
+proc MemStress {args} {
+ set res {}
+ foreach body $args {
+ set end 0
+ for {set i 0} {$i < 5} {incr i} {
+ proc MemStress_Body {} $body
+ uplevel 1 MemStress_Body
+ rename MemStress_Body {}
+ set tmp $end
+ set end [lindex [lindex [split [memory info] "\n"] 3] 3]
+ }
+ lappend res [expr {$end - $tmp}]
+ }
+ return $res
+}
+
+test string-26.11 {tcl::prefix: testing for leaks} -body {
+ # This test is made to stress object reference management
+ MemStress {
+ set table {hejj miff gurk}
+ set item [lindex $table 1]
+ # If not careful, this can cause a circular reference
+ # that will cause a leak.
+ tcl::prefix match $table $item
+ } {
+ # A similar case with nested lists
+ set table2 {hejj {miff maff} gurk}
+ set item [lindex [lindex $table2 1] 0]
+ tcl::prefix match $table2 $item
+ } {
+ # A similar case with dict
+ set table3 {hejj {miff maff} gurk2}
+ set item [lindex [dict keys [lindex $table3 1]] 0]
+ tcl::prefix match $table3 $item
+ }
+} -constraints memory -result {0 0 0}
+
+test string-26.12 {tcl::prefix: testing for leaks} -body {
+ # This is a memory leak test in a form that might actually happen
+ # in real code. The shared literal "miff" causes a connection
+ # between the item and the table.
+ MemStress {
+ proc stress1 {item} {
+ set table [list hejj miff gurk]
+ tcl::prefix match $table $item
+ }
+ proc stress2 {} {
+ stress1 miff
+ }
+ stress2
+ rename stress1 {}
+ rename stress2 {}
+ }
+} -constraints memory -result 0
+
+test string-26.13 {tcl::prefix: testing for leaks} -body {
+ # This test is made to stress object reference management
+ MemStress {
+ set table [list hejj miff]
+ set item $table
+ set error $table
+ # Use the same objects in all places
+ catch {
+ tcl::prefix match -error $error $table $item
+ }
+ }
+} -constraints memory -result {0}
+
+test string-27.1 {tcl::prefix all, too few args} -body {
+ tcl::prefix all a
+} -returnCodes 1 -result {wrong # args: should be "tcl::prefix all table string"}
+test string-27.2 {tcl::prefix all, bad args} -body {
+ tcl::prefix all a b c
+} -returnCodes 1 -result {wrong # args: should be "tcl::prefix all table string"}
+test string-27.3 {tcl::prefix all, bad args} -body {
+ tcl::prefix all "{}x" str2
+} -returnCodes 1 -result {list element in braces followed by "x" instead of space}
+test string-27.4 {tcl::prefix all} {
+ tcl::prefix all {apa bepa cepa depa} c
+} cepa
+test string-27.5 {tcl::prefix all} {
+ tcl::prefix all {apa bepa cepa depa} cepa
+} cepa
+test string-27.6 {tcl::prefix all} {
+ tcl::prefix all {apa bepa cepa depa} cepax
+} {}
+test string-27.7 {tcl::prefix all} {
+ tcl::prefix all {apa aska appa} a
+} {apa aska appa}
+test string-27.8 {tcl::prefix all} {
+ tcl::prefix all {apa aska appa} ap
+} {apa appa}
+test string-27.9 {tcl::prefix all} {
+ tcl::prefix all {apa aska appa} p
+} {}
+test string-27.10 {tcl::prefix all} {
+ tcl::prefix all {apa aska appa} {}
+} {apa aska appa}
+
+test string-28.1 {tcl::prefix longest, too few args} -body {
+ tcl::prefix longest a
+} -returnCodes 1 -result {wrong # args: should be "tcl::prefix longest table string"}
+test string-28.2 {tcl::prefix longest, bad args} -body {
+ tcl::prefix longest a b c
+} -returnCodes 1 -result {wrong # args: should be "tcl::prefix longest table string"}
+test string-28.3 {tcl::prefix longest, bad args} -body {
+ tcl::prefix longest "{}x" str2
+} -returnCodes 1 -result {list element in braces followed by "x" instead of space}
+test string-28.4 {tcl::prefix longest} {
+ tcl::prefix longest {apa bepa cepa depa} c
+} cepa
+test string-28.5 {tcl::prefix longest} {
+ tcl::prefix longest {apa bepa cepa depa} cepa
+} cepa
+test string-28.6 {tcl::prefix longest} {
+ tcl::prefix longest {apa bepa cepa depa} cepax
+} {}
+test string-28.7 {tcl::prefix longest} {
+ tcl::prefix longest {apa aska appa} a
+} a
+test string-28.8 {tcl::prefix longest} {
+ tcl::prefix longest {apa aska appa} ap
+} ap
+test string-28.9 {tcl::prefix longest} {
+ tcl::prefix longest {apa bska appa} a
+} ap
+test string-28.10 {tcl::prefix longest} {
+ tcl::prefix longest {apa bska appa} {}
+} {}
+test string-28.11 {tcl::prefix longest} {
+ tcl::prefix longest {{} bska appa} {}
+} {}
+test string-28.12 {tcl::prefix longest} {
+ tcl::prefix longest {apa {} appa} {}
+} {}
+test string-28.13 {tcl::prefix longest} {
+ # Test UTF8 handling
+ tcl::prefix longest {ax\x90 bep ax\x91} a
+} ax
+
+# cleanup
+rename MemStress {}
+catch {rename foo {}}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/stringComp.test b/pkgs/msgcat/tests/stringComp.test
new file mode 100644
index 0000000..ff18819
--- /dev/null
+++ b/pkgs/msgcat/tests/stringComp.test
@@ -0,0 +1,703 @@
+# Commands covered: string
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# This differs from the original string tests in that the tests call
+# things in procs, which uses the compiled string code instead of
+# the runtime parse string code. The tests of import should match
+# their equivalent number in string.test.
+#
+# Copyright (c) 2001 by ActiveState Corporation.
+# Copyright (c) 2001 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# Some tests require the testobj command
+
+testConstraint testobj [expr {[info commands testobj] != {}}]
+
+test stringComp-1.1 {error conditions} {
+ proc foo {} {string gorp a b}
+ list [catch {foo} msg] $msg
+} {1 {unknown or ambiguous subcommand "gorp": must be bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}}
+test stringComp-1.2 {error conditions} {
+ proc foo {} {string}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string subcommand ?arg ...?"}}
+test stringComp-1.3 {error condition - undefined method during compile} {
+ # We don't want this to complain about 'never' because it may never
+ # be called, or string may get redefined. This must compile OK.
+ proc foo {str i} {
+ if {"yes" == "no"} { string never called but complains here }
+ string index $str $i
+ }
+ foo abc 0
+} a
+
+## Test string compare|equal over equal constraints
+## Use result for string compare, and negate it for string equal
+## The body will be tested both in and outside a proc
+set i 0
+foreach {tname tbody tresult tcode} {
+ {too few args} {
+ string compare a
+ } {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"} {error}
+ {bad args} {
+ string compare a b c
+ } {bad option "a": must be -nocase or -length} {error}
+ {bad args} {
+ string compare -length -nocase str1 str2
+ } {expected integer but got "-nocase"} {error}
+ {too many args} {
+ string compare -length 10 -nocase str1 str2 str3
+ } {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"} {error}
+ {compare with length unspecified} {
+ string compare -length 10 10
+ } {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"} {error}
+ {basic operation fail} {
+ string compare abcde abdef
+ } {-1} {}
+ {basic operation success} {
+ string compare abcde abcde
+ } {0} {}
+ {with length} {
+ string compare -length 2 abcde abxyz
+ } {0} {}
+ {with special index} {
+ string compare -length end-3 abcde abxyz
+ } {expected integer but got "end-3"} {error}
+ {unicode} {
+ string compare ab\u7266 ab\u7267
+ } {-1} {}
+ {unicode} {string compare \334 \u00dc} 0 {}
+ {unicode} {string compare \334 \u00fc} -1 {}
+ {unicode} {string compare \334\334\334\374\374 \334\334\334\334\334} 1 {}
+ {high bit} {
+ # This test will fail if the underlying comparaison
+ # is using signed chars instead of unsigned chars.
+ # (like SunOS's default memcmp thus the compat/memcmp.c)
+ string compare "\x80" "@"
+ # Nb this tests works also in utf8 space because \x80 is
+ # translated into a 2 or more bytelength but whose first byte has
+ # the high bit set.
+ } {1} {}
+ {-nocase 1} {string compare -nocase abcde abdef} {-1} {}
+ {-nocase 2} {string compare -nocase abcde Abdef} {-1} {}
+ {-nocase 3} {string compare -nocase abcde ABCDE} {0} {}
+ {-nocase 4} {string compare -nocase abcde abcde} {0} {}
+ {-nocase unicode} {
+ string compare -nocase \334 \u00dc
+ } 0 {}
+ {-nocase unicode} {
+ string compare -nocase \334\334\334\374\u00fc \334\334\334\334\334
+ } 0 {}
+ {-nocase with length} {
+ string compare -length 2 -nocase abcde Abxyz
+ } {0} {}
+ {-nocase with length} {
+ string compare -nocase -length 3 abcde Abxyz
+ } {-1} {}
+ {-nocase with length <= 0} {
+ string compare -nocase -length -1 abcde AbCdEf
+ } {-1} {}
+ {-nocase with excessive length} {
+ string compare -nocase -length 50 AbCdEf abcde
+ } {1} {}
+ {-len unicode} {
+ # These are strings that are 6 BYTELENGTH long, but the length
+ # shouldn't make a different because there are actually 3 CHARS long
+ string compare -len 5 \334\334\334 \334\334\374
+ } -1 {}
+ {-nocase with special index} {
+ string compare -nocase -length end-3 Abcde abxyz
+ } {expected integer but got "end-3"} error
+ {null strings} {
+ string compare "" ""
+ } 0 {}
+ {null strings} {
+ string compare "" foo
+ } -1 {}
+ {null strings} {
+ string compare foo ""
+ } 1 {}
+ {-nocase null strings} {
+ string compare -nocase "" ""
+ } 0 {}
+ {-nocase null strings} {
+ string compare -nocase "" foo
+ } -1 {}
+ {-nocase null strings} {
+ string compare -nocase foo ""
+ } 1 {}
+ {with length, unequal strings} {
+ string compare -length 2 abc abde
+ } 0 {}
+ {with length, unequal strings} {
+ string compare -length 2 ab abde
+ } 0 {}
+ {with NUL character vs. other ASCII} {
+ # Be careful here, since UTF-8 rep comparison with memcmp() of
+ # these puts chars in the wrong order
+ string compare \x00 \x01
+ } -1 {}
+ {high bit} {
+ string compare "a\x80" "a@"
+ } 1 {}
+ {high bit} {
+ string compare "a\x00" "a\x01"
+ } -1 {}
+ {high bit} {
+ string compare "\x00\x00" "\x00\x01"
+ } -1 {}
+ {binary equal} {
+ string compare [binary format a100 0] [binary format a100 0]
+ } 0 {}
+ {binary neq} {
+ string compare [binary format a100a 0 1] [binary format a100a 0 0]
+ } 1 {}
+ {binary neq inequal length} {
+ string compare [binary format a20a 0 1] [binary format a100a 0 0]
+ } 1 {}
+} {
+ if {$tname eq ""} { continue }
+ if {$tcode eq ""} { set tcode ok }
+ test stringComp-2.[incr i] "string compare, $tname" \
+ -body [list eval $tbody] \
+ -returnCodes $tcode -result $tresult
+ test stringComp-2.[incr i] "string compare bc, $tname" \
+ -body "[list proc foo {} $tbody];foo" \
+ -returnCodes $tcode -result $tresult
+ if {"error" ni $tcode} {
+ set tresult [expr {!$tresult}]
+ } else {
+ set tresult [string map {compare equal} $tresult]
+ }
+ set tbody [string map {compare equal} $tbody]
+ test stringComp-2.[incr i] "string equal, $tname" \
+ -body [list eval $tbody] \
+ -returnCodes $tcode -result $tresult
+ test stringComp-2.[incr i] "string equal bc, $tname" \
+ -body "[list proc foo {} $tbody];foo" \
+ -returnCodes $tcode -result $tresult
+}
+
+# need a few extra tests short abbr cmd
+test stringComp-3.1 {string compare, shortest method name} {
+ proc foo {} {string c abcde ABCDE}
+ foo
+} 1
+test stringComp-3.2 {string equal, shortest method name} {
+ proc foo {} {string e abcde ABCDE}
+ foo
+} 0
+test stringComp-3.3 {string equal -nocase} {
+ proc foo {} {string eq -nocase abcde ABCDE}
+ foo
+} 1
+
+test stringComp-4.1 {string first, too few args} {
+ proc foo {} {string first a}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string first needleString haystackString ?startIndex?"}}
+test stringComp-4.2 {string first, bad args} {
+ proc foo {} {string first a b c}
+ list [catch {foo} msg] $msg
+} {1 {bad index "c": must be integer?[+-]integer? or end?[+-]integer?}}
+test stringComp-4.3 {string first, too many args} {
+ proc foo {} {string first a b 5 d}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string first needleString haystackString ?startIndex?"}}
+test stringComp-4.4 {string first} {
+ proc foo {} {string first bq abcdefgbcefgbqrs}
+ foo
+} 12
+test stringComp-4.5 {string first} {
+ proc foo {} {string fir bcd abcdefgbcefgbqrs}
+ foo
+} 1
+test stringComp-4.6 {string first} {
+ proc foo {} {string f b abcdefgbcefgbqrs}
+ foo
+} 1
+test stringComp-4.7 {string first} {
+ proc foo {} {string first xxx x123xx345xxx789xxx012}
+ foo
+} 9
+test stringComp-4.8 {string first} {
+ proc foo {} {string first "" x123xx345xxx789xxx012}
+ foo
+} -1
+test stringComp-4.9 {string first, unicode} {
+ proc foo {} {string first x abc\u7266x}
+ foo
+} 4
+test stringComp-4.10 {string first, unicode} {
+ proc foo {} {string first \u7266 abc\u7266x}
+ foo
+} 3
+test stringComp-4.11 {string first, start index} {
+ proc foo {} {string first \u7266 abc\u7266x 3}
+ foo
+} 3
+test stringComp-4.12 {string first, start index} {
+ proc foo {} {string first \u7266 abc\u7266x 4}
+ foo
+} -1
+test stringComp-4.13 {string first, start index} {
+ proc foo {} {string first \u7266 abc\u7266x end-2}
+ foo
+} 3
+test stringComp-4.14 {string first, negative start index} {
+ proc foo {} {string first b abc -1}
+ foo
+} 1
+
+test stringComp-5.1 {string index} {
+ proc foo {} {string index}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string index string charIndex"}}
+test stringComp-5.2 {string index} {
+ proc foo {} {string index a b c}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string index string charIndex"}}
+test stringComp-5.3 {string index} {
+ proc foo {} {string index abcde 0}
+ foo
+} a
+test stringComp-5.4 {string index} {
+ proc foo {} {string in abcde 4}
+ foo
+} e
+test stringComp-5.5 {string index} {
+ proc foo {} {string index abcde 5}
+ foo
+} {}
+test stringComp-5.6 {string index} {
+ proc foo {} {string index abcde -10}
+ list [catch {foo} msg] $msg
+} {0 {}}
+test stringComp-5.7 {string index} {
+ proc foo {} {string index a xyz}
+ list [catch {foo} msg] $msg
+} {1 {bad index "xyz": must be integer?[+-]integer? or end?[+-]integer?}}
+test stringComp-5.8 {string index} {
+ proc foo {} {string index abc end}
+ foo
+} c
+test stringComp-5.9 {string index} {
+ proc foo {} {string index abc end-1}
+ foo
+} b
+test stringComp-5.10 {string index, unicode} {
+ proc foo {} {string index abc\u7266d 4}
+ foo
+} d
+test stringComp-5.11 {string index, unicode} {
+ proc foo {} {string index abc\u7266d 3}
+ foo
+} \u7266
+test stringComp-5.12 {string index, unicode over char length, under byte length} {
+ proc foo {} {string index \334\374\334\374 6}
+ foo
+} {}
+test stringComp-5.13 {string index, bytearray object} {
+ proc foo {} {string index [binary format a5 fuz] 0}
+ foo
+} f
+test stringComp-5.14 {string index, bytearray object} {
+ proc foo {} {string index [binary format I* {0x50515253 0x52}] 3}
+ foo
+} S
+test stringComp-5.15 {string index, bytearray object} {
+ proc foo {} {
+ set b [binary format I* {0x50515253 0x52}]
+ set i1 [string index $b end-6]
+ set i2 [string index $b 1]
+ string compare $i1 $i2
+ }
+ foo
+} 0
+test stringComp-5.16 {string index, bytearray object with string obj shimmering} {
+ proc foo {} {
+ set str "0123456789\x00 abcdedfghi"
+ binary scan $str H* dump
+ string compare [string index $str 10] \x00
+ }
+ foo
+} 0
+test stringComp-5.17 {string index, bad integer} -body {
+ proc foo {} {string index "abc" 0o8}
+ list [catch {foo} msg] $msg
+} -match glob -result {1 {*invalid octal number*}}
+test stringComp-5.18 {string index, bad integer} -body {
+ proc foo {} {string index "abc" end-0o0289}
+ list [catch {foo} msg] $msg
+} -match glob -result {1 {*invalid octal number*}}
+test stringComp-5.19 {string index, bytearray object out of bounds} {
+ proc foo {} {string index [binary format I* {0x50515253 0x52}] -1}
+ foo
+} {}
+test stringComp-5.20 {string index, bytearray object out of bounds} {
+ proc foo {} {string index [binary format I* {0x50515253 0x52}] 20}
+ foo
+} {}
+
+
+proc largest_int {} {
+ # This will give us what the largest valid int on this machine is,
+ # so we can test for overflow properly below on >32 bit systems
+ set int 1
+ set exp 7; # assume we get at least 8 bits
+ while {$int > 0} { set int [expr {1 << [incr exp]}] }
+ return [expr {$int-1}]
+}
+
+## string is
+## not yet bc
+
+catch {rename largest_int {}}
+
+## string last
+## not yet bc
+
+## string length
+## not yet bc
+test stringComp-8.1 {string bytelength} {
+ proc foo {} {string bytelength}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string bytelength string"}}
+test stringComp-8.2 {string bytelength} {
+ proc foo {} {string bytelength a b}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string bytelength string"}}
+test stringComp-8.3 {string bytelength} {
+ proc foo {} {string bytelength "\u00c7"}
+ foo
+} 2
+test stringComp-8.4 {string bytelength} {
+ proc foo {} {string b ""}
+ foo
+} 0
+
+## string length
+##
+test stringComp-9.1 {string length} {
+ proc foo {} {string length}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string length string"}}
+test stringComp-9.2 {string length} {
+ proc foo {} {string length a b}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string length string"}}
+test stringComp-9.3 {string length} {
+ proc foo {} {string length "a little string"}
+ foo
+} 15
+test stringComp-9.4 {string length} {
+ proc foo {} {string le ""}
+ foo
+} 0
+test stringComp-9.5 {string length, unicode} {
+ proc foo {} {string le "abcd\u7266"}
+ foo
+} 5
+test stringComp-9.6 {string length, bytearray object} {
+ proc foo {} {string length [binary format a5 foo]}
+ foo
+} 5
+test stringComp-9.7 {string length, bytearray object} {
+ proc foo {} {string length [binary format I* {0x50515253 0x52}]}
+ foo
+} 8
+
+## string map
+## not yet bc
+
+## string match
+##
+test stringComp-11.1 {string match, too few args} {
+ proc foo {} {string match a}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string match ?-nocase? pattern string"}}
+test stringComp-11.2 {string match, too many args} {
+ proc foo {} {string match a b c d}
+ list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string match ?-nocase? pattern string"}}
+test stringComp-11.3 {string match} {
+ proc foo {} {string match abc abc}
+ foo
+} 1
+test stringComp-11.4 {string match} {
+ proc foo {} {string mat abc abd}
+ foo
+} 0
+test stringComp-11.5 {string match} {
+ proc foo {} {string match ab*c abc}
+ foo
+} 1
+test stringComp-11.6 {string match} {
+ proc foo {} {string match ab**c abc}
+ foo
+} 1
+test stringComp-11.7 {string match} {
+ proc foo {} {string match ab* abcdef}
+ foo
+} 1
+test stringComp-11.8 {string match} {
+ proc foo {} {string match *c abc}
+ foo
+} 1
+test stringComp-11.9 {string match} {
+ proc foo {} {string match *3*6*9 0123456789}
+ foo
+} 1
+test stringComp-11.10 {string match} {
+ proc foo {} {string match *3*6*9 01234567890}
+ foo
+} 0
+test stringComp-11.11 {string match} {
+ proc foo {} {string match a?c abc}
+ foo
+} 1
+test stringComp-11.12 {string match} {
+ proc foo {} {string match a??c abc}
+ foo
+} 0
+test stringComp-11.13 {string match} {
+ proc foo {} {string match ?1??4???8? 0123456789}
+ foo
+} 1
+test stringComp-11.14 {string match} {
+ proc foo {} {string match {[abc]bc} abc}
+ foo
+} 1
+test stringComp-11.15 {string match} {
+ proc foo {} {string match {a[abc]c} abc}
+ foo
+} 1
+test stringComp-11.16 {string match} {
+ proc foo {} {string match {a[xyz]c} abc}
+ foo
+} 0
+test stringComp-11.17 {string match} {
+ proc foo {} {string match {12[2-7]45} 12345}
+ foo
+} 1
+test stringComp-11.18 {string match} {
+ proc foo {} {string match {12[ab2-4cd]45} 12345}
+ foo
+} 1
+test stringComp-11.19 {string match} {
+ proc foo {} {string match {12[ab2-4cd]45} 12b45}
+ foo
+} 1
+test stringComp-11.20 {string match} {
+ proc foo {} {string match {12[ab2-4cd]45} 12d45}
+ foo
+} 1
+test stringComp-11.21 {string match} {
+ proc foo {} {string match {12[ab2-4cd]45} 12145}
+ foo
+} 0
+test stringComp-11.22 {string match} {
+ proc foo {} {string match {12[ab2-4cd]45} 12545}
+ foo
+} 0
+test stringComp-11.23 {string match} {
+ proc foo {} {string match {a\*b} a*b}
+ foo
+} 1
+test stringComp-11.24 {string match} {
+ proc foo {} {string match {a\*b} ab}
+ foo
+} 0
+test stringComp-11.25 {string match} {
+ proc foo {} {string match {a\*\?\[\]\\\x} "a*?\[\]\\x"}
+ foo
+} 1
+test stringComp-11.26 {string match} {
+ proc foo {} {string match ** ""}
+ foo
+} 1
+test stringComp-11.27 {string match} {
+ proc foo {} {string match *. ""}
+ foo
+} 0
+test stringComp-11.28 {string match} {
+ proc foo {} {string match "" ""}
+ foo
+} 1
+test stringComp-11.29 {string match} {
+ proc foo {} {string match \[a a}
+ foo
+} 1
+test stringComp-11.30 {string match, bad args} {
+ proc foo {} {string match - b c}
+ list [catch {foo} msg] $msg
+} {1 {bad option "-": must be -nocase}}
+test stringComp-11.31 {string match case} {
+ proc foo {} {string match a A}
+ foo
+} 0
+test stringComp-11.32 {string match nocase} {
+ proc foo {} {string match -n a A}
+ foo
+} 1
+test stringComp-11.33 {string match nocase} {
+ proc foo {} {string match -nocase a\334 A\374}
+ foo
+} 1
+test stringComp-11.34 {string match nocase} {
+ proc foo {} {string match -nocase a*f ABCDEf}
+ foo
+} 1
+test stringComp-11.35 {string match case, false hope} {
+ # This is true because '_' lies between the A-Z and a-z ranges
+ proc foo {} {string match {[A-z]} _}
+ foo
+} 1
+test stringComp-11.36 {string match nocase range} {
+ # This is false because although '_' lies between the A-Z and a-z ranges,
+ # we lower case the end points before checking the ranges.
+ proc foo {} {string match -nocase {[A-z]} _}
+ foo
+} 0
+test stringComp-11.37 {string match nocase} {
+ proc foo {} {string match -nocase {[A-fh-Z]} g}
+ foo
+} 0
+test stringComp-11.38 {string match case, reverse range} {
+ proc foo {} {string match {[A-fh-Z]} g}
+ foo
+} 1
+test stringComp-11.39 {string match, *\ case} {
+ proc foo {} {string match {*\abc} abc}
+ foo
+} 1
+test stringComp-11.40 {string match, *special case} {
+ proc foo {} {string match {*[ab]} abc}
+ foo
+} 0
+test stringComp-11.41 {string match, *special case} {
+ proc foo {} {string match {*[ab]*} abc}
+ foo
+} 1
+test stringComp-11.42 {string match, *special case} {
+ proc foo {} {string match "*\\" "\\"}
+ foo
+} 0
+test stringComp-11.43 {string match, *special case} {
+ proc foo {} {string match "*\\\\" "\\"}
+ foo
+} 1
+test stringComp-11.44 {string match, *special case} {
+ proc foo {} {string match "*???" "12345"}
+ foo
+} 1
+test stringComp-11.45 {string match, *special case} {
+ proc foo {} {string match "*???" "12"}
+ foo
+} 0
+test stringComp-11.46 {string match, *special case} {
+ proc foo {} {string match "*\\*" "abc*"}
+ foo
+} 1
+test stringComp-11.47 {string match, *special case} {
+ proc foo {} {string match "*\\*" "*"}
+ foo
+} 1
+test stringComp-11.48 {string match, *special case} {
+ proc foo {} {string match "*\\*" "*abc"}
+ foo
+} 0
+test stringComp-11.49 {string match, *special case} {
+ proc foo {} {string match "?\\*" "a*"}
+ foo
+} 1
+test stringComp-11.50 {string match, *special case} {
+ proc foo {} {string match "\\" "\\"}
+ foo
+} 0
+test stringComp-11.51 {string match; *, -nocase and UTF-8} {
+ proc foo {} {string match -nocase [binary format I 717316707] \
+ [binary format I 2028036707]}
+ foo
+} 1
+test stringComp-11.52 {string match, null char in string} {
+ proc foo {} {
+ set ptn "*abc*"
+ foreach elem [list "\u0000@abc" "@abc" "\u0000@abc\u0000" "blahabcblah"] {
+ lappend out [string match $ptn $elem]
+ }
+ set out
+ }
+ foo
+} {1 1 1 1}
+test stringComp-11.53 {string match, null char in pattern} {
+ proc foo {} {
+ set out ""
+ foreach {ptn elem} [list \
+ "*\u0000abc\u0000" "\u0000abc\u0000" \
+ "*\u0000abc\u0000" "\u0000abc\u0000ef" \
+ "*\u0000abc\u0000*" "\u0000abc\u0000ef" \
+ "*\u0000abc\u0000" "@\u0000abc\u0000ef" \
+ "*\u0000abc\u0000*" "@\u0000abc\u0000ef" \
+ ] {
+ lappend out [string match $ptn $elem]
+ }
+ set out
+ }
+ foo
+} {1 0 1 0 1}
+test stringComp-11.54 {string match, failure} {
+ proc foo {} {
+ set longString ""
+ for {set i 0} {$i < 10} {incr i} {
+ append longString "abcdefghijklmnopqrstuvwxy\u0000z01234567890123"
+ }
+ list [string match *cba* $longString] \
+ [string match *a*l*\u0000* $longString] \
+ [string match *a*l*\u0000*123 $longString] \
+ [string match *a*l*\u0000*123* $longString] \
+ [string match *a*l*\u0000*cba* $longString] \
+ [string match *===* $longString]
+ }
+ foo
+} {0 1 1 1 0 0}
+
+## string range
+## not yet bc
+
+## string repeat
+## not yet bc
+
+## string replace
+## not yet bc
+
+## string tolower
+## not yet bc
+
+## string toupper
+## not yet bc
+
+## string totitle
+## not yet bc
+
+## string trim*
+## not yet bc
+
+## string word*
+## not yet bc
+
+# cleanup
+catch {rename foo {}}
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/stringObj.test b/pkgs/msgcat/tests/stringObj.test
new file mode 100644
index 0000000..d93bb82
--- /dev/null
+++ b/pkgs/msgcat/tests/stringObj.test
@@ -0,0 +1,487 @@
+# Commands covered: none
+#
+# This file contains tests for the procedures in tclStringObj.c that implement
+# the Tcl type manager for the string type.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1995-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testobj [llength [info commands testobj]]
+testConstraint testdstring [llength [info commands testdstring]]
+
+test stringObj-1.1 {string type registration} testobj {
+ set t [testobj types]
+ set first [string first "string" $t]
+ set result [expr {$first != -1}]
+} {1}
+
+test stringObj-2.1 {Tcl_NewStringObj} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [teststringobj set 1 abcd]
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} abcd string 2}
+
+test stringObj-3.1 {Tcl_SetStringObj, existing "empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testobj newobj 1]
+ lappend result [teststringobj set 1 xyz] ;# makes existing obj a string
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} {} xyz string 2}
+test stringObj-3.2 {Tcl_SetStringObj, existing non-"empty string" object} testobj {
+ set result ""
+ lappend result [testobj freeallvars]
+ lappend result [testintobj set 1 512]
+ lappend result [teststringobj set 1 foo] ;# makes existing obj a string
+ lappend result [testobj type 1]
+ lappend result [testobj refcount 1]
+} {{} 512 foo string 2}
+
+test stringObj-4.1 {Tcl_SetObjLength procedure, string gets shorter} testobj {
+ testobj freeallvars
+ teststringobj set 1 test
+ teststringobj setlength 1 3
+ list [teststringobj length 1] [teststringobj length2 1] \
+ [teststringobj get 1]
+} {3 4 tes}
+test stringObj-4.2 {Tcl_SetObjLength procedure, string gets longer} testobj {
+ testobj freeallvars
+ teststringobj set 1 abcdef
+ teststringobj setlength 1 10
+ list [teststringobj length 1] [teststringobj length2 1]
+} {10 10}
+test stringObj-4.3 {Tcl_SetObjLength procedure, string gets longer} testobj {
+ testobj freeallvars
+ teststringobj set 1 abcdef
+ teststringobj append 1 xyzq -1
+ list [teststringobj length 1] [teststringobj length2 1] \
+ [teststringobj get 1]
+} {10 20 abcdefxyzq}
+test stringObj-4.4 {Tcl_SetObjLength procedure, "expty string", length 0} testobj {
+ testobj freeallvars
+ testobj newobj 1
+ teststringobj setlength 1 0
+ list [teststringobj length2 1] [teststringobj get 1]
+} {0 {}}
+
+test stringObj-5.1 {Tcl_AppendToObj procedure, type conversion} testobj {
+ testobj freeallvars
+ testintobj set2 1 43
+ teststringobj append 1 xyz -1
+ teststringobj get 1
+} {43xyz}
+test stringObj-5.2 {Tcl_AppendToObj procedure, length calculation} testobj {
+ testobj freeallvars
+ teststringobj set 1 {x y }
+ teststringobj append 1 bbCCddEE 4
+ teststringobj append 1 123 -1
+ teststringobj get 1
+} {x y bbCC123}
+test stringObj-5.3 {Tcl_AppendToObj procedure, reallocating space} testobj {
+ testobj freeallvars
+ teststringobj set 1 xyz
+ teststringobj setlength 1 15
+ teststringobj setlength 1 2
+ set result {}
+ teststringobj append 1 1234567890123 -1
+ lappend result [teststringobj length 1] [teststringobj length2 1]
+ teststringobj setlength 1 10
+ teststringobj append 1 abcdef -1
+ lappend result [teststringobj length 1] [teststringobj length2 1] \
+ [teststringobj get 1]
+} {15 15 16 32 xy12345678abcdef}
+
+test stringObj-6.1 {Tcl_AppendStringsToObj procedure, type conversion} testobj {
+ testobj freeallvars
+ teststringobj set2 1 [list a b]
+ teststringobj appendstrings 1 xyz { 1234 } foo
+ teststringobj get 1
+} {a bxyz 1234 foo}
+test stringObj-6.2 {Tcl_AppendStringsToObj procedure, counting space} testobj {
+ testobj freeallvars
+ teststringobj set 1 abc
+ teststringobj appendstrings 1
+ list [teststringobj length 1] [teststringobj get 1]
+} {3 abc}
+test stringObj-6.3 {Tcl_AppendStringsToObj procedure, counting space} testobj {
+ testobj freeallvars
+ teststringobj set 1 abc
+ teststringobj appendstrings 1 {} {} {} {}
+ list [teststringobj length 1] [teststringobj get 1]
+} {3 abc}
+test stringObj-6.4 {Tcl_AppendStringsToObj procedure, counting space} testobj {
+ testobj freeallvars
+ teststringobj set 1 abc
+ teststringobj appendstrings 1 { 123 } abcdefg
+ list [teststringobj length 1] [teststringobj get 1]
+} {15 {abc 123 abcdefg}}
+test stringObj-6.5 {Tcl_AppendStringsToObj procedure, don't double space if initial string empty} testobj {
+ testobj freeallvars
+ testobj newobj 1
+ teststringobj appendstrings 1 123 abcdefg
+ list [teststringobj length 1] [teststringobj length2 1] [teststringobj get 1]
+} {10 20 123abcdefg}
+test stringObj-6.6 {Tcl_AppendStringsToObj procedure, space reallocation} testobj {
+ testobj freeallvars
+ teststringobj set 1 abc
+ teststringobj setlength 1 10
+ teststringobj setlength 1 2
+ teststringobj appendstrings 1 34567890
+ list [teststringobj length 1] [teststringobj length2 1] \
+ [teststringobj get 1]
+} {10 10 ab34567890}
+test stringObj-6.7 {Tcl_AppendStringsToObj procedure, space reallocation} testobj {
+ testobj freeallvars
+ teststringobj set 1 abc
+ teststringobj setlength 1 10
+ teststringobj setlength 1 2
+ teststringobj appendstrings 1 34567890x
+ list [teststringobj length 1] [teststringobj length2 1] \
+ [teststringobj get 1]
+} {11 22 ab34567890x}
+test stringObj-6.8 {Tcl_AppendStringsToObj procedure, object totally empty} testobj {
+ testobj freeallvars
+ testobj newobj 1
+ teststringobj appendstrings 1 {}
+ list [teststringobj length2 1] [teststringobj get 1]
+} {0 {}}
+test stringObj-6.9 {Tcl_AppendStringToObj, pure unicode} testobj {
+ testobj freeallvars
+ teststringobj set2 1 [string replace abc 1 1 d]
+ teststringobj appendstrings 1 foo bar soom
+ teststringobj get 1
+} adcfoobarsoom
+
+test stringObj-7.1 {SetStringFromAny procedure} testobj {
+ testobj freeallvars
+ teststringobj set2 1 [list a b]
+ teststringobj append 1 x -1
+ list [teststringobj length 1] [teststringobj length2 1] \
+ [teststringobj get 1]
+} {4 8 {a bx}}
+test stringObj-7.2 {SetStringFromAny procedure, null object} testobj {
+ testobj freeallvars
+ testobj newobj 1
+ teststringobj appendstrings 1 {}
+ list [teststringobj length 1] [teststringobj length2 1] \
+ [teststringobj get 1]
+} {0 0 {}}
+test stringObj-7.3 {SetStringFromAny called with non-string obj} testobj {
+ set x 2345
+ list [incr x] [testobj objtype $x] [string index $x end] \
+ [testobj objtype $x]
+} {2346 int 6 string}
+test stringObj-7.4 {SetStringFromAny called with string obj} testobj {
+ set x "abcdef"
+ list [string length $x] [testobj objtype $x] \
+ [string length $x] [testobj objtype $x]
+} {6 string 6 string}
+
+test stringObj-8.1 {DupStringInternalRep procedure} testobj {
+ testobj freeallvars
+ teststringobj set 1 {}
+ teststringobj append 1 abcde -1
+ testobj duplicate 1 2
+ list [teststringobj length 1] [teststringobj length2 1] \
+ [teststringobj maxchars 1] [teststringobj get 1] \
+ [teststringobj length 2] [teststringobj length2 2] \
+ [teststringobj maxchars 2] [teststringobj get 2]
+} {5 10 0 abcde 5 5 0 abcde}
+test stringObj-8.2 {DupUnicodeInternalRep, mixed width chars} testobj {
+ set x abc\u00ef\u00bf\u00aeghi
+ string length $x
+ set y $x
+ list [testobj objtype $x] [testobj objtype $y] [append x "\u00ae\u00bf\u00ef"] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} "string string abc\u00ef\u00bf\u00aeghi\u00ae\u00bf\u00ef abc\u00ef\u00bf\u00aeghi string string"
+test stringObj-8.3 {DupUnicodeInternalRep, mixed width chars} testobj {
+ set x abc\u00ef\u00bf\u00aeghi
+ set y $x
+ string length $x
+ list [testobj objtype $x] [testobj objtype $y] [append x "\u00ae\u00bf\u00ef"] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} "string string abc\u00ef\u00bf\u00aeghi\u00ae\u00bf\u00ef abc\u00ef\u00bf\u00aeghi string string"
+test stringObj-8.4 {DupUnicodeInternalRep, all byte-size chars} testobj {
+ set x abcdefghi
+ string length $x
+ set y $x
+ list [testobj objtype $x] [testobj objtype $y] [append x jkl] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} {string string abcdefghijkl abcdefghi string string}
+test stringObj-8.5 {DupUnicodeInternalRep, all byte-size chars} testobj {
+ set x abcdefghi
+ set y $x
+ string length $x
+ list [testobj objtype $x] [testobj objtype $y] [append x jkl] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} {string string abcdefghijkl abcdefghi string string}
+
+test stringObj-9.1 {TclAppendObjToObj, mixed src & dest} {testobj testdstring} {
+ set x abc\u00ef\u00bf\u00aeghi
+ testdstring free
+ testdstring append \u00ae\u00bf\u00ef -1
+ set y [testdstring get]
+ string length $x
+ list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} "string none abc\u00ef\u00bf\u00aeghi\u00ae\u00bf\u00ef \u00ae\u00bf\u00ef string none"
+test stringObj-9.2 {TclAppendObjToObj, mixed src & dest} testobj {
+ set x abc\u00ef\u00bf\u00aeghi
+ string length $x
+ list [testobj objtype $x] [append x $x] [testobj objtype $x] \
+ [append x $x] [testobj objtype $x]
+} "string abc\u00ef\u00bf\u00aeghiabc\u00ef\u00bf\u00aeghi string\
+abc\u00ef\u00bf\u00aeghiabc\u00ef\u00bf\u00aeghiabc\u00ef\u00bf\u00aeghiabc\u00ef\u00bf\u00aeghi\
+string"
+test stringObj-9.3 {TclAppendObjToObj, mixed src & 1-byte dest} {testobj testdstring} {
+ set x abcdefghi
+ testdstring free
+ testdstring append \u00ae\u00bf\u00ef -1
+ set y [testdstring get]
+ string length $x
+ list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} "string none abcdefghi\u00ae\u00bf\u00ef \u00ae\u00bf\u00ef string none"
+test stringObj-9.4 {TclAppendObjToObj, 1-byte src & dest} {testobj testdstring} {
+ set x abcdefghi
+ testdstring free
+ testdstring append jkl -1
+ set y [testdstring get]
+ string length $x
+ list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} {string none abcdefghijkl jkl string none}
+test stringObj-9.5 {TclAppendObjToObj, 1-byte src & dest} testobj {
+ set x abcdefghi
+ string length $x
+ list [testobj objtype $x] [append x $x] [testobj objtype $x] \
+ [append x $x] [testobj objtype $x]
+} {string abcdefghiabcdefghi string abcdefghiabcdefghiabcdefghiabcdefghi\
+string}
+test stringObj-9.6 {TclAppendObjToObj, 1-byte src & mixed dest} {testobj testdstring} {
+ set x abc\u00ef\u00bf\u00aeghi
+ testdstring free
+ testdstring append jkl -1
+ set y [testdstring get]
+ string length $x
+ list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} "string none abc\u00ef\u00bf\u00aeghijkl jkl string none"
+test stringObj-9.7 {TclAppendObjToObj, integer src & dest} testobj {
+ set x [expr {4 * 5}]
+ set y [expr {4 + 5}]
+ list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+ [testobj objtype $x] [append x $y] [testobj objtype $x] \
+ [testobj objtype $y]
+} {int int 209 string 2099 string int}
+test stringObj-9.8 {TclAppendObjToObj, integer src & dest} testobj {
+ set x [expr {4 * 5}]
+ list [testobj objtype $x] [append x $x] [testobj objtype $x] \
+ [append x $x] [testobj objtype $x]
+} {int 2020 string 20202020 string}
+test stringObj-9.9 {TclAppendObjToObj, integer src & 1-byte dest} testobj {
+ set x abcdefghi
+ set y [expr {4 + 5}]
+ string length $x
+ list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} {string int abcdefghi9 9 string int}
+test stringObj-9.10 {TclAppendObjToObj, integer src & mixed dest} testobj {
+ set x abc\u00ef\u00bf\u00aeghi
+ set y [expr {4 + 5}]
+ string length $x
+ list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+ [set y] [testobj objtype $x] [testobj objtype $y]
+} "string int abc\u00ef\u00bf\u00aeghi9 9 string int"
+test stringObj-9.11 {TclAppendObjToObj, mixed src & 1-byte dest index check} testobj {
+ # bug 2678, in <=8.2.0, the second obj (the one to append) in
+ # Tcl_AppendObjToObj was not correctly checked to see if it was all one
+ # byte chars, so a unicode string would be added as one byte chars.
+ set x abcdef
+ set len [string length $x]
+ set y a\u00fcb\u00e5c\u00ef
+ set len [string length $y]
+ append x $y
+ string length $x
+ set q {}
+ for {set i 0} {$i < 12} {incr i} {
+ lappend q [string index $x $i]
+ }
+ set q
+} "a b c d e f a \u00fc b \u00e5 c \u00ef"
+
+test stringObj-10.1 {Tcl_GetRange with all byte-size chars} {testobj testdstring} {
+ testdstring free
+ testdstring append abcdef -1
+ set x [testdstring get]
+ list [testobj objtype $x] [set y [string range $x 1 end-1]] \
+ [testobj objtype $x] [testobj objtype $y]
+} [list none bcde string string]
+test stringObj-10.2 {Tcl_GetRange with some mixed width chars} {testobj testdstring} {
+ # Because this test does not use \uXXXX notation below instead of
+ # hardcoding the values, it may fail in multibyte locales. However, we
+ # need to test that the parser produces untyped objects even when there
+ # are high-ASCII characters in the input (like "ï"). I don't know what
+ # else to do but inline those characters here.
+ testdstring free
+ testdstring append "abc\u00ef\u00efdef" -1
+ set x [testdstring get]
+ list [testobj objtype $x] [set y [string range $x 1 end-1]] \
+ [testobj objtype $x] [testobj objtype $y]
+} [list none "bc\u00EF\u00EFde" string string]
+test stringObj-10.3 {Tcl_GetRange with some mixed width chars} testobj {
+ # set x "abcïïdef"
+ # Use \uXXXX notation below instead of hardcoding the values, otherwise
+ # the test will fail in multibyte locales.
+ set x "abc\u00EF\u00EFdef"
+ string length $x
+ list [testobj objtype $x] [set y [string range $x 1 end-1]] \
+ [testobj objtype $x] [testobj objtype $y]
+} [list string "bc\u00EF\u00EFde" string string]
+test stringObj-10.4 {Tcl_GetRange with some mixed width chars} testobj {
+ # set a "ïa¿b®cï¿d®"
+ # Use \uXXXX notation below instead of hardcoding the values, otherwise
+ # the test will fail in multibyte locales.
+ set a "\u00EFa\u00BFb\u00AEc\u00EF\u00BFd\u00AE"
+ set result [list]
+ while {[string length $a] > 0} {
+ set a [string range $a 1 end-1]
+ lappend result $a
+ }
+ set result
+} [list a\u00BFb\u00AEc\u00EF\u00BFd \
+ \u00BFb\u00AEc\u00EF\u00BF \
+ b\u00AEc\u00EF \
+ \u00AEc \
+ {}]
+
+test stringObj-11.1 {UpdateStringOfString} testobj {
+ set x 2345
+ list [string index $x end] [testobj objtype $x] [incr x] \
+ [testobj objtype $x]
+} {5 string 2346 int}
+
+test stringObj-12.1 {Tcl_GetUniChar with byte-size chars} testobj {
+ set x "abcdefghi"
+ list [string index $x 0] [string index $x 1]
+} {a b}
+test stringObj-12.2 {Tcl_GetUniChar with byte-size chars} testobj {
+ set x "abcdefghi"
+ list [string index $x 3] [string index $x end]
+} {d i}
+test stringObj-12.3 {Tcl_GetUniChar with byte-size chars} testobj {
+ set x "abcdefghi"
+ list [string index $x end] [string index $x end-1]
+} {i h}
+test stringObj-12.4 {Tcl_GetUniChar with mixed width chars} testobj {
+ string index "\u00efa\u00bfb\u00aec\u00ae\u00bfd\u00ef" 0
+} "\u00ef"
+test stringObj-12.5 {Tcl_GetUniChar} testobj {
+ set x "\u00efa\u00bfb\u00aec\u00ae\u00bfd\u00ef"
+ list [string index $x 4] [string index $x 0]
+} "\u00ae \u00ef"
+test stringObj-12.6 {Tcl_GetUniChar} testobj {
+ string index "\u00efa\u00bfb\u00aec\u00ef\u00bfd\u00ae" end
+} "\u00ae"
+
+test stringObj-13.1 {Tcl_GetCharLength with byte-size chars} testobj {
+ set a ""
+ list [string length $a] [string length $a]
+} {0 0}
+test stringObj-13.2 {Tcl_GetCharLength with byte-size chars} testobj {
+ string length "a"
+} 1
+test stringObj-13.3 {Tcl_GetCharLength with byte-size chars} testobj {
+ set a "abcdef"
+ list [string length $a] [string length $a]
+} {6 6}
+test stringObj-13.4 {Tcl_GetCharLength with mixed width chars} testobj {
+ string length "\u00ae"
+} 1
+test stringObj-13.5 {Tcl_GetCharLength with mixed width chars} testobj {
+ # string length "○○"
+ # Use \uXXXX notation below instead of hardcoding the values, otherwise
+ # the test will fail in multibyte locales.
+ string length "\u00EF\u00BF\u00AE\u00EF\u00BF\u00AE"
+} 6
+test stringObj-13.6 {Tcl_GetCharLength with mixed width chars} testobj {
+ # set a "ïa¿b®cï¿d®"
+ # Use \uXXXX notation below instead of hardcoding the values, otherwise
+ # the test will fail in multibyte locales.
+ set a "\u00EFa\u00BFb\u00AEc\u00EF\u00BFd\u00AE"
+ list [string length $a] [string length $a]
+} {10 10}
+test stringObj-13.7 {Tcl_GetCharLength with identity nulls} testobj {
+ # SF bug #684699
+ string length [encoding convertfrom identity \x00]
+} 1
+test stringObj-13.8 {Tcl_GetCharLength with identity nulls} testobj {
+ string length [encoding convertfrom identity \x01\x00\x02]
+} 3
+
+test stringObj-14.1 {Tcl_SetObjLength on pure unicode object} testobj {
+ teststringobj set 1 foo
+ teststringobj getunicode 1
+ teststringobj append 1 bar -1
+ teststringobj getunicode 1
+ teststringobj append 1 bar -1
+ teststringobj setlength 1 0
+ teststringobj append 1 bar -1
+ teststringobj get 1
+} {bar}
+
+test stringObj-15.1 {Tcl_Append*ToObj: self appends} testobj {
+ teststringobj set 1 foo
+ teststringobj appendself 1 0
+} foofoo
+test stringObj-15.2 {Tcl_Append*ToObj: self appends} testobj {
+ teststringobj set 1 foo
+ teststringobj appendself 1 1
+} foooo
+test stringObj-15.3 {Tcl_Append*ToObj: self appends} testobj {
+ teststringobj set 1 foo
+ teststringobj appendself 1 2
+} fooo
+test stringObj-15.4 {Tcl_Append*ToObj: self appends} testobj {
+ teststringobj set 1 foo
+ teststringobj appendself 1 3
+} foo
+test stringObj-15.5 {Tcl_Append*ToObj: self appends} testobj {
+ teststringobj set 1 foo
+ teststringobj appendself2 1 0
+} foofoo
+test stringObj-15.6 {Tcl_Append*ToObj: self appends} testobj {
+ teststringobj set 1 foo
+ teststringobj appendself2 1 1
+} foooo
+test stringObj-15.7 {Tcl_Append*ToObj: self appends} testobj {
+ teststringobj set 1 foo
+ teststringobj appendself2 1 2
+} fooo
+test stringObj-15.8 {Tcl_Append*ToObj: self appends} testobj {
+ teststringobj set 1 foo
+ teststringobj appendself2 1 3
+} foo
+
+
+if {[testConstraint testobj]} {
+ testobj freeallvars
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/subst.test b/pkgs/msgcat/tests/subst.test
new file mode 100644
index 0000000..4be4798
--- /dev/null
+++ b/pkgs/msgcat/tests/subst.test
@@ -0,0 +1,303 @@
+# Commands covered: subst
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1994 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 Ajuba Solutions.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2.1
+ namespace import -force ::tcltest::*
+}
+
+test subst-1.1 {basics} -returnCodes error -body {
+ subst
+} -result {wrong # args: should be "subst ?-nobackslashes? ?-nocommands? ?-novariables? string"}
+test subst-1.2 {basics} -returnCodes error -body {
+ subst a b c
+} -result {bad switch "a": must be -nobackslashes, -nocommands, or -novariables}
+
+test subst-2.1 {simple strings} {
+ subst {}
+} {}
+test subst-2.2 {simple strings} {
+ subst a
+} a
+test subst-2.3 {simple strings} {
+ subst abcdefg
+} abcdefg
+test subst-2.4 {simple strings} {
+ # Tcl Bug 685106
+ subst [bytestring bar\x00soom]
+} [bytestring bar\x00soom]
+
+test subst-3.1 {backslash substitutions} {
+ subst {\x\$x\[foo bar]\\}
+} "x\$x\[foo bar]\\"
+test subst-3.2 {backslash substitutions with utf chars} {
+ # 'j' is just a char that doesn't mean anything, and \344 is 'ä'
+ # that also doesn't mean anything, but is multi-byte in UTF-8.
+ list [subst \j] [subst \\j] [subst \\344] [subst \\\344]
+} "j j \344 \344"
+
+test subst-4.1 {variable substitutions} {
+ set a 44
+ subst {$a}
+} {44}
+test subst-4.2 {variable substitutions} {
+ set a 44
+ subst {x$a.y{$a}.z}
+} {x44.y{44}.z}
+test subst-4.3 {variable substitutions} -setup {
+ catch {unset a}
+} -body {
+ set a(13) 82
+ set i 13
+ subst {x.$a($i)}
+} -result {x.82}
+catch {unset a}
+set long {This is a very long string, intentionally made so long that it
+ will overflow the static character size for dstrings, so that
+ additional memory will have to be allocated by subst. That way,
+ if the subst procedure forgets to free up memory while returning
+ an error, there will be memory that isn't freed (this will be
+ detected when the tests are run under a checking memory allocator
+ such as Purify).}
+test subst-4.4 {variable substitutions} -returnCodes error -body {
+ subst {$long $a}
+} -result {can't read "a": no such variable}
+
+test subst-5.1 {command substitutions} {
+ subst {[concat {}]}
+} {}
+test subst-5.2 {command substitutions} {
+ subst {[concat A test string]}
+} {A test string}
+test subst-5.3 {command substitutions} {
+ subst {x.[concat foo].y.[concat bar].z}
+} {x.foo.y.bar.z}
+test subst-5.4 {command substitutions} {
+ list [catch {subst {$long [set long] [bogus_command]}} msg] $msg
+} {1 {invalid command name "bogus_command"}}
+test subst-5.5 {command substitutions} {
+ set a 0
+ list [catch {subst {[set a 1}} msg] $a $msg
+} {1 0 {missing close-bracket}}
+test subst-5.6 {command substitutions} {
+ set a 0
+ list [catch {subst {0[set a 1}} msg] $a $msg
+} {1 0 {missing close-bracket}}
+test subst-5.7 {command substitutions} {
+ set a 0
+ list [catch {subst {0[set a 1; set a 2}} msg] $a $msg
+} {1 1 {missing close-bracket}}
+
+# repeat the tests above simulating cmd line input
+test subst-5.8 {command substitutions} {
+ set script {[subst {[set a 1}]}
+ list [catch {exec [info nameofexecutable] << $script} msg] $msg
+} {1 {missing close-bracket}}
+test subst-5.9 {command substitutions} {
+ set script {[subst {0[set a 1}]}
+ list [catch {exec [info nameofexecutable] << $script} msg] $msg
+} {1 {missing close-bracket}}
+test subst-5.10 {command substitutions} {
+ set script {[subst {0[set a 1; set a 2}]}
+ list [catch {exec [info nameofexecutable] << $script} msg] $msg
+} {1 {missing close-bracket}}
+
+test subst-6.1 {clear the result after command substitution} -body {
+ catch {unset a}
+ subst {[concat foo] $a}
+} -returnCodes error -result {can't read "a": no such variable}
+
+test subst-7.1 {switches} -returnCodes error -body {
+ subst foo bar
+} -result {bad switch "foo": must be -nobackslashes, -nocommands, or -novariables}
+test subst-7.2 {switches} -returnCodes error -body {
+ subst -no bar
+} -result {ambiguous switch "-no": must be -nobackslashes, -nocommands, or -novariables}
+test subst-7.3 {switches} -returnCodes error -body {
+ subst -bogus bar
+} -result {bad switch "-bogus": must be -nobackslashes, -nocommands, or -novariables}
+test subst-7.4 {switches} {
+ set x 123
+ subst -nobackslashes {abc $x [expr 1+2] \\\x41}
+} {abc 123 3 \\\x41}
+test subst-7.5 {switches} {
+ set x 123
+ subst -nocommands {abc $x [expr 1+2] \\\x41}
+} {abc 123 [expr 1+2] \A}
+test subst-7.6 {switches} {
+ set x 123
+ subst -novariables {abc $x [expr 1+2] \\\x41}
+} {abc $x 3 \A}
+test subst-7.7 {switches} {
+ set x 123
+ subst -nov -nob -noc {abc $x [expr 1+2] \\\x41}
+} {abc $x [expr 1+2] \\\x41}
+
+test subst-8.1 {return in a subst} {
+ subst {foo [return {x}; bogus code] bar}
+} {foo x bar}
+test subst-8.2 {return in a subst} {
+ subst {foo [return x ; bogus code] bar}
+} {foo x bar}
+test subst-8.3 {return in a subst} {
+ subst {foo [if 1 { return {x}; bogus code }] bar}
+} {foo x bar}
+test subst-8.4 {return in a subst} {
+ subst {[eval {return hi}] there}
+} {hi there}
+test subst-8.5 {return in a subst} {
+ subst {foo [return {]}; bogus code] bar}
+} {foo ] bar}
+test subst-8.6 {return in a subst} -returnCodes error -body {
+ subst "foo \[return {x}; bogus code bar"
+} -result {missing close-bracket}
+test subst-8.7 {return in a subst, parse error} -body {
+ subst {foo [return {x} ; set a {}"" ; stuff] bar}
+} -returnCodes error -result {extra characters after close-brace}
+test subst-8.8 {return in a subst, parse error} -body {
+ subst {foo [return {x} ; set bar baz ; set a {}"" ; stuff] bar}
+} -returnCodes error -result {extra characters after close-brace}
+test subst-8.9 {return in a variable subst} {
+ subst {foo $var([return {x}]) bar}
+} {foo x bar}
+
+test subst-9.1 {error in a subst} -body {
+ subst {[error foo; bogus code]bar}
+} -returnCodes error -result foo
+test subst-9.2 {error in a subst} -body {
+ subst {[if 1 { error foo; bogus code}]bar}
+} -returnCodes error -result foo
+test subst-9.3 {error in a variable subst} -setup {
+ catch {unset var}
+} -body {
+ subst {foo $var([error foo]) bar}
+} -returnCodes error -result foo
+
+test subst-10.1 {break in a subst} {
+ subst {foo [break; bogus code] bar}
+} {foo }
+test subst-10.2 {break in a subst} {
+ subst {foo [break; return x; bogus code] bar}
+} {foo }
+test subst-10.3 {break in a subst} {
+ subst {foo [if 1 { break; bogus code}] bar}
+} {foo }
+test subst-10.4 {break in a subst, parse error} {
+ subst {foo [break ; set a {}{} ; stuff] bar}
+} {foo }
+test subst-10.5 {break in a subst, parse error} {
+ subst {foo [break ;set bar baz ;set a {}{} ; stuff] bar}
+} {foo }
+test subst-10.6 {break in a variable subst} {
+ subst {foo $var([break]) bar}
+} {foo }
+
+test subst-11.1 {continue in a subst} {
+ subst {foo [continue; bogus code] bar}
+} {foo bar}
+test subst-11.2 {continue in a subst} {
+ subst {foo [continue; return x; bogus code] bar}
+} {foo bar}
+test subst-11.3 {continue in a subst} {
+ subst {foo [if 1 { continue; bogus code}] bar}
+} {foo bar}
+test subst-11.4 {continue in a subst, parse error} -body {
+ subst {foo [continue ; set a {}{} ; stuff] bar}
+} -returnCodes error -result {extra characters after close-brace}
+test subst-11.5 {continue in a subst, parse error} -body {
+ subst {foo [continue ;set bar baz ;set a {}{} ; stuff] bar}
+} -returnCodes error -result {extra characters after close-brace}
+test subst-11.6 {continue in a variable subst} {
+ subst {foo $var([continue]) bar}
+} {foo bar}
+
+test subst-12.1 {nasty case, Bug 1036649} {
+ for {set i 0} {$i < 10} {incr i} {
+ set res [list [catch {subst "\[subst {};"} msg] $msg]
+ if {$msg ne "missing close-bracket"} break
+ }
+ return $res
+} {1 {missing close-bracket}}
+test subst-12.2 {nasty case, Bug 1036649} {
+ for {set i 0} {$i < 10} {incr i} {
+ set res [list [catch {subst "\[subst {}; "} msg] $msg]
+ if {$msg ne "missing close-bracket"} break
+ }
+ return $res
+} {1 {missing close-bracket}}
+test subst-12.3 {nasty case, Bug 1036649} {
+ set x 0
+ for {set i 0} {$i < 10} {incr i} {
+ set res [list [catch {subst "\[incr x;"} msg] $msg]
+ if {$msg ne "missing close-bracket"} break
+ }
+ lappend res $x
+} {1 {missing close-bracket} 10}
+test subst-12.4 {nasty case, Bug 1036649} {
+ set x 0
+ for {set i 0} {$i < 10} {incr i} {
+ set res [list [catch {subst "\[incr x; "} msg] $msg]
+ if {$msg ne "missing close-bracket"} break
+ }
+ lappend res $x
+} {1 {missing close-bracket} 10}
+test subst-12.5 {nasty case, Bug 1036649} {
+ set x 0
+ for {set i 0} {$i < 10} {incr i} {
+ set res [list [catch {subst "\[incr x"} msg] $msg]
+ if {$msg ne "missing close-bracket"} break
+ }
+ lappend res $x
+} {1 {missing close-bracket} 0}
+test subst-12.6 {nasty case with compilation} {
+ set x unset
+ set y unset
+ list [eval [list subst {[set x 1;break;incr x][set y $x]}]] $x $y
+} {{} 1 unset}
+test subst-12.7 {nasty case with compilation} {
+ set x unset
+ set y unset
+ list [eval [list subst {[set x 1;continue;incr x][set y $x]}]] $x $y
+} {1 1 1}
+
+test subst-13.1 {Bug 3081065} -setup {
+ set script [makeFile {
+ proc demo {string} {
+ subst $string
+ }
+ demo name2
+ } subst13.tcl]
+} -body {
+ interp create slave
+ slave eval [list source $script]
+ interp delete slave
+ interp create slave
+ slave eval {
+ set count 400
+ while {[incr count -1]} {
+ lappend bloat [expr {rand()}]
+ }
+ }
+ slave eval [list source $script]
+ interp delete slave
+} -cleanup {
+ removeFile subst13.tcl
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/switch.test b/pkgs/msgcat/tests/switch.test
new file mode 100644
index 0000000..a03948b
--- /dev/null
+++ b/pkgs/msgcat/tests/switch.test
@@ -0,0 +1,772 @@
+# Commands covered: switch
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+test switch-1.1 {simple patterns} {
+ switch a a {subst 1} b {subst 2} c {subst 3} default {subst 4}
+} 1
+test switch-1.2 {simple patterns} {
+ switch b a {subst 1} b {subst 2} c {subst 3} default {subst 4}
+} 2
+test switch-1.3 {simple patterns} {
+ switch x a {subst 1} b {subst 2} c {subst 3} default {subst 4}
+} 4
+test switch-1.4 {simple patterns} {
+ switch x a {subst 1} b {subst 2} c {subst 3}
+} {}
+test switch-1.5 {simple pattern matches many times} {
+ switch b a {subst 1} b {subst 2} b {subst 3} b {subst 4}
+} 2
+test switch-1.6 {simple patterns} {
+ switch default a {subst 1} default {subst 2} c {subst 3} default {subst 4}
+} 2
+test switch-1.7 {simple patterns} {
+ switch x a {subst 1} default {subst 2} c {subst 3} default {subst 4}
+} 4
+test switch-1.8 {simple patterns with -nocase} {
+ switch -nocase b a {subst 1} b {subst 2} c {subst 3} default {subst 4}
+} 2
+test switch-1.9 {simple patterns with -nocase} {
+ switch -nocase B a {subst 1} b {subst 2} c {subst 3} default {subst 4}
+} 2
+test switch-1.10 {simple patterns with -nocase} {
+ switch -nocase b a {subst 1} B {subst 2} c {subst 3} default {subst 4}
+} 2
+test switch-1.11 {simple patterns with -nocase} {
+ switch -nocase x a {subst 1} default {subst 2} c {subst 3} default {subst 4}
+} 4
+
+test switch-2.1 {single-argument form for pattern/command pairs} {
+ switch b {
+ a {subst 1}
+ b {subst 2}
+ default {subst 6}
+ }
+} {2}
+test switch-2.2 {single-argument form for pattern/command pairs} -body {
+ switch z {a 2 b}
+} -returnCodes error -result {extra switch pattern with no body}
+
+test switch-3.1 {-exact vs. -glob vs. -regexp} {
+ switch -exact aaaab {
+ ^a*b$ {subst regexp}
+ *b {subst glob}
+ aaaab {subst exact}
+ default {subst none}
+ }
+} exact
+test switch-3.2 {-exact vs. -glob vs. -regexp} {
+ switch -regexp aaaab {
+ ^a*b$ {subst regexp}
+ *b {subst glob}
+ aaaab {subst exact}
+ default {subst none}
+ }
+} regexp
+test switch-3.3 {-exact vs. -glob vs. -regexp} {
+ switch -glob aaaab {
+ ^a*b$ {subst regexp}
+ *b {subst glob}
+ aaaab {subst exact}
+ default {subst none}
+ }
+} glob
+test switch-3.4 {-exact vs. -glob vs. -regexp} {
+ switch aaaab {^a*b$} {subst regexp} *b {subst glob} \
+ aaaab {subst exact} default {subst none}
+} exact
+test switch-3.5 {-exact vs. -glob vs. -regexp} {
+ switch -- -glob {
+ ^g.*b$ {subst regexp}
+ -* {subst glob}
+ -glob {subst exact}
+ default {subst none}
+ }
+} exact
+test switch-3.6 {-exact vs. -glob vs. -regexp} -body {
+ switch -foo a b c
+} -returnCodes error -result {bad option "-foo": must be -exact, -glob, -indexvar, -matchvar, -nocase, -regexp, or --}
+test switch-3.7 {-exact vs. -glob vs. -regexp with -nocase} {
+ switch -exact -nocase aaaab {
+ ^a*b$ {subst regexp}
+ *b {subst glob}
+ aaaab {subst exact}
+ default {subst none}
+ }
+} exact
+test switch-3.8 {-exact vs. -glob vs. -regexp with -nocase} {
+ switch -regexp -nocase aaaab {
+ ^a*b$ {subst regexp}
+ *b {subst glob}
+ aaaab {subst exact}
+ default {subst none}
+ }
+} regexp
+test switch-3.9 {-exact vs. -glob vs. -regexp with -nocase} {
+ switch -glob -nocase aaaab {
+ ^a*b$ {subst regexp}
+ *b {subst glob}
+ aaaab {subst exact}
+ default {subst none}
+ }
+} glob
+test switch-3.10 {-exact vs. -glob vs. -regexp with -nocase} {
+ switch -nocase aaaab {^a*b$} {subst regexp} *b {subst glob} \
+ aaaab {subst exact} default {subst none}
+} exact
+test switch-3.11 {-exact vs. -glob vs. -regexp with -nocase} {
+ switch -nocase -- -glob {
+ ^g.*b$ {subst regexp}
+ -* {subst glob}
+ -glob {subst exact}
+ default {subst none}
+ }
+} exact
+test switch-3.12 {-exact vs. -glob vs. -regexp} {
+ switch -exa Foo Foo {set result OK}
+} OK
+test switch-3.13 {-exact vs. -glob vs. -regexp} {
+ switch -gl Foo Fo? {set result OK}
+} OK
+test switch-3.14 {-exact vs. -glob vs. -regexp} {
+ switch -re Foo Fo. {set result OK}
+} OK
+test switch-3.15 {-exact vs. -glob vs. -regexp} -body {
+ switch -exact -exact Foo Foo {set result OK}
+} -returnCodes error -result {bad option "-exact": -exact option already found}
+test switch-3.16 {-exact vs. -glob vs. -regexp} -body {
+ switch -exact -glob Foo Foo {set result OK}
+} -returnCodes error -result {bad option "-glob": -exact option already found}
+test switch-3.17 {-exact vs. -glob vs. -regexp} -body {
+ switch -glob -regexp Foo Foo {set result OK}
+} -returnCodes error -result {bad option "-regexp": -glob option already found}
+test switch-3.18 {-exact vs. -glob vs. -regexp} -body {
+ switch -regexp -glob Foo Foo {set result OK}
+} -returnCodes error -result {bad option "-glob": -regexp option already found}
+
+test switch-4.1 {error in executed command} {
+ list [catch {switch a a {error "Just a test"} default {subst 1}} msg] \
+ $msg $::errorInfo
+} {1 {Just a test} {Just a test
+ while executing
+"error "Just a test""
+ ("a" arm line 1)
+ invoked from within
+"switch a a {error "Just a test"} default {subst 1}"}}
+test switch-4.2 {error: not enough args} -returnCodes error -body {
+ switch
+} -result {wrong # args: should be "switch ?-switch ...? string ?pattern body ...? ?default body?"}
+test switch-4.3 {error: pattern with no body} -body {
+ switch a b
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-4.4 {error: pattern with no body} -body {
+ switch a b {subst 1} c
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-4.5 {error in default command} {
+ list [catch {switch foo a {error switch1} b {error switch 3} \
+ default {error switch2}} msg] $msg $::errorInfo
+} {1 switch2 {switch2
+ while executing
+"error switch2"
+ ("default" arm line 1)
+ invoked from within
+"switch foo a {error switch1} b {error switch 3} default {error switch2}"}}
+
+test switch-5.1 {errors in -regexp matching} -returnCodes error -body {
+ switch -regexp aaaab {
+ *b {subst glob}
+ aaaab {subst exact}
+ default {subst none}
+ }
+} -result {couldn't compile regular expression pattern: quantifier operand invalid}
+
+test switch-6.1 {backslashes in patterns} {
+ switch -exact {\a\$\.\[} {
+ \a\$\.\[ {subst first}
+ \a\\$\.\\[ {subst second}
+ \\a\\$\\.\\[ {subst third}
+ {\a\\$\.\\[} {subst fourth}
+ {\\a\\$\\.\\[} {subst fifth}
+ default {subst none}
+ }
+} third
+test switch-6.2 {backslashes in patterns} {
+ switch -exact {\a\$\.\[} {
+ \a\$\.\[ {subst first}
+ {\a\$\.\[} {subst second}
+ {{\a\$\.\[}} {subst third}
+ default {subst none}
+ }
+} second
+
+test switch-7.1 {"-" bodies} {
+ switch a {
+ a -
+ b -
+ c {subst 1}
+ default {subst 2}
+ }
+} 1
+test switch-7.2 {"-" bodies} -body {
+ switch a {
+ a -
+ b -
+ c -
+ }
+} -returnCodes error -result {no body specified for pattern "c"}
+test switch-7.3 {"-" bodies} -body {
+ switch a {
+ a -
+ b -foo
+ c -
+ }
+} -returnCodes error -result {no body specified for pattern "c"}
+test switch-7.4 {"-" bodies} -body {
+ switch a {
+ a -
+ b -foo
+ c {}
+ }
+} -returnCodes error -result {invalid command name "-foo"}
+
+test switch-8.1 {empty body} {
+ set msg {}
+ switch {2} {
+ 1 {set msg 1}
+ 2 {}
+ default {set msg 2}
+ }
+} {}
+proc test_switch_body {} {
+ return "INVOKED"
+}
+test switch-8.2 {weird body text, variable} {
+ set cmd {test_switch_body}
+ switch Foo {
+ Foo $cmd
+ }
+} {INVOKED}
+test switch-8.3 {weird body text, variable} {
+ set cmd {test_switch_body}
+ switch Foo {
+ Foo {$cmd}
+ }
+} {INVOKED}
+
+test switch-9.1 {empty pattern/body list} -returnCodes error -body {
+ switch x
+} -result {wrong # args: should be "switch ?-switch ...? string ?pattern body ...? ?default body?"}
+test switch-9.2 {unpaired pattern} -returnCodes error -body {
+ switch -- x
+} -result {extra switch pattern with no body}
+test switch-9.3 {empty pattern/body list} -body {
+ switch x {}
+} -returnCodes error -result {wrong # args: should be "switch ?-switch ...? string {?pattern body ...? ?default body?}"}
+test switch-9.4 {empty pattern/body list} -body {
+ switch -- x {}
+} -returnCodes error -result {wrong # args: should be "switch ?-switch ...? string {?pattern body ...? ?default body?}"}
+test switch-9.5 {unpaired pattern} -body {
+ switch x a {} b
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-9.6 {unpaired pattern} -body {
+ switch x {a {} b}
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-9.7 {unpaired pattern} -body {
+ switch x a {} # comment b
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-9.8 {unpaired pattern} -returnCodes error -body {
+ switch x {a {} # comment b}
+} -result {extra switch pattern with no body, this may be due to a comment incorrectly placed outside of a switch body - see the "switch" documentation}
+test switch-9.9 {unpaired pattern} -body {
+ switch x a {} x {} # comment b
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-9.10 {unpaired pattern} -returnCodes error -body {
+ switch x {a {} x {} # comment b}
+} -result {extra switch pattern with no body, this may be due to a comment incorrectly placed outside of a switch body - see the "switch" documentation}
+
+test switch-10.1 {compiled -exact switch} {
+ if 1 {switch -exact -- a {a {subst 1} b {subst 2}}}
+} 1
+test switch-10.1a {compiled -exact switch} {
+ if 1 {switch -exact a {a {subst 1} b {subst 2}}}
+} 1
+test switch-10.2 {compiled -exact switch} {
+ if 1 {switch -exact -- b {a {subst 1} b {subst 2}}}
+} 2
+test switch-10.2a {compiled -exact switch} {
+ if 1 {switch -exact b {a {subst 1} b {subst 2}}}
+} 2
+test switch-10.3 {compiled -exact switch} {
+ if 1 {switch -exact -- c {a {subst 1} b {subst 2}}}
+} {}
+test switch-10.3a {compiled -exact switch} {
+ if 1 {switch -exact c {a {subst 1} b {subst 2}}}
+} {}
+test switch-10.4 {compiled -exact switch} {
+ if 1 {
+ set x 0
+ switch -exact -- c {a {subst 1} b {subst 2}}
+ }
+} {}
+test switch-10.5 {compiled -exact switch} {
+ if 1 {switch -exact -- a {a - aa {subst 1} b {subst 2}}}
+} 1
+test switch-10.6 {compiled -exact switch} {
+ if 1 {switch -exact -- b {a {
+ set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+ set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+ set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+ set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+ set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+ set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+ set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+ set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+ } b {subst 2}}}
+} 2
+
+# Command variants are:
+# c* are compiled switches, i* are interpreted
+# *-glob use glob matching, *-exact use exact matching
+# *2* include a default clause (different results too.)
+proc cswtest-glob s {
+ set x 0; set y 0
+ foreach c [split $s {}] {
+ switch -glob $c {
+ a {incr x}
+ b {incr y}
+ }
+ }
+ set x [expr {$x*100}]; set y [expr {$y*100}]
+ foreach c [split $s {}] {
+ switch -glob -- $c a {incr x} b {incr y}
+ }
+ return $x,$y
+}
+proc iswtest-glob s {
+ set x 0; set y 0; set switch switch
+ foreach c [split $s {}] {
+ $switch -glob $c {
+ a {incr x}
+ b {incr y}
+ }
+ }
+ set x [expr {$x*100}]; set y [expr {$y*100}]
+ foreach c [split $s {}] {
+ $switch -glob -- $c a {incr x} b {incr y}
+ }
+ return $x,$y
+}
+proc cswtest-exact s {
+ set x 0; set y 0
+ foreach c [split $s {}] {
+ switch -exact $c {
+ a {incr x}
+ b {incr y}
+ }
+ }
+ set x [expr {$x*100}]; set y [expr {$y*100}]
+ foreach c [split $s {}] {
+ switch -exact -- $c a {incr x} b {incr y}
+ }
+ return $x,$y
+}
+proc iswtest-exact s {
+ set x 0; set y 0; set switch switch
+ foreach c [split $s {}] {
+ $switch -exact $c {
+ a {incr x}
+ b {incr y}
+ }
+ }
+ set x [expr {$x*100}]; set y [expr {$y*100}]
+ foreach c [split $s {}] {
+ $switch -exact -- $c a {incr x} b {incr y}
+ }
+ return $x,$y
+}
+proc cswtest2-glob s {
+ set x 0; set y 0; set z 0
+ foreach c [split $s {}] {
+ switch -glob $c {
+ a {incr x}
+ b {incr y}
+ default {incr z}
+ }
+ }
+ set x [expr {$x*100}]; set y [expr {$y*100}]; set z [expr {$z*100}]
+ foreach c [split $s {}] {
+ switch -glob -- $c a {incr x} b {incr y} default {incr z}
+ }
+ return $x,$y,$z
+}
+proc iswtest2-glob s {
+ set x 0; set y 0; set z 0; set switch switch
+ foreach c [split $s {}] {
+ $switch -glob $c {
+ a {incr x}
+ b {incr y}
+ default {incr z}
+ }
+ }
+ set x [expr {$x*100}]; set y [expr {$y*100}]; set z [expr {$z*100}]
+ foreach c [split $s {}] {
+ $switch -glob -- $c a {incr x} b {incr y} default {incr z}
+ }
+ return $x,$y,$z
+}
+proc cswtest2-exact s {
+ set x 0; set y 0; set z 0
+ foreach c [split $s {}] {
+ switch -exact $c {
+ a {incr x}
+ b {incr y}
+ default {incr z}
+ }
+ }
+ set x [expr {$x*100}]; set y [expr {$y*100}]; set z [expr {$z*100}]
+ foreach c [split $s {}] {
+ switch -exact -- $c a {incr x} b {incr y} default {incr z}
+ }
+ return $x,$y,$z
+}
+proc iswtest2-exact s {
+ set x 0; set y 0; set z 0; set switch switch
+ foreach c [split $s {}] {
+ $switch -exact $c {
+ a {incr x}
+ b {incr y}
+ default {incr z}
+ }
+ }
+ set x [expr {$x*100}]; set y [expr {$y*100}]; set z [expr {$z*100}]
+ foreach c [split $s {}] {
+ $switch -exact -- $c a {incr x} b {incr y} default {incr z}
+ }
+ return $x,$y,$z
+}
+
+test switch-10.7 {comparison of compiled and interpreted behaviour of switch, exact matching} {
+ cswtest-exact abcb
+} [iswtest-exact abcb]
+test switch-10.8 {comparison of compiled and interpreted behaviour of switch, glob matching} {
+ cswtest-glob abcb
+} [iswtest-glob abcb]
+test switch-10.9 {comparison of compiled and interpreted behaviour of switch, exact matching with default} {
+ cswtest2-exact abcb
+} [iswtest2-exact abcb]
+test switch-10.10 {comparison of compiled and interpreted behaviour of switch, glob matching with default} {
+ cswtest2-glob abcb
+} [iswtest2-glob abcb]
+proc cswtest-default-exact {x} {
+ switch -- $x {
+ a* {return b}
+ aa {return c}
+ default {return d}
+ }
+}
+test switch-10.11 {default to exact matching when compiled} {
+ cswtest-default-exact a
+} d
+test switch-10.12 {default to exact matching when compiled} {
+ cswtest-default-exact aa
+} c
+test switch-10.13 {default to exact matching when compiled} {
+ cswtest-default-exact a*
+} b
+test switch-10.14 {default to exact matching when compiled} {
+ cswtest-default-exact a**
+} d
+rename cswtest-default-exact {}
+rename cswtest-glob {}
+rename iswtest-glob {}
+rename cswtest2-glob {}
+rename iswtest2-glob {}
+rename cswtest-exact {}
+rename iswtest-exact {}
+rename cswtest2-exact {}
+rename iswtest2-exact {}
+# Bug 1891827
+test switch-10.15 {(not) compiled exact nocase regression} {
+ apply {{} {
+ switch -nocase -- A { a {return yes} default {return no} }
+ }}
+} yes
+
+# Added due to TIP#75
+test switch-11.1 {regexp matching with -matchvar} {
+ switch -regexp -matchvar x -- abc {.(.). {set x}}
+} {abc b}
+test switch-11.2 {regexp matching with -matchvar} {
+ set x GOOD
+ switch -regexp -matchvar x -- abc {.(.).. {list $x z}}
+ set x
+} GOOD
+test switch-11.3 {regexp matching with -matchvar} {
+ switch -regexp -matchvar x -- "a b c" {.(.). {set x}}
+} {{a b} { }}
+test switch-11.4 {regexp matching with -matchvar} {
+ set x BAD
+ switch -regexp -matchvar x -- "a b c" {
+ bc {list $x YES}
+ default {list $x NO}
+ }
+} {{} NO}
+test switch-11.5 {-matchvar without -regexp} {
+ set x {}
+ list [catch {switch -glob -matchvar x -- abc . {set x}} msg] $x $msg
+} {1 {} {-matchvar option requires -regexp option}}
+test switch-11.6 {-matchvar unwritable} {
+ set x {}
+ list [catch {switch -regexp -matchvar x(x) -- abc . {set x}} msg] $x $msg
+} {1 {} {can't set "x(x)": variable isn't array}}
+
+test switch-12.1 {regexp matching with -indexvar} {
+ switch -regexp -indexvar x -- abc {.(.). {set x}}
+} {{0 2} {1 1}}
+test switch-12.2 {regexp matching with -indexvar} {
+ set x GOOD
+ switch -regexp -indexvar x -- abc {.(.).. {list $x z}}
+ set x
+} GOOD
+test switch-12.3 {regexp matching with -indexvar} {
+ switch -regexp -indexvar x -- "a b c" {.(.). {set x}}
+} {{0 2} {1 1}}
+test switch-12.4 {regexp matching with -indexvar} {
+ set x BAD
+ switch -regexp -indexvar x -- "a b c" {
+ bc {list $x YES}
+ default {list $x NO}
+ }
+} {{} NO}
+test switch-12.5 {-indexvar without -regexp} {
+ set x {}
+ list [catch {switch -glob -indexvar x -- abc . {set x}} msg] $x $msg
+} {1 {} {-indexvar option requires -regexp option}}
+test switch-12.6 {-indexvar unwritable} {
+ set x {}
+ list [catch {switch -regexp -indexvar x(x) -- abc . {set x}} msg] $x $msg
+} {1 {} {can't set "x(x)": variable isn't array}}
+test switch-12.7 {[Bug 3106532] -indexvar should be directly usable with [string range]} {
+ set str abcdef
+ switch -regexp -indexvar x -- $str ^... {string range $str {*}[lindex $x 0]}
+} abc
+test switch-12.8 {-indexvar and matched empty strings} {
+ switch -regexp -indexvar x -- abcdef ^...(x?) {return $x}
+} {{0 2} {3 2}}
+test switch-12.9 {-indexvar and unmatched strings} {
+ switch -regexp -indexvar x -- abcdef ^...(x)? {return $x}
+} {{0 2} {-1 -1}}
+
+test switch-13.1 {-indexvar -matchvar combinations} {
+ switch -regexp -indexvar x -matchvar y abc {
+ . {list $x $y}
+ }
+} {{{0 0}} a}
+test switch-13.2 {-indexvar -matchvar combinations} {
+ switch -regexp -indexvar x -matchvar y abc {
+ .$ {list $x $y}
+ }
+} {{{2 2}} c}
+test switch-13.3 {-indexvar -matchvar combinations} {
+ switch -regexp -indexvar x -matchvar y abc {
+ (.)(.)(.) {list $x $y}
+ }
+} {{{0 2} {0 0} {1 1} {2 2}} {abc a b c}}
+test switch-13.4 {-indexvar -matchvar combinations} {
+ set x -
+ set y -
+ switch -regexp -indexvar x -matchvar y abc {
+ (.)(.)(.). -
+ default {list $x $y}
+ }
+} {{} {}}
+test switch-13.5 {-indexvar -matchvar combinations} {
+ set x -
+ set y -
+ list [catch {
+ switch -regexp -indexvar x(x) -matchvar y abc {. {list $x $y}}
+ } msg] $x $y $msg
+} {1 - - {can't set "x(x)": variable isn't array}}
+test switch-13.6 {-indexvar -matchvar combinations} {
+ set x -
+ set y -
+ list [catch {
+ switch -regexp -indexvar x -matchvar y(y) abc {. {list $x $y}}
+ } msg] $x $y $msg
+} {1 {{0 0}} - {can't set "y(y)": variable isn't array}}
+
+test switch-14.1 {-regexp -- compilation [Bug 1854399]} {
+ switch -regexp -- 0 {
+ {[0-9]+} {return yes}
+ default {return no}
+ }
+ foo
+} yes
+test switch-14.2 {-regexp -- compilation [Bug 1854399]} {
+ proc foo {} {
+ switch -regexp -- 0 {
+ {[0-9]+} {return yes}
+ default {return no}
+ }
+ }
+ foo
+} yes
+test switch-14.3 {-regexp -- compilation [Bug 1854399]} {
+ proc foo {} {
+ switch -regexp -- 0 {
+ {\d+} {return yes}
+ default {return no}
+ }
+ }
+ foo
+} yes
+test switch-14.4 {-regexp -- compilation [Bug 1854399]} {
+ proc foo {} {
+ switch -regexp -- 0 {
+ {0} {return yes}
+ default {return no}
+ }
+ }
+ foo
+} yes
+test switch-14.5 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- 0 {
+ {0|1|2} {return yes}
+ default {return no}
+ }
+ }}
+} yes
+test switch-14.6 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- 0 {
+ {0|11|222} {return yes}
+ default {return no}
+ }
+ }}
+} yes
+test switch-14.7 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- 0 {
+ {[012]} {return yes}
+ default {return no}
+ }
+ }}
+} yes
+test switch-14.8 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- x {
+ {0|1|2} {return yes}
+ default {return no}
+ }
+ }}
+} no
+test switch-14.9 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- x {
+ {0|11|222} {return yes}
+ default {return no}
+ }
+ }}
+} no
+test switch-14.10 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- x {
+ {[012]} {return yes}
+ default {return no}
+ }
+ }}
+} no
+test switch-14.11 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- x {
+ {0|1|2} {return yes}
+ .+ {return yes2}
+ default {return no}
+ }
+ }}
+} yes2
+test switch-14.12 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- x {
+ {0|11|222} {return yes}
+ .+ {return yes2}
+ default {return no}
+ }
+ }}
+} yes2
+test switch-14.13 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- x {
+ {[012]} {return yes}
+ .+ {return yes2}
+ default {return no}
+ }
+ }}
+} yes2
+test switch-14.14 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- {} {
+ {0|1|2} {return yes}
+ .+ {return yes2}
+ default {return no}
+ }
+ }}
+} no
+test switch-14.15 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- {} {
+ {0|11|222} {return yes}
+ .+ {return yes2}
+ default {return no}
+ }
+ }}
+} no
+test switch-14.16 {switch -regexp compilation} {
+ apply {{} {
+ switch -regexp -- {} {
+ {[012]} {return yes}
+ .+ {return yes2}
+ default {return no}
+ }
+ }}
+} no
+
+test switch-15.1 {coroutine safety of non-bytecoded switch} {*}{
+ -body {
+ proc coro {} {
+ switch -glob a {
+ a {yield ok1}
+ }
+ return ok2
+ }
+ list [coroutine c coro] [c]
+ }
+ -result {ok1 ok2}
+ -cleanup {
+ rename coro {}
+ }
+}
+
+# cleanup
+catch {rename foo {}}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/tailcall.test b/pkgs/msgcat/tests/tailcall.test
new file mode 100644
index 0000000..e9ec188
--- /dev/null
+++ b/pkgs/msgcat/tests/tailcall.test
@@ -0,0 +1,663 @@
+# Commands covered: tailcall
+#
+# This file contains a collection of tests for experimental commands that are
+# found in ::tcl::unsupported. The tests will migrate to normal test files
+# if/when the commands find their way into the core.
+#
+# Copyright (c) 2008 by Miguel Sofer.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testnrelevels [llength [info commands testnrelevels]]
+
+#
+# The tests that risked blowing the C stack on failure have been removed: we
+# can now actually measure using testnrelevels.
+#
+
+if {[testConstraint testnrelevels]} {
+ namespace eval testnre {
+ #
+ # [testnrelevels] returns a 6-list with: C-stack depth, iPtr->numlevels,
+ # cmdFrame level, callFrame level, tosPtr and callback depth
+ #
+ variable last [testnrelevels]
+ proc depthDiff {} {
+ variable last
+ set depth [testnrelevels]
+ set res {}
+ foreach t $depth l $last {
+ lappend res [expr {$t-$l}]
+ }
+ set last $depth
+ return $res
+ }
+ namespace export *
+ }
+ namespace import testnre::*
+}
+
+proc errorcode options {
+ dict get [dict merge {-errorcode NONE} $options] -errorcode
+}
+
+test tailcall-0.1 {tailcall is constant space} -constraints testnrelevels -setup {
+ proc a i {
+ #
+ # NOTE: there may be a diff in callback depth with the first call
+ # ($i==0) due to the fact that the first is from an eval. Successive
+ # calls should add nothing to any stack depths.
+ #
+ if {$i == 1} {
+ depthDiff
+ }
+ if {[incr i] > 10} {
+ return [depthDiff]
+ }
+ tailcall a $i
+ }
+} -body {
+ a 0
+} -cleanup {
+ rename a {}
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.2 {tailcall is constant space} -constraints testnrelevels -setup {
+ set a { i {
+ if {$i == 1} {
+ depthDiff
+ }
+ if {[incr i] > 10} {
+ return [depthDiff]
+ }
+ upvar 1 a a
+ tailcall apply $a $i
+ }}
+} -body {
+ apply $a 0
+} -cleanup {
+ unset a
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.3 {tailcall is constant space} -constraints testnrelevels -setup {
+ proc a i {
+ if {$i == 1} {
+ depthDiff
+ }
+ if {[incr i] > 10} {
+ return [depthDiff]
+ }
+ tailcall b $i
+ }
+ interp alias {} b {} a
+} -body {
+ b 0
+} -cleanup {
+ rename a {}
+ rename b {}
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.4 {tailcall is constant space} -constraints testnrelevels -setup {
+ namespace eval ::ns {
+ namespace export *
+ }
+ proc ::ns::a i {
+ if {$i == 1} {
+ depthDiff
+ }
+ if {[incr i] > 10} {
+ return [depthDiff]
+ }
+ set b [uplevel 1 [list namespace which b]]
+ tailcall $b $i
+ }
+ namespace import ::ns::a
+ rename a b
+} -body {
+ b 0
+} -cleanup {
+ rename b {}
+ namespace delete ::ns
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.5 {tailcall is constant space} -constraints testnrelevels -setup {
+ proc b i {
+ if {$i == 1} {
+ depthDiff
+ }
+ if {[incr i] > 10} {
+ return [depthDiff]
+ }
+ tailcall a b $i
+ }
+ namespace ensemble create -command a -map {b b}
+} -body {
+ a b 0
+} -cleanup {
+ rename a {}
+ rename b {}
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.6 {tailcall is constant space} -constraints {testnrelevels knownBug} -setup {
+ #
+ # This test fails because ns-unknown is not NR-enabled
+ #
+ proc c i {
+ if {$i == 1} {
+ depthDiff
+ }
+ if {[incr i] > 10} {
+ return [depthDiff]
+ }
+ tailcall a b $i
+ }
+ proc d {ens sub args} {
+ return [list $ens c]
+ }
+ namespace ensemble create -command a -unknown d
+} -body {
+ a b 0
+} -cleanup {
+ rename a {}
+ rename c {}
+ rename d {}
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.7 {tailcall is constant space} -constraints testnrelevels -setup {
+ catch {rename foo {}}
+ oo::class create foo {
+ method b i {
+ if {$i == 1} {
+ depthDiff
+ }
+ if {[incr i] > 10} {
+ return [depthDiff]
+ }
+ tailcall [self] b $i
+ }
+ }
+} -body {
+ foo create a
+ a b 0
+} -cleanup {
+ rename a {}
+ rename foo {}
+} -result {0 0 0 0 0 0}
+
+test tailcall-1 {tailcall} -body {
+ namespace eval a {
+ variable x *::a
+ proc xset {} {
+ set tmp {}
+ set ns {[namespace current]}
+ set level [info level]
+ for {set i 0} {$i <= [info level]} {incr i} {
+ uplevel #$i "set x $i$ns"
+ lappend tmp "$i [info level $i]"
+ }
+ lrange $tmp 1 end
+ }
+ proc foo {} {tailcall xset; set x noreach}
+ }
+ namespace eval b {
+ variable x *::b
+ proc xset args {error b::xset}
+ proc moo {} {set x 0; variable y [::a::foo]; set x}
+ }
+ variable x *::
+ proc xset args {error ::xset}
+ list [::b::moo] | $x $a::x $b::x | $::b::y
+} -cleanup {
+ unset x
+ rename xset {}
+ namespace delete a b
+} -result {1::b | 0:: *::a *::b | {{1 ::b::moo} {2 xset}}}
+
+
+test tailcall-2 {tailcall in non-proc} -body {
+ namespace eval a [list tailcall set x 1]
+} -match glob -result *tailcall* -returnCodes error
+
+test tailcall-3 {tailcall falls off tebc} -body {
+ unset -nocomplain x
+ proc foo {} {tailcall set x 1}
+ list [catch foo msg] $msg [set x]
+} -cleanup {
+ rename foo {}
+ unset x
+} -result {0 1 1}
+
+test tailcall-4 {tailcall falls off tebc} -body {
+ set x 2
+ proc foo {} {tailcall set x 1}
+ foo
+ set x
+} -cleanup {
+ rename foo {}
+ unset x
+} -result 1
+
+test tailcall-5 {tailcall falls off tebc} -body {
+ set x 2
+ namespace eval bar {
+ variable x 3
+ proc foo {} {tailcall set x 1}
+ }
+ bar::foo
+ list $x $bar::x
+} -cleanup {
+ unset x
+ namespace delete bar
+} -result {1 3}
+
+test tailcall-6 {tailcall does remove callframes} -body {
+ proc foo {} {info level}
+ proc moo {} {tailcall foo}
+ proc boo {} {expr {[moo] - [info level]}}
+ boo
+} -cleanup {
+ rename foo {}
+ rename moo {}
+ rename boo {}
+} -result 1
+
+test tailcall-7 {tailcall does return} -setup {
+ namespace eval ::foo {
+ variable res {}
+ proc a {} {
+ variable res
+ append res a
+ tailcall set x 1
+ append res a
+ }
+ proc b {} {
+ variable res
+ append res b
+ a
+ append res b
+ }
+ proc c {} {
+ variable res
+ append res c
+ b
+ append res c
+ }
+ }
+} -body {
+ namespace eval ::foo c
+} -cleanup {
+ namespace delete ::foo
+} -result cbabc
+
+test tailcall-8 {tailcall tailcall} -setup {
+ namespace eval ::foo {
+ variable res {}
+ proc a {} {
+ variable res
+ append res a
+ tailcall tailcall set x 1
+ append res a
+ }
+ proc b {} {
+ variable res
+ append res b
+ a
+ append res b
+ }
+ proc c {} {
+ variable res
+ append res c
+ b
+ append res c
+ }
+ }
+} -body {
+ namespace eval ::foo c
+} -cleanup {
+ namespace delete ::foo
+} -result cbac
+
+test tailcall-9 {tailcall factorial} -setup {
+ proc fact {n {b 1}} {
+ if {$n == 1} {
+ return $b
+ }
+ tailcall fact [expr {$n-1}] [expr {$n*$b}]
+ }
+} -body {
+ list [fact 1] [fact 5] [fact 10] [fact 15]
+} -cleanup {
+ rename fact {}
+} -result {1 120 3628800 1307674368000}
+
+test tailcall-10a {tailcall and eval} -setup {
+ set ::x 0
+ proc a {} {
+ eval [list tailcall lappend ::x 2]
+ set ::x 1
+ }
+} -body {
+ list [a] $::x
+} -cleanup {
+ unset -nocomplain ::x
+} -result {{0 2} {0 2}}
+
+test tailcall-10b {tailcall and eval} -setup {
+ set ::x 0
+ proc a {} {
+ eval {tailcall lappend ::x 2}
+ set ::x 1
+ }
+} -body {
+ list [a] $::x
+} -cleanup {
+ unset -nocomplain ::x
+} -result {{0 2} {0 2}}
+
+test tailcall-11a {tailcall and uplevel} -setup {
+ proc a {} {
+ uplevel 1 [list tailcall set ::x 2]
+ set ::x 1
+ }
+} -body {
+ list [a] $::x
+} -cleanup {
+ unset -nocomplain ::x
+} -match glob -result *tailcall* -returnCodes error
+
+test tailcall-11b {tailcall and uplevel} -setup {
+ proc a {} {
+ uplevel 1 {tailcall set ::x 2}
+ set ::x 1
+ }
+} -body {
+ list [a] $::x
+} -cleanup {
+ unset -nocomplain ::x
+} -match glob -result *tailcall* -returnCodes error
+
+test tailcall-11c {tailcall and uplevel} -setup {
+ proc a {} {
+ uplevel 1 {tailcall lappend ::x 2}
+ set ::x 1
+ }
+ proc b {} {set ::x 0; a; lappend ::x 3}
+} -body {
+ list [b] $::x
+} -cleanup {
+ rename a {}
+ rename b {}
+ unset -nocomplain ::x
+} -result {{0 3 2} {0 3 2}}
+
+test tailcall-12.1 {[Bug 2649975]} -setup {
+ proc dump {{text {}}} {
+ set text [uplevel 1 [list subst $text]]
+ set l [expr {[info level] -1}]
+ if {$text eq {}} {
+ set text [info level $l]
+ }
+ puts "$l: $text"
+ }
+ # proc dump args {}
+ proc bravo {} {
+ upvar 1 v w
+ dump {inside bravo, v -> $w}
+ set v "procedure bravo"
+ #uplevel 1 [list delta ::betty]
+ uplevel 1 {delta ::betty}
+ return $::resolution
+ }
+ proc delta name {
+ upvar 1 v w
+ dump {inside delta, v -> $w}
+ set v "procedure delta"
+ tailcall foxtrot
+ }
+ proc foxtrot {} {
+ upvar 1 v w
+ dump {inside foxtrot, v -> $w}
+ global resolution
+ set ::resolution $w
+ }
+ set v "global level"
+} -body {
+ set result [bravo]
+ if {$result ne $v} {
+ puts "v should have been found at $v but was found in $result"
+ }
+} -cleanup {
+ unset v
+ rename dump {}
+ rename bravo {}
+ rename delta {}
+ rename foxtrot {}
+} -output {1: inside bravo, v -> global level
+1: inside delta, v -> global level
+1: inside foxtrot, v -> global level
+}
+
+test tailcall-12.2 {[Bug 2649975]} -setup {
+ proc dump {{text {}}} {
+ set text [uplevel 1 [list subst $text]]
+ set l [expr {[info level] -1}]
+ if {$text eq {}} {
+ set text [info level $l]
+ }
+ puts "$l: $text"
+ }
+ # proc dump args {}
+ set v "global level"
+ oo::class create foo { # like connection
+ method alpha {} { # like connections 'tables' method
+ dump
+ upvar 1 v w
+ dump {inside foo's alpha, v resolves to $w}
+ set v "foo's method alpha"
+ dump {foo's alpha is calling [self] bravo - v should resolve at global level}
+ set result [uplevel 1 [list [self] bravo]]
+ dump {exiting from foo's alpha}
+ return $result
+ }
+ method bravo {} { # like connections 'foreach' method
+ dump
+ upvar 1 v w
+ dump {inside foo's bravo, v resolves to $w}
+ set v "foo's method bravo"
+ dump {foo's bravo is calling charlie to create barney}
+ set barney [my charlie ::barney]
+ dump {foo's bravo is calling bravo on $barney}
+ dump {v should resolve at global scope there}
+ set result [uplevel 1 [list $barney bravo]]
+ dump {exiting from foo's bravo}
+ return $result
+ }
+ method charlie {name} { # like tdbc prepare
+ dump
+ set v "foo's method charlie"
+ dump {tailcalling bar's constructor}
+ tailcall ::bar create $name
+ }
+ }
+ oo::class create bar { # like statement
+ method bravo {} { # like statement foreach method
+ dump
+ upvar 1 v w
+ dump {inside bar's bravo, v is resolving to $w}
+ set v "bar's method bravo"
+ dump {calling delta to construct betty - v should resolve global there}
+ uplevel 1 [list [self] delta ::betty]
+ dump {exiting from bar's bravo}
+ return [::betty whathappened]
+ }
+ method delta {name} { # like statement execute method
+ dump
+ upvar 1 v w
+ dump {inside bar's delta, v is resolving to $w}
+ set v "bar's method delta"
+ dump {tailcalling to construct $name as instance of grill}
+ dump {v should resolve at global level in grill's constructor}
+ dump {grill's constructor should run at level [info level]}
+ tailcall grill create $name
+ }
+ }
+ oo::class create grill {
+ variable resolution
+ constructor {} {
+ dump
+ upvar 1 v w
+ dump "in grill's constructor, v resolves to $w"
+ set resolution $w
+ }
+ method whathappened {} {
+ return $resolution
+ }
+ }
+ foo create fred
+} -body {
+ set result [fred alpha]
+ if {$result ne "global level"} {
+ puts "v should have been found at global level but was found in $result"
+ }
+} -cleanup {
+ unset result
+ rename fred {}
+ rename dump {}
+ rename foo {}
+ rename bar {}
+ rename grill {}
+} -output {1: fred alpha
+1: inside foo's alpha, v resolves to global level
+1: foo's alpha is calling ::fred bravo - v should resolve at global level
+1: ::fred bravo
+1: inside foo's bravo, v resolves to global level
+1: foo's bravo is calling charlie to create barney
+2: my charlie ::barney
+2: tailcalling bar's constructor
+1: foo's bravo is calling bravo on ::barney
+1: v should resolve at global scope there
+1: ::barney bravo
+1: inside bar's bravo, v is resolving to global level
+1: calling delta to construct betty - v should resolve global there
+1: ::barney delta ::betty
+1: inside bar's delta, v is resolving to global level
+1: tailcalling to construct ::betty as instance of grill
+1: v should resolve at global level in grill's constructor
+1: grill's constructor should run at level 1
+1: grill create ::betty
+1: in grill's constructor, v resolves to global level
+1: exiting from bar's bravo
+1: exiting from foo's bravo
+1: exiting from foo's alpha
+}
+
+test tailcall-12.3a0 {[Bug 2695587]} -body {
+ apply {{} {
+ catch [list tailcall foo]
+ }}
+} -returnCodes 1 -result {invalid command name "foo"}
+
+test tailcall-12.3a1 {[Bug 2695587]} -body {
+ apply {{} {
+ catch [list tailcall foo]
+ tailcall
+ }}
+} -result {}
+
+test tailcall-12.3a2 {[Bug 2695587]} -body {
+ apply {{} {
+ catch [list tailcall foo]
+ tailcall moo
+ }}
+} -returnCodes 1 -result {invalid command name "moo"}
+
+test tailcall-12.3a3 {[Bug 2695587]} -body {
+ set x 0
+ apply {{} {
+ catch [list tailcall foo]
+ tailcall lappend x 1
+ }}
+ set x
+} -cleanup {
+ unset x
+} -result {0 1}
+
+test tailcall-12.3b0 {[Bug 2695587]} -body {
+ apply {{} {
+ set catch catch
+ $catch [list tailcall foo]
+ }}
+} -returnCodes 1 -result {invalid command name "foo"}
+
+test tailcall-12.3b1 {[Bug 2695587]} -body {
+ apply {{} {
+ set catch catch
+ $catch [list tailcall foo]
+ tailcall
+ }}
+} -result {}
+
+test tailcall-12.3b2 {[Bug 2695587]} -body {
+ apply {{} {
+ set catch catch
+ $catch [list tailcall foo]
+ tailcall moo
+ }}
+} -returnCodes 1 -result {invalid command name "moo"}
+
+test tailcall-12.3b3 {[Bug 2695587]} -body {
+ set x 0
+ apply {{} {
+ set catch catch
+ $catch [list tailcall foo]
+ tailcall lappend x 1
+ }}
+ set x
+} -cleanup {
+ unset x
+} -result {0 1}
+
+# MORE VARIANTS MISSING: bc'ed caught script vs (bc'ed, not-bc'ed)
+# catch. Actually superfluous now, as tailcall just returns TCL_RETURN so that
+# standard catch behaviour is required.
+
+test tailcall-13.1 {directly tailcalling the tailcall command is ok} {
+ list [catch {
+ apply {{} {
+ apply {{} {
+ tailcall tailcall subst ok
+ subst b
+ }}
+ subst c
+ }}
+ } msg opt] $msg [errorcode $opt]
+} {0 ok NONE}
+test tailcall-13.2 {indirectly tailcalling the tailcall command is ok} {
+ list [catch {
+ apply {{} {
+ apply {{} {
+ tailcall eval tailcall subst ok
+ subst b
+ }}
+ subst c
+ }}
+ } msg opt] $msg [errorcode $opt]
+} {0 ok NONE}
+
+if {[testConstraint testnrelevels]} {
+ namespace forget testnre::*
+ namespace delete testnre
+}
+
+# cleanup
+::tcltest::cleanupTests
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/tcltest.test b/pkgs/msgcat/tests/tcltest.test
new file mode 100755
index 0000000..86aca6f
--- /dev/null
+++ b/pkgs/msgcat/tests/tcltest.test
@@ -0,0 +1,1837 @@
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2000 by Ajuba Solutions
+# All rights reserved.
+
+# Note that there are several places where the value of
+# tcltest::currentFailure is stored/reset in the -setup/-cleanup
+# of a test that has a body that runs [test] that will fail.
+# This is a workaround of using the same tcltest code that we are
+# testing to run the test itself. Ditto on things like [verbose].
+#
+# It would be better to have the -body of the tests run the tcltest
+# commands in a slave interp so the [test] being tested would not
+# interfere with the [test] doing the testing.
+#
+
+if {[catch {package require tcltest 2.1}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2.1 required."
+ return
+}
+
+namespace eval ::tcltest::test {
+
+namespace import ::tcltest::*
+
+makeFile {
+ package require tcltest
+ namespace import ::tcltest::test
+ test a-1.0 {test a} {
+ list 0
+ } {0}
+ test b-1.0 {test b} {
+ list 1
+ } {0}
+ test c-1.0 {test c} {knownBug} {
+ } {}
+ test d-1.0 {test d} {
+ error "foo" foo 9
+ } {}
+ tcltest::cleanupTests
+ exit
+} test.tcl
+
+cd [temporaryDirectory]
+testConstraint exec [llength [info commands exec]]
+# test -help
+# Child processes because -help [exit]s.
+test tcltest-1.1 {tcltest -help} {exec} {
+ set result [catch {exec [interpreter] test.tcl -help} msg]
+ list $result [regexp Usage $msg]
+} {1 1}
+test tcltest-1.2 {tcltest -help -something} {exec} {
+ set result [catch {exec [interpreter] test.tcl -help -something} msg]
+ list $result [regexp Usage $msg]
+} {1 1}
+test tcltest-1.3 {tcltest -h} {exec} {
+ set result [catch {exec [interpreter] test.tcl -h} msg]
+ list $result [regexp Usage $msg]
+} {1 0}
+
+# -verbose, implicit & explicit testing of [verbose]
+proc slave {msgVar args} {
+ upvar 1 $msgVar msg
+
+ interp create [namespace current]::i
+ # Fake the slave interp into dumping output to a file
+ i eval {namespace eval ::tcltest {}}
+ i eval "set tcltest::outputChannel\
+ \[[list open [set of [makeFile {} output]] w]]"
+ i eval "set tcltest::errorChannel\
+ \[[list open [set ef [makeFile {} error]] w]]"
+ i eval [list set argv0 [lindex $args 0]]
+ i eval [list set argv [lrange $args 1 end]]
+ i eval [list package ifneeded tcltest [package provide tcltest] \
+ [package ifneeded tcltest [package provide tcltest]]]
+ i eval {proc exit args {}}
+
+ # Need to capture output in msg
+
+ set code [catch {i eval {source $argv0}} foo]
+if $code {
+#puts "$code: $foo\n$::errorInfo"
+}
+ i eval {close $tcltest::outputChannel}
+ interp delete [namespace current]::i
+ set f [open $of]
+ set msg [read -nonewline $f]
+ close $f
+ set f [open $ef]
+ set err [read -nonewline $f]
+ close $f
+ removeFile output
+ removeFile error
+ if {[string length $err]} {
+ set code 1
+ append msg \n$err
+ }
+ return $code
+
+# return [catch {uplevel 1 [linsert $args 0 exec [interpreter]]} msg]
+}
+test tcltest-2.0 {tcltest (verbose default - 'b')} {unixOrPc} {
+ set result [slave msg test.tcl]
+ list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+ [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 1 0 0 1}
+test tcltest-2.1 {tcltest -verbose 'b'} {unixOrPc} {
+ set result [slave msg test.tcl -verbose 'b']
+ list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+ [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 1 0 0 1}
+test tcltest-2.2 {tcltest -verbose 'p'} {unixOrPc} {
+ set result [slave msg test.tcl -verbose 'p']
+ list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+ [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 0 1 0 1}
+test tcltest-2.3 {tcltest -verbose 's'} {unixOrPc} {
+ set result [slave msg test.tcl -verbose 's']
+ list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+ [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 0 0 1 1}
+test tcltest-2.4 {tcltest -verbose 'ps'} {unixOrPc} {
+ set result [slave msg test.tcl -verbose 'ps']
+ list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+ [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 0 1 1 1}
+test tcltest-2.5 {tcltest -verbose 'psb'} {unixOrPc} {
+ set result [slave msg test.tcl -verbose 'psb']
+ list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+ [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 1 1 1 1}
+
+test tcltest-2.5a {tcltest -verbose 'pass skip body'} {unixOrPc} {
+ set result [slave msg test.tcl -verbose "pass skip body"]
+ list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+ [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 1 1 1 1}
+
+test tcltest-2.6 {tcltest -verbose 't'} {
+ -constraints {unixOrPc}
+ -body {
+ set result [slave msg test.tcl -verbose 't']
+ list $result $msg
+ }
+ -result {^0 .*a-1.0 start.*b-1.0 start}
+ -match regexp
+}
+
+test tcltest-2.6a {tcltest -verbose 'start'} {
+ -constraints {unixOrPc}
+ -body {
+ set result [slave msg test.tcl -verbose start]
+ list $result $msg
+ }
+ -result {^0 .*a-1.0 start.*b-1.0 start}
+ -match regexp
+}
+
+test tcltest-2.7 {tcltest::verbose} {
+ -body {
+ set oldVerbosity [verbose]
+ verbose bar
+ set currentVerbosity [verbose]
+ verbose foo
+ set newVerbosity [verbose]
+ verbose $oldVerbosity
+ list $currentVerbosity $newVerbosity
+ }
+ -result {body {}}
+}
+
+test tcltest-2.8 {tcltest -verbose 'error'} {
+ -constraints {unixOrPc}
+ -body {
+ set result [slave msg test.tcl -verbose error]
+ list $result $msg
+ }
+ -result {errorInfo: foo.*errorCode: 9}
+ -match regexp
+}
+# -match, [match]
+test tcltest-3.1 {tcltest -match 'a*'} {unixOrPc} {
+ set result [slave msg test.tcl -match a* -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+3.+Failed.+0" $msg]
+} {0 1 0 0 1}
+test tcltest-3.2 {tcltest -match 'b*'} {unixOrPc} {
+ set result [slave msg test.tcl -match b* -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+0.+Skipped.+3.+Failed.+1" $msg]
+} {0 0 1 0 1}
+test tcltest-3.3 {tcltest -match 'c*'} {unixOrPc} {
+ set result [slave msg test.tcl -match c* -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+0.+Skipped.+4.+Failed.+0" $msg]
+} {0 0 0 1 1}
+test tcltest-3.4 {tcltest -match 'a* b*'} {unixOrPc} {
+ set result [slave msg test.tcl -match {a* b*} -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+2.+Failed.+1" $msg]
+} {0 1 1 0 1}
+
+test tcltest-3.5 {tcltest::match} {
+ -body {
+ set oldMatch [match]
+ match foo
+ set currentMatch [match]
+ match bar
+ set newMatch [match]
+ match $oldMatch
+ list $currentMatch $newMatch
+ }
+ -result {foo bar}
+}
+
+# -skip, [skip]
+test tcltest-4.1 {tcltest -skip 'a*'} {unixOrPc} {
+ set result [slave msg test.tcl -skip a* -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+0.+Skipped.+2.+Failed.+1" $msg]
+} {0 0 1 1 1}
+test tcltest-4.2 {tcltest -skip 'b*'} {unixOrPc} {
+ set result [slave msg test.tcl -skip b* -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+2.+Failed.+1" $msg]
+} {0 1 0 1 1}
+test tcltest-4.3 {tcltest -skip 'c*'} {unixOrPc} {
+ set result [slave msg test.tcl -skip c* -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 1 1 0 1}
+test tcltest-4.4 {tcltest -skip 'a* b*'} {unixOrPc} {
+ set result [slave msg test.tcl -skip {a* b*} -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+0.+Skipped.+3.+Failed.+1" $msg]
+} {0 0 0 1 1}
+test tcltest-4.5 {tcltest -match 'a* b*' -skip 'b*'} {unixOrPc} {
+ set result [slave msg test.tcl -match {a* b*} -skip b* -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+3.+Failed.+0" $msg]
+} {0 1 0 0 1}
+
+test tcltest-4.6 {tcltest::skip} {
+ -body {
+ set oldSkip [skip]
+ skip foo
+ set currentSkip [skip]
+ skip bar
+ set newSkip [skip]
+ skip $oldSkip
+ list $currentSkip $newSkip
+ }
+ -result {foo bar}
+}
+
+# -constraints, -limitconstraints, [testConstraint],
+# $constraintsSpecified, [limitConstraints]
+test tcltest-5.1 {tcltest -constraints 'knownBug'} {unixOrPc} {
+ set result [slave msg test.tcl -constraints knownBug -verbose 'ps']
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+2.+Skipped.+0.+Failed.+2" $msg]
+} {0 1 1 1 1}
+test tcltest-5.2 {tcltest -constraints 'knownBug' -limitconstraints 1} {unixOrPc} {
+ set result [slave msg test.tcl -constraints knownBug -verbose 'p' -limitconstraints 1]
+ list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+ [regexp "Total.+4.+Passed.+1.+Skipped.+3.+Failed.+0" $msg]
+} {0 0 0 1 1}
+
+test tcltest-5.3 {testConstraint - constraint empty (tcltest::safeFetch)} {
+ -body {
+ set r1 [testConstraint tcltestFakeConstraint]
+ set r2 [testConstraint tcltestFakeConstraint 4]
+ set r3 [testConstraint tcltestFakeConstraint]
+ list $r1 $r2 $r3
+ }
+ -result {0 4 4}
+ -cleanup {unset ::tcltest::testConstraints(tcltestFakeConstraint)}
+}
+
+# Removed this test of internals of tcltest. Those internals have changed.
+#test tcltest-5.4 {tcltest::constraintsSpecified} {
+# -setup {
+# set constraintlist $::tcltest::constraintsSpecified
+# set ::tcltest::constraintsSpecified {}
+# }
+# -body {
+# set r1 $::tcltest::constraintsSpecified
+# testConstraint tcltestFakeConstraint1 1
+# set r2 $::tcltest::constraintsSpecified
+# testConstraint tcltestFakeConstraint2 1
+# set r3 $::tcltest::constraintsSpecified
+# list $r1 $r2 $r3
+# }
+# -result {{} tcltestFakeConstraint1 {tcltestFakeConstraint1 tcltestFakeConstraint2}}
+# -cleanup {
+# set ::tcltest::constraintsSpecified $constraintlist
+# unset ::tcltest::testConstraints(tcltestFakeConstraint1)
+# unset ::tcltest::testConstraints(tcltestFakeConstraint2)
+# }
+#}
+
+test tcltest-5.5 {InitConstraints: list of built-in constraints} \
+ -constraints {!singleTestInterp} \
+ -setup {tcltest::InitConstraints} \
+ -body { lsort [array names ::tcltest::testConstraints] } \
+ -result [lsort {
+ 95 98 asyncPipeClose eformat emptyTest exec hasIsoLocale interactive
+ knownBug mac macCrash macOnly macOrPc macOrUnix macOrWin nonBlockFiles
+ nonPortable notRoot nt pc pcCrash pcOnly root singleTestInterp socket
+ stdio tempNotMac tempNotPc tempNotUnix tempNotWin unix unixCrash unixExecs
+ unixOnly unixOrPc unixOrWin userInteraction win winCrash winOnly
+}]
+
+# Removed this broken test. Its usage of [limitConstraints] was not
+# in agreement with the documentation. [limitConstraints] is supposed
+# to take an optional boolean argument, and "knownBug" ain't no boolean!
+#test tcltest-5.6 {tcltest::limitConstraints} {
+# -setup {
+# set keeplc $::tcltest::limitConstraints
+# set keepkb [testConstraint knownBug]
+# }
+# -body {
+# set r1 [limitConstraints]
+# set r2 [limitConstraints knownBug]
+# set r3 [limitConstraints]
+# list $r1 $r2 $r3
+# }
+# -cleanup {
+# limitConstraints $keeplc
+# testConstraint knownBug $keepkb
+# }
+# -result {false knownBug knownBug}
+#}
+
+# -outfile, -errfile, [outputChannel], [outputFile], [errorChannel], [errorFile]
+set printerror [makeFile {
+ package require tcltest
+ namespace import ::tcltest::*
+ puts [outputChannel] "a test"
+ ::tcltest::PrintError "a really short string"
+ ::tcltest::PrintError "a really really really really really really long \
+ string containing \"quotes\" and other bad bad stuff"
+ ::tcltest::PrintError "a really really long string containing a \
+ \"Path/that/is/really/long/and/contains/no/spaces\""
+ ::tcltest::PrintError "a really really long string containing a \
+ \"Really/Long/Path/that/contains/no/spaces/and/is/longer/than/eighty/characters/to/see/what/happens\""
+ ::tcltest::PrintError "Problem renaming file: error renaming \"Z:/ws/tcl8.2/win32-ix86/tests/core\" to \"Z:/ws/tcl8.2/win32-ix86/tests/movecore-core\""
+ exit
+} printerror.tcl]
+
+test tcltest-6.1 {tcltest -outfile, -errfile defaults} {
+ -constraints unixOrPc
+ -body {
+ slave msg $printerror
+ return $msg
+ }
+ -result {a test.*a really}
+ -match regexp
+}
+test tcltest-6.2 {tcltest -outfile a.tmp} {unixOrPc unixExecs} {
+ slave msg $printerror -outfile a.tmp
+ set result1 [catch {exec grep "a test" a.tmp}]
+ set result2 [catch {exec grep "a really" a.tmp}]
+ list [regexp "a test" $msg] [regexp "a really" $msg] \
+ $result1 $result2 [file exists a.tmp] [file delete a.tmp]
+} {0 1 0 1 1 {}}
+test tcltest-6.3 {tcltest -errfile a.tmp} {unixOrPc unixExecs} {
+ slave msg $printerror -errfile a.tmp
+ set result1 [catch {exec grep "a test" a.tmp}]
+ set result2 [catch {exec grep "a really" a.tmp}]
+ list [regexp "a test" $msg] [regexp "a really" $msg] \
+ $result1 $result2 [file exists a.tmp] [file delete a.tmp]
+} {1 0 1 0 1 {}}
+test tcltest-6.4 {tcltest -outfile a.tmp -errfile b.tmp} {unixOrPc unixExecs} {
+ slave msg $printerror -outfile a.tmp -errfile b.tmp
+ set result1 [catch {exec grep "a test" a.tmp}]
+ set result2 [catch {exec grep "a really" b.tmp}]
+ list [regexp "a test" $msg] [regexp "a really" $msg] \
+ $result1 $result2 \
+ [file exists a.tmp] [file delete a.tmp] \
+ [file exists b.tmp] [file delete b.tmp]
+} {0 0 0 0 1 {} 1 {}}
+
+test tcltest-6.5 {tcltest::errorChannel - retrieval} {
+ -setup {
+ set of [errorChannel]
+ set ::tcltest::errorChannel stderr
+ }
+ -body {
+ errorChannel
+ }
+ -result {stderr}
+ -cleanup {
+ set ::tcltest::errorChannel $of
+ }
+}
+
+test tcltest-6.6 {tcltest::errorFile (implicit errorChannel)} {
+ -setup {
+ set ef [makeFile {} efile]
+ set of [errorFile]
+ set ::tcltest::errorChannel stderr
+ set ::tcltest::errorFile stderr
+ }
+ -body {
+ set f0 [errorChannel]
+ set f1 [errorFile]
+ set f2 [errorFile $ef]
+ set f3 [errorChannel]
+ set f4 [errorFile]
+ subst {$f0;$f1;$f2;$f3;$f4}
+ }
+ -result {stderr;stderr;.*efile;file[0-9a-f]+;.*efile}
+ -match regexp
+ -cleanup {
+ errorFile $of
+ removeFile efile
+ }
+}
+test tcltest-6.7 {tcltest::outputChannel - retrieval} {
+ -setup {
+ set of [outputChannel]
+ set ::tcltest::outputChannel stdout
+ }
+ -body {
+ outputChannel
+ }
+ -result {stdout}
+ -cleanup {
+ set ::tcltest::outputChannel $of
+ }
+}
+
+test tcltest-6.8 {tcltest::outputFile (implicit outputFile)} {
+ -setup {
+ set ef [makeFile {} efile]
+ set of [outputFile]
+ set ::tcltest::outputChannel stdout
+ set ::tcltest::outputFile stdout
+ }
+ -body {
+ set f0 [outputChannel]
+ set f1 [outputFile]
+ set f2 [outputFile $ef]
+ set f3 [outputChannel]
+ set f4 [outputFile]
+ subst {$f0;$f1;$f2;$f3;$f4}
+ }
+ -result {stdout;stdout;.*efile;file[0-9a-f]+;.*efile}
+ -match regexp
+ -cleanup {
+ outputFile $of
+ removeFile efile
+ }
+}
+
+# -debug, [debug]
+# Must use child processes to test -debug because it always writes
+# messages to stdout, and we have no way to capture stdout of a
+# slave interp
+test tcltest-7.1 {tcltest test.tcl -debug 0} {unixOrPc} {
+ catch {exec [interpreter] test.tcl -debug 0} msg
+ regexp "Flags passed into tcltest" $msg
+} {0}
+test tcltest-7.2 {tcltest test.tcl -debug 1} {unixOrPc} {
+ catch {exec [interpreter] test.tcl -debug 1 -skip b*} msg
+ list [regexp userSpecifiedSkip $msg] \
+ [regexp "Flags passed into tcltest" $msg]
+} {1 0}
+test tcltest-7.3 {tcltest test.tcl -debug 1} {unixOrPc} {
+ catch {exec [interpreter] test.tcl -debug 1 -match b*} msg
+ list [regexp userSpecifiedNonMatch $msg] \
+ [regexp "Flags passed into tcltest" $msg]
+} {1 0}
+test tcltest-7.4 {tcltest test.tcl -debug 2} {unixOrPc} {
+ catch {exec [interpreter] test.tcl -debug 2} msg
+ list [regexp "Flags passed into tcltest" $msg] [regexp "Running" $msg]
+} {1 0}
+test tcltest-7.5 {tcltest test.tcl -debug 3} {unixOrPc} {
+ catch {exec [interpreter] test.tcl -debug 3} msg
+ list [regexp "Flags passed into tcltest" $msg] [regexp "Running" $msg]
+} {1 1}
+
+test tcltest-7.6 {tcltest::debug} {
+ -setup {
+ set old $::tcltest::debug
+ set ::tcltest::debug 0
+ }
+ -body {
+ set f1 [debug]
+ set f2 [debug 1]
+ set f3 [debug]
+ set f4 [debug 2]
+ set f5 [debug]
+ list $f1 $f2 $f3 $f4 $f5
+ }
+ -result {0 1 1 2 2}
+ -cleanup {
+ set ::tcltest::debug $old
+ }
+}
+removeFile test.tcl
+
+# directory tests
+
+set a [makeFile {
+ package require tcltest
+ tcltest::makeFile {} a.tmp
+ puts [tcltest::outputChannel] "testdir: [tcltest::testsDirectory]"
+ exit
+} a.tcl]
+
+set tdiaf [makeFile {} thisdirectoryisafile]
+
+set normaldirectory [makeDirectory normaldirectory]
+normalizePath normaldirectory
+
+# -tmpdir, [temporaryDirectory]
+test tcltest-8.1 {tcltest a.tcl -tmpdir a} -constraints unixOrPc -setup {
+ file delete -force thisdirectorydoesnotexist
+} -body {
+ slave msg $a -tmpdir thisdirectorydoesnotexist
+ file exists [file join thisdirectorydoesnotexist a.tmp]
+} -cleanup {
+ file delete -force thisdirectorydoesnotexist
+} -result 1
+test tcltest-8.2 {tcltest a.tcl -tmpdir thisdirectoryisafile} {
+ -constraints unixOrPc
+ -body {
+ slave msg $a -tmpdir $tdiaf
+ return $msg
+ }
+ -result {*not a directory*}
+ -match glob
+}
+# Test non-writeable directories, non-readable directories with directory flags
+set notReadableDir [file join [temporaryDirectory] notreadable]
+set notWriteableDir [file join [temporaryDirectory] notwriteable]
+makeDirectory notreadable
+makeDirectory notwriteable
+switch -- $::tcl_platform(platform) {
+ "unix" {
+ file attributes $notReadableDir -permissions 00333
+ file attributes $notWriteableDir -permissions 00555
+ }
+ default {
+ catch {file attributes $notWriteableDir -readonly 1}
+ catch {testchmod 000 $notWriteableDir}
+ }
+}
+test tcltest-8.3 {tcltest a.tcl -tmpdir notReadableDir} {
+ -constraints {unix notRoot}
+ -body {
+ slave msg $a -tmpdir $notReadableDir
+ return $msg
+ }
+ -result {*not readable*}
+ -match glob
+}
+# This constraint doesn't go at the top of the file so that it doesn't
+# interfere with tcltest-5.5
+testConstraint notFAT [expr {
+ ![string match "FAT*" [lindex [file system $notWriteableDir] 1]]
+}]
+# FAT permissions are fairly hopeless; ignore this test if that FS is used
+test tcltest-8.4 {tcltest a.tcl -tmpdir notWriteableDir} {
+ -constraints {unixOrPc notRoot notFAT}
+ -body {
+ slave msg $a -tmpdir $notWriteableDir
+ return $msg
+ }
+ -result {*not writeable*}
+ -match glob
+}
+test tcltest-8.5 {tcltest a.tcl -tmpdir normaldirectory} {
+ -constraints unixOrPc
+ -body {
+ slave msg $a -tmpdir $normaldirectory
+ # The join is necessary because the message can be split on multiple
+ # lines
+ file exists [file join $normaldirectory a.tmp]
+ }
+ -cleanup {
+ catch {file delete [file join $normaldirectory a.tmp]}
+ }
+ -result 1
+}
+cd [workingDirectory]
+test tcltest-8.6 {temporaryDirectory} {
+ -setup {
+ set old $::tcltest::temporaryDirectory
+ set ::tcltest::temporaryDirectory $normaldirectory
+ }
+ -body {
+ set f1 [temporaryDirectory]
+ set f2 [temporaryDirectory [workingDirectory]]
+ set f3 [temporaryDirectory]
+ list $f1 $f2 $f3
+ }
+ -result "[list $normaldirectory [workingDirectory] [workingDirectory]]"
+ -cleanup {
+ set ::tcltest::temporaryDirectory $old
+ }
+}
+test tcltest-8.6a {temporaryDirectory - test format 2} -setup {
+ set old $::tcltest::temporaryDirectory
+ set ::tcltest::temporaryDirectory $normaldirectory
+} -body {
+ set f1 [temporaryDirectory]
+ set f2 [temporaryDirectory [workingDirectory]]
+ set f3 [temporaryDirectory]
+ list $f1 $f2 $f3
+} -cleanup {
+ set ::tcltest::temporaryDirectory $old
+} -result [list $normaldirectory [workingDirectory] [workingDirectory]]
+cd [temporaryDirectory]
+# -testdir, [testsDirectory]
+test tcltest-8.10 {tcltest a.tcl -testdir thisdirectorydoesnotexist} {
+ -constraints unixOrPc
+ -setup {
+ file delete -force thisdirectorydoesnotexist
+ }
+ -body {
+ slave msg $a -testdir thisdirectorydoesnotexist
+ return $msg
+ }
+ -match glob
+ -result {*does not exist*}
+}
+test tcltest-8.11 {tcltest a.tcl -testdir thisdirectoryisafile} {
+ -constraints unixOrPc
+ -body {
+ slave msg $a -testdir $tdiaf
+ return $msg
+ }
+ -match glob
+ -result {*not a directory*}
+}
+test tcltest-8.12 {tcltest a.tcl -testdir notReadableDir} {
+ -constraints {unix notRoot}
+ -body {
+ slave msg $a -testdir $notReadableDir
+ return $msg
+ }
+ -match glob
+ -result {*not readable*}
+}
+test tcltest-8.13 {tcltest a.tcl -testdir normaldirectory} {
+ -constraints unixOrPc
+ -body {
+ slave msg $a -testdir $normaldirectory
+ # The join is necessary because the message can be split on multiple
+ # lines
+ list [string first "testdir: $normaldirectory" [join $msg]] \
+ [file exists [file join [temporaryDirectory] a.tmp]]
+ }
+ -cleanup {
+ file delete [file join [temporaryDirectory] a.tmp]
+ }
+ -result {0 1}
+}
+cd [workingDirectory]
+set current [pwd]
+test tcltest-8.14 {testsDirectory} {
+ -setup {
+ set old $::tcltest::testsDirectory
+ set ::tcltest::testsDirectory $normaldirectory
+ }
+ -body {
+ set f1 [testsDirectory]
+ set f2 [testsDirectory $current]
+ set f3 [testsDirectory]
+ list $f1 $f2 $f3
+ }
+ -result "[list $normaldirectory $current $current]"
+ -cleanup {
+ set ::tcltest::testsDirectory $old
+ }
+}
+# [workingDirectory]
+test tcltest-8.60 {::workingDirectory} {
+ -setup {
+ set old $::tcltest::workingDirectory
+ set current [pwd]
+ set ::tcltest::workingDirectory $normaldirectory
+ cd $normaldirectory
+ }
+ -body {
+ set f1 [workingDirectory]
+ set f2 [pwd]
+ set f3 [workingDirectory $current]
+ set f4 [pwd]
+ set f5 [workingDirectory]
+ list $f1 $f2 $f3 $f4 $f5
+ }
+ -result "[list $normaldirectory \
+ $normaldirectory \
+ $current \
+ $current \
+ $current]"
+ -cleanup {
+ set ::tcltest::workingDirectory $old
+ cd $current
+ }
+}
+
+# clean up from directory testing
+
+switch $::tcl_platform(platform) {
+ "unix" {
+ file attributes $notReadableDir -permissions 777
+ file attributes $notWriteableDir -permissions 777
+ }
+ default {
+ catch {testchmod 777 $notWriteableDir}
+ catch {file attributes $notWriteableDir -readonly 0}
+ }
+}
+
+file delete -force $notReadableDir $notWriteableDir
+removeFile a.tcl
+removeFile thisdirectoryisafile
+removeDirectory normaldirectory
+
+# -file, -notfile, [matchFiles], [skipFiles]
+test tcltest-9.1 {-file d*.tcl} -constraints {unixOrPc} -setup {
+ set old [testsDirectory]
+ testsDirectory [file dirname [info script]]
+} -body {
+ slave msg [file join [testsDirectory] all.tcl] -file d*.test
+ return $msg
+} -cleanup {
+ testsDirectory $old
+} -match regexp -result {dstring\.test}
+
+test tcltest-9.2 {-file d*.tcl} -constraints {unixOrPc} -setup {
+ set old [testsDirectory]
+ testsDirectory [file dirname [info script]]
+} -body {
+ slave msg [file join [testsDirectory] all.tcl] \
+ -file d*.test -notfile dstring*
+ regexp {dstring\.test} $msg
+} -cleanup {
+ testsDirectory $old
+} -result 0
+
+test tcltest-9.3 {matchFiles} {
+ -body {
+ set old [matchFiles]
+ matchFiles foo
+ set current [matchFiles]
+ matchFiles bar
+ set new [matchFiles]
+ matchFiles $old
+ list $current $new
+ }
+ -result {foo bar}
+}
+
+test tcltest-9.4 {skipFiles} {
+ -body {
+ set old [skipFiles]
+ skipFiles foo
+ set current [skipFiles]
+ skipFiles bar
+ set new [skipFiles]
+ skipFiles $old
+ list $current $new
+ }
+ -result {foo bar}
+}
+
+test tcltest-9.5 {GetMatchingFiles: Bug 1119798} -setup {
+ set d [makeDirectory tmp]
+ makeDirectory foo $d
+ makeFile {} fee $d
+ file copy [file join [file dirname [info script]] all.tcl] $d
+} -body {
+ slave msg [file join [temporaryDirectory] all.tcl] -file f*
+ regexp {exiting with errors:} $msg
+} -cleanup {
+ file delete [file join $d all.tcl]
+ removeFile fee $d
+ removeDirectory foo $d
+ removeDirectory tmp
+} -result 0
+
+# -preservecore, [preserveCore]
+set mc [makeFile {
+ package require tcltest
+ namespace import ::tcltest::test
+ test makecore {make a core file} {
+ set f [open core w]
+ close $f
+ } {}
+ ::tcltest::cleanupTests
+ return
+} makecore.tcl]
+
+cd [temporaryDirectory]
+test tcltest-10.1 {-preservecore 0} {unixOrPc} {
+ slave msg $mc -preservecore 0
+ file delete core
+ regexp "Core file produced" $msg
+} {0}
+test tcltest-10.2 {-preservecore 1} {unixOrPc} {
+ slave msg $mc -preservecore 1
+ file delete core
+ regexp "Core file produced" $msg
+} {1}
+test tcltest-10.3 {-preservecore 2} {unixOrPc} {
+ slave msg $mc -preservecore 2
+ file delete core
+ list [regexp "Core file produced" $msg] [regexp "Moving file to" $msg] \
+ [regexp "core-" $msg] [file delete core-makecore]
+} {1 1 1 {}}
+test tcltest-10.4 {-preservecore 3} {unixOrPc} {
+ slave msg $mc -preservecore 3
+ file delete core
+ list [regexp "Core file produced" $msg] [regexp "Moving file to" $msg] \
+ [regexp "core-" $msg] [file delete core-makecore]
+} {1 1 1 {}}
+
+# Removing this test. It makes no sense to test the ability of
+# [preserveCore] to accept an invalid value that will cause errors
+# in other parts of tcltest's operation.
+#test tcltest-10.5 {preserveCore} {
+# -body {
+# set old [preserveCore]
+# set result [preserveCore foo]
+# set result2 [preserveCore]
+# preserveCore $old
+# list $result $result2
+# }
+# -result {foo foo}
+#}
+removeFile makecore.tcl
+
+# -load, -loadfile, [loadScript], [loadFile]
+set contents {
+ package require tcltest
+ namespace import tcltest::*
+ puts [outputChannel] $::tcltest::loadScript
+ exit
+}
+set loadfile [makeFile $contents load.tcl]
+
+test tcltest-12.1 {-load xxx} {unixOrPc} {
+ slave msg $loadfile -load xxx
+ return $msg
+} {xxx}
+
+# Using child process because of -debug usage.
+test tcltest-12.2 {-loadfile load.tcl} {unixOrPc} {
+ catch {exec [interpreter] $loadfile -debug 2 -loadfile $loadfile} msg
+ list \
+ [regexp {tcltest} [join [list $msg] [split $msg \n]]] \
+ [regexp {loadScript} [join [list $msg] [split $msg \n]]]
+} {1 1}
+
+test tcltest-12.3 {loadScript} {
+ -setup {
+ set old $::tcltest::loadScript
+ set ::tcltest::loadScript {}
+ }
+ -body {
+ set f1 [loadScript]
+ set f2 [loadScript xxx]
+ set f3 [loadScript]
+ list $f1 $f2 $f3
+ }
+ -result {{} xxx xxx}
+ -cleanup {
+ set ::tcltest::loadScript $old
+ }
+}
+
+test tcltest-12.4 {loadFile} {
+ -setup {
+ set olds $::tcltest::loadScript
+ set ::tcltest::loadScript {}
+ set oldf $::tcltest::loadFile
+ set ::tcltest::loadFile {}
+ }
+ -body {
+ set f1 [loadScript]
+ set f2 [loadFile]
+ set f3 [loadFile $loadfile]
+ set f4 [loadScript]
+ set f5 [loadFile]
+ list $f1 $f2 $f3 $f4 $f5
+ }
+ -result "[list {} {} $loadfile $contents $loadfile]\n"
+ -cleanup {
+ set ::tcltest::loadScript $olds
+ set ::tcltest::loadFile $oldf
+ }
+}
+removeFile load.tcl
+
+# [interpreter]
+test tcltest-13.1 {interpreter} {
+ -setup {
+ set old $::tcltest::tcltest
+ set ::tcltest::tcltest tcltest
+ }
+ -body {
+ set f1 [interpreter]
+ set f2 [interpreter tclsh]
+ set f3 [interpreter]
+ list $f1 $f2 $f3
+ }
+ -result {tcltest tclsh tclsh}
+ -cleanup {
+ set ::tcltest::tcltest $old
+ }
+}
+
+# -singleproc, [singleProcess]
+set spd [makeDirectory singleprocdir]
+makeFile {
+ set foo 1
+} single1.test $spd
+
+makeFile {
+ unset foo
+} single2.test $spd
+
+set allfile [makeFile {
+ package require tcltest
+ namespace import tcltest::*
+ testsDirectory [file join [temporaryDirectory] singleprocdir]
+ runAllTests
+} all-single.tcl $spd]
+cd [workingDirectory]
+
+test tcltest-14.1 {-singleproc - single process} {
+ -constraints {unixOrPc}
+ -body {
+ slave msg $allfile -singleproc 0 -tmpdir [temporaryDirectory]
+ return $msg
+ }
+ -result {Test file error: can't unset .foo.: no such variable}
+ -match regexp
+}
+
+test tcltest-14.2 {-singleproc - multiple process} {
+ -constraints {unixOrPc}
+ -body {
+ slave msg $allfile -singleproc 1 -tmpdir [temporaryDirectory]
+ return $msg
+ }
+ -result {single1.test.*single2.test.*all\-single.tcl:.*Total.*0.*Passed.*0.*Skipped.*0.*Failed.*0}
+ -match regexp
+}
+
+test tcltest-14.3 {singleProcess} {
+ -setup {
+ set old $::tcltest::singleProcess
+ set ::tcltest::singleProcess 0
+ }
+ -body {
+ set f1 [singleProcess]
+ set f2 [singleProcess 1]
+ set f3 [singleProcess]
+ list $f1 $f2 $f3
+ }
+ -result {0 1 1}
+ -cleanup {
+ set ::tcltest::singleProcess $old
+ }
+}
+removeFile single1.test $spd
+removeFile single2.test $spd
+removeDirectory singleprocdir
+
+# -asidefromdir, -relateddir, [matchDirectories], [skipDirectories]
+
+# Before running these tests, need to set up test subdirectories with their own
+# all.tcl files.
+
+set dtd [makeDirectory dirtestdir]
+set dtd1 [makeDirectory dirtestdir2.1 $dtd]
+set dtd2 [makeDirectory dirtestdir2.2 $dtd]
+set dtd3 [makeDirectory dirtestdir2.3 $dtd]
+makeFile {
+ package require tcltest
+ namespace import -force tcltest::*
+ testsDirectory [file join [temporaryDirectory] dirtestdir]
+ runAllTests
+} all.tcl $dtd
+makeFile {
+ package require tcltest
+ namespace import -force tcltest::*
+ testsDirectory [file join [temporaryDirectory] dirtestdir dirtestdir2.1]
+ runAllTests
+} all.tcl $dtd1
+makeFile {
+ package require tcltest
+ namespace import -force tcltest::*
+ testsDirectory [file join [temporaryDirectory] dirtestdir dirtestdir2.2]
+ runAllTests
+} all.tcl $dtd2
+makeFile {
+ package require tcltest
+ namespace import -force tcltest::*
+ testsDirectory [file join [temporaryDirectory] dirtestdir dirtestdir2.3]
+ runAllTests
+} all.tcl $dtd3
+
+test tcltest-15.1 {basic directory walking} {
+ -constraints {unixOrPc}
+ -body {
+ if {[slave msg \
+ [file join $dtd all.tcl] \
+ -tmpdir [temporaryDirectory]] == 1} {
+ error $msg
+ }
+ }
+ -match regexp
+ -returnCodes 1
+ -result {Tests located in:.*dirtestdir.*Tests located in:.*dirtestdir2.[123].*Tests located in:.*dirtestdir2.[123].*Tests located in:.*dirtestdir2.[123]}
+}
+
+test tcltest-15.2 {-asidefromdir} {
+ -constraints {unixOrPc}
+ -body {
+ if {[slave msg \
+ [file join $dtd all.tcl] \
+ -asidefromdir dirtestdir2.3 \
+ -tmpdir [temporaryDirectory]] == 1} {
+ error $msg
+ }
+ }
+ -match regexp
+ -returnCodes 1
+ -result {Tests located in:.*dirtestdir.*Tests located in:.*dirtestdir2.[12].*Tests located in:.*dirtestdir2.[12].*dirtestdir2.[12] test ended at .*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Error: No test files remain after applying your match and skip patterns!
+Error: No test files remain after applying your match and skip patterns!
+Error: No test files remain after applying your match and skip patterns!$}
+}
+
+test tcltest-15.3 {-relateddir, non-existent dir} {
+ -constraints {unixOrPc}
+ -body {
+ if {[slave msg \
+ [file join $dtd all.tcl] \
+ -relateddir [file join [temporaryDirectory] dirtestdir0] \
+ -tmpdir [temporaryDirectory]] == 1} {
+ error $msg
+ }
+ }
+ -returnCodes 1
+ -match regexp
+ -result {[^~]|dirtestdir[^2]}
+}
+
+test tcltest-15.4 {-relateddir, subdir} {
+ -constraints {unixOrPc}
+ -body {
+ if {[slave msg \
+ [file join $dtd all.tcl] \
+ -relateddir dirtestdir2.1 -tmpdir [temporaryDirectory]] == 1} {
+ error $msg
+ }
+ }
+ -returnCodes 1
+ -match regexp
+ -result {Tests located in:.*dirtestdir2.[^23]}
+}
+test tcltest-15.5 {-relateddir, -asidefromdir} {
+ -constraints {unixOrPc}
+ -body {
+ if {[slave msg \
+ [file join $dtd all.tcl] \
+ -relateddir "dirtestdir2.1 dirtestdir2.2" \
+ -asidefromdir dirtestdir2.2 \
+ -tmpdir [temporaryDirectory]] == 1} {
+ error $msg
+ }
+ }
+ -match regexp
+ -returnCodes 1
+ -result {Tests located in:.*dirtestdir2.[^23]}
+}
+
+test tcltest-15.6 {matchDirectories} {
+ -setup {
+ set old [matchDirectories]
+ set ::tcltest::matchDirectories {}
+ }
+ -body {
+ set r1 [matchDirectories]
+ set r2 [matchDirectories foo]
+ set r3 [matchDirectories]
+ list $r1 $r2 $r3
+ }
+ -cleanup {
+ set ::tcltest::matchDirectories $old
+ }
+ -result {{} foo foo}
+}
+
+test tcltest-15.7 {skipDirectories} {
+ -setup {
+ set old [skipDirectories]
+ set ::tcltest::skipDirectories {}
+ }
+ -body {
+ set r1 [skipDirectories]
+ set r2 [skipDirectories foo]
+ set r3 [skipDirectories]
+ list $r1 $r2 $r3
+ }
+ -cleanup {
+ set ::tcltest::skipDirectories $old
+ }
+ -result {{} foo foo}
+}
+removeDirectory dirtestdir2.3 $dtd
+removeDirectory dirtestdir2.2 $dtd
+removeDirectory dirtestdir2.1 $dtd
+removeDirectory dirtestdir
+
+# TCLTEST_OPTIONS
+test tcltest-19.1 {TCLTEST_OPTIONS default} -setup {
+ if {[info exists ::env(TCLTEST_OPTIONS)]} {
+ set oldoptions $::env(TCLTEST_OPTIONS)
+ } else {
+ set oldoptions none
+ }
+ # set this to { } instead of just {} to get around quirk in
+ # Windows env handling that removes empty elements from env array.
+ set ::env(TCLTEST_OPTIONS) { }
+ interp create slave1
+ slave1 eval [list set argv {-debug 2}]
+ slave1 alias puts puts
+ interp create slave2
+ slave2 alias puts puts
+ } -cleanup {
+ interp delete slave2
+ interp delete slave1
+ if {$oldoptions == "none"} {
+ unset ::env(TCLTEST_OPTIONS)
+ } else {
+ set ::env(TCLTEST_OPTIONS) $oldoptions
+ }
+ } -body {
+ slave1 eval [package ifneeded tcltest [package provide tcltest]]
+ slave1 eval tcltest::debug
+ set ::env(TCLTEST_OPTIONS) "-debug 3"
+ slave2 eval [package ifneeded tcltest [package provide tcltest]]
+ slave2 eval tcltest::debug
+ } -result {^3$} -match regexp -output\
+{tcltest::debug\s+= 2.*tcltest::debug\s+= 3}
+
+# Begin testing of tcltest procs ...
+
+cd [temporaryDirectory]
+# PrintError
+test tcltest-20.1 {PrintError} {unixOrPc} {
+ set result [slave msg $printerror]
+ list $result [regexp "Error: a really short string" $msg] \
+ [regexp " \"quotes\"" $msg] [regexp " \"Path" $msg] \
+ [regexp " \"Really" $msg] [regexp Problem $msg]
+} {1 1 1 1 1 1}
+cd [workingDirectory]
+removeFile printerror.tcl
+
+# test::test
+test tcltest-21.0 {name and desc but no args specified} -setup {
+ set v [verbose]
+} -cleanup {
+ verbose $v
+} -body {
+ verbose {}
+ test tcltest-21.0.0 bar
+} -result {}
+
+test tcltest-21.1 {expect with glob} {
+ -body {
+ list a b c d e
+ }
+ -match glob
+ -result {[ab] b c d e}
+}
+
+test tcltest-21.2 {force a test command failure} {
+ -body {
+ test tcltest-21.2.0 {
+ return 2
+ } {1}
+ }
+ -returnCodes 1
+ -result {bad option "1": must be -body, -cleanup, -constraints, -errorOutput, -match, -output, -result, -returnCodes, or -setup}
+}
+
+test tcltest-21.3 {test command with setup} {
+ -setup {
+ set foo 1
+ }
+ -body {
+ set foo
+ }
+ -cleanup {unset foo}
+ -result {1}
+}
+
+test tcltest-21.4 {test command with cleanup failure} {
+ -setup {
+ if {[info exists foo]} {
+ unset foo
+ }
+ set fail $::tcltest::currentFailure
+ set v [verbose]
+ }
+ -body {
+ verbose {}
+ test tcltest-21.4.0 {foo-1} {
+ -cleanup {unset foo}
+ }
+ }
+ -result {^$}
+ -match regexp
+ -cleanup {verbose $v; set ::tcltest::currentFailure $fail}
+ -output "Test cleanup failed:.*can't unset \"foo\": no such variable"
+}
+
+test tcltest-21.5 {test command with setup failure} {
+ -setup {
+ if {[info exists foo]} {
+ unset foo
+ }
+ set fail $::tcltest::currentFailure
+ }
+ -body {
+ test tcltest-21.5.0 {foo-2} {
+ -setup {unset foo}
+ }
+ }
+ -result {^$}
+ -match regexp
+ -cleanup {set ::tcltest::currentFailure $fail}
+ -output "Test setup failed:.*can't unset \"foo\": no such variable"
+}
+
+test tcltest-21.6 {test command - setup occurs before cleanup & before script} {
+ -setup {set v [verbose]; set fail $::tcltest::currentFailure}
+ -body {
+ verbose {}
+ test tcltest-21.6.0 {foo-3} {
+ -setup {
+ if {[info exists foo]} {
+ unset foo
+ }
+ set foo 1
+ set expected 2
+ }
+ -body {
+ incr foo
+ set foo
+ }
+ -cleanup {
+ if {$foo != 2} {
+ puts [outputChannel] "foo is wrong"
+ } else {
+ puts [outputChannel] "foo is 2"
+ }
+ }
+ -result {$expected}
+ }
+ }
+ -cleanup {verbose $v; set ::tcltest::currentFailure $fail}
+ -result {^$}
+ -match regexp
+ -output "foo is 2"
+}
+
+test tcltest-21.7 {test command - bad flag} {
+ -setup {set fail $::tcltest::currentFailure}
+ -cleanup {set ::tcltest::currentFailure $fail}
+ -body {
+ test tcltest-21.7.0 {foo-4} {
+ -foobar {}
+ }
+ }
+ -returnCodes 1
+ -result {bad option "-foobar": must be -body, -cleanup, -constraints, -errorOutput, -match, -output, -result, -returnCodes, or -setup}
+}
+
+# alternate test command format (these are the same as 21.1-21.6, with the
+# exception of being in the all-inline format)
+
+test tcltest-21.7a {expect with glob} \
+ -body {list a b c d e} \
+ -result {[ab] b c d e} \
+ -match glob
+
+test tcltest-21.8 {force a test command failure} \
+ -setup {set fail $::tcltest::currentFailure} \
+ -body {
+ test tcltest-21.8.0 {
+ return 2
+ } {1}
+ } \
+ -returnCodes 1 \
+ -cleanup {set ::tcltest::currentFailure $fail} \
+ -result {bad option "1": must be -body, -cleanup, -constraints, -errorOutput, -match, -output, -result, -returnCodes, or -setup}
+
+test tcltest-21.9 {test command with setup} \
+ -setup {set foo 1} \
+ -body {set foo} \
+ -cleanup {unset foo} \
+ -result {1}
+
+test tcltest-21.10 {test command with cleanup failure} -setup {
+ if {[info exists foo]} {
+ unset foo
+ }
+ set fail $::tcltest::currentFailure
+ set v [verbose]
+} -cleanup {
+ verbose $v
+ set ::tcltest::currentFailure $fail
+} -body {
+ verbose {}
+ test tcltest-21.10.0 {foo-1} -cleanup {unset foo}
+} -result {^$} -match regexp \
+ -output {Test cleanup failed:.*can't unset \"foo\": no such variable}
+
+test tcltest-21.11 {test command with setup failure} -setup {
+ if {[info exists foo]} {
+ unset foo
+ }
+ set fail $::tcltest::currentFailure
+} -cleanup {set ::tcltest::currentFailure $fail} -body {
+ test tcltest-21.11.0 {foo-2} -setup {unset foo}
+} -result {^$} -output {Test setup failed:.*can't unset \"foo\": no such variable} -match regexp
+
+test tcltest-21.12 {
+ test command - setup occurs before cleanup & before script
+} -setup {
+ set fail $::tcltest::currentFailure
+ set v [verbose]
+} -cleanup {
+ verbose $v
+ set ::tcltest::currentFailure $fail
+} -body {
+ verbose {}
+ test tcltest-21.12.0 {foo-3} -setup {
+ if {[info exists foo]} {
+ unset foo
+ }
+ set foo 1
+ set expected 2
+ } -body {
+ incr foo
+ set foo
+ } -cleanup {
+ if {$foo != 2} {
+ puts [outputChannel] "foo is wrong"
+ } else {
+ puts [outputChannel] "foo is 2"
+ }
+ } -result {$expected}
+} -result {^$} -output {foo is 2} -match regexp
+
+# test all.tcl usage (runAllTests); simulate .test file failure, as well as
+# crashes to determine whether or not these errors are logged.
+
+set atd [makeDirectory alltestdir]
+makeFile {
+ package require tcltest
+ namespace import -force tcltest::*
+ testsDirectory [file join [temporaryDirectory] alltestdir]
+ runAllTests
+} all.tcl $atd
+makeFile {
+ exit 1
+} exit.test $atd
+makeFile {
+ error "throw an error"
+} error.test $atd
+makeFile {
+ package require tcltest
+ namespace import -force tcltest::*
+ test foo-1.1 {foo} {
+ -body { return 1 }
+ -result {1}
+ }
+ cleanupTests
+} test.test $atd
+
+# Must use a child process because stdout/stderr parsing can't be
+# duplicated in slave interp.
+test tcltest-22.1 {runAllTests} {
+ -constraints {unixOrPc}
+ -body {
+ exec [interpreter] \
+ [file join $atd all.tcl] \
+ -verbose t -tmpdir [temporaryDirectory]
+ }
+ -match regexp
+ -result "Test files exiting with errors:.*error.test.*exit.test"
+}
+removeDirectory alltestdir
+
+# makeFile, removeFile, makeDirectory, removeDirectory, viewFile
+test tcltest-23.1 {makeFile} {
+ -setup {
+ set mfdir [file join [temporaryDirectory] mfdir]
+ file mkdir $mfdir
+ }
+ -body {
+ makeFile {} t1.tmp
+ makeFile {} et1.tmp $mfdir
+ list [file exists [file join [temporaryDirectory] t1.tmp]] \
+ [file exists [file join $mfdir et1.tmp]]
+ }
+ -cleanup {
+ file delete -force $mfdir \
+ [file join [temporaryDirectory] t1.tmp]
+ }
+ -result {1 1}
+}
+test tcltest-23.2 {removeFile} {
+ -setup {
+ set mfdir [file join [temporaryDirectory] mfdir]
+ file mkdir $mfdir
+ makeFile {} t1.tmp
+ makeFile {} et1.tmp $mfdir
+ if {![file exists [file join [temporaryDirectory] t1.tmp]] || \
+ ![file exists [file join $mfdir et1.tmp]]} {
+ error "file creation didn't work"
+ }
+ }
+ -body {
+ removeFile t1.tmp
+ removeFile et1.tmp $mfdir
+ list [file exists [file join [temporaryDirectory] t1.tmp]] \
+ [file exists [file join $mfdir et1.tmp]]
+ }
+ -cleanup {
+ file delete -force $mfdir \
+ [file join [temporaryDirectory] t1.tmp]
+ }
+ -result {0 0}
+}
+test tcltest-23.3 {makeDirectory} {
+ -body {
+ set mfdir [file join [temporaryDirectory] mfdir]
+ file mkdir $mfdir
+ makeDirectory d1
+ makeDirectory d2 $mfdir
+ list [file exists [file join [temporaryDirectory] d1]] \
+ [file exists [file join $mfdir d2]]
+ }
+ -cleanup {
+ file delete -force [file join [temporaryDirectory] d1] $mfdir
+ }
+ -result {1 1}
+}
+test tcltest-23.4 {removeDirectory} {
+ -setup {
+ set mfdir [makeDirectory mfdir]
+ makeDirectory t1
+ makeDirectory t2 $mfdir
+ if {![file exists $mfdir] || \
+ ![file exists [file join [temporaryDirectory] $mfdir t2]]} {
+ error "setup failed - directory not created"
+ }
+ }
+ -body {
+ removeDirectory t1
+ removeDirectory t2 $mfdir
+ list [file exists [file join [temporaryDirectory] t1]] \
+ [file exists [file join $mfdir t2]]
+ }
+ -result {0 0}
+}
+test tcltest-23.5 {viewFile} {
+ -body {
+ set mfdir [file join [temporaryDirectory] mfdir]
+ file mkdir $mfdir
+ makeFile {foobar} t1.tmp
+ makeFile {foobarbaz} t2.tmp $mfdir
+ list [viewFile t1.tmp] [viewFile t2.tmp $mfdir]
+ }
+ -result {foobar foobarbaz}
+ -cleanup {
+ file delete -force $mfdir
+ removeFile t1.tmp
+ }
+}
+
+# customMatch
+proc matchNegative { expected actual } {
+ set match 0
+ foreach a $actual e $expected {
+ if { $a != $e } {
+ set match 1
+ break
+ }
+ }
+ return $match
+}
+
+test tcltest-24.0 {
+ customMatch: syntax
+} -body {
+ list [catch {customMatch} result] $result
+} -result [list 1 "wrong # args: should be \"customMatch mode script\""]
+
+test tcltest-24.1 {
+ customMatch: syntax
+} -body {
+ list [catch {customMatch foo} result] $result
+} -result [list 1 "wrong # args: should be \"customMatch mode script\""]
+
+test tcltest-24.2 {
+ customMatch: syntax
+} -body {
+ list [catch {customMatch foo bar baz} result] $result
+} -result [list 1 "wrong # args: should be \"customMatch mode script\""]
+
+test tcltest-24.3 {
+ customMatch: argument checking
+} -body {
+ list [catch {customMatch bad "a \{ b"} result] $result
+} -result [list 1 "invalid customMatch script; can't evaluate after completion"]
+
+test tcltest-24.4 {
+ test: valid -match values
+} -body {
+ list [catch {
+ test tcltest-24.4.0 {} \
+ -match [namespace current]::noSuchMode
+ } result] $result
+} -match glob -result {1 *bad -match value*}
+
+test tcltest-24.5 {
+ test: valid -match values
+} -setup {
+ customMatch [namespace current]::alwaysMatch "format 1 ;#"
+} -body {
+ list [catch {
+ test tcltest-24.5.0 {} \
+ -match [namespace current]::noSuchMode
+ } result] $result
+} -match glob -result {1 *bad -match value*: must be *alwaysMatch,*}
+
+test tcltest-24.6 {
+ customMatch: -match script that always matches
+} -setup {
+ customMatch [namespace current]::alwaysMatch "format 1 ;#"
+ set v [verbose]
+} -body {
+ verbose {}
+ test tcltest-24.6.0 {} -match [namespace current]::alwaysMatch \
+ -body {format 1} -result 0
+} -cleanup {
+ verbose $v
+} -result {} -output {} -errorOutput {}
+
+test tcltest-24.7 {
+ customMatch: replace default -exact matching
+} -setup {
+ set saveExactMatchScript $::tcltest::CustomMatch(exact)
+ customMatch exact "format 1 ;#"
+ set v [verbose]
+} -body {
+ verbose {}
+ test tcltest-24.7.0 {} -body {format 1} -result 0
+} -cleanup {
+ verbose $v
+ customMatch exact $saveExactMatchScript
+ unset saveExactMatchScript
+} -result {} -output {}
+
+test tcltest-24.9 {
+ customMatch: error during match
+} -setup {
+ proc errorDuringMatch args {return -code error "match returned error"}
+ customMatch [namespace current]::errorDuringMatch \
+ [namespace code errorDuringMatch]
+ set v [verbose]
+ set fail $::tcltest::currentFailure
+} -body {
+ verbose {}
+ test tcltest-24.9.0 {} -match [namespace current]::errorDuringMatch
+} -cleanup {
+ verbose $v
+ set ::tcltest::currentFailure $fail
+} -match glob -result {} -output {*FAILED*match returned error*}
+
+test tcltest-24.10 {
+ customMatch: bad return from match command
+} -setup {
+ proc nonBooleanReturn args {return foo}
+ customMatch nonBooleanReturn [namespace code nonBooleanReturn]
+ set v [verbose]
+ set fail $::tcltest::currentFailure
+} -body {
+ verbose {}
+ test tcltest-24.10.0 {} -match nonBooleanReturn
+} -cleanup {
+ verbose $v
+ set ::tcltest::currentFailure $fail
+} -match glob -result {} -output {*FAILED*expected boolean value*}
+
+test tcltest-24.11 {
+ test: -match exact
+} -body {
+ set result {A B C}
+} -match exact -result {A B C}
+
+test tcltest-24.12 {
+ test: -match exact match command eval in ::, not caller namespace
+} -setup {
+ set saveExactMatchScript $::tcltest::CustomMatch(exact)
+ customMatch exact [list string equal]
+ set v [verbose]
+ proc string args {error {called [string] in caller namespace}}
+} -body {
+ verbose {}
+ test tcltest-24.12.0 {} -body {format 1} -result 1
+} -cleanup {
+ rename string {}
+ verbose $v
+ customMatch exact $saveExactMatchScript
+ unset saveExactMatchScript
+} -match exact -result {} -output {}
+
+test tcltest-24.13 {
+ test: -match exact failure
+} -setup {
+ set saveExactMatchScript $::tcltest::CustomMatch(exact)
+ customMatch exact [list string equal]
+ set v [verbose]
+ set fail $::tcltest::currentFailure
+} -body {
+ verbose {}
+ test tcltest-24.13.0 {} -body {format 1} -result 0
+} -cleanup {
+ set ::tcltest::currentFailure $fail
+ verbose $v
+ customMatch exact $saveExactMatchScript
+ unset saveExactMatchScript
+} -match glob -result {} -output {*FAILED*Result was:
+1*(exact matching):
+0*}
+
+test tcltest-24.14 {
+ test: -match glob
+} -body {
+ set result {A B C}
+} -match glob -result {A B*}
+
+test tcltest-24.15 {
+ test: -match glob failure
+} -setup {
+ set v [verbose]
+ set fail $::tcltest::currentFailure
+} -body {
+ verbose {}
+ test tcltest-24.15.0 {} -match glob -body {format {A B C}} \
+ -result {A B* }
+} -cleanup {
+ set ::tcltest::currentFailure $fail
+ verbose $v
+} -match glob -result {} -output {*FAILED*Result was:
+*(glob matching):
+*}
+
+test tcltest-24.16 {
+ test: -match regexp
+} -body {
+ set result {A B C}
+} -match regexp -result {A B.*}
+
+test tcltest-24.17 {
+ test: -match regexp failure
+} -setup {
+ set fail $::tcltest::currentFailure
+ set v [verbose]
+} -body {
+ verbose {}
+ test tcltest-24.17.0 {} -match regexp -body {format {A B C}} \
+ -result {A B.* X}
+} -cleanup {
+ set ::tcltest::currentFailure $fail
+ verbose $v
+} -match glob -result {} -output {*FAILED*Result was:
+*(regexp matching):
+*}
+
+test tcltest-24.18 {
+ test: -match custom forget namespace qualification
+} -setup {
+ set fail $::tcltest::currentFailure
+ set v [verbose]
+ customMatch negative matchNegative
+} -body {
+ verbose {}
+ test tcltest-24.18.0 {} -match negative -body {format {A B C}} \
+ -result {A B X}
+} -cleanup {
+ set ::tcltest::currentFailure $fail
+ verbose $v
+} -match glob -result {} -output {*FAILED*Error testing result:*}
+
+test tcltest-24.19 {
+ test: -match custom
+} -setup {
+ set v [verbose]
+ customMatch negative [namespace code matchNegative]
+} -body {
+ verbose {}
+ test tcltest-24.19.0 {} -match negative -body {format {A B C}} \
+ -result {A B X}
+} -cleanup {
+ verbose $v
+} -match exact -result {} -output {}
+
+test tcltest-24.20 {
+ test: -match custom failure
+} -setup {
+ set fail $::tcltest::currentFailure
+ set v [verbose]
+ customMatch negative [namespace code matchNegative]
+} -body {
+ verbose {}
+ test tcltest-24.20.0 {} -match negative -body {format {A B C}} \
+ -result {A B C}
+} -cleanup {
+ set ::tcltest::currentFailure $fail
+ verbose $v
+} -match glob -result {} -output {*FAILED*Result was:
+*(negative matching):
+*}
+
+test tcltest-25.1 {
+ constraint of setup/cleanup (Bug 589859)
+} -setup {
+ set foo 0
+} -body {
+ # Buggy tcltest will generate result of 2
+ test tcltest-25.1.0 {} -constraints knownBug -setup {
+ incr foo
+ } -body {
+ incr foo
+ } -cleanup {
+ incr foo
+ } -match glob -result *
+ set foo
+} -cleanup {
+ unset foo
+} -result 0
+
+test tcltest-25.2 {
+ puts -nonewline (Bug 612786)
+} -body {
+ puts -nonewline stdout bla
+ puts -nonewline stdout bla
+} -output {blabla}
+
+test tcltest-25.3 {
+ reported return code (Bug 611922)
+} -setup {
+ set fail $::tcltest::currentFailure
+ set v [verbose]
+} -body {
+ verbose {}
+ test tcltest-25.3.0 {} -body {
+ error foo
+ }
+} -cleanup {
+ set ::tcltest::currentFailure $fail
+ verbose $v
+} -match glob -output {*generated error; Return code was: 1*}
+
+test tcltest-26.1 {Bug/RFE 1017151} -setup {
+ makeFile {
+ package require tcltest
+ set ::errorInfo "Should never see this"
+ tcltest::test tcltest-26.1.0 {
+ no errorInfo when only return code mismatch
+ } -body {
+ set x 1
+ } -returnCodes error -result 1
+ tcltest::cleanupTests
+ } test.tcl
+} -body {
+ slave msg [file join [temporaryDirectory] test.tcl]
+ return $msg
+} -cleanup {
+ removeFile test.tcl
+} -match glob -result {*
+---- Return code should have been one of: 1
+==== tcltest-26.1.0 FAILED*}
+
+test tcltest-26.2 {Bug/RFE 1017151} -setup {
+ makeFile {
+ package require tcltest
+ set ::errorInfo "Should never see this"
+ tcltest::test tcltest-26.2.0 {do not mask body errorInfo} -body {
+ error "body error"
+ } -cleanup {
+ error "cleanup error"
+ } -result 1
+ tcltest::cleanupTests
+ } test.tcl
+} -body {
+ slave msg [file join [temporaryDirectory] test.tcl]
+ return $msg
+} -cleanup {
+ removeFile test.tcl
+} -match glob -result {*
+---- errorInfo: body error
+*
+---- errorInfo(cleanup): cleanup error*}
+
+cleanupTests
+}
+
+namespace delete ::tcltest::test
+return
diff --git a/pkgs/msgcat/tests/thread.test b/pkgs/msgcat/tests/thread.test
new file mode 100644
index 0000000..44789fa
--- /dev/null
+++ b/pkgs/msgcat/tests/thread.test
@@ -0,0 +1,1436 @@
+# Commands covered: (test)thread
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2006-2008 by Joe Mistachkin. All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2.2
+ namespace import -force ::tcltest::*
+}
+
+# Some tests require the testthread command
+
+testConstraint testthread [expr {[info commands testthread] != {}}]
+
+# Some tests require the Thread package
+
+testConstraint thread [expr {0 == [catch {package require Thread 2.7}]}]
+
+# Some tests may not work under valgrind
+
+testConstraint notValgrind [expr {![testConstraint valgrind]}]
+
+set threadSuperKillScript {
+ rename catch ""
+ rename while ""
+ rename unknown ""
+ rename update ""
+ thread::release
+}
+
+proc getThreadErrorFromInfo { info } {
+ set list [split $info \n]
+ set idx [lsearch -glob $list "*eval*unwound*"]
+ if {$idx != -1} then {
+ return [lindex $list $idx]
+ }
+ set idx [lsearch -glob $list "*eval*canceled*"]
+ if {$idx != -1} then {
+ return [lindex $list $idx]
+ }
+ return ""; # some other error we do not care about.
+}
+
+proc findThreadError { info } {
+ foreach error [lreverse $info] {
+ set error [getThreadErrorFromInfo $error]
+ if {[string length $error] > 0} then {
+ return $error
+ }
+ }
+ return ""; # some other error we do not care about.
+}
+
+proc ThreadError {id info} {
+ global threadSawError
+ if {[string length [getThreadErrorFromInfo $info]] > 0} then {
+ global threadId threadError
+ set threadId $id
+ lappend threadError($id) $info
+ }
+ set threadSawError($id) true; # signal main thread to exit [vwait].
+}
+
+if {[testConstraint thread]} {
+ thread::errorproc ThreadError
+}
+
+if {[testConstraint testthread]} {
+ proc drainEventQueue {} {
+ while {[set x [testthread event]]} {
+ puts "WARNING: drained $x event(s) on main thread"
+ }
+ }
+
+ testthread errorproc ThreadError
+
+ set mainThread [testthread id]
+
+ proc ThreadNullError {id info} {
+ # ignore
+ }
+
+ proc threadReap {} {
+ testthread errorproc ThreadNullError
+ while {[llength [testthread names]] > 1} {
+ foreach tid [testthread names] {
+ if {$tid != [testthread id]} {
+ catch {
+ testthread send -async $tid {testthread exit}
+ }
+ }
+ }
+ after 1
+ }
+ testthread errorproc ThreadError
+ return [llength [testthread names]]
+ }
+}
+
+# Some tests require manual draining of the event queue
+
+testConstraint drainEventQueue [expr {[info commands drainEventQueue] != {}}]
+
+test thread-1.3 {Tcl_ThreadObjCmd: initial thread list} {thread} {
+ llength [thread::names]
+} 1
+test thread-1.4 {Tcl_ThreadObjCmd: thread create } {thread} {
+ set serverthread [thread::create -preserved]
+ set numthreads [llength [thread::names]]
+ thread::release $serverthread
+ set numthreads
+} {2}
+test thread-1.5 {Tcl_ThreadObjCmd: thread create one shot} {thread} {
+ thread::create {set x 5}
+ foreach try {0 1 2 4 5 6} {
+ # Try various ways to yield
+ update
+ after 10
+ set l [llength [thread::names]]
+ if {$l == 1} {
+ break
+ }
+ }
+ set l
+} {1}
+test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {thread} {
+ thread::create {{*}{}}
+ update
+ after 10
+ llength [thread::names]
+} {1}
+test thread-1.13 {Tcl_ThreadObjCmd: send args} {thread} {
+ set serverthread [thread::create -preserved]
+ set five [thread::send $serverthread {set x 5}]
+ thread::release $serverthread
+ set five
+} 5
+test thread-1.15 {Tcl_ThreadObjCmd: wait} {thread} {
+ set serverthread [thread::create -preserved {set z 5 ; thread::wait}]
+ set five [thread::send $serverthread {set z}]
+ thread::release $serverthread
+ set five
+} 5
+
+# The tests above also cover:
+# TclCreateThread, except when pthread_create fails
+# NewThread, safe and regular
+# ThreadErrorProc, except for printing to standard error
+
+test thread-2.1 {ListUpdateInner and ListRemove} {thread} {
+ catch {unset tid}
+ foreach t {0 1 2} {
+ upvar #0 t$t tid
+ set tid [thread::create -preserved]
+ }
+ foreach t {0 1 2} {
+ upvar #0 t$t tid
+ thread::release $tid
+ }
+ llength [thread::names]
+} 1
+
+test thread-3.1 {TclThreadList} {thread} {
+ catch {unset tid}
+ set len [llength [thread::names]]
+ set l1 {}
+ foreach t {0 1 2} {
+ lappend l1 [thread::create -preserved]
+ }
+ set l2 [thread::names]
+ set c [string compare [lsort [concat [thread::id] $l1]] [lsort $l2]]
+ foreach t $l1 {
+ thread::release $t
+ }
+ list $len $c
+} {1 0}
+
+test thread-4.1 {TclThreadSend to self} {thread} {
+ catch {unset x}
+ thread::send [thread::id] {
+ set x 4
+ }
+ set x
+} {4}
+test thread-4.2 {TclThreadSend -async} {thread} {
+ set len [llength [thread::names]]
+ set serverthread [thread::create -preserved]
+ thread::send -async $serverthread {
+ after 1 {thread::release}
+ }
+ set two [llength [thread::names]]
+ after 100 {set done 1}
+ vwait done
+ list $len [llength [thread::names]] $two
+} {1 1 2}
+test thread-4.3 {TclThreadSend preserve errorInfo} {thread} {
+ set len [llength [thread::names]]
+ set serverthread [thread::create -preserved]
+ set x [catch {thread::send $serverthread {set undef}} msg]
+ set savedErrorInfo $::errorInfo
+ thread::release $serverthread
+ list $len $x $msg $savedErrorInfo
+} {1 1 {can't read "undef": no such variable} {can't read "undef": no such variable
+ while executing
+"set undef"
+ invoked from within
+"thread::send $serverthread {set undef}"}}
+test thread-4.4 {TclThreadSend preserve code} {thread} {
+ set len [llength [thread::names]]
+ set serverthread [thread::create -preserved]
+ set ::errorInfo {}
+ set x [catch {thread::send $serverthread {set ::errorInfo {}; break}} msg]
+ set savedErrorInfo $::errorInfo
+ thread::release $serverthread
+ list $len $x $msg $savedErrorInfo
+} {1 3 {} {}}
+test thread-4.5 {TclThreadSend preserve errorCode} {thread} {
+ set serverthread [thread::create]
+ set x [catch {thread::send $serverthread {error ERR INFO CODE}} msg]
+ set savedErrorCode $::errorCode
+ thread::release $serverthread
+ list $x $msg $savedErrorCode
+} {1 ERR CODE}
+
+
+test thread-5.0 {Joining threads} {thread} {
+ set serverthread [thread::create -joinable -preserved]
+ thread::send -async $serverthread {after 1000 ; thread::release}
+ thread::join $serverthread
+} {0}
+test thread-5.1 {Joining threads after the fact} {thread} {
+ set serverthread [thread::create -joinable -preserved]
+ thread::send -async $serverthread {thread::release}
+ after 2000
+ thread::join $serverthread
+} {0}
+test thread-5.2 {Try to join a detached thread} {thread} {
+ set serverthread [thread::create -preserved]
+ thread::send -async $serverthread {after 1000 ; thread::release}
+ catch {set res [thread::join $serverthread]} msg
+ while {[llength [thread::names]] > 1} {
+ after 20
+ }
+ lrange $msg 0 2
+} {cannot join thread}
+
+test thread-6.1 {freeing very large object trees in a thread} thread {
+ # conceptual duplicate of obj-32.1
+ set serverthread [thread::create -preserved]
+ thread::send -async $serverthread {
+ set x {}
+ for {set i 0} {$i<100000} {incr i} {
+ set x [list $x {}]
+ }
+ unset x
+ }
+ thread::release -wait $serverthread
+} 0
+
+# TIP #285: Script cancellation support
+test thread-7.4 {cancel: pure bytecode loop} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ while {1} {
+ # No bytecode at all here...
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.5 {cancel: pure inside-command loop} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ set while while
+ $while {1} {
+ # No bytecode at all here...
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.6 {cancel: pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ while {1} {
+ # No bytecode at all here...
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.7 {cancel: pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ set while while
+ $while {1} {
+ # No bytecode at all here...
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.8 {cancel: pure bytecode loop custom result} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ while {1} {
+ # No bytecode at all here...
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread "the eval was canceled"]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {the eval was canceled}}
+test thread-7.9 {cancel: pure inside-command loop custom result} -constraints {
+ thread
+ drainEventQueue
+} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ set while while
+ $while {1} {
+ # No bytecode at all here...
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread "the eval was canceled"]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {the eval was canceled}}
+test thread-7.10 {cancel: pure bytecode loop custom result -unwind} -constraints {
+ thread
+ drainEventQueue
+} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ while {1} {
+ # No bytecode at all here...
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread "the eval was unwound"]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {the eval was unwound}}
+test thread-7.11 {cancel: pure inside-command loop custom result -unwind} -constraints {
+ thread
+ drainEventQueue
+} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ set while while
+ $while {1} {
+ # No bytecode at all here...
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread "the eval was unwound"]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {the eval was unwound}}
+test thread-7.12 {cancel: after} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ after 30000
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.13 {cancel: after -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ after 30000
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.14 {cancel: vwait} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID [thread::id]] {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ vwait forever
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.15 {cancel: vwait -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ vwait forever
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.16 {cancel: expr} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ expr {[while {1} {incr x}]}
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.17 {cancel: expr -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ expr {[while {1} {incr x}]}
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.18 {cancel: expr bignum} {thread drainEventQueue knownBug} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ #
+ # BUGBUG: This will not cancel because libtommath
+ # does not check Tcl_Canceled.
+ #
+ expr {2**99999}
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted; after 1000
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread); # WARNING: Never returns (see above).
+ thread::join $serverthread; drainEventQueue; # WARNING: Never returns (see above).
+ list $res [expr {[info exists ::threadIdStarted] ? \
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 0 {}}
+test thread-7.19 {cancel: expr bignum -unwind} {thread drainEventQueue knownBug} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ #
+ # BUGBUG: This will not cancel because libtommath
+ # does not check Tcl_Canceled.
+ #
+ expr {2**99999}
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted; after 1000
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread); # WARNING: Never returns (see above).
+ thread::join $serverthread; drainEventQueue; # WARNING: Never returns (see above).
+ list $res [expr {[info exists ::threadIdStarted] ? \
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 0 {}}
+test thread-7.20 {cancel: subst} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ subst {[while {1} {incr x}]}
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.21 {cancel: subst -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ subst {[while {1} {incr x}]}
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.22 {cancel: slave interp} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ while {1} {}
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.23 {cancel: slave interp -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ set while while; $while {1} {}
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.24 {cancel: nested catch inside pure bytecode loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ catch {
+ while {1} {
+ catch {
+ while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted; after 1000
+ set res [thread::cancel $serverthread]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {[info exists ::threadIdStarted] ? \
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 0 {}}
+test thread-7.25 {cancel: nested catch inside pure inside-command loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ set catch catch
+ set while while
+ $while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ $catch {
+ $while {1} {
+ $catch {
+ $while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted; after 1000
+ set res [thread::cancel $serverthread]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {[info exists ::threadIdStarted] ? \
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 0 {}}
+test thread-7.26 {cancel: send async cancel bad interp path} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ update
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ catch {thread::send $serverthread {interp cancel -- bad}} msg
+ thread::send -async $serverthread {interp cancel -unwind}
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list [expr {$::threadIdStarted == $serverthread}] $msg
+} {1 {could not find interpreter "bad"}}
+test thread-7.27 {cancel: send async cancel -- switch} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ set i [interp create -- -unwind]
+ $i eval "package require -exact Thread [package present Thread]"
+ $i eval {
+ proc foobar {} {
+ while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ update
+ }
+ }
+ foobar
+ }
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::send -async $serverthread {interp cancel -- -unwind}]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.28 {cancel: send async cancel nested catch inside pure bytecode loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ catch {
+ while {1} {
+ catch {
+ while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted; after 1000
+ set res [thread::send -async $serverthread {interp cancel}]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {[info exists ::threadIdStarted] ? \
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 1 {eval canceled}}
+test thread-7.29 {cancel: send async cancel nested catch pure inside-command loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ set catch catch
+ set while while
+ $while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ $catch {
+ $while {1} {
+ $catch {
+ $while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted; after 1000
+ set res [thread::send -async $serverthread {interp cancel}]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {[info exists ::threadIdStarted] ? \
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 1 {eval canceled}}
+test thread-7.30 {cancel: send async thread cancel nested catch inside pure bytecode loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ catch {
+ while {1} {
+ catch {
+ while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted; after 1000
+ set res [thread::send -async $serverthread {thread::cancel [thread::id]}]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {[info exists ::threadIdStarted] ? \
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 1 {eval canceled}}
+test thread-7.31 {cancel: send async thread cancel nested catch pure inside-command loop} {thread drainEventQueue} {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ set catch catch
+ set while while
+ $while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ $catch {
+ $while {1} {
+ $catch {
+ $while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted; after 1000
+ set res [thread::send -async $serverthread {thread::cancel [thread::id]}]
+ thread::send $serverthread $::threadSuperKillScript
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {[info exists ::threadIdStarted] ? \
+ $::threadIdStarted == $serverthread : 0}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 1 {eval canceled}}
+test thread-7.32 {cancel: nested catch inside pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ catch {
+ while {1} {
+ catch {
+ while {1} {
+ # No bytecode at all here...
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.33 {cancel: nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ set catch catch
+ set while while
+ $while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ $catch {
+ $while {1} {
+ $catch {
+ $while {1} {
+ # No bytecode at all here...
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::cancel -unwind $serverthread]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.34 {cancel: send async cancel nested catch inside pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ catch {
+ while {1} {
+ catch {
+ while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::send -async $serverthread {interp cancel -unwind}]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.35 {cancel: send async cancel nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ set catch catch
+ set while while
+ $while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ $catch {
+ $while {1} {
+ $catch {
+ $while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::send -async $serverthread {interp cancel -unwind}]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.36 {cancel: send async thread cancel nested catch inside pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID% [thread::id]] {
+ proc foobar {} {
+ while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ catch {
+ while {1} {
+ catch {
+ while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::send -async $serverthread {thread::cancel -unwind [thread::id]}]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.37 {cancel: send async thread cancel nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+ set serverthread [thread::create -joinable \
+ [string map [list %ID [thread::id]] {
+ proc foobar {} {
+ set catch catch
+ set while while
+ $while {1} {
+ if {![info exists foo]} then {
+ # signal the primary thread that we are ready
+ # to be canceled now (we are running).
+ thread::send %ID% [list set ::threadIdStarted [thread::id]]
+ set foo 1
+ }
+ $catch {
+ $while {1} {
+ $catch {
+ $while {1} {
+ # we must call update here because otherwise
+ # the thread cannot even be forced to exit.
+ update
+ }
+ }
+ }
+ }
+ }
+ }
+ foobar
+ }]]
+ # wait for other thread to signal "ready to cancel"
+ vwait ::threadIdStarted
+ set res [thread::send -async $serverthread {thread::cancel -unwind [thread::id]}]
+ vwait ::threadSawError($serverthread)
+ thread::join $serverthread; drainEventQueue
+ list $res [expr {$::threadIdStarted == $serverthread}] \
+ [expr {[info exists ::threadId] ? \
+ $::threadId == $serverthread : 0}] \
+ [expr {[info exists ::threadError($serverthread)] ? \
+ [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+ unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/timer.test b/pkgs/msgcat/tests/timer.test
new file mode 100644
index 0000000..ab6efc9
--- /dev/null
+++ b/pkgs/msgcat/tests/timer.test
@@ -0,0 +1,605 @@
+# This file contains a collection of tests for the procedures in the
+# file tclTimer.c, which includes the "after" Tcl command. Sourcing
+# this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+test timer-1.1 {Tcl_CreateTimerHandler procedure} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x ""
+ foreach i {100 200 1000 50 150} {
+ after $i lappend x $i
+ }
+ after 200 set done 1
+ vwait done
+ return $x
+} -cleanup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {50 100 150 200}
+
+test timer-2.1 {Tcl_DeleteTimerHandler procedure} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x ""
+ foreach i {100 200 1000 50 150} {
+ after $i lappend x $i
+ }
+ after cancel lappend x 150
+ after cancel lappend x 50
+ after 200 set done 1
+ vwait done
+ return $x
+} -result {100 200}
+
+# No tests for Tcl_ServiceTimer or ResetTimer, since it is already tested
+# above.
+
+test timer-3.1 {TimerHandlerEventProc procedure: event masks} {
+ set x start
+ after 100 { set x fired }
+ update idletasks
+ set result $x
+ after 200
+ update
+ lappend result $x
+} {start fired}
+test timer-3.2 {TimerHandlerEventProc procedure: multiple timers} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ foreach i {200 600 1000} {
+ after $i lappend x $i
+ }
+ after 200
+ set result ""
+ set x ""
+ update
+ lappend result $x
+ after 400
+ update
+ lappend result $x
+ after 400
+ update
+ lappend result $x
+} -result {200 {200 600} {200 600 1000}}
+test timer-3.3 {TimerHandlerEventProc procedure: reentrant timer deletion} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x {}
+ after 100 lappend x 100
+ set i [after 300 lappend x 300]
+ after 200 after cancel $i
+ after 400
+ update
+ return $x
+} -result 100
+test timer-3.4 {TimerHandlerEventProc procedure: all expired timers fire} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x {}
+ after 100 lappend x a
+ after 200 lappend x b
+ after 300 lappend x c
+ after 300
+ vwait x
+ return $x
+} -result {a b c}
+test timer-3.5 {TimerHandlerEventProc procedure: reentrantly added timers don't fire} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x {}
+ after 100 {lappend x a; after 0 lappend x b}
+ after 100
+ vwait x
+ return $x
+} -result a
+test timer-3.6 {TimerHandlerEventProc procedure: reentrantly added timers don't fire} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x {}
+ after 100 {lappend x a; after 100 lappend x b; after 100}
+ after 100
+ vwait x
+ set result $x
+ vwait x
+ lappend result $x
+} -result {a {a b}}
+
+# No tests for Tcl_DoWhenIdle: it's already tested by other tests
+# below.
+
+test timer-4.1 {Tcl_CancelIdleCall procedure} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x before
+ set y before
+ set z before
+ after idle set x after1
+ after idle set y after2
+ after idle set z after3
+ after cancel set y after2
+ update idletasks
+ list $x $y $z
+} -result {after1 before after3}
+test timer-4.2 {Tcl_CancelIdleCall procedure} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x before
+ set y before
+ set z before
+ after idle set x after1
+ after idle set y after2
+ after idle set z after3
+ after cancel set x after1
+ update idletasks
+ list $x $y $z
+} -result {before after2 after3}
+
+test timer-5.1 {Tcl_ServiceIdle, self-rescheduling handlers} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x 1
+ set y 23
+ after idle {incr x; after idle {incr x; after idle {incr x}}}
+ after idle {incr y}
+ vwait x
+ set result "$x $y"
+ update idletasks
+ lappend result $x
+} -result {2 24 4}
+
+test timer-6.1 {Tcl_AfterCmd procedure, basics} -returnCodes error -body {
+ after
+} -result {wrong # args: should be "after option ?arg ...?"}
+test timer-6.2 {Tcl_AfterCmd procedure, basics} -returnCodes error -body {
+ after 2x
+} -result {bad argument "2x": must be cancel, idle, info, or an integer}
+test timer-6.3 {Tcl_AfterCmd procedure, basics} -returnCodes error -body {
+ after gorp
+} -result {bad argument "gorp": must be cancel, idle, info, or an integer}
+test timer-6.4 {Tcl_AfterCmd procedure, ms argument} {
+ set x before
+ after 400 {set x after}
+ after 200
+ update
+ set y $x
+ after 400
+ update
+ list $y $x
+} {before after}
+test timer-6.5 {Tcl_AfterCmd procedure, ms argument} {
+ set x before
+ after 300 set x after
+ after 200
+ update
+ set y $x
+ after 200
+ update
+ list $y $x
+} {before after}
+test timer-6.6 {Tcl_AfterCmd procedure, cancel option} -body {
+ after cancel
+} -returnCodes error -result {wrong # args: should be "after cancel id|command"}
+test timer-6.7 {Tcl_AfterCmd procedure, cancel option} {
+ after cancel after#1
+} {}
+test timer-6.8 {Tcl_AfterCmd procedure, cancel option} {
+ after cancel {foo bar}
+} {}
+test timer-6.9 {Tcl_AfterCmd procedure, cancel option} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x before
+ set y [after 100 set x after]
+ after cancel $y
+ after 200
+ update
+ return $x
+} -result {before}
+test timer-6.10 {Tcl_AfterCmd procedure, cancel option} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x before
+ after 100 set x after
+ after cancel {set x after}
+ after 200
+ update
+ return $x
+} -result {before}
+test timer-6.11 {Tcl_AfterCmd procedure, cancel option} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x before
+ after 100 set x after
+ set id [after 300 set x after]
+ after cancel $id
+ after 200
+ update
+ set y $x
+ set x cleared
+ after 200
+ update
+ list $y $x
+} -result {after cleared}
+test timer-6.12 {Tcl_AfterCmd procedure, cancel option} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x first
+ after idle lappend x second
+ after idle lappend x third
+ set i [after idle lappend x fourth]
+ after cancel {lappend x second}
+ after cancel $i
+ update idletasks
+ return $x
+} -result {first third}
+test timer-6.13 {Tcl_AfterCmd procedure, cancel option, multiple arguments for command} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x first
+ after idle lappend x second
+ after idle lappend x third
+ set i [after idle lappend x fourth]
+ after cancel lappend x second
+ after cancel $i
+ update idletasks
+ return $x
+} -result {first third}
+test timer-6.14 {Tcl_AfterCmd procedure, cancel option, cancel during handler, used to dump core} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set id [
+ after 100 {
+ set x done
+ after cancel $id
+ }
+ ]
+ vwait x
+} -result {}
+test timer-6.15 {Tcl_AfterCmd procedure, cancel option, multiple interps} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ interp create x
+ x eval {set a before; set b before; after idle {set a a-after};
+ after idle {set b b-after}}
+ set result [llength [x eval after info]]
+ lappend result [llength [after info]]
+ after cancel {set b b-after}
+ set a aaa
+ set b bbb
+ x eval {after cancel set a a-after}
+ update idletasks
+ lappend result $a $b [x eval {list $a $b}]
+} -cleanup {
+ interp delete x
+} -result {2 0 aaa bbb {before b-after}}
+test timer-6.16 {Tcl_AfterCmd procedure, idle option} -body {
+ after idle
+} -returnCodes error -result {wrong # args: should be "after idle script ?script ...?"}
+test timer-6.17 {Tcl_AfterCmd procedure, idle option} {
+ set x before
+ after idle {set x after}
+ set y $x
+ update idletasks
+ list $y $x
+} {before after}
+test timer-6.18 {Tcl_AfterCmd procedure, idle option} {
+ set x before
+ after idle set x after
+ set y $x
+ update idletasks
+ list $y $x
+} {before after}
+
+set event1 [after idle event 1]
+set event2 [after 1000 event 2]
+interp create x
+set childEvent [x eval {after idle event in child}]
+test timer-6.19 {Tcl_AfterCmd, info option} {
+ lsort [after info]
+} [lsort "$event1 $event2"]
+test timer-6.20 {Tcl_AfterCmd, info option} -returnCodes error -body {
+ after info a b
+} -result {wrong # args: should be "after info ?id?"}
+test timer-6.21 {Tcl_AfterCmd, info option} -returnCodes error -body {
+ after info $childEvent
+} -result "event \"$childEvent\" doesn't exist"
+test timer-6.22 {Tcl_AfterCmd, info option} {
+ list [after info $event1] [after info $event2]
+} {{{event 1} idle} {{event 2} timer}}
+after cancel $event1
+after cancel $event2
+interp delete x
+
+test timer-6.23 {Tcl_AfterCmd procedure, no option, script with NUL} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x "hello world"
+ after 1 "set x ab\0cd"
+ after 10
+ update
+ string length $x
+} -result {5}
+test timer-6.24 {Tcl_AfterCmd procedure, no option, script with NUL} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x "hello world"
+ after 1 set x ab\0cd
+ after 10
+ update
+ string length $x
+} -result {5}
+test timer-6.25 {Tcl_AfterCmd procedure, cancel option, script with NUL} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x "hello world"
+ after 1 set x ab\0cd
+ after cancel "set x ab\0ef"
+ llength [after info]
+} -cleanup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {1}
+test timer-6.26 {Tcl_AfterCmd procedure, cancel option, script with NUL} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x "hello world"
+ after 1 set x ab\0cd
+ after cancel set x ab\0ef
+ llength [after info]
+} -cleanup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result {1}
+test timer-6.27 {Tcl_AfterCmd procedure, idle option, script with NUL} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x "hello world"
+ after idle "set x ab\0cd"
+ update
+ string length $x
+} -result {5}
+test timer-6.28 {Tcl_AfterCmd procedure, idle option, script with NUL} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x "hello world"
+ after idle set x ab\0cd
+ update
+ string length $x
+} -result {5}
+test timer-6.29 {Tcl_AfterCmd procedure, info option, script with NUL} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ set x "hello world"
+ set id junk
+ set id [after 10 set x ab\0cd]
+ update
+ string length [lindex [lindex [after info $id] 0] 2]
+} -cleanup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -result 5
+
+set event [after idle foo bar]
+scan $event after#%d lastId
+test timer-7.1 {GetAfterEvent procedure} -returnCodes error -body {
+ after info xfter#$lastId
+} -result "event \"xfter#$lastId\" doesn't exist"
+test timer-7.2 {GetAfterEvent procedure} -returnCodes error -body {
+ after info afterx$lastId
+} -result "event \"afterx$lastId\" doesn't exist"
+test timer-7.3 {GetAfterEvent procedure} -returnCodes error -body {
+ after info after#ab
+} -result {event "after#ab" doesn't exist}
+test timer-7.4 {GetAfterEvent procedure} -returnCodes error -body {
+ after info after#
+} -result {event "after#" doesn't exist}
+test timer-7.5 {GetAfterEvent procedure} -returnCodes error -body {
+ after info after#${lastId}x
+} -result "event \"after#${lastId}x\" doesn't exist"
+test timer-7.6 {GetAfterEvent procedure} -returnCodes error -body {
+ after info afterx[expr {$lastId+1}]
+} -result "event \"afterx[expr {$lastId+1}]\" doesn't exist"
+after cancel $event
+
+test timer-8.1 {AfterProc procedure} {
+ set x before
+ proc foo {} {
+ set x untouched
+ after 100 {set x after}
+ after 200
+ update
+ return $x
+ }
+ list [foo] $x
+} {untouched after}
+test timer-8.2 {AfterProc procedure} -setup {
+ variable x empty
+ proc myHandler {msg options} {
+ variable x [list $msg [dict get $options -errorinfo]]
+ }
+ set handler [interp bgerror {}]
+ interp bgerror {} [namespace which myHandler]
+} -body {
+ after 100 {error "After error"}
+ after 200
+ set y $x
+ update
+ list $y $x
+} -cleanup {
+ interp bgerror {} $handler
+} -result {empty {{After error} {After error
+ while executing
+"error "After error""
+ ("after" script)}}}
+test timer-8.3 {AfterProc procedure, deleting handler from itself} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ proc foo {} {
+ global x
+ set x {}
+ foreach i [after info] {
+ lappend x [after info $i]
+ }
+ after cancel foo
+ }
+ after idle foo
+ after 1000 {error "I shouldn't ever have executed"}
+ update idletasks
+ return $x
+} -result {{{error "I shouldn't ever have executed"} timer}}
+test timer-8.4 {AfterProc procedure, deleting handler from itself} -setup {
+ foreach i [after info] {
+ after cancel $i
+ }
+} -body {
+ proc foo {} {
+ global x
+ set x {}
+ foreach i [after info] {
+ lappend x [after info $i]
+ }
+ after cancel foo
+ }
+ after 1000 {error "I shouldn't ever have executed"}
+ after idle foo
+ update idletasks
+ return $x
+} -result {{{error "I shouldn't ever have executed"} timer}}
+
+foreach i [after info] {
+ after cancel $i
+}
+
+# No test for FreeAfterPtr, since it is already tested above.
+
+test timer-9.1 {AfterCleanupProc procedure} -setup {
+ catch {interp delete x}
+} -body {
+ interp create x
+ x eval {after 200 {
+ lappend x after
+ puts "part 1: this message should not appear"
+ }}
+ after 200 {lappend x after2}
+ x eval {after 200 {
+ lappend x after3
+ puts "part 2: this message should not appear"
+ }}
+ after 200 {lappend x after4}
+ x eval {after 200 {
+ lappend x after5
+ puts "part 3: this message should not appear"
+ }}
+ interp delete x
+ set x before
+ after 300
+ update
+ return $x
+} -result {before after2 after4}
+
+test timer-10.1 {Bug 1016167: [after] overwrites imports} -setup {
+ interp create slave
+ slave eval namespace export after
+ slave eval namespace eval foo namespace import ::after
+} -body {
+ slave eval foo::after 1
+ slave eval namespace origin foo::after
+} -cleanup {
+ # Bug will cause crash here; would cause failure otherwise
+ interp delete slave
+} -result ::after
+
+test timer-11.1 {Bug 1350291: [after] overflowing 32-bit field} -body {
+ set b ok
+ set a [after 0x100000001 {set b "after fired early"}]
+ after 100 set done 1
+ vwait done
+ return $b
+} -cleanup {
+ catch {after cancel $a}
+} -result ok
+test timer-11.2 {Bug 1350293: [after] negative argument} -body {
+ set l {}
+ after 100 {lappend l 100; set done 1}
+ after -1 {lappend l -1}
+ vwait done
+ return $l
+} -result {-1 100}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/tm.test b/pkgs/msgcat/tests/tm.test
new file mode 100644
index 0000000..149a65d
--- /dev/null
+++ b/pkgs/msgcat/tests/tm.test
@@ -0,0 +1,245 @@
+# This file contains tests for the ::tcl::tm::* commands.
+#
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 2004 by Donal K. Fellows.
+# All rights reserved.
+
+package require Tcl 8.5
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+test tm-1.1 {tm: path command exists} {
+ catch { ::tcl::tm::path }
+ info commands ::tcl::tm::path
+} ::tcl::tm::path
+test tm-1.2 {tm: path command syntax} -returnCodes error -body {
+ ::tcl::tm::path foo
+} -result {unknown or ambiguous subcommand "foo": must be add, list, or remove}
+test tm-1.3 {tm: path command syntax} {
+ ::tcl::tm::path add
+} {}
+test tm-1.4 {tm: path command syntax} {
+ ::tcl::tm::path remove
+} {}
+test tm-1.5 {tm: path command syntax} -returnCodes error -body {
+ ::tcl::tm::path list foobar
+} -result "wrong # args: should be \"::tcl::tm::path list\""
+
+test tm-2.1 {tm: roots command exists} {
+ catch { ::tcl::tm::roots }
+ info commands ::tcl::tm::roots
+} ::tcl::tm::roots
+test tm-2.2 {tm: roots command syntax} -returnCodes error -body {
+ ::tcl::tm::roots
+} -result "wrong # args: should be \"::tcl::tm::roots paths\""
+test tm-2.3 {tm: roots command syntax} -returnCodes error -body {
+ ::tcl::tm::roots foo bar
+} -result "wrong # args: should be \"::tcl::tm::roots paths\""
+
+
+test tm-3.1 {tm: module path management, input validation} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -returnCodes error -body {
+ ::tcl::tm::path add foo/bar
+ ::tcl::tm::path add foo
+} -result {foo is ancestor of existing module path foo/bar.}
+
+test tm-3.2 {tm: module path management, input validation} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -returnCodes error -body {
+ ::tcl::tm::path add foo
+ ::tcl::tm::path add foo/bar
+} -result {foo/bar is subdirectory of existing module path foo.}
+
+test tm-3.3 {tm: module path management, add/list interaction} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ ::tcl::tm::path add foo
+ ::tcl::tm::path add bar
+ ::tcl::tm::path list
+} -result {bar foo}
+
+test tm-3.4 {tm: module path management, add/list interaction} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ ::tcl::tm::path add foo bar baz
+ ::tcl::tm::path list
+} -result {baz bar foo}
+
+test tm-3.5 {tm: module path management, input validation/list interaction} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ catch {::tcl::tm::path add snarf foo geode foo/bar}
+ # Nothing is added if a problem was found.
+ ::tcl::tm::path list
+} -result {}
+
+test tm-3.6 {tm: module path management, input validation/list interaction} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ catch {::tcl::tm::path add snarf foo/bar geode foo}
+ # Nothing is added if a problem was found.
+ ::tcl::tm::path list
+} -result {}
+
+test tm-3.7 {tm: module path management, input validation/list interaction} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ catch {
+ ::tcl::tm::path add foo/bar
+ ::tcl::tm::path add snarf geode foo
+ }
+ # Nothing is added if a problem was found.
+ ::tcl::tm::path list
+} -result {foo/bar}
+
+test tm-3.8 {tm: module path management, input validation, ignore duplicates} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ # Ignore path if present
+ ::tcl::tm::path add foo
+ ::tcl::tm::path add snarf geode foo
+ ::tcl::tm::path list
+} -result {geode snarf foo}
+
+test tm-3.9 {tm: module path management, input validation, ignore duplicates} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ # Ignore path if present
+ ::tcl::tm::path add foo snarf geode foo
+ ::tcl::tm::path list
+} -result {geode snarf foo}
+
+test tm-3.10 {tm: module path management, remove} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ ::tcl::tm::path add snarf geode foo
+ ::tcl::tm::path remove foo
+ ::tcl::tm::path list
+} -result {geode snarf}
+
+test tm-3.11 {tm: module path management, remove ignores unknown path} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ ::tcl::tm::path add foo snarf geode
+ ::tcl::tm::path remove fox
+ ::tcl::tm::path list
+} -result {geode snarf foo}
+
+
+proc genpaths {base} {
+ # Normalizing picks up drive letters on windows [Bug 1053568]
+ set base [file normalize $base]
+ foreach {major minor} [split [info tclversion] .] break
+ set results {}
+ set base [file join $base tcl$major]
+ lappend results [file join $base site-tcl]
+ for {set i 0} {$i <= $minor} {incr i} {
+ lappend results [file join $base ${major}.$i]
+ }
+ return $results
+}
+
+test tm-3.12 {tm: module path management, roots} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ ::tcl::tm::roots /FOO
+ ::tcl::tm::path list
+} -result [genpaths /FOO]
+
+test tm-3.13 {tm: module path management, roots} -setup {
+ # Save and clear the list
+ set defaults [::tcl::tm::path list]
+ foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+ # Restore old contents of path list.
+ foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+ foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+ ::tcl::tm::roots [list /FOO /BAR]
+ ::tcl::tm::path list
+} -result [concat [genpaths /BAR] [genpaths /FOO]]
+
+rename genpaths {}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/trace.test b/pkgs/msgcat/tests/trace.test
new file mode 100644
index 0000000..693dbad
--- /dev/null
+++ b/pkgs/msgcat/tests/trace.test
@@ -0,0 +1,2639 @@
+# Commands covered: trace
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testcmdtrace [llength [info commands testcmdtrace]]
+testConstraint testevalobjv [llength [info commands testevalobjv]]
+
+# Used for constraining memory leak tests
+testConstraint memory [llength [info commands memory]]
+
+proc getbytes {} {
+ set lines [split [memory info] "\n"]
+ lindex [lindex $lines 3] 3
+}
+
+proc traceScalar {name1 name2 op} {
+ global info
+ set info [list $name1 $name2 $op [catch {uplevel set $name1} msg] $msg]
+}
+proc traceScalarAppend {name1 name2 op} {
+ global info
+ lappend info $name1 $name2 $op [catch {uplevel set $name1} msg] $msg
+}
+proc traceArray {name1 name2 op} {
+ global info
+ set info [list $name1 $name2 $op [catch {uplevel set [set name1]($name2)} msg] $msg]
+}
+proc traceArray2 {name1 name2 op} {
+ global info
+ set info [list $name1 $name2 $op]
+}
+proc traceProc {name1 name2 op} {
+ global info
+ set info [concat $info [list $name1 $name2 $op]]
+}
+proc traceTag {tag args} {
+ global info
+ set info [concat $info $tag]
+}
+proc traceError {args} {
+ error "trace returned error"
+}
+proc traceCheck {cmd args} {
+ global info
+ set info [list [catch $cmd msg] $msg]
+}
+proc traceCrtElement {value name1 name2 op} {
+ uplevel set ${name1}($name2) $value
+}
+proc traceCommand {oldName newName op} {
+ global info
+ set info [list $oldName $newName $op]
+}
+
+test trace-0.0 {memory corruption in trace (Tcl Bug 484339)} {
+ # You may need Purify or Electric Fence to reliably
+ # see this one fail.
+ catch {unset z}
+ trace add variable z array {set z(foo) 1 ;#}
+ set res "names: [array names z]"
+ catch {unset ::z}
+ trace variable ::z w {unset ::z; error "memory corruption";#}
+ list [catch {set ::z 1} msg] $msg
+} {1 {can't set "::z": memory corruption}}
+
+# Read-tracing on variables
+
+test trace-1.1 {trace variable reads} {
+ catch {unset x}
+ set info {}
+ trace add variable x read traceScalar
+ list [catch {set x} msg] $msg $info
+} {1 {can't read "x": no such variable} {x {} read 1 {can't read "x": no such variable}}}
+test trace-1.2 {trace variable reads} {
+ catch {unset x}
+ set x 123
+ set info {}
+ trace add variable x read traceScalar
+ list [catch {set x} msg] $msg $info
+} {0 123 {x {} read 0 123}}
+test trace-1.3 {trace variable reads} {
+ catch {unset x}
+ set info {}
+ trace add variable x read traceScalar
+ set x 123
+ set info
+} {}
+test trace-1.4 {trace array element reads} {
+ catch {unset x}
+ set info {}
+ trace add variable x(2) read traceArray
+ list [catch {set x(2)} msg] $msg $info
+} {1 {can't read "x(2)": no such element in array} {x 2 read 1 {can't read "x(2)": no such element in array}}}
+test trace-1.5 {trace array element reads} {
+ catch {unset x}
+ set x(2) zzz
+ set info {}
+ trace add variable x(2) read traceArray
+ list [catch {set x(2)} msg] $msg $info
+} {0 zzz {x 2 read 0 zzz}}
+test trace-1.6 {trace array element reads} {
+ catch {unset x}
+ set info {}
+ trace add variable x read traceArray2
+ proc p {} {
+ global x
+ set x(2) willi
+ return $x(2)
+ }
+ list [catch {p} msg] $msg $info
+} {0 willi {x 2 read}}
+test trace-1.7 {trace array element reads, create element undefined if nonexistant} {
+ catch {unset x}
+ set info {}
+ trace add variable x read q
+ proc q {name1 name2 op} {
+ global info
+ set info [list $name1 $name2 $op]
+ global $name1
+ set ${name1}($name2) wolf
+ }
+ proc p {} {
+ global x
+ set x(X) willi
+ return $x(Y)
+ }
+ list [catch {p} msg] $msg $info
+} {0 wolf {x Y read}}
+test trace-1.8 {trace reads on whole arrays} {
+ catch {unset x}
+ set info {}
+ trace add variable x read traceArray
+ list [catch {set x(2)} msg] $msg $info
+} {1 {can't read "x(2)": no such variable} {}}
+test trace-1.9 {trace reads on whole arrays} {
+ catch {unset x}
+ set x(2) zzz
+ set info {}
+ trace add variable x read traceArray
+ list [catch {set x(2)} msg] $msg $info
+} {0 zzz {x 2 read 0 zzz}}
+test trace-1.10 {trace variable reads} {
+ catch {unset x}
+ set x 444
+ set info {}
+ trace add variable x read traceScalar
+ unset x
+ set info
+} {}
+test trace-1.11 {read traces that modify the array structure} {
+ catch {unset x}
+ set x(bar) 0
+ trace variable x r {set x(foo) 1 ;#}
+ trace variable x r {unset -nocomplain x(bar) ;#}
+ array get x
+} {}
+test trace-1.12 {read traces that modify the array structure} {
+ catch {unset x}
+ set x(bar) 0
+ trace variable x r {unset -nocomplain x(bar) ;#}
+ trace variable x r {set x(foo) 1 ;#}
+ array get x
+} {}
+test trace-1.13 {read traces that modify the array structure} {
+ catch {unset x}
+ set x(bar) 0
+ trace variable x r {set x(foo) 1 ;#}
+ trace variable x r {unset -nocomplain x;#}
+ list [catch {array get x} res] $res
+} {1 {can't read "x(bar)": no such variable}}
+test trace-1.14 {read traces that modify the array structure} {
+ catch {unset x}
+ set x(bar) 0
+ trace variable x r {unset -nocomplain x;#}
+ trace variable x r {set x(foo) 1 ;#}
+ list [catch {array get x} res] $res
+} {1 {can't read "x(bar)": no such variable}}
+
+# Basic write-tracing on variables
+
+test trace-2.1 {trace variable writes} {
+ catch {unset x}
+ set info {}
+ trace add variable x write traceScalar
+ set x 123
+ set info
+} {x {} write 0 123}
+test trace-2.2 {trace writes to array elements} {
+ catch {unset x}
+ set info {}
+ trace add variable x(33) write traceArray
+ set x(33) 444
+ set info
+} {x 33 write 0 444}
+test trace-2.3 {trace writes on whole arrays} {
+ catch {unset x}
+ set info {}
+ trace add variable x write traceArray
+ set x(abc) qq
+ set info
+} {x abc write 0 qq}
+test trace-2.4 {trace variable writes} {
+ catch {unset x}
+ set x 1234
+ set info {}
+ trace add variable x write traceScalar
+ set x
+ set info
+} {}
+test trace-2.5 {trace variable writes} {
+ catch {unset x}
+ set x 1234
+ set info {}
+ trace add variable x write traceScalar
+ unset x
+ set info
+} {}
+test trace-2.6 {trace variable writes on compiled local} {
+ #
+ # Check correct function of whole array traces on compiled local
+ # arrays [Bug 1770591]. The corresponding function for read traces is
+ # already indirectly tested in trace-1.7
+ #
+ catch {unset x}
+ set info {}
+ proc p {} {
+ trace add variable x write traceArray
+ set x(X) willy
+ }
+ p
+ set info
+} {x X write 0 willy}
+test trace-2.7 {trace variable writes on errorInfo} -body {
+ #
+ # Check correct behaviour of write traces on errorInfo.
+ # [Bug 1773040]
+ trace add variable ::errorInfo write traceScalar
+ catch {set dne}
+ lrange [set info] 0 2
+} -cleanup {
+ # always remove trace on errorInfo otherwise further tests will fail
+ unset ::errorInfo
+} -result {::errorInfo {} write}
+
+
+
+# append no longer triggers read traces when fetching the old values of
+# variables before doing the append operation. However, lappend _does_
+# still trigger these read traces. Also lappend triggers only one write
+# trace: after appending all arguments to the list.
+
+test trace-3.1 {trace variable read-modify-writes} {
+ catch {unset x}
+ set info {}
+ trace add variable x read traceScalarAppend
+ append x 123
+ append x 456
+ lappend x 789
+ set info
+} {x {} read 0 123456}
+test trace-3.2 {trace variable read-modify-writes} {
+ catch {unset x}
+ set info {}
+ trace add variable x {read write} traceScalarAppend
+ append x 123
+ lappend x 456
+ set info
+} {x {} write 0 123 x {} read 0 123 x {} write 0 {123 456}}
+
+# Basic unset-tracing on variables
+
+test trace-4.1 {trace variable unsets} {
+ catch {unset x}
+ set info {}
+ trace add variable x unset traceScalar
+ catch {unset x}
+ set info
+} {x {} unset 1 {can't read "x": no such variable}}
+test trace-4.2 {variable mustn't exist during unset trace} {
+ catch {unset x}
+ set x 1234
+ set info {}
+ trace add variable x unset traceScalar
+ unset x
+ set info
+} {x {} unset 1 {can't read "x": no such variable}}
+test trace-4.3 {unset traces mustn't be called during reads and writes} {
+ catch {unset x}
+ set info {}
+ trace add variable x unset traceScalar
+ set x 44
+ set x
+ set info
+} {}
+test trace-4.4 {trace unsets on array elements} {
+ catch {unset x}
+ set x(0) 18
+ set info {}
+ trace add variable x(1) unset traceArray
+ catch {unset x(1)}
+ set info
+} {x 1 unset 1 {can't read "x(1)": no such element in array}}
+test trace-4.5 {trace unsets on array elements} {
+ catch {unset x}
+ set x(1) 18
+ set info {}
+ trace add variable x(1) unset traceArray
+ unset x(1)
+ set info
+} {x 1 unset 1 {can't read "x(1)": no such element in array}}
+test trace-4.6 {trace unsets on array elements} {
+ catch {unset x}
+ set x(1) 18
+ set info {}
+ trace add variable x(1) unset traceArray
+ unset x
+ set info
+} {x 1 unset 1 {can't read "x(1)": no such variable}}
+test trace-4.7 {trace unsets on whole arrays} {
+ catch {unset x}
+ set x(1) 18
+ set info {}
+ trace add variable x unset traceProc
+ catch {unset x(0)}
+ set info
+} {}
+test trace-4.8 {trace unsets on whole arrays} {
+ catch {unset x}
+ set x(1) 18
+ set x(2) 144
+ set x(3) 14
+ set info {}
+ trace add variable x unset traceProc
+ unset x(1)
+ set info
+} {x 1 unset}
+test trace-4.9 {trace unsets on whole arrays} {
+ catch {unset x}
+ set x(1) 18
+ set x(2) 144
+ set x(3) 14
+ set info {}
+ trace add variable x unset traceProc
+ unset x
+ set info
+} {x {} unset}
+
+# Array tracing on variables
+test trace-5.1 {array traces fire on accesses via [array]} {
+ catch {unset x}
+ set x(b) 2
+ trace add variable x array traceArray2
+ set ::info {}
+ array set x {a 1}
+ set ::info
+} {x {} array}
+test trace-5.2 {array traces do not fire on normal accesses} {
+ catch {unset x}
+ set x(b) 2
+ trace add variable x array traceArray2
+ set ::info {}
+ set x(a) 1
+ set x(b) $x(a)
+ set ::info
+} {}
+test trace-5.3 {array traces do not outlive variable} {
+ catch {unset x}
+ trace add variable x array traceArray2
+ set ::info {}
+ set x(a) 1
+ unset x
+ array set x {a 1}
+ set ::info
+} {}
+test trace-5.4 {array traces properly listed in trace information} {
+ catch {unset x}
+ trace add variable x array traceArray2
+ set result [trace info variable x]
+ set result
+} [list [list array traceArray2]]
+test trace-5.5 {array traces properly listed in trace information} {
+ catch {unset x}
+ trace variable x a traceArray2
+ set result [trace vinfo x]
+ set result
+} [list [list a traceArray2]]
+test trace-5.6 {array traces don't fire on scalar variables} {
+ catch {unset x}
+ set x foo
+ trace add variable x array traceArray2
+ set ::info {}
+ catch {array set x {a 1}}
+ set ::info
+} {}
+test trace-5.7 {array traces fire for undefined variables} {
+ catch {unset x}
+ trace add variable x array traceArray2
+ set ::info {}
+ array set x {a 1}
+ set ::info
+} {x {} array}
+test trace-5.8 {array traces fire for undefined variables} {
+ catch {unset x}
+ trace add variable x array {set x(foo) 1 ;#}
+ set res "names: [array names x]"
+} {names: foo}
+
+# Trace multiple trace types at once.
+
+test trace-6.1 {multiple ops traced at once} {
+ catch {unset x}
+ set info {}
+ trace add variable x {read write unset} traceProc
+ catch {set x}
+ set x 22
+ set x
+ set x 33
+ unset x
+ set info
+} {x {} read x {} write x {} read x {} write x {} unset}
+test trace-6.2 {multiple ops traced on array element} {
+ catch {unset x}
+ set info {}
+ trace add variable x(0) {read write unset} traceProc
+ catch {set x(0)}
+ set x(0) 22
+ set x(0)
+ set x(0) 33
+ unset x(0)
+ unset x
+ set info
+} {x 0 read x 0 write x 0 read x 0 write x 0 unset}
+test trace-6.3 {multiple ops traced on whole array} {
+ catch {unset x}
+ set info {}
+ trace add variable x {read write unset} traceProc
+ catch {set x(0)}
+ set x(0) 22
+ set x(0)
+ set x(0) 33
+ unset x(0)
+ unset x
+ set info
+} {x 0 write x 0 read x 0 write x 0 unset x {} unset}
+
+# Check order of invocation of traces
+
+test trace-7.1 {order of invocation of traces} {
+ catch {unset x}
+ set info {}
+ trace add variable x read "traceTag 1"
+ trace add variable x read "traceTag 2"
+ trace add variable x read "traceTag 3"
+ catch {set x}
+ set x 22
+ set x
+ set info
+} {3 2 1 3 2 1}
+test trace-7.2 {order of invocation of traces} {
+ catch {unset x}
+ set x(0) 44
+ set info {}
+ trace add variable x(0) read "traceTag 1"
+ trace add variable x(0) read "traceTag 2"
+ trace add variable x(0) read "traceTag 3"
+ set x(0)
+ set info
+} {3 2 1}
+test trace-7.3 {order of invocation of traces} {
+ catch {unset x}
+ set x(0) 44
+ set info {}
+ trace add variable x(0) read "traceTag 1"
+ trace add variable x read "traceTag A1"
+ trace add variable x(0) read "traceTag 2"
+ trace add variable x read "traceTag A2"
+ trace add variable x(0) read "traceTag 3"
+ trace add variable x read "traceTag A3"
+ set x(0)
+ set info
+} {A3 A2 A1 3 2 1}
+
+# Check effects of errors in trace procedures
+
+test trace-8.1 {error returns from traces} {
+ catch {unset x}
+ set x 123
+ set info {}
+ trace add variable x read "traceTag 1"
+ trace add variable x read traceError
+ list [catch {set x} msg] $msg $info
+} {1 {can't read "x": trace returned error} {}}
+test trace-8.2 {error returns from traces} {
+ catch {unset x}
+ set x 123
+ set info {}
+ trace add variable x write "traceTag 1"
+ trace add variable x write traceError
+ list [catch {set x 44} msg] $msg $info
+} {1 {can't set "x": trace returned error} {}}
+test trace-8.3 {error returns from traces} {
+ catch {unset x}
+ set x 123
+ set info {}
+ trace add variable x write traceError
+ list [catch {append x 44} msg] $msg $info
+} {1 {can't set "x": trace returned error} {}}
+test trace-8.4 {error returns from traces} {
+ catch {unset x}
+ set x 123
+ set info {}
+ trace add variable x unset "traceTag 1"
+ trace add variable x unset traceError
+ list [catch {unset x} msg] $msg $info
+} {0 {} 1}
+test trace-8.5 {error returns from traces} {
+ catch {unset x}
+ set x(0) 123
+ set info {}
+ trace add variable x(0) read "traceTag 1"
+ trace add variable x read "traceTag 2"
+ trace add variable x read traceError
+ trace add variable x read "traceTag 3"
+ list [catch {set x(0)} msg] $msg $info
+} {1 {can't read "x(0)": trace returned error} 3}
+test trace-8.6 {error returns from traces} {
+ catch {unset x}
+ set x 123
+ trace add variable x unset traceError
+ list [catch {unset x} msg] $msg
+} {0 {}}
+test trace-8.7 {error returns from traces} {
+ # This test just makes sure that the memory for the error message
+ # gets deallocated correctly when the trace is invoked again or
+ # when the trace is deleted.
+ catch {unset x}
+ set x 123
+ trace add variable x read traceError
+ catch {set x}
+ catch {set x}
+ trace remove variable x read traceError
+} {}
+test trace-8.8 {error returns from traces} {
+ # Yet more elaborate memory corruption testing that checks nothing
+ # bad happens when the trace deletes itself and installs something
+ # new. Alas, there is no neat way to guarantee that this test will
+ # fail if there is a problem, but that's life and with the new code
+ # it should *never* fail.
+ #
+ # Adapted from Bug #219393 reported by Don Porter.
+ catch {rename ::foo {}}
+ proc foo {old args} {
+ trace remove variable ::x write [list foo $old]
+ trace add variable ::x write [list foo $::x]
+ error "foo"
+ }
+ catch {unset ::x ::y}
+ set x junk
+ trace add variable ::x write [list foo $x]
+ for {set y 0} {$y<100} {incr y} {
+ catch {set x junk}
+ }
+ unset x
+} {}
+
+# Check to see that variables are expunged before trace
+# procedures are invoked, so trace procedure can even manipulate
+# a new copy of the variables.
+
+test trace-9.1 {be sure variable is unset before trace is called} {
+ catch {unset x}
+ set x 33
+ set info {}
+ trace add variable x unset {traceCheck {uplevel set x}}
+ unset x
+ set info
+} {1 {can't read "x": no such variable}}
+test trace-9.2 {be sure variable is unset before trace is called} {
+ catch {unset x}
+ set x 33
+ set info {}
+ trace add variable x unset {traceCheck {uplevel set x 22}}
+ unset x
+ concat $info [list [catch {set x} msg] $msg]
+} {0 22 0 22}
+test trace-9.3 {be sure traces are cleared before unset trace called} {
+ catch {unset x}
+ set x 33
+ set info {}
+ trace add variable x unset {traceCheck {uplevel trace info variable x}}
+ unset x
+ set info
+} {0 {}}
+test trace-9.4 {set new trace during unset trace} {
+ catch {unset x}
+ set x 33
+ set info {}
+ trace add variable x unset {traceCheck {global x; trace add variable x unset traceProc}}
+ unset x
+ concat $info [trace info variable x]
+} {0 {} {unset traceProc}}
+
+test trace-10.1 {make sure array elements are unset before traces are called} {
+ catch {unset x}
+ set x(0) 33
+ set info {}
+ trace add variable x(0) unset {traceCheck {uplevel set x(0)}}
+ unset x(0)
+ set info
+} {1 {can't read "x(0)": no such element in array}}
+test trace-10.2 {make sure array elements are unset before traces are called} {
+ catch {unset x}
+ set x(0) 33
+ set info {}
+ trace add variable x(0) unset {traceCheck {uplevel set x(0) zzz}}
+ unset x(0)
+ concat $info [list [catch {set x(0)} msg] $msg]
+} {0 zzz 0 zzz}
+test trace-10.3 {array elements are unset before traces are called} {
+ catch {unset x}
+ set x(0) 33
+ set info {}
+ trace add variable x(0) unset {traceCheck {global x; trace info variable x(0)}}
+ unset x(0)
+ set info
+} {0 {}}
+test trace-10.4 {set new array element trace during unset trace} {
+ catch {unset x}
+ set x(0) 33
+ set info {}
+ trace add variable x(0) unset {traceCheck {uplevel {trace add variable x(0) read {}}}}
+ catch {unset x(0)}
+ concat $info [trace info variable x(0)]
+} {0 {} {read {}}}
+
+test trace-11.1 {make sure arrays are unset before traces are called} {
+ catch {unset x}
+ set x(0) 33
+ set info {}
+ trace add variable x unset {traceCheck {uplevel set x(0)}}
+ unset x
+ set info
+} {1 {can't read "x(0)": no such variable}}
+test trace-11.2 {make sure arrays are unset before traces are called} {
+ catch {unset x}
+ set x(y) 33
+ set info {}
+ trace add variable x unset {traceCheck {uplevel set x(y) 22}}
+ unset x
+ concat $info [list [catch {set x(y)} msg] $msg]
+} {0 22 0 22}
+test trace-11.3 {make sure arrays are unset before traces are called} {
+ catch {unset x}
+ set x(y) 33
+ set info {}
+ trace add variable x unset {traceCheck {uplevel array exists x}}
+ unset x
+ set info
+} {0 0}
+test trace-11.4 {make sure arrays are unset before traces are called} {
+ catch {unset x}
+ set x(y) 33
+ set info {}
+ set cmd {traceCheck {uplevel {trace info variable x}}}
+ trace add variable x unset $cmd
+ unset x
+ set info
+} {0 {}}
+test trace-11.5 {set new array trace during unset trace} {
+ catch {unset x}
+ set x(y) 33
+ set info {}
+ trace add variable x unset {traceCheck {global x; trace add variable x read {}}}
+ unset x
+ concat $info [trace info variable x]
+} {0 {} {read {}}}
+test trace-11.6 {create scalar during array unset trace} {
+ catch {unset x}
+ set x(y) 33
+ set info {}
+ trace add variable x unset {traceCheck {global x; set x 44}}
+ unset x
+ concat $info [list [catch {set x} msg] $msg]
+} {0 44 0 44}
+
+# Check special conditions (e.g. errors) in Tcl_TraceVar2.
+
+test trace-12.1 {creating array when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace add variable x(0) write traceProc
+ list [catch {set x 22} msg] $msg
+} {1 {can't set "x": variable is array}}
+test trace-12.2 {creating array when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace add variable x(0) write traceProc
+ list [catch {set x(0)} msg] $msg
+} {1 {can't read "x(0)": no such element in array}}
+test trace-12.3 {creating array when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace add variable x(0) write traceProc
+ set x(0) 22
+ set info
+} {x 0 write}
+test trace-12.4 {creating variable when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace add variable x write traceProc
+ list [catch {set x} msg] $msg
+} {1 {can't read "x": no such variable}}
+test trace-12.5 {creating variable when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace add variable x write traceProc
+ set x 22
+ set info
+} {x {} write}
+test trace-12.6 {creating variable when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace add variable x write traceProc
+ set x(0) 22
+ set info
+} {x 0 write}
+test trace-12.7 {create array element during read trace} {
+ catch {unset x}
+ set x(2) zzz
+ trace add variable x read {traceCrtElement xyzzy}
+ list [catch {set x(3)} msg] $msg
+} {0 xyzzy}
+test trace-12.8 {errors when setting variable traces} {
+ catch {unset x}
+ set x 44
+ list [catch {trace add variable x(0) write traceProc} msg] $msg
+} {1 {can't trace "x(0)": variable isn't array}}
+
+# Check trace deletion
+
+test trace-13.1 {delete one trace from another} {
+ proc delTraces {args} {
+ global x
+ trace remove variable x read {traceTag 2}
+ trace remove variable x read {traceTag 3}
+ trace remove variable x read {traceTag 4}
+ }
+ catch {unset x}
+ set x 44
+ set info {}
+ trace add variable x read {traceTag 1}
+ trace add variable x read {traceTag 2}
+ trace add variable x read {traceTag 3}
+ trace add variable x read {traceTag 4}
+ trace add variable x read delTraces
+ trace add variable x read {traceTag 5}
+ set x
+ set info
+} {5 1}
+
+test trace-13.2 {leak when unsetting traced variable} \
+ -constraints memory -body {
+ set end [getbytes]
+ proc f args {}
+ for {set i 0} {$i < 5} {incr i} {
+ trace add variable bepa write f
+ set bepa a
+ unset bepa
+ set tmp $end
+ set end [getbytes]
+ }
+ expr {$end - $tmp}
+ } -cleanup {
+ unset -nocomplain end i tmp
+ } -result 0
+test trace-13.3 {leak when removing traces} \
+ -constraints memory -body {
+ set end [getbytes]
+ proc f args {}
+ for {set i 0} {$i < 5} {incr i} {
+ trace add variable bepa write f
+ set bepa a
+ trace remove variable bepa write f
+ set tmp $end
+ set end [getbytes]
+ }
+ expr {$end - $tmp}
+ } -cleanup {
+ unset -nocomplain end i tmp
+ } -result 0
+test trace-13.4 {leaks in error returns from traces} \
+ -constraints memory -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ set apa {a 1 b 2}
+ set bepa [lrange $apa 0 end]
+ trace add variable bepa write {error hej}
+ catch {set bepa a}
+ unset bepa
+ set tmp $end
+ set end [getbytes]
+ }
+ expr {$end - $tmp}
+ } -cleanup {
+ unset -nocomplain end i tmp
+ } -result 0
+
+# Check operation and syntax of "trace" command.
+
+# Syntax for adding/removing variable and command traces is basically the
+# same:
+# trace add variable name opList command
+# trace remove variable name opList command
+#
+# The following loops just get all the common "wrong # args" tests done.
+
+set i 0
+set start "wrong # args:"
+foreach type {variable command} {
+ foreach op {add remove} {
+ test trace-14.0.[incr i] "trace command, wrong # args errors" {
+ list [catch {trace $op $type} msg] $msg
+ } [list 1 "$start should be \"trace $op $type name opList command\""]
+ test trace-14.0.[incr i] "trace command wrong # args errors" {
+ list [catch {trace $op $type foo} msg] $msg
+ } [list 1 "$start should be \"trace $op $type name opList command\""]
+ test trace-14.0.[incr i] "trace command, wrong # args errors" {
+ list [catch {trace $op $type foo bar} msg] $msg
+ } [list 1 "$start should be \"trace $op $type name opList command\""]
+ test trace-14.0.[incr i] "trace command, wrong # args errors" {
+ list [catch {trace $op $type foo bar baz boo} msg] $msg
+ } [list 1 "$start should be \"trace $op $type name opList command\""]
+ }
+ test trace-14.0.[incr i] "trace command, wrong # args errors" {
+ list [catch {trace info $type foo bar} msg] $msg
+ } [list 1 "$start should be \"trace info $type name\""]
+ test trace-14.0.[incr i] "trace command, wrong # args errors" {
+ list [catch {trace info $type} msg] $msg
+ } [list 1 "$start should be \"trace info $type name\""]
+}
+
+test trace-14.1 "trace command, wrong # args errors" {
+ list [catch {trace} msg] $msg
+} [list 1 "wrong # args: should be \"trace option ?arg ...?\""]
+test trace-14.2 "trace command, wrong # args errors" {
+ list [catch {trace add} msg] $msg
+} [list 1 "wrong # args: should be \"trace add type ?arg ...?\""]
+test trace-14.3 "trace command, wrong # args errors" {
+ list [catch {trace remove} msg] $msg
+} [list 1 "wrong # args: should be \"trace remove type ?arg ...?\""]
+test trace-14.4 "trace command, wrong # args errors" {
+ list [catch {trace info} msg] $msg
+} [list 1 "wrong # args: should be \"trace info type name\""]
+
+test trace-14.5 {trace command, invalid option} {
+ list [catch {trace gorp} msg] $msg
+} [list 1 "bad option \"gorp\": must be add, info, remove, variable, vdelete, or vinfo"]
+
+# Again, [trace ... command] and [trace ... variable] share syntax and
+# error message styles for their opList options; these loops test those
+# error messages.
+
+set i 0
+set errs [list "array, read, unset, or write" "delete or rename" "enter, leave, enterstep, or leavestep"]
+set abbvs [list {a r u w} {d r} {}]
+proc x {} {}
+foreach type {variable command execution} err $errs abbvlist $abbvs {
+ foreach op {add remove} {
+ test trace-14.6.[incr i] "trace $op $type errors" {
+ list [catch {trace $op $type x {y z w} a} msg] $msg
+ } [list 1 "bad operation \"y\": must be $err"]
+ foreach abbv $abbvlist {
+ test trace-14.6.[incr i] "trace $op $type rejects abbreviations" {
+ list [catch {trace $op $type x $abbv a} msg] $msg
+ } [list 1 "bad operation \"$abbv\": must be $err"]
+ }
+ test trace-14.6.[incr i] "trace $op $type rejects null opList" {
+ list [catch {trace $op $type x {} a} msg] $msg
+ } [list 1 "bad operation list \"\": must be one or more of $err"]
+ }
+}
+rename x {}
+
+test trace-14.7 {trace command, "trace variable" errors} {
+ list [catch {trace variable} msg] $msg
+} [list 1 "wrong # args: should be \"trace variable name ops command\""]
+test trace-14.8 {trace command, "trace variable" errors} {
+ list [catch {trace variable x} msg] $msg
+} [list 1 "wrong # args: should be \"trace variable name ops command\""]
+test trace-14.9 {trace command, "trace variable" errors} {
+ list [catch {trace variable x y} msg] $msg
+} [list 1 "wrong # args: should be \"trace variable name ops command\""]
+test trace-14.10 {trace command, "trace variable" errors} {
+ list [catch {trace variable x y z w} msg] $msg
+} [list 1 "wrong # args: should be \"trace variable name ops command\""]
+test trace-14.11 {trace command, "trace variable" errors} {
+ list [catch {trace variable x y z} msg] $msg
+} [list 1 "bad operations \"y\": should be one or more of rwua"]
+
+
+test trace-14.12 {trace command ("remove variable" option)} {
+ catch {unset x}
+ set info {}
+ trace add variable x write traceProc
+ trace remove variable x write traceProc
+} {}
+test trace-14.13 {trace command ("remove variable" option)} {
+ catch {unset x}
+ set info {}
+ trace add variable x write traceProc
+ trace remove variable x write traceProc
+ set x 12345
+ set info
+} {}
+test trace-14.14 {trace command ("remove variable" option)} {
+ catch {unset x}
+ set info {}
+ trace add variable x write {traceTag 1}
+ trace add variable x write traceProc
+ trace add variable x write {traceTag 2}
+ set x yy
+ trace remove variable x write traceProc
+ set x 12345
+ trace remove variable x write {traceTag 1}
+ set x foo
+ trace remove variable x write {traceTag 2}
+ set x gorp
+ set info
+} {2 x {} write 1 2 1 2}
+test trace-14.15 {trace command ("remove variable" option)} {
+ catch {unset x}
+ set info {}
+ trace add variable x write {traceTag 1}
+ trace remove variable x write non_existent
+ set x 12345
+ set info
+} {1}
+test trace-14.16 {trace command ("info variable" option)} {
+ catch {unset x}
+ trace add variable x write {traceTag 1}
+ trace add variable x write traceProc
+ trace add variable x write {traceTag 2}
+ trace info variable x
+} {{write {traceTag 2}} {write traceProc} {write {traceTag 1}}}
+test trace-14.17 {trace command ("info variable" option)} {
+ catch {unset x}
+ trace info variable x
+} {}
+test trace-14.18 {trace command ("info variable" option)} {
+ catch {unset x}
+ trace info variable x(0)
+} {}
+test trace-14.19 {trace command ("info variable" option)} {
+ catch {unset x}
+ set x 44
+ trace info variable x(0)
+} {}
+test trace-14.20 {trace command ("info variable" option)} {
+ catch {unset x}
+ set x 44
+ trace add variable x write {traceTag 1}
+ proc check {} {global x; trace info variable x}
+ check
+} {{write {traceTag 1}}}
+
+# Check fancy trace commands (long ones, weird arguments, etc.)
+
+test trace-15.1 {long trace command} {
+ catch {unset x}
+ set info {}
+ trace add variable x write {traceTag {This is a very very long argument. It's \
+ designed to test out the facilities of TraceVarProc for dealing \
+ with such long arguments by malloc-ing space. One possibility \
+ is that space doesn't get freed properly. If this happens, then \
+ invoking this test over and over again will eventually leak memory.}}
+ set x 44
+ set info
+} {This is a very very long argument. It's \
+ designed to test out the facilities of TraceVarProc for dealing \
+ with such long arguments by malloc-ing space. One possibility \
+ is that space doesn't get freed properly. If this happens, then \
+ invoking this test over and over again will eventually leak memory.}
+test trace-15.2 {long trace command result to ignore} {
+ proc longResult {args} {return "quite a bit of text, designed to
+ generate a core leak if this command file is invoked over and over again
+ and memory isn't being recycled correctly"}
+ catch {unset x}
+ trace add variable x write longResult
+ set x 44
+ set x 5
+ set x abcde
+} abcde
+test trace-15.3 {special list-handling in trace commands} {
+ catch {unset "x y z"}
+ set "x y z(a\n\{)" 44
+ set info {}
+ trace add variable "x y z(a\n\{)" write traceProc
+ set "x y z(a\n\{)" 33
+ set info
+} "{x y z} a\\n\\\{ write"
+
+# Check for proper handling of unsets during traces.
+
+proc traceUnset {unsetName args} {
+ global info
+ upvar $unsetName x
+ lappend info [catch {unset x} msg] $msg [catch {set x} msg] $msg
+}
+proc traceReset {unsetName resetName args} {
+ global info
+ upvar $unsetName x $resetName y
+ lappend info [catch {unset x} msg] $msg [catch {set y xyzzy} msg] $msg
+}
+proc traceReset2 {unsetName resetName args} {
+ global info
+ lappend info [catch {uplevel unset $unsetName} msg] $msg \
+ [catch {uplevel set $resetName xyzzy} msg] $msg
+}
+proc traceAppend {string name1 name2 op} {
+ global info
+ lappend info $string
+}
+
+test trace-16.1 {unsets during read traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace add variable y read {traceUnset y}
+ trace add variable y unset {traceAppend unset}
+ lappend info [catch {set y} msg] $msg
+} {unset 0 {} 1 {can't read "x": no such variable} 1 {can't read "y": no such variable}}
+test trace-16.2 {unsets during read traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) read {traceUnset y(0)}
+ lappend info [catch {set y(0)} msg] $msg
+} {0 {} 1 {can't read "x": no such variable} 1 {can't read "y(0)": no such element in array}}
+test trace-16.3 {unsets during read traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) read {traceUnset y}
+ lappend info [catch {set y(0)} msg] $msg
+} {0 {} 1 {can't read "x": no such variable} 1 {can't read "y(0)": no such variable}}
+test trace-16.4 {unsets during read traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace add variable y read {traceReset y y}
+ lappend info [catch {set y} msg] $msg
+} {0 {} 0 xyzzy 0 xyzzy}
+test trace-16.5 {unsets during read traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) read {traceReset y(0) y(0)}
+ lappend info [catch {set y(0)} msg] $msg
+} {0 {} 0 xyzzy 0 xyzzy}
+test trace-16.6 {unsets during read traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) read {traceReset y y(0)}
+ lappend info [catch {set y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 1 {can't set "y": upvar refers to element in deleted array} 1 {can't read "y(0)": no such variable} 1 {can't read "y(0)": no such variable}}
+test trace-16.7 {unsets during read traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) read {traceReset2 y y(0)}
+ lappend info [catch {set y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 0 xyzzy 1 {can't read "y(0)": no such element in array} 0 xyzzy}
+test trace-16.8 {unsets during write traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace add variable y write {traceUnset y}
+ trace add variable y unset {traceAppend unset}
+ lappend info [catch {set y xxx} msg] $msg
+} {unset 0 {} 1 {can't read "x": no such variable} 0 {}}
+test trace-16.9 {unsets during write traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) write {traceUnset y(0)}
+ lappend info [catch {set y(0) xxx} msg] $msg
+} {0 {} 1 {can't read "x": no such variable} 0 {}}
+test trace-16.10 {unsets during write traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) write {traceUnset y}
+ lappend info [catch {set y(0) xxx} msg] $msg
+} {0 {} 1 {can't read "x": no such variable} 0 {}}
+test trace-16.11 {unsets during write traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace add variable y write {traceReset y y}
+ lappend info [catch {set y xxx} msg] $msg
+} {0 {} 0 xyzzy 0 xyzzy}
+test trace-16.12 {unsets during write traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) write {traceReset y(0) y(0)}
+ lappend info [catch {set y(0) xxx} msg] $msg
+} {0 {} 0 xyzzy 0 xyzzy}
+test trace-16.13 {unsets during write traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) write {traceReset y y(0)}
+ lappend info [catch {set y(0) xxx} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 1 {can't set "y": upvar refers to element in deleted array} 0 {} 1 {can't read "y(0)": no such variable}}
+test trace-16.14 {unsets during write traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) write {traceReset2 y y(0)}
+ lappend info [catch {set y(0) xxx} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 0 xyzzy 0 {} 0 xyzzy}
+test trace-16.15 {unsets during unset traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace add variable y unset {traceUnset y}
+ lappend info [catch {unset y} msg] $msg [catch {set y} msg] $msg
+} {1 {can't unset "x": no such variable} 1 {can't read "x": no such variable} 0 {} 1 {can't read "y": no such variable}}
+test trace-16.16 {unsets during unset traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) unset {traceUnset y(0)}
+ lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {1 {can't unset "x": no such variable} 1 {can't read "x": no such variable} 0 {} 1 {can't read "y(0)": no such element in array}}
+test trace-16.17 {unsets during unset traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) unset {traceUnset y}
+ lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 1 {can't read "x": no such variable} 0 {} 1 {can't read "y(0)": no such variable}}
+test trace-16.18 {unsets during unset traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace add variable y unset {traceReset2 y y}
+ lappend info [catch {unset y} msg] $msg [catch {set y} msg] $msg
+} {1 {can't unset "y": no such variable} 0 xyzzy 0 {} 0 xyzzy}
+test trace-16.19 {unsets during unset traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) unset {traceReset2 y(0) y(0)}
+ lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {1 {can't unset "y(0)": no such element in array} 0 xyzzy 0 {} 0 xyzzy}
+test trace-16.20 {unsets during unset traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) unset {traceReset2 y y(0)}
+ lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 0 xyzzy 0 {} 0 xyzzy}
+test trace-16.21 {unsets cancelling traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace add variable y read {traceAppend first}
+ trace add variable y read {traceUnset y}
+ trace add variable y read {traceAppend third}
+ trace add variable y unset {traceAppend unset}
+ lappend info [catch {set y} msg] $msg
+} {third unset 0 {} 1 {can't read "x": no such variable} 1 {can't read "y": no such variable}}
+test trace-16.22 {unsets cancelling traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace add variable y(0) read {traceAppend first}
+ trace add variable y(0) read {traceUnset y}
+ trace add variable y(0) read {traceAppend third}
+ trace add variable y(0) unset {traceAppend unset}
+ lappend info [catch {set y(0)} msg] $msg
+} {third unset 0 {} 1 {can't read "x": no such variable} 1 {can't read "y(0)": no such variable}}
+
+# Check various non-interference between traces and other things.
+
+test trace-17.1 {trace doesn't prevent unset errors} {
+ catch {unset x}
+ set info {}
+ trace add variable x unset {traceProc}
+ list [catch {unset x} msg] $msg $info
+} {1 {can't unset "x": no such variable} {x {} unset}}
+test trace-17.2 {traced variables must survive procedure exits} {
+ catch {unset x}
+ proc p1 {} {global x; trace add variable x write traceProc}
+ p1
+ trace info variable x
+} {{write traceProc}}
+test trace-17.3 {traced variables must survive procedure exits} {
+ catch {unset x}
+ set info {}
+ proc p1 {} {global x; trace add variable x write traceProc}
+ p1
+ set x 44
+ set info
+} {x {} write}
+
+# Be sure that procedure frames are released before unset traces
+# are invoked.
+
+test trace-18.1 {unset traces on procedure returns} {
+ proc p1 {x y} {set a 44; p2 14}
+ proc p2 {z} {trace add variable z unset {traceCheck {lsort [uplevel {info vars}]}}}
+ set info {}
+ p1 foo bar
+ set info
+} {0 {a x y}}
+test trace-18.2 {namespace delete / trace vdelete combo} {
+ namespace eval ::foo {
+ variable x 123
+ }
+ proc p1 args {
+ trace vdelete ::foo::x u p1
+ }
+ trace variable ::foo::x u p1
+ namespace delete ::foo
+ info exists ::foo::x
+} 0
+test trace-18.3 {namespace delete / trace vdelete combo, Bug \#1337229} {
+ namespace eval ::ns {}
+ trace add variable ::ns::var unset {unset ::ns::var ;#}
+ namespace delete ::ns
+} {}
+test trace-18.4 {namespace delete / trace vdelete combo, Bug \#1338280} {
+ namespace eval ::ref {}
+ set ::ref::var1 AAA
+ trace add variable ::ref::var1 unset doTrace
+ set ::ref::var2 BBB
+ trace add variable ::ref::var2 {unset} doTrace
+ proc doTrace {vtraced vidx op} {
+ global info
+ append info [catch {set ::$vtraced}][llength [info vars ::ref::*]]
+ }
+ set info {}
+ namespace delete ::ref
+ rename doTrace {}
+ set info
+} 1110
+
+# Delete arrays when done, so they can be re-used as scalars
+# elsewhere.
+
+catch {unset x}
+catch {unset y}
+
+test trace-19.0.1 {trace add command (command existence)} {
+ # Just in case!
+ catch {rename nosuchname ""}
+ list [catch {trace add command nosuchname rename traceCommand} msg] $msg
+} {1 {unknown command "nosuchname"}}
+test trace-19.0.2 {trace add command (command existence in ns)} {
+ list [catch {trace add command nosuchns::nosuchname rename traceCommand} msg] $msg
+} {1 {unknown command "nosuchns::nosuchname"}}
+
+
+test trace-19.1 {trace add command (rename option)} {
+ proc foo {} {}
+ catch {rename bar {}}
+ trace add command foo rename traceCommand
+ rename foo bar
+ set info
+} {::foo ::bar rename}
+test trace-19.2 {traces stick with renamed commands} {
+ proc foo {} {}
+ catch {rename bar {}}
+ trace add command foo rename traceCommand
+ rename foo bar
+ rename bar foo
+ set info
+} {::bar ::foo rename}
+test trace-19.2.1 {trace add command rename trace exists} {
+ proc foo {} {}
+ trace add command foo rename traceCommand
+ trace info command foo
+} {{rename traceCommand}}
+test trace-19.3 {command rename traces don't fire on command deletion} {
+ proc foo {} {}
+ set info {}
+ trace add command foo rename traceCommand
+ rename foo {}
+ set info
+} {}
+test trace-19.4 {trace add command rename doesn't trace recreated commands} {
+ proc foo {} {}
+ catch {rename bar {}}
+ trace add command foo rename traceCommand
+ proc foo {} {}
+ rename foo bar
+ set info
+} {}
+test trace-19.5 {trace add command deleted removes traces} {
+ proc foo {} {}
+ trace add command foo rename traceCommand
+ proc foo {} {}
+ trace info command foo
+} {}
+
+namespace eval tc {}
+proc tc::tcfoo {} {}
+test trace-19.6 {trace add command rename in namespace} {
+ trace add command tc::tcfoo rename traceCommand
+ rename tc::tcfoo tc::tcbar
+ set info
+} {::tc::tcfoo ::tc::tcbar rename}
+test trace-19.7 {trace add command rename in namespace back again} {
+ rename tc::tcbar tc::tcfoo
+ set info
+} {::tc::tcbar ::tc::tcfoo rename}
+test trace-19.8 {trace add command rename in namespace to out of namespace} {
+ rename tc::tcfoo tcbar
+ set info
+} {::tc::tcfoo ::tcbar rename}
+test trace-19.9 {trace add command rename back into namespace} {
+ rename tcbar tc::tcfoo
+ set info
+} {::tcbar ::tc::tcfoo rename}
+test trace-19.10 {trace add command failed rename doesn't trigger trace} {
+ set info {}
+ proc foo {} {}
+ proc bar {} {}
+ trace add command foo {rename delete} traceCommand
+ catch {rename foo bar}
+ set info
+} {}
+catch {rename foo {}}
+catch {rename bar {}}
+test trace-19.11 {trace add command qualifies when renamed in namespace} {
+ set info {}
+ namespace eval tc {rename tcfoo tcbar}
+ set info
+} {::tc::tcfoo ::tc::tcbar rename}
+
+# Make sure it exists again
+proc foo {} {}
+
+test trace-20.1 {trace add command (delete option)} {
+ trace add command foo delete traceCommand
+ rename foo ""
+ set info
+} {::foo {} delete}
+test trace-20.2 {trace add command delete doesn't trace recreated commands} {
+ set info {}
+ proc foo {} {}
+ rename foo ""
+ set info
+} {}
+test trace-20.2.1 {trace add command delete trace info} {
+ proc foo {} {}
+ trace add command foo delete traceCommand
+ trace info command foo
+} {{delete traceCommand}}
+test trace-20.3 {trace add command implicit delete} {
+ proc foo {} {}
+ trace add command foo delete traceCommand
+ proc foo {} {}
+ set info
+} {::foo {} delete}
+test trace-20.3.1 {trace add command delete trace info} {
+ proc foo {} {}
+ trace info command foo
+} {}
+test trace-20.4 {trace add command rename followed by delete} {
+ set infotemp {}
+ proc foo {} {}
+ trace add command foo {rename delete} traceCommand
+ rename foo bar
+ lappend infotemp $info
+ rename bar {}
+ lappend infotemp $info
+ set info $infotemp
+ unset infotemp
+ set info
+} {{::foo ::bar rename} {::bar {} delete}}
+catch {rename foo {}}
+catch {rename bar {}}
+
+test trace-20.5 {trace add command rename and delete} {
+ set infotemp {}
+ set info {}
+ proc foo {} {}
+ trace add command foo {rename delete} traceCommand
+ rename foo bar
+ lappend infotemp $info
+ rename bar {}
+ lappend infotemp $info
+ set info $infotemp
+ unset infotemp
+ set info
+} {{::foo ::bar rename} {::bar {} delete}}
+
+test trace-20.6 {trace add command rename and delete in subinterp} {
+ set tc [interp create]
+ foreach p {traceCommand} {
+ $tc eval [list proc $p [info args $p] [info body $p]]
+ }
+ $tc eval [list set infotemp {}]
+ $tc eval [list set info {}]
+ $tc eval [list proc foo {} {}]
+ $tc eval [list trace add command foo {rename delete} traceCommand]
+ $tc eval [list rename foo bar]
+ $tc eval {lappend infotemp $info}
+ $tc eval [list rename bar {}]
+ $tc eval {lappend infotemp $info}
+ $tc eval {set info $infotemp}
+ $tc eval [list unset infotemp]
+ set info [$tc eval [list set info]]
+ interp delete $tc
+ set info
+} {{::foo ::bar rename} {::bar {} delete}}
+
+# I'd like it if this test could give 'foo {} d' as a result,
+# but interp deletion means there is no interp to evaluate
+# the trace in.
+test trace-20.7 {trace add command delete in subinterp while being deleted} {
+ set info {}
+ set tc [interp create]
+ interp alias $tc traceCommand {} traceCommand
+ $tc eval [list proc foo {} {}]
+ $tc eval [list trace add command foo {rename delete} traceCommand]
+ interp delete $tc
+ set info
+} {}
+
+proc traceDelete {cmd old new op} {
+ trace remove command $cmd {*}[lindex [trace info command $cmd] 0]
+ global info
+ set info [list $old $new $op]
+}
+proc traceCmdrename {cmd old new op} {
+ rename $old someothername
+}
+proc traceCmddelete {cmd old new op} {
+ rename $old ""
+}
+test trace-20.8 {trace delete while trace is active} {
+ set info {}
+ proc foo {} {}
+ catch {rename bar {}}
+ trace add command foo {rename delete} [list traceDelete foo]
+ rename foo bar
+ list [set info] [trace info command bar]
+} {{::foo ::bar rename} {}}
+
+test trace-20.9 {rename trace deletes command} {
+ set info {}
+ proc foo {} {}
+ catch {rename bar {}}
+ catch {rename someothername {}}
+ trace add command foo rename [list traceCmddelete foo]
+ rename foo bar
+ list [info commands foo] [info commands bar] [info commands someothername]
+} {{} {} {}}
+
+test trace-20.10 {rename trace renames command} {
+ set info {}
+ proc foo {} {}
+ catch {rename bar {}}
+ catch {rename someothername {}}
+ trace add command foo rename [list traceCmdrename foo]
+ rename foo bar
+ set info [list [info commands foo] [info commands bar] [info commands someothername]]
+ rename someothername {}
+ set info
+} {{} {} someothername}
+
+test trace-20.11 {delete trace deletes command} {
+ set info {}
+ proc foo {} {}
+ catch {rename bar {}}
+ catch {rename someothername {}}
+ trace add command foo delete [list traceCmddelete foo]
+ rename foo {}
+ list [info commands foo] [info commands bar] [info commands someothername]
+} {{} {} {}}
+
+test trace-20.12 {delete trace renames command} {
+ set info {}
+ proc foo {} {}
+ catch {rename bar {}}
+ catch {rename someothername {}}
+ trace add command foo delete [list traceCmdrename foo]
+ rename foo bar
+ rename bar {}
+ # None of these should exist.
+ list [info commands foo] [info commands bar] [info commands someothername]
+} {{} {} {}}
+
+test trace-20.13 {rename trace discards result [Bug 1355342]} {
+ proc foo {} {}
+ trace add command foo rename {set w Aha!;#}
+ list [rename foo bar] [rename bar {}]
+} {{} {}}
+test trace-20.14 {rename trace discards error result [Bug 1355342]} {
+ proc foo {} {}
+ trace add command foo rename {error}
+ list [rename foo bar] [rename bar {}]
+} {{} {}}
+test trace-20.15 {delete trace discards result [Bug 1355342]} {
+ proc foo {} {}
+ trace add command foo delete {set w Aha!;#}
+ rename foo {}
+} {}
+test trace-20.16 {delete trace discards error result [Bug 1355342]} {
+ proc foo {} {}
+ trace add command foo delete {error}
+ rename foo {}
+} {}
+
+
+proc foo {b} { set a $b }
+
+
+# Delete arrays when done, so they can be re-used as scalars
+# elsewhere.
+
+catch {unset x}
+catch {unset y}
+
+# Delete procedures when done, so we don't clash with other tests
+# (e.g. foobar will clash with 'unknown' tests).
+catch {rename foobar {}}
+catch {rename foo {}}
+catch {rename bar {}}
+
+proc foo {a} {
+ set b $a
+}
+
+proc traceExecute {args} {
+ global info
+ lappend info $args
+}
+
+test trace-21.1 {trace execution: enter} {
+ set info {}
+ trace add execution foo enter [list traceExecute foo]
+ foo 1
+ trace remove execution foo enter [list traceExecute foo]
+ set info
+} {{foo {foo 1} enter}}
+
+test trace-21.2 {trace exeuction: leave} {
+ set info {}
+ trace add execution foo leave [list traceExecute foo]
+ foo 2
+ trace remove execution foo leave [list traceExecute foo]
+ set info
+} {{foo {foo 2} 0 2 leave}}
+
+test trace-21.3 {trace exeuction: enter, leave} {
+ set info {}
+ trace add execution foo {enter leave} [list traceExecute foo]
+ foo 3
+ trace remove execution foo {enter leave} [list traceExecute foo]
+ set info
+} {{foo {foo 3} enter} {foo {foo 3} 0 3 leave}}
+
+test trace-21.4 {trace execution: enter, leave, enterstep} {
+ set info {}
+ trace add execution foo {enter leave enterstep} [list traceExecute foo]
+ foo 3
+ trace remove execution foo {enter leave enterstep} [list traceExecute foo]
+ set info
+} {{foo {foo 3} enter} {foo {set b 3} enterstep} {foo {foo 3} 0 3 leave}}
+
+test trace-21.5 {trace execution: enter, leave, enterstep, leavestep} {
+ set info {}
+ trace add execution foo {enter leave enterstep leavestep} [list traceExecute foo]
+ foo 3
+ trace remove execution foo {enter leave enterstep leavestep} [list traceExecute foo]
+ set info
+} {{foo {foo 3} enter} {foo {set b 3} enterstep} {foo {set b 3} 0 3 leavestep} {foo {foo 3} 0 3 leave}}
+
+test trace-21.6 {trace execution: enterstep, leavestep} {
+ set info {}
+ trace add execution foo {enterstep leavestep} [list traceExecute foo]
+ foo 3
+ trace remove execution foo {enterstep leavestep} [list traceExecute foo]
+ set info
+} {{foo {set b 3} enterstep} {foo {set b 3} 0 3 leavestep}}
+
+test trace-21.7 {trace execution: enterstep} {
+ set info {}
+ trace add execution foo {enterstep} [list traceExecute foo]
+ foo 3
+ trace remove execution foo {enterstep} [list traceExecute foo]
+ set info
+} {{foo {set b 3} enterstep}}
+
+test trace-21.8 {trace execution: leavestep} {
+ set info {}
+ trace add execution foo {leavestep} [list traceExecute foo]
+ foo 3
+ trace remove execution foo {leavestep} [list traceExecute foo]
+ set info
+} {{foo {set b 3} 0 3 leavestep}}
+
+test trace-21.9 {trace execution: TCL_EVAL_GLOBAL} testevalobjv {
+ trace add execution foo enter soom
+ proc ::soom args {lappend ::info SUCCESS [info level]}
+ set ::info {}
+ namespace eval test_ns_1 {
+ proc soom args {lappend ::info FAIL [info level]}
+ # [testevalobjv 1 ...] ought to produce the same
+ # results as [uplevel #0 ...].
+ testevalobjv 1 foo x
+ uplevel #0 foo x
+ }
+ namespace delete test_ns_1
+ trace remove execution foo enter soom
+ set ::info
+} {SUCCESS 1 SUCCESS 1}
+
+test trace-21.10 {trace execution: TCL_EVAL_GLOBAL} testevalobjv {
+ trace add execution foo leave soom
+ proc ::soom args {lappend ::info SUCCESS [info level]}
+ set ::info {}
+ namespace eval test_ns_1 {
+ proc soom args {lappend ::info FAIL [info level]}
+ # [testevalobjv 1 ...] ought to produce the same
+ # results as [uplevel #0 ...].
+ testevalobjv 1 foo x
+ uplevel #0 foo x
+ }
+ namespace delete test_ns_1
+ trace remove execution foo leave soom
+ set ::info
+} {SUCCESS 1 SUCCESS 1}
+
+test trace-21.11 {trace execution and alias} -setup {
+ set res {}
+ proc ::x {} {return ::}
+ namespace eval a {}
+ proc ::a::x {} {return ::a}
+ interp alias {} y {} x
+} -body {
+ lappend res [namespace eval ::a y]
+ trace add execution ::x enter {
+ rename ::x {}
+ proc ::x {} {return ::}
+ #}
+ lappend res [namespace eval ::a y]
+} -cleanup {
+ namespace delete a
+ rename ::x {}
+} -result {:: ::}
+
+proc factorial {n} {
+ if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }
+ return 1
+}
+
+test trace-22.1 {recursive(1) trace execution: enter} {
+ set info {}
+ trace add execution factorial {enter} [list traceExecute factorial]
+ factorial 1
+ trace remove execution factorial {enter} [list traceExecute factorial]
+ set info
+} {{factorial {factorial 1} enter}}
+
+test trace-22.2 {recursive(2) trace execution: enter} {
+ set info {}
+ trace add execution factorial {enter} [list traceExecute factorial]
+ factorial 2
+ trace remove execution factorial {enter} [list traceExecute factorial]
+ set info
+} {{factorial {factorial 2} enter} {factorial {factorial 1} enter}}
+
+test trace-22.3 {recursive(3) trace execution: enter} {
+ set info {}
+ trace add execution factorial {enter} [list traceExecute factorial]
+ factorial 3
+ trace remove execution factorial {enter} [list traceExecute factorial]
+ set info
+} {{factorial {factorial 3} enter} {factorial {factorial 2} enter} {factorial {factorial 1} enter}}
+
+test trace-23.1 {recursive(1) trace execution: enter, leave, enterstep, leavestep} {
+ set info {}
+ trace add execution factorial {enter leave enterstep leavestep} [list traceExecute]
+ factorial 1
+ trace remove execution factorial {enter leave enterstep leavestep} [list traceExecute]
+ join $info "\n"
+} {{factorial 1} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 0 {} leavestep
+{return 1} enterstep
+{return 1} 2 1 leavestep
+{factorial 1} 0 1 leave}
+
+test trace-23.2 {recursive(2) trace execution: enter, leave, enterstep, leavestep} {
+ set info {}
+ trace add execution factorial {enter leave enterstep leavestep} [list traceExecute]
+ factorial 2
+ trace remove execution factorial {enter leave enterstep leavestep} [list traceExecute]
+ join $info "\n"
+} {{factorial 2} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{expr {$n * [factorial [expr {$n -1 }]]}} enterstep
+{expr {$n -1 }} enterstep
+{expr {$n -1 }} 0 1 leavestep
+{factorial 1} enterstep
+{factorial 1} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 0 {} leavestep
+{return 1} enterstep
+{return 1} 2 1 leavestep
+{factorial 1} 0 1 leave
+{factorial 1} 0 1 leavestep
+{expr {$n * [factorial [expr {$n -1 }]]}} 0 2 leavestep
+{return 2} enterstep
+{return 2} 2 2 leavestep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 2 2 leavestep
+{factorial 2} 0 2 leave}
+
+test trace-23.3 {recursive(3) trace execution: enter, leave, enterstep, leavestep} {
+ set info {}
+ trace add execution factorial {enter leave enterstep leavestep} [list traceExecute]
+ factorial 3
+ trace remove execution factorial {enter leave enterstep leavestep} [list traceExecute]
+ join $info "\n"
+} {{factorial 3} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{expr {$n * [factorial [expr {$n -1 }]]}} enterstep
+{expr {$n -1 }} enterstep
+{expr {$n -1 }} 0 2 leavestep
+{factorial 2} enterstep
+{factorial 2} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{expr {$n * [factorial [expr {$n -1 }]]}} enterstep
+{expr {$n -1 }} enterstep
+{expr {$n -1 }} 0 1 leavestep
+{factorial 1} enterstep
+{factorial 1} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 0 {} leavestep
+{return 1} enterstep
+{return 1} 2 1 leavestep
+{factorial 1} 0 1 leave
+{factorial 1} 0 1 leavestep
+{expr {$n * [factorial [expr {$n -1 }]]}} 0 2 leavestep
+{return 2} enterstep
+{return 2} 2 2 leavestep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 2 2 leavestep
+{factorial 2} 0 2 leave
+{factorial 2} 0 2 leavestep
+{expr {$n * [factorial [expr {$n -1 }]]}} 0 6 leavestep
+{return 6} enterstep
+{return 6} 2 6 leavestep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 2 6 leavestep
+{factorial 3} 0 6 leave}
+
+proc traceDelete {cmd args} {
+ trace remove execution $cmd {*}[lindex [trace info execution $cmd] 0]
+ global info
+ set info $args
+}
+
+test trace-24.1 {delete trace during enter trace} {
+ set info {}
+ trace add execution foo enter [list traceDelete foo]
+ foo 1
+ list $info [catch {trace info execution foo} res] $res
+} {{{foo 1} enter} 0 {}}
+
+test trace-24.2 {delete trace during leave trace} {
+ set info {}
+ trace add execution foo leave [list traceDelete foo]
+ foo 1
+ list $info [catch {trace info execution foo} res] $res
+} {{{foo 1} 0 1 leave} 0 {}}
+
+test trace-24.3 {delete trace during enter-leave trace} {
+ set info {}
+ trace add execution foo {enter leave} [list traceDelete foo]
+ foo 1
+ list $info [catch {trace info execution foo} res] $res
+} {{{foo 1} enter} 0 {}}
+
+test trace-24.4 {delete trace during all exec traces} {
+ set info {}
+ trace add execution foo {enter leave enterstep leavestep} [list traceDelete foo]
+ foo 1
+ list $info [catch {trace info execution foo} res] $res
+} {{{foo 1} enter} 0 {}}
+
+test trace-24.5 {delete trace during all exec traces except enter} {
+ set info {}
+ trace add execution foo {leave enterstep leavestep} [list traceDelete foo]
+ foo 1
+ list $info [catch {trace info execution foo} res] $res
+} {{{set b 1} enterstep} 0 {}}
+
+proc traceDelete {cmd args} {
+ rename $cmd {}
+ global info
+ set info $args
+}
+
+proc foo {a} {
+ set b $a
+}
+
+test trace-25.1 {delete command during enter trace} {
+ set info {}
+ trace add execution foo enter [list traceDelete foo]
+ catch {foo 1} err
+ list $err $info [catch {trace info execution foo} res] $res
+} {{invalid command name "foo"} {{foo 1} enter} 1 {unknown command "foo"}}
+
+proc foo {a} {
+ set b $a
+}
+
+test trace-25.2 {delete command during leave trace} {
+ set info {}
+ trace add execution foo leave [list traceDelete foo]
+ foo 1
+ list $info [catch {trace info execution foo} res] $res
+} {{{foo 1} 0 1 leave} 1 {unknown command "foo"}}
+
+proc foo {a} {
+ set b $a
+}
+
+test trace-25.3 {delete command during enter then leave trace} {
+ set info {}
+ trace add execution foo enter [list traceDelete foo]
+ trace add execution foo leave [list traceDelete foo]
+ catch {foo 1} err
+ list $err $info [catch {trace info execution foo} res] $res
+} {{invalid command name "foo"} {{foo 1} enter} 1 {unknown command "foo"}}
+
+proc foo {a} {
+ set b $a
+}
+proc traceExecute2 {args} {
+ global info
+ lappend info $args
+}
+
+# This shows the peculiar consequences of having two traces
+# at the same time: as well as tracing the procedure you want
+test trace-25.4 {order dependencies of two enter traces} {
+ set info {}
+ trace add execution foo enter [list traceExecute traceExecute]
+ trace add execution foo enter [list traceExecute2 traceExecute2]
+ catch {foo 1} err
+ trace remove execution foo enter [list traceExecute traceExecute]
+ trace remove execution foo enter [list traceExecute2 traceExecute2]
+ join [list $err [join $info \n] [trace info execution foo]] "\n"
+} {1
+traceExecute2 {foo 1} enter
+traceExecute {foo 1} enter
+}
+
+test trace-25.5 {order dependencies of two step traces} {
+ set info {}
+ trace add execution foo enterstep [list traceExecute traceExecute]
+ trace add execution foo enterstep [list traceExecute2 traceExecute2]
+ catch {foo 1} err
+ trace remove execution foo enterstep [list traceExecute traceExecute]
+ trace remove execution foo enterstep [list traceExecute2 traceExecute2]
+ join [list $err [join $info \n] [trace info execution foo]] "\n"
+} {1
+traceExecute2 {set b 1} enterstep
+traceExecute {set b 1} enterstep
+}
+
+# We don't want the result string (5th argument), or the results
+# will get unmanageable.
+proc tracePostExecute {args} {
+ global info
+ lappend info [concat [lrange $args 0 2] [lindex $args 4]]
+}
+proc tracePostExecute2 {args} {
+ global info
+ lappend info [concat [lrange $args 0 2] [lindex $args 4]]
+}
+
+test trace-25.6 {order dependencies of two leave traces} {
+ set info {}
+ trace add execution foo leave [list tracePostExecute tracePostExecute]
+ trace add execution foo leave [list tracePostExecute2 tracePostExecute2]
+ catch {foo 1} err
+ trace remove execution foo leave [list tracePostExecute tracePostExecute]
+ trace remove execution foo leave [list tracePostExecute2 tracePostExecute2]
+ join [list $err [join $info \n] [trace info execution foo]] "\n"
+} {1
+tracePostExecute {foo 1} 0 leave
+tracePostExecute2 {foo 1} 0 leave
+}
+
+test trace-25.7 {order dependencies of two leavestep traces} {
+ set info {}
+ trace add execution foo leavestep [list tracePostExecute tracePostExecute]
+ trace add execution foo leavestep [list tracePostExecute2 tracePostExecute2]
+ catch {foo 1} err
+ trace remove execution foo leavestep [list tracePostExecute tracePostExecute]
+ trace remove execution foo leavestep [list tracePostExecute2 tracePostExecute2]
+ join [list $err [join $info \n] [trace info execution foo]] "\n"
+} {1
+tracePostExecute {set b 1} 0 leavestep
+tracePostExecute2 {set b 1} 0 leavestep
+}
+
+proc foo {a} {
+ set b $a
+}
+
+proc traceDelete {cmd args} {
+ rename $cmd {}
+ global info
+ set info $args
+}
+
+test trace-25.8 {delete command during enter leave and enter/leave-step traces} {
+ set info {}
+ trace add execution foo enter [list traceDelete foo]
+ trace add execution foo leave [list traceDelete foo]
+ trace add execution foo enterstep [list traceDelete foo]
+ trace add execution foo leavestep [list traceDelete foo]
+ catch {foo 1} err
+ list $err $info [catch {trace info execution foo} res] $res
+} {{invalid command name "foo"} {{foo 1} enter} 1 {unknown command "foo"}}
+
+proc foo {a} {
+ set b $a
+}
+
+test trace-25.9 {delete command during enter leave and leavestep traces} {
+ set info {}
+ trace add execution foo enter [list traceDelete foo]
+ trace add execution foo leave [list traceDelete foo]
+ trace add execution foo leavestep [list traceDelete foo]
+ catch {foo 1} err
+ list $err $info [catch {trace info execution foo} res] $res
+} {{invalid command name "foo"} {{foo 1} enter} 1 {unknown command "foo"}}
+
+proc foo {a} {
+ set b $a
+}
+
+test trace-25.10 {delete command during leave and leavestep traces} {
+ set info {}
+ trace add execution foo leave [list traceDelete foo]
+ trace add execution foo leavestep [list traceDelete foo]
+ catch {foo 1} err
+ list $err $info [catch {trace info execution foo} res] $res
+} {1 {{set b 1} 0 1 leavestep} 1 {unknown command "foo"}}
+
+proc foo {a} {
+ set b $a
+}
+
+test trace-25.11 {delete command during enter and enterstep traces} {
+ set info {}
+ trace add execution foo enter [list traceDelete foo]
+ trace add execution foo enterstep [list traceDelete foo]
+ catch {foo 1} err
+ list $err $info [catch {trace info execution foo} res] $res
+} {{invalid command name "foo"} {{foo 1} enter} 1 {unknown command "foo"}}
+
+test trace-26.1 {trace targetCmd when invoked through an alias} {
+ proc foo {args} {
+ set b $args
+ }
+ set info {}
+ trace add execution foo enter [list traceExecute foo]
+ interp alias {} bar {} foo 1
+ bar 2
+ trace remove execution foo enter [list traceExecute foo]
+ set info
+} {{foo {foo 1 2} enter}}
+test trace-26.2 {trace targetCmd when invoked through an alias} {
+ proc foo {args} {
+ set b $args
+ }
+ set info {}
+ trace add execution foo enter [list traceExecute foo]
+ interp create child
+ interp alias child bar {} foo 1
+ child eval bar 2
+ interp delete child
+ trace remove execution foo enter [list traceExecute foo]
+ set info
+} {{foo {foo 1 2} enter}}
+
+test trace-27.1 {memory leak in rename trace (604609)} {
+ catch {rename bar {}}
+ proc foo {} {error foo}
+ trace add command foo rename {rename foo "" ;#}
+ rename foo bar
+ info commands foo
+} {}
+
+test trace-27.2 {command trace remove nonsense} {
+ list [catch {trace remove command thisdoesntexist \
+ {delete rename} bar} res] $res
+} {1 {unknown command "thisdoesntexist"}}
+
+test trace-27.3 {command trace info nonsense} {
+ list [catch {trace info command thisdoesntexist} res] $res
+} {1 {unknown command "thisdoesntexist"}}
+
+
+test trace-28.1 {enterstep and leavestep traces with update idletasks (615043)} {
+ catch {rename foo {}}
+ proc foo {} {
+ set a 1
+ update idletasks
+ set b 1
+ }
+
+ set info {}
+ trace add execution foo {enter enterstep leavestep leave} \
+ [list traceExecute foo]
+ update
+ after idle {set a "idle"}
+ foo
+
+ trace remove execution foo {enter enterstep leavestep leave} \
+ [list traceExecute foo]
+ rename foo {}
+ catch {unset a}
+ join $info "\n"
+} {foo foo enter
+foo {set a 1} enterstep
+foo {set a 1} 0 1 leavestep
+foo {update idletasks} enterstep
+foo {set a idle} enterstep
+foo {set a idle} 0 idle leavestep
+foo {update idletasks} 0 {} leavestep
+foo {set b 1} enterstep
+foo {set b 1} 0 1 leavestep
+foo foo 0 1 leave}
+
+test trace-28.2 {exec traces with 'error'} {
+ set info {}
+ set res {}
+
+ proc foo {} {
+ if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }
+ }
+
+ proc bar {} { error "msg" }
+
+ lappend res [foo]
+
+ trace add execution foo {enter enterstep leave leavestep} \
+ [list traceExecute foo]
+
+ # With the trace active
+
+ lappend res [foo]
+
+ trace remove execution foo {enter enterstep leave leavestep} \
+ [list traceExecute foo]
+
+ list $res [join $info \n]
+} {{error error} {foo foo enter
+foo {if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }} enterstep
+foo {catch bar} enterstep
+foo bar enterstep
+foo {error msg} enterstep
+foo {error msg} 1 msg leavestep
+foo bar 1 msg leavestep
+foo {catch bar} 0 1 leavestep
+foo {return error} enterstep
+foo {return error} 2 error leavestep
+foo {if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }} 2 error leavestep
+foo foo 0 error leave}}
+
+test trace-28.3 {exec traces with 'return -code error'} {
+ set info {}
+ set res {}
+
+ proc foo {} {
+ if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }
+ }
+
+ proc bar {} { return -code error "msg" }
+
+ lappend res [foo]
+
+ trace add execution foo {enter enterstep leave leavestep} \
+ [list traceExecute foo]
+
+ # With the trace active
+
+ lappend res [foo]
+
+ trace remove execution foo {enter enterstep leave leavestep} \
+ [list traceExecute foo]
+
+ list $res [join $info \n]
+} {{error error} {foo foo enter
+foo {if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }} enterstep
+foo {catch bar} enterstep
+foo bar enterstep
+foo {return -code error msg} enterstep
+foo {return -code error msg} 2 msg leavestep
+foo bar 1 msg leavestep
+foo {catch bar} 0 1 leavestep
+foo {return error} enterstep
+foo {return error} 2 error leavestep
+foo {if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }} 2 error leavestep
+foo foo 0 error leave}}
+
+test trace-28.4 {exec traces in slave with 'return -code error'} {
+ interp create slave
+ interp alias slave traceExecute {} traceExecute
+ set info {}
+ set res [interp eval slave {
+ set info {}
+ set res {}
+
+ proc foo {} {
+ if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }
+ }
+
+ proc bar {} { return -code error "msg" }
+
+ lappend res [foo]
+
+ trace add execution foo {enter enterstep leave leavestep} \
+ [list traceExecute foo]
+
+ # With the trace active
+
+ lappend res [foo]
+
+ trace remove execution foo {enter enterstep leave leavestep} \
+ [list traceExecute foo]
+
+ list $res
+ }]
+ interp delete slave
+ lappend res [join $info \n]
+} {{error error} {foo foo enter
+foo {if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }} enterstep
+foo {catch bar} enterstep
+foo bar enterstep
+foo {return -code error msg} enterstep
+foo {return -code error msg} 2 msg leavestep
+foo bar 1 msg leavestep
+foo {catch bar} 0 1 leavestep
+foo {return error} enterstep
+foo {return error} 2 error leavestep
+foo {if {[catch {bar}]} {
+ return "error"
+ } else {
+ return "ok"
+ }} 2 error leavestep
+foo foo 0 error leave}}
+
+test trace-28.5 {exec traces} {
+ set info {}
+ proc foo {args} { set a 1 }
+ trace add execution foo {enter enterstep leave leavestep} \
+ [list traceExecute foo]
+ after idle [list foo test-28.4]
+ update
+ # Complicated way of removing traces
+ set ti [lindex [eval [list trace info execution ::foo]] 0]
+ if {[llength $ti]} {
+ eval [concat [list trace remove execution foo] $ti]
+ }
+ join $info \n
+} {foo {foo test-28.4} enter
+foo {set a 1} enterstep
+foo {set a 1} 0 1 leavestep
+foo {foo test-28.4} 0 1 leave}
+
+test trace-28.6 {exec traces firing order} {
+ set info {}
+ proc enterStep {cmd op} {lappend ::info "enter $cmd/$op"}
+ proc leaveStep {cmd code result op} {lappend ::info "leave $cmd/$code/$result/$op"}
+
+ proc foo x {
+ set b x=$x
+ incr x
+ }
+ trace add execution foo enterstep enterStep
+ trace add execution foo leavestep leaveStep
+ foo 42
+ rename foo {}
+ join $info \n
+} {enter set b x=42/enterstep
+leave set b x=42/0/x=42/leavestep
+enter incr x/enterstep
+leave incr x/0/43/leavestep}
+
+test trace-28.7 {exec trace information} {
+ set info {}
+ proc foo x { incr x }
+ proc bar {args} {}
+ trace add execution foo {enter leave enterstep leavestep} bar
+ set info [trace info execution foo]
+ trace remove execution foo {enter leave enterstep leavestep} bar
+} {}
+
+test trace-28.8 {exec trace remove nonsense} {
+ list [catch {trace remove execution thisdoesntexist \
+ {enter leave enterstep leavestep} bar} res] $res
+} {1 {unknown command "thisdoesntexist"}}
+
+test trace-28.9 {exec trace info nonsense} {
+ list [catch {trace info execution thisdoesntexist} res] $res
+} {1 {unknown command "thisdoesntexist"}}
+
+test trace-28.10 {exec trace info nonsense} {
+ list [catch {trace remove execution} res] $res
+} {1 {wrong # args: should be "trace remove execution name opList command"}}
+
+test trace-29.1 {Tcl_CreateTrace, correct command and argc/argv arguments of trace proc} {testcmdtrace} {
+ testcmdtrace tracetest {set stuff [expr 14 + 16]}
+} {{expr 14 + 16} {expr 14 + 16} {set stuff [expr 14 + 16]} {set stuff 30}}
+test trace-29.2 {Tcl_CreateTrace, correct command and argc/argv arguments of trace proc} {testcmdtrace} {
+ testcmdtrace tracetest {set stuff [info tclversion]}
+} [concat {{info tclversion} {info tclversion} ::tcl::info::tclversion {::tcl::info::tclversion} {set stuff [info tclversion]}} [list "set stuff [info tclversion]"]]
+test trace-29.3 {Tcl_CreateTrace, correct command and argc/argv arguments of trace proc} {testcmdtrace} {
+ testcmdtrace deletetest {set stuff [info tclversion]}
+} [info tclversion]
+test trace-29.4 {Tcl_CreateTrace, check that tracing doesn't cause memory faults} {testcmdtrace} {
+ # Note that the proc call is the same as the variable name, and that
+ # the call can be direct or indirect by way of another procedure
+ proc tracer {args} {}
+ proc tracedLoop {level} {
+ incr level
+ tracer
+ foreach tracer [expr {$level==1 ? {1 2} : {}}] {tracedLoop $level}
+ }
+ testcmdtrace tracetest {tracedLoop 0}
+} {{tracedLoop 0} {tracedLoop 0} {incr level} {incr level} tracer {tracer} {expr {$level==1 ? {1 2} : {}}} {expr {$level==1 ? {1 2} : {}}} {foreach tracer [expr {$level==1 ? {1 2} : {}}] {tracedLoop $level}} {foreach tracer {1 2} {tracedLoop $level}} {tracedLoop $level} {tracedLoop 1} {incr level} {incr level} tracer {tracer} {expr {$level==1 ? {1 2} : {}}} {expr {$level==1 ? {1 2} : {}}} {foreach tracer [expr {$level==1 ? {1 2} : {}}] {tracedLoop $level}} {foreach tracer {} {tracedLoop $level}} {tracedLoop $level} {tracedLoop 1} {incr level} {incr level} tracer {tracer} {expr {$level==1 ? {1 2} : {}}} {expr {$level==1 ? {1 2} : {}}} {foreach tracer [expr {$level==1 ? {1 2} : {}}] {tracedLoop $level}} {foreach tracer {} {tracedLoop $level}}}
+catch {rename tracer {}}
+catch {rename tracedLoop {}}
+
+test trace-29.5 {Tcl_CreateObjTrace, status return TCL_ERROR} {testcmdtrace} {
+ proc Error { args } { error "Shouldn't get here" }
+ set x 1;
+ list [catch {testcmdtrace resulttest {Error $x}} result] [set result]
+} {1 {Error $x}}
+
+test trace-29.6 {Tcl_CreateObjTrace, status return TCL_RETURN} {testcmdtrace} {
+ proc Return { args } { error "Shouldn't get here" }
+ set x 1;
+ list [catch {testcmdtrace resulttest {Return $x}} result] [set result]
+} {2 {}}
+
+test trace-29.7 {Tcl_CreateObjTrace, status return TCL_BREAK} {testcmdtrace} {
+ proc Break { args } { error "Shouldn't get here" }
+ set x 1;
+ list [catch {testcmdtrace resulttest {Break $x}} result] [set result]
+} {3 {}}
+
+test trace-29.8 {Tcl_CreateObjTrace, status return TCL_CONTINUE} {testcmdtrace} {
+ proc Continue { args } { error "Shouldn't get here" }
+ set x 1;
+ list [catch {testcmdtrace resulttest {Continue $x}} result] [set result]
+} {4 {}}
+
+test trace-29.9 {Tcl_CreateObjTrace, status return unknown} {testcmdtrace} {
+ proc OtherStatus { args } { error "Shouldn't get here" }
+ set x 1;
+ list [catch {testcmdtrace resulttest {OtherStatus $x}} result] [set result]
+} {6 {}}
+
+test trace-29.10 {Tcl_CreateTrace, correct level interpretation} {testcmdtrace} {
+ proc foo {} {uplevel 1 bar}
+ proc bar {} {uplevel 1 grok}
+ proc grok {} {uplevel 1 spock}
+ proc spock {} {uplevel 1 fascinating}
+ proc fascinating {} {}
+ testcmdtrace leveltest {foo}
+} {foo {foo} {uplevel 1 bar} {uplevel 1 bar} bar {bar} {uplevel 1 grok} {uplevel 1 grok}}
+
+test trace-29.11 {Tcl_CreateTrace, multiple traces} {testcmdtrace} {
+ testcmdtrace doubletest {format xx}
+} {{format xx} {format xx}}
+
+test trace-30.1 {Tcl_DeleteTrace} {emptyTest} {
+ # the above tests have tested Tcl_DeleteTrace
+} {}
+
+test trace-31.1 {command and execution traces shared struct} {
+ # Tcl Bug 807243
+ proc foo {} {}
+ trace add command foo delete foo
+ trace add execution foo enter foo
+ set result [trace info command foo]
+ trace remove command foo delete foo
+ trace remove execution foo enter foo
+ rename foo {}
+ set result
+} [list [list delete foo]]
+test trace-31.2 {command and execution traces shared struct} {
+ # Tcl Bug 807243
+ proc foo {} {}
+ trace add command foo delete foo
+ trace add execution foo enter foo
+ set result [trace info execution foo]
+ trace remove command foo delete foo
+ trace remove execution foo enter foo
+ rename foo {}
+ set result
+} [list [list enter foo]]
+
+test trace-32.1 {
+ TraceCommandInfo refcount decr in TraceCommandProc w/o loss of reference
+} {
+ # Tcl Bug 811483
+ proc foo {} {}
+ trace add command foo delete foo
+ trace add execution foo enter foo
+ set result [trace info command foo]
+ rename foo {}
+ set result
+} [list [list delete foo]]
+
+test trace-33.1 {variable match with remove variable} {
+ unset -nocomplain x
+ trace variable x w foo
+ trace remove variable x write foo
+ llength [trace info variable x]
+} 0
+
+test trace-34.1 {Bug 1201035} {
+ set ::x [list]
+ proc foo {} {lappend ::x foo}
+ proc bar args {
+ lappend ::x $args
+ trace remove execution foo leavestep bar
+ trace remove execution foo enterstep bar
+ trace add execution foo leavestep bar
+ trace add execution foo enterstep bar
+ lappend ::x done
+ }
+ trace add execution foo leavestep bar
+ trace add execution foo enterstep bar
+ foo
+ set ::x
+} {{{lappend ::x foo} enterstep} done foo}
+
+test trace-34.2 {Bug 1224585} {
+ proc foo {} {}
+ proc bar args {trace remove execution foo leave soom}
+ trace add execution foo leave bar
+ trace add execution foo leave soom
+ foo
+} {}
+
+test trace-34.3 {Bug 1224585} {
+ proc foo {} {set x {}}
+ proc bar args {trace remove execution foo enterstep soom}
+ trace add execution foo enterstep soom
+ trace add execution foo enterstep bar
+ foo
+} {}
+
+# We test here for the half-documented and currently valid interplay between
+# delete traces and namespace deletion.
+test trace-34.4 {Bug 1047286} {
+ variable x notrace
+ proc callback {old - -} {
+ variable x "$old exists: [namespace which -command $old]"
+ }
+ namespace eval ::foo {proc bar {} {}}
+ trace add command ::foo::bar delete [namespace code callback]
+ namespace delete ::foo
+ set x
+} {::foo::bar exists: ::foo::bar}
+
+test trace-34.5 {Bug 1047286} {
+ variable x notrace
+ proc callback {old - -} {
+ variable x "$old exists: [namespace which -command $old]"
+ }
+ namespace eval ::foo {proc bar {} {}}
+ trace add command ::foo::bar delete [namespace code callback]
+ namespace eval ::foo namespace delete ::foo
+ set x
+} {::foo::bar exists: }
+
+test trace-34.6 {Bug 1458266} -setup {
+ proc dummy {} {}
+ proc stepTraceHandler {cmdString args} {
+ variable log
+ append log "[expr {[info level] - 1}]: [lindex [split $cmdString] 0]\n"
+ dummy
+ isTracedInside_2
+ }
+ proc cmdTraceHandler {cmdString args} {
+ # silent
+ }
+ proc isTracedInside_1 {} {
+ isTracedInside_2
+ }
+ proc isTracedInside_2 {} {
+ set x 2
+ }
+} -body {
+ variable log {}
+ trace add execution isTracedInside_1 enterstep stepTraceHandler
+ trace add execution isTracedInside_2 enterstep stepTraceHandler
+ isTracedInside_1
+ variable first $log
+ set log {}
+ trace add execution dummy enter cmdTraceHandler
+ isTracedInside_1
+ variable second $log
+ expr {($first eq $second) ? "ok" : "\n$first\nand\n\n$second\ndiffer"}
+} -cleanup {
+ unset -nocomplain log first second
+ rename dummy {}
+ rename stepTraceHandler {}
+ rename cmdTraceHandler {}
+ rename isTracedInside_1 {}
+ rename isTracedInside_2 {}
+} -result ok
+
+test trace-35.1 {527164: Keep -errorinfo of traces} -setup {
+ unset -nocomplain x y
+} -body {
+ trace add variable x write {error foo;#}
+ trace add variable y write {set x 2;#}
+ list [catch {set y 1} msg opts] $msg [dict get $opts -errorinfo]
+} -cleanup {
+ unset -nocomplain x y
+} -result {1 {can't set "y": can't set "x": foo} {foo
+ while executing
+"error foo"
+ (write trace on "x")
+ invoked from within
+"set x 2"
+ (write trace on "y")
+ invoked from within
+"set y 1"}}
+
+
+#
+# Test for the correct(?) dynamics of execution traces. This test insures that
+# the dynamics of the original implementation remain valid; note that
+# these aspects are neither documented nor do they appear in TIP 62
+
+proc traceproc {tracevar args} {
+ append ::$tracevar *
+}
+proc untraced {type} {
+ trace add execution untraced $type {traceproc tracevar}
+ append ::tracevar -
+}
+proc runbase {results base} {
+ set tt {enter leave enterstep leavestep}
+ foreach n {1 2 3 4} t $tt r $results {
+ eval [subst $base]
+ }
+}
+set base {
+ test trace-36.$n {dynamic trace creation: $t} -setup {
+ set ::tracevar {}
+ } -cleanup {
+ unset ::tracevar
+ trace remove execution untraced $t {traceproc tracevar}
+ } -body {
+ untraced $t
+ set ::tracevar
+ } -result {$r}
+}
+runbase {- - - -} $base
+
+set base {
+ test trace-37.$n {dynamic trace addition: $t} -setup {
+ set ::tracevar {}
+ set ::tracevar2 {}
+ trace add execution untraced enter {traceproc tracevar2}
+ } -cleanup {
+ trace remove execution untraced $t {traceproc tracevar}
+ trace remove execution untraced enter {traceproc tracevar2}
+ unset ::tracevar ::tracevar2
+ } -body {
+ untraced $t
+ list \$::tracevar \$::tracevar2
+ } -result {$r}
+}
+runbase {{- *} {-* *} {- *} {- *}} $base
+
+set base {
+ test trace-38.$n {dynamic trace addition: $t} -setup {
+ set ::tracevar {}
+ set ::tracevar2 {}
+ trace add execution untraced leave {traceproc tracevar2}
+ } -cleanup {
+ trace remove execution untraced $t {traceproc tracevar}
+ trace remove execution untraced leave {traceproc tracevar2}
+ unset ::tracevar ::tracevar2
+ } -body {
+ untraced $t
+ list \$::tracevar \$::tracevar2
+ } -result {$r}
+}
+runbase {{- *} {-* *} {- *} {- *}} $base
+
+test trace-39 {bug #3484621: tracing Bc'ed commands} -setup {
+ set ::traceLog 0
+ set ::traceCalls 0
+ set ::bar [list 0 1 2 3]
+ set res {}
+ proc dotrace args {
+ incr ::traceLog
+ }
+ proc foo {} {
+ incr ::traceCalls
+ # choose a BC'ed command that is 'unlikely' to interfere with tcltest's
+ # internals
+ lset ::bar 1 2
+ }
+} -body {
+ foo
+ lappend res $::traceLog
+
+ trace add execution lset enter dotrace
+ foo
+ lappend res $::traceLog
+
+ trace remove execution lset enter dotrace
+ foo
+ lappend res $::traceLog
+
+ list $::traceCalls | {*}$res
+} -cleanup {
+ unset ::traceLog ::traceCalls ::bar res
+ rename dotrace {}
+ rename foo {}
+} -result {3 | 0 1 1}
+
+test trace-39.1 {bug #3485022: tracing Bc'ed commands} -setup {
+ set ::traceLog 0
+ set ::traceCalls 0
+ set res {}
+ proc dotrace args {
+ incr ::traceLog
+ }
+ proc foo {} {
+ incr ::traceCalls
+ string equal zip zap
+ }
+} -body {
+ foo
+ lappend res $::traceLog
+
+ trace add execution ::tcl::string::equal enter dotrace
+ foo
+ lappend res $::traceLog
+
+ trace remove execution tcl::string::equal enter dotrace
+ foo
+ lappend res $::traceLog
+
+ list $::traceCalls | {*}$res
+} -cleanup {
+ unset ::traceLog ::traceCalls res
+ rename dotrace {}
+ rename foo {}
+} -result {3 | 0 1 1}
+
+# Delete procedures when done, so we don't clash with other tests
+# (e.g. foobar will clash with 'unknown' tests).
+catch {rename foobar {}}
+catch {rename foo {}}
+catch {rename bar {}}
+catch {rename untraced {}}
+catch {rename traceproc {}}
+catch {rename runbase {}}
+
+# Unset the variable when done
+catch {unset info}
+catch {unset base}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/unixFCmd.test b/pkgs/msgcat/tests/unixFCmd.test
new file mode 100644
index 0000000..e8148e9
--- /dev/null
+++ b/pkgs/msgcat/tests/unixFCmd.test
@@ -0,0 +1,437 @@
+# This file tests the tclUnixFCmd.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testchmod [llength [info commands testchmod]]
+
+# These tests really need to be run from a writable directory, which
+# it is assumed [temporaryDirectory] is.
+set oldcwd [pwd]
+cd [temporaryDirectory]
+
+# Several tests require need to match results against the unix username
+set user {}
+if {[testConstraint unix]} {
+ catch {set user [exec whoami]}
+ if {$user == ""} {
+ catch {regexp {^[^(]*\(([^)]*)\)} [exec id] dummy user}
+ }
+ if {$user == ""} {
+ set user "root"
+ }
+}
+
+# Find a group that exists on this system, or else skip tests that require
+# groups
+testConstraint foundGroup 0
+if {[testConstraint unix]} {
+ catch {
+ set groupList [exec groups]
+ set group [lindex $groupList 0]
+ testConstraint foundGroup 1
+ }
+}
+
+# check whether -readonly attribute is supported
+testConstraint readonlyAttr 0
+if {[testConstraint unix]} {
+ set f [makeFile "whatever" probe]
+ catch {
+ file attributes $f -readonly
+ testConstraint readonlyAttr 1
+ }
+ removeFile probe
+}
+
+proc openup {path} {
+ testchmod 777 $path
+ if {[file isdirectory $path]} {
+ catch {
+ foreach p [glob -directory $path *] {
+ openup $p
+ }
+ }
+ }
+}
+
+proc cleanup {args} {
+ foreach p ". $args" {
+ set x ""
+ catch {
+ set x [glob -directory $p tf* td*]
+ }
+ foreach file $x {
+ if {
+ [catch {file delete -force -- $file}]
+ && [testConstraint testchmod]
+ } then {
+ openup $file
+ file delete -force -- $file
+ }
+ }
+ }
+}
+
+if {[testConstraint unix] && [testConstraint notRoot]} {
+ testConstraint execMknod [expr {![catch {exec mknod tf1 p}]}]
+ cleanup
+}
+
+test unixFCmd-1.1 {TclpRenameFile: EACCES} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir td1/td2/td3
+ file attributes td1/td2 -permissions 0000
+ file rename td1/td2/td3 td2
+} -returnCodes error -cleanup {
+ file attributes td1/td2 -permissions 0755
+ cleanup
+} -result {error renaming "td1/td2/td3": permission denied}
+test unixFCmd-1.2 {TclpRenameFile: EEXIST} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir td1/td2
+ file mkdir td2
+ file rename td2 td1
+} -returnCodes error -cleanup {
+ cleanup
+} -result {error renaming "td2" to "td1/td2": file already exists}
+test unixFCmd-1.3 {TclpRenameFile: EINVAL} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir td1
+ file rename td1 td1
+} -returnCodes error -cleanup {
+ cleanup
+} -result {error renaming "td1" to "td1/td1": trying to rename a volume or move a directory into itself}
+test unixFCmd-1.4 {TclpRenameFile: EISDIR} {emptyTest unix notRoot} {
+ # can't make it happen
+} {}
+test unixFCmd-1.5 {TclpRenameFile: ENOENT} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir td1
+ file rename td2 td1
+} -returnCodes error -cleanup {
+ cleanup
+} -result {error renaming "td2": no such file or directory}
+test unixFCmd-1.6 {TclpRenameFile: ENOTDIR} {emptyTest unix notRoot} {
+ # can't make it happen
+} {}
+test unixFCmd-1.7 {TclpRenameFile: EXDEV} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ file mkdir foo/bar
+ file attr foo -perm 040555
+ file rename foo/bar /tmp
+} -returnCodes error -cleanup {
+ catch {file delete /tmp/bar}
+ catch {file attr foo -perm 040777}
+ catch {file delete -force foo}
+} -match glob -result {*: permission denied}
+test unixFCmd-1.8 {Checking EINTR Bug} {unix notRoot nonPortable} {
+ testalarm
+ after 2000
+ list [testgotsig] [testgotsig]
+} {1 0}
+test unixFCmd-1.9 {Checking EINTR Bug} -constraints {unix notRoot nonPortable} -setup {
+ cleanup
+ set f [open tfalarm w]
+ puts $f {
+ after 2000
+ puts "hello world"
+ exit 0
+ }
+ close $f
+} -body {
+ testalarm
+ set pipe [open "|[info nameofexecutable] tfalarm" r+]
+ set line [read $pipe 1]
+ catch {close $pipe}
+ list $line [testgotsig]
+} -cleanup {
+ cleanup
+} -result {h 1}
+
+test unixFCmd-2.1 {TclpCopyFile: target exists: lstat(dst) == 0} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ close [open tf1 a]
+ close [open tf2 a]
+ file copy -force tf1 tf2
+} -cleanup {
+ cleanup
+} -result {}
+test unixFCmd-2.2.1 {TclpCopyFile: src is symlink} -setup {
+ cleanup
+} -constraints {unix notRoot dontCopyLinks} -body {
+ # copying links should end up with real files
+ close [open tf1 a]
+ file link -symbolic tf2 tf1
+ file copy tf2 tf3
+ file type tf3
+} -cleanup {
+ cleanup
+} -result file
+test unixFCmd-2.2.2 {TclpCopyFile: src is symlink} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ # copying links should end up with the links copied
+ close [open tf1 a]
+ file link -symbolic tf2 tf1
+ file copy tf2 tf3
+ file type tf3
+} -cleanup {
+ cleanup
+} -result link
+test unixFCmd-2.3 {TclpCopyFile: src is block} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ set null "/dev/null"
+ while {[file type $null] != "characterSpecial"} {
+ set null [file join [file dirname $null] [file readlink $null]]
+ }
+ # file copy $null tf1
+} -result {}
+test unixFCmd-2.4 {TclpCopyFile: src is fifo} -setup {
+ cleanup
+} -constraints {unix notRoot execMknod} -body {
+ exec mknod tf1 p
+ file copy tf1 tf2
+ list [file type tf1] [file type tf2]
+} -cleanup {
+ cleanup
+} -result {fifo fifo}
+test unixFCmd-2.5 {TclpCopyFile: copy attributes} -setup {
+ cleanup
+} -constraints {unix notRoot} -body {
+ close [open tf1 a]
+ file attributes tf1 -permissions 0472
+ file copy tf1 tf2
+ file attributes tf2 -permissions
+} -cleanup {
+ cleanup
+} -result 00472 ;# i.e. perms field of [exec ls -l tf2] is -r--rwx-w-
+
+test unixFCmd-3.1 {CopyFile not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-4.1 {TclpDeleteFile not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-5.1 {TclpCreateDirectory not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-6.1 {TclpCopyDirectory not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-7.1 {TclpRemoveDirectory not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-8.1 {TraverseUnixTree not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-9.1 {TraversalCopy not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-10.1 {TraversalDelete not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-11.1 {CopyFileAttrs not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-12.1 {GetGroupAttribute - file not found} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+ file attributes foo.test -group
+} -result {could not read "foo.test": no such file or directory}
+test unixFCmd-12.2 {GetGroupAttribute - file found} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+ close [open foo.test w]
+ file attributes foo.test -group
+} -cleanup {
+ file delete -force -- foo.test
+} -match glob -result *
+
+test unixFCmd-13.1 {GetOwnerAttribute - file not found} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+ file attributes foo.test -group
+} -result {could not read "foo.test": no such file or directory}
+test unixFCmd-13.2 {GetOwnerAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+ close [open foo.test w]
+ file attributes foo.test -owner
+} -cleanup {
+ file delete -force -- foo.test
+} -result $user
+
+test unixFCmd-14.1 {GetPermissionsAttribute - file not found} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+ file attributes foo.test -permissions
+} -result {could not read "foo.test": no such file or directory}
+test unixFCmd-14.2 {GetPermissionsAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+ close [open foo.test w]
+ file attribute foo.test -permissions
+} -cleanup {
+ file delete -force -- foo.test
+} -match glob -result *
+
+#groups hard to test
+test unixFCmd-15.1 {SetGroupAttribute - invalid group} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+ file attributes foo.test -group foozzz
+} -returnCodes error -cleanup {
+ file delete -force -- foo.test
+} -result {could not set group for file "foo.test": group "foozzz" does not exist}
+test unixFCmd-15.2 {SetGroupAttribute - invalid file} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot foundGroup} -returnCodes error -body {
+ file attributes foo.test -group $group
+} -result {could not set group for file "foo.test": no such file or directory}
+
+#changing owners hard to do
+test unixFCmd-16.1 {SetOwnerAttribute - current owner} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+ close [open foo.test w]
+ list [file attributes foo.test -owner $user] \
+ [file attributes foo.test -owner]
+} -cleanup {
+ file delete -force -- foo.test
+} -result [list {} $user]
+test unixFCmd-16.2 {SetOwnerAttribute - invalid file} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+ file attributes foo.test -owner $user
+} -result {could not set owner for file "foo.test": no such file or directory}
+test unixFCmd-16.3 {SetOwnerAttribute - invalid owner} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+ file attributes foo.test -owner foozzz
+} -result {could not set owner for file "foo.test": user "foozzz" does not exist}
+
+test unixFCmd-17.1 {SetPermissionsAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+ close [open foo.test w]
+ list [file attributes foo.test -permissions 0000] \
+ [file attributes foo.test -permissions]
+} -cleanup {
+ file delete -force -- foo.test
+} -result {{} 00000}
+test unixFCmd-17.2 {SetPermissionsAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+ file attributes foo.test -permissions 0000
+} -result {could not set permissions for file "foo.test": no such file or directory}
+test unixFCmd-17.3 {SetPermissionsAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+ close [open foo.test w]
+ file attributes foo.test -permissions foo
+} -cleanup {
+ file delete -force -- foo.test
+} -returnCodes error -result {unknown permission string format "foo"}
+test unixFCmd-17.4 {SetPermissionsAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+ close [open foo.test w]
+ file attributes foo.test -permissions ---rwx
+} -cleanup {
+ file delete -force -- foo.test
+} -returnCodes error -result {unknown permission string format "---rwx"}
+
+close [open foo.test w]
+set ::i 4
+proc permcheck {testnum permstr expected} {
+ test $testnum {SetPermissionsAttribute} {unix notRoot} {
+ file attributes foo.test -permissions $permstr
+ file attributes foo.test -permissions
+ } $expected
+}
+permcheck unixFCmd-17.5 rwxrwxrwx 00777
+permcheck unixFCmd-17.6 r--r---w- 00442
+permcheck unixFCmd-17.7 0 00000
+permcheck unixFCmd-17.8 u+rwx,g+r 00740
+permcheck unixFCmd-17.9 u-w 00540
+permcheck unixFCmd-17.10 o+rwx 00547
+permcheck unixFCmd-17.11 --x--x--x 00111
+permcheck unixFCmd-17.12 a+rwx 00777
+file delete -force -- foo.test
+
+test unixFCmd-18.1 {Unix pwd} -constraints {unix notRoot nonPortable} -setup {
+ set cd [pwd]
+} -body {
+ # This test is nonportable because SunOS generates a weird error
+ # message when the current directory isn't readable.
+ set nd $cd/tstdir
+ file mkdir $nd
+ cd $nd
+ file attributes $nd -permissions 0000
+ pwd
+} -returnCodes error -cleanup {
+ cd $cd
+ file attributes $nd -permissions 0755
+ file delete $nd
+} -match glob -result {error getting working directory name:*}
+
+test unixFCmd-19.1 {GetReadOnlyAttribute - file not found} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot readonlyAttr} -returnCodes error -body {
+ file attributes foo.test -readonly
+} -result {could not read "foo.test": no such file or directory}
+test unixFCmd-19.2 {GetReadOnlyAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot readonlyAttr} -body {
+ close [open foo.test w]
+ file attribute foo.test -readonly
+} -cleanup {
+ file delete -force -- foo.test
+} -result 0
+
+test unixFCmd-20.1 {SetReadOnlyAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot readonlyAttr} -body {
+ close [open foo.test w]
+ list [catch {file attributes foo.test -readonly 1} msg] $msg \
+ [catch {file attribute foo.test -readonly} msg] $msg \
+ [catch {file delete -force -- foo.test}] \
+ [catch {file attributes foo.test -readonly 0} msg] $msg \
+ [catch {file attribute foo.test -readonly} msg] $msg
+} -cleanup {
+ file delete -force -- foo.test
+} -result {0 {} 0 1 1 0 {} 0 0}
+test unixFCmd-20.2 {SetReadOnlyAttribute} -setup {
+ catch {file delete -force -- foo.test}
+} -constraints {unix notRoot readonlyAttr} -returnCodes error -body {
+ file attributes foo.test -readonly 1
+} -result {could not read "foo.test": no such file or directory}
+
+# cleanup
+cleanup
+cd $oldcwd
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/unixFile.test b/pkgs/msgcat/tests/unixFile.test
new file mode 100644
index 0000000..0ea0ec1
--- /dev/null
+++ b/pkgs/msgcat/tests/unixFile.test
@@ -0,0 +1,62 @@
+# This file contains tests for the routines in the file tclUnixFile.c
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testfindexecutable [llength [info commands testfindexecutable]]
+
+set oldpwd [pwd]
+cd [temporaryDirectory]
+
+catch {
+ set oldPath $env(PATH)
+ file attributes [makeFile "" junk] -perm 0777
+}
+set absPath [file join [temporaryDirectory] junk]
+
+test unixFile-1.1 {Tcl_FindExecutable} {testfindexecutable unix} {
+ set env(PATH) ""
+ testfindexecutable junk
+} $absPath
+test unixFile-1.2 {Tcl_FindExecutable} {testfindexecutable unix} {
+ set env(PATH) "/dummy"
+ testfindexecutable junk
+} {}
+test unixFile-1.3 {Tcl_FindExecutable} {testfindexecutable unix} {
+ set env(PATH) "/dummy:[pwd]"
+ testfindexecutable junk
+} $absPath
+test unixFile-1.4 {Tcl_FindExecutable} {testfindexecutable unix} {
+ set env(PATH) "/dummy:"
+ testfindexecutable junk
+} $absPath
+test unixFile-1.5 {Tcl_FindExecutable} {testfindexecutable unix} {
+ set env(PATH) "/dummy:/dummy"
+ testfindexecutable junk
+} {}
+test unixFile-1.6 {Tcl_FindExecutable} {testfindexecutable unix} {
+ set env(PATH) "/dummy::/dummy"
+ testfindexecutable junk
+} $absPath
+test unixFile-1.7 {Tcl_FindExecutable} {testfindexecutable unix} {
+ set env(PATH) ":/dummy"
+ testfindexecutable junk
+} $absPath
+
+# cleanup
+catch {set env(PATH) $oldPath}
+removeFile junk
+cd $oldpwd
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/unixInit.test b/pkgs/msgcat/tests/unixInit.test
new file mode 100644
index 0000000..9ba9c11
--- /dev/null
+++ b/pkgs/msgcat/tests/unixInit.test
@@ -0,0 +1,402 @@
+# The file tests the functions in the tclUnixInit.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+package require tcltest 2.2
+namespace import -force ::tcltest::*
+unset -nocomplain path
+catch {set oldlang $env(LANG)}
+set env(LANG) C
+
+test unixInit-1.1 {TclpInitPlatform: ignore SIGPIPE} {unix stdio} {
+ set x {}
+ # Watch out for a race condition here. If tcltest is too slow to start
+ # then we'll kill it before it has a chance to set up its signal handler.
+ set f [open "|[list [interpreter]]" w+]
+ puts $f "puts hi"
+ flush $f
+ gets $f
+ exec kill -PIPE [pid $f]
+ lappend x [catch {close $f}]
+ set f [open "|[list [interpreter]]" w+]
+ puts $f "puts hi"
+ flush $f
+ gets $f
+ exec kill [pid $f]
+ lappend x [catch {close $f}]
+ set x
+} {0 1}
+# This test is really a test of code in tclUnixChan.c, but the channels are
+# set up as part of initialisation of the interpreter so the test seems to me
+# to fit here as well as anywhere else.
+test unixInit-1.2 {initialisation: standard channel type deduction} {unix stdio} {
+ # pipe1 is a connection to a server that reports what port it starts on,
+ # and delivers a constant string to the first client to connect to that
+ # port before exiting.
+ set pipe1 [open "|[list [interpreter]]" r+]
+ puts $pipe1 {
+ proc accept {channel host port} {
+ puts $channel {puts [fconfigure stdin -peername]; exit}
+ close $channel
+ exit
+ }
+ puts [fconfigure [socket -server accept -myaddr 127.0.0.1 0] -sockname]
+ vwait forever \
+ }
+ # Note the backslash above; this is important to make sure that the whole
+ # string is read before an [exit] can happen...
+ flush $pipe1
+ set port [lindex [gets $pipe1] 2]
+ set sock [socket localhost $port]
+ # pipe2 is a connection to a Tcl interpreter that takes its orders from
+ # the socket we hand it (i.e. the server we create above.) These orders
+ # will tell it to print out the details about the socket it is taking
+ # instructions from, hopefully identifying it as a socket. Which is what
+ # this test is all about.
+ set pipe2 [open "|[list [interpreter] <@$sock]" r]
+ set result [gets $pipe2]
+ # Clear any pending data; stops certain kinds of (non-important) errors
+ fconfigure $pipe1 -blocking 0; gets $pipe1
+ fconfigure $pipe2 -blocking 0; gets $pipe2
+ # Close the pipes and the socket.
+ close $pipe2
+ close $pipe1
+ catch {close $sock}
+ # Can't use normal comparison, as hostname varies due to some
+ # installations having a messed up /etc/hosts file.
+ if {
+ "127.0.0.1" eq [lindex $result 0] && $port == [lindex $result 2]
+ } then {
+ subst "OK"
+ } else {
+ subst "Expected: `[list 127.0.0.1 localhost $port]', Got `$result'"
+ }
+} {OK}
+
+# The unixInit-2.* tests were written to test the internal routine,
+# TclpInitLibraryPath. That routine no longer does the things it used to do
+# so those tests are obsolete. Skip them.
+
+skip [concat [skip] unixInit-2.*]
+
+test unixInit-2.0 {TclpInitLibraryPath: setting tclDefaultEncodingDir} {
+ set origDir [testgetdefenc]
+ testsetdefenc slappy
+ set path [testgetdefenc]
+ testsetdefenc $origDir
+ set path
+} {slappy}
+test unixInit-2.1 {TclpInitLibraryPath: value of installLib, developLib} -setup {
+ unset -nocomplain oldlibrary
+ if {[info exists env(TCL_LIBRARY)]} {
+ set oldlibrary $env(TCL_LIBRARY)
+ unset env(TCL_LIBRARY)
+ }
+} -body {
+ set path [getlibpath]
+ set installLib lib/tcl[info tclversion]
+ set developLib tcl[info patchlevel]/library
+ set prefix [file dirname [file dirname [interpreter]]]
+ list [string equal [lindex $path 0] $prefix/$installLib] \
+ [string equal [lindex $path 4] [file dirname $prefix]/$developLib]
+} -cleanup {
+ if {[info exists oldlibrary]} {
+ set env(TCL_LIBRARY) $oldlibrary
+ unset oldlibrary
+ }
+} -result {1 1}
+test unixInit-2.2 {TclpInitLibraryPath: TCL_LIBRARY} -setup {
+ unset -nocomplain oldlibrary
+ if {[info exists env(TCL_LIBRARY)]} {
+ set oldlibrary $env(TCL_LIBRARY)
+ }
+} -body {
+ # ((str != NULL) && (str[0] != '\0'))
+ set env(TCL_LIBRARY) sparkly
+ lindex [getlibpath] 0
+} -cleanup {
+ unset -nocomplain env(TCL_LIBRARY)
+ if {[info exists oldlibrary]} {
+ set env(TCL_LIBRARY) $oldlibrary
+ unset oldlibrary
+ }
+} -result "sparkly"
+test unixInit-2.3 {TclpInitLibraryPath: TCL_LIBRARY wrong version} -setup {
+ unset -nocomplain oldlibrary
+ if {[info exists env(TCL_LIBRARY)]} {
+ set oldlibrary $env(TCL_LIBRARY)
+ }
+} -body {
+ # ((pathc > 0) && (strcasecmp(installLib + 4, pathv[pathc - 1]) != 0))
+ set env(TCL_LIBRARY) /a/b/tcl1.7
+ lrange [getlibpath] 0 1
+} -cleanup {
+ unset -nocomplain env(TCL_LIBRARY)
+ if {[info exists oldlibrary]} {
+ set env(TCL_LIBRARY) $oldlibrary
+ unset oldlibrary
+ }
+} -result [list /a/b/tcl1.7 /a/b/tcl[info tclversion]]
+test unixInit-2.4 {TclpInitLibraryPath: TCL_LIBRARY: INTL} -setup {
+ if {[info exists env(TCL_LIBRARY)]} {
+ set oldlibrary $env(TCL_LIBRARY)
+ }
+} -body {
+ # Child process translates env variable from native encoding.
+ set env(TCL_LIBRARY) "\xa7"
+ lindex [getlibpath] 0
+} -cleanup {
+ unset -nocomplain env(TCL_LIBRARY) env(LANG)
+ if {[info exists oldlibrary]} {
+ set env(TCL_LIBRARY) $oldlibrary
+ unset oldlibrary
+ }
+} -result "\xa7"
+test unixInit-2.5 {TclpInitLibraryPath: compiled-in library path} {
+ # cannot test
+} {}
+test unixInit-2.6 {TclpInitLibraryPath: executable relative} -setup {
+ unset -nocomplain oldlibrary
+ if {[info exists env(TCL_LIBRARY)]} {
+ set oldlibrary $env(TCL_LIBRARY)
+ }
+ set env(TCL_LIBRARY) [info library]
+ makeDirectory tmp
+ makeDirectory [file join tmp sparkly]
+ makeDirectory [file join tmp sparkly bin]
+ file copy [interpreter] [file join [temporaryDirectory] tmp sparkly \
+ bin tcltest]
+ makeDirectory [file join tmp sparkly lib]
+ makeDirectory [file join tmp sparkly lib tcl[info tclversion]]
+ makeFile {} [file join tmp sparkly lib tcl[info tclversion] init.tcl]
+} -body {
+ lrange [getlibpath [file join [temporaryDirectory] tmp sparkly \
+ bin tcltest]] 1 2
+} -cleanup {
+ removeFile [file join tmp sparkly lib tcl[info tclversion] init.tcl]
+ removeDirectory [file join tmp sparkly lib tcl[info tclversion]]
+ removeDirectory [file join tmp sparkly lib]
+ removeDirectory [file join tmp sparkly bin]
+ removeDirectory [file join tmp sparkly]
+ removeDirectory tmp
+ unset env(TCL_LIBRARY)
+ if {[info exists oldlibrary]} {
+ set env(TCL_LIBRARY) $oldlibrary
+ unset oldlibrary
+ }
+} -result [list [temporaryDirectory]/tmp/sparkly/lib/tcl[info tclversion] [temporaryDirectory]/tmp/lib/tcl[info tclversion]]
+test unixInit-2.7 {TclpInitLibraryPath: compiled-in library path} {
+ # would need test command to get defaultLibDir and compare it to
+ # [lindex $auto_path end]
+} {}
+#
+# The following two tests write to the directory /tmp/sparkly instead of to
+# [temporaryDirectory]. This is because the failures tested by these tests
+# need paths near the "root" of the file system to present themselves.
+#
+test unixInit-2.8 {TclpInitLibraryPath: all absolute pathtype} -setup {
+ unset -nocomplain oldlibrary
+ if {[info exists env(TCL_LIBRARY)]} {
+ set oldlibrary $env(TCL_LIBRARY)
+ }
+ set env(TCL_LIBRARY) [info library]
+ # Checking for Bug 219416
+ # When a program that embeds the Tcl library, like tcltest, is installed
+ # near the "root" of the file system, there was a problem constructing
+ # directories relative to the executable. When a relative ".." went past
+ # the root, relative path names were created rather than absolute
+ # pathnames. In some cases, accessing past the root caused memory access
+ # violations too.
+ #
+ # The bug is now fixed, but here we check for it by making sure that the
+ # directories constructed relative to the executable are all absolute
+ # pathnames, even when the executable is installed near the root of the
+ # filesystem.
+ #
+ # The only directory near the root we are likely to have write access to
+ # is /tmp.
+ file delete -force /tmp/sparkly
+ file delete -force /tmp/lib/tcl[info tclversion]
+ file mkdir /tmp/sparkly
+ file copy [interpreter] /tmp/sparkly/tcltest
+ # Keep any existing /tmp/lib directory
+ set deletelib 1
+ if {[file exists /tmp/lib]} {
+ if {[file isdirectory /tmp/lib]} {
+ set deletelib 0
+ } else {
+ file delete -force /tmp/lib
+ }
+ }
+ # For a successful Tcl_Init, we need a [source]-able init.tcl in
+ # ../lib/tcl$version relative to the executable.
+ file mkdir /tmp/lib/tcl[info tclversion]
+ close [open /tmp/lib/tcl[info tclversion]/init.tcl w]
+} -body {
+ # Check that all directories in the library path are absolute pathnames
+ set allAbsolute 1
+ foreach dir [getlibpath /tmp/sparkly/tcltest] {
+ set allAbsolute [expr {$allAbsolute \
+ && [string equal absolute [file pathtype $dir]]}]
+ }
+ set allAbsolute
+} -cleanup {
+ # Clean up temporary installation
+ file delete -force /tmp/sparkly
+ file delete -force /tmp/lib/tcl[info tclversion]
+ if {$deletelib} {file delete -force /tmp/lib}
+ unset env(TCL_LIBRARY)
+ if {[info exists oldlibrary]} {
+ set env(TCL_LIBRARY) $oldlibrary
+ unset oldlibrary
+ }
+} -result 1
+test unixInit-2.9 {TclpInitLibraryPath: paths relative to executable} -setup {
+ # Checking for Bug 438014
+ unset -nocomplain oldlibrary
+ if {[info exists env(TCL_LIBRARY)]} {
+ set oldlibrary $env(TCL_LIBRARY)
+ }
+ set env(TCL_LIBRARY) [info library]
+ file delete -force /tmp/sparkly
+ file delete -force /tmp/library
+ file mkdir /tmp/sparkly
+ file copy [interpreter] /tmp/sparkly/tcltest
+ file mkdir /tmp/library/
+ close [open /tmp/library/init.tcl w]
+} -body {
+ lrange [getlibpath /tmp/sparkly/tcltest] 1 5
+} -cleanup {
+ file delete -force /tmp/sparkly
+ file delete -force /tmp/library
+ unset env(TCL_LIBRARY)
+ if {[info exists oldlibrary]} {
+ set env(TCL_LIBRARY) $oldlibrary
+ unset oldlibrary
+ }
+} -result [list /tmp/lib/tcl[info tclversion] /lib/tcl[info tclversion] \
+ /tmp/library /library /tcl[info patchlevel]/library]
+test unixInit-2.10 {TclpInitLibraryPath: executable relative} -setup {
+ unset -nocomplain oldlibrary
+ if {[info exists env(TCL_LIBRARY)]} {
+ set oldlibrary $env(TCL_LIBRARY)
+ }
+ set env(TCL_LIBRARY) [info library]
+ set tmpDir [makeDirectory tmp]
+ set sparklyDir [makeDirectory sparkly $tmpDir]
+ set execPath [file join [makeDirectory bin $sparklyDir] tcltest]
+ file copy [interpreter] $execPath
+ set libDir [makeDirectory lib $sparklyDir]
+ set scriptDir [makeDirectory tcl[info tclversion] $libDir]
+ makeFile {} init.tcl $scriptDir
+ set saveDir [pwd]
+ cd $libDir
+} -body {
+ # Checking for Bug 832657
+ set x [lrange [getlibpath [file join .. bin tcltest]] 3 4]
+ foreach p $x {
+ lappend y [file normalize $p]
+ }
+ set y
+} -cleanup {
+ cd $saveDir
+ removeFile init.tcl $scriptDir
+ removeDirectory tcl[info tclversion] $libDir
+ file delete $execPath
+ removeDirectory bin $sparklyDir
+ removeDirectory lib $sparklyDir
+ removeDirectory sparkly $tmpDir
+ removeDirectory tmp
+ unset -nocomplain saveDir scriptDir libDir execPath sparklyDir tmpDir
+ unset -nocomplain x p y env(TCL_LIBRARY)
+ if {[info exists oldlibrary]} {
+ set env(TCL_LIBRARY) $oldlibrary
+ unset oldlibrary
+ }
+} -result [list [file join [temporaryDirectory] tmp sparkly library] \
+ [file join [temporaryDirectory] tmp library] ]
+
+test unixInit-3.1 {TclpSetInitialEncodings} -constraints {
+ unix stdio
+} -body {
+ set env(LANG) C
+ set f [open "|[list [interpreter]]" w+]
+ fconfigure $f -buffering none
+ puts $f {puts [encoding system]; exit}
+ set enc [gets $f]
+ close $f
+ return $enc
+} -cleanup {
+ unset -nocomplain env(LANG)
+} -match regexp -result [expr {
+ ($tcl_platform(os) eq "Darwin") ? "^utf-8$" : "^iso8859-15?$"}]
+test unixInit-3.2 {TclpSetInitialEncodings} -setup {
+ catch {set oldlc_all $env(LC_ALL)}
+} -constraints {unix stdio} -body {
+ set env(LANG) japanese
+ set env(LC_ALL) japanese
+ set f [open "|[list [interpreter]]" w+]
+ fconfigure $f -buffering none
+ puts $f {puts [encoding system]; exit}
+ set enc [gets $f]
+ close $f
+ set validEncodings [list euc-jp]
+ if {[string match HP-UX $tcl_platform(os)]} {
+ # Some older HP-UX systems need us to accept this as valid Bug 453883
+ # reports that newer HP-UX systems report euc-jp like everybody else.
+ lappend validEncodings shiftjis
+ }
+ expr {$enc ni $validEncodings}
+} -cleanup {
+ unset -nocomplain env(LANG) env(LC_ALL)
+ catch {set env(LC_ALL) $oldlc_all}
+} -result 0
+
+test unixInit-4.1 {TclpSetVariables} {unix} {
+ # just make sure they exist
+ set a [list $tcl_library $tcl_pkgPath $tcl_platform(os)]
+ set a [list $tcl_platform(osVersion) $tcl_platform(machine)]
+ set tcl_platform(platform)
+} "unix"
+
+test unixInit-5.1 {Tcl_Init} {emptyTest unix} {
+ # test initScript
+} {}
+
+test unixInit-6.1 {Tcl_SourceRCFile} {emptyTest unix} {
+} {}
+
+test unixInit-7.1 {closed standard channel: Bug 772288} -constraints {
+ unix stdio
+} -body {
+ set tclsh [interpreter]
+ set crash [makeFile {puts [open /dev/null]} crash.tcl]
+ set crashtest [makeFile "
+ close stdin
+ [list exec $tclsh $crash]
+ " crashtest.tcl]
+ exec $tclsh $crashtest
+} -cleanup {
+ removeFile crash.tcl
+ removeFile crashtest.tcl
+} -returnCodes 0
+
+# cleanup
+catch {unset env(LANG)}
+catch {set env(LANG) $oldlang}
+unset -nocomplain path
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/unixNotfy.test b/pkgs/msgcat/tests/unixNotfy.test
new file mode 100644
index 0000000..0646a3d
--- /dev/null
+++ b/pkgs/msgcat/tests/unixNotfy.test
@@ -0,0 +1,102 @@
+# This file contains tests for tclUnixNotfy.c.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# When run in a Tk shell, these tests hang.
+testConstraint noTk [expr {0 != [catch {package present Tk}]}]
+testConstraint thread [expr {0 == [catch {package require Thread 2.6}]}]
+# Darwin always uses a threaded notifier
+testConstraint unthreaded [expr {
+ ![::tcl::pkgconfig get threaded]
+ && $tcl_platform(os) ne "Darwin"
+}]
+
+# The next two tests will hang if threads are enabled because the notifier
+# will not necessarily wait for ever in this case, so it does not generate
+# an error.
+test unixNotfy-1.1 {Tcl_DeleteFileHandler} -constraints {noTk unix unthreaded} -body {
+ catch {vwait x}
+ set f [open [makeFile "" foo] w]
+ fileevent $f writable {set x 1}
+ vwait x
+ close $f
+ list [catch {vwait x} msg] $msg
+} -result {1 {can't wait for variable "x": would wait forever}} -cleanup {
+ catch { close $f }
+ catch { removeFile foo }
+}
+test unixNotfy-1.2 {Tcl_DeleteFileHandler} -constraints {noTk unix unthreaded} -body {
+ catch {vwait x}
+ set f1 [open [makeFile "" foo] w]
+ set f2 [open [makeFile "" foo2] w]
+ fileevent $f1 writable {set x 1}
+ fileevent $f2 writable {set y 1}
+ vwait x
+ close $f1
+ vwait y
+ close $f2
+ list [catch {vwait x} msg] $msg
+} -result {1 {can't wait for variable "x": would wait forever}} -cleanup {
+ catch { close $f1 }
+ catch { close $f2 }
+ catch { removeFile foo }
+ catch { removeFile foo2 }
+}
+
+test unixNotfy-2.1 {Tcl_DeleteFileHandler} \
+ -constraints {noTk unix thread} \
+ -body {
+ update
+ set f [open [makeFile "" foo] w]
+ fileevent $f writable {set x 1}
+ vwait x
+ close $f
+ thread::create "thread::send [thread::id] {set x ok}"
+ vwait x
+ set x
+ } \
+ -result {ok} \
+ -cleanup {
+ catch { close $f }
+ catch { removeFile foo }
+ }
+test unixNotfy-2.2 {Tcl_DeleteFileHandler} \
+ -constraints {noTk unix thread} \
+ -body {
+ update
+ set f1 [open [makeFile "" foo] w]
+ set f2 [open [makeFile "" foo2] w]
+ fileevent $f1 writable {set x 1}
+ fileevent $f2 writable {set y 1}
+ vwait x
+ close $f1
+ vwait y
+ close $f2
+ thread::create "thread::send [thread::id] {set x ok}"
+ vwait x
+ set x
+ } \
+ -result {ok} \
+ -cleanup {
+ catch { close $f1 }
+ catch { close $f2 }
+ catch { removeFile foo }
+ catch { removeFile foo2 }
+ }
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/unknown.test b/pkgs/msgcat/tests/unknown.test
new file mode 100644
index 0000000..40be6602
--- /dev/null
+++ b/pkgs/msgcat/tests/unknown.test
@@ -0,0 +1,67 @@
+# Commands covered: unknown
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+catch {unset x}
+catch {rename unknown unknown.old}
+
+test unknown-1.1 {non-existent "unknown" command} {
+ list [catch {_non-existent_ foo bar} msg] $msg
+} {1 {invalid command name "_non-existent_"}}
+
+proc unknown {args} {
+ global x
+ set x $args
+}
+test unknown-2.1 {calling "unknown" command} {
+ foobar x y z
+ set x
+} {foobar x y z}
+test unknown-2.2 {calling "unknown" command with lots of args} {
+ foobar 1 2 3 4 5 6 7
+ set x
+} {foobar 1 2 3 4 5 6 7}
+test unknown-2.3 {calling "unknown" command with lots of args} {
+ foobar 1 2 3 4 5 6 7 8
+ set x
+} {foobar 1 2 3 4 5 6 7 8}
+test unknown-2.4 {calling "unknown" command with lots of args} {
+ foobar 1 2 3 4 5 6 7 8 9
+ set x
+} {foobar 1 2 3 4 5 6 7 8 9}
+
+test unknown-3.1 {argument quoting in calls to "unknown"} {
+ foobar \{ \} a\{b \; "\\" \$a a\[b \]
+ set x
+} "foobar \\{ \\} a\\{b {;} \\\\ {\$a} {a\[b} \\]"
+
+proc unknown args {
+ error "unknown failed"
+}
+test unknown-4.1 {errors in "unknown" procedure} {
+ list [catch {non-existent a b} msg] $msg $errorCode
+} {1 {unknown failed} NONE}
+
+# cleanup
+catch {rename unknown {}}
+catch {rename unknown.old unknown}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/unload.test b/pkgs/msgcat/tests/unload.test
new file mode 100644
index 0000000..a103cc5
--- /dev/null
+++ b/pkgs/msgcat/tests/unload.test
@@ -0,0 +1,242 @@
+# Commands covered: unload
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1995 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2003-2004 by Georgios Petasis
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Figure out what extension is used for shared libraries on this
+# platform.
+if {![info exists ext]} {
+ set ext [info sharedlibextension]
+}
+
+# Tests require the existence of one of the DLLs in the dltest directory.
+set testDir [file join [file dirname [info nameofexecutable]] dltest]
+set x [file join $testDir pkgua$ext]
+set dll "[file tail $x]Required"
+testConstraint $dll [file readable $x]
+
+# Tests also require that this DLL has not already been loaded.
+set loaded "[file tail $x]Loaded"
+set alreadyLoaded [info loaded]
+testConstraint $loaded [expr {![string match *pkgua* $alreadyLoaded]}]
+
+set alreadyTotalLoaded [info loaded]
+
+# Certain tests require the 'teststaticpkg' command from tcltest
+testConstraint teststaticpkg [llength [info commands teststaticpkg]]
+
+# Certain tests need the 'testsimplefilsystem' in tcltest
+testConstraint testsimplefilesystem \
+ [llength [info commands testsimplefilesystem]]
+
+# Basic tests: parameter testing...
+test unload-1.1 {basic errors} -returnCodes error -body {
+ unload
+} -result {wrong # args: should be "unload ?-switch ...? fileName ?packageName? ?interp?"}
+test unload-1.2 {basic errors} -returnCodes error -body {
+ unload a b c d
+} -result {wrong # args: should be "unload ?-switch ...? fileName ?packageName? ?interp?"}
+test unload-1.3 {basic errors} -returnCodes error -body {
+ unload a b foobar
+} -result {could not find interpreter "foobar"}
+test unload-1.4 {basic errors} -returnCodes error -body {
+ unload {}
+} -result {must specify either file name or package name}
+test unload-1.5 {basic errors} -returnCodes error -body {
+ unload {} {}
+} -result {must specify either file name or package name}
+test unload-1.6 {basic errors} -returnCodes error -body {
+ unload {} Unknown
+} -result {package "Unknown" is loaded statically and cannot be unloaded}
+test unload-1.7 {-nocomplain switch} {
+ unload -nocomplain {} Unknown
+} {}
+
+set pkgua_loaded {}
+set pkgua_detached {}
+set pkgua_unloaded {}
+# Tests for loading/unloading in trusted (non-safe) interpreters...
+test unload-2.1 {basic loading of non-unloadable package, with guess for package name} [list $dll $loaded] {
+ load [file join $testDir pkga$ext]
+ list [pkga_eq abc def] [lsort [info commands pkga_*]]
+} {0 {pkga_eq pkga_quote}}
+test unload-2.2 {basic loading of unloadable package, with guess for package name} [list $dll $loaded] {
+ list $pkgua_loaded $pkgua_detached $pkgua_unloaded \
+ [load [file join $testDir pkgua$ext]] \
+ [pkgua_eq abc def] [lsort [info commands pkgua_*]] \
+ $pkgua_loaded $pkgua_detached $pkgua_unloaded
+} {{} {} {} {} 0 {pkgua_eq pkgua_quote} . {} {}}
+test unload-2.3 {basic unloading of non-unloadable package, with guess for package name} [list $dll $loaded] {
+ list [catch {unload [file join $testDir pkga$ext]} msg] \
+ [string map [list [file join $testDir pkga$ext] file] $msg]
+} {1 {file "file" cannot be unloaded under a trusted interpreter}}
+test unload-2.4 {basic unloading of unloadable package, with guess for package name} [list $dll $loaded] {
+ list $pkgua_loaded $pkgua_detached $pkgua_unloaded \
+ [unload [file join $testDir pkgua$ext]] \
+ [info commands pkgua_*] \
+ $pkgua_loaded $pkgua_detached $pkgua_unloaded
+} {. {} {} {} {} . . .}
+test unload-2.5 {reloading of unloaded package, with guess for package name} [list $dll $loaded] {
+ list $pkgua_loaded $pkgua_detached $pkgua_unloaded \
+ [load [file join $testDir pkgua$ext]] \
+ [pkgua_eq abc def] [lsort [info commands pkgua_*]] \
+ $pkgua_loaded $pkgua_detached $pkgua_unloaded
+} {. . . {} 0 {pkgua_eq pkgua_quote} .. . .}
+test unload-2.6 {basic unloading of re-loaded package, with guess for package name} [list $dll $loaded] {
+ list $pkgua_loaded $pkgua_detached $pkgua_unloaded \
+ [unload [file join $testDir pkgua$ext]] \
+ [info commands pkgua_*] \
+ $pkgua_loaded $pkgua_detached $pkgua_unloaded
+} {.. . . {} {} .. .. ..}
+
+# Tests for loading/unloading in safe interpreters...
+interp create -safe child
+child eval {
+ set pkgua_loaded {}
+ set pkgua_detached {}
+ set pkgua_unloaded {}
+}
+test unload-3.1 {basic loading of non-unloadable package in a safe interpreter, with package name conversion} \
+ [list $dll $loaded] {
+ catch {rename pkgb_sub {}}
+ load [file join $testDir pkgb$ext] pKgB child
+ list [child eval pkgb_sub 44 13] [catch {child eval pkgb_unsafe} msg] $msg \
+ [catch {pkgb_sub 12 10} msg2] $msg2
+} {31 1 {invalid command name "pkgb_unsafe"} 1 {invalid command name "pkgb_sub"}}
+test unload-3.2 {basic loading of unloadable package in a safe interpreter, with package name conversion} \
+ [list $dll $loaded] {
+ list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+ [load [file join $testDir pkgua$ext] pKgUA child] \
+ [child eval pkgua_eq abc def] \
+ [lsort [child eval info commands pkgua_*]] \
+ [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} {{{} {} {}} {} 0 {pkgua_eq pkgua_quote} {. {} {}}}
+test unload-3.3 {unloading of a package that has never been loaded from a safe interpreter} \
+ [list $dll $loaded] {
+ list [catch {unload [file join $testDir pkga$ext] {} child} msg] \
+ [string map [list [file join $testDir pkga$ext] file] $msg]
+} {1 {file "file" has never been loaded in this interpreter}}
+test unload-3.4 {basic unloading of a non-unloadable package from a safe interpreter, with guess for package name} \
+ [list $dll $loaded] {
+ list [catch {unload [file join $testDir pkgb$ext] {} child} msg] \
+ [string map [list [file join $testDir pkgb$ext] file] $msg]
+} {1 {file "file" cannot be unloaded under a safe interpreter}}
+test unload-3.5 {basic unloading of an unloadable package from a safe interpreter, with guess for package name} \
+ [list $dll $loaded] {
+ list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+ [unload [file join $testDir pkgua$ext] {} child] \
+ [child eval info commands pkgua_*] \
+ [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} {{. {} {}} {} {} {. . .}}
+test unload-3.6 {reloading of unloaded package in a safe interpreter, with guess for package name} \
+ [list $dll $loaded] {
+ list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+ [load [file join $testDir pkgua$ext] {} child] \
+ [child eval pkgua_eq abc def] \
+ [lsort [child eval info commands pkgua_*]] \
+ [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} {{. . .} {} 0 {pkgua_eq pkgua_quote} {.. . .}}
+test unload-3.7 {basic unloading of re-loaded package from a safe interpreter, with package name conversion} \
+ [list $dll $loaded] {
+ list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+ [unload [file join $testDir pkgua$ext] pKgUa child] \
+ [child eval info commands pkgua_*] \
+ [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} {{.. . .} {} {} {.. .. ..}}
+
+# Tests for loading/unloading of a package among multiple interpreters...
+interp create child-trusted
+child-trusted eval {
+ set pkgua_loaded {}
+ set pkgua_detached {}
+ set pkgua_unloaded {}
+}
+## Load package in main trusted interpreter...
+test unload-4.1 {loading of unloadable package in trusted interpreter, with guess for package name} \
+ [list $dll $loaded] {
+ list [list $pkgua_loaded $pkgua_detached $pkgua_unloaded] \
+ [load [file join $testDir pkgua$ext]] \
+ [pkgua_eq abc def] [lsort [info commands pkgua_*]] \
+ [list $pkgua_loaded $pkgua_detached $pkgua_unloaded]
+} {{.. .. ..} {} 0 {pkgua_eq pkgua_quote} {... .. ..}}
+## Load package in child-safe interpreter...
+test unload-4.2 {basic loading of unloadable package in a safe interpreter, with package name conversion} \
+ [list $dll $loaded] {
+ list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+ [load [file join $testDir pkgua$ext] pKgUA child] \
+ [child eval pkgua_eq abc def] \
+ [lsort [child eval info commands pkgua_*]] \
+ [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} {{.. .. ..} {} 0 {pkgua_eq pkgua_quote} {... .. ..}}
+## Load package in child-trusted interpreter...
+test unload-4.3 {basic loading of unloadable package in a second trusted interpreter, with package name conversion} \
+ [list $dll $loaded] {
+ list [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+ [load [file join $testDir pkgua$ext] pkguA child-trusted] \
+ [child-trusted eval pkgua_eq abc def] \
+ [lsort [child-trusted eval info commands pkgua_*]] \
+ [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} {{{} {} {}} {} 0 {pkgua_eq pkgua_quote} {. {} {}}}
+## Unload the package from the main trusted interpreter...
+test unload-4.4 {basic unloading of unloadable package from trusted interpreter, with guess for package name} \
+ [list $dll $loaded] {
+ list [list $pkgua_loaded $pkgua_detached $pkgua_unloaded] \
+ [unload [file join $testDir pkgua$ext]] \
+ [info commands pkgua_*] \
+ [list $pkgua_loaded $pkgua_detached $pkgua_unloaded]
+} {{... .. ..} {} {} {... ... ..}}
+## Unload the package from the child safe interpreter...
+test unload-4.5 {basic unloading of unloadable package from a safe interpreter, with guess for package name} \
+ [list $dll $loaded] {
+ list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+ [unload [file join $testDir pkgua$ext] {} child] \
+ [child eval info commands pkgua_*] \
+ [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} {{... .. ..} {} {} {... ... ..}}
+## Unload the package from the child trusted interpreter...
+test unload-4.6 {basic unloading of unloadable package from a safe interpreter, with guess for package name} \
+ [list $dll $loaded] {
+ list [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+ [unload [file join $testDir pkgua$ext] {} child-trusted] \
+ [child-trusted eval info commands pkgua_*] \
+ [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} {{. {} {}} {} {} {. . .}}
+
+test unload-5.1 {unload a module loaded from vfs} \
+ -constraints [list $dll $loaded testsimplefilesystem] \
+ -setup {
+ set dir [pwd]
+ cd $testDir
+ testsimplefilesystem 1
+ load simplefs:/pkgua$ext pkgua
+ } \
+ -body {
+ list [catch {unload simplefs:/pkgua$ext} msg] $msg
+ } \
+ -result {0 {}}
+
+
+
+# cleanup
+interp delete child
+interp delete child-trusted
+unset ext
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/uplevel.test b/pkgs/msgcat/tests/uplevel.test
new file mode 100644
index 0000000..0410469
--- /dev/null
+++ b/pkgs/msgcat/tests/uplevel.test
@@ -0,0 +1,206 @@
+# Commands covered: uplevel
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+proc a {x y} {
+ newset z [expr $x+$y]
+ return $z
+}
+proc newset {name value} {
+ uplevel set $name $value
+ uplevel 1 {uplevel 1 {set xyz 22}}
+}
+
+test uplevel-1.1 {simple operation} {
+ set xyz 0
+ a 22 33
+} 55
+test uplevel-1.2 {command is another uplevel command} {
+ set xyz 0
+ a 22 33
+ set xyz
+} 22
+
+proc a1 {} {
+ b1
+ global a a1
+ set a $x
+ set a1 $y
+}
+proc b1 {} {
+ c1
+ global b b1
+ set b $x
+ set b1 $y
+}
+proc c1 {} {
+ uplevel 1 set x 111
+ uplevel #2 set y 222
+ uplevel 2 set x 333
+ uplevel #1 set y 444
+ uplevel 3 set x 555
+ uplevel #0 set y 666
+}
+a1
+test uplevel-2.1 {relative and absolute uplevel} {set a} 333
+test uplevel-2.2 {relative and absolute uplevel} {set a1} 444
+test uplevel-2.3 {relative and absolute uplevel} {set b} 111
+test uplevel-2.4 {relative and absolute uplevel} {set b1} 222
+test uplevel-2.5 {relative and absolute uplevel} {set x} 555
+test uplevel-2.6 {relative and absolute uplevel} {set y} 666
+
+test uplevel-3.1 {uplevel to same level} {
+ set x 33
+ uplevel #0 set x 44
+ set x
+} 44
+test uplevel-3.2 {uplevel to same level} {
+ set x 33
+ uplevel 0 set x
+} 33
+test uplevel-3.3 {uplevel to same level} {
+ set y xxx
+ proc a1 {} {set y 55; uplevel 0 set y 66; return $y}
+ a1
+} 66
+test uplevel-3.4 {uplevel to same level} {
+ set y zzz
+ proc a1 {} {set y 55; uplevel #1 set y}
+ a1
+} 55
+
+test uplevel-4.1 {error: non-existent level} -returnCodes error -body {
+ apply {{} {
+ uplevel #2 {set y 222}
+ }}
+} -result {bad level "#2"}
+test uplevel-4.2 {error: non-existent level} -returnCodes error -body {
+ apply {{} {
+ uplevel 3 {set a b}
+ }}
+} -result {bad level "3"}
+test uplevel-4.3 {error: not enough args} -returnCodes error -body {
+ uplevel
+} -result {wrong # args: should be "uplevel ?level? command ?arg ...?"}
+test uplevel-4.4 {error: not enough args} -returnCodes error -body {
+ apply {{} {
+ uplevel 1
+ }}
+} -result {wrong # args: should be "uplevel ?level? command ?arg ...?"}
+
+proc a2 {} {
+ uplevel a3
+}
+proc a3 {} {
+ global x y
+ set x [info level]
+ set y [info level 1]
+}
+a2
+test uplevel-5.1 {info level} {set x} 1
+test uplevel-5.2 {info level} {set y} a3
+
+namespace eval ns1 {
+ proc set args {return ::ns1}
+}
+proc a2 {} {
+ uplevel {set x ::}
+}
+test uplevel-6.1 {uplevel and shadowed cmds} {
+ set res [namespace eval ns1 a2]
+ lappend res [namespace eval ns2 a2]
+ lappend res [namespace eval ns1 a2]
+ namespace eval ns1 {rename set {}}
+ lappend res [namespace eval ns1 a2]
+} {::ns1 :: ::ns1 ::}
+
+#
+# These tests verify that upleveled scripts run in the correct level and access
+# the proper variables.
+#
+
+test uplevel-7.1 {var access, no LVT in either level} -setup {
+ set x 1
+ unset -nocomplain y z
+} -body {
+ namespace eval foo {
+ set x 2
+ set y 2
+ uplevel 1 {
+ set x 3
+ set y 3
+ set z 3
+ }
+ }
+ list $x $y $z
+} -cleanup {
+ namespace delete foo
+ unset -nocomplain x y z
+} -result {3 3 3}
+
+test uplevel-7.2 {var access, no LVT in upper level} -setup {
+ set x 1
+ unset -nocomplain y z
+} -body {
+ proc foo {} {
+ set x 2
+ set y 2
+ uplevel 1 {
+ set x 3
+ set y 3
+ set z 3
+ }
+ }
+ foo
+ list $x $y $z
+} -cleanup {
+ rename foo {}
+ unset -nocomplain x y z
+} -result {3 3 3}
+
+test uplevel-7.3 {var access, LVT in upper level} -setup {
+ proc moo {} {
+ set x 1; #var in LVT
+ unset -nocomplain y z
+ foo
+ list $x $y $z
+ }
+} -body {
+ proc foo {} {
+ set x 2
+ set y 2
+ uplevel 1 {
+ set x 3
+ set y 3
+ set z 3
+ }
+ }
+ foo
+ moo
+} -cleanup {
+ rename foo {}
+ rename moo {}
+} -result {3 3 3}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/upvar.test b/pkgs/msgcat/tests/upvar.test
new file mode 100644
index 0000000..cd78c31
--- /dev/null
+++ b/pkgs/msgcat/tests/upvar.test
@@ -0,0 +1,543 @@
+# Commands covered: 'upvar', 'namespace upvar'
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testupvar [llength [info commands testupvar]]
+
+test upvar-1.1 {reading variables with upvar} {
+ proc p1 {a b} {set c 22; set d 33; p2}
+ proc p2 {} {upvar a x1 b x2 c x3 d x4; set a abc; list $x1 $x2 $x3 $x4 $a}
+ p1 foo bar
+} {foo bar 22 33 abc}
+test upvar-1.2 {reading variables with upvar} {
+ proc p1 {a b} {set c 22; set d 33; p2}
+ proc p2 {} {p3}
+ proc p3 {} {upvar 2 a x1 b x2 c x3 d x4; set a abc; list $x1 $x2 $x3 $x4 $a}
+ p1 foo bar
+} {foo bar 22 33 abc}
+test upvar-1.3 {reading variables with upvar} {
+ proc p1 {a b} {set c 22; set d 33; p2}
+ proc p2 {} {p3}
+ proc p3 {} {
+ upvar #1 a x1 b x2 c x3 d x4
+ set a abc
+ list $x1 $x2 $x3 $x4 $a
+ }
+ p1 foo bar
+} {foo bar 22 33 abc}
+test upvar-1.4 {reading variables with upvar} {
+ set x1 44
+ set x2 55
+ proc p1 {} {p2}
+ proc p2 {} {
+ upvar 2 x1 x1 x2 a
+ upvar #0 x1 b
+ set c $b
+ incr b 3
+ list $x1 $a $b
+ }
+ p1
+} {47 55 47}
+test upvar-1.5 {reading array elements with upvar} {
+ proc p1 {} {set a(0) zeroth; set a(1) first; p2}
+ proc p2 {} {upvar a(0) x; set x}
+ p1
+} {zeroth}
+
+test upvar-2.1 {writing variables with upvar} {
+ proc p1 {a b} {set c 22; set d 33; p2; list $a $b $c $d}
+ proc p2 {} {
+ upvar a x1 b x2 c x3 d x4
+ set x1 14
+ set x4 88
+ }
+ p1 foo bar
+} {14 bar 22 88}
+test upvar-2.2 {writing variables with upvar} {
+ set x1 44
+ set x2 55
+ proc p1 {x1 x2} {
+ upvar #0 x1 a
+ upvar x2 b
+ set a $x1
+ set b $x2
+ }
+ p1 newbits morebits
+ list $x1 $x2
+} {newbits morebits}
+test upvar-2.3 {writing variables with upvar} {
+ catch {unset x1}
+ catch {unset x2}
+ proc p1 {x1 x2} {
+ upvar #0 x1 a
+ upvar x2 b
+ set a $x1
+ set b $x2
+ }
+ p1 newbits morebits
+ list [catch {set x1} msg] $msg [catch {set x2} msg] $msg
+} {0 newbits 0 morebits}
+test upvar-2.4 {writing array elements with upvar} {
+ proc p1 {} {set a(0) zeroth; set a(1) first; list [p2] $a(0)}
+ proc p2 {} {upvar a(0) x; set x xyzzy}
+ p1
+} {xyzzy xyzzy}
+
+test upvar-3.1 {unsetting variables with upvar} {
+ proc p1 {a b} {set c 22; set d 33; p2; lsort [info vars]}
+ proc p2 {} {
+ upvar 1 a x1 d x2
+ unset x1 x2
+ }
+ p1 foo bar
+} {b c}
+test upvar-3.2 {unsetting variables with upvar} {
+ proc p1 {a b} {set c 22; set d 33; p2; lsort [info vars]}
+ proc p2 {} {
+ upvar 1 a x1 d x2
+ unset x1 x2
+ set x2 28
+ }
+ p1 foo bar
+} {b c d}
+test upvar-3.3 {unsetting variables with upvar} {
+ set x1 44
+ set x2 55
+ proc p1 {} {p2}
+ proc p2 {} {
+ upvar 2 x1 a
+ upvar #0 x2 b
+ unset a b
+ }
+ p1
+ list [info exists x1] [info exists x2]
+} {0 0}
+test upvar-3.4 {unsetting variables with upvar} {
+ set x1 44
+ set x2 55
+ proc p1 {} {
+ upvar x1 a x2 b
+ unset a b
+ set b 118
+ }
+ p1
+ list [info exists x1] [catch {set x2} msg] $msg
+} {0 0 118}
+test upvar-3.5 {unsetting array elements with upvar} {
+ proc p1 {} {
+ set a(0) zeroth
+ set a(1) first
+ set a(2) second
+ p2
+ array names a
+ }
+ proc p2 {} {upvar a(0) x; unset x}
+ lsort [p1]
+} {1 2}
+test upvar-3.6 {unsetting then resetting array elements with upvar} {
+ proc p1 {} {
+ set a(0) zeroth
+ set a(1) first
+ set a(2) second
+ p2
+ list [lsort [array names a]] [catch {set a(0)} msg] $msg
+ }
+ proc p2 {} {upvar a(0) x; unset x; set x 12345}
+ p1
+} {{0 1 2} 0 12345}
+
+test upvar-4.1 {nested upvars} {
+ set x1 88
+ proc p1 {a b} {set c 22; set d 33; p2}
+ proc p2 {} {global x1; upvar c x2; p3}
+ proc p3 {} {
+ upvar x1 a x2 b
+ list $a $b
+ }
+ p1 14 15
+} {88 22}
+test upvar-4.2 {nested upvars} {
+ set x1 88
+ proc p1 {a b} {set c 22; set d 33; p2; list $a $b $c $d}
+ proc p2 {} {global x1; upvar c x2; p3}
+ proc p3 {} {
+ upvar x1 a x2 b
+ set a foo
+ set b bar
+ }
+ list [p1 14 15] $x1
+} {{14 15 bar 33} foo}
+
+proc tproc {args} {global x; set x [list $args [uplevel info vars]]}
+test upvar-5.1 {traces involving upvars} {
+ proc p1 {a b} {set c 22; set d 33; trace var c rw tproc; p2}
+ proc p2 {} {upvar c x1; set x1 22}
+ set x ---
+ p1 foo bar
+ set x
+} {{x1 {} w} x1}
+test upvar-5.2 {traces involving upvars} {
+ proc p1 {a b} {set c 22; set d 33; trace var c rw tproc; p2}
+ proc p2 {} {upvar c x1; set x1}
+ set x ---
+ p1 foo bar
+ set x
+} {{x1 {} r} x1}
+test upvar-5.3 {traces involving upvars} {
+ proc p1 {a b} {set c 22; set d 33; trace var c rwu tproc; p2}
+ proc p2 {} {upvar c x1; unset x1}
+ set x ---
+ p1 foo bar
+ set x
+} {{x1 {} u} x1}
+
+test upvar-6.1 {retargeting an upvar} {
+ proc p1 {} {
+ set a(0) zeroth
+ set a(1) first
+ set a(2) second
+ p2
+ }
+ proc p2 {} {
+ upvar a x
+ set result {}
+ foreach i [array names x] {
+ upvar a($i) x
+ lappend result $x
+ }
+ lsort $result
+ }
+ p1
+} {first second zeroth}
+test upvar-6.2 {retargeting an upvar} {
+ set x 44
+ set y abcde
+ proc p1 {} {
+ global x
+ set result $x
+ upvar y x
+ lappend result $x
+ }
+ p1
+} {44 abcde}
+test upvar-6.3 {retargeting an upvar} {
+ set x 44
+ set y abcde
+ proc p1 {} {
+ upvar y x
+ lappend result $x
+ global x
+ lappend result $x
+ }
+ p1
+} {abcde 44}
+
+test upvar-7.1 {upvar to same level} {
+ set x 44
+ set y 55
+ catch {unset uv}
+ upvar #0 x uv
+ set uv abc
+ upvar 0 y uv
+ set uv xyzzy
+ list $x $y
+} {abc xyzzy}
+test upvar-7.2 {upvar to same level} {
+ set x 1234
+ set y 4567
+ proc p1 {x y} {
+ upvar 0 x uv
+ set uv $y
+ return "$x $y"
+ }
+ p1 44 89
+} {89 89}
+test upvar-7.3 {upvar to same level} {
+ set x 1234
+ set y 4567
+ proc p1 {x y} {
+ upvar #1 x uv
+ set uv $y
+ return "$x $y"
+ }
+ p1 xyz abc
+} {abc abc}
+test upvar-7.4 {upvar to same level: tricky problems when deleting variable table} {
+ proc tt {} {upvar #1 toto loc; return $loc}
+ list [catch tt msg] $msg
+} {1 {can't read "loc": no such variable}}
+test upvar-7.5 {potential memory leak when deleting variable table} {
+ proc leak {} {
+ array set foo {1 2 3 4}
+ upvar 0 foo(1) bar
+ }
+ leak
+} {}
+
+test upvar-8.1 {errors in upvar command} -returnCodes error -body {
+ upvar
+} -result {wrong # args: should be "upvar ?level? otherVar localVar ?otherVar localVar ...?"}
+test upvar-8.2 {errors in upvar command} -returnCodes error -body {
+ upvar 1
+} -result {wrong # args: should be "upvar ?level? otherVar localVar ?otherVar localVar ...?"}
+test upvar-8.2.1 {upvar with numeric first argument} {
+ apply {{} {set 0 ok; apply {{} {upvar 0 x; return $x}}}}
+} ok
+test upvar-8.3 {errors in upvar command} -returnCodes error -body {
+ proc p1 {} {upvar a b c}
+ p1
+} -result {bad level "a"}
+test upvar-8.4 {errors in upvar command} -returnCodes error -body {
+ proc p1 {} {upvar 0 b b}
+ p1
+} -result {can't upvar from variable to itself}
+test upvar-8.5 {errors in upvar command} -returnCodes error -body {
+ proc p1 {} {upvar 0 a b; upvar 0 b a}
+ p1
+} -result {can't upvar from variable to itself}
+test upvar-8.6 {errors in upvar command} -returnCodes error -body {
+ proc p1 {} {set a 33; upvar b a}
+ p1
+} -result {variable "a" already exists}
+test upvar-8.7 {errors in upvar command} -returnCodes error -body {
+ proc p1 {} {trace variable a w foo; upvar b a}
+ p1
+} -result {variable "a" has traces: can't use for upvar}
+test upvar-8.8 {create nested array with upvar} -body {
+ proc p1 {} {upvar x(a) b; set b(2) 44}
+ catch {unset x}
+ p1
+} -returnCodes error -cleanup {
+ unset x
+} -result {can't set "b(2)": variable isn't array}
+test upvar-8.9 {upvar won't create namespace variable that refers to procedure variable} -setup {
+ catch {namespace delete {*}[namespace children :: test_ns_*]}
+ catch {rename MakeLink ""}
+ namespace eval ::test_ns_1 {}
+} -returnCodes error -body {
+ proc MakeLink {a} {
+ namespace eval ::test_ns_1 {
+ upvar a a
+ }
+ unset ::test_ns_1::a
+ }
+ MakeLink 1
+} -result {bad variable name "a": upvar won't create namespace variable that refers to procedure variable}
+test upvar-8.10 {upvar will create element alias for new array element} -setup {
+ catch {unset upvarArray}
+} -body {
+ array set upvarArray {}
+ catch {upvar 0 upvarArray(elem) upvarArrayElemAlias}
+} -result {0}
+test upvar-8.11 {upvar will not create a variable that looks like an array} -setup {
+ catch {unset upvarArray}
+} -body {
+ array set upvarArray {}
+ upvar 0 upvarArray(elem) upvarArrayElemAlias(elem)
+} -returnCodes 1 -match glob -result *
+
+test upvar-9.1 {Tcl_UpVar2 procedure} testupvar {
+ list [catch {testupvar xyz a {} x global} msg] $msg
+} {1 {bad level "xyz"}}
+test upvar-9.2 {Tcl_UpVar2 procedure} testupvar {
+ catch {unset a}
+ catch {unset x}
+ set a 44
+ list [catch "testupvar #0 a 1 x global" msg] $msg
+} {1 {can't access "a(1)": variable isn't array}}
+test upvar-9.3 {Tcl_UpVar2 procedure} testupvar {
+ proc foo {} {
+ testupvar 1 a {} x local
+ set x
+ }
+ catch {unset a}
+ catch {unset x}
+ set a 44
+ foo
+} {44}
+test upvar-9.4 {Tcl_UpVar2 procedure} testupvar {
+ proc foo {} {
+ testupvar 1 a {} _up_ global
+ list [catch {set x} msg] $msg
+ }
+ catch {unset a}
+ catch {unset _up_}
+ set a 44
+ concat [foo] $_up_
+} {1 {can't read "x": no such variable} 44}
+test upvar-9.5 {Tcl_UpVar2 procedure} testupvar {
+ proc foo {} {
+ testupvar 1 a b x local
+ set x
+ }
+ catch {unset a}
+ catch {unset x}
+ set a(b) 1234
+ foo
+} {1234}
+test upvar-9.6 {Tcl_UpVar procedure} testupvar {
+ proc foo {} {
+ testupvar 1 a x local
+ set x
+ }
+ catch {unset a}
+ catch {unset x}
+ set a xyzzy
+ foo
+} {xyzzy}
+test upvar-9.7 {Tcl_UpVar procedure} testupvar {
+ proc foo {} {
+ testupvar #0 a(b) x local
+ set x
+ }
+ catch {unset a}
+ catch {unset x}
+ set a(b) 1234
+ foo
+} {1234}
+catch {unset a}
+
+#
+# Tests for 'namespace upvar'. As the implementation is essentially the same as
+# for 'upvar', we only test that the variables are linked correctly, i.e., we
+# assume that the behaviour of variables once the link is established has
+# already been tested above.
+#
+
+# Clear out any namespaces called test_ns_*
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+namespace eval test_ns_0 {
+ variable x test_ns_0
+}
+set ::x test_global
+
+test upvar-NS-1.1 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ namespace upvar ::test_ns_0 x w
+ set w
+ }
+} -result {test_ns_0} -cleanup {
+ namespace delete test_ns_1
+}
+test upvar-NS-1.2 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ proc a {} {
+ namespace upvar ::test_ns_0 x w
+ set w
+ }
+ return [a]
+ }
+} -result {test_ns_0} -cleanup {
+ namespace delete test_ns_1
+}
+test upvar-NS-1.3 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ namespace upvar test_ns_0 x w
+ set w
+ }
+} -returnCodes error -cleanup {
+ namespace delete test_ns_1
+} -result {namespace "test_ns_0" not found in "::test_ns_1"}
+test upvar-NS-1.4 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ proc a {} {
+ namespace upvar test_ns_0 x w
+ set w
+ }
+ return [a]
+ }
+} -returnCodes error -cleanup {
+ namespace delete test_ns_1
+} -result {namespace "test_ns_0" not found in "::test_ns_1"}
+
+test upvar-NS-1.5 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ namespace eval test_ns_0 {}
+ namespace upvar test_ns_0 x w
+ set w
+ }
+} -cleanup {
+ namespace delete test_ns_1
+} -result {can't read "w": no such variable} -returnCodes error
+test upvar-NS-1.6 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ namespace eval test_ns_0 {}
+ proc a {} {
+ namespace upvar test_ns_0 x w
+ set w
+ }
+ return [a]
+ }
+} -cleanup {
+ namespace delete test_ns_1
+} -result {can't read "w": no such variable} -returnCodes error
+test upvar-NS-1.7 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ namespace eval test_ns_0 {
+ variable x test_ns_1::test_ns_0
+ }
+ namespace upvar test_ns_0 x w
+ set w
+ }
+} -cleanup {
+ namespace delete test_ns_1
+} -result {test_ns_1::test_ns_0}
+test upvar-NS-1.8 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ namespace eval test_ns_0 {
+ variable x test_ns_1::test_ns_0
+ }
+ proc a {} {
+ namespace upvar test_ns_0 x w
+ set w
+ }
+ return [a]
+ }
+} -cleanup {
+ namespace delete test_ns_1
+} -result {test_ns_1::test_ns_0}
+test upvar-NS-1.9 {nsupvar links to correct variable} -body {
+ namespace eval test_ns_1 {
+ variable x test_ns_1
+ proc a {} {
+ namespace upvar test_ns_0 x w
+ set w
+ }
+ return [a]
+ }
+} -returnCodes error -cleanup {
+ namespace delete test_ns_1
+} -result {namespace "test_ns_0" not found in "::test_ns_1"}
+
+test upvar-NS-2.1 {TIP 323} -returnCodes error -body {
+ namespace upvar
+} -result {wrong # args: should be "namespace upvar ns ?otherVar myVar ...?"}
+test upvar-NS-2.2 {TIP 323} -setup {
+ namespace eval test_ns_1 {}
+} -body {
+ namespace upvar test_ns_1
+} -cleanup {
+ namespace delete test_ns_1
+} -result {}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/utf.test b/pkgs/msgcat/tests/utf.test
new file mode 100644
index 0000000..fcd2a73
--- /dev/null
+++ b/pkgs/msgcat/tests/utf.test
@@ -0,0 +1,445 @@
+# This file contains a collection of tests for tclUtf.c
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+catch {unset x}
+
+test utf-1.1 {Tcl_UniCharToUtf: 1 byte sequences} {
+ set x \x01
+} [bytestring "\x01"]
+test utf-1.2 {Tcl_UniCharToUtf: 2 byte sequences} {
+ set x "\x00"
+} [bytestring "\xc0\x80"]
+test utf-1.3 {Tcl_UniCharToUtf: 2 byte sequences} {
+ set x "\xe0"
+} [bytestring "\xc3\xa0"]
+test utf-1.4 {Tcl_UniCharToUtf: 3 byte sequences} {
+ set x "\u4e4e"
+} [bytestring "\xe4\xb9\x8e"]
+test utf-1.5 {Tcl_UniCharToUtf: overflowed Tcl_UniChar} {
+ format %c 0x110000
+} [bytestring "\xef\xbf\xbd"]
+test utf-1.6 {Tcl_UniCharToUtf: negative Tcl_UniChar} {
+ format %c -1
+} [bytestring "\xef\xbf\xbd"]
+
+test utf-2.1 {Tcl_UtfToUniChar: low ascii} {
+ string length "abc"
+} {3}
+test utf-2.2 {Tcl_UtfToUniChar: naked trail bytes} {
+ string length [bytestring "\x82\x83\x84"]
+} {3}
+test utf-2.3 {Tcl_UtfToUniChar: lead (2-byte) followed by non-trail} {
+ string length [bytestring "\xC2"]
+} {1}
+test utf-2.4 {Tcl_UtfToUniChar: lead (2-byte) followed by trail} {
+ string length [bytestring "\xC2\xa2"]
+} {1}
+test utf-2.5 {Tcl_UtfToUniChar: lead (3-byte) followed by non-trail} {
+ string length [bytestring "\xE2"]
+} {1}
+test utf-2.6 {Tcl_UtfToUniChar: lead (3-byte) followed by 1 trail} {
+ string length [bytestring "\xE2\xA2"]
+} {2}
+test utf-2.7 {Tcl_UtfToUniChar: lead (3-byte) followed by 2 trail} {
+ string length [bytestring "\xE4\xb9\x8e"]
+} {1}
+test utf-2.8 {Tcl_UtfToUniChar: longer UTF sequences not supported} {
+ string length [bytestring "\xF4\xA2\xA2\xA2"]
+} {4}
+
+test utf-3.1 {Tcl_UtfCharComplete} {
+} {}
+
+testConstraint testnumutfchars [llength [info commands testnumutfchars]]
+test utf-4.1 {Tcl_NumUtfChars: zero length} testnumutfchars {
+ testnumutfchars ""
+} {0}
+test utf-4.2 {Tcl_NumUtfChars: length 1} testnumutfchars {
+ testnumutfchars [bytestring "\xC2\xA2"]
+} {1}
+test utf-4.3 {Tcl_NumUtfChars: long string} testnumutfchars {
+ testnumutfchars [bytestring "abc\xC2\xA2\xe4\xb9\x8e\uA2\u4e4e"]
+} {7}
+test utf-4.4 {Tcl_NumUtfChars: #u0000} testnumutfchars {
+ testnumutfchars [bytestring "\xC0\x80"]
+} {1}
+test utf-4.5 {Tcl_NumUtfChars: zero length, calc len} testnumutfchars {
+ testnumutfchars "" 1
+} {0}
+test utf-4.6 {Tcl_NumUtfChars: length 1, calc len} testnumutfchars {
+ testnumutfchars [bytestring "\xC2\xA2"] 1
+} {1}
+test utf-4.7 {Tcl_NumUtfChars: long string, calc len} testnumutfchars {
+ testnumutfchars [bytestring "abc\xC2\xA2\xe4\xb9\x8e\uA2\u4e4e"] 1
+} {7}
+test utf-4.8 {Tcl_NumUtfChars: #u0000, calc len} testnumutfchars {
+ testnumutfchars [bytestring "\xC0\x80"] 1
+} {1}
+
+test utf-5.1 {Tcl_UtfFindFirsts} {
+} {}
+
+test utf-6.1 {Tcl_UtfNext} {
+} {}
+
+test utf-7.1 {Tcl_UtfPrev} {
+} {}
+
+test utf-8.1 {Tcl_UniCharAtIndex: index = 0} {
+ string index abcd 0
+} {a}
+test utf-8.2 {Tcl_UniCharAtIndex: index = 0} {
+ string index \u4e4e\u25a 0
+} "\u4e4e"
+test utf-8.3 {Tcl_UniCharAtIndex: index > 0} {
+ string index abcd 2
+} {c}
+test utf-8.4 {Tcl_UniCharAtIndex: index > 0} {
+ string index \u4e4e\u25a\xff\u543 2
+} "\uff"
+
+test utf-9.1 {Tcl_UtfAtIndex: index = 0} {
+ string range abcd 0 2
+} {abc}
+test utf-9.2 {Tcl_UtfAtIndex: index > 0} {
+ string range \u4e4e\u25a\xff\u543klmnop 1 5
+} "\u25a\xff\u543kl"
+
+
+test utf-10.1 {Tcl_UtfBackslash: dst == NULL} {
+ set x \n
+} {
+}
+test utf-10.2 {Tcl_UtfBackslash: \u subst} {
+ set x \ua2
+} [bytestring "\xc2\xa2"]
+test utf-10.3 {Tcl_UtfBackslash: longer \u subst} {
+ set x \u4e21
+} [bytestring "\xe4\xb8\xa1"]
+test utf-10.4 {Tcl_UtfBackslash: stops at first non-hex} {
+ set x \u4e2k
+} "[bytestring \xd3\xa2]k"
+test utf-10.5 {Tcl_UtfBackslash: stops after 4 hex chars} {
+ set x \u4e216
+} "[bytestring \xe4\xb8\xa1]6"
+proc bsCheck {char num} {
+ global errNum
+ test utf-10.$errNum {backslash substitution} {
+ scan $char %c value
+ set value
+ } $num
+ incr errNum
+}
+set errNum 6
+bsCheck \b 8
+bsCheck \e 101
+bsCheck \f 12
+bsCheck \n 10
+bsCheck \r 13
+bsCheck \t 9
+bsCheck \v 11
+bsCheck \{ 123
+bsCheck \} 125
+bsCheck \[ 91
+bsCheck \] 93
+bsCheck \$ 36
+bsCheck \ 32
+bsCheck \; 59
+bsCheck \\ 92
+bsCheck \Ca 67
+bsCheck \Ma 77
+bsCheck \CMa 67
+# prior to 8.3, this returned 8, as \8 as accepted as an
+# octal value - but it isn't! [Bug: 3975]
+bsCheck \8a 56
+bsCheck \14 12
+bsCheck \141 97
+bsCheck b\0 98
+bsCheck \x 120
+bsCheck \xa 10
+bsCheck \xA 10
+bsCheck \x41 65
+bsCheck \x541 84
+bsCheck \u 117
+bsCheck \uk 117
+bsCheck \u41 65
+bsCheck \ua 10
+bsCheck \uA 10
+bsCheck \340 224
+bsCheck \ua1 161
+bsCheck \u4e21 20001
+bsCheck \741 60
+bsCheck \U 85
+bsCheck \Uk 85
+bsCheck \U41 65
+bsCheck \Ua 10
+bsCheck \UA 10
+bsCheck \Ua1 161
+bsCheck \U4e21 20001
+bsCheck \U004e21 20001
+bsCheck \U00004e21 20001
+bsCheck \U00110000 65533
+bsCheck \Uffffffff 65533
+
+test utf-11.1 {Tcl_UtfToUpper} {
+ string toupper {}
+} {}
+test utf-11.2 {Tcl_UtfToUpper} {
+ string toupper abc
+} ABC
+test utf-11.3 {Tcl_UtfToUpper} {
+ string toupper \u00e3ab
+} \u00c3AB
+test utf-11.4 {Tcl_UtfToUpper} {
+ string toupper \u01e3ab
+} \u01e2AB
+
+test utf-12.1 {Tcl_UtfToLower} {
+ string tolower {}
+} {}
+test utf-12.2 {Tcl_UtfToLower} {
+ string tolower ABC
+} abc
+test utf-12.3 {Tcl_UtfToLower} {
+ string tolower \u00c3AB
+} \u00e3ab
+test utf-12.4 {Tcl_UtfToLower} {
+ string tolower \u01e2AB
+} \u01e3ab
+
+test utf-13.1 {Tcl_UtfToTitle} {
+ string totitle {}
+} {}
+test utf-13.2 {Tcl_UtfToTitle} {
+ string totitle abc
+} Abc
+test utf-13.3 {Tcl_UtfToTitle} {
+ string totitle \u00e3ab
+} \u00c3ab
+test utf-13.4 {Tcl_UtfToTitle} {
+ string totitle \u01f3ab
+} \u01f2ab
+
+test utf-14.1 {Tcl_UtfNcasecmp} {
+ string compare -nocase a b
+} -1
+test utf-14.2 {Tcl_UtfNcasecmp} {
+ string compare -nocase b a
+} 1
+test utf-14.3 {Tcl_UtfNcasecmp} {
+ string compare -nocase B a
+} 1
+test utf-14.4 {Tcl_UtfNcasecmp} {
+ string compare -nocase aBcB abca
+} 1
+
+test utf-15.1 {Tcl_UniCharToUpper, negative delta} {
+ string toupper aA
+} AA
+test utf-15.2 {Tcl_UniCharToUpper, positive delta} {
+ string toupper \u0178\u00ff
+} \u0178\u0178
+test utf-15.3 {Tcl_UniCharToUpper, no delta} {
+ string toupper !
+} !
+
+test utf-16.1 {Tcl_UniCharToLower, negative delta} {
+ string tolower aA
+} aa
+test utf-16.2 {Tcl_UniCharToLower, positive delta} {
+ string tolower \u0178\u00ff\uA78D\u01c5
+} \u00ff\u00ff\u0265\u01c6
+
+test utf-17.1 {Tcl_UniCharToLower, no delta} {
+ string tolower !
+} !
+
+test utf-18.1 {Tcl_UniCharToTitle, add one for title} {
+ string totitle \u01c4
+} \u01c5
+test utf-18.2 {Tcl_UniCharToTitle, subtract one for title} {
+ string totitle \u01c6
+} \u01c5
+test utf-18.3 {Tcl_UniCharToTitle, subtract delta for title (positive)} {
+ string totitle \u017f
+} \u0053
+test utf-18.4 {Tcl_UniCharToTitle, subtract delta for title (negative)} {
+ string totitle \u00ff
+} \u0178
+test utf-18.5 {Tcl_UniCharToTitle, no delta} {
+ string totitle !
+} !
+
+test utf-19.1 {TclUniCharLen} {
+ list [regexp \\d abc456def foo] $foo
+} {1 4}
+
+test utf-20.1 {TclUniCharNcmp} {
+} {}
+
+test utf-21.1 {TclUniCharIsAlnum} {
+ # this returns 1 with Unicode 6 compliance
+ string is alnum \u1040\u021f\u0220
+} {1}
+test utf-21.2 {unicode alnum char in regc_locale.c} {
+ # this returns 1 with Unicode 6 compliance
+ list [regexp {^[[:alnum:]]+$} \u1040\u021f\u0220] [regexp {^\w+$} \u1040\u021f\u0220]
+} {1 1}
+test utf-21.3 {unicode print char in regc_locale.c} {
+ # this returns 1 with Unicode 6 compliance
+ regexp {^[[:print:]]+$} \ufbc1
+} 1
+test utf-21.4 {TclUniCharIsGraph} {
+ # [Bug 3464428]
+ string is graph \u0120
+} {1}
+test utf-21.5 {unicode graph char in regc_locale.c} {
+ # [Bug 3464428]
+ regexp {^[[:graph:]]+$} \u0120
+} {1}
+test utf-21.6 {TclUniCharIsGraph} {
+ # [Bug 3464428]
+ string is graph \u00a0
+} {0}
+test utf-21.7 {unicode graph char in regc_locale.c} {
+ # [Bug 3464428]
+ regexp {[[:graph:]]} \u0020\u00a0\u2028\u2029
+} {0}
+test utf-21.8 {TclUniCharIsPrint} {
+ # [Bug 3464428]
+ string is print \u0009
+} {0}
+test utf-21.9 {unicode print char in regc_locale.c} {
+ # [Bug 3464428]
+ regexp {[[:print:]]} \u0009
+} {0}
+test utf-21.10 {unicode print char in regc_locale.c} {
+ # [Bug 3464428]
+ regexp {[[:print:]]} \u0009
+} {0}
+test utf-21.11 {TclUniCharIsControl} {
+ # [Bug 3464428]
+ string is control \u00ad
+} {1}
+test utf-21.12 {unicode control char in regc_locale.c} {
+ # [Bug 3464428]
+ regexp {^[[:cntrl:]]$} \u00ad
+} {1}
+
+test utf-22.1 {TclUniCharIsWordChar} {
+ string wordend "xyz123_bar fg" 0
+} 10
+test utf-22.2 {TclUniCharIsWordChar} {
+ string wordend "x\u5080z123_bar\u203c fg" 0
+} 10
+
+test utf-23.1 {TclUniCharIsAlpha} {
+ # this returns 1 with Unicode 6 compliance
+ string is alpha \u021f\u0220
+} {1}
+test utf-23.2 {unicode alpha char in regc_locale.c} {
+ # this returns 1 with Unicode 6 compliance
+ regexp {^[[:alpha:]]+$} \u021f\u0220
+} {1}
+
+test utf-24.1 {TclUniCharIsDigit} {
+ # this returns 1 with Unicode 6 compliance
+ string is digit \u1040\uabf0
+} {1}
+test utf-24.2 {unicode digit char in regc_locale.c} {
+ # this returns 1 with Unicode 6 compliance
+ list [regexp {^[[:digit:]]+$} \u1040\uabf0] [regexp {^\d+$} \u1040\uabf0]
+} {1 1}
+
+test utf-24.3 {TclUniCharIsSpace} {
+ # this returns 1 with Unicode 6 compliance
+ string is space \u1680\u180e
+} {1}
+test utf-24.4 {unicode space char in regc_locale.c} {
+ # this returns 1 with Unicode 6 compliance
+ list [regexp {^[[:space:]]+$} \u1680\u180e] [regexp {^\s+$} \u1680\u180e]
+} {1 1}
+
+testConstraint teststringobj [llength [info commands teststringobj]]
+
+test utf-25.1 {Tcl_UniCharNcasecmp} -constraints teststringobj \
+ -setup {
+ testobj freeallvars
+ } \
+ -body {
+ teststringobj set 1 a
+ teststringobj set 2 b
+ teststringobj getunicode 1
+ teststringobj getunicode 2
+ string compare -nocase [teststringobj get 1] [teststringobj get 2]
+ } \
+ -cleanup {
+ testobj freeallvars
+ } \
+ -result -1
+test utf-25.2 {Tcl_UniCharNcasecmp} -constraints teststringobj \
+ -setup {
+ testobj freeallvars
+ } \
+ -body {
+ teststringobj set 1 b
+ teststringobj set 2 a
+ teststringobj getunicode 1
+ teststringobj getunicode 2
+ string compare -nocase [teststringobj get 1] [teststringobj get 2]
+ } \
+ -cleanup {
+ testobj freeallvars
+ } \
+ -result 1
+test utf-25.3 {Tcl_UniCharNcasecmp} -constraints teststringobj \
+ -setup {
+ testobj freeallvars
+ } \
+ -body {
+ teststringobj set 1 B
+ teststringobj set 2 a
+ teststringobj getunicode 1
+ teststringobj getunicode 2
+ string compare -nocase [teststringobj get 1] [teststringobj get 2]
+ } \
+ -cleanup {
+ testobj freeallvars
+ } \
+ -result 1
+
+test utf-25.4 {Tcl_UniCharNcasecmp} -constraints teststringobj \
+ -setup {
+ testobj freeallvars
+ } \
+ -body {
+ teststringobj set 1 aBcB
+ teststringobj set 2 abca
+ teststringobj getunicode 1
+ teststringobj getunicode 2
+ string compare -nocase [teststringobj get 1] [teststringobj get 2]
+ } \
+ -cleanup {
+ testobj freeallvars
+ } \
+ -result 1
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/util.test b/pkgs/msgcat/tests/util.test
new file mode 100644
index 0000000..1da533c
--- /dev/null
+++ b/pkgs/msgcat/tests/util.test
@@ -0,0 +1,4024 @@
+# This file is a Tcl script to test the code in the file tclUtil.c.
+# This file is organized in the standard fashion for Tcl tests.
+#
+# Copyright (c) 1995-1998 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint controversialNaN 1
+testConstraint testdstring [llength [info commands testdstring]]
+testConstraint testconcatobj [llength [info commands testconcatobj]]
+testConstraint testdoubledigits [llength [info commands testdoubledigits]]
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+ variable ieeeValues
+ binary scan [binary format dd -1.0 1.0] c* c
+ switch -exact -- $c {
+ {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+ # little endian
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+ ieeeValues(-Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+ ieeeValues(-Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+ ieeeValues(-Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+ ieeeValues(+Normal)
+ binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+ ieeeValues(+Infinity)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+ ieeeValues(NaN)
+ binary scan \x00\x00\x00\x00\x00\x00\xf8\xff d \
+ ieeeValues(-NaN)
+ binary scan \xef\xcd\xab\x89\x67\x45\xfb\xff d \
+ ieeeValues(-NaN(3456789abcdef))
+ set ieeeValues(littleEndian) 1
+ return 1
+ }
+ {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+ binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Infinity)
+ binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Normal)
+ binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-Subnormal)
+ binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-0)
+ binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+0)
+ binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Subnormal)
+ binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Normal)
+ binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(+Infinity)
+ binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(NaN)
+ binary scan \xff\xf8\x00\x00\x00\x00\x00\x00 d \
+ ieeeValues(-NaN)
+ binary scan \xff\xfb\x45\x67\x89\xab\xcd\xef d \
+ ieeeValues(-NaN(3456789abcdef))
+ set ieeeValues(littleEndian) 0
+ return 1
+ }
+ default {
+ return 0
+ }
+ }
+}
+testConstraint ieeeFloatingPoint [testIEEE]
+
+proc convertDouble { x } {
+ variable ieeeValues
+ if { $ieeeValues(littleEndian) } {
+ binary scan [binary format w $x] d result
+ } else {
+ binary scan [binary format W $x] d result
+ }
+ return $result
+}
+
+proc verdonk_test {sig binexp shouldbe exp} {
+ regexp {([-+]?)([0-9a-f]+)} $sig -> signum sig
+ scan $sig %llx sig
+ if {$signum eq {-}} {
+ set signum [expr 1<<63]
+ } else {
+ set signum 0
+ }
+ regexp {E([-+]?[0-9]+)} $binexp -> binexp
+ set word [expr {$signum | (($binexp + 0x3ff)<<52)|($sig & ~(1<<52))}]
+ binary scan [binary format w $word] q double
+ regexp {([-+])(\d+)_(\d+)\&} $shouldbe -> signum digits1 digits2
+ regexp {E([-+]\d+)} $exp -> decexp
+ incr decexp [expr {[string length $digits1] - 1}]
+ lassign [testdoubledigits $double [string length $digits1] e] \
+ outdigits decpt outsign
+ if {[string index $digits2 0] >= 5} {
+ incr digits1
+ }
+ if {$outsign != $signum || $outdigits != $digits1 || $decpt != $decexp} {
+ return -code error "result is ${outsign}0.${outdigits}E$decpt\
+ should be ${signum}0.${digits1}E$decexp"
+ }
+}
+
+test util-1.1 {TclFindElement procedure - binary element in middle of list} {
+ lindex {0 foo\x00help 1} 1
+} "foo\x00help"
+test util-1.2 {TclFindElement procedure - binary element at end of list} {
+ lindex {0 foo\x00help} 1
+} "foo\x00help"
+
+test util-2.1 {TclCopyAndCollapse procedure - normal string} {
+ lindex {0 foo} 1
+} {foo}
+test util-2.2 {TclCopyAndCollapse procedure - string with backslashes} {
+ lindex {0 foo\n\x00help 1} 1
+} "foo\n\x00help"
+
+test util-3.1 {Tcl_ScanCountedElement procedure - don't leave unmatched braces} {
+ # This test checks for a very tricky feature. Any list element
+ # generated with Tcl_ScanCountedElement and Tcl_ConvertElement must
+ # have the property that it can be enclosing in curly braces to make
+ # an embedded sub-list. If this property doesn't hold, then
+ # Tcl_DStringStartSublist doesn't work.
+ set x {}
+ lappend x "# \\\{ \\"
+ concat $x [llength "{$x}"]
+} {\#\ \\\{\ \\ 1}
+test util-3.2 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+ list # # a
+} {{#} # a}
+test util-3.3 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+ list #\{ # a
+} {\#\{ # a}
+test util-3.4 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+ proc # {} {return #}
+ set result [eval [list #]]
+ rename # {}
+ set result
+} {#}
+test util-3.4.1 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+ proc # {} {return #}
+ set cmd [list #]
+ append cmd "" ;# force string rep generation
+ set result [eval $cmd]
+ rename # {}
+ set result
+} {#}
+test util-3.5 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+ proc #\{ {} {return #}
+ set result [eval [list #\{]]
+ rename #\{ {}
+ set result
+} {#}
+test util-3.5.1 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+ proc #\{ {} {return #}
+ set cmd [list #\{]
+ append cmd "" ;# force string rep generation
+ set result [eval $cmd]
+ rename #\{ {}
+ set result
+} {#}
+test util-3.6 {Tcl_ConvertElement, Bug 3371644} {
+ interp create #\\
+ interp alias {} x #\\ concat
+ interp target {} x ;# Crash if bug not fixed
+ interp delete #\\
+} {}
+
+test util-4.1 {Tcl_ConcatObj - backslash-space at end of argument} {
+ concat a {b\ } c
+} {a b\ c}
+test util-4.2 {Tcl_ConcatObj - backslash-space at end of argument} {
+ concat a {b\ } c
+} {a b\ c}
+test util-4.3 {Tcl_ConcatObj - backslash-space at end of argument} {
+ concat a {b\\ } c
+} {a b\\ c}
+test util-4.4 {Tcl_ConcatObj - backslash-space at end of argument} {
+ concat a {b } c
+} {a b c}
+test util-4.5 {Tcl_ConcatObj - backslash-space at end of argument} {
+ concat a { } c
+} {a c}
+test util-4.6 {Tcl_ConcatObj - utf-8 sequence with "whitespace" char} {
+ # Check for Bug #227512. If this violates C isspace, then it returns \xc3.
+ concat \xe0
+} \xe0
+test util-4.7 {Tcl_ConcatObj - refCount safety} testconcatobj {
+ # Check for Bug #1447328 (actually, bugs in its original "fix"). One of the
+ # symptoms was Bug #2055782.
+ testconcatobj
+} {}
+
+proc Wrapper_Tcl_StringMatch {pattern string} {
+ # Forces use of Tcl_StringMatch, not Tcl_UniCharCaseMatch
+ switch -glob -- $string $pattern {return 1} default {return 0}
+}
+test util-5.1 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch ab*c abc
+} 1
+test util-5.2 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch ab**c abc
+} 1
+test util-5.3 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch ab* abcdef
+} 1
+test util-5.4 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch *c abc
+} 1
+test util-5.5 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch *3*6*9 0123456789
+} 1
+test util-5.6 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch *3*6*9 01234567890
+} 0
+test util-5.7 {Tcl_StringMatch: UTF-8} {
+ Wrapper_Tcl_StringMatch *u \u4e4fu
+} 1
+test util-5.8 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch a?c abc
+} 1
+test util-5.9 {Tcl_StringMatch: UTF-8} {
+ # skip one character in string
+ Wrapper_Tcl_StringMatch a?c a\u4e4fc
+} 1
+test util-5.10 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch a??c abc
+} 0
+test util-5.11 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch ?1??4???8? 0123456789
+} 1
+test util-5.12 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {[abc]bc} abc
+} 1
+test util-5.13 {Tcl_StringMatch: UTF-8} {
+ # string += Tcl_UtfToUniChar(string, &ch);
+ Wrapper_Tcl_StringMatch "\[\u4e4fxy\]bc" "\u4e4fbc"
+} 1
+test util-5.14 {Tcl_StringMatch} {
+ # if ((*pattern == ']') || (*pattern == '\0'))
+ # badly formed pattern
+ Wrapper_Tcl_StringMatch {[]} {[]}
+} 0
+test util-5.15 {Tcl_StringMatch} {
+ # if ((*pattern == ']') || (*pattern == '\0'))
+ # badly formed pattern
+ Wrapper_Tcl_StringMatch {[} {[}
+} 0
+test util-5.16 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {a[abc]c} abc
+} 1
+test util-5.17 {Tcl_StringMatch: UTF-8} {
+ # pattern += Tcl_UtfToUniChar(pattern, &endChar);
+ # get 1 UTF-8 character
+ Wrapper_Tcl_StringMatch "a\[a\u4e4fc]c" "a\u4e4fc"
+} 1
+test util-5.18 {Tcl_StringMatch: UTF-8} {
+ # pattern += Tcl_UtfToUniChar(pattern, &endChar);
+ # proper advance: wrong answer would match on UTF trail byte of \u4e4f
+ Wrapper_Tcl_StringMatch {a[a\u4e4fc]c} [bytestring a\u008fc]
+} 0
+test util-5.19 {Tcl_StringMatch: UTF-8} {
+ # pattern += Tcl_UtfToUniChar(pattern, &endChar);
+ # proper advance.
+ Wrapper_Tcl_StringMatch {a[a\u4e4fc]c} "acc"
+} 1
+test util-5.20 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {a[xyz]c} abc
+} 0
+test util-5.21 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {12[2-7]45} 12345
+} 1
+test util-5.22 {Tcl_StringMatch: UTF-8 range} {
+ Wrapper_Tcl_StringMatch "\[\u4e00-\u4e4f]" "0"
+} 0
+test util-5.23 {Tcl_StringMatch: UTF-8 range} {
+ Wrapper_Tcl_StringMatch "\[\u4e00-\u4e4f]" "\u4e33"
+} 1
+test util-5.24 {Tcl_StringMatch: UTF-8 range} {
+ Wrapper_Tcl_StringMatch "\[\u4e00-\u4e4f]" "\uff08"
+} 0
+test util-5.25 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {12[ab2-4cd]45} 12345
+} 1
+test util-5.26 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {12[ab2-4cd]45} 12b45
+} 1
+test util-5.27 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {12[ab2-4cd]45} 12d45
+} 1
+test util-5.28 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {12[ab2-4cd]45} 12145
+} 0
+test util-5.29 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {12[ab2-4cd]45} 12545
+} 0
+test util-5.30 {Tcl_StringMatch: forwards range} {
+ Wrapper_Tcl_StringMatch {[k-w]} "z"
+} 0
+test util-5.31 {Tcl_StringMatch: forwards range} {
+ Wrapper_Tcl_StringMatch {[k-w]} "w"
+} 1
+test util-5.32 {Tcl_StringMatch: forwards range} {
+ Wrapper_Tcl_StringMatch {[k-w]} "r"
+} 1
+test util-5.33 {Tcl_StringMatch: forwards range} {
+ Wrapper_Tcl_StringMatch {[k-w]} "k"
+} 1
+test util-5.34 {Tcl_StringMatch: forwards range} {
+ Wrapper_Tcl_StringMatch {[k-w]} "a"
+} 0
+test util-5.35 {Tcl_StringMatch: reverse range} {
+ Wrapper_Tcl_StringMatch {[w-k]} "z"
+} 0
+test util-5.36 {Tcl_StringMatch: reverse range} {
+ Wrapper_Tcl_StringMatch {[w-k]} "w"
+} 1
+test util-5.37 {Tcl_StringMatch: reverse range} {
+ Wrapper_Tcl_StringMatch {[w-k]} "r"
+} 1
+test util-5.38 {Tcl_StringMatch: reverse range} {
+ Wrapper_Tcl_StringMatch {[w-k]} "k"
+} 1
+test util-5.39 {Tcl_StringMatch: reverse range} {
+ Wrapper_Tcl_StringMatch {[w-k]} "a"
+} 0
+test util-5.40 {Tcl_StringMatch: skip correct number of ']'} {
+ Wrapper_Tcl_StringMatch {[A-]x} Ax
+} 0
+test util-5.41 {Tcl_StringMatch: skip correct number of ']'} {
+ Wrapper_Tcl_StringMatch {[A-]]x} Ax
+} 1
+test util-5.42 {Tcl_StringMatch: skip correct number of ']'} {
+ Wrapper_Tcl_StringMatch {[A-]]x} \ue1x
+} 0
+test util-5.43 {Tcl_StringMatch: skip correct number of ']'} {
+ Wrapper_Tcl_StringMatch \[A-]\ue1]x \ue1x
+} 1
+test util-5.44 {Tcl_StringMatch: skip correct number of ']'} {
+ Wrapper_Tcl_StringMatch {[A-]h]x} hx
+} 1
+test util-5.45 {Tcl_StringMatch} {
+ # if (*pattern == '\0')
+ # badly formed pattern, still treats as a set
+ Wrapper_Tcl_StringMatch {[a} a
+} 1
+test util-5.46 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {a\*b} a*b
+} 1
+test util-5.47 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {a\*b} ab
+} 0
+test util-5.48 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch {a\*\?\[\]\\\x} "a*?\[\]\\x"
+} 1
+test util-5.49 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch ** ""
+} 1
+test util-5.50 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch *. ""
+} 0
+test util-5.51 {Tcl_StringMatch} {
+ Wrapper_Tcl_StringMatch "" ""
+} 1
+
+test util-6.1 {Tcl_PrintDouble - using tcl_precision} -setup {
+ set old_precision $::tcl_precision
+ set ::tcl_precision 12
+} -body {
+ concat x[expr 1.4]
+} -cleanup {
+ set ::tcl_precision $old_precision
+} -result {x1.4}
+test util-6.2 {Tcl_PrintDouble - using tcl_precision} -setup {
+ set old_precision $::tcl_precision
+ set ::tcl_precision 12
+} -body {
+ concat x[expr 1.39999999999]
+} -cleanup {
+ set ::tcl_precision $old_precision
+} -result {x1.39999999999}
+test util-6.3 {Tcl_PrintDouble - using tcl_precision} -setup {
+ set old_precision $::tcl_precision
+ set ::tcl_precision 12
+} -body {
+ concat x[expr 1.399999999999]
+} -cleanup {
+ set ::tcl_precision $old_precision
+} -result {x1.4}
+test util-6.4 {Tcl_PrintDouble - using tcl_precision} -setup {
+ set old_precision $::tcl_precision
+ set ::tcl_precision 5
+} -body {
+ concat x[expr 1.123412341234]
+} -cleanup {
+ set tcl_precision $old_precision
+} -result {x1.1234}
+test util-6.5 {Tcl_PrintDouble - make sure there's a decimal point} {
+ concat x[expr 2.0]
+} {x2.0}
+test util-6.6 {Tcl_PrintDouble - make sure there's a decimal point} {
+ concat x[expr 3.0e98]
+} {x3e+98}
+
+test util-7.1 {TclPrecTraceProc - unset callbacks} -setup {
+ set old_precision $::tcl_precision
+} -body {
+ set tcl_precision 7
+ set x $tcl_precision
+ unset tcl_precision
+ list $x $tcl_precision
+} -cleanup {
+ set ::tcl_precision $old_precision
+} -result {7 7}
+test util-7.2 {TclPrecTraceProc - read traces, sharing among interpreters} -setup {
+ set old_precision $::tcl_precision
+} -body {
+ set tcl_precision 12
+ interp create child
+ set x [child eval set tcl_precision]
+ child eval {set tcl_precision 6}
+ interp delete child
+ list $x $tcl_precision
+} -cleanup {
+ set ::tcl_precision $old_precision
+} -result {12 6}
+test util-7.3 {TclPrecTraceProc - write traces, safe interpreters} -setup {
+ set old_precision $::tcl_precision
+} -body {
+ set tcl_precision 12
+ interp create -safe child
+ set x [child eval {
+ list [catch {set tcl_precision 8} msg] $msg
+ }]
+ interp delete child
+ list $x $tcl_precision
+} -cleanup {
+ set ::tcl_precision $old_precision
+} -result {{1 {can't set "tcl_precision": can't modify precision from a safe interpreter}} 12}
+test util-7.4 {TclPrecTraceProc - write traces, bogus values} -setup {
+ set old_precision $::tcl_precision
+} -body {
+ set tcl_precision 12
+ list [catch {set tcl_precision abc} msg] $msg $tcl_precision
+} -cleanup {
+ set ::tcl_precision $old_precision
+} -result {1 {can't set "tcl_precision": improper value for precision} 12}
+
+# This test always succeeded in the C locale anyway...
+test util-8.1 {TclNeedSpace - correct UTF8 handling} {
+ # Bug 411825
+ # Note that this test relies on the fact that
+ # [interp target] calls on Tcl_AppendElement()
+ # which calls on TclNeedSpace(). If [interp target]
+ # is ever updated, this test will no longer test
+ # TclNeedSpace.
+ interp create \u5420
+ interp create [list \u5420 foo]
+ interp alias {} fooset [list \u5420 foo] set
+ set result [interp target {} fooset]
+ interp delete \u5420
+ set result
+} "\u5420 foo"
+test util-8.2 {TclNeedSpace - correct UTF8 handling} testdstring {
+ # Bug 411825
+ # This tests the same bug as the previous test, but
+ # should be more future-proof, as the DString
+ # operations will likely continue to call TclNeedSpace
+ testdstring free
+ testdstring append \u5420 -1
+ testdstring element foo
+ llength [testdstring get]
+} 2
+test util-8.3 {TclNeedSpace - correct UTF8 handling} testdstring {
+ # Bug 411825 - new variant reported by Dossy Shiobara
+ testdstring free
+ testdstring append \u00A0 -1
+ testdstring element foo
+ llength [testdstring get]
+} 2
+test util-8.4 {TclNeedSpace - correct UTF8 handling} testdstring {
+ # Another bug uncovered while fixing 411825
+ testdstring free
+ testdstring append {\ } -1
+ testdstring append \{ -1
+ testdstring element foo
+ llength [testdstring get]
+} 2
+test util-8.5 {TclNeedSpace - correct UTF8 handling} testdstring {
+ # Note that in this test TclNeedSpace actually gets it wrong,
+ # claiming we need a space when we really do not. Extra space
+ # between list elements is harmless though, and better to have
+ # extra space in really weird string reps of lists, than to
+ # invest the effort required to make TclNeedSpace foolproof.
+ testdstring free
+ testdstring append {\\ } -1
+ testdstring element foo
+ list [llength [testdstring get]] [string length [testdstring get]]
+} {2 7}
+test util-8.6 {TclNeedSpace - correct UTF8 handling} testdstring {
+ # Another example of TclNeedSpace harmlessly getting it wrong.
+ testdstring free
+ testdstring append {\\ } -1
+ testdstring append \{ -1
+ testdstring element foo
+ testdstring append \} -1
+ list [llength [testdstring get]] [string length [testdstring get]]
+} {2 9}
+
+test util-9.0.0 {TclGetIntForIndex} {
+ string index abcd 0
+} a
+test util-9.0.1 {TclGetIntForIndex} {
+ string index abcd 0x0
+} a
+test util-9.0.2 {TclGetIntForIndex} {
+ string index abcd -0x0
+} a
+test util-9.0.3 {TclGetIntForIndex} {
+ string index abcd { 0 }
+} a
+test util-9.0.4 {TclGetIntForIndex} {
+ string index abcd { 0x0 }
+} a
+test util-9.0.5 {TclGetIntForIndex} {
+ string index abcd { -0x0 }
+} a
+test util-9.0.6 {TclGetIntForIndex} {
+ string index abcd 01
+} b
+test util-9.0.7 {TclGetIntForIndex} {
+ string index abcd { 01 }
+} b
+test util-9.1.0 {TclGetIntForIndex} {
+ string index abcd 3
+} d
+test util-9.1.1 {TclGetIntForIndex} {
+ string index abcd { 3 }
+} d
+test util-9.1.2 {TclGetIntForIndex} {
+ string index abcdefghijk 0xa
+} k
+test util-9.1.3 {TclGetIntForIndex} {
+ string index abcdefghijk { 0xa }
+} k
+test util-9.2.0 {TclGetIntForIndex} {
+ string index abcd end
+} d
+test util-9.2.1 {TclGetIntForIndex} -body {
+ string index abcd { end}
+} -returnCodes error -match glob -result *
+test util-9.2.2 {TclGetIntForIndex} -body {
+ string index abcd {end }
+} -returnCodes error -match glob -result *
+test util-9.3 {TclGetIntForIndex} {
+ # Deprecated
+ string index abcd en
+} d
+test util-9.4 {TclGetIntForIndex} {
+ # Deprecated
+ string index abcd e
+} d
+test util-9.5.0 {TclGetIntForIndex} {
+ string index abcd end-1
+} c
+test util-9.5.1 {TclGetIntForIndex} {
+ string index abcd {end-1 }
+} c
+test util-9.5.2 {TclGetIntForIndex} -body {
+ string index abcd { end-1}
+} -returnCodes error -match glob -result *
+test util-9.6 {TclGetIntForIndex} {
+ string index abcd end+-1
+} c
+test util-9.7 {TclGetIntForIndex} {
+ string index abcd end+1
+} {}
+test util-9.8 {TclGetIntForIndex} {
+ string index abcd end--1
+} {}
+test util-9.9.0 {TclGetIntForIndex} {
+ string index abcd 0+0
+} a
+test util-9.9.1 {TclGetIntForIndex} {
+ string index abcd { 0+0 }
+} a
+test util-9.10 {TclGetIntForIndex} {
+ string index abcd 0-0
+} a
+test util-9.11 {TclGetIntForIndex} {
+ string index abcd 1+0
+} b
+test util-9.12 {TclGetIntForIndex} {
+ string index abcd 1-0
+} b
+test util-9.13 {TclGetIntForIndex} {
+ string index abcd 1+1
+} c
+test util-9.14 {TclGetIntForIndex} {
+ string index abcd 1-1
+} a
+test util-9.15 {TclGetIntForIndex} {
+ string index abcd -1+2
+} b
+test util-9.16 {TclGetIntForIndex} {
+ string index abcd -1--2
+} b
+test util-9.17 {TclGetIntForIndex} {
+ string index abcd { -1+2 }
+} b
+test util-9.18 {TclGetIntForIndex} {
+ string index abcd { -1--2 }
+} b
+test util-9.19 {TclGetIntForIndex} -body {
+ string index a {}
+} -returnCodes error -match glob -result *
+test util-9.20 {TclGetIntForIndex} -body {
+ string index a { }
+} -returnCodes error -match glob -result *
+test util-9.21 {TclGetIntForIndex} -body {
+ string index a " \r\t\n"
+} -returnCodes error -match glob -result *
+test util-9.22 {TclGetIntForIndex} -body {
+ string index a +
+} -returnCodes error -match glob -result *
+test util-9.23 {TclGetIntForIndex} -body {
+ string index a -
+} -returnCodes error -match glob -result *
+test util-9.24 {TclGetIntForIndex} -body {
+ string index a x
+} -returnCodes error -match glob -result *
+test util-9.25 {TclGetIntForIndex} -body {
+ string index a +x
+} -returnCodes error -match glob -result *
+test util-9.26 {TclGetIntForIndex} -body {
+ string index a -x
+} -returnCodes error -match glob -result *
+test util-9.27 {TclGetIntForIndex} -body {
+ string index a 0y
+} -returnCodes error -match glob -result *
+test util-9.28 {TclGetIntForIndex} -body {
+ string index a 1*
+} -returnCodes error -match glob -result *
+test util-9.29 {TclGetIntForIndex} -body {
+ string index a 0+
+} -returnCodes error -match glob -result *
+test util-9.30 {TclGetIntForIndex} -body {
+ string index a {0+ }
+} -returnCodes error -match glob -result *
+test util-9.31 {TclGetIntForIndex} -body {
+ string index a 0x
+} -returnCodes error -match glob -result *
+test util-9.32 {TclGetIntForIndex} -body {
+ string index a 0x1FFFFFFFF+0
+} -returnCodes error -match glob -result *
+test util-9.33 {TclGetIntForIndex} -body {
+ string index a 100000000000+0
+} -returnCodes error -match glob -result *
+test util-9.34 {TclGetIntForIndex} -body {
+ string index a 1.0
+} -returnCodes error -match glob -result *
+test util-9.35 {TclGetIntForIndex} -body {
+ string index a 1e23
+} -returnCodes error -match glob -result *
+test util-9.36 {TclGetIntForIndex} -body {
+ string index a 1.5e2
+} -returnCodes error -match glob -result *
+test util-9.37 {TclGetIntForIndex} -body {
+ string index a 0+x
+} -returnCodes error -match glob -result *
+test util-9.38 {TclGetIntForIndex} -body {
+ string index a 0+0x
+} -returnCodes error -match glob -result *
+test util-9.39 {TclGetIntForIndex} -body {
+ string index a 0+0xg
+} -returnCodes error -match glob -result *
+test util-9.40 {TclGetIntForIndex} -body {
+ string index a 0+0xg
+} -returnCodes error -match glob -result *
+test util-9.41 {TclGetIntForIndex} -body {
+ string index a 0+1.0
+} -returnCodes error -match glob -result *
+test util-9.42 {TclGetIntForIndex} -body {
+ string index a 0+1e2
+} -returnCodes error -match glob -result *
+test util-9.43 {TclGetIntForIndex} -body {
+ string index a 0+1.5e1
+} -returnCodes error -match glob -result *
+test util-9.44 {TclGetIntForIndex} -body {
+ string index a 0+1000000000000
+} -returnCodes error -match glob -result *
+
+test util-10.1 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x0000000000000000
+} {0.0}
+test util-10.2 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x8000000000000000
+} {-0.0}
+test util-10.3 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x7ef754e31cd072da
+} {4e+303}
+test util-10.4 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xd08afcef51f0fb5f
+} {-1e+80}
+test util-10.5 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x7ed754e31cd072da
+} {1e+303}
+test util-10.6 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xfee754e31cd072da
+} {-2e+303}
+test util-10.7 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x0afe07b27dd78b14
+} {1e-255}
+test util-10.8 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x93ae29e9c56687fe
+} {-7e-214}
+test util-10.9 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x376be03d0bf225c7
+} {1e-41}
+test util-10.10 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xa0ca2fe76a3f9475
+} {-1e-150}
+test util-10.11 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x7fa9a2028368022e
+} {9e+306}
+test util-10.12 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xdfc317e5ef3ab327
+} {-2e+153}
+test util-10.13 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x5fd317e5ef3ab327
+} {4e+153}
+test util-10.14 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xdfe317e5ef3ab327
+} {-8e+153}
+test util-10.15 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x00feb8e84fa0b278
+} {7e-304}
+test util-10.16 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x8133339131c46f8b
+} {-7e-303}
+test util-10.17 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x35dc0f92a6276c9d
+} {3e-49}
+test util-10.18 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xa445ce1f143d7ad2
+} {-6e-134}
+test util-10.19 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x2d2c0794d9d40e96
+} {4.3e-91}
+test util-10.20 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xad3c0794d9d40e96
+} {-8.6e-91}
+test util-10.21 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x30ecd5bee57763e6
+} {5.1e-73}
+test util-10.22 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x68ad1c26db7d0dae
+} {1.7e+196}
+test util-10.23 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbfa3f7ced916872b
+} {-0.039}
+test util-10.24 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x64b7d93193f78fc6
+} {1.51e+177}
+test util-10.25 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x98ea82a1631eeb30
+} {-1.19e-188}
+test util-10.26 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xd216c309024bab4b
+} {-2.83e+87}
+test util-10.27 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x0dfdbbac6f83a821
+} {2.7869147e-241}
+test util-10.28 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xdadc569e968e0944
+} {-4.91080654e+129}
+test util-10.29 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x5acc569e968e0944
+} {2.45540327e+129}
+test util-10.30 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xab5fc575867314ee
+} {-9.078555839e-100}
+test util-10.31 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xdabc569e968e0944
+} {-1.227701635e+129}
+test util-10.32 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x2b6fc575867314ee
+} {1.8157111678e-99}
+test util-10.33 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xb3b8bf7e7fa6f02a
+} {-1.5400733123779e-59}
+test util-10.34 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xcd83de005bd620df
+} {-2.6153245263757307e+65}
+test util-10.35 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x6cdf92bacb3cb40c
+} {2.7210404151224248e+216}
+test util-10.36 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xecef92bacb3cb40c
+} {-5.4420808302448496e+216}
+test util-10.37 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x49342dbf25096cf5
+} {4.5e+44}
+test util-10.38 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xd06afcef51f0fb5f
+} {-2.5e+79}
+test util-10.39 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x49002498ea6df0c4
+} {4.5e+43}
+test util-10.40 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xfeb754e31cd072da
+} {-2.5e+302}
+test util-10.41 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x1d22deac01e2b4f7
+} {2.5e-168}
+test util-10.42 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xaccb1df536c13eee
+} {-6.5e-93}
+test util-10.43 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3650711fed5b19a4
+} {4.5e-47}
+test util-10.44 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xb6848d67e8b1e00d
+} {-4.5e-46}
+test util-10.45 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x4bac8c574c0c6be7
+} {3.5e+56}
+test util-10.46 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xccd756183c147514
+} {-1.5e+62}
+test util-10.47 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x4ca2ab469676c410
+} {1.5e+61}
+test util-10.48 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xcf5539684e774b48
+} {-1.5e+74}
+test util-10.49 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x2e12e5f5dfa4fe9d
+} {9.5e-87}
+test util-10.50 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x8b9bdc2417bf7787
+} {-9.5e-253}
+test util-10.51 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x00eeb8e84fa0b278
+} {3.5e-304}
+test util-10.52 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xadde3cbc9907fdc8
+} {-9.5e-88}
+test util-10.53 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x2bb0ad836f269a17
+} {3.05e-98}
+test util-10.54 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x950b39ae1909c31b
+} {-2.65e-207}
+test util-10.55 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x1bfb2ab18615fcc6
+} {6.865e-174}
+test util-10.56 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x98f3e1f90a573064
+} {-1.785e-188}
+test util-10.57 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x5206c309024bab4b
+} {1.415e+87}
+test util-10.58 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xcc059bd3ad46e346
+} {-1.6955e+58}
+test util-10.59 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x47bdf4170f0fdecc
+} {3.9815e+37}
+test util-10.60 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x59e7e1e0f1c7a4ac
+} {1.263005e+125}
+test util-10.61 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xda1dda592e398dd7
+} {-1.263005e+126}
+test util-10.62 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xdc4e597c0b94b7ae
+} {-4.4118455e+136}
+test util-10.63 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x5aac569e968e0944
+} {6.138508175e+128}
+test util-10.64 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xdabc569e968e0944
+} {-1.227701635e+129}
+test util-10.65 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x6ce7ae0c186d8709
+} {4.081560622683637e+216}
+test util-10.66 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x44b52d02c7e14af7
+} {1.0000000000000001e+23}
+test util-10.67 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc589d971e4fe8402
+} {-1e+27}
+test util-10.68 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x4599d971e4fe8402
+} {2e+27}
+test util-10.69 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc5a9d971e4fe8402
+} {-4e+27}
+test util-10.70 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3e45798ee2308c3a
+} {1e-8}
+test util-10.71 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbe55798ee2308c3a
+} {-2e-8}
+test util-10.72 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3e65798ee2308c3a
+} {4e-8}
+test util-10.73 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbabef2d0f5da7dd9
+} {-1e-25}
+test util-10.74 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x44da784379d99db4
+} {5e+23}
+test util-10.75 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc4fa784379d99db4
+} {-2e+24}
+test util-10.76 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x4503da329b633647
+} {3e+24}
+test util-10.77 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc54cf389cd46047d
+} {-7e+25}
+test util-10.78 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3fc999999999999a
+} {0.2}
+test util-10.79 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbfd3333333333333
+} {-0.3}
+test util-10.80 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3cf6849b86a12b9b
+} {5e-15}
+test util-10.81 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbd16849b86a12b9b
+} {-2e-14}
+test util-10.82 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3b87ccfc73126788
+} {6.3e-22}
+test util-10.83 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbbbdc03b8fd7016a
+} {-6.3e-21}
+test util-10.84 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3fa3f7ced916872b
+} {0.039}
+test util-10.85 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x460b297cad9f70b6
+} {2.69e+29}
+test util-10.86 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc61b297cad9f70b6
+} {-5.38e+29}
+test util-10.87 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3adcdc06b20ef183
+} {3.73e-25}
+test util-10.88 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x45fb297cad9f70b6
+} {1.345e+29}
+test util-10.89 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc60b297cad9f70b6
+} {-2.69e+29}
+test util-10.90 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbc050a246ecd44f3
+} {-1.4257e-19}
+test util-10.91 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbec19b96f36ec68b
+} {-2.09901e-6}
+test util-10.92 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3dcc06d366394441
+} {5.0980203373e-11}
+test util-10.93 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc79f58ac4db68c90
+} {-1.04166211811e+37}
+test util-10.94 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x4569d971e4fe8402
+} {2.5e+26}
+test util-10.95 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc50dc74be914d16b
+} {-4.5e+24}
+test util-10.96 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x4534adf4b7320335
+} {2.5e+25}
+test util-10.97 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc54ae22487c1042b
+} {-6.5e+25}
+test util-10.98 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3c987fe49aab41e0
+} {8.5e-17}
+test util-10.99 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbc2f5c05e4b23fd7
+} {-8.5e-19}
+test util-10.100 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3d5faa7ab552a552
+} {4.5e-13}
+test util-10.101 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbdbb7cdfd9d7bdbb
+} {-2.5e-11}
+test util-10.102 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x44f3da329b633647
+} {1.5e+24}
+test util-10.103 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc53cf389cd46047d
+} {-3.5e+25}
+test util-10.104 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x454f04ef12cb04cf
+} {7.5e+25}
+test util-10.105 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc55f04ef12cb04cf
+} {-1.5e+26}
+test util-10.106 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3fc3333333333333
+} {0.15}
+test util-10.107 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbdb07e1fe91b0b70
+} {-1.5e-11}
+test util-10.108 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3de49da7e361ce4c
+} {1.5e-10}
+test util-10.109 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbe19c511dc3a41df
+} {-1.5e-9}
+test util-10.110 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc5caa83d74267822
+} {-1.65e+28}
+test util-10.111 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x4588f1d5969453de
+} {9.65e+26}
+test util-10.112 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3b91d9bd564dcda6
+} {9.45e-22}
+test util-10.113 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbcfa58973ecbede6
+} {-5.85e-15}
+test util-10.114 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x45eb297cad9f70b6
+} {6.725e+28}
+test util-10.115 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc5fb297cad9f70b6
+} {-1.345e+29}
+test util-10.116 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3accdc06b20ef183
+} {1.865e-25}
+test util-10.117 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xbd036071dcae4565
+} {-8.605e-15}
+test util-10.118 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x462cb968d297dde8
+} {1.137885e+30}
+test util-10.119 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0xc661f3e1839eeab1
+} {-1.137885e+31}
+test util-10.120 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x474e9cec176c96f8
+} {3.179033335e+35}
+test util-10.121 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x3dbc06d366394441
+} {2.54901016865e-11}
+test util-10.122 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+ convertDouble 0x478f58ac4db68c90
+} {5.20831059055e+36}
+
+test util-11.1 {Tcl_PrintDouble - scaling} {
+ expr 1.1e-5
+} {1.1e-5}
+test util-11.2 {Tcl_PrintDouble - scaling} {
+ expr 1.1e-4
+} {0.00011}
+test util-11.3 {Tcl_PrintDouble - scaling} {
+ expr 1.1e-3
+} {0.0011}
+test util-11.4 {Tcl_PrintDouble - scaling} {
+ expr 1.1e-2
+} {0.011}
+test util-11.5 {Tcl_PrintDouble - scaling} {
+ expr 1.1e-1
+} {0.11}
+test util-11.6 {Tcl_PrintDouble - scaling} {
+ expr 1.1e0
+} {1.1}
+test util-11.7 {Tcl_PrintDouble - scaling} {
+ expr 1.1e1
+} {11.0}
+test util-11.8 {Tcl_PrintDouble - scaling} {
+ expr 1.1e2
+} {110.0}
+test util-11.9 {Tcl_PrintDouble - scaling} {
+ expr 1.1e3
+} {1100.0}
+test util-11.10 {Tcl_PrintDouble - scaling} {
+ expr 1.1e4
+} {11000.0}
+test util-11.11 {Tcl_PrintDouble - scaling} {
+ expr 1.1e5
+} {110000.0}
+test util-11.12 {Tcl_PrintDouble - scaling} {
+ expr 1.1e6
+} {1100000.0}
+test util-11.13 {Tcl_PrintDouble - scaling} {
+ expr 1.1e7
+} {11000000.0}
+test util-11.14 {Tcl_PrintDouble - scaling} {
+ expr 1.1e8
+} {110000000.0}
+test util-11.15 {Tcl_PrintDouble - scaling} {
+ expr 1.1e9
+} {1100000000.0}
+test util-11.16 {Tcl_PrintDouble - scaling} {
+ expr 1.1e10
+} {11000000000.0}
+test util-11.17 {Tcl_PrintDouble - scaling} {
+ expr 1.1e11
+} {110000000000.0}
+test util-11.18 {Tcl_PrintDouble - scaling} {
+ expr 1.1e12
+} {1100000000000.0}
+test util-11.19 {Tcl_PrintDouble - scaling} {
+ expr 1.1e13
+} {11000000000000.0}
+test util-11.20 {Tcl_PrintDouble - scaling} {
+ expr 1.1e14
+} {110000000000000.0}
+test util-11.21 {Tcl_PrintDouble - scaling} {
+ expr 1.1e15
+} {1100000000000000.0}
+test util-11.22 {Tcl_PrintDouble - scaling} {
+ expr 1.1e16
+} {11000000000000000.0}
+test util-11.23 {Tcl_PrintDouble - scaling} {
+ expr 1.1e17
+} {1.1e+17}
+
+test util-12.1 {TclDoubleDigits - Inf} {testdoubledigits ieeeFloatingPoint} {
+ testdoubledigits Inf -1 shortest
+} {Infinity 9999 +}
+test util-12.2 {TclDoubleDigits - -Inf} {testdoubledigits ieeeFloatingPoint} {
+ testdoubledigits -Inf -1 shortest
+} {Infinity 9999 -}
+test util-12.3 {TclDoubleDigits - NaN} {testdoubledigits ieeeFloatingPoint} {
+ testdoubledigits $ieeeValues(NaN) -1 shortest
+} {NaN 9999 +}
+test util-12.4 {TclDoubleDigits - NaN} {*}{
+ -constraints {testdoubledigits ieeeFloatingPoint controversialNaN}
+ -body {
+ testdoubledigits -NaN -1 shortest
+ }
+ -result {NaN 9999 -}
+}
+test util-12.5 {TclDoubleDigits - 0} testdoubledigits {
+ testdoubledigits 0.0 -1 shortest
+} {0 0 +}
+test util-12.6 {TclDoubleDigits - -0} testdoubledigits {
+ testdoubledigits -0.0 -1 shortest
+} {0 0 -}
+
+# Verdonk test vectors
+
+test util-13.1 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1754e31cd072da E+1008 +4_000000000000000000& E+303
+ }
+ -result {}
+}
+test util-13.2 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1afcef51f0fb5f E+265 -1_000000000000000000& E+80
+ }
+ -result {}
+}
+test util-13.3 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1754e31cd072da E+1006 +1_000000000000000000& E+303
+ }
+ -result {}
+}
+test util-13.4 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1754e31cd072da E+1007 -2_000000000000000000& E+303
+ }
+ -result {}
+}
+test util-13.5 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1e07b27dd78b14 E-848 +1_00000000000000000& E-255
+ }
+ -result {}
+}
+test util-13.6 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1e29e9c56687fe E-709 -7_00000000000000000& E-214
+ }
+ -result {}
+}
+test util-13.7 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1be03d0bf225c7 E-137 +1_00000000000000000& E-41
+ }
+ -result {}
+}
+test util-13.8 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1a2fe76a3f9475 E-499 -1_00000000000000000& E-150
+ }
+ -result {}
+}
+test util-13.9 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 19a2028368022e E+1019 +8_999999999999999999& E+306
+ }
+ -result {}
+}
+test util-13.10 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1317e5ef3ab327 E+509 -1_999999999999999999& E+153
+ }
+ -result {}
+}
+test util-13.11 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1317e5ef3ab327 E+510 +3_99999999999999999& E+153
+ }
+ -result {}
+}
+test util-13.12 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1317e5ef3ab327 E+511 -7_99999999999999999& E+153
+ }
+ -result {}
+}
+test util-13.13 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1eb8e84fa0b278 E-1008 +6_999999999999999999& E-304
+ }
+ -result {}
+}
+test util-13.14 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -13339131c46f8b E-1004 -6_999999999999999999& E-303
+ }
+ -result {}
+}
+test util-13.15 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1c0f92a6276c9d E-162 +2_999999999999999999& E-49
+ }
+ -result {}
+}
+test util-13.16 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -15ce1f143d7ad2 E-443 -5_99999999999999999& E-134
+ }
+ -result {}
+}
+test util-13.17 {just over exact - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1c0794d9d40e96 E-301 +43_000000000000000000& E-92
+ }
+ -result {}
+}
+test util-13.18 {just over exact - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1c0794d9d40e96 E-300 -86_000000000000000000& E-92
+ }
+ -result {}
+}
+test util-13.19 {just over exact - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1cd5bee57763e6 E-241 +51_000000000000000000& E-74
+ }
+ -result {}
+}
+test util-13.20 {just under exact - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1d1c26db7d0dae E+651 +16_999999999999999999& E+195
+ }
+ -result {}
+}
+test util-13.21 {just under exact - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -13f7ced916872b E-5 -38_999999999999999999& E-3
+ }
+ -result {}
+}
+test util-13.22 {just over exact - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 17d93193f78fc6 E+588 +151_0000000000000000000& E+175
+ }
+ -result {}
+}
+test util-13.23 {just over exact - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1a82a1631eeb30 E-625 -119_000000000000000000& E-190
+ }
+ -result {}
+}
+test util-13.24 {just under exact - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -16c309024bab4b E+290 -282_999999999999999999& E+85
+ }
+ -result {}
+}
+test util-13.25 {just over exact - 8 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1dbbac6f83a821 E-800 +27869147_0000000000000000000& E-248
+ }
+ -result {}
+}
+test util-13.26 {just under exact - 9 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1c569e968e0944 E+430 -491080653_9999999999999999999& E+121
+ }
+ -result {}
+}
+test util-13.27 {just under exact - 9 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1c569e968e0944 E+429 +245540326_9999999999999999999& E+121
+ }
+ -result {}
+}
+test util-13.28 {just over exact - 10 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1fc575867314ee E-330 -9078555839_0000000000000000000& E-109
+ }
+ -result {}
+}
+test util-13.29 {just under exact - 10 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1c569e968e0944 E+428 -1227701634_9999999999999999999& E+120
+ }
+ -result {}
+}
+test util-13.30 {just over exact - 11 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1fc575867314ee E-329 +18157111678_0000000000000000000& E-109
+ }
+ -result {}
+}
+test util-13.31 {just over exact - 14 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -18bf7e7fa6f02a E-196 -15400733123779_0000000000000000000& E-72
+ }
+ -result {}
+}
+test util-13.32 {just over exact - 17 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -13de005bd620df E+217 -26153245263757307_0000000000000000000& E+49
+ }
+ -result {}
+}
+test util-13.33 {just over exact - 18 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1f92bacb3cb40c E+718 +272104041512242479_0000000000000000000& E+199
+ }
+ -result {}
+}
+test util-13.34 {just over exact - 18 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1f92bacb3cb40c E+719 -544208083024484958_0000000000000000000& E+199
+ }
+ -result {}
+}
+test util-13.35 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 142dbf25096cf5 E+148 +4_500000000000000000& E+44
+ }
+ -result {}
+}
+test util-13.36 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1afcef51f0fb5f E+263 -2_500000000000000000& E+79
+ }
+ -result {}
+}
+test util-13.37 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 102498ea6df0c4 E+145 +4_500000000000000000& E+43
+ }
+ -result {}
+}
+test util-13.38 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1754e31cd072da E+1004 -2_500000000000000000& E+302
+ }
+ -result {}
+}
+test util-13.39 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 12deac01e2b4f7 E-557 +2_50000000000000000& E-168
+ }
+ -result {}
+}
+test util-13.40 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1b1df536c13eee E-307 -6_50000000000000000& E-93
+ }
+ -result {}
+}
+test util-13.41 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 10711fed5b19a4 E-154 +4_50000000000000000& E-47
+ }
+ -result {}
+}
+test util-13.42 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -148d67e8b1e00d E-151 -4_50000000000000000& E-46
+ }
+ -result {}
+}
+test util-13.43 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1c8c574c0c6be7 E+187 +3_49999999999999999& E+56
+ }
+ -result {}
+}
+test util-13.44 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1756183c147514 E+206 -1_49999999999999999& E+62
+ }
+ -result {}
+}
+test util-13.45 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 12ab469676c410 E+203 +1_49999999999999999& E+61
+ }
+ -result {}
+}
+test util-13.46 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1539684e774b48 E+246 -1_49999999999999999& E+74
+ }
+ -result {}
+}
+test util-13.47 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 12e5f5dfa4fe9d E-286 +9_499999999999999999& E-87
+ }
+ -result {}
+}
+test util-13.48 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1bdc2417bf7787 E-838 -9_499999999999999999& E-253
+ }
+ -result {}
+}
+test util-13.49 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1eb8e84fa0b278 E-1009 +3_499999999999999999& E-304
+ }
+ -result {}
+}
+test util-13.50 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1e3cbc9907fdc8 E-290 -9_499999999999999999& E-88
+ }
+ -result {}
+}
+test util-13.51 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 10ad836f269a17 E-324 +30_500000000000000000& E-99
+ }
+ -result {}
+}
+test util-13.52 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1b39ae1909c31b E-687 -26_500000000000000000& E-208
+ }
+ -result {}
+}
+test util-13.53 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1b2ab18615fcc6 E-576 +686_500000000000000000& E-176
+ }
+ -result {}
+}
+test util-13.54 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -13e1f90a573064 E-624 -178_500000000000000000& E-190
+ }
+ -result {}
+}
+test util-13.55 {just under half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 16c309024bab4b E+289 +141_499999999999999999& E+85
+ }
+ -result {}
+}
+test util-13.56 {just under half ulp - 4 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -159bd3ad46e346 E+193 -1695_499999999999999999& E+55
+ }
+ -result {}
+}
+test util-13.57 {just under half ulp - 4 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1df4170f0fdecc E+124 +3981_499999999999999999& E+34
+ }
+ -result {}
+}
+test util-13.58 {just over half ulp - 6 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 17e1e0f1c7a4ac E+415 +126300_5000000000000000000& E+120
+ }
+ -result {}
+}
+test util-13.59 {just over half ulp - 6 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1dda592e398dd7 E+418 -126300_5000000000000000000& E+121
+ }
+ -result {}
+}
+test util-13.60 {just under half ulp - 7 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1e597c0b94b7ae E+453 -4411845_499999999999999999& E+130
+ }
+ -result {}
+}
+test util-13.61 {just under half ulp - 9 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1c569e968e0944 E+427 +613850817_4999999999999999999& E+120
+ }
+ -result {}
+}
+test util-13.62 {just under half ulp - 9 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1c569e968e0944 E+428 -122770163_49999999999999999999& E+121
+ }
+ -result {}
+}
+test util-13.63 {just over half ulp - 18 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 17ae0c186d8709 E+719 +408156062268363718_5000000000000000000& E+199
+ }
+ -result {}
+}
+test util-13.64 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 152d02c7e14af7 E+76 +1_0000000000000000& E+23
+ }
+ -result {}
+}
+test util-13.65 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -19d971e4fe8402 E+89 -1_0000000000000000& E+27
+ }
+ -result {}
+}
+test util-13.66 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 19d971e4fe8402 E+90 +2_0000000000000000& E+27
+ }
+ -result {}
+}
+test util-13.67 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -19d971e4fe8402 E+91 -4_0000000000000000& E+27
+ }
+ -result {}
+}
+test util-13.68 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 15798ee2308c3a E-27 +1_0000000000000000& E-8
+ }
+ -result {}
+}
+test util-13.69 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -15798ee2308c3a E-26 -2_0000000000000000& E-8
+ }
+ -result {}
+}
+test util-13.70 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 15798ee2308c3a E-25 +4_0000000000000000& E-8
+ }
+ -result {}
+}
+test util-13.71 {just over exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1ef2d0f5da7dd9 E-84 -1_0000000000000000& E-25
+ }
+ -result {}
+}
+test util-13.72 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1a784379d99db4 E+78 +4_9999999999999999& E+23
+ }
+ -result {}
+}
+test util-13.73 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1a784379d99db4 E+80 -1_9999999999999999& E+24
+ }
+ -result {}
+}
+test util-13.74 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 13da329b633647 E+81 +2_9999999999999999& E+24
+ }
+ -result {}
+}
+test util-13.75 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1cf389cd46047d E+85 -6_9999999999999999& E+25
+ }
+ -result {}
+}
+test util-13.76 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 19999999999999 E-3 +1_99999999999999999& E-1
+ }
+ -result {}
+}
+test util-13.77 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -13333333333333 E-2 -2_99999999999999999& E-1
+ }
+ -result {}
+}
+test util-13.78 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 16849b86a12b9b E-48 +4_99999999999999999& E-15
+ }
+ -result {}
+}
+test util-13.79 {just under exact - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -16849b86a12b9b E-46 -1_99999999999999999& E-14
+ }
+ -result {}
+}
+test util-13.80 {just over exact - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 17ccfc73126788 E-71 +63_00000000000000000& E-23
+ }
+ -result {}
+}
+test util-13.81 {just over exact - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1dc03b8fd7016a E-68 -63_00000000000000000& E-22
+ }
+ -result {}
+}
+test util-13.82 {just under exact - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 13f7ced916872b E-5 +38_999999999999999999& E-3
+ }
+ -result {}
+}
+test util-13.83 {just over exact - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1b297cad9f70b6 E+97 +269_000000000000000000& E+27
+ }
+ -result {}
+}
+test util-13.84 {just over exact - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1b297cad9f70b6 E+98 -538_00000000000000000& E+27
+ }
+ -result {}
+}
+test util-13.85 {just over exact - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1cdc06b20ef183 E-82 +373_00000000000000000& E-27
+ }
+ -result {}
+}
+test util-13.86 {just over exact - 4 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1b297cad9f70b6 E+96 +1345_00000000000000000& E+26
+ }
+ -result {}
+}
+# this one is not 4 digits, it is 3, and it is covered above.
+test util-13.87 {just over exact - 4 digits} {*}{
+ -constraints {testdoubledigits knownBadTest}
+ -body {
+ verdonk_test -1b297cad9f70b6 E+97 -2690_00000000000000000& E+26
+ }
+ -result {}
+}
+test util-13.88 {just over exact - 5 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -150a246ecd44f3 E-63 -14257_00000000000000000& E-23
+ }
+ -result {}
+}
+test util-13.89 {just under exact - 6 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -119b96f36ec68b E-19 -209900_999999999999999999& E-11
+ }
+ -result {}
+}
+test util-13.90 {just over exact - 11 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1c06d366394441 E-35 +50980203373_000000000000000000& E-21
+ }
+ -result {}
+}
+test util-13.91 {just under exact - 12 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1f58ac4db68c90 E+122 -104166211810_99999999999999999& E+26
+ }
+ -result {}
+}
+test util-13.92 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 19d971e4fe8402 E+87 +2_5000000000000000& E+26
+ }
+ -result {}
+}
+test util-13.93 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1dc74be914d16b E+81 -4_500000000000000& E+24
+ }
+ -result {}
+}
+test util-13.94 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 14adf4b7320335 E+84 +2_500000000000000& E+25
+ }
+ -result {}
+}
+test util-13.95 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1ae22487c1042b E+85 -6_5000000000000000& E+25
+ }
+ -result {}
+}
+test util-13.96 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 187fe49aab41e0 E-54 +8_5000000000000000& E-17
+ }
+ -result {}
+}
+test util-13.97 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1f5c05e4b23fd7 E-61 -8_5000000000000000& E-19
+ }
+ -result {}
+}
+test util-13.98 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1faa7ab552a552 E-42 +4_5000000000000000& E-13
+ }
+ -result {}
+}
+test util-13.99 {just over half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1b7cdfd9d7bdbb E-36 -2_5000000000000000& E-11
+ }
+ -result {}
+}
+test util-13.100 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 13da329b633647 E+80 +1_4999999999999999& E+24
+ }
+ -result {}
+}
+test util-13.101 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1cf389cd46047d E+84 -3_49999999999999999& E+25
+ }
+ -result {}
+}
+test util-13.102 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1f04ef12cb04cf E+85 +7_4999999999999999& E+25
+ }
+ -result {}
+}
+test util-13.103 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1f04ef12cb04cf E+86 -1_4999999999999999& E+26
+ }
+ -result {}
+}
+test util-13.104 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 13333333333333 E-3 +1_49999999999999999& E-1
+ }
+ -result {}
+}
+test util-13.105 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -107e1fe91b0b70 E-36 -1_49999999999999999& E-11
+ }
+ -result {}
+}
+test util-13.106 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 149da7e361ce4c E-33 +1_49999999999999999& E-10
+ }
+ -result {}
+}
+test util-13.107 {just under half ulp - 1 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -19c511dc3a41df E-30 -1_49999999999999999& E-9
+ }
+ -result {}
+}
+test util-13.108 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1aa83d74267822 E+93 -16_5000000000000000& E+27
+ }
+ -result {}
+}
+test util-13.109 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 18f1d5969453de E+89 +96_5000000000000000& E+25
+ }
+ -result {}
+}
+test util-13.110 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 11d9bd564dcda6 E-70 +94_50000000000000000& E-23
+ }
+ -result {}
+}
+test util-13.111 {just over half ulp - 2 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1a58973ecbede6 E-48 -58_50000000000000000& E-16
+ }
+ -result {}
+}
+test util-13.112 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1b297cad9f70b6 E+95 +672_50000000000000000& E+26
+ }
+ -result {}
+}
+test util-13.113 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -1b297cad9f70b6 E+96 -134_500000000000000000& E+27
+ }
+ -result {}
+}
+test util-13.114 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1cdc06b20ef183 E-83 +186_50000000000000000& E-27
+ }
+ -result {}
+}
+test util-13.115 {just over half ulp - 3 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -136071dcae4565 E-47 -860_50000000000000000& E-17
+ }
+ -result {}
+}
+test util-13.116 {just over half ulp - 6 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1cb968d297dde8 E+99 +113788_50000000000000000& E+25
+ }
+ -result {}
+}
+test util-13.117 {just over half ulp - 6 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test -11f3e1839eeab1 E+103 -113788_50000000000000000& E+26
+ }
+ -result {}
+}
+test util-13.118 {just under half ulp - 9 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1e9cec176c96f8 E+117 +317903333_49999999999999999& E+27
+ }
+ -result {}
+}
+test util-13.119 {just over half ulp - 11 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1c06d366394441 E-36 +25490101686_500000000000000000& E-21
+ }
+ -result {}
+}
+test util-13.120 {just under half ulp - 11 digits} {*}{
+ -constraints testdoubledigits
+ -body {
+ verdonk_test 1f58ac4db68c90 E+121 +52083105905_49999999999999999& E+26
+ }
+ -result {}
+}
+
+test util-14.1 {funky NaN} {*}{
+ -constraints {ieeeFloatingPoint controversialNaN}
+ -body {
+ set ieeeValues(-NaN)
+ }
+ -result -NaN
+}
+
+test util-14.2 {funky NaN} {*}{
+ -constraints {ieeeFloatingPoint controversialNaN}
+ -body {
+ set ieeeValues(-NaN(3456789abcdef))
+ }
+ -result -NaN(3456789abcdef)
+}
+
+test util-15.1 {largest subnormal} {*}{
+ -body {
+ binary scan [binary format w 0x000fffffffffffff] q x
+ set x
+ }
+ -result 2.225073858507201e-308
+ -cleanup {
+ unset x
+ }
+}
+
+test util-15.2 {largest subnormal} {*}{
+ -body {
+ binary scan [binary format w 0x800fffffffffffff] q x
+ set x
+ }
+ -result -2.225073858507201e-308
+ -cleanup {
+ unset x
+ }
+}
+
+test util-15.3 {largest subnormal} {*}{
+ -body {
+ binary scan [binary format q 2.225073858507201e-308] w x
+ format %#lx $x
+ }
+ -result 0xfffffffffffff
+ -cleanup {
+ unset x
+ }
+}
+
+test util-15.4 {largest subnormal} {*}{
+ -body {
+ binary scan [binary format q -2.225073858507201e-308] w x
+ format %#lx $x
+ }
+ -result 0x800fffffffffffff
+ -cleanup {
+ unset x
+ }
+}
+
+test util-15.5 {smallest normal} {*}{
+ -body {
+ binary scan [binary format w 0x0010000000000000] q x
+ set x
+ }
+ -result 2.2250738585072014e-308
+ -cleanup {
+ unset x
+ }
+}
+
+test util-15.6 {smallest normal} {*}{
+ -body {
+ binary scan [binary format w 0x8010000000000000] q x
+ set x
+ }
+ -result -2.2250738585072014e-308
+ -cleanup {
+ unset x
+ }
+}
+
+test util-15.7 {smallest normal} {*}{
+ -body {
+ binary scan [binary format q 2.2250738585072014e-308] w x
+ format %#lx $x
+ }
+ -result 0x10000000000000
+ -cleanup {
+ unset x
+ }
+}
+
+test util-15.8 {smallest normal} {*}{
+ -body {
+ binary scan [binary format q -2.2250738585072014e-308] w x
+ format %#lx $x
+ }
+ -result 0x8010000000000000
+ -cleanup {
+ unset x
+ }
+}
+
+set saved_precision $::tcl_precision
+foreach ::tcl_precision {0 12} {
+ for {set e -312} {$e < -9} {incr e} {
+ test util-16.1.$::tcl_precision.$e {shortening of numbers} \
+ "expr 1.1e$e" 1.1e$e
+ }
+}
+set tcl_precision 0
+for {set e -9} {$e < -4} {incr e} {
+ test util-16.1.$::tcl_precision.$e {shortening of numbers} \
+ "expr 1.1e$e" 1.1e$e
+}
+set tcl_precision 12
+for {set e -9} {$e < -4} {incr e} {
+ test util-16.1.$::tcl_precision.$e {8.4 compatible formatting of doubles} \
+ "expr 1.1e$e" 1.1e[format %+03d $e]
+}
+foreach ::tcl_precision {0 12} {
+ test util-16.1.$::tcl_precision.-4 {shortening of numbers} \
+ {expr 1.1e-4} \
+ 0.00011
+ test util-16.1.$::tcl_precision.-3 {shortening of numbers} \
+ {expr 1.1e-3} \
+ 0.0011
+ test util-16.1.$::tcl_precision.-2 {shortening of numbers} \
+ {expr 1.1e-2} \
+ 0.011
+ test util-16.1.$::tcl_precision.-1 {shortening of numbers} \
+ {expr 1.1e-1} \
+ 0.11
+ test util-16.1.$::tcl_precision.0 {shortening of numbers} \
+ {expr 1.1} \
+ 1.1
+ for {set e 1} {$e < 17} {incr e} {
+ test util-16.1.$::tcl_precision.$e {shortening of numbers} \
+ "expr 11[string repeat 0 [expr {$e-1}]].0" \
+ 11[string repeat 0 [expr {$e-1}]].0
+ }
+ for {set e 17} {$e < 309} {incr e} {
+ test util-16.1.$::tcl_precision.$e {shortening of numbers} \
+ "expr 1.1e$e" 1.1e+$e
+ }
+}
+set tcl_precision 17
+test util-16.1.17.-300 {8.4 compatible formatting of doubles} \
+ {expr 1e-300} \
+ 1e-300
+test util-16.1.17.-299 {8.4 compatible formatting of doubles} \
+ {expr 1e-299} \
+ 9.9999999999999999e-300
+test util-16.1.17.-298 {8.4 compatible formatting of doubles} \
+ {expr 1e-298} \
+ 9.9999999999999991e-299
+test util-16.1.17.-297 {8.4 compatible formatting of doubles} \
+ {expr 1e-297} \
+ 1e-297
+test util-16.1.17.-296 {8.4 compatible formatting of doubles} \
+ {expr 1e-296} \
+ 1e-296
+test util-16.1.17.-295 {8.4 compatible formatting of doubles} \
+ {expr 1e-295} \
+ 1.0000000000000001e-295
+test util-16.1.17.-294 {8.4 compatible formatting of doubles} \
+ {expr 1e-294} \
+ 1e-294
+test util-16.1.17.-293 {8.4 compatible formatting of doubles} \
+ {expr 1e-293} \
+ 1.0000000000000001e-293
+test util-16.1.17.-292 {8.4 compatible formatting of doubles} \
+ {expr 1e-292} \
+ 1.0000000000000001e-292
+test util-16.1.17.-291 {8.4 compatible formatting of doubles} \
+ {expr 1e-291} \
+ 9.9999999999999996e-292
+test util-16.1.17.-290 {8.4 compatible formatting of doubles} \
+ {expr 1e-290} \
+ 1.0000000000000001e-290
+test util-16.1.17.-289 {8.4 compatible formatting of doubles} \
+ {expr 1e-289} \
+ 1e-289
+test util-16.1.17.-288 {8.4 compatible formatting of doubles} \
+ {expr 1e-288} \
+ 1.0000000000000001e-288
+test util-16.1.17.-287 {8.4 compatible formatting of doubles} \
+ {expr 1e-287} \
+ 1e-287
+test util-16.1.17.-286 {8.4 compatible formatting of doubles} \
+ {expr 1e-286} \
+ 1.0000000000000001e-286
+test util-16.1.17.-285 {8.4 compatible formatting of doubles} \
+ {expr 1e-285} \
+ 1.0000000000000001e-285
+test util-16.1.17.-284 {8.4 compatible formatting of doubles} \
+ {expr 1e-284} \
+ 1e-284
+test util-16.1.17.-283 {8.4 compatible formatting of doubles} \
+ {expr 1e-283} \
+ 9.9999999999999995e-284
+test util-16.1.17.-282 {8.4 compatible formatting of doubles} \
+ {expr 1e-282} \
+ 1e-282
+test util-16.1.17.-281 {8.4 compatible formatting of doubles} \
+ {expr 1e-281} \
+ 1e-281
+test util-16.1.17.-280 {8.4 compatible formatting of doubles} \
+ {expr 1e-280} \
+ 9.9999999999999996e-281
+test util-16.1.17.-279 {8.4 compatible formatting of doubles} \
+ {expr 1e-279} \
+ 1.0000000000000001e-279
+test util-16.1.17.-278 {8.4 compatible formatting of doubles} \
+ {expr 1e-278} \
+ 9.9999999999999994e-279
+test util-16.1.17.-277 {8.4 compatible formatting of doubles} \
+ {expr 1e-277} \
+ 9.9999999999999997e-278
+test util-16.1.17.-276 {8.4 compatible formatting of doubles} \
+ {expr 1e-276} \
+ 1.0000000000000001e-276
+test util-16.1.17.-275 {8.4 compatible formatting of doubles} \
+ {expr 1e-275} \
+ 9.9999999999999993e-276
+test util-16.1.17.-274 {8.4 compatible formatting of doubles} \
+ {expr 1e-274} \
+ 9.9999999999999997e-275
+test util-16.1.17.-273 {8.4 compatible formatting of doubles} \
+ {expr 1e-273} \
+ 1.0000000000000001e-273
+test util-16.1.17.-272 {8.4 compatible formatting of doubles} \
+ {expr 1e-272} \
+ 9.9999999999999993e-273
+test util-16.1.17.-271 {8.4 compatible formatting of doubles} \
+ {expr 1e-271} \
+ 9.9999999999999996e-272
+test util-16.1.17.-270 {8.4 compatible formatting of doubles} \
+ {expr 1e-270} \
+ 1e-270
+test util-16.1.17.-269 {8.4 compatible formatting of doubles} \
+ {expr 1e-269} \
+ 9.9999999999999996e-270
+test util-16.1.17.-268 {8.4 compatible formatting of doubles} \
+ {expr 1e-268} \
+ 9.9999999999999996e-269
+test util-16.1.17.-267 {8.4 compatible formatting of doubles} \
+ {expr 1e-267} \
+ 9.9999999999999998e-268
+test util-16.1.17.-266 {8.4 compatible formatting of doubles} \
+ {expr 1e-266} \
+ 9.9999999999999998e-267
+test util-16.1.17.-265 {8.4 compatible formatting of doubles} \
+ {expr 1e-265} \
+ 9.9999999999999998e-266
+test util-16.1.17.-264 {8.4 compatible formatting of doubles} \
+ {expr 1e-264} \
+ 1e-264
+test util-16.1.17.-263 {8.4 compatible formatting of doubles} \
+ {expr 1e-263} \
+ 1e-263
+test util-16.1.17.-262 {8.4 compatible formatting of doubles} \
+ {expr 1e-262} \
+ 1e-262
+test util-16.1.17.-261 {8.4 compatible formatting of doubles} \
+ {expr 1e-261} \
+ 9.9999999999999998e-262
+test util-16.1.17.-260 {8.4 compatible formatting of doubles} \
+ {expr 1e-260} \
+ 9.9999999999999996e-261
+test util-16.1.17.-259 {8.4 compatible formatting of doubles} \
+ {expr 1e-259} \
+ 1.0000000000000001e-259
+test util-16.1.17.-258 {8.4 compatible formatting of doubles} \
+ {expr 1e-258} \
+ 9.9999999999999995e-259
+test util-16.1.17.-257 {8.4 compatible formatting of doubles} \
+ {expr 1e-257} \
+ 9.9999999999999998e-258
+test util-16.1.17.-256 {8.4 compatible formatting of doubles} \
+ {expr 1e-256} \
+ 9.9999999999999998e-257
+test util-16.1.17.-255 {8.4 compatible formatting of doubles} \
+ {expr 1e-255} \
+ 1e-255
+test util-16.1.17.-254 {8.4 compatible formatting of doubles} \
+ {expr 1e-254} \
+ 9.9999999999999991e-255
+test util-16.1.17.-253 {8.4 compatible formatting of doubles} \
+ {expr 1e-253} \
+ 1.0000000000000001e-253
+test util-16.1.17.-252 {8.4 compatible formatting of doubles} \
+ {expr 1e-252} \
+ 9.9999999999999994e-253
+test util-16.1.17.-251 {8.4 compatible formatting of doubles} \
+ {expr 1e-251} \
+ 1e-251
+test util-16.1.17.-250 {8.4 compatible formatting of doubles} \
+ {expr 1e-250} \
+ 1.0000000000000001e-250
+test util-16.1.17.-249 {8.4 compatible formatting of doubles} \
+ {expr 1e-249} \
+ 1.0000000000000001e-249
+test util-16.1.17.-248 {8.4 compatible formatting of doubles} \
+ {expr 1e-248} \
+ 9.9999999999999998e-249
+test util-16.1.17.-247 {8.4 compatible formatting of doubles} \
+ {expr 1e-247} \
+ 1e-247
+test util-16.1.17.-246 {8.4 compatible formatting of doubles} \
+ {expr 1e-246} \
+ 9.9999999999999996e-247
+test util-16.1.17.-245 {8.4 compatible formatting of doubles} \
+ {expr 1e-245} \
+ 9.9999999999999993e-246
+test util-16.1.17.-244 {8.4 compatible formatting of doubles} \
+ {expr 1e-244} \
+ 9.9999999999999993e-245
+test util-16.1.17.-243 {8.4 compatible formatting of doubles} \
+ {expr 1e-243} \
+ 1e-243
+test util-16.1.17.-242 {8.4 compatible formatting of doubles} \
+ {expr 1e-242} \
+ 9.9999999999999997e-243
+test util-16.1.17.-241 {8.4 compatible formatting of doubles} \
+ {expr 1e-241} \
+ 9.9999999999999997e-242
+test util-16.1.17.-240 {8.4 compatible formatting of doubles} \
+ {expr 1e-240} \
+ 9.9999999999999997e-241
+test util-16.1.17.-239 {8.4 compatible formatting of doubles} \
+ {expr 1e-239} \
+ 1.0000000000000001e-239
+test util-16.1.17.-238 {8.4 compatible formatting of doubles} \
+ {expr 1e-238} \
+ 9.9999999999999999e-239
+test util-16.1.17.-237 {8.4 compatible formatting of doubles} \
+ {expr 1e-237} \
+ 9.9999999999999999e-238
+test util-16.1.17.-236 {8.4 compatible formatting of doubles} \
+ {expr 1e-236} \
+ 1e-236
+test util-16.1.17.-235 {8.4 compatible formatting of doubles} \
+ {expr 1e-235} \
+ 9.9999999999999996e-236
+test util-16.1.17.-234 {8.4 compatible formatting of doubles} \
+ {expr 1e-234} \
+ 9.9999999999999996e-235
+test util-16.1.17.-233 {8.4 compatible formatting of doubles} \
+ {expr 1e-233} \
+ 9.9999999999999996e-234
+test util-16.1.17.-232 {8.4 compatible formatting of doubles} \
+ {expr 1e-232} \
+ 1e-232
+test util-16.1.17.-231 {8.4 compatible formatting of doubles} \
+ {expr 1e-231} \
+ 9.9999999999999999e-232
+test util-16.1.17.-230 {8.4 compatible formatting of doubles} \
+ {expr 1e-230} \
+ 1e-230
+test util-16.1.17.-229 {8.4 compatible formatting of doubles} \
+ {expr 1e-229} \
+ 1.0000000000000001e-229
+test util-16.1.17.-228 {8.4 compatible formatting of doubles} \
+ {expr 1e-228} \
+ 1e-228
+test util-16.1.17.-227 {8.4 compatible formatting of doubles} \
+ {expr 1e-227} \
+ 9.9999999999999994e-228
+test util-16.1.17.-226 {8.4 compatible formatting of doubles} \
+ {expr 1e-226} \
+ 9.9999999999999992e-227
+test util-16.1.17.-225 {8.4 compatible formatting of doubles} \
+ {expr 1e-225} \
+ 9.9999999999999996e-226
+test util-16.1.17.-224 {8.4 compatible formatting of doubles} \
+ {expr 1e-224} \
+ 1e-224
+test util-16.1.17.-223 {8.4 compatible formatting of doubles} \
+ {expr 1e-223} \
+ 9.9999999999999997e-224
+test util-16.1.17.-222 {8.4 compatible formatting of doubles} \
+ {expr 1e-222} \
+ 1e-222
+test util-16.1.17.-221 {8.4 compatible formatting of doubles} \
+ {expr 1e-221} \
+ 1e-221
+test util-16.1.17.-220 {8.4 compatible formatting of doubles} \
+ {expr 1e-220} \
+ 9.9999999999999999e-221
+test util-16.1.17.-219 {8.4 compatible formatting of doubles} \
+ {expr 1e-219} \
+ 1e-219
+test util-16.1.17.-218 {8.4 compatible formatting of doubles} \
+ {expr 1e-218} \
+ 1e-218
+test util-16.1.17.-217 {8.4 compatible formatting of doubles} \
+ {expr 1e-217} \
+ 1.0000000000000001e-217
+test util-16.1.17.-216 {8.4 compatible formatting of doubles} \
+ {expr 1e-216} \
+ 1e-216
+test util-16.1.17.-215 {8.4 compatible formatting of doubles} \
+ {expr 1e-215} \
+ 1e-215
+test util-16.1.17.-214 {8.4 compatible formatting of doubles} \
+ {expr 1e-214} \
+ 9.9999999999999991e-215
+test util-16.1.17.-213 {8.4 compatible formatting of doubles} \
+ {expr 1e-213} \
+ 9.9999999999999995e-214
+test util-16.1.17.-212 {8.4 compatible formatting of doubles} \
+ {expr 1e-212} \
+ 9.9999999999999995e-213
+test util-16.1.17.-211 {8.4 compatible formatting of doubles} \
+ {expr 1e-211} \
+ 1.0000000000000001e-211
+test util-16.1.17.-210 {8.4 compatible formatting of doubles} \
+ {expr 1e-210} \
+ 1e-210
+test util-16.1.17.-209 {8.4 compatible formatting of doubles} \
+ {expr 1e-209} \
+ 1e-209
+test util-16.1.17.-208 {8.4 compatible formatting of doubles} \
+ {expr 1e-208} \
+ 1.0000000000000001e-208
+test util-16.1.17.-207 {8.4 compatible formatting of doubles} \
+ {expr 1e-207} \
+ 9.9999999999999993e-208
+test util-16.1.17.-206 {8.4 compatible formatting of doubles} \
+ {expr 1e-206} \
+ 1e-206
+test util-16.1.17.-205 {8.4 compatible formatting of doubles} \
+ {expr 1e-205} \
+ 1e-205
+test util-16.1.17.-204 {8.4 compatible formatting of doubles} \
+ {expr 1e-204} \
+ 1e-204
+test util-16.1.17.-203 {8.4 compatible formatting of doubles} \
+ {expr 1e-203} \
+ 1e-203
+test util-16.1.17.-202 {8.4 compatible formatting of doubles} \
+ {expr 1e-202} \
+ 1e-202
+test util-16.1.17.-201 {8.4 compatible formatting of doubles} \
+ {expr 1e-201} \
+ 9.9999999999999995e-202
+test util-16.1.17.-200 {8.4 compatible formatting of doubles} \
+ {expr 1e-200} \
+ 9.9999999999999998e-201
+test util-16.1.17.-199 {8.4 compatible formatting of doubles} \
+ {expr 1e-199} \
+ 9.9999999999999998e-200
+test util-16.1.17.-198 {8.4 compatible formatting of doubles} \
+ {expr 1e-198} \
+ 9.9999999999999991e-199
+test util-16.1.17.-197 {8.4 compatible formatting of doubles} \
+ {expr 1e-197} \
+ 9.9999999999999999e-198
+test util-16.1.17.-196 {8.4 compatible formatting of doubles} \
+ {expr 1e-196} \
+ 1e-196
+test util-16.1.17.-195 {8.4 compatible formatting of doubles} \
+ {expr 1e-195} \
+ 1.0000000000000001e-195
+test util-16.1.17.-194 {8.4 compatible formatting of doubles} \
+ {expr 1e-194} \
+ 1e-194
+test util-16.1.17.-193 {8.4 compatible formatting of doubles} \
+ {expr 1e-193} \
+ 1e-193
+test util-16.1.17.-192 {8.4 compatible formatting of doubles} \
+ {expr 1e-192} \
+ 1.0000000000000001e-192
+test util-16.1.17.-191 {8.4 compatible formatting of doubles} \
+ {expr 1e-191} \
+ 1e-191
+test util-16.1.17.-190 {8.4 compatible formatting of doubles} \
+ {expr 1e-190} \
+ 1e-190
+test util-16.1.17.-189 {8.4 compatible formatting of doubles} \
+ {expr 1e-189} \
+ 1.0000000000000001e-189
+test util-16.1.17.-188 {8.4 compatible formatting of doubles} \
+ {expr 1e-188} \
+ 9.9999999999999995e-189
+test util-16.1.17.-187 {8.4 compatible formatting of doubles} \
+ {expr 1e-187} \
+ 1e-187
+test util-16.1.17.-186 {8.4 compatible formatting of doubles} \
+ {expr 1e-186} \
+ 9.9999999999999991e-187
+test util-16.1.17.-185 {8.4 compatible formatting of doubles} \
+ {expr 1e-185} \
+ 9.9999999999999999e-186
+test util-16.1.17.-184 {8.4 compatible formatting of doubles} \
+ {expr 1e-184} \
+ 1.0000000000000001e-184
+test util-16.1.17.-183 {8.4 compatible formatting of doubles} \
+ {expr 1e-183} \
+ 1e-183
+test util-16.1.17.-182 {8.4 compatible formatting of doubles} \
+ {expr 1e-182} \
+ 1e-182
+test util-16.1.17.-181 {8.4 compatible formatting of doubles} \
+ {expr 1e-181} \
+ 1e-181
+test util-16.1.17.-180 {8.4 compatible formatting of doubles} \
+ {expr 1e-180} \
+ 1e-180
+test util-16.1.17.-179 {8.4 compatible formatting of doubles} \
+ {expr 1e-179} \
+ 1e-179
+test util-16.1.17.-178 {8.4 compatible formatting of doubles} \
+ {expr 1e-178} \
+ 9.9999999999999995e-179
+test util-16.1.17.-177 {8.4 compatible formatting of doubles} \
+ {expr 1e-177} \
+ 9.9999999999999995e-178
+test util-16.1.17.-176 {8.4 compatible formatting of doubles} \
+ {expr 1e-176} \
+ 1e-176
+test util-16.1.17.-175 {8.4 compatible formatting of doubles} \
+ {expr 1e-175} \
+ 1e-175
+test util-16.1.17.-174 {8.4 compatible formatting of doubles} \
+ {expr 1e-174} \
+ 1e-174
+test util-16.1.17.-173 {8.4 compatible formatting of doubles} \
+ {expr 1e-173} \
+ 1e-173
+test util-16.1.17.-172 {8.4 compatible formatting of doubles} \
+ {expr 1e-172} \
+ 1e-172
+test util-16.1.17.-171 {8.4 compatible formatting of doubles} \
+ {expr 1e-171} \
+ 9.9999999999999998e-172
+test util-16.1.17.-170 {8.4 compatible formatting of doubles} \
+ {expr 1e-170} \
+ 9.9999999999999998e-171
+test util-16.1.17.-169 {8.4 compatible formatting of doubles} \
+ {expr 1e-169} \
+ 1e-169
+test util-16.1.17.-168 {8.4 compatible formatting of doubles} \
+ {expr 1e-168} \
+ 1e-168
+test util-16.1.17.-167 {8.4 compatible formatting of doubles} \
+ {expr 1e-167} \
+ 1e-167
+test util-16.1.17.-166 {8.4 compatible formatting of doubles} \
+ {expr 1e-166} \
+ 1e-166
+test util-16.1.17.-165 {8.4 compatible formatting of doubles} \
+ {expr 1e-165} \
+ 1e-165
+test util-16.1.17.-164 {8.4 compatible formatting of doubles} \
+ {expr 1e-164} \
+ 9.9999999999999996e-165
+test util-16.1.17.-163 {8.4 compatible formatting of doubles} \
+ {expr 1e-163} \
+ 9.9999999999999992e-164
+test util-16.1.17.-162 {8.4 compatible formatting of doubles} \
+ {expr 1e-162} \
+ 9.9999999999999995e-163
+test util-16.1.17.-161 {8.4 compatible formatting of doubles} \
+ {expr 1e-161} \
+ 1e-161
+test util-16.1.17.-160 {8.4 compatible formatting of doubles} \
+ {expr 1e-160} \
+ 9.9999999999999999e-161
+test util-16.1.17.-159 {8.4 compatible formatting of doubles} \
+ {expr 1e-159} \
+ 9.9999999999999999e-160
+test util-16.1.17.-158 {8.4 compatible formatting of doubles} \
+ {expr 1e-158} \
+ 1.0000000000000001e-158
+test util-16.1.17.-157 {8.4 compatible formatting of doubles} \
+ {expr 1e-157} \
+ 9.9999999999999994e-158
+test util-16.1.17.-156 {8.4 compatible formatting of doubles} \
+ {expr 1e-156} \
+ 1e-156
+test util-16.1.17.-155 {8.4 compatible formatting of doubles} \
+ {expr 1e-155} \
+ 1e-155
+test util-16.1.17.-154 {8.4 compatible formatting of doubles} \
+ {expr 1e-154} \
+ 9.9999999999999997e-155
+test util-16.1.17.-153 {8.4 compatible formatting of doubles} \
+ {expr 1e-153} \
+ 1e-153
+test util-16.1.17.-152 {8.4 compatible formatting of doubles} \
+ {expr 1e-152} \
+ 1.0000000000000001e-152
+test util-16.1.17.-151 {8.4 compatible formatting of doubles} \
+ {expr 1e-151} \
+ 9.9999999999999994e-152
+test util-16.1.17.-150 {8.4 compatible formatting of doubles} \
+ {expr 1e-150} \
+ 1e-150
+test util-16.1.17.-149 {8.4 compatible formatting of doubles} \
+ {expr 1e-149} \
+ 9.9999999999999998e-150
+test util-16.1.17.-148 {8.4 compatible formatting of doubles} \
+ {expr 1e-148} \
+ 9.9999999999999994e-149
+test util-16.1.17.-147 {8.4 compatible formatting of doubles} \
+ {expr 1e-147} \
+ 9.9999999999999997e-148
+test util-16.1.17.-146 {8.4 compatible formatting of doubles} \
+ {expr 1e-146} \
+ 1e-146
+test util-16.1.17.-145 {8.4 compatible formatting of doubles} \
+ {expr 1e-145} \
+ 9.9999999999999991e-146
+test util-16.1.17.-144 {8.4 compatible formatting of doubles} \
+ {expr 1e-144} \
+ 9.9999999999999995e-145
+test util-16.1.17.-143 {8.4 compatible formatting of doubles} \
+ {expr 1e-143} \
+ 9.9999999999999995e-144
+test util-16.1.17.-142 {8.4 compatible formatting of doubles} \
+ {expr 1e-142} \
+ 1e-142
+test util-16.1.17.-141 {8.4 compatible formatting of doubles} \
+ {expr 1e-141} \
+ 1e-141
+test util-16.1.17.-140 {8.4 compatible formatting of doubles} \
+ {expr 1e-140} \
+ 9.9999999999999998e-141
+test util-16.1.17.-139 {8.4 compatible formatting of doubles} \
+ {expr 1e-139} \
+ 1e-139
+test util-16.1.17.-138 {8.4 compatible formatting of doubles} \
+ {expr 1e-138} \
+ 1.0000000000000001e-138
+test util-16.1.17.-137 {8.4 compatible formatting of doubles} \
+ {expr 1e-137} \
+ 9.9999999999999998e-138
+test util-16.1.17.-136 {8.4 compatible formatting of doubles} \
+ {expr 1e-136} \
+ 1e-136
+test util-16.1.17.-135 {8.4 compatible formatting of doubles} \
+ {expr 1e-135} \
+ 1e-135
+test util-16.1.17.-134 {8.4 compatible formatting of doubles} \
+ {expr 1e-134} \
+ 1e-134
+test util-16.1.17.-133 {8.4 compatible formatting of doubles} \
+ {expr 1e-133} \
+ 1.0000000000000001e-133
+test util-16.1.17.-132 {8.4 compatible formatting of doubles} \
+ {expr 1e-132} \
+ 9.9999999999999999e-133
+test util-16.1.17.-131 {8.4 compatible formatting of doubles} \
+ {expr 1e-131} \
+ 9.9999999999999999e-132
+test util-16.1.17.-130 {8.4 compatible formatting of doubles} \
+ {expr 1e-130} \
+ 1.0000000000000001e-130
+test util-16.1.17.-129 {8.4 compatible formatting of doubles} \
+ {expr 1e-129} \
+ 9.9999999999999993e-130
+test util-16.1.17.-128 {8.4 compatible formatting of doubles} \
+ {expr 1e-128} \
+ 1.0000000000000001e-128
+test util-16.1.17.-127 {8.4 compatible formatting of doubles} \
+ {expr 1e-127} \
+ 1e-127
+test util-16.1.17.-126 {8.4 compatible formatting of doubles} \
+ {expr 1e-126} \
+ 9.9999999999999995e-127
+test util-16.1.17.-125 {8.4 compatible formatting of doubles} \
+ {expr 1e-125} \
+ 1e-125
+test util-16.1.17.-124 {8.4 compatible formatting of doubles} \
+ {expr 1e-124} \
+ 9.9999999999999993e-125
+test util-16.1.17.-123 {8.4 compatible formatting of doubles} \
+ {expr 1e-123} \
+ 1.0000000000000001e-123
+test util-16.1.17.-122 {8.4 compatible formatting of doubles} \
+ {expr 1e-122} \
+ 1.0000000000000001e-122
+test util-16.1.17.-121 {8.4 compatible formatting of doubles} \
+ {expr 1e-121} \
+ 9.9999999999999998e-122
+test util-16.1.17.-120 {8.4 compatible formatting of doubles} \
+ {expr 1e-120} \
+ 9.9999999999999998e-121
+test util-16.1.17.-119 {8.4 compatible formatting of doubles} \
+ {expr 1e-119} \
+ 1e-119
+test util-16.1.17.-118 {8.4 compatible formatting of doubles} \
+ {expr 1e-118} \
+ 9.9999999999999999e-119
+test util-16.1.17.-117 {8.4 compatible formatting of doubles} \
+ {expr 1e-117} \
+ 1e-117
+test util-16.1.17.-116 {8.4 compatible formatting of doubles} \
+ {expr 1e-116} \
+ 9.9999999999999999e-117
+test util-16.1.17.-115 {8.4 compatible formatting of doubles} \
+ {expr 1e-115} \
+ 1.0000000000000001e-115
+test util-16.1.17.-114 {8.4 compatible formatting of doubles} \
+ {expr 1e-114} \
+ 1.0000000000000001e-114
+test util-16.1.17.-113 {8.4 compatible formatting of doubles} \
+ {expr 1e-113} \
+ 9.9999999999999998e-114
+test util-16.1.17.-112 {8.4 compatible formatting of doubles} \
+ {expr 1e-112} \
+ 9.9999999999999995e-113
+test util-16.1.17.-111 {8.4 compatible formatting of doubles} \
+ {expr 1e-111} \
+ 1.0000000000000001e-111
+test util-16.1.17.-110 {8.4 compatible formatting of doubles} \
+ {expr 1e-110} \
+ 1.0000000000000001e-110
+test util-16.1.17.-109 {8.4 compatible formatting of doubles} \
+ {expr 1e-109} \
+ 9.9999999999999999e-110
+test util-16.1.17.-108 {8.4 compatible formatting of doubles} \
+ {expr 1e-108} \
+ 1e-108
+test util-16.1.17.-107 {8.4 compatible formatting of doubles} \
+ {expr 1e-107} \
+ 1e-107
+test util-16.1.17.-106 {8.4 compatible formatting of doubles} \
+ {expr 1e-106} \
+ 9.9999999999999994e-107
+test util-16.1.17.-105 {8.4 compatible formatting of doubles} \
+ {expr 1e-105} \
+ 9.9999999999999997e-106
+test util-16.1.17.-104 {8.4 compatible formatting of doubles} \
+ {expr 1e-104} \
+ 9.9999999999999993e-105
+test util-16.1.17.-103 {8.4 compatible formatting of doubles} \
+ {expr 1e-103} \
+ 9.9999999999999996e-104
+test util-16.1.17.-102 {8.4 compatible formatting of doubles} \
+ {expr 1e-102} \
+ 9.9999999999999993e-103
+test util-16.1.17.-101 {8.4 compatible formatting of doubles} \
+ {expr 1e-101} \
+ 1.0000000000000001e-101
+test util-16.1.17.-100 {8.4 compatible formatting of doubles} \
+ {expr 1e-100} \
+ 1e-100
+test util-16.1.17.-99 {8.4 compatible formatting of doubles} \
+ {expr 1e-99} \
+ 1e-99
+test util-16.1.17.-98 {8.4 compatible formatting of doubles} \
+ {expr 1e-98} \
+ 9.9999999999999994e-99
+test util-16.1.17.-97 {8.4 compatible formatting of doubles} \
+ {expr 1e-97} \
+ 1e-97
+test util-16.1.17.-96 {8.4 compatible formatting of doubles} \
+ {expr 1e-96} \
+ 9.9999999999999991e-97
+test util-16.1.17.-95 {8.4 compatible formatting of doubles} \
+ {expr 1e-95} \
+ 9.9999999999999999e-96
+test util-16.1.17.-94 {8.4 compatible formatting of doubles} \
+ {expr 1e-94} \
+ 9.9999999999999996e-95
+test util-16.1.17.-93 {8.4 compatible formatting of doubles} \
+ {expr 1e-93} \
+ 9.999999999999999e-94
+test util-16.1.17.-92 {8.4 compatible formatting of doubles} \
+ {expr 1e-92} \
+ 9.9999999999999999e-93
+test util-16.1.17.-91 {8.4 compatible formatting of doubles} \
+ {expr 1e-91} \
+ 1e-91
+test util-16.1.17.-90 {8.4 compatible formatting of doubles} \
+ {expr 1e-90} \
+ 9.9999999999999999e-91
+test util-16.1.17.-89 {8.4 compatible formatting of doubles} \
+ {expr 1e-89} \
+ 1e-89
+test util-16.1.17.-88 {8.4 compatible formatting of doubles} \
+ {expr 1e-88} \
+ 9.9999999999999993e-89
+test util-16.1.17.-87 {8.4 compatible formatting of doubles} \
+ {expr 1e-87} \
+ 1e-87
+test util-16.1.17.-86 {8.4 compatible formatting of doubles} \
+ {expr 1e-86} \
+ 1.0000000000000001e-86
+test util-16.1.17.-85 {8.4 compatible formatting of doubles} \
+ {expr 1e-85} \
+ 9.9999999999999998e-86
+test util-16.1.17.-84 {8.4 compatible formatting of doubles} \
+ {expr 1e-84} \
+ 1e-84
+test util-16.1.17.-83 {8.4 compatible formatting of doubles} \
+ {expr 1e-83} \
+ 1e-83
+test util-16.1.17.-82 {8.4 compatible formatting of doubles} \
+ {expr 1e-82} \
+ 9.9999999999999996e-83
+test util-16.1.17.-81 {8.4 compatible formatting of doubles} \
+ {expr 1e-81} \
+ 9.9999999999999996e-82
+test util-16.1.17.-80 {8.4 compatible formatting of doubles} \
+ {expr 1e-80} \
+ 9.9999999999999996e-81
+test util-16.1.17.-79 {8.4 compatible formatting of doubles} \
+ {expr 1e-79} \
+ 1e-79
+test util-16.1.17.-78 {8.4 compatible formatting of doubles} \
+ {expr 1e-78} \
+ 1e-78
+test util-16.1.17.-77 {8.4 compatible formatting of doubles} \
+ {expr 1e-77} \
+ 9.9999999999999993e-78
+test util-16.1.17.-76 {8.4 compatible formatting of doubles} \
+ {expr 1e-76} \
+ 9.9999999999999993e-77
+test util-16.1.17.-75 {8.4 compatible formatting of doubles} \
+ {expr 1e-75} \
+ 9.9999999999999996e-76
+test util-16.1.17.-74 {8.4 compatible formatting of doubles} \
+ {expr 1e-74} \
+ 9.9999999999999996e-75
+test util-16.1.17.-73 {8.4 compatible formatting of doubles} \
+ {expr 1e-73} \
+ 1e-73
+test util-16.1.17.-72 {8.4 compatible formatting of doubles} \
+ {expr 1e-72} \
+ 9.9999999999999997e-73
+test util-16.1.17.-71 {8.4 compatible formatting of doubles} \
+ {expr 1e-71} \
+ 9.9999999999999992e-72
+test util-16.1.17.-70 {8.4 compatible formatting of doubles} \
+ {expr 1e-70} \
+ 1e-70
+test util-16.1.17.-69 {8.4 compatible formatting of doubles} \
+ {expr 1e-69} \
+ 9.9999999999999996e-70
+test util-16.1.17.-68 {8.4 compatible formatting of doubles} \
+ {expr 1e-68} \
+ 1.0000000000000001e-68
+test util-16.1.17.-67 {8.4 compatible formatting of doubles} \
+ {expr 1e-67} \
+ 9.9999999999999994e-68
+test util-16.1.17.-66 {8.4 compatible formatting of doubles} \
+ {expr 1e-66} \
+ 9.9999999999999998e-67
+test util-16.1.17.-65 {8.4 compatible formatting of doubles} \
+ {expr 1e-65} \
+ 9.9999999999999992e-66
+test util-16.1.17.-64 {8.4 compatible formatting of doubles} \
+ {expr 1e-64} \
+ 9.9999999999999997e-65
+test util-16.1.17.-63 {8.4 compatible formatting of doubles} \
+ {expr 1e-63} \
+ 1.0000000000000001e-63
+test util-16.1.17.-62 {8.4 compatible formatting of doubles} \
+ {expr 1e-62} \
+ 1e-62
+test util-16.1.17.-61 {8.4 compatible formatting of doubles} \
+ {expr 1e-61} \
+ 1e-61
+test util-16.1.17.-60 {8.4 compatible formatting of doubles} \
+ {expr 1e-60} \
+ 9.9999999999999997e-61
+test util-16.1.17.-59 {8.4 compatible formatting of doubles} \
+ {expr 1e-59} \
+ 1e-59
+test util-16.1.17.-58 {8.4 compatible formatting of doubles} \
+ {expr 1e-58} \
+ 1e-58
+test util-16.1.17.-57 {8.4 compatible formatting of doubles} \
+ {expr 1e-57} \
+ 9.9999999999999995e-58
+test util-16.1.17.-56 {8.4 compatible formatting of doubles} \
+ {expr 1e-56} \
+ 1e-56
+test util-16.1.17.-55 {8.4 compatible formatting of doubles} \
+ {expr 1e-55} \
+ 9.9999999999999999e-56
+test util-16.1.17.-54 {8.4 compatible formatting of doubles} \
+ {expr 1e-54} \
+ 1e-54
+test util-16.1.17.-53 {8.4 compatible formatting of doubles} \
+ {expr 1e-53} \
+ 1e-53
+test util-16.1.17.-52 {8.4 compatible formatting of doubles} \
+ {expr 1e-52} \
+ 1e-52
+test util-16.1.17.-51 {8.4 compatible formatting of doubles} \
+ {expr 1e-51} \
+ 1e-51
+test util-16.1.17.-50 {8.4 compatible formatting of doubles} \
+ {expr 1e-50} \
+ 1e-50
+test util-16.1.17.-49 {8.4 compatible formatting of doubles} \
+ {expr 1e-49} \
+ 9.9999999999999994e-50
+test util-16.1.17.-48 {8.4 compatible formatting of doubles} \
+ {expr 1e-48} \
+ 9.9999999999999997e-49
+test util-16.1.17.-47 {8.4 compatible formatting of doubles} \
+ {expr 1e-47} \
+ 9.9999999999999997e-48
+test util-16.1.17.-46 {8.4 compatible formatting of doubles} \
+ {expr 1e-46} \
+ 1e-46
+test util-16.1.17.-45 {8.4 compatible formatting of doubles} \
+ {expr 1e-45} \
+ 9.9999999999999998e-46
+test util-16.1.17.-44 {8.4 compatible formatting of doubles} \
+ {expr 1e-44} \
+ 9.9999999999999995e-45
+test util-16.1.17.-43 {8.4 compatible formatting of doubles} \
+ {expr 1e-43} \
+ 1.0000000000000001e-43
+test util-16.1.17.-42 {8.4 compatible formatting of doubles} \
+ {expr 1e-42} \
+ 1e-42
+test util-16.1.17.-41 {8.4 compatible formatting of doubles} \
+ {expr 1e-41} \
+ 1e-41
+test util-16.1.17.-40 {8.4 compatible formatting of doubles} \
+ {expr 1e-40} \
+ 9.9999999999999993e-41
+test util-16.1.17.-39 {8.4 compatible formatting of doubles} \
+ {expr 1e-39} \
+ 9.9999999999999993e-40
+test util-16.1.17.-38 {8.4 compatible formatting of doubles} \
+ {expr 1e-38} \
+ 9.9999999999999996e-39
+test util-16.1.17.-37 {8.4 compatible formatting of doubles} \
+ {expr 1e-37} \
+ 1.0000000000000001e-37
+test util-16.1.17.-36 {8.4 compatible formatting of doubles} \
+ {expr 1e-36} \
+ 9.9999999999999994e-37
+test util-16.1.17.-35 {8.4 compatible formatting of doubles} \
+ {expr 1e-35} \
+ 1e-35
+test util-16.1.17.-34 {8.4 compatible formatting of doubles} \
+ {expr 1e-34} \
+ 9.9999999999999993e-35
+test util-16.1.17.-33 {8.4 compatible formatting of doubles} \
+ {expr 1e-33} \
+ 1.0000000000000001e-33
+test util-16.1.17.-32 {8.4 compatible formatting of doubles} \
+ {expr 1e-32} \
+ 1.0000000000000001e-32
+test util-16.1.17.-31 {8.4 compatible formatting of doubles} \
+ {expr 1e-31} \
+ 1.0000000000000001e-31
+test util-16.1.17.-30 {8.4 compatible formatting of doubles} \
+ {expr 1e-30} \
+ 1.0000000000000001e-30
+test util-16.1.17.-29 {8.4 compatible formatting of doubles} \
+ {expr 1e-29} \
+ 9.9999999999999994e-30
+test util-16.1.17.-28 {8.4 compatible formatting of doubles} \
+ {expr 1e-28} \
+ 9.9999999999999997e-29
+test util-16.1.17.-27 {8.4 compatible formatting of doubles} \
+ {expr 1e-27} \
+ 1e-27
+test util-16.1.17.-26 {8.4 compatible formatting of doubles} \
+ {expr 1e-26} \
+ 1e-26
+test util-16.1.17.-25 {8.4 compatible formatting of doubles} \
+ {expr 1e-25} \
+ 1e-25
+test util-16.1.17.-24 {8.4 compatible formatting of doubles} \
+ {expr 1e-24} \
+ 9.9999999999999992e-25
+test util-16.1.17.-23 {8.4 compatible formatting of doubles} \
+ {expr 1e-23} \
+ 9.9999999999999996e-24
+test util-16.1.17.-22 {8.4 compatible formatting of doubles} \
+ {expr 1e-22} \
+ 1e-22
+test util-16.1.17.-21 {8.4 compatible formatting of doubles} \
+ {expr 1e-21} \
+ 9.9999999999999991e-22
+test util-16.1.17.-20 {8.4 compatible formatting of doubles} \
+ {expr 1e-20} \
+ 9.9999999999999995e-21
+test util-16.1.17.-19 {8.4 compatible formatting of doubles} \
+ {expr 1e-19} \
+ 9.9999999999999998e-20
+test util-16.1.17.-18 {8.4 compatible formatting of doubles} \
+ {expr 1e-18} \
+ 1.0000000000000001e-18
+test util-16.1.17.-17 {8.4 compatible formatting of doubles} \
+ {expr 1e-17} \
+ 1.0000000000000001e-17
+test util-16.1.17.-16 {8.4 compatible formatting of doubles} \
+ {expr 1e-16} \
+ 9.9999999999999998e-17
+test util-16.1.17.-15 {8.4 compatible formatting of doubles} \
+ {expr 1e-15} \
+ 1.0000000000000001e-15
+test util-16.1.17.-14 {8.4 compatible formatting of doubles} \
+ {expr 1e-14} \
+ 1e-14
+test util-16.1.17.-13 {8.4 compatible formatting of doubles} \
+ {expr 1e-13} \
+ 1e-13
+test util-16.1.17.-12 {8.4 compatible formatting of doubles} \
+ {expr 1e-12} \
+ 9.9999999999999998e-13
+test util-16.1.17.-11 {8.4 compatible formatting of doubles} \
+ {expr 1e-11} \
+ 9.9999999999999994e-12
+test util-16.1.17.-10 {8.4 compatible formatting of doubles} \
+ {expr 1e-10} \
+ 1e-10
+test util-16.1.17.-9 {8.4 compatible formatting of doubles} \
+ {expr 1e-9} \
+ 1.0000000000000001e-09
+test util-16.1.17.-8 {8.4 compatible formatting of doubles} \
+ {expr 1e-8} \
+ 1e-08
+test util-16.1.17.-7 {8.4 compatible formatting of doubles} \
+ {expr 1e-7} \
+ 9.9999999999999995e-08
+test util-16.1.17.-6 {8.4 compatible formatting of doubles} \
+ {expr 1e-6} \
+ 9.9999999999999995e-07
+test util-16.1.17.-5 {8.4 compatible formatting of doubles} \
+ {expr 1e-5} \
+ 1.0000000000000001e-05
+test util-16.1.17.-4 {8.4 compatible formatting of doubles} \
+ {expr 1e-4} \
+ 0.0001
+test util-16.1.17.-3 {8.4 compatible formatting of doubles} \
+ {expr 1e-3} \
+ 0.001
+test util-16.1.17.-2 {8.4 compatible formatting of doubles} \
+ {expr 1e-2} \
+ 0.01
+test util-16.1.17.-1 {8.4 compatible formatting of doubles} \
+ {expr 1e-1} \
+ 0.10000000000000001
+test util-16.1.17.0 {8.4 compatible formatting of doubles} \
+ {expr 1e0} \
+ 1.0
+test util-16.1.17.1 {8.4 compatible formatting of doubles} \
+ {expr 1e1} \
+ 10.0
+test util-16.1.17.2 {8.4 compatible formatting of doubles} \
+ {expr 1e2} \
+ 100.0
+test util-16.1.17.3 {8.4 compatible formatting of doubles} \
+ {expr 1e3} \
+ 1000.0
+test util-16.1.17.4 {8.4 compatible formatting of doubles} \
+ {expr 1e4} \
+ 10000.0
+test util-16.1.17.5 {8.4 compatible formatting of doubles} \
+ {expr 1e5} \
+ 100000.0
+test util-16.1.17.6 {8.4 compatible formatting of doubles} \
+ {expr 1e6} \
+ 1000000.0
+test util-16.1.17.7 {8.4 compatible formatting of doubles} \
+ {expr 1e7} \
+ 10000000.0
+test util-16.1.17.8 {8.4 compatible formatting of doubles} \
+ {expr 1e8} \
+ 100000000.0
+test util-16.1.17.9 {8.4 compatible formatting of doubles} \
+ {expr 1e9} \
+ 1000000000.0
+test util-16.1.17.10 {8.4 compatible formatting of doubles} \
+ {expr 1e10} \
+ 10000000000.0
+test util-16.1.17.11 {8.4 compatible formatting of doubles} \
+ {expr 1e11} \
+ 100000000000.0
+test util-16.1.17.12 {8.4 compatible formatting of doubles} \
+ {expr 1e12} \
+ 1000000000000.0
+test util-16.1.17.13 {8.4 compatible formatting of doubles} \
+ {expr 1e13} \
+ 10000000000000.0
+test util-16.1.17.14 {8.4 compatible formatting of doubles} \
+ {expr 1e14} \
+ 100000000000000.0
+test util-16.1.17.15 {8.4 compatible formatting of doubles} \
+ {expr 1e15} \
+ 1000000000000000.0
+test util-16.1.17.16 {8.4 compatible formatting of doubles} \
+ {expr 1e16} \
+ 10000000000000000.0
+test util-16.1.17.17 {8.4 compatible formatting of doubles} \
+ {expr 1e17} \
+ 1e+17
+test util-16.1.17.18 {8.4 compatible formatting of doubles} \
+ {expr 1e18} \
+ 1e+18
+test util-16.1.17.19 {8.4 compatible formatting of doubles} \
+ {expr 1e19} \
+ 1e+19
+test util-16.1.17.20 {8.4 compatible formatting of doubles} \
+ {expr 1e20} \
+ 1e+20
+test util-16.1.17.21 {8.4 compatible formatting of doubles} \
+ {expr 1e21} \
+ 1e+21
+test util-16.1.17.22 {8.4 compatible formatting of doubles} \
+ {expr 1e22} \
+ 1e+22
+test util-16.1.17.23 {8.4 compatible formatting of doubles} \
+ {expr 1e23} \
+ 9.9999999999999992e+22
+test util-16.1.17.24 {8.4 compatible formatting of doubles} \
+ {expr 1e24} \
+ 9.9999999999999998e+23
+test util-16.1.17.25 {8.4 compatible formatting of doubles} \
+ {expr 1e25} \
+ 1.0000000000000001e+25
+test util-16.1.17.26 {8.4 compatible formatting of doubles} \
+ {expr 1e26} \
+ 1e+26
+test util-16.1.17.27 {8.4 compatible formatting of doubles} \
+ {expr 1e27} \
+ 1e+27
+test util-16.1.17.28 {8.4 compatible formatting of doubles} \
+ {expr 1e28} \
+ 9.9999999999999996e+27
+test util-16.1.17.29 {8.4 compatible formatting of doubles} \
+ {expr 1e29} \
+ 9.9999999999999991e+28
+test util-16.1.17.30 {8.4 compatible formatting of doubles} \
+ {expr 1e30} \
+ 1e+30
+test util-16.1.17.31 {8.4 compatible formatting of doubles} \
+ {expr 1e31} \
+ 9.9999999999999996e+30
+test util-16.1.17.32 {8.4 compatible formatting of doubles} \
+ {expr 1e32} \
+ 1.0000000000000001e+32
+test util-16.1.17.33 {8.4 compatible formatting of doubles} \
+ {expr 1e33} \
+ 9.9999999999999995e+32
+test util-16.1.17.34 {8.4 compatible formatting of doubles} \
+ {expr 1e34} \
+ 9.9999999999999995e+33
+test util-16.1.17.35 {8.4 compatible formatting of doubles} \
+ {expr 1e35} \
+ 9.9999999999999997e+34
+test util-16.1.17.36 {8.4 compatible formatting of doubles} \
+ {expr 1e36} \
+ 1e+36
+test util-16.1.17.37 {8.4 compatible formatting of doubles} \
+ {expr 1e37} \
+ 9.9999999999999995e+36
+test util-16.1.17.38 {8.4 compatible formatting of doubles} \
+ {expr 1e38} \
+ 9.9999999999999998e+37
+test util-16.1.17.39 {8.4 compatible formatting of doubles} \
+ {expr 1e39} \
+ 9.9999999999999994e+38
+test util-16.1.17.40 {8.4 compatible formatting of doubles} \
+ {expr 1e40} \
+ 1e+40
+test util-16.1.17.41 {8.4 compatible formatting of doubles} \
+ {expr 1e41} \
+ 1e+41
+test util-16.1.17.42 {8.4 compatible formatting of doubles} \
+ {expr 1e42} \
+ 1e+42
+test util-16.1.17.43 {8.4 compatible formatting of doubles} \
+ {expr 1e43} \
+ 1e+43
+test util-16.1.17.44 {8.4 compatible formatting of doubles} \
+ {expr 1e44} \
+ 1.0000000000000001e+44
+test util-16.1.17.45 {8.4 compatible formatting of doubles} \
+ {expr 1e45} \
+ 9.9999999999999993e+44
+test util-16.1.17.46 {8.4 compatible formatting of doubles} \
+ {expr 1e46} \
+ 9.9999999999999999e+45
+test util-16.1.17.47 {8.4 compatible formatting of doubles} \
+ {expr 1e47} \
+ 1e+47
+test util-16.1.17.48 {8.4 compatible formatting of doubles} \
+ {expr 1e48} \
+ 1e+48
+test util-16.1.17.49 {8.4 compatible formatting of doubles} \
+ {expr 1e49} \
+ 9.9999999999999995e+48
+test util-16.1.17.50 {8.4 compatible formatting of doubles} \
+ {expr 1e50} \
+ 1.0000000000000001e+50
+test util-16.1.17.51 {8.4 compatible formatting of doubles} \
+ {expr 1e51} \
+ 9.9999999999999999e+50
+test util-16.1.17.52 {8.4 compatible formatting of doubles} \
+ {expr 1e52} \
+ 9.9999999999999999e+51
+test util-16.1.17.53 {8.4 compatible formatting of doubles} \
+ {expr 1e53} \
+ 9.9999999999999999e+52
+test util-16.1.17.54 {8.4 compatible formatting of doubles} \
+ {expr 1e54} \
+ 1.0000000000000001e+54
+test util-16.1.17.55 {8.4 compatible formatting of doubles} \
+ {expr 1e55} \
+ 1e+55
+test util-16.1.17.56 {8.4 compatible formatting of doubles} \
+ {expr 1e56} \
+ 1.0000000000000001e+56
+test util-16.1.17.57 {8.4 compatible formatting of doubles} \
+ {expr 1e57} \
+ 1e+57
+test util-16.1.17.58 {8.4 compatible formatting of doubles} \
+ {expr 1e58} \
+ 9.9999999999999994e+57
+test util-16.1.17.59 {8.4 compatible formatting of doubles} \
+ {expr 1e59} \
+ 9.9999999999999997e+58
+test util-16.1.17.60 {8.4 compatible formatting of doubles} \
+ {expr 1e60} \
+ 9.9999999999999995e+59
+test util-16.1.17.61 {8.4 compatible formatting of doubles} \
+ {expr 1e61} \
+ 9.9999999999999995e+60
+test util-16.1.17.62 {8.4 compatible formatting of doubles} \
+ {expr 1e62} \
+ 1e+62
+test util-16.1.17.63 {8.4 compatible formatting of doubles} \
+ {expr 1e63} \
+ 1.0000000000000001e+63
+test util-16.1.17.64 {8.4 compatible formatting of doubles} \
+ {expr 1e64} \
+ 1e+64
+test util-16.1.17.65 {8.4 compatible formatting of doubles} \
+ {expr 1e65} \
+ 9.9999999999999999e+64
+test util-16.1.17.66 {8.4 compatible formatting of doubles} \
+ {expr 1e66} \
+ 9.9999999999999995e+65
+test util-16.1.17.67 {8.4 compatible formatting of doubles} \
+ {expr 1e67} \
+ 9.9999999999999998e+66
+test util-16.1.17.68 {8.4 compatible formatting of doubles} \
+ {expr 1e68} \
+ 9.9999999999999995e+67
+test util-16.1.17.69 {8.4 compatible formatting of doubles} \
+ {expr 1e69} \
+ 1.0000000000000001e+69
+test util-16.1.17.70 {8.4 compatible formatting of doubles} \
+ {expr 1e70} \
+ 1.0000000000000001e+70
+test util-16.1.17.71 {8.4 compatible formatting of doubles} \
+ {expr 1e71} \
+ 1e+71
+test util-16.1.17.72 {8.4 compatible formatting of doubles} \
+ {expr 1e72} \
+ 9.9999999999999994e+71
+test util-16.1.17.73 {8.4 compatible formatting of doubles} \
+ {expr 1e73} \
+ 9.9999999999999998e+72
+test util-16.1.17.74 {8.4 compatible formatting of doubles} \
+ {expr 1e74} \
+ 9.9999999999999995e+73
+test util-16.1.17.75 {8.4 compatible formatting of doubles} \
+ {expr 1e75} \
+ 9.9999999999999993e+74
+test util-16.1.17.76 {8.4 compatible formatting of doubles} \
+ {expr 1e76} \
+ 1e+76
+test util-16.1.17.77 {8.4 compatible formatting of doubles} \
+ {expr 1e77} \
+ 9.9999999999999998e+76
+test util-16.1.17.78 {8.4 compatible formatting of doubles} \
+ {expr 1e78} \
+ 1e+78
+test util-16.1.17.79 {8.4 compatible formatting of doubles} \
+ {expr 1e79} \
+ 9.9999999999999997e+78
+test util-16.1.17.80 {8.4 compatible formatting of doubles} \
+ {expr 1e80} \
+ 1e+80
+test util-16.1.17.81 {8.4 compatible formatting of doubles} \
+ {expr 1e81} \
+ 9.9999999999999992e+80
+test util-16.1.17.82 {8.4 compatible formatting of doubles} \
+ {expr 1e82} \
+ 9.9999999999999996e+81
+test util-16.1.17.83 {8.4 compatible formatting of doubles} \
+ {expr 1e83} \
+ 1e+83
+test util-16.1.17.84 {8.4 compatible formatting of doubles} \
+ {expr 1e84} \
+ 1.0000000000000001e+84
+test util-16.1.17.85 {8.4 compatible formatting of doubles} \
+ {expr 1e85} \
+ 1e+85
+test util-16.1.17.86 {8.4 compatible formatting of doubles} \
+ {expr 1e86} \
+ 1e+86
+test util-16.1.17.87 {8.4 compatible formatting of doubles} \
+ {expr 1e87} \
+ 9.9999999999999996e+86
+test util-16.1.17.88 {8.4 compatible formatting of doubles} \
+ {expr 1e88} \
+ 9.9999999999999996e+87
+test util-16.1.17.89 {8.4 compatible formatting of doubles} \
+ {expr 1e89} \
+ 9.9999999999999999e+88
+test util-16.1.17.90 {8.4 compatible formatting of doubles} \
+ {expr 1e90} \
+ 9.9999999999999997e+89
+test util-16.1.17.91 {8.4 compatible formatting of doubles} \
+ {expr 1e91} \
+ 1.0000000000000001e+91
+test util-16.1.17.92 {8.4 compatible formatting of doubles} \
+ {expr 1e92} \
+ 1e+92
+test util-16.1.17.93 {8.4 compatible formatting of doubles} \
+ {expr 1e93} \
+ 1e+93
+test util-16.1.17.94 {8.4 compatible formatting of doubles} \
+ {expr 1e94} \
+ 1e+94
+test util-16.1.17.95 {8.4 compatible formatting of doubles} \
+ {expr 1e95} \
+ 1e+95
+test util-16.1.17.96 {8.4 compatible formatting of doubles} \
+ {expr 1e96} \
+ 1e+96
+test util-16.1.17.97 {8.4 compatible formatting of doubles} \
+ {expr 1e97} \
+ 1.0000000000000001e+97
+test util-16.1.17.98 {8.4 compatible formatting of doubles} \
+ {expr 1e98} \
+ 1e+98
+test util-16.1.17.99 {8.4 compatible formatting of doubles} \
+ {expr 1e99} \
+ 9.9999999999999997e+98
+test util-16.1.17.100 {8.4 compatible formatting of doubles} \
+ {expr 1e100} \
+ 1e+100
+test util-16.1.17.101 {8.4 compatible formatting of doubles} \
+ {expr 1e101} \
+ 9.9999999999999998e+100
+test util-16.1.17.102 {8.4 compatible formatting of doubles} \
+ {expr 1e102} \
+ 9.9999999999999998e+101
+test util-16.1.17.103 {8.4 compatible formatting of doubles} \
+ {expr 1e103} \
+ 1e+103
+test util-16.1.17.104 {8.4 compatible formatting of doubles} \
+ {expr 1e104} \
+ 1e+104
+test util-16.1.17.105 {8.4 compatible formatting of doubles} \
+ {expr 1e105} \
+ 9.9999999999999994e+104
+test util-16.1.17.106 {8.4 compatible formatting of doubles} \
+ {expr 1e106} \
+ 1.0000000000000001e+106
+test util-16.1.17.107 {8.4 compatible formatting of doubles} \
+ {expr 1e107} \
+ 9.9999999999999997e+106
+test util-16.1.17.108 {8.4 compatible formatting of doubles} \
+ {expr 1e108} \
+ 1e+108
+test util-16.1.17.109 {8.4 compatible formatting of doubles} \
+ {expr 1e109} \
+ 9.9999999999999998e+108
+test util-16.1.17.110 {8.4 compatible formatting of doubles} \
+ {expr 1e110} \
+ 1e+110
+test util-16.1.17.111 {8.4 compatible formatting of doubles} \
+ {expr 1e111} \
+ 9.9999999999999996e+110
+test util-16.1.17.112 {8.4 compatible formatting of doubles} \
+ {expr 1e112} \
+ 9.9999999999999993e+111
+test util-16.1.17.113 {8.4 compatible formatting of doubles} \
+ {expr 1e113} \
+ 1e+113
+test util-16.1.17.114 {8.4 compatible formatting of doubles} \
+ {expr 1e114} \
+ 1e+114
+test util-16.1.17.115 {8.4 compatible formatting of doubles} \
+ {expr 1e115} \
+ 1e+115
+test util-16.1.17.116 {8.4 compatible formatting of doubles} \
+ {expr 1e116} \
+ 1e+116
+test util-16.1.17.117 {8.4 compatible formatting of doubles} \
+ {expr 1e117} \
+ 1.0000000000000001e+117
+test util-16.1.17.118 {8.4 compatible formatting of doubles} \
+ {expr 1e118} \
+ 9.9999999999999997e+117
+test util-16.1.17.119 {8.4 compatible formatting of doubles} \
+ {expr 1e119} \
+ 9.9999999999999994e+118
+test util-16.1.17.120 {8.4 compatible formatting of doubles} \
+ {expr 1e120} \
+ 9.9999999999999998e+119
+test util-16.1.17.121 {8.4 compatible formatting of doubles} \
+ {expr 1e121} \
+ 1e+121
+test util-16.1.17.122 {8.4 compatible formatting of doubles} \
+ {expr 1e122} \
+ 1e+122
+test util-16.1.17.123 {8.4 compatible formatting of doubles} \
+ {expr 1e123} \
+ 9.9999999999999998e+122
+test util-16.1.17.124 {8.4 compatible formatting of doubles} \
+ {expr 1e124} \
+ 9.9999999999999995e+123
+test util-16.1.17.125 {8.4 compatible formatting of doubles} \
+ {expr 1e125} \
+ 9.9999999999999992e+124
+test util-16.1.17.126 {8.4 compatible formatting of doubles} \
+ {expr 1e126} \
+ 9.9999999999999992e+125
+test util-16.1.17.127 {8.4 compatible formatting of doubles} \
+ {expr 1e127} \
+ 9.9999999999999995e+126
+test util-16.1.17.128 {8.4 compatible formatting of doubles} \
+ {expr 1e128} \
+ 1.0000000000000001e+128
+test util-16.1.17.129 {8.4 compatible formatting of doubles} \
+ {expr 1e129} \
+ 1e+129
+test util-16.1.17.130 {8.4 compatible formatting of doubles} \
+ {expr 1e130} \
+ 1.0000000000000001e+130
+test util-16.1.17.131 {8.4 compatible formatting of doubles} \
+ {expr 1e131} \
+ 9.9999999999999991e+130
+test util-16.1.17.132 {8.4 compatible formatting of doubles} \
+ {expr 1e132} \
+ 9.9999999999999999e+131
+test util-16.1.17.133 {8.4 compatible formatting of doubles} \
+ {expr 1e133} \
+ 1e+133
+test util-16.1.17.134 {8.4 compatible formatting of doubles} \
+ {expr 1e134} \
+ 9.9999999999999992e+133
+test util-16.1.17.135 {8.4 compatible formatting of doubles} \
+ {expr 1e135} \
+ 9.9999999999999996e+134
+test util-16.1.17.136 {8.4 compatible formatting of doubles} \
+ {expr 1e136} \
+ 1.0000000000000001e+136
+test util-16.1.17.137 {8.4 compatible formatting of doubles} \
+ {expr 1e137} \
+ 1e+137
+test util-16.1.17.138 {8.4 compatible formatting of doubles} \
+ {expr 1e138} \
+ 1e+138
+test util-16.1.17.139 {8.4 compatible formatting of doubles} \
+ {expr 1e139} \
+ 1e+139
+test util-16.1.17.140 {8.4 compatible formatting of doubles} \
+ {expr 1e140} \
+ 1.0000000000000001e+140
+test util-16.1.17.141 {8.4 compatible formatting of doubles} \
+ {expr 1e141} \
+ 1e+141
+test util-16.1.17.142 {8.4 compatible formatting of doubles} \
+ {expr 1e142} \
+ 1.0000000000000001e+142
+test util-16.1.17.143 {8.4 compatible formatting of doubles} \
+ {expr 1e143} \
+ 1e+143
+test util-16.1.17.144 {8.4 compatible formatting of doubles} \
+ {expr 1e144} \
+ 1e+144
+test util-16.1.17.145 {8.4 compatible formatting of doubles} \
+ {expr 1e145} \
+ 9.9999999999999999e+144
+test util-16.1.17.146 {8.4 compatible formatting of doubles} \
+ {expr 1e146} \
+ 9.9999999999999993e+145
+test util-16.1.17.147 {8.4 compatible formatting of doubles} \
+ {expr 1e147} \
+ 9.9999999999999998e+146
+test util-16.1.17.148 {8.4 compatible formatting of doubles} \
+ {expr 1e148} \
+ 1e+148
+test util-16.1.17.149 {8.4 compatible formatting of doubles} \
+ {expr 1e149} \
+ 1e+149
+test util-16.1.17.150 {8.4 compatible formatting of doubles} \
+ {expr 1e150} \
+ 9.9999999999999998e+149
+test util-16.1.17.151 {8.4 compatible formatting of doubles} \
+ {expr 1e151} \
+ 1e+151
+test util-16.1.17.152 {8.4 compatible formatting of doubles} \
+ {expr 1e152} \
+ 1e+152
+test util-16.1.17.153 {8.4 compatible formatting of doubles} \
+ {expr 1e153} \
+ 1e+153
+test util-16.1.17.154 {8.4 compatible formatting of doubles} \
+ {expr 1e154} \
+ 1e+154
+test util-16.1.17.155 {8.4 compatible formatting of doubles} \
+ {expr 1e155} \
+ 1e+155
+test util-16.1.17.156 {8.4 compatible formatting of doubles} \
+ {expr 1e156} \
+ 9.9999999999999998e+155
+test util-16.1.17.157 {8.4 compatible formatting of doubles} \
+ {expr 1e157} \
+ 9.9999999999999998e+156
+test util-16.1.17.158 {8.4 compatible formatting of doubles} \
+ {expr 1e158} \
+ 9.9999999999999995e+157
+test util-16.1.17.159 {8.4 compatible formatting of doubles} \
+ {expr 1e159} \
+ 9.9999999999999993e+158
+test util-16.1.17.160 {8.4 compatible formatting of doubles} \
+ {expr 1e160} \
+ 1e+160
+test util-16.1.17.161 {8.4 compatible formatting of doubles} \
+ {expr 1e161} \
+ 1e+161
+test util-16.1.17.162 {8.4 compatible formatting of doubles} \
+ {expr 1e162} \
+ 9.9999999999999994e+161
+test util-16.1.17.163 {8.4 compatible formatting of doubles} \
+ {expr 1e163} \
+ 9.9999999999999994e+162
+test util-16.1.17.164 {8.4 compatible formatting of doubles} \
+ {expr 1e164} \
+ 1e+164
+test util-16.1.17.165 {8.4 compatible formatting of doubles} \
+ {expr 1e165} \
+ 9.999999999999999e+164
+test util-16.1.17.166 {8.4 compatible formatting of doubles} \
+ {expr 1e166} \
+ 9.9999999999999994e+165
+test util-16.1.17.167 {8.4 compatible formatting of doubles} \
+ {expr 1e167} \
+ 1e+167
+test util-16.1.17.168 {8.4 compatible formatting of doubles} \
+ {expr 1e168} \
+ 9.9999999999999993e+167
+test util-16.1.17.169 {8.4 compatible formatting of doubles} \
+ {expr 1e169} \
+ 9.9999999999999993e+168
+test util-16.1.17.170 {8.4 compatible formatting of doubles} \
+ {expr 1e170} \
+ 1e+170
+test util-16.1.17.171 {8.4 compatible formatting of doubles} \
+ {expr 1e171} \
+ 9.9999999999999995e+170
+test util-16.1.17.172 {8.4 compatible formatting of doubles} \
+ {expr 1e172} \
+ 1.0000000000000001e+172
+test util-16.1.17.173 {8.4 compatible formatting of doubles} \
+ {expr 1e173} \
+ 1e+173
+test util-16.1.17.174 {8.4 compatible formatting of doubles} \
+ {expr 1e174} \
+ 1.0000000000000001e+174
+test util-16.1.17.175 {8.4 compatible formatting of doubles} \
+ {expr 1e175} \
+ 9.9999999999999994e+174
+test util-16.1.17.176 {8.4 compatible formatting of doubles} \
+ {expr 1e176} \
+ 1e+176
+test util-16.1.17.177 {8.4 compatible formatting of doubles} \
+ {expr 1e177} \
+ 1e+177
+test util-16.1.17.178 {8.4 compatible formatting of doubles} \
+ {expr 1e178} \
+ 1.0000000000000001e+178
+test util-16.1.17.179 {8.4 compatible formatting of doubles} \
+ {expr 1e179} \
+ 9.9999999999999998e+178
+test util-16.1.17.180 {8.4 compatible formatting of doubles} \
+ {expr 1e180} \
+ 1e+180
+test util-16.1.17.181 {8.4 compatible formatting of doubles} \
+ {expr 1e181} \
+ 9.9999999999999992e+180
+test util-16.1.17.182 {8.4 compatible formatting of doubles} \
+ {expr 1e182} \
+ 1.0000000000000001e+182
+test util-16.1.17.183 {8.4 compatible formatting of doubles} \
+ {expr 1e183} \
+ 9.9999999999999995e+182
+test util-16.1.17.184 {8.4 compatible formatting of doubles} \
+ {expr 1e184} \
+ 1e+184
+test util-16.1.17.185 {8.4 compatible formatting of doubles} \
+ {expr 1e185} \
+ 9.9999999999999998e+184
+test util-16.1.17.186 {8.4 compatible formatting of doubles} \
+ {expr 1e186} \
+ 9.9999999999999998e+185
+test util-16.1.17.187 {8.4 compatible formatting of doubles} \
+ {expr 1e187} \
+ 9.9999999999999991e+186
+test util-16.1.17.188 {8.4 compatible formatting of doubles} \
+ {expr 1e188} \
+ 1e+188
+test util-16.1.17.189 {8.4 compatible formatting of doubles} \
+ {expr 1e189} \
+ 1e+189
+test util-16.1.17.190 {8.4 compatible formatting of doubles} \
+ {expr 1e190} \
+ 1.0000000000000001e+190
+test util-16.1.17.191 {8.4 compatible formatting of doubles} \
+ {expr 1e191} \
+ 1.0000000000000001e+191
+test util-16.1.17.192 {8.4 compatible formatting of doubles} \
+ {expr 1e192} \
+ 1e+192
+test util-16.1.17.193 {8.4 compatible formatting of doubles} \
+ {expr 1e193} \
+ 1.0000000000000001e+193
+test util-16.1.17.194 {8.4 compatible formatting of doubles} \
+ {expr 1e194} \
+ 9.9999999999999994e+193
+test util-16.1.17.195 {8.4 compatible formatting of doubles} \
+ {expr 1e195} \
+ 9.9999999999999998e+194
+test util-16.1.17.196 {8.4 compatible formatting of doubles} \
+ {expr 1e196} \
+ 9.9999999999999995e+195
+test util-16.1.17.197 {8.4 compatible formatting of doubles} \
+ {expr 1e197} \
+ 9.9999999999999995e+196
+test util-16.1.17.198 {8.4 compatible formatting of doubles} \
+ {expr 1e198} \
+ 1e+198
+test util-16.1.17.199 {8.4 compatible formatting of doubles} \
+ {expr 1e199} \
+ 1.0000000000000001e+199
+test util-16.1.17.200 {8.4 compatible formatting of doubles} \
+ {expr 1e200} \
+ 9.9999999999999997e+199
+test util-16.1.17.201 {8.4 compatible formatting of doubles} \
+ {expr 1e201} \
+ 1e+201
+test util-16.1.17.202 {8.4 compatible formatting of doubles} \
+ {expr 1e202} \
+ 9.999999999999999e+201
+test util-16.1.17.203 {8.4 compatible formatting of doubles} \
+ {expr 1e203} \
+ 9.9999999999999999e+202
+test util-16.1.17.204 {8.4 compatible formatting of doubles} \
+ {expr 1e204} \
+ 9.9999999999999999e+203
+test util-16.1.17.205 {8.4 compatible formatting of doubles} \
+ {expr 1e205} \
+ 1e+205
+test util-16.1.17.206 {8.4 compatible formatting of doubles} \
+ {expr 1e206} \
+ 1e+206
+test util-16.1.17.207 {8.4 compatible formatting of doubles} \
+ {expr 1e207} \
+ 1e+207
+test util-16.1.17.208 {8.4 compatible formatting of doubles} \
+ {expr 1e208} \
+ 9.9999999999999998e+207
+test util-16.1.17.209 {8.4 compatible formatting of doubles} \
+ {expr 1e209} \
+ 1.0000000000000001e+209
+test util-16.1.17.210 {8.4 compatible formatting of doubles} \
+ {expr 1e210} \
+ 9.9999999999999993e+209
+test util-16.1.17.211 {8.4 compatible formatting of doubles} \
+ {expr 1e211} \
+ 9.9999999999999996e+210
+test util-16.1.17.212 {8.4 compatible formatting of doubles} \
+ {expr 1e212} \
+ 9.9999999999999991e+211
+test util-16.1.17.213 {8.4 compatible formatting of doubles} \
+ {expr 1e213} \
+ 9.9999999999999998e+212
+test util-16.1.17.214 {8.4 compatible formatting of doubles} \
+ {expr 1e214} \
+ 9.9999999999999995e+213
+test util-16.1.17.215 {8.4 compatible formatting of doubles} \
+ {expr 1e215} \
+ 9.9999999999999991e+214
+test util-16.1.17.216 {8.4 compatible formatting of doubles} \
+ {expr 1e216} \
+ 1e+216
+test util-16.1.17.217 {8.4 compatible formatting of doubles} \
+ {expr 1e217} \
+ 9.9999999999999996e+216
+test util-16.1.17.218 {8.4 compatible formatting of doubles} \
+ {expr 1e218} \
+ 1.0000000000000001e+218
+test util-16.1.17.219 {8.4 compatible formatting of doubles} \
+ {expr 1e219} \
+ 9.9999999999999997e+218
+test util-16.1.17.220 {8.4 compatible formatting of doubles} \
+ {expr 1e220} \
+ 1e+220
+test util-16.1.17.221 {8.4 compatible formatting of doubles} \
+ {expr 1e221} \
+ 1e+221
+test util-16.1.17.222 {8.4 compatible formatting of doubles} \
+ {expr 1e222} \
+ 1e+222
+test util-16.1.17.223 {8.4 compatible formatting of doubles} \
+ {expr 1e223} \
+ 1e+223
+test util-16.1.17.224 {8.4 compatible formatting of doubles} \
+ {expr 1e224} \
+ 9.9999999999999997e+223
+test util-16.1.17.225 {8.4 compatible formatting of doubles} \
+ {expr 1e225} \
+ 9.9999999999999993e+224
+test util-16.1.17.226 {8.4 compatible formatting of doubles} \
+ {expr 1e226} \
+ 9.9999999999999996e+225
+test util-16.1.17.227 {8.4 compatible formatting of doubles} \
+ {expr 1e227} \
+ 1.0000000000000001e+227
+test util-16.1.17.228 {8.4 compatible formatting of doubles} \
+ {expr 1e228} \
+ 9.9999999999999992e+227
+test util-16.1.17.229 {8.4 compatible formatting of doubles} \
+ {expr 1e229} \
+ 9.9999999999999999e+228
+test util-16.1.17.230 {8.4 compatible formatting of doubles} \
+ {expr 1e230} \
+ 1.0000000000000001e+230
+test util-16.1.17.231 {8.4 compatible formatting of doubles} \
+ {expr 1e231} \
+ 1.0000000000000001e+231
+test util-16.1.17.232 {8.4 compatible formatting of doubles} \
+ {expr 1e232} \
+ 1.0000000000000001e+232
+test util-16.1.17.233 {8.4 compatible formatting of doubles} \
+ {expr 1e233} \
+ 9.9999999999999997e+232
+test util-16.1.17.234 {8.4 compatible formatting of doubles} \
+ {expr 1e234} \
+ 1e+234
+test util-16.1.17.235 {8.4 compatible formatting of doubles} \
+ {expr 1e235} \
+ 1.0000000000000001e+235
+test util-16.1.17.236 {8.4 compatible formatting of doubles} \
+ {expr 1e236} \
+ 1.0000000000000001e+236
+test util-16.1.17.237 {8.4 compatible formatting of doubles} \
+ {expr 1e237} \
+ 9.9999999999999994e+236
+test util-16.1.17.238 {8.4 compatible formatting of doubles} \
+ {expr 1e238} \
+ 1e+238
+test util-16.1.17.239 {8.4 compatible formatting of doubles} \
+ {expr 1e239} \
+ 9.9999999999999999e+238
+test util-16.1.17.240 {8.4 compatible formatting of doubles} \
+ {expr 1e240} \
+ 1e+240
+test util-16.1.17.241 {8.4 compatible formatting of doubles} \
+ {expr 1e241} \
+ 1.0000000000000001e+241
+test util-16.1.17.242 {8.4 compatible formatting of doubles} \
+ {expr 1e242} \
+ 1.0000000000000001e+242
+test util-16.1.17.243 {8.4 compatible formatting of doubles} \
+ {expr 1e243} \
+ 1.0000000000000001e+243
+test util-16.1.17.244 {8.4 compatible formatting of doubles} \
+ {expr 1e244} \
+ 1.0000000000000001e+244
+test util-16.1.17.245 {8.4 compatible formatting of doubles} \
+ {expr 1e245} \
+ 1e+245
+test util-16.1.17.246 {8.4 compatible formatting of doubles} \
+ {expr 1e246} \
+ 1.0000000000000001e+246
+test util-16.1.17.247 {8.4 compatible formatting of doubles} \
+ {expr 1e247} \
+ 9.9999999999999995e+246
+test util-16.1.17.248 {8.4 compatible formatting of doubles} \
+ {expr 1e248} \
+ 1e+248
+test util-16.1.17.249 {8.4 compatible formatting of doubles} \
+ {expr 1e249} \
+ 9.9999999999999992e+248
+test util-16.1.17.250 {8.4 compatible formatting of doubles} \
+ {expr 1e250} \
+ 9.9999999999999992e+249
+test util-16.1.17.251 {8.4 compatible formatting of doubles} \
+ {expr 1e251} \
+ 1e+251
+test util-16.1.17.252 {8.4 compatible formatting of doubles} \
+ {expr 1e252} \
+ 1.0000000000000001e+252
+test util-16.1.17.253 {8.4 compatible formatting of doubles} \
+ {expr 1e253} \
+ 9.9999999999999994e+252
+test util-16.1.17.254 {8.4 compatible formatting of doubles} \
+ {expr 1e254} \
+ 9.9999999999999994e+253
+test util-16.1.17.255 {8.4 compatible formatting of doubles} \
+ {expr 1e255} \
+ 9.9999999999999999e+254
+test util-16.1.17.256 {8.4 compatible formatting of doubles} \
+ {expr 1e256} \
+ 1e+256
+test util-16.1.17.257 {8.4 compatible formatting of doubles} \
+ {expr 1e257} \
+ 1e+257
+test util-16.1.17.258 {8.4 compatible formatting of doubles} \
+ {expr 1e258} \
+ 1.0000000000000001e+258
+test util-16.1.17.259 {8.4 compatible formatting of doubles} \
+ {expr 1e259} \
+ 9.9999999999999993e+258
+test util-16.1.17.260 {8.4 compatible formatting of doubles} \
+ {expr 1e260} \
+ 1.0000000000000001e+260
+test util-16.1.17.261 {8.4 compatible formatting of doubles} \
+ {expr 1e261} \
+ 9.9999999999999993e+260
+test util-16.1.17.262 {8.4 compatible formatting of doubles} \
+ {expr 1e262} \
+ 1e+262
+test util-16.1.17.263 {8.4 compatible formatting of doubles} \
+ {expr 1e263} \
+ 1e+263
+test util-16.1.17.264 {8.4 compatible formatting of doubles} \
+ {expr 1e264} \
+ 1e+264
+test util-16.1.17.265 {8.4 compatible formatting of doubles} \
+ {expr 1e265} \
+ 1.0000000000000001e+265
+test util-16.1.17.266 {8.4 compatible formatting of doubles} \
+ {expr 1e266} \
+ 1e+266
+test util-16.1.17.267 {8.4 compatible formatting of doubles} \
+ {expr 1e267} \
+ 9.9999999999999997e+266
+test util-16.1.17.268 {8.4 compatible formatting of doubles} \
+ {expr 1e268} \
+ 9.9999999999999997e+267
+test util-16.1.17.269 {8.4 compatible formatting of doubles} \
+ {expr 1e269} \
+ 1e+269
+test util-16.1.17.270 {8.4 compatible formatting of doubles} \
+ {expr 1e270} \
+ 1e+270
+test util-16.1.17.271 {8.4 compatible formatting of doubles} \
+ {expr 1e271} \
+ 9.9999999999999995e+270
+test util-16.1.17.272 {8.4 compatible formatting of doubles} \
+ {expr 1e272} \
+ 1.0000000000000001e+272
+test util-16.1.17.273 {8.4 compatible formatting of doubles} \
+ {expr 1e273} \
+ 9.9999999999999995e+272
+test util-16.1.17.274 {8.4 compatible formatting of doubles} \
+ {expr 1e274} \
+ 9.9999999999999992e+273
+test util-16.1.17.275 {8.4 compatible formatting of doubles} \
+ {expr 1e275} \
+ 9.9999999999999996e+274
+test util-16.1.17.276 {8.4 compatible formatting of doubles} \
+ {expr 1e276} \
+ 1.0000000000000001e+276
+test util-16.1.17.277 {8.4 compatible formatting of doubles} \
+ {expr 1e277} \
+ 1e+277
+test util-16.1.17.278 {8.4 compatible formatting of doubles} \
+ {expr 1e278} \
+ 9.9999999999999996e+277
+test util-16.1.17.279 {8.4 compatible formatting of doubles} \
+ {expr 1e279} \
+ 1.0000000000000001e+279
+test util-16.1.17.280 {8.4 compatible formatting of doubles} \
+ {expr 1e280} \
+ 1e+280
+test util-16.1.17.281 {8.4 compatible formatting of doubles} \
+ {expr 1e281} \
+ 1e+281
+test util-16.1.17.282 {8.4 compatible formatting of doubles} \
+ {expr 1e282} \
+ 1e+282
+test util-16.1.17.283 {8.4 compatible formatting of doubles} \
+ {expr 1e283} \
+ 9.9999999999999996e+282
+test util-16.1.17.284 {8.4 compatible formatting of doubles} \
+ {expr 1e284} \
+ 1.0000000000000001e+284
+test util-16.1.17.285 {8.4 compatible formatting of doubles} \
+ {expr 1e285} \
+ 9.9999999999999998e+284
+test util-16.1.17.286 {8.4 compatible formatting of doubles} \
+ {expr 1e286} \
+ 1e+286
+test util-16.1.17.287 {8.4 compatible formatting of doubles} \
+ {expr 1e287} \
+ 1.0000000000000001e+287
+test util-16.1.17.288 {8.4 compatible formatting of doubles} \
+ {expr 1e288} \
+ 1e+288
+test util-16.1.17.289 {8.4 compatible formatting of doubles} \
+ {expr 1e289} \
+ 1.0000000000000001e+289
+test util-16.1.17.290 {8.4 compatible formatting of doubles} \
+ {expr 1e290} \
+ 1.0000000000000001e+290
+test util-16.1.17.291 {8.4 compatible formatting of doubles} \
+ {expr 1e291} \
+ 9.9999999999999996e+290
+test util-16.1.17.292 {8.4 compatible formatting of doubles} \
+ {expr 1e292} \
+ 1e+292
+test util-16.1.17.293 {8.4 compatible formatting of doubles} \
+ {expr 1e293} \
+ 9.9999999999999992e+292
+test util-16.1.17.294 {8.4 compatible formatting of doubles} \
+ {expr 1e294} \
+ 1.0000000000000001e+294
+test util-16.1.17.295 {8.4 compatible formatting of doubles} \
+ {expr 1e295} \
+ 9.9999999999999998e+294
+test util-16.1.17.296 {8.4 compatible formatting of doubles} \
+ {expr 1e296} \
+ 9.9999999999999998e+295
+test util-16.1.17.297 {8.4 compatible formatting of doubles} \
+ {expr 1e297} \
+ 1e+297
+test util-16.1.17.298 {8.4 compatible formatting of doubles} \
+ {expr 1e298} \
+ 9.9999999999999996e+297
+test util-16.1.17.299 {8.4 compatible formatting of doubles} \
+ {expr 1e299} \
+ 1.0000000000000001e+299
+test util-16.1.17.300 {8.4 compatible formatting of doubles} \
+ {expr 1e300} \
+ 1.0000000000000001e+300
+test util-16.1.17.301 {8.4 compatible formatting of doubles} \
+ {expr 1e301} \
+ 1.0000000000000001e+301
+test util-16.1.17.302 {8.4 compatible formatting of doubles} \
+ {expr 1e302} \
+ 1.0000000000000001e+302
+test util-16.1.17.303 {8.4 compatible formatting of doubles} \
+ {expr 1e303} \
+ 1e+303
+test util-16.1.17.304 {8.4 compatible formatting of doubles} \
+ {expr 1e304} \
+ 9.9999999999999994e+303
+test util-16.1.17.305 {8.4 compatible formatting of doubles} \
+ {expr 1e305} \
+ 9.9999999999999994e+304
+test util-16.1.17.306 {8.4 compatible formatting of doubles} \
+ {expr 1e306} \
+ 1e+306
+test util-16.1.17.307 {8.4 compatible formatting of doubles} \
+ {expr 1e307} \
+ 9.9999999999999999e+306
+
+test util-17.1 {bankers' rounding [Bug 3349507]} {ieeeFloatingPoint} {
+ set r {}
+ foreach {input} {
+ 0x1ffffffffffffc000
+ 0x1ffffffffffffc800
+ 0x1ffffffffffffd000
+ 0x1ffffffffffffd800
+ 0x1ffffffffffffe000
+ 0x1ffffffffffffe800
+ 0x1fffffffffffff000
+ 0x1fffffffffffff800
+ } {
+ binary scan [binary format q [expr double($input)]] wu x
+ lappend r [format %#llx $x]
+ binary scan [binary format q [expr double(-$input)]] wu x
+ lappend r [format %#llx $x]
+ }
+ set r
+} [list {*}{
+ 0x43fffffffffffffc 0xc3fffffffffffffc
+ 0x43fffffffffffffc 0xc3fffffffffffffc
+ 0x43fffffffffffffd 0xc3fffffffffffffd
+ 0x43fffffffffffffe 0xc3fffffffffffffe
+ 0x43fffffffffffffe 0xc3fffffffffffffe
+ 0x43fffffffffffffe 0xc3fffffffffffffe
+ 0x43ffffffffffffff 0xc3ffffffffffffff
+ 0x4400000000000000 0xc400000000000000
+}]
+
+set ::tcl_precision $saved_precision
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/var.test b/pkgs/msgcat/tests/var.test
new file mode 100644
index 0000000..f2923de
--- /dev/null
+++ b/pkgs/msgcat/tests/var.test
@@ -0,0 +1,815 @@
+# This file contains tests for the tclVar.c source file. Tests appear in the
+# same order as the C code that they test. The set of tests is currently
+# incomplete since it currently includes only new tests for code changed for
+# the addition of Tcl namespaces. Other variable-related tests appear in
+# several other test files including namespace.test, set.test, trace.test, and
+# upvar.test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2.2
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testupvar [llength [info commands testupvar]]
+testConstraint testgetvarfullname [llength [info commands testgetvarfullname]]
+testConstraint testsetnoerr [llength [info commands testsetnoerr]]
+
+catch {rename p ""}
+catch {namespace delete test_ns_var}
+catch {unset xx}
+catch {unset x}
+catch {unset y}
+catch {unset i}
+catch {unset a}
+catch {unset arr}
+
+test var-1.1 {TclLookupVar, Array handling} -setup {
+ catch {unset a}
+} -body {
+ set x "incr" ;# force no compilation and runtime call to Tcl_IncrCmd
+ set i 10
+ set arr(foo) 37
+ list [$x i] $i [$x arr(foo)] $arr(foo)
+} -result {11 11 38 38}
+test var-1.2 {TclLookupVar, TCL_GLOBAL_ONLY implies global namespace var} {
+ set x "global value"
+ namespace eval test_ns_var {
+ variable x "namespace value"
+ proc p {} {
+ global x ;# specifies TCL_GLOBAL_ONLY to get global x
+ return $x
+ }
+ }
+ test_ns_var::p
+} {global value}
+test var-1.3 {TclLookupVar, TCL_NAMESPACE_ONLY implies namespace var} {
+ namespace eval test_ns_var {
+ proc q {} {
+ variable x ;# specifies TCL_NAMESPACE_ONLY to get namespace x
+ return $x
+ }
+ }
+ test_ns_var::q
+} {namespace value}
+test var-1.4 {TclLookupVar, no active call frame implies global namespace var} {
+ set x
+} {global value}
+test var-1.5 {TclLookupVar, active call frame pushed for namespace eval implies namespace var} {
+ namespace eval test_ns_var {set x}
+} {namespace value}
+test var-1.6 {TclLookupVar, name starts with :: implies some namespace var} {
+ namespace eval test_ns_var {set ::x}
+} {global value}
+test var-1.7 {TclLookupVar, error finding namespace var} -body {
+ set a:::b
+} -returnCodes error -result {can't read "a:::b": no such variable}
+test var-1.8 {TclLookupVar, error finding namespace var} -body {
+ set ::foobarfoo
+} -returnCodes error -result {can't read "::foobarfoo": no such variable}
+test var-1.9 {TclLookupVar, create new namespace var} {
+ namespace eval test_ns_var {
+ set v hello
+ }
+} {hello}
+test var-1.10 {TclLookupVar, create new namespace var} -setup {
+ catch {unset y}
+} -body {
+ namespace eval test_ns_var {
+ set ::y 789
+ }
+ set y
+} -result {789}
+test var-1.11 {TclLookupVar, error creating new namespace var} -body {
+ namespace eval test_ns_var {
+ set ::test_ns_var::foo::bar 314159
+ }
+} -returnCodes error -result {can't set "::test_ns_var::foo::bar": parent namespace doesn't exist}
+test var-1.12 {TclLookupVar, error creating new namespace var} -body {
+ namespace eval test_ns_var {
+ set ::test_ns_var::foo:: 1997
+ }
+} -returnCodes error -result {can't set "::test_ns_var::foo::": parent namespace doesn't exist}
+test var-1.13 {TclLookupVar, new namespace var is created in a particular namespace} {
+ catch {unset aNeWnAmEiNnS}
+ namespace eval test_ns_var {
+ namespace eval test_ns_var2::test_ns_var3 {
+ set aNeWnAmEiNnS 77777
+ }
+ # namespace which builds a name by traversing nsPtr chain to ::
+ namespace which -variable test_ns_var2::test_ns_var3::aNeWnAmEiNnS
+ }
+} {::test_ns_var::test_ns_var2::test_ns_var3::aNeWnAmEiNnS}
+test var-1.14 {TclLookupVar, namespace code ignores ":"s in middle and end of var names} {
+ namespace eval test_ns_var {
+ set : 123
+ set v: 456
+ set x:y: 789
+ list [set :] [set v:] [set x:y:] \
+ ${:} ${v:} ${x:y:} \
+ [expr {":" in [info vars]}] \
+ [expr {"v:" in [info vars]}] \
+ [expr {"x:y:" in [info vars]}]
+ }
+} {123 456 789 123 456 789 1 1 1}
+test var-1.15 {TclLookupVar, resurrect variable via upvar to deleted namespace: compiled code path} {
+ namespace eval test_ns_var {
+ variable foo 2
+ }
+ proc p {} {
+ variable ::test_ns_var::foo
+ lappend result [catch {set foo} msg] $msg
+ namespace delete ::test_ns_var
+ lappend result [catch {set foo 3} msg] $msg
+ lappend result [catch {set foo(3) 3} msg] $msg
+ }
+ p
+} {0 2 1 {can't set "foo": upvar refers to variable in deleted namespace} 1 {can't set "foo(3)": upvar refers to variable in deleted namespace}}
+test var-1.16 {TclLookupVar, resurrect variable via upvar to deleted namespace: uncompiled code path} {
+ namespace eval test_ns_var {
+ variable result
+ namespace eval subns {
+ variable foo 2
+ }
+ upvar 0 subns::foo foo
+ lappend result [catch {set foo} msg] $msg
+ namespace delete subns
+ lappend result [catch {set foo 3} msg] $msg
+ lappend result [catch {set foo(3) 3} msg] $msg
+ namespace delete [namespace current]
+ set result
+ }
+} {0 2 1 {can't set "foo": upvar refers to variable in deleted namespace} 1 {can't set "foo(3)": upvar refers to variable in deleted namespace}}
+test var-1.17 {TclLookupVar, resurrect array element via upvar to deleted array: compiled code path} {
+ namespace eval test_ns_var {
+ variable result
+ proc p {} {
+ array set x {1 2 3 4}
+ upvar 0 x(1) foo
+ lappend result [catch {set foo} msg] $msg
+ unset x
+ lappend result [catch {set foo 3} msg] $msg
+ }
+ set result [p]
+ namespace delete [namespace current]
+ set result
+ }
+} {0 2 1 {can't set "foo": upvar refers to element in deleted array}}
+test var-1.18 {TclLookupVar, resurrect array element via upvar to deleted array: uncompiled code path} {
+ namespace eval test_ns_var {
+ variable result {}
+ variable x
+ array set x {1 2 3 4}
+ upvar 0 x(1) foo
+ lappend result [catch {set foo} msg] $msg
+ unset x
+ lappend result [catch {set foo 3} msg] $msg
+ namespace delete [namespace current]
+ set result
+ }
+} {0 2 1 {can't set "foo": upvar refers to element in deleted array}}
+test var-1.19 {TclLookupVar, right error message when parsing variable name} -body {
+ [format set] thisvar(doesntexist)
+} -returnCodes error -result {can't read "thisvar(doesntexist)": no such variable}
+
+test var-2.1 {Tcl_LappendObjCmd, create var if new} {
+ catch {unset x}
+ lappend x 1 2
+} {1 2}
+
+test var-3.1 {MakeUpvar, TCL_NAMESPACE_ONLY not specified for other var} -setup {
+ catch {unset x}
+} -body {
+ set x 1997
+ proc p {} {
+ global x ;# calls MakeUpvar with TCL_NAMESPACE_ONLY for other var x
+ return $x
+ }
+ p
+} -result {1997}
+test var-3.2 {MakeUpvar, other var has TCL_NAMESPACE_ONLY specified} {
+ namespace eval test_ns_var {
+ catch {unset v}
+ variable v 1998
+ proc p {} {
+ variable v ;# TCL_NAMESPACE_ONLY specified for other var x
+ return $v
+ }
+ p
+ }
+} {1998}
+test var-3.3 {MakeUpvar, my var has TCL_GLOBAL_ONLY specified} -setup {
+ catch {unset a}
+} -constraints testupvar -body {
+ set a 123321
+ proc p {} {
+ # create global xx linked to global a
+ testupvar 1 a {} xx global
+ }
+ list [p] $xx [set xx 789] $a
+} -result {{} 123321 789 789}
+test var-3.4 {MakeUpvar, my var has TCL_NAMESPACE_ONLY specified} -setup {
+ catch {unset a}
+} -constraints testupvar -body {
+ set a 456
+ namespace eval test_ns_var {
+ catch {unset ::test_ns_var::vv}
+ proc p {} {
+ # create namespace var vv linked to global a
+ testupvar 1 a {} vv namespace
+ }
+ p
+ }
+ list $test_ns_var::vv [set test_ns_var::vv 123] $a
+} -result {456 123 123}
+test var-3.5 {MakeUpvar, no call frame so my var will be in global :: ns} -setup {
+ catch {unset aaaaa}
+ catch {unset xxxxx}
+} -body {
+ set aaaaa 77777
+ upvar #0 aaaaa xxxxx
+ list [set xxxxx] [set aaaaa]
+} -result {77777 77777}
+test var-3.6 {MakeUpvar, active call frame pushed for namespace eval} -setup {
+ catch {unset a}
+} -body {
+ set a 121212
+ namespace eval test_ns_var {
+ upvar ::a vvv
+ set vvv
+ }
+} -result {121212}
+test var-3.7 {MakeUpvar, my var has ::s} -setup {
+ catch {unset a}
+} -body {
+ set a 789789
+ upvar #0 a test_ns_var::lnk
+ namespace eval test_ns_var {
+ set lnk
+ }
+} -result {789789}
+test var-3.8 {MakeUpvar, my var already exists in global ns} -setup {
+ catch {unset aaaaa}
+ catch {unset xxxxx}
+} -body {
+ set aaaaa 456654
+ set xxxxx hello
+ upvar #0 aaaaa xxxxx
+ set xxxxx
+} -result {hello}
+test var-3.9 {MakeUpvar, my var has invalid ns name} -setup {
+ catch {unset aaaaa}
+} -returnCodes error -body {
+ set aaaaa 789789
+ upvar #0 aaaaa test_ns_fred::lnk
+} -result {can't create "test_ns_fred::lnk": parent namespace doesn't exist}
+test var-3.10 {MakeUpvar, between namespaces} -body {
+ namespace eval {} {
+ variable bar 0
+ namespace eval foo upvar bar bar
+ set foo::bar 1
+ list $bar $foo::bar
+ }
+} -cleanup {
+ unset ::aaaaa
+} -result {1 1}
+test var-3.11 {MakeUpvar, my var looks like array elem} -setup {
+ catch {unset aaaaa}
+} -returnCodes error -body {
+ set aaaaa 789789
+ upvar #0 aaaaa foo(bar)
+} -result {bad variable name "foo(bar)": upvar won't create a scalar variable that looks like an array element}
+
+test var-4.1 {Tcl_GetVariableName, global variable} testgetvarfullname {
+ catch {unset a}
+ set a 123
+ testgetvarfullname a global
+} ::a
+test var-4.2 {Tcl_GetVariableName, namespace variable} testgetvarfullname {
+ namespace eval test_ns_var {
+ variable george
+ testgetvarfullname george namespace
+ }
+} ::test_ns_var::george
+test var-4.3 {Tcl_GetVariableName, variable can't be array element} -setup {
+ catch {unset a}
+} -constraints testgetvarfullname -body {
+ set a(1) foo
+ testgetvarfullname a(1) global
+} -returnCodes error -result {unknown variable "a(1)"}
+
+test var-5.1 {Tcl_GetVariableFullName, global variable} -setup {
+ catch {unset a}
+} -body {
+ set a bar
+ namespace which -variable a
+} -result {::a}
+test var-5.2 {Tcl_GetVariableFullName, namespace variable} {
+ namespace eval test_ns_var {
+ variable martha
+ namespace which -variable martha
+ }
+} {::test_ns_var::martha}
+test var-5.3 {Tcl_GetVariableFullName, namespace variable} {
+ namespace which -variable test_ns_var::martha
+} {::test_ns_var::martha}
+
+test var-6.1 {Tcl_GlobalObjCmd, variable is qualified by a namespace name} {
+ namespace eval test_ns_var {
+ variable boeing 777
+ }
+ apply {{} {
+ global ::test_ns_var::boeing
+ set boeing
+ }}
+} {777}
+test var-6.2 {Tcl_GlobalObjCmd, variable is qualified by a namespace name} {
+ namespace eval test_ns_var {
+ namespace eval test_ns_nested {
+ variable java java
+ }
+ proc p {} {
+ global ::test_ns_var::test_ns_nested::java
+ set java
+ }
+ }
+ test_ns_var::p
+} {java}
+test var-6.3 {Tcl_GlobalObjCmd, variable named {} qualified by a namespace name} {
+ set ::test_ns_var::test_ns_nested:: 24
+ apply {{} {
+ global ::test_ns_var::test_ns_nested::
+ set {}
+ }}
+} {24}
+test var-6.4 {Tcl_GlobalObjCmd, variable name matching :*} {
+ # Test for Tcl Bug 480176
+ set :v broken
+ proc p {} {
+ global :v
+ set :v fixed
+ }
+ p
+ set :v
+} {fixed}
+test var-6.5 {Tcl_GlobalObjCmd, no-op case (TIP 323)} {
+ global
+} {}
+test var-6.6 {Tcl_GlobalObjCmd, no-op case (TIP 323)} {
+ proc p {} {
+ global
+ }
+ p
+} {}
+
+test var-7.1 {Tcl_VariableObjCmd, create and initialize one new ns variable} -setup {
+ catch {namespace delete test_ns_var}
+} -body {
+ namespace eval test_ns_var {
+ variable one 1
+ }
+ list [info vars test_ns_var::*] [set test_ns_var::one]
+} -result {::test_ns_var::one 1}
+test var-7.2 {Tcl_VariableObjCmd, if new and no value, leave undefined} {
+ set two 2222222
+ namespace eval test_ns_var {
+ variable two
+ }
+ list [info exists test_ns_var::two] [catch {set test_ns_var::two} msg] $msg
+} {0 1 {can't read "test_ns_var::two": no such variable}}
+test var-7.3 {Tcl_VariableObjCmd, "define" var already created above} {
+ namespace eval test_ns_var {
+ variable two 2
+ }
+ list [lsort [info vars test_ns_var::*]] \
+ [namespace eval test_ns_var {set two}]
+} [list [lsort {::test_ns_var::two ::test_ns_var::one}] 2]
+test var-7.4 {Tcl_VariableObjCmd, list of vars} {
+ namespace eval test_ns_var {
+ variable three 3 four 4
+ }
+ list [lsort [info vars test_ns_var::*]] \
+ [namespace eval test_ns_var {expr $three+$four}]
+} [list [lsort {::test_ns_var::four ::test_ns_var::three ::test_ns_var::two ::test_ns_var::one}] 7]
+test var-7.5 {Tcl_VariableObjCmd, value for last var is optional} -setup {
+ catch {unset a}
+ catch {unset five}
+ catch {unset six}
+} -body {
+ set a ""
+ set five 555
+ set six 666
+ namespace eval test_ns_var {
+ variable five 5 six
+ lappend a $five
+ }
+ lappend a $test_ns_var::five \
+ [set test_ns_var::six 6] [set test_ns_var::six] $six
+} -cleanup {
+ catch {unset five}
+ catch {unset six}
+} -result {5 5 6 6 666}
+test var-7.6 {Tcl_VariableObjCmd, variable name can be qualified} -setup {
+ catch {unset newvar}
+} -body {
+ namespace eval test_ns_var {
+ variable ::newvar cheers!
+ }
+ return $newvar
+} -cleanup {
+ catch {unset newvar}
+} -result {cheers!}
+test var-7.7 {Tcl_VariableObjCmd, bad var name} -returnCodes error -body {
+ namespace eval test_ns_var {
+ variable sev:::en 7
+ }
+} -result {can't define "sev:::en": parent namespace doesn't exist}
+test var-7.8 {Tcl_VariableObjCmd, if var already exists and no value is given, leave value unchanged} {
+ set a ""
+ namespace eval test_ns_var {
+ variable eight 8
+ lappend a $eight
+ variable eight
+ lappend a $eight
+ }
+ set a
+} {8 8}
+test var-7.9 {Tcl_VariableObjCmd, mark as namespace var so var persists until namespace is destroyed or var is unset} -setup {
+ catch {namespace delete test_ns_var2}
+} -body {
+ set a ""
+ namespace eval test_ns_var2 {
+ variable x 123
+ variable y
+ variable z
+ }
+ lappend a [lsort [info vars test_ns_var2::*]]
+ lappend a [info exists test_ns_var2::x] [info exists test_ns_var2::y] \
+ [info exists test_ns_var2::z]
+ lappend a [list [catch {set test_ns_var2::y} msg] $msg]
+ lappend a [lsort [info vars test_ns_var2::*]]
+ lappend a [info exists test_ns_var2::y] [info exists test_ns_var2::z]
+ lappend a [set test_ns_var2::y hello]
+ lappend a [info exists test_ns_var2::y] [info exists test_ns_var2::z]
+ lappend a [list [catch {unset test_ns_var2::y} msg] $msg]
+ lappend a [lsort [info vars test_ns_var2::*]]
+ lappend a [info exists test_ns_var2::y] [info exists test_ns_var2::z]
+ lappend a [list [catch {unset test_ns_var2::z} msg] $msg]
+ lappend a [namespace delete test_ns_var2]
+} -result [list [lsort {::test_ns_var2::x ::test_ns_var2::y ::test_ns_var2::z}] 1 0 0\
+ {1 {can't read "test_ns_var2::y": no such variable}}\
+ [lsort {::test_ns_var2::x ::test_ns_var2::y ::test_ns_var2::z}] 0 0\
+ hello 1 0\
+ {0 {}}\
+ [lsort {::test_ns_var2::x ::test_ns_var2::z}] 0 0\
+ {1 {can't unset "test_ns_var2::z": no such variable}}\
+ {}]
+test var-7.10 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} {
+ namespace eval test_ns_var {
+ proc p {} {
+ variable eight
+ list [set eight] [info vars]
+ }
+ p
+ }
+} {8 eight}
+test var-7.11 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} {
+ proc p {} { ;# note this proc is at global :: scope
+ variable test_ns_var::eight
+ list [set eight] [info vars]
+ }
+ p
+} {8 eight}
+test var-7.12 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} {
+ namespace eval test_ns_var {
+ variable {} {My name is empty}
+ }
+ proc p {} { ;# note this proc is at global :: scope
+ variable test_ns_var::
+ list [set {}] [info vars]
+ }
+ p
+} {{My name is empty} {{}}}
+test var-7.13 {Tcl_VariableObjCmd, variable named ":"} {
+ namespace eval test_ns_var {
+ variable : {My name is ":"}
+ proc p {} {
+ variable :
+ list [set :] [info vars]
+ }
+ p
+ }
+} {{My name is ":"} :}
+test var-7.14 {Tcl_VariableObjCmd, array element parameter} -body {
+ namespace eval test_ns_var { variable arrayvar(1) }
+} -returnCodes error -result "can't define \"arrayvar(1)\": name refers to an element in an array"
+test var-7.15 {Tcl_VariableObjCmd, array element parameter} -body {
+ namespace eval test_ns_var {
+ variable arrayvar
+ set arrayvar(1) x
+ variable arrayvar(1) y
+ }
+} -returnCodes error -result "can't define \"arrayvar(1)\": name refers to an element in an array"
+test var-7.16 {Tcl_VariableObjCmd, no args (TIP 323)} {
+ variable
+} {}
+test var-7.17 {Tcl_VariableObjCmd, no args (TIP 323)} {
+ namespace eval test_ns_var {
+ variable
+ }
+} {}
+
+test var-8.1 {TclDeleteVars, "unset" traces are called with fully-qualified var names} -setup {
+ catch {namespace delete test_ns_var}
+ catch {unset a}
+} -body {
+ namespace eval test_ns_var {
+ variable v 123
+ variable info ""
+ proc traceUnset {name1 name2 op} {
+ variable info
+ set info [concat $info [list $name1 $name2 $op]]
+ }
+ trace var v u [namespace code traceUnset]
+ }
+ list [unset test_ns_var::v] $test_ns_var::info
+} -result {{} {test_ns_var::v {} u}}
+test var-8.2 {TclDeleteNamespaceVars, "unset" traces on ns delete are called with fully-qualified var names} -setup {
+ catch {namespace delete test_ns_var}
+ catch {unset a}
+} -body {
+ set info ""
+ namespace eval test_ns_var {
+ variable v 123 1
+ trace var v u ::traceUnset
+ }
+ proc traceUnset {name1 name2 op} {
+ set ::info [concat $::info [list $name1 $name2 $op]]
+ }
+ list [namespace delete test_ns_var] $::info
+} -result {{} {::test_ns_var::v {} u}}
+
+test var-9.1 {behaviour of TclGet/SetVar simple get/set} -setup {
+ catch {unset u}
+ catch {unset v}
+} -constraints testsetnoerr -body {
+ list \
+ [set u a; testsetnoerr u] \
+ [testsetnoerr v b] \
+ [testseterr u] \
+ [unset v; testseterr v b]
+} -result [list {before get a} {before set b} {before get a} {before set b}]
+test var-9.2 {behaviour of TclGet/SetVar namespace get/set} -setup {
+ catch {namespace delete ns}
+} -constraints testsetnoerr -body {
+ namespace eval ns {variable u a; variable v}
+ list \
+ [testsetnoerr ns::u] \
+ [testsetnoerr ns::v b] \
+ [testseterr ns::u] \
+ [unset ns::v; testseterr ns::v b]
+} -result [list {before get a} {before set b} {before get a} {before set b}]
+test var-9.3 {behaviour of TclGetVar no variable} -setup {
+ catch {unset u}
+} -constraints testsetnoerr -body {
+ list \
+ [catch {testsetnoerr u} res] $res \
+ [catch {testseterr u} res] $res
+} -result {1 {before get} 1 {can't read "u": no such variable}}
+test var-9.4 {behaviour of TclGetVar no namespace variable} -setup {
+ catch {namespace delete ns}
+} -constraints testsetnoerr -body {
+ namespace eval ns {}
+ list \
+ [catch {testsetnoerr ns::w} res] $res \
+ [catch {testseterr ns::w} res] $res
+} -result {1 {before get} 1 {can't read "ns::w": no such variable}}
+test var-9.5 {behaviour of TclGetVar no namespace} -setup {
+ catch {namespace delete ns}
+} -constraints testsetnoerr -body {
+ list \
+ [catch {testsetnoerr ns::u} res] $res \
+ [catch {testseterr ns::v} res] $res
+} -result {1 {before get} 1 {can't read "ns::v": no such variable}}
+test var-9.6 {behaviour of TclSetVar no namespace} -setup {
+ catch {namespace delete ns}
+} -constraints testsetnoerr -body {
+ list \
+ [catch {testsetnoerr ns::v 1} res] $res \
+ [catch {testseterr ns::v 1} res] $res
+} -result {1 {before set} 1 {can't set "ns::v": parent namespace doesn't exist}}
+test var-9.7 {behaviour of TclGetVar array variable} -setup {
+ catch {unset arr}
+} -constraints testsetnoerr -body {
+ set arr(1) 1
+ list \
+ [catch {testsetnoerr arr} res] $res \
+ [catch {testseterr arr} res] $res
+} -result {1 {before get} 1 {can't read "arr": variable is array}}
+test var-9.8 {behaviour of TclSetVar array variable} -setup {
+ catch {unset arr}
+} -constraints testsetnoerr -body {
+ set arr(1) 1
+ list \
+ [catch {testsetnoerr arr 2} res] $res \
+ [catch {testseterr arr 2} res] $res
+} -result {1 {before set} 1 {can't set "arr": variable is array}}
+test var-9.9 {behaviour of TclGetVar read trace success} -setup {
+ catch {unset u}
+ catch {unset v}
+} -constraints testsetnoerr -body {
+ proc resetvar {val name elem op} {upvar 1 $name v; set v $val}
+ set u 10
+ trace var u r [list resetvar 1]
+ trace var v r [list resetvar 2]
+ list \
+ [testsetnoerr u] \
+ [testseterr v]
+} -result {{before get 1} {before get 2}}
+test var-9.10 {behaviour of TclGetVar read trace error} testsetnoerr {
+ proc writeonly args {error "write-only"}
+ set v 456
+ trace var v r writeonly
+ list \
+ [catch {testsetnoerr v} msg] $msg \
+ [catch {testseterr v} msg] $msg
+} {1 {before get} 1 {can't read "v": write-only}}
+test var-9.11 {behaviour of TclSetVar write trace success} -setup {
+ catch {unset u}
+ catch {unset v}
+} -constraints testsetnoerr -body {
+ proc doubleval {name elem op} {upvar 1 $name v; set v [expr {2 * $v}]}
+ set v 1
+ trace var v w doubleval
+ trace var u w doubleval
+ list \
+ [testsetnoerr u 2] \
+ [testseterr v 3]
+} -result {{before set 4} {before set 6}}
+test var-9.12 {behaviour of TclSetVar write trace error} testsetnoerr {
+ proc readonly args {error "read-only"}
+ set v 456
+ trace var v w readonly
+ list \
+ [catch {testsetnoerr v 2} msg] $msg $v \
+ [catch {testseterr v 3} msg] $msg $v
+} {1 {before set} 2 1 {can't set "v": read-only} 3}
+
+test var-10.1 {can't nest arrays with array set} -setup {
+ catch {unset arr}
+} -returnCodes error -body {
+ array set arr(x) {a 1 b 2}
+} -result {can't set "arr(x)": variable isn't array}
+test var-10.2 {can't nest arrays with array set} -setup {
+ catch {unset arr}
+} -returnCodes error -body {
+ array set arr(x) {}
+} -result {can't set "arr(x)": variable isn't array}
+
+test var-11.1 {array unset} -setup {
+ catch {unset a}
+} -body {
+ array set a { 1,1 a 1,2 b 2,1 c 2,3 d }
+ array unset a 1,*
+ lsort -dict [array names a]
+} -result {2,1 2,3}
+test var-11.2 {array unset} -setup {
+ catch {unset a}
+} -body {
+ array set a { 1,1 a 1,2 b }
+ array unset a
+ array exists a
+} -result 0
+test var-11.3 {array unset errors} -setup {
+ catch {unset a}
+} -returnCodes error -body {
+ array set a { 1,1 a 1,2 b }
+ array unset a pattern too
+} -result {wrong # args: should be "array unset arrayName ?pattern?"}
+
+test var-12.1 {TclFindCompiledLocals, {} array name} {
+ namespace eval n {
+ proc p {} {
+ variable {}
+ set (0) 0
+ set (1) 1
+ set n 2
+ set ($n) 2
+ set ($n,foo) 2
+ }
+ p
+ lsort -dictionary [array names {}]
+ }
+} {0 1 2 2,foo}
+
+test var-13.1 {Tcl_UnsetVar2, unset array with trace set on element} -setup {
+ catch {unset t}
+} -body {
+ proc foo {var ind op} {
+ global t
+ set foo bar
+ }
+ namespace eval :: {
+ set t(1) 1
+ trace variable t(1) u foo
+ unset t
+ }
+ set x "If you see this, it worked"
+} -result "If you see this, it worked"
+
+test var-14.1 {array names syntax} -body {
+ array names foo bar baz snafu
+} -returnCodes 1 -match glob -result *
+test var-14.2 {array names -glob} -body {
+ array names tcl_platform -glob os
+} -result os
+
+test var-15.1 {segfault in [unset], [Bug 735335]} {
+ proc A { name } {
+ upvar $name var
+ set var $name
+ }
+ #
+ # Note that the variable name has to be
+ # unused previously for the segfault to
+ # be triggered.
+ #
+ namespace eval test A useSomeUnlikelyNameHere
+ namespace eval test unset useSomeUnlikelyNameHere
+} {}
+
+test var-16.1 {CallVarTraces: save/restore interp error state} {
+ trace add variable ::errorCode write " ;#"
+ catch {error foo bar baz}
+ trace remove variable ::errorCode write " ;#"
+ set ::errorInfo
+} bar
+
+test var-17.1 {TclArraySet [Bug 1669489]} -setup {
+ unset -nocomplain ::a
+} -body {
+ namespace eval :: {
+ set elements {1 2 3 4}
+ trace add variable a write "string length \$elements ;#"
+ array set a $elements
+ }
+} -cleanup {
+ unset -nocomplain ::a ::elements
+} -result {}
+
+test var-18.1 {array unset and unset traces: Bug 2939073} -setup {
+ set already 0
+ unset x
+} -body {
+ array set x {e 1 i 1}
+ trace add variable x unset {apply {args {
+ global already x
+ if {!$already} {
+ set already 1
+ unset x(i)
+ }
+ }}}
+ # The next command would crash reliably with memory debugging prior to the
+ # bug fix.
+ array unset x *
+ array size x
+} -cleanup {
+ unset x already
+} -result 0
+
+test var-19.1 {crash when freeing locals hashtable: Bug 3037525} {
+ proc foo {} { catch {upvar 0 dummy \$index} }
+ foo ; # This crashes without the fix for the bug
+ rename foo {}
+} {}
+
+catch {namespace delete ns}
+catch {unset arr}
+catch {unset v}
+
+catch {rename p ""}
+catch {namespace delete test_ns_var}
+catch {namespace delete test_ns_var2}
+catch {unset xx}
+catch {unset x}
+catch {unset y}
+catch {unset i}
+catch {unset a}
+catch {unset xxxxx}
+catch {unset aaaaa}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/while-old.test b/pkgs/msgcat/tests/while-old.test
new file mode 100644
index 0000000..ee17d0b
--- /dev/null
+++ b/pkgs/msgcat/tests/while-old.test
@@ -0,0 +1,119 @@
+# Commands covered: while
+#
+# This file contains the original set of tests for Tcl's while command.
+# Since the while command is now compiled, a new set of tests covering
+# the new implementation is in the file "while.test". Sourcing this file
+# into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+test while-old-1.1 {basic while loops} {
+ set count 0
+ while {$count < 10} {set count [expr $count+1]}
+ set count
+} 10
+test while-old-1.2 {basic while loops} {
+ set value xxx
+ while {2 > 3} {set value yyy}
+ set value
+} xxx
+test while-old-1.3 {basic while loops} {
+ set value 1
+ while {"true"} {
+ incr value;
+ if {$value > 5} {
+ break;
+ }
+ }
+ set value
+} 6
+test while-old-1.4 {basic while loops, multiline test expr} {
+ set value 1
+ while {($tcl_platform(platform) != "foobar1") && \
+ ($tcl_platform(platform) != "foobar2")} {
+ incr value
+ break
+ }
+ set value
+} {2}
+test while-old-1.5 {basic while loops, test expr in quotes} {
+ set value 1
+ while "0 < 3" {set value 2; break}
+ set value
+} {2}
+
+test while-old-2.1 {continue in while loop} {
+ set list {1 2 3 4 5}
+ set index 0
+ set result {}
+ while {$index < 5} {
+ if {$index == 2} {set index [expr $index+1]; continue}
+ set result [concat $result [lindex $list $index]]
+ set index [expr $index+1]
+ }
+ set result
+} {1 2 4 5}
+
+test while-old-3.1 {break in while loop} {
+ set list {1 2 3 4 5}
+ set index 0
+ set result {}
+ while {$index < 5} {
+ if {$index == 3} break
+ set result [concat $result [lindex $list $index]]
+ set index [expr $index+1]
+ }
+ set result
+} {1 2 3}
+
+test while-old-4.1 {errors in while loops} {
+ set err [catch {while} msg]
+ list $err $msg
+} {1 {wrong # args: should be "while test command"}}
+test while-old-4.2 {errors in while loops} {
+ set err [catch {while 1} msg]
+ list $err $msg
+} {1 {wrong # args: should be "while test command"}}
+test while-old-4.3 {errors in while loops} {
+ set err [catch {while 1 2 3} msg]
+ list $err $msg
+} {1 {wrong # args: should be "while test command"}}
+test while-old-4.4 {errors in while loops} {
+ set err [catch {while {"a"+"b"} {error "loop aborted"}} msg]
+ list $err $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test while-old-4.5 {errors in while loops} {
+ catch {unset x}
+ set x 1
+ set err [catch {while {$x} {set x foo}} msg]
+ list $err $msg
+} {1 {expected boolean value but got "foo"}}
+test while-old-4.6 {errors in while loops} {
+ set err [catch {while {1} {error "loop aborted"}} msg]
+ list $err $msg $::errorInfo
+} {1 {loop aborted} {loop aborted
+ while executing
+"error "loop aborted""}}
+
+test while-old-5.1 {while return result} {
+ while {0} {set a 400}
+} {}
+test while-old-5.2 {while return result} {
+ set x 1
+ while {$x} {set x 0}
+} {}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/while.test b/pkgs/msgcat/tests/while.test
new file mode 100644
index 0000000..642ec93
--- /dev/null
+++ b/pkgs/msgcat/tests/while.test
@@ -0,0 +1,702 @@
+# Commands covered: while
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# Basic "while" operation.
+
+catch {unset i}
+catch {unset a}
+
+test while-1.1 {TclCompileWhileCmd: missing test expression} -body {
+ while
+} -returnCodes error -result {wrong # args: should be "while test command"}
+test while-1.2 {TclCompileWhileCmd: error in test expression} -body {
+ set i 0
+ catch {while {$i<} break}
+ return $::errorInfo
+} -cleanup {
+ unset i
+} -match glob -result {*"while {$i<} break"}
+test while-1.3 {TclCompileWhileCmd: error in test expression} -body {
+ while {"a"+"b"} {error "loop aborted"}
+} -returnCodes error -result {can't use non-numeric string as operand of "+"}
+test while-1.4 {TclCompileWhileCmd: multiline test expr} -body {
+ set value 1
+ while {($tcl_platform(platform) != "foobar1") && \
+ ($tcl_platform(platform) != "foobar2")} {
+ incr value
+ break
+ }
+ return $value
+} -cleanup {
+ unset value
+} -result {2}
+test while-1.5 {TclCompileWhileCmd: non-numeric boolean test expr} -body {
+ set value 1
+ while {"true"} {
+ incr value;
+ if {$value > 5} {
+ break;
+ }
+ }
+ return $value
+} -cleanup {
+ unset value
+} -result 6
+test while-1.6 {TclCompileWhileCmd: test expr is enclosed in quotes} {
+ set i 0
+ while "$i > 5" {}
+} {}
+test while-1.7 {TclCompileWhileCmd: missing command body} -body {
+ set i 0
+ while {$i < 5}
+} -returnCodes error -result {wrong # args: should be "while test command"}
+test while-1.8 {TclCompileWhileCmd: error compiling command body} -body {
+ set i 0
+ catch {while {$i < 5} {set}}
+ return $::errorInfo
+} -match glob -cleanup {
+ unset i
+} -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"*}
+test while-1.9 {TclCompileWhileCmd: simple command body} -body {
+ set a {}
+ set i 1
+ while {$i<6} {
+ if $i==4 break
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i
+} -result {1 2 3}
+test while-1.10 {TclCompileWhileCmd: command body in quotes} -body {
+ set a {}
+ set i 1
+ while {$i<6} "append a x; incr i"
+ return $a
+} -cleanup {
+ unset a i
+} -result {xxxxx}
+test while-1.11 {TclCompileWhileCmd: computed command body} -setup {
+ catch {unset x1}
+ catch {unset bb}
+ catch {unset x2}
+} -body {
+ set x1 {append a x1; }
+ set bb {break}
+ set x2 {; append a x2; incr i}
+ set a {}
+ set i 1
+ while {$i<6} $x1$bb$x2
+ return $a
+} -cleanup {
+ unset x1 bb x2 a i
+} -result {x1}
+test while-1.12 {TclCompileWhileCmd: long command body} -body {
+ set a {}
+ set i 1
+ while {$i<6} {
+ if $i==4 break
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i
+} -result {1 2 3}
+test while-1.13 {TclCompileWhileCmd: while command result} -body {
+ set i 0
+ set a [while {$i < 5} {incr i}]
+ return $a
+} -cleanup {
+ unset a i
+} -result {}
+test while-1.14 {TclCompileWhileCmd: while command result} -body {
+ set i 0
+ set a [while {$i < 5} {if $i==3 break; incr i}]
+ return $a
+} -cleanup {
+ unset a i
+} -result {}
+
+# Check "while" and "continue".
+
+test while-2.1 {continue tests} -body {
+ set a {}
+ set i 1
+ while {$i <= 4} {
+ incr i
+ if {$i == 3} continue
+ set a [concat $a $i]
+ }
+ return $a
+} -cleanup {
+ unset a i
+} -result {2 4 5}
+test while-2.2 {continue tests} -body {
+ set a {}
+ set i 1
+ while {$i <= 4} {
+ incr i
+ if {$i != 2} continue
+ set a [concat $a $i]
+ }
+ return $a
+} -cleanup {
+ unset a i
+} -result {2}
+test while-2.3 {continue tests, nested loops} -body {
+ set msg {}
+ set i 1
+ while {$i <= 4} {
+ incr i
+ set a 1
+ while {$a <= 2} {
+ incr a
+ if {$i>=3 && $a>=3} continue
+ set msg [concat $msg "$i.$a"]
+ }
+ }
+ return $msg
+} -cleanup {
+ unset a i msg
+} -result {2.2 2.3 3.2 4.2 5.2}
+test while-2.4 {continue tests, long command body} -body {
+ set a {}
+ set i 1
+ while {$i<6} {
+ if $i==2 {incr i; continue}
+ if $i==4 break
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i
+} -result {1 3}
+
+# Check "while" and "break".
+
+test while-3.1 {break tests} -body {
+ set a {}
+ set i 1
+ while {$i <= 4} {
+ if {$i == 3} break
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i
+} -result {1 2}
+test while-3.2 {break tests, nested loops} -body {
+ set msg {}
+ set i 1
+ while {$i <= 4} {
+ set a 1
+ while {$a <= 2} {
+ if {$i>=2 && $a>=2} break
+ set msg [concat $msg "$i.$a"]
+ incr a
+ }
+ incr i
+ }
+ return $msg
+} -cleanup {
+ unset a i msg
+} -result {1.1 1.2 2.1 3.1 4.1}
+test while-3.3 {break tests, long command body} -body {
+ set a {}
+ set i 1
+ while {$i<6} {
+ if $i==2 {incr i; continue}
+ if $i==5 break
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if $i==4 break
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i
+} -result {1 3}
+
+# Check "while" with computed command names.
+
+test while-4.1 {while and computed command names} -body {
+ set i 0
+ set z while
+ $z {$i < 10} {
+ incr i
+ }
+ return $i
+} -cleanup {
+ unset i z
+} -result 10
+test while-4.2 {while (not compiled): missing test expression} -body {
+ set z while
+ $z
+} -returnCodes error -cleanup {
+ unset z
+} -result {wrong # args: should be "while test command"}
+test while-4.3 {while (not compiled): error in test expression} -body {
+ set i 0
+ set z while
+ catch {$z {$i<} {set x 1}}
+ return $::errorInfo
+} -match glob -cleanup {
+ unset i z
+} -result {*"$z {$i<} {set x 1}"}
+test while-4.4 {while (not compiled): error in test expression} -body {
+ set z while
+ $z {"a"+"b"} {error "loop aborted"}
+} -returnCodes error -result {can't use non-numeric string as operand of "+"}
+test while-4.5 {while (not compiled): multiline test expr} -body {
+ set value 1
+ set z while
+ $z {($tcl_platform(platform) != "foobar1") && \
+ ($tcl_platform(platform) != "foobar2")} {
+ incr value
+ break
+ }
+ return $value
+} -cleanup {
+ unset value z
+} -result {2}
+test while-4.6 {while (not compiled): non-numeric boolean test expr} -body {
+ set value 1
+ set z while
+ $z {"true"} {
+ incr value;
+ if {$value > 5} {
+ break;
+ }
+ }
+ return $value
+} -cleanup {
+ unset value z
+} -result 6
+test while-4.7 {while (not compiled): test expr is enclosed in quotes} -body {
+ set i 0
+ set z while
+ $z "$i > 5" {}
+} -cleanup {
+ unset i z
+} -result {}
+test while-4.8 {while (not compiled): missing command body} -body {
+ set i 0
+ set z while
+ $z {$i < 5}
+} -returnCodes error -cleanup {
+ unset i z
+} -result {wrong # args: should be "while test command"}
+test while-4.9 {while (not compiled): error compiling command body} -body {
+ set i 0
+ set z while
+ catch {$z {$i < 5} {set}}
+ set ::errorInfo
+} -match glob -cleanup {
+ unset i z
+} -result {wrong # args: should be "set varName ?newValue?"
+ while *ing
+"set"
+ ("while" body line 1)
+ invoked from within
+"$z {$i < 5} {set}"}
+test while-4.10 {while (not compiled): simple command body} -body {
+ set a {}
+ set i 1
+ set z while
+ $z {$i<6} {
+ if $i==4 break
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i z
+} -result {1 2 3}
+test while-4.11 {while (not compiled): command body in quotes} -body {
+ set a {}
+ set i 1
+ set z while
+ $z {$i<6} "append a x; incr i"
+ return $a
+} -cleanup {
+ unset a i z
+} -result {xxxxx}
+test while-4.12 {while (not compiled): computed command body} -setup {
+ catch {unset x1}
+ catch {unset bb}
+ catch {unset x2}
+} -body {
+ set z while
+ set x1 {append a x1; }
+ set bb {break}
+ set x2 {; append a x2; incr i}
+ set a {}
+ set i 1
+ $z {$i<6} $x1$bb$x2
+ return $a
+} -cleanup {
+ unset z x1 bb x2 a i
+} -result {x1}
+test while-4.13 {while (not compiled): long command body} -body {
+ set a {}
+ set z while
+ set i 1
+ $z {$i<6} {
+ if $i==4 break
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i z
+} -result {1 2 3}
+test while-4.14 {while (not compiled): while command result} -body {
+ set i 0
+ set z while
+ set a [$z {$i < 5} {incr i}]
+ return $a
+} -cleanup {
+ unset a i z
+} -result {}
+test while-4.15 {while (not compiled): while command result} -body {
+ set i 0
+ set z while
+ set a [$z {$i < 5} {if $i==3 break; incr i}]
+ return $a
+} -cleanup {
+ unset a i z
+} -result {}
+
+# Check "break" with computed command names.
+
+test while-5.1 {break and computed command names} -body {
+ set i 0
+ set z break
+ while 1 {
+ if {$i > 10} $z
+ incr i
+ }
+ return $i
+} -cleanup {
+ unset i z
+} -result 11
+test while-5.2 {break tests with computed command names} -body {
+ set a {}
+ set i 1
+ set z break
+ while {$i <= 4} {
+ if {$i == 3} $z
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i z
+} -result {1 2}
+test while-5.3 {break tests, nested loops with computed command names} -body {
+ set msg {}
+ set i 1
+ set z break
+ while {$i <= 4} {
+ set a 1
+ while {$a <= 2} {
+ if {$i>=2 && $a>=2} $z
+ set msg [concat $msg "$i.$a"]
+ incr a
+ }
+ incr i
+ }
+ return $msg
+} -cleanup {
+ unset a i z msg
+} -result {1.1 1.2 2.1 3.1 4.1}
+test while-5.4 {break tests, long command body with computed command names} -body {
+ set a {}
+ set i 1
+ set z break
+ while {$i<6} {
+ if $i==2 {incr i; continue}
+ if $i==5 $z
+ if $i>5 continue
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if $i==4 $z
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i z
+} -result {1 3}
+
+# Check "continue" with computed command names.
+
+test while-6.1 {continue and computed command names} -body {
+ set i 0
+ set z continue
+ while 1 {
+ incr i
+ if {$i < 10} $z
+ break
+ }
+ return $i
+} -cleanup {
+ unset i z
+} -result 10
+test while-6.2 {continue tests} -body {
+ set a {}
+ set i 1
+ set z continue
+ while {$i <= 4} {
+ incr i
+ if {$i == 3} $z
+ set a [concat $a $i]
+ }
+ return $a
+} -cleanup {
+ unset a i z
+} -result {2 4 5}
+test while-6.3 {continue tests with computed command names} -body {
+ set a {}
+ set i 1
+ set z continue
+ while {$i <= 4} {
+ incr i
+ if {$i != 2} $z
+ set a [concat $a $i]
+ }
+ return $a
+} -cleanup {
+ unset a i z
+} -result {2}
+test while-6.4 {continue tests, nested loops with computed command names} -body {
+ set msg {}
+ set i 1
+ set z continue
+ while {$i <= 4} {
+ incr i
+ set a 1
+ while {$a <= 2} {
+ incr a
+ if {$i>=3 && $a>=3} $z
+ set msg [concat $msg "$i.$a"]
+ }
+ }
+ return $msg
+} -cleanup {
+ unset a i z msg
+} -result {2.2 2.3 3.2 4.2 5.2}
+test while-6.5 {continue tests, long command body with computed command names} -body {
+ set a {}
+ set i 1
+ set z continue
+ while {$i<6} {
+ if $i==2 {incr i; continue}
+ if $i==4 break
+ if $i>5 $z
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ if {$i>6 && $tcl_platform(machine)=="xxx"} {
+ catch {set a $a} msg
+ catch {incr i 5} msg
+ catch {incr i -5} msg
+ }
+ set a [concat $a $i]
+ incr i
+ }
+ return $a
+} -cleanup {
+ unset a i z
+} -result {1 3}
+
+# Test for incorrect "double evaluation" semantics
+
+test while-7.1 {delayed substitution of body} -body {
+ set i 0
+ while {[incr i] < 10} "
+ set result $i
+ "
+ proc p {} {
+ set i 0
+ while {[incr i] < 10} "
+ set result $i
+ "
+ return $result
+ }
+ append result [p]
+} -cleanup {
+ unset result i
+} -result {00}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/pkgs/msgcat/tests/winConsole.test b/pkgs/msgcat/tests/winConsole.test
new file mode 100644
index 0000000..fdde41c
--- /dev/null
+++ b/pkgs/msgcat/tests/winConsole.test
@@ -0,0 +1,48 @@
+# This file tests the tclWinConsole.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+
+test winConsole-1.1 {Console file channel: non-blocking gets} {win interactive} {
+ set oldmode [fconfigure stdin]
+
+ puts stdout "Enter abcdef<return> now: " nonewline
+ flush stdout
+ fileevent stdin readable {
+ if {[gets stdin line] >= 0} {
+ set result $line
+ } else {
+ set result "gets failed"
+ }
+ }
+
+ fconfigure stdin -blocking 0 -buffering line
+
+ set result {}
+ vwait result
+
+ #cleanup the fileevent
+ fileevent stdin readable {}
+ fconfigure stdin {*}$oldmode
+
+ set result
+
+} "abcdef"
+
+#cleanup
+
+::tcltest::cleanupTests
+return
+
diff --git a/pkgs/msgcat/tests/winDde.test b/pkgs/msgcat/tests/winDde.test
new file mode 100644
index 0000000..83f3598
--- /dev/null
+++ b/pkgs/msgcat/tests/winDde.test
@@ -0,0 +1,471 @@
+# This file tests the tclWinDde.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {"::tcltest" ni [namespace children]} {
+ package require tcltest 2
+ #tcltest::configure -verbose {pass start}
+ namespace import -force ::tcltest::*
+}
+
+if [catch {
+ # Is the dde extension already static to this shell?
+ if [catch {load {} Dde; set ::ddelib {}}] {
+ # try the location given to use on the commandline to tcltest
+ ::tcltest::loadTestedCommands
+ load $::ddelib Dde
+ }
+ testConstraint dde 1
+}] {
+ testConstraint dde 0
+}
+
+
+# -------------------------------------------------------------------------
+# Setup a script for a test server
+#
+
+set scriptName [makeFile {} script1.tcl]
+
+proc createChildProcess {ddeServerName args} {
+ file delete -force $::scriptName
+
+ set f [open $::scriptName w+]
+ puts $f [list set ddeServerName $ddeServerName]
+ if {$::ddelib != ""} {
+ puts $f [list load $::ddelib Dde]
+ }
+ puts $f {
+ # DDE child server -
+ #
+ if {"::tcltest" ni [namespace children]} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+ }
+
+ # If an error occurs during the tests, this process may end up not
+ # being closed down. To deal with this we create a 30s timeout.
+ proc ::DoTimeout {} {
+ global done ddeServerName
+ set done 1
+ puts "winDde.test child process $ddeServerName timed out."
+ flush stdout
+ }
+ set timeout [after 30000 ::DoTimeout]
+
+ # Define a restricted handler.
+ proc Handler1 {cmd} {
+ if {$cmd eq "stop"} {set ::done 1}
+ if {$cmd == ""} {
+ set cmd "null data"
+ }
+ puts $cmd ; flush stdout
+ return
+ }
+ proc Handler2 {cmd} {
+ if {$cmd eq "stop"} {set ::done 1}
+ puts [uplevel \#0 $cmd] ; flush stdout
+ return
+ }
+ proc Handler3 {prefix cmd} {
+ if {$cmd eq "stop"} {set ::done 1}
+ puts [list $prefix $cmd] ; flush stdout
+ return
+ }
+ }
+ # set the dde server name to the supplied argument.
+ puts $f [list dde servername {*}$args -- $ddeServerName]
+ puts $f {
+ # run the server and handle final cleanup.
+ after 200;# give dde a chance to get going.
+ puts ready
+ flush stdout
+ vwait done
+ # allow enough time for the calling process to
+ # claim all results, to avoid spurious "server did
+ # not respond"
+ after 200 {set reallyDone 1}
+ vwait reallyDone
+ exit
+ }
+ close $f
+
+ # run the child server script.
+ set f [open |[list [interpreter] $::scriptName] r]
+ fconfigure $f -buffering line
+ gets $f line
+ return $f
+}
+
+# -------------------------------------------------------------------------
+
+test winDde-1.1 {Settings the server's topic name} -constraints dde -body {
+ list [dde servername foobar] [dde servername] [dde servername self]
+} -result {foobar foobar self}
+
+test winDde-2.1 {Checking for other services} -constraints dde -body {
+ expr [llength [dde services {} {}]] >= 0
+} -result 1
+test winDde-2.2 {Checking for existence, with service and topic specified} \
+ -constraints dde -body {
+ llength [dde services TclEval self]
+} -result 1
+test winDde-2.3 {Checking for existence, with only the service specified} \
+ -constraints dde -body {
+ expr [llength [dde services TclEval {}]] >= 1
+} -result 1
+test winDde-2.4 {Checking for existence, with only the topic specified} \
+ -constraints dde -body {
+ expr [llength [dde services {} self]] >= 1
+} -result 1
+
+# -------------------------------------------------------------------------
+
+test winDde-3.1 {DDE execute locally} -constraints dde -body {
+ set \xe1 ""
+ dde execute TclEval self [list set \xe1 foo]
+ set \xe1
+} -result foo
+test winDde-3.2 {DDE execute -async locally} -constraints dde -body {
+ set \xe1 ""
+ dde execute -async TclEval self [list set \xe1 foo]
+ update
+ set \xe1
+} -result foo
+test winDde-3.3 {DDE request locally} -constraints dde -body {
+ set a ""
+ dde execute TclEval self [list set a foo]
+ dde request TclEval self a
+} -result foo
+test winDde-3.4 {DDE eval locally} -constraints dde -body {
+ set \xe1 ""
+ dde eval self set \xe1 foo
+} -result foo
+test winDde-3.5 {DDE request locally} -constraints dde -body {
+ set a ""
+ dde execute TclEval self [list set a foo]
+ dde request -binary TclEval self a
+} -result "foo\x00"
+# Set variable a to A with diaeresis (unicode C4) by relying on the fact
+# that utf8 is sent (e.g. "c3 84" on the wire)
+test winDde-3.6 {DDE request utf8} -constraints dde -body {
+ set a "not set"
+ dde execute TclEval self "set a \xc4"
+ scan $a %c
+} -result 196
+# Set variable a to A with diaeresis (unicode C4) using binary execute
+# and compose utf-8 (e.g. "c3 84" ) manualy
+test winDde-3.7 {DDE request binary} -constraints dde -body {
+ set a "not set"
+ dde execute -binary TclEval self [list set a \xc3\x84\x00]
+ scan $a %c
+} -result 196
+
+# -------------------------------------------------------------------------
+
+test winDde-4.1 {DDE execute remotely} -constraints {dde stdio} -body {
+ set \xe1 ""
+ set name ch\xEDld-4.1
+ set child [createChildProcess $name]
+ dde execute TclEval $name [list set \xe1 foo]
+ dde execute TclEval $name {set done 1}
+ update
+ set \xe1
+} -result ""
+test winDde-4.2 {DDE execute async remotely} -constraints {dde stdio} -body {
+ set \xe1 ""
+ set name ch\xEDld-4.2
+ set child [createChildProcess $name]
+ dde execute -async TclEval $name [list set \xe1 foo]
+ update
+ dde execute TclEval $name {set done 1}
+ update
+ set \xe1
+} -result ""
+test winDde-4.3 {DDE request remotely} -constraints {dde stdio} -body {
+ set a ""
+ set name ch\xEDld-4.3
+ set child [createChildProcess $name]
+ dde execute TclEval $name [list set a foo]
+ set a [dde request TclEval $name a]
+ dde execute TclEval $name {set done 1}
+ update
+ set a
+} -result foo
+test winDde-4.4 {DDE eval remotely} -constraints {dde stdio} -body {
+ set a ""
+ set name ch\xEDld-4.4
+ set child [createChildProcess $name]
+ set a [dde eval $name set a foo]
+ dde execute TclEval $name {set done 1}
+ update
+ set a
+} -result foo
+
+# -------------------------------------------------------------------------
+
+test winDde-5.1 {check for bad arguments} -constraints dde -body {
+ dde execute "" "" "" ""
+} -returnCodes error -result {wrong # args: should be "dde execute ?-async? ?-binary? serviceName topicName value"}
+test winDde-5.2 {check for bad arguments} -constraints dde -body {
+ dde execute -binary "" "" ""
+} -returnCodes error -result {cannot execute null data}
+test winDde-5.3 {check for bad arguments} -constraints dde -body {
+ dde execute -foo "" "" ""
+} -returnCodes error -result {wrong # args: should be "dde execute ?-async? ?-binary? serviceName topicName value"}
+test winDde-5.4 {DDE eval bad arguments} -constraints dde -body {
+ dde eval "" "foo"
+} -returnCodes error -result {invalid service name ""}
+
+# -------------------------------------------------------------------------
+
+test winDde-6.1 {DDE servername bad arguments} -constraints dde -body {
+ dde servername -z -z -z
+} -returnCodes error -result {bad option "-z": must be -force, -handler, or --}
+test winDde-6.2 {DDE servername set name} -constraints dde -body {
+ dde servername -- winDde-6.2
+} -result {winDde-6.2}
+test winDde-6.3 {DDE servername set exact name} -constraints dde -body {
+ dde servername -force winDde-6.3
+} -result {winDde-6.3}
+test winDde-6.4 {DDE servername set exact name} -constraints dde -body {
+ dde servername -force -- winDde-6.4
+} -result {winDde-6.4}
+test winDde-6.5 {DDE remote servername collision} -constraints {dde stdio} -setup {
+ set name ch\xEDld-6.5
+ set child [createChildProcess $name]
+} -body {
+ dde servername -- $name
+} -cleanup {
+ dde execute TclEval $name {set done 1}
+ update
+} -result "ch\xEDld-6.5 #2"
+test winDde-6.6 {DDE remote servername collision force} -constraints {dde stdio} -setup {
+ set name ch\xEDld-6.6
+ set child [createChildProcess $name]
+} -body {
+ dde servername -force -- $name
+} -cleanup {
+ dde execute TclEval $name {set done 1}
+ update
+} -result "ch\xEDld-6.6"
+
+# -------------------------------------------------------------------------
+
+test winDde-7.1 {Load DDE in slave interpreter} -constraints dde -setup {
+ interp create slave
+} -body {
+ slave eval [list load $::ddelib Dde]
+ slave eval [list dde servername -- dde-interp-7.1]
+} -cleanup {
+ interp delete slave
+} -result {dde-interp-7.1}
+test winDde-7.2 {DDE slave cleanup} -constraints dde -setup {
+ interp create slave
+ slave eval [list load $::ddelib Dde]
+ slave eval [list dde servername -- dde-interp-7.5]
+ interp delete slave
+} -body {
+ dde services TclEval {}
+ set s [dde services TclEval {}]
+ set m [list [list TclEval dde-interp-7.5]]
+ if {$m in $s} {
+ set s
+ }
+} -result {}
+test winDde-7.3 {DDE present in slave interp} -constraints dde -setup {
+ interp create slave
+ slave eval [list load $::ddelib Dde]
+ slave eval [list dde servername -- dde-interp-7.3]
+} -body {
+ dde services TclEval dde-interp-7.3
+} -cleanup {
+ interp delete slave
+} -result {{TclEval dde-interp-7.3}}
+test winDde-7.4 {interp name collision with -force} -constraints dde -setup {
+ interp create slave
+ slave eval [list load $::ddelib Dde]
+ slave eval [list dde servername -- dde-interp-7.4]
+} -body {
+ dde servername -force -- dde-interp-7.4
+} -cleanup {
+ interp delete slave
+} -result {dde-interp-7.4}
+test winDde-7.5 {interp name collision without -force} -constraints dde -setup {
+ interp create slave
+ slave eval [list load $::ddelib Dde]
+ slave eval [list dde servername -- dde-interp-7.5]
+} -body {
+ dde servername -- dde-interp-7.5
+} -cleanup {
+ interp delete slave
+} -result "dde-interp-7.5 #2"
+
+# -------------------------------------------------------------------------
+
+test winDde-8.1 {Safe DDE load} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+} -body {
+ slave eval dde servername slave
+} -cleanup {
+ interp delete slave
+} -returnCodes error -result {invalid command name "dde"}
+test winDde-8.2 {Safe DDE set servername} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+} -body {
+ slave invokehidden dde servername slave
+} -cleanup {interp delete slave} -result {slave}
+test winDde-8.3 {Safe DDE check handler required for eval} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave invokehidden dde servername slave
+} -body {
+ catch {dde eval slave set a 1} msg
+} -cleanup {interp delete slave} -result {1}
+test winDde-8.4 {Safe DDE check that execute is denied} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave invokehidden dde servername slave
+} -body {
+ slave eval set a 1
+ dde execute TclEval slave {set a 2}
+ slave eval set a
+} -cleanup {interp delete slave} -result 1
+test winDde-8.5 {Safe DDE check that request is denied} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave invokehidden dde servername slave
+} -body {
+ slave eval set a 1
+ dde request TclEval slave a
+} -cleanup {
+ interp delete slave
+} -returnCodes error -result {remote server cannot handle this command}
+test winDde-8.6 {Safe DDE assign handler procedure} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave eval {proc DDEACCEPT {cmd} {set ::DDECMD $cmd}}
+} -body {
+ slave invokehidden dde servername -handler DDEACCEPT slave
+} -cleanup {interp delete slave} -result slave
+test winDde-8.7 {Safe DDE check simple command} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave eval {proc DDEACCEPT {cmd} {set ::DDECMD $cmd}}
+ slave invokehidden dde servername -handler DDEACCEPT slave
+} -body {
+ dde eval slave set x 1
+} -cleanup {interp delete slave} -result {set x 1}
+test winDde-8.8 {Safe DDE check non-list command} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave eval {proc DDEACCEPT {cmd} {set ::DDECMD $cmd}}
+ slave invokehidden dde servername -handler DDEACCEPT slave
+} -body {
+ set s "c:\\Program Files\\Microsoft Visual Studio\\"
+ dde eval slave $s
+ string equal [slave eval set DDECMD] $s
+} -cleanup {interp delete slave} -result 1
+test winDde-8.9 {Safe DDE check command evaluation} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave eval {proc DDEACCEPT {cmd} {set ::DDECMD [uplevel \#0 $cmd]}}
+ slave invokehidden dde servername -handler DDEACCEPT slave
+} -body {
+ dde eval slave set \xe1 1
+ slave eval set \xe1
+} -cleanup {interp delete slave} -result 1
+test winDde-8.10 {Safe DDE check command evaluation (2)} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave eval {proc DDEACCEPT {cmd} {set ::DDECMD [uplevel \#0 $cmd]}}
+ slave invokehidden dde servername -handler DDEACCEPT slave
+} -body {
+ dde eval slave [list set x 1]
+ slave eval set x
+} -cleanup {interp delete slave} -result 1
+test winDde-8.11 {Safe DDE check command evaluation (3)} -constraints dde -setup {
+ interp create -safe slave
+ slave invokehidden load $::ddelib Dde
+ slave eval {proc DDEACCEPT {cmd} {set ::DDECMD [uplevel \#0 $cmd]}}
+ slave invokehidden dde servername -handler DDEACCEPT slave
+} -body {
+ dde eval slave [list [list set x 1]]
+ slave eval set x
+} -cleanup {interp delete slave} -returnCodes error -result {invalid command name "set x 1"}
+
+# -------------------------------------------------------------------------
+
+test winDde-9.1 {External safe DDE check string passing} -constraints {dde stdio} -setup {
+ set name ch\xEDld-9.1
+ set child [createChildProcess $name -handler Handler1]
+ file copy -force script1.tcl dde-script.tcl
+} -body {
+ dde eval $name set x 1
+ gets $child line
+ set line
+} -cleanup {
+ dde execute TclEval $name stop
+ update
+ file delete -force -- dde-script.tcl
+} -result {set x 1}
+test winDde-9.2 {External safe DDE check command evaluation} -constraints {dde stdio} -setup {
+ set name ch\xEDld-9.2
+ set child [createChildProcess $name -handler Handler2]
+ file copy -force script1.tcl dde-script.tcl
+} -body {
+ dde eval $name set x 1
+ gets $child line
+ set line
+} -cleanup {
+ dde execute TclEval $name stop
+ update
+ file delete -force -- dde-script.tcl
+} -result 1
+test winDde-9.3 {External safe DDE check prefixed arguments} -constraints {dde stdio} -setup {
+ set name ch\xEDld-9.3
+ set child [createChildProcess $name -handler [list Handler3 ARG]]
+ file copy -force script1.tcl dde-script.tcl
+} -body {
+ dde eval $name set x 1
+ gets $child line
+ set line
+} -cleanup {
+ dde execute TclEval $name stop
+ update
+ file delete -force -- dde-script.tcl
+} -result {ARG {set x 1}}
+test winDde-9.4 {External safe DDE check null data passing} -constraints {dde stdio} -setup {
+ set name ch\xEDld-9.4
+ set child [createChildProcess $name -handler Handler1]
+ file copy -force script1.tcl dde-script.tcl
+} -body {
+ dde execute TclEval $name ""
+ gets $child line
+ set line
+} -cleanup {
+ dde execute TclEval $name stop
+ update
+ file delete -force -- dde-script.tcl
+} -result {null data}
+
+# -------------------------------------------------------------------------
+
+#cleanup
+#catch {interp delete $slave}; # ensure we clean up the slave.
+file delete -force $::scriptName
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/winFCmd.test b/pkgs/msgcat/tests/winFCmd.test
new file mode 100644
index 0000000..b49356d
--- /dev/null
+++ b/pkgs/msgcat/tests/winFCmd.test
@@ -0,0 +1,1549 @@
+# This file tests the tclWinFCmd.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1996-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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# Initialise the test constraints
+
+testConstraint winVista 0
+testConstraint win2000orXP 0
+testConstraint winOlderThan2000 0
+testConstraint testvolumetype [llength [info commands testvolumetype]]
+testConstraint testfile [llength [info commands testfile]]
+testConstraint testchmod [llength [info commands testchmod]]
+testConstraint cdrom 0
+testConstraint exdev 0
+testConstraint longFileNames 0
+
+proc createfile {file {string a}} {
+ set f [open $file w]
+ puts -nonewline $f $string
+ close $f
+ return $string
+}
+
+proc contents {file} {
+ set f [open $file r]
+ set r [read $f]
+ close $f
+ set r
+}
+
+proc cleanup {args} {
+ foreach p ". $args" {
+ set x ""
+ catch {
+ set x [glob -directory $p tf* td*]
+ }
+ if {$x != ""} {
+ catch {file delete -force -- {*}$x}
+ }
+ }
+}
+
+if {[testConstraint winOnly]} {
+ set major [string index $tcl_platform(osVersion) 0]
+ if {[testConstraint nt] && $major > 4} {
+ if {$major > 5} {
+ testConstraint winVista 1
+ } elseif {$major == 5} {
+ testConstraint win2000orXP 1
+ }
+ } else {
+ testConstraint winOlderThan2000 1
+ }
+}
+
+# find a CD-ROM so we can test read-only filesystems.
+
+proc findfile {dir} {
+ foreach p [glob -nocomplain -type f -directory $dir *] {
+ return $p
+ }
+ foreach p [glob -nocomplain -type d -directory $dir *] {
+ set f [findfile $p]
+ if {$f ne ""} {
+ return $f
+ }
+ }
+ return ""
+}
+
+if {[testConstraint testvolumetype]} {
+ foreach p {d e f g h i j k l m n o p q r s t u v w x y z} {
+ if {![catch {testvolumetype ${p}:} result] && $result in {CDFS UDF}} {
+ set cdrom ${p}:
+ set cdfile [findfile $cdrom]
+ testConstraint cdrom 1
+ break
+ }
+ }
+}
+
+# NB: filename is chosen to be short but unlikely to clash with other apps
+if {[file exists c:/] && [file exists d:/]} {
+ catch {file delete d:/TclTmpF.1}
+ if {[catch {createfile d:/TclTmpF.1 {}}] == 0} {
+ file delete d:/TclTmpF.1
+ testConstraint exdev 1
+ }
+}
+
+file delete -force -- td1
+if {![catch {open td1 w} testfile]} {
+ close $testfile
+ testConstraint longFileNames 1
+ file delete -force -- td1
+}
+
+# A really long file name
+# length of longname is 1216 chars, which should be greater than any static
+# buffer or allowable filename.
+
+set longname "abcdefghihjllmnopqrstuvwxyz01234567890"
+append longname $longname
+append longname $longname
+append longname $longname
+append longname $longname
+append longname $longname
+
+# Uses the "testfile" command instead of the "file" command. The "file"
+# command provides several layers of sanity checks on the arguments and
+# it can be difficult to actually forward "insane" arguments to the
+# low-level posix emulation layer.
+
+test winFCmd-1.1 {TclpRenameFile: errno: EACCES} -body {
+ testfile mv $cdfile $cdrom/dummy~~.fil
+} -constraints {win cdrom testfile} -returnCodes error -result EACCES
+test winFCmd-1.2 {TclpRenameFile: errno: EEXIST} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1/td2/td3
+ file mkdir td2
+ testfile mv td2 td1/td2
+} -returnCodes error -result EEXIST
+test winFCmd-1.3 {TclpRenameFile: errno: EINVAL} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mv / td1
+} -returnCodes error -result EINVAL
+test winFCmd-1.4 {TclpRenameFile: errno: EINVAL} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile mv td1 td1/td2
+} -returnCodes error -result EINVAL
+test winFCmd-1.5 {TclpRenameFile: errno: EISDIR} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile tf1
+ testfile mv tf1 td1
+} -returnCodes error -result EISDIR
+test winFCmd-1.6 {TclpRenameFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mv tf1 tf2
+} -returnCodes error -result ENOENT
+test winFCmd-1.7 {TclpRenameFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mv "" tf2
+} -returnCodes error -result ENOENT
+test winFCmd-1.8 {TclpRenameFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ testfile mv tf1 ""
+} -returnCodes error -result ENOENT
+test winFCmd-1.9 {TclpRenameFile: errno: ENOTDIR} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile tf1
+ testfile mv td1 tf1
+} -returnCodes error -result ENOTDIR
+test winFCmd-1.10 {TclpRenameFile: errno: EXDEV} -setup {
+ file delete -force d:/tf1
+} -constraints {win exdev testfile} -body {
+ file mkdir c:/tf1
+ testfile mv c:/tf1 d:/tf1
+} -cleanup {
+ file delete -force c:/tf1
+} -returnCodes error -result EXDEV
+test winFCmd-1.11 {TclpRenameFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ set fd [open tf1 w]
+ testfile mv tf1 tf2
+} -cleanup {
+ catch {close $fd}
+} -returnCodes error -result EACCES
+test winFCmd-1.12 {TclpRenameFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ set fd [open tf2 w]
+ testfile mv tf1 tf2
+} -cleanup {
+ catch {close $fd}
+} -returnCodes error -result EACCES
+test winFCmd-1.13 {TclpRenameFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win win2000orXP testfile} -body {
+ testfile mv nul tf1
+} -returnCodes error -result EINVAL
+test winFCmd-1.13.1 {TclpRenameFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win nt winOlderThan2000 testfile} -body {
+ testfile mv nul tf1
+} -returnCodes error -result EACCES
+test winFCmd-1.13.2 {TclpRenameFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ testfile mv nul tf1
+} -returnCodes error -result ENOENT
+test winFCmd-1.14 {TclpRenameFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ createfile tf1
+ testfile mv tf1 nul
+} -returnCodes error -result EACCES
+test winFCmd-1.15 {TclpRenameFile: errno: EEXIST} -setup {
+ cleanup
+} -constraints {win nt testfile} -body {
+ createfile tf1
+ testfile mv tf1 nul
+} -returnCodes error -result EEXIST
+test winFCmd-1.16 {TclpRenameFile: MoveFile() != FALSE} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1 tf1
+ testfile mv tf1 tf2
+ list [file exists tf1] [contents tf2]
+} -result {0 tf1}
+test winFCmd-1.17 {TclpRenameFile: MoveFile() == FALSE} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mv tf1 tf2
+} -returnCodes error -result ENOENT
+test winFCmd-1.18 {TclpRenameFile: srcAttr == -1} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mv tf1 tf2
+} -returnCodes error -result ENOENT
+test winFCmd-1.19 {TclpRenameFile: errno == EACCES} -setup {
+ cleanup
+} -constraints {win win2000orXP testfile} -body {
+ testfile mv nul tf1
+} -returnCodes error -result EINVAL
+test winFCmd-1.19.1 {TclpRenameFile: errno == EACCES} -setup {
+ cleanup
+} -constraints {win nt winOlderThan2000 testfile} -body {
+ testfile mv nul tf1
+} -returnCodes error -result EACCES
+test winFCmd-1.19.2 {TclpRenameFile: errno == ENOENT} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ testfile mv nul tf1
+} -returnCodes error -result ENOENT
+test winFCmd-1.20 {TclpRenameFile: src is dir} -setup {
+ cleanup
+} -constraints {win nt testfile} -body {
+ # under 95, this would actually succeed and move the current dir out from
+ # under the current process!
+ file delete /tf1
+ testfile mv [pwd] /tf1
+} -returnCodes error -result EACCES
+test winFCmd-1.21 {TclpRenameFile: long src} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mv $longname tf1
+} -returnCodes error -result ENAMETOOLONG
+test winFCmd-1.22 {TclpRenameFile: long dst} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ testfile mv tf1 $longname
+} -returnCodes error -result ENAMETOOLONG
+test winFCmd-1.23 {TclpRenameFile: move dir into self} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile mv [pwd]/td1 td1/td2
+} -returnCodes error -result EINVAL
+test winFCmd-1.24 {TclpRenameFile: move a root dir} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mv / c:/
+} -returnCodes error -result EINVAL
+test winFCmd-1.25 {TclpRenameFile: cross file systems} -setup {
+ cleanup
+} -constraints {win cdrom testfile} -body {
+ file mkdir td1
+ testfile mv td1 $cdrom/td1
+} -returnCodes error -result EXDEV
+test winFCmd-1.26 {TclpRenameFile: readonly fs} -setup {
+ cleanup
+} -constraints {win cdrom testfile} -body {
+ testfile mv $cdfile $cdrom/dummy~~.fil
+} -returnCodes error -result EACCES
+test winFCmd-1.27 {TclpRenameFile: open file} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ set fd [open tf1 w]
+ testfile mv tf1 tf2
+} -cleanup {
+ catch {close $fd}
+} -returnCodes error -result EACCES
+test winFCmd-1.28 {TclpRenameFile: errno == EEXIST} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ createfile tf2
+ testfile mv tf1 tf2
+ list [file exists tf1] [file exists tf2]
+} -result {0 1}
+test winFCmd-1.29 {TclpRenameFile: src is dir} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile tf1
+ testfile mv td1 tf1
+} -returnCodes error -result ENOTDIR
+test winFCmd-1.30 {TclpRenameFile: dst is dir} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ file mkdir td2/td2
+ testfile mv td1 td2
+} -returnCodes error -result EEXIST
+test winFCmd-1.31 {TclpRenameFile: TclpRemoveDirectory fails} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ file mkdir td2/td2
+ testfile mv td1 td2
+} -returnCodes error -result EEXIST
+test winFCmd-1.32 {TclpRenameFile: TclpRemoveDirectory succeeds} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1/td2
+ file mkdir td2
+ testfile mv td1 td2
+ list [file exists td1] [file exists td2] [file exists td2/td2]
+} -result {0 1 1}
+test winFCmd-1.33 {TclpRenameFile: After removing dst dir, MoveFile fails} \
+ -constraints {win exdev testfile testchmod} -body {
+ file mkdir d:/td1
+ testchmod 000 d:/td1
+ file mkdir c:/tf1
+ catch {testfile mv c:/tf1 d:/td1} msg
+ list $msg [file writable d:/td1]
+} -cleanup {
+ catch {testchmod 666 d:/td1}
+ file delete d:/td1
+ file delete -force c:/tf1
+} -result {EXDEV 0}
+test winFCmd-1.34 {TclpRenameFile: src is dir, dst is not} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile tf1
+ testfile mv td1 tf1
+} -cleanup {
+ cleanup
+} -returnCodes error -result ENOTDIR
+test winFCmd-1.35 {TclpRenameFile: src is not dir, dst is} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile tf1
+ testfile mv tf1 td1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-1.36 {TclpRenameFile: src and dst not dir} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1 tf1
+ createfile tf2 tf2
+ testfile mv tf1 tf2
+ contents tf2
+} -cleanup {
+ cleanup
+} -result {tf1}
+test winFCmd-1.37 {TclpRenameFile: need to restore temp file} {win emptyTest} {
+ # Can't figure out how to cause this.
+ # Need a file that can't be copied.
+} {}
+
+# If the native filesystem produces 0 for inodes numbers there is no point
+# doing the following test.
+testConstraint winNonZeroInodes [eval {
+ file stat [info nameofexecutable] statExe
+ expr {$statExe(ino) != 0}
+}]
+
+proc MakeFiles {dirname} {
+ set inodes {}
+ set ndx -1
+ while {1} {
+ # upped to 50K for 64bit Server 2008
+ if {$ndx > 50000} {
+ return -code error "limit reached without finding a collistion."
+ }
+ set filename [file join $dirname Test[incr ndx]]
+ set f [open $filename w]
+ close $f
+ file stat $filename stat
+ if {[set n [lsearch -exact -integer $inodes $stat(ino)]] != -1} {
+ return [list [file join $dirname Test$n] $filename]
+ }
+ lappend inodes $stat(ino)
+ unset stat
+ }
+}
+
+test winFCmd-1.38 {TclpRenameFile: check rename of conflicting inodes} -setup {
+ cleanup
+} -constraints {win winNonZeroInodes} -body {
+ file mkdir td1
+ foreach {a b} [MakeFiles td1] break
+ file rename -force $a $b
+ file exists $a
+} -cleanup {
+ cleanup
+} -result {0}
+
+
+test winFCmd-2.1 {TclpCopyFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win cdrom testfile} -body {
+ testfile cp $cdfile $cdrom/dummy~~.fil
+} -returnCodes error -result EACCES
+test winFCmd-2.2 {TclpCopyFile: errno: EISDIR} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile cp td1 tf1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.3 {TclpCopyFile: errno: EISDIR} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ file mkdir td1
+ testfile cp tf1 td1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.4 {TclpCopyFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile cp tf1 tf2
+} -returnCodes error -result ENOENT
+test winFCmd-2.5 {TclpCopyFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile cp "" tf2
+} -returnCodes error -result ENOENT
+test winFCmd-2.6 {TclpCopyFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ testfile cp tf1 ""
+} -cleanup {
+ cleanup
+} -returnCodes error -result ENOENT
+test winFCmd-2.7 {TclpCopyFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ createfile tf1
+ set fd [open tf2 w]
+ testfile cp tf1 tf2
+} -cleanup {
+ close $fd
+ cleanup
+} -returnCodes error -result EACCES
+test winFCmd-2.8 {TclpCopyFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win win2000orXP testfile} -body {
+ testfile cp nul tf1
+} -returnCodes error -result EINVAL
+test winFCmd-2.8.1 {TclpCopyFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win nt winOlderThan2000 testfile} -body {
+ testfile cp nul tf1
+} -returnCodes error -result EACCES
+test winFCmd-2.9 {TclpCopyFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ testfile cp nul tf1
+} -returnCodes error -result ENOENT
+test winFCmd-2.10 {TclpCopyFile: CopyFile succeeds} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1 tf1
+ testfile cp tf1 tf2
+ list [contents tf1] [contents tf2]
+} -cleanup {
+ cleanup
+} -result {tf1 tf1}
+test winFCmd-2.11 {TclpCopyFile: CopyFile succeeds} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1 tf1
+ createfile tf2 tf2
+ testfile cp tf1 tf2
+ list [contents tf1] [contents tf2]
+} -cleanup {
+ cleanup
+} -result {tf1 tf1}
+test winFCmd-2.12 {TclpCopyFile: CopyFile succeeds} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1 tf1
+ testchmod 000 tf1
+ testfile cp tf1 tf2
+ list [contents tf2] [file writable tf2]
+} -cleanup {
+ catch {testchmod 666 tf1}
+ cleanup
+} -result {tf1 0}
+test winFCmd-2.13 {TclpCopyFile: CopyFile fails} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ file mkdir td1
+ testfile cp tf1 td1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.14 {TclpCopyFile: errno == EACCES} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile cp td1 tf1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.15 {TclpCopyFile: src is directory} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile cp td1 tf1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.16 {TclpCopyFile: dst is directory} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ file mkdir td1
+ testfile cp tf1 td1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.17 {TclpCopyFile: dst is readonly} -setup {
+ cleanup
+} -constraints {win testfile testchmod} -body {
+ createfile tf1 tf1
+ createfile tf2 tf2
+ testchmod 000 tf2
+ testfile cp tf1 tf2
+ list [file writable tf2] [contents tf2]
+} -cleanup {
+ catch {testchmod 666 tf2}
+ cleanup
+} -result {1 tf1}
+test winFCmd-2.18 {TclpCopyFile: still can't copy onto dst} -setup {
+ cleanup
+} -constraints {win 95 testfile testchmod} -body {
+ createfile tf1
+ createfile tf2
+ testchmod 000 tf2
+ set fd [open tf2]
+ set msg [list [catch {testfile cp tf1 tf2} msg] $msg]
+ close $fd
+ lappend msg [file writable tf2]
+} -result {1 EACCES 0}
+
+test winFCmd-3.1 {TclpDeleteFile: errno: EACCES} -body {
+ testfile rm $cdfile $cdrom/dummy~~.fil
+} -constraints {win cdrom testfile} -returnCodes error -result EACCES
+test winFCmd-3.2 {TclpDeleteFile: errno: EISDIR} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile rm td1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-3.3 {TclpDeleteFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile rm tf1
+} -returnCodes error -result ENOENT
+test winFCmd-3.4 {TclpDeleteFile: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile rm ""
+} -returnCodes error -result ENOENT
+test winFCmd-3.5 {TclpDeleteFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ set fd [open tf1 w]
+ testfile rm tf1
+} -cleanup {
+ close $fd
+ cleanup
+} -returnCodes error -result EACCES
+test winFCmd-3.6 {TclpDeleteFile: errno: EACCES} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile rm nul
+} -returnCodes error -result EACCES
+test winFCmd-3.7 {TclpDeleteFile: DeleteFile succeeds} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ testfile rm tf1
+ file exists tf1
+} -result {0}
+test winFCmd-3.8 {TclpDeleteFile: DeleteFile fails} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile rm td1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-3.9 {TclpDeleteFile: errno == EACCES} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ set fd [open tf1 w]
+ testfile rm tf1
+} -cleanup {
+ close $fd
+} -returnCodes error -result EACCES
+test winFCmd-3.10 {TclpDeleteFile: path is readonly} -setup {
+ cleanup
+} -constraints {win testfile testchmod} -body {
+ createfile tf1
+ testchmod 000 tf1
+ testfile rm tf1
+ file exists tf1
+} -result {0}
+test winFCmd-3.11 {TclpDeleteFile: still can't remove path} -setup {
+ cleanup
+} -constraints {win testfile testchmod} -body {
+ set fd [open tf1 w]
+ testchmod 000 tf1
+ testfile rm tf1
+} -cleanup {
+ close $fd
+ catch {testchmod 666 tf1}
+ cleanup
+} -returnCodes error -result EACCES
+
+test winFCmd-4.1 {TclpCreateDirectory: errno: EACCES} -body {
+ testfile mkdir $cdrom/dummy~~.dir
+} -constraints {win nt cdrom testfile} -returnCodes error -result EACCES
+test winFCmd-4.2 {TclpCreateDirectory: errno: EACCES} -body {
+ testfile mkdir $cdrom/dummy~~.dir
+} -constraints {win 95 cdrom testfile} -returnCodes error -result ENOSPC
+test winFCmd-4.3 {TclpCreateDirectory: errno: EEXIST} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile mkdir td1
+} -cleanup {
+ cleanup
+} -returnCodes error -result EEXIST
+test winFCmd-4.4 {TclpCreateDirectory: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mkdir td1/td2
+} -returnCodes error -result ENOENT
+test winFCmd-4.5 {TclpCreateDirectory: CreateDirectory succeeds} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile mkdir td1
+ file type td1
+} -cleanup cleanup -result directory
+
+test winFCmd-5.1 {TclpCopyDirectory: calls TraverseWinTree} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile cpdir td1 td2
+ list [file type td1] [file type td2]
+} -cleanup {
+ cleanup
+} -result {directory directory}
+
+test winFCmd-6.1 {TclpRemoveDirectory: errno: EACCES} -setup {
+ cleanup
+} -constraints {winVista testfile testchmod} -body {
+ file mkdir td1
+ testchmod 000 td1
+ testfile rmdir td1
+ file exists td1
+} -returnCodes error -cleanup {
+ catch {testchmod 666 td1}
+ cleanup
+} -result {td1 EACCES}
+# This next test has a very hokey way of matching...
+test winFCmd-6.2 {TclpRemoveDirectory: errno: EEXIST} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1/td2
+ list [catch {testfile rmdir td1} msg] [file tail $msg]
+} -result {1 {td1 EEXIST}}
+test winFCmd-6.3 {TclpRemoveDirectory: errno: EACCES} {win emptyTest} {
+ # can't test this w/o removing everything on your hard disk first!
+ # testfile rmdir /
+} {}
+# This next test has a very hokey way of matching...
+test winFCmd-6.4 {TclpRemoveDirectory: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ list [catch {testfile rmdir td1} msg] [file tail $msg]
+} -result {1 {td1 ENOENT}}
+test winFCmd-6.5 {TclpRemoveDirectory: errno: ENOENT} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile rmdir ""
+} -returnCodes error -result ENOENT
+# This next test has a very hokey way of matching...
+test winFCmd-6.6 {TclpRemoveDirectory: errno: ENOTDIR} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ list [catch {testfile rmdir tf1} msg] [file tail $msg]
+} -result {1 {tf1 ENOTDIR}}
+test winFCmd-6.7 {TclpRemoveDirectory: RemoveDirectory succeeds} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile rmdir td1
+ file exists td1
+} -result {0}
+# This next test has a very hokey way of matching...
+test winFCmd-6.8 {TclpRemoveDirectory: RemoveDirectory fails} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ list [catch {testfile rmdir tf1} msg] [file tail $msg]
+} -result {1 {tf1 ENOTDIR}}
+test winFCmd-6.9 {TclpRemoveDirectory: errno == EACCES} -setup {
+ cleanup
+} -constraints {winVista testfile testchmod} -body {
+ file mkdir td1
+ testchmod 000 td1
+ testfile rmdir td1
+ file exists td1
+} -returnCodes error -cleanup {
+ catch {testchmod 666 td1}
+ cleanup
+} -result {td1 EACCES}
+test winFCmd-6.10 {TclpRemoveDirectory: attr == -1} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ testfile rmdir nul
+} -returnCodes error -result {nul EACCES}
+test winFCmd-6.11 {TclpRemoveDirectory: attr == -1} -setup {
+ cleanup
+} -constraints {win nt testfile} -body {
+ testfile rmdir /
+ # WinXP returns EEXIST, WinNT seems to return EACCES. No policy
+ # decision has been made as to which is correct.
+} -returnCodes error -match regexp -result {^/ E(ACCES|EXIST)$}
+# This next test has a very hokey way of matching...
+test winFCmd-6.12 {TclpRemoveDirectory: errno == EACCES} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ createfile tf1
+ set res [catch {testfile rmdir tf1} msg]
+ # get rid of path
+ set msg [list [file tail [lindex $msg 0]] [lindex $msg 1]]
+ list $res $msg
+} -result {1 {tf1 ENOTDIR}}
+test winFCmd-6.13 {TclpRemoveDirectory: write-protected} -setup {
+ cleanup
+} -constraints {winVista testfile testchmod} -body {
+ file mkdir td1
+ testchmod 000 td1
+ testfile rmdir td1
+ file exists td1
+} -cleanup {
+ catch {testchmod 666 td1}
+ cleanup
+} -returnCodes error -result {td1 EACCES}
+# This next test has a very hokey way of matching...
+test winFCmd-6.14 {TclpRemoveDirectory: check if empty dir} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ file mkdir td1/td2
+ set res [catch {testfile rmdir td1} msg]
+ # get rid of path
+ set msg [list [file tail [lindex $msg 0]] [lindex $msg 1]]
+ list $res $msg
+} -result {1 {td1 EEXIST}}
+# This next test has a very hokey way of matching...
+test winFCmd-6.15 {TclpRemoveDirectory: !recursive} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1/td2
+ list [catch {testfile rmdir td1} msg] [file tail $msg]
+} -result {1 {td1 EEXIST}}
+test winFCmd-6.16 {TclpRemoveDirectory: recursive, but errno != EEXIST} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ createfile tf1
+ testfile rmdir -force tf1
+} -returnCodes error -result {tf1 ENOTDIR}
+test winFCmd-6.17 {TclpRemoveDirectory: calls TraverseWinTree} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1/td2
+ testfile rmdir -force td1
+ file exists td1
+} -result {0}
+
+test winFCmd-7.1 {TraverseWinTree: targetPtr == NULL} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1/td2/td3
+ testfile rmdir -force td1
+ file exists td1
+} -result {0}
+test winFCmd-7.2 {TraverseWinTree: targetPtr != NULL} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1/td2/td3
+ testfile cpdir td1 td2
+ list [file exists td1] [file exists td2]
+} -cleanup {
+ cleanup
+} -result {1 1}
+test winFCmd-7.3 {TraverseWinTree: sourceAttr == -1} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile cpdir td1 td2
+} -returnCodes error -result {td1 ENOENT}
+test winFCmd-7.4 {TraverseWinTree: source isn't directory} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testfile cpdir td1 td2
+ contents td2/tf1
+} -cleanup {
+ cleanup
+} -result {tf1}
+test winFCmd-7.5 {TraverseWinTree: call TraversalCopy: DOTREE_F} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testfile cpdir td1 td2
+ contents td2/tf1
+} -cleanup {
+ cleanup
+} -result {tf1}
+test winFCmd-7.6 {TraverseWinTree: call TraversalDelete: DOTREE_F} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testfile rmdir -force td1
+ file exists td1
+} -result {0}
+test winFCmd-7.7 {TraverseWinTree: append \ to source if necessary} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testfile cpdir td1 td2
+ contents td2/tf1
+} -cleanup {
+ cleanup
+} -result {tf1}
+test winFCmd-7.8 {TraverseWinTree: append \ to source if necessary} -body {
+ # cdrom can return either d:\ or D:/, but we only care about the errcode
+ testfile rmdir $cdrom/
+} -constraints {win 95 cdrom testfile} -returnCodes error -match glob \
+ -result {* EACCES} ; # was EEXIST, but changed for win98.
+test winFCmd-7.9 {TraverseWinTree: append \ to source if necessary} -body {
+ testfile rmdir $cdrom/
+} -constraints {win nt cdrom testfile} -returnCodes error -match glob \
+ -result {* EACCES}
+test winFCmd-7.10 {TraverseWinTree: can't read directory: handle == INVALID} \
+ {win emptyTest} {
+ # can't make it happen
+} {}
+test winFCmd-7.11 {TraverseWinTree: call TraversalCopy: DOTREE_PRED} -setup {
+ cleanup
+} -constraints {win testfile testchmod} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testchmod 000 td1
+ testfile cpdir td1 td2
+ list [file exists td2] [file writable td2]
+} -cleanup {
+ catch {testchmod 666 td1}
+ cleanup
+} -result {1 1}
+test winFCmd-7.12 {TraverseWinTree: call TraversalDelete: DOTREE_PRED} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testfile rmdir -force td1
+ file exists td1
+} -result {0}
+test winFCmd-7.13 {TraverseWinTree: append \ to target if necessary} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testfile cpdir td1 td2
+ contents td2/tf1
+} -cleanup {
+ cleanup
+} -result {tf1}
+test winFCmd-7.14 {TraverseWinTree: append \ to target if necessary} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ file mkdir td1
+ testfile cpdir td1 /
+} -cleanup {
+ cleanup
+} -returnCodes error -result {/ EEXIST}
+test winFCmd-7.15 {TraverseWinTree: append \ to target if necessary} -setup {
+ cleanup
+} -constraints {win nt testfile} -body {
+ file mkdir td1
+ testfile cpdir td1 /
+} -cleanup {
+ cleanup
+ # Windows7 returns EEXIST, XP returns EACCES
+} -returnCodes error -match regexp -result {^/ E(ACCES|EXIST)$}
+test winFCmd-7.16 {TraverseWinTree: recurse on files: no files} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile cpdir td1 td2
+} -cleanup {
+ cleanup
+} -result {}
+test winFCmd-7.17 {TraverseWinTree: recurse on files: one file} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/td2
+ testfile cpdir td1 td2
+ glob td2/*
+} -cleanup {
+ cleanup
+} -result {td2/td2}
+test winFCmd-7.18 {TraverseWinTree: recurse on files: several files and dir} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1
+ createfile td1/tf2
+ file mkdir td1/td2/td3
+ createfile td1/tf3
+ createfile td1/tf4
+ testfile cpdir td1 td2
+ lsort [glob td2/*]
+} -cleanup {
+ cleanup
+} -result {td2/td2 td2/tf1 td2/tf2 td2/tf3 td2/tf4}
+test winFCmd-7.19 {TraverseWinTree: call TraversalCopy: DOTREE_POSTD} -setup {
+ cleanup
+} -constraints {win testfile testchmod} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testchmod 000 td1
+ testfile cpdir td1 td2
+ list [file exists td2] [file writable td2]
+} -cleanup {
+ catch {testchmod 666 td1}
+ cleanup
+} -result {1 1}
+test winFCmd-7.20 {TraverseWinTree: call TraversalDelete: DOTREE_POSTD} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1 tf1
+ testfile rmdir -force td1
+ file exists td1
+} -result {0}
+test winFCmd-7.21 {TraverseWinTree: fill errorPtr} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ testfile cpdir td1 td2
+} -returnCodes error -result {td1 ENOENT}
+
+test winFCmd-8.1 {TraversalCopy: DOTREE_F} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile cpdir td1 td1
+} -returnCodes error -result {td1 EEXIST}
+test winFCmd-8.2 {TraversalCopy: DOTREE_PRED} -setup {
+ cleanup
+} -constraints {win testfile testchmod} -body {
+ file mkdir td1/td2
+ testchmod 000 td1
+ testfile cpdir td1 td2
+ list [file writable td1] [file writable td1/td2]
+} -cleanup {
+ catch {testchmod 666 td1}
+ cleanup
+} -result {0 1}
+test winFCmd-8.3 {TraversalCopy: DOTREE_POSTD} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ testfile cpdir td1 td2
+} -cleanup {
+ cleanup
+} -result {}
+
+test winFCmd-9.1 {TraversalDelete: DOTREE_F} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1
+ createfile td1/tf1
+ testfile rmdir -force td1
+} -result {}
+test winFCmd-9.2 {TraversalDelete: DOTREE_F} -setup {
+ cleanup
+} -constraints {win 95 testfile} -body {
+ file mkdir td1
+ set fd [open td1/tf1 w]
+ testfile rmdir -force td1
+} -cleanup {
+ close $fd
+} -returnCodes error -result {td1\tf1 EACCES}
+test winFCmd-9.3 {TraversalDelete: DOTREE_PRED} -setup {
+ cleanup
+} -constraints {winVista testfile testchmod} -body {
+ file mkdir td1/td2
+ testchmod 000 td1
+ testfile rmdir -force td1
+ file exists td1
+} -cleanup {
+ catch {testchmod 666 td1}
+ cleanup
+} -returnCodes error -result {td1 EACCES}
+test winFCmd-9.4 {TraversalDelete: DOTREE_POSTD} -setup {
+ cleanup
+} -constraints {win testfile} -body {
+ file mkdir td1/td1/td3/td4/td5
+ testfile rmdir -force td1
+} -result {}
+
+test winFCmd-10.1 {AttributesPosixError - get} -constraints {win} -setup {
+ cleanup
+} -body {
+ file attributes td1 -archive
+} -returnCodes error -result {could not read "td1": no such file or directory}
+test winFCmd-10.2 {AttributesPosixError - set} -constraints {win} -setup {
+ cleanup
+} -body {
+ file attributes td1 -archive 0
+} -returnCodes error -result {could not read "td1": no such file or directory}
+
+test winFCmd-11.1 {GetWinFileAttributes} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ file attributes td1 -archive
+} -cleanup {
+ cleanup
+} -result 1
+test winFCmd-11.2 {GetWinFileAttributes} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ file attributes td1 -readonly
+} -cleanup {
+ cleanup
+} -result 0
+test winFCmd-11.3 {GetWinFileAttributes} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ file attributes td1 -hidden
+} -cleanup {
+ cleanup
+} -result 0
+test winFCmd-11.4 {GetWinFileAttributes} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ file attributes td1 -system
+} -cleanup {
+ cleanup
+} -result 0
+test winFCmd-11.5 {GetWinFileAttributes} -constraints {win} -setup {
+ set old [pwd]
+} -body {
+ # Attr of relative paths that resolve to root was failing don't care about
+ # answer, just that test runs.
+ cd c:/
+ file attr c:
+ file attr c:.
+ file attr .
+} -cleanup {
+ cd $old
+} -match glob -result *
+test winFCmd-11.6 {GetWinFileAttributes} -constraints {win} -body {
+ file attr c:/ -hidden
+} -result {0}
+
+test winFCmd-12.1 {ConvertFileNameFormat} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ string tolower [file attributes td1 -longname]
+} -cleanup {
+ cleanup
+} -result {td1}
+test winFCmd-12.2 {ConvertFileNameFormat} -constraints {win} -setup {
+ cleanup
+} -body {
+ file mkdir td1
+ createfile td1/td1 {}
+ string tolower [file attributes td1/td1 -longname]
+} -cleanup {
+ cleanup
+} -result {td1/td1}
+test winFCmd-12.3 {ConvertFileNameFormat} -constraints {win} -setup {
+ cleanup
+} -body {
+ file mkdir td1
+ file mkdir td1/td2
+ createfile td1/td3 {}
+ string tolower [file attributes td1/td2/../td3 -longname]
+} -cleanup {
+ cleanup
+} -result {td1/td2/../td3}
+test winFCmd-12.4 {ConvertFileNameFormat} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ string tolower [file attributes ./td1 -longname]
+} -cleanup {
+ cleanup
+} -result {./td1}
+test winFCmd-12.5 {ConvertFileNameFormat: absolute path} -body {
+ list [file attributes / -longname] [file attributes \\ -longname]
+} -constraints {win} -result {/ /}
+test winFCmd-12.6 {ConvertFileNameFormat: absolute path with drive} -setup {
+ catch {file delete -force -- c:/td1}
+} -constraints {win win2000orXP} -body {
+ createfile c:/td1 {}
+ string tolower [file attributes c:/td1 -longname]
+} -cleanup {
+ file delete -force -- c:/td1
+} -result {c:/td1}
+test winFCmd-12.7 {ConvertFileNameFormat} -body {
+ string tolower [file attributes //bisque/tcl/ws -longname]
+} -constraints {nonPortable win} -result {//bisque/tcl/ws}
+test winFCmd-12.8 {ConvertFileNameFormat} -setup {
+ cleanup
+} -constraints {win longFileNames} -body {
+ createfile td1 {}
+ string tolower [file attributes td1 -longname]
+} -cleanup {
+ cleanup
+} -result {td1}
+test winFCmd-12.10 {ConvertFileNameFormat} -setup {
+ cleanup
+} -constraints {longFileNames win} -body {
+ createfile td1td1td1 {}
+ file attributes td1td1td1 -shortname
+} -cleanup {
+ cleanup
+} -match glob -result *
+test winFCmd-12.11 {ConvertFileNameFormat} -setup {
+ cleanup
+} -constraints {longFileNames win} -body {
+ createfile td1 {}
+ string tolower [file attributes td1 -shortname]
+} -cleanup {
+ cleanup
+} -result {td1}
+
+test winFCmd-13.1 {GetWinFileLongName} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ string tolower [file attributes td1 -longname]
+} -cleanup {
+ cleanup
+} -result td1
+
+test winFCmd-14.1 {GetWinFileShortName} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ string tolower [file attributes td1 -shortname]
+} -cleanup {
+ cleanup
+} -result td1
+
+test winFCmd-15.1 {SetWinFileAttributes} -constraints {win} -setup {
+ cleanup
+} -body {
+ file attributes td1 -archive 0
+} -returnCodes error -result {could not read "td1": no such file or directory}
+test winFCmd-15.2 {SetWinFileAttributes - archive} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ list [file attributes td1 -archive 1] [file attributes td1 -archive]
+} -cleanup {
+ cleanup
+} -result {{} 1}
+test winFCmd-15.3 {SetWinFileAttributes - archive} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ list [file attributes td1 -archive 0] [file attributes td1 -archive]
+} -cleanup {
+ cleanup
+} -result {{} 0}
+test winFCmd-15.4 {SetWinFileAttributes - hidden} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ list [file attributes td1 -hidden 1] [file attributes td1 -hidden] \
+ [file attributes td1 -hidden 0]
+} -cleanup {
+ cleanup
+} -result {{} 1 {}}
+test winFCmd-15.5 {SetWinFileAttributes - hidden} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ list [file attributes td1 -hidden 0] [file attributes td1 -hidden]
+} -cleanup {
+ cleanup
+} -result {{} 0}
+test winFCmd-15.6 {SetWinFileAttributes - readonly} -setup {
+ cleanup
+} -constraints {win} -body {
+ createfile td1 {}
+ list [file attributes td1 -readonly 1] [file attributes td1 -readonly]
+} -cleanup {
+ cleanup
+} -result {{} 1}
+test winFCmd-15.7 {SetWinFileAttributes - readonly} -setup {
+ cleanup
+} -constraints {win} -body {
+ createfile td1 {}
+ list [file attributes td1 -readonly 0] [file attributes td1 -readonly]
+} -cleanup {
+ cleanup
+} -result {{} 0}
+test winFCmd-15.8 {SetWinFileAttributes - system} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ list [file attributes td1 -system 1] [file attributes td1 -system]
+} -cleanup {
+ cleanup
+} -result {{} 1}
+test winFCmd-15.9 {SetWinFileAttributes - system} -constraints {win} -setup {
+ cleanup
+} -body {
+ createfile td1 {}
+ list [file attributes td1 -system 0] [file attributes td1 -system]
+} -cleanup {
+ cleanup
+} -result {{} 0}
+test winFCmd-15.10 {SetWinFileAttributes - failing} -setup {
+ cleanup
+} -constraints {win cdrom} -body {
+ file attributes $cdfile -archive 1
+} -returnCodes error -match glob -result *
+
+test winFCmd-16.1 {Windows file normalization} -constraints {win} -body {
+ list [file normalize c:/] [file normalize C:/]
+} -result {C:/ C:/}
+test winFCmd-16.2 {Windows file normalization} -constraints {win} -body {
+ createfile td1... {}
+ file tail [file normalize td1]
+} -cleanup {
+ file delete td1...
+} -result {td1}
+set pwd [pwd]
+set d [string index $pwd 0]
+test winFCmd-16.3 {Windows file normalization} -constraints {win} -body {
+ file norm ${d}:foo
+} -result [file join $pwd foo]
+test winFCmd-16.4 {Windows file normalization} -constraints {win} -body {
+ file norm [string tolower ${d}]:foo
+} -result [file join $pwd foo]
+test winFCmd-16.5 {Windows file normalization} -constraints {win} -body {
+ file norm ${d}:foo/bar
+} -result [file join $pwd foo/bar]
+test winFCmd-16.6 {Windows file normalization} -constraints {win} -body {
+ file norm ${d}:foo\\bar
+} -result [file join $pwd foo/bar]
+test winFCmd-16.7 {Windows file normalization} -constraints {win} -body {
+ file norm /bar
+} -result "${d}:/bar"
+test winFCmd-16.8 {Windows file normalization} -constraints {win} -body {
+ file norm ///bar
+} -result "${d}:/bar"
+test winFCmd-16.9 {Windows file normalization} -constraints {win} -body {
+ file norm /bar/foo
+} -result "${d}:/bar/foo"
+if {$d eq "C"} { set dd "D" } else { set dd "C" }
+test winFCmd-16.10 {Windows file normalization} -constraints {win} -body {
+ file norm ${dd}:foo
+} -result "${dd}:/foo"
+test winFCmd-16.11 {Windows file normalization} -body {
+ cd ${d}:
+ cd $cdrom
+ cd ${d}:
+ cd $cdrom
+ # Must not crash
+ set result "no crash"
+} -constraints {win cdrom} -cleanup {
+ cd $pwd
+} -result {no crash}
+test winFCmd-16.12 {Windows file normalization - no crash} \
+ -constraints win -setup {
+ set oldhome ""
+ catch {set oldhome $::env(HOME)}
+} -body {
+ set expectedResult [file normalize ${d}:]
+ set ::env(HOME) ${d}:
+ cd
+ # At one point this led to an infinite recursion in Tcl
+ set result [pwd]; # <- Must not crash
+ set result "no crash"
+} -cleanup {
+ set ::env(HOME) $oldhome
+ cd $pwd
+} -result {no crash}
+test winFCmd-16.13 {Windows file normalization - absolute HOME} -setup {
+ set oldhome ""
+ catch {set oldhome $::env(HOME)}
+} -constraints win -body {
+ # Test 'cd' normalization when HOME is absolute
+ set ::env(HOME) ${d}:/
+ cd
+ pwd
+} -cleanup {
+ set ::env(HOME) $oldhome
+ cd $pwd
+} -result [file normalize ${d}:/]
+test winFCmd-16.14 {Windows file normalization - relative HOME} -setup {
+ set oldhome ""
+ catch {set oldhome $::env(HOME)}
+} -constraints win -body {
+ # Test 'cd' normalization when HOME is relative
+ set ::env(HOME) ${d}:
+ cd
+ pwd
+} -cleanup {
+ set ::env(HOME) $oldhome
+ cd $pwd
+} -result $pwd
+
+test winFCmd-17.1 {Windows bad permissions cd} -constraints win -body {
+ set d {}
+ foreach dd {c:/ d:/ e:/} {
+ eval lappend d [glob -nocomplain \
+ -types hidden -dir $dd "System Volume Information"]
+ }
+ # Old versions of Tcl gave a misleading error that the
+ # directory in question didn't exist.
+ if {[llength $d] && [catch {cd [lindex $d 0]} err]} {
+ regsub ".*: " $err "" err
+ set err
+ } else {
+ set err "permission denied"
+ }
+} -cleanup {
+ cd $pwd
+} -result "permission denied"
+
+cd $pwd
+unset d dd pwd
+
+test winFCmd-18.1 {Windows reserved path names} -constraints win -body {
+ file pathtype com1
+} -result "absolute"
+test winFCmd-18.1.2 {Windows reserved path names} -constraints win -body {
+ file pathtype com4
+} -result "absolute"
+test winFCmd-18.1.3 {Windows reserved path names} -constraints win -body {
+ file pathtype com5
+} -result "relative"
+test winFCmd-18.1.4 {Windows reserved path names} -constraints win -body {
+ file pathtype lpt3
+} -result "absolute"
+test winFCmd-18.1.5 {Windows reserved path names} -constraints win -body {
+ file pathtype lpt4
+} -result "relative"
+test winFCmd-18.1.6 {Windows reserved path names} -constraints win -body {
+ file pathtype nul
+} -result "absolute"
+test winFCmd-18.1.7 {Windows reserved path names} -constraints win -body {
+ file pathtype null
+} -result "relative"
+test winFCmd-18.2 {Windows reserved path names} -constraints win -body {
+ file pathtype com1:
+} -result "absolute"
+test winFCmd-18.3 {Windows reserved path names} -constraints win -body {
+ file pathtype COM1
+} -result "absolute"
+test winFCmd-18.4 {Windows reserved path names} -constraints win -body {
+ file pathtype CoM1:
+} -result "absolute"
+test winFCmd-18.5 {Windows reserved path names} -constraints win -body {
+ file normalize com1:
+} -result COM1
+test winFCmd-18.6 {Windows reserved path names} -constraints win -body {
+ file normalize COM1:
+} -result COM1
+test winFCmd-18.7 {Windows reserved path names} -constraints win -body {
+ file normalize cOm1
+} -result COM1
+test winFCmd-18.8 {Windows reserved path names} -constraints win -body {
+ file normalize cOm1:
+} -result COM1
+
+test winFCmd-19.1 {Windows extended path names} -constraints nt -body {
+ file normalize //?/c:/windows/win.ini
+} -result //?/c:/windows/win.ini
+test winFCmd-19.2 {Windows extended path names} -constraints nt -body {
+ file normalize //?/c:/windows/../windows/win.ini
+} -result //?/c:/windows/win.ini
+test winFCmd-19.3 {Windows extended path names} -constraints nt -setup {
+ set tmpfile [file join $::env(TEMP) tcl[string repeat x 20].tmp]
+ set tmpfile [file normalize $tmpfile]
+} -body {
+ list [catch {
+ set f [open $tmpfile [list WRONLY CREAT]]
+ close $f
+ } res] $res
+} -cleanup {
+ catch {file delete $tmpfile}
+} -result [list 0 {}]
+test winFCmd-19.4 {Windows extended path names} -constraints nt -setup {
+ set tmpfile [file join $::env(TEMP) tcl[string repeat x 20].tmp]
+ set tmpfile //?/[file normalize $tmpfile]
+} -body {
+ list [catch {
+ set f [open $tmpfile [list WRONLY CREAT]]
+ close $f
+ } res] $res
+} -cleanup {
+ catch {file delete $tmpfile}
+} -result [list 0 {}]
+test winFCmd-19.5 {Windows extended path names} -constraints nt -setup {
+ set tmpfile [file join $::env(TEMP) tcl[string repeat x 248].tmp]
+ set tmpfile [file normalize $tmpfile]
+} -body {
+ list [catch {
+ set f [open $tmpfile [list WRONLY CREAT]]
+ close $f
+ } res] errormsg ;#$res
+} -cleanup {
+ catch {file delete $tmpfile}
+} -result [list 1 errormsg]
+test winFCmd-19.6 {Windows extended path names} -constraints nt -setup {
+ set tmpfile [file join $::env(TEMP) tcl[string repeat x 248].tmp]
+ set tmpfile //?/[file normalize $tmpfile]
+} -body {
+ list [catch {
+ set f [open $tmpfile [list WRONLY CREAT]]
+ close $f
+ } res] $res
+} -cleanup {
+ catch {file delete $tmpfile}
+} -result [list 0 {}]
+test winFCmd-19.7 {Windows extended path names} -constraints nt -setup {
+ set tmpfile [file join $::env(TEMP) "tcl[pid].tmp "]
+ set tmpfile [file normalize $tmpfile]
+} -body {
+ list [catch {
+ set f [open $tmpfile [list WRONLY CREAT]]
+ close $f
+ } res] $res [glob -directory $::env(TEMP) -tails tcl[pid].*]
+} -cleanup {
+ catch {file delete $tmpfile}
+} -result [list 0 {} [list tcl[pid].tmp]]
+test winFCmd-19.8 {Windows extended path names} -constraints nt -setup {
+ set tmpfile [file join $::env(TEMP) "tcl[pid].tmp "]
+ set tmpfile //?/[file normalize $tmpfile]
+} -body {
+ list [catch {
+ set f [open $tmpfile [list WRONLY CREAT]]
+ close $f
+ } res] $res [glob -directory $::env(TEMP) -tails tcl[pid].*]
+} -cleanup {
+ catch {file delete $tmpfile}
+} -result [list 0 {} [list "tcl[pid].tmp "]]
+
+# This block of code used to occur after the "return" call, so I'm
+# commenting it out and assuming that this code is still under construction.
+#foreach source {tef ted tnf tnd "" nul com1} {
+# foreach chmodsrc {000 755} {
+# foreach dest "tfn tfe tdn tdempty tdfull td1/td2 $p $p/td1 {} nul" {
+# foreach chmoddst {000 755} {
+# puts hi
+# cleanup
+# file delete -force ted tef
+# file mkdir ted
+# createfile tef
+# createfile tfe
+# file mkdir tdempty
+# file mkdir tdfull/td1/td2
+#
+# catch {testchmod $chmodsrc $source}
+# catch {testchmod $chmoddst $dest}
+#
+# if [catch {file rename $source $dest} msg] {
+# puts "file rename $source ($chmodsrc) $dest ($chmoddst)"
+# puts $msg
+# }
+# }
+# }
+# }
+#}
+
+# cleanup
+cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/winFile.test b/pkgs/msgcat/tests/winFile.test
new file mode 100644
index 0000000..ad34624
--- /dev/null
+++ b/pkgs/msgcat/tests/winFile.test
@@ -0,0 +1,239 @@
+# This file tests the tclWinFile.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[catch {package require tcltest 2.0.2}]} {
+ puts stderr "Skipping tests in [info script]. tcltest 2.0.2 required."
+ return
+}
+namespace import -force ::tcltest::*
+
+testConstraint testvolumetype [llength [info commands testvolumetype]]
+testConstraint notNTFS 0
+testConstraint win2000 0
+
+if {[testConstraint testvolumetype]} {
+ testConstraint notNTFS [expr {[testvolumetype] eq "NTFS"}]
+}
+if {[testConstraint nt] && $::tcl_platform(osVersion) >= 5.0} {
+ testConstraint win2000 1
+}
+
+test winFile-1.1 {TclpGetUserHome} -constraints {win} -body {
+ glob ~nosuchuser
+} -returnCodes error -result {user "nosuchuser" doesn't exist}
+test winFile-1.2 {TclpGetUserHome} -constraints {win nt nonPortable} -body {
+ # The administrator account should always exist.
+ glob ~administrator
+} -match glob -result *
+test winFile-1.3 {TclpGetUserHome} -constraints {win 95} -body {
+ # Find some user in system.ini and then see if they have a home.
+
+ set f [open $::env(windir)/system.ini]
+ while {[gets $f line] >= 0} {
+ if {$line ne {[Password Lists]}} {
+ continue
+ }
+ gets $f
+ set name [lindex [split [gets $f] =] 0]
+ if {$name ne ""} {
+ return [catch {glob ~$name}]
+ }
+ }
+ return 0 ;# didn't find anything...
+} -cleanup {
+ catch {close $f}
+} -result {0}
+test winFile-1.4 {TclpGetUserHome} {win nt nonPortable} {
+ catch {glob ~stanton@workgroup}
+} {0}
+
+test winFile-2.1 {TclpMatchFiles: case sensitivity} -constraints {win} -body {
+ makeFile {} GlobCapS
+ list [glob -nocomplain GlobC*] [glob -nocomplain globc*]
+} -cleanup {
+ removeFile GlobCapS
+} -result {GlobCapS GlobCapS}
+test winFile-2.2 {TclpMatchFiles: case sensitivity} -constraints {win} -body {
+ makeFile {} globlower
+ list [glob -nocomplain globl*] [glob -nocomplain gLOBl*]
+} -cleanup {
+ removeFile globlower
+} -result {globlower globlower}
+
+test winFile-3.1 {file system} -constraints {win testvolumetype} -setup {
+ set res ""
+} -body {
+ foreach vol [file volumes] {
+ # Have to catch in case there is a removable drive (CDROM, floppy)
+ # with nothing in it.
+ catch {
+ if {[lindex [file system $vol] 1] ne [testvolumetype $vol]} {
+ append res "For $vol, we found [file system $vol]\
+ and [testvolumetype $vol] are different\n"
+ }
+ }
+ }
+ set res
+} -result {}
+
+proc cacls {fname args} {
+ string trim [eval [list exec cacls [file nativename $fname]] $args <<y]
+}
+
+# dir/q output:
+# 2003-11-03 20:36 598 OCTAVIAN\benny filename.txt
+# Note this output from a german win2k machine:
+# 14.12.2007 14:26 30 VORDEFINIERT\Administratest.dat
+#
+# Modified to cope with Msys environment and use ls -l.
+proc getuser {fname} {
+ global env
+ set tryname $fname
+ if {[file isdirectory $fname]} {
+ set tryname [file dirname $fname]
+ }
+ set owner ""
+ set tail [file tail $tryname]
+ if {[info exists env(OSTYPE)] && $env(OSTYPE) eq "msys"} {
+ set dirtext [exec ls -l $fname]
+ foreach line [split $dirtext "\n"] {
+ set owner [lindex $line 2]
+ }
+ } else {
+ set dirtext [exec cmd /c dir /q [file nativename $fname]]
+ foreach line [split $dirtext "\n"] {
+ if {[string match -nocase "*$tail" $line]} {
+ set attrs [string range $line 0 end-[string length $tail]]
+ regexp { [^ \\]+\\.*$} $attrs owner
+ set owner [string trim $owner]
+ }
+ }
+ }
+ if {$owner eq ""} {
+ error "getuser: Owner not found in output of dir/q"
+ }
+ return $owner
+}
+
+proc test_read {fname} {
+ if {[catch {open $fname r} ifs]} {
+ return 0
+ }
+ set readfailed [catch {read $ifs}]
+ return [expr {![catch {close $ifs}] && !$readfailed}]
+}
+
+proc test_writ {fname} {
+ if {[catch {open $fname w} ofs]} {
+ return 0
+ }
+ set writefailed [catch {puts $ofs "Hello"}]
+ return [expr {![catch {close $ofs}] && !$writefailed}]
+}
+
+proc test_access {fname read writ} {
+ set problem {}
+ foreach type {read writ} {
+ if {[set $type] != [file ${type}able $fname]} {
+ lappend problem "[set $type] != \[file ${type}able $fname\]"
+ }
+ if {[set $type] != [test_${type} $fname]} {
+ lappend problem "[set $type] != \[test_${type} $fname\]"
+ }
+ }
+ if {![llength $problem]} {
+ return
+ }
+ return "Problem [join $problem \n]\nActual rights are: [cacls $fname]"
+}
+
+if {[testConstraint win]} {
+ # Create the test file
+ # NOTE: [tcltest::makeFile] not used. Presumably to force file
+ # creation in a particular filesystem? If not, try [makeFile]
+ # in a -setup script.
+ set fname test.dat
+ file delete $fname
+ close [open $fname w]
+}
+
+test winFile-4.0 {
+ Enhanced NTFS user/group permissions: test no acccess
+} -constraints {
+ win nt notNTFS win2000
+} -setup {
+ set owner [getuser $fname]
+ set user $::env(USERDOMAIN)\\$::env(USERNAME)
+} -body {
+ # Clean out all well-known ACLs
+ catch {cacls $fname /E /R "Everyone"} result
+ catch {cacls $fname /E /R $user} result
+ catch {cacls $fname /E /R $owner} result
+ cacls $fname /E /P $user:N
+ test_access $fname 0 0
+} -result {}
+test winFile-4.1 {
+ Enhanced NTFS user/group permissions: test readable only
+} -constraints {
+ win nt notNTFS
+} -setup {
+ set user $::env(USERDOMAIN)\\$::env(USERNAME)
+} -body {
+ cacls $fname /E /P $user:N
+ cacls $fname /E /G $user:R
+ test_access $fname 1 0
+} -result {}
+test winFile-4.2 {
+ Enhanced NTFS user/group permissions: test writable only
+} -constraints {
+ win nt notNTFS
+} -setup {
+ set user $::env(USERDOMAIN)\\$::env(USERNAME)
+} -body {
+ catch {cacls $fname /E /R $user} result
+ cacls $fname /E /P $user:N
+ cacls $fname /E /G $user:W
+ test_access $fname 0 1
+} -result {}
+test winFile-4.3 {
+ Enhanced NTFS user/group permissions: test read+write
+} -constraints {
+ win nt notNTFS
+} -setup {
+ set user $::env(USERDOMAIN)\\$::env(USERNAME)
+} -body {
+ catch {cacls $fname /E /R $user} result
+ cacls $fname /E /P $user:N
+ cacls $fname /E /G $user:R
+ cacls $fname /E /G $user:W
+ test_access $fname 1 1
+} -result {}
+test winFile-4.4 {
+ Enhanced NTFS user/group permissions: test full access
+} -constraints {
+ win nt notNTFS
+} -setup {
+ set user $::env(USERDOMAIN)\\$::env(USERNAME)
+} -body {
+ catch {cacls $fname /E /R $user} result
+ cacls $fname /E /P $user:N
+ cacls $fname /E /G $user:F
+ test_access $fname 1 1
+} -result {}
+
+if {[testConstraint win]} {
+ file delete $fname
+}
+
+# cleanup
+cleanupTests
+return
diff --git a/pkgs/msgcat/tests/winNotify.test b/pkgs/msgcat/tests/winNotify.test
new file mode 100644
index 0000000..f9c75a3
--- /dev/null
+++ b/pkgs/msgcat/tests/winNotify.test
@@ -0,0 +1,159 @@
+# This file tests the tclWinNotify.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testeventloop [expr {[info commands testeventloop] != {}}]
+
+# There is no explicit test for InitNotifier or NotifierExitHandler
+
+test winNotify-1.1 {Tcl_SetTimer: positive timeout} {win} {
+ set done 0
+ after 1000 { set done 1 }
+ vwait done
+ set done
+} 1
+test winNotify-1.2 {Tcl_SetTimer: positive timeout, message pending} {win} {
+ set x 0
+ set y 1
+ set a1 [after 0 { incr y }]
+ after cancel $a1
+ after 500 { incr x }
+ vwait x
+ list $x $y
+} {1 1}
+test winNotify-1.3 {Tcl_SetTimer: cancelling positive timeout} {win} {
+ set x 0
+ set y 1
+ set id [after 10000 { incr y }]
+ after 0 { incr x }
+ vwait x
+ after cancel $id
+ list $x $y
+} {1 1}
+test winNotify-1.4 {Tcl_SetTimer: null timeout, message pending} {win} {
+ set x 0
+ set y 1
+ after 0 { incr x }
+ after 0 { incr y }
+ vwait x
+ list $x $y
+} {1 2}
+
+test winNotify-2.1 {Tcl_ResetIdleTimer} {win} {
+ set x 0
+ update
+ after idle { incr x }
+ vwait x
+ set x
+} 1
+test winNotify-2.2 {Tcl_ResetIdleTimer: message pending} {win} {
+ set x 0
+ set y 1
+ update
+ after idle { incr x }
+ after idle { incr y }
+ update
+ list $x $y
+} {1 2}
+
+test winNotify-3.1 {NotifierProc: non-modal normal timer} {win testeventloop} {
+ update
+ set x 0
+ foreach i [after info] {
+ after cancel $i
+ }
+ after 500 { incr x; testeventloop done }
+ testeventloop wait
+ set x
+} 1
+test winNotify-3.2 {NotifierProc: non-modal normal timer, rescheduled} {win testeventloop} {
+ update
+ set x 0
+ foreach i [after info] {
+ after cancel $i
+ }
+ after 500 { incr x; after 100 {incr x; testeventloop done }}
+ testeventloop wait
+ set x
+} 2
+test winNotify-3.3 {NotifierProc: modal normal timer} {win} {
+ update
+ set x 0
+ foreach i [after info] {
+ after cancel $i
+ }
+ after 500 { incr x }
+ vwait x
+ set x
+} 1
+test winNotify-3.4 {NotifierProc: modal normal timer, rescheduled} {win} {
+ update
+ set x 0
+ foreach i [after info] {
+ after cancel $i
+ }
+ set y 0
+ after 500 { incr y; after 100 {incr x}}
+ vwait x
+ list $x $y
+} {1 1}
+test winNotify-3.5 {NotifierProc: non-modal idle timer} {win testeventloop} {
+ update
+ set x 0
+ foreach i [after info] {
+ after cancel $i
+ }
+ after idle { incr x; testeventloop done }
+ testeventloop wait
+ set x
+} 1
+test winNotify-3.6 {NotifierProc: non-modal idle timer, rescheduled} {win testeventloop} {
+ update
+ set x 0
+ foreach i [after info] {
+ after cancel $i
+ }
+ after idle { incr x; after idle {incr x; testeventloop done }}
+ testeventloop wait
+ set x
+} 2
+test winNotify-3.7 {NotifierProc: modal idle timer} {win} {
+ update
+ set x 0
+ foreach i [after info] {
+ after cancel $i
+ }
+ after idle { incr x }
+ vwait x
+ set x
+} 1
+test winNotify-3.8 {NotifierProc: modal idle timer, rescheduled} {win} {
+ update
+ set x 0
+ foreach i [after info] {
+ after cancel $i
+ }
+ set y 0
+ after idle { incr y; after idle {incr x}}
+ vwait x
+ list $x $y
+} {1 1}
+
+# Tcl_DoOneEvent is tested by the timer.test, io.test, and event.test files
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/winPipe.test b/pkgs/msgcat/tests/winPipe.test
new file mode 100644
index 0000000..62d7d0d
--- /dev/null
+++ b/pkgs/msgcat/tests/winPipe.test
@@ -0,0 +1,450 @@
+#
+# winPipe.test --
+#
+# This file contains a collection of tests for tclWinPipe.c
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output (except for one message) means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest
+namespace import -force ::tcltest::*
+unset -nocomplain path
+
+set bindir [file join [pwd] [file dirname [info nameofexecutable]]]
+set cat32 [file join $bindir cat32.exe]
+
+testConstraint exec [llength [info commands exec]]
+testConstraint cat32 [file exists $cat32]
+testConstraint AllocConsole [catch {puts console1 ""}]
+testConstraint RealConsole [expr {![testConstraint AllocConsole]}]
+
+set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n
+append big $big
+append big $big
+append big $big
+append big $big
+append big $big
+append big $big
+
+set path(little) [makeFile {} little]
+set f [open $path(little) w]
+puts -nonewline $f "little"
+close $f
+
+set path(big) [makeFile {} big]
+set f [open $path(big) w]
+puts -nonewline $f $big
+close $f
+
+proc contents {file} {
+ set f [open $file r]
+ set r [read $f]
+ close $f
+ set r
+}
+
+set path(more) [makeFile {
+ while {[eof stdin] == 0} {
+ puts -nonewline [read stdin]
+ }
+} more]
+
+set path(stdout) [makeFile {} stdout]
+set path(stderr) [makeFile {} stderr]
+
+test winpipe-1.1 {32 bit comprehensive tests: from little file} {win exec cat32} {
+ exec $cat32 < $path(little) > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.2 {32 bit comprehensive tests: from big file} {win exec cat32} {
+ exec $cat32 < $path(big) > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} "{$big} stderr32"
+test winpipe-1.3 {32 bit comprehensive tests: a little from pipe} {win nt exec cat32} {
+ exec [interpreter] $path(more) < $path(little) | $cat32 > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.4 {32 bit comprehensive tests: a lot from pipe} {win nt exec cat32} {
+ exec [interpreter] $path(more) < $path(big) | $cat32 > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} "{$big} stderr32"
+test winpipe-1.5 {32 bit comprehensive tests: a lot from pipe} {win 95 exec cat32} {
+ exec command /c type $path(big) |& $cat32 > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} "{$big} stderr32"
+test winpipe-1.6 {32 bit comprehensive tests: from console} \
+ {win cat32 AllocConsole} {
+ # would block waiting for human input
+} {}
+test winpipe-1.7 {32 bit comprehensive tests: from NUL} {win exec cat32} {
+ exec $cat32 < nul > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} {{} stderr32}
+test winpipe-1.8 {32 bit comprehensive tests: from socket} {win cat32} {
+ # doesn't work
+} {}
+test winpipe-1.9 {32 bit comprehensive tests: from nowhere} \
+ {win exec cat32 RealConsole} {
+ exec $cat32 > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} {{} stderr32}
+test winpipe-1.10 {32 bit comprehensive tests: from file handle} \
+ {win exec cat32} {
+ set f [open $path(little) r]
+ exec $cat32 <@$f > $path(stdout) 2> $path(stderr)
+ close $f
+ list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.11 {32 bit comprehensive tests: read from application} \
+ {win exec cat32} {
+ set f [open "|[list $cat32] < [list $path(little)]" r]
+ gets $f line
+ catch {close $f} msg
+ list $line $msg
+} {little stderr32}
+test winpipe-1.12 {32 bit comprehensive tests: a little to file} \
+ {win exec cat32} {
+ exec $cat32 < $path(little) > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.13 {32 bit comprehensive tests: a lot to file} \
+ {win exec cat32} {
+ exec $cat32 < $path(big) > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} "{$big} stderr32"
+test winpipe-1.14 {32 bit comprehensive tests: a little to pipe} \
+ {win exec stdio cat32} {
+ exec $cat32 < $path(little) | [interpreter] $path(more) > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.15 {32 bit comprehensive tests: a lot to pipe} \
+ {win exec stdio cat32} {
+ exec $cat32 < $path(big) | [interpreter] $path(more) > $path(stdout) 2> $path(stderr)
+ list [contents $path(stdout)] [contents $path(stderr)]
+} "{$big} stderr32"
+test winpipe-1.16 {32 bit comprehensive tests: to console} {win exec cat32} {
+ catch {exec $cat32 << "You should see this\n" >@stdout} msg
+ set msg
+} stderr32
+test winpipe-1.17 {32 bit comprehensive tests: to NUL} {win exec cat32} {
+ # some apps hang when sending a large amount to NUL. $cat32 isn't one.
+ catch {exec $cat32 < $path(big) > nul} msg
+ set msg
+} stderr32
+test winpipe-1.18 {32 bit comprehensive tests: to nowhere} \
+ {win exec cat32 RealConsole} {
+ exec $cat32 < $path(big) >&@stdout
+} {}
+test winpipe-1.19 {32 bit comprehensive tests: to file handle} {win exec cat32} {
+ set f1 [open $path(stdout) w]
+ set f2 [open $path(stderr) w]
+ exec $cat32 < $path(little) >@$f1 2>@$f2
+ close $f1
+ close $f2
+ list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.20 {32 bit comprehensive tests: write to application} \
+ {win exec cat32} {
+ set f [open |[list $cat32 >$path(stdout)] w]
+ puts -nonewline $f "foo"
+ catch {close $f} msg
+ list [contents $path(stdout)] $msg
+} {foo stderr32}
+test winpipe-1.21 {32 bit comprehensive tests: read/write application} \
+ {win exec cat32} {
+ set f [open "|[list $cat32]" r+]
+ puts $f $big
+ puts $f \032
+ flush $f
+ set r [read $f 64]
+ catch {close $f}
+ set r
+} "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
+test winpipe-1.22 {Checking command.com for Win95/98 hanging} {win 95 exec} {
+ exec command.com /c dir /b
+ set result 1
+} 1
+
+test winpipe-4.1 {Tcl_WaitPid} {win nt exec cat32} {
+ proc readResults {f} {
+ global x result
+ if { [eof $f] } {
+ close $f
+ set x 1
+ } else {
+ set line [read $f ]
+ set result "$result$line"
+ }
+ }
+ set f [open "|[list $cat32] < $path(big) 2> $path(stderr)" r]
+ fconfigure $f -buffering none -blocking 0
+ fileevent $f readable "readResults $f"
+ set x 0
+ set result ""
+ vwait x
+ list $result $x [contents $path(stderr)]
+} "{$big} 1 stderr32"
+test winpipe-4.2 {Tcl_WaitPid: return of exception codes, SIGFPE} {win exec} {
+ set f [open "|[list [interpreter]]" w+]
+ set pid [pid $f]
+ puts $f "testexcept float_underflow"
+ set status [catch {close $f}]
+ list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2]
+} {1 1 SIGFPE}
+test winpipe-4.3 {Tcl_WaitPid: return of exception codes, SIGSEGV} {win exec} {
+ set f [open "|[list [interpreter]]" w+]
+ set pid [pid $f]
+ puts $f "testexcept access_violation"
+ set status [catch {close $f}]
+ list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2]
+} {1 1 SIGSEGV}
+test winpipe-4.4 {Tcl_WaitPid: return of exception codes, SIGILL} {win exec} {
+ set f [open "|[list [interpreter]]" w+]
+ set pid [pid $f]
+ puts $f "testexcept illegal_instruction"
+ set status [catch {close $f}]
+ list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2]
+} {1 1 SIGILL}
+test winpipe-4.5 {Tcl_WaitPid: return of exception codes, SIGINT} {win exec} {
+ set f [open "|[list [interpreter]]" w+]
+ set pid [pid $f]
+ puts $f "testexcept ctrl+c"
+ set status [catch {close $f}]
+ list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2]
+} {1 1 SIGINT}
+
+set path(nothing) [makeFile {} nothing]
+close [open $path(nothing) w]
+
+catch {set env_tmp $env(TMP)}
+catch {set env_temp $env(TEMP)}
+
+set env(TMP) c:/
+set env(TEMP) c:/
+
+test winpipe-5.1 {TclpCreateTempFile: cleanup temp files} {win exec} {
+ set x {}
+ set existing [glob -nocomplain c:/tcl*.tmp]
+ exec [interpreter] < $path(nothing)
+ foreach p [glob -nocomplain c:/tcl*.tmp] {
+ if {$p ni $existing} {
+ lappend x $p
+ }
+ }
+ set x
+} {}
+test winpipe-5.2 {TclpCreateTempFile: TMP and TEMP not defined} {win exec} {
+ set tmp $env(TMP)
+ set temp $env(TEMP)
+ unset env(TMP)
+ unset env(TEMP)
+ exec [interpreter] < $path(nothing)
+ set env(TMP) $tmp
+ set env(TEMP) $temp
+ set x {}
+} {}
+test winpipe-5.3 {TclpCreateTempFile: TMP specifies non-existent directory} \
+ {win exec } {
+ set tmp $env(TMP)
+ set env(TMP) snarky
+ exec [interpreter] < $path(nothing)
+ set env(TMP) $tmp
+ set x {}
+} {}
+test winpipe-5.4 {TclpCreateTempFile: TEMP specifies non-existent directory} \
+ {win exec} {
+ set tmp $env(TMP)
+ set temp $env(TEMP)
+ unset env(TMP)
+ set env(TEMP) snarky
+ exec [interpreter] < $path(nothing)
+ set env(TMP) $tmp
+ set env(TEMP) $temp
+ set x {}
+} {}
+
+test winpipe-6.1 {PipeSetupProc & PipeCheckProc: read threads} \
+ {win exec cat32} {
+ set f [open "|[list $cat32]" r+]
+ fconfigure $f -blocking 0
+ fileevent $f writable { set x writable }
+ set x {}
+ vwait x
+ fileevent $f writable {}
+ fileevent $f readable { lappend x readable }
+ after 100 { lappend x timeout }
+ vwait x
+ puts $f foobar
+ flush $f
+ vwait x
+ lappend x [read $f]
+ after 100 { lappend x timeout }
+ vwait x
+ fconfigure $f -blocking 1
+ lappend x [catch {close $f} msg] $msg
+} {writable timeout readable {foobar
+} timeout 1 stderr32}
+test winpipe-6.2 {PipeSetupProc & PipeCheckProc: write threads} \
+ {win exec cat32} {
+ set f [open "|[list $cat32]" r+]
+ fconfigure $f -blocking 0
+ fileevent $f writable { set x writable }
+ set x {}
+ vwait x
+ puts -nonewline $f $big$big$big$big
+ flush $f
+ after 100 { lappend x timeout }
+ vwait x
+ lappend x [catch {close $f} msg] $msg
+} {writable timeout 0 {}}
+
+set path(echoArgs.tcl) [makeFile {
+ puts "[list $argv0 $argv]"
+} echoArgs.tcl]
+
+### validate the raw output of BuildCommandLine().
+###
+test winpipe-7.1 {BuildCommandLine: null arguments} {win exec} {
+ exec $env(COMSPEC) /c echo foo "" bar
+} {foo "" bar}
+test winpipe-7.2 {BuildCommandLine: null arguments} {win exec} {
+ exec $env(COMSPEC) /c echo foo {} bar
+} {foo "" bar}
+test winpipe-7.3 {BuildCommandLine: dbl quote quoting #1} {win exec} {
+ exec $env(COMSPEC) /c echo foo "\"" bar
+} {foo \" bar}
+test winpipe-7.4 {BuildCommandLine: dbl quote quoting #2} {win exec} {
+ exec $env(COMSPEC) /c echo foo {""} bar
+} {foo \"\" bar}
+test winpipe-7.5 {BuildCommandLine: dbl quote quoting #3} {win exec} {
+ exec $env(COMSPEC) /c echo foo "\" " bar
+} {foo "\" " bar}
+test winpipe-7.6 {BuildCommandLine: dbl quote quoting #4} {win exec} {
+ exec $env(COMSPEC) /c echo foo {a="b"} bar
+} {foo a=\"b\" bar}
+test winpipe-7.7 {BuildCommandLine: dbl quote quoting #5} {win exec} {
+ exec $env(COMSPEC) /c echo foo {a = "b"} bar
+} {foo "a = \"b\"" bar}
+test winpipe-7.8 {BuildCommandLine: dbl quote quoting #6} {win exec} {
+ exec $env(COMSPEC) /c echo {"hello"} {""hello""} {"""hello"""} {"\"hello\""} {he llo} "he \" llo"
+} {\"hello\" \"\"hello\"\" \"\"\"hello\"\"\" \"\\\"hello\\\"\" "he llo" "he \" llo"}
+test winpipe-7.9 {BuildCommandLine: N backslashes followed a quote rule #1} {win exec} {
+ exec $env(COMSPEC) /c echo foo \\ bar
+} {foo \ bar}
+test winpipe-7.10 {BuildCommandLine: N backslashes followed a quote rule #2} {win exec} {
+ exec $env(COMSPEC) /c echo foo \\\\ bar
+} {foo \\ bar}
+test winpipe-7.11 {BuildCommandLine: N backslashes followed a quote rule #3} {win exec} {
+ exec $env(COMSPEC) /c echo foo \\\ \\ bar
+} {foo "\ \\" bar}
+test winpipe-7.12 {BuildCommandLine: N backslashes followed a quote rule #4} {win exec} {
+ exec $env(COMSPEC) /c echo foo \\\ \\\\ bar
+} {foo "\ \\\\" bar}
+test winpipe-7.13 {BuildCommandLine: N backslashes followed a quote rule #5} {win exec} {
+ exec $env(COMSPEC) /c echo foo \\\ \\\\\\ bar
+} {foo "\ \\\\\\" bar}
+test winpipe-7.14 {BuildCommandLine: N backslashes followed a quote rule #6} {win exec} {
+ exec $env(COMSPEC) /c echo foo \\\ \\\" bar
+} {foo "\ \\\"" bar}
+test winpipe-7.15 {BuildCommandLine: N backslashes followed a quote rule #7} {win exec} {
+ exec $env(COMSPEC) /c echo foo \\\ \\\\\" bar
+} {foo "\ \\\\\"" bar}
+test winpipe-7.16 {BuildCommandLine: N backslashes followed a quote rule #8} {win exec} {
+ exec $env(COMSPEC) /c echo foo \\\ \\\\\\\" bar
+} {foo "\ \\\\\\\"" bar}
+test winpipe-7.17 {BuildCommandLine: special chars #4} {win exec} {
+ exec $env(COMSPEC) /c echo foo \{ bar
+} "foo \{ bar"
+test winpipe-7.18 {BuildCommandLine: special chars #5} {win exec} {
+ exec $env(COMSPEC) /c echo foo \} bar
+} "foo \} bar"
+
+### validate the pass-thru from BuildCommandLine() to the crt's parse_cmdline().
+###
+test winpipe-8.1 {BuildCommandLine/parse_cmdline pass-thru: null arguments} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo "" bar
+} [list $path(echoArgs.tcl) [list foo {} bar]]
+test winpipe-8.2 {BuildCommandLine/parse_cmdline pass-thru: null arguments} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo {} bar
+} [list $path(echoArgs.tcl) [list foo {} bar]]
+test winpipe-8.3 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #1} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo "\"" bar
+} [list $path(echoArgs.tcl) [list foo "\"" bar]]
+test winpipe-8.4 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #2} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo {""} bar
+} [list $path(echoArgs.tcl) [list foo {""} bar]]
+test winpipe-8.5 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #3} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo "\" " bar
+} [list $path(echoArgs.tcl) [list foo "\" " bar]]
+test winpipe-8.6 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #4} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo {a="b"} bar
+} [list $path(echoArgs.tcl) [list foo {a="b"} bar]]
+test winpipe-8.7 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #5} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo {a = "b"} bar
+} [list $path(echoArgs.tcl) [list foo {a = "b"} bar]]
+test winpipe-8.8 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #6} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) {"hello"} {""hello""} {"""hello"""} {"\"hello\""} {he llo} {he " llo}
+} [list $path(echoArgs.tcl) [list {"hello"} {""hello""} {"""hello"""} {"\"hello\""} {he llo} {he " llo}]]
+test winpipe-8.9 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #1} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \\ bar
+} [list $path(echoArgs.tcl) [list foo \\ bar]]
+test winpipe-8.10 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #2} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \\\\ bar
+} [list $path(echoArgs.tcl) [list foo \\\\ bar]]
+test winpipe-8.11 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #3} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \\\ \\ bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\ bar]]
+test winpipe-8.12 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #4} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\ bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\\\ bar]]
+test winpipe-8.13 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #5} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\\\ bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\\\\\ bar]]
+test winpipe-8.14 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #6} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\" bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\\" bar]]
+test winpipe-8.15 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #7} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\\" bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\\\\" bar]]
+test winpipe-8.16 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #8} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\\\\" bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\\\\\\" bar]]
+test winpipe-8.17 {BuildCommandLine/parse_cmdline pass-thru: special chars #1} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \{ bar
+} [list $path(echoArgs.tcl) [list foo \{ bar]]
+test winpipe-8.18 {BuildCommandLine/parse_cmdline pass-thru: special chars #2} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo \} bar
+} [list $path(echoArgs.tcl) [list foo \} bar]]
+test winpipe-8.19 {ensure parse_cmdline isn't doing wildcard replacement} {win exec} {
+ exec [interpreter] $path(echoArgs.tcl) foo * makefile.?c bar
+} [list $path(echoArgs.tcl) [list foo * makefile.?c bar]]
+
+# restore old values for env(TMP) and env(TEMP)
+
+if {[catch {set env(TMP) $env_tmp}]} {
+ unset env(TMP)
+}
+if {[catch {set env(TEMP) $env_temp}]} {
+ unset env(TEMP)
+}
+
+# cleanup
+removeFile little
+removeFile big
+removeFile more
+removeFile stdout
+removeFile stderr
+removeFile nothing
+removeFile echoArgs.tcl
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/pkgs/msgcat/tests/winTime.test b/pkgs/msgcat/tests/winTime.test
new file mode 100644
index 0000000..278db32
--- /dev/null
+++ b/pkgs/msgcat/tests/winTime.test
@@ -0,0 +1,63 @@
+# This file tests the tclWinTime.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+testConstraint testwinclock [llength [info commands testwinclock]]
+
+# The next two tests will crash on Windows if the check for negative
+# clock values is not done properly.
+
+test winTime-1.1 {TclpGetDate} {win} {
+ set ::env(TZ) JST-9
+ set result [clock format -1 -format %Y]
+ unset ::env(TZ)
+ set result
+} {1970}
+test winTime-1.2 {TclpGetDate} {win} {
+ set ::env(TZ) PST8
+ set result [clock format 1 -format %Y]
+ unset ::env(TZ)
+ set result
+} {1969}
+
+# Next test tries to make sure that the Tcl clock stays in step
+# with the Windows clock. 30 sec really isn't enough,
+# but how much time does a tester have patience for?
+
+test winTime-2.1 {Synchronization of Tcl and Windows clocks} {testwinclock} {
+ # May fail due to OS/hardware discrepancies. See:
+ # http://support.microsoft.com/default.aspx?scid=kb;en-us;274323
+ set failed {}
+ set ok 1
+ foreach start_sec [testwinclock] break
+ while { 1 } {
+ foreach { sys_sec sys_usec tcl_sec tcl_usec } [testwinclock] break
+ set diff [expr { $tcl_sec - $sys_sec
+ + 1.0e-6 * ( $tcl_usec - $sys_usec ) }]
+ if { abs($diff) > 0.06 } {
+ set failed "Tcl clock differs from system clock by $diff sec"
+ break
+ } else {
+ testwinsleep 1
+ }
+ if { $sys_sec - $start_sec >= 30 } break
+ }
+ set failed
+} {}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/pkgs/msgcat/tests/zlib.test b/pkgs/msgcat/tests/zlib.test
new file mode 100644
index 0000000..8212082
--- /dev/null
+++ b/pkgs/msgcat/tests/zlib.test
@@ -0,0 +1,672 @@
+# The file tests the tclZlib.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1996-1998 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.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2.1
+ namespace import -force ::tcltest::*
+}
+
+testConstraint zlib [llength [info commands zlib]]
+
+test zlib-1.1 {zlib basics} -constraints zlib -returnCodes error -body {
+ zlib
+} -result {wrong # args: should be "zlib command arg ?...?"}
+test zlib-1.2 {zlib basics} -constraints zlib -returnCodes error -body {
+ zlib ? {}
+} -result {bad command "?": must be adler32, compress, crc32, decompress, deflate, gunzip, gzip, inflate, push, or stream}
+
+test zlib-2.1 {zlib compress/decompress} zlib {
+ zlib decompress [zlib compress abcdefghijklm]
+} abcdefghijklm
+
+test zlib-3.1 {zlib deflate/inflate} zlib {
+ zlib inflate [zlib deflate abcdefghijklm]
+} abcdefghijklm
+
+test zlib-4.1 {zlib gzip/gunzip} zlib {
+ zlib gunzip [zlib gzip abcdefghijklm]
+} abcdefghijklm
+test zlib-4.2 {zlib gzip/gunzip} zlib {
+ set s [string repeat abcdef 5]
+ list [zlib gunzip [zlib gzip $s -header {comment gorp}] -header head] \
+ [dict get $head comment] [dict get $head size]
+} {abcdefabcdefabcdefabcdefabcdef gorp 30}
+
+test zlib-5.1 {zlib adler32} zlib {
+ format %x [expr {[zlib adler32 abcdeabcdeabcdeabcdeabcdeabcde] & 0xffffffff}]
+} b3b50b9b
+test zlib-5.2 {zlib adler32} zlib {
+ format %x [expr {[zlib adler32 abcdeabcdeabcdeabcdeabcdeabcde 42] & 0xffffffff}]
+} b8830bc4
+test zlib-5.3 {zlib adler32} -constraints zlib -returnCodes error -body {
+ zlib adler32 abcdeabcdeabcdeabcdeabcdeabcde 42 x
+} -result {wrong # args: should be "zlib adler32 data ?startValue?"}
+
+test zlib-6.1 {zlib crc32} zlib {
+ format %x [expr {[zlib crc32 abcdeabcdeabcdeabcdeabcdeabcde] & 0xffffffff}]
+} 6f73e901
+test zlib-6.2 {zlib crc32} zlib {
+ format %x [expr {[zlib crc32 abcdeabcdeabcdeabcdeabcdeabcde 42] & 0xffffffff}]
+} ce1c4914
+test zlib-6.3 {zlib crc32} -constraints zlib -returnCodes error -body {
+ zlib crc32 abcdeabcdeabcdeabcdeabcdeabcde 42 x
+} -result {wrong # args: should be "zlib crc32 data ?startValue?"}
+test zlib-6.4 {zlib crc32: bug 2662434} -constraints zlib -body {
+ zlib crc32 "dabale arroz a la zorra el abad"
+} -result 3842832571
+
+test zlib-7.0 {zlib stream} -constraints zlib -returnCodes error -setup {
+ set s [zlib stream compress]
+} -body {
+ $s ?
+} -cleanup {
+ $s close
+} -result {bad option "?": must be add, checksum, close, eof, finalize, flush, fullflush, get, put, or reset}
+test zlib-7.1 {zlib stream} zlib {
+ set s [zlib stream compress]
+ $s put -finalize abcdeEDCBA
+ set data [$s get]
+ set result [list [$s get] [format %x [$s checksum]]]
+ $s close
+ lappend result [zlib decompress $data]
+} {{} 136f033f abcdeEDCBA}
+test zlib-7.2 {zlib stream} zlib {
+ set s [zlib stream decompress]
+ $s put -finalize [zlib compress abcdeEDCBA]
+ set data [$s get]
+ set result [list [$s get] [format %x [$s checksum]]]
+ $s close
+ lappend result $data
+} {{} 136f033f abcdeEDCBA}
+test zlib-7.3 {zlib stream} zlib {
+ set s [zlib stream deflate]
+ $s put -finalize abcdeEDCBA
+ set data [$s get]
+ set result [list [$s get] [format %x [$s checksum]]]
+ $s close
+ lappend result [zlib inflate $data]
+} {{} 1 abcdeEDCBA}
+test zlib-7.4 {zlib stream} zlib {
+ set s [zlib stream inflate]
+ $s put -finalize [zlib deflate abcdeEDCBA]
+ set data [$s get]
+ set result [list [$s get] [format %x [$s checksum]]]
+ $s close
+ lappend result $data
+} {{} 1 abcdeEDCBA}
+test zlib-7.5 {zlib stream} zlib {
+ set s [zlib stream gzip]
+ $s put -finalize abcdeEDCBA..
+ set data [$s get]
+ set result [list [$s get] [format %x [$s checksum]]]
+ $s close
+ lappend result [zlib gunzip $data]
+} {{} 69f34b6a abcdeEDCBA..}
+test zlib-7.6 {zlib stream} zlib {
+ set s [zlib stream gunzip]
+ $s put -finalize [zlib gzip abcdeEDCBA..]
+ set data [$s get]
+ set result [list [$s get] [format %x [$s checksum]]]
+ $s close
+ lappend result $data
+} {{} 69f34b6a abcdeEDCBA..}
+
+test zlib-8.1 {zlib transformation} -constraints zlib -setup {
+ set file [makeFile {} test.gz]
+} -body {
+ set f [zlib push gzip [open $file w] -header {comment gorp}]
+ puts $f "ok"
+ close $f
+ set f [zlib push gunzip [open $file]]
+ list [gets $f] [dict get [chan configure $f -header] comment]
+} -cleanup {
+ close $f
+ removeFile $file
+} -result {ok gorp}
+test zlib-8.2 {zlib transformation} -constraints zlib -setup {
+ set file [makeFile {} test.z]
+} -body {
+ set f [zlib push compress [open $file w]]
+ puts $f "ok"
+ close $f
+ set f [zlib push decompress [open $file]]
+ gets $f
+} -cleanup {
+ close $f
+ removeFile $file
+} -result ok
+test zlib-8.3 {zlib transformation and fileevent} -constraints zlib -setup {
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ fconfigure $c -translation binary -buffering none -blocking 0
+ puts -nonewline $c [zlib gzip [string repeat a 81920]]
+ close $c
+ }}} 0]
+ set port [lindex [fconfigure $srv -sockname] 2]
+ set file [makeFile {} test.gz]
+ set fout [open $file wb]
+} -body {
+ set sin [socket localhost $port]
+ try {
+ fconfigure $sin -translation binary
+ zlib push gunzip $sin
+ after 1000 {set total timeout}
+ fcopy $sin $fout -command {apply {{c {e {}}} {
+ set ::total [expr {$e eq {} ? $c : $e}]
+ }}}
+ vwait total
+ after cancel {set total timeout}
+ } finally {
+ close $sin
+ }
+ append total --> [file size $file]
+} -cleanup {
+ close $fout
+ close $srv
+ removeFile $file
+} -result 81920-->81920
+test zlib-8.4 {transformation and flushing: Bug 3517696} -setup {
+ set file [makeFile {} test.z]
+ set fd [open $file w]
+} -constraints zlib -body {
+ zlib push compress $fd
+ puts $fd "qwertyuiop"
+ fconfigure $fd -flush sync
+ puts $fd "qwertyuiop"
+} -cleanup {
+ catch {close $fd}
+ removeFile $file
+} -result {}
+test zlib-8.5 {transformation and flushing and fileevents: Bug 3525907} -setup {
+ foreach {r w} [chan pipe] break
+} -constraints zlib -body {
+ set ::res {}
+ fconfigure $w -buffering none
+ zlib push compress $w
+ puts -nonewline $w qwertyuiop
+ chan configure $w -flush sync
+ after 500 {puts -nonewline $w asdfghjkl;close $w}
+ fconfigure $r -blocking 0 -buffering none
+ zlib push decompress $r
+ fileevent $r readable {set msg [read $r];lappend ::res $msg;if {[eof $r]} {set ::done 1}}
+ after 250 {lappend ::res MIDDLE}
+ vwait ::done
+ set ::res
+} -cleanup {
+ catch {close $r}
+} -result {qwertyuiop MIDDLE asdfghjkl}
+
+test zlib-9.1 "check fcopy with push" -constraints zlib -setup {
+ set sfile [makeFile {} testsrc.gz]
+ set file [makeFile {} test.gz]
+ set f [open $sfile wb]
+ puts -nonewline $f [zlib gzip [string repeat a 81920]]
+ close $f
+} -body {
+ set fin [zlib push gunzip [open $sfile rb]]
+ set fout [open $file wb]
+ set total [fcopy $fin $fout]
+ close $fin ; close $fout
+ list copied $total size [file size $file]
+} -cleanup {
+ removeFile $file
+ removeFile $sfile
+} -result {copied 81920 size 81920}
+test zlib-9.2 "socket fcopy with push" -constraints zlib -setup {
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ puts -nonewline $c [zlib gzip [string repeat a 81920]]
+ close $c
+ }}} 0]
+ set file [makeFile {} test.gz]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ set sin [socket $addr $port]
+ chan configure $sin -translation binary
+ zlib push gunzip $sin
+ update
+ set total [fcopy $sin [set fout [open $file wb]]]
+ close $sin
+ close $fout
+ list read $total size [file size $file]
+} -cleanup {
+ close $srv
+ removeFile $file
+} -result {read 81920 size 81920}
+test zlib-9.3 "socket fcopy bg (identity)" -constraints {tempNotWin zlib} -setup {
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ #puts "connection from $a:$p on $c"
+ chan configure $c -translation binary -buffering none -blocking 0
+ puts -nonewline $c [string repeat a 81920]
+ close $c
+ }}} 0]
+ set file [makeFile {} test.gz]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ #puts "listening for connections on $addr $port"
+ set sin [socket localhost $port]
+ chan configure $sin -translation binary
+ update
+ set fout [open $file wb]
+ after 1000 {set ::total timeout}
+ fcopy $sin $fout -command {apply {{c {e {}}} {
+ set ::total [expr {$e eq {} ? $c : $e}]
+ }}}
+ vwait ::total
+ after cancel {set ::total timeout}
+ close $sin; close $fout
+ list read $::total size [file size $file]
+} -cleanup {
+ close $srv
+ removeFile $file
+} -returnCodes {ok error} -result {read 81920 size 81920}
+test zlib-9.4 "socket fcopy bg (gzip)" -constraints zlib -setup {
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ puts -nonewline $c [zlib gzip [string repeat a 81920]]
+ close $c
+ }}} 0]
+ set file [makeFile {} test.gz]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ set sin [socket $addr $port]
+ chan configure $sin -translation binary
+ zlib push gunzip $sin
+ update
+ set fout [open $file wb]
+ after 1000 {set ::total timeout}
+ fcopy $sin $fout -command {apply {{c {e {}}} {
+ set ::total [expr {$e eq {} ? $c : $e}]
+ }}}
+ vwait ::total
+ after cancel {set ::total timeout}
+ close $sin; close $fout
+ list read $::total size [file size $file]
+} -cleanup {
+ close $srv
+ removeFile $file
+} -result {read 81920 size 81920}
+test zlib-9.5 "socket fcopy incremental (gzip)" -constraints zlib -setup {
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ puts -nonewline $c [zlib gzip [string repeat a 81920]]
+ close $c
+ }}} 0]
+ proc zlib95copy {i o t c {e {}}} {
+ incr t $c
+ if {$e ne {}} {
+ set ::total [list error $e]
+ } elseif {[eof $i]} {
+ set ::total [list eof $t]
+ } else {
+ fcopy $i $o -size 8192 -command [list zlib95copy $i $o $t]
+ }
+ }
+ set file [makeFile {} test.gz]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ set sin [socket $addr $port]
+ chan configure $sin -translation binary
+ zlib push gunzip $sin
+ update
+ set fout [open $file wb]
+ after 1000 {set ::total timeout}
+ fcopy $sin $fout -size 8192 -command [list zlib95copy $sin $fout 0]
+ vwait ::total
+ after cancel {set ::total timeout}
+ close $sin; close $fout
+ list $::total size [file size $file]
+} -cleanup {
+ close $srv
+ rename zlib95copy {}
+ removeFile $file
+} -result {{eof 81920} size 81920}
+test zlib-9.6 "bug #2818131 (gzip)" -constraints zlib -setup {
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ zlib push gzip $c
+ puts -nonewline $c [string repeat hello 100]
+ close $c
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ chan configure $s -translation binary
+ zlib push gunzip $s
+ chan event $s readable [list apply {{s} {
+ set d [read $s]
+ if {[eof $s]} {
+ chan event $s readable {}
+ set ::total [list eof [string length $d]]
+ }
+ }} $s]
+ vwait ::total
+ after cancel {set ::total timeout}
+ close $s
+ set ::total
+} -cleanup {
+ close $srv
+ unset -nocomplain total
+} -result {eof 500}
+test zlib-9.7 "bug #2818131 (compress)" -constraints zlib -setup {
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ zlib push compress $c
+ puts -nonewline $c [string repeat hello 100]
+ close $c
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ chan configure $s -translation binary
+ zlib push decompress $s
+ chan event $s readable [list apply {{s} {
+ set d [read $s]
+ if {[eof $s]} {
+ chan event $s readable {}
+ set ::total [list eof [string length $d]]
+ }
+ }} $s]
+ vwait ::total
+ after cancel {set ::total timeout}
+ close $s
+ set ::total
+} -cleanup {
+ close $srv
+ unset -nocomplain total
+} -result {eof 500}
+test zlib-9.8 "bug #2818131 (deflate)" -constraints zlib -setup {
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ zlib push deflate $c
+ puts -nonewline $c [string repeat hello 100]
+ close $c
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ chan configure $s -translation binary
+ zlib push inflate $s
+ chan event $s readable [list apply {{s} {
+ set d [read $s]
+ if {[eof $s]} {
+ chan event $s readable {}
+ set ::total [list eof [string length $d]]
+ }
+ }} $s]
+ vwait ::total
+ after cancel {set ::total timeout}
+ close $s
+ set ::total
+} -cleanup {
+ unset -nocomplain total
+ close $srv
+} -result {eof 500}
+test zlib-9.9 "bug #2818131 (gzip mismatch)" -constraints zlib -setup {
+ proc bgerror {s} {set ::total [list error $s]}
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ zlib push gzip $c
+ puts -nonewline $c [string repeat hello 100]
+ close $c
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ try {
+ chan configure $s -translation binary
+ zlib push inflate $s
+ chan event $s readable [list apply {{s} {
+ set d [read $s]
+ if {[eof $s]} {
+ chan event $s readable {}
+ set ::total [list eof [string length $d]]
+ }
+ }} $s]
+ vwait ::total
+ } finally {
+ after cancel {set ::total timeout}
+ close $s
+ }
+ set ::total
+} -cleanup {
+ unset -nocomplain total
+ close $srv
+ rename bgerror {}
+} -result {error {invalid block type}}
+test zlib-9.10 "bug #2818131 (compress mismatch)" -constraints zlib -setup {
+ proc bgerror {s} {set ::total [list error $s]}
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ zlib push compress $c
+ puts -nonewline $c [string repeat hello 100]
+ close $c
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ try {
+ chan configure $s -translation binary
+ zlib push inflate $s
+ chan event $s readable [list apply {{s} {
+ set d [read $s]
+ if {[eof $s]} {
+ chan event $s readable {}
+ set ::total [list eof [string length $d]]
+ }
+ }} $s]
+ vwait ::total
+ } finally {
+ after cancel {set ::total timeout}
+ close $s
+ }
+ set ::total
+} -cleanup {
+ unset -nocomplain total
+ close $srv
+ rename bgerror {}
+} -result {error {invalid stored block lengths}}
+test zlib-9.11 "bug #2818131 (deflate mismatch)" -constraints zlib -setup {
+ proc bgerror {s} {set ::total [list error $s]}
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary -buffering none -blocking 0
+ zlib push deflate $c
+ puts -nonewline $c [string repeat hello 100]
+ close $c
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ try {
+ chan configure $s -translation binary
+ zlib push gunzip $s
+ chan event $s readable [list apply {{s} {
+ set d [read $s]
+ if {[eof $s]} {
+ chan event $s readable {}
+ set ::total [list eof [string length $d]]
+ }
+ }} $s]
+ vwait ::total
+ } finally {
+ after cancel {set ::total timeout}
+ close $s
+ }
+ set ::total
+} -cleanup {
+ unset -nocomplain total
+ close $srv
+ rename bgerror {}
+} -result {error {incorrect header check}}
+
+test zlib-10.0 "bug #2818131 (close with null interp)" -constraints {
+ zlib
+} -setup {
+ proc bgerror {s} {set ::total [list error $s]}
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary
+ zlib push inflate $c
+ chan event $c readable [list apply {{c} {
+ set d [read $c]
+ if {[eof $c]} {
+ chan event $c readable {}
+ close $c
+ set ::total [list eof [string length $d]]
+ }
+ }} $c]
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ chan configure $s -translation binary -buffering none -blocking 0
+ zlib push gzip $s
+ chan event $s xyzzy [list apply {{s} {
+ if {[gets $s line] < 0} {
+ chan close $s
+ }
+ }} $s]
+ after idle [list apply {{s} {
+ puts $s test
+ chan close $s
+ after 100 {set ::total done}
+ }} $s]
+ vwait ::total
+ after cancel {set ::total timeout}
+ after cancel {set ::total done}
+ set ::total
+} -cleanup {
+ close $srv
+ rename bgerror {}
+} -returnCodes error \
+ -result {bad event name "xyzzy": must be readable or writable}
+test zlib-10.1 "bug #2818131 (mismatch read)" -constraints {
+ zlib
+} -setup {
+ proc bgerror {s} {set ::total [list error $s]}
+ proc zlibRead {c} {
+ set d [read $c]
+ if {[eof $c]} {
+ chan event $c readable {}
+ close $c
+ set ::total [list eof [string length $d]]
+ }
+ }
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary
+ zlib push inflate $c
+ chan event $c readable [list zlibRead $c]
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ chan configure $s -translation binary -buffering none -blocking 0
+ zlib push gzip $s
+ chan event $s readable [list zlibRead $s]
+ after idle [list apply {{s} {
+ puts $s test
+ chan close $s
+ after 100 {set ::total done}
+ }} $s]
+ vwait ::total
+ after cancel {set ::total timeout}
+ after cancel {set ::total done}
+ set ::total
+} -cleanup {
+ close $srv
+ rename bgerror {}
+ rename zlibRead {}
+} -result {error {invalid block type}}
+test zlib-10.2 "bug #2818131 (mismatch gets)" -constraints {
+ zlib
+} -setup {
+ proc bgerror {s} {set ::total [list error $s]}
+ proc zlibRead {c} {
+ if {[gets $c line] < 0} {
+ close $c
+ set ::total [list error -1]
+ } elseif {[eof $c]} {
+ chan event $c readable {}
+ close $c
+ set ::total [list eof 0]
+ }
+ }
+ set srv [socket -myaddr localhost -server {apply {{c a p} {
+ chan configure $c -translation binary
+ zlib push inflate $c
+ chan event $c readable [list zlibRead $c]
+ }}} 0]
+} -body {
+ lassign [chan configure $srv -sockname] addr name port
+ after 1000 {set ::total timeout}
+ set s [socket $addr $port]
+ chan configure $s -translation binary -buffering none -blocking 0
+ zlib push gzip $s
+ chan event $s readable [list zlibRead $s]
+ after idle [list apply {{s} {
+ puts $s test
+ chan close $s
+ after 100 {set ::total done}
+ }} $s]
+ vwait ::total
+ after cancel {set ::total timeout}
+ after cancel {set ::total done}
+ set ::total
+} -cleanup {
+ close $srv
+ rename bgerror {}
+ rename zlibRead {}
+} -result {error {invalid block type}}
+
+test zlib-11.1 "Bug #3390073: mis-appled gzip filtering" -setup {
+ set file [makeFile {} test.input]
+} -constraints zlib -body {
+ set f [open $file wb]
+ puts -nonewline [zlib push gzip $f] [string repeat "hello" 1000]
+ close $f
+ set f [open $file rb]
+ set d [read $f]
+ close $f
+ set d [zlib gunzip $d]
+ list [regexp -all "hello" $d] [string length [regsub -all "hello" $d {}]]
+} -cleanup {
+ removeFile $file
+} -result {1000 0}
+test zlib-11.2 "Bug #3390073: mis-appled gzip filtering" -setup {
+ set file [makeFile {} test.input]
+} -constraints zlib -body {
+ set f [open $file wb]
+ puts -nonewline [zlib push gzip $f -header {filename /foo/bar}] \
+ [string repeat "hello" 1000]
+ close $f
+ set f [open $file rb]
+ set d [read $f]
+ close $f
+ set d [zlib gunzip $d -header h]
+ list [regexp -all "hello" $d] [dict get $h filename] \
+ [string length [regsub -all "hello" $d {}]]
+} -cleanup {
+ removeFile $file
+} -result {1000 /foo/bar 0}
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End: